diff --git a/.cmake.conf b/.cmake.conf index 4e73b3d6071..842b347cedd 100644 --- a/.cmake.conf +++ b/.cmake.conf @@ -1 +1,2 @@ -set(QT_REPO_MODULE_VERSION "6.2.0") +set(QT_REPO_MODULE_VERSION "6.2.11") +set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "") diff --git a/.gitattributes b/.gitattributes index 9842d4e766f..7be61e4c7e1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,5 @@ -*_crlf.* eol=crlf -.tag export-subst -.gitignore export-ignore -.gitattributes export-ignore +*_crlf.* eol=crlf +.tag export-subst +.gitignore export-ignore +.gitattributes export-ignore +.commit-template export-ignore diff --git a/.gitignore b/.gitignore index 87ac2687b15..39f4cbaca50 100644 --- a/.gitignore +++ b/.gitignore @@ -85,12 +85,32 @@ bin/qml* bin/qttracereplay* configure.cache config.status +examples/quickcontrols2/chattutorial/chapter1-settingup/chapter1-settingup +examples/quickcontrols2/chattutorial/chapter2-lists/chapter2-lists +examples/quickcontrols2/chattutorial/chapter3-navigation/chapter3-navigation +examples/quickcontrols2/chattutorial/chapter4-models/chapter4-models +examples/quickcontrols2/chattutorial/chapter5-styling/chapter5-styling +examples/quickcontrols2/contactlist/contactlist +examples/quickcontrols2/flatstyle/flatstyle +examples/quickcontrols2/gallery/gallery +examples/quickcontrols2/imagine/automotive/automotive +examples/quickcontrols2/imagine/musicplayer/musicplayer +examples/quickcontrols2/sidepanel/sidepanel +examples/quickcontrols2/swipetoremove/swipetoremove +examples/quickcontrols2/texteditor/texteditor +examples/quickcontrols2/wearable/wearable moc_*.cpp qmake/qmake.exe qmake/Makefile.bak src/corelib/global/qconfig.cpp src/corelib/global/qconfig.h src/corelib/global/qconfig.h.qmake +src/quickcontrols2/qtquickcontrols2-config.h +src/quickcontrols2/qtquickcontrols2-config.pri +src/quickcontrols2/qtquickcontrols2-config_p.h +src/quicktemplates2/qtquicktemplates2-config.h +src/quicktemplates2/qtquicktemplates2-config.pri +src/quicktemplates2/qtquicktemplates2-config_p.h ui_*.h tests/auto/cmake/build tests/auto/installed_cmake/build @@ -107,6 +127,50 @@ tests/auto/qprocess/fileWriterProcess.txt .com.apple.timemachine.supported tests/auto/qlibrary/libmylib.so* tests/auto/qresourceengine/runtime_resource.rcc +tests/auto/quickcontrols2/accessibility/tst_accessibility +tests/auto/quickcontrols2/calendar/tst_calendar +tests/auto/quickcontrols2/controls/basic/tst_basic +tests/auto/quickcontrols2/controls/fusion/tst_fusion +tests/auto/quickcontrols2/controls/imagine/tst_imagine +tests/auto/quickcontrols2/controls/material/tst_material +tests/auto/quickcontrols2/controls/universal/tst_universal +tests/auto/quickcontrols2/cursor/tst_cursor +tests/auto/quickcontrols2/customization/tst_customization +tests/auto/quickcontrols2/focus/tst_focus +tests/auto/quickcontrols2/font/tst_font +tests/auto/quickcontrols2/palette/tst_palette +tests/auto/quickcontrols2/platform/tst_platform +tests/auto/quickcontrols2/pressandhold/tst_pressandhold +tests/auto/quickcontrols2/qquickapplicationwindow/tst_qquickapplicationwindow +tests/auto/quickcontrols2/qquickcolor/tst_qquickcolor +tests/auto/quickcontrols2/qquickdrawer/tst_qquickdrawer +tests/auto/quickcontrols2/qquickiconimage/tst_qquickiconimage +tests/auto/quickcontrols2/qquickiconlabel/tst_qquickiconlabel +tests/auto/quickcontrols2/qquickimaginestyle/tst_qquickimaginestyle +tests/auto/quickcontrols2/qquickmaterialstyle/tst_qquickmaterialstyle +tests/auto/quickcontrols2/qquickmaterialstyleconf/tst_qquickmaterialstyleconf +tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu +tests/auto/quickcontrols2/qquickmenubar/tst_qquickmenubar +tests/auto/quickcontrols2/qquickninepatchimage/tst_qquickninepatchimage +tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup +tests/auto/quickcontrols2/qquickstyle/tst_qquickstyle +tests/auto/quickcontrols2/qquickstyleselector/tst_qquickstyleselector +tests/auto/quickcontrols2/qquickuniversalstyle/tst_qquickuniversalstyle +tests/auto/quickcontrols2/qquickuniversalstyleconf/tst_qquickuniversalstyleconf +tests/auto/quickcontrols2/revisions/tst_revisions +tests/auto/quickcontrols2/sanity/tst_sanity +tests/auto/quickcontrols2/snippets/tst_snippets +tests/auto/quickcontrols2/styles/tst_styles +tests/auto/quickcontrols2/snippets/screenshots/*.png +tests/benchmarks/creationtime/tst_creationtime +tests/benchmarks/objectcount/tst_objectcount +tests/manual/quickcontrols2/buttons/buttons +tests/manual/quickcontrols2/fonts/fonts +tests/manual/quickcontrols2/gifs/tst_gifs +tests/manual/quickcontrols2/styles/styles +tests/manual/quickcontrols2/testbench/testbench +tests/manual/quickcontrols2/screenshots/screenshots +tests/manual/quickcontrols2/gifs/gifs/*.gif tools/qtestlib/chart/chart* tools/qtestlib/updater/updater* tools/qmleasing/qmleasing diff --git a/.qmake.conf b/.qmake.conf index dfee5ef72d3..7f5f2c33a70 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -3,4 +3,6 @@ CONFIG += warning_clean DEFINES += QT_NO_JAVA_STYLE_ITERATORS -MODULE_VERSION = 6.2.0 +QQC2_SOURCE_TREE = $$PWD + +MODULE_VERSION = 6.2.11 diff --git a/.tag b/.tag index 6828f88dcb0..8b42f85cf57 100644 --- a/.tag +++ b/.tag @@ -1 +1 @@ -$Format:%H$ +$Format:%T$ diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c6596342c9..9996810794e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from qtdeclarative.pro. -cmake_minimum_required(VERSION 3.15.0) +cmake_minimum_required(VERSION 3.16) include(.cmake.conf) project(QtDeclarative # special case @@ -39,9 +39,17 @@ if(NOT "${QT_HOST_PATH}" STREQUAL "") set(CMAKE_FIND_ROOT_PATH ${_qt_backup_qtdeclarative_CMAKE_FIND_ROOT_PATH}) endif() +# Optionally look for the target ShaderTools package to avoid warnings +# when configuring the project to build examples in-tree in a prefix Qt build. +# See QTBUG-96358 for details. +find_package(Qt6 ${PROJECT_VERSION} CONFIG OPTIONAL_COMPONENTS ShaderTools) + # special case begin # export QT6_ADD_QML_MODULE to this project include(src/qml/Qt6QmlMacros.cmake) +if(ANDROID) + include("${CMAKE_CURRENT_LIST_DIR}/src/qml/Qt6AndroidQmlMacros.cmake") +endif() # special case end if(NOT QT_FEATURE_commandlineparser) diff --git a/LICENSE.GPLv3 b/LICENSE.GPLv3 new file mode 100644 index 00000000000..cffb3b30007 --- /dev/null +++ b/LICENSE.GPLv3 @@ -0,0 +1,686 @@ + GNU GENERAL PUBLIC LICENSE + + The Qt Toolkit is Copyright (C) 2017 The Qt Company Ltd. + Contact: http://www.qt.io/licensing/ + + You may use, distribute and copy the Qt Toolkit under the terms of + GNU Lesser General Public License version 3. That license references + the General Public License version 3, that is displayed below. Other + portions of the Qt Toolkit may be licensed directly under this license. + +------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/LICENSE.LGPLv3 b/LICENSE.LGPLv3 new file mode 100644 index 00000000000..1d9bb2133b5 --- /dev/null +++ b/LICENSE.LGPLv3 @@ -0,0 +1,174 @@ + GNU LESSER GENERAL PUBLIC LICENSE + + The Qt Toolkit is Copyright (C) 2017 The Qt Company Ltd. + Contact: http://www.qt.io/licensing/ + + You may use, distribute and copy the Qt Toolkit under the terms of + GNU Lesser General Public License version 3, which is displayed below. + This license makes reference to the version 3 of the GNU General + Public License, which you can find in the LICENSE.GPLv3 file. + +------------------------------------------------------------------------- + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright © 2007 Free Software Foundation, Inc. +Everyone is permitted to copy and distribute verbatim copies of this +licensedocument, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + +0. Additional Definitions. + + As used herein, “this License” refers to version 3 of the GNU Lesser +General Public License, and the “GNU GPL” refers to version 3 of the +GNU General Public License. + + “The Library” refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An “Application” is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A “Combined Work” is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the “Linked +Version”. + + The “Minimal Corresponding Source” for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The “Corresponding Application Code” for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + +1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + +2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort + to ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + +3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this + license document. + +4. Combined Works. + + You may convey a Combined Work under terms of your choice that, taken +together, effectively do not restrict modification of the portions of +the Library contained in the Combined Work and reverse engineering for +debugging such modifications, if you also do each of the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this + license document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of + this License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with + the Library. A suitable mechanism is one that (a) uses at run + time a copy of the Library already present on the user's + computer system, and (b) will operate properly with a modified + version of the Library that is interface-compatible with the + Linked Version. + + e) Provide Installation Information, but only if you would + otherwise be required to provide such information under section 6 + of the GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the Application + with a modified version of the Linked Version. (If you use option + 4d0, the Installation Information must accompany the Minimal + Corresponding Source and Corresponding Application Code. If you + use option 4d1, you must provide the Installation Information in + the manner specified by section 6 of the GNU GPL for conveying + Corresponding Source.) + +5. Combined Libraries. + + You may place library facilities that are a work based on the Library +side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities, conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of + it is a work based on the Library, and explaining where to find + the accompanying uncombined form of the same work. + +6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +as you received it specifies that a certain numbered version of the +GNU Lesser General Public License “or any later version” applies to +it, you have the option of following the terms and conditions either +of that published version or of any later version published by the +Free Software Foundation. If the Library as you received it does not +specify a version number of the GNU Lesser General Public License, +you may choose any version of the GNU Lesser General Public License +ever published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the Library. diff --git a/README.md b/README.md new file mode 100644 index 00000000000..256124e863b --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +qtdeclarative +============= + +The qtdeclarative repository is home to QML, Qt Quick and several related modules: + +- [Qt QML](https://doc.qt.io/qt-6/qtqml-index.html) +- [Qt QML Core](https://doc.qt.io/qt-6/qtqmlcore-index.html) +- [Qt QML Models](https://doc.qt.io/qt-6/qtqml-models-qmlmodule.html) +- [Qt QML WorkerScript](https://doc.qt.io/qt-6/qml-qtqml-workerscript-workerscript.html) +- [Qt QML XmlListModel](https://doc.qt.io/qt-6/qml-qtqml-xmllistmodel-xmllistmodel.html) +- [Qt Quick](https://doc.qt.io/qt-6/qtquick-index.html) +- [Qt Quick Controls 2](https://doc.qt.io/qt-6/qtquickcontrols-index.html) +- [Qt Quick Layouts](https://doc.qt.io/qt-6/qtquicklayouts-index.html) +- [Qt Quick Local Storage](https://doc.qt.io/qt-6/qtquick-localstorage-qmlmodule.html) +- [Qt Quick Particles](https://doc.qt.io/qt-6/qtquick-particles-qmlmodule.html) +- [Qt Quick Shapes](https://doc.qt.io/qt-6/qtquick-shapes-qmlmodule.html) +- [Qt Quick Templates](https://doc.qt.io/qt-6/qtquick-templates2-qmlmodule.html) +- [Qt Quick Test](https://doc.qt.io/qt-6/qtquicktest-index.html) + +In addition, there are several Qt Labs modules: + +- [Qt Labs Animation](https://doc.qt.io/qt-6/qt-labs-animation-qmlmodule.html) +- [Qt Labs FolderListModel](https://doc.qt.io/qt-6/qml-qt-labs-folderlistmodel-folderlistmodel.html) +- [Qt Labs Platform](https://doc.qt.io/qt-6/qtlabsplatform-index.html) +- [Qt Labs Models](https://doc.qt.io/qt-6/qtqml-models-qmlmodule.html) +- [Qt Labs Settings](https://doc.qt.io/qt-6/qml-qt-labs-settings-settings.html) +- [Qt Labs Shared Image Provider](https://doc.qt.io/qt-6/qt-labs-sharedimage-qmlmodule.html) +- [Qt Labs WavefrontMesh](https://doc.qt.io/qt-6/qt-labs-wavefrontmesh-qmlmodule.html) diff --git a/cmake/QtDeclarativeSetup.cmake b/cmake/QtDeclarativeSetup.cmake index cd5ae32e14f..3513fdad0b7 100644 --- a/cmake/QtDeclarativeSetup.cmake +++ b/cmake/QtDeclarativeSetup.cmake @@ -1,24 +1,51 @@ -# Generates a header file with a hash. +# Create a header containing a hash that describes this library. For a +# released version of Qt, we'll use the .tag file that is updated by git +# archive with the tree hash. For unreleased versions, we'll ask git +# rev-parse. If none of this works, we use CMake to hash all the files +# in the src/qml/ directory. +# Skip recreation of the hash when doing a developer build. function(qt_declarative_write_tag_header target_name) + set(out_file "${CMAKE_CURRENT_BINARY_DIR}/qml_compile_hash_p.h") + if(FEATURE_developer_build AND EXISTS "${out_file}") + return() + endif() + set(tag_file "${CMAKE_CURRENT_SOURCE_DIR}/../../.tag") set(tag_contents "") if(EXISTS "${tag_file}") file(READ "${tag_file}" tag_contents) + string(STRIP "${tag_contents}" tag_contents) endif() - if(NOT tag_file STREQUAL "$Format:%H$") + find_program(git_path git) + + if(tag_contents AND NOT tag_contents STREQUAL "$Format:%T$") set(QML_COMPILE_HASH "${tag_contents}") - string(STRIP "${QML_COMPILE_HASH}" QML_COMPILE_HASH) - elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../.git") + elseif(git_path AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../.git") execute_process( - COMMAND git rev-parse HEAD + COMMAND ${git_path} rev-parse HEAD OUTPUT_VARIABLE QML_COMPILE_HASH - OUTPUT_STRIP_TRAILING_WHITESPACE) + OUTPUT_STRIP_TRAILING_WHITESPACE + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") endif() string(LENGTH "${QML_COMPILE_HASH}" QML_COMPILE_HASH_LENGTH) - configure_file("qml_compile_hash_p.h.in" "${CMAKE_CURRENT_BINARY_DIR}/qml_compile_hash_p.h") -endfunction() + if(QML_COMPILE_HASH_LENGTH EQUAL 0) + set(sources_hash "") + file(GLOB_RECURSE qtqml_source_files "${CMAKE_CURRENT_SOURCE_DIR}/*") + foreach(file IN LISTS qtqml_source_files) + file(SHA1 ${file} file_hash) + string(APPEND sources_hash ${file_hash}) + endforeach() + string(SHA1 QML_COMPILE_HASH "${sources_hash}") + endif() -find_package(PythonInterp REQUIRED) + string(LENGTH "${QML_COMPILE_HASH}" QML_COMPILE_HASH_LENGTH) + if(QML_COMPILE_HASH_LENGTH GREATER 0) + configure_file("qml_compile_hash_p.h.in" "${out_file}") + else() + message(FATAL_ERROR "QML compile hash is empty! " + "You need either a valid git repository or a non-empty .tag file.") + endif() +endfunction() # Generate a header file containing a regular expression jit table. function(qt_declarative_generate_reg_exp_jit_tables consuming_target) @@ -34,21 +61,9 @@ function(qt_declarative_generate_reg_exp_jit_tables consuming_target) add_custom_command( OUTPUT "${output_file}" - COMMAND "${PYTHON_EXECUTABLE}" ${retgen_script_file} ${output_file} + COMMAND "${QT_INTERNAL_DECLARATIVE_PYTHON}" ${retgen_script_file} ${output_file} MAIN_DEPENDENCY ${retgen_script_file} ) target_sources(${consuming_target} PRIVATE ${output_file}) target_include_directories(${consuming_target} PRIVATE $) endfunction() - -function(qt_qml_find_python out_var_path out_var_found) - find_program(QT_QML_PYTHON_PATH - NAMES python python2 python3 py - DOC "Qt Declarative python path") - if(QT_QML_PYTHON_PATH) - set(${out_var_path} "${QT_QML_PYTHON_PATH}" PARENT_SCOPE) - set(${out_var_found} "TRUE" PARENT_SCOPE) - else() - set(${out_var_found} "FALSE" PARENT_SCOPE) - endif() -endfunction() diff --git a/coin/module_config.yaml b/coin/module_config.yaml index 16d158c6b26..e1d12d4464a 100644 --- a/coin/module_config.yaml +++ b/coin/module_config.yaml @@ -1,9 +1,16 @@ version: 2 +alias: qtdeclarative accept_configuration: condition: property property: features not_contains_value: Disable +machine_type: + Build: + cores: 4 + Test: + cores: 4 + instructions: Build: - !include "{{qt/qtbase}}/coin_module_build_template_v2.yaml" diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 00000000000..a2ca5cecc5c --- /dev/null +++ b/conanfile.py @@ -0,0 +1,103 @@ +############################################################################# +## +## Copyright (C) 2021 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the release tools 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$ +## +############################################################################# + +from conans import ConanFile +import re +from pathlib import Path +from typing import Dict, Any + +_qtdeclarative_features = [ + "qml-animation", + "qml-debug", + "qml-delegate-model", + "qml-devtools", + "qml-itemmodel", + "qml-jit", + "qml-list-model", + "qml-locale", + "qml-network", + "qml-object-model", + "qml-preview", + "qml-profiler", + "qml-sequence-object", + "qml-table-model", + "qml-worker-script", + "qml-xml-http-request", + "qml-xmllistmodel", + "quick-animatedimage", + "quick-canvas", + "quick-designer", + "quick-draganddrop", + "quick-flipable", + "quick-gridview", + "quick-listview", + "quick-particles", + "quick-path", + "quick-pathview", + "quick-positioners", + "quick-repeater", + "quick-shadereffect", + "quick-sprite", + "quick-tableview", +] + + +def _parse_qt_version_by_key(key: str) -> str: + with open(Path(__file__).parent.resolve() / ".cmake.conf") as f: + m = re.search(fr'{key} .*"(.*)"', f.read()) + return m.group(1) if m else "" + + +def _get_qt_minor_version() -> str: + return ".".join(_parse_qt_version_by_key("QT_REPO_MODULE_VERSION").split(".")[:2]) + + +class QtDeclarative(ConanFile): + name = "qtdeclarative" + license = "LGPL-3.0, GPL-2.0+, Commercial Qt License Agreement" + author = "The Qt Company " + url = "https://code.qt.io/cgit/qt/qtdeclarative.git" + description = ( + "The Qt Declarative module provides a declarative framework for building highly dynamic, " + "custom user interfaces" + ) + topics = "qt", "qt6", "qtdeclarative" + settings = "os", "compiler", "arch", "build_type" + # for referencing the version number and prerelease tag and dependencies info + exports = ".cmake.conf", "dependencies.yaml" + exports_sources = "*", "!conan*.*" + python_requires = f"qt-conan-common/{_get_qt_minor_version()}@qt/everywhere" + python_requires_extend = "qt-conan-common.QtLeafModule" + + def get_qt_leaf_module_options(self) -> Dict[str, Any]: + """Implements abstractmethod from qt-conan-common.QtLeafModule""" + return {item.replace("-", "_"): ["yes", "no", None] for item in _qtdeclarative_features} + + def get_qt_leaf_module_default_options(self) -> Dict[str, Any]: + """Implements abstractmethod from qt-conan-common.QtLeafModule""" + return {item.replace("-", "_"): None for item in _qtdeclarative_features} diff --git a/configure.cmake b/configure.cmake new file mode 100644 index 00000000000..53e3f1109ae --- /dev/null +++ b/configure.cmake @@ -0,0 +1,21 @@ + + +#### Inputs + + + +#### Libraries + + + +#### Tests + + + +#### Features + + +qt_extra_definition("QT_VERSION_STR" "\"${PROJECT_VERSION}\"" PUBLIC) +qt_extra_definition("QT_VERSION_MAJOR" ${PROJECT_VERSION_MAJOR} PUBLIC) +qt_extra_definition("QT_VERSION_MINOR" ${PROJECT_VERSION_MINOR} PUBLIC) +qt_extra_definition("QT_VERSION_PATCH" ${PROJECT_VERSION_PATCH} PUBLIC) diff --git a/configure.json b/configure.json deleted file mode 100644 index df68a1765e2..00000000000 --- a/configure.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "subconfigs": [ - "src/qml", - "src/qmlmodels", - "src/quick" - ] -} diff --git a/dependencies.yaml b/dependencies.yaml index a090c30b13a..73185bf9930 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1,10 +1,13 @@ dependencies: - ../qtbase: - ref: 33aa461ec96201a2d32ce4ec80319f75878fed60 + ../tqtc-qtbase: + ref: dee139fa5ef483113e69fa67fd61a1d752a8ff45 required: true - ../qtshadertools: - ref: 37f9bda06d422a4a0945ce645459d7068455e2bb + ../tqtc-qtimageformats: + ref: aabdb2d6a44effa602b803aba4c8505fb141b4ca required: false - ../qtsvg: - ref: 749a1ee6611dfd1200d476e3bf8c63159fb5fdbb + ../tqtc-qtshadertools: + ref: 19b2da7db7aca19e121564645f94c79fe0d1c865 + required: false + ../tqtc-qtsvg: + ref: 1bed2504a2201cfab77e32ea849776d88e0f9d71 required: false diff --git a/dist/archived/qtquickcontrols2/changes-5.10.0 b/dist/archived/qtquickcontrols2/changes-5.10.0 new file mode 100644 index 00000000000..88f2afe820a --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.10.0 @@ -0,0 +1,166 @@ +Qt 5.10 introduces many new features and improvements as well as bugfixes +over the 5.9.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.10 series is binary compatible with the 5.10.x series. +Applications compiled for 5.9 will continue to run with 5.10. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - [QTBUG-58060] DialogButtonBox with Material style now uses the Android + button layout. + +**************************************************************************** +* Controls * +**************************************************************************** + + - AbstractButton: + * [QTBUG-49820] Added support for icons. The following properties are + now available for derived types to use: icon.name, icon.source, + icon.width, icon.height, icon.color. + * [QTBUG-49820] Added display property to allow control over how icons + and text are displayed within buttons, without having to implement + custom delegates. + * [QTBUG-50705] Added AbstractButton::action property. + + - Action: + * [QTBUG-50705] Introduced Action, an abstract user interface action + that can have shortcuts and be assigned to buttons. + + - ActionGroup: + * [QTBUG-50705] Introduced ActionGroup, a non-visual group of actions + that is mutually exclusive by default. + + - ApplicationWindow: + * [QTBUG-61336] The attached activeFocusControl property has been made + functional with a plain QML Window to make the functionality available + when using QQuickWindow/View/Widget instead of ApplicationWindow. + * [QTBUG-61336] Deprecated the overlay grouped property in favor of the + newly introduced Overlay attached properties. + + - ButtonGroup: + * Added exclusive property to allow creating non-exclusive button + groups. + + - Container: + * Deprecated removeItem(int) in favor of removeItem(Item) and + takeItem(int) with clearer semantics. The former destroys the item, + whereas the latter transfers ownership to the caller. + + - Dialog: + * Added "result" property that holds whether the dialog was previously + accepted or rejected. + * Added a standardButton() method for accessing the standard buttons in + the dialog's button box. + * [QTBUG-59423] Added missing applied(), discarded(), helpRequested(), + and reset() signals that are emitted when the respective standard + buttons are clicked. + + - DialogButtonBox: + * [QTBUG-59423] Added missing applied(), reset(), and discarded() + signals. + + - Menu: + * [QTBUG-50471] Added a popup() method that opens a menu at the mouse + cursor on desktop platforms that have a mouse cursor available, and + otherwise centers the menu over its parent item. + * Added support for declaring Actions. The new "delegate" property is + used to define a Component that is used to create menu items that + present the actions. + * Deprecated removeItem(int) in favor of removeItem(Item) and + takeItem(int) with clearer semantics. The former destroys the item, + whereas the latter transfers ownership to the caller. + * [QTBUG-60351] Added support for cascading sub-menus. + * Added addMenu(), insertMenu(), removeMenu(), and takeMenu() methods + for adding and removing sub-menus programmatically. + * Added addAction(), insertAction(), removeAction(), and takeAction() + methods for adding and removing actions programmatically. + * Added currentIndex property for styling purposes. + * Added actionAt() and menuAt() accessors. + * Added a dismiss() method. Unlike close() that only closes a menu and + its sub-menus, dismiss() closes the whole hierarchy of menus, + including the parent menus. + * Added "count" property. + + - MenuBar: + * [QTBUG-60350] Introduced a MenuBar control. + + - MenuItem: + * Added a "menu" property that provides access to the menu that contains + the menu item. + * Menu has been fixed to highlight its items while key navigating and + mouse hovering to ensure seamless item highlight between mouse hover + and key navigation. In order to provide appropriate highlighting that + works for key navigation and mouse hover, styles should bind their + visual highlight to MenuItem::highlighted instead of + Control::activeFocus or Control::hovered. + + - Overlay: + * [QTBUG-61336] Introduced Overlay attached properties and signals that + supersede the overlay grouped property in Application Window. The + Overlay attached type allows providing background dimming for popups + without requiring an ApplicationWindow instance. + + - Popup: + * Added an "opened" boolean property that holds whether a popup is fully + open. That is, the popup is visible and neither the enter nor exit + transitions are running. + * Added "enabled" property. + * Added a read-only "mirrored" property that is true when the popup's + locale is right-to-left. + + - RangeSlider: + * Added horizontal and vertical properties to make it more convenient to + create orientation-dependent bindings in styles. + + - ScrollBar: + * Added horizontal and vertical properties to make it more convenient to + create orientation-dependent bindings in styles. + + - ScrollIndicator: + * Added horizontal and vertical properties to make it more convenient to + create orientation-dependent bindings in styles. + + - Slider: + * Added horizontal and vertical properties to make it more convenient to + create orientation-dependent bindings in styles. + + - SpinBox: + * [QTBUG-58760] Added wrap-property to allow wrapping circular + spinboxes. + + - StackView: + * Allowed specifying a transition when clearing the stack view. + + - SwipeView: + * Added horizontal and vertical properties to make it more convenient to + create orientation-dependent bindings in styles. + + - TabBar: + * Added index/tabBar/position attached properties. + +**************************************************************************** +* Styles * +**************************************************************************** + + - Introduced a Fusion style that offers a platform agnostic + desktop-oriented look'n'feel. + - Added the Imagine style, which is based on image assets that can be + provided using a predefined naming convention. + - Added support for specifying the default font for different styles in + qtquickcontrols2.conf. + - Fixed the style selection mechanism so that now it is possible to + organize platform and locale-specific files into sub-directories, such + as "+linux", "+macos", and "+windows". diff --git a/dist/archived/qtquickcontrols2/changes-5.10.1 b/dist/archived/qtquickcontrols2/changes-5.10.1 new file mode 100644 index 00000000000..c94cb75dbca --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.10.1 @@ -0,0 +1,49 @@ +Qt 5.10.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.10.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.10 series is binary compatible with the 5.9.x series. +Applications compiled for 5.9 will continue to run with 5.10. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +This release contains all fixes included in the Qt 5.9.4 release. + +**************************************************************************** +* Qt 5.10.1 Changes * +**************************************************************************** + +Controls +-------- + + - AbstractButton: + * [QTBUG-65193] Made button's text win over action's when both are + specified. + + - Action: + * [QTBUG-65108] Fixed an issue where a checkable action would toggle + twice when toggling an associated checkable button. + * [QTBUG-65889] Fixed shortcuts in Repeater. + +Styles +------ + + - Imagine: + * [QTBUG-65500] Fixed to respect user font settings from + qtquickcontrols2.conf. + +Third-Party Code +---------------- + + - [QTBUG-65409] Document constants from AngularJS in + src/imports/controls/material/ElevationEffect.qml diff --git a/dist/archived/qtquickcontrols2/changes-5.11.0 b/dist/archived/qtquickcontrols2/changes-5.11.0 new file mode 100644 index 00000000000..9368e9514fc --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.11.0 @@ -0,0 +1,161 @@ +Qt 5.11 introduces many new features and improvements as well as bugfixes +over the 5.10.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.11 series is binary compatible with the 5.10.x series. +Applications compiled for 5.10 will continue to run with 5.11. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.11.0 Changes * +**************************************************************************** + +Important Behavior Changes +-------------------------- + + - [QTBUG-56295] CheckBox and CheckDelegate no longer force the tristate + property to true when setting checkState to Qt.PartiallyChecked. This + allows the controls to present a partially checked state without being + interactively tri-state. + - [QTBUG-56295] CheckBox and CheckDelegate no longer consider the partially + checked state as a checked state. This fixes check state cycling for non- + tri-state controls so that the check state goes from partially checked to + fully checked state. + +Controls +-------- + + - AbstractButton: + * The autoRepeat property was promoted from Button to AbstractButton. + * Added autoRepeatDelay and autoRepeatInterval properties. + * [QTBUG-62811] Added pressX and pressY properties. + * [QTBUG-66625] Fixed the icon property group type registration. + + - Action: + * [QTBUG-65193] Made AbstractButton's icon properties win over Action's + when both are set. + * [QTBUG-66625] Fixed the icon property group type registration. + + - ButtonGroup: + * [QTBUG-56295][QTBUG-63782] Added checkState property that indicates + the combined check state of the entire group. + + - CheckBox: + * [QTBUG-63238] Made it possible to implement nextCheckState() in QML. + + - CheckDelegate: + * [QTBUG-63238] Made it possible to implement nextCheckState() in QML. + + - ComboBox: + * [QTBUG-61348] Fixed key search in the popup. + * [QTBUG-66044] Fixed wheel event propagation. + + - Control: + * [QTBUG-66133] Fixed focus scope controls, such as Frame, GroupBox, + Page, and Pane, to respect click focus policy by clearing a potential + sub-focus child. This makes it possible to close the virtual keyboard + by clicking the background of a Pane that has Qt.ClickFocus set as its + focusPolicy, for example. + * [QTBUG-66133] Fixed focus scope controls to respect wheel focus + policy. + + - Dial: + * [QTBUG-66637] Fixed to keep mouse grab on mouse press. + + - DialogButtonBox: + * [QTBUG-59719] Fixed implicit size calculation with one button. + + - Drawer: + * [QTBUG-66637] Fixed to no steal mouse/touch grab when e.g. dragging a + horizontal Slider in a horizontal Drawer. + + - Label: + * [QTBUG-65880] Fixed a background size regression caused by deferred + execution. + + - Popup: + * [QTBUG-66113] Fixed restoring focus for popups that did not originally + request focus, but gained focus after opening. + * Fixed Shortcuts in Popups with window context not being activated. + + - RangeSlider: + * [QTBUG-66637] Fixed to keep mouse grab on mouse press. + + - ScrollBar: + * [QTBUG-56557] Added minimumSize, visualSize, and visualPosition + properties. + + - ScrollIndicator: + * [QTBUG-56557] Added minimumSize, visualSize, and visualPosition + properties. + + - Slider: + * [QTBUG-66637] Fixed to keep mouse grab on mouse press. + + - SpinBox: + * Added a displayText property that allows styles to create a simple + and efficient QML binding to display the textual value instead of + calling the textFromValue() JS-function. + * [QTBUG-66044] Fixed wheel event propagation. + + - StackView: + * [QTBUG-51321] Fixed to transfer focus to the current item. + * [QTBUG-67118] Fixed a crash with initialItem. + + - TextArea: + * [QTBUG-67334] Fixed the background to not scroll when TextArea is + placed in a ScrollView. + * [QTBUG-65880] Fixed a background size regression caused by deferred + execution. + + - TextField: + * [QTBUG-65880] Fixed a background size regression caused by deferred + execution. + +Styles +------ + + - [QTBUG-66430] Fixed to not override/reset platform default fonts and + palettes if :/qtquickcontrols2.conf exists but doesn't define fonts + or palettes. + + - Fusion: + * [QTBUG-66752] Fixed BusyIndicator to show up when running is set to + true after creation. + * [QTBUG-66276] Added missing plugins.qmltypes. + + - Material: + * Decreased Dial's handle size from 14 to 10. + * [QTBUG-64872] Made BusyIndicator's line size adapt to the size of the + control. + * [QTBUG-58646] Fixed artifacts in ripple effects. + * [QTBUG-67442] Fixed CheckBox's, CheckDelegate's, RadioButton's and + RadioDelegate's indicator in disabled state. + + - Universal: + * Decreased Dial's handle size from 20 to 14. + +Platform +-------- + + - ColorDialog: + * [QT3DS-1363] Fixed currentColor to get correctly updated when opening + the dialog first time. + + - Menu: + * [QTBUG-55251] Fixed positioning on high-DPI screens. + * [QTBUG-66876] Fixed menu titles not being visible if they were defined + using qsTr() or bindings. + * [QTBUG-66889] Fixed a crash on exist with sub-menus on Windows. + + - MenuItem: + * [QTBUG-66386] Fixed checked state handling. diff --git a/dist/archived/qtquickcontrols2/changes-5.11.1 b/dist/archived/qtquickcontrols2/changes-5.11.1 new file mode 100644 index 00000000000..5680f38b534 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.11.1 @@ -0,0 +1,25 @@ +Qt 5.11.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.11.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.11 series is binary compatible with the 5.10.x series. +Applications compiled for 5.10 will continue to run with 5.11. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.11.1 Changes * +**************************************************************************** + + - [QTBUG-67684] ComboBox: don't block the escape/back key + - [QTBUG-67684] ComboBox: reset when hidden diff --git a/dist/archived/qtquickcontrols2/changes-5.11.2 b/dist/archived/qtquickcontrols2/changes-5.11.2 new file mode 100644 index 00000000000..335804a47f9 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.11.2 @@ -0,0 +1,32 @@ +Qt 5.11.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.11.0 through 5.11.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.11 series is binary compatible with the 5.10.x series. +Applications compiled for 5.10 will continue to run with 5.11. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.11.2 Changes * +**************************************************************************** + + - [QTBUG-69897] StackView: fixed a crash in viewItemTransitionFinished() + - [QTBUG-69839] ColorDialog: fixed a crash when initializing the platform dialog helper + - [QTBUG-69506] IconImage: prevented the color from being applied twice + - [QTBUG-66483] Popup: fixed a crash on exit when using a shader + - [QTBUG-68219] Styles: fixed handling of QRC paths in QT_QUICK_CONTROLS_STYLE_PATH + - [QTBUG-68858] Menu: fixed items not being scrollable when using Window + - [QTBUG-68737] Tumbler: fixed to respect currentIndex changes in onModelChanged + - [QTBUG-68769] TextArea, TextField: fixed to use the control's renderType in placeholder text + - SpinBox: fixed "function expressions as statements" warnings diff --git a/dist/archived/qtquickcontrols2/changes-5.11.3 b/dist/archived/qtquickcontrols2/changes-5.11.3 new file mode 100644 index 00000000000..f71fa34123c --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.11.3 @@ -0,0 +1,20 @@ +Qt 5.11.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.11.0 through 5.11.2. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.11 series is binary compatible with the 5.10.x series. +Applications compiled for 5.10 will continue to run with 5.11. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + - This release contains only minor code improvements. diff --git a/dist/archived/qtquickcontrols2/changes-5.12.0 b/dist/archived/qtquickcontrols2/changes-5.12.0 new file mode 100644 index 00000000000..fd9b1ba358e --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.12.0 @@ -0,0 +1,171 @@ +Qt 5.12 introduces many new features and improvements as well as bugfixes +over the 5.11.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - AbstractButton: + * Added implicitIndicatorWidth and implicitIndicatorHeight properties. + + - ComboBox: + * Added implicitIndicatorWidth and implicitIndicatorHeight properties. + + - Control: + * Added horizontalPadding and verticalPadding properties as a convenient + way to set both left and right, or top and bottom paddings in one go. + * Unless explicitly specified, baselineOffset is now automatically + updated based on the top padding of the control and the baselineOffset + of the contentItem. Styles no longer need to specify the + baselineOffset in QML. + * [QTBUG-60156] Added implicitBackgroundWidth and + implicitBackgroundHeight properties that can be used to simplify + complex implicit size bindings. + * Added implicitContentWidth and implicitContentHeight properties that + can be used to simplify complex implicit size bindings. + * [QTBUG-60156] Added topInset, bottomInset, leftInset, and rightInset + properties to control the geometry of the background similarly to how + paddings control the geometry of the contentItem. + + - Dial: + * [QTBUG-56323] Added the inputMode property. This property controls how + the dial is interacted with. The circular input mode (default, old + behavior) operates on an absolute input system, whereas the horizontal + and vertical input modes use a relative input system. + + - Dialog: + * Added implicitHeaderWidth, implicitHeaderHeight, implicitFooterWidth, + and implicitFooterHeight properties. + + - DialogButtonBox: + * Added buttonLayout property that can be used to arrange the buttons. + * Added contentWidth and contentHeight properties. + + - GroupBox: + * Added implicitLabelWidth and implicitLabelHeight properties. + + - Label: + * Added implicitBackgroundWidth and implicitBackgroundHeight properties + that can be used to simplify complex implicit size bindings. + [ChangeLog][Controls][TextArea] Added implicitBackgroundWidth and + implicitBackgroundHeight properties that can be used to simplify + complex implicit size bindings. [ChangeLog][Controls][TextField] Added + implicitBackgroundWidth and implicitBackgroundHeight properties that + can be used to simplify complex implicit size bindings. + * Added topInset, bottomInset, leftInset, and rightInset properties to + control the geometry of the background similarly to how paddings + control the geometry of the contentItem. + + - Page: + * Added implicitHeaderWidth, implicitHeaderHeight, implicitFooterWidth, + and implicitFooterHeight properties. + + - Popup: + * Added horizontalPadding and verticalPadding properties as a convenient + way to set both left and right, or top and bottom paddings in one go. + * [QTBUG-60354] Added anchors.centerIn to Popup to allow a covenient way + of centering a popup. + * Added implicitBackgroundWidth, implicitBackgroundHeight, + implicitContentWidth, and implicitContentHeight properties. + * [QTBUG-60156] Added topInset, bottomInset, leftInset, and rightInset + properties to control the geometry of the background similarly to how + paddings control the geometry of the contentItem. + + - QQuickStyle: + * [QTBUG-67062] Added stylePathList() and addStylePath() methods for + managing the list of directories where Qt Quick Controls 2 searches + for available styles. + + - RangeSlider: + * [QTBUG-67311] Added a moved() signal to each handle (similar to the + Slider's moved() signal) to react to the values being interactively + changed by the user. + * [QTBUG-67317] Added a valueAt() function to allow accessing each + handle's value when the live property is set to false. + * Added first.implicitHandleWidth, first.implicitHandleHeight, + second.implicitHandleWidth, and second.implicitHandleHeight + properties. + * [QTBUG-62784] Added touchDragThreshold property for configuring the + threshold to initiate the touch 'drag' of the handle of the slider. The + mouse 'drag' won't be affected by the property. + + - Slider: + * Added implicitHandleWidth and implicitHandleHeight properties. + * [QTBUG-62784] Added touchDragThreshold property for configuring the + threshold to initiate the touch 'drag' of the handle of the slider. The + mouse 'drag' won't be affected by the property. + + - SpinBox: + * Added up.implicitIndicatorWidth, up.implicitIndicatorHeight, + down.implicitIndicatorWidth, and down.implicitIndicatorHeight + properties. + + - SwipeView: + * Added contentWidth and contentHeight properties. + + - TextArea: + * Added topInset, bottomInset, leftInset, and rightInset properties to + control the geometry of the background similarly to how paddings + control the geometry of the contentItem. + * Added placeholderTextColor property for user convenience to customize + the placeholderText color to fit the backgrounds. + + - TextField: + * Added topInset, bottomInset, leftInset, and rightInset properties to + control the geometry of the background similarly to how paddings + control the geometry of the contentItem. + * [QTBUG-66260] Added placeholderTextColor property for user convenience + to customize the placeholderText color to fit the backgrounds. + + - ToolTip: + * [QTBUG-62890] Added non-attached show() and hide() methods to make it + more flexible to meet certain requirements. + + - Tumbler: + * [QTBUG-66358] Added positionViewAtIndex() function that calls the + respective PathView/ListView function, depending on the value of wrap. + This allows changing currentIndex without animations. + +**************************************************************************** +* Material * +**************************************************************************** + + - [QTBUG-51109] Added Dense variant of the Material style for use on + desktop platforms. Some controls are slightly smaller in height and use + smaller font sizes. The variant can be enabled by setting + QT_QUICK_CONTROLS_MATERIAL_VARIANT to Dense or setting Variant=Dense in + the qtquickcontrols.conf file. + +**************************************************************************** +* Platform * +**************************************************************************** + + - Menu: + * [QTBUG-67730] Deprecated iconName and iconSource properties in favor + of icon.name and icon.source grouped properties. + * [QTBUG-67730] Added icon.mask grouped property. + [ChangeLog][Platform][MenuItem] Added icon.mask grouped property. + [ChangeLog][Platform][SystemTrayIcon] Added icon.mask grouped + property. + + - MenuItem: + * [QTBUG-67730] Deprecated iconName and iconSource properties in favor + of icon.name and icon.source grouped properties. + + - SystemTrayIcon: + * [QTBUG-67730] Deprecated iconName and iconSource properties in favor + of icon.name and icon.source grouped properties. diff --git a/dist/archived/qtquickcontrols2/changes-5.12.1 b/dist/archived/qtquickcontrols2/changes-5.12.1 new file mode 100644 index 00000000000..1cb4dd73d17 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.12.1 @@ -0,0 +1,20 @@ +Qt 5.12.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + - This release contains only minor code improvements. diff --git a/dist/archived/qtquickcontrols2/changes-5.12.10 b/dist/archived/qtquickcontrols2/changes-5.12.10 new file mode 100644 index 00000000000..a49b10ff06d --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.12.10 @@ -0,0 +1,27 @@ +Qt 5.12.10 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.9. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + https://doc.qt.io/qt-5.12/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - [QTBUG-84579] Fixed crash on exit when centering Popup within Overlay in + StackView item. + - [QTBUG-79464] QQuickPopup: fixed focus not being transferred to the + appropriate item when multiple popups were closing. diff --git a/dist/archived/qtquickcontrols2/changes-5.12.2 b/dist/archived/qtquickcontrols2/changes-5.12.2 new file mode 100644 index 00000000000..420ded77f3a --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.12.2 @@ -0,0 +1,60 @@ +Qt 5.12.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - [QTBUG-73849] Fixed incorrect documentation link to + Number.toLocaleString(). + - [QTBUG-72536] Fixed bug with long text in ScrollView. + - [QTBUG-73447] Fixed Menu's appearance not changing when enabled state + changes + - [QTBUG-70181] Fixed disabled menu items getting focus. + - [QTBUG-69540] Fixed disabled sub-menu items being highlighted. + - [QTBUG-72023] Fixed font and palette settings in .conf files not being + respected. + - [QTBUG-69682] Fixed Menu not being dismissed when the triggered item + disables itself. + - [QTBUG-73412] Fixed Dial's new properties not being detected by Creator. + - [QTBUG-73202] Documented how to move active focus out of TextArea with + tab. + - [QTBUG-72786] Fixed palette colors not propagating to ComboBox's popup. + - [QTBUG-73179] Fixed Qt.labs.platform.FileDialog not honoring folder + property. + - [QTBUG-72811] Fixed AbstractButton's clicked() signal not being emitted + after long press. + - [QTBUG-72746] Fixed crash on exit when using popups. + - [QTBUG-72372] Fixed issue where a button would go outside of + DialogButtonBox. + - [QTBUG-71902] Fixed incorrect font size in certain styles on Windows. + - [QTBUG-72750] Fixed Slider's wheel event propagation. + +**************************************************************************** +* Controls * +**************************************************************************** + +Fusion +------ + + - [QTBUG-70819] Made Active and Disabled button colors closer to Widgets' + Fusion style. + - [QTBUG-70819] Use white ButtonText when a dark system theme is in use. + - [QTBUG-70652] Use system palette for highlightedText instead of a fixed + white color. diff --git a/dist/archived/qtquickcontrols2/changes-5.12.3 b/dist/archived/qtquickcontrols2/changes-5.12.3 new file mode 100644 index 00000000000..8a9bad9f287 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.12.3 @@ -0,0 +1,46 @@ +Qt 5.12.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.2. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - [QTBUG-70451] DialogButtonBox: fixed buttons with equal roles being + randomly sorted. + - [QTBUG-70161] ComboBox: fixed popup immediately closing on iOS + - [QTBUG-72886] DialogButtonBox: fixed content size calculation + - [QTBUG-74226] Fixed attached ToolTips using the timeout of the last shown + tool tip + - [QTBUG-72536] ScrollView now respects the content size set on/by + the flickable + - [QTBUG-73354] Menu: enter/return can now be used to activate items, + rather than just space. + - [QTBUG-71290] Drawer: fixed infinite positioning loop + - [QTBUG-66494] Page: fixed binding loop + +**************************************************************************** +* Styles * +**************************************************************************** + +Default +-------- + - [QTBUG-72786] Made ItemDelegate respect highlightedText and improved + highlightedText color so that text shows up against a highlighted background. + This also allows easily switching ComboBox to a dark style via palette + customization. diff --git a/dist/archived/qtquickcontrols2/changes-5.12.4 b/dist/archived/qtquickcontrols2/changes-5.12.4 new file mode 100644 index 00000000000..a285cd8e234 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.12.4 @@ -0,0 +1,20 @@ +Qt 5.12.4 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.3. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + - This release contains only minor code improvements. diff --git a/dist/archived/qtquickcontrols2/changes-5.12.5 b/dist/archived/qtquickcontrols2/changes-5.12.5 new file mode 100644 index 00000000000..3d5d25e7fbf --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.12.5 @@ -0,0 +1,28 @@ +Qt 5.12.5 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.4. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - TextArea: + * [QTBUG-76369] Fixed rendering issue using the Material style. + + - Container + * [QTBUG-76164] Fixed crash when removing items. diff --git a/dist/archived/qtquickcontrols2/changes-5.13.0 b/dist/archived/qtquickcontrols2/changes-5.13.0 new file mode 100644 index 00000000000..5792b0328ce --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.13.0 @@ -0,0 +1,33 @@ +Qt 5.13 introduces many new features and improvements as well as bugfixes +over the 5.12.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.13 series is binary compatible with the 5.12.x series. +Applications compiled for 5.12 will continue to run with 5.13. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - Added SplitView, a control that lays out items horizontally or vertically + with a draggable splitter between each item. + - Added cache property to icon. + - [QTBUG-75072] ScrollBar: fixed value not changing when scrolling via + VoiceOver. + - [QTBUG-74661] QQuickComboBox: we no longer hide popup when it's focused. + - [QTBUG-69096] Doc: expanded upon Pane's Content Sizing section. + - [QTBUG-74902] Doc: added a Size section to explain StackView's sizing + behavior. + - [QTBUG-74688] SpinBox: fixed indicators being hovered when mouse is moved + while pressed. + - [QTBUG-74276] Fix SplitView crash when using certain attached properties. diff --git a/dist/archived/qtquickcontrols2/changes-5.13.1 b/dist/archived/qtquickcontrols2/changes-5.13.1 new file mode 100644 index 00000000000..3acd7b6e752 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.13.1 @@ -0,0 +1,31 @@ +Qt 5.13.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.13.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.13 series is binary compatible with the 5.12.x series. +Applications compiled for 5.12 will continue to run with 5.13. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - [QTBUG-76356] Accessibility: a Switch now has checkbox as its accessibleRole. + - [QTBUG-75572] Fixed an issue with transforming Shortcut.sequence to string. + - [QTBUG-75844] The text cursor no longer disappears while dragging it + around on iOS with the magnifier showing. + - [QTBUG-75972] The countChanged signal now will be emitted when a new + model is set on a ComboBox. + - [QTBUG-67343] It's now OK to use a ShaderEffect in a ComboBox delegate + (fixed in Qt Quick, tested in Controls 2) diff --git a/dist/archived/qtquickcontrols2/changes-5.13.2 b/dist/archived/qtquickcontrols2/changes-5.13.2 new file mode 100644 index 00000000000..af5214cd38a --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.13.2 @@ -0,0 +1,25 @@ +Qt 5.13.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.13.0 through 5.13.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.13 series is binary compatible with the 5.12.x series. +Applications compiled for 5.12 will continue to run with 5.13. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - QQuickTextArea: + * Fixed rendering issue when using TextArea in a ScrollView. diff --git a/dist/archived/qtquickcontrols2/changes-5.14.0 b/dist/archived/qtquickcontrols2/changes-5.14.0 new file mode 100644 index 00000000000..08e9cdbdc93 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.14.0 @@ -0,0 +1,51 @@ +Qt 5.14 introduces many new features and improvements as well as bugfixes +over the 5.13.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.14 series is binary compatible with the 5.13.x series. +Applications compiled for 5.13 will continue to run with 5.14. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - ComboBox: + * Added valueRole, currentValue and indexOfValue(). These allow + convenient management of data for a role associated with the text + role. + + - QQuickMenuBar: + * Fixed issue with dynamically menu bar items not losing their highlight + when their menu was dismissed. + + - QQuickPopup: + * Fixed the issue that Popup doesn't respond to CloseOnEscape if the + initial value of visible is true + +- [QTBUG-79790] Fixed issue where font changes would result in an extra + signal being emitted. +- [QTBUG-59330] The documentation now advises against naming root resource + directories with the same name as a style name. +- [QTBUG-79302] SplitView: fix issue where Repeater items were not created. +- [QTBUG-79302] SplitView: fix cursor shape staying as Split*Cursor in some + cases. +- [QTBUG-79270] Fixed assertion failure when hiding a SplitView with only + one item. + +**************************************************************************** +* Universal * +**************************************************************************** + + - TabBar: + * Disabled wrapping. The Universal style TabBar now behaves like TabBar + from other styles. diff --git a/dist/archived/qtquickcontrols2/changes-5.14.1 b/dist/archived/qtquickcontrols2/changes-5.14.1 new file mode 100644 index 00000000000..e12ea637333 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.14.1 @@ -0,0 +1,29 @@ +Qt 5.14.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.14.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.14 series is binary compatible with the 5.13.x series. +Applications compiled for 5.13 will continue to run with 5.14. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - StackView: + * [QTBUG-80353] fixed crash when recursively removing items. + * [QTBUG-57267] fix an issue where the current item became hidden. + + - SplitView: + * [QTBUG-79846] fixed hoverable child items breaking handle hover state. diff --git a/dist/archived/qtquickcontrols2/changes-5.14.2 b/dist/archived/qtquickcontrols2/changes-5.14.2 new file mode 100644 index 00000000000..95572790952 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.14.2 @@ -0,0 +1,40 @@ +Qt 5.14.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.14.0 through 5.14.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.14 series is binary compatible with the 5.13.x series. +Applications compiled for 5.13 will continue to run with 5.14. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - [QTBUG-82032] AbstractButton: fixed clicked() being emitted after + doubleClicked(). + - [QTBUG-81935] ToolTip: fixed timeout not activating if opened during exit + transition. + - [QTBUG-77202] Control: we now account for when a touch event is + synthesized by Qt as a mouse event. + - [QTBUG-81796] DialogButtonBox: fixed explicitly set button text not being + rendered. + - [QTBUG-75682] Fixed issue where Qt Quick Designer was not able to work + with the module on WebAssembly/static builds. + - [QTBUG-80970] RangeSlider: fixed errors in the documentation's example + code. + - [QDS-456] placeholderText is now set by default in Qt Design Studio + instead of text when dragging a TextField or TextArea onto the form + editor. + - [QTBUG-81216] Fixed QQuickStyle::setFallbackStyle() not working on + Android. diff --git a/dist/archived/qtquickcontrols2/changes-5.15.0 b/dist/archived/qtquickcontrols2/changes-5.15.0 new file mode 100644 index 00000000000..b20691ea012 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.15.0 @@ -0,0 +1,80 @@ +Qt 5.15 introduces many new features and improvements as well as bugfixes +over the 5.14.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.15 series is binary compatible with the 5.14.x series. +Applications compiled for 5.14 will continue to run with 5.15. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +Qt 5.15 introduces many new features and improvements as well as bugfixes +over the 5.14.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + + https://doc.qt.io/qt-5.15/index.html + +The Qt version 5.15 series is binary compatible with the 5.14.x series. +Applications compiled for 5.14 will continue to run with 5.15. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - [QTBUG-72085] Old delegate items (background, contentItem, etc.) are no + longer destroyed, as they are technically owned by user code. Instead, + they are hidden, unparented from the control (QQuickItem parent, not + QObject), and Accessible.ignored is set to true. This prevents them from + being unintentionally visible and interfering with the accessibility + tree when a new delegate item is set. + + See the following page for more information: + + https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#considerations-for-custom-styles + +**************************************************************************** +* Controls * +**************************************************************************** + +- Added HorizontalHeaderView and VerticalHeaderView for use with TableView. +- Added selectTextByMouse property to ComboBox. +- [QTBUG-82473] Fixed Menu not taking padding into account when checking + if it is interactive. +- [QTBUG-73687] Fixed Menu positioning when a scale is set. +- [QTBUG-81867] Fixed hidden SplitView items causing visible items to not + be resizable. +- [QTBUG-82020] Fixed ComboBox text not being retranslated after a + translator is installed. +- [QTBUG-79501] Fixed keyboard navigation via tab in non-modal popups + (i.e. Drawer). +- [QTBUG-78858] Fixed Editable ComboBox's auto-completion performance. + +**************************************************************************** +* Styles * +**************************************************************************** + +Material +-------- +- [QTBUG-70768] Added missing visual distinction between enabled and + disabled sliders. +- [QTBUG-70768] Aligned Slider's visuals closer to the Material Design + guidelines. + +Imagine +------- +- [QTBUG-82463] Fixed squished Dial. diff --git a/dist/archived/qtquickcontrols2/changes-5.15.1 b/dist/archived/qtquickcontrols2/changes-5.15.1 new file mode 100644 index 00000000000..dea0ef2c33e --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.15.1 @@ -0,0 +1,49 @@ +Qt 5.15.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.15.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + https://doc.qt.io/qt-5.15/index.html + +The Qt version 5.15 series is binary compatible with the 5.14.x series. +Applications compiled for 5.14 will continue to run with 5.15. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - [QTBUG-64151] QQuickSpinBox: fixed "function expressions as statements" + warning. + - [QTBUG-85804] SwipeDelegate: fixed being able to call close() when + pressed. This conflicts with the behavior of SwipeDelegate. The + released() or clicked() signals should be used instead. + - [QTBUG-85806] SwipeDelegate: fixed closed() being emitted when already + closed. + - [QTBUG-85884] Fixed Dialog not releasing focus when it was hidden as a + result of losing focus. + - [QTBUG-84488] Fixed ComboBox popup position jumping when opened with + styles that user enter transitions. + - [QTBUG-84579] Fixed crash on exit when centering Popup within Overlay in + StackView item. + - [QTBUG-81976][QTBUG-86131] Fixed various "Cannot read property 'width' + of null" errors. + - [QTBUG-84381] StackView: fixed heap-use-after-free when pushing after clear. + - [QTBUG-83554] ComboBox: fixed currentValue not being updated on model + changes. + +Platform +-------- + + - MenuItem: + * [QTBUG-84102] Fix MenuItem.icon.* properties not being accessible when + importing version 1.1. + diff --git a/dist/archived/qtquickcontrols2/changes-5.15.2 b/dist/archived/qtquickcontrols2/changes-5.15.2 new file mode 100644 index 00000000000..e71e2bf358c --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.15.2 @@ -0,0 +1,42 @@ +Qt 5.15.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.15.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + https://doc.qt.io/qt-5.15/index.html + +The Qt version 5.15 series is binary compatible with the 5.14.x series. +Applications compiled for 5.14 will continue to run with 5.15. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - [QTBUG-83698] Fixed issue where a menu opened by pressing enter (handled + via attached Keys property) would instantly trigger the first menu + item. + - [QTBUG-86851] QQuickMenu: fixed memory leak due to contentModel not being + deleted. Also fixed a heap-use-after-free that was exposed by the + previously mentioned fix. + - [QTBUG-85884] Fixed expected item not getting focus when a dialog closes. + - [QTBUG-85719] Fixed SpinBox failing to validate input correctly after + previous input was out of range. + +**************************************************************************** +* Styles * +**************************************************************************** + +Material +-------- + + - [QTBUG-85699] Fixed binding loops when binding between attached + properties. diff --git a/dist/archived/qtquickcontrols2/changes-5.7.1 b/dist/archived/qtquickcontrols2/changes-5.7.1 new file mode 100644 index 00000000000..a206118e9d7 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.7.1 @@ -0,0 +1,196 @@ +Qt 5.7.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.7.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.7 series is binary compatible with the 5.6.x series. +Applications compiled for 5.6 will continue to run with 5.7. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - AbstractButton, Control, and Container now calculate their implicit size + based on the implicit size of the content item plus paddings, and the + implicit size of the background item. This makes it convenient to implement + custom controls and buttons, because the implicit size calculation for + these abstract/non-visual base types works as expected out of the box, but + may cause surprises if an application relies on the old behavior that a + custom control does not have any implicit size by default. + + - Drawers have been changed to follow the same visibility rules than all + other types of popups do. This means that drawers no longer stay visible + at the window edge in order to intercept input events, because that caused + severe conflicts in input handling and stacking order between multiple + drawers and other popups. + + - Popups have been fixed to respect explicitly set width and height. + Previously, explicitly set size was accidentally ignored when a popup had + implicit size set. + +**************************************************************************** +* Controls * +**************************************************************************** + + - ApplicationWindow: + * [QTBUG-55143] Fixed the content layout to take header and footer + visibility into account. + + - ComboBox: + * [QTBUG-54573] Fixed a bug which caused ghost items, from outside the + popup's visible area, to appear in the popup. + * [QTBUG-55118] Fixed the display text to be properly updated on model + changes. + * [QTBUG-55050] Fixed the default delegates to respect the popup width. + * [QTBUG-55030] Fixed the highlighted item to be visible in the popup when + it is opened. + + - Control: + * [QTBUG-56007] Fixed the hovered state to get cleared when hidden. + + - Dial: + * [QTBUG-55228] Fixed step size and snap mode handling with ranges starting + from a non-zero value. + + - Drawer: + * [QTBUG-54578] Fixed a closed drawer to not peek out from the window edge + while resizing the window. + * [QTBUG-54629] Fixed a bug in drag margin handling that allowed the user + to sometimes drag out the drawer even if dragging was disabled. + * Fixed a bug in the calculation of swipe velocity. + * [QTBUG-54800] Fixed conflicts between multiple drawers. + * [QTBUG-54794][QTBUG-55022] Fixed conflicts between drawers and other + popups. + * [QTBUG-55703] Fixed the stacking order of multiple drawers and popups. + * [QTBUG-55995] Fixed flickering on touch release. + * [QTBUG-55360] Made it possible to control the vertical position of + a horizontal drawer, and vice versa. This allows placing a drawer below + a header/toolbar, for instance. + + - Page: + * [QTBUG-55143] Fixed the content layout to take header and footer + visibility into account. + + - RangeSlider: + * [QTBUG-55015] Fixed step size and snap mode handling with ranges starting + from a non-zero value. + + - Slider: + * [QTBUG-54140] Fixed step size and snap mode handling with ranges starting + from a non-zero value. + + - Popup: + * [QTBUG-56025] Fixed to respect explicitly set width and height. + * [QTBUG-53419] Fixed hover events to not leak through popups or modal + background dimming. + * [QTBUG-55004] Fixed popups to appear above the QML-based dialogs from + QtQuick.Dialogs 1.x. + * [QTBUG-55347] Fixed a crash on dynamic parent item changes. + * [QTBUG-54797] Fixed the background dimming to update accordingly on + dynamic changes to the dim and modal properties. + * [QTBUG-55729] Fixed popups to close on touch events when using a plain + Window instead of ApplicationWindow. + * [QTBUG-54913] Fixed hover event delivery with plain Window. + * [QTBUG-55769] Fixed wheel events to not leak through modal background + dimming. + + - ScrollIndicator: + * [QTBUG-55620] Fixed to respect the paddings when overshooting, so that + the indicator doesn't move outside the bounds of the attached flickable. + + - SpinBox: + * [QTBUG-56215] Fixed valueFromText() to not get called for non-editable + spinboxes. + + - StackView: + * Fixed the "unknown argument" warning when popping down to the current + item. + * [QTBUG-54552] Fixed to claim ownership of dynamically created items. + * [QTBUG-56158] Fixed a crash in pop() when attempting to pop an item that + is still activating from a previous popup. + * [QTBUG-55749] Allowed loading remote URLs. + + - SwipeDelegate: + * [QTBUG-54648] Fixed the use of buttons or other interactive controls at + the sides or behind the delegate. + * [QTBUG-54660][QTBUG-54780] Fixed content re-layouting issues. + * [QTBUG-55040] Added a warning for conflicting anchors. + + - Switch: + * [QTBUG-55647] Fixed focus on tap/click over the handle. + * Fixed missing pressed() and released() signals. + * Fixed dragging of the handle on touch. + + - SwitchDelegate: + * Made the handle draggable. + + - TabBar: + * [QTBUG-55129] Fixed a bug which caused ghost items, from outside the + tabbar's visible area, to appear in the tabbar. + * [QTBUG-55129] Improved the behavior of flickable tabs. + * [QTBUG-56265] Fixed mixing of fixed and implicitly resized tabs. + * Fixed to re-layout as appropriate when tabs are resized at run-time. + + - TabButton: + * [QTBUG-55129] Fixed implicit width calculation. + + - TextArea: + * [QTBUG-54615] Fixed mouse double click to select a word. + * [QTBUG-54897] Fixed to not intercept input events outside the visual + bounds when attached to a Flickable. + * Set a caret or ibeam mouse cursor, indicating that the control can accept + and display text input. + + - TextField: + * [QTBUG-54615] Fixed mouse double click to select a word. + * Set a caret or ibeam mouse cursor, indicating that the control can accept + and display text input. + * [QTBUG-55684] Improved the implicit size calculation. + + - ToolTip: + * Fixed the shared tooltip instance to get destructed when the associated + QML engine is destructed. + * [QTBUG-55347] Fixed attached properties to apply to the shared tooltip + instance only when the shared tooltip is visible for the respective item + that the property is attached to. + * [QTBUG-54206] Fixed a bug that caused the shared tooltip to sometimes + fade out when it should stay visible. + * [QTBUG-55572] Fixed delay and visibility handling for standlone tooltips. + +Material +-------- + + - Fixed (optional) elevation effects for Frame, GroupBox, Pane, and TabBar. + - Fixed SpinBox text color in disabled state. + - [QTBUG-54269] Added documentation for Material.Shade and the related + parameter of Material.color(). + - [QTBUG-54935] Fixed white text on white background in ComboBox that is + placed in a ToolBar. + - [QTBUG-54472] Fixed rendering issues with multiple BusyIndicators. + - [QTBUG-55366] Fixed the default foreground and background colors read from + :/qtquickcontrols2.conf or environment variables. + - [QTBUG-55687] Fixed several issues with accent and background inheritance. + - Fixed the accent color, where the shade depends on the theme, to update as + appropriate on run-time theme changes. + - [QTBUG-52631] Fixed style inheritance issues with popups. + - [QTBUG-53266] Fixed the background color of dialogs in the dark theme. + - Fixed text cursor blink period. + +Universal +--------- + + - Fixed Dial press effect. + - [QTBUG-52738] Fixed editor colors in the dark theme. + - [QTBUG-55366] Fixed the default foreground and background colors read from + :/qtquickcontrols2.conf or environment variables. diff --git a/dist/archived/qtquickcontrols2/changes-5.8.0 b/dist/archived/qtquickcontrols2/changes-5.8.0 new file mode 100644 index 00000000000..5b431fca05b --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.8.0 @@ -0,0 +1,208 @@ +Qt 5.8 introduces many new features and improvements as well as bugfixes +over the 5.7.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + + http://doc.qt.io/qt-5/index.html + +The Qt version 5.8 series is binary compatible with the 5.7.x series. +Applications compiled for 5.7 will continue to run with 5.8. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - Control: + * Control::hoverEnabled has been made to inherit to children, to make it + possible to disable hover effects for a tree of controls in one place. + + - Tumbler: + * Changed the default value of visibleItemCount to 5 to make it visually + clearer that it's a Tumbler. + * [QTBUG-53587] Changed the default value of wrap to be false when count + is less than visibleItemCount. Explicitly setting wrap overrides this + behavior. + +**************************************************************************** +* Controls * +**************************************************************************** + + - AbstractButton: + * A plain AbstractButton now calculates its implicit size based on the + implicit size of the content item plus paddings, and the implicit size + of the background item. + * [QTBUG-51554] The checkable property has been made accessible from + QML. Previously it was only exposed for Button and MenuItem, but it is + now available for any AbstractButton to make it possible to create + custom QML-based checkable buttons. + * [QTBUG-57085] Fixed auto-repeat to not cancel on the tiniest mouse/touch + move, but keep repeating until moved outside the button. + * Fixed press-and-hold for checkable buttons to not toggle the checked + state on release after press-and-hold. + + - ButtonGroup: + * Added clicked(AbstractButton) signal for centralized click handling for + grouped buttons. + + - ComboBox: + * [QTBUG-56884] Added handling for Home and End keys. + * [QTBUG-56884] Added missing keyboard search functionality. + * [QTBUG-54935] Added a flat property that provides more suitable looks + for using ComboBox in a ToolBar. + + - Container: + * Added incrementCurrentIndex() and decrementCurrentIndex() methods for + changing the current index without losing its property binding. + * A plain Container now calculates its implicit size based on the + implicit size of the content item plus paddings, and the implicit size + of the background item. + + - Control: + * A plain Control now calculates its implicit size based on the implicit + size of the content item plus paddings, and the implicit size of the + background item. + + - Dialog: + * Added a new Dialog type to provide convenience for handling dialog + popups. Dialog integrates with DialogButtonBox, and provides convenient + accepted() and rejected() signals. + + - DialogButtonBox: + * Added DialogButtonBox to provide convenience for handling dialog buttons. + DialogButtonBox is able to create a set of standard buttons with a single + line of QML code, and provides convenient accepted() and rejected() signals. + + - Drawer: + * [QTBUG-55360] Made it possible to control the vertical position of a + horizontal drawer, and vice versa. This allows placing a drawer below + a header/toolbar, for instance. + + - MenuSeparator: + * [QTBUG-54862] Added MenuSeparator to visually distinguish between groups + of items in a menu. + + - Page: + * [QTBUG-56709] Page has been made to calculate its implicit size based + on the implicit size of the header, content, and footer plus paddings, + and the implicit size of the background item. + + - Popup: + * [QTBUG-56025] Fixed to respect explicitly set width and height. + * [QTBUG-56562] The QML Shortcut type from QtQuick has been fixed to + respect modal popups from QtQuick Controls 2. + * [QTBUG-56755] Fixed binding loops with size-dependent positioning. + + - RangeSlider: + * [QTBUG-50003] Added first.hovered and second.hovered properties that + hold whether the respective handles are hovered. + + - RoundButton: + * [QTBUG-54967] Added RoundButton. + + - Slider: + * [QTBUG-53847] Added valueAt() method for converting any position to a + value in the slider's range. It is also possible to use valueAt() to get + continuous value updates. + + - SpinBox: + * [QTBUG-50003] Added up.hovered and down.hovered properties that hold + whether the respective buttons are hovered. + * [QTBUG-57085] Fixed auto-repeat to not cancel on the tiniest mouse/touch + move, but keep repeating until moved outside the button. + + - StackView: + * Added attached StackView.activated(), StackView.deactivated(), + StackView.activating(), and StackView.deactivating() signals that are + convenient for initializing and cleaning up item-specific resources. + * [QTBUG-55405] Added StackView.removed() attached signal to provide a + way to delete items that StackView won't. + * Made it possible to choose the visual transition type for any operation. + This allows using for example push and pop transitions with replace(), + which allows implementing an "infinite" back and forward navigation + pattern while keeping the amount of instantiated items constant. + + - SwipeDelegate: + * [QTBUG-54651] Added swipe.close() for setting swipe.position to 0. + * [QTBUG-54651] Added swipe.completed() for responding to completion of + swipes. + * [QTBUG-54651] Added attached SwipeDelegate.pressed property and + SwipeDelegate.clicked() signal for detecting when non-interactive + left/right/behind items are pressed and clicked. + * [QTBUG-56312][QTBUG-57285] Fixed spurious clicked() signal emission when + released outside the delegate. + * [QTBUG-57271] Fixed swipes that begin over a child item of a delegate. + + - SwipeView: + * Added SwipeView.isNextItem and SwipeView.isPreviousItem attached + properties to make it straight-forward to use Loader for unloading + pages that are outside the reach. + * [QTBUG-54268] Added interactive property for controlling whether swipe + interaction is enabled. + + - TextArea: + * [QTBUG-51009] Added pressed() and released() signals. + + - TextField: + * [QTBUG-51009] Added pressed() and released() signals. + * Aligned the name of the pressAndHold() argument with TextArea + + - ToolSeparator: + * [QTBUG-54862] Added ToolSeparator to visually distinguish between groups + of items in a toolbar by separating them with a line. It can be used in + horizontal or vertical toolbars. + + - Tumbler: + * [QTBUG-53587] Added wrap property to control whether or not tumbler + wraps when it reaches the top and bottom. + +**************************************************************************** +* Styles * +**************************************************************************** + + - Added support for specifying the fallback style for custom styles via + :/qtquickcontrols2.conf, QT_QUICK_CONTROLS_FALLBACK_STYLE or + QQuickStyle::setFallbackStyle(). + +Material +-------- + + - [QTBUG-50003] Implemented ripple and hover effects. + - Fixed (optional) elevation effects for Frame, GroupBox, Pane, and + TabBar. + - Added Material.System theme enum value, that can be used to let the + Material style choose either the light or dark theme based on the + system theme colors. + +Universal +--------- + + - [QTBUG-50003] Implemented hover effects + - Added Universal.System theme enum value, that can be used to let the + Universal style choose either the light or dark theme based on the + system theme colors. + +**************************************************************************** +* Platform * +**************************************************************************** + + - Introduced a new experimental Qt Labs Platform module that provides the + following native (Qt Widgets fallback when not available) QML types: + * ColorDialog + * FileDialog + * FolderDialog + * FontDialog + * Menu + * MenuBar + * MenuItem + * MenuItemGroup + * MenuSeparator + * MessageDialog + * StandardPaths + * SystemTrayIcon diff --git a/dist/archived/qtquickcontrols2/changes-5.9.0 b/dist/archived/qtquickcontrols2/changes-5.9.0 new file mode 100644 index 00000000000..39b064fb92f --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.9.0 @@ -0,0 +1,208 @@ +Qt 5.9 introduces many new features and improvements as well as bugfixes +over the 5.8.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - Added multi-touch support for buttons and sliders. It is now possible to + touch-interact with multiple sliders and buttons at the same time. + - By popular demand, Slider, RangeSlider, and Dial have been changed to + report live value updates by default. This can be disabled by setting the + "live" property to false. + - [QTBUG-59920] Sliders and Dials now react immediately when using a + mouse. Now the initial drag threshold applies only on touch, to avoid + conflicting with flickables. + - [QTBUG-58667] ScrollBar now reacts immediately when using a mouse. + - [QTBUG-59629] Set explicit cursors on all interactive controls. + +**************************************************************************** +* Controls * +**************************************************************************** + + - AbstractButton: + * Added support for multi-touch. + * [QTBUG-57203] Added a toggled() signal that is emitted whenever a + checkable button is interactively toggled by the user by using either + touch, mouse, or keys. + + - ApplicationWindow: + * [QTBUG-58932] The "data" property has been renamed to contentData, as it + was documented. Notice that a "data" property still exists in QML + Window, but is no longer overshadowed in ApplicationWindow. + + - Control: + * [QTBUG-50992] Resolved the "Object destroyed during incubation" issue + that occurred randomly when customizing built-in delegates. + + - ComboBox: + * [QTBUG-53876] Added "editable" property. + * Added "down" property. + + - DelayButton: + * Added DelayButton that incorporates a delay before the button becomes + activated, to prevent accidental triggers. + + - Dial: + * Added a "live" property that determines whether the dial provides live + updates for the "value" property while the handle is dragged. + * Added support for wheel handling when wheelEnabled is set to true. + * [QTBUG-57203] Added a moved() signal that is emitted whenever the dial + is interactively moved by the user by using either touch, mouse, or + keys. + * Fixed handling of inverted wheel events (natural touchpad scrolling + direction on macOS). + + - Drawer: + * [QTBUG-53169] Added "interactive" property that specifies whether the + drawer reacts to swipes. This can be used to make drawer a + non-closable persistent side-bar. + + - Menu: + * Fixed populating Menus with a Repeater. + + - Popup: + * Allowed passing a Window as a parent when creating dynamic Popup + instances using eg. Component.createObject(). Previously, Popup + assumed the parent to be an Item, and would complain "cannot find + any window to open popup in" if a Window was passed. + * [QTBUG-58196] Allowed dynamic window changes after construction. + * Fixed the CloseOnRelease close policy for non-modal popups. + + - RangeSlider: + * Added a "live" property that determines whether the range slider + provides live updates for the first.value and second.value properties + while the respective handle is dragged. + + - ScrollBar: + * [QTBUG-56569] Added snapMode property for incremental or discrete + scrolling. + * Added an "interactive "property. A non-interactive ScrollBar is visually + and behaviorally similar to ScrollIndicator. This property is useful + for switching between typical mouse- and touch-orientated UIs with + interactive and non- interactive scroll bars, respectively. + * Added a "policy" property, which holds whether the scroll bar is shown + always/never/as needed (default). + + - ScrollView: + * Added ScrollView. On touch, ScrollView enables flicking and makes + the scroll bars non-interactive. When interacted with a mouse device, + flicking is disabled and the scroll bars are interactive. + + - Slider: + * Added support for multi-touch. + * Added a "live" property that determines whether the slider provides live + updates for the "value" property while the handle is dragged. + * [QTBUG-57203] Added a moved() signal that is emitted whenever the + slider is interactively moved by the user by using either touch, + mouse, wheel, or keys. + * Fixed handling of inverted wheel events (natural touchpad scrolling + direction on macOS). + + - SpinBox: + * [QTBUG-56837] Added inputMethodHints and inputMethodComposing + properties for controlling the input method when using editable spin + boxes. + * [QTBUG-57203] Added a valueModified() signal that is emitted whenever + the value of a spin box has been interactively modified by the user by + using either touch, mouse, wheel, or keys. + * [QTBUG-60356] Forwarded focus to the internal editor of an editable + spin box. + + - StackView: + * [QTBUG-56801] Added attached "StackView.visible" property that can be + used to control whether items below the top- most item are kept + visible. + * [QTBUG-57266] Prevented pushing duplicate items. + * [QTBUG-59034] Fixed pop/replace exit transition leak, sometimes leading + to random crashes since a transition could have been left running in the + background at destruction time. + * [QTBUG-59098] Prevented StackView filtering mouse ungrab events to avoid + MouseAreas being stuck in the pressed state. + * [QTBUG-59634] Improved component creation errors by using the standard + QML warning system that gives a context/location for the error. + + - SwipeDelegate: + * [QTBUG-57192] Added "swipe.enabled" property to allow disabling of + swiping. + * Added swipe.open(side) method that can be used to programmatically + open the side item on the specified side, which can be either + SwipeDelegate.Left or SwipeDelegate.Right. + * Added swipe.opened() and swipe.closed() signals, which are emitted + when the delegate has been opened or closed by swipe, and the + respective transition has finished. + * Added a swipe.transition property that holds the transition that is + applied when a swipe is released, or swipe.open() or swipe.close() is + called. + + - SwipeView: + * [QTBUG-56031] Added "orientation" property. + + - TabBar: + * [QTBUG-57858] Added contentWidth and contentHeight properties that are + automatically calculated based on the total size of the tab items, but + can be manually overridden if desired. This fixes an issue that TabBar + was not able to reliably calculate an implicit size, and could in + certain scenarios enter an infinite loop due to a circular dependency + between the items' sizes and the tabbar's size. + + - TextArea: + * [QTBUG-55999] Fixed the horizontal alignment of the placeholder text + in right-to-left UIs. + * TextArea has been made to work inside ScrollView, providing necessary + scroll bars out of the box. + + - TextField: + * [QTBUG-55999] Fixed the horizontal alignment of the placeholder text + in right-to-left UIs. + + - Tumbler: + * Added a "moving" property that describes whether the tumbler is + currently moving, due to the user either dragging or flicking the + tumbler. + +**************************************************************************** +* Styles * +**************************************************************************** + + - Added support for a QT_QUICK_CONTROLS_STYLE_PATH environment variable, + which can be used to specify lookup paths for Qt Quick Controls 2 + styles. This allows device manufacturers and Linux distributions to + specify a system-wide style installation folder that may be located + outside the Qt installation tree. + - Added support for a QT_QUICK_CONTROLS_STYLE_CONF environment variable, + which can be used to override the default location of the Qt Quick + 2 Controls configuration file (:/qtquickcontrols2.conf). + - QQuickStyle: + * Added availableStyles() method that returns the list of available + built-in styles. + +Default +-------- + - Visualized RangeSliders's range. + +Material +-------- + - [QTBUG-58797] Fixed cursor visibility for read-only editors. + +**************************************************************************** +* Platform * +**************************************************************************** + + - Menu: + * Fixed sub-menu handling when using the Qt Widgets fallbacks on + platforms that do not support native menus (Windows, for example). diff --git a/dist/archived/qtquickcontrols2/changes-5.9.1 b/dist/archived/qtquickcontrols2/changes-5.9.1 new file mode 100644 index 00000000000..46c62047563 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.9.1 @@ -0,0 +1,75 @@ +Qt 5.9.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* General * +**************************************************************************** + + - [QTBUG-58571] Enabled the use of QML caching at build time. + - [QTBUG-61144] Added a configure feature for disabling multi- touch + support (configure -no-feature-quicktemplates2-multitouch). + +**************************************************************************** +* Controls * +**************************************************************************** + + - ApplicationWindow: + * [QTBUG-60893] Fixed access to revisioned members in base classes. + + - ComboBox: + * [QTBUG-60684] Fixed an empty popup being shown after model is cleared. + + - Container: + * [QTBUG-61310] Fixed a crash that occurred with Repeater under certain + circumstances. + + - Menu: + * Fixed key navigation to skip separators. + + - Page: + * [QTBUG-61109] Fixed the initial content layouting of dynamically created + Page instances. + + - Popup: + * [QTBUG-61114] Fixed font inheritance for popups. + + - SpinBox: + * [QTBUG-61426] Fixed valueModified() to get emitted on repeated value + changes during long press. + + - StackView: + * Fixed clear() to not emit depthChanged() when the view is empty. + +**************************************************************************** +* Styles * +**************************************************************************** + + - QQuickStyle: + * [QTBUG-60973] Fixed availableStyles() to exclude debug symbol folders + (.dSYM) on macOS. + +Default +-------- + - RangeSlider: + * Fixed the second handle to visualize its pressed state. + +Material & Universal +-------------------- + - ScrollBar: + * Fixed flashing when calling decrease() or increase() for key navigation. diff --git a/dist/archived/qtquickcontrols2/changes-5.9.2 b/dist/archived/qtquickcontrols2/changes-5.9.2 new file mode 100644 index 00000000000..370f77cb1f6 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.9.2 @@ -0,0 +1,79 @@ +Qt 5.9.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Controls * +**************************************************************************** + + - BusyIndicator: + * [QTBUG-61785] Fixed busy indicators to not block touch events. + + - Control: + * [QTBUG-63119] Fixed font inheritance in item views. + + - Drawer: + * [QTBUG-61581] Fixed multi-touch leaking through modal overlay. + * [QTBUG-59652] Fixed non-modal drawer drag/swipe open and close. + + - Menu: + * [QTBUG-61608] Fixed press-and-hold support by removing OnReleaseOutside + from the default close policy, to avoid closing on release when opened + from an onPressAndHold signal handler. + + - Popup: + * [QTBUG-61698] Fixed multi-touch leaking through modal overlay + * Fixed focus handling for chained popups. When a popup is closed, focus + is now restored to the next popup in chain instead of transferring focus + to the window content. + * [QTBUG-62158] Fixed popups to take Window::contentOrientation into + account. + + - PageIndicator: + * Fixed interactive page indicators to work on touch. + * [QTBUG-61785] Fixed non-interactive page indicators to not block touch + events. + + - ScrollIndicator: + * [QTBUG-61785] Fixed scroll indicators to not block touch events. + + - SpinBox: + * [QTBUG-61426] Fixed to emit valueModified() on long press. + * [QTBUG-62508] Fixed initial value validation. + + - StackView: + * [QTBUG-62153] Fixed a crash that would occur when pushing new items + from a StackView.onRemoved signal handler. + * Fixed resolving of the initialItem URL. + + - TextArea: + - TextField: + * [QTBUG-62854] Improved the Default style. + + - ToolTip: + * [QTBUG-60492] Fixed tooltips to not block shortcuts. + + - Tumbler: + * [QTBUG-61374] Fixed a regression with currentIndex and currentItem. + +**************************************************************************** +* Calendar * +**************************************************************************** + + - MonthGrid: + * [QTBUG-61585] Fixed the clicked() signal to be emitted on touch. diff --git a/dist/archived/qtquickcontrols2/changes-5.9.3 b/dist/archived/qtquickcontrols2/changes-5.9.3 new file mode 100644 index 00000000000..8879b9391a7 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.9.3 @@ -0,0 +1,52 @@ +Qt 5.9.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.9.3 Changes * +**************************************************************************** + + - ButtonGroup: + * [QTBUG-62946][QTBUG-63470] Fixed an issue in tracking of the currently + checked button that caused a crash under certain circumstances. + + - DialogButtonBox: + * [QTBUG-63898] Fixed a potential crash when using DialogButtonBox without + a contentItem. + + - Popup: + * [QTBUG-63672] Fixed a dangling QML context that was causing random + crashes in the QML engine debug service. + + - ScrollView: + * [QTBUG-62325] Fixed a binding loop when using a wrapping TextArea as + content. + + - StackView: + * Fixed a resource leak that occurred when the creation of the initial + item failed. + + - TextArea & TextField: + * [QTBUG-62854] Improved the Default style. + - Removed top-level opacity assignments to allow full customization. + - Added more distinction between disabled and placeholder text. + - Made disabled text more visible. + + - ToolTip: + * [QTBUG-63644] Disabled hover to avoid tooltips blocking hover events, + which are typically used for showing tooltips on desktop platforms. diff --git a/dist/archived/qtquickcontrols2/changes-5.9.4 b/dist/archived/qtquickcontrols2/changes-5.9.4 new file mode 100644 index 00000000000..3ac6f4a5ee8 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.9.4 @@ -0,0 +1,63 @@ +Qt 5.9.4 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - As a fix to QTBUG-50992, execution of delegates, such as contentItem and + background, is deferred until the construction of a control is complete, + or a delegate is accessed. Consequently, if a delegate is replaced with + a custom delegate, the default delegate is not created. Previously, when + a default delegate was replaced by a custom delegate, the default + delegate was nevertheless created and destroyed during the construction + of the control. + +**************************************************************************** +* Controls * +**************************************************************************** + + - [QTBUG-64548] Fixed shortcuts in QQuickWidget + + - [QTBUG-65016] Fixed QQuickStyle::setFallbackStyle() in static builds + + - [QTBUG-50992] Fixed a bug which caused delegates of customized controls + to often be "destroyed during incubation" when asynchronously incubated + by item views or asynchronous loaders. + + - BusyIndicator: + * [QTBUG-62874] Fixed busy animation in QQuickWidget + + - ProgressBar: + * [QTBUG-62874] Fixed indeterminate animation in QQuickWidget + + - StackView: + * [QTBUG-65084] Fixed to not block touch events. + + - SwipeView: + * [QTBUG-62110] Fixed slow swiping in large views + + - ToolButton: + * [QTBUG-65052] Fixed round ripple for square buttons in the Material style + + - Tumbler: + * [QTBUG-65165] Made currentIndex animations take a constant amount of + time (1 second) regardless of how many items are in the model. This + prevents Tumblers with large amounts of items from scrolling too + slowly when changing the currentIndex. diff --git a/dist/archived/qtquickcontrols2/changes-5.9.5 b/dist/archived/qtquickcontrols2/changes-5.9.5 new file mode 100644 index 00000000000..82842addd81 --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.9.5 @@ -0,0 +1,56 @@ +Qt 5.9.5 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.9.5 Changes * +**************************************************************************** + +Controls +-------- + + - Control: + * [QTBUG-65880] Fixed a bug in deferred execution, that caused the + background item to not follow the size of the control under certain + circumstances, leading to a visually missing background. + * [QTBUG-66133] Fixed focus scope controls, such as Frame, GroupBox, + Page, and Pane, to respect click and wheel focus policies by clearing + a potential sub-focus child. This makes it possible to close the virtual + keyboard by clicking the background of a Pane that has Qt.ClickFocus + set as its focusPolicy, for example. + + - ComboBox: + * [QTBUG-65962] Fixed a bug in deferred execution, that caused the popup's + bindings to not get finalized under certain circumstances, leading to + a visually missing popup. + + - Popup: + * [QTBUG-66113] Fixed restoring focus to popups that did not request + focus when opened, but gained focus later. + +Platform +-------- + + - Menu: + * [QTBUG-55251] Fixed opening position on high-DPI screens. + +Third-Party Code +---------------- + + - [QTBUG-65409] Document constants from AngularJS in + src/imports/controls/material/ElevationEffect.qml diff --git a/dist/archived/qtquickcontrols2/changes-5.9.6 b/dist/archived/qtquickcontrols2/changes-5.9.6 new file mode 100644 index 00000000000..9684e2b10fe --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-5.9.6 @@ -0,0 +1,39 @@ +Qt 5.9.6 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0 through 5.9.5. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.9.6 Changes * +**************************************************************************** + +Controls +-------- + + - Label: + * [QTBUG-65880] Fixed a background size regression caused by deferred + execution. + + - TextArea: + * [QTBUG-67334] Fixed the background to not scroll when TextArea is + placed in a ScrollView. + * [QTBUG-65880] Fixed a background size regression caused by deferred + execution. + + - TextField: + * [QTBUG-65880] Fixed a background size regression caused by deferred + execution. diff --git a/dist/archived/qtquickcontrols2/changes-6.0.0 b/dist/archived/qtquickcontrols2/changes-6.0.0 new file mode 100644 index 00000000000..f1f569f39be --- /dev/null +++ b/dist/archived/qtquickcontrols2/changes-6.0.0 @@ -0,0 +1,17 @@ +Qt 6.0.0 is a new major version release of Qt. It is not binary compatible with +earlier Qt releases. + +The goal has been to retain as much source compatibility with Qt 5.15 as +possible, but some changes were inevitable to make Qt a better framework. + +To make it easier to port to Qt 6.0, we have created a porting guide to +summarize those changes and provide guidance to handle them. In the guide, you +can find links to articles about changes that may affect your application and +help you transition from Qt 5.15 to Qt 6.0: + +https://doc.qt.io/qt-6/portingguide.html + +For more details refer to the online documentation of Qt 6.0: + +https://doc.qt.io/qt-6/index.html + diff --git a/examples/.prev_CMakeLists.txt b/examples/.prev_CMakeLists.txt deleted file mode 100644 index c2ccea65c11..00000000000 --- a/examples/.prev_CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# Generated from examples.pro. - -qt_examples_build_begin() - -add_subdirectory(qml) -if(TARGET Qt::QuickTest) - add_subdirectory(qmltest) -endif() -if(TARGET Qt::Quick) - add_subdirectory(quick) -endif() - -qt_examples_build_end() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 20338e9f6ce..d9fabda3c44 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,3 +1,5 @@ +find_package(Qt6 COMPONENTS Sql) # special case + qt_examples_build_begin(EXTERNAL_BUILD) add_subdirectory(qml) @@ -7,5 +9,8 @@ endif() if(TARGET Qt::Quick) add_subdirectory(quick) endif() +if(TARGET Qt::QuickTemplates2) + add_subdirectory(quickcontrols2) +endif() qt_examples_build_end() diff --git a/examples/examples.pro b/examples/examples.pro index 0712e81552d..4cdc5f27f9f 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs qtHaveModule(qmltest): SUBDIRS += qmltest SUBDIRS += qml -qtHaveModule(quick): SUBDIRS += quick +qtHaveModule(quick): SUBDIRS += quick quickcontrols2 diff --git a/examples/qml/.prev_CMakeLists.txt b/examples/qml/.prev_CMakeLists.txt deleted file mode 100644 index 0ec4c9b39d1..00000000000 --- a/examples/qml/.prev_CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# Generated from qml.pro. - -add_subdirectory(referenceexamples) -add_subdirectory(tutorials) -add_subdirectory(shell) -if(TARGET Qt::Quick) - add_subdirectory(qmlextensionplugins) - add_subdirectory(xmlhttprequest) -endif() -if(QT_FEATURE_qml_network AND TARGET Qt::Quick) - add_subdirectory(networkaccessmanagerfactory) -endif() diff --git a/examples/qml/CMakeLists.txt b/examples/qml/CMakeLists.txt index 61e550762dd..7f84d6e2571 100644 --- a/examples/qml/CMakeLists.txt +++ b/examples/qml/CMakeLists.txt @@ -1,5 +1,6 @@ # Generated from qml.pro. +qt_internal_add_example(dynamicscene) add_subdirectory(referenceexamples) add_subdirectory(tutorials) qt_internal_add_example(shell) diff --git a/examples/qml/doc/src/qml-extending.qdoc b/examples/qml/doc/src/qml-extending.qdoc index c9922ebd451..36d7ee290cf 100644 --- a/examples/qml/doc/src/qml-extending.qdoc +++ b/examples/qml/doc/src/qml-extending.qdoc @@ -168,10 +168,12 @@ developed in the previous examples into two types - a \c Boy and a \c Girl. \snippet referenceexamples/coercion/person.h 0 The Person class remains unaltered in this example and the Boy and Girl C++ -classes are trivial extensions of it. As an example, the inheritance used here -is a little contrived, but in real applications it is likely that the two -extensions would add additional properties or modify the Person classes -behavior. +classes are trivial extensions of it. The types and their QML name are +registered with the QML engine. + +As an example, the inheritance used here is a little contrived, but in real +applications it is likely that the two extensions would add additional +properties or modify the Person classes behavior. \section2 Define People as a Base Class @@ -187,15 +189,6 @@ to be registered with the QML engine, so that it can be used as a property type and other types can be coerced to it. This is what the QML_UNCREATABLE macro does. -\section2 Define Boy and Girl - -The implementation of Boy and Girl is trivial. - -\snippet referenceexamples/coercion/person.cpp 1 - -All that is necessary is to implement the constructor, and to register the types -and their QML name with the QML engine. - \section1 Running the Example The BirthdayParty type has not changed since the previous example. The @@ -271,6 +264,12 @@ This example builds on: \brief Attached Properties. \ingroup qmlextendingexamples +This example demonstrates how to create custom +\l {Attached Properties and Attached Signal Handlers} {attached properties}. +For a more in-depth description on how one can create attached properties, +see \l {Providing Attached Properties}. + + This example builds on: \list \li \l {Extending QML - Grouped Properties Example} diff --git a/examples/qml/dynamicscene/CMakeLists.txt b/examples/qml/dynamicscene/CMakeLists.txt new file mode 100644 index 00000000000..623ab1f78bc --- /dev/null +++ b/examples/qml/dynamicscene/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.16) +project(dynamicscene LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/dynamicscene") + +find_package(Qt6 COMPONENTS Core Gui Quick Qml) + +qt_add_executable(dynamicsceneexample WIN32 MACOSX_BUNDLE main.cpp) + +target_link_libraries(dynamicsceneexample PUBLIC + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +qt_add_qml_module(dynamicsceneexample + URI dynamicscene + VERSION 1.0 + QML_FILES + "GenericSceneItem.qml" + "PaletteItem.qml" + "PerspectiveItem.qml" + "Sun.qml" + "dynamicscene.qml" + "itemCreation.js" + RESOURCES + "images/NOTE" + "images/face-smile.png" + "images/moon.png" + "images/rabbit_brown.png" + "images/rabbit_bw.png" + "images/star.png" + "images/sun.png" + "images/tree_s.png" +) + +install(TARGETS dynamicsceneexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/qml/dynamicscene/content/GenericSceneItem.qml b/examples/qml/dynamicscene/GenericSceneItem.qml similarity index 97% rename from examples/qml/dynamicscene/content/GenericSceneItem.qml rename to examples/qml/dynamicscene/GenericSceneItem.qml index 3c83169c7af..bc09fd58174 100644 --- a/examples/qml/dynamicscene/content/GenericSceneItem.qml +++ b/examples/qml/dynamicscene/GenericSceneItem.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick Image { property bool created: false diff --git a/examples/qml/dynamicscene/content/PaletteItem.qml b/examples/qml/dynamicscene/PaletteItem.qml similarity index 97% rename from examples/qml/dynamicscene/content/PaletteItem.qml rename to examples/qml/dynamicscene/PaletteItem.qml index ca734a5dba0..d6df4be870f 100644 --- a/examples/qml/dynamicscene/content/PaletteItem.qml +++ b/examples/qml/dynamicscene/PaletteItem.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick import "itemCreation.js" as Code Image { diff --git a/examples/qml/dynamicscene/content/PerspectiveItem.qml b/examples/qml/dynamicscene/PerspectiveItem.qml similarity index 97% rename from examples/qml/dynamicscene/content/PerspectiveItem.qml rename to examples/qml/dynamicscene/PerspectiveItem.qml index a7123580007..d02a188043e 100644 --- a/examples/qml/dynamicscene/content/PerspectiveItem.qml +++ b/examples/qml/dynamicscene/PerspectiveItem.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick Image { id: rootItem diff --git a/examples/qml/dynamicscene/content/Sun.qml b/examples/qml/dynamicscene/Sun.qml similarity index 98% rename from examples/qml/dynamicscene/content/Sun.qml rename to examples/qml/dynamicscene/Sun.qml index 0e70f3b5dbc..062a6065e08 100644 --- a/examples/qml/dynamicscene/content/Sun.qml +++ b/examples/qml/dynamicscene/Sun.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick Image { id: sun diff --git a/examples/qml/dynamicscene/content/Button.qml b/examples/qml/dynamicscene/content/Button.qml deleted file mode 100644 index d558ef76089..00000000000 --- a/examples/qml/dynamicscene/content/Button.qml +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Rectangle { - id: container - - property variant text - signal clicked - - height: text.height + 10; width: text.width + 20 - border.width: 1 - radius: 4 - antialiasing: true - - gradient: Gradient { - GradientStop { - position: 0.0 - color: !mouseArea.pressed ? "#eeeeee" : "#888888" - } - GradientStop { - position: 1.0 - color: !mouseArea.pressed ? "#888888" : "#333333" - } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - onClicked: container.clicked() - } - - Text { - id: text - anchors.centerIn:parent - font.pointSize: 10 - text: parent.text - } -} diff --git a/examples/qml/dynamicscene/dynamicscene.qml b/examples/qml/dynamicscene/dynamicscene.qml index d197b952358..0775d7593e5 100644 --- a/examples/qml/dynamicscene/dynamicscene.qml +++ b/examples/qml/dynamicscene/dynamicscene.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,9 +48,9 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 -import "content" +import QtQuick +import QtQuick.Particles +import QtQuick.Controls Item { id: window @@ -82,7 +82,7 @@ Item { dialogAnim.start(); } - Text { + Label { id: dialogText x: 3; y: 3 font.pixelSize: 14 @@ -119,7 +119,7 @@ Item { ImageParticle { id: stars - source: "content/images/star.png" + source: "images/star.png" groups: ["stars"] opacity: .5 } @@ -156,7 +156,7 @@ Item { anchors.centerIn: parent spacing: 8 - Text { text: "Drag an item into the scene." } + Label { text: "Drag an item into the scene." } Rectangle { width: palette.width + 10; height: palette.height + 10 @@ -170,37 +170,37 @@ Item { PaletteItem { anchors.verticalCenter: parent.verticalCenter componentFile: "Sun.qml" - source: "content/images/sun.png" + source: "images/sun.png" image: "images/sun.png" } PaletteItem { anchors.verticalCenter: parent.verticalCenter componentFile: "GenericSceneItem.qml" - source: "content/images/moon.png" + source: "images/moon.png" image: "images/moon.png" } PaletteItem { anchors.verticalCenter: parent.verticalCenter componentFile: "PerspectiveItem.qml" - source: "content/images/tree_s.png" + source: "images/tree_s.png" image: "images/tree_s.png" } PaletteItem { anchors.verticalCenter: parent.verticalCenter componentFile: "PerspectiveItem.qml" - source: "content/images/rabbit_brown.png" + source: "images/rabbit_brown.png" image: "images/rabbit_brown.png" } PaletteItem { anchors.verticalCenter: parent.verticalCenter componentFile: "PerspectiveItem.qml" - source: "content/images/rabbit_bw.png" + source: "images/rabbit_bw.png" image: "images/rabbit_bw.png" } } } - Text { text: "Active Suns: " + window.activeSuns } + Label { text: "Active Suns: " + window.activeSuns } } } @@ -226,7 +226,7 @@ Item { Row { height: createButton.height spacing: 8 - Text { text: "Custom QML:"; anchors.verticalCenter: parent.verticalCenter } + Label { text: "Custom QML:"; anchors.verticalCenter: parent.verticalCenter } Button { id: popupButton text: popupToolbox.poppedUp ? "Hide" : "Show" @@ -249,7 +249,7 @@ Item { Rectangle { width: 360; height: 240 - TextEdit { + TextArea { id: qmlText anchors.fill: parent; anchors.margins: 5 readOnly: false @@ -257,7 +257,7 @@ Item { selectByMouse: true wrapMode: TextEdit.WordWrap - text: "import QtQuick 2.0\nImage {\n id: smile\n x: 360 * Math.random()\n y: 40 * Math.random() \n source: 'content/images/face-smile.png'\n NumberAnimation on opacity { \n to: 0; duration: 1500\n }\n Component.onCompleted: smile.destroy(1500);\n}" + text: "import QtQuick 2.0\nImage {\n id: smile\n x: 360 * Math.random()\n y: 40 * Math.random() \n source: 'images/face-smile.png'\n NumberAnimation on opacity { \n to: 0; duration: 1500\n }\n Component.onCompleted: smile.destroy(1500);\n}" } } } diff --git a/examples/qml/dynamicscene/dynamicscene.qrc b/examples/qml/dynamicscene/dynamicscene.qrc index ac9baa49413..052b9f85360 100644 --- a/examples/qml/dynamicscene/dynamicscene.qrc +++ b/examples/qml/dynamicscene/dynamicscene.qrc @@ -1,19 +1,18 @@ - + dynamicscene.qml - content/images/face-smile.png - content/images/moon.png - content/images/NOTE - content/images/rabbit_brown.png - content/images/rabbit_bw.png - content/images/star.png - content/images/sun.png - content/images/tree_s.png - content/Button.qml - content/GenericSceneItem.qml - content/itemCreation.js - content/PaletteItem.qml - content/PerspectiveItem.qml - content/Sun.qml + images/face-smile.png + images/moon.png + images/NOTE + images/rabbit_brown.png + images/rabbit_bw.png + images/star.png + images/sun.png + images/tree_s.png + GenericSceneItem.qml + itemCreation.js + PaletteItem.qml + PerspectiveItem.qml + Sun.qml diff --git a/examples/qml/dynamicscene/content/images/NOTE b/examples/qml/dynamicscene/images/NOTE similarity index 100% rename from examples/qml/dynamicscene/content/images/NOTE rename to examples/qml/dynamicscene/images/NOTE diff --git a/examples/qml/dynamicscene/content/images/face-smile.png b/examples/qml/dynamicscene/images/face-smile.png similarity index 100% rename from examples/qml/dynamicscene/content/images/face-smile.png rename to examples/qml/dynamicscene/images/face-smile.png diff --git a/examples/qml/dynamicscene/content/images/moon.png b/examples/qml/dynamicscene/images/moon.png similarity index 100% rename from examples/qml/dynamicscene/content/images/moon.png rename to examples/qml/dynamicscene/images/moon.png diff --git a/examples/qml/dynamicscene/content/images/rabbit_brown.png b/examples/qml/dynamicscene/images/rabbit_brown.png similarity index 100% rename from examples/qml/dynamicscene/content/images/rabbit_brown.png rename to examples/qml/dynamicscene/images/rabbit_brown.png diff --git a/examples/qml/dynamicscene/content/images/rabbit_bw.png b/examples/qml/dynamicscene/images/rabbit_bw.png similarity index 100% rename from examples/qml/dynamicscene/content/images/rabbit_bw.png rename to examples/qml/dynamicscene/images/rabbit_bw.png diff --git a/examples/qml/dynamicscene/content/images/star.png b/examples/qml/dynamicscene/images/star.png similarity index 100% rename from examples/qml/dynamicscene/content/images/star.png rename to examples/qml/dynamicscene/images/star.png diff --git a/examples/qml/dynamicscene/content/images/sun.png b/examples/qml/dynamicscene/images/sun.png similarity index 100% rename from examples/qml/dynamicscene/content/images/sun.png rename to examples/qml/dynamicscene/images/sun.png diff --git a/examples/qml/dynamicscene/content/images/tree_s.png b/examples/qml/dynamicscene/images/tree_s.png similarity index 100% rename from examples/qml/dynamicscene/content/images/tree_s.png rename to examples/qml/dynamicscene/images/tree_s.png diff --git a/examples/qml/dynamicscene/content/itemCreation.js b/examples/qml/dynamicscene/itemCreation.js similarity index 100% rename from examples/qml/dynamicscene/content/itemCreation.js rename to examples/qml/dynamicscene/itemCreation.js diff --git a/examples/qml/dynamicscene/main.cpp b/examples/qml/dynamicscene/main.cpp index e28375158d3..f6d2ee9a787 100644 --- a/examples/qml/dynamicscene/main.cpp +++ b/examples/qml/dynamicscene/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../quick/shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(dynamicscene) +DECLARATIVE_EXAMPLE_MAIN(dynamicscene/dynamicscene) diff --git a/examples/qml/networkaccessmanagerfactory/CMakeLists.txt b/examples/qml/networkaccessmanagerfactory/CMakeLists.txt index 11a88738ab2..fd4444a99b2 100644 --- a/examples/qml/networkaccessmanagerfactory/CMakeLists.txt +++ b/examples/qml/networkaccessmanagerfactory/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from networkaccessmanagerfactory.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(networkaccessmanagerfactory LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -36,17 +36,11 @@ target_link_libraries(networkaccessmanagerfactory PUBLIC Qt::Quick ) - -# Resources: -set(networkaccessmanagerfactory_resource_files - "view.qml" -) - -qt6_add_resources(networkaccessmanagerfactory "networkaccessmanagerfactory" - PREFIX - "/" - FILES - ${networkaccessmanagerfactory_resource_files} +qt_add_qml_module(networkaccessmanagerfactory + URI Example + VERSION 1.0 + QML_FILES view.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS networkaccessmanagerfactory diff --git a/examples/qml/qmlextensionplugins/CMakeLists.txt b/examples/qml/qmlextensionplugins/CMakeLists.txt index dcfde4a8ae7..8156f23eb13 100644 --- a/examples/qml/qmlextensionplugins/CMakeLists.txt +++ b/examples/qml/qmlextensionplugins/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from qmlextensionplugins.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(qmlqtimeexample LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -19,15 +19,27 @@ find_package(Qt6 COMPONENTS Core) find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Qml) -set_source_files_properties(imports/TimeExample/Clock.qml PROPERTIES - QT_RESOURCE_ALIAS Clock.qml +set(qml_files + imports/TimeExample/Clock.qml ) +set(images + imports/TimeExample/center.png + imports/TimeExample/clock.png + imports/TimeExample/hour.png + imports/TimeExample/minute.png +) +foreach(file IN LISTS qml_files images) + get_filename_component(filename ${file} NAME) + set_source_files_properties(${file} PROPERTIES QT_RESOURCE_ALIAS ${filename}) +endforeach() + qt6_add_qml_module(qmlqtimeexample - OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/imports/TimeExample" + OUTPUT_DIRECTORY TimeExample VERSION 1.0 URI "TimeExample" SOURCES timemodel.cpp timemodel.h - QML_FILES imports/TimeExample/Clock.qml + QML_FILES ${qml_files} + RESOURCES ${images} ) set_target_properties(qmlqtimeexample PROPERTIES WIN32_EXECUTABLE TRUE @@ -39,16 +51,6 @@ target_link_libraries(qmlqtimeexample PUBLIC Qt::Qml ) -qt6_add_resources(qmlqtimeexample example_images - PREFIX "/TimeExample" - BASE imports/TimeExample - FILES - imports/TimeExample/center.png - imports/TimeExample/clock.png - imports/TimeExample/hour.png - imports/TimeExample/minute.png -) - install(TARGETS qmlqtimeexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/qml/qmlextensionplugins/doc/src/qmlpluginex.qdoc b/examples/qml/qmlextensionplugins/doc/src/qmlpluginex.qdoc index 24d6991d52b..cbc7de29363 100644 --- a/examples/qml/qmlextensionplugins/doc/src/qmlpluginex.qdoc +++ b/examples/qml/qmlextensionplugins/doc/src/qmlpluginex.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -37,6 +37,6 @@ \code > qmake > make - > qmlscene -I imports plugins.qml + > qml -I imports plugins.qml \endcode */ diff --git a/examples/qml/referenceexamples/adding/CMakeLists.txt b/examples/qml/referenceexamples/adding/CMakeLists.txt index 9e04f3799a9..b86d90a4c35 100644 --- a/examples/qml/referenceexamples/adding/CMakeLists.txt +++ b/examples/qml/referenceexamples/adding/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from adding.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(adding LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -31,17 +31,11 @@ target_link_libraries(adding PUBLIC Qt::Qml ) - -# Resources: -set(adding_resource_files - "example.qml" -) - -qt6_add_resources(adding "adding" - PREFIX - "/" - FILES - ${adding_resource_files} +qt_add_qml_module(adding + URI People + VERSION 1.0 + QML_FILES example.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS adding @@ -49,10 +43,3 @@ install(TARGETS adding BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(adding PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI People -) - -qt6_qml_type_registration(adding) diff --git a/examples/qml/referenceexamples/adding/main.cpp b/examples/qml/referenceexamples/adding/main.cpp index 6c3920f04b1..fbf3e71af73 100644 --- a/examples/qml/referenceexamples/adding/main.cpp +++ b/examples/qml/referenceexamples/adding/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #include #include #include @@ -60,12 +61,13 @@ int main(int argc, char ** argv) QQmlEngine engine; QQmlComponent component(&engine, QUrl("qrc:example.qml")); auto *person = qobject_cast(component.create()); - if (person) { - qWarning() << "The person's name is" << person->name(); - qWarning() << "They wear a" << person->shoeSize() << "sized shoe"; - } else { + if (!person) { qWarning() << component.errors(); + return EXIT_FAILURE; } + qInfo() << "The person's name is" << person->name() + << "\nThey wear a" << person->shoeSize() << "sized shoe"; + return EXIT_SUCCESS; } diff --git a/examples/qml/referenceexamples/adding/person.cpp b/examples/qml/referenceexamples/adding/person.cpp index de4a33dd007..4741442cf0c 100644 --- a/examples/qml/referenceexamples/adding/person.cpp +++ b/examples/qml/referenceexamples/adding/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,14 +47,10 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #include "person.h" // ![0] -Person::Person(QObject *parent) -: QObject(parent), m_shoeSize(0) -{ -} - QString Person::name() const { return m_name; diff --git a/examples/qml/referenceexamples/adding/person.h b/examples/qml/referenceexamples/adding/person.h index 530c335dee2..03a72d184f4 100644 --- a/examples/qml/referenceexamples/adding/person.h +++ b/examples/qml/referenceexamples/adding/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef PERSON_H #define PERSON_H @@ -61,7 +62,7 @@ class Person : public QObject Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize) QML_ELEMENT public: - Person(QObject *parent = nullptr); + using QObject::QObject; QString name() const; void setName(const QString &); @@ -71,7 +72,7 @@ class Person : public QObject private: QString m_name; - int m_shoeSize; + int m_shoeSize = 0; }; //![0] diff --git a/examples/qml/referenceexamples/attached/CMakeLists.txt b/examples/qml/referenceexamples/attached/CMakeLists.txt index 10aa52293c9..4d49cc56630 100644 --- a/examples/qml/referenceexamples/attached/CMakeLists.txt +++ b/examples/qml/referenceexamples/attached/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from attached.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(attached LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -34,17 +34,11 @@ target_link_libraries(attached PUBLIC Qt::Qml ) - -# Resources: -set(attached_resource_files - "example.qml" -) - -qt6_add_resources(attached "attached" - PREFIX - "/" - FILES - ${attached_resource_files} +qt_add_qml_module(attached + URI People + VERSION 1.0 + QML_FILES example.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS attached @@ -52,10 +46,3 @@ install(TARGETS attached BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(attached PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI People -) - -qt6_qml_type_registration(attached) diff --git a/examples/qml/referenceexamples/attached/birthdayparty.cpp b/examples/qml/referenceexamples/attached/birthdayparty.cpp index 9aed5df621e..fc27a22631d 100644 --- a/examples/qml/referenceexamples/attached/birthdayparty.cpp +++ b/examples/qml/referenceexamples/attached/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "birthdayparty.h" -BirthdayPartyAttached::BirthdayPartyAttached(QObject *object) -: QObject(object) -{ -} +#include "birthdayparty.h" QDate BirthdayPartyAttached::rsvp() const { @@ -64,11 +60,6 @@ void BirthdayPartyAttached::setRsvp(QDate d) m_rsvp = d; } -BirthdayParty::BirthdayParty(QObject *parent) -: QObject(parent), m_host(nullptr) -{ -} - Person *BirthdayParty::host() const { return m_host; @@ -84,12 +75,12 @@ QQmlListProperty BirthdayParty::guests() return {this, &m_guests}; } -int BirthdayParty::guestCount() const +qsizetype BirthdayParty::guestCount() const { return m_guests.count(); } -Person *BirthdayParty::guest(int index) const +Person *BirthdayParty::guest(qsizetype index) const { return m_guests.at(index); } diff --git a/examples/qml/referenceexamples/attached/birthdayparty.h b/examples/qml/referenceexamples/attached/birthdayparty.h index 4f2ed1702a7..30f5cbbb643 100644 --- a/examples/qml/referenceexamples/attached/birthdayparty.h +++ b/examples/qml/referenceexamples/attached/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef BIRTHDAYPARTY_H #define BIRTHDAYPARTY_H @@ -61,7 +62,7 @@ class BirthdayPartyAttached : public QObject Q_PROPERTY(QDate rsvp READ rsvp WRITE setRsvp) QML_ANONYMOUS public: - BirthdayPartyAttached(QObject *object); + using QObject::QObject; QDate rsvp() const; void setRsvp(QDate); @@ -83,20 +84,20 @@ class BirthdayParty : public QObject //! [declare attached] public: - BirthdayParty(QObject *parent = nullptr); + using QObject::QObject; Person *host() const; void setHost(Person *); QQmlListProperty guests(); - int guestCount() const; - Person *guest(int) const; + qsizetype guestCount() const; + Person *guest(qsizetype) const; //! [static attached] static BirthdayPartyAttached *qmlAttachedProperties(QObject *); //! [static attached] private: - Person *m_host; + Person *m_host = nullptr; QList m_guests; }; diff --git a/examples/qml/referenceexamples/attached/main.cpp b/examples/qml/referenceexamples/attached/main.cpp index 2fceb98ac9a..5f8497bed36 100644 --- a/examples/qml/referenceexamples/attached/main.cpp +++ b/examples/qml/referenceexamples/attached/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #include #include #include @@ -63,14 +64,14 @@ int main(int argc, char ** argv) auto *party = qobject_cast(component.create()); if (party && party->host()) { - qWarning() << party->host()->name() << "is having a birthday!"; + qInfo() << party->host()->name() << "is having a birthday!"; if (qobject_cast(party->host())) - qWarning() << "He is inviting:"; + qInfo() << "He is inviting:"; else - qWarning() << "She is inviting:"; + qInfo() << "She is inviting:"; - for (int ii = 0; ii < party->guestCount(); ++ii) { + for (qsizetype ii = 0; ii < party->guestCount(); ++ii) { Person *guest = party->guest(ii); //! [query rsvp] @@ -81,9 +82,9 @@ int main(int argc, char ** argv) rsvpDate = attached->property("rsvp").toDate(); //! [query rsvp] if (rsvpDate.isNull()) - qWarning() << " " << guest->name() << "RSVP date: Hasn't RSVP'd"; + qInfo() << " " << guest->name() << "RSVP date: Hasn't RSVP'd"; else - qWarning() << " " << guest->name() << "RSVP date:" << qPrintable(rsvpDate.toString()); + qInfo() << " " << guest->name() << "RSVP date:" << rsvpDate.toString(); } return EXIT_SUCCESS; diff --git a/examples/qml/referenceexamples/attached/person.cpp b/examples/qml/referenceexamples/attached/person.cpp index 06036441087..4e52da76c8a 100644 --- a/examples/qml/referenceexamples/attached/person.cpp +++ b/examples/qml/referenceexamples/attached/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "person.h" -ShoeDescription::ShoeDescription(QObject *parent) -: QObject(parent), m_size(0), m_price(0) -{ -} +#include "person.h" int ShoeDescription::size() const { @@ -94,11 +90,6 @@ void ShoeDescription::setPrice(qreal p) m_price = p; } -Person::Person(QObject *parent) -: QObject(parent) -{ -} - QString Person::name() const { return m_name; @@ -113,16 +104,3 @@ ShoeDescription *Person::shoe() { return &m_shoe; } - - -Boy::Boy(QObject * parent) -: Person(parent) -{ -} - - -Girl::Girl(QObject * parent) -: Person(parent) -{ -} - diff --git a/examples/qml/referenceexamples/attached/person.h b/examples/qml/referenceexamples/attached/person.h index 239f4405c02..ddd3baa5f20 100644 --- a/examples/qml/referenceexamples/attached/person.h +++ b/examples/qml/referenceexamples/attached/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef PERSON_H #define PERSON_H @@ -63,7 +64,7 @@ class ShoeDescription : public QObject Q_PROPERTY(qreal price READ price WRITE setPrice) QML_ANONYMOUS public: - ShoeDescription(QObject *parent = 0); + using QObject::QObject; int size() const; void setSize(int); @@ -76,11 +77,12 @@ class ShoeDescription : public QObject qreal price() const; void setPrice(qreal); + private: - int m_size; + int m_size = 0; QColor m_color; QString m_brand; - qreal m_price; + qreal m_price = 0; }; class Person : public QObject @@ -90,7 +92,7 @@ class Person : public QObject Q_PROPERTY(ShoeDescription *shoe READ shoe) QML_ANONYMOUS public: - Person(QObject *parent = nullptr); + using QObject::QObject; QString name() const; void setName(const QString &); @@ -106,7 +108,7 @@ class Boy : public Person Q_OBJECT QML_ELEMENT public: - Boy(QObject * parent = nullptr); + using Person::Person; }; class Girl : public Person @@ -114,7 +116,7 @@ class Girl : public Person Q_OBJECT QML_ELEMENT public: - Girl(QObject * parent = nullptr); + using Person::Person; }; #endif // PERSON_H diff --git a/examples/qml/referenceexamples/binding/CMakeLists.txt b/examples/qml/referenceexamples/binding/CMakeLists.txt index f64c24803c3..2a2d6575c0d 100644 --- a/examples/qml/referenceexamples/binding/CMakeLists.txt +++ b/examples/qml/referenceexamples/binding/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from binding.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(binding LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -35,17 +35,11 @@ target_link_libraries(binding PUBLIC Qt::Qml ) - -# Resources: -set(binding_resource_files - "example.qml" -) - -qt6_add_resources(binding "binding" - PREFIX - "/" - FILES - ${binding_resource_files} +qt_add_qml_module(binding + URI People + VERSION 1.0 + QML_FILES example.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS binding @@ -53,10 +47,3 @@ install(TARGETS binding BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(binding PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI People -) - -qt6_qml_type_registration(binding) diff --git a/examples/qml/referenceexamples/binding/birthdayparty.cpp b/examples/qml/referenceexamples/binding/birthdayparty.cpp index 02a1adbb354..ce86c7faa4b 100644 --- a/examples/qml/referenceexamples/binding/birthdayparty.cpp +++ b/examples/qml/referenceexamples/binding/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "birthdayparty.h" -BirthdayPartyAttached::BirthdayPartyAttached(QObject *object) -: QObject(object) -{ -} +#include "birthdayparty.h" QDate BirthdayPartyAttached::rsvp() const { @@ -67,12 +63,6 @@ void BirthdayPartyAttached::setRsvp(QDate d) } } - -BirthdayParty::BirthdayParty(QObject *parent) -: QObject(parent), m_host(nullptr) -{ -} - Person *BirthdayParty::host() const { return m_host; @@ -90,12 +80,12 @@ QQmlListProperty BirthdayParty::guests() return QQmlListProperty(this, &m_guests); } -int BirthdayParty::guestCount() const +qsizetype BirthdayParty::guestCount() const { return m_guests.count(); } -Person *BirthdayParty::guest(int index) const +Person *BirthdayParty::guest(qsizetype index) const { return m_guests.at(index); } @@ -113,7 +103,7 @@ QString BirthdayParty::announcement() const void BirthdayParty::setAnnouncement(const QString &speak) { - qWarning() << qPrintable(speak); + qWarning().noquote() << speak; } BirthdayPartyAttached *BirthdayParty::qmlAttachedProperties(QObject *object) diff --git a/examples/qml/referenceexamples/binding/birthdayparty.h b/examples/qml/referenceexamples/binding/birthdayparty.h index 846a016cfc9..2881dfead27 100644 --- a/examples/qml/referenceexamples/binding/birthdayparty.h +++ b/examples/qml/referenceexamples/binding/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef BIRTHDAYPARTY_H #define BIRTHDAYPARTY_H @@ -62,7 +63,7 @@ class BirthdayPartyAttached : public QObject Q_PROPERTY(QDate rsvp READ rsvp WRITE setRsvp NOTIFY rsvpChanged) QML_ANONYMOUS public: - BirthdayPartyAttached(QObject *object); + using QObject::QObject; QDate rsvp() const; void setRsvp(QDate); @@ -86,14 +87,14 @@ class BirthdayParty : public QObject QML_ELEMENT QML_ATTACHED(BirthdayPartyAttached) public: - BirthdayParty(QObject *parent = nullptr); + using QObject::QObject; Person *host() const; void setHost(Person *); QQmlListProperty guests(); - int guestCount() const; - Person *guest(int) const; + qsizetype guestCount() const; + Person *guest(qsizetype) const; QString announcement() const; void setAnnouncement(const QString &); @@ -106,7 +107,7 @@ class BirthdayParty : public QObject void hostChanged(); private: - Person *m_host; + Person *m_host = nullptr; QList m_guests; }; diff --git a/examples/qml/referenceexamples/binding/happybirthdaysong.cpp b/examples/qml/referenceexamples/binding/happybirthdaysong.cpp index 5f8e6d696ed..2722b65e064 100644 --- a/examples/qml/referenceexamples/binding/happybirthdaysong.cpp +++ b/examples/qml/referenceexamples/binding/happybirthdaysong.cpp @@ -50,10 +50,9 @@ #include "happybirthdaysong.h" #include -HappyBirthdaySong::HappyBirthdaySong(QObject *parent) -: QObject(parent), m_line(-1) +HappyBirthdaySong::HappyBirthdaySong(QObject *parent) : + QObject(parent) { - setName(QString()); auto *timer = new QTimer(this); QObject::connect(timer, &QTimer::timeout, this, &HappyBirthdaySong::advance); timer->start(1000); diff --git a/examples/qml/referenceexamples/binding/happybirthdaysong.h b/examples/qml/referenceexamples/binding/happybirthdaysong.h index c84e9d9e5e6..078bdac72b4 100644 --- a/examples/qml/referenceexamples/binding/happybirthdaysong.h +++ b/examples/qml/referenceexamples/binding/happybirthdaysong.h @@ -64,7 +64,7 @@ class HappyBirthdaySong : public QObject, public QQmlPropertyValueSource Q_INTERFACES(QQmlPropertyValueSource) QML_ELEMENT public: - HappyBirthdaySong(QObject *parent = nullptr); + explicit HappyBirthdaySong(QObject *parent = nullptr); void setTarget(const QQmlProperty &) override; @@ -77,7 +77,7 @@ private slots: signals: void nameChanged(); private: - int m_line; + qsizetype m_line = -1; QStringList m_lyrics; QQmlProperty m_target; QString m_name; diff --git a/examples/qml/referenceexamples/binding/main.cpp b/examples/qml/referenceexamples/binding/main.cpp index 2e9995fcd88..a100497659c 100644 --- a/examples/qml/referenceexamples/binding/main.cpp +++ b/examples/qml/referenceexamples/binding/main.cpp @@ -64,14 +64,14 @@ int main(int argc, char ** argv) auto *party = qobject_cast(component.create()); if (party && party->host()) { - qWarning() << party->host()->name() << "is having a birthday!"; + qInfo() << party->host()->name() << "is having a birthday!"; if (qobject_cast(party->host())) - qWarning() << "He is inviting:"; + qInfo() << "He is inviting:"; else - qWarning() << "She is inviting:"; + qInfo() << "She is inviting:"; - for (int ii = 0; ii < party->guestCount(); ++ii) { + for (qsizetype ii = 0; ii < party->guestCount(); ++ii) { Person *guest = party->guest(ii); QDate rsvpDate; @@ -81,9 +81,9 @@ int main(int argc, char ** argv) rsvpDate = attached->property("rsvp").toDate(); if (rsvpDate.isNull()) - qWarning() << " " << guest->name() << "RSVP date: Hasn't RSVP'd"; + qInfo() << " " << guest->name() << "RSVP date: Hasn't RSVP'd"; else - qWarning() << " " << guest->name() << "RSVP date:" << qPrintable(rsvpDate.toString()); + qInfo() << " " << guest->name() << "RSVP date:" << rsvpDate.toString(); } party->startParty(); diff --git a/examples/qml/referenceexamples/binding/person.cpp b/examples/qml/referenceexamples/binding/person.cpp index 1a23d0a4f5e..0296b0a7c6c 100644 --- a/examples/qml/referenceexamples/binding/person.cpp +++ b/examples/qml/referenceexamples/binding/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "person.h" -ShoeDescription::ShoeDescription(QObject *parent) -: QObject(parent), m_size(0), m_price(0) -{ -} +#include "person.h" int ShoeDescription::size() const { @@ -110,11 +106,6 @@ void ShoeDescription::setPrice(qreal p) emit shoeChanged(); } -Person::Person(QObject *parent) -: QObject(parent) -{ -} - QString Person::name() const { return m_name; @@ -133,16 +124,3 @@ ShoeDescription *Person::shoe() { return &m_shoe; } - - -Boy::Boy(QObject * parent) -: Person(parent) -{ -} - - -Girl::Girl(QObject * parent) -: Person(parent) -{ -} - diff --git a/examples/qml/referenceexamples/binding/person.h b/examples/qml/referenceexamples/binding/person.h index af9864950a2..e84075bb36c 100644 --- a/examples/qml/referenceexamples/binding/person.h +++ b/examples/qml/referenceexamples/binding/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef PERSON_H #define PERSON_H @@ -63,7 +64,7 @@ class ShoeDescription : public QObject Q_PROPERTY(qreal price READ price WRITE setPrice NOTIFY shoeChanged) QML_ANONYMOUS public: - ShoeDescription(QObject *parent = nullptr); + using QObject::QObject; int size() const; void setSize(int); @@ -76,14 +77,15 @@ class ShoeDescription : public QObject qreal price() const; void setPrice(qreal); + signals: void shoeChanged(); private: - int m_size; + int m_size = 0; QColor m_color; QString m_brand; - qreal m_price; + qreal m_price = 0; }; class Person : public QObject @@ -95,12 +97,13 @@ class Person : public QObject // ![0] QML_ANONYMOUS public: - Person(QObject *parent = nullptr); + using QObject::QObject; QString name() const; void setName(const QString &); ShoeDescription *shoe(); + signals: void nameChanged(); @@ -114,7 +117,7 @@ class Boy : public Person Q_OBJECT QML_ELEMENT public: - Boy(QObject * parent = nullptr); + using Person::Person; }; class Girl : public Person @@ -122,7 +125,7 @@ class Girl : public Person Q_OBJECT QML_ELEMENT public: - Girl(QObject * parent = nullptr); + using Person::Person; }; #endif // PERSON_H diff --git a/examples/qml/referenceexamples/coercion/CMakeLists.txt b/examples/qml/referenceexamples/coercion/CMakeLists.txt index 3160b927822..b9613de1164 100644 --- a/examples/qml/referenceexamples/coercion/CMakeLists.txt +++ b/examples/qml/referenceexamples/coercion/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from coercion.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(coercion LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -32,17 +32,11 @@ target_link_libraries(coercion PUBLIC Qt::Qml ) - -# Resources: -set(coercion_resource_files - "example.qml" -) - -qt6_add_resources(coercion "coercion" - PREFIX - "/" - FILES - ${coercion_resource_files} +qt_add_qml_module(coercion + URI People + VERSION 1.0 + QML_FILES example.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS coercion @@ -50,10 +44,3 @@ install(TARGETS coercion BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(coercion PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI People -) - -qt6_qml_type_registration(coercion) diff --git a/examples/qml/referenceexamples/coercion/birthdayparty.cpp b/examples/qml/referenceexamples/coercion/birthdayparty.cpp index 81db8ab1b84..269f45e02c7 100644 --- a/examples/qml/referenceexamples/coercion/birthdayparty.cpp +++ b/examples/qml/referenceexamples/coercion/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "birthdayparty.h" -BirthdayParty::BirthdayParty(QObject *parent) -: QObject(parent), m_host(nullptr) -{ -} +#include "birthdayparty.h" Person *BirthdayParty::host() const { @@ -69,13 +65,12 @@ QQmlListProperty BirthdayParty::guests() return {this, &m_guests}; } -int BirthdayParty::guestCount() const +qsizetype BirthdayParty::guestCount() const { return m_guests.count(); } -Person *BirthdayParty::guest(int index) const +Person *BirthdayParty::guest(qsizetype index) const { return m_guests.at(index); } - diff --git a/examples/qml/referenceexamples/coercion/birthdayparty.h b/examples/qml/referenceexamples/coercion/birthdayparty.h index ba8b2445f16..a504479e4d0 100644 --- a/examples/qml/referenceexamples/coercion/birthdayparty.h +++ b/examples/qml/referenceexamples/coercion/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef BIRTHDAYPARTY_H #define BIRTHDAYPARTY_H @@ -63,17 +64,17 @@ class BirthdayParty : public QObject QML_ELEMENT // ![0] public: - BirthdayParty(QObject *parent = nullptr); + using QObject::QObject; Person *host() const; void setHost(Person *); QQmlListProperty guests(); - int guestCount() const; - Person *guest(int) const; + qsizetype guestCount() const; + Person *guest(qsizetype) const; private: - Person *m_host; + Person *m_host = nullptr; QList m_guests; }; diff --git a/examples/qml/referenceexamples/coercion/main.cpp b/examples/qml/referenceexamples/coercion/main.cpp index 6b47d0d4c4a..095602af9dc 100644 --- a/examples/qml/referenceexamples/coercion/main.cpp +++ b/examples/qml/referenceexamples/coercion/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #include #include #include @@ -63,15 +64,15 @@ int main(int argc, char ** argv) auto *party = qobject_cast(component.create()); if (party && party->host()) { - qWarning() << party->host()->name() << "is having a birthday!"; + qInfo() << party->host()->name() << "is having a birthday!"; if (qobject_cast(party->host())) - qWarning() << "He is inviting:"; + qInfo() << "He is inviting:"; else - qWarning() << "She is inviting:"; + qInfo() << "She is inviting:"; - for (int ii = 0; ii < party->guestCount(); ++ii) - qWarning() << " " << party->guest(ii)->name(); + for (qsizetype ii = 0; ii < party->guestCount(); ++ii) + qInfo() << " " << party->guest(ii)->name(); return EXIT_SUCCESS; } diff --git a/examples/qml/referenceexamples/coercion/person.cpp b/examples/qml/referenceexamples/coercion/person.cpp index 178d7052ce3..e2847a26826 100644 --- a/examples/qml/referenceexamples/coercion/person.cpp +++ b/examples/qml/referenceexamples/coercion/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "person.h" -Person::Person(QObject *parent) -: QObject(parent), m_shoeSize(0) -{ -} +#include "person.h" QString Person::name() const { @@ -73,17 +69,3 @@ void Person::setShoeSize(int s) { m_shoeSize = s; } - -// ![1] -Boy::Boy(QObject * parent) -: Person(parent) -{ -} - - -Girl::Girl(QObject * parent) -: Person(parent) -{ -} - -// ![1] diff --git a/examples/qml/referenceexamples/coercion/person.h b/examples/qml/referenceexamples/coercion/person.h index 7e2828da04f..1ec095e841b 100644 --- a/examples/qml/referenceexamples/coercion/person.h +++ b/examples/qml/referenceexamples/coercion/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef PERSON_H #define PERSON_H @@ -63,16 +64,17 @@ class Person : public QObject QML_UNCREATABLE("Person is an abstract base class.") //![0] public: - Person(QObject *parent = nullptr); + using QObject::QObject; QString name() const; void setName(const QString &); int shoeSize() const; void setShoeSize(int); + private: QString m_name; - int m_shoeSize; + int m_shoeSize = 0; }; @@ -82,7 +84,7 @@ class Boy : public Person Q_OBJECT QML_ELEMENT public: - Boy(QObject * parent = nullptr); + using Person::Person; }; //! [girl class] @@ -91,7 +93,7 @@ class Girl : public Person Q_OBJECT QML_ELEMENT public: - Girl(QObject * parent = nullptr); + using Person::Person; }; //! [girl class] diff --git a/examples/qml/referenceexamples/default/CMakeLists.txt b/examples/qml/referenceexamples/default/CMakeLists.txt index 6e207f36412..419b14d464c 100644 --- a/examples/qml/referenceexamples/default/CMakeLists.txt +++ b/examples/qml/referenceexamples/default/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from default.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(default LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -32,17 +32,11 @@ target_link_libraries(default PUBLIC Qt::Qml ) - -# Resources: -set(default_resource_files - "example.qml" -) - -qt6_add_resources(default "default" - PREFIX - "/" - FILES - ${default_resource_files} +qt_add_qml_module(default + URI People + VERSION 1.0 + QML_FILES example.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS default @@ -50,10 +44,3 @@ install(TARGETS default BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(default PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI People -) - -qt6_qml_type_registration(default) diff --git a/examples/qml/referenceexamples/default/birthdayparty.cpp b/examples/qml/referenceexamples/default/birthdayparty.cpp index 81db8ab1b84..aeaf6fbd9cb 100644 --- a/examples/qml/referenceexamples/default/birthdayparty.cpp +++ b/examples/qml/referenceexamples/default/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "birthdayparty.h" -BirthdayParty::BirthdayParty(QObject *parent) -: QObject(parent), m_host(nullptr) -{ -} +#include "birthdayparty.h" Person *BirthdayParty::host() const { @@ -69,12 +65,12 @@ QQmlListProperty BirthdayParty::guests() return {this, &m_guests}; } -int BirthdayParty::guestCount() const +qsizetype BirthdayParty::guestCount() const { return m_guests.count(); } -Person *BirthdayParty::guest(int index) const +Person *BirthdayParty::guest(qsizetype index) const { return m_guests.at(index); } diff --git a/examples/qml/referenceexamples/default/birthdayparty.h b/examples/qml/referenceexamples/default/birthdayparty.h index 5eb6c887630..cb12a1510b9 100644 --- a/examples/qml/referenceexamples/default/birthdayparty.h +++ b/examples/qml/referenceexamples/default/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef BIRTHDAYPARTY_H #define BIRTHDAYPARTY_H @@ -63,17 +64,17 @@ class BirthdayParty : public QObject Q_CLASSINFO("DefaultProperty", "guests") QML_ELEMENT public: - BirthdayParty(QObject *parent = nullptr); + using QObject::QObject; Person *host() const; void setHost(Person *); QQmlListProperty guests(); - int guestCount() const; - Person *guest(int) const; + qsizetype guestCount() const; + Person *guest(qsizetype) const; private: - Person *m_host; + Person *m_host = nullptr; QList m_guests; }; // ![0] diff --git a/examples/qml/referenceexamples/default/main.cpp b/examples/qml/referenceexamples/default/main.cpp index 6b47d0d4c4a..82e6f5ba378 100644 --- a/examples/qml/referenceexamples/default/main.cpp +++ b/examples/qml/referenceexamples/default/main.cpp @@ -63,15 +63,15 @@ int main(int argc, char ** argv) auto *party = qobject_cast(component.create()); if (party && party->host()) { - qWarning() << party->host()->name() << "is having a birthday!"; + qInfo() << party->host()->name() << "is having a birthday!"; if (qobject_cast(party->host())) - qWarning() << "He is inviting:"; + qInfo() << "He is inviting:"; else - qWarning() << "She is inviting:"; + qInfo() << "She is inviting:"; - for (int ii = 0; ii < party->guestCount(); ++ii) - qWarning() << " " << party->guest(ii)->name(); + for (qsizetype ii = 0; ii < party->guestCount(); ++ii) + qInfo() << " " << party->guest(ii)->name(); return EXIT_SUCCESS; } diff --git a/examples/qml/referenceexamples/default/person.cpp b/examples/qml/referenceexamples/default/person.cpp index a1d887a4d0c..e2847a26826 100644 --- a/examples/qml/referenceexamples/default/person.cpp +++ b/examples/qml/referenceexamples/default/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "person.h" -Person::Person(QObject *parent) -: QObject(parent), m_shoeSize(0) -{ -} +#include "person.h" QString Person::name() const { @@ -73,16 +69,3 @@ void Person::setShoeSize(int s) { m_shoeSize = s; } - - -Boy::Boy(QObject * parent) -: Person(parent) -{ -} - - -Girl::Girl(QObject * parent) -: Person(parent) -{ -} - diff --git a/examples/qml/referenceexamples/default/person.h b/examples/qml/referenceexamples/default/person.h index 361a89c599c..0b2e280747d 100644 --- a/examples/qml/referenceexamples/default/person.h +++ b/examples/qml/referenceexamples/default/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef PERSON_H #define PERSON_H @@ -60,7 +61,7 @@ class Person : public QObject Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize) QML_ANONYMOUS public: - Person(QObject *parent = nullptr); + using QObject::QObject; QString name() const; void setName(const QString &); @@ -69,7 +70,7 @@ class Person : public QObject void setShoeSize(int); private: QString m_name; - int m_shoeSize; + int m_shoeSize = 0; }; class Boy : public Person @@ -77,7 +78,7 @@ class Boy : public Person Q_OBJECT QML_ELEMENT public: - Boy(QObject * parent = nullptr); + using Person::Person; }; class Girl : public Person @@ -85,7 +86,7 @@ class Girl : public Person Q_OBJECT QML_ELEMENT public: - Girl(QObject * parent = nullptr); + using Person::Person; }; #endif // PERSON_H diff --git a/examples/qml/referenceexamples/extended/CMakeLists.txt b/examples/qml/referenceexamples/extended/CMakeLists.txt index 6843b39d384..ea659e5f714 100644 --- a/examples/qml/referenceexamples/extended/CMakeLists.txt +++ b/examples/qml/referenceexamples/extended/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from extended.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(extended LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -35,17 +35,11 @@ target_link_libraries(extended PUBLIC Qt::Widgets ) - -# Resources: -set(extended_resource_files - "example.qml" -) - -qt6_add_resources(extended "extended" - PREFIX - "/" - FILES - ${extended_resource_files} +qt_add_qml_module(extended + URI People + VERSION 1.0 + QML_FILES example.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS extended @@ -53,10 +47,3 @@ install(TARGETS extended BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(extended PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI People -) - -qt6_qml_type_registration(extended) diff --git a/examples/qml/referenceexamples/grouped/CMakeLists.txt b/examples/qml/referenceexamples/grouped/CMakeLists.txt index 19dd60358bb..f7a31d9c1e3 100644 --- a/examples/qml/referenceexamples/grouped/CMakeLists.txt +++ b/examples/qml/referenceexamples/grouped/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from grouped.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(grouped LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -34,17 +34,11 @@ target_link_libraries(grouped PUBLIC Qt::Qml ) - -# Resources: -set(grouped_resource_files - "example.qml" -) - -qt6_add_resources(grouped "grouped" - PREFIX - "/" - FILES - ${grouped_resource_files} +qt_add_qml_module(grouped + URI People + VERSION 1.0 + QML_FILES example.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS grouped @@ -52,10 +46,3 @@ install(TARGETS grouped BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(grouped PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI People -) - -qt6_qml_type_registration(grouped) diff --git a/examples/qml/referenceexamples/grouped/birthdayparty.cpp b/examples/qml/referenceexamples/grouped/birthdayparty.cpp index 81db8ab1b84..269f45e02c7 100644 --- a/examples/qml/referenceexamples/grouped/birthdayparty.cpp +++ b/examples/qml/referenceexamples/grouped/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "birthdayparty.h" -BirthdayParty::BirthdayParty(QObject *parent) -: QObject(parent), m_host(nullptr) -{ -} +#include "birthdayparty.h" Person *BirthdayParty::host() const { @@ -69,13 +65,12 @@ QQmlListProperty BirthdayParty::guests() return {this, &m_guests}; } -int BirthdayParty::guestCount() const +qsizetype BirthdayParty::guestCount() const { return m_guests.count(); } -Person *BirthdayParty::guest(int index) const +Person *BirthdayParty::guest(qsizetype index) const { return m_guests.at(index); } - diff --git a/examples/qml/referenceexamples/grouped/birthdayparty.h b/examples/qml/referenceexamples/grouped/birthdayparty.h index f6834dad89e..a8e0964365e 100644 --- a/examples/qml/referenceexamples/grouped/birthdayparty.h +++ b/examples/qml/referenceexamples/grouped/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef BIRTHDAYPARTY_H #define BIRTHDAYPARTY_H @@ -62,14 +63,14 @@ class BirthdayParty : public QObject Q_CLASSINFO("DefaultProperty", "guests") QML_ELEMENT public: - BirthdayParty(QObject *parent = nullptr); + using QObject::QObject; Person *host() const; void setHost(Person *); QQmlListProperty guests(); - int guestCount() const; - Person *guest(int) const; + qsizetype guestCount() const; + Person *guest(qsizetype) const; private: Person *m_host; diff --git a/examples/qml/referenceexamples/grouped/main.cpp b/examples/qml/referenceexamples/grouped/main.cpp index 63dbe988a44..6d4ec517cc0 100644 --- a/examples/qml/referenceexamples/grouped/main.cpp +++ b/examples/qml/referenceexamples/grouped/main.cpp @@ -63,23 +63,23 @@ int main(int argc, char ** argv) auto *party = qobject_cast(component.create()); if (party && party->host()) { - qWarning() << party->host()->name() << "is having a birthday!"; + qInfo() << party->host()->name() << "is having a birthday!"; if (qobject_cast(party->host())) - qWarning() << "He is inviting:"; + qInfo() << "He is inviting:"; else - qWarning() << "She is inviting:"; + qInfo() << "She is inviting:"; Person *bestShoe = nullptr; - for (int ii = 0; ii < party->guestCount(); ++ii) { + for (qsizetype ii = 0; ii < party->guestCount(); ++ii) { Person *guest = party->guest(ii); - qWarning() << " " << guest->name(); + qInfo() << " " << guest->name(); if (!bestShoe || bestShoe->shoe()->price() < guest->shoe()->price()) bestShoe = guest; } if (bestShoe) - qWarning() << bestShoe->name() << "is wearing the best shoes!"; + qInfo() << bestShoe->name() << "is wearing the best shoes!"; return EXIT_SUCCESS; } diff --git a/examples/qml/referenceexamples/grouped/person.cpp b/examples/qml/referenceexamples/grouped/person.cpp index 06036441087..4e52da76c8a 100644 --- a/examples/qml/referenceexamples/grouped/person.cpp +++ b/examples/qml/referenceexamples/grouped/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "person.h" -ShoeDescription::ShoeDescription(QObject *parent) -: QObject(parent), m_size(0), m_price(0) -{ -} +#include "person.h" int ShoeDescription::size() const { @@ -94,11 +90,6 @@ void ShoeDescription::setPrice(qreal p) m_price = p; } -Person::Person(QObject *parent) -: QObject(parent) -{ -} - QString Person::name() const { return m_name; @@ -113,16 +104,3 @@ ShoeDescription *Person::shoe() { return &m_shoe; } - - -Boy::Boy(QObject * parent) -: Person(parent) -{ -} - - -Girl::Girl(QObject * parent) -: Person(parent) -{ -} - diff --git a/examples/qml/referenceexamples/grouped/person.h b/examples/qml/referenceexamples/grouped/person.h index df507c73864..ed77f8c4d82 100644 --- a/examples/qml/referenceexamples/grouped/person.h +++ b/examples/qml/referenceexamples/grouped/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef PERSON_H #define PERSON_H @@ -63,7 +64,7 @@ class ShoeDescription : public QObject Q_PROPERTY(qreal price READ price WRITE setPrice) QML_ANONYMOUS public: - ShoeDescription(QObject *parent = nullptr); + using QObject::QObject; int size() const; void setSize(int); @@ -76,11 +77,12 @@ class ShoeDescription : public QObject qreal price() const; void setPrice(qreal); + private: - int m_size; + int m_size = 0; QColor m_color; QString m_brand; - qreal m_price; + qreal m_price = 0; }; class Person : public QObject @@ -92,7 +94,7 @@ class Person : public QObject // ![1] QML_ANONYMOUS public: - Person(QObject *parent = nullptr); + using QObject::QObject; QString name() const; void setName(const QString &); @@ -108,7 +110,7 @@ class Boy : public Person Q_OBJECT QML_ELEMENT public: - Boy(QObject * parent = nullptr); + using Person::Person; }; class Girl : public Person @@ -116,7 +118,7 @@ class Girl : public Person Q_OBJECT QML_ELEMENT public: - Girl(QObject * parent = nullptr); + using Person::Person; }; #endif // PERSON_H diff --git a/examples/qml/referenceexamples/methods/CMakeLists.txt b/examples/qml/referenceexamples/methods/CMakeLists.txt index 886928e10e8..304aa3082a1 100644 --- a/examples/qml/referenceexamples/methods/CMakeLists.txt +++ b/examples/qml/referenceexamples/methods/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from methods.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(methods LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -32,17 +32,11 @@ target_link_libraries(methods PUBLIC Qt::Qml ) - -# Resources: -set(methods_resource_files - "example.qml" -) - -qt6_add_resources(methods "methods" - PREFIX - "/" - FILES - ${methods_resource_files} +qt_add_qml_module(methods + URI People + VERSION 1.0 + QML_FILES example.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS methods @@ -50,10 +44,3 @@ install(TARGETS methods BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(methods PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI People -) - -qt6_qml_type_registration(methods) diff --git a/examples/qml/referenceexamples/methods/birthdayparty.cpp b/examples/qml/referenceexamples/methods/birthdayparty.cpp index 4b30d31aebb..1308a09b728 100644 --- a/examples/qml/referenceexamples/methods/birthdayparty.cpp +++ b/examples/qml/referenceexamples/methods/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "birthdayparty.h" -BirthdayParty::BirthdayParty(QObject *parent) -: QObject(parent), m_host(nullptr) -{ -} +#include "birthdayparty.h" // ![0] Person *BirthdayParty::host() const @@ -70,12 +66,12 @@ QQmlListProperty BirthdayParty::guests() return {this, &m_guests}; } -int BirthdayParty::guestCount() const +qsizetype BirthdayParty::guestCount() const { return m_guests.count(); } -Person *BirthdayParty::guest(int index) const +Person *BirthdayParty::guest(qsizetype index) const { return m_guests.at(index); } diff --git a/examples/qml/referenceexamples/methods/birthdayparty.h b/examples/qml/referenceexamples/methods/birthdayparty.h index 5c2f3c9def8..b43308ac8fa 100644 --- a/examples/qml/referenceexamples/methods/birthdayparty.h +++ b/examples/qml/referenceexamples/methods/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef BIRTHDAYPARTY_H #define BIRTHDAYPARTY_H @@ -61,21 +62,21 @@ class BirthdayParty : public QObject Q_PROPERTY(QQmlListProperty guests READ guests) QML_ELEMENT public: - BirthdayParty(QObject *parent = nullptr); + using QObject::QObject; Person *host() const; void setHost(Person *); QQmlListProperty guests(); - int guestCount() const; - Person *guest(int) const; + qsizetype guestCount() const; + Person *guest(qsizetype) const; // ![0] Q_INVOKABLE void invite(const QString &name); // ![0] private: - Person *m_host; + Person *m_host = nullptr; QList m_guests; }; diff --git a/examples/qml/referenceexamples/methods/main.cpp b/examples/qml/referenceexamples/methods/main.cpp index e30e1d9fb17..32eb4831cca 100644 --- a/examples/qml/referenceexamples/methods/main.cpp +++ b/examples/qml/referenceexamples/methods/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #include #include #include @@ -63,10 +64,10 @@ int main(int argc, char ** argv) auto *party = qobject_cast(component.create()); if (party && party->host()) { - qWarning() << party->host()->name() << "is having a birthday!"; - qWarning() << "They are inviting:"; - for (int ii = 0; ii < party->guestCount(); ++ii) - qWarning() << " " << party->guest(ii)->name(); + qInfo() << party->host()->name() << "is having a birthday!" + << "\nThey are inviting:"; + for (qsizetype ii = 0; ii < party->guestCount(); ++ii) + qInfo() << " " << party->guest(ii)->name(); return EXIT_SUCCESS; } diff --git a/examples/qml/referenceexamples/methods/person.cpp b/examples/qml/referenceexamples/methods/person.cpp index 7712363ebf4..e2847a26826 100644 --- a/examples/qml/referenceexamples/methods/person.cpp +++ b/examples/qml/referenceexamples/methods/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "person.h" -Person::Person(QObject *parent) -: QObject(parent), m_shoeSize(0) -{ -} +#include "person.h" QString Person::name() const { @@ -73,4 +69,3 @@ void Person::setShoeSize(int s) { m_shoeSize = s; } - diff --git a/examples/qml/referenceexamples/methods/person.h b/examples/qml/referenceexamples/methods/person.h index 2407fbb1b98..0849d1ee8c5 100644 --- a/examples/qml/referenceexamples/methods/person.h +++ b/examples/qml/referenceexamples/methods/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef PERSON_H #define PERSON_H @@ -60,16 +61,17 @@ class Person : public QObject Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize) QML_ELEMENT public: - Person(QObject *parent = nullptr); + using QObject::QObject; QString name() const; void setName(const QString &); int shoeSize() const; void setShoeSize(int); + private: QString m_name; - int m_shoeSize; + int m_shoeSize = 0; }; #endif // PERSON_H diff --git a/examples/qml/referenceexamples/properties/CMakeLists.txt b/examples/qml/referenceexamples/properties/CMakeLists.txt index 1d4daf56d67..11f70f337f9 100644 --- a/examples/qml/referenceexamples/properties/CMakeLists.txt +++ b/examples/qml/referenceexamples/properties/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from properties.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(properties LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -32,17 +32,11 @@ target_link_libraries(properties PUBLIC Qt::Qml ) - -# Resources: -set(properties_resource_files - "example.qml" -) - -qt6_add_resources(properties "properties" - PREFIX - "/" - FILES - ${properties_resource_files} +qt_add_qml_module(properties + URI People + VERSION 1.0 + QML_FILES example.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS properties @@ -50,10 +44,3 @@ install(TARGETS properties BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(properties PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI People -) - -qt6_qml_type_registration(properties) diff --git a/examples/qml/referenceexamples/properties/birthdayparty.cpp b/examples/qml/referenceexamples/properties/birthdayparty.cpp index 2dc9bd803de..aca626db74f 100644 --- a/examples/qml/referenceexamples/properties/birthdayparty.cpp +++ b/examples/qml/referenceexamples/properties/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "birthdayparty.h" -BirthdayParty::BirthdayParty(QObject *parent) -: QObject(parent), m_host(nullptr) -{ -} +#include "birthdayparty.h" // ![0] Person *BirthdayParty::host() const @@ -76,11 +72,11 @@ QQmlListProperty BirthdayParty::guests() &BirthdayParty::removeLastGuest}; } -void BirthdayParty::appendGuest(Person* p) { +void BirthdayParty::appendGuest(Person *p) +{ m_guests.append(p); } - qsizetype BirthdayParty::guestCount() const { return m_guests.count(); @@ -107,12 +103,14 @@ void BirthdayParty::removeLastGuest() // ![0] -void BirthdayParty::appendGuest(QQmlListProperty* list, Person* p) { - reinterpret_cast< BirthdayParty* >(list->data)->appendGuest(p); +void BirthdayParty::appendGuest(QQmlListProperty *list, Person *p) +{ + reinterpret_cast< BirthdayParty *>(list->data)->appendGuest(p); } -void BirthdayParty::clearGuests(QQmlListProperty* list) { - reinterpret_cast< BirthdayParty* >(list->data)->clearGuests(); +void BirthdayParty::clearGuests(QQmlListProperty* list) +{ + reinterpret_cast< BirthdayParty *>(list->data)->clearGuests(); } void BirthdayParty::replaceGuest(QQmlListProperty *list, qsizetype i, Person *p) @@ -125,10 +123,12 @@ void BirthdayParty::removeLastGuest(QQmlListProperty *list) reinterpret_cast< BirthdayParty* >(list->data)->removeLastGuest(); } -Person* BirthdayParty::guest(QQmlListProperty* list, qsizetype i) { +Person* BirthdayParty::guest(QQmlListProperty *list, qsizetype i) +{ return reinterpret_cast< BirthdayParty* >(list->data)->guest(i); } -qsizetype BirthdayParty::guestCount(QQmlListProperty* list) { +qsizetype BirthdayParty::guestCount(QQmlListProperty *list) +{ return reinterpret_cast< BirthdayParty* >(list->data)->guestCount(); } diff --git a/examples/qml/referenceexamples/properties/birthdayparty.h b/examples/qml/referenceexamples/properties/birthdayparty.h index 7e1668add3d..278c011d11f 100644 --- a/examples/qml/referenceexamples/properties/birthdayparty.h +++ b/examples/qml/referenceexamples/properties/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef BIRTHDAYPARTY_H #define BIRTHDAYPARTY_H @@ -69,28 +70,28 @@ class BirthdayParty : public QObject // ![3] QML_ELEMENT public: - BirthdayParty(QObject *parent = nullptr); + using QObject::QObject; Person *host() const; void setHost(Person *); QQmlListProperty guests(); - void appendGuest(Person*); + void appendGuest(Person *); qsizetype guestCount() const; Person *guest(qsizetype) const; void clearGuests(); - void replaceGuest(qsizetype, Person*); + void replaceGuest(qsizetype, Person *); void removeLastGuest(); private: - static void appendGuest(QQmlListProperty*, Person*); - static qsizetype guestCount(QQmlListProperty*); - static Person* guest(QQmlListProperty*, qsizetype); - static void clearGuests(QQmlListProperty*); - static void replaceGuest(QQmlListProperty*, qsizetype, Person*); - static void removeLastGuest(QQmlListProperty*); + static void appendGuest(QQmlListProperty *, Person *); + static qsizetype guestCount(QQmlListProperty *); + static Person* guest(QQmlListProperty *, qsizetype); + static void clearGuests(QQmlListProperty *); + static void replaceGuest(QQmlListProperty *, qsizetype, Person *); + static void removeLastGuest(QQmlListProperty *); - Person *m_host; + Person *m_host = nullptr; QList m_guests; }; // ![3] diff --git a/examples/qml/referenceexamples/properties/main.cpp b/examples/qml/referenceexamples/properties/main.cpp index e30e1d9fb17..cd714970028 100644 --- a/examples/qml/referenceexamples/properties/main.cpp +++ b/examples/qml/referenceexamples/properties/main.cpp @@ -63,10 +63,10 @@ int main(int argc, char ** argv) auto *party = qobject_cast(component.create()); if (party && party->host()) { - qWarning() << party->host()->name() << "is having a birthday!"; - qWarning() << "They are inviting:"; - for (int ii = 0; ii < party->guestCount(); ++ii) - qWarning() << " " << party->guest(ii)->name(); + qInfo() << party->host()->name() << "is having a birthday!\n" + "They are inviting:"; + for (qsizetype ii = 0; ii < party->guestCount(); ++ii) + qInfo() << " " << party->guest(ii)->name(); return EXIT_SUCCESS; } diff --git a/examples/qml/referenceexamples/properties/person.cpp b/examples/qml/referenceexamples/properties/person.cpp index 7712363ebf4..e2847a26826 100644 --- a/examples/qml/referenceexamples/properties/person.cpp +++ b/examples/qml/referenceexamples/properties/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "person.h" -Person::Person(QObject *parent) -: QObject(parent), m_shoeSize(0) -{ -} +#include "person.h" QString Person::name() const { @@ -73,4 +69,3 @@ void Person::setShoeSize(int s) { m_shoeSize = s; } - diff --git a/examples/qml/referenceexamples/properties/person.h b/examples/qml/referenceexamples/properties/person.h index 2407fbb1b98..0849d1ee8c5 100644 --- a/examples/qml/referenceexamples/properties/person.h +++ b/examples/qml/referenceexamples/properties/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef PERSON_H #define PERSON_H @@ -60,16 +61,17 @@ class Person : public QObject Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize) QML_ELEMENT public: - Person(QObject *parent = nullptr); + using QObject::QObject; QString name() const; void setName(const QString &); int shoeSize() const; void setShoeSize(int); + private: QString m_name; - int m_shoeSize; + int m_shoeSize = 0; }; #endif // PERSON_H diff --git a/examples/qml/referenceexamples/signal/CMakeLists.txt b/examples/qml/referenceexamples/signal/CMakeLists.txt index b309efc576e..23e494f7c97 100644 --- a/examples/qml/referenceexamples/signal/CMakeLists.txt +++ b/examples/qml/referenceexamples/signal/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from signal.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(signal LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -34,17 +34,11 @@ target_link_libraries(signal PUBLIC Qt::Qml ) - -# Resources: -set(signal_resource_files - "example.qml" -) - -qt6_add_resources(signal "signal" - PREFIX - "/" - FILES - ${signal_resource_files} +qt_add_qml_module(signal + URI People + VERSION 1.0 + QML_FILES example.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS signal @@ -52,10 +46,3 @@ install(TARGETS signal BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(signal PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI People -) - -qt6_qml_type_registration(signal) diff --git a/examples/qml/referenceexamples/signal/birthdayparty.cpp b/examples/qml/referenceexamples/signal/birthdayparty.cpp index 215c09782a7..27498c9cc9c 100644 --- a/examples/qml/referenceexamples/signal/birthdayparty.cpp +++ b/examples/qml/referenceexamples/signal/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,16 +47,12 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "birthdayparty.h" -BirthdayPartyAttached::BirthdayPartyAttached(QObject *object) -: QObject(object) -{ -} +#include "birthdayparty.h" QDate BirthdayPartyAttached::rsvp() const { - return m_rsvp; + return m_rsvp; } void BirthdayPartyAttached::setRsvp(QDate d) @@ -64,12 +60,6 @@ void BirthdayPartyAttached::setRsvp(QDate d) m_rsvp = d; } - -BirthdayParty::BirthdayParty(QObject *parent) -: QObject(parent), m_host(nullptr) -{ -} - Person *BirthdayParty::host() const { return m_host; @@ -85,12 +75,12 @@ QQmlListProperty BirthdayParty::guests() return {this, &m_guests}; } -int BirthdayParty::guestCount() const +qsizetype BirthdayParty::guestCount() const { return m_guests.count(); } -Person *BirthdayParty::guest(int index) const +Person *BirthdayParty::guest(qsizetype index) const { return m_guests.at(index); } diff --git a/examples/qml/referenceexamples/signal/birthdayparty.h b/examples/qml/referenceexamples/signal/birthdayparty.h index 6d7e022df0b..c4a4da5dfb5 100644 --- a/examples/qml/referenceexamples/signal/birthdayparty.h +++ b/examples/qml/referenceexamples/signal/birthdayparty.h @@ -61,7 +61,7 @@ class BirthdayPartyAttached : public QObject Q_PROPERTY(QDate rsvp READ rsvp WRITE setRsvp) QML_ANONYMOUS public: - BirthdayPartyAttached(QObject *object); + using QObject::QObject; QDate rsvp() const; void setRsvp(QDate); @@ -79,14 +79,14 @@ class BirthdayParty : public QObject QML_ELEMENT QML_ATTACHED(BirthdayPartyAttached) public: - BirthdayParty(QObject *parent = nullptr); + using QObject::QObject; Person *host() const; void setHost(Person *); QQmlListProperty guests(); - int guestCount() const; - Person *guest(int) const; + qsizetype guestCount() const; + Person *guest(qsizetype) const; static BirthdayPartyAttached *qmlAttachedProperties(QObject *); @@ -97,7 +97,7 @@ class BirthdayParty : public QObject // ![0] private: - Person *m_host; + Person *m_host = nullptr; QList m_guests; }; diff --git a/examples/qml/referenceexamples/signal/main.cpp b/examples/qml/referenceexamples/signal/main.cpp index 7ef3595a8c8..d0b060d8e6b 100644 --- a/examples/qml/referenceexamples/signal/main.cpp +++ b/examples/qml/referenceexamples/signal/main.cpp @@ -63,14 +63,14 @@ int main(int argc, char ** argv) auto *party = qobject_cast(component.create()); if (party && party->host()) { - qWarning() << party->host()->name() << "is having a birthday!"; + qInfo() << party->host()->name() << "is having a birthday!"; if (qobject_cast(party->host())) - qWarning() << "He is inviting:"; + qInfo() << "He is inviting:"; else - qWarning() << "She is inviting:"; + qInfo() << "She is inviting:"; - for (int ii = 0; ii < party->guestCount(); ++ii) { + for (qsizetype ii = 0; ii < party->guestCount(); ++ii) { Person *guest = party->guest(ii); QDate rsvpDate; @@ -80,9 +80,9 @@ int main(int argc, char ** argv) rsvpDate = attached->property("rsvp").toDate(); if (rsvpDate.isNull()) - qWarning() << " " << guest->name() << "RSVP date: Hasn't RSVP'd"; + qInfo() << " " << guest->name() << "RSVP date: Hasn't RSVP'd"; else - qWarning() << " " << guest->name() << "RSVP date:" << qPrintable(rsvpDate.toString()); + qInfo() << " " << guest->name() << "RSVP date:" << rsvpDate.toString(); } party->startParty(); diff --git a/examples/qml/referenceexamples/signal/person.cpp b/examples/qml/referenceexamples/signal/person.cpp index 06036441087..4e52da76c8a 100644 --- a/examples/qml/referenceexamples/signal/person.cpp +++ b/examples/qml/referenceexamples/signal/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "person.h" -ShoeDescription::ShoeDescription(QObject *parent) -: QObject(parent), m_size(0), m_price(0) -{ -} +#include "person.h" int ShoeDescription::size() const { @@ -94,11 +90,6 @@ void ShoeDescription::setPrice(qreal p) m_price = p; } -Person::Person(QObject *parent) -: QObject(parent) -{ -} - QString Person::name() const { return m_name; @@ -113,16 +104,3 @@ ShoeDescription *Person::shoe() { return &m_shoe; } - - -Boy::Boy(QObject * parent) -: Person(parent) -{ -} - - -Girl::Girl(QObject * parent) -: Person(parent) -{ -} - diff --git a/examples/qml/referenceexamples/signal/person.h b/examples/qml/referenceexamples/signal/person.h index 7283f39f61a..ddd3baa5f20 100644 --- a/examples/qml/referenceexamples/signal/person.h +++ b/examples/qml/referenceexamples/signal/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef PERSON_H #define PERSON_H @@ -63,7 +64,7 @@ class ShoeDescription : public QObject Q_PROPERTY(qreal price READ price WRITE setPrice) QML_ANONYMOUS public: - ShoeDescription(QObject *parent = nullptr); + using QObject::QObject; int size() const; void setSize(int); @@ -76,11 +77,12 @@ class ShoeDescription : public QObject qreal price() const; void setPrice(qreal); + private: - int m_size; + int m_size = 0; QColor m_color; QString m_brand; - qreal m_price; + qreal m_price = 0; }; class Person : public QObject @@ -90,7 +92,7 @@ class Person : public QObject Q_PROPERTY(ShoeDescription *shoe READ shoe) QML_ANONYMOUS public: - Person(QObject *parent = nullptr); + using QObject::QObject; QString name() const; void setName(const QString &); @@ -106,7 +108,7 @@ class Boy : public Person Q_OBJECT QML_ELEMENT public: - Boy(QObject * parent = nullptr); + using Person::Person; }; class Girl : public Person @@ -114,7 +116,7 @@ class Girl : public Person Q_OBJECT QML_ELEMENT public: - Girl(QObject * parent = nullptr); + using Person::Person; }; #endif // PERSON_H diff --git a/examples/qml/referenceexamples/valuesource/CMakeLists.txt b/examples/qml/referenceexamples/valuesource/CMakeLists.txt index 9bdf9fc3096..3e997bb8f80 100644 --- a/examples/qml/referenceexamples/valuesource/CMakeLists.txt +++ b/examples/qml/referenceexamples/valuesource/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from valuesource.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(valuesource LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -35,17 +35,11 @@ target_link_libraries(valuesource PUBLIC Qt::Qml ) - -# Resources: -set(valuesource_resource_files - "example.qml" -) - -qt6_add_resources(valuesource "valuesource" - PREFIX - "/" - FILES - ${valuesource_resource_files} +qt_add_qml_module(valuesource + URI People + VERSION 1.0 + QML_FILES example.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS valuesource @@ -53,10 +47,3 @@ install(TARGETS valuesource BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(valuesource PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI People -) - -qt6_qml_type_registration(valuesource) diff --git a/examples/qml/referenceexamples/valuesource/birthdayparty.cpp b/examples/qml/referenceexamples/valuesource/birthdayparty.cpp index 7ad11066cb5..ced34c0cbbb 100644 --- a/examples/qml/referenceexamples/valuesource/birthdayparty.cpp +++ b/examples/qml/referenceexamples/valuesource/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "birthdayparty.h" -BirthdayPartyAttached::BirthdayPartyAttached(QObject *object) -: QObject(object) -{ -} +#include "birthdayparty.h" QDate BirthdayPartyAttached::rsvp() const { @@ -64,12 +60,6 @@ void BirthdayPartyAttached::setRsvp(QDate d) m_rsvp = d; } - -BirthdayParty::BirthdayParty(QObject *parent) -: QObject(parent), m_host(nullptr) -{ -} - Person *BirthdayParty::host() const { return m_host; @@ -85,12 +75,12 @@ QQmlListProperty BirthdayParty::guests() return {this, &m_guests}; } -int BirthdayParty::guestCount() const +qsizetype BirthdayParty::guestCount() const { return m_guests.count(); } -Person *BirthdayParty::guest(int index) const +Person *BirthdayParty::guest(qsizetype index) const { return m_guests.at(index); } @@ -108,11 +98,10 @@ QString BirthdayParty::announcement() const void BirthdayParty::setAnnouncement(const QString &speak) { - qWarning() << qPrintable(speak); + qInfo().noquote() << speak; } BirthdayPartyAttached *BirthdayParty::qmlAttachedProperties(QObject *object) { return new BirthdayPartyAttached(object); } - diff --git a/examples/qml/referenceexamples/valuesource/birthdayparty.h b/examples/qml/referenceexamples/valuesource/birthdayparty.h index abd63635712..4c661499cea 100644 --- a/examples/qml/referenceexamples/valuesource/birthdayparty.h +++ b/examples/qml/referenceexamples/valuesource/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef BIRTHDAYPARTY_H #define BIRTHDAYPARTY_H @@ -62,7 +63,7 @@ class BirthdayPartyAttached : public QObject Q_PROPERTY(QDate rsvp READ rsvp WRITE setRsvp) QML_ANONYMOUS public: - BirthdayPartyAttached(QObject *object); + using QObject::QObject; QDate rsvp() const; void setRsvp(QDate); @@ -83,14 +84,14 @@ class BirthdayParty : public QObject QML_ELEMENT QML_ATTACHED(BirthdayPartyAttached) public: - BirthdayParty(QObject *parent = nullptr); + using QObject::QObject; Person *host() const; void setHost(Person *); QQmlListProperty guests(); - int guestCount() const; - Person *guest(int) const; + qsizetype guestCount() const; + Person *guest(qsizetype) const; QString announcement() const; void setAnnouncement(const QString &); @@ -98,11 +99,12 @@ class BirthdayParty : public QObject static BirthdayPartyAttached *qmlAttachedProperties(QObject *); void startParty(); + signals: void partyStarted(QTime time); private: - Person *m_host; + Person *m_host = nullptr; QList m_guests; }; diff --git a/examples/qml/referenceexamples/valuesource/happybirthdaysong.cpp b/examples/qml/referenceexamples/valuesource/happybirthdaysong.cpp index da09d3d7bad..635a50ef129 100644 --- a/examples/qml/referenceexamples/valuesource/happybirthdaysong.cpp +++ b/examples/qml/referenceexamples/valuesource/happybirthdaysong.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,13 +47,13 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #include "happybirthdaysong.h" #include -HappyBirthdaySong::HappyBirthdaySong(QObject *parent) -: QObject(parent), m_line(-1) +HappyBirthdaySong::HappyBirthdaySong(QObject *parent) : + QObject(parent) { - setName(QString()); auto *timer = new QTimer(this); QObject::connect(timer, &QTimer::timeout, this, &HappyBirthdaySong::advance); timer->start(1000); diff --git a/examples/qml/referenceexamples/valuesource/happybirthdaysong.h b/examples/qml/referenceexamples/valuesource/happybirthdaysong.h index 2600208968c..146e336487d 100644 --- a/examples/qml/referenceexamples/valuesource/happybirthdaysong.h +++ b/examples/qml/referenceexamples/valuesource/happybirthdaysong.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef HAPPYBIRTHDAYSONG_H #define HAPPYBIRTHDAYSONG_H @@ -66,7 +67,7 @@ class HappyBirthdaySong : public QObject, public QQmlPropertyValueSource // ![1] QML_ELEMENT public: - HappyBirthdaySong(QObject *parent = nullptr); + explicit HappyBirthdaySong(QObject *parent = nullptr); void setTarget(const QQmlProperty &) override; // ![1] @@ -78,7 +79,7 @@ private slots: void advance(); private: - int m_line; + qsizetype m_line = -1; QStringList m_lyrics; QQmlProperty m_target; QString m_name; diff --git a/examples/qml/referenceexamples/valuesource/main.cpp b/examples/qml/referenceexamples/valuesource/main.cpp index 2e9995fcd88..a100497659c 100644 --- a/examples/qml/referenceexamples/valuesource/main.cpp +++ b/examples/qml/referenceexamples/valuesource/main.cpp @@ -64,14 +64,14 @@ int main(int argc, char ** argv) auto *party = qobject_cast(component.create()); if (party && party->host()) { - qWarning() << party->host()->name() << "is having a birthday!"; + qInfo() << party->host()->name() << "is having a birthday!"; if (qobject_cast(party->host())) - qWarning() << "He is inviting:"; + qInfo() << "He is inviting:"; else - qWarning() << "She is inviting:"; + qInfo() << "She is inviting:"; - for (int ii = 0; ii < party->guestCount(); ++ii) { + for (qsizetype ii = 0; ii < party->guestCount(); ++ii) { Person *guest = party->guest(ii); QDate rsvpDate; @@ -81,9 +81,9 @@ int main(int argc, char ** argv) rsvpDate = attached->property("rsvp").toDate(); if (rsvpDate.isNull()) - qWarning() << " " << guest->name() << "RSVP date: Hasn't RSVP'd"; + qInfo() << " " << guest->name() << "RSVP date: Hasn't RSVP'd"; else - qWarning() << " " << guest->name() << "RSVP date:" << qPrintable(rsvpDate.toString()); + qInfo() << " " << guest->name() << "RSVP date:" << rsvpDate.toString(); } party->startParty(); diff --git a/examples/qml/referenceexamples/valuesource/person.cpp b/examples/qml/referenceexamples/valuesource/person.cpp index 06036441087..4e52da76c8a 100644 --- a/examples/qml/referenceexamples/valuesource/person.cpp +++ b/examples/qml/referenceexamples/valuesource/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,12 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "person.h" -ShoeDescription::ShoeDescription(QObject *parent) -: QObject(parent), m_size(0), m_price(0) -{ -} +#include "person.h" int ShoeDescription::size() const { @@ -94,11 +90,6 @@ void ShoeDescription::setPrice(qreal p) m_price = p; } -Person::Person(QObject *parent) -: QObject(parent) -{ -} - QString Person::name() const { return m_name; @@ -113,16 +104,3 @@ ShoeDescription *Person::shoe() { return &m_shoe; } - - -Boy::Boy(QObject * parent) -: Person(parent) -{ -} - - -Girl::Girl(QObject * parent) -: Person(parent) -{ -} - diff --git a/examples/qml/referenceexamples/valuesource/person.h b/examples/qml/referenceexamples/valuesource/person.h index 7283f39f61a..ed77f8c4d82 100644 --- a/examples/qml/referenceexamples/valuesource/person.h +++ b/examples/qml/referenceexamples/valuesource/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,6 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef PERSON_H #define PERSON_H @@ -63,7 +64,7 @@ class ShoeDescription : public QObject Q_PROPERTY(qreal price READ price WRITE setPrice) QML_ANONYMOUS public: - ShoeDescription(QObject *parent = nullptr); + using QObject::QObject; int size() const; void setSize(int); @@ -76,21 +77,24 @@ class ShoeDescription : public QObject qreal price() const; void setPrice(qreal); + private: - int m_size; + int m_size = 0; QColor m_color; QString m_brand; - qreal m_price; + qreal m_price = 0; }; class Person : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName) +// ![1] Q_PROPERTY(ShoeDescription *shoe READ shoe) +// ![1] QML_ANONYMOUS public: - Person(QObject *parent = nullptr); + using QObject::QObject; QString name() const; void setName(const QString &); @@ -106,7 +110,7 @@ class Boy : public Person Q_OBJECT QML_ELEMENT public: - Boy(QObject * parent = nullptr); + using Person::Person; }; class Girl : public Person @@ -114,7 +118,7 @@ class Girl : public Person Q_OBJECT QML_ELEMENT public: - Girl(QObject * parent = nullptr); + using Person::Person; }; #endif // PERSON_H diff --git a/examples/qml/shell/CMakeLists.txt b/examples/qml/shell/CMakeLists.txt index 6c986b7778e..c048159fc40 100644 --- a/examples/qml/shell/CMakeLists.txt +++ b/examples/qml/shell/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from shell.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(shell LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) diff --git a/examples/qml/tutorials/extending-qml/.prev_CMakeLists.txt b/examples/qml/tutorials/extending-qml/.prev_CMakeLists.txt deleted file mode 100644 index 8e41f3d77d1..00000000000 --- a/examples/qml/tutorials/extending-qml/.prev_CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Generated from extending-qml.pro. - -add_subdirectory(chapter1-basics) -add_subdirectory(chapter2-methods) -add_subdirectory(chapter3-bindings) -add_subdirectory(chapter4-customPropertyTypes) -add_subdirectory(chapter5-listproperties) -add_subdirectory(chapter6-plugins) diff --git a/examples/qml/tutorials/extending-qml/chapter1-basics/CMakeLists.txt b/examples/qml/tutorials/extending-qml/chapter1-basics/CMakeLists.txt index 7e1f1887c4e..146ba6c887d 100644 --- a/examples/qml/tutorials/extending-qml/chapter1-basics/CMakeLists.txt +++ b/examples/qml/tutorials/extending-qml/chapter1-basics/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from chapter1-basics.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(chapter1-basics LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -35,17 +35,12 @@ target_link_libraries(chapter1-basics PUBLIC Qt::Quick ) - -# Resources: -set(chapter1-basics_resource_files - "app.qml" -) - -qt6_add_resources(chapter1-basics "chapter1-basics" - PREFIX - "/" - FILES - ${chapter1-basics_resource_files} +qt_add_qml_module(chapter1-basics + URI Charts + VERSION 1.0 + QML_FILES app.qml + NO_RESOURCE_TARGET_PATH + DEPENDENCIES QtQuick ) install(TARGETS chapter1-basics @@ -53,10 +48,3 @@ install(TARGETS chapter1-basics BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(chapter1-basics PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI Charts -) - -qt6_qml_type_registration(chapter1-basics) diff --git a/examples/qml/tutorials/extending-qml/chapter1-basics/piechart.h b/examples/qml/tutorials/extending-qml/chapter1-basics/piechart.h index 687f8e2b4dc..742f8ec0fd2 100644 --- a/examples/qml/tutorials/extending-qml/chapter1-basics/piechart.h +++ b/examples/qml/tutorials/extending-qml/chapter1-basics/piechart.h @@ -57,8 +57,8 @@ class PieChart : public QQuickPaintedItem { Q_OBJECT - Q_PROPERTY(QString name READ name WRITE setName) - Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(QString name READ name WRITE setName FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) QML_ELEMENT public: diff --git a/examples/qml/tutorials/extending-qml/chapter2-methods/CMakeLists.txt b/examples/qml/tutorials/extending-qml/chapter2-methods/CMakeLists.txt index 456c3965ebe..c5e066cad02 100644 --- a/examples/qml/tutorials/extending-qml/chapter2-methods/CMakeLists.txt +++ b/examples/qml/tutorials/extending-qml/chapter2-methods/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from chapter2-methods.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(chapter2-methods LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -35,17 +35,12 @@ target_link_libraries(chapter2-methods PUBLIC Qt::Quick ) - -# Resources: -set(chapter2-methods_resource_files - "app.qml" -) - -qt6_add_resources(chapter2-methods "chapter2-methods" - PREFIX - "/" - FILES - ${chapter2-methods_resource_files} +qt_add_qml_module(chapter2-methods + URI Charts + VERSION 1.0 + QML_FILES app.qml + NO_RESOURCE_TARGET_PATH + DEPENDENCIES QtQuick ) install(TARGETS chapter2-methods @@ -53,10 +48,3 @@ install(TARGETS chapter2-methods BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(chapter2-methods PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI Charts -) - -qt6_qml_type_registration(chapter2-methods) diff --git a/examples/qml/tutorials/extending-qml/chapter2-methods/piechart.h b/examples/qml/tutorials/extending-qml/chapter2-methods/piechart.h index 271afbf6539..6457a8561df 100644 --- a/examples/qml/tutorials/extending-qml/chapter2-methods/piechart.h +++ b/examples/qml/tutorials/extending-qml/chapter2-methods/piechart.h @@ -58,8 +58,8 @@ class PieChart : public QQuickPaintedItem { //![0] Q_OBJECT - Q_PROPERTY(QString name READ name WRITE setName) - Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(QString name READ name WRITE setName FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) QML_ELEMENT //![1] public: diff --git a/examples/qml/tutorials/extending-qml/chapter3-bindings/CMakeLists.txt b/examples/qml/tutorials/extending-qml/chapter3-bindings/CMakeLists.txt index 6b81e93dff7..184f440c1dc 100644 --- a/examples/qml/tutorials/extending-qml/chapter3-bindings/CMakeLists.txt +++ b/examples/qml/tutorials/extending-qml/chapter3-bindings/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from chapter3-bindings.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(chapter3-bindings LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -35,17 +35,12 @@ target_link_libraries(chapter3-bindings PUBLIC Qt::Quick ) - -# Resources: -set(chapter3-bindings_resource_files - "app.qml" -) - -qt6_add_resources(chapter3-bindings "chapter3-bindings" - PREFIX - "/" - FILES - ${chapter3-bindings_resource_files} +qt_add_qml_module(chapter3-bindings + URI Charts + VERSION 1.0 + QML_FILES app.qml + NO_RESOURCE_TARGET_PATH + DEPENDENCIES QtQuick ) install(TARGETS chapter3-bindings @@ -53,10 +48,3 @@ install(TARGETS chapter3-bindings BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(chapter3-bindings PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI Charts -) - -qt6_qml_type_registration(chapter3-bindings) diff --git a/examples/qml/tutorials/extending-qml/chapter3-bindings/piechart.h b/examples/qml/tutorials/extending-qml/chapter3-bindings/piechart.h index 58b1339298e..ef3f6a79dc3 100644 --- a/examples/qml/tutorials/extending-qml/chapter3-bindings/piechart.h +++ b/examples/qml/tutorials/extending-qml/chapter3-bindings/piechart.h @@ -58,11 +58,11 @@ class PieChart : public QQuickPaintedItem { //![0] Q_OBJECT - Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QString name READ name WRITE setName FINAL) QML_ELEMENT //![1] - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL) public: //![1] diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/CMakeLists.txt b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/CMakeLists.txt index 55fb20ea416..51855394e34 100644 --- a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/CMakeLists.txt +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from chapter4-customPropertyTypes.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(chapter4-customPropertyTypes LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -36,17 +36,12 @@ target_link_libraries(chapter4-customPropertyTypes PUBLIC Qt::Quick ) - -# Resources: -set(chapter4-customPropertyTypes_resource_files - "app.qml" -) - -qt6_add_resources(chapter4-customPropertyTypes "chapter4-customPropertyTypes" - PREFIX - "/" - FILES - ${chapter4-customPropertyTypes_resource_files} +qt_add_qml_module(chapter4-customPropertyTypes + URI Charts + VERSION 1.0 + QML_FILES app.qml + NO_RESOURCE_TARGET_PATH + DEPENDENCIES QtQuick ) install(TARGETS chapter4-customPropertyTypes @@ -54,10 +49,3 @@ install(TARGETS chapter4-customPropertyTypes BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(chapter4-customPropertyTypes PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI Charts -) - -qt6_qml_type_registration(chapter4-customPropertyTypes) diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/piechart.h b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/piechart.h index 855ad7ae3a2..57ef7d90e2a 100644 --- a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/piechart.h +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/piechart.h @@ -58,9 +58,9 @@ class PieSlice; class PieChart : public QQuickItem { Q_OBJECT - Q_PROPERTY(PieSlice* pieSlice READ pieSlice WRITE setPieSlice) + Q_PROPERTY(PieSlice* pieSlice READ pieSlice WRITE setPieSlice FINAL) //![0] - Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QString name READ name WRITE setName FINAL) Q_MOC_INCLUDE("pieslice.h") QML_ELEMENT //![1] diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.h b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.h index 6e64917851e..84d1789e560 100644 --- a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.h +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.h @@ -57,7 +57,7 @@ class PieSlice : public QQuickPaintedItem { Q_OBJECT - Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) QML_ELEMENT public: diff --git a/examples/qml/tutorials/extending-qml/chapter5-listproperties/CMakeLists.txt b/examples/qml/tutorials/extending-qml/chapter5-listproperties/CMakeLists.txt index f41a349eac9..ac3f7839abc 100644 --- a/examples/qml/tutorials/extending-qml/chapter5-listproperties/CMakeLists.txt +++ b/examples/qml/tutorials/extending-qml/chapter5-listproperties/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from chapter5-listproperties.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(chapter5-listproperties LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -36,17 +36,12 @@ target_link_libraries(chapter5-listproperties PUBLIC Qt::Quick ) - -# Resources: -set(chapter5-listproperties_resource_files - "app.qml" -) - -qt6_add_resources(chapter5-listproperties "chapter5-listproperties" - PREFIX - "/" - FILES - ${chapter5-listproperties_resource_files} +qt_add_qml_module(chapter5-listproperties + URI Charts + VERSION 1.0 + QML_FILES app.qml + NO_RESOURCE_TARGET_PATH + DEPENDENCIES QtQuick ) install(TARGETS chapter5-listproperties @@ -54,10 +49,3 @@ install(TARGETS chapter5-listproperties BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(chapter5-listproperties PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI Charts -) - -qt6_qml_type_registration(chapter5-listproperties) diff --git a/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.h b/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.h index 236fa6796fb..3caa80ed533 100644 --- a/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.h +++ b/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.h @@ -58,9 +58,9 @@ class PieSlice; class PieChart : public QQuickItem { Q_OBJECT - Q_PROPERTY(QQmlListProperty slices READ slices) + Q_PROPERTY(QQmlListProperty slices READ slices FINAL) //![0] - Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QString name READ name WRITE setName FINAL) QML_ELEMENT //![1] diff --git a/examples/qml/tutorials/extending-qml/chapter5-listproperties/pieslice.h b/examples/qml/tutorials/extending-qml/chapter5-listproperties/pieslice.h index 0b290851f00..50c573c7bc9 100644 --- a/examples/qml/tutorials/extending-qml/chapter5-listproperties/pieslice.h +++ b/examples/qml/tutorials/extending-qml/chapter5-listproperties/pieslice.h @@ -57,9 +57,9 @@ class PieSlice : public QQuickPaintedItem { Q_OBJECT - Q_PROPERTY(QColor color READ color WRITE setColor) - Q_PROPERTY(int fromAngle READ fromAngle WRITE setFromAngle) - Q_PROPERTY(int angleSpan READ angleSpan WRITE setAngleSpan) + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + Q_PROPERTY(int fromAngle READ fromAngle WRITE setFromAngle FINAL) + Q_PROPERTY(int angleSpan READ angleSpan WRITE setAngleSpan FINAL) QML_ELEMENT //![0] diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/.prev_CMakeLists.txt b/examples/qml/tutorials/extending-qml/chapter6-plugins/.prev_CMakeLists.txt deleted file mode 100644 index 0d68df497a1..00000000000 --- a/examples/qml/tutorials/extending-qml/chapter6-plugins/.prev_CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -# Generated from chapter6-plugins.pro. - -cmake_minimum_required(VERSION 3.14) -project(chapter6-plugins LANGUAGES CXX) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/tutorials/extending-qml/chapter6-plugins") - -find_package(Qt6 COMPONENTS Qml) -find_package(Qt6 COMPONENTS Quick) - -qt_add_executable(chapter6-plugins - main.cpp -) -set_target_properties(chapter6-plugins PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(chapter6-plugins PUBLIC - Qt::Qml - Qt::Quick -) - - -# Resources: -set(app_resource_files - "app.qml" -) - -qt6_add_resources(chapter6-plugins "app" - PREFIX - "/" - FILES - ${app_resource_files} -) - -install(TARGETS chapter6-plugins - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) -add_subdirectory(import) diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/CMakeLists.txt b/examples/qml/tutorials/extending-qml/chapter6-plugins/CMakeLists.txt index 1c19c84caa4..dc0b20dc215 100644 --- a/examples/qml/tutorials/extending-qml/chapter6-plugins/CMakeLists.txt +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from chapter6-plugins.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(chapter6-plugins LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -25,22 +25,16 @@ set_target_properties(chapter6-plugins PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) -target_link_libraries(chapter6-plugins PUBLIC +target_link_libraries(chapter6-plugins PRIVATE Qt::Qml Qt::Quick ) - -# Resources: -set(app_resource_files - "app.qml" -) - -qt6_add_resources(chapter6-plugins "app" - PREFIX - "/" - FILES - ${app_resource_files} +qt_add_qml_module(chapter6-plugins + URI ChartsApp + VERSION 1.0 + QML_FILES app.qml + NO_RESOURCE_TARGET_PATH ) install(TARGETS chapter6-plugins @@ -49,4 +43,4 @@ install(TARGETS chapter6-plugins LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) -add_subdirectory(import) +add_subdirectory(Charts) diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/CMakeLists.txt b/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/CMakeLists.txt new file mode 100644 index 00000000000..62d4c71fc48 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/CMakeLists.txt @@ -0,0 +1,49 @@ +qt6_add_qml_module(chartsplugin + VERSION 1.0 + URI "Charts" + PLUGIN_TARGET chartsplugin + DEPENDENCIES QtQuick +) + +target_sources(chartsplugin PRIVATE + piechart.cpp piechart.h + pieslice.cpp pieslice.h +) + +target_link_libraries(chartsplugin PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +if(QT6_IS_SHARED_LIBS_BUILD AND APPLE) + get_target_property(is_bundle chapter6-plugins MACOSX_BUNDLE) + if(is_bundle) + # The application's main.cpp adds an explicit QML import path to look for qml modules under + # a PlugIns subdirectory in a macOS bundle. + # Copy the qmldir and shared library qml plugin. + + set(charts_dir "$") + set(chars_qmldir_file "${charts_dir}/qmldir") + set(app_dir "$") + set(bundle_charts_dir "${app_dir}/../PlugIns/Charts") + + add_custom_command(TARGET chartsplugin POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${bundle_charts_dir} + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ ${bundle_charts_dir} + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${chars_qmldir_file} ${bundle_charts_dir} + ) + endif() +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLEDIR}/Charts") +install(TARGETS chartsplugin + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qmldir + DESTINATION "${INSTALL_EXAMPLEDIR}") diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/Charts.pro b/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/Charts.pro new file mode 100644 index 00000000000..e3763b6f5e1 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/Charts.pro @@ -0,0 +1,31 @@ +TEMPLATE = lib +CONFIG += plugin qmltypes +QT += qml quick + +QML_IMPORT_NAME = Charts +QML_IMPORT_MAJOR_VERSION = 1 + +TARGET = $$qtLibraryTarget(chartsplugin) + +HEADERS += piechart.h \ + pieslice.h \ + chartsplugin.h + +SOURCES += piechart.cpp \ + pieslice.cpp + +DESTPATH=$$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter6-plugins/$$QML_IMPORT_NAME + +target.path=$$DESTPATH +qmldir.files=$$PWD/qmldir +qmldir.path=$$DESTPATH +INSTALLS += target qmldir + +CONFIG += install_ok # Do not cargo-cult this! + +OTHER_FILES += qmldir + +# Copy the qmldir file to the same folder as the plugin binary +cpqmldir.files = qmldir +cpqmldir.path = . +COPIES += cpqmldir diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/chartsplugin.h b/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/chartsplugin.h similarity index 100% rename from examples/qml/tutorials/extending-qml/chapter6-plugins/import/chartsplugin.h rename to examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/chartsplugin.h diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.cpp b/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/piechart.cpp similarity index 100% rename from examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.cpp rename to examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/piechart.cpp diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.h b/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/piechart.h similarity index 95% rename from examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.h rename to examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/piechart.h index e6b768b274e..d48f217ea46 100644 --- a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.h +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/piechart.h @@ -57,8 +57,8 @@ class PieSlice; class PieChart : public QQuickItem { Q_OBJECT - Q_PROPERTY(QQmlListProperty slices READ slices) - Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QQmlListProperty slices READ slices FINAL) + Q_PROPERTY(QString name READ name WRITE setName FINAL) QML_ELEMENT public: diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.cpp b/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/pieslice.cpp similarity index 100% rename from examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.cpp rename to examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/pieslice.cpp diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.h b/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/pieslice.h similarity index 93% rename from examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.h rename to examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/pieslice.h index 091870bd516..965b50f0586 100644 --- a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.h +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/pieslice.h @@ -56,9 +56,9 @@ class PieSlice : public QQuickPaintedItem { Q_OBJECT - Q_PROPERTY(QColor color READ color WRITE setColor) - Q_PROPERTY(int fromAngle READ fromAngle WRITE setFromAngle) - Q_PROPERTY(int angleSpan READ angleSpan WRITE setAngleSpan) + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + Q_PROPERTY(int fromAngle READ fromAngle WRITE setFromAngle FINAL) + Q_PROPERTY(int angleSpan READ angleSpan WRITE setAngleSpan FINAL) QML_ELEMENT public: diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/qmldir b/examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/qmldir similarity index 100% rename from examples/qml/tutorials/extending-qml/chapter6-plugins/import/qmldir rename to examples/qml/tutorials/extending-qml/chapter6-plugins/Charts/qmldir diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/app.pro b/examples/qml/tutorials/extending-qml/chapter6-plugins/app.pro index b340981e42c..8f53075a7dc 100644 --- a/examples/qml/tutorials/extending-qml/chapter6-plugins/app.pro +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/app.pro @@ -3,9 +3,9 @@ QT += qml quick # Ensure that the application will see the import path for the Charts module: # * On Windows, do not build into a debug/release subdirectory. -# * On OS X, add the plugin files into the bundle. +# * On macOS, add the plugin files into the bundle, only in a shared build though win32: DESTDIR = ./ -osx { +macos:!qtConfig(static) { charts.files = $$OUT_PWD/Charts charts.path = Contents/PlugIns QMAKE_BUNDLE_DATA += charts diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/chapter6-plugins.pro b/examples/qml/tutorials/extending-qml/chapter6-plugins/chapter6-plugins.pro index f858c80876c..2d782354546 100644 --- a/examples/qml/tutorials/extending-qml/chapter6-plugins/chapter6-plugins.pro +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/chapter6-plugins.pro @@ -1,5 +1,5 @@ TEMPLATE = subdirs CONFIG += ordered SUBDIRS = \ - import \ + Charts \ app.pro diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/CMakeLists.txt b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/CMakeLists.txt deleted file mode 100644 index f75028aa690..00000000000 --- a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# Generated from import.pro. - -cmake_minimum_required(VERSION 3.14) -project(chartsplugin LANGUAGES CXX) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/tutorials/extending-qml/chapter6-plugins/Charts") - -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Qml) -find_package(Qt6 COMPONENTS Quick) - -qt6_add_qml_module(chartsplugin - OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../Charts" - VERSION 1.0 - URI "Charts" - PLUGIN_TARGET chartsplugin -) - -target_sources(chartsplugin PRIVATE - piechart.cpp piechart.h - pieslice.cpp pieslice.h -) -set_target_properties(chartsplugin PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(chartsplugin PUBLIC - Qt::Core - Qt::Gui - Qt::Qml - Qt::Quick -) - -install(TARGETS chartsplugin - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/import.pro b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/import.pro deleted file mode 100644 index c37cd1fdeef..00000000000 --- a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/import.pro +++ /dev/null @@ -1,36 +0,0 @@ -TEMPLATE = lib -CONFIG += plugin qmltypes -QT += qml quick - -QML_IMPORT_NAME = Charts -QML_IMPORT_MAJOR_VERSION = 1 - -DESTDIR = ../$$QML_IMPORT_NAME -TARGET = $$qtLibraryTarget(chartsplugin) - -HEADERS += piechart.h \ - pieslice.h \ - chartsplugin.h - -SOURCES += piechart.cpp \ - pieslice.cpp - -DESTPATH=$$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter6-plugins/$$QML_IMPORT_NAME - -copy_qmltypes.files = $$OUT_PWD/plugins.qmltypes -copy_qmltypes.path = $$DESTDIR -COPIES += copy_qmltypes - -target.path=$$DESTPATH -qmldir.files=$$PWD/qmldir -qmldir.path=$$DESTPATH -INSTALLS += target qmldir - -CONFIG += install_ok # Do not cargo-cult this! - -OTHER_FILES += qmldir - -# Copy the qmldir file to the same folder as the plugin binary -cpqmldir.files = qmldir -cpqmldir.path = $$DESTDIR -COPIES += cpqmldir diff --git a/examples/qml/xmlhttprequest/CMakeLists.txt b/examples/qml/xmlhttprequest/CMakeLists.txt index ebb0d0c011d..a3fe890634d 100644 --- a/examples/qml/xmlhttprequest/CMakeLists.txt +++ b/examples/qml/xmlhttprequest/CMakeLists.txt @@ -1,13 +1,12 @@ # Generated from xmlhttprequest.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(xmlhttprequest LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,65 +14,32 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/xmlhttprequest") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) -qt_add_executable(xmlhttprequest +qt_add_executable(xmlhttprequestexample + WIN32 + MACOSX_BUNDLE main.cpp ) -set_target_properties(xmlhttprequest PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE + +qt_add_qml_module(xmlhttprequestexample + URI xmlhttprequest + VERSION 1.0 + QML_FILES + "methods.js" + "xmlhttprequest.qml" + RESOURCES + data.xml ) -target_link_libraries(xmlhttprequest PUBLIC + +target_link_libraries(xmlhttprequestexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) - -# Resources: -set(xmlhttprequest_resource_files - "Get.qml" - "GetForm.ui.qml" - "data.xml" - "methods.js" - "xmlhttprequest.qml" -) - -qt6_add_resources(xmlhttprequest "xmlhttprequest" - PREFIX - "/qml/xmlhttprequest" - FILES - ${xmlhttprequest_resource_files} -) -set(quick_shared_resource_files - "../../quick/shared/Button.qml" - "../../quick/shared/CheckBox.qml" - "../../quick/shared/Label.qml" - "../../quick/shared/LauncherList.qml" - "../../quick/shared/SimpleLauncherDelegate.qml" - "../../quick/shared/Slider.qml" - "../../quick/shared/TextField.qml" - "../../quick/shared/images/back.png" - "../../quick/shared/images/checkmark.png" - "../../quick/shared/images/next.png" - "../../quick/shared/images/slider_handle.png" -) - -qt6_add_resources(xmlhttprequest "quick_shared" - PREFIX - "/quick/shared" - BASE - "../../quick/shared" - FILES - ${quick_shared_resource_files} -) - -install(TARGETS xmlhttprequest +install(TARGETS xmlhttprequestexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/qml/xmlhttprequest/Get.qml b/examples/qml/xmlhttprequest/Get.qml deleted file mode 100644 index 96cec2a99dd..00000000000 --- a/examples/qml/xmlhttprequest/Get.qml +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -import "methods.js" as Utils - -GetForm -{ - anchors.fill: parent - - mouseArea.onClicked: Utils.makeRequest() - - button.border.width: mouseArea.pressed ? 2 : 1 - text.text: "Request data.xml" - -} diff --git a/examples/qml/xmlhttprequest/GetForm.ui.qml b/examples/qml/xmlhttprequest/GetForm.ui.qml deleted file mode 100644 index 284299ef354..00000000000 --- a/examples/qml/xmlhttprequest/GetForm.ui.qml +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - - -Rectangle { - id:rect - width: 350 - height: 400 - - property alias button: button - property alias text: buttonText - property alias mouseArea: mouseArea - property alias msg: ttext - - Text { id: ttext; anchors.fill: parent; anchors.margins: 10 } - - Rectangle { - id: button - anchors.horizontalCenter: parent.horizontalCenter; - anchors.bottom: parent.bottom - anchors.margins: 10 - width: buttonText.width + 10 - height: buttonText.height + 10 - radius : 5; antialiasing: true - - Text { id: buttonText; anchors.centerIn: parent } - - MouseArea { - id: mouseArea - anchors.fill: parent - } - } -} - diff --git a/examples/qml/xmlhttprequest/main.cpp b/examples/qml/xmlhttprequest/main.cpp index 02be6d21963..cef60a5e6f4 100644 --- a/examples/qml/xmlhttprequest/main.cpp +++ b/examples/qml/xmlhttprequest/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,5 +47,27 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "../../quick/shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(qml/xmlhttprequest/xmlhttprequest) + +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + app.setOrganizationName("QtProject"); + app.setOrganizationDomain("qt-project.org"); + app.setApplicationName(QFileInfo(app.applicationFilePath()).baseName()); + QQuickView view; + + qputenv("QML_XHR_ALLOW_FILE_READ", QByteArray("1")); + + view.connect(view.engine(), &QQmlEngine::quit, &app, &QCoreApplication::quit); + view.setSource(QUrl("qrc:///xmlhttprequest/xmlhttprequest.qml")); + if (view.status() == QQuickView::Error) + return -1; + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.show(); + return app.exec(); +} diff --git a/examples/qml/xmlhttprequest/xmlhttprequest.pro b/examples/qml/xmlhttprequest/xmlhttprequest.pro index 3b78db0252b..6d572fff590 100644 --- a/examples/qml/xmlhttprequest/xmlhttprequest.pro +++ b/examples/qml/xmlhttprequest/xmlhttprequest.pro @@ -3,8 +3,7 @@ TEMPLATE = app QT += quick qml SOURCES += main.cpp RESOURCES += \ - xmlhttprequest.qrc \ - ../../quick/shared/quick_shared.qrc + xmlhttprequest.qrc EXAMPLE_FILES = \ data.xml @@ -13,6 +12,4 @@ target.path = $$[QT_INSTALL_EXAMPLES]/qml/xmlhttprequest INSTALLS += target DISTFILES += \ - Get.qml \ - GetForm.ui.qml \ methods.js diff --git a/examples/qml/xmlhttprequest/xmlhttprequest.qml b/examples/qml/xmlhttprequest/xmlhttprequest.qml index e6c7b10e16c..31aa1824e96 100644 --- a/examples/qml/xmlhttprequest/xmlhttprequest.qml +++ b/examples/qml/xmlhttprequest/xmlhttprequest.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,17 +48,28 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "../../quick/shared" as Examples +import QtQuick +import QtQuick.Controls +import "methods.js" as Utils + Item { height: 480 width: 320 - Examples.LauncherList { - id: ll - anchors.fill: parent - Component.onCompleted: { - addExample("Get data", "Send get request and show received header and body", Qt.resolvedUrl("Get.qml")); - } + + property alias msg: ttext + + Label { id: ttext; anchors.fill: parent; anchors.margins: 10 } + + Button { + id: button + anchors.horizontalCenter: parent.horizontalCenter; + anchors.bottom: parent.bottom + anchors.margins: 10 + antialiasing: true + + text: qsTr("Request data.xml") + + onClicked: Utils.makeRequest() } } diff --git a/examples/qml/xmlhttprequest/xmlhttprequest.qrc b/examples/qml/xmlhttprequest/xmlhttprequest.qrc index 2e5dae4bb81..75c0edca8ae 100644 --- a/examples/qml/xmlhttprequest/xmlhttprequest.qrc +++ b/examples/qml/xmlhttprequest/xmlhttprequest.qrc @@ -1,9 +1,7 @@ - + xmlhttprequest.qml - data.xml methods.js - Get.qml - GetForm.ui.qml + data.xml diff --git a/examples/qmltest/qmltest/.prev_CMakeLists.txt b/examples/qmltest/qmltest/.prev_CMakeLists.txt deleted file mode 100644 index c50eb7bcd36..00000000000 --- a/examples/qmltest/qmltest/.prev_CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -# Generated from qmltest.pro. - -cmake_minimum_required(VERSION 3.14) -project(tst_qmltestexample LANGUAGES CXX) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}") - -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) - -qt_add_executable(tst_qmltestexample - tst_qmltest.cpp -) -set_target_properties(tst_qmltestexample PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(tst_qmltestexample PUBLIC - Qt::Core - Qt::Gui -) - -if(QT_BUILDING_QT) - target_link_libraries(tst_qmltestexample PUBLIC - Qt::Qml - Qt::QuickTest - ) -endif() - -if(MACOS AND QT_BUILDING_QT) - set_target_properties(tst_qmltestexample PROPERTIES - MACOSX_BUNDLE FALSE - ) -endif() - -install(TARGETS tst_qmltestexample - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/qmltest/qmltest/CMakeLists.txt b/examples/qmltest/qmltest/CMakeLists.txt index c8a83615784..adafbce610a 100644 --- a/examples/qmltest/qmltest/CMakeLists.txt +++ b/examples/qmltest/qmltest/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from qmltest.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(tst_qmltestexample LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -14,6 +14,7 @@ if(NOT DEFINED INSTALL_EXAMPLESDIR) endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}") +set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/examples) find_package(Qt6 COMPONENTS Core) find_package(Qt6 COMPONENTS Gui) diff --git a/examples/quick/.prev_CMakeLists.txt b/examples/quick/.prev_CMakeLists.txt deleted file mode 100644 index 5299e95ae2b..00000000000 --- a/examples/quick/.prev_CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -# Generated from quick.pro. - -add_subdirectory(quick-accessibility) -add_subdirectory(animation) -add_subdirectory(draganddrop) -add_subdirectory(externaldraganddrop) -add_subdirectory(canvas) -add_subdirectory(imageelements) -add_subdirectory(keyinteraction) -add_subdirectory(layouts) -add_subdirectory(localstorage) -add_subdirectory(models) -add_subdirectory(views) -add_subdirectory(tableview) -add_subdirectory(mousearea) -add_subdirectory(positioners) -add_subdirectory(righttoleft) -add_subdirectory(scenegraph) -add_subdirectory(shadereffects) -add_subdirectory(text) -add_subdirectory(threading) -add_subdirectory(touchinteraction) -add_subdirectory(tutorials) -add_subdirectory(customitems) -add_subdirectory(imageprovider) -add_subdirectory(imageresponseprovider) -add_subdirectory(window) -add_subdirectory(particles) -add_subdirectory(delegatechooser) -add_subdirectory(shapes) -if(QT_FEATURE_opengl OR QT_FEATURE_opengles2 OR QT_FEATURE_opengles3) - add_subdirectory(textureprovider) - add_subdirectory(rendercontrol) -endif() -if(TARGET Qt::Widgets) - add_subdirectory(embeddedinwidgets) -endif() -if(TARGET Qt::Widgets AND (QT_FEATURE_opengl OR QT_FEATURE_opengles2 OR QT_FEATURE_opengles3) AND (QT_FEATURE_opengles2 OR QT_FEATURE_opengles3 OR TARGET Qt::QuickWidgets)) - add_subdirectory(quickwidgets) -endif() diff --git a/examples/quick/CMakeLists.txt b/examples/quick/CMakeLists.txt index 80c163856a8..e138f7039af 100644 --- a/examples/quick/CMakeLists.txt +++ b/examples/quick/CMakeLists.txt @@ -8,7 +8,7 @@ qt_internal_add_example(canvas) qt_internal_add_example(imageelements) qt_internal_add_example(keyinteraction) qt_internal_add_example(layouts) -add_subdirectory(localstorage) +qt_internal_add_example(localstorage) add_subdirectory(models) qt_internal_add_example(views) add_subdirectory(tableview) @@ -37,3 +37,35 @@ endif() if(TARGET Qt::QuickWidgets AND TARGET Qt::Widgets AND (QT_FEATURE_opengl OR QT_FEATURE_opengles2 OR QT_FEATURE_opengles3)) add_subdirectory(quickwidgets) endif() + +# qt_examples_build_end() misses at least some of these due to some +# source subdirectories being added multiple times. See QTBUG-96159. +set(reused_dir_targets + animation_shared + canvas_shared + views_shared + positioners_shared + righttoleft_shared + text_shared + threading_shared + touchinteraction_shared + window_shared + shapes_shared + imageelements_shared + delegatechooser_shared + pointerhandlers_shared + affectors_shared + emitters_shared + imageparticle_shared + itemparticle_shared + system_shared + draganddrop_shared +) +foreach(target IN LISTS reused_dir_targets) + if(TARGET ${target}) + qt_autogen_tools(${target} ENABLE_AUTOGEN_TOOLS moc rcc) + if(TARGET Qt::Widgets) + qt_autogen_tools(${target} ENABLE_AUTOGEN_TOOLS uic) + endif() + endif() +endforeach() diff --git a/examples/quick/animation/CMakeLists.txt b/examples/quick/animation/CMakeLists.txt index 2f47a43d937..29c6e184e0e 100644 --- a/examples/quick/animation/CMakeLists.txt +++ b/examples/quick/animation/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from animation.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(animation LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -20,80 +20,53 @@ find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Quick) find_package(Qt6 COMPONENTS Qml) -qt_add_executable(animation +add_subdirectory("../shared" "shared") + +qt_add_executable(animationexample main.cpp ) -set_target_properties(animation PROPERTIES +set_target_properties(animationexample PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) -target_link_libraries(animation PUBLIC +target_link_libraries(animationexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(animationexample animation_shared) - -# Resources: -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(animation "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} -) -set(animation_resource_files - "animation.qml" - "basics/animators.qml" - "basics/color-animation.qml" - "basics/images/face-smile.png" - "basics/images/moon.png" - "basics/images/shadow.png" - "basics/images/star.png" - "basics/images/sun.png" - "basics/property-animation.qml" - "behaviors/FocusRect.qml" - "behaviors/SideRect.qml" - "behaviors/behavior-example.qml" - "behaviors/tvtennis.qml" - "behaviors/wigglytext.qml" - "easing/easing.qml" - "pathanimation/pathanimation.qml" - "pathinterpolator/pathinterpolator.qml" - "states/qt-logo.png" - "states/states.qml" - "states/transitions.qml" -) - -qt6_add_resources(animation "animation" - PREFIX - "/animation" - FILES - ${animation_resource_files} +qt_add_qml_module(animationexample + URI animation + VERSION 1.0 + QML_FILES + "animation.qml" + "basics/animators.qml" + "basics/color-animation.qml" + "basics/property-animation.qml" + "behaviors/FocusRect.qml" + "behaviors/SideRect.qml" + "behaviors/behavior-example.qml" + "behaviors/tvtennis.qml" + "behaviors/wigglytext.qml" + "easing/easing.qml" + "pathanimation/pathanimation.qml" + "pathinterpolator/pathinterpolator.qml" + "states/states.qml" + "states/transitions.qml" + RESOURCES + "basics/images/face-smile.png" + "basics/images/moon.png" + "basics/images/shadow.png" + "basics/images/star.png" + "basics/images/sun.png" + "states/qt-logo.png" ) -install(TARGETS animation +install(TARGETS animationexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) +bundle_shared(animationexample) diff --git a/examples/quick/animation/animation.qml b/examples/quick/animation/animation.qml index efc4e6fa270..2674bfee577 100644 --- a/examples/quick/animation/animation.qml +++ b/examples/quick/animation/animation.qml @@ -49,7 +49,7 @@ ****************************************************************************/ import QtQuick 2.0 -import "../shared" as Examples +import shared as Examples Item { height: 480 diff --git a/examples/quick/animation/animation.qmlproject b/examples/quick/animation/animation.qmlproject index 2e96daa8817..94433ab9d0b 100644 --- a/examples/quick/animation/animation.qmlproject +++ b/examples/quick/animation/animation.qmlproject @@ -2,6 +2,7 @@ import QmlProject 1.1 Project { mainFile: "animation.qml" + importPaths: ["../"] /* Include .qml, .js, and image files from current directory and subdirectories */ QmlFiles { diff --git a/examples/quick/canvas/CMakeLists.txt b/examples/quick/canvas/CMakeLists.txt index 43a8d2b9493..ff031fcc0a6 100644 --- a/examples/quick/canvas/CMakeLists.txt +++ b/examples/quick/canvas/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from canvas.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(canvas LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -20,72 +20,44 @@ find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Quick) find_package(Qt6 COMPONENTS Qml) -qt_add_executable(canvas +add_subdirectory("../shared" "shared") + +qt_add_executable(canvasexample main.cpp ) -set_target_properties(canvas PROPERTIES +set_target_properties(canvasexample PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) -target_link_libraries(canvas PUBLIC +target_link_libraries(canvasexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) - -# Resources: -set(canvas_resource_files - "LabeledSlider.qml" - "bezierCurve/bezierCurve.qml" - "canvas.qml" - "clip/clip.qml" - "contents/qt-logo.png" - "quadraticCurveTo/quadraticCurveTo.qml" - "roundedrect/roundedrect.qml" - "smile/smile.qml" - "squircle/squircle.png" - "squircle/squircle.qml" - "tiger/tiger.js" - "tiger/tiger.qml" -) - -qt6_add_resources(canvas "canvas" - PREFIX - "/canvas" - FILES - ${canvas_resource_files} -) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(canvas "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} -) - -install(TARGETS canvas +qt_add_qml_module(canvasexample + URI canvas + VERSION 1.0 + QML_FILES + "LabeledSlider.qml" + "bezierCurve/bezierCurve.qml" + "canvas.qml" + "clip/clip.qml" + "quadraticCurveTo/quadraticCurveTo.qml" + "roundedrect/roundedrect.qml" + "smile/smile.qml" + "squircle/squircle.qml" + "tiger/tiger.js" + "tiger/tiger.qml" + RESOURCES + "contents/qt-logo.png" + "squircle/squircle.png" +) + +install(TARGETS canvasexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) +bundle_shared(canvasexample) diff --git a/examples/quick/canvas/canvas.qml b/examples/quick/canvas/canvas.qml index 34e4f5a07b4..6f579b55cf0 100644 --- a/examples/quick/canvas/canvas.qml +++ b/examples/quick/canvas/canvas.qml @@ -49,7 +49,7 @@ ****************************************************************************/ import QtQuick -import "../shared" as Examples +import shared as Examples Item { height: 480 diff --git a/examples/quick/customitems/.prev_CMakeLists.txt b/examples/quick/customitems/.prev_CMakeLists.txt deleted file mode 100644 index 4afbfe3f6b1..00000000000 --- a/examples/quick/customitems/.prev_CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -# Generated from customitems.pro. - -add_subdirectory(painteditem) -add_subdirectory(maskedmousearea) diff --git a/examples/quick/customitems/dialcontrol/CMakeLists.txt b/examples/quick/customitems/dialcontrol/CMakeLists.txt index 9d2fa2818aa..dfc69c3c67a 100644 --- a/examples/quick/customitems/dialcontrol/CMakeLists.txt +++ b/examples/quick/customitems/dialcontrol/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from dialcontrol.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(dialcontrol LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -20,41 +20,36 @@ find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Quick) find_package(Qt6 COMPONENTS Qml) -qt_add_executable(dialcontrol +qt_add_executable(dialcontrolexample main.cpp ) -set_target_properties(dialcontrol PROPERTIES +set_target_properties(dialcontrolexample PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) -target_link_libraries(dialcontrol PUBLIC +target_link_libraries(dialcontrolexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) - -# Resources: -set(dialcontrol_resource_files - "content/Dial.qml" - "content/QuitButton.qml" - "content/background.png" - "content/needle.png" - "content/needle_shadow.png" - "content/overlay.png" - "content/quit.png" - "dialcontrol.qml" -) - -qt6_add_resources(dialcontrol "dialcontrol" - PREFIX - "/" - FILES - ${dialcontrol_resource_files} +qt_add_qml_module(dialcontrolexample + URI dialcontrol + VERSION 1.0 + QML_FILES + "Dial.qml" + "QuitButton.qml" + "dialcontrol.qml" + RESOURCES + "background.png" + "needle.png" + "needle_shadow.png" + "overlay.png" + "quit.png" ) -install(TARGETS dialcontrol +install(TARGETS dialcontrolexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/quick/customitems/dialcontrol/content/Dial.qml b/examples/quick/customitems/dialcontrol/Dial.qml similarity index 100% rename from examples/quick/customitems/dialcontrol/content/Dial.qml rename to examples/quick/customitems/dialcontrol/Dial.qml diff --git a/examples/quick/customitems/dialcontrol/content/QuitButton.qml b/examples/quick/customitems/dialcontrol/QuitButton.qml similarity index 100% rename from examples/quick/customitems/dialcontrol/content/QuitButton.qml rename to examples/quick/customitems/dialcontrol/QuitButton.qml diff --git a/examples/quick/customitems/dialcontrol/content/background.png b/examples/quick/customitems/dialcontrol/background.png similarity index 100% rename from examples/quick/customitems/dialcontrol/content/background.png rename to examples/quick/customitems/dialcontrol/background.png diff --git a/examples/quick/customitems/dialcontrol/dialcontrol.qml b/examples/quick/customitems/dialcontrol/dialcontrol.qml index d0a623a72a4..c6bff8f2c06 100644 --- a/examples/quick/customitems/dialcontrol/dialcontrol.qml +++ b/examples/quick/customitems/dialcontrol/dialcontrol.qml @@ -51,7 +51,6 @@ //! [imports] import QtQuick 2.2 import QtQuick.Window 2.1 -import "content" //! [imports] //! [0] diff --git a/examples/quick/customitems/dialcontrol/dialcontrol.qrc b/examples/quick/customitems/dialcontrol/dialcontrol.qrc index 6433d68bb89..9b9bd42f237 100644 --- a/examples/quick/customitems/dialcontrol/dialcontrol.qrc +++ b/examples/quick/customitems/dialcontrol/dialcontrol.qrc @@ -1,12 +1,12 @@ - + + Dial.qml + QuitButton.qml + background.png dialcontrol.qml - content/background.png - content/Dial.qml - content/needle_shadow.png - content/needle.png - content/overlay.png - content/quit.png - content/QuitButton.qml + needle.png + needle_shadow.png + overlay.png + quit.png diff --git a/examples/quick/customitems/dialcontrol/main.cpp b/examples/quick/customitems/dialcontrol/main.cpp index 6ebe203a701..3b925c3d8b2 100644 --- a/examples/quick/customitems/dialcontrol/main.cpp +++ b/examples/quick/customitems/dialcontrol/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(dialcontrol) +DECLARATIVE_EXAMPLE_MAIN(dialcontrol/dialcontrol) diff --git a/examples/quick/customitems/dialcontrol/content/needle.png b/examples/quick/customitems/dialcontrol/needle.png similarity index 100% rename from examples/quick/customitems/dialcontrol/content/needle.png rename to examples/quick/customitems/dialcontrol/needle.png diff --git a/examples/quick/customitems/dialcontrol/content/needle_shadow.png b/examples/quick/customitems/dialcontrol/needle_shadow.png similarity index 100% rename from examples/quick/customitems/dialcontrol/content/needle_shadow.png rename to examples/quick/customitems/dialcontrol/needle_shadow.png diff --git a/examples/quick/customitems/dialcontrol/content/overlay.png b/examples/quick/customitems/dialcontrol/overlay.png similarity index 100% rename from examples/quick/customitems/dialcontrol/content/overlay.png rename to examples/quick/customitems/dialcontrol/overlay.png diff --git a/examples/quick/customitems/dialcontrol/content/quit.png b/examples/quick/customitems/dialcontrol/quit.png similarity index 100% rename from examples/quick/customitems/dialcontrol/content/quit.png rename to examples/quick/customitems/dialcontrol/quit.png diff --git a/examples/quick/customitems/flipable/content/5_heart.png b/examples/quick/customitems/flipable/5_heart.png similarity index 100% rename from examples/quick/customitems/flipable/content/5_heart.png rename to examples/quick/customitems/flipable/5_heart.png diff --git a/examples/quick/customitems/flipable/content/9_club.png b/examples/quick/customitems/flipable/9_club.png similarity index 100% rename from examples/quick/customitems/flipable/content/9_club.png rename to examples/quick/customitems/flipable/9_club.png diff --git a/examples/quick/customitems/flipable/CMakeLists.txt b/examples/quick/customitems/flipable/CMakeLists.txt new file mode 100644 index 00000000000..469cde10eec --- /dev/null +++ b/examples/quick/customitems/flipable/CMakeLists.txt @@ -0,0 +1,49 @@ +# Generated from flipable.pro. + +cmake_minimum_required(VERSION 3.16) + +project(flipable LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/customitems/flipable") + +find_package(Qt6 COMPONENTS Core Gui Quick Qml) + +qt_add_executable(flipableexample + WIN32 + MACOSX_BUNDLE + main.cpp +) + +target_link_libraries(flipableexample PUBLIC + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +qt_add_qml_module(flipableexample + URI flipable + VERSION 1.0 + QML_FILES + "flipable.qml" + "Card.qml" + RESOURCES + "5_heart.png" + "9_club.png" + "back.png" +) + +install(TARGETS flipableexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quick/customitems/flipable/content/Card.qml b/examples/quick/customitems/flipable/Card.qml similarity index 98% rename from examples/quick/customitems/flipable/content/Card.qml rename to examples/quick/customitems/flipable/Card.qml index ffffdb6b7d3..bc50bbe4731 100644 --- a/examples/quick/customitems/flipable/content/Card.qml +++ b/examples/quick/customitems/flipable/Card.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick Flipable { id: container diff --git a/examples/quick/customitems/flipable/content/back.png b/examples/quick/customitems/flipable/back.png similarity index 100% rename from examples/quick/customitems/flipable/content/back.png rename to examples/quick/customitems/flipable/back.png diff --git a/examples/quick/customitems/flipable/flipable.qml b/examples/quick/customitems/flipable/flipable.qml index 3662898864e..c22eb841b08 100644 --- a/examples/quick/customitems/flipable/flipable.qml +++ b/examples/quick/customitems/flipable/flipable.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "content" +import QtQuick Rectangle { id: window @@ -59,7 +58,7 @@ Rectangle { Row { anchors.centerIn: parent; spacing: 30 - Card { source: "content/9_club.png"; angle: 180; yAxis: 1 } - Card { source: "content/5_heart.png"; angle: 540; xAxis: 1 } + Card { source: "9_club.png"; angle: 180; yAxis: 1 } + Card { source: "5_heart.png"; angle: 540; xAxis: 1 } } } diff --git a/examples/quick/customitems/flipable/flipable.qrc b/examples/quick/customitems/flipable/flipable.qrc index 7918ccf00e2..b7bc2f30215 100644 --- a/examples/quick/customitems/flipable/flipable.qrc +++ b/examples/quick/customitems/flipable/flipable.qrc @@ -1,9 +1,9 @@ - + flipable.qml - content/5_heart.png - content/9_club.png - content/back.png - content/Card.qml + 5_heart.png + 9_club.png + back.png + Card.qml diff --git a/examples/quick/customitems/flipable/main.cpp b/examples/quick/customitems/flipable/main.cpp index a0f0d67d454..6a4967bc654 100644 --- a/examples/quick/customitems/flipable/main.cpp +++ b/examples/quick/customitems/flipable/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(flipable) +DECLARATIVE_EXAMPLE_MAIN(flipable/flipable) diff --git a/examples/quick/customitems/maskedmousearea/CMakeLists.txt b/examples/quick/customitems/maskedmousearea/CMakeLists.txt index 0c5a19b5e7d..afe52f0a9dd 100644 --- a/examples/quick/customitems/maskedmousearea/CMakeLists.txt +++ b/examples/quick/customitems/maskedmousearea/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from maskedmousearea.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(maskedmousearea LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -35,20 +35,17 @@ target_link_libraries(maskedmousearea PUBLIC Qt::Quick ) - -# Resources: -set(maskedmousearea_resource_files - "images/cloud_1.png" - "images/cloud_2.png" - "images/moon.png" - "maskedmousearea.qml" -) - -qt6_add_resources(maskedmousearea "maskedmousearea" - PREFIX - "/customitems/maskedmousearea" - FILES - ${maskedmousearea_resource_files} +qt_add_qml_module(maskedmousearea + URI Example + VERSION 1.0 + QML_FILES + maskedmousearea.qml + RESOURCES + images/cloud_1.png + images/cloud_2.png + images/moon.png + RESOURCE_PREFIX /customitems/maskedmousearea + NO_RESOURCE_TARGET_PATH ) install(TARGETS maskedmousearea @@ -56,10 +53,3 @@ install(TARGETS maskedmousearea BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(maskedmousearea PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI Example -) - -qt6_qml_type_registration(maskedmousearea) diff --git a/examples/quick/customitems/painteditem/CMakeLists.txt b/examples/quick/customitems/painteditem/CMakeLists.txt index fa964778d0c..8299de48823 100644 --- a/examples/quick/customitems/painteditem/CMakeLists.txt +++ b/examples/quick/customitems/painteditem/CMakeLists.txt @@ -1,63 +1,46 @@ -# Generated from painteditem.pro. - -cmake_minimum_required(VERSION 3.14) -project(qmltextballoonplugin LANGUAGES CXX) +cmake_minimum_required(VERSION 3.16) +project(painteditem LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) - set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") endif() -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/customitems/painteditem/TextBalloonPlugin") +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/customitems/painteditem") + +find_package(Qt6 COMPONENTS Core Gui Quick Qml) + +add_subdirectory(TextBalloon) -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Qml) -find_package(Qt6 COMPONENTS Quick) +qt_add_executable(painteditemexample WIN32 MACOSX_BUNDLE main.cpp) -qt6_add_qml_module(qmltextballoonplugin - OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/TextBalloonPlugin" +qt_add_qml_module(painteditemexample + URI painteditem VERSION 1.0 - URI "TextBalloonPlugin" - PLUGIN_TARGET qmltextballoonplugin - QML_FILES textballoons.qml - RESOURCE_PREFIX "/painteditem" + QML_FILES + "textballoons.qml" ) -target_sources(qmltextballoonplugin PRIVATE - textballoon.cpp textballoon.h -) -set_target_properties(qmltextballoonplugin PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(qmltextballoonplugin PUBLIC +target_link_libraries(painteditemexample PRIVATE Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(painteditemexample qmltextballoon) - -# Resources: -set(painteditem_resource_files - "textballoon.h" -) - -qt6_add_resources(qmltextballoonplugin "painteditem" - PREFIX - "/painteditem" - FILES - ${painteditem_resource_files} -) - -install(TARGETS qmltextballoonplugin +install(TARGETS painteditemexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) + +include(../../shared/QtBundleQmlModuleForMacOS.cmake) + +set(app_target "painteditemexample") +set(qml_plugin_target "qmltextballoon") +set(qml_module_uri "TextBalloon") +add_qml_module_to_macos_app_bundle( + "${app_target}" "${qml_plugin_target}" "${qml_module_uri}") diff --git a/examples/quick/customitems/painteditem/TextBalloon/CMakeLists.txt b/examples/quick/customitems/painteditem/TextBalloon/CMakeLists.txt new file mode 100644 index 00000000000..fb2bf7568ed --- /dev/null +++ b/examples/quick/customitems/painteditem/TextBalloon/CMakeLists.txt @@ -0,0 +1,30 @@ +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + message(FATAL_ERROR "TextBalloon should be built as part of the 'painteditem' project, and not in isolation.") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/customitems/painteditem/TextBalloon") + +qt_add_qml_module(qmltextballoon + VERSION 1.0 + URI "TextBalloon" + PLUGIN_TARGET qmltextballoon + SOURCES + textballoon.cpp textballoon.h +) + +target_link_libraries(qmltextballoon PUBLIC + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +install(TARGETS qmltextballoon + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qmldir + DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quick/customitems/painteditem/TextBalloonPlugin/plugin.h b/examples/quick/customitems/painteditem/TextBalloon/plugin.h similarity index 98% rename from examples/quick/customitems/painteditem/TextBalloonPlugin/plugin.h rename to examples/quick/customitems/painteditem/TextBalloon/plugin.h index 4abf2cf3dc4..6fabbe0b373 100644 --- a/examples/quick/customitems/painteditem/TextBalloonPlugin/plugin.h +++ b/examples/quick/customitems/painteditem/TextBalloon/plugin.h @@ -50,7 +50,7 @@ #include -#include "../textballoon.h" +#include "textballoon.h" class TextBalloonPlugin : public QQmlEngineExtensionPlugin { diff --git a/examples/quick/customitems/painteditem/TextBalloon/qmldir b/examples/quick/customitems/painteditem/TextBalloon/qmldir new file mode 100644 index 00000000000..3b72e9a44d5 --- /dev/null +++ b/examples/quick/customitems/painteditem/TextBalloon/qmldir @@ -0,0 +1,2 @@ +module TextBalloon +plugin qmltextballoonplugin diff --git a/examples/quick/customitems/painteditem/textballoon.cpp b/examples/quick/customitems/painteditem/TextBalloon/textballoon.cpp similarity index 100% rename from examples/quick/customitems/painteditem/textballoon.cpp rename to examples/quick/customitems/painteditem/TextBalloon/textballoon.cpp diff --git a/examples/quick/customitems/painteditem/textballoon.h b/examples/quick/customitems/painteditem/TextBalloon/textballoon.h similarity index 96% rename from examples/quick/customitems/painteditem/textballoon.h rename to examples/quick/customitems/painteditem/TextBalloon/textballoon.h index 129b0f7ee1a..520def639e6 100644 --- a/examples/quick/customitems/painteditem/textballoon.h +++ b/examples/quick/customitems/painteditem/TextBalloon/textballoon.h @@ -61,8 +61,8 @@ class TextBalloon : public QQuickPaintedItem QML_ELEMENT public: - TextBalloon(QQuickItem *parent = 0); - void paint(QPainter *painter); + TextBalloon(QQuickItem *parent = nullptr); + void paint(QPainter *painter) override; bool isRightAligned() const; void setRightAligned(bool rightAligned); diff --git a/examples/quick/customitems/painteditem/TextBalloon/textballoon.pro b/examples/quick/customitems/painteditem/TextBalloon/textballoon.pro new file mode 100644 index 00000000000..7f7662b4516 --- /dev/null +++ b/examples/quick/customitems/painteditem/TextBalloon/textballoon.pro @@ -0,0 +1,28 @@ +TEMPLATE = lib +CONFIG += plugin qmltypes +QT += qml quick + +QML_IMPORT_NAME = TextBalloon +QML_IMPORT_MAJOR_VERSION = 1 + +TARGET = qmltextballoonplugin + +HEADERS += \ + plugin.h \ + textballoon.h + +SOURCES += textballoon.cpp + +RESOURCES += textballoon.qrc + +qmldir_output.files = qmldir +qmldir_output.path = $$OUT_PWD +COPIES += qmldir_output + +target.path = $$[QT_INSTALL_EXAMPLES]/quick/customitems/painteditem/$$QML_IMPORT_NAME +qmldir_install.files = qmldir +qmldir_install.path = $$[QT_INSTALL_EXAMPLES]/quick/customitems/painteditem/$$QML_IMPORT_NAME + +INSTALLS += qmldir_install target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/quick/customitems/painteditem/TextBalloon/textballoon.qrc b/examples/quick/customitems/painteditem/TextBalloon/textballoon.qrc new file mode 100644 index 00000000000..42c42bd0a62 --- /dev/null +++ b/examples/quick/customitems/painteditem/TextBalloon/textballoon.qrc @@ -0,0 +1,5 @@ + + + qmldir + + diff --git a/examples/quick/customitems/painteditem/TextBalloonPlugin/qmldir b/examples/quick/customitems/painteditem/TextBalloonPlugin/qmldir deleted file mode 100644 index e8a08ae9d3d..00000000000 --- a/examples/quick/customitems/painteditem/TextBalloonPlugin/qmldir +++ /dev/null @@ -1 +0,0 @@ -plugin qmltextballoonplugin diff --git a/examples/quick/customitems/painteditem/doc/src/textballoons.qdoc b/examples/quick/customitems/painteditem/doc/src/textballoons.qdoc index 4541ba0bd9c..57ffd0f6b16 100644 --- a/examples/quick/customitems/painteditem/doc/src/textballoons.qdoc +++ b/examples/quick/customitems/painteditem/doc/src/textballoons.qdoc @@ -38,16 +38,14 @@ The QQuickPaintedItem class is a class derived from QQuickItem for implementing custom QML Scene Graph items using the QPainter interfaces. - The example consists of an item class, a plugin class and a QML file - to use this plugin. The \c TextBalloon class represents the individual - text balloons extending QQuickPaintedItem, the \c TextBalloonPlugin class - represents the skeleton code for a \l {Qt Quick} plugin and the - \c textballoons.qml file is used to load the plugin and display the text - balloons. + The example consists of an item class and a QML file to use the item. The + \c TextBalloon class represents the individual text balloons extending + QQuickPaintedItem and the \c textballoons.qml file is used to load the module + containing the TextBalloon QML type and display the text balloons. We will focus on the \c TextBalloon class first and continue with the - \c textballoons.qml file. For an example on how to implement a \l {Qt Quick} - plugin please look at \l{Chapter 6: Writing an Extension Plugin} + \c textballoons.qml file. For an example on how to implement a plugin for a + QML module please look at \l{Chapter 6: Writing an Extension Plugin} {Writing an Extension Plugin} \section1 TextBalloon Class Declaration @@ -56,7 +54,7 @@ is the base class for all QPainter based items in the QML Scene Graph framework. - \snippet customitems/painteditem/textballoon.h 0 + \snippet customitems/painteditem/TextBalloon/textballoon.h 0 To implement a QQuickPaintedItem you must implement QQuickPaintedIem's pure virtual function \l {QQuickPaintedItem::}{paint()} which implements the @@ -67,13 +65,13 @@ We have to be sure to initialize the rightAligned property for a TextBalloon item. - \snippet customitems/painteditem/textballoon.cpp 0 + \snippet customitems/painteditem/TextBalloon/textballoon.cpp 0 Then we implement the \c paint() function which is automatically called by the Scene Graph framework to paint the contents of the item. The function paints the item in local coordinates. - \snippet customitems/painteditem/textballoon.cpp 1 + \snippet customitems/painteditem/TextBalloon/textballoon.cpp 1 We start with setting the pen and brush on the item to define the look of the item. After that we start drawing. Note that the \l {QQuickPaintedItem::}{contentsBoundingRect()} @@ -81,7 +79,7 @@ returned by the \l {QQuickPaintedItem::}{contentsBoundingRect()} function is the size of the item as defined in the QML file. - \section1 Textballoons.qml File + \section1 textballoons.qml File The Interface consists of two main parts. The scrollable area with the textballoons and the controls button to add new balloons. diff --git a/examples/quick/customitems/painteditem/main.cpp b/examples/quick/customitems/painteditem/main.cpp new file mode 100644 index 00000000000..7f01df3395a --- /dev/null +++ b/examples/quick/customitems/painteditem/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "../../shared/shared.h" +DECLARATIVE_EXAMPLE_MAIN(painteditem/textballoons) diff --git a/examples/quick/customitems/painteditem/painteditem.pro b/examples/quick/customitems/painteditem/painteditem.pro index 641833f3aae..7c26304b263 100644 --- a/examples/quick/customitems/painteditem/painteditem.pro +++ b/examples/quick/customitems/painteditem/painteditem.pro @@ -1,29 +1,2 @@ -TEMPLATE = lib -CONFIG += plugin qmltypes -QT += qml quick - -QML_IMPORT_NAME = TextBalloonPlugin -QML_IMPORT_MAJOR_VERSION = 1 - -TARGET = qmltextballoonplugin - -HEADERS += \ - TextBalloonPlugin/plugin.h \ - textballoon.h - -SOURCES += textballoon.cpp - -RESOURCES += painteditem.qrc - -DESTDIR = $$QML_IMPORT_NAME - -target.path = $$[QT_INSTALL_EXAMPLES]/quick/customitems/painteditem/$$QML_IMPORT_NAME -qmldir.files = $$QML_IMPORT_NAME/qmldir -qmldir.path = $$[QT_INSTALL_EXAMPLES]/quick/customitems/painteditem/$$QML_IMPORT_NAME - -INSTALLS += qmldir target - -CONFIG += install_ok # Do not cargo-cult this! - -OTHER_FILES += \ - textballoons.qml +TEMPLATE = subdirs +SUBDIRS = TextBalloon/textballoon.pro textballoonuser.pro diff --git a/examples/quick/customitems/painteditem/painteditem.qrc b/examples/quick/customitems/painteditem/painteditem.qrc index c240be02a1a..d436ab32e22 100644 --- a/examples/quick/customitems/painteditem/painteditem.qrc +++ b/examples/quick/customitems/painteditem/painteditem.qrc @@ -1,6 +1,5 @@ - textballoon.h textballoons.qml diff --git a/examples/quick/customitems/painteditem/textballoons.qml b/examples/quick/customitems/painteditem/textballoons.qml index 2c749bb4404..c520dda2714 100644 --- a/examples/quick/customitems/painteditem/textballoons.qml +++ b/examples/quick/customitems/painteditem/textballoons.qml @@ -49,7 +49,7 @@ ****************************************************************************/ import QtQuick 2.0 -import "TextBalloonPlugin" 1.0 +import TextBalloon 1.0 Item { height: 480 diff --git a/examples/quick/customitems/painteditem/textballoonuser.pro b/examples/quick/customitems/painteditem/textballoonuser.pro new file mode 100644 index 00000000000..7504542f4c4 --- /dev/null +++ b/examples/quick/customitems/painteditem/textballoonuser.pro @@ -0,0 +1,10 @@ +TEMPLATE = app + +QT += qml quick + +TARGET = painteditem +SOURCES += main.cpp +RESOURCES += painteditem.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/quick/customitems/painteditem +INSTALLS += target diff --git a/examples/quick/customitems/scrollbar/ScrollBar.qml b/examples/quick/customitems/scrollbar/ScrollBar.qml index f2e46c56818..655335d78cc 100644 --- a/examples/quick/customitems/scrollbar/ScrollBar.qml +++ b/examples/quick/customitems/scrollbar/ScrollBar.qml @@ -60,24 +60,24 @@ Item { // orientation can be either Qt.Vertical or Qt.Horizontal property real position property real pageSize - property variant orientation : Qt.Vertical + property int orientation : Qt.Vertical // A light, semi-transparent background Rectangle { id: background anchors.fill: parent - radius: orientation == Qt.Vertical ? (width/2 - 1) : (height/2 - 1) + radius: orientation === Qt.Vertical ? (width/2 - 1) : (height/2 - 1) color: "white" opacity: 0.3 } // Size the bar to the required size, depending upon the orientation. Rectangle { - x: orientation == Qt.Vertical ? 1 : (scrollBar.position * (scrollBar.width-2) + 1) - y: orientation == Qt.Vertical ? (scrollBar.position * (scrollBar.height-2) + 1) : 1 - width: orientation == Qt.Vertical ? (parent.width-2) : (scrollBar.pageSize * (scrollBar.width-2)) - height: orientation == Qt.Vertical ? (scrollBar.pageSize * (scrollBar.height-2)) : (parent.height-2) - radius: orientation == Qt.Vertical ? (width/2 - 1) : (height/2 - 1) + x: orientation === Qt.Vertical ? 1 : (scrollBar.position * (scrollBar.width-2) + 1) + y: orientation === Qt.Vertical ? (scrollBar.position * (scrollBar.height-2) + 1) : 1 + width: orientation === Qt.Vertical ? (parent.width-2) : (scrollBar.pageSize * (scrollBar.width-2)) + height: orientation === Qt.Vertical ? (scrollBar.pageSize * (scrollBar.height-2)) : (parent.height-2) + radius: orientation === Qt.Vertical ? (width/2 - 1) : (height/2 - 1) color: "black" opacity: 0.7 } diff --git a/examples/quick/delegatechooser/CMakeLists.txt b/examples/quick/delegatechooser/CMakeLists.txt index ab9d1537ac0..1c6abcff472 100644 --- a/examples/quick/delegatechooser/CMakeLists.txt +++ b/examples/quick/delegatechooser/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from delegatechooser.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(delegatechooser LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -15,66 +15,30 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/delegatechooser") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) -qt_add_executable(delegatechooser - main.cpp -) -set_target_properties(delegatechooser PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(delegatechooser PUBLIC +add_subdirectory("../shared" "shared") + +qt_add_executable(delegatechooserexample WIN32 MACOSX_BUNDLE main.cpp) + +target_link_libraries(delegatechooserexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(delegatechooserexample delegatechooser_shared) - -# Resources: -set(qml_resource_files - "delegatechooser.qml" -) - -qt6_add_resources(delegatechooser "qml" - PREFIX - "/" - FILES - ${qml_resource_files} -) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(delegatechooser "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} +qt_add_qml_module(delegatechooserexample + URI delegatechooser + VERSION 1.0 + QML_FILES + "delegatechooser.qml" ) -install(TARGETS delegatechooser +install(TARGETS delegatechooserexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) +bundle_shared(delegatechooserexample) diff --git a/examples/quick/delegatechooser/delegatechooser.qml b/examples/quick/delegatechooser/delegatechooser.qml index afb8518abf9..75ab363d056 100644 --- a/examples/quick/delegatechooser/delegatechooser.qml +++ b/examples/quick/delegatechooser/delegatechooser.qml @@ -52,6 +52,7 @@ import QtQuick 2.12 import QtQml.Models 2.12 import QtQuick.Layouts 1.12 import Qt.labs.qmlmodels 1.0 +import shared Rectangle { visible: true @@ -61,9 +62,9 @@ Rectangle { ListModel { id: listModel ListElement { dataType: "rect"; color: "green" } - ListElement { dataType: "image"; source: "../shared/images/qt-logo.png" } + ListElement { dataType: "image" } ListElement { dataType: "rect"; color: "green" } - ListElement { dataType: "image"; source: "../shared/images/qt-logo.png" } + ListElement { dataType: "image" } ListElement { dataType: "rect"; color: "blue" } ListElement { dataType: "rect"; color: "blue" } ListElement { dataType: "rect"; color: "blue" } @@ -77,9 +78,9 @@ Rectangle { ListElement { dataType: "rect"; color: "blue" } ListElement { dataType: "rect"; color: "blue" } ListElement { dataType: "rect"; color: "green" } - ListElement { dataType: "image"; source: "../shared/images/qt-logo.png" } + ListElement { dataType: "image" } ListElement { dataType: "rect"; color: "green" } - ListElement { dataType: "image"; source: "../shared/images/qt-logo.png" } + ListElement { dataType: "image" } ListElement { dataType: "rect"; color: "blue" } ListElement { dataType: "rect"; color: "lightsteelblue" } ListElement { dataType: "rect"; color: "fuchsia" } @@ -118,7 +119,7 @@ Rectangle { delegate: Image { width: parent.width height: 100 - source: model.source + source: Images.qtLogo fillMode: Image.PreserveAspectFit } } diff --git a/examples/quick/delegatechooser/main.cpp b/examples/quick/delegatechooser/main.cpp index 5df9207e247..79b79135334 100644 --- a/examples/quick/delegatechooser/main.cpp +++ b/examples/quick/delegatechooser/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(delegatechooser) +DECLARATIVE_EXAMPLE_MAIN(delegatechooser/delegatechooser) diff --git a/examples/quick/delegatechooser/qml.qrc b/examples/quick/delegatechooser/qml.qrc index 0788f84c640..abd2efbddab 100644 --- a/examples/quick/delegatechooser/qml.qrc +++ b/examples/quick/delegatechooser/qml.qrc @@ -1,5 +1,5 @@ - + delegatechooser.qml diff --git a/examples/quick/draganddrop/CMakeLists.txt b/examples/quick/draganddrop/CMakeLists.txt index 2f84c9cca8b..dea3d2c27db 100644 --- a/examples/quick/draganddrop/CMakeLists.txt +++ b/examples/quick/draganddrop/CMakeLists.txt @@ -1,13 +1,12 @@ # Generated from draganddrop.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(draganddrop LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,71 +14,41 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/draganddrop") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) -qt_add_executable(draganddrop +add_subdirectory("../shared" "shared") + +qt_add_executable(draganddropexample + WIN32 + MACOSX_BUNDLE main.cpp ) -set_target_properties(draganddrop PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE + +qt_add_qml_module(draganddropexample + URI draganddrop + VERSION 1.0 + QML_FILES + "draganddrop.qml" + "tiles/DragTile.qml" + "tiles/DropTile.qml" + "tiles/tiles.qml" + "views/Icon.qml" + "views/gridview.qml" ) -target_link_libraries(draganddrop PUBLIC + +target_link_libraries(draganddropexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(draganddropexample draganddrop_shared) -# Resources: -set(draganddrop_resource_files - "draganddrop.qml" - "tiles/DragTile.qml" - "tiles/DropTile.qml" - "tiles/tiles.qml" - "views/Icon.qml" - "views/gridview.qml" -) - -qt6_add_resources(draganddrop "draganddrop" - PREFIX - "/draganddrop" - FILES - ${draganddrop_resource_files} -) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(draganddrop "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} -) - -install(TARGETS draganddrop +install(TARGETS draganddropexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) + +bundle_shared(draganddropexample) diff --git a/examples/quick/draganddrop/draganddrop.qml b/examples/quick/draganddrop/draganddrop.qml index b1fb6eb268c..490223d7c00 100644 --- a/examples/quick/draganddrop/draganddrop.qml +++ b/examples/quick/draganddrop/draganddrop.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "../shared" as Examples +import QtQuick +import shared as Examples Item { height: 480 diff --git a/examples/quick/draganddrop/tiles/DragTile.qml b/examples/quick/draganddrop/tiles/DragTile.qml index 47f0ebed5ee..1762ca8327b 100644 --- a/examples/quick/draganddrop/tiles/DragTile.qml +++ b/examples/quick/draganddrop/tiles/DragTile.qml @@ -94,10 +94,8 @@ Item { //! [1] states: State { when: mouseArea.drag.active - ParentChange { target: tile; parent: root } AnchorChanges { target: tile; anchors.verticalCenter: undefined; anchors.horizontalCenter: undefined } } - } } } diff --git a/examples/quick/draganddrop/views/gridview.qml b/examples/quick/draganddrop/views/gridview.qml index 05bd48e7fae..98a67ca5137 100644 --- a/examples/quick/draganddrop/views/gridview.qml +++ b/examples/quick/draganddrop/views/gridview.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,9 +48,9 @@ ** ****************************************************************************/ -import QtQml 2.14 -import QtQuick 2.14 -import QtQml.Models 2.14 +import QtQml +import QtQuick +import QtQml.Models GridView { id: root diff --git a/examples/quick/embeddedinwidgets/CMakeLists.txt b/examples/quick/embeddedinwidgets/CMakeLists.txt index 4862e58f5c0..9f90d696b7c 100644 --- a/examples/quick/embeddedinwidgets/CMakeLists.txt +++ b/examples/quick/embeddedinwidgets/CMakeLists.txt @@ -1,13 +1,10 @@ -# Generated from embeddedinwidgets.pro. - -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(embeddedinwidgets LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,19 +12,12 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/embeddedinwidgets") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Widgets) -find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Core Gui Widgets Quick) -qt_add_executable(embeddedinwidgets +qt_add_executable(embeddedinwidgetsexample WIN32 MACOSX_BUNDLE main.cpp ) -set_target_properties(embeddedinwidgets PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(embeddedinwidgets PUBLIC +target_link_libraries(embeddedinwidgetsexample PRIVATE Qt::Core Qt::Gui Qt::Quick @@ -36,19 +26,16 @@ target_link_libraries(embeddedinwidgets PUBLIC # Resources: -set(embeddedinwidgets_resource_files - "TextBox.qml" - "main.qml" -) - -qt6_add_resources(embeddedinwidgets "embeddedinwidgets" - PREFIX - "/embeddedinwidgets" - FILES - ${embeddedinwidgets_resource_files} +qt_add_qml_module(embeddedinwidgetsexample + URI embeddedinwidgets + VERSION 1.0 + QML_FILES + "main.qml" + RESOURCES + "reflect.frag.qsb" ) -install(TARGETS embeddedinwidgets +install(TARGETS embeddedinwidgetsexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/quick/embeddedinwidgets/TextBox.qml b/examples/quick/embeddedinwidgets/TextBox.qml deleted file mode 100644 index b45bb0ef1bc..00000000000 --- a/examples/quick/embeddedinwidgets/TextBox.qml +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -FocusScope { - id: root - - width: 100 - height: 30 - - property Item nextInFocus; - property string label; - - Rectangle { - anchors.margins: 2 - anchors.fill: parent - radius: 8 - gradient: Gradient { - GradientStop { position: 0; color: "lightgray" } - GradientStop { position: 1; color: "white" } - } - border.color: "white" - border.width: 2 - antialiasing: true - - TextInput { - anchors.fill: parent - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - focus: true - - text: root.label; - - KeyNavigation.tab: root.nextInFocus; - } - } -} diff --git a/examples/quick/embeddedinwidgets/embeddedinwidgets.pro b/examples/quick/embeddedinwidgets/embeddedinwidgets.pro index de47a397ab3..936da9dfeb2 100644 --- a/examples/quick/embeddedinwidgets/embeddedinwidgets.pro +++ b/examples/quick/embeddedinwidgets/embeddedinwidgets.pro @@ -3,7 +3,7 @@ QT += widgets quick SOURCES += main.cpp -OTHER_FILES += main.qml TextBox.qml +OTHER_FILES += main.qml RESOURCES += \ embeddedinwidgets.qrc diff --git a/examples/quick/embeddedinwidgets/embeddedinwidgets.qrc b/examples/quick/embeddedinwidgets/embeddedinwidgets.qrc index 62e0ed2161b..9fc33601d00 100644 --- a/examples/quick/embeddedinwidgets/embeddedinwidgets.qrc +++ b/examples/quick/embeddedinwidgets/embeddedinwidgets.qrc @@ -1,6 +1,6 @@ main.qml - TextBox.qml + reflect.frag.qsb diff --git a/examples/quick/embeddedinwidgets/main.cpp b/examples/quick/embeddedinwidgets/main.cpp index 91147772ba4..e7687c9feca 100644 --- a/examples/quick/embeddedinwidgets/main.cpp +++ b/examples/quick/embeddedinwidgets/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the demonstration applications of the Qt Toolkit. diff --git a/examples/quick/embeddedinwidgets/main.qml b/examples/quick/embeddedinwidgets/main.qml index e644a76587f..fea6118f907 100644 --- a/examples/quick/embeddedinwidgets/main.qml +++ b/examples/quick/embeddedinwidgets/main.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the demonstration applications of the Qt Toolkit. @@ -48,7 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick +import QtQuick.Controls Rectangle { id: window @@ -63,31 +64,22 @@ Rectangle { Column { id: column - opacity: 0.99 // work around QTBUG-29037 y: 50 width: 200 anchors.horizontalCenter: parent.horizontalCenter + spacing: 4 - TextBox { - id: input1 + + TextField { + text: "A QML text field..." width: parent.width - height: 30 focus: true - - label: "A QML text box.." - - nextInFocus: input2; } - TextBox { - id: input2 + TextField { + text: "Another QML text field..." width: parent.width - height: 30 - - label: "Another QML text box.." - - nextInFocus: input1; } layer.enabled: true @@ -103,20 +95,6 @@ Rectangle { property variant source: column; property size sourceSize: Qt.size(0.5 / column.width, 0.5 / column.height); - fragmentShader: ` - varying highp vec2 qt_TexCoord0; - uniform lowp sampler2D source; - uniform lowp vec2 sourceSize; - uniform lowp float qt_Opacity; - void main() { - - lowp vec2 tc = qt_TexCoord0 * vec2(1, -1) + vec2(0, 1); - lowp vec4 col = 0.25 * (texture2D(source, tc + sourceSize) - + texture2D(source, tc- sourceSize) - + texture2D(source, tc + sourceSize * vec2(1, -1)) - + texture2D(source, tc + sourceSize * vec2(-1, 1)) - ); - gl_FragColor = col * qt_Opacity * (1.0 - qt_TexCoord0.y) * 0.2; - }` + fragmentShader: "reflect.frag.qsb" } } diff --git a/examples/quick/embeddedinwidgets/reflect.frag b/examples/quick/embeddedinwidgets/reflect.frag new file mode 100644 index 00000000000..e1d5dbf4507 --- /dev/null +++ b/examples/quick/embeddedinwidgets/reflect.frag @@ -0,0 +1,25 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#version 440 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(binding = 1) uniform sampler2D source; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + vec2 sourceSize; +}; + +void main() +{ + vec2 tc = qt_TexCoord0 * vec2(1, -1) + vec2(0, 1); + vec4 col = 0.25 * (texture(source, tc + sourceSize) + + texture(source, tc- sourceSize) + + texture(source, tc + sourceSize * vec2(1, -1)) + + texture(source, tc + sourceSize * vec2(-1, 1))); + fragColor = col * qt_Opacity * (1.0 - qt_TexCoord0.y) * 0.2; +} diff --git a/examples/quick/embeddedinwidgets/reflect.frag.qsb b/examples/quick/embeddedinwidgets/reflect.frag.qsb new file mode 100644 index 00000000000..a4d25dcbf55 Binary files /dev/null and b/examples/quick/embeddedinwidgets/reflect.frag.qsb differ diff --git a/examples/quick/externaldraganddrop/CMakeLists.txt b/examples/quick/externaldraganddrop/CMakeLists.txt index 26a9f7271c7..a1ccea79367 100644 --- a/examples/quick/externaldraganddrop/CMakeLists.txt +++ b/examples/quick/externaldraganddrop/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from externaldraganddrop.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(externaldraganddrop LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -20,61 +20,30 @@ find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Quick) find_package(Qt6 COMPONENTS Qml) -qt_add_executable(externaldraganddrop +qt_add_executable(externaldraganddropexample main.cpp ) -set_target_properties(externaldraganddrop PROPERTIES +set_target_properties(externaldraganddropexample PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) -target_link_libraries(externaldraganddrop PUBLIC + +qt_add_qml_module(externaldraganddropexample + URI externaldraganddrop + VERSION 1.0 + QML_FILES + "DragAndDropTextItem.qml" + "externaldraganddrop.qml" +) + +target_link_libraries(externaldraganddropexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) - -# Resources: -set(externaldraganddrop_resource_files - "DragAndDropTextItem.qml" - "externaldraganddrop.qml" -) - -qt6_add_resources(externaldraganddrop "externaldraganddrop" - PREFIX - "/externaldraganddrop" - FILES - ${externaldraganddrop_resource_files} -) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(externaldraganddrop "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} -) - -install(TARGETS externaldraganddrop +install(TARGETS externaldraganddropexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/quick/externaldraganddrop/DragAndDropTextItem.qml b/examples/quick/externaldraganddrop/DragAndDropTextItem.qml index 605dc074344..ada96d2172a 100644 --- a/examples/quick/externaldraganddrop/DragAndDropTextItem.qml +++ b/examples/quick/externaldraganddrop/DragAndDropTextItem.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.2 -import "../shared" as Examples +import QtQuick +import QtQuick.Controls Rectangle { id: item @@ -62,8 +62,9 @@ Rectangle { to: "#EEE" duration: 1000 } - Text { + Label { anchors.fill: parent + anchors.margins: 10 text: item.display wrapMode: Text.WordWrap } @@ -104,9 +105,9 @@ Rectangle { item.display = "" } } - Examples.CheckBox { + CheckBox { id: acceptDropCB - anchors.right: parent.right + anchors.bottom: parent.bottom checked: true text: "accept drop" } diff --git a/examples/quick/externaldraganddrop/externaldraganddrop.pro b/examples/quick/externaldraganddrop/externaldraganddrop.pro index 0a592a84f3b..cd456f9b272 100644 --- a/examples/quick/externaldraganddrop/externaldraganddrop.pro +++ b/examples/quick/externaldraganddrop/externaldraganddrop.pro @@ -2,7 +2,7 @@ TEMPLATE = app QT += quick qml SOURCES += main.cpp -RESOURCES += externaldraganddrop.qrc ../shared/shared.qrc +RESOURCES += externaldraganddrop.qrc EXAMPLE_FILES = \ externaldraganddrop.qml \ diff --git a/examples/quick/externaldraganddrop/externaldraganddrop.qml b/examples/quick/externaldraganddrop/externaldraganddrop.qml index 47a76a259ad..05742ff4090 100644 --- a/examples/quick/externaldraganddrop/externaldraganddrop.qml +++ b/examples/quick/externaldraganddrop/externaldraganddrop.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,9 @@ ** ****************************************************************************/ -import QtQuick 2.2 -import QtQuick.Layouts 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts Item { id: root @@ -61,7 +62,7 @@ Item { anchors.fill: parent anchors.margins: 8 - Text { + Label { Layout.fillWidth: true text: "Drag text into, out of, and between the boxes below." wrapMode: Text.WordWrap @@ -69,19 +70,19 @@ Item { DragAndDropTextItem { Layout.fillWidth: true - height: 142 + Layout.fillHeight: true display: "Sample Text" } DragAndDropTextItem { Layout.fillWidth: true - height: 142 + Layout.fillHeight: true display: "Option/ctrl drag to copy instead of move text." } DragAndDropTextItem { Layout.fillWidth: true - height: 142 + Layout.fillHeight: true dropEnabled: false display: "Drag out into other applications." } diff --git a/examples/quick/imageelements/content/BorderImageSelector.qml b/examples/quick/imageelements/BorderImageSelector.qml similarity index 97% rename from examples/quick/imageelements/content/BorderImageSelector.qml rename to examples/quick/imageelements/BorderImageSelector.qml index d8c2101be78..76fbe380713 100644 --- a/examples/quick/imageelements/content/BorderImageSelector.qml +++ b/examples/quick/imageelements/BorderImageSelector.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick Item { id: selector @@ -66,7 +66,7 @@ Item { curIdx += steps; } Image { - source: "arrow.png" + source: "pics/arrow.png" MouseArea{ anchors.fill: parent onClicked: selector.advance(-1) @@ -78,7 +78,7 @@ Item { Behavior on opacity {NumberAnimation{}} } Image { - source: "arrow.png" + source: "pics/arrow.png" mirror: true MouseArea{ anchors.fill: parent diff --git a/examples/quick/imageelements/CMakeLists.txt b/examples/quick/imageelements/CMakeLists.txt index 1ffb16694df..425e8933bd4 100644 --- a/examples/quick/imageelements/CMakeLists.txt +++ b/examples/quick/imageelements/CMakeLists.txt @@ -1,13 +1,12 @@ # Generated from imageelements.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(imageelements LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,89 +14,58 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/imageelements") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) -qt_add_executable(imageelements +add_subdirectory("../shared" "shared") + +qt_add_executable(imageelementsexample + WIN32 + MACOSX_BUNDLE main.cpp ) -set_target_properties(imageelements PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(imageelements PUBLIC + +target_link_libraries(imageelementsexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +qt_add_qml_module(imageelementsexample + URI imageelements + VERSION 1.0 + QML_FILES + "animatedimage.qml" + "animatedsprite.qml" + "borderimage.qml" + "framestepping.qml" + "image.qml" + "imageelements.qml" + "multiframeborderimage.qml" + "shadows.qml" + "spritesequence.qml" + "BorderImageSelector.qml" + "ImageCell.qml" + "MyBorderImage.qml" + "ShadowRectangle.qml" + RESOURCES + "pics/qt-logo.png" + "pics/shadow.png" + "pics/speaker.png" + "pics/colors.png" + "pics/BearSheet.png" + "pics/Uniflow_steam_engine.gif" + "pics/arrow.png" + "pics/bw.png" + "pics/multi.ico" + "pics/colors-round.sci" + "pics/colors-stretch.sci" + ) -# Resources: -set(imageelements_resource_files - "animatedimage.qml" - "animatedsprite.qml" - "borderimage.qml" - "content/BearSheet.png" - "content/BorderImageSelector.qml" - "content/ImageCell.qml" - "content/MyBorderImage.qml" - "content/ShadowRectangle.qml" - "content/Uniflow_steam_engine.gif" - "content/arrow.png" - "content/bw.png" - "content/colors-round.sci" - "content/colors-stretch.sci" - "content/colors.png" - "content/multi.ico" - "content/qt-logo.png" - "content/shadow.png" - "content/speaker.png" - "framestepping.qml" - "image.qml" - "imageelements.qml" - "multiframeborderimage.qml" - "shadows.qml" - "spritesequence.qml" -) - -qt6_add_resources(imageelements "imageelements" - PREFIX - "/imageelements" - FILES - ${imageelements_resource_files} -) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(imageelements "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} -) - -install(TARGETS imageelements +install(TARGETS imageelementsexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) + +bundle_shared(imageelementsexample) diff --git a/examples/quick/imageelements/content/ImageCell.qml b/examples/quick/imageelements/ImageCell.qml similarity index 95% rename from examples/quick/imageelements/content/ImageCell.qml rename to examples/quick/imageelements/ImageCell.qml index 7804346bd46..053afdde5d3 100644 --- a/examples/quick/imageelements/content/ImageCell.qml +++ b/examples/quick/imageelements/ImageCell.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,7 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick +import QtQuick.Controls Item { property alias mode: image.fillMode @@ -56,11 +57,11 @@ Item { Image { id: image width: parent.width; height: parent.height - captionItem.height - source: "qt-logo.png" + source: "pics/qt-logo.png" clip: true // only makes a difference if mode is PreserveAspectCrop } - Text { + Label { id: captionItem anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom } diff --git a/examples/quick/imageelements/content/MyBorderImage.qml b/examples/quick/imageelements/MyBorderImage.qml similarity index 98% rename from examples/quick/imageelements/content/MyBorderImage.qml rename to examples/quick/imageelements/MyBorderImage.qml index 3198de3bf14..5d11716a435 100644 --- a/examples/quick/imageelements/content/MyBorderImage.qml +++ b/examples/quick/imageelements/MyBorderImage.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQml 2.0 -import QtQuick 2.0 +import QtQml +import QtQuick Item { id: container diff --git a/examples/quick/imageelements/content/ShadowRectangle.qml b/examples/quick/imageelements/ShadowRectangle.qml similarity index 96% rename from examples/quick/imageelements/content/ShadowRectangle.qml rename to examples/quick/imageelements/ShadowRectangle.qml index 7bce665b236..b112004fbc8 100644 --- a/examples/quick/imageelements/content/ShadowRectangle.qml +++ b/examples/quick/imageelements/ShadowRectangle.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick Item { property alias color : rectangle.color @@ -58,7 +58,7 @@ Item { anchors.fill: rectangle anchors { leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8 } border { left: 10; top: 10; right: 10; bottom: 10 } - source: "shadow.png" + source: "pics/shadow.png" } //! [shadow] diff --git a/examples/quick/imageelements/animatedimage.qml b/examples/quick/imageelements/animatedimage.qml index 04bc38fe956..11c41e3ae39 100644 --- a/examples/quick/imageelements/animatedimage.qml +++ b/examples/quick/imageelements/animatedimage.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,8 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -import QtQuick 2.12 -import "../shared" as Examples +import QtQuick +import QtQuick.Controls Column { width: 320 @@ -59,7 +59,7 @@ Column { //! [image] AnimatedImage { id: animation - source: "content/Uniflow_steam_engine.gif" + source: "pics/Uniflow_steam_engine.gif" anchors.horizontalCenter: parent.horizontalCenter speed: speedSlider.value TapHandler { @@ -86,29 +86,43 @@ Column { } } - Examples.Slider { - id: speedSlider - name: "Speed" - min: 0 - max: 5 - init: 1 - width: 240 - x: animation.x - Text { + Row { + spacing: 6 + anchors.horizontalCenter: parent.horizontalCenter + + Label { + text: qsTr("Speed:") + font.pointSize: 12 + anchors.verticalCenter: speedSlider.verticalCenter + } + + Slider { + id: speedSlider + from: 0 + to: 5 + value: 1 + } + + Label { + font: fontMetrics.font + text: qsTr(Math.round(animation.speed * 100) + "%") + width: fontMetrics.width + anchors.verticalCenter: speedSlider.verticalCenter + } + + TextMetrics { + id: fontMetrics + text: "100%" font.pointSize: 12 - text: Math.round(animation.speed * 100) + "%" - x: animation.width - width - anchors.verticalCenter: parent.verticalCenter - anchors.margins: 6 } } - Examples.Button { - text: "Reset" + Button { + text: qsTr("Reset") enabled: speedSlider.value !== 1 anchors.horizontalCenter: parent.horizontalCenter onClicked: { - speedSlider.setValue(1) + speedSlider.value = 1 animation.playing = true } } diff --git a/examples/quick/imageelements/animatedsprite.qml b/examples/quick/imageelements/animatedsprite.qml index 8666c2b9fcf..3a01eb427bb 100644 --- a/examples/quick/imageelements/animatedsprite.qml +++ b/examples/quick/imageelements/animatedsprite.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,7 +47,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick +import QtQuick.Controls Item { width: 320 @@ -61,7 +62,7 @@ Item { AnimatedSprite { id: sprite anchors.centerIn: parent - source: "content/speaker.png" + source: "pics/speaker.png" frameCount: 60 frameSync: true frameWidth: 170 @@ -70,7 +71,7 @@ Item { } //! [sprite] - Text { + Label { text: "Left click to resume\nMiddle click to advance backward\nRight click to advance forward" visible: sprite.paused } diff --git a/examples/quick/imageelements/borderimage.qml b/examples/quick/imageelements/borderimage.qml index 00f18737f6c..15fe32ed9f7 100644 --- a/examples/quick/imageelements/borderimage.qml +++ b/examples/quick/imageelements/borderimage.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "content" +import QtQuick Rectangle { id: page @@ -81,47 +80,47 @@ Rectangle { MyBorderImage { minWidth: 120; maxWidth: 240; minHeight: 120; maxHeight: 200 - source: "content/colors.png"; margin: 30 + source: "pics/colors.png"; margin: 30 } MyBorderImage { minWidth: 120; maxWidth: 240; minHeight: 120; maxHeight: 200 - source: "content/colors.png"; margin: 30 + source: "pics/colors.png"; margin: 30 horizontalMode: BorderImage.Repeat; verticalMode: BorderImage.Repeat } MyBorderImage { minWidth: 120; maxWidth: 240; minHeight: 120; maxHeight: 200 - source: "content/colors.png"; margin: 30 + source: "pics/colors.png"; margin: 30 horizontalMode: BorderImage.Stretch; verticalMode: BorderImage.Repeat } MyBorderImage { minWidth: 120; maxWidth: 240; minHeight: 120; maxHeight: 200 - source: "content/colors.png"; margin: 30 + source: "pics/colors.png"; margin: 30 horizontalMode: BorderImage.Round; verticalMode: BorderImage.Round } MyBorderImage { minWidth: 60; maxWidth: 200; minHeight: 40; maxHeight: 200 - source: "content/bw.png"; margin: 10 + source: "pics/bw.png"; margin: 10 } MyBorderImage { minWidth: 60; maxWidth: 200; minHeight: 40; maxHeight: 200 - source: "content/bw.png"; margin: 10 + source: "pics/bw.png"; margin: 10 horizontalMode: BorderImage.Repeat; verticalMode: BorderImage.Repeat } MyBorderImage { minWidth: 60; maxWidth: 200; minHeight: 40; maxHeight: 200 - source: "content/bw.png"; margin: 10 + source: "pics/bw.png"; margin: 10 horizontalMode: BorderImage.Stretch; verticalMode: BorderImage.Repeat } MyBorderImage { minWidth: 60; maxWidth: 200; minHeight: 40; maxHeight: 200 - source: "content/bw.png"; margin: 10 + source: "pics/bw.png"; margin: 10 horizontalMode: BorderImage.Round; verticalMode: BorderImage.Round } } diff --git a/examples/quick/imageelements/doc/src/imageelements.qdoc b/examples/quick/imageelements/doc/src/imageelements.qdoc index 4c00915e565..90cb2c4d2e4 100644 --- a/examples/quick/imageelements/doc/src/imageelements.qdoc +++ b/examples/quick/imageelements/doc/src/imageelements.qdoc @@ -49,7 +49,7 @@ \e Shadows shows how to create a drop shadow effect for a rectangular item using a \l BorderImage: - \snippet imageelements/content/ShadowRectangle.qml shadow + \snippet imageelements/ShadowRectangle.qml shadow \section1 Sprite Animations with AnimatedSprite diff --git a/examples/quick/imageelements/framestepping.qml b/examples/quick/imageelements/framestepping.qml index f5bad46e7b3..a536bb28d8c 100644 --- a/examples/quick/imageelements/framestepping.qml +++ b/examples/quick/imageelements/framestepping.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.14 +import QtQuick +import QtQuick.Controls Rectangle { width: 480 @@ -57,7 +58,7 @@ Rectangle { id: img anchors.centerIn: parent cache: true - source: "content/multi.ico" + source: "pics/multi.ico" Shortcut { sequence: StandardKey.MoveToNextPage @@ -71,7 +72,7 @@ Rectangle { } } - Text { + Label { anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom anchors.margins: 6 diff --git a/examples/quick/imageelements/image.qml b/examples/quick/imageelements/image.qml index 0750ea3b79f..d4040e0be06 100644 --- a/examples/quick/imageelements/image.qml +++ b/examples/quick/imageelements/image.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "content" +import QtQuick Rectangle { width: 320 diff --git a/examples/quick/imageelements/imageelements.qml b/examples/quick/imageelements/imageelements.qml index 91f2e034f70..74fb36c5bb2 100644 --- a/examples/quick/imageelements/imageelements.qml +++ b/examples/quick/imageelements/imageelements.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,13 +48,13 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "../shared" +import QtQuick +import shared as Shared Item { height: 480 width: 320 - LauncherList { + Shared.LauncherList { id: ll anchors.fill: parent Component.onCompleted: { diff --git a/examples/quick/imageelements/imageelements.qrc b/examples/quick/imageelements/imageelements.qrc index cedef2204ca..62f2bbfc76d 100644 --- a/examples/quick/imageelements/imageelements.qrc +++ b/examples/quick/imageelements/imageelements.qrc @@ -1,28 +1,28 @@ - content/arrow.png - content/BearSheet.png - content/BorderImageSelector.qml - content/bw.png - content/colors-round.sci - content/colors-stretch.sci - content/colors.png - content/ImageCell.qml - content/multi.ico - content/MyBorderImage.qml - content/qt-logo.png - content/shadow.png - content/ShadowRectangle.qml - content/speaker.png - content/Uniflow_steam_engine.gif - imageelements.qml animatedimage.qml animatedsprite.qml borderimage.qml + BorderImageSelector.qml framestepping.qml - multiframeborderimage.qml + ImageCell.qml + imageelements.qml image.qml + multiframeborderimage.qml + MyBorderImage.qml + ShadowRectangle.qml shadows.qml spritesequence.qml + pics/arrow.png + pics/BearSheet.png + pics/bw.png + pics/colors-round.sci + pics/colors-stretch.sci + pics/colors.png + pics/multi.ico + pics/qt-logo.png + pics/shadow.png + pics/speaker.png + pics/Uniflow_steam_engine.gif diff --git a/examples/quick/imageelements/multiframeborderimage.qml b/examples/quick/imageelements/multiframeborderimage.qml index 0805ea42434..d3a64d88d18 100644 --- a/examples/quick/imageelements/multiframeborderimage.qml +++ b/examples/quick/imageelements/multiframeborderimage.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.14 +import QtQuick +import QtQuick.Controls Rectangle { width: 480 @@ -58,7 +59,7 @@ Rectangle { anchors.fill: parent anchors.margins: 6 cache: true - source: "content/multi.ico" + source: "pics/multi.ico" border { left: 19; top: 19; right: 19; bottom: 19 } horizontalTileMode: BorderImage.Stretch @@ -74,7 +75,7 @@ Rectangle { } } - Text { + Label { anchors.centerIn: parent horizontalAlignment: Text.AlignHCenter text: "frame " + (img.currentFrame + 1) + " of " + img.frameCount + diff --git a/examples/quick/imageelements/content/BearSheet.png b/examples/quick/imageelements/pics/BearSheet.png similarity index 100% rename from examples/quick/imageelements/content/BearSheet.png rename to examples/quick/imageelements/pics/BearSheet.png diff --git a/examples/quick/imageelements/content/Uniflow_steam_engine.gif b/examples/quick/imageelements/pics/Uniflow_steam_engine.gif similarity index 100% rename from examples/quick/imageelements/content/Uniflow_steam_engine.gif rename to examples/quick/imageelements/pics/Uniflow_steam_engine.gif diff --git a/examples/quick/imageelements/content/arrow.png b/examples/quick/imageelements/pics/arrow.png similarity index 100% rename from examples/quick/imageelements/content/arrow.png rename to examples/quick/imageelements/pics/arrow.png diff --git a/examples/quick/imageelements/content/bw.png b/examples/quick/imageelements/pics/bw.png similarity index 100% rename from examples/quick/imageelements/content/bw.png rename to examples/quick/imageelements/pics/bw.png diff --git a/examples/quick/imageelements/content/colors-round.sci b/examples/quick/imageelements/pics/colors-round.sci similarity index 100% rename from examples/quick/imageelements/content/colors-round.sci rename to examples/quick/imageelements/pics/colors-round.sci diff --git a/examples/quick/imageelements/content/colors-stretch.sci b/examples/quick/imageelements/pics/colors-stretch.sci similarity index 100% rename from examples/quick/imageelements/content/colors-stretch.sci rename to examples/quick/imageelements/pics/colors-stretch.sci diff --git a/examples/quick/imageelements/content/colors.png b/examples/quick/imageelements/pics/colors.png similarity index 100% rename from examples/quick/imageelements/content/colors.png rename to examples/quick/imageelements/pics/colors.png diff --git a/examples/quick/imageelements/content/multi.ico b/examples/quick/imageelements/pics/multi.ico similarity index 100% rename from examples/quick/imageelements/content/multi.ico rename to examples/quick/imageelements/pics/multi.ico diff --git a/examples/quick/imageelements/content/qt-logo.png b/examples/quick/imageelements/pics/qt-logo.png similarity index 100% rename from examples/quick/imageelements/content/qt-logo.png rename to examples/quick/imageelements/pics/qt-logo.png diff --git a/examples/quick/imageelements/content/shadow.png b/examples/quick/imageelements/pics/shadow.png similarity index 100% rename from examples/quick/imageelements/content/shadow.png rename to examples/quick/imageelements/pics/shadow.png diff --git a/examples/quick/imageelements/content/speaker.png b/examples/quick/imageelements/pics/speaker.png similarity index 100% rename from examples/quick/imageelements/content/speaker.png rename to examples/quick/imageelements/pics/speaker.png diff --git a/examples/quick/imageelements/shadows.qml b/examples/quick/imageelements/shadows.qml index 981133f7255..8fea9250bc2 100644 --- a/examples/quick/imageelements/shadows.qml +++ b/examples/quick/imageelements/shadows.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "content" +import QtQuick Rectangle { id: window diff --git a/examples/quick/imageelements/spritesequence.qml b/examples/quick/imageelements/spritesequence.qml index 8581bf1ea84..a047b22fbc8 100644 --- a/examples/quick/imageelements/spritesequence.qml +++ b/examples/quick/imageelements/spritesequence.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,7 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick Item { width: 320 @@ -73,9 +73,9 @@ Item { interpolate: false goalSprite: "" //! [still] - Sprite{ + Sprite { name: "still" - source: "content/BearSheet.png" + source: "pics/BearSheet.png" frameCount: 1 frameWidth: 256 frameHeight: 256 @@ -83,9 +83,9 @@ Item { to: {"still":1, "blink":0.1, "floating":0} } //! [still] - Sprite{ + Sprite { name: "blink" - source: "content/BearSheet.png" + source: "pics/BearSheet.png" frameCount: 3 frameX: 256 frameY: 1536 @@ -94,9 +94,9 @@ Item { frameDuration: 100 to: {"still":1} } - Sprite{ + Sprite { name: "floating" - source: "content/BearSheet.png" + source: "pics/BearSheet.png" frameCount: 9 frameX: 0 frameY: 0 @@ -105,9 +105,9 @@ Item { frameDuration: 160 to: {"still":0, "flailing":1} } - Sprite{ + Sprite { name: "flailing" - source: "content/BearSheet.png" + source: "pics/BearSheet.png" frameCount: 8 frameX: 0 frameY: 768 @@ -116,9 +116,9 @@ Item { frameDuration: 160 to: {"falling":1} } - Sprite{ + Sprite { name: "falling" - source: "content/BearSheet.png" + source: "pics/BearSheet.png" frameCount: 5 frameY: 1280 frameWidth: 256 diff --git a/examples/quick/imageprovider/CMakeLists.txt b/examples/quick/imageprovider/CMakeLists.txt index 5a25a45deb1..56cffa33c55 100644 --- a/examples/quick/imageprovider/CMakeLists.txt +++ b/examples/quick/imageprovider/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from imageprovider.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(qmlimageproviderplugin LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -14,6 +14,7 @@ if(NOT DEFINED INSTALL_EXAMPLESDIR) endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/imageprovider/ImageProviderCore") +set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/examples/quick/imageprovider) find_package(Qt6 COMPONENTS Core) find_package(Qt6 COMPONENTS Gui) @@ -21,7 +22,6 @@ find_package(Qt6 COMPONENTS Qml) find_package(Qt6 COMPONENTS Quick) qt6_add_qml_module(qmlimageproviderplugin - OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/ImageProviderCore" VERSION 1.0 URI "ImageProviderCore" PLUGIN_TARGET qmlimageproviderplugin diff --git a/examples/quick/imageresponseprovider/CMakeLists.txt b/examples/quick/imageresponseprovider/CMakeLists.txt index 551ce01197d..7f11e8ff86d 100644 --- a/examples/quick/imageresponseprovider/CMakeLists.txt +++ b/examples/quick/imageresponseprovider/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from imageresponseprovider.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(qmlimageresponseproviderplugin LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -14,6 +14,7 @@ if(NOT DEFINED INSTALL_EXAMPLESDIR) endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/imageresponseprovider/ImageResponseProviderCore") +set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/examples/quick/imageresponseprovider) find_package(Qt6 COMPONENTS Core) find_package(Qt6 COMPONENTS Gui) @@ -21,7 +22,6 @@ find_package(Qt6 COMPONENTS Qml) find_package(Qt6 COMPONENTS Quick) qt6_add_qml_module(qmlimageresponseproviderplugin - OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/ImageResponseProviderCore" VERSION 1.0 URI "ImageResponseProviderCore" PLUGIN_TARGET qmlimageresponseproviderplugin diff --git a/examples/quick/keyinteraction/CMakeLists.txt b/examples/quick/keyinteraction/CMakeLists.txt index b62d6754d38..e338c110244 100644 --- a/examples/quick/keyinteraction/CMakeLists.txt +++ b/examples/quick/keyinteraction/CMakeLists.txt @@ -1,13 +1,9 @@ -# Generated from keyinteraction.pro. - -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(keyinteraction LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,47 +11,36 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/keyinteraction") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) -qt_add_executable(keyinteraction +qt_add_executable(keyinteractionexample WIN32 MACOSX_BUNDLE main.cpp ) -set_target_properties(keyinteraction PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(keyinteraction PUBLIC +target_link_libraries(keyinteractionexample PRIVATE Qt::Core Qt::Gui Qt::Qml Qt::Quick ) - # Resources: -set(keyinteraction_resource_files - "focus/Core/ContextMenu.qml" - "focus/Core/GridMenu.qml" - "focus/Core/ListMenu.qml" - "focus/Core/ListViewDelegate.qml" - "focus/Core/TabMenu.qml" - "focus/Core/images/arrow.png" - "focus/Core/images/qt-logo.png" - "focus/focus.qml" - "keyinteraction.qml" -) - -qt6_add_resources(keyinteraction "keyinteraction" - PREFIX - "/keyinteraction" - FILES - ${keyinteraction_resource_files} +qt_add_qml_module(keyinteractionexample + URI keyinteraction + VERSION 1.0 + QML_FILES + "ContextMenu.qml" + "GridMenu.qml" + "ListMenu.qml" + "ListViewDelegate.qml" + "TabMenu.qml" + "focus.qml" + "keyinteraction.qml" + RESOURCES + "images/arrow.png" + "images/qt-logo.png" ) -install(TARGETS keyinteraction +install(TARGETS keyinteractionexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/quick/keyinteraction/focus/Core/ContextMenu.qml b/examples/quick/keyinteraction/ContextMenu.qml similarity index 98% rename from examples/quick/keyinteraction/focus/Core/ContextMenu.qml rename to examples/quick/keyinteraction/ContextMenu.qml index 31b5e1b83de..66dcdf3fe8d 100644 --- a/examples/quick/keyinteraction/focus/Core/ContextMenu.qml +++ b/examples/quick/keyinteraction/ContextMenu.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.1 +import QtQuick FocusScope { id: container diff --git a/examples/quick/keyinteraction/focus/Core/GridMenu.qml b/examples/quick/keyinteraction/GridMenu.qml similarity index 98% rename from examples/quick/keyinteraction/focus/Core/GridMenu.qml rename to examples/quick/keyinteraction/GridMenu.qml index 78d66549573..d5914fe4d6a 100644 --- a/examples/quick/keyinteraction/focus/Core/GridMenu.qml +++ b/examples/quick/keyinteraction/GridMenu.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.1 +import QtQuick FocusScope { id: menu diff --git a/examples/quick/keyinteraction/focus/Core/ListMenu.qml b/examples/quick/keyinteraction/ListMenu.qml similarity index 98% rename from examples/quick/keyinteraction/focus/Core/ListMenu.qml rename to examples/quick/keyinteraction/ListMenu.qml index 694ae3cac6c..97a37a714b1 100644 --- a/examples/quick/keyinteraction/focus/Core/ListMenu.qml +++ b/examples/quick/keyinteraction/ListMenu.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQml 2.1 -import QtQuick 2.1 +import QtQml +import QtQuick FocusScope { id: menu diff --git a/examples/quick/keyinteraction/focus/Core/ListViewDelegate.qml b/examples/quick/keyinteraction/ListViewDelegate.qml similarity index 98% rename from examples/quick/keyinteraction/focus/Core/ListViewDelegate.qml rename to examples/quick/keyinteraction/ListViewDelegate.qml index 5a2957eab0c..1d14f221957 100644 --- a/examples/quick/keyinteraction/focus/Core/ListViewDelegate.qml +++ b/examples/quick/keyinteraction/ListViewDelegate.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.1 +import QtQuick Item { id: container diff --git a/examples/quick/keyinteraction/focus/Core/TabMenu.qml b/examples/quick/keyinteraction/TabMenu.qml similarity index 98% rename from examples/quick/keyinteraction/focus/Core/TabMenu.qml rename to examples/quick/keyinteraction/TabMenu.qml index 11b3d005c33..cfa38e958c7 100644 --- a/examples/quick/keyinteraction/focus/Core/TabMenu.qml +++ b/examples/quick/keyinteraction/TabMenu.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.1 +import QtQuick FocusScope { id: menu diff --git a/examples/quick/keyinteraction/focus/focus.qml b/examples/quick/keyinteraction/focus.qml similarity index 97% rename from examples/quick/keyinteraction/focus/focus.qml rename to examples/quick/keyinteraction/focus.qml index 9db9ab48bc4..7b1452ba35c 100644 --- a/examples/quick/keyinteraction/focus/focus.qml +++ b/examples/quick/keyinteraction/focus.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,9 +48,8 @@ ** ****************************************************************************/ -import QtQml 2.1 -import QtQuick 2.1 -import "Core" +import QtQml +import QtQuick Rectangle { id: window @@ -145,7 +144,7 @@ Rectangle { } Image { - source: "Core/images/arrow.png" + source: "images/arrow.png" rotation: 90 anchors.verticalCenter: parent.verticalCenter diff --git a/examples/quick/keyinteraction/focus/Core/images/arrow.png b/examples/quick/keyinteraction/images/arrow.png similarity index 100% rename from examples/quick/keyinteraction/focus/Core/images/arrow.png rename to examples/quick/keyinteraction/images/arrow.png diff --git a/examples/quick/keyinteraction/focus/Core/images/qt-logo.png b/examples/quick/keyinteraction/images/qt-logo.png similarity index 100% rename from examples/quick/keyinteraction/focus/Core/images/qt-logo.png rename to examples/quick/keyinteraction/images/qt-logo.png diff --git a/examples/quick/keyinteraction/keyinteraction.qml b/examples/quick/keyinteraction/keyinteraction.qml index 7fa3078803e..c79ba7217ef 100644 --- a/examples/quick/keyinteraction/keyinteraction.qml +++ b/examples/quick/keyinteraction/keyinteraction.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,10 +48,10 @@ ** ****************************************************************************/ -import QtQuick 2.1 +import QtQuick Loader {//Just loader, since there's only one. - source: "focus/focus.qml" + source: "focus.qml" focus: true // Exception to the standard sizing, because this is primarily a desktop // example and it benefits from being able to see everything at once. diff --git a/examples/quick/keyinteraction/keyinteraction.qrc b/examples/quick/keyinteraction/keyinteraction.qrc index c7196548350..8738ef98260 100644 --- a/examples/quick/keyinteraction/keyinteraction.qrc +++ b/examples/quick/keyinteraction/keyinteraction.qrc @@ -1,13 +1,13 @@ keyinteraction.qml - focus/focus.qml - focus/Core/images/arrow.png - focus/Core/images/qt-logo.png - focus/Core/ContextMenu.qml - focus/Core/GridMenu.qml - focus/Core/ListMenu.qml - focus/Core/ListViewDelegate.qml - focus/Core/TabMenu.qml + focus.qml + ContextMenu.qml + GridMenu.qml + ListMenu.qml + ListViewDelegate.qml + TabMenu.qml + images/arrow.png + images/qt-logo.png diff --git a/examples/quick/layouts/CMakeLists.txt b/examples/quick/layouts/CMakeLists.txt index e87ef25e926..dc9bf06e66d 100644 --- a/examples/quick/layouts/CMakeLists.txt +++ b/examples/quick/layouts/CMakeLists.txt @@ -1,13 +1,12 @@ # Generated from layouts.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(layouts LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,39 +14,29 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/layouts") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Qml) -find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Core Gui Qml Quick) -qt_add_executable(layouts +qt_add_executable(layoutsexample + WIN32 + MACOSX_BUNDLE main.cpp ) -set_target_properties(layouts PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE + +qt_add_qml_module(layoutsexample + URI layouts + VERSION 1.0 + QML_FILES + "layouts.qml" ) -target_link_libraries(layouts PUBLIC + +target_link_libraries(layoutsexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) - -# Resources: -set(layouts_resource_files - "layouts.qml" -) - -qt6_add_resources(layouts "layouts" - PREFIX - "/layouts" - FILES - ${layouts_resource_files} -) - -install(TARGETS layouts +install(TARGETS layoutsexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/quick/layouts/layouts.qml b/examples/quick/layouts/layouts.qml index 8a1cb20d22b..423b670b068 100644 --- a/examples/quick/layouts/layouts.qml +++ b/examples/quick/layouts/layouts.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,9 +48,9 @@ ** ****************************************************************************/ -import QtQuick 2.2 -import QtQuick.Controls 2.12 -import QtQuick.Layouts 1.3 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts ApplicationWindow { id: appWindow diff --git a/examples/quick/localstorage/CMakeLists.txt b/examples/quick/localstorage/CMakeLists.txt index 6a405efc817..1f5e60197b4 100644 --- a/examples/quick/localstorage/CMakeLists.txt +++ b/examples/quick/localstorage/CMakeLists.txt @@ -1,3 +1,47 @@ # Generated from localstorage.pro. -qt_internal_add_example(localstorage) +cmake_minimum_required(VERSION 3.16) +project(localstorage LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/localstorage") + +find_package(Qt6 COMPONENTS Core Gui Quick Qml) + +qt_add_executable(localstorageexample + WIN32 + MACOSX_BUNDLE + main.cpp +) + +qt_add_qml_module(localstorageexample + URI localstorage + VERSION 1.0 + QML_FILES + "Database.js" + "Header.qml" + "MyDelegate.qml" + "MyModel.qml" + "localstorage.qml" + ) + +target_link_libraries(localstorageexample PUBLIC + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +install(TARGETS localstorageexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quick/localstorage/localstorage/Database.js b/examples/quick/localstorage/Database.js similarity index 100% rename from examples/quick/localstorage/localstorage/Database.js rename to examples/quick/localstorage/Database.js diff --git a/examples/quick/localstorage/localstorage/Header.qml b/examples/quick/localstorage/Header.qml similarity index 100% rename from examples/quick/localstorage/localstorage/Header.qml rename to examples/quick/localstorage/Header.qml diff --git a/examples/quick/localstorage/localstorage/MyDelegate.qml b/examples/quick/localstorage/MyDelegate.qml similarity index 100% rename from examples/quick/localstorage/localstorage/MyDelegate.qml rename to examples/quick/localstorage/MyDelegate.qml diff --git a/examples/quick/localstorage/localstorage/MyModel.qml b/examples/quick/localstorage/MyModel.qml similarity index 100% rename from examples/quick/localstorage/localstorage/MyModel.qml rename to examples/quick/localstorage/MyModel.qml diff --git a/examples/quick/localstorage/localstorage.pro b/examples/quick/localstorage/localstorage.pro index dd2eb802501..9709733c139 100644 --- a/examples/quick/localstorage/localstorage.pro +++ b/examples/quick/localstorage/localstorage.pro @@ -1,2 +1,9 @@ -TEMPLATE = subdirs -SUBDIRS += localstorage +TEMPLATE = app + +QT += quick qml +SOURCES += main.cpp +RESOURCES += \ + localstorage.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/quick/localstorage +INSTALLS += target diff --git a/examples/quick/localstorage/localstorage/localstorage.qml b/examples/quick/localstorage/localstorage.qml similarity index 100% rename from examples/quick/localstorage/localstorage/localstorage.qml rename to examples/quick/localstorage/localstorage.qml diff --git a/examples/quick/localstorage/localstorage/localstorage.qrc b/examples/quick/localstorage/localstorage.qrc similarity index 83% rename from examples/quick/localstorage/localstorage/localstorage.qrc rename to examples/quick/localstorage/localstorage.qrc index a761306f3d3..62c72daa9f2 100644 --- a/examples/quick/localstorage/localstorage/localstorage.qrc +++ b/examples/quick/localstorage/localstorage.qrc @@ -1,5 +1,5 @@ - + Header.qml Database.js MyModel.qml diff --git a/examples/quick/localstorage/localstorage/CMakeLists.txt b/examples/quick/localstorage/localstorage/CMakeLists.txt deleted file mode 100644 index bfb304b1cc1..00000000000 --- a/examples/quick/localstorage/localstorage/CMakeLists.txt +++ /dev/null @@ -1,58 +0,0 @@ -# Generated from localstorage.pro. - -cmake_minimum_required(VERSION 3.14) -project(localstorage LANGUAGES CXX) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/localstorage/localstorage") - -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) - -qt_add_executable(localstorage - main.cpp -) -set_target_properties(localstorage PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(localstorage PUBLIC - Qt::Core - Qt::Gui - Qt::Qml - Qt::Quick -) - - -# Resources: -set(localstorage_resource_files - "Database.js" - "Header.qml" - "MyDelegate.qml" - "MyModel.qml" - "localstorage.qml" -) - -qt6_add_resources(localstorage "localstorage" - PREFIX - "/" - FILES - ${localstorage_resource_files} -) - -install(TARGETS localstorage - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/quick/localstorage/localstorage/localstorage.pro b/examples/quick/localstorage/localstorage/localstorage.pro deleted file mode 100644 index 8feca66f28b..00000000000 --- a/examples/quick/localstorage/localstorage/localstorage.pro +++ /dev/null @@ -1,9 +0,0 @@ -TEMPLATE = app - -QT += quick qml -SOURCES += main.cpp -RESOURCES += \ - localstorage.qrc - -target.path = $$[QT_INSTALL_EXAMPLES]/quick/localstorage/localstorage -INSTALLS += target diff --git a/examples/quick/localstorage/localstorage/main.cpp b/examples/quick/localstorage/localstorage/main.cpp deleted file mode 100644 index 293c81768a9..00000000000 --- a/examples/quick/localstorage/localstorage/main.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - - QQmlApplicationEngine engine; - engine.load(QUrl(QStringLiteral("qrc:/localstorage.qml"))); - - return app.exec(); -} diff --git a/examples/quick/localstorage/main.cpp b/examples/quick/localstorage/main.cpp new file mode 100644 index 00000000000..6ff5d33cc5b --- /dev/null +++ b/examples/quick/localstorage/main.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/localstorage/localstorage.qml"))); + + return app.exec(); +} diff --git a/examples/quick/models/abstractitemmodel/CMakeLists.txt b/examples/quick/models/abstractitemmodel/CMakeLists.txt index 992fdd0f8ad..486e6d376a7 100644 --- a/examples/quick/models/abstractitemmodel/CMakeLists.txt +++ b/examples/quick/models/abstractitemmodel/CMakeLists.txt @@ -1,13 +1,12 @@ # Generated from abstractitemmodel.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(abstractitemmodel LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,20 +14,13 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/models/abstractitemmodel") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Qml) -find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Core Gui Qml Quick) -qt_add_executable(abstractitemmodel +qt_add_executable(abstractitemmodelexample WIN32 MACOSX_BUNDLE main.cpp - model.cpp model.h + model.cpp ) -set_target_properties(abstractitemmodel PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(abstractitemmodel PUBLIC +target_link_libraries(abstractitemmodelexample PUBLIC Qt::Core Qt::Gui Qt::Qml @@ -37,18 +29,14 @@ target_link_libraries(abstractitemmodel PUBLIC # Resources: -set(abstractitemmodel_resource_files - "view.qml" -) - -qt6_add_resources(abstractitemmodel "abstractitemmodel" - PREFIX - "/" - FILES - ${abstractitemmodel_resource_files} +qt_add_qml_module(abstractitemmodelexample + URI abstractitemmodel + VERSION 1.0 + QML_FILES + "view.qml" ) -install(TARGETS abstractitemmodel +install(TARGETS abstractitemmodelexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/quick/models/abstractitemmodel/abstractitemmodel.qrc b/examples/quick/models/abstractitemmodel/abstractitemmodel.qrc index 4ae861cb3de..ad8c2df8aec 100644 --- a/examples/quick/models/abstractitemmodel/abstractitemmodel.qrc +++ b/examples/quick/models/abstractitemmodel/abstractitemmodel.qrc @@ -1,5 +1,5 @@ - + view.qml diff --git a/examples/quick/models/abstractitemmodel/main.cpp b/examples/quick/models/abstractitemmodel/main.cpp index dd5b368c6bb..9e820391f67 100644 --- a/examples/quick/models/abstractitemmodel/main.cpp +++ b/examples/quick/models/abstractitemmodel/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -70,7 +70,7 @@ int main(int argc, char ** argv) view.setResizeMode(QQuickView::SizeRootObjectToView); view.setInitialProperties({{"model", QVariant::fromValue(&model)}}); //![0] - view.setSource(QUrl("qrc:view.qml")); + view.setSource(QUrl("qrc:/abstractitemmodel/view.qml")); view.show(); return app.exec(); diff --git a/examples/quick/models/abstractitemmodel/model.cpp b/examples/quick/models/abstractitemmodel/model.cpp index 9d0032e34c9..c58e05577a8 100644 --- a/examples/quick/models/abstractitemmodel/model.cpp +++ b/examples/quick/models/abstractitemmodel/model.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. diff --git a/examples/quick/models/abstractitemmodel/view.qml b/examples/quick/models/abstractitemmodel/view.qml index 2b9f87df923..f80c4dca72c 100644 --- a/examples/quick/models/abstractitemmodel/view.qml +++ b/examples/quick/models/abstractitemmodel/view.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -47,7 +47,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick //![0] ListView { diff --git a/examples/quick/models/objectlistmodel/CMakeLists.txt b/examples/quick/models/objectlistmodel/CMakeLists.txt index 23b4cf7ed5c..8dbee3ae0be 100644 --- a/examples/quick/models/objectlistmodel/CMakeLists.txt +++ b/examples/quick/models/objectlistmodel/CMakeLists.txt @@ -1,13 +1,12 @@ # Generated from objectlistmodel.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(objectlistmodel LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,20 +14,13 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/models/objectlistmodel") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Qml) -find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Core Gui Qml Quick) -qt_add_executable(objectlistmodel - dataobject.cpp dataobject.h +qt_add_executable(objectlistmodelexample WIN32 MACOSX_BUNDLE + dataobject.cpp main.cpp ) -set_target_properties(objectlistmodel PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(objectlistmodel PUBLIC +target_link_libraries(objectlistmodelexample PUBLIC Qt::Core Qt::Gui Qt::Qml @@ -37,18 +29,14 @@ target_link_libraries(objectlistmodel PUBLIC # Resources: -set(objectlistmodel_resource_files - "view.qml" -) - -qt6_add_resources(objectlistmodel "objectlistmodel" - PREFIX - "/" - FILES - ${objectlistmodel_resource_files} +qt_add_qml_module(objectlistmodelexample + URI objectlistmodel + VERSION 1.0 + QML_FILES + "view.qml" ) -install(TARGETS objectlistmodel +install(TARGETS objectlistmodelexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/quick/models/objectlistmodel/dataobject.cpp b/examples/quick/models/objectlistmodel/dataobject.cpp index 6963d75c42a..354b9d74b4f 100644 --- a/examples/quick/models/objectlistmodel/dataobject.cpp +++ b/examples/quick/models/objectlistmodel/dataobject.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. diff --git a/examples/quick/models/objectlistmodel/main.cpp b/examples/quick/models/objectlistmodel/main.cpp index 8fbe7c183c1..5d406f356c8 100644 --- a/examples/quick/models/objectlistmodel/main.cpp +++ b/examples/quick/models/objectlistmodel/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the demonstration applications of the Qt Toolkit. @@ -49,6 +49,7 @@ ****************************************************************************/ #include +#include #include #include @@ -68,21 +69,36 @@ int main(int argc, char ** argv) { QGuiApplication app(argc, argv); - QList dataList = { - new DataObject("Item 1", "red"), - new DataObject("Item 2", "green"), - new DataObject("Item 3", "blue"), - new DataObject("Item 4", "yellow") - }; + const QStringList colorList = {"red", + "green", + "blue", + "yellow"}; + + const QStringList moduleList = {"Core", "GUI", "Multimedia", "Multimedia Widgets", "Network", + "QML", "Quick", "Quick Controls", "Quick Dialogs", + "Quick Layouts", "Quick Test", "SQL", "Widgets", "3D", + "Android Extras", "Bluetooth", "Concurrent", "D-Bus", + "Gamepad", "Graphical Effects", "Help", "Image Formats", + "Location", "Mac Extras", "NFC", "OpenGL", "Platform Headers", + "Positioning", "Print Support", "Purchasing", "Quick Extras", + "Quick Timeline", "Quick Widgets", "Remote Objects", "Script", + "SCXML", "Script Tools", "Sensors", "Serial Bus", + "Serial Port", "Speech", "SVG", "UI Tools", "WebEngine", + "WebSockets", "WebView", "Windows Extras", "XML", + "XML Patterns", "Charts", "Network Authorization", + "Virtual Keyboard", "Quick 3D", "Quick WebGL"}; + + QList dataList; + for (const QString &module : moduleList) + dataList.append(new DataObject("Qt " + module, colorList.at(rand() % colorList.length()))); QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); view.setInitialProperties({{ "model", QVariant::fromValue(dataList) }}); //![0] - view.setSource(QUrl("qrc:view.qml")); + view.setSource(QUrl("qrc:/objectlistmodel/view.qml")); view.show(); return app.exec(); } - diff --git a/examples/quick/models/objectlistmodel/objectlistmodel.qrc b/examples/quick/models/objectlistmodel/objectlistmodel.qrc index 17e9301471e..a6e8cffb085 100644 --- a/examples/quick/models/objectlistmodel/objectlistmodel.qrc +++ b/examples/quick/models/objectlistmodel/objectlistmodel.qrc @@ -1,5 +1,5 @@ - + view.qml diff --git a/examples/quick/models/objectlistmodel/view.qml b/examples/quick/models/objectlistmodel/view.qml index ba0c905e1e1..4adc8ca84f2 100644 --- a/examples/quick/models/objectlistmodel/view.qml +++ b/examples/quick/models/objectlistmodel/view.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,19 +48,22 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick +import QtQuick.Controls //![0] ListView { - width: 100; height: 100 + id: listview + width: 200; height: 320 required model + ScrollBar.vertical: ScrollBar { } delegate: Rectangle { + width: listview.width; height: 25 + required color required property string name - height: 25 - width: 100 Text { text: parent.name } } } diff --git a/examples/quick/models/stringlistmodel/CMakeLists.txt b/examples/quick/models/stringlistmodel/CMakeLists.txt index acf6be69812..3bfb3ca4bf8 100644 --- a/examples/quick/models/stringlistmodel/CMakeLists.txt +++ b/examples/quick/models/stringlistmodel/CMakeLists.txt @@ -1,13 +1,12 @@ # Generated from stringlistmodel.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(stringlistmodel LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,19 +14,12 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/models/stringlistmodel") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Qml) -find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Core Gui Qml Quick) -qt_add_executable(stringlistmodel +qt_add_executable(stringlistmodelexample WIN32 MACOSX_BUNDLE main.cpp ) -set_target_properties(stringlistmodel PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(stringlistmodel PUBLIC +target_link_libraries(stringlistmodelexample PUBLIC Qt::Core Qt::Gui Qt::Qml @@ -36,18 +28,14 @@ target_link_libraries(stringlistmodel PUBLIC # Resources: -set(stringlistmodel_resource_files - "view.qml" -) - -qt6_add_resources(stringlistmodel "stringlistmodel" - PREFIX - "/" - FILES - ${stringlistmodel_resource_files} +qt_add_qml_module(stringlistmodelexample + URI stringlistmodel + VERSION 1.0 + QML_FILES + "view.qml" ) -install(TARGETS stringlistmodel +install(TARGETS stringlistmodelexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/quick/models/stringlistmodel/main.cpp b/examples/quick/models/stringlistmodel/main.cpp index d9de69b3aa3..f3319d0f3e8 100644 --- a/examples/quick/models/stringlistmodel/main.cpp +++ b/examples/quick/models/stringlistmodel/main.cpp @@ -79,7 +79,7 @@ int main(int argc, char ** argv) view.setInitialProperties({{ "model", QVariant::fromValue(dataList) }}); //![0] - view.setSource(QUrl("qrc:view.qml")); + view.setSource(QUrl("qrc:/stringlistmodel/view.qml")); view.show(); return app.exec(); diff --git a/examples/quick/models/stringlistmodel/stringlistmodel.qrc b/examples/quick/models/stringlistmodel/stringlistmodel.qrc index 17e9301471e..31928f0738c 100644 --- a/examples/quick/models/stringlistmodel/stringlistmodel.qrc +++ b/examples/quick/models/stringlistmodel/stringlistmodel.qrc @@ -1,5 +1,5 @@ - + view.qml diff --git a/examples/quick/mousearea/CMakeLists.txt b/examples/quick/mousearea/CMakeLists.txt index 941f02b6135..ea635462bec 100644 --- a/examples/quick/mousearea/CMakeLists.txt +++ b/examples/quick/mousearea/CMakeLists.txt @@ -1,13 +1,9 @@ -# Generated from mousearea.pro. - -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(mousearea LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,19 +11,12 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/mousearea") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) -qt_add_executable(mousearea +qt_add_executable(mouseareaexample WIN32 MACOSX_BUNDLE main.cpp ) -set_target_properties(mousearea PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(mousearea PUBLIC +target_link_libraries(mouseareaexample PUBLIC Qt::Core Qt::Gui Qt::Qml @@ -36,19 +25,15 @@ target_link_libraries(mousearea PUBLIC # Resources: -set(mousearea_resource_files - "mousearea-wheel-example.qml" - "mousearea.qml" -) - -qt6_add_resources(mousearea "mousearea" - PREFIX - "/mousearea" - FILES - ${mousearea_resource_files} +qt_add_qml_module(mouseareaexample + URI mousearea + VERSION 1.0 + QML_FILES + "mousearea-wheel-example.qml" + "mousearea.qml" ) -install(TARGETS mousearea +install(TARGETS mouseareaexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/quick/mousearea/mousearea-wheel-example.qml b/examples/quick/mousearea/mousearea-wheel-example.qml index 5e8fba3ac33..77893fd57c3 100644 --- a/examples/quick/mousearea/mousearea-wheel-example.qml +++ b/examples/quick/mousearea/mousearea-wheel-example.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick Rectangle { height: 700 diff --git a/examples/quick/mousearea/mousearea.qml b/examples/quick/mousearea/mousearea.qml index ff792f952d5..677b5f384dd 100644 --- a/examples/quick/mousearea/mousearea.qml +++ b/examples/quick/mousearea/mousearea.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.4 +import QtQuick Rectangle { id: box @@ -177,7 +177,7 @@ Rectangle { id: info anchors.bottom: btn.top; anchors.horizontalCenter: parent.horizontalCenter; anchors.margins: 20 - onTextChanged: console.log(text) + onTextChanged: function(text) { console.log(text) } } Text { diff --git a/examples/quick/particles/.prev_CMakeLists.txt b/examples/quick/particles/.prev_CMakeLists.txt deleted file mode 100644 index 1dbf49be211..00000000000 --- a/examples/quick/particles/.prev_CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Generated from particles.pro. - -add_subdirectory(affectors) -add_subdirectory(emitters) -add_subdirectory(imageparticle) -add_subdirectory(itemparticle) -add_subdirectory(system) diff --git a/examples/quick/particles/affectors/CMakeLists.txt b/examples/quick/particles/affectors/CMakeLists.txt index 4766ee11007..94340634291 100644 --- a/examples/quick/particles/affectors/CMakeLists.txt +++ b/examples/quick/particles/affectors/CMakeLists.txt @@ -1,13 +1,10 @@ -# Generated from affectors.pro. - -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(affectors LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,119 +12,61 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/particles/affectors") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) + +add_subdirectory("../../shared" "shared") -qt_add_executable(affectors +qt_add_executable(affectorsexample WIN32 MACOSX_BUNDLE main.cpp ) -set_target_properties(affectors PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(affectors PUBLIC +target_link_libraries(affectorsexample PRIVATE Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(affectorsexample affectors_shared) # Resources: -set(affectors_resource_files - "affectors.qml" - "content/GreyButton.qml" - "content/age.qml" - "content/attractor.qml" - "content/customaffector.qml" - "content/friction.qml" - "content/gravity.qml" - "content/groupgoal.qml" - "content/move.qml" - "content/spritegoal.qml" - "content/turbulence.qml" - "content/wander.qml" -) - -qt6_add_resources(affectors "affectors" - PREFIX - "/particles/affectors" - FILES - ${affectors_resource_files} -) -set(images_resource_files - "../images/_explo.png" - "../images/backgroundLeaves.jpg" - "../images/bear_tiles.png" - "../images/candle.png" - "../images/colortable.png" - "../images/finalfrontier.png" - "../images/flower.png" - "../images/matchmask.png" - "../images/meteor.png" - "../images/meteor_explo.png" - "../images/meteors.png" - "../images/nullRock.png" - "../images/particle2.png" - "../images/particle3.png" - "../images/particleA.png" - "../images/portal_bg.png" - "../images/realLeaf1.png" - "../images/realLeaf2.png" - "../images/realLeaf3.png" - "../images/realLeaf4.png" - "../images/rocket.png" - "../images/rocket2.png" - "../images/sizeInOut.png" - "../images/snowflake.png" - "../images/sparkleSize.png" - "../images/starfish_0.png" - "../images/starfish_1.png" - "../images/starfish_2.png" - "../images/starfish_3.png" - "../images/starfish_4.png" - "../images/starfish_mask.png" +qt_add_qml_module(affectorsexample + URI affectors + VERSION 1.0 + QML_FILES + "affectors.qml" + "GreyButton.qml" + "age.qml" + "attractor.qml" + "customaffector.qml" + "friction.qml" + "gravity.qml" + "groupgoal.qml" + "move.qml" + "spritegoal.qml" + "turbulence.qml" + "wander.qml" + RESOURCES + "images/snowflake.png" + "images/finalfrontier.png" + "images/meteor.png" + "images/rocket.png" + "images/rocket2.png" + "images/backgroundLeaves.jpg" + "images/realLeaf1.png" + "images/realLeaf2.png" + "images/realLeaf3.png" + "images/realLeaf4.png" + "images/particleA.png" + "images/matchmask.png" + "images/nullRock.png" + "images/_explo.png" + "images/candle.png" ) -qt6_add_resources(affectors "images" - PREFIX - "/particles" - BASE - ".." - FILES - ${images_resource_files} -) -set(shared_resource_files - "../../shared/Button.qml" - "../../shared/CheckBox.qml" - "../../shared/FlickrRssModel.qml" - "../../shared/Label.qml" - "../../shared/LauncherList.qml" - "../../shared/SimpleLauncherDelegate.qml" - "../../shared/Slider.qml" - "../../shared/TabSet.qml" - "../../shared/TextField.qml" - "../../shared/images/back.png" - "../../shared/images/checkmark.png" - "../../shared/images/next.png" - "../../shared/images/qt-logo.png" - "../../shared/images/slider_handle.png" - "../../shared/images/tab.png" -) - -qt6_add_resources(affectors "shared" - PREFIX - "/shared" - BASE - "../../shared" - FILES - ${shared_resource_files} -) - -install(TARGETS affectors +install(TARGETS affectorsexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) + +bundle_shared(affectorsexample) diff --git a/examples/quick/particles/affectors/content/GreyButton.qml b/examples/quick/particles/affectors/GreyButton.qml similarity index 100% rename from examples/quick/particles/affectors/content/GreyButton.qml rename to examples/quick/particles/affectors/GreyButton.qml diff --git a/examples/quick/particles/affectors/affectors.pro b/examples/quick/particles/affectors/affectors.pro index 673ccfbb815..fc049c21b03 100644 --- a/examples/quick/particles/affectors/affectors.pro +++ b/examples/quick/particles/affectors/affectors.pro @@ -4,7 +4,6 @@ QT += quick qml SOURCES += main.cpp RESOURCES += \ affectors.qrc \ - ../images.qrc \ ../../shared/shared.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/particles/affectors diff --git a/examples/quick/particles/affectors/affectors.qml b/examples/quick/particles/affectors/affectors.qml index 81240fed9ba..9fa067713e2 100644 --- a/examples/quick/particles/affectors/affectors.qml +++ b/examples/quick/particles/affectors/affectors.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,26 +48,26 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "../../shared" as Examples +import QtQuick +import shared Item { height: 480 width: 320 - Examples.LauncherList { + LauncherList { id: ll anchors.fill: parent Component.onCompleted: { - addExample("Age", "Kills off particles that enter the affector", Qt.resolvedUrl("content/age.qml")); - addExample("Attractor", "Simulates a small black hole", Qt.resolvedUrl("content/attractor.qml")); - addExample("Custom Affector", "Custom falling leaves", Qt.resolvedUrl("content/customaffector.qml")); - addExample("Friction", "Leaves that slow down as they fall", Qt.resolvedUrl("content/friction.qml")); - addExample("Gravity", "Leaves that fall towards the earth as you move it", Qt.resolvedUrl("content/gravity.qml")); - addExample("GroupGoal", "Balls that can be set on fire various ways", Qt.resolvedUrl("content/groupgoal.qml")); - addExample("Move", "Some effects you can get by altering trajectory midway", Qt.resolvedUrl("content/move.qml")); - addExample("SpriteGoal", "A ship that makes asteroids explode", Qt.resolvedUrl("content/spritegoal.qml")); - addExample("Turbulence", "A candle with faint wind", Qt.resolvedUrl("content/turbulence.qml")); - addExample("Wander", "Drifting snow flakes", Qt.resolvedUrl("content/wander.qml")); + addExample("Age", "Kills off particles that enter the affector", Qt.resolvedUrl("age.qml")); + addExample("Attractor", "Simulates a small black hole", Qt.resolvedUrl("attractor.qml")); + addExample("Custom Affector", "Custom falling leaves", Qt.resolvedUrl("customaffector.qml")); + addExample("Friction", "Leaves that slow down as they fall", Qt.resolvedUrl("friction.qml")); + addExample("Gravity", "Leaves that fall towards the earth as you move it", Qt.resolvedUrl("gravity.qml")); + addExample("GroupGoal", "Balls that can be set on fire various ways", Qt.resolvedUrl("groupgoal.qml")); + addExample("Move", "Some effects you can get by altering trajectory midway", Qt.resolvedUrl("move.qml")); + addExample("SpriteGoal", "A ship that makes asteroids explode", Qt.resolvedUrl("spritegoal.qml")); + addExample("Turbulence", "A candle with faint wind", Qt.resolvedUrl("turbulence.qml")); + addExample("Wander", "Drifting snow flakes", Qt.resolvedUrl("wander.qml")); } } } diff --git a/examples/quick/particles/affectors/affectors.qrc b/examples/quick/particles/affectors/affectors.qrc index c1d797e4d81..e26bf0b1734 100644 --- a/examples/quick/particles/affectors/affectors.qrc +++ b/examples/quick/particles/affectors/affectors.qrc @@ -1,16 +1,31 @@ - + affectors.qml - content/age.qml - content/attractor.qml - content/customaffector.qml - content/friction.qml - content/gravity.qml - content/GreyButton.qml - content/groupgoal.qml - content/move.qml - content/spritegoal.qml - content/turbulence.qml - content/wander.qml + age.qml + attractor.qml + customaffector.qml + friction.qml + gravity.qml + GreyButton.qml + groupgoal.qml + move.qml + spritegoal.qml + turbulence.qml + wander.qml + images/snowflake.png + images/finalfrontier.png + images/meteor.png + images/rocket.png + images/rocket2.png + images/backgroundLeaves.jpg + images/realLeaf1.png + images/realLeaf2.png + images/realLeaf3.png + images/realLeaf4.png + images/particleA.png + images/matchmask.png + images/nullRock.png + images/_explo.png + images/candle.png diff --git a/examples/quick/particles/affectors/content/age.qml b/examples/quick/particles/affectors/age.qml similarity index 96% rename from examples/quick/particles/affectors/content/age.qml rename to examples/quick/particles/affectors/age.qml index ff5114a596e..a7875635068 100644 --- a/examples/quick/particles/affectors/content/age.qml +++ b/examples/quick/particles/affectors/age.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { id: root @@ -63,7 +63,7 @@ Rectangle { system: particles sprites: Sprite { name: "snow" - source: "../../images/snowflake.png" + source: "images/snowflake.png" frameCount: 51 frameDuration: 40 frameDurationVariation: 8 diff --git a/examples/quick/particles/affectors/content/attractor.qml b/examples/quick/particles/affectors/attractor.qml similarity index 96% rename from examples/quick/particles/affectors/content/attractor.qml rename to examples/quick/particles/affectors/attractor.qml index 7fbb6069b22..41055e3629d 100644 --- a/examples/quick/particles/affectors/content/attractor.qml +++ b/examples/quick/particles/affectors/attractor.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { id: root @@ -57,7 +57,7 @@ Rectangle { height: 540 color: "black" Image { - source: "../../images/finalfrontier.png" + source: "images/finalfrontier.png" anchors.centerIn:parent } ParticleSystem { @@ -98,7 +98,7 @@ Rectangle { sprites: Sprite { id: spinState name: "spinning" - source: "../../images/meteor.png" + source: "images/meteor.png" frameCount: 35 frameDuration: 60 } @@ -156,7 +156,7 @@ Rectangle { } Image { - source:"../../images/rocket2.png" + source:"images/rocket2.png" id: ship width: 45 height: 22 diff --git a/examples/quick/particles/affectors/content/customaffector.qml b/examples/quick/particles/affectors/customaffector.qml similarity index 92% rename from examples/quick/particles/affectors/content/customaffector.qml rename to examples/quick/particles/affectors/customaffector.qml index 76fc4dc3021..ea26b2de848 100644 --- a/examples/quick/particles/affectors/content/customaffector.qml +++ b/examples/quick/particles/affectors/customaffector.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,15 +48,15 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Item { width: 360 height: 600 Image { - source: "../../images/backgroundLeaves.jpg" + source: "images/backgroundLeaves.jpg" anchors.fill: parent } ParticleSystem { @@ -120,31 +120,31 @@ Item { anchors.fill: parent id: particles sprites: [Sprite { - source: "../../images/realLeaf1.png" + source: "images/realLeaf1.png" frameCount: 1 frameDuration: 1 to: {"a":1, "b":1, "c":1, "d":1} }, Sprite { name: "a" - source: "../../images/realLeaf1.png" + source: "images/realLeaf1.png" frameCount: 1 frameDuration: 10000 }, Sprite { name: "b" - source: "../../images/realLeaf2.png" + source: "images/realLeaf2.png" frameCount: 1 frameDuration: 10000 }, Sprite { name: "c" - source: "../../images/realLeaf3.png" + source: "images/realLeaf3.png" frameCount: 1 frameDuration: 10000 }, Sprite { name: "d" - source: "../../images/realLeaf4.png" + source: "images/realLeaf4.png" frameCount: 1 frameDuration: 10000 } diff --git a/examples/quick/particles/affectors/doc/src/affectors.qdoc b/examples/quick/particles/affectors/doc/src/affectors.qdoc index 9857a86241e..c3469fd957d 100644 --- a/examples/quick/particles/affectors/doc/src/affectors.qdoc +++ b/examples/quick/particles/affectors/doc/src/affectors.qdoc @@ -35,7 +35,7 @@ Each example is a small QML file emphasizing a particular type or feature. Age demonstrates using an Age affector to prematurely end the lives of particles. - \snippet particles/affectors/content/age.qml 0 + \snippet particles/affectors/age.qml 0 As you move the affector around the screen, the particles inside it (which haven't already been affected) jump to a period near the end @@ -44,7 +44,7 @@ the end of their life instantly. Attractor demonstrates using an Attractor affector to simulate a black hole - \snippet particles/affectors/content/attractor.qml 0 + \snippet particles/affectors/attractor.qml 0 All particles in the scene, including the rocket ship's exhaust and pellets, are pulled towards the black hole. This effect is stronger closer to the black hole, so the @@ -55,58 +55,58 @@ Custom Affector manipulates the properties of the particles directly in javascript. One Affector is used to make the leaves rock back and forth as they fall, looking more leaf-like than just spinning in circles: - \snippet particles/affectors/content/customaffector.qml 0 + \snippet particles/affectors/customaffector.qml 0 Another is used to provide a slightly varying friction to the leaves as they 'land', to look more natural: - \snippet particles/affectors/content/customaffector.qml 1 + \snippet particles/affectors/customaffector.qml 1 Friction is similar to the falling leaves in the custom affector, except that it uses a flat friction the whole way down instead of custom affectors. - \snippet particles/affectors/content/friction.qml 0 + \snippet particles/affectors/friction.qml 0 Gravity is a convenience affector for applying a constant acceleration to particles inside it - \snippet particles/affectors/content/gravity.qml 0 + \snippet particles/affectors/gravity.qml 0 GroupGoal sets up two particle groups for flaming and non-flaming balls, and gives you various ways to transition between them. - \snippet particles/affectors/content/groupgoal.qml unlit + \snippet particles/affectors/groupgoal.qml unlit The non-flaming balls have a one in a hundred chance of lighting on their own each second, but they also have a GroupGoal set on the whole group. This affector affects all particles of the unlit group, when colliding with particles in the lit group, and cause them to move to the lighting group. - \snippet particles/affectors/content/groupgoal.qml lighting + \snippet particles/affectors/groupgoal.qml lighting lighting is an intermediate group so that the glow builds up and the transition is less jarring. So it automatically moves into the lit group after 100ms. - \snippet particles/affectors/content/groupgoal.qml lit + \snippet particles/affectors/groupgoal.qml lit The lit group also has TrailEmitters on it for additional fire and smoke, but does not transition anywhere. There are two more GroupGoal objects that allow particles in the unlit group to transition to the lighting group (and then to the lit group). - \snippet particles/affectors/content/groupgoal.qml groupgoal-pilot + \snippet particles/affectors/groupgoal.qml groupgoal-pilot The first is just an area bound to the location of an image of a pilot flame. When unlit balls pass through the flame, they go straight to lit because the pilot flame is so hot. - \snippet particles/affectors/content/groupgoal.qml groupgoal-ma + \snippet particles/affectors/groupgoal.qml groupgoal-ma The second is bound to the location of the last pointer interaction, so that touching or clicking on unlit balls (which is hard due to their constant movement) causes them to move to the lighting group. Move shows some simple effects you can get by altering trajectory midway. The red particles have an affector that affects their position, jumping them forwards by 120px. - \snippet particles/affectors/content/move.qml A + \snippet particles/affectors/move.qml A The green particles have an affector that affects their velocity, but with some angle variation. By adding some random direction velocity to their existing forwards velocity, they begin to spray off in a cone. - \snippet particles/affectors/content/move.qml B + \snippet particles/affectors/move.qml B The blue particles have an affector that affects their acceleration, and because it sets relative to false this resets the acceleration instead of adding to it. Once the blue particles reach the affector, their horizontal velocity stops increasing as their vertical velocity decreases. - \snippet particles/affectors/content/move.qml C + \snippet particles/affectors/move.qml C SpriteGoal has an affector which interacts with the sprite engine of particles, if they are being drawn as sprites by ImageParticle. - \snippet particles/affectors/content/spritegoal.qml 0 + \snippet particles/affectors/spritegoal.qml 0 The SpriteGoal follows the image of the rocket ship on screen, and when it interacts with particles drawn by ImageParticle as sprites, it instructs them to move immediately to the "explode" state, which in this case is the animation of the asteroid breaking into many pieces. Turbulence has a flame with smoke, and both sets of particles being affected by a Turbulence affector. This gives a faint wind effect. - \snippet particles/affectors/content/turbulence.qml 0 + \snippet particles/affectors/turbulence.qml 0 To make the wind change direction, subsitute a black and white noise image in the noiseSource parameter (it currently uses a default noise source). Wander uses a Wander affector to add some horizontal drift to snowflakes as they fall down. - \snippet particles/affectors/content/wander.qml 0 + \snippet particles/affectors/wander.qml 0 There are different movements given by applying the Wander to different attributes of the trajectory, so the example makes it easy to play around and see the difference. */ diff --git a/examples/quick/particles/affectors/content/friction.qml b/examples/quick/particles/affectors/friction.qml similarity index 90% rename from examples/quick/particles/affectors/content/friction.qml rename to examples/quick/particles/affectors/friction.qml index 1fa85ec2fe5..aa2d1c72d79 100644 --- a/examples/quick/particles/affectors/content/friction.qml +++ b/examples/quick/particles/affectors/friction.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,15 +48,15 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Item { width: 360 height: 600 Image { - source: "../../images/backgroundLeaves.jpg" + source: "images/backgroundLeaves.jpg" anchors.fill: parent } ParticleSystem { @@ -73,31 +73,31 @@ Item { anchors.fill: parent id: particles sprites: [Sprite { - source: "../../images/realLeaf1.png" + source: "images/realLeaf1.png" frameCount: 1 frameDuration: 1 to: {"a":1, "b":1, "c":1, "d":1} }, Sprite { name: "a" - source: "../../images/realLeaf1.png" + source: "images/realLeaf1.png" frameCount: 1 frameDuration: 10000 }, Sprite { name: "b" - source: "../../images/realLeaf2.png" + source: "images/realLeaf2.png" frameCount: 1 frameDuration: 10000 }, Sprite { name: "c" - source: "../../images/realLeaf3.png" + source: "images/realLeaf3.png" frameCount: 1 frameDuration: 10000 }, Sprite { name: "d" - source: "../../images/realLeaf4.png" + source: "images/realLeaf4.png" frameCount: 1 frameDuration: 10000 } diff --git a/examples/quick/particles/affectors/content/gravity.qml b/examples/quick/particles/affectors/gravity.qml similarity index 96% rename from examples/quick/particles/affectors/content/gravity.qml rename to examples/quick/particles/affectors/gravity.qml index 99b14f3b1fa..cf517ae3198 100644 --- a/examples/quick/particles/affectors/content/gravity.qml +++ b/examples/quick/particles/affectors/gravity.qml @@ -1,6 +1,6 @@ /**************************************************************************** * -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Item { id: window @@ -109,7 +109,7 @@ Item { ImageParticle { anchors.fill: parent system: sys - source: "../../images/realLeaf1.png" + source: "images/realLeaf1.png" } } diff --git a/examples/quick/particles/affectors/content/groupgoal.qml b/examples/quick/particles/affectors/groupgoal.qml similarity index 96% rename from examples/quick/particles/affectors/content/groupgoal.qml rename to examples/quick/particles/affectors/groupgoal.qml index 9910531a980..27c910e69a5 100644 --- a/examples/quick/particles/affectors/content/groupgoal.qml +++ b/examples/quick/particles/affectors/groupgoal.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { @@ -74,7 +74,7 @@ Rectangle { duration: 1000 to: {"lighting":1, "unlit":99} ImageParticle { - source: "../../images/particleA.png" + source: "images/particleA.png" colorVariation: 0.1 color: "#2060160f" } @@ -151,7 +151,7 @@ Rectangle { id: flame anchors.fill: parent groups: ["flame", "lit", "lighting"] - source: "../../images/particleA.png" + source: "images/particleA.png" colorVariation: 0.1 color: "#00ff400f" } @@ -188,7 +188,7 @@ Rectangle { y: -55 height: 75 width: 30 - shape: MaskShape {source: "../../images/matchmask.png"} + shape: MaskShape {source: "images/matchmask.png"} } // ![groupgoal-pilot] } diff --git a/examples/quick/particles/images/_explo.png b/examples/quick/particles/affectors/images/_explo.png similarity index 100% rename from examples/quick/particles/images/_explo.png rename to examples/quick/particles/affectors/images/_explo.png diff --git a/examples/quick/particles/images/backgroundLeaves.jpg b/examples/quick/particles/affectors/images/backgroundLeaves.jpg similarity index 100% rename from examples/quick/particles/images/backgroundLeaves.jpg rename to examples/quick/particles/affectors/images/backgroundLeaves.jpg diff --git a/examples/quick/particles/images/candle.png b/examples/quick/particles/affectors/images/candle.png similarity index 100% rename from examples/quick/particles/images/candle.png rename to examples/quick/particles/affectors/images/candle.png diff --git a/examples/quick/particles/images/finalfrontier.png b/examples/quick/particles/affectors/images/finalfrontier.png similarity index 100% rename from examples/quick/particles/images/finalfrontier.png rename to examples/quick/particles/affectors/images/finalfrontier.png diff --git a/examples/quick/particles/images/matchmask.png b/examples/quick/particles/affectors/images/matchmask.png similarity index 100% rename from examples/quick/particles/images/matchmask.png rename to examples/quick/particles/affectors/images/matchmask.png diff --git a/examples/quick/particles/images/meteor.png b/examples/quick/particles/affectors/images/meteor.png similarity index 100% rename from examples/quick/particles/images/meteor.png rename to examples/quick/particles/affectors/images/meteor.png diff --git a/examples/quick/particles/images/nullRock.png b/examples/quick/particles/affectors/images/nullRock.png similarity index 100% rename from examples/quick/particles/images/nullRock.png rename to examples/quick/particles/affectors/images/nullRock.png diff --git a/examples/quick/particles/images/particleA.png b/examples/quick/particles/affectors/images/particleA.png similarity index 100% rename from examples/quick/particles/images/particleA.png rename to examples/quick/particles/affectors/images/particleA.png diff --git a/examples/quick/particles/images/realLeaf1.png b/examples/quick/particles/affectors/images/realLeaf1.png similarity index 100% rename from examples/quick/particles/images/realLeaf1.png rename to examples/quick/particles/affectors/images/realLeaf1.png diff --git a/examples/quick/particles/images/realLeaf2.png b/examples/quick/particles/affectors/images/realLeaf2.png similarity index 100% rename from examples/quick/particles/images/realLeaf2.png rename to examples/quick/particles/affectors/images/realLeaf2.png diff --git a/examples/quick/particles/images/realLeaf3.png b/examples/quick/particles/affectors/images/realLeaf3.png similarity index 100% rename from examples/quick/particles/images/realLeaf3.png rename to examples/quick/particles/affectors/images/realLeaf3.png diff --git a/examples/quick/particles/images/realLeaf4.png b/examples/quick/particles/affectors/images/realLeaf4.png similarity index 100% rename from examples/quick/particles/images/realLeaf4.png rename to examples/quick/particles/affectors/images/realLeaf4.png diff --git a/examples/quick/particles/images/rocket.png b/examples/quick/particles/affectors/images/rocket.png similarity index 100% rename from examples/quick/particles/images/rocket.png rename to examples/quick/particles/affectors/images/rocket.png diff --git a/examples/quick/particles/images/rocket2.png b/examples/quick/particles/affectors/images/rocket2.png similarity index 100% rename from examples/quick/particles/images/rocket2.png rename to examples/quick/particles/affectors/images/rocket2.png diff --git a/examples/quick/particles/images/snowflake.png b/examples/quick/particles/affectors/images/snowflake.png similarity index 100% rename from examples/quick/particles/images/snowflake.png rename to examples/quick/particles/affectors/images/snowflake.png diff --git a/examples/quick/particles/affectors/main.cpp b/examples/quick/particles/affectors/main.cpp index 9e902170005..854f1d92a86 100644 --- a/examples/quick/particles/affectors/main.cpp +++ b/examples/quick/particles/affectors/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(particles/affectors/affectors) +DECLARATIVE_EXAMPLE_MAIN(affectors/affectors) diff --git a/examples/quick/particles/affectors/content/move.qml b/examples/quick/particles/affectors/move.qml similarity index 100% rename from examples/quick/particles/affectors/content/move.qml rename to examples/quick/particles/affectors/move.qml diff --git a/examples/quick/particles/affectors/content/spritegoal.qml b/examples/quick/particles/affectors/spritegoal.qml similarity index 95% rename from examples/quick/particles/affectors/content/spritegoal.qml rename to examples/quick/particles/affectors/spritegoal.qml index 294f6932217..1ba7b46dd6d 100644 --- a/examples/quick/particles/affectors/content/spritegoal.qml +++ b/examples/quick/particles/affectors/spritegoal.qml @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Item { id: root @@ -62,7 +62,7 @@ Item { ParticleSystem { id: sys } Image { - source: "../../images/finalfrontier.png" + source: "images/finalfrontier.png" transformOrigin: Item.Center anchors.centerIn: parent NumberAnimation on rotation { @@ -113,20 +113,20 @@ Item { sprites:[Sprite { id: spinState name: "spinning" - source: "../../images/meteor.png" + source: "images/meteor.png" frameCount: 35 frameDuration: 40 randomStart: true to: {"explode":0, "spinning":1} },Sprite { name: "explode" - source: "../../images/_explo.png" + source: "images/_explo.png" frameCount: 22 frameDuration: 40 to: {"nullFrame":1} },Sprite {//Not sure if this is needed, but seemed easiest name: "nullFrame" - source: "../../images/nullRock.png" + source: "images/nullRock.png" frameCount: 1 frameDuration: 1000 } @@ -145,7 +145,7 @@ Item { //! [0] Image { id: rocketShip - source: "../../images/rocket.png" + source: "images/rocket.png" anchors.centerIn: holder rotation: (circle.percent+0.25) * 360 z: 2 diff --git a/examples/quick/particles/affectors/content/turbulence.qml b/examples/quick/particles/affectors/turbulence.qml similarity index 98% rename from examples/quick/particles/affectors/content/turbulence.qml rename to examples/quick/particles/affectors/turbulence.qml index e58b3ede7f8..83c2b1744f6 100644 --- a/examples/quick/particles/affectors/content/turbulence.qml +++ b/examples/quick/particles/affectors/turbulence.qml @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { width: 320 @@ -57,7 +57,7 @@ Rectangle { color: "#222222" id: root Image { - source: "../../images/candle.png" + source: "images/candle.png" anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter anchors.bottomMargin: -60 diff --git a/examples/quick/particles/affectors/content/wander.qml b/examples/quick/particles/affectors/wander.qml similarity index 97% rename from examples/quick/particles/affectors/content/wander.qml rename to examples/quick/particles/affectors/wander.qml index 736fc1af766..613298eb4f6 100644 --- a/examples/quick/particles/affectors/content/wander.qml +++ b/examples/quick/particles/affectors/wander.qml @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { width: 360 @@ -59,7 +59,7 @@ Rectangle { system: particles sprites: Sprite { name: "snow" - source: "../../images/snowflake.png" + source: "images/snowflake.png" frameCount: 51 frameDuration: 40 frameDurationVariation: 8 diff --git a/examples/quick/particles/emitters/CMakeLists.txt b/examples/quick/particles/emitters/CMakeLists.txt index 37295148fad..bf68c59cf51 100644 --- a/examples/quick/particles/emitters/CMakeLists.txt +++ b/examples/quick/particles/emitters/CMakeLists.txt @@ -1,13 +1,10 @@ -# Generated from emitters.pro. - -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(emitters LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,115 +12,44 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/particles/emitters") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) + +add_subdirectory("../../shared" "shared") -qt_add_executable(emitters +qt_add_executable(emittersexample WIN32 MACOSX_BUNDLE main.cpp ) -set_target_properties(emitters PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(emitters PUBLIC +target_link_libraries(emittersexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(emittersexample emitters_shared) # Resources: -set(emitters_resource_files - "content/burstandpulse.qml" - "content/customemitter.qml" - "content/emitmask.qml" - "content/maximumemitted.qml" - "content/shapeanddirection.qml" - "content/trailemitter.qml" - "content/velocityfrommotion.qml" - "emitters.qml" -) - -qt6_add_resources(emitters "emitters" - PREFIX - "/particles/emitters" - FILES - ${emitters_resource_files} -) -set(images_resource_files - "../images/_explo.png" - "../images/backgroundLeaves.jpg" - "../images/bear_tiles.png" - "../images/candle.png" - "../images/colortable.png" - "../images/finalfrontier.png" - "../images/flower.png" - "../images/matchmask.png" - "../images/meteor.png" - "../images/meteor_explo.png" - "../images/meteors.png" - "../images/nullRock.png" - "../images/particle2.png" - "../images/particle3.png" - "../images/particleA.png" - "../images/portal_bg.png" - "../images/realLeaf1.png" - "../images/realLeaf2.png" - "../images/realLeaf3.png" - "../images/realLeaf4.png" - "../images/rocket.png" - "../images/rocket2.png" - "../images/sizeInOut.png" - "../images/snowflake.png" - "../images/sparkleSize.png" - "../images/starfish_0.png" - "../images/starfish_1.png" - "../images/starfish_2.png" - "../images/starfish_3.png" - "../images/starfish_4.png" - "../images/starfish_mask.png" -) - -qt6_add_resources(emitters "images" - PREFIX - "/particles" - BASE - ".." - FILES - ${images_resource_files} -) -set(shared_resource_files - "../../shared/Button.qml" - "../../shared/CheckBox.qml" - "../../shared/FlickrRssModel.qml" - "../../shared/Label.qml" - "../../shared/LauncherList.qml" - "../../shared/SimpleLauncherDelegate.qml" - "../../shared/Slider.qml" - "../../shared/TabSet.qml" - "../../shared/TextField.qml" - "../../shared/images/back.png" - "../../shared/images/checkmark.png" - "../../shared/images/next.png" - "../../shared/images/qt-logo.png" - "../../shared/images/slider_handle.png" - "../../shared/images/tab.png" -) - -qt6_add_resources(emitters "shared" - PREFIX - "/shared" - BASE - "../../shared" - FILES - ${shared_resource_files} -) - -install(TARGETS emitters +qt_add_qml_module(emittersexample + URI emitters + VERSION 1.0 + QML_FILES + "burstandpulse.qml" + "customemitter.qml" + "emitmask.qml" + "maximumemitted.qml" + "shapeanddirection.qml" + "trailemitter.qml" + "velocityfrommotion.qml" + "emitters.qml" + RESOURCES + "images/portal_bg.png" + "images/starfish_mask.png" +) + +install(TARGETS emittersexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) + +bundle_shared(emittersexample) diff --git a/examples/quick/particles/emitters/content/burstandpulse.qml b/examples/quick/particles/emitters/burstandpulse.qml similarity index 100% rename from examples/quick/particles/emitters/content/burstandpulse.qml rename to examples/quick/particles/emitters/burstandpulse.qml diff --git a/examples/quick/particles/emitters/content/customemitter.qml b/examples/quick/particles/emitters/customemitter.qml similarity index 100% rename from examples/quick/particles/emitters/content/customemitter.qml rename to examples/quick/particles/emitters/customemitter.qml diff --git a/examples/quick/particles/emitters/doc/src/emitters.qdoc b/examples/quick/particles/emitters/doc/src/emitters.qdoc index 2ba7ceb0b9a..a00ae280b89 100644 --- a/examples/quick/particles/emitters/doc/src/emitters.qdoc +++ b/examples/quick/particles/emitters/doc/src/emitters.qdoc @@ -34,27 +34,27 @@ Each example is a small QML file emphasizing a particular type or feature. Velocity from motion gives the effect of strong particle motion through primarily moving the emitters: - \snippet particles/emitters/content/velocityfrommotion.qml 0 + \snippet particles/emitters/velocityfrommotion.qml 0 Burst and pulse calls the burst and pulse methods on two idential emitters. - \snippet particles/emitters/content/burstandpulse.qml 0 + \snippet particles/emitters/burstandpulse.qml 0 Note how burst takes an argument of number of particles to emit, and pulse takes an argument of number of milliseconds to emit for. This gives a slightly different behaviour, which is easy to see in this example. Custom Emitter connects to the emitParticles signal to set arbitrary values on particle data as they're emitted; - \snippet particles/emitters/content/customemitter.qml 0 + \snippet particles/emitters/customemitter.qml 0 This is used to emit curving particles in six rotating spokes. Emit mask sets an image mask on the Emitter, to emit out of an arbitrary shape. - \snippet particles/emitters/content/emitmask.qml 0 + \snippet particles/emitters/emitmask.qml 0 Maximum emitted emits no more than a certain number of particles at a time. This example makes it easy to see what happens when the limit is reached. Shape and Direction emits particles out of an unfilled Ellipse shape, using a TargetDirection - \snippet particles/emitters/content/shapeanddirection.qml 0 + \snippet particles/emitters/shapeanddirection.qml 0 This sends the particles towards the center of the ellipse with proportional speed, keeping the ellipse outline as they move to the center. TrailEmitter uses that type to add smoke particles to trail the fire particles in the scene. - \snippet particles/emitters/content/customemitter.qml 0 + \snippet particles/emitters/customemitter.qml 0 */ diff --git a/examples/quick/particles/emitters/content/emitmask.qml b/examples/quick/particles/emitters/emitmask.qml similarity index 98% rename from examples/quick/particles/emitters/content/emitmask.qml rename to examples/quick/particles/emitters/emitmask.qml index db13480e295..00fe9e63100 100644 --- a/examples/quick/particles/emitters/content/emitmask.qml +++ b/examples/quick/particles/emitters/emitmask.qml @@ -75,7 +75,7 @@ Rectangle { size: 10 //! [0] shape: MaskShape { - source: "../../images/starfish_mask.png" + source: "images/starfish_mask.png" } //! [0] } diff --git a/examples/quick/particles/emitters/emitters.pro b/examples/quick/particles/emitters/emitters.pro index c5d8b8b0c96..e493bc6a729 100644 --- a/examples/quick/particles/emitters/emitters.pro +++ b/examples/quick/particles/emitters/emitters.pro @@ -4,7 +4,6 @@ QT += quick qml SOURCES += main.cpp RESOURCES += \ emitters.qrc \ - ../images.qrc \ ../../shared/shared.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/particles/emitters diff --git a/examples/quick/particles/emitters/emitters.qml b/examples/quick/particles/emitters/emitters.qml index 83b9eacc7c5..c884ec23419 100644 --- a/examples/quick/particles/emitters/emitters.qml +++ b/examples/quick/particles/emitters/emitters.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,23 +48,23 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "../../shared" as Examples +import QtQuick +import shared Item { height: 480 width: 320 - Examples.LauncherList { + LauncherList { id: ll anchors.fill: parent Component.onCompleted: { - addExample("Velocity from Motion", "Particle motion just by moving emitters", Qt.resolvedUrl("content/velocityfrommotion.qml")); - addExample("Burst and Pulse", "Emit imperatively", Qt.resolvedUrl("content/burstandpulse.qml")); - addExample("Custom Emitter", "Custom starting state", Qt.resolvedUrl("content/customemitter.qml")); - addExample("Emit Mask", "Emit arbitrary shapes", Qt.resolvedUrl("content/emitmask.qml")); - addExample("Maximum Emitted", "Put a limit on emissions", Qt.resolvedUrl("content/maximumemitted.qml")); - addExample("Shape and Direction", "Creates a portal effect", Qt.resolvedUrl("content/shapeanddirection.qml")); - addExample("TrailEmitter", "Emit from other particles", Qt.resolvedUrl("content/trailemitter.qml")); + addExample("Velocity from Motion", "Particle motion just by moving emitters", Qt.resolvedUrl("velocityfrommotion.qml")); + addExample("Burst and Pulse", "Emit imperatively", Qt.resolvedUrl("burstandpulse.qml")); + addExample("Custom Emitter", "Custom starting state", Qt.resolvedUrl("customemitter.qml")); + addExample("Emit Mask", "Emit arbitrary shapes", Qt.resolvedUrl("emitmask.qml")); + addExample("Maximum Emitted", "Put a limit on emissions", Qt.resolvedUrl("maximumemitted.qml")); + addExample("Shape and Direction", "Creates a portal effect", Qt.resolvedUrl("shapeanddirection.qml")); + addExample("TrailEmitter", "Emit from other particles", Qt.resolvedUrl("trailemitter.qml")); } } } diff --git a/examples/quick/particles/emitters/emitters.qrc b/examples/quick/particles/emitters/emitters.qrc index 708c8683f09..5eaf30cb04f 100644 --- a/examples/quick/particles/emitters/emitters.qrc +++ b/examples/quick/particles/emitters/emitters.qrc @@ -1,12 +1,14 @@ - + emitters.qml - content/burstandpulse.qml - content/customemitter.qml - content/emitmask.qml - content/maximumemitted.qml - content/shapeanddirection.qml - content/trailemitter.qml - content/velocityfrommotion.qml + burstandpulse.qml + customemitter.qml + emitmask.qml + maximumemitted.qml + shapeanddirection.qml + trailemitter.qml + velocityfrommotion.qml + images/starfish_mask.png + images/portal_bg.png diff --git a/examples/quick/particles/images/portal_bg.png b/examples/quick/particles/emitters/images/portal_bg.png similarity index 100% rename from examples/quick/particles/images/portal_bg.png rename to examples/quick/particles/emitters/images/portal_bg.png diff --git a/examples/quick/particles/images/starfish_mask.png b/examples/quick/particles/emitters/images/starfish_mask.png similarity index 100% rename from examples/quick/particles/images/starfish_mask.png rename to examples/quick/particles/emitters/images/starfish_mask.png diff --git a/examples/quick/particles/emitters/main.cpp b/examples/quick/particles/emitters/main.cpp index e2b3cf20269..1d35645e636 100644 --- a/examples/quick/particles/emitters/main.cpp +++ b/examples/quick/particles/emitters/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(particles/emitters/emitters) +DECLARATIVE_EXAMPLE_MAIN(emitters/emitters) diff --git a/examples/quick/particles/emitters/content/maximumemitted.qml b/examples/quick/particles/emitters/maximumemitted.qml similarity index 100% rename from examples/quick/particles/emitters/content/maximumemitted.qml rename to examples/quick/particles/emitters/maximumemitted.qml diff --git a/examples/quick/particles/emitters/content/shapeanddirection.qml b/examples/quick/particles/emitters/shapeanddirection.qml similarity index 98% rename from examples/quick/particles/emitters/content/shapeanddirection.qml rename to examples/quick/particles/emitters/shapeanddirection.qml index 8d1659b099e..cffec4196b4 100644 --- a/examples/quick/particles/emitters/content/shapeanddirection.qml +++ b/examples/quick/particles/emitters/shapeanddirection.qml @@ -58,7 +58,7 @@ Rectangle { color: "black" Image { anchors.fill: parent - source: "../../images/portal_bg.png" + source: "images/portal_bg.png" } ParticleSystem { diff --git a/examples/quick/particles/emitters/content/trailemitter.qml b/examples/quick/particles/emitters/trailemitter.qml similarity index 100% rename from examples/quick/particles/emitters/content/trailemitter.qml rename to examples/quick/particles/emitters/trailemitter.qml diff --git a/examples/quick/particles/emitters/content/velocityfrommotion.qml b/examples/quick/particles/emitters/velocityfrommotion.qml similarity index 100% rename from examples/quick/particles/emitters/content/velocityfrommotion.qml rename to examples/quick/particles/emitters/velocityfrommotion.qml diff --git a/examples/quick/particles/imageparticle/CMakeLists.txt b/examples/quick/particles/imageparticle/CMakeLists.txt index 2bc34b35322..387c5bdd415 100644 --- a/examples/quick/particles/imageparticle/CMakeLists.txt +++ b/examples/quick/particles/imageparticle/CMakeLists.txt @@ -1,13 +1,10 @@ -# Generated from imageparticle.pro. - -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(imageparticle LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,115 +12,50 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/particles/imageparticle") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) + +add_subdirectory("../../shared" "shared") -qt_add_executable(imageparticle +qt_add_executable(imageparticleexample WIN32 MACOSX_BUNDLE main.cpp ) -set_target_properties(imageparticle PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(imageparticle PUBLIC +target_link_libraries(imageparticleexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(imageparticleexample imageparticle_shared) # Resources: -set(imageparticle_resource_files - "content/allatonce.qml" - "content/colored.qml" - "content/colortable.qml" - "content/deformation.qml" - "content/rotation.qml" - "content/sharing.qml" - "content/sprites.qml" - "imageparticle.qml" -) - -qt6_add_resources(imageparticle "imageparticle" - PREFIX - "/particles/imageparticle" - FILES - ${imageparticle_resource_files} -) -set(images_resource_files - "../images/_explo.png" - "../images/backgroundLeaves.jpg" - "../images/bear_tiles.png" - "../images/candle.png" - "../images/colortable.png" - "../images/finalfrontier.png" - "../images/flower.png" - "../images/matchmask.png" - "../images/meteor.png" - "../images/meteor_explo.png" - "../images/meteors.png" - "../images/nullRock.png" - "../images/particle2.png" - "../images/particle3.png" - "../images/particleA.png" - "../images/portal_bg.png" - "../images/realLeaf1.png" - "../images/realLeaf2.png" - "../images/realLeaf3.png" - "../images/realLeaf4.png" - "../images/rocket.png" - "../images/rocket2.png" - "../images/sizeInOut.png" - "../images/snowflake.png" - "../images/sparkleSize.png" - "../images/starfish_0.png" - "../images/starfish_1.png" - "../images/starfish_2.png" - "../images/starfish_3.png" - "../images/starfish_4.png" - "../images/starfish_mask.png" -) - -qt6_add_resources(imageparticle "images" - PREFIX - "/particles" - BASE - ".." - FILES - ${images_resource_files} -) -set(shared_resource_files - "../../shared/Button.qml" - "../../shared/CheckBox.qml" - "../../shared/FlickrRssModel.qml" - "../../shared/Label.qml" - "../../shared/LauncherList.qml" - "../../shared/SimpleLauncherDelegate.qml" - "../../shared/Slider.qml" - "../../shared/TabSet.qml" - "../../shared/TextField.qml" - "../../shared/images/back.png" - "../../shared/images/checkmark.png" - "../../shared/images/next.png" - "../../shared/images/qt-logo.png" - "../../shared/images/slider_handle.png" - "../../shared/images/tab.png" -) - -qt6_add_resources(imageparticle "shared" - PREFIX - "/shared" - BASE - "../../shared" - FILES - ${shared_resource_files} -) - -install(TARGETS imageparticle +qt_add_qml_module(imageparticleexample + URI imageparticle + VERSION 1.0 + QML_FILES + "allatonce.qml" + "colored.qml" + "colortable.qml" + "deformation.qml" + "imageparticle.qml" + "rotation.qml" + "sharing.qml" + "sprites.qml" + RESOURCES + "images/bear_tiles.png" + "images/colortable.png" + "images/starfish_0.png" + "images/starfish_1.png" + "images/starfish_2.png" + "images/starfish_3.png" + "images/starfish_4.png" + "images/flower.png" +) + +install(TARGETS imageparticleexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) + +bundle_shared(imageparticleexample) diff --git a/examples/quick/particles/imageparticle/content/allatonce.qml b/examples/quick/particles/imageparticle/allatonce.qml similarity index 94% rename from examples/quick/particles/imageparticle/content/allatonce.qml rename to examples/quick/particles/imageparticle/allatonce.qml index 4b6c9b35ccc..5a250bc79a4 100644 --- a/examples/quick/particles/imageparticle/content/allatonce.qml +++ b/examples/quick/particles/imageparticle/allatonce.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { color: "white" @@ -64,14 +64,14 @@ Rectangle { sprites: [ Sprite { name: "bear" - source: "../../images/bear_tiles.png" + source: "images/bear_tiles.png" frameCount: 13 frameDuration: 120 } ] colorVariation: 0.5 rotationVelocityVariation: 360 - colorTable: "../../images/colortable.png" + colorTable: "images/colortable.png" // ![0] system: sys } diff --git a/examples/quick/particles/imageparticle/content/colored.qml b/examples/quick/particles/imageparticle/colored.qml similarity index 97% rename from examples/quick/particles/imageparticle/content/colored.qml rename to examples/quick/particles/imageparticle/colored.qml index 3452cad8055..11c43044574 100644 --- a/examples/quick/particles/imageparticle/content/colored.qml +++ b/examples/quick/particles/imageparticle/colored.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { width: 360 diff --git a/examples/quick/particles/imageparticle/content/colortable.qml b/examples/quick/particles/imageparticle/colortable.qml similarity index 94% rename from examples/quick/particles/imageparticle/content/colortable.qml rename to examples/quick/particles/imageparticle/colortable.qml index 5f88c1a8b3f..809ad345f95 100644 --- a/examples/quick/particles/imageparticle/content/colortable.qml +++ b/examples/quick/particles/imageparticle/colortable.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick.Particles 2.0 -import QtQuick 2.0 +import QtQuick.Particles +import QtQuick Rectangle { id: root @@ -66,8 +66,8 @@ Rectangle { //! [0] source: "qrc:///particleresources/glowdot.png" - colorTable: "../../images/colortable.png" - sizeTable: "../../images/colortable.png" + colorTable: "images/colortable.png" + sizeTable: "images/colortable.png" //! [0] } diff --git a/examples/quick/particles/imageparticle/content/deformation.qml b/examples/quick/particles/imageparticle/deformation.qml similarity index 95% rename from examples/quick/particles/imageparticle/content/deformation.qml rename to examples/quick/particles/imageparticle/deformation.qml index ce672c8fa34..f8f0f31e330 100644 --- a/examples/quick/particles/imageparticle/content/deformation.qml +++ b/examples/quick/particles/imageparticle/deformation.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { color: "goldenrod" @@ -61,7 +61,7 @@ Rectangle { ImageParticle { system: sys groups: ["goingLeft", "goingRight"] - source: "../../images/starfish_4.png" + source: "images/starfish_4.png" rotation: 90 rotationVelocity: 90 autoRotation: true @@ -71,7 +71,7 @@ Rectangle { ImageParticle { system: sys groups: ["goingDown"] - source: "../../images/starfish_0.png" + source: "images/starfish_0.png" rotation: 180 yVector: PointDirection { y: 0.5; yVariation: 0.25; xVariation: 0.25; } } diff --git a/examples/quick/particles/imageparticle/doc/src/imageparticle.qdoc b/examples/quick/particles/imageparticle/doc/src/imageparticle.qdoc index 6a71e1f5fd7..9ef3228126a 100644 --- a/examples/quick/particles/imageparticle/doc/src/imageparticle.qdoc +++ b/examples/quick/particles/imageparticle/doc/src/imageparticle.qdoc @@ -35,25 +35,25 @@ Each example is a small QML file emphasizing a particular type or feature. All at once shows off several of the features of ImageParticle at the same time. - \snippet particles/imageparticle/content/allatonce.qml 0 + \snippet particles/imageparticle/allatonce.qml 0 Colored shows a simple ImageParticle with some color variation. - \snippet particles/imageparticle/content/colored.qml 0 + \snippet particles/imageparticle/colored.qml 0 Color Table sets the color over life on the particles to provide a fixed rainbow effect. - \snippet particles/imageparticle/content/colortable.qml 0 + \snippet particles/imageparticle/colortable.qml 0 Deformation spins and squishes a starfish particle. - \snippet particles/imageparticle/content/deformation.qml spin - \snippet particles/imageparticle/content/deformation.qml deform + \snippet particles/imageparticle/deformation.qml spin + \snippet particles/imageparticle/deformation.qml deform Rotation demonstrates the autoRotate property, so that particles rotate in the direction that they travel. Sharing demonstrates what happens when multiple ImageParticles try to render the same particle. The following ImageParticle renders the particles inside the ListView: - \snippet particles/imageparticle/content/sharing.qml 0 + \snippet particles/imageparticle/sharing.qml 0 The following ImageParticle is placed inside the list highlight, and renders the particles above the other ImageParticle. - \snippet particles/imageparticle/content/sharing.qml 1 + \snippet particles/imageparticle/sharing.qml 1 Note that because it sets the color and alpha in this ImageParticle, it renders the particles in a different color. Since it doesn't specify anything about the rotation, it shares the rotation with the other ImageParticle so that the flowers are rotated the same way in both. Note that you can undo rotation in another ImageParticle, you just need to explicitly set rotationVariation to 0. diff --git a/examples/quick/particles/imageparticle/imageparticle.pro b/examples/quick/particles/imageparticle/imageparticle.pro index e639c7423a4..c9c5e59eb01 100644 --- a/examples/quick/particles/imageparticle/imageparticle.pro +++ b/examples/quick/particles/imageparticle/imageparticle.pro @@ -4,7 +4,6 @@ QT += quick qml SOURCES += main.cpp RESOURCES += \ imageparticle.qrc \ - ../images.qrc \ ../../shared/shared.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/particles/imageparticle diff --git a/examples/quick/particles/imageparticle/imageparticle.qml b/examples/quick/particles/imageparticle/imageparticle.qml index a8dfa6a0c92..0423e72e28f 100644 --- a/examples/quick/particles/imageparticle/imageparticle.qml +++ b/examples/quick/particles/imageparticle/imageparticle.qml @@ -48,23 +48,23 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "../../shared" as Examples +import QtQuick +import shared Item { height: 480 width: 320 - Examples.LauncherList { + LauncherList { id: ll anchors.fill: parent Component.onCompleted: { - addExample("All at once", "Uses all ImageParticle features", Qt.resolvedUrl("content/allatonce.qml")); - addExample("Colored", "Colorized image particles", Qt.resolvedUrl("content/colored.qml")); - addExample("Color Table", "Color-over-life rainbow particles", Qt.resolvedUrl("content/colortable.qml")); - addExample("Deformation", "Deformed particles", Qt.resolvedUrl("content/deformation.qml")); - addExample("Rotation", "Rotated particles", Qt.resolvedUrl("content/rotation.qml")); - addExample("Sharing", "Multiple ImageParticles on the same particles", Qt.resolvedUrl("content/sharing.qml")); - addExample("Sprites", "Particles rendered with sprites", Qt.resolvedUrl("content/sprites.qml")); + addExample("All at once", "Uses all ImageParticle features", Qt.resolvedUrl("allatonce.qml")); + addExample("Colored", "Colorized image particles", Qt.resolvedUrl("colored.qml")); + addExample("Color Table", "Color-over-life rainbow particles", Qt.resolvedUrl("colortable.qml")); + addExample("Deformation", "Deformed particles", Qt.resolvedUrl("deformation.qml")); + addExample("Rotation", "Rotated particles", Qt.resolvedUrl("rotation.qml")); + addExample("Sharing", "Multiple ImageParticles on the same particles", Qt.resolvedUrl("sharing.qml")); + addExample("Sprites", "Particles rendered with sprites", Qt.resolvedUrl("sprites.qml")); } } } diff --git a/examples/quick/particles/imageparticle/imageparticle.qrc b/examples/quick/particles/imageparticle/imageparticle.qrc index d9e4115e3ec..ef9bddaaae5 100644 --- a/examples/quick/particles/imageparticle/imageparticle.qrc +++ b/examples/quick/particles/imageparticle/imageparticle.qrc @@ -1,12 +1,20 @@ - + imageparticle.qml - content/allatonce.qml - content/colored.qml - content/colortable.qml - content/deformation.qml - content/rotation.qml - content/sharing.qml - content/sprites.qml + allatonce.qml + colored.qml + colortable.qml + deformation.qml + rotation.qml + sharing.qml + sprites.qml + images/bear_tiles.png + images/colortable.png + images/starfish_0.png + images/starfish_1.png + images/starfish_2.png + images/starfish_3.png + images/starfish_4.png + images/flower.png diff --git a/examples/quick/particles/images/bear_tiles.png b/examples/quick/particles/imageparticle/images/bear_tiles.png similarity index 100% rename from examples/quick/particles/images/bear_tiles.png rename to examples/quick/particles/imageparticle/images/bear_tiles.png diff --git a/examples/quick/particles/images/colortable.png b/examples/quick/particles/imageparticle/images/colortable.png similarity index 100% rename from examples/quick/particles/images/colortable.png rename to examples/quick/particles/imageparticle/images/colortable.png diff --git a/examples/quick/particles/images/flower.png b/examples/quick/particles/imageparticle/images/flower.png similarity index 100% rename from examples/quick/particles/images/flower.png rename to examples/quick/particles/imageparticle/images/flower.png diff --git a/examples/quick/particles/images/starfish_0.png b/examples/quick/particles/imageparticle/images/starfish_0.png similarity index 100% rename from examples/quick/particles/images/starfish_0.png rename to examples/quick/particles/imageparticle/images/starfish_0.png diff --git a/examples/quick/particles/images/starfish_1.png b/examples/quick/particles/imageparticle/images/starfish_1.png similarity index 100% rename from examples/quick/particles/images/starfish_1.png rename to examples/quick/particles/imageparticle/images/starfish_1.png diff --git a/examples/quick/particles/images/starfish_2.png b/examples/quick/particles/imageparticle/images/starfish_2.png similarity index 100% rename from examples/quick/particles/images/starfish_2.png rename to examples/quick/particles/imageparticle/images/starfish_2.png diff --git a/examples/quick/particles/images/starfish_3.png b/examples/quick/particles/imageparticle/images/starfish_3.png similarity index 100% rename from examples/quick/particles/images/starfish_3.png rename to examples/quick/particles/imageparticle/images/starfish_3.png diff --git a/examples/quick/particles/images/starfish_4.png b/examples/quick/particles/imageparticle/images/starfish_4.png similarity index 100% rename from examples/quick/particles/images/starfish_4.png rename to examples/quick/particles/imageparticle/images/starfish_4.png diff --git a/examples/quick/particles/imageparticle/main.cpp b/examples/quick/particles/imageparticle/main.cpp index ff0764a730e..a831728d0b5 100644 --- a/examples/quick/particles/imageparticle/main.cpp +++ b/examples/quick/particles/imageparticle/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(particles/imageparticle/imageparticle) +DECLARATIVE_EXAMPLE_MAIN(imageparticle/imageparticle) diff --git a/examples/quick/particles/imageparticle/content/rotation.qml b/examples/quick/particles/imageparticle/rotation.qml similarity index 95% rename from examples/quick/particles/imageparticle/content/rotation.qml rename to examples/quick/particles/imageparticle/rotation.qml index d118bb1d972..f7b101d0c2e 100644 --- a/examples/quick/particles/imageparticle/content/rotation.qml +++ b/examples/quick/particles/imageparticle/rotation.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { color: "goldenrod" @@ -59,7 +59,7 @@ Rectangle { ImageParticle { id: up system: sys - source: "../../images/starfish_2.png" + source: "images/starfish_2.png" autoRotation: true //leaving these two settings at default allows you to test going up performance levels rotation: -90 } diff --git a/examples/quick/particles/imageparticle/content/sharing.qml b/examples/quick/particles/imageparticle/sharing.qml similarity index 97% rename from examples/quick/particles/imageparticle/content/sharing.qml rename to examples/quick/particles/imageparticle/sharing.qml index 13b0dadf85a..365d2e99fda 100644 --- a/examples/quick/particles/imageparticle/content/sharing.qml +++ b/examples/quick/particles/imageparticle/sharing.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -52,8 +52,8 @@ // that uses a SpringAnimation to provide custom movement when the // highlight bar is moved between items. -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { id: root @@ -108,7 +108,7 @@ Rectangle { ImageParticle { anchors.fill: parent system: particles - source: "../../images/flower.png" + source: "images/flower.png" color: "red" clip: true alpha: 1.0 @@ -147,7 +147,7 @@ Rectangle { ImageParticle { anchors.fill: parent system: particles - source: "../../images/flower.png" + source: "images/flower.png" alpha: 0.1 color: "white" rotationVariation: 180 diff --git a/examples/quick/particles/imageparticle/content/sprites.qml b/examples/quick/particles/imageparticle/sprites.qml similarity index 92% rename from examples/quick/particles/imageparticle/content/sprites.qml rename to examples/quick/particles/imageparticle/sprites.qml index c8ffe6c0e5c..3e7d09bdded 100644 --- a/examples/quick/particles/imageparticle/content/sprites.qml +++ b/examples/quick/particles/imageparticle/sprites.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { color: "lightsteelblue" @@ -60,7 +60,7 @@ Rectangle { SpriteSequence { sprites: Sprite { name: "bear" - source: "../../images/bear_tiles.png" + source: "images/bear_tiles.png" frameCount: 13 frameDuration: 120 } @@ -80,25 +80,25 @@ Rectangle { system: sys sprites: [Sprite { name: "happy" - source: "../../images/starfish_1.png" + source: "images/starfish_1.png" frameCount: 1 frameDuration: 260 to: {"happy": 1, "silly": 1, "angry": 1} }, Sprite { name: "angry" - source: "../../images/starfish_0.png" + source: "images/starfish_0.png" frameCount: 1 frameDuration: 260 to: {"happy": 1, "silly": 1, "angry": 1} }, Sprite { name: "silly" - source: "../../images/starfish_2.png" + source: "images/starfish_2.png" frameCount: 1 frameDuration: 260 to: {"happy": 1, "silly": 1, "noticedbear": 0} }, Sprite { name: "noticedbear" - source: "../../images/starfish_3.png" + source: "images/starfish_3.png" frameCount: 1 frameDuration: 2600 }] diff --git a/examples/quick/particles/images.qrc b/examples/quick/particles/images.qrc deleted file mode 100644 index 1f754838a82..00000000000 --- a/examples/quick/particles/images.qrc +++ /dev/null @@ -1,35 +0,0 @@ - - - images/_explo.png - images/backgroundLeaves.jpg - images/bear_tiles.png - images/candle.png - images/colortable.png - images/finalfrontier.png - images/flower.png - images/matchmask.png - images/meteor_explo.png - images/meteor.png - images/meteors.png - images/nullRock.png - images/particle2.png - images/particle3.png - images/particleA.png - images/portal_bg.png - images/realLeaf1.png - images/realLeaf2.png - images/realLeaf3.png - images/realLeaf4.png - images/rocket.png - images/rocket2.png - images/sizeInOut.png - images/snowflake.png - images/sparkleSize.png - images/starfish_0.png - images/starfish_1.png - images/starfish_2.png - images/starfish_3.png - images/starfish_4.png - images/starfish_mask.png - - diff --git a/examples/quick/particles/images/meteor_explo.png b/examples/quick/particles/images/meteor_explo.png deleted file mode 100644 index e659bfe2cf0..00000000000 Binary files a/examples/quick/particles/images/meteor_explo.png and /dev/null differ diff --git a/examples/quick/particles/images/meteors.png b/examples/quick/particles/images/meteors.png deleted file mode 100644 index bada8a1407e..00000000000 Binary files a/examples/quick/particles/images/meteors.png and /dev/null differ diff --git a/examples/quick/particles/images/sizeInOut.png b/examples/quick/particles/images/sizeInOut.png deleted file mode 100644 index 43d8862dbe7..00000000000 Binary files a/examples/quick/particles/images/sizeInOut.png and /dev/null differ diff --git a/examples/quick/particles/itemparticle/CMakeLists.txt b/examples/quick/particles/itemparticle/CMakeLists.txt index 80c63de81f6..6df338e00ef 100644 --- a/examples/quick/particles/itemparticle/CMakeLists.txt +++ b/examples/quick/particles/itemparticle/CMakeLists.txt @@ -1,13 +1,9 @@ -# Generated from itemparticle.pro. - -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(itemparticle LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,119 +11,38 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/particles/itemparticle") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) + +add_subdirectory("../../shared" "shared") -qt_add_executable(itemparticle +qt_add_executable(itemparticleexample WIN32 MACOSX_BUNDLE main.cpp ) -set_target_properties(itemparticle PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(itemparticle PUBLIC +target_link_libraries(itemparticleexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) - -file(GLOB resource_glob_0 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "content/*") -foreach(file IN LISTS resource_glob_0) - set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}") -endforeach() - -file(GLOB resource_glob_1 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*qml") -foreach(file IN LISTS resource_glob_1) - set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}") -endforeach() +add_dependencies(itemparticleexample itemparticle_shared) # Resources: -set(images_resource_files - "../images/_explo.png" - "../images/backgroundLeaves.jpg" - "../images/bear_tiles.png" - "../images/candle.png" - "../images/colortable.png" - "../images/finalfrontier.png" - "../images/flower.png" - "../images/matchmask.png" - "../images/meteor.png" - "../images/meteor_explo.png" - "../images/meteors.png" - "../images/nullRock.png" - "../images/particle2.png" - "../images/particle3.png" - "../images/particleA.png" - "../images/portal_bg.png" - "../images/realLeaf1.png" - "../images/realLeaf2.png" - "../images/realLeaf3.png" - "../images/realLeaf4.png" - "../images/rocket.png" - "../images/rocket2.png" - "../images/sizeInOut.png" - "../images/snowflake.png" - "../images/sparkleSize.png" - "../images/starfish_0.png" - "../images/starfish_1.png" - "../images/starfish_2.png" - "../images/starfish_3.png" - "../images/starfish_4.png" - "../images/starfish_mask.png" -) - -qt6_add_resources(itemparticle "images" - PREFIX - "/particles" - BASE - ".." - FILES - ${images_resource_files} -) -set(shared_resource_files - "../../shared/Button.qml" - "../../shared/CheckBox.qml" - "../../shared/FlickrRssModel.qml" - "../../shared/Label.qml" - "../../shared/LauncherList.qml" - "../../shared/SimpleLauncherDelegate.qml" - "../../shared/Slider.qml" - "../../shared/TabSet.qml" - "../../shared/TextField.qml" - "../../shared/images/back.png" - "../../shared/images/checkmark.png" - "../../shared/images/next.png" - "../../shared/images/qt-logo.png" - "../../shared/images/slider_handle.png" - "../../shared/images/tab.png" -) - -qt6_add_resources(itemparticle "shared" - PREFIX - "/shared" - BASE - "../../shared" - FILES - ${shared_resource_files} -) -set(qmake_immediate_resource_files - ${resource_glob_0} - ${resource_glob_1} -) - -qt6_add_resources(itemparticle "qmake_immediate" - PREFIX - "/" - FILES - ${qmake_immediate_resource_files} -) - -install(TARGETS itemparticle +qt_add_qml_module(itemparticleexample + URI itemparticle + VERSION 1.0 + QML_FILES + "itemparticle.qml" + "delegates.qml" + "script.js" + RESOURCES + "images/rocket.png" +) + +install(TARGETS itemparticleexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) + +bundle_shared(itemparticleexample) diff --git a/examples/quick/particles/itemparticle/content/Delegate.qml b/examples/quick/particles/itemparticle/content/Delegate.qml deleted file mode 100644 index 946b7b8748b..00000000000 --- a/examples/quick/particles/itemparticle/content/Delegate.qml +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//![0] -Package { - Text { id: listDelegate; width: 200; height: 25; text: 'Empty'; Package.name: 'list' } - Text { id: gridDelegate; width: 100; height: 50; text: 'Empty'; Package.name: 'grid' } - - Rectangle { - id: wrapper - width: 200; height: 25 - color: 'lightsteelblue' - - Text { text: display; anchors.centerIn: parent } - MouseArea { - anchors.fill: parent - onClicked: { - if (wrapper.state == 'inList') - wrapper.state = 'inGrid'; - else - wrapper.state = 'inList'; - } - } - - state: 'inList' - states: [ - State { - name: 'inList' - ParentChange { target: wrapper; parent: listDelegate } - }, - State { - name: 'inGrid' - ParentChange { - target: wrapper; parent: gridDelegate - x: 0; y: 0; width: gridDelegate.width; height: gridDelegate.height - } - } - ] - - transitions: [ - Transition { - ParentAnimation { - NumberAnimation { properties: 'x,y,width,height'; duration: 300 } - } - } - ] - } -} -//![0] diff --git a/examples/quick/particles/itemparticle/content/Delegate2.qml b/examples/quick/particles/itemparticle/content/Delegate2.qml deleted file mode 100644 index 03465609d91..00000000000 --- a/examples/quick/particles/itemparticle/content/Delegate2.qml +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//![0] -Package { - Item { id: gridDelegate; width: w; height: h; Package.name: 'grid' } - Item { id: particleDelegate; width: w; height: h; Package.name: 'particles' - - Rectangle { - id: wrapper - width: w; height: h; - color: col - rotation: Math.random()*360 - Behavior on rotation {RotationAnimation {}} - - states: State { - name: "gridded" - when: root.inGrid - PropertyChanges { - target: wrapper - rotation: 0 - } - ParentChange { - target: wrapper - parent: gridDelegate - x:0 - y:0 - } - } - transitions: [ - Transition { - ParentAnimation { - NumberAnimation { properties: 'x,y,width,height'; duration: 300 } - } - } - ] - } - } -} -//![0] diff --git a/examples/quick/particles/itemparticle/content/ExpandingDelegate.qml b/examples/quick/particles/itemparticle/content/ExpandingDelegate.qml deleted file mode 100644 index 9ffbc7f3502..00000000000 --- a/examples/quick/particles/itemparticle/content/ExpandingDelegate.qml +++ /dev/null @@ -1,215 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 -import "../../../modelviews/listview/content" - -// This example illustrates expanding a list item to show a more detailed view. - - // Delegate for the recipes. This delegate has two modes: - // 1. List mode (default), which just shows the picture and title of the recipe. - // 2. Details mode, which also shows the ingredients and method. - Component { - id: recipeDelegate - - Item { - id: recipe - - // Create a property to contain the visibility of the details. - // We can bind multiple element's opacity to this one property, - // rather than having a "PropertyChanges" line for each element we - // want to fade. - property real detailsOpacity : 0 - - //this bit changed for aesthetics - width: 70 - height: 70 - // A simple rounded rectangle for the background - Rectangle { - id: background - x: 2; y: 2; width: parent.width - x*2; height: parent.height - y*2 - color: "ivory" - border.color: "orange" - radius: 5 - antialiasing: true - } - Image { - anchors.fill:parent - anchors.margins: -32 - source: "bubble.png" - } - - - // This mouse region covers the entire delegate. - // When clicked it changes mode to 'Details'. If we are already - // in Details mode, then no change will happen. - MouseArea { - anchors.fill: parent - onClicked: recipe.state = 'Details'; - } - - // Lay out the page: picture, title and ingredients at the top, and method at the - // bottom. Note that elements that should not be visible in the list - // mode have their opacity set to recipe.detailsOpacity. - Row { - id: topLayout - x: 10; y: 10; height: recipeImage.height; width: parent.width - spacing: 10 - - Image { - id: recipeImage - width: 50; height: 50 - source: "../../modelviews/listview/" + picture - } - - Column { - width: background.width - recipeImage.width - 20; height: recipeImage.height - spacing: 5 - - Text { - text: title - font.bold: true; font.pointSize: 16 - } - - Text { - text: "Ingredients" - font.pointSize: 12; font.bold: true - opacity: recipe.detailsOpacity - } - - Text { - text: ingredients - wrapMode: Text.WordWrap - width: parent.width - opacity: recipe.detailsOpacity - } - } - } - - Item { - id: details - x: 10; width: parent.width - 20 - anchors { top: topLayout.bottom; topMargin: 10; bottom: parent.bottom; bottomMargin: 10 } - opacity: recipe.detailsOpacity - - Text { - id: methodTitle - anchors.top: parent.top - text: "Method" - font.pointSize: 12; font.bold: true - } - - Flickable { - id: flick - width: parent.width - anchors { top: methodTitle.bottom; bottom: parent.bottom } - contentHeight: methodText.height - clip: true - - Text { id: methodText; text: method; wrapMode: Text.WordWrap; width: details.width } - } - - Image { - anchors { right: flick.right; top: flick.top } - source: "../../modelviews/listview/" + "content/pics/moreUp.png" - opacity: flick.atYBeginning ? 0 : 1 - } - - Image { - anchors { right: flick.right; bottom: flick.bottom } - source: "../../modelviews/listview/" + "content/pics/moreDown.png" - opacity: flick.atYEnd ? 0 : 1 - } - } - - // A button to close the detailed view, i.e. set the state back to default (''). - TextButton { - y: 10 - anchors { right: background.right; rightMargin: 10 } - opacity: recipe.detailsOpacity - text: "Close" - - onClicked: recipe.state = ''; - } - - states: State { - name: "Details" - - PropertyChanges { target: background; color: "white" } - PropertyChanges { target: recipeImage; width: 130; height: 130 } // Make picture bigger - PropertyChanges { target: recipe; detailsOpacity: 1; x: 0; opacity: 1 } // Make details visible - PropertyChanges { target: recipe; height: root.height; width: root.height; x:0; y:0; z:100} // Fill the entire list area with the detailed view - - // Move the list so that this item is at the top. - //PropertyChanges { target: recipe.ListView.view; explicit: true; contentY: recipe.y } - - // Disallow flicking while we're in detailed view - //PropertyChanges { target: recipe.ListView.view; interactive: false } - } - - transitions: Transition { - //The only strictly necessary particle specific lines - to: "Details" - reversible: true - ScriptAction {script: { - if(state == "Details") - mp.freeze(index); - else - mp.unfreeze(index); - } - } - // Make the state changes smooth - ParallelAnimation { - ColorAnimation { property: "color"; duration: 500 } - NumberAnimation { duration: 300; properties: "detailsOpacity,opacity,x,y,height,width" } - } - } - } - } diff --git a/examples/quick/particles/itemparticle/content/bubble.png b/examples/quick/particles/itemparticle/content/bubble.png deleted file mode 100644 index f26ed1d3f23..00000000000 Binary files a/examples/quick/particles/itemparticle/content/bubble.png and /dev/null differ diff --git a/examples/quick/particles/itemparticle/delegates.qml b/examples/quick/particles/itemparticle/delegates.qml index 0e9267214f3..a53c7198284 100644 --- a/examples/quick/particles/itemparticle/delegates.qml +++ b/examples/quick/particles/itemparticle/delegates.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { id: root; diff --git a/examples/quick/particles/itemparticle/images/rocket.png b/examples/quick/particles/itemparticle/images/rocket.png new file mode 100644 index 00000000000..a171610b03e Binary files /dev/null and b/examples/quick/particles/itemparticle/images/rocket.png differ diff --git a/examples/quick/particles/itemparticle/itemparticle.pro b/examples/quick/particles/itemparticle/itemparticle.pro index f5c0576b4ad..c0426cd032f 100644 --- a/examples/quick/particles/itemparticle/itemparticle.pro +++ b/examples/quick/particles/itemparticle/itemparticle.pro @@ -3,10 +3,8 @@ TEMPLATE = app QT += quick qml SOURCES += main.cpp RESOURCES += \ - ../images.qrc \ - ../../shared/shared.qrc \ - $$files("content/*") \ - $$files("*qml") + itemparticle.qrc \ + ../../shared/shared.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/particles/itemparticle INSTALLS += target diff --git a/examples/quick/particles/itemparticle/itemparticle.qml b/examples/quick/particles/itemparticle/itemparticle.qml new file mode 100644 index 00000000000..ad2038fdbf7 --- /dev/null +++ b/examples/quick/particles/itemparticle/itemparticle.qml @@ -0,0 +1,309 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Particles +import shared +import "script.js" as Script + +Item { + id: root + width: 640 + height: 480 + Rectangle { + anchors.fill: parent + color: "black" + z: -1 + } + Item { + id: loading + Behavior on opacity {NumberAnimation {}} + anchors.fill: parent + Text { + anchors.centerIn: parent + text: "Loading" + color: "white" + } + } + ParticleSystem { + id: sys; + running: true + } + Emitter { + id: emitter + system: sys + height: parent.height - 132/2 + x: -132/2 + y: 132/2 + velocity: PointDirection { x: 32; xVariation: 8 } + emitRate: 0.5 + lifeSpan: Emitter.InfiniteLife + group: "photos" + } + Age { + system: sys + x: parent.width + 132/2 + height: parent.height + width: 1000 + } + ImageParticle { + system: sys + groups: ["fireworks"] + source: "qrc:///particleresources/star.png" + color: "lightsteelblue" + alpha: 0 + colorVariation: 0 + z: 1000 + } + ItemParticle { + id: mp + z: 0 + system: sys + fade: false + groups: ["photos"] + } + Component { + id: alertDelegate + Rectangle { + color: "DarkSlateGray" + border.width: 1 + border.color: "LightSteelBlue" + width: 144 + height: 132 + antialiasing: true + radius: 3 + NumberAnimation on scale { + running: true + loops: 1 + from: 0.2 + to: 1 + } + Image { + source: "images/rocket.png" + anchors.centerIn: parent + } + Text { + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + text: "A new ship has arrived!" + color: "LightSteelBlue" + } + } + } + property Item alertItem; + function alert() { + force.enabled = true; + alertItem = alertDelegate.createObject(root); + alertItem.x = root.width/2 - alertItem.width/2 + alertItem.y = root.height/2 - alertItem.height/2 + spawnFireworks.pulse(200); + stopAlert.start(); + } + focus: true + Keys.onSpacePressed: alert(); + Timer { + id: stopAlert + running: false + repeat: false + interval: 800 + onTriggered: { + force.enabled = false; + mp.take(root.alertItem, true); + centerEmitter.burst(1); + } + } + Attractor { + id: force + system: sys + pointX: root.width/2 + pointY: root.height/2 + strength: -10000 + enabled: false + anchors.centerIn: parent + width: parent.width/2 + height: parent.height/2 + groups:["photos"] + affectedParameter: Attractor.Position + } + Emitter { + id: centerEmitter + velocity: PointDirection { x: 32; xVariation: 8;} + emitRate: 0.5 + lifeSpan: 12000 //TODO: A -1 or something which does 'infinite'? (but need disable fade first) + maximumEmitted: 20 + group: "photos" + system: sys + anchors.centerIn: parent + enabled: false + + //TODO: Zoom in effect + } + Emitter { + id: spawnFireworks + group: "fireworks" + system: sys + maximumEmitted: 400 + emitRate: 400 + lifeSpan: 2800 + x: parent.width/2 + y: parent.height/2 - 64 + width: 8 + height: 8 + enabled: false + size: 32 + endSize: 8 + velocity: AngleDirection { magnitude: 160; magnitudeVariation: 120; angleVariation: 90; angle: 270 } + acceleration: PointDirection { y: 160 } + } + Item { x: -1000; y: -1000 //offscreen + Repeater {//Load them here, add to system on completed + model: flickrModel + delegate: theDelegate + } + } + FlickrRssModel { + id: flickrModel + tags: "particle,particles" + } + Component { + id: theDelegate + Image { + required property int index + required property string title + required property string media + required property string thumbnail + + id: image + antialiasing: true; + source: thumbnail + cache: true + property real depth: Math.random() + property real darken: 0.75 + z: Math.floor(depth * 100) + scale: (depth + 1) / 2 + sourceSize { + width: root.width + height: root.height + } + width: 132 + height: 132 + fillMode: Image.PreserveAspectFit + Rectangle { + // Darken based on depth + anchors.centerIn: parent + width: parent.paintedWidth + 1 + height: parent.paintedHeight + 1 + color: "black" + opacity: image.darken * (1 - image.depth) + antialiasing: true; + } + Text { + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: Math.max(parent.paintedWidth, parent.paintedHeight) - Math.min(parent.width, parent.height) + width: parent.paintedWidth - 4 + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight + text: image.title + color: "black" + } + ItemParticle.onDetached: mp.take(image); // respawns + onStatusChanged: if (image.status == Image.Ready) { + loading.opacity = 0; + mp.take(image); + } + function manage() + { + if (state == "selected") { + console.log("Taking " + index); + mp.freeze(image); + } else { + console.log("Returning " +index); + mp.unfreeze(image); + } + } + TapHandler { + gesturePolicy: TapHandler.ReleaseWithinBounds + onTapped: image.state = (image.state == "" ? "selected" : "") + } + states: State { + name: "selected" + ParentChange { + target: image + parent: root + } + PropertyChanges { + image { + source: image.media + x: 0 + y: 0 + width: root.width + height: root.height + z: 101 + opacity: 1 + rotation: 0 + darken: 0 + } + } + } + transitions: Transition { + to: "selected" + reversible: true + SequentialAnimation { + ScriptAction { script: image.manage() } + ParallelAnimation { + ParentAnimation {NumberAnimation { properties: "x,y" }} + PropertyAnimation { properties: "width, height, z, rotation, darken"; easing.type: Easing.InOutQuad } + } + } + } + } + } +} diff --git a/examples/quick/particles/itemparticle/itemparticle.qrc b/examples/quick/particles/itemparticle/itemparticle.qrc new file mode 100644 index 00000000000..f951ba63660 --- /dev/null +++ b/examples/quick/particles/itemparticle/itemparticle.qrc @@ -0,0 +1,8 @@ + + + itemparticle.qml + delegates.qml + script.js + images/rocket.png + + diff --git a/examples/quick/particles/itemparticle/main.cpp b/examples/quick/particles/itemparticle/main.cpp index da21f15be37..5c7f7d5f3c4 100644 --- a/examples/quick/particles/itemparticle/main.cpp +++ b/examples/quick/particles/itemparticle/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(particleview) +DECLARATIVE_EXAMPLE_MAIN(itemparticle/itemparticle) diff --git a/examples/quick/particles/itemparticle/particleview.qml b/examples/quick/particles/itemparticle/particleview.qml deleted file mode 100644 index 8eb18dc283f..00000000000 --- a/examples/quick/particles/itemparticle/particleview.qml +++ /dev/null @@ -1,309 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.12 -import QtQuick.Particles 2.12 -import "shared" as Shared -import "content/script.js" as Script -import "content" - -Item { - id: root - width: 640 - height: 480 - Rectangle { - anchors.fill: parent - color: "black" - z: -1 - } - Item { - id: loading - Behavior on opacity {NumberAnimation {}} - anchors.fill: parent - Text { - anchors.centerIn: parent - text: "Loading" - color: "white" - } - } - ParticleSystem { - id: sys; - running: true - } - Emitter { - id: emitter - system: sys - height: parent.height - 132/2 - x: -132/2 - y: 132/2 - velocity: PointDirection { x: 32; xVariation: 8 } - emitRate: 0.5 - lifeSpan: Emitter.InfiniteLife - group: "photos" - } - Age { - system: sys - x: parent.width + 132/2 - height: parent.height - width: 1000 - } - ImageParticle { - system: sys - groups: ["fireworks"] - source: "qrc:///particleresources/star.png" - color: "lightsteelblue" - alpha: 0 - colorVariation: 0 - z: 1000 - } - ItemParticle { - id: mp - z: 0 - system: sys - fade: false - groups: ["photos"] - } - Component { - id: alertDelegate - Rectangle { - color: "DarkSlateGray" - border.width: 1 - border.color: "LightSteelBlue" - width: 144 - height: 132 - antialiasing: true - radius: 3 - NumberAnimation on scale { - running: true - loops: 1 - from: 0.2 - to: 1 - } - Image { - source: "qrc:///particles/images/rocket.png" - anchors.centerIn: parent - } - Text { - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - text: "A new ship has arrived!" - color: "LightSteelBlue" - } - } - } - property Item alertItem; - function alert() { - force.enabled = true; - alertItem = alertDelegate.createObject(root); - alertItem.x = root.width/2 - alertItem.width/2 - alertItem.y = root.height/2 - alertItem.height/2 - spawnFireworks.pulse(200); - stopAlert.start(); - } - focus: true - Keys.onSpacePressed: alert(); - Timer { - id: stopAlert - running: false - repeat: false - interval: 800 - onTriggered: { - force.enabled = false; - mp.take(root.alertItem, true); - centerEmitter.burst(1); - } - } - Attractor { - id: force - system: sys - pointX: root.width/2 - pointY: root.height/2 - strength: -10000 - enabled: false - anchors.centerIn: parent - width: parent.width/2 - height: parent.height/2 - groups:["photos"] - affectedParameter: Attractor.Position - } - Emitter { - id: centerEmitter - velocity: PointDirection { x: 32; xVariation: 8;} - emitRate: 0.5 - lifeSpan: 12000 //TODO: A -1 or something which does 'infinite'? (but need disable fade first) - maximumEmitted: 20 - group: "photos" - system: sys - anchors.centerIn: parent - enabled: false - - //TODO: Zoom in effect - } - Emitter { - id: spawnFireworks - group: "fireworks" - system: sys - maximumEmitted: 400 - emitRate: 400 - lifeSpan: 2800 - x: parent.width/2 - y: parent.height/2 - 64 - width: 8 - height: 8 - enabled: false - size: 32 - endSize: 8 - velocity: AngleDirection { magnitude: 160; magnitudeVariation: 120; angleVariation: 90; angle: 270 } - acceleration: PointDirection { y: 160 } - } - Item { x: -1000; y: -1000 //offscreen - Repeater {//Load them here, add to system on completed - model: flickrModel - delegate: theDelegate - } - } - Shared.FlickrRssModel { - id: flickrModel - tags: "particle,particles" - } - Component { - id: theDelegate - Image { - required property int index - required property string title - required property string media - required property string thumbnail - - id: image - antialiasing: true; - source: thumbnail - cache: true - property real depth: Math.random() - property real darken: 0.75 - z: Math.floor(depth * 100) - scale: (depth + 1) / 2 - sourceSize { - width: root.width - height: root.height - } - width: 132 - height: 132 - fillMode: Image.PreserveAspectFit - Rectangle { - // Darken based on depth - anchors.centerIn: parent - width: parent.paintedWidth + 1 - height: parent.paintedHeight + 1 - color: "black" - opacity: image.darken * (1 - image.depth) - antialiasing: true; - } - Text { - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: Math.max(parent.paintedWidth, parent.paintedHeight) - Math.min(parent.width, parent.height) - width: parent.paintedWidth - 4 - horizontalAlignment: Text.AlignHCenter - elide: Text.ElideRight - text: image.title - color: "black" - } - ItemParticle.onDetached: mp.take(image); // respawns - onStatusChanged: if (image.status == Image.Ready) { - loading.opacity = 0; - mp.take(image); - } - function manage() - { - if (state == "selected") { - console.log("Taking " + index); - mp.freeze(image); - } else { - console.log("Returning " +index); - mp.unfreeze(image); - } - } - TapHandler { - gesturePolicy: TapHandler.ReleaseWithinBounds - onTapped: image.state = (image.state == "" ? "selected" : "") - } - states: State { - name: "selected" - ParentChange { - target: image - parent: root - } - PropertyChanges { - target: image - source: image.media - x: 0 - y: 0 - width: root.width - height: root.height - z: 101 - opacity: 1 - rotation: 0 - darken: 0 - } - } - transitions: Transition { - to: "selected" - reversible: true - SequentialAnimation { - ScriptAction { script: image.manage() } - ParallelAnimation { - ParentAnimation {NumberAnimation { properties: "x,y" }} - PropertyAnimation { properties: "width, height, z, rotation, darken"; easing.type: Easing.InOutQuad } - } - } - } - } - } -} diff --git a/examples/quick/particles/itemparticle/content/script.js b/examples/quick/particles/itemparticle/script.js similarity index 100% rename from examples/quick/particles/itemparticle/content/script.js rename to examples/quick/particles/itemparticle/script.js diff --git a/examples/quick/particles/particles.pro b/examples/quick/particles/particles.pro index 5343fa00f13..7ef86618d5b 100644 --- a/examples/quick/particles/particles.pro +++ b/examples/quick/particles/particles.pro @@ -5,9 +5,6 @@ SUBDIRS += affectors \ itemparticle \ system -EXAMPLE_FILES = \ - images.qrc - #Install shared images too qml.files = images qml.path = $$[QT_INSTALL_EXAMPLES]/quick/particles diff --git a/examples/quick/particles/system/CMakeLists.txt b/examples/quick/particles/system/CMakeLists.txt index 91c754786fd..c8ab118550a 100644 --- a/examples/quick/particles/system/CMakeLists.txt +++ b/examples/quick/particles/system/CMakeLists.txt @@ -1,13 +1,12 @@ # Generated from system.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(system LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,113 +14,43 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/particles/system") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) -qt_add_executable(system +add_subdirectory("../../shared" "shared") + +qt_add_executable(systemexample WIN32 MACOSX_BUNDLE main.cpp ) -set_target_properties(system PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(system PUBLIC +target_link_libraries(systemexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(systemexample system_shared) # Resources: -set(system_resource_files - "content/dynamiccomparison.qml" - "content/dynamicemitters.qml" - "content/multiplepainters.qml" - "content/startstop.qml" - "content/timedgroupchanges.qml" - "system.qml" -) - -qt6_add_resources(system "system" - PREFIX - "/particles/system" - FILES - ${system_resource_files} -) -set(images_resource_files - "../images/_explo.png" - "../images/backgroundLeaves.jpg" - "../images/bear_tiles.png" - "../images/candle.png" - "../images/colortable.png" - "../images/finalfrontier.png" - "../images/flower.png" - "../images/matchmask.png" - "../images/meteor.png" - "../images/meteor_explo.png" - "../images/meteors.png" - "../images/nullRock.png" - "../images/particle2.png" - "../images/particle3.png" - "../images/particleA.png" - "../images/portal_bg.png" - "../images/realLeaf1.png" - "../images/realLeaf2.png" - "../images/realLeaf3.png" - "../images/realLeaf4.png" - "../images/rocket.png" - "../images/rocket2.png" - "../images/sizeInOut.png" - "../images/snowflake.png" - "../images/sparkleSize.png" - "../images/starfish_0.png" - "../images/starfish_1.png" - "../images/starfish_2.png" - "../images/starfish_3.png" - "../images/starfish_4.png" - "../images/starfish_mask.png" -) - -qt6_add_resources(system "images" - PREFIX - "/particles" - BASE - ".." - FILES - ${images_resource_files} -) -set(shared_resource_files - "../../shared/Button.qml" - "../../shared/CheckBox.qml" - "../../shared/FlickrRssModel.qml" - "../../shared/Label.qml" - "../../shared/LauncherList.qml" - "../../shared/SimpleLauncherDelegate.qml" - "../../shared/Slider.qml" - "../../shared/TabSet.qml" - "../../shared/TextField.qml" - "../../shared/images/back.png" - "../../shared/images/checkmark.png" - "../../shared/images/next.png" - "../../shared/images/qt-logo.png" - "../../shared/images/slider_handle.png" - "../../shared/images/tab.png" -) - -qt6_add_resources(system "shared" - PREFIX - "/shared" - BASE - "../../shared" - FILES - ${shared_resource_files} -) - -install(TARGETS system +qt_add_qml_module(systemexample + URI system + VERSION 1.0 + QML_FILES + "dynamiccomparison.qml" + "dynamicemitters.qml" + "multiplepainters.qml" + "timedgroupchanges.qml" + "startstop.qml" + "system.qml" + RESOURCES + "images/sparkleSize.png" + "images/particle2.png" + "images/particle3.png" +) + +install(TARGETS systemexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) + +bundle_shared(systemexample) diff --git a/examples/quick/particles/system/doc/src/system.qdoc b/examples/quick/particles/system/doc/src/system.qdoc index 22382190d30..6b795070fd9 100644 --- a/examples/quick/particles/system/doc/src/system.qdoc +++ b/examples/quick/particles/system/doc/src/system.qdoc @@ -35,7 +35,7 @@ Each example is a small QML file emphasizing a particular type or feature. Dynamic comparison compares using the particle system to getting a similar effect with the following code that dynamically instantiates Image types. - \snippet particles/system/content/dynamiccomparison.qml fake + \snippet particles/system/dynamiccomparison.qml fake Note how the Image objects are not able to be randomly colorized. Start and Stop simply sets the running and paused states of a ParticleSystem. While the system does not perform any simulation when stopped or paused, a restart restarts the simulation from the beginning, while unpausing resumes the simulation from where it was. @@ -43,14 +43,14 @@ Timed group changes is an example that highlights the ParticleGroup type. While normally referring to groups with a string name is sufficient, additional effects can be done by setting properties on groups. The first group has a variable duration on it, but always transitions to the second group. - \snippet particles/system/content/timedgroupchanges.qml 0 + \snippet particles/system/timedgroupchanges.qml 0 The second group has a TrailEmitter on it, and a fixed duration for emitting into the third group. By placing the TrailEmitter as a direct child of the ParticleGroup, it automatically selects that group to follow. - \snippet particles/system/content/timedgroupchanges.qml 1 + \snippet particles/system/timedgroupchanges.qml 1 The third group has an Affector as a direct child, which makes the affector automatically target this group. The affector means that as soon as particles enter this group, a burst function can be called on another emitter, using the x,y positions of this particle. - \snippet particles/system/content/timedgroupchanges.qml 2 + \snippet particles/system/timedgroupchanges.qml 2 If TrailEmitter does not suit your needs for multiple emitters, you can also dynamically create Emitters while still using the same ParticleSystem and image particle - \snippet particles/system/content/dynamicemitters.qml 0 + \snippet particles/system/dynamicemitters.qml 0 Note that this effect, a flurry of flying rainbow spears, would be better served with TrailEmitter. It is only done with dynamic emitters in this example to show the concept more simply. Multiple Painters shows how to control paint ordering of individual particles. While the paint ordering of particles within one ImagePainter is not strictly defined, ImageParticle objects follow the normal Z-ordering rules for \l {Qt Quick} items. This example allow you to paint the inside of the particles above the black borders using a pair of ImageParticles each painting different parts of the same logical particle. diff --git a/examples/quick/particles/system/content/dynamiccomparison.qml b/examples/quick/particles/system/dynamiccomparison.qml similarity index 98% rename from examples/quick/particles/system/content/dynamiccomparison.qml rename to examples/quick/particles/system/dynamiccomparison.qml index c1d42863eeb..ad529a2041d 100644 --- a/examples/quick/particles/system/content/dynamiccomparison.qml +++ b/examples/quick/particles/system/dynamiccomparison.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { id: root diff --git a/examples/quick/particles/system/content/dynamicemitters.qml b/examples/quick/particles/system/dynamicemitters.qml similarity index 98% rename from examples/quick/particles/system/content/dynamicemitters.qml rename to examples/quick/particles/system/dynamicemitters.qml index 8eb87d2baa8..2b1ca0885e5 100644 --- a/examples/quick/particles/system/content/dynamicemitters.qml +++ b/examples/quick/particles/system/dynamicemitters.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { id: root diff --git a/examples/quick/particles/images/particle2.png b/examples/quick/particles/system/images/particle2.png similarity index 100% rename from examples/quick/particles/images/particle2.png rename to examples/quick/particles/system/images/particle2.png diff --git a/examples/quick/particles/images/particle3.png b/examples/quick/particles/system/images/particle3.png similarity index 100% rename from examples/quick/particles/images/particle3.png rename to examples/quick/particles/system/images/particle3.png diff --git a/examples/quick/particles/images/sparkleSize.png b/examples/quick/particles/system/images/sparkleSize.png similarity index 100% rename from examples/quick/particles/images/sparkleSize.png rename to examples/quick/particles/system/images/sparkleSize.png diff --git a/examples/quick/particles/system/main.cpp b/examples/quick/particles/system/main.cpp index 63a88412f5b..cc77f3a62d7 100644 --- a/examples/quick/particles/system/main.cpp +++ b/examples/quick/particles/system/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(particles/system/system) +DECLARATIVE_EXAMPLE_MAIN(system/system) diff --git a/examples/quick/particles/system/content/multiplepainters.qml b/examples/quick/particles/system/multiplepainters.qml similarity index 94% rename from examples/quick/particles/system/content/multiplepainters.qml rename to examples/quick/particles/system/multiplepainters.qml index 1f2dcb62146..62ca583e2ec 100644 --- a/examples/quick/particles/system/content/multiplepainters.qml +++ b/examples/quick/particles/system/multiplepainters.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { id: root @@ -83,14 +83,14 @@ Rectangle { ImageParticle { system: sys visible: !cloneMode - source: "../../images/particle2.png" + source: "images/particle2.png" } ImageParticle { system: sys visible: cloneMode z: 0 - source: "../../images/particle3.png" + source: "images/particle3.png" } ImageParticle { diff --git a/examples/quick/particles/system/content/startstop.qml b/examples/quick/particles/system/startstop.qml similarity index 95% rename from examples/quick/particles/system/content/startstop.qml rename to examples/quick/particles/system/startstop.qml index a9ef7285aa9..1eff8e962ed 100644 --- a/examples/quick/particles/system/content/startstop.qml +++ b/examples/quick/particles/system/startstop.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { width: 360 @@ -80,7 +80,7 @@ Rectangle { anchors.fill: parent system: particles source: "qrc:///particleresources/star.png" - sizeTable: "../../images/sparkleSize.png" + sizeTable: "images/sparkleSize.png" alpha: 0 colorVariation: 0.6 } diff --git a/examples/quick/particles/system/system.pro b/examples/quick/particles/system/system.pro index df143f10a34..ea620f687a8 100644 --- a/examples/quick/particles/system/system.pro +++ b/examples/quick/particles/system/system.pro @@ -4,7 +4,6 @@ QT += quick qml SOURCES += main.cpp RESOURCES += \ system.qrc \ - ../images.qrc \ ../../shared/shared.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/particles/system diff --git a/examples/quick/particles/system/system.qml b/examples/quick/particles/system/system.qml index 569676d4240..9f3af987443 100644 --- a/examples/quick/particles/system/system.qml +++ b/examples/quick/particles/system/system.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,21 +48,21 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "../../shared" as Examples +import QtQuick +import shared Item { height: 480 width: 320 - Examples.LauncherList { + LauncherList { id: ll anchors.fill: parent Component.onCompleted: { - addExample("Dynamic Comparison", "Compares with dynamically created elements", Qt.resolvedUrl("content/dynamiccomparison.qml")); - addExample("StartStop", "Start and stop the simulation", Qt.resolvedUrl("content/startstop.qml")); - addExample("Timed group changes", "Emit into managed groups", Qt.resolvedUrl("content/timedgroupchanges.qml")); - addExample("Dynamic Emitters", "Dynamically instantiated emitters with a single system", Qt.resolvedUrl("content/dynamicemitters.qml")); - addExample("Multiple Painters", "Several ParticlePainters on the same logical particles", Qt.resolvedUrl("content/multiplepainters.qml")); + addExample("Dynamic Comparison", "Compares with dynamically created elements", Qt.resolvedUrl("dynamiccomparison.qml")); + addExample("StartStop", "Start and stop the simulation", Qt.resolvedUrl("startstop.qml")); + addExample("Timed group changes", "Emit into managed groups", Qt.resolvedUrl("timedgroupchanges.qml")); + addExample("Dynamic Emitters", "Dynamically instantiated emitters with a single system", Qt.resolvedUrl("dynamicemitters.qml")); + addExample("Multiple Painters", "Several ParticlePainters on the same logical particles", Qt.resolvedUrl("multiplepainters.qml")); } } } diff --git a/examples/quick/particles/system/system.qrc b/examples/quick/particles/system/system.qrc index 3fb8221fb1a..e86bc19e68a 100644 --- a/examples/quick/particles/system/system.qrc +++ b/examples/quick/particles/system/system.qrc @@ -1,10 +1,13 @@ - + system.qml - content/dynamiccomparison.qml - content/dynamicemitters.qml - content/multiplepainters.qml - content/startstop.qml - content/timedgroupchanges.qml + dynamiccomparison.qml + dynamicemitters.qml + multiplepainters.qml + startstop.qml + timedgroupchanges.qml + images/sparkleSize.png + images/particle2.png + images/particle3.png diff --git a/examples/quick/particles/system/content/timedgroupchanges.qml b/examples/quick/particles/system/timedgroupchanges.qml similarity index 98% rename from examples/quick/particles/system/content/timedgroupchanges.qml rename to examples/quick/particles/system/timedgroupchanges.qml index cab992f8989..e3eb0c3d08f 100644 --- a/examples/quick/particles/system/content/timedgroupchanges.qml +++ b/examples/quick/particles/system/timedgroupchanges.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { width: 360 diff --git a/examples/quick/pointerhandlers/CMakeLists.txt b/examples/quick/pointerhandlers/CMakeLists.txt new file mode 100644 index 00000000000..1447bbe16d0 --- /dev/null +++ b/examples/quick/pointerhandlers/CMakeLists.txt @@ -0,0 +1,85 @@ +# Generated from pointer.pro. + +cmake_minimum_required(VERSION 3.16) +project(pointerhandlers LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/pointerhandlers") + +find_package(Qt6 COMPONENTS Core Gui Quick Qml Svg) + +add_subdirectory("../shared" "shared") + +qt_add_executable(pointerhandlersexample WIN32 MACOSX_BUNDLE main.cpp) + +target_link_libraries(pointerhandlersexample PUBLIC + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick + Qt::Svg +) + +add_dependencies(pointerhandlersexample pointerhandlers_shared) + +qt_add_qml_module(pointerhandlersexample + URI pointerhandlers + VERSION 1.0 + QML_FILES + "components/Button.qml" + "components/CheckBox.qml" + "components/FakeFlickable.qml" + "components/FlashAnimation.qml" + "components/LeftDrawer.qml" + "components/MomentumAnimation.qml" + "components/MouseFeedbackSprite.qml" + "components/ScrollBar.qml" + "components/Slider.qml" + "components/TouchpointFeedbackSprite.qml" + "fakeFlickable.qml" + "flingAnimation.qml" + "joystick.qml" + "map.qml" + "mixer.qml" + "multibuttons.qml" + "pinchHandler.qml" + "pointerhandlers.qml" + "sidebar.qml" + "singlePointHandlerProperties.qml" + "tabletCanvasDrawing.qml" + "tapHandler.qml" + RESOURCES + "components/images/checkmark.png" + "components/images/fingersprite.png" + "components/images/mixer-knob.png" + "components/images/mouse.png" + "components/images/mouse_left.png" + "components/images/mouse_middle.png" + "components/images/mouse_right.png" + "images/arrowhead.png" + "images/balloon.png" + "images/cursor-airbrush.png" + "images/cursor-eraser.png" + "images/cursor-felt-marker.png" + "images/cursor-pencil.png" + "images/fighter.png" + "images/grabbing-location.svg" + "images/joystick-outer-case-pov.jpg" + "images/map.svgz" + "images/missile.png" + "images/redball.png" +) + +install(TARGETS pointerhandlersexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) +bundle_shared(pointerhandlersexample) diff --git a/examples/quick/pointerhandlers/components/Button.qml b/examples/quick/pointerhandlers/components/Button.qml new file mode 100644 index 00000000000..9ff3870d7b7 --- /dev/null +++ b/examples/quick/pointerhandlers/components/Button.qml @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Rectangle { + id: root + property alias label: label + property alias text: label.text + property alias pressed: tap.pressed + property alias hovered: hoverHandler.hovered + property alias gesturePolicy: tap.gesturePolicy + property alias margin: tap.margin + signal tapped + + implicitHeight: Math.max(Screen.pixelDensity * 7, label.implicitHeight * 2) + implicitWidth: Math.max(Screen.pixelDensity * 11, label.implicitWidth * 1.3) + height: implicitHeight + width: implicitWidth + radius: height / 6 + + border { color: Qt.darker(palette.button, 1.5); width: 1 } + gradient: Gradient { + GradientStop { position: 0.0; color: tap.pressed ? Qt.darker(palette.button, 1.3) : palette.button } + GradientStop { position: 1.0; color: Qt.darker(palette.button, 1.3) } + } + + TapHandler { + id: tap + margin: 10 // the user can tap a little beyond the edges + objectName: label.text + " Tap" + onTapped: { + tapFlash.start() + root.tapped() + } + } + HoverHandler { + id: hoverHandler + } + + Text { + id: label + font.pointSize: 14 + color: palette.buttonText + text: "Button" + anchors.centerIn: parent + } + + Rectangle { + anchors.fill: parent + color: "transparent" + border.width: 2; radius: root.radius; antialiasing: true + opacity: tapFlash.running ? 1 : 0 + FlashAnimation on visible { + id: tapFlash + } + } +} diff --git a/examples/quick/pointerhandlers/components/CheckBox.qml b/examples/quick/pointerhandlers/components/CheckBox.qml new file mode 100644 index 00000000000..bcd9ad99db3 --- /dev/null +++ b/examples/quick/pointerhandlers/components/CheckBox.qml @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Item { + id: root + implicitHeight: frame.height + implicitWidth: row.implicitWidth + width: implicitWidth + height: implicitHeight + property alias text: label.text + property bool checked + + property alias pressed: tapHandler.pressed + property alias row: row + signal clicked + + Row { + id: row + anchors.verticalCenter: parent.verticalCenter + spacing: 6 + Rectangle { + id: frame + gradient: Gradient { + GradientStop { position: 0.0; color: tapHandler.pressed ? Qt.darker(palette.button, 1.3) : palette.button } + GradientStop { position: 1.0; color: Qt.darker(palette.button, 1.3) } + } + height: label.implicitHeight * 1.5 + width: height + anchors.margins: 1 + radius: 3 + antialiasing: true + border.color: Qt.darker(palette.button, 1.5) + Image { + id: theX + source: "images/checkmark.png" + anchors.fill: frame + anchors.margins: frame.width / 5 + fillMode: Image.PreserveAspectFit + smooth: true + visible: root.checked + } + } + Text { + id: label + color: palette.text + anchors.verticalCenter: frame.verticalCenter + } + } + TapHandler { + id: tapHandler + onTapped: { + parent.checked = !parent.checked + parent.clicked() + } + } +} diff --git a/examples/quick/pointerhandlers/components/FakeFlickable.qml b/examples/quick/pointerhandlers/components/FakeFlickable.qml new file mode 100644 index 00000000000..5e652e4e685 --- /dev/null +++ b/examples/quick/pointerhandlers/components/FakeFlickable.qml @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import Qt.labs.animation + +Item { + id: root + objectName: "viewport" + default property alias data: __contentItem.data + property alias velocity: anim.velocity + property alias contentX: __contentItem.x // sign is reversed compared to Flickable.contentX + property alias contentY: __contentItem.y // sign is reversed compared to Flickable.contentY + property alias contentWidth: __contentItem.width + property alias contentHeight: __contentItem.height + signal flickStarted + signal flickEnded + + Item { + id: __contentItem + objectName: "__contentItem" + width: childrenRect.width + height: childrenRect.height + + BoundaryRule on x { + id: xbr + minimum: root.width - __contentItem.width + maximum: 0 + minimumOvershoot: 100 + maximumOvershoot: 100 + overshootFilter: BoundaryRule.Peak + } + + BoundaryRule on y { + id: ybr + minimum: root.height - __contentItem.height + maximum: 0 + minimumOvershoot: 100 + maximumOvershoot: 100 + overshootFilter: BoundaryRule.Peak + } + + DragHandler { + id: dragHandler + onActiveChanged: + if (active) { + anim.stop() + root.flickStarted() + } else { + var vel = centroid.velocity + if (xbr.returnToBounds()) + vel.x = 0 + if (ybr.returnToBounds()) + vel.y = 0 + if (vel.x !== 0 || vel.y !== 0) + anim.restart(vel) + else + root.flickEnded() + } + } + WheelHandler { + rotationScale: 15 + property: "x" + orientation: Qt.Horizontal + acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad + onActiveChanged: + // emitting signals in both instances is redundant but hard to avoid + // when the touchpad is flicking along both axes + if (active) { + anim.stop() + root.flickStarted() + } else { + xbr.returnToBounds() + root.flickEnded() + } + } + WheelHandler { + rotationScale: 15 + property: "y" + orientation: Qt.Vertical + acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad + onActiveChanged: + if (active) { + anim.stop() + root.flickStarted() + } else { + ybr.returnToBounds() + root.flickEnded() + } + } + MomentumAnimation { + id: anim + target: __contentItem + onStarted: root.flickStarted() + onStopped: { + xbr.returnToBounds() + ybr.returnToBounds() + root.flickEnded() + } + } + } +} diff --git a/examples/quick/pointerhandlers/components/FlashAnimation.qml b/examples/quick/pointerhandlers/components/FlashAnimation.qml new file mode 100644 index 00000000000..ac41b2c1d6b --- /dev/null +++ b/examples/quick/pointerhandlers/components/FlashAnimation.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +SequentialAnimation { + id: tapFlash + running: false + loops: 3 + PropertyAction { value: false } + PauseAnimation { duration: 100 } + PropertyAction { value: true } + PauseAnimation { duration: 100 } +} diff --git a/examples/quick/pointerhandlers/components/LeftDrawer.qml b/examples/quick/pointerhandlers/components/LeftDrawer.qml new file mode 100644 index 00000000000..5cf14205199 --- /dev/null +++ b/examples/quick/pointerhandlers/components/LeftDrawer.qml @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick +import Qt.labs.animation + +Item { + id: root + objectName: "LeftHandlerDrawer" + width: 100 + height: 400 + property real stickout: 4 + property real xOpen: rect.radius * -2 + property real xClosed: stickout - width + x: xClosed + y: 10 + + function close() { + openCloseAnimation.to = xClosed + openCloseAnimation.start() + } + function open() { + openCloseAnimation.to = xOpen + openCloseAnimation.start() + } + + DragHandler { + id: dragHandler + yAxis.enabled: false + xAxis.minimum: -1000 + margin: 20 + onActiveChanged: + if (!active) { + if (xbr.returnToBounds()) + return; + if (activeTranslation.x > 0) + open() + if (activeTranslation.x < 0) + close() + } + } + + BoundaryRule on x { + id: xbr + minimum: xClosed + maximum: xOpen + minimumOvershoot: rect.radius + maximumOvershoot: rect.radius + } + + NumberAnimation on x { + id: openCloseAnimation + duration: 300 + easing { type: Easing.OutBounce; overshoot: 5 } + } + + // TODO this was supposed to be RectangularGlow but we lost QtGraphicalEffects in Qt 6 + Rectangle { + id: effect + anchors.fill: parent + border.width: dragHandler.margin + border.color: "cyan" + opacity: 0.2 + radius: rect.radius + dragHandler.margin + } + + Rectangle { + id: rect + anchors.fill: parent + anchors.margins: 3 + color: "#333" + border.color: "cyan" + border.width: 2 + radius: 10 + antialiasing: true + } +} diff --git a/examples/quick/pointerhandlers/components/MomentumAnimation.qml b/examples/quick/pointerhandlers/components/MomentumAnimation.qml new file mode 100644 index 00000000000..a19d41c83fe --- /dev/null +++ b/examples/quick/pointerhandlers/components/MomentumAnimation.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +ParallelAnimation { + id: root + property Item target: null + property int duration: 500 + property vector2d velocity: Qt.vector2d(0,0) + + function restart(vel) { + stop() + velocity = vel + start() + } + + NumberAnimation { + id: xAnim + target: root.target + property: "x" + to: target.x + velocity.x / duration * 100 + duration: root.duration + easing.type: Easing.OutQuad + } + NumberAnimation { + id: yAnim + target: root.target + property: "y" + to: target.y + velocity.y / duration * 100 + duration: root.duration + easing.type: Easing.OutQuad + } +} diff --git a/tests/manual/pointer/content/MouseFeedbackSprite.qml b/examples/quick/pointerhandlers/components/MouseFeedbackSprite.qml similarity index 90% rename from tests/manual/pointer/content/MouseFeedbackSprite.qml rename to examples/quick/pointerhandlers/components/MouseFeedbackSprite.qml index d3068ff5035..0fa2db3aa7d 100644 --- a/tests/manual/pointer/content/MouseFeedbackSprite.qml +++ b/examples/quick/pointerhandlers/components/MouseFeedbackSprite.qml @@ -1,9 +1,9 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the manual tests of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.12 +import QtQuick PointHandler { id: handler @@ -57,21 +57,21 @@ PointHandler { acceptedButtons: Qt.AllButtons target: Image { objectName: "mouse sprite" - source: "../resources/mouse.png" + source: "images/mouse.png" visible: handler.active x: handler.point.position.x - width / 2 y: handler.point.position.y - height / 2 parent: handler.parent Image { - source: "../resources/mouse_left.png" + source: "images/mouse_left.png" visible: handler.point.pressedButtons & Qt.LeftButton } Image { - source: "../resources/mouse_middle.png" + source: "images/mouse_middle.png" visible: handler.point.pressedButtons & Qt.MiddleButton } Image { - source: "../resources/mouse_right.png" + source: "images/mouse_right.png" visible: handler.point.pressedButtons & Qt.RightButton } } diff --git a/examples/quick/pointerhandlers/components/ScrollBar.qml b/examples/quick/pointerhandlers/components/ScrollBar.qml new file mode 100644 index 00000000000..0ed720eca05 --- /dev/null +++ b/examples/quick/pointerhandlers/components/ScrollBar.qml @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Rectangle { + id: root + property real contentHeight: 100 + property FakeFlickable flick: null + property real position + + onPositionChanged: if (flick && (drag.active || tap.active)) { + if (knob.state === "horizontal") + flick.contentX = position * knob.scrollDistance + else if (knob.state === "vertical") + flick.contentY = position * knob.scrollDistance + } + + color: palette.button + border.color: Qt.darker(palette.button, 1.5) + gradient: Gradient { + GradientStop { position: 0; color: Qt.darker(palette.button, 1.3) } + GradientStop { position: 1; color: palette.button } + } + antialiasing: true + radius: Math.min(width, height) / 6 + width: 20 + height: 20 + + TapHandler { + id: tap + onTapped: { + if (knob.state === "horizontal") + knob.x = position.x - knob.width / 2 + else if (knob.state === "vertical") + knob.y = position.y - knob.height / 2 + } + } + + Rectangle { + id: knob + border.color: "black" + border.width: 1 + gradient: Gradient { + GradientStop { position: 0; color: palette.button } + GradientStop { position: 1; color: Qt.darker(palette.button, 1.3) } + } + radius: 2 + antialiasing: true + state: root.height > root.width ? "vertical" : root.height < root.width ? "horizontal" : "" + property real scrollDistance: 0 + property real scrolledX: 0 + property real scrolledY: 0 + property real max: 0 + + Binding on x { + value: knob.scrolledX + when: !drag.active + } + + Binding on y { + value: knob.scrolledY + when: !drag.active + } + + states: [ + // We will control the horizontal. We will control the vertical. + State { + name: "horizontal" + PropertyChanges { + target: knob + max: root.width - knob.width + scrolledX: Math.min(max, Math.max(0, max * flick.contentX / (flick.width - flick.contentWidth))) + scrolledY: 1 + scrollDistance: flick.width - flick.contentWidth + width: flick.width * (flick.width / flick.contentWidth) - (height - anchors.margins) * 2 + height: root.height - 2 + } + PropertyChanges { + target: drag + xAxis.minimum: 0 + xAxis.maximum: knob.max + yAxis.minimum: 1 + yAxis.maximum: 1 + } + PropertyChanges { + target: root + position: knob.x / drag.xAxis.maximum + } + }, + State { + name: "vertical" + PropertyChanges { + target: knob + max: root.height - knob.height + scrolledX: 1 + scrolledY: Math.min(max, Math.max(0, max * flick.contentY / (flick.height - flick.contentHeight))) + scrollDistance: flick.height - flick.contentHeight + width: root.width - 2 + height: root.width - 2 + } + PropertyChanges { + target: drag + xAxis.minimum: 1 + xAxis.maximum: 1 + yAxis.minimum: 0 + yAxis.maximum: knob.max + } + PropertyChanges { + target: root + position: knob.y / drag.yAxis.maximum + } + } + ] + + DragHandler { + id: drag + } + } +} diff --git a/examples/quick/pointerhandlers/components/Slider.qml b/examples/quick/pointerhandlers/components/Slider.qml new file mode 100644 index 00000000000..0365d01149d --- /dev/null +++ b/examples/quick/pointerhandlers/components/Slider.qml @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import Qt.labs.animation + +Item { + id: root + property int value: 50 + property int maximumValue: 99 + property alias label: label.text + property alias tapEnabled: tap.enabled + property alias pressed: tap.pressed + signal tapped + + DragHandler { + id: dragHandler + objectName: label.text + " DragHandler" + target: knob + xAxis.enabled: false + } + + WheelHandler { + id: wheelHandler + objectName: label.text + " WheelHandler" + acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad + invertible: false // Don't let the system "natural scrolling" setting affect this + rotationScale: -0.5 // But make it go consistently in the same direction as the fingers or wheel, a bit slow + target: knob + property: "y" + } + + Rectangle { + id: slot + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.margins: 10 + anchors.topMargin: label.height + 6 + anchors.bottomMargin: valueLabel.height + 4 + anchors.horizontalCenter: parent.horizontalCenter + width: 10 + color: "black" + radius: width / 2 + smooth: true + } + + Rectangle { + // RectangularGlow is better, but that's a different module + id: glow + anchors.fill: knob + anchors.margins: -5 + anchors.leftMargin: -2 + anchors.horizontalCenterOffset: 1 + radius: 5 + color: "#4400FFFF" + opacity: tap.pressed || tapFlash.running ? 1 : 0 + FlashAnimation on visible { + id: tapFlash + } + } + Image { + id: knob + source: "images/mixer-knob.png" + antialiasing: true + x: slot.x - width / 2 + slot.width / 2 + height: root.width / 2 + width: implicitWidth / implicitHeight * height + property bool programmatic: false + property real multiplier: root.maximumValue / (ybr.maximum - ybr.minimum) + onYChanged: if (!programmatic) root.value = root.maximumValue - (knob.y - ybr.minimum) * multiplier + transformOrigin: Item.Center + function setValue(value) { knob.y = ybr.maximum - value / knob.multiplier } + TapHandler { + id: tap + objectName: label.text + " TapHandler" + gesturePolicy: TapHandler.DragThreshold + onTapped: { + tapFlash.start() + root.tapped + } + } + BoundaryRule on y { + id: ybr + minimum: slot.y + maximum: slot.height + slot.y - knob.height + } + } + + Text { + id: valueLabel + font.pointSize: 16 + color: "red" + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + text: root.value + } + + Text { + id: label + font.pointSize: 12 + color: "red" + anchors.top: parent.top + anchors.topMargin: 5 + anchors.horizontalCenter: parent.horizontalCenter + } + + onHeightChanged: { + knob.programmatic = true + knob.setValue(root.value) + knob.programmatic = false + } +} diff --git a/examples/quick/pointerhandlers/components/TouchpointFeedbackSprite.qml b/examples/quick/pointerhandlers/components/TouchpointFeedbackSprite.qml new file mode 100644 index 00000000000..d8e76c10461 --- /dev/null +++ b/examples/quick/pointerhandlers/components/TouchpointFeedbackSprite.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +PointHandler { + id: handler + objectName: "point " + handler.point.id.toString(16) + acceptedDevices: PointerDevice.TouchScreen | PointerDevice.TouchPad + target: AnimatedSprite { + objectName: "sprite " + handler.point.id.toString(16) + source: "images/fingersprite.png" + visible: handler.active + running: visible // QTBUG-64544: running defaults to true, but we don't see it animating if we don't toggle it like this + x: handler.point.position.x - 20 + y: handler.point.position.y - 13 + width: frameWidth + height: frameHeight + frameWidth: 43 + frameHeight: 64 + frameCount: 3 + frameRate: 5 + parent: handler.parent + } +} diff --git a/examples/quick/pointerhandlers/components/images/checkmark.png b/examples/quick/pointerhandlers/components/images/checkmark.png new file mode 100644 index 00000000000..821aafccdd7 Binary files /dev/null and b/examples/quick/pointerhandlers/components/images/checkmark.png differ diff --git a/examples/quick/pointerhandlers/components/images/fingersprite.png b/examples/quick/pointerhandlers/components/images/fingersprite.png new file mode 100644 index 00000000000..423d115fdfa Binary files /dev/null and b/examples/quick/pointerhandlers/components/images/fingersprite.png differ diff --git a/examples/quick/pointerhandlers/components/images/mixer-knob.png b/examples/quick/pointerhandlers/components/images/mixer-knob.png new file mode 100644 index 00000000000..b7d42ee3bd9 Binary files /dev/null and b/examples/quick/pointerhandlers/components/images/mixer-knob.png differ diff --git a/tests/manual/pointer/resources/mouse.png b/examples/quick/pointerhandlers/components/images/mouse.png similarity index 100% rename from tests/manual/pointer/resources/mouse.png rename to examples/quick/pointerhandlers/components/images/mouse.png diff --git a/tests/manual/pointer/resources/mouse_left.png b/examples/quick/pointerhandlers/components/images/mouse_left.png similarity index 100% rename from tests/manual/pointer/resources/mouse_left.png rename to examples/quick/pointerhandlers/components/images/mouse_left.png diff --git a/tests/manual/pointer/resources/mouse_middle.png b/examples/quick/pointerhandlers/components/images/mouse_middle.png similarity index 100% rename from tests/manual/pointer/resources/mouse_middle.png rename to examples/quick/pointerhandlers/components/images/mouse_middle.png diff --git a/tests/manual/pointer/resources/mouse_right.png b/examples/quick/pointerhandlers/components/images/mouse_right.png similarity index 100% rename from tests/manual/pointer/resources/mouse_right.png rename to examples/quick/pointerhandlers/components/images/mouse_right.png diff --git a/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-fakeflickable.jpg b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-fakeflickable.jpg new file mode 100644 index 00000000000..5149665a076 Binary files /dev/null and b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-fakeflickable.jpg differ diff --git a/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-fling.webp b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-fling.webp new file mode 100644 index 00000000000..4b8794971e6 Binary files /dev/null and b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-fling.webp differ diff --git a/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-joystick.jpg b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-joystick.jpg new file mode 100644 index 00000000000..c9d167b1e71 Binary files /dev/null and b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-joystick.jpg differ diff --git a/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-map.webp b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-map.webp new file mode 100644 index 00000000000..b96b0cf90a0 Binary files /dev/null and b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-map.webp differ diff --git a/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-mixer.webp b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-mixer.webp new file mode 100644 index 00000000000..f263458d120 Binary files /dev/null and b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-mixer.webp differ diff --git a/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-multibutton.webp b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-multibutton.webp new file mode 100644 index 00000000000..1d13805c64f Binary files /dev/null and b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-multibutton.webp differ diff --git a/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-pinchhandler.webp b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-pinchhandler.webp new file mode 100644 index 00000000000..89f61251ab8 Binary files /dev/null and b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-pinchhandler.webp differ diff --git a/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-pointhandler.webp b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-pointhandler.webp new file mode 100644 index 00000000000..1a0ac33d0c9 Binary files /dev/null and b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-pointhandler.webp differ diff --git a/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-taphandler.webp b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-taphandler.webp new file mode 100644 index 00000000000..162e97ea150 Binary files /dev/null and b/examples/quick/pointerhandlers/doc/images/pointerhandlers-example-taphandler.webp differ diff --git a/examples/quick/pointerhandlers/doc/src/pointerhandlers.qdoc b/examples/quick/pointerhandlers/doc/src/pointerhandlers.qdoc new file mode 100644 index 00000000000..7d19d472199 --- /dev/null +++ b/examples/quick/pointerhandlers/doc/src/pointerhandlers.qdoc @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example pointerhandlers + \title Pointer Handlers Example + \ingroup qtquickexamples + \meta tags {quick, input handlers} + \brief Shows how to use \l {Qt Quick Input Handlers} in interactive components. + + \l {Qt Quick Controls} contains pre-built components that are sufficient + for many kinds of user interfaces; but you may sometimes find a need to + write such components "from scratch". In that case, you will need to make + substantial use of Pointer Handlers. This is a collection of small examples + that show how to implement some common and less-common interaction patterns. + + If you build the example as an executable, you can choose pages from a + top-level ListView. The \c TouchpointFeedbackSprite and \c MouseFeedbackSprite + components show how to use PointHandler to provide feedback about what the + user is doing with the pointing devices: these components are always + visible throughout the example, and do not interfere with interaction + anywhere else. These components are handy for reuse if you ever need to do + a video or live demonstration of a user interface. + + Alternatively, some of the individual QML files can be run on the command + line with the \l {QML Runtime Tool}{qml tool}, as a quick reminder to see + how a particular kind of component can be built. + + \section1 TapHandler + + \image pointerhandlers-example-taphandler.webp + + The "tap" page shows how to detect touchscreen taps, long-presses, and + mouse clicks with different buttons. You can also try out the different + \l {TapHandler::}{gesturePolicy} values. + + \section2 Multi-tap Buttons + + On this page are three custom \c Button components, with different + \l {TapHandler::}{gesturePolicy} values: one button requires you + to keep your finger or mouse within the button during the whole time + from press to release; one will execute even if you drag outside + the button and then drag back in before releasing; and one will + exit its pressed state if you drag a little past the + \l {QStyleHints::startDragDistance}{system-wide drag threshold}. + If you try this example on a touchscreen, you should be able to interact + with all three buttons at the same time with different fingers. + + \image pointerhandlers-example-multibutton.webp + + \section1 PointHandler + + On the "single point handler" page, PointHandler provides feedback from + some of the properties that can be found in \l SinglePointHandler::point + and \l handlerPoint::device. If you have built the example as + an executable, you will see this feedback at the same time as the feedback + from the PointHandlers in the main pointerhandlers.qml file. + + \image pointerhandlers-example-pointhandler.webp + + The "tablet canvas" page uses PointHandler to uniquely detect different + \l {QPointingDevice::PointerType}{types of pointing devices}, so that if + you have a drawing tablet connected to your computer, you can draw on the + Canvas item with different types of stylus: pen, airbrush or marker. You + can "erase" strokes with the stylus eraser (done here by drawing on top + with the background color). Several \l {HoverHandler}{HoverHandlers} + provide feedback about which type of stylus or eraser is detected. + + \section1 HoverHandler + + The "hover sidebar" page shows how to detect when the mouse is hovering a + button component and its container at the same time. The propagation can be + disabled by setting the \l HoverHandler::blocking property. You can try out + all combinations of HoverHandler and MouseArea here, to compare how they + handle hover detection. And one more HoverHandler is used to show the + current mouse position in scene coordinates. + + You can also verify that the HoverHandler on the animated "platform" + is hovered whenever it slides under the mouse cursor. + + \section1 DragHandler + + The "joystick" page simply has a \l DragHandler dragging an \l Image. + A \l State with \l AnchorChanges unlocks the \l anchors so that dragging is + possible; and an \l AnchorAnimation animates the knob's return to the + center position when released. + + \image pointerhandlers-example-joystick.jpg + + The "fling animation" page demonstrates one use of the + DragHandler::centroid::velocity property, which simply makes the value from + QEventPoint::velocity() available in QML. The \c MomentumAnimation component + that is used in this example shows one way to simulate phyics (momentum and + friction) without resorting to heavier solutions. + + \image pointerhandlers-example-fling.webp + + \section1 PinchHandler + + The "pinch" page demonstrates multiple PinchHandlers: some require two + fingers and some require three, to perform the usual scaling, rotation and + translation, with constraints managed via PinchHandler's axis min and max + properties. One of the PinchHandler instances is used to manipulate + different \l Rectangle properties rather than position, scale and rotation. + Various PinchHandler properties are bound in various ways. You should be + able to manipulate each instance uniquely. Some items also have + DragHandlers and TapHandlers. + + \image pointerhandlers-example-pinchhandler.webp + + \section1 Interoperability + + \section2 Sliders + + The "mixer" page demonstrates the use of multiple handlers inside a + ListView delegate. You can interact with multiple \c Slider components + simultaneously, and you can flick the ListView sideways. + + \list + \li A DragHandler allows you to start dragging anywhere along the "track" + where the slider knob can slide. Because the default \l{DragHandler::}{snapMode} + is \c DragHandler.SnapAuto, the knob will \e snap into a position centered + under the mouse or touchpoint after you have dragged past the + \l {QStyleHints::startDragDistance}{system-wide drag threshold}. + + \li A WheelHandler directly adjusts the \c y property of the knob \l Image. + + \li A BoundaryRule prevents either the DragHandler or the WheelHandler from + dragging the knob too far. + + \li A TapHandler provides one more gesture than a typical \c Slider component + would have: you can tap on the knob. + \endlist + + \image pointerhandlers-example-mixer.webp + + \section2 Map + + The "map" page demonstrates dragging, transformation and re-scaling an + \l {Qt SVG}{SVG} \l Image. You should be able to zoom into a particular + location on the map; and if the zoom level is changed substantially, + \l Image::sourceSize is changed to request the SVG to be re-rendered at a + different resolution. Dragging vertically with two fingers activates a + DragHandler that manipulates a \l Rotation transform to tilt the map. + + \image pointerhandlers-example-map.webp + + \section2 Fake Flickable + + The "fake Flickable" page contains an attempt to reproduce much of the + functionality of \l Flickable using discrete pointer handlers and + animations. Flickable is a complex component, but here you can see one way + of separating the individual behaviors that it provides, in case you would + like to have only part of the functionality without the complexity. + + There's also a slide-out "drawer" component holding a few more + pointer-handler-powered controls. + + \image pointerhandlers-example-fakeflickable.jpg +*/ diff --git a/examples/quick/pointerhandlers/fakeFlickable.qml b/examples/quick/pointerhandlers/fakeFlickable.qml new file mode 100644 index 00000000000..0c07deedb7f --- /dev/null +++ b/examples/quick/pointerhandlers/fakeFlickable.qml @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "components" + +Rectangle { + id: root + color: "#444" + width: 480 + height: 640 + + FakeFlickable { + id: ff + anchors.fill: parent + anchors.leftMargin: 20 + anchors.rightMargin: rightSB.width + + Text { + id: text + color: "beige" + font.family: "mono" + font.pointSize: slider.value + onTextChanged: console.log("text geom " + width + "x" + height + + ", parent " + parent + " geom " + parent.width + "x" + parent.height) + } + + onFlickStarted: { + root.border.color = "green" + console.log("flick started with velocity " + velocity) + } + onFlickEnded: { + root.border.color = "transparent" + console.log("flick ended with velocity " + velocity) + } + + Component.onCompleted: { + var request = new XMLHttpRequest() + request.open('GET', 'components/FakeFlickable.qml') + request.onreadystatechange = function(event) { + if (request.readyState === XMLHttpRequest.DONE) + text.text = request.responseText + } + request.send() + } + } + + ScrollBar { + id: rightSB + objectName: "rightSB" + flick: ff + height: parent.height - width + anchors.right: parent.right + } + + ScrollBar { + id: bottomSB + objectName: "bottomSB" + flick: ff + width: parent.width - height + anchors.bottom: parent.bottom + } + + Rectangle { + id: cornerCover + color: "lightgray" + width: rightSB.width + height: bottomSB.height + anchors { + right: parent.right + bottom: parent.bottom + } + } + + LeftDrawer { + width: 100 + anchors.verticalCenter: parent.verticalCenter + Slider { + id: slider + label: "font\nsize" + anchors.fill: parent + anchors.margins: 10 + maximumValue: 36 + value: 14 + } + } +} diff --git a/examples/quick/pointerhandlers/flingAnimation.qml b/examples/quick/pointerhandlers/flingAnimation.qml new file mode 100644 index 00000000000..d3231ffc41e --- /dev/null +++ b/examples/quick/pointerhandlers/flingAnimation.qml @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "components" + +Rectangle { + id: root + width: 640 + height: 480 + color: "black" + + Repeater { + model: 2 + + Image { + id: ball + objectName: "ball" + index + source: "images/redball.png" + property real homeX: 200 + index * 200 + property real homeY: 200 + width: 80; height: 80; x: homeX; y: 200 + + Text { + anchors.centerIn: parent + color: "white" + text: momentum.velocity.x.toFixed(2) + "," + momentum.velocity.y.toFixed(2) + } + + SequentialAnimation { + id: anim + + function restart(vel) { + stop() + momentum.velocity = vel + start() + } + + MomentumAnimation { id: momentum; target: ball } + + PauseAnimation { duration: 500 } + + ParallelAnimation { + id: ballReturn + NumberAnimation { + target: ball + property: "x" + to: homeX + duration: 1000 + easing.period: 50 + easing.type: Easing.OutElastic + } + NumberAnimation { + target: ball + property: "y" + to: homeY + duration: 1000 + easing.type: Easing.OutElastic + } + } + } + + DragHandler { + id: dragHandler + objectName: "dragHandler" + index + onActiveChanged: { + if (!active) + anim.restart(centroid.velocity) + } + } + Rectangle { + visible: dragHandler.active + anchors.fill: parent + anchors.margins: -5 + radius: width / 2 + opacity: 0.25 + } + + Rectangle { + visible: width > 0 + width: dragHandler.centroid.velocity.length() / 10 + height: 2 + x: ball.width / 2 + y: ball.height / 2 + z: -1 + rotation: Math.atan2(dragHandler.centroid.velocity.y, dragHandler.centroid.velocity.x) * 180 / Math.PI + transformOrigin: Item.BottomLeft + antialiasing: true + + Image { + source: "images/arrowhead.png" + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + width: 16 + height: 12 + antialiasing: true + } + } + } + } +} diff --git a/tests/manual/pointer/resources/arrowhead.png b/examples/quick/pointerhandlers/images/arrowhead.png similarity index 100% rename from tests/manual/pointer/resources/arrowhead.png rename to examples/quick/pointerhandlers/images/arrowhead.png diff --git a/tests/manual/pointer/resources/balloon.png b/examples/quick/pointerhandlers/images/balloon.png similarity index 100% rename from tests/manual/pointer/resources/balloon.png rename to examples/quick/pointerhandlers/images/balloon.png diff --git a/tests/manual/pointer/resources/cursor-airbrush.png b/examples/quick/pointerhandlers/images/cursor-airbrush.png similarity index 100% rename from tests/manual/pointer/resources/cursor-airbrush.png rename to examples/quick/pointerhandlers/images/cursor-airbrush.png diff --git a/tests/manual/pointer/resources/cursor-eraser.png b/examples/quick/pointerhandlers/images/cursor-eraser.png similarity index 100% rename from tests/manual/pointer/resources/cursor-eraser.png rename to examples/quick/pointerhandlers/images/cursor-eraser.png diff --git a/tests/manual/pointer/resources/cursor-felt-marker.png b/examples/quick/pointerhandlers/images/cursor-felt-marker.png similarity index 100% rename from tests/manual/pointer/resources/cursor-felt-marker.png rename to examples/quick/pointerhandlers/images/cursor-felt-marker.png diff --git a/tests/manual/pointer/resources/cursor-pencil.png b/examples/quick/pointerhandlers/images/cursor-pencil.png similarity index 100% rename from tests/manual/pointer/resources/cursor-pencil.png rename to examples/quick/pointerhandlers/images/cursor-pencil.png diff --git a/tests/manual/pointer/resources/fighter.png b/examples/quick/pointerhandlers/images/fighter.png similarity index 100% rename from tests/manual/pointer/resources/fighter.png rename to examples/quick/pointerhandlers/images/fighter.png diff --git a/tests/manual/pointer/resources/grabbing-location.svg b/examples/quick/pointerhandlers/images/grabbing-location.svg similarity index 100% rename from tests/manual/pointer/resources/grabbing-location.svg rename to examples/quick/pointerhandlers/images/grabbing-location.svg diff --git a/tests/manual/pointer/resources/joystick-outer-case-pov.jpg b/examples/quick/pointerhandlers/images/joystick-outer-case-pov.jpg similarity index 100% rename from tests/manual/pointer/resources/joystick-outer-case-pov.jpg rename to examples/quick/pointerhandlers/images/joystick-outer-case-pov.jpg diff --git a/examples/quick/pointerhandlers/images/map.svgz b/examples/quick/pointerhandlers/images/map.svgz new file mode 100644 index 00000000000..64d509c1061 Binary files /dev/null and b/examples/quick/pointerhandlers/images/map.svgz differ diff --git a/tests/manual/pointer/resources/missile.png b/examples/quick/pointerhandlers/images/missile.png similarity index 100% rename from tests/manual/pointer/resources/missile.png rename to examples/quick/pointerhandlers/images/missile.png diff --git a/tests/manual/pointer/resources/redball.png b/examples/quick/pointerhandlers/images/redball.png similarity index 100% rename from tests/manual/pointer/resources/redball.png rename to examples/quick/pointerhandlers/images/redball.png diff --git a/examples/quick/pointerhandlers/joystick.qml b/examples/quick/pointerhandlers/joystick.qml new file mode 100644 index 00000000000..5433bf8be97 --- /dev/null +++ b/examples/quick/pointerhandlers/joystick.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Item { + width: image.implicitWidth; height: image.implicitHeight + Image { + id: image + anchors.centerIn: parent + source: "images/joystick-outer-case-pov.jpg" + property real margin: 50 + + Image { + id: knob + source: "images/redball.png" + DragHandler { + id: dragHandler + xAxis { + minimum: image.margin + maximum: image.width - image.margin - knob.width + } + yAxis { + minimum: image.margin + maximum: image.height - image.margin - knob.height + } + } + + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } + states: [ + State { + when: dragHandler.active + AnchorChanges { + target: knob + anchors.horizontalCenter: undefined + anchors.verticalCenter: undefined + } + } + ] + transitions: [ + Transition { + AnchorAnimation { easing.type: Easing.OutElastic } + } + ] + } + } +} diff --git a/examples/quick/pointerhandlers/main.cpp b/examples/quick/pointerhandlers/main.cpp new file mode 100644 index 00000000000..c2c98b96d6b --- /dev/null +++ b/examples/quick/pointerhandlers/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "../shared/shared.h" +DECLARATIVE_EXAMPLE_MAIN(pointerhandlers/pointerhandlers) diff --git a/examples/quick/pointerhandlers/map.qml b/examples/quick/pointerhandlers/map.qml new file mode 100644 index 00000000000..1a25a3b4ca5 --- /dev/null +++ b/examples/quick/pointerhandlers/map.qml @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Item { + width: 640 + height: 480 + + Rectangle { + id: map + color: "aqua" + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: image.width + height: image.height + transform: Rotation { + id: tilt + origin.x: width / 2 + origin.y: height / 2 + axis { x: 1; y: 0; z: 0 } + angle: tiltHandler.persistentTranslation.y / -2 + } + + WheelHandler { + id: wheelHandler + objectName: "vertical mouse wheel for scaling" + property: "scale" + onWheel: function(event) { + console.log("rotation " + event.angleDelta + " scaled " + rotation + " @ " + point.position + " => " + map.scale) + } + } + + WheelHandler { + id: horizontalWheelHandler + objectName: "horizontal mouse wheel for side-scrolling" + property: "x" + orientation: Qt.Horizontal + } + + Image { + id: image + anchors.centerIn: parent + fillMode: Image.PreserveAspectFit + source: "images/map.svgz" + Component.onCompleted: { width = implicitWidth; height = implicitHeight } + } + + Text { + anchors.centerIn: parent + text: image.sourceSize.width + " x " + image.sourceSize.height + + " scale " + map.scale.toFixed(2) + " active scale " + pinch.activeScale.toFixed(2) + } + } + + DragHandler { + objectName: "single-point drag" + target: map + } + + DragHandler { + id: tiltHandler + objectName: "two-point tilt" + minimumPointCount: 2 + maximumPointCount: 2 + xAxis.enabled: false + target: null + } + + PinchHandler { + id: pinch + objectName: "two-point pinch" + target: map + minimumScale: 0.1 + maximumScale: 10 + onActiveChanged: if (!active) reRenderIfNecessary() + grabPermissions: PinchHandler.TakeOverForbidden // don't allow takeover if pinch has started + } + + function reRenderIfNecessary() { + var newSourceWidth = image.sourceSize.width * pinch.scale + var ratio = newSourceWidth / image.sourceSize.width + if (ratio > 1.1 || ratio < 0.9) + image.sourceSize.width = newSourceWidth + } +} diff --git a/examples/quick/pointerhandlers/mixer.qml b/examples/quick/pointerhandlers/mixer.qml new file mode 100644 index 00000000000..73a39c58f27 --- /dev/null +++ b/examples/quick/pointerhandlers/mixer.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "components" + +Rectangle { + id: root + width: 1280 + height: 960 + objectName: "root" + color: "#222222" + + ListView { + id: list + objectName: "listView" + anchors.fill: parent + anchors.margins: 10 + orientation: Qt.Horizontal + + model: 20 + + delegate: Item { + objectName: "delegateItem" + index + width: 154 + height: list.height + + Slider { + anchors.fill: parent + label: "Channel " + (index + 1) + } + } + } +} diff --git a/examples/quick/pointerhandlers/multibuttons.qml b/examples/quick/pointerhandlers/multibuttons.qml new file mode 100644 index 00000000000..a3a4e21771e --- /dev/null +++ b/examples/quick/pointerhandlers/multibuttons.qml @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Particles +import QtQuick.Layouts +import "components" + +Item { + width: 800 + height: 800 + ColumnLayout { + anchors.right: parent.right + anchors.margins: 20 + spacing: 20 + Text { text: "protagonist"; font.pointSize: 12; font.weight: Font.Bold; bottomPadding: -10 } + Button { + id: balloonsButton + text: "Launch Balloons" + Layout.fillWidth: true + gesturePolicy: TapHandler.WithinBounds + Text { + anchors { top: parent.bottom; horizontalCenter: parent.horizontalCenter } + text: "gesturePolicy: WithinBounds" + } + } + Text { text: "the goons"; font.pointSize: 12; font.weight: Font.Bold; bottomPadding: -10 } + Button { + id: missilesButton + text: "Launch Missile" + Layout.fillWidth: true + gesturePolicy: TapHandler.ReleaseWithinBounds + onTapped: missileEmitter.burst(1) + Text { + anchors { top: parent.bottom; horizontalCenter: parent.horizontalCenter } + text: "gesturePolicy: ReleaseWithinBounds" + } + } + Button { + id: fightersButton + text: "Launch Fighters" + Layout.fillWidth: true + gesturePolicy: TapHandler.DragThreshold + Text { + anchors { top: parent.bottom; horizontalCenter: parent.horizontalCenter } + text: "gesturePolicy: DragThreshold" + } + } + } + ParticleSystem { + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.leftMargin: 150 + ImageParticle { source: "images/balloon.png" } + Emitter { anchors.bottom: parent.bottom; enabled: balloonsButton.pressed; lifeSpan: 5000; size: 64 + maximumEmitted: 99 + emitRate: 50; velocity: PointDirection { x: 10; y: -150; yVariation: 30; xVariation: 50 } } } + ParticleSystem { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + ImageParticle { source: "images/fighter.png" } + Emitter { anchors.bottom: parent.bottom; enabled: fightersButton.pressed; lifeSpan: 15000; size: 204 + emitRate: 3; velocity: PointDirection { x: -1000; y: -250; yVariation: 150; xVariation: 50 } } } + ParticleSystem { + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.rightMargin: 100 + ImageParticle { source: "images/missile.png"; autoRotation: true; rotation: 90 } + Emitter { id: missileEmitter; anchors.bottom: parent.bottom; lifeSpan: 5000; size: 128; + emitRate: 0; velocity: PointDirection { x: -200; y: -350; yVariation: 200; xVariation: 100 } } } +} diff --git a/tests/manual/pointer/pinchHandler.qml b/examples/quick/pointerhandlers/pinchHandler.qml similarity index 76% rename from tests/manual/pointer/pinchHandler.qml rename to examples/quick/pointerhandlers/pinchHandler.qml index 93169da60a8..74f0bd5209f 100644 --- a/tests/manual/pointer/pinchHandler.qml +++ b/examples/quick/pointerhandlers/pinchHandler.qml @@ -1,11 +1,11 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the manual tests of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,20 +14,42 @@ ** 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. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ -import QtQuick 2.12 -import "content" +import QtQuick +import "components" Rectangle { width: 1024; height: 600 @@ -65,10 +87,11 @@ Rectangle { minimumScale: 0.5 maximumScale: 3 minimumPointCount: 3 + maximumPointCount: 6 // mutants are allowed; using both hands is not normal for a pinch gesture, but we can't tell } Text { - text: "Pinch with 3 fingers to scale, rotate and translate" + text: "Pinch with 3 or more fingers to scale, rotate and translate" + getTransformationDetails(parent, grandparentPinch) } diff --git a/examples/quick/pointerhandlers/pointerhandlers.qml b/examples/quick/pointerhandlers/pointerhandlers.qml new file mode 100644 index 00000000000..ba3eb27132a --- /dev/null +++ b/examples/quick/pointerhandlers/pointerhandlers.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import shared as Examples +import "components" + +Rectangle { + id: window + width: 800 + height: 800 + visible: true + Examples.LauncherList { + id: ll + objectName: "LauncherList" + anchors.fill: parent + Component.onCompleted: { + addExample("tap", "TapHandler: device-agnostic tap/click detection for buttons", Qt.resolvedUrl("tapHandler.qml")) + addExample("multibuttons", "TapHandler: gesturePolicy (99 red balloons)", Qt.resolvedUrl("multibuttons.qml")) + addExample("single point handler", "PointHandler: properties such as seat, device, modifiers, velocity, pressure", Qt.resolvedUrl("singlePointHandlerProperties.qml")) + addExample("hover sidebar", "HoverHandler: a hierarchy of items sharing the hover state", Qt.resolvedUrl("sidebar.qml")) + addExample("joystick", "DragHandler: move one item inside another with any pointing device", Qt.resolvedUrl("joystick.qml")) + addExample("mixer", "DragHandler: drag multiple sliders with multiple fingers", Qt.resolvedUrl("mixer.qml")) + addExample("fling animation", "DragHandler: after dragging, use an animation to simulate momentum", Qt.resolvedUrl("flingAnimation.qml")) + addExample("pinch", "PinchHandler: scale, rotate and drag", Qt.resolvedUrl("pinchHandler.qml")) + addExample("map", "scale, pan, re-render at different resolutions", Qt.resolvedUrl("map.qml")) + addExample("fake Flickable", "implementation of a simplified Flickable using only Items, DragHandler and MomentumAnimation", Qt.resolvedUrl("fakeFlickable.qml")) + addExample("tablet canvas", "PointHandler and HoverHandler with a tablet: detect the stylus, and draw", Qt.resolvedUrl("tabletCanvasDrawing.qml")) + } + } + Item { + id: glassPane + objectName: "glassPane" + z: 10000 + anchors.fill: parent + + // TODO use Instantiator to create these... but we need to be able to set their parents to glassPane somehow (QTBUG-64546) + TouchpointFeedbackSprite { } + TouchpointFeedbackSprite { } + TouchpointFeedbackSprite { } + TouchpointFeedbackSprite { } + TouchpointFeedbackSprite { } + TouchpointFeedbackSprite { } + + MouseFeedbackSprite { } + } +} diff --git a/examples/quick/pointerhandlers/qml.qrc b/examples/quick/pointerhandlers/qml.qrc new file mode 100644 index 00000000000..39164527de7 --- /dev/null +++ b/examples/quick/pointerhandlers/qml.qrc @@ -0,0 +1,47 @@ + + + flingAnimation.qml + fakeFlickable.qml + flickablesWithHandlers.qml + joystick.qml + map.qml + mixer.qml + multibuttons.qml + photosurface.qml + pinchHandler.qml + pointerDrag.qml + pointerhandlers.qml + singlePointHandlerProperties.qml + sidebar.qml + tabletCanvasDrawing.qml + tapHandler.qml + components/Button.qml + components/CheckBox.qml + components/FakeFlickable.qml + components/FlashAnimation.qml + components/LeftDrawer.qml + components/MomentumAnimation.qml + components/ScrollBar.qml + components/Slider.qml + components/TouchpointFeedbackSprite.qml + images/arrowhead.png + images/balloon.png + components/images/checkmark.png + images/cursor-airbrush.png + images/cursor-eraser.png + images/cursor-felt-marker.png + images/cursor-pencil.png + images/fighter.png + components/images/fingersprite.png + images/grabbing-location.svg + images/joystick-outer-case-pov.jpg + images/map.svgz + images/missile.png + components/images/mixer-knob.png + components/images/mouse.png + components/images/mouse_left.png + components/images/mouse_middle.png + components/images/mouse_right.png + images/redball.png + + diff --git a/examples/quick/pointerhandlers/sidebar.qml b/examples/quick/pointerhandlers/sidebar.qml new file mode 100644 index 00000000000..a5e1256d0f4 --- /dev/null +++ b/examples/quick/pointerhandlers/sidebar.qml @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "components" + +Rectangle { + id: root + width: 640 + height: 480 + color: "#444" + + Component { + id: buttonsAndStuff + Column { + anchors.fill: parent + anchors.margins: 8 + spacing: 8 + + Rectangle { + objectName: "buttonWithMA" + width: parent.width + height: 30 + color: buttonMA.pressed ? "lightsteelblue" : "#999" + border.color: buttonMA.containsMouse ? "cyan" : "transparent" + + MouseArea { + id: buttonMA + objectName: "buttonMA" + hoverEnabled: true + cursorShape: Qt.UpArrowCursor + anchors.fill: parent + onClicked: console.log("clicked MA") + } + + Text { + anchors.centerIn: parent + text: "MouseArea" + } + } + + Rectangle { + objectName: "buttonWithHH" + width: parent.width + height: 30 + color: flash ? "#999" : "white" + border.color: buttonHH.hovered ? "cyan" : "transparent" + property bool flash: true + + HoverHandler { + id: buttonHH + objectName: "buttonHH" + acceptedDevices: PointerDevice.AllDevices + cursorShape: tapHandler.pressed ? Qt.BusyCursor : Qt.PointingHandCursor + } + + TapHandler { + id: tapHandler + onTapped: tapFlash.start() + } + + Text { + anchors.centerIn: parent + text: "HoverHandler" + } + + FlashAnimation on flash { + id: tapFlash + } + } + } + } + + Rectangle { + id: paddle + width: 100 + height: 40 + color: paddleHH.hovered ? "indianred" : "#888" + y: parent.height - 100 + radius: 10 + + HoverHandler { + id: paddleHH + objectName: "paddleHH" + } + + SequentialAnimation on x { + NumberAnimation { + to: root.width - paddle.width + duration: 2000 + easing { type: Easing.InOutQuad } + } + PauseAnimation { duration: 100 } + NumberAnimation { + to: 0 + duration: 2000 + easing { type: Easing.InOutQuad } + } + PauseAnimation { duration: 100 } + loops: Animation.Infinite + } + } + + Rectangle { + objectName: "topSidebar" + radius: 5 + antialiasing: true + x: -radius + y: -radius + width: 120 + height: 200 + border.color: topSidebarHH.hovered ? "cyan" : "black" + color: "#777" + + Rectangle { + color: "cyan" + width: 10 + height: width + radius: width / 2 + visible: topSidebarHH.hovered + x: topSidebarHH.point.position.x - width / 2 + y: topSidebarHH.point.position.y - height / 2 + z: 100 + } + + HoverHandler { + id: topSidebarHH + objectName: "topSidebarHH" + cursorShape: Qt.OpenHandCursor + } + + Loader { + objectName: "topSidebarLoader" + sourceComponent: buttonsAndStuff + anchors.fill: parent + } + } + + Rectangle { + objectName: "bottomSidebar" + radius: 5 + antialiasing: true + x: -radius + anchors.bottom: parent.bottom + anchors.bottomMargin: -radius + width: 120 + height: 200 + border.color: bottomSidebarMA.containsMouse ? "cyan" : "black" + color: "#777" + + MouseArea { + id: bottomSidebarMA + objectName: "bottomSidebarMA" + hoverEnabled: true + cursorShape: Qt.ClosedHandCursor + anchors.fill: parent + + Loader { + objectName: "bottomSidebarLoader" + sourceComponent: buttonsAndStuff + anchors.fill: parent + } + } + } + + HoverHandler { + id: rootHover + } + + Text { + anchors.right: parent.right + color: "cyan" + text: "scene " + rootHover.point.scenePosition.x.toFixed(1) + ", " + rootHover.point.scenePosition.y.toFixed(1) + } +} diff --git a/examples/quick/pointerhandlers/singlePointHandlerProperties.qml b/examples/quick/pointerhandlers/singlePointHandlerProperties.qml new file mode 100644 index 00000000000..a04bf0fe6cf --- /dev/null +++ b/examples/quick/pointerhandlers/singlePointHandlerProperties.qml @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Rectangle { + id: root + width: 480 + height: 480 + color: "black" + + Item { + id: crosshairs + x: pointHandler.point.position.x - width / 2 + y: pointHandler.point.position.y - height / 2 + width: parent.width / 2; height: parent.height / 2 + visible: pointHandler.active + rotation: pointHandler.point.rotation + + Rectangle { + color: "goldenrod" + anchors.centerIn: parent + width: 2; height: parent.height + antialiasing: true + } + Rectangle { + color: "goldenrod" + anchors.centerIn: parent + width: parent.width; height: 2 + antialiasing: true + } + Rectangle { + color: "goldenrod" + width: Math.max(2, 50 * pointHandler.point.pressure) + height: width + radius: width / 2 + anchors.centerIn: parent + antialiasing: true + Rectangle { + y: -56 + anchors.horizontalCenter: parent.horizontalCenter + color: "lightsteelblue" + implicitWidth: label.implicitWidth + implicitHeight: label.implicitHeight + Text { + id: label + text: 'seat: ' + pointHandler.point.device.seatName + '\ndevice: ' + pointHandler.point.device.name + + '\nid: ' + pointHandler.point.id.toString(16) + " uid: " + pointHandler.point.uniqueId.numericId + + '\npos: (' + pointHandler.point.position.x.toFixed(2) + ', ' + pointHandler.point.position.y.toFixed(2) + ')' + + '\nmodifiers: ' + pointHandler.point.modifiers.toString(16) + } + } + } + Rectangle { + color: "transparent" + border.color: "white" + antialiasing: true + width: pointHandler.point.ellipseDiameters.width + height: pointHandler.point.ellipseDiameters.height + radius: Math.min(width / 2, height / 2) + anchors.centerIn: parent + } + } + Rectangle { + id: velocityVector + visible: width > 0 + width: pointHandler.point.velocity.length() / 10 + height: 2 + x: pointHandler.point.position.x + y: pointHandler.point.position.y + rotation: Math.atan2(pointHandler.point.velocity.y, pointHandler.point.velocity.x) * 180 / Math.PI + transformOrigin: Item.BottomLeft + antialiasing: true + + Image { + source: "images/arrowhead.png" + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + width: 16 + height: 12 + antialiasing: true + } + } + + Component { + id: grabbingLocationIndicator + Image { + source: "components/images/grabbing-location.svg" + sourceSize.width: 32 + sourceSize.height: 32 + } + } + + Component { + id: mouseButtonIndicator + Image { + property int buttons + source: "components/images/mouse.png" + Image { + source: "components/images/mouse_left.png" + visible: buttons & Qt.LeftButton + } + Image { + source: "components/images/mouse_middle.png" + visible: buttons & Qt.MiddleButton + } + Image { + source: "components/images/mouse_right.png" + visible: buttons & Qt.RightButton + } + } + } + + PointHandler { + id: pointHandler + target: null + acceptedButtons: Qt.AllButtons + onGrabChanged: function(transition, point) { + if (active) { + console.log("grabbed " + point.pointId + " @ " + point.sceneGrabPos) + grabbingLocationIndicator.createObject(root, {"x": point.sceneGrabPosition.x, "y": point.sceneGrabPosition.y - 16}) + } + } + onPointChanged: { + if (point.pressedButtons) + mouseButtonIndicator.createObject(root, {"x": point.pressPosition.x - 44, "y": point.pressPosition.y - 64, "buttons": point.pressedButtons}) + } + } + + Text { + color: "white" + text: "drag to see feedback" + anchors { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + margins: 6 + } + } +} diff --git a/tests/manual/pointer/tabletCanvasDrawing.qml b/examples/quick/pointerhandlers/tabletCanvasDrawing.qml similarity index 93% rename from tests/manual/pointer/tabletCanvasDrawing.qml rename to examples/quick/pointerhandlers/tabletCanvasDrawing.qml index c340dee5f47..36630f16aad 100644 --- a/tests/manual/pointer/tabletCanvasDrawing.qml +++ b/examples/quick/pointerhandlers/tabletCanvasDrawing.qml @@ -1,9 +1,9 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the manual tests of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage @@ -48,9 +48,9 @@ ** ****************************************************************************/ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import "content" +import QtQuick +import QtQuick.Layouts +import "components" Rectangle { width: 1024 @@ -165,6 +165,15 @@ Rectangle { } } + Text { + text: "draw with a drawing-tablet stylus" + anchors { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + margins: 6 + } + } + PointHandler { acceptedPointerTypes: PointerDevice.Pen onActiveChanged: @@ -206,7 +215,7 @@ Rectangle { target: Image { parent: rect source: stylusHandler.point.rotation === 0 ? - "resources/cursor-pencil.png" : "resources/cursor-felt-marker.png" + "images/cursor-pencil.png" : "images/cursor-felt-marker.png" visible: stylusHandler.hovered rotation: stylusHandler.point.rotation x: stylusHandler.point.position.x @@ -220,7 +229,7 @@ Rectangle { acceptedPointerTypes: PointerDevice.Pen target: Image { parent: rect - source: "resources/cursor-airbrush.png" + source: "images/cursor-airbrush.png" visible: airbrushHandler.hovered x: airbrushHandler.point.position.x y: airbrushHandler.point.position.y @@ -232,7 +241,7 @@ Rectangle { acceptedPointerTypes: PointerDevice.Eraser target: Image { parent: rect - source: "resources/cursor-eraser.png" + source: "images/cursor-eraser.png" visible: eraserHandler.hovered x: eraserHandler.point.position.x y: eraserHandler.point.position.y - 32 diff --git a/examples/quick/pointerhandlers/tapHandler.qml b/examples/quick/pointerhandlers/tapHandler.qml new file mode 100644 index 00000000000..90cf778eded --- /dev/null +++ b/examples/quick/pointerhandlers/tapHandler.qml @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "components" + +Item { + width: 800 + height: 480 + + Rectangle { + id: rect + anchors.fill: parent; anchors.margins: 40 + border.width: 3; border.color: "transparent" + color: handler.pressed ? "lightsteelblue" : "darkgrey" + + TapHandler { + id: handler + acceptedButtons: (leftAllowedCB.checked ? Qt.LeftButton : Qt.NoButton) | + (middleAllowedCB.checked ? Qt.MiddleButton : Qt.NoButton) | + (rightAllowedCB.checked ? Qt.RightButton : Qt.NoButton) + gesturePolicy: (policyDragThresholdCB.checked ? TapHandler.DragThreshold : + policyWithinBoundsCB.checked ? TapHandler.WithinBounds : + TapHandler.ReleaseWithinBounds) + + onCanceled: { + console.log("canceled @ " + point.position) + borderBlink.blinkColor = "red" + borderBlink.start() + } + onTapped: function(point, button) { + console.log("tapped button " + button + " @ " + point.scenePosition + + " on device '" + point.device.name + "' with modifiers " + handler.point.modifiers + + " " + (tapCount > 1 ? (tapCount + " times") : "for the first time")) + if (tapCount > 1) { + tapCountLabel.text = tapCount + flashAnimation.start() + } else { + borderBlink.tapFeedback(button) + } + } + onLongPressed: longPressFeedback.createObject(rect, + {"x": point.position.x, "y": point.position.y, + "text": "long press after\n" + handler.timeHeld.toFixed(3) + " sec", + "color": buttonToBlinkColor(point.pressedButtons)}) + } + + Text { + id: tapCountLabel + anchors.centerIn: parent + font.pixelSize: 72 + font.weight: Font.Black + SequentialAnimation { + id: flashAnimation + PropertyAction { target: tapCountLabel; property: "visible"; value: true } + PropertyAction { target: tapCountLabel; property: "opacity"; value: 1.0 } + PropertyAction { target: tapCountLabel; property: "scale"; value: 1.0 } + ParallelAnimation { + NumberAnimation { + target: tapCountLabel + property: "opacity" + to: 0 + duration: 500 + } + NumberAnimation { + target: tapCountLabel + property: "scale" + to: 1.5 + duration: 500 + } + } + } + } + + Rectangle { + id: expandingCircle + radius: handler.timeHeld * 100 + visible: radius > 0 && handler.pressed + border.width: 3 + border.color: buttonToBlinkColor(handler.point.pressedButtons) + color: "transparent" + width: radius * 2 + height: radius * 2 + x: handler.point.pressPosition.x - radius + y: handler.point.pressPosition.y - radius + opacity: 0.25 + } + + Component { + id: longPressFeedback + Text { } + } + + SequentialAnimation { + id: borderBlink + property color blinkColor: "red" + function tapFeedback(button) { + blinkColor = buttonToBlinkColor(button); + start(); + } + loops: 3 + ScriptAction { script: rect.border.color = borderBlink.blinkColor } + PauseAnimation { duration: 100 } + ScriptAction { script: rect.border.color = "transparent" } + PauseAnimation { duration: 100 } + } + + Text { + text: "tap, click with different buttons, double-click, long press in this area" + anchors { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + margins: 6 + } + } + } + + function buttonToBlinkColor(button) { + switch (button) { + case Qt.MiddleButton: return "orange"; + case Qt.RightButton: return "magenta"; + default: return "green"; + } + } + + Row { + spacing: 6 + Text { + text: "accepted mouse clicks:" + anchors.verticalCenter: leftAllowedCB.verticalCenter + } + CheckBox { + id: leftAllowedCB + checked: true + text: "left" + } + CheckBox { + id: middleAllowedCB + text: "middle" + } + CheckBox { + id: rightAllowedCB + text: "right" + } + Text { + text: " gesture policy:" + anchors.verticalCenter: leftAllowedCB.verticalCenter + } + CheckBox { + id: policyDragThresholdCB + text: "drag threshold" + onCheckedChanged: if (checked) { + policyWithinBoundsCB.checked = false; + policyReleaseWithinBoundsCB.checked = false; + } + } + CheckBox { + id: policyWithinBoundsCB + text: "within bounds" + onCheckedChanged: if (checked) { + policyDragThresholdCB.checked = false; + policyReleaseWithinBoundsCB.checked = false; + } + } + CheckBox { + id: policyReleaseWithinBoundsCB + checked: true + text: "release within bounds" + onCheckedChanged: if (checked) { + policyDragThresholdCB.checked = false; + policyWithinBoundsCB.checked = false; + } + } + } +} diff --git a/examples/quick/pointerhandlers/tapWithModifiers.qml b/examples/quick/pointerhandlers/tapWithModifiers.qml new file mode 100644 index 00000000000..a38be819be7 --- /dev/null +++ b/examples/quick/pointerhandlers/tapWithModifiers.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Item { + width: 200 + height: 200 + TapHandler { + acceptedModifiers: Qt.ControlModifier + onTapped: console.log("control-tapped") + } + TapHandler { + acceptedModifiers: Qt.NoModifier + onTapped: console.log("tapped with no modifiers") + } + TapHandler { + onTapped: + switch (point.modifiers) { + case Qt.ControlModifier | Qt.AltModifier: + console.log("CTRL+ALT"); + break; + case Qt.ControlModifier | Qt.AltModifier | Qt.MetaModifier: + console.log("CTRL+META+ALT"); + break; + default: + console.log("other modifiers", point.modifiers) + } + } +} diff --git a/examples/quick/positioners/CMakeLists.txt b/examples/quick/positioners/CMakeLists.txt index 572f53e56cd..e1c96393261 100644 --- a/examples/quick/positioners/CMakeLists.txt +++ b/examples/quick/positioners/CMakeLists.txt @@ -1,13 +1,12 @@ # Generated from positioners.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(positioners LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,68 +14,36 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/positioners") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) -qt_add_executable(positioners +add_subdirectory("../shared" "shared") + +qt_add_executable(positionersexample + WIN32 + MACOSX_BUNDLE main.cpp ) -set_target_properties(positioners PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE + +qt_add_qml_module(positionersexample + URI positioners + VERSION 1.0 + QML_FILES + "positioners-attachedproperties.qml" + "positioners-transitions.qml" + "positioners.qml" ) -target_link_libraries(positioners PUBLIC + +target_link_libraries(positionersexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) - -# Resources: -set(positioners_resource_files - "positioners-attachedproperties.qml" - "positioners-transitions.qml" - "positioners.qml" -) - -qt6_add_resources(positioners "positioners" - PREFIX - "/positioners" - FILES - ${positioners_resource_files} -) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(positioners "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} -) - -install(TARGETS positioners +install(TARGETS positionersexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) + +bundle_shared(positionersexample) diff --git a/examples/quick/positioners/positioners-attachedproperties.qml b/examples/quick/positioners/positioners-attachedproperties.qml index af89543289c..41f09c978cc 100644 --- a/examples/quick/positioners/positioners-attachedproperties.qml +++ b/examples/quick/positioners/positioners-attachedproperties.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Controls 1.1 +import QtQuick +import QtQuick.Controls Rectangle { id: page @@ -90,14 +90,14 @@ Rectangle { anchors.leftMargin: 20 anchors.verticalCenter: parent.verticalCenter text: "Index: " + parent.Positioner.index - + (parent.Positioner.isFirstItem ? " (First)" : "") - + (parent.Positioner.isLastItem ? " (Last)" : "") + + (parent.Positioner.isFirstItem ? " (First)" : "") + + (parent.Positioner.isLastItem ? " (Last)" : "") } // When mouse is clicked, display the values of the positioner MouseArea { - anchors.fill: parent - onClicked: column.showInfo(green.Positioner) + anchors.fill: parent + onClicked: column.showInfo(green.Positioner) } } //! [0] @@ -113,14 +113,14 @@ Rectangle { anchors.leftMargin: 20 anchors.verticalCenter: parent.verticalCenter text: "Index: " + parent.Positioner.index - + (parent.Positioner.isFirstItem ? " (First)" : "") - + (parent.Positioner.isLastItem ? " (Last)" : "") + + (parent.Positioner.isFirstItem ? " (First)" : "") + + (parent.Positioner.isLastItem ? " (Last)" : "") } // When mouse is clicked, display the values of the positioner MouseArea { - anchors.fill: parent - onClicked: column.showInfo(blue.Positioner) + anchors.fill: parent + onClicked: column.showInfo(blue.Positioner) } } @@ -135,14 +135,14 @@ Rectangle { anchors.leftMargin: 20 anchors.verticalCenter: parent.verticalCenter text: "Index: " + parent.Positioner.index - + (parent.Positioner.isFirstItem ? " (First)" : "") - + (parent.Positioner.isLastItem ? " (Last)" : "") + + (parent.Positioner.isFirstItem ? " (First)" : "") + + (parent.Positioner.isLastItem ? " (Last)" : "") } // When mouse is clicked, display the values of the positioner MouseArea { - anchors.fill: parent - onClicked: column.showInfo(purple.Positioner) + anchors.fill: parent + onClicked: column.showInfo(purple.Positioner) } } @@ -159,8 +159,8 @@ Rectangle { anchors.leftMargin: 20 anchors.verticalCenter: parent.verticalCenter text: "Index: " + parent.Positioner.index - + (parent.Positioner.isFirstItem ? " (First)" : "") - + (parent.Positioner.isLastItem ? " (Last)" : "") + + (parent.Positioner.isFirstItem ? " (First)" : "") + + (parent.Positioner.isLastItem ? " (Last)" : "") } } diff --git a/examples/quick/positioners/positioners-transitions.qml b/examples/quick/positioners/positioners-transitions.qml index d4f3772c4e0..bfc9bafa172 100644 --- a/examples/quick/positioners/positioners-transitions.qml +++ b/examples/quick/positioners/positioners-transitions.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQml 2.0 -import QtQuick 2.0 +import QtQml +import QtQuick Item { id: page diff --git a/examples/quick/positioners/positioners.qml b/examples/quick/positioners/positioners.qml index b16df6858b6..37b3b8dfd4d 100644 --- a/examples/quick/positioners/positioners.qml +++ b/examples/quick/positioners/positioners.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "../shared" as Examples +import QtQuick +import shared as Examples Item { height: 480 diff --git a/examples/quick/quick-accessibility/content/Button.qml b/examples/quick/quick-accessibility/Button.qml similarity index 100% rename from examples/quick/quick-accessibility/content/Button.qml rename to examples/quick/quick-accessibility/Button.qml diff --git a/examples/quick/quick-accessibility/CMakeLists.txt b/examples/quick/quick-accessibility/CMakeLists.txt index ae216735a29..04189a77a3a 100644 --- a/examples/quick/quick-accessibility/CMakeLists.txt +++ b/examples/quick/quick-accessibility/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from quick-accessibility.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(quick-accessibility LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -34,20 +34,14 @@ target_link_libraries(quick-accessibility PUBLIC Qt::Quick ) - -# Resources: -set(accessibility_resource_files - "accessibility.qml" - "content/Button.qml" - "content/Checkbox.qml" - "content/Slider.qml" -) - -qt6_add_resources(quick-accessibility "accessibility" - PREFIX - "/accessibility" - FILES - ${accessibility_resource_files} +qt_add_qml_module(quick-accessibility + URI accessibility + VERSION 1.0 + QML_FILES + "accessibility.qml" + "Button.qml" + "Checkbox.qml" + "Slider.qml" ) install(TARGETS quick-accessibility diff --git a/examples/quick/quick-accessibility/content/Checkbox.qml b/examples/quick/quick-accessibility/Checkbox.qml similarity index 100% rename from examples/quick/quick-accessibility/content/Checkbox.qml rename to examples/quick/quick-accessibility/Checkbox.qml diff --git a/examples/quick/quick-accessibility/content/Slider.qml b/examples/quick/quick-accessibility/Slider.qml similarity index 100% rename from examples/quick/quick-accessibility/content/Slider.qml rename to examples/quick/quick-accessibility/Slider.qml diff --git a/examples/quick/quick-accessibility/accessibility.qml b/examples/quick/quick-accessibility/accessibility.qml index d3365cdd127..5caee3439ee 100644 --- a/examples/quick/quick-accessibility/accessibility.qml +++ b/examples/quick/quick-accessibility/accessibility.qml @@ -48,8 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "content" +import QtQuick Rectangle { id: window diff --git a/examples/quick/quick-accessibility/accessibility.qrc b/examples/quick/quick-accessibility/accessibility.qrc index 462a9a590ce..f106d551c80 100644 --- a/examples/quick/quick-accessibility/accessibility.qrc +++ b/examples/quick/quick-accessibility/accessibility.qrc @@ -1,8 +1,8 @@ accessibility.qml - content/Button.qml - content/Checkbox.qml - content/Slider.qml + Button.qml + Checkbox.qml + Slider.qml diff --git a/examples/quick/quick-accessibility/doc/src/accessibility.qdoc b/examples/quick/quick-accessibility/doc/src/accessibility.qdoc index b31db0d3138..1b7a0d8d76e 100644 --- a/examples/quick/quick-accessibility/doc/src/accessibility.qdoc +++ b/examples/quick/quick-accessibility/doc/src/accessibility.qdoc @@ -40,7 +40,7 @@ The button identifies itself and its functionality to the accessibility system: - \snippet quick-accessibility/content/Button.qml button + \snippet quick-accessibility/Button.qml button Similarly, \l Text types inside the example also identify themselves: \snippet quick-accessibility/accessibility.qml text diff --git a/examples/quick/quickwidgets/qquickviewcomparison/CMakeLists.txt b/examples/quick/quickwidgets/qquickviewcomparison/CMakeLists.txt index 408bfb0ad27..428f7b53a36 100644 --- a/examples/quick/quickwidgets/qquickviewcomparison/CMakeLists.txt +++ b/examples/quick/quickwidgets/qquickviewcomparison/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from qquickviewcomparison.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(qquickviewcomparison LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -20,6 +20,7 @@ find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Quick) find_package(Qt6 COMPONENTS Widgets) find_package(Qt6 COMPONENTS QuickWidgets) +find_package(Qt6 COMPONENTS ShaderTools) qt_add_executable(qquickviewcomparison fbitem.cpp fbitem.h @@ -39,17 +40,21 @@ target_link_libraries(qquickviewcomparison PUBLIC Qt::Widgets ) - -# Resources: -set(qquickviewcomparison_resource_files - "test.qml" +qt_add_qml_module(qquickviewcomparison + URI fbitem + VERSION 1.0 + QML_FILES test.qml + RESOURCE_PREFIX /qquickviewcomparison + NO_RESOURCE_TARGET_PATH ) -qt6_add_resources(qquickviewcomparison "qquickviewcomparison" +qt6_add_shaders(qquickviewcomparison "shaders" + PRECOMPILE + OPTIMIZED PREFIX "/qquickviewcomparison" FILES - ${qquickviewcomparison_resource_files} + "wobble.frag" ) install(TARGETS qquickviewcomparison @@ -57,10 +62,3 @@ install(TARGETS qquickviewcomparison BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(qquickviewcomparison PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI fbitem -) - -qt6_qml_type_registration(qquickviewcomparison) diff --git a/examples/quick/quickwidgets/qquickviewcomparison/main.cpp b/examples/quick/quickwidgets/qquickviewcomparison/main.cpp index e40c509829c..c0a26eefba6 100644 --- a/examples/quick/quickwidgets/qquickviewcomparison/main.cpp +++ b/examples/quick/quickwidgets/qquickviewcomparison/main.cpp @@ -61,7 +61,7 @@ int main(int argc, char **argv) QApplication app(argc, argv); // this example and QQuickWidget are only functional when rendering with OpenGL - QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi); + QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); QCoreApplication::setApplicationName("Qt QQuickView/QQuickWidget Comparison Example"); QCoreApplication::setOrganizationName("QtProject"); diff --git a/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.qrc b/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.qrc index 2b259fdeec4..e545c993c06 100644 --- a/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.qrc +++ b/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.qrc @@ -1,5 +1,6 @@ test.qml + wobble.frag.qsb diff --git a/examples/quick/quickwidgets/qquickviewcomparison/test.qml b/examples/quick/quickwidgets/qquickviewcomparison/test.qml index e142add0845..82243205093 100644 --- a/examples/quick/quickwidgets/qquickviewcomparison/test.qml +++ b/examples/quick/quickwidgets/qquickviewcomparison/test.qml @@ -213,16 +213,6 @@ Rectangle { property real frequency: 10 property real time: 0 NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 1000 } - fragmentShader: - "uniform lowp float qt_Opacity;" + - "uniform highp float amplitude;" + - "uniform highp float frequency;" + - "uniform highp float time;" + - "uniform sampler2D source;" + - "varying highp vec2 qt_TexCoord0;" + - "void main() {" + - " highp vec2 p = sin(time + frequency * qt_TexCoord0);" + - " gl_FragColor = texture2D(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity;" + - "}" + fragmentShader: "wobble.frag.qsb" } } diff --git a/examples/quick/quickwidgets/qquickviewcomparison/wobble.frag b/examples/quick/quickwidgets/qquickviewcomparison/wobble.frag new file mode 100644 index 00000000000..9fddf1a162f --- /dev/null +++ b/examples/quick/quickwidgets/qquickviewcomparison/wobble.frag @@ -0,0 +1,20 @@ +#version 440 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(binding = 1) uniform sampler2D source; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float amplitude; + float frequency; + float time; +}; + +void main() +{ + vec2 p = sin(time + frequency * qt_TexCoord0); + fragColor = texture(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity; +} diff --git a/examples/quick/quickwidgets/qquickviewcomparison/wobble.frag.qsb b/examples/quick/quickwidgets/qquickviewcomparison/wobble.frag.qsb new file mode 100644 index 00000000000..ab764e83266 Binary files /dev/null and b/examples/quick/quickwidgets/qquickviewcomparison/wobble.frag.qsb differ diff --git a/examples/quick/quickwidgets/quickwidget/CMakeLists.txt b/examples/quick/quickwidgets/quickwidget/CMakeLists.txt index 5cd4b9445ac..5aeeb70505e 100644 --- a/examples/quick/quickwidgets/quickwidget/CMakeLists.txt +++ b/examples/quick/quickwidgets/quickwidget/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from quickwidget.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(quickwidget LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -37,19 +37,15 @@ target_link_libraries(quickwidget PUBLIC Qt::Widgets ) - -# Resources: -set(quickwidget_resource_files - "customgl.qml" - "rotatingsquare.qml" - "rotatingsquaretab.qml" -) - -qt6_add_resources(quickwidget "quickwidget" - PREFIX - "/quickwidget" - FILES - ${quickwidget_resource_files} +qt_add_qml_module(quickwidget + URI QuickWidgetExample + VERSION 1.0 + QML_FILES + customgl.qml + rotatingsquare.qml + rotatingsquaretab.qml + RESOURCE_PREFIX /quickwidget + NO_RESOURCE_TARGET_PATH ) install(TARGETS quickwidget @@ -57,10 +53,3 @@ install(TARGETS quickwidget BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(quickwidget PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI QuickWidgetExample -) - -qt6_qml_type_registration(quickwidget) diff --git a/examples/quick/quickwidgets/quickwidget/main.cpp b/examples/quick/quickwidgets/quickwidget/main.cpp index 1c8b21f790f..191adcc451d 100644 --- a/examples/quick/quickwidgets/quickwidget/main.cpp +++ b/examples/quick/quickwidgets/quickwidget/main.cpp @@ -198,7 +198,7 @@ int main(int argc, char **argv) QApplication app(argc, argv); // this example and QQuickWidget are only functional when rendering with OpenGL - QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi); + QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); QCoreApplication::setApplicationName("Qt QQuickWidget Example"); QCoreApplication::setOrganizationName("QtProject"); diff --git a/examples/quick/rendercontrol/.prev_CMakeLists.txt b/examples/quick/rendercontrol/.prev_CMakeLists.txt deleted file mode 100644 index 53924b33ce3..00000000000 --- a/examples/quick/rendercontrol/.prev_CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Generated from rendercontrol.pro. - -add_subdirectory(rendercontrol_opengl) -if(WIN32 AND NOT MINGW) - add_subdirectory(rendercontrol_d3d11) -endif() diff --git a/examples/quick/rendercontrol/rendercontrol_d3d11/CMakeLists.txt b/examples/quick/rendercontrol/rendercontrol_d3d11/CMakeLists.txt index afb1149fc6e..1851fba31d1 100644 --- a/examples/quick/rendercontrol/rendercontrol_d3d11/CMakeLists.txt +++ b/examples/quick/rendercontrol/rendercontrol_d3d11/CMakeLists.txt @@ -1,13 +1,11 @@ # Generated from rendercontrol_d3d11.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(rendercontrol_d3d11 LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,21 +13,14 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/rendercontrol/rendercontrol_d3d11") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) -qt_add_executable(rendercontrol_d3d11 - engine.cpp engine.h +qt_add_executable(rendercontrol_d3d11example WIN32 MACOSX_BUNDLE + engine.cpp main.cpp - window.cpp window.h + window.cpp ) -set_target_properties(rendercontrol_d3d11 PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(rendercontrol_d3d11 PUBLIC +target_link_libraries(rendercontrol_d3d11example PUBLIC Qt::Core Qt::Gui Qt::Qml @@ -42,18 +33,14 @@ target_link_libraries(rendercontrol_d3d11 PUBLIC # Resources: -set(rendercontrol_resource_files - "demo.qml" -) - -qt6_add_resources(rendercontrol_d3d11 "rendercontrol" - PREFIX - "/rendercontrol" - FILES - ${rendercontrol_resource_files} +qt_add_qml_module(rendercontrol_d3d11example + URI rendercontrol + VERSION 1.0 + QML_FILES + "demo.qml" ) -install(TARGETS rendercontrol_d3d11 +install(TARGETS rendercontrol_d3d11example RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/quick/rendercontrol/rendercontrol_d3d11/demo.qml b/examples/quick/rendercontrol/rendercontrol_d3d11/demo.qml index 32e2f423d16..d724d6304be 100644 --- a/examples/quick/rendercontrol/rendercontrol_d3d11/demo.qml +++ b/examples/quick/rendercontrol/rendercontrol_d3d11/demo.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { id: root diff --git a/examples/quick/rendercontrol/rendercontrol_d3d11/main.cpp b/examples/quick/rendercontrol/rendercontrol_d3d11/main.cpp index 119b2895003..defb080a91d 100644 --- a/examples/quick/rendercontrol/rendercontrol_d3d11/main.cpp +++ b/examples/quick/rendercontrol/rendercontrol_d3d11/main.cpp @@ -64,7 +64,7 @@ int main(int argc, char **argv) QCoreApplication::setApplicationVersion(QT_VERSION_STR); // only functional when Qt Quick is also using D3D11 - QQuickWindow::setGraphicsApi(QSGRendererInterface::Direct3D11Rhi); + QQuickWindow::setGraphicsApi(QSGRendererInterface::Direct3D11); Engine engine; if (!engine.create()) diff --git a/examples/quick/rendercontrol/rendercontrol_d3d11/quad.frag b/examples/quick/rendercontrol/rendercontrol_d3d11/quad.frag index 09914ccdbe2..a72c43db0fa 100644 --- a/examples/quick/rendercontrol/rendercontrol_d3d11/quad.frag +++ b/examples/quick/rendercontrol/rendercontrol_d3d11/quad.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + struct PSIn { float2 coord : TEXCOORD0; diff --git a/examples/quick/rendercontrol/rendercontrol_opengl/CMakeLists.txt b/examples/quick/rendercontrol/rendercontrol_opengl/CMakeLists.txt index 3445fd00cbb..e15de24f08a 100644 --- a/examples/quick/rendercontrol/rendercontrol_opengl/CMakeLists.txt +++ b/examples/quick/rendercontrol/rendercontrol_opengl/CMakeLists.txt @@ -1,13 +1,9 @@ -# Generated from rendercontrol_opengl.pro. - -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(rendercontrol_opengl LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,22 +11,14 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/rendercontrol/rendercontrol_opengl") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) -find_package(Qt6 COMPONENTS OpenGL) +find_package(Qt6 COMPONENTS Core Gui Quick Qml OpenGL) -qt_add_executable(rendercontrol_opengl - cuberenderer.cpp cuberenderer.h +qt_add_executable(rendercontrol_openglexample WIN32 MACOSX_BUNDLE + cuberenderer.cpp main.cpp - window_singlethreaded.cpp window_singlethreaded.h -) -set_target_properties(rendercontrol_opengl PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE + window_singlethreaded.cpp ) -target_link_libraries(rendercontrol_opengl PUBLIC +target_link_libraries(rendercontrol_openglexample PUBLIC Qt::Core Qt::Gui Qt::OpenGL @@ -38,20 +26,15 @@ target_link_libraries(rendercontrol_opengl PUBLIC Qt::Quick ) - # Resources: -set(rendercontrol_resource_files - "demo.qml" -) - -qt6_add_resources(rendercontrol_opengl "rendercontrol" - PREFIX - "/rendercontrol" - FILES - ${rendercontrol_resource_files} +qt_add_qml_module(rendercontrol_openglexample + URI rendercontrol + VERSION 1.0 + QML_FILES + "demo.qml" ) -install(TARGETS rendercontrol_opengl +install(TARGETS rendercontrol_openglexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/quick/rendercontrol/rendercontrol_opengl/demo.qml b/examples/quick/rendercontrol/rendercontrol_opengl/demo.qml index 0312c2ec1c6..6fad1c5ef51 100644 --- a/examples/quick/rendercontrol/rendercontrol_opengl/demo.qml +++ b/examples/quick/rendercontrol/rendercontrol_opengl/demo.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQuick.Particles 2.0 +import QtQuick +import QtQuick.Particles Rectangle { id: root diff --git a/examples/quick/rendercontrol/rendercontrol_opengl/main.cpp b/examples/quick/rendercontrol/rendercontrol_opengl/main.cpp index 11db82773b2..e0315cef385 100644 --- a/examples/quick/rendercontrol/rendercontrol_opengl/main.cpp +++ b/examples/quick/rendercontrol/rendercontrol_opengl/main.cpp @@ -57,7 +57,7 @@ int main(int argc, char **argv) QGuiApplication app(argc, argv); // only functional when Qt Quick is also using OpenGL - QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi); + QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); WindowSingleThreaded window; window.resize(1024, 768); diff --git a/examples/quick/righttoleft/CMakeLists.txt b/examples/quick/righttoleft/CMakeLists.txt index 377792acedc..51b5de17344 100644 --- a/examples/quick/righttoleft/CMakeLists.txt +++ b/examples/quick/righttoleft/CMakeLists.txt @@ -1,13 +1,12 @@ # Generated from righttoleft.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(righttoleft LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) if(NOT DEFINED INSTALL_EXAMPLESDIR) set(INSTALL_EXAMPLESDIR "examples") @@ -15,69 +14,37 @@ endif() set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/righttoleft") -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Core Gui Quick Qml) -qt_add_executable(righttoleft +add_subdirectory("../shared" "shared") + +qt_add_executable(righttoleftexample + WIN32 + MACOSX_BUNDLE main.cpp ) -set_target_properties(righttoleft PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE + +qt_add_qml_module(righttoleftexample + URI righttoleft + VERSION 1.0 + QML_FILES + "layoutdirection/layoutdirection.qml" + "layoutmirroring/layoutmirroring.qml" + "righttoleft.qml" + "textalignment/textalignment.qml" ) -target_link_libraries(righttoleft PUBLIC + +target_link_libraries(righttoleftexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) - -# Resources: -set(righttoleft_resource_files - "layoutdirection/layoutdirection.qml" - "layoutmirroring/layoutmirroring.qml" - "righttoleft.qml" - "textalignment/textalignment.qml" -) - -qt6_add_resources(righttoleft "righttoleft" - PREFIX - "/righttoleft" - FILES - ${righttoleft_resource_files} -) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(righttoleft "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} -) - -install(TARGETS righttoleft +install(TARGETS righttoleftexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) + +bundle_shared(righttoleftexample) diff --git a/examples/quick/righttoleft/layoutdirection/layoutdirection.qml b/examples/quick/righttoleft/layoutdirection/layoutdirection.qml index b83b9f4e65e..8b953da2c71 100644 --- a/examples/quick/righttoleft/layoutdirection/layoutdirection.qml +++ b/examples/quick/righttoleft/layoutdirection/layoutdirection.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick Rectangle { id: root diff --git a/examples/quick/righttoleft/layoutmirroring/layoutmirroring.qml b/examples/quick/righttoleft/layoutmirroring/layoutmirroring.qml index 675e049b152..dc95aa82a87 100644 --- a/examples/quick/righttoleft/layoutmirroring/layoutmirroring.qml +++ b/examples/quick/righttoleft/layoutmirroring/layoutmirroring.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick Rectangle { id: root diff --git a/examples/quick/righttoleft/righttoleft.qml b/examples/quick/righttoleft/righttoleft.qml index a9d85848351..dd540f06fcf 100644 --- a/examples/quick/righttoleft/righttoleft.qml +++ b/examples/quick/righttoleft/righttoleft.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "../shared" as Examples +import QtQuick +import shared as Examples Item { height: 480 diff --git a/examples/quick/righttoleft/textalignment/textalignment.qml b/examples/quick/righttoleft/textalignment/textalignment.qml index 698917a3c0d..bd023d74a01 100644 --- a/examples/quick/righttoleft/textalignment/textalignment.qml +++ b/examples/quick/righttoleft/textalignment/textalignment.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick Rectangle { id: root diff --git a/examples/quick/scenegraph/.prev_CMakeLists.txt b/examples/quick/scenegraph/.prev_CMakeLists.txt deleted file mode 100644 index a0619410b0b..00000000000 --- a/examples/quick/scenegraph/.prev_CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# Generated from scenegraph.pro. - -add_subdirectory(customgeometry) -add_subdirectory(custommaterial) -add_subdirectory(graph) -add_subdirectory(threadedanimation) -add_subdirectory(twotextureproviders) -if(QT_FEATURE_opengl OR QT_FEATURE_opengles2 OR QT_FEATURE_opengles3) - add_subdirectory(fboitem) - add_subdirectory(openglunderqml) -endif() -if(IOS OR MACOS) - add_subdirectory(metalunderqml) - add_subdirectory(metaltextureimport) -endif() -if(WIN32) - add_subdirectory(d3d11underqml) -endif() -if(QT_FEATURE_vulkan) - add_subdirectory(vulkanunderqml) - add_subdirectory(vulkantextureimport) -endif() diff --git a/examples/quick/scenegraph/customgeometry/.prev_CMakeLists.txt b/examples/quick/scenegraph/customgeometry/.prev_CMakeLists.txt deleted file mode 100644 index 28613e67a3f..00000000000 --- a/examples/quick/scenegraph/customgeometry/.prev_CMakeLists.txt +++ /dev/null @@ -1,60 +0,0 @@ -# Generated from customgeometry.pro. - -cmake_minimum_required(VERSION 3.14) -project(customgeometry LANGUAGES CXX) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/scenegraph/customgeometry") - -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) - -qt_add_executable(customgeometry - beziercurve.cpp beziercurve.h - main.cpp -) -set_target_properties(customgeometry PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(customgeometry PUBLIC - Qt::Core - Qt::Gui - Qt::Quick -) - - -# Resources: -set(customgeometry_resource_files - "main.qml" -) - -qt6_add_resources(customgeometry "customgeometry" - PREFIX - "/scenegraph/customgeometry" - FILES - ${customgeometry_resource_files} -) - -install(TARGETS customgeometry - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) - -set_target_properties(customgeometry PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI CustomGeometry -) - -qt6_qml_type_registration(customgeometry) diff --git a/examples/quick/scenegraph/customgeometry/CMakeLists.txt b/examples/quick/scenegraph/customgeometry/CMakeLists.txt index 0e54c00d243..4e3d13d08a1 100644 --- a/examples/quick/scenegraph/customgeometry/CMakeLists.txt +++ b/examples/quick/scenegraph/customgeometry/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from customgeometry.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(customgeometry_declarative LANGUAGES CXX) # special case set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -33,17 +33,12 @@ target_link_libraries(customgeometry_declarative PUBLIC # special case Qt::Quick ) - -# Resources: -set(customgeometry_resource_files - "main.qml" -) - -qt6_add_resources(customgeometry_declarative "customgeometry" # special case - PREFIX - "/scenegraph/customgeometry" - FILES - ${customgeometry_resource_files} +qt_add_qml_module(customgeometry_declarative + URI CustomGeometry + VERSION 1.0 + QML_FILES main.qml + RESOURCE_PREFIX /scenegraph/customgeometry + NO_RESOURCE_TARGET_PATH ) install(TARGETS customgeometry_declarative # special case @@ -51,10 +46,3 @@ install(TARGETS customgeometry_declarative # special case BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(customgeometry_declarative PROPERTIES # special case - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI CustomGeometry -) - -qt6_qml_type_registration(customgeometry_declarative) # special case diff --git a/examples/quick/scenegraph/custommaterial/.prev_CMakeLists.txt b/examples/quick/scenegraph/custommaterial/.prev_CMakeLists.txt deleted file mode 100644 index 6acf1a858ba..00000000000 --- a/examples/quick/scenegraph/custommaterial/.prev_CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -# Generated from custommaterial.pro. - -cmake_minimum_required(VERSION 3.14) -project(custommaterial LANGUAGES CXX) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/scenegraph/custommaterial") - -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Qml) -find_package(Qt6 COMPONENTS Quick) - -qt_add_executable(custommaterial - customitem.cpp customitem.h - main.cpp -) -set_target_properties(custommaterial PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(custommaterial PUBLIC - Qt::Core - Qt::Gui - Qt::Qml - Qt::Quick -) - - -# Resources: -set(custommaterial_resource_files - "main.qml" - "shaders/mandelbrot.frag.qsb" - "shaders/mandelbrot.vert.qsb" -) - -qt6_add_resources(custommaterial "custommaterial" - PREFIX - "/scenegraph/custommaterial" - FILES - ${custommaterial_resource_files} -) - -install(TARGETS custommaterial - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) - -set_target_properties(custommaterial PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI ExampleCustomMaterial -) - -qt6_qml_type_registration(custommaterial) diff --git a/examples/quick/scenegraph/custommaterial/CMakeLists.txt b/examples/quick/scenegraph/custommaterial/CMakeLists.txt index 46cb238af81..cbf6b0b5c7a 100644 --- a/examples/quick/scenegraph/custommaterial/CMakeLists.txt +++ b/examples/quick/scenegraph/custommaterial/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from custommaterial.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(custommaterial_declarative LANGUAGES CXX) # special case set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -19,6 +19,7 @@ find_package(Qt6 COMPONENTS Core) find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Qml) find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS ShaderTools) qt_add_executable(custommaterial_declarative # special case customitem.cpp customitem.h @@ -35,19 +36,24 @@ target_link_libraries(custommaterial_declarative PUBLIC # special case Qt::Quick ) - -# Resources: -set(custommaterial_resource_files - "main.qml" - "shaders/mandelbrot.frag.qsb" - "shaders/mandelbrot.vert.qsb" +qt_add_qml_module(custommaterial_declarative + URI ExampleCustomMaterial + VERSION 1.0 + QML_FILES + main.qml + RESOURCE_PREFIX /scenegraph/custommaterial + NO_RESOURCE_TARGET_PATH ) -qt6_add_resources(custommaterial_declarative "custommaterial" # special case +qt6_add_shaders(custommaterial_declarative "shaders" + BATCHABLE + PRECOMPILE + OPTIMIZED PREFIX "/scenegraph/custommaterial" FILES - ${custommaterial_resource_files} + "shaders/mandelbrot.vert" + "shaders/mandelbrot.frag" ) install(TARGETS custommaterial_declarative # special case @@ -55,10 +61,3 @@ install(TARGETS custommaterial_declarative # special case BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(custommaterial_declarative PROPERTIES # special case - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI ExampleCustomMaterial -) - -qt6_qml_type_registration(custommaterial_declarative) # special case diff --git a/examples/quick/scenegraph/custommaterial/shaders/mandelbrot.frag b/examples/quick/scenegraph/custommaterial/shaders/mandelbrot.frag index 0e5f63e7a8c..77cc67e4b5d 100644 --- a/examples/quick/scenegraph/custommaterial/shaders/mandelbrot.frag +++ b/examples/quick/scenegraph/custommaterial/shaders/mandelbrot.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + //! [1] #version 440 diff --git a/examples/quick/scenegraph/d3d11underqml/CMakeLists.txt b/examples/quick/scenegraph/d3d11underqml/CMakeLists.txt index b443ffb29fe..74e077a7a50 100644 --- a/examples/quick/scenegraph/d3d11underqml/CMakeLists.txt +++ b/examples/quick/scenegraph/d3d11underqml/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from d3d11underqml.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(d3d11underqml LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -37,19 +37,16 @@ target_link_libraries(d3d11underqml PUBLIC d3dcompiler ) - -# Resources: -set(d3d11underqml_resource_files - "main.qml" - "squircle.frag" - "squircle.vert" -) - -qt6_add_resources(d3d11underqml "d3d11underqml" - PREFIX - "/scenegraph/d3d11underqml" - FILES - ${d3d11underqml_resource_files} +qt_add_qml_module(d3d11underqml + URI D3D11UnderQML + VERSION 1.0 + QML_FILES + main.qml + RESOURCES + squircle.frag + squircle.vert + RESOURCE_PREFIX /scenegraph/d3d11underqml + NO_RESOURCE_TARGET_PATH ) install(TARGETS d3d11underqml @@ -57,10 +54,3 @@ install(TARGETS d3d11underqml BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(d3d11underqml PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI D3D11UnderQML -) - -qt6_qml_type_registration(d3d11underqml) diff --git a/examples/quick/scenegraph/d3d11underqml/d3d11squircle.cpp b/examples/quick/scenegraph/d3d11underqml/d3d11squircle.cpp index 9acfbfff239..ef46c6361dc 100644 --- a/examples/quick/scenegraph/d3d11underqml/d3d11squircle.cpp +++ b/examples/quick/scenegraph/d3d11underqml/d3d11squircle.cpp @@ -210,7 +210,7 @@ void SquircleRenderer::frameStart() QSGRendererInterface *rif = m_window->rendererInterface(); // We are not prepared for anything other than running with the RHI and its D3D11 backend. - Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::Direct3D11Rhi); + Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::Direct3D11); m_device = reinterpret_cast(rif->getResource(m_window, QSGRendererInterface::DeviceResource)); Q_ASSERT(m_device); diff --git a/examples/quick/scenegraph/d3d11underqml/main.cpp b/examples/quick/scenegraph/d3d11underqml/main.cpp index f2a224c1a21..c225fe9df7e 100644 --- a/examples/quick/scenegraph/d3d11underqml/main.cpp +++ b/examples/quick/scenegraph/d3d11underqml/main.cpp @@ -56,7 +56,7 @@ int main(int argc, char **argv) { QGuiApplication app(argc, argv); - QQuickWindow::setGraphicsApi(QSGRendererInterface::Direct3D11Rhi); + QQuickWindow::setGraphicsApi(QSGRendererInterface::Direct3D11); QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); diff --git a/examples/quick/scenegraph/d3d11underqml/squircle.frag b/examples/quick/scenegraph/d3d11underqml/squircle.frag index a907c84e58f..713b2d89f25 100644 --- a/examples/quick/scenegraph/d3d11underqml/squircle.frag +++ b/examples/quick/scenegraph/d3d11underqml/squircle.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + cbuffer buf : register(b0) { float ubuf_t : packoffset(c0); diff --git a/examples/quick/scenegraph/fboitem/CMakeLists.txt b/examples/quick/scenegraph/fboitem/CMakeLists.txt index a9c460b2287..45c939b0d81 100644 --- a/examples/quick/scenegraph/fboitem/CMakeLists.txt +++ b/examples/quick/scenegraph/fboitem/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from fboitem.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(fboitem LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -40,18 +40,13 @@ target_link_libraries(fboitem PUBLIC Qt::Quick ) - -# Resources: -set(fboitem_resource_files - "main.qml" - "shaders/checker.frag.qsb" -) - -qt6_add_resources(fboitem "fboitem" - PREFIX - "/scenegraph/fboitem" - FILES - ${fboitem_resource_files} +qt_add_qml_module(fboitem + URI SceneGraphRendering + VERSION 1.0 + QML_FILES main.qml + RESOURCES shaders/checker.frag.qsb + RESOURCE_PREFIX /scenegraph/fboitem + NO_RESOURCE_TARGET_PATH ) install(TARGETS fboitem @@ -59,10 +54,3 @@ install(TARGETS fboitem BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(fboitem PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI SceneGraphRendering -) - -qt6_qml_type_registration(fboitem) diff --git a/examples/quick/scenegraph/fboitem/main.cpp b/examples/quick/scenegraph/fboitem/main.cpp index 61510cdb938..f7fea90f6cb 100644 --- a/examples/quick/scenegraph/fboitem/main.cpp +++ b/examples/quick/scenegraph/fboitem/main.cpp @@ -58,7 +58,7 @@ int main(int argc, char **argv) { QGuiApplication app(argc, argv); - QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi); + QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); diff --git a/examples/quick/scenegraph/graph/CMakeLists.txt b/examples/quick/scenegraph/graph/CMakeLists.txt index 6066a58499e..93d0e6d61a8 100644 --- a/examples/quick/scenegraph/graph/CMakeLists.txt +++ b/examples/quick/scenegraph/graph/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from graph.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(graph LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -29,6 +29,9 @@ qt_add_executable(graph set_target_properties(graph PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE + + # Prevent name clash with build subdirectory on case-insensitive file systems + OUTPUT_NAME graphapp ) target_link_libraries(graph PUBLIC Qt::Core @@ -36,21 +39,18 @@ target_link_libraries(graph PUBLIC Qt::Quick ) - -# Resources: -set(graph_resource_files - "main.qml" - "shaders/line.frag.qsb" - "shaders/line.vert.qsb" - "shaders/noisy.frag.qsb" - "shaders/noisy.vert.qsb" -) - -qt6_add_resources(graph "graph" - PREFIX - "/scenegraph/graph" - FILES - ${graph_resource_files} +qt_add_qml_module(graph + URI Graph + VERSION 1.0 + QML_FILES + main.qml + RESOURCES + shaders/line.frag.qsb + shaders/line.vert.qsb + shaders/noisy.frag.qsb + shaders/noisy.vert.qsb + RESOURCE_PREFIX /scenegraph/graph + NO_RESOURCE_TARGET_PATH ) install(TARGETS graph @@ -58,10 +58,3 @@ install(TARGETS graph BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(graph PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI Graph -) - -qt6_qml_type_registration(graph) diff --git a/examples/quick/scenegraph/graph/noisynode.cpp b/examples/quick/scenegraph/graph/noisynode.cpp index f8b72bfe67c..b9a9b6b1ae3 100644 --- a/examples/quick/scenegraph/graph/noisynode.cpp +++ b/examples/quick/scenegraph/graph/noisynode.cpp @@ -151,6 +151,7 @@ void NoisyShader::updateSampledImage(RenderState &state, int binding, QSGTexture Q_UNUSED(binding); NoisyMaterial *mat = static_cast(newMaterial); + mat->state.texture->commitTextureOperations(state.rhi(), state.resourceUpdateBatch()); *texture = mat->state.texture; } diff --git a/examples/quick/scenegraph/graph/shaders/line.frag b/examples/quick/scenegraph/graph/shaders/line.frag index 44b5b24c946..b9531cede6e 100644 --- a/examples/quick/scenegraph/graph/shaders/line.frag +++ b/examples/quick/scenegraph/graph/shaders/line.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #version 440 layout(location = 0) in float vT; diff --git a/examples/quick/scenegraph/graph/shaders/noisy.frag b/examples/quick/scenegraph/graph/shaders/noisy.frag index 8cea9de02b9..0b7cb1306b5 100644 --- a/examples/quick/scenegraph/graph/shaders/noisy.frag +++ b/examples/quick/scenegraph/graph/shaders/noisy.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #version 440 layout(location = 0) in vec2 vTexCoord; diff --git a/examples/quick/scenegraph/metaltextureimport/CMakeLists.txt b/examples/quick/scenegraph/metaltextureimport/CMakeLists.txt index d01ee2a3dfa..eb3740f6efa 100644 --- a/examples/quick/scenegraph/metaltextureimport/CMakeLists.txt +++ b/examples/quick/scenegraph/metaltextureimport/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from metaltextureimport.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(metaltextureimport LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -27,6 +27,9 @@ qt_add_executable(metaltextureimport set_target_properties(metaltextureimport PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE + + # Prevent name clash with build subdirectory on case-insensitive file systems + OUTPUT_NAME metaltextureimportapp ) target_link_libraries(metaltextureimport PUBLIC "-framework Metal" @@ -36,36 +39,26 @@ target_link_libraries(metaltextureimport PUBLIC Qt::Quick ) - -# Resources: -set(metaltextureimport_resource_files - "main.qml" - "squircle.frag" - "squircle.vert" -) - -qt6_add_resources(metaltextureimport "metaltextureimport" - PREFIX - "/scenegraph/metaltextureimport" - FILES - ${metaltextureimport_resource_files} -) - if(MACOS) target_link_libraries(metaltextureimport PUBLIC "-framework AppKit" ) endif() +qt_add_qml_module(metaltextureimport + URI MetalTextureImport + VERSION 1.0 + QML_FILES + main.qml + RESOURCES + squircle.frag + squircle.vert + RESOURCE_PREFIX /scenegraph/metaltextureimport + NO_RESOURCE_TARGET_PATH +) + install(TARGETS metaltextureimport RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(metaltextureimport PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI MetalTextureImport -) - -qt6_qml_type_registration(metaltextureimport) diff --git a/examples/quick/scenegraph/metaltextureimport/main.cpp b/examples/quick/scenegraph/metaltextureimport/main.cpp index 2abc1c5671c..9fb9d9ba122 100644 --- a/examples/quick/scenegraph/metaltextureimport/main.cpp +++ b/examples/quick/scenegraph/metaltextureimport/main.cpp @@ -54,7 +54,7 @@ int main(int argc, char **argv) { QGuiApplication app(argc, argv); - QQuickWindow::setGraphicsApi(QSGRendererInterface::MetalRhi); + QQuickWindow::setGraphicsApi(QSGRendererInterface::Metal); QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); diff --git a/examples/quick/scenegraph/metaltextureimport/squircle.frag b/examples/quick/scenegraph/metaltextureimport/squircle.frag index 15f34624fe3..8303e970068 100644 --- a/examples/quick/scenegraph/metaltextureimport/squircle.frag +++ b/examples/quick/scenegraph/metaltextureimport/squircle.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #include #include diff --git a/examples/quick/scenegraph/metalunderqml/CMakeLists.txt b/examples/quick/scenegraph/metalunderqml/CMakeLists.txt index 1cbff4c7f51..752a5aa5783 100644 --- a/examples/quick/scenegraph/metalunderqml/CMakeLists.txt +++ b/examples/quick/scenegraph/metalunderqml/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from metalunderqml.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(metalunderqml LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -36,36 +36,26 @@ target_link_libraries(metalunderqml PUBLIC Qt::Quick ) - -# Resources: -set(metalunderqml_resource_files - "main.qml" - "squircle.frag" - "squircle.vert" -) - -qt6_add_resources(metalunderqml "metalunderqml" - PREFIX - "/scenegraph/metalunderqml" - FILES - ${metalunderqml_resource_files} -) - if(MACOS) target_link_libraries(metalunderqml PUBLIC "-framework AppKit" ) endif() +qt_add_qml_module(metalunderqml + URI MetalUnderQML + VERSION 1.0 + QML_FILES + main.qml + RESOURCES + squircle.frag + squircle.vert + RESOURCE_PREFIX /scenegraph/metalunderqml + NO_RESOURCE_TARGET_PATH + ) + install(TARGETS metalunderqml RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(metalunderqml PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI MetalUnderQML -) - -qt6_qml_type_registration(metalunderqml) diff --git a/examples/quick/scenegraph/metalunderqml/main.cpp b/examples/quick/scenegraph/metalunderqml/main.cpp index 4a657a6bf47..220bed14f8a 100644 --- a/examples/quick/scenegraph/metalunderqml/main.cpp +++ b/examples/quick/scenegraph/metalunderqml/main.cpp @@ -56,7 +56,7 @@ int main(int argc, char **argv) { QGuiApplication app(argc, argv); - QQuickWindow::setGraphicsApi(QSGRendererInterface::MetalRhi); + QQuickWindow::setGraphicsApi(QSGRendererInterface::Metal); QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); diff --git a/examples/quick/scenegraph/metalunderqml/metalsquircle.mm b/examples/quick/scenegraph/metalunderqml/metalsquircle.mm index 4acedcab02c..edac29665c3 100644 --- a/examples/quick/scenegraph/metalunderqml/metalsquircle.mm +++ b/examples/quick/scenegraph/metalunderqml/metalsquircle.mm @@ -205,7 +205,7 @@ QSGRendererInterface *rif = m_window->rendererInterface(); // We are not prepared for anything other than running with the RHI and its Metal backend. - Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::MetalRhi); + Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::Metal); m_device = (id) rif->getResource(m_window, QSGRendererInterface::DeviceResource); Q_ASSERT(m_device); diff --git a/examples/quick/scenegraph/metalunderqml/squircle.frag b/examples/quick/scenegraph/metalunderqml/squircle.frag index 15f34624fe3..8303e970068 100644 --- a/examples/quick/scenegraph/metalunderqml/squircle.frag +++ b/examples/quick/scenegraph/metalunderqml/squircle.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #include #include diff --git a/examples/quick/scenegraph/openglunderqml/CMakeLists.txt b/examples/quick/scenegraph/openglunderqml/CMakeLists.txt index 0772c05259b..a99c5d84d18 100644 --- a/examples/quick/scenegraph/openglunderqml/CMakeLists.txt +++ b/examples/quick/scenegraph/openglunderqml/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from openglunderqml.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(openglunderqml LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -27,6 +27,9 @@ qt_add_executable(openglunderqml set_target_properties(openglunderqml PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE + + # Prevent name clash with build subdirectory on case-insensitive file systems + OUTPUT_NAME openglunderqmlapp ) target_link_libraries(openglunderqml PUBLIC Qt::Core @@ -35,17 +38,12 @@ target_link_libraries(openglunderqml PUBLIC Qt::Quick ) - -# Resources: -set(openglunderqml_resource_files - "main.qml" -) - -qt6_add_resources(openglunderqml "openglunderqml" - PREFIX - "/scenegraph/openglunderqml" - FILES - ${openglunderqml_resource_files} +qt_add_qml_module(openglunderqml + URI OpenGLUnderQML + VERSION 1.0 + QML_FILES main.qml + RESOURCE_PREFIX /scenegraph/openglunderqml + NO_RESOURCE_TARGET_PATH ) install(TARGETS openglunderqml @@ -53,10 +51,3 @@ install(TARGETS openglunderqml BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(openglunderqml PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI OpenGLUnderQML -) - -qt6_qml_type_registration(openglunderqml) diff --git a/examples/quick/scenegraph/openglunderqml/main.cpp b/examples/quick/scenegraph/openglunderqml/main.cpp index d92cbb2d800..5df329c425f 100644 --- a/examples/quick/scenegraph/openglunderqml/main.cpp +++ b/examples/quick/scenegraph/openglunderqml/main.cpp @@ -59,7 +59,7 @@ int main(int argc, char **argv) { QGuiApplication app(argc, argv); - QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi); + QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); diff --git a/examples/quick/scenegraph/openglunderqml/squircle.cpp b/examples/quick/scenegraph/openglunderqml/squircle.cpp index d80309cbfb2..2e224e77b0a 100644 --- a/examples/quick/scenegraph/openglunderqml/squircle.cpp +++ b/examples/quick/scenegraph/openglunderqml/squircle.cpp @@ -137,7 +137,7 @@ void SquircleRenderer::init() { if (!m_program) { QSGRendererInterface *rif = m_window->rendererInterface(); - Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::OpenGL || rif->graphicsApi() == QSGRendererInterface::OpenGLRhi); + Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::OpenGL); initializeOpenGLFunctions(); diff --git a/examples/quick/scenegraph/shared/squircle_rhi.frag b/examples/quick/scenegraph/shared/squircle_rhi.frag index 8da62b93e69..835a6b28232 100644 --- a/examples/quick/scenegraph/shared/squircle_rhi.frag +++ b/examples/quick/scenegraph/shared/squircle_rhi.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #version 440 layout(location = 0) in vec2 coords; diff --git a/examples/quick/scenegraph/threadedanimation/CMakeLists.txt b/examples/quick/scenegraph/threadedanimation/CMakeLists.txt index de00297e69b..328b41bc9e3 100644 --- a/examples/quick/scenegraph/threadedanimation/CMakeLists.txt +++ b/examples/quick/scenegraph/threadedanimation/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from threadedanimation.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(threadedanimation LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -35,18 +35,13 @@ target_link_libraries(threadedanimation PUBLIC Qt::Quick ) - -# Resources: -set(threadedanimation_resource_files - "main.qml" - "spinner.png" -) - -qt6_add_resources(threadedanimation "threadedanimation" - PREFIX - "/scenegraph/threadedanimation" - FILES - ${threadedanimation_resource_files} +qt_add_qml_module(threadedanimation + URI Spinner + VERSION 1.0 + QML_FILES main.qml + RESOURCES spinner.png + RESOURCE_PREFIX /scenegraph/threadedanimation + NO_RESOURCE_TARGET_PATH ) install(TARGETS threadedanimation @@ -54,10 +49,3 @@ install(TARGETS threadedanimation BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(threadedanimation PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI Spinner -) - -qt6_qml_type_registration(threadedanimation) diff --git a/examples/quick/scenegraph/twotextureproviders/CMakeLists.txt b/examples/quick/scenegraph/twotextureproviders/CMakeLists.txt index 5515a14b237..b33809f8a8c 100644 --- a/examples/quick/scenegraph/twotextureproviders/CMakeLists.txt +++ b/examples/quick/scenegraph/twotextureproviders/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from twotextureproviders.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(twotextureproviders LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -19,6 +19,7 @@ find_package(Qt6 COMPONENTS Core) find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Qml) find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS ShaderTools) qt_add_executable(twotextureproviders main.cpp @@ -35,20 +36,25 @@ target_link_libraries(twotextureproviders PUBLIC Qt::Quick ) - -# Resources: -set(twotextureproviders_resource_files - "main.qml" - "shaders/checker.frag.qsb" - "shaders/xorblender.frag.qsb" - "shaders/xorblender.vert.qsb" +qt_add_qml_module(twotextureproviders + URI SceneGraphRendering + VERSION 1.0 + QML_FILES + main.qml + RESOURCE_PREFIX /scenegraph/twotextureproviders + NO_RESOURCE_TARGET_PATH ) -qt6_add_resources(twotextureproviders "twotextureproviders" +qt6_add_shaders(twotextureproviders "shaders" + BATCHABLE + PRECOMPILE + OPTIMIZED PREFIX "/scenegraph/twotextureproviders" FILES - ${twotextureproviders_resource_files} + "shaders/xorblender.vert" + "shaders/xorblender.frag" + "shaders/checker.frag" ) install(TARGETS twotextureproviders @@ -56,10 +62,3 @@ install(TARGETS twotextureproviders BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(twotextureproviders PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI SceneGraphRendering -) - -qt6_qml_type_registration(twotextureproviders) diff --git a/examples/quick/scenegraph/twotextureproviders/shaders/checker.frag b/examples/quick/scenegraph/twotextureproviders/shaders/checker.frag index 0932bc8c376..c684a2cedd3 100644 --- a/examples/quick/scenegraph/twotextureproviders/shaders/checker.frag +++ b/examples/quick/scenegraph/twotextureproviders/shaders/checker.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #version 440 layout(location = 0) in vec2 qt_TexCoord0; diff --git a/examples/quick/scenegraph/twotextureproviders/shaders/compile.bat b/examples/quick/scenegraph/twotextureproviders/shaders/compile.bat deleted file mode 100644 index 99e0ff2a915..00000000000 --- a/examples/quick/scenegraph/twotextureproviders/shaders/compile.bat +++ /dev/null @@ -1,42 +0,0 @@ -::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -:: -:: Copyright (C) 2020 The Qt Company Ltd. -:: Contact: https://www.qt.io/licensing/ -:: -:: This file is part of the QtQuick module 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$ -:: -::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - -qsb --glsl "100es,120,150" --hlsl 50 --msl 12 -c -O -o checker.frag.qsb checker.frag -qsb -b --glsl "100es,120,150" --hlsl 50 --msl 12 -c -O -o xorblender.vert.qsb xorblender.vert -qsb --glsl "100es,120,150" --hlsl 50 --msl 12 -c -O -o xorblender.frag.qsb xorblender.frag diff --git a/examples/quick/scenegraph/twotextureproviders/shaders/xorblender.frag b/examples/quick/scenegraph/twotextureproviders/shaders/xorblender.frag index bc68160c1f7..8587ae5316d 100644 --- a/examples/quick/scenegraph/twotextureproviders/shaders/xorblender.frag +++ b/examples/quick/scenegraph/twotextureproviders/shaders/xorblender.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #version 440 layout(location = 0) in vec2 vTexCoord; diff --git a/examples/quick/scenegraph/vulkantextureimport/CMakeLists.txt b/examples/quick/scenegraph/vulkantextureimport/CMakeLists.txt index b26aedf6eee..5f58bd78c3e 100644 --- a/examples/quick/scenegraph/vulkantextureimport/CMakeLists.txt +++ b/examples/quick/scenegraph/vulkantextureimport/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from vulkantextureimport.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(vulkantextureimport LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -27,6 +27,9 @@ qt_add_executable(vulkantextureimport set_target_properties(vulkantextureimport PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE + + # Prevent name clash with build subdirectory on case-insensitive file systems + OUTPUT_NAME vulkantextureimportapp ) target_link_libraries(vulkantextureimport PUBLIC Qt::Core @@ -35,19 +38,16 @@ target_link_libraries(vulkantextureimport PUBLIC Qt::Quick ) - -# Resources: -set(vulkantextureimport_resource_files - "main.qml" - "squircle.frag.spv" - "squircle.vert.spv" -) - -qt6_add_resources(vulkantextureimport "vulkantextureimport" - PREFIX - "/scenegraph/vulkantextureimport" - FILES - ${vulkantextureimport_resource_files} +qt_add_qml_module(vulkantextureimport + URI VulkanTextureImport + VERSION 1.0 + QML_FILES + main.qml + RESOURCES + squircle.frag.spv + squircle.vert.spv + RESOURCE_PREFIX /scenegraph/vulkantextureimport + NO_RESOURCE_TARGET_PATH ) install(TARGETS vulkantextureimport @@ -55,10 +55,3 @@ install(TARGETS vulkantextureimport BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(vulkantextureimport PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI VulkanTextureImport -) - -qt6_qml_type_registration(vulkantextureimport) diff --git a/examples/quick/scenegraph/vulkantextureimport/main.cpp b/examples/quick/scenegraph/vulkantextureimport/main.cpp index d2eb5184dc3..290eccdc425 100644 --- a/examples/quick/scenegraph/vulkantextureimport/main.cpp +++ b/examples/quick/scenegraph/vulkantextureimport/main.cpp @@ -55,7 +55,7 @@ int main(int argc, char **argv) { QGuiApplication app(argc, argv); - QQuickWindow::setGraphicsApi(QSGRendererInterface::VulkanRhi); + QQuickWindow::setGraphicsApi(QSGRendererInterface::Vulkan); QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); diff --git a/examples/quick/scenegraph/vulkanunderqml/CMakeLists.txt b/examples/quick/scenegraph/vulkanunderqml/CMakeLists.txt index 96741c6e869..6921427d1bb 100644 --- a/examples/quick/scenegraph/vulkanunderqml/CMakeLists.txt +++ b/examples/quick/scenegraph/vulkanunderqml/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from vulkanunderqml.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(vulkanunderqml LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -27,6 +27,9 @@ qt_add_executable(vulkanunderqml set_target_properties(vulkanunderqml PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE + + # Prevent name clash with build subdirectory on case-insensitive file systems + OUTPUT_NAME vulkanunderqmlapp ) target_link_libraries(vulkanunderqml PUBLIC Qt::Core @@ -35,19 +38,16 @@ target_link_libraries(vulkanunderqml PUBLIC Qt::Quick ) - -# Resources: -set(vulkanunderqml_resource_files - "main.qml" - "squircle.frag.spv" - "squircle.vert.spv" -) - -qt6_add_resources(vulkanunderqml "vulkanunderqml" - PREFIX - "/scenegraph/vulkanunderqml" - FILES - ${vulkanunderqml_resource_files} +qt_add_qml_module(vulkanunderqml + URI VulkanUnderQML + VERSION 1.0 + QML_FILES + main.qml + RESOURCES + squircle.frag.spv + squircle.vert.spv + RESOURCE_PREFIX /scenegraph/vulkanunderqml + NO_RESOURCE_TARGET_PATH ) install(TARGETS vulkanunderqml @@ -55,10 +55,3 @@ install(TARGETS vulkanunderqml BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(vulkanunderqml PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI VulkanUnderQML -) - -qt6_qml_type_registration(vulkanunderqml) diff --git a/examples/quick/scenegraph/vulkanunderqml/main.cpp b/examples/quick/scenegraph/vulkanunderqml/main.cpp index e4a3f36ca7c..112332f4fd6 100644 --- a/examples/quick/scenegraph/vulkanunderqml/main.cpp +++ b/examples/quick/scenegraph/vulkanunderqml/main.cpp @@ -56,7 +56,7 @@ int main(int argc, char **argv) QGuiApplication app(argc, argv); // This example needs Vulkan. It will not run otherwise. - QQuickWindow::setGraphicsApi(QSGRendererInterface::VulkanRhi); + QQuickWindow::setGraphicsApi(QSGRendererInterface::Vulkan); QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); diff --git a/examples/quick/scenegraph/vulkanunderqml/vulkansquircle.cpp b/examples/quick/scenegraph/vulkanunderqml/vulkansquircle.cpp index 5942b49843e..f272570d03c 100644 --- a/examples/quick/scenegraph/vulkanunderqml/vulkansquircle.cpp +++ b/examples/quick/scenegraph/vulkanunderqml/vulkansquircle.cpp @@ -205,7 +205,7 @@ void SquircleRenderer::frameStart() QSGRendererInterface *rif = m_window->rendererInterface(); // We are not prepared for anything other than running with the RHI and its Vulkan backend. - Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::VulkanRhi); + Q_ASSERT(rif->graphicsApi() == QSGRendererInterface::Vulkan); if (m_vert.isEmpty()) prepareShader(VertexStage); diff --git a/examples/quick/shadereffects/CMakeLists.txt b/examples/quick/shadereffects/CMakeLists.txt index 136cff77831..172146c441c 100644 --- a/examples/quick/shadereffects/CMakeLists.txt +++ b/examples/quick/shadereffects/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from shadereffects.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(shadereffects LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -19,15 +19,16 @@ find_package(Qt6 COMPONENTS Core) find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Quick) find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS ShaderTools) -qt_add_executable(shadereffects +qt_add_executable(shadereffectsexample main.cpp ) -set_target_properties(shadereffects PROPERTIES +set_target_properties(shadereffectsexample PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) -target_link_libraries(shadereffects PUBLIC +target_link_libraries(shadereffectsexample PUBLIC Qt::Core Qt::Gui Qt::Qml @@ -35,28 +36,32 @@ target_link_libraries(shadereffects PUBLIC ) -# Resources: -set(shadereffects_resource_files - "content/Slider.qml" - "content/face-smile.png" - "content/qt-logo.png" - "content/shaders/blur.frag.qsb" - "content/shaders/colorize.frag.qsb" - "content/shaders/genie.vert.qsb" - "content/shaders/outline.frag.qsb" - "content/shaders/shadow.frag.qsb" - "content/shaders/wobble.frag.qsb" - "shadereffects.qml" +qt_add_qml_module(shadereffectsexample + URI shadereffects + VERSION 1.0 + QML_FILES + "shadereffects.qml" + RESOURCES + "content/face-smile.png" + "content/qt-logo.png" ) -qt6_add_resources(shadereffects "shadereffects" +qt6_add_shaders(shadereffectsexample "shaders" + BATCHABLE + PRECOMPILE + OPTIMIZED PREFIX "/shadereffects" FILES - ${shadereffects_resource_files} + "content/shaders/genie.vert" + "content/shaders/blur.frag" + "content/shaders/colorize.frag" + "content/shaders/outline.frag" + "content/shaders/shadow.frag" + "content/shaders/wobble.frag" ) -install(TARGETS shadereffects +install(TARGETS shadereffectsexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/quick/shadereffects/content/Slider.qml b/examples/quick/shadereffects/content/Slider.qml deleted file mode 100644 index 402b7224132..00000000000 --- a/examples/quick/shadereffects/content/Slider.qml +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Item { - property real value: bar.x / (foo.width - bar.width) - Item { - id: foo - width: parent.width - 4 - height: 6 - anchors.centerIn: parent - - Rectangle { - height: parent.height - anchors.left: parent.left - anchors.right: bar.horizontalCenter - color: "blue" - radius: 3 - } - Rectangle { - height: parent.height - anchors.left: bar.horizontalCenter - anchors.right: parent.right - color: "gray" - radius: 3 - } - Rectangle { - anchors.fill: parent - color: "transparent" - radius: 3 - border.width: 2 - border.color: "black" - } - - Rectangle { - id: bar - y: -7 - width: 20 - height: 20 - radius: 15 - color: "white" - border.width: 2 - border.color: "black" - MouseArea { - anchors.fill: parent - drag.target: parent - drag.axis: Drag.XAxis - drag.minimumX: 0 - drag.maximumX: foo.width - parent.width - } - } - } -} - diff --git a/examples/quick/shadereffects/content/shaders/blur.frag b/examples/quick/shadereffects/content/shaders/blur.frag index 0c914d4244f..b73a2133485 100644 --- a/examples/quick/shadereffects/content/shaders/blur.frag +++ b/examples/quick/shadereffects/content/shaders/blur.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #version 440 layout(location = 0) in vec2 qt_TexCoord0; diff --git a/examples/quick/shadereffects/content/shaders/colorize.frag b/examples/quick/shadereffects/content/shaders/colorize.frag index bc8067cc8c6..eb50da93444 100644 --- a/examples/quick/shadereffects/content/shaders/colorize.frag +++ b/examples/quick/shadereffects/content/shaders/colorize.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #version 440 layout(location = 0) in vec2 qt_TexCoord0; diff --git a/examples/quick/shadereffects/content/shaders/compile.bat b/examples/quick/shadereffects/content/shaders/compile.bat deleted file mode 100755 index e03cfde8d25..00000000000 --- a/examples/quick/shadereffects/content/shaders/compile.bat +++ /dev/null @@ -1,56 +0,0 @@ -::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -:: -:: Copyright (C) 2019 The Qt Company Ltd. -:: Contact: https://www.qt.io/licensing/ -:: -:: This file is part of the examples of the Qt Toolkit. -:: -:: $QT_BEGIN_LICENSE:BSD$ -:: Commercial License Usage -:: Licensees holding valid commercial Qt licenses may use this file in -:: accordance with the commercial license agreement provided with the -:: Software or, alternatively, in accordance with the terms contained in -:: a written agreement between you and The Qt Company. For licensing terms -:: and conditions see https://www.qt.io/terms-conditions. For further -:: information use the contact form at https://www.qt.io/contact-us. -:: -:: BSD License Usage -:: Alternatively, you may use this file under the terms of the BSD license -:: as follows: -:: -:: "Redistribution and use in source and binary forms, with or without -:: modification, are permitted provided that the following conditions are -:: met: -:: * Redistributions of source code must retain the above copyright -:: notice, this list of conditions and the following disclaimer. -:: * Redistributions in binary form must reproduce the above copyright -:: notice, this list of conditions and the following disclaimer in -:: the documentation and/or other materials provided with the -:: distribution. -:: * Neither the name of The Qt Company Ltd nor the names of its -:: contributors may be used to endorse or promote products derived -:: from this software without specific prior written permission. -:: -:: -:: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -:: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -:: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -:: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -:: OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -:: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -:: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -:: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -:: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -:: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -:: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -:: -:: $QT_END_LICENSE$ -:: -::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - -qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -c -O -o blur.frag.qsb blur.frag -qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -c -O -o colorize.frag.qsb colorize.frag -qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -c -O -o outline.frag.qsb outline.frag -qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -c -O -o shadow.frag.qsb shadow.frag -qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -c -O -o wobble.frag.qsb wobble.frag -qsb -b --glsl "150,120,100 es" --hlsl 50 --msl 12 -c -O -o genie.vert.qsb genie.vert diff --git a/examples/quick/shadereffects/content/shaders/outline.frag b/examples/quick/shadereffects/content/shaders/outline.frag index 26df69c5fec..11e9b74af6f 100644 --- a/examples/quick/shadereffects/content/shaders/outline.frag +++ b/examples/quick/shadereffects/content/shaders/outline.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #version 440 layout(location = 0) in vec2 qt_TexCoord0; diff --git a/examples/quick/shadereffects/content/shaders/shadow.frag b/examples/quick/shadereffects/content/shaders/shadow.frag index 8247517b6df..f42fa6c0b0a 100644 --- a/examples/quick/shadereffects/content/shaders/shadow.frag +++ b/examples/quick/shadereffects/content/shaders/shadow.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #version 440 layout(location = 0) in vec2 qt_TexCoord0; diff --git a/examples/quick/shadereffects/content/shaders/wobble.frag b/examples/quick/shadereffects/content/shaders/wobble.frag index a34481c2f25..a97f9d17f54 100644 --- a/examples/quick/shadereffects/content/shaders/wobble.frag +++ b/examples/quick/shadereffects/content/shaders/wobble.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #version 440 layout(location = 0) in vec2 qt_TexCoord0; diff --git a/examples/quick/shadereffects/shadereffects.qml b/examples/quick/shadereffects/shadereffects.qml index 563a09c15d0..9d7a6005430 100644 --- a/examples/quick/shadereffects/shadereffects.qml +++ b/examples/quick/shadereffects/shadereffects.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -48,9 +48,9 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import QtQml.Models 2.1 -import "content" +import QtQuick +import QtQml.Models +import QtQuick.Controls Rectangle { id: root @@ -135,6 +135,8 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom + anchors.leftMargin: 4 + anchors.rightMargin: 4 height: 40 } } @@ -170,6 +172,8 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom + anchors.leftMargin: 4 + anchors.rightMargin: 4 height: 40 } } @@ -191,6 +195,8 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom + anchors.leftMargin: 4 + anchors.rightMargin: 4 height: 40 } } @@ -227,6 +233,8 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom + anchors.leftMargin: 4 + anchors.rightMargin: 4 height: 40 } } diff --git a/examples/quick/shadereffects/shadereffects.qrc b/examples/quick/shadereffects/shadereffects.qrc index e6965d76749..f2d61d4297e 100644 --- a/examples/quick/shadereffects/shadereffects.qrc +++ b/examples/quick/shadereffects/shadereffects.qrc @@ -3,7 +3,6 @@ shadereffects.qml content/face-smile.png content/qt-logo.png - content/Slider.qml content/shaders/wobble.frag.qsb content/shaders/blur.frag.qsb content/shaders/shadow.frag.qsb diff --git a/examples/quick/shapes/CMakeLists.txt b/examples/quick/shapes/CMakeLists.txt index 517f986e276..dce5effb637 100644 --- a/examples/quick/shapes/CMakeLists.txt +++ b/examples/quick/shapes/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from shapes.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(shapes LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -20,150 +20,55 @@ find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Quick) find_package(Qt6 COMPONENTS Qml) -qt_add_executable(shapes +add_subdirectory("../shared" "shared") + +qt_add_executable(shapesexample main.cpp ) -set_target_properties(shapes PROPERTIES +set_target_properties(shapesexample PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) -target_link_libraries(shapes PUBLIC +target_link_libraries(shapesexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(shapesexample shapes_shared) - -# Resources: -set_source_files_properties("../shared/LauncherList.qml" - PROPERTIES QT_RESOURCE_ALIAS "LauncherList.qml" -) -set_source_files_properties("../shared/SimpleLauncherDelegate.qml" - PROPERTIES QT_RESOURCE_ALIAS "SimpleLauncherDelegate.qml" -) -set_source_files_properties("../shared/Slider.qml" - PROPERTIES QT_RESOURCE_ALIAS "Slider.qml" -) -set_source_files_properties("../shared/images/back.png" - PROPERTIES QT_RESOURCE_ALIAS "images/back.png" -) -set_source_files_properties("../shared/images/next.png" - PROPERTIES QT_RESOURCE_ALIAS "images/next.png" -) -set_source_files_properties("../shared/images/slider_handle.png" - PROPERTIES QT_RESOURCE_ALIAS "images/slider_handle.png" -) -set_source_files_properties("content/clippedtigers.qml" - PROPERTIES QT_RESOURCE_ALIAS "clippedtigers.qml" -) -set_source_files_properties("content/interactive.qml" - PROPERTIES QT_RESOURCE_ALIAS "interactive.qml" -) -set_source_files_properties("content/item10.qml" - PROPERTIES QT_RESOURCE_ALIAS "item10.qml" -) -set_source_files_properties("content/item11.qml" - PROPERTIES QT_RESOURCE_ALIAS "item11.qml" -) -set_source_files_properties("content/item12.qml" - PROPERTIES QT_RESOURCE_ALIAS "item12.qml" -) -set_source_files_properties("content/item13.qml" - PROPERTIES QT_RESOURCE_ALIAS "item13.qml" -) -set_source_files_properties("content/item14.qml" - PROPERTIES QT_RESOURCE_ALIAS "item14.qml" -) -set_source_files_properties("content/item15.qml" - PROPERTIES QT_RESOURCE_ALIAS "item15.qml" -) -set_source_files_properties("content/item17.qml" - PROPERTIES QT_RESOURCE_ALIAS "item17.qml" -) -set_source_files_properties("content/item18.qml" - PROPERTIES QT_RESOURCE_ALIAS "item18.qml" -) -set_source_files_properties("content/item2.qml" - PROPERTIES QT_RESOURCE_ALIAS "item2.qml" -) -set_source_files_properties("content/item3.qml" - PROPERTIES QT_RESOURCE_ALIAS "item3.qml" -) -set_source_files_properties("content/item4.qml" - PROPERTIES QT_RESOURCE_ALIAS "item4.qml" -) -set_source_files_properties("content/item5.qml" - PROPERTIES QT_RESOURCE_ALIAS "item5.qml" -) -set_source_files_properties("content/item6.qml" - PROPERTIES QT_RESOURCE_ALIAS "item6.qml" -) -set_source_files_properties("content/item7.qml" - PROPERTIES QT_RESOURCE_ALIAS "item7.qml" -) -set_source_files_properties("content/item8.qml" - PROPERTIES QT_RESOURCE_ALIAS "item8.qml" -) -set_source_files_properties("content/item9.qml" - PROPERTIES QT_RESOURCE_ALIAS "item9.qml" -) -set_source_files_properties("content/main.qml" - PROPERTIES QT_RESOURCE_ALIAS "main.qml" -) -set_source_files_properties("content/sampling.qml" - PROPERTIES QT_RESOURCE_ALIAS "sampling.qml" -) -set_source_files_properties("content/shapegallery.qml" - PROPERTIES QT_RESOURCE_ALIAS "shapegallery.qml" -) -set_source_files_properties("content/tapableTriangle.qml" - PROPERTIES QT_RESOURCE_ALIAS "tapableTriangle.qml" -) -set_source_files_properties("content/tiger.qml" - PROPERTIES QT_RESOURCE_ALIAS "tiger.qml" -) -set(shapes_resource_files - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/images/back.png" - "../shared/images/next.png" - "../shared/images/slider_handle.png" - "content/clippedtigers.qml" - "content/interactive.qml" - "content/item10.qml" - "content/item11.qml" - "content/item12.qml" - "content/item13.qml" - "content/item14.qml" - "content/item15.qml" - "content/item17.qml" - "content/item18.qml" - "content/item2.qml" - "content/item3.qml" - "content/item4.qml" - "content/item5.qml" - "content/item6.qml" - "content/item7.qml" - "content/item8.qml" - "content/item9.qml" - "content/main.qml" - "content/sampling.qml" - "content/shapegallery.qml" - "content/tapableTriangle.qml" - "content/tiger.qml" -) - -qt6_add_resources(shapes "shapes" - PREFIX - "/shapes" - FILES - ${shapes_resource_files} +qt_add_qml_module(shapesexample + URI shapes + VERSION 1.0 + QML_FILES + "clippedtigers.qml" + "interactive.qml" + "cubicCurve.qml" + "ellipticalArcs.qml" + "gradientSpreadModes.qml" + "arcDirection.qml" + "largeOrSmallArc.qml" + "arcRotation.qml" + "tigerLoader.qml" + "text.qml" + "strokeOrFill.qml" + "dashPattern.qml" + "linearGradient.qml" + "radialGradient.qml" + "fillRules.qml" + "joinStyles.qml" + "capStyles.qml" + "quadraticCurve.qml" + "main.qml" + "sampling.qml" + "shapegallery.qml" + "tapableTriangle.qml" + "tiger.qml" ) -install(TARGETS shapes +install(TARGETS shapesexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) +bundle_shared(shapesexample) diff --git a/examples/quick/shapes/arcDirection.qml b/examples/quick/shapes/arcDirection.qml new file mode 100644 index 00000000000..428e7056b86 --- /dev/null +++ b/examples/quick/shapes/arcDirection.qml @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + + Rectangle { + width: 100 + height: 100 + anchors.centerIn: parent + border.color: "gray" + + Repeater { + model: 2 + Shape { + anchors.fill: parent + + ShapePath { + fillColor: "transparent" + strokeColor: model.index === 0 ? "red" : "blue" + strokeStyle: ShapePath.DashLine + strokeWidth: 4 + + startX: 4; startY: 4 + PathArc { + id: arc + x: 96; y: 96 + radiusX: 100; radiusY: 100 + direction: model.index === 0 ? PathArc.Clockwise : PathArc.Counterclockwise + } + } + } + } + } + + Column { + anchors.right: parent.right + Text { + text: "Clockwise (sweep 1)" + color: "red" + } + Text { + text: "Counter clockwise (sweep 0)" + color: "blue" + } + } +} diff --git a/examples/quick/shapes/arcRotation.qml b/examples/quick/shapes/arcRotation.qml new file mode 100644 index 00000000000..20be8a84461 --- /dev/null +++ b/examples/quick/shapes/arcRotation.qml @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + + Repeater { + model: 2 + Shape { + width: 200 + height: 200 + anchors.centerIn: parent + + ShapePath { + fillColor: "transparent" + strokeColor: model.index === 0 ? "red" : "blue" + strokeStyle: ShapePath.DashLine + strokeWidth: 4 + + startX: 50; startY: 100 + PathArc { + x: 150; y: 100 + radiusX: 50; radiusY: 20 + xAxisRotation: model.index === 0 ? 0 : 45 + } + } + } + } + + Repeater { + model: 2 + Shape { + width: 200 + height: 200 + anchors.centerIn: parent + + ShapePath { + fillColor: "transparent" + strokeColor: model.index === 0 ? "red" : "blue" + + startX: 50; startY: 100 + PathArc { + x: 150; y: 100 + radiusX: 50; radiusY: 20 + xAxisRotation: model.index === 0 ? 0 : 45 + direction: PathArc.Counterclockwise + } + } + } + } + + Column { + anchors.right: parent.right + Text { + text: "0 degrees" + color: "red" + } + Text { + text: "45 degrees" + color: "blue" + } + } +} diff --git a/examples/quick/shapes/capStyles.qml b/examples/quick/shapes/capStyles.qml new file mode 100644 index 00000000000..2eb5047fb1e --- /dev/null +++ b/examples/quick/shapes/capStyles.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256; height: 256 + + Shape { + anchors.centerIn: parent + width: 200 + height: 100 + + ShapePath { + id: capTest + strokeColor: "green" + strokeWidth: 20 + fillColor: "transparent" + + property int capStyleIdx: 0 + property variant styles: [ ShapePath.FlatCap, ShapePath.SquareCap, ShapePath.RoundCap ] + property variant styleTexts: [ "FlatCap", "SquareCap", "RoundCap" ] + + capStyle: styles[capStyleIdx] + + startX: 40; startY: 30 + PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 } + PathLine { x: 150; y: 80 } + PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 } + } + } + + Timer { + interval: 1000 + repeat: true + running: true + onTriggered: capTest.capStyleIdx = (capTest.capStyleIdx + 1) % capTest.styles.length + } + + Text { + id: txt + anchors.right: parent.right + text: capTest.styleTexts[capTest.capStyleIdx] + } +} diff --git a/examples/quick/shapes/content/clippedtigers.qml b/examples/quick/shapes/clippedtigers.qml similarity index 98% rename from examples/quick/shapes/content/clippedtigers.qml rename to examples/quick/shapes/clippedtigers.qml index c55efdc4030..845eb959c13 100644 --- a/examples/quick/shapes/content/clippedtigers.qml +++ b/examples/quick/shapes/clippedtigers.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.9 -import QtQuick.Shapes 1.0 +import QtQuick +import QtQuick.Shapes Rectangle { id: root diff --git a/examples/quick/shapes/content/interactive.qml b/examples/quick/shapes/content/interactive.qml deleted file mode 100644 index 1f7aad3ab05..00000000000 --- a/examples/quick/shapes/content/interactive.qml +++ /dev/null @@ -1,344 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - id: root - width: 1024 - height: 768 - - property color col: "lightsteelblue" - gradient: Gradient { - GradientStop { position: 0.0; color: Qt.tint(root.col, "#20FFFFFF") } - GradientStop { position: 0.1; color: Qt.tint(root.col, "#20AAAAAA") } - GradientStop { position: 0.9; color: Qt.tint(root.col, "#20666666") } - GradientStop { position: 1.0; color: Qt.tint(root.col, "#20000000") } - } - - property int mode: 0 - property bool showResizers: true - property bool fill: false - - Row { - x: 20 - y: 10 - spacing: 20 - Rectangle { - border.color: "black" - color: root.mode === 0 ? "red" : "transparent" - width: 100 - height: 40 - Text { - anchors.centerIn: parent - text: "Line" - } - MouseArea { - anchors.fill: parent - onClicked: root.mode = 0 - } - } - Rectangle { - border.color: "black" - color: root.mode === 1 ? "red" : "transparent" - width: 100 - height: 40 - Text { - anchors.centerIn: parent - text: "Cubic" - } - MouseArea { - anchors.fill: parent - onClicked: root.mode = 1 - } - } - Rectangle { - border.color: "black" - color: root.mode === 2 ? "red" : "transparent" - width: 100 - height: 40 - Text { - anchors.centerIn: parent - text: "Quadratic" - } - MouseArea { - anchors.fill: parent - onClicked: root.mode = 2 - } - } - - Slider { - id: widthSlider - name: "Width" - min: 1 - max: 60 - init: 4 - } - - Rectangle { - border.color: "black" - color: root.showResizers ? "yellow" : "transparent" - width: 50 - height: 40 - Text { - anchors.centerIn: parent - text: "Manip" - } - MouseArea { - anchors.fill: parent - onClicked: { - root.showResizers = !root.showResizers; - for (var i = 0; i < canvas.resizers.length; ++i) - canvas.resizers[i].visible = root.showResizers; - } - } - } - - Rectangle { - border.color: "black" - color: root.fill ? "yellow" : "transparent" - width: 50 - height: 40 - Text { - anchors.centerIn: parent - text: "Fill" - } - MouseArea { - anchors.fill: parent - onClicked: root.fill = !root.fill - } - } - } - - Rectangle { - id: canvas - width: root.width - 40 - height: root.height - 120 - x: 20 - y: 100 - - property variant activePath: null - - property variant resizers: [] - property variant funcs - - property Component mouseArea: Component { - Rectangle { - id: rr - - property variant obj - property string xprop - property string yprop - - width: 20 - height: 20 - - MouseArea { - property bool a: false - - anchors.fill: parent - hoverEnabled: true - onEntered: color = "yellow" - onExited: color = rr.color - onPressed: a = true - onReleased: a = false - onPositionChanged: (mouse)=> { - if (a) { - var pt = mapToItem(rr.parent, mouse.x, mouse.y); - rr.obj[rr.xprop] = pt.x - rr.obj[rr.yprop] = pt.y - rr.x = pt.x - 10 - rr.y = pt.y - 10 - } - } - } - } - } - - function genResizer(obj, x, y, xprop, yprop, color) { - var ma = mouseArea.createObject(canvas, { - color: color, - xprop: xprop, - yprop: yprop - }); - ma.visible = root.showResizers; - ma.obj = obj; - ma.x = x - 10; - ma.y = y - 10; - resizers.push(ma); - return ma; - } - - property Component linePath: Component { - ShapePath { - id: lineShapePath - strokeColor: "black" - strokeWidth: widthSlider.value - fillColor: "transparent" - PathLine { - x: lineShapePath.startX + 1 - y: lineShapePath.startY + 1 - } - } - } - - property Component cubicPath: Component { - ShapePath { - id: cubicShapePath - strokeColor: "black" - strokeWidth: widthSlider.value - fillColor: root.fill ? 'green' : 'transparent' - PathCubic { - x: cubicShapePath.startX + 1 - y: cubicShapePath.startY + 1 - control1X: cubicShapePath.startX + 50; - control1Y: cubicShapePath.startY + 50; - control2X: cubicShapePath.startX + 150; - control2Y: cubicShapePath.startY + 50; - } - } - } - - property Component quadPath: Component { - ShapePath { - id: quadShapePath - strokeColor: "black" - strokeWidth: widthSlider.value - fillColor: root.fill ? 'green' : 'transparent' - PathQuad { - x: quadShapePath.startx + 1 - y: quadShapePath.startY + 1 - controlX: quadShapePath.startX + 50 - controlY: quadShapePath.startY + 50 - } - } - } - - Component.onCompleted: { - funcs = [ - { "start": function(x, y) { - var p = linePath.createObject(root, { startX: x, startY: y }); - shape.data.push(p); - activePath = p; - }, "move": function(x, y) { - if (!activePath) - return; - var pathObj = activePath.pathElements[0]; - pathObj.x = x; - pathObj.y = y; - }, "end": function() { - canvas.genResizer(activePath, activePath.startX, activePath.startY, "startX", "startY", "red"); - var pathObj = activePath.pathElements[0]; - canvas.genResizer(pathObj, pathObj.x, pathObj.y, "x", "y", "red"); - activePath = null; - } - }, - { "start": function(x, y) { - var p = cubicPath.createObject(root, { startX: x, startY: y }); - shape.data.push(p); - activePath = p; - }, "move": function(x, y) { - if (!activePath) - return; - var pathObj = activePath.pathElements[0]; - pathObj.x = x; - pathObj.y = y; - }, "end": function() { - canvas.genResizer(activePath, activePath.startX, activePath.startY, "startX", "startY", "red"); - var pathObj = activePath.pathElements[0]; - canvas.genResizer(pathObj, pathObj.x, pathObj.y, "x", "y", "red"); - canvas.genResizer(pathObj, pathObj.control1X, pathObj.control1Y, "control1X", "control1Y", "blue"); - canvas.genResizer(pathObj, pathObj.control2X, pathObj.control2Y, "control2X", "control2Y", "lightBlue"); - activePath = null; - } - }, - { "start": function(x, y) { - var p = quadPath.createObject(root, { startX: x, startY: y }); - shape.data.push(p); - activePath = p; - }, "move": function(x, y) { - if (!activePath) - return; - var pathObj = activePath.pathElements[0]; - pathObj.x = x; - pathObj.y = y; - }, "end": function() { - canvas.genResizer(activePath, activePath.startX, activePath.startY, "startX", "startY", "red"); - var pathObj = activePath.pathElements[0]; - canvas.genResizer(pathObj, pathObj.x, pathObj.y, "x", "y", "red"); - canvas.genResizer(pathObj, pathObj.controlX, pathObj.controlY, "controlX", "controlY", "blue"); - activePath = null; - } - } - ]; - } - - MouseArea { - anchors.fill: parent - onPressed: (mouse)=> { - canvas.funcs[root.mode].start(mouse.x, mouse.y); - } - onPositionChanged: (mouse)=> { - canvas.funcs[root.mode].move(mouse.x, mouse.y); - } - onReleased: { - canvas.funcs[root.mode].end(); - } - } - - Shape { - id: shape - anchors.fill: parent - - data: [] - } - } -} diff --git a/examples/quick/shapes/content/item10.qml b/examples/quick/shapes/content/item10.qml deleted file mode 100644 index e91342c2fe2..00000000000 --- a/examples/quick/shapes/content/item10.qml +++ /dev/null @@ -1,174 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - - Item { - width: 200 - height: 200 - anchors.centerIn: parent - - Shape { - id: shape - anchors.fill: parent - - ShapePath { - strokeWidth: 4 - strokeColor: "black" - fillGradient: ConicalGradient { - id: conGrad - centerX: 100; centerY: 75 - NumberAnimation on angle { from: 0; to: 360; duration: 10000; loops: Animation.Infinite } - GradientStop { position: 0; color: "#00000000" } - GradientStop { position: 0.10; color: "#ffe0cc73" } - GradientStop { position: 0.17; color: "#ffc6a006" } - GradientStop { position: 0.46; color: "#ff600659" } - GradientStop { position: 0.72; color: "#ff0680ac" } - GradientStop { position: 0.92; color: "#ffb9d9e6" } - GradientStop { position: 1.00; color: "#00000000" } - } - - startX: 50; startY: 100 - PathCubic { - x: 150; y: 100 - control1X: cp1.x; control1Y: cp1.y - control2X: cp2.x; control2Y: cp2.y - } - } - } - - Rectangle { - id: cp1 - color: "red" - width: 10; height: 10 - SequentialAnimation { - loops: Animation.Infinite - running: true - NumberAnimation { - target: cp1 - property: "x" - from: 0 - to: shape.width - cp1.width - duration: 5000 - } - NumberAnimation { - target: cp1 - property: "x" - from: shape.width - cp1.width - to: 0 - duration: 5000 - } - NumberAnimation { - target: cp1 - property: "y" - from: 0 - to: shape.height - cp1.height - duration: 5000 - } - NumberAnimation { - target: cp1 - property: "y" - from: shape.height - cp1.height - to: 0 - duration: 5000 - } - } - } - - Rectangle { - id: cp2 - color: "blue" - width: 10; height: 10 - x: shape.width - width - SequentialAnimation { - loops: Animation.Infinite - running: true - NumberAnimation { - target: cp2 - property: "y" - from: 0 - to: shape.height - cp2.height - duration: 5000 - } - NumberAnimation { - target: cp2 - property: "y" - from: shape.height - cp2.height - to: 0 - duration: 5000 - } - NumberAnimation { - target: cp2 - property: "x" - from: shape.width - cp2.width - to: 0 - duration: 5000 - } - NumberAnimation { - target: cp2 - property: "x" - from: 0 - to: shape.width - cp2.width - duration: 5000 - } - } - } - } - - Text { - anchors.right: parent.right - anchors.top: parent.top - text: "Conical gradient angle: " + Math.round(conGrad.angle) - } -} diff --git a/examples/quick/shapes/content/item11.qml b/examples/quick/shapes/content/item11.qml deleted file mode 100644 index bdd08339e38..00000000000 --- a/examples/quick/shapes/content/item11.qml +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.11 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - Shape { - id: shape - width: 220 - height: 200 - anchors.centerIn: parent - - ShapePath { - fillGradient: LinearGradient { - y2: shape.height - GradientStop { position: 0; color: "yellow" } - GradientStop { position: 1; color: "green" } - } - - startX: 10; startY: 100 - PathArc { - relativeX: 50; y: 100 - radiusX: 25; radiusY: 25 - } - PathArc { - relativeX: 50; y: 100 - radiusX: 25; radiusY: 35 - } - PathArc { - relativeX: 50; y: 100 - radiusX: 25; radiusY: 60 - } - PathArc { - relativeX: 50; y: 100 - radiusX: 50; radiusY: 120 - } - } - } - - Shape { - width: 120 - height: 130 - anchors.bottom: parent.bottom - anchors.right: parent.right - - scale: 0.5 - - ShapePath { - fillColor: "transparent" - strokeColor: "darkBlue" - strokeWidth: 20 - capStyle: ShapePath.RoundCap - - PathAngleArc { - centerX: 65; centerY: 95 - radiusX: 45; radiusY: 45 - startAngle: -180 - SequentialAnimation on sweepAngle { - loops: Animation.Infinite - NumberAnimation { to: 360; duration: 2000 } - NumberAnimation { to: 0; duration: 2000 } - } - } - } - } -} diff --git a/examples/quick/shapes/content/item12.qml b/examples/quick/shapes/content/item12.qml deleted file mode 100644 index 8bdd1bfe508..00000000000 --- a/examples/quick/shapes/content/item12.qml +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - Rectangle { - border.color: "black" - width: 200 - height: 200 - anchors.centerIn: parent - - Shape { - anchors.fill: parent - - ShapePath { - strokeColor: "transparent" - - fillGradient: LinearGradient { - id: grad - y1: 50; y2: 150 - GradientStop { position: 0; color: "black" } - GradientStop { position: 1; color: "red" } - } - - startX: 10; startY: 10 - PathLine { relativeX: 180; relativeY: 0 } - PathLine { relativeX: 0; relativeY: 180 } - PathLine { relativeX: -180; relativeY: 0 } - PathLine { relativeX: 0; relativeY: -180 } - } - } - - Timer { - id: spreadTimer - interval: 3000 - running: true - repeat: true - property variant spreads: [ ShapeGradient.PadSpread, ShapeGradient.RepeatSpread, ShapeGradient.ReflectSpread ] - property variant spreadTexts: [ "PadSpread", "RepeatSpread", "ReflectSpread" ] - property int spreadIdx: 0 - onTriggered: { spreadIdx = (spreadIdx + 1) % spreads.length; grad.spread = spreads[spreadIdx] } - } - - - Shape { - anchors.fill: parent - ShapePath { - strokeColor: "gray" - strokeWidth: 2 - fillColor: "transparent" - PathMove { x: 0; y: 50 } - PathLine { relativeX: 200; relativeY: 0 } - PathMove { x: 0; y: 150 } - PathLine { relativeX: 200; relativeY: 0 } - } - } - } - - Text { - anchors.right: parent.right - text: spreadTimer.spreadTexts[spreadTimer.spreadIdx] - } -} diff --git a/examples/quick/shapes/content/item13.qml b/examples/quick/shapes/content/item13.qml deleted file mode 100644 index 93160af7d8c..00000000000 --- a/examples/quick/shapes/content/item13.qml +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - - Rectangle { - width: 100 - height: 100 - anchors.centerIn: parent - border.color: "gray" - - Repeater { - model: 2 - Shape { - anchors.fill: parent - - ShapePath { - fillColor: "transparent" - strokeColor: model.index === 0 ? "red" : "blue" - strokeStyle: ShapePath.DashLine - strokeWidth: 4 - - startX: 4; startY: 4 - PathArc { - id: arc - x: 96; y: 96 - radiusX: 100; radiusY: 100 - direction: model.index === 0 ? PathArc.Clockwise : PathArc.Counterclockwise - } - } - } - } - } - - Column { - anchors.right: parent.right - Text { - text: "Clockwise (sweep 1)" - color: "red" - } - Text { - text: "Counter clockwise (sweep 0)" - color: "blue" - } - } -} diff --git a/examples/quick/shapes/content/item14.qml b/examples/quick/shapes/content/item14.qml deleted file mode 100644 index fd5b7d10484..00000000000 --- a/examples/quick/shapes/content/item14.qml +++ /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 QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - - Repeater { - model: 2 - Shape { - width: 200 - height: 200 - anchors.centerIn: parent - - ShapePath { - fillColor: "transparent" - strokeColor: model.index === 0 ? "red" : "blue" - strokeStyle: ShapePath.DashLine - strokeWidth: 4 - - startX: 50; startY: 100 - PathArc { - x: 100; y: 150 - radiusX: 50; radiusY: 50 - useLargeArc: model.index === 1 - } - } - } - } - - Column { - anchors.right: parent.right - Text { - text: "Small" - color: "red" - } - Text { - text: "Large" - color: "blue" - } - } -} diff --git a/examples/quick/shapes/content/item15.qml b/examples/quick/shapes/content/item15.qml deleted file mode 100644 index eb23b8b3c52..00000000000 --- a/examples/quick/shapes/content/item15.qml +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - - Repeater { - model: 2 - Shape { - width: 200 - height: 200 - anchors.centerIn: parent - - ShapePath { - fillColor: "transparent" - strokeColor: model.index === 0 ? "red" : "blue" - strokeStyle: ShapePath.DashLine - strokeWidth: 4 - - startX: 50; startY: 100 - PathArc { - x: 150; y: 100 - radiusX: 50; radiusY: 20 - xAxisRotation: model.index === 0 ? 0 : 45 - } - } - } - } - - Repeater { - model: 2 - Shape { - width: 200 - height: 200 - anchors.centerIn: parent - - ShapePath { - fillColor: "transparent" - strokeColor: model.index === 0 ? "red" : "blue" - - startX: 50; startY: 100 - PathArc { - x: 150; y: 100 - radiusX: 50; radiusY: 20 - xAxisRotation: model.index === 0 ? 0 : 45 - direction: PathArc.Counterclockwise - } - } - } - } - - Column { - anchors.right: parent.right - Text { - text: "0 degrees" - color: "red" - } - Text { - text: "45 degrees" - color: "blue" - } - } -} diff --git a/examples/quick/shapes/content/item17.qml b/examples/quick/shapes/content/item17.qml deleted file mode 100644 index 6ee03ddd049..00000000000 --- a/examples/quick/shapes/content/item17.qml +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - - Item { - anchors.fill: parent - - Text { - anchors.centerIn: parent - text: "Loading" - // Phase #1: Loader loads tiger.qml. After this we have our item. - // Phase #2: With some backends (generic) the item will start async processing. Wait for this too. - visible: shapeLoader.status != Loader.Ready || shapeLoader.item.status === Shape.Processing - } - - Loader { - id: shapeLoader - anchors.fill: parent - source: "tiger.qml" - asynchronous: true - visible: status == Loader.Ready - scale: 0.4 - } - } -} diff --git a/examples/quick/shapes/content/item18.qml b/examples/quick/shapes/content/item18.qml deleted file mode 100644 index 192438408d0..00000000000 --- a/examples/quick/shapes/content/item18.qml +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.15 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - - Shape { - anchors.centerIn: parent - width: 200 - height: 100 - - ShapePath { - id: capTest - strokeColor: "black" - strokeWidth: 1 - fillColor: "black" - - PathText { x: 0; y: 0; font.family: "Arial"; font.pixelSize: 150; text: "Qt!" } - } - } -} diff --git a/examples/quick/shapes/content/item2.qml b/examples/quick/shapes/content/item2.qml deleted file mode 100644 index a033ba88c75..00000000000 --- a/examples/quick/shapes/content/item2.qml +++ /dev/null @@ -1,153 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - - Shape { - id: circ1 - anchors.fill: parent - - ShapePath { - id: p1 - fillColor: "transparent" // stroke only - strokeWidth: 4 - - SequentialAnimation on strokeColor { - loops: Animation.Infinite - ColorAnimation { - from: "black" - to: "yellow" - duration: 5000 - } - ColorAnimation { - from: "yellow" - to: "green" - duration: 5000 - } - ColorAnimation { - from: "green" - to: "black" - duration: 5000 - } - } - - property real r: 60 - startX: circ1.width / 2 - r - startY: circ1.height / 2 - r - PathArc { - x: circ1.width / 2 + p1.r - y: circ1.height / 2 + p1.r - radiusX: p1.r; radiusY: p1.r - useLargeArc: true - } - PathArc { - x: circ1.width / 2 - p1.r - y: circ1.height / 2 - p1.r - radiusX: p1.r; radiusY: p1.r - useLargeArc: true - } - } - } - - Shape { - id: circ2 - anchors.fill: parent - - SequentialAnimation on opacity { - loops: Animation.Infinite - NumberAnimation { from: 1.0; to: 0.0; duration: 5000 } - NumberAnimation { from: 0.0; to: 1.0; duration: 5000 } - } - - ShapePath { - id: p2 - strokeWidth: -1 // or strokeColor: "transparent" - - SequentialAnimation on fillColor { - loops: Animation.Infinite - ColorAnimation { - from: "gray" - to: "purple" - duration: 3000 - } - ColorAnimation { - from: "purple" - to: "red" - duration: 3000 - } - ColorAnimation { - from: "red" - to: "gray" - duration: 3000 - } - } - - property real r: 40 - startX: circ2.width / 2 - r - startY: circ2.height / 2 - r - PathArc { - x: circ2.width / 2 + p2.r - y: circ2.height / 2 + p2.r - radiusX: p2.r; radiusY: p2.r - useLargeArc: true - } - PathArc { - x: circ2.width / 2 - p2.r - y: circ2.height / 2 - p2.r - radiusX: p2.r; radiusY: p2.r - useLargeArc: true - } - } - } -} diff --git a/examples/quick/shapes/content/item3.qml b/examples/quick/shapes/content/item3.qml deleted file mode 100644 index 4274f260f33..00000000000 --- a/examples/quick/shapes/content/item3.qml +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - Shape { - width: 200 - height: 150 - anchors.centerIn: parent - ShapePath { - strokeWidth: 4 - strokeColor: "red" - fillGradient: RadialGradient { - centerX: 100; centerY: 100; centerRadius: 100 - SequentialAnimation on focalRadius { - loops: Animation.Infinite - NumberAnimation { from: 1; to: 20; duration: 2000 } - NumberAnimation { from: 20; to: 1; duration: 2000 } - } - SequentialAnimation on focalX { - loops: Animation.Infinite - NumberAnimation { from: 50; to: 150; duration: 3000 } - NumberAnimation { from: 150; to: 50; duration: 3000 } - } - SequentialAnimation on focalY { - loops: Animation.Infinite - NumberAnimation { from: 50; to: 150; duration: 1000 } - NumberAnimation { from: 150; to: 50; duration: 1000 } - } - GradientStop { position: 0; color: "#ffffff" } - GradientStop { position: 0.11; color: "#f9ffa0" } - GradientStop { position: 0.13; color: "#f9ff99" } - GradientStop { position: 0.14; color: "#f3ff86" } - GradientStop { position: 0.49; color: "#93b353" } - GradientStop { position: 0.87; color: "#264619" } - GradientStop { position: 0.96; color: "#0c1306" } - GradientStop { position: 1; color: "#000000" } - } - fillColor: "blue" // ignored with the gradient set - strokeStyle: ShapePath.DashLine - dashPattern: [ 1, 4 ] - startX: 20; startY: 20 - PathLine { x: 180; y: 130 } - PathLine { x: 20; y: 130 } - PathLine { x: 20; y: 20 } - } - } -} diff --git a/examples/quick/shapes/content/item4.qml b/examples/quick/shapes/content/item4.qml deleted file mode 100644 index 2b20c0a263b..00000000000 --- a/examples/quick/shapes/content/item4.qml +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - Shape { - id: shape - anchors.fill: parent - - ShapePath { - id: p - strokeWidth: 5 - strokeColor: "blue" - strokeStyle: ShapePath.DashLine - dashPattern: [ 1, 4, 4, 4 ] - fillColor: "lightBlue" - - property real xr: 70 - property real yr: 30 - startX: shape.width / 2 - xr - startY: shape.height / 2 - yr - PathArc { - x: shape.width / 2 + p.xr - y: shape.height / 2 + p.yr - radiusX: p.xr; radiusY: p.yr - useLargeArc: true - } - PathArc { - x: shape.width / 2 - p.xr - y: shape.height / 2 - p.yr - radiusX: p.xr; radiusY: p.yr - useLargeArc: true - } - } - } -} diff --git a/examples/quick/shapes/content/item5.qml b/examples/quick/shapes/content/item5.qml deleted file mode 100644 index 5fd25093aed..00000000000 --- a/examples/quick/shapes/content/item5.qml +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - Shape { - width: 200 - height: 150 - anchors.centerIn: parent - ShapePath { - strokeWidth: 4 - strokeColor: "red" - fillGradient: LinearGradient { - x1: 20; y1: 20 - x2: 180; y2: 130 - GradientStop { position: 0; color: "blue" } - GradientStop { position: 0.2; color: "green" } - GradientStop { position: 0.4; color: "red" } - GradientStop { position: 0.6; color: "yellow" } - GradientStop { position: 1; color: "cyan" } - } - fillColor: "blue" // ignored with the gradient set - strokeStyle: ShapePath.DashLine - dashPattern: [ 1, 4 ] - startX: 20; startY: 20 - PathLine { x: 180; y: 130 } - PathLine { x: 20; y: 130 } - PathLine { x: 20; y: 20 } - } - transform: Rotation { origin.x: 100; origin.y: 50; axis { x: 0; y: 1; z: 0 } - SequentialAnimation on angle { - NumberAnimation { from: 0; to: 75; duration: 2000 } - NumberAnimation { from: 75; to: -75; duration: 4000 } - NumberAnimation { from: -75; to: 0; duration: 2000 } - loops: Animation.Infinite - } - } - } -} diff --git a/examples/quick/shapes/content/item6.qml b/examples/quick/shapes/content/item6.qml deleted file mode 100644 index f0791c30d25..00000000000 --- a/examples/quick/shapes/content/item6.qml +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - Shape { - width: 100 - height: 100 - anchors.centerIn: parent - ShapePath { - id: star - strokeColor: "blue" - fillColor: "magenta" - strokeWidth: 2 - PathMove { x: 90; y: 50 } - PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) } - PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) } - PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) } - PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) } - PathLine { x: 90; y: 50 } - } - NumberAnimation on rotation { - from: 0 - to: 360 - duration: 5000 - loops: Animation.Infinite - } - } - Timer { - interval: 2000 - onTriggered: star.fillRule = (star.fillRule === ShapePath.OddEvenFill ? ShapePath.WindingFill : ShapePath.OddEvenFill) - repeat: true - running: true - } - Text { - anchors.right: parent.right - text: star.fillRule === ShapePath.OddEvenFill ? "OddEvenFill" : "WindingFill" - } -} diff --git a/examples/quick/shapes/content/item7.qml b/examples/quick/shapes/content/item7.qml deleted file mode 100644 index ff5c5702da4..00000000000 --- a/examples/quick/shapes/content/item7.qml +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - - Shape { - width: 120 - height: 120 - anchors.centerIn: parent - - ShapePath { - id: joinTest - - strokeColor: "black" - strokeWidth: 16 - fillColor: "transparent" - capStyle: ShapePath.RoundCap - - property int joinStyleIdx: 0 - property variant styles: [ ShapePath.BevelJoin, ShapePath.MiterJoin, ShapePath.RoundJoin ] - property variant styleTexts: [ "BevelJoin", "MiterJoin", "RoundJoin" ] - - joinStyle: styles[joinStyleIdx] - - startX: 30 - startY: 30 - PathLine { x: 100; y: 100 } - PathLine { x: 30; y: 100 } - } - } - - Timer { - interval: 1000 - repeat: true - running: true - onTriggered: joinTest.joinStyleIdx = (joinTest.joinStyleIdx + 1) % joinTest.styles.length - } - - Text { - id: txt - anchors.right: parent.right - text: joinTest.styleTexts[joinTest.joinStyleIdx] - } -} diff --git a/examples/quick/shapes/content/item8.qml b/examples/quick/shapes/content/item8.qml deleted file mode 100644 index 07f633fa567..00000000000 --- a/examples/quick/shapes/content/item8.qml +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - - Shape { - anchors.centerIn: parent - width: 200 - height: 100 - - ShapePath { - id: capTest - strokeColor: "green" - strokeWidth: 20 - fillColor: "transparent" - - property int capStyleIdx: 0 - property variant styles: [ ShapePath.FlatCap, ShapePath.SquareCap, ShapePath.RoundCap ] - property variant styleTexts: [ "FlatCap", "SquareCap", "RoundCap" ] - - capStyle: styles[capStyleIdx] - - startX: 40; startY: 30 - PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 } - PathLine { x: 150; y: 80 } - PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 } - } - } - - Timer { - interval: 1000 - repeat: true - running: true - onTriggered: capTest.capStyleIdx = (capTest.capStyleIdx + 1) % capTest.styles.length - } - - Text { - id: txt - anchors.right: parent.right - text: capTest.styleTexts[capTest.capStyleIdx] - } -} diff --git a/examples/quick/shapes/content/item9.qml b/examples/quick/shapes/content/item9.qml deleted file mode 100644 index 4e5b4022b6d..00000000000 --- a/examples/quick/shapes/content/item9.qml +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.9 -import QtQuick.Shapes 1.0 - -Rectangle { - color: "lightGray" - - Item { - width: 200 - height: 100 - anchors.centerIn: parent - - Shape { - id: shape - anchors.fill: parent - - ShapePath { - strokeWidth: 4 - strokeColor: "black" - fillColor: "transparent" - - startX: 50 - startY: 50 - PathQuad { - x: 150; y: 50 - controlX: cp.x; controlY: cp.y - } - } - } - - Rectangle { - id: cp - color: "red" - width: 10 - height: 10 - SequentialAnimation on x { - loops: Animation.Infinite - NumberAnimation { - from: 0 - to: shape.width - cp.width - duration: 5000 - } - NumberAnimation { - from: shape.width - cp.width - to: 0 - duration: 5000 - } - } - } - } -} diff --git a/examples/quick/shapes/content/main.qml b/examples/quick/shapes/content/main.qml deleted file mode 100644 index 8efa47d30bb..00000000000 --- a/examples/quick/shapes/content/main.qml +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Item { - width: 1280 - height: 720 - LauncherList { - anchors.fill: parent - Component.onCompleted: { - addExample("Shape Gallery", "Simple path rendering examples", Qt.resolvedUrl("shapegallery.qml")) - addExample("Interactive Shape", "Dynamic, interactive path rendering examples", Qt.resolvedUrl("interactive.qml")) - addExample("Super- and multisampling", "Improving quality", Qt.resolvedUrl("sampling.qml")) - addExample("Clip My Tiger!", "Clip examples, a.k.a. What Not To Do", Qt.resolvedUrl("clippedtigers.qml")) - } - } -} diff --git a/examples/quick/shapes/cubicCurve.qml b/examples/quick/shapes/cubicCurve.qml new file mode 100644 index 00000000000..319942ecb14 --- /dev/null +++ b/examples/quick/shapes/cubicCurve.qml @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + + Item { + width: 200 + height: 200 + anchors.centerIn: parent + + Shape { + id: shape + anchors.fill: parent + + ShapePath { + strokeWidth: 4 + strokeColor: "black" + fillGradient: ConicalGradient { + id: conGrad + centerX: 100; centerY: 75 + NumberAnimation on angle { from: 0; to: 360; duration: 10000; loops: Animation.Infinite } + GradientStop { position: 0; color: "#00000000" } + GradientStop { position: 0.10; color: "#ffe0cc73" } + GradientStop { position: 0.17; color: "#ffc6a006" } + GradientStop { position: 0.46; color: "#ff600659" } + GradientStop { position: 0.72; color: "#ff0680ac" } + GradientStop { position: 0.92; color: "#ffb9d9e6" } + GradientStop { position: 1.00; color: "#00000000" } + } + + startX: 50; startY: 100 + PathCubic { + x: 150; y: 100 + control1X: cp1.x; control1Y: cp1.y + control2X: cp2.x; control2Y: cp2.y + } + } + } + + Rectangle { + id: cp1 + color: "red" + width: 10; height: 10 + SequentialAnimation { + loops: Animation.Infinite + running: true + NumberAnimation { + target: cp1 + property: "x" + from: 0 + to: shape.width - cp1.width + duration: 5000 + } + NumberAnimation { + target: cp1 + property: "x" + from: shape.width - cp1.width + to: 0 + duration: 5000 + } + NumberAnimation { + target: cp1 + property: "y" + from: 0 + to: shape.height - cp1.height + duration: 5000 + } + NumberAnimation { + target: cp1 + property: "y" + from: shape.height - cp1.height + to: 0 + duration: 5000 + } + } + } + + Rectangle { + id: cp2 + color: "blue" + width: 10; height: 10 + x: shape.width - width + SequentialAnimation { + loops: Animation.Infinite + running: true + NumberAnimation { + target: cp2 + property: "y" + from: 0 + to: shape.height - cp2.height + duration: 5000 + } + NumberAnimation { + target: cp2 + property: "y" + from: shape.height - cp2.height + to: 0 + duration: 5000 + } + NumberAnimation { + target: cp2 + property: "x" + from: shape.width - cp2.width + to: 0 + duration: 5000 + } + NumberAnimation { + target: cp2 + property: "x" + from: 0 + to: shape.width - cp2.width + duration: 5000 + } + } + } + } + + Text { + anchors.right: parent.right + anchors.top: parent.top + text: "Conical gradient angle: " + Math.round(conGrad.angle) + } +} diff --git a/examples/quick/shapes/dashPattern.qml b/examples/quick/shapes/dashPattern.qml new file mode 100644 index 00000000000..c427e35c386 --- /dev/null +++ b/examples/quick/shapes/dashPattern.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + Shape { + id: shape + anchors.fill: parent + + ShapePath { + id: p + strokeWidth: 5 + strokeColor: "blue" + strokeStyle: ShapePath.DashLine + dashPattern: [ 1, 4, 4, 4 ] + fillColor: "lightBlue" + + property real xr: 70 + property real yr: 30 + startX: shape.width / 2 - xr + startY: shape.height / 2 - yr + PathArc { + x: shape.width / 2 + p.xr + y: shape.height / 2 + p.yr + radiusX: p.xr; radiusY: p.yr + useLargeArc: true + } + PathArc { + x: shape.width / 2 - p.xr + y: shape.height / 2 - p.yr + radiusX: p.xr; radiusY: p.yr + useLargeArc: true + } + } + } +} diff --git a/examples/quick/shapes/ellipticalArcs.qml b/examples/quick/shapes/ellipticalArcs.qml new file mode 100644 index 00000000000..de9379f35e1 --- /dev/null +++ b/examples/quick/shapes/ellipticalArcs.qml @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + Shape { + id: shape + width: 220 + height: 200 + anchors.centerIn: parent + + ShapePath { + fillGradient: LinearGradient { + y2: shape.height + GradientStop { position: 0; color: "yellow" } + GradientStop { position: 1; color: "green" } + } + + startX: 10; startY: 100 + PathArc { + relativeX: 50; y: 100 + radiusX: 25; radiusY: 25 + } + PathArc { + relativeX: 50; y: 100 + radiusX: 25; radiusY: 35 + } + PathArc { + relativeX: 50; y: 100 + radiusX: 25; radiusY: 60 + } + PathArc { + relativeX: 50; y: 100 + radiusX: 50; radiusY: 120 + } + } + } + + Shape { + width: 120 + height: 130 + anchors.bottom: parent.bottom + anchors.right: parent.right + + scale: 0.5 + + ShapePath { + fillColor: "transparent" + strokeColor: "darkBlue" + strokeWidth: 20 + capStyle: ShapePath.RoundCap + + PathAngleArc { + centerX: 65; centerY: 95 + radiusX: 45; radiusY: 45 + startAngle: -180 + SequentialAnimation on sweepAngle { + loops: Animation.Infinite + NumberAnimation { to: 360; duration: 2000 } + NumberAnimation { to: 0; duration: 2000 } + } + } + } + } +} diff --git a/examples/quick/shapes/fillRules.qml b/examples/quick/shapes/fillRules.qml new file mode 100644 index 00000000000..8bddc29737a --- /dev/null +++ b/examples/quick/shapes/fillRules.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + Shape { + width: 100 + height: 100 + anchors.centerIn: parent + ShapePath { + id: star + strokeColor: "blue" + fillColor: "magenta" + strokeWidth: 2 + PathMove { x: 90; y: 50 } + PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) } + PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) } + PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) } + PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) } + PathLine { x: 90; y: 50 } + } + NumberAnimation on rotation { + from: 0 + to: 360 + duration: 5000 + loops: Animation.Infinite + } + } + Timer { + interval: 2000 + onTriggered: star.fillRule = (star.fillRule === ShapePath.OddEvenFill ? ShapePath.WindingFill : ShapePath.OddEvenFill) + repeat: true + running: true + } + Text { + anchors.right: parent.right + text: star.fillRule === ShapePath.OddEvenFill ? "OddEvenFill" : "WindingFill" + } +} diff --git a/examples/quick/shapes/gradientSpreadModes.qml b/examples/quick/shapes/gradientSpreadModes.qml new file mode 100644 index 00000000000..c0b42c88329 --- /dev/null +++ b/examples/quick/shapes/gradientSpreadModes.qml @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + Rectangle { + border.color: "black" + width: 200 + height: 200 + anchors.centerIn: parent + + Shape { + anchors.fill: parent + + ShapePath { + strokeColor: "transparent" + + fillGradient: LinearGradient { + id: grad + y1: 50; y2: 150 + GradientStop { position: 0; color: "black" } + GradientStop { position: 1; color: "red" } + } + + startX: 10; startY: 10 + PathLine { relativeX: 180; relativeY: 0 } + PathLine { relativeX: 0; relativeY: 180 } + PathLine { relativeX: -180; relativeY: 0 } + PathLine { relativeX: 0; relativeY: -180 } + } + } + + Timer { + id: spreadTimer + interval: 3000 + running: true + repeat: true + property variant spreads: [ ShapeGradient.PadSpread, ShapeGradient.RepeatSpread, ShapeGradient.ReflectSpread ] + property variant spreadTexts: [ "PadSpread", "RepeatSpread", "ReflectSpread" ] + property int spreadIdx: 0 + onTriggered: { spreadIdx = (spreadIdx + 1) % spreads.length; grad.spread = spreads[spreadIdx] } + } + + + Shape { + anchors.fill: parent + ShapePath { + strokeColor: "gray" + strokeWidth: 2 + fillColor: "transparent" + PathMove { x: 0; y: 50 } + PathLine { relativeX: 200; relativeY: 0 } + PathMove { x: 0; y: 150 } + PathLine { relativeX: 200; relativeY: 0 } + } + } + } + + Text { + anchors.right: parent.right + text: spreadTimer.spreadTexts[spreadTimer.spreadIdx] + } +} diff --git a/examples/quick/shapes/interactive.qml b/examples/quick/shapes/interactive.qml new file mode 100644 index 00000000000..dc3489ee2d1 --- /dev/null +++ b/examples/quick/shapes/interactive.qml @@ -0,0 +1,261 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Shapes + +Rectangle { + id: root + width: 1024 + height: 768 + color: palette.window + + RowLayout { + id: topRow + x: 20 + y: 10 + spacing: 20 + + ButtonGroup { + id: toolButtons + buttons: drawingTools.children + } + + RowLayout { + id: drawingTools + ToolButton { + text: qsTr("Line") + checkable: true + checked: true + + property Component shapeType: Component { + ShapePath { + id: lineShapePath + strokeColor: root.palette.windowText + strokeWidth: widthSlider.value + fillColor: "transparent" + PathLine { + id: pathSegment + x: lineShapePath.startX + 1 + y: lineShapePath.startY + 1 + } + function finishCreation() { + createStartEndHandles(this, pathSegment); + } + } + } + } + ToolButton { + text: qsTr("Quadratic") + checkable: true + + property Component shapeType: Component { + ShapePath { + id: quadShapePath + strokeColor: root.palette.windowText + strokeWidth: widthSlider.value + fillColor: fillSwitch.checked ? "green" : "transparent" + PathQuad { + id: pathSegment + x: quadShapePath.startx + 1 + y: quadShapePath.startY + 1 + controlX: quadShapePath.startX + 50 + controlY: quadShapePath.startY + 50 + } + function finishCreation() { + createStartEndHandles(this, pathSegment); + pointDragHandle.createObject(canvas, { + idleColor: "blue", + target: pathSegment, xprop: "controlX", yprop: "controlY" + }); + } + } + } + } + ToolButton { + text: qsTr("Cubic") + checkable: true + + property Component shapeType: Component { + ShapePath { + id: cubicShapePath + strokeColor: root.palette.windowText + strokeWidth: widthSlider.value + fillColor: fillSwitch.checked ? "green" : "transparent" + PathCubic { + id: pathSegment + x: cubicShapePath.startX + 1 + y: cubicShapePath.startY + 1 + control1X: cubicShapePath.startX + 50; + control1Y: cubicShapePath.startY + 50; + control2X: cubicShapePath.startX + 150; + control2Y: cubicShapePath.startY + 50; + } + function finishCreation() { + createStartEndHandles(this, pathSegment); + pointDragHandle.createObject(canvas, { + idleColor: "blue", + target: pathSegment, xprop: "control1X", yprop: "control1Y" + }); + pointDragHandle.createObject(canvas, { + idleColor: "lightBlue", + target: pathSegment, xprop: "control2X", yprop: "control2Y" + }); + } + } + } + } + } + + Label { + text: qsTr("Width") + } + Slider { + id: widthSlider + from: 1 + to: 60 + value: 4 + } + + Switch { + id: showHandlesSwitch + text: qsTr("Handles") + } + + Switch { + id: fillSwitch + text: qsTr("Fill") + } + } + + Component { + id: pointDragHandle + + Rectangle { + id: rect + property variant target + property string xprop + property string yprop + property color idleColor: "red" + + width: 20 + height: width + visible: showHandlesSwitch.checked + color: hh.hovered ? "yellow" : idleColor + border.color: "grey" + + property real halfWidth: width / 2 + property bool complete: false + Binding { target: rect.target; property: xprop; value: x + halfWidth; when: complete } + Binding { target: rect.target; property: yprop; value: y + halfWidth; when: complete } + + DragHandler { } + + HoverHandler { id: hh } + + Component.onCompleted: { + x = target[xprop] - halfWidth; + y = target[yprop] - halfWidth; + complete = true; + } + } + } + + function createStartEndHandles(shapePath, pathSegment) { + pointDragHandle.createObject(canvas, { + idleColor: "red", + target: shapePath, xprop: "startX", yprop: "startY" + }); + pointDragHandle.createObject(canvas, { + idleColor: "red", + target: pathSegment, xprop: "x", yprop: "y" + }); + } + + Rectangle { + id: canvas + color: palette.base + width: root.width - 40 + height: root.height - y - 20 + x: 20 + anchors.top: topRow.bottom + anchors.topMargin: 20 + + DragHandler { + target: null + grabPermissions: DragHandler.TakeOverForbidden + property ShapePath activePath: null + onActiveChanged: { + const tool = toolButtons.checkedButton; + if (active) { + activePath = tool.shapeType.createObject(root, { + startX: centroid.position.x, startY: centroid.position.y + }); + shape.data.push(activePath); + } else { + activePath.finishCreation(); + activePath = null; + } + } + onCentroidChanged: if (activePath) { + var pathObj = activePath.pathElements[0]; + pathObj.x = centroid.position.x; + pathObj.y = centroid.position.y; + } + } + + Shape { + id: shape + anchors.fill: parent + } + } +} diff --git a/examples/quick/shapes/joinStyles.qml b/examples/quick/shapes/joinStyles.qml new file mode 100644 index 00000000000..140151d0f0d --- /dev/null +++ b/examples/quick/shapes/joinStyles.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + + Shape { + width: 120 + height: 120 + anchors.centerIn: parent + + ShapePath { + id: joinTest + + strokeColor: "black" + strokeWidth: 16 + fillColor: "transparent" + capStyle: ShapePath.RoundCap + + property int joinStyleIdx: 0 + property variant styles: [ ShapePath.BevelJoin, ShapePath.MiterJoin, ShapePath.RoundJoin ] + property variant styleTexts: [ "BevelJoin", "MiterJoin", "RoundJoin" ] + + joinStyle: styles[joinStyleIdx] + + startX: 30 + startY: 30 + PathLine { x: 100; y: 100 } + PathLine { x: 30; y: 100 } + } + } + + Timer { + interval: 1000 + repeat: true + running: true + onTriggered: joinTest.joinStyleIdx = (joinTest.joinStyleIdx + 1) % joinTest.styles.length + } + + Text { + id: txt + anchors.right: parent.right + text: joinTest.styleTexts[joinTest.joinStyleIdx] + } +} diff --git a/examples/quick/shapes/largeOrSmallArc.qml b/examples/quick/shapes/largeOrSmallArc.qml new file mode 100644 index 00000000000..3079b9c2ad6 --- /dev/null +++ b/examples/quick/shapes/largeOrSmallArc.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + + Repeater { + model: 2 + Shape { + width: 200 + height: 200 + anchors.centerIn: parent + + ShapePath { + fillColor: "transparent" + strokeColor: model.index === 0 ? "red" : "blue" + strokeStyle: ShapePath.DashLine + strokeWidth: 4 + + startX: 50; startY: 100 + PathArc { + x: 100; y: 150 + radiusX: 50; radiusY: 50 + useLargeArc: model.index === 1 + } + } + } + } + + Column { + anchors.right: parent.right + Text { + text: "Small" + color: "red" + } + Text { + text: "Large" + color: "blue" + } + } +} diff --git a/examples/quick/shapes/linearGradient.qml b/examples/quick/shapes/linearGradient.qml new file mode 100644 index 00000000000..9ac48187ff3 --- /dev/null +++ b/examples/quick/shapes/linearGradient.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + Shape { + width: 200 + height: 150 + anchors.centerIn: parent + ShapePath { + strokeWidth: 4 + strokeColor: "red" + fillGradient: LinearGradient { + x1: 20; y1: 20 + x2: 180; y2: 130 + GradientStop { position: 0; color: "blue" } + GradientStop { position: 0.2; color: "green" } + GradientStop { position: 0.4; color: "red" } + GradientStop { position: 0.6; color: "yellow" } + GradientStop { position: 1; color: "cyan" } + } + fillColor: "blue" // ignored with the gradient set + strokeStyle: ShapePath.DashLine + dashPattern: [ 1, 4 ] + startX: 20; startY: 20 + PathLine { x: 180; y: 130 } + PathLine { x: 20; y: 130 } + PathLine { x: 20; y: 20 } + } + transform: Rotation { origin.x: 100; origin.y: 50; axis { x: 0; y: 1; z: 0 } + SequentialAnimation on angle { + NumberAnimation { from: 0; to: 75; duration: 2000 } + NumberAnimation { from: 75; to: -75; duration: 4000 } + NumberAnimation { from: -75; to: 0; duration: 2000 } + loops: Animation.Infinite + } + } + } +} diff --git a/examples/quick/shapes/main.cpp b/examples/quick/shapes/main.cpp index 60f6c98f42d..8e3e1137f82 100644 --- a/examples/quick/shapes/main.cpp +++ b/examples/quick/shapes/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. diff --git a/examples/quick/shapes/main.qml b/examples/quick/shapes/main.qml new file mode 100644 index 00000000000..1ddb9d07841 --- /dev/null +++ b/examples/quick/shapes/main.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import shared + +Item { + width: 1280 + height: 720 + LauncherList { + anchors.fill: parent + Component.onCompleted: { + addExample("Shape Gallery", "Simple path rendering examples", Qt.resolvedUrl("shapegallery.qml")) + addExample("Interactive Shape", "Dynamic, interactive path rendering examples", Qt.resolvedUrl("interactive.qml")) + addExample("Super- and multisampling", "Improving quality", Qt.resolvedUrl("sampling.qml")) + addExample("Clip My Tiger!", "Clip examples, a.k.a. What Not To Do", Qt.resolvedUrl("clippedtigers.qml")) + } + } +} diff --git a/examples/quick/shapes/quadraticCurve.qml b/examples/quick/shapes/quadraticCurve.qml new file mode 100644 index 00000000000..311ff471d06 --- /dev/null +++ b/examples/quick/shapes/quadraticCurve.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + + Item { + width: 200 + height: 100 + anchors.centerIn: parent + + Shape { + id: shape + anchors.fill: parent + + ShapePath { + strokeWidth: 4 + strokeColor: "black" + fillColor: "transparent" + + startX: 50 + startY: 50 + PathQuad { + x: 150; y: 50 + controlX: cp.x; controlY: cp.y + } + } + } + + Rectangle { + id: cp + color: "red" + width: 10 + height: 10 + SequentialAnimation on x { + loops: Animation.Infinite + NumberAnimation { + from: 0 + to: shape.width - cp.width + duration: 5000 + } + NumberAnimation { + from: shape.width - cp.width + to: 0 + duration: 5000 + } + } + } + } +} diff --git a/examples/quick/shapes/radialGradient.qml b/examples/quick/shapes/radialGradient.qml new file mode 100644 index 00000000000..f64f02c5d9f --- /dev/null +++ b/examples/quick/shapes/radialGradient.qml @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + Shape { + width: 200 + height: 150 + anchors.centerIn: parent + ShapePath { + strokeWidth: 4 + strokeColor: "red" + fillGradient: RadialGradient { + centerX: 100; centerY: 100; centerRadius: 100 + SequentialAnimation on focalRadius { + loops: Animation.Infinite + NumberAnimation { from: 1; to: 20; duration: 2000 } + NumberAnimation { from: 20; to: 1; duration: 2000 } + } + SequentialAnimation on focalX { + loops: Animation.Infinite + NumberAnimation { from: 50; to: 150; duration: 3000 } + NumberAnimation { from: 150; to: 50; duration: 3000 } + } + SequentialAnimation on focalY { + loops: Animation.Infinite + NumberAnimation { from: 50; to: 150; duration: 1000 } + NumberAnimation { from: 150; to: 50; duration: 1000 } + } + GradientStop { position: 0; color: "#ffffff" } + GradientStop { position: 0.11; color: "#f9ffa0" } + GradientStop { position: 0.13; color: "#f9ff99" } + GradientStop { position: 0.14; color: "#f3ff86" } + GradientStop { position: 0.49; color: "#93b353" } + GradientStop { position: 0.87; color: "#264619" } + GradientStop { position: 0.96; color: "#0c1306" } + GradientStop { position: 1; color: "#000000" } + } + fillColor: "blue" // ignored with the gradient set + strokeStyle: ShapePath.DashLine + dashPattern: [ 1, 4 ] + startX: 20; startY: 20 + PathLine { x: 180; y: 130 } + PathLine { x: 20; y: 130 } + PathLine { x: 20; y: 20 } + } + } +} diff --git a/examples/quick/shapes/content/sampling.qml b/examples/quick/shapes/sampling.qml similarity index 98% rename from examples/quick/shapes/content/sampling.qml rename to examples/quick/shapes/sampling.qml index 6b651f8a1dc..ca45a3ab7c8 100644 --- a/examples/quick/shapes/content/sampling.qml +++ b/examples/quick/shapes/sampling.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.9 -import QtQuick.Shapes 1.0 +import QtQuick +import QtQuick.Shapes Rectangle { id: root diff --git a/examples/quick/shapes/content/shapegallery.qml b/examples/quick/shapes/shapegallery.qml similarity index 89% rename from examples/quick/shapes/content/shapegallery.qml rename to examples/quick/shapes/shapegallery.qml index e5a7c514834..3683f0a8220 100644 --- a/examples/quick/shapes/content/shapegallery.qml +++ b/examples/quick/shapes/shapegallery.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.9 -import QtQuick.Shapes 1.0 +import QtQuick +import QtQuick.Shapes Rectangle { id: root @@ -72,67 +72,67 @@ Rectangle { } ListElement { name: "Stroke or fill only" - shapeUrl: "item2.qml" + shapeUrl: "strokeOrFill.qml" } ListElement { name: "Dash pattern" - shapeUrl: "item4.qml" + shapeUrl: "dashPattern.qml" } ListElement { name: "Linear gradient" - shapeUrl: "item5.qml" + shapeUrl: "linearGradient.qml" } ListElement { name: "Radial gradient" - shapeUrl: "item3.qml" + shapeUrl: "radialGradient.qml" } ListElement { name: "Fill rules" - shapeUrl: "item6.qml" + shapeUrl: "fillRules.qml" } ListElement { name: "Join styles" - shapeUrl: "item7.qml" + shapeUrl: "joinStyles.qml" } ListElement { name: "Cap styles" - shapeUrl: "item8.qml" + shapeUrl: "capStyles.qml" } ListElement { name: "Quadratic curve" - shapeUrl: "item9.qml" + shapeUrl: "quadraticCurve.qml" } ListElement { name: "Cubic curve" - shapeUrl: "item10.qml" + shapeUrl: "cubicCurve.qml" } ListElement { name: "Elliptical arc" - shapeUrl: "item11.qml" + shapeUrl: "ellipticalArcs.qml" } ListElement { name: "Gradient spread modes" - shapeUrl: "item12.qml" + shapeUrl: "gradientSpreadModes.qml" } ListElement { name: "Arc direction" - shapeUrl: "item13.qml" + shapeUrl: "arcDirection.qml" } ListElement { name: "Large/small arc" - shapeUrl: "item14.qml" + shapeUrl: "largeOrSmallArc.qml" } ListElement { name: "Arc rotation" - shapeUrl: "item15.qml" + shapeUrl: "arcRotation.qml" } ListElement { name: "Tiger" - shapeUrl: "item17.qml" + shapeUrl: "tigerLoader.qml" } ListElement { name: "Text" - shapeUrl: "item18.qml" + shapeUrl: "text.qml" } } diff --git a/examples/quick/shapes/shapes.pro b/examples/quick/shapes/shapes.pro index f99d941804e..eb2baae0b44 100644 --- a/examples/quick/shapes/shapes.pro +++ b/examples/quick/shapes/shapes.pro @@ -2,30 +2,9 @@ TEMPLATE = app QT += quick qml SOURCES += main.cpp -RESOURCES += shapes.qrc -OTHER_FILES += content/main.qml \ - content/shapegallery.qml \ - content/interactive.qml \ - content/sampling.qml \ - content/clippedtigers.qml \ - content/tiger.qml \ - content/tapableTriangle.qml \ - content/item2.qml \ - content/item3.qml \ - content/item4.qml \ - content/item5.qml \ - content/item6.qml \ - content/item7.qml \ - content/item8.qml \ - content/item9.qml \ - content/item10.qml \ - content/item11.qml \ - content/item12.qml \ - content/item13.qml \ - content/item14.qml \ - content/item15.qml \ - content/item17.qml \ - content/item18.qml +RESOURCES += \ + shapes.qrc \ + ../shared/shared.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/shapes INSTALLS += target diff --git a/examples/quick/shapes/shapes.qrc b/examples/quick/shapes/shapes.qrc index 6de463dd337..60bf842a3a0 100644 --- a/examples/quick/shapes/shapes.qrc +++ b/examples/quick/shapes/shapes.qrc @@ -1,33 +1,27 @@ - ../shared/LauncherList.qml - ../shared/SimpleLauncherDelegate.qml - ../shared/images/next.png - ../shared/images/back.png - ../shared/images/slider_handle.png - ../shared/Slider.qml - content/main.qml - content/shapegallery.qml - content/interactive.qml - content/sampling.qml - content/clippedtigers.qml - content/tiger.qml - content/tapableTriangle.qml - content/item2.qml - content/item3.qml - content/item4.qml - content/item5.qml - content/item6.qml - content/item7.qml - content/item8.qml - content/item9.qml - content/item10.qml - content/item11.qml - content/item12.qml - content/item13.qml - content/item14.qml - content/item15.qml - content/item17.qml - content/item18.qml + main.qml + shapegallery.qml + interactive.qml + sampling.qml + clippedtigers.qml + tiger.qml + tapableTriangle.qml + strokeOrFill.qml + dashPattern.qml + linearGradient.qml + radialGradient.qml + fillRules.qml + joinStyles.qml + capStyles.qml + quadraticCurve.qml + cubicCurve.qml + ellipticalArcs.qml + gradientSpreadModes.qml + arcDirection.qml + largeOrSmallArc.qml + arcRotation.qml + tigerLoader.qml + text.qml diff --git a/examples/quick/shapes/strokeOrFill.qml b/examples/quick/shapes/strokeOrFill.qml new file mode 100644 index 00000000000..fdb93bf0d88 --- /dev/null +++ b/examples/quick/shapes/strokeOrFill.qml @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256; height: 256 + + Shape { + id: circ1 + anchors.fill: parent + + ShapePath { + id: p1 + fillColor: "transparent" // stroke only + strokeWidth: 4 + + SequentialAnimation on strokeColor { + loops: Animation.Infinite + ColorAnimation { + from: "black" + to: "yellow" + duration: 5000 + } + ColorAnimation { + from: "yellow" + to: "green" + duration: 5000 + } + ColorAnimation { + from: "green" + to: "black" + duration: 5000 + } + } + + property real r: 60 + startX: circ1.width / 2 - r + startY: circ1.height / 2 - r + PathArc { + x: circ1.width / 2 + p1.r + y: circ1.height / 2 + p1.r + radiusX: p1.r; radiusY: p1.r + useLargeArc: true + } + PathArc { + x: circ1.width / 2 - p1.r + y: circ1.height / 2 - p1.r + radiusX: p1.r; radiusY: p1.r + useLargeArc: true + } + } + } + + Shape { + id: circ2 + anchors.fill: parent + + SequentialAnimation on opacity { + loops: Animation.Infinite + NumberAnimation { from: 1.0; to: 0.0; duration: 5000 } + NumberAnimation { from: 0.0; to: 1.0; duration: 5000 } + } + + ShapePath { + id: p2 + strokeWidth: -1 // or strokeColor: "transparent" + + SequentialAnimation on fillColor { + loops: Animation.Infinite + ColorAnimation { + from: "gray" + to: "purple" + duration: 3000 + } + ColorAnimation { + from: "purple" + to: "red" + duration: 3000 + } + ColorAnimation { + from: "red" + to: "gray" + duration: 3000 + } + } + + property real r: 40 + startX: circ2.width / 2 - r + startY: circ2.height / 2 - r + PathArc { + x: circ2.width / 2 + p2.r + y: circ2.height / 2 + p2.r + radiusX: p2.r; radiusY: p2.r + useLargeArc: true + } + PathArc { + x: circ2.width / 2 - p2.r + y: circ2.height / 2 - p2.r + radiusX: p2.r; radiusY: p2.r + useLargeArc: true + } + } + } +} diff --git a/examples/quick/shapes/content/tapableTriangle.qml b/examples/quick/shapes/tapableTriangle.qml similarity index 96% rename from examples/quick/shapes/content/tapableTriangle.qml rename to examples/quick/shapes/tapableTriangle.qml index 22ed577bcbe..b224a950346 100644 --- a/examples/quick/shapes/content/tapableTriangle.qml +++ b/examples/quick/shapes/tapableTriangle.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -48,12 +48,12 @@ ** ****************************************************************************/ -import QtQuick 2.12 -import QtQuick.Shapes 1.12 +import QtQuick +import QtQuick.Shapes Rectangle { - width: 120 - height: 120 + width: 256 + height: 256 color: th.pressed ? "steelBlue" : "lightGray" containmentMask: ctr diff --git a/examples/quick/shapes/text.qml b/examples/quick/shapes/text.qml new file mode 100644 index 00000000000..3914fe20855 --- /dev/null +++ b/examples/quick/shapes/text.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + + Shape { + anchors.centerIn: parent + width: 200 + height: 100 + + ShapePath { + id: capTest + strokeColor: "black" + strokeWidth: 1 + fillColor: "black" + + PathText { x: 0; y: 0; font.family: "Arial"; font.pixelSize: 150; text: "Qt!" } + } + } +} diff --git a/examples/quick/shapes/content/tiger.qml b/examples/quick/shapes/tiger.qml similarity index 99% rename from examples/quick/shapes/content/tiger.qml rename to examples/quick/shapes/tiger.qml index 371db791b00..0bdef97675d 100644 --- a/examples/quick/shapes/content/tiger.qml +++ b/examples/quick/shapes/tiger.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.12 -import QtQuick.Shapes 1.12 +import QtQuick +import QtQuick.Shapes Shape { asynchronous: true diff --git a/examples/quick/shapes/tigerLoader.qml b/examples/quick/shapes/tigerLoader.qml new file mode 100644 index 00000000000..d220fcdd7d9 --- /dev/null +++ b/examples/quick/shapes/tigerLoader.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +Rectangle { + color: "lightGray" + width: 256 + height: 256 + + Item { + anchors.fill: parent + + Text { + anchors.centerIn: parent + text: "Loading" + // Phase #1: Loader loads tiger.qml. After this we have our item. + // Phase #2: With some backends (generic) the item will start async processing. Wait for this too. + visible: shapeLoader.status != Loader.Ready || shapeLoader.item.status === Shape.Processing + } + + Loader { + id: shapeLoader + anchors.fill: parent + source: "tiger.qml" + asynchronous: true + visible: status == Loader.Ready + scale: 0.4 + } + } +} diff --git a/examples/quick/shared/CMakeLists.txt b/examples/quick/shared/CMakeLists.txt new file mode 100644 index 00000000000..ad3e89f6ff9 --- /dev/null +++ b/examples/quick/shared/CMakeLists.txt @@ -0,0 +1,55 @@ +set_source_files_properties(CheckBox.qml TabSet.qml TextField.qml + PROPERTIES + QT_QML_SOURCE_VERSIONS 2.1 +) + +set_source_files_properties(Images.qml + PROPERTIES + QT_QML_SINGLETON_TYPE true + QT_QML_SOURCE_VERSIONS 2.2 +) + +qt_add_qml_module(${PROJECT_NAME}_shared + URI shared + VERSION 2.2 + PLUGIN_TARGET ${PROJECT_NAME}_shared + SOURCES + "shared.h" + QML_FILES + "Button.qml" + "CheckBox.qml" + "FlickrRssModel.qml" + "Label.qml" + "LauncherList.qml" + "SimpleLauncherDelegate.qml" + "Slider.qml" + "TabSet.qml" + "TextField.qml" + "Images.qml" + RESOURCES + "images/back.png" + "images/checkmark.png" + "images/next.png" + "images/qt-logo.png" + "images/slider_handle.png" + "images/tab.png" +) + +include(QtBundleQmlModuleForMacOS.cmake) +# Puts the shared qml module plugin and qmldir into the macOS app bundle directory. +# Only call this function if your main project has the MACOSX_BUNDLE option set. +function(bundle_shared app_target) + set(qml_plugin_target "${PROJECT_NAME}_shared") + set(qml_module_uri "shared") + add_qml_module_to_macos_app_bundle( + "${app_target}" "${qml_plugin_target}" "${qml_module_uri}") +endfunction() + +set(INSTALL_SHAREDDIR "${INSTALL_EXAMPLESDIR}/quick/${PROJECT_NAME}/shared") +install(TARGETS ${PROJECT_NAME}_shared + RUNTIME DESTINATION "${INSTALL_SHAREDDIR}" + LIBRARY DESTINATION "${INSTALL_SHAREDDIR}" +) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qmldir + DESTINATION "${INSTALL_SHAREDDIR}" +) diff --git a/examples/quick/shared/Images.qml b/examples/quick/shared/Images.qml new file mode 100644 index 00000000000..f3093cc8419 --- /dev/null +++ b/examples/quick/shared/Images.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +pragma Singleton +import QtQml + +QtObject { + readonly property url back: Qt.resolvedUrl("images/back.png") + readonly property url checkmark: Qt.resolvedUrl("images/checkmark.png") + readonly property url next: Qt.resolvedUrl("images/next.png") + readonly property url qtLogo: Qt.resolvedUrl("images/qt-logo.png") + readonly property url sliderHandle: Qt.resolvedUrl("images/slider_handle.png") + readonly property url tab: Qt.resolvedUrl("images/tab.png") +} diff --git a/examples/quick/shared/QtBundleQmlModuleForMacOS.cmake b/examples/quick/shared/QtBundleQmlModuleForMacOS.cmake new file mode 100644 index 00000000000..86edd352ebd --- /dev/null +++ b/examples/quick/shared/QtBundleQmlModuleForMacOS.cmake @@ -0,0 +1,29 @@ +function(add_qml_module_to_macos_app_bundle app_target qml_plugin_target qml_module_uri) + if(QT6_IS_SHARED_LIBS_BUILD AND APPLE) + # The application's main.cpp adds an explicit QML import path to look for qml module plugins + # under a PlugIns subdirectory of a macOS app bundle. + # Copy the qmldir and shared library qml plugin. + + # Ensure the executable depends on the plugin so the plugin is copied + # only after it was built. + add_dependencies(${app_target} ${qml_plugin_target}) + + set(app_dir "$") + + string(REGEX REPLACE "[^A-Za-z0-9]" "_" escaped_uri "${qml_module_uri}") + + set(dest_module_dir_in_app_bundle "${app_dir}/../PlugIns/${escaped_uri}") + + set(qml_plugin_dir "$") + set(qmldir_file "${qml_plugin_dir}/qmldir") + + add_custom_command(TARGET ${app_target} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${dest_module_dir_in_app_bundle} + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ ${dest_module_dir_in_app_bundle} + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${qmldir_file} ${dest_module_dir_in_app_bundle} + ) + endif() +endfunction() + diff --git a/examples/quick/shared/qmldir b/examples/quick/shared/qmldir index b539191fecc..5ccdf602194 100644 --- a/examples/quick/shared/qmldir +++ b/examples/quick/shared/qmldir @@ -1,7 +1,11 @@ +module shared Button 2.0 Button.qml CheckBox 2.1 CheckBox.qml +FlickrRssModel 2.0 FlickrRssModel.qml +Label 2.0 Label.qml LauncherList 2.0 LauncherList.qml SimpleLauncherDelegate 2.0 SimpleLauncherDelegate.qml Slider 2.0 Slider.qml TabSet 2.1 TabSet.qml TextField 2.1 TextField.qml +singleton Images 2.2 Images.qml diff --git a/examples/quick/shared/shared.h b/examples/quick/shared/shared.h index a6a468ddcb9..96bef11d986 100644 --- a/examples/quick/shared/shared.h +++ b/examples/quick/shared/shared.h @@ -52,6 +52,14 @@ #include #include #include //Not using QQmlApplicationEngine because many examples don't have a Window{} + +#ifdef Q_OS_MACOS +#define ADD_MACOS_BUNDLE_IMPORT_PATH \ + view.engine()->addImportPath(app.applicationDirPath() + QStringLiteral("/../PlugIns")); +#else +#define ADD_MACOS_BUNDLE_IMPORT_PATH +#endif + #define DECLARATIVE_EXAMPLE_MAIN(NAME) int main(int argc, char* argv[]) \ {\ QGuiApplication app(argc,argv);\ @@ -59,13 +67,15 @@ app.setOrganizationDomain("qt-project.org");\ app.setApplicationName(QFileInfo(app.applicationFilePath()).baseName());\ QQuickView view;\ - if (qgetenv("QT_QUICK_CORE_PROFILE").toInt()) {\ + ADD_MACOS_BUNDLE_IMPORT_PATH\ + view.engine()->addImportPath(QStringLiteral(":/"));\ + if (qEnvironmentVariableIntValue("QT_QUICK_CORE_PROFILE")) {\ QSurfaceFormat f = view.format();\ f.setProfile(QSurfaceFormat::CoreProfile);\ f.setVersion(4, 4);\ view.setFormat(f);\ }\ - if (qgetenv("QT_QUICK_MULTISAMPLE").toInt()) {\ + if (qEnvironmentVariableIntValue("QT_QUICK_MULTISAMPLE")) {\ QSurfaceFormat f = view.format();\ f.setSamples(4);\ view.setFormat(f);\ diff --git a/examples/quick/shared/shared.qrc b/examples/quick/shared/shared.qrc index cce683f8a32..c19063a585d 100644 --- a/examples/quick/shared/shared.qrc +++ b/examples/quick/shared/shared.qrc @@ -1,19 +1,21 @@ + Button.qml + CheckBox.qml FlickrRssModel.qml + Images.qml + Label.qml LauncherList.qml SimpleLauncherDelegate.qml - Button.qml Slider.qml - images/slider_handle.png - CheckBox.qml - Label.qml TabSet.qml TextField.qml images/back.png + images/checkmark.png images/next.png images/qt-logo.png - images/checkmark.png + images/slider_handle.png images/tab.png + qmldir diff --git a/examples/quick/tableview/gameoflife/CMakeLists.txt b/examples/quick/tableview/gameoflife/CMakeLists.txt index 4592943c111..f47c27a7cec 100644 --- a/examples/quick/tableview/gameoflife/CMakeLists.txt +++ b/examples/quick/tableview/gameoflife/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from gameoflife.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(gameoflife LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -35,18 +35,12 @@ target_link_libraries(gameoflife PUBLIC Qt::Quick ) - -# Resources: -set(qmake_immediate_resource_files - "gosperglidergun.cells" - "main.qml" -) - -qt6_add_resources(gameoflife "qmake_immediate" - PREFIX - "/" - FILES - ${qmake_immediate_resource_files} +qt_add_qml_module(gameoflife + URI GameOfLifeModel + VERSION 1.0 + QML_FILES main.qml + RESOURCES gosperglidergun.cells + NO_RESOURCE_TARGET_PATH ) install(TARGETS gameoflife @@ -54,10 +48,3 @@ install(TARGETS gameoflife BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(gameoflife PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI GameOfLifeModel -) - -qt6_qml_type_registration(gameoflife) diff --git a/examples/quick/tableview/pixelator/CMakeLists.txt b/examples/quick/tableview/pixelator/CMakeLists.txt index 41b0a139c87..4db28964df7 100644 --- a/examples/quick/tableview/pixelator/CMakeLists.txt +++ b/examples/quick/tableview/pixelator/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from pixelator.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(qml_pixelator LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -35,18 +35,12 @@ target_link_libraries(qml_pixelator PUBLIC Qt::Quick ) - -# Resources: -set(qmake_immediate_resource_files - "main.qml" - "qt.png" -) - -qt6_add_resources(qml_pixelator "qmake_immediate" - PREFIX - "/" - FILES - ${qmake_immediate_resource_files} +qt_add_qml_module(qml_pixelator + URI ImageModel + VERSION 1.0 + QML_FILES main.qml + RESOURCES qt.png + NO_RESOURCE_TARGET_PATH ) install(TARGETS qml_pixelator @@ -54,10 +48,3 @@ install(TARGETS qml_pixelator BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) - -set_target_properties(qml_pixelator PROPERTIES - QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI ImageModel -) - -qt6_qml_type_registration(qml_pixelator) diff --git a/examples/quick/text/.prev_CMakeLists.txt b/examples/quick/text/.prev_CMakeLists.txt deleted file mode 100644 index ada8f2b376a..00000000000 --- a/examples/quick/text/.prev_CMakeLists.txt +++ /dev/null @@ -1,99 +0,0 @@ -# Generated from text.pro. - -cmake_minimum_required(VERSION 3.14) -project(text LANGUAGES CXX) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -set(CMAKE_AUTOUIC ON) - -if(NOT DEFINED INSTALL_EXAMPLESDIR) - set(INSTALL_EXAMPLESDIR "examples") -endif() - -set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/text") - -find_package(Qt6 COMPONENTS Core) -find_package(Qt6 COMPONENTS Gui) -find_package(Qt6 COMPONENTS Quick) -find_package(Qt6 COMPONENTS Qml) - -qt_add_executable(text - main.cpp -) -set_target_properties(text PROPERTIES - WIN32_EXECUTABLE TRUE - MACOSX_BUNDLE TRUE -) -target_link_libraries(text PUBLIC - Qt::Core - Qt::Gui - Qt::Qml - Qt::Quick -) - - -# Resources: -set(text_resource_files - "fonts/availableFonts.qml" - "fonts/banner.qml" - "fonts/content/fonts/tarzeau_ocr_a.ttf" - "fonts/fonts.qml" - "fonts/hello.qml" - "imgtag/TextWithImage.qml" - "imgtag/images/face-sad.png" - "imgtag/images/face-smile-big.png" - "imgtag/images/face-smile.png" - "imgtag/images/heart200.png" - "imgtag/images/qtlogo.png" - "imgtag/images/starfish_2.png" - "imgtag/imgtag.qml" - "styledtext-layout.qml" - "text.qml" - "textselection/pics/endHandle.png" - "textselection/pics/endHandle.sci" - "textselection/pics/startHandle.png" - "textselection/pics/startHandle.sci" - "textselection/textselection.qml" -) - -qt6_add_resources(text "text" - PREFIX - "/text" - FILES - ${text_resource_files} -) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(text "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} -) - -install(TARGETS text - RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" - BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" - LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" -) diff --git a/examples/quick/text/CMakeLists.txt b/examples/quick/text/CMakeLists.txt index 570b0a59dff..e2fa455b8b6 100644 --- a/examples/quick/text/CMakeLists.txt +++ b/examples/quick/text/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from text.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(text LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -20,82 +20,53 @@ find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Quick) find_package(Qt6 COMPONENTS Qml) -qt_add_executable(text +add_subdirectory("../shared" "shared") + +qt_add_executable(textexample main.cpp ) -set_target_properties(text PROPERTIES +set_target_properties(textexample PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) -target_link_libraries(text PUBLIC +target_link_libraries(textexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(textexample text_shared) - -# Resources: -set(text_resource_files - "fonts/availableFonts.qml" - "fonts/banner.qml" - "fonts/content/fonts/tarzeau_ocr_a.ttf" - "fonts/fonts.qml" - "fonts/hello.qml" - "imgtag/TextWithImage.qml" - "imgtag/images/face-sad.png" - "imgtag/images/face-smile-big.png" - "imgtag/images/face-smile.png" - "imgtag/images/heart200.png" - "imgtag/images/qtlogo.png" - "imgtag/images/starfish_2.png" - "imgtag/imgtag.qml" - "styledtext-layout.qml" - "text.qml" - "textselection/pics/endHandle.png" - "textselection/pics/endHandle.sci" - "textselection/pics/startHandle.png" - "textselection/pics/startHandle.sci" - "textselection/textselection.qml" -) - -qt6_add_resources(text "text" - PREFIX - "/text" - FILES - ${text_resource_files} +qt_add_qml_module(textexample + URI text + VERSION 1.0 + QML_FILES + "fonts/availableFonts.qml" + "fonts/banner.qml" + "fonts/fonts.qml" + "fonts/hello.qml" + "imgtag/TextWithImage.qml" + "imgtag/imgtag.qml" + "styledtext-layout.qml" + "text.qml" + "textselection/textselection.qml" + RESOURCES + "fonts/content/fonts/tarzeau_ocr_a.ttf" + "imgtag/images/face-sad.png" + "imgtag/images/face-smile-big.png" + "imgtag/images/face-smile.png" + "imgtag/images/heart200.png" + "imgtag/images/qtlogo.png" + "imgtag/images/starfish_2.png" + "textselection/pics/endHandle.png" + "textselection/pics/endHandle.sci" + "textselection/pics/startHandle.png" + "textselection/pics/startHandle.sci" ) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(text "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} -) - -qt_import_qml_plugins(text) # special case -install(TARGETS text +install(TARGETS textexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) +bundle_shared(textexample) diff --git a/examples/quick/text/text.qml b/examples/quick/text/text.qml index f97a4e62dee..fd63cbd5d0f 100644 --- a/examples/quick/text/text.qml +++ b/examples/quick/text/text.qml @@ -49,7 +49,7 @@ ****************************************************************************/ import QtQuick 2.0 -import "../shared" +import shared Item { height: 480 diff --git a/examples/quick/text/text.qmlproject b/examples/quick/text/text.qmlproject index c08d9b9a89e..5613abe903c 100644 --- a/examples/quick/text/text.qmlproject +++ b/examples/quick/text/text.qmlproject @@ -2,6 +2,7 @@ import QmlProject 1.1 Project { mainFile: "text.qml" + importPaths: ["../"] /* Include .qml, .js, and image files from current directory and subdirectories */ QmlFiles { diff --git a/examples/quick/threading/CMakeLists.txt b/examples/quick/threading/CMakeLists.txt index cb1a13835ba..eb08dbe6128 100644 --- a/examples/quick/threading/CMakeLists.txt +++ b/examples/quick/threading/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from threading.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(threading LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -20,66 +20,38 @@ find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Quick) find_package(Qt6 COMPONENTS Qml) -qt_add_executable(threading +add_subdirectory("../shared" "shared") + +qt_add_executable(threadingexample main.cpp ) -set_target_properties(threading PROPERTIES +set_target_properties(threadingexample PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) -target_link_libraries(threading PUBLIC +target_link_libraries(threadingexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(threadingexample threading_shared) - -# Resources: -set(threading_resource_files - "threadedlistmodel/dataloader.mjs" - "threadedlistmodel/timedisplay.qml" - "threading.qml" - "workerscript/Spinner.qml" - "workerscript/workerscript.mjs" - "workerscript/workerscript.qml" -) - -qt6_add_resources(threading "threading" - PREFIX - "/threading" - FILES - ${threading_resource_files} -) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(threading "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} +qt_add_qml_module(threadingexample + URI threading + VERSION 1.0 + QML_FILES + "threadedlistmodel/dataloader.mjs" + "threadedlistmodel/timedisplay.qml" + "threading.qml" + "workerscript/Spinner.qml" + "workerscript/workerscript.mjs" + "workerscript/workerscript.qml" ) -install(TARGETS threading +install(TARGETS threadingexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) +bundle_shared(threadingexample) diff --git a/examples/quick/threading/threading.qml b/examples/quick/threading/threading.qml index 674e4a4bc66..1732293cf2c 100644 --- a/examples/quick/threading/threading.qml +++ b/examples/quick/threading/threading.qml @@ -49,7 +49,7 @@ ****************************************************************************/ import QtQuick 2.0 -import "../shared" as Examples +import shared as Examples Item { height: 480 diff --git a/examples/quick/threading/threading.qmlproject b/examples/quick/threading/threading.qmlproject index d17405d4dcd..877dcd7d635 100644 --- a/examples/quick/threading/threading.qmlproject +++ b/examples/quick/threading/threading.qmlproject @@ -2,6 +2,7 @@ import QmlProject 1.1 Project { mainFile: "threading.qml" + importPaths: ["../"] /* Include .qml, .js, and image files from current directory and subdirectories */ QmlFiles { diff --git a/examples/quick/touchinteraction/CMakeLists.txt b/examples/quick/touchinteraction/CMakeLists.txt index 4435a6a3075..f2856b7f6ec 100644 --- a/examples/quick/touchinteraction/CMakeLists.txt +++ b/examples/quick/touchinteraction/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from touchinteraction.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(touchinteraction LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -20,83 +20,56 @@ find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Quick) find_package(Qt6 COMPONENTS Qml) -qt_add_executable(touchinteraction +add_subdirectory("../shared" "shared") + +qt_add_executable(touchinteractionexample main.cpp ) -set_target_properties(touchinteraction PROPERTIES +set_target_properties(touchinteractionexample PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) -target_link_libraries(touchinteraction PUBLIC +target_link_libraries(touchinteractionexample PUBLIC Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(touchinteractionexample touchinteraction_shared) - -# Resources: -set(touchinteraction_resource_files - "flickable/basic-flickable.qml" - "flickable/content/Panel.qml" - "flickable/content/cork.jpg" - "flickable/content/note-yellow.png" - "flickable/content/tack.png" - "flickable/corkboards.qml" - "multipointtouch/bearwhack.qml" - "multipointtouch/content/AugmentedTouchPoint.qml" - "multipointtouch/content/Bear0.png" - "multipointtouch/content/Bear1.png" - "multipointtouch/content/Bear2.png" - "multipointtouch/content/Bear3.png" - "multipointtouch/content/BearB.png" - "multipointtouch/content/BearWhackParticleSystem.qml" - "multipointtouch/content/ParticleFlame.qml" - "multipointtouch/content/blur-circle.png" - "multipointtouch/content/blur-circle3.png" - "multipointtouch/content/heart-blur.png" - "multipointtouch/content/title.png" - "multipointtouch/multiflame.qml" - "pincharea/flickresize.qml" - "pincharea/qt-logo.jpg" - "touchinteraction.qml" -) - -qt6_add_resources(touchinteraction "touchinteraction" - PREFIX - "/touchinteraction" - FILES - ${touchinteraction_resource_files} -) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(touchinteraction "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} +qt_add_qml_module(touchinteractionexample + URI touchinteraction + VERSION 1.0 + QML_FILES + "flickable/Panel.qml" + "flickable/basic-flickable.qml" + "flickable/corkboards.qml" + "multipointtouch/AugmentedTouchPoint.qml" + "multipointtouch/BearWhackParticleSystem.qml" + "multipointtouch/ParticleFlame.qml" + "multipointtouch/bearwhack.qml" + "multipointtouch/multiflame.qml" + "pincharea/flickresize.qml" + "touchinteraction.qml" + RESOURCES + "flickable/cork.jpg" + "flickable/note-yellow.png" + "flickable/tack.png" + "multipointtouch/Bear0.png" + "multipointtouch/Bear1.png" + "multipointtouch/Bear2.png" + "multipointtouch/Bear3.png" + "multipointtouch/BearB.png" + "multipointtouch/blur-circle.png" + "multipointtouch/blur-circle3.png" + "multipointtouch/heart-blur.png" + "multipointtouch/title.png" + "pincharea/qt-logo.jpg" ) -install(TARGETS touchinteraction +install(TARGETS touchinteractionexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) +bundle_shared(touchinteractionexample) diff --git a/examples/quick/touchinteraction/doc/src/touchinteraction.qdoc b/examples/quick/touchinteraction/doc/src/touchinteraction.qdoc index 8526a9d58f4..4adf1f8c035 100644 --- a/examples/quick/touchinteraction/doc/src/touchinteraction.qdoc +++ b/examples/quick/touchinteraction/doc/src/touchinteraction.qdoc @@ -56,7 +56,7 @@ is done through a SpriteGoal that follows the TouchPoint. The TouchPoints added to the MultiPointTouchArea are a component with the relevant logic embedded into it: - \snippet touchinteraction/multipointtouch/content/AugmentedTouchPoint.qml 0 + \snippet touchinteraction/multipointtouch/AugmentedTouchPoint.qml 0 \section1 Flick Resize Example diff --git a/examples/quick/touchinteraction/flickable/content/Panel.qml b/examples/quick/touchinteraction/flickable/Panel.qml similarity index 100% rename from examples/quick/touchinteraction/flickable/content/Panel.qml rename to examples/quick/touchinteraction/flickable/Panel.qml diff --git a/examples/quick/touchinteraction/flickable/content/cork.jpg b/examples/quick/touchinteraction/flickable/cork.jpg similarity index 100% rename from examples/quick/touchinteraction/flickable/content/cork.jpg rename to examples/quick/touchinteraction/flickable/cork.jpg diff --git a/examples/quick/touchinteraction/flickable/corkboards.qml b/examples/quick/touchinteraction/flickable/corkboards.qml index 4825053f3f5..2188219a640 100644 --- a/examples/quick/touchinteraction/flickable/corkboards.qml +++ b/examples/quick/touchinteraction/flickable/corkboards.qml @@ -49,7 +49,6 @@ ****************************************************************************/ import QtQuick 2.0 -import "content" Rectangle { width: 320; height: 480 diff --git a/examples/quick/touchinteraction/flickable/content/note-yellow.png b/examples/quick/touchinteraction/flickable/note-yellow.png similarity index 100% rename from examples/quick/touchinteraction/flickable/content/note-yellow.png rename to examples/quick/touchinteraction/flickable/note-yellow.png diff --git a/examples/quick/touchinteraction/flickable/content/tack.png b/examples/quick/touchinteraction/flickable/tack.png similarity index 100% rename from examples/quick/touchinteraction/flickable/content/tack.png rename to examples/quick/touchinteraction/flickable/tack.png diff --git a/examples/quick/touchinteraction/multipointtouch/content/AugmentedTouchPoint.qml b/examples/quick/touchinteraction/multipointtouch/AugmentedTouchPoint.qml similarity index 100% rename from examples/quick/touchinteraction/multipointtouch/content/AugmentedTouchPoint.qml rename to examples/quick/touchinteraction/multipointtouch/AugmentedTouchPoint.qml diff --git a/examples/quick/touchinteraction/multipointtouch/content/Bear0.png b/examples/quick/touchinteraction/multipointtouch/Bear0.png similarity index 100% rename from examples/quick/touchinteraction/multipointtouch/content/Bear0.png rename to examples/quick/touchinteraction/multipointtouch/Bear0.png diff --git a/examples/quick/touchinteraction/multipointtouch/content/Bear1.png b/examples/quick/touchinteraction/multipointtouch/Bear1.png similarity index 100% rename from examples/quick/touchinteraction/multipointtouch/content/Bear1.png rename to examples/quick/touchinteraction/multipointtouch/Bear1.png diff --git a/examples/quick/touchinteraction/multipointtouch/content/Bear2.png b/examples/quick/touchinteraction/multipointtouch/Bear2.png similarity index 100% rename from examples/quick/touchinteraction/multipointtouch/content/Bear2.png rename to examples/quick/touchinteraction/multipointtouch/Bear2.png diff --git a/examples/quick/touchinteraction/multipointtouch/content/Bear3.png b/examples/quick/touchinteraction/multipointtouch/Bear3.png similarity index 100% rename from examples/quick/touchinteraction/multipointtouch/content/Bear3.png rename to examples/quick/touchinteraction/multipointtouch/Bear3.png diff --git a/examples/quick/touchinteraction/multipointtouch/content/BearB.png b/examples/quick/touchinteraction/multipointtouch/BearB.png similarity index 100% rename from examples/quick/touchinteraction/multipointtouch/content/BearB.png rename to examples/quick/touchinteraction/multipointtouch/BearB.png diff --git a/examples/quick/touchinteraction/multipointtouch/content/BearWhackParticleSystem.qml b/examples/quick/touchinteraction/multipointtouch/BearWhackParticleSystem.qml similarity index 100% rename from examples/quick/touchinteraction/multipointtouch/content/BearWhackParticleSystem.qml rename to examples/quick/touchinteraction/multipointtouch/BearWhackParticleSystem.qml diff --git a/examples/quick/touchinteraction/multipointtouch/content/ParticleFlame.qml b/examples/quick/touchinteraction/multipointtouch/ParticleFlame.qml similarity index 100% rename from examples/quick/touchinteraction/multipointtouch/content/ParticleFlame.qml rename to examples/quick/touchinteraction/multipointtouch/ParticleFlame.qml diff --git a/examples/quick/touchinteraction/multipointtouch/bearwhack.qml b/examples/quick/touchinteraction/multipointtouch/bearwhack.qml index 90c1a668910..5186d81e94a 100644 --- a/examples/quick/touchinteraction/multipointtouch/bearwhack.qml +++ b/examples/quick/touchinteraction/multipointtouch/bearwhack.qml @@ -49,7 +49,6 @@ ****************************************************************************/ import QtQuick 2.0 import QtQuick.Particles 2.0 -import "content" Item { id: root @@ -60,7 +59,7 @@ Item { anchors.fill: parent z: 1000 Image { - source: "content/title.png" + source: "title.png" anchors.centerIn: parent } MouseArea{ diff --git a/examples/quick/touchinteraction/multipointtouch/content/blur-circle.png b/examples/quick/touchinteraction/multipointtouch/blur-circle.png similarity index 100% rename from examples/quick/touchinteraction/multipointtouch/content/blur-circle.png rename to examples/quick/touchinteraction/multipointtouch/blur-circle.png diff --git a/examples/quick/touchinteraction/multipointtouch/content/blur-circle3.png b/examples/quick/touchinteraction/multipointtouch/blur-circle3.png similarity index 100% rename from examples/quick/touchinteraction/multipointtouch/content/blur-circle3.png rename to examples/quick/touchinteraction/multipointtouch/blur-circle3.png diff --git a/examples/quick/touchinteraction/multipointtouch/content/heart-blur.png b/examples/quick/touchinteraction/multipointtouch/heart-blur.png similarity index 100% rename from examples/quick/touchinteraction/multipointtouch/content/heart-blur.png rename to examples/quick/touchinteraction/multipointtouch/heart-blur.png diff --git a/examples/quick/touchinteraction/multipointtouch/multiflame.qml b/examples/quick/touchinteraction/multipointtouch/multiflame.qml index 514d583044b..47fccd65f67 100644 --- a/examples/quick/touchinteraction/multipointtouch/multiflame.qml +++ b/examples/quick/touchinteraction/multipointtouch/multiflame.qml @@ -48,7 +48,6 @@ ** ****************************************************************************/ import QtQuick 2.0 -import "content" Rectangle { width: 360 diff --git a/examples/quick/touchinteraction/multipointtouch/content/title.png b/examples/quick/touchinteraction/multipointtouch/title.png similarity index 100% rename from examples/quick/touchinteraction/multipointtouch/content/title.png rename to examples/quick/touchinteraction/multipointtouch/title.png diff --git a/examples/quick/touchinteraction/touchinteraction.qml b/examples/quick/touchinteraction/touchinteraction.qml index a95867b6c10..3b9bfdaab51 100644 --- a/examples/quick/touchinteraction/touchinteraction.qml +++ b/examples/quick/touchinteraction/touchinteraction.qml @@ -49,7 +49,7 @@ ****************************************************************************/ import QtQuick 2.0 -import "../shared" +import shared Item { height: 480 diff --git a/examples/quick/touchinteraction/touchinteraction.qmlproject b/examples/quick/touchinteraction/touchinteraction.qmlproject index a9aa9d2e818..50254f287f9 100644 --- a/examples/quick/touchinteraction/touchinteraction.qmlproject +++ b/examples/quick/touchinteraction/touchinteraction.qmlproject @@ -2,6 +2,7 @@ import QmlProject 1.1 Project { mainFile: "touchinteraction.qml" + importPaths: [ "../" ] /* Include .qml, .js, and image files from current directory and subdirectories */ QmlFiles { diff --git a/examples/quick/touchinteraction/touchinteraction.qrc b/examples/quick/touchinteraction/touchinteraction.qrc index 6cec506a0f5..cc5bcaceb0e 100644 --- a/examples/quick/touchinteraction/touchinteraction.qrc +++ b/examples/quick/touchinteraction/touchinteraction.qrc @@ -3,24 +3,24 @@ touchinteraction.qml flickable/basic-flickable.qml flickable/corkboards.qml - flickable/content/cork.jpg - flickable/content/note-yellow.png - flickable/content/Panel.qml - flickable/content/tack.png + flickable/cork.jpg + flickable/note-yellow.png + flickable/Panel.qml + flickable/tack.png multipointtouch/bearwhack.qml multipointtouch/multiflame.qml - multipointtouch/content/AugmentedTouchPoint.qml - multipointtouch/content/Bear0.png - multipointtouch/content/Bear1.png - multipointtouch/content/Bear2.png - multipointtouch/content/Bear3.png - multipointtouch/content/BearB.png - multipointtouch/content/BearWhackParticleSystem.qml - multipointtouch/content/blur-circle.png - multipointtouch/content/blur-circle3.png - multipointtouch/content/heart-blur.png - multipointtouch/content/ParticleFlame.qml - multipointtouch/content/title.png + multipointtouch/AugmentedTouchPoint.qml + multipointtouch/Bear0.png + multipointtouch/Bear1.png + multipointtouch/Bear2.png + multipointtouch/Bear3.png + multipointtouch/BearB.png + multipointtouch/BearWhackParticleSystem.qml + multipointtouch/blur-circle.png + multipointtouch/blur-circle3.png + multipointtouch/heart-blur.png + multipointtouch/ParticleFlame.qml + multipointtouch/title.png pincharea/flickresize.qml pincharea/qt-logo.jpg diff --git a/examples/quick/tutorials/CMakeLists.txt b/examples/quick/tutorials/CMakeLists.txt index 87d2caf01f0..b200b54f9f0 100644 --- a/examples/quick/tutorials/CMakeLists.txt +++ b/examples/quick/tutorials/CMakeLists.txt @@ -1,2 +1,2 @@ -# Generated from tutorials.pro. - +add_subdirectory(samegame) +add_subdirectory(dynamicview) diff --git a/examples/quick/tutorials/dynamicview/CMakeLists.txt b/examples/quick/tutorials/dynamicview/CMakeLists.txt new file mode 100644 index 00000000000..38f8e7907bf --- /dev/null +++ b/examples/quick/tutorials/dynamicview/CMakeLists.txt @@ -0,0 +1,4 @@ +qt_internal_add_example(dynamicview1) +qt_internal_add_example(dynamicview2) +qt_internal_add_example(dynamicview3) +qt_internal_add_example(dynamicview4) diff --git a/examples/quick/tutorials/dynamicview/dynamicview1/CMakeLists.txt b/examples/quick/tutorials/dynamicview/dynamicview1/CMakeLists.txt new file mode 100644 index 00000000000..2d38954fd91 --- /dev/null +++ b/examples/quick/tutorials/dynamicview/dynamicview1/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.16) +project(dynamicview1 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/tutorials/dynamicview/dynamicview1") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Qml) + +qt_add_executable(dynamicview1 + main.cpp +) +set_target_properties(dynamicview1 PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +qt_add_qml_module(dynamicview1 + URI dynamicview + VERSION 1.0 + QML_FILES + dynamicview.qml + PetsModel.qml +) + +target_link_libraries(dynamicview1 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +install(TARGETS dynamicview1 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quick/tutorials/dynamicview/dynamicview1/dynamicview.qml b/examples/quick/tutorials/dynamicview/dynamicview1/dynamicview.qml index 60167aa813f..228dc4b56f1 100644 --- a/examples/quick/tutorials/dynamicview/dynamicview1/dynamicview.qml +++ b/examples/quick/tutorials/dynamicview/dynamicview1/dynamicview.qml @@ -63,7 +63,7 @@ Rectangle { Rectangle { id: content - anchors { left: parent.left; right: parent.right } + width: ListView.view.width height: column.implicitHeight + 4 border.width: 1 diff --git a/examples/quick/tutorials/dynamicview/dynamicview1/dynamicview1.qrc b/examples/quick/tutorials/dynamicview/dynamicview1/dynamicview1.qrc index c89a5e3a97b..18b503f9ccc 100644 --- a/examples/quick/tutorials/dynamicview/dynamicview1/dynamicview1.qrc +++ b/examples/quick/tutorials/dynamicview/dynamicview1/dynamicview1.qrc @@ -1,5 +1,5 @@ - + dynamicview.qml PetsModel.qml diff --git a/examples/quick/tutorials/dynamicview/dynamicview1/main.cpp b/examples/quick/tutorials/dynamicview/dynamicview1/main.cpp index 72b8b667f51..710b1f868bd 100644 --- a/examples/quick/tutorials/dynamicview/dynamicview1/main.cpp +++ b/examples/quick/tutorials/dynamicview/dynamicview1/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(dynamicview) +DECLARATIVE_EXAMPLE_MAIN(dynamicview/dynamicview) diff --git a/examples/quick/tutorials/dynamicview/dynamicview2/CMakeLists.txt b/examples/quick/tutorials/dynamicview/dynamicview2/CMakeLists.txt new file mode 100644 index 00000000000..cbb7ac5b3ff --- /dev/null +++ b/examples/quick/tutorials/dynamicview/dynamicview2/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.16) +project(dynamicview2 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/tutorials/dynamicview/dynamicview2") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Qml) + +qt_add_executable(dynamicview2 + main.cpp +) +set_target_properties(dynamicview2 PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +qt_add_qml_module(dynamicview2 + URI dynamicview + VERSION 1.0 + QML_FILES + dynamicview.qml + PetsModel.qml +) + +target_link_libraries(dynamicview2 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +install(TARGETS dynamicview2 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quick/tutorials/dynamicview/dynamicview2/dynamicview2.qrc b/examples/quick/tutorials/dynamicview/dynamicview2/dynamicview2.qrc index c89a5e3a97b..18b503f9ccc 100644 --- a/examples/quick/tutorials/dynamicview/dynamicview2/dynamicview2.qrc +++ b/examples/quick/tutorials/dynamicview/dynamicview2/dynamicview2.qrc @@ -1,5 +1,5 @@ - + dynamicview.qml PetsModel.qml diff --git a/examples/quick/tutorials/dynamicview/dynamicview2/main.cpp b/examples/quick/tutorials/dynamicview/dynamicview2/main.cpp index 72b8b667f51..710b1f868bd 100644 --- a/examples/quick/tutorials/dynamicview/dynamicview2/main.cpp +++ b/examples/quick/tutorials/dynamicview/dynamicview2/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(dynamicview) +DECLARATIVE_EXAMPLE_MAIN(dynamicview/dynamicview) diff --git a/examples/quick/tutorials/dynamicview/dynamicview3/CMakeLists.txt b/examples/quick/tutorials/dynamicview/dynamicview3/CMakeLists.txt new file mode 100644 index 00000000000..242585423bd --- /dev/null +++ b/examples/quick/tutorials/dynamicview/dynamicview3/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.16) +project(dynamicview3 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/tutorials/dynamicview/dynamicview3") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Qml) + +qt_add_executable(dynamicview3 + main.cpp +) +set_target_properties(dynamicview3 PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +qt_add_qml_module(dynamicview3 + URI dynamicview + VERSION 1.0 + QML_FILES + dynamicview.qml + PetsModel.qml +) + +target_link_libraries(dynamicview3 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +install(TARGETS dynamicview3 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quick/tutorials/dynamicview/dynamicview3/dynamicview3.qrc b/examples/quick/tutorials/dynamicview/dynamicview3/dynamicview3.qrc index c89a5e3a97b..18b503f9ccc 100644 --- a/examples/quick/tutorials/dynamicview/dynamicview3/dynamicview3.qrc +++ b/examples/quick/tutorials/dynamicview/dynamicview3/dynamicview3.qrc @@ -1,5 +1,5 @@ - + dynamicview.qml PetsModel.qml diff --git a/examples/quick/tutorials/dynamicview/dynamicview3/main.cpp b/examples/quick/tutorials/dynamicview/dynamicview3/main.cpp index 72b8b667f51..710b1f868bd 100644 --- a/examples/quick/tutorials/dynamicview/dynamicview3/main.cpp +++ b/examples/quick/tutorials/dynamicview/dynamicview3/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(dynamicview) +DECLARATIVE_EXAMPLE_MAIN(dynamicview/dynamicview) diff --git a/examples/quick/tutorials/dynamicview/dynamicview4/CMakeLists.txt b/examples/quick/tutorials/dynamicview/dynamicview4/CMakeLists.txt new file mode 100644 index 00000000000..2faae8b119f --- /dev/null +++ b/examples/quick/tutorials/dynamicview/dynamicview4/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.16) +project(dynamicview4 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/tutorials/dynamicview/dynamicview4") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Qml) + +qt_add_executable(dynamicview4 + main.cpp +) +set_target_properties(dynamicview4 PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +qt_add_qml_module(dynamicview4 + URI dynamicview + VERSION 1.0 + QML_FILES + dynamicview.qml + ListSelector.qml + PetsModel.qml +) + +target_link_libraries(dynamicview4 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +install(TARGETS dynamicview4 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quick/tutorials/dynamicview/dynamicview4/dynamicview4.qrc b/examples/quick/tutorials/dynamicview/dynamicview4/dynamicview4.qrc index c89a5e3a97b..8615c442b2b 100644 --- a/examples/quick/tutorials/dynamicview/dynamicview4/dynamicview4.qrc +++ b/examples/quick/tutorials/dynamicview/dynamicview4/dynamicview4.qrc @@ -1,6 +1,8 @@ - + dynamicview.qml + ListSelector.qml PetsModel.qml + ListSelector.qml diff --git a/examples/quick/tutorials/dynamicview/dynamicview4/main.cpp b/examples/quick/tutorials/dynamicview/dynamicview4/main.cpp index 72b8b667f51..710b1f868bd 100644 --- a/examples/quick/tutorials/dynamicview/dynamicview4/main.cpp +++ b/examples/quick/tutorials/dynamicview/dynamicview4/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(dynamicview) +DECLARATIVE_EXAMPLE_MAIN(dynamicview/dynamicview) diff --git a/examples/quick/tutorials/samegame/CMakeLists.txt b/examples/quick/tutorials/samegame/CMakeLists.txt new file mode 100644 index 00000000000..df1a8256512 --- /dev/null +++ b/examples/quick/tutorials/samegame/CMakeLists.txt @@ -0,0 +1,4 @@ +qt_internal_add_example(samegame1) +qt_internal_add_example(samegame2) +qt_internal_add_example(samegame3) +qt_internal_add_example(samegame4) diff --git a/examples/quick/tutorials/samegame/samegame1/Block.qml b/examples/quick/tutorials/samegame/samegame1/Block.qml index eac8e938104..157a3aa0c9e 100644 --- a/examples/quick/tutorials/samegame/samegame1/Block.qml +++ b/examples/quick/tutorials/samegame/samegame1/Block.qml @@ -57,7 +57,7 @@ Item { Image { id: img anchors.fill: parent - source: "../shared/pics/redStone.png" + source: "pics/redStone.png" } } //![0] diff --git a/examples/quick/tutorials/samegame/samegame1/CMakeLists.txt b/examples/quick/tutorials/samegame/samegame1/CMakeLists.txt new file mode 100644 index 00000000000..ad791d77b5e --- /dev/null +++ b/examples/quick/tutorials/samegame/samegame1/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.16) +project(samegame1 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/tutorials/samegame/samegame1") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Qml) + +qt_add_executable(samegame1 + main.cpp +) +set_target_properties(samegame1 PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +qt_add_qml_module(samegame1 + URI samegame + VERSION 1.0 + QML_FILES + "Block.qml" + "Button.qml" + "samegame.qml" + RESOURCES + "pics/background.jpg" + "pics/redStone.png" +) + +target_link_libraries(samegame1 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +install(TARGETS samegame1 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quick/tutorials/samegame/samegame1/main.cpp b/examples/quick/tutorials/samegame/samegame1/main.cpp index 7589b929062..f76b5d89406 100644 --- a/examples/quick/tutorials/samegame/samegame1/main.cpp +++ b/examples/quick/tutorials/samegame/samegame1/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(samegame) +DECLARATIVE_EXAMPLE_MAIN(samegame/samegame) diff --git a/examples/quick/tutorials/samegame/shared/pics/background.jpg b/examples/quick/tutorials/samegame/samegame1/pics/background.jpg similarity index 100% rename from examples/quick/tutorials/samegame/shared/pics/background.jpg rename to examples/quick/tutorials/samegame/samegame1/pics/background.jpg diff --git a/examples/quick/tutorials/samegame/shared/pics/redStone.png b/examples/quick/tutorials/samegame/samegame1/pics/redStone.png similarity index 100% rename from examples/quick/tutorials/samegame/shared/pics/redStone.png rename to examples/quick/tutorials/samegame/samegame1/pics/redStone.png diff --git a/examples/quick/tutorials/samegame/samegame1/samegame.qml b/examples/quick/tutorials/samegame/samegame1/samegame.qml index 68a1921da7f..9eea87fc9c2 100644 --- a/examples/quick/tutorials/samegame/samegame1/samegame.qml +++ b/examples/quick/tutorials/samegame/samegame1/samegame.qml @@ -65,7 +65,7 @@ Rectangle { Image { id: background anchors.fill: parent - source: "../shared/pics/background.jpg" + source: "pics/background.jpg" fillMode: Image.PreserveAspectCrop } } diff --git a/examples/quick/tutorials/samegame/samegame1/samegame1.pro b/examples/quick/tutorials/samegame/samegame1/samegame1.pro index 9f316b68686..d523857d649 100644 --- a/examples/quick/tutorials/samegame/samegame1/samegame1.pro +++ b/examples/quick/tutorials/samegame/samegame1/samegame1.pro @@ -2,10 +2,7 @@ TEMPLATE = app QT += quick qml SOURCES += main.cpp - -RESOURCES += \ - samegame1.qrc \ - ../shared/pics/shared.qrc +RESOURCES += samegame1.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/tutorials/samegame/samegame1 INSTALLS += target diff --git a/examples/quick/tutorials/samegame/samegame1/samegame1.qrc b/examples/quick/tutorials/samegame/samegame1/samegame1.qrc index 866cf899bf6..1f061d606f0 100644 --- a/examples/quick/tutorials/samegame/samegame1/samegame1.qrc +++ b/examples/quick/tutorials/samegame/samegame1/samegame1.qrc @@ -1,7 +1,9 @@ - + Button.qml Block.qml samegame.qml + pics/background.jpg + pics/redStone.png diff --git a/examples/quick/tutorials/samegame/samegame2/Block.qml b/examples/quick/tutorials/samegame/samegame2/Block.qml index 12cc0ea0430..24672233b82 100644 --- a/examples/quick/tutorials/samegame/samegame2/Block.qml +++ b/examples/quick/tutorials/samegame/samegame2/Block.qml @@ -56,6 +56,6 @@ Item { Image { id: img anchors.fill: parent - source: "../shared/pics/redStone.png" + source: "pics/redStone.png" } } diff --git a/examples/quick/tutorials/samegame/samegame2/CMakeLists.txt b/examples/quick/tutorials/samegame/samegame2/CMakeLists.txt new file mode 100644 index 00000000000..5830622762e --- /dev/null +++ b/examples/quick/tutorials/samegame/samegame2/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.16) +project(samegame2 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/tutorials/samegame/samegame2") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Qml) + +qt_add_executable(samegame2 + main.cpp +) +set_target_properties(samegame2 PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +qt_add_qml_module(samegame2 + URI samegame + VERSION 1.0 + QML_FILES + "Block.qml" + "Button.qml" + "samegame.qml" + "samegame.js" + RESOURCES + "pics/background.jpg" + "pics/redStone.png" +) + +target_link_libraries(samegame2 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +install(TARGETS samegame2 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quick/tutorials/samegame/samegame2/main.cpp b/examples/quick/tutorials/samegame/samegame2/main.cpp index 7589b929062..f76b5d89406 100644 --- a/examples/quick/tutorials/samegame/samegame2/main.cpp +++ b/examples/quick/tutorials/samegame/samegame2/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(samegame) +DECLARATIVE_EXAMPLE_MAIN(samegame/samegame) diff --git a/examples/quick/tutorials/samegame/samegame2/pics/background.jpg b/examples/quick/tutorials/samegame/samegame2/pics/background.jpg new file mode 100644 index 00000000000..903d395c8d0 Binary files /dev/null and b/examples/quick/tutorials/samegame/samegame2/pics/background.jpg differ diff --git a/examples/quick/tutorials/samegame/samegame2/pics/redStone.png b/examples/quick/tutorials/samegame/samegame2/pics/redStone.png new file mode 100644 index 00000000000..36b09a26869 Binary files /dev/null and b/examples/quick/tutorials/samegame/samegame2/pics/redStone.png differ diff --git a/examples/quick/tutorials/samegame/samegame2/samegame.qml b/examples/quick/tutorials/samegame/samegame2/samegame.qml index 2c68fcf1556..473b52f9ed0 100644 --- a/examples/quick/tutorials/samegame/samegame2/samegame.qml +++ b/examples/quick/tutorials/samegame/samegame2/samegame.qml @@ -67,7 +67,7 @@ Rectangle { Image { id: background anchors.fill: parent - source: "../shared/pics/background.jpg" + source: "pics/background.jpg" fillMode: Image.PreserveAspectCrop } } diff --git a/examples/quick/tutorials/samegame/samegame2/samegame2.pro b/examples/quick/tutorials/samegame/samegame2/samegame2.pro index 5ede9042ccf..a0fc36e857c 100644 --- a/examples/quick/tutorials/samegame/samegame2/samegame2.pro +++ b/examples/quick/tutorials/samegame/samegame2/samegame2.pro @@ -2,10 +2,7 @@ TEMPLATE = app QT += quick qml SOURCES += main.cpp - -RESOURCES += \ - samegame2.qrc \ - ../shared/pics/shared.qrc +RESOURCES += samegame2.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/tutorials/samegame/samegame2 INSTALLS += target diff --git a/examples/quick/tutorials/samegame/samegame2/samegame2.qrc b/examples/quick/tutorials/samegame/samegame2/samegame2.qrc index 0f95174d835..f632e88f6aa 100644 --- a/examples/quick/tutorials/samegame/samegame2/samegame2.qrc +++ b/examples/quick/tutorials/samegame/samegame2/samegame2.qrc @@ -1,8 +1,10 @@ - + Button.qml Block.qml samegame.qml samegame.js + pics/background.jpg + pics/redStone.png diff --git a/examples/quick/tutorials/samegame/samegame3/Block.qml b/examples/quick/tutorials/samegame/samegame3/Block.qml index d49bf89727e..b543b06a7e0 100644 --- a/examples/quick/tutorials/samegame/samegame3/Block.qml +++ b/examples/quick/tutorials/samegame/samegame3/Block.qml @@ -62,11 +62,11 @@ Item { anchors.fill: parent source: { if (type == 0) - return "../shared/pics/redStone.png"; + return "pics/redStone.png"; else if (type == 1) - return "../shared/pics/blueStone.png"; + return "pics/blueStone.png"; else - return "../shared/pics/greenStone.png"; + return "pics/greenStone.png"; } } } diff --git a/examples/quick/tutorials/samegame/samegame3/CMakeLists.txt b/examples/quick/tutorials/samegame/samegame3/CMakeLists.txt new file mode 100644 index 00000000000..0c3aa34b9dd --- /dev/null +++ b/examples/quick/tutorials/samegame/samegame3/CMakeLists.txt @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.16) +project(samegame3 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/tutorials/samegame/samegame3") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Qml) + +qt_add_executable(samegame3 + main.cpp +) +set_target_properties(samegame3 PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +qt_add_qml_module(samegame3 + URI samegame + VERSION 1.0 + QML_FILES + "Block.qml" + "Button.qml" + "Dialog.qml" + "samegame.qml" + "samegame.js" + RESOURCES + "pics/background.jpg" + "pics/blueStone.png" + "pics/greenStone.png" + "pics/redStone.png" +) + +target_link_libraries(samegame3 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +install(TARGETS samegame3 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quick/tutorials/samegame/samegame3/main.cpp b/examples/quick/tutorials/samegame/samegame3/main.cpp index 7589b929062..f76b5d89406 100644 --- a/examples/quick/tutorials/samegame/samegame3/main.cpp +++ b/examples/quick/tutorials/samegame/samegame3/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(samegame) +DECLARATIVE_EXAMPLE_MAIN(samegame/samegame) diff --git a/examples/quick/tutorials/samegame/samegame3/pics/background.jpg b/examples/quick/tutorials/samegame/samegame3/pics/background.jpg new file mode 100644 index 00000000000..903d395c8d0 Binary files /dev/null and b/examples/quick/tutorials/samegame/samegame3/pics/background.jpg differ diff --git a/examples/quick/tutorials/samegame/shared/pics/blueStone.png b/examples/quick/tutorials/samegame/samegame3/pics/blueStone.png similarity index 100% rename from examples/quick/tutorials/samegame/shared/pics/blueStone.png rename to examples/quick/tutorials/samegame/samegame3/pics/blueStone.png diff --git a/examples/quick/tutorials/samegame/shared/pics/greenStone.png b/examples/quick/tutorials/samegame/samegame3/pics/greenStone.png similarity index 100% rename from examples/quick/tutorials/samegame/shared/pics/greenStone.png rename to examples/quick/tutorials/samegame/samegame3/pics/greenStone.png diff --git a/examples/quick/tutorials/samegame/samegame3/pics/redStone.png b/examples/quick/tutorials/samegame/samegame3/pics/redStone.png new file mode 100644 index 00000000000..36b09a26869 Binary files /dev/null and b/examples/quick/tutorials/samegame/samegame3/pics/redStone.png differ diff --git a/examples/quick/tutorials/samegame/samegame3/samegame.qml b/examples/quick/tutorials/samegame/samegame3/samegame.qml index 11376232a2d..a83cb01b7b9 100644 --- a/examples/quick/tutorials/samegame/samegame3/samegame.qml +++ b/examples/quick/tutorials/samegame/samegame3/samegame.qml @@ -66,7 +66,7 @@ Rectangle { Image { id: background anchors.fill: parent - source: "../shared/pics/background.jpg" + source: "pics/background.jpg" fillMode: Image.PreserveAspectCrop } diff --git a/examples/quick/tutorials/samegame/samegame3/samegame3.pro b/examples/quick/tutorials/samegame/samegame3/samegame3.pro index 7b99673e57b..88f8f87699e 100644 --- a/examples/quick/tutorials/samegame/samegame3/samegame3.pro +++ b/examples/quick/tutorials/samegame/samegame3/samegame3.pro @@ -2,10 +2,7 @@ TEMPLATE = app QT += quick qml SOURCES += main.cpp - -RESOURCES += \ - samegame3.qrc \ - ../shared/pics/shared.qrc +RESOURCES += samegame3.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/tutorials/samegame/samegame3 INSTALLS += target diff --git a/examples/quick/tutorials/samegame/samegame3/samegame3.qrc b/examples/quick/tutorials/samegame/samegame3/samegame3.qrc index 0f95174d835..16c90b45160 100644 --- a/examples/quick/tutorials/samegame/samegame3/samegame3.qrc +++ b/examples/quick/tutorials/samegame/samegame3/samegame3.qrc @@ -1,8 +1,13 @@ - + Button.qml Block.qml + Dialog.qml samegame.qml samegame.js + pics/background.jpg + pics/blueStone.png + pics/greenStone.png + pics/redStone.png diff --git a/examples/quick/tutorials/samegame/samegame4/content/BoomBlock.qml b/examples/quick/tutorials/samegame/samegame4/BoomBlock.qml similarity index 92% rename from examples/quick/tutorials/samegame/samegame4/content/BoomBlock.qml rename to examples/quick/tutorials/samegame/samegame4/BoomBlock.qml index 12cc64a09bd..83534375428 100644 --- a/examples/quick/tutorials/samegame/samegame4/content/BoomBlock.qml +++ b/examples/quick/tutorials/samegame/samegame4/BoomBlock.qml @@ -76,11 +76,11 @@ Item { anchors.fill: parent source: { if (block.type == 0) - return "../../shared/pics/redStone.png"; + return "pics/redStone.png"; else if (block.type == 1) - return "../../shared/pics/blueStone.png"; + return "pics/blueStone.png"; else - return "../../shared/pics/greenStone.png"; + return "pics/greenStone.png"; } opacity: 0 @@ -98,11 +98,11 @@ Item { // ![0] source: { if (block.type == 0) - return "../../shared/pics/redStar.png"; + return "pics/redStar.png"; else if (block.type == 1) - return "../../shared/pics/blueStar.png"; + return "pics/blueStar.png"; else - return "../../shared/pics/greenStar.png"; + return "pics/greenStar.png"; } rotationVelocityVariation: 360 // ![0] diff --git a/examples/quick/tutorials/samegame/samegame4/content/Button.qml b/examples/quick/tutorials/samegame/samegame4/Button.qml similarity index 100% rename from examples/quick/tutorials/samegame/samegame4/content/Button.qml rename to examples/quick/tutorials/samegame/samegame4/Button.qml diff --git a/examples/quick/tutorials/samegame/samegame4/CMakeLists.txt b/examples/quick/tutorials/samegame/samegame4/CMakeLists.txt new file mode 100644 index 00000000000..c89d1918730 --- /dev/null +++ b/examples/quick/tutorials/samegame/samegame4/CMakeLists.txt @@ -0,0 +1,62 @@ +cmake_minimum_required(VERSION 3.16) +project(samegame4 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/tutorials/samegame/samegame4") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS Qml) + +qt_add_executable(samegame4 + main.cpp +) +set_target_properties(samegame4 PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +qt_add_qml_module(samegame4 + URI samegame + VERSION 1.0 + QML_FILES + "BoomBlock.qml" + "Button.qml" + "Dialog.qml" + "samegame.qml" + "samegame.js" + RESOURCES + "highscores/README" + "highscores/score_data.xml" + "highscores/score_style.xsl" + "highscores/scores.php" + "pics/background.jpg" + "pics/blueStar.png" + "pics/blueStone.png" + "pics/greenStar.png" + "pics/greenStone.png" + "pics/redStar.png" + "pics/redStone.png" +) + +target_link_libraries(samegame4 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +install(TARGETS samegame4 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quick/tutorials/samegame/samegame4/content/Dialog.qml b/examples/quick/tutorials/samegame/samegame4/Dialog.qml similarity index 100% rename from examples/quick/tutorials/samegame/samegame4/content/Dialog.qml rename to examples/quick/tutorials/samegame/samegame4/Dialog.qml diff --git a/examples/quick/tutorials/samegame/samegame4/main.cpp b/examples/quick/tutorials/samegame/samegame4/main.cpp index 7589b929062..f76b5d89406 100644 --- a/examples/quick/tutorials/samegame/samegame4/main.cpp +++ b/examples/quick/tutorials/samegame/samegame4/main.cpp @@ -48,4 +48,4 @@ ** ****************************************************************************/ #include "../../../shared/shared.h" -DECLARATIVE_EXAMPLE_MAIN(samegame) +DECLARATIVE_EXAMPLE_MAIN(samegame/samegame) diff --git a/examples/quick/tutorials/samegame/samegame4/pics/background.jpg b/examples/quick/tutorials/samegame/samegame4/pics/background.jpg new file mode 100644 index 00000000000..903d395c8d0 Binary files /dev/null and b/examples/quick/tutorials/samegame/samegame4/pics/background.jpg differ diff --git a/examples/quick/tutorials/samegame/shared/pics/blueStar.png b/examples/quick/tutorials/samegame/samegame4/pics/blueStar.png similarity index 100% rename from examples/quick/tutorials/samegame/shared/pics/blueStar.png rename to examples/quick/tutorials/samegame/samegame4/pics/blueStar.png diff --git a/examples/quick/tutorials/samegame/samegame4/pics/blueStone.png b/examples/quick/tutorials/samegame/samegame4/pics/blueStone.png new file mode 100644 index 00000000000..20e43c75b6b Binary files /dev/null and b/examples/quick/tutorials/samegame/samegame4/pics/blueStone.png differ diff --git a/examples/quick/tutorials/samegame/shared/pics/greenStar.png b/examples/quick/tutorials/samegame/samegame4/pics/greenStar.png similarity index 100% rename from examples/quick/tutorials/samegame/shared/pics/greenStar.png rename to examples/quick/tutorials/samegame/samegame4/pics/greenStar.png diff --git a/examples/quick/tutorials/samegame/samegame4/pics/greenStone.png b/examples/quick/tutorials/samegame/samegame4/pics/greenStone.png new file mode 100644 index 00000000000..b568a1900c3 Binary files /dev/null and b/examples/quick/tutorials/samegame/samegame4/pics/greenStone.png differ diff --git a/examples/quick/tutorials/samegame/shared/pics/redStar.png b/examples/quick/tutorials/samegame/samegame4/pics/redStar.png similarity index 100% rename from examples/quick/tutorials/samegame/shared/pics/redStar.png rename to examples/quick/tutorials/samegame/samegame4/pics/redStar.png diff --git a/examples/quick/tutorials/samegame/samegame4/pics/redStone.png b/examples/quick/tutorials/samegame/samegame4/pics/redStone.png new file mode 100644 index 00000000000..36b09a26869 Binary files /dev/null and b/examples/quick/tutorials/samegame/samegame4/pics/redStone.png differ diff --git a/examples/quick/tutorials/samegame/samegame4/content/samegame.js b/examples/quick/tutorials/samegame/samegame4/samegame.js similarity index 100% rename from examples/quick/tutorials/samegame/samegame4/content/samegame.js rename to examples/quick/tutorials/samegame/samegame4/samegame.js diff --git a/examples/quick/tutorials/samegame/samegame4/samegame.qml b/examples/quick/tutorials/samegame/samegame4/samegame.qml index 0cdbcd8cb01..1335024b137 100644 --- a/examples/quick/tutorials/samegame/samegame4/samegame.qml +++ b/examples/quick/tutorials/samegame/samegame4/samegame.qml @@ -49,8 +49,7 @@ ****************************************************************************/ import QtQuick 2.0 -import "content" -import "content/samegame.js" as SameGame +import "samegame.js" as SameGame Rectangle { id: screen @@ -66,7 +65,7 @@ Rectangle { Image { id: background anchors.fill: parent - source: "../shared/pics/background.jpg" + source: "pics/background.jpg" fillMode: Image.PreserveAspectCrop } diff --git a/examples/quick/tutorials/samegame/samegame4/samegame4.pro b/examples/quick/tutorials/samegame/samegame4/samegame4.pro index 5da0d46e198..e9d341d5554 100644 --- a/examples/quick/tutorials/samegame/samegame4/samegame4.pro +++ b/examples/quick/tutorials/samegame/samegame4/samegame4.pro @@ -2,10 +2,7 @@ TEMPLATE = app QT += quick qml SOURCES += main.cpp - -RESOURCES += \ - samegame4.qrc \ - ../shared/pics/shared.qrc +RESOURCES += samegame4.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/tutorials/samegame/samegame4 INSTALLS += target diff --git a/examples/quick/tutorials/samegame/samegame4/samegame4.qrc b/examples/quick/tutorials/samegame/samegame4/samegame4.qrc index 8b130721f51..9dc482d7ded 100644 --- a/examples/quick/tutorials/samegame/samegame4/samegame4.qrc +++ b/examples/quick/tutorials/samegame/samegame4/samegame4.qrc @@ -1,13 +1,20 @@ - + samegame.qml - content/BoomBlock.qml - content/Button.qml - content/Dialog.qml - content/samegame.js + BoomBlock.qml + Button.qml + Dialog.qml + samegame.js highscores/README highscores/score_data.xml highscores/score_style.xsl highscores/scores.php + pics/background.jpg + pics/blueStar.png + pics/blueStone.png + pics/greenStar.png + pics/greenStone.png + pics/redStar.png + pics/redStone.png diff --git a/examples/quick/tutorials/samegame/shared/pics/shared.qrc b/examples/quick/tutorials/samegame/shared/pics/shared.qrc deleted file mode 100644 index 8982a9face8..00000000000 --- a/examples/quick/tutorials/samegame/shared/pics/shared.qrc +++ /dev/null @@ -1,13 +0,0 @@ - - - background.jpg - blueStar.png - blueStone.png - greenStar.png - greenStone.png - redStar.png - redStone.png - star.png - yellowStone.png - - diff --git a/examples/quick/tutorials/samegame/shared/pics/star.png b/examples/quick/tutorials/samegame/shared/pics/star.png deleted file mode 100644 index defbde53ca4..00000000000 Binary files a/examples/quick/tutorials/samegame/shared/pics/star.png and /dev/null differ diff --git a/examples/quick/tutorials/samegame/shared/pics/yellowStone.png b/examples/quick/tutorials/samegame/shared/pics/yellowStone.png deleted file mode 100644 index b1ce76212c6..00000000000 Binary files a/examples/quick/tutorials/samegame/shared/pics/yellowStone.png and /dev/null differ diff --git a/examples/quick/views/CMakeLists.txt b/examples/quick/views/CMakeLists.txt index 53ced26e550..59df78d940b 100644 --- a/examples/quick/views/CMakeLists.txt +++ b/examples/quick/views/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from views.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(views LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -20,106 +20,79 @@ find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Quick) find_package(Qt6 COMPONENTS Qml) -qt_add_executable(views +add_subdirectory("../shared" "shared") + +qt_add_executable(viewsexample main.cpp ) -set_target_properties(views PROPERTIES +set_target_properties(viewsexample PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) -target_link_libraries(views PUBLIC +target_link_libraries(viewsexample PRIVATE Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(viewsexample views_shared) - -# Resources: -set(views_resource_files - "delegatemodel/dragselection.qml" - "delegatemodel/slideshow.qml" - "gridview/gridview-example.qml" - "gridview/pics/AddressBook_48.png" - "gridview/pics/AudioPlayer_48.png" - "gridview/pics/Camera_48.png" - "gridview/pics/DateBook_48.png" - "gridview/pics/EMail_48.png" - "gridview/pics/TodoList_48.png" - "gridview/pics/VideoPlayer_48.png" - "listview/content/PetsModel.qml" - "listview/content/PressAndHoldButton.qml" - "listview/content/RecipesModel.qml" - "listview/content/SmallText.qml" - "listview/content/TextButton.qml" - "listview/content/ToggleButton.qml" - "listview/content/pics/arrow-down.png" - "listview/content/pics/arrow-up.png" - "listview/content/pics/fruit-salad.jpg" - "listview/content/pics/hamburger.jpg" - "listview/content/pics/lemonade.jpg" - "listview/content/pics/list-delete.png" - "listview/content/pics/minus-sign.png" - "listview/content/pics/moreDown.png" - "listview/content/pics/moreUp.png" - "listview/content/pics/pancakes.jpg" - "listview/content/pics/plus-sign.png" - "listview/content/pics/vegetable-soup.jpg" - "listview/displaymargin.qml" - "listview/dynamiclist.qml" - "listview/expandingdelegates.qml" - "listview/highlight.qml" - "listview/highlightranges.qml" - "listview/sections.qml" - "objectmodel/objectmodel.qml" - "package/Delegate.qml" - "package/view.qml" - "pathview/pathview-example.qml" - "pathview/pics/AddressBook_48.png" - "pathview/pics/AudioPlayer_48.png" - "pathview/pics/Camera_48.png" - "pathview/pics/DateBook_48.png" - "pathview/pics/EMail_48.png" - "pathview/pics/TodoList_48.png" - "pathview/pics/VideoPlayer_48.png" - "views.qml" -) - -qt6_add_resources(views "views" - PREFIX - "/views" - FILES - ${views_resource_files} -) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(views "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} +qt_add_qml_module(viewsexample + URI views + VERSION 1.0 + QML_FILES + "delegatemodel/dragselection.qml" + "delegatemodel/slideshow.qml" + "gridview/gridview-example.qml" + "listview/content/PetsModel.qml" + "listview/content/PressAndHoldButton.qml" + "listview/content/RecipesModel.qml" + "listview/content/SmallText.qml" + "listview/content/TextButton.qml" + "listview/content/ToggleButton.qml" + "listview/displaymargin.qml" + "listview/dynamiclist.qml" + "listview/expandingdelegates.qml" + "listview/highlight.qml" + "listview/highlightranges.qml" + "listview/sections.qml" + "objectmodel/objectmodel.qml" + "package/Delegate.qml" + "package/view.qml" + "pathview/pathview-example.qml" + "views.qml" + RESOURCES + "gridview/pics/AddressBook_48.png" + "gridview/pics/AudioPlayer_48.png" + "gridview/pics/Camera_48.png" + "gridview/pics/DateBook_48.png" + "gridview/pics/EMail_48.png" + "gridview/pics/TodoList_48.png" + "gridview/pics/VideoPlayer_48.png" + "listview/content/pics/arrow-down.png" + "listview/content/pics/arrow-up.png" + "listview/content/pics/fruit-salad.jpg" + "listview/content/pics/hamburger.jpg" + "listview/content/pics/lemonade.jpg" + "listview/content/pics/list-delete.png" + "listview/content/pics/minus-sign.png" + "listview/content/pics/moreDown.png" + "listview/content/pics/moreUp.png" + "listview/content/pics/pancakes.jpg" + "listview/content/pics/plus-sign.png" + "listview/content/pics/vegetable-soup.jpg" + "pathview/pics/AddressBook_48.png" + "pathview/pics/AudioPlayer_48.png" + "pathview/pics/Camera_48.png" + "pathview/pics/DateBook_48.png" + "pathview/pics/EMail_48.png" + "pathview/pics/TodoList_48.png" + "pathview/pics/VideoPlayer_48.png" ) -install(TARGETS views +install(TARGETS viewsexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) +bundle_shared(viewsexample) diff --git a/examples/quick/views/delegatemodel/delegatemodel.qmlproject b/examples/quick/views/delegatemodel/delegatemodel.qmlproject index 2bb40169967..e78ddcb187e 100644 --- a/examples/quick/views/delegatemodel/delegatemodel.qmlproject +++ b/examples/quick/views/delegatemodel/delegatemodel.qmlproject @@ -1,6 +1,9 @@ import QmlProject 1.0 Project { + mainFile: "slideshow.qml" + importPaths: [ "../../" ] + /* Include .qml, .js, and image files from current directory and subdirectories */ QmlFiles { directory: "." diff --git a/examples/quick/views/delegatemodel/slideshow.qml b/examples/quick/views/delegatemodel/slideshow.qml index 638c8bf10f0..f11feb61bc7 100644 --- a/examples/quick/views/delegatemodel/slideshow.qml +++ b/examples/quick/views/delegatemodel/slideshow.qml @@ -50,7 +50,7 @@ import QtQuick 2.12 import QtQml.Models 2.12 -import "../../shared" as Shared +import shared as Shared Rectangle { id: root diff --git a/examples/quick/views/views.qml b/examples/quick/views/views.qml index 0dfde6672f1..d42f60e792f 100644 --- a/examples/quick/views/views.qml +++ b/examples/quick/views/views.qml @@ -48,8 +48,8 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import "../shared" as Examples +import QtQuick +import shared as Examples Item { height: 480 diff --git a/examples/quick/views/views.qmlproject b/examples/quick/views/views.qmlproject index 7e6baf0a7f2..f0e49ad0082 100644 --- a/examples/quick/views/views.qmlproject +++ b/examples/quick/views/views.qmlproject @@ -2,6 +2,7 @@ import QmlProject 1.1 Project { mainFile: "views.qml" + importPaths: [ "../" ] /* Include .qml, .js, and image files from current directory and subdirectories */ QmlFiles { diff --git a/examples/quick/window/CMakeLists.txt b/examples/quick/window/CMakeLists.txt index ca9f75b0820..f8a9f456007 100644 --- a/examples/quick/window/CMakeLists.txt +++ b/examples/quick/window/CMakeLists.txt @@ -1,6 +1,6 @@ # Generated from window.pro. -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(window LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -20,64 +20,37 @@ find_package(Qt6 COMPONENTS Gui) find_package(Qt6 COMPONENTS Quick) find_package(Qt6 COMPONENTS Qml) -qt_add_executable(window +add_subdirectory("../shared" "shared") + +qt_add_executable(windowexample main.cpp ) -set_target_properties(window PROPERTIES +set_target_properties(windowexample PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) -target_link_libraries(window PUBLIC + +qt_add_qml_module(windowexample + URI window + VERSION 1.0 + QML_FILES + "AllScreens.qml" + "CurrentScreen.qml" + "Splash.qml" + "window.qml" +) + +target_link_libraries(windowexample PRIVATE Qt::Core Qt::Gui Qt::Qml Qt::Quick ) +add_dependencies(windowexample window_shared) - -# Resources: -set(window_resource_files - "AllScreens.qml" - "CurrentScreen.qml" - "Splash.qml" - "window.qml" -) - -qt6_add_resources(window "window" - PREFIX - "/window" - FILES - ${window_resource_files} -) -set(shared_resource_files - "../shared/Button.qml" - "../shared/CheckBox.qml" - "../shared/FlickrRssModel.qml" - "../shared/Label.qml" - "../shared/LauncherList.qml" - "../shared/SimpleLauncherDelegate.qml" - "../shared/Slider.qml" - "../shared/TabSet.qml" - "../shared/TextField.qml" - "../shared/images/back.png" - "../shared/images/checkmark.png" - "../shared/images/next.png" - "../shared/images/qt-logo.png" - "../shared/images/slider_handle.png" - "../shared/images/tab.png" -) - -qt6_add_resources(window "shared" - PREFIX - "/shared" - BASE - "../shared" - FILES - ${shared_resource_files} -) - -install(TARGETS window +install(TARGETS windowexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" ) +bundle_shared(windowexample) diff --git a/examples/quick/window/Splash.qml b/examples/quick/window/Splash.qml index cc520bd5a4c..b19e6f81e3c 100644 --- a/examples/quick/window/Splash.qml +++ b/examples/quick/window/Splash.qml @@ -49,6 +49,7 @@ ****************************************************************************/ import QtQuick +import shared //! [splash-properties] Window { @@ -69,7 +70,7 @@ Window { Image { id: splashImage - source: "../shared/images/qt-logo.png" + source: Images.qtLogo MouseArea { anchors.fill: parent onClicked: Qt.quit() diff --git a/examples/quick/window/doc/src/window.qdoc b/examples/quick/window/doc/src/window.qdoc index 26caafce9aa..355bc30f01f 100644 --- a/examples/quick/window/doc/src/window.qdoc +++ b/examples/quick/window/doc/src/window.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -74,7 +74,8 @@ applications which need to rotate some content when the screen orientation changes, to position windows on the screen or to convert real units to logical pixel units. CurrentScreen.qml (which is displayed inline in - window.qml, or can be run by itself with qmlscene) simply displays the + window.qml, or can be run by itself with the + \l {Prototyping with the QML Runtime Tool}{qml tool}) simply displays the property values, while the splash screen uses them to center the window on the screen. diff --git a/examples/quick/window/main.cpp b/examples/quick/window/main.cpp index 25eb3663abc..7d2b0903fd6 100644 --- a/examples/quick/window/main.cpp +++ b/examples/quick/window/main.cpp @@ -60,6 +60,14 @@ int main(int argc, char* argv[]) { QGuiApplication app(argc, argv); QQmlEngine engine; + + // Add the qrc root as QML import path so that the "shared" module can be found. + engine.addImportPath(QStringLiteral(":/")); + +#ifdef Q_OS_MACOS + engine.addImportPath(app.applicationDirPath() + QStringLiteral("/../PlugIns")); +#endif + QQmlComponent component(&engine); QQuickWindow::setDefaultAlphaBuffer(true); component.loadUrl(QUrl("qrc:///window/window.qml")); diff --git a/examples/quickcontrols2/CMakeLists.txt b/examples/quickcontrols2/CMakeLists.txt new file mode 100644 index 00000000000..4c3c54b0328 --- /dev/null +++ b/examples/quickcontrols2/CMakeLists.txt @@ -0,0 +1,14 @@ +# Generated from quickcontrols2.pro. + +qt_internal_add_example(gallery) +add_subdirectory(chattutorial) +qt_internal_add_example(texteditor) +qt_internal_add_example(contactlist) +qt_internal_add_example(sidepanel) +qt_internal_add_example(swipetoremove) +qt_internal_add_example(wearable) +qt_internal_add_example(imagine/automotive) +qt_internal_add_example(imagine/musicplayer) +if(TARGET Qt::Widgets) + qt_internal_add_example(flatstyle) +endif() diff --git a/examples/quickcontrols2/chattutorial/CMakeLists.txt b/examples/quickcontrols2/chattutorial/CMakeLists.txt new file mode 100644 index 00000000000..88f9cb5cf28 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/CMakeLists.txt @@ -0,0 +1,10 @@ +# Generated from chattutorial.pro. + +qt_internal_add_example(chapter1) +qt_internal_add_example(chapter2) +qt_internal_add_example(chapter3) +if (TARGET Qt::Sql) + qt_internal_add_example(chapter4) + qt_internal_add_example(chapter5) +endif() + diff --git a/examples/quickcontrols2/chattutorial/chapter1/CMakeLists.txt b/examples/quickcontrols2/chattutorial/chapter1/CMakeLists.txt new file mode 100644 index 00000000000..4b8770a83d8 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter1/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 3.16) +project(chapter1 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/chattutorial/chapter1") + +find_package(Qt6 COMPONENTS Core Gui Qml Quick) + +qt_add_executable(chattutorial-chapter1 WIN32 MACOSX_BUNDLE + main.cpp +) +target_link_libraries(chattutorial-chapter1 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +qt_add_qml_module(chattutorial-chapter1 + URI chapter1 + VERSION 1.0 + QML_FILES + "main.qml" +) + +qt6_add_resources(chattutorial-chapter1 "conf" + PREFIX + "/" + FILES + "qtquickcontrols2.conf" +) + +install(TARGETS chattutorial-chapter1 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/chattutorial/chapter1/chapter1.pro b/examples/quickcontrols2/chattutorial/chapter1/chapter1.pro new file mode 100644 index 00000000000..6b50809f20a --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter1/chapter1.pro @@ -0,0 +1,14 @@ +TEMPLATE = app + +QT += qml quick +CONFIG += c++11 + +SOURCES += main.cpp + +resources.files = main.qml +resources.prefix = chapter1/ +RESOURCES += resources \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/chattutorial/chapter1 +INSTALLS += target diff --git a/examples/quickcontrols2/chattutorial/chapter1/main.cpp b/examples/quickcontrols2/chattutorial/chapter1/main.cpp new file mode 100644 index 00000000000..ca175ccf9cf --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter1/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/chapter1/main.qml"))); + + return app.exec(); +} + diff --git a/examples/quickcontrols2/chattutorial/chapter1/main.qml b/examples/quickcontrols2/chattutorial/chapter1/main.qml new file mode 100644 index 00000000000..3dc93e47d00 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter1/main.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 540 + height: 960 + visible: true + + Page { + anchors.fill: parent + header: Label { + padding: 10 + text: qsTr("Contacts") + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } +} + diff --git a/examples/quickcontrols2/chattutorial/chapter1/qtquickcontrols2.conf b/examples/quickcontrols2/chattutorial/chapter1/qtquickcontrols2.conf new file mode 100644 index 00000000000..db9486764e7 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter1/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Basic diff --git a/examples/quickcontrols2/chattutorial/chapter2/CMakeLists.txt b/examples/quickcontrols2/chattutorial/chapter2/CMakeLists.txt new file mode 100644 index 00000000000..5c73c212cea --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter2/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.16) +project(chapter2 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/chattutorial/chapter2") + +find_package(Qt6 COMPONENTS Core Gui Qml Quick) + +qt_add_executable(chattutorial-chapter2 WIN32 MACOSX_BUNDLE + main.cpp +) +target_link_libraries(chattutorial-chapter2 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +qt_add_qml_module(chattutorial-chapter2 + URI chapter2 + VERSION 1.0 + QML_FILES + "main.qml" + RESOURCES + "images/Albert_Einstein.png" + "images/Albert_Einstein@2x.png" + "images/Albert_Einstein@3x.png" + "images/Albert_Einstein@4x.png" + "images/Ernest_Hemingway.png" + "images/Ernest_Hemingway@2x.png" + "images/Ernest_Hemingway@3x.png" + "images/Ernest_Hemingway@4x.png" + "images/Hans_Gude.png" + "images/Hans_Gude@2x.png" + "images/Hans_Gude@3x.png" + "images/Hans_Gude@4x.png" +) + +qt6_add_resources(chattutorial-chapter2 "conf" + PREFIX + "/" + FILES + "qtquickcontrols2.conf" +) + +install(TARGETS chattutorial-chapter2 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/chattutorial/chapter2/chapter2.pro b/examples/quickcontrols2/chattutorial/chapter2/chapter2.pro new file mode 100644 index 00000000000..15429b7c89b --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter2/chapter2.pro @@ -0,0 +1,27 @@ +TEMPLATE = app + +QT += qml quick +CONFIG += c++11 + +SOURCES += main.cpp + +resources.files = \ + images/Albert_Einstein.png \ + images/Albert_Einstein@2x.png \ + images/Albert_Einstein@3x.png \ + images/Albert_Einstein@4x.png \ + images/Ernest_Hemingway.png \ + images/Ernest_Hemingway@2x.png \ + images/Ernest_Hemingway@3x.png \ + images/Ernest_Hemingway@4x.png \ + images/Hans_Gude.png \ + images/Hans_Gude@2x.png \ + images/Hans_Gude@3x.png \ + images/Hans_Gude@4x.png \ + main.qml +resources.prefix = chapter2/ +RESOURCES += resources \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/chattutorial/chapter2 +INSTALLS += target diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/Albert_Einstein.png b/examples/quickcontrols2/chattutorial/chapter2/images/Albert_Einstein.png new file mode 100644 index 00000000000..7c44b90b8d0 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter2/images/Albert_Einstein.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/Albert_Einstein@2x.png b/examples/quickcontrols2/chattutorial/chapter2/images/Albert_Einstein@2x.png new file mode 100644 index 00000000000..6ce9c39b6c3 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter2/images/Albert_Einstein@2x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/Albert_Einstein@3x.png b/examples/quickcontrols2/chattutorial/chapter2/images/Albert_Einstein@3x.png new file mode 100644 index 00000000000..aab6a6a1628 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter2/images/Albert_Einstein@3x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/Albert_Einstein@4x.png b/examples/quickcontrols2/chattutorial/chapter2/images/Albert_Einstein@4x.png new file mode 100644 index 00000000000..3611284df46 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter2/images/Albert_Einstein@4x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/Ernest_Hemingway.png b/examples/quickcontrols2/chattutorial/chapter2/images/Ernest_Hemingway.png new file mode 100644 index 00000000000..3ac8992fd9b Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter2/images/Ernest_Hemingway.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/Ernest_Hemingway@2x.png b/examples/quickcontrols2/chattutorial/chapter2/images/Ernest_Hemingway@2x.png new file mode 100644 index 00000000000..122d9f1e53d Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter2/images/Ernest_Hemingway@2x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/Ernest_Hemingway@3x.png b/examples/quickcontrols2/chattutorial/chapter2/images/Ernest_Hemingway@3x.png new file mode 100644 index 00000000000..2fe9c2cc1c9 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter2/images/Ernest_Hemingway@3x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/Ernest_Hemingway@4x.png b/examples/quickcontrols2/chattutorial/chapter2/images/Ernest_Hemingway@4x.png new file mode 100644 index 00000000000..96fb6788b5a Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter2/images/Ernest_Hemingway@4x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/Hans_Gude.png b/examples/quickcontrols2/chattutorial/chapter2/images/Hans_Gude.png new file mode 100644 index 00000000000..907e38bc619 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter2/images/Hans_Gude.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/Hans_Gude@2x.png b/examples/quickcontrols2/chattutorial/chapter2/images/Hans_Gude@2x.png new file mode 100644 index 00000000000..6837796a835 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter2/images/Hans_Gude@2x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/Hans_Gude@3x.png b/examples/quickcontrols2/chattutorial/chapter2/images/Hans_Gude@3x.png new file mode 100644 index 00000000000..29af422ad31 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter2/images/Hans_Gude@3x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/Hans_Gude@4x.png b/examples/quickcontrols2/chattutorial/chapter2/images/Hans_Gude@4x.png new file mode 100644 index 00000000000..bc35eeaa799 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter2/images/Hans_Gude@4x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter2/images/images.qrc b/examples/quickcontrols2/chattutorial/chapter2/images/images.qrc new file mode 100644 index 00000000000..9eda6aa29c4 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter2/images/images.qrc @@ -0,0 +1,16 @@ + + + Albert_Einstein.png + Albert_Einstein@2x.png + Albert_Einstein@3x.png + Albert_Einstein@4x.png + Ernest_Hemingway.png + Ernest_Hemingway@2x.png + Ernest_Hemingway@3x.png + Ernest_Hemingway@4x.png + Hans_Gude.png + Hans_Gude@2x.png + Hans_Gude@3x.png + Hans_Gude@4x.png + + diff --git a/examples/quickcontrols2/chattutorial/chapter2/main.cpp b/examples/quickcontrols2/chattutorial/chapter2/main.cpp new file mode 100644 index 00000000000..55997aa8adc --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter2/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/chapter2/main.qml"))); + + return app.exec(); +} + diff --git a/examples/quickcontrols2/chattutorial/chapter2/main.qml b/examples/quickcontrols2/chattutorial/chapter2/main.qml new file mode 100644 index 00000000000..8a87d410206 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter2/main.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 540 + height: 960 + visible: true + + Page { + anchors.fill: parent + header: Label { + padding: 10 + text: qsTr("Contacts") + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + ListView { + id: listView + anchors.fill: parent + topMargin: 48 + leftMargin: 48 + bottomMargin: 48 + rightMargin: 48 + spacing: 20 + model: ["Albert Einstein", "Ernest Hemingway", "Hans Gude"] + delegate: ItemDelegate { + text: modelData + width: listView.width - listView.leftMargin - listView.rightMargin + height: avatar.implicitHeight + leftPadding: avatar.implicitWidth + 32 + + Image { + id: avatar + source: "images/" + modelData.replace(" ", "_") + ".png" + } + } + } + } +} + diff --git a/examples/quickcontrols2/chattutorial/chapter2/qtquickcontrols2.conf b/examples/quickcontrols2/chattutorial/chapter2/qtquickcontrols2.conf new file mode 100644 index 00000000000..db9486764e7 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter2/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Basic diff --git a/examples/quickcontrols2/chattutorial/chapter3/CMakeLists.txt b/examples/quickcontrols2/chattutorial/chapter3/CMakeLists.txt new file mode 100644 index 00000000000..e835d38ac9a --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter3/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required(VERSION 3.16) +project(chapter3 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/chattutorial/chapter3") + +find_package(Qt6 COMPONENTS Core Gui Qml Quick) + +qt_add_executable(chattutorial-chapter3 WIN32 MACOSX_BUNDLE + main.cpp +) +target_link_libraries(chattutorial-chapter3 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +# Resources: +qt_add_qml_module(chattutorial-chapter3 + URI chapter3 + VERSION 1.0 + QML_FILES + "ContactPage.qml" + "ConversationPage.qml" + "main.qml" + RESOURCES + "images/Albert_Einstein.png" + "images/Albert_Einstein@2x.png" + "images/Albert_Einstein@3x.png" + "images/Albert_Einstein@4x.png" + "images/Ernest_Hemingway.png" + "images/Ernest_Hemingway@2x.png" + "images/Ernest_Hemingway@3x.png" + "images/Ernest_Hemingway@4x.png" + "images/Hans_Gude.png" + "images/Hans_Gude@2x.png" + "images/Hans_Gude@3x.png" + "images/Hans_Gude@4x.png" +) + +qt6_add_resources(chattutorial-chapter3 "conf" + PREFIX + "/" + FILES + "qtquickcontrols2.conf" +) + +install(TARGETS chattutorial-chapter3 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/chattutorial/chapter3/ContactPage.qml b/examples/quickcontrols2/chattutorial/chapter3/ContactPage.qml new file mode 100644 index 00000000000..b0be22718e3 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter3/ContactPage.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Page { + id: root + + header: ToolBar { + Label { + text: qsTr("Contacts") + font.pixelSize: 20 + anchors.centerIn: parent + } + } + + ListView { + id: listView + anchors.fill: parent + topMargin: 48 + leftMargin: 48 + bottomMargin: 48 + rightMargin: 48 + spacing: 20 + model: ["Albert Einstein", "Ernest Hemingway", "Hans Gude"] + delegate: ItemDelegate { + text: modelData + width: listView.width - listView.leftMargin - listView.rightMargin + height: avatar.implicitHeight + leftPadding: avatar.implicitWidth + 32 + onClicked: root.StackView.view.push("ConversationPage.qml", { inConversationWith: modelData }) + + Image { + id: avatar + source: "images/" + modelData.replace(" ", "_") + ".png" + } + } + } +} + diff --git a/examples/quickcontrols2/chattutorial/chapter3/ConversationPage.qml b/examples/quickcontrols2/chattutorial/chapter3/ConversationPage.qml new file mode 100644 index 00000000000..2ae56444c7e --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter3/ConversationPage.qml @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +Page { + id: root + + property string inConversationWith + + header: ToolBar { + ToolButton { + text: qsTr("Back") + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.verticalCenter: parent.verticalCenter + onClicked: root.StackView.view.pop() + } + + Label { + id: pageTitle + text: inConversationWith + font.pixelSize: 20 + anchors.centerIn: parent + } + } + + ColumnLayout { + anchors.fill: parent + + ListView { + id: listView + Layout.fillWidth: true + Layout.fillHeight: true + Layout.margins: pane.leftPadding + messageField.leftPadding + displayMarginBeginning: 40 + displayMarginEnd: 40 + verticalLayoutDirection: ListView.BottomToTop + spacing: 12 + model: 10 + delegate: Row { + readonly property bool sentByMe: index % 2 == 0 + + anchors.right: sentByMe ? listView.contentItem.right : undefined + spacing: 6 + + Rectangle { + id: avatar + width: height + height: parent.height + color: "grey" + visible: !sentByMe + } + + Rectangle { + width: 80 + height: 40 + color: sentByMe ? "lightgrey" : "steelblue" + + Label { + anchors.centerIn: parent + text: index + color: sentByMe ? "black" : "white" + } + } + } + + ScrollBar.vertical: ScrollBar {} + } + + Pane { + id: pane + Layout.fillWidth: true + + RowLayout { + width: parent.width + + TextArea { + id: messageField + Layout.fillWidth: true + placeholderText: qsTr("Compose message") + wrapMode: TextArea.Wrap + } + + Button { + id: sendButton + text: qsTr("Send") + enabled: messageField.length > 0 + } + } + } + } +} + diff --git a/examples/quickcontrols2/chattutorial/chapter3/chapter3.pro b/examples/quickcontrols2/chattutorial/chapter3/chapter3.pro new file mode 100644 index 00000000000..42adc69fe9c --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter3/chapter3.pro @@ -0,0 +1,29 @@ +TEMPLATE = app + +QT += qml quick +CONFIG += c++11 + +SOURCES += main.cpp + +resources.files = \ + ContactPage.qml \ + ConversationPage.qml \ + images/Albert_Einstein.png \ + images/Albert_Einstein@2x.png \ + images/Albert_Einstein@3x.png \ + images/Albert_Einstein@4x.png \ + images/Ernest_Hemingway.png \ + images/Ernest_Hemingway@2x.png \ + images/Ernest_Hemingway@3x.png \ + images/Ernest_Hemingway@4x.png \ + images/Hans_Gude.png \ + images/Hans_Gude@2x.png \ + images/Hans_Gude@3x.png \ + images/Hans_Gude@4x.png \ + main.qml +resources.prefix = chapter3/ +RESOURCES += resources \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/chattutorial/chapter3 +INSTALLS += target diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/Albert_Einstein.png b/examples/quickcontrols2/chattutorial/chapter3/images/Albert_Einstein.png new file mode 100644 index 00000000000..7c44b90b8d0 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter3/images/Albert_Einstein.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/Albert_Einstein@2x.png b/examples/quickcontrols2/chattutorial/chapter3/images/Albert_Einstein@2x.png new file mode 100644 index 00000000000..6ce9c39b6c3 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter3/images/Albert_Einstein@2x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/Albert_Einstein@3x.png b/examples/quickcontrols2/chattutorial/chapter3/images/Albert_Einstein@3x.png new file mode 100644 index 00000000000..aab6a6a1628 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter3/images/Albert_Einstein@3x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/Albert_Einstein@4x.png b/examples/quickcontrols2/chattutorial/chapter3/images/Albert_Einstein@4x.png new file mode 100644 index 00000000000..3611284df46 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter3/images/Albert_Einstein@4x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/Ernest_Hemingway.png b/examples/quickcontrols2/chattutorial/chapter3/images/Ernest_Hemingway.png new file mode 100644 index 00000000000..3ac8992fd9b Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter3/images/Ernest_Hemingway.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/Ernest_Hemingway@2x.png b/examples/quickcontrols2/chattutorial/chapter3/images/Ernest_Hemingway@2x.png new file mode 100644 index 00000000000..122d9f1e53d Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter3/images/Ernest_Hemingway@2x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/Ernest_Hemingway@3x.png b/examples/quickcontrols2/chattutorial/chapter3/images/Ernest_Hemingway@3x.png new file mode 100644 index 00000000000..2fe9c2cc1c9 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter3/images/Ernest_Hemingway@3x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/Ernest_Hemingway@4x.png b/examples/quickcontrols2/chattutorial/chapter3/images/Ernest_Hemingway@4x.png new file mode 100644 index 00000000000..96fb6788b5a Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter3/images/Ernest_Hemingway@4x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/Hans_Gude.png b/examples/quickcontrols2/chattutorial/chapter3/images/Hans_Gude.png new file mode 100644 index 00000000000..907e38bc619 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter3/images/Hans_Gude.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/Hans_Gude@2x.png b/examples/quickcontrols2/chattutorial/chapter3/images/Hans_Gude@2x.png new file mode 100644 index 00000000000..6837796a835 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter3/images/Hans_Gude@2x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/Hans_Gude@3x.png b/examples/quickcontrols2/chattutorial/chapter3/images/Hans_Gude@3x.png new file mode 100644 index 00000000000..29af422ad31 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter3/images/Hans_Gude@3x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/Hans_Gude@4x.png b/examples/quickcontrols2/chattutorial/chapter3/images/Hans_Gude@4x.png new file mode 100644 index 00000000000..bc35eeaa799 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter3/images/Hans_Gude@4x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter3/images/images.qrc b/examples/quickcontrols2/chattutorial/chapter3/images/images.qrc new file mode 100644 index 00000000000..9eda6aa29c4 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter3/images/images.qrc @@ -0,0 +1,16 @@ + + + Albert_Einstein.png + Albert_Einstein@2x.png + Albert_Einstein@3x.png + Albert_Einstein@4x.png + Ernest_Hemingway.png + Ernest_Hemingway@2x.png + Ernest_Hemingway@3x.png + Ernest_Hemingway@4x.png + Hans_Gude.png + Hans_Gude@2x.png + Hans_Gude@3x.png + Hans_Gude@4x.png + + diff --git a/examples/quickcontrols2/chattutorial/chapter3/main.cpp b/examples/quickcontrols2/chattutorial/chapter3/main.cpp new file mode 100644 index 00000000000..657318a775a --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter3/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/chapter3/main.qml"))); + + return app.exec(); +} + diff --git a/examples/quickcontrols2/chattutorial/chapter3/main.qml b/examples/quickcontrols2/chattutorial/chapter3/main.qml new file mode 100644 index 00000000000..029f45e3c84 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter3/main.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 540 + height: 960 + visible: true + + StackView { + id: stackView + anchors.fill: parent + initialItem: ContactPage {} + } +} + diff --git a/examples/quickcontrols2/chattutorial/chapter3/qtquickcontrols2.conf b/examples/quickcontrols2/chattutorial/chapter3/qtquickcontrols2.conf new file mode 100644 index 00000000000..db9486764e7 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter3/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Basic diff --git a/examples/quickcontrols2/chattutorial/chapter4/CMakeLists.txt b/examples/quickcontrols2/chattutorial/chapter4/CMakeLists.txt new file mode 100644 index 00000000000..aba8c1000b7 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter4/CMakeLists.txt @@ -0,0 +1,63 @@ +cmake_minimum_required(VERSION 3.16) +project(chapter4 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/chattutorial/chapter4") + +find_package(Qt6 COMPONENTS Core Gui Qml Quick Sql) + +qt_add_executable(chattutorial-chapter4 WIN32 MACOSX_BUNDLE + main.cpp + sqlcontactmodel.cpp sqlcontactmodel.h + sqlconversationmodel.cpp sqlconversationmodel.h +) +target_link_libraries(chattutorial-chapter4 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick + Qt::Sql +) + +# Resources: +qt_add_qml_module(chattutorial-chapter4 + URI chapter4 + VERSION 1.0 + QML_FILES + "ContactPage.qml" + "ConversationPage.qml" + "main.qml" + RESOURCES + "images/Albert_Einstein.png" + "images/Albert_Einstein@2x.png" + "images/Albert_Einstein@3x.png" + "images/Albert_Einstein@4x.png" + "images/Ernest_Hemingway.png" + "images/Ernest_Hemingway@2x.png" + "images/Ernest_Hemingway@3x.png" + "images/Ernest_Hemingway@4x.png" + "images/Hans_Gude.png" + "images/Hans_Gude@2x.png" + "images/Hans_Gude@3x.png" + "images/Hans_Gude@4x.png" +) + +qt6_add_resources(chattutorial-chapter4 "conf" + PREFIX + "/" + FILES + "qtquickcontrols2.conf" +) + +install(TARGETS chattutorial-chapter4 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/chattutorial/chapter4/ContactPage.qml b/examples/quickcontrols2/chattutorial/chapter4/ContactPage.qml new file mode 100644 index 00000000000..e0fc2e12c92 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter4/ContactPage.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +import io.qt.examples.chattutorial + +Page { + id: root + + header: ToolBar { + Label { + text: qsTr("Contacts") + font.pixelSize: 20 + anchors.centerIn: parent + } + } + + ListView { + id: listView + anchors.fill: parent + topMargin: 48 + leftMargin: 48 + bottomMargin: 48 + rightMargin: 48 + spacing: 20 + model: SqlContactModel {} + delegate: ItemDelegate { + text: model.display + width: listView.width - listView.leftMargin - listView.rightMargin + height: avatar.implicitHeight + leftPadding: avatar.implicitWidth + 32 + onClicked: root.StackView.view.push("ConversationPage.qml", { inConversationWith: model.display }) + + Image { + id: avatar + source: "images/" + model.display.replace(" ", "_") + ".png" + } + } + } +} + diff --git a/examples/quickcontrols2/chattutorial/chapter4/ConversationPage.qml b/examples/quickcontrols2/chattutorial/chapter4/ConversationPage.qml new file mode 100644 index 00000000000..f69ebcd467d --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter4/ConversationPage.qml @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +import io.qt.examples.chattutorial + +Page { + id: root + + property string inConversationWith + + header: ToolBar { + ToolButton { + text: qsTr("Back") + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.verticalCenter: parent.verticalCenter + onClicked: root.StackView.view.pop() + } + + Label { + id: pageTitle + text: inConversationWith + font.pixelSize: 20 + anchors.centerIn: parent + } + } + + ColumnLayout { + anchors.fill: parent + + ListView { + id: listView + Layout.fillWidth: true + Layout.fillHeight: true + Layout.margins: pane.leftPadding + messageField.leftPadding + displayMarginBeginning: 40 + displayMarginEnd: 40 + verticalLayoutDirection: ListView.BottomToTop + spacing: 12 + model: SqlConversationModel { + recipient: inConversationWith + } + delegate: Column { + anchors.right: sentByMe ? listView.contentItem.right : undefined + spacing: 6 + + readonly property bool sentByMe: model.recipient !== "Me" + + Row { + id: messageRow + spacing: 6 + anchors.right: sentByMe ? parent.right : undefined + + Image { + id: avatar + source: !sentByMe ? "images/" + model.author.replace(" ", "_") + ".png" : "" + } + + Rectangle { + width: Math.min(messageText.implicitWidth + 24, + listView.width - (!sentByMe ? avatar.width + messageRow.spacing : 0)) + height: messageText.implicitHeight + 24 + color: sentByMe ? "lightgrey" : "steelblue" + + Label { + id: messageText + text: model.message + color: sentByMe ? "black" : "white" + anchors.fill: parent + anchors.margins: 12 + wrapMode: Label.Wrap + } + } + } + + Label { + id: timestampText + text: Qt.formatDateTime(model.timestamp, "d MMM hh:mm") + color: "lightgrey" + anchors.right: sentByMe ? parent.right : undefined + } + } + + ScrollBar.vertical: ScrollBar {} + } + + Pane { + id: pane + Layout.fillWidth: true + + RowLayout { + width: parent.width + + TextArea { + id: messageField + Layout.fillWidth: true + placeholderText: qsTr("Compose message") + wrapMode: TextArea.Wrap + } + + Button { + id: sendButton + text: qsTr("Send") + enabled: messageField.length > 0 + onClicked: { + listView.model.sendMessage(inConversationWith, messageField.text); + messageField.text = ""; + } + } + } + } + } +} + diff --git a/examples/quickcontrols2/chattutorial/chapter4/chapter4.pro b/examples/quickcontrols2/chattutorial/chapter4/chapter4.pro new file mode 100644 index 00000000000..ae8141f7f17 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter4/chapter4.pro @@ -0,0 +1,34 @@ +TEMPLATE = app + +QT += qml quick sql +CONFIG += c++11 + +HEADERS += sqlcontactmodel.h \ + sqlconversationmodel.h + +SOURCES += main.cpp \ + sqlcontactmodel.cpp \ + sqlconversationmodel.cpp + +resources.files = \ + ContactPage.qml \ + ConversationPage.qml \ + images/Albert_Einstein.png \ + images/Albert_Einstein@2x.png \ + images/Albert_Einstein@3x.png \ + images/Albert_Einstein@4x.png \ + images/Ernest_Hemingway.png \ + images/Ernest_Hemingway@2x.png \ + images/Ernest_Hemingway@3x.png \ + images/Ernest_Hemingway@4x.png \ + images/Hans_Gude.png \ + images/Hans_Gude@2x.png \ + images/Hans_Gude@3x.png \ + images/Hans_Gude@4x.png \ + main.qml +resources.prefix = chapter4/ +RESOURCES += resources \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/chattutorial/chapter4 +INSTALLS += target diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/Albert_Einstein.png b/examples/quickcontrols2/chattutorial/chapter4/images/Albert_Einstein.png new file mode 100644 index 00000000000..7c44b90b8d0 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter4/images/Albert_Einstein.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/Albert_Einstein@2x.png b/examples/quickcontrols2/chattutorial/chapter4/images/Albert_Einstein@2x.png new file mode 100644 index 00000000000..6ce9c39b6c3 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter4/images/Albert_Einstein@2x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/Albert_Einstein@3x.png b/examples/quickcontrols2/chattutorial/chapter4/images/Albert_Einstein@3x.png new file mode 100644 index 00000000000..aab6a6a1628 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter4/images/Albert_Einstein@3x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/Albert_Einstein@4x.png b/examples/quickcontrols2/chattutorial/chapter4/images/Albert_Einstein@4x.png new file mode 100644 index 00000000000..3611284df46 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter4/images/Albert_Einstein@4x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/Ernest_Hemingway.png b/examples/quickcontrols2/chattutorial/chapter4/images/Ernest_Hemingway.png new file mode 100644 index 00000000000..3ac8992fd9b Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter4/images/Ernest_Hemingway.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/Ernest_Hemingway@2x.png b/examples/quickcontrols2/chattutorial/chapter4/images/Ernest_Hemingway@2x.png new file mode 100644 index 00000000000..122d9f1e53d Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter4/images/Ernest_Hemingway@2x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/Ernest_Hemingway@3x.png b/examples/quickcontrols2/chattutorial/chapter4/images/Ernest_Hemingway@3x.png new file mode 100644 index 00000000000..2fe9c2cc1c9 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter4/images/Ernest_Hemingway@3x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/Ernest_Hemingway@4x.png b/examples/quickcontrols2/chattutorial/chapter4/images/Ernest_Hemingway@4x.png new file mode 100644 index 00000000000..96fb6788b5a Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter4/images/Ernest_Hemingway@4x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/Hans_Gude.png b/examples/quickcontrols2/chattutorial/chapter4/images/Hans_Gude.png new file mode 100644 index 00000000000..907e38bc619 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter4/images/Hans_Gude.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/Hans_Gude@2x.png b/examples/quickcontrols2/chattutorial/chapter4/images/Hans_Gude@2x.png new file mode 100644 index 00000000000..6837796a835 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter4/images/Hans_Gude@2x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/Hans_Gude@3x.png b/examples/quickcontrols2/chattutorial/chapter4/images/Hans_Gude@3x.png new file mode 100644 index 00000000000..29af422ad31 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter4/images/Hans_Gude@3x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/Hans_Gude@4x.png b/examples/quickcontrols2/chattutorial/chapter4/images/Hans_Gude@4x.png new file mode 100644 index 00000000000..bc35eeaa799 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter4/images/Hans_Gude@4x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter4/images/images.qrc b/examples/quickcontrols2/chattutorial/chapter4/images/images.qrc new file mode 100644 index 00000000000..9eda6aa29c4 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter4/images/images.qrc @@ -0,0 +1,16 @@ + + + Albert_Einstein.png + Albert_Einstein@2x.png + Albert_Einstein@3x.png + Albert_Einstein@4x.png + Ernest_Hemingway.png + Ernest_Hemingway@2x.png + Ernest_Hemingway@3x.png + Ernest_Hemingway@4x.png + Hans_Gude.png + Hans_Gude@2x.png + Hans_Gude@3x.png + Hans_Gude@4x.png + + diff --git a/examples/quickcontrols2/chattutorial/chapter4/main.cpp b/examples/quickcontrols2/chattutorial/chapter4/main.cpp new file mode 100644 index 00000000000..e4a06399e85 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter4/main.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "sqlcontactmodel.h" +#include "sqlconversationmodel.h" + +static void connectToDatabase() +{ + QSqlDatabase database = QSqlDatabase::database(); + if (!database.isValid()) { + database = QSqlDatabase::addDatabase("QSQLITE"); + if (!database.isValid()) + qFatal("Cannot add database: %s", qPrintable(database.lastError().text())); + } + + const QDir writeDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + if (!writeDir.mkpath(".")) + qFatal("Failed to create writable directory at %s", qPrintable(writeDir.absolutePath())); + + // Ensure that we have a writable location on all devices. + const QString fileName = writeDir.absolutePath() + "/chat-database.sqlite3"; + // When using the SQLite driver, open() will create the SQLite database if it doesn't exist. + database.setDatabaseName(fileName); + if (!database.open()) { + qFatal("Cannot open database: %s", qPrintable(database.lastError().text())); + QFile::remove(fileName); + } +} + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType("io.qt.examples.chattutorial", 1, 0, "SqlContactModel"); + qmlRegisterType("io.qt.examples.chattutorial", 1, 0, "SqlConversationModel"); + + connectToDatabase(); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/chapter4/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} + diff --git a/examples/quickcontrols2/chattutorial/chapter4/main.qml b/examples/quickcontrols2/chattutorial/chapter4/main.qml new file mode 100644 index 00000000000..029f45e3c84 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter4/main.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 540 + height: 960 + visible: true + + StackView { + id: stackView + anchors.fill: parent + initialItem: ContactPage {} + } +} + diff --git a/examples/quickcontrols2/chattutorial/chapter4/qtquickcontrols2.conf b/examples/quickcontrols2/chattutorial/chapter4/qtquickcontrols2.conf new file mode 100644 index 00000000000..db9486764e7 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter4/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Basic diff --git a/examples/quickcontrols2/chattutorial/chapter4/sqlcontactmodel.cpp b/examples/quickcontrols2/chattutorial/chapter4/sqlcontactmodel.cpp new file mode 100644 index 00000000000..017e7f4a977 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter4/sqlcontactmodel.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "sqlcontactmodel.h" + +#include +#include +#include + +static void createTable() +{ + if (QSqlDatabase::database().tables().contains(QStringLiteral("Contacts"))) { + // The table already exists; we don't need to do anything. + return; + } + + QSqlQuery query; + if (!query.exec( + "CREATE TABLE IF NOT EXISTS 'Contacts' (" + " 'name' TEXT NOT NULL," + " PRIMARY KEY(name)" + ")")) { + qFatal("Failed to query database: %s", qPrintable(query.lastError().text())); + } + + query.exec("INSERT INTO Contacts VALUES('Albert Einstein')"); + query.exec("INSERT INTO Contacts VALUES('Ernest Hemingway')"); + query.exec("INSERT INTO Contacts VALUES('Hans Gude')"); +} + +SqlContactModel::SqlContactModel(QObject *parent) : + QSqlQueryModel(parent) +{ + createTable(); + + QSqlQuery query; + if (!query.exec("SELECT * FROM Contacts")) + qFatal("Contacts SELECT query failed: %s", qPrintable(query.lastError().text())); + + setQuery(std::move(query)); + if (lastError().isValid()) + qFatal("Cannot set query on SqlContactModel: %s", qPrintable(lastError().text())); +} diff --git a/examples/quickcontrols2/chattutorial/chapter4/sqlcontactmodel.h b/examples/quickcontrols2/chattutorial/chapter4/sqlcontactmodel.h new file mode 100644 index 00000000000..5953c762581 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter4/sqlcontactmodel.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SQLCONTACTMODEL_H +#define SQLCONTACTMODEL_H + +#include + +class SqlContactModel : public QSqlQueryModel +{ +public: + SqlContactModel(QObject *parent = nullptr); +}; + +#endif // SQLCONTACTMODEL_H diff --git a/examples/quickcontrols2/chattutorial/chapter4/sqlconversationmodel.cpp b/examples/quickcontrols2/chattutorial/chapter4/sqlconversationmodel.cpp new file mode 100644 index 00000000000..99526e81d39 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter4/sqlconversationmodel.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "sqlconversationmodel.h" + +#include +#include +#include +#include +#include + +static const char *conversationsTableName = "Conversations"; + +static void createTable() +{ + if (QSqlDatabase::database().tables().contains(conversationsTableName)) { + // The table already exists; we don't need to do anything. + return; + } + + QSqlQuery query; + if (!query.exec( + "CREATE TABLE IF NOT EXISTS 'Conversations' (" + "'author' TEXT NOT NULL," + "'recipient' TEXT NOT NULL," + "'timestamp' TEXT NOT NULL," + "'message' TEXT NOT NULL," + "FOREIGN KEY('author') REFERENCES Contacts ( name )," + "FOREIGN KEY('recipient') REFERENCES Contacts ( name )" + ")")) { + qFatal("Failed to query database: %s", qPrintable(query.lastError().text())); + } + + query.exec("INSERT INTO Conversations VALUES('Me', 'Ernest Hemingway', '2016-01-07T14:36:06', 'Hello!')"); + query.exec("INSERT INTO Conversations VALUES('Ernest Hemingway', 'Me', '2016-01-07T14:36:16', 'Good afternoon.')"); + query.exec("INSERT INTO Conversations VALUES('Me', 'Albert Einstein', '2016-01-01T11:24:53', 'Hi!')"); + query.exec("INSERT INTO Conversations VALUES('Albert Einstein', 'Me', '2016-01-07T14:36:16', 'Good morning.')"); + query.exec("INSERT INTO Conversations VALUES('Hans Gude', 'Me', '2015-11-20T06:30:02', 'God morgen. Har du fått mitt maleri?')"); + query.exec("INSERT INTO Conversations VALUES('Me', 'Hans Gude', '2015-11-20T08:21:03', 'God morgen, Hans. Ja, det er veldig fint. Tusen takk! " + "Hvor mange timer har du brukt på den?')"); +} + +SqlConversationModel::SqlConversationModel(QObject *parent) : + QSqlTableModel(parent) +{ + createTable(); + setTable(conversationsTableName); + setSort(2, Qt::DescendingOrder); + // Ensures that the model is sorted correctly after submitting a new row. + setEditStrategy(QSqlTableModel::OnManualSubmit); +} + +QString SqlConversationModel::recipient() const +{ + return m_recipient; +} + +void SqlConversationModel::setRecipient(const QString &recipient) +{ + if (recipient == m_recipient) + return; + + m_recipient = recipient; + + const QString filterString = QString::fromLatin1( + "(recipient = '%1' AND author = 'Me') OR (recipient = 'Me' AND author='%1')").arg(m_recipient); + setFilter(filterString); + select(); + + emit recipientChanged(); +} + +QVariant SqlConversationModel::data(const QModelIndex &index, int role) const +{ + if (role < Qt::UserRole) + return QSqlTableModel::data(index, role); + + const QSqlRecord sqlRecord = record(index.row()); + return sqlRecord.value(role - Qt::UserRole); +} + +QHash SqlConversationModel::roleNames() const +{ + QHash names; + names[Qt::UserRole] = "author"; + names[Qt::UserRole + 1] = "recipient"; + names[Qt::UserRole + 2] = "timestamp"; + names[Qt::UserRole + 3] = "message"; + return names; +} + +void SqlConversationModel::sendMessage(const QString &recipient, const QString &message) +{ + const QString timestamp = QDateTime::currentDateTime().toString(Qt::ISODate); + + QSqlRecord newRecord = record(); + newRecord.setValue("author", "Me"); + newRecord.setValue("recipient", recipient); + newRecord.setValue("timestamp", timestamp); + newRecord.setValue("message", message); + if (!insertRecord(rowCount(), newRecord)) { + qWarning() << "Failed to send message:" << lastError().text(); + return; + } + + submitAll(); +} diff --git a/examples/quickcontrols2/chattutorial/chapter4/sqlconversationmodel.h b/examples/quickcontrols2/chattutorial/chapter4/sqlconversationmodel.h new file mode 100644 index 00000000000..9c65d64a841 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter4/sqlconversationmodel.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SQLCONVERSATIONMODEL_H +#define SQLCONVERSATIONMODEL_H + +#include + +class SqlConversationModel : public QSqlTableModel +{ + Q_OBJECT + Q_PROPERTY(QString recipient READ recipient WRITE setRecipient NOTIFY recipientChanged) + +public: + SqlConversationModel(QObject *parent = nullptr); + + QString recipient() const; + void setRecipient(const QString &recipient); + + QVariant data(const QModelIndex &index, int role) const override; + QHash roleNames() const override; + + Q_INVOKABLE void sendMessage(const QString &recipient, const QString &message); + +signals: + void recipientChanged(); + +private: + QString m_recipient; +}; + +#endif // SQLCONVERSATIONMODEL_H diff --git a/examples/quickcontrols2/chattutorial/chapter5/+Material/ChatToolBar.qml b/examples/quickcontrols2/chattutorial/chapter5/+Material/ChatToolBar.qml new file mode 100644 index 00000000000..d4a66764bd3 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/+Material/ChatToolBar.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls +import QtQuick.Controls.Material + +ToolBar { + Material.theme: Material.Dark +} diff --git a/examples/quickcontrols2/chattutorial/chapter5/CMakeLists.txt b/examples/quickcontrols2/chattutorial/chapter5/CMakeLists.txt new file mode 100644 index 00000000000..1d39757f1d0 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/CMakeLists.txt @@ -0,0 +1,65 @@ +cmake_minimum_required(VERSION 3.16) +project(chapter5 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/chattutorial/chapter5") + +find_package(Qt6 COMPONENTS Core Gui Qml Quick Sql) + +qt_add_executable(chattutorial-chapter5 WIN32 MACOSX_BUNDLE + main.cpp + sqlcontactmodel.cpp sqlcontactmodel.h + sqlconversationmodel.cpp sqlconversationmodel.h +) +target_link_libraries(chattutorial-chapter5 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick + Qt::Sql +) + +# Resources: +qt_add_qml_module(chattutorial-chapter5 + URI chapter5 + VERSION 1.0 + QML_FILES + "+Material/ChatToolBar.qml" + "ChatToolBar.qml" + "ContactPage.qml" + "ConversationPage.qml" + "main.qml" + RESOURCES + "images/Albert_Einstein.png" + "images/Albert_Einstein@2x.png" + "images/Albert_Einstein@3x.png" + "images/Albert_Einstein@4x.png" + "images/Ernest_Hemingway.png" + "images/Ernest_Hemingway@2x.png" + "images/Ernest_Hemingway@3x.png" + "images/Ernest_Hemingway@4x.png" + "images/Hans_Gude.png" + "images/Hans_Gude@2x.png" + "images/Hans_Gude@3x.png" + "images/Hans_Gude@4x.png" +) + +qt6_add_resources(chattutorial-chapter5 "conf" + PREFIX + "/" + FILES + "qtquickcontrols2.conf" +) + +install(TARGETS chattutorial-chapter5 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/chattutorial/chapter5/ChatToolBar.qml b/examples/quickcontrols2/chattutorial/chapter5/ChatToolBar.qml new file mode 100644 index 00000000000..c192aeb51a6 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/ChatToolBar.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls + +ToolBar { +} diff --git a/examples/quickcontrols2/chattutorial/chapter5/ContactPage.qml b/examples/quickcontrols2/chattutorial/chapter5/ContactPage.qml new file mode 100644 index 00000000000..34a138edca2 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/ContactPage.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +import io.qt.examples.chattutorial + +Page { + id: root + + header: ChatToolBar { + Label { + text: qsTr("Contacts") + font.pixelSize: 20 + anchors.centerIn: parent + } + } + + ListView { + id: listView + anchors.fill: parent + topMargin: 48 + leftMargin: 48 + bottomMargin: 48 + rightMargin: 48 + spacing: 20 + model: SqlContactModel {} + delegate: ItemDelegate { + text: model.display + width: listView.width - listView.leftMargin - listView.rightMargin + height: avatar.implicitHeight + leftPadding: avatar.implicitWidth + 32 + onClicked: root.StackView.view.push("ConversationPage.qml", { inConversationWith: model.display }) + + Image { + id: avatar + source: "images/" + model.display.replace(" ", "_") + ".png" + } + } + } +} + diff --git a/examples/quickcontrols2/chattutorial/chapter5/ConversationPage.qml b/examples/quickcontrols2/chattutorial/chapter5/ConversationPage.qml new file mode 100644 index 00000000000..60dbc4a2ee2 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/ConversationPage.qml @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +import io.qt.examples.chattutorial + +Page { + id: root + + property string inConversationWith + + header: ChatToolBar { + ToolButton { + text: qsTr("Back") + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.verticalCenter: parent.verticalCenter + onClicked: root.StackView.view.pop() + } + + Label { + id: pageTitle + text: inConversationWith + font.pixelSize: 20 + anchors.centerIn: parent + } + } + + ColumnLayout { + anchors.fill: parent + + ListView { + id: listView + Layout.fillWidth: true + Layout.fillHeight: true + Layout.margins: pane.leftPadding + messageField.leftPadding + displayMarginBeginning: 40 + displayMarginEnd: 40 + verticalLayoutDirection: ListView.BottomToTop + spacing: 12 + model: SqlConversationModel { + recipient: inConversationWith + } + delegate: Column { + anchors.right: sentByMe ? listView.contentItem.right : undefined + spacing: 6 + + readonly property bool sentByMe: model.recipient !== "Me" + + Row { + id: messageRow + spacing: 6 + anchors.right: sentByMe ? parent.right : undefined + + Image { + id: avatar + source: !sentByMe ? "images/" + model.author.replace(" ", "_") + ".png" : "" + } + + Rectangle { + width: Math.min(messageText.implicitWidth + 24, listView.width - avatar.width - messageRow.spacing) + height: messageText.implicitHeight + 24 + color: sentByMe ? "lightgrey" : "steelblue" + + Label { + id: messageText + text: model.message + color: sentByMe ? "black" : "white" + anchors.fill: parent + anchors.margins: 12 + wrapMode: Label.Wrap + } + } + } + + Label { + id: timestampText + text: Qt.formatDateTime(model.timestamp, "d MMM hh:mm") + color: "lightgrey" + anchors.right: sentByMe ? parent.right : undefined + } + } + + ScrollBar.vertical: ScrollBar {} + } + + Pane { + id: pane + Layout.fillWidth: true + + RowLayout { + width: parent.width + + TextArea { + id: messageField + Layout.fillWidth: true + placeholderText: qsTr("Compose message") + wrapMode: TextArea.Wrap + } + + Button { + id: sendButton + text: qsTr("Send") + enabled: messageField.length > 0 + onClicked: { + listView.model.sendMessage(inConversationWith, messageField.text); + messageField.text = ""; + } + } + } + } + } +} + diff --git a/examples/quickcontrols2/chattutorial/chapter5/chapter5.pro b/examples/quickcontrols2/chattutorial/chapter5/chapter5.pro new file mode 100644 index 00000000000..625642d7b51 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/chapter5.pro @@ -0,0 +1,36 @@ +TEMPLATE = app + +QT += qml quick sql +CONFIG += c++11 + +HEADERS += sqlcontactmodel.h \ + sqlconversationmodel.h + +SOURCES += main.cpp \ + sqlcontactmodel.cpp \ + sqlconversationmodel.cpp + +resources.files = \ + +Material/ChatToolBar.qml \ + ChatToolBar.qml \ + ContactPage.qml \ + ConversationPage.qml \ + images/Albert_Einstein.png \ + images/Albert_Einstein@2x.png \ + images/Albert_Einstein@3x.png \ + images/Albert_Einstein@4x.png \ + images/Ernest_Hemingway.png \ + images/Ernest_Hemingway@2x.png \ + images/Ernest_Hemingway@3x.png \ + images/Ernest_Hemingway@4x.png \ + images/Hans_Gude.png \ + images/Hans_Gude@2x.png \ + images/Hans_Gude@3x.png \ + images/Hans_Gude@4x.png \ + main.qml +resources.prefix = chapter5/ +RESOURCES += resources \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/chattutorial/chapter5 +INSTALLS += target diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/Albert_Einstein.png b/examples/quickcontrols2/chattutorial/chapter5/images/Albert_Einstein.png new file mode 100644 index 00000000000..7c44b90b8d0 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter5/images/Albert_Einstein.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/Albert_Einstein@2x.png b/examples/quickcontrols2/chattutorial/chapter5/images/Albert_Einstein@2x.png new file mode 100644 index 00000000000..6ce9c39b6c3 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter5/images/Albert_Einstein@2x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/Albert_Einstein@3x.png b/examples/quickcontrols2/chattutorial/chapter5/images/Albert_Einstein@3x.png new file mode 100644 index 00000000000..aab6a6a1628 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter5/images/Albert_Einstein@3x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/Albert_Einstein@4x.png b/examples/quickcontrols2/chattutorial/chapter5/images/Albert_Einstein@4x.png new file mode 100644 index 00000000000..3611284df46 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter5/images/Albert_Einstein@4x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/Ernest_Hemingway.png b/examples/quickcontrols2/chattutorial/chapter5/images/Ernest_Hemingway.png new file mode 100644 index 00000000000..3ac8992fd9b Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter5/images/Ernest_Hemingway.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/Ernest_Hemingway@2x.png b/examples/quickcontrols2/chattutorial/chapter5/images/Ernest_Hemingway@2x.png new file mode 100644 index 00000000000..122d9f1e53d Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter5/images/Ernest_Hemingway@2x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/Ernest_Hemingway@3x.png b/examples/quickcontrols2/chattutorial/chapter5/images/Ernest_Hemingway@3x.png new file mode 100644 index 00000000000..2fe9c2cc1c9 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter5/images/Ernest_Hemingway@3x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/Ernest_Hemingway@4x.png b/examples/quickcontrols2/chattutorial/chapter5/images/Ernest_Hemingway@4x.png new file mode 100644 index 00000000000..96fb6788b5a Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter5/images/Ernest_Hemingway@4x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/Hans_Gude.png b/examples/quickcontrols2/chattutorial/chapter5/images/Hans_Gude.png new file mode 100644 index 00000000000..907e38bc619 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter5/images/Hans_Gude.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/Hans_Gude@2x.png b/examples/quickcontrols2/chattutorial/chapter5/images/Hans_Gude@2x.png new file mode 100644 index 00000000000..6837796a835 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter5/images/Hans_Gude@2x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/Hans_Gude@3x.png b/examples/quickcontrols2/chattutorial/chapter5/images/Hans_Gude@3x.png new file mode 100644 index 00000000000..29af422ad31 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter5/images/Hans_Gude@3x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/Hans_Gude@4x.png b/examples/quickcontrols2/chattutorial/chapter5/images/Hans_Gude@4x.png new file mode 100644 index 00000000000..bc35eeaa799 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/chapter5/images/Hans_Gude@4x.png differ diff --git a/examples/quickcontrols2/chattutorial/chapter5/images/images.qrc b/examples/quickcontrols2/chattutorial/chapter5/images/images.qrc new file mode 100644 index 00000000000..9eda6aa29c4 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/images/images.qrc @@ -0,0 +1,16 @@ + + + Albert_Einstein.png + Albert_Einstein@2x.png + Albert_Einstein@3x.png + Albert_Einstein@4x.png + Ernest_Hemingway.png + Ernest_Hemingway@2x.png + Ernest_Hemingway@3x.png + Ernest_Hemingway@4x.png + Hans_Gude.png + Hans_Gude@2x.png + Hans_Gude@3x.png + Hans_Gude@4x.png + + diff --git a/examples/quickcontrols2/chattutorial/chapter5/main.cpp b/examples/quickcontrols2/chattutorial/chapter5/main.cpp new file mode 100644 index 00000000000..74e66106d4c --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/main.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "sqlcontactmodel.h" +#include "sqlconversationmodel.h" + +static void connectToDatabase() +{ + QSqlDatabase database = QSqlDatabase::database(); + if (!database.isValid()) { + database = QSqlDatabase::addDatabase("QSQLITE"); + if (!database.isValid()) + qFatal("Cannot add database: %s", qPrintable(database.lastError().text())); + } + + const QDir writeDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + if (!writeDir.mkpath(".")) + qFatal("Failed to create writable directory at %s", qPrintable(writeDir.absolutePath())); + + // Ensure that we have a writable location on all devices. + const QString fileName = writeDir.absolutePath() + "/chat-database.sqlite3"; + // When using the SQLite driver, open() will create the SQLite database if it doesn't exist. + database.setDatabaseName(fileName); + if (!database.open()) { + qFatal("Cannot open database: %s", qPrintable(database.lastError().text())); + QFile::remove(fileName); + } +} + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType("io.qt.examples.chattutorial", 1, 0, "SqlContactModel"); + qmlRegisterType("io.qt.examples.chattutorial", 1, 0, "SqlConversationModel"); + + connectToDatabase(); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/chapter5/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} + diff --git a/examples/quickcontrols2/chattutorial/chapter5/main.qml b/examples/quickcontrols2/chattutorial/chapter5/main.qml new file mode 100644 index 00000000000..029f45e3c84 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/main.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 540 + height: 960 + visible: true + + StackView { + id: stackView + anchors.fill: parent + initialItem: ContactPage {} + } +} + diff --git a/examples/quickcontrols2/chattutorial/chapter5/qtquickcontrols2.conf b/examples/quickcontrols2/chattutorial/chapter5/qtquickcontrols2.conf new file mode 100644 index 00000000000..c8a8eeeb052 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/qtquickcontrols2.conf @@ -0,0 +1,10 @@ +[Controls] +Style=Basic + +[Material] +Primary=Indigo +Accent=Indigo +Theme=Dark + +[Universal] +Theme=Dark diff --git a/examples/quickcontrols2/chattutorial/chapter5/sqlcontactmodel.cpp b/examples/quickcontrols2/chattutorial/chapter5/sqlcontactmodel.cpp new file mode 100644 index 00000000000..017e7f4a977 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/sqlcontactmodel.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "sqlcontactmodel.h" + +#include +#include +#include + +static void createTable() +{ + if (QSqlDatabase::database().tables().contains(QStringLiteral("Contacts"))) { + // The table already exists; we don't need to do anything. + return; + } + + QSqlQuery query; + if (!query.exec( + "CREATE TABLE IF NOT EXISTS 'Contacts' (" + " 'name' TEXT NOT NULL," + " PRIMARY KEY(name)" + ")")) { + qFatal("Failed to query database: %s", qPrintable(query.lastError().text())); + } + + query.exec("INSERT INTO Contacts VALUES('Albert Einstein')"); + query.exec("INSERT INTO Contacts VALUES('Ernest Hemingway')"); + query.exec("INSERT INTO Contacts VALUES('Hans Gude')"); +} + +SqlContactModel::SqlContactModel(QObject *parent) : + QSqlQueryModel(parent) +{ + createTable(); + + QSqlQuery query; + if (!query.exec("SELECT * FROM Contacts")) + qFatal("Contacts SELECT query failed: %s", qPrintable(query.lastError().text())); + + setQuery(std::move(query)); + if (lastError().isValid()) + qFatal("Cannot set query on SqlContactModel: %s", qPrintable(lastError().text())); +} diff --git a/examples/quickcontrols2/chattutorial/chapter5/sqlcontactmodel.h b/examples/quickcontrols2/chattutorial/chapter5/sqlcontactmodel.h new file mode 100644 index 00000000000..5953c762581 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/sqlcontactmodel.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SQLCONTACTMODEL_H +#define SQLCONTACTMODEL_H + +#include + +class SqlContactModel : public QSqlQueryModel +{ +public: + SqlContactModel(QObject *parent = nullptr); +}; + +#endif // SQLCONTACTMODEL_H diff --git a/examples/quickcontrols2/chattutorial/chapter5/sqlconversationmodel.cpp b/examples/quickcontrols2/chattutorial/chapter5/sqlconversationmodel.cpp new file mode 100644 index 00000000000..99526e81d39 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/sqlconversationmodel.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "sqlconversationmodel.h" + +#include +#include +#include +#include +#include + +static const char *conversationsTableName = "Conversations"; + +static void createTable() +{ + if (QSqlDatabase::database().tables().contains(conversationsTableName)) { + // The table already exists; we don't need to do anything. + return; + } + + QSqlQuery query; + if (!query.exec( + "CREATE TABLE IF NOT EXISTS 'Conversations' (" + "'author' TEXT NOT NULL," + "'recipient' TEXT NOT NULL," + "'timestamp' TEXT NOT NULL," + "'message' TEXT NOT NULL," + "FOREIGN KEY('author') REFERENCES Contacts ( name )," + "FOREIGN KEY('recipient') REFERENCES Contacts ( name )" + ")")) { + qFatal("Failed to query database: %s", qPrintable(query.lastError().text())); + } + + query.exec("INSERT INTO Conversations VALUES('Me', 'Ernest Hemingway', '2016-01-07T14:36:06', 'Hello!')"); + query.exec("INSERT INTO Conversations VALUES('Ernest Hemingway', 'Me', '2016-01-07T14:36:16', 'Good afternoon.')"); + query.exec("INSERT INTO Conversations VALUES('Me', 'Albert Einstein', '2016-01-01T11:24:53', 'Hi!')"); + query.exec("INSERT INTO Conversations VALUES('Albert Einstein', 'Me', '2016-01-07T14:36:16', 'Good morning.')"); + query.exec("INSERT INTO Conversations VALUES('Hans Gude', 'Me', '2015-11-20T06:30:02', 'God morgen. Har du fått mitt maleri?')"); + query.exec("INSERT INTO Conversations VALUES('Me', 'Hans Gude', '2015-11-20T08:21:03', 'God morgen, Hans. Ja, det er veldig fint. Tusen takk! " + "Hvor mange timer har du brukt på den?')"); +} + +SqlConversationModel::SqlConversationModel(QObject *parent) : + QSqlTableModel(parent) +{ + createTable(); + setTable(conversationsTableName); + setSort(2, Qt::DescendingOrder); + // Ensures that the model is sorted correctly after submitting a new row. + setEditStrategy(QSqlTableModel::OnManualSubmit); +} + +QString SqlConversationModel::recipient() const +{ + return m_recipient; +} + +void SqlConversationModel::setRecipient(const QString &recipient) +{ + if (recipient == m_recipient) + return; + + m_recipient = recipient; + + const QString filterString = QString::fromLatin1( + "(recipient = '%1' AND author = 'Me') OR (recipient = 'Me' AND author='%1')").arg(m_recipient); + setFilter(filterString); + select(); + + emit recipientChanged(); +} + +QVariant SqlConversationModel::data(const QModelIndex &index, int role) const +{ + if (role < Qt::UserRole) + return QSqlTableModel::data(index, role); + + const QSqlRecord sqlRecord = record(index.row()); + return sqlRecord.value(role - Qt::UserRole); +} + +QHash SqlConversationModel::roleNames() const +{ + QHash names; + names[Qt::UserRole] = "author"; + names[Qt::UserRole + 1] = "recipient"; + names[Qt::UserRole + 2] = "timestamp"; + names[Qt::UserRole + 3] = "message"; + return names; +} + +void SqlConversationModel::sendMessage(const QString &recipient, const QString &message) +{ + const QString timestamp = QDateTime::currentDateTime().toString(Qt::ISODate); + + QSqlRecord newRecord = record(); + newRecord.setValue("author", "Me"); + newRecord.setValue("recipient", recipient); + newRecord.setValue("timestamp", timestamp); + newRecord.setValue("message", message); + if (!insertRecord(rowCount(), newRecord)) { + qWarning() << "Failed to send message:" << lastError().text(); + return; + } + + submitAll(); +} diff --git a/examples/quickcontrols2/chattutorial/chapter5/sqlconversationmodel.h b/examples/quickcontrols2/chattutorial/chapter5/sqlconversationmodel.h new file mode 100644 index 00000000000..9c65d64a841 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chapter5/sqlconversationmodel.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SQLCONVERSATIONMODEL_H +#define SQLCONVERSATIONMODEL_H + +#include + +class SqlConversationModel : public QSqlTableModel +{ + Q_OBJECT + Q_PROPERTY(QString recipient READ recipient WRITE setRecipient NOTIFY recipientChanged) + +public: + SqlConversationModel(QObject *parent = nullptr); + + QString recipient() const; + void setRecipient(const QString &recipient); + + QVariant data(const QModelIndex &index, int role) const override; + QHash roleNames() const override; + + Q_INVOKABLE void sendMessage(const QString &recipient, const QString &message); + +signals: + void recipientChanged(); + +private: + QString m_recipient; +}; + +#endif // SQLCONVERSATIONMODEL_H diff --git a/examples/quickcontrols2/chattutorial/chattutorial.pro b/examples/quickcontrols2/chattutorial/chattutorial.pro new file mode 100644 index 00000000000..1c70b2653e4 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/chattutorial.pro @@ -0,0 +1,8 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + chapter1 \ + chapter2 \ + chapter3 \ + chapter4 \ + chapter5 diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter1.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter1.png new file mode 100644 index 00000000000..aa3c4bb5bef Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter1.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter2-listview-header.gif b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter2-listview-header.gif new file mode 100644 index 00000000000..17096519b05 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter2-listview-header.gif differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter2.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter2.png new file mode 100644 index 00000000000..af25cff94e2 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter2.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3-listview-header.gif b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3-listview-header.gif new file mode 100644 index 00000000000..07eb93b191b Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3-listview-header.gif differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3-view-margins.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3-view-margins.png new file mode 100644 index 00000000000..1c8ffbf46e3 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3-view-margins.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3.gif b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3.gif new file mode 100644 index 00000000000..1763b1f3a56 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3.gif differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4-long-message.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4-long-message.png new file mode 100644 index 00000000000..b2f4c2adf8e Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4-long-message.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4-message-timestamp.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4-message-timestamp.png new file mode 100644 index 00000000000..ea75b1dce52 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4-message-timestamp.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4.gif b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4.gif new file mode 100644 index 00000000000..dd47c4cbf81 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4.gif differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material-dark.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material-dark.png new file mode 100644 index 00000000000..8b8f05faa1d Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material-dark.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material-test.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material-test.png new file mode 100644 index 00000000000..29e149df9f1 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material-test.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material.png new file mode 100644 index 00000000000..23d744e7be1 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-universal-dark.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-universal-dark.png new file mode 100644 index 00000000000..2aef535c396 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-universal-dark.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-universal.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-universal.png new file mode 100644 index 00000000000..c18a341b42d Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-universal.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material-dark.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material-dark.png new file mode 100644 index 00000000000..f15c7d7d766 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material-dark.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material-test.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material-test.png new file mode 100644 index 00000000000..b33fc74ea6b Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material-test.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material.png new file mode 100644 index 00000000000..31833164d8c Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-universal-dark.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-universal-dark.png new file mode 100644 index 00000000000..b4bd7e9f4f5 Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-universal-dark.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-universal.png b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-universal.png new file mode 100644 index 00000000000..09ed5ceb94b Binary files /dev/null and b/examples/quickcontrols2/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-universal.png differ diff --git a/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc b/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc new file mode 100644 index 00000000000..e457a414b13 --- /dev/null +++ b/examples/quickcontrols2/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc @@ -0,0 +1,897 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\example chattutorial +\keyword Qt Quick Controls - Chat Tutorial +\title Qt Quick Controls - Chat Tutorial +\keyword Qt Quick Controls 2 - Chat Tutorial +\brief Tutorial about writing a basic chat client using Qt Quick Controls. +\ingroup qtquickcontrols2-examples + +This tutorial shows how to write a basic chat application using Qt Quick +Controls. It will also explain how to integrate an SQL database into a Qt +application. + +\section1 Chapter 1: Setting Up + +When setting up a new project, it's easiest to use +\l {Qt Creator Manual}{Qt Creator}. For this project, we chose the +\l {Qt Creator: Creating Qt Quick Projects}{Qt Quick application} template, which creates a +basic "Hello World" application with the following files: + +\list +\li \c MainForm.ui.qml - Defines the default UI +\li \c main.qml - Embeds the default UI in a Window +\li \c qml.qrc - Lists the \c .qml files that are built into the binary +\li \c main.cpp - Loads \c main.qml +\li \c chattutorial.pro - Provides the qmake configuration +\endlist + +\note Delete the \c MainForm.ui.qml and \c qml.qrc files from the project, as +we will not use them in this tutorial. + +\section2 main.cpp + +The default code in \c main.cpp has two includes: + +\quotefromfile chattutorial/chapter1/main.cpp +\skipto include +\printline include +\printline include + +The first gives us access to QGuiApplication. All Qt applications require +an application object, but the precise type depends on what the application +does. QCoreApplication is sufficient for non-graphical applications. +QGuiApplication is sufficient for graphical applications that do not use +\l {Qt Widgets}, while QApplication is required for those that do. + +The second include makes QQmlApplicationEngine available, along with +some useful functions required for making C++ types accessible from QML. + +Within \c main(), we set up the application object and QML engine: + +\skipto main +\printuntil } + +It begins with enabling \l {High DPI}{high DPI scaling}, which is not +part of the default code. It is necessary to do so before the application +object is constructed. + +After that's done, we construct the application object, passing any application +arguments provided by the user. + +Next, the QML engine is created. \l QQmlApplicationEngine is a convenient +wrapper over QQmlEngine, providing the \l {QQmlApplicationEngine::load}{load()} +function to easily load QML for an application. It also adds some convenience +for using \l {Using File Selectors with Qt Quick Controls}{file selectors}. + +Once we've set up things in C++, we can move on to the user interface in QML. + +\section2 main.qml + +Let's modify the default QML code to suit our needs. + +\quotefromfile chattutorial/chapter1/main.qml +\skipto import +\printuntil import QtQuick.Controls + +First, import the \l {Qt Quick} module. This gives us +access to graphical primitives such as \l Item, \l Rectangle, \l Text, and so +on. +For the full list of types, see the \l {Qt Quick QML Types} documentation. + +Next, import the Qt Quick Controls module. Amongst other things, this +provides access to \l ApplicationWindow, which will replace the existing +root type, \c Window: + +\skipto ApplicationWindow +\printuntil visible: true +\dots +\skipto } +\skipuntil } +\printuntil } + +ApplicationWindow is a \l Window with some added convenience for creating a +\l {ApplicationWindow::}{header} and a \l {ApplicationWindow::}{footer}. +It also provides the foundation for \l {Popup}{popups} and supports some +basic styling, such as the background \l {Window::}{color}. + +There are three properties that are almost always set when using +ApplicationWindow: \l {Window::}{width}, \l {Window::}{height}, and +\l {Window::}{visible}. +Once we've set these, we have a properly sized, empty window ready to be +filled with content. + +\note The \c title property from the default code is removed. + +The first \e "screen" in our application will be a list of contacts. It would +be nice to have some text at the top of each screen that describes its purpose. +The header and footer properties of ApplicationWindow could work in +this situation. They have some characteristics that make them ideal for +items that should be displayed on every screen of an application: + +\list +\li They are anchored to the top and bottom of the window, respectively. +\li They fill the width of the window. +\endlist + +However, when the contents of the header and footer varies depending on +which screen the user is viewing, it is much easier to use \l Page. +For now, we'll just add one page, but in the next chapter, we'll demonstrate +how to navigate between several pages. + +\quotefromfile chattutorial/chapter1/main.qml +\skipto Page +\printuntil } +\printuntil } + +We replace the default \c{MainForm {...}} code block with a Page, which is +sized to occupy all the space on the window using the \l {Item::}{anchors.fill} +property. + +Then, we assign a \l Label to its \l {Page::}{header} property. Label extends +the primitive \l Text item from the Qt Quick module by adding +\l{Styling Qt Quick Controls}{styling} and \l {Control::}{font} inheritance. +This means that a Label can look different depending on which style is in use, +and can also propagate its pixel size to its children. + +We want some distance between the top of the application window and the text, +so we set the \l {Text::padding}{padding} property. This allocates extra +space on each side of the label (within its bounds). We can also explicitly set +the \l {Text::}{topPadding} and \l {Text::}{bottomPadding} properties instead. + +We set the text of the label using the \c qsTr() function, which ensures that +the text can be translated by \l {Writing Source Code for Translation}{Qt's +translation system}. It's a good practice to follow for text that is visible to +the end users of your application. + +By default, text is vertically aligned to the top of its bounds, while the +horizontal alignment depends on the natural direction of the text; for example, +text that is read from left to right will be aligned to the left. If we +used these defaults, our text would be at the top-left corner of the window. +This is not desirable for a header, so we align the text to the center of its +bounds, both horizontally and vertically. + +\section2 The Project File + +The \c .pro or \l {Creating Project Files}{project} file contains all of the +information needed by \l {qmake Manual}{qmake} to generate a Makefile, which is +then used to compile and link the application. + +\quotefromfile chattutorial/chapter1/chapter1.pro +\printline TEMPLATE + +The first line tells \c qmake which kind of project this is. We're building an +application, so we use the \c app template. + +\printline QT + +The next line declares the Qt libraries that we want to use from C++. + +\printline CONFIG + +This line states that a C++11 compatible compiler is required to build the +project. + +\printline SOURCES + +The \c SOURCES variable lists all of the source files that should be compiled. +A similar variable, \c HEADERS, is available for header files. + +\printuntil qtquickcontrols2 + +The next line tells \c qmake that we have a collection of +\l {The Qt Resource System}{resources} that should be built into the +executable. + +\printline target.path + +This line replaces deployment settings that come with the default project file. +It determines where the example is copied, on running "\c{make install}". + +Now we can build and run the application: + +\borderedimage qtquickcontrols2-chattutorial-chapter1.png + +\noautolist +\generatelist examplefiles .*chapter1.* + +\section1 Chapter 2: Lists + +In this chapter, we'll explain how to create a list of interactive items using +\l ListView and \l ItemDelegate. + +ListView comes from the Qt Quick module, and displays a list of items +populated from a \l {Models and Views in Qt Quick}{model}. ItemDelegate comes from +the Qt Quick Controls module, and provides a standard view item for use in views +and controls such as ListView and \l ComboBox. For example, each ItemDelegate +can display text, be checked on and off, and react to mouse clicks. + +Here is our ListView: + +\quotefromfile chattutorial/chapter2/main.qml +\dots 8 +\codeline +\skipto ListView +\printuntil } +\printuntil } +\printuntil } +\codeline +\dots 8 + +\section2 Sizing and Positioning + +The first thing we do is set a size for the view. It should fill the available +space on the page, so we use \l {Item::}{anchors.fill}. Note that +Page ensures that its header and footer have enough of their own space +reserved, so the view in this case will sit below the header, for example. + +Next, we set \l {Flickable::leftMargin}{margins} around the ListView to put +some distance between it and the edges of the window. The margin properties +reserve space within the bounds of the view, which means that the empty areas +can still be \e "flicked" by the user. + +The items should be nicely spaced out within the view, so the +\l {ListView::}{spacing} property is set to \c 20. + +\section2 Model + +In order to quickly populate the view with some items, we've used a JavaScript +array as the model. One of the greatest strengths of QML is its ability to +make prototyping an application extremely quick, and this is an example of +that. It's also possible to simply assign a \l {Integers as Models}{number} to +the model property to indicate how many items you need. For example, if you +assign \c 10 to the \c model property, each item's display text will be a +number from \c 0 to \c 9. + +However, once the application gets past the prototype stage, it quickly becomes +necessary to use some real data. For this, it's best to use a proper C++ model +by \l {QAbstractItemModel}{subclassing QAbstractItemModel}. + +\section2 Delegate + +On to the \l {ListView::}{delegate}. We assign the corresponding text from the +model to the \l {AbstractButton::text}{text} property of ItemDelegate. The exact +manner in which the data from the model is made available to each delegate +depends on the type of model used. See \l {Models and Views in Qt Quick} for +more information. + +In our application, the width of each item in the view should be the same +as the width of the view. This ensures that the user has a lot of room with +which to select a contact from the list, which is an important factor on +devices with small touch screens, like mobile phones. However, the width of the +view includes our \c 48 pixel margins, so we must account for that in our +assignment to the width property. + +Next, we define an \l Image. This will display a picture of the user's contact. +The image will be \c 40 pixels wide and \c 40 pixels high. We'll base the +height of the delegate on the image's height, so that we don't have any empty +vertical space. + +\borderedimage qtquickcontrols2-chattutorial-chapter2.png + +\generatelist examplefiles .*(chapter2|shared).* +\generatelist exampleimages .*shared.*(Einstein|Hemingway|Gude)\.png + +\section1 Chapter 3: Navigation + +In this chapter, you'll learn how to use \l StackView to navigate between pages +in an application. Here's the revised \c main.qml: + +\quotefromfile chattutorial/chapter3/main.qml +\skipto import +\printuntil } +\printuntil } +\printuntil } + +\section2 Navigating with StackView + +As its name suggests, StackView provides stack-based navigation. The last item +to be \e "pushed" onto the stack is the first one to be removed, and the +top-most item is always the one that is visible. + +In the same manner as we did with Page, we tell the StackView to fill the +application window. The only thing left to do after that is to give it an item +to display, via \l {StackView::}{initialItem}. StackView accepts +\l {Item}{items}, \l {Component}{components} and \l [QML]{url}{URLs}. + +You'll notice that we moved the code for the contact list into +\c ContactPage.qml. It's a good idea to do this as soon as you have a general +idea of which screens your application will contain. Doing so not only makes +your code easier to read, but ensures that items are only instantiated from +a given component when completely necessary, reducing memory usage. + +\note Qt Creator provides several convenient \l {http://doc.qt.io/qtcreator/creator-editor-refactoring.html#refactoring-qml-code}{refactoring options for QML}, +one of which allows you to move a block of code into a separate file + (\c {Alt + Enter > Move Component into Separate File}). + +Another thing to consider when using ListView is whether to refer to it by +\c id, or use the attached \l {ListView::view}{ListView.view} +property. The best approach depends on a few different factors. Giving the +view an id will result in shorter and more efficient binding expressions, as +the attached property has a very small amount of overhead. However, if you plan +on reusing the delegate in other views, it is better to use the attached +properties to avoid tying the delegate to a particular view. For example, using +the attached properties, the \c width assignment in our delegate becomes: + +\code +width: ListView.view.width - ListView.view.leftMargin - ListView.view.rightMargin +\endcode + +In chapter 2, we added a ListView below the header. If you run the application +for that chapter, you'll see that the contents of the view can be scrolled over +the top of the header: + +\borderedimage qtquickcontrols2-chattutorial-chapter2-listview-header.gif + +This is not that nice, especially if the text in the +delegates is long enough that it reaches the text in the header. What we +ideally want to do is to have a solid block of color under the header text, but +\e {above} the view. This ensures that the listview contents can't visually +interfere with the header contents. Note that it's also possible to achieve +this by setting the \l {Item::}{clip} property of the view to \c true, but +doing so \l {Clipping}{can affect performance}. + +\l ToolBar is the right tool for this job. It is a container of both +application-wide and context-sensitive actions and controls, such as navigation +buttons and search fields. Best of all, it has a background color that, as +usual, comes from the application style. Here it is in action: + +\quotefromfile chattutorial/chapter3/ContactPage.qml +\skipto header +\printuntil } +\printuntil } + +\borderedimage qtquickcontrols2-chattutorial-chapter3-listview-header.gif + +It has no layout of its own, so we center the label within it ourselves. + +The rest of the code is the same as it was in chapter 2, except that we've +taken advantage of the \l {AbstractButton::}{clicked} signal to push the next +page onto the stackview: + +\skipto onClicked +\printline onClicked + +When pushing a \l Component or \l [QML] url onto StackView, it's often +necessary to initialize the (eventually) instantiated item with some variables. +StackView's \l {StackView::push}{push()} function accounts for this, by taking a JavaScript object +as the second argument. We use this to provide the next page with a contact's +name, which it then uses to display the relevant conversation. Note the +\c {root.StackView.view.push} syntax; this is necessary because of how +\l {A Note About Accessing Attached Properties and Signal Handlers} +{attached properties} work. + +Let's step through \c ConversationPage.qml, beginning with the imports: + +\quotefromfile chattutorial/chapter3/ConversationPage.qml +\skipto import +\printline import +\printline import +\printline import + +These are the same as before, except for the addition of the \c QtQuick.Layouts +import, which we'll cover shortly. + +\skipto Page +\printuntil } +\printuntil } +\printuntil } +\dots 4 + +The root item of this component is another Page, which has a custom property +called \c inConversationWith. For now, this property will simply determine what +the label in the header displays. Later on, we'll use it in the SQL query that +populates the list of messages in the conversation. + +To allow the user to go back to the Contact page, we add a \l ToolButton that +calls \l {StackView::pop}{pop()} when clicked. A \l ToolButton is functionally +similar to \l Button, but provides a look that is more suitable within a +ToolBar. + +There are two ways of laying out items in QML: \l {Item Positioners} +and \l {Qt Quick Layouts}. Item positioners (\l Row, \l Column, and so on) are +useful for situations where the size of items is known or fixed, and all that +is required is to neatly position them in a certain formation. The layouts in +Qt Quick Layouts can both position and resize items, making them well suited +for resizable user interfaces. Below, we use \l ColumnLayout to vertically +lay out a ListView and a \l Pane: + +\skipto ColumnLayout +\printto Layout.margins +\codeline +\dots 12 +\codeline +\skipuntil ScrollBar +\printline } +\codeline +\dots 8 +\codeline +\printuntil Layout.fillWidth: true +\dots 12 +\skipuntil } +\skipuntil } +\skipuntil } +\skipuntil } +\printline } + +Pane is basically a rectangle whose color comes from the application's style. +It is similar to \l Frame, with the only difference being that it has no stroke +around its border. + +Items that are direct children of a layout have various +\l {Layout}{attached properties} available to them. We use +\l {Layout::fillWidth}{Layout.fillWidth} and +\l {Layout::fillHeight}{Layout.fillHeight} on the ListView to ensure +that it takes as much space within the ColumnLayout as it can. The +same is done for the Pane. As ColumnLayout is a vertical layout, there +aren't any items to the left or right of each child, so this will result in +each item consuming the entire width of the layout. + +On the other hand, the \l {Layout::fillHeight}{Layout.fillHeight} statement in +the ListView will enable it to occupy the remaining space that is left after +accommodating the Pane. + +Let's look at the listview in detail: + +\quotefromfile chattutorial/chapter3/ConversationPage.qml +\skipto ListView +\printuntil ScrollBar +\printuntil } + +After filling the width and height of its parent, we also set some margins on +the view. This gives us a nice alignment with the placeholder text in the +"compose message" field: + +\borderedimage qtquickcontrols2-chattutorial-chapter3-view-margins.png + +Next, we set \l {ListView::}{displayMarginBeginning} and \l +{ListView::}{displayMarginEnd}. These properties ensure that the delegates +outside the bounds of the view do not disappear while scrolling at the edges of +the view. It's easiest to understand this by commenting out the properties and +seeing what happens when scrolling the view. + +We then flip the vertical direction of the view, so that first items are at the +bottom. The delegates are spaced out by 12 pixels, and a \e "dummy" model is +assigned for testing purposes, until we implement the real model in chapter 4. + +Within the delegate, we declare a \l Row as the root item, as we want the +avatar to be followed by the message contents, as shown in the image above. + +Messages sent by the user should be distinguished from those sent by a contact. +For now, we set a dummy property \c sentByMe, which simply uses the index +of the delegate to alternate between different authors. Using this property, +we distinguish between different authors in three ways: + +\list +\li Messages sent by the user are aligned to the right side of the screen +by setting \c anchors.right to \c listView.contentItem.right. + +\li By setting the \c visible property of the avatar (which is simply a +Rectangle for now) based on \c sentByMe, we only show it if the message was +sent by a contact. + +\li We change the color of the rectangle depending on the author. Since we +do not want to display dark text on a dark background, and vice versa, we also +set the text color depending on who the author is. In chapter 5, we'll see how +styling takes care of matters like this for us. +\endlist + +At the bottom of the screen, we place a \l TextArea item to allow multi-line +text input, and a button to send the message. We use Pane to cover the area +under these two items, in the same way that we use ToolBar to prevent the +contents of the listview from interfering with the page header: + +\skipto Pane +\printuntil } +\printuntil } +\printuntil } +\printuntil } + +The TextArea should fill the available width of the screen. We assign some +placeholder text to provide a visual cue to the user as to where they should +begin typing. The text within the input area is wrapped to ensure that it +does not go outside of the screen. + +Finally, the button is only enabled when there is actually a message to send. + +\borderedimage qtquickcontrols2-chattutorial-chapter3.gif + +\generatelist examplefiles .*(chapter3|shared).* +\generatelist exampleimages .*shared.*(Einstein|Hemingway|Gude)\.png + +\section1 Chapter 4: Models + +In chapter 4, we'll take you through the process of creating both read-only and +read-write SQL models in C++ and exposing them to QML to populate views. + +\section2 QSqlQueryModel + +In order to keep the tutorial simple, we've chosen to make the list of user +contacts non-editable. \l QSqlQueryModel is the logical choice for this +purpose, as it provides a read-only data model for SQL result sets. + +Let's take a look at our \c SqlContactModel class that derives from +QSqlQueryModel: + +\quotefromfile chattutorial/chapter4/sqlcontactmodel.h +\skipto #include +\printuntil }; + +There's not much going on here, so let's move on to the \c .cpp file: + +\quotefromfile chattutorial/chapter4/sqlcontactmodel.cpp +\skipto #include +\printuntil } +\printuntil } +\printuntil } + +We include the header file of our class and those that we require from Qt. We +then define a static function named \c createTable() that we'll use to create +the SQL table (if it doesn't already exist), and then populate it with some +dummy contacts. + +The call to \l {QSqlDatabase::database}{database()} might look a little bit +confusing because we have not set up a specific database yet. If no connection +name is passed to this function, it will return a \e {"default connection"}, +whose creation we will cover soon. + +\skipto SqlContactModel +\printuntil } + +In the constructor, we call \c createTable(). We then construct a query that +will be used to populate the model. In this case, we are simply interested in +all rows of the \c Contacts table. + +\section2 QSqlTableModel + +\c SqlConversationModel is more complex: + +\quotefromfile chattutorial/chapter4/sqlconversationmodel.h +\skipto #include +\printuntil }; + +We use both the \c Q_PROPERTY and \c Q_INVOKABLE macros, and therefore we must +let \l {Using the Meta-Object Compiler (moc)}{moc} know by using the \c +Q_OBJECT macro. + +The \c recipient property will be set from QML to let the model know which +conversation it should retrieve messages for. + +We override the \l {QSqlTableModel::data}{data()} and +\l {QAbstractItemModel::}{roleNames()} functions so that we can use our +custom roles in QML. + +We also define the \c sendMessage() function that we want to call from +QML, hence the \c Q_INVOKABLE macro. + +Let's take a look at the \c .cpp file: + +\quotefromfile chattutorial/chapter4/sqlconversationmodel.cpp +\skipto #include +\printuntil } +\printuntil } +\printuntil } + +This is very similar to \c sqlcontactmodel.cpp, with the exception that we are +now operating on the \c Conversations table. We also define +\c conversationsTableName as a static const variable, as we use it in a couple +of places throughout the file. + +\skipto SqlConversationModel +\printuntil } + +As with \c SqlContactModel, the first thing that we do in the constructor is +create the table. We tell QSqlTableModel the name of the table we'll be using +via the \l {QSqlTableModel::setTable}{setTable()} function. To ensure that the +latest messages in the conversation are shown first, we sort the query results +by the \c timestamp field in descending order. This goes hand in hand with +setting ListView's \l {ListView::}{verticalLayoutDirection} property to +\c ListView.BottomToTop (which we covered in chapter 3). + +\skipto ::recipient( +\printuntil } +\printuntil } + +In \c setRecipient(), we set a filter over the results returned from +the database. + +\skipto ::data( +\printuntil } + +The \c data() function falls back to QSqlTableModel's implementation if the +role is not a custom user role. If the role is a user role, we can subtract +Qt::UserRole from it to get the index of that field and then use that to find +the value that we need to return. + +\skipto ::roleNames( +\printuntil } + +In \c roleNames(), we return a mapping of our custom role values to role names. +This enables us to use these roles in QML. It can be useful to declare an enum +to hold all of the role values, but since we don't refer to any specific value +in code outside of this function, we don't bother. + +\skipto ::sendMessage( +\printuntil } + +The \c sendMessage() function uses the given \c recipient and a \c message to +insert a new record into the database. Due to our usage +of \l QSqlTableModel::OnManualSubmit, we must manually call +\l {QSqlTableModel::submitAll}{submitAll()}. + +\section2 Connecting to the Database and Registering Types With QML + +Now that we've established the model classes, let's take a look at \c main.cpp: + +\quotefromfile chattutorial/chapter4/main.cpp +\skipto #include +\printuntil return app.exec(); +\printuntil } + +\c connectToDatabase() creates the connection to the SQLite database, creating +the actual file if it doesn't already exist. + +Within \c main(), we call \l {qmlRegisterType}{qmlRegisterType()} to +register our models as types within QML. + +\section2 Using the Models in QML + +Now that we have the models available as QML types, there are some minor +changes to be done to \c ContactPage.qml. To be able to use the types, +we must first import them using the URI we set in \c main.cpp: + +\quotefromfile chattutorial/chapter4/ContactPage.qml +\skipto import io.qt.examples.chattutorial +\printline import io.qt.examples.chattutorial + +We then replace the dummy model with the proper one: + +\skipto model: SqlContactModel {} +\printline model: SqlContactModel {} + +Within the delegate, we use a different syntax for accessing the model data: + +\skipto text: model.display +\printline text: model.display + +In \c ConversationPage.qml, we add the same \c chattutorial import, and replace +the dummy model: + +\quotefromfile chattutorial/chapter4/ConversationPage.qml +\skipto model: SqlConversationModel { +\printuntil } + +Within the model, we set the \c recipient property to the name of the contact +for which the page is being displayed. + +The root delegate item changes from a Row to a Column, to accommodate the +timestamp that we want to display below every message: + +\skipto delegate: Column { +\printuntil Label { +\printuntil } +\printuntil } +\printuntil } +\printuntil } +\printuntil } + +\borderedimage qtquickcontrols2-chattutorial-chapter4-message-timestamp.png + +Now that we have a proper model, we can use its \c recipient role in the +expression for the \c sentByMe property. + +The Rectangle that was used for the avatar has been converted into an Image. +The image has its own implicit size, so we don't need to specify it explicitly. +As before, we only show the avatar when the author isn't the user, except this +time we set the \c source of the image to an empty URL instead of using the +\c visible property. + +We want each message background to be slightly wider (12 pixels each side) than +its text. However, if it's too long, we want to limit its width to the edge +of the listview, hence the usage of \c Math.min(). When the message wasn't sent +by us, an avatar will always come before it, so we account for that by +subtracting the width of the avatar and the row spacing. + +For example, in the image above, the implicit width of the message text is the +smaller value. However, in the image below, the message text is quite long, so +the smaller value (the width of the view) is chosen, ensuring that the text +stops at the opposite edge of the screen: + +\borderedimage qtquickcontrols2-chattutorial-chapter4-long-message.png + +In order to display the timestamp for each message that we discussed earlier, +we use a Label. The date and time are formatted with +\l {QtQml::Qt::formatDateTime}{Qt.formatDateTime()}, using a custom format. + +The \e "send" button must now react to being clicked: + +\skipto Button +\printuntil } +\printuntil } + +First, we call the invokable \c sendMessage() function of the model, which +inserts a new row into the Conversations database table. Then, we clear the +text field to make way for future input. + +\borderedimage qtquickcontrols2-chattutorial-chapter4.gif + +\generatelist examplefiles .*(chapter4|shared).* +\generatelist exampleimages + +\section1 Chapter 5: Styling + +Styles in Qt Quick Controls are designed to work on any platform. In this +chapter, we'll do some minor visual tweaks to make sure our application +looks good when run with the \l {Basic Style}{Basic}, +\l {Material Style}{Material}, and \l {Universal Style}{Universal} styles. + +So far, we've just been testing the application with the Basic style. If we +run it with the \l {Material Style}, for example, we'll immediately see some issues. +Here is the Contacts page: + +\borderedimage qtquickcontrols2-chattutorial-chapter5-contacts-material-test.png + +The header text is black on a dark blue background, which is very difficult to +read. The same thing occurs with the Conversations page: + +\borderedimage qtquickcontrols2-chattutorial-chapter5-conversations-material-test.png + +The solution is to tell the toolbar that it should use the \e "Dark" theme, so +that this information is propagated to its children, allowing them to switch +their text color to something lighter. The simplest way of doing so is to +import the Material style directly and use the Material attached property: + +\code + import QtQuick.Controls.Material 2.12 + + // ... + + header: ToolBar { + Material.theme: Material.Dark + + // ... + } +\endcode + +However, this brings with it a hard dependency to the Material style; the +Material style plugin \e must be deployed with the application, even if the +target device doesn't use it, otherwise the QML engine will fail to find the +import. + +Instead, it is better to rely on Qt Quick Controls's built-in support for +\l {Using File Selectors with Qt Quick Controls}{style-based file selectors}. +To do this, we must move the ToolBar out into its own file. We'll call it +\c ChatToolBar.qml. This will be the \e "default" version of the file, which +means that it will be used when the \l {Basic Style}{Basic style} (which is the +style that is used when none is specified) is in +use. Here's the new file: + +\quotefromfile chattutorial/chapter5/ChatToolBar.qml +\skipto import +\printuntil } + +As we only use the ToolBar type within this file, we only need the +Qt Quick Controls import. The code itself has not changed from how it was +in \c ContactPage.qml, which is how it should be; for the default version +of the file, nothing needs to be different. + +Back in \c ContactPage.qml, we update the code to use the new type: + +\quotefromfile chattutorial/chapter5/ContactPage.qml +\skipto ToolBar +\printuntil } +\printuntil } + +Now we need to add the Material version of the toolbar. File selectors expect +variants of a file to be in appropriately named directories that exist +alongside the default version of the file. This means that we need to add a +folder named "+Material" in the same directory that ChatToolBar.qml is in: +the root folder. The "+" is required by \l QFileSelector as a way of ensuring +that the selection feature is not accidentally triggered. + +Here's \c +Material/ChatToolBar.qml: + +\quotefromfile chattutorial/chapter5/+Material/ChatToolBar.qml +\skipto import +\printuntil } + +We'll make the same changes to \c ConversationPage.qml: + +\quotefromfile chattutorial/chapter5/ConversationPage.qml +\skipto header: ChatToolBar +\printuntil } +\printuntil } +\printuntil } + +Now both pages look correct: + +\borderedimage qtquickcontrols2-chattutorial-chapter5-contacts-material.png +\borderedimage qtquickcontrols2-chattutorial-chapter5-conversations-material.png + +Let's try out the Universal style: + +\borderedimage qtquickcontrols2-chattutorial-chapter5-contacts-universal.png +\borderedimage qtquickcontrols2-chattutorial-chapter5-conversations-universal.png + +No issues there. For a relatively simple application such as this one, there +should be very few adjustments necessary when switching styles. + +Now let's try each style's dark theme. The Basic style has no dark theme, as +it would add a slight overhead to a style that is designed to be as performant +as possible. We'll test out the Material style first, so add an entry to +\c qtquickcontrols2.conf that tells it to use its dark theme: + +\code +[Material] +Primary=Indigo +Accent=Indigo +Theme=Dark +\endcode + +Once this is done, build and run the application. This is what you should see: + +\borderedimage qtquickcontrols2-chattutorial-chapter5-contacts-material-dark.png +\borderedimage qtquickcontrols2-chattutorial-chapter5-conversations-material-dark.png + +Both pages look fine. Now add an entry for the Universal style: + +\code +[universal] +Theme=Dark +\endcode + +After building and running the application, you should see these results: + +\borderedimage qtquickcontrols2-chattutorial-chapter5-contacts-universal-dark.png +\borderedimage qtquickcontrols2-chattutorial-chapter5-conversations-universal-dark.png + +\generatelist examplefiles .*(chapter5|shared).* +\generatelist exampleimages + +\section1 Summary + +In this tutorial, we've taken you through the following steps of writing a +basic application using Qt Quick Controls: + +\list +\li Creating a new project using Qt Creator. +\li Setting up a basic ApplicationWindow. +\li Defining headers and footers with Page. +\li Displaying content in a ListView. +\li Refactoring components into their own files. +\li Navigating between screens with StackView. +\li Using layouts to allow an application to resize gracefully. +\li Implementing both custom read-only and writable models that integrate an +SQL database into the application. +\li Integrating C++ with QML via \l Q_PROPERTY, \l Q_INVOKABLE, and +\l qmlRegisterType(). +\li Testing and configuring multiple styles. +\endlist + +*/ diff --git a/examples/quickcontrols2/contactlist/CMakeLists.txt b/examples/quickcontrols2/contactlist/CMakeLists.txt new file mode 100644 index 00000000000..6c705c373fa --- /dev/null +++ b/examples/quickcontrols2/contactlist/CMakeLists.txt @@ -0,0 +1,59 @@ +# Generated from contactlist.pro. + +cmake_minimum_required(VERSION 3.16) +project(contactlist LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/contactlist") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) + +qt_add_executable(contactlist + contactmodel.cpp contactmodel.h + main.cpp +) +set_target_properties(contactlist PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(contactlist PUBLIC + Qt::Core + Qt::Gui + Qt::Quick +) + + +# Resources: +set(qmake_immediate_resource_files + "ContactDelegate.ui.qml" + "ContactDialog.qml" + "ContactForm.ui.qml" + "ContactView.ui.qml" + "SectionDelegate.ui.qml" + "contactlist.qml" + "designer/Backend/ContactModel.qml" +) + +qt6_add_resources(contactlist "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + +install(TARGETS contactlist + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/contactlist/ContactDelegate.ui.qml b/examples/quickcontrols2/contactlist/ContactDelegate.ui.qml new file mode 100644 index 00000000000..dde9a4f4250 --- /dev/null +++ b/examples/quickcontrols2/contactlist/ContactDelegate.ui.qml @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +ItemDelegate { + id: delegate + + checkable: true + + contentItem: ColumnLayout { + spacing: 10 + + Label { + text: fullName + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + + GridLayout { + id: grid + visible: false + + columns: 2 + rowSpacing: 10 + columnSpacing: 10 + + Label { + text: qsTr("Address:") + Layout.leftMargin: 60 + } + + Label { + text: address + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + + Label { + text: qsTr("City:") + Layout.leftMargin: 60 + } + + Label { + text: city + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + + Label { + text: qsTr("Number:") + Layout.leftMargin: 60 + } + + Label { + text: number + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + } + } + + states: [ + State { + name: "expanded" + when: delegate.checked + + PropertyChanges { + target: grid + visible: true + } + } + ] +} diff --git a/examples/quickcontrols2/contactlist/ContactDialog.qml b/examples/quickcontrols2/contactlist/ContactDialog.qml new file mode 100644 index 00000000000..679a2673b12 --- /dev/null +++ b/examples/quickcontrols2/contactlist/ContactDialog.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Dialog { + id: dialog + + signal finished(string fullName, string address, string city, string number) + + function createContact() { + form.fullName.clear(); + form.address.clear(); + form.city.clear(); + form.number.clear(); + + dialog.title = qsTr("Add Contact"); + dialog.open(); + } + + function editContact(contact) { + form.fullName.text = contact.fullName; + form.address.text = contact.address; + form.city.text = contact.city; + form.number.text = contact.number; + + dialog.title = qsTr("Edit Contact"); + dialog.open(); + } + + x: parent.width / 2 - width / 2 + y: parent.height / 2 - height / 2 + + focus: true + modal: true + title: qsTr("Add Contact") + standardButtons: Dialog.Ok | Dialog.Cancel + + contentItem: ContactForm { + id: form + } + + onAccepted: finished(form.fullName.text, form.address.text, form.city.text, form.number.text) +} diff --git a/examples/quickcontrols2/contactlist/ContactForm.ui.qml b/examples/quickcontrols2/contactlist/ContactForm.ui.qml new file mode 100644 index 00000000000..406a300a266 --- /dev/null +++ b/examples/quickcontrols2/contactlist/ContactForm.ui.qml @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +GridLayout { + id: grid + property alias fullName: fullName + property alias address: address + property alias city: city + property alias number: number + property int minimumInputSize: 120 + property string placeholderText: qsTr("") + + rows: 4 + columns: 2 + + Label { + text: qsTr("Full Name") + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + } + + TextField { + id: fullName + focus: true + Layout.fillWidth: true + Layout.minimumWidth: grid.minimumInputSize + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + placeholderText: grid.placeholderText + } + + Label { + text: qsTr("Address") + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + } + + TextField { + id: address + Layout.fillWidth: true + Layout.minimumWidth: grid.minimumInputSize + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + placeholderText: grid.placeholderText + } + + Label { + text: qsTr("City") + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + } + + TextField { + id: city + Layout.fillWidth: true + Layout.minimumWidth: grid.minimumInputSize + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + placeholderText: grid.placeholderText + } + + Label { + text: qsTr("Number") + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + } + + TextField { + id: number + Layout.fillWidth: true + Layout.minimumWidth: grid.minimumInputSize + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + placeholderText: grid.placeholderText + } +} diff --git a/examples/quickcontrols2/contactlist/ContactView.ui.qml b/examples/quickcontrols2/contactlist/ContactView.ui.qml new file mode 100644 index 00000000000..88ac01cfd56 --- /dev/null +++ b/examples/quickcontrols2/contactlist/ContactView.ui.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import Backend + +ListView { + id: listView + + signal pressAndHold(int index) + + width: 320 + height: 480 + + focus: true + boundsBehavior: Flickable.StopAtBounds + + section.property: "fullName" + section.criteria: ViewSection.FirstCharacter + section.delegate: SectionDelegate { + width: listView.width + } + + delegate: ContactDelegate { + id: delegate + width: listView.width + onPressAndHold: listView.pressAndHold(index) + } + + model: ContactModel { + id: contactModel + } + + ScrollBar.vertical: ScrollBar { } +} diff --git a/examples/quickcontrols2/contactlist/SectionDelegate.ui.qml b/examples/quickcontrols2/contactlist/SectionDelegate.ui.qml new file mode 100644 index 00000000000..49ae528b565 --- /dev/null +++ b/examples/quickcontrols2/contactlist/SectionDelegate.ui.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ToolBar { + id: background + + Label { + id: label + text: section + anchors.fill: parent + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + } +} diff --git a/examples/quickcontrols2/contactlist/contactlist.pro b/examples/quickcontrols2/contactlist/contactlist.pro new file mode 100644 index 00000000000..101db15a3df --- /dev/null +++ b/examples/quickcontrols2/contactlist/contactlist.pro @@ -0,0 +1,28 @@ +TEMPLATE = app +TARGET = contactlist +QT += quick + +HEADERS += \ + contactmodel.h + +SOURCES += \ + main.cpp \ + contactmodel.cpp + +RESOURCES += \ + ContactDelegate.ui.qml \ + ContactDialog.qml \ + ContactForm.ui.qml \ + contactlist.qml \ + ContactView.ui.qml \ + designer/Backend/ContactModel.qml \ + SectionDelegate.ui.qml + +# Additional import path used to resolve QML modules just for Qt Quick Designer +QML_DESIGNER_IMPORT_PATH = $$PWD/designer + +OTHER_FILES += \ + designer/Backend/*.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/contactlist +INSTALLS += target diff --git a/examples/quickcontrols2/contactlist/contactlist.qml b/examples/quickcontrols2/contactlist/contactlist.qml new file mode 100644 index 00000000000..e904c9faeb8 --- /dev/null +++ b/examples/quickcontrols2/contactlist/contactlist.qml @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property int currentContact: -1 + + width: 320 + height: 480 + visible: true + title: qsTr("Contact List") + + ContactDialog { + id: contactDialog + onFinished: { + if (currentContact === -1) + contactView.model.append(fullName, address, city, number) + else + contactView.model.set(currentContact, fullName, address, city, number) + } + } + + Menu { + id: contactMenu + x: parent.width / 2 - width / 2 + y: parent.height / 2 - height / 2 + modal: true + + Label { + padding: 10 + font.bold: true + width: parent.width + horizontalAlignment: Qt.AlignHCenter + text: currentContact >= 0 ? contactView.model.get(currentContact).fullName : "" + } + MenuItem { + text: qsTr("Edit...") + onTriggered: contactDialog.editContact(contactView.model.get(currentContact)) + } + MenuItem { + text: qsTr("Remove") + onTriggered: contactView.model.remove(currentContact) + } + } + + ContactView { + id: contactView + anchors.fill: parent + onPressAndHold: { + currentContact = index + contactMenu.open() + } + } + + RoundButton { + text: qsTr("+") + highlighted: true + anchors.margins: 10 + anchors.right: parent.right + anchors.bottom: parent.bottom + onClicked: { + currentContact = -1 + contactDialog.createContact() + } + } +} diff --git a/examples/quickcontrols2/contactlist/contactmodel.cpp b/examples/quickcontrols2/contactlist/contactmodel.cpp new file mode 100644 index 00000000000..9c83090c1c2 --- /dev/null +++ b/examples/quickcontrols2/contactlist/contactmodel.cpp @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "contactmodel.h" + +ContactModel::ContactModel(QObject *parent ) : QAbstractListModel(parent) +{ + m_contacts.append({ "Angel Hogan", "Chapel St. 368 ", "Clearwater" , "0311 1823993" }); + m_contacts.append({ "Felicia Patton", "Annadale Lane 2", "Knoxville" , "0368 1244494" }); + m_contacts.append({ "Grant Crawford", "Windsor Drive 34", "Riverdale" , "0351 7826892" }); + m_contacts.append({ "Gretchen Little", "Sunset Drive 348", "Virginia Beach" , "0343 1234991" }); + m_contacts.append({ "Geoffrey Richards", "University Lane 54", "Trussville" , "0423 2144944" }); + m_contacts.append({ "Henrietta Chavez", "Via Volto San Luca 3", "Piobesi Torinese" , "0399 2826994" }); + m_contacts.append({ "Harvey Chandler", "North Squaw Creek 11", "Madisonville" , "0343 1244492" }); + m_contacts.append({ "Miguel Gomez", "Wild Rose Street 13", "Trussville" , "0343 9826996" }); + m_contacts.append({ "Norma Rodriguez", " Glen Eagles Street 53", "Buffalo" , "0241 5826596" }); + m_contacts.append({ "Shelia Ramirez", "East Miller Ave 68", "Pickerington" , "0346 4844556" }); + m_contacts.append({ "Stephanie Moss", "Piazza Trieste e Trento 77", "Roata Chiusani" , "0363 0510490" }); +} + +int ContactModel::rowCount(const QModelIndex &) const +{ + return m_contacts.count(); +} + +QVariant ContactModel::data(const QModelIndex &index, int role) const +{ + if (index.row() < rowCount()) + switch (role) { + case FullNameRole: return m_contacts.at(index.row()).fullName; + case AddressRole: return m_contacts.at(index.row()).address; + case CityRole: return m_contacts.at(index.row()).city; + case NumberRole: return m_contacts.at(index.row()).number; + default: return QVariant(); + } + return QVariant(); +} + +QHash ContactModel::roleNames() const +{ + static const QHash roles { + { FullNameRole, "fullName" }, + { AddressRole, "address" }, + { CityRole, "city" }, + { NumberRole, "number" } + }; + return roles; +} + +QVariantMap ContactModel::get(int row) const +{ + const Contact contact = m_contacts.value(row); + return { {"fullName", contact.fullName}, {"address", contact.address}, {"city", contact.city}, {"number", contact.number} }; +} + +void ContactModel::append(const QString &fullName, const QString &address, const QString &city, const QString &number) +{ + int row = 0; + while (row < m_contacts.count() && fullName > m_contacts.at(row).fullName) + ++row; + beginInsertRows(QModelIndex(), row, row); + m_contacts.insert(row, {fullName, address, city, number}); + endInsertRows(); +} + +void ContactModel::set(int row, const QString &fullName, const QString &address, const QString &city, const QString &number) +{ + if (row < 0 || row >= m_contacts.count()) + return; + + m_contacts.replace(row, { fullName, address, city, number }); + dataChanged(index(row, 0), index(row, 0), { FullNameRole, AddressRole, CityRole, NumberRole }); +} + +void ContactModel::remove(int row) +{ + if (row < 0 || row >= m_contacts.count()) + return; + + beginRemoveRows(QModelIndex(), row, row); + m_contacts.removeAt(row); + endRemoveRows(); +} diff --git a/examples/quickcontrols2/contactlist/contactmodel.h b/examples/quickcontrols2/contactlist/contactmodel.h new file mode 100644 index 00000000000..ec7ce35f166 --- /dev/null +++ b/examples/quickcontrols2/contactlist/contactmodel.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CONTACTMODEL_H +#define CONTACTMODEL_H + +#include + +class ContactModel : public QAbstractListModel +{ + Q_OBJECT + +public: + enum ContactRole { + FullNameRole = Qt::DisplayRole, + AddressRole = Qt::UserRole, + CityRole, + NumberRole + }; + Q_ENUM(ContactRole) + + ContactModel(QObject *parent = nullptr); + + int rowCount(const QModelIndex & = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QHash roleNames() const; + + Q_INVOKABLE QVariantMap get(int row) const; + Q_INVOKABLE void append(const QString &fullName, const QString &address, const QString &city, const QString &number); + Q_INVOKABLE void set(int row, const QString &fullName, const QString &address, const QString &city, const QString &number); + Q_INVOKABLE void remove(int row); + +private: + struct Contact { + QString fullName; + QString address; + QString city; + QString number; + }; + + QList m_contacts; +}; + +#endif // CONTACTMODEL_H diff --git a/examples/quickcontrols2/contactlist/designer/Backend/ContactModel.qml b/examples/quickcontrols2/contactlist/designer/Backend/ContactModel.qml new file mode 100644 index 00000000000..2bdeae2e708 --- /dev/null +++ b/examples/quickcontrols2/contactlist/designer/Backend/ContactModel.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +ListModel { + ListElement { + address: "Chapel St. 368" + city: "Knoxville" + number: "0311 1823993" + fullName: "Angel Hogan" + } + + ListElement { + address: "Annadale Lane 2" + city: "Clearwater" + number: "0368 1244494" + fullName: "Felicia Patton" + } + + ListElement { + address: "Windsor Drive 34" + city: "Riverdale" + number: "0368 1244494" + fullName: "Grant Crawford" + } + + ListElement { + address: "Sunset Drive 348" + city: "Virginia Beach" + number: "0351 7826892" + fullName: "Gretchen Little" + } + + ListElement { + address: "University Lane 54" + city: "Trussville" + number: "0399 2826994" + fullName: "Geoffrey Richards" + } +} diff --git a/examples/quickcontrols2/contactlist/designer/Backend/qmldir b/examples/quickcontrols2/contactlist/designer/Backend/qmldir new file mode 100644 index 00000000000..8e2037d4d79 --- /dev/null +++ b/examples/quickcontrols2/contactlist/designer/Backend/qmldir @@ -0,0 +1,2 @@ +module Backend +ContactModel 1.0 ContactModel.qml diff --git a/examples/quickcontrols2/contactlist/doc/images/qtquickcontrols2-contactlist.png b/examples/quickcontrols2/contactlist/doc/images/qtquickcontrols2-contactlist.png new file mode 100644 index 00000000000..9f1c306544f Binary files /dev/null and b/examples/quickcontrols2/contactlist/doc/images/qtquickcontrols2-contactlist.png differ diff --git a/examples/quickcontrols2/contactlist/doc/src/qtquickcontrols2-contactlist.qdoc b/examples/quickcontrols2/contactlist/doc/src/qtquickcontrols2-contactlist.qdoc new file mode 100644 index 00000000000..1c97617cf25 --- /dev/null +++ b/examples/quickcontrols2/contactlist/doc/src/qtquickcontrols2-contactlist.qdoc @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ +/*! + \example contactlist + \keyword Qt Quick Controls - Contact List + \title Qt Quick Controls - Contact List + \keyword Qt Quick Controls 2 - Contact List + \ingroup qtquickcontrols2-examples + \brief A QML app using Qt Quick Controls and a C++ class that implements + a simple contact list. + + The \e {Contact List Example} shows how to integrate a C++ backend in a way that + is compatible with Qt Quick Designer. + For the declarative parts of the UI, .ui.qml files are used that can be edited + visually in the Qt Quick Designer. + + \image qtquickcontrols2-contactlist.png + + \section1 C++ Backend + + The contact list application allows the user to add, edit, and remove contacts. + The actual implementation is done in C++ and exposed as a QAbstractListModel. + + The ContactModel C++ class is registered under a namespace and later + imported and instantiated by \e MainForm.ui.qml. For more information about registering C++ + classes as QML types, see \l {Defining QML Types from C++}. + + \code + #include + ... + qmlRegisterType("Backend", 1, 0, "ContactModel"); + ... + \endcode + + \section1 Designer Support + + In the designer subdirectory, we create a plugin that replaces the ContactModel + in Qt Quick Designer. For this to work we add the following line to \e contactlist.pro. + + \code + QML_DESIGNER_IMPORT_PATH = $$PWD/designer + \endcode + + Because Qt Quick Designer cannot instantiate the ContactModel C++ class, we define + a mockup using a ListModel. This ensures that the ListView using the model shows something + in Qt Quick Designer. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols2/contactlist/main.cpp b/examples/quickcontrols2/contactlist/main.cpp new file mode 100644 index 00000000000..44619663eca --- /dev/null +++ b/examples/quickcontrols2/contactlist/main.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "contactmodel.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType("Backend", 1, 0, "ContactModel"); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/contactlist.qml"))); + + return app.exec(); +} diff --git a/examples/quickcontrols2/flatstyle/CMakeLists.txt b/examples/quickcontrols2/flatstyle/CMakeLists.txt new file mode 100644 index 00000000000..008fda82b60 --- /dev/null +++ b/examples/quickcontrols2/flatstyle/CMakeLists.txt @@ -0,0 +1,64 @@ +# Generated from flatstyle.pro. + +cmake_minimum_required(VERSION 3.16) +project(flatstyle LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/flatstyle") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS QuickControls2) +find_package(Qt6 COMPONENTS Widgets) + +qt_add_executable(flatstyle + main.cpp +) +set_target_properties(flatstyle PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(flatstyle PUBLIC + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 + Qt::Widgets +) + + +# Resources: +set(qmake_immediate_resource_files + "MainForm.ui.qml" + "flatstyle.qml" + "imports/Flat/Button.qml" + "imports/Flat/CheckBox.qml" + "imports/Flat/Switch.qml" + "imports/Flat/qmldir" + "imports/Theme/Theme.qml" + "imports/Theme/qmldir" + "qtquickcontrols2.conf" +) + +qt6_add_resources(flatstyle "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + +install(TARGETS flatstyle + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/flatstyle/MainForm.ui.qml b/examples/quickcontrols2/flatstyle/MainForm.ui.qml new file mode 100644 index 00000000000..fcb17adc08d --- /dev/null +++ b/examples/quickcontrols2/flatstyle/MainForm.ui.qml @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Theme + +Item { + id: form + + width: 320 + height: 480 + property alias slider: slider + property alias checkBoxUnderline: checkBoxUnderline + property alias checkBoxBold: checkBoxBold + property alias sizeSwitch: sizeSwitch + property alias button: button + + Slider { + id: slider + width: 297 + height: 38 + stepSize: 1 + to: 18 + from: 10 + value: 14 + anchors.topMargin: Theme.baseSize + anchors.top: gridLayout.bottom + anchors.right: gridLayout.right + anchors.left: gridLayout.left + handle: Rectangle { + id: sliderHandle + x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width) + y: slider.topPadding + slider.availableHeight / 2 - height / 2 + implicitWidth: 26 + implicitHeight: 26 + radius: 13 + color: slider.pressed ? Theme.mainColorDarker : Theme.mainColor + border.color: Theme.gray + } + } + + GridLayout { + id: gridLayout + anchors.top: parent.top + anchors.topMargin: 64 + + anchors.horizontalCenter: parent.horizontalCenter + columnSpacing: Theme.baseSize * 0.5 + rowSpacing: Theme.baseSize * 0.5 + rows: 4 + columns: 2 + + Label { + text: qsTr("Toggle Size") + font: Theme.font + } + + Switch { + id: sizeSwitch + Layout.fillWidth: true + } + + CheckBox { + id: checkBoxBold + text: qsTr("Bold") + checked: true + Layout.fillWidth: true + } + + CheckBox { + id: checkBoxUnderline + text: qsTr("Underline") + Layout.fillWidth: true + } + + Rectangle { + id: rectangle + color: Theme.mainColor + Layout.fillWidth: true + Layout.columnSpan: 2 + Layout.preferredHeight: 38 + Layout.preferredWidth: 297 + } + + Label { + id: label + text: qsTr("Customization") + font: Theme.font + } + + Button { + id: button + text: qsTr("Change Color") + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + } + } +} diff --git a/examples/quickcontrols2/flatstyle/doc/images/qtquickcontrols2-flatstyle-creator.png b/examples/quickcontrols2/flatstyle/doc/images/qtquickcontrols2-flatstyle-creator.png new file mode 100644 index 00000000000..d77a7ffc4be Binary files /dev/null and b/examples/quickcontrols2/flatstyle/doc/images/qtquickcontrols2-flatstyle-creator.png differ diff --git a/examples/quickcontrols2/flatstyle/doc/images/qtquickcontrols2-flatstyle.png b/examples/quickcontrols2/flatstyle/doc/images/qtquickcontrols2-flatstyle.png new file mode 100644 index 00000000000..a43b4c39fa2 Binary files /dev/null and b/examples/quickcontrols2/flatstyle/doc/images/qtquickcontrols2-flatstyle.png differ diff --git a/examples/quickcontrols2/flatstyle/doc/src/qtquickcontrols2-flatstyle.qdoc b/examples/quickcontrols2/flatstyle/doc/src/qtquickcontrols2-flatstyle.qdoc new file mode 100644 index 00000000000..5da21ff45b6 --- /dev/null +++ b/examples/quickcontrols2/flatstyle/doc/src/qtquickcontrols2-flatstyle.qdoc @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example flatstyle + \keyword Qt Quick Controls - Flat Style + \title Qt Quick Controls - Flat Style + \keyword Qt Quick Controls 2 - Flat Style + \ingroup qtquickcontrols2-examples + \brief A QML app using Qt Quick Controls and a QML plugin + with customized controls. + + \e Flat Style shows how to integrate customized controls into Qt Quick Designer. + The example uses a pure QML plugin to define constants in a singleton. For the + declarative parts of the UI, \c .ui.qml files are used. These can be edited + visually in Qt Quick Designer. + + \borderedimage qtquickcontrols2-flatstyle.png + + \section1 QML Plugin + + The example contains a plugin called Theme. The plugin consists of a QML file + \c Theme.qml and a \c qmldir file. The plugin is located in the imports subdirectory + and added as a resource. + To ensure the plugin is found by QML, we add the import directory to the import + paths of the engine in \c main.cpp. + + \code + ... + engine.addImportPath(":/imports"); + ... + \endcode + + To ensure the code model and Qt Quick Designer can find the plugin, we add the following + line to \e flatstyle.pro. + + \code + QML_IMPORT_PATH = $$PWD/imports + \endcode + + All colors, font parameters, and size constants that are used in this example + are defined as properties in the singleton called \e Theme.qml. + Usually such attribute values are defined as constants as they are not suppose to change at run time. + In this example, we allow the user to change some attributes like the main color, the size parameter, + and some font parameters while the application is running. + + Defining these attribute values in a singleton makes it easy to maintain and change them. + This pattern makes it easy to implement theming. + + \section1 Implementing Custom Controls + + The plugin also contains a style for a couple of controls that implement a custom look and feel. + This style is located in \c Flat and is set as the style for the application in \c qtquickcontrols2.conf. + + The example uses the states of a Qt Quick Item to implement the different states of a control. + This has the advantage that we can define the custom look in Qt Quick Designer and we can easily + verify the different states of a control. + To edit the indicator of a switch in Qt Quick Designer we can open Switch.qml and then enter the implementation + of the indicator called \c switchHandle using the combo box on the top next to the combo box for the open documents. + + \borderedimage qtquickcontrols2-flatstyle-creator.png + + The application itself is just a simple form that allows the user to adjust a couple of parameters of the custom controls. + The user can choose another main color, set the font to bold or underline, and increase the size of the controls by + toggling a switch. + + \e MainForm.ui.qml is just the pure declarative definition of the form, while \e flatstyle.qml instantiates the form + and implements the logic. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols2/flatstyle/flatstyle.pro b/examples/quickcontrols2/flatstyle/flatstyle.pro new file mode 100644 index 00000000000..c430a30af46 --- /dev/null +++ b/examples/quickcontrols2/flatstyle/flatstyle.pro @@ -0,0 +1,23 @@ +TEMPLATE = app +TARGET = flatstyle + +QT += quick quickcontrols2 widgets + +SOURCES += main.cpp + +RESOURCES += \ + qtquickcontrols2.conf \ + flatstyle.qml \ + MainForm.ui.qml \ + imports/Flat/Button.qml \ + imports/Flat/CheckBox.qml \ + imports/Flat/qmldir \ + imports/Flat/Switch.qml \ + imports/Theme/Theme.qml \ + imports/Theme/qmldir + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = $$PWD/imports + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/flatstyle +INSTALLS += target diff --git a/examples/quickcontrols2/flatstyle/flatstyle.qml b/examples/quickcontrols2/flatstyle/flatstyle.qml new file mode 100644 index 00000000000..273cd3db27f --- /dev/null +++ b/examples/quickcontrols2/flatstyle/flatstyle.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import Qt.labs.platform +import Theme + +ApplicationWindow { + id: window + visible: true + minimumWidth: 360 + height: 480 + + title: qsTr("Flat Style") + + MainForm { + id: form + + anchors.fill: parent + button.onClicked: colorDialog.open() + + sizeSwitch.onCheckedChanged: Theme.baseSize = (sizeSwitch.checked ? Theme.largeSize : Theme.smallSize) + checkBoxBold.onCheckedChanged: Theme.font.bold = checkBoxBold.checked + checkBoxUnderline.onCheckedChanged: Theme.font.underline = checkBoxUnderline.checked + slider.onPositionChanged: Theme.font.pixelSize = slider.valueAt(slider.position) + } + + ColorDialog { + id: colorDialog + onCurrentColorChanged: Theme.mainColor = currentColor + } +} diff --git a/examples/quickcontrols2/flatstyle/flatstyle.qmlproject b/examples/quickcontrols2/flatstyle/flatstyle.qmlproject new file mode 100644 index 00000000000..80b42820ad7 --- /dev/null +++ b/examples/quickcontrols2/flatstyle/flatstyle.qmlproject @@ -0,0 +1,45 @@ +import QmlProject + +Project { + mainFile: "flatstyle.qml" + + /* Include .qml, .js, and image files from current directory and subdirectories */ + QmlFiles { + directory: "." + } + + JavaScriptFiles { + directory: "." + } + + ImageFiles { + directory: "." + } + + Files { + filter: "*.conf" + files: ["qtquickcontrols2.conf"] + } + + Files { + filter: "qmldir" + directory: "." + } + + Files { + filter: "*.ttf;*.otf" + } + + Environment { + QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf" + QT_AUTO_SCREEN_SCALE_FACTOR: "1" + } + + qt6Project: true + + /* List of plugin directories passed to QML runtime */ + importPaths: [ ".", "imports" ] + + /* Required for deployment */ + targetDirectory: "/opt/flatstyle" +} diff --git a/examples/quickcontrols2/flatstyle/imports/Flat/Button.qml b/examples/quickcontrols2/flatstyle/imports/Flat/Button.qml new file mode 100644 index 00000000000..f072038a1d4 --- /dev/null +++ b/examples/quickcontrols2/flatstyle/imports/Flat/Button.qml @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import Theme + +T.Button { + id: control + + font: Theme.font + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentItem.implicitHeight + topPadding + bottomPadding) + leftPadding: 4 + rightPadding: 4 + + background: Rectangle { + id: buttonBackground + implicitWidth: 100 + implicitHeight: 40 + opacity: enabled ? 1 : 0.3 + border.color: Theme.mainColor + border.width: 1 + radius: 2 + + states: [ + State { + name: "normal" + when: !control.down + PropertyChanges { + target: buttonBackground + } + }, + State { + name: "down" + when: control.down + PropertyChanges { + target: buttonBackground + border.color: Theme.mainColorDarker + } + } + ] + } + + contentItem: Text { + id: textItem + text: control.text + + font: control.font + opacity: enabled ? 1.0 : 0.3 + color: Theme.mainColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + + states: [ + State { + name: "normal" + when: !control.down + }, + State { + name: "down" + when: control.down + PropertyChanges { + target: textItem + color: Theme.mainColorDarker + } + } + ] + } +} + diff --git a/examples/quickcontrols2/flatstyle/imports/Flat/CheckBox.qml b/examples/quickcontrols2/flatstyle/imports/Flat/CheckBox.qml new file mode 100644 index 00000000000..014160330ee --- /dev/null +++ b/examples/quickcontrols2/flatstyle/imports/Flat/CheckBox.qml @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import Theme + +T.CheckBox { + id: control + + font: Theme.font + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(contentItem.implicitHeight, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + leftPadding: 4 + indicator: Rectangle { + id: checkboxHandle + implicitWidth: Theme.baseSize * 2.6 + implicitHeight: Theme.baseSize * 2.6 + x: control.leftPadding + anchors.verticalCenter: parent.verticalCenter + radius: 2 + border.color: Theme.mainColor + + Rectangle { + id: rectangle + width: Theme.baseSize * 1.4 + height: Theme.baseSize * 1.4 + x: Theme.baseSize * 0.6 + y: Theme.baseSize * 0.6 + radius: Theme.baseSize * 0.4 + visible: false + color: Theme.mainColor + } + + states: [ + State { + name: "unchecked" + when: !control.checked && !control.down + }, + State { + name: "checked" + when: control.checked && !control.down + + PropertyChanges { + target: rectangle + visible: true + } + }, + State { + name: "unchecked_down" + when: !control.checked && control.down + + PropertyChanges { + target: rectangle + color: Theme.mainColorDarker + } + + PropertyChanges { + target: checkboxHandle + border.color: Theme.mainColorDarker + } + }, + State { + name: "checked_down" + extend: "unchecked_down" + when: control.checked && control.down + + PropertyChanges { + target: rectangle + visible: true + } + } + ] + } + + background: Rectangle { + implicitWidth: 140 + implicitHeight: Theme.baseSize * 3.8 + color: Theme.lightGray + border.color: Theme.gray + } + + contentItem: Text { + leftPadding: control.indicator.width + 4 + + text: control.text + font: control.font + color: Theme.dark + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } +} + diff --git a/examples/quickcontrols2/flatstyle/imports/Flat/Switch.qml b/examples/quickcontrols2/flatstyle/imports/Flat/Switch.qml new file mode 100644 index 00000000000..1f3bd3251e9 --- /dev/null +++ b/examples/quickcontrols2/flatstyle/imports/Flat/Switch.qml @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import Theme + +T.Switch { + id: control + + implicitWidth: indicator.implicitWidth + implicitHeight: background.implicitHeight + + background: Rectangle { + implicitWidth: 140 + implicitHeight: Theme.baseSize * 3.8 + color: Theme.lightGray + border.color: Theme.gray + } + + leftPadding: 4 + + indicator: Rectangle { + id: switchHandle + implicitWidth: Theme.baseSize * 4.8 + implicitHeight: Theme.baseSize * 2.6 + x: control.leftPadding + anchors.verticalCenter: parent.verticalCenter + radius: Theme.baseSize * 1.3 + color: Theme.light + border.color: Theme.lightGray + + Rectangle { + id: rectangle + + width: Theme.baseSize * 2.6 + height: Theme.baseSize * 2.6 + radius: Theme.baseSize * 1.3 + color: Theme.light + border.color: Theme.gray + } + + states: [ + State { + name: "off" + when: !control.checked && !control.down + }, + State { + name: "on" + when: control.checked && !control.down + + PropertyChanges { + target: switchHandle + color: Theme.mainColor + border.color: Theme.mainColor + } + + PropertyChanges { + target: rectangle + x: parent.width - width + + } + }, + State { + name: "off_down" + when: !control.checked && control.down + + PropertyChanges { + target: rectangle + color: Theme.light + } + + }, + State { + name: "on_down" + extend: "off_down" + when: control.checked && control.down + + PropertyChanges { + target: rectangle + x: parent.width - width + color: Theme.light + } + + PropertyChanges { + target: switchHandle + color: Theme.mainColorDarker + border.color: Theme.mainColorDarker + } + } + ] + } +} diff --git a/examples/quickcontrols2/flatstyle/imports/Flat/qmldir b/examples/quickcontrols2/flatstyle/imports/Flat/qmldir new file mode 100644 index 00000000000..451a865969b --- /dev/null +++ b/examples/quickcontrols2/flatstyle/imports/Flat/qmldir @@ -0,0 +1,5 @@ +module Flat + +Button 1.0 Button.qml +CheckBox 1.0 CheckBox.qml +Switch 1.0 Switch.qml diff --git a/examples/quickcontrols2/flatstyle/imports/Theme/Theme.qml b/examples/quickcontrols2/flatstyle/imports/Theme/Theme.qml new file mode 100644 index 00000000000..4529fd547a3 --- /dev/null +++ b/examples/quickcontrols2/flatstyle/imports/Theme/Theme.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +pragma Singleton + +import QtQuick + +QtObject { + readonly property color gray: "#b2b1b1" + readonly property color lightGray: "#dddddd" + readonly property color light: "#ffffff" + readonly property color blue: "#2d548b" + property color mainColor: "#17a81a" + readonly property color dark: "#222222" + readonly property color mainColorDarker: Qt.darker(mainColor, 1.5) + + property int baseSize: 10 + + readonly property int smallSize: 10 + readonly property int largeSize: 16 + + property font font + font.bold: true + font.underline: false + font.pixelSize: 14 + font.family: "arial" +} diff --git a/examples/quickcontrols2/flatstyle/imports/Theme/qmldir b/examples/quickcontrols2/flatstyle/imports/Theme/qmldir new file mode 100644 index 00000000000..4a58c13a907 --- /dev/null +++ b/examples/quickcontrols2/flatstyle/imports/Theme/qmldir @@ -0,0 +1,2 @@ +module Theme +singleton Theme 1.0 Theme.qml diff --git a/examples/quickcontrols2/flatstyle/main.cpp b/examples/quickcontrols2/flatstyle/main.cpp new file mode 100644 index 00000000000..ccc12492702 --- /dev/null +++ b/examples/quickcontrols2/flatstyle/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.addImportPath(":/imports"); + engine.load(QUrl(QStringLiteral("qrc:/flatstyle.qml"))); + + return app.exec(); +} diff --git a/examples/quickcontrols2/flatstyle/qtquickcontrols2.conf b/examples/quickcontrols2/flatstyle/qtquickcontrols2.conf new file mode 100644 index 00000000000..9cd59e5aa07 --- /dev/null +++ b/examples/quickcontrols2/flatstyle/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Flat diff --git a/examples/quickcontrols2/gallery/+Material/ToolBar.qml b/examples/quickcontrols2/gallery/+Material/ToolBar.qml new file mode 100644 index 00000000000..18ca5c82fe0 --- /dev/null +++ b/examples/quickcontrols2/gallery/+Material/ToolBar.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls.Material + +ToolBar { + Material.foreground: "white" +} diff --git a/examples/quickcontrols2/gallery/CMakeLists.txt b/examples/quickcontrols2/gallery/CMakeLists.txt new file mode 100644 index 00000000000..b3270205fa9 --- /dev/null +++ b/examples/quickcontrols2/gallery/CMakeLists.txt @@ -0,0 +1,116 @@ +# Generated from gallery.pro. + +cmake_minimum_required(VERSION 3.16) +project(gallery_controls2 LANGUAGES CXX) # special case + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/gallery") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS QuickControls2) + +qt_add_executable(gallery_controls2 # special case + gallery.cpp +) +set_target_properties(gallery_controls2 PROPERTIES # special case + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(gallery_controls2 PUBLIC # special case + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) +# special case begin +if(UNIX AND NOT APPLE AND CMAKE_CROSSCOMPILING) + find_package(Qt6 COMPONENTS QuickTemplates2) + # Work around QTBUG-86533 + target_link_libraries(gallery_controls2 PRIVATE Qt::QuickTemplates2) +endif() +# special case end + +# Resources: +set(qmake_immediate_resource_files + "+Material/ToolBar.qml" + "ToolBar.qml" + "gallery.qml" + "icons/gallery/20x20/back.png" + "icons/gallery/20x20/drawer.png" + "icons/gallery/20x20/menu.png" + "icons/gallery/20x20@2/back.png" + "icons/gallery/20x20@2/drawer.png" + "icons/gallery/20x20@2/menu.png" + "icons/gallery/20x20@3/back.png" + "icons/gallery/20x20@3/drawer.png" + "icons/gallery/20x20@3/menu.png" + "icons/gallery/20x20@4/back.png" + "icons/gallery/20x20@4/drawer.png" + "icons/gallery/20x20@4/menu.png" + "icons/gallery/index.theme" + "images/arrow.png" + "images/arrow@2x.png" + "images/arrow@3x.png" + "images/arrow@4x.png" + "images/arrows.png" + "images/arrows@2x.png" + "images/arrows@3x.png" + "images/arrows@4x.png" + "images/qt-logo.png" + "images/qt-logo@2x.png" + "images/qt-logo@3x.png" + "images/qt-logo@4x.png" + "pages/BusyIndicatorPage.qml" + "pages/ButtonPage.qml" + "pages/CheckBoxPage.qml" + "pages/ComboBoxPage.qml" + "pages/DelayButtonPage.qml" + "pages/DelegatePage.qml" + "pages/DialPage.qml" + "pages/DialogPage.qml" + "pages/FramePage.qml" + "pages/GroupBoxPage.qml" + "pages/PageIndicatorPage.qml" + "pages/ProgressBarPage.qml" + "pages/RadioButtonPage.qml" + "pages/RangeSliderPage.qml" + "pages/ScrollBarPage.qml" + "pages/ScrollIndicatorPage.qml" + "pages/ScrollablePage.qml" + "pages/SliderPage.qml" + "pages/SpinBoxPage.qml" + "pages/StackViewPage.qml" + "pages/SwipeViewPage.qml" + "pages/SwitchPage.qml" + "pages/TabBarPage.qml" + "pages/TextAreaPage.qml" + "pages/TextFieldPage.qml" + "pages/ToolTipPage.qml" + "pages/TumblerPage.qml" + "qmldir" + "qtquickcontrols2.conf" +) + +qt6_add_resources(gallery_controls2 "qmake_immediate" # special case + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + +install(TARGETS gallery_controls2 # special case + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/gallery/ToolBar.qml b/examples/quickcontrols2/gallery/ToolBar.qml new file mode 100644 index 00000000000..9f1d1f9e7c6 --- /dev/null +++ b/examples/quickcontrols2/gallery/ToolBar.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls + +ToolBar {} diff --git a/examples/quickcontrols2/gallery/doc/images/qtquickcontrols2-gallery-drawer.png b/examples/quickcontrols2/gallery/doc/images/qtquickcontrols2-gallery-drawer.png new file mode 100644 index 00000000000..0df43fbc4b3 Binary files /dev/null and b/examples/quickcontrols2/gallery/doc/images/qtquickcontrols2-gallery-drawer.png differ diff --git a/examples/quickcontrols2/gallery/doc/images/qtquickcontrols2-gallery-menu.png b/examples/quickcontrols2/gallery/doc/images/qtquickcontrols2-gallery-menu.png new file mode 100644 index 00000000000..3bdaae942a4 Binary files /dev/null and b/examples/quickcontrols2/gallery/doc/images/qtquickcontrols2-gallery-menu.png differ diff --git a/examples/quickcontrols2/gallery/doc/images/qtquickcontrols2-gallery-welcome.png b/examples/quickcontrols2/gallery/doc/images/qtquickcontrols2-gallery-welcome.png new file mode 100644 index 00000000000..ded30381d2f Binary files /dev/null and b/examples/quickcontrols2/gallery/doc/images/qtquickcontrols2-gallery-welcome.png differ diff --git a/examples/quickcontrols2/gallery/doc/src/qtquickcontrols2-gallery.qdoc b/examples/quickcontrols2/gallery/doc/src/qtquickcontrols2-gallery.qdoc new file mode 100644 index 00000000000..174960433c4 --- /dev/null +++ b/examples/quickcontrols2/gallery/doc/src/qtquickcontrols2-gallery.qdoc @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example gallery + \keyword Qt Quick Controls - Gallery + \title Qt Quick Controls - Gallery + \keyword Qt Quick Controls 2 - Gallery + \ingroup qtquickcontrols2-examples + \brief A gallery of controls. + + \raw HTML +
+ +
+ \endraw + \image qtquickcontrols2-gallery-welcome.png + \caption Welcome Screen + \raw HTML + + \endraw + \image qtquickcontrols2-gallery-drawer.png + \caption Side Drawer + \raw HTML + + \endraw + \image qtquickcontrols2-gallery-menu.png + \caption Options Menu + \raw HTML +
+ \endraw + + The gallery example is a simple application with a drawer menu that contains + all the \l {Qt Quick Controls}. Each menu item opens a page that shows the + graphical appearance of a control, allows you to interact with the control, + and explains in which circumstances it is handy to use this control. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols2/gallery/gallery.cpp b/examples/quickcontrols2/gallery/gallery.cpp new file mode 100644 index 00000000000..1ea5cf9840f --- /dev/null +++ b/examples/quickcontrols2/gallery/gallery.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication::setApplicationName("Gallery"); + QGuiApplication::setOrganizationName("QtProject"); + + QGuiApplication app(argc, argv); + + QIcon::setThemeName("gallery"); + + QSettings settings; + if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) + QQuickStyle::setStyle(settings.value("style").toString()); + + // If this is the first time we're running the application, + // we need to set a style in the settings so that the QML + // can find it in the list of built-in styles. + const QString styleInSettings = settings.value("style").toString(); + if (styleInSettings.isEmpty()) + settings.setValue(QLatin1String("style"), QQuickStyle::name()); + + QQmlApplicationEngine engine; + + QStringList builtInStyles = { QLatin1String("Basic"), QLatin1String("Fusion"), + QLatin1String("Imagine"), QLatin1String("Material"), QLatin1String("Universal") }; +#if defined(Q_OS_MACOS) + builtInStyles << QLatin1String("macOS"); +#elif defined(Q_OS_WINDOWS) + builtInStyles << QLatin1String("Windows"); +#endif + + engine.setInitialProperties({{ "builtInStyles", builtInStyles }}); + engine.load(QUrl("qrc:/gallery.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols2/gallery/gallery.pro b/examples/quickcontrols2/gallery/gallery.pro new file mode 100644 index 00000000000..e1ac462a7c6 --- /dev/null +++ b/examples/quickcontrols2/gallery/gallery.pro @@ -0,0 +1,68 @@ +TEMPLATE = app +TARGET = gallery +QT += quick quickcontrols2 + +SOURCES += \ + gallery.cpp + +RESOURCES += \ + gallery.qml \ + pages/BusyIndicatorPage.qml \ + pages/ButtonPage.qml \ + pages/CheckBoxPage.qml \ + pages/ComboBoxPage.qml \ + pages/DelayButtonPage.qml \ + pages/DelegatePage.qml \ + pages/DialogPage.qml \ + pages/DialPage.qml \ + pages/FramePage.qml \ + pages/GroupBoxPage.qml \ + pages/PageIndicatorPage.qml \ + pages/ProgressBarPage.qml \ + pages/RadioButtonPage.qml \ + pages/RangeSliderPage.qml \ + pages/ScrollablePage.qml \ + pages/ScrollBarPage.qml \ + pages/ScrollIndicatorPage.qml \ + pages/SliderPage.qml \ + pages/SpinBoxPage.qml \ + pages/StackViewPage.qml \ + pages/SwipeViewPage.qml \ + pages/SwitchPage.qml \ + pages/TabBarPage.qml \ + pages/TextAreaPage.qml \ + pages/TextFieldPage.qml \ + pages/ToolTipPage.qml \ + pages/TumblerPage.qml \ + qmldir \ + qtquickcontrols2.conf \ + icons/gallery/index.theme \ + icons/gallery/20x20/back.png \ + icons/gallery/20x20/drawer.png \ + icons/gallery/20x20/menu.png \ + icons/gallery/20x20@2/back.png \ + icons/gallery/20x20@2/drawer.png \ + icons/gallery/20x20@2/menu.png \ + icons/gallery/20x20@3/back.png \ + icons/gallery/20x20@3/drawer.png \ + icons/gallery/20x20@3/menu.png \ + icons/gallery/20x20@4/back.png \ + icons/gallery/20x20@4/drawer.png \ + icons/gallery/20x20@4/menu.png \ + images/arrow.png \ + images/arrow@2x.png \ + images/arrow@3x.png \ + images/arrow@4x.png \ + images/arrows.png \ + images/arrows@2x.png \ + images/arrows@3x.png \ + images/arrows@4x.png \ + images/qt-logo.png \ + images/qt-logo@2x.png \ + images/qt-logo@3x.png \ + images/qt-logo@4x.png \ + ToolBar.qml \ + +Material/ToolBar.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/gallery +INSTALLS += target diff --git a/examples/quickcontrols2/gallery/gallery.qml b/examples/quickcontrols2/gallery/gallery.qml new file mode 100644 index 00000000000..58d1b49ece5 --- /dev/null +++ b/examples/quickcontrols2/gallery/gallery.qml @@ -0,0 +1,342 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Qt.labs.settings + +import "." as App + +ApplicationWindow { + id: window + width: 360 + height: 520 + visible: true + title: "Qt Quick Controls" + + function help() { + let displayingControl = listView.currentIndex !== -1 + let currentControlName = displayingControl + ? listView.model.get(listView.currentIndex).title.toLowerCase() : "" + let url = "https://doc.qt.io/qt-5/" + + (displayingControl + ? "qml-qtquick-controls2-" + currentControlName + ".html" + : "qtquick-controls2-qmlmodule.html"); + Qt.openUrlExternally(url) + } + + required property var builtInStyles + + Settings { + id: settings + property string style + } + + Shortcut { + sequences: ["Esc", "Back"] + enabled: stackView.depth > 1 + onActivated: navigateBackAction.trigger() + } + + Shortcut { + sequence: StandardKey.HelpContents + onActivated: help() + } + + Action { + id: navigateBackAction + icon.name: stackView.depth > 1 ? "back" : "drawer" + onTriggered: { + if (stackView.depth > 1) { + stackView.pop() + listView.currentIndex = -1 + } else { + drawer.open() + } + } + } + + Shortcut { + sequence: "Menu" + onActivated: optionsMenuAction.trigger() + } + + Action { + id: optionsMenuAction + icon.name: "menu" + onTriggered: optionsMenu.open() + } + + header: App.ToolBar { + RowLayout { + spacing: 20 + anchors.fill: parent + + ToolButton { + action: navigateBackAction + } + + Label { + id: titleLabel + text: listView.currentItem ? listView.currentItem.text : "Gallery" + font.pixelSize: 20 + elide: Label.ElideRight + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + Layout.fillWidth: true + } + + ToolButton { + action: optionsMenuAction + + Menu { + id: optionsMenu + x: parent.width - width + transformOrigin: Menu.TopRight + + Action { + text: "Settings" + onTriggered: settingsDialog.open() + } + Action { + text: "Help" + onTriggered: help() + } + Action { + text: "About" + onTriggered: aboutDialog.open() + } + } + } + } + } + + Drawer { + id: drawer + width: Math.min(window.width, window.height) / 3 * 2 + height: window.height + interactive: stackView.depth === 1 + + ListView { + id: listView + + focus: true + currentIndex: -1 + anchors.fill: parent + + delegate: ItemDelegate { + width: listView.width + text: model.title + highlighted: ListView.isCurrentItem + onClicked: { + listView.currentIndex = index + stackView.push(model.source) + drawer.close() + } + } + + model: ListModel { + ListElement { title: "BusyIndicator"; source: "qrc:/pages/BusyIndicatorPage.qml" } + ListElement { title: "Button"; source: "qrc:/pages/ButtonPage.qml" } + ListElement { title: "CheckBox"; source: "qrc:/pages/CheckBoxPage.qml" } + ListElement { title: "ComboBox"; source: "qrc:/pages/ComboBoxPage.qml" } + ListElement { title: "DelayButton"; source: "qrc:/pages/DelayButtonPage.qml" } + ListElement { title: "Dial"; source: "qrc:/pages/DialPage.qml" } + ListElement { title: "Dialog"; source: "qrc:/pages/DialogPage.qml" } + ListElement { title: "Delegates"; source: "qrc:/pages/DelegatePage.qml" } + ListElement { title: "Frame"; source: "qrc:/pages/FramePage.qml" } + ListElement { title: "GroupBox"; source: "qrc:/pages/GroupBoxPage.qml" } + ListElement { title: "PageIndicator"; source: "qrc:/pages/PageIndicatorPage.qml" } + ListElement { title: "ProgressBar"; source: "qrc:/pages/ProgressBarPage.qml" } + ListElement { title: "RadioButton"; source: "qrc:/pages/RadioButtonPage.qml" } + ListElement { title: "RangeSlider"; source: "qrc:/pages/RangeSliderPage.qml" } + ListElement { title: "ScrollBar"; source: "qrc:/pages/ScrollBarPage.qml" } + ListElement { title: "ScrollIndicator"; source: "qrc:/pages/ScrollIndicatorPage.qml" } + ListElement { title: "Slider"; source: "qrc:/pages/SliderPage.qml" } + ListElement { title: "SpinBox"; source: "qrc:/pages/SpinBoxPage.qml" } + ListElement { title: "StackView"; source: "qrc:/pages/StackViewPage.qml" } + ListElement { title: "SwipeView"; source: "qrc:/pages/SwipeViewPage.qml" } + ListElement { title: "Switch"; source: "qrc:/pages/SwitchPage.qml" } + ListElement { title: "TabBar"; source: "qrc:/pages/TabBarPage.qml" } + ListElement { title: "TextArea"; source: "qrc:/pages/TextAreaPage.qml" } + ListElement { title: "TextField"; source: "qrc:/pages/TextFieldPage.qml" } + ListElement { title: "ToolTip"; source: "qrc:/pages/ToolTipPage.qml" } + ListElement { title: "Tumbler"; source: "qrc:/pages/TumblerPage.qml" } + } + + ScrollIndicator.vertical: ScrollIndicator { } + } + } + + StackView { + id: stackView + anchors.fill: parent + + initialItem: Pane { + id: pane + + Image { + id: logo + width: pane.availableWidth / 2 + height: pane.availableHeight / 2 + anchors.centerIn: parent + anchors.verticalCenterOffset: -50 + fillMode: Image.PreserveAspectFit + source: "images/qt-logo.png" + } + + Label { + text: "Qt Quick Controls provides a set of controls that can be used to build complete interfaces in Qt Quick." + anchors.margins: 20 + anchors.top: logo.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: arrow.top + horizontalAlignment: Label.AlignHCenter + verticalAlignment: Label.AlignVCenter + wrapMode: Label.Wrap + } + + Image { + id: arrow + source: "images/arrow.png" + anchors.left: parent.left + anchors.bottom: parent.bottom + } + } + } + + Dialog { + id: settingsDialog + x: Math.round((window.width - width) / 2) + y: Math.round(window.height / 6) + width: Math.round(Math.min(window.width, window.height) / 3 * 2) + modal: true + focus: true + title: "Settings" + + standardButtons: Dialog.Ok | Dialog.Cancel + onAccepted: { + settings.style = styleBox.displayText + settingsDialog.close() + } + onRejected: { + styleBox.currentIndex = styleBox.styleIndex + settingsDialog.close() + } + + contentItem: ColumnLayout { + id: settingsColumn + spacing: 20 + + RowLayout { + spacing: 10 + + Label { + text: "Style:" + } + + ComboBox { + id: styleBox + property int styleIndex: -1 + model: window.builtInStyles + Component.onCompleted: { + styleIndex = find(settings.style, Qt.MatchFixedString) + if (styleIndex !== -1) + currentIndex = styleIndex + } + Layout.fillWidth: true + } + } + + Label { + text: "Restart required" + color: "#e41e25" + opacity: styleBox.currentIndex !== styleBox.styleIndex ? 1.0 : 0.0 + horizontalAlignment: Label.AlignHCenter + verticalAlignment: Label.AlignVCenter + Layout.fillWidth: true + Layout.fillHeight: true + } + } + } + + Dialog { + id: aboutDialog + modal: true + focus: true + title: "About" + x: (window.width - width) / 2 + y: window.height / 6 + width: Math.min(window.width, window.height) / 3 * 2 + contentHeight: aboutColumn.height + + Column { + id: aboutColumn + spacing: 20 + + Label { + width: aboutDialog.availableWidth + text: "The Qt Quick Controls module delivers the next generation user interface controls based on Qt Quick." + wrapMode: Label.Wrap + font.pixelSize: 12 + } + + Label { + width: aboutDialog.availableWidth + text: "In comparison to Qt Quick Controls 1, Qt Quick Controls " + + "are an order of magnitude simpler, lighter, and faster." + wrapMode: Label.Wrap + font.pixelSize: 12 + } + } + } +} diff --git a/examples/quickcontrols2/gallery/icons/gallery/20x20/back.png b/examples/quickcontrols2/gallery/icons/gallery/20x20/back.png new file mode 100644 index 00000000000..1f89ee058ca Binary files /dev/null and b/examples/quickcontrols2/gallery/icons/gallery/20x20/back.png differ diff --git a/examples/quickcontrols2/gallery/icons/gallery/20x20/drawer.png b/examples/quickcontrols2/gallery/icons/gallery/20x20/drawer.png new file mode 100644 index 00000000000..1e974efae87 Binary files /dev/null and b/examples/quickcontrols2/gallery/icons/gallery/20x20/drawer.png differ diff --git a/examples/quickcontrols2/gallery/icons/gallery/20x20/menu.png b/examples/quickcontrols2/gallery/icons/gallery/20x20/menu.png new file mode 100644 index 00000000000..a10473d9e1e Binary files /dev/null and b/examples/quickcontrols2/gallery/icons/gallery/20x20/menu.png differ diff --git a/examples/quickcontrols2/gallery/icons/gallery/20x20@2/back.png b/examples/quickcontrols2/gallery/icons/gallery/20x20@2/back.png new file mode 100644 index 00000000000..88e290b132f Binary files /dev/null and b/examples/quickcontrols2/gallery/icons/gallery/20x20@2/back.png differ diff --git a/examples/quickcontrols2/gallery/icons/gallery/20x20@2/drawer.png b/examples/quickcontrols2/gallery/icons/gallery/20x20@2/drawer.png new file mode 100644 index 00000000000..eba3b6cccf6 Binary files /dev/null and b/examples/quickcontrols2/gallery/icons/gallery/20x20@2/drawer.png differ diff --git a/examples/quickcontrols2/gallery/icons/gallery/20x20@2/menu.png b/examples/quickcontrols2/gallery/icons/gallery/20x20@2/menu.png new file mode 100644 index 00000000000..649c2a08c69 Binary files /dev/null and b/examples/quickcontrols2/gallery/icons/gallery/20x20@2/menu.png differ diff --git a/examples/quickcontrols2/gallery/icons/gallery/20x20@3/back.png b/examples/quickcontrols2/gallery/icons/gallery/20x20@3/back.png new file mode 100644 index 00000000000..4402c7d30b8 Binary files /dev/null and b/examples/quickcontrols2/gallery/icons/gallery/20x20@3/back.png differ diff --git a/examples/quickcontrols2/gallery/icons/gallery/20x20@3/drawer.png b/examples/quickcontrols2/gallery/icons/gallery/20x20@3/drawer.png new file mode 100644 index 00000000000..3584ed6d8b1 Binary files /dev/null and b/examples/quickcontrols2/gallery/icons/gallery/20x20@3/drawer.png differ diff --git a/examples/quickcontrols2/gallery/icons/gallery/20x20@3/menu.png b/examples/quickcontrols2/gallery/icons/gallery/20x20@3/menu.png new file mode 100644 index 00000000000..9554b6952b3 Binary files /dev/null and b/examples/quickcontrols2/gallery/icons/gallery/20x20@3/menu.png differ diff --git a/examples/quickcontrols2/gallery/icons/gallery/20x20@4/back.png b/examples/quickcontrols2/gallery/icons/gallery/20x20@4/back.png new file mode 100644 index 00000000000..9982478c189 Binary files /dev/null and b/examples/quickcontrols2/gallery/icons/gallery/20x20@4/back.png differ diff --git a/examples/quickcontrols2/gallery/icons/gallery/20x20@4/drawer.png b/examples/quickcontrols2/gallery/icons/gallery/20x20@4/drawer.png new file mode 100644 index 00000000000..60d93aff7b0 Binary files /dev/null and b/examples/quickcontrols2/gallery/icons/gallery/20x20@4/drawer.png differ diff --git a/examples/quickcontrols2/gallery/icons/gallery/20x20@4/menu.png b/examples/quickcontrols2/gallery/icons/gallery/20x20@4/menu.png new file mode 100644 index 00000000000..187c171cdef Binary files /dev/null and b/examples/quickcontrols2/gallery/icons/gallery/20x20@4/menu.png differ diff --git a/examples/quickcontrols2/gallery/icons/gallery/index.theme b/examples/quickcontrols2/gallery/icons/gallery/index.theme new file mode 100644 index 00000000000..a1bcd5e03cd --- /dev/null +++ b/examples/quickcontrols2/gallery/icons/gallery/index.theme @@ -0,0 +1,24 @@ +[Icon Theme] +Name=Gallery +Comment=Qt Quick Controls 2 Gallery Example Icon Theme + +Directories=20x20,20x20@2,20x20@3,20x20@4 + +[20x20] +Size=20 +Type=Fixed + +[20x20@2] +Size=20 +Scale=2 +Type=Fixed + +[20x20@3] +Size=20 +Scale=3 +Type=Fixed + +[20x20@4] +Size=20 +Scale=4 +Type=Fixed diff --git a/examples/quickcontrols2/gallery/images/arrow.png b/examples/quickcontrols2/gallery/images/arrow.png new file mode 100644 index 00000000000..9835108eb9e Binary files /dev/null and b/examples/quickcontrols2/gallery/images/arrow.png differ diff --git a/examples/quickcontrols2/gallery/images/arrow@2x.png b/examples/quickcontrols2/gallery/images/arrow@2x.png new file mode 100644 index 00000000000..a5187d48cf7 Binary files /dev/null and b/examples/quickcontrols2/gallery/images/arrow@2x.png differ diff --git a/examples/quickcontrols2/gallery/images/arrow@3x.png b/examples/quickcontrols2/gallery/images/arrow@3x.png new file mode 100644 index 00000000000..a512f648c86 Binary files /dev/null and b/examples/quickcontrols2/gallery/images/arrow@3x.png differ diff --git a/examples/quickcontrols2/gallery/images/arrow@4x.png b/examples/quickcontrols2/gallery/images/arrow@4x.png new file mode 100644 index 00000000000..fd893ebb0d4 Binary files /dev/null and b/examples/quickcontrols2/gallery/images/arrow@4x.png differ diff --git a/examples/quickcontrols2/gallery/images/arrows.png b/examples/quickcontrols2/gallery/images/arrows.png new file mode 100644 index 00000000000..3a4cc9b95f5 Binary files /dev/null and b/examples/quickcontrols2/gallery/images/arrows.png differ diff --git a/examples/quickcontrols2/gallery/images/arrows@2x.png b/examples/quickcontrols2/gallery/images/arrows@2x.png new file mode 100644 index 00000000000..8c80a2b45be Binary files /dev/null and b/examples/quickcontrols2/gallery/images/arrows@2x.png differ diff --git a/examples/quickcontrols2/gallery/images/arrows@3x.png b/examples/quickcontrols2/gallery/images/arrows@3x.png new file mode 100644 index 00000000000..22f23cefb98 Binary files /dev/null and b/examples/quickcontrols2/gallery/images/arrows@3x.png differ diff --git a/examples/quickcontrols2/gallery/images/arrows@4x.png b/examples/quickcontrols2/gallery/images/arrows@4x.png new file mode 100644 index 00000000000..6d1afeef5c4 Binary files /dev/null and b/examples/quickcontrols2/gallery/images/arrows@4x.png differ diff --git a/examples/quickcontrols2/gallery/images/qt-logo.png b/examples/quickcontrols2/gallery/images/qt-logo.png new file mode 100644 index 00000000000..dff7729515a Binary files /dev/null and b/examples/quickcontrols2/gallery/images/qt-logo.png differ diff --git a/examples/quickcontrols2/gallery/images/qt-logo@2x.png b/examples/quickcontrols2/gallery/images/qt-logo@2x.png new file mode 100644 index 00000000000..dbd73aab776 Binary files /dev/null and b/examples/quickcontrols2/gallery/images/qt-logo@2x.png differ diff --git a/examples/quickcontrols2/gallery/images/qt-logo@3x.png b/examples/quickcontrols2/gallery/images/qt-logo@3x.png new file mode 100644 index 00000000000..68e763b597e Binary files /dev/null and b/examples/quickcontrols2/gallery/images/qt-logo@3x.png differ diff --git a/examples/quickcontrols2/gallery/images/qt-logo@4x.png b/examples/quickcontrols2/gallery/images/qt-logo@4x.png new file mode 100644 index 00000000000..08fd882572b Binary files /dev/null and b/examples/quickcontrols2/gallery/images/qt-logo@4x.png differ diff --git a/examples/quickcontrols2/gallery/pages/BusyIndicatorPage.qml b/examples/quickcontrols2/gallery/pages/BusyIndicatorPage.qml new file mode 100644 index 00000000000..867f5d2886a --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/BusyIndicatorPage.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "BusyIndicator is used to indicate activity while content is being loaded," + + " or when the UI is blocked waiting for a resource to become available." + } + + BusyIndicator { + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/ButtonPage.qml b/examples/quickcontrols2/gallery/pages/ButtonPage.qml new file mode 100644 index 00000000000..38404570052 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/ButtonPage.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Button presents a push-button that can be pushed or clicked by the user. " + + "Buttons are normally used to perform an action, or to answer a question." + } + + ColumnLayout { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + Button { + text: "First" + Layout.fillWidth: true + } + Button { + id: button + text: "Second" + highlighted: true + Layout.fillWidth: true + } + Button { + text: "Third" + enabled: false + Layout.fillWidth: true + } + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/CheckBoxPage.qml b/examples/quickcontrols2/gallery/pages/CheckBoxPage.qml new file mode 100644 index 00000000000..39ea53ca6cb --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/CheckBoxPage.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "CheckBox presents an option button that can be toggled on or off. " + + "Check boxes are typically used to select one or more options from a set of options." + } + + Column { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + CheckBox { + text: "First" + checked: true + } + CheckBox { + text: "Second" + } + CheckBox { + text: "Third" + checked: true + enabled: false + } + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/ComboBoxPage.qml b/examples/quickcontrols2/gallery/pages/ComboBoxPage.qml new file mode 100644 index 00000000000..04bb634ab78 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/ComboBoxPage.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ComboBox is a combined button and popup list. It presents " + + "a list of options to the user that occupies minimal screen space." + } + + ComboBox { + model: ["First", "Second", "Third"] + anchors.horizontalCenter: parent.horizontalCenter + } + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ComboBox can be made \l editable. An editable combo box auto-" + + "completes its text based on what is available in the model." + } + + ComboBox { + editable: true + model: ListModel { + id: model + ListElement { text: "Banana" } + ListElement { text: "Apple" } + ListElement { text: "Coconut" } + } + onAccepted: { + if (find(editText) === -1) + model.append({text: editText}) + } + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/DelayButtonPage.qml b/examples/quickcontrols2/gallery/pages/DelayButtonPage.qml new file mode 100644 index 00000000000..b0cc30c2dc3 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/DelayButtonPage.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "DelayButton is a checkable button that incorporates a delay before the " + + "button is activated. This delay prevents accidental presses." + } + + DelayButton { + text: "DelayButton" + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/DelegatePage.qml b/examples/quickcontrols2/gallery/pages/DelegatePage.qml new file mode 100644 index 00000000000..116762154d6 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/DelegatePage.qml @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +Pane { + padding: 0 + + property var delegateComponentMap: { + "ItemDelegate": itemDelegateComponent, + "SwipeDelegate": swipeDelegateComponent, + "CheckDelegate": checkDelegateComponent, + "RadioDelegate": radioDelegateComponent, + "SwitchDelegate": switchDelegateComponent + } + + Component { + id: itemDelegateComponent + + ItemDelegate { + text: labelText + width: parent.width + } + } + + Component { + id: swipeDelegateComponent + + SwipeDelegate { + id: swipeDelegate + text: labelText + width: parent.width + + Component { + id: removeComponent + + Rectangle { + color: SwipeDelegate.pressed ? "#333" : "#444" + width: parent.width + height: parent.height + clip: true + + SwipeDelegate.onClicked: view.model.remove(ourIndex) + + Label { + font.pixelSize: swipeDelegate.font.pixelSize + text: "Remove" + color: "white" + anchors.centerIn: parent + } + } + } + + swipe.left: removeComponent + swipe.right: removeComponent + } + } + + Component { + id: checkDelegateComponent + + CheckDelegate { + text: labelText + } + } + + ButtonGroup { + id: radioButtonGroup + } + + Component { + id: radioDelegateComponent + + RadioDelegate { + text: labelText + ButtonGroup.group: radioButtonGroup + } + } + + Component { + id: switchDelegateComponent + + SwitchDelegate { + text: labelText + } + } + + ColumnLayout { + id: column + spacing: 40 + anchors.fill: parent + anchors.topMargin: 20 + + Label { + Layout.fillWidth: true + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Delegate controls are used as delegates in views such as ListView." + } + + ListView { + id: listView + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + model: ListModel { + ListElement { type: "ItemDelegate"; text: "ItemDelegate" } + ListElement { type: "ItemDelegate"; text: "ItemDelegate" } + ListElement { type: "ItemDelegate"; text: "ItemDelegate" } + ListElement { type: "SwipeDelegate"; text: "SwipeDelegate" } + ListElement { type: "SwipeDelegate"; text: "SwipeDelegate" } + ListElement { type: "SwipeDelegate"; text: "SwipeDelegate" } + ListElement { type: "CheckDelegate"; text: "CheckDelegate" } + ListElement { type: "CheckDelegate"; text: "CheckDelegate" } + ListElement { type: "CheckDelegate"; text: "CheckDelegate" } + ListElement { type: "RadioDelegate"; text: "RadioDelegate" } + ListElement { type: "RadioDelegate"; text: "RadioDelegate" } + ListElement { type: "RadioDelegate"; text: "RadioDelegate" } + ListElement { type: "SwitchDelegate"; text: "SwitchDelegate" } + ListElement { type: "SwitchDelegate"; text: "SwitchDelegate" } + ListElement { type: "SwitchDelegate"; text: "SwitchDelegate" } + } + + section.property: "type" + section.delegate: Pane { + width: listView.width + height: sectionLabel.implicitHeight + 20 + + Label { + id: sectionLabel + text: section + anchors.centerIn: parent + } + } + + delegate: Loader { + id: delegateLoader + width: listView.width + sourceComponent: delegateComponentMap[text] + + property string labelText: text + property ListView view: listView + property int ourIndex: index + + // Can't find a way to do this in the SwipeDelegate component itself, + // so do it here instead. + SequentialAnimation { + id: removeAnimation + + PropertyAction { + target: delegateLoader + property: "ListView.delayRemove" + value: true + } + NumberAnimation { + target: item + property: "height" + to: 0 + easing.type: Easing.InOutQuad + } + PropertyAction { + target: delegateLoader + property: "ListView.delayRemove" + value: false + } + } + ListView.onRemove: removeAnimation.start() + } + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/DialPage.qml b/examples/quickcontrols2/gallery/pages/DialPage.qml new file mode 100644 index 00000000000..55519fb3a95 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/DialPage.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "The Dial is similar to a traditional dial knob that is found on devices such as " + + "stereos or industrial equipment. It allows the user to specify a value within a range." + } + + Dial { + value: 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/DialogPage.qml b/examples/quickcontrols2/gallery/pages/DialogPage.qml new file mode 100644 index 00000000000..e5162b36f47 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/DialogPage.qml @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +ScrollablePage { + id: page + + readonly property int buttonWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 2, page.availableWidth / 3)) + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Dialog is a popup that is mostly used for short-term tasks " + + "and brief communications with the user." + } + + Button { + text: "Message" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: messageDialog.open() + + Dialog { + id: messageDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + title: "Message" + + Label { + text: "Lorem ipsum dolor sit amet..." + } + } + } + + Button { + id: button + text: "Confirmation" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: confirmationDialog.open() + + Dialog { + id: confirmationDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + parent: Overlay.overlay + + modal: true + title: "Confirmation" + standardButtons: Dialog.Yes | Dialog.No + + Column { + spacing: 20 + anchors.fill: parent + Label { + text: "The document has been modified.\nDo you want to save your changes?" + } + CheckBox { + text: "Do not ask again" + anchors.right: parent.right + } + } + } + } + + Button { + text: "Content" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: contentDialog.open() + + Dialog { + id: contentDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: Math.min(page.width, page.height) / 3 * 2 + contentHeight: logo.height * 2 + parent: Overlay.overlay + + modal: true + title: "Content" + standardButtons: Dialog.Close + + Flickable { + id: flickable + clip: true + anchors.fill: parent + contentHeight: column.height + + Column { + id: column + spacing: 20 + width: parent.width + + Image { + id: logo + width: parent.width / 2 + anchors.horizontalCenter: parent.horizontalCenter + fillMode: Image.PreserveAspectFit + source: "../images/qt-logo.png" + } + + Label { + width: parent.width + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc finibus " + + "in est quis laoreet. Interdum et malesuada fames ac ante ipsum primis " + + "in faucibus. Curabitur eget justo sollicitudin enim faucibus bibendum. " + + "Suspendisse potenti. Vestibulum cursus consequat mauris id sollicitudin. " + + "Duis facilisis hendrerit consectetur. Curabitur sapien tortor, efficitur " + + "id auctor nec, efficitur et nisl. Ut venenatis eros in nunc placerat, " + + "eu aliquam enim suscipit." + wrapMode: Label.Wrap + } + } + + ScrollIndicator.vertical: ScrollIndicator { + parent: contentDialog.contentItem + anchors.top: flickable.top + anchors.bottom: flickable.bottom + anchors.right: parent.right + anchors.rightMargin: -contentDialog.rightPadding + 1 + } + } + } + } + + Button { + text: "Input" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: inputDialog.open() + + Dialog { + id: inputDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + parent: Overlay.overlay + + focus: true + modal: true + title: "Input" + standardButtons: Dialog.Ok | Dialog.Cancel + + ColumnLayout { + spacing: 20 + anchors.fill: parent + Label { + elide: Label.ElideRight + text: "Please enter the credentials:" + Layout.fillWidth: true + } + TextField { + focus: true + placeholderText: "Username" + Layout.fillWidth: true + } + TextField { + placeholderText: "Password" + echoMode: TextField.PasswordEchoOnEdit + Layout.fillWidth: true + } + } + } + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/FramePage.qml b/examples/quickcontrols2/gallery/pages/FramePage.qml new file mode 100644 index 00000000000..7fda3d6683a --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/FramePage.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + readonly property int itemWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 3, page.availableWidth / 3 * 2)) + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Frame is used to layout a logical group of controls together, within a visual frame." + } + + Frame { + anchors.horizontalCenter: parent.horizontalCenter + + Column { + spacing: 20 + width: page.itemWidth + + RadioButton { + text: "First" + checked: true + width: parent.width + } + RadioButton { + id: button + text: "Second" + width: parent.width + } + RadioButton { + text: "Third" + width: parent.width + } + } + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/GroupBoxPage.qml b/examples/quickcontrols2/gallery/pages/GroupBoxPage.qml new file mode 100644 index 00000000000..2a01297bbb1 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/GroupBoxPage.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + readonly property int itemWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 3, page.availableWidth / 3 * 2)) + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "A GroupBox provides a frame, a title on top of it, and a logical group of controls within that frame." + } + + GroupBox { + title: "Title" + anchors.horizontalCenter: parent.horizontalCenter + + Column { + spacing: 20 + width: page.itemWidth + + RadioButton { + text: "First" + checked: true + width: parent.width + } + RadioButton { + id: button + text: "Second" + width: parent.width + } + RadioButton { + text: "Third" + width: parent.width + } + } + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/PageIndicatorPage.qml b/examples/quickcontrols2/gallery/pages/PageIndicatorPage.qml new file mode 100644 index 00000000000..612a942c83e --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/PageIndicatorPage.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "PageIndicator is used to indicate the currently active page in a container of pages." + } + + PageIndicator { + count: 5 + currentIndex: 2 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/ProgressBarPage.qml b/examples/quickcontrols2/gallery/pages/ProgressBarPage.qml new file mode 100644 index 00000000000..252e8eff9c2 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/ProgressBarPage.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ProgressBar indicates the progress of an operation. It can be set in an " + + "indeterminate mode to indicate that the length of the operation is unknown." + } + + ProgressBar { + id: bar + value: 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + + ProgressBar { + indeterminate: true + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/RadioButtonPage.qml b/examples/quickcontrols2/gallery/pages/RadioButtonPage.qml new file mode 100644 index 00000000000..41d4d34ea45 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/RadioButtonPage.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "RadioButton presents an option button that can be toggled on or off. " + + "Radio buttons are typically used to select one option from a set of options." + } + + Column { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + RadioButton { + text: "First" + } + RadioButton { + text: "Second" + checked: true + } + RadioButton { + text: "Third" + enabled: false + } + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/RangeSliderPage.qml b/examples/quickcontrols2/gallery/pages/RangeSliderPage.qml new file mode 100644 index 00000000000..65f852ffd0f --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/RangeSliderPage.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "RangeSlider is used to select a range specified by two values, by sliding each handle along a track." + } + + RangeSlider { + id: slider + first.value: 0.25 + second.value: 0.75 + anchors.horizontalCenter: parent.horizontalCenter + } + + RangeSlider { + orientation: Qt.Vertical + first.value: 0.25 + second.value: 0.75 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/ScrollBarPage.qml b/examples/quickcontrols2/gallery/pages/ScrollBarPage.qml new file mode 100644 index 00000000000..90c43965b08 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/ScrollBarPage.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Flickable { + id: flickable + + contentHeight: pane.height + + Pane { + id: pane + width: flickable.width + height: flickable.height * 1.25 + + Column { + id: column + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ScrollBar is an interactive bar that can be used to scroll to a specific position. " + + "A scroll bar can be either vertical or horizontal, and can be attached to any Flickable, " + + "such as ListView and GridView." + } + + Image { + rotation: 90 + source: "../images/arrows.png" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + + ScrollBar.vertical: ScrollBar { } +} diff --git a/examples/quickcontrols2/gallery/pages/ScrollIndicatorPage.qml b/examples/quickcontrols2/gallery/pages/ScrollIndicatorPage.qml new file mode 100644 index 00000000000..301146eaf0b --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/ScrollIndicatorPage.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Flickable { + id: flickable + + contentHeight: pane.height + + Pane { + id: pane + width: flickable.width + height: flickable.height * 1.25 + + Column { + id: column + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ScrollIndicator is a non-interactive indicator that indicates the current scroll position. " + + "A scroll indicator can be either vertical or horizontal, and can be attached to any Flickable, " + + "such as ListView and GridView." + } + + Image { + rotation: 90 + source: "../images/arrows.png" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + + ScrollIndicator.vertical: ScrollIndicator { } +} diff --git a/examples/quickcontrols2/gallery/pages/ScrollablePage.qml b/examples/quickcontrols2/gallery/pages/ScrollablePage.qml new file mode 100644 index 00000000000..483159e72cf --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/ScrollablePage.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Page { + id: page + + default property alias content: pane.contentItem + + Flickable { + anchors.fill: parent + contentHeight: pane.implicitHeight + flickableDirection: Flickable.AutoFlickIfNeeded + + Pane { + id: pane + width: parent.width + } + + ScrollIndicator.vertical: ScrollIndicator { } + } +} diff --git a/examples/quickcontrols2/gallery/pages/SliderPage.qml b/examples/quickcontrols2/gallery/pages/SliderPage.qml new file mode 100644 index 00000000000..5dcac2d899e --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/SliderPage.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Slider is used to select a value by sliding a handle along a track." + } + + Slider { + id: slider + value: 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + + Slider { + orientation: Qt.Vertical + value: 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/SpinBoxPage.qml b/examples/quickcontrols2/gallery/pages/SpinBoxPage.qml new file mode 100644 index 00000000000..6fddbd27e45 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/SpinBoxPage.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "SpinBox allows the user to choose an integer value by clicking the up or down indicator buttons, " + + "by pressing up or down on the keyboard, or by entering a text value in the input field." + } + + SpinBox { + id: box + value: 50 + anchors.horizontalCenter: parent.horizontalCenter + editable: true + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/StackViewPage.qml b/examples/quickcontrols2/gallery/pages/StackViewPage.qml new file mode 100644 index 00000000000..fc2a4bdf17e --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/StackViewPage.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +StackView { + id: stackView + initialItem: page + + Component { + id: page + + Pane { + id: pane + width: parent ? parent.width : 0 // TODO: fix null parent on destruction + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "StackView provides a stack-based navigation model which can be used with a set of interlinked pages. " + + "Items are pushed onto the stack as the user navigates deeper into the material, and popped off again " + + "when he chooses to go back." + } + + Button { + id: button + text: "Push" + anchors.horizontalCenter: parent.horizontalCenter + width: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 2, pane.availableWidth / 3)) + onClicked: stackView.push(page) + } + + Button { + text: "Pop" + enabled: stackView.depth > 1 + width: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 2, pane.availableWidth / 3)) + anchors.horizontalCenter: parent.horizontalCenter + onClicked: stackView.pop() + } + } + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/SwipeViewPage.qml b/examples/quickcontrols2/gallery/pages/SwipeViewPage.qml new file mode 100644 index 00000000000..9cff5db89a3 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/SwipeViewPage.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Pane { + id: pane + + SwipeView { + id: view + currentIndex: 1 + anchors.fill: parent + + Repeater { + model: 3 + + Pane { + width: view.width + height: view.height + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "SwipeView provides a navigation model that simplifies horizontal paged scrolling. " + + "The page indicator on the bottom shows which is the presently active page." + } + + Image { + source: "../images/arrows.png" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + } + } + + PageIndicator { + count: view.count + currentIndex: view.currentIndex + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/quickcontrols2/gallery/pages/SwitchPage.qml b/examples/quickcontrols2/gallery/pages/SwitchPage.qml new file mode 100644 index 00000000000..2f4089a0e37 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/SwitchPage.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Switch is an option button that can be dragged or toggled on or off. " + + "Switches are typically used to select between two states." + } + + Column { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + Switch { + text: "First" + } + Switch { + text: "Second" + checked: true + } + Switch { + text: "Third" + enabled: false + } + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/TabBarPage.qml b/examples/quickcontrols2/gallery/pages/TabBarPage.qml new file mode 100644 index 00000000000..b14df6d1255 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/TabBarPage.qml @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Page { + id: page + + SwipeView { + id: swipeView + anchors.fill: parent + currentIndex: tabBar.currentIndex + + Repeater { + model: 3 + + Pane { + width: swipeView.width + height: swipeView.height + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "TabBar is a bar with icons or text which allows the user " + + "to switch between different subtasks, views, or modes." + } + + Image { + source: "../images/arrows.png" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + } + } + + footer: TabBar { + id: tabBar + currentIndex: swipeView.currentIndex + + TabButton { + text: "First" + } + TabButton { + text: "Second" + } + TabButton { + text: "Third" + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/TextAreaPage.qml b/examples/quickcontrols2/gallery/pages/TextAreaPage.qml new file mode 100644 index 00000000000..c3a2bf94ac1 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/TextAreaPage.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "TextArea is a multi-line text editor." + } + + TextArea { + width: pane.availableWidth / 3 + anchors.horizontalCenter: parent.horizontalCenter + + wrapMode: TextArea.Wrap + text: "TextArea\n...\n...\n..." + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/TextFieldPage.qml b/examples/quickcontrols2/gallery/pages/TextFieldPage.qml new file mode 100644 index 00000000000..7ecdddc203e --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/TextFieldPage.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "TextField is a single-line text editor." + } + + TextField { + id: field + placeholderText: "TextField" + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/ToolTipPage.qml b/examples/quickcontrols2/gallery/pages/ToolTipPage.qml new file mode 100644 index 00000000000..eaae72b15e4 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/ToolTipPage.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "A tool tip is a short piece of text that informs the user of a control's function." + } + + Button { + text: "Tip" + anchors.horizontalCenter: parent.horizontalCenter + + ToolTip.timeout: 5000 + ToolTip.visible: pressed + ToolTip.text: "This is a tool tip." + } + } +} diff --git a/examples/quickcontrols2/gallery/pages/TumblerPage.qml b/examples/quickcontrols2/gallery/pages/TumblerPage.qml new file mode 100644 index 00000000000..8a22a025459 --- /dev/null +++ b/examples/quickcontrols2/gallery/pages/TumblerPage.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Tumbler is used to select a value by spinning a wheel." + } + + Tumbler { + model: 10 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols2/gallery/qmldir b/examples/quickcontrols2/gallery/qmldir new file mode 100644 index 00000000000..6b7f86bfacd --- /dev/null +++ b/examples/quickcontrols2/gallery/qmldir @@ -0,0 +1 @@ +module App diff --git a/examples/quickcontrols2/gallery/qtquickcontrols2.conf b/examples/quickcontrols2/gallery/qtquickcontrols2.conf new file mode 100644 index 00000000000..da1a8f41d2e --- /dev/null +++ b/examples/quickcontrols2/gallery/qtquickcontrols2.conf @@ -0,0 +1,8 @@ +[Material] +Primary=#41cd52 +Accent=#41cd52 +Theme=System + +[Universal] +Accent=#41cd52 +Theme=System diff --git a/examples/quickcontrols2/imagine/automotive/CMakeLists.txt b/examples/quickcontrols2/imagine/automotive/CMakeLists.txt new file mode 100644 index 00000000000..cc5c60735ca --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/CMakeLists.txt @@ -0,0 +1,191 @@ +# Generated from automotive.pro. + +cmake_minimum_required(VERSION 3.16) +project(automotive LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/imagine/automotive") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS QuickControls2) + +qt_add_executable(automotive + automotive.cpp +) +set_target_properties(automotive PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(automotive PUBLIC + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) + + +# Resources: +set(icons_resource_files + "icons/automotive/44x44/air-con.png" + "icons/automotive/44x44/command.png" + "icons/automotive/44x44/message.png" + "icons/automotive/44x44/music.png" + "icons/automotive/44x44/seats.png" + "icons/automotive/44x44/settings.png" + "icons/automotive/44x44/statistics.png" + "icons/automotive/44x44/windows.png" + "icons/automotive/44x44@2/air-con.png" + "icons/automotive/44x44@2/command.png" + "icons/automotive/44x44@2/message.png" + "icons/automotive/44x44@2/music.png" + "icons/automotive/44x44@2/navigation.png" + "icons/automotive/44x44@2/seats.png" + "icons/automotive/44x44@2/settings.png" + "icons/automotive/44x44@2/statistics.png" + "icons/automotive/44x44@2/windows.png" + "icons/automotive/icons.svg" + "icons/automotive/index.theme" + "icons/car.png" + "icons/car@2x.png" + "icons/warning.png" + "icons/warning@2x.png" + "icons/weather.png" + "icons/weather@2x.png" +) + +qt6_add_resources(automotive "icons" + PREFIX + "/icons" + BASE + "icons" + FILES + ${icons_resource_files} +) +set(imagine-assets_resource_files + "imagine-assets/applicationwindow-background.png" + "imagine-assets/applicationwindow-background@2x.png" + "imagine-assets/button-background-checked-hovered.9.png" + "imagine-assets/button-background-checked-hovered@2x.9.png" + "imagine-assets/button-background-checked.9.png" + "imagine-assets/button-background-checked@2x.9.png" + "imagine-assets/button-background-hovered.9.png" + "imagine-assets/button-background-hovered@2x.9.png" + "imagine-assets/button-background-pressed.9.png" + "imagine-assets/button-background-pressed@2x.9.png" + "imagine-assets/button-background.9.png" + "imagine-assets/button-background@2x.9.png" + "imagine-assets/dial-background-hovered.png" + "imagine-assets/dial-background-hovered@2x.png" + "imagine-assets/dial-background-pressed.png" + "imagine-assets/dial-background-pressed@2x.png" + "imagine-assets/dial-background.png" + "imagine-assets/dial-background@2x.png" + "imagine-assets/dial-handle-pressed.png" + "imagine-assets/dial-handle-pressed@2x.png" + "imagine-assets/dial-handle.png" + "imagine-assets/dial-handle@2x.png" + "imagine-assets/frame-background.9.png" + "imagine-assets/frame-background@2x.9.png" + "imagine-assets/itemdelegate-background-checked.9.png" + "imagine-assets/itemdelegate-background-checked@2x.9.png" + "imagine-assets/itemdelegate-background-hovered.9.png" + "imagine-assets/itemdelegate-background-hovered@2x.9.png" + "imagine-assets/itemdelegate-background-pressed.9.png" + "imagine-assets/itemdelegate-background-pressed@2x.9.png" + "imagine-assets/itemdelegate-background.9.png" + "imagine-assets/itemdelegate-background@2x.9.png" + "imagine-assets/radiobutton-indicator-checked-hovered.png" + "imagine-assets/radiobutton-indicator-checked-hovered@2x.png" + "imagine-assets/radiobutton-indicator-checked-pressed.png" + "imagine-assets/radiobutton-indicator-checked-pressed@2x.png" + "imagine-assets/radiobutton-indicator-checked.png" + "imagine-assets/radiobutton-indicator-checked@2x.png" + "imagine-assets/radiobutton-indicator-hovered.png" + "imagine-assets/radiobutton-indicator-hovered@2x.png" + "imagine-assets/radiobutton-indicator-pressed.png" + "imagine-assets/radiobutton-indicator-pressed@2x.png" + "imagine-assets/radiobutton-indicator.png" + "imagine-assets/radiobutton-indicator@2x.png" + "imagine-assets/scrollindicator-handle.png" + "imagine-assets/scrollindicator-handle@2x.png" + "imagine-assets/slider-background-horizontal.9.png" + "imagine-assets/slider-background-horizontal@2x.9.png" + "imagine-assets/slider-handle-hovered.png" + "imagine-assets/slider-handle-hovered@2x.png" + "imagine-assets/slider-handle-pressed.png" + "imagine-assets/slider-handle-pressed@2x.png" + "imagine-assets/slider-handle.png" + "imagine-assets/slider-handle@2x.png" + "imagine-assets/slider-progress-horizontal-pressed.9.png" + "imagine-assets/slider-progress-horizontal-pressed@2x.9.png" + "imagine-assets/slider-progress-horizontal.9.png" + "imagine-assets/slider-progress-horizontal@2x.9.png" + "imagine-assets/switchdelegate-background.9.png" + "imagine-assets/switchdelegate-background@2x.9.png" + "imagine-assets/switchdelegate-handle-checked-hovered.png" + "imagine-assets/switchdelegate-handle-checked-hovered@2x.png" + "imagine-assets/switchdelegate-handle-checked.png" + "imagine-assets/switchdelegate-handle-checked@2x.png" + "imagine-assets/switchdelegate-handle-hovered.png" + "imagine-assets/switchdelegate-handle-hovered@2x.png" + "imagine-assets/switchdelegate-handle-pressed.png" + "imagine-assets/switchdelegate-handle-pressed@2x.png" + "imagine-assets/switchdelegate-handle.png" + "imagine-assets/switchdelegate-handle@2x.png" + "imagine-assets/switchdelegate-indicator-pressed.png" + "imagine-assets/switchdelegate-indicator-pressed@2x.png" + "imagine-assets/switchdelegate-indicator.png" + "imagine-assets/switchdelegate-indicator@2x.png" + "imagine-assets/toolseparator-separator-vertical.9.png" + "imagine-assets/toolseparator-separator-vertical@2x.9.png" +) + +qt6_add_resources(automotive "imagine-assets" + PREFIX + "/imagine-assets" + BASE + "imagine-assets" + FILES + ${imagine-assets_resource_files} +) +set(qml_resource_files + "qml/FeatureButton.qml" + "qml/LargeLabel.qml" + "qml/automotive.qml" +) + +qt6_add_resources(automotive "qml" + PREFIX + "/qml" + BASE + "qml" + FILES + ${qml_resource_files} +) +set(qmake_immediate_resource_files + "qtquickcontrols2.conf" +) + +qt6_add_resources(automotive "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + +install(TARGETS automotive + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/imagine/automotive/automotive.cpp b/examples/quickcontrols2/imagine/automotive/automotive.cpp new file mode 100644 index 00000000000..dc1d83e4e49 --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/automotive.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication::setApplicationName("Automotive"); + QGuiApplication::setOrganizationName("QtProject"); + + QGuiApplication app(argc, argv); + + QIcon::setThemeName("automotive"); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/qml/automotive.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols2/imagine/automotive/automotive.pro b/examples/quickcontrols2/imagine/automotive/automotive.pro new file mode 100644 index 00000000000..890e63d84b5 --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/automotive.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +TARGET = automotive +QT += quick quickcontrols2 + +SOURCES += \ + automotive.cpp + +RESOURCES += \ + icons/icons.qrc \ + imagine-assets/imagine-assets.qrc \ + qml/qml.qrc \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/imagine/automotive +INSTALLS += target diff --git a/examples/quickcontrols2/imagine/automotive/doc/images/qtquickcontrols2-automotive.png b/examples/quickcontrols2/imagine/automotive/doc/images/qtquickcontrols2-automotive.png new file mode 100644 index 00000000000..93ea28545b3 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/doc/images/qtquickcontrols2-automotive.png differ diff --git a/examples/quickcontrols2/imagine/automotive/doc/src/qtquickcontrols2-automotive.qdoc b/examples/quickcontrols2/imagine/automotive/doc/src/qtquickcontrols2-automotive.qdoc new file mode 100644 index 00000000000..4e3d3352279 --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/doc/src/qtquickcontrols2-automotive.qdoc @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example imagine/automotive + \keyword Qt Quick Controls - Imagine Style Example: Automotive + \title Qt Quick Controls - Imagine Style Example: Automotive + \keyword Qt Quick Controls 2 - Imagine Style Example: Automotive + \ingroup qtquickcontrols2-examples + \brief An automotive user interface using custom Imagine style assets. + + This example demonstrates how custom Imagine style assets can be used to + style an automotive user interface. + + \image qtquickcontrols2-automotive.png + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/air-con.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/air-con.png new file mode 100644 index 00000000000..70175f6f05d Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/air-con.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/command.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/command.png new file mode 100644 index 00000000000..8f712c78810 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/command.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/message.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/message.png new file mode 100644 index 00000000000..7773ca63baf Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/message.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/music.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/music.png new file mode 100644 index 00000000000..dc73322bfed Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/music.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/seats.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/seats.png new file mode 100644 index 00000000000..2f9eaa62272 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/seats.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/settings.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/settings.png new file mode 100644 index 00000000000..b65598b58c6 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/settings.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/statistics.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/statistics.png new file mode 100644 index 00000000000..979702989b8 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/statistics.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/windows.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/windows.png new file mode 100644 index 00000000000..8ed8cec4bf8 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44/windows.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/air-con.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/air-con.png new file mode 100644 index 00000000000..8822979e6a5 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/air-con.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/command.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/command.png new file mode 100644 index 00000000000..918e2b69eb4 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/command.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/message.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/message.png new file mode 100644 index 00000000000..1debfdfb263 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/message.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/music.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/music.png new file mode 100644 index 00000000000..01a3ece417b Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/music.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/navigation.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/navigation.png new file mode 100644 index 00000000000..3a18fb5f4e2 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/navigation.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/seats.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/seats.png new file mode 100644 index 00000000000..7d67f1be3f1 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/seats.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/settings.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/settings.png new file mode 100644 index 00000000000..3ce2a1f1b4d Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/settings.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/statistics.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/statistics.png new file mode 100644 index 00000000000..afc2cc09067 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/statistics.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/windows.png b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/windows.png new file mode 100644 index 00000000000..59bac584edf Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/automotive/44x44@2/windows.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/icons.svg b/examples/quickcontrols2/imagine/automotive/icons/automotive/icons.svg new file mode 100644 index 00000000000..daf4633c252 --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/icons/automotive/icons.svg @@ -0,0 +1,526 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ! + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/quickcontrols2/imagine/automotive/icons/automotive/index.theme b/examples/quickcontrols2/imagine/automotive/icons/automotive/index.theme new file mode 100644 index 00000000000..cd84146e950 --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/icons/automotive/index.theme @@ -0,0 +1,14 @@ +[Icon Theme] +Name=Automotive +Comment=Icon theme for the Qt Quick Controls 2 Automotive Imagine Style Example + +Directories=44x44,44x44@2 + +[44x44] +Size=44 +Type=Fixed + +[44x44@2] +Size=44 +Scale=2 +Type=Fixed diff --git a/examples/quickcontrols2/imagine/automotive/icons/car.png b/examples/quickcontrols2/imagine/automotive/icons/car.png new file mode 100644 index 00000000000..4bfc9a474ad Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/car.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/car@2x.png b/examples/quickcontrols2/imagine/automotive/icons/car@2x.png new file mode 100644 index 00000000000..966bc47bc7d Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/car@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/icons.qrc b/examples/quickcontrols2/imagine/automotive/icons/icons.qrc new file mode 100644 index 00000000000..5cb797817b7 --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/icons/icons.qrc @@ -0,0 +1,29 @@ + + + car.png + car@2x.png + warning.png + warning@2x.png + weather.png + weather@2x.png + automotive/icons.svg + automotive/index.theme + automotive/44x44/air-con.png + automotive/44x44/command.png + automotive/44x44/message.png + automotive/44x44/music.png + automotive/44x44/seats.png + automotive/44x44/settings.png + automotive/44x44/statistics.png + automotive/44x44/windows.png + automotive/44x44@2/air-con.png + automotive/44x44@2/command.png + automotive/44x44@2/message.png + automotive/44x44@2/music.png + automotive/44x44@2/navigation.png + automotive/44x44@2/seats.png + automotive/44x44@2/settings.png + automotive/44x44@2/statistics.png + automotive/44x44@2/windows.png + + diff --git a/examples/quickcontrols2/imagine/automotive/icons/warning.png b/examples/quickcontrols2/imagine/automotive/icons/warning.png new file mode 100644 index 00000000000..590a61eb800 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/warning.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/warning@2x.png b/examples/quickcontrols2/imagine/automotive/icons/warning@2x.png new file mode 100644 index 00000000000..487fbafcfd2 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/warning@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/weather.png b/examples/quickcontrols2/imagine/automotive/icons/weather.png new file mode 100644 index 00000000000..b1479de27a2 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/weather.png differ diff --git a/examples/quickcontrols2/imagine/automotive/icons/weather@2x.png b/examples/quickcontrols2/imagine/automotive/icons/weather@2x.png new file mode 100644 index 00000000000..8b4333ab151 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/icons/weather@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/applicationwindow-background.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/applicationwindow-background.png new file mode 100644 index 00000000000..aac403dbb12 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/applicationwindow-background.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/applicationwindow-background@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/applicationwindow-background@2x.png new file mode 100644 index 00000000000..a8ef3dd456a Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/applicationwindow-background@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-checked-hovered.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-checked-hovered.9.png new file mode 100644 index 00000000000..f92dd66afe7 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-checked-hovered.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-checked-hovered@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-checked-hovered@2x.9.png new file mode 100644 index 00000000000..b64640e2b14 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-checked-hovered@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-checked.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-checked.9.png new file mode 100644 index 00000000000..5a70d1d3025 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-checked.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-checked@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-checked@2x.9.png new file mode 100644 index 00000000000..9d080dc823e Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-checked@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-hovered.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-hovered.9.png new file mode 100644 index 00000000000..94e37b8334d Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-hovered.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-hovered@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-hovered@2x.9.png new file mode 100644 index 00000000000..905d9e47050 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-hovered@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-pressed.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-pressed.9.png new file mode 100644 index 00000000000..bc4c3b38802 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-pressed.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-pressed@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-pressed@2x.9.png new file mode 100644 index 00000000000..778fe537527 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background-pressed@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background.9.png new file mode 100644 index 00000000000..85ed1a03ba4 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background@2x.9.png new file mode 100644 index 00000000000..1eb7ebed204 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/button-background@2x.9.png differ diff --git a/tests/auto/cmake/qtquickcompiler/empty.qrc b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-background-hovered.png similarity index 100% rename from tests/auto/cmake/qtquickcompiler/empty.qrc rename to examples/quickcontrols2/imagine/automotive/imagine-assets/dial-background-hovered.png diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-background-hovered@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-background-hovered@2x.png new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-background-pressed.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-background-pressed.png new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-background-pressed@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-background-pressed@2x.png new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-background.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-background.png new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-background@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-background@2x.png new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-handle-pressed.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-handle-pressed.png new file mode 100644 index 00000000000..93992626ced Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-handle-pressed.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-handle-pressed@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-handle-pressed@2x.png new file mode 100644 index 00000000000..5c563abba5a Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-handle-pressed@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-handle.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-handle.png new file mode 100644 index 00000000000..a997dd58f87 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-handle.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-handle@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-handle@2x.png new file mode 100644 index 00000000000..afd13307040 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/dial-handle@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/frame-background.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/frame-background.9.png new file mode 100644 index 00000000000..fd7d5453ff1 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/frame-background.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/frame-background@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/frame-background@2x.9.png new file mode 100644 index 00000000000..83284457e4d Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/frame-background@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/imagine-assets.qrc b/examples/quickcontrols2/imagine/automotive/imagine-assets/imagine-assets.qrc new file mode 100644 index 00000000000..81eadda6171 --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/imagine-assets/imagine-assets.qrc @@ -0,0 +1,80 @@ + + + applicationwindow-background.png + applicationwindow-background@2x.png + button-background.9.png + button-background@2x.9.png + button-background-checked.9.png + button-background-checked@2x.9.png + button-background-checked-hovered.9.png + button-background-checked-hovered@2x.9.png + button-background-hovered.9.png + button-background-hovered@2x.9.png + button-background-pressed.9.png + button-background-pressed@2x.9.png + dial-background.png + dial-background@2x.png + dial-background-hovered.png + dial-background-hovered@2x.png + dial-background-pressed.png + dial-background-pressed@2x.png + dial-handle.png + dial-handle@2x.png + dial-handle-pressed.png + dial-handle-pressed@2x.png + frame-background.9.png + frame-background@2x.9.png + itemdelegate-background.9.png + itemdelegate-background@2x.9.png + itemdelegate-background-checked.9.png + itemdelegate-background-checked@2x.9.png + itemdelegate-background-hovered.9.png + itemdelegate-background-hovered@2x.9.png + itemdelegate-background-pressed.9.png + itemdelegate-background-pressed@2x.9.png + radiobutton-indicator.png + radiobutton-indicator@2x.png + radiobutton-indicator-checked.png + radiobutton-indicator-checked@2x.png + radiobutton-indicator-checked-hovered.png + radiobutton-indicator-checked-hovered@2x.png + radiobutton-indicator-checked-pressed.png + radiobutton-indicator-checked-pressed@2x.png + radiobutton-indicator-hovered.png + radiobutton-indicator-hovered@2x.png + radiobutton-indicator-pressed.png + radiobutton-indicator-pressed@2x.png + scrollindicator-handle.png + scrollindicator-handle@2x.png + slider-background-horizontal.9.png + slider-background-horizontal@2x.9.png + slider-handle.png + slider-handle@2x.png + slider-handle-hovered.png + slider-handle-hovered@2x.png + slider-handle-pressed.png + slider-handle-pressed@2x.png + slider-progress-horizontal.9.png + slider-progress-horizontal@2x.9.png + slider-progress-horizontal-pressed.9.png + slider-progress-horizontal-pressed@2x.9.png + switchdelegate-background.9.png + switchdelegate-background@2x.9.png + switchdelegate-handle.png + switchdelegate-handle@2x.png + switchdelegate-handle-checked.png + switchdelegate-handle-checked@2x.png + switchdelegate-handle-checked-hovered.png + switchdelegate-handle-checked-hovered@2x.png + switchdelegate-handle-hovered.png + switchdelegate-handle-hovered@2x.png + switchdelegate-handle-pressed.png + switchdelegate-handle-pressed@2x.png + switchdelegate-indicator.png + switchdelegate-indicator@2x.png + switchdelegate-indicator-pressed.png + switchdelegate-indicator-pressed@2x.png + toolseparator-separator-vertical.9.png + toolseparator-separator-vertical@2x.9.png + + diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-checked.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-checked.9.png new file mode 100644 index 00000000000..4c6b475441d Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-checked.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-checked@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-checked@2x.9.png new file mode 100644 index 00000000000..9f4f70575f0 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-checked@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-hovered.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-hovered.9.png new file mode 100644 index 00000000000..a5c189c9e3e Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-hovered.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-hovered@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-hovered@2x.9.png new file mode 100644 index 00000000000..2b3c9c67438 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-hovered@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-pressed.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-pressed.9.png new file mode 100644 index 00000000000..56b5534ea60 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-pressed.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-pressed@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-pressed@2x.9.png new file mode 100644 index 00000000000..bbbbb8b1d86 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background-pressed@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background.9.png new file mode 100644 index 00000000000..1fbb562689f Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background@2x.9.png new file mode 100644 index 00000000000..18880980f08 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/itemdelegate-background@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked-hovered.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked-hovered.png new file mode 100644 index 00000000000..f64c9665b27 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked-hovered.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked-hovered@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked-hovered@2x.png new file mode 100644 index 00000000000..ace1717a97d Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked-hovered@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked-pressed.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked-pressed.png new file mode 100644 index 00000000000..c77ad470c01 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked-pressed.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked-pressed@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked-pressed@2x.png new file mode 100644 index 00000000000..2798f77f0f3 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked-pressed@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked.png new file mode 100644 index 00000000000..ea714eaaf96 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked@2x.png new file mode 100644 index 00000000000..4f29b80b31c Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-checked@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-hovered.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-hovered.png new file mode 100644 index 00000000000..a7d07ed17c3 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-hovered.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-hovered@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-hovered@2x.png new file mode 100644 index 00000000000..b0fff06e51e Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-hovered@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-pressed.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-pressed.png new file mode 100644 index 00000000000..7d657ac9c20 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-pressed.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-pressed@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-pressed@2x.png new file mode 100644 index 00000000000..9a8b9cd829a Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator-pressed@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator.png new file mode 100644 index 00000000000..b59ba0cef88 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator@2x.png new file mode 100644 index 00000000000..e4a2b9a2b94 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/radiobutton-indicator@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/scrollindicator-handle.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/scrollindicator-handle.png new file mode 100644 index 00000000000..99206d7e26a Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/scrollindicator-handle.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/scrollindicator-handle@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/scrollindicator-handle@2x.png new file mode 100644 index 00000000000..85a9ebccf7c Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/scrollindicator-handle@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-background-horizontal.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-background-horizontal.9.png new file mode 100644 index 00000000000..3d2406cf06e Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-background-horizontal.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-background-horizontal@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-background-horizontal@2x.9.png new file mode 100644 index 00000000000..6c8104ff97e Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-background-horizontal@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle-hovered.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle-hovered.png new file mode 100644 index 00000000000..bd26d82451c Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle-hovered.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle-hovered@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle-hovered@2x.png new file mode 100644 index 00000000000..000db404446 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle-hovered@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle-pressed.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle-pressed.png new file mode 100644 index 00000000000..4a4d0be7f8f Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle-pressed.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle-pressed@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle-pressed@2x.png new file mode 100644 index 00000000000..903c1024401 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle-pressed@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle.png new file mode 100644 index 00000000000..8f812dae345 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle@2x.png new file mode 100644 index 00000000000..b30a4f38f02 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-handle@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-progress-horizontal-pressed.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-progress-horizontal-pressed.9.png new file mode 100644 index 00000000000..7789f09f2c1 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-progress-horizontal-pressed.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-progress-horizontal-pressed@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-progress-horizontal-pressed@2x.9.png new file mode 100644 index 00000000000..e64c13dc396 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-progress-horizontal-pressed@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-progress-horizontal.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-progress-horizontal.9.png new file mode 100644 index 00000000000..8e65ca35c5d Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-progress-horizontal.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-progress-horizontal@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-progress-horizontal@2x.9.png new file mode 100644 index 00000000000..d512e407086 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/slider-progress-horizontal@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-background.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-background.9.png new file mode 100644 index 00000000000..1fbb562689f Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-background.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-background@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-background@2x.9.png new file mode 100644 index 00000000000..18880980f08 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-background@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-checked-hovered.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-checked-hovered.png new file mode 100644 index 00000000000..e66ef7137cc Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-checked-hovered.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-checked-hovered@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-checked-hovered@2x.png new file mode 100644 index 00000000000..05d6f82e7aa Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-checked-hovered@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-checked.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-checked.png new file mode 100644 index 00000000000..bcfa06aec6c Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-checked.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-checked@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-checked@2x.png new file mode 100644 index 00000000000..b9985f0fe32 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-checked@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-hovered.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-hovered.png new file mode 100644 index 00000000000..3de8aa1512c Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-hovered.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-hovered@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-hovered@2x.png new file mode 100644 index 00000000000..b955159055e Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-hovered@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-pressed.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-pressed.png new file mode 100644 index 00000000000..547b2c17588 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-pressed.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-pressed@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-pressed@2x.png new file mode 100644 index 00000000000..b4bb748aa46 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle-pressed@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle.png new file mode 100644 index 00000000000..fd81422a882 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle@2x.png new file mode 100644 index 00000000000..9a7456aa418 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-handle@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-indicator-pressed.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-indicator-pressed.png new file mode 100644 index 00000000000..6833d624ae4 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-indicator-pressed.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-indicator-pressed@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-indicator-pressed@2x.png new file mode 100644 index 00000000000..3d5498a0904 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-indicator-pressed@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-indicator.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-indicator.png new file mode 100644 index 00000000000..3db5fe2042d Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-indicator.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-indicator@2x.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-indicator@2x.png new file mode 100644 index 00000000000..b5c10f74977 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/switchdelegate-indicator@2x.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/toolseparator-separator-vertical.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/toolseparator-separator-vertical.9.png new file mode 100644 index 00000000000..02c7a564bee Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/toolseparator-separator-vertical.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/imagine-assets/toolseparator-separator-vertical@2x.9.png b/examples/quickcontrols2/imagine/automotive/imagine-assets/toolseparator-separator-vertical@2x.9.png new file mode 100644 index 00000000000..e0390d36f59 Binary files /dev/null and b/examples/quickcontrols2/imagine/automotive/imagine-assets/toolseparator-separator-vertical@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/automotive/qml/FeatureButton.qml b/examples/quickcontrols2/imagine/automotive/qml/FeatureButton.qml new file mode 100644 index 00000000000..54ebeb48611 --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/qml/FeatureButton.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +Button { + id: button + checkable: true + font.pixelSize: fontSizeExtraSmall + leftPadding: 4 + rightPadding: 4 + topPadding: 12 + bottomPadding: 12 + implicitWidth: 60 + implicitHeight: 90 + + icon.name: "placeholder" + icon.width: 44 + icon.height: 44 + display: Button.TextUnderIcon +} diff --git a/examples/quickcontrols2/imagine/automotive/qml/LargeLabel.qml b/examples/quickcontrols2/imagine/automotive/qml/LargeLabel.qml new file mode 100644 index 00000000000..186e28267df --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/qml/LargeLabel.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +// This container and the transform on the Label are +// necessary to get precise bounding rect of the text for layouting reasons, +// since some of the labels' font sizes can get quite large. +Item { + id: root + implicitHeight: labelTextMetrics.tightBoundingRect.height + implicitWidth: label.implicitWidth + + property alias text: label.text + property alias font: label.font + property alias horizontalAlignment: label.horizontalAlignment + property alias verticalAlignment: label.verticalAlignment + property bool glowEnabled: true + property color color: colorBright + + Label { + id: label + anchors.baseline: root.baseline + color: root.color + + TextMetrics { + id: labelTextMetrics + text: label.text + font: label.font + } + + transform: Translate { + y: -labelTextMetrics.tightBoundingRect.y + } + } +} diff --git a/examples/quickcontrols2/imagine/automotive/qml/automotive.qml b/examples/quickcontrols2/imagine/automotive/qml/automotive.qml new file mode 100644 index 00000000000..7a8ce2224f2 --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/qml/automotive.qml @@ -0,0 +1,633 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Imagine +import QtQuick.Window + +ApplicationWindow { + id: window + width: 1280 + height: 720 + minimumWidth: 1180 + minimumHeight: 663 + visible: true + title: "Qt Quick Controls - Imagine Style Example: Automotive" + + readonly property color colorGlow: "#1d6d64" + readonly property color colorWarning: "#d5232f" + readonly property color colorMain: "#6affcd" + readonly property color colorBright: "#ffffff" + readonly property color colorLightGrey: "#888" + readonly property color colorDarkGrey: "#333" + + readonly property int fontSizeExtraSmall: Qt.application.font.pixelSize * 0.8 + readonly property int fontSizeMedium: Qt.application.font.pixelSize * 1.5 + readonly property int fontSizeLarge: Qt.application.font.pixelSize * 2 + readonly property int fontSizeExtraLarge: Qt.application.font.pixelSize * 5 + + Component.onCompleted: { + x = Screen.width / 2 - width / 2 + y = Screen.height / 2 - height / 2 + } + + Shortcut { + sequence: "Ctrl+Q" + onActivated: Qt.quit() + } + + Frame { + id: frame + anchors.fill: parent + anchors.margins: 90 + + RowLayout { + id: mainRowLayout + anchors.fill: parent + anchors.margins: 24 + spacing: 36 + + Container { + id: leftTabBar + + currentIndex: 1 + + Layout.fillWidth: false + Layout.fillHeight: true + + ButtonGroup { + buttons: columnLayout.children + } + + contentItem: ColumnLayout { + id: columnLayout + spacing: 3 + + Repeater { + model: leftTabBar.contentModel + } + } + + FeatureButton { + id: navigationFeatureButton + text: qsTr("Navigation") + icon.name: "navigation" + Layout.fillHeight: true + } + + FeatureButton { + text: qsTr("Music") + icon.name: "music" + checked: true + Layout.fillHeight: true + } + + FeatureButton { + text: qsTr("Message") + icon.name: "message" + Layout.fillHeight: true + } + + FeatureButton { + text: qsTr("Command") + icon.name: "command" + Layout.fillHeight: true + } + + FeatureButton { + text: qsTr("Settings") + icon.name: "settings" + Layout.fillHeight: true + } + } + + StackLayout { + currentIndex: leftTabBar.currentIndex + + Layout.preferredWidth: 150 + Layout.maximumWidth: 150 + Layout.fillWidth: false + + Item {} + + ColumnLayout { + spacing: 12 + + ButtonGroup { + id: viewButtonGroup + buttons: viewTypeRowLayout.children + } + + RowLayout { + id: viewTypeRowLayout + spacing: 3 + + Layout.bottomMargin: 12 + + Button { + text: qsTr("Compact") + font.pixelSize: fontSizeExtraSmall + checkable: true + checked: true + + Layout.fillWidth: true + } + Button { + text: qsTr("Full") + font.pixelSize: fontSizeExtraSmall + checkable: true + + Layout.fillWidth: true + } + } + + LargeLabel { + text: qsTr("VOLUME") + color: "white" + font.pixelSize: fontSizeMedium + } + + Dial { + id: volumeDial + from: 0 + value: 42 + to: 100 + stepSize: 1 + + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: 128 + Layout.preferredHeight: 128 + + Label { + text: volumeDial.value.toFixed(0) + color: "white" + font.pixelSize: Qt.application.font.pixelSize * 3 + anchors.centerIn: parent + } + } + + ButtonGroup { + id: audioSourceButtonGroup + } + + RowLayout { + Layout.topMargin: 8 + + LargeLabel { + id: radioOption + text: qsTr("RADIO") + color: "white" + font.pixelSize: fontSizeMedium + horizontalAlignment: Label.AlignLeft + + Layout.fillWidth: true + } + LargeLabel { + text: qsTr("AUX") + color: colorLightGrey + font.pixelSize: fontSizeMedium * 0.8 + horizontalAlignment: Label.AlignHCenter + glowEnabled: false + + Layout.alignment: Qt.AlignBottom + Layout.fillWidth: true + } + LargeLabel { + text: qsTr("MP3") + color: colorDarkGrey + font.pixelSize: fontSizeMedium * 0.6 + horizontalAlignment: Label.AlignRight + glowEnabled: false + + Layout.alignment: Qt.AlignBottom + Layout.fillWidth: true + } + } + + Frame { + id: stationFrame + leftPadding: 1 + rightPadding: 1 + topPadding: 1 + bottomPadding: 1 + + Layout.fillWidth: true + Layout.fillHeight: true + Layout.preferredHeight: 128 + + ListView { + id: stationListView + clip: true + anchors.fill: parent + + ScrollIndicator.vertical: ScrollIndicator { + parent: stationFrame + anchors.top: parent.top + anchors.right: parent.right + anchors.rightMargin: 1 + anchors.bottom: parent.bottom + } + + model: ListModel { + ListElement { name: "V-Radio"; frequency: "105.5" } + ListElement { name: "World News"; frequency: "93.4" } + ListElement { name: "TekStep FM"; frequency: "95.0" } + ListElement { name: "Classic Radio"; frequency: "89.9" } + ListElement { name: "Buena Vista FM"; frequency: "100.8" } + ListElement { name: "Drive-by Radio"; frequency: "99.1" } + ListElement { name: "Unknown #1"; frequency: "104.5" } + ListElement { name: "Unknown #2"; frequency: "91.2" } + ListElement { name: "Unknown #3"; frequency: "93.8" } + ListElement { name: "Unknown #4"; frequency: "80.4" } + ListElement { name: "Unknown #5"; frequency: "101.1" } + ListElement { name: "Unknown #6"; frequency: "92.2" } + } + delegate: ItemDelegate { + id: stationDelegate + width: stationListView.width + height: 22 + text: model.name + font.pixelSize: fontSizeExtraSmall + topPadding: 0 + bottomPadding: 0 + + contentItem: RowLayout { + Label { + text: model.name + font: stationDelegate.font + horizontalAlignment: Text.AlignLeft + elide: Text.ElideRight + + Layout.fillWidth: true + } + Label { + text: model.frequency + font: stationDelegate.font + horizontalAlignment: Text.AlignRight + elide: Text.ElideRight + + Layout.fillWidth: true + } + } + } + } + } + + Frame { + Layout.fillWidth: true + + ColumnLayout { + anchors.fill: parent + + Label { + text: qsTr("Sort by") + font.pixelSize: fontSizeExtraSmall + } + + ColumnLayout { + RadioButton { + text: qsTr("Name") + font.pixelSize: fontSizeExtraSmall + } + RadioButton { + text: qsTr("Frequency") + font.pixelSize: fontSizeExtraSmall + } + RadioButton { + text: qsTr("Favourites") + font.pixelSize: fontSizeExtraSmall + checked: true + } + } + } + } + } + } + + Rectangle { + color: colorMain + implicitWidth: 1 + Layout.fillHeight: true + } + + ColumnLayout { + Layout.preferredWidth: 350 + Layout.fillWidth: true + Layout.fillHeight: true + + LargeLabel { + id: timeLabel + text: qsTr("11:02") + font.pixelSize: fontSizeExtraLarge + + Layout.alignment: Qt.AlignHCenter + + LargeLabel { + text: qsTr("AM") + font.pixelSize: fontSizeLarge + anchors.left: parent.right + anchors.leftMargin: 8 + } + } + + Label { + text: qsTr("01/01/2018") + color: colorLightGrey + font.pixelSize: fontSizeMedium + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 2 + Layout.bottomMargin: 10 + } + + Image { + source: "qrc:/icons/car.png" + fillMode: Image.PreserveAspectFit + + Layout.fillHeight: true + + Column { + x: parent.width * 0.88 + y: parent.height * 0.56 + spacing: 3 + + Image { + source: "qrc:/icons/warning.png" + anchors.horizontalCenter: parent.horizontalCenter + } + + LargeLabel { + text: qsTr("Door open") + color: colorWarning + } + } + } + } + + Rectangle { + color: colorMain + implicitWidth: 1 + Layout.fillHeight: true + } + + ColumnLayout { + Row { + spacing: 8 + + Image { + source: "qrc:/icons/weather.png" + } + + Column { + spacing: 8 + + Row { + anchors.horizontalCenter: parent.horizontalCenter + + LargeLabel { + id: outsideTempValueLabel + text: qsTr("31") + font.pixelSize: fontSizeExtraLarge + } + + LargeLabel { + text: qsTr("°C") + font.pixelSize: Qt.application.font.pixelSize * 2.5 + anchors.baseline: outsideTempValueLabel.baseline + } + } + + Label { + text: qsTr("Osaka, Japan") + color: colorLightGrey + font.pixelSize: fontSizeMedium + } + } + } + + ColumnLayout { + id: airConRowLayout + spacing: 8 + + Layout.preferredWidth: 128 + Layout.preferredHeight: 380 + Layout.fillHeight: true + + Item { + Layout.fillHeight: true + } + + SwitchDelegate { + text: qsTr("AC") + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + Layout.fillWidth: true + } + + // QTBUG-63269 + Item { + implicitHeight: temperatureValueLabel.implicitHeight + Layout.fillWidth: true + Layout.topMargin: 16 + + Label { + text: qsTr("Temperature") + anchors.baseline: temperatureValueLabel.bottom + anchors.left: parent.left + } + + LargeLabel { + id: temperatureValueLabel + text: qsTr("24°C") + font.pixelSize: fontSizeLarge + anchors.right: parent.right + } + } + + Slider { + value: 0.35 + Layout.fillWidth: true + } + + // QTBUG-63269 + Item { + implicitHeight: powerValueLabel.implicitHeight + Layout.fillWidth: true + Layout.topMargin: 16 + + Label { + text: qsTr("Power") + anchors.baseline: powerValueLabel.bottom + anchors.left: parent.left + } + + LargeLabel { + id: powerValueLabel + text: qsTr("10%") + font.pixelSize: fontSizeLarge + anchors.right: parent.right + } + } + + Slider { + value: 0.25 + Layout.fillWidth: true + } + + SwitchDelegate { + text: qsTr("Low") + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + Layout.fillWidth: true + Layout.topMargin: 16 + } + + SwitchDelegate { + text: qsTr("High") + checked: true + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + Layout.fillWidth: true + } + + SwitchDelegate { + text: qsTr("Defog") + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + Layout.fillWidth: true + } + + SwitchDelegate { + text: qsTr("Recirculate") + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + Layout.fillWidth: true + } + + Item { + Layout.fillHeight: true + } + } + } + + Container { + id: rightTabBar + + currentIndex: 1 + + Layout.fillHeight: true + + ButtonGroup { + buttons: rightTabBarContentLayout.children + } + + contentItem: ColumnLayout { + id: rightTabBarContentLayout + spacing: 3 + + Repeater { + model: rightTabBar.contentModel + } + } + + Item { + Layout.fillHeight: true + } + + FeatureButton { + text: qsTr("Windows") + icon.name: "windows" + + Layout.maximumHeight: navigationFeatureButton.height + Layout.fillHeight: true + } + FeatureButton { + text: qsTr("Air Con.") + icon.name: "air-con" + checked: true + + Layout.maximumHeight: navigationFeatureButton.height + Layout.fillHeight: true + } + FeatureButton { + text: qsTr("Seats") + icon.name: "seats" + + Layout.maximumHeight: navigationFeatureButton.height + Layout.fillHeight: true + } + FeatureButton { + text: qsTr("Statistics") + icon.name: "statistics" + + Layout.maximumHeight: navigationFeatureButton.height + Layout.fillHeight: true + } + } + } + } +} diff --git a/examples/quickcontrols2/imagine/automotive/qml/qml.qrc b/examples/quickcontrols2/imagine/automotive/qml/qml.qrc new file mode 100644 index 00000000000..b0e4e558a8d --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/qml/qml.qrc @@ -0,0 +1,7 @@ + + + FeatureButton.qml + automotive.qml + LargeLabel.qml + + diff --git a/examples/quickcontrols2/imagine/automotive/qtquickcontrols2.conf b/examples/quickcontrols2/imagine/automotive/qtquickcontrols2.conf new file mode 100644 index 00000000000..c7fc7a61698 --- /dev/null +++ b/examples/quickcontrols2/imagine/automotive/qtquickcontrols2.conf @@ -0,0 +1,10 @@ +[Controls] +Style=Imagine + +[Imagine] +Path=:/imagine-assets + +[Imagine\Palette] +Text=#6affcd +ButtonText=#6affcd +WindowText=#6affcd diff --git a/examples/quickcontrols2/imagine/musicplayer/CMakeLists.txt b/examples/quickcontrols2/imagine/musicplayer/CMakeLists.txt new file mode 100644 index 00000000000..0ca89d7ada9 --- /dev/null +++ b/examples/quickcontrols2/imagine/musicplayer/CMakeLists.txt @@ -0,0 +1,223 @@ +# Generated from musicplayer.pro. + +cmake_minimum_required(VERSION 3.16) +project(musicplayer LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/imagine/musicplayer") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS QuickControls2) + +qt_add_executable(musicplayer + musicplayer.cpp +) +set_target_properties(musicplayer PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(musicplayer PUBLIC + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) + + +# Resources: +set(icons_resource_files + "icons/musicplayer/32x32/bluetooth.png" + "icons/musicplayer/32x32/cart.png" + "icons/musicplayer/32x32/cloud.png" + "icons/musicplayer/32x32/favorite.png" + "icons/musicplayer/32x32/filter.png" + "icons/musicplayer/32x32/folder.png" + "icons/musicplayer/32x32/message.png" + "icons/musicplayer/32x32/music.png" + "icons/musicplayer/32x32/next.png" + "icons/musicplayer/32x32/pause.png" + "icons/musicplayer/32x32/power.png" + "icons/musicplayer/32x32/previous.png" + "icons/musicplayer/32x32/repeat.png" + "icons/musicplayer/32x32/save.png" + "icons/musicplayer/32x32/settings.png" + "icons/musicplayer/32x32/shuffle.png" + "icons/musicplayer/32x32/stop.png" + "icons/musicplayer/32x32@2/bluetooth.png" + "icons/musicplayer/32x32@2/cart.png" + "icons/musicplayer/32x32@2/cloud.png" + "icons/musicplayer/32x32@2/favorite.png" + "icons/musicplayer/32x32@2/filter.png" + "icons/musicplayer/32x32@2/folder.png" + "icons/musicplayer/32x32@2/grid.png" + "icons/musicplayer/32x32@2/message.png" + "icons/musicplayer/32x32@2/music.png" + "icons/musicplayer/32x32@2/next.png" + "icons/musicplayer/32x32@2/pause.png" + "icons/musicplayer/32x32@2/power.png" + "icons/musicplayer/32x32@2/previous.png" + "icons/musicplayer/32x32@2/repeat.png" + "icons/musicplayer/32x32@2/save.png" + "icons/musicplayer/32x32@2/settings.png" + "icons/musicplayer/32x32@2/shuffle.png" + "icons/musicplayer/32x32@2/stop.png" + "icons/musicplayer/index.theme" +) + +qt6_add_resources(musicplayer "icons" + PREFIX + "/icons" + BASE + "icons" + FILES + ${icons_resource_files} +) +set(imagine-assets_resource_files + "imagine-assets/applicationwindow-background.png" + "imagine-assets/button-background-checked-hovered.9.png" + "imagine-assets/button-background-checked-hovered@2x.9.png" + "imagine-assets/button-background-checked.9.png" + "imagine-assets/button-background-checked@2x.9.png" + "imagine-assets/button-background-disabled.9.png" + "imagine-assets/button-background-disabled@2x.9.png" + "imagine-assets/button-background-hovered.9.png" + "imagine-assets/button-background-hovered@2x.9.png" + "imagine-assets/button-background-pressed.9.png" + "imagine-assets/button-background-pressed@2x.9.png" + "imagine-assets/button-background.9.png" + "imagine-assets/button-background@2x.9.png" + "imagine-assets/combobox-background-hovered.9.png" + "imagine-assets/combobox-background-hovered@2x.9.png" + "imagine-assets/combobox-background-open.9.png" + "imagine-assets/combobox-background-open@2x.9.png" + "imagine-assets/combobox-background-pressed.9.png" + "imagine-assets/combobox-background-pressed@2x.9.png" + "imagine-assets/combobox-background.9.png" + "imagine-assets/combobox-background@2x.9.png" + "imagine-assets/combobox-indicator-hovered.png" + "imagine-assets/combobox-indicator-hovered@2x.png" + "imagine-assets/combobox-indicator-open.png" + "imagine-assets/combobox-indicator-open@2x.png" + "imagine-assets/combobox-indicator-pressed.png" + "imagine-assets/combobox-indicator-pressed@2x.png" + "imagine-assets/combobox-indicator.png" + "imagine-assets/combobox-indicator@2x.png" + "imagine-assets/combobox-popup.9.png" + "imagine-assets/combobox-popup@2x.9.png" + "imagine-assets/dial-background-hovered.png" + "imagine-assets/dial-background-hovered@2x.png" + "imagine-assets/dial-background-pressed.png" + "imagine-assets/dial-background-pressed@2x.png" + "imagine-assets/dial-background.png" + "imagine-assets/dial-background@2x.png" + "imagine-assets/dial-handle-pressed.png" + "imagine-assets/dial-handle-pressed@2x.png" + "imagine-assets/dial-handle.png" + "imagine-assets/dial-handle@2x.png" + "imagine-assets/frame-background.9.png" + "imagine-assets/frame-background@2x.9.png" + "imagine-assets/itemdelegate-background-checked.9.png" + "imagine-assets/itemdelegate-background-checked@2x.9.png" + "imagine-assets/itemdelegate-background-disabled.9.png" + "imagine-assets/itemdelegate-background-disabled@2x.9.png" + "imagine-assets/itemdelegate-background-hovered.9.png" + "imagine-assets/itemdelegate-background-hovered@2x.9.png" + "imagine-assets/itemdelegate-background-pressed.9.png" + "imagine-assets/itemdelegate-background-pressed@2x.9.png" + "imagine-assets/itemdelegate-background.9.png" + "imagine-assets/itemdelegate-background@2x.9.png" + "imagine-assets/roundbutton-background-checked-hovered.png" + "imagine-assets/roundbutton-background-checked-hovered@2x.png" + "imagine-assets/roundbutton-background-checked.png" + "imagine-assets/roundbutton-background-checked@2x.png" + "imagine-assets/roundbutton-background-disabled.png" + "imagine-assets/roundbutton-background-disabled@2x.png" + "imagine-assets/roundbutton-background-hovered.png" + "imagine-assets/roundbutton-background-hovered@2x.png" + "imagine-assets/roundbutton-background-pressed.png" + "imagine-assets/roundbutton-background-pressed@2x.png" + "imagine-assets/roundbutton-background.png" + "imagine-assets/roundbutton-background@2x.png" + "imagine-assets/scrollbar-handle-interactive-hovered.png" + "imagine-assets/scrollbar-handle-interactive-hovered@2x.png" + "imagine-assets/scrollbar-handle-interactive-pressed.png" + "imagine-assets/scrollbar-handle-interactive-pressed@2x.png" + "imagine-assets/scrollbar-handle-interactive.png" + "imagine-assets/scrollbar-handle-interactive@2x.png" + "imagine-assets/slider-background-horizontal-disabled.9.png" + "imagine-assets/slider-background-horizontal-disabled@2x.9.png" + "imagine-assets/slider-background-horizontal.9.png" + "imagine-assets/slider-background-horizontal@2x.9.png" + "imagine-assets/slider-background-vertical-disabled.9.png" + "imagine-assets/slider-background-vertical-disabled@2x.9.png" + "imagine-assets/slider-background-vertical.9.png" + "imagine-assets/slider-background-vertical@2x.9.png" + "imagine-assets/slider-handle-disabled.png" + "imagine-assets/slider-handle-disabled@2x.png" + "imagine-assets/slider-handle-hovered.png" + "imagine-assets/slider-handle-hovered@2x.png" + "imagine-assets/slider-handle.png" + "imagine-assets/slider-handle@2x.png" + "imagine-assets/slider-progress-horizontal.9.png" + "imagine-assets/slider-progress-horizontal@2x.9.png" + "imagine-assets/slider-progress-vertical-disabled.9.png" + "imagine-assets/slider-progress-vertical-disabled@2x.9.png" + "imagine-assets/slider-progress-vertical.9.png" + "imagine-assets/slider-progress-vertical@2x.9.png" + "imagine-assets/textfield-background-disabled.9.png" + "imagine-assets/textfield-background-disabled@2x.9.png" + "imagine-assets/textfield-background.9.png" + "imagine-assets/textfield-background@2x.9.png" + "imagine-assets/toolbar-background.9.png" + "imagine-assets/toolbar-background@2x.9.png" + "imagine-assets/toolbutton-background-checked-hovered.9.png" + "imagine-assets/toolbutton-background-checked-hovered@2x.9.png" + "imagine-assets/toolbutton-background-checked.9.png" + "imagine-assets/toolbutton-background-checked@2x.9.png" + "imagine-assets/toolbutton-background-hovered.9.png" + "imagine-assets/toolbutton-background-hovered@2x.9.png" + "imagine-assets/toolbutton-background-pressed.9.png" + "imagine-assets/toolbutton-background-pressed@2x.9.png" + "imagine-assets/toolbutton-background.9.png" + "imagine-assets/toolbutton-background@2x.9.png" + "imagine-assets/tooltip-background.9.png" + "imagine-assets/tooltip-background@2x.9.png" +) + +qt6_add_resources(musicplayer "imagine-assets" + PREFIX + "/imagine-assets" + BASE + "imagine-assets" + FILES + ${imagine-assets_resource_files} +) +set(qmake_immediate_resource_files + "images/album-cover.jpg" + "musicplayer.qml" + "qtquickcontrols2.conf" +) + +qt6_add_resources(musicplayer "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + +install(TARGETS musicplayer + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/imagine/musicplayer/doc/images/qtquickcontrols2-musicplayer.png b/examples/quickcontrols2/imagine/musicplayer/doc/images/qtquickcontrols2-musicplayer.png new file mode 100644 index 00000000000..25b6344f3e0 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/doc/images/qtquickcontrols2-musicplayer.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/doc/src/qtquickcontrols2-musicplayer.qdoc b/examples/quickcontrols2/imagine/musicplayer/doc/src/qtquickcontrols2-musicplayer.qdoc new file mode 100644 index 00000000000..28d298e7ce1 --- /dev/null +++ b/examples/quickcontrols2/imagine/musicplayer/doc/src/qtquickcontrols2-musicplayer.qdoc @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example imagine/musicplayer + \keyword Qt Quick Controls - Imagine Style Example: Music Player + \title Qt Quick Controls - Imagine Style Example: Music Player + \keyword Qt Quick Controls 2 - Imagine Style Example: Music Player + \ingroup qtquickcontrols2-examples + \brief An audio player user interface using custom Imagine style assets. + + This example demonstrates how custom Imagine style assets + can be used to style a user interface for an audio player application. + + \image qtquickcontrols2-musicplayer.png + + \omit + The assets are generated from a Photoshop file: \e musicplayer.psd. + This file can found in the \e design folder in the example directory. + All objects related to a particular asset are collected in a layer group. + For example, the assets for Button's background element are under a layer group with the following name: + + \badcode + 100% button-background.9.png, 200% button-background@2x.9.png, 300% button-background@3x.9.png, 400% button-background@4x.9.png + \endcode + + Using Photoshop's \l {Generate Image Assets}{https://helpx.adobe.com/photoshop/using/generate-assets-layers.html} feature, + the size and name for each asset are encoded into the name of the layer group. + + Where applicable, \l {Smart Objects}{https://helpx.adobe.com/photoshop/using/create-smart-objects.html} + are used to reduce duplication for common objects such as 9-patch lines. + \endomit + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/icons.qrc b/examples/quickcontrols2/imagine/musicplayer/icons/icons.qrc new file mode 100644 index 00000000000..870b4445e59 --- /dev/null +++ b/examples/quickcontrols2/imagine/musicplayer/icons/icons.qrc @@ -0,0 +1,40 @@ + + + musicplayer/index.theme + musicplayer/32x32/bluetooth.png + musicplayer/32x32/cart.png + musicplayer/32x32/cloud.png + musicplayer/32x32/filter.png + musicplayer/32x32/folder.png + musicplayer/32x32/message.png + musicplayer/32x32/music.png + musicplayer/32x32/next.png + musicplayer/32x32/pause.png + musicplayer/32x32/power.png + musicplayer/32x32/previous.png + musicplayer/32x32/repeat.png + musicplayer/32x32/save.png + musicplayer/32x32/settings.png + musicplayer/32x32/shuffle.png + musicplayer/32x32/stop.png + musicplayer/32x32@2/bluetooth.png + musicplayer/32x32@2/cart.png + musicplayer/32x32@2/cloud.png + musicplayer/32x32@2/filter.png + musicplayer/32x32@2/folder.png + musicplayer/32x32@2/grid.png + musicplayer/32x32@2/message.png + musicplayer/32x32@2/music.png + musicplayer/32x32@2/next.png + musicplayer/32x32@2/pause.png + musicplayer/32x32@2/power.png + musicplayer/32x32@2/previous.png + musicplayer/32x32@2/repeat.png + musicplayer/32x32@2/save.png + musicplayer/32x32@2/settings.png + musicplayer/32x32@2/shuffle.png + musicplayer/32x32@2/stop.png + musicplayer/32x32/favorite.png + musicplayer/32x32@2/favorite.png + + diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/bluetooth.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/bluetooth.png new file mode 100644 index 00000000000..925f564c9e7 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/bluetooth.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/cart.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/cart.png new file mode 100644 index 00000000000..4d5ad099553 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/cart.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/cloud.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/cloud.png new file mode 100644 index 00000000000..62ef5118336 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/cloud.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/favorite.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/favorite.png new file mode 100644 index 00000000000..16ea84deb65 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/favorite.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/filter.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/filter.png new file mode 100644 index 00000000000..4472cead58a Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/filter.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/folder.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/folder.png new file mode 100644 index 00000000000..5dd05778fd6 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/folder.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/message.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/message.png new file mode 100644 index 00000000000..1d93b3c6603 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/message.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/music.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/music.png new file mode 100644 index 00000000000..44489213896 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/music.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/next.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/next.png new file mode 100644 index 00000000000..ab9164e8774 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/next.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/pause.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/pause.png new file mode 100644 index 00000000000..9c9ef8fa604 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/pause.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/power.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/power.png new file mode 100644 index 00000000000..8f7d0c778cc Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/power.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/previous.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/previous.png new file mode 100644 index 00000000000..3a0880fdbc1 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/previous.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/repeat.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/repeat.png new file mode 100644 index 00000000000..7c8e8c1c2d3 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/repeat.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/save.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/save.png new file mode 100644 index 00000000000..c0b27483270 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/save.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/settings.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/settings.png new file mode 100644 index 00000000000..7992146a6ea Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/settings.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/shuffle.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/shuffle.png new file mode 100644 index 00000000000..885782a2193 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/shuffle.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/stop.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/stop.png new file mode 100644 index 00000000000..3e9c332732b Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32/stop.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/bluetooth.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/bluetooth.png new file mode 100644 index 00000000000..2e70afc396c Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/bluetooth.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/cart.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/cart.png new file mode 100644 index 00000000000..5717dd65822 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/cart.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/cloud.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/cloud.png new file mode 100644 index 00000000000..ce5ab9f9912 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/cloud.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/favorite.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/favorite.png new file mode 100644 index 00000000000..ddc9aa45c88 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/favorite.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/filter.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/filter.png new file mode 100644 index 00000000000..3632c556fe9 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/filter.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/folder.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/folder.png new file mode 100644 index 00000000000..49d41e202e0 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/folder.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/grid.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/grid.png new file mode 100644 index 00000000000..8a1624e70b6 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/grid.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/message.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/message.png new file mode 100644 index 00000000000..6650f26b6a9 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/message.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/music.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/music.png new file mode 100644 index 00000000000..2cb8d49a676 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/music.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/next.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/next.png new file mode 100644 index 00000000000..d7bb4b278e8 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/next.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/pause.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/pause.png new file mode 100644 index 00000000000..8a081d02f33 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/pause.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/power.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/power.png new file mode 100644 index 00000000000..1201e55b4f1 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/power.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/previous.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/previous.png new file mode 100644 index 00000000000..4236afdbbd7 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/previous.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/repeat.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/repeat.png new file mode 100644 index 00000000000..c8cb06d84d4 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/repeat.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/save.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/save.png new file mode 100644 index 00000000000..448b25e4be7 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/save.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/settings.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/settings.png new file mode 100644 index 00000000000..12a0cf6b763 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/settings.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/shuffle.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/shuffle.png new file mode 100644 index 00000000000..22b901cce9e Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/shuffle.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/stop.png b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/stop.png new file mode 100644 index 00000000000..0521a943d41 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/32x32@2/stop.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/icons.svg b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/icons.svg new file mode 100644 index 00000000000..4cede992c35 --- /dev/null +++ b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/icons.svg @@ -0,0 +1,648 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/index.theme b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/index.theme new file mode 100644 index 00000000000..2523293552f --- /dev/null +++ b/examples/quickcontrols2/imagine/musicplayer/icons/musicplayer/index.theme @@ -0,0 +1,14 @@ +[Icon Theme] +Name=Music Player +Comment=Icon theme for the Qt Quick Controls 2 Music Player Imagine Style Example + +Directories=32x32,32x32@2 + +[32x32] +Size=32 +Type=Fixed + +[32x32@2] +Size=32 +Scale=2 +Type=Fixed diff --git a/examples/quickcontrols2/imagine/musicplayer/images/album-cover.jpg b/examples/quickcontrols2/imagine/musicplayer/images/album-cover.jpg new file mode 100644 index 00000000000..48bd6231ba9 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/images/album-cover.jpg differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/applicationwindow-background.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/applicationwindow-background.png new file mode 100644 index 00000000000..036bf74692f Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/applicationwindow-background.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-checked-hovered.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-checked-hovered.9.png new file mode 100644 index 00000000000..c275d3242d8 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-checked-hovered.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-checked-hovered@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-checked-hovered@2x.9.png new file mode 100644 index 00000000000..eec285f3058 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-checked-hovered@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-checked.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-checked.9.png new file mode 100644 index 00000000000..2d284a5bc89 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-checked.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-checked@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-checked@2x.9.png new file mode 100644 index 00000000000..fec385f539d Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-checked@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-disabled.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-disabled.9.png new file mode 100644 index 00000000000..bcad147094e Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-disabled.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-disabled@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-disabled@2x.9.png new file mode 100644 index 00000000000..03aba1535ca Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-disabled@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-hovered.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-hovered.9.png new file mode 100644 index 00000000000..962cf6778ed Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-hovered.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-hovered@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-hovered@2x.9.png new file mode 100644 index 00000000000..841c0064e7f Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-hovered@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-pressed.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-pressed.9.png new file mode 100644 index 00000000000..f97f42b8097 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-pressed.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-pressed@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-pressed@2x.9.png new file mode 100644 index 00000000000..970583495c2 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background-pressed@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background.9.png new file mode 100644 index 00000000000..74a8574fd3f Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background@2x.9.png new file mode 100644 index 00000000000..251633853e9 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/button-background@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-hovered.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-hovered.9.png new file mode 100644 index 00000000000..f9f90df4f44 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-hovered.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-hovered@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-hovered@2x.9.png new file mode 100644 index 00000000000..a4be50e1546 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-hovered@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-open.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-open.9.png new file mode 100644 index 00000000000..147231ecb7c Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-open.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-open@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-open@2x.9.png new file mode 100644 index 00000000000..0a978572e7d Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-open@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-pressed.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-pressed.9.png new file mode 100644 index 00000000000..7726198ab1d Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-pressed.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-pressed@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-pressed@2x.9.png new file mode 100644 index 00000000000..d64d4052391 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background-pressed@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background.9.png new file mode 100644 index 00000000000..e919d50aa00 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background@2x.9.png new file mode 100644 index 00000000000..5effba7e8b1 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-background@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-hovered.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-hovered.png new file mode 100644 index 00000000000..78b0650555c Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-hovered.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-hovered@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-hovered@2x.png new file mode 100644 index 00000000000..ec3c8734c88 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-hovered@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-open.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-open.png new file mode 100644 index 00000000000..7a831632fec Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-open.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-open@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-open@2x.png new file mode 100644 index 00000000000..47c664a2c81 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-open@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-pressed.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-pressed.png new file mode 100644 index 00000000000..3340294f058 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-pressed.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-pressed@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-pressed@2x.png new file mode 100644 index 00000000000..aa35b88200d Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator-pressed@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator.png new file mode 100644 index 00000000000..2c7f557819c Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator@2x.png new file mode 100644 index 00000000000..20b9c44c345 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-indicator@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-popup.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-popup.9.png new file mode 100644 index 00000000000..cae75cd78e4 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-popup.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-popup@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-popup@2x.9.png new file mode 100644 index 00000000000..392607bcdf1 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/combobox-popup@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background-hovered.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background-hovered.png new file mode 100644 index 00000000000..ac614678b3a Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background-hovered.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background-hovered@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background-hovered@2x.png new file mode 100644 index 00000000000..b13783c23a4 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background-hovered@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background-pressed.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background-pressed.png new file mode 100644 index 00000000000..1bd74acac69 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background-pressed.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background-pressed@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background-pressed@2x.png new file mode 100644 index 00000000000..ffd7d009eb8 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background-pressed@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background.png new file mode 100644 index 00000000000..c81fcb700bf Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background@2x.png new file mode 100644 index 00000000000..be3e15476b7 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-background@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-handle-pressed.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-handle-pressed.png new file mode 100644 index 00000000000..d27f9355d5a Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-handle-pressed.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-handle-pressed@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-handle-pressed@2x.png new file mode 100644 index 00000000000..a44e141066b Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-handle-pressed@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-handle.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-handle.png new file mode 100644 index 00000000000..9992a839909 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-handle.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-handle@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-handle@2x.png new file mode 100644 index 00000000000..8816482a088 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/dial-handle@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/frame-background.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/frame-background.9.png new file mode 100644 index 00000000000..1e436f2b360 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/frame-background.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/frame-background@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/frame-background@2x.9.png new file mode 100644 index 00000000000..abdf3ab8e3c Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/frame-background@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/imagine-assets.qrc b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/imagine-assets.qrc new file mode 100644 index 00000000000..7bda4995d40 --- /dev/null +++ b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/imagine-assets.qrc @@ -0,0 +1,113 @@ + + + applicationwindow-background.png + button-background-checked-hovered.9.png + button-background-checked-hovered@2x.9.png + button-background-checked.9.png + button-background-checked@2x.9.png + button-background-disabled.9.png + button-background-disabled@2x.9.png + button-background-hovered.9.png + button-background-hovered@2x.9.png + button-background-pressed.9.png + button-background-pressed@2x.9.png + button-background.9.png + button-background@2x.9.png + combobox-background-hovered.9.png + combobox-background-hovered@2x.9.png + combobox-background-open.9.png + combobox-background-open@2x.9.png + combobox-background-pressed.9.png + combobox-background-pressed@2x.9.png + combobox-background.9.png + combobox-background@2x.9.png + combobox-indicator-hovered.png + combobox-indicator-hovered@2x.png + combobox-indicator-open.png + combobox-indicator-open@2x.png + combobox-indicator-pressed.png + combobox-indicator-pressed@2x.png + combobox-indicator.png + combobox-indicator@2x.png + combobox-popup.9.png + combobox-popup@2x.9.png + dial-background-hovered.png + dial-background-hovered@2x.png + dial-background-pressed.png + dial-background-pressed@2x.png + dial-background.png + dial-background@2x.png + dial-handle-pressed.png + dial-handle-pressed@2x.png + dial-handle.png + dial-handle@2x.png + frame-background.9.png + frame-background@2x.9.png + itemdelegate-background-checked.9.png + itemdelegate-background-checked@2x.9.png + itemdelegate-background-disabled.9.png + itemdelegate-background-disabled@2x.9.png + itemdelegate-background-hovered.9.png + itemdelegate-background-hovered@2x.9.png + itemdelegate-background-pressed.9.png + itemdelegate-background-pressed@2x.9.png + itemdelegate-background.9.png + itemdelegate-background@2x.9.png + roundbutton-background-checked-hovered.png + roundbutton-background-checked-hovered@2x.png + roundbutton-background-checked.png + roundbutton-background-checked@2x.png + roundbutton-background-disabled.png + roundbutton-background-disabled@2x.png + roundbutton-background-hovered.png + roundbutton-background-hovered@2x.png + roundbutton-background-pressed.png + roundbutton-background-pressed@2x.png + roundbutton-background.png + roundbutton-background@2x.png + scrollbar-handle-interactive-hovered.png + scrollbar-handle-interactive-hovered@2x.png + scrollbar-handle-interactive-pressed.png + scrollbar-handle-interactive-pressed@2x.png + scrollbar-handle-interactive.png + scrollbar-handle-interactive@2x.png + slider-background-horizontal-disabled.9.png + slider-background-horizontal-disabled@2x.9.png + slider-background-horizontal.9.png + slider-background-horizontal@2x.9.png + slider-background-vertical-disabled.9.png + slider-background-vertical-disabled@2x.9.png + slider-background-vertical.9.png + slider-background-vertical@2x.9.png + slider-handle-disabled.png + slider-handle-disabled@2x.png + slider-handle-hovered.png + slider-handle-hovered@2x.png + slider-handle.png + slider-handle@2x.png + slider-progress-horizontal.9.png + slider-progress-horizontal@2x.9.png + slider-progress-vertical-disabled.9.png + slider-progress-vertical-disabled@2x.9.png + slider-progress-vertical.9.png + slider-progress-vertical@2x.9.png + textfield-background-disabled.9.png + textfield-background-disabled@2x.9.png + textfield-background.9.png + textfield-background@2x.9.png + toolbar-background.9.png + toolbar-background@2x.9.png + toolbutton-background-checked-hovered.9.png + toolbutton-background-checked-hovered@2x.9.png + toolbutton-background-checked.9.png + toolbutton-background-checked@2x.9.png + toolbutton-background-hovered.9.png + toolbutton-background-hovered@2x.9.png + toolbutton-background-pressed.9.png + toolbutton-background-pressed@2x.9.png + toolbutton-background.9.png + toolbutton-background@2x.9.png + tooltip-background.9.png + tooltip-background@2x.9.png + + diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-checked.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-checked.9.png new file mode 100644 index 00000000000..6c7915aab9c Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-checked.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-checked@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-checked@2x.9.png new file mode 100644 index 00000000000..24ddbce09a0 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-checked@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-disabled.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-disabled.9.png new file mode 100644 index 00000000000..65a670ebb52 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-disabled.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-disabled@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-disabled@2x.9.png new file mode 100644 index 00000000000..df81dd0a982 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-disabled@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-hovered.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-hovered.9.png new file mode 100644 index 00000000000..a8eb9e7a13e Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-hovered.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-hovered@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-hovered@2x.9.png new file mode 100644 index 00000000000..23559a28b40 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-hovered@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-pressed.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-pressed.9.png new file mode 100644 index 00000000000..7d7a2bb9609 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-pressed.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-pressed@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-pressed@2x.9.png new file mode 100644 index 00000000000..911563fc0ec Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background-pressed@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background.9.png new file mode 100644 index 00000000000..65a670ebb52 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background@2x.9.png new file mode 100644 index 00000000000..df81dd0a982 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/itemdelegate-background@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-checked-hovered.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-checked-hovered.png new file mode 100644 index 00000000000..fae98b91b7f Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-checked-hovered.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-checked-hovered@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-checked-hovered@2x.png new file mode 100644 index 00000000000..1b575b0354e Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-checked-hovered@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-checked.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-checked.png new file mode 100644 index 00000000000..859232e2e53 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-checked.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-checked@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-checked@2x.png new file mode 100644 index 00000000000..ef147a334a0 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-checked@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-disabled.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-disabled.png new file mode 100644 index 00000000000..862f4a26d89 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-disabled.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-disabled@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-disabled@2x.png new file mode 100644 index 00000000000..f99e11fd080 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-disabled@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-hovered.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-hovered.png new file mode 100644 index 00000000000..6239eb32148 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-hovered.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-hovered@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-hovered@2x.png new file mode 100644 index 00000000000..aa2e8f46d8e Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-hovered@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-pressed.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-pressed.png new file mode 100644 index 00000000000..81d2cd74429 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-pressed.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-pressed@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-pressed@2x.png new file mode 100644 index 00000000000..fd82c0c38c7 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background-pressed@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background.png new file mode 100644 index 00000000000..ab2e9ceea88 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background@2x.png new file mode 100644 index 00000000000..33e81bf6193 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/roundbutton-background@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-hovered.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-hovered.png new file mode 100644 index 00000000000..2657743a819 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-hovered.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-hovered@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-hovered@2x.png new file mode 100644 index 00000000000..60ade78071e Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-hovered@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-pressed.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-pressed.png new file mode 100644 index 00000000000..626ab8b6bbb Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-pressed.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-pressed@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-pressed@2x.png new file mode 100644 index 00000000000..92789571d19 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-pressed@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive.png new file mode 100644 index 00000000000..a7a73471208 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive@2x.png new file mode 100644 index 00000000000..837e1795530 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-horizontal-disabled.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-horizontal-disabled.9.png new file mode 100644 index 00000000000..f45f5888380 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-horizontal-disabled.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-horizontal-disabled@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-horizontal-disabled@2x.9.png new file mode 100644 index 00000000000..40e6d505672 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-horizontal-disabled@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-horizontal.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-horizontal.9.png new file mode 100644 index 00000000000..a465f300ccb Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-horizontal.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-horizontal@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-horizontal@2x.9.png new file mode 100644 index 00000000000..7a3170f5296 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-horizontal@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-vertical-disabled.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-vertical-disabled.9.png new file mode 100644 index 00000000000..0bee2685a04 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-vertical-disabled.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-vertical-disabled@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-vertical-disabled@2x.9.png new file mode 100644 index 00000000000..7fed90c816b Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-vertical-disabled@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-vertical.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-vertical.9.png new file mode 100644 index 00000000000..a5074864b0e Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-vertical.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-vertical@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-vertical@2x.9.png new file mode 100644 index 00000000000..a3974ebe3c0 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-background-vertical@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle-disabled.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle-disabled.png new file mode 100644 index 00000000000..02a9df388d4 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle-disabled.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle-disabled@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle-disabled@2x.png new file mode 100644 index 00000000000..b37cef32723 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle-disabled@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle-hovered.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle-hovered.png new file mode 100644 index 00000000000..2048aa6b07c Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle-hovered.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle-hovered@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle-hovered@2x.png new file mode 100644 index 00000000000..0515be8e113 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle-hovered@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle.png new file mode 100644 index 00000000000..2a80f27f27f Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle@2x.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle@2x.png new file mode 100644 index 00000000000..29447041183 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-handle@2x.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-horizontal.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-horizontal.9.png new file mode 100644 index 00000000000..1224522f9dd Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-horizontal.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-horizontal@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-horizontal@2x.9.png new file mode 100644 index 00000000000..c304bfe5ad7 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-horizontal@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-vertical-disabled.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-vertical-disabled.9.png new file mode 100644 index 00000000000..0e7b08bd0e9 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-vertical-disabled.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-vertical-disabled@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-vertical-disabled@2x.9.png new file mode 100644 index 00000000000..d9654ceec46 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-vertical-disabled@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-vertical.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-vertical.9.png new file mode 100644 index 00000000000..928ff864f0b Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-vertical.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-vertical@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-vertical@2x.9.png new file mode 100644 index 00000000000..3d640b277a5 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/slider-progress-vertical@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/textfield-background-disabled.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/textfield-background-disabled.9.png new file mode 100644 index 00000000000..de557cbc5fa Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/textfield-background-disabled.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/textfield-background-disabled@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/textfield-background-disabled@2x.9.png new file mode 100644 index 00000000000..23984d715db Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/textfield-background-disabled@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/textfield-background.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/textfield-background.9.png new file mode 100644 index 00000000000..0dc163a4a34 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/textfield-background.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/textfield-background@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/textfield-background@2x.9.png new file mode 100644 index 00000000000..41aae23d7fb Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/textfield-background@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbar-background.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbar-background.9.png new file mode 100644 index 00000000000..ab2f47e2430 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbar-background.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbar-background@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbar-background@2x.9.png new file mode 100644 index 00000000000..7e389fe0f00 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbar-background@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-checked-hovered.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-checked-hovered.9.png new file mode 100644 index 00000000000..3acf92e12a9 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-checked-hovered.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-checked-hovered@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-checked-hovered@2x.9.png new file mode 100644 index 00000000000..0f43f933371 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-checked-hovered@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-checked.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-checked.9.png new file mode 100644 index 00000000000..ff0faa567be Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-checked.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-checked@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-checked@2x.9.png new file mode 100644 index 00000000000..694f5eab88d Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-checked@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-hovered.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-hovered.9.png new file mode 100644 index 00000000000..c60e64d10cc Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-hovered.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-hovered@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-hovered@2x.9.png new file mode 100644 index 00000000000..d0103202bd1 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-hovered@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-pressed.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-pressed.9.png new file mode 100644 index 00000000000..f2ec9c6e4b9 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-pressed.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-pressed@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-pressed@2x.9.png new file mode 100644 index 00000000000..e3a86911eea Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background-pressed@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background.9.png new file mode 100644 index 00000000000..a292ac09590 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background@2x.9.png new file mode 100644 index 00000000000..6f8880c3938 Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/toolbutton-background@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/tooltip-background.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/tooltip-background.9.png new file mode 100644 index 00000000000..a74441c92ac Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/tooltip-background.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/imagine-assets/tooltip-background@2x.9.png b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/tooltip-background@2x.9.png new file mode 100644 index 00000000000..d4b20b74b3a Binary files /dev/null and b/examples/quickcontrols2/imagine/musicplayer/imagine-assets/tooltip-background@2x.9.png differ diff --git a/examples/quickcontrols2/imagine/musicplayer/musicplayer.cpp b/examples/quickcontrols2/imagine/musicplayer/musicplayer.cpp new file mode 100644 index 00000000000..bd125625b16 --- /dev/null +++ b/examples/quickcontrols2/imagine/musicplayer/musicplayer.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication::setApplicationName("Music Player"); + QGuiApplication::setOrganizationName("QtProject"); + + QGuiApplication app(argc, argv); + + QIcon::setThemeName("musicplayer"); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/musicplayer.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols2/imagine/musicplayer/musicplayer.pro b/examples/quickcontrols2/imagine/musicplayer/musicplayer.pro new file mode 100644 index 00000000000..b1970ee905a --- /dev/null +++ b/examples/quickcontrols2/imagine/musicplayer/musicplayer.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +TARGET = musicplayer +QT += quick quickcontrols2 + +SOURCES += \ + musicplayer.cpp + +RESOURCES += \ + icons/icons.qrc \ + images/album-cover.jpg \ + imagine-assets/imagine-assets.qrc \ + qtquickcontrols2.conf \ + musicplayer.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/imagine/musicplayer +INSTALLS += target diff --git a/examples/quickcontrols2/imagine/musicplayer/musicplayer.qml b/examples/quickcontrols2/imagine/musicplayer/musicplayer.qml new file mode 100644 index 00000000000..1fa7bcf8a57 --- /dev/null +++ b/examples/quickcontrols2/imagine/musicplayer/musicplayer.qml @@ -0,0 +1,467 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Window + +ApplicationWindow { + id: window + width: 1280 + height: 720 + visible: true + title: "Qt Quick Controls - Imagine Style Example: Music Player" + + Component.onCompleted: { + x = Screen.width / 2 - width / 2 + y = Screen.height / 2 - height / 2 + } + + Shortcut { + sequence: "Ctrl+Q" + onActivated: Qt.quit() + } + + header: ToolBar { + RowLayout { + id: headerRowLayout + anchors.fill: parent + spacing: 0 + + ToolButton { + icon.name: "grid" + } + ToolButton { + icon.name: "settings" + } + ToolButton { + icon.name: "filter" + } + ToolButton { + icon.name: "message" + } + ToolButton { + icon.name: "music" + } + ToolButton { + icon.name: "cloud" + } + ToolButton { + icon.name: "bluetooth" + } + ToolButton { + icon.name: "cart" + } + + Item { + Layout.fillWidth: true + } + + ToolButton { + icon.name: "power" + onClicked: Qt.quit() + } + } + } + + Label { + text: "Qtify" + font.pixelSize: Qt.application.font.pixelSize * 1.3 + anchors.centerIn: header + z: header.z + 1 + } + + RowLayout { + spacing: 115 + anchors.fill: parent + anchors.margins: 70 + + ColumnLayout { + spacing: 0 + Layout.preferredWidth: 230 + + RowLayout { + Layout.maximumHeight: 170 + + ColumnLayout { + Label { + text: "12 dB" + Layout.fillHeight: true + } + Label { + text: "6 dB" + Layout.fillHeight: true + } + Label { + text: "0 dB" + Layout.fillHeight: true + } + Label { + text: "-6 dB" + Layout.fillHeight: true + } + Label { + text: "-12 dB" + Layout.fillHeight: true + } + } + + Repeater { + model: 7 + + Slider { + value: Math.random() + orientation: Qt.Vertical + + Layout.fillWidth: true + Layout.fillHeight: true + } + } + } + + RowLayout { + spacing: 10 + Layout.topMargin: 23 + + ComboBox { + currentIndex: 1 + model: ["Blues", "Classical", "Jazz", "Metal"] + Layout.fillWidth: true + } + + Button { + icon.name: "folder" + } + + Button { + icon.name: "save" + enabled: false + } + } + + Dial { + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 50 + } + + Label { + text: "Volume" + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 12 + } + } + + ColumnLayout { + spacing: 26 + Layout.preferredWidth: 230 + + Item { + Layout.fillWidth: true + Layout.fillHeight: true + + Image { + anchors.fill: parent + fillMode: Image.PreserveAspectCrop + source: "images/album-cover.jpg" + } + } + + Item { + id: songLabelContainer + clip: true + + Layout.fillWidth: true + Layout.preferredHeight: songNameLabel.implicitHeight + + SequentialAnimation { + running: true + loops: Animation.Infinite + + PauseAnimation { + duration: 2000 + } + ParallelAnimation { + XAnimator { + target: songNameLabel + from: 0 + to: songLabelContainer.width - songNameLabel.implicitWidth + duration: 5000 + } + OpacityAnimator { + target: leftGradient + from: 0 + to: 1 + } + } + OpacityAnimator { + target: rightGradient + from: 1 + to: 0 + } + PauseAnimation { + duration: 1000 + } + OpacityAnimator { + target: rightGradient + from: 0 + to: 1 + } + ParallelAnimation { + XAnimator { + target: songNameLabel + from: songLabelContainer.width - songNameLabel.implicitWidth + to: 0 + duration: 5000 + } + OpacityAnimator { + target: leftGradient + from: 0 + to: 1 + } + } + OpacityAnimator { + target: leftGradient + from: 1 + to: 0 + } + } + + Rectangle { + id: leftGradient + gradient: Gradient { + GradientStop { + position: 0 + color: "#dfe4ea" + } + GradientStop { + position: 1 + color: "#00dfe4ea" + } + } + + width: height + height: parent.height + anchors.left: parent.left + z: 1 + rotation: -90 + opacity: 0 + } + + Label { + id: songNameLabel + text: "Edvard Grieg - In the Hall of the Mountain King" + font.pixelSize: Qt.application.font.pixelSize * 1.4 + } + + Rectangle { + id: rightGradient + gradient: Gradient { + GradientStop { + position: 0 + color: "#00dfe4ea" + } + GradientStop { + position: 1 + color: "#dfe4ea" + } + } + + width: height + height: parent.height + anchors.right: parent.right + rotation: -90 + } + } + + RowLayout { + spacing: 8 + Layout.alignment: Qt.AlignHCenter + + RoundButton { + icon.name: "favorite" + icon.width: 32 + icon.height: 32 + } + RoundButton { + icon.name: "stop" + icon.width: 32 + icon.height: 32 + } + RoundButton { + icon.name: "previous" + icon.width: 32 + icon.height: 32 + } + RoundButton { + icon.name: "pause" + icon.width: 32 + icon.height: 32 + } + RoundButton { + icon.name: "next" + icon.width: 32 + icon.height: 32 + } + RoundButton { + icon.name: "repeat" + icon.width: 32 + icon.height: 32 + } + RoundButton { + icon.name: "shuffle" + icon.width: 32 + icon.height: 32 + } + } + + Slider { + id: seekSlider + value: 113 + to: 261 + + Layout.fillWidth: true + + ToolTip { + parent: seekSlider.handle + visible: seekSlider.pressed + text: pad(Math.floor(value / 60)) + ":" + pad(Math.floor(value % 60)) + y: parent.height + + readonly property int value: seekSlider.valueAt(seekSlider.position) + + function pad(number) { + if (number <= 9) + return "0" + number; + return number; + } + } + } + } + + ColumnLayout { + spacing: 16 + Layout.preferredWidth: 230 + + ButtonGroup { + buttons: libraryRowLayout.children + } + + RowLayout { + id: libraryRowLayout + Layout.alignment: Qt.AlignHCenter + + Button { + text: "Files" + checked: true + } + Button { + text: "Playlists" + checkable: true + } + Button { + text: "Favourites" + checkable: true + } + } + + RowLayout { + TextField { + Layout.fillWidth: true + } + Button { + icon.name: "folder" + } + } + + Frame { + id: filesFrame + leftPadding: 1 + rightPadding: 1 + + Layout.fillWidth: true + Layout.fillHeight: true + + ListView { + id: filesListView + clip: true + anchors.fill: parent + model: ListModel { + Component.onCompleted: { + for (var i = 0; i < 100; ++i) { + append({ + author: "Author", + album: "Album", + track: "Track 0" + (i % 9 + 1), + }); + } + } + } + delegate: ItemDelegate { + text: model.author + " - " + model.album + " - " + model.track + width: filesListView.width + } + + ScrollBar.vertical: ScrollBar { + parent: filesFrame + policy: ScrollBar.AlwaysOn + anchors.top: parent.top + anchors.topMargin: filesFrame.topPadding + anchors.right: parent.right + anchors.rightMargin: 1 + anchors.bottom: parent.bottom + anchors.bottomMargin: filesFrame.bottomPadding + } + } + } + } + } +} diff --git a/examples/quickcontrols2/imagine/musicplayer/qtquickcontrols2.conf b/examples/quickcontrols2/imagine/musicplayer/qtquickcontrols2.conf new file mode 100644 index 00000000000..33eab6a5631 --- /dev/null +++ b/examples/quickcontrols2/imagine/musicplayer/qtquickcontrols2.conf @@ -0,0 +1,10 @@ +[Controls] +Style=Imagine + +[Imagine] +Path=:/imagine-assets + +[Imagine\Palette] +Text=#6b7b89 +ButtonText=#6b7b89 +WindowText=#6b7b89 diff --git a/examples/quickcontrols2/quickcontrols2.pro b/examples/quickcontrols2/quickcontrols2.pro new file mode 100644 index 00000000000..a9784d8620f --- /dev/null +++ b/examples/quickcontrols2/quickcontrols2.pro @@ -0,0 +1,13 @@ +TEMPLATE = subdirs +SUBDIRS += \ + gallery \ + chattutorial \ + texteditor \ + contactlist \ + sidepanel \ + swipetoremove \ + wearable \ + imagine/automotive \ + imagine/musicplayer + +qtHaveModule(widgets): SUBDIRS += flatstyle diff --git a/examples/quickcontrols2/sidepanel/CMakeLists.txt b/examples/quickcontrols2/sidepanel/CMakeLists.txt new file mode 100644 index 00000000000..2ab6d605a4d --- /dev/null +++ b/examples/quickcontrols2/sidepanel/CMakeLists.txt @@ -0,0 +1,59 @@ +# Generated from sidepanel.pro. + +cmake_minimum_required(VERSION 3.16) +project(sidepanel LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/sidepanel") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) + +qt_add_executable(sidepanel + sidepanel.cpp +) +set_target_properties(sidepanel PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(sidepanel PUBLIC + Qt::Core + Qt::Gui + Qt::Quick +) + + +# Resources: +set(qmake_immediate_resource_files + "doc/images/qtquickcontrols2-sidepanel-landscape.png" + "doc/images/qtquickcontrols2-sidepanel-portrait.png" + "images/qt-logo.png" + "images/qt-logo@2x.png" + "images/qt-logo@3x.png" + "images/qt-logo@4x.png" + "qtquickcontrols2.conf" + "sidepanel.qml" +) + +qt6_add_resources(sidepanel "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + +install(TARGETS sidepanel + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/sidepanel/doc/images/qtquickcontrols2-sidepanel-landscape.png b/examples/quickcontrols2/sidepanel/doc/images/qtquickcontrols2-sidepanel-landscape.png new file mode 100644 index 00000000000..86907591b26 Binary files /dev/null and b/examples/quickcontrols2/sidepanel/doc/images/qtquickcontrols2-sidepanel-landscape.png differ diff --git a/examples/quickcontrols2/sidepanel/doc/images/qtquickcontrols2-sidepanel-portrait.png b/examples/quickcontrols2/sidepanel/doc/images/qtquickcontrols2-sidepanel-portrait.png new file mode 100644 index 00000000000..cf1ed2efd08 Binary files /dev/null and b/examples/quickcontrols2/sidepanel/doc/images/qtquickcontrols2-sidepanel-portrait.png differ diff --git a/examples/quickcontrols2/sidepanel/doc/src/qtquickcontrols2-sidepanel.qdoc b/examples/quickcontrols2/sidepanel/doc/src/qtquickcontrols2-sidepanel.qdoc new file mode 100644 index 00000000000..49e997fb5dd --- /dev/null +++ b/examples/quickcontrols2/sidepanel/doc/src/qtquickcontrols2-sidepanel.qdoc @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example sidepanel + \keyword Qt Quick Controls - Side Panel + \title Qt Quick Controls - Side Panel + \keyword Qt Quick Controls 2 - Side Panel + \ingroup qtquickcontrols2-examples + \brief A persistent side panel with Drawer. + + This example demonstrates how \l Drawer can be used as a persistent side + panel. + + \raw HTML +
+ +
+ \endraw + \image qtquickcontrols2-sidepanel-portrait.png + \caption An interactive Drawer in portrait mode + \raw HTML + + \endraw + \image qtquickcontrols2-sidepanel-landscape.png + \caption A non-interactive Drawer in landscape mode + \raw HTML +
+ \endraw + + When the application is in portrait mode, the drawer is an interactive + side panel that can be swiped open from the left edge. It appears on + top of the content, blocking user interaction through its modal + background. When the application is in landscape mode, the drawer and + the content are laid out side-by-side. + + The current orientation of the application is determined by comparing + the width and height of the window: + + \snippet sidepanel/sidepanel.qml orientation + + This is used to determine whether the drawer should be \l {Popup::}{modal} + and \l {Drawer::}{interactive}, and to configure its \l {Drawer::}{position} + and \l {Popup::visible}{visibility} accordingly. + + \quotefromfile sidepanel/sidepanel.qml + \skipto Drawer + \printline Drawer + \dots 8 + \codeline + \skipto modal + \printuntil visible + \dots 8 + \skipuntil ScrollIndicator + \skipuntil } + \printline } + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols2/sidepanel/images/qt-logo.png b/examples/quickcontrols2/sidepanel/images/qt-logo.png new file mode 100644 index 00000000000..dff7729515a Binary files /dev/null and b/examples/quickcontrols2/sidepanel/images/qt-logo.png differ diff --git a/examples/quickcontrols2/sidepanel/images/qt-logo@2x.png b/examples/quickcontrols2/sidepanel/images/qt-logo@2x.png new file mode 100644 index 00000000000..dbd73aab776 Binary files /dev/null and b/examples/quickcontrols2/sidepanel/images/qt-logo@2x.png differ diff --git a/examples/quickcontrols2/sidepanel/images/qt-logo@3x.png b/examples/quickcontrols2/sidepanel/images/qt-logo@3x.png new file mode 100644 index 00000000000..68e763b597e Binary files /dev/null and b/examples/quickcontrols2/sidepanel/images/qt-logo@3x.png differ diff --git a/examples/quickcontrols2/sidepanel/images/qt-logo@4x.png b/examples/quickcontrols2/sidepanel/images/qt-logo@4x.png new file mode 100644 index 00000000000..08fd882572b Binary files /dev/null and b/examples/quickcontrols2/sidepanel/images/qt-logo@4x.png differ diff --git a/examples/quickcontrols2/sidepanel/qtquickcontrols2.conf b/examples/quickcontrols2/sidepanel/qtquickcontrols2.conf new file mode 100644 index 00000000000..b6c7c87ea13 --- /dev/null +++ b/examples/quickcontrols2/sidepanel/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Material diff --git a/examples/quickcontrols2/sidepanel/sidepanel.cpp b/examples/quickcontrols2/sidepanel/sidepanel.cpp new file mode 100644 index 00000000000..4b328d1dd40 --- /dev/null +++ b/examples/quickcontrols2/sidepanel/sidepanel.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/sidepanel.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols2/sidepanel/sidepanel.pro b/examples/quickcontrols2/sidepanel/sidepanel.pro new file mode 100644 index 00000000000..3ae9cd8d6b7 --- /dev/null +++ b/examples/quickcontrols2/sidepanel/sidepanel.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +TARGET = sidepanel +QT += quick + +SOURCES += \ + sidepanel.cpp + +RESOURCES += \ + doc/images/qtquickcontrols2-sidepanel-landscape.png \ + doc/images/qtquickcontrols2-sidepanel-portrait.png \ + images/qt-logo@2x.png \ + images/qt-logo@3x.png \ + images/qt-logo@4x.png \ + images/qt-logo.png \ + qtquickcontrols2.conf \ + sidepanel.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/sidepanel +INSTALLS += target diff --git a/examples/quickcontrols2/sidepanel/sidepanel.qml b/examples/quickcontrols2/sidepanel/sidepanel.qml new file mode 100644 index 00000000000..33e8515992e --- /dev/null +++ b/examples/quickcontrols2/sidepanel/sidepanel.qml @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 360 + height: 520 + visible: true + title: qsTr("Side Panel") + + //! [orientation] + readonly property bool inPortrait: window.width < window.height + //! [orientation] + + ToolBar { + id: overlayHeader + + z: 1 + width: parent.width + parent: Overlay.overlay + + Label { + id: label + anchors.centerIn: parent + text: "Qt Quick Controls" + } + } + + Drawer { + id: drawer + + y: overlayHeader.height + width: window.width / 2 + height: window.height - overlayHeader.height + + modal: inPortrait + interactive: inPortrait + position: inPortrait ? 0 : 1 + visible: !inPortrait + + ListView { + id: listView + anchors.fill: parent + + headerPositioning: ListView.OverlayHeader + header: Pane { + id: header + z: 2 + width: parent.width + + contentHeight: logo.height + + Image { + id: logo + width: parent.width + source: "images/qt-logo.png" + fillMode: implicitWidth > width ? Image.PreserveAspectFit : Image.Pad + } + + MenuSeparator { + parent: header + width: parent.width + anchors.verticalCenter: parent.bottom + visible: !listView.atYBeginning + } + } + + footer: ItemDelegate { + id: footer + text: qsTr("Footer") + width: parent.width + + MenuSeparator { + parent: footer + width: parent.width + anchors.verticalCenter: parent.top + } + } + + model: 10 + + delegate: ItemDelegate { + text: qsTr("Title %1").arg(index + 1) + width: listView.width + } + + ScrollIndicator.vertical: ScrollIndicator { } + } + } + + Flickable { + id: flickable + + anchors.fill: parent + anchors.topMargin: overlayHeader.height + anchors.leftMargin: !inPortrait ? drawer.width : undefined + + topMargin: 20 + bottomMargin: 20 + contentHeight: column.height + + Column { + id: column + spacing: 20 + anchors.margins: 20 + anchors.left: parent.left + anchors.right: parent.right + + Label { + font.pixelSize: 22 + width: parent.width + elide: Label.ElideRight + horizontalAlignment: Qt.AlignHCenter + text: qsTr("Side Panel Example") + } + + Label { + width: parent.width + wrapMode: Label.WordWrap + text: qsTr("This example demonstrates how Drawer can be used as a non-closable persistent side panel.\n\n" + + "When the application is in portrait mode, the drawer is an interactive side panel that can " + + "be swiped open from the left edge. When the application is in landscape mode, the drawer " + + "and the content are laid out side by side.\n\nThe application is currently in %1 mode.").arg(inPortrait ? qsTr("portrait") : qsTr("landscape")) + } + } + + ScrollIndicator.vertical: ScrollIndicator { } + } +} diff --git a/examples/quickcontrols2/swipetoremove/CMakeLists.txt b/examples/quickcontrols2/swipetoremove/CMakeLists.txt new file mode 100644 index 00000000000..c5d6c1ef457 --- /dev/null +++ b/examples/quickcontrols2/swipetoremove/CMakeLists.txt @@ -0,0 +1,53 @@ +# Generated from swipetoremove.pro. + +cmake_minimum_required(VERSION 3.16) +project(swipetoremove LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/swipetoremove") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Qml) + +qt_add_executable(swipetoremove + swipetoremove.cpp +) +set_target_properties(swipetoremove PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(swipetoremove PUBLIC + Qt::Core + Qt::Gui + Qt::Qml +) + + +# Resources: +set(qmake_immediate_resource_files + "fonts/fontello.ttf" + "swipetoremove.qml" +) + +qt6_add_resources(swipetoremove "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + +install(TARGETS swipetoremove + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/swipetoremove/doc/images/qtquickcontrols2-swipetoremove.png b/examples/quickcontrols2/swipetoremove/doc/images/qtquickcontrols2-swipetoremove.png new file mode 100644 index 00000000000..07a200fe92a Binary files /dev/null and b/examples/quickcontrols2/swipetoremove/doc/images/qtquickcontrols2-swipetoremove.png differ diff --git a/examples/quickcontrols2/swipetoremove/doc/src/qtquickcontrols2-swipetoremove.qdoc b/examples/quickcontrols2/swipetoremove/doc/src/qtquickcontrols2-swipetoremove.qdoc new file mode 100644 index 00000000000..c359a423613 --- /dev/null +++ b/examples/quickcontrols2/swipetoremove/doc/src/qtquickcontrols2-swipetoremove.qdoc @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example swipetoremove + \keyword Qt Quick Controls - Swipe to Remove + \title Qt Quick Controls - Swipe to Remove + \keyword Qt Quick Controls 2 - Swipe to Remove + \ingroup qtquickcontrols2-examples + \brief Demonstrates removal of list items by swipe gesture. + + This example demonstrates how \l SwipeDelegate can be used to implement + removal of list items by swiping. This UI pattern is often used in touch + user interfaces. + + \image qtquickcontrols2-swipetoremove.png + + Each list item can be swiped to the left, which reveals a label on the + \l {SwipeDelegate::swipe}{right} side indicating that the item will be + removed if the swipe is completed. The following snippet contains the + implementation of the side item. + + \snippet swipetoremove/swipetoremove.qml delegate + + The following snippet presents how the logic of removing items is + implemented. When the swipe is \l {SwipeDelegate::swipe}{completed}, it + starts a timer that waits a few seconds to let the user undo the remove + action. Once the undo timer triggers, the item is removed from the list: + + \snippet swipetoremove/swipetoremove.qml removal + + Finally, the removal of an item triggers the following transitions. The + \l {ListView::} {remove} transition applies to the item that is removed, + and the \l {ListView::}{displaced} transition applies to the other items + that got displaced due to the removal: + + \snippet swipetoremove/swipetoremove.qml transitions + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols2/swipetoremove/fonts/LICENSE.txt b/examples/quickcontrols2/swipetoremove/fonts/LICENSE.txt new file mode 100644 index 00000000000..7394a58ddfd --- /dev/null +++ b/examples/quickcontrols2/swipetoremove/fonts/LICENSE.txt @@ -0,0 +1,12 @@ +Font license info + + +## Elusive + + Copyright (C) 2013 by Aristeides Stathopoulos + + Author: Aristeides Stathopoulos + License: SIL (http://scripts.sil.org/OFL) + Homepage: http://aristeides.com/ + + diff --git a/examples/quickcontrols2/swipetoremove/fonts/fontello.ttf b/examples/quickcontrols2/swipetoremove/fonts/fontello.ttf new file mode 100644 index 00000000000..553fd2efca1 Binary files /dev/null and b/examples/quickcontrols2/swipetoremove/fonts/fontello.ttf differ diff --git a/examples/quickcontrols2/swipetoremove/swipetoremove.cpp b/examples/quickcontrols2/swipetoremove/swipetoremove.cpp new file mode 100644 index 00000000000..7f89344fc88 --- /dev/null +++ b/examples/quickcontrols2/swipetoremove/swipetoremove.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QFontDatabase::addApplicationFont(":/fonts/fontello.ttf"); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/swipetoremove.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols2/swipetoremove/swipetoremove.pro b/examples/quickcontrols2/swipetoremove/swipetoremove.pro new file mode 100644 index 00000000000..8e6bd5f663c --- /dev/null +++ b/examples/quickcontrols2/swipetoremove/swipetoremove.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = swipetoremove +QT += qml + +SOURCES += \ + swipetoremove.cpp + +RESOURCES += \ + swipetoremove.qml \ + fonts/fontello.ttf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/swipetoremove +INSTALLS += target diff --git a/examples/quickcontrols2/swipetoremove/swipetoremove.qml b/examples/quickcontrols2/swipetoremove/swipetoremove.qml new file mode 100644 index 00000000000..41c578c685a --- /dev/null +++ b/examples/quickcontrols2/swipetoremove/swipetoremove.qml @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material + +ApplicationWindow { + id: window + width: 300 + height: 400 + visible: true + title: qsTr("Swipe to Remove") + + ListView { + id: listView + anchors.fill: parent + + delegate: SwipeDelegate { + id: delegate + + text: modelData + width: listView.width + + //! [delegate] + swipe.right: Rectangle { + width: parent.width + height: parent.height + + clip: true + color: SwipeDelegate.pressed ? "#555" : "#666" + + Label { + font.family: "Fontello" + text: delegate.swipe.complete ? "\ue805" // icon-cw-circled + : "\ue801" // icon-cancel-circled-1 + + padding: 20 + anchors.fill: parent + horizontalAlignment: Qt.AlignRight + verticalAlignment: Qt.AlignVCenter + + opacity: 2 * -delegate.swipe.position + + color: Material.color(delegate.swipe.complete ? Material.Green : Material.Red, Material.Shade200) + Behavior on color { ColorAnimation { } } + } + + Label { + text: qsTr("Removed") + color: "white" + + padding: 20 + anchors.fill: parent + horizontalAlignment: Qt.AlignLeft + verticalAlignment: Qt.AlignVCenter + + opacity: delegate.swipe.complete ? 1 : 0 + Behavior on opacity { NumberAnimation { } } + } + + SwipeDelegate.onClicked: delegate.swipe.close() + SwipeDelegate.onPressedChanged: undoTimer.stop() + } + //! [delegate] + + //! [removal] + Timer { + id: undoTimer + interval: 3600 + onTriggered: listModel.remove(index) + } + + swipe.onCompleted: undoTimer.start() + //! [removal] + } + + model: ListModel { + id: listModel + ListElement { text: "Lorem ipsum dolor sit amet" } + ListElement { text: "Curabitur sit amet risus" } + ListElement { text: "Suspendisse vehicula nisi" } + ListElement { text: "Mauris imperdiet libero" } + ListElement { text: "Sed vitae dui aliquet augue" } + ListElement { text: "Praesent in elit eu nulla" } + ListElement { text: "Etiam vitae magna" } + ListElement { text: "Pellentesque eget elit euismod" } + ListElement { text: "Nulla at enim porta" } + ListElement { text: "Fusce tincidunt odio" } + ListElement { text: "Ut non ex a ligula molestie" } + ListElement { text: "Nam vitae justo scelerisque" } + ListElement { text: "Vestibulum pulvinar tellus" } + ListElement { text: "Quisque dignissim leo sed gravida" } + } + + //! [transitions] + remove: Transition { + SequentialAnimation { + PauseAnimation { duration: 125 } + NumberAnimation { property: "height"; to: 0; easing.type: Easing.InOutQuad } + } + } + + displaced: Transition { + SequentialAnimation { + PauseAnimation { duration: 125 } + NumberAnimation { property: "y"; easing.type: Easing.InOutQuad } + } + } + //! [transitions] + + ScrollIndicator.vertical: ScrollIndicator { } + } + + Label { + id: placeholder + text: qsTr("Swipe no more") + + anchors.margins: 60 + anchors.fill: parent + + opacity: 0.5 + visible: listView.count === 0 + + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + wrapMode: Label.WordWrap + font.pixelSize: 18 + } +} diff --git a/examples/quickcontrols2/texteditor/+touch/texteditor.html b/examples/quickcontrols2/texteditor/+touch/texteditor.html new file mode 100644 index 00000000000..b5f03f258e8 --- /dev/null +++ b/examples/quickcontrols2/texteditor/+touch/texteditor.html @@ -0,0 +1,19 @@ + + + + + Text Editor Example + + + +

+ +

+

+ Qt Quick Controls 2 +

+

+ This example demonstrates a modern rich text editor. +

+ + diff --git a/examples/quickcontrols2/texteditor/CMakeLists.txt b/examples/quickcontrols2/texteditor/CMakeLists.txt new file mode 100644 index 00000000000..6c3de0891f5 --- /dev/null +++ b/examples/quickcontrols2/texteditor/CMakeLists.txt @@ -0,0 +1,66 @@ +# Generated from texteditor.pro. + +cmake_minimum_required(VERSION 3.16) +project(texteditor LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/texteditor") + +find_package(Qt6 COMPONENTS Core Gui Quick QuickControls2) +find_package(Qt6 COMPONENTS Widgets) + +qt_add_executable(texteditor WIN32 MACOSX_BUNDLE + documenthandler.cpp + texteditor.cpp +) + +target_link_libraries(texteditor PUBLIC + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) + + +# Resources: +set(texteditor_resource_files + "+touch/texteditor.html" + "fonts/fontello.ttf" + "images/qt-logo.png" + "qml/+touch/texteditor.qml" + "qml/texteditor.qml" + "texteditor.html" +) + +qt6_add_resources(texteditor "texteditor" + PREFIX + "/" + FILES + ${texteditor_resource_files} +) + +if(TARGET Qt::Widgets) + target_link_libraries(texteditor PUBLIC + Qt::Widgets + ) +endif() + +if(CMAKE_CROSSCOMPILING) + target_compile_definitions(texteditor PUBLIC + QT_EXTRA_FILE_SELECTOR="touch" # special case + ) +endif() + +install(TARGETS texteditor + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/texteditor/creatorKateHighlighter.png b/examples/quickcontrols2/texteditor/creatorKateHighlighter.png new file mode 100644 index 00000000000..7dd819507ff Binary files /dev/null and b/examples/quickcontrols2/texteditor/creatorKateHighlighter.png differ diff --git a/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpg b/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpg new file mode 100644 index 00000000000..259e0e8b071 Binary files /dev/null and b/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpg differ diff --git a/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpg b/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpg new file mode 100644 index 00000000000..6a924cdf52e Binary files /dev/null and b/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpg differ diff --git a/examples/quickcontrols2/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc b/examples/quickcontrols2/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc new file mode 100644 index 00000000000..28cf3f3b3f9 --- /dev/null +++ b/examples/quickcontrols2/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ +/*! + \example texteditor + \keyword Qt Quick Controls - Text Editor + \title Qt Quick Controls - Text Editor + \keyword Qt Quick Controls 2 - Text Editor + \ingroup qtquickcontrols2-examples + \brief A QML app using Qt Quick Controls and a C++ class to + provide a fully-functional rich-text editor application. + + The \e {Text Editor Example} presents a sample HTML file using the TextArea + control, preserving the HTML formatting. The application comes with two user + interfaces; one for traditional desktop platforms with a mouse pointer, and + another simpler, touch-oriented version. + + \section1 Desktop User Interface + + \image qtquickcontrols2-texteditor-desktop.jpg + + The desktop version is a complete text editor with capabilities for formatting + text, and opening and saving HTML and plain text files. It demonstrates the + native-looking dialogs and menus using the \l{Qt Labs Platform} module. These + types are mostly suitable for desktop platforms with support for multiple + top-level windows, a mouse pointer, and moderate screen size. + + The desktop UI uses FileDialog for opening and saving files: + + \quotefromfile texteditor/qml/texteditor.qml + \skipto FileDialog + \printuntil /\bsaveAs\b/ + \printline } + + It uses FontDialog and ColorDialog for choosing fonts and colors: + + \skipto FontDialog + \printuntil /.*colorDialog$/ + \printuntil /^\s{4}\}$/ + + It also uses \l[QML QtLabsPlatform]{Menu} and + \l[QML QtLabsPlatform]{MenuItem} that provide a context menu to format text + within: + + \skipto /\bMenu\b/ + \printuntil /^\s{4}\}$/ + + \note There is also a standard menubar with more options than the + context menu. + + \section1 Touch User Interface + + \image qtquickcontrols2-texteditor-touch.jpg + + The touch user interface is a simplified version of the text editor. It is + suitable for touch devices with limited screen size. The example uses + \l{Using File Selectors with Qt Quick Controls}{file selectors} to load + the appropriate user interface automatically. + + Unlike the desktop version, which uses top-level dialogs, the touch version + uses the QML \l Dialog type, which is not a top-level window. This type of + dialog is fully supported on mobile and embedded platforms that do not support + multiple top-level windows. + + \quotefromfile texteditor/qml/+touch/texteditor.qml + \skipto /\bDialog\b/ + \printuntil /^\s{4}\}$/ + + \section1 C++ Backend + + Both user interfaces use the same C++ backend, which supports opening, formatting, + and editing a document. The C++ class, \c DocumentHandler, extends QObject and is + registered as a QML type under the namespace \c {io.qt.examples.texteditor 1.0}. + + The following snippets show how the type is registered under a namespace and later + imported and instantiated by \e main.qml. For more information about registering C++ + classes as QML types, see \l {Defining QML Types from C++}. + + QML type registration: + + \code + #include + ... + qmlRegisterType("io.qt.examples.texteditor", 1, 0, "DocumentHandler"); + ... + \endcode + + QML namespace import: + + \code + import io.qt.examples.texteditor 1.0 + \endcode + + QML instance: + + \quotefromfile texteditor/qml/texteditor.qml + \skipto DocumentHandler + \printuntil /^\s{4}\}$/ + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols2/texteditor/documenthandler.cpp b/examples/quickcontrols2/texteditor/documenthandler.cpp new file mode 100644 index 00000000000..b266bc56946 --- /dev/null +++ b/examples/quickcontrols2/texteditor/documenthandler.cpp @@ -0,0 +1,395 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "documenthandler.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DocumentHandler::DocumentHandler(QObject *parent) + : QObject(parent) + , m_document(nullptr) + , m_cursorPosition(-1) + , m_selectionStart(0) + , m_selectionEnd(0) +{ +} + +QQuickTextDocument *DocumentHandler::document() const +{ + return m_document; +} + +void DocumentHandler::setDocument(QQuickTextDocument *document) +{ + if (document == m_document) + return; + + if (m_document) + disconnect(m_document->textDocument(), &QTextDocument::modificationChanged, this, &DocumentHandler::modifiedChanged); + m_document = document; + if (m_document) + connect(m_document->textDocument(), &QTextDocument::modificationChanged, this, &DocumentHandler::modifiedChanged); + emit documentChanged(); +} + +int DocumentHandler::cursorPosition() const +{ + return m_cursorPosition; +} + +void DocumentHandler::setCursorPosition(int position) +{ + if (position == m_cursorPosition) + return; + + m_cursorPosition = position; + reset(); + emit cursorPositionChanged(); +} + +int DocumentHandler::selectionStart() const +{ + return m_selectionStart; +} + +void DocumentHandler::setSelectionStart(int position) +{ + if (position == m_selectionStart) + return; + + m_selectionStart = position; + emit selectionStartChanged(); +} + +int DocumentHandler::selectionEnd() const +{ + return m_selectionEnd; +} + +void DocumentHandler::setSelectionEnd(int position) +{ + if (position == m_selectionEnd) + return; + + m_selectionEnd = position; + emit selectionEndChanged(); +} + +QColor DocumentHandler::textColor() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return QColor(Qt::black); + QTextCharFormat format = cursor.charFormat(); + return format.foreground().color(); +} + +void DocumentHandler::setTextColor(const QColor &color) +{ + QTextCharFormat format; + format.setForeground(QBrush(color)); + mergeFormatOnWordOrSelection(format); + emit textColorChanged(); +} + +Qt::Alignment DocumentHandler::alignment() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return Qt::AlignLeft; + return textCursor().blockFormat().alignment(); +} + +void DocumentHandler::setAlignment(Qt::Alignment alignment) +{ + QTextBlockFormat format; + format.setAlignment(alignment); + QTextCursor cursor = textCursor(); + cursor.mergeBlockFormat(format); + emit alignmentChanged(); +} + +QString DocumentHandler::fileName() const +{ + const QString filePath = QQmlFile::urlToLocalFileOrQrc(m_fileUrl); + const QString fileName = QFileInfo(filePath).fileName(); + if (fileName.isEmpty()) + return QStringLiteral("untitled.txt"); + return fileName; +} + +QString DocumentHandler::fileType() const +{ + return QFileInfo(fileName()).suffix(); +} + +QUrl DocumentHandler::fileUrl() const +{ + return m_fileUrl; +} + +void DocumentHandler::load(const QUrl &fileUrl) +{ + if (fileUrl == m_fileUrl) + return; + + QQmlEngine *engine = qmlEngine(this); + if (!engine) { + qWarning() << "load() called before DocumentHandler has QQmlEngine"; + return; + } + + const QUrl path = QQmlFileSelector::get(engine)->selector()->select(fileUrl); + const QString fileName = QQmlFile::urlToLocalFileOrQrc(path); + if (QFile::exists(fileName)) { + QMimeType mime = QMimeDatabase().mimeTypeForFile(fileName); + QFile file(fileName); + if (file.open(QFile::ReadOnly)) { + QByteArray data = file.readAll(); + if (QTextDocument *doc = textDocument()) { + doc->setBaseUrl(path.adjusted(QUrl::RemoveFilename)); + doc->setModified(false); + if (mime.inherits("text/markdown")) { + emit loaded(QString::fromUtf8(data), Qt::MarkdownText); + } else { + auto encoding = QStringConverter::encodingForHtml(data); + if (encoding) { + QStringDecoder decoder(*encoding); + emit loaded(decoder(data), Qt::AutoText); + } else { + // fall back to utf8 + emit loaded(QString::fromUtf8(data), Qt::AutoText); + } + } + } + + reset(); + } + } + + m_fileUrl = fileUrl; + emit fileUrlChanged(); +} + +void DocumentHandler::saveAs(const QUrl &fileUrl) +{ + QTextDocument *doc = textDocument(); + if (!doc) + return; + + const QString filePath = fileUrl.toLocalFile(); + const bool isHtml = QFileInfo(filePath).suffix().contains(QLatin1String("htm")); + QFile file(filePath); + if (!file.open(QFile::WriteOnly | QFile::Truncate | (isHtml ? QFile::NotOpen : QFile::Text))) { + emit error(tr("Cannot save: ") + file.errorString()); + return; + } + file.write((isHtml ? doc->toHtml() : doc->toPlainText()).toUtf8()); + file.close(); + + if (fileUrl == m_fileUrl) + return; + + m_fileUrl = fileUrl; + emit fileUrlChanged(); +} + +void DocumentHandler::reset() +{ + emit alignmentChanged(); + emit textColorChanged(); + emit fontChanged(); +} + +QTextCursor DocumentHandler::textCursor() const +{ + QTextDocument *doc = textDocument(); + if (!doc) + return QTextCursor(); + + QTextCursor cursor = QTextCursor(doc); + if (m_selectionStart != m_selectionEnd) { + cursor.setPosition(m_selectionStart); + cursor.setPosition(m_selectionEnd, QTextCursor::KeepAnchor); + } else { + cursor.setPosition(m_cursorPosition); + } + return cursor; +} + +QTextDocument *DocumentHandler::textDocument() const +{ + if (!m_document) + return nullptr; + + return m_document->textDocument(); +} + +void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format) +{ + QTextCursor cursor = textCursor(); + if (!cursor.hasSelection()) + cursor.select(QTextCursor::WordUnderCursor); + cursor.mergeCharFormat(format); +} + +bool DocumentHandler::modified() const +{ + return m_document && m_document->textDocument()->isModified(); +} + +void DocumentHandler::setModified(bool m) +{ + if (m_document) + m_document->textDocument()->setModified(m); +} + +QFont DocumentHandler::font() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return m_document->textDocument()->defaultFont(); + QTextCharFormat format = cursor.charFormat(); + return format.font(); +} + +void DocumentHandler::setFont(const QFont & font){ + + QTextCursor cursor = textCursor(); + if (!cursor.isNull() && cursor.charFormat().font() == font) + return; + + QTextCharFormat format; + format.setFont(font); + mergeFormatOnWordOrSelection(format); + + emit fontChanged(); +} + +bool DocumentHandler::bold() const +{ + const QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return m_document->textDocument()->defaultFont().bold(); + return cursor.charFormat().font().bold(); +} + +void DocumentHandler::setBold(bool bold) +{ + const QTextCursor cursor = textCursor(); + if (!cursor.isNull() && cursor.charFormat().font().bold() == bold) + return; + + QFont font = cursor.charFormat().font(); + font.setBold(bold); + QTextCharFormat format; + format.setFont(font); + mergeFormatOnWordOrSelection(format); + + emit boldChanged(); +} + +bool DocumentHandler::underline() const +{ + const QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return m_document->textDocument()->defaultFont().underline(); + return cursor.charFormat().font().underline(); +} + +void DocumentHandler::setUnderline(bool underline) +{ + const QTextCursor cursor = textCursor(); + if (!cursor.isNull() && cursor.charFormat().font().underline() == underline) + return; + + QFont font = cursor.charFormat().font(); + font.setUnderline(underline); + QTextCharFormat format; + format.setFont(font); + mergeFormatOnWordOrSelection(format); + + emit underlineChanged(); +} + +bool DocumentHandler::italic() const +{ + const QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return m_document->textDocument()->defaultFont().italic(); + return cursor.charFormat().font().italic(); +} + +void DocumentHandler::setItalic(bool italic) +{ + const QTextCursor cursor = textCursor(); + if (!cursor.isNull() && cursor.charFormat().font().italic() == italic) + return; + + QFont font = cursor.charFormat().font(); + font.setItalic(italic); + QTextCharFormat format; + format.setFont(font); + mergeFormatOnWordOrSelection(format); + + emit italicChanged(); +} + +#include "moc_documenthandler.cpp" diff --git a/examples/quickcontrols2/texteditor/documenthandler.h b/examples/quickcontrols2/texteditor/documenthandler.h new file mode 100644 index 00000000000..aa3f2575585 --- /dev/null +++ b/examples/quickcontrols2/texteditor/documenthandler.h @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DOCUMENTHANDLER_H +#define DOCUMENTHANDLER_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QTextDocument; +class QQuickTextDocument; +QT_END_NAMESPACE + +class DocumentHandler : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QQuickTextDocument *document READ document WRITE setDocument NOTIFY documentChanged) + Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged) + Q_PROPERTY(int selectionStart READ selectionStart WRITE setSelectionStart NOTIFY selectionStartChanged) + Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged) + + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor NOTIFY textColorChanged) + Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged) + + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) + + Q_PROPERTY(bool bold READ bold WRITE setBold NOTIFY boldChanged) + Q_PROPERTY(bool underline READ underline WRITE setUnderline NOTIFY underlineChanged) + Q_PROPERTY(bool italic READ italic WRITE setItalic NOTIFY italicChanged) + + Q_PROPERTY(QString fileName READ fileName NOTIFY fileUrlChanged) + Q_PROPERTY(QString fileType READ fileType NOTIFY fileUrlChanged) + Q_PROPERTY(QUrl fileUrl READ fileUrl NOTIFY fileUrlChanged) + + Q_PROPERTY(bool modified READ modified WRITE setModified NOTIFY modifiedChanged) + +public: + explicit DocumentHandler(QObject *parent = nullptr); + + QQuickTextDocument *document() const; + void setDocument(QQuickTextDocument *document); + + int cursorPosition() const; + void setCursorPosition(int position); + + int selectionStart() const; + void setSelectionStart(int position); + + int selectionEnd() const; + void setSelectionEnd(int position); + + QColor textColor() const; + void setTextColor(const QColor &color); + + Qt::Alignment alignment() const; + void setAlignment(Qt::Alignment alignment); + + QFont font() const; + void setFont(const QFont & font); + + bool bold() const; + void setBold(bool bold); + + bool underline() const; + void setUnderline(bool underline); + + bool italic() const; + void setItalic(bool italic); + + QString fileName() const; + QString fileType() const; + QUrl fileUrl() const; + + bool modified() const; + void setModified(bool m); + +public Q_SLOTS: + void load(const QUrl &fileUrl); + void saveAs(const QUrl &fileUrl); + +Q_SIGNALS: + void documentChanged(); + void cursorPositionChanged(); + void selectionStartChanged(); + void selectionEndChanged(); + + void fontChanged(); + void boldChanged(); + void underlineChanged(); + void italicChanged(); + void textColorChanged(); + void alignmentChanged(); + + void textChanged(); + void fileUrlChanged(); + + void loaded(const QString &text, int format); + void error(const QString &message); + + void modifiedChanged(); + +private: + void reset(); + QTextCursor textCursor() const; + QTextDocument *textDocument() const; + void mergeFormatOnWordOrSelection(const QTextCharFormat &format); + + QQuickTextDocument *m_document; + + int m_cursorPosition; + int m_selectionStart; + int m_selectionEnd; + + QUrl m_fileUrl; +}; + +#endif // DOCUMENTHANDLER_H diff --git a/examples/quickcontrols2/texteditor/einstein.png b/examples/quickcontrols2/texteditor/einstein.png new file mode 100644 index 00000000000..3611284df46 Binary files /dev/null and b/examples/quickcontrols2/texteditor/einstein.png differ diff --git a/examples/quickcontrols2/texteditor/example.md b/examples/quickcontrols2/texteditor/example.md new file mode 100644 index 00000000000..169ff4338e4 --- /dev/null +++ b/examples/quickcontrols2/texteditor/example.md @@ -0,0 +1,173 @@ +# Markdown in Qt Quick + +The Text, TextEdit and TextArea items support rich text formatted in HTML. +Since Qt 5.14, they now support two dialects of Markdown as well: +[The CommonMark Specification](https://spec.commonmark.org/0.29/) is the +conservative formal specification, while +[GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) +adds extra features such as task lists and tables. + +If you are viewing this document in the Qt Quick Controls Text Editor example, +you can edit this document to explore Qt's rich text editing features. +We have included some comments in each of the following sections to +encourage you to experiment. + +## Font and Paragraph Styles + +Markdown supports **bold**, *italic*, ~~strikethrough~~ and `monospace` font +styles. + +> A block quote is indented according to the convention for email quoting. + + A block of code; + can be indented; + with 4 spaces or a tab; + +or + +``` +Block { + id: code + CanBe { + wrappedBy: "triple backticks" + } +} +``` + +Block quotes can be nested, and block quotes can include indented code blocks. + +In [The CommonMark Specification](https://spec.commonmark.org/0.29/) +John MacFarlane writes: + +> What distinguishes Markdown from many other lightweight markup syntaxes, +> which are often easier to write, is its readability. As Gruber writes: + +> > The overriding design goal for Markdown's formatting syntax is to make it +> > as readable as possible. The idea is that a Markdown-formatted document should +> > be publishable as-is, as plain text, without looking like it's been marked up +> > with tags or formatting instructions. ( +> > [http://daringfireball.net/projects/markdown/](http://daringfireball.net/projects/markdown/)) + +> The point can be illustrated by comparing a sample of AsciiDoc with an +> equivalent sample of Markdown. Here is a sample of AsciiDoc from the AsciiDoc +> manual: + +> 1. List item one. +> + +> List item one continued with a second paragraph followed by an +> Indented block. +> + +> ................. +> $ ls *.sh +> $ mv *.sh ~/tmp +> ................. +> + +> List item continued with a third paragraph. +> +> 2. List item two continued with an open block. +> ... +> + +## Hyperlinks + +Hyperlinks can be written with the link text first, and the URL immediately +following: [Qt Assistant](http://doc.qt.io/qt-5/qtassistant-index.html) + +A plain url is automatically recognized: https://doc.qt.io/qt-5/qml-qtquick-text.html + +There are also "reference links" where the link text is first labeled +and then the URL for the label is given elsewhere: +[The Qt Creator Manual][creatormanual] + +## Images + +Inline images like this one ![red square](red.png) flow with the surrounding text. + +The code for including an image is just a link that starts with a bang. +An image in its own paragraph is given its own space: + +![Albert Einstein image](einstein.png) + +## Lists + +Different kinds of lists can be included. Standard bullet lists can be nested, +using different symbols for each level of the list. List items can have nested +items such as block quotes, code blocks and images. Check boxes can be included +to form a task list. + +- Disc symbols are typically used for top-level list items. + * Circle symbols can be used to distinguish between items in lower-level + lists. + + Square symbols provide a reasonable alternative to discs and circles. + * Lists can be continued... + * further down +- List items can include images: ![red square](red.png) +- and even nested quotes, like this: + + The [Qt Documentation](https://doc.qt.io/qt-5/qml-qtquick-textedit.html#details) + points out that + > The TextEdit item displays a block of editable, formatted text. + > + > It can display both plain and rich text. For example: + > + > TextEdit { + > width: 240 + > text: "Hello World!" + > font.family: "Helvetica" + > font.pointSize: 20 + > color: "blue" + > focus: true + > } +- List items with check boxes allow task lists to be incorporated: + * [ ] This task is not yet done + * [x] We aced this one! + +Ordered lists can be used for tables of contents, for example. Each number +should end with a period or a parenthesis: + +1. Markdown in Qt Quick + 1) Font and Paragraph Styles + 5) Hyperlinks + 3) Images ![red square](red.png) + 2) Lists + 4) Tables +2. Related work + +The list will automatically be renumbered during rendering. + +## Tables + +One of the GitHub extensions is support for tables: + +| |Development Tools |Programming Techniques |Graphical User Interfaces| +|-------------|------------------------------------|---------------------------|-------------------------| +|9:00 - 11:00 |Introduction to Qt ||| +|11:00 - 13:00|Using Qt Creator |QML and its runtime |Layouts in Qt | +|13:00 - 15:00|Qt Quick Designer Tutorial |Extreme Programming |Writing Custom Styles | +|15:00 - 17:00|Qt Linguist and Internationalization| | | + +# Related Work + +Some Qt Widgets also support Markdown. +[QTextEdit](https://doc.qt.io/qt-5/qtextedit.html) has similar WYSIWYG +editing features as TextEdit and TextArea: you can edit the rendered text +directly. You can use +[QTextDocument::toMarkdown](https://doc-snapshots.qt.io/qt5-dev/qtextdocument.html#toMarkdown) +to rewrite the Markdown format, and save it back to a file. + +If you have the [KDE Kate Editor](https://kate-editor.org/) installed on your +system, you probably also have the `markdown.xml` syntax highlighting +definition file; that can be reused to add Markdown syntax highlighting to +Qt Creator. + +![creator markdown highlighting from Kate](creatorKateHighlighter.png) + +Qt owes thanks to the authors of the [MD4C parser](https://github.com/mity/md4c) +for making markdown import possible. The QTextMarkdownWriter class does not +have such dependencies, and also has not yet been tested as extensively, so we +do not yet guarantee that we are able to rewrite every Markdown document that +you are able to read and display with Text or TextEdit. But you are free to +write [bugs](https://bugreports.qt.io) about any troublesome cases that you +encounter. + +[creatormanual]: https://doc.qt.io/qtcreator/ "Qt Creator Manual" diff --git a/examples/quickcontrols2/texteditor/fonts/fontello.ttf b/examples/quickcontrols2/texteditor/fonts/fontello.ttf new file mode 100644 index 00000000000..f02b44ec124 Binary files /dev/null and b/examples/quickcontrols2/texteditor/fonts/fontello.ttf differ diff --git a/examples/quickcontrols2/texteditor/images/qt-logo.png b/examples/quickcontrols2/texteditor/images/qt-logo.png new file mode 100644 index 00000000000..2ebc01aafa9 Binary files /dev/null and b/examples/quickcontrols2/texteditor/images/qt-logo.png differ diff --git a/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml b/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml new file mode 100644 index 00000000000..677d25fbd96 --- /dev/null +++ b/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml @@ -0,0 +1,264 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Window + +import io.qt.examples.texteditor + +// TODO: +// - make designer-friendly + +ApplicationWindow { + id: window + visible: true + title: document.fileName + " - Text Editor Example" + + header: ToolBar { + leftPadding: 5 + + RowLayout { + anchors.fill: parent + spacing: 0 + + ToolButton { + id: doneEditingButton + font.family: "fontello" + text: "\uE80A" // icon-ok + opacity: !textArea.readOnly ? 1 : 0 + onClicked: textArea.readOnly = true + } + + Label { + text: qsTr("Text Editor Example") + font.bold: true + font.pixelSize: 20 + elide: Label.ElideRight + Layout.fillWidth: true + } + + ToolButton { + font.family: "fontello" + text: "\uF142" // icon-ellipsis-vert + onClicked: menu.open() + + Menu { + id: menu + + MenuItem { + text: qsTr("About") + onTriggered: aboutDialog.open() + } + } + } + } + } + + DocumentHandler { + id: document + document: textArea.textDocument + cursorPosition: textArea.cursorPosition + selectionStart: textArea.selectionStart + selectionEnd: textArea.selectionEnd + // textColor: TODO + Component.onCompleted: document.load("qrc:/texteditor.html") + onLoaded: { + textArea.text = text + } + onError: { + errorDialog.text = message + errorDialog.visible = true + } + } + + Flickable { + id: flickable + flickableDirection: Flickable.VerticalFlick + anchors.fill: parent + + TextArea.flickable: TextArea { + id: textArea + textFormat: Qt.RichText + wrapMode: TextArea.Wrap + readOnly: true + persistentSelection: true + // Different styles have different padding and background + // decorations, but since this editor is almost taking up the + // entire window, we don't need them. + leftPadding: 6 + rightPadding: 6 + topPadding: 0 + bottomPadding: 0 + background: null + + onLinkActivated: Qt.openUrlExternally(link) + } + + ScrollBar.vertical: ScrollBar {} + } + + footer: ToolBar { + visible: !textArea.readOnly && textArea.activeFocus + + Flickable { + anchors.fill: parent + contentWidth: toolRow.implicitWidth + flickableDirection: Qt.Horizontal + boundsBehavior: Flickable.StopAtBounds + + Row { + id: toolRow + + ToolButton { + id: boldButton + text: "\uE800" // icon-bold + font.family: "fontello" + // Don't want to close the virtual keyboard when this is clicked. + focusPolicy: Qt.NoFocus + checkable: true + checked: document.bold + onClicked: document.bold = !document.bold + } + ToolButton { + id: italicButton + text: "\uE801" // icon-italic + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.italic + onClicked: document.italic = !document.italic + } + ToolButton { + id: underlineButton + text: "\uF0CD" // icon-underline + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.underline + onClicked: document.underline = !document.underline + } + + ToolSeparator {} + + ToolButton { + id: alignLeftButton + text: "\uE803" // icon-align-left + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.alignment == Qt.AlignLeft + onClicked: document.alignment = Qt.AlignLeft + } + ToolButton { + id: alignCenterButton + text: "\uE804" // icon-align-center + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.alignment == Qt.AlignHCenter + onClicked: document.alignment = Qt.AlignHCenter + } + ToolButton { + id: alignRightButton + text: "\uE805" // icon-align-right + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.alignment == Qt.AlignRight + onClicked: document.alignment = Qt.AlignRight + } + ToolButton { + id: alignJustifyButton + text: "\uE806" // icon-align-justify + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.alignment == Qt.AlignJustify + onClicked: document.alignment = Qt.AlignJustify + } + } + } + } + + RoundButton { + id: editButton + font.family: "fontello" + text: "\uE809" // icon-pencil + width: 48 + height: width + // Don't want to use anchors for the y position, because it will anchor + // to the footer, leaving a large vertical gap. + y: parent.height - height - 12 + anchors.right: parent.right + anchors.margins: 12 + visible: textArea.readOnly + highlighted: true + + onClicked: { + textArea.readOnly = false + // Force focus on the text area so the cursor and footer show up. + textArea.forceActiveFocus() + } + } + + Dialog { + id: aboutDialog + standardButtons: Dialog.Ok + modal: true + x: parent.width / 2 - width / 2 + y: parent.height / 2 - height / 2 + + contentItem: Label { + text: qsTr("Qt Quick Controls - Text Editor Example") + } + } +} diff --git a/examples/quickcontrols2/texteditor/qml/texteditor.qml b/examples/quickcontrols2/texteditor/qml/texteditor.qml new file mode 100644 index 00000000000..5f47223bd30 --- /dev/null +++ b/examples/quickcontrols2/texteditor/qml/texteditor.qml @@ -0,0 +1,515 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtCore +import QtQuick.Controls +import QtQuick.Window +import QtQuick.Dialogs +import Qt.labs.platform as Platform + +import io.qt.examples.texteditor + +// TODO: +// - make designer-friendly + +ApplicationWindow { + id: window + width: 1024 + height: 600 + visible: true + title: document.fileName + " - Text Editor Example" + + Component.onCompleted: { + x = Screen.width / 2 - width / 2 + y = Screen.height / 2 - height / 2 + } + + Action { + id: openAction + shortcut: StandardKey.Open + onTriggered: openDialog.open() + } + + Action { + id: saveAsAction + shortcut: StandardKey.SaveAs + onTriggered: saveDialog.open() + } + + Action { + id: quitAction + shortcut: StandardKey.Quit + onTriggered: close() + } + + Action { + id: copyAction + shortcut: StandardKey.Copy + onTriggered: textArea.copy() + } + + Action { + id: cutAction + shortcut: StandardKey.Cut + onTriggered: textArea.cut() + } + + Action { + id: pasteAction + shortcut: StandardKey.Paste + onTriggered: textArea.paste() + } + + Action { + id: boldAction + shortcut: StandardKey.Bold + onTriggered: document.bold = !document.bold + } + + Action { + id: italicAction + shortcut: StandardKey.Italic + onTriggered: document.italic = !document.italic + } + + Action { + id: underlineAction + shortcut: StandardKey.Underline + onTriggered: document.underline = !document.underline + } + + Platform.MenuBar { + Platform.Menu { + title: qsTr("&File") + + Platform.MenuItem { + text: qsTr("&Open") + onTriggered: openDialog.open() + } + Platform.MenuItem { + text: qsTr("&Save As...") + onTriggered: saveDialog.open() + } + Platform.MenuItem { + text: qsTr("&Quit") + onTriggered: close() + } + } + + Platform.Menu { + title: qsTr("&Edit") + + Platform.MenuItem { + text: qsTr("&Copy") + enabled: textArea.selectedText + onTriggered: textArea.copy() + } + Platform.MenuItem { + text: qsTr("Cu&t") + enabled: textArea.selectedText + onTriggered: textArea.cut() + } + Platform.MenuItem { + text: qsTr("&Paste") + enabled: textArea.canPaste + onTriggered: textArea.paste() + } + } + + Platform.Menu { + title: qsTr("F&ormat") + + Platform.MenuItem { + text: qsTr("&Bold") + checkable: true + checked: document.bold + onTriggered: document.bold = !document.bold + } + Platform.MenuItem { + text: qsTr("&Italic") + checkable: true + checked: document.italic + onTriggered: document.italic = !document.italic + } + Platform.MenuItem { + text: qsTr("&Underline") + checkable: true + checked: document.underline + onTriggered: document.underline = !document.underline + } + Platform.MenuItem { + text: qsTr("&Strikeout") + checkable: true + checked: document.strikeout + onTriggered: document.strikeout = !document.strikeout + } + } + } + + FileDialog { + id: openDialog + fileMode: FileDialog.OpenFile + selectedNameFilter.index: 1 + nameFilters: ["Text files (*.txt)", "HTML files (*.html *.htm)", "Markdown files (*.md *.markdown)"] + currentFolder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) + onAccepted: document.load(file) + } + + FileDialog { + id: saveDialog + fileMode: FileDialog.SaveFile + defaultSuffix: document.fileType + nameFilters: openDialog.nameFilters + selectedNameFilter.index: document.fileType === "txt" ? 0 : 1 + currentFolder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) + onAccepted: document.saveAs(file) + } + + FontDialog { + id: fontDialog + + onAccepted: document.font = fontDialog.selectedFont + onVisibleChanged: if (visible) currentFont = document.font + } + + Platform.ColorDialog { + id: colorDialog + currentColor: "black" + } + + Platform.MessageDialog { + id: errorDialog + } + + Platform.MessageDialog { + id : quitDialog + title: qsTr("Quit?") + text: qsTr("The file has been modified. Quit anyway?") + buttons: (Platform.MessageDialog.Yes | Platform.MessageDialog.No) + onYesClicked: Qt.quit() + } + + header: ToolBar { + leftPadding: 8 + + Flow { + id: flow + width: parent.width + + Row { + id: fileRow + ToolButton { + id: openButton + text: "\uF115" // icon-folder-open-empty + font.family: "fontello" + action: openAction + focusPolicy: Qt.TabFocus + } + ToolSeparator { + contentItem.visible: fileRow.y === editRow.y + } + } + + Row { + id: editRow + ToolButton { + id: copyButton + text: "\uF0C5" // icon-docs + font.family: "fontello" + focusPolicy: Qt.TabFocus + enabled: textArea.selectedText + action: copyAction + } + ToolButton { + id: cutButton + text: "\uE802" // icon-scissors + font.family: "fontello" + focusPolicy: Qt.TabFocus + enabled: textArea.selectedText + action: cutAction + } + ToolButton { + id: pasteButton + text: "\uF0EA" // icon-paste + font.family: "fontello" + focusPolicy: Qt.TabFocus + enabled: textArea.canPaste + action: pasteAction + } + ToolSeparator { + contentItem.visible: editRow.y === formatRow.y + } + } + + Row { + id: formatRow + ToolButton { + id: boldButton + text: "\uE800" // icon-bold + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.bold + action: boldAction + } + ToolButton { + id: italicButton + text: "\uE801" // icon-italic + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.italic + action: italicAction + } + ToolButton { + id: underlineButton + text: "\uF0CD" // icon-underline + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.underline + action: underlineAction + } + ToolButton { + id: strikeoutButton + text: "\uF0CC" + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.strikeout + onClicked: document.strikeout = !document.strikeout + } + ToolButton { + id: fontFamilyToolButton + text: qsTr("\uE808") // icon-font + font.family: "fontello" + font.bold: document.bold + font.italic: document.italic + font.underline: document.underline + font.strikeout: document.strikeout + focusPolicy: Qt.TabFocus + onClicked: fontDialog.open() + } + ToolButton { + id: textColorButton + text: "\uF1FC" // icon-brush + font.family: "fontello" + focusPolicy: Qt.TabFocus + onClicked: colorDialog.open() + + Rectangle { + width: aFontMetrics.width + 3 + height: 2 + color: document.textColor + parent: textColorButton.contentItem + anchors.horizontalCenter: parent.horizontalCenter + anchors.baseline: parent.baseline + anchors.baselineOffset: 6 + + TextMetrics { + id: aFontMetrics + font: textColorButton.font + text: textColorButton.text + } + } + } + ToolSeparator { + contentItem.visible: formatRow.y === alignRow.y + } + } + + Row { + id: alignRow + ToolButton { + id: alignLeftButton + text: "\uE803" // icon-align-left + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.alignment == Qt.AlignLeft + onClicked: document.alignment = Qt.AlignLeft + } + ToolButton { + id: alignCenterButton + text: "\uE804" // icon-align-center + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.alignment == Qt.AlignHCenter + onClicked: document.alignment = Qt.AlignHCenter + } + ToolButton { + id: alignRightButton + text: "\uE805" // icon-align-right + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.alignment == Qt.AlignRight + onClicked: document.alignment = Qt.AlignRight + } + ToolButton { + id: alignJustifyButton + text: "\uE806" // icon-align-justify + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.alignment == Qt.AlignJustify + onClicked: document.alignment = Qt.AlignJustify + } + } + } + } + + DocumentHandler { + id: document + document: textArea.textDocument + cursorPosition: textArea.cursorPosition + selectionStart: textArea.selectionStart + selectionEnd: textArea.selectionEnd + textColor: colorDialog.color + + property alias family: document.font.family + property alias bold: document.font.bold + property alias italic: document.font.italic + property alias underline: document.font.underline + property alias strikeout: document.font.strikeout + property alias size: document.font.pointSize + + Component.onCompleted: { + if (Qt.application.arguments.length === 2) + document.load("file:" + Qt.application.arguments[1]); + else + document.load("qrc:/texteditor.html") + } + onLoaded: function (text, format) { + textArea.textFormat = format + textArea.text = text + } + onError: function (message) { + errorDialog.text = message + errorDialog.visible = true + } + } + + Flickable { + id: flickable + flickableDirection: Flickable.VerticalFlick + anchors.fill: parent + + TextArea.flickable: TextArea { + id: textArea + textFormat: Qt.RichText + wrapMode: TextArea.Wrap + focus: true + selectByMouse: true + persistentSelection: true + // Different styles have different padding and background + // decorations, but since this editor is almost taking up the + // entire window, we don't need them. + leftPadding: 6 + rightPadding: 6 + topPadding: 0 + bottomPadding: 0 + background: null + + MouseArea { + acceptedButtons: Qt.RightButton + anchors.fill: parent + onClicked: contextMenu.open() + } + + onLinkActivated: function (link) { + Qt.openUrlExternally(link) + } + } + + ScrollBar.vertical: ScrollBar {} + } + + Platform.Menu { + id: contextMenu + + Platform.MenuItem { + text: qsTr("Copy") + enabled: textArea.selectedText + onTriggered: textArea.copy() + } + Platform.MenuItem { + text: qsTr("Cut") + enabled: textArea.selectedText + onTriggered: textArea.cut() + } + Platform.MenuItem { + text: qsTr("Paste") + enabled: textArea.canPaste + onTriggered: textArea.paste() + } + + Platform.MenuSeparator {} + + Platform.MenuItem { + text: qsTr("Font...") + onTriggered: fontDialog.open() + } + + Platform.MenuItem { + text: qsTr("Color...") + onTriggered: colorDialog.open() + } + } + + onClosing: function (close) { + if (document.modified) { + quitDialog.open() + close.accepted = false + } + } +} diff --git a/examples/quickcontrols2/texteditor/red.png b/examples/quickcontrols2/texteditor/red.png new file mode 100644 index 00000000000..9038fef784d Binary files /dev/null and b/examples/quickcontrols2/texteditor/red.png differ diff --git a/examples/quickcontrols2/texteditor/texteditor.cpp b/examples/quickcontrols2/texteditor/texteditor.cpp new file mode 100644 index 00000000000..72148c72ea0 --- /dev/null +++ b/examples/quickcontrols2/texteditor/texteditor.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifdef QT_WIDGETS_LIB +#include +#else +#include +#endif +#include +#include +#include +#include +#include + +#include "documenthandler.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication::setApplicationName("Text Editor"); + QGuiApplication::setOrganizationName("QtProject"); + +#ifdef QT_WIDGETS_LIB + QApplication app(argc, argv); +#else + QGuiApplication app(argc, argv); +#endif + + if (QFontDatabase::addApplicationFont(":/fonts/fontello.ttf") == -1) + qWarning() << "Failed to load fontello.ttf"; + + qmlRegisterType("io.qt.examples.texteditor", 1, 0, "DocumentHandler"); + + QStringList selectors; +#ifdef QT_EXTRA_FILE_SELECTOR + selectors += QT_EXTRA_FILE_SELECTOR; +#else + if (app.arguments().contains("-touch")) + selectors += "touch"; +#endif + + QQmlApplicationEngine engine; + engine.setExtraFileSelectors(selectors); + + engine.load(QUrl("qrc:/qml/texteditor.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols2/texteditor/texteditor.html b/examples/quickcontrols2/texteditor/texteditor.html new file mode 100644 index 00000000000..3c59a053c53 --- /dev/null +++ b/examples/quickcontrols2/texteditor/texteditor.html @@ -0,0 +1,43 @@ + + + + + Text Editor Example + + + +

+ +

+

+ Qt Quick Controls 2 +

+

+ This example demonstrates a modern rich text editor. The UI uses Qt Labs Platforms to provide native menus and dialogs. +

+
+
+
+ +

+ Below you'll find a list of the native controls used in this application. +

+ +
    +
  • Menu - provides a QML API for native platform menu popups.
  • +
  • MenuBar - provides a QML API for native platform menubars.
  • +
  • MenuItem - provides a QML API for native platform menu items.
  • +
  • FileDialog - provides a QML API for native platform file dialogs.
  • +
  • FontDialog - provides a QML API for native platform font dialogs.
  • +
  • ColorDialog - provides a QML API for native platform color dialogs.
  • +
  • MessageDialog - provides a QML API for native platform message dialogs.
  • +
+ + diff --git a/examples/quickcontrols2/texteditor/texteditor.pro b/examples/quickcontrols2/texteditor/texteditor.pro new file mode 100644 index 00000000000..deb2457615d --- /dev/null +++ b/examples/quickcontrols2/texteditor/texteditor.pro @@ -0,0 +1,22 @@ +TEMPLATE = app +TARGET = texteditor +QT += quick quickcontrols2 +qtHaveModule(widgets): QT += widgets + +cross_compile: DEFINES += QT_EXTRA_FILE_SELECTOR=\\\"touch\\\" + +HEADERS += \ + documenthandler.h + +SOURCES += \ + texteditor.cpp \ + documenthandler.cpp + +OTHER_FILES += \ + qml/*.qml + +RESOURCES += \ + texteditor.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/texteditor +INSTALLS += target diff --git a/examples/quickcontrols2/texteditor/texteditor.qrc b/examples/quickcontrols2/texteditor/texteditor.qrc new file mode 100644 index 00000000000..cdb7225a398 --- /dev/null +++ b/examples/quickcontrols2/texteditor/texteditor.qrc @@ -0,0 +1,10 @@ + + + images/qt-logo.png + fonts/fontello.ttf + qml/texteditor.qml + texteditor.html + qml/+touch/texteditor.qml + +touch/texteditor.html + + diff --git a/examples/quickcontrols2/wearable/CMakeLists.txt b/examples/quickcontrols2/wearable/CMakeLists.txt new file mode 100644 index 00000000000..123ee6acdc9 --- /dev/null +++ b/examples/quickcontrols2/wearable/CMakeLists.txt @@ -0,0 +1,210 @@ +# Generated from wearable.pro. + +cmake_minimum_required(VERSION 3.16) +project(wearable LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/wearable") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS QuickControls2) + +qt_add_executable(wearable + wearable.cpp +) +set_target_properties(wearable PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(wearable PUBLIC + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) +# special case begin +if(UNIX AND NOT APPLE AND CMAKE_CROSSCOMPILING) + find_package(Qt6 COMPONENTS QuickTemplates2) + # Work around QTBUG-86533 + target_link_libraries(wearable PRIVATE Qt::QuickTemplates2) +endif() +# special case end + +# Resources: +set(wearable_resource_files + "icons/wearable/36x36/alarms.png" + "icons/wearable/36x36/fitness.png" + "icons/wearable/36x36/navigation.png" + "icons/wearable/36x36/notifications.png" + "icons/wearable/36x36/settings.png" + "icons/wearable/36x36/weather.png" + "icons/wearable/36x36/worldclock.png" + "icons/wearable/36x36@2/alarms.png" + "icons/wearable/36x36@2/fitness.png" + "icons/wearable/36x36@2/navigation.png" + "icons/wearable/36x36@2/notifications.png" + "icons/wearable/36x36@2/settings.png" + "icons/wearable/36x36@2/weather.png" + "icons/wearable/36x36@2/worldclock.png" + "icons/wearable/index.theme" + "images/back.png" + "images/back@2x.png" + "images/background-dark.png" + "images/background-light.png" + "images/home.png" + "images/home@2x.png" + "qml/Alarms/AlarmsPage.qml" + "qml/DemoMode.qml" + "qml/DemoModeIndicator.qml" + "qml/Fitness/FitnessPage.qml" + "qml/Fitness/fitness.js" + "qml/Fitness/images/man-running-dark.png" + "qml/Fitness/images/man-running-dark@2x.png" + "qml/Fitness/images/man-running-light.png" + "qml/Fitness/images/man-running-light@2x.png" + "qml/Fitness/images/man-walking-dark.png" + "qml/Fitness/images/man-walking-dark@2x.png" + "qml/Fitness/images/man-walking-light.png" + "qml/Fitness/images/man-walking-light@2x.png" + "qml/LauncherPage.qml" + "qml/NaviButton.qml" + "qml/Navigation/NavigationPage.qml" + "qml/Navigation/RouteElement.qml" + "qml/Navigation/images/end.png" + "qml/Navigation/images/end@2x.png" + "qml/Navigation/images/leftturn-dark.png" + "qml/Navigation/images/leftturn-dark@2x.png" + "qml/Navigation/images/leftturn-light.png" + "qml/Navigation/images/leftturn-light@2x.png" + "qml/Navigation/images/navigation-dark.png" + "qml/Navigation/images/navigation-dark@2x.png" + "qml/Navigation/images/navigation-light.png" + "qml/Navigation/images/navigation-light@2x.png" + "qml/Navigation/images/rightturn-dark.png" + "qml/Navigation/images/rightturn-dark@2x.png" + "qml/Navigation/images/rightturn-light.png" + "qml/Navigation/images/rightturn-light@2x.png" + "qml/Navigation/images/start.png" + "qml/Navigation/images/start@2x.png" + "qml/Navigation/images/straight-dark.png" + "qml/Navigation/images/straight-dark@2x.png" + "qml/Navigation/images/straight-light.png" + "qml/Navigation/images/straight-light@2x.png" + "qml/Navigation/images/uturn.png" + "qml/Navigation/images/uturn@2x.png" + "qml/Navigation/navigation.js" + "qml/Navigation/walk_route.json" + "qml/Notifications/NotificationsPage.qml" + "qml/Notifications/images/avatarf-dark.png" + "qml/Notifications/images/avatarf-dark@2x.png" + "qml/Notifications/images/avatarf-light.png" + "qml/Notifications/images/avatarf-light@2x.png" + "qml/Notifications/images/avatarm-dark.png" + "qml/Notifications/images/avatarm-dark@2x.png" + "qml/Notifications/images/avatarm-light.png" + "qml/Notifications/images/avatarm-light@2x.png" + "qml/Notifications/images/missedcall-dark.png" + "qml/Notifications/images/missedcall-dark@2x.png" + "qml/Notifications/images/missedcall-light.png" + "qml/Notifications/images/missedcall-light@2x.png" + "qml/Notifications/notifications.js" + "qml/Settings/SettingsPage.qml" + "qml/Settings/images/bluetooth-dark.png" + "qml/Settings/images/bluetooth-dark@2x.png" + "qml/Settings/images/bluetooth-light.png" + "qml/Settings/images/bluetooth-light@2x.png" + "qml/Settings/images/brightness-dark.png" + "qml/Settings/images/brightness-dark@2x.png" + "qml/Settings/images/brightness-light.png" + "qml/Settings/images/brightness-light@2x.png" + "qml/Settings/images/demo-mode-dark.png" + "qml/Settings/images/demo-mode-dark@2x.png" + "qml/Settings/images/demo-mode-light.png" + "qml/Settings/images/demo-mode-light@2x.png" + "qml/Settings/images/demo-mode-white.png" + "qml/Settings/images/demo-mode-white@2x.png" + "qml/Settings/images/theme-dark.png" + "qml/Settings/images/theme-dark@2x.png" + "qml/Settings/images/theme-light.png" + "qml/Settings/images/theme-light@2x.png" + "qml/Settings/images/wifi-dark.png" + "qml/Settings/images/wifi-dark@2x.png" + "qml/Settings/images/wifi-light.png" + "qml/Settings/images/wifi-light@2x.png" + "qml/Style/PageIndicator.qml" + "qml/Style/Slider.qml" + "qml/Style/Switch.qml" + "qml/Style/UIStyle.qml" + "qml/Style/qmldir" + "qml/SwipeViewPage.qml" + "qml/Weather/WeatherPage.qml" + "qml/Weather/images/humidity-dark.png" + "qml/Weather/images/humidity-dark@2x.png" + "qml/Weather/images/humidity-light.png" + "qml/Weather/images/humidity-light@2x.png" + "qml/Weather/images/pressure-dark.png" + "qml/Weather/images/pressure-dark@2x.png" + "qml/Weather/images/pressure-light.png" + "qml/Weather/images/pressure-light@2x.png" + "qml/Weather/images/sunrise-dark.png" + "qml/Weather/images/sunrise-dark@2x.png" + "qml/Weather/images/sunrise-light.png" + "qml/Weather/images/sunrise-light@2x.png" + "qml/Weather/images/sunset-dark.png" + "qml/Weather/images/sunset-dark@2x.png" + "qml/Weather/images/sunset-light.png" + "qml/Weather/images/sunset-light@2x.png" + "qml/Weather/images/temperature-dark.png" + "qml/Weather/images/temperature-dark@2x.png" + "qml/Weather/images/temperature-light.png" + "qml/Weather/images/temperature-light@2x.png" + "qml/Weather/images/wind-dark.png" + "qml/Weather/images/wind-dark@2x.png" + "qml/Weather/images/wind-light.png" + "qml/Weather/images/wind-light@2x.png" + "qml/Weather/weather.js" + "qml/Weather/weather.json" + "qml/WorldClock/Clock.qml" + "qml/WorldClock/WorldClockPage.qml" + "qml/WorldClock/images/center.png" + "qml/WorldClock/images/center@2x.png" + "qml/WorldClock/images/second.png" + "qml/WorldClock/images/second@2x.png" + "qml/WorldClock/images/swissdaydial.png" + "qml/WorldClock/images/swissdaydial@2x.png" + "qml/WorldClock/images/swissdayhour.png" + "qml/WorldClock/images/swissdayhour@2x.png" + "qml/WorldClock/images/swissdayminute.png" + "qml/WorldClock/images/swissdayminute@2x.png" + "qml/WorldClock/images/swissnightdial.png" + "qml/WorldClock/images/swissnightdial@2x.png" + "qml/WorldClock/images/swissnighthour.png" + "qml/WorldClock/images/swissnighthour@2x.png" + "qml/WorldClock/images/swissnightminute.png" + "qml/WorldClock/images/swissnightminute@2x.png" + "wearable.qml" +) + +qt6_add_resources(wearable "wearable" + PREFIX + "/" + FILES + ${wearable_resource_files} +) + +install(TARGETS wearable + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols2/wearable/doc/images/qtquickcontrols2-wearable.png b/examples/quickcontrols2/wearable/doc/images/qtquickcontrols2-wearable.png new file mode 100644 index 00000000000..c61055340c1 Binary files /dev/null and b/examples/quickcontrols2/wearable/doc/images/qtquickcontrols2-wearable.png differ diff --git a/examples/quickcontrols2/wearable/doc/src/qtquickcontrols2-wearable.qdoc b/examples/quickcontrols2/wearable/doc/src/qtquickcontrols2-wearable.qdoc new file mode 100644 index 00000000000..7e4edea49ed --- /dev/null +++ b/examples/quickcontrols2/wearable/doc/src/qtquickcontrols2-wearable.qdoc @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example wearable + \keyword Qt Quick Controls - Wearable Demo + \title Qt Quick Controls - Wearable Demo + \keyword Qt Quick Controls 2 - Wearable Demo + \ingroup qtquickcontrols2-examples + \brief Demonstrates an application launcher designed for wearable devices. + + \image qtquickcontrols2-wearable.png + + The \e {Wearable Demo} consists of an application launcher and a collection + of small and simple example applications aimed at wearable devices. + + \section1 Structure + + The main .qml file, \c wearable.qml, consists of an ApplicationWindow, a StackView + for a stack-based navigation model, and buttons for interactive navigation. + + \quotefromfile wearable/wearable.qml + \skipuntil import "qml/Style" + \printuntil id: window + \dots + \skipto header + \printuntil id: homeButton + \dots 8 + \skipto onClicked + \printuntil } + \printuntil id: backButton + \dots 8 + \skipto onClicked + \printuntil id: stackView + \dots 8 + \skipuntil initialItem + \printuntil /^\}/ + + \section1 Styling + + The demo uses a custom \l {Styling Qt Quick Controls}{Qt Quick Controls 2 style} + embedded into the demo's resources. The custom style is implemented for a + few controls only, as it is specific to this particular demo. It uses a + singleton type for various styling attributes, such as fonts and colors. + + \list + \li \c qml/Style/PageIndicator.qml + \li \c qml/Style/Slider.qml + \li \c qml/Style/Switch.qml + \li \c qml/Style/UIStyle.qml + \endlist + + The style is applied in \c main() in \c wearable.cpp: + + \snippet wearable/wearable.cpp style + + The main benefit of using the built-in styling system is that the style selection + is fully transparent to the application code. There is no need to import a specific + folder that contains the styled controls. This way, the application can be run with + other styles too. + + \section1 Custom Type + + The demo application contains a custom button type implemented in + \c qml/NaviButton.qml. The navigation button is used as a home and back + button in \c wearable.qml. \c NaviButton extends the AbstractButton type + with properties that control the slide in and slide out transitions and + the button image. + + \quotefromfile wearable/qml/NaviButton.qml + \skipuntil import "Style" + \printuntil id: image + \dots 8 + \skipuntil } + \printuntil background: + \dots 8 + \skipto } + \printuntil /^\}/ + + \section1 Icons + + The demo ships a custom icon theme. The icons are bundled into the \c :/icons + folder in the application's resources. The \c index.theme file lists the contents + of the icon theme: + + \quotefile wearable/icons/wearable/index.theme + + Finally, the icon theme is selected in \c main(): + + \snippet wearable/wearable.cpp icons + + The icons are used on the Launcher Page, which is presented below. See + \l {Icons in Qt Quick Controls} for more details about icons and themes. + + \section1 Launcher Page + + The application launcher is implemented using a circular PathView in + \c LauncherPage.qml. Each application is in a separate .qml file, + which is added to the ListModel on the launcher page. + + \quotefromfile wearable/qml/LauncherPage.qml + \skipto PathView + \printuntil signal launched + \dots + \skipto ListModel + \printuntil } + \dots 8 + \printline ListElement + \skipto "Settings" + \printuntil delegate: + \dots 8 + \skipto icon.width + \printuntil icon.name + \dots 8 + \skipto onClicked: + \printto path: + \dots + \skipto /^\}/ + \printline } + + \section1 Applications + + The applications are designed for touch input based on what input methods + or communication means are typically offered by wearable devices. + + Most applications have their own JavaScript files that act as dummy + application backends. They illustrate fetching external data and help + manipulating or converting the data. In the \c Navigation and \c Weather + applications, data acquisition is implemented using \l XMLHttpRequest to + read from local files. These files were generated by storing responses from + remote servers in JSON format. This code can be easily modified to acquire + data from remote servers. + + \section2 Navigation + + This application displays a walking route from source to destination. This + route information is obtained using the REST API provided by + \l {https://www.openstreetmap.org/}. The API response is in JSON format, which + is parsed using JavaScript by the application. Currently, it is not possible + to specify the source and destination from within the application, but it can + be added based on the device's capabilities. For example, user input + could be implemented as screens with input fields, or can be communicated + over Bluetooth/Wifi from a paired application running on another device + such as a smart phone or PC. + + \section2 Weather + + This application displays weather information such as temperature, sunrise + and sunset times, air pressure, and so on. This information is obtained + from \l {https://openweathermap.org/} using its REST API. The API response is + in JSON format, which is parsed using JavaScript by the application. This + application can also be modified by adding screens to obtain weather data for + a given location. + + \section2 World Clock + + This application displays a world clock for different cities. As of now, the + list of cities is hard-coded in the application, but that can be changed based + on the input capabilities of the device. + + \section2 Others + + The remaining applications return static data for now, but they can be + modified to process response data obtained from respective services. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36/alarms.png b/examples/quickcontrols2/wearable/icons/wearable/36x36/alarms.png new file mode 100644 index 00000000000..252dcf938f6 Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36/alarms.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36/fitness.png b/examples/quickcontrols2/wearable/icons/wearable/36x36/fitness.png new file mode 100644 index 00000000000..4b0679e271a Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36/fitness.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36/navigation.png b/examples/quickcontrols2/wearable/icons/wearable/36x36/navigation.png new file mode 100644 index 00000000000..08e73005fdd Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36/navigation.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36/notifications.png b/examples/quickcontrols2/wearable/icons/wearable/36x36/notifications.png new file mode 100644 index 00000000000..6309312122e Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36/notifications.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36/settings.png b/examples/quickcontrols2/wearable/icons/wearable/36x36/settings.png new file mode 100644 index 00000000000..c1552fb3601 Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36/settings.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36/weather.png b/examples/quickcontrols2/wearable/icons/wearable/36x36/weather.png new file mode 100644 index 00000000000..61be79a24fc Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36/weather.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36/worldclock.png b/examples/quickcontrols2/wearable/icons/wearable/36x36/worldclock.png new file mode 100644 index 00000000000..d23e32e5129 Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36/worldclock.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36@2/alarms.png b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/alarms.png new file mode 100644 index 00000000000..6047e231fc5 Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/alarms.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36@2/fitness.png b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/fitness.png new file mode 100644 index 00000000000..1d2caa33854 Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/fitness.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36@2/navigation.png b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/navigation.png new file mode 100644 index 00000000000..7d4a62b9e1d Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/navigation.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36@2/notifications.png b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/notifications.png new file mode 100644 index 00000000000..8d3b333350a Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/notifications.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36@2/settings.png b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/settings.png new file mode 100644 index 00000000000..e89188743dc Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/settings.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36@2/weather.png b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/weather.png new file mode 100644 index 00000000000..0a2ae7d54e6 Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/weather.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/36x36@2/worldclock.png b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/worldclock.png new file mode 100644 index 00000000000..ca6eb879e19 Binary files /dev/null and b/examples/quickcontrols2/wearable/icons/wearable/36x36@2/worldclock.png differ diff --git a/examples/quickcontrols2/wearable/icons/wearable/index.theme b/examples/quickcontrols2/wearable/icons/wearable/index.theme new file mode 100644 index 00000000000..da702d4a920 --- /dev/null +++ b/examples/quickcontrols2/wearable/icons/wearable/index.theme @@ -0,0 +1,14 @@ +[Icon Theme] +Name=Wearable +Comment=Qt Quick Controls 2 Wearable Demo Icon Theme + +Directories=36x36,36x36@2 + +[36x36] +Size=36 +Type=Fixed + +[36x36@2] +Size=36 +Scale=2 +Type=Fixed diff --git a/examples/quickcontrols2/wearable/images/back.png b/examples/quickcontrols2/wearable/images/back.png new file mode 100644 index 00000000000..cf80aa65f54 Binary files /dev/null and b/examples/quickcontrols2/wearable/images/back.png differ diff --git a/examples/quickcontrols2/wearable/images/back@2x.png b/examples/quickcontrols2/wearable/images/back@2x.png new file mode 100644 index 00000000000..02f27981e05 Binary files /dev/null and b/examples/quickcontrols2/wearable/images/back@2x.png differ diff --git a/examples/quickcontrols2/wearable/images/back@3x.png b/examples/quickcontrols2/wearable/images/back@3x.png new file mode 100644 index 00000000000..6d2d6cf120f Binary files /dev/null and b/examples/quickcontrols2/wearable/images/back@3x.png differ diff --git a/examples/quickcontrols2/wearable/images/back@4x.png b/examples/quickcontrols2/wearable/images/back@4x.png new file mode 100644 index 00000000000..03193681b1b Binary files /dev/null and b/examples/quickcontrols2/wearable/images/back@4x.png differ diff --git a/examples/quickcontrols2/wearable/images/background-dark.png b/examples/quickcontrols2/wearable/images/background-dark.png new file mode 100644 index 00000000000..6a8c0761aa7 Binary files /dev/null and b/examples/quickcontrols2/wearable/images/background-dark.png differ diff --git a/examples/quickcontrols2/wearable/images/background-light.png b/examples/quickcontrols2/wearable/images/background-light.png new file mode 100644 index 00000000000..913befab821 Binary files /dev/null and b/examples/quickcontrols2/wearable/images/background-light.png differ diff --git a/examples/quickcontrols2/wearable/images/home.png b/examples/quickcontrols2/wearable/images/home.png new file mode 100644 index 00000000000..b6ee1459f7c Binary files /dev/null and b/examples/quickcontrols2/wearable/images/home.png differ diff --git a/examples/quickcontrols2/wearable/images/home@2x.png b/examples/quickcontrols2/wearable/images/home@2x.png new file mode 100644 index 00000000000..d5595b2378d Binary files /dev/null and b/examples/quickcontrols2/wearable/images/home@2x.png differ diff --git a/examples/quickcontrols2/wearable/images/home@3x.png b/examples/quickcontrols2/wearable/images/home@3x.png new file mode 100644 index 00000000000..9a5188d22bd Binary files /dev/null and b/examples/quickcontrols2/wearable/images/home@3x.png differ diff --git a/examples/quickcontrols2/wearable/images/home@4x.png b/examples/quickcontrols2/wearable/images/home@4x.png new file mode 100644 index 00000000000..c4d2eb515a2 Binary files /dev/null and b/examples/quickcontrols2/wearable/images/home@4x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Alarms/AlarmsPage.qml b/examples/quickcontrols2/wearable/qml/Alarms/AlarmsPage.qml new file mode 100644 index 00000000000..eda81e1f2ff --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Alarms/AlarmsPage.qml @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as QQC2 +import ".." +import "../Style" + +Item { + QQC2.SwipeView { + id: svAlarmsContainer + + anchors.fill: parent + + Repeater { + model: ListModel { + ListElement { name: qsTr("Week Days"); state: true; time: "06:00 AM" } + ListElement { name: qsTr("Week Ends"); state: false; time: "07:30 AM" } + } + + SwipeViewPage { + property alias stateSwitch: stateSwitch + + Column { + spacing: 30 + anchors.centerIn: parent + + QQC2.Switch { + id: stateSwitch + checked: model.state + anchors.left: nameLabel.right + } + + Text { + text: model.time + anchors.horizontalCenter: parent.horizontalCenter + verticalAlignment: Text.AlignVCenter + height: UIStyle.fontSizeXL + font.bold: stateSwitch.checked + font.pixelSize: stateSwitch.checked ? UIStyle.fontSizeXL : UIStyle.fontSizeL + font.letterSpacing: 4 + color: UIStyle.themeColorQtGray1 + } + + Text { + id: nameLabel + text: model.name + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: UIStyle.fontSizeS + font.italic: true + font.bold: true + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray2 + } + } + } + } + } + + QQC2.PageIndicator { + count: svAlarmsContainer.count + currentIndex: svAlarmsContainer.currentIndex + + anchors.bottom: svAlarmsContainer.bottom + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/quickcontrols2/wearable/qml/DemoMode.qml b/examples/quickcontrols2/wearable/qml/DemoMode.qml new file mode 100644 index 00000000000..17b1ea3c31d --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/DemoMode.qml @@ -0,0 +1,258 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +import "Style" + +Item { + property StackView stackView + + SequentialAnimation { + id: demoModeAnimation + running: settings.demoMode + + // Set brightness back to normal. + ScriptAction { script: settings.brightness = 0 } + + // Go back to the launcher page. + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the world clock page. + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("WorldClock/WorldClockPage.qml")) } + PauseAnimation { duration: 2000 } + + // Swipe across a few times. + SequentialAnimation { + loops: 6 + + ScriptAction { script: stackView.currentItem.children[0].incrementCurrentIndex() } + PauseAnimation { duration: 2500 } + } + + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the navigation page. + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("Navigation/NavigationPage.qml")) } + PauseAnimation { duration: 2000 } + + // Flick down a few times. + SequentialAnimation { + loops: 6 + + ScriptAction { script: stackView.currentItem.routeListView.incrementCurrentIndex() } + PauseAnimation { duration: 2000 } + } + + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the weather page. + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("Weather/WeatherPage.qml")) } + PauseAnimation { duration: 2000 } + + // Swipe across a few times. + SequentialAnimation { + loops: 4 + + ScriptAction { script: stackView.currentItem.children[0].incrementCurrentIndex() } + PauseAnimation { duration: 2000 } + } + + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the fitness page. + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("Fitness/FitnessPage.qml")) } + PauseAnimation { duration: 2000 } + + // Swipe across a few times. + SequentialAnimation { + loops: 2 + + ScriptAction { script: stackView.currentItem.children[0].incrementCurrentIndex() } + PauseAnimation { duration: 2000 } + } + + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the notifications page. + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("Notifications/NotificationsPage.qml")) } + + // Flick down a few times. + SequentialAnimation { + loops: 3 + + PauseAnimation { duration: 2000 } + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + } + + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the alarms page. + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("Alarms/AlarmsPage.qml")) } + PauseAnimation { duration: 2000 } + + // Toggle the switch. + ScriptAction { script: stackView.currentItem.children[0].currentItem.stateSwitch.toggle() } + PauseAnimation { duration: 2000 } + + // Go to the next alarm. + ScriptAction { script: stackView.currentItem.children[0].incrementCurrentIndex() } + PauseAnimation { duration: 2000 } + + // Toggle the switch there too. + ScriptAction { script: stackView.currentItem.children[0].currentItem.stateSwitch.toggle() } + PauseAnimation { duration: 2000 } + + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the settings page. + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("Settings/SettingsPage.qml")) } + PauseAnimation { duration: 3000 } + + // Toggle the switches. + ScriptAction { script: stackView.currentItem.children[0].currentItem.bluetoothSwitch.toggle() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.children[0].currentItem.wirelessSwitch.toggle() } + PauseAnimation { duration: 3000 } + + // Go to the next page. + ScriptAction { script: stackView.currentItem.children[0].incrementCurrentIndex() } + + // Play with the brightness slider. + // First, set it to full brightness so we start in the correct state. + ScriptAction { + script: { + var brightnessSlider = stackView.currentItem.children[0].currentItem.brightnessSlider + brightnessSlider.value = 0 + // increase()/decrease() are not a result of user interaction and + // hence moved() will not be emitted, so we do it ourselves. + brightnessSlider.moved() + } + } + + // Decrease the brightness. + SequentialAnimation { + loops: 3 + + PauseAnimation { duration: 1000 } + ScriptAction { + script: { + var brightnessSlider = stackView.currentItem.children[0].currentItem.brightnessSlider + brightnessSlider.decrease() + brightnessSlider.moved() + } + } + } + + // Increase the brightness back to full. + PauseAnimation { duration: 3000 } + SequentialAnimation { + loops: 3 + + PauseAnimation { duration: 1000 } + ScriptAction { + script: { + var brightnessSlider = stackView.currentItem.children[0].currentItem.brightnessSlider + brightnessSlider.increase() + brightnessSlider.moved() + } + } + } + + // Toggle the dark theme switch. + PauseAnimation { duration: 2000 } + ScriptAction { + script: { + var darkThemeSwitch = stackView.currentItem.children[0].currentItem.darkThemeSwitch + darkThemeSwitch.toggle() + // As above, only proper user interaction results in toggled() being emitted, + // so we do it ourselves. + darkThemeSwitch.toggled() + } + } + PauseAnimation { duration: 4000 } + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + } +} diff --git a/examples/quickcontrols2/wearable/qml/DemoModeIndicator.qml b/examples/quickcontrols2/wearable/qml/DemoModeIndicator.qml new file mode 100644 index 00000000000..a264a79b3d2 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/DemoModeIndicator.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as QQC2 +import "Style" + +Item { + id: root + width: row.implicitWidth + margins * 2 + + readonly property int topMargin: 24 + readonly property int margins: 12 + + Behavior on y { + NumberAnimation {} + } + + Rectangle { + id: demoModeIndicatorBg + anchors.fill: parent + anchors.topMargin: -topMargin + radius: 20 + color: UIStyle.colorRed + } + + Row { + id: row + spacing: 8 + anchors.fill: parent + anchors.leftMargin: margins + anchors.rightMargin: margins + + Image { + source: "Settings/images/demo-mode-white.png" + width: height + height: instructionLabel.height * 2 + anchors.verticalCenter: parent.verticalCenter + } + QQC2.Label { + id: instructionLabel + text: "Tap screen to use" + color: UIStyle.colorQtGray10 + anchors.verticalCenter: parent.verticalCenter + } + } +} diff --git a/examples/quickcontrols2/wearable/qml/Fitness/FitnessPage.qml b/examples/quickcontrols2/wearable/qml/Fitness/FitnessPage.qml new file mode 100644 index 00000000000..81bad76195e --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Fitness/FitnessPage.qml @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as QQC2 +import ".." +import "../Style" +import "fitness.js" as FitnessData + +Item { + QQC2.SwipeView { + id: svFitnessContainer + + anchors.fill: parent + + SwipeViewPage { + id: fitnessPage1 + + Column { + anchors.centerIn: parent + spacing: 15 + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Steps: ") + FitnessData.getSteps() + font.italic: true + font.pixelSize: UIStyle.fontSizeM + color: UIStyle.themeColorQtGray1 + } + Image { + anchors.horizontalCenter: parent.horizontalCenter + source: UIStyle.themeImagePath("images/man-walking") + } + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Calories: ") + FitnessData.getCalories() + font.pixelSize: UIStyle.fontSizeS + font.italic: true + color: UIStyle.themeColorQtGray3 + } + } + } + + SwipeViewPage { + id: fitnessPage2 + + Column { + anchors.centerIn: parent + spacing: 15 + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Distance: ") + + FitnessData.getDistance() + + qsTr(" miles") + font.italic: true + font.pixelSize: UIStyle.fontSizeM + color: UIStyle.themeColorQtGray1 + } + Image { + anchors.horizontalCenter: parent.horizontalCenter + source: UIStyle.themeImagePath("images/man-running") + } + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Time: ") + + FitnessData.getTime() + + qsTr(" mins") + font.pixelSize: UIStyle.fontSizeS + font.italic: true + color: UIStyle.themeColorQtGray3 + } + } + } + } + + QQC2.PageIndicator { + count: svFitnessContainer.count + currentIndex: svFitnessContainer.currentIndex + + anchors.bottom: svFitnessContainer.bottom + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/quickcontrols2/wearable/qml/Fitness/fitness.js b/examples/quickcontrols2/wearable/qml/Fitness/fitness.js new file mode 100644 index 00000000000..7e159e2aaf6 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Fitness/fitness.js @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +function getSteps() { + return 105; +} + +function getCalories() { + return 150; +} + +function getDistance() { + return 10; +} + +function getTime() { + return "00:30"; +} diff --git a/examples/quickcontrols2/wearable/qml/Fitness/images/man-running-dark.png b/examples/quickcontrols2/wearable/qml/Fitness/images/man-running-dark.png new file mode 100644 index 00000000000..6c791d61708 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Fitness/images/man-running-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Fitness/images/man-running-dark@2x.png b/examples/quickcontrols2/wearable/qml/Fitness/images/man-running-dark@2x.png new file mode 100644 index 00000000000..e9abae9de41 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Fitness/images/man-running-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Fitness/images/man-running-light.png b/examples/quickcontrols2/wearable/qml/Fitness/images/man-running-light.png new file mode 100644 index 00000000000..e7eef12cb3f Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Fitness/images/man-running-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Fitness/images/man-running-light@2x.png b/examples/quickcontrols2/wearable/qml/Fitness/images/man-running-light@2x.png new file mode 100644 index 00000000000..79861f5718c Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Fitness/images/man-running-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Fitness/images/man-walking-dark.png b/examples/quickcontrols2/wearable/qml/Fitness/images/man-walking-dark.png new file mode 100644 index 00000000000..6d455b4925f Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Fitness/images/man-walking-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Fitness/images/man-walking-dark@2x.png b/examples/quickcontrols2/wearable/qml/Fitness/images/man-walking-dark@2x.png new file mode 100644 index 00000000000..a3ac08baf3b Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Fitness/images/man-walking-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Fitness/images/man-walking-light.png b/examples/quickcontrols2/wearable/qml/Fitness/images/man-walking-light.png new file mode 100644 index 00000000000..f963f8897bd Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Fitness/images/man-walking-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Fitness/images/man-walking-light@2x.png b/examples/quickcontrols2/wearable/qml/Fitness/images/man-walking-light@2x.png new file mode 100644 index 00000000000..1b4d7592d67 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Fitness/images/man-walking-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/LauncherPage.qml b/examples/quickcontrols2/wearable/qml/LauncherPage.qml new file mode 100644 index 00000000000..e0de97c3de3 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/LauncherPage.qml @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as QQC2 +import "Style" + +PathView { + id: circularView + + signal launched(string page) + + readonly property int cX: width / 2 + readonly property int cY: height / 2 + readonly property int itemSize: size / 4 + readonly property int size: Math.min(width - 80, height) + readonly property int radius: size / 2 - itemSize / 3 + + snapMode: PathView.SnapToItem + + model: ListModel { + ListElement { + title: qsTr("World Clock") + icon: "worldclock" + page: "WorldClock/WorldClockPage.qml" + } + ListElement { + title: qsTr("Navigation") + icon: "navigation" + page: "Navigation/NavigationPage.qml" + } + ListElement { + title: qsTr("Weather") + icon: "weather" + page: "Weather/WeatherPage.qml" + } + ListElement { + title: qsTr("Fitness") + icon: "fitness" + page: "Fitness/FitnessPage.qml" + } + ListElement { + title: qsTr("Notifications") + icon: "notifications" + page: "Notifications/NotificationsPage.qml" + } + ListElement { + title: qsTr("Alarm") + icon: "alarms" + page: "Alarms/AlarmsPage.qml" + } + ListElement { + title: qsTr("Settings") + icon: "settings" + page: "Settings/SettingsPage.qml" + } + } + + delegate: QQC2.RoundButton { + width: circularView.itemSize + height: circularView.itemSize + + property string title: model.title + + icon.width: 36 + icon.height: 36 + icon.name: model.icon + opacity: PathView.itemOpacity + padding: 12 + + background: Rectangle { + radius: width / 2 + border.width: 3 + border.color: parent.PathView.isCurrentItem ? UIStyle.colorQtPrimGreen : UIStyle.themeColorQtGray4 + } + + onClicked: { + if (PathView.isCurrentItem) + circularView.launched(Qt.resolvedUrl(page)) + else + circularView.currentIndex = index + } + } + + path: Path { + startX: circularView.cX + startY: circularView.cY + PathAttribute { + name: "itemOpacity" + value: 1.0 + } + PathLine { + x: circularView.cX + circularView.radius + y: circularView.cY + } + PathAttribute { + name: "itemOpacity" + value: 0.7 + } + PathArc { + x: circularView.cX - circularView.radius + y: circularView.cY + radiusX: circularView.radius + radiusY: circularView.radius + useLargeArc: true + direction: PathArc.Clockwise + } + PathAttribute { + name: "itemOpacity" + value: 0.5 + } + PathArc { + x: circularView.cX + circularView.radius + y: circularView.cY + radiusX: circularView.radius + radiusY: circularView.radius + useLargeArc: true + direction: PathArc.Clockwise + } + PathAttribute { + name: "itemOpacity" + value: 0.3 + } + } + + Text { + id: appTitle + + property Item currentItem: circularView.currentItem + + visible: currentItem ? currentItem.PathView.itemOpacity === 1.0 : 0 + + text: currentItem ? currentItem.title : "" + anchors.centerIn: parent + anchors.verticalCenterOffset: (circularView.itemSize + height) / 2 + + font.bold: true + font.pixelSize: circularView.itemSize / 3 + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } +} diff --git a/examples/quickcontrols2/wearable/qml/NaviButton.qml b/examples/quickcontrols2/wearable/qml/NaviButton.qml new file mode 100644 index 00000000000..1d4dc552ddf --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/NaviButton.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as QQC2 +import "Style" + +QQC2.AbstractButton { + id: button + + property int edge: Qt.TopEdge + property alias imageSource: image.source + + contentItem: Image { + id: image + fillMode: Image.Pad + sourceSize { width: 40; height: 40 } // ### TODO: resize the image + } + + background: Rectangle { + height: button.height * 4 + width: height + radius: width / 2 + + anchors.horizontalCenter: button.horizontalCenter + anchors.top: edge === Qt.BottomEdge ? button.top : undefined + anchors.bottom: edge === Qt.TopEdge ? button.bottom : undefined + + color: UIStyle.colorQtGray2 + } + + transform: Translate { + Behavior on y { NumberAnimation { } } + y: enabled ? 0 : edge === Qt.TopEdge ? -button.height : button.height + } +} diff --git a/examples/quickcontrols2/wearable/qml/Navigation/NavigationPage.qml b/examples/quickcontrols2/wearable/qml/Navigation/NavigationPage.qml new file mode 100644 index 00000000000..06c9909eb70 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Navigation/NavigationPage.qml @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../Style" +import "navigation.js" as NavigationData + +Item { + property alias routeListView: routeView + + Column { + anchors.fill: parent + anchors.margins: 2 + spacing: 2 + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + height: titleRow.height + + color: UIStyle.themeColorQtGray9 + + Row { + id: titleRow + spacing: 10 + anchors.centerIn: parent + + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/navigation") + fillMode: Image.PreserveAspectCrop + } + Text { + anchors.verticalCenter: parent.verticalCenter + text: qsTr("Walking") + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 2 + color: UIStyle.themeColorQtGray2 + } + } + } + + ListModel { + id: routeModel + } + + ListView { + id: routeView + + width: parent.width + height: parent.height - titleRow.height - parent.spacing + property var imageList: [UIStyle.themeImagePath("images/straight"), + UIStyle.themeImagePath("images/leftturn"), + UIStyle.themeImagePath("images/rightturn"), + "images/uturn.png", + "images/start.png", + "images/end.png"] + + clip: true + focus: true + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + model: routeModel + delegate: RouteElement { + width: routeView.width + height: routeView.height + } + } + } + Component.onCompleted: { + NavigationData.requestNavigationRoute(routeModel) + } +} diff --git a/examples/quickcontrols2/wearable/qml/Navigation/RouteElement.qml b/examples/quickcontrols2/wearable/qml/Navigation/RouteElement.qml new file mode 100644 index 00000000000..4f5262f1d78 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Navigation/RouteElement.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../Style" + +Rectangle { + color: UIStyle.themeColorQtGray8 + + Row { + spacing: 5 + width: parent.width - 80 + anchors.centerIn: parent + + Image { + id: img + anchors.verticalCenter: parent.verticalCenter + source: navImage + fillMode: Image.PreserveAspectFit + } + + Column { + spacing: 5 + width: parent.width - img.width + anchors.verticalCenter: parent.verticalCenter + + Text { + width: parent.width + wrapMode: Text.WordWrap + text: navInstruction + font.pixelSize: UIStyle.fontSizeS + verticalAlignment: Text.AlignVCenter + padding: 1 + color: UIStyle.themeColorQtGray1 + } + + Text { + width: parent.width + wrapMode: Text.WordWrap + text: navAuxInfo + font.pixelSize: UIStyle.fontSizeXS + verticalAlignment: Text.AlignVCenter + padding: 1 + color: UIStyle.themeColorQtGray2 + } + } + } +} diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/end.png b/examples/quickcontrols2/wearable/qml/Navigation/images/end.png new file mode 100644 index 00000000000..4805ad82074 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/end.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/end@2x.png b/examples/quickcontrols2/wearable/qml/Navigation/images/end@2x.png new file mode 100644 index 00000000000..e91d537465b Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/end@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/leftturn-dark.png b/examples/quickcontrols2/wearable/qml/Navigation/images/leftturn-dark.png new file mode 100644 index 00000000000..66d258f5ace Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/leftturn-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/leftturn-dark@2x.png b/examples/quickcontrols2/wearable/qml/Navigation/images/leftturn-dark@2x.png new file mode 100644 index 00000000000..639deb81cf0 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/leftturn-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/leftturn-light.png b/examples/quickcontrols2/wearable/qml/Navigation/images/leftturn-light.png new file mode 100644 index 00000000000..1346e8eaff1 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/leftturn-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/leftturn-light@2x.png b/examples/quickcontrols2/wearable/qml/Navigation/images/leftturn-light@2x.png new file mode 100644 index 00000000000..268a6283f97 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/leftturn-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/marker.png b/examples/quickcontrols2/wearable/qml/Navigation/images/marker.png new file mode 100644 index 00000000000..4805ad82074 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/marker.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/navigation-dark.png b/examples/quickcontrols2/wearable/qml/Navigation/images/navigation-dark.png new file mode 100644 index 00000000000..b80b7b610f9 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/navigation-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/navigation-dark@2x.png b/examples/quickcontrols2/wearable/qml/Navigation/images/navigation-dark@2x.png new file mode 100644 index 00000000000..b198aa3d9ab Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/navigation-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/navigation-light.png b/examples/quickcontrols2/wearable/qml/Navigation/images/navigation-light.png new file mode 100644 index 00000000000..08e73005fdd Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/navigation-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/navigation-light@2x.png b/examples/quickcontrols2/wearable/qml/Navigation/images/navigation-light@2x.png new file mode 100644 index 00000000000..7d4a62b9e1d Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/navigation-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/rightturn-dark.png b/examples/quickcontrols2/wearable/qml/Navigation/images/rightturn-dark.png new file mode 100644 index 00000000000..6a779dadc40 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/rightturn-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/rightturn-dark@2x.png b/examples/quickcontrols2/wearable/qml/Navigation/images/rightturn-dark@2x.png new file mode 100644 index 00000000000..13143c2e2cd Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/rightturn-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/rightturn-light.png b/examples/quickcontrols2/wearable/qml/Navigation/images/rightturn-light.png new file mode 100644 index 00000000000..a6be08c1a13 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/rightturn-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/rightturn-light@2x.png b/examples/quickcontrols2/wearable/qml/Navigation/images/rightturn-light@2x.png new file mode 100644 index 00000000000..58f04b50528 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/rightturn-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/start.png b/examples/quickcontrols2/wearable/qml/Navigation/images/start.png new file mode 100644 index 00000000000..41de60e60ce Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/start.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/start@2x.png b/examples/quickcontrols2/wearable/qml/Navigation/images/start@2x.png new file mode 100644 index 00000000000..6fe3ba9dbdd Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/start@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/straight-dark.png b/examples/quickcontrols2/wearable/qml/Navigation/images/straight-dark.png new file mode 100644 index 00000000000..3f4ab664300 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/straight-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/straight-dark@2x.png b/examples/quickcontrols2/wearable/qml/Navigation/images/straight-dark@2x.png new file mode 100644 index 00000000000..f5baa6da42b Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/straight-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/straight-light.png b/examples/quickcontrols2/wearable/qml/Navigation/images/straight-light.png new file mode 100644 index 00000000000..1321b97aa53 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/straight-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/straight-light@2x.png b/examples/quickcontrols2/wearable/qml/Navigation/images/straight-light@2x.png new file mode 100644 index 00000000000..a2d3c4c2abb Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/straight-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/uturn.png b/examples/quickcontrols2/wearable/qml/Navigation/images/uturn.png new file mode 100644 index 00000000000..596046ca9a2 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/uturn.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/images/uturn@2x.png b/examples/quickcontrols2/wearable/qml/Navigation/images/uturn@2x.png new file mode 100644 index 00000000000..659f103573d Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Navigation/images/uturn@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Navigation/navigation.js b/examples/quickcontrols2/wearable/qml/Navigation/navigation.js new file mode 100644 index 00000000000..0414731d471 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Navigation/navigation.js @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +function requestNavigationRoute(rModel) { + var xhr = new XMLHttpRequest; + xhr.open("GET", "walk_route.json"); + xhr.onreadystatechange = function () { + if (xhr.readyState === XMLHttpRequest.DONE) { + var a = JSON.parse(xhr.responseText); + var steps = a.routes[0].legs[0].steps; + + for (var step in steps) { + var maneuver = steps[step].maneuver; + var duration = steps[step].duration; + var distance = steps[step].distance; + + rModel.append({ + navInstruction: maneuver.instruction, + navImage: getNavigationImage( + maneuver.type, + maneuver.modifier, + routeView.imageList), + navAuxInfo: getAuxInfo(distance, + duration) + }); + } + } + } + xhr.send(); +} + +function getNavigationImage(maneuverType, maneuverModifier, imageList) { + var imageToReturn; + if (maneuverType === "depart") { + imageToReturn = imageList[4]; + } else if (maneuverType === "arrive") { + imageToReturn = imageList[5]; + } else if (maneuverType === "turn") { + if (maneuverModifier.search("left") >= 0) + imageToReturn = imageList[1]; + else if (maneuverModifier.search("right") >= 0) + imageToReturn = imageList[2]; + else + imageToReturn = imageList[0]; + } else { + if (maneuverModifier === "uturn") { + imageToReturn = imageList[3]; + } else { + imageToReturn = imageList[0]; + } + } + + return imageToReturn; +} + +function getAuxInfo(distInMeters, timeInSecs) { + var distance = convertDistance(distInMeters); + if (distance.length > 0) + return "Distance: " + distance + "\nTime: " + formatSeconds( + timeInSecs); + else + return ""; +} + +function convertDistance(meter) { + var dist = ""; + var feet = (meter * 0.3048).toPrecision(6); + var miles = (meter * 0.000621371).toPrecision(6); + + if (Math.floor(miles) > 1) { + dist += Math.floor(miles) + " mi"; + feet = ((miles - Math.floor(miles)) * 0.3048).toPrecision(6); + } + if (Math.floor(feet) > 1) + dist += Math.floor(feet) + " ft"; + + return dist +} + +function formatSeconds(seconds) { + var date = new Date(1970, 0, 1); + date.setSeconds(seconds); + return date.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1"); +} diff --git a/examples/quickcontrols2/wearable/qml/Navigation/walk_route.json b/examples/quickcontrols2/wearable/qml/Navigation/walk_route.json new file mode 100644 index 00000000000..e69b5cc1875 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Navigation/walk_route.json @@ -0,0 +1 @@ +{"routes":[{"legs":[{"steps":[{"intersections":[{"out":0,"entry":[true],"bearings":[144],"location":[-122.394553,37.795984]},{"out":1,"location":[-122.393896,37.795268],"bearings":[60,150,225,330],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.393179,37.79453],"bearings":[60,135,180,225,315],"entry":[true,true,true,true,false],"in":4},{"out":1,"location":[-122.393072,37.79443],"bearings":[45,135,225,315],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.392787,37.79415],"bearings":[60,135,315],"entry":[true,true,false],"in":2},{"out":1,"location":[-122.392537,37.793915],"bearings":[45,135,225,315],"entry":[true,true,true,false],"in":3},{"out":0,"location":[-122.392448,37.793831],"bearings":[135,225,315],"entry":[true,true,false],"in":2}],"geometry":"{_ueF|d`jVRQdB}ARQh@g@XUVWVW^a@RUv@w@l@q@PQNQ","maneuver":{"bearing_after":144,"location":[-122.394553,37.795984],"bearing_before":0,"type":"depart","instruction":"Head southeast on The Embarcadero"},"duration":230.8,"distance":314.8,"name":"The Embarcadero","mode":"walking"},{"intersections":[{"out":2,"location":[-122.392361,37.793748],"bearings":[45,135,225,315],"entry":[true,true,true,false],"in":3}],"geometry":"}qteFfw_jVHJBDHJ","maneuver":{"bearing_after":225,"type":"turn","modifier":"right","bearing_before":140,"location":[-122.392361,37.793748],"instruction":"Turn right"},"duration":13.2,"distance":18.5,"name":"","mode":"walking"},{"intersections":[{"out":1,"location":[-122.39251,37.793631],"bearings":[45,135,225,315],"entry":[false,true,true,true],"in":0},{"out":1,"location":[-122.391284,37.792459],"bearings":[45,150,225,330],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.391217,37.792342],"bearings":[45,165,225,330],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.391165,37.792231],"bearings":[45,165,225,345],"entry":[true,true,true,false],"in":3},{"out":0,"location":[-122.390884,37.791536],"bearings":[150,285,345],"entry":[true,true,false],"in":2},{"out":1,"location":[-122.390254,37.790827],"bearings":[45,135,210,315],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.390144,37.790745],"bearings":[45,135,225,315],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.390038,37.790665],"bearings":[45,135,240,315],"entry":[true,true,true,false],"in":3},{"out":0,"location":[-122.389245,37.790036],"bearings":[135,225,315],"entry":[true,true,false],"in":2},{"out":1,"location":[-122.38871,37.789596],"bearings":[45,150,210,315],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.388618,37.789494],"bearings":[45,150,225,330],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.388527,37.789394],"bearings":[45,150,225,330],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.388005,37.787907],"bearings":[0,180,270],"entry":[false,true,true],"in":0},{"out":1,"location":[-122.387985,37.787622],"bearings":[0,180,240],"entry":[false,true,true],"in":0},{"out":2,"location":[-122.388005,37.787197],"bearings":[0,90,180,270],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.388015,37.787093],"bearings":[0,90,180,270],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.388022,37.786994],"bearings":[0,90,180,285],"entry":[false,true,true,true],"in":0},{"out":1,"location":[-122.388163,37.785186],"bearings":[0,180,315],"entry":[false,true,true],"in":0},{"out":1,"location":[-122.388184,37.784944],"bearings":[0,180,315],"entry":[false,true,true],"in":0},{"out":2,"location":[-122.388191,37.784855],"bearings":[0,90,180,270],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.388198,37.784748],"bearings":[0,90,180,270],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.388207,37.784633],"bearings":[0,90,180,270],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.388309,37.783373],"bearings":[0,60,180,270],"entry":[false,true,true,true],"in":0},{"out":1,"location":[-122.388376,37.782545],"bearings":[0,180,315],"entry":[false,true,true],"in":0},{"out":1,"location":[-122.388394,37.782316],"bearings":[0,180,315],"entry":[false,true,true],"in":0}],"geometry":"eqteFdx_jVf@k@\\a@|@iAV[FGJMPOTOPKDAPITItAa@r@WXOXQXSTUTWRYNUNS|B}CdAwAPSTQRQ\\W^Q\\KZIrB]^EPCH?\\CZ?Z?\\?XBT@R?~IZF?H@f@@N@T@V@zFRbDLl@@pADV@","maneuver":{"bearing_after":139,"type":"turn","modifier":"left","bearing_before":226,"location":[-122.39251,37.793631],"instruction":"Turn left onto The Embarcadero"},"duration":1055.9,"distance":1450.3,"name":"The Embarcadero","mode":"walking"},{"intersections":[{"out":2,"location":[-122.388431,37.781791],"bearings":[0,90,180,285],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.389672,37.779922],"bearings":[45,135,225,315],"entry":[false,true,true,true],"in":0},{"out":1,"location":[-122.390803,37.77905],"bearings":[45,225,315],"entry":[false,true,true],"in":0},{"out":2,"location":[-122.391916,37.778155],"bearings":[45,135,225,315],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.393073,37.777251],"bearings":[45,75,225,315],"entry":[false,true,true,true],"in":0}],"geometry":"egreFt~~iVR@bABXDVDXHVNXNXVVZp@|@z@hAnCvDLRNTHLFJbArAzApBdB`CTZZb@\\b@@@pCvD","maneuver":{"bearing_after":183,"type":"new name","modifier":"straight","bearing_before":183,"location":[-122.388431,37.781791],"instruction":"Continue straight onto King Street"},"duration":567.4,"distance":782.5,"name":"King Street","mode":"walking"},{"intersections":[{"out":3,"location":[-122.394003,37.776513],"bearings":[45,135,225,300],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.394218,37.776486],"bearings":[45,135,225,315],"entry":[false,true,true,true],"in":0}],"geometry":"efqeFna`jVGJ?NJNNR","maneuver":{"bearing_after":313,"type":"turn","modifier":"straight","bearing_before":225,"location":[-122.394003,37.776513],"instruction":"Go straight"},"duration":26.1,"distance":36.2,"name":"","mode":"walking"},{"intersections":[{"out":2,"location":[-122.394321,37.776405],"bearings":[45,180,315],"entry":[false,true,true],"in":0},{"out":1,"location":[-122.394729,37.776487],"bearings":[45,180],"entry":[false,true],"in":0}],"geometry":"qeqeFnc`jVe@p@A@V\\DF","maneuver":{"bearing_after":315,"type":"turn","modifier":"right","bearing_before":225,"location":[-122.394321,37.776405],"instruction":"Turn right"},"duration":39.9,"distance":55.6,"name":"","mode":"walking"},{"intersections":[{"in":0,"entry":[true],"bearings":[45],"location":[-122.394768,37.776455]}],"geometry":"{eqeFhf`jV","maneuver":{"bearing_after":0,"type":"arrive","modifier":"straight","bearing_before":225,"location":[-122.394729,37.776487],"instruction":"You have arrived at your destination, straight ahead"},"duration":0,"distance":0,"name":"","mode":"walking"}],"summary":"The Embarcadero, King Street","duration":1933.3,"distance":2657.8}],"geometry":"{_ueF|d`jV|LuLV\\`EyElHaD~I_LvB_AdGk@he@|AbBd@bZl`@R~@g@r@\\d@","duration":1933.3,"distance":2657.8}],"waypoints":[{"name":"The Embarcadero","location":[-122.394553,37.795984]},{"name":"","location":[-122.394768,37.776455]}],"code":"Ok"} diff --git a/examples/quickcontrols2/wearable/qml/Notifications/NotificationsPage.qml b/examples/quickcontrols2/wearable/qml/Notifications/NotificationsPage.qml new file mode 100644 index 00000000000..45f0dcb2716 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Notifications/NotificationsPage.qml @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as QQC2 +import "../Style" +import "notifications.js" as NotificationData + +ListView { + id: missedCallsView + + clip: true + focus: true + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + + model: ListModel { + id: missedCallsList + } + + Image { + id: missedCallIcon + width: parent.width / 2 + anchors.right: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/missedcall") + fillMode: Image.Pad + } + + delegate: Item { + height: missedCallsView.height + width: missedCallsView.width / 2 + anchors.left: missedCallsView.contentItem.horizontalCenter + + Column { + spacing: 15 + anchors.verticalCenter: parent.verticalCenter + + Image { + anchors.horizontalCenter: parent.horizontalCenter + source: qsTr("images/avatar%1-%2.png").arg(model.gender).arg(UIStyle.darkTheme ? "dark" : "light") + } + + Text { + text: model.name + anchors.horizontalCenter: parent.horizontalCenter + font.bold: true + font.pixelSize: UIStyle.fontSizeS + color: UIStyle.themeColorQtGray1 + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: date + " " + time + font.pixelSize: UIStyle.fontSizeXS + font.italic: true + color: UIStyle.themeColorQtGray2 + } + } + } + + Component.onCompleted: { + NotificationData.populateData(missedCallsList) + } +} diff --git a/examples/quickcontrols2/wearable/qml/Notifications/images/avatarf-dark.png b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarf-dark.png new file mode 100644 index 00000000000..37bc1f291bb Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarf-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Notifications/images/avatarf-dark@2x.png b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarf-dark@2x.png new file mode 100644 index 00000000000..efcd7cba742 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarf-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Notifications/images/avatarf-light.png b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarf-light.png new file mode 100644 index 00000000000..e38b260724a Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarf-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Notifications/images/avatarf-light@2x.png b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarf-light@2x.png new file mode 100644 index 00000000000..1f28beac6c0 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarf-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Notifications/images/avatarm-dark.png b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarm-dark.png new file mode 100644 index 00000000000..5a2a394d8cc Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarm-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Notifications/images/avatarm-dark@2x.png b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarm-dark@2x.png new file mode 100644 index 00000000000..1a19b0fc8e2 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarm-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Notifications/images/avatarm-light.png b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarm-light.png new file mode 100644 index 00000000000..f0fc7a96060 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarm-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Notifications/images/avatarm-light@2x.png b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarm-light@2x.png new file mode 100644 index 00000000000..64a0f1f9acf Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Notifications/images/avatarm-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Notifications/images/missedcall-dark.png b/examples/quickcontrols2/wearable/qml/Notifications/images/missedcall-dark.png new file mode 100644 index 00000000000..26bcf98ad30 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Notifications/images/missedcall-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Notifications/images/missedcall-dark@2x.png b/examples/quickcontrols2/wearable/qml/Notifications/images/missedcall-dark@2x.png new file mode 100644 index 00000000000..5eb54ce809a Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Notifications/images/missedcall-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Notifications/images/missedcall-light.png b/examples/quickcontrols2/wearable/qml/Notifications/images/missedcall-light.png new file mode 100644 index 00000000000..641e1f0c435 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Notifications/images/missedcall-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Notifications/images/missedcall-light@2x.png b/examples/quickcontrols2/wearable/qml/Notifications/images/missedcall-light@2x.png new file mode 100644 index 00000000000..e8d2d81c9a1 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Notifications/images/missedcall-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Notifications/notifications.js b/examples/quickcontrols2/wearable/qml/Notifications/notifications.js new file mode 100644 index 00000000000..8716c56f05e --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Notifications/notifications.js @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +function populateData(listData) { + listData.append({ + name: "John Doe", + gender: "m", + date: "02/15/2017", + time: "09:20 am" + }); + + listData.append({ + name: "Jane Worldege", + gender: "f", + date: "02/06/2017", + time: "10:15 am" + }); + + listData.append({ + name: "Jennifer Wang", + gender: "f", + date: "02/03/2017", + time: "05:16 pm" + }); +} diff --git a/examples/quickcontrols2/wearable/qml/Settings/SettingsPage.qml b/examples/quickcontrols2/wearable/qml/Settings/SettingsPage.qml new file mode 100644 index 00000000000..347ad417e43 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Settings/SettingsPage.qml @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as QQC2 +import ".." +import "../Style" + +Item { + + QQC2.SwipeView { + id: svSettingsContainer + + anchors.fill: parent + + SwipeViewPage { + id: settingsPage1 + + property alias bluetoothSwitch: bluetoothSwitch + property alias wirelessSwitch: wirelessSwitch + + Column { + anchors.centerIn: parent + spacing: 25 + + Row { + spacing: 50 + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/bluetooth") + } + QQC2.Switch { + id: bluetoothSwitch + anchors.verticalCenter: parent.verticalCenter + checked: settings.bluetooth + onToggled: settings.bluetooth = checked + } + } + Row { + spacing: 50 + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/wifi") + } + QQC2.Switch { + id: wirelessSwitch + anchors.verticalCenter: parent.verticalCenter + checked: settings.wireless + onToggled: settings.wireless = checked + } + } + } + } + + SwipeViewPage { + id: settingsPage2 + + property alias brightnessSlider: brightnessSlider + property alias darkThemeSwitch: darkThemeSwitch + + Column { + anchors.centerIn: parent + spacing: 2 + + Column { + Image { + anchors.horizontalCenter: parent.horizontalCenter + source: UIStyle.themeImagePath("images/brightness") + } + QQC2.Slider { + id: brightnessSlider + anchors.horizontalCenter: parent.horizontalCenter + from: 0 + to: 5 + stepSize: 1 + value: settings.brightness + onMoved: settings.brightness = value + } + } + Column { + anchors.horizontalCenter: parent.horizontalCenter + + Image { + anchors.horizontalCenter: parent.horizontalCenter + source: UIStyle.themeImagePath("images/theme") + } + QQC2.Switch { + id: darkThemeSwitch + anchors.horizontalCenter: parent.horizontalCenter + checked: settings.darkTheme + onToggled: settings.darkTheme = checked + } + } + } + } + + SwipeViewPage { + id: settingsPage3 + + Column { + anchors.centerIn: parent + + Column { + anchors.horizontalCenter: parent.horizontalCenter + spacing: 6 + + Image { + anchors.horizontalCenter: parent.horizontalCenter + source: UIStyle.themeImagePath("images/demo-mode") + } + QQC2.Switch { + id: demoModeSwitch + anchors.horizontalCenter: parent.horizontalCenter + checked: settings.demoMode + onToggled: settings.demoMode = checked + } + } + } + } + } + + QQC2.PageIndicator { + count: svSettingsContainer.count + currentIndex: svSettingsContainer.currentIndex + + anchors.bottom: svSettingsContainer.bottom + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/bluetooth-dark.png b/examples/quickcontrols2/wearable/qml/Settings/images/bluetooth-dark.png new file mode 100644 index 00000000000..0f1f4d0a54a Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/bluetooth-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/bluetooth-dark@2x.png b/examples/quickcontrols2/wearable/qml/Settings/images/bluetooth-dark@2x.png new file mode 100644 index 00000000000..7496fc56859 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/bluetooth-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/bluetooth-light.png b/examples/quickcontrols2/wearable/qml/Settings/images/bluetooth-light.png new file mode 100644 index 00000000000..6e297cfab38 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/bluetooth-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/bluetooth-light@2x.png b/examples/quickcontrols2/wearable/qml/Settings/images/bluetooth-light@2x.png new file mode 100644 index 00000000000..62d084032f2 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/bluetooth-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/brightness-dark.png b/examples/quickcontrols2/wearable/qml/Settings/images/brightness-dark.png new file mode 100644 index 00000000000..f9eb07b5839 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/brightness-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/brightness-dark@2x.png b/examples/quickcontrols2/wearable/qml/Settings/images/brightness-dark@2x.png new file mode 100644 index 00000000000..3efc5a6c4bd Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/brightness-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/brightness-light.png b/examples/quickcontrols2/wearable/qml/Settings/images/brightness-light.png new file mode 100644 index 00000000000..ce3023b5654 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/brightness-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/brightness-light@2x.png b/examples/quickcontrols2/wearable/qml/Settings/images/brightness-light@2x.png new file mode 100644 index 00000000000..dc01aae1fd6 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/brightness-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-dark.png b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-dark.png new file mode 100644 index 00000000000..e93c417d79c Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-dark@2x.png b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-dark@2x.png new file mode 100644 index 00000000000..faa1bf6d112 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-light.png b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-light.png new file mode 100644 index 00000000000..c38d146d371 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-light@2x.png b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-light@2x.png new file mode 100644 index 00000000000..b9d6409cbc1 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-white.png b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-white.png new file mode 100644 index 00000000000..aac8ef3f6c9 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-white.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-white@2x.png b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-white@2x.png new file mode 100644 index 00000000000..b4d8954f5d6 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-white@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode.svg b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode.svg new file mode 100644 index 00000000000..ad1ce448738 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/theme-dark.png b/examples/quickcontrols2/wearable/qml/Settings/images/theme-dark.png new file mode 100644 index 00000000000..d4c4a8c0949 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/theme-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/theme-dark@2x.png b/examples/quickcontrols2/wearable/qml/Settings/images/theme-dark@2x.png new file mode 100644 index 00000000000..30d8c6de28a Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/theme-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/theme-light.png b/examples/quickcontrols2/wearable/qml/Settings/images/theme-light.png new file mode 100644 index 00000000000..e7a0771b945 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/theme-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/theme-light@2x.png b/examples/quickcontrols2/wearable/qml/Settings/images/theme-light@2x.png new file mode 100644 index 00000000000..83bc878b037 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/theme-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/theme.svg b/examples/quickcontrols2/wearable/qml/Settings/images/theme.svg new file mode 100644 index 00000000000..bf3f1e57d7b --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Settings/images/theme.svg @@ -0,0 +1,84 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/wifi-dark.png b/examples/quickcontrols2/wearable/qml/Settings/images/wifi-dark.png new file mode 100644 index 00000000000..14bfe8f5c86 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/wifi-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/wifi-dark@2x.png b/examples/quickcontrols2/wearable/qml/Settings/images/wifi-dark@2x.png new file mode 100644 index 00000000000..b70d04290bd Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/wifi-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/wifi-light.png b/examples/quickcontrols2/wearable/qml/Settings/images/wifi-light.png new file mode 100644 index 00000000000..2de34118a79 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/wifi-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Settings/images/wifi-light@2x.png b/examples/quickcontrols2/wearable/qml/Settings/images/wifi-light@2x.png new file mode 100644 index 00000000000..64b5f1725c5 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Settings/images/wifi-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Style/PageIndicator.qml b/examples/quickcontrols2/wearable/qml/Style/PageIndicator.qml new file mode 100644 index 00000000000..8328f627dcb --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Style/PageIndicator.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import "." + +T.PageIndicator { + id: control + + implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding + implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding + + spacing: 6 + padding: 6 + bottomPadding: 7 + + delegate: Rectangle { + implicitWidth: 8 + implicitHeight: 8 + + radius: width / 2 + color: UIStyle.themeColorQtGray3 + + opacity: index === control.currentIndex ? 1.0 : 0.35 + + Behavior on opacity { + OpacityAnimator { + duration: 100 + } + } + } + + contentItem: Row { + spacing: control.spacing + + Repeater { + model: control.count + delegate: control.delegate + } + } +} diff --git a/examples/quickcontrols2/wearable/qml/Style/Slider.qml b/examples/quickcontrols2/wearable/qml/Style/Slider.qml new file mode 100644 index 00000000000..533510f5cd3 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Style/Slider.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import "." + +T.Slider { + id: control + + implicitWidth: 200 + implicitHeight: 26 + + handle: Rectangle { + x: control.visualPosition * (control.width - width) + y: (control.height - height) / 2 + width: 20 + height: 15 + + radius: 5 + color: control.pressed ? "#f0f0f0" : "#f6f6f6" + border.color: UIStyle.themeColorQtGray7 + } + + background: Rectangle { + y: (control.height - height) / 2 + height: 4 + radius: 2 + color: UIStyle.themeColorQtGray3 + + Rectangle { + width: control.visualPosition * parent.width + height: parent.height + color: UIStyle.colorQtAuxGreen2 + radius: 2 + } + } +} + diff --git a/examples/quickcontrols2/wearable/qml/Style/Switch.qml b/examples/quickcontrols2/wearable/qml/Style/Switch.qml new file mode 100644 index 00000000000..e5631bbbfab --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Style/Switch.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import "." + +T.Switch { + id: control + + implicitWidth: 48 + implicitHeight: 26 + + indicator: Rectangle { + x: control.visualPosition * (control.width - width) + y: (control.height - height) / 2 + width: 26 + height: 26 + + radius: 13 + color: control.down ? UIStyle.themeColorQtGray6 : UIStyle.themeColorQtGray10 + border.color: !control.checked ? "#999999" + : (control.down ? UIStyle.colorQtAuxGreen2 + : UIStyle.colorQtAuxGreen1) + + Behavior on x { + enabled: !control.pressed + SmoothedAnimation { velocity: 200 } + } + } + + background: Rectangle { + radius: 13 + color: control.checked ? UIStyle.colorQtAuxGreen2 : UIStyle.colorRed + border.color: control.checked ? UIStyle.colorQtAuxGreen2 + : UIStyle.themeColorQtGray6 + } +} + diff --git a/examples/quickcontrols2/wearable/qml/Style/UIStyle.qml b/examples/quickcontrols2/wearable/qml/Style/UIStyle.qml new file mode 100644 index 00000000000..626d37ec6dc --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Style/UIStyle.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +pragma Singleton + +QtObject { + id: uiStyle + + // Font Sizes + readonly property int fontSizeXXS: 10 + readonly property int fontSizeXS: 15 + readonly property int fontSizeS: 20 + readonly property int fontSizeM: 25 + readonly property int fontSizeL: 30 + readonly property int fontSizeXL: 35 + readonly property int fontSizeXXL: 40 + + // Color Scheme + // Green + readonly property color colorQtPrimGreen: "#41cd52" + readonly property color colorQtAuxGreen1: "#21be2b" + readonly property color colorQtAuxGreen2: "#17a81a" + + // Red + readonly property color colorRed: "#e6173d" + + // Gray + readonly property color colorQtGray1: "#09102b" + readonly property color colorQtGray2: "#222840" + readonly property color colorQtGray3: "#3a4055" + readonly property color colorQtGray4: "#53586b" + readonly property color colorQtGray5: "#53586b" + readonly property color colorQtGray6: "#848895" + readonly property color colorQtGray7: "#9d9faa" + readonly property color colorQtGray8: "#b5b7bf" + readonly property color colorQtGray9: "#cecfd5" + readonly property color colorQtGray10: "#f3f3f4" + + // Light/dark versions of the colors above. + // Some UI elements always use a specific color regardless of theme, + // which is why we have both sets: so that those elements don't need to hard-code the hex string. + readonly property color themeColorQtGray1: darkTheme ? colorQtGray10 : colorQtGray1 + readonly property color themeColorQtGray2: darkTheme ? colorQtGray9 : colorQtGray2 + readonly property color themeColorQtGray3: darkTheme ? colorQtGray8 : colorQtGray3 + readonly property color themeColorQtGray4: darkTheme ? colorQtGray7 : colorQtGray4 + readonly property color themeColorQtGray5: darkTheme ? colorQtGray6 : colorQtGray5 + readonly property color themeColorQtGray6: darkTheme ? colorQtGray5 : colorQtGray6 + readonly property color themeColorQtGray7: darkTheme ? colorQtGray4 : colorQtGray7 + readonly property color themeColorQtGray8: darkTheme ? colorQtGray3 : colorQtGray8 + readonly property color themeColorQtGray9: darkTheme ? colorQtGray2 : colorQtGray9 + readonly property color themeColorQtGray10: darkTheme ? colorQtGray1 : colorQtGray10 + + property bool darkTheme: false + + function themeImagePath(baseImagePath) { + return baseImagePath + (darkTheme ? "-dark" : "-light") + ".png" + } +} diff --git a/examples/quickcontrols2/wearable/qml/Style/qmldir b/examples/quickcontrols2/wearable/qml/Style/qmldir new file mode 100644 index 00000000000..a04072bed68 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Style/qmldir @@ -0,0 +1 @@ +singleton UIStyle 1.0 UIStyle.qml diff --git a/examples/quickcontrols2/wearable/qml/SwipeViewPage.qml b/examples/quickcontrols2/wearable/qml/SwipeViewPage.qml new file mode 100644 index 00000000000..b897127ba82 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/SwipeViewPage.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + // Don't show the item when the StackView that contains us + // is being popped off the stack, as we use an x animation + // and hence would show pages that we shouldn't since we + // also don't have our own background. + visible: SwipeView.isCurrentItem || (SwipeView.view.contentItem.moving && (SwipeView.isPreviousItem || SwipeView.isNextItem)) +} diff --git a/examples/quickcontrols2/wearable/qml/Weather/WeatherPage.qml b/examples/quickcontrols2/wearable/qml/Weather/WeatherPage.qml new file mode 100644 index 00000000000..28fc0bc1eb4 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Weather/WeatherPage.qml @@ -0,0 +1,297 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as QQC2 +import ".." +import "../Style" +import "weather.js" as WeatherData + +Item { + QQC2.SwipeView { + id: svWeatherContainer + + anchors.fill: parent + + SwipeViewPage { + id: weatherPage1 + + Row { + anchors.centerIn: parent + spacing: 2 + + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/temperature") + } + + Column { + anchors.verticalCenter: parent.verticalCenter + spacing: 40 + + Text { + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.temp) ? + qsTr("Avg: ") + + String(wDataCntr.weatherData.main.temp) + + " °F" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + + Text { + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.temp_min) ? + qsTr("Min: ") + + String(wDataCntr.weatherData.main.temp_min) + + " °F" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + + Text { + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.temp_max) ? + qsTr("Max: ") + + String(wDataCntr.weatherData.main.temp_max) + + " °F " : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + } + } + } + + SwipeViewPage { + id: weatherPage2 + + Column { + spacing: 40 + anchors.centerIn: parent + + Row { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + Image { + id: wImg + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/wind") + } + + Text { + anchors.verticalCenter: parent.verticalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.wind + && wDataCntr.weatherData.wind.speed) ? + String(wDataCntr.weatherData.wind.speed) + + " mph" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + } + + Row { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + Image { + id: hImg + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/humidity") + } + + Text { + anchors.verticalCenter: parent.verticalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.humidity) ? + String(wDataCntr.weatherData.main.humidity) + + " %" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + } + } + } + + SwipeViewPage { + id: weatherPage3 + + Row { + anchors.centerIn: parent + spacing: 10 + + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/pressure") + } + + Column { + anchors.verticalCenter: parent.verticalCenter + spacing: 40 + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.pressure) ? + String(wDataCntr.weatherData.main.pressure) + + " hPa" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.sea_level) ? + String(wDataCntr.weatherData.main.sea_level) + + " hPa" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.grnd_level) ? + String(wDataCntr.weatherData.main.grnd_level) + + " hPa" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + } + } + } + + SwipeViewPage { + id: weatherPage4 + + Column { + spacing: 40 + anchors.centerIn: parent + + Row { + spacing: 30 + anchors.horizontalCenter: parent.horizontalCenter + + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/sunrise") + } + + Text { + anchors.verticalCenter: parent.verticalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.sys + && wDataCntr.weatherData.sys.sunrise) ? + WeatherData.getTimeHMS(wDataCntr.weatherData.sys.sunrise) + : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + } + + Row { + spacing: 30 + anchors.horizontalCenter: parent.horizontalCenter + + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/sunset") + } + + Text { + anchors.verticalCenter: parent.verticalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.sys + && wDataCntr.weatherData.sys.sunset) ? + WeatherData.getTimeHMS(wDataCntr.weatherData.sys.sunset) + : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + } + } + } + } + + QtObject { + id: wDataCntr + property var weatherData + } + + QQC2.PageIndicator { + count: svWeatherContainer.count + currentIndex: svWeatherContainer.currentIndex + + anchors.bottom: svWeatherContainer.bottom + anchors.horizontalCenter: parent.horizontalCenter + } + Component.onCompleted: { + WeatherData.requestWeatherData(wDataCntr) + } +} diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/humidity-dark.png b/examples/quickcontrols2/wearable/qml/Weather/images/humidity-dark.png new file mode 100644 index 00000000000..5d82238cdbb Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/humidity-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/humidity-dark@2x.png b/examples/quickcontrols2/wearable/qml/Weather/images/humidity-dark@2x.png new file mode 100644 index 00000000000..d83bb4f00c3 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/humidity-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/humidity-light.png b/examples/quickcontrols2/wearable/qml/Weather/images/humidity-light.png new file mode 100644 index 00000000000..5f3bf714e6e Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/humidity-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/humidity-light@2x.png b/examples/quickcontrols2/wearable/qml/Weather/images/humidity-light@2x.png new file mode 100644 index 00000000000..a23364c52c6 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/humidity-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/pressure-dark.png b/examples/quickcontrols2/wearable/qml/Weather/images/pressure-dark.png new file mode 100644 index 00000000000..b2870a55a67 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/pressure-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/pressure-dark@2x.png b/examples/quickcontrols2/wearable/qml/Weather/images/pressure-dark@2x.png new file mode 100644 index 00000000000..061f9b82660 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/pressure-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/pressure-light.png b/examples/quickcontrols2/wearable/qml/Weather/images/pressure-light.png new file mode 100644 index 00000000000..7b1b158734d Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/pressure-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/pressure-light@2x.png b/examples/quickcontrols2/wearable/qml/Weather/images/pressure-light@2x.png new file mode 100644 index 00000000000..1a40c6422a2 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/pressure-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/sunrise-dark.png b/examples/quickcontrols2/wearable/qml/Weather/images/sunrise-dark.png new file mode 100644 index 00000000000..9cac22e1e18 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/sunrise-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/sunrise-dark@2x.png b/examples/quickcontrols2/wearable/qml/Weather/images/sunrise-dark@2x.png new file mode 100644 index 00000000000..fe32682386b Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/sunrise-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/sunrise-light.png b/examples/quickcontrols2/wearable/qml/Weather/images/sunrise-light.png new file mode 100644 index 00000000000..f67a5dff34b Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/sunrise-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/sunrise-light@2x.png b/examples/quickcontrols2/wearable/qml/Weather/images/sunrise-light@2x.png new file mode 100644 index 00000000000..86f54837616 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/sunrise-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/sunset-dark.png b/examples/quickcontrols2/wearable/qml/Weather/images/sunset-dark.png new file mode 100644 index 00000000000..0068d305395 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/sunset-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/sunset-dark@2x.png b/examples/quickcontrols2/wearable/qml/Weather/images/sunset-dark@2x.png new file mode 100644 index 00000000000..e515bcc37c8 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/sunset-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/sunset-light.png b/examples/quickcontrols2/wearable/qml/Weather/images/sunset-light.png new file mode 100644 index 00000000000..495f78a7861 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/sunset-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/sunset-light@2x.png b/examples/quickcontrols2/wearable/qml/Weather/images/sunset-light@2x.png new file mode 100644 index 00000000000..d220e829d17 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/sunset-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/temperature-dark.png b/examples/quickcontrols2/wearable/qml/Weather/images/temperature-dark.png new file mode 100644 index 00000000000..a207d9440d9 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/temperature-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/temperature-dark@2x.png b/examples/quickcontrols2/wearable/qml/Weather/images/temperature-dark@2x.png new file mode 100644 index 00000000000..c0e4ef39bfa Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/temperature-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/temperature-light.png b/examples/quickcontrols2/wearable/qml/Weather/images/temperature-light.png new file mode 100644 index 00000000000..c4f7b61c2e7 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/temperature-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/temperature-light@2x.png b/examples/quickcontrols2/wearable/qml/Weather/images/temperature-light@2x.png new file mode 100644 index 00000000000..50d4f4c43c6 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/temperature-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/wind-dark.png b/examples/quickcontrols2/wearable/qml/Weather/images/wind-dark.png new file mode 100644 index 00000000000..6a530491af3 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/wind-dark.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/wind-dark@2x.png b/examples/quickcontrols2/wearable/qml/Weather/images/wind-dark@2x.png new file mode 100644 index 00000000000..487e3e78a37 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/wind-dark@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/wind-light.png b/examples/quickcontrols2/wearable/qml/Weather/images/wind-light.png new file mode 100644 index 00000000000..97824bee8fd Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/wind-light.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/images/wind-light@2x.png b/examples/quickcontrols2/wearable/qml/Weather/images/wind-light@2x.png new file mode 100644 index 00000000000..7f94bd8542c Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/Weather/images/wind-light@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/Weather/weather.js b/examples/quickcontrols2/wearable/qml/Weather/weather.js new file mode 100644 index 00000000000..b3bf446568a --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Weather/weather.js @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +function requestWeatherData(cntr) { + var xhr = new XMLHttpRequest; + xhr.open("GET", "weather.json"); + xhr.onreadystatechange = function () { + if (xhr.readyState === XMLHttpRequest.DONE) { + cntr.weatherData = JSON.parse(xhr.responseText) + } + } + xhr.send(); +} + +function getTimeHMS(utcTime) { + var date = new Date(utcTime * 1000); + // Hours part from the timestamp + var hours = date.getHours(); + var ampm = Math.floor((hours / 12)) ? " PM" : " AM"; + hours = (hours % 12); + + // Minutes part from the timestamp + var minutes = "0" + date.getMinutes(); + // Seconds part from the timestamp + var seconds = "0" + date.getSeconds(); + + // Will display time in 10:30:23 format + return hours % 12 + ':' + minutes.substr(-2) + ':' + seconds.substr(-2) + + ampm; +} diff --git a/examples/quickcontrols2/wearable/qml/Weather/weather.json b/examples/quickcontrols2/wearable/qml/Weather/weather.json new file mode 100644 index 00000000000..2cce95c60b0 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/Weather/weather.json @@ -0,0 +1 @@ +{"coord":{"lon":-122.42,"lat":37.77},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"base":"stations","main":{"temp":45.22,"pressure":1020.17,"humidity":88,"temp_min":36.92,"temp_max":58.92,"sea_level":1028.19,"grnd_level":1020.17},"wind":{"speed":6.73,"deg":201.002},"clouds":{"all":68},"dt":1476412232,"sys":{"message":0.012,"country":"US","sunrise":1476454666,"sunset":1476495156},"id":5391959,"name":"San Francisco","cod":200} diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/Clock.qml b/examples/quickcontrols2/wearable/qml/WorldClock/Clock.qml new file mode 100644 index 00000000000..312113091e4 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/WorldClock/Clock.qml @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as QQC2 +import ".." +import "../Style" + +SwipeViewPage { + id: clock + + property int hours + property int minutes + property int seconds + property real shift: timeShift + property bool night: false + property bool internationalTime: true //Unset for local time + + function getWatchFaceImage(imageName) { + return "images/" + imageName + } + + function timeChanged() { + var date = new Date + hours = internationalTime ? date.getUTCHours() + Math.floor( + clock.shift) : date.getHours() + night = (hours < 7 || hours > 19) + minutes = internationalTime ? + date.getUTCMinutes() + ((clock.shift % 1) * 60) : date.getMinutes() + seconds = date.getUTCSeconds() + } + + Timer { + interval: 100 + running: true + repeat: true + onTriggered: clock.timeChanged() + } + + Item { + anchors.centerIn: parent + + width: 200 + height: 220 + + Rectangle { + color: clock.night ? UIStyle.colorQtGray1 : UIStyle.colorQtGray10 + radius: width / 2 + width: parent.width + height: parent.width + } + + Image { + id: background + source: getWatchFaceImage("swissdaydial.png") + visible: clock.night == false + } + Image { + source: getWatchFaceImage("swissnightdial.png") + visible: clock.night == true + } + + Image { + x: 92.5 + y: 27 + source: getWatchFaceImage(clock.night ? + "swissnighthour.png" + : "swissdayhour.png") + transform: Rotation { + id: hourRotation + origin.x: 7.5 + origin.y: 73 + angle: (clock.hours * 30) + (clock.minutes * 0.5) + Behavior on angle { + SpringAnimation { + spring: 2 + damping: 0.2 + modulus: 360 + } + } + } + } + + Image { + x: 93.5 + y: 17 + source: getWatchFaceImage(clock.night ? + "swissnightminute.png" + : "swissdayminute.png") + transform: Rotation { + id: minuteRotation + origin.x: 6.5 + origin.y: 83 + angle: clock.minutes * 6 + Behavior on angle { + SpringAnimation { + spring: 2 + damping: 0.2 + modulus: 360 + } + } + } + } + + Image { + x: 97.5 + y: 20 + source: getWatchFaceImage("second.png") + transform: Rotation { + id: secondRotation + origin.x: 2.5 + origin.y: 80 + angle: clock.seconds * 6 + Behavior on angle { + SpringAnimation { + spring: 2 + damping: 0.2 + modulus: 360 + } + } + } + } + + Image { + anchors.centerIn: background + source: getWatchFaceImage("center.png") + } + + Text { + id: cityLabel + anchors.bottom: parent.bottom + anchors.bottomMargin: 2 + anchors.horizontalCenter: parent.horizontalCenter + + text: cityName + color: UIStyle.themeColorQtGray1 + font.pixelSize: UIStyle.fontSizeXS + font.letterSpacing: 2 + } + } +} diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/WorldClockPage.qml b/examples/quickcontrols2/wearable/qml/WorldClock/WorldClockPage.qml new file mode 100644 index 00000000000..b2f881e3630 --- /dev/null +++ b/examples/quickcontrols2/wearable/qml/WorldClock/WorldClockPage.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as QQC2 +import "../Style" + +Item { + QQC2.SwipeView { + id: svWatchContainer + + anchors.fill: parent + + ListModel { + id: placesList + ListElement { + cityName: "New York" + timeShift: -4 + } + ListElement { + cityName: "London" + timeShift: 0 + } + ListElement { + cityName: "Oslo" + timeShift: 1 + } + ListElement { + cityName: "Mumbai" + timeShift: 5.5 + } + ListElement { + cityName: "Tokyo" + timeShift: 9 + } + ListElement { + cityName: "Brisbane" + timeShift: 10 + } + ListElement { + cityName: "Los Angeles" + timeShift: -8 + } + } + + Repeater { + model: placesList + delegate: Clock { + } + } + } + + QQC2.PageIndicator { + count: svWatchContainer.count + currentIndex: svWatchContainer.currentIndex + + anchors.bottom: svWatchContainer.bottom + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/center.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/center.png new file mode 100644 index 00000000000..0dec43a0aa2 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/center.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/center@2x.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/center@2x.png new file mode 100644 index 00000000000..dffc5d60e4a Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/center@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/clock-night.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/clock-night.png new file mode 100644 index 00000000000..2de330243ae Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/clock-night.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/clock-night@2x.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/clock-night@2x.png new file mode 100644 index 00000000000..f675acea692 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/clock-night@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/clock.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/clock.png new file mode 100644 index 00000000000..686fb8c2f7e Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/clock.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/second.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/second.png new file mode 100644 index 00000000000..1e64f357df4 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/second.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/second@2x.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/second@2x.png new file mode 100644 index 00000000000..cebc1deb06b Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/second@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdaydial.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdaydial.png new file mode 100644 index 00000000000..0e6321537af Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdaydial.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdaydial@2x.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdaydial@2x.png new file mode 100644 index 00000000000..ed5de8c6463 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdaydial@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdayhour.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdayhour.png new file mode 100644 index 00000000000..4a835ac3f00 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdayhour.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdayhour@2x.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdayhour@2x.png new file mode 100644 index 00000000000..70f3fa0eee4 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdayhour@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdayminute.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdayminute.png new file mode 100644 index 00000000000..048acc7b3f6 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdayminute.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdayminute@2x.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdayminute@2x.png new file mode 100644 index 00000000000..4cc6ce64b4b Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissdayminute@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnightdial.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnightdial.png new file mode 100644 index 00000000000..ee5a15bb9b6 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnightdial.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnightdial@2x.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnightdial@2x.png new file mode 100644 index 00000000000..ec7e5c77dc0 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnightdial@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnighthour.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnighthour.png new file mode 100644 index 00000000000..c5b41cb043f Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnighthour.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnighthour@2x.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnighthour@2x.png new file mode 100644 index 00000000000..bbbc36f1d7b Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnighthour@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnightminute.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnightminute.png new file mode 100644 index 00000000000..026c7424467 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnightminute.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnightminute@2x.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnightminute@2x.png new file mode 100644 index 00000000000..8ad69047a43 Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissnightminute@2x.png differ diff --git a/examples/quickcontrols2/wearable/qml/WorldClock/images/swissseconds.png b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissseconds.png new file mode 100644 index 00000000000..06446ac0fee Binary files /dev/null and b/examples/quickcontrols2/wearable/qml/WorldClock/images/swissseconds.png differ diff --git a/examples/quickcontrols2/wearable/wearable.cpp b/examples/quickcontrols2/wearable/wearable.cpp new file mode 100644 index 00000000000..a602eddc308 --- /dev/null +++ b/examples/quickcontrols2/wearable/wearable.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QCoreApplication::setApplicationName("Wearable"); + QCoreApplication::setOrganizationName("QtProject"); + + QGuiApplication app(argc, argv); + + //! [style] + QQuickStyle::setStyle(QStringLiteral("qrc:/qml/Style")); + //! [style] + + //! [icons] + QIcon::setThemeName(QStringLiteral("wearable")); + //! [icons] + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/wearable.qml"))); + + return app.exec(); +} diff --git a/examples/quickcontrols2/wearable/wearable.pro b/examples/quickcontrols2/wearable/wearable.pro new file mode 100644 index 00000000000..8d55e44eaa5 --- /dev/null +++ b/examples/quickcontrols2/wearable/wearable.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = wearable +QT += quick quickcontrols2 + +SOURCES += \ + wearable.cpp + +RESOURCES += \ + wearable.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/wearable +INSTALLS += target diff --git a/examples/quickcontrols2/wearable/wearable.qml b/examples/quickcontrols2/wearable/wearable.qml new file mode 100644 index 00000000000..645ff5619c9 --- /dev/null +++ b/examples/quickcontrols2/wearable/wearable.qml @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as QQC2 +import Qt.labs.settings +import "qml" +import "qml/Style" + +QQC2.ApplicationWindow { + id: window + visible: true + width: 320 + height: 320 + title: qsTr("Wearable") + + Settings { + id: settings + property bool wireless + property bool bluetooth + property int brightness + property bool darkTheme + property bool demoMode + } + + Binding { + target: UIStyle + property: "darkTheme" + value: settings.darkTheme + } + + // We need the settings object both here and in SettingsPage, + // so for convenience, we declare it as a property of the root object so that + // it will be available to all of the QML files that we load. + property alias settings: settings + + background: Image { + source: "images/background-" + (settings.darkTheme ? "dark" : "light") + ".png" + } + + header: NaviButton { + id: homeButton + + edge: Qt.TopEdge + enabled: stackView.depth > 1 + imageSource: "images/home.png" + + onClicked: stackView.pop(null) + } + + footer: NaviButton { + id: backButton + + edge: Qt.BottomEdge + enabled: stackView.depth > 1 + imageSource: "images/back.png" + + onClicked: stackView.pop() + } + + QQC2.StackView { + id: stackView + + focus: true + anchors.fill: parent + + initialItem: LauncherPage { + onLaunched: stackView.push(page) + } + } + + DemoMode { + stackView: stackView + } + + DemoModeIndicator { + id: demoModeIndicator + y: settings.demoMode ? -height : -height * 2 + anchors.horizontalCenter: parent.horizontalCenter + height: header.height + z: window.header.z + 1 + } + + MouseArea { + enabled: settings.demoMode + anchors.fill: parent + onClicked: { + // Stop demo mode and return to the launcher page. + settings.demoMode = false + stackView.pop(null) + } + } +} diff --git a/examples/quickcontrols2/wearable/wearable.qrc b/examples/quickcontrols2/wearable/wearable.qrc new file mode 100644 index 00000000000..db59d038f69 --- /dev/null +++ b/examples/quickcontrols2/wearable/wearable.qrc @@ -0,0 +1,155 @@ + + + wearable.qml + qml/LauncherPage.qml + qml/NaviButton.qml + icons/wearable/index.theme + icons/wearable/36x36/alarms.png + icons/wearable/36x36/fitness.png + icons/wearable/36x36/navigation.png + icons/wearable/36x36/notifications.png + icons/wearable/36x36/settings.png + icons/wearable/36x36/weather.png + icons/wearable/36x36/worldclock.png + icons/wearable/36x36@2/alarms.png + icons/wearable/36x36@2/fitness.png + icons/wearable/36x36@2/navigation.png + icons/wearable/36x36@2/notifications.png + icons/wearable/36x36@2/settings.png + icons/wearable/36x36@2/weather.png + icons/wearable/36x36@2/worldclock.png + images/background-light.png + images/background-dark.png + images/back.png + images/back@2x.png + images/home.png + images/home@2x.png + qml/Alarms/AlarmsPage.qml + qml/Fitness/fitness.js + qml/Fitness/FitnessPage.qml + qml/Fitness/images/man-running-light.png + qml/Fitness/images/man-running-light@2x.png + qml/Fitness/images/man-walking-light.png + qml/Fitness/images/man-walking-light@2x.png + qml/Fitness/images/man-running-dark.png + qml/Fitness/images/man-running-dark@2x.png + qml/Fitness/images/man-walking-dark.png + qml/Fitness/images/man-walking-dark@2x.png + qml/Navigation/navigation.js + qml/Navigation/NavigationPage.qml + qml/Navigation/RouteElement.qml + qml/Navigation/walk_route.json + qml/Navigation/images/end.png + qml/Navigation/images/end@2x.png + qml/Navigation/images/leftturn-light.png + qml/Navigation/images/leftturn-light@2x.png + qml/Navigation/images/leftturn-dark.png + qml/Navigation/images/leftturn-dark@2x.png + qml/Navigation/images/navigation-light.png + qml/Navigation/images/navigation-light@2x.png + qml/Navigation/images/navigation-dark.png + qml/Navigation/images/navigation-dark@2x.png + qml/Navigation/images/rightturn-light.png + qml/Navigation/images/rightturn-light@2x.png + qml/Navigation/images/rightturn-dark.png + qml/Navigation/images/rightturn-dark@2x.png + qml/Navigation/images/start.png + qml/Navigation/images/start@2x.png + qml/Navigation/images/straight-light.png + qml/Navigation/images/straight-light@2x.png + qml/Navigation/images/straight-dark.png + qml/Navigation/images/straight-dark@2x.png + qml/Navigation/images/uturn.png + qml/Navigation/images/uturn@2x.png + qml/Notifications/notifications.js + qml/Notifications/NotificationsPage.qml + qml/Notifications/images/avatarf-light.png + qml/Notifications/images/avatarf-light@2x.png + qml/Notifications/images/avatarm-light.png + qml/Notifications/images/avatarm-light@2x.png + qml/Notifications/images/missedcall-light.png + qml/Notifications/images/missedcall-light@2x.png + qml/Notifications/images/avatarf-dark.png + qml/Notifications/images/avatarf-dark@2x.png + qml/Notifications/images/avatarm-dark.png + qml/Notifications/images/avatarm-dark@2x.png + qml/Notifications/images/missedcall-dark.png + qml/Notifications/images/missedcall-dark@2x.png + qml/Settings/SettingsPage.qml + qml/Settings/images/bluetooth-light.png + qml/Settings/images/bluetooth-light@2x.png + qml/Settings/images/brightness-light.png + qml/Settings/images/brightness-light@2x.png + qml/Settings/images/demo-mode-light.png + qml/Settings/images/demo-mode-light@2x.png + qml/Settings/images/demo-mode-dark.png + qml/Settings/images/demo-mode-dark@2x.png + qml/Settings/images/demo-mode-white.png + qml/Settings/images/demo-mode-white@2x.png + qml/Settings/images/theme-light.png + qml/Settings/images/theme-light@2x.png + qml/Settings/images/wifi-light.png + qml/Settings/images/wifi-light@2x.png + qml/Settings/images/bluetooth-dark.png + qml/Settings/images/bluetooth-dark@2x.png + qml/Settings/images/brightness-dark.png + qml/Settings/images/brightness-dark@2x.png + qml/Settings/images/theme-dark.png + qml/Settings/images/theme-dark@2x.png + qml/Settings/images/wifi-dark.png + qml/Settings/images/wifi-dark@2x.png + qml/Style/qmldir + qml/Style/PageIndicator.qml + qml/Style/Slider.qml + qml/Style/Switch.qml + qml/Style/UIStyle.qml + qml/Weather/weather.js + qml/Weather/weather.json + qml/Weather/WeatherPage.qml + qml/Weather/images/humidity-light.png + qml/Weather/images/humidity-light@2x.png + qml/Weather/images/pressure-light.png + qml/Weather/images/pressure-light@2x.png + qml/Weather/images/sunrise-light.png + qml/Weather/images/sunrise-light@2x.png + qml/Weather/images/sunset-light.png + qml/Weather/images/sunset-light@2x.png + qml/Weather/images/temperature-light.png + qml/Weather/images/temperature-light@2x.png + qml/Weather/images/wind-light.png + qml/Weather/images/wind-light@2x.png + qml/Weather/images/humidity-dark.png + qml/Weather/images/humidity-dark@2x.png + qml/Weather/images/pressure-dark.png + qml/Weather/images/pressure-dark@2x.png + qml/Weather/images/sunrise-dark.png + qml/Weather/images/sunrise-dark@2x.png + qml/Weather/images/sunset-dark.png + qml/Weather/images/sunset-dark@2x.png + qml/Weather/images/temperature-dark.png + qml/Weather/images/temperature-dark@2x.png + qml/Weather/images/wind-dark.png + qml/Weather/images/wind-dark@2x.png + qml/WorldClock/Clock.qml + qml/WorldClock/WorldClockPage.qml + qml/WorldClock/images/center.png + qml/WorldClock/images/center@2x.png + qml/WorldClock/images/second.png + qml/WorldClock/images/second@2x.png + qml/WorldClock/images/swissdaydial.png + qml/WorldClock/images/swissdaydial@2x.png + qml/WorldClock/images/swissdayhour.png + qml/WorldClock/images/swissdayhour@2x.png + qml/WorldClock/images/swissdayminute.png + qml/WorldClock/images/swissdayminute@2x.png + qml/WorldClock/images/swissnightdial.png + qml/WorldClock/images/swissnightdial@2x.png + qml/WorldClock/images/swissnighthour.png + qml/WorldClock/images/swissnighthour@2x.png + qml/WorldClock/images/swissnightminute.png + qml/WorldClock/images/swissnightminute@2x.png + qml/SwipeViewPage.qml + qml/DemoMode.qml + qml/DemoModeIndicator.qml + + diff --git a/qt_cmdline.cmake b/qt_cmdline.cmake index b8a80693829..0cc6f2b6252 100644 --- a/qt_cmdline.cmake +++ b/qt_cmdline.cmake @@ -1,3 +1,5 @@ qt_commandline_subconfig(src/qml) qt_commandline_subconfig(src/qmlmodels) qt_commandline_subconfig(src/quick) +qt_commandline_subconfig(src/quickcontrols2) +qt_commandline_subconfig(src/quicktemplates2) diff --git a/src/3rdparty/masm/assembler/ARM64Assembler.h b/src/3rdparty/masm/assembler/ARM64Assembler.h index a856196fe60..9928da3abde 100644 --- a/src/3rdparty/masm/assembler/ARM64Assembler.h +++ b/src/3rdparty/masm/assembler/ARM64Assembler.h @@ -517,6 +517,7 @@ typedef enum { x29 = fp, x30 = lr, zr = 0x3f, + none = 0xff, } RegisterID; typedef enum { @@ -676,11 +677,11 @@ class ARM64Assembler { struct RealTypes { int64_t m_from : 48; int64_t m_to : 48; + RegisterID m_compareRegister; JumpType m_type : 8; JumpLinkType m_linkType : 8; Condition m_condition : 4; unsigned m_bitNumber : 6; - RegisterID m_compareRegister : 6; bool m_is64Bit : 1; } realTypes; } data; diff --git a/src/3rdparty/masm/assembler/ARMv7Assembler.h b/src/3rdparty/masm/assembler/ARMv7Assembler.h index 03cb9f42f8a..330b6c3629f 100644 --- a/src/3rdparty/masm/assembler/ARMv7Assembler.h +++ b/src/3rdparty/masm/assembler/ARMv7Assembler.h @@ -64,6 +64,7 @@ namespace ARMRegisters { r13, sp = r13, r14, lr = r14, r15, pc = r15, + none = 0xff, } RegisterID; typedef enum { diff --git a/src/3rdparty/masm/assembler/MIPSAssembler.h b/src/3rdparty/masm/assembler/MIPSAssembler.h index 7f553bb9a1f..0419ea0504f 100644 --- a/src/3rdparty/masm/assembler/MIPSAssembler.h +++ b/src/3rdparty/masm/assembler/MIPSAssembler.h @@ -105,7 +105,8 @@ typedef enum { gp = r28, sp = r29, fp = r30, - ra = r31 + ra = r31, + none = 0xff, } RegisterID; typedef enum { diff --git a/src/3rdparty/masm/assembler/X86Assembler.h b/src/3rdparty/masm/assembler/X86Assembler.h index e8ae687036f..ab80e42e792 100644 --- a/src/3rdparty/masm/assembler/X86Assembler.h +++ b/src/3rdparty/masm/assembler/X86Assembler.h @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef X86Assembler_h @@ -62,6 +62,7 @@ namespace X86Registers { r14, r15, #endif + none = 0xff, } RegisterID; typedef enum { @@ -163,7 +164,7 @@ class X86Assembler { OP_HLT = 0xF4, OP_GROUP3_EbIb = 0xF6, OP_GROUP3_Ev = 0xF7, - OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test. + OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test. OP_GROUP5_Ev = 0xFF, } OneByteOpcodeID; @@ -201,12 +202,12 @@ class X86Assembler { TwoByteOpcodeID jccRel32(Condition cond) { - return (TwoByteOpcodeID)(OP2_JCC_rel32 + cond); + return (TwoByteOpcodeID)(int(OP2_JCC_rel32) + cond); } TwoByteOpcodeID setccOpcode(Condition cond) { - return (TwoByteOpcodeID)(OP_SETCC + cond); + return (TwoByteOpcodeID)(int(OP_SETCC) + cond); } typedef enum { @@ -219,12 +220,12 @@ class X86Assembler { GROUP1_OP_CMP = 7, GROUP1A_OP_POP = 0, - + GROUP2_OP_ROL = 0, GROUP2_OP_ROR = 1, GROUP2_OP_RCL = 2, GROUP2_OP_RCR = 3, - + GROUP2_OP_SHL = 4, GROUP2_OP_SHR = 5, GROUP2_OP_SAR = 7, @@ -245,7 +246,7 @@ class X86Assembler { ESCAPE_DD_FSTP_doubleReal = 3, } GroupOpcodeID; - + class X86InstructionFormatter; public: @@ -307,7 +308,7 @@ class X86Assembler { { m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset); } - + #if !CPU(X86_64) void addl_mr(const void* addr, RegisterID dst) { @@ -576,7 +577,7 @@ class X86Assembler { m_formatter.immediate32(imm); } } - + void subl_im(int imm, int offset, RegisterID base) { if (CAN_SIGN_EXTEND_8_32(imm)) { @@ -670,12 +671,12 @@ class X86Assembler { m_formatter.immediate32(imm); } } - + void xorq_rm(RegisterID src, int offset, RegisterID base) { m_formatter.oneByteOp64(OP_XOR_EvGv, src, base, offset); } - + void rorq_i8r(int imm, RegisterID dst) { if (imm == 1) @@ -748,7 +749,7 @@ class X86Assembler { { m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst); } - + void shrl_i8r(int imm, RegisterID dst) { if (imm == 1) @@ -758,7 +759,7 @@ class X86Assembler { m_formatter.immediate8(imm); } } - + void shrl_CLr(RegisterID dst) { m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst); @@ -833,7 +834,7 @@ class X86Assembler { m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst); m_formatter.immediate32(imm); } - + void cmpl_im(int imm, int offset, RegisterID base) { if (CAN_SIGN_EXTEND_8_32(imm)) { @@ -844,19 +845,19 @@ class X86Assembler { m_formatter.immediate32(imm); } } - + void cmpb_im(int imm, int offset, RegisterID base) { m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, offset); m_formatter.immediate8(imm); } - + void cmpb_im(int imm, int offset, RegisterID base, RegisterID index, int scale) { m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, index, scale, offset); m_formatter.immediate8(imm); } - + #if CPU(X86) void cmpb_im(int imm, const void* addr) { @@ -984,7 +985,7 @@ class X86Assembler { { m_formatter.oneByteOp(OP_TEST_EvGv, src, dst); } - + void testl_i32r(int imm, RegisterID dst) { m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst); @@ -1007,7 +1008,7 @@ class X86Assembler { m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, offset); m_formatter.immediate8(imm); } - + void testb_im(int imm, int offset, RegisterID base, RegisterID index, int scale) { m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, index, scale, offset); @@ -1056,14 +1057,14 @@ class X86Assembler { m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset); m_formatter.immediate32(imm); } -#endif +#endif void testw_rr(RegisterID src, RegisterID dst) { m_formatter.prefix(PRE_OPERAND_SIZE); m_formatter.oneByteOp(OP_TEST_EvGv, src, dst); } - + void testb_i8r(int imm, RegisterID dst) { m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst); @@ -1123,7 +1124,7 @@ class X86Assembler { { m_formatter.oneByteOp(OP_MOV_EvGv, src, dst); } - + void movl_rm(RegisterID src, int offset, RegisterID base) { m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset); @@ -1138,7 +1139,7 @@ class X86Assembler { { m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset); } - + void movl_mEAX(const void* addr) { m_formatter.oneByteOp(OP_MOV_EAXOv); @@ -1158,7 +1159,7 @@ class X86Assembler { { m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, base, offset); } - + void movl_mr_disp8(int offset, RegisterID base, RegisterID dst) { m_formatter.oneByteOp_disp8(OP_MOV_GvEv, dst, base, offset); @@ -1180,7 +1181,7 @@ class X86Assembler { m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset); m_formatter.immediate32(imm); } - + void movl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale) { m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset); @@ -1209,12 +1210,12 @@ class X86Assembler { m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, index, scale, offset); m_formatter.immediate8(imm); } - + void movb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) { m_formatter.oneByteOp8(OP_MOV_EbGb, src, base, index, scale, offset); } - + void movw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) { m_formatter.prefix(PRE_OPERAND_SIZE); @@ -1295,22 +1296,22 @@ class X86Assembler { m_formatter.oneByteOp64(OP_MOV_EAXIv, dst); m_formatter.immediate64(imm); } - + void movsxd_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src); } - - + + #else void movl_rm(RegisterID src, const void* addr) { if (src == X86Registers::eax) movl_EAXm(addr); - else + else m_formatter.oneByteOp(OP_MOV_EvGv, src, addr); } - + void movl_mr(const void* addr, RegisterID dst) { if (dst == X86Registers::eax) @@ -1350,7 +1351,7 @@ class X86Assembler { { m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, offset); } - + void movzbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) { m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, index, scale, offset); @@ -1360,7 +1361,7 @@ class X86Assembler { { m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, offset); } - + void movsbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) { m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, index, scale, offset); @@ -1403,13 +1404,13 @@ class X86Assembler { m_formatter.oneByteOp(OP_CALL_rel32); return m_formatter.immediateRel32(); } - + AssemblerLabel call(RegisterID dst) { m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst); return m_formatter.label(); } - + void call_m(int offset, RegisterID base) { m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, base, offset); @@ -1420,7 +1421,7 @@ class X86Assembler { m_formatter.oneByteOp(OP_JMP_rel32); return m_formatter.immediateRel32(); } - + // Return a AssemblerLabel so we have a label to the jump, so we can use this // To make a tail recursive call on x86-64. The MacroAssembler // really shouldn't wrap this as a Jump, since it can't be linked. :-/ @@ -1429,12 +1430,12 @@ class X86Assembler { m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst); return m_formatter.label(); } - + void jmp_m(int offset, RegisterID base) { m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset); } - + #if !CPU(X86_64) void jmp_m(const void* address) { @@ -1447,7 +1448,7 @@ class X86Assembler { m_formatter.twoByteOp(jccRel32(ConditionNE)); return m_formatter.immediateRel32(); } - + AssemblerLabel jnz() { return jne(); @@ -1458,7 +1459,7 @@ class X86Assembler { m_formatter.twoByteOp(jccRel32(ConditionE)); return m_formatter.immediateRel32(); } - + AssemblerLabel jz() { return je(); @@ -1469,25 +1470,25 @@ class X86Assembler { m_formatter.twoByteOp(jccRel32(ConditionL)); return m_formatter.immediateRel32(); } - + AssemblerLabel jb() { m_formatter.twoByteOp(jccRel32(ConditionB)); return m_formatter.immediateRel32(); } - + AssemblerLabel jle() { m_formatter.twoByteOp(jccRel32(ConditionLE)); return m_formatter.immediateRel32(); } - + AssemblerLabel jbe() { m_formatter.twoByteOp(jccRel32(ConditionBE)); return m_formatter.immediateRel32(); } - + AssemblerLabel jge() { m_formatter.twoByteOp(jccRel32(ConditionGE)); @@ -1505,13 +1506,13 @@ class X86Assembler { m_formatter.twoByteOp(jccRel32(ConditionA)); return m_formatter.immediateRel32(); } - + AssemblerLabel jae() { m_formatter.twoByteOp(jccRel32(ConditionAE)); return m_formatter.immediateRel32(); } - + AssemblerLabel jo() { m_formatter.twoByteOp(jccRel32(ConditionO)); @@ -1529,7 +1530,7 @@ class X86Assembler { m_formatter.twoByteOp(jccRel32(ConditionP)); return m_formatter.immediateRel32(); } - + AssemblerLabel js() { m_formatter.twoByteOp(jccRel32(ConditionS)); @@ -1610,7 +1611,7 @@ class X86Assembler { m_formatter.prefix(PRE_SSE_F3); m_formatter.twoByteOp(OP2_CVTSS2SD_VsdWsd, dst, (RegisterID)src); } - + #if CPU(X86_64) void cvttsd2siq_rr(XMMRegisterID src, RegisterID dst) { @@ -1656,19 +1657,19 @@ class X86Assembler { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset); } - + void movsd_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset); } - + void movss_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale) { m_formatter.prefix(PRE_SSE_F3); m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset); } - + void movsd_mr(int offset, RegisterID base, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); @@ -1680,7 +1681,7 @@ class X86Assembler { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset); } - + void movss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F3); @@ -1799,7 +1800,7 @@ class X86Assembler { { m_formatter.oneByteOp(OP_INT3); } - + void ret() { m_formatter.oneByteOp(OP_RET); @@ -1816,7 +1817,7 @@ class X86Assembler { { return m_formatter.codeSize(); } - + AssemblerLabel labelForWatchpoint() { AssemblerLabel result = m_formatter.label(); @@ -1826,7 +1827,7 @@ class X86Assembler { m_indexOfTailOfLastWatchpoint = result.m_offset + maxJumpReplacementSize(); return result; } - + AssemblerLabel labelIgnoringWatchpoints() { return m_formatter.label(); @@ -1876,7 +1877,7 @@ class X86Assembler { memcpy(&val, t_ptr, sizeof(T)); return val; } - + static void linkJump(void* code, AssemblerLabel from, void* to) { ASSERT(from.isSet()); @@ -1902,12 +1903,12 @@ class X86Assembler { { setRel32(from, to); } - + static void relinkCall(void* from, void* to) { setRel32(from, to); } - + static void repatchCompact(void* where, int32_t value) { ASSERT(value >= std::numeric_limits::min()); @@ -1924,7 +1925,7 @@ class X86Assembler { { setPointer(where, value); } - + static void* readPointer(void* where) { return reinterpret_cast(where)[-1]; @@ -1938,12 +1939,12 @@ class X86Assembler { ptr[0] = static_cast(OP_JMP_rel32); *reinterpret_cast(ptr + 1) = static_cast(distance); } - + static ptrdiff_t maxJumpReplacementSize() { return 5; } - + #if CPU(X86_64) static void revertJumpTo_movq_i64r(void* instructionStart, int64_t imm, RegisterID dst) { @@ -1953,7 +1954,7 @@ class X86Assembler { uint8_t* ptr = reinterpret_cast(instructionStart); ptr[0] = PRE_REX | (1 << 3) | (dst >> 3); ptr[1] = OP_MOV_EAXIv | (dst & 7); - + union { uint64_t asWord; uint8_t asBytes[8]; @@ -1963,7 +1964,7 @@ class X86Assembler { ptr[i] = u.asBytes[i - rexBytes - opcodeBytes]; } #endif - + static void revertJumpTo_cmpl_ir_force32(void* instructionStart, int32_t imm, RegisterID dst) { const int opcodeBytes = 1; @@ -1980,7 +1981,7 @@ class X86Assembler { for (unsigned i = opcodeBytes + modRMBytes; i < static_cast(maxJumpReplacementSize()); ++i) ptr[i] = u.asBytes[i - opcodeBytes - modRMBytes]; } - + static void revertJumpTo_cmpl_im_force32(void* instructionStart, int32_t imm, int offset, RegisterID dst) { ASSERT_UNUSED(offset, !offset); @@ -1998,7 +1999,7 @@ class X86Assembler { for (unsigned i = opcodeBytes + modRMBytes; i < static_cast(maxJumpReplacementSize()); ++i) ptr[i] = u.asBytes[i - opcodeBytes - modRMBytes]; } - + static void replaceWithLoad(void* instructionStart) { uint8_t* ptr = reinterpret_cast(instructionStart); @@ -2016,7 +2017,7 @@ class X86Assembler { RELEASE_ASSERT_NOT_REACHED(); } } - + static void replaceWithAddressComputation(void* instructionStart) { uint8_t* ptr = reinterpret_cast(instructionStart); @@ -2034,7 +2035,7 @@ class X86Assembler { RELEASE_ASSERT_NOT_REACHED(); } } - + static unsigned getCallReturnOffset(AssemblerLabel call) { ASSERT(call.isSet()); @@ -2046,12 +2047,12 @@ class X86Assembler { ASSERT(label.isSet()); return reinterpret_cast(reinterpret_cast(code) + label.m_offset); } - + static int getDifferenceBetweenLabels(AssemblerLabel a, AssemblerLabel b) { return b.m_offset - a.m_offset; } - + PassRefPtr executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort) { return m_formatter.executableCopy(globalData, ownerUID, effort); @@ -2085,7 +2086,7 @@ class X86Assembler { T *ptr = &reinterpret_cast(where)[idx]; memcpy(ptr, &value, sizeof(T)); } - + static void setInt8(void* where, int8_t value) { reinterpret_cast(where)[-1] = value; @@ -2171,7 +2172,7 @@ class X86Assembler { m_buffer.putByteUnchecked(opcode); memoryModRM_disp32(reg, base, offset); } - + void oneByteOp_disp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset) { m_buffer.ensureSpace(maxInstructionSize); @@ -2285,7 +2286,7 @@ class X86Assembler { m_buffer.putByteUnchecked(opcode); memoryModRM_disp32(reg, base, offset); } - + void oneByteOp64_disp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset) { m_buffer.ensureSpace(maxInstructionSize); @@ -2364,7 +2365,7 @@ class X86Assembler { void twoByteOp8(TwoByteOpcodeID opcode, RegisterID reg, RegisterID rm) { m_buffer.ensureSpace(maxInstructionSize); - emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm); + emitRexIf(byteRegRequiresRex(reg) || byteRegRequiresRex(rm), reg, 0, rm); m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE); m_buffer.putByteUnchecked(opcode); registerModRM(reg, rm); @@ -2566,7 +2567,7 @@ class X86Assembler { m_buffer.putIntUnchecked(offset); } } - + void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset) { ASSERT(index != noIndex); diff --git a/src/3rdparty/masm/stubs/WTFStubs.cpp b/src/3rdparty/masm/stubs/WTFStubs.cpp index f408b355f50..facba7d9379 100644 --- a/src/3rdparty/masm/stubs/WTFStubs.cpp +++ b/src/3rdparty/masm/stubs/WTFStubs.cpp @@ -44,6 +44,10 @@ #include // qvsnprintf #include +#if ENABLE(ASSEMBLER) && CPU(X86) && !OS(MAC_OS_X) +#include +#endif + namespace WTF { void* fastMalloc(size_t size) @@ -142,8 +146,6 @@ void WTFInvokeCrashHook() #if ENABLE(ASSEMBLER) && CPU(X86) && !OS(MAC_OS_X) -#include - JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse2CheckState = JSC::MacroAssemblerX86Common::NotCheckedSSE2; #endif diff --git a/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp b/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp index d59fdcd675d..d799f913a47 100644 --- a/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp +++ b/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp @@ -98,6 +98,9 @@ static int memfdForUsage(size_t bytes, OSAllocator::Usage usage) void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable, bool executable) { #if OS(QNX) + UNUSED_PARAM(usage); + UNUSED_PARAM(writable); + UNUSED_PARAM(executable); // Reserve memory with PROT_NONE and MAP_LAZY so it isn't committed now. void* result = mmap(0, bytes, PROT_NONE, MAP_LAZY | MAP_PRIVATE | MAP_ANON, -1, 0); if (result == MAP_FAILED) @@ -111,7 +114,11 @@ void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable, (fd == -1 ? MAP_ANON : 0), fd, 0); if (result == MAP_FAILED) CRASH(); - madvise(result, bytes, MADV_DONTNEED); + + while (madvise(result, bytes, MADV_DONTNEED)) { + if (errno != EAGAIN) + CRASH(); + } if (fd != -1) close(fd); @@ -218,7 +225,12 @@ void OSAllocator::commit(void* address, size_t bytes, bool writable, bool execut protection |= PROT_EXEC; if (mprotect(address, bytes, protection)) CRASH(); - madvise(address, bytes, MADV_WILLNEED); + + while (madvise(address, bytes, MADV_WILLNEED)) { + if (errno != EAGAIN) + break; // We don't have to crash here. MADV_WILLNEED is only advisory + } + #elif HAVE(MADV_FREE_REUSE) UNUSED_PARAM(writable); UNUSED_PARAM(executable); @@ -238,7 +250,10 @@ void OSAllocator::decommit(void* address, size_t bytes) // Use PROT_NONE and MAP_LAZY to decommit the pages. mmap(address, bytes, PROT_NONE, MAP_FIXED | MAP_LAZY | MAP_PRIVATE | MAP_ANON, -1, 0); #elif OS(LINUX) - madvise(address, bytes, MADV_DONTNEED); + while (madvise(address, bytes, MADV_DONTNEED)) { + if (errno != EAGAIN) + CRASH(); + } if (mprotect(address, bytes, PROT_NONE)) CRASH(); #elif HAVE(MADV_FREE_REUSE) diff --git a/src/3rdparty/masm/wtf/Platform.h b/src/3rdparty/masm/wtf/Platform.h index 29decfadcf7..5c83dec2b93 100644 --- a/src/3rdparty/masm/wtf/Platform.h +++ b/src/3rdparty/masm/wtf/Platform.h @@ -224,6 +224,7 @@ || defined(__ARM_ARCH_6K__) \ || defined(__ARM_ARCH_6Z__) \ || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6KZ__) \ || defined(__ARM_ARCH_6T2__) \ || defined(__ARMV6__) #define WTF_ARM_ARCH_VERSION 6 diff --git a/src/3rdparty/masm/yarr/Yarr.h b/src/3rdparty/masm/yarr/Yarr.h index ccf78f98800..2955ea7e72f 100644 --- a/src/3rdparty/masm/yarr/Yarr.h +++ b/src/3rdparty/masm/yarr/Yarr.h @@ -28,6 +28,7 @@ #pragma once #include +#include #include "YarrErrorCode.h" namespace JSC { namespace Yarr { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ca221d9f5f1..3c6a28072f4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,9 +28,12 @@ if(TARGET Qt::Gui AND TARGET Qt::qsb AND QT_FEATURE_qml_animation) add_subdirectory(quickshapes) add_subdirectory(quicklayouts) - find_package(Qt6 ${PROJECT_VERSION} CONFIG COMPONENTS Test) # special case - if(QT_FEATURE_testlib AND TARGET Qt::Test) # special case + find_package(Qt6 ${PROJECT_VERSION} QUIET CONFIG OPTIONAL_COMPONENTS Test) + if(QT_FEATURE_testlib AND TARGET Qt::Test) add_subdirectory(qmltest) + if(QT_FEATURE_network) + add_subdirectory(quicktestutils) + endif() endif() if(QT_FEATURE_quick_particles) @@ -40,6 +43,16 @@ if(TARGET Qt::Gui AND TARGET Qt::qsb AND QT_FEATURE_qml_animation) if(TARGET Qt::Widgets) add_subdirectory(quickwidgets) endif() + + add_subdirectory(quicktemplates2) + add_subdirectory(quickcontrols2impl) + add_subdirectory(quickcontrols2) + add_subdirectory(quickdialogs2) + add_subdirectory(quicknativestyle) + + if(QT_FEATURE_testlib AND QT_FEATURE_network AND TARGET Qt::Test AND TARGET Qt::QuickControls2) + add_subdirectory(quickcontrolstestutils) + endif() else() qt_configure_add_summary_section(NAME "Qt Quick") qt_configure_add_summary_entry(TYPE "message" ARGS "Qt Quick support" MESSAGE "no") diff --git a/src/core/qqmlcoreglobal_p.h b/src/core/qqmlcoreglobal_p.h index 85dc15b095e..f97e7df911f 100644 --- a/src/core/qqmlcoreglobal_p.h +++ b/src/core/qqmlcoreglobal_p.h @@ -69,6 +69,4 @@ QT_BEGIN_NAMESPACE QT_END_NAMESPACE -void Q_QMLCORE_PRIVATE_EXPORT qml_register_types_QtCore(); - #endif // QQMLCOREGLOBAL_P_H diff --git a/src/core/qqmlstandardpaths.cpp b/src/core/qqmlstandardpaths.cpp index 39c5eb3ebf1..12f401b565f 100644 --- a/src/core/qqmlstandardpaths.cpp +++ b/src/core/qqmlstandardpaths.cpp @@ -149,3 +149,5 @@ QUrl QQmlStandardPaths::writableLocation(QStandardPaths::StandardLocation type) } QT_END_NAMESPACE + +#include "moc_qqmlstandardpaths_p.cpp" diff --git a/src/imports/builtins/CMakeLists.txt b/src/imports/builtins/CMakeLists.txt index fb6984a9614..e1632e1b09f 100644 --- a/src/imports/builtins/CMakeLists.txt +++ b/src/imports/builtins/CMakeLists.txt @@ -4,3 +4,10 @@ qt_path_join(qml_install_dir "${QT_INSTALL_DIR}" "${INSTALL_QMLDIR}") qt_copy_or_install(FILES ${qml_type_files} DESTINATION ${qml_install_dir} ) + +# in prefix builds we also need to copy the files into the build directory of +# the module, so that they are located together with the QML modules +if(QT_WILL_INSTALL) + qt_path_join(qml_build_dir "${QT_BUILD_DIR}" "${INSTALL_QMLDIR}") + file(COPY ${qml_type_files} DESTINATION ${qml_build_dir}) +endif() diff --git a/src/imports/builtins/builtins.qmltypes b/src/imports/builtins/builtins.qmltypes index f1a57cfab30..907f24fef64 100644 --- a/src/imports/builtins/builtins.qmltypes +++ b/src/imports/builtins/builtins.qmltypes @@ -5,6 +5,8 @@ Module { Component { name: "void" + extension: "undefined" + exports: ["QML/void 1.0"] accessSemantics: "none" } @@ -86,15 +88,9 @@ Module { } } - Component { - name: "number" - extension: "Number" - accessSemantics: "value" - } - Component { name: "int" - prototype: "number" + extension: "Number" exports: ["QML/int 1.0"] exportMetaObjectRevisions: [256] accessSemantics: "value" @@ -102,13 +98,13 @@ Module { Component { name: "float" - prototype: "number" + extension: "Number" accessSemantics: "value" } Component { name: "double" - prototype: "number" + extension: "Number" exports: ["QML/real 1.0", "QML/double 1.0"] exportMetaObjectRevisions: [256] accessSemantics: "value" @@ -124,6 +120,7 @@ Module { Component { name: "bool" + extension: "Boolean" exports: ["QML/bool 1.0"] exportMetaObjectRevisions: [256] accessSemantics: "value" @@ -139,6 +136,7 @@ Module { Component { name: "QUrl" + extension: "Url" exports: ["QML/url 1.0"] exportMetaObjectRevisions: [256] accessSemantics: "value" @@ -160,4 +158,9 @@ Module { extension: "RegExp" accessSemantics: "value" } + + Component { + name: "QByteArray" + accessSemantics: "value" + } } diff --git a/src/imports/builtins/jsroot.qmltypes b/src/imports/builtins/jsroot.qmltypes index 419a4e57265..39878d8cf36 100644 --- a/src/imports/builtins/jsroot.qmltypes +++ b/src/imports/builtins/jsroot.qmltypes @@ -623,7 +623,7 @@ Module { Property { name: "Math"; type: "Math" } Property { name: "JSON"; type: "JSON" } Property { name: "Reflect"; type: "Reflect" } - Property { name: "undefined" } + Property { name: "undefined"; isReadonly: true } Property { name: "NaN"; type: "number"; isReadonly: true } Property { name: "Infinity"; type: "number"; isReadonly: true } Property { name: "Qt"; type: "Qt" } @@ -1356,6 +1356,7 @@ Module { Method { name: "formatTime" } Method { name: "formatDateTime" } Method { name: "locale" } + Method { name: "url" } Method { name: "resolvedUrl" } Method { name: "openUrlExternally" } Method { name: "font" } diff --git a/src/imports/tooling/CMakeLists.txt b/src/imports/tooling/CMakeLists.txt index a39f9ee91b6..f8daf9f4eb0 100644 --- a/src/imports/tooling/CMakeLists.txt +++ b/src/imports/tooling/CMakeLists.txt @@ -10,7 +10,7 @@ set(qml_files ) set_source_files_properties(${qml_files} PROPERTIES - QT_QML_SOURCE_VERSION "1.2;6.0" + QT_QML_SOURCE_VERSIONS "1.2;6.0" ) qt_internal_add_qml_module(quicktooling diff --git a/src/imports/tooling/Method.qml b/src/imports/tooling/Method.qml index 3b019c4549e..b43aaf69126 100644 --- a/src/imports/tooling/Method.qml +++ b/src/imports/tooling/Method.qml @@ -44,4 +44,6 @@ Member { property string type property int revision: 0 property bool isConstructor: false + property bool isList: false + property bool isPointer: false } diff --git a/src/imports/tooling/Parameter.qml b/src/imports/tooling/Parameter.qml index a45f9d33ff1..ee110c8b392 100644 --- a/src/imports/tooling/Parameter.qml +++ b/src/imports/tooling/Parameter.qml @@ -40,7 +40,8 @@ import QML QtObject { - required property string name - required property string type + property string name + property string type property bool isPointer: false + property bool isList: false } diff --git a/src/imports/tooling/Property.qml b/src/imports/tooling/Property.qml index dd5be3661da..0f1da3928c4 100644 --- a/src/imports/tooling/Property.qml +++ b/src/imports/tooling/Property.qml @@ -40,7 +40,7 @@ import QML Member { - required property string type + property string type property bool isPointer: false property bool isReadonly: false property bool isRequired: false diff --git a/src/imports/tooling/Signal.qml b/src/imports/tooling/Signal.qml index 4ac1dc1fea2..1fa8a96b3ad 100644 --- a/src/imports/tooling/Signal.qml +++ b/src/imports/tooling/Signal.qml @@ -42,4 +42,5 @@ import QML Member { default property list parameters property int revision: 0 + property string type } diff --git a/src/labs/CMakeLists.txt b/src/labs/CMakeLists.txt index 6ca0d7a695e..fc340e42e55 100644 --- a/src/labs/CMakeLists.txt +++ b/src/labs/CMakeLists.txt @@ -12,6 +12,10 @@ if(TARGET Qt::Quick) add_subdirectory(animation) endif() +if(TARGET Qt::QuickTemplates2) + add_subdirectory(platform) +endif() + if(QT_FEATURE_quick_shadereffect AND TARGET Qt::Quick) add_subdirectory(wavefrontmesh) endif() @@ -19,3 +23,4 @@ endif() if(QT_FEATURE_systemsemaphore AND TARGET Qt::Quick) add_subdirectory(sharedimage) endif() + diff --git a/src/labs/animation/CMakeLists.txt b/src/labs/animation/CMakeLists.txt index 88e756f3a6b..6524c654777 100644 --- a/src/labs/animation/CMakeLists.txt +++ b/src/labs/animation/CMakeLists.txt @@ -3,6 +3,8 @@ qt_internal_add_qml_module(LabsAnimation VERSION "${PROJECT_VERSION}" PLUGIN_TARGET labsanimationplugin CLASS_NAME QtLabsAnimationPlugin + DEPENDENCIES + QtQml SOURCES qquickboundaryrule.cpp qquickboundaryrule_p.h qqmlanimationglobal_p.h diff --git a/src/labs/animation/doc/src/qmlanimation.qdoc b/src/labs/animation/doc/src/qmlanimation.qdoc index c8d949b27b6..2104b8f9f5a 100644 --- a/src/labs/animation/doc/src/qmlanimation.qdoc +++ b/src/labs/animation/doc/src/qmlanimation.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \qmlmodule Qt.labs.animation 1.0 + \qmlmodule Qt.labs.animation \title Qt Quick experimental animation types \ingroup qmlmodules \brief Provides QML experimental types for animation diff --git a/src/labs/animation/qqmlanimationglobal_p.h b/src/labs/animation/qqmlanimationglobal_p.h index 9ba3ecea2a4..445ca8b1367 100644 --- a/src/labs/animation/qqmlanimationglobal_p.h +++ b/src/labs/animation/qqmlanimationglobal_p.h @@ -68,6 +68,4 @@ QT_BEGIN_NAMESPACE QT_END_NAMESPACE -void Q_LABSANIMATION_PRIVATE_EXPORT qml_register_types_Qt_labs_animation(); - #endif // QTLABSANIMATIONGLOBAL_P_H diff --git a/src/labs/animation/qquickboundaryrule.cpp b/src/labs/animation/qquickboundaryrule.cpp index 61e5d007d52..0b2d2e2856e 100644 --- a/src/labs/animation/qquickboundaryrule.cpp +++ b/src/labs/animation/qquickboundaryrule.cpp @@ -146,7 +146,7 @@ void QQuickBoundaryReturnJob::updateState(QAbstractAnimationJob::State newState, Note that a property cannot have more than one assigned BoundaryRule. - \sa {Animation and Transitions in Qt Quick}, {Qt Quick Examples - Animation#Behaviors}{Behavior example}, {Qt QML} + \sa {Animation and Transitions in Qt Quick}, {Qt Quick Examples - Animation#Behaviors}{Behavior example}, {Qt QML}, {Pointer Handlers Example} */ QQuickBoundaryRule::QQuickBoundaryRule(QObject *parent) @@ -353,7 +353,7 @@ qreal QQuickBoundaryRule::peakOvershoot() const } /*! - \qmlproperty enum QtQuick::BoundaryRule::overshootFilter + \qmlproperty enumeration QtQuick::BoundaryRule::overshootFilter This property specifies the aggregation function that will be applied to the intercepted property value. @@ -419,7 +419,7 @@ bool QQuickBoundaryRule::returnToBounds() } /*! - \qmlproperty qreal QtQuick::BoundaryRule::easing + \qmlproperty enumeration QtQuick::BoundaryRule::easing This property holds the easing curve to be applied in overshoot mode (whenever the \l minimum or \l maximum constraint is violated, while diff --git a/src/labs/folderlistmodel/fileinfothread.cpp b/src/labs/folderlistmodel/fileinfothread.cpp index a93edd3b1ba..69dcedef775 100644 --- a/src/labs/folderlistmodel/fileinfothread.cpp +++ b/src/labs/folderlistmodel/fileinfothread.cpp @@ -44,6 +44,7 @@ #include +QT_BEGIN_NAMESPACE FileInfoThread::FileInfoThread(QObject *parent) : QThread(parent), @@ -367,3 +368,7 @@ void FileInfoThread::findChangeRange(const QList &list, int &fromI // For now I let the rest of the list be updated.. toIndex = list.size() > currentFileList.size() ? list.size() - 1 : currentFileList.size() - 1; } + +QT_END_NAMESPACE + +#include "moc_fileinfothread_p.cpp" diff --git a/src/labs/folderlistmodel/fileinfothread_p.h b/src/labs/folderlistmodel/fileinfothread_p.h index 1ed3a9904b3..903a95efa1d 100644 --- a/src/labs/folderlistmodel/fileinfothread_p.h +++ b/src/labs/folderlistmodel/fileinfothread_p.h @@ -63,6 +63,8 @@ #include "fileproperty_p.h" #include "qquickfolderlistmodel_p.h" +QT_BEGIN_NAMESPACE + class FileInfoThread : public QThread { Q_OBJECT @@ -130,4 +132,6 @@ public Q_SLOTS: bool caseSensitive; }; +QT_END_NAMESPACE + #endif // FILEINFOTHREAD_P_H diff --git a/src/labs/folderlistmodel/fileproperty_p.h b/src/labs/folderlistmodel/fileproperty_p.h index 48be4a3d854..26f2b71b470 100644 --- a/src/labs/folderlistmodel/fileproperty_p.h +++ b/src/labs/folderlistmodel/fileproperty_p.h @@ -54,6 +54,8 @@ #include #include +QT_BEGIN_NAMESPACE + class FileProperty { public: @@ -100,4 +102,7 @@ class FileProperty QDateTime mLastModified; QDateTime mLastRead; }; + +QT_END_NAMESPACE + #endif // FILEPROPERTY_P_H diff --git a/src/labs/folderlistmodel/qquickfolderlistmodel.cpp b/src/labs/folderlistmodel/qquickfolderlistmodel.cpp index 33206e5fe65..b05613b4105 100644 --- a/src/labs/folderlistmodel/qquickfolderlistmodel.cpp +++ b/src/labs/folderlistmodel/qquickfolderlistmodel.cpp @@ -252,16 +252,16 @@ QString QQuickFolderListModelPrivate::resolvePath(const QUrl &path) Components access names and paths via the following roles: \list - \li \c fileName - \li \c filePath - \li \c fileURL (since Qt 5.2; deprecated since Qt 5.15) - \li \c fileUrl (since Qt 5.15) - \li \c fileBaseName - \li \c fileSuffix - \li \c fileSize - \li \c fileModified - \li \c fileAccessed - \li \c fileIsDir + \li \c fileName (\c string) + \li \c filePath (\c string) + \li \c fileURL (\c url) (since Qt 5.2; deprecated since Qt 5.15) + \li \c fileUrl (\c url) (since Qt 5.15) + \li \c fileBaseName (\c string) + \li \c fileSuffix (\c string) + \li \c fileSize (\c qlonglong) + \li \c fileModified (\c date) + \li \c fileAccessed (\c date) + \li \c fileIsDir (\c bool) \endlist Additionally a file entry can be differentiated from a folder entry via the @@ -304,6 +304,7 @@ QString QQuickFolderListModelPrivate::resolvePath(const QUrl &path) Component { id: fileDelegate + required property string fileName Text { text: fileName } } @@ -395,6 +396,7 @@ QHash QQuickFolderListModel::roleNames() const /*! \qmlproperty int FolderListModel::count + \readonly Returns the number of items in the current folder that match the filter criteria. @@ -419,7 +421,8 @@ QModelIndex QQuickFolderListModel::index(int row, int , const QModelIndex &) con The value must be a \c file: or \c qrc: URL, or a relative URL. - The default value is an invalid URL. + The default value is the application's working directory at the time + when the FolderListModel is first initialized. */ QUrl QQuickFolderListModel::folder() const { @@ -493,6 +496,7 @@ void QQuickFolderListModel::setRootFolder(const QUrl &path) /*! \qmlproperty url FolderListModel::parentFolder + \readonly Returns the URL of the parent of the current \l folder. */ @@ -563,15 +567,14 @@ void QQuickFolderListModel::componentComplete() /*! \qmlproperty enumeration FolderListModel::sortField - The \a sortField property contains field to use for sorting. sortField - may be one of: - \list - \li Unsorted - no sorting is applied. - \li Name - sort by filename - \li Time - sort by time modified - \li Size - sort by file size - \li Type - sort by file type (extension) - \endlist + The \a sortField property contains the field to use for sorting. + \c sortField may be one of: + + \value FolderListModel.Unsorted no sorting is applied + \value FolderListModel.Name sort by filename (default) + \value FolderListModel.Time sort by time modified + \value FolderListModel.Size sort by file size + \value FolderListModel.Type sort by file type/extension \sa sortReversed */ @@ -819,13 +822,13 @@ void QQuickFolderListModel::setCaseSensitive(bool on) /*! \qmlproperty enumeration FolderListModel::status \since 5.11 + \readonly This property holds the status of folder reading. It can be one of: - \list - \li FolderListModel.Null - no \a folder has been set - \li FolderListModel.Ready - the folder has been loaded - \li FolderListModel.Loading - the folder is currently being loaded - \endlist + + \value FolderListModel.Null no \a folder has been set + \value FolderListModel.Ready the folder has been loaded + \value FolderListModel.Loading the folder is currently being loaded Use this status to provide an update or respond to the status change in some way. For example, you could: @@ -886,16 +889,16 @@ void QQuickFolderListModel::setSortCaseSensitive(bool on) are available: \list - \li \c fileName - \li \c filePath - \li \c fileURL (since Qt 5.2; deprecated since Qt 5.15) - \li \c fileUrl (since Qt 5.15) - \li \c fileBaseName - \li \c fileSuffix - \li \c fileSize - \li \c fileModified - \li \c fileAccessed - \li \c fileIsDir + \li \c fileName (\c string) + \li \c filePath (\c string) + \li \c fileURL (\c url) (since Qt 5.2; deprecated since Qt 5.15) + \li \c fileUrl (\c url) (since Qt 5.15) + \li \c fileBaseName (\c string) + \li \c fileSuffix (\c string) + \li \c fileSize (\c qlonglong) + \li \c fileModified (\c date) + \li \c fileAccessed (\c date) + \li \c fileIsDir (\c bool) \endlist */ QVariant QQuickFolderListModel::get(int idx, const QString &property) const diff --git a/src/labs/folderlistmodel/qquickfolderlistmodelglobal_p.h b/src/labs/folderlistmodel/qquickfolderlistmodelglobal_p.h index c8df4e9ff7c..578ea49fcdb 100644 --- a/src/labs/folderlistmodel/qquickfolderlistmodelglobal_p.h +++ b/src/labs/folderlistmodel/qquickfolderlistmodelglobal_p.h @@ -68,6 +68,4 @@ QT_BEGIN_NAMESPACE QT_END_NAMESPACE -void Q_LABSFOLDERMODEL_PRIVATE_EXPORT qml_register_types_Qt_labs_folderlistmodel(); - #endif // QTLABSFOLDERLISTMODELGLOBAL_P_H diff --git a/src/labs/models/CMakeLists.txt b/src/labs/models/CMakeLists.txt index e417013ea6d..fa4ebbd70b2 100644 --- a/src/labs/models/CMakeLists.txt +++ b/src/labs/models/CMakeLists.txt @@ -10,6 +10,8 @@ qt_internal_add_qml_module(LabsQmlModels PUBLIC_LIBRARIES Qt::QmlModelsPrivate Qt::QmlPrivate + DEPENDENCIES + QtQml.Models ) qt_internal_extend_target(LabsQmlModels CONDITION QT_FEATURE_qml_table_model diff --git a/src/labs/models/doc/src/qmllabsmodels.qdoc b/src/labs/models/doc/src/qmllabsmodels.qdoc index f780a75687d..f2b57323dcd 100644 --- a/src/labs/models/doc/src/qmllabsmodels.qdoc +++ b/src/labs/models/doc/src/qmllabsmodels.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \qmlmodule Qt.labs.qmlmodels 1.0 + \qmlmodule Qt.labs.qmlmodels \title Qt QML Models experimental QML Types \ingroup qmlmodules \brief Provides QML experimental types for data models. @@ -36,7 +36,7 @@ To use the types in this module, import the module with the following line: - \code + \qml import Qt.labs.qmlmodels - \endcode + \endqml */ diff --git a/src/labs/models/qqmldelegatecomponent.cpp b/src/labs/models/qqmldelegatecomponent.cpp index f7b778e5748..1ef7f532a0a 100644 --- a/src/labs/models/qqmldelegatecomponent.cpp +++ b/src/labs/models/qqmldelegatecomponent.cpp @@ -155,7 +155,17 @@ bool QQmlDelegateChoice::match(int row, int column, const QVariant &value) const if (!m_value.isValid() && m_row < 0 && m_column < 0) return true; - const bool roleMatched = (m_value.isValid()) ? value == m_value : true; + bool roleMatched = true; + if (m_value.isValid()) { + roleMatched = (value == m_value); + if (!roleMatched) { + bool valueOk = false; + bool mValueOk = false; + roleMatched = (value.toInt(&valueOk) == m_value.toInt(&mValueOk) && valueOk && mValueOk); + } + if (!roleMatched) + roleMatched = (value.toString() == m_value.toString()); + } const bool rowMatched = (m_row < 0 ) ? true : m_row == row; const bool columnMatched = (m_column < 0 ) ? true : m_column == column; return roleMatched && rowMatched && columnMatched; @@ -330,3 +340,5 @@ QQmlComponent *QQmlDelegateChooser::delegate(QQmlAdaptorModel *adaptorModel, int } QT_END_NAMESPACE + +#include "moc_qqmldelegatecomponent_p.cpp" diff --git a/src/labs/models/qqmlmodelsglobal_p.h b/src/labs/models/qqmlmodelsglobal_p.h index ceb7ac1f55f..46638b04425 100644 --- a/src/labs/models/qqmlmodelsglobal_p.h +++ b/src/labs/models/qqmlmodelsglobal_p.h @@ -68,6 +68,4 @@ QT_BEGIN_NAMESPACE QT_END_NAMESPACE -void Q_LABSQMLMODELS_PRIVATE_EXPORT qml_register_types_Qt_labs_qmlmodels(); - #endif // QTLABSQMLMODELSGLOBAL_P_H diff --git a/src/labs/models/qqmltablemodel.cpp b/src/labs/models/qqmltablemodel.cpp index e60c525b0de..ea1671fb119 100644 --- a/src/labs/models/qqmltablemodel.cpp +++ b/src/labs/models/qqmltablemodel.cpp @@ -1085,3 +1085,5 @@ bool QQmlTableModel::validateRowIndex(const char *functionName, const char *argu } QT_END_NAMESPACE + +#include "moc_qqmltablemodel_p.cpp" diff --git a/src/labs/models/qqmltablemodelcolumn.cpp b/src/labs/models/qqmltablemodelcolumn.cpp index 93da0642de4..73dfd595fbd 100644 --- a/src/labs/models/qqmltablemodelcolumn.cpp +++ b/src/labs/models/qqmltablemodelcolumn.cpp @@ -198,3 +198,5 @@ const QHash QQmlTableModelColumn::supportedRoleNames() } QT_END_NAMESPACE + +#include "moc_qqmltablemodelcolumn_p.cpp" diff --git a/src/labs/models/qqmltablemodelcolumn_p.h b/src/labs/models/qqmltablemodelcolumn_p.h index 7da31c9e2ac..ef0fd18fe07 100644 --- a/src/labs/models/qqmltablemodelcolumn_p.h +++ b/src/labs/models/qqmltablemodelcolumn_p.h @@ -216,8 +216,6 @@ class Q_LABSQMLMODELS_PRIVATE_EXPORT QQmlTableModelColumn : public QObject void setSizeHintChanged(); private: - int mIndex = -1; - // We store these in hashes because QQuickTableModel needs string-based lookup in certain situations. QHash mGetters; QHash mSetters; diff --git a/src/labs/platform/CMakeLists.txt b/src/labs/platform/CMakeLists.txt new file mode 100644 index 00000000000..92a41808da6 --- /dev/null +++ b/src/labs/platform/CMakeLists.txt @@ -0,0 +1,91 @@ +##################################################################### +## qtlabsplatformplugin Plugin: +##################################################################### + +qt_internal_add_qml_module(qtlabsplatformplugin + URI "Qt.labs.platform" + VERSION "1.1" + CLASS_NAME QtLabsPlatformPlugin + DEPENDENCIES + QtQuick + PLUGIN_TARGET qtlabsplatformplugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + SOURCES + qquicklabsplatformcolordialog.cpp qquicklabsplatformcolordialog_p.h + qquicklabsplatformdialog.cpp qquicklabsplatformdialog_p.h + qquicklabsplatformfiledialog.cpp qquicklabsplatformfiledialog_p.h + qquicklabsplatformfolderdialog.cpp qquicklabsplatformfolderdialog_p.h + qquicklabsplatformfontdialog.cpp qquicklabsplatformfontdialog_p.h + qquicklabsplatformicon.cpp qquicklabsplatformicon_p.h + qquicklabsplatformiconloader.cpp qquicklabsplatformiconloader_p.h + qquicklabsplatformmenu.cpp qquicklabsplatformmenu_p.h + qquicklabsplatformmenubar.cpp qquicklabsplatformmenubar_p.h + qquicklabsplatformmenuitem.cpp qquicklabsplatformmenuitem_p.h + qquicklabsplatformmenuitemgroup.cpp qquicklabsplatformmenuitemgroup_p.h + qquicklabsplatformmenuseparator.cpp qquicklabsplatformmenuseparator_p.h + qquicklabsplatformmessagedialog.cpp qquicklabsplatformmessagedialog_p.h + qquicklabsplatformstandardpaths.cpp qquicklabsplatformstandardpaths_p.h + qtlabsplatformplugin.cpp + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private +) + +qt_internal_extend_target(qtlabsplatformplugin CONDITION TARGET Qt::Widgets + SOURCES + widgets/qwidgetplatform_p.h + LIBRARIES + Qt::Widgets +) + +qt_internal_extend_target(qtlabsplatformplugin CONDITION TARGET Qt::Widgets AND QT_FEATURE_systemtrayicon AND TARGET Qt::Widgets # special case + SOURCES + widgets/qwidgetplatformsystemtrayicon.cpp widgets/qwidgetplatformsystemtrayicon_p.h +) + +qt_internal_extend_target(qtlabsplatformplugin CONDITION TARGET Qt::Widgets AND (QT_FEATURE_colordialog OR QT_FEATURE_filedialog OR QT_FEATURE_fontdialog OR QT_FEATURE_messagebox) + SOURCES + widgets/qwidgetplatformdialog.cpp widgets/qwidgetplatformdialog_p.h +) + +qt_internal_extend_target(qtlabsplatformplugin CONDITION TARGET Qt::Widgets AND QT_FEATURE_colordialog AND TARGET Qt::Widgets # special case + SOURCES + widgets/qwidgetplatformcolordialog.cpp widgets/qwidgetplatformcolordialog_p.h +) + +qt_internal_extend_target(qtlabsplatformplugin CONDITION TARGET Qt::Widgets AND QT_FEATURE_filedialog AND TARGET Qt::Widgets # special case + SOURCES + widgets/qwidgetplatformfiledialog.cpp widgets/qwidgetplatformfiledialog_p.h +) + +qt_internal_extend_target(qtlabsplatformplugin CONDITION TARGET Qt::Widgets AND QT_FEATURE_fontdialog AND TARGET Qt::Widgets # special case + SOURCES + widgets/qwidgetplatformfontdialog.cpp widgets/qwidgetplatformfontdialog_p.h +) + +qt_internal_extend_target(qtlabsplatformplugin CONDITION TARGET Qt::Widgets AND QT_FEATURE_menu AND TARGET Qt::Widgets # special case + SOURCES + widgets/qwidgetplatformmenu.cpp widgets/qwidgetplatformmenu_p.h + widgets/qwidgetplatformmenuitem.cpp widgets/qwidgetplatformmenuitem_p.h +) + +qt_internal_extend_target(qtlabsplatformplugin CONDITION TARGET Qt::Widgets AND QT_FEATURE_messagebox AND TARGET Qt::Widgets # special case + SOURCES + widgets/qwidgetplatformmessagedialog.cpp widgets/qwidgetplatformmessagedialog_p.h +) + +qt_internal_extend_target(qtlabsplatformplugin CONDITION QT_FEATURE_systemtrayicon + SOURCES + qquicklabsplatformsystemtrayicon.cpp qquicklabsplatformsystemtrayicon_p.h +) + +qt_internal_add_docs(qtlabsplatformplugin + doc/qtlabsplatform.qdocconf +) diff --git a/src/labs/platform/doc/images/qtlabsplatform-colordialog-gtk.png b/src/labs/platform/doc/images/qtlabsplatform-colordialog-gtk.png new file mode 100644 index 00000000000..12197f7f74d Binary files /dev/null and b/src/labs/platform/doc/images/qtlabsplatform-colordialog-gtk.png differ diff --git a/src/labs/platform/doc/images/qtlabsplatform-filedialog-gtk.png b/src/labs/platform/doc/images/qtlabsplatform-filedialog-gtk.png new file mode 100644 index 00000000000..9360d747a2b Binary files /dev/null and b/src/labs/platform/doc/images/qtlabsplatform-filedialog-gtk.png differ diff --git a/src/labs/platform/doc/images/qtlabsplatform-folderdialog-gtk.png b/src/labs/platform/doc/images/qtlabsplatform-folderdialog-gtk.png new file mode 100644 index 00000000000..45f0585c5d7 Binary files /dev/null and b/src/labs/platform/doc/images/qtlabsplatform-folderdialog-gtk.png differ diff --git a/src/labs/platform/doc/images/qtlabsplatform-fontdialog-gtk.png b/src/labs/platform/doc/images/qtlabsplatform-fontdialog-gtk.png new file mode 100644 index 00000000000..0c6217bdb43 Binary files /dev/null and b/src/labs/platform/doc/images/qtlabsplatform-fontdialog-gtk.png differ diff --git a/src/labs/platform/doc/images/qtlabsplatform-menu.png b/src/labs/platform/doc/images/qtlabsplatform-menu.png new file mode 100644 index 00000000000..7945b45fbe8 Binary files /dev/null and b/src/labs/platform/doc/images/qtlabsplatform-menu.png differ diff --git a/src/labs/platform/doc/images/qtlabsplatform-menubar.png b/src/labs/platform/doc/images/qtlabsplatform-menubar.png new file mode 100644 index 00000000000..7faa81412bd Binary files /dev/null and b/src/labs/platform/doc/images/qtlabsplatform-menubar.png differ diff --git a/src/labs/platform/doc/images/qtlabsplatform-messagedialog-android.png b/src/labs/platform/doc/images/qtlabsplatform-messagedialog-android.png new file mode 100644 index 00000000000..3986694f7d4 Binary files /dev/null and b/src/labs/platform/doc/images/qtlabsplatform-messagedialog-android.png differ diff --git a/src/labs/platform/doc/images/qtlabsplatform-messagedialog-informative-android.png b/src/labs/platform/doc/images/qtlabsplatform-messagedialog-informative-android.png new file mode 100644 index 00000000000..b2d3cd37cb5 Binary files /dev/null and b/src/labs/platform/doc/images/qtlabsplatform-messagedialog-informative-android.png differ diff --git a/src/labs/platform/doc/images/qtlabsplatform-systemtrayicon-menu.png b/src/labs/platform/doc/images/qtlabsplatform-systemtrayicon-menu.png new file mode 100644 index 00000000000..670df8ed135 Binary files /dev/null and b/src/labs/platform/doc/images/qtlabsplatform-systemtrayicon-menu.png differ diff --git a/src/labs/platform/doc/images/qtlabsplatform-systemtrayicon-message.png b/src/labs/platform/doc/images/qtlabsplatform-systemtrayicon-message.png new file mode 100644 index 00000000000..beaeed92c48 Binary files /dev/null and b/src/labs/platform/doc/images/qtlabsplatform-systemtrayicon-message.png differ diff --git a/src/labs/platform/doc/images/qtlabsplatform-systemtrayicon.png b/src/labs/platform/doc/images/qtlabsplatform-systemtrayicon.png new file mode 100644 index 00000000000..2f7a851c881 Binary files /dev/null and b/src/labs/platform/doc/images/qtlabsplatform-systemtrayicon.png differ diff --git a/src/labs/platform/doc/qtlabsplatform.qdocconf b/src/labs/platform/doc/qtlabsplatform.qdocconf new file mode 100644 index 00000000000..8f64cae7948 --- /dev/null +++ b/src/labs/platform/doc/qtlabsplatform.qdocconf @@ -0,0 +1,40 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) +include($QT_INSTALL_DOCS/config/exampleurl-qtquickcontrols2.qdocconf) + +project = QtLabsPlatform +description = Qt Labs Platform Reference Documentation +version = $QT_VERSION + +qhp.projects = QtLabsPlatform + +qhp.QtLabsPlatform.file = qtlabsplatform.qhp +qhp.QtLabsPlatform.namespace = org.qt-project.qtlabsplatform.$QT_VERSION_TAG +qhp.QtLabsPlatform.virtualFolder = qtlabsplatform +qhp.QtLabsPlatform.indexTitle = Qt Labs Platform +qhp.QtLabsPlatform.indexRoot = + +qhp.QtLabsPlatform.filterAttributes = qtlabsplatform $QT_VERSION qtrefdoc +qhp.QtLabsPlatform.customFilters.Qt.name = QtLabsPlatform $QT_VERSION +qhp.QtLabsPlatform.customFilters.Qt.filterAttributes = qtlabsplatform $QT_VERSION + +qhp.QtLabsPlatform.subprojects = qmltypes +qhp.QtLabsPlatform.subprojects.qmltypes.title = QML Types +qhp.QtLabsPlatform.subprojects.qmltypes.indexTitle = Qt Labs Platform QML Types +qhp.QtLabsPlatform.subprojects.qmltypes.selectors = qmlclass +qhp.QtLabsPlatform.subprojects.qmltypes.sortPages = true + +depends = qtcore qtgui qtdoc qtqml qtqmlmodels qtquick qtquickcontrols qtwidgets + +# This module has no documented C++ types, clear the module header +moduleheader = + +{headerdirs,sourcedirs} += .. + +imagedirs += images + +navigation.landingpage = "Qt Labs Platform" +navigation.qmltypespage = "Qt Labs Platform QML Types" + +tagfile = qtlabsplatform.tags + +macro.labs = "\\note \\e{Types in Qt.labs modules are not guaranteed to remain compatible in future versions.}" diff --git a/src/labs/platform/doc/src/includes/widgets.qdocinc b/src/labs/platform/doc/src/includes/widgets.qdocinc new file mode 100644 index 00000000000..44ebba6de60 --- /dev/null +++ b/src/labs/platform/doc/src/includes/widgets.qdocinc @@ -0,0 +1,28 @@ +//! [1] +The Qt Labs Platform module uses Qt Widgets as a fallback on platforms that +do not have a native implementation available. Therefore, applications that +use types from the Qt Labs Platform module should link to QtWidgets and use +\l QApplication instead of \l QGuiApplication. + +To link against the QtWidgets library, add the following to your qmake project +file: + +\code +QT += widgets +\endcode + +Create an instance of \l QApplication in \c main(): + +\code +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + return app.exec(); +} +\endcode +//! [1] diff --git a/src/labs/platform/doc/src/qt6-changes.qdoc b/src/labs/platform/doc/src/qt6-changes.qdoc new file mode 100644 index 00000000000..de1c7a292fb --- /dev/null +++ b/src/labs/platform/doc/src/qt6-changes.qdoc @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquicklabsplatform-changes-qt6.html + \title Changes to Qt Quick Labs Platform + \ingroup changes-qt-5-to-6 + \brief Migrate Qt Quick Labs Platform to Qt 6. + + Qt 6 is a result of the conscious effort to make the framework more + efficient and easy to use. + + We try to maintain compatibility for all the public APIs in each release. + Some changes were inevitable in an effort to make Qt a better framework. + + In this topic we summarize those changes in Qt Quick Labs Platform, and + provide guidance to handle them. + + \section1 The Menu type + + The deprecated \c iconName and \c iconSource properties were removed. Use + the \l {Menu::}{icon} property instead. + + \section1 The MenuItem type + + The deprecated \c iconName and \c iconSource properties were removed. Use + the \l {MenuItem::}{icon} property instead. + + \section1 The SystemTrayIcon type + + The deprecated \c iconName and \c iconSource properties were removed. Use + the \l {SystemTrayIcon::}{icon} property instead. +*/ diff --git a/src/labs/platform/doc/src/qtlabsplatform-index.qdoc b/src/labs/platform/doc/src/qtlabsplatform-index.qdoc new file mode 100644 index 00000000000..c6eff0baa0d --- /dev/null +++ b/src/labs/platform/doc/src/qtlabsplatform-index.qdoc @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtlabsplatform-index.html + \title Qt Labs Platform + + \brief The experimental Qt Labs Platform module provides QML types for + native platform extensions. + + The experimental Qt Labs Platform module provides QML types for native + platform extensions. The module was introduced in Qt 5.8. + + \section1 QML Types + + \generatelist {qmltypesbymodule Qt.labs.platform} + + \labs + + \section1 Module Evolution + \l{Changes to Qt Quick Labs Platform} lists important changes in the + module API and functionality that were done for the Qt 6 series of Qt. + + \section1 Related Information + + \list + \li \l{Qt Quick} + \li \l{Qt Quick Controls} + \endlist +*/ diff --git a/src/labs/platform/doc/src/qtlabsplatform-qmltypes.qdoc b/src/labs/platform/doc/src/qtlabsplatform-qmltypes.qdoc new file mode 100644 index 00000000000..8a7d33a1519 --- /dev/null +++ b/src/labs/platform/doc/src/qtlabsplatform-qmltypes.qdoc @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \qmlmodule Qt.labs.platform + \title Qt Labs Platform QML Types + \ingroup qmlmodules + \brief Provides QML types for native platform extensions. + + The experimental \l{Qt Labs Platform} module provides QML types for native + platform extensions. These QML types work in conjunction with \l{Qt Quick} + and \l{Qt Quick Controls}. + + The QML types can be imported into your application using the + following import statement in your .qml file: + + \qml + import Qt.labs.platform + \endqml + + \section1 QML Types + + \generatelist {qmltypesbymodule Qt.labs.platform} + + \labs + + \section1 Related Information + + \list + \li \l {Qt Quick Controls QML Types} + \endlist + + \noautolist +*/ diff --git a/src/labs/platform/platform.pri b/src/labs/platform/platform.pri new file mode 100644 index 00000000000..c145663c239 --- /dev/null +++ b/src/labs/platform/platform.pri @@ -0,0 +1,39 @@ +HEADERS += \ + $$PWD/qquicklabsplatformcolordialog_p.h \ + $$PWD/qquicklabsplatformdialog_p.h \ + $$PWD/qquicklabsplatformfiledialog_p.h \ + $$PWD/qquicklabsplatformfolderdialog_p.h \ + $$PWD/qquicklabsplatformfontdialog_p.h \ + $$PWD/qquicklabsplatformicon_p.h \ + $$PWD/qquicklabsplatformiconloader_p.h \ + $$PWD/qquicklabsplatformmenu_p.h \ + $$PWD/qquicklabsplatformmenubar_p.h \ + $$PWD/qquicklabsplatformmenuitem_p.h \ + $$PWD/qquicklabsplatformmenuitemgroup_p.h \ + $$PWD/qquicklabsplatformmenuseparator_p.h \ + $$PWD/qquicklabsplatformmessagedialog_p.h \ + $$PWD/qquicklabsplatformstandardpaths_p.h + +SOURCES += \ + $$PWD/qquicklabsplatformcolordialog.cpp \ + $$PWD/qquicklabsplatformdialog.cpp \ + $$PWD/qquicklabsplatformfiledialog.cpp \ + $$PWD/qquicklabsplatformfolderdialog.cpp \ + $$PWD/qquicklabsplatformfontdialog.cpp \ + $$PWD/qquicklabsplatformicon.cpp \ + $$PWD/qquicklabsplatformiconloader.cpp \ + $$PWD/qquicklabsplatformmenu.cpp \ + $$PWD/qquicklabsplatformmenubar.cpp \ + $$PWD/qquicklabsplatformmenuitem.cpp \ + $$PWD/qquicklabsplatformmenuitemgroup.cpp \ + $$PWD/qquicklabsplatformmenuseparator.cpp \ + $$PWD/qquicklabsplatformmessagedialog.cpp \ + $$PWD/qquicklabsplatformstandardpaths.cpp + + +qtConfig(systemtrayicon) { + HEADERS += \ + $$PWD/qquicklabsplatformsystemtrayicon_p.h + SOURCES += \ + $$PWD/qquicklabsplatformsystemtrayicon.cpp +} diff --git a/src/labs/platform/qquicklabsplatformcolordialog.cpp b/src/labs/platform/qquicklabsplatformcolordialog.cpp new file mode 100644 index 00000000000..b6177cdf684 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformcolordialog.cpp @@ -0,0 +1,208 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformcolordialog_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ColorDialog + \inherits Dialog +//! \instantiates QQuickLabsPlatformColorDialog + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief A native color dialog. + + The ColorDialog type provides a QML API for native platform color dialogs. + + \image qtlabsplatform-colordialog-gtk.png + + To show a color dialog, construct an instance of ColorDialog, set the + desired properties, and call \l {Dialog::}{open()}. The \l currentColor + property can be used to determine the currently selected color in the + dialog. The \l color property is updated only after the final selection + has been made by accepting the dialog. + + \code + MenuItem { + text: "Color" + onTriggered: colorDialog.open() + } + + ColorDialog { + id: colorDialog + currentColor: document.color + } + + MyDocument { + id: document + color: colorDialog.color + } + \endcode + + \section2 Availability + + A native platform color dialog is currently available on the following platforms: + + \list + \li macOS + \li Linux (when running with the GTK+ platform theme) + \endlist + + \input includes/widgets.qdocinc 1 + + \labs +*/ + +QQuickLabsPlatformColorDialog::QQuickLabsPlatformColorDialog(QObject *parent) + : QQuickLabsPlatformDialog(QPlatformTheme::ColorDialog, parent), + m_options(QColorDialogOptions::create()) +{ +} + +/*! + \qmlproperty color Qt.labs.platform::ColorDialog::color + + This property holds the final accepted color. + + Unlike the \l currentColor property, the \c color property is not updated + while the user is selecting colors in the dialog, but only after the final + selection has been made. That is, when the user has clicked \uicontrol OK + to accept a color. Alternatively, the \l {Dialog::}{accepted()} signal + can be handled to get the final selection. + + \sa currentColor, {Dialog::}{accepted()} +*/ +QColor QQuickLabsPlatformColorDialog::color() const +{ + return m_color; +} + +void QQuickLabsPlatformColorDialog::setColor(const QColor &color) +{ + if (m_color == color) + return; + + m_color = color; + setCurrentColor(color); + emit colorChanged(); +} + +/*! + \qmlproperty color Qt.labs.platform::ColorDialog::currentColor + + This property holds the currently selected color in the dialog. + + Unlike the \l color property, the \c currentColor property is updated + while the user is selecting colors in the dialog, even before the final + selection has been made. + + \sa color +*/ +QColor QQuickLabsPlatformColorDialog::currentColor() const +{ + if (QPlatformColorDialogHelper *colorDialog = qobject_cast(handle())) + return colorDialog->currentColor(); + return m_currentColor; +} + +void QQuickLabsPlatformColorDialog::setCurrentColor(const QColor &color) +{ + if (QPlatformColorDialogHelper *colorDialog = qobject_cast(handle())) + colorDialog->setCurrentColor(color); + m_currentColor = color; +} + +/*! + \qmlproperty flags Qt.labs.platform::ColorDialog::options + + This property holds the various options that affect the look and feel of the dialog. + + By default, all options are disabled. + + Options should be set before showing the dialog. Setting them while the dialog is + visible is not guaranteed to have an immediate effect on the dialog (depending on + the option and on the platform). + + Available options: + \value ColorDialog.ShowAlphaChannel Allow the user to select the alpha component of a color. + \value ColorDialog.NoButtons Don't display \uicontrol OK and \uicontrol Cancel buttons (useful for "live dialogs"). +*/ +QColorDialogOptions::ColorDialogOptions QQuickLabsPlatformColorDialog::options() const +{ + return m_options->options(); +} + +void QQuickLabsPlatformColorDialog::setOptions(QColorDialogOptions::ColorDialogOptions options) +{ + if (options == m_options->options()) + return; + + m_options->setOptions(options); + emit optionsChanged(); +} + +bool QQuickLabsPlatformColorDialog::useNativeDialog() const +{ + return QQuickLabsPlatformDialog::useNativeDialog() + && !m_options->testOption(QColorDialogOptions::DontUseNativeDialog); +} + +void QQuickLabsPlatformColorDialog::onCreate(QPlatformDialogHelper *dialog) +{ + if (QPlatformColorDialogHelper *colorDialog = qobject_cast(dialog)) { + connect(colorDialog, &QPlatformColorDialogHelper::currentColorChanged, this, &QQuickLabsPlatformColorDialog::currentColorChanged); + colorDialog->setOptions(m_options); + colorDialog->setCurrentColor(m_currentColor); + } +} + +void QQuickLabsPlatformColorDialog::onShow(QPlatformDialogHelper *dialog) +{ + m_options->setWindowTitle(title()); + if (QPlatformColorDialogHelper *colorDialog = qobject_cast(dialog)) + colorDialog->setOptions(m_options); +} + +void QQuickLabsPlatformColorDialog::accept() +{ + setColor(currentColor()); + QQuickLabsPlatformDialog::accept(); +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformcolordialog_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformcolordialog_p.h b/src/labs/platform/qquicklabsplatformcolordialog_p.h new file mode 100644 index 00000000000..7eef090ffca --- /dev/null +++ b/src/labs/platform/qquicklabsplatformcolordialog_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMCOLORDIALOG_P_H +#define QQUICKLABSPLATFORMCOLORDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquicklabsplatformdialog_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +class QQuickLabsPlatformColorDialog : public QQuickLabsPlatformDialog +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL) + Q_PROPERTY(QColor currentColor READ currentColor WRITE setCurrentColor NOTIFY currentColorChanged FINAL) + Q_PROPERTY(QColorDialogOptions::ColorDialogOptions options READ options WRITE setOptions NOTIFY optionsChanged FINAL) + Q_FLAGS(QColorDialogOptions::ColorDialogOptions) + +public: + explicit QQuickLabsPlatformColorDialog(QObject *parent = nullptr); + + QColor color() const; + void setColor(const QColor &color); + + QColor currentColor() const; + void setCurrentColor(const QColor &color); + + QColorDialogOptions::ColorDialogOptions options() const; + void setOptions(QColorDialogOptions::ColorDialogOptions options); + +Q_SIGNALS: + void colorChanged(); + void currentColorChanged(); + void optionsChanged(); + +protected: + bool useNativeDialog() const override; + void onCreate(QPlatformDialogHelper *dialog) override; + void onShow(QPlatformDialogHelper *dialog) override; + void accept() override; + +private: + QColor m_color; + QColor m_currentColor; // TODO: QColorDialogOptions::initialColor + QSharedPointer m_options; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformColorDialog) + +#endif // QQUICKLABSPLATFORMCOLORDIALOG_P_H diff --git a/src/labs/platform/qquicklabsplatformdialog.cpp b/src/labs/platform/qquicklabsplatformdialog.cpp new file mode 100644 index 00000000000..a05129e5aa1 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformdialog.cpp @@ -0,0 +1,411 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformdialog_p.h" + +#include +#include +#include +#include + +#include "widgets/qwidgetplatform_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Dialog + \inherits QtObject +//! \instantiates QQuickLabsPlatformDialog + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief The base class of native dialogs. + + The Dialog type provides common QML API for native platform dialogs. + + To show a native dialog, construct an instance of one of the concrete + Dialog implementations, set the desired properties, and call \l open(). + Dialog emits \l accepted() or \l rejected() when the user is done with + the dialog. + + \labs +*/ + +/*! + \qmlsignal void Qt.labs.platform::Dialog::accepted() + + This signal is emitted when the dialog has been accepted either + interactively or by calling \l accept(). + + \note This signal is \e not emitted when closing the dialog with \l close(). + + \sa rejected() +*/ + +/*! + \qmlsignal void Qt.labs.platform::Dialog::rejected() + + This signal is emitted when the dialog has been rejected either + interactively or by calling \l reject(). + + \note This signal is \e not emitted when closing the dialog with \l close(). + + \sa accepted() +*/ + +Q_DECLARE_LOGGING_CATEGORY(qtLabsPlatformDialogs) + +QQuickLabsPlatformDialog::QQuickLabsPlatformDialog(QPlatformTheme::DialogType type, QObject *parent) + : QObject(parent), + m_visible(false), + m_complete(false), + m_result(0), + m_parentWindow(nullptr), + m_flags(Qt::Dialog), + m_modality(Qt::WindowModal), + m_type(type), + m_handle(nullptr) +{ +} + +QQuickLabsPlatformDialog::~QQuickLabsPlatformDialog() +{ + destroy(); +} + +QPlatformDialogHelper *QQuickLabsPlatformDialog::handle() const +{ + return m_handle; +} + +/*! + \qmldefault + \qmlproperty list Qt.labs.platform::Dialog::data + + This default property holds the list of all objects declared as children of + the dialog. +*/ +QQmlListProperty QQuickLabsPlatformDialog::data() +{ + return QQmlListProperty(this, &m_data); +} + +/*! + \qmlproperty Window Qt.labs.platform::Dialog::parentWindow + + This property holds the parent window of the dialog. + + Unless explicitly set, the window is automatically resolved by iterating + the QML parent objects until a \l Window or an \l Item that has a window + is found. +*/ +QWindow *QQuickLabsPlatformDialog::parentWindow() const +{ + return m_parentWindow; +} + +void QQuickLabsPlatformDialog::setParentWindow(QWindow *window) +{ + if (m_parentWindow == window) + return; + + m_parentWindow = window; + emit parentWindowChanged(); +} + +/*! + \qmlproperty string Qt.labs.platform::Dialog::title + + This property holds the title of the dialog. +*/ +QString QQuickLabsPlatformDialog::title() const +{ + return m_title; +} + +void QQuickLabsPlatformDialog::setTitle(const QString &title) +{ + if (m_title == title) + return; + + m_title = title; + emit titleChanged(); +} + +/*! + \qmlproperty Qt::WindowFlags Qt.labs.platform::Dialog::flags + + This property holds the window flags of the dialog. The default value is \c Qt.Dialog. +*/ +Qt::WindowFlags QQuickLabsPlatformDialog::flags() const +{ + return m_flags; +} + +void QQuickLabsPlatformDialog::setFlags(Qt::WindowFlags flags) +{ + if (m_flags == flags) + return; + + m_flags = flags; + emit flagsChanged(); +} + +/*! + \qmlproperty Qt::WindowModality Qt.labs.platform::Dialog::modality + + This property holds the modality of the dialog. The default value is \c Qt.WindowModal. + + Available values: + \value Qt.NonModal The dialog is not modal and does not block input to other windows. + \value Qt.WindowModal The dialog is modal to a single window hierarchy and blocks input to its parent window, all grandparent windows, and all siblings of its parent and grandparent windows. + \value Qt.ApplicationModal The dialog is modal to the application and blocks input to all windows. +*/ +Qt::WindowModality QQuickLabsPlatformDialog::modality() const +{ + return m_modality; +} + +void QQuickLabsPlatformDialog::setModality(Qt::WindowModality modality) +{ + if (m_modality == modality) + return; + + m_modality = modality; + emit modalityChanged(); +} + +/*! + \qmlproperty bool Qt.labs.platform::Dialog::visible + + This property holds the visibility of the dialog. The default value is \c false. + + \sa open(), close() +*/ +bool QQuickLabsPlatformDialog::isVisible() const +{ + return m_handle && m_visible; +} + +void QQuickLabsPlatformDialog::setVisible(bool visible) +{ + if (visible) + open(); + else + close(); +} + +/*! + \qmlproperty int Qt.labs.platform::Dialog::result + + This property holds the result code. + + Standard result codes: + \value Dialog.Accepted + \value Dialog.Rejected + + \note MessageDialog sets the result to the value of the clicked standard + button instead of using the standard result codes. +*/ +int QQuickLabsPlatformDialog::result() const +{ + return m_result; +} + +void QQuickLabsPlatformDialog::setResult(int result) +{ + if (m_result == result) + return; + + m_result = result; + emit resultChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::Dialog::open() + + Opens the dialog. + + \sa visible, close() +*/ +void QQuickLabsPlatformDialog::open() +{ + if (m_visible || !create()) + return; + + onShow(m_handle); + m_visible = m_handle->show(m_flags, m_modality, m_parentWindow); + if (m_visible) + emit visibleChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::Dialog::close() + + Closes the dialog. + + \sa visible, open() +*/ +void QQuickLabsPlatformDialog::close() +{ + if (!m_handle || !m_visible) + return; + + onHide(m_handle); + m_handle->hide(); + m_visible = false; + emit visibleChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::Dialog::accept() + + Closes the dialog and emits the \l accepted() signal. + + \sa reject() +*/ +void QQuickLabsPlatformDialog::accept() +{ + done(Accepted); +} + +/*! + \qmlmethod void Qt.labs.platform::Dialog::reject() + + Closes the dialog and emits the \l rejected() signal. + + \sa accept() +*/ +void QQuickLabsPlatformDialog::reject() +{ + done(Rejected); +} + +/*! + \qmlmethod void Qt.labs.platform::Dialog::done(int result) + + Closes the dialog and sets the \a result. + + \sa accept(), reject(), result +*/ +void QQuickLabsPlatformDialog::done(int result) +{ + close(); + setResult(result); + + if (result == Accepted) + emit accepted(); + else if (result == Rejected) + emit rejected(); +} + +void QQuickLabsPlatformDialog::classBegin() +{ +} + +void QQuickLabsPlatformDialog::componentComplete() +{ + m_complete = true; + if (!m_parentWindow) + setParentWindow(findParentWindow()); +} + +static const char *qmlTypeName(const QObject *object) +{ + return object->metaObject()->className() + qstrlen("QQuickLabsPlatform"); +} + +bool QQuickLabsPlatformDialog::create() +{ + if (!m_handle) { + if (useNativeDialog()) + m_handle = QGuiApplicationPrivate::platformTheme()->createPlatformDialogHelper(m_type); + if (!m_handle) + m_handle = QWidgetPlatform::createDialog(m_type, this); + qCDebug(qtLabsPlatformDialogs) << qmlTypeName(this) << "->" << m_handle; + if (m_handle) { + onCreate(m_handle); + connect(m_handle, &QPlatformDialogHelper::accept, this, &QQuickLabsPlatformDialog::accept); + connect(m_handle, &QPlatformDialogHelper::reject, this, &QQuickLabsPlatformDialog::reject); + } + } + return m_handle; +} + +void QQuickLabsPlatformDialog::destroy() +{ + delete m_handle; + m_handle = nullptr; +} + +bool QQuickLabsPlatformDialog::useNativeDialog() const +{ + return !QCoreApplication::testAttribute(Qt::AA_DontUseNativeDialogs) + && QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(m_type); +} + +void QQuickLabsPlatformDialog::onCreate(QPlatformDialogHelper *dialog) +{ + Q_UNUSED(dialog); +} + +void QQuickLabsPlatformDialog::onShow(QPlatformDialogHelper *dialog) +{ + Q_UNUSED(dialog); +} + +void QQuickLabsPlatformDialog::onHide(QPlatformDialogHelper *dialog) +{ + Q_UNUSED(dialog); +} + +QWindow *QQuickLabsPlatformDialog::findParentWindow() const +{ + QObject *obj = parent(); + while (obj) { + QWindow *window = qobject_cast(obj); + if (window) + return window; + QQuickItem *item = qobject_cast(obj); + if (item && item->window()) + return item->window(); + obj = obj->parent(); + } + return nullptr; +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformdialog_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformdialog_p.h b/src/labs/platform/qquicklabsplatformdialog_p.h new file mode 100644 index 00000000000..802a8461061 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformdialog_p.h @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMDIALOG_P_H +#define QQUICKLABSPLATFORMDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QWindow; +class QPlatformDialogHelper; + +class QQuickLabsPlatformDialog : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + Q_PROPERTY(QQmlListProperty data READ data FINAL) + Q_PROPERTY(QWindow *parentWindow READ parentWindow WRITE setParentWindow NOTIFY parentWindowChanged FINAL) + Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL) + Q_PROPERTY(Qt::WindowFlags flags READ flags WRITE setFlags NOTIFY flagsChanged FINAL) + Q_PROPERTY(Qt::WindowModality modality READ modality WRITE setModality NOTIFY modalityChanged FINAL) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL) + Q_PROPERTY(int result READ result WRITE setResult NOTIFY resultChanged FINAL) + Q_CLASSINFO("DefaultProperty", "data") + +public: + explicit QQuickLabsPlatformDialog(QPlatformTheme::DialogType type, QObject *parent = nullptr); + ~QQuickLabsPlatformDialog(); + + QPlatformDialogHelper *handle() const; + + QQmlListProperty data(); + + QWindow *parentWindow() const; + void setParentWindow(QWindow *window); + + QString title() const; + void setTitle(const QString &title); + + Qt::WindowFlags flags() const; + void setFlags(Qt::WindowFlags flags); + + Qt::WindowModality modality() const; + void setModality(Qt::WindowModality modality); + + bool isVisible() const; + void setVisible(bool visible); + + enum StandardCode { Rejected, Accepted }; + Q_ENUM(StandardCode) + + int result() const; + void setResult(int result); + +public Q_SLOTS: + void open(); + void close(); + virtual void accept(); + virtual void reject(); + virtual void done(int result); + +Q_SIGNALS: + void accepted(); + void rejected(); + void parentWindowChanged(); + void titleChanged(); + void flagsChanged(); + void modalityChanged(); + void visibleChanged(); + void resultChanged(); + +protected: + void classBegin() override; + void componentComplete() override; + + bool create(); + void destroy(); + + virtual bool useNativeDialog() const; + virtual void onCreate(QPlatformDialogHelper *dialog); + virtual void onShow(QPlatformDialogHelper *dialog); + virtual void onHide(QPlatformDialogHelper *dialog); + + QWindow *findParentWindow() const; + +private: + bool m_visible; + bool m_complete; + int m_result; + QWindow *m_parentWindow; + QString m_title; + Qt::WindowFlags m_flags; + Qt::WindowModality m_modality; + QPlatformTheme::DialogType m_type; + QList m_data; + QPlatformDialogHelper *m_handle; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformDialog) + +#endif // QQUICKLABSPLATFORMDIALOG_P_H diff --git a/src/labs/platform/qquicklabsplatformfiledialog.cpp b/src/labs/platform/qquicklabsplatformfiledialog.cpp new file mode 100644 index 00000000000..82da455ef46 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformfiledialog.cpp @@ -0,0 +1,669 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformfiledialog_p.h" + +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmltype FileDialog + \inherits Dialog +//! \instantiates QQuickLabsPlatformFileDialog + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief A native file dialog. + + The FileDialog type provides a QML API for native platform file dialogs. + + \image qtlabsplatform-filedialog-gtk.png + + To show a file dialog, construct an instance of FileDialog, set the + desired properties, and call \l {Dialog::}{open()}. The \l currentFile + or \l currentFiles properties can be used to determine the currently + selected file(s) in the dialog. The \l file and \l files properties + are updated only after the final selection has been made by accepting + the dialog. + + \code + MenuItem { + text: "Open..." + onTriggered: fileDialog.open() + } + + FileDialog { + id: fileDialog + currentFile: document.source + folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) + } + + MyDocument { + id: document + source: fileDialog.file + } + \endcode + + \section2 Availability + + A native platform file dialog is currently available on the following platforms: + + \list + \li iOS + \li Linux (when running with the GTK+ platform theme) + \li macOS + \li Windows + \endlist + + \input includes/widgets.qdocinc 1 + + \labs + + \sa FolderDialog, StandardPaths +*/ + +QQuickLabsPlatformFileDialog::QQuickLabsPlatformFileDialog(QObject *parent) + : QQuickLabsPlatformDialog(QPlatformTheme::FileDialog, parent), + m_fileMode(OpenFile), + m_options(QFileDialogOptions::create()), + m_selectedNameFilter(nullptr) +{ + m_options->setFileMode(QFileDialogOptions::ExistingFile); + m_options->setAcceptMode(QFileDialogOptions::AcceptOpen); +} + +/*! + \qmlproperty enumeration Qt.labs.platform::FileDialog::fileMode + + This property holds the mode of the dialog. + + Available values: + \value FileDialog.OpenFile The dialog is used to select an existing file (default). + \value FileDialog.OpenFiles The dialog is used to select multiple existing files. + \value FileDialog.SaveFile The dialog is used to select any file. The file does not have to exist. +*/ +QQuickLabsPlatformFileDialog::FileMode QQuickLabsPlatformFileDialog::fileMode() const +{ + return m_fileMode; +} + +void QQuickLabsPlatformFileDialog::setFileMode(FileMode mode) +{ + if (mode == m_fileMode) + return; + + switch (mode) { + case OpenFile: + m_options->setFileMode(QFileDialogOptions::ExistingFile); + m_options->setAcceptMode(QFileDialogOptions::AcceptOpen); + break; + case OpenFiles: + m_options->setFileMode(QFileDialogOptions::ExistingFiles); + m_options->setAcceptMode(QFileDialogOptions::AcceptOpen); + break; + case SaveFile: + m_options->setFileMode(QFileDialogOptions::AnyFile); + m_options->setAcceptMode(QFileDialogOptions::AcceptSave); + break; + default: + break; + } + + m_fileMode = mode; + emit fileModeChanged(); +} + +/*! + \qmlproperty url Qt.labs.platform::FileDialog::file + + This property holds the final accepted file. + + Unlike the \l currentFile property, the \c file property is not updated + while the user is selecting files in the dialog, but only after the final + selection has been made. That is, when the user has clicked \uicontrol OK + to accept a file. Alternatively, the \l {Dialog::}{accepted()} signal + can be handled to get the final selection. + + \sa currentFile, {Dialog::}{accepted()} +*/ +QUrl QQuickLabsPlatformFileDialog::file() const +{ + return addDefaultSuffix(m_files.value(0)); +} + +void QQuickLabsPlatformFileDialog::setFile(const QUrl &file) +{ + setFiles(QList() << file); +} + +/*! + \qmlproperty list Qt.labs.platform::FileDialog::files + + This property holds the final accepted files. + + Unlike the \l currentFiles property, the \c files property is not updated + while the user is selecting files in the dialog, but only after the final + selection has been made. That is, when the user has clicked \uicontrol OK + to accept files. Alternatively, the \l {Dialog::}{accepted()} signal + can be handled to get the final selection. + + \sa currentFiles, {Dialog::}{accepted()} +*/ +QList QQuickLabsPlatformFileDialog::files() const +{ + return addDefaultSuffixes(m_files); +} + +void QQuickLabsPlatformFileDialog::setFiles(const QList &files) +{ + if (m_files == files) + return; + + bool firstChanged = m_files.value(0) != files.value(0); + m_files = files; + if (firstChanged) + emit fileChanged(); + emit filesChanged(); +} + +/*! + \qmlproperty url Qt.labs.platform::FileDialog::currentFile + + This property holds the currently selected file in the dialog. + + Unlike the \l file property, the \c currentFile property is updated + while the user is selecting files in the dialog, even before the final + selection has been made. + + \sa file, currentFiles +*/ +QUrl QQuickLabsPlatformFileDialog::currentFile() const +{ + return currentFiles().value(0); +} + +void QQuickLabsPlatformFileDialog::setCurrentFile(const QUrl &file) +{ + setCurrentFiles(QList() << file); +} + +/*! + \qmlproperty list Qt.labs.platform::FileDialog::currentFiles + + This property holds the currently selected files in the dialog. + + Unlike the \l files property, the \c currentFiles property is updated + while the user is selecting files in the dialog, even before the final + selection has been made. + + \sa files, currentFile +*/ +QList QQuickLabsPlatformFileDialog::currentFiles() const +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast(handle())) + return fileDialog->selectedFiles(); + return m_options->initiallySelectedFiles(); +} + +void QQuickLabsPlatformFileDialog::setCurrentFiles(const QList &files) +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast(handle())) { + for (const QUrl &file : files) + fileDialog->selectFile(file); + } + m_options->setInitiallySelectedFiles(files); +} + +/*! + \qmlproperty url Qt.labs.platform::FileDialog::folder + + This property holds the folder where files are selected. + For selecting a folder, use FolderDialog instead. + + \sa FolderDialog +*/ +QUrl QQuickLabsPlatformFileDialog::folder() const +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast(handle())) + return fileDialog->directory(); + return m_options->initialDirectory(); +} + +void QQuickLabsPlatformFileDialog::setFolder(const QUrl &folder) +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast(handle())) + fileDialog->setDirectory(folder); + m_options->setInitialDirectory(folder); +} + +/*! + \qmlproperty flags Qt.labs.platform::FileDialog::options + + This property holds the various options that affect the look and feel of the dialog. + + By default, all options are disabled. + + Options should be set before showing the dialog. Setting them while the dialog is + visible is not guaranteed to have an immediate effect on the dialog (depending on + the option and on the platform). + + Available options: + \value FileDialog.DontResolveSymlinks Don't resolve symlinks in the file dialog. By default symlinks are resolved. + \value FileDialog.DontConfirmOverwrite Don't ask for confirmation if an existing file is selected. By default confirmation is requested. + \value FileDialog.ReadOnly Indicates that the dialog doesn't allow creating directories. + \value FileDialog.HideNameFilterDetails Indicates if the file name filter details are hidden or not. +*/ +QFileDialogOptions::FileDialogOptions QQuickLabsPlatformFileDialog::options() const +{ + return m_options->options(); +} + +void QQuickLabsPlatformFileDialog::setOptions(QFileDialogOptions::FileDialogOptions options) +{ + if (options == m_options->options()) + return; + + m_options->setOptions(options); + emit optionsChanged(); +} + +void QQuickLabsPlatformFileDialog::resetOptions() +{ + setOptions({}); +} + +/*! + \qmlproperty list Qt.labs.platform::FileDialog::nameFilters + + This property holds the filters that restrict the types of files that + can be selected. + + \code + FileDialog { + nameFilters: ["Text files (*.txt)", "HTML files (*.html *.htm)"] + } + \endcode + + \note \b{*.*} is not a portable filter, because the historical assumption + that the file extension determines the file type is not consistent on every + operating system. It is possible to have a file with no dot in its name (for + example, \c Makefile). In a native Windows file dialog, \b{*.*} will match + such files, while in other types of file dialogs it may not. So it is better + to use \b{*} if you mean to select any file. + + \sa selectedNameFilter +*/ +QStringList QQuickLabsPlatformFileDialog::nameFilters() const +{ + return m_options->nameFilters(); +} + +void QQuickLabsPlatformFileDialog::setNameFilters(const QStringList &filters) +{ + if (filters == m_options->nameFilters()) + return; + + m_options->setNameFilters(filters); + if (m_selectedNameFilter) { + int index = m_selectedNameFilter->index(); + if (index < 0 || index >= filters.count()) + index = 0; + m_selectedNameFilter->update(filters.value(index)); + } + emit nameFiltersChanged(); +} + +void QQuickLabsPlatformFileDialog::resetNameFilters() +{ + setNameFilters(QStringList()); +} + +/*! + \qmlproperty int Qt.labs.platform::FileDialog::selectedNameFilter.index + \qmlproperty string Qt.labs.platform::FileDialog::selectedNameFilter.name + \qmlproperty list Qt.labs.platform::FileDialog::selectedNameFilter.extensions + + These properties hold the currently selected name filter. + + \table + \header + \li Name + \li Description + \row + \li \b index : int + \li This property determines which \l {nameFilters}{name filter} is selected. + The specified filter is selected when the dialog is opened. The value is + updated when the user selects another filter. + \row + \li [read-only] \b name : string + \li This property holds the name of the selected filter. In the + example below, the name of the first filter is \c {"Text files"} + and the second is \c {"HTML files"}. + \row + \li [read-only] \b extensions : list + \li This property holds the list of extensions of the selected filter. + In the example below, the list of extensions of the first filter is + \c {["txt"]} and the second is \c {["html", "htm"]}. + \endtable + + \code + FileDialog { + id: fileDialog + selectedNameFilter.index: 1 + nameFilters: ["Text files (*.txt)", "HTML files (*.html *.htm)"] + } + + MyDocument { + id: document + fileType: fileDialog.selectedNameFilter.extensions[0] + } + \endcode + + \sa nameFilters +*/ +QQuickLabsPlatformFileNameFilter *QQuickLabsPlatformFileDialog::selectedNameFilter() const +{ + if (!m_selectedNameFilter) { + QQuickLabsPlatformFileDialog *that = const_cast(this); + m_selectedNameFilter = new QQuickLabsPlatformFileNameFilter(that); + m_selectedNameFilter->setOptions(m_options); + } + return m_selectedNameFilter; +} + +/*! + \qmlproperty string Qt.labs.platform::FileDialog::defaultSuffix + + This property holds a suffix that is added to selected files that have + no suffix specified. The suffix is typically used to indicate the file + type (e.g. "txt" indicates a text file). + + If the first character is a dot ('.'), it is removed. +*/ +QString QQuickLabsPlatformFileDialog::defaultSuffix() const +{ + return m_options->defaultSuffix(); +} + +void QQuickLabsPlatformFileDialog::setDefaultSuffix(const QString &suffix) +{ + if (suffix == m_options->defaultSuffix()) + return; + + m_options->setDefaultSuffix(suffix); + emit defaultSuffixChanged(); +} + +void QQuickLabsPlatformFileDialog::resetDefaultSuffix() +{ + setDefaultSuffix(QString()); +} + +/*! + \qmlproperty string Qt.labs.platform::FileDialog::acceptLabel + + This property holds the label text shown on the button that accepts the dialog. + + When set to an empty string, the default label of the underlying platform is used. + The default label is typically \uicontrol Open or \uicontrol Save depending on which + \l fileMode the dialog is used in. + + The default value is an empty string. + + \sa rejectLabel +*/ +QString QQuickLabsPlatformFileDialog::acceptLabel() const +{ + return m_options->labelText(QFileDialogOptions::Accept); +} + +void QQuickLabsPlatformFileDialog::setAcceptLabel(const QString &label) +{ + if (label == m_options->labelText(QFileDialogOptions::Accept)) + return; + + m_options->setLabelText(QFileDialogOptions::Accept, label); + emit acceptLabelChanged(); +} + +void QQuickLabsPlatformFileDialog::resetAcceptLabel() +{ + setAcceptLabel(QString()); +} + +/*! + \qmlproperty string Qt.labs.platform::FileDialog::rejectLabel + + This property holds the label text shown on the button that rejects the dialog. + + When set to an empty string, the default label of the underlying platform is used. + The default label is typically \uicontrol Cancel. + + The default value is an empty string. + + \sa acceptLabel +*/ +QString QQuickLabsPlatformFileDialog::rejectLabel() const +{ + return m_options->labelText(QFileDialogOptions::Reject); +} + +void QQuickLabsPlatformFileDialog::setRejectLabel(const QString &label) +{ + if (label == m_options->labelText(QFileDialogOptions::Reject)) + return; + + m_options->setLabelText(QFileDialogOptions::Reject, label); + emit rejectLabelChanged(); +} + +void QQuickLabsPlatformFileDialog::resetRejectLabel() +{ + setRejectLabel(QString()); +} + +bool QQuickLabsPlatformFileDialog::useNativeDialog() const +{ + return QQuickLabsPlatformDialog::useNativeDialog() + && !m_options->testOption(QFileDialogOptions::DontUseNativeDialog); +} + +void QQuickLabsPlatformFileDialog::onCreate(QPlatformDialogHelper *dialog) +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast(dialog)) { + // TODO: emit currentFileChanged only when the first entry in currentFiles changes + connect(fileDialog, &QPlatformFileDialogHelper::currentChanged, this, &QQuickLabsPlatformFileDialog::currentFileChanged); + connect(fileDialog, &QPlatformFileDialogHelper::currentChanged, this, &QQuickLabsPlatformFileDialog::currentFilesChanged); + connect(fileDialog, &QPlatformFileDialogHelper::directoryEntered, this, &QQuickLabsPlatformFileDialog::folderChanged); + fileDialog->setOptions(m_options); + } +} + +void QQuickLabsPlatformFileDialog::onShow(QPlatformDialogHelper *dialog) +{ + m_options->setWindowTitle(title()); + if (QPlatformFileDialogHelper *fileDialog = qobject_cast(dialog)) { + fileDialog->setOptions(m_options); // setOptions only assigns a member and isn't virtual + if (m_firstShow && m_options->initialDirectory().isValid()) + fileDialog->setDirectory(m_options->initialDirectory()); + if (m_selectedNameFilter) { + const int index = m_selectedNameFilter->index(); + const QString filter = m_options->nameFilters().value(index); + m_options->setInitiallySelectedNameFilter(filter); + fileDialog->selectNameFilter(filter); + connect(fileDialog, &QPlatformFileDialogHelper::filterSelected, m_selectedNameFilter, &QQuickLabsPlatformFileNameFilter::update); + } + } + if (m_firstShow) + m_firstShow = false; +} + +void QQuickLabsPlatformFileDialog::onHide(QPlatformDialogHelper *dialog) +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast(dialog)) { + if (m_selectedNameFilter) + disconnect(fileDialog, &QPlatformFileDialogHelper::filterSelected, m_selectedNameFilter, &QQuickLabsPlatformFileNameFilter::update); + } +} + +void QQuickLabsPlatformFileDialog::accept() +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast(handle())) + setFiles(fileDialog->selectedFiles()); + QQuickLabsPlatformDialog::accept(); +} + +QUrl QQuickLabsPlatformFileDialog::addDefaultSuffix(const QUrl &file) const +{ + QUrl url = file; + const QString path = url.path(); + const QString suffix = m_options->defaultSuffix(); + // Urls with "content" scheme do not require suffixes. Such schemes are + // used on Android. + const bool isContentScheme = url.scheme() == u"content"_qs; + if (!isContentScheme && !suffix.isEmpty() && !path.endsWith(QLatin1Char('/')) + && path.lastIndexOf(QLatin1Char('.')) == -1) { + url.setPath(path + QLatin1Char('.') + suffix); + } + return url; +} + +QList QQuickLabsPlatformFileDialog::addDefaultSuffixes(const QList &files) const +{ + QList urls; + urls.reserve(files.size()); + for (const QUrl &file : files) + urls += addDefaultSuffix(file); + return urls; +} + +QQuickLabsPlatformFileNameFilter::QQuickLabsPlatformFileNameFilter(QObject *parent) + : QObject(parent), m_index(-1) +{ +} + +int QQuickLabsPlatformFileNameFilter::index() const +{ + return m_index; +} + +void QQuickLabsPlatformFileNameFilter::setIndex(int index) +{ + if (m_index == index) + return; + + m_index = index; + emit indexChanged(index); +} + +QString QQuickLabsPlatformFileNameFilter::name() const +{ + return m_name; +} + +QStringList QQuickLabsPlatformFileNameFilter::extensions() const +{ + return m_extensions; +} + +QSharedPointer QQuickLabsPlatformFileNameFilter::options() const +{ + return m_options; +} + +void QQuickLabsPlatformFileNameFilter::setOptions(const QSharedPointer &options) +{ + m_options = options; +} + +static QString extractName(const QString &filter) +{ + return filter.left(filter.indexOf(QLatin1Char('(')) - 1); +} + +static QString extractExtension(QStringView filter) +{ + return filter.mid(filter.indexOf(QLatin1Char('.')) + 1).toString(); +} + +static QStringList extractExtensions(QStringView filter) +{ + QStringList extensions; + const int from = filter.indexOf(QLatin1Char('(')); + const int to = filter.lastIndexOf(QLatin1Char(')')) - 1; + if (from >= 0 && from < to) { + const QStringView ref = filter.mid(from + 1, to - from); + const QList exts = ref.split(QLatin1Char(' '), Qt::SkipEmptyParts); + for (const QStringView &ref : exts) + extensions += extractExtension(ref); + } + + return extensions; +} + +void QQuickLabsPlatformFileNameFilter::update(const QString &filter) +{ + const QStringList filters = nameFilters(); + + const int oldIndex = m_index; + const QString oldName = m_name; + const QStringList oldExtensions = m_extensions; + + m_index = filters.indexOf(filter); + m_name = extractName(filter); + m_extensions = extractExtensions(filter); + + if (oldIndex != m_index) + emit indexChanged(m_index); + if (oldName != m_name) + emit nameChanged(m_name); + if (oldExtensions != m_extensions) + emit extensionsChanged(m_extensions); +} + +QStringList QQuickLabsPlatformFileNameFilter::nameFilters() const +{ + return m_options ? m_options->nameFilters() : QStringList(); +} + +QString QQuickLabsPlatformFileNameFilter::nameFilter(int index) const +{ + return m_options ? m_options->nameFilters().value(index) : QString(); +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformfiledialog_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformfiledialog_p.h b/src/labs/platform/qquicklabsplatformfiledialog_p.h new file mode 100644 index 00000000000..782b5980477 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformfiledialog_p.h @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMFILEDIALOG_P_H +#define QQUICKLABSPLATFORMFILEDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquicklabsplatformdialog_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +class QQuickLabsPlatformFileNameFilter; + +class QQuickLabsPlatformFileDialog : public QQuickLabsPlatformDialog +{ + Q_OBJECT + Q_PROPERTY(FileMode fileMode READ fileMode WRITE setFileMode NOTIFY fileModeChanged FINAL) + Q_PROPERTY(QUrl file READ file WRITE setFile NOTIFY fileChanged FINAL) + Q_PROPERTY(QList files READ files WRITE setFiles NOTIFY filesChanged FINAL) + Q_PROPERTY(QUrl currentFile READ currentFile WRITE setCurrentFile NOTIFY currentFileChanged FINAL) + Q_PROPERTY(QList currentFiles READ currentFiles WRITE setCurrentFiles NOTIFY currentFilesChanged FINAL) + Q_PROPERTY(QUrl folder READ folder WRITE setFolder NOTIFY folderChanged FINAL) + Q_PROPERTY(QFileDialogOptions::FileDialogOptions options READ options WRITE setOptions RESET resetOptions NOTIFY optionsChanged FINAL) + Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters RESET resetNameFilters NOTIFY nameFiltersChanged FINAL) + Q_PROPERTY(QQuickLabsPlatformFileNameFilter *selectedNameFilter READ selectedNameFilter CONSTANT) + Q_PROPERTY(QString defaultSuffix READ defaultSuffix WRITE setDefaultSuffix RESET resetDefaultSuffix NOTIFY defaultSuffixChanged FINAL) + Q_PROPERTY(QString acceptLabel READ acceptLabel WRITE setAcceptLabel RESET resetAcceptLabel NOTIFY acceptLabelChanged FINAL) + Q_PROPERTY(QString rejectLabel READ rejectLabel WRITE setRejectLabel RESET resetRejectLabel NOTIFY rejectLabelChanged FINAL) + Q_FLAGS(QFileDialogOptions::FileDialogOptions) + +public: + explicit QQuickLabsPlatformFileDialog(QObject *parent = nullptr); + + enum FileMode { + OpenFile, + OpenFiles, + SaveFile + }; + Q_ENUM(FileMode) + + FileMode fileMode() const; + void setFileMode(FileMode fileMode); + + QUrl file() const; + void setFile(const QUrl &file); + + QList files() const; + void setFiles(const QList &files); + + QUrl currentFile() const; + void setCurrentFile(const QUrl &file); + + QList currentFiles() const; + void setCurrentFiles(const QList &files); + + QUrl folder() const; + void setFolder(const QUrl &folder); + + QFileDialogOptions::FileDialogOptions options() const; + void setOptions(QFileDialogOptions::FileDialogOptions options); + void resetOptions(); + + QStringList nameFilters() const; + void setNameFilters(const QStringList &filters); + void resetNameFilters(); + + QQuickLabsPlatformFileNameFilter *selectedNameFilter() const; + + QString defaultSuffix() const; + void setDefaultSuffix(const QString &suffix); + void resetDefaultSuffix(); + + QString acceptLabel() const; + void setAcceptLabel(const QString &label); + void resetAcceptLabel(); + + QString rejectLabel() const; + void setRejectLabel(const QString &label); + void resetRejectLabel(); + +Q_SIGNALS: + void fileModeChanged(); + void fileChanged(); + void filesChanged(); + void currentFileChanged(); + void currentFilesChanged(); + void folderChanged(); + void optionsChanged(); + void nameFiltersChanged(); + void defaultSuffixChanged(); + void acceptLabelChanged(); + void rejectLabelChanged(); + +protected: + bool useNativeDialog() const override; + void onCreate(QPlatformDialogHelper *dialog) override; + void onShow(QPlatformDialogHelper *dialog) override; + void onHide(QPlatformDialogHelper *dialog) override; + void accept() override; + +private: + QUrl addDefaultSuffix(const QUrl &file) const; + QList addDefaultSuffixes(const QList &files) const; + + FileMode m_fileMode; + QList m_files; + bool m_firstShow = true; + QSharedPointer m_options; + mutable QQuickLabsPlatformFileNameFilter *m_selectedNameFilter; +}; + +class QQuickLabsPlatformFileNameFilter : public QObject +{ + Q_OBJECT + Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged FINAL) + Q_PROPERTY(QString name READ name NOTIFY nameChanged FINAL) + Q_PROPERTY(QStringList extensions READ extensions NOTIFY extensionsChanged FINAL) + +public: + explicit QQuickLabsPlatformFileNameFilter(QObject *parent = nullptr); + + int index() const; + void setIndex(int index); + + QString name() const; + QStringList extensions() const; + + QSharedPointer options() const; + void setOptions(const QSharedPointer &options); + + void update(const QString &filter); + +Q_SIGNALS: + void indexChanged(int index); + void nameChanged(const QString &name); + void extensionsChanged(const QStringList &extensions); + +private: + QStringList nameFilters() const; + QString nameFilter(int index) const; + + int m_index; + QString m_name; + QStringList m_extensions; + QSharedPointer m_options; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformFileDialog) + +#endif // QQUICKLABSPLATFORMFILEDIALOG_P_H diff --git a/src/labs/platform/qquicklabsplatformfolderdialog.cpp b/src/labs/platform/qquicklabsplatformfolderdialog.cpp new file mode 100644 index 00000000000..83e615e5b8a --- /dev/null +++ b/src/labs/platform/qquicklabsplatformfolderdialog.cpp @@ -0,0 +1,285 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformfolderdialog_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype FolderDialog + \inherits Dialog +//! \instantiates QQuickLabsPlatformFolderDialog + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief A native folder dialog. + + The FolderDialog type provides a QML API for native platform folder dialogs. + + \image qtlabsplatform-folderdialog-gtk.png + + To show a folder dialog, construct an instance of FolderDialog, set the + desired properties, and call \l {Dialog::}{open()}. The \l currentFolder + property can be used to determine the currently selected folder in the + dialog. The \l folder property is updated only after the final selection + has been made by accepting the dialog. + + \code + MenuItem { + text: "Open..." + onTriggered: folderDialog.open() + } + + FolderDialog { + id: folderDialog + currentFolder: viewer.folder + folder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0] + } + + MyViewer { + id: viewer + folder: folderDialog.folder + } + \endcode + + \section2 Availability + + A native platform folder dialog is currently available on the following platforms: + + \list + \li iOS + \li Linux (when running with the GTK+ platform theme) + \li macOS + \li Windows + \endlist + + \input includes/widgets.qdocinc 1 + + \labs + + \sa FileDialog, StandardPaths +*/ + +QQuickLabsPlatformFolderDialog::QQuickLabsPlatformFolderDialog(QObject *parent) + : QQuickLabsPlatformDialog(QPlatformTheme::FileDialog, parent), + m_options(QFileDialogOptions::create()) +{ + m_options->setFileMode(QFileDialogOptions::Directory); + m_options->setAcceptMode(QFileDialogOptions::AcceptOpen); +} + +/*! + \qmlproperty url Qt.labs.platform::FolderDialog::folder + + This property holds the final accepted folder. + + Unlike the \l currentFolder property, the \c folder property is not updated + while the user is selecting folders in the dialog, but only after the final + selection has been made. That is, when the user has clicked \uicontrol OK + to accept a folder. Alternatively, the \l {Dialog::}{accepted()} signal + can be handled to get the final selection. + + \sa currentFolder, {Dialog::}{accepted()} +*/ +QUrl QQuickLabsPlatformFolderDialog::folder() const +{ + return m_folder; +} + +void QQuickLabsPlatformFolderDialog::setFolder(const QUrl &folder) +{ + if (m_folder == folder) + return; + + m_folder = folder; + emit folderChanged(); +} + +/*! + \qmlproperty url Qt.labs.platform::FolderDialog::currentFolder + + This property holds the currently selected folder in the dialog. + + Unlike the \l folder property, the \c currentFolder property is updated + while the user is selecting folders in the dialog, even before the final + selection has been made. + + \sa folder +*/ +QUrl QQuickLabsPlatformFolderDialog::currentFolder() const +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast(handle())) { + const QList selectedFiles = fileDialog->selectedFiles(); + if (!selectedFiles.isEmpty()) + return selectedFiles.first(); + return fileDialog->directory(); + } + return m_options->initialDirectory(); +} + +void QQuickLabsPlatformFolderDialog::setCurrentFolder(const QUrl &folder) +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast(handle())) + fileDialog->setDirectory(folder); + m_options->setInitialDirectory(folder); +} + +/*! + \qmlproperty flags Qt.labs.platform::FolderDialog::options + + This property holds the various options that affect the look and feel of the dialog. + + By default, all options are disabled. + + Options should be set before showing the dialog. Setting them while the dialog is + visible is not guaranteed to have an immediate effect on the dialog (depending on + the option and on the platform). + + Available options: + \value FolderDialog.ShowDirsOnly Only show directories in the folder dialog. By default both folders and directories are shown. + \value FolderDialog.DontResolveSymlinks Don't resolve symlinks in the folder dialog. By default symlinks are resolved. + \value FolderDialog.ReadOnly Indicates that the dialog doesn't allow creating directories. +*/ +QFileDialogOptions::FileDialogOptions QQuickLabsPlatformFolderDialog::options() const +{ + return m_options->options(); +} + +void QQuickLabsPlatformFolderDialog::setOptions(QFileDialogOptions::FileDialogOptions options) +{ + if (options == m_options->options()) + return; + + m_options->setOptions(options); + emit optionsChanged(); +} + +void QQuickLabsPlatformFolderDialog::resetOptions() +{ + setOptions({}); +} + +/*! + \qmlproperty string Qt.labs.platform::FolderDialog::acceptLabel + + This property holds the label text shown on the button that accepts the dialog. + + When set to an empty string, the default label of the underlying platform is used. + The default label is typically \uicontrol Open. + + The default value is an empty string. + + \sa rejectLabel +*/ +QString QQuickLabsPlatformFolderDialog::acceptLabel() const +{ + return m_options->labelText(QFileDialogOptions::Accept); +} + +void QQuickLabsPlatformFolderDialog::setAcceptLabel(const QString &label) +{ + if (label == m_options->labelText(QFileDialogOptions::Accept)) + return; + + m_options->setLabelText(QFileDialogOptions::Accept, label); + emit acceptLabelChanged(); +} + +void QQuickLabsPlatformFolderDialog::resetAcceptLabel() +{ + setAcceptLabel(QString()); +} + +/*! + \qmlproperty string Qt.labs.platform::FolderDialog::rejectLabel + + This property holds the label text shown on the button that rejects the dialog. + + When set to an empty string, the default label of the underlying platform is used. + The default label is typically \uicontrol Cancel. + + The default value is an empty string. + + \sa acceptLabel +*/ +QString QQuickLabsPlatformFolderDialog::rejectLabel() const +{ + return m_options->labelText(QFileDialogOptions::Reject); +} + +void QQuickLabsPlatformFolderDialog::setRejectLabel(const QString &label) +{ + if (label == m_options->labelText(QFileDialogOptions::Reject)) + return; + + m_options->setLabelText(QFileDialogOptions::Reject, label); + emit rejectLabelChanged(); +} + +void QQuickLabsPlatformFolderDialog::resetRejectLabel() +{ + setRejectLabel(QString()); +} + +bool QQuickLabsPlatformFolderDialog::useNativeDialog() const +{ + return QQuickLabsPlatformDialog::useNativeDialog() + && !m_options->testOption(QFileDialogOptions::DontUseNativeDialog); +} + +void QQuickLabsPlatformFolderDialog::onCreate(QPlatformDialogHelper *dialog) +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast(dialog)) { + connect(fileDialog, &QPlatformFileDialogHelper::currentChanged, this, &QQuickLabsPlatformFolderDialog::currentFolderChanged); + fileDialog->setOptions(m_options); + } +} + +void QQuickLabsPlatformFolderDialog::onShow(QPlatformDialogHelper *dialog) +{ + m_options->setWindowTitle(title()); + if (QPlatformFileDialogHelper *fileDialog = qobject_cast(dialog)) + fileDialog->setOptions(m_options); +} + +void QQuickLabsPlatformFolderDialog::accept() +{ + setFolder(currentFolder()); + QQuickLabsPlatformDialog::accept(); +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformfolderdialog_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformfolderdialog_p.h b/src/labs/platform/qquicklabsplatformfolderdialog_p.h new file mode 100644 index 00000000000..21ee3c6c43a --- /dev/null +++ b/src/labs/platform/qquicklabsplatformfolderdialog_p.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMFOLDERDIALOG_P_H +#define QQUICKLABSPLATFORMFOLDERDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This folder is not part of the Qt API. It exists purely as an +// implementation detail. This header folder may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquicklabsplatformdialog_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +class QQuickLabsPlatformFolderDialog : public QQuickLabsPlatformDialog +{ + Q_OBJECT + Q_PROPERTY(QUrl folder READ folder WRITE setFolder NOTIFY folderChanged FINAL) + Q_PROPERTY(QUrl currentFolder READ currentFolder WRITE setCurrentFolder NOTIFY currentFolderChanged FINAL) + Q_PROPERTY(QFileDialogOptions::FileDialogOptions options READ options WRITE setOptions RESET resetOptions NOTIFY optionsChanged FINAL) + Q_PROPERTY(QString acceptLabel READ acceptLabel WRITE setAcceptLabel RESET resetAcceptLabel NOTIFY acceptLabelChanged FINAL) + Q_PROPERTY(QString rejectLabel READ rejectLabel WRITE setRejectLabel RESET resetRejectLabel NOTIFY rejectLabelChanged FINAL) + Q_FLAGS(QFileDialogOptions::FileDialogOptions) + +public: + explicit QQuickLabsPlatformFolderDialog(QObject *parent = nullptr); + + QUrl folder() const; + void setFolder(const QUrl &folder); + + QUrl currentFolder() const; + void setCurrentFolder(const QUrl &folder); + + QFileDialogOptions::FileDialogOptions options() const; + void setOptions(QFileDialogOptions::FileDialogOptions options); + void resetOptions(); + + QString acceptLabel() const; + void setAcceptLabel(const QString &label); + void resetAcceptLabel(); + + QString rejectLabel() const; + void setRejectLabel(const QString &label); + void resetRejectLabel(); + +Q_SIGNALS: + void folderChanged(); + void currentFolderChanged(); + void optionsChanged(); + void acceptLabelChanged(); + void rejectLabelChanged(); + +protected: + bool useNativeDialog() const override; + void onCreate(QPlatformDialogHelper *dialog) override; + void onShow(QPlatformDialogHelper *dialog) override; + void accept() override; + +private: + QUrl m_folder; + QSharedPointer m_options; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformFolderDialog) + +#endif // QQUICKLABSPLATFORMFOLDERDIALOG_P_H diff --git a/src/labs/platform/qquicklabsplatformfontdialog.cpp b/src/labs/platform/qquicklabsplatformfontdialog.cpp new file mode 100644 index 00000000000..a473d0f2a8b --- /dev/null +++ b/src/labs/platform/qquicklabsplatformfontdialog.cpp @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformfontdialog_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype FontDialog + \inherits Dialog +//! \instantiates QQuickLabsPlatformFontDialog + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief A native font dialog. + + The FontDialog type provides a QML API for native platform font dialogs. + + \image qtlabsplatform-fontdialog-gtk.png + + To show a font dialog, construct an instance of FontDialog, set the + desired properties, and call \l {Dialog::}{open()}. The \l currentFont + property can be used to determine the currently selected font in the + dialog. The \l font property is updated only after the final selection + has been made by accepting the dialog. + + \code + MenuItem { + text: "Font" + onTriggered: fontDialog.open() + } + + FontDialog { + id: fontDialog + currentFont.family: document.font + } + + MyDocument { + id: document + font: fontDialog.font + } + \endcode + + \section2 Availability + + A native platform font dialog is currently available on the following platforms: + + \list + \li macOS + \li Linux (when running with the GTK+ platform theme) + \endlist + + \input includes/widgets.qdocinc 1 + + \labs +*/ + +QQuickLabsPlatformFontDialog::QQuickLabsPlatformFontDialog(QObject *parent) + : QQuickLabsPlatformDialog(QPlatformTheme::FontDialog, parent), + m_options(QFontDialogOptions::create()) +{ +} + +/*! + \qmlproperty font Qt.labs.platform::FontDialog::font + + This property holds the final accepted font. + + Unlike the \l currentFont property, the \c font property is not updated + while the user is selecting fonts in the dialog, but only after the final + selection has been made. That is, when the user has clicked \uicontrol OK + to accept a font. Alternatively, the \l {Dialog::}{accepted()} signal + can be handled to get the final selection. + + \sa currentFont, {Dialog::}{accepted()} +*/ +QFont QQuickLabsPlatformFontDialog::font() const +{ + return m_font; +} + +void QQuickLabsPlatformFontDialog::setFont(const QFont &font) +{ + if (m_font == font) + return; + + m_font = font; + setCurrentFont(font); + emit fontChanged(); +} + +/*! + \qmlproperty font Qt.labs.platform::FontDialog::currentFont + + This property holds the currently selected font in the dialog. + + Unlike the \l font property, the \c currentFont property is updated + while the user is selecting fonts in the dialog, even before the final + selection has been made. + + \sa font +*/ +QFont QQuickLabsPlatformFontDialog::currentFont() const +{ + if (QPlatformFontDialogHelper *fontDialog = qobject_cast(handle())) + return fontDialog->currentFont(); + return m_currentFont; +} + +void QQuickLabsPlatformFontDialog::setCurrentFont(const QFont &font) +{ + if (QPlatformFontDialogHelper *fontDialog = qobject_cast(handle())) + fontDialog->setCurrentFont(font); + m_currentFont = font; +} + +/*! + \qmlproperty flags Qt.labs.platform::FontDialog::options + + This property holds the various options that affect the look and feel of the dialog. + + By default, all options are disabled. + + Options should be set before showing the dialog. Setting them while the dialog is + visible is not guaranteed to have an immediate effect on the dialog (depending on + the option and on the platform). + + Available options: + \value FontDialog.ScalableFonts Show scalable fonts. + \value FontDialog.NonScalableFonts Show non-scalable fonts. + \value FontDialog.MonospacedFonts Show monospaced fonts. + \value FontDialog.ProportionalFonts Show proportional fonts. + \value FontDialog.NoButtons Don't display \uicontrol OK and \uicontrol Cancel buttons (useful for "live dialogs"). +*/ +QFontDialogOptions::FontDialogOptions QQuickLabsPlatformFontDialog::options() const +{ + return m_options->options(); +} + +void QQuickLabsPlatformFontDialog::setOptions(QFontDialogOptions::FontDialogOptions options) +{ + if (options == m_options->options()) + return; + + m_options->setOptions(options); + emit optionsChanged(); +} + +bool QQuickLabsPlatformFontDialog::useNativeDialog() const +{ + return QQuickLabsPlatformDialog::useNativeDialog() + && !m_options->testOption(QFontDialogOptions::DontUseNativeDialog); +} + +void QQuickLabsPlatformFontDialog::onCreate(QPlatformDialogHelper *dialog) +{ + if (QPlatformFontDialogHelper *fontDialog = qobject_cast(dialog)) { + connect(fontDialog, &QPlatformFontDialogHelper::currentFontChanged, this, &QQuickLabsPlatformFontDialog::currentFontChanged); + fontDialog->setOptions(m_options); + } +} + +void QQuickLabsPlatformFontDialog::onShow(QPlatformDialogHelper *dialog) +{ + m_options->setWindowTitle(title()); + if (QPlatformFontDialogHelper *fontDialog = qobject_cast(dialog)) + fontDialog->setOptions(m_options); +} + +void QQuickLabsPlatformFontDialog::accept() +{ + setFont(currentFont()); + QQuickLabsPlatformDialog::accept(); +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformfontdialog_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformfontdialog_p.h b/src/labs/platform/qquicklabsplatformfontdialog_p.h new file mode 100644 index 00000000000..eb9399d9988 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformfontdialog_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMFONTDIALOG_P_H +#define QQUICKLABSPLATFORMFONTDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquicklabsplatformdialog_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +class QQuickLabsPlatformFontDialog : public QQuickLabsPlatformDialog +{ + Q_OBJECT + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged FINAL) + Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged FINAL) + Q_PROPERTY(QFontDialogOptions::FontDialogOptions options READ options WRITE setOptions NOTIFY optionsChanged FINAL) + Q_FLAGS(QFontDialogOptions::FontDialogOptions) + +public: + explicit QQuickLabsPlatformFontDialog(QObject *parent = nullptr); + + QFont font() const; + void setFont(const QFont &font); + + QFont currentFont() const; + void setCurrentFont(const QFont &font); + + QFontDialogOptions::FontDialogOptions options() const; + void setOptions(QFontDialogOptions::FontDialogOptions options); + +Q_SIGNALS: + void fontChanged(); + void currentFontChanged(); + void optionsChanged(); + +protected: + bool useNativeDialog() const override; + void onCreate(QPlatformDialogHelper *dialog) override; + void onShow(QPlatformDialogHelper *dialog) override; + void accept() override; + +private: + QFont m_font; + QFont m_currentFont; // TODO: QFontDialogOptions::initialFont + QSharedPointer m_options; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformFontDialog) + +#endif // QQUICKLABSPLATFORMFONTDIALOG_P_H diff --git a/src/labs/platform/qquicklabsplatformicon.cpp b/src/labs/platform/qquicklabsplatformicon.cpp new file mode 100644 index 00000000000..ae7c8ef10da --- /dev/null +++ b/src/labs/platform/qquicklabsplatformicon.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformicon_p.h" + +QT_BEGIN_NAMESPACE + +QUrl QQuickLabsPlatformIcon::source() const +{ + return m_source; +} + +void QQuickLabsPlatformIcon::setSource(const QUrl& source) +{ + m_source = source; +} + +QString QQuickLabsPlatformIcon::name() const +{ + return m_name; +} + +void QQuickLabsPlatformIcon::setName(const QString& name) +{ + m_name = name; +} + +bool QQuickLabsPlatformIcon::isMask() const +{ + return m_mask; +} + +void QQuickLabsPlatformIcon::setMask(bool mask) +{ + m_mask = mask; +} + +bool QQuickLabsPlatformIcon::operator==(const QQuickLabsPlatformIcon &other) const +{ + return m_source == other.m_source && m_name == other.m_name && m_mask == other.m_mask; +} + +bool QQuickLabsPlatformIcon::operator!=(const QQuickLabsPlatformIcon &other) const +{ + return !(*this == other); +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformicon_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformicon_p.h b/src/labs/platform/qquicklabsplatformicon_p.h new file mode 100644 index 00000000000..eaf0c2d3df9 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformicon_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMICON_P_H +#define QQUICKLABSPLATFORMICON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +QT_BEGIN_NAMESPACE + +class QObject; + +class QQuickLabsPlatformIcon +{ + Q_GADGET + Q_PROPERTY(QUrl source READ source WRITE setSource) + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(bool mask READ isMask WRITE setMask) + +public: + QUrl source() const; + void setSource(const QUrl &source); + + QString name() const; + void setName(const QString &name); + + bool isMask() const; + void setMask(bool mask); + + bool operator==(const QQuickLabsPlatformIcon &other) const; + bool operator!=(const QQuickLabsPlatformIcon &other) const; + +private: + bool m_mask = false; + QUrl m_source; + QString m_name; +}; + +QT_END_NAMESPACE + +#endif // QQUICKLABSPLATFORMICON_P_H diff --git a/src/labs/platform/qquicklabsplatformiconloader.cpp b/src/labs/platform/qquicklabsplatformiconloader.cpp new file mode 100644 index 00000000000..6d6deb58126 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformiconloader.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformiconloader_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QQuickLabsPlatformIconLoader::QQuickLabsPlatformIconLoader(int slot, QObject *parent) + : m_parent(parent), + m_slot(slot), + m_enabled(false) +{ + Q_ASSERT(slot != -1 && parent); +} + +bool QQuickLabsPlatformIconLoader::isEnabled() const +{ + return m_enabled; +} + +void QQuickLabsPlatformIconLoader::setEnabled(bool enabled) +{ + m_enabled = enabled; + if (m_enabled) + loadIcon(); +} + +QIcon QQuickLabsPlatformIconLoader::toQIcon() const +{ + QIcon fallback = QPixmap::fromImage(image()); + QIcon icon = QIcon::fromTheme(m_icon.name(), fallback); + icon.setIsMask(m_icon.isMask()); + return icon; +} + +QQuickLabsPlatformIcon QQuickLabsPlatformIconLoader::icon() const +{ + return m_icon; +} + +void QQuickLabsPlatformIconLoader::setIcon(const QQuickLabsPlatformIcon& icon) +{ + m_icon = icon; + if (m_enabled) + loadIcon(); +} + +void QQuickLabsPlatformIconLoader::loadIcon() +{ + if (m_icon.source().isEmpty()) { + clear(m_parent); + } else { + load(qmlEngine(m_parent), m_icon.source()); + if (m_slot != -1 && isLoading()) { + connectFinished(m_parent, m_slot); + m_slot = -1; + } + } + + if (!isLoading()) + m_parent->metaObject()->method(m_slot).invoke(m_parent); +} + +QT_END_NAMESPACE diff --git a/src/labs/platform/qquicklabsplatformiconloader_p.h b/src/labs/platform/qquicklabsplatformiconloader_p.h new file mode 100644 index 00000000000..ed48e1cf67a --- /dev/null +++ b/src/labs/platform/qquicklabsplatformiconloader_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMICONLOADER_P_H +#define QQUICKLABSPLATFORMICONLOADER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include + +#include "qquicklabsplatformicon_p.h" + +QT_BEGIN_NAMESPACE + +class QObject; + +class QQuickLabsPlatformIconLoader : public QQuickPixmap +{ +public: + QQuickLabsPlatformIconLoader(int slot, QObject *parent); + + bool isEnabled() const; + void setEnabled(bool enabled); + + QIcon toQIcon() const; + + QQuickLabsPlatformIcon icon() const; + void setIcon(const QQuickLabsPlatformIcon &icon); + +private: + void loadIcon(); + + QObject *m_parent; + int m_slot; + bool m_enabled; + QQuickLabsPlatformIcon m_icon; +}; + +QT_END_NAMESPACE + +#endif // QQUICKLABSPLATFORMICONLOADER_P_H diff --git a/src/labs/platform/qquicklabsplatformmenu.cpp b/src/labs/platform/qquicklabsplatformmenu.cpp new file mode 100644 index 00000000000..e5cf45d3865 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformmenu.cpp @@ -0,0 +1,895 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformmenu_p.h" +#include "qquicklabsplatformmenubar_p.h" +#include "qquicklabsplatformmenuitem_p.h" +#include "qquicklabsplatformiconloader_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "widgets/qwidgetplatform_p.h" + +#if QT_CONFIG(systemtrayicon) +#include "qquicklabsplatformsystemtrayicon_p.h" +#endif + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Menu + \inherits QtObject +//! \instantiates QQuickLabsPlatformMenu + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief A native menu. + + The Menu type provides a QML API for native platform menu popups. + + \image qtlabsplatform-menu.png + + Menu can be used in a \l MenuBar, or as a stand-alone context menu. + The following example shows how to open a context menu on right mouse + click: + + \code + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.RightButton + onClicked: zoomMenu.open() + } + + Menu { + id: zoomMenu + + MenuItem { + text: qsTr("Zoom In") + shortcut: StandardKey.ZoomIn + onTriggered: zoomIn() + } + + MenuItem { + text: qsTr("Zoom Out") + shortcut: StandardKey.ZoomOut + onTriggered: zoomOut() + } + } + \endcode + + \section2 Submenus + + To create submenus, declare a Menu as a child of another Menu: + + \qml + Menu { + title: qsTr("Edit") + + Menu { + title: qsTr("Advanced") + + MenuItem { + text: qsTr("Auto-indent Selection") + onTriggered: autoIndentSelection() + } + + MenuItem { + text: qsTr("Rewrap Paragraph") + onTriggered: rewrapParagraph() + } + } + } + \endqml + + \section2 Dynamically Generating Menu Items + + It is possible to dynamically generate menu items. One of the easiest ways + to do so is with \l Instantiator. For example, to implement a + "Recent Files" submenu, where the items are based on a list of files stored + in settings, the following code could be used: + + \qml + Menu { + title: qsTr("File") + + Menu { + id: recentFilesSubMenu + title: qsTr("Recent Files") + enabled: recentFilesInstantiator.count > 0 + + Instantiator { + id: recentFilesInstantiator + model: settings.recentFiles + delegate: MenuItem { + text: settings.displayableFilePath(modelData) + onTriggered: loadFile(modelData) + } + + onObjectAdded: recentFilesSubMenu.insertItem(index, object) + onObjectRemoved: recentFilesSubMenu.removeItem(object) + } + + MenuSeparator {} + + MenuItem { + text: qsTr("Clear Recent Files") + onTriggered: settings.clearRecentFiles() + } + } + } + \endqml + + \section2 Availability + + A native platform menu is currently available on the following platforms: + + \list + \li macOS + \li iOS + \li Android + \li Linux (only available as a stand-alone context menu when running with the GTK+ platform theme) + \endlist + + \input includes/widgets.qdocinc 1 + + \labs + + \sa MenuItem, MenuSeparator, MenuBar +*/ + +/*! + \qmlsignal Qt.labs.platform::Menu::aboutToShow() + + This signal is emitted when the menu is about to be shown to the user. +*/ + +/*! + \qmlsignal Qt.labs.platform::Menu::aboutToHide() + + This signal is emitted when the menu is about to be hidden from the user. +*/ + +Q_DECLARE_LOGGING_CATEGORY(qtLabsPlatformMenus) + +QQuickLabsPlatformMenu::QQuickLabsPlatformMenu(QObject *parent) + : QObject(parent), + m_complete(false), + m_enabled(true), + m_visible(true), + m_minimumWidth(-1), + m_type(QPlatformMenu::DefaultMenu), + m_menuBar(nullptr), + m_parentMenu(nullptr), + m_systemTrayIcon(nullptr), + m_menuItem(nullptr), + m_iconLoader(nullptr), + m_handle(nullptr) +{ +} + +QQuickLabsPlatformMenu::~QQuickLabsPlatformMenu() +{ + if (m_menuBar) + m_menuBar->removeMenu(this); + if (m_parentMenu) + m_parentMenu->removeMenu(this); + + unparentSubmenus(); + + delete m_iconLoader; + m_iconLoader = nullptr; + delete m_handle; + m_handle = nullptr; +} + +void QQuickLabsPlatformMenu::unparentSubmenus() +{ + for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) { + if (QQuickLabsPlatformMenu *subMenu = item->subMenu()) + subMenu->setParentMenu(nullptr); + item->setMenu(nullptr); + } +} + +QPlatformMenu *QQuickLabsPlatformMenu::handle() const +{ + return m_handle; +} + +QPlatformMenu * QQuickLabsPlatformMenu::create() +{ + if (!m_handle) { + if (m_menuBar && m_menuBar->handle()) + m_handle = m_menuBar->handle()->createMenu(); + else if (m_parentMenu && m_parentMenu->handle()) + m_handle = m_parentMenu->handle()->createSubMenu(); +#if QT_CONFIG(systemtrayicon) + else if (m_systemTrayIcon && m_systemTrayIcon->handle()) + m_handle = m_systemTrayIcon->handle()->createMenu(); +#endif + + // TODO: implement ^ + // - QCocoaMenuBar::createMenu() + // - QCocoaMenu::createSubMenu() + // - QCocoaSystemTrayIcon::createMenu() + if (!m_handle) + m_handle = QGuiApplicationPrivate::platformTheme()->createPlatformMenu(); + + if (!m_handle) + m_handle = QWidgetPlatform::createMenu(); + + qCDebug(qtLabsPlatformMenus) << "Menu ->" << m_handle; + + if (m_handle) { + connect(m_handle, &QPlatformMenu::aboutToShow, this, &QQuickLabsPlatformMenu::aboutToShow); + connect(m_handle, &QPlatformMenu::aboutToHide, this, &QQuickLabsPlatformMenu::aboutToHide); + + for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) + m_handle->insertMenuItem(item->create(), nullptr); + + if (m_menuItem) { + if (QPlatformMenuItem *handle = m_menuItem->create()) + handle->setMenu(m_handle); + } + } + } + return m_handle; +} + +void QQuickLabsPlatformMenu::destroy() +{ + if (!m_handle) + return; + + // Ensure that all submenus are unparented before we are destroyed, + // so that they don't try to access a destroyed menu. + unparentSubmenus(); + + delete m_handle; + m_handle = nullptr; +} + +void QQuickLabsPlatformMenu::sync() +{ + if (!m_complete || !create()) + return; + + m_handle->setText(m_title); + m_handle->setEnabled(m_enabled); + m_handle->setVisible(m_visible); + m_handle->setMinimumWidth(m_minimumWidth); + m_handle->setMenuType(m_type); + m_handle->setFont(m_font); + + if (m_menuBar && m_menuBar->handle()) + m_menuBar->handle()->syncMenu(m_handle); +#if QT_CONFIG(systemtrayicon) + else if (m_systemTrayIcon && m_systemTrayIcon->handle()) + m_systemTrayIcon->handle()->updateMenu(m_handle); +#endif + + for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) + item->sync(); +} + +/*! + \qmldefault + \qmlproperty list Qt.labs.platform::Menu::data + + This default property holds the list of all objects declared as children of + the menu. The data property includes objects that are not \l MenuItem instances, + such as \l Timer and \l QtObject. + + \sa items +*/ +QQmlListProperty QQuickLabsPlatformMenu::data() +{ + return QQmlListProperty(this, nullptr, data_append, data_count, data_at, data_clear); +} + +/*! + \qmlproperty list Qt.labs.platform::Menu::items + + This property holds the list of items in the menu. +*/ +QQmlListProperty QQuickLabsPlatformMenu::items() +{ + return QQmlListProperty(this, nullptr, items_append, items_count, items_at, items_clear); +} + +/*! + \readonly + \qmlproperty MenuBar Qt.labs.platform::Menu::menuBar + + This property holds the menubar that the menu belongs to, or \c null if the + menu is not in a menubar. +*/ +QQuickLabsPlatformMenuBar *QQuickLabsPlatformMenu::menuBar() const +{ + return m_menuBar; +} + +void QQuickLabsPlatformMenu::setMenuBar(QQuickLabsPlatformMenuBar *menuBar) +{ + if (m_menuBar == menuBar) + return; + + m_menuBar = menuBar; + destroy(); + emit menuBarChanged(); +} + +/*! + \readonly + \qmlproperty Menu Qt.labs.platform::Menu::parentMenu + + This property holds the parent menu that the menu belongs to, or \c null if the + menu is not a sub-menu. +*/ +QQuickLabsPlatformMenu *QQuickLabsPlatformMenu::parentMenu() const +{ + return m_parentMenu; +} + +void QQuickLabsPlatformMenu::setParentMenu(QQuickLabsPlatformMenu *menu) +{ + if (m_parentMenu == menu) + return; + + m_parentMenu = menu; + destroy(); + emit parentMenuChanged(); +} + +/*! + \readonly + \qmlproperty SystemTrayIcon Qt.labs.platform::Menu::systemTrayIcon + + This property holds the system tray icon that the menu belongs to, or \c null + if the menu is not in a system tray icon. +*/ +QQuickLabsPlatformSystemTrayIcon *QQuickLabsPlatformMenu::systemTrayIcon() const +{ + return m_systemTrayIcon; +} + +void QQuickLabsPlatformMenu::setSystemTrayIcon(QQuickLabsPlatformSystemTrayIcon *icon) +{ + if (m_systemTrayIcon == icon) + return; + + m_systemTrayIcon = icon; + destroy(); + emit systemTrayIconChanged(); +} + +/*! + \readonly + \qmlproperty MenuItem Qt.labs.platform::Menu::menuItem + + This property holds the item that presents the menu (in a parent menu). +*/ +QQuickLabsPlatformMenuItem *QQuickLabsPlatformMenu::menuItem() const +{ + if (!m_menuItem) { + QQuickLabsPlatformMenu *that = const_cast(this); + m_menuItem = new QQuickLabsPlatformMenuItem(that); + m_menuItem->setSubMenu(that); + m_menuItem->setText(m_title); + m_menuItem->setIcon(icon()); + m_menuItem->setVisible(m_visible); + m_menuItem->setEnabled(m_enabled); + m_menuItem->componentComplete(); + } + return m_menuItem; +} + +/*! + \qmlproperty bool Qt.labs.platform::Menu::enabled + + This property holds whether the menu is enabled. The default value is \c true. +*/ +bool QQuickLabsPlatformMenu::isEnabled() const +{ + return m_enabled; +} + +void QQuickLabsPlatformMenu::setEnabled(bool enabled) +{ + if (m_enabled == enabled) + return; + + if (m_menuItem) + m_menuItem->setEnabled(enabled); + + m_enabled = enabled; + sync(); + emit enabledChanged(); +} + +/*! + \qmlproperty bool Qt.labs.platform::Menu::visible + + This property holds whether the menu is visible. The default value is \c true. +*/ +bool QQuickLabsPlatformMenu::isVisible() const +{ + return m_visible; +} + +void QQuickLabsPlatformMenu::setVisible(bool visible) +{ + if (m_visible == visible) + return; + + if (m_menuItem) + m_menuItem->setVisible(visible); + + m_visible = visible; + sync(); + emit visibleChanged(); +} + +/*! + \qmlproperty int Qt.labs.platform::Menu::minimumWidth + + This property holds the minimum width of the menu. The default value is \c -1 (no minimum width). +*/ +int QQuickLabsPlatformMenu::minimumWidth() const +{ + return m_minimumWidth; +} + +void QQuickLabsPlatformMenu::setMinimumWidth(int width) +{ + if (m_minimumWidth == width) + return; + + m_minimumWidth = width; + sync(); + emit minimumWidthChanged(); +} + +/*! + \qmlproperty enumeration Qt.labs.platform::Menu::type + + This property holds the type of the menu. + + Available values: + \value Menu.DefaultMenu A normal menu (default). + \value Menu.EditMenu An edit menu with pre-populated cut, copy and paste items. +*/ +QPlatformMenu::MenuType QQuickLabsPlatformMenu::type() const +{ + return m_type; +} + +void QQuickLabsPlatformMenu::setType(QPlatformMenu::MenuType type) +{ + if (m_type == type) + return; + + m_type = type; + sync(); + emit typeChanged(); +} + +/*! + \qmlproperty string Qt.labs.platform::Menu::title + + This property holds the menu's title. +*/ +QString QQuickLabsPlatformMenu::title() const +{ + return m_title; +} + +void QQuickLabsPlatformMenu::setTitle(const QString &title) +{ + if (m_title == title) + return; + + if (m_menuItem) + m_menuItem->setText(title); + + m_title = title; + sync(); + emit titleChanged(); +} + +/*! + \qmlproperty font Qt.labs.platform::Menu::font + + This property holds the menu's font. + + \sa title +*/ +QFont QQuickLabsPlatformMenu::font() const +{ + return m_font; +} + +void QQuickLabsPlatformMenu::setFont(const QFont& font) +{ + if (m_font == font) + return; + + m_font = font; + sync(); + emit fontChanged(); +} + +/*! + \since Qt.labs.platform 1.1 (Qt 5.12) + \qmlproperty url Qt.labs.platform::Menu::icon.source + \qmlproperty string Qt.labs.platform::Menu::icon.name + \qmlproperty bool Qt.labs.platform::Menu::icon.mask + + This property holds the menu item's icon. +*/ +QQuickLabsPlatformIcon QQuickLabsPlatformMenu::icon() const +{ + if (!m_iconLoader) + return QQuickLabsPlatformIcon(); + + return iconLoader()->icon(); +} + +void QQuickLabsPlatformMenu::setIcon(const QQuickLabsPlatformIcon &icon) +{ + if (iconLoader()->icon() == icon) + return; + + if (m_menuItem) + m_menuItem->setIcon(icon); + + iconLoader()->setIcon(icon); + emit iconChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::Menu::addItem(MenuItem item) + + Adds an \a item to the end of the menu. +*/ +void QQuickLabsPlatformMenu::addItem(QQuickLabsPlatformMenuItem *item) +{ + insertItem(m_items.count(), item); +} + +/*! + \qmlmethod void Qt.labs.platform::Menu::insertItem(int index, MenuItem item) + + Inserts an \a item at the specified \a index in the menu. +*/ +void QQuickLabsPlatformMenu::insertItem(int index, QQuickLabsPlatformMenuItem *item) +{ + if (!item || m_items.contains(item)) + return; + + m_items.insert(index, item); + m_data.append(item); + item->setMenu(this); + if (m_handle && item->create()) { + QQuickLabsPlatformMenuItem *before = m_items.value(index + 1); + m_handle->insertMenuItem(item->handle(), before ? before->create() : nullptr); + } + sync(); + emit itemsChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::Menu::removeItem(MenuItem item) + + Removes an \a item from the menu. +*/ +void QQuickLabsPlatformMenu::removeItem(QQuickLabsPlatformMenuItem *item) +{ + if (!item || !m_items.removeOne(item)) + return; + + m_data.removeOne(item); + if (m_handle) + m_handle->removeMenuItem(item->handle()); + item->setMenu(nullptr); + sync(); + emit itemsChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::Menu::addMenu(Menu submenu) + + Adds a \a submenu to the end of the menu. +*/ +void QQuickLabsPlatformMenu::addMenu(QQuickLabsPlatformMenu *menu) +{ + insertMenu(m_items.count(), menu); +} + +/*! + \qmlmethod void Qt.labs.platform::Menu::insertMenu(int index, Menu submenu) + + Inserts a \a submenu at the specified \a index in the menu. +*/ +void QQuickLabsPlatformMenu::insertMenu(int index, QQuickLabsPlatformMenu *menu) +{ + if (!menu) + return; + + menu->setParentMenu(this); + insertItem(index, menu->menuItem()); +} + +/*! + \qmlmethod void Qt.labs.platform::Menu::removeMenu(Menu submenu) + + Removes a \a submenu from the menu. +*/ +void QQuickLabsPlatformMenu::removeMenu(QQuickLabsPlatformMenu *menu) +{ + if (!menu) + return; + + menu->setParentMenu(nullptr); + removeItem(menu->menuItem()); +} + +/*! + \qmlmethod void Qt.labs.platform::Menu::clear() + + Removes all items from the menu. +*/ +void QQuickLabsPlatformMenu::clear() +{ + if (m_items.isEmpty()) + return; + + for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) { + m_data.removeOne(item); + if (m_handle) + m_handle->removeMenuItem(item->handle()); + item->setMenu(nullptr); + delete item; + } + + m_items.clear(); + sync(); + emit itemsChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::Menu::open(MenuItem item) + + Opens the menu at the current mouse position, optionally aligned to a menu \a item. +*/ + +/*! + \qmlmethod void Qt.labs.platform::Menu::open(Item target, MenuItem item) + + Opens the menu at the specified \a target item, optionally aligned to a menu \a item. +*/ +void QQuickLabsPlatformMenu::open(QQmlV4Function *args) +{ + if (!m_handle) + return; + + if (args->length() > 2) { + args->v4engine()->throwTypeError(); + return; + } + + QV4::ExecutionEngine *v4 = args->v4engine(); + QV4::Scope scope(v4); + + QQuickItem *targetItem = nullptr; + if (args->length() > 0) { + QV4::ScopedValue value(scope, (*args)[0]); + QV4::Scoped object(scope, value->as()); + if (object) + targetItem = qobject_cast(object->object()); + } + + QQuickLabsPlatformMenuItem *menuItem = nullptr; + if (args->length() > 1) { + QV4::ScopedValue value(scope, (*args)[1]); + QV4::Scoped object(scope, value->as()); + if (object) + menuItem = qobject_cast(object->object()); + } + + QPoint offset; + QWindow *window = findWindow(targetItem, &offset); + + QRect targetRect; + if (targetItem) { + QRectF sceneBounds = targetItem->mapRectToScene(targetItem->boundingRect()); + targetRect = sceneBounds.toAlignedRect().translated(offset); + } else { +#if QT_CONFIG(cursor) + QPoint pos = QCursor::pos(); + if (window) + pos = window->mapFromGlobal(pos); + targetRect.moveTo(pos); +#endif + } + m_handle->showPopup(window, + QHighDpi::toNativePixels(targetRect, window), + menuItem ? menuItem->handle() : nullptr); +} + +/*! + \qmlmethod void Qt.labs.platform::Menu::close() + + Closes the menu. +*/ +void QQuickLabsPlatformMenu::close() +{ + if (m_handle) + m_handle->dismiss(); +} + +void QQuickLabsPlatformMenu::classBegin() +{ +} + +void QQuickLabsPlatformMenu::componentComplete() +{ + m_complete = true; + if (m_handle && m_iconLoader) + m_iconLoader->setEnabled(true); + sync(); +} + +QQuickLabsPlatformIconLoader *QQuickLabsPlatformMenu::iconLoader() const +{ + if (!m_iconLoader) { + QQuickLabsPlatformMenu *that = const_cast(this); + static int slot = staticMetaObject.indexOfSlot("updateIcon()"); + m_iconLoader = new QQuickLabsPlatformIconLoader(slot, that); + m_iconLoader->setEnabled(m_complete); + } + return m_iconLoader; +} + +static QWindow *effectiveWindow(QWindow *window, QPoint *offset) +{ + QQuickWindow *quickWindow = qobject_cast(window); + if (quickWindow) { + QWindow *renderWindow = QQuickRenderControl::renderWindowFor(quickWindow, offset); + if (renderWindow) + return renderWindow; + } + return window; +} + +QWindow *QQuickLabsPlatformMenu::findWindow(QQuickItem *target, QPoint *offset) const +{ + if (target) + return effectiveWindow(target->window(), offset); + + if (m_menuBar && m_menuBar->window()) + return effectiveWindow(m_menuBar->window(), offset); + + QObject *obj = parent(); + while (obj) { + QWindow *window = qobject_cast(obj); + if (window) + return effectiveWindow(window, offset); + + QQuickItem *item = qobject_cast(obj); + if (item && item->window()) + return effectiveWindow(item->window(), offset); + + obj = obj->parent(); + } + return nullptr; +} + +void QQuickLabsPlatformMenu::data_append(QQmlListProperty *property, QObject *object) +{ + QQuickLabsPlatformMenu *menu = static_cast(property->object); + if (QQuickLabsPlatformMenuItem *item = qobject_cast(object)) + menu->addItem(item); + else if (QQuickLabsPlatformMenu *subMenu = qobject_cast(object)) + menu->addMenu(subMenu); + else + menu->m_data.append(object); +} + +qsizetype QQuickLabsPlatformMenu::data_count(QQmlListProperty *property) +{ + QQuickLabsPlatformMenu *menu = static_cast(property->object); + return menu->m_data.count(); +} + +QObject *QQuickLabsPlatformMenu::data_at(QQmlListProperty *property, qsizetype index) +{ + QQuickLabsPlatformMenu *menu = static_cast(property->object); + return menu->m_data.value(index); +} + +void QQuickLabsPlatformMenu::data_clear(QQmlListProperty *property) +{ + QQuickLabsPlatformMenu *menu = static_cast(property->object); + menu->m_data.clear(); +} + +void QQuickLabsPlatformMenu::items_append(QQmlListProperty *property, QQuickLabsPlatformMenuItem *item) +{ + QQuickLabsPlatformMenu *menu = static_cast(property->object); + menu->addItem(item); +} + +qsizetype QQuickLabsPlatformMenu::items_count(QQmlListProperty *property) +{ + QQuickLabsPlatformMenu *menu = static_cast(property->object); + return menu->m_items.count(); +} + +QQuickLabsPlatformMenuItem *QQuickLabsPlatformMenu::items_at(QQmlListProperty *property, qsizetype index) +{ + QQuickLabsPlatformMenu *menu = static_cast(property->object); + return menu->m_items.value(index); +} + +void QQuickLabsPlatformMenu::items_clear(QQmlListProperty *property) +{ + QQuickLabsPlatformMenu *menu = static_cast(property->object); + menu->clear(); +} + +void QQuickLabsPlatformMenu::updateIcon() +{ + if (!m_handle || !m_iconLoader) + return; + + m_handle->setIcon(m_iconLoader->toQIcon()); + sync(); +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformmenu_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformmenu_p.h b/src/labs/platform/qquicklabsplatformmenu_p.h new file mode 100644 index 00000000000..cd41dec13e8 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformmenu_p.h @@ -0,0 +1,213 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMMENU_P_H +#define QQUICKLABSPLATFORMMENU_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include +#include +#include + +#include "qquicklabsplatformicon_p.h" + +QT_BEGIN_NAMESPACE + +class QIcon; +class QWindow; +class QQuickItem; +class QPlatformMenu; +class QQmlV4Function; +class QQuickLabsPlatformMenuBar; +class QQuickLabsPlatformMenuItem; +class QQuickLabsPlatformIconLoader; +class QQuickLabsPlatformSystemTrayIcon; + +class QQuickLabsPlatformMenu : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + Q_PROPERTY(QQmlListProperty data READ data FINAL) + Q_PROPERTY(QQmlListProperty items READ items NOTIFY itemsChanged FINAL) + Q_PROPERTY(QQuickLabsPlatformMenuBar *menuBar READ menuBar NOTIFY menuBarChanged FINAL) + Q_PROPERTY(QQuickLabsPlatformMenu *parentMenu READ parentMenu NOTIFY parentMenuChanged FINAL) + Q_PROPERTY(QQuickLabsPlatformSystemTrayIcon *systemTrayIcon READ systemTrayIcon NOTIFY systemTrayIconChanged FINAL) + Q_PROPERTY(QQuickLabsPlatformMenuItem *menuItem READ menuItem CONSTANT FINAL) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL) + Q_PROPERTY(int minimumWidth READ minimumWidth WRITE setMinimumWidth NOTIFY minimumWidthChanged FINAL) + Q_PROPERTY(QPlatformMenu::MenuType type READ type WRITE setType NOTIFY typeChanged FINAL) + Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL) + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged FINAL) + Q_PROPERTY(QQuickLabsPlatformIcon icon READ icon WRITE setIcon NOTIFY iconChanged FINAL REVISION(1, 1)) + Q_ENUMS(QPlatformMenu::MenuType) + Q_CLASSINFO("DefaultProperty", "data") + +public: + explicit QQuickLabsPlatformMenu(QObject *parent = nullptr); + ~QQuickLabsPlatformMenu(); + + QPlatformMenu *handle() const; + QPlatformMenu *create(); + void destroy(); + void sync(); + + QQmlListProperty data(); + QQmlListProperty items(); + + QQuickLabsPlatformMenuBar *menuBar() const; + void setMenuBar(QQuickLabsPlatformMenuBar *menuBar); + + QQuickLabsPlatformMenu *parentMenu() const; + void setParentMenu(QQuickLabsPlatformMenu *menu); + + QQuickLabsPlatformSystemTrayIcon *systemTrayIcon() const; + void setSystemTrayIcon(QQuickLabsPlatformSystemTrayIcon *icon); + + QQuickLabsPlatformMenuItem *menuItem() const; + + bool isEnabled() const; + void setEnabled(bool enabled); + + bool isVisible() const; + void setVisible(bool visible); + + int minimumWidth() const; + void setMinimumWidth(int width); + + QPlatformMenu::MenuType type() const; + void setType(QPlatformMenu::MenuType type); + + QString title() const; + void setTitle(const QString &title); + + QFont font() const; + void setFont(const QFont &font); + + QQuickLabsPlatformIcon icon() const; + void setIcon(const QQuickLabsPlatformIcon &icon); + + Q_INVOKABLE void addItem(QQuickLabsPlatformMenuItem *item); + Q_INVOKABLE void insertItem(int index, QQuickLabsPlatformMenuItem *item); + Q_INVOKABLE void removeItem(QQuickLabsPlatformMenuItem *item); + + Q_INVOKABLE void addMenu(QQuickLabsPlatformMenu *menu); + Q_INVOKABLE void insertMenu(int index, QQuickLabsPlatformMenu *menu); + Q_INVOKABLE void removeMenu(QQuickLabsPlatformMenu *menu); + + Q_INVOKABLE void clear(); + +public Q_SLOTS: + void open(QQmlV4Function *args); + void close(); + +Q_SIGNALS: + void aboutToShow(); + void aboutToHide(); + + void itemsChanged(); + void menuBarChanged(); + void parentMenuChanged(); + void systemTrayIconChanged(); + void titleChanged(); + void enabledChanged(); + void visibleChanged(); + void minimumWidthChanged(); + void fontChanged(); + void typeChanged(); + Q_REVISION(2, 1) void iconChanged(); + +protected: + void classBegin() override; + void componentComplete() override; + + QQuickLabsPlatformIconLoader *iconLoader() const; + + QWindow *findWindow(QQuickItem *target, QPoint *offset) const; + + static void data_append(QQmlListProperty *property, QObject *object); + static qsizetype data_count(QQmlListProperty *property); + static QObject *data_at(QQmlListProperty *property, qsizetype index); + static void data_clear(QQmlListProperty *property); + + static void items_append(QQmlListProperty *property, QQuickLabsPlatformMenuItem *item); + static qsizetype items_count(QQmlListProperty *property); + static QQuickLabsPlatformMenuItem *items_at(QQmlListProperty *property, qsizetype index); + static void items_clear(QQmlListProperty *property); + +private Q_SLOTS: + void updateIcon(); + +private: + void unparentSubmenus(); + + bool m_complete; + bool m_enabled; + bool m_visible; + int m_minimumWidth; + QPlatformMenu::MenuType m_type; + QString m_title; + QFont m_font; + QList m_data; + QList m_items; + QQuickLabsPlatformMenuBar *m_menuBar; + QQuickLabsPlatformMenu *m_parentMenu; + QQuickLabsPlatformSystemTrayIcon *m_systemTrayIcon; + mutable QQuickLabsPlatformMenuItem *m_menuItem; + mutable QQuickLabsPlatformIconLoader *m_iconLoader; + QPlatformMenu *m_handle; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformMenu) +Q_DECLARE_METATYPE(QPlatformMenu::MenuType) + +#endif // QQUICKLABSPLATFORMMENU_P_H diff --git a/src/labs/platform/qquicklabsplatformmenubar.cpp b/src/labs/platform/qquicklabsplatformmenubar.cpp new file mode 100644 index 00000000000..0ebc6990089 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformmenubar.cpp @@ -0,0 +1,334 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformmenubar_p.h" +#include "qquicklabsplatformmenu_p.h" + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmltype MenuBar + \inherits QtObject +//! \instantiates QQuickLabsPlatformMenuBar + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief A native menubar. + + The MenuBar type provides a QML API for native platform menubars. + + \image qtlabsplatform-menubar.png + + A menubar consists of a list of drop-down menus. + + \code + MenuBar { + id: menuBar + + Menu { + id: fileMenu + title: qsTr("File") + // ... + } + + Menu { + id: editMenu + title: qsTr("&Edit") + // ... + } + + Menu { + id: viewMenu + title: qsTr("&View") + // ... + } + + Menu { + id: helpMenu + title: qsTr("&Help") + // ... + } + } + \endcode + + MenuBar is currently available on the following platforms: + + \list + \li macOS + \li Android + \li Linux (only available on desktop environments that provide a global D-Bus menu bar) + \li Windows + \endlist + + \labs + + \sa Menu +*/ + +Q_DECLARE_LOGGING_CATEGORY(qtLabsPlatformMenus) + +QQuickLabsPlatformMenuBar::QQuickLabsPlatformMenuBar(QObject *parent) + : QObject(parent), + m_complete(false), + m_window(nullptr), + m_handle(nullptr) +{ + m_handle = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar(); + qCDebug(qtLabsPlatformMenus) << "MenuBar ->" << m_handle; +} + +QQuickLabsPlatformMenuBar::~QQuickLabsPlatformMenuBar() +{ + for (QQuickLabsPlatformMenu *menu : qAsConst(m_menus)) + menu->setMenuBar(nullptr); + delete m_handle; + m_handle = nullptr; +} + +QPlatformMenuBar *QQuickLabsPlatformMenuBar::handle() const +{ + return m_handle; +} + +/*! + \qmldefault + \qmlproperty list Qt.labs.platform::MenuBar::data + + This default property holds the list of all objects declared as children of + the menubar. The data property includes objects that are not \l Menu instances, + such as \l Timer and \l QtObject. + + \sa menus +*/ +QQmlListProperty QQuickLabsPlatformMenuBar::data() +{ + return QQmlListProperty(this, nullptr, data_append, data_count, data_at, data_clear); +} + +/*! + \qmlproperty list Qt.labs.platform::MenuBar::menus + + This property holds the list of menus in the menubar. +*/ +QQmlListProperty QQuickLabsPlatformMenuBar::menus() +{ + return QQmlListProperty(this, nullptr, menus_append, menus_count, menus_at, menus_clear); +} + +/*! + \qmlproperty Window Qt.labs.platform::MenuBar::window + + This property holds the menubar's window. + + Unless explicitly set, the window is automatically resolved by iterating + the QML parent objects until a \l Window or an \l Item that has a window + is found. +*/ +QWindow *QQuickLabsPlatformMenuBar::window() const +{ + return m_window; +} + +void QQuickLabsPlatformMenuBar::setWindow(QWindow *window) +{ + if (m_window == window) + return; + + if (m_handle) + m_handle->handleReparent(window); + + m_window = window; + emit windowChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::MenuBar::addMenu(Menu menu) + + Adds a \a menu to end of the menubar. +*/ +void QQuickLabsPlatformMenuBar::addMenu(QQuickLabsPlatformMenu *menu) +{ + insertMenu(m_menus.count(), menu); +} + +/*! + \qmlmethod void Qt.labs.platform::MenuBar::insertMenu(int index, Menu menu) + + Inserts a \a menu at the specified \a index in the menubar. +*/ +void QQuickLabsPlatformMenuBar::insertMenu(int index, QQuickLabsPlatformMenu *menu) +{ + if (!menu || m_menus.contains(menu)) + return; + + QQuickLabsPlatformMenu *before = m_menus.value(index); + m_menus.insert(index, menu); + m_data.append(menu); + menu->setMenuBar(this); + if (m_handle) + m_handle->insertMenu(menu->create(), before ? before->handle() : nullptr); + menu->sync(); + emit menusChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::MenuBar::removeMenu(Menu menu) + + Removes a \a menu from the menubar. +*/ +void QQuickLabsPlatformMenuBar::removeMenu(QQuickLabsPlatformMenu *menu) +{ + if (!menu || !m_menus.removeOne(menu)) + return; + + m_data.removeOne(menu); + if (m_handle) + m_handle->removeMenu(menu->handle()); + menu->setMenuBar(nullptr); + emit menusChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::MenuBar::clear() + + Removes all menus from the menubar. +*/ +void QQuickLabsPlatformMenuBar::clear() +{ + if (m_menus.isEmpty()) + return; + + for (QQuickLabsPlatformMenu *menu : qAsConst(m_menus)) { + m_data.removeOne(menu); + if (m_handle) + m_handle->removeMenu(menu->handle()); + menu->setMenuBar(nullptr); + delete menu; + } + + m_menus.clear(); + emit menusChanged(); +} + +void QQuickLabsPlatformMenuBar::classBegin() +{ +} + +void QQuickLabsPlatformMenuBar::componentComplete() +{ + m_complete = true; + for (QQuickLabsPlatformMenu *menu : qAsConst(m_menus)) + menu->sync(); + if (!m_window) + setWindow(findWindow()); +} + +QWindow *QQuickLabsPlatformMenuBar::findWindow() const +{ + QObject *obj = parent(); + while (obj) { + QWindow *window = qobject_cast(obj); + if (window) + return window; + QQuickItem *item = qobject_cast(obj); + if (item && item->window()) + return item->window(); + obj = obj->parent(); + } + return nullptr; +} + +void QQuickLabsPlatformMenuBar::data_append(QQmlListProperty *property, QObject *object) +{ + QQuickLabsPlatformMenuBar *menuBar = static_cast(property->object); + QQuickLabsPlatformMenu *menu = qobject_cast(object); + if (menu) + menuBar->addMenu(menu); + else + menuBar->m_data.append(object); +} + +qsizetype QQuickLabsPlatformMenuBar::data_count(QQmlListProperty *property) +{ + QQuickLabsPlatformMenuBar *menuBar = static_cast(property->object); + return menuBar->m_data.count(); +} + +QObject *QQuickLabsPlatformMenuBar::data_at(QQmlListProperty *property, qsizetype index) +{ + QQuickLabsPlatformMenuBar *menuBar = static_cast(property->object); + return menuBar->m_data.value(index); +} + +void QQuickLabsPlatformMenuBar::data_clear(QQmlListProperty *property) +{ + QQuickLabsPlatformMenuBar *menuBar = static_cast(property->object); + menuBar->m_data.clear(); +} + +void QQuickLabsPlatformMenuBar::menus_append(QQmlListProperty *property, QQuickLabsPlatformMenu *menu) +{ + QQuickLabsPlatformMenuBar *menuBar = static_cast(property->object); + menuBar->addMenu(menu); +} + +qsizetype QQuickLabsPlatformMenuBar::menus_count(QQmlListProperty *property) +{ + QQuickLabsPlatformMenuBar *menuBar = static_cast(property->object); + return menuBar->m_menus.count(); +} + +QQuickLabsPlatformMenu *QQuickLabsPlatformMenuBar::menus_at(QQmlListProperty *property, qsizetype index) +{ + QQuickLabsPlatformMenuBar *menuBar = static_cast(property->object); + return menuBar->m_menus.value(index); +} + +void QQuickLabsPlatformMenuBar::menus_clear(QQmlListProperty *property) +{ + QQuickLabsPlatformMenuBar *menuBar = static_cast(property->object); + menuBar->clear(); +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformmenubar_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformmenubar_p.h b/src/labs/platform/qquicklabsplatformmenubar_p.h new file mode 100644 index 00000000000..25583bee526 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformmenubar_p.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMMENUBAR_P_H +#define QQUICKLABSPLATFORMMENUBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QWindow; +class QPlatformMenuBar; +class QQuickLabsPlatformMenu; + +class QQuickLabsPlatformMenuBar : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + Q_PROPERTY(QQmlListProperty data READ data FINAL) + Q_PROPERTY(QQmlListProperty menus READ menus NOTIFY menusChanged FINAL) + Q_PROPERTY(QWindow *window READ window WRITE setWindow NOTIFY windowChanged FINAL) + Q_CLASSINFO("DefaultProperty", "data") + +public: + explicit QQuickLabsPlatformMenuBar(QObject *parent = nullptr); + ~QQuickLabsPlatformMenuBar(); + + QPlatformMenuBar *handle() const; + + QQmlListProperty data(); + QQmlListProperty menus(); + + QWindow *window() const; + void setWindow(QWindow *window); + + Q_INVOKABLE void addMenu(QQuickLabsPlatformMenu *menu); + Q_INVOKABLE void insertMenu(int index, QQuickLabsPlatformMenu *menu); + Q_INVOKABLE void removeMenu(QQuickLabsPlatformMenu *menu); + Q_INVOKABLE void clear(); + +Q_SIGNALS: + void menusChanged(); + void windowChanged(); + +protected: + void classBegin() override; + void componentComplete() override; + + QWindow *findWindow() const; + + static void data_append(QQmlListProperty *property, QObject *object); + static qsizetype data_count(QQmlListProperty *property); + static QObject *data_at(QQmlListProperty *property, qsizetype index); + static void data_clear(QQmlListProperty *property); + + static void menus_append(QQmlListProperty *property, QQuickLabsPlatformMenu *menu); + static qsizetype menus_count(QQmlListProperty *property); + static QQuickLabsPlatformMenu *menus_at(QQmlListProperty *property, qsizetype index); + static void menus_clear(QQmlListProperty *property); + +private: + bool m_complete; + QWindow *m_window; + QList m_data; + QList m_menus; + QPlatformMenuBar *m_handle; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformMenuBar) + +#endif // QQUICKLABSPLATFORMMENUBAR_P_H diff --git a/src/labs/platform/qquicklabsplatformmenuitem.cpp b/src/labs/platform/qquicklabsplatformmenuitem.cpp new file mode 100644 index 00000000000..59b9c04d6b7 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformmenuitem.cpp @@ -0,0 +1,650 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformmenuitem_p.h" +#include "qquicklabsplatformmenu_p.h" +#include "qquicklabsplatformmenuitemgroup_p.h" +#include "qquicklabsplatformiconloader_p.h" + +#include +#if QT_CONFIG(shortcut) +#include +#endif +#include +#include +#include + +#include "widgets/qwidgetplatform_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype MenuItem + \inherits QtObject +//! \instantiates QQuickLabsPlatformMenuItem + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief A native menu item. + + The MenuItem type provides a QML API for native platform menu items. + + \image qtlabsplatform-menu.png + + A menu item consists of an \l icon, \l text, and \l shortcut. + + \code + Menu { + id: zoomMenu + + MenuItem { + text: qsTr("Zoom In") + shortcut: StandardKey.ZoomIn + onTriggered: zoomIn() + } + + MenuItem { + text: qsTr("Zoom Out") + shortcut: StandardKey.ZoomOut + onTriggered: zoomOut() + } + } + \endcode + + \labs + + \sa Menu, MenuItemGroup +*/ + +/*! + \qmlsignal Qt.labs.platform::MenuItem::triggered() + + This signal is emitted when the menu item is triggered by the user. +*/ + +/*! + \qmlsignal Qt.labs.platform::MenuItem::hovered() + + This signal is emitted when the menu item is hovered by the user. +*/ + +QQuickLabsPlatformMenuItem::QQuickLabsPlatformMenuItem(QObject *parent) + : QObject(parent), + m_complete(false), + m_enabled(true), + m_visible(true), + m_separator(false), + m_checkable(false), + m_checked(false), + m_role(QPlatformMenuItem::TextHeuristicRole), + m_menu(nullptr), + m_subMenu(nullptr), + m_group(nullptr), + m_iconLoader(nullptr), + m_handle(nullptr) +{ +} + +QQuickLabsPlatformMenuItem::~QQuickLabsPlatformMenuItem() +{ + if (m_menu) + m_menu->removeItem(this); + if (m_group) + m_group->removeItem(this); + removeShortcut(); + delete m_iconLoader; + m_iconLoader = nullptr; + delete m_handle; + m_handle = nullptr; +} + +QPlatformMenuItem *QQuickLabsPlatformMenuItem::handle() const +{ + return m_handle; +} + +QPlatformMenuItem *QQuickLabsPlatformMenuItem::create() +{ + if (!m_handle && m_menu && m_menu->handle()) { + m_handle = m_menu->handle()->createMenuItem(); + + // TODO: implement QCocoaMenu::createMenuItem() + if (!m_handle) + m_handle = QGuiApplicationPrivate::platformTheme()->createPlatformMenuItem(); + + if (!m_handle) + m_handle = QWidgetPlatform::createMenuItem(); + + if (m_handle) { + connect(m_handle, &QPlatformMenuItem::activated, this, &QQuickLabsPlatformMenuItem::activate); + connect(m_handle, &QPlatformMenuItem::hovered, this, &QQuickLabsPlatformMenuItem::hovered); + } + } + return m_handle; +} + +void QQuickLabsPlatformMenuItem::sync() +{ + if (!m_complete || !create()) + return; + + m_handle->setEnabled(isEnabled()); + m_handle->setVisible(isVisible()); + m_handle->setIsSeparator(m_separator); + m_handle->setCheckable(m_checkable); + m_handle->setChecked(m_checked); + m_handle->setRole(m_role); + m_handle->setText(m_text); + m_handle->setFont(m_font); + m_handle->setHasExclusiveGroup(m_group && m_group->isExclusive()); + + if (m_iconLoader) + m_handle->setIcon(m_iconLoader->toQIcon()); + + if (m_subMenu) { + // Sync first as dynamically created menus may need to get the + // handle recreated + m_subMenu->sync(); + if (m_subMenu->handle()) + m_handle->setMenu(m_subMenu->handle()); + } + +#if QT_CONFIG(shortcut) + QKeySequence sequence; + if (m_shortcut.metaType().id() == QMetaType::Int) + sequence = QKeySequence(static_cast(m_shortcut.toInt())); + else + sequence = QKeySequence::fromString(m_shortcut.toString()); + m_handle->setShortcut(sequence.toString()); +#endif + + if (m_menu && m_menu->handle()) + m_menu->handle()->syncMenuItem(m_handle); +} + +/*! + \readonly + \qmlproperty Menu Qt.labs.platform::MenuItem::menu + + This property holds the menu that the item belongs to, or \c null if the + item is not in a menu. +*/ +QQuickLabsPlatformMenu *QQuickLabsPlatformMenuItem::menu() const +{ + return m_menu; +} + +void QQuickLabsPlatformMenuItem::setMenu(QQuickLabsPlatformMenu *menu) +{ + if (m_menu == menu) + return; + + m_menu = menu; + emit menuChanged(); +} + +/*! + \readonly + \qmlproperty Menu Qt.labs.platform::MenuItem::subMenu + + This property holds the sub-menu that the item contains, or \c null if + the item is not a sub-menu item. +*/ +QQuickLabsPlatformMenu *QQuickLabsPlatformMenuItem::subMenu() const +{ + return m_subMenu; +} + +void QQuickLabsPlatformMenuItem::setSubMenu(QQuickLabsPlatformMenu *menu) +{ + if (m_subMenu == menu) + return; + + m_subMenu = menu; + sync(); + emit subMenuChanged(); +} + +/*! + \qmlproperty MenuItemGroup Qt.labs.platform::MenuItem::group + + This property holds the group that the item belongs to, or \c null if the + item is not in a group. +*/ +QQuickLabsPlatformMenuItemGroup *QQuickLabsPlatformMenuItem::group() const +{ + return m_group; +} + +void QQuickLabsPlatformMenuItem::setGroup(QQuickLabsPlatformMenuItemGroup *group) +{ + if (m_group == group) + return; + + bool wasEnabled = isEnabled(); + bool wasVisible = isVisible(); + + if (group) + group->addItem(this); + + m_group = group; + sync(); + emit groupChanged(); + + if (isEnabled() != wasEnabled) + emit enabledChanged(); + if (isVisible() != wasVisible) + emit visibleChanged(); +} + +/*! + \qmlproperty bool Qt.labs.platform::MenuItem::enabled + + This property holds whether the item is enabled. The default value is \c true. + + Disabled items cannot be triggered by the user. They do not disappear from menus, + but they are displayed in a way which indicates that they are unavailable. For + example, they might be displayed using only shades of gray. + + When an item is disabled, it is not possible to trigger it through its \l shortcut. +*/ +bool QQuickLabsPlatformMenuItem::isEnabled() const +{ + return m_enabled && (!m_group || m_group->isEnabled()); +} + +void QQuickLabsPlatformMenuItem::setEnabled(bool enabled) +{ + if (m_enabled == enabled) + return; + + if (!enabled) + removeShortcut(); + + bool wasEnabled = isEnabled(); + m_enabled = enabled; + + if (enabled) + addShortcut(); + + sync(); + if (isEnabled() != wasEnabled) + emit enabledChanged(); +} + +/*! + \qmlproperty bool Qt.labs.platform::MenuItem::visible + + This property holds whether the item is visible. The default value is \c true. +*/ +bool QQuickLabsPlatformMenuItem::isVisible() const +{ + return m_visible && (!m_group || m_group->isVisible()); +} + +void QQuickLabsPlatformMenuItem::setVisible(bool visible) +{ + if (m_visible == visible) + return; + + bool wasVisible = isVisible(); + m_visible = visible; + sync(); + if (isVisible() != wasVisible) + emit visibleChanged(); +} + +/*! + \qmlproperty bool Qt.labs.platform::MenuItem::separator + + This property holds whether the item is a separator line. The default value + is \c false. + + \sa MenuSeparator +*/ +bool QQuickLabsPlatformMenuItem::isSeparator() const +{ + return m_separator; +} + +void QQuickLabsPlatformMenuItem::setSeparator(bool separator) +{ + if (m_separator == separator) + return; + + m_separator = separator; + sync(); + emit separatorChanged(); +} + +/*! + \qmlproperty bool Qt.labs.platform::MenuItem::checkable + + This property holds whether the item is checkable. + + A checkable menu item has an on/off state. For example, in a word processor, + a "Bold" menu item may be either on or off. A menu item that is not checkable + is a command item that is simply executed, e.g. file save. + + The default value is \c false. + + \sa checked, MenuItemGroup +*/ +bool QQuickLabsPlatformMenuItem::isCheckable() const +{ + return m_checkable; +} + +void QQuickLabsPlatformMenuItem::setCheckable(bool checkable) +{ + if (m_checkable == checkable) + return; + + m_checkable = checkable; + sync(); + emit checkableChanged(); +} + +/*! + \qmlproperty bool Qt.labs.platform::MenuItem::checked + + This property holds whether the item is checked (on) or unchecked (off). + The default value is \c false. + + \sa checkable, MenuItemGroup +*/ +bool QQuickLabsPlatformMenuItem::isChecked() const +{ + return m_checked; +} + +void QQuickLabsPlatformMenuItem::setChecked(bool checked) +{ + if (m_checked == checked) + return; + + if (checked && !m_checkable) + setCheckable(true); + + m_checked = checked; + sync(); + emit checkedChanged(); +} + +/*! + \qmlproperty enumeration Qt.labs.platform::MenuItem::role + + This property holds the role of the item. The role determines whether + the item should be placed into the application menu on macOS. + + Available values: + \value MenuItem.NoRole The item should not be put into the application menu + \value MenuItem.TextHeuristicRole The item should be put in the application menu based on the action's text (default) + \value MenuItem.ApplicationSpecificRole The item should be put in the application menu with an application-specific role + \value MenuItem.AboutQtRole The item handles the "About Qt" menu item. + \value MenuItem.AboutRole The item should be placed where the "About" menu item is in the application menu. The text of + the menu item will be set to "About ". The application name is fetched from the + \c{Info.plist} file in the application's bundle (See \l{Qt for macOS - Deployment}). + \value MenuItem.PreferencesRole The item should be placed where the "Preferences..." menu item is in the application menu. + \value MenuItem.QuitRole The item should be placed where the Quit menu item is in the application menu. + + Specifying the role only has effect on items that are in the immediate + menus of a menubar, not in the submenus of those menus. For example, if + you have a "File" menu in your menubar and the "File" menu has a submenu, + specifying a role for the items in that submenu has no effect. They will + never be moved to the application menu. +*/ +QPlatformMenuItem::MenuRole QQuickLabsPlatformMenuItem::role() const +{ + return m_role; +} + +void QQuickLabsPlatformMenuItem::setRole(QPlatformMenuItem::MenuRole role) +{ + if (m_role == role) + return; + + m_role = role; + sync(); + emit roleChanged(); +} + +/*! + \qmlproperty string Qt.labs.platform::MenuItem::text + + This property holds the menu item's text. +*/ +QString QQuickLabsPlatformMenuItem::text() const +{ + return m_text; +} + +void QQuickLabsPlatformMenuItem::setText(const QString &text) +{ + if (m_text == text) + return; + + m_text = text; + sync(); + emit textChanged(); +} + +/*! + \qmlproperty keysequence Qt.labs.platform::MenuItem::shortcut + + This property holds the menu item's shortcut. + + The shortcut key sequence can be set to one of the + \l{QKeySequence::StandardKey}{standard keyboard shortcuts}, or it can be + specified by a string containing a sequence of up to four key presses + that are needed to \l{triggered}{trigger} the shortcut. + + The default value is an empty key sequence. + + \code + MenuItem { + shortcut: "Ctrl+E,Ctrl+W" + onTriggered: edit.wrapMode = TextEdit.Wrap + } + \endcode +*/ +QVariant QQuickLabsPlatformMenuItem::shortcut() const +{ + return m_shortcut; +} + +bool QQuickLabsPlatformMenuItem::event(QEvent *e) +{ +#if QT_CONFIG(shortcut) + if (e->type() == QEvent::Shortcut) { + QShortcutEvent *se = static_cast(e); + if (se->shortcutId() == m_shortcutId) { + activate(); + return true; + } + } +#endif + return QObject::event(e); +} + +void QQuickLabsPlatformMenuItem::setShortcut(const QVariant& shortcut) +{ + if (m_shortcut == shortcut) + return; + + removeShortcut(); + m_shortcut = shortcut; + sync(); + addShortcut(); + emit shortcutChanged(); +} + +/*! + \qmlproperty font Qt.labs.platform::MenuItem::font + + This property holds the menu item's font. + + \sa text +*/ +QFont QQuickLabsPlatformMenuItem::font() const +{ + return m_font; +} + +void QQuickLabsPlatformMenuItem::setFont(const QFont& font) +{ + if (m_font == font) + return; + + m_font = font; + sync(); + emit fontChanged(); +} + +/*! + \since Qt.labs.platform 1.1 (Qt 5.12) + \qmlproperty url Qt.labs.platform::MenuItem::icon.source + \qmlproperty string Qt.labs.platform::MenuItem::icon.name + \qmlproperty bool Qt.labs.platform::MenuItem::icon.mask + + This property holds the menu item's icon. + + \code + MenuItem { + icon.mask: true + icon.name: "edit-undo" + icon.source: "qrc:/images/undo.png" + } + \endcode + + \sa QIcon::fromTheme() +*/ +QQuickLabsPlatformIcon QQuickLabsPlatformMenuItem::icon() const +{ + if (!m_iconLoader) + return QQuickLabsPlatformIcon(); + + return m_iconLoader->icon(); +} + +void QQuickLabsPlatformMenuItem::setIcon(const QQuickLabsPlatformIcon &icon) +{ + if (iconLoader()->icon() == icon) + return; + + iconLoader()->setIcon(icon); + emit iconChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::MenuItem::toggle() + + Toggles the \l checked state to its opposite state. +*/ +void QQuickLabsPlatformMenuItem::toggle() +{ + if (m_checkable) + setChecked(!m_checked); +} + +void QQuickLabsPlatformMenuItem::classBegin() +{ +} + +void QQuickLabsPlatformMenuItem::componentComplete() +{ + if (m_iconLoader) + m_iconLoader->setEnabled(true); + m_complete = true; + sync(); +} + +QQuickLabsPlatformIconLoader *QQuickLabsPlatformMenuItem::iconLoader() const +{ + if (!m_iconLoader) { + QQuickLabsPlatformMenuItem *that = const_cast(this); + static int slot = staticMetaObject.indexOfSlot("updateIcon()"); + m_iconLoader = new QQuickLabsPlatformIconLoader(slot, that); + m_iconLoader->setEnabled(m_complete); + } + return m_iconLoader; +} + +void QQuickLabsPlatformMenuItem::activate() +{ + toggle(); + emit triggered(); +} + +void QQuickLabsPlatformMenuItem::updateIcon() +{ + sync(); +} + +void QQuickLabsPlatformMenuItem::addShortcut() +{ +#if QT_CONFIG(shortcut) + QKeySequence sequence; + if (m_shortcut.metaType().id() == QMetaType::Int) + sequence = QKeySequence(static_cast(m_shortcut.toInt())); + else + sequence = QKeySequence::fromString(m_shortcut.toString()); + if (!sequence.isEmpty() && m_enabled) { + m_shortcutId = QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(this, sequence, + Qt::WindowShortcut, QQuickShortcutContext::matcher); + } else { + m_shortcutId = -1; + } +#endif +} + +void QQuickLabsPlatformMenuItem::removeShortcut() +{ +#if QT_CONFIG(shortcut) + if (m_shortcutId == -1) + return; + + QKeySequence sequence; + if (m_shortcut.metaType().id() == QMetaType::Int) + sequence = QKeySequence(static_cast(m_shortcut.toInt())); + else + sequence = QKeySequence::fromString(m_shortcut.toString()); + QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(m_shortcutId, this, sequence); +#endif +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformmenuitem_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformmenuitem_p.h b/src/labs/platform/qquicklabsplatformmenuitem_p.h new file mode 100644 index 00000000000..ab7403e0daa --- /dev/null +++ b/src/labs/platform/qquicklabsplatformmenuitem_p.h @@ -0,0 +1,194 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMMENUITEM_P_H +#define QQUICKLABSPLATFORMMENUITEM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include +#include + +#include "qquicklabsplatformicon_p.h" + +QT_BEGIN_NAMESPACE + +class QPlatformMenuItem; +class QQuickLabsPlatformMenu; +class QQuickLabsPlatformIconLoader; +class QQuickLabsPlatformMenuItemGroup; + +class QQuickLabsPlatformMenuItem : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + Q_PROPERTY(QQuickLabsPlatformMenu *menu READ menu NOTIFY menuChanged FINAL) + Q_PROPERTY(QQuickLabsPlatformMenu *subMenu READ subMenu NOTIFY subMenuChanged FINAL) + Q_PROPERTY(QQuickLabsPlatformMenuItemGroup *group READ group WRITE setGroup NOTIFY groupChanged FINAL) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL) + Q_PROPERTY(bool separator READ isSeparator WRITE setSeparator NOTIFY separatorChanged FINAL) + Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable NOTIFY checkableChanged FINAL) + Q_PROPERTY(bool checked READ isChecked WRITE setChecked NOTIFY checkedChanged FINAL) + Q_PROPERTY(QPlatformMenuItem::MenuRole role READ role WRITE setRole NOTIFY roleChanged FINAL) + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged FINAL) + Q_PROPERTY(QVariant shortcut READ shortcut WRITE setShortcut NOTIFY shortcutChanged FINAL) + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged FINAL) + Q_PROPERTY(QQuickLabsPlatformIcon icon READ icon WRITE setIcon NOTIFY iconChanged FINAL REVISION(1, 1)) + Q_ENUMS(QPlatformMenuItem::MenuRole) + +public: + explicit QQuickLabsPlatformMenuItem(QObject *parent = nullptr); + ~QQuickLabsPlatformMenuItem(); + + QPlatformMenuItem *handle() const; + QPlatformMenuItem *create(); + void sync(); + + QQuickLabsPlatformMenu *menu() const; + void setMenu(QQuickLabsPlatformMenu* menu); + + QQuickLabsPlatformMenu *subMenu() const; + void setSubMenu(QQuickLabsPlatformMenu *menu); + + QQuickLabsPlatformMenuItemGroup *group() const; + void setGroup(QQuickLabsPlatformMenuItemGroup *group); + + bool isEnabled() const; + void setEnabled(bool enabled); + + bool isVisible() const; + void setVisible(bool visible); + + bool isSeparator() const; + void setSeparator(bool separator); + + bool isCheckable() const; + void setCheckable(bool checkable); + + bool isChecked() const; + void setChecked(bool checked); + + QPlatformMenuItem::MenuRole role() const; + void setRole(QPlatformMenuItem::MenuRole role); + + QString text() const; + void setText(const QString &text); + + QVariant shortcut() const; + void setShortcut(const QVariant& shortcut); + + QFont font() const; + void setFont(const QFont &font); + + QQuickLabsPlatformIcon icon() const; + void setIcon(const QQuickLabsPlatformIcon &icon); + +public Q_SLOTS: + void toggle(); + +Q_SIGNALS: + void triggered(); + void hovered(); + + void menuChanged(); + void subMenuChanged(); + void groupChanged(); + void enabledChanged(); + void visibleChanged(); + void separatorChanged(); + void checkableChanged(); + void checkedChanged(); + void roleChanged(); + void textChanged(); + void shortcutChanged(); + void fontChanged(); + Q_REVISION(2, 1) void iconChanged(); + +protected: + void classBegin() override; + void componentComplete() override; + + QQuickLabsPlatformIconLoader *iconLoader() const; + + bool event(QEvent *e) override; +private Q_SLOTS: + void activate(); + void updateIcon(); + +private: + void addShortcut(); + void removeShortcut(); + + bool m_complete; + bool m_enabled; + bool m_visible; + bool m_separator; + bool m_checkable; + bool m_checked; + QPlatformMenuItem::MenuRole m_role; + QString m_text; + QVariant m_shortcut; + QFont m_font; + QQuickLabsPlatformMenu *m_menu; + QQuickLabsPlatformMenu *m_subMenu; + QQuickLabsPlatformMenuItemGroup *m_group; + mutable QQuickLabsPlatformIconLoader *m_iconLoader; + QPlatformMenuItem *m_handle; + int m_shortcutId = -1; + + friend class QQuickLabsPlatformMenu; + friend class QQuickLabsPlatformMenuItemGroup; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformMenuItem) + +#endif // QQUICKLABSPLATFORMMENUITEM_P_H diff --git a/src/labs/platform/qquicklabsplatformmenuitemgroup.cpp b/src/labs/platform/qquicklabsplatformmenuitemgroup.cpp new file mode 100644 index 00000000000..bb2d116e235 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformmenuitemgroup.cpp @@ -0,0 +1,392 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Templates module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformmenuitemgroup_p.h" +#include "qquicklabsplatformmenuitem_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype MenuItemGroup + \inherits QtObject +//! \instantiates QQuickLabsPlatformMenuItemGroup + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief A group for managing native menu items. + + The MenuItemGroup groups native menu items together. + + MenuItemGroup is exclusive by default. In an exclusive menu item + group, only one item can be checked at any time; checking another + item automatically unchecks the previously checked one. MenuItemGroup + can be configured as non-exclusive, which is particularly useful for + showing, hiding, enabling and disabling items together as a group. + + The most straight-forward way to use MenuItemGroup is to assign + a list of items. + + \code + Menu { + id: verticalMenu + title: qsTr("Vertical") + + MenuItemGroup { + id: verticalGroup + items: verticalMenu.items + } + + MenuItem { text: qsTr("Top"); checkable: true } + MenuItem { text: qsTr("Center"); checked: true } + MenuItem { text: qsTr("Bottom"); checkable: true } + } + \endcode + + The same menu may sometimes contain items that should not be included + in the same exclusive group. Such cases are best handled using the + \l {MenuItem::group}{group} property. + + \code + Menu { + id: horizontalMenu + title: qsTr("Horizontal") + + MenuItemGroup { + id: horizontalGroup + } + + MenuItem { + checked: true + text: qsTr("Left") + group: horizontalGroup + } + MenuItem { + checkable: true + text: qsTr("Center") + group: horizontalGroup + } + MenuItem { + text: qsTr("Right") + checkable: true + group: horizontalGroup + } + + MenuItem { separator: true } + MenuItem { text: qsTr("Justify"); checkable: true } + MenuItem { text: qsTr("Absolute"); checkable: true } + } + \endcode + + More advanced use cases can be handled using the addItem() and + removeItem() methods. + + \labs + + \sa MenuItem +*/ + +/*! + \qmlsignal Qt.labs.platform::MenuItemGroup::triggered(MenuItem item) + + This signal is emitted when an \a item in the group is triggered by the user. + + \sa MenuItem::triggered() +*/ + +/*! + \qmlsignal Qt.labs.platform::MenuItemGroup::hovered(MenuItem item) + + This signal is emitted when an \a item in the group is hovered by the user. + + \sa MenuItem::hovered() +*/ + +QQuickLabsPlatformMenuItemGroup::QQuickLabsPlatformMenuItemGroup(QObject *parent) + : QObject(parent), m_enabled(true), m_visible(true), m_exclusive(true), m_checkedItem(nullptr) +{ +} + +QQuickLabsPlatformMenuItemGroup::~QQuickLabsPlatformMenuItemGroup() +{ + clear(); +} + +/*! + \qmlproperty bool Qt.labs.platform::MenuItemGroup::enabled + + This property holds whether the group is enabled. The default value is \c true. + + The enabled state of the group affects the enabled state of each item in the group, + except that explicitly disabled items are not enabled even if the group is enabled. +*/ +bool QQuickLabsPlatformMenuItemGroup::isEnabled() const +{ + return m_enabled; +} + +void QQuickLabsPlatformMenuItemGroup::setEnabled(bool enabled) +{ + if (m_enabled == enabled) + return; + + m_enabled = enabled; + emit enabledChanged(); + + for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) { + if (item->m_enabled) { + item->sync(); + emit item->enabledChanged(); + } + } +} + +/*! + \qmlproperty bool Qt.labs.platform::MenuItemGroup::visible + + This property holds whether the group is visible. The default value is \c true. + + The visibility of the group affects the visibility of each item in the group, + except that explicitly hidden items are not visible even if the group is visible. +*/ +bool QQuickLabsPlatformMenuItemGroup::isVisible() const +{ + return m_visible; +} + +void QQuickLabsPlatformMenuItemGroup::setVisible(bool visible) +{ + if (m_visible == visible) + return; + + m_visible = visible; + emit visibleChanged(); + + for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) { + if (item->m_visible) { + item->sync(); + emit item->visibleChanged(); + } + } +} + +/*! + \qmlproperty bool Qt.labs.platform::MenuItemGroup::exclusive + + This property holds whether the group is exclusive. The default value is \c true. + + In an exclusive menu item group, only one item can be checked at any time; + checking another item automatically unchecks the previously checked one. +*/ +bool QQuickLabsPlatformMenuItemGroup::isExclusive() const +{ + return m_exclusive; +} + +void QQuickLabsPlatformMenuItemGroup::setExclusive(bool exclusive) +{ + if (m_exclusive == exclusive) + return; + + m_exclusive = exclusive; + emit exclusiveChanged(); + + for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) + item->sync(); +} + +/*! + \qmlproperty MenuItem Qt.labs.platform::MenuItemGroup::checkedItem + + This property holds the currently checked item in the group, or \c null if no item is checked. +*/ +QQuickLabsPlatformMenuItem *QQuickLabsPlatformMenuItemGroup::checkedItem() const +{ + return m_checkedItem; +} + +void QQuickLabsPlatformMenuItemGroup::setCheckedItem(QQuickLabsPlatformMenuItem *item) +{ + if (m_checkedItem == item) + return; + + if (m_checkedItem) + m_checkedItem->setChecked(false); + + m_checkedItem = item; + emit checkedItemChanged(); + + if (item) + item->setChecked(true); +} + +/*! + \qmlproperty list Qt.labs.platform::MenuItemGroup::items + + This property holds the list of items in the group. +*/ +QQmlListProperty QQuickLabsPlatformMenuItemGroup::items() +{ + return QQmlListProperty(this, nullptr, items_append, items_count, items_at, items_clear); +} + +/*! + \qmlmethod void Qt.labs.platform::MenuItemGroup::addItem(MenuItem item) + + Adds an \a item to the group. +*/ +void QQuickLabsPlatformMenuItemGroup::addItem(QQuickLabsPlatformMenuItem *item) +{ + if (!item || m_items.contains(item)) + return; + + m_items.append(item); + item->setGroup(this); + + connect(item, &QQuickLabsPlatformMenuItem::checkedChanged, this, &QQuickLabsPlatformMenuItemGroup::updateCurrent); + connect(item, &QQuickLabsPlatformMenuItem::triggered, this, &QQuickLabsPlatformMenuItemGroup::activateItem); + connect(item, &QQuickLabsPlatformMenuItem::hovered, this, &QQuickLabsPlatformMenuItemGroup::hoverItem); + + if (m_exclusive && item->isChecked()) + setCheckedItem(item); + + emit itemsChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::MenuItemGroup::removeItem(MenuItem item) + + Removes an \a item from the group. +*/ +void QQuickLabsPlatformMenuItemGroup::removeItem(QQuickLabsPlatformMenuItem *item) +{ + if (!item || !m_items.contains(item)) + return; + + m_items.removeOne(item); + item->setGroup(nullptr); + + disconnect(item, &QQuickLabsPlatformMenuItem::checkedChanged, this, &QQuickLabsPlatformMenuItemGroup::updateCurrent); + disconnect(item, &QQuickLabsPlatformMenuItem::triggered, this, &QQuickLabsPlatformMenuItemGroup::activateItem); + disconnect(item, &QQuickLabsPlatformMenuItem::hovered, this, &QQuickLabsPlatformMenuItemGroup::hoverItem); + + if (m_checkedItem == item) + setCheckedItem(nullptr); + + emit itemsChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::MenuItemGroup::clear() + + Removes all items from the group. +*/ +void QQuickLabsPlatformMenuItemGroup::clear() +{ + if (m_items.isEmpty()) + return; + + for (QQuickLabsPlatformMenuItem *item : qAsConst(m_items)) { + item->setGroup(nullptr); + disconnect(item, &QQuickLabsPlatformMenuItem::checkedChanged, this, &QQuickLabsPlatformMenuItemGroup::updateCurrent); + disconnect(item, &QQuickLabsPlatformMenuItem::triggered, this, &QQuickLabsPlatformMenuItemGroup::activateItem); + disconnect(item, &QQuickLabsPlatformMenuItem::hovered, this, &QQuickLabsPlatformMenuItemGroup::hoverItem); + } + + setCheckedItem(nullptr); + + m_items.clear(); + emit itemsChanged(); +} + +QQuickLabsPlatformMenuItem *QQuickLabsPlatformMenuItemGroup::findCurrent() const +{ + for (QQuickLabsPlatformMenuItem *item : m_items) { + if (item->isChecked()) + return item; + } + return nullptr; +} + +void QQuickLabsPlatformMenuItemGroup::updateCurrent() +{ + if (!m_exclusive) + return; + + QQuickLabsPlatformMenuItem *item = qobject_cast(sender()); + if (item && item->isChecked()) + setCheckedItem(item); +} + +void QQuickLabsPlatformMenuItemGroup::activateItem() +{ + QQuickLabsPlatformMenuItem *item = qobject_cast(sender()); + if (item) + emit triggered(item); +} + +void QQuickLabsPlatformMenuItemGroup::hoverItem() +{ + QQuickLabsPlatformMenuItem *item = qobject_cast(sender()); + if (item) + emit hovered(item); +} + +void QQuickLabsPlatformMenuItemGroup::items_append(QQmlListProperty *prop, QQuickLabsPlatformMenuItem *item) +{ + QQuickLabsPlatformMenuItemGroup *group = static_cast(prop->object); + group->addItem(item); +} + +qsizetype QQuickLabsPlatformMenuItemGroup::items_count(QQmlListProperty *prop) +{ + QQuickLabsPlatformMenuItemGroup *group = static_cast(prop->object); + return group->m_items.count(); +} + +QQuickLabsPlatformMenuItem *QQuickLabsPlatformMenuItemGroup::items_at(QQmlListProperty *prop, qsizetype index) +{ + QQuickLabsPlatformMenuItemGroup *group = static_cast(prop->object); + return group->m_items.value(index); +} + +void QQuickLabsPlatformMenuItemGroup::items_clear(QQmlListProperty *prop) +{ + QQuickLabsPlatformMenuItemGroup *group = static_cast(prop->object); + group->clear(); +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformmenuitemgroup_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformmenuitemgroup_p.h b/src/labs/platform/qquicklabsplatformmenuitemgroup_p.h new file mode 100644 index 00000000000..2dc60a70d22 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformmenuitemgroup_p.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Templates module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMMENUITEMGROUP_P_H +#define QQUICKLABSPLATFORMMENUITEMGROUP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QQuickLabsPlatformMenuItem; +class QQuickLabsPlatformMenuItemGroupPrivate; + +class QQuickLabsPlatformMenuItemGroup : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL) + Q_PROPERTY(bool exclusive READ isExclusive WRITE setExclusive NOTIFY exclusiveChanged FINAL) + Q_PROPERTY(QQuickLabsPlatformMenuItem *checkedItem READ checkedItem WRITE setCheckedItem NOTIFY checkedItemChanged FINAL) + Q_PROPERTY(QQmlListProperty items READ items NOTIFY itemsChanged FINAL) + +public: + explicit QQuickLabsPlatformMenuItemGroup(QObject *parent = nullptr); + ~QQuickLabsPlatformMenuItemGroup(); + + bool isEnabled() const; + void setEnabled(bool enabled); + + bool isVisible() const; + void setVisible(bool visible); + + bool isExclusive() const; + void setExclusive(bool exclusive); + + QQuickLabsPlatformMenuItem *checkedItem() const; + void setCheckedItem(QQuickLabsPlatformMenuItem *item); + + QQmlListProperty items(); + + Q_INVOKABLE void addItem(QQuickLabsPlatformMenuItem *item); + Q_INVOKABLE void removeItem(QQuickLabsPlatformMenuItem *item); + Q_INVOKABLE void clear(); + +Q_SIGNALS: + void triggered(QQuickLabsPlatformMenuItem *item); + void hovered(QQuickLabsPlatformMenuItem *item); + + void enabledChanged(); + void visibleChanged(); + void exclusiveChanged(); + void checkedItemChanged(); + void itemsChanged(); + +private: + QQuickLabsPlatformMenuItem *findCurrent() const; + void updateCurrent(); + void activateItem(); + void hoverItem(); + + static void items_append(QQmlListProperty *prop, QQuickLabsPlatformMenuItem *obj); + static qsizetype items_count(QQmlListProperty *prop); + static QQuickLabsPlatformMenuItem *items_at(QQmlListProperty *prop, qsizetype index); + static void items_clear(QQmlListProperty *prop); + + bool m_enabled; + bool m_visible; + bool m_exclusive; + QQuickLabsPlatformMenuItem *m_checkedItem; + QList m_items; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformMenuItemGroup) + +#endif // QQUICKLABSPLATFORMMENUITEMGROUP_P_H diff --git a/src/labs/platform/qquicklabsplatformmenuseparator.cpp b/src/labs/platform/qquicklabsplatformmenuseparator.cpp new file mode 100644 index 00000000000..c3c2dd80df1 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformmenuseparator.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformmenuseparator_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype MenuSeparator + \inherits MenuItem +//! \instantiates QQuickLabsPlatformMenuSeparator + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief A native menu separator. + + The MenuSeparator type is provided for convenience. It is a MenuItem + that has the \l {MenuItem::}{separator} property set to \c true by default. + + \image qtlabsplatform-menubar.png + + \labs + + \sa Menu, MenuItem +*/ + +QQuickLabsPlatformMenuSeparator::QQuickLabsPlatformMenuSeparator(QObject *parent) + : QQuickLabsPlatformMenuItem(parent) +{ + setSeparator(true); +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformmenuseparator_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformmenuseparator_p.h b/src/labs/platform/qquicklabsplatformmenuseparator_p.h new file mode 100644 index 00000000000..d77903dda8e --- /dev/null +++ b/src/labs/platform/qquicklabsplatformmenuseparator_p.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMMENUSEPARATOR_P_H +#define QQUICKLABSPLATFORMMENUSEPARATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquicklabsplatformmenuitem_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickLabsPlatformMenuSeparator : public QQuickLabsPlatformMenuItem +{ + Q_OBJECT + +public: + explicit QQuickLabsPlatformMenuSeparator(QObject *parent = nullptr); +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformMenuSeparator) + +#endif // QQUICKLABSPLATFORMMENUSEPARATOR_P_H diff --git a/src/labs/platform/qquicklabsplatformmessagedialog.cpp b/src/labs/platform/qquicklabsplatformmessagedialog.cpp new file mode 100644 index 00000000000..83ec2d9fd1a --- /dev/null +++ b/src/labs/platform/qquicklabsplatformmessagedialog.cpp @@ -0,0 +1,384 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformmessagedialog_p.h" + +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmltype MessageDialog + \inherits Dialog +//! \instantiates QQuickLabsPlatformMessageDialog + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief A native message dialog. + + The MessageDialog type provides a QML API for native platform message dialogs. + + \image qtlabsplatform-messagedialog-android.png + + A message dialog is used to inform the user, or ask the user a question. + A message dialog displays a primary \l text to alert the user to a situation, + an \l {informativeText}{informative text} to further explain the alert or to + ask the user a question, and an optional \l {detailedText}{detailed text} to + provide even more data if the user requests it. A message box can also display + a configurable set of \l buttons for accepting a user response. + + To show a message dialog, construct an instance of MessageDialog, set the + desired properties, and call \l {Dialog::}{open()}. + + \code + MessageDialog { + buttons: MessageDialog.Ok + text: "The document has been modified." + } + \endcode + + The user must click the \uicontrol OK button to dismiss the message dialog. + A modal message dialog blocks the rest of the GUI until the message is + dismissed. + + A more elaborate approach than just alerting the user to an event is to + also ask the user what to do about it. Store the question in the + \l {informativeText}{informative text} property, and specify the \l buttons + property to the set of buttons you want as the set of user responses. The + buttons are specified by combining values using the bitwise OR operator. The + display order for the buttons is platform dependent. + + \code + MessageDialog { + text: "The document has been modified." + informativeText: "Do you want to save your changes?" + buttons: MessageDialog.Ok | MessageDialog.Cancel + + onAccepted: document.save() + } + \endcode + + \image qtlabsplatform-messagedialog-informative-android.png + + The \l clicked() signal passes the information of which button was clicked. + + A native platform message dialog is currently available on the following platforms: + + \list + \li iOS + \li Android + \endlist + + \input includes/widgets.qdocinc 1 + + \labs +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::clicked(button) + + This signal is emitted when a dialog \a button is clicked. + + \sa buttons +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::okClicked() + + This signal is emitted when \uicontrol Ok is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::saveClicked() + + This signal is emitted when \uicontrol Save is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::saveAllClicked() + + This signal is emitted when \uicontrol {Save All} is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::openClicked() + + This signal is emitted when \uicontrol Open is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::yesClicked() + + This signal is emitted when \uicontrol Yes is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::yesToAllClicked() + + This signal is emitted when \uicontrol {Yes To All} is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::noClicked() + + This signal is emitted when \uicontrol No is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::noToAllClicked() + + This signal is emitted when \uicontrol {No To All} is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::abortClicked() + + This signal is emitted when \uicontrol Abort is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::retryClicked() + + This signal is emitted when \uicontrol Retry is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::ignoreClicked() + + This signal is emitted when \uicontrol Ignore is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::closeClicked() + + This signal is emitted when \uicontrol Close is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::cancelClicked() + + This signal is emitted when \uicontrol Cancel is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::discardClicked() + + This signal is emitted when \uicontrol Discard is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::helpClicked() + + This signal is emitted when \uicontrol Help is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::applyClicked() + + This signal is emitted when \uicontrol Apply is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::resetClicked() + + This signal is emitted when \uicontrol Reset is clicked. +*/ + +/*! + \qmlsignal Qt.labs.platform::MessageDialog::restoreDefaultsClicked() + + This signal is emitted when \uicontrol {Restore Defaults} is clicked. +*/ + +QQuickLabsPlatformMessageDialog::QQuickLabsPlatformMessageDialog(QObject *parent) + : QQuickLabsPlatformDialog(QPlatformTheme::MessageDialog, parent), + m_options(QMessageDialogOptions::create()) +{ +} + +/*! + \qmlproperty string Qt.labs.platform::MessageDialog::text + + This property holds the text to be displayed on the message dialog. + + \sa informativeText, detailedText +*/ +QString QQuickLabsPlatformMessageDialog::text() const +{ + return m_options->text(); +} + +void QQuickLabsPlatformMessageDialog::setText(const QString &text) +{ + if (m_options->text() == text) + return; + + m_options->setText(text); + emit textChanged(); +} + +/*! + \qmlproperty string Qt.labs.platform::MessageDialog::informativeText + + This property holds the informative text that provides a fuller description for the message. + + Informative text can be used to expand upon the \l text to give more information to the user. + + \sa text, detailedText +*/ +QString QQuickLabsPlatformMessageDialog::informativeText() const +{ + return m_options->informativeText(); +} + +void QQuickLabsPlatformMessageDialog::setInformativeText(const QString &text) +{ + if (m_options->informativeText() == text) + return; + + m_options->setInformativeText(text); + emit informativeTextChanged(); +} + +/*! + \qmlproperty string Qt.labs.platform::MessageDialog::detailedText + + This property holds the text to be displayed in the details area. + + \sa text, informativeText +*/ +QString QQuickLabsPlatformMessageDialog::detailedText() const +{ + return m_options->detailedText(); +} + +void QQuickLabsPlatformMessageDialog::setDetailedText(const QString &text) +{ + if (m_options->detailedText() == text) + return; + + m_options->setDetailedText(text); + emit detailedTextChanged(); +} + +/*! + \qmlproperty flags Qt.labs.platform::MessageDialog::buttons + + This property holds a combination of buttons that are used by the message dialog. + The default value is \c MessageDialog.NoButton. + + Possible flags: + \value MessageDialog.Ok An "OK" button defined with the \c AcceptRole. + \value MessageDialog.Open An "Open" button defined with the \c AcceptRole. + \value MessageDialog.Save A "Save" button defined with the \c AcceptRole. + \value MessageDialog.Cancel A "Cancel" button defined with the \c RejectRole. + \value MessageDialog.Close A "Close" button defined with the \c RejectRole. + \value MessageDialog.Discard A "Discard" or "Don't Save" button, depending on the platform, defined with the \c DestructiveRole. + \value MessageDialog.Apply An "Apply" button defined with the \c ApplyRole. + \value MessageDialog.Reset A "Reset" button defined with the \c ResetRole. + \value MessageDialog.RestoreDefaults A "Restore Defaults" button defined with the \c ResetRole. + \value MessageDialog.Help A "Help" button defined with the \c HelpRole. + \value MessageDialog.SaveAll A "Save All" button defined with the \c AcceptRole. + \value MessageDialog.Yes A "Yes" button defined with the \c YesRole. + \value MessageDialog.YesToAll A "Yes to All" button defined with the \c YesRole. + \value MessageDialog.No A "No" button defined with the \c NoRole. + \value MessageDialog.NoToAll A "No to All" button defined with the \c NoRole. + \value MessageDialog.Abort An "Abort" button defined with the \c RejectRole. + \value MessageDialog.Retry A "Retry" button defined with the \c AcceptRole. + \value MessageDialog.Ignore An "Ignore" button defined with the \c AcceptRole. + \value MessageDialog.NoButton The dialog has no buttons. + + \sa clicked() +*/ +QPlatformDialogHelper::StandardButtons QQuickLabsPlatformMessageDialog::buttons() const +{ + return m_options->standardButtons(); +} + +void QQuickLabsPlatformMessageDialog::setButtons(QPlatformDialogHelper::StandardButtons buttons) +{ + if (m_options->standardButtons() == buttons) + return; + + m_options->setStandardButtons(buttons); + emit buttonsChanged(); +} + +void QQuickLabsPlatformMessageDialog::onCreate(QPlatformDialogHelper *dialog) +{ + if (QPlatformMessageDialogHelper *messageDialog = qobject_cast(dialog)) { + connect(messageDialog, &QPlatformMessageDialogHelper::clicked, this, &QQuickLabsPlatformMessageDialog::handleClick); + messageDialog->setOptions(m_options); + } +} + +void QQuickLabsPlatformMessageDialog::onShow(QPlatformDialogHelper *dialog) +{ + m_options->setWindowTitle(title()); + if (QPlatformMessageDialogHelper *messageDialog = qobject_cast(dialog)) + messageDialog->setOptions(m_options); +} + +void QQuickLabsPlatformMessageDialog::handleClick(QPlatformDialogHelper::StandardButton button) +{ + done(button); + emit clicked(button); + + switch (button) { + case QPlatformDialogHelper::Ok: emit okClicked(); break; + case QPlatformDialogHelper::Save: emit saveClicked(); break; + case QPlatformDialogHelper::SaveAll: emit saveAllClicked(); break; + case QPlatformDialogHelper::Open: emit openClicked(); break; + case QPlatformDialogHelper::Yes: emit yesClicked(); break; + case QPlatformDialogHelper::YesToAll: emit yesToAllClicked(); break; + case QPlatformDialogHelper::No: emit noClicked(); break; + case QPlatformDialogHelper::NoToAll: emit noToAllClicked(); break; + case QPlatformDialogHelper::Abort: emit abortClicked(); break; + case QPlatformDialogHelper::Retry: emit retryClicked(); break; + case QPlatformDialogHelper::Ignore: emit ignoreClicked(); break; + case QPlatformDialogHelper::Close: emit closeClicked(); break; + case QPlatformDialogHelper::Cancel: emit cancelClicked(); break; + case QPlatformDialogHelper::Discard: emit discardClicked(); break; + case QPlatformDialogHelper::Help: emit helpClicked(); break; + case QPlatformDialogHelper::Apply: emit applyClicked(); break; + case QPlatformDialogHelper::Reset: emit resetClicked(); break; + case QPlatformDialogHelper::RestoreDefaults: emit restoreDefaultsClicked(); break; + default: qmlWarning(this) << "unknown button" << int(button); break; + } +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformmessagedialog_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformmessagedialog_p.h b/src/labs/platform/qquicklabsplatformmessagedialog_p.h new file mode 100644 index 00000000000..af5ee252419 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformmessagedialog_p.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMMESSAGEDIALOG_P_H +#define QQUICKLABSPLATFORMMESSAGEDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquicklabsplatformdialog_p.h" +#include + +QT_BEGIN_NAMESPACE + +class QQuickLabsPlatformMessageDialog : public QQuickLabsPlatformDialog +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged FINAL) + Q_PROPERTY(QString informativeText READ informativeText WRITE setInformativeText NOTIFY informativeTextChanged FINAL) + Q_PROPERTY(QString detailedText READ detailedText WRITE setDetailedText NOTIFY detailedTextChanged FINAL) + Q_PROPERTY(QPlatformDialogHelper::StandardButtons buttons READ buttons WRITE setButtons NOTIFY buttonsChanged FINAL) + Q_FLAGS(QPlatformDialogHelper::StandardButtons) + +public: + explicit QQuickLabsPlatformMessageDialog(QObject *parent = nullptr); + + QString text() const; + void setText(const QString &text); + + QString informativeText() const; + void setInformativeText(const QString &text); + + QString detailedText() const; + void setDetailedText(const QString &text); + + QPlatformDialogHelper::StandardButtons buttons() const; + void setButtons(QPlatformDialogHelper::StandardButtons buttons); + +Q_SIGNALS: + void textChanged(); + void informativeTextChanged(); + void detailedTextChanged(); + void buttonsChanged(); + void clicked(QPlatformDialogHelper::StandardButton button); + + void okClicked(); + void saveClicked(); + void saveAllClicked(); + void openClicked(); + void yesClicked(); + void yesToAllClicked(); + void noClicked(); + void noToAllClicked(); + void abortClicked(); + void retryClicked(); + void ignoreClicked(); + void closeClicked(); + void cancelClicked(); + void discardClicked(); + void helpClicked(); + void applyClicked(); + void resetClicked(); + void restoreDefaultsClicked(); + +protected: + void onCreate(QPlatformDialogHelper *dialog) override; + void onShow(QPlatformDialogHelper *dialog) override; + +private Q_SLOTS: + void handleClick(QPlatformDialogHelper::StandardButton button); + +private: + QSharedPointer m_options; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformMessageDialog) + +#endif // QQUICKLABSPLATFORMMESSAGEDIALOG_P_H diff --git a/src/labs/platform/qquicklabsplatformstandardpaths.cpp b/src/labs/platform/qquicklabsplatformstandardpaths.cpp new file mode 100644 index 00000000000..33e40b85176 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformstandardpaths.cpp @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module 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 "qquicklabsplatformstandardpaths_p.h" + +#include + +QT_BEGIN_NAMESPACE + +/*! + \qmltype StandardPaths + \inherits QtObject +//! \instantiates QQuickLabsPlatformStandardPaths + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief Provides access to the standard system paths. + + The StandardPaths singleton type provides methods for querying the standard + system paths. The standard paths are mostly useful in conjunction with the + FileDialog and FolderDialog types. + + \qml + FileDialog { + folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) + } + \endqml + + \labs + + \sa FileDialog, FolderDialog, QStandardPaths +*/ + +static QList toUrlList(const QStringList &paths) +{ + QList urls; + urls.reserve(paths.size()); + for (const QString &path : paths) + urls += QUrl::fromLocalFile(path); + return urls; +} + +QQuickLabsPlatformStandardPaths::QQuickLabsPlatformStandardPaths(QObject *parent) + : QObject(parent) +{ +} + +QObject *QQuickLabsPlatformStandardPaths::create(QQmlEngine *engine, QJSEngine *scriptEngine) +{ + Q_UNUSED(scriptEngine); + return new QQuickLabsPlatformStandardPaths(engine); +} + +/*! + \qmlmethod string Qt.labs.platform::StandardPaths::displayName(StandardLocation type) + + \include standardpath/functiondocs.qdocinc displayName + + \sa QStandardPaths::displayName() +*/ +QString QQuickLabsPlatformStandardPaths::displayName(QStandardPaths::StandardLocation type) +{ + return QStandardPaths::displayName(type); +} + +/*! + \qmlmethod url Qt.labs.platform::StandardPaths::findExecutable(string executableName, list paths) + + \include standardpath/functiondocs.qdocinc findExecutable + + \sa QStandardPaths::findExecutable() +*/ +QUrl QQuickLabsPlatformStandardPaths::findExecutable(const QString &executableName, const QStringList &paths) +{ + return QUrl::fromLocalFile(QStandardPaths::findExecutable(executableName, paths)); +} + +/*! + \qmlmethod url Qt.labs.platform::StandardPaths::locate(StandardLocation type, string fileName, LocateOptions options) + + \include standardpath/functiondocs.qdocinc locate + + \sa QStandardPaths::locate() +*/ +QUrl QQuickLabsPlatformStandardPaths::locate(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options) +{ + return QUrl::fromLocalFile(QStandardPaths::locate(type, fileName, options)); +} + +/*! + \qmlmethod list Qt.labs.platform::StandardPaths::locateAll(StandardLocation type, string fileName, LocateOptions options) + + \include standardpath/functiondocs.qdocinc locateAll + + \sa QStandardPaths::locateAll() +*/ +QList QQuickLabsPlatformStandardPaths::locateAll(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options) +{ + return toUrlList(QStandardPaths::locateAll(type, fileName, options)); +} + +/*! + \qmlmethod void Qt.labs.platform::StandardPaths::setTestModeEnabled(bool testMode) + + \include standardpath/functiondocs.qdocinc setTestModeEnabled + + \sa QStandardPaths::setTestModeEnabled() +*/ +void QQuickLabsPlatformStandardPaths::setTestModeEnabled(bool testMode) +{ + QStandardPaths::setTestModeEnabled(testMode); +} + +/*! + \qmlmethod list Qt.labs.platform::StandardPaths::standardLocations(StandardLocation type) + + \include standardpath/functiondocs.qdocinc standardLocations + + \sa QStandardPaths::standardLocations() +*/ +QList QQuickLabsPlatformStandardPaths::standardLocations(QStandardPaths::StandardLocation type) +{ + return toUrlList(QStandardPaths::standardLocations(type)); +} + +/*! + \qmlmethod url Qt.labs.platform::StandardPaths::writableLocation(StandardLocation type) + + \include standardpath/functiondocs.qdocinc writableLocation + + \sa QStandardPaths::writableLocation() +*/ +QUrl QQuickLabsPlatformStandardPaths::writableLocation(QStandardPaths::StandardLocation type) +{ + return QUrl::fromLocalFile(QStandardPaths::writableLocation(type)); +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformstandardpaths_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformstandardpaths_p.h b/src/labs/platform/qquicklabsplatformstandardpaths_p.h new file mode 100644 index 00000000000..2dd3247e729 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformstandardpaths_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module 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 QQUICKLABSPLATFORMSTANDARDPATHS_P_H +#define QQUICKLABSPLATFORMSTANDARDPATHS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QQmlEngine; +class QJSEngine; + +class QQuickLabsPlatformStandardPaths : public QObject +{ + Q_OBJECT + Q_ENUMS(QStandardPaths::StandardLocation QStandardPaths::LocateOptions) + +public: + explicit QQuickLabsPlatformStandardPaths(QObject *parent = nullptr); + + static QObject *create(QQmlEngine *engine, QJSEngine *scriptEngine); + + Q_INVOKABLE static QString displayName(QStandardPaths::StandardLocation type); + Q_INVOKABLE static QUrl findExecutable(const QString &executableName, const QStringList &paths = QStringList()); + Q_INVOKABLE static QUrl locate(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options = QStandardPaths::LocateFile); + Q_INVOKABLE static QList locateAll(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options = QStandardPaths::LocateFile); + Q_INVOKABLE static void setTestModeEnabled(bool testMode); + Q_INVOKABLE static QList standardLocations(QStandardPaths::StandardLocation type); + Q_INVOKABLE static QUrl writableLocation(QStandardPaths::StandardLocation type); + +private: + Q_DISABLE_COPY(QQuickLabsPlatformStandardPaths) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformStandardPaths) +Q_DECLARE_METATYPE(QStandardPaths::StandardLocation) +Q_DECLARE_METATYPE(QStandardPaths::LocateOptions) + +#endif // QQUICKLABSPLATFORMSTANDARDPATHS_P_H diff --git a/src/labs/platform/qquicklabsplatformsystemtrayicon.cpp b/src/labs/platform/qquicklabsplatformsystemtrayicon.cpp new file mode 100644 index 00000000000..d3bb83aeed1 --- /dev/null +++ b/src/labs/platform/qquicklabsplatformsystemtrayicon.cpp @@ -0,0 +1,443 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabsplatformsystemtrayicon_p.h" +#include "qquicklabsplatformmenu_p.h" +#include "qquicklabsplatformiconloader_p.h" + +#include +#include +#include + +#include "widgets/qwidgetplatform_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype SystemTrayIcon + \inherits QtObject +//! \instantiates QQuickLabsPlatformSystemTrayIcon + \inqmlmodule Qt.labs.platform + \since 5.8 + \brief A system tray icon. + + The SystemTrayIcon type provides an icon for an application in the system tray. + + Many desktop platforms provide a special system tray or notification area, + where applications can display icons and notification messages. + + \image qtlabsplatform-systemtrayicon.png + + The following example shows how to create a system tray icon, and how to make + use of the \l activated() signal: + + \code + SystemTrayIcon { + visible: true + icon.source: "qrc:/images/tray-icon.png" + + onActivated: { + window.show() + window.raise() + window.requestActivate() + } + } + \endcode + + \section2 Tray menu + + SystemTrayIcon can have a menu that opens when the icon is activated. + + \image qtlabsplatform-systemtrayicon-menu.png + + The following example illustrates how to assign a \l Menu to a system tray icon: + + \code + SystemTrayIcon { + visible: true + icon.source: "qrc:/images/tray-icon.png" + + menu: Menu { + MenuItem { + text: qsTr("Quit") + onTriggered: Qt.quit() + } + } + } + \endcode + + \section2 Notification messages + + SystemTrayIcon can display notification messages. + + \image qtlabsplatform-systemtrayicon-message.png + + The following example presents how to show a notification message using + \l showMessage(), and how to make use of the \l messageClicked() signal: + + \code + SystemTrayIcon { + visible: true + icon.source: "qrc:/images/tray-icon.png" + + onMessageClicked: console.log("Message clicked") + Component.onCompleted: showMessage("Message title", "Something important came up. Click this to know more.") + } + \endcode + + \section2 Availability + + A native system tray icon is currently \l available on the following platforms: + + \list + \li All window managers and independent tray implementations for X11 that implement the + \l{http://standards.freedesktop.org/systemtray-spec/systemtray-spec-0.2.html} + {freedesktop.org XEmbed system tray specification}. + \li All desktop environments that implement the + \l{http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem} + {freedesktop.org D-Bus StatusNotifierItem specification}, including recent versions of KDE and Unity. + \li All supported versions of macOS. Note that the Growl notification system must be installed + for showMessage() to display messages on OS X prior to 10.8 (Mountain Lion). + \endlist + + \input includes/widgets.qdocinc 1 + + \labs + + \sa Menu +*/ + +/*! + \qmlsignal Qt.labs.platform::SystemTrayIcon::activated(ActivationReason reason) + + This signal is emitted when the system tray icon is activated by the user. The + \a reason argument specifies how the system tray icon was activated. + + Available reasons: + + \value SystemTrayIcon.Unknown Unknown reason + \value SystemTrayIcon.Context The context menu for the system tray icon was requested + \value SystemTrayIcon.DoubleClick The system tray icon was double clicked + \value SystemTrayIcon.Trigger The system tray icon was clicked + \value SystemTrayIcon.MiddleClick The system tray icon was clicked with the middle mouse button +*/ + +/*! + \qmlsignal Qt.labs.platform::SystemTrayIcon::messageClicked() + + This signal is emitted when a notification message is clicked by the user. + + \sa showMessage() +*/ + +Q_DECLARE_LOGGING_CATEGORY(qtLabsPlatformTray) + +QQuickLabsPlatformSystemTrayIcon::QQuickLabsPlatformSystemTrayIcon(QObject *parent) + : QObject(parent), + m_complete(false), + m_visible(false), + m_menu(nullptr), + m_iconLoader(nullptr), + m_handle(nullptr) +{ + m_handle = QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon(); + if (!m_handle) + m_handle = QWidgetPlatform::createSystemTrayIcon(this); + qCDebug(qtLabsPlatformTray) << "SystemTrayIcon ->" << m_handle; + + if (m_handle) { + connect(m_handle, &QPlatformSystemTrayIcon::activated, this, &QQuickLabsPlatformSystemTrayIcon::activated); + connect(m_handle, &QPlatformSystemTrayIcon::messageClicked, this, &QQuickLabsPlatformSystemTrayIcon::messageClicked); + } +} + +QQuickLabsPlatformSystemTrayIcon::~QQuickLabsPlatformSystemTrayIcon() +{ + if (m_menu) + m_menu->setSystemTrayIcon(nullptr); + cleanup(); + delete m_iconLoader; + m_iconLoader = nullptr; + delete m_handle; + m_handle = nullptr; +} + +QPlatformSystemTrayIcon *QQuickLabsPlatformSystemTrayIcon::handle() const +{ + return m_handle; +} + +/*! + \readonly + \qmlproperty bool Qt.labs.platform::SystemTrayIcon::available + + This property holds whether the system tray is available. +*/ +bool QQuickLabsPlatformSystemTrayIcon::isAvailable() const +{ + return m_handle && m_handle->isSystemTrayAvailable(); +} + +/*! + \readonly + \qmlproperty bool Qt.labs.platform::SystemTrayIcon::supportsMessages + + This property holds whether the system tray icon supports notification messages. + + \sa showMessage() +*/ +bool QQuickLabsPlatformSystemTrayIcon::supportsMessages() const +{ + return m_handle && m_handle->supportsMessages(); +} + +/*! + \qmlproperty bool Qt.labs.platform::SystemTrayIcon::visible + + This property holds whether the system tray icon is visible. + + The default value is \c false. +*/ +bool QQuickLabsPlatformSystemTrayIcon::isVisible() const +{ + return m_visible; +} + +void QQuickLabsPlatformSystemTrayIcon::setVisible(bool visible) +{ + if (m_visible == visible) + return; + + if (m_handle && m_complete) { + if (visible) + init(); + else + cleanup(); + } + + m_visible = visible; + emit visibleChanged(); +} + +/*! + \qmlproperty string Qt.labs.platform::SystemTrayIcon::tooltip + + This property holds the tooltip of the system tray icon. +*/ +QString QQuickLabsPlatformSystemTrayIcon::tooltip() const +{ + return m_tooltip; +} + +void QQuickLabsPlatformSystemTrayIcon::setTooltip(const QString &tooltip) +{ + if (m_tooltip == tooltip) + return; + + if (m_handle && m_complete) + m_handle->updateToolTip(tooltip); + + m_tooltip = tooltip; + emit tooltipChanged(); +} + +/*! + \qmlproperty Menu Qt.labs.platform::SystemTrayIcon::menu + + This property holds a menu for the system tray icon. +*/ +QQuickLabsPlatformMenu *QQuickLabsPlatformSystemTrayIcon::menu() const +{ + return m_menu; +} + +void QQuickLabsPlatformSystemTrayIcon::setMenu(QQuickLabsPlatformMenu *menu) +{ + if (m_menu == menu) + return; + + if (m_menu) + m_menu->setSystemTrayIcon(nullptr); + if (menu) { + menu->setSystemTrayIcon(this); + if (m_handle && m_complete && menu->create()) + m_handle->updateMenu(menu->handle()); + } + + m_menu = menu; + emit menuChanged(); +} + +/*! + \since Qt.labs.platform 1.1 (Qt 5.12) + \qmlproperty rect Qt.labs.platform::SystemTrayIcon::geometry + + This property holds the geometry of the system tray icon. +*/ +QRect QQuickLabsPlatformSystemTrayIcon::geometry() const +{ + return m_handle ? m_handle->geometry() : QRect(); +} + +/*! + \since Qt.labs.platform 1.1 (Qt 5.12) + \qmlproperty url Qt.labs.platform::SystemTrayIcon::icon.source + \qmlproperty string Qt.labs.platform::SystemTrayIcon::icon.name + \qmlproperty bool Qt.labs.platform::SystemTrayIcon::icon.mask + + This property holds the system tray icon. + + \code + SystemTrayIcon { + icon.mask: true + icon.source: "qrc:/images/tray-icon.png" + } + \endcode +*/ +QQuickLabsPlatformIcon QQuickLabsPlatformSystemTrayIcon::icon() const +{ + if (!m_iconLoader) + return QQuickLabsPlatformIcon(); + + return m_iconLoader->icon(); +} + +void QQuickLabsPlatformSystemTrayIcon::setIcon(const QQuickLabsPlatformIcon &icon) +{ + if (iconLoader()->icon() == icon) + return; + + iconLoader()->setIcon(icon); + emit iconChanged(); +} + +/*! + \qmlmethod void Qt.labs.platform::SystemTrayIcon::show() + + Shows the system tray icon. +*/ +void QQuickLabsPlatformSystemTrayIcon::show() +{ + setVisible(true); +} + +/*! + \qmlmethod void Qt.labs.platform::SystemTrayIcon::hide() + + Hides the system tray icon. +*/ +void QQuickLabsPlatformSystemTrayIcon::hide() +{ + setVisible(false); +} + +/*! + \qmlmethod void Qt.labs.platform::SystemTrayIcon::showMessage(string title, string message, MessageIcon icon, int msecs) + + Shows a system tray message with the given \a title, \a message and \a icon + for the time specified in \a msecs. + + \note System tray messages are dependent on the system configuration and user preferences, + and may not appear at all. Therefore, it should not be relied upon as the sole means for providing + critical information. + + \sa supportsMessages, messageClicked() +*/ +void QQuickLabsPlatformSystemTrayIcon::showMessage(const QString &title, const QString &msg, QPlatformSystemTrayIcon::MessageIcon icon, int msecs) +{ + if (m_handle) + m_handle->showMessage(title, msg, QIcon(), icon, msecs); +} + +void QQuickLabsPlatformSystemTrayIcon::init() +{ + if (!m_handle) + return; + + m_handle->init(); + if (m_menu && m_menu->create()) + m_handle->updateMenu(m_menu->handle()); + m_handle->updateToolTip(m_tooltip); + if (m_iconLoader) + m_iconLoader->setEnabled(true); +} + +void QQuickLabsPlatformSystemTrayIcon::cleanup() +{ + if (m_handle) + m_handle->cleanup(); + if (m_iconLoader) + m_iconLoader->setEnabled(false); +} + +void QQuickLabsPlatformSystemTrayIcon::classBegin() +{ +} + +void QQuickLabsPlatformSystemTrayIcon::componentComplete() +{ + m_complete = true; + if (m_visible) + init(); +} + +QQuickLabsPlatformIconLoader *QQuickLabsPlatformSystemTrayIcon::iconLoader() const +{ + if (!m_iconLoader) { + QQuickLabsPlatformSystemTrayIcon *that = const_cast(this); + static int slot = staticMetaObject.indexOfSlot("updateIcon()"); + m_iconLoader = new QQuickLabsPlatformIconLoader(slot, that); + m_iconLoader->setEnabled(m_complete); + } + return m_iconLoader; +} + +void QQuickLabsPlatformSystemTrayIcon::updateIcon() +{ + if (!m_handle || !m_iconLoader) + return; + + const QRect oldGeometry = m_handle->geometry(); + + m_handle->updateIcon(m_iconLoader->toQIcon()); + + if (oldGeometry != m_handle->geometry()) + emit geometryChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qquicklabsplatformsystemtrayicon_p.cpp" diff --git a/src/labs/platform/qquicklabsplatformsystemtrayicon_p.h b/src/labs/platform/qquicklabsplatformsystemtrayicon_p.h new file mode 100644 index 00000000000..f59fc55094a --- /dev/null +++ b/src/labs/platform/qquicklabsplatformsystemtrayicon_p.h @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABSPLATFORMSYSTEMTRAYICON_P_H +#define QQUICKLABSPLATFORMSYSTEMTRAYICON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include + +#include "qquicklabsplatformicon_p.h" + +QT_REQUIRE_CONFIG(systemtrayicon); + +QT_BEGIN_NAMESPACE + +class QQuickLabsPlatformMenu; +class QQuickLabsPlatformIconLoader; + +class QQuickLabsPlatformSystemTrayIcon : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + Q_PROPERTY(bool available READ isAvailable CONSTANT FINAL) + Q_PROPERTY(bool supportsMessages READ supportsMessages CONSTANT FINAL) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL) + Q_PROPERTY(QString tooltip READ tooltip WRITE setTooltip NOTIFY tooltipChanged FINAL) + Q_PROPERTY(QQuickLabsPlatformMenu *menu READ menu WRITE setMenu NOTIFY menuChanged FINAL) + Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged FINAL REVISION(1, 1)) + Q_PROPERTY(QQuickLabsPlatformIcon icon READ icon WRITE setIcon NOTIFY iconChanged FINAL REVISION(1, 1)) + Q_ENUMS(QPlatformSystemTrayIcon::ActivationReason QPlatformSystemTrayIcon::MessageIcon) + +public: + explicit QQuickLabsPlatformSystemTrayIcon(QObject *parent = nullptr); + ~QQuickLabsPlatformSystemTrayIcon(); + + QPlatformSystemTrayIcon *handle() const; + + bool isAvailable() const; + bool supportsMessages() const; + + bool isVisible() const; + void setVisible(bool visible); + + QString tooltip() const; + void setTooltip(const QString &tooltip); + + QQuickLabsPlatformMenu *menu() const; + void setMenu(QQuickLabsPlatformMenu *menu); + + QRect geometry() const; + + QQuickLabsPlatformIcon icon() const; + void setIcon(const QQuickLabsPlatformIcon &icon); + +public Q_SLOTS: + void show(); + void hide(); + + void showMessage(const QString &title, const QString &message, + QPlatformSystemTrayIcon::MessageIcon iconType = QPlatformSystemTrayIcon::Information, int msecs = 10000); + +Q_SIGNALS: + void activated(QPlatformSystemTrayIcon::ActivationReason reason); + void messageClicked(); + void visibleChanged(); + void tooltipChanged(); + void menuChanged(); + Q_REVISION(2, 1) void geometryChanged(); + Q_REVISION(2, 1) void iconChanged(); + +protected: + void init(); + void cleanup(); + + void classBegin() override; + void componentComplete() override; + + QQuickLabsPlatformIconLoader *iconLoader() const; + +private Q_SLOTS: + void updateIcon(); + +private: + bool m_complete; + bool m_visible; + QString m_tooltip; + QQuickLabsPlatformMenu *m_menu; + mutable QQuickLabsPlatformIconLoader *m_iconLoader; + QPlatformSystemTrayIcon *m_handle; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabsPlatformSystemTrayIcon) +Q_DECLARE_METATYPE(QPlatformSystemTrayIcon::ActivationReason) +Q_DECLARE_METATYPE(QPlatformSystemTrayIcon::MessageIcon) + +#endif // QQUICKLABSPLATFORMSYSTEMTRAYICON_P_H diff --git a/src/labs/platform/qtlabsplatformplugin.cpp b/src/labs/platform/qtlabsplatformplugin.cpp new file mode 100644 index 00000000000..90b166f6e99 --- /dev/null +++ b/src/labs/platform/qtlabsplatformplugin.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Templates module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include "qquicklabsplatformdialog_p.h" +#include "qquicklabsplatformcolordialog_p.h" +#include "qquicklabsplatformfiledialog_p.h" +#include "qquicklabsplatformfolderdialog_p.h" +#include "qquicklabsplatformfontdialog_p.h" +#include "qquicklabsplatformmessagedialog_p.h" + +#include "qquicklabsplatformmenu_p.h" +#include "qquicklabsplatformmenubar_p.h" +#include "qquicklabsplatformmenuitem_p.h" +#include "qquicklabsplatformmenuitemgroup_p.h" +#include "qquicklabsplatformmenuseparator_p.h" + +#include "qquicklabsplatformstandardpaths_p.h" +#if QT_CONFIG(systemtrayicon) +# include "qquicklabsplatformsystemtrayicon_p.h" +#endif + +#include "qquicklabsplatformicon_p.h" + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(qtLabsPlatformDialogs, "qt.labs.platform.dialogs") +Q_LOGGING_CATEGORY(qtLabsPlatformMenus, "qt.labs.platform.menus") +Q_LOGGING_CATEGORY(qtLabsPlatformTray, "qt.labs.platform.tray") + +class QtLabsPlatformPlugin: public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtLabsPlatformPlugin(QObject *parent = nullptr); + void registerTypes(const char *uri) override; +}; + +QtLabsPlatformPlugin::QtLabsPlatformPlugin(QObject *parent) : QQmlExtensionPlugin(parent) +{ +} + +void QtLabsPlatformPlugin::registerTypes(const char *uri) +{ + qmlRegisterUncreatableType(uri, 1, 0, "Dialog", QQuickLabsPlatformDialog::tr("Dialog is an abstract base class")); + qmlRegisterType(uri, 1, 0, "ColorDialog"); + qmlRegisterType(uri, 1, 0, "FileDialog"); + qmlRegisterAnonymousType(uri, 1); + qmlRegisterType(uri, 1, 0, "FolderDialog"); + qmlRegisterType(uri, 1, 0, "FontDialog"); + qmlRegisterType(uri, 1, 0, "MessageDialog"); + + qmlRegisterType(uri, 1, 0, "Menu"); + qmlRegisterType(uri, 1, 0, "MenuBar"); + qmlRegisterType(uri, 1, 0, "MenuItem"); + qmlRegisterType(uri, 1, 1, "MenuItem"); + qmlRegisterType(uri, 1, 0, "MenuItemGroup"); + qmlRegisterType(uri, 1, 0, "MenuSeparator"); + qRegisterMetaType(); + + qmlRegisterUncreatableType(uri, 1, 0, "StandardButton", QQuickLabsPlatformDialog::tr("Cannot create an instance of StandardButton")); + qmlRegisterSingletonType(uri, 1, 0, "StandardPaths", QQuickLabsPlatformStandardPaths::create); + qRegisterMetaType(); + qRegisterMetaType(); + +#if QT_CONFIG(systemtrayicon) + qmlRegisterType(uri, 1, 0, "SystemTrayIcon"); + qmlRegisterType(uri, 1, 1, "SystemTrayIcon"); + qRegisterMetaType(); + qRegisterMetaType(); +#endif + + qmlRegisterAnonymousType(uri, 1); + qRegisterMetaType(); +} + +QT_END_NAMESPACE + +#include "qtlabsplatformplugin.moc" diff --git a/src/labs/platform/widgets/qwidgetplatform_p.h b/src/labs/platform/widgets/qwidgetplatform_p.h new file mode 100644 index 00000000000..cbdaa24a1e6 --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatform_p.h @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWIDGETPLATFORM_P_H +#define QWIDGETPLATFORM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include +#include + +#ifdef QT_WIDGETS_LIB +#include +#if QT_CONFIG(colordialog) +#include "qwidgetplatformcolordialog_p.h" +#endif +#if QT_CONFIG(filedialog) +#include "qwidgetplatformfiledialog_p.h" +#endif +#if QT_CONFIG(fontdialog) +#include "qwidgetplatformfontdialog_p.h" +#endif +#if QT_CONFIG(messagebox) +#include "qwidgetplatformmessagedialog_p.h" +#endif +#if QT_CONFIG(menu) +#include "qwidgetplatformmenu_p.h" +#include "qwidgetplatformmenuitem_p.h" +#endif +#ifndef QT_NO_SYSTEMTRAYICON +#include "qwidgetplatformsystemtrayicon_p.h" +#endif +#endif + +QT_BEGIN_NAMESPACE + +#ifndef QT_WIDGETS_LIB +typedef QPlatformMenu QWidgetPlatformMenu; +typedef QPlatformMenuItem QWidgetPlatformMenuItem; +typedef QPlatformColorDialogHelper QWidgetPlatformColorDialog; +typedef QPlatformFileDialogHelper QWidgetPlatformFileDialog; +typedef QPlatformFontDialogHelper QWidgetPlatformFontDialog; +typedef QPlatformMessageDialogHelper QWidgetPlatformMessageDialog; +typedef QPlatformSystemTrayIcon QWidgetPlatformSystemTrayIcon; +#endif + +namespace QWidgetPlatform +{ + static inline bool isAvailable(const char *type) + { + if (!qApp->inherits("QApplication")) { + qCritical("\nERROR: No native %s implementation available." + "\nQt Labs Platform requires Qt Widgets on this setup." + "\nAdd 'QT += widgets' to .pro and create QApplication in main().\n", type); + return false; + } + return true; + } + + template + static inline T *createWidget(const char *name, QObject *parent) + { + static bool available = isAvailable(name); +#ifdef QT_WIDGETS_LIB + if (available) + return new T(parent); +#else + Q_UNUSED(parent); + Q_UNUSED(available); +#endif + return nullptr; + } + + static inline QPlatformMenu *createMenu(QObject *parent = nullptr) { +#if defined(QT_WIDGETS_LIB) && QT_CONFIG(menu) + return createWidget("Menu", parent); +#else + Q_UNUSED(parent); + return nullptr; +#endif + } + static inline QPlatformMenuItem *createMenuItem(QObject *parent = nullptr) { +#if defined(QT_WIDGETS_LIB) && QT_CONFIG(menu) + return createWidget("MenuItem", parent); +#else + Q_UNUSED(parent); + return nullptr; +#endif + } + static inline QPlatformSystemTrayIcon *createSystemTrayIcon(QObject *parent = nullptr) { +#ifndef QT_NO_SYSTEMTRAYICON + return createWidget("SystemTrayIcon", parent); +#else + Q_UNUSED(parent); + return nullptr; +#endif + } + static inline QPlatformDialogHelper *createDialog(QPlatformTheme::DialogType type, QObject *parent = nullptr) + { +#if !defined(QT_WIDGETS_LIB) || !(QT_CONFIG(colordialog) || QT_CONFIG(filedialog) || QT_CONFIG(fontdialog) || QT_CONFIG(messagebox)) + Q_UNUSED(parent); +#endif + switch (type) { +#if defined(QT_WIDGETS_LIB) && QT_CONFIG(colordialog) + case QPlatformTheme::ColorDialog: return createWidget("ColorDialog", parent); +#endif +#if defined(QT_WIDGETS_LIB) && QT_CONFIG(filedialog) + case QPlatformTheme::FileDialog: return createWidget("FileDialog", parent); +#endif +#if defined(QT_WIDGETS_LIB) && QT_CONFIG(fontdialog) + case QPlatformTheme::FontDialog: return createWidget("FontDialog", parent); +#endif +#if defined(QT_WIDGETS_LIB) && QT_CONFIG(messagebox) + case QPlatformTheme::MessageDialog: return createWidget("MessageDialog", parent); +#endif + default: break; + } + return nullptr; + } +} + +QT_END_NAMESPACE + +#endif // QWIDGETPLATFORM_P_H diff --git a/src/labs/platform/widgets/qwidgetplatformcolordialog.cpp b/src/labs/platform/widgets/qwidgetplatformcolordialog.cpp new file mode 100644 index 00000000000..472f584faed --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformcolordialog.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwidgetplatformcolordialog_p.h" +#include "qwidgetplatformdialog_p.h" + +#include + +QT_BEGIN_NAMESPACE + +QWidgetPlatformColorDialog::QWidgetPlatformColorDialog(QObject *parent) + : m_dialog(new QColorDialog) +{ + setParent(parent); + + connect(m_dialog.data(), &QColorDialog::accepted, this, &QPlatformDialogHelper::accept); + connect(m_dialog.data(), &QColorDialog::rejected, this, &QPlatformDialogHelper::reject); + connect(m_dialog.data(), &QColorDialog::currentColorChanged, this, &QPlatformColorDialogHelper::currentColorChanged); +} + +QWidgetPlatformColorDialog::~QWidgetPlatformColorDialog() +{ +} + +QColor QWidgetPlatformColorDialog::currentColor() const +{ + return m_dialog->currentColor(); +} + +void QWidgetPlatformColorDialog::setCurrentColor(const QColor &color) +{ + m_dialog->setCurrentColor(color); +} + +void QWidgetPlatformColorDialog::exec() +{ + m_dialog->exec(); +} + +bool QWidgetPlatformColorDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) +{ + QSharedPointer options = QPlatformColorDialogHelper::options(); + m_dialog->setWindowTitle(options->windowTitle()); + m_dialog->setOptions(static_cast(int(options->options())) | QColorDialog::DontUseNativeDialog); + + return QWidgetPlatformDialog::show(m_dialog.data(), flags, modality, parent); +} + +void QWidgetPlatformColorDialog::hide() +{ + m_dialog->hide(); +} + +QT_END_NAMESPACE + +#include "moc_qwidgetplatformcolordialog_p.cpp" diff --git a/src/labs/platform/widgets/qwidgetplatformcolordialog_p.h b/src/labs/platform/widgets/qwidgetplatformcolordialog_p.h new file mode 100644 index 00000000000..09ed5a1e7c0 --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformcolordialog_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWIDGETPLATFORMCOLORDIALOG_P_H +#define QWIDGETPLATFORMCOLORDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +class QColorDialog; + +class QWidgetPlatformColorDialog : public QPlatformColorDialogHelper +{ + Q_OBJECT + +public: + explicit QWidgetPlatformColorDialog(QObject *parent = nullptr); + ~QWidgetPlatformColorDialog(); + + QColor currentColor() const override; + void setCurrentColor(const QColor &color) override; + + void exec() override; + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) override; + void hide() override; + +private: + QScopedPointer m_dialog; +}; + +QT_END_NAMESPACE + +#endif // QWIDGETPLATFORMCOLORDIALOG_P_H diff --git a/src/labs/platform/widgets/qwidgetplatformdialog.cpp b/src/labs/platform/widgets/qwidgetplatformdialog.cpp new file mode 100644 index 00000000000..3a206839e21 --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformdialog.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwidgetplatformdialog_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +bool QWidgetPlatformDialog::show(QDialog *dialog, Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) +{ + dialog->setWindowFlags(flags); + dialog->setWindowModality(modality); + + dialog->createWinId(); + QWindow *handle = dialog->windowHandle(); + Q_ASSERT(handle); + handle->setTransientParent(const_cast(parent)); + + dialog->show(); + return true; +} + +QT_END_NAMESPACE diff --git a/src/labs/platform/widgets/qwidgetplatformdialog_p.h b/src/labs/platform/widgets/qwidgetplatformdialog_p.h new file mode 100644 index 00000000000..d4f27655ea1 --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformdialog_p.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWIDGETPLATFORMDIALOG_P_H +#define QWIDGETPLATFORMDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +class QDialog; +class QWindow; + +class QWidgetPlatformDialog +{ +public: + static bool show(QDialog *dialog, Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); +}; + +QT_END_NAMESPACE + +#endif // QWIDGETPLATFORMDIALOG_P_H diff --git a/src/labs/platform/widgets/qwidgetplatformfiledialog.cpp b/src/labs/platform/widgets/qwidgetplatformfiledialog.cpp new file mode 100644 index 00000000000..5ab27db45f5 --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformfiledialog.cpp @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwidgetplatformfiledialog_p.h" +#include "qwidgetplatformdialog_p.h" + +#include + +QT_BEGIN_NAMESPACE + +QWidgetPlatformFileDialog::QWidgetPlatformFileDialog(QObject *parent) + : m_dialog(new QFileDialog) +{ + setParent(parent); + + connect(m_dialog.data(), &QDialog::accepted, this, &QPlatformDialogHelper::accept); + connect(m_dialog.data(), &QDialog::rejected, this, &QPlatformDialogHelper::reject); + + connect(m_dialog.data(), &QFileDialog::fileSelected, [this](const QString &file) { + emit fileSelected(QUrl::fromLocalFile(file)); + }); + connect(m_dialog.data(), &QFileDialog::filesSelected, [this](const QList &files) { + QList urls; + urls.reserve(files.count()); + for (const QString &file : files) + urls += QUrl::fromLocalFile(file); + emit filesSelected(urls); + }); + connect(m_dialog.data(), &QFileDialog::currentChanged, [this](const QString &path) { + emit currentChanged(QUrl::fromLocalFile(path)); + }); + connect(m_dialog.data(), &QFileDialog::directoryEntered, this, &QWidgetPlatformFileDialog::directoryEntered); + connect(m_dialog.data(), &QFileDialog::filterSelected, this, &QWidgetPlatformFileDialog::filterSelected); +} + +QWidgetPlatformFileDialog::~QWidgetPlatformFileDialog() +{ +} + +bool QWidgetPlatformFileDialog::defaultNameFilterDisables() const +{ + return false; // TODO: ? +} + +void QWidgetPlatformFileDialog::setDirectory(const QUrl &directory) +{ + m_dialog->setDirectory(directory.toLocalFile()); +} + +QUrl QWidgetPlatformFileDialog::directory() const +{ + return m_dialog->directoryUrl(); +} + +void QWidgetPlatformFileDialog::selectFile(const QUrl &filename) +{ + m_dialog->selectUrl(filename); +} + +QList QWidgetPlatformFileDialog::selectedFiles() const +{ + return m_dialog->selectedUrls(); +} + +void QWidgetPlatformFileDialog::setFilter() +{ + // TODO: ? +} + +void QWidgetPlatformFileDialog::selectNameFilter(const QString &filter) +{ + m_dialog->selectNameFilter(filter); +} + +QString QWidgetPlatformFileDialog::selectedNameFilter() const +{ + return m_dialog->selectedNameFilter(); +} + +void QWidgetPlatformFileDialog::exec() +{ + m_dialog->exec(); +} + +bool QWidgetPlatformFileDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) +{ + QSharedPointer options = QPlatformFileDialogHelper::options(); + m_dialog->setWindowTitle(options->windowTitle()); + m_dialog->setAcceptMode(static_cast(options->acceptMode())); + m_dialog->setFileMode(static_cast(options->fileMode())); + m_dialog->setOptions(static_cast(int(options->options())) | QFileDialog::DontUseNativeDialog); + m_dialog->setNameFilters(options->nameFilters()); + m_dialog->setDefaultSuffix(options->defaultSuffix()); + if (options->isLabelExplicitlySet(QFileDialogOptions::Accept)) + m_dialog->setLabelText(QFileDialog::Accept, options->labelText(QFileDialogOptions::Accept)); + if (options->isLabelExplicitlySet(QFileDialogOptions::Reject)) + m_dialog->setLabelText(QFileDialog::Reject, options->labelText(QFileDialogOptions::Reject)); + + return QWidgetPlatformDialog::show(m_dialog.data(), flags, modality, parent); +} + +void QWidgetPlatformFileDialog::hide() +{ + m_dialog->hide(); +} + +QT_END_NAMESPACE + +#include "moc_qwidgetplatformfiledialog_p.cpp" diff --git a/src/labs/platform/widgets/qwidgetplatformfiledialog_p.h b/src/labs/platform/widgets/qwidgetplatformfiledialog_p.h new file mode 100644 index 00000000000..3dba6038456 --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformfiledialog_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWIDGETPLATFORMFILEDIALOG_P_H +#define QWIDGETPLATFORMFILEDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +class QFileDialog; + +class QWidgetPlatformFileDialog : public QPlatformFileDialogHelper +{ + Q_OBJECT + +public: + explicit QWidgetPlatformFileDialog(QObject *parent = nullptr); + ~QWidgetPlatformFileDialog(); + + bool defaultNameFilterDisables() const override; + void setDirectory(const QUrl &directory) override; + QUrl directory() const override; + void selectFile(const QUrl &filename) override; + QList selectedFiles() const override; + void setFilter() override; + void selectNameFilter(const QString &filter) override; + QString selectedNameFilter() const override; + + void exec() override; + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) override; + void hide() override; + +private: + QScopedPointer m_dialog; +}; + +QT_END_NAMESPACE + +#endif // QWIDGETPLATFORMFILEDIALOG_P_H diff --git a/src/labs/platform/widgets/qwidgetplatformfontdialog.cpp b/src/labs/platform/widgets/qwidgetplatformfontdialog.cpp new file mode 100644 index 00000000000..ba24e7433e1 --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformfontdialog.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwidgetplatformfontdialog_p.h" +#include "qwidgetplatformdialog_p.h" + +#include + +QT_BEGIN_NAMESPACE + +QWidgetPlatformFontDialog::QWidgetPlatformFontDialog(QObject *parent) + : m_dialog(new QFontDialog) +{ + setParent(parent); + + connect(m_dialog.data(), &QFontDialog::accepted, this, &QPlatformDialogHelper::accept); + connect(m_dialog.data(), &QFontDialog::rejected, this, &QPlatformDialogHelper::reject); + connect(m_dialog.data(), &QFontDialog::currentFontChanged, this, &QPlatformFontDialogHelper::currentFontChanged); +} + +QWidgetPlatformFontDialog::~QWidgetPlatformFontDialog() +{ +} + +QFont QWidgetPlatformFontDialog::currentFont() const +{ + return m_dialog->currentFont(); +} + +void QWidgetPlatformFontDialog::setCurrentFont(const QFont &font) +{ + m_dialog->setCurrentFont(font); +} + +void QWidgetPlatformFontDialog::exec() +{ + m_dialog->exec(); +} + +bool QWidgetPlatformFontDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) +{ + QSharedPointer options = QPlatformFontDialogHelper::options(); + m_dialog->setWindowTitle(options->windowTitle()); + m_dialog->setOptions(static_cast(int(options->options())) | QFontDialog::DontUseNativeDialog); + + return QWidgetPlatformDialog::show(m_dialog.data(), flags, modality, parent); +} + +void QWidgetPlatformFontDialog::hide() +{ + m_dialog->hide(); +} + +QT_END_NAMESPACE + +#include "moc_qwidgetplatformfontdialog_p.cpp" diff --git a/src/labs/platform/widgets/qwidgetplatformfontdialog_p.h b/src/labs/platform/widgets/qwidgetplatformfontdialog_p.h new file mode 100644 index 00000000000..e5d13b31e67 --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformfontdialog_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWIDGETPLATFORMFONTDIALOG_P_H +#define QWIDGETPLATFORMFONTDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +class QFontDialog; + +class QWidgetPlatformFontDialog : public QPlatformFontDialogHelper +{ + Q_OBJECT + +public: + explicit QWidgetPlatformFontDialog(QObject *parent = nullptr); + ~QWidgetPlatformFontDialog(); + + QFont currentFont() const override; + void setCurrentFont(const QFont &font) override; + + void exec() override; + bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override; + void hide() override; + +private: + QScopedPointer m_dialog; +}; + +QT_END_NAMESPACE + +#endif // QWIDGETPLATFORMFONTDIALOG_P_H diff --git a/src/labs/platform/widgets/qwidgetplatformmenu.cpp b/src/labs/platform/widgets/qwidgetplatformmenu.cpp new file mode 100644 index 00000000000..5cb36eacdbc --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformmenu.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwidgetplatformmenu_p.h" +#include "qwidgetplatformmenuitem_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QWidgetPlatformMenu::QWidgetPlatformMenu(QObject *parent) + : m_menu(new QMenu) +{ + setParent(parent); + + connect(m_menu.data(), &QMenu::aboutToShow, this, &QPlatformMenu::aboutToShow); + connect(m_menu.data(), &QMenu::aboutToHide, this, &QPlatformMenu::aboutToHide); +} + +QWidgetPlatformMenu::~QWidgetPlatformMenu() +{ +} + +QMenu *QWidgetPlatformMenu::menu() const +{ + return m_menu.data(); +} + +void QWidgetPlatformMenu::insertMenuItem(QPlatformMenuItem *item, QPlatformMenuItem *before) +{ + QWidgetPlatformMenuItem *widgetItem = qobject_cast(item); + if (!widgetItem) + return; + + QWidgetPlatformMenuItem *widgetBefore = qobject_cast(before); + m_menu->insertAction(widgetBefore ? widgetBefore->action() : nullptr, widgetItem->action()); + int index = m_items.indexOf(widgetBefore); + if (index < 0) + index = m_items.count(); + m_items.insert(index, widgetItem); +} + +void QWidgetPlatformMenu::removeMenuItem(QPlatformMenuItem *item) +{ + QWidgetPlatformMenuItem *widgetItem = qobject_cast(item); + if (!widgetItem) + return; + + m_items.removeOne(widgetItem); + m_menu->removeAction(widgetItem->action()); +} + +void QWidgetPlatformMenu::syncMenuItem(QPlatformMenuItem *item) +{ + Q_UNUSED(item); +} + +void QWidgetPlatformMenu::syncSeparatorsCollapsible(bool enable) +{ + m_menu->setSeparatorsCollapsible(enable); +} + +void QWidgetPlatformMenu::setText(const QString &text) +{ + m_menu->setTitle(text); +} + +void QWidgetPlatformMenu::setIcon(const QIcon &icon) +{ + m_menu->setIcon(icon); +} + +void QWidgetPlatformMenu::setEnabled(bool enabled) +{ + m_menu->menuAction()->setEnabled(enabled); +} + +bool QWidgetPlatformMenu::isEnabled() const +{ + return m_menu->menuAction()->isEnabled(); +} + +void QWidgetPlatformMenu::setVisible(bool visible) +{ + m_menu->menuAction()->setVisible(visible); +} + +void QWidgetPlatformMenu::setMinimumWidth(int width) +{ + if (width > 0) + m_menu->setMinimumWidth(width); +} + +void QWidgetPlatformMenu::setFont(const QFont &font) +{ + m_menu->setFont(font); +} + +void QWidgetPlatformMenu::setMenuType(MenuType type) +{ + Q_UNUSED(type); +} + +void QWidgetPlatformMenu::showPopup(const QWindow *window, const QRect &targetRect, const QPlatformMenuItem *item) +{ + m_menu->createWinId(); + QWindow *handle = m_menu->windowHandle(); + Q_ASSERT(handle); + handle->setTransientParent(const_cast(window)); + + QPoint targetPos = targetRect.bottomLeft(); + if (window) + targetPos = window->mapToGlobal(targetPos); + + const QWidgetPlatformMenuItem *widgetItem = qobject_cast(item); + m_menu->popup(targetPos, widgetItem ? widgetItem->action() : nullptr); +} + +void QWidgetPlatformMenu::dismiss() +{ + m_menu->close(); +} + +QPlatformMenuItem *QWidgetPlatformMenu::menuItemAt(int position) const +{ + return m_items.value(position); +} + +QPlatformMenuItem *QWidgetPlatformMenu::menuItemForTag(quintptr tag) const +{ + for (QWidgetPlatformMenuItem *item : m_items) { + if (item->tag() == tag) + return item; + } + return nullptr; +} + +QPlatformMenuItem *QWidgetPlatformMenu::createMenuItem() const +{ + return new QWidgetPlatformMenuItem; +} + +QPlatformMenu *QWidgetPlatformMenu::createSubMenu() const +{ + return new QWidgetPlatformMenu; +} + +QT_END_NAMESPACE + +#include "moc_qwidgetplatformmenu_p.cpp" diff --git a/src/labs/platform/widgets/qwidgetplatformmenu_p.h b/src/labs/platform/widgets/qwidgetplatformmenu_p.h new file mode 100644 index 00000000000..9d1ef57e2fe --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformmenu_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWIDGETPLATFORMMENU_P_H +#define QWIDGETPLATFORMMENU_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +class QMenu; +class QWidgetPlatformMenuItem; + +class QWidgetPlatformMenu : public QPlatformMenu +{ + Q_OBJECT + +public: + explicit QWidgetPlatformMenu(QObject *parent = nullptr); + ~QWidgetPlatformMenu(); + + QMenu *menu() const; + + void insertMenuItem(QPlatformMenuItem *item, QPlatformMenuItem *before) override; + void removeMenuItem(QPlatformMenuItem *item) override; + void syncMenuItem(QPlatformMenuItem *item) override; + void syncSeparatorsCollapsible(bool enable) override; + + void setText(const QString &text) override; + void setIcon(const QIcon &icon) override; + void setEnabled(bool enabled) override; + bool isEnabled() const override; + void setVisible(bool visible) override; + void setMinimumWidth(int width) override; + void setFont(const QFont &font) override; + void setMenuType(MenuType type) override; + + void showPopup(const QWindow *window, const QRect &targetRect, const QPlatformMenuItem *item) override; + void dismiss() override; + + QPlatformMenuItem *menuItemAt(int position) const override; + QPlatformMenuItem *menuItemForTag(quintptr tag) const override; + + QPlatformMenuItem *createMenuItem() const override; + QPlatformMenu *createSubMenu() const override; + +private: + QScopedPointer m_menu; + QList m_items; +}; + +QT_END_NAMESPACE + +#endif // QWIDGETPLATFORMMENU_P_H diff --git a/src/labs/platform/widgets/qwidgetplatformmenuitem.cpp b/src/labs/platform/widgets/qwidgetplatformmenuitem.cpp new file mode 100644 index 00000000000..3539c179616 --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformmenuitem.cpp @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwidgetplatformmenuitem_p.h" +#include "qwidgetplatformmenu_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +QWidgetPlatformMenuItem::QWidgetPlatformMenuItem(QObject *parent) + : m_action(new QAction) +{ + setParent(parent); + connect(m_action.data(), &QAction::hovered, this, &QPlatformMenuItem::hovered); + connect(m_action.data(), &QAction::triggered, this, &QPlatformMenuItem::activated); +} + +QWidgetPlatformMenuItem::~QWidgetPlatformMenuItem() +{ +} + +QAction *QWidgetPlatformMenuItem::action() const +{ + return m_action.data(); +} + +void QWidgetPlatformMenuItem::setText(const QString &text) +{ + m_action->setText(text); +} + +void QWidgetPlatformMenuItem::setIcon(const QIcon &icon) +{ + m_action->setIcon(icon); +} + +void QWidgetPlatformMenuItem::setMenu(QPlatformMenu *menu) +{ + QWidgetPlatformMenu *widgetMenu = qobject_cast(menu); + m_action->setMenu(widgetMenu ? widgetMenu->menu() : nullptr); +} + +void QWidgetPlatformMenuItem::setVisible(bool visible) +{ + m_action->setVisible(visible); +} + +void QWidgetPlatformMenuItem::setIsSeparator(bool separator) +{ + m_action->setSeparator(separator); +} + +void QWidgetPlatformMenuItem::setFont(const QFont &font) +{ + m_action->setFont(font); +} + +void QWidgetPlatformMenuItem::setRole(MenuRole role) +{ + m_action->setMenuRole(static_cast(role)); +} + +void QWidgetPlatformMenuItem::setCheckable(bool checkable) +{ + m_action->setCheckable(checkable); +} + +void QWidgetPlatformMenuItem::setChecked(bool checked) +{ + m_action->setChecked(checked); +} + +#if QT_CONFIG(shortcut) +void QWidgetPlatformMenuItem::setShortcut(const QKeySequence &shortcut) +{ + m_action->setShortcut(shortcut); +} +#endif + +void QWidgetPlatformMenuItem::setEnabled(bool enabled) +{ + m_action->setEnabled(enabled); +} + +void QWidgetPlatformMenuItem::setIconSize(int size) +{ + Q_UNUSED(size); +} + +QT_END_NAMESPACE + +#include "moc_qwidgetplatformmenuitem_p.cpp" diff --git a/src/labs/platform/widgets/qwidgetplatformmenuitem_p.h b/src/labs/platform/widgets/qwidgetplatformmenuitem_p.h new file mode 100644 index 00000000000..43b3fc174e9 --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformmenuitem_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWIDGETPLATFORMMENUITEM_P_H +#define QWIDGETPLATFORMMENUITEM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +class QAction; + +class QWidgetPlatformMenuItem : public QPlatformMenuItem +{ + Q_OBJECT + +public: + explicit QWidgetPlatformMenuItem(QObject *parent = nullptr); + ~QWidgetPlatformMenuItem(); + + QAction *action() const; + + void setText(const QString &text) override; + void setIcon(const QIcon &icon) override; + void setMenu(QPlatformMenu *menu) override; + void setVisible(bool visible) override; + void setIsSeparator(bool separator) override; + void setFont(const QFont &font) override; + void setRole(MenuRole role) override; + void setCheckable(bool checkable) override; + void setChecked(bool checked) override; +#if QT_CONFIG(shortcut) + void setShortcut(const QKeySequence& shortcut) override; +#endif + void setEnabled(bool enabled) override; + void setIconSize(int size) override; + +private: + QScopedPointer m_action; +}; + +QT_END_NAMESPACE + +#endif // QWIDGETPLATFORMMENUITEM_P_H diff --git a/src/labs/platform/widgets/qwidgetplatformmessagedialog.cpp b/src/labs/platform/widgets/qwidgetplatformmessagedialog.cpp new file mode 100644 index 00000000000..f3d850eefb6 --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformmessagedialog.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwidgetplatformmessagedialog_p.h" +#include "qwidgetplatformdialog_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +QWidgetPlatformMessageDialog::QWidgetPlatformMessageDialog(QObject *parent) + : m_dialog(new QMessageBox) +{ + setParent(parent); + + connect(m_dialog.data(), &QMessageBox::accepted, this, &QPlatformDialogHelper::accept); + connect(m_dialog.data(), &QMessageBox::rejected, this, &QPlatformDialogHelper::reject); + connect(m_dialog.data(), &QMessageBox::buttonClicked, [this](QAbstractButton *button) { + QMessageBox::ButtonRole role = m_dialog->buttonRole(button); + QMessageBox::StandardButton standardButton = m_dialog->standardButton(button); + emit clicked(static_cast(standardButton), static_cast(role)); + }); +} + +QWidgetPlatformMessageDialog::~QWidgetPlatformMessageDialog() +{ +} +void QWidgetPlatformMessageDialog::exec() +{ + m_dialog->exec(); +} + +bool QWidgetPlatformMessageDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) +{ + QSharedPointer options = QPlatformMessageDialogHelper::options(); + m_dialog->setWindowTitle(options->windowTitle()); + m_dialog->setIcon(static_cast(options->icon())); + m_dialog->setText(options->text()); + m_dialog->setInformativeText(options->informativeText()); +#if QT_CONFIG(textedit) + m_dialog->setDetailedText(options->detailedText()); +#endif + m_dialog->setStandardButtons(static_cast(int(options->standardButtons()))); + + return QWidgetPlatformDialog::show(m_dialog.data(), flags, modality, parent); +} + +void QWidgetPlatformMessageDialog::hide() +{ + m_dialog->hide(); +} + +QT_END_NAMESPACE + +#include "moc_qwidgetplatformmessagedialog_p.cpp" diff --git a/src/labs/platform/widgets/qwidgetplatformmessagedialog_p.h b/src/labs/platform/widgets/qwidgetplatformmessagedialog_p.h new file mode 100644 index 00000000000..6581337ab3a --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformmessagedialog_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWIDGETPLATFORMMESSAGEDIALOG_P_H +#define QWIDGETPLATFORMMESSAGEDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +class QMessageBox; + +class QWidgetPlatformMessageDialog : public QPlatformMessageDialogHelper +{ + Q_OBJECT + +public: + explicit QWidgetPlatformMessageDialog(QObject *parent = nullptr); + ~QWidgetPlatformMessageDialog(); + + void exec() override; + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) override; + void hide() override; + +private: + QScopedPointer m_dialog; +}; + +QT_END_NAMESPACE + +#endif // QWIDGETPLATFORMMESSAGEDIALOG_P_H diff --git a/src/labs/platform/widgets/qwidgetplatformsystemtrayicon.cpp b/src/labs/platform/widgets/qwidgetplatformsystemtrayicon.cpp new file mode 100644 index 00000000000..76d814256ee --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformsystemtrayicon.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwidgetplatformsystemtrayicon_p.h" +#include "qwidgetplatformmenu_p.h" + +#include + +QT_BEGIN_NAMESPACE + +QWidgetPlatformSystemTrayIcon::QWidgetPlatformSystemTrayIcon(QObject *parent) + : m_systray(new QSystemTrayIcon) +{ + setParent(parent); + + connect(m_systray.data(), &QSystemTrayIcon::messageClicked, this, &QPlatformSystemTrayIcon::messageClicked); + connect(m_systray.data(), &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) { + emit activated(static_cast(reason)); + }); +} + +QWidgetPlatformSystemTrayIcon::~QWidgetPlatformSystemTrayIcon() +{ +} + +void QWidgetPlatformSystemTrayIcon::init() +{ + m_systray->show(); +} + +void QWidgetPlatformSystemTrayIcon::cleanup() +{ + m_systray->hide(); +} + +void QWidgetPlatformSystemTrayIcon::updateIcon(const QIcon &icon) +{ + m_systray->setIcon(icon); +} + +void QWidgetPlatformSystemTrayIcon::updateToolTip(const QString &tooltip) +{ + m_systray->setToolTip(tooltip); +} + +void QWidgetPlatformSystemTrayIcon::updateMenu(QPlatformMenu *menu) +{ +#if QT_CONFIG(menu) + QWidgetPlatformMenu *widgetMenu = qobject_cast(menu); + if (!widgetMenu) + return; + + m_systray->setContextMenu(widgetMenu->menu()); +#else + Q_UNUSED(menu); +#endif +} + +QRect QWidgetPlatformSystemTrayIcon::geometry() const +{ + return m_systray->geometry(); +} + +void QWidgetPlatformSystemTrayIcon::showMessage(const QString &title, const QString &msg, const QIcon &icon, MessageIcon iconType, int msecs) +{ + Q_UNUSED(icon); + m_systray->showMessage(title, msg, static_cast(iconType), msecs); +} + +bool QWidgetPlatformSystemTrayIcon::isSystemTrayAvailable() const +{ + return QSystemTrayIcon::isSystemTrayAvailable(); +} + +bool QWidgetPlatformSystemTrayIcon::supportsMessages() const +{ + return QSystemTrayIcon::supportsMessages(); +} + +QPlatformMenu *QWidgetPlatformSystemTrayIcon::createMenu() const +{ + return new QWidgetPlatformMenu; +} + +QT_END_NAMESPACE + +#include "moc_qwidgetplatformsystemtrayicon_p.cpp" diff --git a/src/labs/platform/widgets/qwidgetplatformsystemtrayicon_p.h b/src/labs/platform/widgets/qwidgetplatformsystemtrayicon_p.h new file mode 100644 index 00000000000..11ea5377b37 --- /dev/null +++ b/src/labs/platform/widgets/qwidgetplatformsystemtrayicon_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Platform module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWIDGETPLATFORMSYSTEMTRAYICON_P_H +#define QWIDGETPLATFORMSYSTEMTRAYICON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_REQUIRE_CONFIG(systemtrayicon); + +QT_BEGIN_NAMESPACE + +class QSystemTrayIcon; + +class QWidgetPlatformSystemTrayIcon : public QPlatformSystemTrayIcon +{ + Q_OBJECT + +public: + explicit QWidgetPlatformSystemTrayIcon(QObject *parent = nullptr); + ~QWidgetPlatformSystemTrayIcon(); + + void init() override; + void cleanup() override; + void updateIcon(const QIcon &icon) override; + void updateToolTip(const QString &tooltip) override; + void updateMenu(QPlatformMenu *menu) override; + QRect geometry() const override; + void showMessage(const QString &title, const QString &msg, + const QIcon &icon, MessageIcon iconType, int msecs) override; + + bool isSystemTrayAvailable() const override; + bool supportsMessages() const override; + + QPlatformMenu *createMenu() const override; + +private: + QScopedPointer m_systray; +}; + +QT_END_NAMESPACE + +#endif // QWIDGETPLATFORMSYSTEMTRAYICON_P_H diff --git a/src/labs/platform/widgets/widgets.pri b/src/labs/platform/widgets/widgets.pri new file mode 100644 index 00000000000..54ad7187cc5 --- /dev/null +++ b/src/labs/platform/widgets/widgets.pri @@ -0,0 +1,56 @@ +QT += widgets +DEPENDPATH += $$PWD + +HEADERS += \ + $$PWD/qwidgetplatform_p.h + +qtConfig(systemtrayicon) { + HEADERS += \ + $$PWD/qwidgetplatformsystemtrayicon_p.h + SOURCES += \ + $$PWD/qwidgetplatformsystemtrayicon.cpp +} + +qtConfig(colordialog) | qtConfig(filedialog) | qtConfig(fontdialog) | qtConfig(messagebox) { + HEADERS += \ + $$PWD/qwidgetplatformdialog_p.h + SOURCES += \ + $$PWD/qwidgetplatformdialog.cpp +} + +qtConfig(colordialog) { + HEADERS += \ + $$PWD/qwidgetplatformcolordialog_p.h + SOURCES += \ + $$PWD/qwidgetplatformcolordialog.cpp +} + +qtConfig(filedialog) { + HEADERS += \ + $$PWD/qwidgetplatformfiledialog_p.h + SOURCES += \ + $$PWD/qwidgetplatformfiledialog.cpp +} + +qtConfig(fontdialog) { + HEADERS += \ + $$PWD/qwidgetplatformfontdialog_p.h + SOURCES += \ + $$PWD/qwidgetplatformfontdialog.cpp +} + +qtConfig(menu) { + HEADERS += \ + $$PWD/qwidgetplatformmenu_p.h \ + $$PWD/qwidgetplatformmenuitem_p.h + SOURCES += \ + $$PWD/qwidgetplatformmenu.cpp \ + $$PWD/qwidgetplatformmenuitem.cpp +} + +qtConfig(messagebox) { + HEADERS += \ + $$PWD/qwidgetplatformmessagedialog_p.h + SOURCES += \ + $$PWD/qwidgetplatformmessagedialog.cpp +} diff --git a/src/labs/settings/qqmlsettingsglobal_p.h b/src/labs/settings/qqmlsettingsglobal_p.h index c0bea2585e5..16a90de5a6e 100644 --- a/src/labs/settings/qqmlsettingsglobal_p.h +++ b/src/labs/settings/qqmlsettingsglobal_p.h @@ -68,6 +68,4 @@ QT_BEGIN_NAMESPACE QT_END_NAMESPACE -void Q_LABSSETTINGS_PRIVATE_EXPORT qml_register_types_Qt_labs_settings(); - #endif // QTLABSSETTINGSGLOBAL_P_H diff --git a/src/labs/sharedimage/doc/src/qsharedimage.qdoc b/src/labs/sharedimage/doc/src/qsharedimage.qdoc index 119f49bf915..bb3cafebfe6 100644 --- a/src/labs/sharedimage/doc/src/qsharedimage.qdoc +++ b/src/labs/sharedimage/doc/src/qsharedimage.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \qmlmodule Qt.labs.sharedimage 1 + \qmlmodule Qt.labs.sharedimage \title Qt Quick Shared Image Provider \ingroup qmlmodules \brief Adds an image provider which utilizes shared CPU memory diff --git a/src/labs/sharedimage/qsharedimageloader.cpp b/src/labs/sharedimage/qsharedimageloader.cpp index c9e3ef3eb3b..c37c4b890ed 100644 --- a/src/labs/sharedimage/qsharedimageloader.cpp +++ b/src/labs/sharedimage/qsharedimageloader.cpp @@ -264,3 +264,5 @@ QString QSharedImageLoader::key(const QString &path, ImageParameters *params) QT_END_NAMESPACE + +#include "moc_qsharedimageloader_p.cpp" diff --git a/src/labs/sharedimage/qsharedimageprovider.cpp b/src/labs/sharedimage/qsharedimageprovider.cpp index 74822a4e87b..402bebfd71f 100644 --- a/src/labs/sharedimage/qsharedimageprovider.cpp +++ b/src/labs/sharedimage/qsharedimageprovider.cpp @@ -46,6 +46,7 @@ Q_DECLARE_METATYPE(QQuickImageProviderOptions) +QT_BEGIN_NAMESPACE QuickSharedImageLoader::QuickSharedImageLoader(QObject *parent) : QSharedImageLoader(parent) {} @@ -137,3 +138,7 @@ QImage SharedImageProvider::requestImage(const QString &id, QSize *size, const Q return img; } + +QT_END_NAMESPACE + +#include "moc_qsharedimageprovider_p.cpp" diff --git a/src/labs/sharedimage/qsharedimageprovider_p.h b/src/labs/sharedimage/qsharedimageprovider_p.h index f8bea9e7849..d590372bf4e 100644 --- a/src/labs/sharedimage/qsharedimageprovider_p.h +++ b/src/labs/sharedimage/qsharedimageprovider_p.h @@ -59,6 +59,8 @@ #include "qsharedimageloader_p.h" +QT_BEGIN_NAMESPACE + class SharedImageProvider; class QuickSharedImageLoader : public QSharedImageLoader @@ -90,4 +92,7 @@ class Q_LABSSHAREDIMAGE_PRIVATE_EXPORT SharedImageProvider : public QQuickImageP protected: QScopedPointer loader; }; + +QT_END_NAMESPACE + #endif // QSHAREDIMAGEPROVIDER_H diff --git a/src/labs/wavefrontmesh/CMakeLists.txt b/src/labs/wavefrontmesh/CMakeLists.txt index 7a6c7a5cc09..2063f6fb4d4 100644 --- a/src/labs/wavefrontmesh/CMakeLists.txt +++ b/src/labs/wavefrontmesh/CMakeLists.txt @@ -3,6 +3,8 @@ qt_internal_add_qml_module(LabsWavefrontMesh VERSION "${PROJECT_VERSION}" PLUGIN_TARGET qmlwavefrontmeshplugin CLASS_NAME QmlWavefrontMeshPlugin + DEPENDENCIES + QtQuick SOURCES qwavefrontmesh.cpp qwavefrontmesh_p.h qqmlwavefrontmeshglobal_p.h diff --git a/src/labs/wavefrontmesh/qqmlwavefrontmeshglobal_p.h b/src/labs/wavefrontmesh/qqmlwavefrontmeshglobal_p.h index ca57c1f7f36..81296535b4c 100644 --- a/src/labs/wavefrontmesh/qqmlwavefrontmeshglobal_p.h +++ b/src/labs/wavefrontmesh/qqmlwavefrontmeshglobal_p.h @@ -68,6 +68,4 @@ QT_BEGIN_NAMESPACE QT_END_NAMESPACE -void Q_LABSWAVEFRONTMESH_PRIVATE_EXPORT qml_register_types_Qt_labs_wavefrontmesh(); - #endif // QTLABSWAVEFRONTMESHGLOBAL_P_H diff --git a/src/labs/wavefrontmesh/qwavefrontmesh.cpp b/src/labs/wavefrontmesh/qwavefrontmesh.cpp index 472b6635093..5f5f6c4bfae 100644 --- a/src/labs/wavefrontmesh/qwavefrontmesh.cpp +++ b/src/labs/wavefrontmesh/qwavefrontmesh.cpp @@ -695,3 +695,5 @@ QVector3D QWavefrontMesh::projectionPlaneW() const QT_END_NAMESPACE + +#include "moc_qwavefrontmesh_p.cpp" diff --git a/src/particles/CMakeLists.txt b/src/particles/CMakeLists.txt index 076cac11e01..9e98783638a 100644 --- a/src/particles/CMakeLists.txt +++ b/src/particles/CMakeLists.txt @@ -2,7 +2,7 @@ ## QuickParticles Module: ##################################################################### -qt_internal_add_qml_module(QuickParticles +qt_internal_add_qml_module(QuickParticlesPrivate URI "QtQuick.Particles" VERSION "${PROJECT_VERSION}" PLUGIN_TARGET particlesplugin @@ -58,7 +58,7 @@ set(particles_resource_files "particleresources/star.png" ) -qt_internal_add_resource(QuickParticles "particles" +qt_internal_add_resource(QuickParticlesPrivate "particles" PREFIX "/" FILES @@ -79,14 +79,14 @@ set(particles1_resource_files "shaders_ng/imageparticle_tabled.vert.qsb" ) -qt_internal_add_resource(QuickParticles "particles1" +qt_internal_add_resource(QuickParticlesPrivate "particles1" PREFIX "/particles" FILES ${particles1_resource_files} ) -qt_internal_extend_target(QuickParticles CONDITION MSVC +qt_internal_extend_target(QuickParticlesPrivate CONDITION MSVC DEFINES _CRT_SECURE_NO_WARNINGS ) @@ -94,7 +94,7 @@ qt_internal_extend_target(QuickParticles CONDITION MSVC #### Keys ignored in scope 3:.:.:particles.pro:solaris-cc_x_: # QMAKE_CXXFLAGS_RELEASE = "--O2" -qt_internal_extend_target(QuickParticles CONDITION EXISTS "qqml_enable_gcov" +qt_internal_extend_target(QuickParticlesPrivate CONDITION EXISTS "qqml_enable_gcov" LIBRARIES gcov COMPILE_OPTIONS diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp index 884edc3390d..75e710cdb36 100644 --- a/src/particles/qquickimageparticle.cpp +++ b/src/particles/qquickimageparticle.cpp @@ -687,13 +687,12 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size) For fine-grained control, see sizeTable and opacityTable. Acceptable values are - \list - \li ImageParticle.None: Particles just appear and disappear. - \li ImageParticle.Fade: Particles fade in from 0 opacity at the start of their life, and fade out to 0 at the end. - \li ImageParticle.Scale: Particles scale in from 0 size at the start of their life, and scale back to 0 at the end. - \endlist - Default value is Fade. + \value ImageParticle.None Particles just appear and disappear. + \value ImageParticle.Fade Particles fade in from 0 opacity at the start of their life, and fade out to 0 at the end. + \value ImageParticle.Scale Particles scale in from 0 size at the start of their life, and scale back to 0 at the end. + + The default value is \c ImageParticle.Fade. */ /*! \qmlproperty bool QtQuick.Particles::ImageParticle::spritesInterpolate @@ -766,6 +765,7 @@ void QQuickImageParticle::sceneGraphInvalidated() m_material = nullptr; delete m_outgoingNode; m_outgoingNode = nullptr; + m_apiChecked = false; } void QQuickImageParticle::setImage(const QUrl &image) @@ -1074,6 +1074,12 @@ void QQuickImageParticle::reset() update(); } + +void QQuickImageParticle::invalidateSceneGraph() +{ + reset(); +} + void QQuickImageParticle::createEngine() { if (m_spriteEngine) diff --git a/src/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h index 19000f6c9bd..03a96b79013 100644 --- a/src/particles/qquickimageparticle_p.h +++ b/src/particles/qquickimageparticle_p.h @@ -395,6 +395,8 @@ private Q_SLOTS: void spritesUpdate(qreal time = 0 ); void mainThreadFetchImageData(); void finishBuildParticleNodes(QSGNode **n); + void invalidateSceneGraph(); + private: struct ImageData { QUrl source; diff --git a/src/particles/qquickparticlesystem.cpp b/src/particles/qquickparticlesystem.cpp index 5806d7914c1..5744c61849d 100644 --- a/src/particles/qquickparticlesystem.cpp +++ b/src/particles/qquickparticlesystem.cpp @@ -767,10 +767,9 @@ void QQuickParticleSystem::reset() timeInt = 0; //Clear guarded pointers which have been deleted - int cleared = 0; - cleared += m_emitters.removeAll(nullptr); - cleared += m_painters.removeAll(nullptr); - cleared += m_affectors.removeAll(nullptr); + m_emitters.removeAll(nullptr); + m_painters.removeAll(nullptr); + m_affectors.removeAll(nullptr); bySysIdx.resize(0); initGroups();//Also clears all logical particles diff --git a/src/particles/qtquickparticlesglobal_p.h b/src/particles/qtquickparticlesglobal_p.h index 927bc29050d..d7647b3d97d 100644 --- a/src/particles/qtquickparticlesglobal_p.h +++ b/src/particles/qtquickparticlesglobal_p.h @@ -65,6 +65,4 @@ # define Q_QUICKPARTICLES_PRIVATE_EXPORT #endif -void Q_QUICKPARTICLES_PRIVATE_EXPORT qml_register_types_QtQuick_Particles(); - #endif // QTQUICKPARTICLESGLOBAL_P_H diff --git a/src/particles/shaders_ng/imageparticle.frag b/src/particles/shaders_ng/imageparticle.frag index 90b79e6ea9c..074771f4fd8 100644 --- a/src/particles/shaders_ng/imageparticle.frag +++ b/src/particles/shaders_ng/imageparticle.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 #if defined(TABLE) diff --git a/src/plugins/qmltooling/packetprotocol/CMakeLists.txt b/src/plugins/qmltooling/packetprotocol/CMakeLists.txt index 30e42963658..bac9e735a15 100644 --- a/src/plugins/qmltooling/packetprotocol/CMakeLists.txt +++ b/src/plugins/qmltooling/packetprotocol/CMakeLists.txt @@ -1,10 +1,10 @@ # Generated from packetprotocol.pro. ##################################################################### -## PacketProtocol Module: +## PacketProtocolPrivate Module: ##################################################################### -qt_internal_add_module(PacketProtocol +qt_internal_add_module(PacketProtocolPrivate STATIC INTERNAL_MODULE SOURCES diff --git a/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp index 3e75e39f869..c89fb86aecc 100644 --- a/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp +++ b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp @@ -324,3 +324,5 @@ bool QPacketProtocolPrivate::readFromDevice(char *buffer, qint64 size) */ QT_END_NAMESPACE + +#include "moc_qpacketprotocol_p.cpp" diff --git a/src/plugins/qmltooling/qmldbg_debugger/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_debugger/CMakeLists.txt index de3f663d09d..67e408e8aab 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/CMakeLists.txt +++ b/src/plugins/qmltooling/qmldbg_debugger/CMakeLists.txt @@ -4,9 +4,10 @@ ## QQmlDebuggerServiceFactory Plugin: ##################################################################### -qt_internal_add_plugin(QQmlDebuggerServiceFactory +qt_internal_add_plugin(QQmlDebuggerServiceFactoryPlugin OUTPUT_NAME qmldbg_debugger - TYPE qmltooling + CLASS_NAME QQmlDebuggerServiceFactory + PLUGIN_TYPE qmltooling SOURCES qqmldebuggerservicefactory.cpp qqmldebuggerservicefactory.h qqmlenginedebugservice.cpp qqmlenginedebugservice.h @@ -16,7 +17,7 @@ qt_internal_add_plugin(QQmlDebuggerServiceFactory qv4debuggeragent.cpp qv4debuggeragent.h qv4debugjob.cpp qv4debugjob.h qv4debugservice.cpp qv4debugservice.h - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::PacketProtocolPrivate Qt::QmlPrivate diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp index 3851cdc71f5..c28bf0aaffc 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp @@ -56,3 +56,5 @@ QQmlDebugService *QQmlDebuggerServiceFactory::create(const QString &key) } QT_END_NAMESPACE + +#include "moc_qqmldebuggerservicefactory.cpp" diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp index 3afda162e60..89baceeb36d 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp @@ -808,9 +808,9 @@ bool QQmlEngineDebugServiceImpl::setMethodBody(int objectId, const QString &meth int lineNumber = 0; QV4::ScopedFunctionObject oldMethod(scope, vmeMetaObject->vmeMethod(prop->coreIndex())); - if (oldMethod && oldMethod->d()->function) { - lineNumber = oldMethod->d()->function->compiledFunction->location.line; - } + if (oldMethod && oldMethod->d()->function) + lineNumber = oldMethod->d()->function->compiledFunction->location.line(); + QV4::ScopedValue v(scope, QQmlJavaScriptExpression::evalFunction(contextData, object, jsfunction, contextData->urlString(), lineNumber)); vmeMetaObject->setVmeMethod(prop->coreIndex(), v); return true; diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp index ae502250353..9c83f8c1fd0 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp @@ -224,9 +224,10 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr) QV4::ScopedValue v(scope); QV4::Heap::InternalClass *ic = ctxt->internalClass(); for (uint i = 0; i < ic->size; ++i) { - QString name = ic->keyAt(i); - names.append(name); - v = static_cast(ctxt->d())->locals[i]; + QV4::ScopedValue stringOrSymbol(scope, ic->keyAt(i)); + QV4::ScopedString propName(scope, stringOrSymbol->toString(scope.engine)); + names.append(propName->toQString()); + v = ctxt->getProperty(propName); collectedRefs.append(addValueRef(v)); } diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp index e0c24979a95..381f09742a9 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp @@ -211,8 +211,8 @@ void ValueLookupJob::run() QScopedPointer scopeObject; QV4::ExecutionEngine *engine = collector->engine(); QV4::Scope scope(engine); - QV4::Heap::ExecutionContext *qmlContext = nullptr; - if (engine->qmlEngine() && !engine->qmlContext()) { + QV4::Heap::ExecutionContext *qmlContext = engine->qmlContext(); + if (engine->qmlEngine() && !qmlContext) { scopeObject.reset(new QObject); qmlContext = QV4::QmlContext::create(engine->currentContext(), QQmlContextData::get(engine->qmlEngine()->rootContext()), diff --git a/src/plugins/qmltooling/qmldbg_inspector/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_inspector/CMakeLists.txt index da79890824c..40eee66b2ee 100644 --- a/src/plugins/qmltooling/qmldbg_inspector/CMakeLists.txt +++ b/src/plugins/qmltooling/qmldbg_inspector/CMakeLists.txt @@ -4,9 +4,10 @@ ## QQmlInspectorServiceFactory Plugin: ##################################################################### -qt_internal_add_plugin(QQmlInspectorServiceFactory +qt_internal_add_plugin(QQmlInspectorServiceFactoryPlugin OUTPUT_NAME qmldbg_inspector - TYPE qmltooling + CLASS_NAME QQmlInspectorServiceFactory + PLUGIN_TYPE qmltooling SOURCES globalinspector.cpp globalinspector.h highlight.cpp highlight.h @@ -14,7 +15,7 @@ qt_internal_add_plugin(QQmlInspectorServiceFactory qqmlinspectorservice.cpp qqmlinspectorservicefactory.h qquickwindowinspector.cpp qquickwindowinspector.h - PUBLIC_LIBRARIES + LIBRARIES Qt::Core Qt::CorePrivate Qt::Gui diff --git a/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp index 301db599526..741cbe8f5ae 100644 --- a/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp +++ b/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp @@ -407,4 +407,6 @@ GlobalInspector::~GlobalInspector() QT_END_NAMESPACE +#include "moc_globalinspector.cpp" + #include diff --git a/src/plugins/qmltooling/qmldbg_local/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_local/CMakeLists.txt index faeef01111a..82fb91d4231 100644 --- a/src/plugins/qmltooling/qmldbg_local/CMakeLists.txt +++ b/src/plugins/qmltooling/qmldbg_local/CMakeLists.txt @@ -4,13 +4,14 @@ ## QLocalClientConnectionFactory Plugin: ##################################################################### -qt_internal_add_plugin(QLocalClientConnectionFactory +qt_internal_add_plugin(QLocalClientConnectionFactoryPlugin OUTPUT_NAME qmldbg_local - TYPE qmltooling + CLASS_NAME QLocalClientConnectionFactory + PLUGIN_TYPE qmltooling SOURCES qlocalclientconnection.cpp qlocalclientconnectionfactory.h - PUBLIC_LIBRARIES + LIBRARIES Qt::QmlPrivate ) diff --git a/src/plugins/qmltooling/qmldbg_messages/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_messages/CMakeLists.txt index 7785a4c8ede..9587709f1db 100644 --- a/src/plugins/qmltooling/qmldbg_messages/CMakeLists.txt +++ b/src/plugins/qmltooling/qmldbg_messages/CMakeLists.txt @@ -4,13 +4,14 @@ ## QDebugMessageServiceFactory Plugin: ##################################################################### -qt_internal_add_plugin(QDebugMessageServiceFactory +qt_internal_add_plugin(QDebugMessageServiceFactoryPlugin OUTPUT_NAME qmldbg_messages - TYPE qmltooling + CLASS_NAME QDebugMessageServiceFactory + PLUGIN_TYPE qmltooling SOURCES qdebugmessageservice.cpp qdebugmessageservice.h qdebugmessageservicefactory.cpp qdebugmessageservicefactory.h - PUBLIC_LIBRARIES + LIBRARIES Qt::Core Qt::PacketProtocolPrivate Qt::QmlPrivate diff --git a/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp index 4f6cb9364da..2de805d40d5 100644 --- a/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp +++ b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp @@ -106,3 +106,5 @@ void QDebugMessageServiceImpl::synchronizeTime(const QElapsedTimer &otherTimer) } QT_END_NAMESPACE + +#include "moc_qdebugmessageservice.cpp" diff --git a/src/plugins/qmltooling/qmldbg_native/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_native/CMakeLists.txt index 37447f593ac..1e300ba8070 100644 --- a/src/plugins/qmltooling/qmldbg_native/CMakeLists.txt +++ b/src/plugins/qmltooling/qmldbg_native/CMakeLists.txt @@ -4,12 +4,13 @@ ## QQmlNativeDebugConnectorFactory Plugin: ##################################################################### -qt_internal_add_plugin(QQmlNativeDebugConnectorFactory +qt_internal_add_plugin(QQmlNativeDebugConnectorFactoryPlugin OUTPUT_NAME qmldbg_native - TYPE qmltooling + CLASS_NAME QQmlNativeDebugConnectorFactory + PLUGIN_TYPE qmltooling SOURCES qqmlnativedebugconnector.cpp qqmlnativedebugconnector.h - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::PacketProtocolPrivate Qt::QmlPrivate diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_nativedebugger/CMakeLists.txt index b26b66ec6b3..ccfcd7e183c 100644 --- a/src/plugins/qmltooling/qmldbg_nativedebugger/CMakeLists.txt +++ b/src/plugins/qmltooling/qmldbg_nativedebugger/CMakeLists.txt @@ -4,13 +4,14 @@ ## QQmlNativeDebugServiceFactory Plugin: ##################################################################### -qt_internal_add_plugin(QQmlNativeDebugServiceFactory +qt_internal_add_plugin(QQmlNativeDebugServiceFactoryPlugin OUTPUT_NAME qmldbg_nativedebugger - TYPE qmltooling + CLASS_NAME QQmlNativeDebugServiceFactory + PLUGIN_TYPE qmltooling SOURCES qqmlnativedebugservice.cpp qqmlnativedebugservice.h qqmlnativedebugservicefactory.cpp qqmlnativedebugservicefactory.h - PUBLIC_LIBRARIES + LIBRARIES Qt::Core Qt::PacketProtocolPrivate Qt::QmlPrivate diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp index 85b6bac2032..ca8f3e31451 100644 --- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp @@ -493,9 +493,10 @@ void NativeDebugger::handleVariables(QJsonObject *response, const QJsonObject &a QV4::Heap::InternalClass *ic = callContext->internalClass(); QV4::ScopedValue v(scope); for (uint i = 0; i < ic->size; ++i) { - QString name = ic->keyAt(i); - v = callContext->d()->locals[i]; - collector.collect(&output, QString(), name, v); + QV4::ScopedValue stringOrSymbol(scope, ic->keyAt(i)); + QV4::ScopedString propName(scope, stringOrSymbol->toString(scope.engine)); + v = callContext->getProperty(propName); + collector.collect(&output, QString(), propName->toQString(), v); } } diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservicefactory.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservicefactory.cpp index c0b74c74ff2..f3990f7e57d 100644 --- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservicefactory.cpp +++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservicefactory.cpp @@ -52,3 +52,5 @@ QQmlDebugService *QQmlNativeDebugServiceFactory::create(const QString &key) } QT_END_NAMESPACE + +#include "moc_qqmlnativedebugservicefactory.cpp" diff --git a/src/plugins/qmltooling/qmldbg_preview/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_preview/CMakeLists.txt index 2b3611b90d3..7ebbf09dde1 100644 --- a/src/plugins/qmltooling/qmldbg_preview/CMakeLists.txt +++ b/src/plugins/qmltooling/qmldbg_preview/CMakeLists.txt @@ -4,9 +4,10 @@ ## QQmlPreviewServiceFactory Plugin: ##################################################################### -qt_internal_add_plugin(QQmlPreviewServiceFactory +qt_internal_add_plugin(QQmlPreviewServiceFactoryPlugin OUTPUT_NAME qmldbg_preview - TYPE qmltooling + CLASS_NAME QQmlPreviewServiceFactory + PLUGIN_TYPE qmltooling SOURCES qqmlpreviewblacklist.cpp qqmlpreviewblacklist.h qqmlpreviewfileengine.cpp qqmlpreviewfileengine.h @@ -15,7 +16,7 @@ qt_internal_add_plugin(QQmlPreviewServiceFactory qqmlpreviewposition.cpp qqmlpreviewposition.h qqmlpreviewservice.cpp qqmlpreviewservice.h qqmlpreviewservicefactory.cpp qqmlpreviewservicefactory.h - PUBLIC_LIBRARIES + LIBRARIES Qt::Core Qt::CorePrivate Qt::Gui @@ -29,10 +30,10 @@ qt_internal_add_plugin(QQmlPreviewServiceFactory #### Keys ignored in scope 1:.:.:qmldbg_preview.pro:: # OTHER_FILES = "$$PWD/qqmlpreviewservice.json" -qt_internal_extend_target(QQmlPreviewServiceFactory CONDITION QT_FEATURE_translation +qt_internal_extend_target(QQmlPreviewServiceFactoryPlugin CONDITION QT_FEATURE_translation SOURCES proxytranslator.cpp proxytranslator.h qqmldebugtranslationservice.cpp qqmldebugtranslationservice.h - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui ) diff --git a/src/plugins/qmltooling/qmldbg_preview/proxytranslator.cpp b/src/plugins/qmltooling/qmldbg_preview/proxytranslator.cpp index 7f5227296a0..ddf2df12ff0 100644 --- a/src/plugins/qmltooling/qmldbg_preview/proxytranslator.cpp +++ b/src/plugins/qmltooling/qmldbg_preview/proxytranslator.cpp @@ -75,9 +75,10 @@ QString ProxyTranslator::originStringFromInformation(const TranslationBindingInf QQmlSourceLocation ProxyTranslator::sourceLocationFromInformation(const TranslationBindingInformation &translationBindingInformation) { - return QQmlSourceLocation(translationBindingInformation.compilationUnit->fileName(), - translationBindingInformation.compiledBinding->valueLocation.line, - translationBindingInformation.compiledBinding->valueLocation.column); + return QQmlSourceLocation( + translationBindingInformation.compilationUnit->fileName(), + translationBindingInformation.compiledBinding->valueLocation.line(), + translationBindingInformation.compiledBinding->valueLocation.column()); } @@ -125,7 +126,7 @@ QString ProxyTranslator::translate(const char *context, const char *sourceText, result = m_qtTranslator->translate(context, sourceText, disambiguation, n); if (result.isNull() && m_qmlTranslator) result = m_qmlTranslator->translate(context, sourceText, disambiguation, n); - m_translationFound = !result.isNull(); + m_translationFound = !(result.isNull() || result.isEmpty() || result == sourceText); return result; } @@ -154,3 +155,5 @@ QString ProxyTranslator::currentUILanguages() const } QT_END_NAMESPACE + +#include "moc_proxytranslator.cpp" diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp index 4f9d76432f8..d21f54dd2c9 100644 --- a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp +++ b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.cpp @@ -39,6 +39,7 @@ #include "qqmldebugtranslationservice.h" #include "proxytranslator.h" +#include "qqmlpreviewservice.h" #include #include @@ -73,8 +74,8 @@ QDebug operator<<(QDebug debug, const TranslationBindingInformation &translation { QQmlError error; error.setUrl(translationBindingInformation.compilationUnit->url()); - error.setLine(translationBindingInformation.compiledBinding->valueLocation.line); - error.setColumn(translationBindingInformation.compiledBinding->valueLocation.column); + error.setLine(translationBindingInformation.compiledBinding->valueLocation.line()); + error.setColumn(translationBindingInformation.compiledBinding->valueLocation.column()); error.setDescription( QString(QLatin1String( "QDebug translation binding" @@ -96,8 +97,7 @@ class QQmlDebugTranslationServicePrivate : public QObject void setState(const QString &stateName) { - if (currentQuickView) { - QQuickItem *rootItem = currentQuickView->rootObject(); + if (QQuickItem *rootItem = currentRootItem()) { QQuickStateGroup *stateGroup = QQuickItemPrivate::get(rootItem)->_states(); if (stateGroup->findState(stateName)) { connect(stateGroup, &QQuickStateGroup::stateChanged, @@ -106,17 +106,16 @@ class QQmlDebugTranslationServicePrivate : public QObject stateGroup->setState(stateName); } else - qWarning() << QString("Could not switch the state to %1").arg(stateName); + qWarning() << "Could not switch the state" << stateName << "at" << rootItem; } } void sendStateChanged() { - QString stateName; if (QQuickStateGroup *stateGroup = qobject_cast(sender())) - stateName = stateGroup->state(); + currentStateName = stateGroup->state(); QVersionedPacket packet; - packet << Reply::StateChanged << stateName; + packet << Reply::StateChanged << currentStateName; emit q->messageToClient(q->name(), packet.data()); } @@ -124,17 +123,18 @@ class QQmlDebugTranslationServicePrivate : public QObject { QVersionedPacket packet; packet << Reply::StateList; + QVector qmlStates; - QQuickItem *rootItem = currentQuickView->rootObject(); - QQuickStateGroup *stateGroup = QQuickItemPrivate::get(rootItem)->_states(); + if (QQuickItem *rootItem = currentRootItem()) { + QQuickStateGroup *stateGroup = QQuickItemPrivate::get(rootItem)->_states(); - QList states = stateGroup->states(); - QVector qmlStates; + QList states = stateGroup->states(); - for (QQuickState *state : states) { - QmlState qmlState; - qmlState.name = state->name(); - qmlStates.append(qmlState); + for (QQuickState *state : states) { + QmlState qmlState; + qmlState.name = state->name(); + qmlStates.append(qmlState); + } } packet << qmlStates; @@ -157,6 +157,22 @@ class QQmlDebugTranslationServicePrivate : public QObject } } + QString getStyleNameForFont(const QFont& font) + { + if (font.styleName() != "") + return font.styleName(); + QString styleName; + if (font.bold()) + styleName.append("Bold "); + if (font.italic()) + styleName.append("Italic " ); + if (font.strikeOut()) + styleName.append("StrikeThrough "); + if (font.underline()) + styleName.append("Underline "); + return styleName.trimmed(); + } + void sendTranslatableTextOccurrences() { @@ -193,13 +209,14 @@ class QQmlDebugTranslationServicePrivate : public QObject qmlElement.fontFamily = font.family(); qmlElement.fontPointSize = font.pointSize(); qmlElement.fontPixelSize = font.pixelSize(); - qmlElement.fontStyleName = font.styleName(); + qmlElement.fontStyleName = getStyleNameForFont(font); qmlElement.horizontalAlignment = scopeObject->property("horizontalAlignment").toInt(); qmlElement.verticalAlignment = scopeObject->property("verticalAlignment").toInt(); QQmlType qmlType = QQmlMetaType::qmlType(metaObject); qmlElement.elementType = qmlType.qmlTypeName() + "/" + qmlType.typeName(); + qmlElement.stateName = currentStateName; qmlElements.append(qmlElement); } else { @@ -224,10 +241,10 @@ class QQmlDebugTranslationServicePrivate : public QObject emit q->messageToClient(q->name(), packet.data()); } - void sendMissingTranslations() + void sendTranslationIssues() { QVersionedPacket packet; - packet << Reply::MissingTranslations; + packet << Reply::TranslationIssues; QVector issues; for (auto &&information : qAsConst(objectTranslationBindingMultiMap)) { @@ -238,6 +255,18 @@ class QQmlDebugTranslationServicePrivate : public QObject issue.language = proxyTranslator->currentUILanguages(); issues.append(issue); } + + QObject *scopeObject = information.scopeObject; + QQuickText *quickText = static_cast(scopeObject); + if (quickText) { + if (quickText->truncated()) { + TranslationIssue issue; + issue.type = TranslationIssue::Type::Elided; + issue.codeMarker = codeMarker(information); + issue.language = proxyTranslator->currentUILanguages(); + issues.append(issue); + } + } } std::sort(issues.begin(), issues.end(), [](const auto &l1, const auto &l2){ return l1.codeMarker < l2.codeMarker; @@ -246,20 +275,6 @@ class QQmlDebugTranslationServicePrivate : public QObject emit q->messageToClient(q->name(), packet.data()); } - void sendElidedTextWarning(const TranslationBindingInformation &information) - { - QVersionedPacket packet; - packet << Reply::TextElided; - - TranslationIssue issue; - issue.type = TranslationIssue::Type::Elided; - issue.codeMarker = codeMarker(information); - issue.language = proxyTranslator->currentUILanguages(); - - packet << issue; - emit q->messageToClient(q->name(), packet.data()); - } - QQmlDebugTranslationServiceImpl *q; bool watchTextElides = false; @@ -271,16 +286,26 @@ class QQmlDebugTranslationServicePrivate : public QObject QTimer translatableTextOccurrenceTimer; QList> translatableTextOccurrences; - QPointer currentQuickView; + QQuickItem *currentRootItem() + { + if (QQmlPreviewServiceImpl *service = QQmlDebugConnector::service()) + return service->currentRootItem(); + if (currentQuickView) + return currentQuickView->rootObject(); + return nullptr; + } + QQuickView* currentQuickView = nullptr; + private: CodeMarker codeMarker(const TranslationBindingInformation &information) { CodeMarker c; c.url = information.compilationUnit->url(); - c.line = information.compiledBinding->valueLocation.line; - c.column = information.compiledBinding->valueLocation.column; + c.line = information.compiledBinding->valueLocation.line(); + c.column = information.compiledBinding->valueLocation.column(); return c; } + QString currentStateName; }; QQmlDebugTranslationServiceImpl::QQmlDebugTranslationServiceImpl(QObject *parent) @@ -300,14 +325,17 @@ QQmlDebugTranslationServiceImpl::QQmlDebugTranslationServiceImpl(QObject *parent d, &QQmlDebugTranslationServicePrivate::setState, Qt::QueuedConnection); - connect(this, &QQmlDebugTranslationServiceImpl::stateList, d, - &QQmlDebugTranslationServicePrivate::sendStateList, Qt::QueuedConnection); + connect(this, &QQmlDebugTranslationServiceImpl::stateList, + d, &QQmlDebugTranslationServicePrivate::sendStateList, + Qt::QueuedConnection); connect(d->proxyTranslator, &ProxyTranslator::languageChanged, - d, &QQmlDebugTranslationServicePrivate::sendLanguageChanged); + d, &QQmlDebugTranslationServicePrivate::sendLanguageChanged, + Qt::QueuedConnection); - connect(this, &QQmlDebugTranslationServiceImpl::missingTranslations, - d, &QQmlDebugTranslationServicePrivate::sendMissingTranslations); + connect(this, &QQmlDebugTranslationServiceImpl::translationIssues, + d, &QQmlDebugTranslationServicePrivate::sendTranslationIssues, + Qt::QueuedConnection); connect(this, &QQmlDebugTranslationServiceImpl::sendTranslatableTextOccurrences, d, &QQmlDebugTranslationServicePrivate::sendTranslatableTextOccurrences, @@ -344,8 +372,8 @@ void QQmlDebugTranslationServiceImpl::messageReceived(const QByteArray &message) emit stateList(); break; } - case QQmlDebugTranslation::Request::MissingTranslations: { - emit missingTranslations(); + case QQmlDebugTranslation::Request::TranslationIssues: { + emit translationIssues(); break; } case QQmlDebugTranslation::Request::TranslatableTextOccurrences: { @@ -385,59 +413,18 @@ void QQmlDebugTranslationServiceImpl::engineAboutToBeRemoved(QJSEngine *engine) emit detachedFromEngine(engine); } -QString QQmlDebugTranslationServiceImpl::foundElidedText(QObject *textObject, const QString &layoutText, const QString &elideText) -{ - Q_UNUSED(layoutText) - QString elidedTextResult = elideText; - // do the check only for text objects which have translation bindings - auto it = d->objectTranslationBindingMultiMap.find(textObject); - if (it != d->objectTranslationBindingMultiMap.end()) { - if (QQuickItem* quickItem = qobject_cast(textObject)) { - //const QColor originColor = quickItem->color(); - const TranslationBindingInformation information = d->objectTranslationBindingMultiMap.value(quickItem); - if (d->watchTextElides && d->proxyTranslator->hasTranslation(information)) { - d->sendElidedTextWarning(information); - } - if (!d->elideConnections.contains(quickItem)) { - // add "refresh" elide state connections which remove themself - auto clearElideInformation = [=]() { - //quickItem->setColor(originColor); - for (QMetaObject::Connection connection : d->elideConnections.value(quickItem)) - quickItem->disconnect(connection); - d->elideConnections.remove(quickItem); - }; - - auto connectWithChangedWidthThreshold = [=] () { - return connect(quickItem, &QQuickItem::widthChanged, [=]() { - if (quickItem->implicitWidth() <= quickItem->width()) - clearElideInformation(); - }); - }; - auto connectImplicitWidthChangedThreshold = [=] () { - return connect(quickItem, &QQuickItem::implicitWidthChanged, [=]() { - if (quickItem->implicitWidth() <= quickItem->width()) - clearElideInformation(); - }); - }; - - d->elideConnections.insert(quickItem, - {connectWithChangedWidthThreshold(), - connectImplicitWidthChangedThreshold()}); - } - } - } - return elidedTextResult; -} - void QQmlDebugTranslationServiceImpl::foundTranslationBinding(const TranslationBindingInformation &translationBindingInformation) { QObject *scopeObject = translationBindingInformation.scopeObject; connect(scopeObject, &QObject::destroyed, [this, scopeObject] () { this->d->objectTranslationBindingMultiMap.remove(scopeObject); }); + d->objectTranslationBindingMultiMap.insert(scopeObject, translationBindingInformation); } QT_END_NAMESPACE +#include "moc_qqmldebugtranslationservice.cpp" + #include diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h index 72e70f4b290..e0d1b2d9a85 100644 --- a/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h +++ b/src/plugins/qmltooling/qmldbg_preview/qqmldebugtranslationservice.h @@ -68,7 +68,6 @@ class QQmlDebugTranslationServiceImpl : public QQmlDebugTranslationService QQmlDebugTranslationServiceImpl(QObject *parent = 0); ~QQmlDebugTranslationServiceImpl(); - QString foundElidedText(QObject *textObject, const QString &layoutText, const QString &elideText) override; void foundTranslationBinding(const TranslationBindingInformation &translationBindingInformation) override; void messageReceived(const QByteArray &message) override; @@ -80,7 +79,8 @@ class QQmlDebugTranslationServiceImpl : public QQmlDebugTranslationService void state(const QString &stateName); void stateList(); void watchTextElides(bool); - void missingTranslations(); + void translationIssues(); + void elidedTranslations(); void sendTranslatableTextOccurrences(); private: diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileengine.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileengine.cpp index 5e78539155a..e11b8c97769 100644 --- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileengine.cpp +++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileengine.cpp @@ -398,6 +398,14 @@ bool QQmlPreviewFileEngine::supportsExtension(Extension extension) const void QQmlPreviewFileEngine::load() const { + // We can get here from different threads on different instances of QQmlPreviewFileEngine. + // However, there is only one loader per QQmlPreviewFileEngineHandler and it is not thread-safe. + // Its content mutex doesn't help us here because we explicitly wait on it in load(), which + // causes it to be released. Therefore, lock the load mutex first. + // This doesn't cause any deadlocks because the only thread that wakes the loader on the content + // mutex never calls load(). It's the QML debug server thread that handles the debug protocol. + QMutexLocker loadLocker(m_loader->loadMutex()); + m_result = m_loader->load(m_absolute); switch (m_result) { case QQmlPreviewFileLoader::File: diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.cpp index ffe50697f88..48e61dcae8e 100644 --- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.cpp +++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.cpp @@ -60,7 +60,7 @@ QQmlPreviewFileLoader::QQmlPreviewFileLoader(QQmlPreviewServiceImpl *service) : for (int loc = QLibraryInfo::PrefixPath; loc < QLibraryInfo::TestsPath; ++loc) { m_blacklist.blacklist(QLibraryInfo::path( - static_cast(loc))); + static_cast(loc))); } m_blacklist.blacklist(QLibraryInfo::path(QLibraryInfo::SettingsPath)); @@ -99,7 +99,7 @@ QQmlPreviewFileLoader::~QQmlPreviewFileLoader() { QQmlPreviewFileLoader::Result QQmlPreviewFileLoader::load(const QString &path) { - QMutexLocker locker(&m_mutex); + QMutexLocker locker(&m_contentMutex); m_path = path; auto fileIterator = m_fileCache.constFind(path); @@ -122,19 +122,19 @@ QQmlPreviewFileLoader::Result QQmlPreviewFileLoader::load(const QString &path) m_entries.clear(); m_contents.clear(); emit request(path); - m_waitCondition.wait(&m_mutex); + m_waitCondition.wait(&m_contentMutex); return m_result; } QByteArray QQmlPreviewFileLoader::contents() { - QMutexLocker locker(&m_mutex); + QMutexLocker locker(&m_contentMutex); return m_contents; } QStringList QQmlPreviewFileLoader::entries() { - QMutexLocker locker(&m_mutex); + QMutexLocker locker(&m_contentMutex); return m_entries; } @@ -142,20 +142,20 @@ void QQmlPreviewFileLoader::whitelist(const QUrl &url) { const QString path = QQmlFile::urlToLocalFileOrQrc(url); if (!path.isEmpty()) { - QMutexLocker locker(&m_mutex); + QMutexLocker locker(&m_contentMutex); m_blacklist.whitelist(path); } } bool QQmlPreviewFileLoader::isBlacklisted(const QString &path) { - QMutexLocker locker(&m_mutex); + QMutexLocker locker(&m_contentMutex); return m_blacklist.isBlacklisted(path); } void QQmlPreviewFileLoader::file(const QString &path, const QByteArray &contents) { - QMutexLocker locker(&m_mutex); + QMutexLocker locker(&m_contentMutex); m_blacklist.whitelist(path); m_fileCache[path] = contents; if (path == m_path) { @@ -167,7 +167,7 @@ void QQmlPreviewFileLoader::file(const QString &path, const QByteArray &contents void QQmlPreviewFileLoader::directory(const QString &path, const QStringList &entries) { - QMutexLocker locker(&m_mutex); + QMutexLocker locker(&m_contentMutex); m_blacklist.whitelist(path); m_directoryCache[path] = entries; if (path == m_path) { @@ -179,7 +179,7 @@ void QQmlPreviewFileLoader::directory(const QString &path, const QStringList &en void QQmlPreviewFileLoader::error(const QString &path) { - QMutexLocker locker(&m_mutex); + QMutexLocker locker(&m_contentMutex); m_blacklist.blacklist(path); if (path == m_path) { m_result = Fallback; @@ -189,9 +189,11 @@ void QQmlPreviewFileLoader::error(const QString &path) void QQmlPreviewFileLoader::clearCache() { - QMutexLocker locker(&m_mutex); + QMutexLocker locker(&m_contentMutex); m_fileCache.clear(); m_directoryCache.clear(); } QT_END_NAMESPACE + +#include "moc_qqmlpreviewfileloader.cpp" diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.h b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.h index 0c55c48c4a8..ffda9c0dbfa 100644 --- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.h +++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewfileloader.h @@ -79,7 +79,9 @@ class QQmlPreviewFileLoader : public QObject QQmlPreviewFileLoader(QQmlPreviewServiceImpl *service); ~QQmlPreviewFileLoader(); + QMutex *loadMutex() { return &m_loadMutex; } Result load(const QString &file); + QByteArray contents(); QStringList entries(); @@ -90,7 +92,8 @@ class QQmlPreviewFileLoader : public QObject void request(const QString &file); private: - QMutex m_mutex; + QMutex m_loadMutex; + QMutex m_contentMutex; QWaitCondition m_waitCondition; QThread m_thread; diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.cpp index b8453128d87..e3dfa7b9ede 100644 --- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.cpp +++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.cpp @@ -112,6 +112,11 @@ bool QQmlPreviewHandler::eventFilter(QObject *obj, QEvent *event) return QObject::eventFilter(obj, event); } +QQuickItem *QQmlPreviewHandler::currentRootItem() +{ + return m_currentRootItem; +} + void QQmlPreviewHandler::addEngine(QQmlEngine *qmlEngine) { m_engines.append(qmlEngine); @@ -288,6 +293,8 @@ void QQmlPreviewHandler::showObject(QObject *object) item->setParentItem(m_currentWindow->contentItem()); m_currentWindow->resize(item->size().toSize()); + // used by debug translation service to get the states + m_currentRootItem = item; } else { emit error(QLatin1String("Created object is neither a QWindow nor a QQuickItem.")); } @@ -417,3 +424,5 @@ void QQmlPreviewHandler::tryCreateObject() } QT_END_NAMESPACE + +#include "moc_qqmlpreviewhandler.cpp" diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.h b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.h index b7ee8fa09ba..4e9a092a58b 100644 --- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.h +++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewhandler.h @@ -74,6 +74,8 @@ class QQmlPreviewHandler : public QObject explicit QQmlPreviewHandler(QObject *parent = nullptr); ~QQmlPreviewHandler(); + QQuickItem *currentRootItem(); + void addEngine(QQmlEngine *engine); void removeEngine(QQmlEngine *engine); @@ -116,6 +118,7 @@ class QQmlPreviewHandler : public QObject QScopedPointer m_dummyItem; QList m_engines; + QPointer m_currentRootItem; QVector> m_createdObjects; QScopedPointer m_component; QPointer m_currentWindow; diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.cpp index b6d6a7a2209..cf61d25a0fd 100644 --- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.cpp +++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.cpp @@ -183,4 +183,11 @@ void QQmlPreviewServiceImpl::forwardFps(const QQmlPreviewHandler::FpsInfo &frame emit messageToClient(name(), packet.data()); } +QQuickItem *QQmlPreviewServiceImpl::currentRootItem() +{ + return m_handler.currentRootItem(); +} + QT_END_NAMESPACE + +#include "moc_qqmlpreviewservice.cpp" diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.h b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.h index 56deb7f092c..39d68bbc398 100644 --- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.h +++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservice.h @@ -90,6 +90,8 @@ class QQmlPreviewServiceImpl : public QQmlDebugService void forwardError(const QString &error); void forwardFps(const QQmlPreviewHandler::FpsInfo &frames); + QQuickItem *currentRootItem(); + signals: void error(const QString &file); void file(const QString &file, const QByteArray &contents); diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp index 23329dbcf22..9c09e1fc1ac 100644 --- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp +++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewservicefactory.cpp @@ -57,3 +57,5 @@ QQmlDebugService *QQmlPreviewServiceFactory::create(const QString &key) } QT_END_NAMESPACE + +#include "moc_qqmlpreviewservicefactory.cpp" diff --git a/src/plugins/qmltooling/qmldbg_profiler/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_profiler/CMakeLists.txt index ac1bf3fe691..b18c9f7c1a8 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/CMakeLists.txt +++ b/src/plugins/qmltooling/qmldbg_profiler/CMakeLists.txt @@ -4,16 +4,17 @@ ## QQmlProfilerServiceFactory Plugin: ##################################################################### -qt_internal_add_plugin(QQmlProfilerServiceFactory +qt_internal_add_plugin(QQmlProfilerServiceFactoryPlugin OUTPUT_NAME qmldbg_profiler - TYPE qmltooling + CLASS_NAME QQmlProfilerServiceFactory + PLUGIN_TYPE qmltooling SOURCES qqmlenginecontrolservice.cpp qqmlenginecontrolservice.h qqmlprofileradapter.cpp qqmlprofileradapter.h qqmlprofilerservice.cpp qqmlprofilerservice.h qqmlprofilerservicefactory.cpp qqmlprofilerservicefactory.h qv4profileradapter.cpp qv4profileradapter.h - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::PacketProtocolPrivate Qt::QmlPrivate diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp index 4702bc3c335..7a1b19ab8bb 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp @@ -159,3 +159,5 @@ void QQmlProfilerAdapter::receiveData(const QVector &new_data, } QT_END_NAMESPACE + +#include "moc_qqmlprofileradapter.cpp" diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_quickprofiler/CMakeLists.txt index a7a346eeeff..5b38060052f 100644 --- a/src/plugins/qmltooling/qmldbg_quickprofiler/CMakeLists.txt +++ b/src/plugins/qmltooling/qmldbg_quickprofiler/CMakeLists.txt @@ -4,13 +4,14 @@ ## QQuickProfilerAdapterFactory Plugin: ##################################################################### -qt_internal_add_plugin(QQuickProfilerAdapterFactory +qt_internal_add_plugin(QQuickProfilerAdapterFactoryPlugin OUTPUT_NAME qmldbg_quickprofiler - TYPE qmltooling + CLASS_NAME QQuickProfilerAdapterFactory + PLUGIN_TYPE qmltooling SOURCES qquickprofileradapter.cpp qquickprofileradapter.h qquickprofileradapterfactory.cpp qquickprofileradapterfactory.h - PUBLIC_LIBRARIES + LIBRARIES Qt::Core Qt::CorePrivate Qt::Gui diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp index 79a1c824114..0abd54dfb14 100644 --- a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp +++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp @@ -175,3 +175,5 @@ void QQuickProfilerAdapter::receiveData(const QVector &new_d } QT_END_NAMESPACE + +#include "moc_qquickprofileradapter.cpp" diff --git a/src/plugins/qmltooling/qmldbg_server/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_server/CMakeLists.txt index 490be0be7c2..927f077b642 100644 --- a/src/plugins/qmltooling/qmldbg_server/CMakeLists.txt +++ b/src/plugins/qmltooling/qmldbg_server/CMakeLists.txt @@ -4,13 +4,14 @@ ## QQmlDebugServerFactory Plugin: ##################################################################### -qt_internal_add_plugin(QQmlDebugServerFactory +qt_internal_add_plugin(QQmlDebugServerFactoryPlugin OUTPUT_NAME qmldbg_server - TYPE qmltooling + CLASS_NAME QQmlDebugServerFactory + PLUGIN_TYPE qmltooling SOURCES - qqmldebugserver.cpp + qqmldebugserverfactory.cpp qqmldebugserverfactory.h - PUBLIC_LIBRARIES + LIBRARIES Qt::PacketProtocolPrivate Qt::QmlPrivate ) diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp deleted file mode 100644 index 0e4c90f9875..00000000000 --- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp +++ /dev/null @@ -1,769 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module 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 "qqmldebugserverfactory.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -/* - QQmlDebug Protocol (Version 1): - - handshake: - 1. Client sends - "QDeclarativeDebugServer" 0 version pluginNames [QDataStream version] - version: an int representing the highest protocol version the client knows - pluginNames: plugins available on client side - 2. Server sends - "QDeclarativeDebugClient" 0 version pluginNames pluginVersions [QDataStream version] - version: an int representing the highest protocol version the client & server know - pluginNames: plugins available on server side. plugins both in the client and server message are enabled. - client plugin advertisement - 1. Client sends - "QDeclarativeDebugServer" 1 pluginNames - server plugin advertisement (not implemented: all services are required to register before open()) - 1. Server sends - "QDeclarativeDebugClient" 1 pluginNames pluginVersions - plugin communication: - Everything send with a header different to "QDeclarativeDebugServer" is sent to the appropriate plugin. - */ - -Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugServerConnection) - -const int protocolVersion = 1; -using QQmlDebugPacket = QVersionedPacket; - -class QQmlDebugServerImpl; -class QQmlDebugServerThread : public QThread -{ -public: - QQmlDebugServerThread() : m_server(nullptr), m_portFrom(-1), m_portTo(-1) {} - - void setServer(QQmlDebugServerImpl *server) - { - m_server = server; - } - - void setPortRange(int portFrom, int portTo, const QString &hostAddress) - { - m_pluginName = QLatin1String("QTcpServerConnection"); - m_portFrom = portFrom; - m_portTo = portTo; - m_hostAddress = hostAddress; - } - - void setFileName(const QString &fileName) - { - m_pluginName = QLatin1String("QLocalClientConnection"); - m_fileName = fileName; - } - - const QString &pluginName() const - { - return m_pluginName; - } - - void run() override; - -private: - QQmlDebugServerImpl *m_server; - QString m_pluginName; - int m_portFrom; - int m_portTo; - QString m_hostAddress; - QString m_fileName; -}; - -class QQmlDebugServerImpl : public QQmlDebugServer -{ - Q_OBJECT -public: - QQmlDebugServerImpl(); - - bool blockingMode() const override; - - QQmlDebugService *service(const QString &name) const override; - - void addEngine(QJSEngine *engine) override; - void removeEngine(QJSEngine *engine) override; - bool hasEngine(QJSEngine *engine) const override; - - bool addService(const QString &name, QQmlDebugService *service) override; - bool removeService(const QString &name) override; - - bool open(const QVariantHash &configuration) override; - void setDevice(QIODevice *socket) override; - - void parseArguments(); - - static void cleanup(); - -private: - friend class QQmlDebugServerThread; - friend class QQmlDebugServerFactory; - - class EngineCondition { - public: - EngineCondition() : numServices(0), condition(new QWaitCondition) {} - - bool waitForServices(QMutex *locked, int numEngines); - bool isWaiting() const { return numServices > 0; } - - void wake(); - private: - int numServices; - - // shared pointer to allow for QHash-inflicted copying. - QSharedPointer condition; - }; - - bool canSendMessage(const QString &name); - void doSendMessage(const QString &name, const QByteArray &message); - void wakeEngine(QJSEngine *engine); - void sendMessage(const QString &name, const QByteArray &message); - void sendMessages(const QString &name, const QList &messages); - void changeServiceState(const QString &serviceName, QQmlDebugService::State state); - void removeThread(); - void receiveMessage(); - void protocolError(); - - QQmlDebugServerConnection *m_connection; - QHash m_plugins; - QStringList m_clientPlugins; - bool m_gotHello; - bool m_blockingMode; - - QHash m_engineConditions; - - mutable QMutex m_helloMutex; - QWaitCondition m_helloCondition; - QQmlDebugServerThread m_thread; - QPacketProtocol *m_protocol; - QAtomicInt m_changeServiceStateCalls; -}; - -void QQmlDebugServerImpl::cleanup() -{ - QQmlDebugServerImpl *server = static_cast( - QQmlDebugConnector::instance()); - if (!server) - return; - - { - QObject signalSource; - for (QHash::ConstIterator i = server->m_plugins.constBegin(); - i != server->m_plugins.constEnd(); ++i) { - server->m_changeServiceStateCalls.ref(); - QString key = i.key(); - // Process this in the server's thread. - connect(&signalSource, &QObject::destroyed, server, [key, server](){ - server->changeServiceState(key, QQmlDebugService::NotConnected); - }, Qt::QueuedConnection); - } - } - - // Wait for changeServiceState calls to finish - // (while running an event loop because some services - // might again defer execution of stuff in the GUI thread) - QEventLoop loop; - while (!server->m_changeServiceStateCalls.testAndSetOrdered(0, 0)) - loop.processEvents(); - - // Stop the thread while the application is still there. - server->m_thread.exit(); - server->m_thread.wait(); -} - -void QQmlDebugServerThread::run() -{ - Q_ASSERT_X(m_server != nullptr, Q_FUNC_INFO, "There should always be a debug server available here."); - QQmlDebugServerConnection *connection = loadQQmlDebugServerConnection(m_pluginName); - if (connection) { - { - QMutexLocker connectionLocker(&m_server->m_helloMutex); - m_server->m_connection = connection; - connection->setServer(m_server); - m_server->m_helloCondition.wakeAll(); - } - - if (m_fileName.isEmpty()) { - if (!connection->setPortRange(m_portFrom, m_portTo, m_server->blockingMode(), - m_hostAddress)) - return; - } else if (!connection->setFileName(m_fileName, m_server->blockingMode())) { - return; - } - - if (m_server->blockingMode()) - connection->waitForConnection(); - } else { - qWarning() << "QML Debugger: Couldn't load plugin" << m_pluginName; - return; - } - - exec(); - - // make sure events still waiting are processed - QEventLoop eventLoop; - eventLoop.processEvents(QEventLoop::AllEvents); -} - -bool QQmlDebugServerImpl::blockingMode() const -{ - return m_blockingMode; -} - -static void cleanupOnShutdown() -{ - // We cannot do this in the destructor as the connection plugin will get unloaded before the - // server plugin and we need the connection to send any remaining data. This function is - // triggered before any plugins are unloaded. - QQmlDebugServerImpl::cleanup(); -} - -QQmlDebugServerImpl::QQmlDebugServerImpl() : - m_connection(nullptr), - m_gotHello(false), - m_blockingMode(false) -{ - static bool postRoutineAdded = false; - if (!postRoutineAdded) { - qAddPostRoutine(cleanupOnShutdown); - postRoutineAdded = true; - } - - // used in sendMessages - qRegisterMetaType >("QList"); - // used in changeServiceState - qRegisterMetaType("QQmlDebugService::State"); - - m_thread.setServer(this); - moveToThread(&m_thread); - - // Remove the thread immmediately when it finishes, so that we don't have to wait for the - // event loop to signal that. - QObject::connect(&m_thread, &QThread::finished, this, &QQmlDebugServerImpl::removeThread, - Qt::DirectConnection); - m_thread.setObjectName(QStringLiteral("QQmlDebugServerThread")); - parseArguments(); -} - -bool QQmlDebugServerImpl::open(const QVariantHash &configuration = QVariantHash()) -{ - if (m_thread.isRunning()) - return false; - if (!configuration.isEmpty()) { - m_blockingMode = configuration[QLatin1String("block")].toBool(); - if (configuration.contains(QLatin1String("portFrom"))) { - int portFrom = configuration[QLatin1String("portFrom")].toInt(); - int portTo = configuration[QLatin1String("portTo")].toInt(); - m_thread.setPortRange(portFrom, portTo == -1 ? portFrom : portTo, - configuration[QLatin1String("hostAddress")].toString()); - } else if (configuration.contains(QLatin1String("fileName"))) { - m_thread.setFileName(configuration[QLatin1String("fileName")].toString()); - } else { - return false; - } - } - - if (m_thread.pluginName().isEmpty()) - return false; - - QMutexLocker locker(&m_helloMutex); - m_thread.start(); - m_helloCondition.wait(&m_helloMutex); // wait for connection - if (m_blockingMode && !m_gotHello) - m_helloCondition.wait(&m_helloMutex); // wait for hello - return true; -} - -void QQmlDebugServerImpl::parseArguments() -{ - // format: qmljsdebugger=port:[,port_to],host:][,block] - const QString args = commandLineArguments(); - if (args.isEmpty()) - return; // Manual initialization, through QQmlDebugServer::open() - - // ### remove port definition when protocol is changed - int portFrom = 0; - int portTo = 0; - bool block = false; - bool ok = false; - QString hostAddress; - QString fileName; - QStringList services; - - const auto lstjsDebugArguments = QStringView{args}.split(QLatin1Char(','), Qt::SkipEmptyParts); - for (auto argsIt = lstjsDebugArguments.begin(), argsItEnd = lstjsDebugArguments.end(); argsIt != argsItEnd; ++argsIt) { - const QStringView &strArgument = *argsIt; - if (strArgument.startsWith(QLatin1String("port:"))) { - portFrom = strArgument.mid(5).toInt(&ok); - portTo = portFrom; - const auto argsNext = argsIt + 1; - if (argsNext == argsItEnd) - break; - if (ok) { - portTo = argsNext->toString().toInt(&ok); - if (ok) { - ++argsIt; - } else { - portTo = portFrom; - ok = true; - } - } - } else if (strArgument.startsWith(QLatin1String("host:"))) { - hostAddress = strArgument.mid(5).toString(); - } else if (strArgument == QLatin1String("block")) { - block = true; - } else if (strArgument.startsWith(QLatin1String("file:"))) { - fileName = strArgument.mid(5).toString(); - ok = !fileName.isEmpty(); - } else if (strArgument.startsWith(QLatin1String("services:"))) { - services.append(strArgument.mid(9).toString()); - } else if (!services.isEmpty()) { - services.append(strArgument.toString()); - } else if (!strArgument.startsWith(QLatin1String("connector:"))) { - const QString message = tr("QML Debugger: Invalid argument \"%1\" detected." - " Ignoring the same.").arg(strArgument.toString()); - qWarning("%s", qPrintable(message)); - } - } - - if (ok) { - setServices(services); - m_blockingMode = block; - if (!fileName.isEmpty()) - m_thread.setFileName(fileName); - else - m_thread.setPortRange(portFrom, portTo, hostAddress); - } else { - QString usage; - QTextStream str(&usage); - str << tr("QML Debugger: Ignoring \"-qmljsdebugger=%1\".").arg(args) << '\n' - << tr("The format is \"-qmljsdebugger=[file:|port:][,]" - "[,host:][,block][,services:][,]*\"") << '\n' - << tr("\"file:\" can be used to specify the name of a file the debugger will try " - "to connect to using a QLocalSocket. If \"file:\" is given any \"host:\" and" - "\"port:\" arguments will be ignored.") << '\n' - << tr("\"host:\" and \"port:\" can be used to specify an address and a single " - "port or a range of ports the debugger will try to bind to with a " - "QTcpServer.") << '\n' - << tr("\"block\" makes the debugger and some services wait for clients to be " - "connected and ready before the first QML engine starts.") << '\n' - << tr("\"services:\" can be used to specify which debug services the debugger " - "should load. Some debug services interact badly with others. The V4 " - "debugger should not be loaded when using the QML profiler as it will force " - "any V4 engines to use the JavaScript interpreter rather than the JIT. The " - "following debug services are available by default:") << '\n' - << QQmlEngineDebugService::s_key << "\t- " << tr("The QML debugger") << '\n' - << QV4DebugService::s_key << "\t- " << tr("The V4 debugger") << '\n' - << QQmlInspectorService::s_key << "\t- " << tr("The QML inspector") << '\n' - << QQmlProfilerService::s_key << "\t- " << tr("The QML profiler") << '\n' - << QQmlEngineControlService::s_key << "\t- " - //: Please preserve the line breaks and formatting - << tr("Allows the client to delay the starting and stopping of\n" - "\t\t QML engines until other services are ready. QtCreator\n" - "\t\t uses this service with the QML profiler in order to\n" - "\t\t profile multiple QML engines at the same time.") - << '\n' << QDebugMessageService::s_key << "\t- " - //: Please preserve the line breaks and formatting - << tr("Sends qDebug() and similar messages over the QML debug\n" - "\t\t connection. QtCreator uses this for showing debug\n" - "\t\t messages in the debugger console.") << '\n' -#if QT_CONFIG(translation) - << '\n' << QQmlDebugTranslationService::s_key << "\t- " - //: Please preserve the line breaks and formatting - << tr("helps to see if a translated text\n" - "\t\t will result in an elided text\n" - "\t\t in QML elements.") << '\n' -#endif //QT_CONFIG(translation) - << tr("Other services offered by qmltooling plugins that implement " - "QQmlDebugServiceFactory and which can be found in the standard plugin " - "paths will also be available and can be specified. If no \"services\" " - "argument is given, all services found this way, including the default " - "ones, are loaded."); - qWarning("%s", qPrintable(usage)); - } -} - -void QQmlDebugServerImpl::receiveMessage() -{ - typedef QHash::const_iterator DebugServiceConstIt; - - // to be executed in debugger thread - Q_ASSERT(QThread::currentThread() == thread()); - - if (!m_protocol) - return; - - QQmlDebugPacket in(m_protocol->read()); - - QString name; - - in >> name; - if (name == QLatin1String("QDeclarativeDebugServer")) { - int op = -1; - in >> op; - if (op == 0) { - int version; - in >> version >> m_clientPlugins; - - //Get the supported QDataStream version - if (!in.atEnd()) { - in >> s_dataStreamVersion; - if (s_dataStreamVersion > QDataStream::Qt_DefaultCompiledVersion) - s_dataStreamVersion = QDataStream::Qt_DefaultCompiledVersion; - } - - bool clientSupportsMultiPackets = false; - if (!in.atEnd()) - in >> clientSupportsMultiPackets; - - // Send the hello answer immediately, since it needs to arrive before - // the plugins below start sending messages. - - QQmlDebugPacket out; - QStringList pluginNames; - QList pluginVersions; - if (clientSupportsMultiPackets) { // otherwise, disable all plugins - const int count = m_plugins.count(); - pluginNames.reserve(count); - pluginVersions.reserve(count); - for (QHash::ConstIterator i = m_plugins.constBegin(); - i != m_plugins.constEnd(); ++i) { - pluginNames << i.key(); - pluginVersions << i.value()->version(); - } - } - - out << QString(QStringLiteral("QDeclarativeDebugClient")) << 0 << protocolVersion - << pluginNames << pluginVersions << dataStreamVersion(); - - m_protocol->send(out.data()); - m_connection->flush(); - - QMutexLocker helloLock(&m_helloMutex); - m_gotHello = true; - - for (DebugServiceConstIt iter = m_plugins.constBegin(), cend = m_plugins.constEnd(); iter != cend; ++iter) { - QQmlDebugService::State newState = QQmlDebugService::Unavailable; - if (m_clientPlugins.contains(iter.key())) - newState = QQmlDebugService::Enabled; - m_changeServiceStateCalls.ref(); - changeServiceState(iter.key(), newState); - } - - m_helloCondition.wakeAll(); - - } else if (op == 1) { - // Service Discovery - QStringList oldClientPlugins = m_clientPlugins; - in >> m_clientPlugins; - - for (DebugServiceConstIt iter = m_plugins.constBegin(), cend = m_plugins.constEnd(); iter != cend; ++iter) { - const QString &pluginName = iter.key(); - QQmlDebugService::State newState = QQmlDebugService::Unavailable; - if (m_clientPlugins.contains(pluginName)) - newState = QQmlDebugService::Enabled; - - if (oldClientPlugins.contains(pluginName) - != m_clientPlugins.contains(pluginName)) { - m_changeServiceStateCalls.ref(); - changeServiceState(iter.key(), newState); - } - } - - } else { - qWarning("QML Debugger: Invalid control message %d.", op); - protocolError(); - return; - } - - } else { - if (m_gotHello) { - QHash::Iterator iter = m_plugins.find(name); - if (iter == m_plugins.end()) { - qWarning() << "QML Debugger: Message received for missing plugin" << name << '.'; - } else { - QQmlDebugService *service = *iter; - QByteArray message; - while (!in.atEnd()) { - in >> message; - service->messageReceived(message); - } - } - } else { - qWarning("QML Debugger: Invalid hello message."); - } - - } -} - -void QQmlDebugServerImpl::changeServiceState(const QString &serviceName, - QQmlDebugService::State newState) -{ - // to be executed in debugger thread - Q_ASSERT(QThread::currentThread() == thread()); - - QQmlDebugService *service = m_plugins.value(serviceName); - if (service && service->state() != newState) { - service->stateAboutToBeChanged(newState); - service->setState(newState); - service->stateChanged(newState); - } - - m_changeServiceStateCalls.deref(); -} - -void QQmlDebugServerImpl::removeThread() -{ - Q_ASSERT(m_thread.isFinished()); - Q_ASSERT(QThread::currentThread() == thread()); - - QThread *parentThread = m_thread.thread(); - - delete m_connection; - m_connection = nullptr; - - // Move it back to the parent thread so that we can potentially restart it on a new thread. - moveToThread(parentThread); -} - -QQmlDebugService *QQmlDebugServerImpl::service(const QString &name) const -{ - return m_plugins.value(name); -} - -void QQmlDebugServerImpl::addEngine(QJSEngine *engine) -{ - // to be executed outside of debugger thread - Q_ASSERT(QThread::currentThread() != &m_thread); - - QMutexLocker locker(&m_helloMutex); - Q_ASSERT(!m_engineConditions.contains(engine)); - - for (QQmlDebugService *service : qAsConst(m_plugins)) - service->engineAboutToBeAdded(engine); - - m_engineConditions[engine].waitForServices(&m_helloMutex, m_plugins.count()); - - for (QQmlDebugService *service : qAsConst(m_plugins)) - service->engineAdded(engine); -} - -void QQmlDebugServerImpl::removeEngine(QJSEngine *engine) -{ - // to be executed outside of debugger thread - Q_ASSERT(QThread::currentThread() != &m_thread); - - QMutexLocker locker(&m_helloMutex); - Q_ASSERT(m_engineConditions.contains(engine)); - - for (QQmlDebugService *service : qAsConst(m_plugins)) - service->engineAboutToBeRemoved(engine); - - m_engineConditions[engine].waitForServices(&m_helloMutex, m_plugins.count()); - - for (QQmlDebugService *service : qAsConst(m_plugins)) - service->engineRemoved(engine); - - m_engineConditions.remove(engine); -} - -bool QQmlDebugServerImpl::hasEngine(QJSEngine *engine) const -{ - QMutexLocker locker(&m_helloMutex); - QHash::ConstIterator i = m_engineConditions.constFind(engine); - // if we're still waiting the engine isn't fully "there", yet, nor fully removed. - return i != m_engineConditions.constEnd() && !i.value().isWaiting(); -} - -bool QQmlDebugServerImpl::addService(const QString &name, QQmlDebugService *service) -{ - // to be executed before thread starts - Q_ASSERT(!m_thread.isRunning()); - - if (!service || m_plugins.contains(name)) - return false; - - connect(service, &QQmlDebugService::messageToClient, - this, &QQmlDebugServerImpl::sendMessage); - connect(service, &QQmlDebugService::messagesToClient, - this, &QQmlDebugServerImpl::sendMessages); - - connect(service, &QQmlDebugService::attachedToEngine, - this, &QQmlDebugServerImpl::wakeEngine, Qt::QueuedConnection); - connect(service, &QQmlDebugService::detachedFromEngine, - this, &QQmlDebugServerImpl::wakeEngine, Qt::QueuedConnection); - - service->setState(QQmlDebugService::Unavailable); - m_plugins.insert(name, service); - - return true; -} - -bool QQmlDebugServerImpl::removeService(const QString &name) -{ - // to be executed after thread ends - Q_ASSERT(!m_thread.isRunning()); - - QQmlDebugService *service = m_plugins.value(name); - if (!service) - return false; - - m_plugins.remove(name); - service->setState(QQmlDebugService::NotConnected); - - disconnect(service, &QQmlDebugService::detachedFromEngine, - this, &QQmlDebugServerImpl::wakeEngine); - disconnect(service, &QQmlDebugService::attachedToEngine, - this, &QQmlDebugServerImpl::wakeEngine); - - disconnect(service, &QQmlDebugService::messagesToClient, - this, &QQmlDebugServerImpl::sendMessages); - disconnect(service, &QQmlDebugService::messageToClient, - this, &QQmlDebugServerImpl::sendMessage); - - return true; -} - -bool QQmlDebugServerImpl::canSendMessage(const QString &name) -{ - // to be executed in debugger thread - Q_ASSERT(QThread::currentThread() == thread()); - return m_connection && m_connection->isConnected() && m_protocol && - m_clientPlugins.contains(name); -} - -void QQmlDebugServerImpl::doSendMessage(const QString &name, const QByteArray &message) -{ - QQmlDebugPacket out; - out << name << message; - m_protocol->send(out.data()); -} - -void QQmlDebugServerImpl::sendMessage(const QString &name, const QByteArray &message) -{ - if (canSendMessage(name)) { - doSendMessage(name, message); - m_connection->flush(); - } -} - -void QQmlDebugServerImpl::sendMessages(const QString &name, const QList &messages) -{ - if (canSendMessage(name)) { - QQmlDebugPacket out; - out << name; - for (const QByteArray &message : messages) - out << message; - m_protocol->send(out.data()); - m_connection->flush(); - } -} - -void QQmlDebugServerImpl::wakeEngine(QJSEngine *engine) -{ - // to be executed in debugger thread - Q_ASSERT(QThread::currentThread() == thread()); - - QMutexLocker locker(&m_helloMutex); - m_engineConditions[engine].wake(); -} - -bool QQmlDebugServerImpl::EngineCondition::waitForServices(QMutex *locked, int num) -{ - Q_ASSERT_X(numServices == 0, Q_FUNC_INFO, "Request to wait again before previous wait finished"); - numServices = num; - return numServices > 0 ? condition->wait(locked) : true; -} - -void QQmlDebugServerImpl::EngineCondition::wake() -{ - if (--numServices == 0) - condition->wakeAll(); - Q_ASSERT_X(numServices >=0, Q_FUNC_INFO, "Woken more often than #services."); -} - -void QQmlDebugServerImpl::setDevice(QIODevice *socket) -{ - m_protocol = new QPacketProtocol(socket, this); - QObject::connect(m_protocol, &QPacketProtocol::readyRead, - this, &QQmlDebugServerImpl::receiveMessage); - QObject::connect(m_protocol, &QPacketProtocol::error, - this, &QQmlDebugServerImpl::protocolError); - - if (blockingMode()) - m_protocol->waitForReadyRead(-1); -} - -void QQmlDebugServerImpl::protocolError() -{ - qWarning("QML Debugger: A protocol error has occurred! Giving up ..."); - m_connection->disconnect(); - // protocol might still be processing packages at this point - m_protocol->deleteLater(); - m_protocol = nullptr; -} - -QQmlDebugConnector *QQmlDebugServerFactory::create(const QString &key) -{ - // Cannot parent it to this because it gets moved to another thread - return (key == QLatin1String("QQmlDebugServer") ? new QQmlDebugServerImpl : nullptr); -} - -QT_END_NAMESPACE - -#include "qqmldebugserver.moc" diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.cpp new file mode 100644 index 00000000000..8f17eb94cd6 --- /dev/null +++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserverfactory.cpp @@ -0,0 +1,770 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 "qqmldebugserverfactory.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/* + QQmlDebug Protocol (Version 1): + + handshake: + 1. Client sends + "QDeclarativeDebugServer" 0 version pluginNames [QDataStream version] + version: an int representing the highest protocol version the client knows + pluginNames: plugins available on client side + 2. Server sends + "QDeclarativeDebugClient" 0 version pluginNames pluginVersions [QDataStream version] + version: an int representing the highest protocol version the client & server know + pluginNames: plugins available on server side. plugins both in the client and server message are enabled. + client plugin advertisement + 1. Client sends + "QDeclarativeDebugServer" 1 pluginNames + server plugin advertisement (not implemented: all services are required to register before open()) + 1. Server sends + "QDeclarativeDebugClient" 1 pluginNames pluginVersions + plugin communication: + Everything send with a header different to "QDeclarativeDebugServer" is sent to the appropriate plugin. + */ + +Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugServerConnection) + +const int protocolVersion = 1; +using QQmlDebugPacket = QVersionedPacket; + +class QQmlDebugServerImpl; +class QQmlDebugServerThread : public QThread +{ +public: + QQmlDebugServerThread() : m_server(nullptr), m_portFrom(-1), m_portTo(-1) {} + + void setServer(QQmlDebugServerImpl *server) + { + m_server = server; + } + + void setPortRange(int portFrom, int portTo, const QString &hostAddress) + { + m_pluginName = QLatin1String("QTcpServerConnection"); + m_portFrom = portFrom; + m_portTo = portTo; + m_hostAddress = hostAddress; + } + + void setFileName(const QString &fileName) + { + m_pluginName = QLatin1String("QLocalClientConnection"); + m_fileName = fileName; + } + + const QString &pluginName() const + { + return m_pluginName; + } + + void run() override; + +private: + QQmlDebugServerImpl *m_server; + QString m_pluginName; + int m_portFrom; + int m_portTo; + QString m_hostAddress; + QString m_fileName; +}; + +class QQmlDebugServerImpl : public QQmlDebugServer +{ + Q_OBJECT +public: + QQmlDebugServerImpl(); + + bool blockingMode() const override; + + QQmlDebugService *service(const QString &name) const override; + + void addEngine(QJSEngine *engine) override; + void removeEngine(QJSEngine *engine) override; + bool hasEngine(QJSEngine *engine) const override; + + bool addService(const QString &name, QQmlDebugService *service) override; + bool removeService(const QString &name) override; + + bool open(const QVariantHash &configuration) override; + void setDevice(QIODevice *socket) override; + + void parseArguments(); + + static void cleanup(); + +private: + friend class QQmlDebugServerThread; + friend class QQmlDebugServerFactory; + + class EngineCondition { + public: + EngineCondition() : numServices(0), condition(new QWaitCondition) {} + + bool waitForServices(QMutex *locked, int numEngines); + bool isWaiting() const { return numServices > 0; } + + void wake(); + private: + int numServices; + + // shared pointer to allow for QHash-inflicted copying. + QSharedPointer condition; + }; + + bool canSendMessage(const QString &name); + void doSendMessage(const QString &name, const QByteArray &message); + void wakeEngine(QJSEngine *engine); + void sendMessage(const QString &name, const QByteArray &message); + void sendMessages(const QString &name, const QList &messages); + void changeServiceState(const QString &serviceName, QQmlDebugService::State state); + void removeThread(); + void receiveMessage(); + void protocolError(); + + QQmlDebugServerConnection *m_connection; + QHash m_plugins; + QStringList m_clientPlugins; + bool m_gotHello; + bool m_blockingMode; + + QHash m_engineConditions; + + mutable QMutex m_helloMutex; + QWaitCondition m_helloCondition; + QQmlDebugServerThread m_thread; + QPacketProtocol *m_protocol; + QAtomicInt m_changeServiceStateCalls; +}; + +void QQmlDebugServerImpl::cleanup() +{ + QQmlDebugServerImpl *server = static_cast( + QQmlDebugConnector::instance()); + if (!server) + return; + + { + QObject signalSource; + for (QHash::ConstIterator i = server->m_plugins.constBegin(); + i != server->m_plugins.constEnd(); ++i) { + server->m_changeServiceStateCalls.ref(); + QString key = i.key(); + // Process this in the server's thread. + connect(&signalSource, &QObject::destroyed, server, [key, server](){ + server->changeServiceState(key, QQmlDebugService::NotConnected); + }, Qt::QueuedConnection); + } + } + + // Wait for changeServiceState calls to finish + // (while running an event loop because some services + // might again defer execution of stuff in the GUI thread) + QEventLoop loop; + while (!server->m_changeServiceStateCalls.testAndSetOrdered(0, 0)) + loop.processEvents(); + + // Stop the thread while the application is still there. + server->m_thread.exit(); + server->m_thread.wait(); +} + +void QQmlDebugServerThread::run() +{ + Q_ASSERT_X(m_server != nullptr, Q_FUNC_INFO, "There should always be a debug server available here."); + QQmlDebugServerConnection *connection = loadQQmlDebugServerConnection(m_pluginName); + if (connection) { + { + QMutexLocker connectionLocker(&m_server->m_helloMutex); + m_server->m_connection = connection; + connection->setServer(m_server); + m_server->m_helloCondition.wakeAll(); + } + + if (m_fileName.isEmpty()) { + if (!connection->setPortRange(m_portFrom, m_portTo, m_server->blockingMode(), + m_hostAddress)) + return; + } else if (!connection->setFileName(m_fileName, m_server->blockingMode())) { + return; + } + + if (m_server->blockingMode()) + connection->waitForConnection(); + } else { + qWarning() << "QML Debugger: Couldn't load plugin" << m_pluginName; + return; + } + + exec(); + + // make sure events still waiting are processed + QEventLoop eventLoop; + eventLoop.processEvents(QEventLoop::AllEvents); +} + +bool QQmlDebugServerImpl::blockingMode() const +{ + return m_blockingMode; +} + +static void cleanupOnShutdown() +{ + // We cannot do this in the destructor as the connection plugin will get unloaded before the + // server plugin and we need the connection to send any remaining data. This function is + // triggered before any plugins are unloaded. + QQmlDebugServerImpl::cleanup(); +} + +QQmlDebugServerImpl::QQmlDebugServerImpl() : + m_connection(nullptr), + m_gotHello(false), + m_blockingMode(false) +{ + static bool postRoutineAdded = false; + if (!postRoutineAdded) { + qAddPostRoutine(cleanupOnShutdown); + postRoutineAdded = true; + } + + // used in sendMessages + qRegisterMetaType >("QList"); + // used in changeServiceState + qRegisterMetaType("QQmlDebugService::State"); + + m_thread.setServer(this); + moveToThread(&m_thread); + + // Remove the thread immmediately when it finishes, so that we don't have to wait for the + // event loop to signal that. + QObject::connect(&m_thread, &QThread::finished, this, &QQmlDebugServerImpl::removeThread, + Qt::DirectConnection); + m_thread.setObjectName(QStringLiteral("QQmlDebugServerThread")); + parseArguments(); +} + +bool QQmlDebugServerImpl::open(const QVariantHash &configuration = QVariantHash()) +{ + if (m_thread.isRunning()) + return false; + if (!configuration.isEmpty()) { + m_blockingMode = configuration[QLatin1String("block")].toBool(); + if (configuration.contains(QLatin1String("portFrom"))) { + int portFrom = configuration[QLatin1String("portFrom")].toInt(); + int portTo = configuration[QLatin1String("portTo")].toInt(); + m_thread.setPortRange(portFrom, portTo == -1 ? portFrom : portTo, + configuration[QLatin1String("hostAddress")].toString()); + } else if (configuration.contains(QLatin1String("fileName"))) { + m_thread.setFileName(configuration[QLatin1String("fileName")].toString()); + } else { + return false; + } + } + + if (m_thread.pluginName().isEmpty()) + return false; + + QMutexLocker locker(&m_helloMutex); + m_thread.start(); + m_helloCondition.wait(&m_helloMutex); // wait for connection + if (m_blockingMode && !m_gotHello) + m_helloCondition.wait(&m_helloMutex); // wait for hello + return true; +} + +void QQmlDebugServerImpl::parseArguments() +{ + // format: qmljsdebugger=port:[,port_to],host:][,block] + const QString args = commandLineArguments(); + if (args.isEmpty()) + return; // Manual initialization, through QQmlDebugServer::open() + + // ### remove port definition when protocol is changed + int portFrom = 0; + int portTo = 0; + bool block = false; + bool ok = false; + QString hostAddress; + QString fileName; + QStringList services; + + const auto lstjsDebugArguments = QStringView{args}.split(QLatin1Char(','), Qt::SkipEmptyParts); + for (auto argsIt = lstjsDebugArguments.begin(), argsItEnd = lstjsDebugArguments.end(); argsIt != argsItEnd; ++argsIt) { + const QStringView &strArgument = *argsIt; + if (strArgument.startsWith(QLatin1String("port:"))) { + portFrom = strArgument.mid(5).toInt(&ok); + portTo = portFrom; + const auto argsNext = argsIt + 1; + if (argsNext == argsItEnd) + break; + if (ok) { + portTo = argsNext->toString().toInt(&ok); + if (ok) { + ++argsIt; + } else { + portTo = portFrom; + ok = true; + } + } + } else if (strArgument.startsWith(QLatin1String("host:"))) { + hostAddress = strArgument.mid(5).toString(); + } else if (strArgument == QLatin1String("block")) { + block = true; + } else if (strArgument.startsWith(QLatin1String("file:"))) { + fileName = strArgument.mid(5).toString(); + ok = !fileName.isEmpty(); + } else if (strArgument.startsWith(QLatin1String("services:"))) { + services.append(strArgument.mid(9).toString()); + } else if (!services.isEmpty()) { + services.append(strArgument.toString()); + } else if (!strArgument.startsWith(QLatin1String("connector:"))) { + const QString message = tr("QML Debugger: Invalid argument \"%1\" detected." + " Ignoring the same.").arg(strArgument.toString()); + qWarning("%s", qPrintable(message)); + } + } + + if (ok) { + setServices(services); + m_blockingMode = block; + if (!fileName.isEmpty()) + m_thread.setFileName(fileName); + else + m_thread.setPortRange(portFrom, portTo, hostAddress); + } else { + QString usage; + QTextStream str(&usage); + str << tr("QML Debugger: Ignoring \"-qmljsdebugger=%1\".").arg(args) << '\n' + << tr("The format is \"-qmljsdebugger=[file:|port:][,]" + "[,host:][,block][,services:][,]*\"") << '\n' + << tr("\"file:\" can be used to specify the name of a file the debugger will try " + "to connect to using a QLocalSocket. If \"file:\" is given any \"host:\" and" + "\"port:\" arguments will be ignored.") << '\n' + << tr("\"host:\" and \"port:\" can be used to specify an address and a single " + "port or a range of ports the debugger will try to bind to with a " + "QTcpServer.") << '\n' + << tr("\"block\" makes the debugger and some services wait for clients to be " + "connected and ready before the first QML engine starts.") << '\n' + << tr("\"services:\" can be used to specify which debug services the debugger " + "should load. Some debug services interact badly with others. The V4 " + "debugger should not be loaded when using the QML profiler as it will force " + "any V4 engines to use the JavaScript interpreter rather than the JIT. The " + "following debug services are available by default:") << '\n' + << QQmlEngineDebugService::s_key << "\t- " << tr("The QML debugger") << '\n' + << QV4DebugService::s_key << "\t- " << tr("The V4 debugger") << '\n' + << QQmlInspectorService::s_key << "\t- " << tr("The QML inspector") << '\n' + << QQmlProfilerService::s_key << "\t- " << tr("The QML profiler") << '\n' + << QQmlEngineControlService::s_key << "\t- " + //: Please preserve the line breaks and formatting + << tr("Allows the client to delay the starting and stopping of\n" + "\t\t QML engines until other services are ready. QtCreator\n" + "\t\t uses this service with the QML profiler in order to\n" + "\t\t profile multiple QML engines at the same time.") + << '\n' << QDebugMessageService::s_key << "\t- " + //: Please preserve the line breaks and formatting + << tr("Sends qDebug() and similar messages over the QML debug\n" + "\t\t connection. QtCreator uses this for showing debug\n" + "\t\t messages in the debugger console.") << '\n' +#if QT_CONFIG(translation) + << '\n' << QQmlDebugTranslationService::s_key << "\t- " + //: Please preserve the line breaks and formatting + << tr("helps to see if a translated text\n" + "\t\t will result in an elided text\n" + "\t\t in QML elements.") << '\n' +#endif //QT_CONFIG(translation) + << tr("Other services offered by qmltooling plugins that implement " + "QQmlDebugServiceFactory and which can be found in the standard plugin " + "paths will also be available and can be specified. If no \"services\" " + "argument is given, all services found this way, including the default " + "ones, are loaded."); + qWarning("%s", qPrintable(usage)); + } +} + +void QQmlDebugServerImpl::receiveMessage() +{ + typedef QHash::const_iterator DebugServiceConstIt; + + // to be executed in debugger thread + Q_ASSERT(QThread::currentThread() == thread()); + + if (!m_protocol) + return; + + QQmlDebugPacket in(m_protocol->read()); + + QString name; + + in >> name; + if (name == QLatin1String("QDeclarativeDebugServer")) { + int op = -1; + in >> op; + if (op == 0) { + int version; + in >> version >> m_clientPlugins; + + //Get the supported QDataStream version + if (!in.atEnd()) { + in >> s_dataStreamVersion; + if (s_dataStreamVersion > QDataStream::Qt_DefaultCompiledVersion) + s_dataStreamVersion = QDataStream::Qt_DefaultCompiledVersion; + } + + bool clientSupportsMultiPackets = false; + if (!in.atEnd()) + in >> clientSupportsMultiPackets; + + // Send the hello answer immediately, since it needs to arrive before + // the plugins below start sending messages. + + QQmlDebugPacket out; + QStringList pluginNames; + QList pluginVersions; + if (clientSupportsMultiPackets) { // otherwise, disable all plugins + const int count = m_plugins.count(); + pluginNames.reserve(count); + pluginVersions.reserve(count); + for (QHash::ConstIterator i = m_plugins.constBegin(); + i != m_plugins.constEnd(); ++i) { + pluginNames << i.key(); + pluginVersions << i.value()->version(); + } + } + + out << QString(QStringLiteral("QDeclarativeDebugClient")) << 0 << protocolVersion + << pluginNames << pluginVersions << dataStreamVersion(); + + m_protocol->send(out.data()); + m_connection->flush(); + + QMutexLocker helloLock(&m_helloMutex); + m_gotHello = true; + + for (DebugServiceConstIt iter = m_plugins.constBegin(), cend = m_plugins.constEnd(); iter != cend; ++iter) { + QQmlDebugService::State newState = QQmlDebugService::Unavailable; + if (m_clientPlugins.contains(iter.key())) + newState = QQmlDebugService::Enabled; + m_changeServiceStateCalls.ref(); + changeServiceState(iter.key(), newState); + } + + m_helloCondition.wakeAll(); + + } else if (op == 1) { + // Service Discovery + QStringList oldClientPlugins = m_clientPlugins; + in >> m_clientPlugins; + + for (DebugServiceConstIt iter = m_plugins.constBegin(), cend = m_plugins.constEnd(); iter != cend; ++iter) { + const QString &pluginName = iter.key(); + QQmlDebugService::State newState = QQmlDebugService::Unavailable; + if (m_clientPlugins.contains(pluginName)) + newState = QQmlDebugService::Enabled; + + if (oldClientPlugins.contains(pluginName) + != m_clientPlugins.contains(pluginName)) { + m_changeServiceStateCalls.ref(); + changeServiceState(iter.key(), newState); + } + } + + } else { + qWarning("QML Debugger: Invalid control message %d.", op); + protocolError(); + return; + } + + } else { + if (m_gotHello) { + QHash::Iterator iter = m_plugins.find(name); + if (iter == m_plugins.end()) { + qWarning() << "QML Debugger: Message received for missing plugin" << name << '.'; + } else { + QQmlDebugService *service = *iter; + QByteArray message; + while (!in.atEnd()) { + in >> message; + service->messageReceived(message); + } + } + } else { + qWarning("QML Debugger: Invalid hello message."); + } + + } +} + +void QQmlDebugServerImpl::changeServiceState(const QString &serviceName, + QQmlDebugService::State newState) +{ + // to be executed in debugger thread + Q_ASSERT(QThread::currentThread() == thread()); + + QQmlDebugService *service = m_plugins.value(serviceName); + if (service && service->state() != newState) { + service->stateAboutToBeChanged(newState); + service->setState(newState); + service->stateChanged(newState); + } + + m_changeServiceStateCalls.deref(); +} + +void QQmlDebugServerImpl::removeThread() +{ + Q_ASSERT(m_thread.isFinished()); + Q_ASSERT(QThread::currentThread() == thread()); + + QThread *parentThread = m_thread.thread(); + + delete m_connection; + m_connection = nullptr; + + // Move it back to the parent thread so that we can potentially restart it on a new thread. + moveToThread(parentThread); +} + +QQmlDebugService *QQmlDebugServerImpl::service(const QString &name) const +{ + return m_plugins.value(name); +} + +void QQmlDebugServerImpl::addEngine(QJSEngine *engine) +{ + // to be executed outside of debugger thread + Q_ASSERT(QThread::currentThread() != &m_thread); + + QMutexLocker locker(&m_helloMutex); + Q_ASSERT(!m_engineConditions.contains(engine)); + + for (QQmlDebugService *service : qAsConst(m_plugins)) + service->engineAboutToBeAdded(engine); + + m_engineConditions[engine].waitForServices(&m_helloMutex, m_plugins.count()); + + for (QQmlDebugService *service : qAsConst(m_plugins)) + service->engineAdded(engine); +} + +void QQmlDebugServerImpl::removeEngine(QJSEngine *engine) +{ + // to be executed outside of debugger thread + Q_ASSERT(QThread::currentThread() != &m_thread); + + QMutexLocker locker(&m_helloMutex); + Q_ASSERT(m_engineConditions.contains(engine)); + + for (QQmlDebugService *service : qAsConst(m_plugins)) + service->engineAboutToBeRemoved(engine); + + m_engineConditions[engine].waitForServices(&m_helloMutex, m_plugins.count()); + + for (QQmlDebugService *service : qAsConst(m_plugins)) + service->engineRemoved(engine); + + m_engineConditions.remove(engine); +} + +bool QQmlDebugServerImpl::hasEngine(QJSEngine *engine) const +{ + QMutexLocker locker(&m_helloMutex); + QHash::ConstIterator i = m_engineConditions.constFind(engine); + // if we're still waiting the engine isn't fully "there", yet, nor fully removed. + return i != m_engineConditions.constEnd() && !i.value().isWaiting(); +} + +bool QQmlDebugServerImpl::addService(const QString &name, QQmlDebugService *service) +{ + // to be executed before thread starts + Q_ASSERT(!m_thread.isRunning()); + + if (!service || m_plugins.contains(name)) + return false; + + connect(service, &QQmlDebugService::messageToClient, + this, &QQmlDebugServerImpl::sendMessage); + connect(service, &QQmlDebugService::messagesToClient, + this, &QQmlDebugServerImpl::sendMessages); + + connect(service, &QQmlDebugService::attachedToEngine, + this, &QQmlDebugServerImpl::wakeEngine, Qt::QueuedConnection); + connect(service, &QQmlDebugService::detachedFromEngine, + this, &QQmlDebugServerImpl::wakeEngine, Qt::QueuedConnection); + + service->setState(QQmlDebugService::Unavailable); + m_plugins.insert(name, service); + + return true; +} + +bool QQmlDebugServerImpl::removeService(const QString &name) +{ + // to be executed after thread ends + Q_ASSERT(!m_thread.isRunning()); + + QQmlDebugService *service = m_plugins.value(name); + if (!service) + return false; + + m_plugins.remove(name); + service->setState(QQmlDebugService::NotConnected); + + disconnect(service, &QQmlDebugService::detachedFromEngine, + this, &QQmlDebugServerImpl::wakeEngine); + disconnect(service, &QQmlDebugService::attachedToEngine, + this, &QQmlDebugServerImpl::wakeEngine); + + disconnect(service, &QQmlDebugService::messagesToClient, + this, &QQmlDebugServerImpl::sendMessages); + disconnect(service, &QQmlDebugService::messageToClient, + this, &QQmlDebugServerImpl::sendMessage); + + return true; +} + +bool QQmlDebugServerImpl::canSendMessage(const QString &name) +{ + // to be executed in debugger thread + Q_ASSERT(QThread::currentThread() == thread()); + return m_connection && m_connection->isConnected() && m_protocol && + m_clientPlugins.contains(name); +} + +void QQmlDebugServerImpl::doSendMessage(const QString &name, const QByteArray &message) +{ + QQmlDebugPacket out; + out << name << message; + m_protocol->send(out.data()); +} + +void QQmlDebugServerImpl::sendMessage(const QString &name, const QByteArray &message) +{ + if (canSendMessage(name)) { + doSendMessage(name, message); + m_connection->flush(); + } +} + +void QQmlDebugServerImpl::sendMessages(const QString &name, const QList &messages) +{ + if (canSendMessage(name)) { + QQmlDebugPacket out; + out << name; + for (const QByteArray &message : messages) + out << message; + m_protocol->send(out.data()); + m_connection->flush(); + } +} + +void QQmlDebugServerImpl::wakeEngine(QJSEngine *engine) +{ + // to be executed in debugger thread + Q_ASSERT(QThread::currentThread() == thread()); + + QMutexLocker locker(&m_helloMutex); + m_engineConditions[engine].wake(); +} + +bool QQmlDebugServerImpl::EngineCondition::waitForServices(QMutex *locked, int num) +{ + Q_ASSERT_X(numServices == 0, Q_FUNC_INFO, "Request to wait again before previous wait finished"); + numServices = num; + return numServices > 0 ? condition->wait(locked) : true; +} + +void QQmlDebugServerImpl::EngineCondition::wake() +{ + if (--numServices == 0) + condition->wakeAll(); + Q_ASSERT_X(numServices >=0, Q_FUNC_INFO, "Woken more often than #services."); +} + +void QQmlDebugServerImpl::setDevice(QIODevice *socket) +{ + m_protocol = new QPacketProtocol(socket, this); + QObject::connect(m_protocol, &QPacketProtocol::readyRead, + this, &QQmlDebugServerImpl::receiveMessage); + QObject::connect(m_protocol, &QPacketProtocol::error, + this, &QQmlDebugServerImpl::protocolError); + + if (blockingMode()) + m_protocol->waitForReadyRead(-1); +} + +void QQmlDebugServerImpl::protocolError() +{ + qWarning("QML Debugger: A protocol error has occurred! Giving up ..."); + m_connection->disconnect(); + // protocol might still be processing packages at this point + m_protocol->deleteLater(); + m_protocol = nullptr; +} + +QQmlDebugConnector *QQmlDebugServerFactory::create(const QString &key) +{ + // Cannot parent it to this because it gets moved to another thread + return (key == QLatin1String("QQmlDebugServer") ? new QQmlDebugServerImpl : nullptr); +} + +QT_END_NAMESPACE + +#include "moc_qqmldebugserverfactory.cpp" +#include "qqmldebugserverfactory.moc" diff --git a/src/plugins/qmltooling/qmldbg_tcp/CMakeLists.txt b/src/plugins/qmltooling/qmldbg_tcp/CMakeLists.txt index 5fc079ea4a0..aaed477b60a 100644 --- a/src/plugins/qmltooling/qmldbg_tcp/CMakeLists.txt +++ b/src/plugins/qmltooling/qmldbg_tcp/CMakeLists.txt @@ -4,13 +4,14 @@ ## QTcpServerConnectionFactory Plugin: ##################################################################### -qt_internal_add_plugin(QTcpServerConnectionFactory +qt_internal_add_plugin(QTcpServerConnectionFactoryPlugin OUTPUT_NAME qmldbg_tcp - TYPE qmltooling + CLASS_NAME QTcpServerConnectionFactory + PLUGIN_TYPE qmltooling SOURCES qtcpserverconnection.cpp qtcpserverconnectionfactory.h - PUBLIC_LIBRARIES + LIBRARIES Qt::Network Qt::QmlPrivate ) diff --git a/src/plugins/scenegraph/openvg/CMakeLists.txt b/src/plugins/scenegraph/openvg/CMakeLists.txt index 8be9b4fad3c..da1cb42656a 100644 --- a/src/plugins/scenegraph/openvg/CMakeLists.txt +++ b/src/plugins/scenegraph/openvg/CMakeLists.txt @@ -4,9 +4,10 @@ ## QSGOpenVGAdaptation Plugin: ##################################################################### -qt_internal_add_plugin(QSGOpenVGAdaptation +qt_internal_add_plugin(QSGOpenVGAdaptationPlugin OUTPUT_NAME qsgopenvgbackend - TYPE scenegraph + CLASS_NAME QSGOpenVGAdaptation + PLUGIN_TYPE scenegraph TARGET_PRODUCT "Qt Quick OpenVG Renderer (Qt $$QT_VERSION)" TARGET_DESCRIPTION "Quick OpenVG Renderer for Qt." SOURCES @@ -46,22 +47,22 @@ qt_internal_add_plugin(QSGOpenVGAdaptation ## Scopes: ##################################################################### -qt_internal_extend_target(QSGOpenVGAdaptation CONDITION CMAKE_BUILD_TYPE STREQUAL Debug AND debug_and_release +qt_internal_extend_target(QSGOpenVGAdaptationPlugin CONDITION CMAKE_BUILD_TYPE STREQUAL Debug AND debug_and_release INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/../../../quick/.tracegen/debug ) -qt_internal_extend_target(QSGOpenVGAdaptation CONDITION debug_and_release AND NOT CMAKE_BUILD_TYPE STREQUAL Debug +qt_internal_extend_target(QSGOpenVGAdaptationPlugin CONDITION debug_and_release AND NOT CMAKE_BUILD_TYPE STREQUAL Debug INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/../../../quick/.tracegen/release ) -qt_internal_extend_target(QSGOpenVGAdaptation CONDITION NOT debug_and_release +qt_internal_extend_target(QSGOpenVGAdaptationPlugin CONDITION NOT debug_and_release INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/../../../quick/.tracegen ) -qt_internal_extend_target(QSGOpenVGAdaptation CONDITION QT_FEATURE_quick_sprite +qt_internal_extend_target(QSGOpenVGAdaptationPlugin CONDITION QT_FEATURE_quick_sprite SOURCES qsgopenvgspritenode.cpp qsgopenvgspritenode.h ) diff --git a/src/plugins/scenegraph/openvg/qsgopenvghelpers.cpp b/src/plugins/scenegraph/openvg/qsgopenvghelpers.cpp index ab5cfb48b81..615d6e87267 100644 --- a/src/plugins/scenegraph/openvg/qsgopenvghelpers.cpp +++ b/src/plugins/scenegraph/openvg/qsgopenvghelpers.cpp @@ -420,6 +420,7 @@ QImage::Format qVGImageFormatToQImageFormat(VGImageFormat format) break; case VG_sL_8: qImageFormat = QImage::Format_Grayscale8; + break; default: qImageFormat = QImage::Format_ARGB32; break; diff --git a/src/qml/.prev_configure.cmake b/src/qml/.prev_configure.cmake deleted file mode 100644 index b4fb15038c1..00000000000 --- a/src/qml/.prev_configure.cmake +++ /dev/null @@ -1,175 +0,0 @@ - - -#### Inputs - - - -#### Libraries - - - -#### Tests - -# pointer_32bit -qt_config_compile_test(pointer_32bit - LABEL "32bit pointers" - CODE -"int main(void) -{ - /* BEGIN TEST: */ -static_assert(sizeof(void *) == 4, \"fail\"); - /* END TEST: */ - return 0; -} -") - -# pointer_64bit -qt_config_compile_test(pointer_64bit - LABEL "64bit pointers" - CODE -"int main(void) -{ - /* BEGIN TEST: */ -static_assert(sizeof(void *) == 8, \"fail\"); - /* END TEST: */ - return 0; -} -") - -# arm_thumb -qt_config_compile_test(arm_thumb - LABEL "THUMB mode on ARM" - CODE -"int main(void) -{ - /* BEGIN TEST: */ -#if defined(thumb2) || defined(__thumb2__) -# define THUMB_OK -#elif (defined(__thumb) || defined(__thumb__)) && __TARGET_ARCH_THUMB-0 == 4 -# define THUMB_OK -#elif defined(__ARM_ARCH_ISA_THUMB) && __ARM_ARCH_ISA_THUMB == 2 -// clang 3.5 and later will set this if the core supports the Thumb-2 ISA. -# define THUMB_OK -#else -# error \"fail\" -#endif - /* END TEST: */ - return 0; -} -") - -# arm_fp -qt_config_compile_test(arm_fp - LABEL "Sufficiently recent FPU on ARM" - CODE -"int main(void) -{ - /* BEGIN TEST: */ -// if !defined(__ARM_FP) we might be on MSVC or we might have a device -// without an FPU. -// TODO: The latter case is not supported, but the test still succeeds. -#if defined(__ARM_FP) && (__ARM_FP <= 0x04) -# error \"fail\" -#endif - /* END TEST: */ - return 0; -} -") - - - -#### Features - -qt_feature("qml-network" PUBLIC - SECTION "QML" - LABEL "QML network support" - PURPOSE "Provides network transparency." - CONDITION QT_FEATURE_network -) -# On arm and arm64 we need a specialization of cacheFlush() for each OS to be enabeled. Therefore the config white list. Also Mind that e.g. x86_32 has arch.x86_64 but 32bit pointers. Therefore the checks for architecture and pointer size. Finally, ios and tvos can technically use the JIT but Apple does not allow it. Therefore, it's disabled by default. -qt_feature("qml-jit" PRIVATE - SECTION "QML" - LABEL "QML just-in-time compiler" - PURPOSE "Provides a JIT for QML and JavaScript" - AUTODETECT NOT IOS AND NOT TVOS - CONDITION ( ( ( TEST_architecture_arch STREQUAL i386 ) AND TEST_pointer_32bit AND QT_FEATURE_sse2 ) OR ( ( TEST_architecture_arch STREQUAL x86_64 ) AND TEST_pointer_64bit AND QT_FEATURE_sse2 ) OR ( ( TEST_architecture_arch STREQUAL arm ) AND TEST_pointer_32bit AND TEST_arm_fp AND TEST_arm_thumb AND ( LINUX OR IOS OR TVOS OR QNX ) ) OR ( ( TEST_architecture_arch STREQUAL arm64 ) AND TEST_pointer_64bit AND TEST_arm_fp AND ( LINUX OR IOS OR TVOS OR QNX OR INTEGRITY ) ) ) -) -qt_feature("qml-debug" PUBLIC - SECTION "QML" - LABEL "QML debugging and profiling support" - PURPOSE "Provides infrastructure and plugins for debugging and profiling." -) -qt_feature("qml-profiler" PRIVATE - SECTION "QML" - LABEL "Command line QML Profiler" - PURPOSE "Supports retrieving QML tracing data from an application." - CONDITION ( QT_FEATURE_commandlineparser ) AND ( QT_FEATURE_qml_debug ) AND ( QT_FEATURE_qml_network AND QT_FEATURE_localserver ) AND ( QT_FEATURE_xmlstreamwriter ) -) -qt_feature("qml-preview" PRIVATE - SECTION "QML" - LABEL "Command line QML Preview tool" - PURPOSE "Updates QML documents in your application live as you change them on disk" - CONDITION ( QT_FEATURE_commandlineparser ) AND ( QT_FEATURE_filesystemwatcher ) AND ( QT_FEATURE_qml_network AND QT_FEATURE_localserver ) AND ( QT_FEATURE_process ) AND ( QT_FEATURE_qml_debug ) -) -qt_feature("qml-devtools" PRIVATE - SECTION "QML" - LABEL "QML Development Tools" - PURPOSE "Provides the QmlDevtools library and various utilities." -) -qt_feature("qml-sequence-object" PRIVATE - SECTION "QML" - LABEL "QML sequence object" - PURPOSE "Supports mapping sequence types into QML." -) -qt_feature("qml-xml-http-request" PRIVATE - SECTION "QML" - LABEL "QML XML http request" - PURPOSE "Provides support for sending XML http requests." - CONDITION ( QT_FEATURE_xmlstreamreader ) AND ( QT_FEATURE_qml_network ) -) -qt_feature("qml-locale" PRIVATE - SECTION "QML" - LABEL "QML Locale" - PURPOSE "Provides support for locales in QML." -) -qt_feature("qml-animation" PRIVATE - SECTION "QML" - LABEL "QML Animations" - PURPOSE "Provides support for animations and timers in QML." - CONDITION QT_FEATURE_animation -) -qt_feature("qml-worker-script" PRIVATE - SECTION "QML" - LABEL "QML WorkerScript" - PURPOSE "Enables the use of threads in QML." - CONDITION QT_FEATURE_thread -) -qt_feature("qml-itemmodel" PRIVATE - SECTION "QML" - LABEL "QML Item Model" - PURPOSE "Provides the item model for item views in QML" - CONDITION QT_FEATURE_itemmodel -) -qt_feature("qml-xmllistmodel" PRIVATE - SECTION "QML" - LABEL "QML XmlListModel" - PURPOSE "Enable XmlListModel in QML" - CONDITION QT_FEATURE_qml_itemmodel AND QT_FEATURE_future -) -qt_feature("qml-python" PRIVATE - LABEL "python" - CONDITION tests.qml-python OR FIXME -) -qt_configure_add_summary_section(NAME "Qt QML") -qt_configure_add_summary_entry(ARGS "qml-network") -qt_configure_add_summary_entry(ARGS "qml-debug") -qt_configure_add_summary_entry(ARGS "qml-jit") -qt_configure_add_summary_entry(ARGS "qml-sequence-object") -qt_configure_add_summary_entry(ARGS "qml-xml-http-request") -qt_configure_add_summary_entry(ARGS "qml-locale") -qt_configure_end_summary_section() # end of "Qt QML" section -qt_configure_add_report_entry( - TYPE ERROR - MESSAGE "Python is required to build QtQml." - CONDITION NOT QT_FEATURE_qml_python -) diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt index adf62af47fe..1cacf0d8893 100644 --- a/src/qml/CMakeLists.txt +++ b/src/qml/CMakeLists.txt @@ -19,6 +19,15 @@ if (QT_FEATURE_qml_worker_script) ) endif() +set(extra_cmake_files) +set(extra_cmake_includes) +if(ANDROID) + list(APPEND extra_cmake_files + "${CMAKE_CURRENT_LIST_DIR}/${INSTALL_CMAKE_NAMESPACE}AndroidQmlMacros.cmake") + list(APPEND extra_cmake_includes + "${INSTALL_CMAKE_NAMESPACE}AndroidQmlMacros.cmake") +endif() + qt_internal_add_qml_module(Qml URI "QtQml" VERSION "${PROJECT_VERSION}" @@ -286,6 +295,7 @@ qt_internal_add_qml_module(Qml qml/qqmlopenmetaobject.cpp qml/qqmlopenmetaobject_p.h qml/qqmlparserstatus.cpp qml/qqmlparserstatus.h qml/qqmlplatform.cpp qml/qqmlplatform_p.h + qml/qqmlpluginimporter.cpp qml/qqmlpluginimporter_p.h qml/qqmlprivate.h qml/qqmlproperty.cpp qml/qqmlproperty.h qml/qqmlproperty_p.h qml/qqmlpropertybinding.cpp qml/qqmlpropertybinding_p.h @@ -378,9 +388,22 @@ qt_internal_add_qml_module(Qml Qt::CorePrivate EXTRA_CMAKE_FILES "${CMAKE_CURRENT_LIST_DIR}/${INSTALL_CMAKE_NAMESPACE}qmldirTemplate.cmake.in" - "${CMAKE_CURRENT_LIST_DIR}/${INSTALL_CMAKE_NAMESPACE}QmlImportScannerTemplate.cpp.in" "${CMAKE_CURRENT_LIST_DIR}/${INSTALL_CMAKE_NAMESPACE}QmlPluginTemplate.cpp.in" -) + "${CMAKE_CURRENT_LIST_DIR}/${INSTALL_CMAKE_NAMESPACE}QmlFindQmlscInternal.cmake" + ${extra_cmake_files} + EXTRA_CMAKE_INCLUDES + "${INSTALL_CMAKE_NAMESPACE}QmlFindQmlscInternal.cmake" + ${extra_cmake_includes} +) + +# Linking to the static qml plugin should also automatically link to the worker script +# static plugin otherwise you get errors like +# module "QtQml.WorkerScript" plugin "workerscriptplugin" not found +# import QtQuick 2.0 +# ^ +if(QT_FEATURE_qml_worker_script) + _qt_internal_add_qml_static_plugin_dependency(qmlplugin workerscriptplugin) +endif() # special case begin remove the block, handled manually # QLALR Grammars: @@ -475,22 +498,6 @@ qt_internal_extend_target(Qml CONDITION QT_FEATURE_qml_animation animations ) -#### Keys ignored in scope 18:.:common:common/common.pri:NOT build_pass: -# compile_hash_contents = "// Generated file, DO NOT EDIT" "$${LITERAL_HASH}define QML_COMPILE_HASH "$$QML_COMPILE_HASH"" "$${LITERAL_HASH}define QML_COMPILE_HASH_LENGTH $$str_size($$QML_COMPILE_HASH)" -# tag = -# tagFile = "$$PWD/../../.tag" - -#### Keys ignored in scope 19:.:common:common/common.pri:EXISTS _ss_tagFile: -# QMAKE_INTERNAL_INCLUDED_FILES = "$$tagFile" -# tag = "$$cat($$tagFile, singleline)" - -#### Keys ignored in scope 20:.:common:common/common.pri:NOT tag___equals____ss_{LITERAL_DOLLAR}Format AND %H_ss_{LITERAL_DOLLAR}: -# QML_COMPILE_HASH = "$$tag" - -#### Keys ignored in scope 22:.:common:common/common.pri:EXISTS _ss_PWD/../../.git: -# QML_COMPILE_HASH = "$$commit" -# commit = "$$system(git rev-parse HEAD)" - qt_internal_extend_target(Qml CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STREQUAL 5 COMPILE_OPTIONS -fno-strict-aliasing @@ -503,7 +510,7 @@ qt_internal_extend_target(Qml CONDITION QT_FEATURE_qml_debug debugger/qqmldebug.cpp debugger/qqmldebugconnector.cpp debugger/qqmldebugpluginmanager_p.h - debugger/qqmldebugserver_p.h + debugger/qqmldebugserver.cpp debugger/qqmldebugserver_p.h debugger/qqmldebugserverconnection_p.h debugger/qqmldebugservice.cpp debugger/qqmldebugservice_p.h debugger/qqmldebugservicefactory_p.h @@ -569,11 +576,6 @@ qt_internal_extend_target(Qml CONDITION hpux-_x_ OR solaris-_x_ OR (QT_FEATURE_c rt ) -qt_internal_extend_target(Qml CONDITION QT_FEATURE_qml_itemmodel - SOURCES - types/qqmlmodelindexvaluetype.cpp types/qqmlmodelindexvaluetype_p.h -) - qt_internal_extend_target(Qml CONDITION disassembler AND ((TEST_architecture_arch STREQUAL "i386") OR (TEST_architecture_arch STREQUAL "x86_64")) DEFINES WTF_USE_UDIS86=1 @@ -666,3 +668,13 @@ qt_internal_create_tracepoints(Qml qtqml.tracepoints) qt_internal_add_docs(Qml doc/qtqml.qdocconf ) + +# include snippet projects for developer shared builds +# static builds fail with +# CMake Error: AUTOMOC for target qt_target_qml_sources_example_resources_3: +# The "moc" executable does not exist +if(QT_FEATURE_private_tests AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.19" AND QT_BUILD_SHARED_LIBS) + add_subdirectory(doc/snippets/cmake/qt_target_qml_sources) + qt_autogen_tools(qt_target_qml_sources_example ENABLE_AUTOGEN_TOOLS moc) + qt_autogen_tools(qt_target_qml_sources_exampleplugin ENABLE_AUTOGEN_TOOLS moc) +endif() diff --git a/src/qml/Qt6AndroidQmlMacros.cmake b/src/qml/Qt6AndroidQmlMacros.cmake new file mode 100644 index 00000000000..12be5155317 --- /dev/null +++ b/src/qml/Qt6AndroidQmlMacros.cmake @@ -0,0 +1,21 @@ +# The function collects qml root paths and sets the QT_QML_ROOT_PATH property to the ${target} +# based on the provided qml source files. +function(_qt_internal_collect_qml_root_paths target) + get_target_property(qml_root_paths ${target} QT_QML_ROOT_PATH) + if(NOT qml_root_paths) + set(qml_root_paths "") + endif() + foreach(file IN LISTS ARGN) + get_filename_component(extension "${file}" LAST_EXT) + if(NOT extension STREQUAL ".qml") + continue() + endif() + + get_filename_component(dir "${file}" DIRECTORY) + get_filename_component(absolute_dir "${dir}" ABSOLUTE) + list(APPEND qml_root_paths "${absolute_dir}") + endforeach() + + list(REMOVE_DUPLICATES qml_root_paths) + set_target_properties(${target} PROPERTIES QT_QML_ROOT_PATH "${qml_root_paths}") +endfunction() diff --git a/src/qml/Qt6QmlBuildInternals.cmake b/src/qml/Qt6QmlBuildInternals.cmake index 48ae45cf8cd..c84a7a9d901 100644 --- a/src/qml/Qt6QmlBuildInternals.cmake +++ b/src/qml/Qt6QmlBuildInternals.cmake @@ -4,37 +4,12 @@ include_guard(GLOBAL) -# This function is essentially a wrapper around qt6_add_qml_module(). -# It creates the targets explicitly and sets up internal properties before -# passing those targets to qt6_add_qml_module() for further updates. -# All keywords supported by qt_internal_add_module() can be used, as can most -# keywords for qt6_add_qml_module() except RESOURCE_PREFIX and -# OUTPUT_TARGETS. -# -# OUTPUT_DIRECTORY and INSTALL_DIRECTORY will be given more appropriate defaults -# if not provided by the caller. The defaults are usually what you want to use. -# -# - SOURCES is only passed through to qt_internal_add_plugin() or -# qt_internal_add_module() but not to qt6_add_qml_module(). -# -# See qt_internal_add_plugin() and qt6_add_qml_module() for the full set of -# supported keywords. -function(qt_internal_add_qml_module target) - - qt_internal_get_internal_add_module_keywords( - module_option_args - module_single_args - module_multi_args - ) - - # We don't want to pass CLASS_NAME to qt_internal_add_plugin(), we will - # pass it to qt6_add_qml_module() to handle instead. qt_internal_add_plugin() - # would just ignore it anyway because we set TYPE to qml_plugin, but we have - # to remove it to prevent duplicates in argument parsing. - list(REMOVE_ITEM module_single_args CLASS_NAME) - - set(qml_module_option_args +macro(qt_internal_get_internal_add_qml_module_keywords + option_args single_args multi_args + internal_option_args internal_single_args internal_multi_args) + set(${option_args} DESIGNER_SUPPORTED + NO_PLUGIN NO_PLUGIN_OPTIONAL NO_CREATE_PLUGIN_TARGET NO_GENERATE_PLUGIN_SOURCE @@ -43,17 +18,8 @@ function(qt_internal_add_qml_module target) NO_LINT NO_CACHEGEN ) - # TODO: Remove these once all repos have been updated to not use them - set(ignore_option_args - SKIP_TYPE_REGISTRATION # Now always done - PLUGIN_OPTIONAL # Now the default - GENERATE_QMLTYPES # Now the default - INSTALL_QMLTYPES # Now the default - ) - - set(qml_module_single_args + set(${single_args} URI - TARGET_PATH VERSION PLUGIN_TARGET TYPEINFO @@ -61,51 +27,87 @@ function(qt_internal_add_qml_module target) CLASSNAME # TODO: Remove once all other repos have been updated to use # CLASS_NAME instead. ) - - set(qml_module_multi_args - # SOURCES will be handled by qt_internal_add_module() + set(${multi_args} QML_FILES + RESOURCES IMPORTS IMPORT_PATH OPTIONAL_IMPORTS DEPENDENCIES PAST_MAJOR_VERSIONS ) - # Args used by qt_internal_add_qml_module directly, which should not be passed to any other # functions. # - # NO_CREATE_BACKING_TARGET option skips the creation of the backing target. It is useful in - # the case where the backing target already exists, a plugin target should still be created - # and the qml specific install rules should still apply to the backing target. - # # INSTALL_SOURCE_QMLTYPES takes a path to an existing plugins.qmltypes file that should be # installed. # # INSTALL_SOURCE_QMLDIR takes a path to an existing qmldir file that should be installed. - set(internal_option_args - NO_CREATE_BACKING_TARGET + set(${internal_option_args} ) - - set(internal_single_args + set(${internal_single_args} INSTALL_SOURCE_QMLTYPES INSTALL_SOURCE_QMLDIR ) + set(${internal_multi_args} + ) + +endmacro() + +# This function is essentially a wrapper around qt6_add_qml_module(). +# It creates the targets explicitly and sets up internal properties before +# passing those targets to qt6_add_qml_module() for further updates. +# All keywords supported by qt_internal_add_module() can be used, as can most +# keywords for qt6_add_qml_module() except RESOURCE_PREFIX and +# OUTPUT_TARGETS. +# +# OUTPUT_DIRECTORY and INSTALL_DIRECTORY will be given more appropriate defaults +# if not provided by the caller. The defaults are usually what you want to use. +# +# - SOURCES is only passed through to qt_internal_add_plugin() or +# qt_internal_add_module() but not to qt6_add_qml_module(). +# +# See qt_internal_add_plugin() and qt6_add_qml_module() for the full set of +# supported keywords. +function(qt_internal_add_qml_module target) + + qt_internal_get_internal_add_module_keywords( + module_option_args + module_single_args + module_multi_args + ) + + qt_internal_get_internal_add_qml_module_keywords( + qml_module_option_args + qml_module_single_args + qml_module_multi_args + qml_module_internal_option_args + qml_module_internal_single_args + qml_module_internal_multi_args + ) + # TODO: Remove these once all repos have been updated to not use them + set(ignore_option_args + SKIP_TYPE_REGISTRATION # Now always done + PLUGIN_OPTIONAL # Now the default + GENERATE_QMLTYPES # Now the default + INSTALL_QMLTYPES # Now the default + ) set(option_args ${module_option_args} ${qml_module_option_args} ${ignore_option_args} - ${internal_option_args} + ${qml_module_internal_option_args} ) set(single_args ${module_single_args} ${qml_module_single_args} - ${internal_single_args} + ${qml_module_internal_single_args} ) set(multi_args ${module_multi_args} ${qml_module_multi_args} + ${qml_module_internal_multi_args} ) qt_parse_all_arguments(arg "qt_internal_add_qml_module" @@ -115,16 +117,17 @@ function(qt_internal_add_qml_module target) ${ARGN} ) - if(NOT arg_TARGET_PATH) - string(REPLACE "." "/" arg_TARGET_PATH ${arg_URI}) - endif() + set(QT_QML_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_QMLDIR}") + string(REPLACE "." "/" target_path ${arg_URI}) if(NOT arg_OUTPUT_DIRECTORY) - set(arg_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_QMLDIR}/${arg_TARGET_PATH}") + set(arg_OUTPUT_DIRECTORY "${QT_QML_OUTPUT_DIRECTORY}/${target_path}") endif() if(NOT arg_INSTALL_DIRECTORY) - set(arg_INSTALL_DIRECTORY "${INSTALL_QMLDIR}/${arg_TARGET_PATH}") + set(arg_INSTALL_DIRECTORY "${INSTALL_QMLDIR}/${target_path}") endif() - if(NOT arg_PLUGIN_TARGET) + if(arg_NO_PLUGIN) + unset(arg_PLUGIN_TARGET) + elseif(NOT arg_PLUGIN_TARGET) set(arg_PLUGIN_TARGET ${target}plugin) endif() @@ -141,8 +144,9 @@ function(qt_internal_add_qml_module target) endif() set(plugin_args "") - if(NOT arg_PLUGIN_TARGET STREQUAL target) - if(NOT arg_NO_CREATE_BACKING_TARGET) + if(arg_NO_PLUGIN OR NOT arg_PLUGIN_TARGET STREQUAL target) + # Allow using an existing backing target. + if(NOT TARGET ${target}) # Create the backing target now to handle module-related things qt_remove_args(module_args ARGS_TO_REMOVE @@ -150,8 +154,9 @@ function(qt_internal_add_qml_module target) ${qml_module_option_args} ${qml_module_single_args} ${qml_module_multi_args} - ${internal_option_args} - ${internal_single_args} + ${qml_module_internal_option_args} + ${qml_module_internal_single_args} + ${qml_module_internal_multi_args} OUTPUT_DIRECTORY INSTALL_DIRECTORY ALL_ARGS @@ -162,6 +167,9 @@ function(qt_internal_add_qml_module target) ${ARGN} ) qt_internal_add_module(${target} ${module_args}) + elseif(arg_SOURCES) + # If a module target was pre-created, we still need to pass the additional sources. + target_sources(${target} PRIVATE ${arg_SOURCES}) endif() else() # Since we are not creating a separate backing target, we have to pass @@ -192,10 +200,20 @@ function(qt_internal_add_qml_module target) ) endif() - if(NOT arg_NO_CREATE_PLUGIN_TARGET) + set(add_qml_module_args "") + + if(NOT arg_NO_PLUGIN AND NOT arg_NO_CREATE_PLUGIN_TARGET) + # If the qt_internal_add_qml_module call didn't specify a CLASS_NAME, we need to pre-compute + # it here and pass it along to qt_internal_add_plugin -> qt_add_plugin so that + # qt_add_qml_plugin does not complain about differing class names (the default pre-computed + # class name of a regular plugin and qml plugin are different). + if(NOT arg_CLASS_NAME) + _qt_internal_compute_qml_plugin_class_name_from_uri("${arg_URI}" arg_CLASS_NAME) + endif() + # Create plugin target now so we can set internal things list(APPEND plugin_args - TYPE qml_plugin + PLUGIN_TYPE qml_plugin DEFAULT_IF FALSE OUTPUT_DIRECTORY ${arg_OUTPUT_DIRECTORY} INSTALL_DIRECTORY ${arg_INSTALL_DIRECTORY} @@ -204,6 +222,40 @@ function(qt_internal_add_qml_module target) qt_internal_add_plugin(${arg_PLUGIN_TARGET} ${plugin_args}) + # Use the plugin target name as the main part of the plugin basename. + set(plugin_basename "${arg_PLUGIN_TARGET}") + + # If the target name already ends with a "plugin" suffix, remove it and re-add it to the end + # of the base name after the infix. + if(plugin_basename MATCHES "(.+)plugin$") + set(plugin_basename "${CMAKE_MATCH_1}") + endif() + + # Add a the infix if Qt was configured with one. + if(QT_LIBINFIX) + string(APPEND plugin_basename "${QT_LIBINFIX}") + endif() + + # Add the "plugin" suffix after the infix. + string(APPEND plugin_basename "plugin") + + # Lowercase the whole thing and use it as the basename of the plugin library. + string(TOLOWER "${plugin_basename}" plugin_basename) + set_target_properties(${arg_PLUGIN_TARGET} PROPERTIES + OUTPUT_NAME "${plugin_basename}" + ) + + get_target_property(export_name ${arg_PLUGIN_TARGET} EXPORT_NAME) + if(export_name) + list(APPEND add_qml_module_args + INSTALLED_PLUGIN_TARGET "${QT_CMAKE_EXPORT_NAMESPACE}::${export_name}" + ) + else() + list(APPEND add_qml_module_args + INSTALLED_PLUGIN_TARGET "${QT_CMAKE_EXPORT_NAMESPACE}::${arg_PLUGIN_TARGET}" + ) + endif() + if(NOT arg_PLUGIN_TARGET STREQUAL target) get_target_property(lib_type ${arg_PLUGIN_TARGET} TYPE) if(lib_type STREQUAL "STATIC_LIBRARY") @@ -220,14 +272,6 @@ function(qt_internal_add_qml_module target) ) endif() endif() - - # FIXME: Some repos expect this to be set and use it to install other - # things relative to it. They should just specify the install - # location directly. Once the other repos have been updated to - # not rely on this, remove this property. - set_target_properties(${arg_PLUGIN_TARGET} PROPERTIES - QT_QML_MODULE_INSTALL_DIR ${arg_INSTALL_DIRECTORY} - ) endif() # TODO: Check if we need arg_SOURCES in this condition @@ -249,37 +293,87 @@ function(qt_internal_add_qml_module target) endif() endforeach() - if(QT_LIBINFIX) - list(APPEND add_qml_module_args __QT_INTERNAL_QT_LIBINFIX "${QT_LIBINFIX}") - endif() - # Update the backing and plugin targets with qml-specific things. qt6_add_qml_module(${target} ${add_qml_module_args} + __QT_INTERNAL_INSTALL_METATYPES_JSON OUTPUT_DIRECTORY ${arg_OUTPUT_DIRECTORY} RESOURCE_PREFIX "/qt-project.org/imports" - OUTPUT_TARGETS resource_targets + OUTPUT_TARGETS output_targets ) - if(resource_targets) - qt_install(TARGETS ${resource_targets} - EXPORT "${INSTALL_CMAKE_NAMESPACE}${target}Targets" - DESTINATION "${arg_INSTALL_DIRECTORY}" - ) - qt_internal_record_rcc_object_files(${target} "${resource_targets}" - INSTALL_DIRECTORY "${arg_INSTALL_DIRECTORY}" - ) + if(output_targets) + set(plugin_export_targets) + set(backing_lib_export_targets) + + # Separate which output target should go to which export set. + # The plugin initializer library should go to the plugin export set, the rest should go to + # the backing lib export set. + # In the case when the plugin target is the same as the backing lib target, all of the + # output targets will go to the plugin export set. + + foreach(output_target IN LISTS output_targets) + get_target_property(is_plugin_init ${output_target} _is_qt_plugin_init_target) + if(is_plugin_init) + list(APPEND plugin_export_targets ${output_target}) + + # Plugin initializers associated with an internal module need the internal + # platform flags. + qt_internal_link_internal_platform_for_object_library("${output_target}") + else() + list(APPEND backing_lib_export_targets ${output_target}) + endif() + endforeach() + + if(backing_lib_export_targets) + qt_install(TARGETS ${backing_lib_export_targets} + EXPORT "${INSTALL_CMAKE_NAMESPACE}${target}Targets" + DESTINATION "${arg_INSTALL_DIRECTORY}" + ) + qt_internal_record_rcc_object_files(${target} "${backing_lib_export_targets}" + INSTALL_DIRECTORY "${arg_INSTALL_DIRECTORY}" + ) + + qt_internal_add_targets_to_additional_targets_export_file( + TARGETS ${backing_lib_export_targets} + EXPORT_NAME_PREFIX "${INSTALL_CMAKE_NAMESPACE}${target}" + ) + endif() + + if(arg_PLUGIN_TARGET AND plugin_export_targets) + qt_install(TARGETS ${plugin_export_targets} + EXPORT "${INSTALL_CMAKE_NAMESPACE}${arg_PLUGIN_TARGET}Targets" + DESTINATION "${arg_INSTALL_DIRECTORY}" + ) + + qt_internal_add_targets_to_additional_targets_export_file( + TARGETS ${plugin_export_targets} + EXPORT_NAME_PREFIX "${INSTALL_CMAKE_NAMESPACE}${arg_PLUGIN_TARGET}" + ) + endif() endif() - # Empty list will not cause an installation error. - qt_install( - FILES $ - DESTINATION "${arg_INSTALL_DIRECTORY}" - ) + if(DEFINED arg_QML_FILES OR DEFINED arg_RESOURCES) + foreach(resource_file IN LISTS arg_QML_FILES arg_RESOURCES) + __qt_get_relative_resource_path_for_file(file_resource_path ${resource_file}) + get_filename_component(resource_dir ${file_resource_path} DIRECTORY) + get_filename_component(resource_name ${file_resource_path} NAME) + if(resource_dir) + set(dest "${arg_INSTALL_DIRECTORY}/${resource_dir}") + else() + set(dest "${arg_INSTALL_DIRECTORY}") + endif() + qt_install( + FILES ${resource_file} + DESTINATION ${dest} + RENAME ${resource_name} + ) + endforeach() + endif() if(NOT arg_NO_GENERATE_QMLTYPES) qt_install( - FILES ${arg_OUTPUT_DIRECTORY}/$ + FILES ${arg_OUTPUT_DIRECTORY}/$ DESTINATION "${arg_INSTALL_DIRECTORY}" ) endif() @@ -292,10 +386,6 @@ function(qt_internal_add_qml_module target) endif() if(arg_INSTALL_SOURCE_QMLTYPES) - message(AUTHOR_WARNING - "INSTALL_SOURCE_QMLTYPES option is deprecated and should not be used. " - "Please port your module to use declarative type registration.") - set(files ${arg_INSTALL_SOURCE_QMLTYPES}) if(QT_WILL_INSTALL) install( @@ -311,10 +401,6 @@ function(qt_internal_add_qml_module target) endif() if(arg_INSTALL_SOURCE_QMLDIR) - message(AUTHOR_WARNING - "INSTALL_SOURCE_QMLDIR option is deprecated and should not be used. " - "Please port your module to use declarative type registration.") - set(files ${arg_INSTALL_SOURCE_QMLDIR}) if(QT_WILL_INSTALL) install( @@ -329,14 +415,3 @@ function(qt_internal_add_qml_module target) endif() endif() endfunction() - -if(NOT QT_NO_INTERNAL_COMPATIBILITY_FUNCTIONS) - # Compatibility functions that should be removed once all their usages are removed. - function(add_qml_module) - qt_add_qml_module(${ARGV}) - endfunction() - - function(qt_add_qml_module) - qt_internal_add_qml_module(${ARGV}) - endfunction() -endif() diff --git a/src/qml/Qt6QmlConfigExtras.cmake.in b/src/qml/Qt6QmlConfigExtras.cmake.in index 3d5be2c22c3..194dc9eef2b 100644 --- a/src/qml/Qt6QmlConfigExtras.cmake.in +++ b/src/qml/Qt6QmlConfigExtras.cmake.in @@ -11,3 +11,10 @@ if(NOT QT_NO_CREATE_TARGETS AND qt@PROJECT_VERSION_MAJOR@_import_qml_plugins ) endif() + +if(ANDROID) + # Set the default staging path of qml modules when building for Android + if("${QT_QML_OUTPUT_DIRECTORY}" STREQUAL "") + set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/android-qml") + endif() +endif() diff --git a/src/qml/Qt6QmlFindQmlscInternal.cmake b/src/qml/Qt6QmlFindQmlscInternal.cmake new file mode 100644 index 00000000000..e3b711b825f --- /dev/null +++ b/src/qml/Qt6QmlFindQmlscInternal.cmake @@ -0,0 +1,8 @@ +if (QT_NO_FIND_QMLSC) + return() +endif() + +set(QT_NO_FIND_QMLSC TRUE) + +# FIXME: Make this work with cross-builds +find_package(Qt6QmlCompilerPlus QUIET) diff --git a/src/qml/Qt6QmlImportScannerTemplate.cpp.in b/src/qml/Qt6QmlImportScannerTemplate.cpp.in deleted file mode 100644 index 715dd87cb22..00000000000 --- a/src/qml/Qt6QmlImportScannerTemplate.cpp.in +++ /dev/null @@ -1,5 +0,0 @@ -// This file is autogenerated by CMake. It imports static plugin classes for -// static plugins used by QML imports. -#include - -@qt_qml_import_cpp_file_content@ diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake index 2e50b43111b..d805d37febb 100644 --- a/src/qml/Qt6QmlMacros.cmake +++ b/src/qml/Qt6QmlMacros.cmake @@ -4,136 +4,12 @@ set(__qt_qml_macros_module_base_dir "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "") -# Create a Qml Module. -# -# target: The name of the target to use for the qml module. If it does not -# already exist, it will be created. This is referred to as the "backing -# target" when a separate plugin is also generated (see PLUGIN_TARGET below). -# (REQUIRED) -# -# URI: Declares the module identifier of the module. The module identifier is -# the (dotted URI notation) identifier for the module, which must match the -# module's install path. (REQUIRED) -# -# VERSION: The module's version. (REQUIRED) -# -# PAST_MAJOR_VERSIONS: List of past major versions this QML module was available -# in. Ensures that the module can be imported when using these major versions. -# (OPTIONAL) -# -# TARGET_PATH: Overwrite the generated target path. By default the target path -# is generated from the URI by replacing the '.' with a '/'. However, under -# certain circumstance this may not be enough. Use this argument to provide -# a replacement. (OPTIONAL) -# -# RESOURCE_PREFIX: Resource Prefix to be used when adding resources to the -# target. This may include the qmldir file, compiled/cached *.qml files, etc. -# If not specified, a default prefix of "/" is used. (OPTIONAL) -# -# OUTPUT_DIRECTORY: Overrides the directory where the qmldir, *.qmltypes and -# plugin library will be created. Defaults to ${CMAKE_CURRENT_BINARY_DIR} if -# not specified. (OPTIONAL) -# -# STATIC, SHARED: Explicitly specify the type of library to create. At most one -# of these two options can be specified. If neither is given, then the type of -# library follows CMake's usual rules of creating a static library unless the -# BUILD_SHARED_LIBS variable is set to true. (OPTIONAL) -# -# CLASS_NAME: Provides the class name of the C++ plugin used by the module. This -# information is required for all the QML modules that depend on a C++ plugin -# for additional functionality. Qt Quick applications built with static -# linking cannot resolve the module imports without this information. -# If no CLASS_NAME is given, it defaults to the URI with non-alphanumeric -# characters converted to underscores, and "Plugin" appended. If an existing -# target is passed in as the PLUGIN_TARGET and it has a QT_PLUGIN_CLASS_NAME -# target property set, that will be used as the default CLASS_NAME instead. -# (OPTIONAL) -# -# PLUGIN_TARGET: The recommended arrangement is to have separate backing and -# plugin libraries. By default, the plugin library will be created as a second -# CMake target with the same name as ${target}, but with "plugin" appended. -# This name can be overridden with PLUGIN_TARGET. To use a single target -# instead of separate backing and plugin targets, set PLUGIN_TARGET to the -# same as ${target}. (OPTIONAL) -# -# NO_CREATE_PLUGIN_TARGET: When given, the plugin target will not be -# automatically created. Use this if the qml module will always be used by -# linking directly to the backing target and no plugin is needed at runtime. -# An executable that is set up as its own qml module is one example where this -# option is appropriate. Note also that an existing target can be specified in -# PLUGIN_TARGET, in which case it will be modified by this function rather -# than created by it. (OPTIONAL) -# -# NO_GENERATE_PLUGIN_SOURCE: A .cpp file will be created for the plugin class -# by default and automatically added to the plugin target. Use this option to -# indicate that no such .cpp file should be generated. The caller is then -# responsible for providing their own plugin class if a separate plugin will -# be created. Note that this option is independent of NO_CREATE_PLUGIN_TARGET. -# (OPTIONAL) -# -# NO_PLUGIN_OPTIONAL: The plugin is marked as optional in the qmldir file by -# default. If the plugin contains code other than just the shim plugin loader -# class, specify this option to indicate that the plugin must always be loaded -# as part of the qml module. (OPTIONAL) -# -# OUTPUT_TARGETS: In static builds, additional CMake targets can be created -# which consumers of the module will need to link to and potentially install. -# Supply the name of an output variable, which will be set to a list of these -# targets. If installing the main target, you will also need to install these -# output targets for static builds. (OPTIONAL) -# -# DESIGNER_SUPPORTED: Specify this argument if the plugin is supported by Qt -# Quick Designer. By default, the plugin will not be supported. (OPTIONAL) -# -# TYPEINFO: Path to a file which declares a type description file for the module -# that can be read by QML tools such as Qt Creator to access information about -# the types defined by the module's plugins. You will typically need to also -# specify NO_GENERATE_QMLTYPES if using this option. When TYPEINFO is not -# specified, it will default to "${target}.qmltypes". (OPTIONAL) -# -# NO_GENERATE_QMLTYPES: Do not automatically generate the *.qmltypes file. -# See also the TYPEINFO option. (OPTIONAL) -# -# NO_GENERATE_QMLDIR: Do not automatically generate the qmldir file. (OPTIONAL) -# -# IMPORTS: List of other Qml Modules that this module imports. A version can be -# specified by appending it after a slash(/), e.g QtQuick/2.0. The minor -# version may be omitted, e.g. QtQuick/2. Alternatively "auto" may be given -# as version to forward the version the current module is being imported with, -# e.g. QtQuick/auto. (OPTIONAL) -# -# OPTIONAL_IMPORTS: List of other Qml Modules that this module may import at -# run-time. Those are not automatically imported by the QML engine when -# importing the current module, but rather serve as hints to tools like -# qmllint. Versions can be specified in the same way as for IMPORTS. -# (OPTIONAL) -# -# DEPENDENCIES: List of QML Module dependencies and their versions. The module -# and its version must be separated via a slash(/). E.g. QtQuick/2.0 -# (OPTIONAL) -# -# IMPORT_PATH: State that QML modules this one depends on may be found in the -# given import paths. (OPTIONAL) -# -# SOURCES: List of C++ sources. (OPTIONAL) -# -# QML_FILES: List of Qml files. See qt6_target_qml_sources() for more -# information on how to specify additional properties on qml files. (OPTIONAL) -# -# NO_LINT: By default, this function will create a separate ${target}_qmllint -# target if any .qml files are added to ${target} (see qt6_add_qml_sources()). -# Provide the NO_LINT option to disable this behavior. (OPTIONAL) -# -# NO_CACHEGEN: By default, this function will compile each .qml file added to -# the target and store that compiled version in the target's resources. -# Provide the NO_CACHEGEN option to disable this behavior. -# See qt6_add_qml_sources() for further details. (OPTIONAL) -# function(qt6_add_qml_module target) set(args_option STATIC SHARED DESIGNER_SUPPORTED + NO_PLUGIN NO_PLUGIN_OPTIONAL NO_CREATE_PLUGIN_TARGET NO_GENERATE_PLUGIN_SOURCE @@ -141,16 +17,22 @@ function(qt6_add_qml_module target) NO_GENERATE_QMLDIR NO_LINT NO_CACHEGEN + NO_RESOURCE_TARGET_PATH # TODO: Remove once all usages have also been removed SKIP_TYPE_REGISTRATION + + # Used only by _qt_internal_qml_type_registration() + # TODO: Remove this once qt6_extract_metatypes does not install by default. + __QT_INTERNAL_INSTALL_METATYPES_JSON ) set(args_single PLUGIN_TARGET + INSTALLED_PLUGIN_TARGET # Internal option only, it may be removed OUTPUT_TARGETS RESOURCE_PREFIX URI - TARGET_PATH + TARGET_PATH # Internal option only, it may be removed VERSION OUTPUT_DIRECTORY CLASS_NAME @@ -161,12 +43,12 @@ function(qt6_add_qml_module target) RESOURCE_EXPORT INSTALL_DIRECTORY INSTALL_LOCATION - __QT_INTERNAL_QT_LIBINFIX # Used only by _qt_internal_target_generate_qmldir() ) set(args_multi SOURCES QML_FILES + RESOURCES IMPORTS IMPORT_PATH OPTIONAL_IMPORTS @@ -240,28 +122,145 @@ function(qt6_add_qml_module target) ) endif() - # Provide defaults for options that have one + # Other arguments and checking for invalid combinations if (NOT arg_TARGET_PATH) + # NOTE: This will always be used for copying things to the build + # directory, but it will not be used for resource paths if + # NO_RESOURCE_TARGET_PATH was given. string(REPLACE "." "/" arg_TARGET_PATH ${arg_URI}) endif() - if(NOT arg_NO_CREATE_PLUGIN_TARGET AND NOT DEFINED arg_PLUGIN_TARGET) + if(arg_NO_PLUGIN AND DEFINED arg_PLUGIN_TARGET) + message(FATAL_ERROR + "NO_PLUGIN was specified, but PLUGIN_TARGET was also given. " + "At most one of these can be present." + ) + endif() + + set(is_executable FALSE) + if(TARGET ${target}) + if(arg_STATIC OR arg_SHARED) + message(FATAL_ERROR + "Cannot use STATIC or SHARED keyword when passed an existing target (${target})" + ) + endif() + + # With CMake 3.17 and earlier, a source file's generated property isn't + # visible outside of the directory scope in which it is set. That can + # lead to build errors for things like type registration due to CMake + # thinking nothing will create a missing file on the first run. With + # CMake 3.18 or later, we can force that visibility. Policy CMP0118 + # added in CMake 3.20 should have made this unnecessary, but we can't + # rely on that because the user project controls what it is set to at + # the point where it matters, which is the end of the target's + # directory scope (hence we can't even test for it here). + get_target_property(source_dir ${target} SOURCE_DIR) + if(NOT source_dir STREQUAL CMAKE_CURRENT_SOURCE_DIR AND + CMAKE_VERSION VERSION_LESS "3.18") + message(WARNING + "qt6_add_qml_module() is being called in a different " + "directory scope to the one in which the target \"${target}\" " + "was created. CMake 3.18 or later is required to generate a " + "project robustly for this scenario, but you are using " + "CMake ${CMAKE_VERSION}. Ideally, qt6_add_qml_module() should " + "only be called from the same scope as the one the target was " + "created in to avoid dependency and visibility problems." + ) + endif() + + get_target_property(backing_target_type ${target} TYPE) + get_target_property(is_android_executable "${target}" _qt_is_android_executable) + if (backing_target_type STREQUAL "EXECUTABLE" OR is_android_executable) + if(DEFINED arg_PLUGIN_TARGET) + message(FATAL_ERROR + "A QML module with an executable as its backing target " + "cannot have a plugin." + ) + endif() + if(arg_NO_CREATE_PLUGIN_TARGET) + message(WARNING + "A QML module with an executable as its backing target " + "cannot have a plugin. The NO_CREATE_PLUGIN_TARGET option " + "has no effect and should be removed." + ) + endif() + set(arg_NO_PLUGIN TRUE) + set(lib_type "") + set(is_executable TRUE) + elseif(arg_NO_RESOURCE_TARGET_PATH) + message(FATAL_ERROR + "NO_RESOURCE_TARGET_PATH cannot be used for a backing target " + "that is not an executable" + ) + elseif(backing_target_type STREQUAL "STATIC_LIBRARY") + set(lib_type STATIC) + elseif(backing_target_type MATCHES "(SHARED|MODULE)_LIBRARY") + set(lib_type SHARED) + else() + message(FATAL_ERROR "Unsupported backing target type: ${backing_target_type}") + endif() + else() + if(arg_STATIC AND arg_SHARED) + message(FATAL_ERROR + "Both STATIC and SHARED specified, at most one can be given" + ) + endif() + + if(arg_NO_RESOURCE_TARGET_PATH) + message(FATAL_ERROR + "NO_RESOURCE_TARGET_PATH can only be provided when an existing " + "executable target is passed in as the backing target" + ) + endif() + + # Explicit arguments take precedence, otherwise default to using the same + # staticality as what Qt was built with. This follows the already + # established default behavior for building ordinary Qt plugins. + # We don't allow the standard CMake BUILD_SHARED_LIBS variable to control + # the default because that can lead to different defaults depending on + # whether you build with a separate backing target or not. + if(arg_STATIC) + set(lib_type STATIC) + elseif(arg_SHARED) + set(lib_type SHARED) + elseif(QT6_IS_SHARED_LIBS_BUILD) + set(lib_type SHARED) + else() + set(lib_type STATIC) + endif() + endif() + + if(arg_NO_PLUGIN) + # Simplifies things a bit further below + set(arg_PLUGIN_TARGET "") + elseif(NOT DEFINED arg_PLUGIN_TARGET) + if(arg_NO_CREATE_PLUGIN_TARGET) + # We technically could allow this and rely on the project using the + # default plugin target name, but not doing so gives us the + # flexibility to potentially change that default later if needed. + message(FATAL_ERROR + "PLUGIN_TARGET must also be provided when NO_CREATE_PLUGIN_TARGET " + "is used. If you want to disable creating a plugin altogether, " + "use the NO_PLUGIN option instead." + ) + endif() set(arg_PLUGIN_TARGET ${target}plugin) endif() - if(NOT DEFINED arg_PLUGIN_TARGET) - set(arg_PLUGIN_TARGET "") # Simplifies things a bit further below + if(arg_NO_CREATE_PLUGIN_TARGET AND arg_PLUGIN_TARGET STREQUAL target AND NOT TARGET ${target}) + message(FATAL_ERROR + "PLUGIN_TARGET is the same as the backing target, which is allowed, " + "but NO_CREATE_PLUGIN_TARGET was also given and the target does not " + "exist. Either ensure the target is already created or do not " + "specify NO_CREATE_PLUGIN_TARGET." + ) + endif() + if(NOT arg_INSTALLED_PLUGIN_TARGET) + set(arg_INSTALLED_PLUGIN_TARGET ${arg_PLUGIN_TARGET}) endif() set(no_gen_source) if(arg_NO_GENERATE_PLUGIN_SOURCE) - set(no_gen_source NO_GENERATE_SOURCE) - endif() - - set(lib_type "") - if(arg_STATIC) - set(lib_type STATIC) - elseif(arg_SHARED) - set(lib_type SHARED) + set(no_gen_source NO_GENERATE_PLUGIN_SOURCE) endif() if(arg_OUTPUT_DIRECTORY) @@ -269,8 +268,49 @@ function(qt6_add_qml_module target) ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}" ) else() - set(arg_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + if("${QT_QML_OUTPUT_DIRECTORY}" STREQUAL "") + set(arg_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + # For libraries, we assume/require that the source directory + # structure is consistent with the target path. For executables, + # the source directory will usually not reflect the target path + # and the project will often expect to be able to use resource + # paths that don't include the target path (they need the + # NO_RESOURCE_TARGET_PATH option if they do that). Tooling always + # needs the target path in the file system though, so the output + # directory should always have it. Handle the special case for + # executables to ensure this is what we get. + if(is_executable) + string(APPEND arg_OUTPUT_DIRECTORY "/${arg_TARGET_PATH}") + endif() + else() + if(NOT IS_ABSOLUTE "${QT_QML_OUTPUT_DIRECTORY}") + message(FATAL_ERROR + "QT_QML_OUTPUT_DIRECTORY must be an absolute path, but given: " + "${QT_QML_OUTPUT_DIRECTORY}" + ) + endif() + # This inherently does what we want for libraries and executables + set(arg_OUTPUT_DIRECTORY ${QT_QML_OUTPUT_DIRECTORY}/${arg_TARGET_PATH}) + endif() + endif() + + # Sanity check that we are not trying to have two different QML modules use + # the same output directory. + get_property(dirs GLOBAL PROPERTY _qt_all_qml_output_dirs) + if(dirs) + list(FIND dirs "${arg_OUTPUT_DIRECTORY}" index) + if(NOT index EQUAL -1) + get_property(qml_targets GLOBAL PROPERTY _qt_all_qml_targets) + list(GET qml_targets ${index} other_target) + message(FATAL_ERROR + "Output directory for target \"${target}\" is already used by " + "another QML module (target \"${other_target}\"). " + "Output directory is:\n ${arg_OUTPUT_DIRECTORY}\n" + ) + endif() endif() + set_property(GLOBAL APPEND PROPERTY _qt_all_qml_output_dirs ${arg_OUTPUT_DIRECTORY}) + set_property(GLOBAL APPEND PROPERTY _qt_all_qml_targets ${target}) # TODO: Support for old keyword, remove once all repos no longer use CLASSNAME if(arg_CLASSNAME) @@ -291,16 +331,10 @@ function(qt6_add_qml_module target) endif() endif() if(NOT arg_CLASS_NAME) - string(REGEX REPLACE "[^A-Za-z0-9]" "_" escaped_uri "${arg_URI}") - set(arg_CLASS_NAME "${escaped_uri}Plugin") + _qt_internal_compute_qml_plugin_class_name_from_uri("${arg_URI}" arg_CLASS_NAME) endif() if(TARGET ${target}) - if(arg_STATIC OR arg_SHARED) - message(FATAL_ERROR - "Cannot use STATIC or SHARED keyword when passed an existing target (${target})" - ) - endif() if(arg_PLUGIN_TARGET STREQUAL target) # Insert the plugin's URI into its meta data to enable usage # of static plugins in QtDeclarative (like in mkspecs/features/qml_plugin.prf). @@ -309,21 +343,7 @@ function(qt6_add_qml_module target) ) endif() else() - if(arg_STATIC AND arg_SHARED) - message(FATAL_ERROR - "Both STATIC and SHARED specified, at most one can be given" - ) - endif() - if(arg_PLUGIN_TARGET STREQUAL target) - if(arg_NO_CREATE_PLUGIN_TARGET AND NOT TARGET ${target}) - message(FATAL_ERROR - "NO_CREATE_PLUGIN_TARGET was given, but PLUGIN_TARGET is " - "the same as the backing target (which is allowed) and the " - "target does not exist. Either ensure the target is already " - "created or do not specify NO_CREATE_PLUGIN_TARGET." - ) - endif() qt6_add_qml_plugin(${target} ${lib_type} ${no_gen_source} @@ -332,11 +352,7 @@ function(qt6_add_qml_module target) CLASS_NAME ${arg_CLASS_NAME} ) else() - add_library(${target} ${lib_type}) - if(ANDROID) - # TODO: Check if we need to do this for a backing library - qt6_android_apply_arch_suffix(${target}) - endif() + qt6_add_library(${target} ${lib_type}) endif() endif() @@ -348,19 +364,6 @@ function(qt6_add_qml_module target) set(arg_TYPEINFO ${target}.qmltypes) endif() - # Make the prefix conform to the following: - # - Starts with a "/" - # - Does not end with a "/" unless the prefix is exactly "/" - if(NOT arg_RESOURCE_PREFIX) - set(arg_RESOURCE_PREFIX "/") - endif() - if(NOT arg_RESOURCE_PREFIX MATCHES "^/") - string(PREPEND arg_RESOURCE_PREFIX "/") - endif() - if(arg_RESOURCE_PREFIX MATCHES [[(.*)/$]]) - set(arg_RESOURCE_PREFIX "${CMAKE_MATCH_1}") - endif() - foreach(import_set IN ITEMS IMPORTS OPTIONAL_IMPORTS) foreach(import IN LISTS arg_${import_set}) string(FIND ${import} "/" slash_position REVERSE) @@ -409,30 +412,59 @@ function(qt6_add_qml_module target) endif() endforeach() + _qt_internal_canonicalize_resource_path("${arg_RESOURCE_PREFIX}" arg_RESOURCE_PREFIX) + if(arg_NO_RESOURCE_TARGET_PATH) + set(qt_qml_module_resource_prefix "${arg_RESOURCE_PREFIX}") + else() + if(arg_RESOURCE_PREFIX STREQUAL "/") # Checked so we prevent double-slash + set(qt_qml_module_resource_prefix "/${arg_TARGET_PATH}") + else() + set(qt_qml_module_resource_prefix "${arg_RESOURCE_PREFIX}/${arg_TARGET_PATH}") + endif() + endif() + set_target_properties(${target} PROPERTIES QT_QML_MODULE_NO_LINT "${arg_NO_LINT}" QT_QML_MODULE_NO_CACHEGEN "${arg_NO_CACHEGEN}" QT_QML_MODULE_NO_GENERATE_QMLDIR "${arg_NO_GENERATE_QMLDIR}" + QT_QML_MODULE_NO_PLUGIN "${arg_NO_PLUGIN}" QT_QML_MODULE_NO_PLUGIN_OPTIONAL "${arg_NO_PLUGIN_OPTIONAL}" QT_QML_MODULE_URI "${arg_URI}" + QT_QML_MODULE_TARGET_PATH "${arg_TARGET_PATH}" QT_QML_MODULE_VERSION "${arg_VERSION}" QT_QML_MODULE_CLASS_NAME "${arg_CLASS_NAME}" - QT_QML_MODULE_LIBINFIX "${arg___QT_INTERNAL_QT_LIBINFIX}" + QT_QML_MODULE_PLUGIN_TARGET "${arg_PLUGIN_TARGET}" + QT_QML_MODULE_INSTALLED_PLUGIN_TARGET "${arg_INSTALLED_PLUGIN_TARGET}" + + # Also Save the PLUGIN_TARGET values in a separate property to circumvent + # https://gitlab.kitware.com/cmake/cmake/-/issues/21484 when exporting the properties + _qt_qml_module_plugin_target "${arg_PLUGIN_TARGET}" + _qt_qml_module_installed_plugin_target "${arg_INSTALLED_PLUGIN_TARGET}" + QT_QML_MODULE_DESIGNER_SUPPORTED "${arg_DESIGNER_SUPPORTED}" - QT_QML_MODULE_OUTPUT_DIR "${arg_OUTPUT_DIRECTORY}" - QT_RESOURCE_PREFIX "${arg_RESOURCE_PREFIX}/${arg_TARGET_PATH}" - QT_QML_PAST_MAJOR_VERSIONS "${arg_PAST_MAJOR_VERSIONS}" - QT_QMLTYPES_FILENAME "${arg_TYPEINFO}" + QT_QML_MODULE_OUTPUT_DIRECTORY "${arg_OUTPUT_DIRECTORY}" + QT_QML_MODULE_RESOURCE_PREFIX "${qt_qml_module_resource_prefix}" + QT_QML_MODULE_PAST_MAJOR_VERSIONS "${arg_PAST_MAJOR_VERSIONS}" + QT_QML_MODULE_TYPEINFO "${arg_TYPEINFO}" # TODO: Check how this is used by qt6_android_generate_deployment_settings() QT_QML_IMPORT_PATH "${arg_IMPORT_PATH}" ) + + # Executables don't have a plugin target, so no need to export the properties. + if(NOT backing_target_type STREQUAL "EXECUTABLE" AND NOT is_android_executable) + set_property(TARGET ${target} APPEND PROPERTY + EXPORT_PROPERTIES _qt_qml_module_plugin_target _qt_qml_module_installed_plugin_target + ) + endif() + set(ensure_set_properties QT_QML_MODULE_PLUGIN_TYPES_FILE QT_QML_MODULE_RESOURCE_PATHS QT_QMLCACHEGEN_DIRECT_CALLS - QT_QMLCACHEGEN_QMLJS_RUNTIME + QT_QMLCACHEGEN_BINARY + QT_QMLCACHEGEN_ARGUMENTS ) foreach(prop IN LISTS ensure_set_properties) get_target_property(val ${target} ${prop}) @@ -442,50 +474,79 @@ function(qt6_add_qml_module target) endforeach() if(NOT arg_NO_GENERATE_QMLTYPES) - qt6_qml_type_registration(${target} OUTPUT_DIRECTORY ${arg_OUTPUT_DIRECTORY}) + set(type_registration_extra_args "") + if(arg___QT_INTERNAL_INSTALL_METATYPES_JSON) + list(APPEND type_registration_extra_args __QT_INTERNAL_INSTALL_METATYPES_JSON) + endif() + _qt_internal_qml_type_registration(${target} ${type_registration_extra_args}) endif() set(output_targets) if(NOT arg_NO_GENERATE_QMLDIR) - _qt_internal_target_generate_qmldir(${target} ${arg_OUTPUT_DIRECTORY} ${arg_TARGET_PATH}) + _qt_internal_target_generate_qmldir(${target}) + + # Embed qmldir in qrc. The following comments relate mostly to Qt5->6 transition. + # The requirement to keep the same resource name might no longer apply, but it doesn't + # currently appear to cause any hinderance to keep it. + # The qmldir resource name needs to match the one generated by qmake's qml_module.prf, to + # ensure that all Q_INIT_RESOURCE(resource_name) calls in Qt code don't lead to undefined + # symbol errors when linking an application project. + # The Q_INIT_RESOURCE() calls are not strictly necessary anymore because the CMake Qt + # build passes around the compiled resources as object files. + # These object files have global initiliazers that don't get discared when linked into + # an application (as opposed to when the resource libraries were embedded into the static + # libraries when Qt was built with qmake). + # The reason to match the naming is to ensure that applications link successfully regardless + # if Qt was built with CMake or qmake, while the build system transition phase is still + # happening. + string(REPLACE "/" "_" qmldir_resource_name "qmake_${arg_TARGET_PATH}") + + # The qmldir file ALWAYS has to be under the target path, even in the + # resources. If it isn't, an explicit import can't find it. We need a + # second copy NOT under the target path if NO_RESOURCE_TARGET_PATH is + # given so that the implicit import will work. + set(prefixes "${qt_qml_module_resource_prefix}") + if(arg_NO_RESOURCE_TARGET_PATH) + # The above prefixes item won't include the target path, so add a + # second one that does. + if(qt_qml_module_resource_prefix STREQUAL "/") + list(APPEND prefixes "/${arg_TARGET_PATH}") + else() + list(APPEND prefixes "${qt_qml_module_resource_prefix}/${arg_TARGET_PATH}") + endif() + endif() + set_source_files_properties(${arg_OUTPUT_DIRECTORY}/qmldir + PROPERTIES QT_RESOURCE_ALIAS "qmldir" + ) - get_target_property(target_type ${target} TYPE) - if(target_type STREQUAL "STATIC_LIBRARY") - # Embed qmldir in static builds. The following comments relate mostly to Qt5->6 transition. - # The requirement to keep the same resource name might no longer apply, but it doesn't - # currently appear to cause any hinderance to keep it. - # The qmldir resource name needs to match the one generated by qmake's qml_module.prf, to - # ensure that all Q_INIT_RESOURCE(resource_name) calls in Qt code don't lead to undefined - # symbol errors when linking an application project. - # The Q_INIT_RESOURCE() calls are not strictly necessary anymore because the CMake Qt - # build passes around the compiled resources as object files. - # These object files have global initiliazers that don't get discared when linked into - # an application (as opposed to when the resource libraries were embedded into the static - # libraries when Qt was built with qmake). - # The reason to match the naming is to ensure that applications link successfully regardless - # if Qt was built with CMake or qmake, while the build system transition phase is still - # happening. - string(REPLACE "/" "_" qmldir_resource_name "qmake_${arg_TARGET_PATH}") - set_source_files_properties(${arg_OUTPUT_DIRECTORY}/qmldir - PROPERTIES QT_RESOURCE_ALIAS "qmldir" - ) + foreach(prefix IN LISTS prefixes) set(resource_targets) qt6_add_resources(${target} ${qmldir_resource_name} FILES ${arg_OUTPUT_DIRECTORY}/qmldir + PREFIX "${prefix}" OUTPUT_TARGETS resource_targets ) list(APPEND output_targets ${resource_targets}) - endif() + # If we are adding the same file twice, we need a different resource + # name for the second one. It has the same QT_RESOURCE_ALIAS but a + # different prefix, so we can't put it in the same resource. + string(APPEND qmldir_resource_name "_copy") + endforeach() endif() - if(arg_PLUGIN_TARGET AND NOT arg_NO_CREATE_PLUGIN_TARGET) + if(NOT arg_NO_PLUGIN AND NOT arg_NO_CREATE_PLUGIN_TARGET) # This also handles the case where ${arg_PLUGIN_TARGET} already exists, # including where it is the same as ${target}. If ${arg_PLUGIN_TARGET} # already exists, it will update the necessary things that are specific # to qml plugins. + if(TARGET ${arg_PLUGIN_TARGET}) + set(plugin_lib_type "") + else() + set(plugin_lib_type ${lib_type}) + endif() qt6_add_qml_plugin(${arg_PLUGIN_TARGET} - ${lib_type} + ${plugin_lib_type} ${no_gen_source} OUTPUT_DIRECTORY ${arg_OUTPUT_DIRECTORY} BACKING_TARGET ${target} @@ -502,19 +563,41 @@ function(qt6_add_qml_module target) set(cache_target) qt6_target_qml_sources(${target} __QT_INTERNAL_FORCE_DEFER_QMLDIR - FILES ${arg_QML_FILES} + QML_FILES ${arg_QML_FILES} + RESOURCES ${arg_RESOURCES} OUTPUT_TARGETS cache_target + PREFIX "${qt_qml_module_resource_prefix}" ) list(APPEND output_targets ${cache_target}) + # Build an init object library for static plugins and propagate it along with the plugin + # target. + # TODO: Figure out if we can move this code block into qt_add_qml_plugin. Need to consider + # various corner cases. + # QTBUG-96937 + if(TARGET "${arg_PLUGIN_TARGET}") + get_target_property(plugin_lib_type ${arg_PLUGIN_TARGET} TYPE) + if(plugin_lib_type STREQUAL "STATIC_LIBRARY") + __qt_internal_add_static_plugin_init_object_library( + "${arg_PLUGIN_TARGET}" plugin_init_target) + list(APPEND output_targets ${plugin_init_target}) + + __qt_internal_propagate_object_library("${arg_PLUGIN_TARGET}" "${plugin_init_target}") + endif() + endif() + if(NOT arg_NO_GENERATE_QMLDIR) if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.19.0") # Defer the write to allow more qml files to be added later by calls to # qt6_target_qml_sources(). We wrap the deferred call with EVAL CODE # so that ${target} is evaluated now rather than the end of the scope. + # We also delay target finalization until after our deferred write + # because the qmldir file must be written before any finalizer + # might call qt_import_qml_plugins(). cmake_language(EVAL CODE - "cmake_language(DEFER CALL _qt_internal_write_deferred_qmldir_file ${target})" + "cmake_language(DEFER ID_VAR write_id CALL _qt_internal_write_deferred_qmldir_file ${target})" ) + _qt_internal_delay_finalization_until_after(${write_id}) else() # Can't defer the write, have to do it now _qt_internal_write_deferred_qmldir_file(${target}) @@ -530,9 +613,39 @@ endfunction() if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) function(qt_add_qml_module) qt6_add_qml_module(${ARGV}) + cmake_parse_arguments(PARSE_ARGV 1 arg "" "OUTPUT_TARGETS" "") + if(arg_OUTPUT_TARGETS) + set(${arg_OUTPUT_TARGETS} ${${arg_OUTPUT_TARGETS}} PARENT_SCOPE) + endif() endfunction() endif() +# Make the prefix conform to the following: +# - Starts with a "/" +# - Does not end with a "/" unless the prefix is exactly "/" +function(_qt_internal_canonicalize_resource_path path out_var) + if(NOT path) + set(path "/") + endif() + if(NOT path MATCHES "^/") + string(PREPEND path "/") + endif() + if(path MATCHES [[(.+)/$]]) + set(path "${CMAKE_MATCH_1}") + endif() + set(${out_var} "${path}" PARENT_SCOPE) +endfunction() + +function(_qt_internal_get_escaped_uri uri out_var) + string(REGEX REPLACE "[^A-Za-z0-9]" "_" escaped_uri "${uri}") + set(${out_var} "${escaped_uri}" PARENT_SCOPE) +endfunction() + +function(_qt_internal_compute_qml_plugin_class_name_from_uri uri out_var) + _qt_internal_get_escaped_uri("${uri}" escaped_uri) + set(${out_var} "${escaped_uri}Plugin" PARENT_SCOPE) +endfunction() + macro(_qt_internal_genex_getproperty var target property) set(${var} "$") set(have_${var} "$") @@ -547,6 +660,20 @@ macro(_qt_internal_genex_getoption var target property) set(${var} "$>") endmacro() +function(_qt_internal_extend_qml_import_paths import_paths_var) + set(local_var ${${import_paths_var}}) + + # prepend extra import path which is a current module's build dir: we need + # this to ensure correct importing of QML modules when having a prefix-build + # with QLibraryInfo::path(QLibraryInfo::QmlImportsPath) pointing to the + # install location + if(QT_BUILDING_QT AND QT_WILL_INSTALL) + list(PREPEND local_var -I "${QT_BUILD_DIR}/${INSTALL_QMLDIR}") + endif() + + set(${import_paths_var} ${local_var} PARENT_SCOPE) +endfunction() + function(_qt_internal_target_enable_qmllint target) set(lint_target ${target}_qmllint) if(TARGET ${lint_target}) @@ -557,43 +684,106 @@ function(_qt_internal_target_enable_qmllint target) _qt_internal_genex_getjoinedproperty(import_args ${target} QT_QML_IMPORT_PATH "-I$" "$" ) + _qt_internal_genex_getjoinedproperty(qrc_args ${target} + _qt_generated_qrc_files "--resource$" "$" + ) + + # Facilitate self-import so it can find the qmldir file. We also try to walk + # back up the directory structure to find a base path under which this QML + # module is located. Such a base path is likely to be used for other QML + # modules that we might need to find, so add it to the import path if we + # find a compatible directory structure. It doesn't make sense to do this + # for an executable though, since it can never be found as a QML module for + # a different QML module/target. + get_target_property(target_type ${target} TYPE) + get_target_property(is_android_executable ${target} _qt_is_android_executable) + if(target_type STREQUAL "EXECUTABLE" OR is_android_executable) + # The executable's own QML module's qmldir file will usually be under a + # subdirectory (matching the module's target path) below the target's + # build directory. + list(APPEND import_args -I "$") + elseif(target_type MATCHES "LIBRARY") + get_target_property(output_dir ${target} QT_QML_MODULE_OUTPUT_DIRECTORY) + get_target_property(target_path ${target} QT_QML_MODULE_TARGET_PATH) + if(output_dir MATCHES "${target_path}$") + string(REGEX REPLACE "(.*)/${target_path}" "\\1" base_dir "${output_dir}") + list(APPEND import_args -I "${base_dir}") + else() + message(WARNING + "The ${target} target is a QML module with target path ${target_path}. " + "It uses an OUTPUT_DIRECTORY of ${output_dir}, which should end in the " + "same target path, but doesn't. Tooling such as qmllint may not work " + "correctly." + ) + endif() + endif() + + if(NOT "${QT_QML_OUTPUT_DIRECTORY}" STREQUAL "") + list(APPEND import_args -I "${QT_QML_OUTPUT_DIRECTORY}") + endif() + + _qt_internal_extend_qml_import_paths(import_args) set(cmd ${QT_TOOL_COMMAND_WRAPPER_PATH} ${QT_CMAKE_EXPORT_NAMESPACE}::qmllint ${import_args} + ${qrc_args} ${qmllint_files} ) + # We need this target to depend on all qml type registrations. This is the + # only way we can be sure that all *.qmltypes files for any QML modules we + # depend on will have been generated. add_custom_target(${lint_target} COMMAND "$<${have_qmllint_files}:${cmd}>" COMMAND_EXPAND_LISTS - DEPENDS ${QT_CMAKE_EXPORT_NAMESPACE}::qmllint ${qmllint_files} + DEPENDS + ${QT_CMAKE_EXPORT_NAMESPACE}::qmllint + ${qmllint_files} + $ WORKING_DIRECTORY "$" ) + + # Make the global linting target depend on the one we add here. + # Note that the caller is free to change the value of QT_QMLLINT_ALL_TARGET + # for different QML modules if they wish, which means they can implement + # their own grouping of the ${target}_qmllint targets. + if("${QT_QMLLINT_ALL_TARGET}" STREQUAL "") + set(QT_QMLLINT_ALL_TARGET all_qmllint) + endif() + if(NOT TARGET ${QT_QMLLINT_ALL_TARGET}) + add_custom_target(${QT_QMLLINT_ALL_TARGET}) + endif() + add_dependencies(${QT_QMLLINT_ALL_TARGET} ${lint_target}) + endfunction() # This is a modified version of __qt_propagate_generated_resource from qtbase. # -# The main reason we can't use it is because it unconditionally links the object library to the -# target (in the static Qt case). We need to link conditionally based on 'link_condition' genex. +# It uses a common __qt_internal_propagate_object_library function to link and propagate the object +# library to the end-point executable. # # The reason for propagating the qmlcache target as a 'fake resource' from the build system # perspective is to ensure proper handling of the object files in generated qmake .prl files. -# -# TODO: The qtbase function should be refactored into separate parts, so that we can reuse the -# common functionality in this function. function(_qt_internal_propagate_qmlcache_object_lib target generated_source_code link_condition output_generated_target) set(resource_target "${target}_qmlcache") - add_library("${resource_target}" OBJECT "${generated_source_code}") + qt6_add_library("${resource_target}" OBJECT "${generated_source_code}") # Needed to trigger the handling of the object library for .prl generation. set_property(TARGET ${resource_target} APPEND PROPERTY _qt_resource_name ${resource_target}) + # Export info that this is a qmlcache target, in case if we ever need to detect such targets, + # similar how we need it for plugin initializers. + set_property(TARGET ${resource_target} PROPERTY _is_qt_qmlcache_target TRUE) + set_property(TARGET ${resource_target} APPEND PROPERTY + EXPORT_PROPERTIES _is_qt_qmlcache_target + ) + # Save the path to the generated source file, relative to the the current build dir. # The path will be used in static library prl file generation to ensure qmake links # against the installed resource object files. @@ -605,80 +795,58 @@ function(_qt_internal_propagate_qmlcache_object_lib set_property(TARGET ${resource_target} APPEND PROPERTY _qt_resource_generated_cpp_relative_path "${generated_cpp_file_relative_path}") - # FIXME: _is_qt_resource_target finalizer mode processing has been removed in this - # implementation, because qtbase's finalizer currently can't handle conditional linking - # of object libraries. It would try to link to the object library unconditionally, ignoring - # ${link_condition}. See the implementation of __qt_internal_collect_dependency_resource_objects - # for the reason why that happens. - - # Do not litter the static libraries - set(not_static_condition - "$,STATIC_LIBRARY>>" - ) - set(resource_objects "$>") - - # It's necessary to link the object library target, since we want to pass - # the object library dependencies to the 'target'. Interface linking doesn't - # add the objects of the resource library to the end-point linker line - # but propagates all the dependencies of the resource_target added before - # or AFTER the line below. - target_link_libraries(${target} INTERFACE - "$<$:${resource_target}>" - ) - # Qml specific additions. target_link_libraries(${resource_target} PRIVATE ${QT_CMAKE_EXPORT_NAMESPACE}::QmlPrivate ${QT_CMAKE_EXPORT_NAMESPACE}::Core ) - # FIXME: Try to adapt finalizer approach to be usable here. - # - # We need the qmlcache_loader.cpp.o file to appear before ${target} on the link line. - # Otherwise GNU ld will discard the compiled-QML files that were embedded into the static - # ${target} library, which are referenced by the loader file. - # - # We can't use target_link_libraries(${target} INTERFACE $) - # because that will place the object file after ${target} on the link line with all CMake - # versions lower than 3.21.0. - # https://gitlab.kitware.com/cmake/cmake/-/merge_requests/6166 - # - # We can't use the qtbase finalizer approach at the moment, because its implementation doesn't - # take into account the ${condition_link} genex. - # There might also be complications using finalizer mode during the Qt build itself, because we - # currently only use it in public user projects (those that call qt_finalize_target). - # - # We are forced to use target_sources to place the object file before ${target}. - # This means linking will fail for user projects that will try to propagate the usage - # of ${target} via their own static library A, if library A doesn't link publicly to ${target}. - # This is not the majority of user projects. - # Hopefully we can lift this limitation once we can use the finalizer approach here. - # - # Until then, this is needed to get the Qt build working. - target_sources(${target} INTERFACE - "$<$:${resource_objects}>" + __qt_internal_propagate_object_library(${target} ${resource_target} + EXTRA_CONDITIONS "${link_condition}" ) set(${output_generated_target} "${resource_target}" PARENT_SCOPE) endfunction() -function(_qt_internal_target_enable_qmlcachegen target output_targets_var) +function(_qt_internal_target_enable_qmlcachegen target output_targets_var qmlcachegen) set(output_targets) set_target_properties(${target} PROPERTIES _qt_cachegen_set_up TRUE) get_target_property(target_binary_dir ${target} BINARY_DIR) - set(qmlcache_dir ${target_binary_dir}/.rcc/qmlcache/${target}) + set(qmlcache_dir ${target_binary_dir}/.rcc/qmlcache) set(qmlcache_resource_name qmlcache_${target}) - set(qmlcache_loader_cpp ${qmlcache_dir}/qmlcache_loader.cpp) - set(qmlcache_loader_list ${qmlcache_dir}/qml_loader_file_list.rsp) + + # INTEGRITY_SYMBOL_UNIQUENESS + # The cache loader file name has to be unique, because the Integrity compiler uses the file name + # for the generation of the translation unit static constructor symbol name. + # e.g. __sti___19_qmlcache_loader_cpp_11acedbd + # For some reason the symbol is created with global visibility. + # + # When an application links against the Basic and Fusion static qml plugins, the linker + # fails with duplicate symbol errors because both of those plugins will contain the same symbol. + # + # With gcc on regular Linux, the symbol names are also the same, but it's not a problem because + # they have local (hidden) visbility. + # + # Make the file name unique by prepending the target name. + set(qmlcache_loader_cpp ${qmlcache_dir}/${target}_qmlcache_loader.cpp) + + set(qmlcache_loader_list ${qmlcache_dir}/${target}_qml_loader_file_list.rsp) set(qmlcache_resource_paths "$") - set(qmlcache_have_resource_paths "$") + _qt_internal_genex_getjoinedproperty(qrc_resource_args ${target} + _qt_generated_qrc_files "--resource$" "$" + ) + + if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config" AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + set(qmlcachegen "$") + endif() set(cmd ${QT_TOOL_COMMAND_WRAPPER_PATH} - $ + ${qmlcachegen} --resource-name "${qmlcache_resource_name}" + ${qrc_resource_args} -o "${qmlcache_loader_cpp}" "@${qmlcache_loader_list}" ) @@ -686,32 +854,46 @@ function(_qt_internal_target_enable_qmlcachegen target output_targets_var) file(GENERATE OUTPUT ${qmlcache_loader_list} CONTENT "$\n" - CONDITION "${qmlcache_have_resource_paths}" ) add_custom_command( OUTPUT ${qmlcache_loader_cpp} - COMMAND "$<${qmlcache_have_resource_paths}:${cmd}>" + COMMAND "${cmd}" COMMAND_EXPAND_LISTS DEPENDS - ${QT_CMAKE_EXPORT_NAMESPACE}::qmlcachegen - ${qmlcache_loader_list} + ${qmlcachegen} + ${qmlcache_loader_list} + $ ) + # The current scope sees the file as generated automatically, but the + # target scope may not if it is different. Force it where we can. + if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.18") + set_source_files_properties( + ${qmlcache_loader_cpp} + TARGET_DIRECTORY ${target} + PROPERTIES GENERATED TRUE + ) + endif() + get_target_property(target_source_dir ${target} SOURCE_DIR) + if(NOT target_source_dir STREQUAL CMAKE_CURRENT_SOURCE_DIR) + add_custom_target(${target}_qmlcachegen DEPENDS ${qmlcache_loader_cpp}) + add_dependencies(${target} ${target}_qmlcachegen) + endif() + # TODO: Probably need to reject ${target} being an object library as unsupported get_target_property(target_type ${target} TYPE) if(target_type STREQUAL "STATIC_LIBRARY") + set(extra_conditions "") _qt_internal_propagate_qmlcache_object_lib( ${target} "${qmlcache_loader_cpp}" - "${qmlcache_have_resource_paths}" + "${extra_conditions}" output_target) list(APPEND output_targets ${output_target}) else() - target_sources(${target} PRIVATE - "$<${qmlcache_have_resource_paths}:${qmlcache_loader_cpp}>" - ) + target_sources(${target} PRIVATE "${qmlcache_loader_cpp}") target_link_libraries(${target} PRIVATE ${QT_CMAKE_EXPORT_NAMESPACE}::QmlPrivate ${QT_CMAKE_EXPORT_NAMESPACE}::Core @@ -729,7 +911,7 @@ endfunction() # trigger some unnecessary rebuilds after reconfiguring due to the qmldir # file's timestamp being updated even though its contents might not change, # but that's the cost of not having deferred write capability. -function(_qt_internal_target_generate_qmldir target out_dir target_path) +function(_qt_internal_target_generate_qmldir target) macro(_qt_internal_qmldir_item prefix property) get_target_property(_value ${target} ${property}) @@ -753,6 +935,8 @@ function(_qt_internal_target_generate_qmldir target out_dir target_path) endif() set(content "module ${uri}\n") + _qt_internal_qmldir_item(linktarget QT_QML_MODULE_INSTALLED_PLUGIN_TARGET) + get_target_property(plugin_target ${target} QT_QML_MODULE_PLUGIN_TARGET) if(plugin_target) get_target_property(no_plugin_optional ${target} QT_QML_MODULE_NO_PLUGIN_OPTIONAL) @@ -760,8 +944,14 @@ function(_qt_internal_target_generate_qmldir target out_dir target_path) string(APPEND content "optional ") endif() - get_target_property(qt_libinfix ${target} QT_QML_MODULE_LIBINFIX) - string(APPEND content "plugin ${plugin_target}${qt_libinfix}\n") + get_target_property(target_path ${target} QT_QML_MODULE_TARGET_PATH) + _qt_internal_get_qml_plugin_output_name(plugin_output_name ${plugin_target} + TARGET_PATH "${target_path}" + URI "${uri}" + ) + string(APPEND content "plugin ${plugin_output_name}\n") + + _qt_internal_qmldir_item(classname QT_QML_MODULE_CLASS_NAME) endif() get_target_property(designer_supported ${target} QT_QML_MODULE_DESIGNER_SUPPORTED) @@ -769,14 +959,13 @@ function(_qt_internal_target_generate_qmldir target out_dir target_path) string(APPEND content "designersupported\n") endif() - _qt_internal_qmldir_item(classname QT_QML_MODULE_CLASS_NAME) - _qt_internal_qmldir_item(typeinfo QT_QMLTYPES_FILENAME) + _qt_internal_qmldir_item(typeinfo QT_QML_MODULE_TYPEINFO) _qt_internal_qmldir_item_list(import QT_QML_MODULE_IMPORTS) _qt_internal_qmldir_item_list("optional import" QT_QML_MODULE_OPTIONAL_IMPORTS) _qt_internal_qmldir_item_list(depends QT_QML_MODULE_DEPENDENCIES) - get_target_property(prefix ${target} QT_RESOURCE_PREFIX) + get_target_property(prefix ${target} QT_QML_MODULE_RESOURCE_PREFIX) if(prefix) # Ensure we use a path that ends with a "/", but handle the special case # of "/" without anything after it @@ -797,69 +986,19 @@ function(_qt_internal_target_generate_qmldir target out_dir target_path) # NOTE: qt6_target_qml_sources() may append further content later. endfunction() -# TODO: Need to consider the case where an executable's finalizer might execute -# before our deferred call. That can occur in the following situations: -# -# - The executable target is created in the same scope as the qml module -# and the executable target is created first. -# - The qml module is created in a parent scope of the executable. -# -# Note that the qml module can safely be created in another scope as long -# as that scope has been finalized by the time the executable target's -# finalizer is called. A child scope satisfies this, as does any other -# scope that has already finished being processed earlier in the CMake run. function(_qt_internal_write_deferred_qmldir_file target) get_target_property(__qt_qmldir_content ${target} _qt_internal_qmldir_content) - get_target_property(out_dir ${target} QT_QML_MODULE_OUTPUT_DIR) + get_target_property(out_dir ${target} QT_QML_MODULE_OUTPUT_DIRECTORY) set(qmldir_file "${out_dir}/qmldir") configure_file(${__qt_qml_macros_module_base_dir}/Qt6qmldirTemplate.cmake.in ${qmldir_file} @ONLY) endfunction() -# Create a Qml plugin. Projects should not normally need to call this function -# directly. Rather, it would normally be called by qt6_add_qml_module() to -# create or update the plugin associated with its backing target. -# -# target: The name of the target to use for the qml plugin. If it does not -# already exist, it will be created. (REQUIRED) -# -# STATIC, SHARED: Explicitly specify the type of plugin library to create. -# At most one of these two options can be specified. (OPTIONAL) -# -# BACKING_TARGET: The backing target that the plugin is associated with. This -# can be the same as ${target}, in which case there is only the one merged -# target. If this option is not provided, then URI must be given. (OPTIONAL) -# -# URI: Declares the module identifier of the qml module this plugin is -# associated with. The module identifier is the (dotted URI notation) -# identifier for the qml module. If URI is not given, then a BACKING_TARGET -# must be provided (the backing target should have its URI recorded on it by -# qt6_add_qml_module()). (OPTIONAL) -# -# TARGET_PATH: Overwrite the generated target path. By default the target path -# is generated from the URI by replacing the '.' with a '/'. However, under -# certain circumstances this may not be enough. Use this argument to provide -# a replacement. It is only used if targeting Android. (OPTIONAL) -# -# CLASS_NAME: By default, the class name will be taken from the backing target, -# if provided, or falling back to the URI with "Plugin" appended. Any -# non-alphanumeric characters in the URI will be replaced with underscores. -# (OPTIONAL) -# -# OUTPUT_DIRECTORY: Overrides the directory where the plugin library will be -# created. Defaults to ${CMAKE_CURRENT_BINARY_DIR} if not specified. -# (OPTIONAL) -# -# NO_GENERATE_SOURCE: A .cpp file will be created for the plugin class -# by default and automatically added to the plugin target. Use this option to -# indicate that no such .cpp file should be generated. The caller is then -# responsible for providing their own plugin class. (OPTIONAL) -# function(qt6_add_qml_plugin target) set(args_option STATIC SHARED - NO_GENERATE_SOURCE + NO_GENERATE_PLUGIN_SOURCE ) set(args_single @@ -868,7 +1007,8 @@ function(qt6_add_qml_plugin target) BACKING_TARGET CLASS_NAME # The following is only needed on Android, and even then, only if the - # default conversion from the URI is not applicable + # default conversion from the URI is not applicable. It is an internal + # option, it may be removed. TARGET_PATH ) @@ -880,21 +1020,53 @@ function(qt6_add_qml_plugin target) "${args_multi}" ) + if(arg_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + if(NOT arg_URI) if(NOT arg_BACKING_TARGET) message(FATAL_ERROR "No URI or BACKING_TARGET provided") endif() - if(arg_BACKING_TARGET STREQUAL target AND NOT TARGET ${target}) + if(NOT TARGET ${arg_BACKING_TARGET}) + if(arg_BACKING_TARGET STREQUAL target) + message(FATAL_ERROR + "Plugin ${target} is its own backing target, URI must be provided" + ) + else() + message(FATAL_ERROR + "No URI provided and unable to obtain it from the BACKING_TARGET " + "(${arg_BACKING_TARGET}) because no such target exists" + ) + endif() + endif() + get_target_property(arg_URI ${arg_BACKING_TARGET} QT_QML_MODULE_URI) + if(NOT arg_URI) message(FATAL_ERROR - "Plugin ${target} is its own backing target, URI must be provided" + "No URI provided and the BACKING_TARGET (${arg_BACKING_TARGET}) " + "does not have one set either" ) endif() - get_target_property(arg_URI ${arg_BACKING_TARGET} QT_QML_MODULE_URI) endif() - string(REGEX REPLACE "[^A-Za-z0-9]" "_" escaped_uri "${arg_URI}") + _qt_internal_get_escaped_uri("${arg_URI}" escaped_uri) + + if(NOT arg_CLASS_NAME) + if(NOT "${arg_BACKING_TARGET}" STREQUAL "") + get_target_property(arg_CLASS_NAME ${arg_BACKING_TARGET} QT_QML_MODULE_CLASS_NAME) + endif() + if(NOT arg_CLASS_NAME) + _qt_internal_compute_qml_plugin_class_name_from_uri("${arg_URI}" arg_CLASS_NAME) + endif() + endif() if(TARGET ${target}) + # Plugin target already exists. Perform a few sanity checks, but we + # otherwise trust that the target is appropriate for use as a plugin. + get_target_property(target_type ${target} TYPE) + if(target_type STREQUAL "EXECUTABLE") + message(FATAL_ERROR "Plugins cannot be executables (target: ${target})") + endif() foreach(arg IN ITEMS STATIC SHARED) if(arg_${arg}) message(FATAL_ERROR @@ -902,17 +1074,22 @@ function(qt6_add_qml_plugin target) ) endif() endforeach() - get_target_property(class_name ${target} QT_PLUGIN_CLASS_NAME) - if(class_name) - if(arg_CLASS_NAME AND NOT arg_CLASS_NAME STREQUAL class_name) + + get_target_property(existing_class_name ${target} QT_PLUGIN_CLASS_NAME) + if(existing_class_name) + if(NOT existing_class_name STREQUAL arg_CLASS_NAME) message(FATAL_ERROR - "CLASS_NAME was specified, but an existing target with a " - "different class name was also given" + "An existing plugin target was given, but it has a different class name " + "(${existing_class_name}) to that being used here (${arg_CLASS_NAME})" ) endif() - set(arg_CLASS_NAME ${class_name}) - elseif(NOT arg_CLASS_NAME) - set(arg_CLASS_NAME "${escaped_uri}Plugin") + elseif(arg_CLASS_NAME) + set_property(TARGET ${target} PROPERTY QT_PLUGIN_CLASS_NAME "${arg_CLASS_NAME}") + else() + message(FATAL_ERROR + "An existing '${target}' plugin target was given, but it has no class name set " + "and no new class name was provided." + ) endif() else() if(arg_STATIC AND arg_SHARED) @@ -927,12 +1104,42 @@ function(qt6_add_qml_plugin target) set(lib_type SHARED) endif() - if(NOT arg_CLASS_NAME) - set(arg_CLASS_NAME "${escaped_uri}Plugin") + if(TARGET "${arg_BACKING_TARGET}") + # Ensure that the plugin type we create will be compatible with the + # type of backing target we were given + get_target_property(backing_type ${arg_BACKING_TARGET} TYPE) + if(backing_type STREQUAL "STATIC_LIBRARY") + if(lib_type STREQUAL "") + set(lib_type STATIC) + elseif(lib_type STREQUAL "SHARED") + message(FATAL_ERROR + "Mixing a static backing library with a non-static plugin " + "is not supported" + ) + endif() + elseif(backing_type STREQUAL "SHARED_LIBRARY") + if(lib_type STREQUAL "") + set(lib_type SHARED) + elseif(lib_type STREQUAL "STATIC") + message(FATAL_ERROR + "Mixing a non-static backing library with a static plugin " + "is not supported" + ) + endif() + elseif(backing_type STREQUAL "EXECUTABLE") + message(FATAL_ERROR + "A separate plugin should not be needed when the backing target " + "is an executable. Pre-create the plugin target before calling " + "this command if you really must have a separate plugin." + ) + else() + # Object libraries, utility/custom targets + message(FATAL_ERROR "Unsupported backing target type: ${backing_type}") + endif() endif() qt6_add_plugin(${target} ${lib_type} - TYPE qml_plugin + PLUGIN_TYPE qml_plugin CLASS_NAME ${arg_CLASS_NAME} ) endif() @@ -955,35 +1162,25 @@ function(qt6_add_qml_plugin target) ) endif() - if (ANDROID) - # Adjust Qml plugin names on Android similar to qml_plugin.prf which calls - # $$qt5LibraryTarget($$TARGET, "qml/$$TARGETPATH/"). - # Example plugin names: - # qtdeclarative - # TARGET_PATH: QtQml/Models - # file name: libqml_QtQml_Models_modelsplugin_arm64-v8a.so - # qtquickcontrols2 - # TARGET_PATH: QtQuick/Controls.2/Material - # file name: - # libqml_QtQuick_Controls.2_Material_qtquickcontrols2materialstyleplugin_arm64-v8a.so - if(NOT arg_TARGET_PATH AND TARGET "${arg_BACKING_TARGET}") - get_target_property(arg_TARGET_PATH ${target} ${arg_BACKING_TARGET}) - endif() - if(arg_TARGET_PATH) - string(REPLACE "/" "_" android_plugin_name_infix_name "${arg_TARGET_PATH}") - else() - string(REPLACE "." "_" android_plugin_name_infix_name "${arg_URI}") - endif() - - set(final_android_qml_plugin_name "qml_${android_plugin_name_infix_name}_${target}") + if(ANDROID) + _qt_internal_get_qml_plugin_output_name(plugin_output_name ${target} + BACKING_TARGET "${arg_BACKING_TARGET}" + TARGET_PATH "${arg_TARGET_PATH}" + URI "${arg_URI}" + ) set_target_properties(${target} PROPERTIES - LIBRARY_OUTPUT_NAME "${final_android_qml_plugin_name}" + LIBRARY_OUTPUT_NAME "${plugin_output_name}" ) qt6_android_apply_arch_suffix(${target}) endif() + if(NOT arg_OUTPUT_DIRECTORY AND arg_BACKING_TARGET AND TARGET ${arg_BACKING_TARGET}) + get_target_property(arg_OUTPUT_DIRECTORY ${arg_BACKING_TARGET} QT_QML_MODULE_OUTPUT_DIRECTORY) + endif() if(arg_OUTPUT_DIRECTORY) + # Plugin target must be in the output directory. The backing target, + # if it is different to the plugin target, can be anywhere. set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${arg_OUTPUT_DIRECTORY} LIBRARY_OUTPUT_DIRECTORY ${arg_OUTPUT_DIRECTORY} @@ -991,14 +1188,14 @@ function(qt6_add_qml_plugin target) ) endif() - if(NOT arg_NO_GENERATE_SOURCE) + if(NOT arg_NO_GENERATE_PLUGIN_SOURCE) set(generated_cpp_file_name_base "${target}_${arg_CLASS_NAME}") set(register_types_function_name "qml_register_types_${escaped_uri}") # These are all substituted in the template file used further below set(qt_qml_plugin_class_name "${arg_CLASS_NAME}") set(qt_qml_plugin_moc_include_name "${generated_cpp_file_name_base}.moc") - set(qt_qml_plugin_intro "extern void ${register_types_function_name}();") + set(qt_qml_plugin_intro "extern void ${register_types_function_name}();\nQ_GHS_KEEP_REFERENCE(${register_types_function_name});") set(qt_qml_plugin_outro "") if(QT_BUILDING_QT) string(APPEND qt_qml_plugin_intro "\n\nQT_BEGIN_NAMESPACE") @@ -1027,10 +1224,24 @@ function(qt6_add_qml_plugin target) endif() target_link_libraries(${target} PRIVATE ${QT_CMAKE_EXPORT_NAMESPACE}::Qml) - if(NOT "${arg_BACKING_TARGET}" STREQUAL target) + + # Link plugin against its backing lib if it has one. + if(NOT arg_BACKING_TARGET STREQUAL "" AND NOT arg_BACKING_TARGET STREQUAL target) target_link_libraries(${target} PRIVATE ${arg_BACKING_TARGET}) endif() + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.19.0") + # Defer the collection of plugin dependencies until after any extra target_link_libraries + # calls that a user project might do. + # We wrap the deferred call with EVAL CODE + # so that ${target} is evaluated now rather than the end of the scope. + cmake_language(EVAL CODE + "cmake_language(DEFER CALL _qt_internal_add_static_qml_plugin_dependencies \"${target}\" \"${arg_BACKING_TARGET}\")" + ) + else() + # Can't defer, have to do it now. + _qt_internal_add_static_qml_plugin_dependencies("${target}" "${arg_BACKING_TARGET}") + endif() endfunction() if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) @@ -1039,76 +1250,15 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) endfunction() endif() -# Add Qml files (.qml,.js,.mjs) to a Qml module. -# -# target: The backing target of the qml module. (REQUIRED) -# -# FILES: The qml files to add to the backing target. Supported file extensions -# are .qml, .js and .mjs. No other file types should be listed. (REQUIRED) -# -# PREFIX: The resource path under which to add the compiled qml files. If not -# specified, the QT_RESOURCE_PREFIX property of the target is used (that -# property is normally set by qt6_add_qml_module()). If the default is empty, -# this option must be provided. (OPTIONAL) -# -# OUTPUT_TARGETS: In static builds, additional CMake targets can be created -# which consumers of the module will need to link to and potentially install. -# Supply the name of an output variable, which will be set to a list of these -# targets. If installing the main target, you will also need to install these -# output targets for static builds. (OPTIONAL) -# -# NO_LINT: Do not add the specified files to the ${target}_qmllint target. -# If this option is not given, the default will be taken from the target. -# -# NO_CACHEGEN: Do not compile the qml files. Add the raw qml files to the -# target resources instead. If this option is not given, the default will be -# taken from the target. -# -# NO_QMLDIR_TYPES: Do not append type information from the qml files to the -# qmldir file associated with the qml module. If this option is not given, -# the default will be taken from the target. -# -# In addition to the above NO_... options, individual files can be explicitly -# skipped by setting the relevant source property. These are: -# -# - QT_QML_SKIP_QMLLINT -# - QT_QML_SKIP_QMLDIR_ENTRY -# - QT_QML_SKIP_CACHEGEN -# -# Disabling the qmldir entry for a qml file would normally only be used for a -# file that does not expose a public type (e.g. a private JS file). -# If appending of type information has not been disabled for a particular qml -# file, the following additional source properties can be specified to -# customize the file's type details: -# -# QT_QML_SOURCE_VERSION: Version(s) for this qml file. If not present the module -# version will be used. -# -# QT_QML_SOURCE_TYPENAME: Override the file's type name. If not present, the -# type name will be deduced using the file's basename. -# -# QT_QML_SINGLETON_TYPE: Set to true if this qml file contains a singleton type. -# -# QT_QML_INTERNAL_TYPE: When set to true, the type specified by -# QT_QML_SOURCE_TYPENAME will not be available to users of this module. -# -# e.g.: -# set_source_files_properties(my_qml_file.qml -# PROPERTIES -# QT_QML_SOURCE_VERSION "2.0;6.0" -# QT_QML_SOURCE_TYPENAME MyQmlFile -# -# qt6_target_qml_sources(my_qml_module -# FILES -# my_qml_file.qml -# ) -# -# The above will produce the following entry in the qmldir file: -# -# MyQmlFile 2.0 my_qml_file.qml -# + function(qt6_target_qml_sources target) + get_target_property(uri ${target} QT_QML_MODULE_URI) + get_target_property(output_dir ${target} QT_QML_MODULE_OUTPUT_DIRECTORY) + if(NOT uri OR NOT output_dir) + message(FATAL_ERROR "Target ${target} is not a QML module") + endif() + set(args_option NO_LINT NO_CACHEGEN @@ -1122,7 +1272,8 @@ function(qt6_target_qml_sources target) ) set(args_multi - FILES + QML_FILES + RESOURCES ) cmake_parse_arguments(PARSE_ARGV 1 arg @@ -1132,25 +1283,28 @@ function(qt6_target_qml_sources target) message(FATAL_ERROR "Unknown/unexpected arguments: ${arg_UNPARSED_ARGUMENTS}") endif() - if (NOT arg_FILES) + if (NOT arg_QML_FILES AND NOT arg_RESOURCES) if(arg_OUTPUT_TARGETS) set(${arg_OUTPUT_TARGETS} "" PARENT_SCOPE) endif() return() endif() - if(arg___QT_INTERNAL_FORCE_DEFER_QMLDIR OR ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.19.0") - set(can_defer_qmldir TRUE) - else() - set(can_defer_qmldir FALSE) + if(NOT arg___QT_INTERNAL_FORCE_DEFER_QMLDIR AND ${CMAKE_VERSION} VERSION_LESS "3.19.0") + message(FATAL_ERROR + "You are using CMake ${CMAKE_VERSION}, but CMake 3.19 or later " + "is required to add qml files with this function. Either pass " + "the qml files to qt6_add_qml_module() instead or update to " + "CMake 3.19 or later." + ) endif() get_target_property(no_lint ${target} QT_QML_MODULE_NO_LINT) get_target_property(no_cachegen ${target} QT_QML_MODULE_NO_CACHEGEN) get_target_property(no_qmldir ${target} QT_QML_MODULE_NO_GENERATE_QMLDIR) - get_target_property(resource_prefix ${target} QT_RESOURCE_PREFIX) + get_target_property(resource_prefix ${target} QT_QML_MODULE_RESOURCE_PREFIX) get_target_property(qml_module_version ${target} QT_QML_MODULE_VERSION) - get_target_property(output_dir ${target} QT_QML_MODULE_OUTPUT_DIR) + get_target_property(past_major_versions ${target} QT_QML_MODULE_PAST_MAJOR_VERSIONS) if(NOT output_dir) # Probably not a qml module. We still want to support tooling for this @@ -1165,14 +1319,29 @@ function(qt6_target_qml_sources target) set(arg_PREFIX ${resource_prefix}) else() message(FATAL_ERROR - "PREFIX option not given and target ${target} was not given a RESOURCE_PREFIX" + "PREFIX option not given and target ${target} does not have a " + "QT_QML_MODULE_RESOURCE_PREFIX property set." ) endif() endif() - if(NOT arg_PREFIX MATCHES [[/$]]) + _qt_internal_canonicalize_resource_path("${arg_PREFIX}" arg_PREFIX) + if(NOT arg_PREFIX STREQUAL "/") string(APPEND arg_PREFIX "/") endif() + if (qml_module_version MATCHES "^([0-9]+)\\.") + set(qml_module_files_versions "${CMAKE_MATCH_1}.0") + else() + message(FATAL_ERROR + "No major version found in '${qml_module_version}'." + ) + endif() + if (past_major_versions OR past_major_versions STREQUAL "0") + foreach (past_major_version ${past_major_versions}) + list(APPEND qml_module_files_versions "${past_major_version}.0") + endforeach() + endif() + # Linting and cachegen can still occur for a target that isn't a qml module, # but for such targets, there is no qmldir file to update. if(arg_NO_LINT) @@ -1185,78 +1354,112 @@ function(qt6_target_qml_sources target) set(no_qmldir TRUE) endif() - if(NOT no_cachegen) + if(NOT no_cachegen AND arg_QML_FILES) _qt_internal_genex_getproperty(types_file ${target} QT_QML_MODULE_PLUGIN_TYPES_FILE) + _qt_internal_genex_getproperty(qmlcachegen ${target} QT_QMLCACHEGEN_BINARY) _qt_internal_genex_getproperty(direct_calls ${target} QT_QMLCACHEGEN_DIRECT_CALLS) - _qt_internal_genex_getproperty(qmljs_runtime ${target} QT_QMLCACHEGEN_QMLJS_RUNTIME) + _qt_internal_genex_getjoinedproperty(arguments ${target} + QT_QMLCACHEGEN_ARGUMENTS "$" "$" + ) _qt_internal_genex_getjoinedproperty(import_paths ${target} QT_QML_IMPORT_PATH "-I$" "$" ) + _qt_internal_genex_getjoinedproperty(qrc_resource_args ${target} + _qt_generated_qrc_files "--resource$" "$" + ) + get_target_property(target_type ${target} TYPE) + get_target_property(is_android_executable ${target} _qt_is_android_executable) + if(target_type STREQUAL "EXECUTABLE" OR is_android_executable) + # The application binary directory is part of the default import path. + list(APPEND import_paths -I "$") + endif() + _qt_internal_extend_qml_import_paths(import_paths) set(cachegen_args - "$<${have_import_paths}:${import_paths}>" + ${import_paths} "$<${have_types_file}:-i$${types_file}>" "$<${have_direct_calls}:--direct-calls>" - "$<${have_qmljs_runtime}:--qmljs-runtime>" + "$<${have_arguments}:${arguments}>" + ${qrc_resource_args} ) + + # For direct evaluation in if() below + get_target_property(cachegen_prop ${target} QT_QMLCACHEGEN_BINARY) + if(cachegen_prop) + if(cachegen_prop STREQUAL "qmlcachegen" OR cachegen_prop STREQUAL "qmlsc") + # If it's qmlcachegen or qmlsc, don't go looking for other programs of that name + set(qmlcachegen "$") + else() + find_program(${target}_QMLCACHEGEN ${cachegen_prop}) + if(${target}_QMLCACHEGEN) + set(qmlcachegen "${${target}_QMLCACHEGEN}") + else() + message(FATAL_ERROR "Invalid qmlcachegen binary ${cachegen_prop} for ${target}") + endif() + endif() + else() + set(have_qmlsc "$") + set(cachegen_name "$") + set(qmlcachegen "$") + endif() endif() set(non_qml_files) set(output_targets) + set(copied_files) - foreach(qml_file_src IN LISTS arg_FILES) - # This is to facilitate updating code that used the earlier tech preview - # API function qt6_target_qml_files() - if(NOT qml_file_src MATCHES "\\.(js|mjs|qml)$") - list(APPEND non_qml_files ${qml_file_src}) - continue() - endif() - + foreach(file_src IN LISTS arg_QML_FILES arg_RESOURCES) # We need to copy the file to the build directory now so that when # qmlimportscanner is run in qt6_import_qml_plugins() as part of - # target finalizers, the qml files will be there. We need to do this + # target finalizers, the files will be there. We need to do this # in a way that CMake doesn't create a dependency on the source or it - # will re-run CMake every time the qml file is modified. We also don't + # will re-run CMake every time the file is modified. We also don't # want to update the file's timestamp if its contents won't change. - # We still enforce the dependency on the qml source file by adding a + # We still enforce the dependency on the source file by adding a # build-time rule. This avoids having to re-run CMake just to re-copy # the file. - get_filename_component(file_absolute ${qml_file_src} ABSOLUTE) - file(RELATIVE_PATH file_relative ${CMAKE_CURRENT_SOURCE_DIR} ${file_absolute}) - - get_property(alias SOURCE ${qml_file_src} PROPERTY QT_RESOURCE_ALIAS) - if(alias) - set(file_resource_path ${alias}) - else() - set(file_resource_path ${file_relative}) - endif() + get_filename_component(file_absolute ${file_src} ABSOLUTE) + __qt_get_relative_resource_path_for_file(file_resource_path ${file_src}) - set(qml_file_out ${output_dir}/${file_resource_path}) + set(file_out ${output_dir}/${file_resource_path}) # Don't generate or copy the file in an in-source build if the source # and destination paths are the same, it will cause a ninja dependency # cycle at build time. - if(NOT qml_file_out STREQUAL file_absolute) - get_filename_component(file_out_dir ${qml_file_out} DIRECTORY) + if(NOT file_out STREQUAL file_absolute) + get_filename_component(file_out_dir ${file_out} DIRECTORY) file(MAKE_DIRECTORY ${file_out_dir}) - set(need_write TRUE) - file(READ ${qml_file_src} new_contents) - if(EXISTS ${qml_file_out}) - file(READ ${qml_file_out} old_contents) - if("${new_contents}" STREQUAL "${old_contents}") - set(need_write FALSE) - endif() - endif() - if(need_write) - file(WRITE ${qml_file_out} "${new_contents}") + if(EXISTS "${file_absolute}") + execute_process(COMMAND + ${CMAKE_COMMAND} -E copy_if_different ${file_absolute} ${file_out} + ) endif() - add_custom_command(OUTPUT ${qml_file_out} - COMMAND ${CMAKE_COMMAND} -E copy ${qml_file_src} ${qml_file_out} - DEPENDS ${qml_file_src} + add_custom_command(OUTPUT ${file_out} + COMMAND ${CMAKE_COMMAND} -E copy ${file_src} ${file_out} + DEPENDS ${file_absolute} WORKING_DIRECTORY $ ) + list(APPEND copied_files ${file_out}) endif() + endforeach() + + set(generated_sources_other_scope) + foreach(qml_file_src IN LISTS arg_QML_FILES) + # This is to facilitate updating code that used the earlier tech preview + # API function qt6_target_qml_files() + if(NOT qml_file_src MATCHES "\\.(js|mjs|qml)$") + list(APPEND non_qml_files ${qml_file_src}) + continue() + endif() + + # Mark QML files as source files, so that they do not appear in in Creator + # or other IDEs + set_source_files_properties(${qml_file_src} HEADER_FILE_ONLY ON) + target_sources(${target} PRIVATE ${qml_file_src}) + + get_filename_component(file_absolute ${qml_file_src} ABSOLUTE) + __qt_get_relative_resource_path_for_file(file_resource_path ${qml_file_src}) # For the tooling steps below, run the tools on the copied qml file in # the build directory, not the source directory. This is required @@ -1266,17 +1469,13 @@ function(qt6_target_qml_sources target) # resource paths and the source locations might be structured quite # differently. - # Fed to qmlimportscanner in qt6_import_qml_plugins. Also may be used in - # generator expressions to install all qml files for the target. - set_property(TARGET ${target} APPEND PROPERTY QT_QML_MODULE_FILES ${qml_file_out}) - # Add file to those processed by qmllint get_source_file_property(skip_qmllint ${qml_file_src} QT_QML_SKIP_QMLLINT) if(NOT no_lint AND NOT skip_qmllint) # The set of qml files to run qmllint on may be a subset of the # full set of files, so record these in a separate property. _qt_internal_target_enable_qmllint(${target}) - set_property(TARGET ${target} APPEND PROPERTY QT_QML_LINT_FILES ${qml_file_out}) + set_property(TARGET ${target} APPEND PROPERTY QT_QML_LINT_FILES ${file_absolute}) endif() # Add qml file's type to qmldir @@ -1284,27 +1483,51 @@ function(qt6_target_qml_sources target) if(NOT no_qmldir AND NOT skip_qmldir) get_source_file_property(qml_file_typename ${qml_file_src} QT_QML_SOURCE_TYPENAME) if (NOT qml_file_typename) - get_filename_component(qml_file_typename ${qml_file_src} NAME_WLE) + get_filename_component(qml_file_ext ${qml_file_src} EXT) + get_filename_component(qml_file_typename ${qml_file_src} NAME_WE) endif() # Do not add qmldir entries for lowercase names. Those are not components. - if (qml_file_typename MATCHES "^[A-Z]") - if(NOT can_defer_qmldir) - message(FATAL_ERROR - "You are using CMake ${CMAKE_VERSION}, but CMake 3.19 or later " - "is required to add qml files with this function. Either pass " - "the qml files to qt6_add_qml_module() instead or update to " - "CMake 3.19 or later." + if (qml_file_typename AND qml_file_typename MATCHES "^[A-Z]") + if (qml_file_ext AND NOT qml_file_ext STREQUAL ".qml" AND NOT qml_file_ext STREQUAL ".ui.qml" + AND NOT qml_file_ext STREQUAL ".js" AND NOT qml_file_ext STREQUAL ".mjs") + message(AUTHOR_WARNING + "${qml_file_src} has a file extension different from .qml, .ui.qml, .js, " + "and .mjs. This leads to unexpected component names." + ) + endif() + + # We previously accepted the singular form of this property name + # during tech preview. Issue a warning for that, but still + # honor it. The plural form will override it if both are set. + get_property(have_singular_property SOURCE ${qml_file_src} + PROPERTY QT_QML_SOURCE_VERSION SET + ) + if(have_singular_property) + message(AUTHOR_WARNING + "The QT_QML_SOURCE_VERSION source file property has been replaced " + "by QT_QML_SOURCE_VERSIONS (i.e. plural rather than singular). " + "The singular form will eventually be removed, please update " + "the project to use the plural form instead for the file at:\n" + " ${qml_file_src}" ) endif() + get_source_file_property(qml_file_versions ${qml_file_src} QT_QML_SOURCE_VERSIONS) + if(NOT qml_file_versions AND have_singular_property) + get_source_file_property(qml_file_versions ${qml_file_src} QT_QML_SOURCE_VERSION) + endif() - # TODO: rename to QT_QML_SOURCE_VERSIONS - get_source_file_property(qml_file_versions ${qml_file_src} QT_QML_SOURCE_VERSION) get_source_file_property(qml_file_singleton ${qml_file_src} QT_QML_SINGLETON_TYPE) get_source_file_property(qml_file_internal ${qml_file_src} QT_QML_INTERNAL_TYPE) + if (qml_file_singleton AND qml_file_internal) + message(FATAL_ERROR + "${qml_file_src} is marked as both internal and as a " + "singleton, but singletons cannot be internal!") + endif() + if (NOT qml_file_versions) - set(qml_file_versions ${qml_module_version}) + set(qml_file_versions ${qml_module_files_versions}) endif() set(qmldir_file_contents "") @@ -1332,7 +1555,7 @@ function(qt6_target_qml_sources target) # after we know there will be at least one file to compile. get_target_property(is_cachegen_set_up ${target} _qt_cachegen_set_up) if(NOT is_cachegen_set_up) - _qt_internal_target_enable_qmlcachegen(${target} resource_target) + _qt_internal_target_enable_qmlcachegen(${target} resource_target ${qmlcachegen}) list(APPEND output_targets ${resource_target}) endif() @@ -1343,52 +1566,106 @@ function(qt6_target_qml_sources target) QT_QML_MODULE_RESOURCE_PATHS ${file_resource_path} ) + file(RELATIVE_PATH file_relative ${CMAKE_CURRENT_SOURCE_DIR} ${file_absolute}) string(REGEX REPLACE "\\.(js|mjs|qml)$" "_\\1" compiled_file ${file_relative}) string(REGEX REPLACE "[$#?]+" "_" compiled_file ${compiled_file}) - set(compiled_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${target}/${compiled_file}.cpp") + + # The file name needs to be unique to work around an Integrity compiler issue. + # Search for INTEGRITY_SYMBOL_UNIQUENESS in this file for details. + set(compiled_file + "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${target}_${compiled_file}.cpp") get_filename_component(out_dir ${compiled_file} DIRECTORY) + if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config" AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") + set(qmlcachegen_cmd "$") + else() + set(qmlcachegen_cmd "${qmlcachegen}") + endif() add_custom_command( OUTPUT ${compiled_file} COMMAND ${CMAKE_COMMAND} -E make_directory ${out_dir} COMMAND ${QT_TOOL_COMMAND_WRAPPER_PATH} - $ + ${qmlcachegen_cmd} --resource-path "${file_resource_path}" ${cachegen_args} -o "${compiled_file}" "${file_absolute}" COMMAND_EXPAND_LISTS DEPENDS - ${QT_CMAKE_EXPORT_NAMESPACE}::qmlcachegen + ${qmlcachegen_cmd} "${file_absolute}" + $ "$<$:${types_file}>" ) - target_sources(${target} PRIVATE - ${compiled_file} - ${qml_file_src} # Make the original qml file show up under this target in the IDE - ) + target_sources(${target} PRIVATE ${compiled_file}) set_source_files_properties(${compiled_file} PROPERTIES SKIP_AUTOGEN ON ) + # The current scope automatically sees the file as generated, but the + # target scope may not if it is different. Force it where we can. + # We will also have to add the generated file to a target in this + # scope at the end to ensure correct dependencies. + get_target_property(target_source_dir ${target} SOURCE_DIR) + if(NOT target_source_dir STREQUAL CMAKE_CURRENT_SOURCE_DIR) + list(APPEND generated_sources_other_scope ${compiled_file}) + if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.18") + set_source_files_properties( + ${compiled_file} + TARGET_DIRECTORY ${target} + PROPERTIES + SKIP_AUTOGEN TRUE + GENERATED TRUE + ) + endif() + endif() endif() endforeach() + if(ANDROID) + _qt_internal_collect_qml_root_paths("${target}" ${arg_QML_FILES}) + endif() + if(non_qml_files) list(JOIN non_qml_files "\n " file_list) - if(COMMAND qt_add_resources) - set(cmd "qt_add_resources()") - else() - set(cmd "qt6_add_resources()") - endif() message(WARNING - "Only .qml, .js or .mjs files should be added with this function. " - "The following files should be added with ${cmd} instead:" + "Only .qml, .js or .mjs files should be added with QML_FILES. " + "The following files should be added with RESOURCES instead:" "\n ${file_list}" ) endif() + if(copied_files OR generated_sources_other_scope) + if(CMAKE_VERSION VERSION_LESS 3.19) + # Called from qt6_add_qml_module() and we know there can only be + # this one call. With those constraints, we can use a custom target + # to implement the necessary dependencies to get files copied to the + # build directory when their source files change. + add_custom_target(${target}_tooling ALL + DEPENDS + ${copied_files} + ${generated_sources_other_scope} + ) + add_dependencies(${target} ${target}_tooling) + else() + # We could be called multiple times and a custom target can only + # have file-level dependencies added at the time the target is + # created. Use an interface library instead, since we can add + # private sources to those and have the library act as a build + # system target from CMake 3.19 onward, and we can add the sources + # progressively over multiple calls. + if(NOT TARGET ${target}_tooling) + add_library(${target}_tooling INTERFACE) + add_dependencies(${target} ${target}_tooling) + endif() + target_sources(${target}_tooling PRIVATE + ${copied_files} + ${generated_sources_other_scope} + ) + endif() + endif() + # Batch all the non-compiled qml sources into a single resource for this # call. Subsequent calls for the same target will be in their own separate # resource file. @@ -1400,14 +1677,14 @@ function(qt6_target_qml_sources target) set(resource_targets) qt6_add_resources(${target} ${resource_name} PREFIX ${arg_PREFIX} - FILES ${arg_FILES} + FILES ${arg_QML_FILES} ${arg_RESOURCES} OUTPUT_TARGETS resource_targets ) math(EXPR counter "${counter} + 1") set_target_properties(${target} PROPERTIES QT_QML_MODULE_RAW_QML_SETS ${counter}) list(APPEND output_targets ${resource_targets}) - if(arg_OUTPUT_TARGETS AND output_targets) + if(arg_OUTPUT_TARGETS) set(${arg_OUTPUT_TARGETS} ${output_targets} PARENT_SCOPE) endif() @@ -1416,27 +1693,23 @@ endfunction() if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) function(qt_target_qml_sources) qt6_target_qml_sources(${ARGV}) + cmake_parse_arguments(PARSE_ARGV 1 arg "" "OUTPUT_TARGETS" "") + if(arg_OUTPUT_TARGETS) + set(${arg_OUTPUT_TARGETS} ${${arg_OUTPUT_TARGETS}} PARENT_SCOPE) + endif() endfunction() endif() -# NOTE: This function does not normally need to be called directly by projects. -# It is called automatically by qt6_add_qml_module() unless -# NO_GENERATE_QMLTYPES is also given to that function. -# # target: Expected to be the backing target for a qml module. Certain target # properties normally set by qt6_add_qml_module() will be retrieved from this # target. (REQUIRED) # -# OUTPUT_DIRECTORY: Specifies the directory in which to write the generated -# ${target}.qmltypes file. If not given, it defaults to the binary directory -# of the target. (OPTIONAL) -# # MANUAL_MOC_JSON_FILES: Specifies a list of json files, generated by a manual # moc call, to extract metatypes. (OPTIONAL) # -function(qt6_qml_type_registration target) - set(args_option "") - set(args_single OUTPUT_DIRECTORY) +function(_qt_internal_qml_type_registration target) + set(args_option __QT_INTERNAL_INSTALL_METATYPES_JSON) + set(args_single "") set(args_multi MANUAL_MOC_JSON_FILES) cmake_parse_arguments(PARSE_ARGV 1 arg @@ -1450,7 +1723,7 @@ function(qt6_qml_type_registration target) if (NOT import_name) message(FATAL_ERROR "Target ${target} is not a QML module") endif() - get_target_property(qmltypes_output_name ${target} QT_QMLTYPES_FILENAME) + get_target_property(qmltypes_output_name ${target} QT_QML_MODULE_TYPEINFO) if (NOT qmltypes_output_name) get_target_property(compile_definitions_list ${target} COMPILE_DEFINITIONS) list(FIND compile_definitions_list QT_PLUGIN is_a_plugin) @@ -1461,24 +1734,20 @@ function(qt6_qml_type_registration target) endif() endif() - # Horrible hack workaround to not install metatypes.json files for examples/ qml plugins into - # ${qt_prefix}/lib/meta_types. - # Put them into QT_QML_MODULE_INSTALL_DIR/lib/meta_types instead. - get_target_property(qml_install_dir ${target} QT_QML_MODULE_INSTALL_DIR) set(meta_types_json_args "") - - # TODO: This is internal Qt logic, it should be moved out of here. - if(QT_BUILDING_QT AND QT_WILL_INSTALL AND qml_install_dir AND - qml_install_dir MATCHES "^${INSTALL_EXAMPLESDIR}") - set(meta_types_json_args "INSTALL_DIR" "${qml_install_dir}/lib/metatypes") - endif() - if(arg_MANUAL_MOC_JSON_FILES) list(APPEND meta_types_json_args "MANUAL_MOC_JSON_FILES" ${arg_MANUAL_MOC_JSON_FILES}) endif() + + # Don't install the metatypes json files by default for user project created qml modules. + # Only install them for Qt provided qml modules. + if(NOT arg___QT_INTERNAL_INSTALL_METATYPES_JSON) + list(APPEND meta_types_json_args __QT_INTERNAL_NO_INSTALL) + endif() qt6_extract_metatypes(${target} ${meta_types_json_args}) get_target_property(import_version ${target} QT_QML_MODULE_VERSION) + get_target_property(output_dir ${target} QT_QML_MODULE_OUTPUT_DIRECTORY) get_target_property(target_source_dir ${target} SOURCE_DIR) get_target_property(target_binary_dir ${target} BINARY_DIR) get_target_property(target_metatypes_file ${target} INTERFACE_QT_META_TYPES_BUILD_FILE) @@ -1486,10 +1755,6 @@ function(qt6_qml_type_registration target) message(FATAL_ERROR "Target ${target} does not have a meta types file") endif() - if(NOT arg_OUTPUT_DIRECTORY) - set(arg_OUTPUT_DIRECTORY ${target_binary_dir}) - endif() - # Extract major and minor version (could also have patch part, but we don't # need that here) if (import_version MATCHES "^([0-9]+)\\.([0-9]+)") @@ -1509,7 +1774,7 @@ function(qt6_qml_type_registration target) endif() set(cmd_args) - set(plugin_types_file "${arg_OUTPUT_DIRECTORY}/${qmltypes_output_name}") + set(plugin_types_file "${output_dir}/${qmltypes_output_name}") set(generated_marker_file "${target_binary_dir}/.generated/${qmltypes_output_name}") get_filename_component(generated_marker_dir "${generated_marker_file}" DIRECTORY) set_target_properties(${target} PROPERTIES @@ -1523,7 +1788,7 @@ function(qt6_qml_type_registration target) ) # Add past minor versions - get_target_property(past_major_versions ${target} QT_QML_PAST_MAJOR_VERSIONS) + get_target_property(past_major_versions ${target} QT_QML_MODULE_PAST_MAJOR_VERSIONS) if (past_major_versions OR past_major_versions STREQUAL "0") foreach (past_major_version ${past_major_versions}) @@ -1553,6 +1818,11 @@ function(qt6_qml_type_registration target) if (TARGET ${target}Private) list(APPEND cmd_args --private-includes) + else() + string(REGEX MATCH "Private$" privateSuffix ${target}) + if (privateSuffix) + list(APPEND cmd_args --private-includes) + endif() endif() get_target_property(target_metatypes_json_file ${target} INTERFACE_QT_META_TYPES_BUILD_FILE) @@ -1560,28 +1830,6 @@ function(qt6_qml_type_registration target) message(FATAL_ERROR "Need target metatypes.json file") endif() - cmake_policy(PUSH) - - set(registration_cpp_file_dep_args) - if (CMAKE_GENERATOR MATCHES "Ninja" OR - (CMAKE_VERSION VERSION_GREATER_EQUAL 3.20 AND CMAKE_GENERATOR MATCHES "Makefiles")) - if(POLICY CMP0116) - # Without explicitly setting this policy to NEW, we get a warning - # even though we ensure there's actually no problem here. - # See https://gitlab.kitware.com/cmake/cmake/-/issues/21959 - cmake_policy(SET CMP0116 NEW) - set(relative_to_dir ${CMAKE_CURRENT_BINARY_DIR}) - else() - set(relative_to_dir ${CMAKE_BINARY_DIR}) - endif() - set(dependency_file_cpp "${target_binary_dir}/qmltypes/${type_registration_cpp_file_name}.d") - set(registration_cpp_file_dep_args DEPFILE ${dependency_file_cpp}) - file(RELATIVE_PATH cpp_file_name "${relative_to_dir}" "${type_registration_cpp_file}") - file(GENERATE OUTPUT "${dependency_file_cpp}" - CONTENT "${cpp_file_name}: $,\\\n$, \\\n>" - ) - endif() - add_custom_command( OUTPUT ${type_registration_cpp_file} @@ -1601,11 +1849,39 @@ function(qt6_qml_type_registration target) ${CMAKE_COMMAND} -E make_directory "${generated_marker_dir}" COMMAND ${CMAKE_COMMAND} -E touch "${generated_marker_file}" - ${registration_cpp_file_dep_args} COMMENT "Automatic QML type registration for target ${target}" ) - cmake_policy(POP) + # The ${target}_qmllint targets need to depend on the generation of all + # *.qmltypes files in the build. We have no way of reliably working out + # which QML modules a given target depends on at configure time, so we + # have to be conservative and make ${target}_qmllint targets depend on all + # *.qmltypes files. We need to provide a target for those dependencies + # here. Note that we can't use ${target} itself for those dependencies + # because the user might want to run qmllint without having to build the + # QML module. + add_custom_target(${target}_qmltyperegistration + DEPENDS + ${type_registration_cpp_file} + ${plugin_types_file} + ) + if(NOT TARGET all_qmltyperegistrations) + add_custom_target(all_qmltyperegistrations) + endif() + add_dependencies(all_qmltyperegistrations ${target}_qmltyperegistration) + + # Both ${target} (via target_sources) and ${target}_qmltyperegistration (via add_custom_target + # DEPENDS option) depend on ${type_registration_cpp_file}. + # The new Xcode build system requires a common target to drive the generation of files, + # otherwise project configuration fails. + # Make ${target} the common target, by adding it as a dependency for + # ${target}_qmltyperegistration. + # The consequence is that the ${target}_qmllint target will now first build ${target} when using + # the Xcode generator (mostly only relevant for projects using Qt for iOS). + # See QTBUG-95763. + if(CMAKE_GENERATOR STREQUAL "Xcode") + add_dependencies(${target}_qmltyperegistration ${target}) + endif() target_sources(${target} PRIVATE ${type_registration_cpp_file}) @@ -1630,15 +1906,35 @@ function(qt6_qml_type_registration target) SKIP_AUTOGEN ON ${additional_source_files_properties} ) + if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.18") + set_source_files_properties( + ${type_registration_cpp_file} + TARGET_DIRECTORY ${target} + PROPERTIES + SKIP_AUTOGEN TRUE + GENERATED TRUE + ${additional_source_files_properties} + ) + endif() target_include_directories(${target} PRIVATE $ ) endfunction() +function(qt6_qml_type_registration) + message(FATAL_ERROR + "This function, previously available under Technical Preview, has been removed. " + "Please use qt6_add_qml_module() instead." + ) +endfunction() + if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) function(qt_qml_type_registration) - qt6_qml_type_registration(${ARGV}) + message(FATAL_ERROR + "This function, previously available under Technical Preview, has been removed. " + "Please use qt_add_qml_module() instead." + ) endfunction() endif() @@ -1659,7 +1955,7 @@ function(qt6_import_qml_plugins target) set_target_properties(${target} PROPERTIES _QT_QML_PLUGINS_IMPORTED TRUE) set(options) - set(oneValueArgs "PATH_TO_SCAN") + set(oneValueArgs "PATH_TO_SCAN") # Internal option, may be removed set(multiValueArgs) cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -1692,10 +1988,24 @@ but this file does not exist. Possible reasons include: ") endif() - # Find location of qml dir. - # TODO: qt.prf implies that there might be more than one qml import path to - # pass to qmlimportscanner. - set(qml_path "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_QML}") + # Find Qt provided QML import paths. + if("${_qt_additional_packages_prefix_paths}" STREQUAL "") + # We have one installation prefix for all Qt modules. Add the "/qml" directory. + set(qml_import_paths "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_QML}") + else() + # We have multiple installation prefixes: one per Qt repository (conan). Add those that have + # a "qml" subdirectory. + set(qml_import_paths) + __qt_internal_prefix_paths_to_roots( + additional_root_paths "${_qt_additional_packages_prefix_paths}") + foreach(root IN ITEMS ${QT6_INSTALL_PREFIX} ${additional_root_paths}) + set(candidate "${root}/${QT6_INSTALL_QML}") + if(IS_DIRECTORY "${candidate}") + list(APPEND qml_import_paths "${candidate}") + endif() + endforeach() + endif() + # Small macro to avoid duplicating code in two different loops. macro(_qt6_QmlImportScanner_parse_entry) @@ -1704,7 +2014,8 @@ but this file does not exist. Possible reasons include: set(entry_name "qml_import_scanner_import_${idx}") cmake_parse_arguments("entry" "" - "CLASSNAME;NAME;PATH;PLUGIN;RELATIVEPATH;TYPE;VERSION;" "" + "CLASSNAME;NAME;PATH;PLUGIN;RELATIVEPATH;TYPE;VERSION;LINKTARGET" + "" ${${entry_name}} ) endmacro() @@ -1716,20 +2027,41 @@ but this file does not exist. Possible reasons include: file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/.qt_plugins) set(cmd_args - "${arg_PATH_TO_SCAN}" + -rootPath "${arg_PATH_TO_SCAN}" -cmake-output - -importPath "${qml_path}" ) get_target_property(qml_import_path ${target} QT_QML_IMPORT_PATH) - if (qml_import_path) - list(APPEND cmd_args ${qml_import_path}) + if(qml_import_path) + list(APPEND qml_import_paths ${qml_import_path}) endif() - get_target_property(qml_files ${target} QT_QML_MODULE_FILES) - if (qml_files) - list(APPEND cmd_args "-qmlFiles" ${qml_files}) + # Facilitate self-import so we can find the qmldir file + get_target_property(module_out_dir ${target} QT_QML_MODULE_OUTPUT_DIRECTORY) + if(module_out_dir) + list(APPEND qml_import_paths "${module_out_dir}") + endif() + + # Find qmldir files we copied to the build directory + if(NOT "${QT_QML_OUTPUT_DIRECTORY}" STREQUAL "") + if(EXISTS "${QT_QML_OUTPUT_DIRECTORY}") + list(APPEND qml_import_paths "${QT_QML_OUTPUT_DIRECTORY}") + endif() + else() + list(APPEND qml_import_paths "${CMAKE_CURRENT_BINARY_DIR}") endif() + # Construct the -importPath arguments. + set(import_path_arguments) + foreach(path IN LISTS qml_import_paths) + list(APPEND import_path_arguments -importPath ${path}) + endforeach() + + list(APPEND cmd_args ${import_path_arguments}) + + # All of the module's .qml files will be listed in one of the generated + # .qrc files, so there's no need to list the files individually. We provide + # the .qrc files instead because they have the additional information for + # each file's resource alias. get_target_property(qrc_files ${target} _qt_generated_qrc_files) if (qrc_files) list(APPEND cmd_args "-qrcFiles" ${qrc_files}) @@ -1748,7 +2080,10 @@ but this file does not exist. Possible reasons include: get_target_property(target_source_dir ${target} SOURCE_DIR) message(VERBOSE "Running qmlimportscanner to find QML plugins needed by ${target}.") - execute_process(COMMAND ${QT_TOOL_COMMAND_WRAPPER_PATH} ${tool_path} ${cmd_args} + set(import_scanner_args ${QT_TOOL_COMMAND_WRAPPER_PATH} ${tool_path} ${cmd_args}) + list(JOIN import_scanner_args " " import_scanner_args_string) + message(DEBUG "qmlimportscanner command: ${import_scanner_args_string}") + execute_process(COMMAND ${import_scanner_args} OUTPUT_FILE "${qml_imports_file_path}" WORKING_DIRECTORY ${target_source_dir} ) @@ -1765,6 +2100,9 @@ but this file does not exist. Possible reasons include: # It is possible for the scanner to find no usage of QML, in which case the import count is 0. if(qml_import_scanner_imports_count) set(added_plugins "") + set(plugins_to_link "") + set(plugin_inits_to_link "") + foreach(idx RANGE "${qml_import_scanner_imports_count}") _qt6_QmlImportScanner_parse_entry() if(entry_PATH AND entry_PLUGIN) @@ -1775,73 +2113,50 @@ but this file does not exist. Possible reasons include: continue() endif() list(APPEND added_plugins "${entry_PLUGIN}") - # Link against the Qml plugin. For plugins provided by Qt, we - # assume those plugins are already defined (typically brought in - # via find_package(Qt6...) ). For other plugins, they can be - # from the project itself or some other external place. - if(TARGET "${QT_CMAKE_EXPORT_NAMESPACE}::${entry_PLUGIN}") - set(plugin_dep "${QT_CMAKE_EXPORT_NAMESPACE}::${entry_PLUGIN}") - elseif(TARGET ${entry_PLUGIN}) - set(plugin_dep ${entry_PLUGIN}) - else() - # We've been told where the plugin should be, but only have - # its basename. Let CMake work out the prefix and suffix. - find_library(${entry_PLUGIN}_LIBRARY ${entry_PLUGIN} - PATHS ${entry_PATH} - NO_DEFAULT_PATH - ) - if(${entry_PLUGIN}_LIBRARY) - set(plugin_dep ${${entry_PLUGIN}_LIBRARY}) - else() - message(FATAL_ERROR - "${entry_PLUGIN} is a dependency of ${target}, but " - "there is no target by that name and no library with " - "that name could be found at the expected location (" - ${entry_PATH} "). Consider making an imported target " - "for it so that its location is known." - ) - endif() - endif() - target_link_libraries("${target}" PRIVATE ${plugin_dep}) - endif() - endforeach() - # Generate content for plugin initialization cpp file. - set(added_imports "") - set(qt_qml_import_cpp_file_content "") - foreach(idx RANGE "${qml_import_scanner_imports_count}") - _qt6_QmlImportScanner_parse_entry() - if(entry_PLUGIN) - if(entry_CLASSNAME) - list(FIND added_imports "${entry_PLUGIN}" _index) - if(_index EQUAL -1) - string(APPEND qt_qml_import_cpp_file_content - "Q_IMPORT_PLUGIN(${entry_CLASSNAME})\n" + # Link against the Qml plugin. + # For plugins provided by Qt, we assume those plugin targets are already defined + # (typically brought in via find_package(Qt6...) ). + # For other plugins, the targets can come from the project itself. + # + if(entry_LINKTARGET) + if(TARGET ${entry_LINKTARGET}) + list(APPEND plugins_to_link "${entry_LINKTARGET}") + else() + message(WARNING + "The qml plugin '${entry_PLUGIN}' is a dependency of '${target}', " + "but the link target it defines (${entry_LINKTARGET}) does not exist " + "in the current scope. The plugin will not be linked." ) - list(APPEND added_imports "${entry_PLUGIN}") endif() + elseif(TARGET ${entry_PLUGIN}) + list(APPEND plugins_to_link "${entry_PLUGIN}") else() - # If the qmldir file was generated by us, there should have - # been a CLASS_NAME automatically computed if one wasn't - # provided. Therefore, it is likely that this is a manually - # prepared qmldir and it is missing a classname entry. - message(FATAL_ERROR - "Plugin ${entry_PLUGIN} is missing a classname entry, " - "please add one to the qmldir file." + # TODO: QTBUG-94605 Figure out if this is a reasonable scenario to support + message(WARNING + "The qml plugin '${entry_PLUGIN}' is a dependency of '${target}', " + "but there is no target by that name in the current scope. The plugin will " + "not be linked." ) endif() endif() endforeach() - # Write to the generated file, and include it as a source for the given target. - set(generated_import_cpp_path - "${CMAKE_CURRENT_BINARY_DIR}/.qt_plugins/Qt6_QmlPlugins_Imports_${target}.cpp" - ) - configure_file("${Qt6Qml_DIR}/Qt6QmlImportScannerTemplate.cpp.in" - "${generated_import_cpp_path}" - @ONLY - ) - target_sources(${target} PRIVATE "${generated_import_cpp_path}") + if(plugins_to_link) + # If ${target} is an executable or a shared library, link the plugins directly to + # the target. + # If ${target} is a static or INTERFACE library, the plugins should be propagated + # across those libraries to the end target (executable or shared library). + # The plugin initializers will be linked via usage requirements from the plugin target. + get_target_property(target_type ${target} TYPE) + if(target_type STREQUAL "EXECUTABLE" OR target_type STREQUAL "SHARED_LIBRARY" + OR target_type STREQUAL "MODULE_LIBRARY") + set(link_type "PRIVATE") + else() + set(link_type "INTERFACE") + endif() + target_link_libraries("${target}" ${link_type} ${plugins_to_link}) + endif() endif() endfunction() @@ -1854,3 +2169,188 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) endif() endfunction() endif() + +function(_qt_internal_add_static_qml_plugin_dependencies plugin_target backing_target) + # Protect against multiple calls of qt_add_qml_plugin. + get_target_property(plugin_deps_added "${plugin_target}" _qt_extra_static_qml_plugin_deps_added) + if(plugin_deps_added) + return() + endif() + set_target_properties("${plugin_target}" PROPERTIES _qt_extra_static_qml_plugin_deps_added TRUE) + + # Get the install plugin target name, which we will need for filtering later on. + if(TARGET "${backing_target}") + get_target_property(installed_plugin_target + "${backing_target}" _qt_qml_module_installed_plugin_target) + endif() + + if(NOT backing_target STREQUAL plugin_target AND TARGET "${backing_target}") + set(has_backing_lib TRUE) + else() + set(has_backing_lib FALSE) + endif() + + get_target_property(plugin_type ${plugin_target} TYPE) + set(skip_prl_marker "$") + + # If ${plugin_target} is a static qml plugin, recursively get its private dependencies (and its + # backing lib private deps), identify which of those are qml modules, extract any associated qml + # plugin target from those qml modules and make them dependencies of ${plugin_target}. + # + # E.g. this ensures that if a user project links directly to the static qtquick2plugin plugin + # target (note the plugin target, not the backing lib) it will automatically also link to + # Quick's transitive plugin dependencies: qmlplugin, modelsplugin and workerscriptplugin, in + # addition to the the Qml, QmlModels and QmlWorkerScript backing libraries. + # + # Note this logic is not specific to qtquick2plugin, it applies to all static qml plugins. + # + # This eliminates the needed boilerplate to link to the full transitive closure of qml plugins + # in user projects that don't want to use qmlimportscanner / qt_import_qml_plugins. + set(additional_plugin_deps "") + + if(plugin_type STREQUAL "STATIC_LIBRARY") + set(all_private_deps "") + + # We walk both plugin_target and backing_lib private deps because they can have differing + # dependencies and we want to consider all of them. + __qt_internal_collect_all_target_dependencies( + "${plugin_target}" plugin_private_deps) + if(plugin_private_deps) + list(APPEND all_private_deps ${plugin_private_deps}) + endif() + + if(has_backing_lib) + __qt_internal_collect_all_target_dependencies( + "${backing_target}" backing_lib_private_deps) + if(backing_lib_private_deps) + list(APPEND all_private_deps ${backing_lib_private_deps}) + endif() + endif() + + foreach(dep IN LISTS all_private_deps) + if(NOT TARGET "${dep}") + continue() + endif() + get_target_property(dep_type ${dep} TYPE) + if(dep_type STREQUAL "STATIC_LIBRARY") + set(associated_qml_plugin "") + + # Check if the target has an associated imported qml plugin (like a Qt-provided + # one). + get_target_property(associated_qml_plugin_candidate ${dep} + _qt_qml_module_installed_plugin_target) + + if(associated_qml_plugin_candidate AND TARGET "${associated_qml_plugin_candidate}") + set(associated_qml_plugin "${associated_qml_plugin_candidate}") + endif() + + # Check if the target has an associated qml plugin that's built as part of the + # current project (non-installed one, so without a target namespace prefix). + get_target_property(associated_qml_plugin_candidate ${dep} + _qt_qml_module_plugin_target) + + if(NOT associated_qml_plugin AND + associated_qml_plugin_candidate + AND TARGET "${associated_qml_plugin_candidate}") + set(associated_qml_plugin "${associated_qml_plugin_candidate}") + endif() + + # We need to filter out adding the plugin_target as a dependency to itself, + # when walking the backing lib of the plugin_target. + if(associated_qml_plugin + AND NOT associated_qml_plugin STREQUAL plugin_target + AND NOT associated_qml_plugin STREQUAL installed_plugin_target) + # Abuse a genex marker, to skip the dependency to be added into prl files. + # TODO: Introduce a more generic marker name in qtbase specifically + # for skipping deps in prl file deps generation. + set(wrapped_associated_qml_plugin + "$<${skip_prl_marker}:$>") + + if(NOT wrapped_associated_qml_plugin IN_LIST additional_plugin_deps) + list(APPEND additional_plugin_deps "${wrapped_associated_qml_plugin}") + endif() + endif() + endif() + endforeach() + endif() + + if(additional_plugin_deps) + target_link_libraries(${plugin_target} PRIVATE ${additional_plugin_deps}) + endif() +endfunction() + +# The function returns the output name of a qml plugin that will be used as library output +# name and in a qmldir file as the 'plugin ' record. +function(_qt_internal_get_qml_plugin_output_name out_var plugin_target) + cmake_parse_arguments(arg + "" + "BACKING_TARGET;TARGET_PATH;URI" + "" + ${ARGN} + ) + set(plugin_name) + if(TARGET ${plugin_target}) + get_target_property(plugin_name ${plugin_target} OUTPUT_NAME) + endif() + if(NOT plugin_name) + set(plugin_name "${plugin_target}") + endif() + + if(ANDROID) + # In Android all plugins are stored in directly the /libs directory. This means that plugin + # names must be unique in scope of apk. To make this work we prepend uri-based prefix to + # each qml plugin in case if users don't use the manually written qmldir files. + get_target_property(no_generate_qmldir ${target} QT_QML_MODULE_NO_GENERATE_QMLDIR) + if(TARGET "${arg_BACKING_TARGET}") + get_target_property(no_generate_qmldir ${arg_BACKING_TARGET} + QT_QML_MODULE_NO_GENERATE_QMLDIR) + + # Adjust Qml plugin names on Android similar to qml_plugin.prf which calls + # $$qt5LibraryTarget($$TARGET, "qml/$$TARGETPATH/"). + # Example plugin names: + # qtdeclarative + # TARGET_PATH: QtQml/Models + # file name: libqml_QtQml_Models_modelsplugin_x86_64.so + # qtquickcontrols2 + # TARGET_PATH: QtQuick/Controls.2/Material + # file name: + # libqml_QtQuick_Controls.2_Material_qtquickcontrols2materialstyleplugin_x86_64.so + if(NOT arg_TARGET_PATH) + get_target_property(arg_TARGET_PATH ${arg_BACKING_TARGET} + QT_QML_MODULE_TARGET_PATH) + endif() + endif() + if(arg_TARGET_PATH) + string(REPLACE "/" "_" android_plugin_name_infix_name "${arg_TARGET_PATH}") + else() + string(REPLACE "." "_" android_plugin_name_infix_name "${arg_URI}") + endif() + + # If plugin supposed to use manually written qmldir file we don't prepend the uri-based + # prefix to the plugin output name. User should keep the file name of a QML plugin in + # qmldir the same as the name of plugin on a file system. Exception is the + # ABI-/platform-specific suffix that has the separate processing and should not be + # a part of plugin name in qmldir. + if(NOT no_generate_qmldir) + set(plugin_name + "qml_${android_plugin_name_infix_name}_${plugin_name}") + endif() + endif() + + set(${out_var} "${plugin_name}" PARENT_SCOPE) +endfunction() + +# Used to add extra dependencies between ${target} and ${dep_target} qml plugins in a static +# Qt build, without creating a dependency in the genereated qmake .prl files. +# These dependencies make manual linking to static plugins a nicer experience for users that don't +# want to use qt_import_qml_plugins. +function(_qt_internal_add_qml_static_plugin_dependency target dep_target) + if(NOT BUILD_SHARED_LIBS) + # Abuse a genex marker, to skip the dependency to be added into prl files. + # TODO: Introduce a more generic marker name in qtbase specifically + # for skipping deps in prl file deps generation. + set(skip_prl_marker "$") + target_link_libraries("${target}" PRIVATE + "$<${skip_prl_marker}:$>") + endif() +endfunction() diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp index 9e82b63771a..05cf786e7d7 100644 --- a/src/qml/animations/qabstractanimationjob.cpp +++ b/src/qml/animations/qabstractanimationjob.cpp @@ -44,6 +44,7 @@ #include "private/qanimationjobutil_p.h" #include "private/qqmlengine_p.h" #include "private/qqmlglobal_p.h" +#include "private/qdoubleendedlist_p.h" QT_BEGIN_NAMESPACE @@ -65,6 +66,32 @@ QQmlAnimationTimer::QQmlAnimationTimer() : { } +void QQmlAnimationTimer::unsetJobTimer(QAbstractAnimationJob *animation) +{ + if (!animation) + return; + if (animation->m_timer == this) + animation->m_timer = nullptr; + + if (animation->isGroup()) { + QAnimationGroupJob *group = static_cast(animation); + if (const auto children = group->children()) { + for (auto *child : *children) + unsetJobTimer(child); + } + } +} + +QQmlAnimationTimer::~QQmlAnimationTimer() +{ + for (const auto &animation : qAsConst(animations)) + unsetJobTimer(animation); + for (const auto &animation : qAsConst(animationsToStart)) + unsetJobTimer(animation); + for (const auto &animation : qAsConst(runningPauseAnimations)) + unsetJobTimer(animation); +} + QQmlAnimationTimer *QQmlAnimationTimer::instance(bool create) { QQmlAnimationTimer *inst; @@ -216,6 +243,7 @@ void QQmlAnimationTimer::registerRunningAnimation(QAbstractAnimationJob *animati void QQmlAnimationTimer::unregisterRunningAnimation(QAbstractAnimationJob *animation) { + unsetJobTimer(animation); if (animation->userControlDisabled()) return; @@ -280,8 +308,10 @@ QAbstractAnimationJob::~QAbstractAnimationJob() Q_ASSERT(m_state == Stopped); if (oldState == Running) { - Q_ASSERT(QQmlAnimationTimer::instance() == m_timer); - m_timer->unregisterAnimation(this); + if (m_timer) { + Q_ASSERT(QQmlAnimationTimer::instance(false) == m_timer); + m_timer->unregisterAnimation(this); + } } Q_ASSERT(!m_hasRegisteredTimer); } @@ -306,8 +336,9 @@ void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState) if (m_loopCount == 0) return; - if (!m_timer) - m_timer = QQmlAnimationTimer::instance(); + if (!m_timer) // don't create a timer just to stop the animation + m_timer = QQmlAnimationTimer::instance(newState != Stopped); + Q_ASSERT(m_timer || newState == Stopped); State oldState = m_state; int oldCurrentTime = m_currentTime; @@ -335,8 +366,9 @@ void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState) if (oldState == Running) { if (newState == Paused && m_hasRegisteredTimer) m_timer->ensureTimerUpdate(); - //the animation, is not running any more - m_timer->unregisterAnimation(this); + // the animation is not running any more + if (m_timer) + m_timer->unregisterAnimation(this); } else if (newState == Running) { m_timer->registerAnimation(this, isTopLevel); } @@ -521,6 +553,14 @@ void QAbstractAnimationJob::stop() setState(Stopped); } +void QAbstractAnimationJob::complete() +{ + // Simulate the full animation cycle + setState(Running); + setCurrentTime(m_direction == Forward ? duration() : 0); + setState(Stopped); +} + void QAbstractAnimationJob::pause() { if (m_state == Stopped) { diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h index c7514f45832..dd978c93d01 100644 --- a/src/qml/animations/qabstractanimationjob_p.h +++ b/src/qml/animations/qabstractanimationjob_p.h @@ -114,6 +114,7 @@ class Q_QML_PRIVATE_EXPORT QAbstractAnimationJob : public QInheritedListNode void pause(); void resume(); void stop(); + void complete(); enum ChangeType { Completion = 0x01, @@ -204,6 +205,8 @@ class Q_QML_PRIVATE_EXPORT QQmlAnimationTimer : public QAbstractAnimationTimer QQmlAnimationTimer(); public: + ~QQmlAnimationTimer(); // must be destructible by QThreadStorage + static QQmlAnimationTimer *instance(); static QQmlAnimationTimer *instance(bool create); @@ -249,6 +252,7 @@ public Q_SLOTS: void registerRunningAnimation(QAbstractAnimationJob *animation); void unregisterRunningAnimation(QAbstractAnimationJob *animation); + void unsetJobTimer(QAbstractAnimationJob *animation); int closestPauseAnimationTimeToFinish(); }; diff --git a/src/qml/animations/qcontinuinganimationgroupjob.cpp b/src/qml/animations/qcontinuinganimationgroupjob.cpp index 7d24d8ce55b..6d2dc38bfd1 100644 --- a/src/qml/animations/qcontinuinganimationgroupjob.cpp +++ b/src/qml/animations/qcontinuinganimationgroupjob.cpp @@ -81,9 +81,9 @@ void QContinuingAnimationGroupJob::updateState(QAbstractAnimationJob::State newS return; } for (QAbstractAnimationJob *animation : m_children) { - resetUncontrolledAnimationFinishTime(animation); + RETURN_IF_DELETED(resetUncontrolledAnimationFinishTime(animation)); animation->setDirection(m_direction); - animation->start(); + RETURN_IF_DELETED(animation->start()); } break; } diff --git a/src/qml/animations/qparallelanimationgroupjob.cpp b/src/qml/animations/qparallelanimationgroupjob.cpp index 4da4a06af20..0d67b2451ea 100644 --- a/src/qml/animations/qparallelanimationgroupjob.cpp +++ b/src/qml/animations/qparallelanimationgroupjob.cpp @@ -144,10 +144,10 @@ void QParallelAnimationGroupJob::updateState(QAbstractAnimationJob::State newSta animation->stop(); m_previousLoop = m_direction == Forward ? 0 : m_loopCount - 1; } - resetUncontrolledAnimationFinishTime(animation); + RETURN_IF_DELETED(resetUncontrolledAnimationFinishTime(animation)); animation->setDirection(m_direction); if (shouldAnimationStart(animation, oldState == Stopped)) - animation->start(); + RETURN_IF_DELETED(animation->start()); } break; } diff --git a/src/qml/common/qjsnumbercoercion.h b/src/qml/common/qjsnumbercoercion.h index 51dbe6beb55..2517442bb60 100644 --- a/src/qml/common/qjsnumbercoercion.h +++ b/src/qml/common/qjsnumbercoercion.h @@ -49,9 +49,13 @@ class QJSNumberCoercion { public: static constexpr int toInteger(double d) { - int i = static_cast(d); + if (!equals(d, d)) + return 0; + + const int i = static_cast(d); if (equals(i, d)) return i; + return QJSNumberCoercion(d).toInteger(); } diff --git a/src/qml/common/qqmljsfixedpoolarray_p.h b/src/qml/common/qqmljsfixedpoolarray_p.h index b65b994d6c7..15a8cd6878d 100644 --- a/src/qml/common/qqmljsfixedpoolarray_p.h +++ b/src/qml/common/qqmljsfixedpoolarray_p.h @@ -86,7 +86,7 @@ class FixedPoolArray if (QTypeInfo::isComplex) { for (int i = 0; i < count; ++i) new (data + i) T(vector.at(i)); - } else { + } else if (count) { memcpy(data, static_cast(vector.constData()), count * sizeof(T)); } } diff --git a/src/qml/common/qqmljsmemorypool_p.h b/src/qml/common/qqmljsmemorypool_p.h index dcf3fafb671..2a1dc431100 100644 --- a/src/qml/common/qqmljsmemorypool_p.h +++ b/src/qml/common/qqmljsmemorypool_p.h @@ -81,13 +81,12 @@ class MemoryPool : public QSharedData free(_blocks); } - qDeleteAll(strings); } inline void *allocate(size_t size) { size = (size + 7) & ~size_t(7); - if (Q_LIKELY(_ptr && (_ptr + size < _end))) { + if (Q_LIKELY(_ptr && size < size_t(_end - _ptr))) { void *addr = _ptr; _ptr += size; return addr; @@ -105,9 +104,8 @@ class MemoryPool : public QSharedData template Tp *New(Ta... args) { return new (this->allocate(sizeof(Tp))) Tp(args...); } - QStringView newString(const QString &string) { - strings.append(new QString(string)); - return QStringView(*strings.last()); + QStringView newString(QString string) { + return strings.emplace_back(std::move(string)); } private: @@ -151,7 +149,7 @@ class MemoryPool : public QSharedData int _blockCount = -1; char *_ptr = nullptr; char *_end = nullptr; - QVector strings; + QStringList strings; enum { diff --git a/src/qml/common/qv4alloca_p.h b/src/qml/common/qv4alloca_p.h index 65c3e4d65ab..b42f74a67b8 100644 --- a/src/qml/common/qv4alloca_p.h +++ b/src/qml/common/qv4alloca_p.h @@ -100,8 +100,10 @@ QT_END_NAMESPACE type *name = nullptr #define Q_ALLOCA_ASSIGN(type, name, size) \ - _qt_alloca_##name.allocate(size); \ - name = static_cast(_qt_alloca_##name.data()) + do { \ + _qt_alloca_##name.allocate(size); \ + name = static_cast(_qt_alloca_##name.data()); \ + } while (false) #endif diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index 00a1890bf6e..9453120eb67 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -79,7 +79,11 @@ QT_BEGIN_NAMESPACE // Also change the comment behind the number to describe the latest change. This has the added // benefit that if another patch changes the version too, it will result in a merge conflict, and // not get removed silently. -#define QV4_DATA_STRUCTURE_VERSION 0x33 // added new bytecode instruction for type assertions + +// Note: We got two different versions 0x36 now, one with builtin value types and one without. +// However, the one without is exclusive to Qt 6.4+ and the compiled data cannot be preserved +// across Qt versions. Therefore, this is fine. +#define QV4_DATA_STRUCTURE_VERSION 0x36 // reordered runtime functions when compiling at run time class QIODevice; class QQmlTypeNameCache; @@ -128,33 +132,45 @@ struct TableIterator struct Location { - union { - quint32 _dummy; - quint32_le_bitfield<0, 20> line; - quint32_le_bitfield<20, 12> column; - }; - - Location() : _dummy(0) { } - Location(quint32 l, quint32 c) - : Location() + Location() : m_data(QSpecialIntegerBitfieldZero) {} + Location(quint32 l, quint32 c) : Location() { - line = l; - column = c; - Q_ASSERT(line == l); - Q_ASSERT(column == c); + m_data.set(l); + m_data.set(c); + Q_ASSERT(m_data.get() == l); + Q_ASSERT(m_data.get() == c); } inline bool operator<(const Location &other) const { - return line < other.line || - (line == other.line && column < other.column); + return m_data.get() < other.m_data.get() + || (m_data.get() == other.m_data.get() + && m_data.get() < other.m_data.get()); } friend size_t qHash(const Location &location, size_t seed = 0) { - return QT_PREPEND_NAMESPACE(qHash)(location._dummy, seed); + return QT_PREPEND_NAMESPACE(qHash)(location.m_data.data(), seed); + } + + friend bool operator==(const Location &a, const Location &b) + { + return a.m_data.data()== b.m_data.data(); + } + + void set(quint32 line, quint32 column) + { + m_data.set(line); + m_data.set(column); } - friend bool operator==(const Location &a, const Location &b) { return a._dummy == b._dummy; } + quint32 line() const { return m_data.get(); } + quint32 column() const { return m_data.get(); } + +private: + using LineField = quint32_le_bitfield_member<0, 20>; + using ColumnField = quint32_le_bitfield_member<20, 12>; + + quint32_le_bitfield_union m_data; }; static_assert(sizeof(Location) == 4, "Location structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); @@ -168,13 +184,21 @@ struct RegExp RegExp_Unicode = 0x08, RegExp_Sticky = 0x10 }; - union { - quint32 _dummy; - quint32_le_bitfield<0, 5> flags; - quint32_le_bitfield<5, 27> stringIndex; - }; - RegExp() : _dummy(0) { } + RegExp() : m_data(QSpecialIntegerBitfieldZero) {} + RegExp(quint32 flags, quint32 stringIndex) : RegExp() + { + m_data.set(flags); + m_data.set(stringIndex); + } + + quint32 flags() const { return m_data.get(); } + quint32 stringIndex() const { return m_data.get(); } + +private: + using FlagsField = quint32_le_bitfield_member<0, 5>; + using StringIndexField = quint32_le_bitfield_member<5, 27>; + quint32_le_bitfield_union m_data; }; static_assert(sizeof(RegExp) == 4, "RegExp structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); @@ -187,25 +211,40 @@ struct Lookup Type_QmlContextPropertyGetter = 3 }; - union { - quint32 _dummy; - quint32_le_bitfield<0, 4> type_and_flags; - quint32_le_bitfield<4, 28> nameIndex; - }; + quint32 typeAndFlags() const { return m_data.get(); } + quint32 nameIndex() const { return m_data.get(); } + + Lookup() : m_data(QSpecialIntegerBitfieldZero) {} + Lookup(Type type, quint32 nameIndex) : Lookup() + { + m_data.set(type); + m_data.set(nameIndex); + } - Lookup() : _dummy(0) { } +private: + using TypeAndFlagsField = quint32_le_bitfield_member<0, 4>; + using NameIndexField = quint32_le_bitfield_member<4, 28>; + quint32_le_bitfield_union m_data; }; static_assert(sizeof(Lookup) == 4, "Lookup structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); struct JSClassMember { - union { - quint32 _dummy; - quint32_le_bitfield<0, 31> nameOffset; - quint32_le_bitfield<31, 1> isAccessor; - }; + JSClassMember() : m_data(QSpecialIntegerBitfieldZero) {} - JSClassMember() : _dummy(0) { } + void set(quint32 nameOffset, bool isAccessor) + { + m_data.set(nameOffset); + m_data.set(isAccessor ? 1 : 0); + } + + quint32 nameOffset() const { return m_data.get(); } + bool isAccessor() const { return m_data.get() != 0; } + +private: + using NameOffsetField = quint32_le_bitfield_member<0, 31>; + using IsAccessorField = quint32_le_bitfield_member<31, 1>; + quint32_le_bitfield_union m_data; }; static_assert(sizeof(JSClassMember) == 4, "JSClassMember structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); @@ -265,11 +304,26 @@ enum class BuiltinType : unsigned int { struct ParameterType { - union { - quint32 _dummy; - quint32_le_bitfield<0, 1> indexIsBuiltinType; - quint32_le_bitfield<1, 31> typeNameIndexOrBuiltinType; - }; + void set(bool indexIsBuiltinType, quint32 typeNameIndexOrBuiltinType) + { + m_data.set(indexIsBuiltinType ? 1 : 0); + m_data.set(typeNameIndexOrBuiltinType); + } + + bool indexIsBuiltinType() const + { + return m_data.get() != 0; + } + + quint32 typeNameIndexOrBuiltinType() const + { + return m_data.get(); + } + +private: + using IndexIsBuiltinTypeField = quint32_le_bitfield_member<0, 1>; + using TypeNameIndexOrBuiltinTypeField = quint32_le_bitfield_member<1, 31>; + quint32_le_bitfield_union m_data; }; static_assert(sizeof(ParameterType) == 4, "ParameterType structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); @@ -287,7 +341,8 @@ struct Function enum Flags : unsigned int { IsStrict = 0x1, IsArrowFunction = 0x2, - IsGenerator = 0x4 + IsGenerator = 0x4, + IsClosureWrapper = 0x8, }; // Absolute offset into file where the code for this function is located. @@ -448,7 +503,7 @@ struct Binding { quint32_le propertyNameIndex; - enum ValueType : unsigned int { + enum Type : unsigned int { Type_Invalid, Type_Boolean, Type_Number, @@ -462,7 +517,7 @@ struct Binding Type_GroupProperty }; - enum Flags : unsigned int { + enum Flag : unsigned int { IsSignalHandlerExpression = 0x1, IsSignalHandlerObject = 0x2, IsOnAssignment = 0x4, @@ -475,11 +530,20 @@ struct Binding IsFunctionExpression = 0x200, IsPropertyObserver = 0x400 }; + Q_DECLARE_FLAGS(Flags, Flag); + + using FlagsField = quint32_le_bitfield_member<0, 16>; + using TypeField = quint32_le_bitfield_member<16, 16>; + quint32_le_bitfield_union flagsAndType; + + void clearFlags() { flagsAndType.set(0); } + void setFlag(Flag flag) { flagsAndType.set(flagsAndType.get() | flag); } + bool hasFlag(Flag flag) const { return Flags(flagsAndType.get()) & flag; } + Flags flags() const { return Flags(flagsAndType.get()); } + + void setType(Type type) { flagsAndType.set(type); } + Type type() const { return Type(flagsAndType.get()); } - union { - quint32_le_bitfield<0, 16> flags; - quint32_le_bitfield<16, 16> type; - }; union { bool b; quint32_le constantValueIndex; @@ -493,24 +557,31 @@ struct Binding Location location; Location valueLocation; + bool hasSignalHandlerBindingFlag() const + { + const Flags bindingFlags = flags(); + return bindingFlags & IsSignalHandlerExpression + || bindingFlags & IsSignalHandlerObject + || bindingFlags & IsPropertyObserver; + } + bool isValueBinding() const { - if (type == Type_AttachedProperty - || type == Type_GroupProperty) - return false; - if (flags & IsSignalHandlerExpression - || flags & IsSignalHandlerObject - || flags & IsPropertyObserver) + switch (type()) { + case Type_AttachedProperty: + case Type_GroupProperty: return false; - return true; + default: + return !hasSignalHandlerBindingFlag(); + } } - bool isValueBindingNoAlias() const { return isValueBinding() && !(flags & IsBindingToAlias); } - bool isValueBindingToAlias() const { return isValueBinding() && (flags & IsBindingToAlias); } + bool isValueBindingNoAlias() const { return isValueBinding() && !hasFlag(IsBindingToAlias); } + bool isValueBindingToAlias() const { return isValueBinding() && hasFlag(IsBindingToAlias); } bool isSignalHandler() const { - if (flags & IsSignalHandlerExpression || flags & IsSignalHandlerObject || flags & IsPropertyObserver) { + if (hasSignalHandlerBindingFlag()) { Q_ASSERT(!isValueBinding()); Q_ASSERT(!isAttachedProperty()); Q_ASSERT(!isGroupProperty()); @@ -521,7 +592,7 @@ struct Binding bool isAttachedProperty() const { - if (type == Type_AttachedProperty) { + if (type() == Type_AttachedProperty) { Q_ASSERT(!isValueBinding()); Q_ASSERT(!isSignalHandler()); Q_ASSERT(!isGroupProperty()); @@ -532,7 +603,7 @@ struct Binding bool isGroupProperty() const { - if (type == Type_GroupProperty) { + if (type() == Type_GroupProperty) { Q_ASSERT(!isValueBinding()); Q_ASSERT(!isSignalHandler()); Q_ASSERT(!isAttachedProperty()); @@ -541,7 +612,7 @@ struct Binding return false; } - bool isFunctionExpression() const { return (flags & IsFunctionExpression); } + bool isFunctionExpression() const { return hasFlag(IsFunctionExpression); } //reverse of Lexer::singleEscape() static QString escapedString(const QString &string) @@ -586,16 +657,19 @@ struct Binding return tmp; } - bool isTranslationBinding() const { return type == Type_Translation || type == Type_TranslationById; } - bool evaluatesToString() const { return type == Type_String || isTranslationBinding(); } + bool isTranslationBinding() const + { + const Binding::Type bindingType = type(); + return bindingType == Type_Translation || bindingType == Type_TranslationById; + } + bool evaluatesToString() const { return type() == Type_String || isTranslationBinding(); } bool valueAsBoolean() const { - if (type == Type_Boolean) + if (type() == Type_Boolean) return value.b; return false; } - }; static_assert(sizeof(Binding) == 24, "Binding structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); @@ -668,37 +742,57 @@ static_assert(sizeof(Signal) == 12, "Signal structure needs to have the expected struct Property { - quint32_le nameIndex; - union { - quint32_le_bitfield<0, 28> builtinTypeOrTypeNameIndex; - quint32_le_bitfield<28, 1> isRequired; - quint32_le_bitfield<29, 1> isBuiltinType; - quint32_le_bitfield<30, 1> isList; - quint32_le_bitfield<31, 1> isReadOnly; - }; +private: + using BuiltinTypeOrTypeNameIndexField = quint32_le_bitfield_member<0, 28>; + using IsRequiredField = quint32_le_bitfield_member<28, 1>; + using IsBuiltinTypeField = quint32_le_bitfield_member<29, 1>; + using IsListField = quint32_le_bitfield_member<30, 1>; + using IsReadOnlyField = quint32_le_bitfield_member<31, 1>; +public: + quint32_le nameIndex; + quint32_le_bitfield_union< + BuiltinTypeOrTypeNameIndexField, + IsRequiredField, + IsBuiltinTypeField, + IsListField, + IsReadOnlyField> data; Location location; void setBuiltinType(BuiltinType t) { - builtinTypeOrTypeNameIndex = static_cast(t); - isBuiltinType = true; + data.set(static_cast(t)); + data.set(true); } + BuiltinType builtinType() const { - if (isBuiltinType) - return static_cast(quint32(builtinTypeOrTypeNameIndex)); + if (data.get() != 0) + return BuiltinType(data.get()); return BuiltinType::InvalidBuiltin; } + void setCustomType(int nameIndex) { - builtinTypeOrTypeNameIndex = nameIndex; - isBuiltinType = false; + data.set(nameIndex); + data.set(false); } int customType() const { - return isBuiltinType ? -1 : builtinTypeOrTypeNameIndex; + return data.get() ? -1 : data.get(); } + + bool isBuiltinType() const { return data.get(); } + uint builtinTypeOrTypeNameIndex() const { return data.get(); } + + bool isList() const { return data.get(); } + void setIsList(bool isList) { data.set(isList); } + + bool isRequired() const { return data.get(); } + void setIsRequired(bool isRequired) { data.set(isRequired); } + + bool isReadOnly() const { return data.get(); } + void setIsReadOnly(bool isReadOnly) { data.set(isReadOnly); } }; static_assert(sizeof(Property) == 12, "Property structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); @@ -709,20 +803,31 @@ struct RequiredPropertyExtraData { static_assert (sizeof(RequiredPropertyExtraData) == 4, "RequiredPropertyExtraData structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); struct Alias { - enum Flags : unsigned int { +private: + using NameIndexField = quint32_le_bitfield_member<0, 29>; + using FlagsField = quint32_le_bitfield_member<29, 3>; + + // object id index (in QQmlContextData::idValues) + using TargetObjectIdField = quint32_le_bitfield_member<0, 31>; + using AliasToLocalAliasField = quint32_le_bitfield_member<31, 1>; + +public: + + enum Flag : unsigned int { IsReadOnly = 0x1, Resolved = 0x2, AliasPointsToPointerObject = 0x4 }; - union { - quint32_le_bitfield<0, 29> nameIndex; - quint32_le_bitfield<29, 3> flags; - }; + Q_DECLARE_FLAGS(Flags, Flag) + + quint32_le_bitfield_union nameIndexAndFlags; + union { quint32_le idIndex; // string index - quint32_le_bitfield<0, 31> targetObjectId; // object id index (in QQmlContextData::idValues) - quint32_le_bitfield<31, 1> aliasToLocalAlias; + quint32_le_bitfield_union + targetObjectIdAndAliasToLocalAlias; }; + union { quint32_le propertyNameIndex; // string index qint32_le encodedMetaPropertyIndex; @@ -731,16 +836,67 @@ struct Alias { Location location; Location referenceLocation; - bool isObjectAlias() const { - Q_ASSERT(flags & Resolved); + bool hasFlag(Flag flag) const + { + return nameIndexAndFlags.get() & flag; + } + + void setFlag(Flag flag) + { + nameIndexAndFlags.set(nameIndexAndFlags.get() | flag); + } + + void clearFlags() + { + nameIndexAndFlags.set(0); + } + + quint32 nameIndex() const + { + return nameIndexAndFlags.get(); + } + + void setNameIndex(quint32 nameIndex) + { + nameIndexAndFlags.set(nameIndex); + } + + bool isObjectAlias() const + { + Q_ASSERT(hasFlag(Resolved)); return encodedMetaPropertyIndex == -1; } + + bool isAliasToLocalAlias() const + { + return targetObjectIdAndAliasToLocalAlias.get(); + } + + void setIsAliasToLocalAlias(bool isAliasToLocalAlias) + { + targetObjectIdAndAliasToLocalAlias.set(isAliasToLocalAlias); + } + + quint32 targetObjectId() const + { + return targetObjectIdAndAliasToLocalAlias.get(); + } + + void setTargetObjectId(quint32 targetObjectId) + { + targetObjectIdAndAliasToLocalAlias.set(targetObjectId); + } }; static_assert(sizeof(Alias) == 20, "Alias structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); struct Object { - enum Flags : unsigned int { +private: + using FlagsField = quint32_le_bitfield_member<0, 15>; + using DefaultPropertyIsAliasField = quint32_le_bitfield_member<15, 1>; + using IdField = quint32_le_bitfield_member<16, 16, qint32>; +public: + enum Flag : unsigned int { NoFlag = 0x0, IsComponent = 0x1, // object was identified to be an explicit or implicit component boundary HasDeferredBindings = 0x2, // any of the bindings are deferred @@ -748,17 +904,15 @@ struct Object IsInlineComponentRoot = 0x8, InPartOfInlineComponent = 0x10 }; + Q_DECLARE_FLAGS(Flags, Flag); // Depending on the use, this may be the type name to instantiate before instantiating this // object. For grouped properties the type name will be empty and for attached properties // it will be the name of the attached type. quint32_le inheritedTypeNameIndex; quint32_le idNameIndex; - union { - quint32_le_bitfield<0, 15> flags; - quint32_le_bitfield<15, 1> defaultPropertyIsAlias; - qint32_le_bitfield<16, 16> id; - }; + quint32_le_bitfield_union + flagsAndDefaultPropertyIsAliasAndId; qint32_le indexOfDefaultPropertyOrAlias; // -1 means no default property declared in this object quint16_le nFunctions; quint16_le nProperties; @@ -787,6 +941,48 @@ struct Object // InlineComponent[] // RequiredPropertyExtraData[] + Flags flags() const + { + return Flags(flagsAndDefaultPropertyIsAliasAndId.get()); + } + + bool hasFlag(Flag flag) const + { + return flagsAndDefaultPropertyIsAliasAndId.get() & flag; + } + + void setFlag(Flag flag) + { + flagsAndDefaultPropertyIsAliasAndId.set( + flagsAndDefaultPropertyIsAliasAndId.get() | flag); + } + + void setFlags(Flags flags) + { + flagsAndDefaultPropertyIsAliasAndId.set(flags); + } + + bool hasAliasAsDefaultProperty() const + { + return flagsAndDefaultPropertyIsAliasAndId.get(); + } + + void setHasAliasAsDefaultProperty(bool defaultAlias) + { + flagsAndDefaultPropertyIsAliasAndId.set(defaultAlias); + } + + qint32 objectId() const + { + return flagsAndDefaultPropertyIsAliasAndId.get(); + } + + void setObjectId(qint32 id) + { + flagsAndDefaultPropertyIsAliasAndId.set(id); + } + + static int calculateSizeExcludingSignalsAndEnums(int nFunctions, int nProperties, int nAliases, int nEnums, int nSignals, int nBindings, int nNamedObjectsInComponent, int nInlineComponents, int nRequiredPropertyExtraData) { return ( sizeof(Object) @@ -1126,6 +1322,28 @@ struct TypeReferenceMap : QHash return *insert(nameIndex, loc); } + template + void collectFromFunctions(Iterator it, Iterator end) + { + for (; it != end; ++it) { + auto formal = it->formalsBegin(); + auto formalEnd = it->formalsEnd(); + for ( ; formal != formalEnd; ++formal) { + if (!formal->type.indexIsBuiltinType()) { + TypeReference &r + = this->add(formal->type.typeNameIndexOrBuiltinType(), it->location); + r.errorWhenNotFound = true; + } + } + + if (!it->returnType.indexIsBuiltinType()) { + TypeReference &r + = this->add(it->returnType.typeNameIndexOrBuiltinType(), it->location); + r.errorWhenNotFound = true; + } + } + } + template void collectFromObject(const CompiledObject *obj) { @@ -1138,8 +1356,8 @@ struct TypeReferenceMap : QHash auto prop = obj->propertiesBegin(); auto const propEnd = obj->propertiesEnd(); for ( ; prop != propEnd; ++prop) { - if (!prop->isBuiltinType) { - TypeReference &r = this->add(prop->builtinTypeOrTypeNameIndex, prop->location); + if (!prop->isBuiltinType()) { + TypeReference &r = this->add(prop->builtinTypeOrTypeNameIndex(), prop->location); r.errorWhenNotFound = true; } } @@ -1147,7 +1365,7 @@ struct TypeReferenceMap : QHash auto binding = obj->bindingsBegin(); auto const bindingEnd = obj->bindingsEnd(); for ( ; binding != bindingEnd; ++binding) { - if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) + if (binding->type() == QV4::CompiledData::Binding::Type_AttachedProperty) this->add(binding->propertyNameIndex, binding->location); } @@ -1157,13 +1375,6 @@ struct TypeReferenceMap : QHash this->add(ic->nameIndex, ic->location); } } - - template - void collectFromObjects(Iterator it, Iterator end) - { - for (; it != end; ++it) - collectFromObject(*it); - } }; using DependentTypesHasher = std::function; @@ -1329,7 +1540,7 @@ struct CompilationUnit : public CompilationUnitBase QString bindingValueAsString(const CompiledData::Binding *binding) const { using namespace CompiledData; - switch (binding->type) { + switch (binding->type()) { case Binding::Type_Script: case Binding::Type_String: return stringAt(binding->stringIndex); @@ -1352,14 +1563,14 @@ struct CompilationUnit : public CompilationUnitBase QString bindingValueAsScriptString(const CompiledData::Binding *binding) const { - return (binding->type == CompiledData::Binding::Type_String) + return (binding->type() == CompiledData::Binding::Type_String) ? CompiledData::Binding::escapedString(stringAt(binding->stringIndex)) : bindingValueAsString(binding); } double bindingValueAsNumber(const CompiledData::Binding *binding) const { - if (binding->type != CompiledData::Binding::Type_Number) + if (binding->type() != CompiledData::Binding::Type_Number) return 0.0; return constants[binding->value.constantValueIndex].doubleValue(); } @@ -1386,7 +1597,8 @@ class SaveableUnitPointer template bool saveToDisk(const std::function &writer) const { - auto cleanup = qScopeGuard([this]() { mutableFlags() ^= temporaryFlags; }); + const quint32_le oldFlags = mutableFlags(); + auto cleanup = qScopeGuard([this, oldFlags]() { mutableFlags() = oldFlags; }); mutableFlags() |= temporaryFlags; return writer(data(), size()); } diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index e2e9d154799..814a5e8c655 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -76,7 +76,7 @@ void Object::simplifyRequiredProperties() { for (auto it = this->propertiesBegin(); it != this->propertiesEnd(); ++it) { auto requiredIt = required.find(it->nameIndex); if (requiredIt != required.end()) { - it->isRequired = true; + it->setIsRequired(true); required.erase(requiredIt); } } @@ -106,20 +106,22 @@ bool Parameter::init(QV4::CompiledData::Parameter *param, const QV4::Compiler::J bool Parameter::initType(QV4::CompiledData::ParameterType *paramType, const QV4::Compiler::JSUnitGenerator *stringGenerator, int typeNameIndex) { - paramType->indexIsBuiltinType = false; - paramType->typeNameIndexOrBuiltinType = 0; const QString typeName = stringGenerator->stringForIndex(typeNameIndex); auto builtinType = stringToBuiltinType(typeName); if (builtinType == QV4::CompiledData::BuiltinType::InvalidBuiltin) { - if (typeName.isEmpty() || !typeName.at(0).isUpper()) + if (typeName.isEmpty() || typeName == QLatin1String("void")) { + paramType->set(true, quint32(builtinType)); return false; - paramType->indexIsBuiltinType = false; - paramType->typeNameIndexOrBuiltinType = typeNameIndex; + } else if (!typeName.at(0).isUpper()) { + paramType->set(false, 0); + return false; + } + Q_ASSERT(quint32(typeNameIndex) < (1u << 31)); + paramType->set(false, typeNameIndex); } else { - paramType->indexIsBuiltinType = true; - paramType->typeNameIndexOrBuiltinType = static_cast(builtinType); Q_ASSERT(quint32(builtinType) < (1u << 31)); + paramType->set(true, static_cast(builtinType)); } return true; } @@ -172,7 +174,7 @@ QV4::CompiledData::BuiltinType Parameter::stringToBuiltinType(const QString &typ void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QV4::CompiledData::Location &loc) { - Q_ASSERT(loc.line > 0 && loc.column > 0); + Q_ASSERT(loc.line() > 0 && loc.column() > 0); inheritedTypeNameIndex = typeNameIndex; location = loc; idNameIndex = idIndex; @@ -197,8 +199,8 @@ QString IRBuilder::sanityCheckFunctionNames(Object *obj, const QSet &il QSet functionNames; for (auto functionit = obj->functionsBegin(); functionit != obj->functionsEnd(); ++functionit) { Function *f = functionit.ptr; - errorLocation->startLine = f->location.line; - errorLocation->startColumn = f->location.column; + errorLocation->startLine = f->location.line(); + errorLocation->startColumn = f->location.column(); if (functionNames.contains(f->nameIndex)) return tr("Duplicate method name"); functionNames.insert(f->nameIndex); @@ -258,6 +260,10 @@ QString Object::appendProperty(Property *prop, const QString &propertyName, bool if (p->nameIndex == prop->nameIndex) return tr("Duplicate property name"); + for (Alias *a = target->aliases->first; a; a = a->next) + if (a->nameIndex() == prop->nameIndex) + return tr("Property duplicates alias name"); + if (propertyName.constData()->isUpper()) return tr("Property names cannot begin with an upper case letter"); @@ -278,12 +284,19 @@ QString Object::appendAlias(Alias *alias, const QString &aliasName, bool isDefau if (!target) target = this; - auto aliasWithSameName = std::find_if(target->aliases->begin(), target->aliases->end(), [&alias](const Alias &targetAlias){ - return targetAlias.nameIndex == alias->nameIndex; + const auto aliasWithSameName = std::find_if(target->aliases->begin(), target->aliases->end(), [&alias](const Alias &targetAlias){ + return targetAlias.nameIndex() == alias->nameIndex(); }); if (aliasWithSameName != target->aliases->end()) return tr("Duplicate alias name"); + const auto aliasSameAsProperty = std::find_if(target->properties->begin(), target->properties->end(), [&alias](const Property &targetProp){ + return targetProp.nameIndex == alias->nameIndex(); + }); + + if (aliasSameAsProperty != target->properties->end()) + return tr("Alias has same name as existing property"); + if (aliasName.constData()->isUpper()) return tr("Alias names cannot begin with an upper case letter"); @@ -322,13 +335,17 @@ void Object::appendRequiredPropertyExtraData(RequiredPropertyExtraData *extraDat QString Object::appendBinding(Binding *b, bool isListBinding) { const bool bindingToDefaultProperty = (b->propertyNameIndex == quint32(0)); - if (!isListBinding && !bindingToDefaultProperty - && b->type != QV4::CompiledData::Binding::Type_GroupProperty - && b->type != QV4::CompiledData::Binding::Type_AttachedProperty - && !(b->flags & QV4::CompiledData::Binding::IsOnAssignment)) { + if (!isListBinding + && !bindingToDefaultProperty + && b->type() != QV4::CompiledData::Binding::Type_GroupProperty + && b->type() != QV4::CompiledData::Binding::Type_AttachedProperty + && !b->hasFlag(QV4::CompiledData::Binding::IsOnAssignment)) { Binding *existing = findBinding(b->propertyNameIndex); - if (existing && existing->isValueBinding() == b->isValueBinding() && !(existing->flags & QV4::CompiledData::Binding::IsOnAssignment)) + if (existing + && existing->isValueBinding() == b->isValueBinding() + && !existing->hasFlag(QV4::CompiledData::Binding::IsOnAssignment)) { return tr("Property value set multiple times"); + } } if (bindingToDefaultProperty) insertSorted(b); @@ -396,8 +413,7 @@ void ScriptDirectivesCollector::importFile(const QString &jsfile, const QString import->type = QV4::CompiledData::Import::ImportScript; import->uriIndex = jsGenerator->registerString(jsfile); import->qualifierIndex = jsGenerator->registerString(module); - import->location.line = lineNumber; - import->location.column = column; + import->location.set(lineNumber, column); document->imports << import; } @@ -408,8 +424,7 @@ void ScriptDirectivesCollector::importModule(const QString &uri, const QString & import->uriIndex = jsGenerator->registerString(uri); import->version = IRBuilder::extractVersion(QStringView(version)); import->qualifierIndex = jsGenerator->registerString(module); - import->location.line = lineNumber; - import->location.column = column; + import->location.set(lineNumber, column); document->imports << import; } @@ -594,8 +609,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiInlineComponent *ast) inlineComponent->nameIndex = registerString(ast->name.toString()); inlineComponent->objectIndex = idx; auto location = ast->firstSourceLocation(); - inlineComponent->location.line = location.startLine; - inlineComponent->location.column = location.startColumn; + inlineComponent->location.set(location.startLine, location.startColumn); _object->appendInlineComponent(inlineComponent); return false; } @@ -791,8 +805,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiImport *node) import->version = QTypeRevision(); } - import->location.line = node->importToken.startLine; - import->location.column = node->importToken.startColumn; + import->location.set(node->importToken.startLine, node->importToken.startColumn); import->uriIndex = registerString(uri); @@ -821,8 +834,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiPragma *node) return false; } - pragma->location.line = node->pragmaToken.startLine; - pragma->location.column = node->pragmaToken.startColumn; + pragma->location.set(node->pragmaToken.startLine, node->pragmaToken.startColumn); _pragmas.append(pragma); return false; @@ -855,8 +867,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiEnumDeclaration *node) if (enumName.at(0).isLower()) COMPILE_EXCEPTION(node->enumToken, tr("Scoped enum names must begin with an upper case letter")); - enumeration->location.line = node->enumToken.startLine; - enumeration->location.column = node->enumToken.startColumn; + enumeration->location.set(node->enumToken.startLine, node->enumToken.startColumn); enumeration->enumValues = New>(); @@ -875,8 +886,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiEnumDeclaration *node) COMPILE_EXCEPTION(e->valueToken, tr("Enum value out of range")); enumValue->value = e->value; - enumValue->location.line = e->memberToken.startLine; - enumValue->location.column = e->memberToken.startColumn; + enumValue->location.set(e->memberToken.startLine, e->memberToken.startColumn); enumeration->enumValues->append(enumValue); e = e->next; @@ -900,8 +910,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) signal->nameIndex = registerString(signalName); QQmlJS::SourceLocation loc = node->typeToken; - signal->location.line = loc.startLine; - signal->location.column = loc.startColumn; + signal->location.set(loc.startLine, loc.startColumn); signal->parameters = New >(); @@ -950,8 +959,8 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) const QStringView &name = node->name; Property *property = New(); - property->isReadOnly = node->isReadonlyMember; - property->isRequired = node->isRequired; + property->setIsReadOnly(node->isReadonlyMember); + property->setIsRequired(node->isRequired); QV4::CompiledData::BuiltinType builtinPropertyType = Parameter::stringToBuiltinType(memberType); bool typeFound = builtinPropertyType != QV4::CompiledData::BuiltinType::InvalidBuiltin; @@ -963,7 +972,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) property->setCustomType(registerString(memberType)); if (typeModifier == QLatin1String("list")) { - property->isList = true; + property->setIsList(true); } else if (!typeModifier.isEmpty()) { recordError(node->typeModifierToken, QCoreApplication::translate("QQmlParser","Invalid property type modifier")); return false; @@ -983,8 +992,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) property->nameIndex = registerString(propName); QQmlJS::SourceLocation loc = node->firstSourceLocation(); - property->location.line = loc.startLine; - property->location.column = loc.startColumn; + property->location.set(loc.startLine, loc.startColumn); QQmlJS::SourceLocation errorLocation; QString error; @@ -1028,8 +1036,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiSourceElement *node) Function *f = New(); QQmlJS::SourceLocation loc = funDecl->identifierToken; - f->location.line = loc.startLine; - f->location.column = loc.startColumn; + f->location.set(loc.startLine, loc.startColumn); f->index = index; f->nameIndex = registerString(funDecl->name.toString()); @@ -1102,26 +1109,31 @@ QStringView IRBuilder::textRefAt(const QQmlJS::SourceLocation &first, const QQml void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST::Statement *statement, QQmlJS::AST::Node *parentNode) { QQmlJS::SourceLocation loc = statement->firstSourceLocation(); - binding->valueLocation.line = loc.startLine; - binding->valueLocation.column = loc.startColumn; - binding->type = QV4::CompiledData::Binding::Type_Invalid; - if (_propertyDeclaration && _propertyDeclaration->isReadOnly) - binding->flags |= QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration; + binding->valueLocation.set(loc.startLine, loc.startColumn); + binding->setType(QV4::CompiledData::Binding::Type_Invalid); + if (_propertyDeclaration && _propertyDeclaration->isReadOnly()) + binding->setFlag(QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration); QQmlJS::AST::ExpressionStatement *exprStmt = QQmlJS::AST::cast(statement); if (exprStmt) { QQmlJS::AST::ExpressionNode * const expr = exprStmt->expression; if (QQmlJS::AST::StringLiteral *lit = QQmlJS::AST::cast(expr)) { - binding->type = QV4::CompiledData::Binding::Type_String; + binding->setType(QV4::CompiledData::Binding::Type_String); binding->stringIndex = registerString(lit->value.toString()); + } else if (QQmlJS::AST::TemplateLiteral *templateLit = QQmlJS::AST::cast(expr); + templateLit && templateLit->hasNoSubstitution) { + // A template literal without substitution is just a string. + // With substitution, it could however be an arbitrarily complex expression + binding->setType(QV4::CompiledData::Binding::Type_String); + binding->stringIndex = registerString(templateLit->value.toString()); } else if (expr->kind == QQmlJS::AST::Node::Kind_TrueLiteral) { - binding->type = QV4::CompiledData::Binding::Type_Boolean; + binding->setType(QV4::CompiledData::Binding::Type_Boolean); binding->value.b = true; } else if (expr->kind == QQmlJS::AST::Node::Kind_FalseLiteral) { - binding->type = QV4::CompiledData::Binding::Type_Boolean; + binding->setType(QV4::CompiledData::Binding::Type_Boolean); binding->value.b = false; } else if (QQmlJS::AST::NumericLiteral *lit = QQmlJS::AST::cast(expr)) { - binding->type = QV4::CompiledData::Binding::Type_Number; + binding->setType(QV4::CompiledData::Binding::Type_Number); binding->value.constantValueIndex = jsGenerator->registerConstant(QV4::Encode(lit->value)); } else if (QQmlJS::AST::CallExpression *call = QQmlJS::AST::cast(expr)) { if (QQmlJS::AST::IdentifierExpression *base = QQmlJS::AST::cast(call->base)) { @@ -1130,21 +1142,21 @@ void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST // below. } } else if (QQmlJS::AST::cast(expr)) { - binding->flags |= QV4::CompiledData::Binding::IsFunctionExpression; + binding->setFlag(QV4::CompiledData::Binding::IsFunctionExpression); } else if (QQmlJS::AST::UnaryMinusExpression *unaryMinus = QQmlJS::AST::cast(expr)) { if (QQmlJS::AST::NumericLiteral *lit = QQmlJS::AST::cast(unaryMinus->expression)) { - binding->type = QV4::CompiledData::Binding::Type_Number; + binding->setType(QV4::CompiledData::Binding::Type_Number); binding->value.constantValueIndex = jsGenerator->registerConstant(QV4::Encode(-lit->value)); } } else if (QQmlJS::AST::cast(expr)) { - binding->type = QV4::CompiledData::Binding::Type_Null; + binding->setType(QV4::CompiledData::Binding::Type_Null); binding->value.nullMarker = 0; } } // Do binding instead - if (binding->type == QV4::CompiledData::Binding::Type_Invalid) { - binding->type = QV4::CompiledData::Binding::Type_Script; + if (binding->type() == QV4::CompiledData::Binding::Type_Invalid) { + binding->setType(QV4::CompiledData::Binding::Type_Script); CompiledFunctionOrExpression *expr = New(); expr->node = statement; @@ -1155,7 +1167,15 @@ void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST binding->value.compiledScriptIndex = index; // We don't need to store the binding script as string, except for script strings // and types with custom parsers. Those will be added later in the compilation phase. - binding->stringIndex = emptyStringIndex; + // Except that we cannot recover the string when cachegen runs; we need to therefore retain + // "undefined". Any other "special" strings (for the various literals) are already handled above + QQmlJS::AST::Node *nodeForString = statement; + if (exprStmt) + nodeForString = exprStmt->expression; + if (asStringRef(nodeForString) == u"undefined") + binding->stringIndex = registerString(u"undefined"_qs); + else + binding->stringIndex = emptyStringIndex; } } @@ -1200,7 +1220,7 @@ void IRBuilder::tryGeneratingTranslationBinding(QStringView base, AST::ArgumentL if (args) return; // too many arguments, stop - binding->type = QV4::CompiledData::Binding::Type_Translation; + binding->setType(QV4::CompiledData::Binding::Type_Translation); binding->value.translationDataIndex = jsGenerator->registerTranslation(translationData); } else if (base == QLatin1String("qsTrId")) { QV4::CompiledData::TranslationData translationData; @@ -1233,7 +1253,7 @@ void IRBuilder::tryGeneratingTranslationBinding(QStringView base, AST::ArgumentL if (args) return; // too many arguments, stop - binding->type = QV4::CompiledData::Binding::Type_TranslationById; + binding->setType(QV4::CompiledData::Binding::Type_TranslationById); binding->value.translationDataIndex = jsGenerator->registerTranslation(translationData); } else if (base == QLatin1String("QT_TR_NOOP") || base == QLatin1String("QT_TRID_NOOP")) { if (!args || !args->expression) @@ -1250,7 +1270,7 @@ void IRBuilder::tryGeneratingTranslationBinding(QStringView base, AST::ArgumentL if (args) return; // too many arguments, stop - binding->type = QV4::CompiledData::Binding::Type_String; + binding->setType(QV4::CompiledData::Binding::Type_String); binding->stringIndex = jsGenerator->registerString(str.toString()); } else if (base == QLatin1String("QT_TRANSLATE_NOOP")) { if (!args || !args->expression) @@ -1271,7 +1291,7 @@ void IRBuilder::tryGeneratingTranslationBinding(QStringView base, AST::ArgumentL if (args) return; // too many arguments, stop - binding->type = QV4::CompiledData::Binding::Type_String; + binding->setType(QV4::CompiledData::Binding::Type_String); binding->stringIndex = jsGenerator->registerString(str.toString()); } } @@ -1308,9 +1328,8 @@ void IRBuilder::appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocatio Binding *binding = New(); binding->propertyNameIndex = propertyNameIndex; binding->offset = nameLocation.offset; - binding->location.line = nameLocation.startLine; - binding->location.column = nameLocation.startColumn; - binding->flags = 0; + binding->location.set(nameLocation.startLine, nameLocation.startColumn); + binding->clearFlags(); setBindingValue(binding, value, parentNode); QString error = bindingsTarget()->appendBinding(binding, /*isListBinding*/false); if (!error.isEmpty()) { @@ -1328,27 +1347,26 @@ void IRBuilder::appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocatio Binding *binding = New(); binding->propertyNameIndex = propertyNameIndex; binding->offset = nameLocation.offset; - binding->location.line = nameLocation.startLine; - binding->location.column = nameLocation.startColumn; + binding->location.set(nameLocation.startLine, nameLocation.startColumn); const Object *obj = _objects.at(objectIndex); binding->valueLocation = obj->location; - binding->flags = 0; + binding->clearFlags(); - if (_propertyDeclaration && _propertyDeclaration->isReadOnly) - binding->flags |= QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration; + if (_propertyDeclaration && _propertyDeclaration->isReadOnly()) + binding->setFlag(QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration); // No type name on the initializer means it must be a group property if (_objects.at(objectIndex)->inheritedTypeNameIndex == emptyStringIndex) - binding->type = QV4::CompiledData::Binding::Type_GroupProperty; + binding->setType(Binding::Type_GroupProperty); else - binding->type = QV4::CompiledData::Binding::Type_Object; + binding->setType(Binding::Type_Object); if (isOnAssignment) - binding->flags |= QV4::CompiledData::Binding::IsOnAssignment; + binding->setFlag(Binding::IsOnAssignment); if (isListItem) - binding->flags |= QV4::CompiledData::Binding::IsListItem; + binding->setFlag(Binding::IsListItem); binding->value.objectIndex = objectIndex; QString error = bindingsTarget()->appendBinding(binding, isListItem); @@ -1360,16 +1378,15 @@ void IRBuilder::appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocatio bool IRBuilder::appendAlias(QQmlJS::AST::UiPublicMember *node) { Alias *alias = New(); - alias->flags = 0; + alias->clearFlags(); if (node->isReadonlyMember) - alias->flags |= QV4::CompiledData::Alias::IsReadOnly; + alias->setFlag(QV4::CompiledData::Alias::IsReadOnly); const QString propName = node->name.toString(); - alias->nameIndex = registerString(propName); + alias->setNameIndex(registerString(propName)); QQmlJS::SourceLocation loc = node->firstSourceLocation(); - alias->location.line = loc.startLine; - alias->location.column = loc.startColumn; + alias->location.set(loc.startLine, loc.startColumn); alias->propertyNameIndex = emptyStringIndex; @@ -1383,8 +1400,7 @@ bool IRBuilder::appendAlias(QQmlJS::AST::UiPublicMember *node) rhsLoc = node->statement->firstSourceLocation(); else rhsLoc = node->semicolonToken; - alias->referenceLocation.line = rhsLoc.startLine; - alias->referenceLocation.column = rhsLoc.startColumn; + alias->referenceLocation.set(rhsLoc.startLine, rhsLoc.startColumn); QStringList aliasReference; @@ -1479,8 +1495,7 @@ bool IRBuilder::setId(const QQmlJS::SourceLocation &idLocation, QQmlJS::AST::Sta COMPILE_EXCEPTION(idLocation, tr("Property value set multiple times")); _object->idNameIndex = registerString(idQString); - _object->locationOfIdProperty.line = idLocation.startLine; - _object->locationOfIdProperty.column = idLocation.startColumn; + _object->locationOfIdProperty.set(idLocation.startLine, idLocation.startColumn); return true; } @@ -1526,19 +1541,19 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O binding = New(); binding->propertyNameIndex = propertyNameIndex; binding->offset = qualifiedIdElement->identifierToken.offset; - binding->location.line = qualifiedIdElement->identifierToken.startLine; - binding->location.column = qualifiedIdElement->identifierToken.startColumn; - binding->valueLocation.line = qualifiedIdElement->next->identifierToken.startLine; - binding->valueLocation.column = qualifiedIdElement->next->identifierToken.startColumn; - binding->flags = 0; + binding->location.set(qualifiedIdElement->identifierToken.startLine, + qualifiedIdElement->identifierToken.startColumn); + binding->valueLocation.set(qualifiedIdElement->next->identifierToken.startLine, + qualifiedIdElement->next->identifierToken.startColumn); + binding->clearFlags(); if (onAssignment) - binding->flags |= QV4::CompiledData::Binding::IsOnAssignment; + binding->setFlag(QV4::CompiledData::Binding::IsOnAssignment); if (isAttachedProperty) - binding->type = QV4::CompiledData::Binding::Type_AttachedProperty; + binding->setType(QV4::CompiledData::Binding::Type_AttachedProperty); else - binding->type = QV4::CompiledData::Binding::Type_GroupProperty; + binding->setType(QV4::CompiledData::Binding::Type_GroupProperty); int objIndex = 0; if (!defineQMLObject(&objIndex, nullptr, binding->location, nullptr, nullptr)) @@ -1599,7 +1614,7 @@ bool IRBuilder::isStatementNodeScript(QQmlJS::AST::Statement *statement) bool IRBuilder::isRedundantNullInitializerForPropertyDeclaration(Property *property, QQmlJS::AST::Statement *statement) { - if (property->isBuiltinType || property->isList) + if (property->isBuiltinType() || property->isList()) return false; QQmlJS::AST::ExpressionStatement *exprStmt = QQmlJS::AST::cast(statement); if (!exprStmt) @@ -1701,10 +1716,10 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen QV4::CompiledData::Object *objectToWrite = reinterpret_cast(objectPtr); objectToWrite->inheritedTypeNameIndex = o->inheritedTypeNameIndex; objectToWrite->indexOfDefaultPropertyOrAlias = o->indexOfDefaultPropertyOrAlias; - objectToWrite->defaultPropertyIsAlias = o->defaultPropertyIsAlias; - objectToWrite->flags = o->flags; + objectToWrite->setHasAliasAsDefaultProperty(o->defaultPropertyIsAlias); + objectToWrite->setFlags(QV4::CompiledData::Object::Flags(o->flags)); objectToWrite->idNameIndex = o->idNameIndex; - objectToWrite->id = o->id; + objectToWrite->setObjectId(o->id); objectToWrite->location = o->location; objectToWrite->locationOfIdProperty = o->locationOfIdProperty; @@ -1794,7 +1809,6 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen nextOffset += signalTableSize; quint32_le *enumOffsetTable = reinterpret_cast(objectPtr + objectToWrite->offsetToEnums); - quint32 enumTableSize = 0; char *enumPtr = objectPtr + nextOffset; for (const Enum *e = o->firstEnum(); e; e = e->next) { *enumOffsetTable++ = enumPtr - objectPtr; @@ -1809,7 +1823,6 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen *enumValueToWrite = *enumValue; int size = QV4::CompiledData::Enum::calculateSize(e->enumValues->count); - enumTableSize += size; enumPtr += size; } @@ -1879,7 +1892,7 @@ char *QmlUnitGenerator::writeBindings(char *bindingPtr, const Object *o, Binding continue; QV4::CompiledData::Binding *bindingToWrite = reinterpret_cast(bindingPtr); *bindingToWrite = *b; - if (b->type == QV4::CompiledData::Binding::Type_Script) + if (b->type() == QV4::CompiledData::Binding::Type_Script) bindingToWrite->value.compiledScriptIndex = o->runtimeFunctionIndices.at(b->value.compiledScriptIndex); bindingPtr += sizeof(QV4::CompiledData::Binding); } @@ -1918,6 +1931,12 @@ QVector JSCodeGen::generateJSCodeForFunctionsAndBindings(const QListbody : f.node); scan.leaveEnvironment(); } @@ -1967,60 +1986,23 @@ QVector JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList &componentRoots) -{ - for (int i = 0; i < componentRoots.count(); ++i) { - if (!compileComponent(componentRoots.at(i))) - return false; - } - - return compileComponent(/*root object*/0); -} - -bool JSCodeGen::compileComponent(int contextObject) +bool JSCodeGen::generateRuntimeFunctions(QmlIR::Object *object) { - const QmlIR::Object *obj = document->objects.at(contextObject); - if (obj->flags & QV4::CompiledData::Object::IsComponent && !obj->isInlineComponent) { - Q_ASSERT(obj->bindingCount() == 1); - const QV4::CompiledData::Binding *componentBinding = obj->firstBinding(); - Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object); - contextObject = componentBinding->value.objectIndex; - } - - return compileJavaScriptCodeInObjectsRecursively(contextObject, contextObject); -} - -bool JSCodeGen::compileJavaScriptCodeInObjectsRecursively(int objectIndex, int scopeObjectIndex) -{ - QmlIR::Object *object = document->objects.at(objectIndex); - if (object->flags & QV4::CompiledData::Object::IsComponent && !object->isInlineComponent) + if (object->functionsAndExpressions->count == 0) return true; - for (auto it = object->inlineComponentsBegin(); it != object->inlineComponentsEnd(); ++it) - compileComponent(it->objectIndex); - - if (object->functionsAndExpressions->count > 0) { - QList functionsToCompile; - for (QmlIR::CompiledFunctionOrExpression *foe = object->functionsAndExpressions->first; foe; foe = foe->next) - functionsToCompile << *foe; - const QVector runtimeFunctionIndices = generateJSCodeForFunctionsAndBindings(functionsToCompile); - if (hasError()) - return false; - - object->runtimeFunctionIndices.allocate(document->jsParserEngine.pool(), - runtimeFunctionIndices); + QList functionsToCompile; + functionsToCompile.reserve(object->functionsAndExpressions->count); + for (QmlIR::CompiledFunctionOrExpression *foe = object->functionsAndExpressions->first; foe; + foe = foe->next) { + functionsToCompile << *foe; } - for (const QmlIR::Binding *binding = object->firstBinding(); binding; binding = binding->next) { - if (binding->type < QV4::CompiledData::Binding::Type_Object) - continue; - - int target = binding->value.objectIndex; - int scope = binding->type == QV4::CompiledData::Binding::Type_Object ? target : scopeObjectIndex; - - if (!compileJavaScriptCodeInObjectsRecursively(binding->value.objectIndex, scope)) - return false; - } + const auto runtimeFunctionIndices = generateJSCodeForFunctionsAndBindings(functionsToCompile); + if (hasError()) + return false; + object->runtimeFunctionIndices.allocate(document->jsParserEngine.pool(), + runtimeFunctionIndices); return true; } diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index 99c1af6cbf6..93e550a5304 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -394,6 +394,10 @@ struct Q_QMLCOMPILER_PRIVATE_EXPORT Object int namedObjectsInComponentCount() const { return namedObjectsInComponent.size(); } const quint32 *namedObjectsInComponentTable() const { return namedObjectsInComponent.begin(); } + bool hasFlag(QV4::CompiledData::Object::Flag flag) const { return flags & flag; } + qint32 objectId() const { return id; } + bool hasAliasAsDefaultProperty() const { return defaultPropertyIsAlias; } + private: friend struct ::QQmlIRLoader; @@ -591,9 +595,7 @@ struct Q_QMLCOMPILER_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen // Returns mapping from input functions to index in IR::Module::functions / compiledData->runtimeFunctions QVector generateJSCodeForFunctionsAndBindings(const QList &functions); - bool generateCodeForComponents(const QVector &componentRoots); - bool compileComponent(int contextObject); - bool compileJavaScriptCodeInObjectsRecursively(int objectIndex, int scopeObjectIndex); + bool generateRuntimeFunctions(QmlIR::Object *object); private: Document *document; diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index f7c4e2c98ff..4f00131a093 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -3048,12 +3048,17 @@ bool Codegen::visit(ThisExpression *) if (hasError()) return false; - if (_context->isArrowFunction) { - Reference r = referenceForName(QStringLiteral("this"), false); - r.isReadonly = true; - setExprResult(r); - return false; + for (Context *parentContext = _context; parentContext; parentContext = parentContext->parent) { + if (parentContext->isArrowFunction) { + Reference r = referenceForName(QStringLiteral("this"), false); + r.isReadonly = true; + setExprResult(r); + return false; + } + if (parentContext->contextType != ContextType::Block) + break; } + setExprResult(Reference::fromThis(this)); return false; } @@ -3158,6 +3163,17 @@ bool Codegen::visit(YieldExpression *ast) return false; } + auto innerMostCurentFunctionContext = _context; + while (innerMostCurentFunctionContext && innerMostCurentFunctionContext->contextType != ContextType::Function) + innerMostCurentFunctionContext = innerMostCurentFunctionContext->parent; + + Q_ASSERT(innerMostCurentFunctionContext); // yield outside function would have been rejected by parser + + if (!innerMostCurentFunctionContext->isGenerator) { + throwSyntaxError(ast->firstSourceLocation(), u"Yield is only valid in generator functions"_qs); + return false; + } + RegisterScope scope(this); TailCallBlocker blockTailCalls(this); Reference expr = ast->expression ? expression(ast->expression) : Reference::fromConst(this, Encode::undefined()); diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index 5511ed304a0..fdb5fcb3318 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -154,10 +154,7 @@ int QV4::Compiler::JSUnitGenerator::registerGetterLookup(const QString &name) int QV4::Compiler::JSUnitGenerator::registerGetterLookup(int nameIndex) { - CompiledData::Lookup l; - l.type_and_flags = CompiledData::Lookup::Type_Getter; - l.nameIndex = nameIndex; - lookups << l; + lookups << CompiledData::Lookup(CompiledData::Lookup::Type_Getter, nameIndex); return lookups.size() - 1; } @@ -168,49 +165,37 @@ int QV4::Compiler::JSUnitGenerator::registerSetterLookup(const QString &name) int QV4::Compiler::JSUnitGenerator::registerSetterLookup(int nameIndex) { - CompiledData::Lookup l; - l.type_and_flags = CompiledData::Lookup::Type_Setter; - l.nameIndex = nameIndex; - lookups << l; + lookups << CompiledData::Lookup(CompiledData::Lookup::Type_Setter, nameIndex); return lookups.size() - 1; } int QV4::Compiler::JSUnitGenerator::registerGlobalGetterLookup(int nameIndex) { - CompiledData::Lookup l; - l.type_and_flags = CompiledData::Lookup::Type_GlobalGetter; - l.nameIndex = nameIndex; - lookups << l; + lookups << CompiledData::Lookup(CompiledData::Lookup::Type_GlobalGetter, nameIndex); return lookups.size() - 1; } int QV4::Compiler::JSUnitGenerator::registerQmlContextPropertyGetterLookup(int nameIndex) { - CompiledData::Lookup l; - l.type_and_flags = CompiledData::Lookup::Type_QmlContextPropertyGetter; - l.nameIndex = nameIndex; - lookups << l; + lookups << CompiledData::Lookup(CompiledData::Lookup::Type_QmlContextPropertyGetter, nameIndex); return lookups.size() - 1; } int QV4::Compiler::JSUnitGenerator::registerRegExp(QQmlJS::AST::RegExpLiteral *regexp) { - CompiledData::RegExp re; - re.stringIndex = registerString(regexp->pattern.toString()); - - re.flags = 0; + quint32 flags = 0; if (regexp->flags & QQmlJS::Lexer::RegExp_Global) - re.flags |= CompiledData::RegExp::RegExp_Global; + flags |= CompiledData::RegExp::RegExp_Global; if (regexp->flags & QQmlJS::Lexer::RegExp_IgnoreCase) - re.flags |= CompiledData::RegExp::RegExp_IgnoreCase; + flags |= CompiledData::RegExp::RegExp_IgnoreCase; if (regexp->flags & QQmlJS::Lexer::RegExp_Multiline) - re.flags |= CompiledData::RegExp::RegExp_Multiline; + flags |= CompiledData::RegExp::RegExp_Multiline; if (regexp->flags & QQmlJS::Lexer::RegExp_Unicode) - re.flags |= CompiledData::RegExp::RegExp_Unicode; + flags |= CompiledData::RegExp::RegExp_Unicode; if (regexp->flags & QQmlJS::Lexer::RegExp_Sticky) - re.flags |= CompiledData::RegExp::RegExp_Sticky; + flags |= CompiledData::RegExp::RegExp_Sticky; - regexps.append(re); + regexps.append(CompiledData::RegExp(flags, registerString(regexp->pattern.toString()))); return regexps.size() - 1; } @@ -243,8 +228,7 @@ int QV4::Compiler::JSUnitGenerator::registerJSClass(const QStringList &members) CompiledData::JSClassMember *member = reinterpret_cast(jsClass + 1); for (const auto &name : members) { - member->nameOffset = registerString(name); - member->isAccessor = false; + member->set(registerString(name), false); ++member; } @@ -432,9 +416,21 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte function->flags |= CompiledData::Function::IsArrowFunction; if (irFunction->isGenerator) function->flags |= CompiledData::Function::IsGenerator; - function->nestedFunctionIndex = - irFunction->returnsClosure ? quint32(module->functions.indexOf(irFunction->nestedContexts.first())) - : std::numeric_limits::max(); + if (irFunction->returnsClosure) + function->flags |= CompiledData::Function::IsClosureWrapper; + + if (!irFunction->returnsClosure + || irFunction->innerFunctionAccessesThis + || irFunction->innerFunctionAccessesNewTarget) { + // If the inner function does things with this and new.target we need to do some work in + // the outer function. Then we shouldn't directly access the nested function. + function->nestedFunctionIndex = std::numeric_limits::max(); + } else { + // Otherwise we can directly use the nested function. + function->nestedFunctionIndex + = quint32(module->functions.indexOf(irFunction->nestedContexts.first())); + } + function->length = irFunction->formals ? irFunction->formals->length() : 0; function->nFormals = irFunction->arguments.size(); function->formalsOffset = currentOffset; @@ -462,8 +458,7 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte currentOffset += function->nLabelInfos * sizeof(quint32); } - function->location.line = irFunction->line; - function->location.column = irFunction->column; + function->location.set(irFunction->line, irFunction->column); function->codeOffset = currentOffset; function->codeSize = irFunction->code.size(); diff --git a/src/qml/compiler/qv4compiler_p.h b/src/qml/compiler/qv4compiler_p.h index 5155c25c06a..457c150b5e2 100644 --- a/src/qml/compiler/qv4compiler_p.h +++ b/src/qml/compiler/qv4compiler_p.h @@ -125,7 +125,7 @@ struct Q_QMLCOMPILER_PRIVATE_EXPORT JSUnitGenerator { int registerSetterLookup(int nameIndex); int registerGlobalGetterLookup(int nameIndex); int registerQmlContextPropertyGetterLookup(int nameIndex); - int lookupNameIndex(int index) const { return lookups[index].nameIndex; } + int lookupNameIndex(int index) const { return lookups[index].nameIndex(); } QString lookupName(int index) const { return stringForIndex(lookupNameIndex(index)); } int registerRegExp(QQmlJS::AST::RegExpLiteral *regexp); diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index 9dec968a91f..7a558478ddf 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -57,10 +57,7 @@ using namespace QQmlJS::AST; static CompiledData::Location location(const QQmlJS::SourceLocation &astLocation) { - CompiledData::Location target; - target.line = astLocation.startLine; - target.column = astLocation.startColumn; - return target; + return CompiledData::Location(astLocation.startLine, astLocation.startColumn); } @@ -382,8 +379,11 @@ bool ScanFunctions::visit(ExpressionStatement *ast) if (!_allowFuncDecls) _cg->throwSyntaxError(expr->functionToken, QStringLiteral("conditional function or closure declaration")); - if (!enterFunction(expr, /*enterName*/ true)) + if (!enterFunction(expr, expr->identifierToken.length > 0 + ? FunctionNameContext::Inner + : FunctionNameContext::None)) { return false; + } Node::accept(expr->formals, this); Node::accept(expr->body, this); leaveEnvironment(); @@ -399,7 +399,9 @@ bool ScanFunctions::visit(ExpressionStatement *ast) bool ScanFunctions::visit(FunctionExpression *ast) { - return enterFunction(ast, /*enterName*/ false); + return enterFunction(ast, ast->identifierToken.length > 0 + ? FunctionNameContext::Inner + : FunctionNameContext::None); } bool ScanFunctions::visit(ClassExpression *ast) @@ -496,12 +498,12 @@ bool ScanFunctions::visit(ArrayPattern *ast) return false; } -bool ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName) +bool ScanFunctions::enterFunction(FunctionExpression *ast, FunctionNameContext nameContext) { Q_ASSERT(_context); if (_context->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments"))) _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Function name may not be eval or arguments in strict mode")); - return enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName); + return enterFunction(ast, ast->name.toString(), ast->formals, ast->body, nameContext); } void ScanFunctions::endVisit(FunctionExpression *) @@ -536,7 +538,7 @@ void ScanFunctions::endVisit(PatternProperty *) bool ScanFunctions::visit(FunctionDeclaration *ast) { - return enterFunction(ast, /*enterName*/ true); + return enterFunction(ast, FunctionNameContext::Outer); } void ScanFunctions::endVisit(FunctionDeclaration *) @@ -674,7 +676,9 @@ void ScanFunctions::endVisit(WithStatement *) leaveEnvironment(); } -bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, StatementList *body, bool enterName) +bool ScanFunctions::enterFunction( + Node *ast, const QString &name, FormalParameterList *formals, StatementList *body, + FunctionNameContext nameContext) { Context *outerContext = _context; enterEnvironment(ast, ContextType::Function, name); @@ -685,7 +689,7 @@ bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete if (outerContext) { outerContext->hasNestedFunctions = true; // The identifier of a function expression cannot be referenced from the enclosing environment. - if (enterName) { + if (nameContext == FunctionNameContext::Outer) { if (!outerContext->addLocalVar(name, Context::FunctionDefinition, VariableScope::Var, expr)) { _cg->throwSyntaxError(ast->firstSourceLocation(), QStringLiteral("Identifier %1 has already been declared").arg(name)); return false; @@ -711,8 +715,10 @@ bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete } - if (!enterName && (!name.isEmpty() && (!formals || !formals->containsName(name)))) + if (nameContext == FunctionNameContext::Inner + && (!name.isEmpty() && (!formals || !formals->containsName(name)))) { _context->addLocalVar(name, Context::ThisFunctionName, VariableScope::Var); + } _context->formals = formals; if (body && !_context->isStrict) diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h index 0336398cac7..d2868fc428e 100644 --- a/src/qml/compiler/qv4compilerscanfunctions_p.h +++ b/src/qml/compiler/qv4compilerscanfunctions_p.h @@ -83,15 +83,32 @@ class ScanFunctions: protected QQmlJS::AST::Visitor ScanFunctions(Codegen *cg, const QString &sourceCode, ContextType defaultProgramType); void operator()(QQmlJS::AST::Node *node); + // see comment at its call site in generateJSCodeForFunctionsAndBindings + // for why this function is necessary + void handleTopLevelFunctionFormals(QQmlJS::AST::FunctionExpression *node) { + if (node && node->formals) + node->formals->accept(this); + } + void enterGlobalEnvironment(ContextType compilationMode); void enterEnvironment(QQmlJS::AST::Node *node, ContextType compilationMode, const QString &name); void leaveEnvironment(); void enterQmlFunction(QQmlJS::AST::FunctionExpression *ast) - { enterFunction(ast, false); } + { enterFunction(ast, FunctionNameContext::None); } protected: + // Function declarations add their name to the outer scope, but not the + // inner scope. Function expressions add their name to the inner scope, + // unless the name is actually picked from the outer scope rather than + // given after the function token. QML functions don't add their name + // anywhere because the name is already recorded in the QML element. + // This enum is used to control the behavior of enterFunction(). + enum class FunctionNameContext { + None, Inner, Outer + }; + using Visitor::visit; using Visitor::endVisit; @@ -118,7 +135,8 @@ class ScanFunctions: protected QQmlJS::AST::Visitor bool visit(QQmlJS::AST::FieldMemberExpression *) override; bool visit(QQmlJS::AST::ArrayPattern *) override; - bool enterFunction(QQmlJS::AST::FunctionExpression *ast, bool enterName); + bool enterFunction(QQmlJS::AST::FunctionExpression *ast, + FunctionNameContext nameContext); void endVisit(QQmlJS::AST::FunctionExpression *) override; @@ -161,7 +179,7 @@ class ScanFunctions: protected QQmlJS::AST::Visitor protected: bool enterFunction(QQmlJS::AST::Node *ast, const QString &name, QQmlJS::AST::FormalParameterList *formals, - QQmlJS::AST::StatementList *body, bool enterName); + QQmlJS::AST::StatementList *body, FunctionNameContext nameContext); void calcEscapingVariables(); // fields: diff --git a/src/qml/configure.cmake b/src/qml/configure.cmake index 11c29620d67..a587a8fe1dc 100644 --- a/src/qml/configure.cmake +++ b/src/qml/configure.cmake @@ -7,9 +7,12 @@ #### Libraries -# special case begin qt_find_package(LTTngUST PROVIDED_TARGETS LTTng::UST MODULE_NAME qml QMAKE_LIB lttng-ust) -# special case end +qt_find_package(Python REQUIRED) +if(Python_Interpreter_FOUND) + # Need to make it globally available to the project + set(QT_INTERNAL_DECLARATIVE_PYTHON "${Python_EXECUTABLE}" CACHE STRING "") +endif() #### Tests @@ -200,13 +203,9 @@ qt_feature("qml-xmllistmodel" PRIVATE CONDITION QT_FEATURE_qml_itemmodel AND QT_FEATURE_future ) -# special case begin -qt_qml_find_python(__qt_qml_python_path __qt_qml_python_found) -# special case end - qt_feature("qml-python" PRIVATE LABEL "python" - CONDITION __qt_qml_python_found # special case + CONDITION Python_Interpreter_FOUND ) qt_configure_add_summary_section(NAME "Qt QML") qt_configure_add_summary_entry(ARGS "qml-network") diff --git a/src/qml/configure.json b/src/qml/configure.json deleted file mode 100644 index 0bc16d31b8d..00000000000 --- a/src/qml/configure.json +++ /dev/null @@ -1,216 +0,0 @@ -{ - "module": "qml", - "depends": [ - "core-private", - "network-private" - ], - - "commandline": { - "options": { - "qml-network": "boolean", - "qml-debug": "boolean" - } - }, - - "tests": { - "pointer_32bit": { - "label": "32bit pointers", - "type": "compile", - "test": { - "main": "static_assert(sizeof(void *) == 4, \"fail\");" - } - }, - "pointer_64bit": { - "label": "64bit pointers", - "type": "compile", - "test": { - "main": "static_assert(sizeof(void *) == 8, \"fail\");" - } - }, - "arm_thumb": { - "label": "THUMB mode on ARM", - "type": "compile", - "test": { - "main": [ - "#if defined(thumb2) || defined(__thumb2__)", - "# define THUMB_OK", - "#elif (defined(__thumb) || defined(__thumb__)) && __TARGET_ARCH_THUMB-0 == 4", - "# define THUMB_OK", - "#elif defined(__ARM_ARCH_ISA_THUMB) && __ARM_ARCH_ISA_THUMB == 2", - "// clang 3.5 and later will set this if the core supports the Thumb-2 ISA.", - "# define THUMB_OK", - "#else", - "# error \"fail\"", - "#endif" - ] - } - }, - "arm_fp": { - "label": "Sufficiently recent FPU on ARM", - "type": "compile", - "test": { - "main": [ - "// if !defined(__ARM_FP) we might be on MSVC or we might have a device", - "// without an FPU.", - "// TODO: The latter case is not supported, but the test still succeeds.", - "#if defined(__ARM_FP) && (__ARM_FP <= 0x04)", - "# error \"fail\"", - "#endif" - ] - } - }, - "qml-python": { - "label": "python", - "type": "detectPython", - "log": "location" - } - }, - - "features": { - "qml-network": { - "label": "QML network support", - "purpose": "Provides network transparency.", - "section": "QML", - "condition": "features.network", - "output": [ "publicFeature" ] - }, - "qml-jit": { - "label": "QML just-in-time compiler", - "purpose": "Provides a JIT for QML and JavaScript", - "section": "QML", - "condition": [ - " (arch.i386 && tests.pointer_32bit && features.sse2) - || (arch.x86_64 && tests.pointer_64bit && features.sse2) - || (arch.arm && tests.pointer_32bit && tests.arm_fp && tests.arm_thumb - && (config.linux || config.ios || config.tvos || config.qnx)) - || (arch.arm64 && tests.pointer_64bit && tests.arm_fp - && (config.linux || config.ios || config.tvos || config.qnx || config.integrity))" - ], - "output": [ "privateFeature" ], - "autoDetect": "!config.ios && !config.tvos", - "comment": "On arm and arm64 we need a specialization of cacheFlush() for each OS to be - enabeled. Therefore the config white list. - Also Mind that e.g. x86_32 has arch.x86_64 but 32bit pointers. Therefore - the checks for architecture and pointer size. - Finally, ios and tvos can technically use the JIT but Apple does not allow - it. Therefore, it's disabled by default." - }, - "qml-debug": { - "label": "QML debugging and profiling support", - "purpose": "Provides infrastructure and plugins for debugging and profiling.", - "section": "QML", - "output": [ "publicFeature" ] - }, - "qml-profiler": { - "label": "Command line QML Profiler", - "purpose": "Supports retrieving QML tracing data from an application.", - "section": "QML", - "condition": [ - "features.commandlineparser", - "features.qml-debug", - "features.qml-network && features.localserver", - "features.xmlstreamwriter" - ], - "output": [ "privateFeature" ] - }, - "qml-preview": { - "label": "Command line QML Preview tool", - "purpose": "Updates QML documents in your application live as you change them on disk", - "section": "QML", - "condition": [ - "features.commandlineparser", - "features.filesystemwatcher", - "features.qml-network && features.localserver", - "features.process", - "features.qml-debug" - ], - "output": [ "privateFeature" ] - }, - "qml-devtools": { - "label": "QML Development Tools", - "purpose": "Provides the QmlDevtools library and various utilities.", - "section": "QML", - "output": [ "privateFeature" ] - }, - "qml-sequence-object": { - "label": "QML sequence object", - "purpose": "Supports mapping sequence types into QML.", - "section": "QML", - "output": [ "privateFeature" ] - }, - "qml-xml-http-request": { - "label": "QML XML http request", - "purpose": "Provides support for sending XML http requests.", - "section": "QML", - "condition": [ - "features.xmlstreamreader", - "features.qml-network" - ], - "output": [ "privateFeature" ] - }, - "qml-locale": { - "label": "QML Locale", - "purpose": "Provides support for locales in QML.", - "section": "QML", - "output": [ "privateFeature" ] - }, - "qml-animation": { - "label": "QML Animations", - "purpose": "Provides support for animations and timers in QML.", - "section": "QML", - "condition": "features.animation", - "output": [ "privateFeature" ] - }, - "qml-worker-script": { - "label": "QML WorkerScript", - "purpose": "Enables the use of threads in QML.", - "section": "QML", - "condition": "features.thread", - "output": [ "privateFeature" ] - }, - "qml-itemmodel": { - "label": "QML Item Model", - "purpose": "Provides the item model for item views in QML", - "section": "QML", - "condition": "features.itemmodel", - "output": [ "privateFeature" ] - }, - "qml-xmllistmodel": { - "label": "QML XmlListModel", - "purpose": "Enable XmlListModel in QML", - "section": "QML", - "condition": "features.qml-itemmodel && features.future", - "output": [ "privateFeature" ] - }, - "qml-python": { - "label": "python", - "condition": "tests.qml-python", - "output": [ - "privateFeature", - { "type": "varAssign", "name": "QMAKE_PYTHON", "value": "tests.qml-python.location" } - ] - } - }, - - "report": [ - { - "type": "error", - "condition": "!features.qml-python", - "message": "Python is required to build QtQml." - } - ], - - "summary": [ - { - "section": "Qt QML", - "entries": [ - "qml-network", - "qml-debug", - "qml-jit", - "qml-sequence-object", - "qml-xml-http-request", - "qml-locale" - ] - } - ] -} diff --git a/src/qml/debugger/qqmldebug.cpp b/src/qml/debugger/qqmldebug.cpp index 58b8ea2c4fa..0ca56f3a702 100644 --- a/src/qml/debugger/qqmldebug.cpp +++ b/src/qml/debugger/qqmldebug.cpp @@ -44,17 +44,26 @@ #include #include +#include #include QT_REQUIRE_CONFIG(qml_debug); QT_BEGIN_NAMESPACE +#if __cplusplus >= 202002L +# define Q_ATOMIC_FLAG_INIT {} +#else +# define Q_ATOMIC_FLAG_INIT ATOMIC_FLAG_INIT // deprecated in C++20 +#endif + +static std::atomic_flag s_printedWarning = Q_ATOMIC_FLAG_INIT; + QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning) { - if (!QQmlEnginePrivate::qml_debugging_enabled && printWarning) + if (printWarning && !s_printedWarning.test_and_set(std::memory_order_relaxed)) fprintf(stderr, "QML debugging is enabled. Only use this in a safe environment.\n"); - QQmlEnginePrivate::qml_debugging_enabled = true; + QQmlEnginePrivate::qml_debugging_enabled.store(true, std::memory_order_relaxed); } /*! diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp index 74b10e64d70..a576cddf1ad 100644 --- a/src/qml/debugger/qqmldebugconnector.cpp +++ b/src/qml/debugger/qqmldebugconnector.cpp @@ -111,7 +111,7 @@ QQmlDebugConnector *QQmlDebugConnector::instance() if (!params) return nullptr; - if (!QQmlEnginePrivate::qml_debugging_enabled) { + if (!QQmlEnginePrivate::qml_debugging_enabled.load(std::memory_order_relaxed)) { if (!params->arguments.isEmpty()) { qWarning().noquote() << QString::fromLatin1( "QML Debugger: Ignoring \"-qmljsdebugger=%1\". Debugging " diff --git a/src/qml/debugger/qqmldebugconnector_p.h b/src/qml/debugger/qqmldebugconnector_p.h index d1ad90adfda..4f7b0131608 100644 --- a/src/qml/debugger/qqmldebugconnector_p.h +++ b/src/qml/debugger/qqmldebugconnector_p.h @@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE class Q_QML_PRIVATE_EXPORT QQmlDebugConnector { + virtual ~QQmlDebugConnector() = default; // don't break 'override' on ~QQmlDebugServer public: static QQmlDebugConnector *instance() { return nullptr; } diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp new file mode 100644 index 00000000000..5119fc42090 --- /dev/null +++ b/src/qml/debugger/qqmldebugserver.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 "qqmldebugserver_p.h" + +QT_BEGIN_NAMESPACE + +QQmlDebugServer::~QQmlDebugServer() + = default; + +QT_END_NAMESPACE + +#include "moc_qqmldebugserver_p.cpp" diff --git a/src/qml/debugger/qqmldebugserver_p.h b/src/qml/debugger/qqmldebugserver_p.h index e848b00bda1..c99155051c3 100644 --- a/src/qml/debugger/qqmldebugserver_p.h +++ b/src/qml/debugger/qqmldebugserver_p.h @@ -62,6 +62,7 @@ class Q_QML_PRIVATE_EXPORT QQmlDebugServer : public QQmlDebugConnector { Q_OBJECT public: + ~QQmlDebugServer() override; virtual void setDevice(QIODevice *socket) = 0; }; diff --git a/src/qml/debugger/qqmldebugserviceinterfaces_p.h b/src/qml/debugger/qqmldebugserviceinterfaces_p.h index 02367d1984f..d01e472edb8 100644 --- a/src/qml/debugger/qqmldebugserviceinterfaces_p.h +++ b/src/qml/debugger/qqmldebugserviceinterfaces_p.h @@ -69,6 +69,8 @@ class QQuickWindow; #if !QT_CONFIG(qml_debug) +class TranslationBindingInformation; + class QV4DebugService { public: @@ -106,7 +108,6 @@ class QQmlEngineControlService {}; class QQmlNativeDebugService {}; class QQmlDebugTranslationService { public: - virtual QString foundElidedText(QObject *, const QString &, const QString &) {return {};} virtual void foundTranslationBinding(const TranslationBindingInformation &) {} }; @@ -184,7 +185,6 @@ class Q_QML_PRIVATE_EXPORT QQmlDebugTranslationService : public QQmlDebugService public: static const QString s_key; - virtual QString foundElidedText(QObject *qQuickTextObject, const QString &layoutText, const QString &elideText) = 0; virtual void foundTranslationBinding(const TranslationBindingInformation &translationBindingInformation) = 0; protected: friend class QQmlDebugConnector; diff --git a/src/qml/debugger/qqmldebugtranslationprotocol_p.h b/src/qml/debugger/qqmldebugtranslationprotocol_p.h index 467b34d5096..06d38505108 100644 --- a/src/qml/debugger/qqmldebugtranslationprotocol_p.h +++ b/src/qml/debugger/qqmldebugtranslationprotocol_p.h @@ -64,19 +64,23 @@ enum class Request { ChangeLanguage = 1, StateList, ChangeState, - MissingTranslations, + TranslationIssues, TranslatableTextOccurrences, WatchTextElides, DisableWatchTextElides, + // following are obsolete, just provided for compilation compatibility + MissingTranslations }; enum class Reply { LanguageChanged = 101, StateList, StateChanged, - MissingTranslations, + TranslationIssues, TranslatableTextOccurrences, - TextElided, + // following are obsolete, just provided for compilation compatibility + MissingTranslations, + TextElided }; inline QByteArray createChangeLanguageRequest(QDataStream &packet, const QUrl &url, @@ -98,6 +102,12 @@ inline QByteArray createMissingTranslationsRequest(QDataStream &packet) return qobject_cast(packet.device())->data(); } +inline QByteArray createTranslationIssuesRequest(QDataStream &packet) +{ + packet << Request::TranslationIssues; + return qobject_cast(packet.device())->data(); +} + inline QByteArray createTranslatableTextOccurrencesRequest(QDataStream &packet) { packet << Request::TranslatableTextOccurrences; @@ -210,7 +220,7 @@ class QmlElement >> qmlElement.propertyName >> qmlElement.translationId >> qmlElement.translatedText >> qmlElement.fontFamily >> qmlElement.fontPointSize >> qmlElement.fontPixelSize >> qmlElement.fontStyleName >> qmlElement.horizontalAlignment - >> qmlElement.verticalAlignment; + >> qmlElement.verticalAlignment >> qmlElement.stateName; } friend QDataStream &operator<<(QDataStream &stream, const QmlElement &qmlElement) @@ -220,7 +230,7 @@ class QmlElement << qmlElement.translatedText << qmlElement.fontFamily << qmlElement.fontPointSize << qmlElement.fontPixelSize << qmlElement.fontStyleName << qmlElement.horizontalAlignment - << qmlElement.verticalAlignment; + << qmlElement.verticalAlignment << qmlElement.stateName; } CodeMarker codeMarker; @@ -232,10 +242,12 @@ class QmlElement QString elementId; QString elementType; qreal fontPointSize = 0.0; + QString stateName; int fontPixelSize = 0; int horizontalAlignment = 0; int verticalAlignment = 0; }; + class QmlState { public: diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h index f7dc326defd..9e2ba98ca43 100644 --- a/src/qml/debugger/qqmlprofiler_p.h +++ b/src/qml/debugger/qqmlprofiler_p.h @@ -176,7 +176,7 @@ class Q_QML_PRIVATE_EXPORT QQmlProfiler : public QObject, public QQmlProfilerDef RefLocation(QV4::ExecutableCompilationUnit *ref, const QUrl &url, const QV4::CompiledData::Object *obj, const QString &type) - : Location(QQmlSourceLocation(type, obj->location.line, obj->location.column), url), + : Location(QQmlSourceLocation(type, obj->location.line(), obj->location.column()), url), locationType(Creating), sent(false) { unit = ref; diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf index 7737ec55754..820e7c67d2d 100644 --- a/src/qml/doc/qtqml.qdocconf +++ b/src/qml/doc/qtqml.qdocconf @@ -47,11 +47,9 @@ depends += \ qmake \ qtcmake -headerdirs += .. \ - ../../qml +headerdirs += .. -sourcedirs += .. \ - ../../qml +sourcedirs += .. exampledirs += ../../../examples/qml \ ../ \ diff --git a/src/qml/doc/snippets/cmake/qt_target_qml_sources/CMakeLists.txt b/src/qml/doc/snippets/cmake/qt_target_qml_sources/CMakeLists.txt new file mode 100644 index 00000000000..d33f009e380 --- /dev/null +++ b/src/qml/doc/snippets/cmake/qt_target_qml_sources/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.19) +project(qt_target_qml_sources_snippet) + +set(CMAKE_AUTOMOC TRUE) +set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + +# ![0] +set_source_files_properties(nested/way/down/File.qml PROPERTIES + QT_RESOURCE_ALIAS File.qml +) +set_source_files_properties(TemplateFile.qml PROPERTIES + QT_RESOURCE_ALIAS templates/File.qml + QT_QML_SKIP_QMLDIR_ENTRY TRUE + QT_QML_SKIP_QMLLINT TRUE + QT_QML_SKIP_CACHEGEN TRUE +) +set_source_files_properties(FunnySingleton.qml PROPERTIES + QT_QML_SINGLETON_TYPE TRUE +) +qt_add_qml_module(qt_target_qml_sources_example + URI Example + VERSION 2.3 + RESOURCE_PREFIX /my.company.com/imports + QML_FILES + nested/way/down/File.qml + TemplateFile.qml + FunnySingleton.qml +) + +set_source_files_properties(some_old_thing.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "1.1;2.0" + QT_QML_SOURCE_TYPENAME OldThing +) +set_source_files_properties(../../../images/button-types.png PROPERTIES + QT_RESOURCE_ALIAS button-types.png +) +qt_target_qml_sources(qt_target_qml_sources_example + QML_FILES some_old_thing.qml + RESOURCES + ../../../images/button-types.png + doc/README.txt +) +# ![0] diff --git a/src/qml/doc/snippets/cmake/qt_target_qml_sources/FunnySingleton.qml b/src/qml/doc/snippets/cmake/qt_target_qml_sources/FunnySingleton.qml new file mode 100644 index 00000000000..4aec01c32d1 --- /dev/null +++ b/src/qml/doc/snippets/cmake/qt_target_qml_sources/FunnySingleton.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +pragma Singleton +import QtQml + +QtObject {} +//! [0] diff --git a/src/qml/doc/snippets/cmake/qt_target_qml_sources/TemplateFile.qml b/src/qml/doc/snippets/cmake/qt_target_qml_sources/TemplateFile.qml new file mode 100644 index 00000000000..8fc36a40daf --- /dev/null +++ b/src/qml/doc/snippets/cmake/qt_target_qml_sources/TemplateFile.qml @@ -0,0 +1,3 @@ +import QtQml + +QtObject {} diff --git a/src/qml/doc/snippets/cmake/qt_target_qml_sources/doc/README.txt b/src/qml/doc/snippets/cmake/qt_target_qml_sources/doc/README.txt new file mode 100644 index 00000000000..52d51e034d1 --- /dev/null +++ b/src/qml/doc/snippets/cmake/qt_target_qml_sources/doc/README.txt @@ -0,0 +1 @@ +Dummy file, contents not important. diff --git a/src/qml/doc/snippets/cmake/qt_target_qml_sources/nested/way/down/File.qml b/src/qml/doc/snippets/cmake/qt_target_qml_sources/nested/way/down/File.qml new file mode 100644 index 00000000000..8fc36a40daf --- /dev/null +++ b/src/qml/doc/snippets/cmake/qt_target_qml_sources/nested/way/down/File.qml @@ -0,0 +1,3 @@ +import QtQml + +QtObject {} diff --git a/src/qml/doc/snippets/cmake/qt_target_qml_sources/some_old_thing.qml b/src/qml/doc/snippets/cmake/qt_target_qml_sources/some_old_thing.qml new file mode 100644 index 00000000000..8fc36a40daf --- /dev/null +++ b/src/qml/doc/snippets/cmake/qt_target_qml_sources/some_old_thing.qml @@ -0,0 +1,3 @@ +import QtQml + +QtObject {} diff --git a/src/qml/doc/snippets/code/doc_src_qtqml.cmake b/src/qml/doc/snippets/code/doc_src_qtqml.cmake index c2e5d3d9d26..c312201ff89 100644 --- a/src/qml/doc/snippets/code/doc_src_qtqml.cmake +++ b/src/qml/doc/snippets/code/doc_src_qtqml.cmake @@ -1,4 +1,4 @@ #! [0] -find_package(Qt6 COMPONENTS Qml REQUIRED) +find_package(Qt6 REQUIRED COMPONENTS Qml) target_link_libraries(mytarget PRIVATE Qt6::Qml) #! [0] diff --git a/src/qml/doc/snippets/qml/CMakeLists.txt b/src/qml/doc/snippets/qml/CMakeLists.txt new file mode 100644 index 00000000000..24e775341ff --- /dev/null +++ b/src/qml/doc/snippets/qml/CMakeLists.txt @@ -0,0 +1,11 @@ +qt_add_library(extra_module STATIC) +qt_add_qml_module(extra_module + URI "ExtraModule" + VERSION 1.0 + QML_FILES + Extra.qml + SOURCES + extrathing.cpp extrathing.h +) + +add_subdirectory(ExtraModule) diff --git a/src/qml/doc/snippets/qml/MajorProject-CMakeLists.txt b/src/qml/doc/snippets/qml/MajorProject-CMakeLists.txt new file mode 100644 index 00000000000..3e5cbd4565c --- /dev/null +++ b/src/qml/doc/snippets/qml/MajorProject-CMakeLists.txt @@ -0,0 +1,23 @@ + +set_source_files_properties(Thing.qml + PROPERTIES + QT_QML_SOURCE_VERSIONS "1.4;2.0;3.0" +) + +set_source_files_properties(OtherThing.qml + PROPERTIES + QT_QML_SOURCE_VERSIONS "2.2;3.0" +) + +qt_add_qml_module(my_module + URI MyModule + VERSION 3.2 + PAST_MAJOR_VERSIONS + 1 2 + QML_FILES + Thing.qml + OtherThing.qml + OneMoreThing.qml + SOURCES + everything.cpp everything.h +) diff --git a/src/qml/doc/snippets/qml/createQmlObject.qml b/src/qml/doc/snippets/qml/createQmlObject.qml index 8a082a71ded..bfb1d98ca87 100644 --- a/src/qml/doc/snippets/qml/createQmlObject.qml +++ b/src/qml/doc/snippets/qml/createQmlObject.qml @@ -58,9 +58,18 @@ Rectangle { function createIt() { //![0] -var newObject = Qt.createQmlObject('import QtQuick 2.0; Rectangle {color: "red"; width: 20; height: 20}', - parentItem, - "dynamicSnippet1"); +const newObject = Qt.createQmlObject(` + import QtQuick 2.0 + + Rectangle { + color: "red" + width: 20 + height: 20 + } + `, + parentItem, + "myDynamicSnippet" +); //![0] //![destroy] diff --git a/src/qml/doc/snippets/qml/imports/merged-named-imports.qml b/src/qml/doc/snippets/qml/imports/merged-named-imports.qml index 8fab0436bd1..533b22cb938 100644 --- a/src/qml/doc/snippets/qml/imports/merged-named-imports.qml +++ b/src/qml/doc/snippets/qml/imports/merged-named-imports.qml @@ -49,8 +49,8 @@ ****************************************************************************/ //! [imports] -import QtQuick 2.0 as Project -import QtMultimedia 5.0 as Project +import QtQuick as Project +import QtMultimedia as Project Project.Rectangle { width: 100; height: 50 diff --git a/src/qml/doc/snippets/qml/integrating-javascript/includejs/script.mjs b/src/qml/doc/snippets/qml/integrating-javascript/includejs/script.mjs index 86c3e078c89..1326b8c87a1 100644 --- a/src/qml/doc/snippets/qml/integrating-javascript/includejs/script.mjs +++ b/src/qml/doc/snippets/qml/integrating-javascript/includejs/script.mjs @@ -50,8 +50,9 @@ //![0] // script.mjs import { factorial } from "factorial.mjs" +export { factorial } -function showCalculations(value) { +export function showCalculations(value) { console.log( "Call factorial() from script.js:", factorial(value)); diff --git a/src/qml/doc/snippets/qml/myProject-CMakeLists.txt b/src/qml/doc/snippets/qml/myProject-CMakeLists.txt new file mode 100644 index 00000000000..49c63a1513a --- /dev/null +++ b/src/qml/doc/snippets/qml/myProject-CMakeLists.txt @@ -0,0 +1,13 @@ +qt_add_executable(main_program main.cpp) + +qt_add_qml_module(main_program + VERSION 1.0 + URI myProject + QML_FILES + main.qml + SOURCES + onething.cpp onething.h + +) + +target_link_libraries(main_program PRIVATE extra_moduleplugin) diff --git a/src/qml/doc/snippets/qml/myimageprovider.txt b/src/qml/doc/snippets/qml/myimageprovider.txt new file mode 100644 index 00000000000..46057343986 --- /dev/null +++ b/src/qml/doc/snippets/qml/myimageprovider.txt @@ -0,0 +1,15 @@ +qt_add_qml_module(imageproviderplugin + VERSION 1.0 + URI "ImageProvider" + PLUGIN_TARGET imageproviderplugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + CLASS_NAME ImageProviderExtensionPlugin + QML_FILES + AAA.qml + BBB.qml + SOURCES + moretypes.cpp moretypes.h + myimageprovider.cpp myimageprovider.h + plugin.cpp +) diff --git a/src/qml/doc/snippets/qml/plugin.cpp.txt b/src/qml/doc/snippets/qml/plugin.cpp.txt new file mode 100644 index 00000000000..02d1112a4a8 --- /dev/null +++ b/src/qml/doc/snippets/qml/plugin.cpp.txt @@ -0,0 +1,14 @@ +#include +#include + +class ImageProviderExtensionPlugin : public QQmlEngineExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid) +public: + void initializeEngine(QQmlEngine *engine, const char *uri) final + { + Q_UNUSED(uri); + engine->addImageProvider("myimg", new MyImageProvider); + } +}; diff --git a/src/qml/doc/snippets/qtjavascript/integratingjswithcpp/exampleqjsascontainer.cpp b/src/qml/doc/snippets/qtjavascript/integratingjswithcpp/exampleqjsascontainer.cpp new file mode 100644 index 00000000000..0064d66a5c5 --- /dev/null +++ b/src/qml/doc/snippets/qtjavascript/integratingjswithcpp/exampleqjsascontainer.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +//! [qjs-as-container] + + class Cache : public QObject + { + Q_OBJECT + QML_ELEMENT + + public: + Q_INVOKABLE QJSValue lookup(const QString &key) { + if (auto it = m_cache.constFind(key); it != m_cache.constEnd()) { + return *it; // impicit conversion + } else { + return QJSValue::UndefinedValue; // implicit conversion + } + } + + QHash m_cache; + } + +//! [qjs-as-container] diff --git a/src/qml/doc/snippets/qtjavascript/integratingjswithcpp/exampleqjsengine.cpp b/src/qml/doc/snippets/qtjavascript/integratingjswithcpp/exampleqjsengine.cpp new file mode 100644 index 00000000000..59ee30c25f3 --- /dev/null +++ b/src/qml/doc/snippets/qtjavascript/integratingjswithcpp/exampleqjsengine.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![qjs-engine-example] + + QJSEngine engine; + // We create an object with a read-only property whose getter throws an exception + auto val = engine.evaluate("let o = { get f() {throw 42;} }; o"); + val.property("f"); + qDebug() << engine.hasError(); // prints false + + // This time, we construct a QJSManagedValue before accessing the property + val = engine.evaluate("let o = { get f() {throw 42;} }; o"); + QJSManagedValue managed(std::move(val), &engine); + managed.property("f"); + qDebug() << engine.hasError(); // prints true + + QJSValue error = engine.catchError(); + Q_ASSERT(error.toInt(), 42); + +//![qjs-engine-example] diff --git a/src/qml/doc/snippets/qtjavascript/integratingjswithcpp/qjsengine.cpp b/src/qml/doc/snippets/qtjavascript/integratingjswithcpp/qjsengine.cpp new file mode 100644 index 00000000000..e8622b2c500 --- /dev/null +++ b/src/qml/doc/snippets/qtjavascript/integratingjswithcpp/qjsengine.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![qjs-engine] + + QJSEngine engine; + QJSValue object = engine.newObject(); + object.setProperty("num", 42); + QJSValue function = engine.evaluate("(o) => o.num *= 2 "); + QJSValueList args = { object }; + QJSValue result = function.call(args); + QJSValue expected = "84"; + Q_ASSERT(result.equals(expected) && !result.strictlyEquals(expected)); + +//![qjs-engine] + diff --git a/src/qml/doc/src/cmake/cmake-properties.qdoc b/src/qml/doc/src/cmake/cmake-properties.qdoc new file mode 100644 index 00000000000..eccc815eca4 --- /dev/null +++ b/src/qml/doc/src/cmake/cmake-properties.qdoc @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\group cmake-source-file-properties-qtqml +\title CMake Source File Properties in Qt6 Qml + +\l{CMake Commands in Qt6 Qml}{CMake Commands} know about the following CMake +source file properties: + +\sa{CMake Property Reference} +*/ + + +/*! +\page cmake-source-file-property-QT_QML_INTERNAL_TYPE.html +\ingroup cmake-source-file-properties-qtqml + +\title QT_QML_INTERNAL_TYPE +\target cmake-source-file-property-QT_QML_INTERNAL_TYPE + +\summary {Marks a QML file as providing an internal type.} + +\cmakepropertysince 6.2 + +Set this property to \c TRUE to indicate that the \c{.qml} file provides an internal type. + +\sa{qml-source-file-properties}{qt_target_qml_sources} +*/ + + +/*! +\page cmake-source-file-property-QT_QML_SINGLETON_TYPE.html +\ingroup cmake-source-file-properties-qtqml + +\title QT_QML_SINGLETON_TYPE +\target cmake-source-file-property-QT_QML_SINGLETON_TYPE + +\summary {Marks a QML file as providing a singleton type.} + +\cmakepropertysince 6.2 + +A \c{.qml} file that provides a singleton type needs to have its \c QT_QML_SINGLETON_TYPE source +property set to \c TRUE to ensure that the singleton command is written into the +\l{Module Definition qmldir Files}{qmldir} file. +This must be done in addition to the QML file containing the \c {pragma Singleton} statement. + +See \l{qt_target_qml_sources_example}{qt_target_qml_sources()} for an example on +how to set the \c QT_QML_SINGLETON_TYPE property. + +\sa{qml-source-file-properties}{qt_target_qml_sources} +*/ + + +/*! +\page cmake-source-file-property-QT_QML_SKIP_CACHEGEN.html +\ingroup cmake-source-file-properties-qtqml + +\title QT_QML_SKIP_CACHEGEN +\target cmake-source-file-property-QT_QML_SKIP_CACHEGEN + +\summary {Excludes a file from being compiled to byte code.} + +\cmakepropertysince 6.2 + +Set this property to \c TRUE to prevent the \c{.qml} file from being compiled to byte code. +The file will still be added to the \c target as a resource in uncompiled form +(see \l{qmlcachegen-auto}{Caching compiled QML sources}). + +\sa{qml-source-file-properties}{qt_target_qml_sources} +*/ + + +/*! +\page cmake-source-file-property-QT_QML_SKIP_QMLDIR_ENTRY.html +\ingroup cmake-source-file-properties-qtqml + +\title QT_QML_SKIP_QMLDIR_ENTRY +\target cmake-source-file-property-QT_QML_SKIP_QMLDIR_ENTRY + +\summary {Excludes a file from being added as a type to the QML module's typeinfo file.} + +\cmakepropertysince 6.2 + +Set this property to \c TRUE to prevent +the \c{.qml} file from being added as a type to the QML module's typeinfo file +(see \l{qmldir-autogeneration}{Auto-generating \c{qmldir} and typeinfo files}). + +\sa{qml-source-file-properties}{qt_target_qml_sources} +*/ + + +/*! +\page cmake-source-file-property-QT_QML_SKIP_QMLLINT.html +\ingroup cmake-source-file-properties-qtqml + +\title QT_QML_SKIP_QMLLINT +\target cmake-source-file-property-QT_QML_SKIP_QMLLINT + +\summary {Prevents a file from being included in automatic qmllint processing.} + +\cmakepropertysince 6.2 + +Set this property to \c TRUE to prevent the file from being included in +\l{qmllint-auto}{automatic qmllint processing}. + +\sa{qml-source-file-properties}{qt_target_qml_sources} +*/ + + +/*! +\page cmake-source-file-property-QT_QML_SOURCE_TYPENAME.html +\ingroup cmake-source-file-properties-qtqml + +\title QT_QML_SOURCE_TYPENAME +\target cmake-source-file-property-QT_QML_SOURCE_TYPENAME + +\summary {Overrides the type name provided by the file.} + +\cmakepropertysince 6.2 + +Use this property to override the \c QML type name provided by this file. + +\sa{qml-source-file-properties}{qt_target_qml_sources} +*/ + + +/*! +\page cmake-source-file-property-QT_QML_SOURCE_VERSIONS.html +\ingroup cmake-source-file-properties-qtqml + +\title QT_QML_SOURCE_VERSIONS +\target cmake-source-file-property-QT_QML_SOURCE_VERSIONS + +\summary {Specifies a custom set of versions for a type.} + +\cmakepropertysince 6.2 + +When the file needs to provide type entries for a custom set of versions, +for example when the QML types were first introduced in a minor patch +version after the \c{.0} release, specify those versions using this property. + +\sa{qml-source-file-properties}{qt_target_qml_sources} +*/ + + +/*! +\page cmake-source-file-property-QT_QMLTC_FILE_BASENAME.html +\ingroup cmake-source-file-properties-qtqml + +\title QT_QMLTC_FILE_BASENAME +\target cmake-source-file-property-QT_QMLTC_FILE_BASENAME + +\summary {Specifies a non-default .h and .cpp file name.} + +\cmakepropertysince 6.3 +\preliminarycmakeproperty + +Use this property to specify a non-default \c .h and \c .cpp file name, which helps to resolve +conflicting file names. + +\sa{qt_target_compile_qml_to_cpp} +*/ diff --git a/src/qml/doc/src/cmake/cmake-variables.qdoc b/src/qml/doc/src/cmake/cmake-variables.qdoc new file mode 100644 index 00000000000..8f5b87b1cbd --- /dev/null +++ b/src/qml/doc/src/cmake/cmake-variables.qdoc @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page cmake-variable-QT_QML_OUTPUT_DIRECTORY.html +\ingroup cmake-variables +\ingroup cmake-variables-qtqml + +\title QT_QML_OUTPUT_DIRECTORY +\target cmake-variable-QT_QML_OUTPUT_DIRECTORY + +\brief Base output directory below which QML modules will be created by default. + +The \l{qt6_add_qml_module}{qt6_add_qml_module()} command accepts an +\c OUTPUT_DIRECTORY argument which specifies where the QML module's \c qmldir +file, typeinfo file and plugin library will be created. When that argument is +not used, the default value is based on the \c QT_QML_OUTPUT_DIRECTORY variable, +if it is set. If \c QT_QML_OUTPUT_DIRECTORY is not set, the default value +depends on the type of backing target (see the +\l{qt6_add_qml_module#OUTPUT_DIRECTORY}{OUTPUT_DIRECTORY} documentation for +details). + +When \c QT_QML_OUTPUT_DIRECTORY is set, the default output directory will be +formed by appending the QML module's \e{target path} (which is based on the +module URI) to \c QT_QML_OUTPUT_DIRECTORY. +The \c QT_QML_OUTPUT_DIRECTORY will also be added to the import path of the +\c qmllint and \c qmlcachegen tooling targets, allowing them to find other QML +modules under the same base location. This allows the project to use a source +directory structure that doesn't exactly match the URI structure of the QML +modules, or to merge sets of QML modules under a common base point. + +When building QML modules for Android, \c QT_QML_OUTPUT_DIRECTORY is set to +\c{${CMAKE_BINARY_DIR}/android-qml} by default. The Android deployment routine +uses this directory to locate the required QML modules in the build tree. +The output directory of a QML module can also be set for a project or for each +QML module target by the user and it can therefore differ from the Android +default directory. In this case, to successfully deploy the executable on +Android, the \e{target path} of the QML module must be based on the module URI. +Also, the \l{cmake-target-property-QT_QML_IMPORT_PATH}{QT_QML_IMPORT_PATH} +property of the executable target must contain the import paths of all QML +modules that are built in the project tree, have a custom output directory, +and are used by the executable target. This behavior will likely change in +a future Qt version due to improvements in the build system implementation. + +*/ + + diff --git a/src/qml/doc/src/cmake/qt_add_qml_module.qdoc b/src/qml/doc/src/cmake/qt_add_qml_module.qdoc new file mode 100644 index 00000000000..b81a0c80ea5 --- /dev/null +++ b/src/qml/doc/src/cmake/qt_add_qml_module.qdoc @@ -0,0 +1,535 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page qt_add_qml_module.html +\ingroup cmake-commands-qtqml + +\title qt_add_qml_module +\target qt6_add_qml_module + +\brief Defines a QML module. + +\cmakecommandsince 6.2 + +\section1 Synopsis + +\badcode +qt_add_qml_module( + target + URI uri + VERSION version + [PAST_MAJOR_VERSIONS ...] + [STATIC | SHARED] + [PLUGIN_TARGET plugin_target] + [OUTPUT_DIRECTORY output_dir] + [RESOURCE_PREFIX resource_prefix] + [CLASS_NAME class_name] + [TYPEINFO typeinfo] + [IMPORTS ...] + [OPTIONAL_IMPORTS ...] + [DEPENDENCIES ...] + [IMPORT_PATH ...] + [SOURCES ...] + [QML_FILES ...] + [RESOURCES ...] + [OUTPUT_TARGETS out_targets_var] + [DESIGNER_SUPPORTED] + [NO_PLUGIN] + [NO_PLUGIN_OPTIONAL] + [NO_CREATE_PLUGIN_TARGET] + [NO_GENERATE_PLUGIN_SOURCE] + [NO_GENERATE_QMLTYPES] + [NO_GENERATE_QMLDIR] + [NO_LINT] + [NO_CACHEGEN] + [NO_RESOURCE_TARGET_PATH] +) + +\endcode + +\versionlessCMakeCommandsNote qt6_add_qml_module() + +See \l {Building a QML application} and \l {Building a reusable QML module} +for examples that define QML modules. + +\section1 Description + +This command defines a QML module that can consist of C++ sources, \c{.qml} +files, or both. It ensures that essential module details are provided and that +they are consistent. It also sets up and coordinates things like cached +compilation of \c{.qml} sources, resource embedding, linting checks, and +auto-generation of some key module files. + +\section2 Target Structure + +A QML module can be structured in a few different ways. The following scenarios +are the typical arrangements: + +\section3 Separate backing and plugin targets + +This is the recommended arrangement for most QML modules. All of the module's +functionality is implemented in the \e backing target, which is given as the +first command argument. C++ sources, \c{.qml} files, and resources should all +be added to the backing target. The backing target is a library that should be +installed in the same location as any other library defined by the project. + +The source directory structure under which the backing target is created should +match the target path of the QML module (the target path is the module's URI +with dots replaced by forward slashes). If the source directory structure +doesn't match the target path, \c{qt_add_qml_module()} will issue a warning. + +The following example shows a suitable source directory structure for a QML +module with a URI of \c{MyThings.Panels}. The call to \c{qt_add_qml_module()} +would be in the \c{CMakeLists.txt} file shown. + +\badcode +src + +-- MyThings + +-- Panels + +-- CMakeLists.txt +\endcode + +A separate \e plugin target is associated with the QML module. It is used at +runtime to load the module dynamically when the application doesn't already +link to the backing target. The plugin target will also be a library and is +normally installed to the same directory as the module's +\l{Module Definition qmldir Files}{qmldir} file. + +The plugin target should ideally contain nothing more than a trivial +implementation of the plugin class. This allows the plugin to be designated as +optional in the \c qmldir file. Other targets can then link directly to the +backing target and the plugin will not be needed at runtime, which can improve +load-time performance. By default, a C++ source file that defines a minimal +plugin class will be automatically generated and added to the plugin target. +For cases where the QML module needs a custom plugin class implementation, the +\l{NO_GENERATE_PLUGIN_SOURCE} and usually the \l{NO_PLUGIN_OPTIONAL} options +will be needed. + +\note +When using static linking, it migt be necessary to use +\c Q_IMPORT_QML_PLUGIN to ensure that the QML plugin is correctly linked. + +\section3 Plugin target with no backing target + +A QML module can be defined with the plugin target serving as its own backing +target. In this case, the module must be loaded dynamically at runtime and +cannot be linked to directly by other targets. To create this arrangement, +the \c PLUGIN_TARGET keyword must be used, with the \c target repeated as the +plugin target name. For example: + +\badcode +qt_add_qml_module(someTarget + PLUGIN_TARGET someTarget + ... +) +\endcode + +While this arrangement may seem marginally simpler to deploy, a separate +backing target should be preferred where possible due to the potentially better +load-time performance. + +\section3 Executable as a QML module + +An executable target can act as a backing target for a QML module. In this case, +there will be no plugin library, since the QML module will always be loaded +directly as part of the application. The \c{qt_add_qml_module()} command will +detect when an executable is used as the backing target and will automatically +disable the creation of a separate plugin. Do not use any of the options with +\c{PLUGIN} in their name when using this arrangement. + +When an executable is used as the backing target, the source directory structure +is not expected to match the QML module's target path. +See \l{qmlcachegen-auto}{Caching compiled QML sources} for additional target +path differences for compiled-in resources. + + +\target qmldir-autogeneration +\section2 Auto-generating \c{qmldir} and typeinfo files + +By default, a \l{Module Definition qmldir Files}{qmldir} file and a typeinfo +file will be auto-generated for the QML module being defined. The contents of +those files are determined by the various arguments given to this command, as +well as the sources and \c{.qml} files added to the backing target. +The \l OUTPUT_DIRECTORY argument determines where the \c qmldir and typeinfo +files will be written to. If the QML module has a plugin, that plugin will also +be created in the same directory as the \c qmldir file. + +If using a statically built Qt, the backing target's \c{.qml} files will be +scanned during the CMake configure run to determine the imports used by the +module and set up linking relationships. When a \c{.qml} file is added to or +removed from the module, CMake will normally re-run automatically and the +relevant files will be re-scanned, since a \c{CMakeLists.txt} file will have +been modified. During the course of development, an existing \c{.qml} file may +add or remove an import or a type. On its own, this would not cause CMake to +re-run automatically, so you should explicitly re-run CMake to force the +\c qmldir file to be regenerated and any linking relationships to be updated. + +The backing target's C++ sources are scanned at build time to generate a +typeinfo file and a C++ file to register the associated types. The generated +C++ file is automatically added to the backing target as a source. +This requires \c AUTOMOC to be enabled on the target. The project is +responsible for ensuring this, usually by setting the \c CMAKE_AUTOMOC variable +to \c TRUE before calling \c qt_add_qml_module(), or by passing in an existing +target with the \c AUTOMOC target property already set to \c TRUE. It isn't an +error to have \c AUTOMOC disabled on the target, but the project is then +responsible for handling the consequences. This may include having to manually +generate the typeinfo file instead of allowing it to be auto-generated with +missing details, and adding C++ code to register the types. + +Projects should prefer to use the auto-generated typeinfo and \c qmldir files +where possible. They are easier to maintain and they don't suffer from the same +susceptibility to errors that hand-written files do. Nevertheless, for +situations where the project needs to provide these files itself, the +auto-generation can be disabled. The \c NO_GENERATE_QMLDIR option disables the +\c qmldir auto-generation and the \c NO_GENERATE_QMLTYPES option disables the +typeinfo and C++ type registration auto-generation. If the auto-generated +typeinfo file is acceptable, but the project wants to use a different name for +that file, it can override the default name with the \c TYPEINFO option (but +this should not typically be needed). + +\target qmlcachegen-auto +\section2 Caching compiled QML sources + +All \c{.qml}, \c{.js}, and \c{.mjs} files added to the module via the +\c QML_FILES argument will be compiled to bytecode and cached directly in the +backing target. This improves load-time performance of the module. The original +uncompiled files are also stored in the backing target's resources, as these +may still be needed in certain situations by the QML engine. + +The resource path of each file is determined by its path relative to the +current source directory (\c CMAKE_CURRENT_SOURCE_DIR). This resource path is +appended to a prefix formed by concatenating the \l{RESOURCE_PREFIX} and +the target path (but see \l NO_RESOURCE_TARGET_PATH for an exception to this). +Ordinarily, the project should aim to place \c{.qml} files in +the same relative location as they would have in the resources. If the \c{.qml} +file is in a different relative directory to its desired resource path, its +location in the resources needs to be explicitly specified. This is done by +setting the \c QT_RESOURCE_ALIAS source file property, which must be set before +the \c{.qml} file is added. For example: + +\badcode +set_source_files_properties(path/to/somewhere/MyFrame.qml PROPERTIES + QT_RESOURCE_ALIAS MyFrame.qml +) + +qt_add_qml_module(someTarget + URI MyCo.Frames + RESOURCE_PREFIX /my.company.com/imports + QML_FILES + path/to/somewhere/MyFrame.qml + AnotherFrame.qml +) +\endcode + +In the above example, the target path will be \c{MyCo/Frames}. After +taking into account the source file properties, the two \c{.qml} files will be +found at the following resource paths: + +\list +\li \c{/my.company.com/imports/MyCo/Frames/MyFrame.qml} +\li \c{/my.company.com/imports/MyCo/Frames/AnotherFrame.qml} +\endlist + +\target qmllint-auto +\section2 Linting QML sources + +A separate linting target will be automatically created if any \c{.qml} files +are added to the module via the \c QML_FILES keyword, or by a later call to +\l{qt6_target_qml_sources}{qt_target_qml_sources()}. The name of the linting +target will be the \c target followed by \c{_qmllint}. An \c{all_qmllint} +target which depends on all the individual \c{*_qmllint} targets is also +provided as a convenience. + +\target qml-naming-js-files +\section2 Naming conventions for \c{.js} files + +JavaScript file names that are intended to be addressed as components should +start with an uppercase letter. + +Alternatively, you may use lowercase file names and set the source file +property +\l{cmake-source-file-property-QT_QML_SOURCE_TYPENAME}{QT_QML_SOURCE_TYPE_NAME} +to the desired type name. + +\target qml-cmake-singletons +\section2 Singletons + +If a QML module has \c{.qml} files which provide singleton types, these files +need to have their \c QT_QML_SINGLETON_TYPE source property set to \c TRUE, to +ensure that the \singleton command is written into the +\l{Module Definition qmldir Files}{qmldir} file. This must be done in addition +to the QML file containing the \c {pragma Singleton} statement. + +See \l{qt_target_qml_sources_example}{qt_target_qml_sources()} for an example on +how to set the \c QT_QML_SINGLETON_TYPE property. + +\section1 Arguments + +The \c target specifies the name of the backing target for the QML module. +By default, it is created as a shared library if Qt was built as shared +libraries, or as a static library otherwise. This choice can be explicitly +overridden with the \c STATIC or \c SHARED options. + +The plugin target associated with the QML module can be specified using the +\c PLUGIN_TARGET argument. The \c PLUGIN_TARGET can be the same as the backing +\c target, in which case there will be no separate backing target. +If \c PLUGIN_TARGET is not given, it defaults to \c target with \c plugin +appended. For example, a backing target called \c mymodule would have a default +plugin name of \c mymoduleplugin. The plugin target's name will be used to +populate a \c{plugin} line in the generated +\l{Module Definition qmldir Files}{qmldir} file. Therefore, you must not try to +change the plugin's output name by setting target properties like +\c OUTPUT_NAME or any of its related properties. + +The backing \c target and the plugin target (if different) will be created by +the command, unless they already exist. Projects should generally let them be +created by the command so that they are created as the appropriate target type. +If the backing \c target is a static library, the plugin will also be created +as a static library. If the backing \c target is a shared library, the plugin +will be created as a module library. If an existing \c target is passed in and +it is an executable target, there will be no plugin. If you intend to always +link directly to the backing target and do not need a plugin, it can be +disabled by adding the \c NO_PLUGIN option. Specifying both \c NO_PLUGIN and +\c PLUGIN_TARGET is an error. + +In certain situations, the project may want to delay creating the plugin target +until after the call. The \c NO_CREATE_PLUGIN_TARGET option can be given in +that situation. The project is then expected to call +\l{qt6_add_qml_plugin}{qt_add_qml_plugin()} on the plugin target once it has +been created. When \c NO_CREATE_PLUGIN_TARGET is given, \c PLUGIN_TARGET must +also be provided to explicitly name the plugin target. + +Every QML module must define a \c URI. It should be specified in dotted URI +notation, such as \c{QtQuick.Layouts}. Each segment must be a well-formed +ECMAScript Identifier Name. This means, for example, the segments +must not start with a number and they must not contain \e{-} (minus) +characters. As the \c URI will be translated into directory names, you +should restrict it to alphanumeric characters of the latin alphabet, +underscores, and dots. Other QML modules may use this name in +\l{qtqml-syntax-imports.html}{import statements} to import the module. The +\c URI will be used in the \c module line of the generated +\l{Module Definition qmldir Files}{qmldir} file. The \c URI is also used to +form the \e{target path} by replacing dots with forward slashes. + +A QML module must also define a \c VERSION in the form \c{Major.Minor}, where +both \c Major and \c Minor must be integers. An additional \c{.Patch} +component may be appended, but will be ignored. A list of earlier major +versions the module provides types for can also optionally be given after the +\c PAST_MAJOR_VERSIONS keyword (see below). +See \l{qtqml-modules-identifiedmodules.html}{Identified Modules} for further +in-depth discussion of the module URI and version numbering. + +A list of additional major versions the module provides may be given using the +\c PAST_MAJOR_VERSIONS keyword. For each of those versions and each QML file +without a \c QT_QML_SOURCE_VERSIONS setting an additional entry in the +\l{Module Definition qmldir Files}{qmldir} file will be generated to specify +the extra version. Furthermore, the generated module registration code will +register the past major versions using \l{qmlRegisterModule()} on the C++ side. +The module registration code is automatically generated for your QML module, +unless you specify \c{NO_GENERATE_QMLTYPES} (but use of this option is strongly +discouraged). Usage of \c PAST_MAJOR_VERSIONS adds some overhead when your +module is imported. You should increment the major version of your module as +rarely as possible. Once you can rely on all QML files importing this module to +omit the version in their imports, you can safely omit \c{PAST_MAJOR_VERSIONS}. +All the QML files will then import the latest version of your module. If you +have to support versioned imports, consider supporting only a limited number of +past major versions. + +\target RESOURCE_PREFIX +\c RESOURCE_PREFIX is intended to encapsulate a namespace for the project and +will often be the same for all QML modules that the project defines. It should +be chosen to avoid clashing with the resource prefix of anything else used by +the project or likely to be used by any other project that might consume it. +A good choice is to incorporate the domain name of the organization the project +belongs to. A common convention is to append \c{/imports} to the domain name to +form the resource prefix. For example: + +\badcode +qt_add_qml_module(someTarget + RESOURCE_PREFIX /my.company.com/imports + ... +) +\endcode + +\target NO_RESOURCE_TARGET_PATH +When various files are added to the compiled-in resources, they are placed +under a path formed by concatenating the \c RESOURCE_PREFIX and the target path. +For the special case where the backing target is an executable, it may be +desirable to place the module's \c{.qml} files and other resources directly +under the \c RESOURCE_PREFIX instead. This can be achieved by specifying the +\c NO_RESOURCE_TARGET_PATH option, which may only be used if the backing target +is an executable. + +\target OUTPUT_DIRECTORY +\c OUTPUT_DIRECTORY specifies where the plugin library, \c qmldir and typeinfo +files are generated. When this keyword is not given, the default value will be +the target path (formed from the \c URI) appended to the value of the +\l QT_QML_OUTPUT_DIRECTORY variable. +If that variable is not defined, the default depends on the type of backing +target. For executables, the value will be the target path appended to +\c{${CMAKE_CURRENT_BINARY_DIR}}, whereas for other targets it will be just +\c{${CMAKE_CURRENT_BINARY_DIR}}. When the structure of the source tree +matches the structure of QML module target paths (which is highly recommended), +\l QT_QML_OUTPUT_DIRECTORY often isn't needed. In order to match the structure +of the target paths, you have to call your directories \e exactly like the +segments of your module URI. For example, if your module URI is +\c{MyUpperCaseThing.mylowercasething}, you need to put this in a directory +called \c{MyUpperCaseThing/mylowercasething/}. + +The need for specifying the \c OUTPUT_DIRECTORY keyword should be rare, but if +it is used, it is likely that the caller will also need to add to the +\l IMPORT_PATH to ensure that \l{qmllint-auto}{linting}, +\l{qmlcachegen-auto}{cached compilation} of qml sources and +\l{qt6_import_qml_plugins}{automatic importing} of plugins in static builds all +work correctly. + +\target NO_GENERATE_PLUGIN_SOURCE +By default, \c{qt_add_qml_module()} will auto-generate a \c{.cpp} file that +implements the plugin class named by the \c CLASS_NAME argument. The generated +\c{.cpp} file will be automatically added to the plugin target as a source file +to be compiled. If the project wants to provide its own implementation of the +plugin class, the \c NO_GENERATE_PLUGIN_SOURCE option should be given. Where no +\c CLASS_NAME is provided, it defaults to the \c URI with dots replaced by +underscores, then \c Plugin appended. Unless the QML module has no plugin, the +class name will be recorded as a \c classname line in the generated +\l{Module Definition qmldir Files}{qmldir} file. You need to add any C++ files +with custom plugin code to the plugin target. Since the plugin then likely +contains functionality that goes beyond simply loading the backing library, you +will probably want to add \l{NO_PLUGIN_OPTIONAL}, too. Otherwise the QML engine +may skip loading the plugin if it detects that the backing library is already +linked. + +\target NO_PLUGIN +If the \c NO_PLUGIN keyword is given, then no plugin will be built. This +keyword is thus incompatible with all the options that customize the plugin +target, in particular \l{NO_GENERATE_PLUGIN_SOURCE}, \l{NO_PLUGIN_OPTIONAL}, +\l{PLUGIN_TARGET}, \l{NO_CREATE_PLUGIN_TARGET}, and \l{CLASS_NAME}. If you do +not provide a plugin for your module, it will only be fully usable if its +backing library has been linked into the executable. It is generally hard to +guarantee that a linker preserves the linkage to a library it considers unused. + +\target NO_PLUGIN_OPTIONAL +If the \c NO_PLUGIN_OPTIONAL keyword is given, then the plugin is recorded in +the generated \c qmldir file as non-optional. If all of a QML module's +functionality is implemented in its backing target and the plugin target is +separate, then the plugin can be optional, which is the default and recommended +arrangement. The auto-generated plugin source file satisfies this requirement. +Where a project provides its own \c{.cpp} implementation for the plugin, that +would normally mean the \c NO_PLUGIN_OPTIONAL keyword is also needed because +the plugin will almost certainly contain functionality that the QML module +requires. + +Type registration is automatically performed for the backing target's C++ +sources that are processed by AUTOMOC. This will generate a typeinfo file in the +\l{OUTPUT_DIRECTORY}{output directory}, the file name being the \c target name +with \c{.qmltypes} appended. This file name can be changed using the +\c TYPEINFO option if desired, but this should not normally be necessary. +The file name is also recorded as a \c typeinfo entry in the generated +\l{Module Definition qmldir Files}{qmldir} file. Automatic type registration +can be disabled using the \c NO_GENERATE_QMLTYPES option, in which case no +typeinfo file will be generated, but the project will still be expected to +generate a typeinfo file and place it in the same directory as the generated +\c qmldir file. + +\c IMPORTS provides a list of other QML modules that this module imports. Each +module listed here will be added as an \c{import} entry in the generated +\l{Module Definition qmldir Files}{qmldir} file. If a QML file imports the +this module, it also imports all the modules listed under \c{IMPORTS}. +Optionally, a version can be specified by appending it after a slash, such as +\c{QtQuick/2.0}. Omitting the version will cause the greatest version available +to be imported. You may only specify the major version, as in \c{QtQuick/2}. In +that case the greatest minor version available with the given major version will +be imported. Finally, \c{auto} may be given as version (\c{QtQuick/auto}). If +\c{auto} is given, the version that the current module is being imported with is +propagated to the module to be imported. Given an entry \c{QtQuick/auto} in a +module \c{YourModule}, if a QML file specifies \c{import YourModule 3.14}, this +results in importing version \c{3.14} of \c{QtQuick}. For related modules that +follow a common versioning scheme, you should use \c{auto}. + +\c OPTIONAL_IMPORTS provides a list of other QML modules that this module +\e may import at run-time. These are not automatically imported by the QML +engine when importing the current module, but rather serve as hints to tools +like \c qmllint. Versions can be specified in the same way as for \c IMPORTS. +Each module listed here will be added as an \c{optional import} entry in the +generated \l{Module Definition qmldir Files}{qmldir} file. + +\c DEPENDENCIES provides a list of other QML modules that this module depends +on, but doesn't necessarily import. It would typically be used for dependencies +that only exist at the C++ level, such as a module registering a class to QML +which is a subclass of one defined in another module. The module version of the +dependencies must be specified along with the module name, in the same form as +used for \c IMPORTS and \c OPTIONAL_IMPORTS. Each module listed here will be +added as a \c{depends} entry in the generated +\l{Module Definition qmldir Files}{qmldir} file. + +\target IMPORT_PATH +\c IMPORT_PATH can be used to add to the search paths where other QML modules +that this one depends on can be found. The other modules must have their +\c qmldir file under their own target path below one of the search paths. + +\c SOURCES specifies a list of non-QML sources to be added to the backing +target. It is provided as a convenience and is equivalent to adding the sources +to the backing target with the built-in \c{target_sources()} CMake command. + +\c QML_FILES lists the \c{.qml}, \c{.js} and \c{.mjs} files for the module. +These will be automatically \l{qmlcachegen-auto}{compiled into bytecode} and +embedded in the backing target unless the \c NO_CACHEGEN option is given. +The uncompiled file is always stored in the embedded resources of the backing +target, even if \c NO_CACHEGEN is specified. Unless the \c NO_LINT option is +given, the uncompiled files will also be +\l{Linting QML sources}{processed by \c qmllint} via a separate custom build +target. The files will also be used to populate type information in the +generated \l{Module Definition qmldir Files}{qmldir} file. +See \l{qt6_target_qml_sources}{qt_target_qml_sources()} for further details on +the source file properties that can be set on these files or if files need to +be added to the backing target after this command has been called. + +\c RESOURCES lists any other files needed by the module, such as images +referenced from the QML code. These files will be added as compiled-in +resources (see \l RESOURCE_PREFIX for an explanation of the base point they +will be located under). If needed, their relative location can +be controlled by setting the \c QT_RESOURCE_ALIAS source property, just as for +\c{.qml} files (see \l{qmlcachegen-auto}{Caching compiled QML sources}). + +\c NO_GENERATE_QMLDIR can be given to disable the automatic generation of the +\c qmldir file. This should normally be avoided, but for cases where the +project needs to provide its own \c qmldir file, this option can be used. + +If the backing target is a static library and that static library will be +installed, \c OUTPUT_TARGETS should be given to provide a variable in which to +store a list of additional targets that will also need to be installed. +These additional targets are generated internally by \c{qt_add_qml_module()} +and are referenced by the backing target's linking requirements as part of +ensuring that resources are set up and loaded correctly. + +The \c DESIGNER_SUPPORTED keyword should be given if the QML module supports +Qt Quick Designer. When present, the generated \c qmldir file will contain +a \c designersupported line. See \l{Module Definition qmldir Files} for how +this affects the way Qt Quick Designer handles the plugin. + +*/ diff --git a/src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc b/src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc new file mode 100644 index 00000000000..fe63d678c7d --- /dev/null +++ b/src/qml/doc/src/cmake/qt_add_qml_plugin.qdoc @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page qt_add_qml_plugin.html +\ingroup cmake-commands-qtqml + +\title qt_add_qml_plugin +\target qt6_add_qml_plugin + +\brief Defines a plugin associated with a QML module. + +\section1 Synopsis + +\badcode +qt_add_qml_plugin( + target + [BACKING_TARGET backing_target] + [STATIC | SHARED] + [OUTPUT_DIRECTORY] + [URI] + [CLASS_NAME] + [NO_GENERATE_PLUGIN_SOURCE] +) + +\endcode + +\versionlessCMakeCommandsNote qt6_add_qml_plugin() + +\section1 Description + +This command creates the plugin target associated with a QML module. It would +normally be called internally by \l{qt6_add_qml_module}{qt_add_qml_module()} to +create or update the plugin associated with its backing target. You should not +call this function directly unless you have special circumstances that require +you to create the target in a special way. + +The documentation for \l{qt6_add_qml_module}{qt_add_qml_module()} describes +different structural patterns for how the CMake targets associated with a QML +module can be arranged. Note that even if the QML module has no separate backing +target and all functionality is implemented directly in the plugin (not the +recommended arrangement), you should still call +\l{qt6_add_qml_module}{qt_add_qml_module()} rather than \c{qt_add_qml_plugin()}. + + +\section1 Arguments + +The \c target specifies the name of the target to use for the QML plugin. If it +does not already exist, it will be created. + +\c BACKING_TARGET specifies the name of the backing target that the plugin is +associated with. The backing target can be the same as the plugin \c target, in +which case there is only the one merged target, but this is not typically +recommended (see \l{qt6_add_qml_module}{qt_add_qml_module()} for more +information). \c BACKING_TARGET should always be provided unless there are +special circumstances that require the plugin target to be created before the +backing target. If \c BACKING_TARGET is not provided, a \c URI option must be +given. + +By default, the plugin is created with a type that is compatible with the +backing target. If the backing target is a static library, the plugin will also +be created as a static library. If the backing target is a shared library, the +plugin will be created as a module library. Where no backing target is +provided or the plugin has no separate backing target, the plugin type can be +specified with either the \c STATIC or \c SHARED keywords. If the plugin type +is not determined by any of the preceding conditions, a static plugin will be +created if Qt was built as static libraries, or a module library plugin +otherwise. + +\c OUTPUT_DIRECTORY specifies the directory where the plugin library will be +created. It should always be the same location as the QML module's +\l{Module Definition qmldir Files}{qmldir} file. When \c OUTPUT_DIRECTORY is +not given, it will be obtained from information stored on the +\c BACKING_TARGET, where available. Note that this could be different to the +directory of the backing target's own library. If an output directory cannot be +obtained from the backing target, the \c CMAKE_CURRENT_BINARY_DIR is used by +default. + +\c URI declares the module identifier of the QML module this plugin is +associated with. The module identifier is the (dotted URI notation) identifier +for the QML module. If \c URI is not given, a \c BACKING_TARGET must be +provided and the backing target must have its URI recorded on it (typically by +an earlier call to \l{qt6_add_qml_module}{qt_add_qml_module()}). + +Each plugin should have a C++ class that registers the module with the QML +engine. By default, \c{qt_add_qml_plugin()} auto-generates the sources for this +C++ class, and adds them to the \c{target}'s list of sources. The generated +plugin class satisfies the requirements of the plugin being optional (see +\l{Module Definition qmldir Files}). The class name is determined as follows: + +\list + \li If \c CLASS_NAME has been given, it will be used. It must match the name + used in the QML module's \c qmldir file. + \li If \c CLASS_NAME has not been given, but \c BACKING_TARGET has, the C++ + class name will be taken from details recorded on that backing target. + Those details are usually recorded by an earlier call to + \l{qt_add_qml_module}{qt_add_qml_module()}, and they will match the name + used in the generated \c qmldir file. This is the recommended way to + provide the class name in most scenarios. + \li If the class name still cannot be determined, it is set to the module's + URI with dots replaced by underscores, and \c Plugin appended. +\endlist + +Some plugins may require the plugin class to be written manually. For example, +the plugin may need to perform additional initialization or register things +not implemented by the default plugin class. In such cases, the +\c NO_GENERATE_PLUGIN_SOURCE option can be given. You are then responsible for +writing your own C++ plugin class and adding it to the \c target. Note that if +you need to write your own plugin class, it is very unlikely that the plugin +can be optional. This in turn means that the \c NO_PLUGIN_OPTIONAL keyword +should be included in the call to \l{qt_add_qml_module}{qt_add_qml_module()} +when defining the QML module, or else the generated \c qmldir file will be +incorrect. Make sure your plugin class uses the same class name as determined +from the logic just above. + +*/ diff --git a/src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc b/src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc new file mode 100644 index 00000000000..249ae57d798 --- /dev/null +++ b/src/qml/doc/src/cmake/qt_import_qml_plugins.qdoc @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page qt_import_qml_plugins.html +\ingroup cmake-commands-qtqml + +\title qt_import_qml_plugins +\target qt6_import_qml_plugins + +\brief Ensures QML plugins needed by a target are imported for static builds. + +\cmakecommandsince 6.0 + +\section1 Synopsis + +\badcode +qt_import_qml_plugins(target) +\endcode + +\versionlessCMakeCommandsNote qt6_import_qml_plugins() + +\section1 Description + +\note This command only has any effect if Qt was built statically. If called + using a non-static Qt, it will do nothing and return immediately. + +\c{qt_import_qml_plugins()} runs \c{qmlimportscanner} on the \c target +immediately as part of the call. It finds the static QML plugins used by the +\c target and links it to those plugins so that they are part of the executable +or shared library that \c target represents. The search follows QML module +imports recursively. + +Because the call to \c{qmlimportscanner} runs at configure time rather than +generation or build time, \c{qt_import_qml_plugins()} only knows about the +information recorded on the \c target (or other targets it links or imports) +at the time \c{qt_import_qml_plugins()} is called. Any linking or import +relationships added after this call will not be considered. Therefore, this +command should be called as late as possible in the \c{target}'s directory +scope so that all the linking and import relationships are known. + +If \c target was created using \l{qt6_add_executable}{qt_add_executable()}, +projects would not normally need to call \c{qt_import_qml_plugins()} directly. +When Qt is built statically, the command is called automatically as part of +\l{qt6_add_executable#Finalization}{target finalization} if \c target links to +the Qml library. By default, this finalization occurs at the end of the same +directory scope in which the \c target was created. If the \c target was +created using the standard CMake \c{add_executable()} command instead, the +project needs to call \c{qt_import_qml_plugins()} itself. + +\sa Q_IMPORT_QML_PLUGIN + +*/ diff --git a/src/qml/doc/src/cmake/qt_target_qml_sources.qdoc b/src/qml/doc/src/cmake/qt_target_qml_sources.qdoc new file mode 100644 index 00000000000..dc1178be292 --- /dev/null +++ b/src/qml/doc/src/cmake/qt_target_qml_sources.qdoc @@ -0,0 +1,228 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page qt_target_qml_sources.html +\ingroup cmake-commands-qtqml + +\title qt_target_qml_sources +\target qt6_target_qml_sources + +\brief Add qml files and resources to an existing QML module target. + +\cmakecommandsince 6.2 + +\section1 Synopsis + +\badcode +qt_target_qml_sources( + target + [QML_FILES ...] + [RESOURCES ...] + [PREFIX resource_path] + [OUTPUT_TARGETS out_targets_var] + [NO_LINT] + [NO_CACHEGEN] + [NO_QMLDIR_TYPES] +) + +\endcode + +\versionlessCMakeCommandsNote qt6_target_qml_sources() + +\section1 Description + +\note This command requires CMake 3.19 or later. + +\c{qt_target_qml_sources()} provides the ability to add more files to a QML +module after \l{qt6_add_qml_module}{qt_add_qml_module()} has been called. +Typically, you pass the set of \c{.qml} files and resources to +\l{qt6_add_qml_module}{qt_add_qml_module()} directly, but in some cases, it may +be desirable, or even necessary, to add files after +\l{qt6_add_qml_module}{qt_add_qml_module()} has been called. For example, you +may wish to add files conditionally based on an \c{if} statement expression, +or from subdirectories that will only be added if certain criteria are met. +You might want to add a set of files with different characteristics to the +others, such as a different resource prefix, or with linting and bytecode +compilation disabled. The \c{qt_target_qml_sources()} command enables these +scenarios. + +\section1 Arguments + +The \c target must be the backing target of a QML module, or if the QML module +has no separate backing target, it must be the module's plugin target. + +\c QML_FILES is a list of \c{.qml}, \c{.js} and \c{.mjs} files to be added to +the QML module. This option has exactly the same effect as the \c QML_FILES +option of the \l{qt6_add_qml_module}{qt_add_qml_module()} command, including +the automatic compilation to bytecode and lint processing. + +The \c NO_CACHEGEN and \c NO_LINT options also have the same effect as they do +for \l{qt6_add_qml_module}{qt_add_qml_module()}. They disable the bytecode +compilation and lint processing for the files listed with \c QML_FILES. This +behavior can also be specified just for individual files using +\l{qml-source-file-properties}{source file properties}. + +\c NO_QMLDIR_TYPES prevents the \c QML_FILES from being added as types to the +generated \l{qmldir-autogeneration}{qmldir} file. + +\c RESOURCES has exactly the same effect as the \c RESOURCES option of the +\l{qt6_add_qml_module}{qt_add_qml_module()} command. It provides a list of +files to be added to the \c target as ordinary resources. These files are +typically things like images, shaders, etc. that the QML code refers to in some +way. + +\target PREFIX +Files added to the module via \c QML_FILES or \c RESOURCES will be placed under +the same resource prefix and target path as they would if they were added by the +\l{qt6_add_qml_module}{qt_add_qml_module()} command. This can be overridden by +providing a different location with the \c PREFIX option. The value following +the \c PREFIX keyword will be used directly, without appending any target path. +The final resource path of each file will be the prefix, plus the path of the +file below the \c CMAKE_CURRENT_SOURCE_DIR. The \l{QT_RESOURCE_ALIAS} source +file property can also be used to override that relative path. + +\badcode +qt_add_qml_module(backing + URI Example + VERSION 1.0 + RESOURCE_PREFIX /my.company.com/imports +) + +qt_target_qml_sources(backing + QML_FILES special/First.qml + RESOURCES icons/logo.png +) + +qt_target_qml_sources(backing + PREFIX /other.company.com/debugging + QML_FILES Inspector.qml +) +\endcode + +In the above example, the \c backing target's resources will end up with the +following contents: + +\list +\li \c{/my.company.com/imports/Example/special/First.qml} +\li \c{/my.company.com/imports/Example/icons/logo.png} +\li \c{/other.company.com/debugging/Inspector.qml} +\endlist + +\c OUTPUT_TARGETS is also analogous to the same option for +\l{qt6_add_qml_module}{qt_add_qml_module()}. Use it to specify the name of a +variable in which to store any additional targets created for static builds. +If the \c target will be installed, these additional targets will also need to +be installed to satisfy linking requirements. + +\target qml-source-file-properties +\section1 Source File Properties + +A number of source file properties can be used to influence how each individual +\c{.qml} file is treated at various points in the QML module processing. These +override any higher level options specified in calls to +\c{qt_target_qml_sources()} or \l{qt6_add_qml_module}{qt_add_qml_module()}. +All of these properties need to be set before the files are added with either +of those two commands. + +\c QT_QML_SKIP_QMLLINT can be set to \c TRUE on a source file to prevent it +from being included in the \l{qmllint-auto}{automatic qmllint processing}. +By default, all \c{.qml} files will be included in the target's lint run, but +this option can be used to exclude specific files. + +\c QT_QML_SKIP_CACHEGEN does a similar thing, preventing a source file from +being compiled to byte code when this property is set to \c TRUE. Note that the +file will still be added to the \c target as a resource in uncompiled form +(see \l{qmlcachegen-auto}{Caching compiled QML sources}). + +Set the \c QT_QML_SKIP_QMLDIR_ENTRY source file property to \c TRUE to prevent +that \c{.qml} file from being added as a type to the QML module's typeinfo file +(see \l{qmldir-autogeneration}{Auto-generating \c{qmldir} and typeinfo files}). +This would normally only be used for a file that does not expose a public type, +such as a private JS file. + +By default, when \l{qmldir-autogeneration}{generating the \c qmldir file}, a +single type entry will be generated for each \c{.qml} file that provides a type. +It will be given a version number \c{X.0} where \c{X} is the major version of +the QML module. If the QML module has any \c PAST_MAJOR_VERSIONS set, the same +pattern will be applied to those too, appending \c{X.0} for each past major +version \c{X}. For situations where a file needs to provide type entries for +a different set of versions instead (e.g. it was first added in a minor patch +version after the \c{.0} release), specify those versions in the source file's +\c QT_QML_SOURCE_VERSIONS property. One type entry will be created for each +version. + +If the type that a \c{.qml} file provides is a singleton, set its +\c QT_QML_SINGLETON_TYPE property to \c TRUE. Similarly, the file's +\c QT_QML_INTERNAL_TYPE source property can be set to \c TRUE to indicate that +the type it provides is an internal one. The name of the type itself can also +be overridden using the \c QT_QML_SOURCE_TYPENAME property. All three of these +will be reflected in the file's type entries in the +\l{qmldir-autogeneration}{generated \c qmldir file}. + +\target QT_RESOURCE_ALIAS +All files listed with \c QML_FILES or \c RESOURCES will be added to the +\c{target}'s resources. Their location in the resources consists of a base point +and a relative path. The base point defaults to the concatenation of the QML +module's resource prefix and its target path, but these can be overridden with +the \l PREFIX argument. The relative path will default to the path of the file +relative to the \c{target}'s \c SOURCE_DIR target property. This relative path +can be overridden by setting the \c QT_RESOURCE_ALIAS property on the source +file. This is commonly used to collect files from different directories and +have them appear in the resources under a common location. + +\target qt_target_qml_sources_example +\snippet cmake/qt_target_qml_sources/CMakeLists.txt 0 + +In the above example, the \c qt_target_qml_sources_example target's resources +will end up with the following contents: + +\list +\li \c{/my.company.com/imports/Example/File.qml} +\li \c{/my.company.com/imports/Example/FunnySingleton.qml} +\li \c{/my.company.com/imports/Example/templates/File.qml} +\li \c{/my.company.com/imports/Example/some_old_thing.qml} +\li \c{/my.company.com/imports/Example/button-types.png} +\li \c{/my.company.com/imports/Example/doc/README.txt} +\endlist + +The generated \c qmldir file will contain the following type entries: + +\badcode +File 2.0 File.qml +singleton FunnySingleton 2.0 FunnySingleton.qml +OldThing 1.1 some_old_thing.qml +OldThing 2.0 some_old_thing.qml +\endcode + +\note The source FunnySingleton.qml file must already contain +the \c {pragma Singleton} statement. Setting the \c QT_QML_SINGLETON_TYPE source +property does not automatically generate the pragma. + +\snippet cmake/qt_target_qml_sources/FunnySingleton.qml 0 + +*/ diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc index 969bf4f7c03..d4fe08e37df 100644 --- a/src/qml/doc/src/cppintegration/definetypes.qdoc +++ b/src/qml/doc/src/cppintegration/definetypes.qdoc @@ -97,15 +97,18 @@ Types to QML} explains, the properties, methods and signals of any QObject-derived class are accessible from QML code. To register a QObject-derived class as an instantiable QML object type, add -\c QML_ELEMENT or \c QML_NAMED_ELEMENT() to the class declaration and +\c QML_ELEMENT or \c QML_NAMED_ELEMENT() to the class declaration. You +also need to make adjustments in the build system. For qmake, add \c {CONFIG += qmltypes}, a \c {QML_IMPORT_NAME}, and a -\c QML_IMPORT_MAJOR_VERSION to your project file. This will register the class -into the type namespace under the given major version, using either the class -name or an explicitly given name as QML type name. The minor version(s) will -be derived from any revisions attached to properties, methods, or signals. The -default minor version is \c 0. You can explicitly restrict the type to be -available only from specific minor versions by adding the -\c QML_ADDED_IN_MINOR_VERSION() macro to the class declaration. Clients can +\c QML_IMPORT_MAJOR_VERSION to your project file. For CMake, the file containing +the class should be part of a target set-up with +\l{qt_add_qml_module}{qt_add_qml_module()}. +This will register the class into the type namespace under the given major version, +using either the class name or an explicitly given name as QML type name. The +minor version(s) will be derived from any revisions attached to properties, +methods, or signals. The default minor version is \c 0. You can explicitly +restrict the type to be available only from specific minor versions by adding +the \c QML_ADDED_IN_MINOR_VERSION() macro to the class declaration. Clients can import suitable versions of the namespace in order to use the type. For example, suppose there is a \c Message class with \c author and @@ -127,26 +130,52 @@ This type can be registered by adding an appropriate type namespace and version number to the project file. For example, to make the type available in the \c com.mycompany.messaging namespace with version 1.0: -\code -CONFIG += qmltypes -QML_IMPORT_NAME = com.mycompany.messaging -QML_IMPORT_MAJOR_VERSION = 1 -\endcode +\if defined(onlinedocs) + \tab {build-qt-app}{tab-cmake}{CMake}{selected} + \tab {build-qt-app}{tab-qmake}{qmake}{} + \tabcontent {tab-cmake} + \else + \section3 Using CMake +\endif + \badcode + qt_add_qml_module(messaging + URI com.mycompany.messaging + VERSION 1.0 + SOURCES + message.cpp message.h + ) + \endcode +\if defined(onlinedocs) + \endtabcontent + \tabcontent {tab-qmake} +\else + \section3 Using QMake +\endif + \code + CONFIG += qmltypes + QML_IMPORT_NAME = com.mycompany.messaging + QML_IMPORT_MAJOR_VERSION = 1 + \endcode + + If the header the class is declared in is not accessible from your project's + include path, you may have to amend the include path so that the generated + registration code can be compiled. + + \code + INCLUDEPATH += com/mycompany/messaging + \endcode +\if defined(onlinedocs) + \endtabcontent +\endif -If the header the class is declared in is not accessible from your project's -include path, you may have to amend the include path so that the generated -registration code can be compiled: -\code -INCLUDEPATH += com/mycompany/messaging -\endcode The type can be used in an \l{qtqml-syntax-basics.html#object-declarations} {object declaration} from QML, and its properties can be read and written to, as per the example below: \qml -import com.mycompany.messaging 1.0 +import com.mycompany.messaging Message { author: "Amelie" @@ -334,10 +363,9 @@ classes directly, if this is either not possible or is complicated by some other concerns, extension objects allow limited extension possibilities without direct modifications. -\e{Extension objects} add additional properties to an existing type. Extension -objects can only add properties, not signals or methods. An extended type -definition allows the programmer to supply an additional type, known as the -\e{extension type}, when registering the class. The properties are transparently +\e{Extension objects} add additional properties to an existing type. An extended +type definition allows the programmer to supply an additional type, known as the +\e{extension type}, when registering the class. Its members are transparently merged with the original target class when used from within QML. For example: \snippet referenceexamples/extended/example.qml 0 @@ -619,6 +647,8 @@ Item { } \endqml +This is commonly referred to as "on" syntax. + Clients can register their own property value source types, but currently not property value write interceptors. diff --git a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc index 6e6d067ba66..b5f06769208 100644 --- a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc +++ b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -397,13 +397,11 @@ plugin with the Qt meta object system. Here is the \c ChartsPlugin definition in \c chartsplugin.h: -\snippet tutorials/extending-qml/chapter6-plugins/import/chartsplugin.h 0 +\snippet tutorials/extending-qml/chapter6-plugins/Charts/chartsplugin.h 0 -Then, we write a \c .pro project file that defines the project as a plugin library -and specifies with DESTDIR that library files should be built into a \c {../Charts} -directory. +Then, we write a \c .pro project file that defines the project as a plugin library. -\quotefile tutorials/extending-qml/chapter6-plugins/import/import.pro +\quotefile tutorials/extending-qml/chapter6-plugins/Charts/Charts.pro When building this example on Windows or Linux, the \c Charts directory will be located at the same level as the application that uses our new import module. @@ -413,7 +411,7 @@ plugin binary is copied to \c Contents/PlugIns in the the application bundle; this path is set in \c {chapter6-plugins/app.pro}: \quotefromfile tutorials/extending-qml/chapter6-plugins/app.pro -\skipto osx +\skipto macos \printuntil } To account for this, we also need to add this location as a @@ -432,16 +430,16 @@ to the same location as the plugin binary. The \c qmldir file declares the module name and the plugin that is made available by the module: -\quotefile tutorials/extending-qml/chapter6-plugins/import/qmldir +\quotefile tutorials/extending-qml/chapter6-plugins/Charts/qmldir Now we have a QML module that can be imported to any application, provided that the QML engine knows where to find it. The example contains an executable that loads \c app.qml, which uses the \c {import Charts 1.0} statement. Alternatively, you can -load the QML file using the \l{Prototyping with qmlscene}{qmlscene tool}, setting the -import path to the current directory so that it finds the \c qmldir file: +load the QML file using the \l {Prototyping with the QML Runtime Tool}{qml tool}, +setting the import path to the current directory so that it finds the \c qmldir file: \code - qmlscene -I . app.qml + qml -I . app.qml \endcode The module "Charts" will be loaded by the QML engine, and the types provided by that diff --git a/src/qml/doc/src/cppintegration/integrating-with-js-values-from-cpp.qdoc b/src/qml/doc/src/cppintegration/integrating-with-js-values-from-cpp.qdoc new file mode 100644 index 00000000000..64342fe1f82 --- /dev/null +++ b/src/qml/doc/src/cppintegration/integrating-with-js-values-from-cpp.qdoc @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2012 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ +/*! +\page qtqml-integrating-with-js-values-from-cpp.html +\title Integrating with JavaScript values from C++ +\brief Description of how to load and access JavaScript from C++ code. + +The following classes can be used to load and access JavaSript from C++ code: + +\list + + \li \l QJSValue, which acts as a container for Qt/JavaScript data types. + \li \l QJSManagedValue, which represents a value on the JavaScript heap + belonging to a \l QJSEngine. + \li \l QJSPrimitiveValue, which operates on primitive types in JavaScript semantics. +\endlist + +Use QJSValue to transfer values to and from the engine, and use QJSManagedValue +to interact with JavaScript values. Only use QJSPrimitiveValues if you have to +emulate the semantics of JS primitive values in C++. + +\table + \header + \li QJSValue + \li QJSManagedValue + \li QJSPrimitiveValue + \row + \li Persistently store values + \li Short lived + \li Short lived + \row + \li Transport values to/from engine + \li Access properties + \li Only Primitives + \row + \li + \li Call methods + \li Basic arithmetic and comparison +\endtable + +\section1 QJSValue as a Container Type + +\l QJSValue stores the Qt/JavaScript data types supported in ECMAScript including +function, array and arbitrary object types as well as anything supported by +QVariant. As a container, it can be used to pass values to and receive values +from a QJSEngine. + +\snippet qtjavascript/integratingjswithcpp/exampleqjsascontainer.cpp qjs-as-container + +In case of a cache miss, \c undefined is returned. Otherwise, the cached value is +returned. Note that implicit conversions (from QString and QJSValue::SpecialValue respectively) +occur when the value is returned. + +QJSValue also has an API to interact with the contained value, but using +QJSManagedValue is recommended. + +\section1 Primitive and Managed Values + +QJSValue and QJSManagedValue store values that can be either managed or primitive. +In QML’s JS engine, a managed value can be thought of as a pointer to some data +structure on the heap, whose memory is managed by the engine’s garbage collector. +The actual content of primitive values is stored directly, using a technique +called NaN-boxing that enables you to represent a NaN-value in multiple ways, even +though only two are actually needed; one for signalling and one for quiet NaN-value. + +\table +\header + \li Primitive Values + \li Managed Values +\row + \li int + \li Function +\row + \li double + \li Array +\row + \li undefined + \li QVariant +\row + \li null + \li string object +\row + \li QString + \li +\endtable + +A pointer to the engine can be obtained from a managed value, but not from a +primitive one. When using QJSValue for its JavaScript API, you need access +to the engine to evaluate JavaScript. For example, to run the \c call(args) function, +you have to interpret it in the engine. This works, as the function is a managed +value, and you can obtain the engine from it. + +Similarly, where the engine is needed when you call a function or +access a property on a primitive number or string. Whenever you call a method on +a primitive, an instance of its corresponding non-primitive objects is created. +This is referred as boxing. When you write \c (42).constructor, that is equivalent +to \c (new Number(42)).constructor, and it returns the constructor method of the +global number object. Accordingly, if you write \c QJSValue(42).property("constructor"), +you would expect to obtain a QJSValue containing that function. However, what you +get is instead a QJSValue containing \c undefined. + +The QJSValue that you constructed contains only a primitive value, and thus you have +no way to access the engine. You also can’t simply hardcode the property lookup +for primitive values in QJSEngine, as in one engine you might set +\e {Number.prototype.constructor.additionalProperty = "the Spanish Inquisition"} +whereas in another \e {Number.prototype.constructor.additionalProperty = 42}. +The end result would then clearly be unexpected. + +To ensure that property accesses always work, you would need to always store boxed +values in QJSValue or store an additional pointer to the engine. + +However, this would be incompatible with how QJSValue is currently used, lead to +pointless JS heap allocations when passing around primitives, and increase the +size needed to store a QJSValue. Therefore, you should use \l QJSValue only for +storage and \l QJSManagedValue to obtain the engine. + +\section1 QJSManagedValue + +QJSManagedValue is similar to QJSValue, with a few differences: + +\list +\li The constructors (except for the default and move constructor2) require + passing a QJSEngine pointer. +\li Methods like \c deleteProperty and \l isSymbol are added. +\li If QJSManagedValue methods encounter an exception, they leave it intact. +\endlist + +To obtain the engine in code, either you are in a scripting context where you’ve +already got access to an engine to create new objects with \c QJSEngine::newObject +and to evaluate expressions with \c QJSEngine::evaluate, or you want to evaluate +some JavaScript in a QObject that has been registered with the engine. In the +latter case, you can use \c qjsEngine(this) to obtain the currently active +QJSEngine. + +QJSManagedValue also provides a few methods that have no equivalent in QJSEngine. + +In the example below, QJSManagedValue methods encounter an exception, and +QJSEngine::catchError is used to handle the exception. + +\snippet qtjavascript/integratingjswithcpp/exampleqjsengine.cpp qjs-engine-example + +However, inside a method of a registered object, you might want to instead let +the exception bubble up the call stack. + +QJSManagedValue should be temporarily created on the stack, +and discarded once you don’t need to work any longer on the contained value. +Since QJSValue can store primitive values in a more efficient way, QJSManagedValue +should also not be used as an interface type which is the return or parameter type of +functions, and the type of properties, as the engine does not treat it in a +special way, and will not convert values to it (in contrast to QJSValue). + +\section1 QJSPrimitiveValue + +\l QJSPrimitiveValue can store any of the primitive types, and supports arithmetic +operations and comparisons according to the ECMA-262 standard. It allows for +low-overhead operations on primitives in contrast to QJSManagedValue, which always goes +through the engine, while still yielding results that are indistinguishable +from what the engine would return. As QJSPrimitiveValue is comparatively large, it +is not recommended to store values. + +*/ diff --git a/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc b/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc index 0a824bb5b53..6277b01af3a 100644 --- a/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc +++ b/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc @@ -105,6 +105,88 @@ You can also connect to any signals or call methods defined in the component using QMetaObject::invokeMethod() and QObject::connect(). See \l {Invoking QML Methods} and \l {Connecting to QML Signals} below for further details. +\section1 Accessing QML Objects via well-defined C++ Interfaces + +The best way of interacting with QML from C++ is to define an interface for +doing so in C++ and accessing it in QML itself. With other methods, refactoring +your QML code can easily lead to your QML / C++ interaction breaking. It also +helps to reason about the interaction of QML and C++ code, as having it driven +via QML can be more easily reasoned about by both users and tooling such as +qmllint. Accessing QML from C++ will lead to QML code that cannot be understood +without manually verifying that no outside C++ code is modifying a given QML +component, and even then the extent of the access might change over time, making +continued use of this strategy a maintenance burden. + +To let QML drive the interaction, first you need to define a C++ interface: + +\code +class CppInterface : public QObject +{ + Q_OBJECT + QML_ELEMENT + // ... +}; +\endcode + +Using a QML-driven approach, this interface can be interacted with in two ways: + +\section2 Singletons + +One option is to register the interface as a singleton by adding the \l +QML_SINGLETON macro to the interface, exposing it to all components. Following +that, the interface becomes available via a simple import statement: + +\code +import my.company.module + +Item { + Component.onCompleted: { + CppInterface.foo(); + } +} +\endcode + +Use this approach if you need your interface in more places than the root component, as +simply passing down an object would require explicitly passing it on to other +components via a property or utilizing the slow and not recommended method of +using \l {Unqualified access}{unqualified access}. + +\section2 Initial properties + +Another option is to mark the interface as uncreatable via \l QML_UNCREATABLE +and supplying it to the root QML Component by using \l +QQmlComponent::createWithInitialProperties() and a \l {Required +Properties}{required property} on the QML end. + +Your root component may look something like this: + +\code +import QtQuick + +Item { + required property CppInterface interface + Component.onCompleted: { + interface.foo(); + } +} +\endcode + +Marking the property as required here protects the component against being +created without the interface property being set. + +You can then initialize your component in the same way as outlined in \l +{Loading QML Objects from C++} except using \c {createWithInitialProperties()}: + +\code + component.createWithInitialProperties(QVariantMap{{u"interface"_qs, QVariant::fromValue(new CppInterface)}}); +\endcode + +This method is to be preferred if you know that your interface only needs to be +available to the root component. It also allows for connecting to signals and +slots of the interface more easily on the C++ side. + +If neither of these methods suit your needs you may want to investigate the usage of +\l {Using C++ Models with Qt Quick Views}{C++ models} instead. \section1 Accessing Loaded QML Objects by Object Name @@ -189,9 +271,9 @@ Notice the parameter and return type specified after the colon. You can use \l {QML Basic Types}{basic types} and \l {QML Object Types}{object types} as type names. -If the type is omitted in QML, then you must specify QVariant as type with -Q_RETURN_ARG() and Q_ARG() when calling QMetaObject::invokeMethod. - +If the type is omitted or specified as \c var in QML, then you must pass +QVariant as type with Q_RETURN_ARG() and Q_ARG() when calling +QMetaObject::invokeMethod. \section2 Connecting to QML Signals diff --git a/src/qml/doc/src/cppintegration/topic.qdoc b/src/qml/doc/src/cppintegration/topic.qdoc index 14a27c9a3ff..1a77039e7c3 100644 --- a/src/qml/doc/src/cppintegration/topic.qdoc +++ b/src/qml/doc/src/cppintegration/topic.qdoc @@ -205,7 +205,8 @@ dynamically load and introspect objects through the Qt meta object system. \include warning.qdocinc For more information on accessing QML objects from C++, see the documentation on -\l{qtqml-cppintegration-interactqmlfromcpp.html}{Interacting with QML Objects from C++}. +\l{qtqml-cppintegration-interactqmlfromcpp.html}{Interacting with QML Objects from C++}, +and the \l {Exposing Data from C++ to QML} section of the Best Practices page. \section1 Data Type Conversion Between QML and C++ diff --git a/src/qml/doc/src/javascript/finetuning.qdoc b/src/qml/doc/src/javascript/finetuning.qdoc index 97dc2421c51..61ac7d0c8f5 100644 --- a/src/qml/doc/src/javascript/finetuning.qdoc +++ b/src/qml/doc/src/javascript/finetuning.qdoc @@ -82,9 +82,12 @@ Running JavaScript code can be influenced by a few environment variables, partic \li \c{QV4_MAX_CALL_DEPTH} \li Stack overflows when running (as opposed to compiling) JavaScript are prevented by controlling the call depth: the number of nested function invocations. By - default, an exception is generated if the call depth exceeds 1234. If it contains a - number, this environment variable overrides the maximum call depth. Beware that the - recursion limit when compiling JavaScript is not affected. + default, an exception is generated if the call depth exceeds a maximum number tuned + to the platform's default stack size. If the \c{QV4_MAX_CALL_DEPTH} environment + variable contains a number, this number is used as maximum call depth. Beware that + the recursion limit when compiling JavaScript is not affected. The default maximum + call depth is 1234 on most platforms. On QNX it is 640 because on QNX the default + stack size is smaller than on most platforms. \row \li \c{QV4_MM_AGGRESSIVE_GC} \li Setting this environment variable runs the garbage collector before each memory diff --git a/src/qml/doc/src/javascript/hostenvironment.qdoc b/src/qml/doc/src/javascript/hostenvironment.qdoc index 6f1134a3e21..943da5cbef8 100644 --- a/src/qml/doc/src/javascript/hostenvironment.qdoc +++ b/src/qml/doc/src/javascript/hostenvironment.qdoc @@ -42,7 +42,8 @@ Like a browser or server-side JavaScript environment, the QML runtime implements all of the built-in types and functions defined by the standard, such as Object, Array, and Math. The QML runtime implements the 7th edition of the standard. -\l{Nullish Coalescing} (since Qt 5.15) and \l{Optional Chaining} (since Qt 6.2) are also implemented in the QML runtime. +\l{Nullish Coalescing} (\c{??}) (since Qt 5.15) and \l{Optional Chaining} (\c{?.}) (since Qt 6.2) +are also implemented in the QML runtime. The standard ECMAScript built-ins are not explicitly documented in the QML documentation. For more information on their use, please refer to the ECMA-262 7th edition standard or one of the many online @@ -70,11 +71,10 @@ to use from C++. See \l {qtqml-cppintegration-interactqmlfromcpp.html}{Interacting with QML Objects from C++} for more information. -Type assertions can also be used in order to cast an object to a different -object type. If the object is actually of the given type, then the type -assertion returns the same object. If not, it returns \c null. In the following -snippet we assert that the \c parent object is a \c Rectangle before accessing -a specific member of it. +Type assertions (sometimes called \e as-casts) can also be used in order to cast an object to a +different object type. If the object is actually of the given type, then the type assertion returns +the same object. If not, it returns \c null. In the following snippet we assert that the \c parent +object is a \c Rectangle before accessing a specific member of it. \qml Item { diff --git a/src/qml/doc/src/javascript/imports.qdoc b/src/qml/doc/src/javascript/imports.qdoc index 9227f0e604b..8d49c02f62c 100644 --- a/src/qml/doc/src/javascript/imports.qdoc +++ b/src/qml/doc/src/javascript/imports.qdoc @@ -95,17 +95,18 @@ or modules). A JavaScript resource may import another in the following fashion: \code -.import "filename.js" as Qualifier +import * as MathFunctions from "factorial.mjs"; \endcode -For example: +Or: \code -import * as MathFunctions from "factorial.mjs"; +.import "filename.js" as Qualifier \endcode -The latter is standard ECMAScript syntax for importing ECMAScript modules, and +The former is standard ECMAScript syntax for importing ECMAScript modules, and only works from within ECMAScript modules as denoted by the \c mjs file -extension. The former is an extension to JavaScript provided by the \c QML -engine and will work also with non-modules. +extension. The latter is an extension to JavaScript provided by the \c QML +engine and will work also with non-modules. As an extension superseded by the +ECMAScript standard, its usage is discouraged. When a JavaScript file is imported this way, it is imported with a qualifier. The functions in that file are then accessible from the importing script via the diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc index 3fc4c86f74a..cc4f4a2747b 100644 --- a/src/qml/doc/src/qmlfunctions.qdoc +++ b/src/qml/doc/src/qmlfunctions.qdoc @@ -45,8 +45,8 @@ \endcode You can use the build system to register the type in the type namespace - \e {com.mycompany.qmlcomponents} with major version \c 1 by specifying the - following in your project file: + \e {com.mycompany.qmlcomponents} with major version \c 1. + For qmake, specify the following in your project file: \badcode CONFIG += qmltypes @@ -54,6 +54,15 @@ QML_IMPORT_MAJOR_VERSION = 1 \endcode + With CMake, you pass the URI and version to qt_add_qml_module + + \badcode + qt6_add_qml_module(myapp + URI com.mycompany.qmlcomponents + VERSION 1.0 + ) + \endcode + Once registered, the type can be used in QML by importing the same type namespace and version number: @@ -101,8 +110,9 @@ \relates QQmlEngine Declares the enclosing type to be available, but anonymous in QML. The type - cannot be created or used as property type, but when passed from C++, it is - recognized. + cannot be created or used to declare properties in QML, but when passed from + C++, it is recognized. In QML, you can use properties of this type if they + are declared in C++. \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), QML_INTERFACE */ @@ -274,7 +284,7 @@ // Initialize this using myObject where you would previously // call qmlRegisterSingletonInstance(). - static MySingleton *s_singletonInstance = nullptr; + inline static MySingleton *s_singletonInstance = nullptr; static MySingleton *create(QQmlEngine *, QJSEngine *engine) { @@ -298,7 +308,7 @@ } private: - static QJSEngine *s_engine = nullptr; + inline static QJSEngine *s_engine = nullptr; }; \endcode @@ -1243,20 +1253,25 @@ \fn bool qmlProtectModule(const char* uri, int majVersion); \relates QQmlEngine - This function protects a module from having types registered into it. This - can be used to prevent other plugins from injecting types into your module. - It can also be a performance improvement, as it allows the engine to skip - checking for the possibility of new types or plugins when this import is - reached. - - The performance benefit is primarily seen when registering application - specific types from within the application instead of through a plugin. - Using qmlProtectModule allows the engine to skip checking for a plugin when - that uri is imported, which can be noticeable with slow file systems. - - After this function is called, any attempt to register C++ types into this - uri, major version combination will lead to a runtime error. Call this after - you have registered all of your types with the engine. + This function protects a module from further modification. This can be used + to prevent other plugins from injecting types into your module. It can also + be a performance improvement, as it allows the engine to skip checking for + the possibility of new types or plugins when this import is reached. + + Once qmlProtectModule has been called, a QML engine will not search for a new + \c qmldir file to load the module anymore. It will re-use any \c qmldir files + it has loaded before, though. Therefore, types present at this point continue + to work. Mind that different QML engines may load different modules. The + module protection, however, is global and affects all engines. The overhead + of locating \c qmldir files and loading plugins may be noticeable with slow file + systems. Therefore, protecting a module once you are sure you won't need to + load it anymore can be a good optimization. Mind also that the module lock + not only affects plugins but also any other qmldir directives, like \c import + or \c prefer, as well as any composite types or scripts declared in a \c qmldir + file. + + In addition, after this function is called, any attempt to register C++ types + into this uri, major version combination will lead to a runtime error. Returns true if the module with \a uri as a \l{Identified Modules} {module identifier} and \a majVersion as a major version number was found diff --git a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc index 718b0c25ac0..562b262271f 100644 --- a/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc +++ b/src/qml/doc/src/qmllanguageref/documents/definetypes.qdoc @@ -53,8 +53,12 @@ The type name has the following requirements: This document is then automatically recognized by the engine as a definition of a QML type. Additionally, a type defined in this manner is automatically made -available to other QML files within the same directory as the engine searches -within the immediate directory when resolving QML type names. +available to other QML files within the same local directory as the engine +searches within the immediate directory when resolving QML type names. + +\note The QML engine does not automatically search remote directories this way. +You have to add a qmldir file if your documents are loaded over the network. See +\l{Importing QML Document Directories}. \section2 Custom QML Type Definition diff --git a/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc b/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc index d762621d6c0..8f21a7348ca 100644 --- a/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc +++ b/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -51,7 +51,8 @@ Image { Network transparency is supported throughout QML, for example, both the FontLoader and Image elements support loading resources from a remote server. -Even QML types themselves can be on the network - if the \l {Prototyping with qmlscene} is used to load +Even QML types themselves can be on the network: if the +\l {Prototyping with the QML Runtime Tool}{qml tool} is used to load \tt http://example.com/mystuff/Hello.qml and that content refers to a type "World", the engine will load \tt http://example.com/mystuff/qmldir and resolve the type just as it would for a local file. For example if the qmldir file contains the line "World World.qml", it will load diff --git a/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc b/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc index 303ed6b18c1..6c235ef388f 100644 --- a/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/identifiedmodules.qdoc @@ -35,8 +35,8 @@ specified by the module in its \c qmldir file. This enables such modules to be imported with a unique identifier that remains the same no matter where the module is located on the local file system. -When importing an identified module, an unquoted identifier is used, with a -mandatory version number: +When importing an identified module, an unquoted identifier is used, with an +optional version number: \snippet qml/imports/installed-module.qml imports @@ -44,6 +44,12 @@ Identified modules must be installed into the \l{qtqml-syntax-imports.html#qml-import-path}{import path} in order to be found by the QML engine. +Syntactically, each dot-separated segment of the URI must be a well-formed +ECMAScript Identifier Name. This means, for example, the segments must not start +with a number and they must not contain \e{-} (minus) characters. As the URI +will be translated into directory names, you should restrict it to alphanumeric +characters of the latin alphabet, underscores, and dots. + \section1 Locally Installed Identified Modules A directory of QML and/or C++ files can be shared as an identified module if it @@ -171,7 +177,6 @@ An identified module has several restrictions upon it: \li the module must register its types into the module identifier type namespace \li the module may not register types into any other module's namespace -\li clients must specify a version when importing the module \endlist For example, if an identified module is installed into @@ -188,10 +193,9 @@ module com.example.CustomUi \endcode Clients will then be able to import the above module with the following import -statement (assuming that the module registers types into version 1.0 of its -namespace): +statement: \qml -import com.example.CustomUi 1.0 +import com.example.CustomUi \endqml */ diff --git a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc index 95e8a179dea..4d7ea272ced 100644 --- a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc @@ -43,278 +43,287 @@ module. For more information about the first form of \c qmldir file, see \section1 Contents of a Module Definition qmldir File -A \c qmldir file is a plain-text file that contains -the following commands: - -\table 70% - \header - \li Syntax - \li Usage - \row - \li - \code -module - \endcode - \li Declares the module identifier of the module. - The is the (dotted URI notation) identifier - for the module, which must match the module's install path. - - The \l{Identified Modules#Semantics of Identified Modules} - {module identifier directive} must be the first line of the file. - Exactly one module identifier directive may exist in the \c qmldir - file. - - Example: - \code -module ExampleModule - \endcode - - \row - \li - \code -[singleton] - \endcode - \li Declares a \l{qtqml-typesystem-objecttypes.html}{QML object type} - to be made available by the module. - \list - \li \c [singleton] Optional. Used to declare a singleton type. - \li \c is the type being made available - \li \c is the module version for which the type is to be made available - \li \c is the (relative) file name of the QML file that defines the type - \endlist - - Zero or more object type declarations may exist in the \c qmldir - file, however each object type must have a unique type name within - any particular version of the module. - \note To declare a \c singleton type, the QML file defining the - type must include the \c {pragma Singleton} statement. - - Example: - \code -//Style.qml with custom singleton type definition -pragma Singleton -import QtQuick 2.0 +A \c qmldir file is a plain-text file that contains the following commands: -QtObject { - property int textSize: 20 - property color textColor: "green" -} +\list + \li \l {Module Identifier Declaration} + \li \l {Object Type Declaration} + \li \l {Internal Object Type Declaration} + \li \l {JavaScript Resource Declaration} + \li \l {Plugin Declaration} + \li \l {Plugin Classname Declaration} + \li \l {Type Description File Declaration} + \li \l {Module Dependencies Declaration} + \li \l {Module Import Declaration} + \li \l {Designer Support Declaration} + \li \l {Preferred Path Declaration} +\endlist -// qmldir declaring the singleton type -module CustomStyles -singleton Style 1.0 Style.qml +\note Each command in a \c qmldir file must be on a separate line. -// singleton type in use -import QtQuick 2.0 -import CustomStyles 1.0 +In addition to commands, you can also add comments, which are lines starting +with \c {#}. -Text { - font.pixelSize: Style.textSize - color: Style.textColor - text: "Hello World" -} - \endcode - - \row - \li - \code -internal - \endcode - \li Declares an object type that is in the module but should not be - made available to users of the module. - - Zero or more internal object type declarations may exist in the - \c qmldir file. - - Example: - \code -internal MyPrivateType MyPrivateType.qml - \endcode - - This is necessary if the module may be imported remotely (see - \l{Identified Modules#Remotely Installed Identified Modules} - {Remotely Installed Identified Modules}) because if an exported type depends - on an non-exported type within the module, the engine must also - load the non-exported type. - - \row - \li - \code - - \endcode - \li Declares a JavaScript file to be made available by the module. - The resource will be made available via the specified identifier - with the specified version number. - - Zero or more JavaScript resource declarations may exist in the - \c qmldir file, however each JavaScript resource must have a unique - identifier within any particular version of the module. - - Example: - \code -MyScript 1.0 MyScript.js - \endcode - - See the documentation about \l{qtqml-javascript-resources.html} - {defining JavaScript resources} and - \l{qtqml-javascript-imports.html} - {Importing JavaScript Resources In QML} for more information. - - \row - \li - \code -[optional] plugin [] - \endcode - \li Declares a plugin to be made available by the module. - - \list - \li \c optional denotes that the plugin itself does not contain - any relevant code and only serves to load a library it links - to. If given, and if any types for the module are already - available, indicating that the library has been loaded by some - other means, QML will not load the plugin. - \li \c is the plugin library name. This is usually not the - same as the file name of the plugin binary, which is platform - dependent; e.g. the library \c MyAppTypes would produce - \c libMyAppTypes.so on Linux and \c MyAppTypes.dll on Windows. - \li \c (optional) specifies either: - \list - \li an absolute path to the directory containing the plugin - file, or - \li a relative path from the directory containing the \c qmldir - file to the directory containing the plugin file. - \endlist - - By default the engine searches for the plugin library in the - directory that contains the \c qmldir file. (The plugin search - path can be queried with QQmlEngine::pluginPathList() and - modified using QQmlEngine::addPluginPath().) - \endlist - - Zero or more C++ plugin declarations may exist in the \c qmldir - file, however since plugin loading is a relatively expensive - operation, clients are advised to specify at most a single plugin. - - Example: - \code -plugin MyPluginLibrary - \endcode - \row - \li - \code -classname - \endcode - \li Provides the class name of the C++ plugin used by the module. - - This information is required for all the QML modules that depend - on a C++ plugin for additional functionality. Qt Quick applications - built with static linking cannot resolve the module imports without - this information. - - \row - \li - \code -typeinfo - \endcode - \li Declares a \l{Type Description Files}{type description file} for - the module that can be read by QML tools such as Qt Creator to - access information about the types defined by the module's plugins. - \c is the (relative) file name of a \c .qmltypes file. - - Example: - \code -typeinfo mymodule.qmltypes - \endcode - - Without such a file, QML tools may be unable to offer features such - as code completion for the types defined in your plugins. - - \row - \li - \code -depends - \endcode - \li Declares that this module depends on another. - - Example: - \code -depends MyOtherModule 1.0 - \endcode - - This declaration is necessary only in cases when the dependency is - hidden: for example, when the C++ code for one module is used to - load QML (perhaps conditionally) which then depends on other - modules. In such cases, the \c depends declaration is necessary - to include the other modules in application packages. - \row - \li - \code -import [] - \endcode - \li Declares that this module imports another. - - Example: - \code -import MyOtherModule 1.0 - \endcode - - The types from the other module are made available in the same type - namespace as this module is imported into. Omitting the version - imports the latest version available of the other module, specifying - \c auto as version imports the same version as the version of this - module specified in the QML \c import statement. - - \row - \li - \code -# - \endcode - \li Declares a comment. These are ignored by the engine. - - Example: - \code -# this is a comment - \endcode - - \row - \li - \code -designersupported - \endcode - - \li Set this property if the plugin is supported by Qt Quick Designer. - By default, the plugin will not be supported. - - A plugin that is supported by Qt Quick Designer has to be properly - tested. This means that the plugin does not crash when running inside - the qml2puppet that is used by Qt Quick Designer to execute QML. - Generally the plugin should work well in the Qt Quick Designer - and not cause any show stoppers, like taking huge amounts of memory, - slowing down the qml2puppet heavily or anything else that renders - the plugin effectively unusable in the Qt Quick Designer. - - The items of an unsupported plugin are not painted in the Qt Quick Designer, - but they are still available as empty boxes and the properties can be edited. - - \row - \li - \code -prefer - \endcode - - \li This property directs the QML engine to load any further files for this - module from , rather than the current directory. This can be used - to load files compiled with qmlcachegen. - - For example, you can add a module's QML files as resources to a resource - path \c{:/my/path/MyModule/}. Then, add \c{prefer :/my/path/MyModule} to - the qmldir file in order to use the files in the resource system, rather - than the ones in the file system. If you then use qmlcachegen for those, - the pre-compiled files will be available to any clients of the module. - -\endtable - -Each command in a \c qmldir file must be on a separate line. +\section2 Module Identifier Declaration + +\code + module +\endcode + +Declares the module identifier of the module. The is the +(dotted URI notation) identifier for the module, which must match the module's +install path. + +The \l{Identified Modules#Semantics of Identified Modules} +{module identifier directive} must be the first line of the file. Exactly one +module identifier directive may exist in the \c qmldir file. + +Example: +\code + module ExampleModule +\endcode + +\section2 Object Type Declaration +\code + [singleton] +\endcode + +Declares a \l{qtqml-typesystem-objecttypes.html}{QML object type} +to be made available by the module. +\list + \li \c [singleton] Optional. Used to declare a singleton type. + \li \c is the type being made available + \li \c is the module version for which the type is to be + made available + \li \c is the (relative) file name of the QML file that defines + the type +\endlist + +Zero or more object type declarations may exist in the \c qmldir +file. However, each object type must have a unique type name within +any particular version of the module. +\note To declare a \c singleton type, the QML file defining the +type must include the \c {pragma Singleton} statement. + +Example: +\code + //Style.qml with custom singleton type definition + pragma Singleton + import QtQuick 2.0 + + QtObject { + property int textSize: 20 + property color textColor: "green" + } + + // qmldir declaring the singleton type + module CustomStyles + singleton Style 1.0 Style.qml + + // singleton type in use + import QtQuick 2.0 + import CustomStyles 1.0 + + Text { + font.pixelSize: Style.textSize + color: Style.textColor + text: "Hello World" + } +\endcode + +\section2 Internal Object Type Declaration + +\code + internal +\endcode + +Declares an object type that is in the module but should not be +made available to users of the module. + +Zero or more internal object type declarations may exist in the +\c qmldir file. + +Example: +\code + internal MyPrivateType MyPrivateType.qml +\endcode + +This is necessary if the module is imported remotely +(see \l{Identified Modules#Remotely Installed Identified Modules} +{Remotely Installed Identified Modules}) because if an exported type depends +on a non-exported type within the module, the engine must also +load the non-exported type. + +\section2 JavaScript Resource Declaration + +\code + +\endcode + +Declares a JavaScript file to be made available by the module. +The resource will be made available via the specified identifier +with the specified version number. + +Zero or more JavaScript resource declarations may exist in the +\c qmldir file. However, each JavaScript resource must have a unique +identifier within any particular version of the module. + +Example: +\code + MyScript 1.0 MyScript.js +\endcode + +See the documentation about \l{qtqml-javascript-resources.html} +{defining JavaScript resources} and +\l{qtqml-javascript-imports.html} +{Importing JavaScript Resources In QML} for more information. + +\section2 Plugin Declaration + +\code + [optional] plugin [] +\endcode + +Declares a plugin to be made available by the module. + +\list + \li \c optional denotes that the plugin itself does not contain + any relevant code and only serves to load a library it links + to. If given, and if any types for the module are already + available, indicating that the library has been loaded by some + other means, QML will not load the plugin. + \li \c is the plugin library name. This is usually not the + same as the file name of the plugin binary, which is platform + dependent. For example, the library \c MyAppTypes would produce + \c libMyAppTypes.so on Linux and \c MyAppTypes.dll on Windows. + \li \c (optional) specifies either: + \list + \li an absolute path to the directory containing the plugin + file, or + \li a relative path from the directory containing the \c qmldir + file to the directory containing the plugin file. + \endlist +\endlist + +By default, the engine searches for the plugin library in the +directory that contains the \c qmldir file. (The plugin search +path can be queried with QQmlEngine::pluginPathList() and +modified using QQmlEngine::addPluginPath().) + +Zero or more C++ plugin declarations may exist in the \c qmldir +file. However, since plugin loading is a relatively expensive +operation, clients are advised to specify at most a single plugin. + +Example: +\code + plugin MyPluginLibrary +\endcode + +\section2 Plugin Classname Declaration + +\code + classname +\endcode + +Provides the class name of the C++ plugin used by the module. + +This information is required for all the QML modules that depend +on a C++ plugin for additional functionality. Qt Quick applications +built with static linking cannot resolve the module imports without +this information. + +\section2 Type Description File Declaration + +\code + typeinfo +\endcode + +Declares a \l{Type Description Files}{type description file} for +the module that can be read by QML tools such as Qt Creator to +access information about the types defined by the module's plugins. +\c is the (relative) file name of a \c .qmltypes file. + +Example: +\code + typeinfo mymodule.qmltypes +\endcode + +Without such a file, QML tools may be unable to offer features such +as code completion for the types defined in your plugins. + +\section2 Module Dependencies Declaration + +\code + depends +\endcode + +Declares that this module depends on another. + +Example: +\code + depends MyOtherModule 1.0 +\endcode + +This declaration is necessary only in cases when the dependency is +hidden: for example, when the C++ code for one module is used to +load QML (perhaps conditionally), which then depends on other +modules. In such cases, the \c depends declaration is necessary +to include the other modules in application packages. + +\section2 Module Import Declaration + +\code + import [] +\endcode + +Declares that this module imports another. + +Example: +\code + import MyOtherModule 1.0 +\endcode + +The types from the other module are made available in the same type +namespace as this module is imported into. Omitting the version +imports the latest version available of the other module. Specifying +\c auto as version imports the same version as the version of this +module specified in the QML \c import statement. + +\section2 Designer Support Declaration + +\code + designersupported +\endcode + +Set this property if the plugin is supported by Qt Quick Designer. +By default, the plugin will not be supported. + +A plugin that is supported by Qt Quick Designer has to be properly +tested. This means that the plugin does not crash when running inside +the qml2puppet that is used by Qt Quick Designer to execute QML. +Generally, the plugin should work well in the Qt Quick Designer +and not cause any show stoppers, like taking excessive amounts of memory, +slowing down the qml2puppet heavily, or anything else that renders +the plugin effectively unusable in the Qt Quick Designer. + +The items of an unsupported plugin are not painted in the Qt Quick Designer, +but they are still available as empty boxes and the properties can be edited. + +\section2 Preferred Path Declaration + +\code + prefer +\endcode + +This property directs the QML engine to load any further files for this +module from , rather than the current directory. This can be used +to load files compiled with qmlcachegen. + +For example, you can add a module's QML files as resources to a resource +path \c{:/my/path/MyModule/}. Then, add \c{prefer :/my/path/MyModule} to +the qmldir file in order to use the files in the resource system, rather +than the ones in the file system. If you then use qmlcachegen for those, +the pre-compiled files will be available to any clients of the module. \section1 Versioning Semantics @@ -434,7 +443,7 @@ documentation on this, no further action is needed. qmltyperegistrar will automatically generate the \c .qmltypes files. Example: -If your module is in \c /tmp/imports/My/Module, a file caled \c plugins.qmltypes +If your module is in \c /tmp/imports/My/Module, a file called \c plugins.qmltypes should be generated alongside the actual plugin binary. Add the line diff --git a/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc b/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc index b1fce12dc37..834977994f1 100644 --- a/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc +++ b/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc @@ -26,6 +26,14 @@ plugins. Library plugins should limit themselves to registering types, as any manipulation of the engine's root context may cause conflicts or other issues in the library user's code. +\note When using the CMake \l qt_add_qml_module API, a plugin will be generated +automatically for you. It will take care of type registration. +You only need to write a custom plugin if you have special +requirements, such as registering custom image +providers. In that case, pass +\l{NO_GENERATE_PLUGIN_SOURCE} to the \c qt_add_qml_module +call to disable the generation of the default plugin. + The linker might erroneously remove the generated type registration function as an optimization. You can prevent that by declaring a synthetic volatile pointer to the function somewhere in your code. If your module is diff --git a/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc index 7ec8a4ff341..0623dd99345 100644 --- a/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/directoryimports.qdoc @@ -109,6 +109,11 @@ a file system path. A directory of QML files can also be imported from a remote location if the directory contains a directory listing \c qmldir file. +\note This also holds for the implicit import of the directory a QML document +resides in. If your QML documents are loaded from a remote location, you need +to add qmldir files even if they don't contain any explicit directory import +statements. Otherwise your QML documents won't see each other. + For example, if the \c myapp directory in the previous example was hosted at "http://www.my-example-server.com", and the \c mycomponents directory contained a \c qmldir file defined as follows: diff --git a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc index 14a99c44f4b..c17ced36011 100644 --- a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -49,7 +49,7 @@ types and JavaScript resources into a given namespace. The generic form of a module import is as follows: \code -import [as ] +import [] [as ] \endcode \list @@ -59,7 +59,9 @@ import [as ] \li The \c is a version of the form \c {MajorVersion.MinorVersion} which specifies which definitions of various object types and JavaScript resources will be made available due - to the import. + to the import. It can be omitted, in which case the latest version of the + module is imported. It is also possible to only omit the minor version. + Then the latest minor version of the given major version is imported. \li The \c is an optional local namespace identifier into which the object types and JavaScript resources provided by the module will be installed, if given. If omitted, the object types and JavaScript @@ -69,7 +71,7 @@ import [as ] An example of an unqualified module import is as follows: \code -import QtQuick 2.0 +import QtQuick \endcode This import allows the use of all of the types provided by the \c QtQuick @@ -77,7 +79,7 @@ module without needing to specify a qualifier. For example, the client code to create a rectangle is as follows: \qml -import QtQuick 2.0 +import QtQuick Rectangle { width: 200 @@ -86,9 +88,16 @@ Rectangle { } \endqml +An example of an unqualified import with version would be +\code +import QtQuick 2.10 +\endcode +In that case, any types defined in QtQuick 2.11 and higher or in any higher major +version, like 6.0, would not be available to the file. + An example of a qualified module import is as follows: \code -import QtQuick 2.0 as Quick +import QtQuick as Quick \endcode This import allows multiple modules which provide conflicting type names to be @@ -100,7 +109,7 @@ An example of client code which creates a rectangle after using a qualified module import is as follows: \qml -import QtQuick 2.0 as Quick +import QtQuick as Quick Quick.Rectangle { width: 200 @@ -149,7 +158,7 @@ references to types from the \c QtQuick module must be prefixed with the \c CoreItems name: \qml -import QtQuick 2.0 as CoreItems +import QtQuick as CoreItems CoreItems.Rectangle { width: 100; height: 100 @@ -171,7 +180,7 @@ two modules can be imported into different namespaces to ensure the code is referring to the correct type: \qml -import QtQuick 2.0 as CoreItems +import QtQuick as CoreItems import "../textwidgets" as MyModule CoreItems.Rectangle { @@ -244,8 +253,8 @@ module by importing the module and using the identifier associated with a declared resource: \qml -import QtQuick 2.0 -import projects.MyQMLProject.MyFunctions 1.0 +import QtQuick +import projects.MyQMLProject.MyFunctions Item { Component.onCompleted: { SystemFunctions.cleanUp(); } @@ -257,9 +266,9 @@ resource identifiers must be prefixed with the namespace qualifier in order to be used: \qml -import QtQuick 2.0 -import projects.MyQMLProject.MyFunctions 1.0 as MyFuncs -import org.example.Functions 1.0 as TheirFuncs +import QtQuick +import projects.MyQMLProject.MyFunctions as MyFuncs +import org.example.Functions as TheirFuncs Item { Component.onCompleted: { @@ -296,8 +305,8 @@ default locations to be searched by the engine. By default, this list contains: Additional import paths can be added through QQmlEngine::addImportPath() or the \c QML_IMPORT_PATH environment variable. When running the -\l{Prototyping with qmlscene}{qmlscene} tool, you can also use the \c -I option -to add an import path. +\l {Prototyping with the QML Runtime Tool}{qml tool}, you can also use the +\c -I option to add an import path. You can specify multiple import paths in the \c QML_IMPORT_PATH environment variable by joining them using the path separator. On Windows the path separator diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc index 787e7b920bc..8b3ff59ecce 100644 --- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc @@ -56,6 +56,7 @@ The set of QML object-type attribute types is as follows: These attributes are discussed in detail below. \section2 The \e id Attribute +\keyword QML.id Every QML object type has exactly one \e id attribute. This attribute is provided by the language itself, and cannot be redefined or overridden by any @@ -686,8 +687,8 @@ the role names of the view's model, then those properties will be initialized with the model's corresponding values. For more information, visit the \l{Models and Views in Qt Quick} page. -\sa {QQmlComponent::createWithInitialProperties}, {QQmlApplicationEngine::setInitialProperties} -and {QQuickView::setInitialProperties} for ways to initialize required properties from C++. +See \l{QQmlComponent::createWithInitialProperties}, \l{QQmlApplicationEngine::setInitialProperties} +and \l{QQuickView::setInitialProperties} for ways to initialize required properties from C++. \section3 Read-Only Properties @@ -730,6 +731,8 @@ with a particular property is as follows: } \endcode +This is commonly referred to as "on" syntax. + It is important to note that the above syntax is in fact an \l{qtqml-syntax-basics.html#object-declarations}{object declaration} which will instantiate an object which acts on a pre-existing property. diff --git a/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc index 5716f6c3869..6e94af6e415 100644 --- a/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc +++ b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc @@ -267,38 +267,18 @@ property is only invoked when the property is reassigned to a different object v var urlObject = new URL(url); \endqml - \section1 Using the url Type - - When a relative URL is written to a \c url type property, it is converted - into a URL object, so \b {matching the URL value against the input string - value will fail}. Instead, convert the string to a URL using Qt.resolvedUrl() - for means of comparison, and use \c toString() to get the contents of the URL: - - \qml - Image { - source: "pics/logo.png" - - Component.onCompleted: { - // This prints 'false'. Although "pics/logo.png" was the input string, - // it's been converted from a string to a URL, so these two are not the same. - console.log(source == "pics/logo.png") - - // This prints 'true' as Qt.resovledUrl() converts the string into a - // URL with the correctly resolved path - console.log(source == Qt.resolvedUrl("pics/logo.png")) - - // This prints the absolute path, e.g. "file:///path/to/pics/logo.png" - console.log(source.toString()) - } - } - \endqml + \note In Qt 5, URLs were automatically resolved based on the current context + when assigning them to any \c url property. This made it impossible to + work with relative URLs and it created inconsistent behavior when reading + back a URL previously written to a property. Therefore, the behavior was + changed in Qt 6. \note When referring to files stored with the \l{resources.html}{Qt Resource System} from within QML, you should use "qrc:///" instead of ":/" as QML requires URL paths. Relative URLs resolved from within that file will use the same protocol. Additionally, URLs may contain encoded characters using the 'percent-encoding' scheme - specified by \l {http://tools.ietf.org/html/rfc3986}{RFC 3986}. These characters + specified by \l {https://datatracker.ietf.org/doc/html/rfc3986}{RFC 3986}. These characters will be preserved within properties of type \c url, to allow QML code to construct precise URL values. diff --git a/src/qml/doc/src/qmltypereference.qdoc b/src/qml/doc/src/qmltypereference.qdoc index 83544b1a661..a3df68b29bc 100644 --- a/src/qml/doc/src/qmltypereference.qdoc +++ b/src/qml/doc/src/qmltypereference.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! -\qmlmodule QtQml 2.\QtMinorVersion +\qmlmodule QtQml \title Qt QML QML Types \ingroup qmlmodules \brief List of QML types provided by the Qt QML module diff --git a/src/qml/doc/src/qt6-changes.qdoc b/src/qml/doc/src/qt6-changes.qdoc index 70c61849e79..9798718b96e 100644 --- a/src/qml/doc/src/qt6-changes.qdoc +++ b/src/qml/doc/src/qt6-changes.qdoc @@ -213,8 +213,8 @@ engine.installTranslatorFunctions(); \newcode QJSEngine engine; - engine.installExtensions(QJSEngine::TranslationExtension - \endcode; + engine.installExtensions(QJSEngine::TranslationExtension); + \endcode \endlist diff --git a/src/qml/doc/src/qtqml-writing-a-module.qdoc b/src/qml/doc/src/qtqml-writing-a-module.qdoc new file mode 100644 index 00000000000..a3464926e1d --- /dev/null +++ b/src/qml/doc/src/qtqml-writing-a-module.qdoc @@ -0,0 +1,289 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page qtqml-writing-a-module.html +\title Writing QML Modules +\brief How to write a custom QML module. + +You can declare a QML module using the \l{qt_add_qml_module} +{CMake QML Module API} to: + +\list +\li Generate \l {Module Definition qmldir Files}{qmldir} and + \l {Type Description Files}{*.qmltypes files}. +\li Register C++ types annotated with \l QML_ELEMENT. +\li Invoke \l {Ahead-of-Time-Compilation}{qmlcachegen}. +\li Provide modules both in the physical and in \l{The Qt Resource System} + {resource file system}. +\li Use the pre-compiled versions of QML files. +\li Bundle the module's files in the resource file system. +\li Combine QML files and C++-based types in the same module. +\li Create a backing library and an optional plugin. Link the backing library + into the application to avoid loading the plugin at run time. +\endlist + +All the above actions can also be configured separately. +For more information, see \l {qt_add_qml_module}{CMake QML Module API}. + +\section1 Multiple QML Modules in One Binary + +You can add multiple QML modules into the same binary. Define a CMake target for +each module and then link the targets to the executable. +If the extra targets are all static libraries, the result will be one binary, +which contains multiple QML modules. In short you can create an application +like this: + +\badcode +myProject + | - CMakeLists.txt + | - main.cpp + | - main.qml + | - onething.h + | - onething.cpp + | - ExtraModule + | - CMakeLists.txt + | - Extra.qml + | - extrathing.h + | - extrathing.cpp +\endcode + +To begin, let's assume main.qml contains an instantiation of Extra.qml: + + \badcode + import ExtraModule + Extra { ... } + \endcode + +The extra module has to be a static library so that you can link it +into the main program. Therefore, state as much in ExtraModule/CMakeLists.txt: + +\quotefromfile qml/CMakeLists.txt +\printuntil extrathing.h +\printuntil ) + +This generates two targets: \c extra_module for the backing library, and +\c extra_moduleplugin for the plugin. Being a static library too, the plugin cannot +be loaded at runtime. + +In myProject/CMakeLists.txt you need to specify the QML module that main.qml +and any types declared in onething.h are part of: + +\quotefromfile qml/myProject-CMakeLists.txt +\printuntil onething.h +\printuntil ) + + +From there, you add the subdirectory for the extra module: + +\quotefromfile qml/CMakeLists.txt +\skipto add_subdirectory +\printuntil ) + +To ensure that linking the extra module works correctly, you need to: + +\list +\li Define a symbol in the extra module. +\li Create a reference to the symbol from the main program. +\endlist + +QML plugins contain a symbol you can use for this purpose. +You can use the \l Q_IMPORT_QML_PLUGIN macro to create a reference to this symbol. +Add the following code to the main.cpp: + +\badcode +#include +Q_IMPORT_QML_PLUGIN(ExtraModulePlugin) +\endcode + +\c ExtraModulePlugin is the name of the generated plugin class. It's composed +of the module URI with \c Plugin appended to it. Then, in the main program's +CMakeLists.txt, link the plugin, not the backing library, into the main program: + +\quotefromfile qml/myProject-CMakeLists.txt +\skipto target_link_libraries +\printuntil ) + +\section1 Exporting Multiple Major Versions from The Same Module + +\l qt_add_qml_module by default considers the major version given in its +URI argument, even if the individual types declare other versions in their +added specific version via \l QT_QML_SOURCE_VERSIONS or \l Q_REVISION. +If a module is available under more than one version, you also need to decide +what versions the individual QML files are available under. To declare further +major versions, you can use the \c PAST_MAJOR_VERSIONS option to +\c qt_add_qml_module as well as the \c {QT_QML_SOURCE_VERSIONS} property on +individual QML files. + +\quotefile qml/MajorProject-CMakeLists.txt + +\c MyModule is available in major versions 1, 2, and 3. The maximum version +available is 3.2. You can import any version 1.x or 2.x with a positive x. For +Thing.qml and OtherThing.qml we have added explicit version information. +Thing.qml is available from version 1.4, and OtherThing.qml is available from +version 2.2. You have to specify the later versions, too, in each +\c set_source_files_properties() because you may remove QML files +from a module when bumping the major version. There is no explicit version +information for OneMoreThing.qml. This means that OneMoreThing.qml is available +in all major versions, from minor version 0. + +With this setup, the generated registration code will register the module +\c versionsqmlRegisterModule() for each of the major versions. This way, all +versions can be imported. + + +\section1 Custom Directory Layouts + +The easiest way to structure QML modules is to keep them in directories named by +their URIs. For example, a module My.Extra.Module would live in a directory +My/Extra/Module relative to the application that uses it. This way, they can +easily be found at run time and by any tools. + +In more complex projects, this convention can be too limiting. You might for +instance want to group all QML modules in one place to avoid polluting the +project's root directory. Or you want to reuse a single module in multiple +applications. For those cases, \c QT_QML_OUTPUT_DIRECTORY in combination with +\c RESOURCE_PREFIX and \l IMPORT_PATH can be used. + +To collect QML modules into a specific output directory, for example a +subdirectory "qml" in the build directory \l QT_QML_OUTPUT_DIRECTORY, set the +following in the top-level CMakeLists.txt: + +\badcode +set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/qml) +\endcode + +The output directories of QML modules move to the new location. +Likewise, the \c qmllint and \c qmlcachegen invocations are automatically +adapted to use the new output directory as an \l {QML Import Path}{import path}. +Because the new output directory is not part of the default QML import path, +you have to add it explicitly at run time, so that the QML modules can be found. + + +Now that the physical file system is taken care of, you may still want to move +the QML modules into a different place in the resource file system. This is what +the RESOURCE_PREFIX option is for. You have to specify it separately in +each \l qt_add_qml_module. The QML module will then be placed under the specified +prefix, with a target path generated from the URI appended. For example, +consider the following module: + +\code +qt_add_qml_module( + URI My.Great.Module + VERSION 1.0 + RESOURCE_PREFIX /example.com/qml + QML_FILES + A.qml + B.qml +) +\endcode + +This will add a directory \c example.com/qml/My/Great/Module to the resource file +system and place the QML module defined above in it. You don't strictly need to +add the resource prefix to the QML import path as the module can still be found +in the physical file system. However, it generally is a good idea to add the +resource prefix to the QML import path because loading from the resource file +system is faster than loading from the physical file system for most modules. + +If the QML modules are meant to be used in a larger project with multiple import +paths, you'll have to do an additional step: Even if you add the import paths at +run time, tooling like \c qmllint does not have access to it, and might fail to +find the correct dependencies. Use \c IMPORT_PATH to tell tooling about the +additional paths it has to consider. For example: + +\badcode +qt_add_qml_module( + URI My.Dependent.Module + VERSION 1.0 + QML_FILES + C.qml + IMPORT_PATH "/some/where/else" +) +\endcode + +\section1 Eliminating Run Time File System Access + +If all QML modules are always loaded from the resource +file system, you can deploy the application as a single binary. Let's first +consider the simple case: + +\badcode +QQmlEngine qmlEngine; +qmlEngine.addImportPath(QStringLiteral(":/")); +// Use qmlEngine to load the main.qml file. +\endcode + +\note ":/" is used for simplicity here. See \l {Custom Directory Layouts} +for more complex cases. + +If all the modules are linked into the application and if you're following +the default resource directory structure, do not add any further import paths as +those might override the one you added. + +If you have specified a custom \c RESOURCE_PREFIX, you have to add the custom +resource prefix to the import path instead. You can also add multiple resource +prefixes. + +The path \c :/qt-project.org/imports/ is part of the default QML import path. If +you use it, you don't have to specially add it. Qt's own QML modules are placed +there, though. You have to be careful not to overwrite them. For modules that are +heavily re-used across different projects \c :/qt-project.org/imports/ is +acceptable. By using it you can avoid forcing all the users to add custom +import paths. + +\section1 Integrating custom QML plugins + +If you bundle an \l {QQuickImageProvider}{image provider} in the QML module, you +need to implement the \l {QQmlEngineExtensionPlugin::initializeEngine()} +method. This, in turn, makes it necessary to write the own plugin. To support +this use case, \l NO_GENERATE_PLUGIN_SOURCE can be used. + +Let's consider a module that provides its own plugin source: + +\quotefile qml/myimageprovider.txt + +You may declare an image provider in myimageprovider.h, like this: + +\badcode +class MyImageProvider : public QQuickImageProvider +{ + [...] +}; +\endcode + +In plugin.cpp you can then define the QQmlEngineExtensionPlugin: + +\quotefile qml/plugin.cpp.txt + +This will make the image provider available. The plugin and the backing library +both are in the same CMake target imageproviderplugin. This is done so that the +linker does not drop parts of the module in various scenarios. + +As the plugin creates an image provider, it no longer has a trivial +\c initializeEngine function. Therefore, the plugin is no longer optional. + +*/ diff --git a/src/qml/doc/src/qtqml.qdoc b/src/qml/doc/src/qtqml.qdoc index e1ff6931955..9f26c9328b6 100644 --- a/src/qml/doc/src/qtqml.qdoc +++ b/src/qml/doc/src/qtqml.qdoc @@ -132,8 +132,14 @@ The QML framework allows QML code to contain JavaScript expressions and for the QML code to interact with C++ code. \list -\li \l{Important C++ Classes Provided By The Qt QML Module} -\li \l{Integrating QML and C++} + \li \l {Overview - QML and C++ Integration} + \li \l {Data Type Conversion Between QML and C++} + \li \l {Integrating with JavaScript values from C++} + \li \l {Exposing Attributes of C++ Types to QML} + \li \l {Defining QML Types from C++} + \li \l {Writing QML Modules} + \li \l {Important C++ Classes Provided By The Qt QML Module} + \li \l {Integrating QML and C++} \endlist \omit diff --git a/src/qml/inlinecomponentutils_p.h b/src/qml/inlinecomponentutils_p.h index ae436d53b0e..56794779a68 100644 --- a/src/qml/inlinecomponentutils_p.h +++ b/src/qml/inlinecomponentutils_p.h @@ -55,24 +55,38 @@ namespace icutils { struct Node { +private: + using IndexType = std::vector::size_type; + using IndexField = quint32_le_bitfield_member<0, 30, IndexType>; + using TemporaryMarkField = quint32_le_bitfield_member<30, 1>; + using PermanentMarkField = quint32_le_bitfield_member<31, 1>; + quint32_le_bitfield_union m_data; + +public: Node() = default; Node(const Node &) = default; Node(Node &&) = default; Node& operator=(Node const &) = default; Node& operator=(Node &&) = default; - bool operator==(Node const &other) const {return index == other.index;} + bool operator==(Node const &other) const {return m_data.data() == other.m_data.data(); } + + Node(IndexType s) : m_data(QSpecialIntegerBitfieldZero) { m_data.set(s); } + + bool hasPermanentMark() const { return m_data.get(); } + bool hasTemporaryMark() const { return m_data.get(); } + + void setPermanentMark() + { + m_data.set(0); + m_data.set(1); + } - Node(std::vector::size_type s) { - index = quint32(s); - temporaryMark = 0; - permanentMark = 0; + void setTemporaryMark() + { + m_data.set(1); } - union { - quint32_le_bitfield<0, 30> index; - quint32_le_bitfield<30, 1> temporaryMark; - quint32_le_bitfield<31, 1> permanentMark; - }; + IndexType index() const { return m_data.get(); } }; using AdjacencyList = std::vector>; @@ -109,8 +123,11 @@ void fillAdjacencyListForInlineComponents(ObjectContainer *objectContainer, Adja auto referencedInICObjectIndex = ic.objectIndex + 1; while (int(referencedInICObjectIndex) < objectContainer->objectCount()) { auto potentiallyReferencedInICObject = objectContainer->objectAt(referencedInICObjectIndex); - bool stillInIC = !(potentiallyReferencedInICObject-> flags & QV4::CompiledData::Object::IsInlineComponentRoot) - && (potentiallyReferencedInICObject-> flags & QV4::CompiledData::Object::InPartOfInlineComponent); + bool stillInIC + = !potentiallyReferencedInICObject->hasFlag( + QV4::CompiledData::Object::IsInlineComponentRoot) + && potentiallyReferencedInICObject->hasFlag( + QV4::CompiledData::Object::InPartOfInlineComponent); if (!stillInIC) break; createEdgeFromTypeRef(objectContainer->resolvedType(potentiallyReferencedInICObject->inheritedTypeNameIndex)); @@ -120,21 +137,20 @@ void fillAdjacencyListForInlineComponents(ObjectContainer *objectContainer, Adja }; inline void topoVisit(Node *node, AdjacencyList &adjacencyList, bool &hasCycle, std::vector &nodesSorted) { - if (node->permanentMark) + if (node->hasPermanentMark()) return; - if (node->temporaryMark) { + if (node->hasTemporaryMark()) { hasCycle = true; return; } - node->temporaryMark = 1; + node->setTemporaryMark(); - auto const &edges = adjacencyList[node->index]; + auto const &edges = adjacencyList[node->index()]; for (auto edgeTarget =edges.begin(); edgeTarget != edges.end(); ++edgeTarget) { topoVisit(*edgeTarget, adjacencyList, hasCycle, nodesSorted); } - node->temporaryMark = 0; - node->permanentMark = 1; + node->setPermanentMark(); nodesSorted.push_back(*node); }; @@ -145,7 +161,7 @@ inline std::vector topoSort(std::vector &nodes, AdjacencyList &adjac hasCycle = false; auto currentNodeIt = std::find_if(nodes.begin(), nodes.end(), [](const Node& node) { - return node.permanentMark == 0; + return !node.hasPermanentMark(); }); // Do a topological sort of all inline components // afterwards, nodesSorted contains the nodes for the inline components in reverse topological order @@ -153,7 +169,7 @@ inline std::vector topoSort(std::vector &nodes, AdjacencyList &adjac Node& currentNode = *currentNodeIt; topoVisit(¤tNode, adjacencyList, hasCycle, nodesSorted); currentNodeIt = std::find_if(nodes.begin(), nodes.end(), [](const Node& node) { - return node.permanentMark == 0; + return !node.hasPermanentMark(); }); } return nodesSorted; diff --git a/src/qml/jit/qv4assemblercommon_p.h b/src/qml/jit/qv4assemblercommon_p.h index 63a88f287fa..c91a61a0a7e 100644 --- a/src/qml/jit/qv4assemblercommon_p.h +++ b/src/qml/jit/qv4assemblercommon_p.h @@ -73,7 +73,7 @@ class PlatformAssembler_X86_64_SysV : public JSC::MacroAssembler { public: - static const RegisterID NoRegister = RegisterID(-1); + static const RegisterID NoRegister = RegisterID::none; static const RegisterID ReturnValueRegister = RegisterID::eax; static const RegisterID ReturnValueRegisterValue = ReturnValueRegister; @@ -250,7 +250,7 @@ typedef PlatformAssembler_Win64 PlatformAssemblerBase; class PlatformAssembler_X86_All : public JSC::MacroAssembler { public: - static const RegisterID NoRegister = RegisterID(-1); + static const RegisterID NoRegister = RegisterID::none; static const RegisterID ReturnValueRegisterValue = RegisterID::eax; static const RegisterID ReturnValueRegisterTag = RegisterID::edx; @@ -340,7 +340,7 @@ typedef PlatformAssembler_X86_All PlatformAssemblerBase; class PlatformAssembler_ARM64 : public JSC::MacroAssembler { public: - static const RegisterID NoRegister = RegisterID(-1); + static const RegisterID NoRegister = RegisterID::none; static const RegisterID ReturnValueRegister = JSC::ARM64Registers::x0; static const RegisterID ReturnValueRegisterValue = ReturnValueRegister; @@ -439,7 +439,7 @@ typedef PlatformAssembler_ARM64 PlatformAssemblerBase; class PlatformAssembler_ARM32 : public JSC::MacroAssembler { public: - static const RegisterID NoRegister = RegisterID(-1); + static const RegisterID NoRegister = RegisterID::none; static const RegisterID ReturnValueRegisterValue = JSC::ARMRegisters::r0; static const RegisterID ReturnValueRegisterTag = JSC::ARMRegisters::r1; diff --git a/src/qml/jit/qv4baselinejit.cpp b/src/qml/jit/qv4baselinejit.cpp index b21acf93c74..ced4c3e057b 100644 --- a/src/qml/jit/qv4baselinejit.cpp +++ b/src/qml/jit/qv4baselinejit.cpp @@ -554,6 +554,8 @@ void BaselineJIT::generate_ThrowException() as->passEngineAsArg(0); BASELINEJIT_GENERATE_RUNTIME_CALL(ThrowException, CallResultDestination::Ignore); as->gotoCatchException(); + + // LOAD_ACC(); <- not needed here since it would be unreachable. } void BaselineJIT::generate_GetException() { as->getException(); } @@ -561,9 +563,11 @@ void BaselineJIT::generate_SetException() { as->setException(); } void BaselineJIT::generate_CreateCallContext() { + STORE_ACC(); as->prepareCallWithArgCount(1); as->passCppFrameAsArg(0); BASELINEJIT_GENERATE_RUNTIME_CALL(PushCallContext, CallResultDestination::Ignore); + LOAD_ACC(); } void BaselineJIT::generate_PushCatchContext(int index, int name) { as->pushCatchContext(index, name); } diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index ed282f5a617..cdcb5b3bffc 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -509,6 +509,9 @@ static QUrl urlForFileName(const QString &fileName) The script code will be evaluated in the context of the global object. + \note If you need to evaluate inside a QML context, use \l QQmlExpression + instead. + The evaluation of \a program can cause an \l{Script Exceptions}{exception} in the engine; in this case the return value will be the exception that was thrown (typically an \c{Error} object; see @@ -539,6 +542,8 @@ static QUrl urlForFileName(const QString &fileName) exception value will still be returned. Use \c exceptionStackTrace->isEmpty() to distinguish whether the value was a normal or an exceptional return value. + + \sa QQmlExpression::evaluate */ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, int lineNumber, QStringList *exceptionStackTrace) { @@ -838,6 +843,14 @@ QJSValue QJSEngine::create(QMetaType type, const void *ptr) return QJSValuePrivate::fromReturnedValue(v->asReturnedValue()); } +#if QT_VERSION < QT_VERSION_CHECK(7,0,0) +QJSValue QJSEngine::create(int typeId, const void *ptr) +{ + QMetaType type(typeId); + return create(type, ptr); +} +#endif + bool QJSEngine::convertManaged(const QJSManagedValue &value, int type, void *ptr) { return convertManaged(value, QMetaType(type), ptr); @@ -1097,13 +1110,9 @@ QJSValue QJSEngine::catchError() after installing translators in your application. By convention, an empty string means no translation from the language used in the source code is intended to occur. */ -void QJSEngine::setUiLanguage(const QString &language) -{ +void QJSEngine::setUiLanguage(const QString &language) { Q_D(QJSEngine); - if (language == d->uiLanguage) - return; - d->uiLanguage = language; - emit uiLanguageChanged(); + d->uiLanguage = language; // property takes care of signal emission if necessary } QString QJSEngine::uiLanguage() const @@ -1180,7 +1189,7 @@ QJSEngine *qjsEngine(const QObject *object) two different engines will not be valid if one of these engines is deleted. This option is similar to QScriptEngine::ScriptOwnership. - Generally an application doesn't need to set an object's ownership explicitly. the JavaScript + Generally an application doesn't need to set an object's ownership explicitly. The JavaScript memory manager uses a heuristic to set the default ownership. By default, an object that is created by the JavaScript memory manager has JavaScriptOwnership. The exception to this are the root objects created by calling QQmlComponent::create() or QQmlComponent::beginCreate(), which @@ -1193,10 +1202,17 @@ QJSEngine *qjsEngine(const QObject *object) but not to property getter invocations. Calling setObjectOwnership() overrides the default ownership. + + \sa {Data Ownership} */ /*! Sets the \a ownership of \a object. + + An object with \c JavaScriptOwnership is not garbage collected as long + as it still has a parent, even if there are no references to it. + + \sa QJSEngine::ObjectOwnership */ void QJSEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership) { @@ -1213,6 +1229,8 @@ void QJSEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership) /*! Returns the ownership of \a object. + + \sa QJSEngine::ObjectOwnership */ QJSEngine::ObjectOwnership QJSEngine::objectOwnership(QObject *object) { diff --git a/src/qml/jsapi/qjsengine.h b/src/qml/jsapi/qjsengine.h index 84730afe2b9..23578a63b6a 100644 --- a/src/qml/jsapi/qjsengine.h +++ b/src/qml/jsapi/qjsengine.h @@ -149,6 +149,9 @@ class Q_QML_EXPORT QJSEngine private: QJSManagedValue createManaged(QMetaType type, const void *ptr); QJSValue create(QMetaType type, const void *ptr); +#if QT_VERSION < QT_VERSION_CHECK(7,0,0) + QJSValue create(int id, const void *ptr); // only there for BC reasons +#endif static bool convertManaged(const QJSManagedValue &value, int type, void *ptr); static bool convertManaged(const QJSManagedValue &value, QMetaType type, void *ptr); diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h index fb88781852f..aa846bb246b 100644 --- a/src/qml/jsapi/qjsengine_p.h +++ b/src/qml/jsapi/qjsengine_p.h @@ -107,8 +107,8 @@ class Q_QML_PRIVATE_EXPORT QJSEnginePrivate : public QObjectPrivate // Shared by QQmlEngine mutable QRecursiveMutex mutex; - - QProperty uiLanguage; + void uiLanguageChanged() { Q_Q(QJSEngine); if (q) q->uiLanguageChanged(); } + Q_OBJECT_BINDABLE_PROPERTY(QJSEnginePrivate, QString, uiLanguage, &QJSEnginePrivate::uiLanguageChanged); // These methods may be called from the QML loader thread inline QQmlPropertyCache *cache(QObject *obj, QTypeRevision version = QTypeRevision(), bool doRef = false); diff --git a/src/qml/jsapi/qjsmanagedvalue.cpp b/src/qml/jsapi/qjsmanagedvalue.cpp index 454dc11fd8a..85406c21b24 100644 --- a/src/qml/jsapi/qjsmanagedvalue.cpp +++ b/src/qml/jsapi/qjsmanagedvalue.cpp @@ -65,6 +65,8 @@ QT_BEGIN_NAMESPACE * \inmodule QtQml * \since 6.1 * + * \inmodule QtQml + * * \brief QJSManagedValue represents a value on the JavaScript heap belonging to a QJSEngine. * * The QJSManagedValue class allows interaction with JavaScript values in most @@ -907,7 +909,7 @@ QJSValue QJSManagedValue::property(quint32 arrayIndex) const if (QV4::String *string = d->as()) { const QString qString = string->toQString(); - if (arrayIndex < qString.size()) + if (arrayIndex < quint32(qString.size())) return qString.sliced(arrayIndex, 1); return QJSValue(); } @@ -1121,8 +1123,11 @@ QStringList QJSManagedValue::jsMetaMembers() const const int size = heapClass->size; QStringList result; result.reserve(size); - for (int i = 0; i < size; ++i) - result.append(heapClass->keyAt(i)); + QV4::Scope scope(c->engine()); + for (int i = 0; i < size; ++i) { + QV4::ScopedValue key(scope, heapClass->keyAt(i)); + result.append(key->toQString()); + } return result; } diff --git a/src/qml/jsapi/qjsprimitivevalue.cpp b/src/qml/jsapi/qjsprimitivevalue.cpp index 1d93a3f0e14..94316c8e1d9 100644 --- a/src/qml/jsapi/qjsprimitivevalue.cpp +++ b/src/qml/jsapi/qjsprimitivevalue.cpp @@ -46,6 +46,9 @@ QT_BEGIN_NAMESPACE /*! \since 6.1 \class QJSPrimitiveUndefined + + \inmodule QtQml + \brief An empty marker type to signify the JavaScript Undefined type and its single value. \inmodule QtQml */ @@ -53,6 +56,9 @@ QT_BEGIN_NAMESPACE /*! \since 6.1 \class QJSPrimitiveNull + + \inmodule QtQml + \brief An empty marker type to signify the JavaScript null value. \inmodule QtQml */ @@ -187,6 +193,7 @@ QT_BEGIN_NAMESPACE /*! \fn QJSPrimitiveValue QJSPrimitiveValue::operator+(const QJSPrimitiveValue &lhs, const QJSPrimitiveValue &rhs) + \since 6.1 Perfoms the JavaScript '+' operation on \a lhs and \a rhs, and returns the diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index 03cd1e9aa9d..f9df4a40c5a 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -142,6 +142,16 @@ integers.append(jsArray.property(i).toInt()); } \endcode + + \section2 Converting to JSON + + It's possible to convert a QJSValue to a JSON type. For example, + to convert to an array, use \l QJSEngine::fromScriptValue(): + + \code + const QJsonValue jsonValue = engine.fromScriptValue(jsValue); + const QJsonArray jsonArray = jsonValue.toArray(); + \endcode */ /*! @@ -190,10 +200,11 @@ /*! \enum QJSValue::ObjectConversionBehavior - This enum is used to specify how JavaScript objects without an equivalent + This enum is used to specify how JavaScript objects and symbols without an equivalent native Qt type should be treated when converting to QVariant. \value ConvertJSObjects A best-effort, possibly lossy, conversion is attempted. + Symbols are converted to QString. \value RetainJSObjects The value is retained as QJSValue wrapped in QVariant. */ diff --git a/src/qml/jsapi/qjsvalue_p.h b/src/qml/jsapi/qjsvalue_p.h index cea48fd9e26..69837d6575b 100644 --- a/src/qml/jsapi/qjsvalue_p.h +++ b/src/qml/jsapi/qjsvalue_p.h @@ -75,7 +75,7 @@ enum PointerMask: quintptr { IsString = 0x1 }; -class Q_AUTOTEST_EXPORT QJSValuePrivate +class QJSValuePrivate { static const QV4::Value *managedValue(const QV4::Value &v) { diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h index 1873c41261b..4000deaeab2 100644 --- a/src/qml/jsruntime/qv4arraybuffer_p.h +++ b/src/qml/jsruntime/qv4arraybuffer_p.h @@ -72,7 +72,7 @@ struct Q_QML_PRIVATE_EXPORT SharedArrayBuffer : Object { void init(size_t length); void init(const QByteArray& array); void destroy(); - std::aligned_storage_t), alignof(QArrayDataPointer)> d; + struct { alignas(QArrayDataPointer) unsigned char data[sizeof(QArrayDataPointer)]; } d; const QArrayDataPointer &data() const { return *reinterpret_cast *>(&d); } QArrayDataPointer &data() { return *reinterpret_cast *>(&d); } bool isShared; diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index 577cc11cf41..224c8985362 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -563,7 +563,7 @@ uint ArrayData::append(Object *obj, ArrayObject *otherObj, uint n) ScopedValue v(scope); for (uint i = 0; i < n; ++i) obj->arraySet(oldSize + i, (v = otherObj->get(i))); - } else if (other && other->isSparse()) { + } else if (other->isSparse()) { Heap::SparseArrayData *os = static_cast(other->d()); if (other->hasAttributes()) { ScopedValue v(scope); @@ -586,7 +586,7 @@ uint ArrayData::append(Object *obj, ArrayObject *otherObj, uint n) obj->arrayPut(oldSize, os->values.data() + os->offset, chunk); toCopy -= chunk; if (toCopy) - obj->setArrayLength(oldSize + chunk + toCopy); + obj->arrayPut(oldSize + chunk, os->values.data(), toCopy); } return oldSize + n; @@ -670,8 +670,8 @@ bool ArrayElementLessThan::operator()(Value v1, Value v2) const return p1s->toQString() < p2s->toQString(); } -template -void sortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan) +template +void sortHelper(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan) { top: int span = int(end - start); @@ -716,7 +716,7 @@ void sortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t ++low; qSwap(*end, *low); - sortHelper(start, low, t, lessThan); + sortHelper(start, low, lessThan); start = low + 1; ++end; @@ -816,8 +816,36 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c ArrayElementLessThan lessThan(engine, static_cast(comparefn)); - Value *begin = thisObject->arrayData()->values.values; - sortHelper(begin, begin + len, *begin, lessThan); + const auto thisArrayData = thisObject->arrayData(); + uint startIndex = thisArrayData->mappedIndex(0); + uint endIndex = thisArrayData->mappedIndex(len - 1) + 1; + if (startIndex < endIndex) { + // Values are contiguous. Sort right away. + sortHelper( + thisArrayData->values.values + startIndex, + thisArrayData->values.values + endIndex, + lessThan); + } else { + // Values wrap around the end of the allocation. Close the gap to form a contiguous array. + // We're going to sort anyway. So we don't need to care about order. + + // ArrayElementLessThan sorts empty and undefined to the end of the array anyway, but we + // probably shouldn't rely on the unused slots to be actually undefined or empty. + + const uint gap = startIndex - endIndex; + const uint allocEnd = thisArrayData->values.alloc - 1; + for (uint i = 0; i < gap; ++i) { + const uint from = allocEnd - i; + const uint to = endIndex + i; + if (from < startIndex) + break; + + std::swap(thisArrayData->values.values[from], thisArrayData->values.values[to]); + } + + thisArrayData->offset = 0; + sortHelper(thisArrayData->values.values, thisArrayData->values.values + len, lessThan); + } #ifdef CHECK_SPARSE_ARRAYS thisObject->initSparseArray(); diff --git a/src/qml/jsruntime/qv4arrayiterator.cpp b/src/qml/jsruntime/qv4arrayiterator.cpp index 199b1a728a5..51387edf6ea 100644 --- a/src/qml/jsruntime/qv4arrayiterator.cpp +++ b/src/qml/jsruntime/qv4arrayiterator.cpp @@ -86,18 +86,18 @@ ReturnedValue ArrayIteratorPrototype::method_next(const FunctionObject *b, const return IteratorPrototype::createIterResultObject(scope.engine, Value::fromInt32(index), false); } - ReturnedValue elementValue = a->get(index); + QV4::ScopedValue elementValue(scope, a->get(index)); CHECK_EXCEPTION(); if (itemKind == ValueIteratorKind) { - return IteratorPrototype::createIterResultObject(scope.engine, Value::fromReturnedValue(elementValue), false); + return IteratorPrototype::createIterResultObject(scope.engine, elementValue, false); } else { Q_ASSERT(itemKind == KeyValueIteratorKind); ScopedArrayObject resultArray(scope, scope.engine->newArrayObject()); resultArray->arrayReserve(2); resultArray->arrayPut(0, Value::fromInt32(index)); - resultArray->arrayPut(1, Value::fromReturnedValue(elementValue)); + resultArray->arrayPut(1, elementValue); resultArray->setArrayLengthUnchecked(2); return IteratorPrototype::createIterResultObject(scope.engine, resultArray, false); diff --git a/src/qml/jsruntime/qv4compilationunitmapper.cpp b/src/qml/jsruntime/qv4compilationunitmapper.cpp index f3e2b445d12..6cff8d3c9bd 100644 --- a/src/qml/jsruntime/qv4compilationunitmapper.cpp +++ b/src/qml/jsruntime/qv4compilationunitmapper.cpp @@ -65,6 +65,11 @@ class StaticUnitCache s_staticUnits.insert(file, staticUnit); } + void remove(const QString &file) + { + s_staticUnits.remove(file); + } + private: QMutexLocker m_lock; @@ -105,4 +110,10 @@ CompiledData::Unit *CompilationUnitMapper::get( return data; } +void CompilationUnitMapper::invalidate(const QString &cacheFilePath) +{ + StaticUnitCache cache; + cache.remove(cacheFilePath); +} + QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4compilationunitmapper_p.h b/src/qml/jsruntime/qv4compilationunitmapper_p.h index 10ad0a6edea..c6773fdd0e5 100644 --- a/src/qml/jsruntime/qv4compilationunitmapper_p.h +++ b/src/qml/jsruntime/qv4compilationunitmapper_p.h @@ -69,6 +69,7 @@ class CompilationUnitMapper CompiledData::Unit *get( const QString &cacheFilePath, const QDateTime &sourceTimeStamp, QString *errorString); + static void invalidate(const QString &cacheFilePath); private: CompiledData::Unit *open( diff --git a/src/qml/jsruntime/qv4compilationunitmapper_unix.cpp b/src/qml/jsruntime/qv4compilationunitmapper_unix.cpp index a9ab2f5ccba..b66e6b94679 100644 --- a/src/qml/jsruntime/qv4compilationunitmapper_unix.cpp +++ b/src/qml/jsruntime/qv4compilationunitmapper_unix.cpp @@ -79,6 +79,16 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co // Data structure and qt version matched, so now we can access the rest of the file safely. length = static_cast(lseek(fd, 0, SEEK_END)); + /* Error out early on file corruption. We assume we can read header.unitSize bytes + later (even before verifying the checksum), potentially causing out-of-bound + reads + Also, no need to wait until checksum verification if we know beforehand + that the cached unit is bogus + */ + if (length != header.unitSize) { + *errorString = QStringLiteral("Potential file corruption, file too small"); + return nullptr; + } void *ptr = mmap(nullptr, length, PROT_READ, MAP_SHARED, fd, /*offset*/0); if (ptr == MAP_FAILED) { diff --git a/src/qml/jsruntime/qv4compilationunitmapper_win.cpp b/src/qml/jsruntime/qv4compilationunitmapper_win.cpp index b4f0a6ff4d0..de950ece056 100644 --- a/src/qml/jsruntime/qv4compilationunitmapper_win.cpp +++ b/src/qml/jsruntime/qv4compilationunitmapper_win.cpp @@ -86,6 +86,23 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co // Data structure and qt version matched, so now we can access the rest of the file safely. + /* Error out early on file corruption. We assume we can read header.unitSize bytes + later (even before verifying the checksum), potentially causing out-of-bound + reads + Also, no need to wait until checksum verification if we know beforehand + that the cached unit is bogus + */ + LARGE_INTEGER fileSize; + if (!GetFileSizeEx(handle, &fileSize)) { + *errorString = QStringLiteral("Could not determine file size"); + return nullptr; + } + if (header.unitSize != fileSize.QuadPart) { + *errorString = QStringLiteral("Potential file corruption, file too small"); + return nullptr; + } + + HANDLE fileMappingHandle = CreateFileMapping(handle, 0, PAGE_READONLY, 0, 0, 0); if (!fileMappingHandle) { *errorString = qt_error_string(GetLastError()); diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 282046f3fab..c3df66f67e5 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -334,9 +334,14 @@ ReturnedValue ExecutionContext::getProperty(String *name) case Heap::ExecutionContext::Type_CallContext: { Heap::CallContext *c = static_cast(ctx); - uint index = c->internalClass->indexOfValueOrGetter(id); - if (index < UINT_MAX) + const uint index = c->internalClass->indexOfValueOrGetter(id); + if (index < c->locals.alloc) return c->locals[index].asReturnedValue(); + + // TODO: We should look up the module imports here, but those are part of the CU: + // imports[index - c->locals.size]; + // See QTBUG-118478 + Q_FALLTHROUGH(); } case Heap::ExecutionContext::Type_WithContext: @@ -384,9 +389,14 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) case Heap::ExecutionContext::Type_CallContext: { Heap::CallContext *c = static_cast(ctx); - uint index = c->internalClass->indexOfValueOrGetter(id); - if (index < UINT_MAX) + const uint index = c->internalClass->indexOfValueOrGetter(id); + if (index < c->locals.alloc) return c->locals[index].asReturnedValue(); + + // TODO: We should look up the module imports here, but those are part of the CU: + // imports[index - c->locals.size]; + // See QTBUG-118478 + Q_FALLTHROUGH(); } case Heap::ExecutionContext::Type_GlobalContext: { diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index 9ab0bb56283..12225d38662 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -78,10 +78,21 @@ QTBUG-75585 for an explanation and possible workarounds. */ #define USE_QTZ_SYSTEM_ZONE +#elif defined(Q_OS_WASM) +/* + TODO: evaluate using this version of the code more generally, rather than + the #else branches of the various USE_QTZ_SYSTEM_ZONE choices. It might even + work better than the timezone variant; experiments needed. +*/ +// Kludge around the lack of time-zone info using QDateTime. +// It uses localtime() and friends to determine offsets from UTC. +#define USE_QDT_LOCAL_TIME #endif #ifdef USE_QTZ_SYSTEM_ZONE #include +#elif defined(USE_QDT_LOCAL_TIME) +// QDateTime already included above #else # ifdef Q_OS_WIN # include @@ -356,6 +367,7 @@ static inline double MakeDate(double day, double time) mean a whole day of DST offset for some zones, that have crossed the international date line. This shall confuse client code.) The bug report against the ECMAScript spec is https://github.com/tc39/ecma262/issues/725 + and they've now changed the spec so that the following conforms to it ;^> */ static inline double DaylightSavingTA(double t, double localTZA) // t is a UTC time @@ -363,6 +375,12 @@ static inline double DaylightSavingTA(double t, double localTZA) // t is a UTC t return QTimeZone::systemTimeZone().offsetFromUtc( QDateTime::fromMSecsSinceEpoch(qint64(t), Qt::UTC)) * 1e3 - localTZA; } +#elif defined(USE_QDT_LOCAL_TIME) +static inline double DaylightSavingTA(double t, double localTZA) // t is a UTC time +{ + return QDateTime::fromMSecsSinceEpoch(qint64(t), Qt::UTC + ).toLocalTime().offsetFromUtc() * 1e3 - localTZA; +} #else // This implementation fails to take account of past changes in standard offset. static inline double DaylightSavingTA(double t, double /*localTZA*/) @@ -632,7 +650,9 @@ static inline double ParseString(const QString &s, double localTZA) QStringLiteral("d MMMM, yyyy hh:mm"), QStringLiteral("d MMMM, yyyy hh:mm:ss"), + // ISO 8601 and RFC 2822 with a GMT as prefix on its offset, or GMT as zone. QStringLiteral("yyyy-MM-dd hh:mm:ss t"), + QStringLiteral("ddd, d MMM yyyy hh:mm:ss t"), }; for (const QString &format : formats) { @@ -722,6 +742,26 @@ static double getLocalTZA() // TODO: QTimeZone::resetSystemTimeZone(), see QTBUG-56899 and comment above. // Standard offset, with no daylight-savings adjustment, in ms: return QTimeZone::systemTimeZone().standardTimeOffset(QDateTime::currentDateTime()) * 1e3; +#elif defined(USE_QDT_LOCAL_TIME) + QDate today = QDate::currentDate(); + QDateTime near = today.startOfDay(Qt::LocalTime); + // Early out if we're in standard time anyway: + if (!near.isDaylightTime()) + return near.offsetFromUtc() * 1000; + int year, month; + today.getDate(&year, &month, nullptr); + // One of the solstices is probably in standard time: + QDate summer(year, 6, 21), winter(year - (month < 7 ? 1 : 0), 12, 21); + // But check the one closest to the present by preference, in case there's a + // standard time offset change between them: + QDateTime far = summer.startOfDay(Qt::LocalTime); + near = winter.startOfDay(Qt::LocalTime); + if (month > 3 && month < 10) + near.swap(far); + bool isDst = near.isDaylightTime(); + if (isDst && far.isDaylightTime()) // Permanent DST, probably an hour west: + return (qMin(near.offsetFromUtc(), far.offsetFromUtc()) - 3600) * 1000; + return (isDst ? far : near).offsetFromUtc() * 1000; #else # ifdef Q_OS_WIN TIME_ZONE_INFORMATION tzInfo; diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 958a994cc30..b303dd497a5 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -356,6 +356,9 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) if (ok && envMaxGCStackSize > 0) m_maxGCStackSize = envMaxGCStackSize; + // We allocate guard pages around our stacks. + const size_t guardPages = 2 * WTF::pageSize(); + memoryManager = new QV4::MemoryManager(this); if (maxCallDepth == -1) { @@ -366,7 +369,13 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok); if (!ok || maxCallDepth <= 0) { #if defined(QT_NO_DEBUG) && !defined(__SANITIZE_ADDRESS__) && !__has_feature(address_sanitizer) +#ifdef Q_OS_QNX + maxCallDepth = 640; // QNX's stack is only 512k by default +#elif defined(Q_OS_WIN) + maxCallDepth = 640; // We've seen crashes around 750. +#else maxCallDepth = 1234; +#endif #else // no (tail call) optimization is done, so there'll be a lot mare stack frames active maxCallDepth = 200; @@ -379,9 +388,9 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) // reserve space for the JS stack // we allow it to grow to a bit more than m_maxJSStackSize, as we can overshoot due to ScopedValues // allocated outside of JIT'ed methods. - *jsStack = WTF::PageAllocation::allocate(m_maxJSStackSize + 256*1024, WTF::OSAllocator::JSVMStackPages, - /* writable */ true, /* executable */ false, - /* includesGuardPages */ true); + *jsStack = WTF::PageAllocation::allocate( + m_maxJSStackSize + 256*1024 + guardPages, WTF::OSAllocator::JSVMStackPages, + /* writable */ true, /* executable */ false, /* includesGuardPages */ true); jsStackBase = (Value *)jsStack->base(); #ifdef V4_USE_VALGRIND VALGRIND_MAKE_MEM_UNDEFINED(jsStackBase, m_maxJSStackSize + 256*1024); @@ -389,9 +398,9 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) jsStackTop = jsStackBase; - *gcStack = WTF::PageAllocation::allocate(m_maxGCStackSize, WTF::OSAllocator::JSVMStackPages, - /* writable */ true, /* executable */ false, - /* includesGuardPages */ true); + *gcStack = WTF::PageAllocation::allocate( + m_maxGCStackSize + guardPages, WTF::OSAllocator::JSVMStackPages, + /* writable */ true, /* executable */ false, /* includesGuardPages */ true); { ok = false; @@ -1497,7 +1506,9 @@ QQmlError ExecutionEngine::catchExceptionAsQmlError() // Variant conversion code typedef QSet V4ObjectSet; -static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjects, V4ObjectSet *visitedObjects); +static QVariant toVariant( + QV4::ExecutionEngine *e, const QV4::Value &value, QMetaType typeHint, + bool createJSValueForObjectsAndSymbols, V4ObjectSet *visitedObjects); static QObject *qtObjectFromJS(const QV4::Value &value); static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V4ObjectSet *visitedObjects = nullptr); static bool convertToNativeQObject(const QV4::Value &value, QMetaType targetType, void **result); @@ -1509,7 +1520,9 @@ static QV4::ReturnedValue variantToJS(QV4::ExecutionEngine *v4, const QVariant & return v4->metaTypeToJS(value.metaType(), value.constData()); } -static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMetaType metaType, bool createJSValueForObjects, V4ObjectSet *visitedObjects) +static QVariant toVariant( + QV4::ExecutionEngine *e, const QV4::Value &value, QMetaType metaType, + bool createJSValueForObjectsAndSymbols, V4ObjectSet *visitedObjects) { Q_ASSERT (!value.isEmpty()); QV4::Scope scope(e); @@ -1521,6 +1534,12 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet if (typeHint == QMetaType::Bool) return QVariant(value.toBoolean()); + if (typeHint == QMetaType::Double) + return QVariant(value.toNumber()); + + if (typeHint == QMetaType::Float) + return QVariant(float(value.toNumber())); + if (typeHint == QMetaType::QJsonValue) return QVariant::fromValue(QV4::JsonObject::toJsonValue(value)); @@ -1597,9 +1616,11 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet continue; } } - asVariant = toVariant(e, arrayValue, valueMetaType, false, - visitedObjects); - if (valueMetaType.id() != QMetaType::QVariant) { + + asVariant = toVariant(e, arrayValue, valueMetaType, false, visitedObjects); + if (valueMetaType == QMetaType::fromType()) { + retnAsIterable.metaContainer().addValue(retn.data(), &asVariant); + } else { auto originalType = asVariant.metaType(); bool couldConvert = asVariant.convert(valueMetaType); if (!couldConvert) { @@ -1610,8 +1631,8 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet // create default constructed value asVariant = QVariant(valueMetaType, nullptr); } + retnAsIterable.metaContainer().addValue(retn.data(), asVariant.constData()); } - retnAsIterable.metaContainer().addValue(retn.data(), asVariant.constData()); } return retn; } @@ -1640,6 +1661,9 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet return *ld->d()->locale; #endif if (const QV4::DateObject *d = value.as()) { + // NOTE: since we convert QTime to JS Date, + // round trip will change the variant type (to QDateTime)! + auto dt = d->toQDateTime(); // See ExecutionEngine::metaTypeFromJS()'s handling of QMetaType::Date: if (typeHint == QMetaType::QDate) { @@ -1653,7 +1677,11 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet return d->toQUrl(); if (const ArrayBuffer *d = value.as()) return d->asByteArray(); - // NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)! + if (const Symbol *symbol = value.as()) { + return createJSValueForObjectsAndSymbols + ? QVariant::fromValue(QJSValuePrivate::fromReturnedValue(symbol->asReturnedValue())) + : symbol->descriptiveString(); + } QV4::ScopedObject o(scope, value); Q_ASSERT(o); @@ -1663,16 +1691,17 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, QMet return re->toQRegularExpression(); #endif - if (createJSValueForObjects) + if (createJSValueForObjectsAndSymbols) return QVariant::fromValue(QJSValuePrivate::fromReturnedValue(o->asReturnedValue())); return objectToVariant(e, o, visitedObjects); } -QVariant ExecutionEngine::toVariant(const Value &value, QMetaType typeHint, bool createJSValueForObjects) +QVariant ExecutionEngine::toVariant( + const Value &value, QMetaType typeHint, bool createJSValueForObjectsAndSymbols) { - return ::toVariant(this, value, typeHint, createJSValueForObjects, nullptr); + return ::toVariant(this, value, typeHint, createJSValueForObjectsAndSymbols, nullptr); } static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V4ObjectSet *visitedObjects) @@ -1703,7 +1732,8 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V int length = a->getLength(); for (int ii = 0; ii < length; ++ii) { v = a->get(ii); - list << ::toVariant(e, v, QMetaType {}, /*createJSValueForObjects*/false, visitedObjects); + list << ::toVariant( + e, v, QMetaType {}, /*createJSValueForObjectsAndSymbols*/false, visitedObjects); } result = list; @@ -1719,7 +1749,9 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V break; QString key = name->toQStringNoThrow(); - map.insert(key, ::toVariant(e, val, /*type hint*/ QMetaType {}, /*createJSValueForObjects*/false, visitedObjects)); + map.insert(key, ::toVariant( + e, val, /*type hint*/ QMetaType {}, + /*createJSValueForObjectsAndSymbols*/false, visitedObjects)); } result = map; @@ -1994,6 +2026,25 @@ int ExecutionEngine::maxGCStackSize() const return m_maxGCStackSize; } +/*! + \internal + Returns \a length converted to int if its safe to + pass to \c Scope::alloc. + Otherwise it throws a RangeError, and returns 0. + */ +int ExecutionEngine::safeForAllocLength(qint64 len64) +{ + if (len64 < 0ll || len64 > qint64(std::numeric_limits::max())) { + this->throwRangeError(QStringLiteral("Invalid array length.")); + return 0; + } + if (len64 > qint64(this->jsStackLimit - this->jsStackTop)) { + this->throwRangeError(QStringLiteral("Array too large for apply().")); + return 0; + } + return len64; +} + ReturnedValue ExecutionEngine::global() { return globalObject->asReturnedValue(); @@ -2186,7 +2237,7 @@ void ExecutionEngine::setQmlEngine(QQmlEngine *engine) static void freeze_recursive(QV4::ExecutionEngine *v4, QV4::Object *object) { - if (object->as() || object->internalClass()->isFrozen) + if (object->as() || object->internalClass()->isFrozen()) return; QV4::Scope scope(v4); @@ -2295,6 +2346,8 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi case QMetaType::QByteArray: if (const ArrayBuffer *ab = value.as()) *reinterpret_cast(data) = ab->asByteArray(); + else if (const String *string = value.as()) + *reinterpret_cast(data) = string->toQString().toUtf8(); else *reinterpret_cast(data) = QByteArray(); return true; @@ -2390,7 +2443,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi const QV4::ArrayObject *a = value.as(); if (a) { *reinterpret_cast(data) = a->engine()->toVariant( - *a, /*typeHint*/QMetaType{}, /*createJSValueForObjects*/false).toList(); + *a, /*typeHint*/QMetaType{}, /*createJSValueForObjectsAndSymbols*/false).toList(); return true; } break; @@ -2404,18 +2457,20 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi break; } case QMetaType::QVariant: - if (const QV4::Managed *m = value.as()) - *reinterpret_cast(data) = m->engine()->toVariant(value, /*typeHint*/QMetaType{}, /*createJSValueForObjects*/false); - else if (value.isNull()) + if (const QV4::Managed *m = value.as()) { + *reinterpret_cast(data) = m->engine()->toVariant( + value, /*typeHint*/QMetaType{}, /*createJSValueForObjectsAndSymbols*/false); + } else if (value.isNull()) { *reinterpret_cast(data) = QVariant::fromValue(nullptr); - else if (value.isUndefined()) + } else if (value.isUndefined()) { *reinterpret_cast(data) = QVariant(); - else if (value.isBoolean()) + } else if (value.isBoolean()) { *reinterpret_cast(data) = QVariant(value.booleanValue()); - else if (value.isInteger()) + } else if (value.isInteger()) { *reinterpret_cast(data) = QVariant(value.integerValue()); - else if (value.isDouble()) + } else if (value.isDouble()) { *reinterpret_cast(data) = QVariant(value.doubleValue()); + } return true; case QMetaType::QJsonValue: *reinterpret_cast(data) = QV4::JsonObject::toJsonValue(value); @@ -2448,6 +2503,13 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi return true; } } + + if (metaType == QMetaType::fromType>()) { + if (const QV4::QmlListWrapper *wrapper = value.as()) { + *reinterpret_cast *>(data) = wrapper->d()->property(); + return true; + } + } } { @@ -2460,25 +2522,6 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi } } -#if 0 - if (isQtVariant(value)) { - const QVariant &var = variantValue(value); - // ### Enable once constructInPlace() is in qt master. - if (var.userType() == type) { - QMetaType::constructInPlace(type, data, var.constData()); - return true; - } - if (var.canConvert(type)) { - QVariant vv = var; - vv.convert(type); - Q_ASSERT(vv.userType() == type); - QMetaType::constructInPlace(type, data, vv.constData()); - return true; - } - - } -#endif - // Try to use magic; for compatibility with qjsvalue_cast. if (convertToNativeQObject(value, metaType, reinterpret_cast(data))) @@ -2529,6 +2572,15 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi } else if (metaType == QMetaType::fromType()) { QJSValuePrivate::setValue(reinterpret_cast(data), value.asReturnedValue()); return true; + } else if (!isPointer) { + QVariant val; + if (QQml_valueTypeProvider()->createValueType( + metaType.id(), QJSValuePrivate::fromReturnedValue(value.asReturnedValue()), val)) { + Q_ASSERT(val.metaType() == metaType); + metaType.destruct(data); + metaType.construct(data, val.constData()); + return true; + } } return false; diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index db6bfcc84bd..d5e32ebedcb 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -682,7 +682,9 @@ struct Q_QML_EXPORT ExecutionEngine : public EngineBase QQmlError catchExceptionAsQmlError(); // variant conversions - QVariant toVariant(const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjects = true); + QVariant toVariant( + const QV4::Value &value, QMetaType typeHint, + bool createJSValueForObjectsAndSymbols = true); QV4::ReturnedValue fromVariant(const QVariant &); QVariantMap variantMapFromJS(const QV4::Object *o); @@ -694,6 +696,7 @@ struct Q_QML_EXPORT ExecutionEngine : public EngineBase int maxGCStackSize() const; bool checkStackLimits(); + int safeForAllocLength(qint64 len64); bool canJIT(Function *f = nullptr) { @@ -778,6 +781,9 @@ struct Q_QML_EXPORT ExecutionEngine : public EngineBase int argc, void **args, QMetaType *types); private: + template + friend struct ExecutionEngineCallDepthRecorder; + QV4::ReturnedValue fromData( const QMetaType &type, const void *ptr, const QVariant *variant = nullptr); @@ -813,12 +819,15 @@ struct Q_QML_EXPORT ExecutionEngine : public EngineBase #define CHECK_STACK_LIMITS(v4) if ((v4)->checkStackLimits()) return Encode::undefined(); \ ExecutionEngineCallDepthRecorder _executionEngineCallDepthRecorder(v4); +template struct ExecutionEngineCallDepthRecorder { ExecutionEngine *ee; - ExecutionEngineCallDepthRecorder(ExecutionEngine *e): ee(e) { ++ee->callDepth; } - ~ExecutionEngineCallDepthRecorder() { --ee->callDepth; } + ExecutionEngineCallDepthRecorder(ExecutionEngine *e): ee(e) { ee->callDepth += Frames; } + ~ExecutionEngineCallDepthRecorder() { ee->callDepth -= Frames; } + + bool hasOverflow() const { return ee->callDepth >= ExecutionEngine::maxCallDepth; } }; inline bool ExecutionEngine::checkStackLimits() diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index ade5204f9ee..ba10d29d513 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -69,14 +69,16 @@ #include #include -#if defined(QML_COMPILE_HASH) +static_assert(QV4::CompiledData::QmlCompileHashSpace > QML_COMPILE_HASH_LENGTH); + +#if defined(QML_COMPILE_HASH) && defined(QML_COMPILE_HASH_LENGTH) && QML_COMPILE_HASH_LENGTH > 0 # ifdef Q_OS_LINUX // Place on a separate section on Linux so it's easier to check from outside // what the hash version is. __attribute__((section(".qml_compile_hash"))) # endif -const char qml_compile_hash[48 + 1] = QML_COMPILE_HASH; -static_assert(sizeof(QV4::CompiledData::Unit::libraryVersionHash) >= QML_COMPILE_HASH_LENGTH + 1, +const char qml_compile_hash[QV4::CompiledData::QmlCompileHashSpace] = QML_COMPILE_HASH; +static_assert(sizeof(QV4::CompiledData::Unit::libraryVersionHash) > QML_COMPILE_HASH_LENGTH, "Compile hash length exceeds reserved size in data structure. Please adjust and bump the format version"); #else # error "QML_COMPILE_HASH must be defined for the build of QtDeclarative to ensure version checking for cache files" @@ -159,10 +161,10 @@ QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine) data->regexpTableSize * sizeof(QV4::Value)); for (uint i = 0; i < data->regexpTableSize; ++i) { const CompiledData::RegExp *re = data->regexpAt(i); - uint f = re->flags; + uint f = re->flags(); const CompiledData::RegExp::Flags flags = static_cast(f); runtimeRegularExpressions[i] = QV4::RegExp::create( - engine, stringAt(re->stringIndex), flags); + engine, stringAt(re->stringIndex()), flags); } if (data->lookupTableSize) { @@ -173,7 +175,7 @@ QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine) QV4::Lookup *l = runtimeLookups + i; CompiledData::Lookup::Type type - = CompiledData::Lookup::Type(uint(compiledLookups[i].type_and_flags)); + = CompiledData::Lookup::Type(uint(compiledLookups[i].typeAndFlags())); if (type == CompiledData::Lookup::Type_Getter) l->getter = QV4::Lookup::getterGeneric; else if (type == CompiledData::Lookup::Type_Setter) @@ -182,7 +184,7 @@ QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine) l->globalGetter = QV4::Lookup::globalGetterGeneric; else if (type == CompiledData::Lookup::Type_QmlContextPropertyGetter) l->qmlContextPropertyGetter = QQmlContextWrapper::resolveQmlContextPropertyLookupGetter; - l->nameIndex = compiledLookups[i].nameIndex; + l->nameIndex = compiledLookups[i].nameIndex(); } } @@ -203,8 +205,8 @@ QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine) runtimeClasses[i] = runtimeClasses[i]->addMember( engine->identifierTable->asPropertyKey( - runtimeStrings[member->nameOffset]), - member->isAccessor + runtimeStrings[member->nameOffset()]), + member->isAccessor() ? QV4::Attr_Accessor : QV4::Attr_Data); } @@ -316,20 +318,8 @@ void ExecutableCompilationUnit::unlink() propertyCaches.clear(); if (runtimeLookups) { - for (uint i = 0; i < data->lookupTableSize; ++i) { - QV4::Lookup &l = runtimeLookups[i]; - if (l.getter == QV4::QObjectWrapper::lookupGetter - || l.setter == QV4::QObjectWrapper::lookupSetter - || l.getter == QQmlTypeWrapper::lookupSingletonProperty) { - if (QQmlPropertyCache *pc = l.qobjectLookup.propertyCache) - pc->release(); - } - if (l.qmlContextPropertyGetter == QQmlContextWrapper::lookupScopeObjectProperty - || l.qmlContextPropertyGetter == QQmlContextWrapper::lookupContextObjectProperty) { - if (QQmlPropertyCache *pc = l.qobjectLookup.propertyCache) - pc->release(); - } - } + for (uint i = 0; i < data->lookupTableSize; ++i) + runtimeLookups[i].releasePropertyCache(); } dependentScripts.clear(); @@ -400,7 +390,7 @@ IdentifierHash ExecutableCompilationUnit::createNamedObjectsPerComponent(int com const quint32_le *namedObjectIndexPtr = component->namedObjectsInComponentTable(); for (quint32 i = 0; i < component->nNamedObjectsInComponent; ++i, ++namedObjectIndexPtr) { const CompiledData::Object *namedObject = objectAt(*namedObjectIndexPtr); - namedObjectCache.add(runtimeStrings[namedObject->idNameIndex], namedObject->id); + namedObjectCache.add(runtimeStrings[namedObject->idNameIndex], namedObject->objectId()); } Q_ASSERT(!namedObjectCache.isEmpty()); return *namedObjectsPerComponentCache.insert(componentObjectIndex, namedObjectCache); @@ -452,13 +442,14 @@ void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngi // We need to first iterate over all inline components, as the containing component might create instances of them // and in that case we need to add its object count for (auto nodeIt = nodesSorted.rbegin(); nodeIt != nodesSorted.rend(); ++nodeIt) { - const auto &ic = allICs.at(nodeIt->index); + const auto &ic = allICs.at(nodeIt->index()); int lastICRoot = ic.objectIndex; for (int i = ic.objectIndex; iflags & QV4::CompiledData::Object::IsInlineComponentRoot) - || !(obj->flags & QV4::CompiledData::Object::InPartOfInlineComponent); + (i != lastICRoot + && obj->hasFlag(QV4::CompiledData::Object::IsInlineComponentRoot)) + || !obj->hasFlag(QV4::CompiledData::Object::InPartOfInlineComponent); if (leftCurrentInlineComponent) break; inlineComponentData[lastICRoot].totalBindingCount += obj->nBindings; @@ -488,9 +479,9 @@ void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngi int objectCount = 0; for (quint32 i = 0, count = this->objectCount(); i < count; ++i) { const QV4::CompiledData::Object *obj = objectAt(i); - if (obj->flags & QV4::CompiledData::Object::InPartOfInlineComponent) { + if (obj->hasFlag(QV4::CompiledData::Object::InPartOfInlineComponent)) continue; - } + bindingCount += obj->nBindings; if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) { const auto type = typeRef->type(); @@ -526,6 +517,15 @@ int ExecutableCompilationUnit::totalObjectCount() const { return inlineComponentData[icRoot].totalObjectCount; } +ResolvedTypeReference *ExecutableCompilationUnit::resolvedType(QMetaType type) const +{ + for (ResolvedTypeReference *ref : std::as_const(resolvedTypes)) { + if (ref->type().typeId() == type) + return ref; + } + return nullptr; +} + int ExecutableCompilationUnit::totalParserStatusCount() const { if (icRoot == -1) return m_totalParserStatusCount; @@ -632,7 +632,9 @@ Heap::Module *ExecutableCompilationUnit::instantiate(ExecutionEngine *engine) referenceErrorMessage += QStringLiteral(" because "); referenceErrorMessage += url.toString(QUrl::RemoveFragment); referenceErrorMessage += QStringLiteral(" is not an object"); - engine->throwReferenceError(referenceErrorMessage, fileName(), entry.location.line, entry.location.column); + engine->throwReferenceError( + referenceErrorMessage, fileName(), + entry.location.line(), entry.location.column()); return nullptr; } @@ -651,7 +653,9 @@ Heap::Module *ExecutableCompilationUnit::instantiate(ExecutionEngine *engine) if (!valuePtr) { QString referenceErrorMessage = QStringLiteral("Unable to resolve import reference "); referenceErrorMessage += importName->toQString(); - engine->throwReferenceError(referenceErrorMessage, fileName(), entry.location.line, entry.location.column); + engine->throwReferenceError( + referenceErrorMessage, fileName(), + entry.location.line(), entry.location.column()); return nullptr; } imports[i] = valuePtr; @@ -668,7 +672,9 @@ Heap::Module *ExecutableCompilationUnit::instantiate(ExecutionEngine *engine) if (!dependentModuleUnit->resolveExport(importName)) { QString referenceErrorMessage = QStringLiteral("Unable to resolve re-export reference "); referenceErrorMessage += importName->toQString(); - engine->throwReferenceError(referenceErrorMessage, fileName(), entry.location.line, entry.location.column); + engine->throwReferenceError( + referenceErrorMessage, fileName(), + entry.location.line(), entry.location.column()); return nullptr; } } @@ -860,8 +866,14 @@ bool ExecutableCompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorSt return CompiledData::SaveableUnitPointer(unitData()).saveToDisk( [&unitUrl, errorString](const char *data, quint32 size) { - return CompiledData::SaveableUnitPointer::writeDataToFile(localCacheFilePath(unitUrl), data, - size, errorString); + const QString cachePath = localCacheFilePath(unitUrl); + if (CompiledData::SaveableUnitPointer::writeDataToFile( + cachePath, data, size, errorString)) { + CompilationUnitMapper::invalidate(cachePath); + return true; + } + + return false; }); } @@ -891,7 +903,7 @@ QString ExecutableCompilationUnit::bindingValueAsString(const CompiledData::Bind { using namespace CompiledData; #if QT_CONFIG(translation) - switch (binding->type) { + switch (binding->type()) { case Binding::Type_TranslationById: { const TranslationData &translation = data->translations()[binding->value.translationDataIndex]; @@ -952,9 +964,15 @@ bool ExecutableCompilationUnit::verifyHeader( } } -#if defined(QML_COMPILE_HASH) - if (qstrcmp(qml_compile_hash, unit->libraryVersionHash) != 0) { - *errorString = QStringLiteral("QML library version mismatch. Expected compile hash does not match"); +#if defined(QML_COMPILE_HASH) && defined(QML_COMPILE_HASH_LENGTH) && QML_COMPILE_HASH_LENGTH > 0 + if (qstrncmp(qml_compile_hash, unit->libraryVersionHash, QML_COMPILE_HASH_LENGTH) != 0) { + *errorString = QStringLiteral("QML compile hashes don't match. Found %1 expected %2") + .arg(QString::fromLatin1( + QByteArray(unit->libraryVersionHash, QML_COMPILE_HASH_LENGTH) + .toPercentEncoding()), + QString::fromLatin1( + QByteArray(qml_compile_hash, QML_COMPILE_HASH_LENGTH) + .toPercentEncoding())); return false; } #else diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h index 9ceec1fbf73..38d35baf3fa 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit_p.h +++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h @@ -175,6 +175,7 @@ class Q_QML_PRIVATE_EXPORT ExecutableCompilationUnit final: public CompiledData: QVector> dependentScripts; ResolvedTypeReferenceMap resolvedTypes; ResolvedTypeReference *resolvedType(int id) const { return resolvedTypes.value(id); } + ResolvedTypeReference *resolvedType(QMetaType type) const; bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const; diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index f6001da1f86..d92714a9e25 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -77,7 +77,7 @@ bool Function::call(const Value *thisObject, void **a, const QMetaType *types, i engine->jsStackTop += frame.requiredJSStackFrameSize(); Moth::VME::exec(&frame, engine); frame.pop(engine); - return true; + return !frame.isReturnValueUndefined(); } ReturnedValue Function::call(const Value *thisObject, const Value *argv, int argc, const ExecutionContext *context) { @@ -208,7 +208,8 @@ QString Function::prettyName(const Function *function, const void *code) QQmlSourceLocation Function::sourceLocation() const { - return QQmlSourceLocation(sourceFile(), compiledFunction->location.line, compiledFunction->location.column); + return QQmlSourceLocation( + sourceFile(), compiledFunction->location.line(), compiledFunction->location.column()); } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index 7577161c014..20afeff140b 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -138,6 +138,7 @@ struct Q_QML_EXPORT Function : public FunctionData { inline bool isStrict() const { return compiledFunction->flags & CompiledData::Function::IsStrict; } inline bool isArrowFunction() const { return compiledFunction->flags & CompiledData::Function::IsArrowFunction; } inline bool isGenerator() const { return compiledFunction->flags & CompiledData::Function::IsGenerator; } + inline bool isClosureWrapper() const { return compiledFunction->flags & CompiledData::Function::IsClosureWrapper; } QQmlSourceLocation sourceLocation() const; diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index d3bafbe0550..798cfc131d2 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -387,15 +387,10 @@ ReturnedValue FunctionPrototype::method_apply(const QV4::FunctionObject *b, cons if (!arr) return v4->throwTypeError(); - const qint64 len64 = arr->getLength(); - if (len64 < 0ll || len64 > qint64(std::numeric_limits::max())) - return v4->throwRangeError(QStringLiteral("Invalid array length.")); - if (len64 > qint64(v4->jsStackLimit - v4->jsStackTop)) - return v4->throwRangeError(QStringLiteral("Array too large for apply().")); - - const uint len = uint(len64); - Scope scope(v4); + const uint len = v4->safeForAllocLength(arr->getLength()); + CHECK_EXCEPTION(); + Value *arguments = scope.alloc(len); if (len) { if (ArgumentsObject::isNonStrictArgumentsObject(arr) && !arr->cast()->fullyCreated()) { diff --git a/src/qml/jsruntime/qv4generatorobject_p.h b/src/qml/jsruntime/qv4generatorobject_p.h index 6eb7b306e0d..3dd2870e5b2 100644 --- a/src/qml/jsruntime/qv4generatorobject_p.h +++ b/src/qml/jsruntime/qv4generatorobject_p.h @@ -87,7 +87,6 @@ struct GeneratorPrototype : FunctionObject { #define GeneratorObjectMembers(class, Member) \ Member(class, Pointer, ExecutionContext *, context) \ - Member(class, Pointer, GeneratorFunction *, function) \ Member(class, NoMark, GeneratorState, state) \ Member(class, NoMark, JSTypesStackFrame, cppFrame) \ Member(class, Pointer, ArrayObject *, values) \ diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index 14934568534..0abdd76c964 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -307,7 +307,6 @@ struct PropertyAttributes void clear() { m_all = 0; } bool isEmpty() const { return !m_all; } - uint flags() const { return m_flags; } uint all() const { return m_all; } bool operator==(PropertyAttributes other) { diff --git a/src/qml/jsruntime/qv4identifierhash.cpp b/src/qml/jsruntime/qv4identifierhash.cpp index d349b7c4fed..e974c2c0ad8 100644 --- a/src/qml/jsruntime/qv4identifierhash.cpp +++ b/src/qml/jsruntime/qv4identifierhash.cpp @@ -127,7 +127,7 @@ const IdentifierHashEntry *IdentifierHash::lookup(const QString &str) const if (!d) return nullptr; - PropertyKey id = d->identifierTable->asPropertyKey(str); + PropertyKey id = d->identifierTable->asPropertyKey(str, IdentifierTable::ForceConversionToId); return lookup(id); } @@ -146,7 +146,7 @@ inline const PropertyKey IdentifierHash::toIdentifier(const QString &str) const { Q_ASSERT(d); - return d->identifierTable->asPropertyKey(str); + return d->identifierTable->asPropertyKey(str, IdentifierTable::ForceConversionToId); } inline diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp index 7c5bc3188c6..f6d10a575fe 100644 --- a/src/qml/jsruntime/qv4identifiertable.cpp +++ b/src/qml/jsruntime/qv4identifiertable.cpp @@ -285,12 +285,17 @@ void IdentifierTable::sweep() size -= freed; } -PropertyKey IdentifierTable::asPropertyKey(const QString &s) +PropertyKey IdentifierTable::asPropertyKey(const QString &s, + IdentifierTable::KeyConversionBehavior conversionBehvior) { uint subtype; - const uint hash = String::createHashValue(s.constData(), s.length(), &subtype); - if (subtype == Heap::String::StringType_ArrayIndex) - return PropertyKey::fromArrayIndex(hash); + uint hash = String::createHashValue(s.constData(), s.size(), &subtype); + if (subtype == Heap::String::StringType_ArrayIndex) { + if (Q_UNLIKELY(conversionBehvior == ForceConversionToId)) + hash = String::createHashValueDisallowingArrayIndex(s.constData(), s.size(), &subtype); + else + return PropertyKey::fromArrayIndex(hash); + } return resolveStringEntry(s, hash, subtype)->identifier; } diff --git a/src/qml/jsruntime/qv4identifiertable_p.h b/src/qml/jsruntime/qv4identifiertable_p.h index b2a9bc11951..c608e5d89e0 100644 --- a/src/qml/jsruntime/qv4identifiertable_p.h +++ b/src/qml/jsruntime/qv4identifiertable_p.h @@ -91,7 +91,8 @@ struct Q_QML_PRIVATE_EXPORT IdentifierTable return asPropertyKey(str->d()); } - PropertyKey asPropertyKey(const QString &s); + enum KeyConversionBehavior { Default, ForceConversionToId }; + PropertyKey asPropertyKey(const QString &s, KeyConversionBehavior conversionBehavior = Default); PropertyKey asPropertyKey(const char *s, int len); PropertyKey asPropertyKeyImpl(const Heap::String *str); diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index 4287563c94d..fdaa8cbaa49 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -178,7 +178,7 @@ void SharedInternalClassDataPrivate::setSize(uint s) data->values.size = s; } -PropertyKey SharedInternalClassDataPrivate::at(uint i) +PropertyKey SharedInternalClassDataPrivate::at(uint i) const { Q_ASSERT(data && i < size()); return PropertyKey::fromId(data->values.values[i].rawValue()); @@ -265,6 +265,13 @@ namespace Heap { void InternalClass::init(ExecutionEngine *engine) { +// InternalClass is automatically zeroed during allocation: +// prototype = nullptr; +// parent = nullptr; +// size = 0; +// numRedundantTransitions = 0; +// flags = 0; + Base::init(); new (&propertyTable) PropertyHash(); new (&nameMap) SharedInternalClassData(engine); @@ -273,13 +280,6 @@ void InternalClass::init(ExecutionEngine *engine) this->engine = engine; vtable = QV4::InternalClass::staticVTable(); -// prototype = nullptr; -// parent = nullptr; -// size = 0; - extensible = true; - isFrozen = false; - isSealed = false; - isUsedAsProto = false; protoId = engine->newProtoId(); // Also internal classes need an internal class pointer. Simply make it point to itself @@ -300,10 +300,8 @@ void InternalClass::init(Heap::InternalClass *other) prototype = other->prototype; parent = other; size = other->size; - extensible = other->extensible; - isSealed = other->isSealed; - isFrozen = other->isFrozen; - isUsedAsProto = other->isUsedAsProto; + numRedundantTransitions = other->numRedundantTransitions; + flags = other->flags; protoId = engine->newProtoId(); internalClass.set(engine, other->internalClass); @@ -331,9 +329,15 @@ void InternalClass::destroy() Base::destroy(); } -QString InternalClass::keyAt(uint index) const +ReturnedValue InternalClass::keyAt(uint index) const { - return nameMap.at(index).toQString(); + PropertyKey key = nameMap.at(index); + if (!key.isValid()) + return Encode::undefined(); + if (key.isArrayIndex()) + return Encode(key.asArrayIndex()); + Q_ASSERT(key.isStringOrSymbol()); + return key.asStringOrSymbol()->asReturnedValue(); } void InternalClass::changeMember(QV4::Object *object, PropertyKey id, PropertyAttributes data, InternalClassEntry *entry) @@ -365,7 +369,99 @@ static void addDummyEntry(InternalClass *newClass, PropertyHash::Entry e) ++newClass->size; } -Heap::InternalClass *InternalClass::changeMember(PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry) +static PropertyAttributes attributesFromFlags(int flags) +{ + PropertyAttributes attributes; + attributes.m_all = uchar(flags); + return attributes; +} + +static Heap::InternalClass *cleanInternalClass(Heap::InternalClass *orig) +{ + if (++orig->numRedundantTransitions < Heap::InternalClass::MaxRedundantTransitions) + return orig; + + // We will generally add quite a few transitions here. We have 255 redundant ones. + // We can expect at least as many significant ones in addition. + std::vector transitions; + + Scope scope(orig->engine); + Scoped child(scope, orig); + + { + quint8 remainingRedundantTransitions = orig->numRedundantTransitions; + QSet properties; + int structureChanges = 0; + + Scoped parent(scope, orig->parent); + while (parent && remainingRedundantTransitions > 0) { + Q_ASSERT(child->d() != scope.engine->classes[ExecutionEngine::Class_Empty]); + const auto it = std::find_if( + parent->d()->transitions.begin(), parent->d()->transitions.end(), + [&child](const InternalClassTransition &t) { + return child->d() == t.lookup; + }); + Q_ASSERT(it != parent->d()->transitions.end()); + + if (it->flags & InternalClassTransition::StructureChange) { + // A structural change. Each kind of structural change has to be recorded only once. + if ((structureChanges & it->flags) != it->flags) { + transitions.push_back(*it); + structureChanges |= it->flags; + } else { + --remainingRedundantTransitions; + } + } else if (!properties.contains(it->id)) { + // We only need the final state of the property. + properties.insert(it->id); + + // Property removal creates _two_ redundant transitions. + // We don't have to replay either, but numRedundantTransitions only records one. + if (it->flags != 0) + transitions.push_back(*it); + } else { + --remainingRedundantTransitions; + } + + child = parent->d(); + parent = child->d()->parent; + Q_ASSERT(child->d() != parent->d()); + } + } + + for (auto it = transitions.rbegin(); it != transitions.rend(); ++it) { + switch (it->flags) { + case InternalClassTransition::NotExtensible: + child = child->d()->nonExtensible(); + continue; + case InternalClassTransition::VTableChange: + child = child->d()->changeVTable(it->vtable); + continue; + case InternalClassTransition::PrototypeChange: + child = child->d()->changePrototype(it->prototype); + continue; + case InternalClassTransition::ProtoClass: + child = child->d()->asProtoClass(); + continue; + case InternalClassTransition::Sealed: + child = child->d()->sealed(); + continue; + case InternalClassTransition::Frozen: + child = child->d()->frozen(); + continue; + default: + Q_ASSERT(it->flags != 0); + Q_ASSERT(it->flags < InternalClassTransition::StructureChange); + child = child->addMember(it->id, attributesFromFlags(it->flags)); + continue; + } + } + + return child->d(); +} + +Heap::InternalClass *InternalClass::changeMember( + PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry) { if (!data.isEmpty()) data.resolve(); @@ -381,7 +477,7 @@ Heap::InternalClass *InternalClass::changeMember(PropertyKey identifier, Propert } if (data == propertyData.at(idx)) - return static_cast(this); + return this; Transition temp = { { identifier }, nullptr, int(data.all()) }; Transition &t = lookupOrInsertTransition(temp); @@ -394,7 +490,8 @@ Heap::InternalClass *InternalClass::changeMember(PropertyKey identifier, Propert Q_ASSERT(!propertyData.at(idx).isAccessor()); // add a dummy entry for the accessor - entry->setterIndex = newClass->size; + if (entry) + entry->setterIndex = newClass->size; e->setterIndex = newClass->size; addDummyEntry(newClass, *e); } @@ -403,7 +500,8 @@ Heap::InternalClass *InternalClass::changeMember(PropertyKey identifier, Propert t.lookup = newClass; Q_ASSERT(t.lookup); - return newClass; + + return cleanInternalClass(newClass); } Heap::InternalClass *InternalClass::changePrototypeImpl(Heap::Object *proto) @@ -413,7 +511,7 @@ Heap::InternalClass *InternalClass::changePrototypeImpl(Heap::Object *proto) if (proto) proto->setUsedAsProto(); Q_ASSERT(prototype != proto); - Q_ASSERT(!proto || proto->internalClass->isUsedAsProto); + Q_ASSERT(!proto || proto->internalClass->isUsedAsProto()); Transition temp = { { PropertyKey::invalid() }, nullptr, Transition::PrototypeChange }; temp.prototype = proto; @@ -427,8 +525,7 @@ Heap::InternalClass *InternalClass::changePrototypeImpl(Heap::Object *proto) newClass->prototype = proto; t.lookup = newClass; - - return newClass; + return prototype ? cleanInternalClass(newClass) : newClass; } Heap::InternalClass *InternalClass::changeVTableImpl(const VTable *vt) @@ -449,12 +546,14 @@ Heap::InternalClass *InternalClass::changeVTableImpl(const VTable *vt) t.lookup = newClass; Q_ASSERT(t.lookup); Q_ASSERT(newClass->vtable); - return newClass; + return vtable == QV4::InternalClass::staticVTable() + ? newClass + : cleanInternalClass(newClass); } Heap::InternalClass *InternalClass::nonExtensible() { - if (!extensible) + if (!isExtensible()) return this; Transition temp = { { PropertyKey::invalid() }, nullptr, Transition::NotExtensible}; @@ -463,7 +562,7 @@ Heap::InternalClass *InternalClass::nonExtensible() return t.lookup; Heap::InternalClass *newClass = engine->newClass(this); - newClass->extensible = false; + newClass->flags |= NotExtensible; t.lookup = newClass; Q_ASSERT(t.lookup); @@ -500,7 +599,7 @@ Heap::InternalClass *InternalClass::addMember(PropertyKey identifier, PropertyAt Heap::InternalClass *InternalClass::addMemberImpl(PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry) { - Transition temp = { { identifier }, nullptr, (int)data.flags() }; + Transition temp = { { identifier }, nullptr, int(data.all()) }; Transition &t = lookupOrInsertTransition(temp); if (entry) { @@ -553,21 +652,23 @@ void InternalClass::removeMember(QV4::Object *object, PropertyKey identifier) changeMember(object, identifier, Attr_Invalid); #ifndef QT_NO_DEBUG - // we didn't remove the data slot, just made it inaccessible - Q_ASSERT(object->internalClass()->size == oldClass->size); + // We didn't remove the data slot, just made it inaccessible. + // ... unless we've rebuilt the whole class. Then all the deleted properties are gone. + Q_ASSERT(object->internalClass()->numRedundantTransitions == 0 + || object->internalClass()->size == oldClass->size); #endif } Heap::InternalClass *InternalClass::sealed() { - if (isSealed) + if (isSealed()) return this; Transition temp = { { PropertyKey::invalid() }, nullptr, InternalClassTransition::Sealed }; Transition &t = lookupOrInsertTransition(temp); if (t.lookup) { - Q_ASSERT(t.lookup && t.lookup->isSealed); + Q_ASSERT(t.lookup && t.lookup->isSealed()); return t.lookup; } @@ -575,7 +676,7 @@ Heap::InternalClass *InternalClass::sealed() Scoped ic(scope, engine->newClass(this)); Heap::InternalClass *s = ic->d(); - if (!isFrozen) { // freezing also makes all properties non-configurable + if (!isFrozen()) { // freezing also makes all properties non-configurable for (uint i = 0; i < size; ++i) { PropertyAttributes attrs = propertyData.at(i); if (attrs.isEmpty()) @@ -584,7 +685,7 @@ Heap::InternalClass *InternalClass::sealed() s->propertyData.set(i, attrs); } } - s->isSealed = true; + s->flags |= Sealed; t.lookup = s; return s; @@ -592,14 +693,14 @@ Heap::InternalClass *InternalClass::sealed() Heap::InternalClass *InternalClass::frozen() { - if (isFrozen) + if (isFrozen()) return this; Transition temp = { { PropertyKey::invalid() }, nullptr, InternalClassTransition::Frozen }; Transition &t = lookupOrInsertTransition(temp); if (t.lookup) { - Q_ASSERT(t.lookup && t.lookup->isFrozen); + Q_ASSERT(t.lookup && t.lookup->isFrozen()); return t.lookup; } @@ -616,7 +717,7 @@ Heap::InternalClass *InternalClass::frozen() attrs.setConfigurable(false); f->propertyData.set(i, attrs); } - f->isFrozen = true; + f->flags |= Frozen; t.lookup = f; return f; @@ -640,7 +741,7 @@ InternalClass *InternalClass::cryopreserved() bool InternalClass::isImplicitlyFrozen() const { - if (isFrozen) + if (isFrozen()) return true; for (uint i = 0; i < size; ++i) { @@ -656,7 +757,7 @@ bool InternalClass::isImplicitlyFrozen() const Heap::InternalClass *InternalClass::asProtoClass() { - if (isUsedAsProto) + if (isUsedAsProto()) return this; Transition temp = { { PropertyKey::invalid() }, nullptr, Transition::ProtoClass }; @@ -665,7 +766,7 @@ Heap::InternalClass *InternalClass::asProtoClass() return t.lookup; Heap::InternalClass *newClass = engine->newClass(this); - newClass->isUsedAsProto = true; + newClass->flags |= UsedAsProto; t.lookup = newClass; Q_ASSERT(t.lookup); @@ -685,7 +786,7 @@ static void updateProtoUsage(Heap::Object *o, Heap::InternalClass *ic) void InternalClass::updateProtoUsage(Heap::Object *o) { - Q_ASSERT(isUsedAsProto); + Q_ASSERT(isUsedAsProto()); Heap::InternalClass *ic = engine->internalClasses(EngineBase::Class_Empty); Q_ASSERT(!ic->prototype); @@ -698,6 +799,9 @@ void InternalClass::markObjects(Heap::Base *b, MarkStack *stack) if (ic->prototype) ic->prototype->mark(stack); + if (ic->parent) + ic->parent->mark(stack); + ic->nameMap.mark(stack); } diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h index c18133f4cd4..a80ec2e9579 100644 --- a/src/qml/jsruntime/qv4internalclass_p.h +++ b/src/qml/jsruntime/qv4internalclass_p.h @@ -173,7 +173,7 @@ struct SharedInternalClassDataPrivate { uint size() const { return m_size; } void setSize(uint s) { m_size = s; } - PropertyAttributes at(uint i) { Q_ASSERT(data && i < m_alloc); return data[i]; } + PropertyAttributes at(uint i) const { Q_ASSERT(data && i < m_alloc); return data[i]; } void set(uint i, PropertyAttributes t) { Q_ASSERT(data && i < m_alloc); data[i] = t; } void mark(MarkStack *) {} @@ -198,7 +198,7 @@ struct SharedInternalClassDataPrivate { uint size() const; void setSize(uint s); - PropertyKey at(uint i); + PropertyKey at(uint i) const; void set(uint i, PropertyKey t); void mark(MarkStack *s); @@ -289,24 +289,33 @@ struct InternalClassTransition int flags; enum { // range 0-0xff is reserved for attribute changes - NotExtensible = 0x100, - VTableChange = 0x200, - PrototypeChange = 0x201, - ProtoClass = 0x202, - Sealed = 0x203, - Frozen = 0x204 + StructureChange = 0x100, + NotExtensible = StructureChange | (1 << 0), + VTableChange = StructureChange | (1 << 1), + PrototypeChange = StructureChange | (1 << 2), + ProtoClass = StructureChange | (1 << 3), + Sealed = StructureChange | (1 << 4), + Frozen = StructureChange | (1 << 5), }; bool operator==(const InternalClassTransition &other) const { return id == other.id && flags == other.flags; } bool operator<(const InternalClassTransition &other) const - { return id < other.id || (id == other.id && flags < other.flags); } + { return flags < other.flags || (flags == other.flags && id < other.id); } }; namespace Heap { struct InternalClass : Base { + enum Flag { + NotExtensible = 1 << 0, + Sealed = 1 << 1, + Frozen = 1 << 2, + UsedAsProto = 1 << 3, + }; + enum { MaxRedundantTransitions = 255 }; + ExecutionEngine *engine; const VTable *vtable; quintptr protoId; // unique across the engine, gets changed whenever the proto chain changes @@ -322,16 +331,19 @@ struct InternalClass : Base { InternalClassTransition &lookupOrInsertTransition(const InternalClassTransition &t); uint size; - bool extensible; - bool isSealed; - bool isFrozen; - bool isUsedAsProto; + quint8 numRedundantTransitions; + quint8 flags; + + bool isExtensible() const { return !(flags & NotExtensible); } + bool isSealed() const { return flags & Sealed; } + bool isFrozen() const { return flags & Frozen; } + bool isUsedAsProto() const { return flags & UsedAsProto; } void init(ExecutionEngine *engine); void init(InternalClass *other); void destroy(); - Q_QML_PRIVATE_EXPORT QString keyAt(uint index) const; + Q_QML_PRIVATE_EXPORT ReturnedValue keyAt(uint index) const; Q_REQUIRED_RESULT InternalClass *nonExtensible(); static void addMember(QV4::Object *object, PropertyKey id, PropertyAttributes data, InternalClassEntry *entry); diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h index c6d320ac20e..70ddaf59c5e 100644 --- a/src/qml/jsruntime/qv4jscall_p.h +++ b/src/qml/jsruntime/qv4jscall_p.h @@ -146,10 +146,12 @@ struct ScopedStackFrame { return; frame.jsFrame = reinterpret_cast(scope.alloc(sizeof(CallData)/sizeof(Value))); frame.jsFrame->context = context; - if (auto *parent = frame.parentFrame()) + if (auto *parent = frame.parentFrame()) { frame.v4Function = parent->v4Function; - else + frame.instructionPointer = parent->instructionPointer; + } else { frame.v4Function = nullptr; + } scope.engine->currentStackFrame = &frame; } ~ScopedStackFrame() { diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index a3ffdb54311..ad9760bfd66 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -646,6 +646,28 @@ struct Stringify QString makeMember(const QString &key, const Value &v); }; +class [[nodiscard]] CallDepthAndCycleChecker +{ + Q_DISABLE_COPY_MOVE(CallDepthAndCycleChecker); + +public: + CallDepthAndCycleChecker(Stringify *stringify, Object *o) + : m_callDepthRecorder(stringify->v4) + { + if (stringify->stackContains(o)) { + stringify->v4->throwTypeError( + QStringLiteral("Cannot convert circular structure to JSON")); + } + + stringify->v4->checkStackLimits(); + } + + bool foundProblem() const { return m_callDepthRecorder.ee->hasException; } + +private: + ExecutionEngineCallDepthRecorder<1> m_callDepthRecorder; +}; + static QString quote(const QString &str) { QString product; @@ -776,10 +798,9 @@ QString Stringify::makeMember(const QString &key, const Value &v) QString Stringify::JO(Object *o) { - if (stackContains(o)) { - v4->throwTypeError(); + CallDepthAndCycleChecker check(this, o); + if (check.foundProblem()) return QString(); - } Scope scope(v4); @@ -836,10 +857,9 @@ QString Stringify::JO(Object *o) QString Stringify::JA(Object *a) { - if (stackContains(a)) { - v4->throwTypeError(); + CallDepthAndCycleChecker check(this, a); + if (check.foundProblem()) return QString(); - } Scope scope(a->engine()); diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index d3ea50867a1..61c0d3daa70 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -41,6 +41,7 @@ #include "qv4jscall_p.h" #include "qv4string_p.h" #include +#include QT_BEGIN_NAMESPACE @@ -144,47 +145,76 @@ ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Va return l->resolvePrimitiveGetter(engine, object); } +static inline void setupObjectLookupTwoClasses(Lookup *l, const Lookup &first, const Lookup &second) +{ + Heap::InternalClass *ic1 = first.objectLookup.ic; + const uint offset1 = first.objectLookup.offset; + Heap::InternalClass *ic2 = second.objectLookup.ic; + const uint offset2 = second.objectLookup.offset; + + l->objectLookupTwoClasses.ic = ic1; + l->objectLookupTwoClasses.ic2 = ic2; + l->objectLookupTwoClasses.offset = offset1; + l->objectLookupTwoClasses.offset2 = offset2; +} + +static inline void setupProtoLookupTwoClasses(Lookup *l, const Lookup &first, const Lookup &second) +{ + const quintptr protoId1 = first.protoLookup.protoId; + const Value *data1 = first.protoLookup.data; + const quintptr protoId2 = second.protoLookup.protoId; + const Value *data2 = second.protoLookup.data; + + l->protoLookupTwoClasses.protoId = protoId1; + l->protoLookupTwoClasses.protoId2 = protoId2; + l->protoLookupTwoClasses.data = data1; + l->protoLookupTwoClasses.data2 = data2; +} + ReturnedValue Lookup::getterTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object) { if (const Object *o = object.as()) { - Lookup first = *l; - Lookup second = *l; - - ReturnedValue result = second.resolveGetter(engine, o); - if (first.getter == getter0Inline && (second.getter == getter0Inline || second.getter == getter0MemberData)) { - l->objectLookupTwoClasses.ic = first.objectLookup.ic; - l->objectLookupTwoClasses.ic2 = second.objectLookup.ic; - l->objectLookupTwoClasses.offset = first.objectLookup.offset; - l->objectLookupTwoClasses.offset2 = second.objectLookup.offset; - l->getter = second.getter == getter0Inline ? getter0Inlinegetter0Inline : getter0Inlinegetter0MemberData; + // Do the resolution on a second lookup, then merge. + Lookup second; + memset(&second, 0, sizeof(Lookup)); + second.nameIndex = l->nameIndex; + second.getter = getterGeneric; + const ReturnedValue result = second.resolveGetter(engine, o); + + if (l->getter == getter0Inline + && (second.getter == getter0Inline || second.getter == getter0MemberData)) { + setupObjectLookupTwoClasses(l, *l, second); + l->getter = (second.getter == getter0Inline) + ? getter0Inlinegetter0Inline + : getter0Inlinegetter0MemberData; return result; } - if (first.getter == getter0MemberData && (second.getter == getter0Inline || second.getter == getter0MemberData)) { - l->objectLookupTwoClasses.ic = second.objectLookup.ic; - l->objectLookupTwoClasses.ic2 = first.objectLookup.ic; - l->objectLookupTwoClasses.offset = second.objectLookup.offset; - l->objectLookupTwoClasses.offset2 = first.objectLookup.offset; - l->getter = second.getter == getter0Inline ? getter0Inlinegetter0MemberData : getter0MemberDatagetter0MemberData; + + if (l->getter == getter0MemberData + && (second.getter == getter0Inline || second.getter == getter0MemberData)) { + setupObjectLookupTwoClasses(l, second, *l); + l->getter = (second.getter == getter0Inline) + ? getter0Inlinegetter0MemberData + : getter0MemberDatagetter0MemberData; return result; } - if (first.getter == getterProto && second.getter == getterProto) { - l->protoLookupTwoClasses.protoId = first.protoLookup.protoId; - l->protoLookupTwoClasses.protoId2 = second.protoLookup.protoId; - l->protoLookupTwoClasses.data = first.protoLookup.data; - l->protoLookupTwoClasses.data2 = second.protoLookup.data; + + + if (l->getter == getterProto && second.getter == getterProto) { + setupProtoLookupTwoClasses(l, *l, second); l->getter = getterProtoTwoClasses; return result; } - if (first.getter == getterProtoAccessor && second.getter == getterProtoAccessor) { - l->protoLookupTwoClasses.protoId = first.protoLookup.protoId; - l->protoLookupTwoClasses.protoId2 = second.protoLookup.protoId; - l->protoLookupTwoClasses.data = first.protoLookup.data; - l->protoLookupTwoClasses.data2 = second.protoLookup.data; + + if (l->getter == getterProtoAccessor && second.getter == getterProtoAccessor) { + setupProtoLookupTwoClasses(l, *l, second); l->getter = getterProtoAccessorTwoClasses; return result; } + // If any of the above options were true, the propertyCache was inactive. + second.releasePropertyCache(); } l->getter = getterFallback; @@ -371,7 +401,19 @@ ReturnedValue Lookup::getterIndexed(Lookup *l, ExecutionEngine *engine, const Va } l->getter = getterFallback; return getterFallback(l, engine, object); +} +ReturnedValue Lookup::getterQObject(Lookup *lookup, ExecutionEngine *engine, const Value &object) +{ + const auto revertLookup = [lookup, engine, &object]() { + lookup->qobjectLookup.propertyCache->release(); + lookup->qobjectLookup.propertyCache = nullptr; + lookup->getter = Lookup::getterGeneric; + return Lookup::getterGeneric(lookup, engine, object); + }; + + return QObjectWrapper::lookupGetterImpl( + lookup, engine, object, /*useOriginalProperty*/ false, revertLookup); } ReturnedValue Lookup::primitiveGetterProto(Lookup *l, ExecutionEngine *engine, const Value &object) @@ -463,23 +505,30 @@ bool Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, co bool Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value) { - Lookup first = *l; - Lookup second = *l; + // A precondition of this method is that l->objectLookup is the active variant of the union. + Q_ASSERT(l->setter == setter0MemberData || l->setter == setter0Inline); if (object.isObject()) { + + // As l->objectLookup is active, we can stash some members here, before resolving. + Heap::InternalClass *ic = l->objectLookup.ic; + const uint index = l->objectLookup.index; + if (!l->resolveSetter(engine, static_cast(&object), value)) { l->setter = setterFallback; return false; } if (l->setter == Lookup::setter0MemberData || l->setter == Lookup::setter0Inline) { - l->objectLookupTwoClasses.ic = first.objectLookup.ic; - l->objectLookupTwoClasses.ic2 = second.objectLookup.ic; - l->objectLookupTwoClasses.offset = first.objectLookup.index; - l->objectLookupTwoClasses.offset2 = second.objectLookup.index; + l->objectLookupTwoClasses.ic = ic; + l->objectLookupTwoClasses.ic2 = ic; + l->objectLookupTwoClasses.offset = index; + l->objectLookupTwoClasses.offset2 = index; l->setter = setter0setter0; return true; } + + l->releasePropertyCache(); } l->setter = setterFallback; @@ -550,6 +599,13 @@ bool Lookup::setterInsert(Lookup *l, ExecutionEngine *engine, Value &object, con return setterFallback(l, engine, object, value); } +bool Lookup::setterQObject(Lookup *l, ExecutionEngine *engine, Value &object, const Value &v) +{ + // This setter just marks the presence of a qobjectlookup. It only does anything with it when + // running AOT-compiled code, though. + return QV4::Lookup::setterFallback(l, engine, object, v); +} + bool Lookup::arrayLengthSetter(Lookup *, ExecutionEngine *engine, Value &object, const Value &value) { Q_ASSERT(object.isObject() && static_cast(object).isArrayObject()); diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h index aab6b665978..382f6c684a6 100644 --- a/src/qml/jsruntime/qv4lookup_p.h +++ b/src/qml/jsruntime/qv4lookup_p.h @@ -56,11 +56,16 @@ #include "qv4context_p.h" #include "qv4object_p.h" #include "qv4internalclass_p.h" +#include "qv4qmlcontext_p.h" +#include QT_BEGIN_NAMESPACE namespace QV4 { +// Note: We cannot hide the copy ctor and assignment operator of this class because it needs to +// be trivially copyable. But you should never ever copy it. There are refcounted members +// in there. struct Q_QML_PRIVATE_EXPORT Lookup { union { ReturnedValue (*getter)(Lookup *l, ExecutionEngine *engine, const Value &object); @@ -125,6 +130,12 @@ struct Q_QML_PRIVATE_EXPORT Lookup { QQmlPropertyCache *propertyCache; QQmlPropertyData *propertyData; } qobjectLookup; + struct { + quintptr isConstant; // This is a bool, encoded as 0 or 1. Both values are ignored by gc + quintptr metaObject; // a (const QMetaObject* & 1) or nullptr + int coreIndex; + int notifyIndex; + } qobjectFallbackLookup; struct { Heap::InternalClass *ic; quintptr metaObject; // a (const QMetaObject* & 1) or nullptr @@ -191,6 +202,7 @@ struct Q_QML_PRIVATE_EXPORT Lookup { static ReturnedValue getterProtoAccessor(Lookup *l, ExecutionEngine *engine, const Value &object); static ReturnedValue getterProtoAccessorTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object); static ReturnedValue getterIndexed(Lookup *l, ExecutionEngine *engine, const Value &object); + static ReturnedValue getterQObject(Lookup *l, ExecutionEngine *engine, const Value &object); static ReturnedValue primitiveGetterProto(Lookup *l, ExecutionEngine *engine, const Value &object); static ReturnedValue primitiveGetterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object); @@ -208,6 +220,7 @@ struct Q_QML_PRIVATE_EXPORT Lookup { static bool setter0Inline(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); static bool setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); static bool setterInsert(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); + static bool setterQObject(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); static bool arrayLengthSetter(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value); void markObjects(MarkStack *stack) { @@ -217,8 +230,16 @@ struct Q_QML_PRIVATE_EXPORT Lookup { markDef.h2->mark(stack); } - void clear() { - memset(&markDef, 0, sizeof(markDef)); + void releasePropertyCache() + { + if (getter == getterQObject + || getter == QQmlTypeWrapper::lookupSingletonProperty + || setter == setterQObject + || qmlContextPropertyGetter == QQmlContextWrapper::lookupScopeObjectProperty + || qmlContextPropertyGetter == QQmlContextWrapper::lookupContextObjectProperty) { + if (QQmlPropertyCache *pc = qobjectLookup.propertyCache) + pc->release(); + } } }; @@ -227,6 +248,33 @@ Q_STATIC_ASSERT(std::is_standard_layout::value); // across 32-bit and 64-bit (matters when cross-compiling). Q_STATIC_ASSERT(offsetof(Lookup, getter) == 0); +inline void setupQObjectLookup( + Lookup *lookup, const QQmlData *ddata, QQmlPropertyData *propertyData) +{ + lookup->releasePropertyCache(); + Q_ASSERT(ddata->propertyCache != nullptr); + lookup->qobjectLookup.propertyCache = ddata->propertyCache; + lookup->qobjectLookup.propertyCache->addref(); + lookup->qobjectLookup.propertyData = propertyData; +} + +inline void setupQObjectLookup( + Lookup *lookup, const QQmlData *ddata, QQmlPropertyData *propertyData, + const Object *self) +{ + lookup->qobjectLookup.ic = self->internalClass(); + setupQObjectLookup(lookup, ddata, propertyData); +} + + +inline void setupQObjectLookup( + Lookup *lookup, const QQmlData *ddata, QQmlPropertyData *propertyData, + const Object *self, const Object *qmlType) +{ + lookup->qobjectLookup.qmlTypeIc = qmlType->internalClass(); + setupQObjectLookup(lookup, ddata, propertyData, self); +} + } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4module.cpp b/src/qml/jsruntime/qv4module.cpp index 26bef9cd370..548dd7be254 100644 --- a/src/qml/jsruntime/qv4module.cpp +++ b/src/qml/jsruntime/qv4module.cpp @@ -258,9 +258,12 @@ OwnPropertyKeyIterator *Module::virtualOwnPropertyKeys(const Object *o, Value *t if (module->d()->unit->isESModule()) { names = module->d()->unit->exportedNames(); } else { - Heap::InternalClass *scopeClass = module->d()->scope->internalClass; - for (uint i = 0; i < scopeClass->size; ++i) - names << scopeClass->keyAt(i); + QV4::Scope scope(module->engine()); + QV4::Scoped scopeClass(scope, module->d()->scope->internalClass); + for (uint i = 0, end = scopeClass->d()->size; i < end; ++i) { + QV4::ScopedValue key(scope, scopeClass->d()->keyAt(i)); + names << key->toQString(); + } } return new ModuleNamespaceIterator(names); diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 2ad1ecb6e3c..564cd47203a 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -61,17 +61,52 @@ DEFINE_OBJECT_VTABLE(Object); void Object::setInternalClass(Heap::InternalClass *ic) { - d()->internalClass.set(engine(), ic); - if (ic->isUsedAsProto) - ic->updateProtoUsage(d()); Q_ASSERT(ic && ic->vtable); - uint nInline = d()->vtable()->nInlineProperties; - if (ic->size <= nInline) - return; - bool hasMD = d()->memberData != nullptr; - uint requiredSize = ic->size - nInline; - if (!(hasMD && requiredSize) || (hasMD && d()->memberData->values.size < requiredSize)) - d()->memberData.set(ic->engine, MemberData::allocate(ic->engine, requiredSize, d()->memberData)); + Heap::Object *p = d(); + + if (ic->numRedundantTransitions < p->internalClass.get()->numRedundantTransitions) { + // IC was rebuilt. The indices are different now. We need to move everything. + + Scope scope(engine()); + + // We allocate before setting the new IC. Protect it from GC. + Scoped newIC(scope, ic); + + // Pick the members of the old IC that are still valid in the new IC. + // Order them by index in memberData (or inline data). + Scoped newMembers(scope, MemberData::allocate(scope.engine, ic->size)); + for (uint i = 0; i < ic->size; ++i) + newMembers->set(scope.engine, i, get(ic->nameMap.at(i))); + + p->internalClass.set(scope.engine, ic); + const uint nInline = p->vtable()->nInlineProperties; + + if (ic->size > nInline) + p->memberData.set(scope.engine, MemberData::allocate(ic->engine, ic->size - nInline)); + else + p->memberData.set(scope.engine, nullptr); + + const auto &memberValues = newMembers->d()->values; + for (uint i = 0; i < ic->size; ++i) + setProperty(i, memberValues[i]); + } else { + // The old indices are still the same. No need to move any values. + // We may need to re-allocate, though. + + p->internalClass.set(ic->engine, ic); + const uint nInline = p->vtable()->nInlineProperties; + if (ic->size > nInline) { + const uint requiredSize = ic->size - nInline; + if ((p->memberData ? p->memberData->values.size : 0) < requiredSize) { + p->memberData.set(ic->engine, MemberData::allocate( + ic->engine, requiredSize, p->memberData)); + } + } + } + + if (ic->isUsedAsProto()) + ic->updateProtoUsage(p); + } void Object::getProperty(const InternalClassEntry &entry, Property *p) const @@ -958,7 +993,7 @@ bool Object::virtualDefineOwnProperty(Managed *m, PropertyKey id, const Property bool Object::virtualIsExtensible(const Managed *m) { - return m->d()->internalClass->extensible; + return m->d()->internalClass->isExtensible(); } bool Object::virtualPreventExtensions(Managed *m) @@ -982,7 +1017,7 @@ bool Object::virtualSetPrototypeOf(Managed *m, const Object *proto) Heap::Object *protod = proto ? proto->d() : nullptr; if (current == protod) return true; - if (!o->internalClass()->extensible) + if (!o->internalClass()->isExtensible()) return false; Heap::Object *p = protod; while (p) { @@ -1013,6 +1048,8 @@ bool Object::setArrayLength(uint newLen) } else { if (newLen >= 0x100000) initSparseArray(); + else + ArrayData::realloc(this, arrayType(), newLen, false); } setArrayLengthUnchecked(newLen); return ok; diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp index 26e1074fe39..1f518966d67 100644 --- a/src/qml/jsruntime/qv4profiling.cpp +++ b/src/qml/jsruntime/qv4profiling.cpp @@ -50,8 +50,8 @@ FunctionLocation FunctionCall::resolveLocation() const { return FunctionLocation(m_function->name()->toQString(), m_function->executableCompilationUnit()->fileName(), - m_function->compiledFunction->location.line, - m_function->compiledFunction->location.column); + m_function->compiledFunction->location.line(), + m_function->compiledFunction->location.column()); } FunctionCallProperties FunctionCall::properties() const diff --git a/src/qml/jsruntime/qv4promiseobject.cpp b/src/qml/jsruntime/qv4promiseobject.cpp index 83bfba9b11f..e155f2c3baf 100644 --- a/src/qml/jsruntime/qv4promiseobject.cpp +++ b/src/qml/jsruntime/qv4promiseobject.cpp @@ -116,6 +116,8 @@ struct ResolveThenableEvent : public QEvent } // namespace QV4 QT_END_NAMESPACE +#include "moc_qv4promiseobject_p.cpp" + ReactionHandler::ReactionHandler(QObject *parent) : QObject(parent) {} diff --git a/src/qml/jsruntime/qv4propertykey_p.h b/src/qml/jsruntime/qv4propertykey_p.h index b5dca2d2ac3..bb93dc518dd 100644 --- a/src/qml/jsruntime/qv4propertykey_p.h +++ b/src/qml/jsruntime/qv4propertykey_p.h @@ -51,6 +51,7 @@ // #include +#include QT_BEGIN_NAMESPACE @@ -145,6 +146,7 @@ struct PropertyKey bool operator ==(const PropertyKey &other) const { return val == other.val; } bool operator !=(const PropertyKey &other) const { return val != other.val; } bool operator <(const PropertyKey &other) const { return val < other.val; } + friend size_t qHash(const PropertyKey &key, size_t seed = 0) { return qHash(key.val, seed); } }; } diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp index 65481e4539f..9f3c2af1742 100644 --- a/src/qml/jsruntime/qv4qmlcontext.cpp +++ b/src/qml/jsruntime/qv4qmlcontext.cpp @@ -215,7 +215,7 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r if (context->imports() && name->startsWithUpper()) { // Search for attached properties, enums and imported scripts - QQmlTypeNameCache::Result r = context->imports()->query(name, QQmlImport::AllowRecursion); + QQmlTypeNameCache::Result r = context->imports()->query(name); if (r.isValid()) { if (hasProperty) @@ -294,8 +294,12 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r bool hasProp = false; QQmlPropertyData *propertyData = nullptr; - QV4::ScopedValue result(scope, QV4::QObjectWrapper::getQmlProperty(v4, context, scopeObject, - name, QV4::QObjectWrapper::CheckRevision, &hasProp, &propertyData)); + + QV4::ScopedObject wrapper(scope, QV4::QObjectWrapper::wrap(v4, scopeObject)); + QV4::ScopedValue result(scope, QV4::QObjectWrapper::getQmlProperty( + v4, context, wrapper->d(), scopeObject, name, + QV4::QObjectWrapper::CheckRevision, &hasProp, + &propertyData)); if (hasProp) { if (hasProperty) *hasProperty = true; @@ -306,11 +310,7 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r QQmlData *ddata = QQmlData::get(scopeObject, false); if (ddata && ddata->propertyCache) { ScopedValue val(scope, base ? *base : Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, scopeObject))); - const QObjectWrapper *That = static_cast(val->objectValue()); - lookup->qobjectLookup.ic = That->internalClass(); - lookup->qobjectLookup.propertyCache = ddata->propertyCache; - lookup->qobjectLookup.propertyCache->addref(); - lookup->qobjectLookup.propertyData = propertyData; + QV4::setupQObjectLookup(lookup, ddata, propertyData, val->objectValue()); lookup->qmlContextPropertyGetter = QQmlContextWrapper::lookupScopeObjectProperty; } } @@ -325,9 +325,10 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r if (QObject *contextObject = context->contextObject()) { bool hasProp = false; QQmlPropertyData *propertyData = nullptr; - result = QV4::QObjectWrapper::getQmlProperty(v4, context, contextObject, - name, QV4::QObjectWrapper::CheckRevision, - &hasProp, &propertyData); + QV4::ScopedObject wrapper(scope, QV4::QObjectWrapper::wrap(v4, contextObject)); + result = QV4::QObjectWrapper::getQmlProperty( + v4, context, wrapper->d(), contextObject, name, + QV4::QObjectWrapper::CheckRevision, &hasProp, &propertyData); if (hasProp) { if (hasProperty) *hasProperty = true; @@ -337,14 +338,12 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r if (propertyData) { if (lookup) { QQmlData *ddata = QQmlData::get(contextObject, false); - if (ddata && ddata->propertyCache) { + if (ddata && ddata->propertyCache + && lookup->qmlContextPropertyGetter != contextGetterFunction) { ScopedValue val(scope, base ? *base : Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, contextObject))); - const QObjectWrapper *That = static_cast(val->objectValue()); - lookup->qobjectLookup.ic = That->internalClass(); - lookup->qobjectLookup.propertyCache = ddata->propertyCache; - lookup->qobjectLookup.propertyCache->addref(); - lookup->qobjectLookup.propertyData = propertyData; + QV4::setupQObjectLookup(lookup, ddata, propertyData, + val->objectValue()); lookup->qmlContextPropertyGetter = contextGetterFunction; } } else if (originalLookup) { @@ -643,6 +642,11 @@ ReturnedValue QQmlContextWrapper::lookupContextObjectProperty(Lookup *l, Executi return QObjectWrapper::lookupGetterImpl(l, engine, obj, /*useOriginalProperty*/ true, revertLookup); } +ReturnedValue QQmlContextWrapper::lookupScopeFallbackProperty(Lookup *l, ExecutionEngine *engine, Value *base) +{ + return resolveQmlContextPropertyLookupGetter(l, engine, base); +} + ReturnedValue QQmlContextWrapper::lookupInGlobalObject(Lookup *l, ExecutionEngine *engine, Value *base) { Q_UNUSED(base); @@ -683,8 +687,9 @@ ReturnedValue QQmlContextWrapper::lookupInParentContextHierarchy(Lookup *l, Exec // Search context object if (QObject *contextObject = context->contextObject()) { bool hasProp = false; + QV4::ScopedObject wrapper(scope, QV4::QObjectWrapper::wrap(engine, contextObject)); result = QV4::QObjectWrapper::getQmlProperty( - engine, context, contextObject, name, + engine, context, wrapper->d(), contextObject, name, QV4::QObjectWrapper::CheckRevision, &hasProp); if (hasProp) { if (base) diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h index 19324b8803e..253df6536d8 100644 --- a/src/qml/jsruntime/qv4qmlcontext_p.h +++ b/src/qml/jsruntime/qv4qmlcontext_p.h @@ -112,6 +112,7 @@ struct Q_QML_EXPORT QQmlContextWrapper : Object static ReturnedValue lookupIdObject(Lookup *l, ExecutionEngine *engine, Value *base); static ReturnedValue lookupIdObjectInParentContext(Lookup *l, ExecutionEngine *engine, Value *base); static ReturnedValue lookupScopeObjectProperty(Lookup *l, ExecutionEngine *engine, Value *base); + static ReturnedValue lookupScopeFallbackProperty(Lookup *l, ExecutionEngine *engine, Value *base); static ReturnedValue lookupContextObjectProperty(Lookup *l, ExecutionEngine *engine, Value *base); static ReturnedValue lookupInGlobalObject(Lookup *l, ExecutionEngine *engine, Value *base); static ReturnedValue lookupInParentContextHierarchy(Lookup *l, ExecutionEngine *engine, Value *base); diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 20ccb00093d..91bace3b017 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -248,9 +248,11 @@ QQmlPropertyData *QObjectWrapper::findProperty( return result; } -ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property) +ReturnedValue QObjectWrapper::getProperty( + ExecutionEngine *engine, Heap::Object *wrapper, QObject *object, + QQmlPropertyData *property) { - QQmlData::flushPendingBinding(object, QQmlPropertyIndex(property->coreIndex())); + QQmlData::flushPendingBinding(object, property->coreIndex()); if (property->isFunction() && !property->isVarProperty()) { if (property->isVMEFunction()) { @@ -262,20 +264,21 @@ ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *obje ScopedContext global(scope, engine->qmlContext()); if (!global) global = engine->rootContext(); - return QV4::QObjectMethod::create(global, object, property->coreIndex()); + return QV4::QObjectMethod::create(global, wrapper, property->coreIndex()); } else if (property->isSignalHandler()) { QmlSignalHandler::initProto(engine); return engine->memoryManager->allocate(object, property->coreIndex())->asReturnedValue(); } else { ExecutionContext *global = engine->rootContext(); - return QV4::QObjectMethod::create(global, object, property->coreIndex()); + return QV4::QObjectMethod::create(global, wrapper, property->coreIndex()); } } QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : nullptr; if (ep && ep->propertyCapture && !property->isConstant()) - ep->propertyCapture->captureProperty(object, property->coreIndex(), property->notifyIndex()); + if (!property->isBindable() || ep->propertyCapture->expression->mustCaptureBindableProperty()) + ep->propertyCapture->captureProperty(object, property->coreIndex(), property->notifyIndex()); if (property->isVarProperty()) { QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object); @@ -286,7 +289,8 @@ ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *obje } } -static OptionalReturnedValue getDestroyOrToStringMethod(ExecutionEngine *v4, String *name, QObject *qobj, bool *hasProperty = nullptr) +static OptionalReturnedValue getDestroyOrToStringMethod( + ExecutionEngine *v4, String *name, Heap::Object *qobj, bool *hasProperty = nullptr) { int index = 0; if (name->equals(v4->id_destroy())) @@ -344,7 +348,7 @@ ReturnedValue QObjectWrapper::getQmlProperty( ExecutionEngine *v4 = engine(); - if (auto methodValue = getDestroyOrToStringMethod(v4, name, d()->object(), hasProperty)) + if (auto methodValue = getDestroyOrToStringMethod(v4, name, d(), hasProperty)) return *methodValue; QQmlPropertyData local; @@ -372,13 +376,13 @@ ReturnedValue QObjectWrapper::getQmlProperty( if (hasProperty) *hasProperty = true; - return getProperty(v4, d()->object(), result); + return getProperty(v4, d(), d()->object(), result); } ReturnedValue QObjectWrapper::getQmlProperty( QV4::ExecutionEngine *engine, const QQmlRefPointer &qmlContext, - QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty, - QQmlPropertyData **property) + Heap::Object *wrapper, QObject *object, String *name, + QObjectWrapper::RevisionMode revisionMode, bool *hasProperty, QQmlPropertyData **property) { if (QQmlData::wasDeleted(object)) { if (hasProperty) @@ -386,7 +390,7 @@ ReturnedValue QObjectWrapper::getQmlProperty( return QV4::Encode::null(); } - if (auto methodValue = getDestroyOrToStringMethod(engine, name, object, hasProperty)) + if (auto methodValue = getDestroyOrToStringMethod(engine, name, wrapper, hasProperty)) return *methodValue; QQmlData *ddata = QQmlData::get(object, false); @@ -408,7 +412,7 @@ ReturnedValue QObjectWrapper::getQmlProperty( if (property && result != &local) *property = result; - return getProperty(engine, object, result); + return getProperty(engine, wrapper, object, result); } else { // Check if this object is already wrapped. if (!ddata || (ddata->jsWrapper.isUndefined() && @@ -428,13 +432,13 @@ ReturnedValue QObjectWrapper::getQmlProperty( Q_ASSERT(ddata); QV4::Scope scope(engine); - QV4::Scoped wrapper(scope, wrap(engine, object)); - if (!wrapper) { + QV4::Scoped rewrapped(scope, wrap(engine, object)); + if (!rewrapped) { if (hasProperty) *hasProperty = false; return QV4::Encode::null(); } - return wrapper->getQmlProperty(qmlContext, name, revisionMode, hasProperty); + return rewrapped->getQmlProperty(qmlContext, name, revisionMode, hasProperty); } @@ -776,7 +780,7 @@ bool QObjectWrapper::virtualPut(Managed *m, PropertyKey id, const Value &value, QObjectWrapper *that = static_cast(m); ScopedString name(scope, id.asStringOrSymbol()); - if (that->internalClass()->isFrozen) { + if (that->internalClass()->isFrozen()) { QString error = QLatin1String("Cannot assign to property \"") + name->toQString() + QLatin1String("\" of read-only object"); scope.engine->throwError(error); @@ -866,7 +870,7 @@ PropertyKey QObjectWrapperOwnPropertyKeyIterator::next(const QV4::Object *o, Pro if (pd) { QQmlPropertyData local; local.load(property); - pd->value = that->getProperty(thatEngine, thatObject, &local); + pd->value = that->getProperty(thatEngine, that->d(), thatObject, &local); } return propName->toPropertyKey(); } @@ -891,7 +895,7 @@ PropertyKey QObjectWrapperOwnPropertyKeyIterator::next(const QV4::Object *o, Pro if (pd) { QQmlPropertyData local; local.load(method); - pd->value = that->getProperty(thatEngine, thatObject, &local); + pd->value = that->getProperty(thatEngine, that->d(), thatObject, &local); } return methodName->toPropertyKey(); } @@ -924,14 +928,14 @@ ReturnedValue QObjectWrapper::virtualResolveLookupGetter(const Object *object, E if (QQmlData::wasDeleted(qobj)) return QV4::Encode::undefined(); - if (auto methodValue = getDestroyOrToStringMethod(engine, name, qobj)) + if (auto methodValue = getDestroyOrToStringMethod(engine, name, This->d())) return *methodValue; QQmlData *ddata = QQmlData::get(qobj, false); if (!ddata || !ddata->propertyCache) { QQmlPropertyData local; QQmlPropertyData *property = QQmlPropertyCache::property(engine->jsEngine(), qobj, name, qmlContext, &local); - return property ? getProperty(engine, qobj, property) : QV4::Encode::undefined(); + return property ? getProperty(engine, This->d(), qobj, property) : QV4::Encode::undefined(); } QQmlPropertyData *property = ddata->propertyCache->property(name.getPointer(), qobj, qmlContext); @@ -944,37 +948,17 @@ ReturnedValue QObjectWrapper::virtualResolveLookupGetter(const Object *object, E return QV4::Object::virtualResolveLookupGetter(object, engine, lookup); } - lookup->qobjectLookup.ic = This->internalClass(); - lookup->qobjectLookup.propertyCache = ddata->propertyCache; - lookup->qobjectLookup.propertyCache->addref(); - lookup->qobjectLookup.propertyData = property; - lookup->getter = QV4::QObjectWrapper::lookupGetter; + QV4::setupQObjectLookup(lookup, ddata, property, This); + lookup->getter = QV4::Lookup::getterQObject; return lookup->getter(lookup, engine, *object); } -ReturnedValue QObjectWrapper::lookupGetter(Lookup *lookup, ExecutionEngine *engine, const Value &object) -{ - const auto revertLookup = [lookup, engine, &object]() { - lookup->qobjectLookup.propertyCache->release(); - lookup->qobjectLookup.propertyCache = nullptr; - lookup->getter = Lookup::getterGeneric; - return Lookup::getterGeneric(lookup, engine, object); - }; - - return lookupGetterImpl(lookup, engine, object, /*useOriginalProperty*/ false, revertLookup); -} - ReturnedValue QObjectWrapper::lookupAttached( Lookup *l, ExecutionEngine *engine, const Value &object) { return QV4::Lookup::getterGeneric(l, engine, object); } -bool QObjectWrapper::lookupSetter(Lookup *l, ExecutionEngine *engine, Value &object, const Value &v) -{ - return QV4::Lookup::setterFallback(l, engine, object, v); -} - bool QObjectWrapper::virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value) { @@ -1256,8 +1240,7 @@ void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markSta void QObjectWrapper::destroyObject(bool lastCall) { Heap::QObjectWrapper *h = d(); - if (!h->internalClass) - return; // destroyObject already got called + Q_ASSERT(h->internalClass); if (h->object()) { QQmlData *ddata = QQmlData::get(h->object(), false); @@ -1266,6 +1249,8 @@ void QObjectWrapper::destroyObject(bool lastCall) if (ddata && ddata->ownContext) { Q_ASSERT(ddata->ownContext.data() == ddata->context); ddata->ownContext->emitDestruction(); + if (ddata->ownContext->contextObject() == h->object()) + ddata->ownContext->setContextObject(nullptr); ddata->ownContext = nullptr; ddata->context = nullptr; } @@ -1287,7 +1272,7 @@ void QObjectWrapper::destroyObject(bool lastCall) } } - h->~Data(); + h->destroy(); } @@ -1904,12 +1889,24 @@ bool CallArgument::fromValue(QMetaType metaType, QV4::ExecutionEngine *engine, c } else if (callType == QMetaType::QObjectStar) { qobjectPtr = nullptr; type = callType; - if (const QV4::QObjectWrapper *qobjectWrapper = value.as()) + if (const QV4::QObjectWrapper *qobjectWrapper = value.as()) { qobjectPtr = qobjectWrapper->object(); - else if (const QV4::QQmlTypeWrapper *qmlTypeWrapper = value.as()) - queryEngine = qmlTypeWrapper->isSingleton(); - else if (!value.isNull() && !value.isUndefined()) // null and undefined are nullptr + } else if (const QV4::QQmlTypeWrapper *qmlTypeWrapper = value.as()) { + if (qmlTypeWrapper->isSingleton()) { + queryEngine = true; + } else if (QObject *obj = qmlTypeWrapper->object()) { + // attached object case + qobjectPtr = obj; + return true; + } else { + // If this is a plain type wrapper without an instance, + // then we got a namespace, and that's a type error + type = QMetaType::UnknownType; + return false; + } + } else if (!value.isNull() && !value.isUndefined()) { // null and undefined are nullptr return false; + } } else if (callType == qMetaTypeId()) { qvariantPtr = new (&allocData) QVariant(scope.engine->toVariant(value, QMetaType {})); type = callType; @@ -2012,7 +2009,7 @@ bool CallArgument::fromValue(QMetaType metaType, QV4::ExecutionEngine *engine, c qvariantPtr->convert(callMetaType); } else { QQmlMetaObject mo = ep ? ep->rawMetaObjectForType(callType) : QQmlMetaObject(); - if (!mo.isNull()) { + if (!mo.isNull() && v.metaType().flags().testFlag(QMetaType::PointerToQObject)) { QObject *obj = QQmlMetaType::toQObject(v); if (obj != nullptr && !QQmlMetaObject::canConvert(obj, mo)) { @@ -2089,35 +2086,49 @@ QV4::ReturnedValue CallArgument::toValue(QV4::ExecutionEngine *engine) } } -ReturnedValue QObjectMethod::create(ExecutionContext *scope, QObject *object, int index) +ReturnedValue QObjectMethod::create(ExecutionContext *scope, Heap::Object *wrapper, int index) { Scope valueScope(scope); - Scoped method(valueScope, valueScope.engine->memoryManager->allocate(scope)); - method->d()->setObject(object); - - method->d()->index = index; + Scoped method( + valueScope, + valueScope.engine->memoryManager->allocate(scope, wrapper, index)); return method.asReturnedValue(); } ReturnedValue QObjectMethod::create(ExecutionContext *scope, Heap::QQmlValueTypeWrapper *valueType, int index) { Scope valueScope(scope); - Scoped method(valueScope, valueScope.engine->memoryManager->allocate(scope)); - method->d()->index = index; - method->d()->valueTypeWrapper.set(valueScope.engine, valueType); + Scoped method( + valueScope, + valueScope.engine->memoryManager->allocate(scope, valueType, index)); return method.asReturnedValue(); } -void Heap::QObjectMethod::init(QV4::ExecutionContext *scope) +void Heap::QObjectMethod::init(QV4::ExecutionContext *scope, Object *object, int methodIndex) { Heap::FunctionObject::init(scope); + wrapper.set(internalClass->engine, object); + index = methodIndex; } const QMetaObject *Heap::QObjectMethod::metaObject() { - if (valueTypeWrapper) - return valueTypeWrapper->metaObject(); - return object()->metaObject(); + Scope scope(internalClass->engine); + if (Scoped valueWrapper(scope, wrapper); valueWrapper) + return valueWrapper->metaObject(); + if (QObject *self = object()) + return self->metaObject(); + return nullptr; +} + +QObject *Heap::QObjectMethod::object() const +{ + Scope scope(internalClass->engine); + if (Scoped objectWrapper(scope, wrapper); objectWrapper) + return objectWrapper->object(); + if (Scoped typeWrapper(scope, wrapper); typeWrapper) + return typeWrapper->object(); + return nullptr; } void Heap::QObjectMethod::ensureMethodsCache() @@ -2213,14 +2224,19 @@ ReturnedValue QObjectMethod::callInternal(const Value *thisObject, const Value * d()->ensureMethodsCache(); Scope scope(v4); - QQmlObjectOrGadget object(d()->object()); - - if (!d()->object()) { - if (!d()->valueTypeWrapper) - return Encode::undefined(); - - object = QQmlObjectOrGadget(d()->metaObject(), d()->valueTypeWrapper->gadgetPtr()); - } + Heap::QQmlValueTypeWrapper *valueWrapper = nullptr; + QQmlObjectOrGadget object = [&]() { + QV4::Scope scope(v4); + if (QV4::Scoped qobject(scope, d()->wrapper); qobject) + return QQmlObjectOrGadget(qobject->object()); + if (QV4::Scoped type(scope, d()->wrapper); type) + return QQmlObjectOrGadget(type->object()); + if (QV4::Scoped value(scope, d()->wrapper); value) { + valueWrapper = value->d(); + return QQmlObjectOrGadget(valueWrapper->metaObject(), valueWrapper->gadgetPtr()); + } + Q_UNREACHABLE(); + }(); JSCallData cData(thisObject, argv, argc); CallData *callData = cData.callData(scope); @@ -2231,8 +2247,7 @@ ReturnedValue QObjectMethod::callInternal(const Value *thisObject, const Value * // The method might change the value. const auto doCall = [&](const auto &call) { if (!method->isConstant()) { - QV4::Scoped valueTypeReference( - scope, d()->valueTypeWrapper.get()); + QV4::Scoped valueTypeReference(scope, valueWrapper); if (valueTypeReference) { QV4::ScopedValue rv(scope, call()); valueTypeReference->d()->writeBack(); @@ -2355,9 +2370,11 @@ ReturnedValue QMetaObjectWrapper::constructInternal(const Value *argv, int argc) objectOrGadget, d()->constructors, d()->constructorCount, v4, callData)) { object = CallPrecise(objectOrGadget, *ctor, v4, callData, QMetaObject::CreateInstance); } - Scoped metaObject(scope, this); - object->defineDefaultProperty(v4->id_constructor(), metaObject); - object->setPrototypeOf(const_cast(this)); + if (object) { + Scoped metaObject(scope, this); + object->defineDefaultProperty(v4->id_constructor(), metaObject); + object->setPrototypeOf(const_cast(this)); + } return object.asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 37cb4d3cac5..ca0e5758c47 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -96,32 +96,29 @@ struct Q_QML_EXPORT QObjectWrapper : Object { }; #define QObjectMethodMembers(class, Member) \ - Member(class, Pointer, QQmlValueTypeWrapper *, valueTypeWrapper) \ + Member(class, Pointer, Object *, wrapper) \ Member(class, NoMark, QV4QPointer, qObj) \ Member(class, NoMark, int, index) -DECLARE_HEAP_OBJECT(QObjectMethod, FunctionObject) { - DECLARE_MARKOBJECTS(QObjectMethod); +DECLARE_EXPORTED_HEAP_OBJECT(QObjectMethod, FunctionObject) { + DECLARE_MARKOBJECTS(QObjectMethod) QQmlPropertyData *methods; int methodCount; alignas(alignof(QQmlPropertyData)) std::byte _singleMethod[sizeof(QQmlPropertyData)]; - void init(QV4::ExecutionContext *scope); + void init(QV4::ExecutionContext *scope, Object *wrapper, int index); void destroy() { if (methods != reinterpret_cast(&_singleMethod)) delete[] methods; - qObj.destroy(); FunctionObject::destroy(); } void ensureMethodsCache(); const QMetaObject *metaObject(); - QObject *object() const { return qObj.data(); } - void setObject(QObject *o) { qObj = o; } - + QObject *object() const; }; struct QMetaObjectWrapper : FunctionObject { @@ -160,6 +157,13 @@ struct Q_QML_EXPORT QObjectWrapper : public Object static void initializeBindings(ExecutionEngine *engine); + const QMetaObject *metaObject() const + { + if (QObject *o = object()) + return o->metaObject(); + return nullptr; + } + QObject *object() const { return d()->object(); } ReturnedValue getQmlProperty( @@ -169,8 +173,8 @@ struct Q_QML_EXPORT QObjectWrapper : public Object \ static ReturnedValue getQmlProperty( ExecutionEngine *engine, const QQmlRefPointer &qmlContext, - QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = nullptr, - QQmlPropertyData **property = nullptr); + Heap::Object *wrapper, QObject *object, String *name, RevisionMode revisionMode, + bool *hasProperty = nullptr, QQmlPropertyData **property = nullptr); static bool setQmlProperty( ExecutionEngine *engine, const QQmlRefPointer &qmlContext, @@ -186,13 +190,12 @@ struct Q_QML_EXPORT QObjectWrapper : public Object void destroyObject(bool lastCall); - static ReturnedValue getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property); + static ReturnedValue getProperty( + ExecutionEngine *engine, Heap::Object *wrapper, QObject *object, + QQmlPropertyData *property); static ReturnedValue virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup); - static ReturnedValue lookupGetter(Lookup *l, ExecutionEngine *engine, const Value &object); static ReturnedValue lookupAttached(Lookup *l, ExecutionEngine *engine, const Value &object); - static bool lookupSetter(QV4::Lookup *l, QV4::ExecutionEngine *engine, - QV4::Value &object, const QV4::Value &value); template static ReturnedValue lookupGetterImpl(Lookup *l, ExecutionEngine *engine, const Value &object, bool useOriginalProperty, ReversalFunctor revert); static bool virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value); @@ -246,7 +249,7 @@ inline ReturnedValue QObjectWrapper::lookupGetterImpl(Lookup *lookup, ExecutionE if (!o || o->internalClass != lookup->qobjectLookup.ic) return revertLookup(); - const Heap::QObjectWrapper *This = static_cast(o); + Heap::QObjectWrapper *This = static_cast(o); QObject *qobj = This->object(); if (QQmlData::wasDeleted(qobj)) return QV4::Encode::undefined(); @@ -274,7 +277,7 @@ inline ReturnedValue QObjectWrapper::lookupGetterImpl(Lookup *lookup, ExecutionE return revertLookup(); } - return getProperty(engine, qobj, property); + return getProperty(engine, This, qobj, property); } struct QQmlValueTypeWrapper; @@ -286,7 +289,7 @@ struct Q_QML_EXPORT QObjectMethod : public QV4::FunctionObject enum { DestroyMethod = -1, ToStringMethod = -2 }; - static ReturnedValue create(QV4::ExecutionContext *scope, QObject *object, int index); + static ReturnedValue create(QV4::ExecutionContext *scope, Heap::Object *wrapper, int index); static ReturnedValue create(QV4::ExecutionContext *scope, Heap::QQmlValueTypeWrapper *valueType, int index); int methodIndex() const { return d()->index; } diff --git a/src/qml/jsruntime/qv4reflect.cpp b/src/qml/jsruntime/qv4reflect.cpp index 2a6c61f044d..39a0b03decb 100644 --- a/src/qml/jsruntime/qv4reflect.cpp +++ b/src/qml/jsruntime/qv4reflect.cpp @@ -76,7 +76,10 @@ struct CallArgs { static CallArgs createListFromArrayLike(Scope &scope, const Object *o) { - int len = o->getLength(); + int len = scope.engine->safeForAllocLength(o->getLength()); + if (scope.engine->hasException) + return {nullptr, 0}; + Value *arguments = scope.alloc(len); for (int i = 0; i < len; ++i) { diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 01a7878dae1..98300b1dd0e 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1544,6 +1544,11 @@ static CallArgs createSpreadArguments(Scope &scope, Value *argv, int argc) if (done->booleanValue()) break; ++argCount; + constexpr auto safetyMargin = 100; // leave some space on the stack for actual work with the elements + if (qint64(scope.engine->jsStackLimit - scope.engine->jsStackTop) < safetyMargin) { + scope.engine->throwRangeError(QLatin1String("Too many elements in array to use it with the spread operator")); + return { nullptr, 0 }; + } v = scope.alloc(); } } @@ -1608,7 +1613,7 @@ ReturnedValue Runtime::TailCall::call(JSTypesStackFrame *frame, ExecutionEngine return checkedResult(engine, fo.call(&thisObject, argv, argc)); } - memcpy(frame->jsFrame->args, argv, argc * sizeof(Value)); + memmove(frame->jsFrame->args, argv, argc * sizeof(Value)); frame->init(fo.function(), frame->jsFrame->argValues(), argc, frame->callerCanHandleTailCall()); frame->setupJSFrame(frame->framePointer(), fo, fo.scope(), thisObject, @@ -2440,6 +2445,7 @@ QHash Runtime::symbolTable() {symbol(), "UMinus" }, {symbol(), "Instanceof" }, + {symbol(), "As" }, {symbol(), "In" }, {symbol(), "Add" }, {symbol(), "Sub" }, diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index 0523d740fbd..b0268afeddb 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -219,7 +219,7 @@ struct QV4Sequence : public QV4::Object } loadReference(); } - if (index < size()) { + if (index < quint32(size())) { if (hasProperty) *hasProperty = true; return engine()->fromVariant(at(index)); @@ -251,7 +251,7 @@ struct QV4Sequence : public QV4::Object loadReference(); } - qsizetype count = size(); + quint32 count = quint32(size()); const QMetaType valueMetaType = meta(d())->valueMetaType(); const QVariant element = engine()->toVariant(value, valueMetaType, false); @@ -284,7 +284,7 @@ struct QV4Sequence : public QV4::Object return QV4::Attr_Invalid; loadReference(); } - return (index < size()) ? QV4::Attr_Data : QV4::Attr_Invalid; + return (index < quint32(size())) ? QV4::Attr_Data : QV4::Attr_Invalid; } struct OwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator @@ -300,7 +300,7 @@ struct QV4Sequence : public QV4::Object s->loadReference(); } - if (arrayIndex < s->size()) { + if (arrayIndex < quint32(s->size())) { uint index = arrayIndex; ++arrayIndex; if (attrs) @@ -333,7 +333,7 @@ struct QV4Sequence : public QV4::Object loadReference(); } - if (index >= size()) + if (index >= quint32(size())) return false; /* according to ECMA262r3 it should be Undefined, */ @@ -709,3 +709,5 @@ int SequencePrototype::metaTypeForSequence(const QV4::Object *object) } QT_END_NAMESPACE + +#include "moc_qv4sequenceobject_p.cpp" diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h index 603d33d6d8b..48e4b5ff18f 100644 --- a/src/qml/jsruntime/qv4sequenceobject_p.h +++ b/src/qml/jsruntime/qv4sequenceobject_p.h @@ -61,8 +61,8 @@ #include "qv4string_p.h" #if QT_CONFIG(qml_itemmodel) -#include #include +#include #endif QT_REQUIRE_CONFIG(qml_sequence_object); diff --git a/src/qml/jsruntime/qv4stackframe.cpp b/src/qml/jsruntime/qv4stackframe.cpp index a716c53aea8..0a060e81a70 100644 --- a/src/qml/jsruntime/qv4stackframe.cpp +++ b/src/qml/jsruntime/qv4stackframe.cpp @@ -53,7 +53,7 @@ QString CppStackFrame::function() const int CppStackFrame::lineNumber() const { - if (!v4Function) + if (!v4Function || instructionPointer <= 0) return -1; auto findLine = [](const CompiledData::CodeOffsetToLine &entry, uint offset) { @@ -61,9 +61,9 @@ int CppStackFrame::lineNumber() const }; const QV4::CompiledData::Function *cf = v4Function->compiledFunction; - uint offset = instructionPointer; + const uint offset = instructionPointer; const CompiledData::CodeOffsetToLine *lineNumbers = cf->lineNumberTable(); - uint nLineNumbers = cf->nLineNumbers; + const uint nLineNumbers = cf->nLineNumbers; const CompiledData::CodeOffsetToLine *line = std::lower_bound(lineNumbers, lineNumbers + nLineNumbers, offset, findLine) - 1; return line->line; } diff --git a/src/qml/jsruntime/qv4stackframe_p.h b/src/qml/jsruntime/qv4stackframe_p.h index ebe3b762afe..be6ec550b65 100644 --- a/src/qml/jsruntime/qv4stackframe_p.h +++ b/src/qml/jsruntime/qv4stackframe_p.h @@ -88,6 +88,7 @@ struct Q_QML_PRIVATE_EXPORT CppStackFrameBase struct { const QMetaType *metaTypes; void **returnAndArgs; + bool returnValueIsUndefined; }; }; @@ -182,11 +183,15 @@ struct Q_QML_PRIVATE_EXPORT MetaTypesStackFrame : public CppStackFrame CppStackFrame::init(v4Function, argc, Kind::Meta); metaTypes = types; returnAndArgs = a; + returnValueIsUndefined = false; } QMetaType returnType() const { return metaTypes[0]; } void *returnValue() const { return returnAndArgs[0]; } + bool isReturnValueUndefined() const { return CppStackFrameBase::returnValueIsUndefined; } + void setReturnValueUndefined() { CppStackFrameBase::returnValueIsUndefined = true; } + const QMetaType *argTypes() const { return metaTypes + 1; } void **argv() const { return returnAndArgs + 1; } }; diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h index d5d11ef6605..69584c114e4 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -88,7 +88,7 @@ struct Q_QML_PRIVATE_EXPORT StringOrSymbol : Base new (&textStorage) QStringPrivate(std::move(text)); } - mutable std::aligned_storage::type textStorage; + mutable struct { alignas(QStringPrivate) unsigned char data[sizeof(QStringPrivate)]; } textStorage; mutable PropertyKey identifier; mutable uint subtype; mutable uint stringHash; @@ -230,6 +230,12 @@ struct Q_QML_PRIVATE_EXPORT String : public StringOrSymbol { return calculateHashValue(ch, end, subtype); } + static uint createHashValueDisallowingArrayIndex(const QChar *ch, int length, uint *subtype) + { + const QChar *end = ch + length; + return calculateHashValue(ch, end, subtype); + } + static uint createHashValue(const char *ch, int length, uint *subtype) { const char *end = ch + length; @@ -243,15 +249,19 @@ struct Q_QML_PRIVATE_EXPORT String : public StringOrSymbol { static qint64 virtualGetLength(const Managed *m); public: - template + enum IndicesBehavior {Default, DisallowArrayIndex}; + template static inline uint calculateHashValue(const T *ch, const T* end, uint *subtype) { // array indices get their number as hash value - uint h = stringToArrayIndex(ch, end); - if (h != UINT_MAX) { - if (subtype) - *subtype = Heap::StringOrSymbol::StringType_ArrayIndex; - return h; + uint h = UINT_MAX; + if constexpr (Behavior != DisallowArrayIndex) { + h = stringToArrayIndex(ch, end); + if (h != UINT_MAX) { + if (subtype) + *subtype = Heap::StringOrSymbol::StringType_ArrayIndex; + return h; + } } while (ch < end) { diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 88bb309b7d6..ab07fe58a69 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -432,16 +432,18 @@ static bool compareEqualInt(QV4::Value &accumulator, QV4::Value lhs, int rhs) void VME::exec(MetaTypesStackFrame *frame, ExecutionEngine *engine) { qt_v4ResolvePendingBreakpointsHook(); - if (engine->checkStackLimits()) + if (engine->checkStackLimits()) { + frame->setReturnValueUndefined(); return; + } ExecutionEngineCallDepthRecorder executionEngineCallDepthRecorder(engine); Function *function = frame->v4Function; Q_ASSERT(function->aotFunction); Q_TRACE_SCOPE(QQmlV4_function_call, engine, function->name()->toQString(), function->executableCompilationUnit()->fileName(), - function->compiledFunction->location.line, - function->compiledFunction->location.column); + function->compiledFunction->location.line(), + function->compiledFunction->location.column()); Profiling::FunctionCallProfiler profiler(engine, function); // start execution profiling const qsizetype numFunctionArguments = function->aotFunction->argumentTypes.size(); @@ -459,9 +461,17 @@ void VME::exec(MetaTypesStackFrame *frame, ExecutionEngine *engine) Q_ASSERT(argumentType.sizeOf() > 0); Q_ALLOCA_VAR(void, arg, argumentType.sizeOf()); - argumentType.construct(arg); - if (frame->argc() > i) - QMetaType::convert(frame->argTypes()[i], frame->argv()[i], argumentType, arg); + + if (argumentType == QMetaType::fromType()) { + if (frame->argc() > i) + new (arg) QVariant(frame->argTypes()[i], frame->argv()[i]); + else + new (arg) QVariant(); + } else { + argumentType.construct(arg); + if (frame->argc() > i) + QMetaType::convert(frame->argTypes()[i], frame->argv()[i], argumentType, arg); + } transformedArguments[i] = arg; } @@ -470,8 +480,10 @@ void VME::exec(MetaTypesStackFrame *frame, ExecutionEngine *engine) const QMetaType frameReturn = frame->returnType(); Q_ALLOCA_DECLARE(void, transformedResult); if (frame->returnValue() && returnType != frameReturn) { - Q_ASSERT(returnType.sizeOf() > 0); - Q_ALLOCA_ASSIGN(void, transformedResult, returnType.sizeOf()); + if (returnType.sizeOf() > 0) + Q_ALLOCA_ASSIGN(void, transformedResult, returnType.sizeOf()); + else + transformedResult = frame; // Some non-null marker value } QQmlPrivate::AOTCompiledContext aotContext; @@ -521,8 +533,8 @@ ReturnedValue VME::exec(JSTypesStackFrame *frame, ExecutionEngine *engine) Function *function = frame->v4Function; Q_TRACE_SCOPE(QQmlV4_function_call, engine, function->name()->toQString(), function->executableCompilationUnit()->fileName(), - function->compiledFunction->location.line, - function->compiledFunction->location.column); + function->compiledFunction->location.line(), + function->compiledFunction->location.column()); Profiling::FunctionCallProfiler profiler(engine, function); // start execution profiling QV4::Debugging::Debugger *debugger = engine->debugger(); diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index 0aeeb0ec5b4..b9f06e41339 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -995,7 +995,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = engine->m_multiplyWrappedQObjects) { for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) { - if (!it.value().isNullOrUndefined()) + if (it.value().isNullOrUndefined()) it = multiplyWrappedQObjects->erase(it); else ++it; diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index eb082b77c29..43d8474cee3 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -1722,6 +1722,18 @@ Type: UiQualifiedId; } break; ./ +Type: T_VAR; +/. case $rule_number: Q_FALLTHROUGH(); ./ + +Type: T_VOID; +/. + case $rule_number: { + AST::UiQualifiedId *id = new (pool) AST::UiQualifiedId(stringRef(1)); + id->identifierToken = loc(1); + sym(1).Type = new (pool) AST::Type(id->finish()); + } break; +./ + TypeAnnotation: T_COLON Type; /. case $rule_number: { @@ -2246,7 +2258,14 @@ InitializerOpt: Initializer; InitializerOpt_In: Initializer_In; TemplateLiteral: T_NO_SUBSTITUTION_TEMPLATE; -/. case $rule_number: Q_FALLTHROUGH(); ./ +/. + case $rule_number: { + AST::TemplateLiteral *node = new (pool) AST::TemplateLiteral(stringRef(1), rawStringRef(1), nullptr); + node->literalToken = loc(1); + node->hasNoSubstitution = true; + sym(1).Node = node; + } break; +./ TemplateSpans: T_TEMPLATE_TAIL; /. diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index d7b4f2a8be2..bd4e2254123 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -735,6 +735,7 @@ class QML_PARSER_EXPORT TemplateLiteral : public LeftHandSideExpression void accept0(BaseVisitor *visitor) override; + bool hasNoSubstitution = false; QStringView value; QStringView rawValue; ExpressionNode *expression; diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h index 03955e0563e..6bef117646c 100644 --- a/src/qml/qml/ftw/qhashedstring_p.h +++ b/src/qml/qml/ftw/qhashedstring_p.h @@ -144,7 +144,7 @@ class Q_QML_PRIVATE_EXPORT QHashedStringRef mutable quint32 m_hash = 0; }; -class Q_AUTOTEST_EXPORT QHashedCStringRef +class QHashedCStringRef { public: inline QHashedCStringRef(); @@ -157,7 +157,7 @@ class Q_AUTOTEST_EXPORT QHashedCStringRef inline const char *constData() const; inline int length() const; - QString toUtf16() const; + Q_AUTOTEST_EXPORT QString toUtf16() const; inline int utf16length() const; inline void writeUtf16(QChar *) const; inline void writeUtf16(quint16 *) const; diff --git a/src/qml/qml/ftw/qintrusivelist_p.h b/src/qml/qml/ftw/qintrusivelist_p.h index 8992be9f935..40dc45095f7 100644 --- a/src/qml/qml/ftw/qintrusivelist_p.h +++ b/src/qml/qml/ftw/qintrusivelist_p.h @@ -241,7 +241,12 @@ typename QIntrusiveList::iterator QIntrusiveList::end() template N *QIntrusiveList::nodeToN(QIntrusiveListNode *node) { + QT_WARNING_PUSH +#if defined(Q_CC_CLANG) && Q_CC_CLANG >= 1300 + QT_WARNING_DISABLE_CLANG("-Wnull-pointer-subtraction") +#endif return (N *)((char *)node - ((char *)&(((N *)nullptr)->*member) - (char *)nullptr)); + QT_WARNING_POP } QIntrusiveListNode::QIntrusiveListNode() diff --git a/src/qml/qml/ftw/qrecyclepool_p.h b/src/qml/qml/ftw/qrecyclepool_p.h index 3ba488d5867..76381324aa8 100644 --- a/src/qml/qml/ftw/qrecyclepool_p.h +++ b/src/qml/qml/ftw/qrecyclepool_p.h @@ -132,8 +132,7 @@ template T *QRecyclePool::New() { T *rv = d->allocate(); - new (rv) T; - return rv; + return new (rv) T; } template @@ -141,8 +140,7 @@ template T *QRecyclePool::New(const T1 &a) { T *rv = d->allocate(); - new (rv) T(a); - return rv; + return new (rv) T(a); } template @@ -150,8 +148,7 @@ template T *QRecyclePool::New(T1 &a) { T *rv = d->allocate(); - new (rv) T(a); - return rv; + return new (rv) T(a); } template diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index 70525f98a46..c5ec43bbb78 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -344,9 +344,9 @@ static QVector availableRevisions(const QMetaObject *metaObject) return revisions; const int propertyOffset = metaObject->propertyOffset(); const int propertyCount = metaObject->propertyCount(); - for (int propertyIndex = propertyOffset, propertyEnd = propertyOffset + propertyCount; - propertyIndex < propertyEnd; ++propertyIndex) { - const QMetaProperty property = metaObject->property(propertyIndex); + for (int coreIndex = propertyOffset, propertyEnd = propertyOffset + propertyCount; + coreIndex < propertyEnd; ++coreIndex) { + const QMetaProperty property = metaObject->property(coreIndex); if (int revision = property.revision()) revisions.append(QTypeRevision::fromEncodedVersion(revision)); } @@ -712,6 +712,28 @@ void AOTCompiledContext::setInstructionPointer(int offset) const frame->instructionPointer = offset; } +void AOTCompiledContext::setReturnValueUndefined() const +{ + if (auto *frame = engine->handle()->currentStackFrame) { + Q_ASSERT(frame->isMetaTypesFrame()); + static_cast(frame)->setReturnValueUndefined(); + } +} + +static void captureFallbackProperty( + QObject *object, int coreIndex, int notifyIndex, bool isConstant, + QQmlContextData *qmlContext) +{ + if (!qmlContext || isConstant) + return; + + QQmlEngine *engine = qmlContext->engine(); + Q_ASSERT(engine); + QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); + Q_ASSERT(ep); + if (QQmlPropertyCapture *capture = ep->propertyCapture) + capture->captureProperty(object, coreIndex, notifyIndex); +} static void captureObjectProperty( QObject *object, const QQmlPropertyCache *propertyCache, @@ -737,31 +759,135 @@ static bool inherits(const QQmlPropertyCache *descendent, const QQmlPropertyCach return false; } -static bool loadObjectProperty(QV4::Lookup *l, QObject *object, void *target, - QQmlContextData *qmlContext) +enum class ObjectPropertyResult { OK, NeedsInit, Deleted }; + +static ObjectPropertyResult loadObjectProperty( + QV4::Lookup *l, QObject *object, void *target, QQmlContextData *qmlContext) { + QQmlData *qmlData = QQmlData::get(object); + if (!qmlData) + return ObjectPropertyResult::NeedsInit; + if (qmlData->isQueuedForDeletion) + return ObjectPropertyResult::Deleted; Q_ASSERT(!QQmlData::wasDeleted(object)); const QQmlPropertyCache *propertyCache = l->qobjectLookup.propertyCache; - if (!inherits(QQmlData::get(object)->propertyCache, propertyCache)) - return false; + if (!inherits(qmlData->propertyCache, propertyCache)) + return ObjectPropertyResult::NeedsInit; const QQmlPropertyData *property = l->qobjectLookup.propertyData; + + const int coreIndex = property->coreIndex(); + if (qmlData->hasPendingBindingBit(coreIndex)) + qmlData->flushPendingBinding(coreIndex); + captureObjectProperty(object, propertyCache, property, qmlContext); property->readProperty(object, target); - return true; + return ObjectPropertyResult::OK; } -static bool storeObjectProperty(QV4::Lookup *l, QObject *object, void *value) +static ObjectPropertyResult loadFallbackProperty( + QV4::Lookup *l, QObject *object, void *target, QQmlContextData *qmlContext) { + QQmlData *qmlData = QQmlData::get(object); + if (qmlData && qmlData->isQueuedForDeletion) + return ObjectPropertyResult::Deleted; + Q_ASSERT(!QQmlData::wasDeleted(object)); - if (!inherits(QQmlData::get(object)->propertyCache, l->qobjectLookup.propertyCache)) - return false; + + const QMetaObject *metaObject + = reinterpret_cast(l->qobjectFallbackLookup.metaObject - 1); + if (!metaObject || metaObject != object->metaObject()) + return ObjectPropertyResult::NeedsInit; + + const int coreIndex = l->qobjectFallbackLookup.coreIndex; + if (qmlData && qmlData->hasPendingBindingBit(coreIndex)) + qmlData->flushPendingBinding(coreIndex); + + captureFallbackProperty(object, coreIndex, l->qobjectFallbackLookup.notifyIndex, + l->qobjectFallbackLookup.isConstant, qmlContext); + + void *a[] = { target, nullptr }; + metaObject->metacall(object, QMetaObject::ReadProperty, coreIndex, a); + + return ObjectPropertyResult::OK; +} + +static ObjectPropertyResult storeObjectProperty(QV4::Lookup *l, QObject *object, void *value) +{ + const QQmlData *qmlData = QQmlData::get(object); + if (!qmlData) + return ObjectPropertyResult::NeedsInit; + if (qmlData->isQueuedForDeletion) + return ObjectPropertyResult::Deleted; + Q_ASSERT(!QQmlData::wasDeleted(object)); + if (!inherits(qmlData->propertyCache, l->qobjectLookup.propertyCache)) + return ObjectPropertyResult::NeedsInit; const QQmlPropertyData *property = l->qobjectLookup.propertyData; QQmlPropertyPrivate::removeBinding(object, QQmlPropertyIndex(property->coreIndex())); property->writeProperty(object, value, {}); + return ObjectPropertyResult::OK; +} + +static ObjectPropertyResult storeFallbackProperty(QV4::Lookup *l, QObject *object, void *value) +{ + const QQmlData *qmlData = QQmlData::get(object); + if (qmlData && qmlData->isQueuedForDeletion) + return ObjectPropertyResult::Deleted; + Q_ASSERT(!QQmlData::wasDeleted(object)); + + const QMetaObject *metaObject + = reinterpret_cast(l->qobjectFallbackLookup.metaObject - 1); + if (!metaObject || metaObject != object->metaObject()) + return ObjectPropertyResult::NeedsInit; + + const int coreIndex = l->qobjectFallbackLookup.coreIndex; + QQmlPropertyPrivate::removeBinding(object, QQmlPropertyIndex(coreIndex)); + + void *args[] = { value, nullptr }; + metaObject->metacall(object, QMetaObject::WriteProperty, coreIndex, args); + return ObjectPropertyResult::OK; +} + +static bool isTypeCompatible(QMetaType lookupType, QMetaType propertyType, + const AOTCompiledContext *aotContext) +{ + if (!lookupType.isValid()) { + // If type is invalid, then the calling code depends on the lookup + // to be set up in order to query the type, via lookupResultMetaType. + // We cannot verify the type in this case. + } else if ((lookupType.flags() & QMetaType::IsQmlList) + && (propertyType.flags() & QMetaType::IsQmlList)) { + // We want to check the value types here, but we cannot easily do it. + // Internally those are all QObject* lists, though. + } else if (lookupType.flags() & QMetaType::PointerToQObject) { + // We accept any base class as type, too + + const QMetaObject *typeMetaObject = lookupType.metaObject(); + const QMetaObject *foundMetaObject = propertyType.metaObject(); + if (!foundMetaObject) { + if (QQmlEngine *engine = aotContext->qmlEngine()) { + foundMetaObject = QQmlEnginePrivate::get(engine)->metaObjectForType( + propertyType.id()).metaObject(); + } + } + + while (foundMetaObject && foundMetaObject != typeMetaObject) + foundMetaObject = foundMetaObject->superClass(); + + if (!foundMetaObject) + return false; + } else if (propertyType != lookupType) { + return false; + } return true; } -static bool initObjectLookup( +enum class ObjectLookupResult { + Failure, + Object, + Fallback +}; + +static ObjectLookupResult initObjectLookup( const AOTCompiledContext *aotContext, QV4::Lookup *l, QObject *object, QMetaType type) { QV4::Scope scope(aotContext->engine->handle()); @@ -777,6 +903,8 @@ static bool initObjectLookup( QQmlData *ddata = QQmlData::get(object, true); Q_ASSERT(ddata); + if (ddata->isQueuedForDeletion) + return ObjectLookupResult::Failure; QQmlPropertyData *property; if (!ddata->propertyCache) { @@ -787,50 +915,36 @@ static bool initObjectLookup( name.getPointer(), object, aotContext->qmlContext); } - if (!property) - return false; - - const QMetaType propType = property->propType(); - if (!type.isValid()) { - // If type is invalid, then the calling code depends on the lookup - // to be set up in order to query the type, via lookupResultMetaType. - // We cannot verify the type in this case. - } else if ((type.flags() & QMetaType::IsQmlList) && (propType.flags() & QMetaType::IsQmlList)) { - // We want to check the value types here, but we cannot easily do it. - // Internally those are all QObject* lists, though. - } else if (type.flags() & QMetaType::PointerToQObject) { - // We accept any base class as type, too - - const QMetaObject *typeMetaObject = type.metaObject(); - const QMetaObject *foundMetaObject = propType.metaObject(); - if (!foundMetaObject) { - if (QQmlEngine *engine = aotContext->qmlEngine()) { - foundMetaObject = QQmlEnginePrivate::get(engine)->metaObjectForType( - propType.id()).metaObject(); - } - } - - while (foundMetaObject) { - if (foundMetaObject == typeMetaObject) - break; - foundMetaObject = foundMetaObject->superClass(); - } - - if (!foundMetaObject) - return false; - } else if (propType != type) { - return false; + if (!property) { + const QMetaObject *metaObject = object->metaObject(); + if (!metaObject) + return ObjectLookupResult::Failure; + + const int coreIndex = metaObject->indexOfProperty( + name->toQStringNoThrow().toUtf8().constData()); + if (coreIndex < 0) + return ObjectLookupResult::Failure; + + const QMetaProperty property = metaObject->property(coreIndex); + if (!isTypeCompatible(type, property.metaType(), aotContext)) + return ObjectLookupResult::Failure; + + l->releasePropertyCache(); + // & 1 to tell the gc that this is not heap allocated; see markObjects in qv4lookup_p.h + l->qobjectFallbackLookup.metaObject = quintptr(metaObject) + 1; + l->qobjectFallbackLookup.coreIndex = coreIndex; + l->qobjectFallbackLookup.notifyIndex = property.notifySignalIndex(); + l->qobjectFallbackLookup.isConstant = property.isConstant() ? 1 : 0; + return ObjectLookupResult::Fallback; } - Q_ASSERT(ddata->propertyCache); + if (!isTypeCompatible(type, property->propType(), aotContext)) + return ObjectLookupResult::Failure; - if (l->qobjectLookup.propertyCache) - l->qobjectLookup.propertyCache->release(); + Q_ASSERT(ddata->propertyCache); - l->qobjectLookup.propertyCache = ddata->propertyCache; - l->qobjectLookup.propertyCache->addref(); - l->qobjectLookup.propertyData = property; - return true; + QV4::setupQObjectLookup(l, ddata, property); + return ObjectLookupResult::Object; } static bool initValueLookup(QV4::Lookup *l, QV4::ExecutableCompilationUnit *compilationUnit, @@ -839,8 +953,8 @@ static bool initValueLookup(QV4::Lookup *l, QV4::ExecutableCompilationUnit *comp Q_ASSERT(metaObject); const QByteArray name = compilationUnit->runtimeStrings[l->nameIndex]->toQString().toUtf8(); const int coreIndex = metaObject->indexOfProperty(name.constData()); - QMetaType lookupType = metaObject->property(l->qgadgetLookup.coreIndex).metaType(); - if (lookupType != type) + QMetaType lookupType = metaObject->property(coreIndex).metaType(); + if (type.isValid() && lookupType != type) return false; l->qgadgetLookup.metaObject = quintptr(metaObject) + 1; l->qgadgetLookup.coreIndex = coreIndex; @@ -862,28 +976,50 @@ static void amendException(QV4::ExecutionEngine *engine) bool AOTCompiledContext::captureLookup(uint index, QObject *object) const { - QV4::Lookup *l = compilationUnit->runtimeLookups + index; - if (l->getter != QV4::QQmlTypeWrapper::lookupSingletonProperty - && l->getter != QV4::QObjectWrapper::lookupGetter) { + if (!object) return false; + + QV4::Lookup *l = compilationUnit->runtimeLookups + index; + if (l->getter == QV4::QQmlTypeWrapper::lookupSingletonProperty + || l->getter == QV4::Lookup::getterQObject) { + const QQmlPropertyData *property = l->qobjectLookup.propertyData; + QQmlData::flushPendingBinding(object, property->coreIndex()); + captureObjectProperty(object, l->qobjectLookup.propertyCache, property, qmlContext); + return true; } - captureObjectProperty( - object, l->qobjectLookup.propertyCache, l->qobjectLookup.propertyData, qmlContext); - return true; + if (l->getter == QV4::Lookup::getterFallback) { + const int coreIndex = l->qobjectFallbackLookup.coreIndex; + QQmlData::flushPendingBinding(object, coreIndex); + captureFallbackProperty( + object, coreIndex, l->qobjectFallbackLookup.notifyIndex, + l->qobjectFallbackLookup.isConstant, qmlContext); + return true; + } + + return false; } bool AOTCompiledContext::captureQmlContextPropertyLookup(uint index) const { QV4::Lookup *l = compilationUnit->runtimeLookups + index; - if (l->qmlContextPropertyGetter != QV4::QQmlContextWrapper::lookupScopeObjectProperty - && l->qmlContextPropertyGetter != QV4::QQmlContextWrapper::lookupContextObjectProperty) { - return false; + if (l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupScopeObjectProperty + && l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupContextObjectProperty) { + const QQmlPropertyData *property = l->qobjectLookup.propertyData; + QQmlData::flushPendingBinding(qmlScopeObject, property->coreIndex()); + captureObjectProperty(qmlScopeObject, l->qobjectLookup.propertyCache, property, qmlContext); + return true; } - captureObjectProperty(qmlScopeObject, l->qobjectLookup.propertyCache, - l->qobjectLookup.propertyData, qmlContext); - return true; + if (l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupScopeFallbackProperty) { + const int coreIndex = l->qobjectFallbackLookup.coreIndex; + QQmlData::flushPendingBinding(qmlScopeObject, coreIndex); + captureFallbackProperty(qmlScopeObject, coreIndex, l->qobjectFallbackLookup.notifyIndex, + l->qobjectFallbackLookup.isConstant, qmlContext); + return true; + } + + return false; } QMetaType AOTCompiledContext::lookupResultMetaType(uint index) const @@ -892,7 +1028,8 @@ QMetaType AOTCompiledContext::lookupResultMetaType(uint index) const if (l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupScopeObjectProperty || l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupContextObjectProperty || l->getter == QV4::QQmlTypeWrapper::lookupSingletonProperty - || l->getter == QV4::QObjectWrapper::lookupGetter) { + || l->getter == QV4::Lookup::getterQObject + || l->setter == QV4::Lookup::setterQObject) { return l->qobjectLookup.propertyData->propType(); } else if (l->getter == QV4::QQmlValueTypeWrapper::lookupGetter) { return QMetaType(l->qgadgetLookup.metaType); @@ -903,6 +1040,14 @@ QMetaType AOTCompiledContext::lookupResultMetaType(uint index) const || l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupSingleton || l->getter == QV4::QObjectWrapper::lookupAttached) { return QMetaType::fromType(); + } else if (l->getter == QV4::Lookup::getterFallback + || l->setter == QV4::Lookup::setterFallback + || l->qmlContextPropertyGetter + == QV4::QQmlContextWrapper::lookupScopeFallbackProperty) { + const QMetaObject *metaObject + = reinterpret_cast(l->qobjectFallbackLookup.metaObject - 1); + const int coreIndex = l->qobjectFallbackLookup.coreIndex; + return metaObject->property(coreIndex).metaType(); } return QMetaType(); } @@ -914,14 +1059,52 @@ void AOTCompiledContext::storeNameSloppy(uint nameIndex, void *value, QMetaType // the property cache we store a value into the property. QV4::Lookup l; - l.clear(); + memset(&l, 0, sizeof(QV4::Lookup)); l.nameIndex = nameIndex; - if (initObjectLookup(this, &l, qmlScopeObject, type)) { - if (!storeObjectProperty(&l, qmlScopeObject, value)) - engine->handle()->throwTypeError(); + ObjectPropertyResult storeResult = ObjectPropertyResult::NeedsInit; + switch (initObjectLookup(this, &l, qmlScopeObject, QMetaType())) { + case ObjectLookupResult::Object: { + const QMetaType propType = l.qobjectLookup.propertyData->propType(); + if (type == propType) { + storeResult = storeObjectProperty(&l, qmlScopeObject, value); + } else { + QVariant var(propType); + propType.convert(type, value, propType, var.data()); + storeResult = storeObjectProperty(&l, qmlScopeObject, var.data()); + } + l.qobjectLookup.propertyCache->release(); - } else { + break; + } + case ObjectLookupResult::Fallback: { + const QMetaObject *metaObject + = reinterpret_cast(l.qobjectFallbackLookup.metaObject - 1); + const QMetaType propType + = metaObject->property(l.qobjectFallbackLookup.coreIndex).metaType(); + if (type == propType) { + storeResult = storeFallbackProperty(&l, qmlScopeObject, value); + } else { + QVariant var(propType); + propType.convert(type, value, propType, var.data()); + storeResult = storeFallbackProperty(&l, qmlScopeObject, var.data()); + } + break; + } + case ObjectLookupResult::Failure: + engine->handle()->throwTypeError(); + return; + } + + switch (storeResult) { + case ObjectPropertyResult::NeedsInit: engine->handle()->throwTypeError(); + break; + case ObjectPropertyResult::Deleted: + engine->handle()->throwTypeError( + QStringLiteral("Value is null and could not be converted to an object")); + break; + case ObjectPropertyResult::OK: + break; } } @@ -1079,19 +1262,52 @@ void AOTCompiledContext::initLoadGlobalLookup(uint index) const bool AOTCompiledContext::loadScopeObjectPropertyLookup(uint index, void *target) const { QV4::Lookup *l = compilationUnit->runtimeLookups + index; - if (l->qmlContextPropertyGetter != QV4::QQmlContextWrapper::lookupScopeObjectProperty) + + ObjectPropertyResult result = ObjectPropertyResult::NeedsInit; + if (l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupScopeObjectProperty) + result = loadObjectProperty(l, qmlScopeObject, target, qmlContext); + else if (l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupScopeFallbackProperty) + result = loadFallbackProperty(l, qmlScopeObject, target, qmlContext); + else + return false; + + switch (result) { + case ObjectPropertyResult::NeedsInit: return false; - return loadObjectProperty(l, qmlScopeObject, target, qmlContext); + case ObjectPropertyResult::Deleted: + engine->handle()->throwTypeError( + QStringLiteral("Cannot read property '%1' of null") + .arg(compilationUnit->runtimeStrings[l->nameIndex]->toQString())); + return false; + case ObjectPropertyResult::OK: + return true; + } + + Q_UNREACHABLE(); + return false; } void AOTCompiledContext::initLoadScopeObjectPropertyLookup(uint index, QMetaType type) const { - Q_ASSERT(!engine->hasError()); + QV4::ExecutionEngine *v4 = engine->handle(); QV4::Lookup *l = compilationUnit->runtimeLookups + index; - if (initObjectLookup(this, l, qmlScopeObject, type)) + + if (v4->hasException) { + amendException(v4); + return; + } + + switch (initObjectLookup(this, l, qmlScopeObject, type)) { + case ObjectLookupResult::Object: l->qmlContextPropertyGetter = QV4::QQmlContextWrapper::lookupScopeObjectProperty; - else - engine->handle()->throwTypeError(); + break; + case ObjectLookupResult::Fallback: + l->qmlContextPropertyGetter = QV4::QQmlContextWrapper::lookupScopeFallbackProperty; + break; + case ObjectLookupResult::Failure: + v4->throwTypeError(); + break; + } } bool AOTCompiledContext::loadTypeLookup(uint index, void *target) const @@ -1156,7 +1372,7 @@ void AOTCompiledContext::initLoadAttachedLookup(uint index, QObject *object) con QV4::Lookup *l = compilationUnit->runtimeLookups + index; QV4::Scope scope(engine->handle()); QV4::ScopedString name(scope, compilationUnit->runtimeStrings[l->nameIndex]); - QQmlTypeNameCache::Result r = qmlContext->imports()->query(name); + QQmlTypeNameCache::Result r = qmlContext->imports()->query(name); if (!r.isValid() || !r.type.isValid()) { scope.engine->throwTypeError(); @@ -1173,18 +1389,37 @@ void AOTCompiledContext::initLoadAttachedLookup(uint index, QObject *object) con bool AOTCompiledContext::getObjectLookup(uint index, QObject *object, void *target) const { + QV4::Lookup *l = compilationUnit->runtimeLookups + index; - if (!object) { + const auto doThrow = [&]() { engine->handle()->throwTypeError( QStringLiteral("Cannot read property '%1' of null") .arg(compilationUnit->runtimeStrings[l->nameIndex]->toQString())); return false; - } + }; + + if (!object) + return doThrow(); - if (l->getter != QV4::QObjectWrapper::lookupGetter) + ObjectPropertyResult result = ObjectPropertyResult::NeedsInit; + if (l->getter == QV4::Lookup::getterQObject) + result = loadObjectProperty(l, object, target, qmlContext); + else if (l->getter == QV4::Lookup::getterFallback) + result = loadFallbackProperty(l, object, target, qmlContext); + else return false; - return loadObjectProperty(l, object, target, qmlContext); + switch (result) { + case ObjectPropertyResult::Deleted: + return doThrow(); + case ObjectPropertyResult::NeedsInit: + return false; + case ObjectPropertyResult::OK: + return true; + } + + Q_UNREACHABLE(); + return false; } void AOTCompiledContext::initGetObjectLookup(uint index, QObject *object, QMetaType type) const @@ -1194,10 +1429,17 @@ void AOTCompiledContext::initGetObjectLookup(uint index, QObject *object, QMetaT amendException(v4); } else { QV4::Lookup *l = compilationUnit->runtimeLookups + index; - if (initObjectLookup(this, l, object, type)) - l->getter = QV4::QObjectWrapper::lookupGetter; - else + switch (initObjectLookup(this, l, object, type)) { + case ObjectLookupResult::Object: + l->getter = QV4::Lookup::getterQObject; + break; + case ObjectLookupResult::Fallback: + l->getter = QV4::Lookup::getterFallback; + break; + case ObjectLookupResult::Failure: engine->handle()->throwTypeError(); + break; + } } } @@ -1246,7 +1488,12 @@ void AOTCompiledContext::initGetEnumLookup( { Q_ASSERT(!engine->hasError()); QV4::Lookup *l = compilationUnit->runtimeLookups + index; - Q_ASSERT(metaObject); + if (!metaObject) { + engine->handle()->throwTypeError( + QStringLiteral("Cannot read property '%1' of undefined") + .arg(QString::fromUtf8(enumValue))); + return; + } const int enumIndex = metaObject->indexOfEnumerator(enumerator); const int value = metaObject->enumerator(enumIndex).keyToValue(enumValue); l->qmlEnumValueLookup.encodedEnumValue = value; @@ -1255,17 +1502,35 @@ void AOTCompiledContext::initGetEnumLookup( bool AOTCompiledContext::setObjectLookup(uint index, QObject *object, void *value) const { - if (!object) { + const auto doThrow = [&]() { engine->handle()->throwTypeError( QStringLiteral("Value is null and could not be converted to an object")); return false; - } + }; + + if (!object) + return doThrow(); QV4::Lookup *l = compilationUnit->runtimeLookups + index; - if (l->setter != QV4::QObjectWrapper::lookupSetter) + ObjectPropertyResult result = ObjectPropertyResult::NeedsInit; + if (l->setter == QV4::Lookup::setterQObject) + result = storeObjectProperty(l, object, value); + else if (l->setter == QV4::Lookup::setterFallback) + result = storeFallbackProperty(l, object, value); + else return false; - return storeObjectProperty(l, object, value); + switch (result) { + case ObjectPropertyResult::Deleted: + return doThrow(); + case ObjectPropertyResult::NeedsInit: + return false; + case ObjectPropertyResult::OK: + return true; + } + + Q_UNREACHABLE(); + return false; } void AOTCompiledContext::initSetObjectLookup(uint index, QObject *object, QMetaType type) const @@ -1275,10 +1540,17 @@ void AOTCompiledContext::initSetObjectLookup(uint index, QObject *object, QMetaT amendException(v4); } else { QV4::Lookup *l = compilationUnit->runtimeLookups + index; - if (initObjectLookup(this, l, object, type)) - l->setter = QV4::QObjectWrapper::lookupSetter; - else + switch (initObjectLookup(this, l, object, type)) { + case ObjectLookupResult::Object: + l->setter = QV4::Lookup::setterQObject; + break; + case ObjectLookupResult::Fallback: + l->setter = QV4::Lookup::setterFallback; + break; + case ObjectLookupResult::Failure: engine->handle()->throwTypeError(); + break; + } } } diff --git a/src/qml/qml/qqmlanybinding_p.h b/src/qml/qml/qqmlanybinding_p.h index c999b9dce7a..a83d4f3752c 100644 --- a/src/qml/qml/qqmlanybinding_p.h +++ b/src/qml/qml/qqmlanybinding_p.h @@ -147,6 +147,30 @@ class QQmlAnyBinding { return binding; } + /*! + \internal + Creates a binding for property \a prop from \a script. + \a obj is the scope object which shall be used for the function and \a ctxt its QML scope. + The binding is not installed on the property (but if a QQmlBinding is created, it has its + target set to \a prop). + */ + static QQmlAnyBinding createFromScriptString(const QQmlProperty &prop, const QQmlScriptString &script, + QObject *obj, QQmlContext *ctxt) + { + QQmlAnyBinding binding; + auto propPriv = QQmlPropertyPrivate::get(prop); + if (prop.isBindable()) { + auto index = QQmlPropertyIndex(propPriv->core.coreIndex(), -1); + binding = QQmlPropertyBinding::createFromScriptString(&propPriv->core, script, obj, ctxt, prop.object(), index); + } else { + auto qmlBinding = QQmlBinding::create(&propPriv->core, script, obj, ctxt); + qmlBinding->setTarget(prop); + binding = qmlBinding; + } + return binding; + } + + /*! \internal Removes the binding from \a prop if there is any. diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index e0ab25892f9..83323a7087a 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -73,7 +73,9 @@ void QQmlApplicationEnginePrivate::init() &QCoreApplication::quit, Qt::QueuedConnection); q->connect(q, &QQmlApplicationEngine::exit, QCoreApplication::instance(), &QCoreApplication::exit, Qt::QueuedConnection); - q->connect(q, SIGNAL(uiLanguageChanged()), q_func(), SLOT(_q_loadTranslations())); + QObject::connect(q, &QJSEngine::uiLanguageChanged, q, [this](){ + _q_loadTranslations(); + }); #if QT_CONFIG(translation) QTranslator* qtTranslator = new QTranslator(q); if (qtTranslator->load(QLocale(), QLatin1String("qt"), QLatin1String("_"), QLibraryInfo::path(QLibraryInfo::TranslationsPath), QLatin1String(".qm"))) @@ -89,11 +91,10 @@ void QQmlApplicationEnginePrivate::init() void QQmlApplicationEnginePrivate::_q_loadTranslations() { #if QT_CONFIG(translation) + Q_Q(QQmlApplicationEngine); if (translationsDirectory.isEmpty()) return; - Q_Q(QQmlApplicationEngine); - QScopedPointer translator(new QTranslator); if (!uiLanguage.value().isEmpty()) { QLocale locale(uiLanguage); diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 788d03b8e21..0b5081d491d 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -259,15 +259,24 @@ class QQmlNonbindingBinding: public QQmlBinding const QV4::Function *v4Function = function(); if (v4Function && v4Function->aotFunction && !hasBoundFunction()) { const auto returnType = v4Function->aotFunction->returnType; - const auto size = returnType.sizeOf(); - if (Q_LIKELY(size > 0)) { - Q_ALLOCA_VAR(void, result, size); + if (returnType == QMetaType::fromType()) { + // It expects uninitialized memory + Q_ALLOCA_VAR(QVariant, result, sizeof(QVariant)); const bool isUndefined = !evaluate(result, returnType); if (canWrite()) - error = !write(result, returnType, isUndefined, flags); - returnType.destruct(result); - } else if (canWrite()) { - error = !write(QV4::Encode::undefined(), true, flags); + error = !write(result->data(), result->metaType(), isUndefined, flags); + result->~QVariant(); + } else { + const auto size = returnType.sizeOf(); + if (Q_LIKELY(size > 0)) { + Q_ALLOCA_VAR(void, result, size); + const bool isUndefined = !evaluate(result, returnType); + if (canWrite()) + error = !write(result, returnType, isUndefined, flags); + returnType.destruct(result); + } else if (canWrite()) { + error = !write(QV4::Encode::undefined(), true, flags); + } } } else { bool isUndefined = false; @@ -385,19 +394,26 @@ class GenericBinding: public QQmlNonbindingBinding } }; -class QQmlTranslationBinding : public GenericBinding { +class QQmlTranslationBinding : public GenericBinding, public QPropertyObserver { public: QQmlTranslationBinding(const QQmlRefPointer &compilationUnit, const QV4::CompiledData::Binding *binding) + : QPropertyObserver(&QQmlTranslationBinding::onLanguageChange) { setCompilationUnit(compilationUnit); m_binding = binding; + setSource(QQmlEnginePrivate::get(compilationUnit->engine)->translationLanguage); } QQmlSourceLocation sourceLocation() const override final { - return QQmlSourceLocation(m_compilationUnit->fileName(), m_binding->valueLocation.line, m_binding->valueLocation.column); + return QQmlSourceLocation( + m_compilationUnit->fileName(), m_binding->valueLocation.line(), + m_binding->valueLocation.column()); } + static void onLanguageChange(QPropertyObserver *observer, QUntypedPropertyData *) + { static_cast(observer)->update(); } + void doUpdate(const DeleteWatcher &watcher, QQmlPropertyData::WriteFlags flags, QV4::Scope &scope) override final { @@ -439,7 +455,7 @@ QQmlBinding *QQmlBinding::createTranslationBinding( b->setNotifyOnValueChanged(true); b->QQmlJavaScriptExpression::setContext(ctxt); b->setScopeObject(obj); -#if QT_CONFIG(translation) +#if QT_CONFIG(translation) && QT_CONFIG(qml_debug) if (QQmlDebugTranslationService *service = QQmlDebugConnector::service()) { service->foundTranslationBinding({unit, binding, b->scopeObject(), ctxt}); @@ -519,8 +535,12 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core, value = v4engine->toVariant(result, QMetaType::fromType >()); } else if (result.isNull() && core.isQObject()) { value = QVariant::fromValue((QObject *)nullptr); - } else if (core.propType().id() == qMetaTypeId >()) { - value = QQmlPropertyPrivate::urlSequence(v4engine->toVariant(result, QMetaType::fromType>())); + } else if (core.propType() == QMetaType::fromType>()) { + const QVariant resultVariant + = v4engine->toVariant(result, QMetaType::fromType>()); + value = QVariant::fromValue(QQmlPropertyPrivate::resolveUrlsOnAssignment() + ? QQmlPropertyPrivate::urlSequence(resultVariant, context()) + : QQmlPropertyPrivate::urlSequence(resultVariant)); } else if (!isVarProperty && metaType != QMetaType::fromType()) { value = v4engine->toVariant(result, metaType); } @@ -671,14 +691,34 @@ bool QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core, const valueType ? valueType->coreIndex() : -1); } -bool QQmlBinding::setTarget(QObject *object, int coreIndex, bool coreIsAlias, int valueTypeIndex) +static const QQmlPropertyData *getObjectPropertyData(QObject *object, int coreIndex) { - m_target = object; + QQmlData *data = QQmlData::get(object, true); + if (!data) + return nullptr; + if (!data->propertyCache) { + data->propertyCache = QQmlMetaType::propertyCache(object->metaObject()); + if (!data->propertyCache) + return nullptr; + data->propertyCache->addref(); + } + const QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex); + Q_ASSERT(propertyData); + return propertyData; +} - if (!object) { +bool QQmlBinding::setTarget(QObject *object, int coreIndex, bool coreIsAlias, int valueTypeIndex) +{ + auto invalidate = [this]() { + m_target = nullptr; m_targetIndex = QQmlPropertyIndex(); return false; - } + }; + + if (!object) + return invalidate(); + + m_target = object; for (bool isAlias = coreIsAlias; isAlias;) { QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex); @@ -686,21 +726,25 @@ bool QQmlBinding::setTarget(QObject *object, int coreIndex, bool coreIsAlias, in int aValueTypeIndex; if (!vme->aliasTarget(coreIndex, &object, &coreIndex, &aValueTypeIndex)) { // can't resolve id (yet) - m_target = nullptr; - m_targetIndex = QQmlPropertyIndex(); - return false; + return invalidate(); } - if (valueTypeIndex == -1) - valueTypeIndex = aValueTypeIndex; - QQmlData *data = QQmlData::get(object, false); - if (!data || !data->propertyCache) { - m_target = nullptr; - m_targetIndex = QQmlPropertyIndex(); - return false; + const QQmlPropertyData *propertyData = getObjectPropertyData(object, coreIndex); + if (!propertyData) + return invalidate(); + if (aValueTypeIndex != -1) { + if (propertyData->propType().flags().testFlag(QMetaType::PointerToQObject)) { + // deep alias + propertyData->readProperty(object, &object); + coreIndex = aValueTypeIndex; + valueTypeIndex = -1; + propertyData = getObjectPropertyData(object, coreIndex); + if (!propertyData) + return invalidate(); + } else { + valueTypeIndex = aValueTypeIndex; + } } - QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex); - Q_ASSERT(propertyData); m_target = object; isAlias = propertyData->isAlias(); @@ -763,17 +807,23 @@ QVector QQmlBinding::dependencies() const for (int i = 0; i < senderMeta->propertyCount(); i++) { QMetaProperty property = senderMeta->property(i); if (property.notifySignalIndex() == QMetaObjectPrivate::signal(senderMeta, guard->signalIndex()).methodIndex()) { - dependencies.push_back(QQmlProperty(senderObject, QString::fromUtf8(senderObject->metaObject()->property(i).name()))); + dependencies.push_back(QQmlProperty(senderObject, QString::fromUtf8(property.name()))); } } } + for (auto trigger = qpropertyChangeTriggers; trigger; trigger = trigger->next) { + QMetaProperty prop = trigger->property(); + if (prop.isValid()) + dependencies.push_back(QQmlProperty(trigger->target, QString::fromUtf8(prop.name()))); + } + return dependencies; } bool QQmlBinding::hasDependencies() const { - return !activeGuards.isEmpty() || translationsCaptured() || qpropertyChangeTriggers; + return !activeGuards.isEmpty() || qpropertyChangeTriggers; } class QObjectPointerBinding: public QQmlNonbindingBinding diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index 4e824fff034..fc7f6f5fb31 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -97,6 +97,8 @@ class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlJavaScriptExpression, ~QQmlBinding() override; + bool mustCaptureBindableProperty() const final {return true;} + void setTarget(const QQmlProperty &); bool setTarget(QObject *, const QQmlPropertyData &, const QQmlPropertyData *valueType); bool setTarget(QObject *, int coreIndex, bool coreIsAlias, int valueTypeIndex); @@ -113,6 +115,10 @@ class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlJavaScriptExpression, }; QVariant evaluate(); + bool evaluate(void *result, QMetaType type) + { + return QQmlJavaScriptExpression::evaluate(&result, &type, 0); + } void expressionChanged() override; @@ -131,6 +137,7 @@ class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlJavaScriptExpression, * Call this method from the UI thread. */ QVector dependencies() const; + // This method is used internally to check whether a binding is constant and can be removed virtual bool hasDependencies() const; protected: @@ -147,10 +154,6 @@ class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlJavaScriptExpression, QQmlPropertyData::WriteFlags flags); QV4::ReturnedValue evaluate(bool *isUndefined); - bool evaluate(void *result, QMetaType type) - { - return QQmlJavaScriptExpression::evaluate(&result, &type, 0); - } private: inline bool updatingFlag() const; diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 665d4e6c75a..13ed3cf95bf 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -114,12 +114,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(const QObject *target, int QV4::ExecutionEngine *engine = ctxt->engine()->handle(); - // If the function is marked as having a nested function, then the user wrote: - // onSomeSignal: function() { /*....*/ } - // So take that nested function: - if (auto closure = function->nestedFunction()) { - function = closure; - } else { + if (!function->isClosureWrapper()) { QList signalParameters = QMetaObjectPrivate::signal(m_target->metaObject(), m_index).parameterNames(); if (!signalParameters.isEmpty()) { QString error; @@ -136,7 +131,29 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(const QObject *target, int QV4::Scoped qmlContext(valueScope, scope); if (!qmlContext) qmlContext = QV4::QmlContext::create(engine->rootContext(), ctxt, scopeObject); - setupFunction(qmlContext, function); + if (auto closure = function->nestedFunction()) { + // If the function is marked as having a nested function, then the user wrote: + // onSomeSignal: function() { /*....*/ } + // So take that nested function: + setupFunction(qmlContext, closure); + } else { + setupFunction(qmlContext, function); + + // If it's a closure wrapper but we cannot directly access the nested function + // we need to run the outer function to get the nested one. + if (function->isClosureWrapper()) { + bool isUndefined = false; + QV4::ScopedFunctionObject result( + valueScope, QQmlJavaScriptExpression::evaluate(&isUndefined)); + + Q_ASSERT(!isUndefined); + Q_ASSERT(result->function()); + Q_ASSERT(result->function()->compilationUnit == function->compilationUnit); + + QV4::Scoped callContext(valueScope, result->scope()); + setupFunction(callContext, result->function()); + } + } } void QQmlBoundSignalExpression::init(const QQmlRefPointer &ctxt, QObject *scope) diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h index 0a3229b7319..89635dec69b 100644 --- a/src/qml/qml/qqmlboundsignal_p.h +++ b/src/qml/qml/qqmlboundsignal_p.h @@ -80,6 +80,8 @@ class Q_QML_PRIVATE_EXPORT QQmlBoundSignalExpression : public QQmlJavaScriptExpr // evaluation of a bound signal expression doesn't return any value void evaluate(void **a); + bool mustCaptureBindableProperty() const final {return true;} + QString expression() const; const QObject *target() const { return m_target; } diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 64698444ff0..6261e8b5101 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -159,11 +159,12 @@ V4_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension); { // ... component = new QQmlComponent(engine, QUrl("http://www.example.com/main.qml")); - if (component->isLoading()) - QObject::connect(component, SIGNAL(statusChanged(QQmlComponent::Status)), - this, SLOT(continueLoading())); - else + if (component->isLoading()) { + QObject::connect(component, &QQmlComponent::statusChanged, + this, &MyApplication::continueLoading); + } else { continueLoading(); + } } void MyApplication::continueLoading() @@ -304,7 +305,7 @@ V4_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension); Specifies whether the QQmlComponent should load the component immediately, or asynchonously. \value PreferSynchronous Prefer loading/compiling the component immediately, blocking the thread. - This is not always possible; for example, remote URLs will always load asynchronously. + This is not always possible; for example, remote URLs will always load asynchronously. \value Asynchronous Load/compile the component in a background thread. */ @@ -344,6 +345,7 @@ void QQmlComponentPrivate::fromTypeData(const QQmlRefPointer &data RequiredProperties &QQmlComponentPrivate::requiredProperties() { + Q_ASSERT(state.creator); return state.creator->requiredProperties(); } @@ -379,7 +381,12 @@ bool QQmlComponentPrivate::setInitialProperty(QObject *component, const QString& QQmlProperty prop = QQmlComponentPrivate::removePropertyFromRequired(component, name, requiredProperties()); QQmlPropertyPrivate *privProp = QQmlPropertyPrivate::get(prop); const bool isValid = prop.isValid(); - if (!isValid || !privProp->writeValueProperty(value, {})) { + if (isValid && privProp->writeValueProperty(value, {})) { + if (prop.isBindable()) { + if (QQmlObjectCreator *creator = state.creator.data()) + creator->removePendingBinding(prop.object(), prop.index()); + } + } else { QQmlError error{}; error.setUrl(url); if (isValid) @@ -389,8 +396,9 @@ bool QQmlComponentPrivate::setInitialProperty(QObject *component, const QString& QQmlMetaType::prettyTypeName(component))); state.errors.push_back(error); return false; - } else - return true; + } + + return true; } /*! @@ -417,7 +425,9 @@ QQmlComponent::~QQmlComponent() qWarning().nospace().noquote() << QLatin1String(" ") << error; } - d->completeCreate(); + // we might not have the creator anymore if the engine is gone + if (d->state.creator) + d->completeCreate(); } if (d->typeData) { @@ -428,15 +438,15 @@ QQmlComponent::~QQmlComponent() /*! \qmlproperty enumeration Component::status + This property holds the status of component loading. The status can be one of the following: - \list - \li Component.Null - no data is available for the component - \li Component.Ready - the component has been loaded, and can be used to create instances. - \li Component.Loading - the component is currently being loaded - \li Component.Error - an error occurred while loading the component. - Calling errorString() will provide a human-readable description of any errors. - \endlist + + \value Component.Null no data is available for the component + \value Component.Ready the component has been loaded, and can be used to create instances. + \value Component.Loading the component is currently being loaded + \value Component.Error an error occurred while loading the component. + Calling \l errorString() will provide a human-readable description of any errors. */ /*! @@ -766,7 +776,7 @@ QList QQmlComponent::errors() const /*! \internal - errorString is only meant as a way to get the errors in script + errorString() is only meant as a way to get the errors from QML side. */ QString QQmlComponent::errorString() const { @@ -807,9 +817,8 @@ QQmlComponent::QQmlComponent(QQmlComponentPrivate &dd, QObject *parent) } /*! - Create an object instance from this component. Returns \nullptr if creation - failed. \a context specifies the context within which to create the object - instance. + Create an object instance from this component, within the specified \a context. + Returns \nullptr if creation failed. If \a context is \nullptr (the default), it will create the instance in the \l {QQmlEngine::rootContext()}{root context} of the engine. @@ -828,8 +837,16 @@ QObject *QQmlComponent::create(QQmlContext *context) Q_D(QQmlComponent); QObject *rv = d->doBeginCreate(this, context); - if (rv) + if (rv) { completeCreate(); + } else if (d->state.completePending) { + // overridden completCreate might assume that + // the object has actually been created + ++creationDepth.localData(); + QQmlEnginePrivate *ep = QQmlEnginePrivate::get(d->engine); + d->complete(ep, &d->state); + --creationDepth.localData(); + } if (rv && !d->requiredProperties().empty()) { delete rv; return nullptr; @@ -838,9 +855,8 @@ QObject *QQmlComponent::create(QQmlContext *context) } /*! - Create an object instance of this component, and initialize its toplevel - properties with \a initialProperties. \a context specifies the context - where the object instance is to be created. + Create an object instance of this component, within the specified \a context, + and initialize its top-level properties with \a initialProperties. \omit TODO: also mention errorString() when QTBUG-93239 is fixed @@ -870,20 +886,21 @@ QObject *QQmlComponent::createWithInitialProperties(const QVariantMap& initialPr } /*! - This method provides advanced control over component instance creation. + Create an object instance from this component, within the specified \a context. + Returns \nullptr if creation failed. + + \note This method provides advanced control over component instance creation. In general, programmers should use QQmlComponent::create() to create object instances. - Create an object instance from this component. Returns \nullptr if creation - failed. \a publicContext specifies the context within which to create the object - instance. - When QQmlComponent constructs an instance, it occurs in three steps: + \list 1 \li The object hierarchy is created, and constant values are assigned. \li Property bindings are evaluated for the first time. \li If applicable, QQmlParserStatus::componentComplete() is called on objects. \endlist + QQmlComponent::beginCreate() differs from QQmlComponent::create() in that it only performs step 1. QQmlComponent::completeCreate() must be called to complete steps 2 and 3. @@ -896,20 +913,21 @@ QObject *QQmlComponent::createWithInitialProperties(const QVariantMap& initialPr \sa completeCreate(), QQmlEngine::ObjectOwnership */ -QObject *QQmlComponent::beginCreate(QQmlContext *publicContext) +QObject *QQmlComponent::beginCreate(QQmlContext *context) { Q_D(QQmlComponent); - Q_ASSERT(publicContext); - return d->beginCreate(QQmlContextData::get(publicContext)); + Q_ASSERT(context); + return d->beginCreate(QQmlContextData::get(context)); } QObject *QQmlComponentPrivate::beginCreate(QQmlRefPointer context) { Q_Q(QQmlComponent); auto cleanup = qScopeGuard([this] { - if (!state.errors.isEmpty()) { - for (const auto &e : qAsConst(state.errors)) + if (!state.errors.isEmpty() && lcQmlComponentGeneral().isDebugEnabled()) { + for (const auto &e : qAsConst(state.errors)) { qCDebug(lcQmlComponentGeneral) << "QQmlComponent: " << e.toString(); + } } }); if (!context) { @@ -961,8 +979,8 @@ QObject *QQmlComponentPrivate::beginCreate(QQmlRefPointer conte if (rv) { QQmlData *ddata = QQmlData::get(rv); Q_ASSERT(ddata); - //top level objects should never get JS ownership. - //if JS ownership is needed this needs to be explicitly undone (like in component.createObject()) + // top-level objects should never get JS ownership. + // if JS ownership is needed this needs to be explicitly undone (like in createObject()) ddata->indestructible = true; ddata->explicitIndestructibleSet = true; ddata->rootObjectInCreation = false; @@ -1022,20 +1040,20 @@ void QQmlComponentPrivate::complete(QQmlEnginePrivate *enginePriv, ConstructionS } /*! - * \internal - * Finds the matching toplevel property with name \a name of the component \a createdComponent. - * If it was a required property or an alias to a required property contained in \a - * requiredProperties, it is removed from it. - * - * If wasInRequiredProperties is non-null, the referenced boolean is set to true iff the property - * was found in requiredProperties. - * - * Returns the QQmlProperty with name \a name (which might be invalid if there is no such property), - * for further processing (for instance, actually setting the property value). - * - * Note: This method is used in QQmlComponent and QQmlIncubator to manage required properties. Most - * classes which create components should not need it and should only need to call - * setInitialProperties. + \internal + Finds the matching top-level property with name \a name of the component \a createdComponent. + If it was a required property or an alias to a required property contained in \a + requiredProperties, it is removed from it. + + If wasInRequiredProperties is non-null, the referenced boolean is set to true iff the property + was found in requiredProperties. + + Returns the QQmlProperty with name \a name (which might be invalid if there is no such property), + for further processing (for instance, actually setting the property value). + + Note: This method is used in QQmlComponent and QQmlIncubator to manage required properties. Most + classes which create components should not need it and should only need to call + setInitialProperties. */ QQmlProperty QQmlComponentPrivate::removePropertyFromRequired(QObject *createdComponent, const QString &name, RequiredProperties &requiredProperties, bool* wasInRequiredProperties) { @@ -1146,14 +1164,14 @@ QQmlComponentAttached *QQmlComponent::qmlAttachedProperties(QObject *obj) \a incubator. \a context specifies the context within which to create the object instance. - If \a context is 0 (the default), it will create the instance in the + If \a context is \nullptr (by default), it will create the instance in the engine's \l {QQmlEngine::rootContext()}{root context}. \a forContext specifies a context that this object creation depends upon. If the \a forContext is being created asynchronously, and the \l QQmlIncubator::IncubationMode is \l QQmlIncubator::AsynchronousIfNested, - this object will also be created asynchronously. If \a forContext is 0 - (the default), the \a context will be used for this decision. + this object will also be created asynchronously. + If \a forContext is \nullptr (by default), the \a context will be used for this decision. The created object and its creation status are available via the \a incubator. @@ -1201,8 +1219,7 @@ void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context, QQmlC } /*! - Set toplevel \a properties of the \a component. - + Set top-level \a properties of the \a component. This method provides advanced control over component instance creation. In general, programmers should use @@ -1339,7 +1356,7 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent) } /*! - \qmlmethod object Component::createObject(QtObject parent, object properties) + \qmlmethod QtObject Component::createObject(QtObject parent, object properties) Creates and returns an object instance of this component that will have the given \a parent and \a properties. The \a properties argument is optional. @@ -1368,9 +1385,10 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent) below creates an object with initial \c x and \c y values of 100 and 100, respectively: \js - var component = Qt.createComponent("Button.qml"); - if (component.status == Component.Ready) - component.createObject(parent, {x: 100, y: 100}); + const component = Qt.createComponent("Button.qml"); + if (component.status === Component.Ready) { + component.createObject(parent, { x: 100, y: 100 }); + } \endjs Dynamically created instances can be deleted with the \c destroy() method. @@ -1380,7 +1398,10 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent) */ -void QQmlComponentPrivate::setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v, RequiredProperties &requiredProperties, QObject *createdComponent) +void QQmlComponentPrivate::setInitialProperties( + QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, + const QV4::Value &v, RequiredProperties &requiredProperties, QObject *createdComponent, + QQmlObjectCreator *creator) { QV4::Scope scope(engine); QV4::ScopedObject object(scope); @@ -1408,11 +1429,20 @@ void QQmlComponentPrivate::setInitialProperties(QV4::ExecutionEngine *engine, QV break; } } - if (engine->hasException || !object) { + if (engine->hasException) { qmlWarning(createdComponent, engine->catchExceptionAsQmlError()); continue; } - name = engine->newString(properties.last()); + if (!object) { + QQmlError error; + error.setUrl(qmlContext ? qmlContext->qmlContext()->url() : QUrl()); + error.setDescription(QLatin1String("Cannot resolve property \"%1\".") + .arg(properties.join(u'.'))); + qmlWarning(createdComponent, error); + continue; + } + const QString lastProperty = properties.last(); + name = engine->newString(lastProperty); object->put(name, val); if (engine->hasException) { qmlWarning(createdComponent, engine->catchExceptionAsQmlError()); @@ -1420,6 +1450,26 @@ void QQmlComponentPrivate::setInitialProperties(QV4::ExecutionEngine *engine, QV } else if (isTopLevelProperty) { auto prop = removePropertyFromRequired(createdComponent, name->toQString(), requiredProperties); } + if (!creator) + continue; + + if (QV4::QObjectWrapper *wrapper = object->as()) { + if (QObject *o = wrapper->object()) { + if (QQmlData *ddata = QQmlData::get(o)) { + if (const QQmlPropertyData *propData = ddata->propertyCache->property( + lastProperty, o, ddata->outerContext)) { + if (propData->isBindable()) + creator->removePendingBinding(o, propData->coreIndex()); + } + } else { + const QMetaObject *meta = o->metaObject(); + Q_ASSERT(meta); + const int index = meta->indexOfProperty(lastProperty.toUtf8()); + if (index != -1 && meta->property(index).isBindable()) + creator->removePendingBinding(o, index); + } + } + } } engine->hasException = false; @@ -1446,8 +1496,10 @@ QQmlError QQmlComponentPrivate::unsetRequiredPropertyToQQmlError(const RequiredP } error.setDescription(description); error.setUrl(unsetRequiredProperty.fileUrl); - error.setLine(qmlConvertSourceCoordinate(unsetRequiredProperty.location.line)); - error.setColumn(qmlConvertSourceCoordinate(unsetRequiredProperty.location.column)); + error.setLine(qmlConvertSourceCoordinate( + unsetRequiredProperty.location.line())); + error.setColumn(qmlConvertSourceCoordinate( + unsetRequiredProperty.location.column())); return error; } @@ -1498,7 +1550,8 @@ void QQmlComponent::createObject(QQmlV4Function *args) if (!valuemap->isUndefined()) { QV4::Scoped qmlContext(scope, v4->qmlContext()); - QQmlComponentPrivate::setInitialProperties(v4, qmlContext, object, valuemap, d->requiredProperties(), rv); + QQmlComponentPrivate::setInitialProperties( + v4, qmlContext, object, valuemap, d->requiredProperties(), rv, d->state.creator.data()); } if (!d->requiredProperties().empty()) { QList errors; @@ -1521,7 +1574,7 @@ void QQmlComponent::createObject(QQmlV4Function *args) } /*! - \qmlmethod object Component::incubateObject(Item parent, object properties, enumeration mode) + \qmlmethod object Component::incubateObject(QtObject parent, object properties, enumeration mode) Creates an incubator for an instance of this component. Incubators allow new component instances to be instantiated asynchronously and do not cause freezes in the UI. @@ -1543,29 +1596,29 @@ void QQmlComponent::createObject(QQmlV4Function *args) properties: \list - \li status The status of the incubator. Valid values are Component.Ready, Component.Loading and + \li \c status - The status of the incubator. Valid values are Component.Ready, Component.Loading and Component.Error. - \li object The created object instance. Will only be available once the incubator is in the + \li \c object - The created object instance. Will only be available once the incubator is in the Ready status. - \li onStatusChanged Specifies a callback function to be invoked when the status changes. The + \li \c onStatusChanged - Specifies a callback function to be invoked when the status changes. The status is passed as a parameter to the callback. - \li forceCompletion() Call to complete incubation synchronously. + \li \c{forceCompletion()} - Call to complete incubation synchronously. \endlist The following example demonstrates how to use an incubator: \js - var component = Qt.createComponent("Button.qml"); + const component = Qt.createComponent("Button.qml"); - var incubator = component.incubateObject(parent, { x: 10, y: 10 }); - if (incubator.status != Component.Ready) { + const incubator = component.incubateObject(parent, { x: 10, y: 10 }); + if (incubator.status !== Component.Ready) { incubator.onStatusChanged = function(status) { - if (status == Component.Ready) { - print ("Object", incubator.object, "is now ready!"); + if (status === Component.Ready) { + print("Object", incubator.object, "is now ready!"); } - } + }; } else { - print ("Object", incubator.object, "is ready immediately!"); + print("Object", incubator.object, "is ready immediately!"); } \endjs @@ -1648,8 +1701,11 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(QV4::QmlContext QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4engine, toCreate)); Q_ASSERT(object->as()); - if (!valuemap.isUndefined()) - setInitialProperties(v4engine, qmlContext, object, valuemap, requiredProperties, toCreate); + if (!valuemap.isUndefined()) { + setInitialProperties( + v4engine, qmlContext, object, valuemap, requiredProperties, + toCreate, state.creator.data()); + } } QQmlComponentExtension::QQmlComponentExtension(QV4::ExecutionEngine *v4) @@ -1748,7 +1804,9 @@ void QV4::QmlIncubatorObject::setInitialState(QObject *o, RequiredProperties &re QV4::Scope scope(v4); QV4::ScopedObject obj(scope, QV4::QObjectWrapper::wrap(v4, o)); QV4::Scoped qmlCtxt(scope, d()->qmlContext); - QQmlComponentPrivate::setInitialProperties(v4, qmlCtxt, obj, d()->valuemap, requiredProperties, o); + QQmlComponentPrivate::setInitialProperties( + v4, qmlCtxt, obj, d()->valuemap, requiredProperties, o, + QQmlIncubatorPrivate::get(d()->incubator)->creator.data()); } } @@ -1785,3 +1843,4 @@ void QV4::QmlIncubatorObject::statusChanged(QQmlIncubator::Status s) QT_END_NAMESPACE #include "moc_qqmlcomponent.cpp" +#include "moc_qqmlcomponentattached_p.cpp" diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index abc0de7438b..85acf2705dc 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -87,7 +87,10 @@ class Q_QML_PRIVATE_EXPORT QQmlComponentPrivate : public QObjectPrivate, public QObject *beginCreate(QQmlRefPointer); void completeCreate(); void initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate, RequiredProperties &requiredProperties); - static void setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v, RequiredProperties &requiredProperties, QObject *createdComponent); + static void setInitialProperties( + QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, + const QV4::Value &v, RequiredProperties &requiredProperties, QObject *createdComponent, + QQmlObjectCreator *creator); static QQmlError unsetRequiredPropertyToQQmlError(const RequiredPropertyInfo &unsetRequiredProperty); virtual void incubateObject( diff --git a/src/qml/qml/qqmlcomponentattached_p.h b/src/qml/qml/qqmlcomponentattached_p.h index b94d474d1f1..2e63289c2d6 100644 --- a/src/qml/qml/qqmlcomponentattached_p.h +++ b/src/qml/qml/qqmlcomponentattached_p.h @@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE +// implemented in qqmlcomponent.cpp class Q_QML_PRIVATE_EXPORT QQmlComponentAttached : public QObject { Q_OBJECT diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp index b6b90f13dc5..5821aca595e 100644 --- a/src/qml/qml/qqmlcontext.cpp +++ b/src/qml/qml/qqmlcontext.cpp @@ -76,11 +76,11 @@ QT_BEGIN_NAMESPACE context->setContextProperty("myModel", &modelData); QQmlComponent component(&engine); - component.setData("import QtQuick 2.0\nListView { model: myModel }", QUrl()); + component.setData("import QtQuick 2.0; ListView { model: myModel }", QUrl()); QObject *window = component.create(context); \endcode - Note it is the responsibility of the creator to delete any QQmlContext it + \note It is the responsibility of the creator to delete any QQmlContext it constructs. If the \c context object in the example is no longer needed when the \c window component instance is destroyed, the \c context must be destroyed explicitly. The simplest way to ensure this is to set \c window as the parent of \c context. @@ -96,10 +96,10 @@ QT_BEGIN_NAMESPACE object. \code - class MyDataSet : ... { - ... + class MyDataSet : public QObject { + // ... Q_PROPERTY(QAbstractItemModel *myModel READ model NOTIFY modelChanged) - ... + // ... }; MyDataSet myDataSet; @@ -108,7 +108,7 @@ QT_BEGIN_NAMESPACE context->setContextObject(&myDataSet); QQmlComponent component(&engine); - component.setData("import QtQuick 2.0\nListView { model: myModel }", QUrl()); + component.setData("import QtQuick 2.0; ListView { model: myModel }", QUrl()); component.create(context); \endcode @@ -132,10 +132,10 @@ QT_BEGIN_NAMESPACE QQmlContext *context1 = new QQmlContext(engine.rootContext()); QQmlContext *context2 = new QQmlContext(context1); - context1->setContextProperty("a", 12); - context1->setContextProperty("b", 12); + context1->setContextProperty("a", 9001); + context1->setContextProperty("b", 9001); - context2->setContextProperty("b", 15); + context2->setContextProperty("b", 42); \endcode While QML objects instantiated in a context are not strictly owned by that @@ -212,7 +212,7 @@ bool QQmlContext::isValid() const } /*! - Return the context's QQmlEngine, or 0 if the context has no QQmlEngine or the + Return the context's QQmlEngine, or \nullptr if the context has no QQmlEngine or the QQmlEngine was destroyed. */ QQmlEngine *QQmlContext::engine() const @@ -222,7 +222,7 @@ QQmlEngine *QQmlContext::engine() const } /*! - Return the context's parent QQmlContext, or 0 if this context has no + Return the context's parent QQmlContext, or \nullptr if this context has no parent or if the parent has been destroyed. */ QQmlContext *QQmlContext::parentContext() const @@ -235,7 +235,7 @@ QQmlContext *QQmlContext::parentContext() const } /*! - Return the context object, or 0 if there is no context object. + Return the context object, or \nullptr if there is no context object. */ QObject *QQmlContext::contextObject() const { diff --git a/src/qml/qml/qqmlcontext.h b/src/qml/qml/qqmlcontext.h index 82d15b8102d..2da9541e5a3 100644 --- a/src/qml/qml/qqmlcontext.h +++ b/src/qml/qml/qqmlcontext.h @@ -108,6 +108,4 @@ class Q_QML_EXPORT QQmlContext : public QObject }; QT_END_NAMESPACE -Q_DECLARE_METATYPE(QList) - #endif // QQMLCONTEXT_H diff --git a/src/qml/qml/qqmlcontextdata.cpp b/src/qml/qml/qqmlcontextdata.cpp index f7decc2992e..c07d52e2a3c 100644 --- a/src/qml/qml/qqmlcontextdata.cpp +++ b/src/qml/qml/qqmlcontextdata.cpp @@ -173,7 +173,7 @@ QQmlContextData::~QQmlContextData() QQmlGuardedContextData *contextGuard = m_contextGuards; while (contextGuard) { QQmlGuardedContextData *next = contextGuard->next(); - next->reset(); + contextGuard->reset(); contextGuard = next; } m_contextGuards = nullptr; diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp index b0df4f26dcf..62bcaa41c6c 100644 --- a/src/qml/qml/qqmlcustomparser.cpp +++ b/src/qml/qml/qqmlcustomparser.cpp @@ -102,8 +102,8 @@ void QQmlCustomParser::clearErrors() void QQmlCustomParser::error(const QV4::CompiledData::Location &location, const QString &description) { QQmlError error; - error.setLine(qmlConvertSourceCoordinate(location.line)); - error.setColumn(qmlConvertSourceCoordinate(location.column)); + error.setLine(qmlConvertSourceCoordinate(location.line())); + error.setColumn(qmlConvertSourceCoordinate(location.column())); error.setDescription(description); exceptions << error; diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index ff55ab49d43..87d61f58398 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -155,24 +155,24 @@ class Q_QML_PRIVATE_EXPORT QQmlData : public QAbstractDeclarativeData }; struct NotifyList { - quint64 connectionMask; - - quint16 maximumTodoIndex; - quint16 notifiesSize; - - QQmlNotifierEndpoint *todo; - QQmlNotifierEndpoint**notifies; + QAtomicInteger connectionMask; + QQmlNotifierEndpoint *todo = nullptr; + QQmlNotifierEndpoint**notifies = nullptr; + quint16 maximumTodoIndex = 0; + quint16 notifiesSize = 0; void layout(); private: void layout(QQmlNotifierEndpoint*); }; - NotifyList *notifyList; + QAtomicPointer notifyList; - inline QQmlNotifierEndpoint *notify(int index); + inline QQmlNotifierEndpoint *notify(int index) const; void addNotify(int index, QQmlNotifierEndpoint *); int endpointCount(int index); bool signalHasEndpoint(int index) const; - void disconnectNotifiers(); + + enum class DeleteNotifyList { Yes, No }; + void disconnectNotifiers(DeleteNotifyList doDelete); // The context that created the C++ object; not refcounted to prevent cycles QQmlContextData *context = nullptr; @@ -258,7 +258,8 @@ class Q_QML_PRIVATE_EXPORT QQmlData : public QAbstractDeclarativeData static void markAsDeleted(QObject *); static void setQueuedForDeletion(QObject *); - static inline void flushPendingBinding(QObject *, QQmlPropertyIndex propertyIndex); + static inline void flushPendingBinding(QObject *object, int coreIndex); + void flushPendingBinding(int coreIndex); static QQmlPropertyCache *ensurePropertyCache(QJSEngine *engine, QObject *object) { @@ -279,8 +280,6 @@ class Q_QML_PRIVATE_EXPORT QQmlData : public QAbstractDeclarativeData Q_NEVER_INLINE static QQmlData *createQQmlData(QObjectPrivate *priv); Q_NEVER_INLINE static QQmlPropertyCache *createPropertyCache(QJSEngine *engine, QObject *object); - void flushPendingBindingImpl(QQmlPropertyIndex index); - Q_ALWAYS_INLINE bool hasBitSet(int bit) const { uint offset = offsetForBit(bit); @@ -327,23 +326,31 @@ bool QQmlData::wasDeleted(const QObject *object) return ddata && ddata->isQueuedForDeletion; } -QQmlNotifierEndpoint *QQmlData::notify(int index) +inline bool isIndexInConnectionMask(quint64 connectionMask, int index) +{ + return connectionMask & (1ULL << quint64(index % 64)); +} + +QQmlNotifierEndpoint *QQmlData::notify(int index) const { + // Can only happen on "home" thread. We apply relaxed semantics when loading the atomics. + Q_ASSERT(index <= 0xFFFF); - if (!notifyList || !(notifyList->connectionMask & (1ULL << quint64(index % 64)))) { + NotifyList *list = notifyList.loadRelaxed(); + if (!list || !isIndexInConnectionMask(list->connectionMask.loadRelaxed(), index)) return nullptr; - } else if (index < notifyList->notifiesSize) { - return notifyList->notifies[index]; - } else if (index <= notifyList->maximumTodoIndex) { - notifyList->layout(); - } - if (index < notifyList->notifiesSize) { - return notifyList->notifies[index]; - } else { - return nullptr; + if (index < list->notifiesSize) + return list->notifies[index]; + + if (index <= list->maximumTodoIndex) { + list->layout(); + if (index < list->notifiesSize) + return list->notifies[index]; } + + return nullptr; } /* @@ -352,7 +359,19 @@ QQmlNotifierEndpoint *QQmlData::notify(int index) */ inline bool QQmlData::signalHasEndpoint(int index) const { - return notifyList && (notifyList->connectionMask & (1ULL << quint64(index % 64))); + // This can be called from any thread. + // We still use relaxed semantics. If we're on a thread different from the "home" thread + // of the QQmlData, two interesting things might happen: + // + // 1. The list might go away while we hold it. In that case we are dealing with an object whose + // QObject dtor is being executed concurrently. This is UB already without the notify lists. + // Therefore, we don't need to consider it. + // 2. The connectionMask may be amended or zeroed while we are looking at it. In that case + // we "misreport" the endpoint. Since ordering of events across threads is inherently + // nondeterministic, either result is correct in that case. We can accept it. + + NotifyList *list = notifyList.loadRelaxed(); + return list && isIndexInConnectionMask(list->connectionMask.loadRelaxed(), index); } bool QQmlData::hasBindingBit(int coreIndex) const @@ -399,11 +418,11 @@ void QQmlData::clearPendingBindingBit(int coreIndex) clearBit(coreIndex * 2 + 1); } -void QQmlData::flushPendingBinding(QObject *o, QQmlPropertyIndex propertyIndex) +void QQmlData::flushPendingBinding(QObject *object, int coreIndex) { - QQmlData *data = QQmlData::get(o, false); - if (data && data->hasPendingBindingBit(propertyIndex.coreIndex())) - data->flushPendingBindingImpl(propertyIndex); + QQmlData *data = QQmlData::get(object, false); + if (data && data->hasPendingBindingBit(coreIndex)) + data->flushPendingBinding(coreIndex); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmldatablob.cpp b/src/qml/qml/qqmldatablob.cpp index f0dc0d77d34..cabfd6b9043 100644 --- a/src/qml/qml/qqmldatablob.cpp +++ b/src/qml/qml/qqmldatablob.cpp @@ -73,16 +73,14 @@ The QQmlTypeLoader invokes callbacks on the QQmlDataBlob as data becomes availab This enum describes the status of the data blob. -\list -\li Null The blob has not yet been loaded by a QQmlTypeLoader -\li Loading The blob is loading network data. The QQmlDataBlob::setData() callback has not yet been - invoked or has not yet returned. -\li WaitingForDependencies The blob is waiting for dependencies to be done before continuing. - This status only occurs after the QQmlDataBlob::setData() callback has been made, and when the - blob has outstanding dependencies. -\li Complete The blob's data has been loaded and all dependencies are done. -\li Error An error has been set on this blob. -\endlist +\value Null The blob has not yet been loaded by a QQmlTypeLoader +\value Loading The blob is loading network data. The QQmlDataBlob::setData() callback has + not yet been invoked or has not yet returned. +\value WaitingForDependencies The blob is waiting for dependencies to be done before continuing. + This status only occurs after the QQmlDataBlob::setData() callback has been made, + and when the blob has outstanding dependencies. +\value Complete The blob's data has been loaded and all dependencies are done. +\value Error An error has been set on this blob. */ /*! @@ -90,11 +88,9 @@ This enum describes the status of the data blob. This enum describes the type of the data blob. -\list -\li QmlFile This is a QQmlTypeData -\li JavaScriptFile This is a QQmlScriptData -\li QmldirFile This is a QQmlQmldirData -\endlist +\value QmlFile This is a QQmlTypeData +\value JavaScriptFile This is a QQmlScriptData +\value QmldirFile This is a QQmlQmldirData */ /*! diff --git a/src/qml/qml/qqmldirdata.cpp b/src/qml/qml/qqmldirdata.cpp index 9c42cbec133..14552aff2d8 100644 --- a/src/qml/qml/qqmldirdata.cpp +++ b/src/qml/qml/qqmldirdata.cpp @@ -51,30 +51,18 @@ const QString &QQmlQmldirData::content() const return m_content; } -QQmlTypeLoader::Blob::PendingImportPtr QQmlQmldirData::import(QQmlTypeLoader::Blob *blob) const +QV4::CompiledData::Location QQmlQmldirData::importLocation(QQmlTypeLoader::Blob *blob) const { - auto it = m_imports.find(blob); - if (it == m_imports.end()) - return nullptr; - return *it; + auto it = m_imports.constFind(blob); + if (it == m_imports.constEnd()) + return QV4::CompiledData::Location(); + return it->import->location; } -void QQmlQmldirData::setImport(QQmlTypeLoader::Blob *blob, QQmlTypeLoader::Blob::PendingImportPtr import) +void QQmlQmldirData::setPriority(QQmlTypeLoader::Blob *blob, + QQmlTypeLoader::Blob::PendingImportPtr import, int priority) { - m_imports[blob] = std::move(import); -} - -int QQmlQmldirData::priority(QQmlTypeLoader::Blob *blob) const -{ - QHash::const_iterator it = m_priorities.find(blob); - if (it == m_priorities.end()) - return 0; - return *it; -} - -void QQmlQmldirData::setPriority(QQmlTypeLoader::Blob *blob, int priority) -{ - m_priorities[blob] = priority; + m_imports.insert(blob, { import, priority }); } void QQmlQmldirData::dataReceived(const SourceCodeData &data) diff --git a/src/qml/qml/qqmldirdata_p.h b/src/qml/qml/qqmldirdata_p.h index d8ca7886e6f..98113b8f292 100644 --- a/src/qml/qml/qqmldirdata_p.h +++ b/src/qml/qml/qqmldirdata_p.h @@ -64,21 +64,39 @@ class Q_AUTOTEST_EXPORT QQmlQmldirData : public QQmlTypeLoader::Blob public: const QString &content() const; + QV4::CompiledData::Location importLocation(Blob *blob) const; - PendingImportPtr import(QQmlTypeLoader::Blob *) const; - void setImport(QQmlTypeLoader::Blob *, PendingImportPtr); + template + bool processImports(Blob *blob, const Callback &callback) const + { + bool result = true; + const auto range = m_imports.equal_range(blob); + for (auto it = range.first; it != range.second; ++it) { + // Do we need to resolve this import? + if ((it->import->priority == 0) || (it->import->priority > it->priority)) { + // This is the (current) best resolution for this import + if (!callback(it->import)) + result = false; + it->import->priority = it->priority; + } + } + return result; + } - int priority(QQmlTypeLoader::Blob *) const; - void setPriority(QQmlTypeLoader::Blob *, int); + void setPriority(Blob *, PendingImportPtr, int); protected: void dataReceived(const SourceCodeData &) override; void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *) override; private: + struct PrioritizedImport { + PendingImportPtr import; + int priority = 0; + }; + QString m_content; - QHash m_imports; - QHash m_priorities; + QMultiHash m_imports; }; QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 4b90f6a501e..e14931ddba2 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -161,7 +162,7 @@ QT_BEGIN_NAMESPACE \endcode */ -bool QQmlEnginePrivate::qml_debugging_enabled = false; +std::atomic QQmlEnginePrivate::qml_debugging_enabled{false}; bool QQmlEnginePrivate::s_designerMode = false; bool QQmlEnginePrivate::designerMode() @@ -378,138 +379,20 @@ The following functions are also on the Qt object. The \c application object provides access to global application state properties shared by many QML components. - Its properties are: - - \table - \row - \li \c application.active - \li - Deprecated, use Qt.application.state == Qt.ApplicationActive instead. - - \row - \li \c application.state - \li - This read-only property indicates the current state of the application. - - Possible values are: - - \list - \li Qt.ApplicationActive - The application is the top-most and focused application, and the - user is able to interact with the application. - \li Qt.ApplicationInactive - The application is visible or partially visible, but not selected - to be in front, the user cannot interact with the application. - On desktop platforms, this typically means that the user activated - another application. On mobile platforms, it is more common to - enter this state when the OS is interrupting the user with for - example incoming calls, SMS-messages or dialogs. This is usually a - transient state during which the application is paused. The user - may return focus to your application, but most of the time it will - be the first indication that the application is going to be suspended. - While in this state, consider pausing or stopping any activity that - should not continue when the user cannot interact with your - application, such as a video, a game, animations, or sensors. - You should also avoid performing CPU-intensive tasks which might - slow down the application in front. - \li Qt.ApplicationSuspended - The application is suspended and not visible to the user. On - mobile platforms, the application typically enters this state when - the user returns to the home screen or switches to another - application. While in this state, the application should ensure - that the user perceives it as always alive and does not lose his - progress, saving any persistent data. The application should cease - all activities and be prepared for code execution to stop. While - suspended, the application can be killed at any time without - further warnings (for example when low memory forces the OS to purge - suspended applications). - \li Qt.ApplicationHidden - The application is hidden and runs in the background. This is the - normal state for applications that need to do background processing, - like playing music, while the user interacts with other applications. - The application should free up all graphical resources when entering - this state. A Qt Quick application should not usually handle this state - at the QML level. Instead, you should unload the entire UI and reload - the QML files whenever the application becomes active again. - \endlist - - \row - \li \c application.layoutDirection - \li - This read-only property can be used to query the default layout direction of the - application. On system start-up, the default layout direction depends on the - application's language. The property has a value of \c Qt.RightToLeft in locales - where text and graphic elements are read from right to left, and \c Qt.LeftToRight - where the reading direction flows from left to right. You can bind to this - property to customize your application layouts to support both layout directions. - - Possible values are: - - \list - \li Qt.LeftToRight - Text and graphics elements should be positioned - from left to right. - \li Qt.RightToLeft - Text and graphics elements should be positioned - from right to left. - \endlist - \row - \li \c application.font - \li This read-only property holds the default application font as - returned by \l QGuiApplication::font(). - \row - \li \c application.arguments - \li This is a string list of the arguments the executable was invoked with. - \row - \li \c application.name - \li This is the application name set on the QCoreApplication instance. This property can be written - to in order to set the application name. - \row - \li \c application.displayName (since Qt 5.9) - \li This is the application display name set on the QGuiApplication instance. This property can be written - to in order to set the application display name. - \row - \li \c application.version - \li This is the application version set on the QCoreApplication instance. This property can be written - to in order to set the application version. - \row - \li \c application.organization - \li This is the organization name set on the QCoreApplication instance. This property can be written - to in order to set the organization name. - \row - \li \c application.domain - \li This is the organization domain set on the QCoreApplication instance. This property can be written - to in order to set the organization domain. - - \row - \li \c application.supportsMultipleWindows - \li This read-only property can be used to determine whether or not the - platform supports multiple windows. Some embedded platforms do not support - multiple windows, for example. - - \row - \li \c application.screens - \li An array containing the descriptions of all connected screens. The - elements of the array are objects with the same properties as the - \l{Screen} attached object. In practice the array corresponds to the screen - list returned by QGuiApplication::screens(). In addition to examining - properties like name, width, height, etc., the array elements can also be - assigned to the screen property of Window items, thus serving as an - alternative to the C++ side's QWindow::setScreen(). This property has been - added in Qt 5.9. - - \endtable - - The object also has one signal, aboutToQuit(), which is the same as \l QCoreApplication::aboutToQuit(). + It is the same as the \l Application singleton. The following example uses the \c application object to indicate whether the application is currently active: \snippet qml/application.qml document - Note that when using QML without a QGuiApplication, the following properties will be undefined: + \note When using QML without a QGuiApplication, the following properties will be undefined: \list \li application.active \li application.state \li application.layoutDirection \li application.font \endlist - - \sa Screen, Window, {Window::screen}{Window.screen} */ /*! @@ -646,7 +529,7 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o) // Disconnect the notifiers now - during object destruction this would be too late, since // the disconnect call wouldn't be able to call disconnectNotify(), as it isn't possible to // get the metaobject anymore. - d->disconnectNotifiers(); + d->disconnectNotifiers(QQmlData::DeleteNotifyList::No); } } @@ -707,7 +590,10 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in // QQmlEngine to emit signals from a different thread. These signals are then automatically // marshalled back onto the QObject's thread and handled by QML from there. This is tested // by the qqmlecmascript::threadSignal() autotest. - if (!ddata->notifyList) + + // Relaxed semantics here. If we're on a different thread we might schedule a useless event, + // but that should be rare. + if (!ddata->notifyList.loadRelaxed()) return; auto objectThreadData = QObjectPrivate::get(object)->threadData.loadRelaxed(); @@ -806,17 +692,17 @@ void QQmlData::setQueuedForDeletion(QObject *object) } } -void QQmlData::flushPendingBindingImpl(QQmlPropertyIndex index) +void QQmlData::flushPendingBinding(int coreIndex) { - clearPendingBindingBit(index.coreIndex()); + clearPendingBindingBit(coreIndex); // Find the binding QQmlAbstractBinding *b = bindings; - while (b && (b->targetPropertyIndex().coreIndex() != index.coreIndex() || + while (b && (b->targetPropertyIndex().coreIndex() != coreIndex || b->targetPropertyIndex().hasValueTypeIndex())) b = b->nextBinding(); - if (b && b->targetPropertyIndex().coreIndex() == index.coreIndex() && + if (b && b->targetPropertyIndex().coreIndex() == coreIndex && !b->targetPropertyIndex().hasValueTypeIndex()) b->setEnabled(true, QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding); @@ -977,6 +863,16 @@ QQmlEngine::~QQmlEngine() Once the component cache has been cleared, components must be loaded before any new objects can be created. + \note Any existing objects created from QML components retain their types, + even if you clear the component cache. This includes singleton objects. If you + create more objects from the same QML code after clearing the cache, the new + objects will be of different types than the old ones. Assigning such a new + object to a property of its declared type belonging to an object created + before clearing the cache won't work. + + As a general rule of thumb, make sure that no objects created from QML + components are alive when you clear the component cache. + \sa trimComponentCache() */ void QQmlEngine::clearComponentCache() @@ -1080,6 +976,15 @@ QUrl QQmlEngine::interceptUrl(const QUrl &url, QQmlAbstractUrlInterceptor::DataT return result; } +/*! + Returns the list of currently active URL interceptors. + */ +QList QQmlEngine::urlInterceptors() const +{ + Q_D(const QQmlEngine); + return d->urlInterceptors; +} + void QQmlEnginePrivate::registerFinalizeCallback(QObject *obj, int index) { if (activeObjectCreator) { @@ -1358,21 +1263,12 @@ QJSValue QQmlEngine::singletonInstance(int qmlTypeId) QCoreApplication::installTranslator, to ensure that your user-interface shows up-to-date translations. - \note Due to a limitation in the implementation, this function - refreshes all the engine's bindings, not only those that use strings - marked for translation. - This may be optimized in a future release. - \since 5.10 */ void QQmlEngine::retranslate() { Q_D(QQmlEngine); - for (QQmlRefPointer context - = QQmlContextData::get(d->rootContext)->childContexts(); - context; context = context->nextChild()) { - context->refreshExpressions(); - } + d->translationLanguage.notify(); } /*! @@ -1531,7 +1427,7 @@ void QQmlData::deferData( const QV4::CompiledData::Binding *binding = compiledObject->bindingTable(); for (quint32 i = 0; i < compiledObject->nBindings; ++i, ++binding) { const QQmlPropertyData *property = propertyData.at(i); - if (property && binding->flags & QV4::CompiledData::Binding::IsDeferredBinding) + if (property && binding->hasFlag(QV4::CompiledData::Binding::IsDeferredBinding)) deferData->bindings.insert(property->coreIndex(), binding); } @@ -1554,49 +1450,73 @@ void QQmlData::releaseDeferredData() void QQmlData::addNotify(int index, QQmlNotifierEndpoint *endpoint) { - if (!notifyList) { - notifyList = (NotifyList *)malloc(sizeof(NotifyList)); - notifyList->connectionMask = 0; - notifyList->maximumTodoIndex = 0; - notifyList->notifiesSize = 0; - notifyList->todo = nullptr; - notifyList->notifies = nullptr; + // Can only happen on "home" thread. We apply relaxed semantics when loading the atomics. + + NotifyList *list = notifyList.loadRelaxed(); + + if (!list) { + list = new NotifyList; + // We don't really care when this change takes effect on other threads. The notifyList can + // only become non-null once in the life time of a QQmlData. It becomes null again when the + // underlying QObject is deleted. At that point any interaction with the QQmlData is UB + // anyway. So, for all intents and purposese, the list becomes non-null once and then stays + // non-null "forever". We can apply relaxed semantics. + notifyList.storeRelaxed(list); } Q_ASSERT(!endpoint->isConnected()); index = qMin(index, 0xFFFF - 1); - notifyList->connectionMask |= (1ULL << quint64(index % 64)); - if (index < notifyList->notifiesSize) { + // Likewise, we don't really care _when_ the change in the connectionMask is propagated to other + // threads. Cross-thread event ordering is inherently nondeterministic. Therefore, when querying + // the conenctionMask in the presence of concurrent modification, any result is correct. + list->connectionMask.storeRelaxed( + list->connectionMask.loadRelaxed() | (1ULL << quint64(index % 64))); - endpoint->next = notifyList->notifies[index]; + if (index < list->notifiesSize) { + endpoint->next = list->notifies[index]; if (endpoint->next) endpoint->next->prev = &endpoint->next; - endpoint->prev = ¬ifyList->notifies[index]; - notifyList->notifies[index] = endpoint; - + endpoint->prev = &list->notifies[index]; + list->notifies[index] = endpoint; } else { - notifyList->maximumTodoIndex = qMax(int(notifyList->maximumTodoIndex), index); + list->maximumTodoIndex = qMax(int(list->maximumTodoIndex), index); - endpoint->next = notifyList->todo; + endpoint->next = list->todo; if (endpoint->next) endpoint->next->prev = &endpoint->next; - endpoint->prev = ¬ifyList->todo; - notifyList->todo = endpoint; + endpoint->prev = &list->todo; + list->todo = endpoint; } } -void QQmlData::disconnectNotifiers() +void QQmlData::disconnectNotifiers(QQmlData::DeleteNotifyList doDelete) { - if (notifyList) { - while (notifyList->todo) - notifyList->todo->disconnect(); - for (int ii = 0; ii < notifyList->notifiesSize; ++ii) { - while (QQmlNotifierEndpoint *ep = notifyList->notifies[ii]) + // Can only happen on "home" thread. We apply relaxed semantics when loading the atomics. + if (NotifyList *list = notifyList.loadRelaxed()) { + while (QQmlNotifierEndpoint *todo = list->todo) + todo->disconnect(); + for (int ii = 0; ii < list->notifiesSize; ++ii) { + while (QQmlNotifierEndpoint *ep = list->notifies[ii]) ep->disconnect(); } - free(notifyList->notifies); - free(notifyList); - notifyList = nullptr; + free(list->notifies); + + if (doDelete == DeleteNotifyList::Yes) { + // We can only get here from QQmlData::destroyed(), and that can only come from the + // the QObject dtor. If you're still sending signals at that point you have UB already + // without any threads. Therefore, it's enough to apply relaxed semantics. + notifyList.storeRelaxed(nullptr); + delete list; + } else { + // We can use relaxed semantics here. The worst thing that can happen is that some + // signal is falsely reported as connected. Signal connectedness across threads + // is not quite deterministic anyway. + list->connectionMask.storeRelaxed(0); + list->maximumTodoIndex = 0; + list->notifiesSize = 0; + list->notifies = nullptr; + + } } } @@ -1680,7 +1600,7 @@ void QQmlData::destroyed(QObject *object) guard->objectDestroyed(object); } - disconnectNotifiers(); + disconnectNotifiers(DeleteNotifyList::Yes); if (extendedData) delete extendedData; @@ -1876,7 +1796,7 @@ void QQmlEnginePrivate::cleanupScarceResources() The newly added \a path will be first in the importPathList(). - \sa setImportPathList(), {QML Modules} + \sa setImportPathList(), {QML Modules}, {QML Import Path} */ void QQmlEngine::addImportPath(const QString& path) { @@ -1894,9 +1814,8 @@ void QQmlEngine::addImportPath(const QString& path) provided by that module. A \c qmldir file is required for defining the type version mapping and possibly QML extensions plugins. - By default, the list contains the directory of the application executable, - paths specified in the \c QML_IMPORT_PATH environment variable, - and the builtin \c QmlImportsPath from QLibraryInfo. + By default, this list contains the paths mentioned in + \l {QML Import Path}. \sa addImportPath(), setImportPathList() */ @@ -1910,9 +1829,11 @@ QStringList QQmlEngine::importPathList() const Sets \a paths as the list of directories where the engine searches for installed modules in a URL-based directory structure. - By default, the list contains the directory of the application executable, - paths specified in the \c QML_IMPORT_PATH environment variable, - and the builtin \c QmlImportsPath from QLibraryInfo. + By default, this list contains the paths mentioned in + \l {QML Import Path}. + + \warning Calling setImportPathList does not preserve the default + import paths. \sa importPathList(), addImportPath() */ @@ -1983,8 +1904,10 @@ void QQmlEngine::setPluginPathList(const QStringList &paths) bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList *errors) { Q_D(QQmlEngine); - return d->importDatabase.importDynamicPlugin(filePath, uri, QString(), QTypeRevision(), false, - errors).isValid(); + QQmlTypeLoaderQmldirContent qmldir; + QQmlPluginImporter importer( + uri, QTypeRevision(), &d->importDatabase, &qmldir, &d->typeLoader, errors); + return importer.importDynamicPlugin(filePath, uri, false).isValid(); } #endif @@ -1995,7 +1918,8 @@ bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList Returns the directory where SQL and other offline storage is placed. - The SQL databases created with openDatabase() are stored here. + The SQL databases created with \c openDatabaseSync() are stored here. + \sa \l{Qt Quick Local Storage QML Types} The default is QML/OfflineStorage in the platform-standard user application data directory. @@ -2394,4 +2318,6 @@ bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn /* = -1 */) QT_END_NAMESPACE +#include "moc_qqmlengine_p.cpp" + #include "moc_qqmlengine.cpp" diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h index 37ca25779fd..64e4a82b03f 100644 --- a/src/qml/qml/qqmlengine.h +++ b/src/qml/qml/qqmlengine.h @@ -136,6 +136,7 @@ class Q_QML_EXPORT QQmlEngine : public QJSEngine void addUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor); void removeUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor); + QList urlInterceptors() const; QUrl interceptUrl(const QUrl &url, QQmlAbstractUrlInterceptor::DataType type) const; void addImageProvider(const QString &id, QQmlImageProviderBase *); diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 499f9dd492c..15315a9000e 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -75,6 +75,7 @@ #include #include #include +#include #include @@ -83,6 +84,8 @@ #include +#include + QT_BEGIN_NAMESPACE class QQmlContext; @@ -127,11 +130,20 @@ class QQmlJavaScriptExpressionGuard : public QQmlNotifierEndpoint }; struct QPropertyChangeTrigger : QPropertyObserver { - QPropertyChangeTrigger(QQmlJavaScriptExpression *expression) : QPropertyObserver(&QPropertyChangeTrigger::trigger), m_expression(expression) {} - QQmlJavaScriptExpression * m_expression; - QObject *target = nullptr; + Q_DISABLE_COPY_MOVE(QPropertyChangeTrigger) + + QPropertyChangeTrigger(QQmlJavaScriptExpression *expression) + : QPropertyObserver(&QPropertyChangeTrigger::trigger) + , m_expression(expression) + { + } + + QPointer target; + QQmlJavaScriptExpression *m_expression; int propertyIndex = 0; static void trigger(QPropertyObserver *, QUntypedPropertyData *); + + QMetaProperty property() const; }; struct TriggerList : QPropertyChangeTrigger { @@ -159,6 +171,7 @@ class Q_QML_PRIVATE_EXPORT QQmlEnginePrivate : public QJSEnginePrivate QRecyclePool qPropertyTriggerPool; QQmlContext *rootContext; + Q_OBJECT_BINDABLE_PROPERTY(QQmlEnginePrivate, QString, translationLanguage); #if !QT_CONFIG(qml_debug) static const quintptr profiler = 0; @@ -275,7 +288,7 @@ class Q_QML_PRIVATE_EXPORT QQmlEnginePrivate : public QJSEnginePrivate static bool designerMode(); static void activateDesignerMode(); - static bool qml_debugging_enabled; + static std::atomic qml_debugging_enabled; mutable QMutex networkAccessManagerMutex; diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp index cb9096ae66c..3cf2bce5881 100644 --- a/src/qml/qml/qqmlexpression.cpp +++ b/src/qml/qml/qqmlexpression.cpp @@ -206,7 +206,7 @@ QQmlExpression::~QQmlExpression() } /*! - Returns the QQmlEngine this expression is associated with, or 0 if there + Returns the QQmlEngine this expression is associated with, or \nullptr if there is no association or the QQmlEngine has been destroyed. */ QQmlEngine *QQmlExpression::engine() const @@ -216,7 +216,7 @@ QQmlEngine *QQmlExpression::engine() const } /*! - Returns the QQmlContext this expression is associated with, or 0 if there + Returns the QQmlContext this expression is associated with, or \nullptr if there is no association or the QQmlContext has been destroyed. */ QQmlContext *QQmlExpression::context() const diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h index 3df839a6a23..26c0cddb9e8 100644 --- a/src/qml/qml/qqmlexpression_p.h +++ b/src/qml/qml/qqmlexpression_p.h @@ -76,6 +76,7 @@ class QQmlExpressionPrivate : public QObjectPrivate, QVariant value(bool *isUndefined = nullptr); QV4::ReturnedValue v4value(bool *isUndefined = nullptr); + bool mustCaptureBindableProperty() const final {return true;} static inline QQmlExpressionPrivate *get(QQmlExpression *expr); static inline QQmlExpression *get(QQmlExpressionPrivate *expr); diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp index f779199b74d..c2fc291d48b 100644 --- a/src/qml/qml/qqmlextensionplugin.cpp +++ b/src/qml/qml/qqmlextensionplugin.cpp @@ -42,6 +42,21 @@ QT_BEGIN_NAMESPACE +/*! + \since 5.0 + \inmodule QtQml + \class QQmlExtensionPlugin + \brief The QQmlExtensionPlugin class provides an abstract base for custom QML extension plugins + with custom type registration functions. + + \ingroup plugins + + \note If you need to write a plugin manually (which is rare) you should always use + \l{QQmlEngineExtensionPlugin}. QQmlExtensionPlugin only provides the registerTypes() and + unregisterTypes() functions in addition. You should not use them, but rather declare your + types with \l{QML_ELEMENT} and friends and have the build system take care of the registration. +*/ + /*! \since 5.14 \inmodule QtQml @@ -61,7 +76,6 @@ QT_BEGIN_NAMESPACE /*! \fn void QQmlExtensionPlugin::registerTypes(const char *uri) - \internal Registers the QML types in the given \a uri. Subclasses should implement this to call qmlRegisterType() for all types which are provided by the extension @@ -127,9 +141,10 @@ void QQmlExtensionPlugin::unregisterTypes() } /*! - \internal -*/ - + Initializes the extension from the \a uri using the \a engine. Here an application + plugin might, for example, expose some data or objects to QML, + as context properties on the engine's root context. + */ void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri) { Q_UNUSED(engine); @@ -165,6 +180,18 @@ void QQmlEngineExtensionPlugin::initializeEngine(QQmlEngine *engine, const char \inmodule QtQml */ + +/*! + \macro Q_IMPORT_QML_PLUGIN(PluginName) + \since 6.2 + \relates QQmlEngineExtensionPlugin + + Ensures the plugin whose metadata-declaring class is named \a PluginName + is linked into static builds. + + \sa Q_IMPORT_PLUGIN +*/ + QT_END_NAMESPACE #include "moc_qqmlextensionplugin.cpp" diff --git a/src/qml/qml/qqmlextensionplugin.h b/src/qml/qml/qqmlextensionplugin.h index 78371106bde..f6fec106541 100644 --- a/src/qml/qml/qqmlextensionplugin.h +++ b/src/qml/qml/qqmlextensionplugin.h @@ -44,6 +44,15 @@ #include #include +#if defined(Q_CC_GHS) +# define Q_GHS_KEEP_REFERENCE(S) QT_DO_PRAGMA(ghs reference S ##__Fv) +#else +# define Q_GHS_KEEP_REFERENCE(S) +#endif + +#define Q_IMPORT_QML_PLUGIN(PLUGIN) \ + Q_IMPORT_PLUGIN(PLUGIN) + QT_BEGIN_NAMESPACE class QQmlEngine; diff --git a/src/qml/qml/qqmlfile.cpp b/src/qml/qml/qqmlfile.cpp index 4db89819754..dc2734d7d1d 100644 --- a/src/qml/qml/qqmlfile.cpp +++ b/src/qml/qml/qqmlfile.cpp @@ -516,58 +516,91 @@ bool QQmlFile::isLocalFile(const QUrl &url) { QString scheme = url.scheme(); - if ((scheme.length() == 4 && 0 == scheme.compare(QLatin1String(file_string), Qt::CaseInsensitive)) || - (scheme.length() == 3 && 0 == scheme.compare(QLatin1String(qrc_string), Qt::CaseInsensitive))) { + // file: URLs with two slashes following the scheme can be interpreted as local files + // where the slashes are part of the path. Therefore, disregard the authority. + // See QUrl::toLocalFile(). + if (scheme.length() == 4 && scheme.startsWith(QLatin1String(file_string), Qt::CaseInsensitive)) return true; + if (scheme.length() == 3 && scheme.startsWith(QLatin1String(qrc_string), Qt::CaseInsensitive)) + return url.authority().isEmpty(); + #if defined(Q_OS_ANDROID) - } else if (scheme.length() == 6 && 0 == scheme.compare(QLatin1String(assets_string), Qt::CaseInsensitive)) { - return true; + if ((scheme.length() == 6 + && scheme.startsWith(QLatin1String(assets_string), Qt::CaseInsensitive)) + || (scheme.length() == 7 + && scheme.startsWith(QLatin1String(content_string), Qt::CaseInsensitive))) { + return url.authority().isEmpty(); + } #endif - } else { + return false; +} + +static bool hasSchemeAndNoAuthority(const QString &url, const char *scheme, qsizetype schemeLength) +{ + const qsizetype urlLength = url.length(); + + if (urlLength < schemeLength + 1) + return false; + + if (!url.startsWith(QLatin1String(scheme, scheme + schemeLength), Qt::CaseInsensitive)) + return false; + + if (url[schemeLength] != QLatin1Char(':')) return false; + + if (urlLength < schemeLength + 3) + return true; + + const QLatin1Char slash('/'); + if (url[schemeLength + 1] == slash && url[schemeLength + 2] == slash) { + // Exactly two slashes denote an authority. We don't want that. + if (urlLength < schemeLength + 4 || url[schemeLength + 3] != slash) + return false; } + + return true; } /*! Returns true if \a url is a local file that can be opened with QFile. -Local file urls have either a qrc:/ or file:// scheme. +Local file urls have either a qrc: or file: scheme. -\note On Android, urls with assets:/ scheme are also considered local files. +\note On Android, urls with assets: or content: scheme are also considered local files. */ bool QQmlFile::isLocalFile(const QString &url) { - if (url.length() < 5 /* qrc:/ */) + if (url.length() < 4 /* qrc: */) return false; - QChar f = url[0]; - - if (f == QLatin1Char('f') || f == QLatin1Char('F')) { - - return url.length() >= 7 /* file:// */ && - url.startsWith(QLatin1String(file_string), Qt::CaseInsensitive) && - url[4] == QLatin1Char(':') && url[5] == QLatin1Char('/') && url[6] == QLatin1Char('/'); - - } else if (f == QLatin1Char('q') || f == QLatin1Char('Q')) { - - return url.length() >= 5 /* qrc:/ */ && - url.startsWith(QLatin1String(qrc_string), Qt::CaseInsensitive) && - url[3] == QLatin1Char(':') && url[4] == QLatin1Char('/'); - + switch (url[0].toLatin1()) { + case 'f': + case 'F': { + // file: URLs with two slashes following the scheme can be interpreted as local files + // where the slashes are part of the path. Therefore, disregard the authority. + // See QUrl::toLocalFile(). + const qsizetype fileLength = strlen(file_string); + return url.startsWith(QLatin1String(file_string, file_string + fileLength), + Qt::CaseInsensitive) + && url.length() > fileLength + && url[fileLength] == QLatin1Char(':'); } + case 'q': + case 'Q': + return hasSchemeAndNoAuthority(url, qrc_string, strlen(qrc_string)); #if defined(Q_OS_ANDROID) - else if (f == QLatin1Char('a') || f == QLatin1Char('A')) { - return url.length() >= 8 /* assets:/ */ && - url.startsWith(QLatin1String(assets_string), Qt::CaseInsensitive) && - url[6] == QLatin1Char(':') && url[7] == QLatin1Char('/'); - } else if (f == QLatin1Char('c') || f == QLatin1Char('C')) { - return url.length() >= 9 /* content:/ */ && - url.startsWith(QLatin1String(content_string), Qt::CaseInsensitive) && - url[7] == QLatin1Char(':') && url[8] == QLatin1Char('/'); - } + case 'a': + case 'A': + return hasSchemeAndNoAuthority(url, assets_string, strlen(assets_string)); + case 'c': + case 'C': + return hasSchemeAndNoAuthority(url, content_string, strlen(content_string)); #endif + default: + break; + } return false; } @@ -585,13 +618,10 @@ QString QQmlFile::urlToLocalFileOrQrc(const QUrl& url) } #if defined(Q_OS_ANDROID) - else if (url.scheme().compare(QLatin1String("assets"), Qt::CaseInsensitive) == 0) { - if (url.authority().isEmpty()) - return url.toString(); - return QString(); - } else if (url.scheme().compare(QLatin1String("content"), Qt::CaseInsensitive) == 0) { - return url.toString(); - } + if (url.scheme().compare(QLatin1String("assets"), Qt::CaseInsensitive) == 0) + return url.authority().isEmpty() ? url.toString() : QString(); + if (url.scheme().compare(QLatin1String("content"), Qt::CaseInsensitive) == 0) + return url.authority().isEmpty() ? url.toString() : QString(); #endif return url.toLocalFile(); @@ -603,11 +633,28 @@ static QString toLocalFile(const QString &url) if (!file.isLocalFile()) return QString(); - //XXX TODO: handle windows hostnames: "//servername/path/to/file.txt" + // QUrl::toLocalFile() interprets two slashes as part of the path. + // Therefore windows hostnames like "//servername/path/to/file.txt" are preserved. return file.toLocalFile(); } +static bool isDoubleSlashed(const QString &url, qsizetype offset) +{ + const qsizetype urlLength = url.length(); + if (urlLength < offset + 2) + return false; + + const QLatin1Char slash('/'); + if (url[offset] != slash || url[offset + 1] != slash) + return false; + + if (urlLength < offset + 3) + return true; + + return url[offset + 2] != slash; +} + /*! If \a url is a local file returns a path suitable for passing to QFile. Otherwise returns an empty string. @@ -615,23 +662,28 @@ empty string. QString QQmlFile::urlToLocalFileOrQrc(const QString& url) { if (url.startsWith(QLatin1String("qrc://"), Qt::CaseInsensitive)) { - if (url.length() > 6) - return QLatin1Char(':') + QStringView{url}.mid(6); - return QString(); + // Exactly two slashes are bad because that's a URL authority. + // One slash is fine and >= 3 slashes are file. + if (url.length() == 6 || url[6] != QLatin1Char('/')) { + Q_ASSERT(isDoubleSlashed(url, strlen("qrc:"))); + return QString(); + } + Q_ASSERT(!isDoubleSlashed(url, strlen("qrc:"))); + return QLatin1Char(':') + QStringView{url}.mid(6); } if (url.startsWith(QLatin1String("qrc:"), Qt::CaseInsensitive)) { + Q_ASSERT(!isDoubleSlashed(url, strlen("qrc:"))); if (url.length() > 4) return QLatin1Char(':') + QStringView{url}.mid(4); - return QString(); + return QStringLiteral(":"); } #if defined(Q_OS_ANDROID) - else if (url.startsWith(QLatin1String("assets:"), Qt::CaseInsensitive)) { - return url; - } else if (url.startsWith(QLatin1String("content:"), Qt::CaseInsensitive)) { - return url; - } + if (url.startsWith(QLatin1String("assets:"), Qt::CaseInsensitive)) + return isDoubleSlashed(url, strlen("assets:")) ? QString() : url; + if (url.startsWith(QLatin1String("content:"), Qt::CaseInsensitive)) + return isDoubleSlashed(url, strlen("content:")) ? QString() : url; #endif return toLocalFile(url); diff --git a/src/qml/qml/qqmlfileselector.cpp b/src/qml/qml/qqmlfileselector.cpp index 4b773adc3e2..5b1264bfd72 100644 --- a/src/qml/qml/qqmlfileselector.cpp +++ b/src/qml/qml/qqmlfileselector.cpp @@ -90,8 +90,7 @@ QT_BEGIN_NAMESPACE directories used for selection must start with a '+' character, so you will not accidentally trigger this feature unless you have directories with such names inside your project. - If a new QQmlFileSelector is set on the engine, the old one will be replaced. Use - \l QQmlFileSelector::get() to query or use the existing instance. + If a new QQmlFileSelector is set on the engine, the old one will be replaced. */ /*! @@ -147,7 +146,7 @@ QQmlFileSelectorPrivate::~QQmlFileSelectorPrivate() /*! Sets the QFileSelector instance for use by the QQmlFileSelector to \a selector. QQmlFileSelector does not take ownership of the new QFileSelector. To reset QQmlFileSelector - to use its internal QFileSelector instance, call setSelector(0). + to use its internal QFileSelector instance, call setSelector(\nullptr). */ void QQmlFileSelector::setSelector(QFileSelector *selector) @@ -180,7 +179,9 @@ void QQmlFileSelector::setExtraSelectors(const QStringList &strings) #if QT_DEPRECATED_SINCE(6, 0) /*! - \deprecated + \deprecated [6.0] The file selector should not be accessed after it + is set. It may be in use. See below for further details. + Gets the QQmlFileSelector currently active on the target \a engine. This method is deprecated. You should not retrieve the files selector from an diff --git a/src/qml/qml/qqmlguard_p.h b/src/qml/qml/qqmlguard_p.h index 3ac63926a09..85b2b898dff 100644 --- a/src/qml/qml/qqmlguard_p.h +++ b/src/qml/qml/qqmlguard_p.h @@ -110,19 +110,19 @@ template class QQmlStrongJSQObjectReference : public QQmlGuard { public: - void setObject(T *o, QObject *parent) { + void setObject(T *obj, QObject *parent) { T *old = this->object(); - if (o == old) + if (obj == old) return; if (m_jsOwnership && old && old->parent() == parent) QQml_setParent_noEvent(old, nullptr); - this->QQmlGuard::operator=(o); + this->QQmlGuard::operator=(obj); - if (o && !o->parent() && !QQmlData::keepAliveDuringGarbageCollection(o)) { + if (obj && !obj->parent() && !QQmlData::keepAliveDuringGarbageCollection(obj)) { m_jsOwnership = true; - QQml_setParent_noEvent(o, parent); + QQml_setParent_noEvent(obj, parent); } else { m_jsOwnership = false; } diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 29f366d5bcc..e33d942833a 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include #include @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -63,11 +64,39 @@ #include #include -#include QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE) + +class QmlImportCategoryHolder +{ + Q_DISABLE_COPY_MOVE(QmlImportCategoryHolder); +public: + + QmlImportCategoryHolder() : m_category("qt.qml.import") + { + // We have to explicitly setEnabled() here because for categories that start with + // "qt." it won't accept QtDebugMsg as argument. Debug messages are off by default + // for all Qt logging categories. + if (qmlImportTrace()) + m_category.setEnabled(QtDebugMsg, true); + } + + ~QmlImportCategoryHolder() = default; + + const QLoggingCategory &category() const { return m_category; } + +private: + QLoggingCategory m_category; +}; + +const QLoggingCategory &lcQmlImport() +{ + static const QmlImportCategoryHolder holder; + return holder.category(); +} + DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES) static const QLatin1Char Dot('.'); @@ -166,74 +195,6 @@ bool isPathAbsolute(const QString &path) } // namespace -struct QmlPlugin { - std::unique_ptr loader; -}; - -class PathPluginMap -{ - Q_DISABLE_COPY_MOVE(PathPluginMap) -public: - PathPluginMap() = default; - using Container = std::unordered_map; - -private: - QBasicMutex mutex; - Container plugins; - friend class PathPluginMapPtr; -}; - -class PathPluginMapPtr -{ - Q_DISABLE_COPY_MOVE(PathPluginMapPtr) -public: - PathPluginMapPtr(PathPluginMap *map) : map(map), locker(&map->mutex) {} - - PathPluginMap::Container &operator*() { return map->plugins; } - const PathPluginMap::Container &operator*() const { return map->plugins; } - - PathPluginMap::Container *operator->() { return &map->plugins; } - const PathPluginMap::Container *operator->() const { return &map->plugins; } - -private: - PathPluginMap *map; - QMutexLocker locker; -}; - -Q_GLOBAL_STATIC(PathPluginMap, qmlPluginsByPath); // stores the uri and the PluginLoaders - -static bool unloadPlugin(const std::pair &plugin) -{ - const auto &loader = plugin.second.loader; - if (!loader) - return false; - -#if QT_CONFIG(library) - if (auto extensionPlugin = qobject_cast(loader->instance())) - extensionPlugin->unregisterTypes(); - -# ifndef Q_OS_MACOS - if (!loader->unload()) { - qWarning("Unloading %s failed: %s", qPrintable(plugin.first), - qPrintable(loader->errorString())); - return false; - } -# endif -#endif - - return true; -} - -void qmlClearEnginePlugins() -{ - PathPluginMapPtr plugins(qmlPluginsByPath()); - for (const auto &plugin : qAsConst(*plugins)) - unloadPlugin(plugin); - plugins->clear(); -} - -typedef QPair StaticPluginPair; - /*! \internal \class QQmlImportInstance @@ -308,17 +269,13 @@ class QQmlImportsPrivate QQmlTypeLoader *typeLoader; - static QQmlImports::LocalQmldirResult locateLocalQmldir( - const QString &uri, QTypeRevision version, QQmlImportDatabase *database, - QString *outQmldirFilePath, QString *outUrl); - static QTypeRevision matchingQmldirVersion( const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, QTypeRevision version, QList *errors); QTypeRevision importExtension( const QString &uri, QTypeRevision version, QQmlImportDatabase *database, - const QQmlTypeLoaderQmldirContent &qmldir, QList *errors); + const QQmlTypeLoaderQmldirContent *qmldir, QList *errors); bool getQmldirContent(const QString &qmldirIdentifier, const QString &uri, QQmlTypeLoaderQmldirContent *qmldir, QList *errors); @@ -329,9 +286,6 @@ class QQmlImportsPrivate const QString &url, QTypeRevision version, QV4::CompiledData::Import::ImportType type, QList *errors, uint flags); - - bool populatePluginPairVector(QVector &result, const QString &uri, const QStringList &versionUris, - const QString &qmldirPath, QList *errors); }; /*! @@ -630,9 +584,9 @@ bool QQmlImports::resolveType(const QHashedStringRef &type, if (type_return) { if (d->resolveType(type, version_return, type_return, errors, registrationType, typeRecursionDetected)) { - if (qmlImportTrace()) { -#define RESOLVE_TYPE_DEBUG qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) \ - << ')' << "::resolveType: " << type.toString() << " => " + if (lcQmlImport().isDebugEnabled()) { +#define RESOLVE_TYPE_DEBUG qCDebug(lcQmlImport) \ + << "resolveType:" << qPrintable(baseUrl().toString()) << type.toString() << " => " if (type_return && type_return->isValid()) { if (type_return->isCompositeSingleton()) @@ -1125,203 +1079,35 @@ QQmlImportNamespace *QQmlImportsPrivate::findQualifiedNamespace(const QHashedStr return nullptr; } -/* - Returns the list of possible versioned URI combinations. For example, if \a uri is - QtQml.Models, \a vmaj is 2, and \a vmin is 0, this method returns the following: - [QtQml.Models.2.0, QtQml.2.0.Models, QtQml.Models.2, QtQml.2.Models, QtQml.Models] - */ -static QStringList versionUriList(const QString &uri, QTypeRevision version) -{ - QStringList result; - for (int mode = QQmlImports::FullyVersioned; mode <= QQmlImports::Unversioned; ++mode) { - int index = uri.length(); - do { - QString versionUri = uri; - versionUri.insert(index, QQmlImports::versionString( - version, QQmlImports::ImportVersion(mode))); - result += versionUri; - - index = uri.lastIndexOf(Dot, index - 1); - } while (index > 0 && mode != QQmlImports::Unversioned); - } - return result; -} - -static QVector makePlugins() -{ - QVector plugins; - // To avoid traversing all static plugins for all imports, we cut down - // the list the first time called to only contain QML plugins: - const auto staticPlugins = QPluginLoader::staticPlugins(); - for (const QStaticPlugin &plugin : staticPlugins) { - const QString iid = plugin.metaData().value(QLatin1String("IID")).toString(); - if (iid == QLatin1String(QQmlEngineExtensionInterface_iid) - || iid == QLatin1String(QQmlExtensionInterface_iid) - || iid == QLatin1String(QQmlExtensionInterface_iid_old)) { - plugins.append(plugin); - } - } - return plugins; -} - -/* - Get all static plugins that are QML plugins and has a meta data URI that matches with one of - \a versionUris, which is a list of all possible versioned URI combinations - see versionUriList() - above. - */ -bool QQmlImportsPrivate::populatePluginPairVector(QVector &result, const QString &uri, const QStringList &versionUris, - const QString &qmldirPath, QList *errors) -{ - static const QVector plugins = makePlugins(); - for (const QStaticPlugin &plugin : plugins) { - // Since a module can list more than one plugin, we keep iterating even after we found a match. - QObject *instance = plugin.instance(); - if (qobject_cast(instance) - || qobject_cast(instance)) { - const QJsonArray metaTagsUriList = plugin.metaData().value(QLatin1String("uri")).toArray(); - if (metaTagsUriList.isEmpty()) { - if (errors) { - QQmlError error; - error.setDescription(QQmlImportDatabase::tr("static plugin for module \"%1\" with name \"%2\" has no metadata URI") - .arg(uri).arg(QString::fromUtf8(instance->metaObject()->className()))); - error.setUrl(QUrl::fromLocalFile(qmldirPath)); - errors->prepend(error); - } - return false; - } - // A plugin can be set up to handle multiple URIs, so go through the list: - for (const QJsonValue metaTagUri : metaTagsUriList) { - if (versionUris.contains(metaTagUri.toString())) { - result.append(qMakePair(plugin, metaTagsUriList)); - break; - } - } - } - } - return true; -} - /* Import an extension defined by a qmldir file. */ QTypeRevision QQmlImportsPrivate::importExtension( const QString &uri, QTypeRevision version, QQmlImportDatabase *database, - const QQmlTypeLoaderQmldirContent &qmldir, QList *errors) + const QQmlTypeLoaderQmldirContent *qmldir, QList *errors) { - Q_ASSERT(qmldir.hasContent()); + Q_ASSERT(qmldir->hasContent()); - const QString qmldirFilePath = qmldir.qmldirLocation(); - if (qmlImportTrace()) - qDebug().nospace() << "QQmlImports(" << qPrintable(base) << ")::importExtension: " - << "loaded " << qmldirFilePath; + qCDebug(lcQmlImport) + << "importExtension:" << qPrintable(base) << "loaded" << qmldir->qmldirLocation(); - if (designerSupportRequired && !qmldir.designerSupported()) { + if (designerSupportRequired && !qmldir->designerSupported()) { if (errors) { QQmlError error; - error.setDescription(QQmlImportDatabase::tr("module does not support the designer \"%1\"").arg(qmldir.typeNamespace())); - error.setUrl(QUrl::fromLocalFile(qmldirFilePath)); + error.setDescription( + QQmlImportDatabase::tr("module does not support the designer \"%1\"") + .arg(qmldir->typeNamespace())); + error.setUrl(QUrl::fromLocalFile(qmldir->qmldirLocation())); errors->prepend(error); } return QTypeRevision(); } - int qmldirPluginCount = qmldir.plugins().count(); - if (qmldirPluginCount == 0) + if (qmldir->plugins().isEmpty()) return validVersion(version); - if (!database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) { - // First search for listed qmldir plugins dynamically. If we cannot resolve them all, we continue - // searching static plugins that has correct metadata uri. Note that since we only know the uri - // for a static plugin, and not the filename, we cannot know which static plugin belongs to which - // listed plugin inside qmldir. And for this reason, mixing dynamic and static plugins inside a - // single module is not recommended. - - QString typeNamespace = qmldir.typeNamespace(); - QString qmldirPath = qmldirFilePath; - int slash = qmldirPath.lastIndexOf(Slash); - if (slash > 0) - qmldirPath.truncate(slash); - - int dynamicPluginsFound = 0; - int staticPluginsFound = 0; - - const auto qmldirPlugins = qmldir.plugins(); - for (const QQmlDirParser::Plugin &plugin : qmldirPlugins) { - const QString resolvedFilePath = database->resolvePlugin( - typeLoader, qmldirPath, plugin.path, plugin.name); - - if (resolvedFilePath.isEmpty()) - continue; - - ++dynamicPluginsFound; - version = database->importDynamicPlugin( - resolvedFilePath, uri, typeNamespace, version, plugin.optional, errors); - if (!version.isValid()) - return QTypeRevision(); - } - - if (dynamicPluginsFound < qmldirPluginCount) { - // Check if the missing plugins can be resolved statically. We do this by looking at - // the URIs embedded in a plugins meta data. Since those URIs can be anything from fully - // versioned to unversioned, we need to compare with differnt version strings. If a module - // has several plugins, they must all have the same version. Start by populating pluginPairs - // with relevant plugins to cut the list short early on: - const QStringList versionUris = versionUriList(uri, version); - QVector pluginPairs; - if (!populatePluginPairVector(pluginPairs, uri, versionUris, qmldirFilePath, errors)) - return QTypeRevision(); - - const QString basePath = QFileInfo(qmldirPath).absoluteFilePath(); - for (const QString &versionUri : versionUris) { - for (const StaticPluginPair &pair : qAsConst(pluginPairs)) { - for (const QJsonValue metaTagUri : pair.second) { - if (versionUri == metaTagUri.toString()) { - staticPluginsFound++; - QObject *instance = pair.first.instance(); - version = database->importStaticPlugin( - instance, basePath, uri, typeNamespace, version, errors); - if (!version.isValid()){ - if (errors) { - Q_ASSERT(!errors->isEmpty()); - QQmlError poppedError = errors->takeFirst(); - QQmlError error; - error.setDescription(QQmlImportDatabase::tr("static plugin for module \"%1\" with name \"%2\" cannot be loaded: %3") - .arg(uri).arg(QString::fromUtf8(instance->metaObject()->className())).arg(poppedError.description())); - error.setUrl(QUrl::fromLocalFile(qmldirFilePath)); - errors->prepend(error); - } - return QTypeRevision(); - } - - if (qmlImportTrace()) - qDebug().nospace() << "QQmlImports(" << qPrintable(base) << ")::importExtension: " - << "loaded static plugin " << versionUri; - - break; - } - } - } - if (staticPluginsFound > 0) - break; - } - } - - if ((dynamicPluginsFound + staticPluginsFound) < qmldirPluginCount) { - if (errors) { - QQmlError error; - if (qmldirPluginCount > 1 && staticPluginsFound > 0) - error.setDescription(QQmlImportDatabase::tr("could not resolve all plugins for module \"%1\"").arg(uri)); - else - error.setDescription(QQmlImportDatabase::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(qmldir.plugins()[dynamicPluginsFound].name)); - error.setUrl(QUrl::fromLocalFile(qmldirFilePath)); - errors->prepend(error); - } - return QTypeRevision(); - } - - database->qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(qmldirFilePath); - } - return validVersion(version); + QQmlPluginImporter importer(uri, version, database, qmldir, typeLoader, errors); + return importer.importPlugins(); } bool QQmlImportsPrivate::getQmldirContent(const QString &qmldirIdentifier, const QString &uri, @@ -1383,92 +1169,42 @@ QString QQmlImportsPrivate::resolvedUri(const QString &dir_arg, QQmlImportDataba return stableRelativePath; } -/* -Locates the qmldir file for \a uri version \a vmaj.vmin. Returns true if found, -and fills in outQmldirFilePath and outQmldirUrl appropriately. Otherwise returns -false. +/* removes all file selector occurrences in path + firstPlus is the position of the initial '+' in the path + which we always have as we check for '+' to decide whether + we need to do some work at all */ -QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir( - const QString &uri, QTypeRevision version, QQmlImportDatabase *database, - QString *outQmldirFilePath, QString *outQmldirPathUrl) +static QString pathWithoutFileSelectors(QString path, // we want a copy of path + qsizetype firstPlus) { - // Check cache first - - QQmlImportDatabase::QmldirCache *cacheHead = nullptr; - { - QQmlImportDatabase::QmldirCache **cachePtr = database->qmldirCache.value(uri); - if (cachePtr) { - cacheHead = *cachePtr; - QQmlImportDatabase::QmldirCache *cache = cacheHead; - while (cache) { - if (cache->version == version) { - *outQmldirFilePath = cache->qmldirFilePath; - *outQmldirPathUrl = cache->qmldirPathUrl; - return cache->qmldirFilePath.isEmpty() ? QQmlImports::QmldirNotFound - : QQmlImports::QmldirFound; - } - cache = cache->next; - } - } - } - - QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(database->engine); - QQmlTypeLoader &typeLoader = enginePrivate->typeLoader; - const bool hasInterceptors = !enginePrivate->urlInterceptors.isEmpty(); - - // Interceptor might redirect remote files to local ones. - QStringList localImportPaths = database->importPathList( - hasInterceptors ? QQmlImportDatabase::LocalOrRemote : QQmlImportDatabase::Local); - - // Search local import paths for a matching version - const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths( - uri, localImportPaths, version); - bool pathTurnedRemote = false; - for (QString qmldirPath : qmlDirPaths) { - if (hasInterceptors) { - const QUrl intercepted = database->engine->interceptUrl( - QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath), - QQmlAbstractUrlInterceptor::QmldirFile); - qmldirPath = QQmlFile::urlToLocalFileOrQrc(intercepted); - if (!pathTurnedRemote && qmldirPath.isEmpty() && !QQmlFile::isLocalFile(intercepted)) - pathTurnedRemote = true; - } + do { + Q_ASSERT(path.at(firstPlus) == u'+'); + const auto eos = path.size(); + qsizetype terminatingSlashPos = firstPlus + 1; + while (terminatingSlashPos != eos && path.at(terminatingSlashPos) != u'/') + ++terminatingSlashPos; + path.remove(firstPlus, terminatingSlashPos - firstPlus + 1); + firstPlus = path.indexOf(u'+', firstPlus); + } while (firstPlus != -1); + return path; +} - QString absoluteFilePath = typeLoader.absoluteFilePath(qmldirPath); - if (!absoluteFilePath.isEmpty()) { - QString url; - const QStringView absolutePath = QStringView{absoluteFilePath}.left(absoluteFilePath.lastIndexOf(Slash) + 1); - if (absolutePath.at(0) == Colon) { - url = QLatin1String("qrc") + absolutePath; - } else { - url = QUrl::fromLocalFile(absolutePath.toString()).toString(); - // This handles the UNC path case as when the path is retrieved from the QUrl it - // will convert the host name from upper case to lower case. So the absoluteFilePath - // is changed at this point to make sure it will match later on in that case. - if (absoluteFilePath.startsWith(QLatin1String("//"))) - absoluteFilePath = QUrl::fromLocalFile(absoluteFilePath).toString(QUrl::RemoveScheme); - } - QQmlImportDatabase::QmldirCache *cache = new QQmlImportDatabase::QmldirCache; - cache->version = version; - cache->qmldirFilePath = absoluteFilePath; - cache->qmldirPathUrl = url; - cache->next = cacheHead; - database->qmldirCache.insert(uri, cache); +/*! + \internal - *outQmldirFilePath = absoluteFilePath; - *outQmldirPathUrl = url; + \fn template + QQmlImportDatabase::LocalQmldirResult QQmlImportDatabase::locateLocalQmldir( + const QString &uri, QTypeRevision version, const Callback &callback) - return QQmlImports::QmldirFound; - } - } + Locates the qmldir files for \a uri version \a version. For each one, calls + the \a callback. If the \a callback returns \c true, returns QmldirFound. - QQmlImportDatabase::QmldirCache *cache = new QQmlImportDatabase::QmldirCache; - cache->version = version; - cache->next = cacheHead; - database->qmldirCache.insert(uri, cache); + If at least one callback invocation returned \c false and there are no qmldir + files left to check, returns QmldirRejected. - return pathTurnedRemote ? QQmlImports::QmldirInterceptedToRemote : QQmlImports::QmldirNotFound; -} + Otherwise, if interception redirects a previously local qmldir URL to a remote + one, returns QmldirInterceptedToRemote. Otherwise, returns QmldirNotFound. +*/ QTypeRevision QQmlImportsPrivate::matchingQmldirVersion( const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, QTypeRevision version, @@ -1499,10 +1235,42 @@ QTypeRevision QQmlImportsPrivate::matchingQmldirVersion( typedef QQmlDirComponents::const_iterator ConstIterator; const QQmlDirComponents &components = qmldir.components(); + QMultiHash baseFileName2ConflictingComponents; + ConstIterator cend = components.constEnd(); for (ConstIterator cit = components.constBegin(); cit != cend; ++cit) { for (ConstIterator cit2 = components.constBegin(); cit2 != cit; ++cit2) { if (cit2->typeName == cit->typeName && cit2->version == cit->version) { + // ugly heuristic to deal with file selectors + const auto comp2PotentialFileSelectorPos = cit2->fileName.indexOf(u'+'); + const bool comp2MightHaveFileSelector = comp2PotentialFileSelectorPos != -1; + /* If we detect conflicting paths, we check if they agree when we remove anything looking like a + file selector. + We need to create copies of the filenames, otherwise QString::replace would modify the + existing file-names + */ + QString compFileName1 = cit->fileName; + QString compFileName2 = cit2->fileName; + if (auto fileSelectorPos1 = compFileName1.indexOf(u'+'); fileSelectorPos1 != -1) { + // existing entry was file selector entry, fix it up + // it could also be the case that _both_ are using file selectors + QString baseName = comp2MightHaveFileSelector ? pathWithoutFileSelectors(compFileName2, + comp2PotentialFileSelectorPos) + : compFileName2; + if (pathWithoutFileSelectors(compFileName1, fileSelectorPos1) == baseName) { + baseFileName2ConflictingComponents.insert(baseName, cit); + baseFileName2ConflictingComponents.insert(baseName, cit2); + continue; + } + // fall through to error case + } else if (comp2MightHaveFileSelector) { + // new entry contains file selector (and we now that cit did not) + if (pathWithoutFileSelectors(compFileName2, comp2PotentialFileSelectorPos) == compFileName1) { + baseFileName2ConflictingComponents.insert(compFileName1, cit2); + continue; + } + // fall through to error case + } // This entry clashes with a predecessor QQmlError error; error.setDescription(QQmlImportDatabase::tr("\"%1\" version %2.%3 is defined more than once in module \"%4\"") @@ -1516,6 +1284,14 @@ QTypeRevision QQmlImportsPrivate::matchingQmldirVersion( addVersion(cit->version); } + // ensure that all components point to the actual base URL, and let the file selectors resolve them correctly during URL resolution + for (auto keyIt = baseFileName2ConflictingComponents.keyBegin(); keyIt != baseFileName2ConflictingComponents.keyEnd(); ++keyIt) { + const QString& baseFileName = *keyIt; + const auto conflictingComponents = baseFileName2ConflictingComponents.values(baseFileName); + for (ConstIterator component: conflictingComponents) + component->fileName = baseFileName; + } + typedef QList::const_iterator SConstIterator; const QQmlDirScripts &scripts = qmldir.scripts(); @@ -1638,7 +1414,7 @@ QTypeRevision QQmlImportsPrivate::addLibraryImport( return QTypeRevision(); if (qmldir.hasContent()) { - version = importExtension(uri, version, database, qmldir, errors); + version = importExtension(uri, version, database, &qmldir, errors); if (!version.isValid()) return QTypeRevision(); @@ -1653,8 +1429,12 @@ QTypeRevision QQmlImportsPrivate::addLibraryImport( return matchingVersion; if (inserted->qmlDirComponents.isEmpty() && inserted->qmlDirScripts.isEmpty()) { - if (qmldir.plugins().isEmpty() && !qmldir.imports().isEmpty()) - return validVersion(); // This is a pure redirection + if (qmldir.plugins().isEmpty()) { + if (!qmldir.imports().isEmpty()) + return validVersion(); // This is a pure redirection + if (qmldir.hasTypeInfo()) + return validVersion(); // A pure C++ module without plugin + } errors->prepend(moduleNotFoundError(uri, relevantVersion(uri, version))); return QTypeRevision(); } else if (qmldir.hasContent()) { @@ -1672,6 +1452,18 @@ QTypeRevision QQmlImportsPrivate::addFileImport( const QString& uri, const QString &prefix, QTypeRevision version, uint flags, QQmlImportDatabase *database, QList *errors) { + if (uri.startsWith(Slash) || uri.startsWith(Colon)) { + QQmlError error; + const QString fix = uri.startsWith(Slash) ? QLatin1String("file:") + uri + : QLatin1String("qrc") + uri; + error.setDescription(QQmlImportDatabase::tr( + "\"%1\" is not a valid import URL. " + "You can pass relative paths or URLs with schema, but not " + "absolute paths or resource paths. Try \"%2\".").arg(uri, fix)); + errors->prepend(error); + return QTypeRevision(); + } + Q_ASSERT(errors); QQmlImportNamespace *nameSpace = importNamespace(prefix); @@ -1727,6 +1519,15 @@ QTypeRevision QQmlImportsPrivate::addFileImport( // The url for the path containing files for this import QString url = resolveLocalUrl(base, uri); + if (url.isEmpty()) { + QQmlError error; + error.setDescription( + QQmlImportDatabase::tr("Cannot resolve URL for import \"%1\"").arg(uri)); + error.setUrl(baseUrl); + errors->prepend(error); + return QTypeRevision(); + } + if (!url.endsWith(Slash) && !url.endsWith(Backslash)) url += Slash; @@ -1757,7 +1558,14 @@ QTypeRevision QQmlImportsPrivate::addFileImport( return QTypeRevision(); if (qmldir.hasContent()) { - version = importExtension(importUri, version, database, qmldir, errors); + if (uri == QStringLiteral(".")) { + // If this is an implicit import, prefer the qmldir URI. Unless it doesn't exist. + const QString qmldirUri = qmldir.typeNamespace(); + if (!qmldirUri.isEmpty()) + importUri = qmldirUri; + } + + version = importExtension(importUri, version, database, &qmldir, errors); if (!version.isValid()) return QTypeRevision(); @@ -1782,7 +1590,8 @@ QTypeRevision QQmlImportsPrivate::updateQmldirContent(const QString &uri, const return QTypeRevision(); if (qmldir.hasContent()) { - QTypeRevision version = importExtension(uri, import->version, database, qmldir, errors); + QTypeRevision version = importExtension(uri, import->version, database, &qmldir, + errors); if (!version.isValid()) return QTypeRevision(); @@ -1825,9 +1634,7 @@ QTypeRevision QQmlImports::addImplicitImport(QQmlImportDatabase *importDb, QList { Q_ASSERT(errors); - if (qmlImportTrace()) - qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) - << ")::addImplicitImport"; + qCDebug(lcQmlImport) << "addImplicitImport:" << qPrintable(baseUrl().toString()); uint flags = ImportImplicit | (!isLocal(baseUrl()) ? ImportIncomplete : 0); return d->addFileImport(QLatin1String("."), QString(), QTypeRevision(), flags, @@ -1877,9 +1684,9 @@ QTypeRevision QQmlImports::addFileImport( Q_ASSERT(importDb); Q_ASSERT(errors); - if (qmlImportTrace()) - qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) << ')' << "::addFileImport: " - << uri << ' ' << version << " as " << prefix; + qCDebug(lcQmlImport) + << "addFileImport:" << qPrintable(baseUrl().toString()) + << uri << version << "as" << prefix; return d->addFileImport(uri, prefix, version, flags, importDb, errors); } @@ -1892,9 +1699,9 @@ QTypeRevision QQmlImports::addLibraryImport( Q_ASSERT(importDb); Q_ASSERT(errors); - if (qmlImportTrace()) - qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) << ')' << "::addLibraryImport: " - << uri << ' ' << version << " as " << prefix; + qCDebug(lcQmlImport) + << "addLibraryImport:" << qPrintable(baseUrl().toString()) + << uri << "version '" << version << "'" << "as" << prefix; return d->addLibraryImport(uri, prefix, version, qmldirIdentifier, qmldirUrl, flags, importDb, errors); @@ -1907,20 +1714,13 @@ QTypeRevision QQmlImports::updateQmldirContent( Q_ASSERT(importDb); Q_ASSERT(errors); - if (qmlImportTrace()) - qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) << ')' << "::updateQmldirContent: " - << uri << " to " << qmldirUrl << " as " << prefix; + qDebug(lcQmlImport) + << "updateQmldirContent:" << qPrintable(baseUrl().toString()) + << uri << "to" << qmldirUrl << "as" << prefix; return d->updateQmldirContent(uri, prefix, qmldirIdentifier, qmldirUrl, importDb, errors); } -QQmlImports::LocalQmldirResult QQmlImports::locateLocalQmldir( - QQmlImportDatabase *importDb, const QString &uri, QTypeRevision version, - QString *qmldirFilePath, QString *url) -{ - return d->locateLocalQmldir(uri, version, importDb, qmldirFilePath, url); -} - bool QQmlImports::isLocal(const QString &url) { return !QQmlFile::urlToLocalFileOrQrc(url).isEmpty(); @@ -2015,130 +1815,6 @@ QQmlImportDatabase::~QQmlImportDatabase() clearDirCache(); } -/*! - \internal - - Returns the result of the merge of \a baseName with \a path, \a suffixes, and \a prefix. - The \a prefix must contain the dot. - - \a qmldirPath is the location of the qmldir file. - */ -QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader, - const QString &qmldirPath, - const QString &qmldirPluginPath, - const QString &baseName, const QStringList &suffixes, - const QString &prefix) const -{ - QStringList searchPaths = filePluginPath; - bool qmldirPluginPathIsRelative = QDir::isRelativePath(qmldirPluginPath); - if (!qmldirPluginPathIsRelative) - searchPaths.prepend(qmldirPluginPath); - - for (const QString &pluginPath : qAsConst(searchPaths)) { - QString resolvedPath; - if (pluginPath == QLatin1String(".")) { - if (qmldirPluginPathIsRelative && !qmldirPluginPath.isEmpty() && qmldirPluginPath != QLatin1String(".")) - resolvedPath = QDir::cleanPath(qmldirPath + Slash + qmldirPluginPath); - else - resolvedPath = qmldirPath; - } else { - if (QDir::isRelativePath(pluginPath)) - resolvedPath = QDir::cleanPath(qmldirPath + Slash + pluginPath); - else - resolvedPath = pluginPath; - } - - // hack for resources, should probably go away - if (resolvedPath.startsWith(Colon)) - resolvedPath = QCoreApplication::applicationDirPath(); - - if (!resolvedPath.endsWith(Slash)) - resolvedPath += Slash; - -#if defined(Q_OS_ANDROID) - if (qmldirPath.size() > 25 && qmldirPath.at(0) == QLatin1Char(':') && qmldirPath.at(1) == QLatin1Char('/') && - qmldirPath.startsWith(QStringLiteral(":/android_rcc_bundle/qml/"), Qt::CaseInsensitive)) { - QString pluginName = qmldirPath.mid(21) + Slash + baseName; - pluginName.replace(QLatin1Char('/'), QLatin1Char('_')); - QString bundledPath = resolvedPath + QLatin1String("lib") + pluginName; - for (const QString &suffix : suffixes) { - const QString absolutePath = typeLoader->absoluteFilePath(bundledPath + suffix); - if (!absolutePath.isEmpty()) - return absolutePath; - } - } -#endif - resolvedPath += prefix + baseName; - for (const QString &suffix : suffixes) { - const QString absolutePath = typeLoader->absoluteFilePath(resolvedPath + suffix); - if (!absolutePath.isEmpty()) - return absolutePath; - } - } - - if (qmlImportTrace()) - qDebug() << "QQmlImportDatabase::resolvePlugin: Could not resolve plugin" << baseName - << "in" << qmldirPath; - - return QString(); -} - -/*! - \internal - - Returns the result of the merge of \a baseName with \a dir and the platform suffix. - - \table - \header \li Platform \li Valid suffixes - \row \li Windows \li \c .dll - \row \li Unix/Linux \li \c .so - \row \li \macos \li \c .dylib, \c .bundle, \c .so - \endtable - - Version number on unix are ignored. -*/ -QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader, - const QString &qmldirPath, const QString &qmldirPluginPath, - const QString &baseName) const -{ -#if defined(Q_OS_WIN) - static const QString prefix; - static const QStringList suffixes = { -# ifdef QT_DEBUG - QLatin1String("d.dll"), // try a qmake-style debug build first - QLatin1String(".dll") -#else - QLatin1String(".dll"), - QLatin1String("d.dll") // try a qmake-style debug build after -# endif - }; -#elif defined(Q_OS_DARWIN) - static const QString prefix = QLatin1String("lib"); - static const QStringList suffixes = { -# ifdef QT_DEBUG - QLatin1String("_debug.dylib"), // try a qmake-style debug build first - QLatin1String(".dylib"), -# else - QLatin1String(".dylib"), - QLatin1String("_debug.dylib"), // try a qmake-style debug build after -# endif - QLatin1String(".so"), - QLatin1String(".bundle") - }; -#else // Unix - static const QString prefix = QLatin1String("lib"); - static const QStringList suffixes = { -# if defined(Q_OS_ANDROID) - QStringLiteral(LIBS_SUFFIX), -# endif - QLatin1String(".so") - - }; -#endif - - return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName, suffixes, prefix); -} - /*! \internal */ @@ -2152,9 +1828,7 @@ QStringList QQmlImportDatabase::pluginPathList() const */ void QQmlImportDatabase::setPluginPathList(const QStringList &paths) { - if (qmlImportTrace()) - qDebug().nospace() << "QQmlImportDatabase::setPluginPathList: " << paths; - + qCDebug(lcQmlImport) << "setPluginPathList:" << paths; filePluginPath = paths; } @@ -2163,8 +1837,7 @@ void QQmlImportDatabase::setPluginPathList(const QStringList &paths) */ void QQmlImportDatabase::addPluginPath(const QString& path) { - if (qmlImportTrace()) - qDebug().nospace() << "QQmlImportDatabase::addPluginPath: " << path; + qCDebug(lcQmlImport) << "addPluginPath:" << path; QUrl url = QUrl(path); if (url.isRelative() || url.scheme() == QLatin1String("file") @@ -2176,13 +1849,17 @@ void QQmlImportDatabase::addPluginPath(const QString& path) } } +QString QQmlImportDatabase::absoluteFilePath(const QString &path) const +{ + return QQmlEnginePrivate::get(engine)->typeLoader.absoluteFilePath(path); +} + /*! \internal */ void QQmlImportDatabase::addImportPath(const QString& path) { - if (qmlImportTrace()) - qDebug().nospace() << "QQmlImportDatabase::addImportPath: " << path; + qCDebug(lcQmlImport) << "addImportPath:" << path; if (path.isEmpty()) return; @@ -2237,8 +1914,7 @@ QStringList QQmlImportDatabase::importPathList(PathType type) const */ void QQmlImportDatabase::setImportPathList(const QStringList &paths) { - if (qmlImportTrace()) - qDebug().nospace() << "QQmlImportDatabase::setImportPathList: " << paths; + qCDebug(lcQmlImport) << "setImportPathList:" << paths; fileImportPath.clear(); for (auto it = paths.crbegin(); it != paths.crend(); ++it) @@ -2251,8 +1927,8 @@ void QQmlImportDatabase::setImportPathList(const QStringList &paths) /*! \internal */ -static QTypeRevision lockModule(const QString &uri, const QString &typeNamespace, - QTypeRevision version, QList *errors) +QTypeRevision QQmlImportDatabase::lockModule(const QString &uri, const QString &typeNamespace, + QTypeRevision version, QList *errors) { if (!version.hasMajorVersion()) { version = QQmlMetaType::latestModuleVersion(uri); @@ -2273,165 +1949,14 @@ static QTypeRevision lockModule(const QString &uri, const QString &typeNamespace return version; } -/*! - \internal -*/ -QTypeRevision QQmlImportDatabase::importStaticPlugin( - QObject *instance, const QString &basePath, const QString &uri, - const QString &typeNamespace, QTypeRevision version, QList *errors) +bool QQmlImportDatabase::removeDynamicPlugin(const QString &pluginId) { - // Dynamic plugins are differentiated by their filepath. For static plugins we - // don't have that information so we use their address as key instead. - const QString uniquePluginID = QString::asprintf("%p", instance); - { - PathPluginMapPtr plugins(qmlPluginsByPath()); - - // Plugin types are global across all engines and should only be - // registered once. But each engine still needs to be initialized. - bool typesRegistered = plugins->find(uniquePluginID) != plugins->end(); - - if (!typesRegistered) { - plugins->insert(std::make_pair(uniquePluginID, QmlPlugin())); - if (QQmlMetaType::registerPluginTypes( - instance, basePath, uri, typeNamespace, version, errors) - == QQmlMetaType::RegistrationResult::Failure) { - return QTypeRevision(); - } - - version = lockModule(uri, typeNamespace, version, errors); - if (!version.isValid()) - return QTypeRevision(); - } - - // Release the lock on plugins early as we're done with the global part. Releasing the lock - // also allows other QML loader threads to acquire the lock while this thread is blocking - // in the initializeEngine call to the gui thread (which in turn may be busy waiting for - // other QML loader threads and thus not process the initializeEngine call). - } - - if (!initializedPlugins.contains(uniquePluginID)) - finalizePlugin(instance, uniquePluginID, uri); - - return validVersion(version); -} - -/*! - \internal -*/ -QTypeRevision QQmlImportDatabase::importDynamicPlugin( - const QString &filePath, const QString &uri, const QString &typeNamespace, - QTypeRevision version, bool isOptional, QList *errors) -{ - QFileInfo fileInfo(filePath); - const QString absoluteFilePath = fileInfo.absoluteFilePath(); - - QObject *instance = nullptr; - bool engineInitialized = initializedPlugins.contains(absoluteFilePath); - { - PathPluginMapPtr plugins(qmlPluginsByPath()); - bool typesRegistered = plugins->find(absoluteFilePath) != plugins->end(); - - if (!engineInitialized || !typesRegistered) { - if (!QQml_isFileCaseCorrect(absoluteFilePath)) { - if (errors) { - QQmlError error; - error.setDescription(tr("File name case mismatch for \"%1\"").arg(absoluteFilePath)); - errors->prepend(error); - } - return QTypeRevision(); - } - - QmlPlugin plugin; - - const QString absolutePath = fileInfo.absolutePath(); - if (!typesRegistered && isOptional) { - switch (QQmlMetaType::registerPluginTypes(nullptr, absolutePath, uri, typeNamespace, - version, errors)) { - case QQmlMetaType::RegistrationResult::NoRegistrationFunction: - // try again with plugin - break; - case QQmlMetaType::RegistrationResult::Success: - version = lockModule(uri, typeNamespace, version, errors); - if (!version.isValid()) - return QTypeRevision(); - // instance and loader intentionally left at nullptr - plugins->insert(std::make_pair(absoluteFilePath, std::move(plugin))); - // Not calling initializeEngine with null instance - initializedPlugins.insert(absoluteFilePath); - return version; - case QQmlMetaType::RegistrationResult::Failure: - return QTypeRevision(); - } - } - -#if QT_CONFIG(library) - if (!typesRegistered) { - plugin.loader = std::make_unique(absoluteFilePath); - if (!plugin.loader->load()) { - if (errors) { - QQmlError error; - error.setDescription(plugin.loader->errorString()); - errors->prepend(error); - } - return QTypeRevision(); - } - - instance = plugin.loader->instance(); - plugins->insert(std::make_pair(absoluteFilePath, std::move(plugin))); - - // Continue with shared code path for dynamic and static plugins: - if (QQmlMetaType::registerPluginTypes( - instance, fileInfo.absolutePath(), uri, typeNamespace, version, errors) - == QQmlMetaType::RegistrationResult::Failure) { - return QTypeRevision(); - } - - version = lockModule(uri, typeNamespace, version, errors); - if (!version.isValid()) - return QTypeRevision(); - } else { - auto it = plugins->find(absoluteFilePath); - if (it != plugins->end() && it->second.loader) - instance = it->second.loader->instance(); - } -#endif // QT_CONFIG(library) - } - - // Release the lock on plugins early as we're done with the global part. Releasing the lock - // also allows other QML loader threads to acquire the lock while this thread is blocking - // in the initializeEngine call to the gui thread (which in turn may be busy waiting for - // other QML loader threads and thus not process the initializeEngine call). - } - - if (!engineInitialized) - finalizePlugin(instance, absoluteFilePath, uri); - - return validVersion(version); -} - -bool QQmlImportDatabase::removeDynamicPlugin(const QString &filePath) -{ - PathPluginMapPtr plugins(qmlPluginsByPath()); - - auto it = plugins->find(QFileInfo(filePath).absoluteFilePath()); - if (it == plugins->end()) - return false; - - const bool success = unloadPlugin(*it); - - plugins->erase(it); - return success; + return QQmlPluginImporter::removePlugin(pluginId); } QStringList QQmlImportDatabase::dynamicPlugins() const { - PathPluginMapPtr plugins(qmlPluginsByPath()); - QStringList results; - for (auto it = plugins->cbegin(), end = plugins->cend(); it != end; ++it) { - if (it->second.loader != nullptr) - results.append(it->first); - } - return results; + return QQmlPluginImporter::plugins(); } void QQmlImportDatabase::clearDirCache() @@ -2450,20 +1975,4 @@ void QQmlImportDatabase::clearDirCache() qmldirCache.clear(); } -void QQmlImportDatabase::finalizePlugin(QObject *instance, const QString &path, const QString &uri) -{ - // The plugin's per-engine initialization does not need lock protection, as this function is - // only called from the engine specific loader thread and importDynamicPlugin as well as - // importStaticPlugin are the only places of access. - - initializedPlugins.insert(path); - if (auto *extensionIface = qobject_cast(instance)) { - QQmlEnginePrivate::get(engine)->typeLoader.initializeEngine( - extensionIface, uri.toUtf8().constData()); - } else if (auto *engineIface = qobject_cast(instance)) { - QQmlEnginePrivate::get(engine)->typeLoader.initializeEngine( - engineIface, uri.toUtf8().constData()); - } -} - QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h index 7a8e1f9dd4c..ba0b6286fd3 100644 --- a/src/qml/qml/qqmlimport_p.h +++ b/src/qml/qml/qqmlimport_p.h @@ -42,9 +42,12 @@ #include #include +#include #include #include +#include #include +#include #include #include #include @@ -71,6 +74,8 @@ class QQmlImportDatabase; class QQmlTypeLoader; class QQmlTypeLoaderQmldirContent; +const QLoggingCategory &lcQmlImport(); + namespace QQmlImport { enum RecursionRestriction { PreventRecursion, AllowRecursion }; } @@ -174,16 +179,6 @@ class Q_QML_PRIVATE_EXPORT QQmlImports QQmlImportDatabase *importDb, const QString &uri, const QString &prefix, const QString &qmldirIdentifier, const QString &qmldirUrl, QList *errors); - enum LocalQmldirResult { - QmldirFound, - QmldirNotFound, - QmldirInterceptedToRemote - }; - - LocalQmldirResult locateLocalQmldir( - QQmlImportDatabase *, const QString &uri, QTypeRevision version, - QString *qmldirFilePath, QString *url); - void populateCache(QQmlTypeNameCache *cache) const; struct ScriptReference @@ -225,13 +220,22 @@ class Q_QML_PRIVATE_EXPORT QQmlImportDatabase public: enum PathType { Local, Remote, LocalOrRemote }; + enum LocalQmldirSearchLocation { + QmldirFileAndCache, + QmldirCacheOnly, + }; + + enum LocalQmldirResult { + QmldirFound, + QmldirNotFound, + QmldirInterceptedToRemote, + QmldirRejected + }; + QQmlImportDatabase(QQmlEngine *); ~QQmlImportDatabase(); - QTypeRevision importDynamicPlugin( - const QString &filePath, const QString &uri, const QString &importNamespace, - QTypeRevision version, bool isOptional, QList *errors); - bool removeDynamicPlugin(const QString &filePath); + bool removeDynamicPlugin(const QString &pluginId); QStringList dynamicPlugins() const; QStringList importPathList(PathType type = LocalOrRemote) const; @@ -242,20 +246,20 @@ class Q_QML_PRIVATE_EXPORT QQmlImportDatabase void setPluginPathList(const QStringList &paths); void addPluginPath(const QString& path); - QString resolvePlugin(QQmlTypeLoader *typeLoader, - const QString &qmldirPath, const QString &qmldirPluginPath, - const QString &baseName) const; + template + LocalQmldirResult locateLocalQmldir( + const QString &uri, QTypeRevision version, LocalQmldirSearchLocation location, + const Callback &callback); + + static QTypeRevision lockModule(const QString &uri, const QString &typeNamespace, + QTypeRevision version, QList *errors); + private: friend class QQmlImportsPrivate; - QString resolvePlugin(QQmlTypeLoader *typeLoader, - const QString &qmldirPath, const QString &qmldirPluginPath, - const QString &baseName, const QStringList &suffixes, - const QString &prefix = QString()) const; - QTypeRevision importStaticPlugin( - QObject *instance, const QString &basePath, const QString &uri, - const QString &typeNamespace, QTypeRevision version, QList *errors); + friend class QQmlPluginImporter; + + QString absoluteFilePath(const QString &path) const; void clearDirCache(); - void finalizePlugin(QObject *instance, const QString &path, const QString &uri); struct QmldirCache { QTypeRevision version; @@ -271,11 +275,129 @@ class Q_QML_PRIVATE_EXPORT QQmlImportDatabase QStringList filePluginPath; QStringList fileImportPath; - QSet qmlDirFilesForWhichPluginsHaveBeenLoaded; + QSet modulesForWhichPluginsHaveBeenLoaded; QSet initializedPlugins; QQmlEngine *engine; }; +template +QQmlImportDatabase::LocalQmldirResult QQmlImportDatabase::locateLocalQmldir( + const QString &uri, QTypeRevision version, + QQmlImportDatabase::LocalQmldirSearchLocation location, const Callback &callback) +{ + // Check cache first + + LocalQmldirResult result = QmldirNotFound; + QmldirCache *cacheTail = nullptr; + + QmldirCache **cachePtr = qmldirCache.value(uri); + QmldirCache *cacheHead = cachePtr ? *cachePtr : nullptr; + if (cacheHead) { + cacheTail = cacheHead; + do { + if (cacheTail->version == version) { + if (cacheTail->qmldirFilePath.isEmpty()) { + return cacheTail->qmldirPathUrl.isEmpty() + ? QmldirNotFound + : QmldirInterceptedToRemote; + } + if (callback(cacheTail->qmldirFilePath, cacheTail->qmldirPathUrl)) + return QmldirFound; + result = QmldirRejected; + } + } while (cacheTail->next && (cacheTail = cacheTail->next)); + } + + + // Do not try to construct the cache if it already had any entries for the URI. + // Otherwise we might duplicate cache entries. + if (location == QmldirCacheOnly || result != QmldirNotFound) + return result; + + const bool hasInterceptors = !engine->urlInterceptors().isEmpty(); + + // Interceptor might redirect remote files to local ones. + QStringList localImportPaths = importPathList(hasInterceptors ? LocalOrRemote : Local); + + // Search local import paths for a matching version + const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths( + uri, localImportPaths, version); + + QString qmldirAbsoluteFilePath; + for (QString qmldirPath : qmlDirPaths) { + if (hasInterceptors) { + const QUrl intercepted = engine->interceptUrl( + QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath), + QQmlAbstractUrlInterceptor::QmldirFile); + qmldirPath = QQmlFile::urlToLocalFileOrQrc(intercepted); + if (result != QmldirInterceptedToRemote + && qmldirPath.isEmpty() + && !QQmlFile::isLocalFile(intercepted)) { + result = QmldirInterceptedToRemote; + } + } + + qmldirAbsoluteFilePath = absoluteFilePath(qmldirPath); + if (!qmldirAbsoluteFilePath.isEmpty()) { + QString url; + const QString absolutePath = qmldirAbsoluteFilePath.left( + qmldirAbsoluteFilePath.lastIndexOf(u'/') + 1); + if (absolutePath.at(0) == u':') { + url = QStringLiteral("qrc") + absolutePath; + } else { + url = QUrl::fromLocalFile(absolutePath).toString(); + // This handles the UNC path case as when the path is retrieved from the QUrl it + // will convert the host name from upper case to lower case. So the absoluteFilePath + // is changed at this point to make sure it will match later on in that case. + if (qmldirAbsoluteFilePath.startsWith(QStringLiteral("//"))) { + qmldirAbsoluteFilePath = QUrl::fromLocalFile(qmldirAbsoluteFilePath) + .toString(QUrl::RemoveScheme); + } + } + + QmldirCache *cache = new QmldirCache; + cache->version = version; + cache->qmldirFilePath = qmldirAbsoluteFilePath; + cache->qmldirPathUrl = url; + cache->next = nullptr; + if (cacheTail) + cacheTail->next = cache; + else + qmldirCache.insert(uri, cache); + cacheTail = cache; + + if (result != QmldirFound) + result = callback(qmldirAbsoluteFilePath, url) ? QmldirFound : QmldirRejected; + + // Do not return here. Rather, construct the complete cache for this URI. + } + } + + // Nothing found? Add an empty cache entry to signal that for further requests. + if (result == QmldirNotFound || result == QmldirInterceptedToRemote) { + QmldirCache *cache = new QmldirCache; + cache->version = version; + cache->next = cacheHead; + if (result == QmldirInterceptedToRemote) { + // The actual value doesn't matter as long as it's not empty. + // We only use it to discern QmldirInterceptedToRemote from QmldirNotFound above. + cache->qmldirPathUrl = QStringLiteral("intercepted"); + } + qmldirCache.insert(uri, cache); + + if (result == QmldirNotFound) { + qCDebug(lcQmlImport) + << "locateLocalQmldir:" << qPrintable(uri) << "module's qmldir file not found"; + } + } else { + qCDebug(lcQmlImport) + << "locateLocalQmldir:" << qPrintable(uri) << "module's qmldir found at" + << qmldirAbsoluteFilePath; + } + + return result; +} + void qmlClearEnginePlugins();// For internal use by qmlClearRegisteredProperties QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp index 7d4ffcec3fb..59f4bf296e6 100644 --- a/src/qml/qml/qqmlincubator.cpp +++ b/src/qml/qml/qqmlincubator.cpp @@ -269,6 +269,7 @@ void QQmlIncubatorPrivate::forceCompletion(QQmlInstantiationInterrupt &i) } } + void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i) { if (!compilationUnit) @@ -280,6 +281,20 @@ void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i) // get a copy of the engine pointer as it might get reset; QQmlEnginePrivate *enginePriv = this->enginePriv; + // Incubating objects takes quite a bit more stack space than our usual V4 function + enum { EstimatedSizeInV4Frames = 2 }; + QV4::ExecutionEngineCallDepthRecorder callDepthRecorder( + compilationUnit->engine); + if (callDepthRecorder.hasOverflow()) { + QQmlError error; + error.setMessageType(QtCriticalMsg); + error.setUrl(compilationUnit->url()); + error.setDescription(QQmlComponent::tr("Maximum call stack size exceeded.")); + errors << error; + progress = QQmlIncubatorPrivate::Completed; + goto finishIncubate; + } + if (!vmeGuard.isOK()) { QQmlError error; error.setMessageType(QtInfoMsg); diff --git a/src/qml/qml/qqmlirloader.cpp b/src/qml/qml/qqmlirloader.cpp index ee75a2b4f7e..c2d9aa941cf 100644 --- a/src/qml/qml/qqmlirloader.cpp +++ b/src/qml/qml/qqmlirloader.cpp @@ -101,10 +101,11 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali serializedObject->location); object->indexOfDefaultPropertyOrAlias = serializedObject->indexOfDefaultPropertyOrAlias; - object->defaultPropertyIsAlias = serializedObject->defaultPropertyIsAlias; - object->isInlineComponent = serializedObject->flags & QV4::CompiledData::Object::IsInlineComponentRoot; - object->flags = serializedObject->flags; - object->id = serializedObject->id; + object->defaultPropertyIsAlias = serializedObject->hasAliasAsDefaultProperty(); + object->isInlineComponent = serializedObject->hasFlag( + QV4::CompiledData::Object::IsInlineComponentRoot); + object->flags = serializedObject->flags(); + object->id = serializedObject->objectId(); object->locationOfIdProperty = serializedObject->locationOfIdProperty; QVector functionIndices; @@ -114,7 +115,7 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali QmlIR::Binding *b = pool->New(); *static_cast(b) = serializedObject->bindingTable()[i]; object->bindings->append(b); - if (b->type == QV4::CompiledData::Binding::Type_Script) { + if (b->type() == QV4::CompiledData::Binding::Type_Script) { functionIndices.append(b->value.compiledScriptIndex); b->value.compiledScriptIndex = functionIndices.count() - 1; diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 75bc944feed..d156862ea4b 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -129,8 +129,8 @@ QString QQmlJavaScriptExpression::expressionIdentifier() const { if (auto f = function()) { QString url = f->sourceFile(); - uint lineNumber = f->compiledFunction->location.line; - uint columnNumber = f->compiledFunction->location.column; + uint lineNumber = f->compiledFunction->location.line(); + uint columnNumber = f->compiledFunction->location.column(); return url + QString::asprintf(":%u:%u", lineNumber, columnNumber); } @@ -221,9 +221,6 @@ class QQmlJavaScriptExpressionCapture while (QQmlJavaScriptExpressionGuard *g = capture.guards.takeFirst()) g->Delete(); - if (!watcher.wasDeleted()) - capture.expression->setTranslationsCaptured(capture.translationCaptured); - ep->propertyCapture = lastPropertyCapture; } @@ -393,23 +390,52 @@ void QQmlPropertyCapture::captureProperty( captureNonBindableProperty(o, propertyData->notifyIndex(), propertyData->coreIndex(), doNotify); } +bool QQmlJavaScriptExpression::needsPropertyChangeTrigger(QObject *target, int propertyIndex) +{ + TriggerList **prev = &qpropertyChangeTriggers; + TriggerList *current = qpropertyChangeTriggers; + while (current) { + if (!current->target) { + *prev = current->next; + QRecyclePool::Delete(current); + current = *prev; + } else if (current->target == target && current->propertyIndex == propertyIndex) { + return false; // already installed + } else { + prev = ¤t->next; + current = current->next; + } + } + + return true; +} + +void QQmlPropertyCapture::captureTranslation() +{ + // use a unique invalid index to avoid needlessly querying the metaobject for + // the correct index of of the translationLanguage property + int const invalidIndex = -2; + if (expression->needsPropertyChangeTrigger(engine, invalidIndex)) { + auto trigger = expression->allocatePropertyChangeTrigger(engine, invalidIndex); + trigger->setSource(QQmlEnginePrivate::get(engine)->translationLanguage); + } +} + void QQmlPropertyCapture::captureBindableProperty( QObject *o, const QMetaObject *metaObjectForBindable, int c) { // if the property is a QPropery, and we're binding to a QProperty // the automatic capturing process already takes care of everything - if (typeid(QQmlPropertyBindingJS) == typeid(*expression)) + if (!expression->mustCaptureBindableProperty()) return; - for (auto trigger = expression->qpropertyChangeTriggers; trigger; - trigger = trigger->next) { - if (trigger->target == o && trigger->propertyIndex == c) - return; // already installed + + if (expression->needsPropertyChangeTrigger(o, c)) { + auto trigger = expression->allocatePropertyChangeTrigger(o, c); + QUntypedBindable bindable; + void *argv[] = { &bindable }; + metaObjectForBindable->metacall(o, QMetaObject::BindableProperty, c, argv); + bindable.observe(trigger); } - auto trigger = expression->allocatePropertyChangeTrigger(o, c); - QUntypedBindable bindable; - void *argv[] = { &bindable }; - metaObjectForBindable->metacall(o, QMetaObject::BindableProperty, c, argv); - bindable.observe(trigger); } void QQmlPropertyCapture::captureNonBindableProperty(QObject *o, int n, int c, bool doNotify) @@ -541,6 +567,16 @@ void QPropertyChangeTrigger::trigger(QPropertyObserver *observer, QUntypedProper This->m_expression->expressionChanged(); } +QMetaProperty QPropertyChangeTrigger::property() const +{ + if (!target) + return {}; + auto const mo = target->metaObject(); + if (!mo) + return {}; + return mo->property(propertyIndex); +} + QPropertyChangeTrigger *QQmlJavaScriptExpression::allocatePropertyChangeTrigger(QObject *target, int propertyIndex) { auto trigger = QQmlEnginePrivate::get(engine())->qPropertyTriggerPool.New( this ); diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h index 7a741afb75e..4edfeda6335 100644 --- a/src/qml/qml/qqmljavascriptexpression_p.h +++ b/src/qml/qml/qqmljavascriptexpression_p.h @@ -158,6 +158,7 @@ class Q_QML_PRIVATE_EXPORT QQmlJavaScriptExpression void clearError(); void clearActiveGuards(); QQmlDelayedError *delayedError(); + virtual bool mustCaptureBindableProperty() const {return true;} static QV4::ReturnedValue evalFunction( const QQmlRefPointer &ctxt, QObject *scope, const QString &code, @@ -165,6 +166,8 @@ class Q_QML_PRIVATE_EXPORT QQmlJavaScriptExpression QQmlEngine *engine() const { return m_context ? m_context->engine() : nullptr; } bool hasUnresolvedNames() const { return m_context && m_context->hasUnresolvedNames(); } + + bool needsPropertyChangeTrigger(QObject *target, int propertyIndex); QPropertyChangeTrigger *allocatePropertyChangeTrigger(QObject *target, int propertyIndex); protected: @@ -186,22 +189,12 @@ class Q_QML_PRIVATE_EXPORT QQmlJavaScriptExpression QForwardFieldList activeGuards; - void setTranslationsCaptured(bool captured) { - Tag newTag = captured ? TranslationsCaptured : NoTag; - if (m_error.tag() & InEvaluationLoop) - newTag = Tag(newTag | InEvaluationLoop); - m_error.setTag(newTag); - } - bool translationsCaptured() const { return m_error.tag() & TranslationsCaptured; } - enum Tag { NoTag, - TranslationsCaptured, InEvaluationLoop }; - // m_error:flag1 translationsCapturedDuringEvaluation - QTaggedPointer m_error; + QTaggedPointer m_error; private: friend class QQmlContextData; @@ -238,14 +231,13 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyCapture void captureProperty(QQmlNotifier *); void captureProperty(QObject *, int, int, bool doNotify = true); void captureProperty(QObject *, const QQmlPropertyCache *, const QQmlPropertyData *, bool doNotify = true); - void captureTranslation() { translationCaptured = true; } + void captureTranslation(); QQmlEngine *engine; QQmlJavaScriptExpression *expression; QQmlJavaScriptExpression::DeleteWatcher *watcher; QForwardFieldList guards; QStringList *errorString; - bool translationCaptured = false; private: void captureBindableProperty(QObject *o, const QMetaObject *metaObjectForBindable, int c); diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 3589dce3f0b..826ecfd1eab 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -703,7 +703,7 @@ ReturnedValue QQmlLocaleData::method_get_ ## VARIABLE (const QV4::FunctionObject LOCALE_STRING_PROPERTY(name) LOCALE_STRING_PROPERTY(nativeLanguageName) -LOCALE_STRING_PROPERTY(nativeCountryName) +QT_IGNORE_DEPRECATIONS(LOCALE_STRING_PROPERTY(nativeCountryName)) LOCALE_STRING_PROPERTY(decimalPoint) LOCALE_STRING_PROPERTY(groupSeparator) LOCALE_STRING_PROPERTY(percent) @@ -821,19 +821,17 @@ V4_DEFINE_EXTENSION(QV4LocaleDataDeletable, localeV4Data); can use the following enumeration values to specify the formatting of the string representation for a Date object. - \list - \li Locale.LongFormat The long version of day and month names; for - example, returning "January" as a month name. - \li Locale.ShortFormat The short version of day and month names; for - example, returning "Jan" as a month name. - \li Locale.NarrowFormat A special version of day and month names for - use when space is limited; for example, returning "J" as a month - name. Note that the narrow format might contain the same text for - different months and days or it can even be an empty string if the - locale doesn't support narrow names, so you should avoid using it - for date formatting. Also, for the system locale this format is - the same as ShortFormat. - \endlist + \value Locale.LongFormat The long version of day and month names; for + example, returning "January" as a month name. + \value Locale.ShortFormat The short version of day and month names; for + example, returning "Jan" as a month name. + \value Locale.NarrowFormat A special version of day and month names for + use when space is limited; for example, returning "J" as a month + name. Note that the narrow format might contain the same text for + different months and days or it can even be an empty string if the + locale doesn't support narrow names, so you should avoid using it + for date formatting. Also, for the system locale this format is + the same as ShortFormat. Additionally the double-to-string and string-to-double conversion functions are @@ -1055,15 +1053,13 @@ ReturnedValue QQmlLocale::method_localeCompare(const QV4::FunctionObject *b, con Holds the first day of the week according to the current locale. - \list - \li Locale.Sunday = 0 - \li Locale.Monday = 1 - \li Locale.Tuesday = 2 - \li Locale.Wednesday = 3 - \li Locale.Thursday = 4 - \li Locale.Friday = 5 - \li Locale.Saturday = 6 - \endlist + \value Locale.Sunday 0 + \value Locale.Monday 1 + \value Locale.Tuesday 2 + \value Locale.Wednesday 3 + \value Locale.Thursday 4 + \value Locale.Friday 5 + \value Locale.Saturday 6 \note that these values match the JS Date API which is different from the Qt C++ API where Qt::Sunday = 7. @@ -1094,10 +1090,9 @@ ReturnedValue QQmlLocale::method_localeCompare(const QV4::FunctionObject *b, con \qmlproperty enumeration QtQml::Locale::textDirection Holds the text direction of the language: - \list - \li Qt.LeftToRight - \li Qt.RightToLeft - \endlist + + \value Qt.LeftToRight Text normally begins at the left side. + \value Qt.RightToLeft Text normally begins at the right side. */ /*! @@ -1116,11 +1111,11 @@ ReturnedValue QQmlLocale::method_localeCompare(const QV4::FunctionObject *b, con \qmlmethod string QtQml::Locale::currencySymbol(format) Returns the currency symbol for the specified \a format: - \list - \li Locale.CurrencyIsoCode a ISO-4217 code of the currency. - \li Locale.CurrencySymbol a currency symbol. - \li Locale.CurrencyDisplayName a user readable name of the currency. - \endlist + + \value Locale.CurrencyIsoCode a ISO-4217 code of the currency. + \value Locale.CurrencySymbol a currency symbol. + \value Locale.CurrencyDisplayName a user readable name of the currency. + \sa Number::toLocaleCurrencyString() */ @@ -1147,16 +1142,13 @@ ReturnedValue QQmlLocale::method_localeCompare(const QV4::FunctionObject *b, con This property defines which units are used for measurement. - \list - \li Locale.MetricSystem This value indicates metric units, such as meters, - centimeters and millimeters. - \li Locale.ImperialUSSystem This value indicates imperial units, such as - inches and miles as they are used in the United States. - \li Locale.ImperialUKSystem This value indicates imperial units, such as - inches and miles as they are used in the United Kingdom. - \li Locale.ImperialSystem Provided for compatibility. The same as - Locale.ImperialUSSystem. - \endlist + \value Locale.MetricSystem This value indicates metric units, such as meters, + centimeters and millimeters. + \value Locale.ImperialUSSystem This value indicates imperial units, such as + inches and miles as they are used in the United States. + \value Locale.ImperialUKSystem This value indicates imperial units, such as + inches and miles as they are used in the United Kingdom. + \value Locale.ImperialSystem Provided for compatibility. The same as Locale.ImperialUSSystem. */ QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlloggingcategory.cpp b/src/qml/qml/qqmlloggingcategory.cpp index b59a26e17e1..98dfe62f0c0 100644 --- a/src/qml/qml/qqmlloggingcategory.cpp +++ b/src/qml/qml/qqmlloggingcategory.cpp @@ -129,7 +129,7 @@ void QQmlLoggingCategory::componentComplete() { m_initialized = true; if (m_name.isNull()) { - qmlWarning(this) << QLatin1String("Declaring the name of the LoggingCategory is mandatory and cannot be changed later !"); + qmlWarning(this) << QLatin1String("Declaring the name of a LoggingCategory is mandatory and cannot be changed later"); } else { QScopedPointer category(new QLoggingCategory(m_name.constData(), QtMsgType(m_defaultLogLevel))); m_category.swap(category); @@ -138,23 +138,30 @@ void QQmlLoggingCategory::componentComplete() void QQmlLoggingCategory::setDefaultLogLevel(DefaultLogLevel defaultLogLevel) { + if (m_defaultLogLevel == defaultLogLevel) + return; + if (m_initialized) { - qmlWarning(this) << QLatin1String("The defaultLogLevel of a LoggingCategory cannot be changed after the Item is created"); + qmlWarning(this) << QLatin1String("The defaultLogLevel of a LoggingCategory cannot be changed after the component is completed"); return; } m_defaultLogLevel = defaultLogLevel; } - void QQmlLoggingCategory::setName(const QString &name) { + const QByteArray newName = name.toUtf8(); + + if (m_name == newName) + return; + if (m_initialized) { - qmlWarning(this) << QLatin1String("The name of a LoggingCategory cannot be changed after the Item is created"); + qmlWarning(this) << QLatin1String("The name of a LoggingCategory cannot be changed after the component is completed"); return; } - m_name = name.toUtf8(); + m_name = newName; } #include "moc_qqmlloggingcategory_p.cpp" diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index e412263825c..80a7ca1e1ab 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -47,10 +47,6 @@ #include #include -#if QT_CONFIG(qml_itemmodel) -#include -#endif - #include #include #include @@ -230,7 +226,8 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el } void QQmlMetaType::clone(QMetaObjectBuilder &builder, const QMetaObject *mo, - const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd) + const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd, + QQmlMetaType::ClonePolicy policy) { // Set classname builder.setClassName(ignoreEnd->className()); @@ -247,44 +244,45 @@ void QQmlMetaType::clone(QMetaObjectBuilder &builder, const QMetaObject *mo, } } - // Clone Q_PROPERTY - for (int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) { - QMetaProperty property = mo->property(ii); + if (policy != QQmlMetaType::CloneEnumsOnly) { + // Clone Q_METHODS - do this first to avoid duplicating the notify signals. + for (int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) { + QMetaMethod method = mo->method(ii); - int otherIndex = ignoreEnd->indexOfProperty(property.name()); - if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) { - builder.addProperty(QByteArray("__qml_ignore__") + property.name(), QByteArray("void")); - // Skip - } else { - builder.addProperty(property); - } - } + // More complex - need to search name + QByteArray name = method.name(); - // Clone Q_METHODS - for (int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) { - QMetaMethod method = mo->method(ii); + bool found = false; - // More complex - need to search name - QByteArray name = method.name(); + for (int ii = ignoreStart->methodOffset() + ignoreStart->methodCount(); + !found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount(); ++ii) { + QMetaMethod other = ignoreEnd->method(ii); - bool found = false; + found = name == other.name(); + } - for (int ii = ignoreStart->methodOffset() + ignoreStart->methodCount(); - !found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount(); - ++ii) { + QMetaMethodBuilder m = builder.addMethod(method); + if (found) // SKIP + m.setAccess(QMetaMethod::Private); + } - QMetaMethod other = ignoreEnd->method(ii); + // Clone Q_PROPERTY + for (int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) { + QMetaProperty property = mo->property(ii); - found = name == other.name(); + int otherIndex = ignoreEnd->indexOfProperty(property.name()); + if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) { + builder.addProperty(QByteArray("__qml_ignore__") + property.name(), + QByteArray("void")); + // Skip + } else { + builder.addProperty(property); + } } - - QMetaMethodBuilder m = builder.addMethod(method); - if (found) // SKIP - m.setAccess(QMetaMethod::Private); } - // Clone Q_ENUMS + // Clone enums registered with the metatype system for (int ii = mo->enumeratorOffset(); ii < mo->enumeratorCount(); ++ii) { QMetaEnum enumerator = mo->enumerator(ii); @@ -339,6 +337,10 @@ void QQmlMetaType::clearTypeRegistrations() data->urlToNonFileImportType.clear(); data->metaObjectToType.clear(); data->undeletableTypes.clear(); + + for (auto it = data->propertyCaches.begin(), end = data->propertyCaches.end(); it != end; ++it) + (*it)->release(); + data->propertyCaches.clear(); } int QQmlMetaType::registerAutoParentFunction(const QQmlPrivate::RegisterAutoParent &function) @@ -431,7 +433,7 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da if (uri && !typeName.isEmpty()) { QString nameSpace = QString::fromUtf8(uri); QQmlTypeModule *qqtm = data->findTypeModule(nameSpace, version); - if (qqtm && qqtm->isLocked()) { + if (qqtm && qqtm->lockLevel() != QQmlTypeModule::LockLevel::Open) { QString failure(QCoreApplication::translate( "qmlRegisterType", "Cannot install %1 '%2' into protected module '%3' version '%4'")); @@ -588,12 +590,14 @@ void QQmlMetaType::unregisterInternalCompositeType(const CompositeMetaTypeIds &t QMetaType metaType(typeIds.id); QMetaType listMetaType(typeIds.listId); + // This may be called from delayed dtors on shutdown when the data is already gone. QQmlMetaTypeDataPtr data; - - if (QQmlValueType *vt = data->metaTypeToValueType.take(metaType.id())) - delete vt; - if (QQmlValueType *vt = data->metaTypeToValueType.take(listMetaType.id())) - delete vt; + if (data.isValid()) { + if (QQmlValueType *vt = data->metaTypeToValueType.take(metaType.id())) + delete vt; + if (QQmlValueType *vt = data->metaTypeToValueType.take(listMetaType.id())) + delete vt; + } QMetaType::unregisterMetaType(metaType); QMetaType::unregisterMetaType(listMetaType); @@ -645,18 +649,19 @@ void QQmlMetaType::unregisterSequentialContainer(int id) unregisterType(id); } -bool QQmlMetaType::protectModule(const QString &uri, QTypeRevision version, bool protectAllVersions) +bool QQmlMetaType::protectModule(const QString &uri, QTypeRevision version, + bool weakProtectAllVersions) { QQmlMetaTypeDataPtr data; if (version.hasMajorVersion()) { - if (QQmlTypeModule *module = data->findTypeModule(uri, version)) { - if (!protectAllVersions) { - module->lock(); - return true; + if (QQmlTypeModule *module = data->findTypeModule(uri, version)) { + if (!weakProtectAllVersions) { + module->setLockLevel(QQmlTypeModule::LockLevel::Strong); + return true; + } + } else { + return false; } - } else { - return false; - } } const auto range = std::equal_range( @@ -664,7 +669,7 @@ bool QQmlMetaType::protectModule(const QString &uri, QTypeRevision version, bool std::less()); for (auto it = range.first; it != range.second; ++it) - (*it)->lock(); + (*it)->setLockLevel(QQmlTypeModule::LockLevel::Weak); return range.first != range.second; } @@ -981,12 +986,12 @@ QTypeRevision QQmlMetaType::latestModuleVersion(const QString &uri) /* Returns true if a module \a uri of this version is installed and locked; */ -bool QQmlMetaType::isLockedModule(const QString &uri, QTypeRevision version) +bool QQmlMetaType::isStronglyLockedModule(const QString &uri, QTypeRevision version) { QQmlMetaTypeDataPtr data; if (QQmlTypeModule* qqtm = data->findTypeModule(uri, version)) - return qqtm->isLocked(); + return qqtm->lockLevel() == QQmlTypeModule::LockLevel::Strong; return false; } @@ -1522,7 +1527,8 @@ QList QQmlMetaType::proxyData(const QMetaObject return; QMetaObjectBuilder builder; - clone(builder, extMetaObject, superdataBaseMetaObject, baseMetaObject); + clone(builder, extMetaObject, superdataBaseMetaObject, baseMetaObject, + extFunc ? QQmlMetaType::CloneAll : QQmlMetaType::CloneEnumsOnly); builder.setFlags(MetaObjectFlag::DynamicMetaObject); QMetaObject *mmo = builder.toMetaObject(); mmo->d.superdata = baseMetaObject; @@ -1597,18 +1603,8 @@ const QMetaObject *QQmlMetaType::metaObjectForValueType(QMetaType metaType) #if QT_CONFIG(easingcurve) case QMetaType::QEasingCurve: return &QQmlEasingValueType::staticMetaObject; -#endif -#if QT_CONFIG(qml_itemmodel) - case QMetaType::QModelIndex: - return &QQmlModelIndexValueType::staticMetaObject; - case QMetaType::QPersistentModelIndex: - return &QQmlPersistentModelIndexValueType::staticMetaObject; #endif default: -#if QT_CONFIG(qml_itemmodel) - if (metaType == QMetaType::fromType()) - return &QQmlItemSelectionRangeValueType::staticMetaObject; -#endif break; } diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 7ee16f9dc94..dc08263511f 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -147,7 +147,7 @@ class Q_QML_PRIVATE_EXPORT QQmlMetaType static void registerModule(const char *uri, QTypeRevision version); static bool protectModule(const QString &uri, QTypeRevision version, - bool protectAllVersions = false); + bool weakProtectAllVersions = false); static void registerModuleImport(const QString &uri, QTypeRevision version, const QQmlDirParser::Import &import); @@ -197,7 +197,7 @@ class Q_QML_PRIVATE_EXPORT QQmlMetaType static bool isList(QMetaType type); static QTypeRevision latestModuleVersion(const QString &uri); - static bool isLockedModule(const QString &uri, QTypeRevision version); + static bool isStronglyLockedModule(const QString &uri, QTypeRevision version); static QTypeRevision matchingModuleVersion(const QString &module, QTypeRevision version); static QQmlTypeModule *typeModule(const QString &uri, QTypeRevision version); @@ -245,8 +245,13 @@ class Q_QML_PRIVATE_EXPORT QQmlMetaType const QMetaObject *baseMetaObject, QMetaObject *lastMetaObject); + enum ClonePolicy { + CloneAll, // default + CloneEnumsOnly, // skip properties and methods + }; static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, - const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd); + const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd, + ClonePolicy policy); static void qmlInsertModuleRegistration(const QString &uri, void (*registerFunction)()); static void qmlRemoveModuleRegistration(const QString &uri); diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp index 71901e23fec..6b21e233495 100644 --- a/src/qml/qml/qqmlmetatypedata.cpp +++ b/src/qml/qml/qqmlmetatypedata.cpp @@ -145,8 +145,9 @@ QQmlRefPointer QQmlMetaTypeData::propertyCache(const QMetaObj return rv; if (!metaObject->superClass()) { - QQmlPropertyCache *rv = new QQmlPropertyCache(metaObject); - propertyCaches.insert(metaObject, rv); + QQmlRefPointer rv = QQmlPropertyCache::createStandalone(metaObject); + rv->addref(); // extra ref for the propertyCaches storage + propertyCaches.insert(metaObject, rv.data()); return rv; } auto super = propertyCache(metaObject->superClass(), version); diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index c0cc917499b..b5448529531 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -168,13 +168,16 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI phase = CreatingObjects; int objectToCreate; + bool isComponentRoot = false; // either a "real" component of or an inline component if (subComponentIndex == -1) { objectToCreate = /*root object*/0; + isComponentRoot = true; } else { Q_ASSERT(subComponentIndex >= 0); if (flags & CreationFlags::InlineComponent) { objectToCreate = subComponentIndex; + isComponentRoot = true; } else { Q_ASSERT(flags & CreationFlags::NormalObject); const QV4::CompiledData::Object *compObj = compilationUnit->objectAt(subComponentIndex); @@ -199,7 +202,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI if (topLevelCreator) sharedState->allJavaScriptObjects = scope.alloc(compilationUnit->totalObjectCount()); - if (subComponentIndex == -1 && compilationUnit->dependentScripts.count()) { + if (isComponentRoot && compilationUnit->dependentScripts.count()) { QV4::ScopedObject scripts(scope, v4->newArrayObject(compilationUnit->dependentScripts.count())); context->setImportedScripts(QV4::PersistentValue(v4, scripts.asReturnedValue())); QV4::ScopedValue v(scope); @@ -290,7 +293,7 @@ void QQmlObjectCreator::populateDeferred(QObject *instance, int deferredIndex, if (binding) { Q_ASSERT(qmlProperty); - Q_ASSERT(binding->flags & QV4::CompiledData::Binding::IsDeferredBinding); + Q_ASSERT(binding->hasFlag(QV4::CompiledData::Binding::IsDeferredBinding)); QQmlListProperty savedList; qSwap(_currentList, savedList); @@ -352,7 +355,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const int propertyType = property->propType().id(); if (property->isEnum()) { - if (binding->flags & QV4::CompiledData::Binding::IsResolvedEnum) { + if (binding->hasFlag(QV4::CompiledData::Binding::IsResolvedEnum)) { propertyType = QMetaType::Int; } else { // ### This should be resolved earlier at compile time and the binding value should be changed accordingly. @@ -366,18 +369,18 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const auto assertOrNull = [&](bool ok) { - Q_ASSERT(ok || binding->type == QV4::CompiledData::Binding::Type_Null); + Q_ASSERT(ok || binding->type() == QV4::CompiledData::Binding::Type_Null); Q_UNUSED(ok); }; - auto assertType = [&](QV4::CompiledData::Binding::ValueType type) + auto assertType = [&](QV4::CompiledData::Binding::Type type) { - Q_ASSERT(binding->type == type || binding->type == QV4::CompiledData::Binding::Type_Null); + Q_ASSERT(binding->type()== type || binding->type() == QV4::CompiledData::Binding::Type_Null); Q_UNUSED(type); }; if (property->isQObject()) { - if (binding->type == QV4::CompiledData::Binding::Type_Null) { + if (binding->type() == QV4::CompiledData::Binding::Type_Null) { QObject *value = nullptr; const bool ok = property->writeProperty(_qobject, &value, propertyWriteFlags); Q_ASSERT(ok); @@ -388,7 +391,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const switch (propertyType) { case QMetaType::QVariant: { - if (binding->type == QV4::CompiledData::Binding::Type_Number) { + if (binding->type() == QV4::CompiledData::Binding::Type_Number) { double n = compilationUnit->bindingValueAsNumber(binding); if (double(int(n)) == n) { if (property->isVarProperty()) { @@ -406,14 +409,14 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const property->writeProperty(_qobject, &value, propertyWriteFlags); } } - } else if (binding->type == QV4::CompiledData::Binding::Type_Boolean) { + } else if (binding->type() == QV4::CompiledData::Binding::Type_Boolean) { if (property->isVarProperty()) { _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::fromBoolean(binding->valueAsBoolean())); } else { QVariant value(binding->valueAsBoolean()); property->writeProperty(_qobject, &value, propertyWriteFlags); } - } else if (binding->type == QV4::CompiledData::Binding::Type_Null) { + } else if (binding->type() == QV4::CompiledData::Binding::Type_Null) { if (property->isVarProperty()) { _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::nullValue()); } else { @@ -453,7 +456,9 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const case QMetaType::QUrl: { assertType(QV4::CompiledData::Binding::Type_String); const QString string = compilationUnit->bindingValueAsString(binding); - QUrl value(string); + QUrl value = (!string.isEmpty() && QQmlPropertyPrivate::resolveUrlsOnAssignment()) + ? compilationUnit->finalUrl().resolved(QUrl(string)) + : QUrl(string); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; @@ -600,7 +605,12 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; } else if (propertyType == qMetaTypeId >()) { assertType(QV4::CompiledData::Binding::Type_String); - QList value { QUrl(compilationUnit->bindingValueAsString(binding)) }; + const QUrl url(compilationUnit->bindingValueAsString(binding)); + QList value { + QQmlPropertyPrivate::resolveUrlsOnAssignment() + ? compilationUnit->finalUrl().resolved(url) + : url + }; property->writeProperty(_qobject, &value, propertyWriteFlags); break; } else if (propertyType == qMetaTypeId >()) { @@ -611,18 +621,24 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; } else if (propertyType == qMetaTypeId()) { QJSValue value; - if (binding->type == QV4::CompiledData::Binding::Type_Boolean) { + switch (binding->type()) { + case QV4::CompiledData::Binding::Type_Boolean: value = QJSValue(binding->valueAsBoolean()); - } else if (binding->type == QV4::CompiledData::Binding::Type_Number) { - double n = compilationUnit->bindingValueAsNumber(binding); - if (double(int(n)) == n) { + break; + case QV4::CompiledData::Binding::Type_Number: { + const double n = compilationUnit->bindingValueAsNumber(binding); + if (double(int(n)) == n) value = QJSValue(int(n)); - } else + else value = QJSValue(n); - } else if (binding->type == QV4::CompiledData::Binding::Type_Null) { + break; + } + case QV4::CompiledData::Binding::Type_Null: value = QJSValue::NullValue; - } else { + break; + default: value = QJSValue(compilationUnit->bindingValueAsString(binding)); + break; } property->writeProperty(_qobject, &value, propertyWriteFlags); break; @@ -662,8 +678,8 @@ void QQmlObjectCreator::setupBindings(bool applyDeferredBindings) if (idProperty && idProperty->isValid() && idProperty->isWritable() && idProperty->propType().id() == QMetaType::QString) { QV4::CompiledData::Binding idBinding; idBinding.propertyNameIndex = 0; // Not used - idBinding.flags = 0; - idBinding.type = QV4::CompiledData::Binding::Type_String; + idBinding.clearFlags(); + idBinding.setType(QV4::CompiledData::Binding::Type_String); idBinding.stringIndex = _compiledObject->idNameIndex; idBinding.location = _compiledObject->location; // ### setPropertyValue(idProperty, &idBinding); @@ -718,10 +734,10 @@ void QQmlObjectCreator::setupBindings(bool applyDeferredBindings) } - if (binding->flags & QV4::CompiledData::Binding::IsCustomParserBinding) + if (binding->hasFlag(QV4::CompiledData::Binding::IsCustomParserBinding)) continue; - if (binding->flags & QV4::CompiledData::Binding::IsDeferredBinding) { + if (binding->hasFlag(QV4::CompiledData::Binding::IsDeferredBinding)) { if (!applyDeferredBindings) continue; } else { @@ -778,7 +794,8 @@ void QQmlObjectCreator::setupBindings(bool applyDeferredBindings) bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProperty, const QV4::CompiledData::Binding *binding) { - if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { + const QV4::CompiledData::Binding::Type bindingType = binding->type(); + if (bindingType == QV4::CompiledData::Binding::Type_AttachedProperty) { Q_ASSERT(stringAt(compilationUnit->objectAt(binding->value.objectIndex)->inheritedTypeNameIndex).isEmpty()); QV4::ResolvedTypeReference *tr = resolvedType(binding->propertyNameIndex); Q_ASSERT(tr); @@ -793,7 +810,15 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper } QObject *qmlObject = qmlAttachedPropertiesObject( _qobject, attachedType.attachedPropertiesFunction(QQmlEnginePrivate::get(engine))); - if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject, /*value type property*/nullptr)) + if (!qmlObject) { + recordError(binding->location, + QStringLiteral("Could not create attached properties object '%1'") + .arg(QString::fromUtf8(attachedType.typeName()))); + return false; + } + + if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject, + /*value type property*/ nullptr, binding)) return false; return true; } @@ -802,11 +827,11 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper if (bindingProperty && bindingProperty->propType() == QMetaType::fromType()) { QQmlScriptString ss(compilationUnit->bindingValueAsScriptString(binding), context->asQQmlContext(), _scopeObject); - ss.d.data()->bindingId = binding->type == QV4::CompiledData::Binding::Type_Script ? binding->value.compiledScriptIndex : (quint32)QQmlBinding::Invalid; - ss.d.data()->lineNumber = binding->location.line; - ss.d.data()->columnNumber = binding->location.column; - ss.d.data()->isStringLiteral = binding->type == QV4::CompiledData::Binding::Type_String; - ss.d.data()->isNumberLiteral = binding->type == QV4::CompiledData::Binding::Type_Number; + ss.d.data()->bindingId = bindingType == QV4::CompiledData::Binding::Type_Script ? binding->value.compiledScriptIndex : (quint32)QQmlBinding::Invalid; + ss.d.data()->lineNumber = binding->location.line(); + ss.d.data()->columnNumber = binding->location.column(); + ss.d.data()->isStringLiteral = bindingType == QV4::CompiledData::Binding::Type_String; + ss.d.data()->isNumberLiteral = bindingType == QV4::CompiledData::Binding::Type_Number; ss.d.data()->numberValue = compilationUnit->bindingValueAsNumber(binding); QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | @@ -818,7 +843,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper } QObject *createdSubObject = nullptr; - if (binding->type == QV4::CompiledData::Binding::Type_Object) { + if (bindingType == QV4::CompiledData::Binding::Type_Object) { createdSubObject = createInstance(binding->value.objectIndex, _bindingTarget); if (!createdSubObject) return false; @@ -827,7 +852,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper if (!bindingProperty) // ### error return true; - if (binding->type == QV4::CompiledData::Binding::Type_GroupProperty) { + if (bindingType == QV4::CompiledData::Binding::Type_GroupProperty) { const QV4::CompiledData::Object *obj = compilationUnit->objectAt(binding->value.objectIndex); if (stringAt(obj->inheritedTypeNameIndex).isEmpty()) { @@ -858,7 +883,8 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper bindingTarget = groupObject; } - if (!populateInstance(binding->value.objectIndex, groupObject, bindingTarget, valueTypeProperty)) + if (!populateInstance(binding->value.objectIndex, groupObject, bindingTarget, + valueTypeProperty, binding)) return false; if (valueType) @@ -868,14 +894,25 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper } } - if (_ddata->hasBindingBit(bindingProperty->coreIndex()) && !(binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) - && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment) - && !_valueTypeProperty) - QQmlPropertyPrivate::removeBinding(_bindingTarget, QQmlPropertyIndex(bindingProperty->coreIndex())); + const QV4::CompiledData::Binding::Flags bindingFlags = binding->flags(); + const bool allowedToRemoveBinding + = !(bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerExpression) + && !(bindingFlags & QV4::CompiledData::Binding::IsOnAssignment) + && !(bindingFlags & QV4::CompiledData::Binding::IsPropertyObserver) + && !_valueTypeProperty; + + if (allowedToRemoveBinding) { + if (bindingProperty->isBindable()) { + removePendingBinding(_bindingTarget, bindingProperty->coreIndex()); + } else { + QQmlPropertyPrivate::removeBinding( + _bindingTarget, QQmlPropertyIndex(bindingProperty->coreIndex())); + } + } - if (binding->type == QV4::CompiledData::Binding::Type_Script || binding->isTranslationBinding()) { - if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression - || binding->flags & QV4::CompiledData::Binding::IsPropertyObserver) { + if (bindingType == QV4::CompiledData::Binding::Type_Script || binding->isTranslationBinding()) { + if (bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerExpression + || bindingFlags & QV4::CompiledData::Binding::IsPropertyObserver) { QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex]; int signalIndex = _propertyCache->methodIndexToSignalIndex(bindingProperty->coreIndex()); QQmlBoundSignalExpression *expr = new QQmlBoundSignalExpression( @@ -915,7 +952,10 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper QQmlPropertyIndex index(bindingProperty->coreIndex(), -1); qmlBinding = QQmlPropertyBinding::create(bindingProperty, runtimeFunction, _scopeObject, context, currentQmlContext(), _bindingTarget, index); } - sharedState.data()->allQPropertyBindings.emplaceBack(_bindingTarget, bindingProperty->coreIndex(), qmlBinding); + sharedState.data()->allQPropertyBindings.push_back(DeferredQPropertyBinding {_bindingTarget, bindingProperty->coreIndex(), qmlBinding }); + + QQmlData *data = QQmlData::get(_bindingTarget, true); + data->setBindingBit(_bindingTarget, bindingProperty->coreIndex()); } else { // When writing bindings to grouped properties implemented as value types, // such as point.x: { someExpression; }, then the binding is installed on @@ -966,8 +1006,8 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper return true; } - if (binding->type == QV4::CompiledData::Binding::Type_Object) { - if (binding->flags & QV4::CompiledData::Binding::IsOnAssignment) { + if (bindingType == QV4::CompiledData::Binding::Type_Object) { + if (bindingFlags & QV4::CompiledData::Binding::IsOnAssignment) { // ### determine value source and interceptor casts ahead of time. QQmlType type = qmlTypeForObject(createdSubObject); Q_ASSERT(type.isValid()); @@ -1031,7 +1071,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper } // Assigning object to signal property? ### Qt 7: Remove that functionality - if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject) { + if (bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerObject) { if (!bindingProperty->isFunction()) { recordError(binding->valueLocation, tr("Cannot assign an object to signal property %1").arg(bindingProperty->name(_qobject))); return false; @@ -1156,16 +1196,16 @@ void QQmlObjectCreator::recordError(const QV4::CompiledData::Location &location, { QQmlError error; error.setUrl(compilationUnit->url()); - error.setLine(qmlConvertSourceCoordinate(location.line)); - error.setColumn(qmlConvertSourceCoordinate(location.column)); + error.setLine(qmlConvertSourceCoordinate(location.line())); + error.setColumn(qmlConvertSourceCoordinate(location.column())); error.setDescription(description); errors << error; } void QQmlObjectCreator::registerObjectWithContextById(const QV4::CompiledData::Object *object, QObject *instance) const { - if (object->id >= 0) - context->setIdValue(object->id, instance); + if (object->objectId() >= 0) + context->setIdValue(object->objectId(), instance); } QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject) @@ -1185,7 +1225,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo QQmlParserStatus *parserStatus = nullptr; bool installPropertyCache = true; - if (obj->flags & QV4::CompiledData::Object::IsComponent) { + if (obj->hasFlag(QV4::CompiledData::Object::IsComponent)) { isComponent = true; QQmlComponent *component = new QQmlComponent(engine, compilationUnit.data(), index, parent); typeName = QStringLiteral(""); @@ -1275,13 +1315,13 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo compilationUnit.data(), obj, typeName, context->url())); Q_UNUSED(typeName); // only relevant for tracing - ddata->lineNumber = obj->location.line; - ddata->columnNumber = obj->location.column; + ddata->lineNumber = obj->location.line(); + ddata->columnNumber = obj->location.column(); ddata->setImplicitDestructible(); // inline components are root objects, but their index is != 0, so we need // an additional check - const bool isInlineComponent = obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot; + const bool isInlineComponent = obj->hasFlag(QV4::CompiledData::Object::IsInlineComponentRoot); if (static_cast(index) == /*root object*/0 || ddata->rootObjectInCreation || isInlineComponent) { if (ddata->context) { Q_ASSERT(ddata->context != context.data()); @@ -1315,7 +1355,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo if (isContextObject) context->setContextObject(instance); - if (customParser && obj->flags & QV4::CompiledData::Object::HasCustomParserBindings) { + if (customParser && obj->hasFlag(QV4::CompiledData::Object::HasCustomParserBindings)) { customParser->engine = QQmlEnginePrivate::get(engine); customParser->imports = compilationUnit->typeNameCache.data(); @@ -1323,9 +1363,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo const QV4::CompiledData::Object *obj = compilationUnit->objectAt(index); const QV4::CompiledData::Binding *binding = obj->bindingTable(); for (quint32 i = 0; i < obj->nBindings; ++i, ++binding) { - if (binding->flags & QV4::CompiledData::Binding::IsCustomParserBinding) { + if (binding->hasFlag(QV4::CompiledData::Binding::IsCustomParserBinding)) bindings << binding; - } } customParser->applyBindings(instance, compilationUnit.data(), bindings); @@ -1434,20 +1473,38 @@ bool QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt) while (!sharedState->allQPropertyBindings.isEmpty()) { auto& [target, index, qmlBinding] = sharedState->allQPropertyBindings.first(); + + QQmlData *data = QQmlData::get(target); + if (!data || !data->hasBindingBit(index)) { + // The target property has been overwritten since we stashed the binding. + sharedState->allQPropertyBindings.pop_front(); + continue; + } + QUntypedBindable bindable; void *argv[] = { &bindable }; // allow interception target->metaObject()->metacall(target, QMetaObject::BindableProperty, index, argv); - bindable.setBinding(qmlBinding); + const bool success = bindable.setBinding(qmlBinding); + + const auto bindingPrivateRefCount = QPropertyBindingPrivate::get(qmlBinding)->ref; + + // Only pop_front after setting the binding as the bindings are refcounted. sharedState->allQPropertyBindings.pop_front(); - if (auto priv = QPropertyBindingPrivate::get(qmlBinding); priv->hasCustomVTable()) { - auto qmlBindingPriv = static_cast(priv); - auto jsExpression = qmlBindingPriv->jsExpression(); - const bool canRemove = !qmlBinding.error().hasError() && !qmlBindingPriv->hasDependencies() - && !jsExpression->hasUnresolvedNames(); - if (canRemove) - bindable.takeBinding(); + + // If the binding was actually not set, it's deleted now. + if (success && bindingPrivateRefCount > 1) { + if (auto priv = QPropertyBindingPrivate::get(qmlBinding); priv->hasCustomVTable()) { + auto qmlBindingPriv = static_cast(priv); + auto jsExpression = qmlBindingPriv->jsExpression(); + const bool canRemove = !qmlBinding.error().hasError() + && !qmlBindingPriv->hasDependencies() + && !jsExpression->hasUnresolvedNames(); + if (canRemove) + bindable.takeBinding(); + } } + if (watcher.hasRecursed() || interrupt.shouldInterrupt()) return false; } @@ -1519,8 +1576,11 @@ void QQmlObjectCreator::clear() phase = Done; } -bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *bindingTarget, const QQmlPropertyData *valueTypeProperty) +bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *bindingTarget, + const QQmlPropertyData *valueTypeProperty, + const QV4::CompiledData::Binding *binding) { + Q_ASSERT(instance); QQmlData *declarativeData = QQmlData::get(instance, /*create*/true); qSwap(_qobject, instance); @@ -1555,9 +1615,10 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * qSwap(_propertyCache, cache); qSwap(_vmeMetaObject, vmeMetaObject); - if (_compiledObject->flags & QV4::CompiledData::Object::HasDeferredBindings) + if (_compiledObject->hasFlag(QV4::CompiledData::Object::HasDeferredBindings)) _ddata->deferData(_compiledObjectIndex, compilationUnit, context); + const qsizetype oldRequiredPropertiesCount = sharedState->requiredProperties.size(); QSet postHocRequired; for (auto it = _compiledObject->requiredPropertyExtraDataBegin(); it != _compiledObject->requiredPropertyExtraDataEnd(); ++it) postHocRequired.insert(stringAt(it->nameIndex)); @@ -1568,7 +1629,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * QQmlPropertyData *propertyData = _propertyCache->property(_propertyCache->propertyOffset() + propertyIndex); // only compute stringAt if there's a chance for the lookup to succeed auto postHocIt = postHocRequired.isEmpty() ? postHocRequired.end() : postHocRequired.find(stringAt(property->nameIndex)); - if (!property->isRequired && postHocRequired.end() == postHocIt) + if (!property->isRequired() && postHocRequired.end() == postHocIt) continue; if (postHocIt != postHocRequired.end()) postHocRequired.erase(postHocIt); @@ -1578,10 +1639,48 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * } - for (int i = 0; i <= _propertyCache->propertyOffset(); ++i) { + const auto getPropertyCacheRange = [&]() -> std::pair { + // the logic in a nutshell: we work with QML instances here. every + // instance has a QQmlType: + // * if QQmlType is valid && not an inline component, it's a C++ type + // * otherwise, it's a QML-defined type (a.k.a. Composite type), where + // invalid type == "comes from another QML document" + // + // 1. if the type we inherit from comes from C++, we must check *all* + // properties in the property cache so far - since we can have + // required properties defined in C++ + // 2. otherwise - the type comes from QML, it's enough to check just + // *own* properties in the property cache, because there's a previous + // type in the hierarchy that has checked the C++ properties (via 1.) + // 3. required attached properties are explicitly not supported. to + // achieve that, go through all its properties + // 4. required group properties: the group itself is covered by 1. + // required sub-properties are not properly handled (QTBUG-96544), so + // just return the old range here for consistency + QV4::ResolvedTypeReference *typeRef = resolvedType(_compiledObject->inheritedTypeNameIndex); + if (!typeRef) { // inside a binding on attached/group property + Q_ASSERT(binding); + if (binding->isAttachedProperty()) + return { 0, _propertyCache->propertyCount() }; // 3. + Q_ASSERT(binding->isGroupProperty()); + return { 0, _propertyCache->propertyOffset() + 1 }; // 4. + } + Q_ASSERT(!_compiledObject->hasFlag(QV4::CompiledData::Object::IsComponent)); + QQmlType type = typeRef->type(); + if (type.isValid() && !type.isInlineComponentType()) { + return { 0, _propertyCache->propertyCount() }; // 1. + } + // Q_ASSERT(type.isComposite()); + return { _propertyCache->propertyOffset(), _propertyCache->propertyCount() }; // 2. + }; + const auto [offset, count] = getPropertyCacheRange(); + for (int i = offset; i < count; ++i) { QQmlPropertyData *propertyData = _propertyCache->maybeUnresolvedProperty(i); if (!propertyData) continue; + // TODO: the property might be a group property (in which case we need + // to dive into its sub-properties and check whether there are any + // required elements there) - QTBUG-96544 if (!propertyData->isRequired() && postHocRequired.isEmpty()) continue; QString name = propertyData->name(_qobject); @@ -1593,8 +1692,43 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * postHocRequired.erase(postHocIt); sharedState->hadRequiredProperties = true; - sharedState->requiredProperties.insert(propertyData, RequiredPropertyInfo {name, compilationUnit->finalUrl(), _compiledObject->location, {}}); + sharedState->requiredProperties.insert( + propertyData, + RequiredPropertyInfo { + name, compilationUnit->finalUrl(), _compiledObject->location, {} }); + } + + if (binding && binding->isAttachedProperty() + && sharedState->requiredProperties.size() != oldRequiredPropertiesCount) { + recordError( + binding->location, + QLatin1String("Attached property has required properties. This is not supported")); + } + + // Note: there's a subtle case with the above logic: if we process a random + // QML-defined leaf type, it could have a required attribute overwrite on an + // *existing* property: `import QtQuick; Text { required text }`. in this + // case, we must add the property to a required list + if (!postHocRequired.isEmpty()) { + // NB: go through [0, offset) range as [offset, count) is already done + for (int i = 0; i < offset; ++i) { + QQmlPropertyData *propertyData = _propertyCache->maybeUnresolvedProperty(i); + if (!propertyData) + continue; + QString name = propertyData->name(_qobject); + auto postHocIt = postHocRequired.find(name); + if (postHocRequired.end() == postHocIt) + continue; + postHocRequired.erase(postHocIt); + + sharedState->hadRequiredProperties = true; + sharedState->requiredProperties.insert( + propertyData, + RequiredPropertyInfo { + name, compilationUnit->finalUrl(), _compiledObject->location, {} }); + } } + if (!postHocRequired.isEmpty() && hadInheritedRequiredProperties) recordError({}, QLatin1String("Property %1 was marked as required but does not exist").arg(*postHocRequired.begin())); @@ -1605,12 +1739,12 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * for (int aliasIndex = 0; aliasIndex != _compiledObject->aliasCount(); ++aliasIndex) { const QV4::CompiledData::Alias* alias = _compiledObject->aliasesBegin() + aliasIndex; const auto originalAlias = alias; - while (alias->aliasToLocalAlias) + while (alias->isAliasToLocalAlias()) alias = _compiledObject->aliasesBegin() + alias->localAliasIndex; - Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved); + Q_ASSERT(alias->hasFlag(QV4::CompiledData::Alias::Resolved)); if (!context->isIdValueSet(0)) // TODO: Do we really want 0 here? continue; - QObject *target = context->idValue(alias->targetObjectId); + QObject *target = context->idValue(alias->targetObjectId()); if (!target) continue; QQmlData *targetDData = QQmlData::get(target, /*create*/false); @@ -1622,7 +1756,11 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * continue; auto it = sharedState->requiredProperties.find(targetProperty); if (it != sharedState->requiredProperties.end()) - it->aliasesToRequired.push_back(AliasToRequiredInfo {compilationUnit->stringAt(originalAlias->nameIndex), compilationUnit->finalUrl()}); + it->aliasesToRequired.push_back( + AliasToRequiredInfo { + compilationUnit->stringAt(originalAlias->nameIndex()), + compilationUnit->finalUrl() + }); } qSwap(_vmeMetaObject, vmeMetaObject); diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 1881b3eb23d..26db10a11f9 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -89,6 +89,12 @@ struct RequiredPropertyInfo class RequiredProperties : public QHash {}; +struct DeferredQPropertyBinding { + QObject *target = nullptr; + int properyIndex = -1; + QUntypedPropertyBinding binding; +}; + struct QQmlObjectCreatorSharedState : QQmlRefCount { QQmlRefPointer rootContext; @@ -102,7 +108,7 @@ struct QQmlObjectCreatorSharedState : QQmlRefCount QQmlVmeProfiler profiler; QRecursionNode recursionNode; RequiredProperties requiredProperties; - QList> allQPropertyBindings; + QList allQPropertyBindings; bool hadRequiredProperties; }; @@ -146,6 +152,16 @@ class Q_QML_PRIVATE_EXPORT QQmlObjectCreator RequiredProperties &requiredProperties() {return sharedState->requiredProperties;} bool componentHadRequiredProperties() const {return sharedState->hadRequiredProperties;} + void removePendingBinding(QObject *target, int propertyIndex) + { + QList &pendingBindings = sharedState.data()->allQPropertyBindings; + auto it = std::remove_if(pendingBindings.begin(), pendingBindings.end(), + [&](const DeferredQPropertyBinding &deferred) { + return deferred.properyIndex == propertyIndex && deferred.target == target; + }); + pendingBindings.erase(it, pendingBindings.end()); + } + private: QQmlObjectCreator(QQmlRefPointer contextData, const QQmlRefPointer &compilationUnit, @@ -155,8 +171,9 @@ class Q_QML_PRIVATE_EXPORT QQmlObjectCreator QObject *createInstance(int index, QObject *parent = nullptr, bool isContextObject = false); - bool populateInstance(int index, QObject *instance, - QObject *bindingTarget, const QQmlPropertyData *valueTypeProperty); + bool populateInstance(int index, QObject *instance, QObject *bindingTarget, + const QQmlPropertyData *valueTypeProperty, + const QV4::CompiledData::Binding *binding = nullptr); // If qmlProperty and binding are null, populate all properties, otherwise only the given one. void populateDeferred(QObject *instance, int deferredIndex, diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp index ec2d57013fc..ddd94630d70 100644 --- a/src/qml/qml/qqmlopenmetaobject.cpp +++ b/src/qml/qml/qqmlopenmetaobject.cpp @@ -40,6 +40,7 @@ #include "qqmlopenmetaobject_p.h" #include #include +#include #include #include @@ -427,8 +428,11 @@ void QQmlOpenMetaObject::setCached(bool c) QQmlData *qmldata = QQmlData::get(d->object, true); if (d->cacheProperties) { + // As the propertyCache is not saved in QQmlMetaType (due to it being dynamic) + // we cannot leak it to other places before we're done with it. Yes, it's still + // terrible. if (!d->type->d->cache) - d->type->d->cache = new QQmlPropertyCache(this); + d->type->d->cache = QQmlPropertyCache::createStandalone(this).take(); qmldata->propertyCache = d->type->d->cache; d->type->d->cache->addref(); } else { diff --git a/src/qml/qml/qqmlpluginimporter.cpp b/src/qml/qml/qqmlpluginimporter.cpp new file mode 100644 index 00000000000..f0cc3d2a5b5 --- /dev/null +++ b/src/qml/qml/qqmlpluginimporter.cpp @@ -0,0 +1,649 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 "qqmlpluginimporter_p.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcQmlImport) + +struct QmlPlugin { + std::unique_ptr loader; +}; + +class PluginMap +{ + Q_DISABLE_COPY_MOVE(PluginMap) +public: + PluginMap() = default; + + // This is a std::unordered_map because QHash cannot handle move-only types. + using Container = std::unordered_map; + +private: + QBasicMutex mutex; + Container plugins; + friend class PluginMapPtr; +}; + +class PluginMapPtr +{ + Q_DISABLE_COPY_MOVE(PluginMapPtr) +public: + PluginMapPtr(PluginMap *map) : map(map), locker(&map->mutex) {} + + PluginMap::Container &operator*() { return map->plugins; } + const PluginMap::Container &operator*() const { return map->plugins; } + + PluginMap::Container *operator->() { return &map->plugins; } + const PluginMap::Container *operator->() const { return &map->plugins; } + +private: + PluginMap *map; + QMutexLocker locker; +}; + +Q_GLOBAL_STATIC(PluginMap, qmlPluginsById); // stores the uri and the PluginLoaders + +static QTypeRevision validVersion(QTypeRevision version = QTypeRevision()) +{ + // If the given version is invalid, return a valid but useless version to signal "It's OK". + return version.isValid() ? version : QTypeRevision::fromMinorVersion(0); +} + +static QVector makePlugins() +{ + QVector plugins; + // To avoid traversing all static plugins for all imports, we cut down + // the list the first time called to only contain QML plugins: + const auto staticPlugins = QPluginLoader::staticPlugins(); + for (const QStaticPlugin &plugin : staticPlugins) { + const QString iid = plugin.metaData().value(QLatin1String("IID")).toString(); + if (iid == QLatin1String(QQmlEngineExtensionInterface_iid) + || iid == QLatin1String(QQmlExtensionInterface_iid) + || iid == QLatin1String(QQmlExtensionInterface_iid_old)) { + plugins.append(plugin); + } + } + return plugins; +} + +/* + Returns the list of possible versioned URI combinations. For example, if \a uri is + QtQml.Models, \a vmaj is 2, and \a vmin is 0, this method returns the following: + [QtQml.Models.2.0, QtQml.2.0.Models, QtQml.Models.2, QtQml.2.Models, QtQml.Models] + */ +static QStringList versionUriList(const QString &uri, QTypeRevision version) +{ + QStringList result; + for (int mode = QQmlImports::FullyVersioned; mode <= QQmlImports::Unversioned; ++mode) { + int index = uri.length(); + do { + QString versionUri = uri; + versionUri.insert(index, QQmlImports::versionString( + version, QQmlImports::ImportVersion(mode))); + result += versionUri; + + index = uri.lastIndexOf(u'.', index - 1); + } while (index > 0 && mode != QQmlImports::Unversioned); + } + return result; +} + +static bool unloadPlugin(const std::pair &plugin) +{ + const auto &loader = plugin.second.loader; + if (!loader) + return false; + +#if QT_CONFIG(library) + if (auto extensionPlugin = qobject_cast(loader->instance())) + extensionPlugin->unregisterTypes(); + +# ifndef Q_OS_MACOS + if (!loader->unload()) { + qWarning("Unloading %s failed: %s", qPrintable(plugin.first), + qPrintable(loader->errorString())); + return false; + } +# endif +#endif + + return true; +} + +void qmlClearEnginePlugins() +{ + PluginMapPtr plugins(qmlPluginsById()); + for (const auto &plugin : qAsConst(*plugins)) + unloadPlugin(plugin); + plugins->clear(); +} + +bool QQmlPluginImporter::removePlugin(const QString &pluginId) +{ + PluginMapPtr plugins(qmlPluginsById()); + + auto it = plugins->find(pluginId); + if (it == plugins->end()) + return false; + + const bool success = unloadPlugin(*it); + + plugins->erase(it); + return success; +} + +QStringList QQmlPluginImporter::plugins() +{ + PluginMapPtr plugins(qmlPluginsById()); + QStringList results; + for (auto it = plugins->cbegin(), end = plugins->cend(); it != end; ++it) { + if (it->second.loader != nullptr) + results.append(it->first); + } + return results; +} + +QString QQmlPluginImporter::truncateToDirectory(const QString &qmldirFilePath) +{ + const int slash = qmldirFilePath.lastIndexOf(u'/'); + return slash > 0 ? qmldirFilePath.left(slash) : qmldirFilePath; +} + +void QQmlPluginImporter::finalizePlugin(QObject *instance, const QString &pluginId) { + // The plugin's per-engine initialization does not need lock protection, as this function is + // only called from the engine specific loader thread and importDynamicPlugin as well as + // importStaticPlugin are the only places of access. + + database->initializedPlugins.insert(pluginId); + if (auto *extensionIface = qobject_cast(instance)) + typeLoader->initializeEngine(extensionIface, uri.toUtf8().constData()); + else if (auto *engineIface = qobject_cast(instance)) + typeLoader->initializeEngine(engineIface, uri.toUtf8().constData()); +} + +QTypeRevision QQmlPluginImporter::importStaticPlugin(QObject *instance, const QString &pluginId) { + // Dynamic plugins are differentiated by their filepath. For static plugins we + // don't have that information so we use their address as key instead. + QTypeRevision importVersion = version; + { + PluginMapPtr plugins(qmlPluginsById()); + + // Plugin types are global across all engines and should only be + // registered once. But each engine still needs to be initialized. + bool typesRegistered = plugins->find(pluginId) != plugins->end(); + + if (!typesRegistered) { + plugins->insert(std::make_pair(pluginId, QmlPlugin())); + if (QQmlMetaType::registerPluginTypes( + instance, QFileInfo(qmldirPath).absoluteFilePath(), uri, + qmldir->typeNamespace(), importVersion, errors) + == QQmlMetaType::RegistrationResult::Failure) { + return QTypeRevision(); + } + + importVersion = QQmlImportDatabase::lockModule( + uri, qmldir->typeNamespace(), importVersion, errors); + if (!importVersion.isValid()) + return QTypeRevision(); + } + + // Release the lock on plugins early as we're done with the global part. Releasing the lock + // also allows other QML loader threads to acquire the lock while this thread is blocking + // in the initializeEngine call to the gui thread (which in turn may be busy waiting for + // other QML loader threads and thus not process the initializeEngine call). + } + + if (!database->initializedPlugins.contains(pluginId)) + finalizePlugin(instance, pluginId); + + return validVersion(importVersion); +} + +QTypeRevision QQmlPluginImporter::importDynamicPlugin( + const QString &filePath, const QString &pluginId, bool optional) +{ + QObject *instance = nullptr; + QTypeRevision importVersion = version; + + const bool engineInitialized = database->initializedPlugins.contains(pluginId); + { + PluginMapPtr plugins(qmlPluginsById()); + bool typesRegistered = plugins->find(pluginId) != plugins->end(); + + if (!engineInitialized || !typesRegistered) { + const QFileInfo fileInfo(filePath); + if (!typesRegistered && optional) { + switch (QQmlMetaType::registerPluginTypes( + nullptr, fileInfo.absolutePath(), uri, qmldir->typeNamespace(), + importVersion, errors)) { + case QQmlMetaType::RegistrationResult::NoRegistrationFunction: + // try again with plugin + break; + case QQmlMetaType::RegistrationResult::Success: + importVersion = QQmlImportDatabase::lockModule( + uri, qmldir->typeNamespace(), importVersion, errors); + if (!importVersion.isValid()) + return QTypeRevision(); + // instance and loader intentionally left at nullptr + plugins->insert(std::make_pair(pluginId, QmlPlugin())); + // Not calling initializeEngine with null instance + database->initializedPlugins.insert(pluginId); + return importVersion; + case QQmlMetaType::RegistrationResult::Failure: + return QTypeRevision(); + } + } + +#if QT_CONFIG(library) + if (!typesRegistered) { + + // Check original filePath. If that one is empty, not being able + // to load the plugin is not an error. We were just checking if + // the types are already available. absoluteFilePath can still be + // empty if filePath is not. + if (filePath.isEmpty()) + return QTypeRevision(); + + const QString absoluteFilePath = fileInfo.absoluteFilePath(); + if (!QQml_isFileCaseCorrect(absoluteFilePath)) { + if (errors) { + QQmlError error; + error.setDescription( + QQmlImportDatabase::tr("File name case mismatch for \"%1\"") + .arg(absoluteFilePath)); + errors->prepend(error); + } + return QTypeRevision(); + } + + QmlPlugin plugin; + plugin.loader = std::make_unique(absoluteFilePath); + if (!plugin.loader->load()) { + if (errors) { + QQmlError error; + error.setDescription(plugin.loader->errorString()); + errors->prepend(error); + } + return QTypeRevision(); + } + + instance = plugin.loader->instance(); + plugins->insert(std::make_pair(pluginId, std::move(plugin))); + + // Continue with shared code path for dynamic and static plugins: + if (QQmlMetaType::registerPluginTypes( + instance, fileInfo.absolutePath(), uri, qmldir->typeNamespace(), + importVersion, errors) + == QQmlMetaType::RegistrationResult::Failure) { + return QTypeRevision(); + } + + importVersion = QQmlImportDatabase::lockModule( + uri, qmldir->typeNamespace(), importVersion, errors); + if (!importVersion.isValid()) + return QTypeRevision(); + } else { + auto it = plugins->find(pluginId); + if (it != plugins->end() && it->second.loader) + instance = it->second.loader->instance(); + } +#else + // Here plugin is not optional and NOT QT_CONFIG(library) + // Cannot finalize such plugin and return valid, because no types are registered. + // Just return invalid. + if (!optional) + return QTypeRevision(); +#endif // QT_CONFIG(library) + } + + // Release the lock on plugins early as we're done with the global part. Releasing the lock + // also allows other QML loader threads to acquire the lock while this thread is blocking + // in the initializeEngine call to the gui thread (which in turn may be busy waiting for + // other QML loader threads and thus not process the initializeEngine call). + } + + if (!engineInitialized) + finalizePlugin(instance, pluginId); + + return validVersion(importVersion); +} + +/*! + \internal + + Searches for a plugin called \a baseName in \a qmldirPluginPath, taking the + path of the qmldir file itself, and the plugin paths of the QQmlImportDatabase + into account. + + The baseName is amended with a platform-dependent prefix and suffix to + construct the final plugin file name: + + \table + \header \li Platform \li Prefix \li Valid suffixes + \row \li Windows \li \li \c .dll, \c .d.dll + \row \li Unix/Linux \li lib \li \c .so + \row \li \macos \li lib \li \c .dylib, \c _debug.dylib \c .bundle, \c .so + \row \li Android \li lib \li \c .so, \c _.so + \endtable + + If the \a qmldirPluginPath is absolute, it is searched first. Then each of the + filePluginPath entries in the QQmlImportDatabase is checked in turn. If the + entry is relative, it is resolved on top of the path of the qmldir file, + otherwise it is taken verbatim. If a "." is found in the filePluginPath, and + \a qmldirPluginPath is relative, then \a qmldirPluginPath is used in its + place. + + TODO: Document the android special casing. + + TODO: The above paragraph, as well as the code implementing it makes very + little sense and is mostly here for backwards compatibility. + */ +QString QQmlPluginImporter::resolvePlugin(const QString &qmldirPluginPath, const QString &baseName) +{ +#if defined(Q_OS_WIN) + static const QString prefix; + static const QStringList suffixes = { + # ifdef QT_DEBUG + QLatin1String("d.dll"), // try a qmake-style debug build first + QLatin1String(".dll") + #else + QLatin1String(".dll"), + QLatin1String("d.dll") // try a qmake-style debug build after + # endif + }; +#elif defined(Q_OS_DARWIN) + static const QString prefix = QLatin1String("lib"); + static const QStringList suffixes = { + # ifdef QT_DEBUG + QLatin1String("_debug.dylib"), // try a qmake-style debug build first + QLatin1String(".dylib"), + # else + QLatin1String(".dylib"), + QLatin1String("_debug.dylib"), // try a qmake-style debug build after + # endif + QLatin1String(".so"), + QLatin1String(".bundle") + }; +#else // Unix + static const QString prefix = QLatin1String("lib"); + static const QStringList suffixes = { + # if defined(Q_OS_ANDROID) + QStringLiteral(LIBS_SUFFIX), + # endif + QLatin1String(".so") + }; +#endif + + QStringList searchPaths = database->filePluginPath; + bool qmldirPluginPathIsRelative = QDir::isRelativePath(qmldirPluginPath); + if (!qmldirPluginPathIsRelative) + searchPaths.prepend(qmldirPluginPath); + + for (const QString &pluginPath : qAsConst(searchPaths)) { + QString resolvedBasePath; + if (pluginPath == QLatin1String(".")) { + if (qmldirPluginPathIsRelative && !qmldirPluginPath.isEmpty() + && qmldirPluginPath != QLatin1String(".")) { + resolvedBasePath = QDir::cleanPath(qmldirPath + u'/' + qmldirPluginPath); + } else { + resolvedBasePath = qmldirPath; + } + } else { + if (QDir::isRelativePath(pluginPath)) + resolvedBasePath = QDir::cleanPath(qmldirPath + u'/' + pluginPath); + else + resolvedBasePath = pluginPath; + } + + // hack for resources, should probably go away + if (resolvedBasePath.startsWith(u':')) + resolvedBasePath = QCoreApplication::applicationDirPath(); + + if (!resolvedBasePath.endsWith(u'/')) + resolvedBasePath += u'/'; + + QString resolvedPath = resolvedBasePath + prefix + baseName; + for (const QString &suffix : suffixes) { + const QString absolutePath = typeLoader->absoluteFilePath(resolvedPath + suffix); + if (!absolutePath.isEmpty()) + return absolutePath; + } + +#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) +# if defined(Q_OS_ANDROID) + if (qmldirPath.size() > 25 && qmldirPath.at(0) == QLatin1Char(':') + && qmldirPath.at(1) == QLatin1Char('/') + && qmldirPath.startsWith(QStringLiteral(":/android_rcc_bundle/qml/"), + Qt::CaseInsensitive)) { + QString pluginName = qmldirPath.mid(21) + u'/' + baseName; + pluginName.replace(QLatin1Char('/'), QLatin1Char('_')); + QString bundledPath = resolvedBasePath + QLatin1String("lib") + pluginName; + for (const QString &suffix : suffixes) { + const QString absolutePath = typeLoader->absoluteFilePath(bundledPath + suffix); + if (!absolutePath.isEmpty()) { + qWarning("The implicit resolving of Qml plugin locations using the URI " + "embedded in the filename has been deprecated. Please use the " + "modern CMake API to create QML modules or set the name of " + "QML plugin in qmldir file, that matches the name of plugin " + "on file system. The correct plugin name is '%s'.", + qPrintable(pluginName)); + return absolutePath; + } + } + } +# endif +#endif + } + + qCDebug(lcQmlImport) << "resolvePlugin" << "Could not resolve dynamic plugin with base name" + << baseName << "in" << qmldirPath + << " file does not exist"; + + return QString(); +} + +/* + Get all static plugins that are QML plugins and has a meta data URI that matches with one of + \a versionUris, which is a list of all possible versioned URI combinations - see versionUriList() + above. + */ +bool QQmlPluginImporter::populatePluginPairVector( + QVector &result, const QStringList &versionUris) +{ + static const QVector plugins = makePlugins(); + for (const QStaticPlugin &plugin : plugins) { + // Since a module can list more than one plugin, + // we keep iterating even after we found a match. + QObject *instance = plugin.instance(); + if (qobject_cast(instance) + || qobject_cast(instance)) { + const QJsonArray metaTagsUriList = plugin.metaData().value( + QStringLiteral("uri")).toArray(); + if (metaTagsUriList.isEmpty()) { + if (errors) { + QQmlError error; + error.setDescription(QQmlImportDatabase::tr( + "static plugin for module \"%1\" with name \"%2\" " + "has no metadata URI") + .arg(uri, QString::fromUtf8( + instance->metaObject()->className()))); + error.setUrl(QUrl::fromLocalFile(qmldir->qmldirLocation())); + errors->prepend(error); + } + return false; + } + // A plugin can be set up to handle multiple URIs, so go through the list: + for (const QJsonValueRef metaTagUri : metaTagsUriList) { + if (versionUris.contains(metaTagUri.toString())) { + result.append(qMakePair(plugin, metaTagsUriList)); + break; + } + } + } + } + return true; +} + +QTypeRevision QQmlPluginImporter::importPlugins() { + const auto qmldirPlugins = qmldir->plugins(); + const int qmldirPluginCount = qmldirPlugins.count(); + QTypeRevision importVersion = version; + + // If the path contains a version marker or if we have more than one plugin, + // we need to use paths. In that case we cannot fall back to other instances + // of the same module if a qmldir is rejected. However, as we don't generate + // such modules, it shouldn't be a problem. + const bool canUseUris = qmldirPluginCount == 1 + && qmldirPath.endsWith(u'/' + QString(uri).replace(u'.', u'/')); + const QString moduleId = canUseUris ? uri : qmldir->qmldirLocation(); + + if (!database->modulesForWhichPluginsHaveBeenLoaded.contains(moduleId)) { + // First search for listed qmldir plugins dynamically. If we cannot resolve them all, we + // continue searching static plugins that has correct metadata uri. Note that since we + // only know the uri for a static plugin, and not the filename, we cannot know which + // static plugin belongs to which listed plugin inside qmldir. And for this reason, + // mixing dynamic and static plugins inside a single module is not recommended. + + int dynamicPluginsFound = 0; + int staticPluginsFound = 0; + + for (const QQmlDirParser::Plugin &plugin : qmldirPlugins) { + const QString resolvedFilePath = resolvePlugin(plugin.path, plugin.name); + + if (!canUseUris && resolvedFilePath.isEmpty()) + continue; + + importVersion = importDynamicPlugin( + resolvedFilePath, + canUseUris ? uri : QFileInfo(resolvedFilePath).absoluteFilePath(), + plugin.optional); + if (importVersion.isValid()) + ++dynamicPluginsFound; + else if (!resolvedFilePath.isEmpty()) + return QTypeRevision(); + } + + if (dynamicPluginsFound < qmldirPluginCount) { + // Check if the missing plugins can be resolved statically. We do this by looking at + // the URIs embedded in a plugins meta data. Since those URIs can be anything from + // fully versioned to unversioned, we need to compare with differnt version strings. + // If a module has several plugins, they must all have the same version. Start by + // populating pluginPairs with relevant plugins to cut the list short early on: + const QStringList versionUris = versionUriList(uri, importVersion); + QVector pluginPairs; + if (!populatePluginPairVector(pluginPairs, versionUris)) + return QTypeRevision(); + + for (const QString &versionUri : versionUris) { + for (const StaticPluginPair &pair : qAsConst(pluginPairs)) { + for (const QJsonValueRef metaTagUri : pair.second) { + if (versionUri == metaTagUri.toString()) { + staticPluginsFound++; + QObject *instance = pair.first.instance(); + importVersion = importStaticPlugin( + instance, + canUseUris ? uri : QString::asprintf("%p", instance)); + if (!importVersion.isValid()){ + if (errors) { + Q_ASSERT(!errors->isEmpty()); + const QQmlError poppedError = errors->takeFirst(); + QQmlError error; + error.setDescription( + QQmlImportDatabase::tr( + "static plugin for module \"%1\" with " + "name \"%2\" cannot be loaded: %3") + .arg(uri, QString::fromUtf8( + instance->metaObject()->className()), + poppedError.description())); + error.setUrl(QUrl::fromLocalFile(qmldir->qmldirLocation())); + errors->prepend(error); + } + return QTypeRevision(); + } + + qCDebug(lcQmlImport) + << "importExtension" << "loaded static plugin " << versionUri; + + break; + } + } + } + if (staticPluginsFound > 0) + break; + } + } + + if ((dynamicPluginsFound + staticPluginsFound) < qmldirPluginCount) { + if (errors) { + QQmlError error; + if (qmldirPluginCount > 1 && staticPluginsFound > 0) { + error.setDescription(QQmlImportDatabase::tr( + "could not resolve all plugins for module \"%1\"") + .arg(uri)); + } else { + error.setDescription(QQmlImportDatabase::tr( + "module \"%1\" plugin \"%2\" not found") + .arg(uri, qmldirPlugins[dynamicPluginsFound].name)); + } + error.setUrl(QUrl::fromLocalFile(qmldir->qmldirLocation())); + errors->prepend(error); + } + return QTypeRevision(); + } + + database->modulesForWhichPluginsHaveBeenLoaded.insert(moduleId); + } + return validVersion(importVersion); +} + +QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlpluginimporter_p.h b/src/qml/qml/qqmlpluginimporter_p.h new file mode 100644 index 00000000000..c423e3f6380 --- /dev/null +++ b/src/qml/qml/qqmlpluginimporter_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 QQMLPLUGINIMPORTER_P_H +#define QQMLPLUGINIMPORTER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class QQmlPluginImporter +{ + Q_DISABLE_COPY_MOVE(QQmlPluginImporter) + +public: + using StaticPluginPair = QPair; + + QQmlPluginImporter(const QString &uri, QTypeRevision version, QQmlImportDatabase *database, + const QQmlTypeLoaderQmldirContent *qmldir, QQmlTypeLoader *typeLoader, + QList *errors) + : uri(uri) + , qmldirPath(truncateToDirectory(qmldir->qmldirLocation())) + , qmldir(qmldir) + , database(database) + , typeLoader(typeLoader) + , errors(errors) + , version(version) + {} + + QTypeRevision importDynamicPlugin( + const QString &filePath, const QString &pluginId, bool optional); + QTypeRevision importStaticPlugin(QObject *instance, const QString &pluginId); + QTypeRevision importPlugins(); + + static bool removePlugin(const QString &pluginId); + static QStringList plugins(); + +private: + static QString truncateToDirectory(const QString &qmldirFilePath); + bool populatePluginPairVector(QVector &result, + const QStringList &versionUris); + + QString resolvePlugin(const QString &qmldirPluginPath, const QString &baseName); + void finalizePlugin(QObject *instance, const QString &path); + + const QString uri; + const QString qmldirPath; + + const QQmlTypeLoaderQmldirContent *qmldir = nullptr; + QQmlImportDatabase *database = nullptr; + QQmlTypeLoader *typeLoader = nullptr; + QList *errors = nullptr; + + const QTypeRevision version; +}; + +QT_END_NAMESPACE + +#endif // QQMLPLUGINIMPORTER_P_H diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index 71855df9660..11c948445fe 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -612,6 +612,7 @@ namespace QQmlPrivate QJSValue jsMetaType(int index) const; void setInstructionPointer(int offset) const; + void setReturnValueUndefined() const; // Run QQmlPropertyCapture::captureProperty() without retrieving the value. bool captureLookup(uint index, QObject *object) const; diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index b24b57a0e4f..372103b94f4 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -74,6 +74,8 @@ Q_DECLARE_METATYPE(QList) QT_BEGIN_NAMESPACE +DEFINE_BOOL_CONFIG_OPTION(compatResolveUrlsOnAssigment, QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT); + /*! \class QQmlProperty \since 5.0 @@ -246,6 +248,11 @@ QQmlProperty QQmlPropertyPrivate::create(QObject *target, const QString &propert return result; } +bool QQmlPropertyPrivate::resolveUrlsOnAssignment() +{ + return ::compatResolveUrlsOnAssigment(); +} + QQmlRefPointer QQmlPropertyPrivate::effectiveContext() const { if (context) @@ -287,17 +294,24 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name) currentObject = qmlAttachedPropertiesObject(currentObject, func); if (!currentObject) return; // Something is broken with the attachable type } else if (r.importNamespace) { - if ((ii + 1) == path.count()) return; // No type following the namespace + if (++ii == path.count()) + return; // No type following the namespace - ++ii; r = typeNameCache->query(path.at(ii), r.importNamespace); - if (!r.type.isValid()) return; // Invalid type in namespace + // TODO: Do we really _not_ want to query the namespaced types here? + r = typeNameCache->query( + path.at(ii), r.importNamespace); + + if (!r.type.isValid()) + return; // Invalid type in namespace QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine); QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate); - if (!func) return; // Not an attachable type + if (!func) + return; // Not an attachable type currentObject = qmlAttachedPropertiesObject(currentObject, func); - if (!currentObject) return; // Something is broken with the attachable type + if (!currentObject) + return; // Something is broken with the attachable type } else if (r.scriptIndex != -1) { return; // Not a type @@ -612,12 +626,8 @@ QObject *QQmlProperty::object() const */ QQmlProperty &QQmlProperty::operator=(const QQmlProperty &other) { - if (d) - d->release(); - d = other.d; - if (d) - d->addref(); - + QQmlProperty copied(other); + qSwap(d, copied.d); return *this; } @@ -1134,32 +1144,38 @@ QVariant QQmlPropertyPrivate::readValueProperty() } // helper function to allow assignment / binding to QList properties. -QVariant QQmlPropertyPrivate::urlSequence(const QVariant &value) +QList QQmlPropertyPrivate::urlSequence(const QVariant &value) { + if (value.metaType() == QMetaType::fromType>()) + return value.value >(); + QList urls; - if (value.userType() == qMetaTypeId()) { + if (value.metaType() == QMetaType::fromType()) { urls.append(value.toUrl()); - } else if (value.userType() == qMetaTypeId()) { + } else if (value.metaType() == QMetaType::fromType()) { urls.append(QUrl(value.toString())); - } else if (value.userType() == qMetaTypeId()) { + } else if (value.metaType() == QMetaType::fromType()) { urls.append(QUrl(QString::fromUtf8(value.toByteArray()))); - } else if (value.userType() == qMetaTypeId >()) { - urls = value.value >(); - } else if (value.userType() == qMetaTypeId()) { + } else if (value.metaType() == QMetaType::fromType()) { QStringList urlStrings = value.value(); const int urlStringsSize = urlStrings.size(); urls.reserve(urlStringsSize); for (int i = 0; i < urlStringsSize; ++i) urls.append(QUrl(urlStrings.at(i))); - } else if (value.userType() == qMetaTypeId >()) { - QList urlStrings = value.value >(); - const int urlStringsSize = urlStrings.size(); - urls.reserve(urlStringsSize); - for (int i = 0; i < urlStringsSize; ++i) - urls.append(QUrl(urlStrings.at(i))); } // note: QList is not currently supported. + return urls; +} - return QVariant::fromValue >(urls); +// ### Qt7: Get rid of this +QList QQmlPropertyPrivate::urlSequence( + const QVariant &value, const QQmlRefPointer &ctxt) +{ + QList urls = urlSequence(value); + + for (auto urlIt = urls.begin(); urlIt != urls.end(); ++urlIt) + *urlIt = ctxt->resolvedUrl(*urlIt); + + return urls; } //writeEnumProperty MIRRORS the relelvant bit of QMetaProperty::write AND MUST BE KEPT IN SYNC! @@ -1293,15 +1309,18 @@ bool QQmlPropertyPrivate::write( return property.writeProperty(object, const_cast(value.constData()), flags); } else if (property.isQObject()) { QVariant val = value; - int varType = variantType; - if (variantType == QMetaType::Nullptr) { + const QMetaType variantMetaType = value.metaType(); + QMetaType varType; + if (variantMetaType == QMetaType::fromType()) { // This reflects the fact that you can assign a nullptr to a QObject pointer // Without the change to QObjectStar, rawMetaObjectForType would not give us a QQmlMetaObject - varType = QMetaType::QObjectStar; + varType = QMetaType::fromType(); val = QVariant(QMetaType::fromType(), nullptr); + } else { + varType = variantMetaType; } - QQmlMetaObject valMo = rawMetaObjectForType(enginePriv, varType); - if (valMo.isNull()) + QQmlMetaObject valMo = rawMetaObjectForType(enginePriv, varType.id()); + if (valMo.isNull() || !varType.flags().testFlag(QMetaType::PointerToQObject)) return false; QObject *o = *static_cast(val.constData()); QQmlMetaObject propMo = rawMetaObjectForType(enginePriv, propertyType); @@ -1354,8 +1373,11 @@ bool QQmlPropertyPrivate::write( return property.writeProperty(object, const_cast(&value), flags); } else if (isUrl) { QUrl u; - if (variantType == QMetaType::QUrl) + if (variantType == QMetaType::QUrl) { u = value.toUrl(); + if (compatResolveUrlsOnAssigment() && context && u.isRelative() && !u.isEmpty()) + u = context->resolvedUrl(u); + } else if (variantType == QMetaType::QByteArray) u = QUrl(QString::fromUtf8(value.toByteArray())); else if (variantType == QMetaType::QString) @@ -1365,7 +1387,9 @@ bool QQmlPropertyPrivate::write( return property.writeProperty(object, &u, flags); } else if (propertyType == qMetaTypeId>()) { - QList urlSeq = urlSequence(value).value>(); + QList urlSeq = compatResolveUrlsOnAssigment() + ? urlSequence(value, context) + : urlSequence(value); return property.writeProperty(object, &urlSeq, flags); } else if (property.isQList()) { QQmlMetaObject listType; @@ -1775,3 +1799,5 @@ void QQmlPropertyPrivate::flushSignal(const QObject *sender, int signal_index) } QT_END_NAMESPACE + +#include "moc_qqmlproperty.cpp" diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h index c54d0661520..5b42134a1fa 100644 --- a/src/qml/qml/qqmlproperty_p.h +++ b/src/qml/qml/qqmlproperty_p.h @@ -82,6 +82,9 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyPrivate : public QQmlRefCount QString nameCache; + // ### Qt7: Get rid of this. + static bool resolveUrlsOnAssignment(); + QQmlPropertyPrivate() {} QQmlPropertyIndex encodedIndex() const @@ -161,7 +164,9 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyPrivate : public QQmlRefCount int type = 0, int *types = nullptr); static void flushSignal(const QObject *sender, int signal_index); - static QVariant urlSequence(const QVariant &value); + static QList urlSequence(const QVariant &value); + static QList urlSequence( + const QVariant &value, const QQmlRefPointer &ctxt); static QQmlProperty create( QObject *target, const QString &propertyName, const QQmlRefPointer &context); diff --git a/src/qml/qml/qqmlpropertybinding.cpp b/src/qml/qml/qqmlpropertybinding.cpp index b1ad3f1767b..51dee8fa5fa 100644 --- a/src/qml/qml/qqmlpropertybinding.cpp +++ b/src/qml/qml/qqmlpropertybinding.cpp @@ -42,6 +42,9 @@ #include #include #include +#include +#include +#include QT_BEGIN_NAMESPACE @@ -61,10 +64,11 @@ QUntypedPropertyBinding QQmlPropertyBinding::create(QMetaType propertyType, QV4: QV4::ExecutionContext *scope, QObject *target, QQmlPropertyIndex targetIndex) { - auto buffer = new std::byte[sizeof(QQmlPropertyBinding)+sizeof(QQmlPropertyBindingJS)+jsExpressionOffsetLength()]; // QQmlPropertyBinding uses delete[] + auto buffer = new std::byte[QQmlPropertyBinding::getSizeEnsuringAlignment() + + sizeof(QQmlPropertyBindingJS)+jsExpressionOffsetLength()]; // QQmlPropertyBinding uses delete[] auto binding = new (buffer) QQmlPropertyBinding(propertyType, target, targetIndex, TargetData::WithoutBoundFunction); - auto js = new(buffer + sizeof(QQmlPropertyBinding) + jsExpressionOffsetLength()) QQmlPropertyBindingJS(); + auto js = new(buffer + QQmlPropertyBinding::getSizeEnsuringAlignment() + jsExpressionOffsetLength()) QQmlPropertyBindingJS(); Q_ASSERT(binding->jsExpression() == js); Q_ASSERT(js->asBinding() == binding); Q_UNUSED(js); @@ -77,9 +81,10 @@ QUntypedPropertyBinding QQmlPropertyBinding::create(QMetaType propertyType, QV4: QUntypedPropertyBinding QQmlPropertyBinding::createFromCodeString(const QQmlPropertyData *pd, const QString& str, QObject *obj, const QQmlRefPointer &ctxt, const QString &url, quint16 lineNumber, QObject *target, QQmlPropertyIndex targetIndex) { - auto buffer = new std::byte[sizeof(QQmlPropertyBinding)+sizeof(QQmlPropertyBindingJS)+jsExpressionOffsetLength()]; // QQmlPropertyBinding uses delete[] + auto buffer = new std::byte[QQmlPropertyBinding::getSizeEnsuringAlignment() + + sizeof(QQmlPropertyBindingJS)+jsExpressionOffsetLength()]; // QQmlPropertyBinding uses delete[] auto binding = new(buffer) QQmlPropertyBinding(QMetaType(pd->propType()), target, targetIndex, TargetData::WithoutBoundFunction); - auto js = new(buffer + sizeof(QQmlPropertyBinding) + jsExpressionOffsetLength()) QQmlPropertyBindingJS(); + auto js = new(buffer + QQmlPropertyBinding::getSizeEnsuringAlignment() + jsExpressionOffsetLength()) QQmlPropertyBindingJS(); Q_ASSERT(binding->jsExpression() == js); Q_ASSERT(js->asBinding() == binding); Q_UNUSED(js); @@ -89,11 +94,50 @@ QUntypedPropertyBinding QQmlPropertyBinding::createFromCodeString(const QQmlProp return QUntypedPropertyBinding(static_cast(QPropertyBindingPrivatePtr(binding).data())); } +QUntypedPropertyBinding QQmlPropertyBinding::createFromScriptString(const QQmlPropertyData *property, const QQmlScriptString &script, QObject *obj, QQmlContext *ctxt, QObject *target, QQmlPropertyIndex targetIndex) +{ + const QQmlScriptStringPrivate *scriptPrivate = script.d.data(); + // without a valid context, we cannot create anything + if (!ctxt && (!scriptPrivate->context || !scriptPrivate->context->isValid())) { + return {}; + } + + auto scopeObject = obj ? obj : scriptPrivate->scope; + + QV4::Function *runtimeFunction = nullptr; + QString url; + QQmlRefPointer ctxtdata = QQmlContextData::get(scriptPrivate->context); + QQmlEnginePrivate *engine = QQmlEnginePrivate::get(scriptPrivate->context->engine()); + if (engine && ctxtdata && !ctxtdata->urlString().isEmpty() && ctxtdata->typeCompilationUnit()) { + url = ctxtdata->urlString(); + if (scriptPrivate->bindingId != QQmlBinding::Invalid) + runtimeFunction = ctxtdata->typeCompilationUnit()->runtimeFunctions.at(scriptPrivate->bindingId); + } + // Do we actually have a function in the script string? If not, this becomes createCodeFromString + if (!runtimeFunction) + return createFromCodeString(property, scriptPrivate->script, obj, ctxtdata, url, scriptPrivate->lineNumber, target, targetIndex); + + auto buffer = new std::byte[QQmlPropertyBinding::getSizeEnsuringAlignment() + + sizeof(QQmlPropertyBindingJS)+jsExpressionOffsetLength()]; // QQmlPropertyBinding uses delete[] + auto binding = new(buffer) QQmlPropertyBinding(QMetaType(property->propType()), target, targetIndex, TargetData::WithoutBoundFunction); + auto js = new(buffer + QQmlPropertyBinding::getSizeEnsuringAlignment() + jsExpressionOffsetLength()) QQmlPropertyBindingJS(); + Q_ASSERT(binding->jsExpression() == js); + Q_ASSERT(js->asBinding() == binding); + js->setContext(QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context)); + + QV4::ExecutionEngine *v4 = engine->v4engine(); + QV4::Scope scope(v4); + QV4::Scoped qmlContext(scope, QV4::QmlContext::create(v4->rootContext(), ctxtdata, scopeObject)); + js->setupFunction(qmlContext, runtimeFunction); + return QUntypedPropertyBinding(static_cast(QPropertyBindingPrivatePtr(binding).data())); +} + QUntypedPropertyBinding QQmlPropertyBinding::createFromBoundFunction(const QQmlPropertyData *pd, QV4::BoundFunction *function, QObject *obj, const QQmlRefPointer &ctxt, QV4::ExecutionContext *scope, QObject *target, QQmlPropertyIndex targetIndex) { - auto buffer = new std::byte[sizeof(QQmlPropertyBinding)+sizeof(QQmlPropertyBindingJSForBoundFunction)+jsExpressionOffsetLength()]; // QQmlPropertyBinding uses delete[] + auto buffer = new std::byte[QQmlPropertyBinding::getSizeEnsuringAlignment() + + sizeof(QQmlPropertyBindingJSForBoundFunction)+jsExpressionOffsetLength()]; // QQmlPropertyBinding uses delete[] auto binding = new(buffer) QQmlPropertyBinding(QMetaType(pd->propType()), target, targetIndex, TargetData::HasBoundFunction); - auto js = new(buffer + sizeof(QQmlPropertyBinding) + jsExpressionOffsetLength()) QQmlPropertyBindingJSForBoundFunction(); + auto js = new(buffer + QQmlPropertyBinding::getSizeEnsuringAlignment() + jsExpressionOffsetLength()) QQmlPropertyBindingJSForBoundFunction(); Q_ASSERT(binding->jsExpression() == js); Q_ASSERT(js->asBinding() == binding); Q_UNUSED(js); @@ -119,10 +163,13 @@ QUntypedPropertyBinding QQmlPropertyBinding::createFromBoundFunction(const QQmlP void QQmlPropertyBindingJS::expressionChanged() { - if (!asBinding()->propertyDataPtr) + auto binding = asBinding(); + if (!binding->propertyDataPtr) + return; + if (QQmlData::wasDeleted(asBinding()->target())) return; const auto currentTag = m_error.tag(); - if (currentTag & InEvaluationLoop) { + if (currentTag == InEvaluationLoop) { QQmlError err; auto location = QQmlJavaScriptExpression::sourceLocation(); err.setUrl(QUrl{location.sourceFile}); @@ -138,15 +185,16 @@ void QQmlPropertyBindingJS::expressionChanged() qmlWarning(this->scopeObject(), err); return; } - m_error.setTag(currentTag | InEvaluationLoop); - asBinding()->evaluateRecursive(); - asBinding()->notifyRecursive(); - m_error.setTag(currentTag); + m_error.setTag(InEvaluationLoop); + PendingBindingObserverList bindingObservers; + binding->evaluateRecursive(bindingObservers); + binding->notifyNonRecursive(bindingObservers); + m_error.setTag(NoTag); } QQmlPropertyBinding::QQmlPropertyBinding(QMetaType mt, QObject *target, QQmlPropertyIndex targetIndex, TargetData::BoundFunction hasBoundFunction) : QPropertyBindingPrivate(mt, - &QtPrivate::bindingFunctionVTable, + bindingFunctionVTableForQQmlPropertyBinding(mt), QPropertyBindingSourceLocation(), true) { static_assert (std::is_trivially_destructible_v); @@ -157,165 +205,6 @@ QQmlPropertyBinding::QQmlPropertyBinding(QMetaType mt, QObject *target, QQmlProp errorCallBack = bindingErrorCallback; } -template -bool compareAndAssign(void *dataPtr, const void *result) -{ - if (*static_cast(result) == *static_cast(dataPtr)) - return false; - *static_cast(dataPtr) = *static_cast(result); - return true; -} - -bool QQmlPropertyBinding::evaluate(QMetaType metaType, void *dataPtr) -{ - const auto ctxt = jsExpression()->context(); - QQmlEngine *engine = ctxt ? ctxt->engine() : nullptr; - if (!engine) { - QPropertyBindingError error(QPropertyBindingError::EvaluationError); - if (auto currentBinding = QPropertyBindingPrivate::currentlyEvaluatingBinding()) - currentBinding->setError(std::move(error)); - return false; - } - QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); - ep->referenceScarceResources(); - - const auto handleErrorAndUndefined = [&](bool evaluatedToUndefined) { - ep->dereferenceScarceResources(); - if (jsExpression()->hasError()) { - QPropertyBindingError error(QPropertyBindingError::UnknownError, - jsExpression()->delayedError()->error().description()); - QPropertyBindingPrivate::currentlyEvaluatingBinding()->setError(std::move(error)); - bindingErrorCallback(this); - return false; - } - - if (evaluatedToUndefined) { - handleUndefinedAssignment(ep, dataPtr); - // if property has been changed due to reset, reset is responsible for - // notifying observers - return false; - } else if (isUndefined()) { - setIsUndefined(false); - } - - return true; - }; - - if (!hasBoundFunction()) { - Q_ASSERT(metaType.sizeOf() > 0); - - // No need to construct here. evaluate() expects uninitialized memory. - Q_ALLOCA_VAR(void, result, metaType.sizeOf()); - - const bool evaluatedToUndefined = !jsExpression()->evaluate(&result, &metaType, 0); - if (!handleErrorAndUndefined(evaluatedToUndefined)) - return false; - - if (metaType.flags() & QMetaType::PointerToQObject) - return compareAndAssign(dataPtr, result); - - switch (metaType.id()) { - case QMetaType::Bool: - return compareAndAssign(dataPtr, result); - case QMetaType::Int: - return compareAndAssign(dataPtr, result); - case QMetaType::Double: - return compareAndAssign(dataPtr, result); - case QMetaType::Float: - return compareAndAssign(dataPtr, result); - case QMetaType::QString: { - const bool hasChanged = compareAndAssign(dataPtr, result); - static_cast(result)->~QString(); - return hasChanged; - } - default: - break; - } - - const bool hasChanged = !metaType.equals(result, dataPtr); - if (hasChanged) { - metaType.destruct(dataPtr); - metaType.construct(dataPtr, result); - } - metaType.destruct(result); - return hasChanged; - } - - bool evaluatedToUndefined = false; - QV4::Scope scope(engine->handle()); - QV4::ScopedValue result(scope, static_cast( - jsExpression())->evaluate(&evaluatedToUndefined)); - - if (!handleErrorAndUndefined(evaluatedToUndefined)) - return false; - - int propertyType = metaType.id(); - - switch (propertyType) { - case QMetaType::Bool: { - bool b; - if (result->isBoolean()) - b = result->booleanValue(); - else - b = result->toBoolean(); - if (b == *static_cast(dataPtr)) - return false; - *static_cast(dataPtr) = b; - return true; - } - case QMetaType::Int: { - int i; - if (result->isInteger()) - i = result->integerValue(); - else if (result->isNumber()) { - i = QV4::StaticValue::toInteger(result->doubleValue()); - } else { - break; - } - if (i == *static_cast(dataPtr)) - return false; - *static_cast(dataPtr) = i; - return true; - } - case QMetaType::Double: - if (result->isNumber()) { - double d = result->asDouble(); - if (d == *static_cast(dataPtr)) - return false; - *static_cast(dataPtr) = d; - return true; - } - break; - case QMetaType::Float: - if (result->isNumber()) { - float d = float(result->asDouble()); - if (d == *static_cast(dataPtr)) - return false; - *static_cast(dataPtr) = d; - return true; - } - break; - case QMetaType::QString: - if (result->isString()) { - QString s = result->toQStringNoThrow(); - if (s == *static_cast(dataPtr)) - return false; - *static_cast(dataPtr) = s; - return true; - } - break; - default: - break; - } - - QVariant resultVariant(scope.engine->toVariant(result, metaType)); - resultVariant.convert(metaType); - const bool hasChanged = !metaType.equals(resultVariant.constData(), dataPtr); - metaType.destruct(dataPtr); - metaType.construct(dataPtr, resultVariant.constData()); - return hasChanged; -} - static QtPrivate::QPropertyBindingData *bindingDataFromPropertyData(QUntypedPropertyData *dataPtr, QMetaType type) { // XXX Qt 7: We need a clean way to access the binding data @@ -376,10 +265,17 @@ void QQmlPropertyBinding::handleUndefinedAssignment(QQmlEnginePrivate *ep, void setIsUndefined(true); //suspend binding evaluation state for reset and subsequent read auto state = QtPrivate::suspendCurrentBindingStatus(); - prop.reset(); + prop.reset(); // May re-allocate the bindingData QVariant currentValue = QVariant(prop.propertyMetaType(), propertyDataPtr); QtPrivate::restoreBindingStatus(state); writeBackCurrentValue(std::move(currentValue)); + + // Re-fetch binding data + bindingData = storage->bindingData(propertyDataPtr); + if (!bindingData) + bindingData = bindingDataFromPropertyData(propertyDataPtr, propertyData->propType()); + bindingDataPointer = QPropertyBindingDataPointer {bindingData}; + // reattach the binding (without causing a new notification) if (Q_UNLIKELY(bindingData->d() & QtPrivate::QPropertyBindingData::BindingBit)) { qCWarning(lcQQPropertyBinding) << "Resetting " << prop.name() << "due to the binding becoming undefined caused a new binding to be installed\n" @@ -391,7 +287,7 @@ void QQmlPropertyBinding::handleUndefinedAssignment(QQmlEnginePrivate *ep, void firstObserver = bindingDataPointer.firstObserver(); bindingData->d_ref() = reinterpret_cast(this) | QtPrivate::QPropertyBindingData::BindingBit; if (firstObserver) - bindingDataPointer.setObservers(firstObserver.ptr); + prependObserver(firstObserver); } else { QQmlError qmlError; auto location = jsExpression()->sourceLocation(); @@ -449,8 +345,8 @@ void QQmlPropertyBinding::bindingErrorCallback(QPropertyBindingPrivate *that) QUntypedPropertyBinding QQmlTranslationPropertyBinding::create(const QQmlPropertyData *pd, const QQmlRefPointer &compilationUnit, const QV4::CompiledData::Binding *binding) { auto translationBinding = [compilationUnit, binding](const QMetaType &metaType, void *dataPtr) -> bool { - // Create a dependency to the uiLanguage - QJSEnginePrivate::get(compilationUnit->engine)->uiLanguage.value(); + // Create a dependency to the translationLanguage + QQmlEnginePrivate::get(compilationUnit->engine)->translationLanguage.value(); QVariant resultVariant(compilationUnit->bindingValueAsString(binding)); if (metaType.id() != QMetaType::QString) diff --git a/src/qml/qml/qqmlpropertybinding_p.h b/src/qml/qml/qqmlpropertybinding_p.h index 2765a13a211..17f74d56754 100644 --- a/src/qml/qml/qqmlpropertybinding_p.h +++ b/src/qml/qml/qqmlpropertybinding_p.h @@ -56,6 +56,7 @@ #include "qqmlpropertydata_p.h" #include "qqmljavascriptexpression_p.h" +#include #include @@ -69,6 +70,8 @@ class QQmlPropertyBinding; class Q_QML_PRIVATE_EXPORT QQmlPropertyBindingJS : public QQmlJavaScriptExpression { + bool mustCaptureBindableProperty() const final {return false;} + friend class QQmlPropertyBinding; void expressionChanged() override; QQmlPropertyBinding *asBinding() @@ -109,7 +112,7 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyBinding : public QPropertyBindingPrivate { return std::launder(reinterpret_cast( reinterpret_cast(this) - + sizeof(QQmlPropertyBinding) + + QPropertyBindingPrivate::getSizeEnsuringAlignment() + jsExpressionOffsetLength())); } @@ -126,6 +129,10 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyBinding : public QPropertyBindingPrivate const QQmlRefPointer &ctxt, const QString &url, quint16 lineNumber, QObject *target, QQmlPropertyIndex targetIndex); + static QUntypedPropertyBinding createFromScriptString(const QQmlPropertyData *property, + const QQmlScriptString& script, QObject *obj, + QQmlContext *ctxt, QObject *target, + QQmlPropertyIndex targetIndex); static QUntypedPropertyBinding createFromBoundFunction(const QQmlPropertyData *pd, QV4::BoundFunction *function, QObject *obj, const QQmlRefPointer &ctxt, @@ -144,11 +151,12 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyBinding : public QPropertyBindingPrivate return static_cast(binding)->isUndefined(); } + template static bool doEvaluate(QMetaType metaType, QUntypedPropertyData *dataPtr, void *f) { auto address = static_cast(f); - address -= sizeof (QPropertyBindingPrivate); // f now points to QPropertyBindingPrivate suboject + address -= QPropertyBindingPrivate::getSizeEnsuringAlignment(); // f now points to QPropertyBindingPrivate suboject // and that has the same address as QQmlPropertyBinding - return reinterpret_cast(address)->evaluate(metaType, dataPtr); + return reinterpret_cast(address)->evaluate(metaType, dataPtr); } bool hasDependencies() @@ -157,6 +165,7 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyBinding : public QPropertyBindingPrivate } private: + template bool evaluate(QMetaType metaType, void *dataPtr); Q_NEVER_INLINE void handleUndefinedAssignment(QQmlEnginePrivate *ep, void *dataPtr); @@ -210,9 +219,9 @@ template struct Print {}; namespace QtPrivate { -template<> -inline constexpr BindingFunctionVTable bindingFunctionVTable = { - &QQmlPropertyBinding::doEvaluate, +template +inline constexpr BindingFunctionVTable bindingFunctionVTableForQQmlPropertyBinding = { + &QQmlPropertyBinding::doEvaluate, [](void *qpropertyBinding){ QQmlPropertyBinding *binding = reinterpret_cast(qpropertyBinding); binding->jsExpression()->~QQmlPropertyBindingJS(); @@ -225,6 +234,24 @@ inline constexpr BindingFunctionVTable bindingFunctionVTable + switch (type.id()) { + FOR_TYPE(QMetaType::Int); + FOR_TYPE(QMetaType::QString); + FOR_TYPE(QMetaType::Double); + FOR_TYPE(QMetaType::Float); + FOR_TYPE(QMetaType::Bool); + default: + if (type.flags() & QMetaType::PointerToQObject) + return &QtPrivate::bindingFunctionVTableForQQmlPropertyBinding; + return &QtPrivate::bindingFunctionVTableForQQmlPropertyBinding; + } +#undef FOR_TYPE +} + class QQmlTranslationPropertyBinding { public: @@ -237,10 +264,179 @@ inline const QQmlPropertyBinding *QQmlPropertyBindingJS::asBinding() const { return std::launder(reinterpret_cast( reinterpret_cast(this) - - sizeof(QQmlPropertyBinding) + - QPropertyBindingPrivate::getSizeEnsuringAlignment() - QQmlPropertyBinding::jsExpressionOffsetLength())); } +static_assert(sizeof(QQmlPropertyBinding) == sizeof(QPropertyBindingPrivate)); // else the whole offset computatation will break +template +bool compareAndAssign(void *dataPtr, const void *result) +{ + if (*static_cast(result) == *static_cast(dataPtr)) + return false; + *static_cast(dataPtr) = *static_cast(result); + return true; +} + +template +bool QQmlPropertyBinding::evaluate(QMetaType metaType, void *dataPtr) +{ + const auto ctxt = jsExpression()->context(); + QQmlEngine *engine = ctxt ? ctxt->engine() : nullptr; + if (!engine) { + QPropertyBindingError error(QPropertyBindingError::EvaluationError); + if (auto currentBinding = QPropertyBindingPrivate::currentlyEvaluatingBinding()) + currentBinding->setError(std::move(error)); + return false; + } + QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); + ep->referenceScarceResources(); + + const auto handleErrorAndUndefined = [&](bool evaluatedToUndefined) { + ep->dereferenceScarceResources(); + if (jsExpression()->hasError()) { + QPropertyBindingError error(QPropertyBindingError::UnknownError, + jsExpression()->delayedError()->error().description()); + QPropertyBindingPrivate::currentlyEvaluatingBinding()->setError(std::move(error)); + bindingErrorCallback(this); + return false; + } + + if (evaluatedToUndefined) { + handleUndefinedAssignment(ep, dataPtr); + // if property has been changed due to reset, reset is responsible for + // notifying observers + return false; + } else if (isUndefined()) { + setIsUndefined(false); + } + + return true; + }; + + if (!hasBoundFunction()) { + Q_ASSERT(metaType.sizeOf() > 0); + + // No need to construct here. evaluate() expects uninitialized memory. + const auto size = [&]() -> qsizetype { + switch (type) { + case QMetaType::QObjectStar: return sizeof(QObject *); + case QMetaType::Bool: return sizeof(bool); + case QMetaType::Int: return (sizeof(int)); + case QMetaType::Double: return (sizeof(double)); + case QMetaType::Float: return (sizeof(float)); + case QMetaType::QString: return (sizeof(QString)); + default: return metaType.sizeOf(); + } + }(); + Q_ALLOCA_VAR(void, result, size); + + const bool evaluatedToUndefined = !jsExpression()->evaluate(&result, &metaType, 0); + if (!handleErrorAndUndefined(evaluatedToUndefined)) + return false; + + switch (type) { + case QMetaType::QObjectStar: + return compareAndAssign(dataPtr, result); + case QMetaType::Bool: + return compareAndAssign(dataPtr, result); + case QMetaType::Int: + return compareAndAssign(dataPtr, result); + case QMetaType::Double: + return compareAndAssign(dataPtr, result); + case QMetaType::Float: + return compareAndAssign(dataPtr, result); + case QMetaType::QString: { + const bool hasChanged = compareAndAssign(dataPtr, result); + static_cast(result)->~QString(); + return hasChanged; + } + default: + break; + } + + const bool hasChanged = !metaType.equals(result, dataPtr); + if (hasChanged) { + metaType.destruct(dataPtr); + metaType.construct(dataPtr, result); + } + metaType.destruct(result); + return hasChanged; + } + + bool evaluatedToUndefined = false; + QV4::Scope scope(engine->handle()); + QV4::ScopedValue result(scope, static_cast( + jsExpression())->evaluate(&evaluatedToUndefined)); + + if (!handleErrorAndUndefined(evaluatedToUndefined)) + return false; + + switch (type) { + case QMetaType::Bool: { + bool b; + if (result->isBoolean()) + b = result->booleanValue(); + else + b = result->toBoolean(); + if (b == *static_cast(dataPtr)) + return false; + *static_cast(dataPtr) = b; + return true; + } + case QMetaType::Int: { + int i; + if (result->isInteger()) + i = result->integerValue(); + else if (result->isNumber()) { + i = QV4::StaticValue::toInteger(result->doubleValue()); + } else { + break; + } + if (i == *static_cast(dataPtr)) + return false; + *static_cast(dataPtr) = i; + return true; + } + case QMetaType::Double: + if (result->isNumber()) { + double d = result->asDouble(); + if (d == *static_cast(dataPtr)) + return false; + *static_cast(dataPtr) = d; + return true; + } + break; + case QMetaType::Float: + if (result->isNumber()) { + float d = float(result->asDouble()); + if (d == *static_cast(dataPtr)) + return false; + *static_cast(dataPtr) = d; + return true; + } + break; + case QMetaType::QString: + if (result->isString()) { + QString s = result->toQStringNoThrow(); + if (s == *static_cast(dataPtr)) + return false; + *static_cast(dataPtr) = s; + return true; + } + break; + default: + break; + } + + QVariant resultVariant(scope.engine->toVariant(result, metaType)); + resultVariant.convert(metaType); + const bool hasChanged = !metaType.equals(resultVariant.constData(), dataPtr); + metaType.destruct(dataPtr); + metaType.construct(dataPtr, resultVariant.constData()); + return hasChanged; +} + QT_END_NAMESPACE #endif // QQMLPROPERTYBINDING_P_H diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 269f02afbd0..2ebba1eb720 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -51,8 +51,8 @@ #include #include +#include -#include // for toupper #include #include @@ -159,14 +159,23 @@ QQmlPropertyCache::QQmlPropertyCache() } /*! -Creates a new QQmlPropertyCache of \a metaObject. + Creates a standalone QQmlPropertyCache of \a metaObject. It is separate from the usual + QQmlPropertyCache hierarchy. Its parent is not equal to any other QQmlPropertyCache + created from QObject::staticMetaObject, for example. */ -QQmlPropertyCache::QQmlPropertyCache(const QMetaObject *metaObject, QTypeRevision metaObjectRevision) - : QQmlPropertyCache() +QQmlRefPointer QQmlPropertyCache::createStandalone( + const QMetaObject *metaObject, QTypeRevision metaObjectRevision) { Q_ASSERT(metaObject); - update(metaObject); + QQmlRefPointer result; + if (const QMetaObject *super = metaObject->superClass()) { + result.adopt(createStandalone(super, metaObjectRevision) + ->copyAndAppend(metaObject, metaObjectRevision)); + } else { + result.adopt(new QQmlPropertyCache()); + result->update(metaObject); + } if (metaObjectRevision.isValid() && metaObjectRevision != QTypeRevision::zero()) { // Set the revision of the meta object that this cache describes to be @@ -174,9 +183,13 @@ QQmlPropertyCache::QQmlPropertyCache(const QMetaObject *metaObject, QTypeRevisio // from a type that was created directly in C++, and not through QML. For such // types, the revision for each recorded QMetaObject would normally be zero, which // would exclude any revisioned properties. - for (int metaObjectOffset = 0; metaObjectOffset < allowedRevisionCache.size(); ++metaObjectOffset) - allowedRevisionCache[metaObjectOffset] = metaObjectRevision; + for (int metaObjectOffset = 0; metaObjectOffset < result->allowedRevisionCache.size(); + ++metaObjectOffset) { + result->allowedRevisionCache[metaObjectOffset] = metaObjectRevision; + } } + + return result; } QQmlPropertyCache::~QQmlPropertyCache() @@ -350,7 +363,7 @@ const QMetaObject *QQmlPropertyCache::createMetaObject() QQmlPropertyData *QQmlPropertyCache::maybeUnresolvedProperty(int index) const { - if (index < 0 || index >= (propertyIndexCacheStart + propertyIndexCache.count())) + if (index < 0 || index >= propertyCount()) return nullptr; QQmlPropertyData *rv = nullptr; @@ -514,7 +527,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, QVarLengthArray str(length+3); str[0] = 'o'; str[1] = 'n'; - str[2] = toupper(rawName[0]); + str[2] = QtMiscUtils::toAsciiUpper(rawName[0]); if (length > 1) memcpy(&str[3], &rawName[1], length - 1); str[length + 2] = '\0'; @@ -593,16 +606,6 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, } } -void QQmlPropertyCache::updateRecur(const QMetaObject *metaObject) -{ - if (!metaObject) - return; - - updateRecur(metaObject->superClass()); - - append(metaObject, QTypeRevision()); -} - void QQmlPropertyCache::update(const QMetaObject *metaObject) { Q_ASSERT(metaObject); @@ -622,7 +625,8 @@ void QQmlPropertyCache::update(const QMetaObject *metaObject) // cached in a parent cache. stringCache.reserve(pc + mc + sc); - updateRecur(metaObject); + if (metaObject) + append(metaObject, QTypeRevision()); } /*! \internal @@ -676,7 +680,8 @@ inline bool contextHasNoExtensions(const QQmlRefPointer &contex { // This context has no extension if its parent is the engine's rootContext, // which has children but no imports - return (!context->parent() || !context->parent()->imports()); + const QQmlRefPointer parent = context->parent(); + return (!parent || !parent->imports()); } inline int maximumIndexForProperty(QQmlPropertyData *prop, const int methodCount, const int signalCount, const int propertyCount) @@ -1062,6 +1067,7 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) property.setWritable(data->isWritable()); property.setResettable(data->isResettable()); property.setBindable(data->isBindable()); + property.setAlias(data->isAlias()); } for (int ii = 0; ii < methods.count(); ++ii) { diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index f3f81fbc789..689ce8d35fb 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -129,7 +129,10 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyCache : public QQmlRefCount { public: QQmlPropertyCache(); - QQmlPropertyCache(const QMetaObject *, QTypeRevision metaObjectRevision = QTypeRevision::zero()); + + static QQmlRefPointer createStandalone( + const QMetaObject *, QTypeRevision metaObjectRevision = QTypeRevision::zero()); + ~QQmlPropertyCache() override; void update(const QMetaObject *); @@ -246,8 +249,6 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyCache : public QQmlRefCount QQmlPropertyData *findProperty(StringCache::ConstIterator it, const QQmlVMEMetaObject *, const QQmlRefPointer &) const; - void updateRecur(const QMetaObject *); - template QQmlPropertyData *findNamedProperty(const K &key) const { @@ -326,7 +327,7 @@ inline const QMetaObject *QQmlPropertyCache::firstCppMetaObject() const inline QQmlPropertyData *QQmlPropertyCache::property(int index) const { - if (index < 0 || index >= (propertyIndexCacheStart + propertyIndexCache.count())) + if (index < 0 || index >= propertyCount()) return nullptr; if (index < propertyIndexCacheStart) diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp index ff607add092..f6bedc94e95 100644 --- a/src/qml/qml/qqmlpropertycachecreator.cpp +++ b/src/qml/qml/qqmlpropertycachecreator.cpp @@ -110,11 +110,15 @@ QQmlBindingInstantiationContext::QQmlBindingInstantiationContext(int referencing bool QQmlBindingInstantiationContext::resolveInstantiatingProperty() { - if (!instantiatingBinding || instantiatingBinding->type != QV4::CompiledData::Binding::Type_GroupProperty) + if (!instantiatingBinding + || instantiatingBinding->type() != QV4::CompiledData::Binding::Type_GroupProperty) { return true; + } + + if (!referencingObjectPropertyCache) + return false; Q_ASSERT(referencingObjectIndex >= 0); - Q_ASSERT(referencingObjectPropertyCache); Q_ASSERT(instantiatingBinding->propertyNameIndex != 0); bool notInRevision = false; @@ -147,6 +151,11 @@ void QQmlPendingGroupPropertyBindings::resolveMissingPropertyCaches(QQmlEnginePr if (propertyCaches->at(groupPropertyObjectIndex)) continue; + if (!pendingBinding.referencingObjectPropertyCache) { + pendingBinding.referencingObjectPropertyCache + = propertyCaches->at(pendingBinding.referencingObjectIndex); + } + if (!pendingBinding.resolveInstantiatingProperty()) continue; diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index 0a5e642c9fd..3ce665c24f6 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -67,8 +67,8 @@ inline QQmlError qQmlCompileError(const QV4::CompiledData::Location &location, const QString &description) { QQmlError error; - error.setLine(qmlConvertSourceCoordinate(location.line)); - error.setColumn(qmlConvertSourceCoordinate(location.column)); + error.setLine(qmlConvertSourceCoordinate(location.line())); + error.setColumn(qmlConvertSourceCoordinate(location.column())); error.setDescription(description); return error; } @@ -243,7 +243,7 @@ QQmlPropertyCacheCreator::buildMetaObjectsIncrementally() // create meta objects for inline components before compiling actual root component if (nodeIt != nodesSorted.rend()) { - const auto &ic = allICs[nodeIt->index]; + const auto &ic = allICs[nodeIt->index()]; QV4::ResolvedTypeReference *typeRef = objectContainer->resolvedType(ic.nameIndex); Q_ASSERT(propertyCaches->at(ic.objectIndex) == nullptr); Q_ASSERT(typeRef->typePropertyCache().isNull()); // not set yet @@ -290,7 +290,7 @@ inline QQmlError QQmlPropertyCacheCreator::buildMetaObjectRecur const CompiledObject *obj = objectContainer->objectAt(objectIndex); bool needVMEMetaObject = isVMERequired == VMEMetaObjectIsRequired::Always || obj->propertyCount() != 0 || obj->aliasCount() != 0 || obj->signalCount() != 0 || obj->functionCount() != 0 || obj->enumCount() != 0 - || (((obj->flags & QV4::CompiledData::Object::IsComponent) + || ((obj->hasFlag(QV4::CompiledData::Object::IsComponent) || (objectIndex == 0 && isAddressable(objectContainer->url()))) && !objectContainer->resolvedType(obj->inheritedTypeNameIndex)->isFullyDynamicType()); @@ -298,7 +298,8 @@ inline QQmlError QQmlPropertyCacheCreator::buildMetaObjectRecur auto binding = obj->bindingsBegin(); auto end = obj->bindingsEnd(); for ( ; binding != end; ++binding) { - if (binding->type == QV4::CompiledData::Binding::Type_Object && (binding->flags & QV4::CompiledData::Binding::IsOnAssignment)) { + if (binding->type() == QV4::CompiledData::Binding::Type_Object + && (binding->flags() & QV4::CompiledData::Binding::IsOnAssignment)) { // If the on assignment is inside a group property, we need to distinguish between QObject based // group properties and value type group properties. For the former the base type is derived from // the property that references us, for the latter we only need a meta-object on the referencing object @@ -340,24 +341,24 @@ inline QQmlError QQmlPropertyCacheCreator::buildMetaObjectRecur } } - if (QQmlPropertyCache *thisCache = propertyCaches->at(objectIndex)) { - auto binding = obj->bindingsBegin(); - auto end = obj->bindingsEnd(); - for ( ; binding != end; ++binding) - if (binding->type >= QV4::CompiledData::Binding::Type_Object) { - QQmlBindingInstantiationContext context(objectIndex, &(*binding), stringAt(binding->propertyNameIndex), thisCache); - - // Binding to group property where we failed to look up the type of the - // property? Possibly a group property that is an alias that's not resolved yet. - // Let's attempt to resolve it after we're done with the aliases and fill in the - // propertyCaches entry then. - if (!context.resolveInstantiatingProperty()) - pendingGroupPropertyBindings->append(context); - - QQmlError error = buildMetaObjectRecursively(binding->value.objectIndex, context, VMEMetaObjectIsRequired::Maybe); - if (error.isValid()) - return error; - } + QQmlPropertyCache *thisCache = propertyCaches->at(objectIndex); + auto binding = obj->bindingsBegin(); + auto end = obj->bindingsEnd(); + for ( ; binding != end; ++binding) { + if (binding->type() >= QV4::CompiledData::Binding::Type_Object) { + QQmlBindingInstantiationContext context(objectIndex, &(*binding), stringAt(binding->propertyNameIndex), thisCache); + + // Binding to group property where we failed to look up the type of the + // property? Possibly a group property that is an alias that's not resolved yet. + // Let's attempt to resolve it after we're done with the aliases and fill in the + // propertyCaches entry then. + if (!thisCache || !context.resolveInstantiatingProperty()) + pendingGroupPropertyBindings->append(context); + + QQmlError error = buildMetaObjectRecursively(binding->value.objectIndex, context, VMEMetaObjectIsRequired::Maybe); + if (error.isValid()) + return error; + } } QQmlError noError; @@ -448,7 +449,7 @@ inline QQmlError QQmlPropertyCacheCreator::createMetaObject(int auto aend = obj->aliasesEnd(); for ( ; a != aend; ++a) { bool notInRevision = false; - QQmlPropertyData *d = resolver.property(stringAt(a->nameIndex), ¬InRevision); + QQmlPropertyData *d = resolver.property(stringAt(a->nameIndex()), ¬InRevision); if (d && d->isFinal()) return qQmlCompileError(a->location, QQmlPropertyCacheCreatorBase::tr("Cannot override FINAL property")); } @@ -496,7 +497,7 @@ inline QQmlError QQmlPropertyCacheCreator::createMetaObject(int for ( ; a != aend; ++a) { auto flags = QQmlPropertyData::defaultSignalFlags(); - QString changedSigName = stringAt(a->nameIndex) + QLatin1String("Changed"); + QString changedSigName = stringAt(a->nameIndex()) + QLatin1String("Changed"); seenSignals.insert(changedSigName); cache->appendSignal(changedSigName, flags, effectiveMethodIndex++); @@ -606,15 +607,14 @@ inline QQmlError QQmlPropertyCacheCreator::createMetaObject(int if (type == QV4::CompiledData::BuiltinType::Var) propertyFlags.type = QQmlPropertyData::Flags::VarPropertyType; - if (type != QV4::CompiledData::BuiltinType::InvalidBuiltin) { propertyType = metaTypeForPropertyType(type); } else { - Q_ASSERT(!p->isBuiltinType); + Q_ASSERT(!p->isBuiltinType()); QQmlType qmltype; bool selfReference = false; - if (!imports->resolveType(stringAt(p->builtinTypeOrTypeNameIndex), &qmltype, nullptr, nullptr, + if (!imports->resolveType(stringAt(p->builtinTypeOrTypeNameIndex()), &qmltype, nullptr, nullptr, nullptr, QQmlType::AnyRegistrationType, &selfReference)) { return qQmlCompileError(p->location, QQmlPropertyCacheCreatorBase::tr("Invalid property type")); } @@ -646,13 +646,13 @@ inline QQmlError QQmlPropertyCacheCreator::createMetaObject(int typeIds = compilationUnit->typeIdsForComponent(); } - if (p->isList) { + if (p->isList()) { propertyType = typeIds.listId; } else { propertyType = typeIds.id; } } else { - if (p->isList) { + if (p->isList()) { propertyType = qmltype.qListTypeId(); } else { propertyType = qmltype.typeId(); @@ -660,18 +660,18 @@ inline QQmlError QQmlPropertyCacheCreator::createMetaObject(int } } - if (p->isList) + if (p->isList()) propertyFlags.type = QQmlPropertyData::Flags::QListType; else propertyFlags.type = QQmlPropertyData::Flags::QObjectDerivedType; } - if (!p->isReadOnly && !p->isList) + if (!p->isReadOnly() && !p->isList()) propertyFlags.setIsWritable(true); QString propertyName = stringAt(p->nameIndex); - if (!obj->defaultPropertyIsAlias && propertyIdx == obj->indexOfDefaultPropertyOrAlias) + if (!obj->hasAliasAsDefaultProperty() && propertyIdx == obj->indexOfDefaultPropertyOrAlias) cache->_defaultPropertyName = propertyName; cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, propertyType, propertyTypeVersion, effectiveSignalIndex); @@ -687,13 +687,14 @@ template inline QMetaType QQmlPropertyCacheCreator::metaTypeForParameter(const QV4::CompiledData::ParameterType ¶m, QString *customTypeName) { - if (param.indexIsBuiltinType) { + if (param.indexIsBuiltinType()) { // built-in type - return metaTypeForPropertyType(static_cast(int(param.typeNameIndexOrBuiltinType))); + return metaTypeForPropertyType( + static_cast(param.typeNameIndexOrBuiltinType())); } // lazily resolved type - const QString typeName = stringAt(param.typeNameIndexOrBuiltinType); + const QString typeName = stringAt(param.typeNameIndexOrBuiltinType()); if (customTypeName) *customTypeName = typeName; QQmlType qmltype; @@ -702,8 +703,15 @@ inline QMetaType QQmlPropertyCacheCreator::metaTypeForParameter QQmlType::AnyRegistrationType, &selfReference)) return QMetaType(); - if (!qmltype.isComposite()) - return qmltype.typeId(); + if (!qmltype.isComposite()) { + const QMetaType typeId = qmltype.typeId(); + if (!typeId.isValid() && qmltype.isInlineComponentType()) { + const int objectId = qmltype.inlineComponentId(); + return objectContainer->typeIdsForComponent(objectId).id; + } else { + return typeId; + } + } if (selfReference) return objectContainer->typeIdsForComponent().id; @@ -756,7 +764,7 @@ inline void QQmlPropertyCacheAliasCreator::appendAliasPropertie // from a binding. for (int i = 1; i < objectContainer->objectCount(); ++i) { const CompiledObject &component = *objectContainer->objectAt(i); - if (!(component.flags & QV4::CompiledData::Object::IsComponent)) + if (!component.hasFlag(QV4::CompiledData::Object::IsComponent)) continue; const auto rootBinding = component.bindingsBegin(); @@ -779,12 +787,12 @@ inline void QQmlPropertyCacheAliasCreator::appendAliasPropertie auto alias = object.aliasesBegin(); auto end = object.aliasesEnd(); for ( ; alias != end; ++alias) { - Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved); + Q_ASSERT(alias->hasFlag(QV4::CompiledData::Alias::Resolved)); - const int targetObjectIndex = objectForId(component, alias->targetObjectId); + const int targetObjectIndex = objectForId(component, alias->targetObjectId()); Q_ASSERT(targetObjectIndex >= 0); - if (alias->aliasToLocalAlias) + if (alias->isAliasToLocalAlias()) continue; if (alias->encodedMetaPropertyIndex == -1) @@ -826,18 +834,21 @@ inline void QQmlPropertyCacheAliasCreator::collectObjectsWithAl objectsWithAliases->append(objectIndex); // Stop at Component boundary - if (object.flags & QV4::CompiledData::Object::IsComponent && objectIndex != /*root object*/0) + if (object.hasFlag(QV4::CompiledData::Object::IsComponent) && objectIndex != /*root object*/0) return; auto binding = object.bindingsBegin(); auto end = object.bindingsEnd(); for (; binding != end; ++binding) { - if (binding->type != QV4::CompiledData::Binding::Type_Object - && binding->type != QV4::CompiledData::Binding::Type_AttachedProperty - && binding->type != QV4::CompiledData::Binding::Type_GroupProperty) - continue; - - collectObjectsWithAliasesRecursively(binding->value.objectIndex, objectsWithAliases); + switch (binding->type()) { + case QV4::CompiledData::Binding::Type_Object: + case QV4::CompiledData::Binding::Type_AttachedProperty: + case QV4::CompiledData::Binding::Type_GroupProperty: + collectObjectsWithAliasesRecursively(binding->value.objectIndex, objectsWithAliases); + break; + default: + break; + } } } @@ -854,12 +865,12 @@ inline QQmlError QQmlPropertyCacheAliasCreator::propertyDataFor propertyFlags->setIsAlias(true); - if (alias.aliasToLocalAlias) { + if (alias.isAliasToLocalAlias()) { const QV4::CompiledData::Alias *lastAlias = &alias; QVarLengthArray seenAliases({lastAlias}); do { - const int targetObjectIndex = objectForId(component, lastAlias->targetObjectId); + const int targetObjectIndex = objectForId(component, lastAlias->targetObjectId()); Q_ASSERT(targetObjectIndex >= 0); const CompiledObject *targetObject = objectContainer->objectAt(targetObjectIndex); Q_ASSERT(targetObject); @@ -876,17 +887,17 @@ inline QQmlError QQmlPropertyCacheAliasCreator::propertyDataFor seenAliases.append(targetAlias); lastAlias = targetAlias; - } while (lastAlias->aliasToLocalAlias); + } while (lastAlias->isAliasToLocalAlias()); return propertyDataForAlias(component, *lastAlias, type, version, propertyFlags, enginePriv); } - const int targetObjectIndex = objectForId(component, alias.targetObjectId); + const int targetObjectIndex = objectForId(component, alias.targetObjectId()); Q_ASSERT(targetObjectIndex >= 0); const CompiledObject &targetObject = *objectContainer->objectAt(targetObjectIndex); if (alias.encodedMetaPropertyIndex == -1) { - Q_ASSERT(alias.flags & QV4::CompiledData::Alias::AliasPointsToPointerObject); + Q_ASSERT(alias.hasFlag(QV4::CompiledData::Alias::AliasPointsToPointerObject)); auto *typeRef = objectContainer->resolvedType(targetObject.inheritedTypeNameIndex); if (!typeRef) { // Can be caused by the alias target not being a valid id or property. E.g.: @@ -897,10 +908,16 @@ inline QQmlError QQmlPropertyCacheAliasCreator::propertyDataFor } const auto referencedType = typeRef->type(); - if (referencedType.isValid()) + if (referencedType.isValid()) { *type = referencedType.typeId(); - else + if (!type->isValid() && referencedType.isInlineComponentType()) { + int objectId = referencedType.inlineComponentId(); + *type = objectContainer->typeIdsForComponent(objectId).id; + Q_ASSERT(type->isValid()); + } + } else { *type = typeRef->compilationUnit()->typeIds.id; + } *version = typeRef->version(); @@ -915,52 +932,74 @@ inline QQmlError QQmlPropertyCacheAliasCreator::propertyDataFor QQmlPropertyData *targetProperty = targetCache->property(coreIndex); Q_ASSERT(targetProperty); + const QMetaType targetPropType = targetProperty->propType(); + + const auto resolveType = [](QMetaType targetPropType) { + if (targetPropType.flags() & QMetaType::IsEnumeration) + return QMetaType::fromType(); + else + return targetPropType; + }; + + const auto populateWithPropertyData = [&](const QQmlPropertyData *property) { + *type = resolveType(property->propType()); + writable = property->isWritable(); + resettable = property->isResettable(); + bindable = property->isBindable(); + + // Copy type flags + propertyFlags->copyPropertyTypeFlags(property->flags()); + if (property->isVarProperty()) + propertyFlags->type = QQmlPropertyData::Flags::QVariantType; + }; + // for deep aliases, valueTypeIndex is always set - if (!QQmlMetaType::isValueType(targetProperty->propType()) && valueTypeIndex != -1) { + if (!QQmlMetaType::isValueType(targetPropType) && valueTypeIndex != -1) { // deep alias property - *type = targetProperty->propType(); - targetCache = enginePriv->propertyCacheForType(type->id()); - Q_ASSERT(targetCache); - targetProperty = targetCache->property(valueTypeIndex); - if (targetProperty == nullptr) { - return qQmlCompileError(alias.referenceLocation, - QQmlPropertyCacheCreatorBase::tr("Invalid alias target")); + QQmlRefPointer typeCache + = enginePriv->propertyCacheForType(targetPropType.id()); + + if (!typeCache) { + // See if it's a half-resolved composite type + if (const QV4::ResolvedTypeReference *typeRef + = objectContainer->resolvedType(targetPropType)) { + typeCache = typeRef->typePropertyCache(); + } } - *type = targetProperty->propType(); - writable = targetProperty->isWritable(); - resettable = targetProperty->isResettable(); - bindable = targetProperty->isBindable(); + const QQmlPropertyData *typeProperty = typeCache + ? typeCache->property(valueTypeIndex) + : nullptr; + if (typeProperty == nullptr) { + return qQmlCompileError( + alias.referenceLocation, + QQmlPropertyCacheCreatorBase::tr("Invalid alias target")); + } + populateWithPropertyData(typeProperty); } else { // value type or primitive type or enum - *type = targetProperty->propType(); - - writable = targetProperty->isWritable(); - resettable = targetProperty->isResettable(); - bindable = targetProperty->isBindable(); + populateWithPropertyData(targetProperty); if (valueTypeIndex != -1) { - const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForValueType(*type); - if (valueTypeMetaObject->property(valueTypeIndex).isEnumType()) - *type = QMetaType::fromType(); - else - *type = valueTypeMetaObject->property(valueTypeIndex).metaType(); - } else { - if (targetProperty->isEnum()) { - *type = QMetaType::fromType(); - } else { - // Copy type flags - propertyFlags->copyPropertyTypeFlags(targetProperty->flags()); - - if (targetProperty->isVarProperty()) - propertyFlags->type = QQmlPropertyData::Flags::QVariantType; - } + const QMetaObject *valueTypeMetaObject + = QQmlMetaType::metaObjectForValueType(*type); + const QMetaProperty valueTypeMetaProperty + = valueTypeMetaObject->property(valueTypeIndex); + *type = resolveType(valueTypeMetaProperty.metaType()); + + // We can only write or reset the value type property if we can write + // the value type itself. + resettable = writable && valueTypeMetaProperty.isResettable(); + writable = writable && valueTypeMetaProperty.isWritable(); + + bindable = valueTypeMetaProperty.isBindable(); } } } - propertyFlags->setIsWritable(!(alias.flags & QV4::CompiledData::Alias::IsReadOnly) && writable); + propertyFlags->setIsWritable( + writable && !alias.hasFlag(QV4::CompiledData::Alias::IsReadOnly)); propertyFlags->setIsResettable(resettable); propertyFlags->setIsBindable(bindable); return QQmlError(); @@ -984,7 +1023,7 @@ inline QQmlError QQmlPropertyCacheAliasCreator::appendAliasesTo auto alias = object.aliasesBegin(); auto end = object.aliasesEnd(); for ( ; alias != end; ++alias, ++aliasIndex) { - Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved); + Q_ASSERT(alias->hasFlag(QV4::CompiledData::Alias::Resolved)); QMetaType type; QTypeRevision version = QTypeRevision::zero(); @@ -994,9 +1033,9 @@ inline QQmlError QQmlPropertyCacheAliasCreator::appendAliasesTo if (error.isValid()) return error; - const QString propertyName = objectContainer->stringAt(alias->nameIndex); + const QString propertyName = objectContainer->stringAt(alias->nameIndex()); - if (object.defaultPropertyIsAlias && aliasIndex == object.indexOfDefaultPropertyOrAlias) + if (object.hasAliasAsDefaultProperty() && aliasIndex == object.indexOfDefaultPropertyOrAlias) propertyCache->_defaultPropertyName = propertyName; propertyCache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, @@ -1012,7 +1051,7 @@ inline int QQmlPropertyCacheAliasCreator::objectForId(const Com for (quint32 i = 0, count = component.namedObjectsInComponentCount(); i < count; ++i) { const int candidateIndex = component.namedObjectsInComponentTable()[i]; const CompiledObject &candidate = *objectContainer->objectAt(candidateIndex); - if (candidate.id == id) + if (candidate.objectId() == id) return candidateIndex; } return -1; diff --git a/src/qml/qml/qqmlpropertydata_p.h b/src/qml/qml/qqmlpropertydata_p.h index edf777ff180..1fbf24a1a72 100644 --- a/src/qml/qml/qqmlpropertydata_p.h +++ b/src/qml/qml/qqmlpropertydata_p.h @@ -281,7 +281,6 @@ class QQmlPropertyData { Q_ASSERT(idx >= std::numeric_limits::min()); Q_ASSERT(idx <= std::numeric_limits::max()); - Q_ASSERT(idx != m_coreIndex); m_overrideIndex = qint16(idx); } diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp index f1826b2f1cd..6a36c279e8f 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -106,10 +106,11 @@ QVector QQmlPropertyValidator::validateObject( return errors; } - if (obj->flags & QV4::CompiledData::Object::IsComponent && !(obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot)) { + if (obj->hasFlag(QV4::CompiledData::Object::IsComponent) + && !obj->hasFlag(QV4::CompiledData::Object::IsInlineComponentRoot)) { Q_ASSERT(obj->nBindings == 1); const QV4::CompiledData::Binding *componentBinding = obj->bindingTable(); - Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object); + Q_ASSERT(componentBinding->type() == QV4::CompiledData::Binding::Type_Object); return validateObject(componentBinding->value.objectIndex, componentBinding); } @@ -134,7 +135,7 @@ QVector QQmlPropertyValidator::validateObject( if (!binding->isGroupProperty()) continue; - if (binding->flags & QV4::CompiledData::Binding::IsOnAssignment) + if (binding->hasFlag(QV4::CompiledData::Binding::IsOnAssignment)) continue; if (populatingValueTypeGroupProperty) { @@ -163,9 +164,11 @@ QVector QQmlPropertyValidator::validateObject( binding = obj->bindingTable(); for (quint32 i = 0; i < obj->nBindings; ++i, ++binding) { QString name = stringAt(binding->propertyNameIndex); + const QV4::CompiledData::Binding::Type bindingType = binding->type(); + const QV4::CompiledData::Binding::Flags bindingFlags = binding->flags(); if (customParser) { - if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { + if (bindingType == QV4::CompiledData::Binding::Type_AttachedProperty) { if (customParser->flags() & QQmlCustomParser::AcceptsAttachedProperties) { customBindings << binding; continue; @@ -178,13 +181,14 @@ QVector QQmlPropertyValidator::validateObject( } bool bindingToDefaultProperty = false; - bool isGroupProperty = instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty; + bool isGroupProperty = instantiatingBinding + && instantiatingBinding->type() == QV4::CompiledData::Binding::Type_GroupProperty; bool notInRevision = false; QQmlPropertyData *pd = nullptr; if (!name.isEmpty()) { - if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression - || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject) { + if (bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerExpression + || bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerObject) { pd = propertyResolver.signal(name, ¬InRevision); } else { pd = propertyResolver.property(name, ¬InRevision, @@ -228,11 +232,12 @@ QVector QQmlPropertyValidator::validateObject( return recordError(binding->location, tr("Invalid attached object assignment")); } - if (binding->type >= QV4::CompiledData::Binding::Type_Object && (pd || binding->isAttachedProperty())) { + if (bindingType >= QV4::CompiledData::Binding::Type_Object + && (pd || binding->isAttachedProperty())) { const bool populatingValueTypeGroupProperty = pd && QQmlMetaType::metaObjectForValueType(pd->propType()) - && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment); + && !binding->hasFlag(QV4::CompiledData::Binding::IsOnAssignment); const QVector subObjectValidatorErrors = validateObject(binding->value.objectIndex, binding, populatingValueTypeGroupProperty); @@ -241,13 +246,13 @@ QVector QQmlPropertyValidator::validateObject( } // Signal handlers were resolved and checked earlier in the signal handler conversion pass. - if (binding->flags & (QV4::CompiledData::Binding::IsSignalHandlerExpression + if (binding->flags() & (QV4::CompiledData::Binding::IsSignalHandlerExpression | QV4::CompiledData::Binding::IsSignalHandlerObject | QV4::CompiledData::Binding::IsPropertyObserver)) { continue; } - if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { + if (bindingType == QV4::CompiledData::Binding::Type_AttachedProperty) { if (instantiatingBinding && (instantiatingBinding->isAttachedProperty() || instantiatingBinding->isGroupProperty())) { return recordError(binding->location, tr("Attached properties cannot be used here")); } @@ -261,15 +266,15 @@ QVector QQmlPropertyValidator::validateObject( if (!pd->isWritable() && !pd->isQList() && !binding->isGroupProperty() - && !(binding->flags & QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration) + && !(bindingFlags & QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration) ) { - if (assigningToGroupProperty && binding->type < QV4::CompiledData::Binding::Type_Object) + if (assigningToGroupProperty && bindingType < QV4::CompiledData::Binding::Type_Object) return recordError(binding->valueLocation, tr("Cannot assign a value directly to a grouped property")); return recordError(binding->valueLocation, tr("Invalid property assignment: \"%1\" is a read-only property").arg(name)); } - if (!pd->isQList() && (binding->flags & QV4::CompiledData::Binding::IsListItem)) { + if (!pd->isQList() && (bindingFlags & QV4::CompiledData::Binding::IsListItem)) { QString error; if (pd->propType() == QMetaType::fromType()) error = tr( "Cannot assign multiple values to a script property"); @@ -280,7 +285,7 @@ QVector QQmlPropertyValidator::validateObject( if (!bindingToDefaultProperty && !binding->isGroupProperty() - && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment) + && !(bindingFlags & QV4::CompiledData::Binding::IsOnAssignment) && assigningToGroupProperty) { QV4::CompiledData::Location loc = binding->valueLocation; if (loc < (*assignedGroupProperty)->valueLocation) @@ -291,11 +296,11 @@ QVector QQmlPropertyValidator::validateObject( return recordError(loc, tr("Cannot assign a value directly to a grouped property")); } - if (binding->type < QV4::CompiledData::Binding::Type_Script) { + if (bindingType < QV4::CompiledData::Binding::Type_Script) { QQmlError bindingError = validateLiteralBinding(propertyCache, pd, binding); if (bindingError.isValid()) return recordError(bindingError); - } else if (binding->type == QV4::CompiledData::Binding::Type_Object) { + } else if (bindingType == QV4::CompiledData::Binding::Type_Object) { QQmlError bindingError = validateObjectBinding(pd, name, binding); if (bindingError.isValid()) return recordError(bindingError); @@ -378,7 +383,7 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope QQmlError noError; if (property->isEnum()) { - if (binding->flags & QV4::CompiledData::Binding::IsResolvedEnum) + if (binding->hasFlag(QV4::CompiledData::Binding::IsResolvedEnum)) return noError; QString value = compilationUnit->bindingValueAsString(binding); @@ -396,11 +401,13 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope } auto warnOrError = [&](const QString &error) { - if (binding->type == QV4::CompiledData::Binding::Type_Null) { + if (binding->type() == QV4::CompiledData::Binding::Type_Null) { QQmlError warning; warning.setUrl(compilationUnit->url()); - warning.setLine(qmlConvertSourceCoordinate(binding->valueLocation.line)); - warning.setColumn(qmlConvertSourceCoordinate(binding->valueLocation.column)); + warning.setLine(qmlConvertSourceCoordinate( + binding->valueLocation.line())); + warning.setColumn(qmlConvertSourceCoordinate( + binding->valueLocation.column())); warning.setDescription(error + tr(" - Assigning null to incompatible properties in QML " "is deprecated. This will become a compile error in " "future versions of Qt.")); @@ -410,10 +417,11 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope return qQmlCompileError(binding->valueLocation, error); }; + const QV4::CompiledData::Binding::Type bindingType = binding->type(); const auto isStringBinding = [&]() -> bool { // validateLiteralBinding is not supposed to be used on scripts - Q_ASSERT(binding->type != QV4::CompiledData::Binding::Type_Script); - return binding->type == QV4::CompiledData::Binding::Type_String; + Q_ASSERT(bindingType != QV4::CompiledData::Binding::Type_Script); + return bindingType == QV4::CompiledData::Binding::Type_String; }; switch (property->propType().id()) { @@ -432,19 +440,17 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope } break; case QMetaType::QByteArray: { - if (binding->type != QV4::CompiledData::Binding::Type_String) { + if (bindingType != QV4::CompiledData::Binding::Type_String) return warnOrError(tr("Invalid property assignment: byte array expected")); - } } break; case QMetaType::QUrl: { - if (binding->type != QV4::CompiledData::Binding::Type_String) { + if (bindingType != QV4::CompiledData::Binding::Type_String) return warnOrError(tr("Invalid property assignment: url expected")); - } } break; case QMetaType::UInt: { - if (binding->type == QV4::CompiledData::Binding::Type_Number) { + if (bindingType == QV4::CompiledData::Binding::Type_Number) { double d = compilationUnit->bindingValueAsNumber(binding); if (double(uint(d)) == d) return noError; @@ -453,7 +459,7 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope } break; case QMetaType::Int: { - if (binding->type == QV4::CompiledData::Binding::Type_Number) { + if (bindingType == QV4::CompiledData::Binding::Type_Number) { double d = compilationUnit->bindingValueAsNumber(binding); if (double(int(d)) == d) return noError; @@ -462,13 +468,13 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope } break; case QMetaType::Float: { - if (binding->type != QV4::CompiledData::Binding::Type_Number) { + if (bindingType != QV4::CompiledData::Binding::Type_Number) { return warnOrError(tr("Invalid property assignment: number expected")); } } break; case QMetaType::Double: { - if (binding->type != QV4::CompiledData::Binding::Type_Number) { + if (bindingType != QV4::CompiledData::Binding::Type_Number) { return warnOrError(tr("Invalid property assignment: number expected")); } } @@ -566,7 +572,7 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope } break; case QMetaType::Bool: { - if (binding->type != QV4::CompiledData::Binding::Type_Boolean) { + if (bindingType != QV4::CompiledData::Binding::Type_Boolean) { return warnOrError(tr("Invalid property assignment: boolean expected")); } } @@ -598,12 +604,12 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope default: { // generate single literal value assignment to a list property if required if (property->propType() == QMetaType::fromType >()) { - if (binding->type != QV4::CompiledData::Binding::Type_Number) { + if (bindingType != QV4::CompiledData::Binding::Type_Number) { return warnOrError(tr("Invalid property assignment: number or array of numbers expected")); } break; } else if (property->propType() == QMetaType::fromType >()) { - bool ok = (binding->type == QV4::CompiledData::Binding::Type_Number); + bool ok = (bindingType == QV4::CompiledData::Binding::Type_Number); if (ok) { double n = compilationUnit->bindingValueAsNumber(binding); if (double(int(n)) != n) @@ -613,12 +619,12 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope return warnOrError(tr("Invalid property assignment: int or array of ints expected")); break; } else if (property->propType() == QMetaType::fromType >()) { - if (binding->type != QV4::CompiledData::Binding::Type_Boolean) { + if (bindingType != QV4::CompiledData::Binding::Type_Boolean) { return warnOrError(tr("Invalid property assignment: bool or array of bools expected")); } break; } else if (property->propType() == QMetaType::fromType >()) { - if (binding->type != QV4::CompiledData::Binding::Type_String) { + if (bindingType != QV4::CompiledData::Binding::Type_String) { return warnOrError(tr("Invalid property assignment: url or array of urls expected")); } break; @@ -632,7 +638,7 @@ QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *prope } else if (property->propType() == QMetaType::fromType()) { break; } else if (property->isQObject() - && binding->type == QV4::CompiledData::Binding::Type_Null) { + && bindingType == QV4::CompiledData::Binding::Type_Null) { break; } @@ -690,8 +696,8 @@ QQmlError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *propert { QQmlError noError; - if (binding->flags & QV4::CompiledData::Binding::IsOnAssignment) { - Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Object); + if (binding->hasFlag(QV4::CompiledData::Binding::IsOnAssignment)) { + Q_ASSERT(binding->type() == QV4::CompiledData::Binding::Type_Object); bool isValueSource = false; bool isPropertyInterceptor = false; @@ -740,7 +746,8 @@ QQmlError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *propert } } return noError; - } else if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject && property->isFunction()) { + } else if (binding->hasFlag(QV4::CompiledData::Binding::IsSignalHandlerObject) + && property->isFunction()) { return noError; } else if (isPrimitiveType(propType)) { auto typeName = QString::fromUtf8(QMetaType(propType).name()); diff --git a/src/qml/qml/qqmlpropertyvalueinterceptor_p.h b/src/qml/qml/qqmlpropertyvalueinterceptor_p.h index be061ba6cda..9ef8360d2dc 100644 --- a/src/qml/qml/qqmlpropertyvalueinterceptor_p.h +++ b/src/qml/qml/qqmlpropertyvalueinterceptor_p.h @@ -54,6 +54,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmlproxymetaobject.cpp b/src/qml/qml/qqmlproxymetaobject.cpp index 21d3c7ed05a..6f48146fa34 100644 --- a/src/qml/qml/qqmlproxymetaobject.cpp +++ b/src/qml/qml/qqmlproxymetaobject.cpp @@ -68,11 +68,8 @@ QQmlProxyMetaObject::~QQmlProxyMetaObject() QObject *QQmlProxyMetaObject::getProxy(int index) { if (!proxies) { - if (!proxies) { - proxies = new QObject*[metaObjects->count()]; - ::memset(proxies, 0, - sizeof(QObject *) * metaObjects->count()); - } + proxies = new QObject *[metaObjects->count()]; + ::memset(proxies, 0, sizeof(QObject *) * metaObjects->count()); } if (!proxies[index]) { @@ -112,6 +109,7 @@ int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void const int globalPropertyOffset = metaObjects->at(ii).propertyOffset; if (id >= globalPropertyOffset) { QObject *proxy = getProxy(ii); + Q_ASSERT(proxy); const int localProxyOffset = proxy->metaObject()->propertyOffset(); const int localProxyId = id - globalPropertyOffset + localProxyOffset; @@ -129,7 +127,7 @@ int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void const int globalMethodOffset = metaObjects->at(ii).methodOffset; if (id >= globalMethodOffset) { QObject *proxy = getProxy(ii); - + Q_ASSERT(proxy); const int localMethodOffset = proxy->metaObject()->methodOffset(); const int localMethodId = id - globalMethodOffset + localMethodOffset; diff --git a/src/qml/qml/qqmlscriptblob.cpp b/src/qml/qml/qqmlscriptblob.cpp index 7b7a842d04b..9e2b02162f5 100644 --- a/src/qml/qml/qqmlscriptblob.cpp +++ b/src/qml/qml/qqmlscriptblob.cpp @@ -169,8 +169,8 @@ void QQmlScriptBlob::done() QList errors = script.script->errors(); QQmlError error; error.setUrl(url()); - error.setLine(qmlConvertSourceCoordinate(script.location.line)); - error.setColumn(qmlConvertSourceCoordinate(script.location.column)); + error.setLine(qmlConvertSourceCoordinate(script.location.line())); + error.setColumn(qmlConvertSourceCoordinate(script.location.column())); error.setDescription(QQmlTypeLoader::tr("Script %1 unavailable").arg(script.script->urlString())); errors.prepend(error); setError(errors); @@ -238,8 +238,8 @@ void QQmlScriptBlob::initializeFromCompilationUnit(const QQmlRefPointerlocation.line); - error.setColumn(import->location.column); + error.setLine(import->location.line()); + error.setColumn(import->location.column()); errors.prepend(error); // put it back on the list after filling out information. setError(errors); return; diff --git a/src/qml/qml/qqmlscriptstring.cpp b/src/qml/qml/qqmlscriptstring.cpp index 3230e69b6d4..4df3a637858 100644 --- a/src/qml/qml/qqmlscriptstring.cpp +++ b/src/qml/qml/qqmlscriptstring.cpp @@ -220,3 +220,5 @@ bool QQmlScriptString::booleanLiteral(bool *ok) const QT_END_NAMESPACE +#include "moc_qqmlscriptstring.cpp" + diff --git a/src/qml/qml/qqmlscriptstring.h b/src/qml/qml/qqmlscriptstring.h index a768dabf9f3..d2ccfe5bc61 100644 --- a/src/qml/qml/qqmlscriptstring.h +++ b/src/qml/qml/qqmlscriptstring.h @@ -86,6 +86,7 @@ class Q_QML_EXPORT QQmlScriptString friend class QQmlScriptStringPrivate; friend class QQmlExpression; friend class QQmlBinding; + friend class QQmlPropertyBinding; friend struct QV4::QObjectWrapper; }; diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp index 811ff668c64..c283f7c7183 100644 --- a/src/qml/qml/qqmltype.cpp +++ b/src/qml/qml/qqmltype.cpp @@ -216,16 +216,15 @@ void QQmlTypePrivate::init() const return; } - auto setupExtendedMetaObject = [&]( - const QMetaObject *extMetaObject, - QObject *(*extFunc)(QObject *)) { - + auto setupExtendedMetaObject = [&](const QMetaObject *extMetaObject, + QObject *(*extFunc)(QObject *)) { if (!extMetaObject) return; // XXX - very inefficient QMetaObjectBuilder builder; - QQmlMetaType::clone(builder, extMetaObject, extMetaObject, extMetaObject); + QQmlMetaType::clone(builder, extMetaObject, extMetaObject, extMetaObject, + extFunc ? QQmlMetaType::CloneAll : QQmlMetaType::CloneEnumsOnly); builder.setFlags(MetaObjectFlag::DynamicMetaObject); QMetaObject *mmo = builder.toMetaObject(); mmo->d.superdata = mo; diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index 839d417a56f..d72fdb4d5c2 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -151,11 +151,13 @@ QQmlRefPointer QQmlTypeCompiler::compile() document->jsModule.fileName = typeData->urlString(); document->jsModule.finalUrl = typeData->finalUrlString(); QmlIR::JSCodeGen v4CodeGenerator(document, engine->v4engine()->illegalNames()); - if (!v4CodeGenerator.generateCodeForComponents(componentRoots())) { - recordError(v4CodeGenerator.error()); - return nullptr; + for (QmlIR::Object *object : qAsConst(document->objects)) { + if (!v4CodeGenerator.generateRuntimeFunctions(object)) { + Q_ASSERT(v4CodeGenerator.hasError()); + recordError(v4CodeGenerator.error()); + return nullptr; + } } - document->javaScriptCompilationUnit = v4CodeGenerator.generateCompilationUnit(/*generated unit data*/false); } @@ -180,8 +182,8 @@ QQmlRefPointer QQmlTypeCompiler::compile() void QQmlTypeCompiler::recordError(const QV4::CompiledData::Location &location, const QString &description) { QQmlError error; - error.setLine(qmlConvertSourceCoordinate(location.line)); - error.setColumn(qmlConvertSourceCoordinate(location.column)); + error.setLine(qmlConvertSourceCoordinate(location.line())); + error.setColumn(qmlConvertSourceCoordinate(location.column())); error.setDescription(description); error.setUrl(url()); errors << error; @@ -340,7 +342,8 @@ bool SignalHandlerResolver::resolveSignalHandlerExpressions(const QmlIR::Object for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) { const QString bindingPropertyName = stringAt(binding->propertyNameIndex); // Attached property? - if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { + const QV4::CompiledData::Binding::Type bindingType = binding->type(); + if (bindingType == QV4::CompiledData::Binding::Type_AttachedProperty) { const QmlIR::Object *attachedObj = qmlObjects.at(binding->value.objectIndex); auto *typeRef = resolvedType(binding->propertyNameIndex); QQmlType type = typeRef ? typeRef->type() : QQmlType(); @@ -373,7 +376,8 @@ bool SignalHandlerResolver::resolveSignalHandlerExpressions(const QmlIR::Object QQmlPropertyData * const signalPropertyData = resolver.property(signalName, /*notInRevision ptr*/nullptr); QQmlPropertyData * const qPropertyData = !qPropertyName.isEmpty() ? resolver.property(qPropertyName) : nullptr; QString finalSignalHandlerPropertyName = signalName; - uint flags = QV4::CompiledData::Binding::IsSignalHandlerExpression; + QV4::CompiledData::Binding::Flag flag + = QV4::CompiledData::Binding::IsSignalHandlerExpression; const bool isPropertyObserver = !signalPropertyData && qPropertyData && qPropertyData->isBindable(); if (signal && !(qPropertyData && qPropertyData->isAlias() && isPropertyObserver)) { @@ -395,7 +399,7 @@ bool SignalHandlerResolver::resolveSignalHandlerExpressions(const QmlIR::Object } } else if (isPropertyObserver) { finalSignalHandlerPropertyName = qPropertyName; - flags = QV4::CompiledData::Binding::IsPropertyObserver; + flag = QV4::CompiledData::Binding::IsPropertyObserver; } else { if (notInRevision) { // Try assinging it as a property later @@ -443,13 +447,13 @@ bool SignalHandlerResolver::resolveSignalHandlerExpressions(const QmlIR::Object } // Binding object to signal means connect the signal to the object's default method. - if (binding->type == QV4::CompiledData::Binding::Type_Object) { - binding->flags |= QV4::CompiledData::Binding::IsSignalHandlerObject; + if (bindingType == QV4::CompiledData::Binding::Type_Object) { + binding->setFlag(QV4::CompiledData::Binding::IsSignalHandlerObject); continue; } - if (binding->type != QV4::CompiledData::Binding::Type_Script) { - if (binding->type < QV4::CompiledData::Binding::Type_Script) { + if (bindingType != QV4::CompiledData::Binding::Type_Script) { + if (bindingType < QV4::CompiledData::Binding::Type_Script) { COMPILE_EXCEPTION(binding, tr("Cannot assign a value to a signal (expecting a script to be run)")); } else { COMPILE_EXCEPTION(binding, tr("Incorrectly specified signal assignment")); @@ -457,7 +461,7 @@ bool SignalHandlerResolver::resolveSignalHandlerExpressions(const QmlIR::Object } binding->propertyNameIndex = compiler->registerString(finalSignalHandlerPropertyName); - binding->flags |= flags; + binding->setFlag(flag); } return true; } @@ -481,12 +485,13 @@ bool QQmlEnumTypeResolver::resolveEnumBindings() QQmlPropertyResolver resolver(propertyCache); for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) { - if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression - || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject - || binding->flags & QV4::CompiledData::Binding::IsPropertyObserver) + const QV4::CompiledData::Binding::Flags bindingFlags = binding->flags(); + if (bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerExpression + || bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerObject + || bindingFlags & QV4::CompiledData::Binding::IsPropertyObserver) continue; - if (binding->type != QV4::CompiledData::Binding::Type_Script) + if (binding->type() != QV4::CompiledData::Binding::Type_Script) continue; const QString propertyName = stringAt(binding->propertyNameIndex); @@ -508,10 +513,10 @@ bool QQmlEnumTypeResolver::resolveEnumBindings() bool QQmlEnumTypeResolver::assignEnumToBinding(QmlIR::Binding *binding, QStringView, int enumValue, bool) { - binding->type = QV4::CompiledData::Binding::Type_Number; + binding->setType(QV4::CompiledData::Binding::Type_Number); binding->value.constantValueIndex = compiler->registerConstant(QV4::Encode((double)enumValue)); // binding->setNumberValueInternal((double)enumValue); - binding->flags |= QV4::CompiledData::Binding::IsResolvedEnum; + binding->setFlag(QV4::CompiledData::Binding::IsResolvedEnum); return true; } @@ -521,14 +526,24 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj, if (!prop->isEnum() && !isIntProp) return true; - if (!prop->isWritable() && !(binding->flags & QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration)) - COMPILE_EXCEPTION(binding, tr("Invalid property assignment: \"%1\" is a read-only property").arg(stringAt(binding->propertyNameIndex))); + if (!prop->isWritable() + && !(binding->hasFlag(QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration))) { + COMPILE_EXCEPTION(binding, tr("Invalid property assignment: \"%1\" is a read-only property") + .arg(stringAt(binding->propertyNameIndex))); + } - Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Script); + Q_ASSERT(binding->type() == QV4::CompiledData::Binding::Type_Script); const QString string = compiler->bindingAsString(obj, binding->value.compiledScriptIndex); if (!string.constData()->isUpper()) return true; + // reject any "complex" expression (even simple arithmetic) + // we do this by excluding everything that is not part of a + // valid identifier or a dot + for (const QChar c: string) + if (!(c.isLetterOrNumber() || c == u'.' || c == u'_' || c.isSpace())) + return true; + // we support one or two '.' in the enum phrase: // * . // * .. @@ -664,15 +679,21 @@ void QQmlCustomParserScriptIndexer::scanObjectRecursively(int objectIndex, bool if (!annotateScriptBindings) annotateScriptBindings = customParsers.contains(obj->inheritedTypeNameIndex); for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) { - if (binding->type >= QV4::CompiledData::Binding::Type_Object) { + switch (binding->type()) { + case QV4::CompiledData::Binding::Type_Script: + if (annotateScriptBindings) { + binding->stringIndex = compiler->registerString( + compiler->bindingAsString(obj, binding->value.compiledScriptIndex)); + } + break; + case QV4::CompiledData::Binding::Type_Object: + case QV4::CompiledData::Binding::Type_AttachedProperty: + case QV4::CompiledData::Binding::Type_GroupProperty: scanObjectRecursively(binding->value.objectIndex, annotateScriptBindings); - continue; - } else if (binding->type != QV4::CompiledData::Binding::Type_Script) - continue; - if (!annotateScriptBindings) - continue; - const QString script = compiler->bindingAsString(obj, binding->value.compiledScriptIndex); - binding->stringIndex = compiler->registerString(script); + break; + default: + break; + } } } @@ -701,7 +722,7 @@ void QQmlAliasAnnotator::annotateBindingsToAliases() bool notInRevision = false; QQmlPropertyData *pd = binding->propertyNameIndex != quint32(0) ? resolver.property(stringAt(binding->propertyNameIndex), ¬InRevision) : defaultProperty; if (pd && pd->isAlias()) - binding->flags |= QV4::CompiledData::Binding::IsBindingToAlias; + binding->setFlag(QV4::CompiledData::Binding::IsBindingToAlias); } } } @@ -728,7 +749,7 @@ void QQmlScriptStringScanner::scan() QQmlPropertyData *defaultProperty = obj->indexOfDefaultPropertyOrAlias != -1 ? propertyCache->parent()->defaultProperty() : propertyCache->defaultProperty(); for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) { - if (binding->type != QV4::CompiledData::Binding::Type_Script) + if (binding->type() != QV4::CompiledData::Binding::Type_Script) continue; bool notInRevision = false; QQmlPropertyData *pd = binding->propertyNameIndex != quint32(0) ? resolver.property(stringAt(binding->propertyNameIndex), ¬InRevision) : defaultProperty; @@ -774,9 +795,9 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI QQmlPropertyData *defaultProperty = obj->indexOfDefaultPropertyOrAlias != -1 ? propertyCache->parent()->defaultProperty() : propertyCache->defaultProperty(); for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) { - if (binding->type != QV4::CompiledData::Binding::Type_Object) + if (binding->type() != QV4::CompiledData::Binding::Type_Object) continue; - if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject) + if (binding->hasFlag(QV4::CompiledData::Binding::IsSignalHandlerObject)) continue; const QmlIR::Object *targetObject = qmlObjects->at(binding->value.objectIndex); @@ -848,7 +869,11 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI QmlIR::Binding *syntheticBinding = pool->New(); *syntheticBinding = *binding; - syntheticBinding->type = QV4::CompiledData::Binding::Type_Object; + + // The synthetic binding inside Component has no name. It's just "Component { Foo {} }". + syntheticBinding->propertyNameIndex = 0; + + syntheticBinding->setType(QV4::CompiledData::Binding::Type_Object); QString error = syntheticComponent->appendBinding(syntheticBinding, /*isListBinding*/false); Q_ASSERT(error.isEmpty()); Q_UNUSED(error); @@ -859,7 +884,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI } } -// resolve ignores everything relating to inline components +// Resolve ignores everything relating to inline components, except for implicit components. bool QQmlComponentAndAliasResolver::resolve(int root) { // Detect real Component {} objects as well as implicitly defined components, such as @@ -870,28 +895,35 @@ bool QQmlComponentAndAliasResolver::resolve(int root) const int startObjectIndex = root == 0 ? root : root+1; // root+1, as ic root is handled at the end for (int i = startObjectIndex; i < objCountWithoutSynthesizedComponents; ++i) { QmlIR::Object *obj = qmlObjects->at(i); - if (root == 0) { - // normal component root, skip over anything inline component related - if (obj->isInlineComponent || obj->flags & QV4::CompiledData::Object::InPartOfInlineComponent) { - continue; - } - } else { - if (!(obj->flags & QV4::CompiledData::Object::InPartOfInlineComponent) || - obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot) - break; // left current inline component (potentially entered a new one) - } - QQmlPropertyCache *cache = propertyCaches.at(i); - if (obj->inheritedTypeNameIndex == 0 && !cache) - continue; + const bool isInlineComponentRoot + = obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot; + const bool isPartOfInlineComponent + = obj->flags & QV4::CompiledData::Object::InPartOfInlineComponent; + QQmlPropertyCache *cache = propertyCaches.at(i); bool isExplicitComponent = false; - if (obj->inheritedTypeNameIndex) { auto *tref = resolvedType(obj->inheritedTypeNameIndex); Q_ASSERT(tref); if (tref->type().metaObject() == &QQmlComponent::staticMetaObject) isExplicitComponent = true; } + + if (root == 0) { + // normal component root, skip over anything inline component related + if (isInlineComponentRoot || isPartOfInlineComponent) + continue; + } else if (!isPartOfInlineComponent || isInlineComponentRoot) { + // We've left the current inline component (potentially entered a new one), + // but we still need to resolve implicit components which are part of inline components. + if (cache && !isExplicitComponent) + findAndRegisterImplicitComponents(obj, cache); + break; + } + + if (obj->inheritedTypeNameIndex == 0 && !cache) + continue; + if (!isExplicitComponent) { if (cache) findAndRegisterImplicitComponents(obj, cache); @@ -917,7 +949,7 @@ bool QQmlComponentAndAliasResolver::resolve(int root) COMPILE_EXCEPTION(rootBinding, tr("Component elements may not contain properties other than id")); } - if (rootBinding->next || rootBinding->type != QV4::CompiledData::Binding::Type_Object) + if (rootBinding->next || rootBinding->type() != QV4::CompiledData::Binding::Type_Object) COMPILE_EXCEPTION(obj, tr("Invalid component body specification")); // For the root object, we are going to collect ids/aliases and resolve them for as a separate @@ -985,13 +1017,16 @@ bool QQmlComponentAndAliasResolver::collectIdsAndAliases(int objectIndex) return true; for (const QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) { - if (binding->type != QV4::CompiledData::Binding::Type_Object - && binding->type != QV4::CompiledData::Binding::Type_AttachedProperty - && binding->type != QV4::CompiledData::Binding::Type_GroupProperty) - continue; - - if (!collectIdsAndAliases(binding->value.objectIndex)) - return false; + switch (binding->type()) { + case QV4::CompiledData::Binding::Type_Object: + case QV4::CompiledData::Binding::Type_AttachedProperty: + case QV4::CompiledData::Binding::Type_GroupProperty: + if (!collectIdsAndAliases(binding->value.objectIndex)) + return false; + break; + default: + break; + } } return true; @@ -1039,7 +1074,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex) if (!atLeastOneAliasResolved && !_objectsWithAliases.isEmpty()) { const QmlIR::Object *obj = qmlObjects->at(_objectsWithAliases.first()); for (auto alias = obj->aliasesBegin(), end = obj->aliasesEnd(); alias != end; ++alias) { - if (!(alias->flags & QV4::CompiledData::Alias::Resolved)) { + if (!alias->hasFlag(QV4::CompiledData::Alias::Resolved)) { recordError(alias->location, tr("Circular alias reference detected")); return false; } @@ -1061,7 +1096,7 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, bool seenUnresolvedAlias = false; for (QmlIR::Alias *alias = obj->firstAlias(); alias; alias = alias->next) { - if (alias->flags & QV4::CompiledData::Alias::Resolved) + if (alias->hasFlag(QV4::CompiledData::Alias::Resolved)) continue; seenUnresolvedAlias = true; @@ -1077,8 +1112,8 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, const QmlIR::Object *targetObject = qmlObjects->at(targetObjectIndex); Q_ASSERT(targetObject->id >= 0); - alias->targetObjectId = targetObject->id; - alias->aliasToLocalAlias = false; + alias->setTargetObjectId(targetObject->id); + alias->setIsAliasToLocalAlias(false); const QString aliasPropertyValue = stringAt(alias->propertyNameIndex); @@ -1095,7 +1130,7 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, QQmlPropertyIndex propIdx; if (property.isEmpty()) { - alias->flags |= QV4::CompiledData::Alias::AliasPointsToPointerObject; + alias->setFlag(QV4::CompiledData::Alias::AliasPointsToPointerObject); } else { QQmlPropertyCache *targetCache = propertyCaches.at(targetObjectIndex); if (!targetCache) { @@ -1114,7 +1149,7 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, bool aliasPointsToOtherAlias = false; int localAliasIndex = 0; for (auto targetAlias = targetObject->aliasesBegin(), end = targetObject->aliasesEnd(); targetAlias != end; ++targetAlias, ++localAliasIndex) { - if (stringAt(targetAlias->nameIndex) == property) { + if (stringAt(targetAlias->nameIndex()) == property) { aliasPointsToOtherAlias = true; break; } @@ -1122,8 +1157,8 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, if (aliasPointsToOtherAlias) { if (targetObjectIndex == objectIndex) { alias->localAliasIndex = localAliasIndex; - alias->aliasToLocalAlias = true; - alias->flags |= QV4::CompiledData::Alias::Resolved; + alias->setIsAliasToLocalAlias(true); + alias->setFlag(QV4::CompiledData::Alias::Resolved); ++numResolvedAliases; continue; } @@ -1185,12 +1220,12 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, } } else { if (targetProperty->isQObject()) - alias->flags |= QV4::CompiledData::Alias::AliasPointsToPointerObject; + alias->setFlag(QV4::CompiledData::Alias::AliasPointsToPointerObject); } } alias->encodedMetaPropertyIndex = propIdx.toEncoded(); - alias->flags |= QV4::CompiledData::Alias::Resolved; + alias->setFlag(QV4::CompiledData::Alias::Resolved); numResolvedAliases++; } @@ -1226,7 +1261,7 @@ bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex) if (obj->flags & QV4::CompiledData::Object::IsComponent && !obj->isInlineComponent) { Q_ASSERT(obj->bindingCount() == 1); const QV4::CompiledData::Binding *componentBinding = obj->firstBinding(); - Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object); + Q_ASSERT(componentBinding->type() == QV4::CompiledData::Binding::Type_Object); return scanObject(componentBinding->value.objectIndex); } @@ -1264,16 +1299,16 @@ bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex) QString name = stringAt(binding->propertyNameIndex); if (customParser) { - if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { + if (binding->type() == QV4::CompiledData::Binding::Type_AttachedProperty) { if (customParser->flags() & QQmlCustomParser::AcceptsAttachedProperties) { - binding->flags |= QV4::CompiledData::Binding::IsCustomParserBinding; + binding->setFlag(QV4::CompiledData::Binding::IsCustomParserBinding); obj->flags |= QV4::CompiledData::Object::HasCustomParserBindings; continue; } } else if (QmlIR::IRBuilder::isSignalPropertyName(name) && !(customParser->flags() & QQmlCustomParser::AcceptsSignalHandlers)) { obj->flags |= QV4::CompiledData::Object::HasCustomParserBindings; - binding->flags |= QV4::CompiledData::Binding::IsCustomParserBinding; + binding->setFlag(QV4::CompiledData::Binding::IsCustomParserBinding); continue; } } @@ -1292,7 +1327,8 @@ bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex) bool seenSubObjectWithId = false; - if (binding->type >= QV4::CompiledData::Binding::Type_Object && (pd || binding->isAttachedProperty())) { + if (binding->type() >= QV4::CompiledData::Binding::Type_Object + && (pd || binding->isAttachedProperty())) { qSwap(_seenObjectWithId, seenSubObjectWithId); const bool subObjectValid = scanObject(binding->value.objectIndex); qSwap(_seenObjectWithId, seenSubObjectWithId); @@ -1301,22 +1337,24 @@ bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex) _seenObjectWithId |= seenSubObjectWithId; } - if (!seenSubObjectWithId && binding->type != QV4::CompiledData::Binding::Type_GroupProperty + if (!seenSubObjectWithId && binding->type() + != QV4::CompiledData::Binding::Type_GroupProperty && !deferredPropertyNames.isEmpty() && deferredPropertyNames.contains(name)) { - binding->flags |= QV4::CompiledData::Binding::IsDeferredBinding; + binding->setFlag(QV4::CompiledData::Binding::IsDeferredBinding); obj->flags |= QV4::CompiledData::Object::HasDeferredBindings; } - if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression - || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject - || binding->flags & QV4::CompiledData::Binding::IsPropertyObserver) + const QV4::CompiledData::Binding::Flags bindingFlags = binding->flags(); + if (bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerExpression + || bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerObject + || bindingFlags & QV4::CompiledData::Binding::IsPropertyObserver) continue; if (!pd) { if (customParser) { obj->flags |= QV4::CompiledData::Object::HasCustomParserBindings; - binding->flags |= QV4::CompiledData::Binding::IsCustomParserBinding; + binding->setFlag(QV4::CompiledData::Binding::IsCustomParserBinding); } } } diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h index 1a100828f8c..5b92b8de4a4 100644 --- a/src/qml/qml/qqmltypecompiler_p.h +++ b/src/qml/qml/qqmltypecompiler_p.h @@ -132,6 +132,15 @@ struct QQmlTypeCompiler return resolvedTypes->value(id); } + QV4::ResolvedTypeReference *resolvedType(QMetaType type) const + { + for (QV4::ResolvedTypeReference *ref : std::as_const(*resolvedTypes)) { + if (ref->type().typeId() == type) + return ref; + } + return nullptr; + } + CompositeMetaTypeIds typeIdsForComponent(int objectId = 0) const; private: diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index ab2d83e57a9..a244bdd0ba6 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -160,6 +160,9 @@ bool QQmlTypeData::tryLoadFromDiskCache() for (int i = 0, count = m_compiledData->objectCount(); i < count; ++i) { auto object = m_compiledData->objectAt(i); m_typeReferences.collectFromObject(object); + m_typeReferences.collectFromFunctions( + m_compiledData->objectFunctionsBegin(object), + m_compiledData->objectFunctionsEnd(object)); const auto inlineComponentTable = object->inlineComponentTable(); for (auto i = 0; i != object->nInlineComponents; ++i) { ics.push_back(inlineComponentTable[i]); @@ -203,26 +206,20 @@ bool QQmlTypeData::tryLoadFromDiskCache() Q_ASSERT(errors.size()); QQmlError error(errors.takeFirst()); error.setUrl(m_importCache.baseUrl()); - error.setLine(qmlConvertSourceCoordinate(import->location.line)); - error.setColumn(qmlConvertSourceCoordinate(import->location.column)); + error.setLine(qmlConvertSourceCoordinate(import->location.line())); + error.setColumn(qmlConvertSourceCoordinate(import->location.column())); errors.prepend(error); // put it back on the list after filling out information. setError(errors); return false; } } - QQmlType containingType; - auto containingTypeName = finalUrl().fileName().split(QLatin1Char('.')).first(); - QTypeRevision version; - QQmlImportNamespace *ns = nullptr; - m_importCache.resolveType(containingTypeName, &containingType, &version, &ns); for (auto&& ic: ics) { QString const nameString = m_compiledData->stringAt(ic.nameIndex); - QByteArray const name = nameString.toUtf8(); auto importUrl = finalUrl(); importUrl.setFragment(QString::number(ic.objectIndex)); auto import = new QQmlImportInstance(); - m_importCache.addInlineComponentImport(import, nameString, importUrl, containingType); + m_importCache.addInlineComponentImport(import, nameString, importUrl, QQmlType()); } return true; @@ -334,8 +331,8 @@ void QQmlTypeData::done() QList errors = script.script->errors(); QQmlError error; error.setUrl(url()); - error.setLine(qmlConvertSourceCoordinate(script.location.line)); - error.setColumn(qmlConvertSourceCoordinate(script.location.column)); + error.setLine(qmlConvertSourceCoordinate(script.location.line())); + error.setColumn(qmlConvertSourceCoordinate(script.location.column())); error.setDescription(QQmlTypeLoader::tr("Script %1 unavailable").arg(script.script->urlString())); errors.prepend(error); setError(errors); @@ -358,8 +355,8 @@ void QQmlTypeData::done() QList errors = type.typeData ? type.typeData->errors() : QList{}; QQmlError error; error.setUrl(url()); - error.setLine(qmlConvertSourceCoordinate(type.location.line)); - error.setColumn(qmlConvertSourceCoordinate(type.location.column)); + error.setLine(qmlConvertSourceCoordinate(type.location.line())); + error.setColumn(qmlConvertSourceCoordinate(type.location.column())); error.setDescription(QQmlTypeLoader::tr("Type %1 has no inline component type called %2").arg(QStringView{typeName}.left(lastDot), type.type.pendingResolutionName())); errors.prepend(error); setError(errors); @@ -374,8 +371,8 @@ void QQmlTypeData::done() QList errors = type.typeData->errors(); QQmlError error; error.setUrl(url()); - error.setLine(qmlConvertSourceCoordinate(type.location.line)); - error.setColumn(qmlConvertSourceCoordinate(type.location.column)); + error.setLine(qmlConvertSourceCoordinate(type.location.line())); + error.setColumn(qmlConvertSourceCoordinate(type.location.column())); error.setDescription(QQmlTypeLoader::tr("Type %1 unavailable").arg(typeName)); errors.prepend(error); setError(errors); @@ -393,8 +390,8 @@ void QQmlTypeData::done() QList errors = type.typeData->errors(); QQmlError error; error.setUrl(url()); - error.setLine(qmlConvertSourceCoordinate(type.location.line)); - error.setColumn(qmlConvertSourceCoordinate(type.location.column)); + error.setLine(qmlConvertSourceCoordinate(type.location.line())); + error.setColumn(qmlConvertSourceCoordinate(type.location.column())); error.setDescription(QQmlTypeLoader::tr("Type %1 unavailable").arg(typeName)); errors.prepend(error); setError(errors); @@ -666,7 +663,13 @@ void QQmlTypeData::continueLoadFromIR() } } - m_typeReferences.collectFromObjects(m_document->objects.constBegin(), m_document->objects.constEnd()); + for (auto it = m_document->objects.constBegin(), end = m_document->objects.constEnd(); + it != end; ++it) { + const QmlIR::Object *object = *it; + m_typeReferences.collectFromObject(object); + m_typeReferences.collectFromFunctions(object->functionsBegin(), object->functionsEnd()); + } + m_importCache.setBaseUrl(finalUrl(), finalUrlString()); // For remote URLs, we don't delay the loading of the implicit import @@ -695,12 +698,15 @@ void QQmlTypeData::continueLoadFromIR() for (const QV4::CompiledData::Import *import : qAsConst(m_document->imports)) { if (!addImport(import, {}, &errors)) { Q_ASSERT(errors.size()); - QQmlError error(errors.takeFirst()); + + // We're only interested in the chronoligically last error. The previous + // errors might be from unsuccessfully trying to load a module from the + // resource file system. + QQmlError error = errors.first(); error.setUrl(m_importCache.baseUrl()); - error.setLine(qmlConvertSourceCoordinate(import->location.line)); - error.setColumn(qmlConvertSourceCoordinate(import->location.column)); - errors.prepend(error); // put it back on the list after filling out information. - setError(errors); + error.setLine(qmlConvertSourceCoordinate(import->location.line())); + error.setColumn(qmlConvertSourceCoordinate(import->location.column())); + setError(error); return; } } @@ -724,8 +730,10 @@ void QQmlTypeData::allDependenciesDone() QQmlError error; error.setDescription(QQmlTypeLoader::tr("module \"%1\" is not installed").arg(import->uri)); error.setUrl(m_importCache.baseUrl()); - error.setLine(qmlConvertSourceCoordinate(import->location.line)); - error.setColumn(qmlConvertSourceCoordinate(import->location.column)); + error.setLine(qmlConvertSourceCoordinate( + import->location.line())); + error.setColumn(qmlConvertSourceCoordinate( + import->location.column())); errors.prepend(error); } } @@ -855,8 +863,8 @@ void QQmlTypeData::resolveTypes() bool *selfReferenceDetection = unresolvedRef->needsCreation ? nullptr : &ref.selfReference; - if (!resolveType(name, version, ref, unresolvedRef->location.line, - unresolvedRef->location.column, reportErrors, + if (!resolveType(name, version, ref, unresolvedRef->location.line(), + unresolvedRef->location.column(), reportErrors, QQmlType::AnyRegistrationType, selfReferenceDetection) && reportErrors) return; @@ -875,11 +883,9 @@ void QQmlTypeData::resolveTypes() } } } - ref.version = version; - - ref.location.line = unresolvedRef->location.line; - ref.location.column = unresolvedRef->location.column; + ref.version = version; + ref.location = unresolvedRef->location; ref.needsCreation = unresolvedRef->needsCreation; m_resolvedTypes.insert(unresolvedRef.key(), ref); } diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index ce1625fb639..d2607009300 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -503,8 +503,7 @@ bool QQmlTypeLoader::Blob::fetchQmldir(const QUrl &url, PendingImportPtr import, { QQmlRefPointer data = typeLoader()->getQmldir(url); - data->setImport(this, std::move(import)); - data->setPriority(this, priority); + data->setPriority(this, std::move(import), priority); if (data->status() == Error) { // This qmldir must not exist - which is not an error @@ -539,7 +538,7 @@ bool QQmlTypeLoader::Blob::updateQmldir(const QQmlRefPointer &da if (!loadImportDependencies(import, qmldirIdentifier, errors)) return false; - import->priority = data->priority(this); + import->priority = 0; // Release this reference at destruction m_qmldirs << data; @@ -581,13 +580,15 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo scriptImported(blob, import->location, import->qualifier, QString()); } else if (import->type == QV4::CompiledData::Import::ImportLibrary) { - QString qmldirFilePath; - QString qmldirUrl; - - const QQmlImports::LocalQmldirResult qmldirResult = m_importCache.locateLocalQmldir( - importDatabase, import->uri, import->version, - &qmldirFilePath, &qmldirUrl); - if (qmldirResult == QQmlImports::QmldirFound) { + const QQmlImportDatabase::LocalQmldirSearchLocation searchMode = + QQmlMetaType::isStronglyLockedModule(import->uri, import->version) + ? QQmlImportDatabase::QmldirCacheOnly + : QQmlImportDatabase::QmldirFileAndCache; + + const QQmlImportDatabase::LocalQmldirResult qmldirResult + = importDatabase->locateLocalQmldir( + import->uri, import->version, searchMode, + [&](const QString &qmldirFilePath, const QString &qmldirUrl) { // This is a local library import const QTypeRevision actualVersion = m_importCache.addLibraryImport( importDatabase, import->uri, import->qualifier, @@ -623,13 +624,26 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo if (!module) QQmlMetaType::qmlRegisterModuleTypes(import->uri); } - } else if ( + return true; + }); + + switch (qmldirResult) { + case QQmlImportDatabase::QmldirFound: + return true; + case QQmlImportDatabase::QmldirNotFound: + case QQmlImportDatabase::QmldirInterceptedToRemote: + break; + case QQmlImportDatabase::QmldirRejected: + return false; + } + + if ( // Major version of module already registered: // We believe that the registration is complete. QQmlMetaType::typeModule(import->uri, import->version) // Otherwise, try to register further module types. - || (qmldirResult != QQmlImports::QmldirInterceptedToRemote + || (qmldirResult != QQmlImportDatabase::QmldirInterceptedToRemote && QQmlMetaType::qmlRegisterModuleTypes(import->uri)) // Otherwise, there is no way to register any further types. @@ -725,16 +739,14 @@ void QQmlTypeLoader::Blob::dependencyComplete(QQmlDataBlob *blob) { if (blob->type() == QQmlDataBlob::QmldirFile) { QQmlQmldirData *data = static_cast(blob); - - PendingImportPtr import = data->import(this); - QList errors; if (!qmldirDataAvailable(data, &errors)) { Q_ASSERT(errors.size()); QQmlError error(errors.takeFirst()); error.setUrl(m_importCache.baseUrl()); - error.setLine(qmlConvertSourceCoordinate(import->location.line)); - error.setColumn(qmlConvertSourceCoordinate(import->location.column)); + const QV4::CompiledData::Location importLocation = data->importLocation(this); + error.setLine(qmlConvertSourceCoordinate(importLocation.line())); + error.setColumn(qmlConvertSourceCoordinate(importLocation.column())); errors.prepend(error); // put it back on the list after filling out information. setError(errors); } @@ -783,28 +795,9 @@ bool QQmlTypeLoader::Blob::diskCacheEnabled() const bool QQmlTypeLoader::Blob::qmldirDataAvailable(const QQmlRefPointer &data, QList *errors) { - PendingImportPtr import = data->import(this); - data->setImport(this, nullptr); - - int priority = data->priority(this); - data->setPriority(this, 0); - - if (import) { - // Do we need to resolve this import? - const bool resolve = (import->priority == 0) || (import->priority > priority); - - if (resolve) { - // This is the (current) best resolution for this import - if (!updateQmldir(data, import, errors)) { - return false; - } - - import->priority = priority; - return true; - } - } - - return true; + return data->processImports(this, [&](PendingImportPtr import) { + return updateQmldir(data, import, errors); + }); } /*! diff --git a/src/qml/qml/qqmltypeloadernetworkreplyproxy.cpp b/src/qml/qml/qqmltypeloadernetworkreplyproxy.cpp index af976431637..bcc5306cf8d 100644 --- a/src/qml/qml/qqmltypeloadernetworkreplyproxy.cpp +++ b/src/qml/qml/qqmltypeloadernetworkreplyproxy.cpp @@ -72,3 +72,5 @@ void QQmlTypeLoaderNetworkReplyProxy::manualFinished(QNetworkReply *reply) } QT_END_NAMESPACE + +#include "moc_qqmltypeloadernetworkreplyproxy_p.cpp" diff --git a/src/qml/qml/qqmltypeloaderqmldircontent_p.h b/src/qml/qml/qqmltypeloaderqmldircontent_p.h index 55cd846925e..41755767baf 100644 --- a/src/qml/qml/qqmltypeloaderqmldircontent_p.h +++ b/src/qml/qml/qqmltypeloaderqmldircontent_p.h @@ -84,6 +84,7 @@ class QQmlTypeLoaderQmldirContent QString preferredPath() const { return m_parser.preferredPath(); } bool designerSupported() const { return m_parser.designerSupported(); } + bool hasTypeInfo() const { return !m_parser.typeInfos().isEmpty(); } private: QQmlDirParser m_parser; diff --git a/src/qml/qml/qqmltypemodule.cpp b/src/qml/qml/qqmltypemodule.cpp index 51207280319..c373a4904e5 100644 --- a/src/qml/qml/qqmltypemodule.cpp +++ b/src/qml/qml/qqmltypemodule.cpp @@ -87,23 +87,8 @@ void QQmlTypeModule::remove(const QQmlTypePrivate *type) QQmlMetaType::removeQQmlTypePrivate(elementIt.value(), type); } -QQmlType QQmlTypeModule::type(const QHashedStringRef &name, QTypeRevision version) const +QQmlType QQmlTypeModule::findType(const QList *types, QTypeRevision version) { - QMutexLocker lock(&m_mutex); - QList *types = m_typeHash.value(name); - if (types) { - for (int ii = 0; ii < types->count(); ++ii) - if (types->at(ii)->version.minorVersion() <= version.minorVersion()) - return QQmlType(types->at(ii)); - } - - return QQmlType(); -} - -QQmlType QQmlTypeModule::type(const QV4::String *name, QTypeRevision version) const -{ - QMutexLocker lock(&m_mutex); - QList *types = m_typeHash.value(name); if (types) { for (int ii = 0; ii < types->count(); ++ii) if (types->at(ii)->version.minorVersion() <= version.minorVersion()) diff --git a/src/qml/qml/qqmltypemodule_p.h b/src/qml/qml/qqmltypemodule_p.h index 0ba6245cbb9..37b9a32b90d 100644 --- a/src/qml/qml/qqmltypemodule_p.h +++ b/src/qml/qml/qqmltypemodule_p.h @@ -53,6 +53,7 @@ #include #include +#include #include #include #include @@ -72,6 +73,12 @@ struct String; class QQmlTypeModule { public: + enum class LockLevel { + Open = 0, + Weak = 1, + Strong = 2 + }; + QQmlTypeModule() = default; QQmlTypeModule(const QString &uri, quint8 majorVersion) : m_module(uri), m_majorVersion(majorVersion) @@ -80,8 +87,17 @@ class QQmlTypeModule void add(QQmlTypePrivate *); void remove(const QQmlTypePrivate *type); - bool isLocked() const { return m_locked.loadRelaxed() != 0; } - void lock() { m_locked.storeRelaxed(1); } + LockLevel lockLevel() const { return LockLevel(m_lockLevel.loadRelaxed()); } + bool setLockLevel(LockLevel mode) + { + while (true) { + const int currentLock = m_lockLevel.loadAcquire(); + if (currentLock > int(mode)) + return false; + if (currentLock == int(mode) || m_lockLevel.testAndSetRelease(currentLock, int(mode))) + return true; + } + } QString module() const { @@ -99,12 +115,24 @@ class QQmlTypeModule quint8 minimumMinorVersion() const { return m_minMinorVersion.loadRelaxed(); } quint8 maximumMinorVersion() const { return m_maxMinorVersion.loadRelaxed(); } - QQmlType type(const QHashedStringRef &, QTypeRevision version) const; - QQmlType type(const QV4::String *, QTypeRevision version) const; + QQmlType type(const QHashedStringRef &name, QTypeRevision version) const + { + QMutexLocker lock(&m_mutex); + return findType(m_typeHash.value(name), version); + } + + QQmlType type(const QV4::String *name, QTypeRevision version) const + { + QMutexLocker lock(&m_mutex); + return findType(m_typeHash.value(name), version); + } void walkCompositeSingletons(const std::function &callback) const; private: + static Q_QML_PRIVATE_EXPORT QQmlType findType( + const QList *types, QTypeRevision version); + const QString m_module; const quint8 m_majorVersion = 0; @@ -114,8 +142,8 @@ class QQmlTypeModule // Can only ever increase QAtomicInt m_maxMinorVersion = 0; - // Bool. Can only be set to 1 once. - QAtomicInt m_locked = 0; + // LockLevel. Can only be increased. + QAtomicInt m_lockLevel = int(LockLevel::Open); using TypeHash = QStringHash>; TypeHash m_typeHash; diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp index 45333668e34..0f23b3190ee 100644 --- a/src/qml/qml/qqmltypenamecache.cpp +++ b/src/qml/qml/qqmltypenamecache.cpp @@ -86,119 +86,5 @@ void QQmlTypeNameCache::add(const QHashedString &name, int importedScriptIndex, m_namedImports.insert(name, import); } -QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name) const -{ - Result result = query(m_namedImports, name); - - if (!result.isValid()) - result = typeSearch(m_anonymousImports, name); - - if (!result.isValid()) - result = query(m_anonymousCompositeSingletons, name); - - if (!result.isValid()) { - // Look up anonymous types from the imports of this document - QQmlImportNamespace *typeNamespace = nullptr; - QList errors; - QQmlType t; - bool typeFound = m_imports.resolveType(name, &t, nullptr, &typeNamespace, &errors); - if (typeFound) { - return Result(t); - } - - } - - return result; -} - -QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name, - const QQmlImportRef *importNamespace) const -{ - Q_ASSERT(importNamespace && importNamespace->scriptIndex == -1); - - Result result = typeSearch(importNamespace->modules, name); - - if (!result.isValid()) - result = query(importNamespace->compositeSingletons, name); - - if (!result.isValid()) { - // Look up types from the imports of this document - // ### it would be nice if QQmlImports allowed us to resolve a namespace - // first, and then types on it. - QString qualifiedTypeName = importNamespace->m_qualifier + QLatin1Char('.') + name.toString(); - QQmlImportNamespace *typeNamespace = nullptr; - QList errors; - QQmlType t; - bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, &typeNamespace, &errors); - if (typeFound) { - return Result(t); - } - } - - return result; -} - -QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, QQmlImport::RecursionRestriction recursionRestriction) const -{ - Result result = query(m_namedImports, name); - - if (!result.isValid()) - result = typeSearch(m_anonymousImports, name); - - if (!result.isValid()) - result = query(m_anonymousCompositeSingletons, name); - - if (!result.isValid()) { - // Look up anonymous types from the imports of this document - QString typeName = name->toQStringNoThrow(); - QQmlImportNamespace *typeNamespace = nullptr; - QList errors; - QQmlType t; - bool typeRecursionDetected = false; - bool typeFound = m_imports.resolveType(typeName, &t, nullptr, &typeNamespace, &errors, - QQmlType::AnyRegistrationType, - recursionRestriction == QQmlImport::AllowRecursion ? &typeRecursionDetected : nullptr); - if (typeFound) { - return Result(t); - } - - } - - return result; -} - -QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, const QQmlImportRef *importNamespace) const -{ - Q_ASSERT(importNamespace && importNamespace->scriptIndex == -1); - - QMap >::const_iterator it = m_namespacedImports.constFind(importNamespace); - if (it != m_namespacedImports.constEnd()) { - Result r = query(*it, name); - if (r.isValid()) - return r; - } - - Result r = typeSearch(importNamespace->modules, name); - - if (!r.isValid()) - r = query(importNamespace->compositeSingletons, name); - - if (!r.isValid()) { - // Look up types from the imports of this document - // ### it would be nice if QQmlImports allowed us to resolve a namespace - // first, and then types on it. - QString qualifiedTypeName = importNamespace->m_qualifier + QLatin1Char('.') + name->toQStringNoThrow(); - QQmlImportNamespace *typeNamespace = nullptr; - QList errors; - QQmlType t; - bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, &typeNamespace, &errors); - if (typeFound) { - return Result(t); - } - } - - return r; -} - QT_END_NAMESPACE diff --git a/src/qml/qml/qqmltypenamecache_p.h b/src/qml/qml/qqmltypenamecache_p.h index 974f99ecae0..5e1a88b2a57 100644 --- a/src/qml/qml/qqmltypenamecache_p.h +++ b/src/qml/qml/qqmltypenamecache_p.h @@ -104,16 +104,131 @@ class Q_QML_PRIVATE_EXPORT QQmlTypeNameCache : public QQmlRefCount const QQmlImportRef *importNamespace; int scriptIndex; }; - Result query(const QHashedStringRef &) const; - Result query(const QHashedStringRef &, const QQmlImportRef *importNamespace) const; - Result query(const QV4::String *, QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion) const; - Result query(const QV4::String *, const QQmlImportRef *importNamespace) const; + + enum class QueryNamespaced { No, Yes }; + + // Restrict the types allowed for key. We don't want QV4::ScopedString, for example. + + template + Result query(const QHashedStringRef &key) const + { + return doQuery(key); + } + + template + Result query(const QHashedStringRef &key, const QQmlImportRef *importNamespace) const + { + return doQuery(key, importNamespace); + } + + template + Result query(const QV4::String *key) const + { + return doQuery(key); + } + + template + Result query(const QV4::String *key, const QQmlImportRef *importNamespace) const + { + return doQuery(key, importNamespace); + } private: friend class QQmlImports; + static QHashedStringRef toHashedStringRef(const QHashedStringRef &key) { return key; } + static QHashedStringRef toHashedStringRef(const QV4::String *key) + { + const QV4::Heap::String *heapString = key->d(); + + // toQString() would also do simplifyString(). Therefore, we can be sure that this + // is safe. Any other operation on the string data cannot keep references on the + // non-simplified pieces. + if (heapString->subtype >= QV4::Heap::String::StringType_Complex) + heapString->simplifyString(); + + // This is safe because the string data is backed by the QV4::String we got as + // parameter. The contract about passing V4 values as parameters is that you have to + // scope them first, so that they don't get gc'd while the callee is working on them. + const QStringPrivate &text = heapString->text(); + return QHashedStringRef(QStringView(text.ptr, text.size)); + } + + static QString toQString(const QHashedStringRef &key) { return key.toString(); } + static QString toQString(const QV4::String *key) { return key->toQStringNoThrow(); } + + template + Result doQuery(Key name) const + { + Result result = doQuery(m_namedImports, name); + + if (!result.isValid()) + result = typeSearch(m_anonymousImports, name); + + if (!result.isValid()) + result = doQuery(m_anonymousCompositeSingletons, name); + + if (!result.isValid()) { + // Look up anonymous types from the imports of this document + // ### it would be nice if QQmlImports allowed us to resolve a namespace + // first, and then types on it. + QQmlImportNamespace *typeNamespace = nullptr; + QList errors; + QQmlType t; + bool typeRecursionDetected = false; + const bool typeFound = m_imports.resolveType( + toHashedStringRef(name), &t, nullptr, &typeNamespace, &errors, + QQmlType::AnyRegistrationType, + recursionRestriction == QQmlImport::AllowRecursion + ? &typeRecursionDetected + : nullptr); + if (typeFound) + return Result(t); + + } + + return result; + } + + template + Result doQuery(Key name, const QQmlImportRef *importNamespace) const + { + Q_ASSERT(importNamespace && importNamespace->scriptIndex == -1); + + if constexpr (queryNamespaced == QueryNamespaced::Yes) { + QMap >::const_iterator it + = m_namespacedImports.constFind(importNamespace); + if (it != m_namespacedImports.constEnd()) { + Result r = doQuery(*it, name); + if (r.isValid()) + return r; + } + } + + Result result = typeSearch(importNamespace->modules, name); + + if (!result.isValid()) + result = doQuery(importNamespace->compositeSingletons, name); + + if (!result.isValid()) { + // Look up types from the imports of this document + // ### it would be nice if QQmlImports allowed us to resolve a namespace + // first, and then types on it. + const QString qualifiedTypeName = importNamespace->m_qualifier + u'.' + toQString(name); + QQmlImportNamespace *typeNamespace = nullptr; + QList errors; + QQmlType t; + bool typeFound = m_imports.resolveType( + qualifiedTypeName, &t, nullptr, &typeNamespace, &errors); + if (typeFound) + return Result(t); + } + + return result; + } + template - Result query(const QStringHash &imports, Key key) const + Result doQuery(const QStringHash &imports, Key key) const { QQmlImportRef *i = imports.value(key); if (i) { @@ -129,7 +244,7 @@ class Q_QML_PRIVATE_EXPORT QQmlTypeNameCache : public QQmlRefCount } template - Result query(const QStringHash &urls, Key key) const + Result doQuery(const QStringHash &urls, Key key) const { QUrl *url = urls.value(key); if (url) { diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index c4d2d82a504..ce245ea6ceb 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -85,19 +85,48 @@ bool QQmlTypeWrapper::isSingleton() const return d()->type().isSingleton(); } +const QMetaObject *QQmlTypeWrapper::metaObject() const +{ + const QQmlType type = d()->type(); + if (!type.isValid()) + return nullptr; + + if (type.isSingleton()) { + auto metaObjectCandidate = type.metaObject(); + // if the candidate is the same as te baseMetaObject, we know that + // we don't have an extended singleton; in that case the + // actual instance might be subclass of type instead of type itself + // so we need to query the actual object for it's meta-object + if (metaObjectCandidate == type.baseMetaObject()) { + QQmlEnginePrivate *qmlEngine = QQmlEnginePrivate::get(engine()->qmlEngine()); + auto object = qmlEngine->singletonInstance(type); + if (object) + return object->metaObject(); + } + /* if we instead have an extended singleton, the dynamic proxy + meta-object must alreday be set up correctly + ### TODO: it isn't, as QQmlTypePrivate::init has no way to + query the object + */ + return metaObjectCandidate; + } + + return type.attachedPropertiesType(QQmlEnginePrivate::get(engine()->qmlEngine())); +} + QObject *QQmlTypeWrapper::object() const { const QQmlType type = d()->type(); if (!type.isValid()) return nullptr; - QQmlEngine *qmlEngine = engine()->qmlEngine(); + QQmlEnginePrivate *qmlEngine = QQmlEnginePrivate::get(engine()->qmlEngine()); if (type.isSingleton()) - return QQmlEnginePrivate::get(qmlEngine)->singletonInstance(type); + return qmlEngine->singletonInstance(type); return qmlAttachedPropertiesObject( d()->object, - type.attachedPropertiesFunction(QQmlEnginePrivate::get(qmlEngine))); + type.attachedPropertiesFunction(qmlEngine)); } QObject* QQmlTypeWrapper::singletonObject() const @@ -111,11 +140,14 @@ QObject* QQmlTypeWrapper::singletonObject() const QVariant QQmlTypeWrapper::toVariant() const { - if (!isSingleton()) - return QVariant::fromValue(d()->object); - QQmlEnginePrivate *e = QQmlEnginePrivate::get(engine()->qmlEngine()); const QQmlType type = d()->type(); + + if (!isSingleton()) { + return QVariant::fromValue(qmlAttachedPropertiesObject( + d()->object, type.attachedPropertiesFunction(e))); + } + if (type.isQJSValueSingleton()) return QVariant::fromValue(e->singletonInstance(type)); @@ -223,7 +255,9 @@ ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, cons // check for property. bool ok; - const ReturnedValue result = QV4::QObjectWrapper::getQmlProperty(v4, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, &ok); + const ReturnedValue result = QV4::QObjectWrapper::getQmlProperty( + v4, context, w->d(), qobjectSingleton, name, + QV4::QObjectWrapper::IgnoreRevision, &ok); if (hasProperty) *hasProperty = ok; @@ -264,8 +298,11 @@ ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, cons QObject *ao = qmlAttachedPropertiesObject( object, type.attachedPropertiesFunction(QQmlEnginePrivate::get(v4->qmlEngine()))); - if (ao) - return QV4::QObjectWrapper::getQmlProperty(v4, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty); + if (ao) { + return QV4::QObjectWrapper::getQmlProperty( + v4, context, w->d(), ao, name, QV4::QObjectWrapper::IgnoreRevision, + hasProperty); + } // Fall through to base implementation } @@ -411,8 +448,10 @@ ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const return Encode(false); QQmlRefPointer td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl()); - ExecutableCompilationUnit *cu = td->compilationUnit(); - myQmlType = qenginepriv->metaObjectForType(cu->typeIds.id.id()); + if (ExecutableCompilationUnit *cu = td->compilationUnit()) + myQmlType = qenginepriv->metaObjectForType(cu->typeIds.id.id()); + else + return Encode(false); // It seems myQmlType has some errors, so we could not compile it. } else { myQmlType = qenginepriv->metaObjectForType(myTypeId.id()); } @@ -450,11 +489,8 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object, QQmlPropertyData *property = ddata->propertyCache->property(name.getPointer(), qobjectSingleton, qmlContext); if (property) { ScopedValue val(scope, Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, qobjectSingleton))); - lookup->qobjectLookup.qmlTypeIc = This->internalClass(); - lookup->qobjectLookup.ic = val->objectValue()->internalClass(); - lookup->qobjectLookup.propertyCache = ddata->propertyCache; - lookup->qobjectLookup.propertyCache->addref(); - lookup->qobjectLookup.propertyData = property; + setupQObjectLookup(lookup, ddata, property, + val->objectValue(), This); lookup->getter = QQmlTypeWrapper::lookupSingletonProperty; return lookup->getter(lookup, engine, *object); } diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index 71e9ee04eb9..56d50bbf835 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -102,6 +102,7 @@ struct Q_QML_EXPORT QQmlTypeWrapper : Object V4_NEEDS_DESTROY bool isSingleton() const; + const QMetaObject *metaObject() const; QObject *object() const; QObject *singletonObject() const; diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index c2bbd7f4982..2cba0375e79 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -281,10 +281,27 @@ PropertyAttributes QQmlValueTypeWrapper::virtualGetOwnProperty(const Managed *m, { if (id.isString()) { const QQmlValueTypeWrapper *r = static_cast(m); - QQmlPropertyData result = r->dataForPropertyKey(id); - if (p && result.isValid()) - p->value = getGadgetProperty(r->engine(), r->d(), result.propType(), result.coreIndex(), result.isFunction(), result.isEnum()); - return result.isValid() ? Attr_Data : Attr_Invalid; + Q_ASSERT(r); + + const QQmlPropertyData result = r->dataForPropertyKey(id); + if (!result.isValid()) + return Attr_Invalid; // Property doesn't exist. Object shouldn't meddle with it. + + if (!p) + return Attr_Data; // Property exists, but we're not interested in the value + + const QQmlValueTypeReference *ref = r->as(); + if (!ref || ref->readReferenceValue()) { + // Property exists, and we can retrieve it + p->value = getGadgetProperty( + r->engine(), r->d(), result.propType(), result.coreIndex(), + result.isFunction(), result.isEnum()); + } else { + // Property exists, but we can't retrieve it. Make it undefined. + p->value = Encode::undefined(); + } + + return Attr_Data; } return QV4::Object::virtualGetOwnProperty(m, id, p); diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h index ed58157c260..a473fc54587 100644 --- a/src/qml/qml/qqmlvaluetypewrapper_p.h +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -163,6 +163,7 @@ struct Q_QML_EXPORT QQmlValueTypeWrapper : Object int typeId() const; QMetaType type() const; bool write(QObject *target, int propertyIndex) const; + const QMetaObject *metaObject() const { return d()->metaObject(); } QQmlPropertyData dataForPropertyKey(PropertyKey id) const; diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index e7248b038ac..053058341a7 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -236,17 +236,18 @@ void QQmlVMEMetaObjectEndpoint::tryConnect() const QV4::CompiledData::Alias *aliasData = &metaObject->compiledObject->aliasTable()[aliasId]; if (!aliasData->isObjectAlias()) { QQmlRefPointer ctxt = metaObject->ctxt; - QObject *target = ctxt->idValue(aliasData->targetObjectId); + QObject *target = ctxt->idValue(aliasData->targetObjectId()); if (!target) return; - QQmlData *targetDData = QQmlData::get(target, /*create*/false); - if (!targetDData) - return; QQmlPropertyIndex encodedIndex = QQmlPropertyIndex::fromEncoded(aliasData->encodedMetaPropertyIndex); int coreIndex = encodedIndex.coreIndex(); int valueTypeIndex = encodedIndex.valueTypeIndex(); - const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex); + QJSEngine *engine = qjsEngine(target); + if (!engine) + return; // dont crash + const QQmlPropertyData *pd = + QQmlData::ensurePropertyCache(engine, target)->property(coreIndex); if (pd && valueTypeIndex != -1 && !QQmlMetaType::valueType(pd->propType())) { // deep alias QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(metaObject->compilationUnit->engine->qmlEngine()); @@ -767,7 +768,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * } break; case QV4::CompiledData::BuiltinType::InvalidBuiltin: - if (property.isList) { + if (property.isList()) { // when reading from the list, we need to find the correct MetaObject, // namely this. However, obejct->metaObject might point to any MetaObject // down the inheritance hierarchy, so we need to store how far we have @@ -872,7 +873,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * writeProperty(id, *reinterpret_cast(a[0])); break; case QV4::CompiledData::BuiltinType::InvalidBuiltin: - if (property.isList) { + if (property.isList()) { // Writing such a property is not supported. Content is added through the list property // methods. } else { @@ -894,16 +895,18 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * if (id < aliasCount) { const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[id]; - if ((aliasData->flags & QV4::CompiledData::Alias::AliasPointsToPointerObject) && c == QMetaObject::ReadProperty) - *reinterpret_cast(a[0]) = nullptr; + if (aliasData->hasFlag(QV4::CompiledData::Alias::AliasPointsToPointerObject) + && c == QMetaObject::ReadProperty){ + *reinterpret_cast(a[0]) = nullptr; + } if (ctxt.isNull()) return -1; - while (aliasData->aliasToLocalAlias) + while (aliasData->isAliasToLocalAlias()) aliasData = &compiledObject->aliasTable()[aliasData->localAliasIndex]; - QObject *target = ctxt->idValue(aliasData->targetObjectId); + QObject *target = ctxt->idValue(aliasData->targetObjectId()); if (!target) return -1; @@ -922,15 +925,20 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * int coreIndex = encodedIndex.coreIndex(); const int valueTypePropertyIndex = encodedIndex.valueTypeIndex(); - // Remove binding (if any) on write - if(c == QMetaObject::WriteProperty) { - int flags = *reinterpret_cast(a[3]); - if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) { - QQmlData *targetData = QQmlData::get(target); - if (targetData && targetData->hasBindingBit(coreIndex)) - QQmlPropertyPrivate::removeBinding(target, encodedIndex); + const auto removePendingBinding + = [c, a](QObject *target, int coreIndex, QQmlPropertyIndex encodedIndex) { + // Remove binding (if any) on write + if (c == QMetaObject::WriteProperty) { + int flags = *reinterpret_cast(a[3]); + if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) { + QQmlData *targetData = QQmlData::get(target); + if (targetData && targetData->hasBindingBit(coreIndex)) { + QQmlPropertyPrivate::removeBinding(target, encodedIndex); + targetData->clearBindingBit(coreIndex); + } + } } - } + }; if (valueTypePropertyIndex != -1) { if (!targetDData->propertyCache) @@ -940,6 +948,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance( ctxt->engine(), pd->propType()); if (valueType) { + removePendingBinding(target, coreIndex, encodedIndex); valueType->read(target, coreIndex); int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a); @@ -951,10 +960,14 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * // deep alias void *argv[1] = { &target }; QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, argv); + removePendingBinding( + target, valueTypePropertyIndex, + QQmlPropertyIndex(valueTypePropertyIndex)); return QMetaObject::metacall(target, c, valueTypePropertyIndex, a); } } else { + removePendingBinding(target, coreIndex, encodedIndex); return QMetaObject::metacall(target, c, coreIndex, a); } @@ -1006,7 +1019,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * auto arguments = methodData->hasArguments() ? methodData->arguments() : nullptr; if (arguments && arguments->names) { - const auto parameterCount = arguments->names->count(); + const quint32 parameterCount = arguments->names->count(); Q_ASSERT(parameterCount == function->formalParameterCount()); if (void *result = a[0]) arguments->types[0].destruct(result); @@ -1250,9 +1263,9 @@ bool QQmlVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex, const int aliasId = index - propOffset() - compiledObject->nProperties; const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[aliasId]; - while (aliasData->aliasToLocalAlias) + while (aliasData->isAliasToLocalAlias()) aliasData = &compiledObject->aliasTable()[aliasData->localAliasIndex]; - *target = ctxt->idValue(aliasData->targetObjectId); + *target = ctxt->idValue(aliasData->targetObjectId()); if (!*target) return false; @@ -1280,7 +1293,7 @@ void QQmlVMEMetaObject::connectAlias(int aliasId) } endpoint->metaObject = this; - endpoint->connect(ctxt->idValueBindings(aliasData->targetObjectId)); + endpoint->connect(ctxt->idValueBindings(aliasData->targetObjectId())); endpoint->tryConnect(); } diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index f15c3aa2015..46dc108b9e7 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -375,26 +375,10 @@ QVariant QtObject::quaternion(double scalar, double x, double y, double z) const } /*! - \qmlmethod matrix4x4 Qt::matrix4x4(real m11, real m12, real m13, real m14, real m21, real m22, real m23, real m24, real m31, real m32, real m33, real m34, real m41, real m42, real m43, real m44) - - Returns a matrix4x4 with the specified values. - - The arguments correspond to their positions in the matrix: + \qmlmethod matrix4x4 Qt::matrix4x4() - \table - \row \li \a m11 \li \a m12 \li \a m13 \li \a m14 - \row \li \a m21 \li \a m22 \li \a m23 \li \a m24 - \row \li \a m31 \li \a m32 \li \a m33 \li \a m34 - \row \li \a m41 \li \a m42 \li \a m43 \li \a m44 - \endtable - - Alternatively, the function may be called with a single argument - where that argument is a JavaScript array which contains the sixteen - matrix values. - - Finally, the function may be called with no arguments and the resulting - matrix will be the identity matrix. -*/ + Returns an identity matrix4x4. + */ QVariant QtObject::matrix4x4() const { QVariant variant; @@ -402,6 +386,21 @@ QVariant QtObject::matrix4x4() const return variant; } +/*! + \qmlmethod matrix4x4 Qt::matrix4x4(var values) + + Returns a matrix4x4 with the specified \a values. \a values is expected to + be a JavaScript array with 16 entries. + + The array indices correspond to positions in the matrix as follows: + + \table + \row \li 0 \li 1 \li 2 \li 3 + \row \li 4 \li 5 \li 6 \li 7 + \row \li 8 \li 9 \li 10 \li 11 + \row \li 12 \li 13 \li 14 \li 15 + \endtable +*/ QVariant QtObject::matrix4x4(const QJSValue &value) const { if (value.isObject()) { @@ -415,6 +414,20 @@ QVariant QtObject::matrix4x4(const QJSValue &value) const return QVariant(); } +/*! + \qmlmethod matrix4x4 Qt::matrix4x4(real m11, real m12, real m13, real m14, real m21, real m22, real m23, real m24, real m31, real m32, real m33, real m34, real m41, real m42, real m43, real m44) + + Returns a matrix4x4 with the specified values. + + The arguments correspond to their positions in the matrix: + + \table + \row \li \a m11 \li \a m12 \li \a m13 \li \a m14 + \row \li \a m21 \li \a m22 \li \a m23 \li \a m24 + \row \li \a m31 \li \a m32 \li \a m33 \li \a m34 + \row \li \a m41 \li \a m42 \li \a m43 \li \a m44 + \endtable +*/ QVariant QtObject::matrix4x4(double m11, double m12, double m13, double m14, double m21, double m22, double m23, double m24, double m31, double m32, double m33, double m34, @@ -810,10 +823,31 @@ bool QtObject::openUrlExternally(const QUrl &url) const return QQml_guiProvider()->openUrlExternally(resolvedUrl(url)); } +/*! + \qmlmethod url Qt::url(url url) + + Returns \a url verbatim. This can be used to force a type coercion to \c url. + In contrast to Qt.resolvedUrl() this retains any relative URLs. As strings + are implicitly converted to urls, the function can be called with a string + as argument, and will then return a url. + + \sa resolvedUrl() +*/ +QUrl QtObject::url(const QUrl &url) const +{ + return url; +} + /*! \qmlmethod url Qt::resolvedUrl(url url) Returns \a url resolved relative to the URL of the caller. + + If there is no caller or the caller is not associated with a QML context, + returns \a url resolved relative to the QML engine's base URL. If the QML + engine has no base URL, just returns \a url. + + \sa url() */ QUrl QtObject::resolvedUrl(const QUrl &url) const { @@ -824,6 +858,29 @@ QUrl QtObject::resolvedUrl(const QUrl &url) const return url; } +/*! + \qmlmethod url Qt::resolvedUrl(url url, object context) + + Returns \a url resolved relative to the URL of the QML context of + \a context. If \a context is not associated with a QML context, + returns \a url resolved relative to the QML engine's base URL. If + the QML engine has no base URL, just returns \a url. + + \sa url() +*/ +QUrl QtObject::resolvedUrl(const QUrl &url, QObject *context) const +{ + if (context) { + QQmlData *data = QQmlData::get(context); + if (data && data->outerContext) + return data->outerContext->resolvedUrl(url); + } + + if (QQmlEngine *engine = qmlEngine()) + return engine->baseUrl().resolved(url); + return url; +} + /*! \qmlmethod list Qt::fontFamilies() @@ -1031,7 +1088,7 @@ QObject *QtObject::createQmlObject(const QString &qml, QObject *parent, const QU } /*! -\qmlmethod object Qt::createComponent(url, mode, parent) +\qmlmethod Component Qt::createComponent(url url, enumeration mode, QtObject parent) Returns a \l Component object created using the QML file at the specified \a url, or \c null if an empty string was given. diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h index 972a0d0b314..7f40a34dddb 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h +++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h @@ -144,7 +144,9 @@ class Q_QML_EXPORT QtObject : public QObject Q_INVOKABLE QLocale locale(const QString &name) const; #endif + Q_INVOKABLE QUrl url(const QUrl &url) const; Q_INVOKABLE QUrl resolvedUrl(const QUrl &url) const; + Q_INVOKABLE QUrl resolvedUrl(const QUrl &url, QObject *context) const; Q_INVOKABLE bool openUrlExternally(const QUrl &url) const; Q_INVOKABLE QVariant font(const QJSValue &fontSpecifier) const; diff --git a/src/qml/qmldirparser/qqmldirparser.cpp b/src/qml/qmldirparser/qqmldirparser.cpp index 1dbf35f1d3b..ae6edde3c02 100644 --- a/src/qml/qmldirparser/qqmldirparser.cpp +++ b/src/qml/qmldirparser/qqmldirparser.cpp @@ -85,6 +85,7 @@ void QQmlDirParser::clear() _designerSupported = false; _typeInfos.clear(); _classNames.clear(); + _linkTarget.clear(); } inline static void scanSpace(const QChar *&ch) { @@ -321,6 +322,24 @@ bool QQmlDirParser::parse(const QString &source) } _preferredPath = sections[1]; + } else if (sections[0] == QLatin1String("linktarget")) { + if (sectionCount < 2) { + reportError(lineNumber, 0, + QStringLiteral("linktarget directive requires an argument, " + "but %1 were provided") + .arg(sectionCount - 1)); + continue; + } + + if (!_linkTarget.isEmpty()) { + reportError( + lineNumber, 0, + QStringLiteral( + "only one linktarget directive may be defined in a qmldir file")); + continue; + } + + _linkTarget = sections[1]; } else if (sectionCount == 2) { // No version specified (should only be used for relative qmldir files) const Component entry(sections[0], sections[1], QTypeRevision()); diff --git a/src/qml/qmldirparser/qqmldirparser_p.h b/src/qml/qmldirparser/qqmldirparser_p.h index eabaceae915..22073d26c5f 100644 --- a/src/qml/qmldirparser/qqmldirparser_p.h +++ b/src/qml/qmldirparser/qqmldirparser_p.h @@ -161,6 +161,7 @@ class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlDirParser QStringList typeInfos() const; QStringList classNames() const; QString preferredPath() const; + QString linkTarget() const { return _linkTarget; } private: bool maybeAddComponent(const QString &typeName, const QString &fileName, const QString &version, QHash &hash, int lineNumber = -1, bool multi = true); @@ -178,6 +179,7 @@ class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlDirParser bool _designerSupported = false; QStringList _typeInfos; QStringList _classNames; + QString _linkTarget; }; using QQmlDirComponents = QMultiHash; diff --git a/src/qml/qmldirparser/qqmlimportresolver_p.h b/src/qml/qmldirparser/qqmlimportresolver_p.h index c2f49ee4ec7..743e9f55269 100644 --- a/src/qml/qmldirparser/qqmlimportresolver_p.h +++ b/src/qml/qmldirparser/qqmlimportresolver_p.h @@ -51,13 +51,15 @@ // We mean it. // +#include + #include #include #include QT_BEGIN_NAMESPACE -QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths, +Q_QMLCOMPILER_PRIVATE_EXPORT QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths, QTypeRevision version); QT_END_NAMESPACE diff --git a/src/qml/qtqmlglobal_p.h b/src/qml/qtqmlglobal_p.h index 0bdad8f08f1..4c0ba338d8f 100644 --- a/src/qml/qtqmlglobal_p.h +++ b/src/qml/qtqmlglobal_p.h @@ -59,8 +59,6 @@ #define Q_QML_PRIVATE_EXPORT Q_QML_EXPORT -void Q_QML_PRIVATE_EXPORT qml_register_types_QtQml(); - #if !defined(QT_QMLDEVTOOLS_LIB) && !defined(QT_BUILD_QMLDEVTOOLS_LIB) # define Q_QML_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT #else diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp index 8e74711776c..3fe7f12a821 100644 --- a/src/qml/types/qqmlbind.cpp +++ b/src/qml/types/qqmlbind.cpp @@ -357,23 +357,18 @@ void QQmlBind::setDelayed(bool delayed) be restored when the binding is disabled. The possible values are: - \list - \li Binding.RestoreNone The original value is not restored at all - \li Binding.RestoreBinding The original value is restored if it was another - binding. In that case the old binding is in effect again. - \li Binding.RestoreValue The original value is restored if it was a plain - value rather than a binding. - \li Binding.RestoreBindingOrValue The original value is always restored. - \endlist - The default value is \c Binding.RestoreBindingOrValue. + \value Binding.RestoreNone The original value is not restored at all + \value Binding.RestoreBinding The original value is restored if it was another binding. + In that case the old binding is in effect again. + \value Binding.RestoreValue The original value is restored if it was a plain + value rather than a binding. + \value Binding.RestoreBindingOrValue The original value is always restored. - If you rely on any specific behavior regarding the restoration of plain - values when bindings get disabled you should migrate to explicitly set the - restoreMode. + The default value is \c Binding.RestoreBindingOrValue. - Reliance on a restoreMode that doesn't restore the previous binding or value - for a specific property results in a run-time warning. + \note This property exists for backwards compatibility with earlier versions + of Qt. Don't use it in new code. */ QQmlBind::RestorationMode QQmlBind::restoreMode() const { diff --git a/src/qml/types/qqmlbind_p.h b/src/qml/types/qqmlbind_p.h index 052af0d1678..25c185fee3c 100644 --- a/src/qml/types/qqmlbind_p.h +++ b/src/qml/types/qqmlbind_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include #include #include @@ -58,7 +59,7 @@ QT_BEGIN_NAMESPACE class QQmlBindPrivate; -class Q_AUTOTEST_EXPORT QQmlBind : public QObject, public QQmlPropertyValueSource, public QQmlParserStatus +class Q_QML_PRIVATE_EXPORT QQmlBind : public QObject, public QQmlPropertyValueSource, public QQmlParserStatus { public: enum RestorationMode { diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp index 77679091690..70e048b0ea3 100644 --- a/src/qml/types/qqmlconnections.cpp +++ b/src/qml/types/qqmlconnections.cpp @@ -60,15 +60,13 @@ Q_LOGGING_CATEGORY(lcQmlConnections, "qt.qml.connections") class QQmlConnectionsPrivate : public QObjectPrivate { public: - QQmlConnectionsPrivate() : target(nullptr), enabled(true), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {} - QList boundsignals; - QObject *target; + QQmlGuard target; - bool enabled; - bool targetSet; - bool ignoreUnknownSignals; - bool componentcomplete; + bool enabled = true; + bool targetSet = false; + bool ignoreUnknownSignals = false; + bool componentcomplete = true; QQmlRefPointer compilationUnit; QList bindings; @@ -130,6 +128,12 @@ class QQmlConnectionsPrivate : public QObjectPrivate } \endqml + \note For backwards compatibility you can also specify the signal handlers + without \c{function}, like you would specify them directly in the target + object. This is not recommended. If you specify one signal handler this way, + then all signal handlers specified as \c{function} in the same Connections + object are ignored. + \sa {Qt QML} */ QQmlConnections::QQmlConnections(QObject *parent) : @@ -153,7 +157,7 @@ QQmlConnections::~QQmlConnections() QObject *QQmlConnections::target() const { Q_D(const QQmlConnections); - return d->targetSet ? d->target : parent(); + return d->targetSet ? d->target.data() : parent(); } class QQmlBoundSignalDeleter : public QObject @@ -248,17 +252,20 @@ void QQmlConnectionsParser::verifyBindings(const QQmlRefPointertype >= QV4::CompiledData::Binding::Type_Object) { + if (binding->type() == QV4::CompiledData::Binding::Type_Script) + continue; + + if (binding->type() >= QV4::CompiledData::Binding::Type_Object) { const QV4::CompiledData::Object *target = compilationUnit->objectAt(binding->value.objectIndex); if (!compilationUnit->stringAt(target->inheritedTypeNameIndex).isEmpty()) error(binding, QQmlConnections::tr("Connections: nested objects not allowed")); else error(binding, QQmlConnections::tr("Connections: syntax error")); return; - } if (binding->type != QV4::CompiledData::Binding::Type_Script) { - error(binding, QQmlConnections::tr("Connections: script expected")); - return; } + + error(binding, QQmlConnections::tr("Connections: script expected")); + return; } } @@ -353,7 +360,7 @@ void QQmlConnections::connectSignalsToBindings() QQmlRefPointer ctxtdata = ddata ? ddata->outerContext : nullptr; for (const QV4::CompiledData::Binding *binding : qAsConst(d->bindings)) { - Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Script); + Q_ASSERT(binding->type() == QV4::CompiledData::Binding::Type_Script); QString propName = d->compilationUnit->stringAt(binding->propertyNameIndex); QQmlProperty prop(target, propName); diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h index 0cf6d045afb..907c8607c7a 100644 --- a/src/qml/types/qqmlconnections_p.h +++ b/src/qml/types/qqmlconnections_p.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE class QQmlBoundSignal; class QQmlContext; class QQmlConnectionsPrivate; -class Q_AUTOTEST_EXPORT QQmlConnections : public QObject, public QQmlParserStatus +class Q_QML_PRIVATE_EXPORT QQmlConnections : public QObject, public QQmlParserStatus { Q_OBJECT Q_DECLARE_PRIVATE(QQmlConnections) diff --git a/src/qml/util/qqmlpropertymap.cpp b/src/qml/util/qqmlpropertymap.cpp index 2bf8ab01902..23bf1b307c2 100644 --- a/src/qml/util/qqmlpropertymap.cpp +++ b/src/qml/util/qqmlpropertymap.cpp @@ -409,3 +409,5 @@ QQmlPropertyMap::QQmlPropertyMap(const QMetaObject *staticMetaObject, QObject *p */ QT_END_NAMESPACE + +#include "moc_qqmlpropertymap.cpp" diff --git a/src/qmlcompiler/CMakeLists.txt b/src/qmlcompiler/CMakeLists.txt index 5a8858a91ea..45a66bab334 100644 --- a/src/qmlcompiler/CMakeLists.txt +++ b/src/qmlcompiler/CMakeLists.txt @@ -1,10 +1,4 @@ -# Generated from qmlcompiler.pro. - -##################################################################### -## QmlCompiler Module: -##################################################################### - -qt_internal_add_module(QmlCompiler +qt_internal_add_module(QmlCompilerPrivate STATIC INTERNAL_MODULE SOURCES @@ -18,6 +12,7 @@ qt_internal_add_module(QmlCompiler qqmljsmetatypes_p.h qqmljsresourcefilemapper.cpp qqmljsresourcefilemapper_p.h qqmljsscope.cpp qqmljsscope_p.h + qqmljsscopesbyid_p.h qqmljsstreamwriter.cpp qqmljsstreamwriter_p.h qqmljstypedescriptionreader.cpp qqmljstypedescriptionreader_p.h qqmljstypereader.cpp qqmljstypereader_p.h @@ -25,8 +20,19 @@ qt_internal_add_module(QmlCompiler qqmljsannotation_p.h qqmljsannotation.cpp PUBLIC_LIBRARIES Qt::CorePrivate - Qt::QmlDevToolsPrivate ) -#### Keys ignored in scope 1:.:.:qmlcompiler.pro:: -# _OPTION = "host_build" +qt_internal_add_resource(QmlCompilerPrivate "builtins" + PREFIX + "/qt-project.org/qml/builtins" + BASE + "${CMAKE_CURRENT_SOURCE_DIR}/../imports/builtins/" + FILES + "${CMAKE_CURRENT_SOURCE_DIR}/../imports/builtins/builtins.qmltypes" + "${CMAKE_CURRENT_SOURCE_DIR}/../imports/builtins/jsroot.qmltypes" +) + +add_dependencies(QmlCompilerPrivate QmlDevToolsPrivate) +get_target_property(devtools_includes QmlDevToolsPrivate EXTRA_INCLUDE_DIRECTORIES) +target_include_directories(QmlCompilerPrivate PUBLIC ${devtools_includes}) +target_compile_definitions(QmlCompilerPrivate PUBLIC QT_QMLDEVTOOLS_LIB) diff --git a/src/qmlcompiler/qdeferredpointer_p.h b/src/qmlcompiler/qdeferredpointer_p.h index 503b205d6ab..125c24c3d01 100644 --- a/src/qmlcompiler/qdeferredpointer_p.h +++ b/src/qmlcompiler/qdeferredpointer_p.h @@ -44,16 +44,25 @@ QT_BEGIN_NAMESPACE +template +class QDeferredSharedPointer; + +template +class QDeferredWeakPointer; + template class QDeferredFactory { public: - T create() const; bool isValid() const; -}; -template -class QDeferredWeakPointer; +private: + friend class QDeferredSharedPointer; + friend class QDeferredWeakPointer; + friend class QDeferredSharedPointer; + friend class QDeferredWeakPointer; + void populate(const QSharedPointer &) const; +}; template class QDeferredSharedPointer @@ -101,14 +110,14 @@ class QDeferredSharedPointer friend size_t qHash(const QDeferredSharedPointer &ptr, size_t seed = 0) { ptr.lazyLoad(); - return qHashMulti(seed, ptr.m_factory, ptr.m_data); + return qHashMulti(seed, ptr.m_data); } friend bool operator==(const QDeferredSharedPointer &a, const QDeferredSharedPointer &b) { a.lazyLoad(); b.lazyLoad(); - return a.m_factory == b.m_factory && a.m_data == b.m_data; + return a.m_data == b.m_data; } friend bool operator!=(const QDeferredSharedPointer &a, const QDeferredSharedPointer &b) @@ -116,6 +125,31 @@ class QDeferredSharedPointer return !(a == b); } + template + friend bool operator==(const QDeferredSharedPointer &a, const QSharedPointer &b) + { + a.lazyLoad(); + return a.m_data == b; + } + + template + friend bool operator!=(const QDeferredSharedPointer &a, const QSharedPointer &b) + { + return !(a == b); + } + + template + friend bool operator==(const QSharedPointer &a, const QDeferredSharedPointer &b) + { + return b == a; + } + + template + friend bool operator!=(const QSharedPointer &a, const QDeferredSharedPointer &b) + { + return b != a; + } + private: friend class QDeferredWeakPointer; @@ -124,7 +158,7 @@ class QDeferredSharedPointer if (m_factory && m_factory->isValid()) { Factory localFactory; std::swap(localFactory, *m_factory); // Swap before executing, to avoid recursion - const_cast &>(*m_data) = localFactory.create(); + localFactory.populate(m_data.template constCast>()); } } @@ -181,14 +215,14 @@ class QDeferredWeakPointer friend size_t qHash(const QDeferredWeakPointer &ptr, size_t seed = 0) { ptr.lazyLoad(); - return qHashMulti(seed, ptr.m_factory, ptr.m_data); + return qHashMulti(seed, ptr.m_data); } friend bool operator==(const QDeferredWeakPointer &a, const QDeferredWeakPointer &b) { a.lazyLoad(); b.lazyLoad(); - return a.m_factory == b.m_factory && a.m_data == b.m_data; + return a.m_data == b.m_data; } friend bool operator!=(const QDeferredWeakPointer &a, const QDeferredWeakPointer &b) @@ -204,8 +238,8 @@ class QDeferredWeakPointer if (factory->isValid()) { Factory localFactory; std::swap(localFactory, *factory); // Swap before executing, to avoid recursion - const_cast &>(*(m_data.toStrongRef())) - = localFactory.create(); + localFactory.populate( + m_data.toStrongRef().template constCast>()); } } } diff --git a/src/qmlcompiler/qqmljscompiler.cpp b/src/qmlcompiler/qqmljscompiler.cpp index c888ddcf87c..e8900a0d694 100644 --- a/src/qmlcompiler/qqmljscompiler.cpp +++ b/src/qmlcompiler/qqmljscompiler.cpp @@ -123,7 +123,7 @@ static void annotateListElements(QmlIR::Document *document) if (!listElementNames.contains(document->stringAt(object->inheritedTypeNameIndex))) continue; for (QmlIR::Binding *binding = object->firstBinding(); binding; binding = binding->next) { - if (binding->type != QV4::CompiledData::Binding::Type_Script) + if (binding->type() != QV4::CompiledData::Binding::Type_Script) continue; binding->stringIndex = document->registerString(object->bindingAsString(document, binding->value.compiledScriptIndex)); } @@ -135,7 +135,7 @@ static bool checkArgumentsObjectUseInSignalHandlers(const QmlIR::Document &doc, { for (QmlIR::Object *object: qAsConst(doc.objects)) { for (auto binding = object->bindingsBegin(); binding != object->bindingsEnd(); ++binding) { - if (binding->type != QV4::CompiledData::Binding::Type_Script) + if (binding->type() != QV4::CompiledData::Binding::Type_Script) continue; const QString propName = doc.stringAt(binding->propertyNameIndex); if (!propName.startsWith(QLatin1String("on")) @@ -238,18 +238,13 @@ bool qCompileQmlFile(QmlIR::Document &irDocument, const QString &inputFileName, for (QmlIR::Object *object: qAsConst(irDocument.objects)) { if (object->functionsAndExpressions->count == 0 && object->bindingCount() == 0) continue; - QList functionsToCompile; - for (QmlIR::CompiledFunctionOrExpression *foe = object->functionsAndExpressions->first; foe; foe = foe->next) - functionsToCompile << *foe; - const QVector runtimeFunctionIndices = v4CodeGen.generateJSCodeForFunctionsAndBindings(functionsToCompile); - if (v4CodeGen.hasError()) { + + if (!v4CodeGen.generateRuntimeFunctions(object)) { + Q_ASSERT(v4CodeGen.hasError()); error->appendDiagnostic(inputFileName, v4CodeGen.error()); return false; } - QQmlJS::MemoryPool *pool = irDocument.jsParserEngine.pool(); - object->runtimeFunctionIndices.allocate(pool, runtimeFunctionIndices); - if (!aotCompiler) continue; @@ -270,6 +265,12 @@ bool qCompileQmlFile(QmlIR::Document &irDocument, const QString &inputFileName, std::copy(object->functionsBegin(), object->functionsEnd(), std::back_inserter(bindingsAndFunctions)); + QList functionsToCompile; + for (QmlIR::CompiledFunctionOrExpression *foe = object->functionsAndExpressions->first; + foe; foe = foe->next) { + functionsToCompile << *foe; + } + // AOT-compile bindings and functions in the same order as above so that the runtime // class indices match std::sort(bindingsAndFunctions.begin(), bindingsAndFunctions.end()); @@ -278,7 +279,7 @@ bool qCompileQmlFile(QmlIR::Document &irDocument, const QString &inputFileName, std::variant result; auto *module = v4CodeGen.module(); if (const auto *binding = bindingOrFunction.binding()) { - switch (binding->type) { + switch (binding->type()) { case QmlIR::Binding::Type_AttachedProperty: case QmlIR::Binding::Type_GroupProperty: effectiveScopes.insert( @@ -296,7 +297,7 @@ bool qCompileQmlFile(QmlIR::Document &irDocument, const QString &inputFileName, break; } - Q_ASSERT(functionsToCompile.length() > binding->value.compiledScriptIndex); + Q_ASSERT(quint32(functionsToCompile.length()) > binding->value.compiledScriptIndex); auto *node = functionsToCompile[binding->value.compiledScriptIndex].parentNode; Q_ASSERT(node); Q_ASSERT(module->contextMap.contains(node)); @@ -307,7 +308,7 @@ bool qCompileQmlFile(QmlIR::Document &irDocument, const QString &inputFileName, << irDocument.stringAt(binding->propertyNameIndex); result = aotCompiler->compileBinding(context, *binding); } else if (const auto *function = bindingOrFunction.function()) { - Q_ASSERT(functionsToCompile.length() > function->index); + Q_ASSERT(quint32(functionsToCompile.length()) > function->index); auto *node = functionsToCompile[function->index].node; Q_ASSERT(node); Q_ASSERT(module->contextMap.contains(node)); @@ -326,7 +327,8 @@ bool qCompileQmlFile(QmlIR::Document &irDocument, const QString &inputFileName, << diagnosticErrorMessage(inputFileName, *error); } else if (auto *func = std::get_if(&result)) { qCInfo(lcAotCompiler) << "Generated code:" << func->code; - aotFunctionsByIndex[runtimeFunctionIndices[bindingOrFunction.index()]] = *func; + aotFunctionsByIndex[object->runtimeFunctionIndices[bindingOrFunction.index()]] = + *func; } }); } diff --git a/src/qmlcompiler/qqmljsimporter.cpp b/src/qmlcompiler/qqmljsimporter.cpp index de3af866325..9ccdf425877 100644 --- a/src/qmlcompiler/qqmljsimporter.cpp +++ b/src/qmlcompiler/qqmljsimporter.cpp @@ -151,15 +151,15 @@ QQmlJSImporter::Import QQmlJSImporter::readQmldir(const QString &path) continue; } - auto mo = qmlComponents.find(it.key()); + auto mo = qmlComponents.find(it->fileName); if (mo == qmlComponents.end()) { QQmlJSScope::Ptr imported = localFile2ScopeTree(filePath); if (it->singleton) imported->setIsSingleton(true); - mo = qmlComponents.insert(it.key(), imported); + mo = qmlComponents.insert(it->fileName, imported); } - (*mo)->addExport(it.key(), reader.typeNamespace(), it->version); + (*mo)->addExport(it.key(), reader.typeNamespace(), it->version, QTypeRevision()); } for (auto it = qmlComponents.begin(), end = qmlComponents.end(); it != end; ++it) result.objects.insert(it.key(), it.value()); @@ -187,79 +187,146 @@ QQmlJSImporter::Import QQmlJSImporter::readQmldir(const QString &path) const auto scripts = reader.scripts(); for (const auto &script : scripts) { const QString filePath = path + QLatin1Char('/') + script.fileName; - result.scripts.insert(script.nameSpace, localFile2ScopeTree(filePath)); + auto mo = result.scripts.find(script.fileName); + if (mo == result.scripts.end()) + mo = result.scripts.insert(script.fileName, localFile2ScopeTree(filePath)); + (*mo)->addExport(script.nameSpace, reader.typeNamespace(), script.version, QTypeRevision()); } return result; } -void QQmlJSImporter::importDependencies( - const QQmlJSImporter::Import &import, - QQmlJSImporter::AvailableTypes *types, const QString &prefix, QTypeRevision version) +void QQmlJSImporter::importDependencies(const QQmlJSImporter::Import &import, + QQmlJSImporter::AvailableTypes *types, + const QString &prefix, QTypeRevision version, + bool isDependency) { // Import the dependencies with an invalid prefix. The prefix will never be matched by actual // QML code but the C++ types will be visible. - const QString invalidPrefix = QString::fromLatin1("$dependency$"); for (auto const &dependency : qAsConst(import.dependencies)) - importHelper(dependency.module, types, invalidPrefix, dependency.version); + importHelper(dependency.module, types, QString(), dependency.version, true); for (auto const &import : qAsConst(import.imports)) { - importHelper(import.module, types, prefix, - (import.flags & QQmlDirParser::Import::Auto) ? version : import.version); + importHelper(import.module, types, isDependency ? QString() : prefix, + (import.flags & QQmlDirParser::Import::Auto) ? version : import.version, + isDependency); } } +static bool isVersionAllowed(const QQmlJSScope::Export &exportEntry, + const QTypeRevision &importVersion) +{ + return !importVersion.isValid() || exportEntry.version() <= importVersion; +} + void QQmlJSImporter::processImport(const QQmlJSImporter::Import &import, QQmlJSImporter::AvailableTypes *types, const QString &prefix, QTypeRevision version) { const QString anonPrefix = QStringLiteral("$anonymous$"); + QHash> seenExports; - if (!prefix.isEmpty()) - types->qmlNames.insert(prefix, {}); // Empty type means "this is the prefix" - - for (auto it = import.scripts.begin(); it != import.scripts.end(); ++it) - types->qmlNames.insert(prefixedName(prefix, it.key()), it.value()); - - // add objects - for (auto it = import.objects.begin(); it != import.objects.end(); ++it) { - const auto &val = it.value(); - types->cppNames.insert(val->internalName(), val); + const auto insertExports = [&](const QQmlJSScope::ConstPtr &val, const QString &cppName) { + QQmlJSScope::Export bestExport; + // Resolve conflicting qmlNames within an import const auto exports = val->exports(); - if (exports.isEmpty()) { - types->qmlNames.insert( - prefixedName(prefix, prefixedName(anonPrefix, val->internalName())), val); - } - for (const auto &valExport : exports) { - const QString &name = prefixedName(prefix, valExport.type()); - // Resolve conflicting qmlNames within an import - if (types->qmlNames.contains(name)) { - const auto &existing = types->qmlNames[name]; - - if (existing == val) + const QString qmlName = prefixedName(prefix, valExport.type()); + if (!isVersionAllowed(valExport, version)) + continue; + + // Even if the QML name is overridden by some other type, we still want + // to insert the C++ type, with the highest revision available. + if (!bestExport.isValid() || valExport.version() > bestExport.version()) + bestExport = valExport; + + const auto it = types->qmlNames.find(qmlName); + if (it != types->qmlNames.end()) { + + // The same set of exports can declare the same name multiple times for different + // versions. That's the common thing and we would just continue here when we hit + // it again after having inserted successfully once. + // However, it can also declare *different* names. Then we need to do the whole + // thing again. + if (it->scope == val && it->revision == valExport.version()) continue; - if (valExport.version() > version) - continue; + const auto existingExports = seenExports.value(qmlName); + enum { LowerVersion, SameVersion, HigherVersion } seenVersion = LowerVersion; + for (const QQmlJSScope::Export &entry : existingExports) { + if (!isVersionAllowed(entry, version)) + continue; - const auto existingExports = existing->exports(); + if (valExport.version() < entry.version()) { + seenVersion = HigherVersion; + break; + } - auto betterExport = - std::find_if(existingExports.constBegin(), existingExports.constEnd(), - [&](const QQmlJSScope::Export &exportEntry) { - return exportEntry.type() == name - && exportEntry.version() - <= version // Ensure that the entry isn't newer - // than the module version - && valExport.version() < exportEntry.version(); - }); + if (seenVersion == LowerVersion && valExport.version() == entry.version()) + seenVersion = SameVersion; + } - if (betterExport != existingExports.constEnd()) + switch (seenVersion) { + case LowerVersion: + break; + case SameVersion: { + m_warnings.append({ + QStringLiteral("Ambiguous type detected. " + "%1 %2.%3 is defined multiple times.") + .arg(qmlName) + .arg(valExport.version().majorVersion()) + .arg(valExport.version().minorVersion()), + QtCriticalMsg, + QQmlJS::SourceLocation() + }); + + // Invalidate the type. We don't know which one to use. + it->scope = QQmlJSScope::ConstPtr(); + continue; + } + case HigherVersion: continue; + } } - types->qmlNames.insert(name, val); + types->qmlNames.insert(qmlName, { val, valExport.version() }); + seenExports[qmlName].append(valExport); + } + + types->cppNames.insert( + cppName, { + val, + bestExport.isValid() ? bestExport.revision() : QTypeRevision::zero() + } + ); + }; + + if (!prefix.isEmpty()) + types->qmlNames.insert(prefix, {}); // Empty type means "this is the prefix" + + for (auto it = import.scripts.begin(); it != import.scripts.end(); ++it) { + // You cannot have a script without an export + Q_ASSERT(!(*it)->exports().isEmpty()); + insertExports(*it, prefixedName(anonPrefix, (*it)->internalName())); + } + + // add objects + for (auto it = import.objects.begin(); it != import.objects.end(); ++it) { + const auto &val = it.value(); + + const QString cppName = val->isComposite() + ? prefixedName(anonPrefix, val->internalName()) + : val->internalName(); + + const auto exports = val->exports(); + if (exports.isEmpty()) { + // Insert an unresolvable dummy name + types->qmlNames.insert( + prefixedName(prefix, prefixedName(anonPrefix, val->internalName())), + { val, QTypeRevision() }); + types->cppNames.insert(cppName, { val, QTypeRevision() }); + } else { + insertExports(val, cppName); } } @@ -287,10 +354,32 @@ void QQmlJSImporter::processImport(const QQmlJSImporter::Import &import, QQmlJSImporter::AvailableTypes tempTypes(builtinImportHelper().cppNames); tempTypes.cppNames.insert(types->cppNames); + // At present, there are corner cases that couldn't be resolved in a single + // pass of resolveTypes() (e.g. QQmlEasingEnums::Type). However, such cases + // only happen when enumerations are involved, thus the strategy is to + // resolve enumerations (which can potentially create new child scopes) + // before resolving the type fully + const QQmlJSScope::ConstPtr intType = tempTypes.cppNames.value(u"int"_qs).scope; + for (auto it = import.objects.begin(); it != import.objects.end(); ++it) + QQmlJSScope::resolveEnums(it.value(), intType); + for (auto it = import.objects.begin(); it != import.objects.end(); ++it) { const auto &val = it.value(); - if (val->baseType().isNull()) // Otherwise we have already done it in localFile2ScopeTree() - QQmlJSScope::resolveTypes(val, tempTypes.cppNames); + if (val->baseType().isNull()) { // Otherwise we have already done it in localFile2ScopeTree() + // Composite types use QML names, and we should have resolved those already. + // ... except that old qmltypes files might specify composite types with C++ names. + // Warn about those. + if (val->isComposite()) { + m_warnings.append({ + QStringLiteral("Found incomplete composite type %1. Do not use qmlplugindump.") + .arg(val->internalName()), + QtWarningMsg, + QQmlJS::SourceLocation() + }); + } + + QQmlJSScope::resolveNonEnumTypes(val, tempTypes.cppNames); + } } } @@ -312,18 +401,40 @@ QQmlJSImporter::AvailableTypes QQmlJSImporter::builtinImportHelper() QStringList qmltypesFiles = { QStringLiteral("builtins.qmltypes"), QStringLiteral("jsroot.qmltypes") }; + const auto importBuiltins = [&](const QStringList &imports) { + for (auto const &dir : imports) { + QDirIterator it { dir, qmltypesFiles, QDir::NoFilter }; + while (it.hasNext() && !qmltypesFiles.isEmpty()) { + readQmltypes(it.next(), &result.objects, &result.dependencies); + qmltypesFiles.removeOne(it.fileName()); + } - for (auto const &dir : m_importPaths) { - QDirIterator it { dir, qmltypesFiles, QDir::NoFilter, QDirIterator::Subdirectories }; - while (it.hasNext() && !qmltypesFiles.isEmpty()) { - readQmltypes(it.next(), &result.objects, &result.dependencies); - qmltypesFiles.removeOne(it.fileName()); + importDependencies(result, &m_builtins); + + if (qmltypesFiles.isEmpty()) + return; } + }; - importDependencies(result, &m_builtins); + importBuiltins(m_importPaths); + if (!qmltypesFiles.isEmpty()) { + const QString pathsString = + m_importPaths.isEmpty() ? u""_qs : m_importPaths.join(u"\n\t"); + m_warnings.append({ QStringLiteral("Failed to find the following builtins: %1 (so will use " + "qrc). Import paths used:\n\t%2") + .arg(qmltypesFiles.join(u", "), pathsString), + QtWarningMsg, QQmlJS::SourceLocation() }); + importBuiltins({ u":/qt-project.org/qml/builtins"_qs }); // use qrc as a "last resort" + } + Q_ASSERT(qmltypesFiles.isEmpty()); // since qrc must cover it in all the bad cases - if (qmltypesFiles.isEmpty()) - break; + if (!qmltypesFiles.isEmpty()) { + m_warnings.append({ + QStringLiteral("Failed to find the following builtins: %1").arg(qmltypesFiles.join(u", ")), + QtWarningMsg, + QQmlJS::SourceLocation() + }); + return m_builtins; } // Process them together since there they have interdependencies that wouldn't get resolved @@ -379,16 +490,16 @@ QQmlJSImporter::ImportedTypes QQmlJSImporter::builtinInternalNames() } bool QQmlJSImporter::importHelper(const QString &module, AvailableTypes *types, - const QString &prefix, QTypeRevision version) + const QString &prefix, QTypeRevision version, bool isDependency, + bool isFile) { - const bool isDependency = prefix == QStringLiteral("$dependency$"); - // QtQuick/Controls and QtQuick.Controls are the same module const QString moduleCacheName = QString(module).replace(u'/', u'.'); - const auto cacheKey = QPair { - (isDependency ? QString() : prefix) + u'|' + moduleCacheName, version - }; + if (isDependency) + Q_ASSERT(prefix.isEmpty()); + + const CacheKey cacheKey = { prefix, moduleCacheName, version, isFile, isDependency }; auto getTypesFromCache = [&]() -> bool { if (!m_cachedImportTypes.contains(cacheKey)) @@ -405,10 +516,16 @@ bool QQmlJSImporter::importHelper(const QString &module, AvailableTypes *types, return true; }; + // The QML module only contains builtins and is not registered declaratively, so ignore requests + // for importing it + if (module == u"QML"_qs) + return true; + if (getTypesFromCache()) return true; - auto cacheTypes = QSharedPointer(new QQmlJSImporter::AvailableTypes({})); + auto cacheTypes = + QSharedPointer(new QQmlJSImporter::AvailableTypes({})); m_cachedImportTypes[cacheKey] = cacheTypes; const QPair importId { module, version }; @@ -418,26 +535,29 @@ bool QQmlJSImporter::importHelper(const QString &module, AvailableTypes *types, if (it->isEmpty()) return false; - const auto import = m_seenQmldirFiles.constFind(*it); - Q_ASSERT(import != m_seenQmldirFiles.constEnd()); + Q_ASSERT(m_seenQmldirFiles.contains(*it)); + const QQmlJSImporter::Import import = m_seenQmldirFiles.value(*it); - importDependencies(*import, cacheTypes.get(), prefix, version); - processImport(*import, cacheTypes.get(), prefix, version); + importDependencies(import, cacheTypes.get(), prefix, version, isDependency); + processImport(import, cacheTypes.get(), prefix, version); const bool typesFromCache = getTypesFromCache(); Q_ASSERT(typesFromCache); return typesFromCache; } - const auto modulePaths = qQmlResolveImportPaths(module, m_importPaths, version); + const auto modulePaths = isFile ? QStringList { module } + : qQmlResolveImportPaths(module, m_importPaths, version); + for (auto const &modulePath : modulePaths) { const QString qmldirPath = modulePath + SlashQmldir; const auto it = m_seenQmldirFiles.constFind(qmldirPath); if (it != m_seenQmldirFiles.constEnd()) { + const QQmlJSImporter::Import import = *it; m_seenImports.insert(importId, qmldirPath); - importDependencies(*it, cacheTypes.get(), prefix, version); - processImport(*it, cacheTypes.get(), prefix, version); + importDependencies(import, cacheTypes.get(), prefix, version, isDependency); + processImport(import, cacheTypes.get(), prefix, version); const bool typesFromCache = getTypesFromCache(); Q_ASSERT(typesFromCache); @@ -449,7 +569,7 @@ bool QQmlJSImporter::importHelper(const QString &module, AvailableTypes *types, const auto import = readQmldir(file.canonicalPath()); m_seenQmldirFiles.insert(qmldirPath, import); m_seenImports.insert(importId, qmldirPath); - importDependencies(import, cacheTypes.get(), prefix, version); + importDependencies(import, cacheTypes.get(), prefix, version, isDependency); processImport(import, cacheTypes.get(), prefix, version); const bool typesFromCache = getTypesFromCache(); @@ -484,7 +604,7 @@ QQmlJSScope::Ptr QQmlJSImporter::importFile(const QString &file) QQmlJSImporter::ImportedTypes QQmlJSImporter::importDirectory( const QString &directory, const QString &prefix) { - QHash qmlNames; + QQmlJSImporter::AvailableTypes types({}); if (directory.startsWith(u':')) { if (m_mapper) { @@ -493,12 +613,16 @@ QQmlJSImporter::ImportedTypes QQmlJSImporter::importDirectory( for (const auto &entry : resources) { const QString name = QFileInfo(entry.resourcePath).baseName(); if (name.front().isUpper()) { - qmlNames.insert(prefixedName(prefix, name), - localFile2ScopeTree(entry.filePath)); + types.qmlNames.insert( + prefixedName(prefix, name), + { localFile2ScopeTree(entry.filePath), QTypeRevision() }); } } } - return qmlNames; + + importHelper(directory, &types, QString(), QTypeRevision(), false, true); + + return types.qmlNames; } QDirIterator it { @@ -511,11 +635,14 @@ QQmlJSImporter::ImportedTypes QQmlJSImporter::importDirectory( if (!it.fileName().front().isUpper()) continue; // Non-uppercase names cannot be imported anyway. - qmlNames.insert(prefixedName(prefix, QFileInfo(it.filePath()).baseName()), - localFile2ScopeTree(it.filePath())); + types.qmlNames.insert( + prefixedName(prefix, QFileInfo(it.filePath()).baseName()), + { localFile2ScopeTree(it.filePath()), QTypeRevision() }); } - return qmlNames; + importHelper(directory, &types, QString(), QTypeRevision(), false, true); + + return types.qmlNames; } void QQmlJSImporter::setImportPaths(const QStringList &importPaths) diff --git a/src/qmlcompiler/qqmljsimporter_p.h b/src/qmlcompiler/qqmljsimporter_p.h index 01d1b30ba16..93e5ff76881 100644 --- a/src/qmlcompiler/qqmljsimporter_p.h +++ b/src/qmlcompiler/qqmljsimporter_p.h @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE class QQmlJSImporter { public: - using ImportedTypes = QHash; + using ImportedTypes = QHash; QQmlJSImporter(const QStringList &importPaths, QQmlJSResourceFileMapper *mapper) : m_importPaths(importPaths) @@ -86,15 +86,15 @@ class QQmlJSImporter struct AvailableTypes { - AvailableTypes(QHash builtins) + AvailableTypes(ImportedTypes builtins) : cppNames(std::move(builtins)) {} // C++ names used in qmltypes files for non-composite types - QHash cppNames; + ImportedTypes cppNames; // Names the importing component sees, including any prefixes - QHash qmlNames; + ImportedTypes qmlNames; }; struct Import { @@ -106,14 +106,13 @@ class QQmlJSImporter AvailableTypes builtinImportHelper(); bool importHelper(const QString &module, AvailableTypes *types, - const QString &prefix = QString(), - QTypeRevision version = QTypeRevision()); + const QString &prefix = QString(), QTypeRevision version = QTypeRevision(), + bool isDependency = false, bool isFile = false); void processImport(const Import &import, AvailableTypes *types, const QString &prefix = QString(), QTypeRevision version = QTypeRevision()); - void importDependencies(const QQmlJSImporter::Import &import, - AvailableTypes *types, + void importDependencies(const QQmlJSImporter::Import &import, AvailableTypes *types, const QString &prefix = QString(), - QTypeRevision version = QTypeRevision()); + QTypeRevision version = QTypeRevision(), bool isDependency = false); void readQmltypes(const QString &filename, QHash *objects, QList *dependencies); Import readQmldir(const QString &dirname); @@ -121,8 +120,29 @@ class QQmlJSImporter QStringList m_importPaths; + struct CacheKey + { + QString prefix; + QString name; + QTypeRevision version; + bool isFile = false; + bool isDependency = false; + + friend inline size_t qHash(const CacheKey &key, size_t seed = 0) noexcept + { + return qHashMulti(seed, key.prefix, key.name, key.version, + key.isFile, key.isDependency); + } + + friend inline bool operator==(const CacheKey &a, const CacheKey &b) + { + return a.prefix == b.prefix && a.name == b.name && a.version == b.version + && a.isFile == b.isFile && a.isDependency == b.isDependency; + } + }; + QHash, QString> m_seenImports; - QHash, QSharedPointer> m_cachedImportTypes; + QHash> m_cachedImportTypes; QHash m_seenQmldirFiles; QHash m_importedFiles; diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp index 05bdae8ec65..733cb3b2c03 100644 --- a/src/qmlcompiler/qqmljsimportvisitor.cpp +++ b/src/qmlcompiler/qqmljsimportvisitor.cpp @@ -32,6 +32,10 @@ #include #include #include +#include + +#include +#include #include @@ -66,25 +70,73 @@ inline QString getScopeName(const QQmlJSScope::ConstPtr &scope, QQmlJSScope::Sco } QQmlJSImportVisitor::QQmlJSImportVisitor( - QQmlJSImporter *importer, const QString &implicitImportDirectory, - const QStringList &qmltypesFiles, const QString &fileName, const QString &code, bool silent) - : m_implicitImportDirectory(implicitImportDirectory) - , m_qmltypesFiles(qmltypesFiles) - , m_currentScope(QQmlJSScope::create(QQmlJSScope::JSFunctionScope)) - , m_importer(importer) - , m_logger(fileName, code, silent) + const QQmlJSScope::Ptr &target, QQmlJSImporter *importer, + const QString &implicitImportDirectory, const QStringList &qmltypesFiles, + const QString &fileName, const QString &code, bool silent) + : m_implicitImportDirectory(implicitImportDirectory), + m_code(code), + m_filePath(fileName), + m_rootId(u""_qs), + m_qmltypesFiles(qmltypesFiles), + m_currentScope(QQmlJSScope::create()), + m_exportedRootScope(target), + m_importer(importer), + m_logger(fileName, code, silent) { + m_currentScope->setScopeType(QQmlJSScope::JSFunctionScope); m_globalScope = m_currentScope; m_currentScope->setIsComposite(true); + + m_currentScope->setInternalName(u"global"_qs); + + QLatin1String jsGlobVars[] = { /* Not listed on the MDN page; browser and QML extensions: */ + // console/debug api + QLatin1String("console"), QLatin1String("print"), + // garbage collector + QLatin1String("gc"), + // i18n + QLatin1String("qsTr"), QLatin1String("qsTrId"), + QLatin1String("QT_TR_NOOP"), QLatin1String("QT_TRANSLATE_NOOP"), + QLatin1String("QT_TRID_NOOP"), + // XMLHttpRequest + QLatin1String("XMLHttpRequest") + }; + + QQmlJSScope::JavaScriptIdentifier globalJavaScript = { + QQmlJSScope::JavaScriptIdentifier::LexicalScoped, QQmlJS::SourceLocation() + }; + for (const char **globalName = QV4::Compiler::Codegen::s_globalNames; *globalName != nullptr; + ++globalName) { + m_currentScope->insertJSIdentifier(QString::fromLatin1(*globalName), globalJavaScript); + } + for (const auto &jsGlobVar : jsGlobVars) + m_currentScope->insertJSIdentifier(jsGlobVar, globalJavaScript); } -void QQmlJSImportVisitor::enterEnvironment(QQmlJSScope::ScopeType type, const QString &name, - const QQmlJS::SourceLocation &location) +void QQmlJSImportVisitor::populateCurrentScope( + QQmlJSScope::ScopeType type, const QString &name, const QQmlJS::SourceLocation &location) { - m_currentScope = QQmlJSScope::create(type, m_currentScope); + m_currentScope->setScopeType(type); setScopeName(m_currentScope, type, name); m_currentScope->setIsComposite(true); m_currentScope->setSourceLocation(location); + m_scopesByIrLocation.insert({ location.startLine, location.startColumn }, m_currentScope); +} + +void QQmlJSImportVisitor::enterRootScope(QQmlJSScope::ScopeType type, const QString &name, const QQmlJS::SourceLocation &location) +{ + QQmlJSScope::reparent(m_currentScope, m_exportedRootScope); + m_currentScope = m_exportedRootScope; + populateCurrentScope(type, name, location); +} + +void QQmlJSImportVisitor::enterEnvironment(QQmlJSScope::ScopeType type, const QString &name, + const QQmlJS::SourceLocation &location) +{ + QQmlJSScope::Ptr newScope = QQmlJSScope::create(); + QQmlJSScope::reparent(m_currentScope, newScope); + m_currentScope = std::move(newScope); + populateCurrentScope(type, name, location); } bool QQmlJSImportVisitor::enterEnvironmentNonUnique(QQmlJSScope::ScopeType type, @@ -109,6 +161,7 @@ bool QQmlJSImportVisitor::enterEnvironmentNonUnique(QQmlJSScope::ScopeType type, return false; } // enter found scope + m_scopesByIrLocation.insert({ location.startLine, location.startColumn }, *it); m_currentScope = *it; return true; } @@ -135,14 +188,14 @@ void QQmlJSImportVisitor::resolveAliases() if (!property.isAlias() || !property.type().isNull()) continue; - QStringList components = property.typeName().split(u'.'); - QQmlJSScope::ConstPtr type; + QStringList components = property.typeName().split(u'.', Qt::SkipEmptyParts); QQmlJSMetaProperty targetProperty; // The first component has to be an ID. Find the object it refers to. - const auto it = m_scopesById.find(components.takeFirst()); - if (it != m_scopesById.end()) { - type = *it; + QQmlJSScope::ConstPtr type = components.isEmpty() + ? QQmlJSScope::ConstPtr() + : m_scopesById.scope(components.takeFirst(), object); + if (!type.isNull()) { // Any further components are nested properties of that object. // Technically we can only resolve a limited depth in the engine, but the rules @@ -205,11 +258,6 @@ void QQmlJSImportVisitor::resolveAliases() } } -QQmlJSScope::Ptr QQmlJSImportVisitor::result() const -{ - return m_exportedRootScope; -} - QString QQmlJSImportVisitor::implicitImportDirectory( const QString &localFile, QQmlJSResourceFileMapper *mapper) { @@ -227,10 +275,10 @@ QString QQmlJSImportVisitor::implicitImportDirectory( return QFileInfo(localFile).canonicalPath() + u'/'; } -void QQmlJSImportVisitor::processImportWarnings(const QString &what, const QQmlJS::SourceLocation &srcLocation) +void QQmlJSImportVisitor::processImportWarnings( + const QString &what, const QQmlJS::SourceLocation &srcLocation) { const auto warnings = m_importer->takeWarnings(); - if (warnings.isEmpty()) return; @@ -251,7 +299,11 @@ void QQmlJSImportVisitor::importBaseModules() if (!m_qmltypesFiles.isEmpty()) m_importer->importQmltypes(m_qmltypesFiles); - m_rootScopeImports.insert(m_importer->importDirectory(m_implicitImportDirectory)); + // Pulling in the modules and neighboring qml files of the qmltypes we're trying to lint is not + // something we need to do. + if (!m_filePath.endsWith(u".qmltypes"_qs)) + m_rootScopeImports.insert(m_importer->importDirectory(m_implicitImportDirectory)); + processImportWarnings(QStringLiteral("base modules")); } @@ -264,6 +316,41 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiProgram *) void QQmlJSImportVisitor::endVisit(UiProgram *) { resolveAliases(); + processDefaultProperties(); + processPropertyTypes(); + processPropertyBindings(); + checkSignals(); + processPropertyBindingObjects(); + checkRequiredProperties(); + + for (const auto &scope : m_objectBindingScopes) { + breakInheritanceCycles(scope); + checkDeprecation(scope); + } + + for (const auto &scope : m_objectDefinitionScopes) { + checkGroupedAndAttachedScopes(scope); + breakInheritanceCycles(scope); + checkDeprecation(scope); + } + + auto unusedImports = m_importLocations; + for (const QString &type : m_usedTypes) { + for (const auto &importLocation : m_importTypeLocationMap.values(type)) + unusedImports.remove(importLocation); + + // If there are no more unused imports left we can abort early + if (unusedImports.isEmpty()) + break; + } + + for (const auto &import : unusedImports) { + m_logger.log(QString::fromLatin1("Unused import at %1:%2:%3") + .arg(m_filePath) + .arg(import.startLine) + .arg(import.startColumn), + Log_UnusedImport, import); + } } static QQmlJSAnnotation::Value bindingToVariant(QQmlJS::AST::Statement *statement) @@ -328,6 +415,536 @@ QVector QQmlJSImportVisitor::parseAnnotations(QQmlJS::AST::UiA return annotationList; } +void QQmlJSImportVisitor::processDefaultProperties() +{ + for (auto it = m_pendingDefaultProperties.constBegin(); + it != m_pendingDefaultProperties.constEnd(); ++it) { + // We can't expect custom parser default properties to be sensible, discard them for now. + if (it.key()->isInCustomParserParent()) + continue; + + const QQmlJSScope *scopeOfDefaultProperty = nullptr; + QString defaultPropertyName; + bool isComponent = false; + /* consider: + * + * QtObject { // <- it.key() + * default property var p // (1) + * QtObject {} // (2) + * } + * + * `p` (1) is a property of a subtype of QtObject, it couldn't be used + * in a property binding (2) + */ + // thus, use a base type of it.key() to detect a default property + for (const auto *s = it.key()->baseType().get(); s; s = s->baseType().get()) { + defaultPropertyName = s->defaultPropertyName(); + if (!defaultPropertyName.isEmpty()) { + scopeOfDefaultProperty = s; + break; + } + + if (s->internalName() == QStringLiteral("QQmlComponent")) { + isComponent = true; + break; + } + } + + // If the parent scope is based on Component it can have any child element + // TODO: We should also store these somewhere + if (isComponent) + continue; + + if (defaultPropertyName.isEmpty()) { + m_logger.log(QStringLiteral("Cannot assign to non-existent default property"), + Log_Property, it.value().constFirst()->sourceLocation()); + continue; + } + + Q_ASSERT(scopeOfDefaultProperty); + QQmlJSMetaProperty defaultProp = scopeOfDefaultProperty->property(defaultPropertyName); + + if (it.value().length() > 1 && !defaultProp.isList()) { + m_logger.log( + QStringLiteral("Cannot assign multiple objects to a default non-list property"), + Log_Property, it.value().constFirst()->sourceLocation()); + } + + // TODO: Currently we only support binding one scope, adjust this once this is no longer + // true + QQmlJSScope::Ptr scope = it.value().first(); + + QQmlJSMetaPropertyBinding binding(defaultProp); + binding.setValue(static_cast(scope)); + binding.setValueTypeName(getScopeName(scope, QQmlJSScope::QMLScope)); + + it.key()->addOwnPropertyBinding(binding); + + auto propType = defaultProp.type(); + if (propType.isNull() || !propType->isFullyResolved() + || !scope->isFullyResolved()) // should be an error somewhere else + return; + + // Assigning any element to a QQmlComponent property implicitly wraps it into a Component + // Check whether the property can be assigned the scope + if (propType->canAssign(scope)) { + if (propType->causesImplicitComponentWrapping()) { + // mark the scope as implicitly wrapped, unless it is a Component + scope->setIsWrappedInImplicitComponent(!scope->causesImplicitComponentWrapping()); + } + continue; + } + + m_logger.log(QStringLiteral("Cannot assign to default property of incompatible type"), + Log_Property, scope->sourceLocation()); + } +} + +void QQmlJSImportVisitor::processPropertyTypes() +{ + for (const PendingPropertyType &type : m_pendingPropertyTypes) { + Q_ASSERT(type.scope->hasOwnProperty(type.name)); + + auto property = type.scope->ownProperty(type.name); + + if (const auto propertyType = m_rootScopeImports.value(property.typeName()).scope) { + property.setType(propertyType); + type.scope->addOwnProperty(property); + } else { + m_logger.log(property.typeName() + + QStringLiteral(" was not found. Did you add all import paths?"), + Log_Import, type.location); + } + } +} + +void QQmlJSImportVisitor::processPropertyBindingObjects() +{ + for (const PendingPropertyObjectBinding &objectBinding : m_pendingPropertyObjectBindings) { + const QString propertyName = objectBinding.name; + QQmlJSScope::ConstPtr childScope = objectBinding.childScope; + + QQmlJSMetaProperty property = objectBinding.scope->property(propertyName); + + if (property.isValid() && !property.type().isNull() + && (objectBinding.onToken || property.type()->canAssign(objectBinding.childScope))) { + + + if (property.type()->causesImplicitComponentWrapping()) + objectBinding.childScope->setIsWrappedInImplicitComponent(!objectBinding.childScope->causesImplicitComponentWrapping()); + + QQmlJSMetaPropertyBinding binding = + objectBinding.scope->hasOwnPropertyBinding(propertyName) + ? objectBinding.scope->ownPropertyBinding(propertyName) + : QQmlJSMetaPropertyBinding(property); + + const QString typeName = getScopeName(childScope, QQmlJSScope::QMLScope); + + if (objectBinding.onToken) { + if (childScope->hasInterface(QStringLiteral("QQmlPropertyValueInterceptor"))) { + if (binding.hasInterceptor()) { + m_logger.log(QStringLiteral("Duplicate interceptor on property \"%1\"") + .arg(propertyName), + Log_Property, objectBinding.location); + } else { + binding.setInterceptor(childScope); + binding.setInterceptorTypeName(typeName); + + objectBinding.scope->addOwnPropertyBinding(binding); + } + } else if (childScope->hasInterface(QStringLiteral("QQmlPropertyValueSource"))) { + if (binding.hasValueSource()) { + m_logger.log(QStringLiteral("Duplicate value source on property \"%1\"") + .arg(propertyName), + Log_Property, objectBinding.location); + } else if (binding.hasValue()) { + m_logger.log(QStringLiteral("Cannot combine value source and binding on " + "property \"%1\"") + .arg(propertyName), + Log_Property, objectBinding.location); + } else { + binding.setValueSource(childScope); + binding.setValueSourceTypeName(typeName); + objectBinding.scope->addOwnPropertyBinding(binding); + } + } else { + m_logger.log( + QStringLiteral("On-binding for property \"%1\" has wrong type \"%2\"") + .arg(propertyName) + .arg(typeName), + Log_Property, objectBinding.location); + } + } else { + // TODO: Warn here if binding.hasValue() is true + if (binding.hasValueSource()) { + m_logger.log( + QStringLiteral( + "Cannot combine value source and binding on property \"%1\"") + .arg(propertyName), + Log_Property, objectBinding.location); + } else { + binding.setValue(childScope); + binding.setValueTypeName(typeName); + objectBinding.scope->addOwnPropertyBinding(binding); + } + } + } else if (!objectBinding.scope->isFullyResolved()) { + // If the current scope is not fully resolved we cannot tell whether the property exists + // or not (we already warn elsewhere) + } else if (!property.isValid()) { + m_logger.log(QStringLiteral("Property \"%1\" is invalid or does not exist") + .arg(propertyName), + Log_Property, objectBinding.location); + } else if (property.type().isNull() || !property.type()->isFullyResolved()) { + // Property type is not fully resolved we cannot tell any more than this + m_logger.log(QStringLiteral("Property \"%1\" has incomplete type \"%2\". You may be " + "missing an import.") + .arg(propertyName) + .arg(property.typeName()), + Log_Property, objectBinding.location); + } else if (!childScope->isFullyResolved()) { + // If the childScope type is not fully resolved we cannot tell whether the type is + // incompatible (we already warn elsewhere) + } else { + // the type is incompatible + m_logger.log(QStringLiteral("Property \"%1\" of type \"%2\" is assigned an " + "incompatible type \"%3\"") + .arg(propertyName) + .arg(property.typeName()) + .arg(getScopeName(childScope, QQmlJSScope::QMLScope)), + Log_Property, objectBinding.location); + } + } +} + +void QQmlJSImportVisitor::checkRequiredProperties() +{ + for (const auto &required : m_requiredProperties) { + if (!required.scope->hasProperty(required.name)) { + m_logger.log( + QStringLiteral("Property \"%1\" was marked as required but does not exist.") + .arg(required.name), + Log_Required, required.location); + } + } + + for (const auto &defScope : m_objectDefinitionScopes) { + if (defScope->parentScope() == m_globalScope || defScope->isInlineComponent() || defScope->isComponentRootElement()) + continue; + + QVector scopesToSearch; + QDuplicateTracker seen; + for (QQmlJSScope::ConstPtr scope = defScope; scope && !seen.hasSeen(scope); + scope = scope->baseType()) { + scopesToSearch << scope; + const auto ownProperties = scope->ownProperties(); + for (auto propertyIt = ownProperties.constBegin(); + propertyIt != ownProperties.constEnd(); ++propertyIt) { + const QString propName = propertyIt.key(); + + QQmlJSScope::ConstPtr prevRequiredScope; + for (QQmlJSScope::ConstPtr requiredScope : scopesToSearch) { + if (requiredScope->isPropertyLocallyRequired(propName)) { + bool found = + std::find_if(scopesToSearch.constBegin(), scopesToSearch.constEnd(), + [&](QQmlJSScope::ConstPtr scope) { + return scope->hasPropertyBinding(propName); + }) + != scopesToSearch.constEnd(); + + if (!found) { + const QString propertyScopeName = scopesToSearch.length() > 1 + ? getScopeName(scopesToSearch.at(scopesToSearch.length() - 2), + QQmlJSScope::QMLScope) + : u"here"_qs; + const QString requiredScopeName = prevRequiredScope + ? getScopeName(prevRequiredScope, QQmlJSScope::QMLScope) + : u"here"_qs; + + QString message = + QStringLiteral( + "Component is missing required property %1 from %2") + .arg(propName) + .arg(propertyScopeName); + if (requiredScope != scope) + message += QStringLiteral(" (marked as required by %3)") + .arg(requiredScopeName); + + m_logger.log(message, Log_Required, defScope->sourceLocation()); + } + } + prevRequiredScope = requiredScope; + } + } + } + } +} + +void QQmlJSImportVisitor::processPropertyBindings() +{ + for (auto it = m_propertyBindings.constBegin(); it != m_propertyBindings.constEnd(); ++it) { + QQmlJSScope::Ptr scope = it.key(); + for (auto &[visibilityScope, location, name] : it.value()) { + if (!scope->hasProperty(name)) { + // These warnings do not apply for custom parsers and their children and need to be + // handled on a case by case basis + + if (scope->isInCustomParserParent()) + continue; + + // TODO: Can this be in a better suited category? + m_logger.log(QStringLiteral("Binding assigned to \"%1\", but no property \"%1\" " + "exists in the current element.") + .arg(name), + Log_Type, location); + continue; + } + + const auto property = scope->property(name); + if (!property.type()) { + m_logger.log(QStringLiteral("No type found for property \"%1\". This may be due " + "to a missing import statement or incomplete " + "qmltypes files.") + .arg(name), + Log_Type, location); + } + + const auto &annotations = property.annotations(); + + const auto deprecationAnn = + std::find_if(annotations.cbegin(), annotations.cend(), + [](const QQmlJSAnnotation &ann) { return ann.isDeprecation(); }); + + if (deprecationAnn != annotations.cend()) { + const auto deprecation = deprecationAnn->deprecation(); + + QString message = QStringLiteral("Binding on deprecated property \"%1\"") + .arg(property.propertyName()); + + if (!deprecation.reason.isEmpty()) + message.append(QStringLiteral(" (Reason: %1)").arg(deprecation.reason)); + + m_logger.log(message, Log_Deprecation, location); + } + + QQmlJSMetaPropertyBinding binding(property); + + // TODO: Actually store the value + + visibilityScope->addOwnPropertyBinding(binding); + } + } +} + +static QString signalName(QStringView handlerName) +{ + if (handlerName.startsWith(u"on") && handlerName.size() > 2) { + QString signal = handlerName.mid(2).toString(); + for (int i = 0; i < signal.length(); ++i) { + QChar &ch = signal[i]; + if (ch.isLower()) + return QString(); + if (ch.isUpper()) { + ch = ch.toLower(); + return signal; + } + } + } + return QString(); +} + +void QQmlJSImportVisitor::checkSignals() +{ + for (auto it = m_signals.constBegin(); it != m_signals.constEnd(); ++it) { + for (const auto &scopeAndPair : it.value()) { + const auto location = scopeAndPair.dataLocation; + const auto &pair = scopeAndPair.data; + const QString signal = signalName(pair.first); + + if (!it.key()->hasMethod(signal)) { + m_logger.log(QStringLiteral("no matching signal found for handler \"%1\"") + .arg(pair.first), + Log_UnqualifiedAccess, location); + continue; + } + + QQmlJSMetaMethod scopeSignal; + for (QQmlJSScope::ConstPtr scope = it.key(); scope; scope = scope->baseType()) { + const auto methods = scope->ownMethods(); + const auto methodsRange = methods.equal_range(signal); + for (auto method = methodsRange.first; method != methodsRange.second; ++method) { + if (method->methodType() != QQmlJSMetaMethod::Signal) + continue; + scopeSignal = *method; + break; + } + } + + const QStringList signalParameters = scopeSignal.parameterNames(); + + if (pair.second.length() > signalParameters.length()) { + m_logger.log(QStringLiteral("Signal handler for \"%2\" has more formal" + " parameters than the signal it handles.") + .arg(pair.first), + Log_Signal, location); + continue; + } + + for (qsizetype i = 0; i < pair.second.length(); i++) { + const QStringView handlerParameter = pair.second.at(i); + const qsizetype j = signalParameters.indexOf(handlerParameter); + if (j == i || j < 0) + continue; + + m_logger.log(QStringLiteral("Parameter %1 to signal handler for \"%2\"" + " is called \"%3\". The signal has a parameter" + " of the same name in position %4.") + .arg(i + 1) + .arg(pair.first, handlerParameter) + .arg(j + 1), + Log_Signal, location); + } + } + } +} + +void QQmlJSImportVisitor::addDefaultProperties() +{ + if (m_currentScope == m_exportedRootScope || m_currentScope->parentScope()->isArrayScope() + || m_currentScope->isInlineComponent()) // inapplicable + return; + + m_pendingDefaultProperties[m_currentScope->parentScope()] << m_currentScope; +} + +void QQmlJSImportVisitor::breakInheritanceCycles(const QQmlJSScope::Ptr &originalScope) +{ + QList scopes; + for (QQmlJSScope::ConstPtr scope = originalScope; scope;) { + if (scopes.contains(scope)) { + QString inheritenceCycle; + for (const auto &seen : qAsConst(scopes)) { + inheritenceCycle.append(seen->baseTypeName()); + inheritenceCycle.append(QLatin1String(" -> ")); + } + inheritenceCycle.append(scopes.first()->baseTypeName()); + + const QString message = QStringLiteral("%1 is part of an inheritance cycle: %2") + .arg(scope->internalName(), inheritenceCycle); + m_logger.log(message, Log_InheritanceCycle); + originalScope->clearBaseType(); + originalScope->setBaseTypeError(message); + break; + } + + scopes.append(scope); + + const auto newScope = scope->baseType(); + if (newScope.isNull()) { + const QString error = scope->baseTypeError(); + const QString name = scope->baseTypeName(); + if (!error.isEmpty()) { + m_logger.log(error, Log_Import); + } else if (!name.isEmpty()) { + m_logger.log(name + QStringLiteral(" was not found. Did you add all import paths?"), + Log_Import); + } + } + + scope = newScope; + } +} + +void QQmlJSImportVisitor::checkDeprecation(const QQmlJSScope::ConstPtr &originalScope) +{ + for (QQmlJSScope::ConstPtr scope = originalScope; scope; scope = scope->baseType()) { + for (const QQmlJSAnnotation &annotation : scope->annotations()) { + if (annotation.isDeprecation()) { + QQQmlJSDeprecation deprecation = annotation.deprecation(); + + QString message = + QStringLiteral("Type \"%1\" is deprecated").arg(scope->internalName()); + + if (!deprecation.reason.isEmpty()) + message.append(QStringLiteral(" (Reason: %1)").arg(deprecation.reason)); + + m_logger.log(message, Log_Deprecation, originalScope->sourceLocation()); + } + } + } +} + +void QQmlJSImportVisitor::checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr scope) +{ + // These warnings do not apply for custom parsers and their children and need to be handled on a + // case by case basis + if (scope->isInCustomParserParent()) + return; + + auto children = scope->childScopes(); + while (!children.isEmpty()) { + auto childScope = children.takeFirst(); + const auto type = childScope->scopeType(); + switch (type) { + case QQmlJSScope::GroupedPropertyScope: + case QQmlJSScope::AttachedPropertyScope: + if (!childScope->baseType()) { + m_logger.log(QStringLiteral("unknown %1 property scope %2.") + .arg(type == QQmlJSScope::GroupedPropertyScope + ? QStringLiteral("grouped") + : QStringLiteral("attached"), + childScope->internalName()), + Log_UnqualifiedAccess, childScope->sourceLocation()); + } + children.append(childScope->childScopes()); + default: + break; + } + } +} + +void QQmlJSImportVisitor::flushPendingSignalParameters() +{ + const QQmlJSMetaSignalHandler handler = m_signalHandlers[m_pendingSignalHandler]; + for (const QString ¶meter : handler.signalParameters) { + m_currentScope->insertJSIdentifier( + parameter, { QQmlJSScope::JavaScriptIdentifier::Injected, m_pendingSignalHandler }); + } + m_pendingSignalHandler = QQmlJS::SourceLocation(); +} + +bool QQmlJSImportVisitor::visit(QQmlJS::AST::ExpressionStatement *ast) +{ + if (m_pendingSignalHandler.isValid()) { + enterEnvironment(QQmlJSScope::JSFunctionScope, u"signalhandler"_qs, + ast->firstSourceLocation()); + flushPendingSignalParameters(); + } + return true; +} + +void QQmlJSImportVisitor::endVisit(QQmlJS::AST::ExpressionStatement *) +{ + if (m_currentScope->scopeType() == QQmlJSScope::JSFunctionScope + && m_currentScope->baseTypeName() == u"signalhandler"_qs) { + leaveEnvironment(); + } +} + +bool QQmlJSImportVisitor::visit(QQmlJS::AST::StringLiteral *sl) +{ + const QString s = m_code.mid(sl->literalToken.begin(), sl->literalToken.length); + + if (s.contains(QLatin1Char('\r')) || s.contains(QLatin1Char('\n')) || s.contains(QChar(0x2028u)) + || s.contains(QChar(0x2029u))) { + m_logger.log(QStringLiteral("String contains unescaped line terminator which is " + "deprecated. Use a template " + "literal instead."), + Log_MultilineString, sl->literalToken); + } + + return true; +} bool QQmlJSImportVisitor::visit(UiObjectDefinition *definition) { @@ -337,26 +954,36 @@ bool QQmlJSImportVisitor::visit(UiObjectDefinition *definition) superType.append(u'.'); superType.append(segment->name.toString()); } - enterEnvironment(QQmlJSScope::QMLScope, superType, definition->firstSourceLocation()); - if (!m_exportedRootScope) - m_exportedRootScope = m_currentScope; - m_currentScope->setAnnotations(parseAnnotations(definition->annotations)); - - if (m_nextIsInlineComponent) { - m_currentScope->setIsInlineComponent(true); - m_rootScopeImports.insert(m_inlineComponentName.toString(), m_currentScope); - m_nextIsInlineComponent = false; + Q_ASSERT(!superType.isEmpty()); + if (superType.front().isUpper()) { + if (rootScopeIsValid()) + enterEnvironment(QQmlJSScope::QMLScope, superType, definition->firstSourceLocation()); + else + enterRootScope(QQmlJSScope::QMLScope, superType, definition->firstSourceLocation()); + + const QTypeRevision revision = QQmlJSScope::resolveTypes( + m_currentScope, m_rootScopeImports, &m_usedTypes); + if (m_nextIsInlineComponent) { + m_currentScope->setIsInlineComponent(true); + m_rootScopeImports.insert( + m_inlineComponentName.toString(), { m_currentScope, revision }); + m_nextIsInlineComponent = false; + } + } else { + enterEnvironmentNonUnique(QQmlJSScope::GroupedPropertyScope, superType, + definition->firstSourceLocation()); + Q_ASSERT(rootScopeIsValid()); + QQmlJSScope::resolveTypes(m_currentScope, m_rootScopeImports, &m_usedTypes); } - QQmlJSScope::resolveTypes(m_currentScope, m_rootScopeImports, &m_usedTypes); + m_currentScope->setAnnotations(parseAnnotations(definition->annotations)); return true; } void QQmlJSImportVisitor::endVisit(UiObjectDefinition *) { QQmlJSScope::resolveTypes(m_currentScope, m_rootScopeImports, &m_usedTypes); - leaveEnvironment(); } @@ -418,17 +1045,27 @@ bool QQmlJSImportVisitor::visit(UiPublicMember *publicMember) Log_Alias, expression->firstSourceLocation()); } + } else { + const auto name = publicMember->memberType->name.toString(); + if (m_rootScopeImports.contains(name) && !m_rootScopeImports[name].scope.isNull()) { + if (m_importTypeLocationMap.contains(name)) + m_usedTypes.insert(name); + } } QQmlJSMetaProperty prop; prop.setPropertyName(publicMember->name.toString()); prop.setIsList(publicMember->typeModifier == QLatin1String("list")); prop.setIsWritable(!publicMember->isReadonlyMember); prop.setIsAlias(isAlias); - if (const auto type = m_rootScopeImports.value(typeName)) { + if (const auto type = m_rootScopeImports.value(typeName).scope) { prop.setType(type); const QString internalName = type->internalName(); prop.setTypeName(internalName.isEmpty() ? typeName : internalName); } else { + if (!isAlias) + m_pendingPropertyTypes + << PendingPropertyType { m_currentScope, prop.propertyName(), + publicMember->firstSourceLocation() }; prop.setTypeName(typeName); } prop.setAnnotations(parseAnnotations(publicMember->annotations)); @@ -441,6 +1078,7 @@ bool QQmlJSImportVisitor::visit(UiPublicMember *publicMember) break; } } + return true; } @@ -448,13 +1086,8 @@ bool QQmlJSImportVisitor::visit(UiRequired *required) { const QString name = required->name.toString(); - // The required property must be defined in some scope - if (!m_currentScope->hasProperty(name)) { - m_logger.log(QStringLiteral("Property \"%1\" was marked as required but does not exist.").arg(name), - Log_Required, - required->firstSourceLocation()); - return true; - } + m_requiredProperties << RequiredProperty { m_currentScope, name, + required->firstSourceLocation() }; m_currentScope->setPropertyLocallyRequired(name, true); return true; @@ -473,17 +1106,31 @@ void QQmlJSImportVisitor::visitFunctionExpressionHelper(QQmlJS::AST::FunctionExp m_pendingMethodAnnotations.clear(); } + bool anyFormalTyped = false; if (const auto *formals = fexpr->formals) { const auto parameters = formals->formals(); for (const auto ¶meter : parameters) { const QString type = parameter.typeName(); - method.addParameter(parameter.id, - type.isEmpty() ? QStringLiteral("var") : type); + if (type.isEmpty()) { + method.addParameter(parameter.id, QStringLiteral("var")); + } else { + anyFormalTyped = true; + method.addParameter(parameter.id, type); + } } } - method.setReturnTypeName(fexpr->typeAnnotation - ? fexpr->typeAnnotation->type->toString() - : QStringLiteral("var")); + + // Methods with explicit return type return that. + // Methods with only untyped arguments return an untyped value. + // Methods with at least one typed argument but no explicit return type return void. + // In order to make a function without arguments return void, you have to specify that. + if (fexpr->typeAnnotation) + method.setReturnTypeName(fexpr->typeAnnotation->type->toString()); + else if (anyFormalTyped) + method.setReturnTypeName(QStringLiteral("void")); + else + method.setReturnTypeName(QStringLiteral("var")); + m_currentScope->addOwnMethod(method); if (m_currentScope->scopeType() != QQmlJSScope::QMLScope) { @@ -543,48 +1190,127 @@ void QQmlJSImportVisitor::endVisit(QQmlJS::AST::ClassExpression *) leaveEnvironment(); } +bool QQmlJSImportVisitor::isImportPrefix(QString prefix) const +{ + if (prefix.isEmpty() || !prefix.front().isUpper()) + return false; + + auto it = m_rootScopeImports.find(prefix); + + if (it == m_rootScopeImports.end()) + return false; + + return it->scope.isNull(); +} + bool QQmlJSImportVisitor::visit(UiScriptBinding *scriptBinding) { + m_savedBindingOuterScope = m_currentScope; const auto id = scriptBinding->qualifiedId; const auto *statement = cast(scriptBinding->statement); if (!id->next && id->name == QLatin1String("id")) { - const auto *idExpression = cast(statement->expression); - m_scopesById.insert(idExpression->name.toString(), m_currentScope); - } else { - for (auto group = id; group->next; group = group->next) { - const QString name = group->name.toString(); + const QString name = [&]() { + if (const auto *idExpression = cast(statement->expression)) { + return idExpression->name.toString(); + } else if (const auto *idString = cast(statement->expression)) { + m_logger.log(u"ids do not need quotation marks"_qs, Log_Syntax, + idString->firstSourceLocation()); + return idString->value.toString(); + } + m_logger.log(u"Failed to parse id"_qs, Log_Syntax, + statement->expression->firstSourceLocation()); + return QString(); + }(); + if (!name.isEmpty()) + m_scopesById.insert(name, m_currentScope); + + // TODO: Discard this once we properly store binding values and can just use + // QQmlJSScope::property() to obtain this + if (m_currentScope->parentScope() && !m_currentScope->parentScope()->parentScope()) + m_rootId = name; - if (name.isEmpty()) - break; + return true; + } - enterEnvironmentNonUnique(name.front().isUpper() ? QQmlJSScope::AttachedPropertyScope - : QQmlJSScope::GroupedPropertyScope, - name, group->firstSourceLocation()); - } - // TODO: remember the actual binding, once we can process it. + auto group = id; + + QString prefix; + for (; group->next; group = group->next) { + const QString name = group->name.toString(); + if (name.isEmpty()) + break; - while (m_currentScope->scopeType() == QQmlJSScope::GroupedPropertyScope - || m_currentScope->scopeType() == QQmlJSScope::AttachedPropertyScope) { - leaveEnvironment(); + if (group == id && isImportPrefix(name)) { + prefix = name + u'.'; + continue; } - if (!statement || !statement->expression->asFunctionDefinition()) { - enterEnvironment(QQmlJSScope::JSFunctionScope, QStringLiteral("binding"), - scriptBinding->statement->firstSourceLocation()); + enterEnvironmentNonUnique(name.front().isUpper() ? QQmlJSScope::AttachedPropertyScope + : QQmlJSScope::GroupedPropertyScope, + prefix + name, group->firstSourceLocation()); + prefix.clear(); + } + + auto name = group->name; + const QString signal = signalName(name); + + if (signal.isEmpty()) { + m_propertyBindings[m_currentScope].append( + { m_savedBindingOuterScope, group->firstSourceLocation(), name.toString() }); + } else { + const auto statement = scriptBinding->statement; + QStringList signalParameters; + + if (ExpressionStatement *expr = cast(statement)) { + if (FunctionExpression *func = expr->expression->asFunctionDefinition()) { + for (FormalParameterList *formal = func->formals; formal; formal = formal->next) + signalParameters << formal->element->bindingIdentifier.toString(); + } + } + m_signals[m_currentScope].append({ m_savedBindingOuterScope, group->firstSourceLocation(), + qMakePair(name.toString(), signalParameters) }); + + QQmlJSMetaMethod scopeSignal; + for (QQmlJSScope::ConstPtr qmlScope = m_savedBindingOuterScope; + qmlScope; qmlScope = qmlScope->baseType()) { + const auto methods = qmlScope->ownMethods(); + const auto methodsRange = methods.equal_range(signal); + for (auto method = methodsRange.first; method != methodsRange.second; ++method) { + if (method->methodType() != QQmlJSMetaMethod::Signal) + continue; + scopeSignal = *method; + break; + } } + + const auto firstSourceLocation = statement->firstSourceLocation(); + bool hasMultilineStatementBody = + statement->lastSourceLocation().startLine > firstSourceLocation.startLine; + m_pendingSignalHandler = firstSourceLocation; + m_signalHandlers.insert(firstSourceLocation, + { scopeSignal.parameterNames(), hasMultilineStatementBody }); + } + + // Leave any group/attached scopes so that the binding scope doesn't see its properties. + while (m_currentScope->scopeType() == QQmlJSScope::GroupedPropertyScope + || m_currentScope->scopeType() == QQmlJSScope::AttachedPropertyScope) { + leaveEnvironment(); + } + + if (!statement || !statement->expression->asFunctionDefinition()) { + enterEnvironment(QQmlJSScope::JSFunctionScope, QStringLiteral("binding"), + scriptBinding->statement->firstSourceLocation()); } return true; } -void QQmlJSImportVisitor::endVisit(UiScriptBinding *scriptBinding) +void QQmlJSImportVisitor::endVisit(UiScriptBinding *) { - const auto id = scriptBinding->qualifiedId; - if (id->next || id->name != QLatin1String("id")) { - const auto *statement = cast(scriptBinding->statement); - if (!statement || !statement->expression->asFunctionDefinition()) - leaveEnvironment(); + if (m_savedBindingOuterScope) { + m_currentScope = m_savedBindingOuterScope; + m_savedBindingOuterScope = {}; } } @@ -599,6 +1325,8 @@ bool QQmlJSImportVisitor::visit(UiArrayBinding *arrayBinding) enterEnvironment(QQmlJSScope::QMLScope, name, arrayBinding->firstSourceLocation()); m_currentScope->setIsArrayScope(true); + // TODO: support group/attached properties + return true; } @@ -657,7 +1385,7 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiImport *import) const QString actualPrefix = prefix.isEmpty() ? QFileInfo(entry.resourcePath).baseName() : prefix; - m_rootScopeImports.insert(actualPrefix, scope); + m_rootScopeImports.insert(actualPrefix, { scope, QTypeRevision() }); addImportLocation(actualPrefix); } else { @@ -681,7 +1409,7 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiImport *import) } else if (path.isFile()) { const auto scope = m_importer->importFile(path.canonicalFilePath()); const QString actualPrefix = prefix.isEmpty() ? scope->internalName() : prefix; - m_rootScopeImports.insert(actualPrefix, scope); + m_rootScopeImports.insert(actualPrefix, { scope, QTypeRevision() }); addImportLocation(actualPrefix); } @@ -755,6 +1483,10 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::Block *ast) { enterEnvironment(QQmlJSScope::JSLexicalScope, QStringLiteral("block"), ast->firstSourceLocation()); + + if (m_pendingSignalHandler.isValid()) + flushPendingSignalParameters(); + return true; } @@ -796,6 +1528,12 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::WithStatement *ast) { enterEnvironment(QQmlJSScope::JSLexicalScope, QStringLiteral("with"), ast->firstSourceLocation()); + + m_logger.log(QStringLiteral("with statements are strongly discouraged in QML " + "and might cause false positives when analysing unqualified " + "identifiers"), + Log_WithStatement, ast->firstSourceLocation()); + return true; } @@ -844,20 +1582,30 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiObjectBinding *uiob) name.chop(1); bool needsResolution = false; + int scopesEnteredCounter = 0; + + QString prefix; for (auto group = uiob->qualifiedId; group->next; group = group->next) { const QString idName = group->name.toString(); if (idName.isEmpty()) break; + if (group == uiob->qualifiedId && isImportPrefix(idName)) { + prefix = idName + u'.'; + continue; + } + const auto scopeKind = idName.front().isUpper() ? QQmlJSScope::AttachedPropertyScope : QQmlJSScope::GroupedPropertyScope; - bool exists = enterEnvironmentNonUnique(scopeKind, idName, group->firstSourceLocation()); + bool exists = enterEnvironmentNonUnique(scopeKind, prefix + idName, group->firstSourceLocation()); + ++scopesEnteredCounter; needsResolution = needsResolution || !exists; + + prefix.clear(); } - while (m_currentScope->scopeType() == QQmlJSScope::GroupedPropertyScope - || m_currentScope->scopeType() == QQmlJSScope::AttachedPropertyScope) { + for (int i=0; i < scopesEnteredCounter; ++i) { // leave the scopes we entered again leaveEnvironment(); } @@ -868,26 +1616,42 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiObjectBinding *uiob) enterEnvironment(QQmlJSScope::QMLScope, name, uiob->qualifiedTypeNameId->identifierToken); QQmlJSScope::resolveTypes(m_currentScope, m_rootScopeImports, &m_usedTypes); + + m_objectBindingScopes << m_currentScope; return true; } void QQmlJSImportVisitor::endVisit(QQmlJS::AST::UiObjectBinding *uiob) { QQmlJSScope::resolveTypes(m_currentScope, m_rootScopeImports, &m_usedTypes); - const QQmlJSScope::ConstPtr childScope = m_currentScope; + // must be mutable, as we might mark it as implicitly wrapped in a component + const QQmlJSScope::Ptr childScope = m_currentScope; leaveEnvironment(); auto group = uiob->qualifiedId; + int scopesEnteredCounter = 0; + + QString prefix; for (; group->next; group = group->next) { const QString idName = group->name.toString(); if (idName.isEmpty()) break; + if (group == uiob->qualifiedId && isImportPrefix(idName)) { + prefix = idName + u'.'; + continue; + } + const auto scopeKind = idName.front().isUpper() ? QQmlJSScope::AttachedPropertyScope : QQmlJSScope::GroupedPropertyScope; // definitely exists - enterEnvironmentNonUnique(scopeKind, idName, group->firstSourceLocation()); + [[maybe_unused]] bool exists = + enterEnvironmentNonUnique(scopeKind, prefix + idName, group->firstSourceLocation()); + Q_ASSERT(exists); + scopesEnteredCounter++; + + prefix.clear(); } // on ending the visit to UiObjectBinding, set the property type to the @@ -895,105 +1659,22 @@ void QQmlJSImportVisitor::endVisit(QQmlJS::AST::UiObjectBinding *uiob) const QString propertyName = group->name.toString(); - QQmlJSMetaProperty property = m_currentScope->property(propertyName); - if (m_currentScope->isInCustomParserParent()) { // These warnings do not apply for custom parsers and their children and need to be handled // on a case by case basis - } else if (property.isValid() && !property.type().isNull() - && (uiob->hasOnToken || property.type()->canAssign(childScope))) { - - QQmlJSMetaPropertyBinding binding = m_currentScope->hasOwnPropertyBinding(propertyName) - ? m_currentScope->ownPropertyBinding(propertyName) - : QQmlJSMetaPropertyBinding(property); - - const QString typeName = getScopeName(childScope, QQmlJSScope::QMLScope); - - if (uiob->hasOnToken) { - if (childScope->hasInterface(QStringLiteral("QQmlPropertyValueInterceptor"))) { - if (binding.hasInterceptor()) { - m_logger.log(QStringLiteral("Duplicate interceptor on property \"%1\"") - .arg(propertyName), - Log_Property, uiob->firstSourceLocation()); - } else { - binding.setInterceptor(childScope); - binding.setInterceptorTypeName(typeName); - - m_currentScope->addOwnPropertyBinding(binding); - } - } else if (childScope->hasInterface(QStringLiteral("QQmlPropertyValueSource"))) { - if (binding.hasValueSource()) { - m_logger.log(QStringLiteral("Duplicate value source on property \"%1\"") - .arg(propertyName), - Log_Property, uiob->firstSourceLocation()); - } else if (binding.hasValue()) { - m_logger.log( - QStringLiteral( - "Cannot combine value source and binding on property \"%1\"") - .arg(propertyName), - Log_Property, uiob->firstSourceLocation()); - } else { - binding.setValueSource(childScope); - binding.setValueSourceTypeName(typeName); - m_currentScope->addOwnPropertyBinding(binding); - } - } else { - m_logger.log(QStringLiteral("On-binding for property \"%1\" has wrong type \"%2\"") - .arg(propertyName) - .arg(typeName), - Log_Property, uiob->firstSourceLocation()); - } - } else { - // TODO: Warn here if binding.hasValue() is true - if (binding.hasValueSource()) { - m_logger.log( - QStringLiteral("Cannot combine value source and binding on property \"%1\"") - .arg(propertyName), - Log_Property, uiob->firstSourceLocation()); - } else { - binding.setValue(childScope); - binding.setValueTypeName(typeName); - m_currentScope->addOwnPropertyBinding(binding); - } - } - } else if (!m_currentScope->isFullyResolved()) { - // If the current scope is not fully resolved we cannot tell whether the property exists or - // not (we already warn elsewhere) - } else if (!property.isValid()) { - m_logger.log( - QStringLiteral("Property \"%1\" is invalid or does not exist").arg(propertyName), - Log_Property, group->firstSourceLocation()); - } else if (property.type().isNull() || !property.type()->isFullyResolved()) { - // Property type is not fully resolved we cannot tell any more than this - m_logger.log( - QStringLiteral( - "Property \"%1\" has incomplete type \"%2\". You may be missing an import.") - .arg(propertyName) - .arg(property.typeName()), - Log_Property, group->firstSourceLocation()); - } else if (!childScope->isFullyResolved()) { - // If the childScope type is not fully resolved we cannot tell whether the type is - // incompatible (we already warn elsewhere) } else { - // the type is incompatible - m_logger.log( - QStringLiteral( - "Property \"%1\" of type \"%2\" is assigned an incompatible type \"%3\"") - .arg(propertyName) - .arg(property.typeName()) - .arg(getScopeName(childScope, QQmlJSScope::QMLScope)), - Log_Property, group->firstSourceLocation()); + m_pendingPropertyObjectBindings + << PendingPropertyObjectBinding { m_currentScope, childScope, propertyName, + uiob->firstSourceLocation(), uiob->hasOnToken }; } - while (m_currentScope->scopeType() == QQmlJSScope::GroupedPropertyScope - || m_currentScope->scopeType() == QQmlJSScope::AttachedPropertyScope) { + for (int i = 0; i < scopesEnteredCounter; ++i) leaveEnvironment(); - } } bool QQmlJSImportVisitor::visit(ExportDeclaration *) { - Q_ASSERT(!m_exportedRootScope.isNull()); + Q_ASSERT(rootScopeIsValid()); Q_ASSERT(m_exportedRootScope != m_globalScope); Q_ASSERT(m_currentScope == m_globalScope); m_currentScope = m_exportedRootScope; @@ -1002,18 +1683,17 @@ bool QQmlJSImportVisitor::visit(ExportDeclaration *) void QQmlJSImportVisitor::endVisit(ExportDeclaration *) { - Q_ASSERT(!m_exportedRootScope.isNull()); + Q_ASSERT(rootScopeIsValid()); m_currentScope = m_exportedRootScope->parentScope(); Q_ASSERT(m_currentScope == m_globalScope); } bool QQmlJSImportVisitor::visit(ESModule *module) { - enterEnvironment(QQmlJSScope::JSLexicalScope, QStringLiteral("module"), - module->firstSourceLocation()); - Q_ASSERT(m_exportedRootScope.isNull()); - m_exportedRootScope = m_currentScope; - m_exportedRootScope->setIsScript(true); + Q_ASSERT(!rootScopeIsValid()); + enterRootScope( + QQmlJSScope::JSLexicalScope, QStringLiteral("module"), module->firstSourceLocation()); + m_currentScope->setIsScript(true); importBaseModules(); leaveEnvironment(); return true; @@ -1027,9 +1707,10 @@ void QQmlJSImportVisitor::endVisit(ESModule *) bool QQmlJSImportVisitor::visit(Program *) { Q_ASSERT(m_globalScope == m_currentScope); - Q_ASSERT(m_exportedRootScope.isNull()); - m_exportedRootScope = m_currentScope; + Q_ASSERT(!rootScopeIsValid()); + *m_exportedRootScope = std::move(*QQmlJSScope::clone(m_currentScope)); m_exportedRootScope->setIsScript(true); + m_currentScope = m_exportedRootScope; importBaseModules(); return true; } diff --git a/src/qmlcompiler/qqmljsimportvisitor_p.h b/src/qmlcompiler/qqmljsimportvisitor_p.h index 3419f4c21be..19e96ebe99d 100644 --- a/src/qmlcompiler/qqmljsimportvisitor_p.h +++ b/src/qmlcompiler/qqmljsimportvisitor_p.h @@ -42,11 +42,12 @@ #include "qqmljsscope_p.h" #include "qqmljsannotation_p.h" #include "qqmljslogger_p.h" +#include "qqmljsscopesbyid_p.h" #include #include #include - +#include QT_BEGIN_NAMESPACE @@ -54,23 +55,36 @@ struct QQmlJSResourceFileMapper; class QQmlJSImportVisitor : public QQmlJS::AST::Visitor { public: - QQmlJSImportVisitor(QQmlJSImporter *importer, const QString &implicitImportDirectory, - const QStringList &qmltypesFiles = QStringList(), const QString &fileName = QString(), const QString &code = QString(), bool silent = true); + QQmlJSImportVisitor( + const QQmlJSScope::Ptr &target, QQmlJSImporter *importer, + const QString &implicitImportDirectory, + const QStringList &qmltypesFiles = QStringList(), const QString &fileName = QString(), + const QString &code = QString(), bool silent = true); - QQmlJSScope::Ptr result() const; + QQmlJSScope::Ptr result() const { return m_exportedRootScope; } // TODO: Should be superseded by accessing the logger instead QList errors() const { return m_logger.warnings() + m_logger.errors(); } QQmlJSLogger &logger() { return m_logger; } - QHash imports() const { return m_rootScopeImports; } - QHash addressableScopes() const { return m_scopesById; } + QQmlJSImporter::ImportedTypes imports() const { return m_rootScopeImports; } + QQmlJSScopesById addressableScopes() const { return m_scopesById; } + QHash scopesBylocation() const + { + return m_scopesByIrLocation; + } static QString implicitImportDirectory( const QString &localFile, QQmlJSResourceFileMapper *mapper); protected: + // Linter warnings, we might want to move this at some point + bool visit(QQmlJS::AST::StringLiteral *) override; + + bool visit(QQmlJS::AST::ExpressionStatement *ast) override; + void endVisit(QQmlJS::AST::ExpressionStatement *ast) override; + bool visit(QQmlJS::AST::UiProgram *) override; void endVisit(QQmlJS::AST::UiProgram *) override; bool visit(QQmlJS::AST::UiObjectDefinition *) override; @@ -125,14 +139,22 @@ class QQmlJSImportVisitor : public QQmlJS::AST::Visitor void throwRecursionDepthError() override; QString m_implicitImportDirectory; + QString m_code; + QString m_filePath; + QString m_rootId; QStringView m_inlineComponentName; bool m_nextIsInlineComponent = false; QStringList m_qmltypesFiles; QQmlJSScope::Ptr m_currentScope; - QQmlJSScope::Ptr m_exportedRootScope; + QQmlJSScope::Ptr m_savedBindingOuterScope; + const QQmlJSScope::Ptr m_exportedRootScope; QQmlJSScope::ConstPtr m_globalScope; - QHash m_scopesById; - QHash m_rootScopeImports; + QQmlJSScopesById m_scopesById; + QQmlJSImporter::ImportedTypes m_rootScopeImports; + + // We need to record the locations as IR locations because those contain less data. + // This way we can look up objects by IR location later. + QHash m_scopesByIrLocation; // Maps all qmlNames to the source location of their import QMultiHash m_importTypeLocationMap; @@ -152,17 +174,107 @@ class QQmlJSImportVisitor : public QQmlJS::AST::Visitor void leaveEnvironment(); QVector parseAnnotations(QQmlJS::AST::UiAnnotationList *list); + void addDefaultProperties(); + void processDefaultProperties(); + void processPropertyBindings(); + void checkRequiredProperties(); + void processPropertyTypes(); + void processPropertyBindingObjects(); + void checkSignals(); + void flushPendingSignalParameters(); + + QQmlJSScope::ConstPtr scopeById(const QString &id, const QQmlJSScope::ConstPtr ¤t); + + void breakInheritanceCycles(const QQmlJSScope::Ptr &scope); + void checkDeprecation(const QQmlJSScope::ConstPtr &scope); + void checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr scope); + bool rootScopeIsValid() const { return m_exportedRootScope->sourceLocation().isValid(); } + + bool isImportPrefix(QString prefix) const; QQmlJSLogger m_logger; // Used to temporarily store annotations for functions and generators wrapped in UiSourceElements QVector m_pendingMethodAnnotations; + + struct PendingPropertyType + { + QQmlJSScope::Ptr scope; + QString name; + QQmlJS::SourceLocation location; + }; + + struct PendingPropertyObjectBinding + { + QQmlJSScope::Ptr scope; + QQmlJSScope::Ptr childScope; + QString name; + QQmlJS::SourceLocation location; + bool onToken; + }; + + struct RequiredProperty + { + QQmlJSScope::Ptr scope; + QString name; + QQmlJS::SourceLocation location; + }; + + /*! + Utility wrapper that adds visibility scope to the data. + + This wrapper becomes useful for binding processing where we need to know + both the property (or signal handler) owner and the scope in which the + binding is executed (the "visibility" scope). + + As visibility scope (and data) does not typically have sufficient + information about a proper source location of that data, the location + also has to be provided to simplify the error reporting. + */ + template + struct WithVisibilityScope + { + QQmlJSScope::Ptr visibilityScope; + QQmlJS::SourceLocation dataLocation; + T data; + }; + + QHash> m_pendingDefaultProperties; + QVector m_pendingPropertyTypes; + QVector m_pendingPropertyObjectBindings; + QVector m_requiredProperties; + QVector m_objectBindingScopes; + QVector m_objectDefinitionScopes; + + QHash>> m_propertyBindings; + QHash>>> m_signals; + + QHash m_signalHandlers; + QQmlJS::SourceLocation m_pendingSignalHandler; + + struct OutstandingConnection + { + QString targetName; + QQmlJSScope::Ptr scope; + QQmlJS::AST::UiObjectDefinition *uiod; + }; + + QVarLengthArray + m_outstandingConnections; // Connections whose target we have not encountered + private: void importBaseModules(); void resolveAliases(); + void visitFunctionExpressionHelper(QQmlJS::AST::FunctionExpression *fexpr); - void processImportWarnings(const QString &what, const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation()); + void processImportWarnings( + const QString &what, + const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation()); void addImportWithLocation(const QString &name, const QQmlJS::SourceLocation &loc); + void populateCurrentScope(QQmlJSScope::ScopeType type, const QString &name, + const QQmlJS::SourceLocation &location); + void enterRootScope(QQmlJSScope::ScopeType type, const QString &name, + const QQmlJS::SourceLocation &location); }; QT_END_NAMESPACE diff --git a/src/qmlcompiler/qqmljslogger.cpp b/src/qmlcompiler/qqmljslogger.cpp index 7f04e3b66ef..833927e082d 100644 --- a/src/qmlcompiler/qqmljslogger.cpp +++ b/src/qmlcompiler/qqmljslogger.cpp @@ -26,6 +26,17 @@ ** ****************************************************************************/ +#include + +// GCC 11 thinks diagMsg.fixSuggestion.fixes.d.ptr is somehow uninitialized in +// QList::emplaceBack(), probably called from QQmlJsLogger::log() +// Ditto for GCC 12, but it emits a different warning +QT_WARNING_PUSH +QT_WARNING_DISABLE_GCC("-Wuninitialized") +QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") +#include +QT_WARNING_POP + #include "qqmljslogger_p.h" const QMap &QQmlJSLogger::options() { diff --git a/src/qmlcompiler/qqmljslogger_p.h b/src/qmlcompiler/qqmljslogger_p.h index 5ccbe910451..2d63a860c3c 100644 --- a/src/qmlcompiler/qqmljslogger_p.h +++ b/src/qmlcompiler/qqmljslogger_p.h @@ -63,7 +63,7 @@ class IssueLocationWithContext \param location: The location where an error occurred. */ IssueLocationWithContext(QStringView code, const QQmlJS::SourceLocation &location) { - int before = qMax(0,code.lastIndexOf(QLatin1Char('\n'), location.offset)); + quint32 before = qMax(0, code.lastIndexOf(QLatin1Char('\n'), location.offset)); if (before != 0) before++; diff --git a/src/qmlcompiler/qqmljsmetatypes_p.h b/src/qmlcompiler/qqmljsmetatypes_p.h index 28b9e07efca..513414d87f0 100644 --- a/src/qmlcompiler/qqmljsmetatypes_p.h +++ b/src/qmlcompiler/qqmljsmetatypes_p.h @@ -416,6 +416,12 @@ class QQmlJSMetaPropertyBinding } }; +struct QQmlJSMetaSignalHandler +{ + QStringList signalParameters; + bool isMultiline; +}; + QT_END_NAMESPACE #endif // QQMLJSMETATYPES_P_H diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp index 2276c108146..ee55fa214af 100644 --- a/src/qmlcompiler/qqmljsscope.cpp +++ b/src/qmlcompiler/qqmljsscope.cpp @@ -34,6 +34,8 @@ #include #include +#include + #include #include @@ -68,20 +70,35 @@ static auto getQQmlJSScopeFromSmartPtr(const From &p) -> decltype(p.get()) template static bool searchBaseAndExtensionTypes(QQmlJSScopePtr type, const Action &check) { + if (!type) + return false; + // NB: among other things, getQQmlJSScopeFromSmartPtr() also resolves const // vs non-const pointer issue, so use it's return value as the type using T = decltype( getQQmlJSScopeFromSmartPtr(std::declval())); - for (T scope = type; scope; + const bool isValueType = (type->accessSemantics() == QQmlJSScope::AccessSemantics::Value); + + QDuplicateTracker seen; + for (T scope = type; scope && !seen.hasSeen(scope); scope = getQQmlJSScopeFromSmartPtr(scope->baseType())) { - // Extensions override their base types - for (T extension = getQQmlJSScopeFromSmartPtr(scope->extensionType()); - extension; - extension = getQQmlJSScopeFromSmartPtr(extension->baseType())) { + QDuplicateTracker seenExtensions; + // Extensions override the types they extend. However, usually base + // types of extensions are ignored. The unusual cases are when we + // have a value type or when we have the QObject type, in which case + // we also study the extension's base type hierarchy. + const bool isQObject = scope->internalName() == QLatin1String("QObject"); + T extension = getQQmlJSScopeFromSmartPtr(scope->extensionType()); + do { + if (!extension || seenExtensions.hasSeen(extension)) + break; + if (check(extension)) return true; - } + + extension = getQQmlJSScopeFromSmartPtr(extension->baseType()); + } while (isValueType || isQObject); if (check(scope)) return true; @@ -90,15 +107,24 @@ static bool searchBaseAndExtensionTypes(QQmlJSScopePtr type, const Action &check return false; } -QQmlJSScope::QQmlJSScope(ScopeType type, const QQmlJSScope::Ptr &parentScope) - : m_parentScope(parentScope), m_scopeType(type) {} - -QQmlJSScope::Ptr QQmlJSScope::create(ScopeType type, const QQmlJSScope::Ptr &parentScope) +void QQmlJSScope::reparent(const QQmlJSScope::Ptr &parentScope, const QQmlJSScope::Ptr &childScope) { - QSharedPointer childScope(new QQmlJSScope{type, parentScope}); + if (const QQmlJSScope::Ptr parent = childScope->m_parentScope.toStrongRef()) + parent->m_childScopes.removeOne(childScope); if (parentScope) - parentScope->m_childScopes.push_back(childScope); - return childScope; + parentScope->m_childScopes.append(childScope); + childScope->m_parentScope = parentScope; +} + +QQmlJSScope::Ptr QQmlJSScope::clone(const ConstPtr &origin) +{ + if (origin.isNull()) + return QQmlJSScope::Ptr(); + QQmlJSScope::Ptr cloned = create(); + *cloned = *origin; + if (QQmlJSScope::Ptr parent = cloned->parentScope()) + parent->m_childScopes.append(cloned); + return cloned; } void QQmlJSScope::insertJSIdentifier(const QString &name, const JavaScriptIdentifier &identifier) @@ -179,6 +205,45 @@ QQmlJSMetaEnum QQmlJSScope::enumeration(const QString &name) const return result; } +/*! + Returns if assigning to a property of this type would cause + implicit component wrapping for non-Component types. + + \note This method can also be used to check whether a type needs + to be implicitly wrapped: A type for which this function returns true + doesn't need to be actually wrapped. + */ +bool QQmlJSScope::causesImplicitComponentWrapping() const { + if (internalName() == u"QQmlComponent") + return true; + else if (isComposite()) // composite types are never treated as Component + return false; + // A class which is derived from component is not treated as a Component + // However isUsableComponent considers also QQmlAbstractDelegateComponent + // See isUsableComponent in qqmltypecompiler.cpp + + for (auto cppBase = nonCompositeBaseType(baseType()); cppBase; cppBase = cppBase->baseType()) + if (cppBase->internalName() == u"QQmlAbstractDelegateComponent") + return true; + return false; +} + +/*! + \internal + Returns true if the scope is the outermost element of a separate Component + Either because it has been implicitly wrapped, e.g. due to an assignment to + a Component property, or because it is the first (and only) child of a + Component. + */ +bool QQmlJSScope::isComponentRootElement() const { + if (m_flags.testFlag(WrappedInImplicitComponent)) + return true; + auto base = nonCompositeBaseType(parentScope()); // handles null parentScope() + if (!base) + return false; + return base->internalName() == u"QQmlComponent"; +} + bool QQmlJSScope::isIdInCurrentQmlScopes(const QString &id) const { if (m_scopeType == QQmlJSScope::QMLScope) @@ -224,70 +289,61 @@ QQmlJSScope::findJSIdentifier(const QString &id) const return std::optional{}; } -void QQmlJSScope::resolveTypes(const QQmlJSScope::Ptr &self, - const QHash &contextualTypes, - QSet *usedTypes) +QQmlJSScope::ImportedScope QQmlJSScope::findType( + const QString &name, const QQmlJSScope::ContextualTypes &contextualTypes, + QSet *usedTypes) { - auto findType = [&](const QString &name) -> QQmlJSScope::ConstPtr { - auto type = contextualTypes.constFind(name); + auto type = contextualTypes.constFind(name); - if (type != contextualTypes.constEnd()) { - if (usedTypes != nullptr) - usedTypes->insert(name); - return *type; - } + if (type != contextualTypes.constEnd()) { + if (usedTypes != nullptr) + usedTypes->insert(name); + return *type; + } - const auto colonColon = name.indexOf(QStringLiteral("::")); - if (colonColon > 0) { - const QString outerTypeName = name.left(colonColon); - const auto outerType = contextualTypes.constFind(outerTypeName); - if (outerType != contextualTypes.constEnd()) { - for (const auto &innerType : qAsConst((*outerType)->m_childScopes)) { - if (innerType->m_internalName == name) { - if (usedTypes != nullptr) - usedTypes->insert(name); - return innerType; - } + const auto colonColon = name.indexOf(QStringLiteral("::")); + if (colonColon > 0) { + const QString outerTypeName = name.left(colonColon); + const auto outerType = contextualTypes.constFind(outerTypeName); + if (outerType != contextualTypes.constEnd()) { + for (const auto &innerType : qAsConst(outerType->scope->m_childScopes)) { + if (innerType->m_internalName == name) { + if (usedTypes != nullptr) + usedTypes->insert(name); + return { innerType, outerType->revision }; } } } + } - return QQmlJSScope::ConstPtr(); - }; + return {}; +} - if (!self->m_baseType && !self->m_baseTypeName.isEmpty()) - self->m_baseType = findType(self->m_baseTypeName); +QTypeRevision QQmlJSScope::resolveType( + const QQmlJSScope::Ptr &self, const QQmlJSScope::ContextualTypes &context, + QSet *usedTypes) +{ + const QString baseTypeName = self->baseTypeName(); + const auto baseType = findType(baseTypeName, context, usedTypes); + if (!self->m_baseType.scope && !baseTypeName.isEmpty()) + self->m_baseType = { baseType.scope, baseType.revision }; if (!self->m_attachedType && !self->m_attachedTypeName.isEmpty()) - self->m_attachedType = findType(self->m_attachedTypeName); + self->m_attachedType = findType(self->m_attachedTypeName, context, usedTypes).scope; if (!self->m_valueType && !self->m_valueTypeName.isEmpty()) - self->m_valueType = findType(self->m_valueTypeName); + self->m_valueType = findType(self->m_valueTypeName, context, usedTypes).scope; if (!self->m_extensionType && !self->m_extensionTypeName.isEmpty()) - self->m_extensionType = findType(self->m_extensionTypeName); - - const auto intType = findType(QStringLiteral("int")); - Q_ASSERT(intType); // There always has to be a builtin "int" type - for (auto it = self->m_enumerations.begin(), end = self->m_enumerations.end(); - it != end; ++it) { - if (it->type()) - continue; - auto enumScope = QQmlJSScope::create(EnumScope, self); - enumScope->m_baseTypeName = QStringLiteral("int"); - enumScope->m_baseType = intType; - enumScope->m_semantics = AccessSemantics::Value; - enumScope->m_internalName = self->internalName() + QStringLiteral("::") + it->name(); - it->setType(ConstPtr(enumScope)); - } + self->m_extensionType = findType(self->m_extensionTypeName, context, usedTypes).scope; for (auto it = self->m_properties.begin(), end = self->m_properties.end(); it != end; ++it) { const QString typeName = it->typeName(); if (it->type() || typeName.isEmpty()) continue; - if (const auto type = findType(typeName)) { - it->setType(type); + if (const auto type = findType(typeName, context, usedTypes); type.scope) { + it->setType(type.scope); continue; } @@ -298,8 +354,10 @@ void QQmlJSScope::resolveTypes(const QQmlJSScope::Ptr &self, for (auto it = self->m_methods.begin(), end = self->m_methods.end(); it != end; ++it) { const QString returnTypeName = it->returnTypeName(); - if (!it->returnType() && !returnTypeName.isEmpty()) - it->setReturnType(findType(returnTypeName)); + if (!it->returnType() && !returnTypeName.isEmpty()) { + const auto returnType = findType(returnTypeName, context, usedTypes); + it->setReturnType(returnType.scope); + } const auto paramTypeNames = it->parameterTypeNames(); QList> paramTypes = it->parameterTypes(); @@ -309,37 +367,97 @@ void QQmlJSScope::resolveTypes(const QQmlJSScope::Ptr &self, for (int i = 0, length = paramTypes.length(); i < length; ++i) { auto ¶mType = paramTypes[i]; const auto paramTypeName = paramTypeNames[i]; - if (!paramType && !paramTypeName.isEmpty()) - paramType = findType(paramTypeName); + if (!paramType && !paramTypeName.isEmpty()) { + const auto type = findType(paramTypeName, context, usedTypes); + paramType = type.scope; + } } it->setParameterTypes(paramTypes); } - for (auto it = self->m_childScopes.begin(), end = self->m_childScopes.end(); it != end; ++it) { - QQmlJSScope::Ptr childScope = *it; - switch (childScope->scopeType()) { - case QQmlJSScope::GroupedPropertyScope: - searchBaseAndExtensionTypes(self.data(), [&](const QQmlJSScope *type) { - const auto propertyIt = type->m_properties.find(childScope->internalName()); - if (propertyIt != type->m_properties.end()) { - childScope->m_baseType = QQmlJSScope::ConstPtr(propertyIt->type()); - childScope->m_baseTypeName = propertyIt->typeName(); - return true; - } - return false; - }); - break; - case QQmlJSScope::AttachedPropertyScope: - if (const auto attachedBase = findType(childScope->internalName())) { - childScope->m_baseType = attachedBase->attachedType(); - childScope->m_baseTypeName = attachedBase->attachedTypeName(); + return baseType.revision; +} + +void QQmlJSScope::updateChildScope( + const QQmlJSScope::Ptr &childScope, const QQmlJSScope::Ptr &self, + const QQmlJSScope::ContextualTypes &contextualTypes, QSet *usedTypes) +{ + switch (childScope->scopeType()) { + case QQmlJSScope::GroupedPropertyScope: + searchBaseAndExtensionTypes(self.data(), [&](const QQmlJSScope *type) { + const auto propertyIt = type->m_properties.find(childScope->internalName()); + if (propertyIt != type->m_properties.end()) { + childScope->m_baseType.scope = QQmlJSScope::ConstPtr(propertyIt->type()); + childScope->setBaseTypeName(propertyIt->typeName()); + return true; } - break; - default: - break; + return false; + }); + break; + case QQmlJSScope::AttachedPropertyScope: + if (const auto attachedBase = findType( + childScope->internalName(), contextualTypes, usedTypes).scope) { + childScope->m_baseType.scope = attachedBase->attachedType(); + childScope->setBaseTypeName(attachedBase->attachedTypeName()); } - resolveTypes(childScope, contextualTypes, usedTypes); + break; + default: + break; + } +} + +template +static QTypeRevision resolveTypesInternal( + Resolver resolve, ChildScopeUpdater update, const QQmlJSScope::Ptr &self, + const QQmlJSScope::ContextualTypes &contextualTypes, QSet *usedTypes) +{ + const QTypeRevision revision = resolve(self, contextualTypes, usedTypes); + // NB: constness ensures no detach + const auto childScopes = self->childScopes(); + for (auto it = childScopes.begin(), end = childScopes.end(); it != end; ++it) { + const auto childScope = *it; + update(childScope, self, contextualTypes, usedTypes); + resolveTypesInternal(resolve, update, childScope, contextualTypes, usedTypes); // recursion + } + return revision; +} + +QTypeRevision QQmlJSScope::resolveTypes( + const QQmlJSScope::Ptr &self, const QQmlJSScope::ContextualTypes &contextualTypes, + QSet *usedTypes) +{ + const auto resolveAll = [](const QQmlJSScope::Ptr &self, + const QQmlJSScope::ContextualTypes &contextualTypes, + QSet *usedTypes) { + resolveEnums(self, findType(u"int"_qs, contextualTypes, usedTypes).scope); + return resolveType(self, contextualTypes, usedTypes); + }; + return resolveTypesInternal(resolveAll, updateChildScope, self, contextualTypes, usedTypes); +} + +void QQmlJSScope::resolveNonEnumTypes( + const QQmlJSScope::Ptr &self, const QQmlJSScope::ContextualTypes &contextualTypes, + QSet *usedTypes) +{ + resolveTypesInternal(resolveType, updateChildScope, self, contextualTypes, usedTypes); +} + +void QQmlJSScope::resolveEnums(const QQmlJSScope::Ptr &self, const QQmlJSScope::ConstPtr &intType) +{ + Q_ASSERT(intType); // There always has to be a builtin "int" type + for (auto it = self->m_enumerations.begin(), end = self->m_enumerations.end(); it != end; + ++it) { + if (it->type()) + continue; + QQmlJSScope::Ptr enumScope = QQmlJSScope::create(); + reparent(self, enumScope); + enumScope->m_scopeType = EnumScope; + enumScope->setBaseTypeName(QStringLiteral("int")); + enumScope->m_baseType.scope = intType; + enumScope->m_semantics = AccessSemantics::Value; + enumScope->m_internalName = self->internalName() + QStringLiteral("::") + it->name(); + it->setType(QQmlJSScope::ConstPtr(enumScope)); } } @@ -352,9 +470,9 @@ QQmlJSScope::ConstPtr QQmlJSScope::findCurrentQMLScope(const QQmlJSScope::ConstP } void QQmlJSScope::addExport(const QString &name, const QString &package, - const QTypeRevision &version) + const QTypeRevision &version, const QTypeRevision &revision) { - m_exports.append(Export(package, name, version)); + m_exports.append(Export(package, name, version, revision)); } bool QQmlJSScope::hasProperty(const QString &name) const @@ -447,6 +565,28 @@ bool QQmlJSScope::hasInterface(const QString &name) const this, [&](const QQmlJSScope *scope) { return scope->m_interfaceNames.contains(name); }); } +void QQmlJSScope::setBaseTypeName(const QString &baseTypeName) +{ + m_flags.setFlag(HasBaseTypeError, false); + m_baseTypeNameOrError = baseTypeName; +} + +QString QQmlJSScope::baseTypeName() const +{ + return m_flags.testFlag(HasBaseTypeError) ? QString() : m_baseTypeNameOrError; +} + +void QQmlJSScope::setBaseTypeError(const QString &baseTypeError) +{ + m_flags.setFlag(HasBaseTypeError); + m_baseTypeNameOrError = baseTypeError; +} + +QString QQmlJSScope::baseTypeError() const +{ + return m_flags.testFlag(HasBaseTypeError) ? m_baseTypeNameOrError : QString(); +} + QString QQmlJSScope::attachedTypeName() const { QString name; @@ -477,10 +617,10 @@ bool QQmlJSScope::isResolved() const { if (m_scopeType == ScopeType::AttachedPropertyScope || m_scopeType == ScopeType::GroupedPropertyScope) { - return m_internalName.isEmpty() || !m_baseType.isNull(); + return m_internalName.isEmpty() || !m_baseType.scope.isNull(); } - return m_baseTypeName.isEmpty() || !m_baseType.isNull(); + return m_baseTypeNameOrError.isEmpty() || !m_baseType.scope.isNull(); } bool QQmlJSScope::isFullyResolved() const @@ -497,10 +637,12 @@ bool QQmlJSScope::isFullyResolved() const return baseResolved; } -QQmlJSScope::Export::Export(QString package, QString type, const QTypeRevision &version) : +QQmlJSScope::Export::Export( + QString package, QString type, QTypeRevision version, QTypeRevision revision) : m_package(std::move(package)), m_type(std::move(type)), - m_version(version) + m_version(std::move(version)), + m_revision(std::move(revision)) { } @@ -509,13 +651,12 @@ bool QQmlJSScope::Export::isValid() const return m_version.isValid() || !m_package.isEmpty() || !m_type.isEmpty(); } -QQmlJSScope QDeferredFactory::create() const +void QDeferredFactory::populate(const QSharedPointer &scope) const { QQmlJSTypeReader typeReader(m_importer, m_filePath); - QQmlJSScope::Ptr result = typeReader(); + typeReader(scope); m_importer->m_warnings.append(typeReader.errors()); - result->setInternalName(QFileInfo(m_filePath).baseName()); - return std::move(*result); + scope->setInternalName(QFileInfo(m_filePath).baseName()); } bool QQmlJSScope::canAssign(const QQmlJSScope::ConstPtr &derived) const @@ -523,15 +664,11 @@ bool QQmlJSScope::canAssign(const QQmlJSScope::ConstPtr &derived) const if (!derived) return false; - bool isBaseComponent = false; - for (auto scope = this; scope; scope = scope->baseType().get()) { - if (internalName() == u"QQmlComponent"_qs) { - isBaseComponent = true; - break; - } - } + bool isBaseComponent = causesImplicitComponentWrapping(); - for (auto scope = derived; !scope.isNull(); scope = scope->baseType()) { + QDuplicateTracker seen; + for (auto scope = derived; !scope.isNull() && !seen.hasSeen(scope); + scope = scope->baseType()) { if (isSameType(scope)) return true; if (isBaseComponent && scope->internalName() == u"QObject"_qs) diff --git a/src/qmlcompiler/qqmljsscope_p.h b/src/qmlcompiler/qqmljsscope_p.h index 3822cd9c324..e0d75dd2dc6 100644 --- a/src/qmlcompiler/qqmljsscope_p.h +++ b/src/qmlcompiler/qqmljsscope_p.h @@ -67,7 +67,7 @@ class QDeferredFactory m_filePath(filePath), m_importer(importer) {} - QQmlJSScope create() const; + void populate(const QSharedPointer &scope) const; bool isValid() const { @@ -81,7 +81,6 @@ class QDeferredFactory class QQmlJSScope { - Q_DISABLE_COPY(QQmlJSScope) public: QQmlJSScope(QQmlJSScope &&) = default; QQmlJSScope &operator=(QQmlJSScope &&) = default; @@ -115,7 +114,9 @@ class QQmlJSScope Script = 0x8, CustomParser = 0x10, Array = 0x20, - InlineComponent = 0x40 + InlineComponent = 0x40, + WrappedInImplicitComponent = 0x80, + HasBaseTypeError = 0x100 }; Q_DECLARE_FLAGS(Flags, Flag) Q_FLAGS(Flags); @@ -123,20 +124,36 @@ class QQmlJSScope class Export { public: Export() = default; - Export(QString package, QString type, const QTypeRevision &version); + Export(QString package, QString type, QTypeRevision version, QTypeRevision revision); bool isValid() const; QString package() const { return m_package; } QString type() const { return m_type; } QTypeRevision version() const { return m_version; } + QTypeRevision revision() const { return m_revision; } private: QString m_package; QString m_type; QTypeRevision m_version; + QTypeRevision m_revision; }; + template + struct ExportedScope { + Pointer scope; + QList exports; + }; + + template + struct ImportedScope { + Pointer scope; + QTypeRevision revision; + }; + + using ContextualTypes = QHash>; + struct JavaScriptIdentifier { enum Kind { @@ -150,8 +167,8 @@ class QQmlJSScope QQmlJS::SourceLocation location; }; - static QQmlJSScope::Ptr create(ScopeType type = QQmlJSScope::QMLScope, - const QQmlJSScope::Ptr &parentScope = QQmlJSScope::Ptr()); + static QQmlJSScope::Ptr create() { return QSharedPointer(new QQmlJSScope); } + static QQmlJSScope::Ptr clone(const QQmlJSScope::ConstPtr &origin); static QQmlJSScope::ConstPtr findCurrentQMLScope(const QQmlJSScope::ConstPtr &scope); QQmlJSScope::Ptr parentScope() @@ -164,6 +181,8 @@ class QQmlJSScope return QQmlJSScope::WeakConstPtr(m_parentScope).toStrongRef(); } + static void reparent(const QQmlJSScope::Ptr &parentScope, const QQmlJSScope::Ptr &childScope); + void insertJSIdentifier(const QString &name, const JavaScriptIdentifier &identifier); // inserts property as qml identifier as well as the corresponding @@ -172,6 +191,7 @@ class QQmlJSScope bool isIdInCurrentScope(const QString &id) const; ScopeType scopeType() const { return m_scopeType; } + void setScopeType(ScopeType type) { m_scopeType = type; } void addOwnMethod(const QQmlJSMetaMethod &method) { m_methods.insert(method.methodName(), method); } QMultiHash ownMethods() const { return m_methods; } @@ -201,8 +221,13 @@ class QQmlJSScope QString internalName() const { return m_internalName; } void setInternalName(const QString &internalName) { m_internalName = internalName; } - void addExport(const QString &name, const QString &package, const QTypeRevision &version); + bool causesImplicitComponentWrapping() const; + bool isComponentRootElement() const; + + void addExport(const QString &name, const QString &package, + const QTypeRevision &version, const QTypeRevision &revision); QList exports() const { return m_exports; } + void setExports(const QList &exports) { m_exports = exports; } void setInterfaceNames(const QStringList& interfaces) { m_interfaceNames = interfaces; } QStringList interfaceNames() const { return m_interfaceNames; } @@ -212,9 +237,15 @@ class QQmlJSScope // If isComposite(), this is the QML/JS name of the prototype. Otherwise it's the // relevant base class (in the hierarchy starting from QObject) of a C++ type. - void setBaseTypeName(const QString &baseTypeName) { m_baseTypeName = baseTypeName; } - QString baseTypeName() const { return m_baseTypeName; } - QQmlJSScope::ConstPtr baseType() const { return m_baseType; } + void setBaseTypeName(const QString &baseTypeName); + QString baseTypeName() const; + + QQmlJSScope::ConstPtr baseType() const { return m_baseType.scope; } + QTypeRevision baseTypeRevision() const { return m_baseType.revision; } + + void clearBaseType() { m_baseType = {}; } + void setBaseTypeError(const QString &baseTypeError); + QString baseTypeError() const; void addOwnProperty(const QQmlJSMetaProperty &prop) { m_properties.insert(prop.propertyName(), prop); } QHash ownProperties() const { return m_properties; } @@ -292,6 +323,7 @@ class QQmlJSScope } void setIsArrayScope(bool v) { m_flags.setFlag(Array, v); } void setIsInlineComponent(bool v) { m_flags.setFlag(InlineComponent, v); } + void setIsWrappedInImplicitComponent(bool v) { m_flags.setFlag(WrappedInImplicitComponent, v); } void setAccessSemantics(AccessSemantics semantics) { m_semantics = semantics; } AccessSemantics accessSemantics() const { return m_semantics; } @@ -316,9 +348,17 @@ class QQmlJSScope return result; } - static void resolveTypes(const QQmlJSScope::Ptr &self, - const QHash &contextualTypes, - QSet *usedTypes = nullptr); + static QTypeRevision resolveTypes( + const QQmlJSScope::Ptr &self, + const QQmlJSScope::ContextualTypes &contextualTypes, + QSet *usedTypes = nullptr); + static void resolveNonEnumTypes( + const QQmlJSScope::Ptr &self, + const QQmlJSScope::ContextualTypes &contextualTypes, + QSet *usedTypes = nullptr); + static void resolveEnums( + const QQmlJSScope::Ptr &self, + const QQmlJSScope::ConstPtr &intType); void setSourceLocation(const QQmlJS::SourceLocation &sourceLocation) { @@ -339,6 +379,16 @@ class QQmlJSScope return {}; } + static QTypeRevision nonCompositeBaseRevision(const ImportedScope &scope) + { + for (auto base = scope; base.scope; + base = { base.scope->m_baseType.scope, base.scope->m_baseType.revision }) { + if (!base.scope->isComposite()) + return base.revision; + } + return {}; + } + /*! \internal Checks whether \a otherScope is the same type as this. @@ -380,7 +430,19 @@ class QQmlJSScope bool isInCustomParserParent() const; private: - QQmlJSScope(ScopeType type, const QQmlJSScope::Ptr &parentScope = QQmlJSScope::Ptr()); + QQmlJSScope() = default; + QQmlJSScope(const QQmlJSScope &) = default; + QQmlJSScope &operator=(const QQmlJSScope &) = default; + + static ImportedScope findType( + const QString &name, const ContextualTypes &contextualTypes, + QSet *usedTypes = nullptr); + static QTypeRevision resolveType( + const QQmlJSScope::Ptr &self, const ContextualTypes &contextualTypes, + QSet *usedTypes); + static void updateChildScope( + const QQmlJSScope::Ptr &childScope, const QQmlJSScope::Ptr &self, + const QQmlJSScope::ContextualTypes &contextualTypes, QSet *usedTypes); QHash m_jsIdentifiers; @@ -395,8 +457,11 @@ class QQmlJSScope QString m_fileName; QString m_internalName; - QString m_baseTypeName; - QQmlJSScope::WeakConstPtr m_baseType; + QString m_baseTypeNameOrError; + + // We only need the revision for the base type as inheritance is + // the only relation between two types where the revisions matter. + ImportedScope m_baseType; ScopeType m_scopeType = QMLScope; QList m_exports; @@ -420,6 +485,9 @@ class QQmlJSScope QQmlJS::SourceLocation m_sourceLocation; }; +using QQmlJSExportedScope = QQmlJSScope::ExportedScope; +using QQmlJSImportedScope = QQmlJSScope::ImportedScope; + QT_END_NAMESPACE #endif // QQMLJSSCOPE_P_H diff --git a/src/qmlcompiler/qqmljsscopesbyid_p.h b/src/qmlcompiler/qqmljsscopesbyid_p.h new file mode 100644 index 00000000000..3abca0ed505 --- /dev/null +++ b/src/qmlcompiler/qqmljsscopesbyid_p.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 QQMLJSSCOPESBYID_P_H +#define QQMLJSSCOPESBYID_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + + +#include "qqmljsscope_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +class QQmlJSScopesById +{ +public: + QString id(const QQmlJSScope::ConstPtr &scope) const + { + for (auto it = m_scopesById.begin(), end = m_scopesById.end(); it != end; ++it) { + if (*it == scope) + return it.key(); + } + return QString(); + } + + QQmlJSScope::ConstPtr scope(const QString &id, const QQmlJSScope::ConstPtr &referrer) const + { + Q_ASSERT(!id.isEmpty()); + const QQmlJSScope::ConstPtr root = componentRoot(referrer); + const auto range = m_scopesById.equal_range(id); + for (auto it = range.first; it != range.second; ++it) { + if (componentRoot(*it) == root) + return *it; + } + return QQmlJSScope::ConstPtr(); + } + + void insert(const QString &id, const QQmlJSScope::ConstPtr &scope) + { + Q_ASSERT(!id.isEmpty()); + m_scopesById.insert(id, scope); + } + + void clear() { m_scopesById.clear(); } + +private: + static QQmlJSScope::ConstPtr componentRoot(const QQmlJSScope::ConstPtr &inner) + { + QQmlJSScope::ConstPtr scope = inner; + while (scope && !scope->isComponentRootElement() && !scope->isInlineComponent()) { + if (QQmlJSScope::ConstPtr parent = scope->parentScope()) + scope = parent; + else + break; + } + return scope; + } + + QMultiHash m_scopesById; +}; + +QT_END_NAMESPACE + +#endif // QQMLJSSCOPESBYID_P_H diff --git a/src/qmlcompiler/qqmljstypedescriptionreader.cpp b/src/qmlcompiler/qqmljstypedescriptionreader.cpp index 3a317fd452c..04293fd14cc 100644 --- a/src/qmlcompiler/qqmljstypedescriptionreader.cpp +++ b/src/qmlcompiler/qqmljstypedescriptionreader.cpp @@ -192,6 +192,7 @@ void QQmlJSTypeDescriptionReader::readComponent(UiObjectDefinition *ast) { QQmlJSScope::Ptr scope = QQmlJSScope::create(); + UiScriptBinding *metaObjectRevisions = nullptr; for (UiObjectMemberList *it = ast->initializer->members; it; it = it->next) { UiObjectMember *member = it->member; auto *component = cast(member); @@ -225,7 +226,7 @@ void QQmlJSTypeDescriptionReader::readComponent(UiObjectDefinition *ast) } else if (name == QLatin1String("interfaces")) { readInterfaces(script, scope); } else if (name == QLatin1String("exportMetaObjectRevisions")) { - readMetaObjectRevisions(script, scope); + metaObjectRevisions = script; } else if (name == QLatin1String("attachedType")) { scope->setOwnAttachedTypeName(readStringBinding(script)); } else if (name == QLatin1String("valueType")) { @@ -273,6 +274,8 @@ void QQmlJSTypeDescriptionReader::readComponent(UiObjectDefinition *ast) return; } + if (metaObjectRevisions) + readMetaObjectRevisions(metaObjectRevisions, scope); m_objects->insert(scope->internalName(), scope); } @@ -296,7 +299,7 @@ void QQmlJSTypeDescriptionReader::readSignalOrMethod(UiObjectDefinition *ast, bo readParameter(component, &metaMethod); } else { addWarning(component->firstSourceLocation(), - tr("Expected only Parameter object definitions.")); + tr("Expected only Parameter in object definitions.")); } } else if (script) { QString name = toString(script->qualifiedId); @@ -308,9 +311,16 @@ void QQmlJSTypeDescriptionReader::readSignalOrMethod(UiObjectDefinition *ast, bo metaMethod.setRevision(readIntBinding(script)); } else if (name == QLatin1String("isConstructor")) { metaMethod.setIsConstructor(true); + } else if (name == QLatin1String("isList")) { + // TODO: Theoretically this can happen. QQmlJSMetaMethod should store it. + } else if (name == QLatin1String("isPointer")) { + // TODO: We don't need this information. We can probably drop all isPointer members + // once we make sure that the type information is always complete. The + // description of the type being referenced has access semantics after all. } else { addWarning(script->firstSourceLocation(), - tr("Expected only name type, revision and isConstructor script bindings.")); + tr("Expected only name, type, revision, isPointer, isList, and " + "isConstructor in script bindings.")); } } else { addWarning(member->firstSourceLocation(), @@ -637,7 +647,7 @@ void QQmlJSTypeDescriptionReader::readExports(UiScriptBinding *ast, const QQmlJS QString name = exp.mid(slashIdx + 1, spaceIdx - (slashIdx+1)); // ### relocatable exports where package is empty? - scope->addExport(name, package, version); + scope->addExport(name, package, version, version); } } @@ -664,8 +674,8 @@ void QQmlJSTypeDescriptionReader::readInterfaces(UiScriptBinding *ast, const QQm scope->setInterfaceNames(list); } -void QQmlJSTypeDescriptionReader::readMetaObjectRevisions(UiScriptBinding *ast, - const QQmlJSScope::Ptr &scope) +void QQmlJSTypeDescriptionReader::readMetaObjectRevisions( + UiScriptBinding *ast, const QQmlJSScope::Ptr &scope) { Q_ASSERT(ast); @@ -688,7 +698,8 @@ void QQmlJSTypeDescriptionReader::readMetaObjectRevisions(UiScriptBinding *ast, } int exportIndex = 0; - const int exportCount = scope->exports().size(); + QList exports = scope->exports(); + const int exportCount = exports.size(); for (PatternElementList *it = arrayLit->elements; it; it = it->next, ++exportIndex) { auto *numberLit = cast(it->element->initializer); if (!numberLit) { @@ -712,16 +723,20 @@ void QQmlJSTypeDescriptionReader::readMetaObjectRevisions(UiScriptBinding *ast, const QTypeRevision metaObjectVersion = QTypeRevision::fromEncodedVersion(metaObjectRevision); - const QTypeRevision exportVersion = scope->exports()[exportIndex].version(); + const QQmlJSScope::Export &entry = exports.at(exportIndex); + const QTypeRevision exportVersion = entry.version(); if (metaObjectVersion != exportVersion) { addWarning(numberLit->firstSourceLocation(), - tr("Meta object revision and export version differ, ignoring the revision.\n" + tr("Meta object revision and export version differ.\n" "Revision %1 corresponds to version %2.%3; it should be %4.%5.") .arg(metaObjectRevision) .arg(metaObjectVersion.majorVersion()).arg(metaObjectVersion.minorVersion()) .arg(exportVersion.majorVersion()).arg(exportVersion.minorVersion())); + exports[exportIndex] = QQmlJSScope::Export( + entry.package(), entry.type(), exportVersion, metaObjectVersion); } } + scope->setExports(exports); } void QQmlJSTypeDescriptionReader::readEnumValues(UiScriptBinding *ast, QQmlJSMetaEnum *metaEnum) diff --git a/src/qmlcompiler/qqmljstypereader.cpp b/src/qmlcompiler/qqmljstypereader.cpp index cd9d6040445..d7e6999bcd7 100644 --- a/src/qmlcompiler/qqmljstypereader.cpp +++ b/src/qmlcompiler/qqmljstypereader.cpp @@ -40,13 +40,13 @@ QT_BEGIN_NAMESPACE -QQmlJSScope::Ptr QQmlJSTypeReader::operator()() +bool QQmlJSTypeReader::operator ()(const QSharedPointer &scope) { using namespace QQmlJS::AST; const QFileInfo info { m_file }; - QString baseName = info.baseName(); - const QString scopeName = baseName.endsWith(QStringLiteral(".ui")) ? baseName.chopped(3) - : baseName; + const QString baseName = info.baseName(); + scope->setInternalName(baseName.endsWith(QStringLiteral(".ui")) ? baseName.chopped(3) + : baseName); QQmlJS::Engine engine; QQmlJS::Lexer lexer(&engine); @@ -55,16 +55,10 @@ QQmlJSScope::Ptr QQmlJSTypeReader::operator()() const bool isESModule = lowerSuffix == QLatin1String("mjs"); const bool isJavaScript = isESModule || lowerSuffix == QLatin1String("js"); - auto errorResult = [&](){ - QQmlJSScope::Ptr result = QQmlJSScope::create( - isJavaScript ? QQmlJSScope::JSLexicalScope : QQmlJSScope::QMLScope); - result->setInternalName(scopeName); - return result; - }; QFile file(m_file); if (!file.open(QFile::ReadOnly)) - return errorResult(); + return false; QString code = QString::fromUtf8(file.readAll()); file.close(); @@ -76,21 +70,19 @@ QQmlJSScope::Ptr QQmlJSTypeReader::operator()() : parser.parseProgram()) : parser.parse(); if (!success) - return errorResult(); + return false; QQmlJS::AST::Node *rootNode = parser.rootNode(); if (!rootNode) - return errorResult(); + return false; QQmlJSImportVisitor membersVisitor( - m_importer, + scope, m_importer, QQmlJSImportVisitor::implicitImportDirectory( m_file, m_importer->resourceFileMapper()), m_qmltypesFiles, m_file, code); rootNode->accept(&membersVisitor); - auto result = membersVisitor.result(); - result->setInternalName(scopeName); - return result; + return true; } QT_END_NAMESPACE diff --git a/src/qmlcompiler/qqmljstypereader_p.h b/src/qmlcompiler/qqmljstypereader_p.h index 08c4ff782b0..8094f0d9b1d 100644 --- a/src/qmlcompiler/qqmljstypereader_p.h +++ b/src/qmlcompiler/qqmljstypereader_p.h @@ -61,7 +61,7 @@ class QQmlJSTypeReader , m_qmltypesFiles(qmltypesFiles) {} - QQmlJSScope::Ptr operator()(); + bool operator()(const QSharedPointer &scope); QList errors() const { return m_errors; } private: diff --git a/src/qmldebug/CMakeLists.txt b/src/qmldebug/CMakeLists.txt index 1801a77793d..fe8f7febcef 100644 --- a/src/qmldebug/CMakeLists.txt +++ b/src/qmldebug/CMakeLists.txt @@ -1,10 +1,10 @@ # Generated from qmldebug.pro. ##################################################################### -## QmlDebug Module: +## QmlDebugPrivate Module: ##################################################################### -qt_internal_add_module(QmlDebug +qt_internal_add_module(QmlDebugPrivate STATIC INTERNAL_MODULE SOURCES @@ -26,7 +26,7 @@ qt_internal_add_module(QmlDebug qqmlprofilerclientdefinitions_p.h qqmlprofilerevent.cpp qqmlprofilerevent_p.h qqmlprofilereventlocation.cpp qqmlprofilereventlocation_p.h - qqmlprofilereventreceiver_p.h + qqmlprofilereventreceiver.cpp qqmlprofilereventreceiver_p.h qqmlprofilereventtype.cpp qqmlprofilereventtype_p.h qqmlprofilertypedevent.cpp qqmlprofilertypedevent_p.h qv4debugclient.cpp qv4debugclient_p.h diff --git a/src/qmldebug/qqmldebugclient.cpp b/src/qmldebug/qqmldebugclient.cpp index 03123cc6e0e..13785dd6db3 100644 --- a/src/qmldebug/qqmldebugclient.cpp +++ b/src/qmldebug/qqmldebugclient.cpp @@ -123,3 +123,5 @@ void QQmlDebugClient::messageReceived(const QByteArray &message) } QT_END_NAMESPACE + +#include "moc_qqmldebugclient_p.cpp" diff --git a/src/qmldebug/qqmldebugmessageclient.cpp b/src/qmldebug/qqmldebugmessageclient.cpp index 08924041949..ce7a3cb2bb7 100644 --- a/src/qmldebug/qqmldebugmessageclient.cpp +++ b/src/qmldebug/qqmldebugmessageclient.cpp @@ -88,3 +88,5 @@ void QQmlDebugMessageClient::messageReceived(const QByteArray &data) } QT_END_NAMESPACE + +#include "moc_qqmldebugmessageclient_p.cpp" diff --git a/src/qmldebug/qqmldebugtranslationclient.cpp b/src/qmldebug/qqmldebugtranslationclient.cpp index a93184b95de..c0656ea8e35 100644 --- a/src/qmldebug/qqmldebugtranslationclient.cpp +++ b/src/qmldebug/qqmldebugtranslationclient.cpp @@ -59,7 +59,7 @@ void QQmlDebugTranslationClient::messageReceived(const QByteArray &message) packet >> type; switch (type) { - case QQmlDebugTranslation::Reply::MissingTranslations: { + case QQmlDebugTranslation::Reply::TranslationIssues: { packet >> translationIssues; break; } @@ -83,3 +83,5 @@ void QQmlDebugTranslationClient::messageReceived(const QByteArray &message) } QT_END_NAMESPACE + +#include "moc_qqmldebugtranslationclient_p.cpp" diff --git a/src/qmldebug/qqmlenginedebugclient.cpp b/src/qmldebug/qqmlenginedebugclient.cpp index 0ca3f573d9e..fd467337d8e 100644 --- a/src/qmldebug/qqmlenginedebugclient.cpp +++ b/src/qmldebug/qqmlenginedebugclient.cpp @@ -566,3 +566,5 @@ qint32 QQmlEngineDebugClient::getId() } QT_END_NAMESPACE + +#include "moc_qqmlenginedebugclient_p.cpp" diff --git a/src/qmldebug/qqmlinspectorclient.cpp b/src/qmldebug/qqmlinspectorclient.cpp index 1de52bd0c19..a3f5c68f0dc 100644 --- a/src/qmldebug/qqmlinspectorclient.cpp +++ b/src/qmldebug/qqmlinspectorclient.cpp @@ -148,3 +148,5 @@ void QQmlInspectorClient::messageReceived(const QByteArray &message) } QT_END_NAMESPACE + +#include "moc_qqmlinspectorclient_p.cpp" diff --git a/src/qmldebug/qqmlpreviewclient.cpp b/src/qmldebug/qqmlpreviewclient.cpp index abda548d014..da12cca5223 100644 --- a/src/qmldebug/qqmlpreviewclient.cpp +++ b/src/qmldebug/qqmlpreviewclient.cpp @@ -130,3 +130,5 @@ void QQmlPreviewClient::triggerZoom(float factor) } QT_END_NAMESPACE + +#include "moc_qqmlpreviewclient_p.cpp" diff --git a/src/qmldebug/qqmlprofilereventreceiver.cpp b/src/qmldebug/qqmlprofilereventreceiver.cpp new file mode 100644 index 00000000000..cb88f821f89 --- /dev/null +++ b/src/qmldebug/qqmlprofilereventreceiver.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 "qqmlprofilereventreceiver_p.h" + +QT_BEGIN_NAMESPACE + +QQmlProfilerEventReceiver::~QQmlProfilerEventReceiver() + = default; + +QT_END_NAMESPACE + +#include "moc_qqmlprofilereventreceiver_p.cpp" diff --git a/src/qmldebug/qqmlprofilereventreceiver_p.h b/src/qmldebug/qqmlprofilereventreceiver_p.h index defe64a42e5..45d9abf71df 100644 --- a/src/qmldebug/qqmlprofilereventreceiver_p.h +++ b/src/qmldebug/qqmlprofilereventreceiver_p.h @@ -62,7 +62,8 @@ class QQmlProfilerEventReceiver : public QObject { Q_OBJECT public: - QQmlProfilerEventReceiver(QObject *parent = nullptr) : QObject(parent) {} + explicit QQmlProfilerEventReceiver(QObject *parent = nullptr) : QObject(parent) {} + ~QQmlProfilerEventReceiver() override; virtual int numLoadedEventTypes() const = 0; virtual void addEventType(const QQmlProfilerEventType &type) = 0; diff --git a/src/qmldebug/qv4debugclient.cpp b/src/qmldebug/qv4debugclient.cpp index 76c2f1ebea1..127e4a405e9 100644 --- a/src/qmldebug/qv4debugclient.cpp +++ b/src/qmldebug/qv4debugclient.cpp @@ -576,3 +576,5 @@ QByteArray QV4DebugClientPrivate::packMessage(const QByteArray &type, const QJso } QT_END_NAMESPACE + +#include "moc_qv4debugclient_p.cpp" diff --git a/src/qmldevtools/CMakeLists.txt b/src/qmldevtools/CMakeLists.txt index 8b6c7917359..aaec48a33c0 100644 --- a/src/qmldevtools/CMakeLists.txt +++ b/src/qmldevtools/CMakeLists.txt @@ -1,10 +1,10 @@ # Generated from qmldevtools.pro. ##################################################################### -## QmlDevTools Module: +## QmlDevToolsPrivate Module: ##################################################################### -qt_internal_add_module(QmlDevTools +qt_internal_add_module(QmlDevToolsPrivate STATIC INTERNAL_MODULE NO_SYNC_QT @@ -51,10 +51,10 @@ qt_internal_add_module(QmlDevTools # special case begin # Need to generate the parser files as in Qml module. set(_qt_qlalr_flags "--no-debug" "--qt") -qt_process_qlalr(QmlDevTools "${CMAKE_CURRENT_SOURCE_DIR}/../qml/parser/qqmljs.g" "${_qt_qlalr_flags}") +qt_process_qlalr(QmlDevToolsPrivate "${CMAKE_CURRENT_SOURCE_DIR}/../qml/parser/qqmljs.g" "${_qt_qlalr_flags}") # Need to propagate some of the include directories from Qml via QmlDevToolsPrivate -# for other tools, and also for the main QmlDevTools module, +# for other tools, and also for the main QmlDevToolsPrivate module, # until we fix the script to handle internal_module to create only one single Private module. qt_internal_module_info(qml_module "Qml") if(QT_FEATURE_framework) @@ -67,13 +67,13 @@ if(QT_FEATURE_framework) ) else() set(_qml_dev_tools_private_includes - $ - $ - $ - $ + $ + $ + $ + $ ) endif() -target_include_directories(QmlDevTools PUBLIC ${_qml_dev_tools_private_includes}) +target_include_directories(QmlDevToolsPrivate PUBLIC ${_qml_dev_tools_private_includes}) if(QT_FEATURE_framework) set(_qml_fw_headers_dir lib/${qml_module}.framework/Headers) set(_qml_dev_tools_public_includes @@ -83,21 +83,25 @@ if(QT_FEATURE_framework) ) else() set(_qml_dev_tools_public_includes - $ - $ - $ + $ + $ + $ ) endif() -target_include_directories(QmlDevTools PUBLIC ${_qml_dev_tools_public_includes}) +target_include_directories(QmlDevToolsPrivate PUBLIC ${_qml_dev_tools_public_includes}) +set_target_properties(QmlDevToolsPrivate + PROPERTIES EXTRA_INCLUDE_DIRECTORIES + "${_qml_dev_tools_public_includes}${_qml_dev_tools_private_includes}" +) # We build the qlalr sources into qmldevtools, so there's no link-time -# dependency to QtQml. However we also include files in QmlDevTools such +# dependency to QtQml. However we also include files in QmlDevToolsPrivate such # as qqmlirbuilder.cpp that include that # originate from QtQml. That particular header was created at cmake time # via syncqt, but it's just a forwarding header that in turn includes # the generated file. That generated file is created when building # QtQml, so we must depend on it: -add_dependencies(QmlDevTools Qml) +add_dependencies(QmlDevToolsPrivate Qml) # special case end #### Keys ignored in scope 1:.:.:qmldevtools.pro:: @@ -129,7 +133,7 @@ add_dependencies(QmlDevTools Qml) # QML_COMPILE_HASH = "$$commit" # commit = "$$system(git rev-parse HEAD)" -qt_internal_extend_target(QmlDevTools CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STREQUAL 5 +qt_internal_extend_target(QmlDevToolsPrivate CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STREQUAL 5 COMPILE_OPTIONS -fno-strict-aliasing ) diff --git a/src/qmldom/CMakeLists.txt b/src/qmldom/CMakeLists.txt index d8f244c7a7c..2387ffe5c71 100644 --- a/src/qmldom/CMakeLists.txt +++ b/src/qmldom/CMakeLists.txt @@ -1,10 +1,10 @@ # Generated from qmldom.pro. ##################################################################### -## QmlDom Module: +## QmlDomPrivate Module: ##################################################################### -qt_internal_add_module(QmlDom +qt_internal_add_module(QmlDomPrivate STATIC INTERNAL_MODULE # NO_SYNC_QT # special case remove, it's actually needed for tests diff --git a/src/qmldom/qqmldomastcreator.cpp b/src/qmldom/qqmldomastcreator.cpp index 98d38024ede..43e422ac47c 100644 --- a/src/qmldom/qqmldomastcreator.cpp +++ b/src/qmldom/qqmldomastcreator.cpp @@ -663,7 +663,7 @@ class QmlDomAstCreator final : public AST::Visitor if (bPtr->name() == u"id") qmlFile.addError(myParseErrors() .error(tr("id attributes should only be a lower case letter " - "followed by letters numbers or underscore")) + "followed by letters, numbers or underscore")) .withPath(bPathFromOwner)); pushEl(bPathFromOwner, *bPtr, el); FileLocations::addRegion(nodeStack.last().fileLocations, u"colon", el->colonToken); @@ -727,7 +727,7 @@ class QmlDomAstCreator final : public AST::Visitor qmlFile.addError( myParseErrors() .error(tr("id attributes should only be a lower case letter " - "followed by letters numbers or underscore, not %1") + "followed by letters, numbers or underscore, not %1") .arg(iExp->name)) .withPath(pathFromOwner)); } @@ -738,7 +738,7 @@ class QmlDomAstCreator final : public AST::Visitor qmlFile.addError( myParseErrors() .error(tr("id attributes should only be a lower case letter " - "followed by letters numbers or underscore, not %1 %2") + "followed by letters, numbers or underscore, not %1 %2") .arg(script->code(), script->astRelocatableDump())) .withPath(pathFromOwner) .handle()); diff --git a/src/qmldom/qqmldomattachedinfo.cpp b/src/qmldom/qqmldomattachedinfo.cpp index 707aae4283c..eb48640d908 100644 --- a/src/qmldom/qqmldomattachedinfo.cpp +++ b/src/qmldom/qqmldomattachedinfo.cpp @@ -369,3 +369,5 @@ bool UpdatedScriptExpression::visitTree(Tree base, function_ref engine, AST::Node *n, } if (iPre == 0) preNewline = 1; - quint32 iPost = cLoc.end(); + qsizetype iPost = cLoc.end(); while (iPost < code.size()) { QChar c = code.at(iPost); if (!c.isSpace()) { diff --git a/src/qmldom/qqmldomelements.cpp b/src/qmldom/qqmldomelements.cpp index 7688c845d74..9a9a1868338 100644 --- a/src/qmldom/qqmldomelements.cpp +++ b/src/qmldom/qqmldomelements.cpp @@ -57,6 +57,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -322,7 +323,7 @@ Import Import::fromUriString(QString importStr, Version v, QString importId, Err v = Version::fromString(m.captured(2)); else if (!m.captured(u"version").isEmpty()) domParsingErrors() - .warning(tr("Version %1 in import string '%2' overridden by explicit " + .warning(tr("Version %1 in import string '%2' overridden by explicit " "version %3") .arg(m.captured(2), importStr, v.stringValue())) .handle(handler); @@ -330,14 +331,14 @@ Import Import::fromUriString(QString importStr, Version v, QString importId, Err importId = m.captured(u"importId"); else if (!m.captured(u"importId").isEmpty()) domParsingErrors() - .warning(tr("namespace %1 in import string '%2' overridden by explicit " + .warning(tr("namespace %1 in import string '%2' overridden by explicit " "importId %3") .arg(m.captured(u"importId"), importStr, importId)) .handle(handler); return Import(m.captured(u"uri").trimmed(), v, importId); } domParsingErrors() - .error(tr("Unexpected uri format in import '%1'").arg(importStr)) + .error(tr("Unexpected URI format in import '%1'").arg(importStr)) .handle(handler); return Import(); } @@ -356,7 +357,7 @@ Import Import::fromFileString(QString importStr, QString baseDir, QString import QString path = p.canonicalFilePath(); if (path.isEmpty()) { domParsingErrors() - .warning(tr("Non existing directory or file referred in uri of import '%1'") + .warning(tr("Non existing directory or file referred in URI of import '%1'") .arg(importStr)) .handle(handler); path = p.filePath(); @@ -653,9 +654,14 @@ MutableDomItem QmlObject::addMethod(MutableDomItem &self, MethodInfo functionDef void QmlObject::writeOut(DomItem &self, OutWriter &ow, QString onTarget) const { + const quint32 posOfNewElements = std::numeric_limits::max(); bool isRootObject = pathFromOwner().length() == 5 && pathFromOwner()[0] == Path::Field(Fields::components) && pathFromOwner()[3] == Path::Field(Fields::objects); + QString code; + DomItem owner = self.owner(); + if (std::shared_ptr qmlFilePtr = self.ownerAs()) + code = qmlFilePtr->code(); ow.writeRegion(u"name", name()); if (!onTarget.isEmpty()) ow.space().writeRegion(u"on", u"on").space().writeRegion(u"onTarget", onTarget).space(); @@ -678,10 +684,10 @@ void QmlObject::writeOut(DomItem &self, OutWriter &ow, QString onTarget) const DomItem component; if (isRootObject) component = self.containingObject(); - auto startLoc = [](FileLocations::Tree l) { + auto startLoc = [&](FileLocations::Tree l) { if (l) return l->info().fullRegion; - return SourceLocation(~quint32(0), 0, 0, 0); + return SourceLocation(posOfNewElements, 0, 0, 0); }; if (ow.lineWriter.options().attributesSequence == LineWriterOptions::AttributesSequence::Preserve) { @@ -749,10 +755,22 @@ void QmlObject::writeOut(DomItem &self, OutWriter &ow, QString onTarget) const qsizetype iAttr = 0; while (iAttr != attribs.size()) { auto &el = attribs[iAttr++]; - if (iAttr > 1 && el.second.internalKind() != attribs[iAttr - 2].second.internalKind()) - ow.ensureNewline(2); - else - ow.ensureNewline(); + // check for an empty line before the current element, and preserve it + int preNewlines = 0; + quint32 start = el.first.offset; + if (start != posOfNewElements && size_t(code.size()) >= start) { + while (start != 0) { + QChar c = code.at(--start); + if (c == u'\n') { + if (++preNewlines == 2) + break; + } else if (!c.isSpace()) + break; + } + } + if (preNewlines == 0) + ++preNewlines; + ow.ensureNewline(preNewlines); if (el.second.internalKind() == DomType::PropertyDefinition && iAttr != attribs.size() && el.first.offset != ~quint32(0)) { DomItem b; @@ -1197,9 +1215,10 @@ void EnumDecl::writeOut(DomItem &self, OutWriter &ow) const QList ImportScope::allSources(DomItem &self) const { - DomItem env = self.environment(); + DomItem top = self.top(); + DomItem env = top.environment(); Path selfPath = self.canonicalPath().field(Fields::allSources); - RefCacheEntry cached = RefCacheEntry::forPath(env, selfPath); + RefCacheEntry cached = (env ? RefCacheEntry::forPath(env, selfPath) : RefCacheEntry()); if (cached.cached == RefCacheEntry::Cached::All) return cached.canonicalPaths; QList res; @@ -1211,7 +1230,7 @@ QList ImportScope::allSources(DomItem &self) const continue; knownPaths.insert(pNow); res.append(pNow); - DomItem sourceBase = env.path(pNow); + DomItem sourceBase = top.path(pNow); for (DomItem autoExp : sourceBase.field(Fields::autoExports).values()) { if (const ModuleAutoExport *autoExpPtr = autoExp.as()) { Path newSource; @@ -1241,7 +1260,8 @@ QList ImportScope::allSources(DomItem &self) const } } } - RefCacheEntry::addForPath(env, selfPath, RefCacheEntry { RefCacheEntry::Cached::All, res }); + if (env) + RefCacheEntry::addForPath(env, selfPath, RefCacheEntry { RefCacheEntry::Cached::All, res }); return res; } @@ -1447,10 +1467,10 @@ class FirstNodeVisitor : public VisitAll { public: quint32 minStart = 0; - quint32 maxEnd = ~quint32(0); + quint32 maxEnd = std::numeric_limits::max(); AST::Node *firstNodeInRange = nullptr; - FirstNodeVisitor(quint32 minStart = 0, quint32 maxEnd = ~quint32(0)) + FirstNodeVisitor(quint32 minStart = 0, quint32 maxEnd = std::numeric_limits::max()) : minStart(minStart), maxEnd(maxEnd) { } @@ -1769,3 +1789,5 @@ void EnumItem::writeOut(DomItem &self, OutWriter &ow) const } // end namespace QQmlJS QT_END_NAMESPACE + +#include "moc_qqmldomelements_p.cpp" diff --git a/src/qmldom/qqmldomelements_p.h b/src/qmldom/qqmldomelements_p.h index 1cb3737b808..023883dfd67 100644 --- a/src/qmldom/qqmldomelements_p.h +++ b/src/qmldom/qqmldomelements_p.h @@ -726,7 +726,6 @@ class QMLDOM_EXPORT EnumDecl final : public CommentableDomElement : CommentableDomElement(pathFromOwner), m_name(name), m_values(values) { } - EnumDecl &operator=(const EnumDecl &) = default; bool iterateDirectSubpaths(DomItem &self, DirectVisitor visitor) override; @@ -766,7 +765,6 @@ class QMLDOM_EXPORT QmlObject final : public CommentableDomElement DomType kind() const override { return kindValue; } QmlObject(Path pathFromOwner = Path()); - QmlObject &operator=(const QmlObject &) = default; bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override; bool iterateBaseDirectSubpaths(DomItem &self, DirectVisitor); QList fields() const; @@ -1103,7 +1101,7 @@ class QMLDOM_EXPORT ImportScope res.append(*e); else self.addError(importErrors.warning( - tr("Expected Export looking up '%1', not %1").arg(name, i.toString()))); + tr("Expected Export looking up '%1', not %2").arg(name, i.toString()))); return res; } diff --git a/src/qmldom/qqmldomerrormessage.cpp b/src/qmldom/qqmldomerrormessage.cpp index e621ac775f7..450ae558b80 100644 --- a/src/qmldom/qqmldomerrormessage.cpp +++ b/src/qmldom/qqmldomerrormessage.cpp @@ -560,3 +560,5 @@ ErrorLevel errorLevelFromQtMsgType(QtMsgType msgType) } // end namespace QQmlJS QT_END_NAMESPACE + +#include "moc_qqmldomerrormessage_p.cpp" diff --git a/src/qmldom/qqmldomerrormessage_p.h b/src/qmldom/qqmldomerrormessage_p.h index fc3e0a2e119..3e7233125ec 100644 --- a/src/qmldom/qqmldomerrormessage_p.h +++ b/src/qmldom/qqmldomerrormessage_p.h @@ -160,6 +160,46 @@ class QMLDOM_EXPORT ErrorMessage { // reuse Some of the other DiagnosticMessages void dump(Sink s) const; QString toString() const; QCborMap toCbor() const; + friend int compare(const ErrorMessage &msg1, const ErrorMessage &msg2) + { + int c; + c = msg1.location.offset - msg2.location.offset; + if (c != 0) + return c; + c = msg1.location.startLine - msg2.location.startLine; + if (c != 0) + return c; + c = msg1.errorId.compare(msg2.errorId); + if (c != 0) + return c; + if (!msg1.errorId.isEmpty()) + return 0; + c = msg1.message.compare(msg2.message); + if (c != 0) + return c; + c = msg1.file.compare(msg2.file); + if (c != 0) + return c; + c = Path::cmp(msg1.path, msg2.path); + if (c != 0) + return c; + c = int(msg1.level) - int(msg2.level); + if (c != 0) + return c; + c = int(msg1.errorGroups.groups.size() - msg2.errorGroups.groups.size()); + if (c != 0) + return c; + for (qsizetype i = 0; i < msg1.errorGroups.groups.size(); ++i) { + c = msg1.errorGroups.groups[i].groupId().compare(msg2.errorGroups.groups[i].groupId()); + if (c != 0) + return c; + } + c = msg1.location.length - msg2.location.length; + if (c != 0) + return c; + c = msg1.location.startColumn - msg2.location.startColumn; + return c; + } QLatin1String errorId; QString message; @@ -171,13 +211,26 @@ class QMLDOM_EXPORT ErrorMessage { // reuse Some of the other DiagnosticMessages }; inline bool operator !=(const ErrorMessage &e1, const ErrorMessage &e2) { - return e1.errorId != e2.errorId || e1.message != e2.message || e1.errorGroups != e2.errorGroups - || e1.level != e2.level || e1.path != e2.path || e1.file != e2.file - || e1.location.startLine != e2.location.startLine || e1.location.offset != e2.location.offset - || e1.location.startColumn != e2.location.startColumn || e1.location.length != e2.location.length; + return compare(e1, e2) != 0; } inline bool operator ==(const ErrorMessage &e1, const ErrorMessage &e2) { - return !(e1 != e2); + return compare(e1, e2) == 0; +} +inline bool operator<(const ErrorMessage &e1, const ErrorMessage &e2) +{ + return compare(e1, e2) < 0; +} +inline bool operator<=(const ErrorMessage &e1, const ErrorMessage &e2) +{ + return compare(e1, e2) <= 0; +} +inline bool operator>(const ErrorMessage &e1, const ErrorMessage &e2) +{ + return compare(e1, e2) > 0; +} +inline bool operator>=(const ErrorMessage &e1, const ErrorMessage &e2) +{ + return compare(e1, e2) >= 0; } QMLDOM_EXPORT void silentError(const ErrorMessage &); diff --git a/src/qmldom/qqmldomfieldfilter.cpp b/src/qmldom/qqmldomfieldfilter.cpp index 3fa39b5b497..1ea27e0ee5a 100644 --- a/src/qmldom/qqmldomfieldfilter.cpp +++ b/src/qmldom/qqmldomfieldfilter.cpp @@ -237,3 +237,5 @@ void FieldFilter::setFiltred() } // end namespace QQmlJS QT_END_NAMESPACE + +#include "moc_qqmldomfieldfilter_p.cpp" diff --git a/src/qmldom/qqmldomfilewriter.cpp b/src/qmldom/qqmldomfilewriter.cpp index b24e5518ba7..b7b0e21d975 100644 --- a/src/qmldom/qqmldomfilewriter.cpp +++ b/src/qmldom/qqmldomfilewriter.cpp @@ -166,3 +166,5 @@ FileWriter::Status FileWriter::write(QString tFile, function_refcontains(refRef)) { myResolveErrors() .error([visitedRefs, refRef](Sink sink) { - sink(tr("Circular reference:\n")); + const QString msg = tr("Circular reference:") + QLatin1Char('\n'); + sink(QStringView{msg}); for (const Path &vPath : *visitedRefs) { sink(u" "); vPath.dump(sink); @@ -1926,14 +1927,23 @@ MutableDomItem DomItem::makeCopy(DomItem::CopyOption option) return MutableDomItem(newItem.path(pathFromOwner())); } DomItem env = environment(); - std::shared_ptr envPtr = env.ownerAs(); - Q_ASSERT(envPtr); - std::shared_ptr newEnvPtr( - new DomEnvironment(envPtr, envPtr->loadPaths(), envPtr->options())); - DomBase *eBase = envPtr.get(); - if (std::holds_alternative(m_element) && eBase - && std::get(m_element) == eBase) - return MutableDomItem(DomItem(newEnvPtr)); + std::shared_ptr newEnvPtr; + if (std::shared_ptr envPtr = env.ownerAs()) { + newEnvPtr = std::shared_ptr( + new DomEnvironment(envPtr, envPtr->loadPaths(), envPtr->options())); + DomBase *eBase = envPtr.get(); + if (std::holds_alternative(m_element) && eBase + && std::get(m_element) == eBase) + return MutableDomItem(DomItem(newEnvPtr)); + } else if (std::shared_ptr univPtr = top().ownerAs()) { + newEnvPtr = std::shared_ptr(new DomEnvironment( + QStringList(), + DomEnvironment::Option::SingleThreaded | DomEnvironment::Option::NoDependencies, + univPtr)); + } else { + Q_ASSERT(false); + return {}; + } DomItem newItem = std::visit( [this, newEnvPtr, &o](auto &&el) { auto copyPtr = el->makeCopy(o); @@ -2278,21 +2288,23 @@ DomItem::DomItem(std::shared_ptr universePtr): } void DomItem::loadFile(QString canonicalFilePath, QString logicalPath, QString code, - QDateTime codeDate, DomTop::Callback callback, LoadOptions loadOptions) + QDateTime codeDate, DomTop::Callback callback, LoadOptions loadOptions, + std::optional fileType) { DomItem topEl = top(); if (topEl.internalKind() == DomType::DomEnvironment || topEl.internalKind() == DomType::DomUniverse) { if (auto univ = topEl.ownerAs()) univ->loadFile(*this, canonicalFilePath, logicalPath, code, codeDate, callback, - loadOptions); + loadOptions, fileType); else if (auto env = topEl.ownerAs()) { if (env->options() & DomEnvironment::Option::NoDependencies) env->loadFile(topEl, canonicalFilePath, logicalPath, code, codeDate, callback, - DomTop::Callback(), DomTop::Callback(), loadOptions); + DomTop::Callback(), DomTop::Callback(), loadOptions, fileType); else env->loadFile(topEl, canonicalFilePath, logicalPath, code, codeDate, - DomTop::Callback(), DomTop::Callback(), callback, loadOptions); + DomTop::Callback(), DomTop::Callback(), callback, loadOptions, + fileType); } else Q_ASSERT(false && "expected either DomUniverse or DomEnvironment cast to succeed"); } else { @@ -2302,7 +2314,7 @@ void DomItem::loadFile(QString canonicalFilePath, QString logicalPath, QString c } void DomItem::loadFile(QString filePath, QString logicalPath, DomTop::Callback callback, - LoadOptions loadOptions) + LoadOptions loadOptions, std::optional fileType) { DomItem topEl = top(); if (topEl.internalKind() == DomType::DomEnvironment @@ -2312,10 +2324,10 @@ void DomItem::loadFile(QString filePath, QString logicalPath, DomTop::Callback c else if (auto env = topEl.ownerAs()) { if (env->options() & DomEnvironment::Option::NoDependencies) env->loadFile(topEl, filePath, logicalPath, callback, DomTop::Callback(), - DomTop::Callback(), loadOptions); + DomTop::Callback(), loadOptions, fileType); else env->loadFile(topEl, filePath, logicalPath, DomTop::Callback(), DomTop::Callback(), - callback, loadOptions); + callback, loadOptions, fileType); } else Q_ASSERT(false && "expected either DomUniverse or DomEnvironment cast to succeed"); } else { @@ -2726,26 +2738,28 @@ DomItem Reference::get(DomItem &self, ErrorHandler h, QList *visitedRefs) Path cachedPath; if (shouldCache()) { env = self.environment(); - selfPath = self.canonicalPath(); - RefCacheEntry cached = RefCacheEntry::forPath(self, selfPath); - switch (cached.cached) { - case RefCacheEntry::Cached::None: - break; - case RefCacheEntry::Cached::First: - case RefCacheEntry::Cached::All: - if (!cached.canonicalPaths.isEmpty()) - cachedPath = cached.canonicalPaths.first(); - else - return res; - break; - } - if (cachedPath) { - res = env.path(cachedPath); - if (!res) - qCWarning(refLog) << "referenceCache outdated, reference at " << selfPath - << " leads to invalid path " << cachedPath; - else - return res; + if (env) { + selfPath = self.canonicalPath(); + RefCacheEntry cached = RefCacheEntry::forPath(self, selfPath); + switch (cached.cached) { + case RefCacheEntry::Cached::None: + break; + case RefCacheEntry::Cached::First: + case RefCacheEntry::Cached::All: + if (!cached.canonicalPaths.isEmpty()) + cachedPath = cached.canonicalPaths.first(); + else + return res; + break; + } + if (cachedPath) { + res = env.path(cachedPath); + if (!res) + qCWarning(refLog) << "referenceCache outdated, reference at " << selfPath + << " leads to invalid path " << cachedPath; + else + return res; + } } } QList visitedRefsLocal; @@ -2971,12 +2985,10 @@ void OwningItem::addError(DomItem &, ErrorMessage msg) void OwningItem::addErrorLocal(ErrorMessage msg) { QMutexLocker l(mutex()); - auto it = m_errors.constFind(msg.path); - while (it != m_errors.constEnd() && it->path == msg.path) { - if (*it++ == msg) - return; - } - m_errors.insert(msg.path, msg); + quint32 &c = m_errorsCounts[msg]; + c += 1; + if (c == 1) + m_errors.insert(msg.path, msg); } void OwningItem::clearErrors(ErrorGroups groups) @@ -3368,3 +3380,5 @@ void ListPBase::writeOut(DomItem &self, OutWriter &ow, bool compact) const } // end namespace QQmlJS QT_END_NAMESPACE + +#include "moc_qqmldomitem_p.cpp" diff --git a/src/qmldom/qqmldomitem_p.h b/src/qmldom/qqmldomitem_p.h index 469001709ca..9388309bf76 100644 --- a/src/qmldom/qqmldomitem_p.h +++ b/src/qmldom/qqmldomitem_p.h @@ -588,7 +588,9 @@ class QMLDOM_EXPORT SimpleObjectWrapT final : public SimpleObjectWrapBase } else if constexpr (domTypeIsObjWrap(T::kindValue)) { return m_value.value(); } else { - Q_ASSERT_X(false, "SimpleObjectWrapT", "wrapping of unexpected type"); + // need dependent static assert to not unconditially trigger + static_assert(!std::is_same_v, "wrapping of unexpected type"); + return nullptr; // necessary to avoid warnings on INTEGRITY } } @@ -1036,11 +1038,11 @@ class QMLDOM_EXPORT DomItem { DomItem(std::shared_ptr); void loadFile(QString filePath, QString logicalPath, - std::function callback, - LoadOptions loadOptions); + std::function callback, LoadOptions loadOptions, + std::optional fileType = std::optional()); void loadFile(QString canonicalFilePath, QString logicalPath, QString code, QDateTime codeDate, - std::function callback, - LoadOptions loadOptions); + std::function callback, LoadOptions loadOptions, + std::optional fileType = std::optional()); void loadModuleDependency(QString uri, Version v, std::function callback = nullptr, ErrorHandler = nullptr); @@ -1342,6 +1344,7 @@ class QMLDOM_EXPORT OwningItem: public DomBase { QDateTime m_lastDataUpdateAt; QDateTime m_frozenAt; QMultiMap m_errors; + QMap m_errorsCounts; }; template diff --git a/src/qmldom/qqmldomlinewriter.cpp b/src/qmldom/qqmldomlinewriter.cpp index a2371c4ccd0..6c04602a55a 100644 --- a/src/qmldom/qqmldomlinewriter.cpp +++ b/src/qmldom/qqmldomlinewriter.cpp @@ -480,3 +480,5 @@ void LineWriter::commitLine(QString eol, TextAddType tType, int untilChar) } // namespace Dom } // namespace QQmlJS QT_END_NAMESPACE + +#include "moc_qqmldomlinewriter_p.cpp" diff --git a/src/qmldom/qqmldommoduleindex.cpp b/src/qmldom/qqmldommoduleindex.cpp index 700537d2877..47a2d9192fa 100644 --- a/src/qmldom/qqmldommoduleindex.cpp +++ b/src/qmldom/qqmldommoduleindex.cpp @@ -145,7 +145,7 @@ ModuleIndex::~ModuleIndex() auto it = scopes.begin(); auto end = scopes.end(); while (it != end) { - free(*it); + delete *it; ++it; } } diff --git a/src/qmldom/qqmldompath.cpp b/src/qmldom/qqmldompath.cpp index 21bcf4c8b8c..d901813f3a6 100644 --- a/src/qmldom/qqmldompath.cpp +++ b/src/qmldom/qqmldompath.cpp @@ -205,24 +205,25 @@ int PathComponent::cmp(const PathComponent &p1, const PathComponent &p2) } // namespace PathEls -PathEls::PathComponent Path::component(int i) const +const PathEls::PathComponent &Path::component(int i) const { + static Component emptyComponent; if (i < 0) i += m_length; if (i >= m_length || i < 0) { Q_ASSERT(false && "index out of bounds"); - return Component(); + return emptyComponent; } i = i - m_length - m_endOffset; auto data = m_data.get(); while (data) { i += data->components.length(); if (i >= 0) - return data->components.at(i); + return qAsConst(data)->components[i]; data = data->parent.get(); } Q_ASSERT(false && "Invalid data reached while resolving a seemengly valid index in Path (inconsisten Path object)"); - return Component(); + return emptyComponent; } Path Path::operator[](int i) const @@ -247,7 +248,7 @@ PathIterator Path::end() const PathRoot Path::headRoot() const { - auto comp = component(0); + auto &comp = component(0); if (PathEls::Root const * r = comp.base()->asRoot()) return r->contextKind; return PathRoot::Other; @@ -285,7 +286,7 @@ index_type Path::headIndex(index_type defaultValue) const function Path::headFilter() const { - auto comp = component(0); + auto &comp = component(0); if (PathEls::Filter const * f = comp.base()->asFilter()) { return f->filterFunction; } @@ -500,7 +501,7 @@ Path Path::fromString(QStringView s, ErrorHandler errorHandler) .arg(QString::number(i0))).handle(errorHandler); return Path(); } else { - myErrors().info(tr("Index shound use square brackets and not a dot (at char %1).") + myErrors().info(tr("Index should use square brackets and not a dot (at char %1).") .arg(QString::number(i0))).handle(errorHandler); } state = PathEls::ParserState::End; @@ -939,7 +940,7 @@ void Path::dump(Sink sink) const { bool first = true; for (int i = 0; i < m_length; ++i) { - auto c = component(i); + auto &c = component(i); if (!c.hasSquareBrackets()) { if (!first || (c.kind() != Kind::Root && c.kind() != Kind::Current)) sink(u"."); @@ -997,3 +998,5 @@ Path Path::fromString(QString s, ErrorHandler errorHandler) } // end namespace Dom } // end namespace QQmlJS QT_END_NAMESPACE + +#include "moc_qqmldompath_p.cpp" diff --git a/src/qmldom/qqmldompath_p.h b/src/qmldom/qqmldompath_p.h index 7fe68428d79..f0fddcabea8 100644 --- a/src/qmldom/qqmldompath_p.h +++ b/src/qmldom/qqmldompath_p.h @@ -124,7 +124,8 @@ class Base { virtual const Filter *asFilter() const { return nullptr; } }; -class Empty: public Base { +class Empty final : public Base +{ public: Empty() = default; Kind kind() const override { return Kind::Empty; } @@ -133,7 +134,8 @@ class Empty: public Base { const Empty * asEmpty() const override { return this; } }; -class Field: public Base { +class Field final : public Base +{ public: Field() = default; Field(QStringView n): fieldName(n) {} @@ -147,7 +149,8 @@ class Field: public Base { QStringView fieldName; }; -class Index: public Base { +class Index final : public Base +{ public: Index() = default; Index(index_type i): indexValue(i) {} @@ -161,7 +164,8 @@ class Index: public Base { index_type indexValue = -1; }; -class Key: public Base { +class Key final : public Base +{ public: Key() = default; Key(QString n) : keyValue(n) { } @@ -180,7 +184,8 @@ class Key: public Base { QString keyValue; }; -class Root: public Base { +class Root final : public Base +{ public: Root() = default; Root(PathRoot r): contextKind(r), contextName() {} @@ -229,7 +234,8 @@ class Root: public Base { QStringView contextName; }; -class Current: public Base { +class Current final : public Base +{ public: Current() = default; Current(PathCurrent c): contextKind(c) {} @@ -283,7 +289,8 @@ class Current: public Base { QStringView contextName; }; -class Any: public Base { +class Any final : public Base +{ public: Any() = default; Kind kind() const override { return Kind::Any; } @@ -293,7 +300,8 @@ class Any: public Base { const Any *asAny() const override { return this; } }; -class QMLDOM_EXPORT Filter: public Base { +class QMLDOM_EXPORT Filter final : public Base +{ public: Filter() = default; Filter(std::function f, QStringView filterDescription = u""); @@ -718,10 +726,12 @@ class QMLDOM_EXPORT Path{ using iterator_category = std::forward_iterator_tag; static int cmp(const Path &p1, const Path &p2); - Component component(int i) const; + private: + const Component &component(int i) const; explicit Path(quint16 endOffset, quint16 length, std::shared_ptr data); friend class QQmlJS::Dom::PathEls::TestPaths; + friend class FieldFilter; friend size_t qHash(const Path &, size_t); Path noEndOffset() const; @@ -762,8 +772,8 @@ class PathIterator { Path operator *() const { return currentEl.head(); } PathIterator operator ++() { currentEl = currentEl.dropFront(); return *this; } PathIterator operator ++(int) { PathIterator res{currentEl}; currentEl = currentEl.dropFront(); return res; } - bool operator ==(const PathIterator &o) { return currentEl == o.currentEl; } - bool operator !=(const PathIterator &o) { return currentEl != o.currentEl; } + bool operator ==(const PathIterator &o) const { return currentEl == o.currentEl; } + bool operator !=(const PathIterator &o) const { return currentEl != o.currentEl; } }; class Source { diff --git a/src/qmldom/qqmldomreformatter.cpp b/src/qmldom/qqmldomreformatter.cpp index d627af12ef6..a2bbb25581d 100644 --- a/src/qmldom/qqmldomreformatter.cpp +++ b/src/qmldom/qqmldomreformatter.cpp @@ -585,16 +585,27 @@ class Rewriter : protected BaseVisitor return false; } + + void outputScope(VariableScope scope) { + switch (scope) { + case VariableScope::Const: + out("const "); + break; + case VariableScope::Let: + out("let "); + break; + case VariableScope::Var: + out("var "); + break; + default: + break; + } + } + bool visit(PatternElement *ast) override { if (ast->isForDeclaration) { - if (ast->scope == VariableScope::Var) { - out("var "); - } else if (ast->scope == VariableScope::Let) { - out("let "); - } else if (ast->scope == VariableScope::Const) { - out("const "); - } + outputScope(ast->scope); } accept(ast->bindingTarget); switch (ast->type) { @@ -678,7 +689,7 @@ class Rewriter : protected BaseVisitor if (ast->initialiser) { accept(ast->initialiser); } else if (ast->declarations) { - out("var "); + outputScope(ast->declarations->declaration->scope); accept(ast->declarations); } out("; "); // ast->firstSemicolonToken @@ -867,12 +878,15 @@ class Rewriter : protected BaseVisitor out(ast->identifierToken); } out(ast->lparenToken); - if (ast->isArrowFunction && ast->formals && ast->formals->next) + const bool needParentheses = ast->formals && + (ast->formals->next || + (ast->formals->element && ast->formals->element->bindingTarget)); + if (ast->isArrowFunction && needParentheses) out("("); int baseIndent = lw.increaseIndent(1); accept(ast->formals); lw.decreaseIndent(1, baseIndent); - if (ast->isArrowFunction && ast->formals && ast->formals->next) + if (ast->isArrowFunction && needParentheses) out(")"); out(ast->rparenToken); if (ast->isArrowFunction && !ast->formals) @@ -963,7 +977,11 @@ class Rewriter : protected BaseVisitor bool visit(FormalParameterList *ast) override { for (FormalParameterList *it = ast; it; it = it->next) { - out(it->element->bindingIdentifier.toString()); // TODO + // compare FormalParameterList::finish + if (auto id = it->element->bindingIdentifier.toString(); !id.startsWith(u"arg#")) + out(id); + if (it->element->bindingTarget) + accept(it->element->bindingTarget); if (it->next) out(", "); } @@ -972,7 +990,11 @@ class Rewriter : protected BaseVisitor // to check bool visit(TypeExpression *) override { return true; } - bool visit(SuperLiteral *) override { return true; } + bool visit(SuperLiteral *) override + { + out("super"); + return true; + } bool visit(PatternProperty *) override { return true; } bool visit(ComputedPropertyName *) override { @@ -989,7 +1011,61 @@ class Rewriter : protected BaseVisitor } bool visit(YieldExpression *) override { return true; } bool visit(ClassExpression *) override { return true; } - bool visit(ClassDeclaration *) override { return true; } + + // Return false because we want to omit default function calls in accept0 implementation. + bool visit(ClassDeclaration *ast) override + { + preVisit(ast); + out(ast->classToken); + out(" "); + out(ast->name); + if (ast->heritage) { + out(" extends "); + accept(ast->heritage); + } + out(" {"); + int baseIndent = lw.increaseIndent(); + for (ClassElementList *it = ast->elements; it; it = it->next) { + PatternProperty *property = it->property; + lw.newline(); + preVisit(property); + if (it->isStatic) + out("static "); + if (property->type == PatternProperty::Getter) + out("get "); + else if (property->type == PatternProperty::Setter) + out("set "); + FunctionExpression *f = AST::cast(property->initializer); + const bool scoped = f->lbraceToken.length != 0; + out(f->functionToken); + out(f->lparenToken); + accept(f->formals); + out(f->rparenToken); + out(f->lbraceToken); + if (scoped) + ++expressionDepth; + if (f->body) { + if (f->body->next || scoped) { + lnAcceptIndented(f->body); + lw.newline(); + } else { + baseIndent = lw.increaseIndent(1); + accept(f->body); + lw.decreaseIndent(1, baseIndent); + } + } + if (scoped) + --expressionDepth; + out(f->rbraceToken); + lw.newline(); + postVisit(property); + } + lw.decreaseIndent(1, baseIndent); + out("}"); + postVisit(ast); + return false; + } + bool visit(ClassElementList *) override { return true; } bool visit(Program *) override { return true; } bool visit(NameSpaceImport *) override { return true; } diff --git a/src/qmldom/qqmldomtop.cpp b/src/qmldom/qqmldomtop.cpp index b1f410e1022..7d2500488b7 100644 --- a/src/qmldom/qqmldomtop.cpp +++ b/src/qmldom/qqmldomtop.cpp @@ -48,7 +48,6 @@ #include #include -#include #include #include #include @@ -157,11 +156,14 @@ DomUniverse::DomUniverse(QString universeName, Options options): std::shared_ptr DomUniverse::guaranteeUniverse(std::shared_ptr univ) { - static QAtomicInt counter(0); + const auto next = [] { + static std::atomic counter(0); + return counter.fetch_add(1, std::memory_order_relaxed) + 1; + }; if (univ) return univ; return std::shared_ptr( - new DomUniverse(QLatin1String("universe") + QString::number(++counter))); + new DomUniverse(QLatin1String("universe") + QString::number(next()))); } DomItem DomUniverse::create(QString universeName, Options options) @@ -248,56 +250,58 @@ std::shared_ptr DomUniverse::doCopy(DomItem &) const } void DomUniverse::loadFile(DomItem &self, QString filePath, QString logicalPath, Callback callback, - LoadOptions loadOptions) + LoadOptions loadOptions, std::optional fileType) { - loadFile(self, filePath, logicalPath, QString(), QDateTime::fromMSecsSinceEpoch(0), callback, loadOptions); + loadFile(self, filePath, logicalPath, QString(), QDateTime::fromMSecsSinceEpoch(0), callback, + loadOptions, fileType); } -void DomUniverse::loadFile(DomItem &self, QString canonicalFilePath, QString logicalPath, - QString code, QDateTime codeDate, Callback callback, - LoadOptions loadOptions) -{ - if (canonicalFilePath.endsWith(u".qml", Qt::CaseInsensitive) || - canonicalFilePath.endsWith(u".qmlannotation", Qt::CaseInsensitive) || - canonicalFilePath.endsWith(u".ui", Qt::CaseInsensitive)) { - m_queue.enqueue(ParsingTask{ - QDateTime::currentDateTime(), - loadOptions, - DomType::QmlFile, - canonicalFilePath, - logicalPath, - code, - codeDate, - self.ownerAs(), - callback}); +static DomType fileTypeForPath(DomItem &self, QString canonicalFilePath) +{ + if (canonicalFilePath.endsWith(u".qml", Qt::CaseInsensitive) + || canonicalFilePath.endsWith(u".qmlannotation", Qt::CaseInsensitive)) { + return DomType::QmlFile; } else if (canonicalFilePath.endsWith(u".qmltypes")) { - m_queue.enqueue(ParsingTask{ - QDateTime::currentDateTime(), - loadOptions, - DomType::QmltypesFile, - canonicalFilePath, - logicalPath, - code, - codeDate, - self.ownerAs(), - callback}); - } else if (QStringView(u"qmldir").compare(QFileInfo(canonicalFilePath).fileName(), Qt::CaseInsensitive) == 0) { - m_queue.enqueue(ParsingTask{ - QDateTime::currentDateTime(), - loadOptions, - DomType::QmldirFile, - canonicalFilePath, - logicalPath, - code, - codeDate, - self.ownerAs(), - callback}); + return DomType::QmltypesFile; + } else if (QStringView(u"qmldir").compare(QFileInfo(canonicalFilePath).fileName(), + Qt::CaseInsensitive) + == 0) { + return DomType::QmltypesFile; } else if (QFileInfo(canonicalFilePath).isDir()) { - m_queue.enqueue(ParsingTask { QDateTime::currentDateTime(), loadOptions, - DomType::QmlDirectory, canonicalFilePath, logicalPath, code, - codeDate, self.ownerAs(), callback }); + return DomType::QmlDirectory; } else { - self.addError(myErrors().error(tr("Ignoring request to load file of unknown type %1, calling callback immediately").arg(canonicalFilePath)).handle()); + self.addError(DomUniverse::myErrors() + .error(QCoreApplication::translate("Dom::filteTypeForPath", + "Could not detect type of file %1") + .arg(canonicalFilePath)) + .handle()); + } + return DomType::Empty; +} + +void DomUniverse::loadFile(DomItem &self, QString canonicalFilePath, QString logicalPath, + QString code, QDateTime codeDate, Callback callback, + LoadOptions loadOptions, std::optional fileType) +{ + DomType fType = (bool(fileType) ? (*fileType) : fileTypeForPath(self, canonicalFilePath)); + switch (fType) { + case DomType::QmlFile: + case DomType::QmltypesFile: + case DomType::QmldirFile: + case DomType::QmlDirectory: { + // Protect the queue from concurrent access. + QMutexLocker l(mutex()); + m_queue.enqueue(ParsingTask { QDateTime::currentDateTime(), loadOptions, fType, + canonicalFilePath, logicalPath, code, codeDate, + self.ownerAs(), callback }); + break; + } + default: + self.addError(myErrors() + .error(tr("Ignoring request to load file %1 of unexpected type %2, " + "calling callback immediately") + .arg(canonicalFilePath, domTypeToString(fType))) + .handle()); Q_ASSERT(false && "loading non supported file type"); callback(Path(), DomItem::empty, DomItem::empty); return; @@ -350,7 +354,14 @@ updateEntry(DomItem &univ, std::shared_ptr newItem, void DomUniverse::execQueue() { - ParsingTask t = m_queue.dequeue(); + ParsingTask t; + { + // Protect the queue from concurrent access. + QMutexLocker l(mutex()); + if (m_queue.isEmpty()) + return; + t = m_queue.dequeue(); + } shared_ptr topPtr = t.requestingUniverse.lock(); if (!topPtr) { myErrors().error(tr("Ignoring callback for loading of %1: universe is not valid anymore").arg(t.canonicalPath)).handle(); @@ -626,7 +637,8 @@ void LoadInfo::advanceLoad(DomItem &self) [this, self, dep](Path, DomItem &, DomItem &) mutable { finishedLoadingDep(self, dep); }, - nullptr, nullptr, LoadOption::DefaultLoad, self.errorHandler()); + nullptr, nullptr, LoadOption::DefaultLoad, dep.fileType, + self.errorHandler()); else Q_ASSERT(false && "missing environment"); } else { @@ -746,12 +758,13 @@ void LoadInfo::doAddDependencies(DomItem &self) DomItem import = currentImports.index(i); if (const Import *importPtr = import.as()) { if (!importPtr->filePath().isEmpty()) { - addDependency( - self, - Dependency { QString(), importPtr->version, importPtr->filePath() }); + addDependency(self, + Dependency { QString(), importPtr->version, importPtr->filePath(), + DomType::Empty }); } else { addDependency(self, - Dependency { importPtr->uri, importPtr->version, QString() }); + Dependency { importPtr->uri, importPtr->version, QString(), + DomType::ModuleIndex }); } } } @@ -763,7 +776,8 @@ void LoadInfo::doAddDependencies(DomItem &self) Path canonicalPath = ref->referredObjectPath[2]; if (canonicalPath && !canonicalPath.headName().isEmpty()) addDependency(self, - Dependency { QString(), Version(), canonicalPath.headName() }); + Dependency { QString(), Version(), canonicalPath.headName(), + DomType::QmltypesFile }); } } DomItem currentQmlFiles = el.field(Fields::currentItem).field(Fields::qmlFiles); @@ -772,9 +786,9 @@ void LoadInfo::doAddDependencies(DomItem &self) if (const Reference *ref = el.as()) { Path canonicalPath = ref->referredObjectPath[2]; if (canonicalPath && !canonicalPath.headName().isEmpty()) - addDependency( - self, - Dependency { QString(), Version(), canonicalPath.headName() }); + addDependency(self, + Dependency { QString(), Version(), canonicalPath.headName(), + DomType::QmlFile }); } return true; }); @@ -783,7 +797,9 @@ void LoadInfo::doAddDependencies(DomItem &self) for (Path qmldirPath : elPtr->qmldirsToLoad(el)) { Path canonicalPath = qmldirPath[2]; if (canonicalPath && !canonicalPath.headName().isEmpty()) - addDependency(self, Dependency { QString(), Version(), canonicalPath.headName() }); + addDependency(self, + Dependency { QString(), Version(), canonicalPath.headName(), + DomType::QmldirFile }); } } else if (!el) { self.addError(DomEnvironment::myErrors().error( @@ -1147,10 +1163,11 @@ std::shared_ptr DomEnvironment::makeCopy(DomItem &self) const void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPath, DomTop::Callback loadCallback, DomTop::Callback directDepsCallback, - DomTop::Callback endCallback, LoadOptions loadOptions, ErrorHandler h) + DomTop::Callback endCallback, LoadOptions loadOptions, + std::optional fileType, ErrorHandler h) { loadFile(self, filePath, logicalPath, QString(), QDateTime::fromMSecsSinceEpoch(0), - loadCallback, directDepsCallback, endCallback, loadOptions, h); + loadCallback, directDepsCallback, endCallback, loadOptions, fileType, h); } std::shared_ptr DomEnvironment::doCopy(DomItem &) const @@ -1167,11 +1184,10 @@ std::shared_ptr DomEnvironment::doCopy(DomItem &) const void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPath, QString code, QDateTime codeDate, Callback loadCallback, Callback directDepsCallback, Callback endCallback, - LoadOptions loadOptions, ErrorHandler h) + LoadOptions loadOptions, std::optional fileType, + ErrorHandler h) { QFileInfo fileInfo(filePath); - bool isDir = fileInfo.isDir(); - QString ext = fileInfo.suffix(); QString canonicalFilePath = fileInfo.canonicalFilePath(); if (canonicalFilePath.isEmpty()) { if (code.isNull()) { @@ -1190,7 +1206,9 @@ void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPa } } shared_ptr oldValue, newValue; - if (isDir) { + DomType fType = (bool(fileType) ? (*fileType) : fileTypeForPath(self, canonicalFilePath)); + switch (fType) { + case DomType::QmlDirectory: { { QMutexLocker l(mutex()); auto it = m_qmlDirectoryWithPath.find(canonicalFilePath); @@ -1217,10 +1235,11 @@ void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPa self.universe().loadFile( canonicalFilePath, logicalPath, code, codeDate, callbackForQmlDirectory(self, loadCallback, directDepsCallback, endCallback), - loadOptions); + loadOptions, fType); return; } - } else if (ext == u"qml" || ext == u"ui" || ext == u"qmlannotation") { + } break; + case DomType::QmlFile: { { QMutexLocker l(mutex()); auto it = m_qmlFileWithPath.find(canonicalFilePath); @@ -1246,10 +1265,11 @@ void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPa self.universe().loadFile( canonicalFilePath, logicalPath, code, codeDate, callbackForQmlFile(self, loadCallback, directDepsCallback, endCallback), - loadOptions); + loadOptions, fType); return; } - } else if (ext == u"qmltypes") { + } break; + case DomType::QmltypesFile: { { QMutexLocker l(mutex()); auto it = m_qmltypesFileWithPath.find(canonicalFilePath); @@ -1276,10 +1296,11 @@ void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPa self.universe().loadFile( canonicalFilePath, logicalPath, code, codeDate, callbackForQmltypesFile(self, loadCallback, directDepsCallback, endCallback), - loadOptions); + loadOptions, fType); return; } - } else if (fileInfo.fileName() == u"qmldir") { + } break; + case DomType::QmldirFile: { { QMutexLocker l(mutex()); auto it = m_qmldirFileWithPath.find(canonicalFilePath); @@ -1305,10 +1326,11 @@ void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPa self.universe().loadFile( canonicalFilePath, logicalPath, code, codeDate, callbackForQmldirFile(self, loadCallback, directDepsCallback, endCallback), - loadOptions); + loadOptions, fType); return; } - } else { + } break; + default: { myErrors().error(tr("Unexpected file to load: '%1'").arg(filePath)).handle(h); if (loadCallback) loadCallback(self.canonicalPath(), DomItem::empty, DomItem::empty); @@ -1317,6 +1339,7 @@ void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPa if (endCallback) endCallback(self.canonicalPath(), DomItem::empty, DomItem::empty); return; + } break; } Path p = self.copy(newValue).canonicalPath(); std::shared_ptr lInfo = loadInfo(p); @@ -1518,7 +1541,7 @@ std::shared_ptr DomEnvironment::moduleIndexWithUri(DomItem &self, Q "Version::Latest)"); std::shared_ptr res; if (changeable == Changeable::Writable && (m_options & Option::Exported)) - myErrors().error(tr("asked mutable module in Multithreaded env")).handle(errorHandler); + myErrors().error(tr("A mutable module was requested in a multithreaded environment")).handle(errorHandler); if (options != EnvLookup::BaseOnly) { QMutexLocker l(mutex()); auto it = m_moduleIndexWithUri.find(uri); @@ -1831,7 +1854,7 @@ void DomEnvironment::addLoadInfo(DomItem &self, std::shared_ptr loadIn } if (oldVal && oldVal->status() != LoadInfo::Status::Done) { self.addError(myErrors() - .error(tr("addLoadinfo replaces a non finished load info for %1") + .error(tr("addLoadinfo replaces unfinished load info for %1") .arg(p.toString())) .handle()); } @@ -2310,3 +2333,5 @@ bool RefCacheEntry::addForPath(DomItem &el, Path canonicalPath, const RefCacheEn } // end namespace QQmlJS QT_END_NAMESPACE + +#include "moc_qqmldomtop_p.cpp" diff --git a/src/qmldom/qqmldomtop_p.h b/src/qmldom/qqmldomtop_p.h index 4c905991af9..eeb0038d09e 100644 --- a/src/qmldom/qqmldomtop_p.h +++ b/src/qmldom/qqmldomtop_p.h @@ -61,6 +61,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -253,9 +254,11 @@ class QMLDOM_EXPORT DomUniverse final : public DomTop } void loadFile(DomItem &self, QString filePath, QString logicalPath, Callback callback, - LoadOptions loadOptions); + LoadOptions loadOptions, + std::optional fileType = std::optional()); void loadFile(DomItem &self, QString canonicalFilePath, QString logicalPath, QString code, - QDateTime codeDate, Callback callback, LoadOptions loadOptions); + QDateTime codeDate, Callback callback, LoadOptions loadOptions, + std::optional fileType = std::optional()); void execQueue(); std::shared_ptr> globalScopeWithName(QString name) const @@ -517,6 +520,7 @@ class Dependency QString uri; // either dotted uri or file:, http: https: uri Version version; QString filePath; // for file deps + DomType fileType; }; class QMLDOM_EXPORT LoadInfo final : public OwningItem @@ -683,10 +687,13 @@ class QMLDOM_EXPORT DomEnvironment final : public DomTop void loadFile(DomItem &self, QString filePath, QString logicalPath, Callback loadCallback, Callback directDepsCallback, Callback endCallback, LoadOptions loadOptions, + std::optional fileType = std::optional(), ErrorHandler h = nullptr); void loadFile(DomItem &self, QString canonicalFilePath, QString logicalPath, QString code, QDateTime codeDate, Callback loadCallback, Callback directDepsCallback, - Callback endCallback, LoadOptions loadOptions, ErrorHandler h = nullptr); + Callback endCallback, LoadOptions loadOptions, + std::optional fileType = std::optional(), + ErrorHandler h = nullptr); void loadModuleDependency(DomItem &self, QString uri, Version v, Callback loadCallback = nullptr, Callback endCallback = nullptr, ErrorHandler = nullptr); diff --git a/src/qmllocalstorage/qqmllocalstorage.cpp b/src/qmllocalstorage/qqmllocalstorage.cpp index 565ebc0a072..8295b441df2 100644 --- a/src/qmllocalstorage/qqmllocalstorage.cpp +++ b/src/qmllocalstorage/qqmllocalstorage.cpp @@ -526,7 +526,7 @@ through the data. */ /*! - \qmlmodule QtQuick.LocalStorage 2.\QtMinorVersion + \qmlmodule QtQuick.LocalStorage \title Qt Quick Local Storage QML Types \ingroup qmlmodules \brief Provides a JavaScript object singleton type for accessing a local @@ -584,10 +584,10 @@ db = Sql.openDatabaseSync(identifier, version, description, estimated_size, call \endqml The above code returns the database identified by \e identifier. If the database does not already -exist, it is created, and the function \e callback is called with the database as a parameter. \e -identifier is the name of the physical file (with or without full path) containing the database. \e -description and \e estimated_size are written to the INI file (described below), but are currently -unused. +exist, it is created, and the function \e callback is called with the database as a parameter. +\e identifier is the name of the physical file (with or without relative path) containing the +database. \e description and \e estimated_size are written to the INI file (described below), but +are currently unused. May throw exception with code property SQLException.DATABASE_ERR, or SQLException.VERSION_ERR. @@ -636,7 +636,7 @@ If the callback throws exceptions, the transaction is rolled back. Below you will find an example of a database transaction which catches exceptions. -\quotefromfile localstorage/localstorage/Database.js +\quotefromfile localstorage/Database.js \skipuntil dbInit() \printto dbGetHandle @@ -692,7 +692,7 @@ SQLException.UNKNOWN_ERR. See below for an example: -\quotefromfile localstorage/localstorage/Database.js +\quotefromfile localstorage/Database.js \skipto dbReadAll() \printto dbUpdate(Pdate @@ -794,3 +794,5 @@ void QQmlLocalStorage::openDatabaseSync(QQmlV4Function *args) } QT_END_NAMESPACE + +#include "moc_qqmllocalstorage_p.cpp" diff --git a/src/qmllocalstorage/qqmllocalstorageglobal_p.h b/src/qmllocalstorage/qqmllocalstorageglobal_p.h index 5eb13cce68f..fb921518f4e 100644 --- a/src/qmllocalstorage/qqmllocalstorageglobal_p.h +++ b/src/qmllocalstorage/qqmllocalstorageglobal_p.h @@ -70,6 +70,4 @@ QT_BEGIN_NAMESPACE QT_END_NAMESPACE -void Q_QMLLOCALSTORAGE_PRIVATE_EXPORT qml_register_types_QtQuick_LocalStorage(); - #endif // QQMLLOCALSTORAGEGLOBAL_P_H diff --git a/src/qmlmodels/CMakeLists.txt b/src/qmlmodels/CMakeLists.txt index 3166e5d90c1..41a14753658 100644 --- a/src/qmlmodels/CMakeLists.txt +++ b/src/qmlmodels/CMakeLists.txt @@ -27,6 +27,11 @@ qt_internal_add_qml_module(QmlModels Qt::QmlPrivate ) +qt_internal_extend_target(QmlModels CONDITION QT_FEATURE_qml_itemmodel + SOURCES + qqmlmodelindexvaluetype.cpp qqmlmodelindexvaluetype_p.h +) + qt_internal_extend_target(QmlModels CONDITION QT_FEATURE_qml_object_model SOURCES qqmlinstantiator.cpp qqmlinstantiator_p.h diff --git a/src/qmlmodels/configure.json b/src/qmlmodels/configure.json deleted file mode 100644 index 1ccca5e35ee..00000000000 --- a/src/qmlmodels/configure.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "module": "qmlmodels", - "depends": [ - "core-private", - "qml-private" - ], - - "features": { - "qml-object-model" : { - "label": "QML object model", - "purpose": "Provides the ObjectModel and Instantiator QML types.", - "section": "QML", - "output": [ "privateFeature" ] - }, - "qml-list-model": { - "label": "QML list model", - "purpose": "Provides the ListModel QML type.", - "section": "QML", - "condition": "features.qml-itemmodel", - "output": [ "privateFeature" ] - }, - "qml-delegate-model": { - "label": "QML delegate model", - "purpose": "Provides the DelegateModel QML type.", - "section": "QML", - "condition": "features.qml-object-model && features.qml-itemmodel", - "output": [ "privateFeature" ] - }, - "qml-table-model": { - "label": "QML table model", - "purpose": "Provides the TableModel QML type.", - "section": "QML", - "condition": "features.qml-itemmodel && features.qml-delegate-model", - "output": [ "privateFeature" ] - } - }, - "summary": [ - { - "section": "Qt QML Models", - "entries": [ - "qml-list-model", - "qml-delegate-model" - ] - } - ] -} diff --git a/src/qmlmodels/doc/src/qtqmlmodel.qdoc b/src/qmlmodels/doc/src/qtqmlmodel.qdoc index 33c648e87fe..ea46bf7da98 100644 --- a/src/qmlmodels/doc/src/qtqmlmodel.qdoc +++ b/src/qmlmodels/doc/src/qtqmlmodel.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \qmlmodule QtQml.Models 2.\QtMinorVersion + \qmlmodule QtQml.Models \title Qt QML Models QML Types \ingroup qmlmodules \brief Provides QML types for data models diff --git a/src/qmlmodels/qqmlabstractdelegatecomponent.cpp b/src/qmlmodels/qqmlabstractdelegatecomponent.cpp index 1058d87485e..869c6a4fa92 100644 --- a/src/qmlmodels/qqmlabstractdelegatecomponent.cpp +++ b/src/qmlmodels/qqmlabstractdelegatecomponent.cpp @@ -59,3 +59,5 @@ QVariant QQmlAbstractDelegateComponent::value(QQmlAdaptorModel *adaptorModel, in } QT_END_NAMESPACE + +#include "moc_qqmlabstractdelegatecomponent_p.cpp" diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp index dc3ea8019e2..f2832710189 100644 --- a/src/qmlmodels/qqmladaptormodel.cpp +++ b/src/qmlmodels/qqmladaptormodel.cpp @@ -549,7 +549,8 @@ class VDMAbstractItemModelDataType : public VDMModelDelegateDataType metaObject.reset(builder.toMetaObject()); *static_cast(this) = *metaObject; - propertyCache.adopt(new QQmlPropertyCache(metaObject.data(), model.modelItemRevision)); + propertyCache = QQmlPropertyCache::createStandalone( + metaObject.data(), model.modelItemRevision); } }; @@ -683,8 +684,8 @@ class VDMListDelegateDataType : public QQmlRefCount, public QQmlAdaptorModel::Ac { VDMListDelegateDataType *dataType = const_cast(this); if (!propertyCache) { - dataType->propertyCache.adopt(new QQmlPropertyCache( - &QQmlDMListAccessorData::staticMetaObject, model.modelItemRevision)); + dataType->propertyCache = QQmlPropertyCache::createStandalone( + &QQmlDMListAccessorData::staticMetaObject, model.modelItemRevision); } return new QQmlDMListAccessorData( @@ -962,30 +963,38 @@ QQmlAdaptorModel::~QQmlAdaptorModel() accessors->cleanup(*this); } -void QQmlAdaptorModel::setModel(const QVariant &variant, QObject *parent) +void QQmlAdaptorModel::setModel(const QVariant &variant, QObject *) { accessors->cleanup(*this); + // Don't use variant anymore after this. list may transform it. list.setList(variant); + modelStrongReference.clear(); + if (QObject *object = qvariant_cast(list.list())) { - setObject(object, parent); + if (QQmlData *ddata = QQmlData::get(object)) + modelStrongReference = ddata->jsWrapper; + setObject(object); if (qobject_cast(object)) accessors = new VDMAbstractItemModelDataType(this); else accessors = new VDMObjectDelegateDataType; } else if (list.type() == QQmlListAccessor::ListProperty) { - setObject(static_cast(variant.constData())->object(), parent); + auto object = static_cast(list.list().constData())->object(); + if (QQmlData *ddata = QQmlData::get(object)) + modelStrongReference = ddata->jsWrapper; + setObject(object); accessors = new VDMObjectDelegateDataType; } else if (list.type() == QQmlListAccessor::ObjectList) { - setObject(nullptr, parent); + setObject(nullptr); accessors = new VDMObjectDelegateDataType; } else if (list.type() != QQmlListAccessor::Invalid && list.type() != QQmlListAccessor::Instance) { // Null QObject - setObject(nullptr, parent); + setObject(nullptr); accessors = new VDMListDelegateDataType; } else { - setObject(nullptr, parent); + setObject(nullptr); accessors = &qt_vdm_null_accessors; } } diff --git a/src/qmlmodels/qqmladaptormodel_p.h b/src/qmlmodels/qqmladaptormodel_p.h index 531e8d91054..8635762bc44 100644 --- a/src/qmlmodels/qqmladaptormodel_p.h +++ b/src/qmlmodels/qqmladaptormodel_p.h @@ -70,7 +70,7 @@ class QQmlDelegateModel; class QQmlDelegateModelItem; class QQmlDelegateModelItemMetaType; -class Q_QMLMODELS_PRIVATE_EXPORT QQmlAdaptorModel : public QQmlStrongJSQObjectReference +class Q_QMLMODELS_PRIVATE_EXPORT QQmlAdaptorModel : public QQmlGuard { public: class Accessors @@ -114,6 +114,10 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlAdaptorModel : public QQmlStrongJSQObjectRe const Accessors *accessors; QPersistentModelIndex rootIndex; QQmlListAccessor list; + // we need to ensure that a JS created model does not get gced, but cannot + // arbitrarily set the parent (using QQmlStrongJSQObjectReference) of QObject based models, + // as that causes issues with singletons + QV4::PersistentValue modelStrongReference; QTypeRevision modelItemRevision = QTypeRevision::zero(); @@ -121,7 +125,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlAdaptorModel : public QQmlStrongJSQObjectRe ~QQmlAdaptorModel(); inline QVariant model() const { return list.list(); } - void setModel(const QVariant &variant, QObject *parent); + void setModel(const QVariant &variant, QObject *parent = nullptr); void invalidateModel(); bool isValid() const; diff --git a/src/qmlmodels/qqmlchangeset.cpp b/src/qmlmodels/qqmlchangeset.cpp index ba876b42e28..99def9567c8 100644 --- a/src/qmlmodels/qqmlchangeset.cpp +++ b/src/qmlmodels/qqmlchangeset.cpp @@ -557,16 +557,17 @@ void QQmlChangeSet::change(QVector *changes) QDebug operator <<(QDebug debug, const QQmlChangeSet &set) { + QDebugStateSaver stateSaver(debug); debug.nospace() << "QQmlChangeSet("; const QVector &removes = set.removes(); for (const QQmlChangeSet::Change &remove : removes) - debug << remove; + debug << remove << ' '; const QVector &inserts = set.inserts(); for (const QQmlChangeSet::Change &insert : inserts) - debug << insert; + debug << insert << ' '; const QVector &changes = set.changes(); for (const QQmlChangeSet::Change &change : changes) - debug << change; + debug << change << ' '; return debug.nospace() << ')'; } @@ -576,7 +577,8 @@ QDebug operator <<(QDebug debug, const QQmlChangeSet &set) QDebug operator <<(QDebug debug, const QQmlChangeSet::Change &change) { - return (debug.nospace() << "Change(" << change.index << ',' << change.count << ')').space(); + QDebugStateSaver stateSaver(debug); + return debug.nospace() << "Change(" << change.index << ',' << change.count << ')'; } QT_END_NAMESPACE diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp index cbefc5d535d..d3cf23b4903 100644 --- a/src/qmlmodels/qqmldelegatemodel.cpp +++ b/src/qmlmodels/qqmldelegatemodel.cpp @@ -259,7 +259,7 @@ QQmlDelegateModel::~QQmlDelegateModel() { Q_D(QQmlDelegateModel); d->disconnectFromAbstractItemModel(); - d->m_adaptorModel.setObject(nullptr, this); + d->m_adaptorModel.setObject(nullptr); for (QQmlDelegateModelItem *cacheItem : qAsConst(d->m_cache)) { if (cacheItem->object) { @@ -389,12 +389,18 @@ void QQmlDelegateModelPrivate::connectToAbstractItemModel() q, QQmlDelegateModel, SLOT(_q_rowsRemoved(QModelIndex,int,int))); qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), q, QQmlDelegateModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); + qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsInserted(QModelIndex,int,int)), + q, QQmlDelegateModel, SLOT(_q_columnsInserted(QModelIndex,int,int))); + qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsRemoved(QModelIndex,int,int)), + q, QQmlDelegateModel, SLOT(_q_columnsRemoved(QModelIndex,int,int))); + qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), + q, QQmlDelegateModel, SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int))); qmlobject_connect(aim, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector)), q, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector))); qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), q, QQmlDelegateModel, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int))); - qmlobject_connect(aim, QAbstractItemModel, SIGNAL(modelReset()), - q, QQmlDelegateModel, SLOT(_q_modelReset())); + + QObject::connect(aim, &QAbstractItemModel::modelAboutToBeReset, q, &QQmlDelegateModel::_q_modelAboutToBeReset); qmlobject_connect(aim, QAbstractItemModel, SIGNAL(layoutChanged(QList,QAbstractItemModel::LayoutChangeHint)), q, QQmlDelegateModel, SLOT(_q_layoutChanged(QList,QAbstractItemModel::LayoutChangeHint))); } @@ -413,12 +419,17 @@ void QQmlDelegateModelPrivate::disconnectFromAbstractItemModel() q, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)), q, SLOT(_q_rowsRemoved(QModelIndex,int,int))); + QObject::disconnect(aim, SIGNAL(columnsInserted(QModelIndex,int,int)), q, + SLOT(_q_columnsInserted(QModelIndex,int,int))); + QObject::disconnect(aim, SIGNAL(columnsRemoved(QModelIndex,int,int)), q, + SLOT(_q_columnsRemoved(QModelIndex,int,int))); + QObject::disconnect(aim, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), q, + SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int))); QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector)), q, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector))); QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), q, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int))); - QObject::disconnect(aim, SIGNAL(modelReset()), - q, SLOT(_q_modelReset())); + QObject::disconnect(aim, &QAbstractItemModel::modelAboutToBeReset, q, &QQmlDelegateModel::_q_modelAboutToBeReset); QObject::disconnect(aim, SIGNAL(layoutChanged(QList,QAbstractItemModel::LayoutChangeHint)), q, SLOT(_q_layoutChanged(QList,QAbstractItemModel::LayoutChangeHint))); } @@ -431,7 +442,7 @@ void QQmlDelegateModel::setModel(const QVariant &model) _q_itemsRemoved(0, d->m_count); d->disconnectFromAbstractItemModel(); - d->m_adaptorModel.setModel(model, this); + d->m_adaptorModel.setModel(model); d->connectToAbstractItemModel(); d->m_adaptorModel.replaceWatchedRoles(QList(), d->m_watchedRoles); @@ -963,8 +974,19 @@ void QQDMIncubationTask::initializeRequiredProperties(QQmlDelegateModelItem *mod if (incubatorPriv->hadRequiredProperties()) { QQmlData *d = QQmlData::get(object); auto contextData = d ? d->context : nullptr; - if (contextData) + if (contextData) { contextData->setExtraObject(modelItemToIncubate); + } + + // If we have required properties, we clear the context object + // so that the model role names are not polluting the context + if (incubating) { + Q_ASSERT(incubating->contextData); + incubating->contextData->setContextObject(nullptr); + } + if (proxyContext) { + proxyContext->setContextObject(nullptr); + } if (incubatorPriv->requiredProperties().empty()) return; @@ -1237,6 +1259,9 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ addCacheItem(cacheItem, it); reuseItem(cacheItem, index, flags); cacheItem->referenceObject(); + + if (index == m_compositor.count(group) - 1) + requestMoreIfNecessary(); return cacheItem->object; } @@ -1277,6 +1302,7 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ QQmlRefPointer ctxt = QQmlContextData::createRefCounted( QQmlContextData::get(creationContext ? creationContext : m_context.data())); + ctxt->setContextObject(cacheItem); cacheItem->contextData = ctxt; if (m_adaptorModel.hasProxyObject()) { @@ -1286,6 +1312,7 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ QObject *proxied = proxy->proxiedObject(); cacheItem->incubationTask->proxiedObject = proxied; cacheItem->incubationTask->proxyContext = ctxt; + ctxt->setContextObject(cacheItem); // We don't own the proxied object. We need to clear it if it goes away. QObject::connect(proxied, &QObject::destroyed, cacheItem, &QQmlDelegateModelItem::childContextObjectDestroyed); @@ -1854,14 +1881,41 @@ void QQmlDelegateModelPrivate::emitChanges() for (int i = 1; i < m_groupCount; ++i) QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitModelUpdated(reset); - auto cacheCopy = m_cache; // deliberate; emitChanges may alter m_cache - for (QQmlDelegateModelItem *cacheItem : qAsConst(cacheCopy)) { - if (cacheItem->attached) - cacheItem->attached->emitChanges(); + // emitChanges may alter m_cache and delete items + QVarLengthArray> attachedObjects; + attachedObjects.reserve(m_cache.length()); + for (const QQmlDelegateModelItem *cacheItem : std::as_const(m_cache)) + attachedObjects.append(cacheItem->attached); + + for (const QPointer &attached : std::as_const(attachedObjects)) { + if (attached && attached->m_cacheItem) + attached->emitChanges(); } } -void QQmlDelegateModel::_q_modelReset() +void QQmlDelegateModel::_q_modelAboutToBeReset() +{ + auto aim = static_cast(sender()); + auto oldRoleNames = aim->roleNames(); + // this relies on the fact that modelAboutToBeReset must be followed + // by a modelReset signal before any further modelAboutToBeReset can occur + QObject::connect(aim, &QAbstractItemModel::modelReset, this, [&, oldRoleNames](){ + auto aim = static_cast(sender()); + if (oldRoleNames == aim->roleNames()) { + // if the rolenames stayed the same (most common case), then we don't have + // to throw away all the setup that we did + handleModelReset(); + } else { + // If they did change, we give up and just start from scratch via setMode + setModel(QVariant::fromValue(model())); + // but we still have to call handleModelReset, otherwise views will + // not refresh + handleModelReset(); + } + }, Qt::SingleShotConnection); +} + +void QQmlDelegateModel::handleModelReset() { Q_D(QQmlDelegateModel); if (!d->m_delegate) @@ -1957,6 +2011,38 @@ void QQmlDelegateModel::_q_rowsMoved( } } +void QQmlDelegateModel::_q_columnsInserted(const QModelIndex &parent, int begin, int end) +{ + Q_D(QQmlDelegateModel); + Q_UNUSED(end); + if (parent == d->m_adaptorModel.rootIndex && begin == 0) { + // mark all items as changed + _q_itemsChanged(0, d->m_count, QVector()); + } +} + +void QQmlDelegateModel::_q_columnsRemoved(const QModelIndex &parent, int begin, int end) +{ + Q_D(QQmlDelegateModel); + Q_UNUSED(end); + if (parent == d->m_adaptorModel.rootIndex && begin == 0) { + // mark all items as changed + _q_itemsChanged(0, d->m_count, QVector()); + } +} + +void QQmlDelegateModel::_q_columnsMoved(const QModelIndex &parent, int start, int end, + const QModelIndex &destination, int column) +{ + Q_D(QQmlDelegateModel); + Q_UNUSED(end); + if ((parent == d->m_adaptorModel.rootIndex && start == 0) + || (destination == d->m_adaptorModel.rootIndex && column == 0)) { + // mark all items as changed + _q_itemsChanged(0, d->m_count, QVector()); + } +} + void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector &roles) { Q_D(QQmlDelegateModel); @@ -1994,7 +2080,7 @@ void QQmlDelegateModel::_q_layoutChanged(const QList &par // Ignored } else { // We don't know what's going on, so reset the model - _q_modelReset(); + handleModelReset(); } } @@ -2041,8 +2127,8 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const // Must be before the new object is inserted into the cache or its indexes will be adjusted too. itemsInserted(QVector(1, Compositor::Insert(before, 1, cacheItem->groups & ~Compositor::CacheFlag))); - before = m_compositor.insert(before, nullptr, 0, 1, cacheItem->groups); m_cache.insert(before.cacheIndex, cacheItem); + m_compositor.insert(before, nullptr, 0, 1, cacheItem->groups); return true; } @@ -2647,20 +2733,24 @@ void QQmlDelegateModelAttached::emitChanges() m_previousGroups = m_cacheItem->groups; int indexChanges = 0; - for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) { + const int groupCount = m_cacheItem->metaType->groupCount; + for (int i = 1; i < groupCount; ++i) { if (m_previousIndex[i] != m_currentIndex[i]) { m_previousIndex[i] = m_currentIndex[i]; indexChanges |= (1 << i); } } + // Don't access m_cacheItem anymore once we've started sending signals. + // We don't own it and someone might delete it. + int notifierId = 0; const QMetaObject *meta = metaObject(); - for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) { + for (int i = 1; i < groupCount; ++i, ++notifierId) { if (groupChanges & (1 << i)) QMetaObject::activate(this, meta, notifierId, nullptr); } - for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) { + for (int i = 1; i < groupCount; ++i, ++notifierId) { if (indexChanges & (1 << i)) QMetaObject::activate(this, meta, notifierId, nullptr); } @@ -3909,4 +3999,6 @@ QV4::ReturnedValue QQmlDelegateModelEngineData::array(QV4::ExecutionEngine *v4, QT_END_NAMESPACE +#include "moc_qqmldelegatemodel_p_p.cpp" + #include "moc_qqmldelegatemodel_p.cpp" diff --git a/src/qmlmodels/qqmldelegatemodel_p.h b/src/qmlmodels/qqmldelegatemodel_p.h index f4578e130e9..1ad5c5145c4 100644 --- a/src/qmlmodels/qqmldelegatemodel_p.h +++ b/src/qmlmodels/qqmldelegatemodel_p.h @@ -150,8 +150,11 @@ private Q_SLOTS: void _q_itemsInserted(int index, int count); void _q_itemsRemoved(int index, int count); void _q_itemsMoved(int from, int to, int count); - void _q_modelReset(); + void _q_modelAboutToBeReset(); void _q_rowsInserted(const QModelIndex &,int,int); + void _q_columnsInserted(const QModelIndex &, int, int); + void _q_columnsRemoved(const QModelIndex &, int, int); + void _q_columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int); void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end); void _q_rowsRemoved(const QModelIndex &,int,int); void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int); @@ -159,6 +162,7 @@ private Q_SLOTS: void _q_layoutChanged(const QList&, QAbstractItemModel::LayoutChangeHint); private: + void handleModelReset(); bool isDescendantOf(const QPersistentModelIndex &desc, const QList &parents) const; Q_DISABLE_COPY(QQmlDelegateModel) diff --git a/src/qmlmodels/qqmlinstantiator.cpp b/src/qmlmodels/qqmlinstantiator.cpp index 3b663badf5f..cb7ca1126c9 100644 --- a/src/qmlmodels/qqmlinstantiator.cpp +++ b/src/qmlmodels/qqmlinstantiator.cpp @@ -147,7 +147,7 @@ void QQmlInstantiatorPrivate::_q_modelUpdated(const QQmlChangeSet &changeSet, bo { Q_Q(QQmlInstantiator); - if (!componentComplete || effectiveReset) + if (!componentComplete || effectiveReset || !active) return; if (reset) { diff --git a/src/qmlmodels/qqmllistaccessor.cpp b/src/qmlmodels/qqmllistaccessor.cpp index 230f190834b..381d5d34de2 100644 --- a/src/qmlmodels/qqmllistaccessor.cpp +++ b/src/qmlmodels/qqmllistaccessor.cpp @@ -75,6 +75,7 @@ void QQmlListAccessor::setList(const QVariant &v) d = d.value().toVariant(); variantsType = d.metaType(); } + if (!d.isValid()) { m_type = Invalid; } else if (variantsType == QMetaType::fromType()) { @@ -85,6 +86,9 @@ void QQmlListAccessor::setList(const QVariant &v) m_type = VariantList; } else if (variantsType == QMetaType::fromType>()) { m_type = ObjectList; + } else if (variantsType.flags() & QMetaType::IsQmlList) { + d = QVariant::fromValue(QQmlListReference(d)); + m_type = ListProperty; } else if (variantsType == QMetaType::fromType()) { m_type = ListProperty; } else if (variantsType.flags() & QMetaType::PointerToQObject) { diff --git a/src/qmlmodels/qqmllistcompositor_p.h b/src/qmlmodels/qqmllistcompositor_p.h index 7bf20397fd1..797a457e8c9 100644 --- a/src/qmlmodels/qqmllistcompositor_p.h +++ b/src/qmlmodels/qqmllistcompositor_p.h @@ -308,6 +308,10 @@ Q_DECLARE_TYPEINFO(QQmlListCompositor::Insert, Q_PRIMITIVE_TYPE); inline QQmlListCompositor::iterator::iterator() {} +QT_WARNING_PUSH +// GCC isn't wrong, as groupCount is public in iterator, but we tried Q_ASSUME(), +// right in front of the loops, and it didn't help, so we disable the warning: +QT_WARNING_DISABLE_GCC("-Warray-bounds") inline QQmlListCompositor::iterator::iterator( Range *range, int offset, Group group, int groupCount) : range(range) @@ -335,6 +339,7 @@ inline void QQmlListCompositor::iterator::decrementIndexes(int difference, uint index[i] -= difference; } } +QT_WARNING_POP // -Warray-bounds inline QQmlListCompositor::insert_iterator::insert_iterator( Range *range, int offset, Group group, int groupCount) diff --git a/src/qmlmodels/qqmllistmodel.cpp b/src/qmlmodels/qqmllistmodel.cpp index 583f12164a3..c060aaec977 100644 --- a/src/qmlmodels/qqmllistmodel.cpp +++ b/src/qmlmodels/qqmllistmodel.cpp @@ -129,8 +129,28 @@ const ListLayout::Role &ListLayout::getRoleOrCreate(QV4::String *key, Role::Data const ListLayout::Role &ListLayout::createRole(const QString &key, ListLayout::Role::DataType type) { - const int dataSizes[] = { sizeof(StringOrTranslation), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QPointer), sizeof(QVariantMap), sizeof(QDateTime), sizeof(QUrl), sizeof(QJSValue) }; - const int dataAlignments[] = { alignof(StringOrTranslation), alignof(double), alignof(bool), alignof(ListModel *), alignof(QObject *), alignof(QVariantMap), alignof(QDateTime), alignof(QUrl), alignof(QJSValue) }; + const int dataSizes[] = { + sizeof(StringOrTranslation), + sizeof(double), + sizeof(bool), + sizeof(ListModel *), + sizeof(QV4::PersistentValue), + sizeof(QVariantMap), + sizeof(QDateTime), + sizeof(QUrl), + sizeof(QJSValue) + }; + const int dataAlignments[] = { + alignof(StringOrTranslation), + alignof(double), + alignof(bool), + alignof(ListModel *), + alignof(QV4::PersistentValue), + alignof(QVariantMap), + alignof(QDateTime), + alignof(QUrl), + alignof(QJSValue) + }; Role *r = new Role; r->name = key; @@ -567,6 +587,17 @@ ListModel *ListModel::getListProperty(int elementIndex, const ListLayout::Role & return e->getListProperty(role); } +void ListModel::updateTranslations() +{ + for (int index = 0; index != elements.count(); ++index) { + ListElement *e = elements[index]; + if (ModelNodeMetaObject *cache = e->objectCache()) { + // TODO: more fine grained tracking? + cache->updateValues(); + } + } +} + void ListModel::set(int elementIndex, QV4::Object *object, QVector *roles) { ListElement *e = elements[elementIndex]; @@ -623,10 +654,9 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector *roles) roleIndex = e->setFunctionProperty(r, jsv); } else if (QV4::Object *o = propertyValue->as()) { if (QV4::QObjectWrapper *wrapper = o->as()) { - QObject *o = wrapper->object(); const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject); if (role.type == ListLayout::Role::QObject) - roleIndex = e->setQObjectProperty(role, o); + roleIndex = e->setQObjectProperty(role, wrapper); } else if (QVariant maybeUrl = o->engine()->toVariant(o->asReturnedValue(), QMetaType::fromType(), true); maybeUrl.metaType() == QMetaType::fromType()) { const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Url); @@ -714,23 +744,21 @@ void ListModel::set(int elementIndex, QV4::Object *object, ListModel::SetElement } } else if (QV4::Object *o = propertyValue->as()) { if (QV4::QObjectWrapper *wrapper = o->as()) { - QObject *o = wrapper->object(); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject); if (r.type == ListLayout::Role::QObject) - e->setQObjectPropertyFast(r, o); + e->setQObjectPropertyFast(r, wrapper); } else { QVariant maybeUrl = o->engine()->toVariant(o->asReturnedValue(), QMetaType::fromType(), true); if (maybeUrl.metaType() == QMetaType::fromType()) { const QUrl qurl = maybeUrl.toUrl(); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Url); - if (r.type == ListLayout::Role::Url) { + if (r.type == ListLayout::Role::Url) e->setUrlPropertyFast(r, qurl); - } - return; + } else { + const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::VariantMap); + if (role.type == ListLayout::Role::VariantMap) + e->setVariantMapFast(role, o); } - const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::VariantMap); - if (role.type == ListLayout::Role::VariantMap) - e->setVariantMapFast(role, o); } } else if (propertyValue->isNullOrUndefined()) { if (reason == SetElement::WasJustInserted) { @@ -842,11 +870,11 @@ StringOrTranslation *ListElement::getStringProperty(const ListLayout::Role &role return s; } -QObject *ListElement::getQObjectProperty(const ListLayout::Role &role) +QV4::QObjectWrapper *ListElement::getQObjectProperty(const ListLayout::Role &role) { char *mem = getPropertyMemory(role); - QPointer *o = reinterpret_cast *>(mem); - return o->data(); + QV4::PersistentValue *g = reinterpret_cast(mem); + return g->as(); } QVariantMap *ListElement::getVariantMapProperty(const ListLayout::Role &role) @@ -893,24 +921,26 @@ QJSValue *ListElement::getFunctionProperty(const ListLayout::Role &role) return f; } -QPointer *ListElement::getGuardProperty(const ListLayout::Role &role) +QV4::PersistentValue * +ListElement::getGuardProperty(const ListLayout::Role &role) { char *mem = getPropertyMemory(role); bool existingGuard = false; - for (size_t i=0 ; i < sizeof(QPointer) ; ++i) { + for (size_t i = 0; i < sizeof(QV4::PersistentValue); + ++i) { if (mem[i] != 0) { existingGuard = true; break; } } - QPointer *o = nullptr; + QV4::PersistentValue *g = nullptr; if (existingGuard) - o = reinterpret_cast *>(mem); + g = reinterpret_cast(mem); - return o; + return g; } ListModel *ListElement::getListProperty(const ListLayout::Role &role) @@ -938,6 +968,8 @@ QVariant ListElement::getProperty(const ListLayout::Role &role, const QQmlListMo StringOrTranslation *value = reinterpret_cast(mem); if (value->isSet()) data = value->toString(owner); + else + data = QString(); } break; case ListLayout::Role::Bool: @@ -964,10 +996,8 @@ QVariant ListElement::getProperty(const ListLayout::Role &role, const QQmlListMo break; case ListLayout::Role::QObject: { - QPointer *guard = reinterpret_cast *>(mem); - QObject *object = guard->data(); - if (object) - data = QVariant::fromValue(object); + QV4::PersistentValue *guard = reinterpret_cast(mem); + data = QVariant::fromValue(guard->as()->object()); } break; case ListLayout::Role::VariantMap: @@ -1079,30 +1109,17 @@ int ListElement::setListProperty(const ListLayout::Role &role, ListModel *m) return roleIndex; } -int ListElement::setQObjectProperty(const ListLayout::Role &role, QObject *o) +int ListElement::setQObjectProperty(const ListLayout::Role &role, QV4::QObjectWrapper *o) { int roleIndex = -1; if (role.type == ListLayout::Role::QObject) { char *mem = getPropertyMemory(role); - QPointer *g = reinterpret_cast *>(mem); - bool existingGuard = false; - for (size_t i=0 ; i < sizeof(QPointer) ; ++i) { - if (mem[i] != 0) { - existingGuard = true; - break; - } - } - bool changed; - if (existingGuard) { - changed = g->data() != o; - g->~QPointer(); - } else { - changed = true; - } - new (mem) QPointer(o); - if (changed) - roleIndex = role.index; + if (isMemoryUsed(mem)) + reinterpret_cast(mem)->set(o->engine(), *o); + else + new (mem) QV4::PersistentValue(o->engine(), o); + roleIndex = role.index; } return roleIndex; @@ -1235,10 +1252,10 @@ void ListElement::setBoolPropertyFast(const ListLayout::Role &role, bool b) *value = b; } -void ListElement::setQObjectPropertyFast(const ListLayout::Role &role, QObject *o) +void ListElement::setQObjectPropertyFast(const ListLayout::Role &role, QV4::QObjectWrapper *o) { char *mem = getPropertyMemory(role); - new (mem) QPointer(o); + new (mem) QV4::PersistentValue(o->engine(), o); } void ListElement::setListPropertyFast(const ListLayout::Role &role, ListModel *m) @@ -1355,7 +1372,7 @@ QVector ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElem break; case ListLayout::Role::QObject: { - QObject *object = src->getQObjectProperty(srcRole); + QV4::QObjectWrapper *object = src->getQObjectProperty(srcRole); roleIndex = target->setQObjectProperty(targetRole, object); } break; @@ -1410,9 +1427,8 @@ void ListElement::destroy(ListLayout *layout) break; case ListLayout::Role::QObject: { - QPointer *guard = getGuardProperty(r); - if (guard) - guard->~QPointer(); + if (QV4::PersistentValue *guard = getGuardProperty(r)) + guard->~PersistentValue(); } break; case ListLayout::Role::VariantMap: @@ -1549,8 +1565,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d QV4::ScopedObject o(scope, d); QV4::QObjectWrapper *wrapper = o->as(); if (role.type == ListLayout::Role::QObject && wrapper) { - QObject *o = wrapper->object(); - roleIndex = setQObjectProperty(role, o); + roleIndex = setQObjectProperty(role, wrapper); } else if (role.type == ListLayout::Role::VariantMap) { roleIndex = setVariantMapProperty(role, o); } else if (role.type == ListLayout::Role::Url) { @@ -2450,6 +2465,27 @@ void QQmlListModel::removeElements(int index, int removeCount) destroyer(); } +void QQmlListModel::updateTranslations() +{ + // assumption: it is impossible to have retranslatable strings in a + // dynamic list model, as they would already have "decayed" to strings + // when they were inserted + if (m_dynamicRoles) + return; + Q_ASSERT(m_listModel); + + QList roles; + for (int i = 0, end = m_listModel->roleCount(); i != end; ++i) { + if (m_listModel->getExistingRole(i).type == ListLayout::Role::String) + roles.append(i); + } + + if (!roles.isEmpty()) + emitItemsChanged(0, rowCount(QModelIndex()), roles); + + m_listModel->updateTranslations(); +} + /*! \qmlmethod ListModel::insert(int index, jsobject dict) @@ -2795,7 +2831,7 @@ void QQmlListModel::sync() bool QQmlListModelParser::verifyProperty(const QQmlRefPointer &compilationUnit, const QV4::CompiledData::Binding *binding) { - if (binding->type >= QV4::CompiledData::Binding::Type_Object) { + if (binding->type() >= QV4::CompiledData::Binding::Type_Object) { const quint32 targetObjectIndex = binding->value.objectIndex; const QV4::CompiledData::Object *target = compilationUnit->objectAt(targetObjectIndex); QString objName = compilationUnit->stringAt(target->inheritedTypeNameIndex); @@ -2823,7 +2859,7 @@ bool QQmlListModelParser::verifyProperty(const QQmlRefPointertype == QV4::CompiledData::Binding::Type_Script) { + } else if (binding->type() == QV4::CompiledData::Binding::Type_Script) { QString scriptStr = compilationUnit->bindingValueAsScriptString(binding); if (!binding->isFunctionExpression() && !definesEmptyList(scriptStr)) { QByteArray script = scriptStr.toUtf8(); @@ -2846,7 +2882,8 @@ bool QQmlListModelParser::applyProperty( const QString elementName = compilationUnit->stringAt(binding->propertyNameIndex); bool roleSet = false; - if (binding->type >= QV4::CompiledData::Binding::Type_Object) { + const QV4::CompiledData::Binding::Type bindingType = binding->type(); + if (bindingType >= QV4::CompiledData::Binding::Type_Object) { const quint32 targetObjectIndex = binding->value.objectIndex; const QV4::CompiledData::Object *target = compilationUnit->objectAt(targetObjectIndex); @@ -2875,17 +2912,18 @@ bool QQmlListModelParser::applyProperty( } else { QVariant value; - if (binding->isTranslationBinding()) { + const bool isTranslationBinding = binding->isTranslationBinding(); + if (isTranslationBinding) { value = QVariant::fromValue(binding); } else if (binding->evaluatesToString()) { value = compilationUnit->bindingValueAsString(binding); - } else if (binding->type == QV4::CompiledData::Binding::Type_Number) { + } else if (bindingType == QV4::CompiledData::Binding::Type_Number) { value = compilationUnit->bindingValueAsNumber(binding); - } else if (binding->type == QV4::CompiledData::Binding::Type_Boolean) { + } else if (bindingType == QV4::CompiledData::Binding::Type_Boolean) { value = binding->valueAsBoolean(); - } else if (binding->type == QV4::CompiledData::Binding::Type_Null) { + } else if (bindingType == QV4::CompiledData::Binding::Type_Null) { value = QVariant::fromValue(nullptr); - } else if (binding->type == QV4::CompiledData::Binding::Type_Script) { + } else if (bindingType == QV4::CompiledData::Binding::Type_Script) { QString scriptStr = compilationUnit->bindingValueAsScriptString(binding); if (definesEmptyList(scriptStr)) { const ListLayout::Role &role = model->getOrCreateListRole(elementName); @@ -2917,7 +2955,17 @@ bool QQmlListModelParser::applyProperty( Q_UNREACHABLE(); } + if (!model) + return roleSet; model->setOrCreateProperty(outterElementIndex, elementName, value); + auto listModel = model->m_modelCache; + if (isTranslationBinding && listModel) { + if (!listModel->translationChangeHandler) { + auto ep = QQmlEnginePrivate::get(compilationUnit->engine); + model->m_modelCache->translationChangeHandler = std::make_unique( + ep->translationLanguage.addNotifier([listModel](){ listModel->updateTranslations(); })); + } + } roleSet = true; } return roleSet; @@ -2948,7 +2996,7 @@ void QQmlListModelParser::applyBindings(QObject *obj, const QQmlRefPointertype != QV4::CompiledData::Binding::Type_Object) + if (binding->type() != QV4::CompiledData::Binding::Type_Object) continue; setRoles |= applyProperty(compilationUnit, binding, rv->m_listModel, /*outter element index*/-1); } @@ -3018,4 +3066,6 @@ bool QQmlListModelParser::definesEmptyList(const QString &s) QT_END_NAMESPACE +#include "moc_qqmllistmodel_p_p.cpp" + #include "moc_qqmllistmodel_p.cpp" diff --git a/src/qmlmodels/qqmllistmodel_p.h b/src/qmlmodels/qqmllistmodel_p.h index 2e8181e10c2..7cd2b4662b3 100644 --- a/src/qmlmodels/qqmllistmodel_p.h +++ b/src/qmlmodels/qqmllistmodel_p.h @@ -148,6 +148,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlListModel : public QAbstractListModel ListLayout *m_layout; ListModel *m_listModel; + std::unique_ptr translationChangeHandler; QVector m_modelObjects; QVector m_roles; @@ -169,6 +170,8 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlListModel : public QAbstractListModel void emitItemsInserted(); void removeElements(int index, int removeCount); + + void updateTranslations(); }; // ### FIXME diff --git a/src/qmlmodels/qqmllistmodel_p_p.h b/src/qmlmodels/qqmllistmodel_p_p.h index 4435fdfc7fc..19cba980f46 100644 --- a/src/qmlmodels/qqmllistmodel_p_p.h +++ b/src/qmlmodels/qqmllistmodel_p_p.h @@ -278,6 +278,8 @@ struct StringOrTranslation class ListElement { public: + enum ObjectIndestructible { Indestructible = 1, ExplicitlySet = 2 }; + enum { BLOCK_SIZE = 64 - sizeof(int) - sizeof(ListElement *) - sizeof(ModelNodeMetaObject *) }; ListElement(); ListElement(int existingUid); @@ -285,11 +287,6 @@ class ListElement static QVector sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout); - enum - { - BLOCK_SIZE = 64 - sizeof(int) - sizeof(ListElement *) - sizeof(ModelNodeMetaObject *) - }; - private: void destroy(ListLayout *layout); @@ -302,7 +299,7 @@ class ListElement int setDoubleProperty(const ListLayout::Role &role, double n); int setBoolProperty(const ListLayout::Role &role, bool b); int setListProperty(const ListLayout::Role &role, ListModel *m); - int setQObjectProperty(const ListLayout::Role &role, QObject *o); + int setQObjectProperty(const ListLayout::Role &role, QV4::QObjectWrapper *o); int setVariantMapProperty(const ListLayout::Role &role, QV4::Object *o); int setVariantMapProperty(const ListLayout::Role &role, QVariantMap *m); int setDateTimeProperty(const ListLayout::Role &role, const QDateTime &dt); @@ -313,7 +310,7 @@ class ListElement void setStringPropertyFast(const ListLayout::Role &role, const QString &s); void setDoublePropertyFast(const ListLayout::Role &role, double n); void setBoolPropertyFast(const ListLayout::Role &role, bool b); - void setQObjectPropertyFast(const ListLayout::Role &role, QObject *o); + void setQObjectPropertyFast(const ListLayout::Role &role, QV4::QObjectWrapper *o); void setListPropertyFast(const ListLayout::Role &role, ListModel *m); void setVariantMapFast(const ListLayout::Role &role, QV4::Object *o); void setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt); @@ -325,8 +322,8 @@ class ListElement QVariant getProperty(const ListLayout::Role &role, const QQmlListModel *owner, QV4::ExecutionEngine *eng); ListModel *getListProperty(const ListLayout::Role &role); StringOrTranslation *getStringProperty(const ListLayout::Role &role); - QObject *getQObjectProperty(const ListLayout::Role &role); - QPointer *getGuardProperty(const ListLayout::Role &role); + QV4::QObjectWrapper *getQObjectProperty(const ListLayout::Role &role); + QV4::PersistentValue *getGuardProperty(const ListLayout::Role &role); QVariantMap *getVariantMapProperty(const ListLayout::Role &role); QDateTime *getDateTimeProperty(const ListLayout::Role &role); QUrl *getUrlProperty(const ListLayout::Role &role); @@ -365,6 +362,8 @@ class ListModel QVariant getProperty(int elementIndex, int roleIndex, const QQmlListModel *owner, QV4::ExecutionEngine *eng); ListModel *getListProperty(int elementIndex, const ListLayout::Role &role); + void updateTranslations(); + int roleCount() const { return m_layout->roleCount(); diff --git a/src/qml/types/qqmlmodelindexvaluetype.cpp b/src/qmlmodels/qqmlmodelindexvaluetype.cpp similarity index 100% rename from src/qml/types/qqmlmodelindexvaluetype.cpp rename to src/qmlmodels/qqmlmodelindexvaluetype.cpp diff --git a/src/qml/types/qqmlmodelindexvaluetype_p.h b/src/qmlmodels/qqmlmodelindexvaluetype_p.h similarity index 100% rename from src/qml/types/qqmlmodelindexvaluetype_p.h rename to src/qmlmodels/qqmlmodelindexvaluetype_p.h diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp index 5b058481ab2..13a07ecc6d2 100644 --- a/src/qmlmodels/qqmltableinstancemodel.cpp +++ b/src/qmlmodels/qqmltableinstancemodel.cpp @@ -461,8 +461,10 @@ void QQmlTableInstanceModel::setModel(const QVariant &model) if (auto const aim = abstractItemModel()) disconnect(aim, &QAbstractItemModel::dataChanged, this, &QQmlTableInstanceModel::dataChangedCallback); m_adaptorModel.setModel(model, this); - if (auto const aim = abstractItemModel()) + if (auto const aim = abstractItemModel()) { connect(aim, &QAbstractItemModel::dataChanged, this, &QQmlTableInstanceModel::dataChangedCallback); + connect(aim, &QAbstractItemModel::modelAboutToBeReset, this, &QQmlTableInstanceModel::modelAboutToBeResetCallback); + } } void QQmlTableInstanceModel::dataChangedCallback(const QModelIndex &begin, const QModelIndex &end, const QVector &roles) @@ -480,6 +482,21 @@ void QQmlTableInstanceModel::dataChangedCallback(const QModelIndex &begin, const } } +void QQmlTableInstanceModel::modelAboutToBeResetCallback() +{ + // When the model is reset, we can no longer rely on any of the data it has + // provided us so far. Normally it's enough for the view to recreate all the + // delegate items in that case, except if the model roles has changed as well + // (since those are cached by QQmlAdaptorModel / Accessors). For the latter case, we + // simply set the model once more in the delegate model to rebuild everything. + auto const aim = abstractItemModel(); + auto oldRoleNames = aim->roleNames(); + QObject::connect(aim, &QAbstractItemModel::modelReset, this, [this, aim, oldRoleNames](){ + if (oldRoleNames != aim->roleNames()) + setModel(model()); + }, Qt::SingleShotConnection); +} + QQmlComponent *QQmlTableInstanceModel::delegate() const { return m_delegate; diff --git a/src/qmlmodels/qqmltableinstancemodel_p.h b/src/qmlmodels/qqmltableinstancemodel_p.h index 18421bae38e..6ae899ed211 100644 --- a/src/qmlmodels/qqmltableinstancemodel_p.h +++ b/src/qmlmodels/qqmltableinstancemodel_p.h @@ -151,6 +151,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlTableInstanceModel : public QQmlInstanceMod void destroyModelItem(QQmlDelegateModelItem *modelItem, DestructionMode mode); void dataChangedCallback(const QModelIndex &begin, const QModelIndex &end, const QVector &roles); + void modelAboutToBeResetCallback(); static bool isDoneIncubating(QQmlDelegateModelItem *modelItem); static void deleteModelItemLater(QQmlDelegateModelItem *modelItem); diff --git a/src/qmlmodels/qquickpackage_p.h b/src/qmlmodels/qquickpackage_p.h index f40ffe552a4..6df7b3df84a 100644 --- a/src/qmlmodels/qquickpackage_p.h +++ b/src/qmlmodels/qquickpackage_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE class QQuickPackagePrivate; class QQuickPackageAttached; -class Q_AUTOTEST_EXPORT QQuickPackage : public QObject +class Q_QMLMODELS_PRIVATE_EXPORT QQuickPackage : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QQuickPackage) diff --git a/src/qmlmodels/qtqmlmodelsglobal_p.h b/src/qmlmodels/qtqmlmodelsglobal_p.h index 1a1157138dd..145112c9c15 100644 --- a/src/qmlmodels/qtqmlmodelsglobal_p.h +++ b/src/qmlmodels/qtqmlmodelsglobal_p.h @@ -58,6 +58,4 @@ #define Q_QMLMODELS_PRIVATE_EXPORT Q_QMLMODELS_EXPORT #define Q_QMLMODELS_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT -void Q_QMLMODELS_PRIVATE_EXPORT qml_register_types_QtQml_Models(); - #endif // QTQMLMODELSGLOBAL_P_H diff --git a/src/qmltest/CMakeLists.txt b/src/qmltest/CMakeLists.txt index e6b6ccfff0f..7f55ebc8b00 100644 --- a/src/qmltest/CMakeLists.txt +++ b/src/qmltest/CMakeLists.txt @@ -2,9 +2,6 @@ ## QuickTest Module: ##################################################################### -set_source_files_properties(TestCase.qml SignalSpy.qml PROPERTIES - QT_QML_SOURCE_VERSION "1.0" -) set_source_files_properties(testlogger.js PROPERTIES QT_QML_SKIP_QMLDIR_ENTRY TRUE ) @@ -12,10 +9,9 @@ set_source_files_properties(testlogger.js PROPERTIES qt_internal_add_qml_module(QuickTest URI "QtTest" VERSION "${PROJECT_VERSION}" - PLUGIN_TARGET qmltestplugin - CLASS_NAME QTestQmlModule + PAST_MAJOR_VERSIONS 1 DEPENDENCIES - QtQuick.Window/2.0 + QtQuick.Window CONFIG_MODULE_NAME qmltest QMAKE_MODULE_CONFIG $${QT.testlib.CONFIG} SOURCES @@ -37,12 +33,12 @@ qt_internal_add_qml_module(QuickTest Qt::CorePrivate Qt::Gui Qt::QmlPrivate - Qt::Quick Qt::QuickPrivate Qt::TestPrivate PUBLIC_LIBRARIES Qt::Core Qt::Test + Qt::Quick PRIVATE_MODULE_INTERFACE Qt::TestPrivate ) diff --git a/src/qmltest/SignalSpy.qml b/src/qmltest/SignalSpy.qml index 52ed83e261e..641f8642c60 100644 --- a/src/qmltest/SignalSpy.qml +++ b/src/qmltest/SignalSpy.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -81,6 +81,16 @@ Item { id: spy visible: false + Component.onDestruction: { + // We are potentially destroyed before the target object, + // and since only the sender (target) being destroyed destroys a connection + // in QML, and not the receiver (us/"spy"), we need to manually disconnect. + // When QTBUG-118166 is implemented, we can remove this. + let signalFunc = target ? target[signalName] : null + if (signalFunc) + signalFunc.disconnect(spy.qtest_activated) + } + TestUtil { id: util } @@ -218,9 +228,14 @@ Item { /*! \internal */ property bool qtest_valid:false /*! \internal */ + property bool qtest_reentrancy_guard: false /*! \internal */ function qtest_update() { + if (qtest_reentrancy_guard) + return; + qtest_reentrancy_guard = true; + if (qtest_prevTarget != null) { var prevHandlerName = qtest_signalHandlerName(qtest_prevSignalName) var prevFunc = qtest_prevTarget[prevHandlerName] @@ -251,6 +266,8 @@ Item { } else { spy.qtest_valid = false } + + qtest_reentrancy_guard = false; } /*! \internal */ diff --git a/src/qmltest/TestCase.qml b/src/qmltest/TestCase.qml index 1c9011e01ef..2b817ad7dd4 100644 --- a/src/qmltest/TestCase.qml +++ b/src/qmltest/TestCase.qml @@ -260,6 +260,105 @@ import "testlogger.js" as TestLogger of \l Component, the \l createTemporaryObject() function can be used. \sa {QtTest::SignalSpy}{SignalSpy}, {Qt Quick Test} + + \section1 Separating tests from application logic + + In most cases, you would want to separate your tests from the application + logic by splitting them into different projects and linking them. + + For example, you could have the following project structure: + + \badcode + . + | — CMakeLists.txt + | — src + | | — main.cpp + | — qml + | | — main.qml + | — modules + | | — MyModule + | | — MyButton.qml + | | — CMakeLists.txt + | — tests + | — UnitQMLTests + | — tst_testqml.qml + | — tests_main.cpp + | — tests_setup.cpp + | — tests_setup.h + \endcode + + Now, to test \c modules/MyModule/MyButton.qml, create a library for + \c MyModule in \c modules/MyModule/CMakeLists.txt and link it to your + test project, \c tests/UnitQMLTests/CMakeLists.txt: + + \if defined(onlinedocs) + \tab {build-qt-app}{tab-cmake-add-library}{modules/MyModule/CMakeLists.txt}{checked} + \tab {build-qt-app}{tab-cmake-link-against-library}{tests/UnitQMLTests/CMakeLists.txt}{} + \tab {build-qt-app}{tab-tests_main}{tests/UnitQMLTests/tests_main.cpp}{} + \tab {build-qt-app}{tab-tests-setup-cpp}{tests/UnitQMLTests/tests_setup.cpp}{} + \tab {build-qt-app}{tab-tests-setup-h}{tests/UnitQMLTests/tests_setup.h}{} + \tabcontent {tab-cmake-add-library} + \else + \section1 Add library + \endif + \dots + \snippet modules_MyModule_CMakeLists.txt add library + \dots + \if defined(onlinedocs) + \endtabcontent + \tabcontent {tab-cmake-link-against-library} + \else + \section1 Link against library + \endif + \dots + \snippet tests_UnitQMLTests_CMakeLists.txt link against library + \dots + \if defined(onlinedocs) + \endtabcontent + \tabcontent {tab-tests_main} + \else + \section1 main.cpp + \endif + \snippet tests_main.cpp main + \if defined(onlinedocs) + \endtabcontent + \tabcontent {tab-tests-setup-cpp} + \else + \section1 setup c++ + \endif + \snippet tests_setup.cpp setup + \if defined(onlinedocs) + \endtabcontent + \tabcontent {tab-tests-setup-h} + \else + \section1 setup header + \endif + \snippet tests_setup.h setup + \if defined(onlinedocs) + \endtabcontent + \endif + + Then, in \c tests/UnitQMLTests/tst_testqml.qml, you can import + \c modules/MyModule/MyButton.qml: + + \if defined(onlinedocs) + \tab {test-qml}{tab-qml-import}{tests/UnitQMLTests/tst_testqml.qml}{checked} + \tab {test-qml}{tab-qml-my-button}{modules/MyModule/MyButton.qml}{} + \tabcontent {tab-qml-import} + \else + \section1 Import QML + \endif + \snippet tests_UnitQMLTests_tst_testqml.qml import + \if defined(onlinedocs) + \endtabcontent + \tabcontent {tab-qml-my-button} + \else + \section1 Define QML button + \endif + \snippet modules_MyModule_MyButton.qml define + \if defined(onlinedocs) + \endtabcontent + \endif */ @@ -1133,7 +1232,7 @@ Item { \qmlmethod TestCase::warn(message) Prints \a message as a warning message. Similar to - \c{QWARN(message)} in C++. + \c{qWarning(message)} in C++. \sa ignoreWarning() */ diff --git a/src/qmltest/doc/snippets/modules_MyModule_CMakeLists.txt b/src/qmltest/doc/snippets/modules_MyModule_CMakeLists.txt new file mode 100644 index 00000000000..37ac70aaa20 --- /dev/null +++ b/src/qmltest/doc/snippets/modules_MyModule_CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.20) + +set(MODULE_NAME "MyModule") +project(${MODULE_NAME} LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) +set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick) + +file(GLOB QML_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.qml) +source_group("Qml Files" FILES ${QML_SOURCES}) + +//! [add library] +qt_add_library(MyModule STATIC) + +qt6_add_qml_module(MyModule + URI MyModule + VERSION 1.0 + QML_FILES ${QML_SOURCES} +) +//! [add library] + +set_target_properties(MyModule PROPERTIES + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE FALSE +) + +target_link_libraries(MyModule PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +target_include_directories(MyModule PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/qmltest/doc/snippets/modules_MyModule_MyButton.qml b/src/qmltest/doc/snippets/modules_MyModule_MyButton.qml new file mode 100644 index 00000000000..5d7dd9c7ddd --- /dev/null +++ b/src/qmltest/doc/snippets/modules_MyModule_MyButton.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [define] +import QtQuick +import QtQuick.Controls + +Button { + width: 50 + height: 50 + onClicked: width = 100 +} +//! [define] diff --git a/src/qmltest/doc/snippets/overview.cmake b/src/qmltest/doc/snippets/overview.cmake index 5415e42a17e..9ea4d01e83b 100644 --- a/src/qmltest/doc/snippets/overview.cmake +++ b/src/qmltest/doc/snippets/overview.cmake @@ -1,4 +1,4 @@ #! [cmake_use] -find_package(Qt6 COMPONENTS QuickTest REQUIRED) +find_package(Qt6 REQUIRED COMPONENTS QuickTest) target_link_libraries(mytarget PRIVATE Qt6::QuickTest) #! [cmake_use] diff --git a/src/qmltest/doc/snippets/tests_UnitQMLTests_CMakeLists.txt b/src/qmltest/doc/snippets/tests_UnitQMLTests_CMakeLists.txt new file mode 100644 index 00000000000..ba444c2cd61 --- /dev/null +++ b/src/qmltest/doc/snippets/tests_UnitQMLTests_CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 3.2) + +project(TestQML LANGUAGES CXX) + +enable_testing() + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS QuickTest Qml) +find_package(Qt6 REQUIRED COMPONENTS QuickTest Qml) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +# no need to copy around qml test files for shadow builds - just set the respective define +add_definitions(-DQUICK_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") + +//! [link against library] +add_executable(TestQML tests_main.cpp + tests_setup.cpp tests_setup.h) + +add_test(NAME TestQML COMMAND TestQML) + +target_link_libraries( + TestQML + PRIVATE Qt6::QuickTest + PRIVATE Qt6::Qml + PRIVATE MyModule + PRIVATE MyModuleplugin +) +//! [link against library] diff --git a/src/qmltest/doc/snippets/tests_UnitQMLTests_tst_testqml.qml b/src/qmltest/doc/snippets/tests_UnitQMLTests_tst_testqml.qml new file mode 100644 index 00000000000..432d20d7629 --- /dev/null +++ b/src/qmltest/doc/snippets/tests_UnitQMLTests_tst_testqml.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [import] +import QtQuick +import QtQuick.Controls + +import QtTest +import MyModule + +Item { + width: 800 + height: 600 + + MyButton { + id: myButton + anchors.centerIn: parent + } + + TestCase { + name: "MyButton" + when: windowShown + + function test_clickToExpand() { + const widthBeforeClick = myButton.width; + mouseClick(myButton); + const widthAfterClick = myButton.width; + verify(widthBeforeClick < widthAfterClick); + } + } +} +//! [import] diff --git a/src/qmltest/doc/snippets/tests_main.cpp b/src/qmltest/doc/snippets/tests_main.cpp new file mode 100644 index 00000000000..983f932acd6 --- /dev/null +++ b/src/qmltest/doc/snippets/tests_main.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [main] +#include +#include "tests_setup.h" + +QUICK_TEST_MAIN_WITH_SETUP(TestQML, Setup) +//! [main] diff --git a/src/qmltest/doc/snippets/tests_setup.cpp b/src/qmltest/doc/snippets/tests_setup.cpp new file mode 100644 index 00000000000..f7914dda87b --- /dev/null +++ b/src/qmltest/doc/snippets/tests_setup.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [setup] +#include "tests_setup.h" + +void Setup::applicationAvailable() +{ + // custom code that doesn't require QQmlEngine +} + +void Setup::qmlEngineAvailable(QQmlEngine *engine) +{ + // add import paths + engine->addImportPath("../../"); +} + +void Setup::cleanupTestCase() +{ + // custom code to clean up before destruction starts +} +//! [setup] diff --git a/src/qmltest/doc/snippets/tests_setup.h b/src/qmltest/doc/snippets/tests_setup.h new file mode 100644 index 00000000000..f5baa04eeb6 --- /dev/null +++ b/src/qmltest/doc/snippets/tests_setup.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [setup] +#ifndef SETUP_H +#define SETUP_H + +#include +#include + +class Setup : public QObject +{ + Q_OBJECT +public: + Setup() = default; + +public slots: + void applicationAvailable(); + void qmlEngineAvailable(QQmlEngine *engine); + void cleanupTestCase(); +}; + +#endif // SETUP_H +//! [setup] diff --git a/src/qmltest/doc/src/qtquicktest-qmltypes.qdoc b/src/qmltest/doc/src/qtquicktest-qmltypes.qdoc index d7cada0db26..d874b20a5aa 100644 --- a/src/qmltest/doc/src/qtquicktest-qmltypes.qdoc +++ b/src/qmltest/doc/src/qtquicktest-qmltypes.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \qmlmodule QtTest 1.\QtMinorVersion + \qmlmodule QtTest \title Qt Quick Test QML Types \brief Provides QML types to unit test your QML application. \ingroup qmlmodules diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp index 276463c7c50..8b1aad5dc08 100644 --- a/src/qmltest/quicktest.cpp +++ b/src/qmltest/quicktest.cpp @@ -298,7 +298,7 @@ class TestCaseCollector if (!object) // Start at root of compilation unit if not enumerating a specific child object = compilationUnit->objectAt(0); - if (object->flags & Object::IsInlineComponentRoot) + if (object->hasFlag(Object::IsInlineComponentRoot)) return result; if (const auto superTypeUnit = compilationUnit->resolvedTypes.value( @@ -314,13 +314,13 @@ class TestCaseCollector // Look for override of name in this type for (auto binding = object->bindingsBegin(); binding != object->bindingsEnd(); ++binding) { if (compilationUnit->stringAt(binding->propertyNameIndex) == QLatin1String("name")) { - if (binding->type == QV4::CompiledData::Binding::Type_String) { + if (binding->type() == QV4::CompiledData::Binding::Type_String) { result.testCaseName = compilationUnit->stringAt(binding->stringIndex); } else { QQmlError error; error.setUrl(compilationUnit->url()); - error.setLine(binding->location.line); - error.setColumn(binding->location.column); + error.setLine(binding->location.line()); + error.setColumn(binding->location.column()); error.setDescription(QStringLiteral("the 'name' property of a TestCase must be a literal string")); result.errors << error; } @@ -344,7 +344,7 @@ class TestCaseCollector } for (auto binding = object->bindingsBegin(); binding != object->bindingsEnd(); ++binding) { - if (binding->type == QV4::CompiledData::Binding::Type_Object) { + if (binding->type() == QV4::CompiledData::Binding::Type_Object) { const Object *child = compilationUnit->objectAt(binding->value.objectIndex); result << enumerateTestCases(compilationUnit, child); } @@ -432,7 +432,7 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch testPath = s; } -#if defined(Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined(Q_OS_INTEGRITY) if (testPath.isEmpty()) testPath = QLatin1String(":/"); #endif @@ -631,3 +631,5 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch } QT_END_NAMESPACE + +#include "moc_quicktest_p.cpp" diff --git a/src/qmltest/quicktestevent.cpp b/src/qmltest/quicktestevent.cpp index a1a707d2d6c..c41061200e5 100644 --- a/src/qmltest/quicktestevent.cpp +++ b/src/qmltest/quicktestevent.cpp @@ -227,7 +227,7 @@ namespace QtQuickTest static const char *mouseActionNames[] = { "MousePress", "MouseRelease", "MouseClick", "MouseDoubleClick", "MouseMove", "MouseDoubleClickSequence" }; QString warning = QString::fromLatin1("Mouse event \"%1\" not accepted by receiving window"); - QWARN(warning.arg(QString::fromLatin1(mouseActionNames[static_cast(action)])).toLatin1().data()); + QTest::qWarn(warning.arg(QString::fromLatin1(mouseActionNames[static_cast(action)])).toLatin1().data()); } } @@ -240,8 +240,10 @@ namespace QtQuickTest QTEST_ASSERT(item); if (delay == -1 || delay < QTest::defaultMouseDelay()) delay = QTest::defaultMouseDelay(); - if (delay > 0) + if (delay > 0) { QTest::qWait(delay); + lastMouseTimestamp += delay; + } QPoint pos; QQuickItem *sgitem = qobject_cast(item); @@ -254,6 +256,7 @@ namespace QtQuickTest stateKey &= static_cast(Qt::KeyboardModifierMask); QWheelEvent we(pos, window->mapToGlobal(pos), QPoint(0, 0), QPoint(xDelta, yDelta), buttons, stateKey, Qt::NoScrollPhase, false); + we.setTimestamp(++lastMouseTimestamp); QSpontaneKeyEvent::setSpontaneous(&we); // hmmmm if (!qApp->notify(window, &we)) @@ -479,3 +482,5 @@ QQuickTouchEventSequence *QuickTestEvent::touchEvent(QObject *item) } QT_END_NAMESPACE + +#include "moc_quicktestevent_p.cpp" diff --git a/src/qmltest/quicktestglobal_p.h b/src/qmltest/quicktestglobal_p.h index 4a70c2478d4..0327f73b4c2 100644 --- a/src/qmltest/quicktestglobal_p.h +++ b/src/qmltest/quicktestglobal_p.h @@ -55,7 +55,4 @@ #define Q_QUICK_TEST_PRIVATE_EXPORT Q_QUICK_TEST_EXPORT -void Q_QUICK_TEST_PRIVATE_EXPORT qml_register_types_QtTest(); - - #endif // QUICKTESTGLOBAL_P_H diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp index 0853c26f514..22edb956874 100644 --- a/src/qmltest/quicktestresult.cpp +++ b/src/qmltest/quicktestresult.cpp @@ -775,7 +775,8 @@ QObject *QuickTestResult::grabImage(QQuickItem *item) if (item && item->window()) { QQuickWindow *window = item->window(); QImage grabbed = window->grabWindow(); - QRectF rf(item->x(), item->y(), item->width(), item->height()); + const auto dpi = grabbed.devicePixelRatio(); + QRectF rf(item->x() * dpi, item->y() * dpi, item->width() * dpi, item->height() * dpi); rf = rf.intersected(QRectF(0, 0, grabbed.width(), grabbed.height())); QObject *o = new QuickTestImageObject(grabbed.copy(rf.toAlignedRect())); QQmlEngine::setContextForObject(o, qmlContext(this)); diff --git a/src/qmltest/quicktestutil.cpp b/src/qmltest/quicktestutil.cpp index 994c66845b1..0e6694fd7ba 100644 --- a/src/qmltest/quicktestutil.cpp +++ b/src/qmltest/quicktestutil.cpp @@ -111,3 +111,5 @@ int QuickTestUtil::callerLine(int frameIndex) const } QT_END_NAMESPACE + +#include "moc_quicktestutil_p.cpp" diff --git a/src/qmltyperegistrar/metatypesjsonprocessor.cpp b/src/qmltyperegistrar/metatypesjsonprocessor.cpp index 4d6f97e8746..1c9e9dfddf2 100644 --- a/src/qmltyperegistrar/metatypesjsonprocessor.cpp +++ b/src/qmltyperegistrar/metatypesjsonprocessor.cpp @@ -296,6 +296,7 @@ void MetaTypesJsonProcessor::processTypes(const QJsonObject &types) if (!include.endsWith(QLatin1String(".h")) && !include.endsWith(QLatin1String(".hpp")) && !include.endsWith(QLatin1String(".hxx")) + && !include.endsWith(QLatin1String(".hh")) && include.contains(QLatin1Char('.'))) { fprintf(stderr, "Class %s is declared in %s, which appears not to be a header.\n" @@ -317,7 +318,7 @@ void MetaTypesJsonProcessor::processTypes(const QJsonObject &types) void MetaTypesJsonProcessor::processForeignTypes(const QJsonObject &types) { - const QString include = types[QLatin1String("inputFile")].toString(); + const QString include = resolvedInclude(types[QLatin1String("inputFile")].toString()); const QJsonArray classes = types[QLatin1String("classes")].toArray(); for (const QJsonValue cls : classes) { QJsonObject classDef = cls.toObject(); diff --git a/src/qmltyperegistrar/qmltyperegistrar.cpp b/src/qmltyperegistrar/qmltyperegistrar.cpp index 914781e7379..981f8bb86e7 100644 --- a/src/qmltyperegistrar/qmltyperegistrar.cpp +++ b/src/qmltyperegistrar/qmltyperegistrar.cpp @@ -192,12 +192,28 @@ int main(int argc, char **argv) fprintf(output, "\n\n"); + // Keep this in sync with _qt_internal_get_escaped_uri in CMake QString moduleAsSymbol = module; - moduleAsSymbol.replace(QLatin1Char('.'), QLatin1Char('_')); + moduleAsSymbol.replace(QRegularExpression(QStringLiteral("[^A-Za-z0-9]")), QStringLiteral("_")); - const QString functionName = QStringLiteral("qml_register_types_") + moduleAsSymbol; + QString underscoredModuleAsSymbol = module; + underscoredModuleAsSymbol.replace(QLatin1Char('.'), QLatin1Char('_')); + + if (underscoredModuleAsSymbol != moduleAsSymbol + || underscoredModuleAsSymbol.isEmpty() + || underscoredModuleAsSymbol.front().isDigit()) { + qWarning() << module << "is an invalid QML module URI. You cannot import this."; + } - fprintf(output, "Q_DECL_EXPORT void %s()\n{", qPrintable(functionName)); + const QString functionName = QStringLiteral("qml_register_types_") + moduleAsSymbol; + fprintf(output, + "#if !defined(QT_STATIC)\n" + "#define Q_QMLTYPE_EXPORT Q_DECL_EXPORT\n" + "#else\n" + "#define Q_QMLTYPE_EXPORT\n" + "#endif\n" + "\n"); + fprintf(output, "Q_QMLTYPE_EXPORT void %s()\n{", qPrintable(functionName)); const auto majorVersion = parser.value(majorVersionOption); const auto pastMajorVersions = parser.values(pastMajorVersionOption); const auto minorVersion = parser.value(minorVersionOption); diff --git a/src/qmltyperegistrar/qmltypes.prf b/src/qmltyperegistrar/qmltypes.prf index 2c6e474a21b..b6dea810ccb 100644 --- a/src/qmltyperegistrar/qmltypes.prf +++ b/src/qmltyperegistrar/qmltypes.prf @@ -43,16 +43,35 @@ qt_module_deps = $$resolve_depends(qt_module_deps, "QT.", ".depends" ".run_depen qt_module_deps = $$replace(qt_module_deps, _private$, '') qt_module_deps = $$unique(qt_module_deps) +# We know we need to prefer the CMake debug build type for qmake debug builds. Which of the CMake +# release build types should be preferred for a qmake release build is guesswork. We apply a +# heuristic here: +# +# If you've gone to the trouble of building a "minsizerel" Qt, you probably want to use it for your +# qmake "release" builds. Conversely, if you have both a "release" and a "relwithdebinfo" Qt, you +# probably want to use the "release" Qt build for qmake "release" builds and the "relwithdebinfo" +# one for qmake "debug" builds. +# +# If no fitting build type exists, we accept the others. On linux, for example, we typically +# have only a single "relwithdebinfo" Qt build for both debug and release builds of user projects. +build_types = minsizerel release relwithdebinfo debug +CONFIG(debug, debug|release): build_types = $$reverse(build_types) + for(dep, qt_module_deps) { android:ABI = _$${ANDROID_TARGET_ARCH} - METATYPES_FILENAME = $$lower($$eval(QT.$${dep}.module))$${ABI}_metatypes.json - INSTALLED_METATYPES = $$[QT_INSTALL_LIBS]/metatypes/$$METATYPES_FILENAME - isEmpty(MODULE_BASE_OUTDIR) { - QML_FOREIGN_METATYPES += $$INSTALLED_METATYPES - } else { - MODULE_BASE_METATYPES = $$MODULE_BASE_OUTDIR/lib/metatypes/$$METATYPES_FILENAME - exists($$MODULE_BASE_METATYPES): QML_FOREIGN_METATYPES += $$MODULE_BASE_METATYPES - else: QML_FOREIGN_METATYPES += $$INSTALLED_METATYPES + infixed_module_name = $$eval(QT.$${dep}.module) + + for(build_type, build_types) { + isEmpty(QT_LIBINFIX) { + metatypes_filename = $$lower($${infixed_module_name})$${ABI}_$${build_type}_metatypes.json + } else { + metatypes_filename = $$lower($$replace($${infixed_module_name}, $$QT_LIBINFIX, ''))$${ABI}_$${build_type}_metatypes.json + } + metatypes_filepath = $$[QT_INSTALL_LIBS]/metatypes/$${metatypes_filename} + exists($${metatypes_filepath}) { + QML_FOREIGN_METATYPES += $${metatypes_filepath} + break() + } } } @@ -82,12 +101,18 @@ qmltyperegistrar_compiler.output = $$TYPEREGISTRATIONS qmltyperegistrar_compiler.variable_out = SOURCES qmltyperegistrar_compiler.name = Automatic QML type registration qmltyperegistrar_compiler.dependency_type = TYPE_C - -qmltyperegistrar_qmltypes.input = METATYPES_JSON -qmltyperegistrar_qmltypes.depends = $$TYPEREGISTRATIONS -qmltyperegistrar_qmltypes.output = $$QMLTYPES_FILENAME -qmltyperegistrar_qmltypes.CONFIG = no_link -qmltyperegistrar_qmltypes.commands = $$escape_expand(\\n) # force creation of rule +QMAKE_EXTRA_COMPILERS += qmltyperegistrar_compiler + +!contains(TEMPLATE, "vc.*") { # work around QTBUG-91033 + # Create a fake extra compiler to announce that we generate $$QMLTYPES_FILENAME. + # This allows us to use $$QMLTYPES_FILENAME as input in other extra compilers. + qmltyperegistrar_qmltypes.input = METATYPES_JSON + qmltyperegistrar_qmltypes.depends = $$TYPEREGISTRATIONS + qmltyperegistrar_qmltypes.output = $$QMLTYPES_FILENAME + qmltyperegistrar_qmltypes.CONFIG = no_link + qmltyperegistrar_qmltypes.commands = $$escape_expand(\\n) # force creation of rule + QMAKE_EXTRA_COMPILERS += qmltyperegistrar_qmltypes +} install_qmltypes { INSTALL_QML_FILES = false @@ -110,5 +135,3 @@ install_qmltypes { else: COPIES += do_install_qmltypes } } - -QMAKE_EXTRA_COMPILERS += qmltyperegistrar_compiler qmltyperegistrar_qmltypes diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp index bf6c0ca5ed1..b58d4ac00a2 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.cpp +++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp @@ -261,11 +261,29 @@ void QmlTypesClassDescription::collect( accessSemantics = QLatin1String("reference"); } else { isCreatable = false; - // If no classDef, we assume it's a value type defined by the foreign/extended trick. - // Objects and namespaces always have metaobjects and therefore classDefs. - accessSemantics = (!classDef || classDef->value(QLatin1String("gadget")).toBool()) - ? QLatin1String("value") - : QLatin1String("none"); + + if (!classDef) { + if (elementName.isEmpty() || elementName[0].isLower()) { + // If no classDef, we generally assume it's a value type defined by the + // foreign/extended trick. + accessSemantics = QLatin1String("value"); + } else { + // Objects and namespaces always have metaobjects and therefore classDefs. + // However, we may not be able to resolve the metaobject at compile time. See + // the "Invisible" test case. In that case, we must not assume anything about + // access semantics. + qWarning() << "Warning: Refusing to generate non-lowercase name" + << elementName << "for unknown foreign type"; + elementName.clear(); + // Make it completely inaccessible. + // We cannot get enums from anonymous types after all. + accessSemantics = QLatin1String("none"); + } + } else if (classDef->value(QLatin1String("gadget")).toBool()) { + accessSemantics = QLatin1String("value"); + } else { + accessSemantics = QLatin1String("none"); + } } } diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp index c5b4bfd54f2..15740579c09 100644 --- a/src/qmltyperegistrar/qmltypescreator.cpp +++ b/src/qmltyperegistrar/qmltypescreator.cpp @@ -115,7 +115,7 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle m_qml.writeScriptBinding(QLatin1String("attachedType"), enquote(collector.attachedType)); } -void QmlTypesCreator::writeType(const QJsonObject &property, const QString &key, bool parsePointer) +void QmlTypesCreator::writeType(const QJsonObject &property, const QString &key) { auto it = property.find(key); if (it == property.end()) @@ -153,7 +153,7 @@ void QmlTypesCreator::writeType(const QJsonObject &property, const QString &key, type = type.mid(listPropertySize, type.size() - listPropertySize - 1); } - if (parsePointer && type.endsWith(QLatin1Char('*'))) { + if (type.endsWith(QLatin1Char('*'))) { isPointer = true; type = type.left(type.size() - 1); } @@ -178,7 +178,7 @@ void QmlTypesCreator::writeProperties(const QJsonArray &properties) if (it != obj.end()) m_qml.writeScriptBinding(QLatin1String("revision"), QString::number(it.value().toInt())); - writeType(obj, QLatin1String("type"), true); + writeType(obj, QLatin1String("type")); if (!obj.contains(QStringLiteral("privateClass"))) { const auto bindable = obj.constFind(QLatin1String("bindable")); @@ -227,7 +227,7 @@ void QmlTypesCreator::writeMethods(const QJsonArray &methods, const QString &typ m_qml.writeScriptBinding(QLatin1String("name"), enquote(name)); if (revision != obj.end()) m_qml.writeScriptBinding(QLatin1String("revision"), QString::number(revision.value().toInt())); - writeType(obj, QLatin1String("returnType"), false); + writeType(obj, QLatin1String("returnType")); const auto isConstructor = obj.find(QLatin1String("isConstructor")); if (isConstructor != obj.constEnd() && isConstructor->toBool()) m_qml.writeScriptBinding(QLatin1String("isConstructor"), QLatin1String("true")); @@ -237,7 +237,7 @@ void QmlTypesCreator::writeMethods(const QJsonArray &methods, const QString &typ const QString name = obj[QLatin1String("name")].toString(); if (!name.isEmpty()) m_qml.writeScriptBinding(QLatin1String("name"), enquote(name)); - writeType(obj, QLatin1String("type"), true); + writeType(obj, QLatin1String("type")); m_qml.writeEndObject(); } m_qml.writeEndObject(); diff --git a/src/qmltyperegistrar/qmltypescreator.h b/src/qmltyperegistrar/qmltypescreator.h index 0908a1e0477..3e8fa480a27 100644 --- a/src/qmltyperegistrar/qmltypescreator.h +++ b/src/qmltyperegistrar/qmltypescreator.h @@ -50,7 +50,7 @@ class QmlTypesCreator private: void writeClassProperties(const QmlTypesClassDescription &collector); - void writeType(const QJsonObject &property, const QString &key, bool parsePointer); + void writeType(const QJsonObject &property, const QString &key); void writeProperties(const QJsonArray &properties); void writeMethods(const QJsonArray &methods, const QString &type); void writeEnums(const QJsonArray &enums); diff --git a/src/qmlworkerscript/doc/src/qmlworkerscript.qdoc b/src/qmlworkerscript/doc/src/qmlworkerscript.qdoc index 8f7f5e546c3..4b01425ab18 100644 --- a/src/qmlworkerscript/doc/src/qmlworkerscript.qdoc +++ b/src/qmlworkerscript/doc/src/qmlworkerscript.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \qmlmodule QtQml.WorkerScript 2.\QtMinorVersion + \qmlmodule QtQml.WorkerScript \title Qt QML WorkerScript QML Types \ingroup qmlmodules \brief Provides QML types for worker scripts. diff --git a/src/qmlworkerscript/qquickworkerscript_p.h b/src/qmlworkerscript/qquickworkerscript_p.h index d1ea34422ac..45e84b4440e 100644 --- a/src/qmlworkerscript/qquickworkerscript_p.h +++ b/src/qmlworkerscript/qquickworkerscript_p.h @@ -84,7 +84,7 @@ Q_OBJECT }; class QQmlV4Function; -class Q_AUTOTEST_EXPORT QQuickWorkerScript : public QObject, public QQmlParserStatus +class Q_QMLWORKERSCRIPT_PRIVATE_EXPORT QQuickWorkerScript : public QObject, public QQmlParserStatus { Q_OBJECT Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) diff --git a/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h b/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h index c75d5f31293..34236cd79ee 100644 --- a/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h +++ b/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h @@ -57,6 +57,4 @@ #define Q_QMLWORKERSCRIPT_PRIVATE_EXPORT Q_QMLWORKERSCRIPT_EXPORT #define Q_QMLWORKERSCRIPT_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT -void Q_QMLWORKERSCRIPT_PRIVATE_EXPORT qml_register_types_QtQml_WorkerScript(); - #endif // QTQMLWORKERSCRIPTGLOBAL_P_H diff --git a/src/qmlxmllistmodel/qqmlxmllistmodel.cpp b/src/qmlxmllistmodel/qqmlxmllistmodel.cpp index af8f434c072..d1f4052a9a4 100644 --- a/src/qmlxmllistmodel/qqmlxmllistmodel.cpp +++ b/src/qmlxmllistmodel/qqmlxmllistmodel.cpp @@ -112,7 +112,7 @@ void QQmlXmlListModelRole::setName(const QString &name) /*! \qmlproperty string QtQml.XmlListModel::XmlListModelRole::elementName - The name of the xml element, or a path to the xml element, that will be + The name of the XML element, or a path to the XML element, that will be used to read the data. The element must actually contain text. Optionally the \l attributeName property can be specified to extract @@ -120,8 +120,8 @@ void QQmlXmlListModelRole::setName(const QString &name) //! [basic-example] For example, the following model has a role named "title", which reads the - data from the xml element \c {}. It also has another role named - "timestamp", which uses the same xml element \c {<title>}, but reads its + data from the XML element \c {<title>}. It also has another role named + "timestamp", which uses the same XML element \c {<title>}, but reads its "created" attribute to extract the actual value. \qml @@ -147,7 +147,7 @@ void QQmlXmlListModelRole::setName(const QString &name) //! [empty-elementName-example] When the \l attributeName is specified, the \l elementName can be left - empty. In this case the attribute of the top level xml element of the query + empty. In this case the attribute of the top level XML element of the query will be read. For example, if you have the following xml document: @@ -224,13 +224,13 @@ QString QQmlXmlListModelRole::elementName() const void QQmlXmlListModelRole::setElementName(const QString &name) { if (name.startsWith(QLatin1Char('/'))) { - qmlWarning(this) << tr("An xml element must not start with '/'"); + qmlWarning(this) << tr("An XML element must not start with '/'"); return; } else if (name.endsWith(QLatin1Char('/'))) { - qmlWarning(this) << tr("An xml element must not end with '/'"); + qmlWarning(this) << tr("An XML element must not end with '/'"); return; } else if (name.contains(QStringLiteral("//"))) { - qmlWarning(this) << tr("An xml element must not contain \"//\""); + qmlWarning(this) << tr("An XML element must not contain \"//\""); return; } @@ -243,14 +243,14 @@ void QQmlXmlListModelRole::setElementName(const QString &name) /*! \qmlproperty string QtQml.XmlListModel::XmlListModelRole::attributeName - The attribute of the xml element that will be used to read the data. - The xml element is specified by \l elementName property. + The attribute of the XML element that will be used to read the data. + The XML element is specified by \l elementName property. \include qqmlxmllistmodel.cpp basic-example \include qqmlxmllistmodel.cpp empty-elementName-example - If you do not need to parse any attributes for the specified xml element, + If you do not need to parse any attributes for the specified XML element, simply leave this property blank. \sa elementName @@ -583,14 +583,12 @@ int QQmlXmlListModel::nextQueryId() \qmlproperty enumeration QtQml.XmlListModel::XmlListModel::status Specifies the model loading status, which can be one of the following: - \list - \li XmlListModel.Null - No XML data has been set for this model. - \li XmlListModel.Ready - The XML data has been loaded into the model. - \li XmlListModel.Loading - The model is in the process of reading and - loading XML data. - \li XmlListModel.Error - An error occurred while the model was loading. See - \l errorString() for details about the error. - \endlist + \value XmlListModel.Null No XML data has been set for this model. + \value XmlListModel.Ready The XML data has been loaded into the model. + \value XmlListModel.Loading The model is in the process of reading and + loading XML data. + \value XmlListModel.Error An error occurred while the model was loading. See + \l errorString() for details about the error. \sa progress */ @@ -991,3 +989,5 @@ void QQmlXmlListModelQueryRunnable::readSubTree(const QString &prefix, QXmlStrea } QT_END_NAMESPACE + +#include "moc_qqmlxmllistmodel_p.cpp" diff --git a/src/qmlxmllistmodel/qtqmlxmllistmodelglobal_p.h b/src/qmlxmllistmodel/qtqmlxmllistmodelglobal_p.h index 068732cc05f..d124891ef33 100644 --- a/src/qmlxmllistmodel/qtqmlxmllistmodelglobal_p.h +++ b/src/qmlxmllistmodel/qtqmlxmllistmodelglobal_p.h @@ -69,6 +69,4 @@ QT_BEGIN_NAMESPACE QT_END_NAMESPACE -void Q_QMLXMLLISTMODEL_PRIVATE_EXPORT qml_register_types_QtQml_XmlListModel(); - #endif // QTQMLXMLLISTMODELGLOBAL_P_H diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index 2c2324d896c..372df6cfd87 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -237,7 +237,7 @@ qt_internal_add_shaders(Quick "scenegraph_shaders" PRECOMPILE OPTIMIZED PREFIX - "/qt-project.org/scenegraph/shaders_ng" + "/qt-project.org" FILES "scenegraph/shaders_ng/24bittextmask.frag" "scenegraph/shaders_ng/32bitcolortext.frag" @@ -345,7 +345,6 @@ qt_internal_extend_target(Quick CONDITION QT_FEATURE_quick_designer designer/qquickdesignersupportproperties.cpp designer/qquickdesignersupportproperties_p.h designer/qquickdesignersupportpropertychanges.cpp designer/qquickdesignersupportpropertychanges_p.h designer/qquickdesignersupportstates.cpp designer/qquickdesignersupportstates_p.h - designer/qquickdesignerwindowmanager.cpp designer/qquickdesignerwindowmanager_p.h ) qt_internal_extend_target(Quick CONDITION QT_FEATURE_accessibility diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp index 5e3a1108d65..ed681273fa7 100644 --- a/src/quick/accessible/qaccessiblequickitem.cpp +++ b/src/quick/accessible/qaccessiblequickitem.cpp @@ -145,7 +145,7 @@ QWindow *QAccessibleHyperlink::window() const } -/*! \reimp */ +/* \reimp */ QRect QAccessibleHyperlink::rect() const { const QVector<QQuickTextPrivate::LinkDesc> links = QQuickTextPrivate::get(textItem())->getLinks(); @@ -156,37 +156,37 @@ QRect QAccessibleHyperlink::rect() const return QRect(); } -/*! \reimp */ +/* \reimp */ QAccessibleInterface *QAccessibleHyperlink::childAt(int, int) const { return nullptr; } -/*! \reimp */ +/* \reimp */ QAccessibleInterface *QAccessibleHyperlink::parent() const { return QAccessible::queryAccessibleInterface(textItem()); } -/*! \reimp */ +/* \reimp */ QAccessibleInterface *QAccessibleHyperlink::child(int) const { return nullptr; } -/*! \reimp */ +/* \reimp */ int QAccessibleHyperlink::childCount() const { return 0; } -/*! \reimp */ +/* \reimp */ int QAccessibleHyperlink::indexOfChild(const QAccessibleInterface *) const { return -1; } -/*! \reimp */ +/* \reimp */ QAccessible::State QAccessibleHyperlink::state() const { QAccessible::State s; @@ -197,13 +197,13 @@ QAccessible::State QAccessibleHyperlink::state() const return s; } -/*! \reimp */ +/* \reimp */ QAccessible::Role QAccessibleHyperlink::role() const { return QAccessible::Link; } -/*! \reimp */ +/* \reimp */ QString QAccessibleHyperlink::text(QAccessible::Text t) const { // AT servers have different behaviors: @@ -221,13 +221,13 @@ QString QAccessibleHyperlink::text(QAccessible::Text t) const return QString(); } -/*! \reimp */ +/* \reimp */ void QAccessibleHyperlink::setText(QAccessible::Text, const QString &) { } -/*! \reimp */ +/* \reimp */ void *QAccessibleHyperlink::interface_cast(QAccessible::InterfaceType t) { if (t == QAccessible::HyperlinkInterface) @@ -448,6 +448,11 @@ QList<QQuickItem *> QAccessibleQuickItem::childItems() const return accessibleUnignoredChildren(item()); } +static bool isTextRole(QAccessible::Role role) +{ + return role == QAccessible::EditableText || role == QAccessible::StaticText; +} + QAccessible::State QAccessibleQuickItem::state() const { QQuickAccessibleAttached *attached = QQuickAccessibleAttached::attachedProperties(item()); @@ -465,7 +470,7 @@ QAccessible::State QAccessibleQuickItem::state() const state.offscreen = true; if ((role() == QAccessible::CheckBox || role() == QAccessible::RadioButton) && object()->property("checked").toBool()) state.checked = true; - if (item()->activeFocusOnTab() || role() == QAccessible::EditableText) + if (item()->activeFocusOnTab() || isTextRole(role())) state.focusable = true; if (item()->hasActiveFocus()) state.focused = true; @@ -483,7 +488,7 @@ QAccessible::Role QAccessibleQuickItem::role() const QAccessible::Role role = QAccessible::NoRole; if (item()) - role = QQuickItemPrivate::get(item())->accessibleRole(); + role = QQuickItemPrivate::get(item())->effectiveAccessibleRole(); if (role == QAccessible::NoRole) { if (qobject_cast<QQuickText*>(const_cast<QQuickItem *>(item()))) role = QAccessible::StaticText; diff --git a/src/quick/configure.json b/src/quick/configure.json deleted file mode 100644 index d29f8e3eaf5..00000000000 --- a/src/quick/configure.json +++ /dev/null @@ -1,203 +0,0 @@ -{ - "module": "quick", - "depends": [ - "core-private", - "qml-private", - "gui", - "gui-private", - "qmlmodels-private" - ], - "condition": "module.gui", - "testDir": "../../config.tests", - - "commandline": { - "options": { - "quick-animatedimage": "boolean", - "quick-canvas": "boolean", - "quick-designer": "boolean", - "quick-flipable": "boolean", - "quick-gridview": "boolean", - "quick-listview": "boolean", - "quick-tableview": "boolean", - "quick-path": "boolean", - "quick-pathview": "boolean", - "quick-positioners": "boolean", - "quick-shadereffect": "boolean", - "quick-sprite": "boolean" - } - }, - - "features": { - "quick-animatedimage": { - "label": "AnimatedImage item", - "purpose": "Provides the AnimatedImage item.", - "section": "Qt Quick", - "condition": "module.gui && features.movie", - "output": [ - "privateFeature" - ] - }, - "quick-canvas": { - "label": "Canvas item", - "purpose": "Provides the Canvas item.", - "section": "Qt Quick", - "condition": "features.quick-path", - "output": [ - "privateFeature" - ] - }, - "quick-designer": { - "label": "Support for Qt Quick Designer", - "purpose": "Provides support for the Qt Quick Designer in Qt Creator.", - "section": "Qt Quick", - "output": [ - "privateFeature" - ] - }, - "quick-flipable": { - "label": "Flipable item", - "purpose": "Provides the Flipable item.", - "section": "Qt Quick", - "output": [ - "privateFeature" - ] - }, - "quick-gridview": { - "label": "GridView item", - "purpose": "Provides the GridView item.", - "section": "Qt Quick", - "condition": "features.qml-delegate-model", - "output": [ - "privateFeature" - ] - }, - "quick-itemview": { - "label": "ItemView item", - "condition": "features.quick-gridview || features.quick-listview || features.quick-tableview", - "output": [ - "privateFeature" - ] - }, - "quick-viewtransitions": { - "label": "Transitions required for ItemViews and Positioners", - "condition": "features.quick-itemview || features.quick-positioners", - "output": [ - "privateFeature" - ] - }, - "quick-listview": { - "label": "ListView item", - "purpose": "Provides the ListView item.", - "section": "Qt Quick", - "condition": "features.qml-delegate-model", - "output": [ - "privateFeature" - ] - }, - "quick-tableview": { - "label": "TableView item", - "purpose": "Provides the TableView item.", - "section": "Qt Quick", - "condition": "features.qml-table-model", - "output": [ - "privateFeature" - ] - }, - "quick-particles": { - "label": "Particle support", - "purpose": "Provides a particle system.", - "section": "Qt Quick", - "condition": "module.gui && features.quick-shadereffect && features.quick-sprite", - "output": [ - "privateFeature" - ] - }, - "quick-path": { - "label": "Path support", - "purpose": "Provides Path elements.", - "section": "Qt Quick", - "condition": "module.gui", - "output": [ - "privateFeature" - ] - }, - "quick-pathview": { - "label": "PathView item", - "purpose": "Provides the PathView item.", - "section": "Qt Quick", - "condition": [ - "features.qml-delegate-model", - "features.quick-path" - ], - "output": [ - "privateFeature" - ] - }, - "quick-positioners": { - "label": "Positioner items", - "purpose": "Provides Positioner items.", - "section": "Qt Quick", - "output": [ - "privateFeature" - ] - }, - "quick-repeater": { - "label": "Repeater item", - "purpose": "Provides the Repeater item.", - "section": "Qt Quick", - "condition": "features.qml-delegate-model", - "output": [ - "privateFeature" - ] - }, - "quick-shadereffect": { - "label": "ShaderEffect item", - "purpose": "Provides Shader effects.", - "section": "Qt Quick", - "output": [ - "privateFeature" - ] - }, - "quick-sprite": { - "label": "Sprite item", - "purpose": "Provides the Sprite item.", - "section": "Qt Quick", - "output": [ - "privateFeature" - ] - }, - "quick-draganddrop": { - "label": "Drag & Drop", - "purpose": "Drag and drop support for Qt Quick", - "section": "Qt Quick", - "condition": [ - "features.draganddrop", - "features.regularexpression" - ], - "output": [ - "publicFeature" - ] - } - }, - - "summary": [ - { - "section": "Qt Quick", - "entries": [ - "quick-animatedimage", - "quick-canvas", - "quick-designer", - "quick-flipable", - "quick-gridview", - "quick-listview", - "quick-tableview", - "quick-path", - "quick-pathview", - "quick-positioners", - "quick-repeater", - "quick-shadereffect", - "quick-sprite" - ] - } - ] -} diff --git a/src/quick/designer/qquickdesignersupport.cpp b/src/quick/designer/qquickdesignersupport.cpp index a2820fbba2a..24b22a2d0f8 100644 --- a/src/quick/designer/qquickdesignersupport.cpp +++ b/src/quick/designer/qquickdesignersupport.cpp @@ -47,7 +47,6 @@ #include <QtQml/private/qabstractanimationjob_p.h> #include <private/qqmlengine_p.h> #include <private/qquickview_p.h> -#include <private/qsgrenderloop_p.h> #include <QtQuick/private/qquickstategroup_p.h> #include <QtGui/QImage> #include <private/qqmlvme_p.h> @@ -55,9 +54,6 @@ #include <private/qqmldata_p.h> #include <private/qsgadaptationlayer_p.h> -#include "qquickdesignerwindowmanager_p.h" - - QT_BEGIN_NAMESPACE QQuickDesignerSupport::QQuickDesignerSupport() @@ -439,12 +435,12 @@ void QQuickDesignerSupport::setRootItem(QQuickView *view, QQuickItem *item) bool QQuickDesignerSupport::isValidWidth(QQuickItem *item) { - return QQuickItemPrivate::get(item)->heightValid; + return QQuickItemPrivate::get(item)->heightValid(); } bool QQuickDesignerSupport::isValidHeight(QQuickItem *item) { - return QQuickItemPrivate::get(item)->widthValid; + return QQuickItemPrivate::get(item)->widthValid(); } void QQuickDesignerSupport::updateDirtyNode(QQuickItem *item) @@ -453,11 +449,6 @@ void QQuickDesignerSupport::updateDirtyNode(QQuickItem *item) QQuickWindowPrivate::get(item->window())->updateDirtyNode(item); } -void QQuickDesignerSupport::activateDesignerWindowManager() -{ - QSGRenderLoop::setInstance(new QQuickDesignerWindowManager); -} - void QQuickDesignerSupport::activateDesignerMode() { QQmlEnginePrivate::activateDesignerMode(); @@ -473,11 +464,6 @@ void QQuickDesignerSupport::enableComponentComplete() QQmlVME::enableComponentComplete(); } -void QQuickDesignerSupport::createOpenGLContext(QQuickWindow *window) -{ - QQuickDesignerWindowManager::createOpenGLContext(window); -} - void QQuickDesignerSupport::polishItems(QQuickWindow *window) { QQuickWindowPrivate::get(window)->polishItems(); diff --git a/src/quick/designer/qquickdesignersupport_p.h b/src/quick/designer/qquickdesignersupport_p.h index fc46745e154..6d2da6aa350 100644 --- a/src/quick/designer/qquickdesignersupport_p.h +++ b/src/quick/designer/qquickdesignersupport_p.h @@ -143,14 +143,11 @@ class Q_QUICK_EXPORT QQuickDesignerSupport static void updateDirtyNode(QQuickItem *item); - static void activateDesignerWindowManager(); static void activateDesignerMode(); static void disableComponentComplete(); static void enableComponentComplete(); - static void createOpenGLContext(QQuickWindow *window); - static void polishItems(QQuickWindow *window); private: diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp index 862b57f2b7e..8a452093637 100644 --- a/src/quick/designer/qquickdesignersupportitems.cpp +++ b/src/quick/designer/qquickdesignersupportitems.cpp @@ -72,7 +72,6 @@ static void stopAnimation(QObject *object) // QQuickScriptAction *scriptAimation = qobject_cast<QQuickScriptAction*>(animation); // if (scriptAimation) FIXME // scriptAimation->setScript(QQmlScriptString()); - animation->setLoops(1); animation->complete(); animation->setDisableUserControl(); } else if (timer) { diff --git a/src/quick/designer/qquickdesignersupportproperties.cpp b/src/quick/designer/qquickdesignersupportproperties.cpp index c9b042a1efe..9239f388a8c 100644 --- a/src/quick/designer/qquickdesignersupportproperties.cpp +++ b/src/quick/designer/qquickdesignersupportproperties.cpp @@ -126,16 +126,15 @@ void QQuickDesignerSupportProperties::getPropertyCache(QObject *object, QQmlEngi QQmlEnginePrivate::get(engine)->cache(object->metaObject()); } -QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::propertyNameListForWritableProperties(QObject *object, +static QQuickDesignerSupport::PropertyNameList propertyNameListForWritableProperties(QObject *object, const QQuickDesignerSupport::PropertyName &baseName, - QObjectList *inspectedObjects) + QObjectList *inspectedObjects, + int depth = 0) { QQuickDesignerSupport::PropertyNameList propertyNameList; - QObjectList localObjectList; - - if (inspectedObjects == nullptr) - inspectedObjects = &localObjectList; + if (depth > 2) + return propertyNameList; if (!inspectedObjects->contains(object)) inspectedObjects->append(object); @@ -150,14 +149,16 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::propert if (childObject) propertyNameList.append(propertyNameListForWritableProperties(childObject, baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()) - + '.', inspectedObjects)); + + '.', inspectedObjects, + depth + 1)); } } else if (QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.metaType())) { valueType->setValue(metaProperty.read(object)); propertyNameList.append(propertyNameListForWritableProperties(valueType, baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()) - + '.', inspectedObjects)); + + '.', inspectedObjects, + depth + 1)); } if (metaProperty.isReadable() && metaProperty.isWritable()) { @@ -169,6 +170,12 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::propert return propertyNameList; } +QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::propertyNameListForWritableProperties(QObject *object) +{ + QObjectList localObjectList; + return ::propertyNameListForWritableProperties(object, {}, &localObjectList); +} + bool QQuickDesignerSupportProperties::isPropertyBlackListed(const QQuickDesignerSupport::PropertyName &propertyName) { if (propertyName.contains(".") && propertyName.contains("__")) @@ -182,7 +189,8 @@ bool QQuickDesignerSupportProperties::isPropertyBlackListed(const QQuickDesigner QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allPropertyNames(QObject *object, const QQuickDesignerSupport::PropertyName &baseName, - QObjectList *inspectedObjects) + QObjectList *inspectedObjects, + int depth) { QQuickDesignerSupport::PropertyNameList propertyNameList; @@ -191,6 +199,9 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allProp if (inspectedObjects == nullptr) inspectedObjects = &localObjectList; + if (depth > 2) + return propertyNameList; + if (!inspectedObjects->contains(object)) inspectedObjects->append(object); @@ -214,7 +225,8 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allProp propertyNameList.append(allPropertyNames(childObject, baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()) - + '.', inspectedObjects)); + + '.', inspectedObjects, + depth + 1)); } } else if (QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.metaType())) { @@ -223,7 +235,8 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allProp propertyNameList.append(allPropertyNames(valueType, baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()) - + '.', inspectedObjects)); + + '.', inspectedObjects, + depth + 1)); } else { addToPropertyNameListIfNotBlackListed(&propertyNameList, baseName + QQuickDesignerSupport::PropertyName(metaProperty.name())); diff --git a/src/quick/designer/qquickdesignersupportproperties_p.h b/src/quick/designer/qquickdesignersupportproperties_p.h index 02e75ea8866..5970eca9f1e 100644 --- a/src/quick/designer/qquickdesignersupportproperties_p.h +++ b/src/quick/designer/qquickdesignersupportproperties_p.h @@ -90,12 +90,11 @@ class Q_QUICK_EXPORT QQuickDesignerSupportProperties static void getPropertyCache(QObject *object, QQmlEngine *engine); static bool isPropertyBlackListed(const QQuickDesignerSupport::PropertyName &propertyName); - static QQuickDesignerSupport::PropertyNameList propertyNameListForWritableProperties(QObject *object, - const QQuickDesignerSupport::PropertyName &baseName = QQuickDesignerSupport::PropertyName(), - QObjectList *inspectedObjects = nullptr); + static QQuickDesignerSupport::PropertyNameList propertyNameListForWritableProperties(QObject *object); static QQuickDesignerSupport::PropertyNameList allPropertyNames(QObject *object, const QQuickDesignerSupport::PropertyName &baseName = QQuickDesignerSupport::PropertyName(), - QObjectList *inspectedObjects = nullptr); + QObjectList *inspectedObjects = nullptr, + int depth = 0); static bool hasFullImplementedListInterface(const QQmlListReference &list); }; diff --git a/src/quick/designer/qquickdesignerwindowmanager.cpp b/src/quick/designer/qquickdesignerwindowmanager.cpp deleted file mode 100644 index 18daab70e8a..00000000000 --- a/src/quick/designer/qquickdesignerwindowmanager.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module 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 "qquickdesignerwindowmanager_p.h" -#include "private/qquickwindow_p.h" -#include "private/qquickitem_p.h" -#include <QtQuick/QQuickWindow> -#if QT_CONFIG(opengl) -#include <private/qsgdefaultrendercontext_p.h> -#endif - -QT_BEGIN_NAMESPACE - -QQuickDesignerWindowManager::QQuickDesignerWindowManager() - : m_sgContext(QSGContext::createDefaultContext()) -{ - m_renderContext.reset(m_sgContext.data()->createRenderContext()); -} - -void QQuickDesignerWindowManager::show(QQuickWindow *window) -{ - makeOpenGLContext(window); -} - -void QQuickDesignerWindowManager::hide(QQuickWindow *) -{ -} - -void QQuickDesignerWindowManager::windowDestroyed(QQuickWindow *) -{ -} - -void QQuickDesignerWindowManager::makeOpenGLContext(QQuickWindow *window) -{ -#if QT_CONFIG(opengl) - if (!m_openGlContext) { - m_openGlContext.reset(new QOpenGLContext()); - m_openGlContext->setFormat(window->requestedFormat()); - m_openGlContext->create(); - if (!m_openGlContext->makeCurrent(window)) - qWarning("QQuickWindow: makeCurrent() failed..."); - QSGDefaultRenderContext::InitParams params; - params.sampleCount = qMax(1, m_openGlContext->format().samples()); - // ### glpurge Designer's RHI migration is left as a future exercise (QTBUG-78598) - //params.openGLContext = m_openGlContext.data(); - params.initialSurfacePixelSize = window->size() * window->effectiveDevicePixelRatio(); - params.maybeSurface = window; - m_renderContext->initialize(¶ms); - } else { - m_openGlContext->makeCurrent(window); - } -#else - Q_UNUSED(window); -#endif -} - -void QQuickDesignerWindowManager::exposureChanged(QQuickWindow *) -{ -} - -QImage QQuickDesignerWindowManager::grab(QQuickWindow *) -{ - return QImage(); -} - -void QQuickDesignerWindowManager::maybeUpdate(QQuickWindow *) -{ -} - -QSGContext *QQuickDesignerWindowManager::sceneGraphContext() const -{ - return m_sgContext.data(); -} - -void QQuickDesignerWindowManager::createOpenGLContext(QQuickWindow *window) -{ - window->create(); - window->update(); -} - -void QQuickDesignerWindowManager::update(QQuickWindow *window) -{ - makeOpenGLContext(window); -} - -QT_END_NAMESPACE - - -#include "moc_qquickdesignerwindowmanager_p.cpp" diff --git a/src/quick/designer/qquickdesignerwindowmanager_p.h b/src/quick/designer/qquickdesignerwindowmanager_p.h deleted file mode 100644 index ac9695953f2..00000000000 --- a/src/quick/designer/qquickdesignerwindowmanager_p.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module 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 DESIGNERWINDOWMANAGER_P_H -#define DESIGNERWINDOWMANAGER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/QScopedPointer> - -#include <private/qsgrenderloop_p.h> -#include <private/qtquickglobal_p.h> -#include <private/qsgcontext_p.h> - -#if QT_CONFIG(opengl) -# include <QOpenGLContext> -#endif - -QT_BEGIN_NAMESPACE - -class QQuickWindow; -class QSGContext; -class QSGDefaultRenderContext; -class QAnimationDriver; - -class QQuickDesignerWindowManager : public QSGRenderLoop -{ - Q_OBJECT -public: - QQuickDesignerWindowManager(); - - void show(QQuickWindow *window) override; - void hide(QQuickWindow *window) override; - - void windowDestroyed(QQuickWindow *window) override; - - void makeOpenGLContext(QQuickWindow *window); - void exposureChanged(QQuickWindow *window) override; - QImage grab(QQuickWindow *window) override; - - void maybeUpdate(QQuickWindow *window) override; - void update(QQuickWindow *window) override; // identical for this implementation. - - void releaseResources(QQuickWindow *) override { } - - QAnimationDriver *animationDriver() const override { return nullptr; } - - QSGContext *sceneGraphContext() const override; - QSGRenderContext *createRenderContext(QSGContext *) const override { return m_renderContext.data(); } - - static void createOpenGLContext(QQuickWindow *window); - -private: -#if QT_CONFIG(opengl) - QScopedPointer<QOpenGLContext> m_openGlContext; -#endif - QScopedPointer<QSGContext> m_sgContext; - QScopedPointer<QSGRenderContext> m_renderContext; -}; - -QT_END_NAMESPACE - -#endif // DESIGNERWINDOWMANAGER_P_H diff --git a/src/quick/doc/images/containmentMask-circle.gif b/src/quick/doc/images/containmentMask-circle.gif new file mode 100644 index 00000000000..80abce625f3 Binary files /dev/null and b/src/quick/doc/images/containmentMask-circle.gif differ diff --git a/src/quick/doc/images/containmentMask-shape.gif b/src/quick/doc/images/containmentMask-shape.gif new file mode 100644 index 00000000000..e7989352eb0 Binary files /dev/null and b/src/quick/doc/images/containmentMask-shape.gif differ diff --git a/src/quick/doc/images/declarative-scalegrid.png b/src/quick/doc/images/declarative-scalegrid.png index 32d87125681..69ad06f8346 100644 Binary files a/src/quick/doc/images/declarative-scalegrid.png and b/src/quick/doc/images/declarative-scalegrid.png differ diff --git a/src/quick/doc/images/pointerHandlers/tapHandlerButtonReleaseWithinBounds.webp b/src/quick/doc/images/pointerHandlers/tapHandlerButtonReleaseWithinBounds.webp new file mode 100644 index 00000000000..3edab7d7a1a Binary files /dev/null and b/src/quick/doc/images/pointerHandlers/tapHandlerButtonReleaseWithinBounds.webp differ diff --git a/src/quick/doc/images/pointerHandlers/tapHandlerButtonWithinBounds.webp b/src/quick/doc/images/pointerHandlers/tapHandlerButtonWithinBounds.webp new file mode 100644 index 00000000000..05cb2f2276b Binary files /dev/null and b/src/quick/doc/images/pointerHandlers/tapHandlerButtonWithinBounds.webp differ diff --git a/src/quick/doc/images/pointerHandlers/tapHandlerOverlappingButtons.webp b/src/quick/doc/images/pointerHandlers/tapHandlerOverlappingButtons.webp new file mode 100644 index 00000000000..0455097159d Binary files /dev/null and b/src/quick/doc/images/pointerHandlers/tapHandlerOverlappingButtons.webp differ diff --git a/src/quick/doc/images/qml-borderimage-rounded.png b/src/quick/doc/images/qml-borderimage-rounded.png new file mode 100644 index 00000000000..562fc277bbd Binary files /dev/null and b/src/quick/doc/images/qml-borderimage-rounded.png differ diff --git a/src/quick/doc/images/qml-borderimage-scaled.png b/src/quick/doc/images/qml-borderimage-scaled.png index e42891ecc7e..230e8a010e6 100644 Binary files a/src/quick/doc/images/qml-borderimage-scaled.png and b/src/quick/doc/images/qml-borderimage-scaled.png differ diff --git a/src/quick/doc/images/qml-borderimage-tiled.png b/src/quick/doc/images/qml-borderimage-tiled.png index e27d9601c4f..f7523e8e94f 100644 Binary files a/src/quick/doc/images/qml-borderimage-tiled.png and b/src/quick/doc/images/qml-borderimage-tiled.png differ diff --git a/src/quick/doc/images/qml-item-canvas-startAngle.png b/src/quick/doc/images/qml-item-canvas-startAngle.png index bf82c3aa4bc..7930284896d 100644 Binary files a/src/quick/doc/images/qml-item-canvas-startAngle.png and b/src/quick/doc/images/qml-item-canvas-startAngle.png differ diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf index 7340413d3f5..ff4fbbc38df 100644 --- a/src/quick/doc/qtquick.qdocconf +++ b/src/quick/doc/qtquick.qdocconf @@ -30,18 +30,19 @@ qhp.QtQuick.subprojects.qmltypes.sortPages = true qhp.QtQuick.subprojects.classes.title = Classes qhp.QtQuick.subprojects.classes.title = C++ Classes qhp.QtQuick.subprojects.classes.indexTitle = Qt Quick C++ Classes -qhp.QtQuick.subprojects.classes.selectors = class fake:headerfile +qhp.QtQuick.subprojects.classes.selectors = class doc:headerfile qhp.QtQuick.subprojects.classes.sortPages = true qhp.QtQuick.subprojects.examples.title = Examples qhp.QtQuick.subprojects.examples.indexTitle = Qt Quick Examples and Tutorials -qhp.QtQuick.subprojects.examples.selectors = fake:example +qhp.QtQuick.subprojects.examples.selectors = doc:example -tagfile = ../../../doc/qtquick/qtquick.tags +tagfile = qtquick.tags depends += \ qtcore \ qtqml \ qtqmlmodels \ + qtqmlxmllistmodel \ qtqmltest \ qtgui \ qtlinguist \ @@ -57,35 +58,37 @@ depends += \ qtcmake {headerdirs,sourcedirs} += \ - ..\ + .. \ ../../quick \ ../../quickwidgets \ ../../qmllocalstorage \ ../../quicklayouts \ - ../../labs/animation \ - ../../labs/folderlistmodel + ../../labs -exampledirs += ../../../examples/quick \ - snippets +# both have their own documentation project +excludedirs += \ + ../../labs/platform \ + ../../labs/models -imagedirs += images +exampledirs += \ + ../../../examples/quick \ + ../../qmlmodels/doc/snippets \ + snippets -#add particles and shapes sources -headerdirs += ../../particles \ - ../../quickshapes -sourcedirs += ../../particles \ - ../../quickshapes +imagedirs += images -#add imports directory because of dependencies -headerdirs += ../../imports -sourcedirs += ../../imports +# Add particles and shapes sources +{headerdirs,sourcedirs} += \ + ../../particles \ + ../../quickshapes -#add plugins directory because of dependencies -headerdirs += ../../plugins -sourcedirs += ../../plugins +# Add imports and plugins directories because of dependencies +{headerdirs,sourcedirs} += \ + ../../imports \ + ../../plugins excludefiles += ../util/qquickpropertychanges_p.h -examples.fileextensions += "*.qm" +examples.fileextensions += "*.qm" manifestmeta.thumbnail.names += "QtQuick/Threaded ListModel Example" \ "QtQuick/QML Dynamic View Ordering Tutorial*" @@ -99,6 +102,5 @@ navigation.qmltypespage = "Qt Quick QML Types" # \svgcolor {#ffdead} macro.svgcolor.HTML = "<div style=\"padding:10px;color:#fff;background:\1;\"></div>" -# youtube video thumbnails that show up in offline and online docs -HTML.extraimages += images/9BcAYDlpuT8.jpg -qhp.QtQuick.extraFiles += images/9BcAYDlpuT8.jpg +# YouTube video thumbnail that show up in offline docs +{HTML.extraimages,qhp.QtQuick.extraFiles} += images/9BcAYDlpuT8.jpg diff --git a/src/quick/doc/snippets/cmake-macros/examples.cmake b/src/quick/doc/snippets/cmake-macros/examples.cmake deleted file mode 100644 index cecc59debc2..00000000000 --- a/src/quick/doc/snippets/cmake-macros/examples.cmake +++ /dev/null @@ -1,6 +0,0 @@ -#! [qt5_import_qml_plugins] -find_package(Qt5 COMPONENTS Quick QmlImportScanner) -add_executable(myapp main.cpp) -target_link_libraries(myapp Qt5::Quick) -qt5_import_qml_plugins(myapp) -#! [qt5_import_qml_plugins] diff --git a/src/quick/doc/snippets/code/doc_src_qtquick.cmake b/src/quick/doc/snippets/code/doc_src_qtquick.cmake index f575b40accf..733145fdc5e 100644 --- a/src/quick/doc/snippets/code/doc_src_qtquick.cmake +++ b/src/quick/doc/snippets/code/doc_src_qtquick.cmake @@ -1,4 +1,4 @@ #! [0] -find_package(Qt6 COMPONENTS Quick REQUIRED) +find_package(Qt6 REQUIRED COMPONENTS Quick) target_link_libraries(mytarget PRIVATE Qt6::Quick) #! [0] diff --git a/src/quick/doc/snippets/pointerHandlers/hoverModifiers.qml b/src/quick/doc/snippets/pointerHandlers/hoverModifiers.qml new file mode 100644 index 00000000000..b8a378ddcff --- /dev/null +++ b/src/quick/doc/snippets/pointerHandlers/hoverModifiers.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick + +Rectangle { + width: 150; height: 50; radius: 3 + color: control.hovered ? "goldenrod" : shift.hovered ? "wheat" : "beige" + + HoverHandler { + id: control + acceptedModifiers: Qt.ControlModifier + cursorShape: Qt.PointingHandCursor + } + + HoverHandler { + id: shift + acceptedModifiers: Qt.ShiftModifier + cursorShape: Qt.CrossCursor + } +} +//![0] diff --git a/src/quick/doc/snippets/pointerHandlers/hoverMouseOrStylus.qml b/src/quick/doc/snippets/pointerHandlers/hoverMouseOrStylus.qml new file mode 100644 index 00000000000..6bd6a40b1a1 --- /dev/null +++ b/src/quick/doc/snippets/pointerHandlers/hoverMouseOrStylus.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick + +Rectangle { + width: 150; height: 50; radius: 3 + color: mouse.hovered ? "goldenrod" : stylus.hovered ? "tomato" : "wheat" + + HoverHandler { + id: stylus + acceptedDevices: PointerDevice.Stylus + cursorShape: Qt.CrossCursor + } + + HoverHandler { + id: mouse + acceptedDevices: PointerDevice.Mouse + cursorShape: Qt.PointingHandCursor + } +} +//![0] diff --git a/src/quick/doc/snippets/pointerHandlers/hoverStylusOrEraser.qml b/src/quick/doc/snippets/pointerHandlers/hoverStylusOrEraser.qml new file mode 100644 index 00000000000..5d82158bafa --- /dev/null +++ b/src/quick/doc/snippets/pointerHandlers/hoverStylusOrEraser.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick + +Rectangle { + id: rect + width: 150; height: 150 + + HoverHandler { + id: stylus + acceptedPointerTypes: PointerDevice.Pen + cursorShape: Qt.CrossCursor + } + + HoverHandler { + id: eraser + acceptedPointerTypes: PointerDevice.Eraser + cursorShape: Qt.BlankCursor + target: Image { + parent: rect + source: "images/cursor-eraser.png" + visible: eraser.hovered + x: eraser.point.position.x + y: eraser.point.position.y - 32 + } + } +} +//![0] diff --git a/src/quick/doc/snippets/pointerHandlers/hoverTapKeyButton.qml b/src/quick/doc/snippets/pointerHandlers/hoverTapKeyButton.qml new file mode 100644 index 00000000000..1564aa16b50 --- /dev/null +++ b/src/quick/doc/snippets/pointerHandlers/hoverTapKeyButton.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick 2.12 + +Rectangle { + id: button + signal clicked + + width: 150; height: 50; radius: 3 + color: tapHandler.pressed ? "goldenrod" : hoverHandler.hovered ? "wheat" : "beige" + border.color: activeFocus ? "brown" : "transparent" + focus: true + + HoverHandler { + id: hoverHandler + } + + TapHandler { + id: tapHandler + onTapped: button.clicked() + } + + Keys.onEnterPressed: button.clicked() +} +//![0] diff --git a/src/quick/doc/snippets/pointerHandlers/images/cursor-eraser.png b/src/quick/doc/snippets/pointerHandlers/images/cursor-eraser.png new file mode 100644 index 00000000000..e5488a89f24 Binary files /dev/null and b/src/quick/doc/snippets/pointerHandlers/images/cursor-eraser.png differ diff --git a/src/quick/doc/snippets/pointerHandlers/pointHandler.qml b/src/quick/doc/snippets/pointerHandlers/pointHandler.qml index 20be1201205..138ad332d92 100644 --- a/src/quick/doc/snippets/pointerHandlers/pointHandler.qml +++ b/src/quick/doc/snippets/pointerHandlers/pointHandler.qml @@ -48,8 +48,7 @@ ** ****************************************************************************/ //![0] -import QtQuick 2.12 -import QtQuick.Window 2.2 +import QtQuick Window { width: 480 @@ -61,6 +60,7 @@ Window { z: 10000 anchors.fill: parent + //![1] PointHandler { id: handler acceptedDevices: PointerDevice.TouchScreen | PointerDevice.TouchPad @@ -73,6 +73,7 @@ Window { width: 20; height: width; radius: width / 2 } } + //![1] } } //![0] diff --git a/src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedButtons.qml b/src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedButtons.qml new file mode 100644 index 00000000000..a884672b0d3 --- /dev/null +++ b/src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedButtons.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick + +Item { + width: 480; height: 320 + + Rectangle { + color: handler.active ? "tomato" : "wheat" + x: handler.point.position.x - width / 2 + y: handler.point.position.y - height / 2 + width: 20; height: width; radius: width / 2 + } + + PointHandler { + id: handler + acceptedButtons: Qt.MiddleButton | Qt.RightButton + } +} +//![0] diff --git a/src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedModifiers.qml b/src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedModifiers.qml new file mode 100644 index 00000000000..0229f3bb0a3 --- /dev/null +++ b/src/quick/doc/snippets/pointerHandlers/pointHandlerAcceptedModifiers.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick + +Item { + id: feedbackPane + width: 480; height: 320 + + PointHandler { + id: control + acceptedModifiers: Qt.ControlModifier + cursorShape: Qt.PointingHandCursor + target: Rectangle { + parent: feedbackPane + color: control.active ? "indianred" : "khaki" + x: control.point.position.x - width / 2 + y: control.point.position.y - height / 2 + width: 20; height: width; radius: width / 2 + } + } + + PointHandler { + id: shift + acceptedModifiers: Qt.ShiftModifier | Qt.MetaModifier + cursorShape: Qt.CrossCursor + target: Rectangle { + parent: feedbackPane + color: shift.active ? "darkslateblue" : "lightseagreen" + x: shift.point.position.x - width / 2 + y: shift.point.position.y - height / 2 + width: 30; height: width; radius: width / 2 + } + } +} +//![0] diff --git a/src/quick/doc/snippets/pointerHandlers/pointHandlerCanvasDrawing.qml b/src/quick/doc/snippets/pointerHandlers/pointHandlerCanvasDrawing.qml new file mode 100644 index 00000000000..5bc98c12309 --- /dev/null +++ b/src/quick/doc/snippets/pointerHandlers/pointHandlerCanvasDrawing.qml @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![0] +import QtQuick + +Canvas { + id: canvas + width: 800 + height: 600 + antialiasing: true + renderTarget: Canvas.FramebufferObject + property var points: [] + onPaint: { + if (points.length < 2) + return + var ctx = canvas.getContext('2d'); + ctx.save() + ctx.strokeStyle = stylusHandler.active ? "blue" : "white" + ctx.lineCap = "round" + ctx.beginPath() + ctx.moveTo(points[0].x, points[0].y) + for (var i = 1; i < points.length; i++) + ctx.lineTo(points[i].x, points[i].y) + ctx.lineWidth = 3 + ctx.stroke() + points = points.slice(points.length - 2, 1) + ctx.restore() + } + + PointHandler { + id: stylusHandler + acceptedPointerTypes: PointerDevice.Pen + onPointChanged: { + canvas.points.push(point.position) + canvas.requestPaint() + } + } + + PointHandler { + id: eraserHandler + acceptedPointerTypes: PointerDevice.Eraser + onPointChanged: { + canvas.points.push(point.position) + canvas.requestPaint() + } + } + + Rectangle { + width: 10; height: 10 + color: stylusHandler.active ? "green" : eraserHandler.active ? "red" : "beige" + } +} +//![0] diff --git a/src/quick/doc/snippets/pointerHandlers/pointHandlerMargin.qml b/src/quick/doc/snippets/pointerHandlers/pointHandlerMargin.qml new file mode 100644 index 00000000000..49161f0abe6 --- /dev/null +++ b/src/quick/doc/snippets/pointerHandlers/pointHandlerMargin.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick + +Item { + width: 480; height: 320 + + Rectangle { + anchors.fill: handlingContainer + anchors.margins: -handler.margin + color: "beige" + } + + Rectangle { + id: handlingContainer + width: 200; height: 200 + anchors.centerIn: parent + border.color: "green" + color: handler.active ? "lightsteelblue" : "khaki" + + Text { + text: "X" + x: handler.point.position.x - width / 2 + y: handler.point.position.y - height / 2 + visible: handler.active + } + + PointHandler { + id: handler + margin: 30 + } + } + +} +//![0] diff --git a/src/quick/doc/snippets/pointerHandlers/tapHandlerButton.qml b/src/quick/doc/snippets/pointerHandlers/tapHandlerButton.qml new file mode 100644 index 00000000000..02d0b4213bf --- /dev/null +++ b/src/quick/doc/snippets/pointerHandlers/tapHandlerButton.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick + +Rectangle { + id: button + signal clicked + property alias text: buttonLabel.text + + height: Math.max(Screen.pixelDensity * 7, buttonLabel.implicitHeight * 1.2) + width: Math.max(Screen.pixelDensity * 11, buttonLabel.implicitWidth * 1.3) + radius: 3 + property color dark: Qt.darker(palette.button, 1.3) + gradient: Gradient { + GradientStop { position: 0.0; color: tapHandler.pressed ? dark : palette.button } + GradientStop { position: 1.0; color: dark } + } + + TapHandler { + id: tapHandler + gesturePolicy: TapHandler.ReleaseWithinBounds + onTapped: button.clicked() + } + + Text { + id: buttonLabel + text: "Click Me" + color: palette.buttonText + anchors.centerIn: parent + } +} +//![0] diff --git a/src/quick/doc/snippets/pointerHandlers/tapHandlerButtonReleaseWithinBounds.qml b/src/quick/doc/snippets/pointerHandlers/tapHandlerButtonReleaseWithinBounds.qml new file mode 100644 index 00000000000..a6b1673d4c4 --- /dev/null +++ b/src/quick/doc/snippets/pointerHandlers/tapHandlerButtonReleaseWithinBounds.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick + +Item { + width: 120; height: 80 + + component Button : Rectangle { + id: button + signal clicked + property alias text: buttonLabel.text + + width: 80 + height: 40 + radius: 3 + property color dark: Qt.darker(palette.button, 1.3) + gradient: Gradient { + GradientStop { position: 0.0; color: tapHandler.pressed ? dark : palette.button } + GradientStop { position: 1.0; color: dark } + } + + SequentialAnimation on border.width { + id: tapFlash + running: false + loops: 3 + PropertyAction { value: 2 } + PauseAnimation { duration: 100 } + PropertyAction { value: 0 } + PauseAnimation { duration: 100 } + } + + //![1] + TapHandler { + id: tapHandler + gesturePolicy: TapHandler.ReleaseWithinBounds + onTapped: tapFlash.start() + } + //![1] + + Text { + id: buttonLabel + text: "Click Me" + color: palette.buttonText + anchors.centerIn: parent + } + } + + Button { x: 10; y: 10 } +} +//![0] diff --git a/src/quick/doc/snippets/pointerHandlers/tapHandlerButtonWithinBounds.qml b/src/quick/doc/snippets/pointerHandlers/tapHandlerButtonWithinBounds.qml new file mode 100644 index 00000000000..f2e968599c6 --- /dev/null +++ b/src/quick/doc/snippets/pointerHandlers/tapHandlerButtonWithinBounds.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick + +Item { + width: 120; height: 80 + + component Button : Rectangle { + id: button + signal clicked + property alias text: buttonLabel.text + + width: 80 + height: 40 + radius: 3 + property color dark: Qt.darker(palette.button, 1.3) + gradient: Gradient { + GradientStop { position: 0.0; color: tapHandler.pressed ? dark : palette.button } + GradientStop { position: 1.0; color: dark } + } + + SequentialAnimation on border.width { + id: tapFlash + running: false + loops: 3 + PropertyAction { value: 2 } + PauseAnimation { duration: 100 } + PropertyAction { value: 0 } + PauseAnimation { duration: 100 } + } + + //![1] + TapHandler { + id: tapHandler + gesturePolicy: TapHandler.WithinBounds + onTapped: tapFlash.start() + } + //![1] + + Text { + id: buttonLabel + text: "Click Me" + color: palette.buttonText + anchors.centerIn: parent + } + } + + Button { x: 10; y: 10 } +} +//![0] diff --git a/src/quick/doc/snippets/pointerHandlers/tapHandlerOnTapped.qml b/src/quick/doc/snippets/pointerHandlers/tapHandlerOnTapped.qml index deff59d034e..2c682df5840 100644 --- a/src/quick/doc/snippets/pointerHandlers/tapHandlerOnTapped.qml +++ b/src/quick/doc/snippets/pointerHandlers/tapHandlerOnTapped.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -48,7 +48,7 @@ ** ****************************************************************************/ //![0] -import QtQuick 2.12 +import QtQuick Rectangle { width: 100 @@ -56,8 +56,8 @@ Rectangle { TapHandler { acceptedButtons: Qt.LeftButton | Qt.RightButton - onTapped: (eventPoint)=> console.log("tapped", eventPoint.event.device.name, - "button", eventPoint.event.button, + onTapped: (eventPoint, button)=> console.log("tapped", eventPoint.device.name, + "button", button, "@", eventPoint.scenePosition) } } diff --git a/src/quick/doc/snippets/pointerHandlers/tapHandlerOverlappingButtons.qml b/src/quick/doc/snippets/pointerHandlers/tapHandlerOverlappingButtons.qml new file mode 100644 index 00000000000..993330a5ec0 --- /dev/null +++ b/src/quick/doc/snippets/pointerHandlers/tapHandlerOverlappingButtons.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import QtQuick + +Item { + width: 120; height: 80 + + component Button : Rectangle { + signal clicked + property alias text: buttonLabel.text + + width: 80 + height: 40 + radius: 3 + property color dark: Qt.darker(palette.button, 1.3) + gradient: Gradient { + GradientStop { position: 0.0; color: tapHandler.pressed ? dark : palette.button } + GradientStop { position: 1.0; color: dark } + } + + SequentialAnimation on border.width { + id: tapFlash + running: false + loops: 3 + PropertyAction { value: 2 } + PauseAnimation { duration: 100 } + PropertyAction { value: 0 } + PauseAnimation { duration: 100 } + } + + //![1] + TapHandler { + id: tapHandler + gesturePolicy: TapHandler.DragThreshold // the default + onTapped: tapFlash.start() + } + //![1] + + Text { + id: buttonLabel + text: "Click Me" + color: palette.buttonText + anchors.centerIn: parent + } + } + + Button { x: 10; y: 10 } + Button { x: 30; y: 30 } +} +//![0] diff --git a/src/quick/doc/snippets/qml/borderimage/borderimage-rounded.qml b/src/quick/doc/snippets/qml/borderimage/borderimage-rounded.qml new file mode 100644 index 00000000000..8e78ce28b04 --- /dev/null +++ b/src/quick/doc/snippets/qml/borderimage/borderimage-rounded.qml @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.0 + +Rectangle { + id: page + color: "white" + width: 182; height: 164 + +//! [tiled border image] +BorderImage { + anchors { fill: parent; margins: 6 } + border { left: 30; top: 30; right: 30; bottom: 30 } + horizontalTileMode: BorderImage.Round + verticalTileMode: BorderImage.Round + source: "pics/borderframe.png" +} +//! [tiled border image] + + Rectangle { + anchors.fill: parent + anchors.margins: 5 + color: "transparent" + border.color: "gray" + + Rectangle { + x: 30; y: 0 + width: 1; height: parent.height + color: "gray" + + Text { + text: "1" + font.pixelSize: 9 + color: "red" + anchors.right: parent.right + anchors.rightMargin: 1 + y: 20 + } + + Text { + text: "4" + font.pixelSize: 9 + color: "red" + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 1 + } + + Text { + text: "7" + font.pixelSize: 9 + color: "red" + y: parent.height - 30 + anchors.right: parent.right + anchors.rightMargin: 1 + } + } + + Rectangle { + x: parent.width - 30; y: 0 + width: 1; height: parent.height + color: "gray" + + Text { + text: "3" + font.pixelSize: 9 + color: "red" + x: 1 + y: 20 + } + + Text { + text: "6" + font.pixelSize: 9 + color: "red" + x: 1 + anchors.verticalCenter: parent.verticalCenter + } + + Text { + text: "9" + font.pixelSize: 9 + color: "red" + x: 1 + y: parent.height - 30 + } + } + + Text { + text: "5" + font.pixelSize: 9 + color: "red" + anchors.centerIn: parent + } + + Rectangle { + x: 0; y: 30 + width: parent.width; height: 1 + color: "gray" + + Text { + text: "2" + font.pixelSize: 9 + color: "red" + anchors.horizontalCenter: parent.horizontalCenter + y: -10 + } + } + + Rectangle { + x: 0; y: parent.height - 30 + width: parent.width; height: 1 + color: "gray" + + Text { + text: "8" + font.pixelSize: 9 + color: "red" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } +} diff --git a/src/quick/doc/snippets/qml/borderimage/borderimage-scaled.qml b/src/quick/doc/snippets/qml/borderimage/borderimage-scaled.qml index c59afb629cb..e713087ef5b 100644 --- a/src/quick/doc/snippets/qml/borderimage/borderimage-scaled.qml +++ b/src/quick/doc/snippets/qml/borderimage/borderimage-scaled.qml @@ -53,11 +53,12 @@ import QtQuick 2.0 Rectangle { id: page color: "white" - width: 180; height: 180 + width: 182; height: 182 + border.color: "gray" //! [scaled border image] BorderImage { - width: 180; height: 180 + anchors { fill: parent; margins: 1 } border { left: 30; top: 30; right: 30; bottom: 30 } horizontalTileMode: BorderImage.Stretch verticalTileMode: BorderImage.Stretch @@ -67,25 +68,98 @@ BorderImage { Rectangle { x: 30; y: 0 - width: 1; height: 180 + width: 1; height: parent.height color: "gray" + + Text { + text: "1" + font.pixelSize: 9 + color: "red" + anchors.right: parent.right + anchors.rightMargin: 1 + y: 20 + } + + Text { + text: "4" + font.pixelSize: 9 + color: "red" + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 1 + } + + Text { + text: "7" + font.pixelSize: 9 + color: "red" + y: parent.height - 30 + anchors.right: parent.right + anchors.rightMargin: 1 + } } Rectangle { - x: 150; y: 0 - width: 1; height: 180 + x: parent.width - 30; y: 0 + width: 1; height: parent.height color: "gray" + + Text { + text: "3" + font.pixelSize: 9 + color: "red" + x: 1 + y: 20 + } + + Text { + text: "6" + font.pixelSize: 9 + color: "red" + x: 1 + anchors.verticalCenter: parent.verticalCenter + } + + Text { + text: "9" + font.pixelSize: 9 + color: "red" + x: 1 + y: parent.height - 30 + } + } + + Text { + text: "5" + font.pixelSize: 9 + color: "red" + anchors.centerIn: parent } Rectangle { x: 0; y: 30 - width: 180; height: 1 + width: parent.width; height: 1 color: "gray" + + Text { + text: "2" + font.pixelSize: 9 + color: "red" + anchors.horizontalCenter: parent.horizontalCenter + y: -10 + } } Rectangle { - x: 0; y: 150 - width: 180; height: 1 + x: 0; y: parent.height - 30 + width: parent.width; height: 1 color: "gray" + + Text { + text: "8" + font.pixelSize: 9 + color: "red" + anchors.horizontalCenter: parent.horizontalCenter + } } } diff --git a/src/quick/doc/snippets/qml/borderimage/borderimage-tiled.qml b/src/quick/doc/snippets/qml/borderimage/borderimage-tiled.qml index 6f6c676b53b..5601b359334 100644 --- a/src/quick/doc/snippets/qml/borderimage/borderimage-tiled.qml +++ b/src/quick/doc/snippets/qml/borderimage/borderimage-tiled.qml @@ -53,11 +53,12 @@ import QtQuick 2.0 Rectangle { id: page color: "white" - width: 180; height: 180 + width: 182; height: 182 + border.color: "gray" //! [tiled border image] BorderImage { - width: 180; height: 180 + anchors { fill: parent; margins: 1 } border { left: 30; top: 30; right: 30; bottom: 30 } horizontalTileMode: BorderImage.Repeat verticalTileMode: BorderImage.Repeat @@ -67,25 +68,98 @@ BorderImage { Rectangle { x: 30; y: 0 - width: 1; height: 180 + width: 1; height: parent.height color: "gray" + + Text { + text: "1" + font.pixelSize: 9 + color: "red" + anchors.right: parent.right + anchors.rightMargin: 1 + y: 20 + } + + Text { + text: "4" + font.pixelSize: 9 + color: "red" + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 1 + } + + Text { + text: "7" + font.pixelSize: 9 + color: "red" + y: parent.height - 30 + anchors.right: parent.right + anchors.rightMargin: 1 + } } Rectangle { - x: 150; y: 0 - width: 1; height: 180 + x: parent.width - 30; y: 0 + width: 1; height: parent.height color: "gray" + + Text { + text: "3" + font.pixelSize: 9 + color: "red" + x: 1 + y: 20 + } + + Text { + text: "6" + font.pixelSize: 9 + color: "red" + x: 1 + anchors.verticalCenter: parent.verticalCenter + } + + Text { + text: "9" + font.pixelSize: 9 + color: "red" + x: 1 + y: parent.height - 30 + } + } + + Text { + text: "5" + font.pixelSize: 9 + color: "red" + anchors.centerIn: parent } Rectangle { x: 0; y: 30 - width: 180; height: 1 + width: parent.width; height: 1 color: "gray" + + Text { + text: "2" + font.pixelSize: 9 + color: "red" + anchors.horizontalCenter: parent.horizontalCenter + y: -10 + } } Rectangle { - x: 0; y: 150 - width: 180; height: 1 + x: 0; y: parent.height - 30 + width: parent.width; height: 1 color: "gray" + + Text { + text: "8" + font.pixelSize: 9 + color: "red" + anchors.horizontalCenter: parent.horizontalCenter + } } } diff --git a/src/quick/doc/snippets/qml/borderimage/normal-image.qml b/src/quick/doc/snippets/qml/borderimage/normal-image.qml index 16938bc8e47..f75ccd09fdd 100644 --- a/src/quick/doc/snippets/qml/borderimage/normal-image.qml +++ b/src/quick/doc/snippets/qml/borderimage/normal-image.qml @@ -53,35 +53,43 @@ import QtQuick 2.0 Rectangle { id: page color: "white" - width: 120; height: 120 + width: 182; height: 182 //! [normal image] Image { source: "pics/borderframe.png" + anchors.centerIn: parent } //! [normal image] Rectangle { - x: 30; y: 0 - width: 1; height: 120 - color: "gray" - } + width: 120; height: 120 + color: "transparent" + border.color: "gray" + anchors.centerIn: parent - Rectangle { - x: 90; y: 0 - width: 1; height: 120 - color: "gray" - } + Rectangle { + x: 30; y: 0 + width: 1; height: 120 + color: "gray" + } - Rectangle { - x: 0; y: 30 - width: 200; height: 1 - color: "gray" - } + Rectangle { + x: 90; y: 0 + width: 1; height: 120 + color: "gray" + } - Rectangle { - x: 0; y: 90 - width: 200; height: 1 - color: "gray" + Rectangle { + x: 0; y: 30 + width: 120; height: 1 + color: "gray" + } + + Rectangle { + x: 0; y: 90 + width: 120; height: 1 + color: "gray" + } } } diff --git a/src/quick/doc/snippets/qml/borderimage/pics/borderframe.png b/src/quick/doc/snippets/qml/borderimage/pics/borderframe.png new file mode 100644 index 00000000000..97a9452d5c1 Binary files /dev/null and b/src/quick/doc/snippets/qml/borderimage/pics/borderframe.png differ diff --git a/src/quick/doc/snippets/qml/borderimage/pics/borderframe.svg b/src/quick/doc/snippets/qml/borderimage/pics/borderframe.svg new file mode 100644 index 00000000000..1f6c1f29012 --- /dev/null +++ b/src/quick/doc/snippets/qml/borderimage/pics/borderframe.svg @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + width="120.00004" + height="120.00018" + id="svg2" + sodipodi:version="0.32" + inkscape:version="1.2.2 (b0a8486541, 2022-12-01)" + sodipodi:docname="borderframe.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + version="1.1" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <defs + id="defs4"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : -406.18091 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : -406.18091 : 1" + inkscape:persp3d-origin="372.04724 : -581.57461 : 1" + id="perspective10" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.8998663" + inkscape:cx="239.22736" + inkscape:cy="198.43502" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + inkscape:window-width="2688" + inkscape:window-height="1698" + inkscape:window-x="4020" + inkscape:window-y="204" + inkscape:showpageshadow="0" + inkscape:pagecheckerboard="1" + inkscape:deskcolor="#d1d1d1" + inkscape:window-maximized="0"> + <inkscape:grid + type="xygrid" + id="grid2383" + visible="true" + enabled="true" + spacingx="1" + spacingy="1" + originx="-93.000067" + originy="-75.362307" /> + </sodipodi:namedview> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-93.000067,-75.362307)"> + <path + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.88977;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m 105.75595,88.1182 c 0,-11.811047 11.81103,-11.811047 11.81103,0 h 23.62207 L 153.00008,76.307153 164.81112,88.1182 h 23.62206 c 0,-11.811047 11.81104,-11.811047 11.81104,0 11.81104,0 11.81104,11.811049 0,11.811049 v 23.622101 l 11.81104,11.81105 -11.81104,11.81105 v 23.62209 c 11.81104,0 11.81104,11.81105 0,11.81105 0,11.81105 -11.81104,11.81105 -11.81104,0 h -23.62206 l -11.81104,11.81105 -11.81103,-11.81105 h -23.62207 c 0,11.81105 -11.81103,11.81105 -11.81103,0 -11.811037,0 -11.811037,-11.81105 0,-11.81105 V 147.17345 L 93.944913,135.3624 105.75595,123.55135 V 99.929249 c -11.811037,0 -11.811037,-11.811049 0,-11.811049 z" + id="rect2387" + sodipodi:nodetypes="ccccccccccccccccccccccccc" /> + <path + sodipodi:nodetypes="ccccccccccccccccccccccccc" + id="path3160" + d="m 110.48036,92.84263 c 0,-10.629942 0,-9.448848 4.72442,-1e-5 l 27.16537,1e-5 10.62993,-10.629942 10.62993,10.629942 27.16538,-1e-5 c 4.72441,-9.448838 4.72441,-10.629932 4.72441,1e-5 10.62993,0 9.44883,-1e-5 0,4.724411 v 27.165419 l 10.62993,10.62995 -10.62993,10.62994 v 27.1654 c 9.44883,4.72442 10.62993,4.72443 0,4.72443 0,10.62995 0,9.44883 -4.72441,-1e-5 l -27.16538,1e-5 -10.62993,10.62995 -10.62993,-10.62995 -27.16537,-1e-5 c -4.72442,9.44884 -4.72442,10.62996 -4.72442,1e-5 -10.629933,0 -9.44883,-1e-5 0,-4.72443 v -27.1654 L 99.850427,135.36241 110.48036,124.73246 V 97.567041 c -9.44883,-4.724421 -10.629933,-4.724411 0,-4.724411 z" + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:3.77954;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + </g> +</svg> diff --git a/src/quick/doc/snippets/qml/externaldrag.qml b/src/quick/doc/snippets/qml/externaldrag.qml index 97a23293ca2..5a88be2d4b9 100644 --- a/src/quick/doc/snippets/qml/externaldrag.qml +++ b/src/quick/doc/snippets/qml/externaldrag.qml @@ -48,7 +48,7 @@ ** ****************************************************************************/ //![0] -import QtQuick 2.8 +import QtQuick 2.12 Item { width: 200; height: 200 @@ -59,7 +59,7 @@ Item { color: "green" radius: 5 - Drag.active: dragArea.drag.active + Drag.active: dragHandler.active Drag.dragType: Drag.Automatic Drag.supportedActions: Qt.CopyAction Drag.mimeData: { @@ -72,14 +72,14 @@ Item { text: "Drag me" } - MouseArea { - id: dragArea - anchors.fill: parent - - drag.target: parent - onPressed: parent.grabToImage(function(result) { - parent.Drag.imageSource = result.url - }) + DragHandler { + id: dragHandler + onActiveChanged: + if (active) { + parent.grabToImage(function(result) { + parent.Drag.imageSource = result.url; + }) + } } } } diff --git a/src/quick/doc/snippets/qml/images/qt-logo.png b/src/quick/doc/snippets/qml/images/qt-logo.png new file mode 100644 index 00000000000..30c621c9c66 Binary files /dev/null and b/src/quick/doc/snippets/qml/images/qt-logo.png differ diff --git a/src/quick/doc/snippets/qml/item/containmentMask-circle-js.qml b/src/quick/doc/snippets/qml/item/containmentMask-circle-js.qml new file mode 100644 index 00000000000..2d97bcdafad --- /dev/null +++ b/src/quick/doc/snippets/qml/item/containmentMask-circle-js.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQml 2.12 +import QtQuick 2.12 + +//![0] +Rectangle { + id: circle + width: 100; height: width + radius: width / 2 + color: tapHandler.pressed ? "tomato" : hoverHandler.hovered ? "darkgray" : "lightgray" + + TapHandler { id: tapHandler } + HoverHandler { id: hoverHandler } + + containmentMask: QtObject { + property alias radius: circle.radius + function contains(point: point) : bool { + return (Math.pow(point.x - radius, 2) + Math.pow(point.y - radius, 2)) < Math.pow(radius, 2) + } + } +} +//![0] diff --git a/src/quick/doc/snippets/qml/item/containmentMask-shape.qml b/src/quick/doc/snippets/qml/item/containmentMask-shape.qml new file mode 100644 index 00000000000..a3da217e73d --- /dev/null +++ b/src/quick/doc/snippets/qml/item/containmentMask-shape.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Shapes 1.12 + +//![0] +Rectangle { + width: 90; height: 100 + color: hoverHandler.hovered ? "wheat" : "lightgray" + containmentMask: shape + + HoverHandler { id: hoverHandler } + + Shape { + id: shape + containsMode: Shape.FillContains + + ShapePath { + fillColor: "lightsteelblue" + startX: 10; startY: 20 + PathArc { + x: 10; y: 80 + radiusX: 40; radiusY: 40 + useLargeArc: true + } + PathLine { + x: 10; y: 20 + } + } + } +} +//![0] diff --git a/src/quick/doc/snippets/qml/itemGrab.qml b/src/quick/doc/snippets/qml/item/itemGrab.qml similarity index 83% rename from src/quick/doc/snippets/qml/itemGrab.qml rename to src/quick/doc/snippets/qml/item/itemGrab.qml index e26e3dc55e4..78fc53833b6 100644 --- a/src/quick/doc/snippets/qml/itemGrab.qml +++ b/src/quick/doc/snippets/qml/item/itemGrab.qml @@ -54,44 +54,33 @@ Item { width: 320 height: 480 -//! [grab-source] +//! [grab-to-file] Rectangle { - id: source + id: sourceRectangle width: 100 height: 100 gradient: Gradient { GradientStop { position: 0; color: "steelblue" } GradientStop { position: 1; color: "black" } } + + Component.onCompleted: { + sourceRectangle.grabToImage(function(result) { + result.saveToFile("something.png") + }) + } } -//! [grab-source] +//! [grab-to-file] -//! [grab-image-target] +//! [grab-to-image] Image { id: image } -//! [grab-image-target] - Timer { - repeat: false - running: true - interval: 1000 - onTriggered: { -//! [grab-to-file] - // ... - source.grabToImage(function(result) { - result.saveToFile("something.png"); - }); -//! [grab-to-file] - -//! [grab-to-cache] - - // ... - source.grabToImage(function(result) { - image.source = result.url; - }, - Qt.size(50, 50)); -//! [grab-to-cache] - } - } +Component.onCompleted: { + sourceRectangle.grabToImage(function(result) { + image.source = result.url + }, Qt.size(50, 50)) +} +//! [grab-to-image] } diff --git a/src/quick/doc/snippets/qml/nestedWindowTransientParent.qml b/src/quick/doc/snippets/qml/nestedWindowTransientParent.qml new file mode 100644 index 00000000000..1946ee4af0d --- /dev/null +++ b/src/quick/doc/snippets/qml/nestedWindowTransientParent.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +//![0] +Window { + // visible is false by default + Window { + transientParent: null + visible: true + } +//![0] + + id: outer + Timer { + interval: 2000 + running: true + onTriggered: outer.visible = true + } +//![1] +} +//![1] diff --git a/src/quick/doc/snippets/qml/pathview/pathview.qml b/src/quick/doc/snippets/qml/pathview/pathview.qml index 58d19b1a0c4..0c3b96bb264 100644 --- a/src/quick/doc/snippets/qml/pathview/pathview.qml +++ b/src/quick/doc/snippets/qml/pathview/pathview.qml @@ -59,15 +59,20 @@ Rectangle { id: delegate Column { id: wrapper + + required property url icon + required property string name + opacity: PathView.isCurrentItem ? 1 : 0.5 + Image { anchors.horizontalCenter: nameText.horizontalCenter width: 64; height: 64 - source: icon + source: wrapper.icon } Text { id: nameText - text: name + text: wrapper.name font.pointSize: 16 } } diff --git a/src/quick/doc/snippets/qml/splashWindow.qml b/src/quick/doc/snippets/qml/splashWindow.qml new file mode 100644 index 00000000000..17d4c674e31 --- /dev/null +++ b/src/quick/doc/snippets/qml/splashWindow.qml @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [entire] +import QtQuick + +Window { + id: mainWindow + title: "Main Window" + color: "#456" + property real defaultSpacing: 10 + + property Splash splash: Splash { + onTimeout: mainWindow.show() + } + + component Splash: Window { + id: splash + + // a splash screen has no titlebar + flags: Qt.SplashScreen + // the transparent color lets background behind the image edges show through + color: "transparent" + modality: Qt.ApplicationModal // in case another application window is showing + title: "Splash Window" // for the taskbar/dock, task switcher etc. + visible: true + + // here we use the Screen attached property to center the splash window + //! [screen-properties] + x: (Screen.width - splashImage.width) / 2 + y: (Screen.height - splashImage.height) / 2 + //! [screen-properties] + width: splashImage.width + height: splashImage.height + + property int timeoutInterval: 2000 + signal timeout + + Image { + id: splashImage + source: "images/qt-logo.png" + } + + TapHandler { + onTapped: splash.timeout() + } + + Timer { + interval: splash.timeoutInterval; running: true; repeat: false + onTriggered: { + splash.visible = false + splash.timeout() + } + } + } +} +//! [entire] diff --git a/src/quick/doc/snippets/qml/tableview/selectionmodel.qml b/src/quick/doc/snippets/qml/tableview/selectionmodel.qml index b971e899798..8d7cb05f1c5 100644 --- a/src/quick/doc/snippets/qml/tableview/selectionmodel.qml +++ b/src/quick/doc/snippets/qml/tableview/selectionmodel.qml @@ -62,17 +62,10 @@ Window { visible: true visibility: Window.AutomaticVisibility - Button { - id: button - text: "Toggle" - onClicked: tableView.selectionModel.select(tableView.model.index(0, 0), ItemSelectionModel.Toggle) - } - //![0] TableView { id: tableView anchors.fill: parent - anchors.topMargin: button.height clip: true model: TableModel { @@ -87,8 +80,10 @@ Window { delegate: Rectangle { implicitWidth: 100 implicitHeight: 30 + color: selected ? "blue" : "lightgray" + required property bool selected - color: selected ? "green" : "lightgray" + Text { text: display } } } diff --git a/src/quick/doc/snippets/qml/windowActiveAttached.qml b/src/quick/doc/snippets/qml/windowActiveAttached.qml new file mode 100644 index 00000000000..9d2ddc2b999 --- /dev/null +++ b/src/quick/doc/snippets/qml/windowActiveAttached.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![entire] +import QtQuick + +Text { + text: Window.active ? "active" : "inactive" +} +//![entire] diff --git a/src/quick/doc/snippets/qml/windowPalette.qml b/src/quick/doc/snippets/qml/windowPalette.qml new file mode 100644 index 00000000000..c566d61dbb2 --- /dev/null +++ b/src/quick/doc/snippets/qml/windowPalette.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![entire] +import QtQuick +import QtQuick.Controls + +//![declaration-and-color] +Window { + visible: true + + // here we use the Window.active and Window.palette ordinary properties + color: active ? palette.active.window : palette.inactive.window +//![declaration-and-color] + + // colors that are not customized here come from SystemPalette + palette.active.window: "peachpuff" + palette.windowText: "brown" + + Text { + anchors.centerIn: parent + // here we use the Window.active attached property and the Item.palette property + color: Window.active ? palette.active.windowText : palette.inactive.windowText + text: Window.active ? "active" : "inactive" + } + + Button { + text: "Button" + anchors { + bottom: parent.bottom + bottomMargin: 6 + horizontalCenter: parent.horizontalCenter + } + } +//![closing-brace] +} +//![closing-brace] +//![entire] diff --git a/src/quick/doc/snippets/qml/windowVisibility.qml b/src/quick/doc/snippets/qml/windowVisibility.qml new file mode 100644 index 00000000000..b5f89a38948 --- /dev/null +++ b/src/quick/doc/snippets/qml/windowVisibility.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [entire] +import QtQuick +import QtQuick.Controls + +Window { + id: win + flags: Qt.Window | Qt.WindowFullscreenButtonHint + visibility: fullscreenButton.checked ? Window.FullScreen : Window.Windowed + + Button { + id: fullscreenButton + anchors { + right: parent.right + top: parent.top + margins: 6 + } + width: height + checkable: true + Binding on checked { value: win.visibility === Window.FullScreen } + text: "⛶" + ToolTip.visible: hovered + ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval + ToolTip.text: win.visibility === Window.FullScreen ? qsTr("restore") : qsTr("fill screen") + } +} +//! [entire] diff --git a/src/quick/doc/snippets/qmllint/config.ini b/src/quick/doc/snippets/qmllint/config.ini new file mode 100644 index 00000000000..29fa21438a3 --- /dev/null +++ b/src/quick/doc/snippets/qmllint/config.ini @@ -0,0 +1,19 @@ +[General] +AdditionalQmlImportPaths= +DisableDefaultImports=false +OverwriteImportTypes= +ResourcePath= + +[Warnings] +BadSignalHandler=warning +Deprecated=warning +ImportFailure=warning +InheritanceCycle=warning +MultilineStrings=info +PropertyAlias=warning +RequiredProperty=warning +TypeError=warning +UnknownProperty=warning +UnqualifiedAccess=warning +UnusedImports=info +WithStatement=warning diff --git a/src/quick/doc/src/advtutorial.qdoc b/src/quick/doc/src/advtutorial.qdoc index 63c70067fd4..66d0d125da9 100644 --- a/src/quick/doc/src/advtutorial.qdoc +++ b/src/quick/doc/src/advtutorial.qdoc @@ -298,9 +298,6 @@ until the next chapter - where your application becomes alive! Now we're going to do two things to liven up the game: animate the blocks and add a High Score system. -We've also cleaned up the directory structure for our application files. We now have a lot of files, so all the -JavaScript and QML files outside of \c samegame.qml have been moved into a new sub-directory named "content". - In anticipation of the new block animations, \c Block.qml file is now renamed to \c BoomBlock.qml. \section3 Animating Block Movement @@ -311,7 +308,7 @@ In \c BoomBlock.qml, we apply a \l SpringAnimation behavior to the \c x and \c y block will follow and animate its movement in a spring-like fashion towards the specified position (whose values will be set by \c samegame.js).Here is the code added to \c BoomBlock.qml: -\snippet tutorials/samegame/samegame4/content/BoomBlock.qml 1 +\snippet tutorials/samegame/samegame4/BoomBlock.qml 1 The \c spring and \c damping values can be changed to modify the spring-like effect of the animation. @@ -328,7 +325,7 @@ animate the opacity value so that it gradually fades in and out, instead of abru visible and invisible. To do this, we'll apply a \l Behavior on the \c opacity property of the \c Image type in \c BoomBlock.qml: -\snippet tutorials/samegame/samegame4/content/BoomBlock.qml 2 +\snippet tutorials/samegame/samegame4/BoomBlock.qml 2 Note the \c{opacity: 0} which means the block is transparent when it is first created. We could set the opacity in \c samegame.js when we create and destroy the blocks, @@ -354,14 +351,14 @@ To fade out, we set \c dying to true instead of setting opacity to 0 when a bloc Finally, we'll add a cool-looking particle effect to the blocks when they are destroyed. To do this, we first add a \l ParticleSystem in \c BoomBlock.qml, like so: -\snippet tutorials/samegame/samegame4/content/BoomBlock.qml 3 +\snippet tutorials/samegame/samegame4/BoomBlock.qml 3 To fully understand this you should read \l {Using the Qt Quick Particle System}, but it's important to note that \c emitRate is set to zero so that particles are not emitted normally. Also, we extend the \c dying State, which creates a burst of particles by calling the \c burst() method on the particles type. The code for the states now look like this: -\snippet tutorials/samegame/samegame4/content/BoomBlock.qml 4 +\snippet tutorials/samegame/samegame4/BoomBlock.qml 4 Now the game is beautifully animated, with subtle (or not-so-subtle) animations added for all of the player's actions. The end result is shown below, with a different set of images to demonstrate basic theming: @@ -378,20 +375,20 @@ To do this, we will show a dialog when the game is over to request the player's This requires a few changes to \c Dialog.qml. In addition to a \c Text type, it now has a \c TextInput child item for receiving keyboard text input: -\snippet tutorials/samegame/samegame4/content/Dialog.qml 0 +\snippet tutorials/samegame/samegame4/Dialog.qml 0 \dots 4 -\snippet tutorials/samegame/samegame4/content/Dialog.qml 2 +\snippet tutorials/samegame/samegame4/Dialog.qml 2 \dots 4 -\snippet tutorials/samegame/samegame4/content/Dialog.qml 3 +\snippet tutorials/samegame/samegame4/Dialog.qml 3 We'll also add a \c showWithInput() function. The text input will only be visible if this function is called instead of \c show(). When the dialog is closed, it emits a \c closed() signal, and other types can retrieve the text entered by the user through an \c inputText property: -\snippet tutorials/samegame/samegame4/content/Dialog.qml 0 -\snippet tutorials/samegame/samegame4/content/Dialog.qml 1 +\snippet tutorials/samegame/samegame4/Dialog.qml 0 +\snippet tutorials/samegame/samegame4/Dialog.qml 1 \dots 4 -\snippet tutorials/samegame/samegame4/content/Dialog.qml 3 +\snippet tutorials/samegame/samegame4/Dialog.qml 3 Now the dialog can be used in \c samegame.qml: @@ -401,9 +398,9 @@ When the dialog emits the \c closed signal, we call the new \c saveHighScore() f The \c nameInputDialog is activated in the \c victoryCheck() function in \c samegame.js: -\snippet tutorials/samegame/samegame4/content/samegame.js 3 +\snippet tutorials/samegame/samegame4/samegame.js 3 \dots 4 -\snippet tutorials/samegame/samegame4/content/samegame.js 4 +\snippet tutorials/samegame/samegame4/samegame.js 4 \section3 Storing High Scores Offline @@ -411,7 +408,7 @@ Now we need to implement the functionality to actually save the High Scores tabl Here is the \c saveHighScore() function in \c samegame.js: -\snippet tutorials/samegame/samegame4/content/samegame.js 2 +\snippet tutorials/samegame/samegame4/samegame.js 2 First we call \c sendHighScore() (explained in the section below) if it is possible to send the high scores to an online database. @@ -430,7 +427,7 @@ If the player entered their name we can send the data to the web service us If the player enters a name, we send the data to the service using this code in \c samegame.js: -\snippet tutorials/samegame/samegame4/content/samegame.js 1 +\snippet tutorials/samegame/samegame4/samegame.js 1 The \l XMLHttpRequest in this code is the same as the \c XMLHttpRequest() as you'll find in standard browser JavaScript, and can be used in the same way to dynamically get XML or QML from the web service to display the high scores. We don't worry about the response in this case - we just post the high diff --git a/src/quick/doc/src/cmake-macros.qdoc b/src/quick/doc/src/cmake-macros.qdoc deleted file mode 100644 index b643a9e4e40..00000000000 --- a/src/quick/doc/src/cmake-macros.qdoc +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** 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 Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! -\page qtqml-cmake-qt5-import-qml-plugins.html -\ingroup cmake-macros-qtqml - -\title qt5_import_qml_plugins - -\brief Scans \c{.qml} files and imports required QML static plugins - -\section1 Overview - -\badcode -find_package(Qt5QmlImportScanner REQUIRED) -qt5_import_qml_plugins(<TARGET>) -\endcode - -\section1 Description - -Runs \c{qmlimportscanner} at configure time to find the static QML plugins -used and links them to the given target. - -\note When used with a non-static Qt build, this function does nothing. - -This CMake command was introduced in Qt 5.14. - -\section1 Example - -\snippet cmake-macros/examples.cmake qt5_import_qml_plugins - -*/ diff --git a/src/quick/doc/src/concepts/effects/particles.qdoc b/src/quick/doc/src/concepts/effects/particles.qdoc index abe721c5abf..aa894504393 100644 --- a/src/quick/doc/src/concepts/effects/particles.qdoc +++ b/src/quick/doc/src/concepts/effects/particles.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \qmlmodule QtQuick.Particles 2.\QtMinorVersion + \qmlmodule QtQuick.Particles \title Qt Quick Particles QML Types \ingroup qmlmodules \brief Provides QML types for particle effects diff --git a/src/quick/doc/src/concepts/input/focus.qdoc b/src/quick/doc/src/concepts/input/focus.qdoc index 9862489f427..6dd5a4b4bc5 100644 --- a/src/quick/doc/src/concepts/input/focus.qdoc +++ b/src/quick/doc/src/concepts/input/focus.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -76,8 +76,9 @@ type whose text is determined by whether or not it has active focus. An \l Item requests focus by setting the \c focus property to \c true. For very simple cases simply setting the \c focus property is sometimes -sufficient. If we run the following example with \l{qtquick-qmlscene.html} -{qmlscene}, we see that the \c {keyHandler} type has active focus and +sufficient. If we run the following example with the +\l {Prototyping with the QML Runtime Tool}{qml tool}, +we see that the \c {keyHandler} type has active focus and pressing the \c A, \c B, or \c C keys modifies the text appropriately. \snippet qml/focus/basicwidget.qml focus true @@ -196,7 +197,7 @@ property. As the \l ListView is a focus scope, this doesn't affect the rest of the application. However, if the \l ListView itself has active focus this causes the delegate itself to receive active focus. In this example, the root type of the delegate is also a focus scope, -which in turn gives active focus to the \c {Text} type that actually performs +which in turn gives active focus to the \l {TextInput} type that actually performs the work of handling the \c {Return} key. All of the QML view classes, such as \l PathView and \l GridView, behave diff --git a/src/quick/doc/src/concepts/inputhandlers/qtquickhandlers-index.qdoc b/src/quick/doc/src/concepts/inputhandlers/qtquickhandlers-index.qdoc index 2ac9860e6f3..7a05583a826 100644 --- a/src/quick/doc/src/concepts/inputhandlers/qtquickhandlers-index.qdoc +++ b/src/quick/doc/src/concepts/inputhandlers/qtquickhandlers-index.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -30,20 +30,23 @@ \title Qt Quick Input Handlers \brief A module with a set of QML elements that handle events from input devices in a user interface. - Qt Quick Input Handlers are a set of QML types used to handle events from - keyboard, touch, mouse, and stylus devices in a UI. In contrast to event-handling - items, such as \l MouseArea and \l Flickable, input handlers are explicitly non-visual, - require less memory and are intended to be used in greater numbers: one - handler instance per aspect of interaction. Each input handler instance - handles certain events on behalf of its \c parent Item. Thus the visual and + Qt Quick Input Handlers are a set of QML types used to handle + \l {QInputEvent}{events} from keyboard, touch, mouse, and stylus + \l {QInputDevice}{devices} in a UI. In contrast to event-handling + items, such as \l MouseArea and \l Flickable, input handlers are explicitly + non-visual, require less memory and are intended to be used in greater + numbers: one handler instance per aspect of interaction. Each input handler + instance handles certain events on behalf of its + \l {QQuickPointerHandler::parent()}{parent} Item. Thus the visual and behavioral concerns are better separated, and the behavior is built up by finer-grained composition. - In Qt 5.10, these handlers were introduced in a separate Qt.labs.handlers module. - Now they are included with Qt Quick since 5.12. The pre-existing - \l Keys attached property is similar in concept, so we refer to the - pointing-device-oriented handlers plus \c Keys together as the set of Input Handlers. - We expect to offer more attached-property use cases in future versions of Qt. + The \l {Pointer Handlers Example} demonstrates some use cases for these. + + The pre-existing \l Keys attached property is similar in concept, so we + refer to the pointing-device-oriented handlers plus \c Keys together as the + set of Input Handlers. We expect to offer more attached-property use cases + in future versions of Qt. \section1 Input Handlers @@ -60,7 +63,45 @@ \li Each Item can have unlimited Handlers \endlist - \omit TODO actual overview with snippets and stuff \endomit + \section1 Handlers Manipulating Items + + Some Handlers add interactivity simply by being declared inside an Item: + + \snippet pointerHandlers/dragHandler.qml 0 + + \section1 Handler Properties and Signals + + All Handlers have properties that can be used in bindings, and signals that + can be handled to react to input: + + \snippet pointerHandlers/hoverTapKeyButton.qml 0 + + \section1 Pointer Grab + + An important concept with Pointer Handlers is the type of grabs that they + perform. The only kind of grab an Item can take is the exclusive grab: for + example if you call \l QPointerEvent::setExclusiveGrabber(), the following + mouse moves and mouse release event will be sent only to that object. (As a + workaround to this exclusivity, see \l QQuickItem::setFiltersChildMouseEvents() + and \l QQuickItem::childMouseEventFilter().) However Pointer Handlers have + an additional mechanism available: the + \l {QPointerEvent::addPassiveGrabber()} {passive grab}. Mouse and touch + \l {QEventPoint::state()}{press} events are delivered by visiting all the + Items in top-down Z order: first each Item's child Handlers, and then the + \l {QQuickItem::event()}{Item} itself. At the time a press event is + delivered, a Handler can take either a passive or an exclusive grab + depending on its needs. If it takes a passive grab, it is guaranteed to + receive the updates and the release, even if other Items or Handlers in the + scene take any kind of grab, passive or exclusve. Some Handlers (such as + PointHandler) can work only with passive grabs; others require exclusive + grabs; and others can "lurk" with passive grabs until they detect that a + gesture is being performed, and then make the transition from passive to + exclusive grab. TapHandler's grabbing behavior is + \l {TapHandler::gesturePolicy}{configurable}. + + When a grab transition is requested, \l PointerHandler::grabPermissions, + \l QQuickItem::keepMouseGrab() and \l QQuickItem::keepTouchGrab() control + whether the transition will be allowed. \section1 Related Information diff --git a/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc b/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc index 369c2f44442..429bd6e8540 100644 --- a/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc +++ b/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc @@ -103,9 +103,16 @@ \l{Layout::minimumWidth}{minimum}, \l{Layout::preferredWidth}{preferred}, and \l{Layout::maximumWidth}{maximum} sizes of all items where \l{Layout::fillWidth}{Layout.fillWidth} or \l{Layout::fillHeight}{Layout.fillHeight} is set to \c true. + + The \l{Layout::preferredWidth}{preferred} width and height is the \e actual width and + height of an item if the layout is not bound to a specific size itself. If the layout is set + to a specific size, it will distribute additional space based on the ratio of preferred sizes + of its items (taking minimum and maximum sizes into account). + For instance, the following will produce a layout with two rectangles lying side-by-side that stretches horizontally. The azure rectangle can be resized from 50x150 to 300x150, and the plum - rectangle can be resized from 100x100 to ∞x100. + rectangle can be resized from 100x100 to ∞x100. As long as the minimum and maximum width of each + item is not reached, the plum rectangle will have two times the width of the azure one. \snippet qml/windowconstraints.qml rowlayout diff --git a/src/quick/doc/src/concepts/layouts/qtquicklayouts.qdoc b/src/quick/doc/src/concepts/layouts/qtquicklayouts.qdoc index 9ea8759318c..0df832cca9e 100644 --- a/src/quick/doc/src/concepts/layouts/qtquicklayouts.qdoc +++ b/src/quick/doc/src/concepts/layouts/qtquicklayouts.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \qmlmodule QtQuick.Layouts 1.\QtMinorVersion + \qmlmodule QtQuick.Layouts \title Qt Quick Layouts QML Types \ingroup qmlmodules \brief Provides QML types for arranging QML items in a user interface. diff --git a/src/quick/doc/src/concepts/positioning/righttoleft.qdoc b/src/quick/doc/src/concepts/positioning/righttoleft.qdoc index 1f3602cde10..da96d312582 100644 --- a/src/quick/doc/src/concepts/positioning/righttoleft.qdoc +++ b/src/quick/doc/src/concepts/positioning/righttoleft.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -171,21 +171,25 @@ This will append the following declaration to the translation file, where you ca </context> \endcode -You can test that the layout direction works as expected by running your Qt Quick application with -the compiled translation file: - +Next, add the following bindings to the root QML component of your application: \code -qmlscene myapp.qml -translation myapp.qm +LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft +LayoutMirroring.childrenInherit: true \endcode -You can test your application in right-to-left layout direction simply by executing qmlscene with a -command-line parameter "-reverse": +The first binding ensures that the UI will be mirrored appropriately when a +right-to-left locale is set. The second binding ensures that child items of the +root component will also respect mirroring. + +You can test that the layout direction works as expected by running your Qt Quick application with +the compiled translation file: \code -qmlscene myapp.qml -reverse +qml myapp.qml -translation myapp.qm \endcode -The layout direction can also be set from C++ by calling the static function \l QGuiApplication::setLayoutDirection(): +You can test your application in right-to-left layout direction by calling the +static function \l QGuiApplication::setLayoutDirection(): \code QGuiApplication app(argc, argv); diff --git a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc index faec8df7e41..b0a66cfb5f1 100644 --- a/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc +++ b/src/quick/doc/src/concepts/visualcanvas/scenegraph.qdoc @@ -194,6 +194,7 @@ throttling, use the \c basic render loop instead by setting \c {QSG_RENDER_LOOP=basic} in the environment. \section2 Threaded Render Loop ('threaded') +\target threaded_render_loop On many configurations, the scene graph rendering will happen on a dedicated render thread. This is done to increase parallelism of diff --git a/src/quick/doc/src/examples.qdoc b/src/quick/doc/src/examples.qdoc index 29f7a026182..2f6c87e8409 100644 --- a/src/quick/doc/src/examples.qdoc +++ b/src/quick/doc/src/examples.qdoc @@ -78,7 +78,7 @@ steps such as use cases and introductory material. For more information about Qt \list \li \l{Qt Creator: Creating Qt Quick Projects}{Creating Qt Quick Projects} \li \l{Qt Creator: Creating Components}{Creating Components} - \li \l{Qt Creator: Exporting from Design Tools}{Exporting from Design Tools} + \li \l{Qt Creator: Exporting QML}{Exporting Components} \li \l{Qt Creator: Using QML Modules with Plugins}{Using QML Modules with Plugins} \endlist \enddiv @@ -123,7 +123,6 @@ Creator. \b{QML Types and Controls} \list \li \l{Qt Quick Controls - Gallery}{Controls Gallery} - \li \l{Calendar Example} \li \l{tableview/gameoflife}{TableView} \li \l{Qt Quick Examples - Text}{Text and Fonts} \li \l{Qt Quick Examples - Toggle Switch}{Custom Toggle Switch} diff --git a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc index 7f5e0fa7606..9aa404a6121 100644 --- a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc +++ b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc @@ -52,11 +52,16 @@ options that align with the latest UI design trends. If these UI controls do not satisfy your application's needs, only then it is recommended to create a custom control. +You can use the controls when you design UIs in Qt Design Studio. In addition, +it provides timeline-based animations, visual effects, layouts, and a +live-preview for prototyping applications. \section2 Related Information \list \li \l{Qt Quick Controls} +\li \l{Customizing Qt Quick Controls} \li \l{Qt Quick} +\li \l{Qt Design Studio Manual} \endlist \omit @@ -87,66 +92,37 @@ of the target OS. For example, consider the following project directory structure: \badcode -project +MyModule ├── images │ ├── image1.png │ └── image2.png -├── project.pro -└── qml - └── main.qml +├── CMakeLists.txt +└── main.qml \endcode -The following entry in \c project.pro ensures that the resources are built into -the application binary, making them available when needed: +You may represent this structure as a \l{qt_add_qml_module}{CMake QML Module} in the following way: -\badcode - RESOURCES += \ - qml/main.qml \ - images/image1.png \ - images/image2.png -\endcode - -A more convenient approach is to use the -\l {files(pattern[, recursive=false])}{wildcard syntax} to select several files -at once: - -\badcode - RESOURCES += \ - $$files(qml/*.qml) \ - $$files(images/*.png) -\endcode - -This approach is convenient for applications that depend on a limited number -of resources. However, whenever a new file is added to \c RESOURCES using this -approach, it causes \e all of the other files in \c RESOURCES to be recompiled -as well. This can be inefficient, especially for large sets of files. -In this case, a better approach is to separate each type of resource into its -own \l [Qt Core] {Resource Collection Files}{.qrc} file. For example, the snippet -above could be changed to the following: - -\badcode - qml.files = $$files(*.qml) - qml.prefix = /qml - RESOURCES += qml - - images.files = $$files(*.png) - images.prefix = /images - RESOURCES += images +\code +qt_add_qml_module(my_module + URI MyModule + VERSION 1.0 + QML_FILES + main.qml + RESOURCES + images/image1.png + images/image2.png + # ... +) \endcode -Now, whenever a QML file is changed, only the QML files have to be recompiled. - -Sometimes it can be necessary to have more control over the path for a -specific file managed by the resource system. For example, if we wanted to give -\c image2.png an alias, we would need to switch to an explicit \c .qrc file. -\l {Creating Resource Files} explains how to do this in detail. +All QML files listed under \c {QML_FILES} will automatically get compiled \l {Ahead-of-Time Compilation}{ahead of time}. \section2 Related Information \list \li \l{The Qt Resource System} \endlist -\section1 Separate UI from Logic +\section1 Separate UI from Business Logic One of the key goals that most application developers want to achieve is to create a maintainable application. One of the ways to achieve this goal is @@ -162,8 +138,8 @@ reasons why an application's UI should be written in QML: \li JavaScript can easily be used in QML to respond to events. \endlist -Being a strongly typed language, C++ is best suited for an application's logic. -Typically, such code performs tasks such as complex calculations +Being a strongly typed language, C++ is best suited for an application's +business logic. Typically, such code performs tasks such as complex calculations or data processing, which are faster in C++ than QML. Qt offers various approaches to integrate QML and C++ code in an application. @@ -174,12 +150,6 @@ sufficient. The following snippet demonstrates examples of models written in QML: \qml - model: ListModel { - ListElement { name: "Item 1" } - ListElement { name: "Item 2" } - ListElement { name: "Item 3" } - } - model: [ "Item 1", "Item 2", "Item 3" ] model: 10 @@ -188,135 +158,21 @@ The following snippet demonstrates examples of models written in QML: Use \l {QAbstractItemModel Subclass}{C++} for dynamic data sets that are large or frequently modified. -\section2 Interacting with QML from C++ - -Although Qt enables you to manipulate QML from C++, it is not recommended to do -so. To explain why, let's take a look at a simplified example. - -\section3 Pulling References from QML - -Suppose we were writing the UI for a settings page: - -\qml - import QtQuick - import QtQuick.Controls - - Page { - Button { - text: qsTr("Restore default settings") - } - } -\endqml - -We want the button to do something in C++ when it is clicked. We know objects -in QML can emit change signals just like they can in C++, so we give the button -an \l [QML]{QtObject::}{objectName} so that we can find it from C++: - -\qml - Button { - objectName: "restoreDefaultsButton" - text: qsTr("Restore default settings") - } -\endqml - -Then, in C++, we find that object and connect to its change signal: - -\code - #include <QGuiApplication> - #include <QQmlApplicationEngine> - #include <QSettings> - - class Backend : public QObject - { - Q_OBJECT - - public: - Backend() {} - - public slots: - void restoreDefaults() { - settings.setValue("loadLastProject", QVariant(false)); - } - - private: - QSettings settings; - }; - - int main(int argc, char *argv[]) - { - QGuiApplication app(argc, argv); - - QQmlApplicationEngine engine; - engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); - if (engine.rootObjects().isEmpty()) - return -1; - - Backend backend; - - QObject *rootObject = engine.rootObjects().first(); - QObject *restoreDefaultsButton = rootObject->findChild<QObject*>("restoreDefaultsButton"); - QObject::connect(restoreDefaultsButton, SIGNAL(clicked()), - &backend, SLOT(restoreDefaults())); - - return app.exec(); - } - - #include "main.moc" -\endcode - -With this approach, references to objects are "pulled" from QML. -The problem with this is that the C++ logic layer depends on the QML -presentation layer. If we were to refactor the QML in such a way that the -\c objectName changes, or some other change breaks the ability for the C++ -to find the QML object, our workflow becomes much more complicated and tedious. - -\section3 Pushing References to QML +\section2 Exposing Data from C++ to QML Refactoring QML is a lot easier than refactoring C++, so in order to make maintenance pain-free, we should strive to keep C++ types unaware of QML as much as possible. This can be achieved by "pushing" references to C++ types -into QML: - -\code - int main(int argc, char *argv[]) - { - QGuiApplication app(argc, argv); - - Backend backend; +into QML. - QQmlApplicationEngine engine; - engine.rootContext()->setContextProperty("backend", &backend); - engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); - if (engine.rootObjects().isEmpty()) - return -1; - - return app.exec(); - } -\endcode - -The QML then calls the C++ slot directly: - -\qml - import QtQuick - import QtQuick.Controls - - Page { - Button { - text: qsTr("Restore default settings") - onClicked: backend.restoreDefaults() - } - } -\endqml +This can be done by using \l {Required properties}{required properties} and +setting them via \l QQmlApplicationEngine::setInitialProperties. It is also +possible to create one or multiple \l {QML_SINGLETON}{singletons} which will +return all the data the C++ side wants to provide to QML. With this approach, the C++ remains unchanged in the event that the QML needs to be refactored in the future. -In the example above, we set a context property on the root context to expose -the C++ object to QML. This means that the property is available to every -component loaded by the engine. Context properties are useful for objects that -must be available as soon as the QML is loaded and cannot be instantiated in -QML. - For a quick guide to choosing the correct approach to expose C++ types to QML, see \l {Choosing the Correct Integration Method Between C++ and QML}. @@ -326,6 +182,22 @@ see \l {Choosing the Correct Integration Method Between C++ and QML}. \li \l{Qt Quick Controls - Chat Tutorial}{Chat application tutorial} \endlist +\section1 Using Qt Design Studio + +Qt Design Studio uses UI files that have the filename extension \e {.ui.qml} +to separate the visual parts of the UI from the UI logic you implement in +\e {.qml} files. You should edit UI files only in the \uicontrol {2D} view in +Qt Design Studio. If you use some other tool to add code that Qt Design Studio +does not support, it displays error messages. Fix the errors to enable visual +editing of the UI files again. Typically, you should move the unsupported code +to a \e {.qml} file. + +\section2 Related Information + +\list + \li \l{Qt Design Studio: UI Files} +\endlist + \section1 Using Qt Quick Layouts Qt offers Qt Quick Layouts to arrange Qt Quick items visually in a layout. diff --git a/src/quick/doc/src/guidelines/qtquick-tool-qmllint.qdoc b/src/quick/doc/src/guidelines/qtquick-tool-qmllint.qdoc new file mode 100644 index 00000000000..0f21e1cae35 --- /dev/null +++ b/src/quick/doc/src/guidelines/qtquick-tool-qmllint.qdoc @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page qtquick-tool-qmllint.html +\title qmllint +\brief A tool for verifying the syntax of QML files and warning about +anti-patterns. + +\e qmllint is a tool shipped with Qt, that verifies the syntatic validity of +QML files. +It also warns about some QML anti-patterns. If you want to disable a specific +warning type, you can find the appropriate flag for doing so by passing +\c{--help} on the command line. + +By default, some issues will result in warnings that will be printed and result +in a non-zero exit code. +Minor issues however (such as unused imports) are just informational messages +by default and will not affect the exit code. +qmllint is very configurable and allows for disabling warnings or changing how +they are treated. +Users may freely turn any issue into a warning, informational message, or +disable them outright. + +qmllint warns about: +\list + \li Unqualified accesses of properties. + \li Usage of signal handlers without a matching signal. + \li Usage of with statements in QML. + \li Unused imports. + \li Deprecated components and properties. + \li And many other things. +\endlist + +\note In order for qmllint to work properly, it requires type information. +That information is provided by QML modules in the import paths. +The current directory, as well as the import paths for Qt's built-in types, +are used as import paths by default. +To add more import paths not included in the default, +add them via the \c{-I} flag. + +To get an overview and explanation of all available command line options, run \c{qmllint --help}. + +\section2 Disabling warnings inline + +You may at any point disable warnings temporarily in a file using \c{// qmllint +disable}. + +You can do this at the end of a line when a single line produces warnings: + +\code +Item { + property string foo + Item { + property string bar: foo // qmllint disable unqualified + } +} +\endcode + +Alternatively you can disable comments for a block of lines by putting the +comment in a line only containing \c{// qmllint disable}, ending the block with +\c{// qmllint enable}: + +\code +Item { + property string foo + Item { + // qmllint disable unqualified + property string bar: foo + property string bar2: foo + // qmllint enable unqualified + } +} +\endcode + +qmllint interprets all single line comments starting with \c {qmllint} as +directives. Thus you may not start a comment that way unless you wish to enable +or disable warnings. + +\note As done in the examples above it is preferable to explicitly specify the +warning or a list of warnings you want to disable instead of disabling all +warnings. This can be done by simply listing warning categories after \c{qmllint disable} (the names are +the same as the options listed in \c{--help}). + +\section2 Settings + +In addition to passing command-line options, you can also +configure qmllint via a settings file. +The command line \c{--write-defaults} will generate one for you. + +Setting files are named \c{.qmllint.ini} and look like this: + +\quotefile qmllint/config.ini + +Warning levels may be set to \c{info}, \c{warning} or \c{disable} just as with +command line options. + +qmllint will automatically look for a settings file at the location of the qml +file that is being linted. +It also looks through all parent directories to find this file and +automatically applies the settings therein. You can disable this behavior by +using \c{--ignore-settings}. +You may always override these defaults by specifying command line parameters +that take precedence over the warning levels in settings. + +\section2 Scripting + +qmllint can output JSON via the \c{--json} option which will return valid JSON +with warning messages, file and line location of warnings, and their severity +level. +This can be used to more easily integrate qmllint in your pre-commit hooks or +CI testing. + +\sa {Type Description Files} +*/ diff --git a/src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc b/src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc index a943f147ab2..96d2163eda6 100644 --- a/src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc +++ b/src/quick/doc/src/guidelines/qtquick-toolsnutilities.qdoc @@ -35,103 +35,68 @@ especially for Qt Quick developers. The following sections provide a brief introduction to those tools and utilities, and provide links to further information about them. -\section1 Qt Quick Designer +\section1 Qt Creator + +The \l{Qt Creator Manual}{Qt Creator} IDE is the key tool that enhances the overall developer +experience of working with Qt and Qt Quick. Its editing, formatting, profiling and +debugging features for Qt Quick make working with Qt Quick easier. -The Qt Quick Designer enables designing Qt Quick-based UIs using simple +\section1 Qt Design Studio + +\l{Qt Design Studio} enables designing Qt Quick-based UIs using simple drag-n-drop gestures that most designers are familiar with. It offers UI elements from the Qt Quick and Qt Quick Controls modules, as well as integration for custom UI elements. -The following is a list of example applications that use UIs created by -the Qt Quick Designer: - -\list - \li \l{Qt Quick Controls - Contact List} - \li \l{Qt Quick Controls - Flat Style} -\endlist +\section1 QML Debugger -\section2 QML Debugger and Profiler - -Being a declarative language, a piece of QML code provides minimal details -about the entities defined. In such a scenario, the QML debugger is a very -useful utility that enables: +The \l{QML debugger} is a very useful utility that enables: \list \li debugging JavaScript functions, \li executing JavaScript expressions, \li and inspecting QML properties. \endlist -Besides this, a QML profiler enables you to get necessary diagnostic information, +The QML debugger is part of both \l{Qt Creator} and \l{Qt Design Studio}. + +\section1 QML Profiler + +The \l{QML profiler} enables you to get necessary diagnostic information, allowing you to analyze the application code for performance issues. For example, too much JavaScript in each frame, long-running C++ functions, and so on. -\section2 Related Information -\list - \li \l{QML Debugger} - \li \l{QML Profiler} -\endlist +The profiler is part of both \l{Qt Creator} and \l{Qt Design Studio}. -\section1 QmlLive, GammaRay, and Squish +\section1 QmlLive -QmlLive is a 3rd party tool that offers a QML runtime capable of rendering +\l{QmlLive} is a 3rd party tool that offers a QML runtime capable of rendering changes to the code in realtime. It avoids the need to rebuild the application after every code change and install it on the target device. You can also extend it to build a custom runtime that suits your needs. -GammaRay is a useful utility that provides diagnostic information +\section1 GammaRay + +\l{GammaRay} is a useful utility that provides diagnostic information about your application. It is similar to the QML Profiler described in the earlier section, but offers a lot more. For example, the number of items or QObjects created, function calls made, time taken by each function call, property value introspection at runtime, and so on. Such information is very handy, especially while debugging QML applications. -Squish is a well-known testing tool that automates UI testing by recording +\section1 Squish + +\l{Squish} is a well-known testing tool that automates UI testing by recording your actions or running scripts. Once the tests are setup, UI tests are a lot easier to run. -\section2 Related Information -\list - \li \l{QmlLive} - \li \l{GammaRay} - \li \l{Squish} -\endlist - -\section1 Qt Creator - -The Qt Creator IDE is the key tool that enhances the overall developer experience of -working with Qt Quick. Its auto-completion and debugging features make working -with Qt Quick easier. Besides this, most of the tools and utilities -mentioned in the earlier sections are integrated into it, with the possibility of -integrating 3rd party tools such as QmlLive and GammaRay. - -\section2 Related Information -\list -\li \l{Qt Creator Manual} -\endlist - \section1 qmllint -\e qmllint is a tool shipped with Qt, that verifies the syntatic validity of QML files. + +\l{qmllint} is a tool shipped with Qt, that verifies the syntatic validity of QML files. It also warns about some QML anti-patterns. If you want to disable a specific warning type, you can find the appropriate flag for doing so by passing \c{--help} on the command line. -qmllint warns about -\list - \li Unqualified accesses of properties. - \li Usage of signal handlers without a matching signal. - \li Usage of with statements in QML. -\endlist - -In order for qmllint to work properly, it requires type information. That information -is provided by qmltypes files. qmltypes files in the current directory, as well as -those for Qt's built-in types, are discovered automatically. For qmltypes files from -libraries that reside outside of the current directory, you can provide their path -via the -I flag. - -\section2 Related Information -\list - \li \l{Type Description Files}{qmltypes} -\endlist +See the full documentation page of \l{qmllint} for details. \section1 qmlformat @@ -146,7 +111,4 @@ by specifying the \c{-n} flag. By default, qmlformat writes the formatted version of the file to stdout. If you wish to have your file updated in-place specify the \c{-i} flag. - -\section2 Related Information -\sa {QML Coding Conventions} */ diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc index 9d79ac862b3..b2be0431152 100644 --- a/src/quick/doc/src/qmltypereference.qdoc +++ b/src/quick/doc/src/qmltypereference.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! -\qmlmodule QtQuick 2.\QtMinorVersion +\qmlmodule QtQuick \title Qt Quick QML Types \ingroup qmlmodules \brief Provides graphical QML types. @@ -189,68 +189,32 @@ available when you import \c QtQuick. Font weighting is classified on a scale from 0 to 99, where a weight of 0 is ultralight, and 99 is extremely black. The following values are supported: - \table - \row - \li \c Font.Thin - \li 0 - \row - \li \c Font.ExtraLight - \li 12 - \row - \li \c Font.Light - \li 25 - \row - \li \c Font.Normal - \li 50 - \row - \li \c Font.Medium - \li 57 - \row - \li \c Font.DemiBold - \li 63 - \row - \li \c Font.Bold - \li 75 - \row - \li \c Font.ExtraBold - \li 81 - \row - \li \c Font.Black - \li 87 - \endtable + \value Font.Thin 0 + \value Font.ExtraLight 12 + \value Font.Light 25 + \value Font.Normal 50 + \value Font.Medium 57 + \value Font.DemiBold 63 + \value Font.Bold 75 + \value Font.ExtraBold 81 + \value Font.Black 87 Capitalization supports the following values: - \table - \row - \li \c Font.MixedCase - \li No capitalization change is applied. - \row - \li \c Font.AllUppercase - \li Alters the text to be rendered in all uppercase type. - \row - \li \c Font.AllLowercase - \li Alters the text to be rendered in all lowercase type. - \row - \li \c Font.SmallCaps - \li Alters the text to be rendered in small-caps type. - \row - \li \c Font.Capitalize - \li Alters the text to be rendered with the first character of each word as an uppercase character. - \endtable + \value Font.MixedCase No capitalization change is applied. + \value Font.AllUppercase Alters the text to be rendered in all uppercase type. + \value Font.AllLowercase Alters the text to be rendered in all lowercase type. + \value Font.SmallCaps Alters the text to be rendered in small-caps type. + \value Font.Capitalize Alters the text to be rendered with the first character of each word as an uppercase character. Setting the hinting preference only has an effect when using the "NativeRendering" render type. The property supports the following values: - \list - \value Font.PreferDefaultHinting - Use the default hinting level for the target platform. - \value Font.PreferNoHinting - If possible, render text without hinting the outlines - of the glyphs. - \value Font.PreferVerticalHinting - If possible, render text with no horizontal hinting, - but align glyphs to the pixel grid in the vertical direction. - \value Font.PreferFullHinting - If possible, render text with hinting in both horizontal and - vertical directions. - \endlist + \value Font.PreferDefaultHinting Use the default hinting level for the target platform. + \value Font.PreferNoHinting If possible, render text without hinting the outlines of the glyphs. + \value Font.PreferVerticalHinting If possible, render text with no horizontal hinting, + but align glyphs to the pixel grid in the vertical direction. + \value Font.PreferFullHinting If possible, render text with hinting in both horizontal and vertical directions. \sa {QML Basic Types} */ @@ -732,6 +696,73 @@ console.log(c + " " + d); // false true \li Description \li Example + \row + \li translate(vector3d vector) + \li Multiplies \c this matrix4x4 by another that translates coordinates by the components + of \c vector + \li \code +var m = Qt.matrix4x4(); +m.translate(Qt.vector3d(1,2,3)); +console.log(m.toString()); +// QMatrix4x4(1, 0, 0, 1, 0, 1, 0, 2, 0, 0, 1, 3, 0, 0, 0, 1) + \endcode + + \row + \li rotate(real angle, vector3d axis) + \li Multiples \c this matrix4x4 by another that rotates coordinates through + \c angle degrees about \c axis + \li \code +var m = Qt.matrix4x4(); +m.rotate(180,vector3d(1,0,0)); +console.log(m.toString()); +// QMatrix4x4(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1) + \endcode + + \row + \li scale(real factor) + \li Multiplies \c this matrix4x4 by another that scales coordinates by the given \c factor + \li \code +var m = Qt.matrix4x4(); +m.scale(2); +console.log(m.toString()); +// QMatrix4x4(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1) + \endcode + + \row + \li scale(real x, real y, real z) + \li Multiplies \c this matrix4x4 by another that scales coordinates by the components + \c x, \c y, and \c z + \li \code +var m = Qt.matrix4x4(); +m.scale(1,2,3); +console.log(m.toString()); +// QMatrix4x4(1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1) + \endcode + + \row + \li scale(vector3d vector) + \li Multiplies \c this matrix4x4 by another that scales coordinates by the components + of \c vector + \li \code +var m = Qt.matrix4x4(); +m.scale(Qt.vector3d(1,2,3)); +console.log(m.toString()); +// QMatrix4x4(1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1) + \endcode + + \row + \li lookAt(vector3d eye, vector3d center, vector3d up) + \li Multiplies \c this matrix4x4 by a viewing matrix derived from an \c eye point. + The \c center vector3d indicates the center of the view that the \c eye is looking at. + The \c up vector3d indicates which direction should be considered up with respect to + the \c eye. + \li \code +var m = Qt.matrix4x4(); +m.lookAt(Qt.vector3d(1,2,3),Qt.vector3d(1,2,0),Qt.vector3d(0,1,0)); +console.log(m.toString()); +// QMatrix4x4(1, 0, 0, -1, 0, 1, 0, -2, 0, 0, 1, -3, 0, 0, 0, 1) + \endcode + \row \li matrix4x4 times(matrix4x4 other) \li Returns the matrix4x4 result of multiplying \c this matrix4x4 with diff --git a/src/quick/doc/src/qt6-changes.qdoc b/src/quick/doc/src/qt6-changes.qdoc index 58a7ebb3e18..defacd95a1a 100644 --- a/src/quick/doc/src/qt6-changes.qdoc +++ b/src/quick/doc/src/qt6-changes.qdoc @@ -138,7 +138,7 @@ OpenGL. It will not be functional when using another graphics API, such as Vulkan or Metal. Applications relying on QQuickWidget should force the usage of OpenGL by calling - \c{QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi)} in their + \c{QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL)} in their main() function. \section2 Changes to QQuick* APIs @@ -206,7 +206,7 @@ not be functional when using another graphics API, such as Vulkan or Metal. Applications relying on QQuickFramebufferObject should force the usage of OpenGL by calling - \c{QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi)} in their + \c{QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL)} in their main() function. \li QQuickRenderControl has a slightly changed API: grab() is now diff --git a/src/quick/doc/src/qtquick.qdoc b/src/quick/doc/src/qtquick.qdoc index 46dfa5651fa..a8665a36410 100644 --- a/src/quick/doc/src/qtquick.qdoc +++ b/src/quick/doc/src/qtquick.qdoc @@ -148,6 +148,7 @@ Additional Qt Quick information: \li \l{Qt Quick Test QML Types}{Tests} - contains types for writing unit test for a QML application \endlist \li \l{Qt Quick Examples and Tutorials} +\li \l{Qt Quick Tools and Utilities} \li \l{Best Practices for QML and Qt Quick}{Qt Quick Guidelines} \endlist diff --git a/src/quick/doc/src/tutorial.qdoc b/src/quick/doc/src/tutorial.qdoc index e84753d8952..040685fae21 100644 --- a/src/quick/doc/src/tutorial.qdoc +++ b/src/quick/doc/src/tutorial.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -100,11 +100,13 @@ The \c font.pointSize and \c font.bold properties are related to fonts and use t \section2 Viewing the Example -To view what you have created, run the \l{Prototyping with qmlscene}{qmlscene} tool (located in the \c bin directory) with your filename as the first argument. -For example, to run the provided completed Tutorial 1 example from the install location, you would type: +To view what you have created, run the +\l{Prototyping with the QML Runtime Tool}{qml tool} (located in the +\c bin directory) with your filename as the first argument. For example, to run +the provided completed Tutorial 1 example from the install location, you would type: \code -qmlscene tutorials/helloworld/tutorial1.qml +qml tutorials/helloworld/tutorial1.qml \endcode */ diff --git a/src/quick/handlers/qquickdragaxis.cpp b/src/quick/handlers/qquickdragaxis.cpp index 88470c8a7d6..806b5d705af 100644 --- a/src/quick/handlers/qquickdragaxis.cpp +++ b/src/quick/handlers/qquickdragaxis.cpp @@ -76,3 +76,5 @@ void QQuickDragAxis::setEnabled(bool enabled) } QT_END_NAMESPACE + +#include "moc_qquickdragaxis_p.cpp" diff --git a/src/quick/handlers/qquickdraghandler.cpp b/src/quick/handlers/qquickdraghandler.cpp index 233516c3a3d..8c9464ee555 100644 --- a/src/quick/handlers/qquickdraghandler.cpp +++ b/src/quick/handlers/qquickdraghandler.cpp @@ -88,7 +88,7 @@ Q_LOGGING_CATEGORY(lcDragHandler, "qt.quick.handler.drag") At this time, drag-and-drop is not yet supported. - \sa Drag, MouseArea + \sa Drag, MouseArea, {Pointer Handlers Example} */ QQuickDragHandler::QQuickDragHandler(QQuickItem *parent) @@ -131,13 +131,13 @@ void QQuickDragHandler::onGrabChanged(QQuickPointerHandler *grabber, QPointingDe This property holds the snap mode. - The snap mode configures snapping of the \l target item's center to the event point. + The snap mode configures snapping of the \l target item's center to the \l eventPoint. Possible values: \value DragHandler.SnapNever Never snap - \value DragHandler.SnapAuto The \l target snaps if the event point was pressed outside of the \l target - item \e and the \l target is a descendant of \l parentItem (default) - \value DragHandler.SnapWhenPressedOutsideTarget The \l target snaps if the event point was pressed outside of the \l target + \value DragHandler.SnapAuto The \l target snaps if the \l eventPoint was pressed outside of the \l target + item \e and the \l target is a descendant of \l {PointerHandler::}{parent} item (default) + \value DragHandler.SnapWhenPressedOutsideTarget The \l target snaps if the \l eventPoint was pressed outside of the \l target \value DragHandler.SnapAlways Always snap */ QQuickDragHandler::SnapMode QQuickDragHandler::snapMode() const @@ -371,7 +371,7 @@ void QQuickDragHandler::setActiveTranslation(const QVector2D &trans) /*! \readonly \qmlproperty QVector2D QtQuick::DragHandler::translation - \deprecated Use activeTranslation + \deprecated [6.2] Use activeTranslation */ /*! @@ -395,3 +395,5 @@ void QQuickDragHandler::setActiveTranslation(const QVector2D &trans) */ QT_END_NAMESPACE + +#include "moc_qquickdraghandler_p.cpp" diff --git a/src/quick/handlers/qquickhandlerpoint.cpp b/src/quick/handlers/qquickhandlerpoint.cpp index c3149983c0a..52513f8273e 100644 --- a/src/quick/handlers/qquickhandlerpoint.cpp +++ b/src/quick/handlers/qquickhandlerpoint.cpp @@ -49,7 +49,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcTouchTarget) \inqmlmodule QtQuick \brief An event point. - A QML representation of a QEventPoint. + A handler-owned QML representation of a QEventPoint. It's possible to make bindings to properties of a handler's current \l {SinglePointHandler::point}{point} or @@ -58,12 +58,12 @@ Q_DECLARE_LOGGING_CATEGORY(lcTouchTarget) \snippet pointerHandlers/dragHandlerNullTarget.qml 0 The point is kept up-to-date when the DragHandler is actively responding to - an EventPoint; but after the point is released, or when the current point is + an \l eventPoint; but after the point is released, or when the current point is being handled by a different handler, \c position.x and \c position.y are 0. - \note This is practically identical to QtQuick::EventPoint; however an - EventPoint is a long-lived QObject which is invalidated between gestures - and reused for subsequent event deliveries. Continuous bindings to its + \note This is practically identical to \l eventPoint; however an eventPoint + is a short-lived copy of a long-lived Q_GADGET which is invalidated between + gestures and reused for subsequent event deliveries. Continuous bindings to its properties are not possible, and an individual handler cannot rely on it outside the period when that point is part of an active gesture which that handler is handling. HandlerPoint is a Q_GADGET that the handler owns. @@ -186,7 +186,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points) During a touch gesture, from the time that the first finger is pressed until the last finger is released, each touchpoint will have a unique ID number. Likewise, if input from multiple devices occurs (for example - simultaneous mouse and touch presses), all the current event points from + simultaneous mouse and touch presses), all the current \l{eventPoint}{eventPoints} from all the devices will have unique IDs. \note Do not assume that id numbers start at zero or that they are @@ -223,7 +223,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points) \qmlproperty QPointF QtQuick::HandlerPoint::position \brief The position within the \c parent Item - This is the position of the event point relative to the bounds of + This is the position of the \l eventPoint relative to the bounds of the \l {PointerHandler::parent} {parent}. */ @@ -232,7 +232,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points) \qmlproperty QPointF QtQuick::HandlerPoint::scenePosition \brief The position within the scene - This is the position of the event point relative to the bounds of the Qt + This is the position of the \l eventPoint relative to the bounds of the Qt Quick scene (typically the whole window). */ @@ -290,7 +290,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points) This is a velocity vector pointing in the direction of movement, in logical pixels per second. It has x and y components, at least one of which will be nonzero when this point is in motion. It holds the average recent velocity: - how fast and in which direction the event point has been moving recently. + how fast and in which direction the \l eventPoint has been moving recently. \sa QtQuick::TouchPoint::velocity, QEventPoint::velocity */ @@ -345,4 +345,13 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points) \sa QtQuick::TouchPoint::ellipseDiameters, QEventPoint::ellipseDiameters */ +/*! + \readonly + \qmlproperty PointerDevice QtQuick::handlerPoint::device + + This property holds the device that the point (and its event) came from. +*/ + QT_END_NAMESPACE + +#include "moc_qquickhandlerpoint_p.cpp" diff --git a/src/quick/handlers/qquickhoverhandler.cpp b/src/quick/handlers/qquickhoverhandler.cpp index 020afc647a7..c5067881a64 100644 --- a/src/quick/handlers/qquickhoverhandler.cpp +++ b/src/quick/handlers/qquickhoverhandler.cpp @@ -67,7 +67,7 @@ Q_LOGGING_CATEGORY(lcHoverHandler, "qt.quick.handler.hover") The \l cursorShape property allows changing the cursor whenever \l hovered changes to \c true. - \sa MouseArea, PointHandler + \sa MouseArea, PointHandler, {Pointer Handlers Example} */ QQuickHoverHandler::QQuickHoverHandler(QQuickItem *parent) @@ -101,14 +101,16 @@ bool QQuickHoverHandler::event(QEvent *event) void QQuickHoverHandler::componentComplete() { - if (auto par = parentItem()) { - par->setAcceptHoverEvents(true); + QQuickSinglePointHandler::componentComplete(); + if (auto par = parentItem()) QQuickItemPrivate::get(par)->setHasHoverInChild(true); - } } bool QQuickHoverHandler::wantsPointerEvent(QPointerEvent *event) { + // No state change should occur if a button is being pressed or released. + if (event->isSinglePointEvent() && static_cast<QSinglePointEvent *>(event)->button()) + return false; auto &point = event->point(0); if (QQuickPointerDeviceHandler::wantsPointerEvent(event) && wantsEventPoint(event, point) && parentContains(point)) { // assume this is a mouse or tablet event, so there's only one point @@ -139,7 +141,6 @@ void QQuickHoverHandler::handleEventPoint(QPointerEvent *ev, QEventPoint &point) else if (QQuickDeliveryAgentPrivate::isTabletEvent(ev)) m_hoveredTablet = true; setHovered(hovered); - setPassiveGrab(ev, point); } /*! @@ -161,6 +162,98 @@ void QQuickHoverHandler::setHovered(bool hovered) } } +/*! + \internal + \qmlproperty flags QtQuick::HoverHandler::acceptedButtons + + This property is not used in HoverHandler. +*/ + +/*! + \qmlproperty flags QtQuick::HoverHandler::acceptedDevices + + The types of pointing devices that can activate the pointer handler. + + By default, this property is set to + \l{QInputDevice::DeviceType}{PointerDevice.AllDevices}. + If you set it to an OR combination of device types, it will ignore pointer + events from the non-matching devices. + + For example, an item could be made to respond to mouse hover in one way, + and stylus hover in another way, with two handlers: + + \snippet pointerHandlers/hoverMouseOrStylus.qml 0 + + The available device types are as follows: + + \value PointerDevice.Mouse A mouse. + \value PointerDevice.TouchScreen A touchscreen. + \value PointerDevice.TouchPad A touchpad or trackpad. + \value PointerDevice.Stylus A stylus on a graphics tablet. + \value PointerDevice.Airbrush An airbrush on a graphics tablet. + \value PointerDevice.Puck A digitizer with crosshairs, on a graphics tablet. + \value PointerDevice.AllDevices Any type of pointing device. + + \sa QInputDevice::DeviceType +*/ + +/*! + \qmlproperty flags QtQuick::HoverHandler::acceptedPointerTypes + + The types of pointing instruments (generic, stylus, eraser, and so on) + that can activate the pointer handler. + + By default, this property is set to + \l {QPointingDevice::PointerType} {PointerDevice.AllPointerTypes}. + If you set it to an OR combination of device types, it will ignore events + from non-matching events. + + For example, you could provide feedback by changing the cursor depending on + whether a stylus or eraser is hovering over a graphics tablet: + + \snippet pointerHandlers/hoverStylusOrEraser.qml 0 + + The available pointer types are as follows: + + \value PointerDevice.Generic A mouse or a device that emulates a mouse. + \value PointerDevice.Finger A finger on a touchscreen (hover detection is unlikely). + \value PointerDevice.Pen A stylus on a graphics tablet. + \value PointerDevice.Eraser An eraser on a graphics tablet. + \value PointerDevice.Cursor A digitizer with crosshairs, on a graphics tablet. + \value PointerDevice.AllPointerTypes Any type of pointing device. + + \sa QPointingDevice::PointerType +*/ + +/*! + \qmlproperty flags QtQuick::HoverHandler::acceptedModifiers + + If this property is set, a hover event is handled only if the given keyboard + modifiers are pressed. The event is ignored without the modifiers. + + This property is set to \c Qt.KeyboardModifierMask by default, resulting + in handling hover events regardless of any modifier keys. + + For example, an \l[QML]{Item} could have two handlers of the same type, one + of which is enabled only if the required keyboard modifiers are pressed: + + \snippet pointerHandlers/hoverModifiers.qml 0 + + The available modifiers are as follows: + + \value Qt.NoModifier No modifier key is allowed. + \value Qt.ShiftModifier A Shift key on the keyboard must be pressed. + \value Qt.ControlModifier A Ctrl key on the keyboard must be pressed. + \value Qt.AltModifier An Alt key on the keyboard must be pressed. + \value Qt.MetaModifier A Meta key on the keyboard must be pressed. + \value Qt.KeypadModifier A keypad button must be pressed. + \value Qt.GroupSwitchModifier A Mode_switch key on the keyboard must be pressed. + X11 only (unless activated on Windows by a command line argument). + \value Qt.KeyboardModifierMask The handler ignores modifier keys. + + \sa Qt::KeyboardModifier +*/ + /*! \since 5.15 \qmlproperty Qt::CursorShape QtQuick::HoverHandler::cursorShape @@ -209,4 +302,13 @@ void QQuickHoverHandler::setHovered(bool hovered) \sa Qt::CursorShape, QQuickItem::cursor() */ +/*! + \internal + \qmlproperty flags HoverHandler::dragThreshold + + This property is not used in HoverHandler. +*/ + QT_END_NAMESPACE + +#include "moc_qquickhoverhandler_p.cpp" diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp index 8c13c84914f..70ceeb47fc7 100644 --- a/src/quick/handlers/qquickmultipointhandler.cpp +++ b/src/quick/handlers/qquickmultipointhandler.cpp @@ -185,7 +185,7 @@ QVector<QEventPoint> QQuickMultiPointHandler::eligiblePoints(QPointerEvent *even // In other cases however, check whether it would be OK to steal the grab if the handler chooses to do that. bool stealingAllowed = event->isBeginEvent() || event->isEndEvent(); for (int i = 0; i < event->pointCount(); ++i) { - auto &p = QMutableEventPoint::from(event->point(i)); + auto &p = event->point(i); if (QQuickDeliveryAgentPrivate::isMouseEvent(event)) { if (static_cast<QMouseEvent *>(event)->buttons() == Qt::NoButton) continue; @@ -398,7 +398,7 @@ bool QQuickMultiPointHandler::grabPoints(QPointerEvent *event, const QVector<QEv } } if (allowed) { - for (auto point : points) + for (const auto &point : qAsConst(points)) setExclusiveGrab(event, point); } return allowed; @@ -444,3 +444,5 @@ QMetaProperty &QQuickMultiPointHandlerPrivate::yMetaProperty() const } QT_END_NAMESPACE + +#include "moc_qquickmultipointhandler_p.cpp" diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp index 403af14ec8b..cb45509de0e 100644 --- a/src/quick/handlers/qquickpinchhandler.cpp +++ b/src/quick/handlers/qquickpinchhandler.cpp @@ -85,7 +85,14 @@ Q_LOGGING_CATEGORY(lcPinchHandler, "qt.quick.handler.pinch") \image touchpoints-pinchhandler.png - \sa PinchArea + \note The pinch begins when the number of fingers pressed is between + \l {MultiPointHandler::minimumPointCount}{minimumPointCount} and + \l {MultiPointHandler::maximumPointCount}{maximumPointCount}, inclusive. + Until then, PinchHandler tracks the positions of any pressed fingers, + but if it's a disallowed number, it does not scale or rotate + its \l target, and the \l active property remains \c false. + + \sa PinchArea, QPointerEvent::pointCount(), QNativeGestureEvent::fingerCount(), {Pointer Handlers Example} */ QQuickPinchHandler::QQuickPinchHandler(QQuickItem *parent) @@ -163,7 +170,8 @@ bool QQuickPinchHandler::wantsPointerEvent(QPointerEvent *event) #if QT_CONFIG(gestures) if (event->type() == QEvent::NativeGesture) { const auto gesture = static_cast<const QNativeGestureEvent *>(event); - if (minimumPointCount() == 2) { + if (!gesture->fingerCount() || (gesture->fingerCount() >= minimumPointCount() && + gesture->fingerCount() <= maximumPointCount())) { switch (gesture->gestureType()) { case Qt::BeginNativeGesture: case Qt::EndNativeGesture: @@ -209,19 +217,13 @@ bool QQuickPinchHandler::wantsPointerEvent(QPointerEvent *event) */ /*! - \qmlproperty int QtQuick::PinchHandler::minimumTouchPoints - - The pinch begins when this number of fingers are pressed. - Until then, PinchHandler tracks the positions of any pressed fingers, - but if it's an insufficient number, it does not scale or rotate - its \l target, and the \l active property will remain false. -*/ - -/*! + \readonly \qmlproperty bool QtQuick::PinchHandler::active - This property is true when all the constraints (epecially \l minimumTouchPoints) - are satisfied and the \l target, if any, is being manipulated. + This property is \c true when all the constraints (epecially + \l {MultiPointHandler::minimumPointCount}{minimumPointCount} and + \l {MultiPointHandler::maximumPointCount}{maximumPointCount}) are satisfied + and the \l target, if any, is being manipulated. */ void QQuickPinchHandler::onActiveChanged() @@ -237,8 +239,8 @@ void QQuickPinchHandler::onActiveChanged() m_startRotation = t->rotation(); m_startPos = t->position(); } else { - m_startScale = 1; - m_startRotation = 0; + m_startScale = m_accumulatedScale; + m_startRotation = 0; // TODO m_accumulatedRotation (QTBUG-94168) } qCDebug(lcPinchHandler) << "activated with starting scale" << m_startScale << "rotation" << m_startRotation; } else { @@ -270,6 +272,7 @@ void QQuickPinchHandler::handlePointerEventImpl(QPointerEvent *event) return; case Qt::ZoomNativeGesture: m_activeScale *= 1 + gesture->value(); + m_activeScale = qBound(m_minimumScale, m_activeScale, m_maximumScale); break; case Qt::RotateNativeGesture: m_activeRotation += gesture->value(); @@ -458,6 +461,13 @@ void QQuickPinchHandler::handlePointerEventImpl(QPointerEvent *event) emit updated(); } +/*! + \internal + \qmlproperty flags QtQuick::PinchHandler::acceptedButtons + + This property is not used in PinchHandler. +*/ + /*! \readonly \qmlproperty QtQuick::HandlerPoint QtQuick::PinchHandler::centroid @@ -505,6 +515,11 @@ void QQuickPinchHandler::handlePointerEventImpl(QPointerEvent *event) The translation of the gesture \l centroid. It is \c (0, 0) when the gesture begins. + + \note On some touchpads, such as on a \macos trackpad, native gestures do + not generate any translation values, and this property stays at \c (0, 0). */ QT_END_NAMESPACE + +#include "moc_qquickpinchhandler_p.cpp" diff --git a/src/quick/handlers/qquickpointerdevicehandler.cpp b/src/quick/handlers/qquickpointerdevicehandler.cpp index 27f9c3fc36c..a016ba5f12c 100644 --- a/src/quick/handlers/qquickpointerdevicehandler.cpp +++ b/src/quick/handlers/qquickpointerdevicehandler.cpp @@ -175,7 +175,7 @@ void QQuickPointerDeviceHandler::setAcceptedDevices(QPointingDevice::DeviceTypes By default, this property is set to \l {QPointingDevice::PointerType} {PointerDevice.AllPointerTypes}. If you set it to an OR combination of device types, it will ignore events - from non-matching events. + from non-matching \l {PointerDevice}{devices}. For example, a control could be made to respond to mouse, touch, and stylus clicks in some way, but delete itself if tapped with an eraser tool on a graphics tablet, @@ -185,7 +185,7 @@ void QQuickPointerDeviceHandler::setAcceptedDevices(QPointingDevice::DeviceTypes Rectangle { id: rect TapHandler { - acceptedPointerTypes: PointerDevice.GenericPointer | PointerDevice.Finger | PointerDevice.Pen + acceptedPointerTypes: PointerDevice.Generic | PointerDevice.Finger | PointerDevice.Pen onTapped: console.log("clicked") } TapHandler { @@ -306,7 +306,7 @@ bool QQuickPointerDeviceHandler::wantsPointerEvent(QPointerEvent *event) if (d->acceptedModifiers != Qt::KeyboardModifierMask && event->modifiers() != d->acceptedModifiers) return false; // Some handlers (HoverHandler, PinchHandler) set acceptedButtons to Qt::NoButton to indicate that button state is irrelevant. - if (event->pointingDevice()->pointerType() != QPointingDevice::PointerType::Finger && + if (event->pointingDevice()->type() != QPointingDevice::DeviceType::TouchScreen && acceptedButtons() != Qt::NoButton && event->type() != QEvent::Wheel && (static_cast<QSinglePointEvent *>(event)->buttons() & acceptedButtons()) == 0 && (static_cast<QSinglePointEvent *>(event)->button() & acceptedButtons()) == 0) @@ -315,3 +315,5 @@ bool QQuickPointerDeviceHandler::wantsPointerEvent(QPointerEvent *event) } QT_END_NAMESPACE + +#include "moc_qquickpointerdevicehandler_p.cpp" diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp index c1b20b13881..ec3c972af3f 100644 --- a/src/quick/handlers/qquickpointerhandler.cpp +++ b/src/quick/handlers/qquickpointerhandler.cpp @@ -92,7 +92,7 @@ QQuickPointerHandler::~QQuickPointerHandler() \qmlproperty real PointerHandler::margin The margin beyond the bounds of the \l {PointerHandler::parent}{parent} - item within which an event point can activate this handler. For example, on + item within which an \l eventPoint can activate this handler. For example, on a PinchHandler where the \l {PointerHandler::target}{target} is also the \c parent, it's useful to set this to a distance at least half the width of a typical user's finger, so that if the \c parent has been scaled down @@ -125,7 +125,7 @@ void QQuickPointerHandler::setMargin(qreal pointDistanceThreshold) \qmlproperty int PointerHandler::dragThreshold \since 5.15 - The distance in pixels that the user must drag an event point in order to + The distance in pixels that the user must drag an \l eventPoint in order to have it treated as a drag gesture. The default value depends on the platform and screen resolution. @@ -217,9 +217,11 @@ void QQuickPointerHandler::setCursorShape(Qt::CursorShape shape) return; d->cursorShape = shape; d->cursorSet = true; - QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parentItem()); - itemPriv->hasCursorHandler = true; - itemPriv->setHasCursorInChild(true); + if (auto *parent = parentItem()) { + QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parent); + itemPriv->hasCursorHandler = true; + itemPriv->setHasCursorInChild(true); + } emit cursorShapeChanged(); } @@ -230,9 +232,11 @@ void QQuickPointerHandler::resetCursorShape() return; d->cursorShape = Qt::ArrowCursor; d->cursorSet = false; - QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parentItem()); - itemPriv->hasCursorHandler = false; - itemPriv->setHasCursorInChild(itemPriv->hasCursor); + if (auto *parent = parentItem()) { + QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parent); + itemPriv->hasCursorHandler = false; + itemPriv->setHasCursorInChild(itemPriv->hasCursor); + } emit cursorShapeChanged(); } @@ -248,8 +252,8 @@ bool QQuickPointerHandler::isCursorShapeExplicitlySet() const The \a grabber (subject) will be the Input Handler whose state is changing, or null if the state change regards an Item. The \a transition (verb) tells what happened. - The \a point (object) is the point that was grabbed or ungrabbed. - EventPoint has the sole responsibility to call this function. + The \a point (object) is the \l eventPoint that was grabbed or ungrabbed. + QQuickDeliveryAgent calls this function. The Input Handler must react in whatever way is appropriate, and must emit the relevant signals (for the benefit of QML code). A subclass is allowed to override this virtual function, but must always @@ -432,6 +436,8 @@ bool QQuickPointerHandler::approveGrabTransition(QPointerEvent *event, const QEv This handler can take the exclusive grab from another handler of the same class. \value PointerHandler.CanTakeOverFromHandlersOfDifferentType This handler can take the exclusive grab from any kind of handler. + \value PointerHandler.CanTakeOverFromItems + This handler can take the exclusive grab from any type of Item. \value PointerHandler.CanTakeOverFromAnything This handler can take the exclusive grab from any type of Item or Handler. \value PointerHandler.ApprovesTakeOverByHandlersOfSameType @@ -472,6 +478,14 @@ void QQuickPointerHandler::classBegin() void QQuickPointerHandler::componentComplete() { + Q_D(const QQuickPointerHandler); + if (d->cursorSet) { + if (auto *parent = parentItem()) { + QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(parent); + itemPriv->hasCursorHandler = true; + itemPriv->setHasCursorInChild(true); + } + } } QPointerEvent *QQuickPointerHandler::currentEvent() @@ -646,10 +660,12 @@ bool QQuickPointerHandler::event(QEvent *e) void QQuickPointerHandler::handlePointerEvent(QPointerEvent *event) { + Q_D(QQuickPointerHandler); bool wants = wantsPointerEvent(event); qCDebug(lcPointerHandlerDispatch) << metaObject()->className() << objectName() << "on" << parent()->metaObject()->className() << parent()->objectName() << (wants ? "WANTS" : "DECLINES") << event; + d->currentEvent = event; if (wants) { handlePointerEventImpl(event); } else { @@ -665,6 +681,7 @@ void QQuickPointerHandler::handlePointerEvent(QPointerEvent *event) } } } + d->currentEvent = nullptr; QQuickPointerHandlerPrivate::deviceDeliveryTargets(event->device()).append(this); } @@ -690,9 +707,9 @@ bool QQuickPointerHandler::wantsEventPoint(const QPointerEvent *event, const QEv \qmlproperty bool QtQuick::PointerHandler::active This holds true whenever this Input Handler has taken sole responsibility - for handing one or more EventPoints, by successfully taking an exclusive - grab of those points. This means that it is keeping its properties - up-to-date according to the movements of those Event Points and actively + for handing one or more \l {eventPoint}{eventPoints}, by successfully taking an + exclusive grab of those points. This means that it is keeping its properties + up-to-date according to the movements of those eventPoints and actively manipulating its \l target (if any). */ void QQuickPointerHandler::setActive(bool active) @@ -706,10 +723,8 @@ void QQuickPointerHandler::setActive(bool active) } } -void QQuickPointerHandler::handlePointerEventImpl(QPointerEvent *event) +void QQuickPointerHandler::handlePointerEventImpl(QPointerEvent *) { - Q_D(QQuickPointerHandler); - d->currentEvent = event; } /*! @@ -718,18 +733,18 @@ void QQuickPointerHandler::handlePointerEventImpl(QPointerEvent *event) The \l Item which is the scope of the handler; the Item in which it was declared. The handler will handle events on behalf of this Item, which means a - pointer event is relevant if at least one of its event points occurs within + pointer event is relevant if at least one of its \l {eventPoint}{eventPoints} occurs within the Item's interior. Initially \l [QML] {target} {target()} is the same, but it can be reassigned. - \note When a handler is declared in a \l QtQuick3D.Model object, the parent - is not an Item, therefore this property is \c null. + \note When a handler is declared in a \l [QtQuick3D] {Model}{QtQuick3D.Model} + object, the parent is not an Item, therefore this property is \c null. \sa {target}, QObject::parent() */ /*! - \qmlsignal QtQuick::PointerHandler::grabChanged(GrabTransition transition, EventPoint point) + \qmlsignal QtQuick::PointerHandler::grabChanged(PointerDevice::GrabTransition transition, eventPoint point) This signal is emitted when the grab has changed in some way which is relevant to this handler. @@ -793,3 +808,5 @@ QVector<QObject *> &QQuickPointerHandlerPrivate::deviceDeliveryTargets(const QIn } QT_END_NAMESPACE + +#include "moc_qquickpointerhandler_p.cpp" diff --git a/src/quick/handlers/qquickpointhandler.cpp b/src/quick/handlers/qquickpointhandler.cpp index 3ce95db51a4..94d1f2f75cc 100644 --- a/src/quick/handlers/qquickpointhandler.cpp +++ b/src/quick/handlers/qquickpointhandler.cpp @@ -102,7 +102,8 @@ QT_BEGIN_NAMESPACE PointHandler will not automatically manipulate the \c target item in any way. You need to use bindings to make it react to the \l point. - \note On macOS, PointHandler does not react to the trackpad by default. + \note On macOS, PointHandler does not react to multiple fingers on the + trackpad by default, although it does react to a pressed point (mouse position). That is because macOS can provide either native gesture recognition, or raw touchpoints, but not both. We prefer to use the native gesture event in PinchHandler, so we do not want to disable it by enabling touch. However @@ -111,7 +112,7 @@ QT_BEGIN_NAMESPACE want to react to all the touchpoints but do not require the smooth native-gesture experience. - \sa MultiPointTouchArea + \sa MultiPointTouchArea, HoverHandler, {Pointer Handlers Example} */ QQuickPointHandler::QQuickPointHandler(QQuickItem *parent) @@ -164,4 +165,127 @@ QVector2D QQuickPointHandler::translation() const return QVector2D(point().position() - point().pressPosition()); } +/*! + \qmlproperty flags PointHandler::acceptedButtons + + The mouse buttons that can activate this PointHandler. + + By default, this property is set to \l {QtQuick::MouseEvent::button} {Qt.LeftButton}. + It can be set to an OR combination of mouse buttons, and will ignore events + in which other buttons are pressed or held. + + \snippet pointerHandlers/pointHandlerAcceptedButtons.qml 0 + + \note On a touchscreen, there are no buttons, so this property does not + prevent PointHandler from reacting to touchpoints. +*/ + +/*! + \qmlproperty flags PointHandler::acceptedDevices + + The types of pointing devices that can activate this PointHandler. + + By default, this property is set to + \l{QInputDevice::DeviceType}{PointerDevice.AllDevices}. + If you set it to an OR combination of device types, it will ignore events + from non-matching \l {PointerDevice}{devices}: + + \snippet pointerHandlers/pointHandler.qml 1 +*/ + +/*! + \qmlproperty flags PointHandler::acceptedPointerTypes + + The types of pointing instruments (finger, stylus, eraser, etc.) + that can activate this PointHandler. + + By default, this property is set to + \l {QPointingDevice::PointerType} {PointerDevice.AllPointerTypes}. + If you set it to an OR combination of device types, it will ignore events + from non-matching \l {PointerDevice}{devices}: + + \snippet pointerHandlers/pointHandlerCanvasDrawing.qml 0 + + The \l {Pointer Handlers Example} includes a more complex example for + drawing on a Canvas with a graphics tablet. +*/ + +/*! + \qmlproperty flags PointHandler::acceptedModifiers + + If this property is set, PointHandler requires the given keyboard modifiers + to be pressed in order to react to \l {PointerEvent}{PointerEvents}, and + otherwise ignores them. + + If this property is set to \c Qt.KeyboardModifierMask (the default value), + then PointHandler ignores the modifier keys. + + For example, an \l [QML] Item could have two handlers, one of which is + enabled only if the required keyboard modifier is pressed: + + \snippet pointerHandlers/pointHandlerAcceptedModifiers.qml 0 + + If you set \c acceptedModifiers to an OR combination of modifier keys, + it means \e all of those modifiers must be pressed to activate the handler. + + The available modifiers are as follows: + + \value NoModifier No modifier key is allowed. + \value ShiftModifier A Shift key on the keyboard must be pressed. + \value ControlModifier A Ctrl key on the keyboard must be pressed. + \value AltModifier An Alt key on the keyboard must be pressed. + \value MetaModifier A Meta key on the keyboard must be pressed. + \value KeypadModifier A keypad button must be pressed. + \value GroupSwitchModifier X11 only (unless activated on Windows by a command line argument). + A Mode_switch key on the keyboard must be pressed. + \value KeyboardModifierMask The handler does not care which modifiers are pressed. + + \sa Qt::KeyboardModifier +*/ + +/*! + \readonly + \qmlproperty bool PointHandler::active + + This holds \c true whenever the constraints are satisfied and this + PointHandler is reacting. This means that it is keeping its properties + up-to-date according to the movements of the \l {eventPoint}{eventPoints} + that satisfy the constraints. +*/ + +/*! + \internal + \qmlproperty flags PointHandler::dragThreshold + + This property is not used in PointHandler. +*/ + +/*! + \qmlproperty real PointHandler::margin + + The margin beyond the bounds of the \l {PointerHandler::parent}{parent} + item within which an \l eventPoint can activate this handler. + + The default value is \c 0. + + \snippet pointerHandlers/pointHandlerMargin.qml 0 +*/ + +/*! + \qmlproperty real PointHandler::target + + A property that can conveniently hold an Item to be manipulated or to show + feedback. Unlike other \l {Qt Quick Input Handlers}{Pointer Handlers}, + PointHandler does not do anything with the \c target on its own: you + usually need to create reactive bindings to properties such as + \l SinglePointHandler::point and \l PointHandler::active. If you declare + an Item instance here, you need to explicitly set its \l {Item::}{parent}, + because PointHandler is not an Item. + + By default, it is the same as the \l {PointerHandler::}{parent}, the Item + within which the handler is declared. +*/ + QT_END_NAMESPACE + +#include "moc_qquickpointhandler_p.cpp" diff --git a/src/quick/handlers/qquicksinglepointhandler.cpp b/src/quick/handlers/qquicksinglepointhandler.cpp index aa650654eb4..22b475637ad 100644 --- a/src/quick/handlers/qquicksinglepointhandler.cpp +++ b/src/quick/handlers/qquicksinglepointhandler.cpp @@ -209,7 +209,7 @@ QQuickHandlerPoint QQuickSinglePointHandler::point() const \readonly \qmlproperty HandlerPoint QtQuick::SinglePointHandler::point - The event point currently being handled. When no point is currently being + The \l eventPoint currently being handled. When no point is currently being handled, this object is reset to default values (all coordinates are 0). */ @@ -226,3 +226,5 @@ void QQuickSinglePointHandlerPrivate::reset() } QT_END_NAMESPACE + +#include "moc_qquicksinglepointhandler_p.cpp" diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp index d16c9e23cb0..2b907d38059 100644 --- a/src/quick/handlers/qquicktaphandler.cpp +++ b/src/quick/handlers/qquicktaphandler.cpp @@ -77,12 +77,14 @@ int QQuickTapHandler::m_touchMultiTapDistanceSquared(-1); button in order to cancel the click. For this use case, set the \l gesturePolicy to \c TapHandler.ReleaseWithinBounds. + \snippet pointerHandlers/tapHandlerButton.qml 0 + For multi-tap gestures (double-tap, triple-tap etc.), the distance moved must not exceed QStyleHints::mouseDoubleClickDistance() with mouse and QStyleHints::touchDoubleTapDistance() with touch, and the time between taps must not exceed QStyleHints::mouseDoubleClickInterval(). - \sa MouseArea + \sa MouseArea, {Pointer Handlers Example} */ QQuickTapHandler::QQuickTapHandler(QQuickItem *parent) @@ -119,15 +121,16 @@ bool QQuickTapHandler::wantsEventPoint(const QPointerEvent *event, const QEventP ret = parentContains(point); break; case QEventPoint::Updated: + ret = point.id() == this->point().id(); switch (m_gesturePolicy) { case DragThreshold: - ret = !overThreshold && parentContains(point); + ret = ret && !overThreshold && parentContains(point); break; case WithinBounds: - ret = parentContains(point); + ret = ret && parentContains(point); break; case ReleaseWithinBounds: - ret = point.id() == this->point().id(); + // no change to ret: depends only whether it's the already-tracking point ID break; } break; @@ -180,7 +183,7 @@ void QQuickTapHandler::handleEventPoint(QPointerEvent *event, QEventPoint &point /*! \qmlproperty real QtQuick::TapHandler::longPressThreshold - The time in seconds that an event point must be pressed in order to + The time in seconds that an \l eventPoint must be pressed in order to trigger a long press gesture and emit the \l longPressed() signal. If the point is released before this time limit, a tap can be detected if the \l gesturePolicy constraint is satisfied. The default value is @@ -225,31 +228,79 @@ void QQuickTapHandler::timerEvent(QTimerEvent *event) If the spatial constraint is violated, \l pressed transitions immediately from true to false, regardless of the time held. - \value TapHandler.DragThreshold - (the default value) The event point must not move significantly. - If the mouse, finger or stylus moves past the system-wide drag - threshold (QStyleHints::startDragDistance), the tap gesture is - canceled, even if the button or finger is still pressed. This policy - can be useful whenever TapHandler needs to cooperate with other - input handlers (for example \l DragHandler) or event-handling Items - (for example QtQuick Controls), because in this case TapHandler - will not take the exclusive grab, but merely a passive grab. - - \value TapHandler.WithinBounds - If the event point leaves the bounds of the \c parent Item, the tap - gesture is canceled. The TapHandler will take the exclusive grab on - press, but will release the grab as soon as the boundary constraint - is no longer satisfied. - - \value TapHandler.ReleaseWithinBounds - At the time of release (the mouse button is released or the finger - is lifted), if the event point is outside the bounds of the - \c parent Item, a tap gesture is not recognized. This corresponds to - typical behavior for button widgets: you can cancel a click by - dragging outside the button, and you can also change your mind by - dragging back inside the button before release. Note that it's - necessary for TapHandler take the exclusive grab on press and retain - it until release in order to detect this gesture. + The \c gesturePolicy also affects grab behavior as described below. + + \table + \header + \li Constant + \li Description + \row + \li \c TapHandler.DragThreshold + \image pointerHandlers/tapHandlerOverlappingButtons.webp + Grab on press: \e passive + \li (the default value) The \l eventPoint must not move significantly. + If the mouse, finger or stylus moves past the system-wide drag + threshold (QStyleHints::startDragDistance), the tap gesture is + canceled, even if the device or finger is still pressed. This policy + can be useful whenever TapHandler needs to cooperate with other + input handlers (for example \l DragHandler) or event-handling Items + (for example \l {Qt Quick Controls}), because in this case TapHandler + will not take the exclusive grab, but merely a + \l {QPointerEvent::addPassiveGrabber()}{passive grab}. + That is, \c DragThreshold is especially useful to \e augment + existing behavior: it reacts to tap/click/long-press even when + another item or handler is already reacting, perhaps even in a + different layer of the UI. The following snippet shows one + TapHandler as used in one component; but if we stack up two + instances of the component, you will see the handlers in both of them + react simultaneously when a press occurs over both of them, because + the passive grab does not stop event propagation: + \quotefromfile pointerHandlers/tapHandlerOverlappingButtons.qml + \skipto Item + \printuntil component Button + \skipto TapHandler + \printuntil } + \skipuntil Text { + \skipuntil } + \printuntil Button + \printuntil Button + \printuntil } + + \row + \li \c TapHandler.WithinBounds + \image pointerHandlers/tapHandlerButtonWithinBounds.webp + Grab on press: \e exclusive + \li If the \l eventPoint leaves the bounds of the \c parent Item, the tap + gesture is canceled. The TapHandler will take the + \l {QPointerEvent::setExclusiveGrabber}{exclusive grab} on + press, but will release the grab as soon as the boundary constraint + is no longer satisfied. + \snippet pointerHandlers/tapHandlerButtonWithinBounds.qml 1 + + \row + \li \c TapHandler.ReleaseWithinBounds + \image pointerHandlers/tapHandlerButtonReleaseWithinBounds.webp + Grab on press: \e exclusive + \li At the time of release (the mouse button is released or the finger + is lifted), if the \l eventPoint is outside the bounds of the + \c parent Item, a tap gesture is not recognized. This corresponds to + typical behavior for button widgets: you can cancel a click by + dragging outside the button, and you can also change your mind by + dragging back inside the button before release. Note that it's + necessary for TapHandler to take the + \l {QPointerEvent::setExclusiveGrabber}{exclusive grab} on press + and retain it until release in order to detect this gesture. + \snippet pointerHandlers/tapHandlerButtonReleaseWithinBounds.qml 1 + \endtable + + The \l {Pointer Handlers Example} demonstrates some use cases for these. + + \note If you find that TapHandler is reacting in cases that conflict with + some other behavior, the first thing you should try is to think about which + \c gesturePolicy is appropriate. If you cannot fix it by changing \c gesturePolicy, + some cases are better served by adjusting \l {PointerHandler::}{grabPermissions}, + either in this handler, or in another handler that should \e prevent TapHandler + from reacting. */ void QQuickTapHandler::setGesturePolicy(QQuickTapHandler::GesturePolicy gesturePolicy) { @@ -266,7 +317,7 @@ void QQuickTapHandler::setGesturePolicy(QQuickTapHandler::GesturePolicy gestureP Holds true whenever the mouse or touch point is pressed, and any movement since the press is compliant with the current - \l gesturePolicy. When the event point is released or the policy is + \l gesturePolicy. When the \l eventPoint is released or the policy is violated, \e pressed will change to false. */ void QQuickTapHandler::setPressed(bool press, bool cancel, QPointerEvent *event, QEventPoint &point) @@ -303,12 +354,13 @@ void QQuickTapHandler::setPressed(bool press, bool cancel, QPointerEvent *event, else m_tapCount = 1; qCDebug(lcTapHandler) << objectName() << "tapped" << m_tapCount << "times"; - emit tapped(point); + auto button = event->isSinglePointEvent() ? static_cast<QSinglePointEvent *>(event)->button() : Qt::NoButton; + emit tapped(point, button); emit tapCountChanged(); if (m_tapCount == 1) - emit singleTapped(point); + emit singleTapped(point, button); else if (m_tapCount == 2) - emit doubleTapped(point); + emit doubleTapped(point, button); m_lastTapTimestamp = ts; m_lastTapPos = point.scenePosition(); } else { @@ -392,7 +444,7 @@ void QQuickTapHandler::updateTimeHeld() */ /*! - \qmlsignal QtQuick::TapHandler::tapped(EventPoint eventPoint) + \qmlsignal QtQuick::TapHandler::tapped(EventPoint eventPoint, Qt::MouseButton button) This signal is emitted each time the \c parent Item is tapped. @@ -400,24 +452,28 @@ void QQuickTapHandler::updateTimeHeld() period less than \l longPressThreshold, while any movement does not exceed the drag threshold, then the \c tapped signal will be emitted at the time of release. The \a eventPoint signal parameter contains information - from the release event about the point that was tapped: + from the release event about the point that was tapped, and \a button + is the \l {Qt::MouseButton}{mouse button} that was clicked, or \c NoButton + on a touchscreen. \snippet pointerHandlers/tapHandlerOnTapped.qml 0 */ /*! - \qmlsignal QtQuick::TapHandler::singleTapped(EventPoint eventPoint) + \qmlsignal QtQuick::TapHandler::singleTapped(EventPoint eventPoint, Qt::MouseButton button) \since 5.11 This signal is emitted when the \c parent Item is tapped once. After an amount of time greater than QStyleHints::mouseDoubleClickInterval, it can be tapped again; but if the time until the next tap is less, \l tapCount will increase. The \a eventPoint signal parameter contains - information from the release event about the point that was tapped. + information from the release event about the point that was tapped, and + \a button is the \l {Qt::MouseButton}{mouse button} that was clicked, or + \c NoButton on a touchscreen. */ /*! - \qmlsignal QtQuick::TapHandler::doubleTapped(EventPoint eventPoint) + \qmlsignal QtQuick::TapHandler::doubleTapped(EventPoint eventPoint, Qt::MouseButton button) \since 5.11 This signal is emitted when the \c parent Item is tapped twice within a @@ -426,7 +482,9 @@ void QQuickTapHandler::updateTimeHeld() QStyleHints::touchDoubleTapDistance()). This signal always occurs after \l singleTapped, \l tapped, and \l tapCountChanged. The \a eventPoint signal parameter contains information from the release event about the - point that was tapped. + point that was tapped, and \a button is the + \l {Qt::MouseButton}{mouse button} that was clicked, or \c NoButton + on a touchscreen. */ /*! @@ -447,3 +505,5 @@ void QQuickTapHandler::updateTimeHeld() from the previous \c tapCount. */ QT_END_NAMESPACE + +#include "moc_qquicktaphandler_p.cpp" diff --git a/src/quick/handlers/qquicktaphandler_p.h b/src/quick/handlers/qquicktaphandler_p.h index d75547eee26..2e0c8e211f4 100644 --- a/src/quick/handlers/qquicktaphandler_p.h +++ b/src/quick/handlers/qquicktaphandler_p.h @@ -97,9 +97,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTapHandler : public QQuickSinglePointHandler void timeHeldChanged(); void longPressThresholdChanged(); void gesturePolicyChanged(); - void tapped(QEventPoint eventPoint); - void singleTapped(QEventPoint eventPoint); - void doubleTapped(QEventPoint eventPoint); + // the second argument (Qt::MouseButton) was added in 6.2: avoid name clashes with IDs by not naming it for now + void tapped(QEventPoint eventPoint, Qt::MouseButton /* button */); + void singleTapped(QEventPoint eventPoint, Qt::MouseButton /* button */); + void doubleTapped(QEventPoint eventPoint, Qt::MouseButton /* button */); void longPressed(); protected: diff --git a/src/quick/handlers/qquickwheelhandler.cpp b/src/quick/handlers/qquickwheelhandler.cpp index 7045f10d8e7..f1e40ba35c8 100644 --- a/src/quick/handlers/qquickwheelhandler.cpp +++ b/src/quick/handlers/qquickwheelhandler.cpp @@ -81,7 +81,7 @@ Q_LOGGING_CATEGORY(lcWheelHandler, "qt.quick.handler.wheel") WheelHandler handles only a rotating mouse wheel by default; this can be changed by setting acceptedDevices. - \sa MouseArea, Flickable + \sa MouseArea, Flickable, {Pointer Handlers Example} */ QQuickWheelHandler::QQuickWheelHandler(QQuickItem *parent) @@ -91,7 +91,7 @@ QQuickWheelHandler::QQuickWheelHandler(QQuickItem *parent) } /*! - \qmlproperty enum QtQuick::WheelHandler::orientation + \qmlproperty enumeration QtQuick::WheelHandler::orientation Which wheel to react to. The default is \c Qt.Vertical. @@ -502,7 +502,7 @@ void QQuickWheelHandler::timerEvent(QTimerEvent *event) } /*! - \qmlsignal QtQuick::WheelHandler::wheel(PointerScrollEvent event) + \qmlsignal QtQuick::WheelHandler::wheel(WheelEvent event) This signal is emitted every time this handler receives an \a event of type \l QWheelEvent: that is, every time the wheel is moved or the @@ -548,3 +548,5 @@ QMetaProperty &QQuickWheelHandlerPrivate::targetMetaProperty() const */ QT_END_NAMESPACE + +#include "moc_qquickwheelhandler_p.cpp" diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index e13c0f6dae0..4b85e1b1010 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -288,7 +288,7 @@ QQuickCanvasItemPrivate::~QQuickCanvasItemPrivate() QPainter instead of the more expensive and likely less performing JavaScript and Context2D approach. - \sa Context2D QQuickPaintedItem + \sa Context2D, QQuickPaintedItem, {Pointer Handlers Example} */ QQuickCanvasItem::QQuickCanvasItem(QQuickItem *parent) @@ -480,9 +480,8 @@ void QQuickCanvasItem::setCanvasWindow(const QRectF& rect) \qmlproperty enumeration QtQuick::Canvas::renderTarget Holds the current canvas render target. - \list - \li Canvas.Image - render to an in memory image buffer. - \endlist + \value Canvas.Image Render to an in-memory image buffer. + \value Canvas.FramebufferObject As of Qt 6.0, this value is ignored. This hint is supplied along with renderStrategy to the graphics context to determine the method of rendering. A renderStrategy, renderTarget or a @@ -516,11 +515,9 @@ void QQuickCanvasItem::setRenderTarget(QQuickCanvasItem::RenderTarget target) \qmlproperty enumeration QtQuick::Canvas::renderStrategy Holds the current canvas rendering strategy. - \list - \li Canvas.Immediate - context will perform graphics commands immediately in the main UI thread. - \li Canvas.Threaded - context will defer graphics commands to a private rendering thread. - \li Canvas.Cooperative - context will defer graphics commands to the applications global render thread. - \endlist + \value Canvas.Immediate context will perform graphics commands immediately in the main UI thread. + \value Canvas.Threaded context will defer graphics commands to a private rendering thread. + \value Canvas.Cooperative context will defer graphics commands to the applications global render thread. This hint is supplied along with renderTarget to the graphics context to determine the method of rendering. A renderStrategy, renderTarget or a @@ -652,6 +649,10 @@ void QQuickCanvasItem::invalidateSceneGraph() d->textureProvider = nullptr; delete d->nodeTexture; d->nodeTexture = nullptr; + + // As we can expect(/hope) that the SG will be "good again", we can requestPaint ( which does 'markDirty(canvasWindow);' ) + // Otherwise this Canvas will be "blank" when SG comes back + requestPaint(); } void QQuickCanvasItem::schedulePolish() diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 64b8b80f8b5..ea1a2372db9 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -1325,29 +1325,81 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(const QV4::Function /*! \qmlproperty string QtQuick::Context2D::globalCompositeOperation - Holds the current the current composition operation, from the list below: - \list - \li source-atop - A atop B. Display the source image wherever both images are opaque. - Display the destination image wherever the destination image is opaque but the source image is transparent. - Display transparency elsewhere. - \li source-in - A in B. Display the source image wherever both the source image and destination image are opaque. - Display transparency elsewhere. - \li source-out - A out B. Display the source image wherever the source image is opaque and the destination image is transparent. - Display transparency elsewhere. - \li source-over - (default) A over B. Display the source image wherever the source image is opaque. - Display the destination image elsewhere. - \li destination-atop - B atop A. Same as source-atop but using the destination image instead of the source image and vice versa. - \li destination-in - B in A. Same as source-in but using the destination image instead of the source image and vice versa. - \li destination-out - B out A. Same as source-out but using the destination image instead of the source image and vice versa. - \li destination-over - B over A. Same as source-over but using the destination image instead of the source image and vice versa. - \li lighter - A plus B. Display the sum of the source image and destination image, with color values approaching 255 (100%) as a limit. - \li copy - A (B is ignored). Display the source image instead of the destination image. - \li xor - A xor B. Exclusive OR of the source image and destination image. - \endlist - - Additionally, this property also accepts the compositon modes listed in QPainter::CompositionMode. According to the W3C standard, these - extension composition modes are provided as "vendorName-operationName" syntax, for example: QPainter::CompositionMode_Exclusion is provided as - "qt-exclusion". + Holds the current the current composition operation. Allowed operations are: + + \value "source-atop" + QPainter::CompositionMode_SourceAtop + A atop B. Display the source image wherever both images are opaque. + Display the destination image wherever the destination image is opaque + but the source image is transparent. Display transparency elsewhere. + \value "source-in" + QPainter::CompositionMode_SourceIn + A in B. Display the source image wherever both the source image and + destination image are opaque. Display transparency elsewhere. + \value "source-out" + QPainter::CompositionMode_SourceOut + A out B. Display the source image wherever the source image is opaque + and the destination image is transparent. Display transparency elsewhere. + \value "source-over" + QPainter::CompositionMode_SourceOver (default) + A over B. Display the source image wherever the source image is opaque. + Display the destination image elsewhere. + \value "destination-atop" + QPainter::CompositionMode_DestinationAtop + B atop A. Same as \c source-atop but using the destination image instead + of the source image and vice versa. + \value "destination-in" + QPainter::CompositionMode_DestinationIn + B in A. Same as \c source-in but using the destination image instead of + the source image and vice versa. + \value "destination-out" + QPainter::CompositionMode_DestinationOut + B out A. Same as \c source-out but using the destination image instead + of the source image and vice versa. + \value "destination-over" + QPainter::CompositionMode_DestinationOver + B over A. Same as \c source-over but using the destination image + instead of the source image and vice versa. + \value "lighter" + QPainter::CompositionMode_Plus + A plus B. Display the sum of the source image and destination image, + with color values approaching \c 255 (100%) as a limit. + \value "copy" + QPainter::CompositionMode_Source + A (B is ignored). Display the source image instead of the destination image. + \value "xor" + QPainter::CompositionMode_Xor + A xor B. Exclusive OR of the source image and destination image. + \value "qt-clear" + QPainter::CompositionMode_Clear + \value "qt-destination" + QPainter::CompositionMode_Destination + \value "qt-multiply" + QPainter::CompositionMode_Multiply + \value "qt-screen" + QPainter::CompositionMode_Screen + \value "qt-overlay" + QPainter::CompositionMode_Overlay + \value "qt-darken" + QPainter::CompositionMode_Darken + \value "qt-lighten" + QPainter::CompositionMode_Lighten + \value "qt-color-dodge" + QPainter::CompositionMode_ColorDodge + \value "qt-color-burn" + QPainter::CompositionMode_ColorBurn + \value "qt-hard-light" + QPainter::CompositionMode_HardLight + \value "qt-soft-light" + QPainter::CompositionMode_SoftLight + \value "qt-difference" + QPainter::CompositionMode_Difference + \value "qt-exclusion" + QPainter::CompositionMode_Exclusion + + In compliance with the W3C standard, the extended composition modes beyond + the required modes are provided as "vendorName-operationName" syntax, for + example: QPainter::CompositionMode_Exclusion is provided as "qt-exclusion". */ QV4::ReturnedValue QQuickJSContext2D::method_get_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { @@ -1458,18 +1510,19 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(const QV4::FunctionOb } RETURN_UNDEFINED(); } + /*! \qmlproperty enumeration QtQuick::Context2D::fillRule - Holds the current fill rule used for filling shapes. The following fill rules are supported: - \list - \li Qt.OddEvenFill - \li Qt.WindingFill - \endlist - Note: Unlike the QPainterPath, the Canvas API uses the winding fill as the default fill rule. - The fillRule property is part of the context rendering state. + Holds the current fill rule used for filling shapes. The following fill rules are supported: - \sa fillStyle - */ + \value Qt.OddEvenFill Qt::OddEvenFill + \value Qt.WindingFill (default) Qt::WindingFill + + \note Unlike QPainterPath, the Canvas API uses the winding fill as the default fill rule. + The fillRule property is part of the context rendering state. + + \sa fillStyle +*/ QV4::ReturnedValue QQuickJSContext2D::method_get_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); @@ -1723,48 +1776,49 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(cons } /*! - \qmlmethod variant QtQuick::Context2D::createPattern(color color, enumeration patternMode) - This is a overload function. - Returns a CanvasPattern object that uses the given \a color and \a patternMode. - The valid pattern modes are: - \list - \li Qt.SolidPattern - \li Qt.Dense1Pattern - \li Qt.Dense2Pattern - \li Qt.Dense3Pattern - \li Qt.Dense4Pattern - \li Qt.Dense5Pattern - \li Qt.Dense6Pattern - \li Qt.Dense7Pattern - \li Qt.HorPattern - \li Qt.VerPattern - \li Qt.CrossPattern - \li Qt.BDiagPattern - \li Qt.FDiagPattern - \li Qt.DiagCrossPattern -\endlist + \qmlmethod variant QtQuick::Context2D::createPattern(color color, enumeration patternMode) + This is an overloaded function. + Returns a CanvasPattern object that uses the given \a color and \a patternMode. + The valid pattern modes are: + + \value Qt.SolidPattern Qt::SolidPattern + \value Qt.Dense1Pattern Qt::Dense1Pattern + \value Qt.Dense2Pattern Qt::Dense2Pattern + \value Qt.Dense3Pattern Qt::Dense3Pattern + \value Qt.Dense4Pattern Qt::Dense4Pattern + \value Qt.Dense5Pattern Qt::Dense5Pattern + \value Qt.Dense6Pattern Qt::Dense6Pattern + \value Qt.Dense7Pattern Qt::Dense7Pattern + \value Qt.HorPattern Qt::HorPattern + \value Qt.VerPattern Qt::VerPattern + \value Qt.CrossPattern Qt::CrossPattern + \value Qt.BDiagPattern Qt::BDiagPattern + \value Qt.FDiagPattern Qt::FDiagPattern + \value Qt.DiagCrossPattern Qt::DiagCrossPattern + \sa Qt::BrushStyle - */ +*/ /*! - \qmlmethod variant QtQuick::Context2D::createPattern(Image image, string repetition) - Returns a CanvasPattern object that uses the given image and repeats in the direction(s) given by the repetition argument. + \qmlmethod variant QtQuick::Context2D::createPattern(Image image, string repetition) + Returns a CanvasPattern object that uses the given image and repeats in the + direction(s) given by the repetition argument. - The \a image parameter must be a valid Image item, a valid CanvasImageData object or loaded image url, if there is no image data, throws an INVALID_STATE_ERR exception. + The \a image parameter must be a valid Image item, a valid CanvasImageData + object or loaded image url. If there is no image data, thus function throws an + INVALID_STATE_ERR exception. - The allowed values for \a repetition are: + The allowed values for \a repetition are: - \list - \li "repeat" - both directions - \li "repeat-x - horizontal only - \li "repeat-y" - vertical only - \li "no-repeat" - neither - \endlist + \value "repeat" both directions + \value "repeat-x horizontal only + \value "repeat-y" vertical only + \value "no-repeat" neither - If the repetition argument is empty or null, the value "repeat" is used. + If the repetition argument is empty or null, the value "repeat" is used. - \sa strokeStyle - \sa fillStyle - */ + \sa strokeStyle + \sa fillStyle +*/ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { QV4::Scope scope(b); @@ -1827,13 +1881,20 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(const QV4::F // line styles /*! \qmlproperty string QtQuick::Context2D::lineCap - Holds the current line cap style. - The possible line cap styles are: - \list - \li butt - the end of each line has a flat edge perpendicular to the direction of the line, this is the default line cap value. - \li round - a semi-circle with the diameter equal to the width of the line must then be added on to the end of the line. - \li square - a rectangle with the length of the line width and the width of half the line width, placed flat against the edge perpendicular to the direction of the line. - \endlist + Holds the current line cap style. + The possible line cap styles are: + + \value "butt" + (default) Qt::FlatCap the end of each line has a flat edge + perpendicular to the direction of the line. + \value "round" + Qt::RoundCap a semi-circle with the diameter equal to the width of the + line is added on to the end of the line. + \value "square" + Qt::SquareCap a rectangle with the length of the line width and the + width of half the line width, placed flat against the edge + perpendicular to the direction of the line. + Other values are ignored. */ QV4::ReturnedValue QQuickJSContext2D::method_get_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) @@ -1883,16 +1944,18 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(const QV4::FunctionObje /*! \qmlproperty string QtQuick::Context2D::lineJoin - Holds the current line join style. A join exists at any point in a subpath - shared by two consecutive lines. When a subpath is closed, then a join also exists - at its first point (equivalent to its last point) connecting the first and last lines in the subpath. + Holds the current line join style. A join exists at any point in a subpath + shared by two consecutive lines. When a subpath is closed, then a join also + exists at its first point (equivalent to its last point) connecting the + first and last lines in the subpath. The possible line join styles are: - \list - \li bevel - this is all that is rendered at joins. - \li round - a filled arc connecting the two aforementioned corners of the join, abutting (and not overlapping) the aforementioned triangle, with the diameter equal to the line width and the origin at the point of the join, must be rendered at joins. - \li miter - a second filled triangle must (if it can given the miter length) be rendered at the join, this is the default line join style. - \endlist + + \value "bevel" Qt::BevelJoin The triangular notch between the two lines is filled. + \value "round" Qt::RoundJoin A circular arc between the two lines is filled. + \value "miter" (default) Qt::MiterJoin The outer edges of the lines are extended to + meet at an angle, and this area is filled. + Other values are ignored. */ QV4::ReturnedValue QQuickJSContext2D::method_get_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) @@ -2341,8 +2404,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(const QV4::Func \image qml-item-canvas-startAngle.png - The \a anticlockwise parameter is \c true for each arc in the figure above - because they are all drawn in the anticlockwise direction. + The \a anticlockwise parameter is \c false for each arc in the figure above + because they are all drawn in the clockwise direction. \sa arcTo, {http://www.w3.org/TR/2dcontext/#dom-context-2d-arc}{W3C's 2D Context Standard for arc()} @@ -2459,7 +2522,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_beginPath(const QV4::Funct \image qml-item-canvas-bezierCurveTo.png \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-beziercurveto}{W3C 2d context standard for bezierCurveTo} - \sa {http://www.openrise.com/lab/FlowerPower/}{The beautiful flower demo by using bezierCurveTo} + \sa {https://web.archive.org/web/20130505222636if_/http://www.openrise.com/lab/FlowerPower/}{The beautiful flower demo by using bezierCurveTo} */ QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { @@ -2825,19 +2888,20 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_font(const QV4::FunctionObject } /*! - \qmlproperty string QtQuick::Context2D::textAlign - - Holds the current text alignment settings. - The possible values are: - \list - \li start - \li end - \li left - \li right - \li center - \endlist - Other values are ignored. The default value is "start". - */ + \qmlproperty string QtQuick::Context2D::textAlign + + Holds the current text alignment settings. The possible values are: + + \value "start" (default) Align to the start edge of the text (left side in + left-to-right text, right side in right-to-left text). + \value "end" Align to the end edge of the text (right side in left-to-right + text, left side in right-to-left text). + \value "left" Qt::AlignLeft + \value "right" Qt::AlignRight + \value "center" Qt::AlignHCenter + + Other values are ignored. +*/ QV4::ReturnedValue QQuickJSContext2D::method_get_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); @@ -2892,20 +2956,19 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(const QV4::FunctionOb } /*! - \qmlproperty string QtQuick::Context2D::textBaseline - - Holds the current baseline alignment settings. - The possible values are: - \list - \li top - \li hanging - \li middle - \li alphabetic - \li ideographic - \li bottom - \endlist - Other values are ignored. The default value is "alphabetic". - */ + \qmlproperty string QtQuick::Context2D::textBaseline + + Holds the current baseline alignment settings. The possible values are: + + \value "top" The top of the em square + \value "hanging" The hanging baseline + \value "middle" The middle of the em square + \value "alphabetic" (default) The alphabetic baseline + \value "ideographic" The ideographic-under baseline + \value "bottom" The bottom of the em square + + Other values are ignored. The default value is "alphabetic". +*/ QV4::ReturnedValue QQuickJSContext2D::method_get_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) { QV4::Scope scope(b); @@ -3884,16 +3947,16 @@ void QQuickContext2D::bezierCurveTo(qreal cp1x, qreal cp1y, m_path.cubicTo(QPointF(cp1x, cp1y), QPointF(cp2x, cp2y), pt); } -void QQuickContext2D::addArcTo(const QPointF& p1, const QPointF& p2, float radius) +void QQuickContext2D::addArcTo(const QPointF& p1, const QPointF& p2, qreal radius) { QPointF p0(m_path.currentPosition()); QPointF p1p0((p0.x() - p1.x()), (p0.y() - p1.y())); QPointF p1p2((p2.x() - p1.x()), (p2.y() - p1.y())); - float p1p0_length = std::sqrt(p1p0.x() * p1p0.x() + p1p0.y() * p1p0.y()); - float p1p2_length = std::sqrt(p1p2.x() * p1p2.x() + p1p2.y() * p1p2.y()); + qreal p1p0_length = std::hypot(p1p0.x(), p1p0.y()); + qreal p1p2_length = std::hypot(p1p2.x(), p1p2.y()); - double cos_phi = (p1p0.x() * p1p2.x() + p1p0.y() * p1p2.y()) / (p1p0_length * p1p2_length); + qreal cos_phi = QPointF::dotProduct(p1p0, p1p2) / (p1p0_length * p1p2_length); // The points p0, p1, and p2 are on the same straight line (HTML5, 4.8.11.1.8) // We could have used areCollinear() here, but since we're reusing @@ -3903,16 +3966,16 @@ void QQuickContext2D::addArcTo(const QPointF& p1, const QPointF& p2, float radiu return; } - float tangent = radius / std::tan(std::acos(cos_phi) / 2); - float factor_p1p0 = tangent / p1p0_length; + qreal tangent = radius / std::tan(std::acos(cos_phi) / 2); + qreal factor_p1p0 = tangent / p1p0_length; QPointF t_p1p0((p1.x() + factor_p1p0 * p1p0.x()), (p1.y() + factor_p1p0 * p1p0.y())); QPointF orth_p1p0(p1p0.y(), -p1p0.x()); - float orth_p1p0_length = std::sqrt(orth_p1p0.x() * orth_p1p0.x() + orth_p1p0.y() * orth_p1p0.y()); - float factor_ra = radius / orth_p1p0_length; + qreal orth_p1p0_length = std::hypot(orth_p1p0.x(), orth_p1p0.y()); + qreal factor_ra = radius / orth_p1p0_length; // angle between orth_p1p0 and p1p2 to get the right vector orthographic to p1p0 - double cos_alpha = (orth_p1p0.x() * p1p2.x() + orth_p1p0.y() * p1p2.y()) / (orth_p1p0_length * p1p2_length); + qreal cos_alpha = QPointF::dotProduct(orth_p1p0, p1p2) / (orth_p1p0_length * p1p2_length); if (cos_alpha < 0.f) orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y()); @@ -3920,20 +3983,15 @@ void QQuickContext2D::addArcTo(const QPointF& p1, const QPointF& p2, float radiu // calculate angles for addArc orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y()); - float sa = std::acos(orth_p1p0.x() / orth_p1p0_length); - if (orth_p1p0.y() < 0.f) - sa = 2 * M_PI - sa; + qreal sa = std::atan2(orth_p1p0.y(), orth_p1p0.x()); // anticlockwise logic bool anticlockwise = false; - float factor_p1p2 = tangent / p1p2_length; + qreal factor_p1p2 = tangent / p1p2_length; QPointF t_p1p2((p1.x() + factor_p1p2 * p1p2.x()), (p1.y() + factor_p1p2 * p1p2.y())); QPointF orth_p1p2((t_p1p2.x() - p.x()), (t_p1p2.y() - p.y())); - float orth_p1p2_length = std::sqrt(orth_p1p2.x() * orth_p1p2.x() + orth_p1p2.y() * orth_p1p2.y()); - float ea = std::acos(orth_p1p2.x() / orth_p1p2_length); - if (orth_p1p2.y() < 0) - ea = 2 * M_PI - ea; + qreal ea = std::atan2(orth_p1p2.y(), orth_p1p2.x()); if ((sa > ea) && ((sa - ea) < M_PI)) anticlockwise = true; if ((sa < ea) && ((ea - sa) > M_PI)) diff --git a/src/quick/items/context2d/qquickcontext2d_p.h b/src/quick/items/context2d/qquickcontext2d_p.h index 92ec1e6470e..ea1354725f3 100644 --- a/src/quick/items/context2d/qquickcontext2d_p.h +++ b/src/quick/items/context2d/qquickcontext2d_p.h @@ -240,7 +240,7 @@ class QQuickContext2D : public QQuickCanvasContext void arc(qreal x, qreal y, qreal radius, qreal startAngle, qreal endAngle, bool anticlockwise); - void addArcTo(const QPointF& p1, const QPointF& p2, float radius); + void addArcTo(const QPointF& p1, const QPointF& p2, qreal radius); bool isPointInPath(qreal x, qreal y) const; diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp index e3f8acad009..18bfc66eee9 100644 --- a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp +++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp @@ -371,7 +371,10 @@ void QQuickContext2DCommandBuffer::replay(QPainter* p, QQuickContext2D::State& s } state.lineDash = pattern; QPen nPen = p->pen(); - nPen.setDashPattern(pattern); + if (count > 0) + nPen.setDashPattern(pattern); + else + nPen.setStyle(Qt::SolidLine); p->setPen(nPen); break; } diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index e111f908d0b..71a5e414f6f 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -120,8 +120,15 @@ void QQuickContext2DTexture::setItem(QQuickCanvasItem* item) bool QQuickContext2DTexture::setCanvasWindow(const QRect& r) { - qreal canvasDevicePixelRatio = (m_item && m_item->window()) ? - m_item->window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio(); + bool ok = false; + static qreal overriddenDevicePixelRatio = + !qEnvironmentVariableIsEmpty("QT_CANVAS_OVERRIDE_DEVICEPIXELRATIO") ? + qgetenv("QT_CANVAS_OVERRIDE_DEVICEPIXELRATIO").toFloat(&ok) : 0.0; + qreal canvasDevicePixelRatio = overriddenDevicePixelRatio; + if (overriddenDevicePixelRatio == 0.0) { + canvasDevicePixelRatio = (m_item && m_item->window()) ? + m_item->window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio(); + } if (!qFuzzyCompare(m_canvasDevicePixelRatio, canvasDevicePixelRatio)) { qCDebug(lcCanvas, "%s device pixel ratio %.1lf -> %.1lf", (m_item->objectName().isEmpty() ? "Canvas" : qPrintable(m_item->objectName())), diff --git a/src/quick/items/qquickaccessibleattached.cpp b/src/quick/items/qquickaccessibleattached.cpp index 0b593c0089e..f63ab764f15 100644 --- a/src/quick/items/qquickaccessibleattached.cpp +++ b/src/quick/items/qquickaccessibleattached.cpp @@ -109,7 +109,7 @@ QT_BEGIN_NAMESPACE This property sets an accessible description. Similar to the name it describes the item. The description can be a little more verbose and tell what the item does, - for example the functionallity of the button it describes. + for example the functionality of the button it describes. */ /*! @@ -406,9 +406,10 @@ void QQuickAccessibleAttached::setRole(QAccessible::Role role) m_state.focusable = true; break; case QAccessible::StaticText: - if (!m_stateExplicitlySet.readOnly) { + if (!m_stateExplicitlySet.readOnly) m_state.readOnly = true; - } + if (!m_stateExplicitlySet.focusable) + m_state.focusable = true; break; default: break; diff --git a/src/quick/items/qquickaccessibleattached_p.h b/src/quick/items/qquickaccessibleattached_p.h index 6d7d46bfd40..13f4b1f52fe 100644 --- a/src/quick/items/qquickaccessibleattached_p.h +++ b/src/quick/items/qquickaccessibleattached_p.h @@ -189,7 +189,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAccessibleAttached : public QObject bool doAction(const QString &actionName); void availableActions(QStringList *actions) const; - Q_INVOKABLE static QString stripHtml(const QString &html); + Q_REVISION(6, 2) Q_INVOKABLE static QString stripHtml(const QString &html); public Q_SLOTS: void valueChanged() { diff --git a/src/quick/items/qquickanchors.cpp b/src/quick/items/qquickanchors.cpp index 8ee42290132..a2657c19f49 100644 --- a/src/quick/items/qquickanchors.cpp +++ b/src/quick/items/qquickanchors.cpp @@ -1409,5 +1409,7 @@ bool QQuickAnchorsPrivate::checkVAnchorValid(QQuickAnchorLine anchor) const QT_END_NAMESPACE +#include "moc_qquickanchors_p_p.cpp" + #include <moc_qquickanchors_p.cpp> diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h index 6f7a7e45d55..98600620790 100644 --- a/src/quick/items/qquickanimatedimage_p.h +++ b/src/quick/items/qquickanimatedimage_p.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE class QMovie; class QQuickAnimatedImagePrivate; -class Q_AUTOTEST_EXPORT QQuickAnimatedImage : public QQuickImage +class Q_QUICK_PRIVATE_EXPORT QQuickAnimatedImage : public QQuickImage { Q_OBJECT diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp index 5b3d9db0911..a3f2494fbac 100644 --- a/src/quick/items/qquickanimatedsprite.cpp +++ b/src/quick/items/qquickanimatedsprite.cpp @@ -894,7 +894,7 @@ void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node) maybeUpdate(); } - qreal frameCount = d->m_spriteEngine->spriteFrames(); + int frameCount = d->m_spriteEngine->spriteFrames(); bool reverse = d->m_spriteEngine->sprite()->reverse(); if (reverse) frameAt = (frameCount - 1) - frameAt; @@ -931,15 +931,15 @@ void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node) x2 = x1 - w; y2 = y1; } else { - x2 = 1.0 - w; + x2 = d->m_sheetSize.width() - w; y2 = y1 - h; - if (y2 < 0.0) { + if (y2 < 0) { //the last row may not fill the entire width int maxRowFrames = d->m_sheetSize.width() / d->m_spriteEngine->spriteWidth(); if (d->m_spriteEngine->maxFrames() % maxRowFrames) x2 = ((d->m_spriteEngine->maxFrames() % maxRowFrames) - 1) * w; - y2 = 1.0 - h; + y2 = d->m_sheetSize.height() - h; } } } else { @@ -947,10 +947,10 @@ void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node) x2 = x1 + w; y2 = y1; } else { - x2 = 0.0; + x2 = 0; y2 = y1 + h; - if (y2 >= 1.0) - y2 = 0.0; + if (y2 >= d->m_sheetSize.height()) + y2 = 0; } } diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h index e231d2a10d1..66a005da7dc 100644 --- a/src/quick/items/qquickanimatedsprite_p.h +++ b/src/quick/items/qquickanimatedsprite_p.h @@ -68,7 +68,7 @@ class QSGGeometryNode; class QQuickAnimatedSpriteMaterial; class QQuickAnimatedSpritePrivate; class QSGSpriteNode; -class Q_AUTOTEST_EXPORT QQuickAnimatedSprite : public QQuickItem +class Q_QUICK_PRIVATE_EXPORT QQuickAnimatedSprite : public QQuickItem { Q_OBJECT Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged) diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp index 9a1c3cc1c1e..3ae28deaf6c 100644 --- a/src/quick/items/qquickborderimage.cpp +++ b/src/quick/items/qquickborderimage.cpp @@ -99,9 +99,8 @@ QT_BEGIN_NAMESPACE \image qml-borderimage-normal-image.png \endfloat - An unscaled image is displayed using an Image. The \l border property is - used to determine the parts of the image that will lie inside the unscaled corner - areas and the parts that will be stretched horizontally and vertically. + For comparison, an unscaled image is displayed using a simple Image item. + Here we have overlaid lines to show how we'd like to break it up with BorderImage: \snippet qml/borderimage/normal-image.qml normal image @@ -110,12 +109,15 @@ QT_BEGIN_NAMESPACE \image qml-borderimage-scaled.png \endfloat - A BorderImage is used to display the image, and it is given a size that is + But when a BorderImage is used to display the image, the \l border property is + used to determine the parts of the image that will lie inside the unscaled corner + areas, and the parts that will be stretched horizontally and vertically. + Then, you can give it a size that is larger than the original image. Since the \l horizontalTileMode property is set to \l{BorderImage::horizontalTileMode}{BorderImage.Stretch}, the parts of image in regions 2 and 8 are stretched horizontally. Since the \l verticalTileMode property is set to \l{BorderImage::verticalTileMode}{BorderImage.Stretch}, the parts of image - in regions 4 and 6 are stretched vertically. + in regions 4 and 6 are stretched vertically: \snippet qml/borderimage/borderimage-scaled.qml scaled border image @@ -128,17 +130,25 @@ QT_BEGIN_NAMESPACE \l horizontalTileMode property set to \l{BorderImage::horizontalTileMode}{BorderImage.Repeat}, the parts of image in regions 2 and 8 are tiled so that they fill the space at the top and bottom of the item. Similarly, the \l verticalTileMode property is set to - \l{BorderImage::verticalTileMode}{BorderImage.Repeat}, the parts of image in regions - 4 and 6 are tiled so that they fill the space at the left and right of the item. + \l{BorderImage::verticalTileMode}{BorderImage.Repeat}, so the parts of image in regions + 4 and 6 are tiled to fill the space at the left and right of the item: \snippet qml/borderimage/borderimage-tiled.qml tiled border image \clearfloat + \beginfloatleft + \image qml-borderimage-rounded.png + \endfloat + In some situations, the width of regions 2 and 8 may not be an exact multiple of the width of the corresponding regions in the source image. Similarly, the height of regions 4 and 6 - may not be an exact multiple of the height of the corresponding regions. It can be useful - to use \l{BorderImage::horizontalTileMode}{BorderImage.Round} instead of - \l{BorderImage::horizontalTileMode}{BorderImage.Repeat} in cases like these. + may not be an exact multiple of the height of the corresponding regions. If you use + \l{BorderImage::horizontalTileMode}{BorderImage.Round} mode, it will choose an integer + number of tiles and shrink them to fit: + + \snippet qml/borderimage/borderimage-rounded.qml tiled border image + + \clearfloat The Border Image example in \l{Qt Quick Examples - Image Elements} shows how a BorderImage can be used to simulate a shadow effect on a rectangular item. @@ -185,12 +195,10 @@ QQuickBorderImage::~QQuickBorderImage() This property describes the status of image loading. It can be one of: - \list - \li BorderImage.Null - no image has been set - \li BorderImage.Ready - the image has been loaded - \li BorderImage.Loading - the image is currently being loaded - \li BorderImage.Error - an error occurred while loading the image - \endlist + \value BorderImage.Null No image has been set + \value BorderImage.Ready The image has been loaded + \value BorderImage.Loading The image is currently being loaded + \value BorderImage.Error An error occurred while loading the image \sa progress */ @@ -368,11 +376,9 @@ QQuickScaleGrid *QQuickBorderImage::border() This property describes how to repeat or stretch the middle parts of the border image. - \list - \li BorderImage.Stretch - Scales the image to fit to the available area. - \li BorderImage.Repeat - Tile the image until there is no more space. May crop the last image. - \li BorderImage.Round - Like Repeat, but scales the images down to ensure that the last image is not cropped. - \endlist + \value BorderImage.Stretch Scales the image to fit to the available area. + \value BorderImage.Repeat Tile the image until there is no more space. May crop the last image. + \value BorderImage.Round Like Repeat, but scales the images down to ensure that the last image is not cropped. The default tile mode for each property is BorderImage.Stretch. */ diff --git a/src/quick/items/qquickborderimage_p.h b/src/quick/items/qquickborderimage_p.h index 48922147ba2..da489b9be7b 100644 --- a/src/quick/items/qquickborderimage_p.h +++ b/src/quick/items/qquickborderimage_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE class QQuickScaleGrid; class QQuickGridScaledImage; class QQuickBorderImagePrivate; -class Q_AUTOTEST_EXPORT QQuickBorderImage : public QQuickImageBase +class Q_QUICK_PRIVATE_EXPORT QQuickBorderImage : public QQuickImageBase { Q_OBJECT diff --git a/src/quick/items/qquickcolorgroup.cpp b/src/quick/items/qquickcolorgroup.cpp index ebbbf07499a..2a039ec1b47 100644 --- a/src/quick/items/qquickcolorgroup.cpp +++ b/src/quick/items/qquickcolorgroup.cpp @@ -47,6 +47,8 @@ QT_BEGIN_NAMESPACE /*! + \internal + \class QQuickColorGroup \brief The QQuickColorGroup class represents a set of colors. \inmodule QtQuick @@ -592,3 +594,5 @@ void QQuickColorGroup::resetColor(QPalette::ColorRole role, Notifier notifier) } QT_END_NAMESPACE + +#include "moc_qquickcolorgroup_p.cpp" diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp index e6ffcee2aa4..1f10be412c2 100644 --- a/src/quick/items/qquickdrag.cpp +++ b/src/quick/items/qquickdrag.cpp @@ -482,7 +482,9 @@ void QQuickDragAttached::setKeys(const QStringList &keys) \qmlattachedproperty stringlist QtQuick::Drag::mimeData \since 5.2 - This property holds a map of mimeData that is used during startDrag. + This property holds a map from mime type to data that is used during startDrag. + The mime data needs to be a \c string, or an \c ArrayBuffer with the data encoded + according to the mime type. */ QVariantMap QQuickDragAttached::mimeData() const @@ -565,11 +567,9 @@ void QQuickDragAttached::setProposedAction(Qt::DropAction action) A drag can also be started manually using \l startDrag. - \list - \li Drag.None - do not start drags automatically - \li Drag.Automatic - start drags automatically - \li Drag.Internal (default) - start backwards compatible drags automatically - \endlist + \value Drag.None do not start drags automatically + \value Drag.Automatic start drags automatically + \value Drag.Internal (default) start backwards compatible drags automatically When using \c Drag.Automatic you should also define \l mimeData and bind the \l active property to the active property of MouseArea : \l {MouseArea::drag.active} @@ -664,12 +664,10 @@ void QQuickDragAttached::start(QQmlV4Function *args) The returned drop action may be one of: - \list - \li Qt.CopyAction Copy the data to the target - \li Qt.MoveAction Move the data from the source to the target - \li Qt.LinkAction Create a link from the source to the target. - \li Qt.IgnoreAction Ignore the action (do nothing with the data). - \endlist + \value Qt.CopyAction Copy the data to the target + \value Qt.MoveAction Move the data from the source to the target + \value Qt.LinkAction Create a link from the source to the target. + \value Qt.IgnoreAction Ignore the action (do nothing with the data). */ int QQuickDragAttached::drop() @@ -767,8 +765,12 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct QDrag *drag = new QDrag(source ? source : q); QMimeData *mimeData = new QMimeData(); - for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) - mimeData->setData(it.key(), it.value().toString().toUtf8()); + for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) { + if (it.value().typeId() == QMetaType::QByteArray) + mimeData->setData(it.key(), it.value().toByteArray()); + else + mimeData->setData(it.key(), it.value().toString().toUtf8()); + } drag->setMimeData(mimeData); if (pixmapLoader.isReady()) { diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h index b02a0ea2e1b..38ec278adb7 100644 --- a/src/quick/items/qquickdrag_p.h +++ b/src/quick/items/qquickdrag_p.h @@ -109,9 +109,12 @@ class QQuickDragGrabber void grab(QQuickItem *item) { m_items.insert(new Item(item)); } iterator release(iterator at) { Item *item = *at; at = at.erase(); delete item; return at; } + auto& ignoreList() { return m_ignoreDragItems; } + private: ItemList m_items; + QVarLengthArray<QQuickItem *, 4> m_ignoreDragItems; QObject *m_target; }; diff --git a/src/quick/items/qquickdroparea.cpp b/src/quick/items/qquickdroparea.cpp index f8b4d91bdac..2e797f2e0de 100644 --- a/src/quick/items/qquickdroparea.cpp +++ b/src/quick/items/qquickdroparea.cpp @@ -91,6 +91,7 @@ QQuickDropAreaPrivate::~QQuickDropAreaPrivate() /*! \qmltype DropArea \instantiates QQuickDropArea + \inherits Item \inqmlmodule QtQuick \ingroup qtquick-input \brief For specifying drag and drop handling in an area. @@ -225,7 +226,7 @@ void QQuickDropArea::dragMoveEvent(QDragMoveEvent *event) emit d->drag->positionChanged(); event->accept(); - QQuickDropEvent dragTargetEvent(d, event); + QQuickDragEvent dragTargetEvent(d, event); emit positionChanged(&dragTargetEvent); } @@ -261,20 +262,27 @@ void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event) if (!d->effectiveEnable || d->containsDrag || !mimeData || !d->hasMatchingKey(d->getKeys(mimeData))) return; + const QQuickDragMimeData *dragMime = qobject_cast<const QQuickDragMimeData *>(mimeData); + auto dragSource = dragMime ? dragMime->source() : event->source(); + + // if the source of the drag is an ancestor of the drop area, then dragging + // also drags the drop area; see QTBUG-64128 + if (QQuickItem *dragSourceItem = qobject_cast<QQuickItem *>(dragSource)) { + if (dragSourceItem->isAncestorOf(this)) + return; + } + d->dragPosition = event->position().toPoint(); event->accept(); - QQuickDropEvent dragTargetEvent(d, event); + QQuickDragEvent dragTargetEvent(d, event); emit entered(&dragTargetEvent); if (!event->isAccepted()) return; d->containsDrag = true; - if (QQuickDragMimeData *dragMime = qobject_cast<QQuickDragMimeData *>(const_cast<QMimeData *>(mimeData))) - d->source = dragMime->source(); - else - d->source = event->source(); + d->source = dragSource; d->dragPosition = event->position().toPoint(); if (d->drag) { emit d->drag->positionChanged(); @@ -317,7 +325,7 @@ void QQuickDropArea::dropEvent(QDropEvent *event) if (!d->containsDrag) return; - QQuickDropEvent dragTargetEvent(d, event); + QQuickDragEvent dragTargetEvent(d, event); emit dropped(&dragTargetEvent); d->containsDrag = false; @@ -329,7 +337,7 @@ void QQuickDropArea::dropEvent(QDropEvent *event) /*! \qmltype DragEvent - \instantiates QQuickDropEvent + \instantiates QQuickDragEvent \inqmlmodule QtQuick \ingroup qtquick-input-events \brief Provides information about a drag event. @@ -381,12 +389,10 @@ void QQuickDropArea::dropEvent(QDropEvent *event) The drop action may be one of: - \list - \li Qt.CopyAction Copy the data to the target. - \li Qt.MoveAction Move the data from the source to the target. - \li Qt.LinkAction Create a link from the source to the target. - \li Qt.IgnoreAction Ignore the action (do nothing with the data). - \endlist + \value Qt.CopyAction Copy the data to the target. + \value Qt.MoveAction Move the data from the source to the target. + \value Qt.LinkAction Create a link from the source to the target. + \value Qt.IgnoreAction Ignore the action (do nothing with the data). */ /*! @@ -506,7 +512,7 @@ void QQuickDropArea::dropEvent(QDropEvent *event) easily be translated into a QByteArray. \a format should be one contained in the \l formats property. */ -QObject *QQuickDropEvent::source() const +QObject *QQuickDragEvent::source() const { if (const QQuickDragMimeData *dragMime = qobject_cast<const QQuickDragMimeData *>(event->mimeData())) return dragMime->source(); @@ -514,57 +520,57 @@ QObject *QQuickDropEvent::source() const return event->source(); } -QStringList QQuickDropEvent::keys() const +QStringList QQuickDragEvent::keys() const { return d->getKeys(event->mimeData()); } -bool QQuickDropEvent::hasColor() const +bool QQuickDragEvent::hasColor() const { return event->mimeData()->hasColor(); } -bool QQuickDropEvent::hasHtml() const +bool QQuickDragEvent::hasHtml() const { return event->mimeData()->hasHtml(); } -bool QQuickDropEvent::hasText() const +bool QQuickDragEvent::hasText() const { return event->mimeData()->hasText(); } -bool QQuickDropEvent::hasUrls() const +bool QQuickDragEvent::hasUrls() const { return event->mimeData()->hasUrls(); } -QVariant QQuickDropEvent::colorData() const +QVariant QQuickDragEvent::colorData() const { return event->mimeData()->colorData(); } -QString QQuickDropEvent::html() const +QString QQuickDragEvent::html() const { return event->mimeData()->html(); } -QString QQuickDropEvent::text() const +QString QQuickDragEvent::text() const { return event->mimeData()->text(); } -QList<QUrl> QQuickDropEvent::urls() const +QList<QUrl> QQuickDragEvent::urls() const { return event->mimeData()->urls(); } -QStringList QQuickDropEvent::formats() const +QStringList QQuickDragEvent::formats() const { return event->mimeData()->formats(); } -void QQuickDropEvent::getDataAsString(QQmlV4Function *args) +void QQuickDragEvent::getDataAsString(QQmlV4Function *args) { if (args->length() != 0) { QV4::ExecutionEngine *v4 = args->v4engine(); @@ -576,7 +582,7 @@ void QQuickDropEvent::getDataAsString(QQmlV4Function *args) } } -void QQuickDropEvent::getDataAsArrayBuffer(QQmlV4Function *args) +void QQuickDragEvent::getDataAsArrayBuffer(QQmlV4Function *args) { if (args->length() != 0) { QV4::ExecutionEngine *v4 = args->v4engine(); @@ -587,12 +593,12 @@ void QQuickDropEvent::getDataAsArrayBuffer(QQmlV4Function *args) } } -void QQuickDropEvent::acceptProposedAction(QQmlV4Function *) +void QQuickDragEvent::acceptProposedAction(QQmlV4Function *) { event->acceptProposedAction(); } -void QQuickDropEvent::accept(QQmlV4Function *args) +void QQuickDragEvent::accept(QQmlV4Function *args) { Qt::DropAction action = event->dropAction(); diff --git a/src/quick/items/qquickdroparea_p.h b/src/quick/items/qquickdroparea_p.h index cabb54011d0..122029a18ab 100644 --- a/src/quick/items/qquickdroparea_p.h +++ b/src/quick/items/qquickdroparea_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <private/qtquickglobal_p.h> #include "qquickitem.h" #include <QtGui/qevent.h> @@ -60,7 +61,7 @@ QT_REQUIRE_CONFIG(quick_draganddrop); QT_BEGIN_NAMESPACE class QQuickDropAreaPrivate; -class QQuickDropEvent : public QObject +class QQuickDragEvent : public QObject { Q_OBJECT Q_PROPERTY(qreal x READ x) @@ -80,10 +81,11 @@ class QQuickDropEvent : public QObject Q_PROPERTY(QString text READ text) Q_PROPERTY(QList<QUrl> urls READ urls) Q_PROPERTY(QStringList formats READ formats) - QML_ANONYMOUS + QML_NAMED_ELEMENT(DragEvent) + QML_UNCREATABLE("DragEvent is only meant to be created by DropArea") QML_ADDED_IN_VERSION(2, 0) public: - QQuickDropEvent(QQuickDropAreaPrivate *d, QDropEvent *event) : d(d), event(event) {} + QQuickDragEvent(QQuickDropAreaPrivate *d, QDropEvent *event) : d(d), event(event) {} qreal x() const { return event->position().x(); } qreal y() const { return event->position().y(); } @@ -149,7 +151,7 @@ class QQuickDropAreaDrag : public QObject }; class QQuickDropAreaPrivate; -class Q_AUTOTEST_EXPORT QQuickDropArea : public QQuickItem +class Q_QUICK_PRIVATE_EXPORT QQuickDropArea : public QQuickItem { Q_OBJECT Q_PROPERTY(bool containsDrag READ containsDrag NOTIFY containsDragChanged) @@ -175,10 +177,10 @@ class Q_AUTOTEST_EXPORT QQuickDropArea : public QQuickItem void keysChanged(); void sourceChanged(); - void entered(QQuickDropEvent *drag); + void entered(QQuickDragEvent *drag); void exited(); - void positionChanged(QQuickDropEvent *drag); - void dropped(QQuickDropEvent *drop); + void positionChanged(QQuickDragEvent *drag); + void dropped(QQuickDragEvent *drop); protected: void dragMoveEvent(QDragMoveEvent *event) override; @@ -193,7 +195,6 @@ class Q_AUTOTEST_EXPORT QQuickDropArea : public QQuickItem QT_END_NAMESPACE -QML_DECLARE_TYPE(QQuickDropEvent) QML_DECLARE_TYPE(QQuickDropArea) #endif // QQUICKDROPAREA_P_H diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index ba9082cc2ac..b749cbe771e 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -133,16 +133,15 @@ Item { This property holds the keyboard modifier flags that existed immediately before the event occurred. - It contains a bitwise combination of: - \list - \li \l {Qt::NoModifier} {Qt.NoModifier} - No modifier key is pressed. - \li \l {Qt::ShiftModifier} {Qt.ShiftModifier} - A Shift key on the keyboard is pressed. - \li \l {Qt::ControlModifier} {Qt.ControlModifier} - A Ctrl key on the keyboard is pressed. - \li \l {Qt::AltModifier} {Qt.AltModifier} - An Alt key on the keyboard is pressed. - \li \l {Qt::MetaModifier} {Qt.MetaModifier} - A Meta key on the keyboard is pressed. - \li \l {Qt::KeypadModifier} {Qt.KeypadModifier} - A keypad button is pressed. - \li \l {Qt::GroupSwitchModifier} {Qt.GroupSwitchModifier} - X11 only. A Mode_switch key on the keyboard is pressed. - \endlist + It contains a bitwise combination of numeric values (the same as in Qt::KeyboardModifier): + + \value Qt.NoModifier No modifier key is pressed. + \value Qt.ShiftModifier} A Shift key on the keyboard is pressed. + \value Qt.ControlModifier A Ctrl key on the keyboard is pressed. + \value Qt.AltModifier An Alt key on the keyboard is pressed. + \value Qt.MetaModifier A Meta key on the keyboard is pressed. + \value Qt.KeypadModifier A keypad button is pressed. + \value Qt.GroupSwitchModifier X11 only. A Mode_switch key on the keyboard is pressed. For example, to react to a Shift key + Enter key combination: \qml @@ -289,6 +288,7 @@ bool QQuickKeyEvent::matches(QKeySequence::StandardKey matchKey) const /*! \qmlproperty int QtQuick::MouseEvent::source \since 5.7 + \deprecated [6.2] Use \l {Qt Quick Input Handlers}{input handlers} with \l {PointerDeviceHandler::acceptedDevices}{acceptedDevices} set. This property holds the source of the mouse event. @@ -364,10 +364,9 @@ bool QQuickKeyEvent::matches(QKeySequence::StandardKey matchKey) const \ingroup qtquick-input-events \brief Provides information about a mouse wheel event. - The position of the mouse can be found via the - \l {Item::x} {x} and \l {Item::y} {y} properties. + The position of the mouse can be found via the \l x and \l y properties. - \sa MouseArea + \sa WheelHandler, MouseArea */ /*! @@ -380,16 +379,20 @@ bool QQuickKeyEvent::matches(QKeySequence::StandardKey matchKey) const \qmlproperty real QtQuick::WheelEvent::y These properties hold the coordinates of the position supplied by the wheel event. + + \sa QWheelEvent::position() */ /*! \qmlproperty bool QtQuick::WheelEvent::accepted - Setting \a accepted to true prevents the wheel event from being - propagated to items below this item. + Setting \a accepted to \c true prevents the wheel event from being + propagated to items below the receiving item or handler. - Generally, if the item acts on the wheel event then it should be accepted + Generally, if the item acts on the wheel event, it should be accepted so that items lower in the stacking order do not also respond to the same event. + + \sa QWheelEvent::accepted */ /*! @@ -403,32 +406,39 @@ bool QQuickKeyEvent::matches(QKeySequence::StandardKey matchKey) const \li \l {Qt::RightButton} {Qt.RightButton} \li \l {Qt::MiddleButton} {Qt.MiddleButton} \endlist + + \sa QWheelEvent::buttons() */ /*! \qmlproperty point QtQuick::WheelEvent::angleDelta - This property holds the distance that the wheel is rotated in wheel degrees. - The x and y cordinate of this property holds the delta in horizontal and - vertical orientation. + This property holds the relative amount that the wheel was rotated, in + eighths of a degree. The \c x and \c y coordinates of this property hold + the delta in horizontal and vertical orientations, respectively. A positive value indicates that the wheel was rotated up/right; a negative value indicates that the wheel was rotated down/left. - Most mouse types work in steps of 15 degrees, in which case the delta value is a - multiple of 120; i.e., 120 units * 1/8 = 15 degrees. + Most mouse types work in steps of \c 15 degrees, in which case the delta value is a + multiple of \c 120; i.e., \c {120 units * 1/8 = 15 degrees}. + + \sa QWheelEvent::angleDelta() */ /*! \qmlproperty point QtQuick::WheelEvent::pixelDelta This property holds the delta in screen pixels and is available in platforms that - have high-resolution trackpads, such as \macos. - The x and y cordinate of this property holds the delta in horizontal and - vertical orientation. The value should be used directly to scroll content on screen. + have high-resolution \l {QInputDevice::DeviceType::TouchPad}{trackpads}, such as \macos. + The \c x and \c y coordinates of this property hold the delta in horizontal + and vertical orientations, respectively. The values can be used directly to + scroll content on screen. - For platforms without high-resolution trackpad support, pixelDelta will always be (0,0), - and angleDelta should be used instead. + For platforms without \l {QInputDevice::Capability::PixelScroll}{high-resolution trackpad} + support, pixelDelta will always be \c {(0,0)}, and \l angleDelta should be used instead. + + \sa QWheelEvent::pixelDelta() */ /*! @@ -449,7 +459,7 @@ bool QQuickKeyEvent::matches(QKeySequence::StandardKey matchKey) const For example, to react to a Control key pressed during the wheel event: \qml - MouseArea { + WheelHandler { onWheel: (wheel)=> { if (wheel.modifiers & Qt.ControlModifier) { adjustZoom(wheel.angleDelta.y / 120); @@ -457,6 +467,8 @@ bool QQuickKeyEvent::matches(QKeySequence::StandardKey matchKey) const } } \endqml + + \sa QWheelEvent::modifiers() */ /*! @@ -478,7 +490,11 @@ bool QQuickKeyEvent::matches(QKeySequence::StandardKey matchKey) const negate the angleDelta or pixelDelta values. \note Many platforms provide no such information. On such platforms - \l inverted always returns false. + \c inverted always returns \c false. + + \sa QWheelEvent::inverted() */ QT_END_NAMESPACE + +#include "moc_qquickevents_p_p.cpp" diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 01a8ddd9865..39a0d6659ad 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -43,6 +43,8 @@ #include "qquickwindow.h" #include "qquickwindow_p.h" #include "qquickevents_p_p.h" +#include "qquickmousearea_p.h" +#include "qquickdrag_p.h" #include <QtQuick/private/qquickpointerhandler_p.h> #include <QtQuick/private/qquicktransition_p.h> @@ -52,8 +54,8 @@ #include <QtGui/qevent.h> #include <QtGui/qguiapplication.h> #include <QtGui/private/qguiapplication_p.h> +#include <QtGui/private/qeventpoint_p.h> #include <QtGui/qstylehints.h> -#include <QtGui/qpa/qplatformtheme.h> #include <QtCore/qmath.h> #include "qplatformdefs.h" @@ -77,10 +79,6 @@ static const int FlickThreshold = 15; // will ensure the Flickable retains the grab on consecutive flicks. static const int RetainGrabVelocity = 100; -// ReportedVelocitySmoothing determines how reported velocity is -// smoothed to avoid erratic output. -static const int ReportedVelocitySmoothing = 100; - // Currently std::round can't be used on Android when using ndk g++, so // use C version instead. We could just define two versions of Round, one // for float and one for double, but then only one of them would be used @@ -142,7 +140,8 @@ void QQuickFlickableVisibleArea::updateVisible() qreal pagePos = 0; qreal pageSize = 0; if (!qFuzzyIsNull(maxYBounds)) { - pagePos = (-p->vData.move.value() + flickable->minYExtent()) / maxYBounds; + qreal y = p->pixelAligned ? Round(p->vData.move.value()) : p->vData.move.value(); + pagePos = (-y + flickable->minYExtent()) / maxYBounds; pageSize = viewheight / maxYBounds; } @@ -160,7 +159,8 @@ void QQuickFlickableVisibleArea::updateVisible() const qreal maxxextent = -flickable->maxXExtent() + flickable->minXExtent(); const qreal maxXBounds = maxxextent + viewwidth; if (!qFuzzyIsNull(maxXBounds)) { - pagePos = (-p->hData.move.value() + flickable->minXExtent()) / maxXBounds; + qreal x = p->pixelAligned ? Round(p->hData.move.value()) : p->hData.move.value(); + pagePos = (-x + flickable->minXExtent()) / maxXBounds; pageSize = viewwidth / maxXBounds; } else { pagePos = 0; @@ -258,11 +258,27 @@ QQuickFlickablePrivate::AxisData::~AxisData() delete transitionToBounds; } - -QVarLengthArray<const QPointingDevice *, 4> QQuickFlickablePrivate::nonClickyWheelMice; +class QQuickFlickableContentItem : public QQuickItem +{ + /*! + \internal + The flickable area inside the viewport can be bigger than the bounds of the + content item itself, if the flickable is using non-zero extents (as returned + by e.g minXExtent()). Since the default implementation in QQuickItem::contains() + only checks if the point is inside the bounds of the item, we need to override it + to check the extents as well. The easist way to do this is to simply check if the + point is inside the bounds of the flickable rather than the content item. + */ + bool contains(const QPointF &point) const override + { + const QQuickItem *flickable = parentItem(); + const QPointF posInFlickable = flickable->mapFromItem(this, point); + return flickable->contains(posInFlickable); + } +}; QQuickFlickablePrivate::QQuickFlickablePrivate() - : contentItem(new QQuickItem) + : contentItem(new QQuickFlickableContentItem) , hData(this, &QQuickFlickablePrivate::setViewportX) , vData(this, &QQuickFlickablePrivate::setViewportY) , hMoved(false), vMoved(false) @@ -275,7 +291,8 @@ QQuickFlickablePrivate::QQuickFlickablePrivate() , deceleration(QML_FLICK_DEFAULTDECELERATION) , maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY) , delayedPressEvent(nullptr), pressDelay(0), fixupDuration(400) - , flickBoost(1.0), fixupMode(Normal), vTime(0), visibleArea(nullptr) + , flickBoost(1.0), initialWheelFlickDistance(qApp->styleHints()->wheelScrollLines() * 24) + , fixupMode(Normal), vTime(0), visibleArea(nullptr) , flickableDirection(QQuickFlickable::AutoFlickDirection) , boundsBehavior(QQuickFlickable::DragAndOvershootBounds) , boundsMovement(QQuickFlickable::FollowBoundsBehavior) @@ -299,16 +316,17 @@ void QQuickFlickablePrivate::init() viewportPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry); } -/* - Returns the amount to overshoot by given a velocity. - Will be roughly in range 0 - size/4 +/*! + \internal + Returns the distance to overshoot, given \a velocity. + Will be in range 0 - velocity / 3, but limited to a max of QML_FLICK_OVERSHOOT */ -qreal QQuickFlickablePrivate::overShootDistance(qreal size) const +qreal QQuickFlickablePrivate::overShootDistance(qreal velocity) const { if (maxVelocity <= 0) - return 0.0; + return 0; - return qMin(qreal(QML_FLICK_OVERSHOOT), size/3); + return qMin(qreal(QML_FLICK_OVERSHOOT), velocity / 3); } void QQuickFlickablePrivate::AxisData::addVelocitySample(qreal v, qreal maxVelocity) @@ -335,7 +353,7 @@ void QQuickFlickablePrivate::AxisData::updateVelocity() } } -void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) +void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeom) { Q_Q(QQuickFlickable); if (item == contentItem) { @@ -344,8 +362,14 @@ void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometr orient |= Qt::Horizontal; if (change.yChange()) orient |= Qt::Vertical; - if (orient) + if (orient) { q->viewportMoved(orient); + const QPointF deltaMoved = item->position() - oldGeom.topLeft(); + if (hData.contentPositionChangedExternallyDuringDrag) + hData.pressPos += deltaMoved.x(); + if (vData.contentPositionChangedExternallyDuringDrag) + vData.pressPos += deltaMoved.y(); + } if (orient & Qt::Horizontal) emit q->contentXChanged(); if (orient & Qt::Vertical) @@ -400,13 +424,10 @@ bool QQuickFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExt resetTimeline(data); if (!data.inOvershoot) { - if (boundsBehavior & QQuickFlickable::OvershootBounds) { - qCDebug(lcVel) << "timeline.accel(" << data.move << v << accel << ')'; + if (boundsBehavior & QQuickFlickable::OvershootBounds) timeline.accel(data.move, v, accel); - } else { - qCDebug(lcVel) << "timeline.accel(" << data.move << v << accel << "maxDist" << maxDistance << ')'; + else timeline.accel(data.move, v, accel, maxDistance); - } } timeline.callback(QQuickTimeLineCallback(&data.move, fixupCallback, this)); @@ -540,32 +561,40 @@ void QQuickFlickablePrivate::updateBeginningEnd() const qreal maxyextent = -q->maxYExtent(); const qreal minyextent = -q->minYExtent(); const qreal ypos = -vData.move.value(); - bool atBeginning = fuzzyLessThanOrEqualTo(ypos, minyextent); - bool atEnd = fuzzyLessThanOrEqualTo(maxyextent, ypos); + bool atBeginning = fuzzyLessThanOrEqualTo(ypos, std::ceil(minyextent)); + bool atEnd = fuzzyLessThanOrEqualTo(std::floor(maxyextent), ypos); if (atBeginning != vData.atBeginning) { vData.atBeginning = atBeginning; atYBeginningChange = true; + if (!vData.moving && atBeginning) + vData.smoothVelocity.setValue(0); } if (atEnd != vData.atEnd) { vData.atEnd = atEnd; atYEndChange = true; + if (!vData.moving && atEnd) + vData.smoothVelocity.setValue(0); } // Horizontal const qreal maxxextent = -q->maxXExtent(); const qreal minxextent = -q->minXExtent(); const qreal xpos = -hData.move.value(); - atBeginning = fuzzyLessThanOrEqualTo(xpos, minxextent); - atEnd = fuzzyLessThanOrEqualTo(maxxextent, xpos); + atBeginning = fuzzyLessThanOrEqualTo(xpos, std::ceil(minxextent)); + atEnd = fuzzyLessThanOrEqualTo(std::floor(maxxextent), xpos); if (atBeginning != hData.atBeginning) { hData.atBeginning = atBeginning; atXBeginningChange = true; + if (!hData.moving && atBeginning) + hData.smoothVelocity.setValue(0); } if (atEnd != hData.atEnd) { hData.atEnd = atEnd; atXEndChange = true; + if (!hData.moving && atEnd) + hData.smoothVelocity.setValue(0); } if (vData.extentsChanged) { @@ -723,7 +752,8 @@ void QQuickFlickablePrivate::updateBeginningEnd() /*! \qmlsignal QtQuick::Flickable::flickEnded() - This signal is emitted when the view stops moving due to a flick. + This signal is emitted when the view stops moving after a flick + or a series of flicks. */ /*! @@ -800,8 +830,11 @@ void QQuickFlickable::setContentX(qreal pos) d->hData.vTime = d->timeline.time(); if (isMoving() || isFlicking()) movementEnding(true, false); - if (!qFuzzyCompare(-pos, d->hData.move.value())) + if (!qFuzzyCompare(-pos, d->hData.move.value())) { + d->hData.contentPositionChangedExternallyDuringDrag = d->hData.dragging; d->hData.move.setValue(-pos); + d->hData.contentPositionChangedExternallyDuringDrag = false; + } } qreal QQuickFlickable::contentY() const @@ -818,8 +851,11 @@ void QQuickFlickable::setContentY(qreal pos) d->vData.vTime = d->timeline.time(); if (isMoving() || isFlicking()) movementEnding(false, true); - if (!qFuzzyCompare(-pos, d->vData.move.value())) + if (!qFuzzyCompare(-pos, d->vData.move.value())) { + d->vData.contentPositionChangedExternallyDuringDrag = d->vData.dragging; d->vData.move.setValue(-pos); + d->vData.contentPositionChangedExternallyDuringDrag = false; + } } /*! @@ -1033,6 +1069,17 @@ void QQuickFlickable::setSynchronousDrag(bool v) } } +/*! \internal + Take the velocity of the first point from the given \a event and transform + it to the local coordinate system (taking scale and rotation into account). +*/ +QVector2D QQuickFlickablePrivate::firstPointLocalVelocity(QPointerEvent *event) +{ + QTransform transform = windowToItemTransform(); + // rotate and scale the velocity vector from scene to local + return QVector2D(transform.map(event->point(0).velocity().toPointF()) - transform.map(QPointF())); +} + qint64 QQuickFlickablePrivate::computeCurrentTime(QInputEvent *event) const { if (0 != event->timestamp()) @@ -1104,7 +1151,9 @@ void QQuickFlickablePrivate::maybeBeginDrag(qint64 currentTimestamp, const QPoin pressPos = pressPosn; hData.pressPos = hData.move.value(); vData.pressPos = vData.move.value(); - bool wasFlicking = hData.flicking || vData.flicking; + const bool wasFlicking = hData.flicking || vData.flicking; + hData.flickingWhenDragBegan = hData.flicking; + vData.flickingWhenDragBegan = vData.flicking; if (hData.flicking) { hData.flicking = false; emit q->flickingHorizontallyChanged(); @@ -1334,20 +1383,24 @@ void QQuickFlickablePrivate::handleMoveEvent(QPointerEvent *event) { Q_Q(QQuickFlickable); if (!interactive || lastPosTime == -1 || - (event->isSinglePointEvent() && static_cast<QSinglePointEvent *>(event)->buttons() == Qt::NoButton)) + (event->isSinglePointEvent() && !static_cast<QSinglePointEvent *>(event)->buttons().testFlag(Qt::LeftButton))) return; qint64 currentTimestamp = computeCurrentTime(event); const auto &firstPoint = event->points().first(); const auto &pos = firstPoint.position(); - QVector2D deltas = QVector2D(pos - q->mapFromGlobal(firstPoint.globalPressPosition())); + const QVector2D deltas = QVector2D(pos - q->mapFromGlobal(firstPoint.globalPressPosition())); + const QVector2D velocity = firstPointLocalVelocity(event); bool overThreshold = false; - QVector2D velocity = event->point(0).velocity(); - if (q->yflick()) - overThreshold |= QQuickDeliveryAgentPrivate::dragOverThreshold(deltas.y(), Qt::YAxis, firstPoint); - if (q->xflick()) - overThreshold |= QQuickDeliveryAgentPrivate::dragOverThreshold(deltas.x(), Qt::XAxis, firstPoint); + if (event->pointCount() == 1) { + if (q->yflick()) + overThreshold |= QQuickDeliveryAgentPrivate::dragOverThreshold(deltas.y(), Qt::YAxis, firstPoint); + if (q->xflick()) + overThreshold |= QQuickDeliveryAgentPrivate::dragOverThreshold(deltas.x(), Qt::XAxis, firstPoint); + } else { + qCDebug(lcFilter) << q->objectName() << "ignoring multi-touch" << event; + } drag(currentTimestamp, event->type(), pos, deltas, overThreshold, false, false, velocity); } @@ -1374,12 +1427,14 @@ void QQuickFlickablePrivate::handleReleaseEvent(QPointerEvent *event) bool canBoost = false; const auto pos = event->points().first().position(); - const auto pressPos = event->points().first().pressPosition(); + const auto pressPos = q->mapFromGlobal(event->points().first().globalPressPosition()); + const QVector2D eventVelocity = firstPointLocalVelocity(event); + qCDebug(lcVel) << event->deviceType() << event->type() << "velocity" << event->points().first().velocity() << "transformed to local" << eventVelocity; qreal vVelocity = 0; if (elapsed < 100 && vData.velocity != 0.) { vVelocity = (event->device()->capabilities().testFlag(QInputDevice::Capability::Velocity) - ? event->point(0).velocity().y() : vData.velocity); + ? eventVelocity.y() : vData.velocity); } if ((vData.atBeginning && vVelocity > 0.) || (vData.atEnd && vVelocity < 0.)) { vVelocity /= 2; @@ -1394,7 +1449,7 @@ void QQuickFlickablePrivate::handleReleaseEvent(QPointerEvent *event) qreal hVelocity = 0; if (elapsed < 100 && hData.velocity != 0.) { hVelocity = (event->device()->capabilities().testFlag(QInputDevice::Capability::Velocity) - ? event->point(0).velocity().x() : hData.velocity); + ? eventVelocity.x() : hData.velocity); } if ((hData.atBeginning && hVelocity > 0.) || (hData.atEnd && hVelocity < 0.)) { hVelocity /= 2; @@ -1433,8 +1488,15 @@ void QQuickFlickablePrivate::handleReleaseEvent(QPointerEvent *event) fixupX(); flickingStarted(flickedHorizontally, flickedVertically); - if (!isViewMoving()) + if (!isViewMoving()) { q->movementEnding(); + } else { + if (flickedVertically) + vMoved = true; + if (flickedHorizontally) + hMoved = true; + q->movementStarting(); + } } void QQuickFlickable::mousePressEvent(QMouseEvent *event) @@ -1546,21 +1608,6 @@ void QQuickFlickable::touchEvent(QTouchEvent *event) QQuickItem::touchEvent(event); } -enum class WheelMomentumSetting { - Default = -1, - Disabled = 0, - Enabled -}; - -static WheelMomentumSetting wheelMomentumEnabled() -{ - bool envIsSet = true; - const bool wheelMomentumEnabled = qEnvironmentVariableIntValue("QT_QUICK_FLICKABLE_WHEEL_MOMENTUM_ENABLED", &envIsSet); - if (!envIsSet) - return WheelMomentumSetting::Default; - return wheelMomentumEnabled ? WheelMomentumSetting::Enabled : WheelMomentumSetting::Disabled; -} - #if QT_CONFIG(wheelevent) void QQuickFlickable::wheelEvent(QWheelEvent *event) { @@ -1580,6 +1627,7 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) d->hData.velocity = 0; d->timer.start(); d->maybeBeginDrag(currentTimestamp, event->position()); + d->lastPosTime = -1; break; case Qt::NoScrollPhase: // default phase with an ordinary wheel mouse case Qt::ScrollUpdate: @@ -1607,101 +1655,57 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) return; } - if (event->source() == Qt::MouseEventNotSynthesized || event->pixelDelta().isNull()) { - // physical mouse wheel, so use angleDelta + qreal elapsed = qreal(currentTimestamp - d->lastPosTime) / qreal(1000); + if (elapsed <= 0) { + d->lastPosTime = currentTimestamp; + qCDebug(lcWheel) << "insufficient elapsed time: can't calculate velocity" << elapsed; + return; + } + + if (event->source() == Qt::MouseEventNotSynthesized || event->pixelDelta().isNull() || event->phase() == Qt::NoScrollPhase) { + // no pixel delta (physical mouse wheel, or "dumb" touchpad), so use angleDelta int xDelta = event->angleDelta().x(); int yDelta = event->angleDelta().y(); - /*! \internal - Will we get smooth scrolling with momentum, or not? - - |env var|enabled |delta|momentum| - |-------|--------|-----|--------| - |not set|Default |120x |y | - |not set|Default |other|n | - |0 |Disabled|120x |n | - |0 |Disabled|other|n | - |1 |Enabled |120x |y | - |1 |Enabled |other|y | - */ - static const WheelMomentumSetting momentumEnvEnabled = wheelMomentumEnabled(); - bool momentumEnabled = (momentumEnvEnabled != WheelMomentumSetting::Disabled); - if (momentumEnvEnabled == WheelMomentumSetting::Default) { - momentumEnabled = !d->nonClickyWheelMice.contains(event->pointingDevice()); - if (momentumEnabled) { - // If a particular mouse ever generates deltas that are not a multiple of 120, - // momentum scrolling is disabled. On a laptop, the "core pointer" might sometimes - // be the touchpad and sometimes a USB mouse (until Qt's multi-mouse support is - // better developed to keep them separate); but if you miss momentum, you can set - // QT_QUICK_FLICKABLE_WHEEL_MOMENTUM_ENABLED=1 to opt back in again. - if (xDelta % 120 || yDelta % 120) { - d->nonClickyWheelMice.append(event->pointingDevice()); - qCDebug(lcWheel) << event->pointingDevice() << "doesn't have a 'clicky' mouse wheel"; - momentumEnabled = false; - } - } - } - qCDebug(lcWheel) << "momentum env:" << int(momentumEnvEnabled) << "this device:" << momentumEnabled; - if (momentumEnabled) { - // engage the velocity timeline for smooth scrolling - if (yflick() && yDelta != 0) { - bool valid = false; - if (yDelta > 0 && contentY() > -minYExtent()) { - d->vData.velocity = qMax(yDelta*2 - d->vData.smoothVelocity.value(), qreal(d->maxVelocity/4)); - valid = true; - } else if (yDelta < 0 && contentY() < -maxYExtent()) { - d->vData.velocity = qMin(yDelta*2 - d->vData.smoothVelocity.value(), qreal(-d->maxVelocity/4)); - valid = true; - } - if (valid) { - d->flickY(d->vData.velocity); + // For a single "clicky" wheel event (angleDelta +/- 120), + // we want flick() to end up moving a distance proportional to QStyleHints::wheelScrollLines(). + // The decel algo from there is + // qreal dist = v2 / (accel * 2.0); + // i.e. initialWheelFlickDistance = (120 / dt)^2 / (deceleration * 2) + // now solve for dt: + // dt = 120 / sqrt(deceleration * 2 * initialWheelFlickDistance) + if (!isMoving()) + elapsed = 120 / qSqrt(d->deceleration * 2 * d->initialWheelFlickDistance); + if (yflick() && yDelta != 0) { + qreal instVelocity = yDelta / elapsed; + // if the direction has changed, start over with filtering, to allow instant movement in the opposite direction + if ((instVelocity < 0 && d->vData.velocity > 0) || (instVelocity > 0 && d->vData.velocity < 0)) + d->vData.velocityBuffer.clear(); + d->vData.addVelocitySample(instVelocity, d->maxVelocity); + d->vData.updateVelocity(); + if ((yDelta > 0 && contentY() > -minYExtent()) || (yDelta < 0 && contentY() < -maxYExtent())) { + const bool newFlick = d->flickY(d->vData.velocity); + if (newFlick && (d->vData.atBeginning != (yDelta > 0) || d->vData.atEnd != (yDelta < 0))) { d->flickingStarted(false, true); - if (d->vData.flicking) { - d->vMoved = true; - movementStarting(); - } - event->accept(); + d->vMoved = true; + movementStarting(); } + event->accept(); } - if (xflick() && xDelta != 0) { - bool valid = false; - if (xDelta > 0 && contentX() > -minXExtent()) { - d->hData.velocity = qMax(xDelta*2 - d->hData.smoothVelocity.value(), qreal(d->maxVelocity/4)); - valid = true; - } else if (xDelta < 0 && contentX() < -maxXExtent()) { - d->hData.velocity = qMin(xDelta*2 - d->hData.smoothVelocity.value(), qreal(-d->maxVelocity/4)); - valid = true; - } - if (valid) { - d->flickX(d->hData.velocity); + } + if (xflick() && xDelta != 0) { + qreal instVelocity = xDelta / elapsed; + // if the direction has changed, start over with filtering, to allow instant movement in the opposite direction + if ((instVelocity < 0 && d->hData.velocity > 0) || (instVelocity > 0 && d->hData.velocity < 0)) + d->hData.velocityBuffer.clear(); + d->hData.addVelocitySample(instVelocity, d->maxVelocity); + d->hData.updateVelocity(); + if ((xDelta > 0 && contentX() > -minXExtent()) || (xDelta < 0 && contentX() < -maxXExtent())) { + const bool newFlick = d->flickX(d->hData.velocity); + if (newFlick && (d->hData.atBeginning != (xDelta > 0) || d->hData.atEnd != (xDelta < 0))) { d->flickingStarted(true, false); - if (d->hData.flicking) { - d->hMoved = true; - movementStarting(); - } - event->accept(); + d->hMoved = true; + movementStarting(); } - } - } else { - // if it's a laptop touchpad, ignore velocity and make scroll distance directly proportional to angleDelta - if (yDelta > 0) - yDelta = qMin(yDelta, int(contentY() + minYExtent())); - else if (yDelta < 0) - yDelta = qMax(yDelta, int(contentY() + maxYExtent())); - if (xDelta > 0) - xDelta = qMin(xDelta, int(contentX() + minXExtent())); - else if (xDelta < 0) - xDelta = qMax(xDelta, int(contentX() + maxXExtent())); - - if ((xflick() && xDelta != 0) || (yflick() && yDelta != 0)) { - // if QStyleHints::wheelScrollLines() != 3, scale it accordingly - // (Flickable has no idea how many "lines" are being scrolled: depends on font size etc.) - static const float defaultWheelScrollLines = QPlatformTheme::defaultThemeHint(QPlatformTheme::WheelScrollLines).toFloat(); - const float configuredWheelScrollLines = qGuiApp->styleHints()->wheelScrollLines(); - const float deltaRatio = configuredWheelScrollLines / defaultWheelScrollLines; - d->accumulatedWheelPixelDelta += QVector2D(xDelta * deltaRatio, yDelta * deltaRatio); - qCDebug(lcWheel) << "scroll lines: default" << defaultWheelScrollLines - << "style hint" << configuredWheelScrollLines << "scaled acc delta" << d->accumulatedWheelPixelDelta; - d->drag(currentTimestamp, event->type(), event->position(), d->accumulatedWheelPixelDelta, true, false, false, {}); event->accept(); } } @@ -1710,13 +1714,7 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) int xDelta = event->pixelDelta().x(); int yDelta = event->pixelDelta().y(); - qreal elapsed = qreal(currentTimestamp - d->lastPosTime) / 1000.; - if (elapsed <= 0) { - d->lastPosTime = currentTimestamp; - return; - } QVector2D velocity(xDelta / elapsed, yDelta / elapsed); - d->lastPosTime = currentTimestamp; d->accumulatedWheelPixelDelta += QVector2D(event->pixelDelta()); // Try to drag if 1) we already are dragging or flicking, or // 2) the flickable is free to flick both directions, or @@ -1734,6 +1732,7 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) "moving?" << isMoving() << "can flick horizontally?" << xflick() << "vertically?" << yflick(); } } + d->lastPosTime = currentTimestamp; if (!event->isAccepted()) QQuickItem::wheelEvent(event); @@ -1921,19 +1920,23 @@ void QQuickFlickable::componentComplete() setContentX(-minXExtent()); if (!d->vData.explicitValue && d->vData.startMargin != 0.) setContentY(-minYExtent()); + if (lcWheel().isDebugEnabled() || lcVel().isDebugEnabled()) { + d->timeline.setObjectName(QLatin1String("timeline for Flickable ") + objectName()); + d->velocityTimeline.setObjectName(QLatin1String("velocity timeline for Flickable ") + objectName()); + } } void QQuickFlickable::viewportMoved(Qt::Orientations orient) { Q_D(QQuickFlickable); if (orient & Qt::Vertical) - d->viewportAxisMoved(d->vData, minYExtent(), maxYExtent(), height(), d->fixupY_callback); + d->viewportAxisMoved(d->vData, minYExtent(), maxYExtent(), d->fixupY_callback); if (orient & Qt::Horizontal) - d->viewportAxisMoved(d->hData, minXExtent(), maxXExtent(), width(), d->fixupX_callback); + d->viewportAxisMoved(d->hData, minXExtent(), maxXExtent(), d->fixupX_callback); d->updateBeginningEnd(); } -void QQuickFlickablePrivate::viewportAxisMoved(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, +void QQuickFlickablePrivate::viewportAxisMoved(AxisData &data, qreal minExtent, qreal maxExtent, QQuickTimeLineCallback::Callback fixupCallback) { if (!scrollingPhase && (pressed || calcVelocity)) { @@ -1942,21 +1945,22 @@ void QQuickFlickablePrivate::viewportAxisMoved(AxisData &data, qreal minExtent, qreal velocity = (data.lastPos - data.move.value()) * 1000 / elapsed; if (qAbs(velocity) > 0) { velocityTimeline.reset(data.smoothVelocity); - if (calcVelocity) - velocityTimeline.set(data.smoothVelocity, velocity); - else - velocityTimeline.move(data.smoothVelocity, velocity, ReportedVelocitySmoothing); - velocityTimeline.move(data.smoothVelocity, 0, ReportedVelocitySmoothing); + velocityTimeline.set(data.smoothVelocity, velocity); qCDebug(lcVel) << "touchpad scroll phase: velocity" << velocity; } } } else { if (timeline.time() > data.vTime) { velocityTimeline.reset(data.smoothVelocity); - qreal velocity = (data.lastPos - data.move.value()) * 1000 / (timeline.time() - data.vTime); - if (!qFuzzyCompare(data.smoothVelocity.value(), velocity)) - qCDebug(lcVel) << "velocity" << data.smoothVelocity.value() << "->" << velocity; - data.smoothVelocity.setValue(velocity); + int dt = timeline.time() - data.vTime; + if (dt > 2) { + qreal velocity = (data.lastPos - data.move.value()) * 1000 / dt; + if (!qFuzzyCompare(data.smoothVelocity.value(), velocity)) + qCDebug(lcVel) << "velocity" << data.smoothVelocity.value() << "->" << velocity + << "computed as (" << data.lastPos << "-" << data.move.value() << ") * 1000 / (" + << timeline.time() << "-" << data.vTime << ")"; + data.smoothVelocity.setValue(velocity); + } } } @@ -1968,13 +1972,10 @@ void QQuickFlickablePrivate::viewportAxisMoved(AxisData &data, qreal minExtent, ? data.move.value() - minExtent : maxExtent - data.move.value(); data.inOvershoot = true; - qreal maxDistance = overShootDistance(vSize) - overBound; + qreal maxDistance = overShootDistance(qAbs(data.smoothVelocity.value())) - overBound; resetTimeline(data); - if (maxDistance > 0) { - qCDebug(lcVel) << "timeline.accel(" << data.move << -data.smoothVelocity.value() - << deceleration*QML_FLICK_OVERSHOOTFRICTION << "maxDist" << maxDistance << ')'; + if (maxDistance > 0) timeline.accel(data.move, -data.smoothVelocity.value(), deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance); - } timeline.callback(QQuickTimeLineCallback(&data.move, fixupCallback, this)); } @@ -2570,16 +2571,51 @@ bool QQuickFlickable::filterPointerEvent(QQuickItem *receiver, QPointerEvent *ev QQuickDeliveryAgentPrivate::isTabletEvent(event))) return false; // don't filter hover events or wheel events, for example Q_ASSERT_X(receiver != this, "", "Flickable received a filter event for itself"); - qCDebug(lcFilter) << objectName() << "filtering" << event << "for" << receiver; Q_D(QQuickFlickable); // If a touch event contains a new press point, don't steal right away: watch the movements for a while if (isTouch && static_cast<QTouchEvent *>(event)->touchPointStates().testFlag(QEventPoint::State::Pressed)) d->stealMouse = false; + // If multiple touchpoints are within bounds, don't grab: it's probably meant for multi-touch interaction in some child + if (event->pointCount() > 1) { + qCDebug(lcFilter) << objectName() << "ignoring multi-touch" << event << "for" << receiver; + d->stealMouse = false; + } else { + qCDebug(lcFilter) << objectName() << "filtering" << event << "for" << receiver; + } const auto &firstPoint = event->points().first(); + + if (event->pointCount() == 1 && event->exclusiveGrabber(firstPoint) == this) { + // We have an exclusive grab (since we're e.g dragging), but at the same time, we have + // a child with a passive grab (which is why this filter is being called). And because + // of that, we end up getting the same pointer events twice; First in our own event + // handlers (because of the grab), then once more in here, since we filter the child. + // To avoid processing the event twice (e.g avoid calling handleReleaseEvent once more + // from below), we mark the event as filtered, and simply return. + event->setAccepted(true); + return true; + } + QPointF localPos = mapFromScene(firstPoint.scenePosition()); bool receiverDisabled = receiver && !receiver->isEnabled(); bool stealThisEvent = d->stealMouse; bool receiverKeepsGrab = receiver && (receiver->keepMouseGrab() || receiver->keepTouchGrab()); + bool receiverRelinquishGrab = false; + + // Special case for MouseArea, try to guess what it does with the event + if (auto *mouseArea = qmlobject_cast<QQuickMouseArea *>(receiver)) { + bool preventStealing = mouseArea->preventStealing(); + if (mouseArea->drag() && mouseArea->drag()->target()) + preventStealing = true; + if (!preventStealing && receiverKeepsGrab) { + receiverRelinquishGrab = !receiverDisabled + || (QQuickDeliveryAgentPrivate::isMouseEvent(event) + && firstPoint.state() == QEventPoint::State::Pressed + && (receiver->acceptedMouseButtons() & static_cast<QMouseEvent *>(event)->button())); + if (receiverRelinquishGrab) + receiverKeepsGrab = false; + } + } + if ((stealThisEvent || contains(localPos)) && (!receiver || !receiverKeepsGrab || receiverDisabled)) { QScopedPointer<QPointerEvent> localizedEvent(QQuickDeliveryAgentPrivate::clonePointerEvent(event, localPos)); localizedEvent->setAccepted(false); @@ -2590,7 +2626,9 @@ bool QQuickFlickable::filterPointerEvent(QQuickItem *receiver, QPointerEvent *ev case QEventPoint::State::Pressed: d->handlePressEvent(localizedEvent.data()); d->captureDelayedPress(receiver, event); - stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by function call above + // never grab the pointing device on press during filtering: do it later, during a move + d->stealMouse = false; + stealThisEvent = false; break; case QEventPoint::State::Released: d->handleReleaseEvent(localizedEvent.data()); @@ -2607,7 +2645,7 @@ bool QQuickFlickable::filterPointerEvent(QQuickItem *receiver, QPointerEvent *ev event->setExclusiveGrabber(firstPoint, this); } - const bool filtered = stealThisEvent || d->delayedPressEvent || receiverDisabled; + const bool filtered = !receiverRelinquishGrab && (stealThisEvent || d->delayedPressEvent || receiverDisabled); if (filtered) { event->setAccepted(true); } @@ -2633,8 +2671,19 @@ bool QQuickFlickable::filterPointerEvent(QQuickItem *receiver, QPointerEvent *ev bool QQuickFlickable::childMouseEventFilter(QQuickItem *i, QEvent *e) { Q_D(QQuickFlickable); + QPointerEvent *pointerEvent = e->isPointerEvent() ? static_cast<QPointerEvent *>(e) : nullptr; + + auto wantsPointerEvent_helper = [this, d, i, pointerEvent]() { + Q_ASSERT(pointerEvent); + QQuickDeliveryAgentPrivate::localizePointerEvent(pointerEvent, this); + const bool wants = d->wantsPointerEvent(pointerEvent); + // re-localize event back to \a i before returning + QQuickDeliveryAgentPrivate::localizePointerEvent(pointerEvent, i); + return wants; + }; + if (!isVisible() || !isEnabled() || !isInteractive() || - (e->isPointerEvent() && !d->wantsPointerEvent(static_cast<QPointerEvent *>(e)))) { + (pointerEvent && !wantsPointerEvent_helper())) { d->cancelInteraction(); return QQuickItem::childMouseEventFilter(i, e); } @@ -2646,8 +2695,8 @@ bool QQuickFlickable::childMouseEventFilter(QQuickItem *i, QEvent *e) qCDebug(lcFilter) << "filtering UngrabMouse" << spe->points().first() << "for" << i << "grabber is" << grabber; if (grabber != this) mouseUngrabEvent(); // A child has been ungrabbed - } else if (e->isPointerEvent()) { - return filterPointerEvent(i, static_cast<QPointerEvent *>(e)); + } else if (pointerEvent) { + return filterPointerEvent(i, pointerEvent); } return QQuickItem::childMouseEventFilter(i, e); @@ -2676,9 +2725,23 @@ void QQuickFlickable::setMaximumFlickVelocity(qreal v) /*! \qmlproperty real QtQuick::Flickable::flickDeceleration - This property holds the rate at which a flick will decelerate. - - The default value is platform dependent. + This property holds the rate at which a flick will decelerate: + the higher the number, the faster it slows down when the user stops + flicking via touch, touchpad or mouse wheel. For example 0.0001 is nearly + "frictionless", and 10000 feels quite "sticky". + + The default value is platform dependent. Values of zero or less are not allowed. + + \note For touchpad flicking, some platforms drive Flickable directly by + sending QWheelEvents with QWheelEvent::phase() being \c Qt::ScrollMomentum, + after the user has released all fingers from the touchpad. In that case, + the operating system is controlling the deceleration, and this property has + no effect. + + \note For mouse wheel scrolling, and for gesture scrolling on touchpads + that do not have a momentum phase, extremely large values of + flickDeceleration can make Flickable very resistant to scrolling, + especially if \l maximumFlickVelocity is too small. */ qreal QQuickFlickable::flickDeceleration() const { @@ -2691,7 +2754,7 @@ void QQuickFlickable::setFlickDeceleration(qreal deceleration) Q_D(QQuickFlickable); if (deceleration == d->deceleration) return; - d->deceleration = deceleration; + d->deceleration = qMax(0.001, deceleration); emit flickDecelerationChanged(); } @@ -2901,6 +2964,12 @@ void QQuickFlickable::movementStarting() if (!wasMoving && (d->hData.moving || d->vData.moving)) { emit movingChanged(); emit movementStarted(); +#if QT_CONFIG(accessibility) + if (QAccessible::isActive()) { + QAccessibleEvent ev(this, QAccessible::ScrollingStart); + QAccessible::updateAccessibility(&ev); + } +#endif } } @@ -2914,7 +2983,7 @@ void QQuickFlickable::movementEnding(bool hMovementEnding, bool vMovementEnding) Q_D(QQuickFlickable); // emit flicking signals - bool wasFlicking = d->hData.flicking || d->vData.flicking; + const bool wasFlicking = d->hData.flicking || d->vData.flicking; if (hMovementEnding && d->hData.flicking) { d->hData.flicking = false; emit flickingHorizontallyChanged(); @@ -2926,6 +2995,10 @@ void QQuickFlickable::movementEnding(bool hMovementEnding, bool vMovementEnding) if (wasFlicking && (!d->hData.flicking || !d->vData.flicking)) { emit flickingChanged(); emit flickEnded(); + } else if (d->hData.flickingWhenDragBegan || d->vData.flickingWhenDragBegan) { + d->hData.flickingWhenDragBegan = !hMovementEnding; + d->vData.flickingWhenDragBegan = !vMovementEnding; + emit flickEnded(); } // emit moving signals @@ -2945,6 +3018,12 @@ void QQuickFlickable::movementEnding(bool hMovementEnding, bool vMovementEnding) if (wasMoving && !isMoving()) { emit movingChanged(); emit movementEnded(); +#if QT_CONFIG(accessibility) + if (QAccessible::isActive()) { + QAccessibleEvent ev(this, QAccessible::ScrollingEnd); + QAccessible::updateAccessibility(&ev); + } +#endif } if (hMovementEnding) { @@ -3072,4 +3151,6 @@ void QQuickFlickable::setBoundsMovement(BoundsMovement movement) QT_END_NAMESPACE +#include "moc_qquickflickable_p_p.cpp" + #include "moc_qquickflickable_p.cpp" diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h index 5e098dfdda9..c748bb9f43c 100644 --- a/src/quick/items/qquickflickable_p_p.h +++ b/src/quick/items/qquickflickable_p_p.h @@ -107,8 +107,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, , smoothVelocity(fp), atEnd(false), atBeginning(true) , transitionToSet(false) , fixingUp(false), inOvershoot(false), inRebound(false), moving(false), flicking(false) - , dragging(false), extentsChanged(false) + , flickingWhenDragBegan(false), dragging(false), extentsChanged(false) , explicitValue(false), minExtentDirty(true), maxExtentDirty(true) + , contentPositionChangedExternallyDuringDrag(false) , unused(0) {} @@ -119,6 +120,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, dragStartOffset = 0; fixingUp = false; inOvershoot = false; + contentPositionChangedExternallyDuringDrag = false; } void markExtentsDirty() { @@ -156,20 +158,22 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, int vTime; QQuickFlickablePrivate::Velocity smoothVelocity; QPODVector<qreal,10> velocityBuffer; - bool atEnd : 1; - bool atBeginning : 1; - bool transitionToSet : 1; - bool fixingUp : 1; - bool inOvershoot : 1; - bool inRebound : 1; - bool moving : 1; - bool flicking : 1; - bool dragging : 1; - bool extentsChanged : 1; - bool explicitValue : 1; - mutable bool minExtentDirty : 1; - mutable bool maxExtentDirty : 1; - uint unused : 19; + uint atEnd : 1; + uint atBeginning : 1; + uint transitionToSet : 1; + uint fixingUp : 1; + uint inOvershoot : 1; + uint inRebound : 1; + uint moving : 1; + uint flicking : 1; + uint flickingWhenDragBegan : 1; + uint dragging : 1; + uint extentsChanged : 1; + uint explicitValue : 1; + mutable uint minExtentDirty : 1; + mutable uint maxExtentDirty : 1; + uint contentPositionChangedExternallyDuringDrag : 1; + uint unused : 17; }; bool flickX(qreal velocity); @@ -195,7 +199,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, void setViewportX(qreal x); void setViewportY(qreal y); - qreal overShootDistance(qreal size) const; + qreal overShootDistance(qreal velocity) const; void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override; @@ -239,6 +243,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, int pressDelay; int fixupDuration; qreal flickBoost; + qreal initialWheelFlickDistance; enum FixupMode { Normal, Immediate, ExtentChanged }; FixupMode fixupMode; @@ -255,7 +260,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, QQuickFlickable::BoundsMovement boundsMovement; QQuickTransition *rebound; - void viewportAxisMoved(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, + void viewportAxisMoved(AxisData &data, qreal minExtent, qreal maxExtent, QQuickTimeLineCallback::Callback fixupCallback); void handlePressEvent(QPointerEvent *); @@ -267,6 +272,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, const QVector2D &deltas, bool overThreshold, bool momentum, bool velocitySensitiveOverBounds, const QVector2D &velocity); + QVector2D firstPointLocalVelocity(QPointerEvent *event); qint64 computeCurrentTime(QInputEvent *event) const; qreal devicePixelRatio() const; @@ -275,11 +281,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, static qsizetype data_count(QQmlListProperty<QObject> *); static QObject *data_at(QQmlListProperty<QObject> *, qsizetype); static void data_clear(QQmlListProperty<QObject> *); - - static QVarLengthArray<const QPointingDevice *, 4> nonClickyWheelMice; }; -class QQuickFlickableVisibleArea : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickFlickableVisibleArea : public QObject { Q_OBJECT diff --git a/src/quick/items/qquickflipable.cpp b/src/quick/items/qquickflipable.cpp index a338985622d..87112c8b934 100644 --- a/src/quick/items/qquickflipable.cpp +++ b/src/quick/items/qquickflipable.cpp @@ -39,7 +39,7 @@ #include "qquickflipable_p.h" #include "qquickitem_p.h" - +#include "qquicktranslate_p.h" #include <QtQml/qqmlinfo.h> @@ -237,9 +237,20 @@ void QQuickFlipable::updatePolish() d->updateSide(); } -// determination on the currently visible side of the flipable -// has to be done on the complete scene transform to give -// correct results. +/*! \internal + Flipable must use the complete scene transform to correctly determine the + currently visible side. + + It must also be independent of camera distance, in case the contents are + too wide: for rotation transforms we simply call QMatrix4x4::rotate(), + whereas QQuickRotation::applyTo(QMatrix4x4*) calls + QMatrix4x4::projectedRotate() which by default assumes the camera distance + is 1024 virtual pixels. So for example if contents inside Flipable are to + be flipped around the y axis, and are wider than 1024*2, some of the + rendering goes behind the "camera". That's expected for rendering (since we + didn't provide API to change camera distance), but not ok for deciding when + to flip. +*/ void QQuickFlipablePrivate::updateSide() { Q_Q(QQuickFlipable); @@ -249,8 +260,39 @@ void QQuickFlipablePrivate::updateSide() sideDirty = false; - QTransform sceneTransform; - itemToParentTransform(sceneTransform); + QMatrix4x4 sceneTransform; + + const qreal tx = x.value(); + const qreal ty = y.value(); + if (!qFuzzyIsNull(tx) || !qFuzzyIsNull(ty)) + sceneTransform.translate(tx, ty); + + for (const auto *transform : std::as_const(transforms)) { + if (const auto *rot = qobject_cast<const QQuickRotation *>(transform)) { + // rotation is a special case: we want to call rotate() instead of projectedRotate() + const auto angle = rot->angle(); + const auto axis = rot->axis(); + if (!(qFuzzyIsNull(angle) || axis.isNull())) { + sceneTransform.translate(rot->origin()); + sceneTransform.rotate(angle, axis.x(), axis.y(), axis.z()); + sceneTransform.translate(-rot->origin()); + } + } else { + transform->applyTo(&sceneTransform); + } + } + + const bool hasRotation = !qFuzzyIsNull(rotation()); + const bool hasScale = !qFuzzyCompare(scale(), 1); + if (hasScale || hasRotation) { + QPointF tp = computeTransformOrigin(); + sceneTransform.translate(tp.x(), tp.y()); + if (hasScale) + sceneTransform.scale(scale(), scale()); + if (hasRotation) + sceneTransform.rotate(rotation(), 0, 0, 1); + sceneTransform.translate(-tp.x(), -tp.y()); + } QPointF p1(0, 0); QPointF p2(1, 0); diff --git a/src/quick/items/qquickflipable_p.h b/src/quick/items/qquickflipable_p.h index 8d6716ec536..7a274395b40 100644 --- a/src/quick/items/qquickflipable_p.h +++ b/src/quick/items/qquickflipable_p.h @@ -64,7 +64,7 @@ QT_REQUIRE_CONFIG(quick_flipable); QT_BEGIN_NAMESPACE class QQuickFlipablePrivate; -class Q_AUTOTEST_EXPORT QQuickFlipable : public QQuickItem +class Q_QUICK_PRIVATE_EXPORT QQuickFlipable : public QQuickItem { Q_OBJECT diff --git a/src/quick/items/qquickfocusscope_p.h b/src/quick/items/qquickfocusscope_p.h index d3e9197fc7e..b8c69a2419f 100644 --- a/src/quick/items/qquickfocusscope_p.h +++ b/src/quick/items/qquickfocusscope_p.h @@ -51,11 +51,12 @@ // We mean it. // +#include <private/qtquickglobal_p.h> #include "qquickitem.h" QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQuickFocusScope : public QQuickItem +class Q_QUICK_PRIVATE_EXPORT QQuickFocusScope : public QQuickItem { Q_OBJECT QML_NAMED_ELEMENT(FocusScope) diff --git a/src/quick/items/qquickgraphicsinfo.cpp b/src/quick/items/qquickgraphicsinfo.cpp index 6e483e8447a..3f4ddac99bf 100644 --- a/src/quick/items/qquickgraphicsinfo.cpp +++ b/src/quick/items/qquickgraphicsinfo.cpp @@ -92,16 +92,15 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object) This property describes the graphics API that is currently in use. The possible values are: - \list - \li GraphicsInfo.Unknown - the default value when no active scenegraph is associated with the item - \li GraphicsInfo.Software - Qt Quick's software renderer based on QPainter with the raster paint engine - \li GraphicsInfo.OpenVG - OpenVG - \li GraphicsInfo.OpenGL - OpenGL or OpenGL ES on top of QRhi, a graphics abstraction layer - \li GraphicsInfo.Direct3D11 - Direct3D 11 on top of QRhi, a graphics abstraction layer - \li GraphicsInfo.Vulkan - Vulkan on top of QRhi, a graphics abstraction layer - \li GraphicsInfo.Metal - Metal on top of QRhi, a graphics abstraction layer - \li GraphicsInfo.Null - Null (no output) on top of QRhi, a graphics abstraction layer - \endlist + + \value GraphicsInfo.Unknown the default value when no active scenegraph is associated with the item + \value GraphicsInfo.Software Qt Quick's software renderer based on QPainter with the raster paint engine + \value GraphicsInfo.OpenVG OpenVG + \value GraphicsInfo.OpenGL OpenGL or OpenGL ES on top of QRhi, a graphics abstraction layer + \value GraphicsInfo.Direct3D11 Direct3D 11 on top of QRhi, a graphics abstraction layer + \value GraphicsInfo.Vulkan Vulkan on top of QRhi, a graphics abstraction layer + \value GraphicsInfo.Metal Metal on top of QRhi, a graphics abstraction layer + \value GraphicsInfo.Null Null (no output) on top of QRhi, a graphics abstraction layer */ /*! @@ -110,12 +109,10 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object) This property contains the shading language supported by the Qt Quick backend the application is using. - \list - \li GraphicsInfo.UnknownShadingLanguage - Not yet known due to no window and scenegraph associated - \li GraphicsInfo.GLSL - GLSL or GLSL ES - \li GraphicsInfo.HLSL - HLSL - \li GraphicsInfo.RhiShader - QShader - \endlist + \value GraphicsInfo.UnknownShadingLanguage Not yet known due to no window and scenegraph associated + \value GraphicsInfo.GLSL GLSL or GLSL ES + \value GraphicsInfo.HLSL HLSL + \value GraphicsInfo.RhiShader QShader \note The value is only up-to-date once the item is associated with a window. Bindings relying on the value have to keep this in mind since the @@ -136,10 +133,8 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object) This property contains a bitmask of the shader compilation approaches supported by the Qt Quick backend the application is using. - \list - \li GraphicsInfo.RuntimeCompilation - \li GraphicsInfo.OfflineCompilation - \endlist + \value GraphicsInfo.RuntimeCompilation + \value GraphicsInfo.OfflineCompilation With OpenGL the value is GraphicsInfo.RuntimeCompilation, which corresponds to the traditional way of using ShaderEffect. Non-OpenGL backends are @@ -163,11 +158,9 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object) This property contains a bitmask of the supported ways of providing shader sources. - \list - \li GraphicsInfo.ShaderSourceString - \li GraphicsInfo.ShaderSourceFile - \li GraphicsInfo.ShaderByteCode - \endlist + \value GraphicsInfo.ShaderSourceString + \value GraphicsInfo.ShaderSourceFile + \value GraphicsInfo.ShaderByteCode With OpenGL the value is GraphicsInfo.ShaderSourceString, which corresponds to the traditional way of inlining GLSL source code into QML. Other, @@ -218,11 +211,10 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object) This property holds the configured OpenGL context profile. The possible values are: - \list - \li GraphicsInfo.OpenGLNoProfile (default) - OpenGL version is lower than 3.2 or OpenGL is not in use. - \li GraphicsInfo.OpenGLCoreProfile - Functionality deprecated in OpenGL version 3.0 is not available. - \li GraphicsInfo.OpenGLCompatibilityProfile - Functionality from earlier OpenGL versions is available. - \endlist + + \value GraphicsInfo.OpenGLNoProfile (default) OpenGL version is lower than 3.2 or OpenGL is not in use. + \value GraphicsInfo.OpenGLCoreProfile Functionality deprecated in OpenGL version 3.0 is not available. + \value GraphicsInfo.OpenGLCompatibilityProfile Functionality from earlier OpenGL versions is available. Reusable QML components will typically use this property in bindings in order to choose between core and non core profile compatible shader sources. @@ -239,11 +231,10 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object) other than OpenGL. The possible values are: - \list - \li GraphicsInfo.SurfaceFormatUnspecified (default) - Unspecified rendering method - \li GraphicsInfo.SurfaceFormatOpenGL - Desktop OpenGL or other graphics API - \li GraphicsInfo.SurfaceFormatOpenGLES - OpenGL ES - \endlist + + \value GraphicsInfo.SurfaceFormatUnspecified (default) Unspecified rendering method + \value GraphicsInfo.SurfaceFormatOpenGL Desktop OpenGL or other graphics API + \value GraphicsInfo.SurfaceFormatOpenGLES OpenGL ES \note This is applicable only to OpenGL. diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index 90fa05f4923..916ae61cf53 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -208,6 +208,8 @@ class QQuickGridViewPrivate : public QQuickItemViewPrivate void updateHeader() override; void updateFooter() override; + void initializeComponentItem(QQuickItem *item) const override; + void changedVisibleIndex(int newIndex) override; void initializeCurrentItem() override; @@ -349,9 +351,27 @@ qreal QQuickGridViewPrivate::rowPosAt(int modelIndex) const return lastItem->rowPos() + rows * rowSize(); } } - return (modelIndex / columns) * rowSize(); -} + qreal rowPos = ((modelIndex / columns) * rowSize()); + + if (flow == QQuickGridView::FlowLeftToRight && verticalLayoutDirection == QQuickItemView::TopToBottom) { + // Add the effective startpos of row 0. Start by subtracting minExtent, which will contain the + // height of the rows outside the beginning of the content item. (Rows can end up outside if + // e.g flicking the viewport a long way down, changing cellSize, and then flick back). + // NOTE: It's not clearly understood why the flow == QQuickGridView::FlowLeftToRight guard is + // needed, since the flow shouldn't normally affect the y postition of an index. But without + // it, several auto tests start failing, so we keep it until this part is better understood. + rowPos -= minExtent; + // minExtent will also contain the size of the topMargin (vData.startMargin), the header, and + // the highlightRangeStart. Those should be added before the start of row 0. So we need to subtract + // them from the rowPos. But only the largest of topMargin and highlightRangeStart will need + // to be taken into account, since having a topMargin will also ensure that currentItem ends + // up within the requested highlight range when view is positioned at the beginning. + rowPos += qMax(vData.startMargin, highlightRangeStart) + headerSize(); + } + + return rowPos; +} qreal QQuickGridViewPrivate::snapPosAt(qreal pos) const { @@ -835,6 +855,14 @@ void QQuickGridViewPrivate::updateFooter() emit q->footerItemChanged(); } +void QQuickGridViewPrivate::initializeComponentItem(QQuickItem *item) const +{ + QQuickGridViewAttached *attached = static_cast<QQuickGridViewAttached *>( + qmlAttachedPropertiesObject<QQuickGridView>(item)); + if (attached) + attached->setView(const_cast<QQuickGridView*>(q_func())); +} + void QQuickGridViewPrivate::updateHeader() { Q_Q(QQuickGridView); @@ -1439,36 +1467,32 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight) Valid values for \c highlightRangeMode are: - \list - \li GridView.ApplyRange - the view attempts to maintain the highlight within the range. + \value GridView.ApplyRange the view attempts to maintain the highlight within the range. However, the highlight can move outside of the range at the ends of the view or due to mouse interaction. - \li GridView.StrictlyEnforceRange - the highlight never moves outside of the range. + \value GridView.StrictlyEnforceRange the highlight never moves outside of the range. The current item changes if a keyboard or mouse action would cause the highlight to move outside of the range. - \li GridView.NoHighlightRange - this is the default value. - \endlist + \value GridView.NoHighlightRange the default value */ /*! - \qmlproperty enumeration QtQuick::GridView::layoutDirection - This property holds the layout direction of the grid. + \qmlproperty enumeration QtQuick::GridView::layoutDirection + This property holds the layout direction of the grid. Possible values: - \list - \li Qt.LeftToRight (default) - Items will be laid out starting in the top, left corner. The flow is - dependent on the \l GridView::flow property. - \li Qt.RightToLeft - Items will be laid out starting in the top, right corner. The flow is dependent - on the \l GridView::flow property. - \endlist + \value Qt.LeftToRight (default) Items will be laid out starting in the top, left corner. The flow is + dependent on the \l GridView::flow property. + \value Qt.RightToLeft Items will be laid out starting in the top, right corner. The flow is dependent + on the \l GridView::flow property. - \b Note: If GridView::flow is set to GridView.FlowLeftToRight, this is not to be confused if - GridView::layoutDirection is set to Qt.RightToLeft. The GridView.FlowLeftToRight flow value simply - indicates that the flow is horizontal. + \b Note: If GridView::flow is set to GridView.FlowLeftToRight, this is not to be confused if + GridView::layoutDirection is set to Qt.RightToLeft. The GridView.FlowLeftToRight flow value simply + indicates that the flow is horizontal. - \sa GridView::effectiveLayoutDirection, GridView::verticalLayoutDirection + \sa GridView::effectiveLayoutDirection, GridView::verticalLayoutDirection */ @@ -1489,10 +1513,8 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight) Possible values: - \list - \li GridView.TopToBottom (default) - Items are laid out from the top of the view down to the bottom of the view. - \li GridView.BottomToTop - Items are laid out from the bottom of the view up to the top of the view. - \endlist + \value GridView.TopToBottom (default) Items are laid out from the top of the view down to the bottom of the view. + \value GridView.BottomToTop Items are laid out from the bottom of the view up to the top of the view. \sa GridView::layoutDirection */ @@ -1600,10 +1622,8 @@ void QQuickGridView::setHighlightMoveDuration(int duration) Possible values: - \list - \li GridView.FlowLeftToRight (default) - Items are laid out from left to right, and the view scrolls vertically - \li GridView.FlowTopToBottom - Items are laid out from top to bottom, and the view scrolls horizontally - \endlist + \value GridView.FlowLeftToRight (default) Items are laid out from left to right, and the view scrolls vertically + \value GridView.FlowTopToBottom Items are laid out from top to bottom, and the view scrolls horizontally */ QQuickGridView::Flow QQuickGridView::flow() const { @@ -1653,6 +1673,7 @@ void QQuickGridView::setCellWidth(qreal cellWidth) d->updateViewport(); emit cellWidthChanged(); d->forceLayoutPolish(); + QQuickFlickable::setContentX(d->contentXForPosition(d->position())); } } @@ -1670,6 +1691,7 @@ void QQuickGridView::setCellHeight(qreal cellHeight) d->updateViewport(); emit cellHeightChanged(); d->forceLayoutPolish(); + QQuickFlickable::setContentY(d->contentYForPosition(d->position())); } } /*! @@ -1678,15 +1700,12 @@ void QQuickGridView::setCellHeight(qreal cellHeight) This property determines how the view scrolling will settle following a drag or flick. The possible values are: - \list - \li GridView.NoSnap (default) - the view stops anywhere within the visible area. - \li GridView.SnapToRow - the view settles with a row (or column for \c GridView.FlowTopToBottom flow) - aligned with the start of the view. - \li GridView.SnapOneRow - the view will settle no more than one row (or column for \c GridView.FlowTopToBottom flow) - away from the first visible row at the time the mouse button is released. - This mode is particularly useful for moving one page at a time. - \endlist - + \value GridView.NoSnap (default) the view stops anywhere within the visible area. + \value GridView.SnapToRow the view settles with a row (or column for \c GridView.FlowTopToBottom flow) + aligned with the start of the view. + \value GridView.SnapOneRow the view will settle no more than one row (or column for \c GridView.FlowTopToBottom flow) + away from the first visible row at the time the mouse button is released. + This mode is particularly useful for moving one page at a time. */ QQuickGridView::SnapMode QQuickGridView::snapMode() const { @@ -2582,18 +2601,15 @@ bool QQuickGridViewPrivate::needsRefillForAddedOrRemovedIndex(int modelIndex) co Positions the view such that the \a index is at the position specified by \a mode: - \list - \li GridView.Beginning - position item at the top (or left for \c GridView.FlowTopToBottom flow) of the view. - \li GridView.Center - position item in the center of the view. - \li GridView.End - position item at bottom (or right for horizontal orientation) of the view. - \li GridView.Visible - if any part of the item is visible then take no action, otherwise - bring the item into view. - \li GridView.Contain - ensure the entire item is visible. If the item is larger than - the view the item is positioned at the top (or left for \c GridView.FlowTopToBottom flow) of the view. - \li GridView.SnapPosition - position the item at \l preferredHighlightBegin. This mode - is only valid if \l highlightRangeMode is StrictlyEnforceRange or snapping is enabled - via \l snapMode. - \endlist + \value GridView.Beginning position item at the top (or left for \c GridView.FlowTopToBottom flow) of the view. + \value GridView.Center position item in the center of the view. + \value GridView.End position item at bottom (or right for horizontal orientation) of the view. + \value GridView.Visible if any part of the item is visible then take no action, otherwise + bring the item into view. + \value GridView.Contain ensure the entire item is visible. If the item is larger than the view, the item + is positioned at the top (or left for \c GridView.FlowTopToBottom flow) of the view. + \value GridView.SnapPosition position the item at \l preferredHighlightBegin. This mode is only valid if + \l highlightRangeMode is \c StrictlyEnforceRange or snapping is enabled via \l snapMode. If positioning the view at the index would cause empty space to be displayed at the beginning or end of the view, the view will be positioned at the boundary. diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h index 8aa7f0be120..9ea621b90e8 100644 --- a/src/quick/items/qquickgridview_p.h +++ b/src/quick/items/qquickgridview_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE class QQuickGridViewAttached; class QQuickGridViewPrivate; -class Q_AUTOTEST_EXPORT QQuickGridView : public QQuickItemView +class Q_QUICK_PRIVATE_EXPORT QQuickGridView : public QQuickItemView { Q_OBJECT Q_DECLARE_PRIVATE(QQuickGridView) diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp index c9edfebf2a5..52300bebe05 100644 --- a/src/quick/items/qquickimage.cpp +++ b/src/quick/items/qquickimage.cpp @@ -151,6 +151,43 @@ QQuickImagePrivate::QQuickImagePrivate() convert foo.png \( +clone -alpha Extract \) -channel RGB -compose Multiply -composite foo_pm.png \endcode + Do not confuse container formats, such as, \c KTX, and the format of the + actual texture data stored in the container file. For example, reading a + \c KTX file is supported on all platforms, independently of what GPU driver is + used at run time. However, this does not guarantee that the compressed + texture format, used by the data in the file, is supported at run time. For + example, if the KTX file contains compressed data with the format + \c{ETC2 RGBA8}, and the 3D graphics API implementation used at run time does not + support \c ETC2 compressed textures, the Image item will not display + anything. + + \note Compressed texture format support is not under Qt's control, and it + is up to the application or device developer to ensure the compressed + texture data is provided in the appropriate format for the target + environment(s). + + Do not assume that compressed format support is specific to a platform. It + may also be specific to the driver and 3D API implementation in use on that + particular platform. In practice, implementations of different 3D graphics + APIs (e.g., Vulkan and OpenGL) on the same platform (e.g., Windows) from + the same vendor for the same hardware may offer a different set of + compressed texture formats. + + When targeting desktop environments (Windows, macOS, Linux) only, a general + recommendation is to consider using the \c{DXTn}/\c{BCn} formats since + these tend to have the widest support amongst the implementations of Direct + 3D, Vulkan, OpenGL, and Metal on these platforms. In contrast, when + targeting mobile or embedded devices, the \c ETC2 or \c ASTC formats are + likely to be a better choice since these are typically the formats + supported by the OpenGL ES implementations on such hardware. + + An application that intends to run across desktop, mobile, and embedded + hardware should plan and design its use of compressed textures carefully. + It is highly likely that relying on a single format is not going to be + sufficient, and therefore the application will likely need to branch based + on the platform to use compressed textures in a format appropriate there, + or perhaps to skip using compressed textures in some cases. + \section1 Automatic Detection of File Extension If the \l source URL indicates a non-existing local file or resource, the @@ -241,15 +278,15 @@ void QQuickImagePrivate::setPixmap(const QQuickPixmap &pixmap) Set this property to define what happens when the source image has a different size than the item. - \list - \li Image.Stretch - the image is scaled to fit - \li Image.PreserveAspectFit - the image is scaled uniformly to fit without cropping - \li Image.PreserveAspectCrop - the image is scaled uniformly to fill, cropping if necessary - \li Image.Tile - the image is duplicated horizontally and vertically - \li Image.TileVertically - the image is stretched horizontally and tiled vertically - \li Image.TileHorizontally - the image is stretched vertically and tiled horizontally - \li Image.Pad - the image is not transformed - \endlist + + \value Image.Stretch the image is scaled to fit + \value Image.PreserveAspectFit the image is scaled uniformly to fit without cropping + \value Image.PreserveAspectCrop the image is scaled uniformly to fill, cropping if necessary + \value Image.Tile the image is duplicated horizontally and vertically + \value Image.TileVertically the image is stretched horizontally and tiled vertically + \value Image.TileHorizontally the image is stretched vertically and tiled horizontally + \value Image.Pad the image is not transformed + \br \table @@ -357,9 +394,9 @@ void QQuickImage::setFillMode(FillMode mode) } /*! - \qmlproperty real QtQuick::Image::paintedWidth \qmlproperty real QtQuick::Image::paintedHeight + \readonly These properties hold the size of the image that is actually painted. In most cases it is the same as \c width and \c height, but when using an @@ -381,14 +418,14 @@ qreal QQuickImage::paintedHeight() const /*! \qmlproperty enumeration QtQuick::Image::status + \readonly This property holds the status of image loading. It can be one of: - \list - \li Image.Null - no image has been set - \li Image.Ready - the image has been loaded - \li Image.Loading - the image is currently being loaded - \li Image.Error - an error occurred while loading the image - \endlist + + \value Image.Null No image has been set + \value Image.Ready The image has been loaded + \value Image.Loading The image is currently being loaded + \value Image.Error An error occurred while loading the image Use this status to provide an update or respond to the status change in some way. For example, you could: @@ -418,6 +455,7 @@ qreal QQuickImage::paintedHeight() const /*! \qmlproperty real QtQuick::Image::progress + \readonly This property holds the progress of image loading, from 0.0 (nothing loaded) to 1.0 (finished). @@ -439,7 +477,7 @@ qreal QQuickImage::paintedHeight() const */ /*! - \qmlproperty QSize QtQuick::Image::sourceSize + \qmlproperty size QtQuick::Image::sourceSize This property holds the scaled width and height of the full-frame image. @@ -492,6 +530,8 @@ qreal QQuickImage::paintedHeight() const \note \e {Changing this property dynamically causes the image source to be reloaded, potentially even from the network, if it is not in the disk cache.} + + \sa {Pointer Handlers Example} */ /*! @@ -968,3 +1008,7 @@ void QQuickImage::setMipmap(bool use) */ QT_END_NAMESPACE + +#include "moc_qquickimage_p_p.cpp" + +#include "moc_qquickimage_p.cpp" diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp index 03de0bb5246..596cd7d63a4 100644 --- a/src/quick/items/qquickimagebase.cpp +++ b/src/quick/items/qquickimagebase.cpp @@ -51,24 +51,25 @@ QT_BEGIN_NAMESPACE +bool isScalableImageFormat(const QUrl &url) +{ + if (url.scheme() == QLatin1String("image")) + return true; + + const QString stringUrl = url.path(QUrl::PrettyDecoded); + return stringUrl.endsWith(QLatin1String("svg")) + || stringUrl.endsWith(QLatin1String("svgz")) + || stringUrl.endsWith(QLatin1String("pdf")); +} + // This function gives derived classes the chance set the devicePixelRatio // if they're not happy with our implementation of it. bool QQuickImageBasePrivate::updateDevicePixelRatio(qreal targetDevicePixelRatio) { // QQuickImageProvider and SVG and PDF can generate a high resolution image when - // sourceSize is set (this function is only called if it's set). - // If sourceSize is not set then the provider default size will be used, as usual. - bool setDevicePixelRatio = false; - if (url.scheme() == QLatin1String("image")) { - setDevicePixelRatio = true; - } else { - QString stringUrl = url.path(QUrl::PrettyDecoded); - if (stringUrl.endsWith(QLatin1String("svg")) || - stringUrl.endsWith(QLatin1String("svgz")) || - stringUrl.endsWith(QLatin1String("pdf"))) { - setDevicePixelRatio = true; - } - } + // sourceSize is set. If sourceSize is not set then the provider default size will + // be used, as usual. + const bool setDevicePixelRatio = isScalableImageFormat(url); if (setDevicePixelRatio) devicePixelRatio = targetDevicePixelRatio; @@ -326,8 +327,10 @@ void QQuickImageBase::loadPixmap(const QUrl &url, LoadPixmapOptions loadOptions) const qreal targetDevicePixelRatio = (window() ? window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio()); d->devicePixelRatio = 1.0; bool updatedDevicePixelRatio = false; - if (d->sourcesize.isValid()) + if (d->sourcesize.isValid() + || (isScalableImageFormat(d->url) && d->url.scheme() != QLatin1String("image"))) { updatedDevicePixelRatio = d->updateDevicePixelRatio(targetDevicePixelRatio); + } if (!updatedDevicePixelRatio) { // (possible) local file: loadUrl and d->devicePixelRatio will be modified if @@ -343,7 +346,8 @@ void QQuickImageBase::loadPixmap(const QUrl &url, LoadPixmapOptions loadOptions) (loadOptions & HandleDPR) ? d->sourcesize * d->devicePixelRatio : QSize(), options, (loadOptions & UseProviderOptions) ? d->providerOptions : QQuickImageProviderOptions(), - d->currentFrame, d->frameCount); + d->currentFrame, d->frameCount, + d->devicePixelRatio); if (d->pix.isLoading()) { if (d->progress != 0.0) { @@ -439,10 +443,14 @@ void QQuickImageBase::itemChange(ItemChange change, const ItemChangeData &value) Q_D(QQuickImageBase); // If the screen DPI changed, reload image. if (change == ItemDevicePixelRatioHasChanged && value.realValue != d->devicePixelRatio) { + const auto oldDpr = d->devicePixelRatio; // ### how can we get here with !qmlEngine(this)? that implies // itemChange() on an item pending deletion, which seems strange. if (qmlEngine(this) && isComponentComplete() && d->url.isValid()) { load(); + // not changed when loading (sourceSize might not be set) + if (d->devicePixelRatio == oldDpr) + d->updateDevicePixelRatio(value.realValue); } } QQuickItem::itemChange(change, value); diff --git a/src/quick/items/qquickimplicitsizeitem_p.h b/src/quick/items/qquickimplicitsizeitem_p.h index 8ae8f9f4472..41f682fe579 100644 --- a/src/quick/items/qquickimplicitsizeitem_p.h +++ b/src/quick/items/qquickimplicitsizeitem_p.h @@ -62,6 +62,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImplicitSizeItem : public QQuickItem Q_OBJECT Q_PROPERTY(qreal implicitWidth READ implicitWidth NOTIFY implicitWidthChanged) Q_PROPERTY(qreal implicitHeight READ implicitHeight NOTIFY implicitHeightChanged) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(6, 2) protected: QQuickImplicitSizeItem(QQuickImplicitSizeItemPrivate &dd, QQuickItem *parent); diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 7fe057ad706..486acfdc017 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -53,6 +53,7 @@ #include <QtGui/qpen.h> #include <QtGui/qguiapplication.h> #include <QtGui/qstylehints.h> +#include <QtGui/private/qeventpoint_p.h> #include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qpointingdevice_p.h> #include <QtGui/qinputmethod.h> @@ -60,6 +61,7 @@ #include <QtCore/private/qnumeric_p.h> #include <QtGui/qpa/qplatformtheme.h> #include <QtCore/qloggingcategory.h> +#include <QtCore/private/qduplicatetracker_p.h> #include <private/qqmlglobal_p.h> #include <private/qqmlengine_p.h> @@ -403,42 +405,42 @@ void QQuickItemKeyFilter::componentComplete() */ /*! - \qmlproperty Item QtQuick::KeyNavigation::left + \qmlattachedproperty Item QtQuick::KeyNavigation::left This property holds the item to assign focus to when the left cursor key is pressed. */ /*! - \qmlproperty Item QtQuick::KeyNavigation::right + \qmlattachedproperty Item QtQuick::KeyNavigation::right This property holds the item to assign focus to when the right cursor key is pressed. */ /*! - \qmlproperty Item QtQuick::KeyNavigation::up + \qmlattachedproperty Item QtQuick::KeyNavigation::up This property holds the item to assign focus to when the up cursor key is pressed. */ /*! - \qmlproperty Item QtQuick::KeyNavigation::down + \qmlattachedproperty Item QtQuick::KeyNavigation::down This property holds the item to assign focus to when the down cursor key is pressed. */ /*! - \qmlproperty Item QtQuick::KeyNavigation::tab + \qmlattachedproperty Item QtQuick::KeyNavigation::tab This property holds the item to assign focus to when the Tab key is pressed. */ /*! - \qmlproperty Item QtQuick::KeyNavigation::backtab + \qmlattachedproperty Item QtQuick::KeyNavigation::backtab This property holds the item to assign focus to when the Shift+Tab key combination (Backtab) is pressed. @@ -590,19 +592,17 @@ void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i) } /*! - \qmlproperty enumeration QtQuick::KeyNavigation::priority + \qmlattachedproperty enumeration QtQuick::KeyNavigation::priority This property determines whether the keys are processed before or after the attached item's own key handling. - \list - \li KeyNavigation.BeforeItem - process the key events before normal - item key processing. If the event is used for key navigation, it will be accepted and will not - be passed on to the item. - \li KeyNavigation.AfterItem (default) - process the key events after normal item key - handling. If the item accepts the key event it will not be - handled by the KeyNavigation attached property handler. - \endlist + \value KeyNavigation.BeforeItem process the key events before normal + item key processing. If the event is used for key navigation, it will be accepted and + will not be passed on to the item. + \value KeyNavigation.AfterItem (default) process the key events after normal item key + handling. If the item accepts the key event it will not be + handled by the KeyNavigation attached property handler. */ QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const { @@ -895,20 +895,17 @@ bool QQuickKeysAttached::isConnected(const char *signalName) const This property determines whether the keys are processed before or after the attached item's own key handling. - \list - \li Keys.BeforeItem (default) - process the key events before normal - item key processing. If the event is accepted it will not - be passed on to the item. - \li Keys.AfterItem - process the key events after normal item key - handling. If the item accepts the key event it will not be - handled by the Keys attached property handler. - \endlist + \value Keys.BeforeItem (default) process the key events before normal item key processing. + If the event is accepted, it will not be passed on to the item. + \value Keys.AfterItem process the key events after normal item key handling. If the item + accepts the key event, it will not be handled by the + Keys attached property handler. \sa {Key Handling Priorities} */ /*! - \qmlproperty list<Object> QtQuick::Keys::forwardTo + \qmlproperty list<Item> QtQuick::Keys::forwardTo This property provides a way to forward key presses, key releases, and keyboard input coming from input methods to other items. This can be useful when you want @@ -2351,31 +2348,22 @@ QQuickItem::~QQuickItem() while (!d->childItems.isEmpty()) d->childItems.constFirst()->setParentItem(nullptr); - if (!d->changeListeners.isEmpty()) { - const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); - if (anchor) - anchor->clearItem(this); - } - - /* + d->notifyChangeListeners(QQuickItemPrivate::AllChanges, [this](const QQuickItemPrivate::ChangeListener &change){ + QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); + if (anchor) + anchor->clearItem(this); + }); + /* update item anchors that depended on us unless they are our child (and will also be destroyed), or our sibling, and our parent is also being destroyed. */ - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); - if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this) - anchor->update(); - } - - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Destroyed) - change.listener->itemDestroyed(this); - } - - d->changeListeners.clear(); - } + d->notifyChangeListeners(QQuickItemPrivate::AllChanges, [this](const QQuickItemPrivate::ChangeListener &change){ + QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); + if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this) + anchor->update(); + }); + d->notifyChangeListeners(QQuickItemPrivate::Destroyed, &QQuickItemChangeListener::itemDestroyed, this); + d->changeListeners.clear(); /* Remove any references our transforms have to us, in case they try to @@ -2411,7 +2399,7 @@ bool QQuickItemPrivate::canAcceptTabFocus(QQuickItem *item) return true; #if QT_CONFIG(accessibility) - QAccessible::Role role = QQuickItemPrivate::get(item)->accessibleRole(); + QAccessible::Role role = QQuickItemPrivate::get(item)->effectiveAccessibleRole(); if (role == QAccessible::EditableText || role == QAccessible::Table || role == QAccessible::List) { return true; } else if (role == QAccessible::ComboBox || role == QAccessible::SpinBox) { @@ -2539,6 +2527,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo QQuickItem *current = item; qCDebug(lcFocus) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: startItem:" << startItem; qCDebug(lcFocus) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: firstFromItem:" << firstFromItem; + QDuplicateTracker<QQuickItem *> cycleDetector; do { qCDebug(lcFocus) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: current:" << current; qCDebug(lcFocus) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: from:" << from; @@ -2605,7 +2594,10 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo // traversed all of the chain (by compare the [current] item with [startItem]) // Since the [startItem] might be promoted to its parent if it is invisible, // we still have to check [current] item with original start item - if ((current == startItem || current == originalStartItem) && from == firstFromItem) { + // We might also run into a cycle before we reach firstFromItem again + // but note that we have to ignore current if we are meant to skip it + if (((current == startItem || current == originalStartItem) && from == firstFromItem) || + (!skip && cycleDetector.hasSeen(current))) { // wrapped around, avoid endless loops if (item == contentItem) { qCDebug(lcFocus) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem"; @@ -3177,8 +3169,8 @@ QQuickItemPrivate::QQuickItemPrivate() : _anchors(nullptr) , _stateGroup(nullptr) , flags(0) - , widthValid(false) - , heightValid(false) + , widthValidFlag(false) + , heightValidFlag(false) , componentComplete(true) , keepMouse(false) , keepTouch(false) @@ -3658,14 +3650,7 @@ QQuickAnchors *QQuickItemPrivate::anchors() const void QQuickItemPrivate::siblingOrderChanged() { Q_Q(QQuickItem); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::SiblingOrder) { - change.listener->itemSiblingOrderChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::SiblingOrder, &QQuickItemChangeListener::itemSiblingOrderChanged, q); } QQmlListProperty<QObject> QQuickItemPrivate::data() @@ -3733,6 +3718,9 @@ QList<QQuickItem *> QQuickItem::childItems() const If clipping is enabled, an item will clip its own painting, as well as the painting of its children, to its bounding rectangle. + + \note Clipping can affect rendering performance. See \l {Clipping} for more + information. */ /*! \property QQuickItem::clip @@ -3783,15 +3771,10 @@ void QQuickItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeom change.setWidthChange(newGeometry.width() != oldGeometry.width()); change.setHeightChange(newGeometry.height() != oldGeometry.height()); - if (!d->changeListeners.isEmpty()) { - const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &listener : listeners) { - if (listener.types & QQuickItemPrivate::Geometry) { - if (change.matches(listener.gTypes)) - listener.listener->itemGeometryChanged(this, change, oldGeometry); - } - } - } + d->notifyChangeListeners(QQuickItemPrivate::Geometry, [&](const QQuickItemPrivate::ChangeListener &listener){ + if (change.matches(listener.gTypes)) + listener.listener->itemGeometryChanged(this, change, oldGeometry); + }); // The notify method takes care of emitting the signal, and also notifies any // property observers. @@ -4419,16 +4402,11 @@ void QQuickItem::setBaselineOffset(qreal offset) d->baselineOffset = offset; - if (!d->changeListeners.isEmpty()) { - const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Geometry) { - QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); - if (anchor) - anchor->updateVerticalAnchors(); - } - } - } + d->notifyChangeListeners(QQuickItemPrivate::Geometry, [](const QQuickItemPrivate::ChangeListener &change){ + QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate(); + if (anchor) + anchor->updateVerticalAnchors(); + }); if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor)) QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors(); @@ -4564,10 +4542,10 @@ static bool unwrapMapFromToFromItemArgs(QQmlV4Function *args, const QQuickItem * } /*! - \qmlmethod object QtQuick::Item::mapFromItem(Item item, real x, real y) - \qmlmethod object QtQuick::Item::mapFromItem(Item item, point p) - \qmlmethod object QtQuick::Item::mapFromItem(Item item, real x, real y, real width, real height) - \qmlmethod object QtQuick::Item::mapFromItem(Item item, rect r) + \qmlmethod point QtQuick::Item::mapFromItem(Item item, real x, real y) + \qmlmethod point QtQuick::Item::mapFromItem(Item item, point p) + \qmlmethod rect QtQuick::Item::mapFromItem(Item item, real x, real y, real width, real height) + \qmlmethod rect QtQuick::Item::mapFromItem(Item item, rect r) Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a item's coordinate system, to this item's coordinate system, and returns a \l point or \l rect @@ -4619,10 +4597,10 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const } /*! - \qmlmethod object QtQuick::Item::mapToItem(Item item, real x, real y) - \qmlmethod object QtQuick::Item::mapToItem(Item item, point p) - \qmlmethod object QtQuick::Item::mapToItem(Item item, real x, real y, real width, real height) - \qmlmethod object QtQuick::Item::mapToItem(Item item, rect r) + \qmlmethod point QtQuick::Item::mapToItem(Item item, real x, real y) + \qmlmethod point QtQuick::Item::mapToItem(Item item, point p) + \qmlmethod rect QtQuick::Item::mapToItem(Item item, real x, real y, real width, real height) + \qmlmethod rect QtQuick::Item::mapToItem(Item item, rect r) Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this item's coordinate system, to \a item's coordinate system, and returns a \l point or \l rect @@ -4704,7 +4682,7 @@ static bool unwrapMapFromToFromGlobalArgs(QQmlV4Function *args, const QQuickItem /*! \since 5.7 - \qmlmethod object QtQuick::Item::mapFromGlobal(real x, real y) + \qmlmethod point QtQuick::Item::mapFromGlobal(real x, real y) Maps the point (\a x, \a y), which is in the global coordinate system, to the item's coordinate system, and returns a \l point matching the mapped coordinate. @@ -4731,7 +4709,7 @@ void QQuickItem::mapFromGlobal(QQmlV4Function *args) const /*! \since 5.7 - \qmlmethod object QtQuick::Item::mapToGlobal(real x, real y) + \qmlmethod point QtQuick::Item::mapToGlobal(real x, real y) Maps the point (\a x, \a y), which is in this item's coordinate system, to the global coordinate system, and returns a \l point matching the mapped coordinate. @@ -4879,10 +4857,7 @@ QQuickItem *QQuickItem::childAt(qreal x, qreal y) const QQuickItem *child = children.at(i); // Map coordinates to the child element's coordinate space QPointF point = mapToItem(child, QPointF(x, y)); - if (child->isVisible() && point.x() >= 0 - && child->width() > point.x() - && point.y() >= 0 - && child->height() > point.y()) + if (child->isVisible() && child->contains(point)) return child; } return nullptr; @@ -6427,26 +6402,12 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt switch (change) { case QQuickItem::ItemChildAddedChange: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Children) { - change.listener->itemChildAdded(q, data.item); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Children, &QQuickItemChangeListener::itemChildAdded, q, data.item); break; } case QQuickItem::ItemChildRemovedChange: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Children) { - change.listener->itemChildRemoved(q, data.item); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Children, &QQuickItemChangeListener::itemChildRemoved, q, data.item); break; } case QQuickItem::ItemSceneChange: @@ -6454,50 +6415,22 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt break; case QQuickItem::ItemVisibleHasChanged: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Visibility) { - change.listener->itemVisibilityChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Visibility, &QQuickItemChangeListener::itemVisibilityChanged, q); break; } case QQuickItem::ItemEnabledHasChanged: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Enabled) { - change.listener->itemEnabledChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Enabled, &QQuickItemChangeListener::itemEnabledChanged, q); break; } case QQuickItem::ItemParentHasChanged: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Parent) { - change.listener->itemParentChanged(q, data.item); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Parent, &QQuickItemChangeListener::itemParentChanged, q, data.item); break; } case QQuickItem::ItemOpacityHasChanged: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Opacity) { - change.listener->itemOpacityChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Opacity, &QQuickItemChangeListener::itemOpacityChanged, q); break; } case QQuickItem::ItemActiveFocusHasChanged: @@ -6505,14 +6438,7 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt break; case QQuickItem::ItemRotationHasChanged: { q->itemChange(change, data); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::Rotation) { - change.listener->itemRotationChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::Rotation, &QQuickItemChangeListener::itemRotationChanged, q); break; } case QQuickItem::ItemAntialiasingHasChanged: @@ -6790,16 +6716,17 @@ void QQuickItem::setX(qreal v) d->x.removeBindingUnlessInWrapper(); if (qt_is_nan(v)) return; - if (d->x == v) + + const qreal oldx = d->x; + if (oldx == v) return; - qreal oldx = d->x; d->x = v; d->dirty(QQuickItemPrivate::Position); - geometryChange(QRectF(v, d->y, d->width, d->height), - QRectF(oldx, d->y, d->width, d->height)); + const qreal y = d->y, w = d->width, h = d->height; + geometryChange(QRectF(v, y, w, h), QRectF(oldx, y, w, h)); } void QQuickItem::setY(qreal v) @@ -6808,18 +6735,19 @@ void QQuickItem::setY(qreal v) d->y.removeBindingUnlessInWrapper(); if (qt_is_nan(v)) return; - if (d->y == v) + + const qreal oldy = d->y; + if (oldy == v) return; - qreal oldy = d->y; d->y = v; d->dirty(QQuickItemPrivate::Position); // we use v instead of d->y, as that avoid a method call // and we have v anyway in scope - geometryChange(QRectF(d->x, v, d->width, d->height), - QRectF(d->x, oldy, d->width, d->height)); + const qreal x = d->x, w = d->width, h = d->height; + geometryChange(QRectF(x, v, w, h), QRectF(x, oldy, w, h)); } /*! @@ -6831,8 +6759,8 @@ void QQuickItem::setPosition(const QPointF &pos) if (QPointF(d->x, d->y) == pos) return; - qreal oldx = d->x; - qreal oldy = d->y; + const qreal oldx = d->x; + const qreal oldy = d->y; /* This preserves the bindings, because that was what the code used to do The effect of this is that you can have @@ -6852,8 +6780,8 @@ void QQuickItem::setPosition(const QPointF &pos) d->dirty(QQuickItemPrivate::Position); - geometryChange(QRectF(d->x, d->y, d->width, d->height), - QRectF(oldx, oldy, d->width, d->height)); + const qreal w = d->width, h = d->height; + geometryChange(QRectF(pos.x(), pos.y(), w, h), QRectF(oldx, oldy, w, h)); } /* The bindable methods return an object which supports inspection (hasBinding) and @@ -6887,38 +6815,31 @@ void QQuickItem::setWidth(qreal w) if (qt_is_nan(w)) return; - d->widthValid = true; - if (d->width == w) + d->widthValidFlag = true; + const qreal oldWidth = d->width; + if (oldWidth == w) return; - qreal oldWidth = d->width; d->width = w; d->dirty(QQuickItemPrivate::Size); - geometryChange(QRectF(d->x, d->y, w, d->height), - QRectF(d->x, d->y, oldWidth, d->height)); + const qreal x = d->x, y = d->y, h = d->height; + geometryChange(QRectF(x, y, w, h), QRectF(x, y, oldWidth, h)); } void QQuickItem::resetWidth() { Q_D(QQuickItem); d->width.takeBinding(); - d->widthValid = false; + d->widthValidFlag = false; setImplicitWidth(implicitWidth()); } void QQuickItemPrivate::implicitWidthChanged() { Q_Q(QQuickItem); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::ImplicitWidth) { - change.listener->itemImplicitWidthChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::ImplicitWidth, &QQuickItemChangeListener::itemImplicitWidthChanged, q); emit q->implicitWidthChanged(); } @@ -6944,7 +6865,14 @@ QBindable<qreal> QQuickItem::bindableWidth() \qmlproperty real QtQuick::Item::implicitWidth \qmlproperty real QtQuick::Item::implicitHeight - Defines the natural width or height of the Item if no \l width or \l height is specified. + Defines the preferred width or height of the Item. + + If \l width or \l height is not specified, an item's effective size will be + determined by its \l implicitWidth or \l implicitHeight. + + However, if an item is the child of a \l {Qt Quick Layouts}{layout}, the + layout will determine the item's preferred size using its implicit size. + In such a scenario, the explicit \l width or \l height will be ignored. The default implicit size for most items is 0x0, however some items have an inherent implicit size which cannot be overridden, for example, \l [QML] Image and \l [QML] Text. @@ -6978,7 +6906,14 @@ QBindable<qreal> QQuickItem::bindableWidth() \property QQuickItem::implicitWidth \property QQuickItem::implicitHeight - Defines the natural width or height of the Item if no \l width or \l height is specified. + Defines the preferred width or height of the Item. + + If \l width or \l height is not specified, an item's effective size will be + determined by its \l implicitWidth or \l implicitHeight. + + However, if an item is the child of a \l {Qt Quick Layouts}{layout}, the + layout will determine the item's preferred size using its implicit size. + In such a scenario, the explicit \l width or \l height will be ignored. The default implicit size for most items is 0x0, however some items have an inherent implicit size which cannot be overridden, for example, \l [QML] Image and \l [QML] Text. @@ -7022,18 +6957,18 @@ void QQuickItem::setImplicitWidth(qreal w) changed = false; } - qreal oldWidth = d->width.valueBypassingBindings(); - Q_ASSERT(!d->width.hasBinding()); - d->width = w; + const qreal oldWidth = d->width.valueBypassingBindings(); + Q_ASSERT(!d->width.hasBinding() || QQmlPropertyBinding::isUndefined(d->width.binding())); + // we need to keep the binding if its undefined (therefore we can't use operator=/setValue) + d->width.setValueBypassingBindings(w); d->dirty(QQuickItemPrivate::Size); - qreal x = d->x.valueBypassingBindings(); - qreal y = d->y.valueBypassingBindings(); - qreal width = w; - qreal height = d->height.valueBypassingBindings(); - geometryChange(QRectF(x, y, width, height), - QRectF(x, y, oldWidth, height)); + const qreal x = d->x.valueBypassingBindings(); + const qreal y = d->y.valueBypassingBindings(); + const qreal width = w; + const qreal height = d->height.valueBypassingBindings(); + geometryChange(QRectF(x, y, width, height), QRectF(x, y, oldWidth, height)); if (changed) d->implicitWidthChanged(); @@ -7062,7 +6997,7 @@ bool QQuickItem::widthValid() const See QQmlPropertyBinding::isUndefined and handleUndefinedAssignment */ - return d->widthValid || d->width.hasBinding(); + return d->widthValid(); } /*! @@ -7086,17 +7021,17 @@ void QQuickItem::setHeight(qreal h) if (qt_is_nan(h)) return; - d->heightValid = true; - if (d->height == h) + d->heightValidFlag = true; + const qreal oldHeight = d->height; + if (oldHeight == h) return; - qreal oldHeight = d->height; d->height = h; d->dirty(QQuickItemPrivate::Size); - geometryChange(QRectF(d->x, d->y, d->width, h), - QRectF(d->x, d->y, d->width, oldHeight)); + const qreal x = d->x, y = d->y, w = d->width; + geometryChange(QRectF(x, y, w, h), QRectF(x, y, w, oldHeight)); } void QQuickItem::resetHeight() @@ -7106,21 +7041,14 @@ void QQuickItem::resetHeight() // property, but preserve the existing value (and avoid some overhead // compared to calling setHeight(height()) d->height.takeBinding(); - d->heightValid = false; + d->heightValidFlag = false; setImplicitHeight(implicitHeight()); } void QQuickItemPrivate::implicitHeightChanged() { Q_Q(QQuickItem); - if (!changeListeners.isEmpty()) { - const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) - for (const QQuickItemPrivate::ChangeListener &change : listeners) { - if (change.types & QQuickItemPrivate::ImplicitHeight) { - change.listener->itemImplicitHeightChanged(q); - } - } - } + notifyChangeListeners(QQuickItemPrivate::ImplicitHeight, &QQuickItemChangeListener::itemImplicitHeightChanged, q); emit q->implicitHeightChanged(); } @@ -7153,16 +7081,17 @@ void QQuickItem::setImplicitHeight(qreal h) changed = false; } - qreal oldHeight = d->height.valueBypassingBindings(); - Q_ASSERT(!d->height.hasBinding()); - d->height = h; + const qreal oldHeight = d->height.valueBypassingBindings(); + Q_ASSERT(!d->height.hasBinding() || QQmlPropertyBinding::isUndefined(d->height.binding())); + // we need to keep the binding if its undefined (therefore we can't use operator=/setValue) + d->height.setValueBypassingBindings(h); d->dirty(QQuickItemPrivate::Size); - qreal x = d->x.valueBypassingBindings(); - qreal y = d->y.valueBypassingBindings(); - qreal width = d->width.valueBypassingBindings(); - qreal height = d->height.valueBypassingBindings(); + const qreal x = d->x.valueBypassingBindings(); + const qreal y = d->y.valueBypassingBindings(); + const qreal width = d->width.valueBypassingBindings(); + const qreal height = d->height.valueBypassingBindings(); geometryChange(QRectF(x, y, width, height), QRectF(x, y, width, oldHeight)); @@ -7201,8 +7130,8 @@ void QQuickItem::setImplicitSize(qreal w, qreal h) if (wDone && hDone) return; - qreal oldWidth = width; - qreal oldHeight = height; + const qreal oldWidth = width; + const qreal oldHeight = height; if (!wDone) { width = w; d->width = w; @@ -7214,8 +7143,8 @@ void QQuickItem::setImplicitSize(qreal w, qreal h) d->dirty(QQuickItemPrivate::Size); - qreal x = d->x.valueBypassingBindings(); - qreal y = d->y.valueBypassingBindings(); + const qreal x = d->x.valueBypassingBindings(); + const qreal y = d->y.valueBypassingBindings(); geometryChange(QRectF(x, y, width, height), QRectF(x, y, oldWidth, oldHeight)); @@ -7231,7 +7160,7 @@ void QQuickItem::setImplicitSize(qreal w, qreal h) bool QQuickItem::heightValid() const { Q_D(const QQuickItem); - return d->heightValid || d->height.hasBinding(); + return d->heightValid(); } /*! @@ -7262,21 +7191,21 @@ QSizeF QQuickItem::size() const void QQuickItem::setSize(const QSizeF &size) { Q_D(QQuickItem); - d->heightValid = true; - d->widthValid = true; + d->heightValidFlag = true; + d->widthValidFlag = true; if (d->width == size.width() && d->height == size.height()) return; - qreal oldHeight = d->height; - qreal oldWidth = d->width; + const qreal oldHeight = d->height; + const qreal oldWidth = d->width; d->height.setValueBypassingBindings(size.height()); d->width.setValueBypassingBindings(size.width()); d->dirty(QQuickItemPrivate::Size); - geometryChange(QRectF(d->x, d->y, d->width, d->height), - QRectF(d->x, d->y, oldWidth, oldHeight)); + const qreal x = d->x, y = d->y; + geometryChange(QRectF(x, y, size.width(), size.height()), QRectF(x, y, oldWidth, oldHeight)); } /*! @@ -7457,20 +7386,19 @@ void QQuickItem::setFocus(bool focus, Qt::FocusReason reason) if (d->focus == focus) return; + bool notifyListeners = false; if (d->window || d->parentItem) { // Need to find our nearest focus scope QQuickItem *scope = parentItem(); while (scope && !scope->isFocusScope() && scope->parentItem()) scope = scope->parentItem(); if (d->window) { - if (reason != Qt::PopupFocusReason) { - auto da = d->deliveryAgentPrivate(); - Q_ASSERT(da); - if (focus) - da->setFocusInScope(scope, this, reason); - else - da->clearFocusInScope(scope, this, reason); - } + auto da = d->deliveryAgentPrivate(); + Q_ASSERT(da); + if (focus) + da->setFocusInScope(scope, this, reason); + else + da->clearFocusInScope(scope, this, reason); } else { // do the focus changes from setFocusInScope/clearFocusInScope that are // unrelated to a window @@ -7488,9 +7416,10 @@ void QQuickItem::setFocus(bool focus, Qt::FocusReason reason) d->focus = focus; changed << this; + notifyListeners = true; emit focusChanged(focus); - QQuickDeliveryAgentPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1); + QQuickDeliveryAgentPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1, reason); } } else { QVarLengthArray<QQuickItem *, 20> changed; @@ -7503,10 +7432,13 @@ void QQuickItem::setFocus(bool focus, Qt::FocusReason reason) d->focus = focus; changed << this; + notifyListeners = true; emit focusChanged(focus); - QQuickDeliveryAgentPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1); + QQuickDeliveryAgentPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1, reason); } + if (notifyListeners) + d->notifyChangeListeners(QQuickItemPrivate::Focus, &QQuickItemChangeListener::itemFocusChanged, this, reason); } /*! @@ -7636,7 +7568,7 @@ bool QQuickItem::isUnderMouse() const return false; QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition; - return contains(mapFromScene(d->window->mapFromGlobal(cursorPos.toPoint()))); + return contains(mapFromScene(d->window->mapFromGlobal(cursorPos))); } /*! @@ -7803,7 +7735,7 @@ void QQuickItem::setCursor(const QCursor &cursor) if (d->window) { QWindow *renderWindow = QQuickRenderControl::renderWindowFor(d->window); QWindow *window = renderWindow ? renderWindow : d->window; - QPointF pos = window->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition.toPoint()); + QPointF pos = window->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition); if (contains(mapFromScene(pos))) updateCursorPos = pos; } @@ -7832,7 +7764,7 @@ void QQuickItem::unsetCursor() if (d->window) { QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(d->window); if (windowPrivate->cursorItem == this) { - QPointF pos = d->window->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition.toPoint()); + QPointF pos = d->window->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition); windowPrivate->updateCursor(pos); } } @@ -8066,7 +7998,7 @@ void QQuickItem::setKeepTouchGrab(bool keep) Returns \c true if this item contains \a point, which is in local coordinates; returns \c false otherwise. This is the same check that is used for hit-testing a QEventPoint during event delivery, and is affected by - containmentMask() if it is set. + \l containmentMask if it is set. */ /*! Returns \c true if this item contains \a point, which is in local coordinates; @@ -8074,7 +8006,7 @@ void QQuickItem::setKeepTouchGrab(bool keep) This function can be overridden in order to handle point collisions in items with custom shapes. The default implementation checks whether the point is inside - containmentMask() if it is set, or inside the bounding box otherwise. + \l containmentMask() if it is set, or inside the bounding box otherwise. \note This method is used for hit-testing each QEventPoint during event delivery, so the implementation should be kept as lightweight as possible. @@ -8083,39 +8015,84 @@ bool QQuickItem::contains(const QPointF &point) const { Q_D(const QQuickItem); if (d->mask) { + if (d->quickMask) + return d->quickMask->contains(point - d->quickMask->position()); + bool res = false; d->extra->maskContains.invoke(d->mask, Qt::DirectConnection, Q_RETURN_ARG(bool, res), Q_ARG(QPointF, point)); return res; - } else { - qreal x = point.x(); - qreal y = point.y(); - return x >= 0 && y >= 0 && x <= d->width && y <= d->height; } + + qreal x = point.x(); + qreal y = point.y(); + return x >= 0 && y >= 0 && x < d->width && y < d->height; } /*! \qmlproperty QObject* QtQuick::Item::containmentMask \since 5.11 This property holds an optional mask for the Item to be used in the - QtQuick::Item::contains method. - QtQuick::Item::contains main use is currently to determine whether - an input event has landed into the item or not. + \l contains() method. Its main use is currently to determine + whether a \l {QPointerEvent}{pointer event} has landed into the item or not. - By default the \l contains method will return true for any point - within the Item's bounding box. \c containmentMask allows for a - more fine-grained control. For example, the developer could - define and use an AnotherItem element as containmentMask, - which has a specialized contains method, like: + By default the \c contains() method will return true for any point + within the Item's bounding box. \c containmentMask allows for + more fine-grained control. For example, if a custom C++ + QQuickItem subclass with a specialized contains() method + is used as containmentMask: \code Item { id: item; containmentMask: AnotherItem { id: anotherItem } } \endcode - \e{item}'s contains method would then return true only if - \e{anotherItem}'s contains implementation returns true. + \e{item}'s contains method would then return \c true only if + \e{anotherItem}'s contains() implementation returns \c true. + + A \l Shape can be used as a mask, to make an item react to + \l {QPointerEvent}{pointer events} only within a non-rectangular region: + + \table + \row + \li \image containmentMask-shape.gif + \li \snippet qml/item/containmentMask-shape.qml 0 + \endtable + + It is also possible to define the contains method in QML. For example, + to create a circular item that only responds to events within its + actual bounds: + + \table + \row + \li \image containmentMask-circle.gif + \li \snippet qml/item/containmentMask-circle-js.qml 0 + \endtable + + \sa {Qt Quick Examples - Shapes} +*/ +/*! + \property QQuickItem::containmentMask + \since 5.11 + This property holds an optional mask to be used in the contains() method, + which is mainly used for hit-testing each \l QPointerEvent. + + By default, \l contains() will return \c true for any point + within the Item's bounding box. But any QQuickItem, or any QObject + that implements a function of the form + \code + Q_INVOKABLE bool contains(const QPointF &point) const; + \endcode + can be used as a mask, to defer hit-testing to that object. + + \note contains() is called frequently during event delivery. + Deferring hit-testing to another object slows it down somewhat. + containmentMask() can cause performance problems if that object's + contains() method is not efficient. If you implement a custom + QQuickItem subclass, you can alternatively override contains(). + + \sa contains() */ QObject *QQuickItem::containmentMask() const { @@ -8146,6 +8123,7 @@ void QQuickItem::setContainmentMask(QObject *mask) } d->mask = mask; quickMask = qobject_cast<QQuickItem *>(mask); + d->quickMask = quickMask; if (quickMask) { QQuickItemPrivate *maskPrivate = QQuickItemPrivate::get(quickMask); maskPrivate->registerAsContainmentMask(this, true); // telling maskPrivate that "this" is using it as mask @@ -8502,6 +8480,14 @@ bool QQuickItem::event(QEvent *ev) break; #endif // gestures case QEvent::LanguageChange: + case QEvent::LocaleChange: + for (QQuickItem *item : d->childItems) + QCoreApplication::sendEvent(item, ev); + break; + case QEvent::WindowActivate: + case QEvent::WindowDeactivate: + if (d->providesPalette()) + d->setCurrentColorGroup(); for (QQuickItem *item : d->childItems) QCoreApplication::sendEvent(item, ev); break; @@ -8617,7 +8603,7 @@ QSGTextureProvider *QQuickItem::textureProvider() const } \endcode - \sa Window::palette, Popup::palette, ColorGroup, Palette + \sa Window::palette, Popup::palette, ColorGroup, Palette, SystemPalette */ /*! @@ -9008,11 +8994,12 @@ void QQuickItemLayer::setMipmap(bool mipmap) specified. Depending on the OpenGL implementation, this property might allow you to save some texture memory. - \list - \li ShaderEffectSource.Alpha - GL_ALPHA; - \li ShaderEffectSource.RGB - GL_RGB - \li ShaderEffectSource.RGBA - GL_RGBA - \endlist + \value ShaderEffectSource.RGBA8 GL_ALPHA + \value ShaderEffectSource.RGBA16F GL_RGB + \value ShaderEffectSource.RGBA32F GL_RGBA + \value ShaderEffectSource.Alpha Starting with Qt 6.0, this value is not in use and has the same effect as \c RGBA8 in practice. + \value ShaderEffectSource.RGB Starting with Qt 6.0, this value is not in use and has the same effect as \c RGBA8 in practice. + \value ShaderEffectSource.RGBA Starting with Qt 6.0, this value is not in use and has the same effect as \c RGBA8 in practice. \note ShaderEffectSource.RGB and ShaderEffectSource.Alpha should be used with caution, as support for these formats in the underlying @@ -9113,12 +9100,10 @@ void QQuickItemLayer::setSize(const QSize &size) Modifying this property makes most sense when the \a layer.effect is specified. - \list - \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically - \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically - \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically - \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically - \endlist + \value ShaderEffectSource.ClampToEdge GL_CLAMP_TO_EDGE both horizontally and vertically + \value ShaderEffectSource.RepeatHorizontally GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically + \value ShaderEffectSource.RepeatVertically GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically + \value ShaderEffectSource.Repeat GL_REPEAT both horizontally and vertically \note Some OpenGL ES 2 implementations do not support the GL_REPEAT wrap mode with non-power-of-two textures. @@ -9148,11 +9133,9 @@ void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode) such as those specified by ShaderEffect. If no effect is specified for the layered item, mirroring has no effect on the UI representation of the item. - \list - \li ShaderEffectSource.NoMirroring - No mirroring - \li ShaderEffectSource.MirrorHorizontally - The generated texture is flipped along X-axis. - \li ShaderEffectSource.MirrorVertically - The generated texture is flipped along Y-axis. - \endlist + \value ShaderEffectSource.NoMirroring No mirroring + \value ShaderEffectSource.MirrorHorizontally The generated texture is flipped along X-axis. + \value ShaderEffectSource.MirrorVertically The generated texture is flipped along Y-axis. */ void QQuickItemLayer::setTextureMirroring(QQuickShaderEffectSource::TextureMirroring mirroring) @@ -9331,13 +9314,20 @@ QQuickItemPrivate::ExtraData::ExtraData() #if QT_CONFIG(accessibility) -QAccessible::Role QQuickItemPrivate::accessibleRole() const +QAccessible::Role QQuickItemPrivate::effectiveAccessibleRole() const { Q_Q(const QQuickItem); - QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, false)); - if (accessibleAttached) - return accessibleAttached->role(); + auto *attached = qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, false); + auto role = QAccessible::NoRole; + if (auto *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(attached)) + role = accessibleAttached->role(); + if (role == QAccessible::NoRole) + role = accessibleRole(); + return role; +} +QAccessible::Role QQuickItemPrivate::accessibleRole() const +{ return QAccessible::NoRole; } #endif diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index 6a3a5db921d..fcaedfb50d2 100644 --- a/src/quick/items/qquickitem.h +++ b/src/quick/items/qquickitem.h @@ -472,6 +472,7 @@ public Q_SLOTS: friend class QSGRenderer; friend class QAccessibleQuickItem; friend class QQuickAccessibleAttached; + friend class QQuickAnchorChanges; Q_DISABLE_COPY(QQuickItem) Q_DECLARE_PRIVATE(QQuickItem) }; diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index de6bb4aedd8..d4c9464fe95 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -331,6 +331,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate ImplicitWidth = 0x100, ImplicitHeight = 0x200, Enabled = 0x400, + Focus = 0x800, + AllChanges = 0xFFFFFFFF }; Q_DECLARE_FLAGS(ChangeTypes, ChangeType) @@ -358,6 +360,32 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate QQuickGeometryChange gTypes; //NOTE: not used for == }; + // call QQuickItemChangeListener PMF + template <typename Fn, typename ...Args> + void notifyChangeListeners(QQuickItemPrivate::ChangeTypes changeTypes, Fn &&function, Args &&...args) + { + if (changeListeners.isEmpty()) + return; + + const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) + for (const QQuickItemPrivate::ChangeListener &change : listeners) { + if (change.types & changeTypes) + (change.listener->*function)(args...); + } + } + // call functor + template <typename Fn> + void notifyChangeListeners(QQuickItemPrivate::ChangeTypes changeTypes, Fn &&function) { + if (changeListeners.isEmpty()) + return; + + const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732) + for (const QQuickItemPrivate::ChangeListener &change : listeners) { + if (change.types & changeTypes) + function(change); + } + } + struct ExtraData { ExtraData(); @@ -418,6 +446,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate QLazilyAllocated<ExtraData, ExtraDataTags> extra; // Contains mask QPointer<QObject> mask; + QPointer<QQuickItem> quickMask; // If the mask is an Item, inform it that it's being used as a mask (true) or is no longer being used (false) virtual void registerAsContainmentMask(QQuickItem * /* maskedItem */, bool /* set */) { } @@ -441,8 +470,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate // Bit 0 quint32 flags:5; - bool widthValid:1; - bool heightValid:1; + bool widthValidFlag:1; + bool heightValidFlag:1; bool componentComplete:1; bool keepMouse:1; bool keepTouch:1; @@ -578,6 +607,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate qreal implicitWidth; qreal implicitHeight; + bool widthValid() const { return widthValidFlag || (width.hasBinding() && !QQmlPropertyBinding::isUndefined(width.binding()) ); } + bool heightValid() const { return heightValidFlag || (height.hasBinding() && !QQmlPropertyBinding::isUndefined(height.binding()) ); } + qreal baselineOffset; QList<QQuickTransform *> transforms; @@ -595,7 +627,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate virtual void implicitHeightChanged(); #if QT_CONFIG(accessibility) + QAccessible::Role effectiveAccessibleRole() const; +private: virtual QAccessible::Role accessibleRole() const; +public: #endif void setImplicitAntialiasing(bool antialiasing); diff --git a/src/quick/items/qquickitemanimation_p.h b/src/quick/items/qquickitemanimation_p.h index ee4df1b6cab..6cc81ab116f 100644 --- a/src/quick/items/qquickitemanimation_p.h +++ b/src/quick/items/qquickitemanimation_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE class QQuickParentAnimationPrivate; -class Q_AUTOTEST_EXPORT QQuickParentAnimation : public QQuickAnimationGroup +class Q_QUICK_PRIVATE_EXPORT QQuickParentAnimation : public QQuickAnimationGroup { Q_OBJECT Q_DECLARE_PRIVATE(QQuickParentAnimation) @@ -95,7 +95,7 @@ class Q_AUTOTEST_EXPORT QQuickParentAnimation : public QQuickAnimationGroup }; class QQuickAnchorAnimationPrivate; -class Q_AUTOTEST_EXPORT QQuickAnchorAnimation : public QQuickAbstractAnimation +class Q_QUICK_PRIVATE_EXPORT QQuickAnchorAnimation : public QQuickAbstractAnimation { Q_OBJECT Q_DECLARE_PRIVATE(QQuickAnchorAnimation) @@ -133,7 +133,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorAnimation : public QQuickAbstractAnimation class QQuickItem; class QQuickPath; class QQuickPathAnimationPrivate; -class Q_AUTOTEST_EXPORT QQuickPathAnimation : public QQuickAbstractAnimation +class Q_QUICK_PRIVATE_EXPORT QQuickPathAnimation : public QQuickAbstractAnimation { Q_OBJECT Q_DECLARE_PRIVATE(QQuickPathAnimation) diff --git a/src/quick/items/qquickitemchangelistener_p.h b/src/quick/items/qquickitemchangelistener_p.h index 31d06c99838..91e2d69cc07 100644 --- a/src/quick/items/qquickitemchangelistener_p.h +++ b/src/quick/items/qquickitemchangelistener_p.h @@ -134,6 +134,7 @@ class QQuickItemChangeListener virtual void itemRotationChanged(QQuickItem *) {} virtual void itemImplicitWidthChanged(QQuickItem *) {} virtual void itemImplicitHeightChanged(QQuickItem *) {} + virtual void itemFocusChanged(QQuickItem *, Qt::FocusReason /* reason */) {} virtual QQuickAnchorsPrivate *anchorPrivate() { return nullptr; } }; diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp index 68c5f3db97e..dc5750dc0a3 100644 --- a/src/quick/items/qquickitemgrabresult.cpp +++ b/src/quick/items/qquickitemgrabresult.cpp @@ -381,17 +381,15 @@ QSharedPointer<QQuickItemGrabResult> QQuickItem::grabToImage(const QSize &target * * If the grab could not be initiated, the function returns \c false. * - * The following snippet shows how to grab an item and store the results to - * a file. + * The following snippet shows how to grab an item and store the results in + * a file: * - * \snippet qml/itemGrab.qml grab-source - * \snippet qml/itemGrab.qml grab-to-file + * \snippet qml/item/itemGrab.qml grab-to-file * * The following snippet shows how to grab an item and use the results in - * another image element. + * another image element: * - * \snippet qml/itemGrab.qml grab-image-target - * \snippet qml/itemGrab.qml grab-to-cache + * \snippet qml/item/itemGrab.qml grab-to-image * * \note This function will render the item to an offscreen surface and * copy that surface from the GPU's memory into the CPU's memory, which can diff --git a/src/quick/items/qquickitemgrabresult.h b/src/quick/items/qquickitemgrabresult.h index a055c0638b4..e800c713770 100644 --- a/src/quick/items/qquickitemgrabresult.h +++ b/src/quick/items/qquickitemgrabresult.h @@ -75,7 +75,7 @@ class Q_QUICK_EXPORT QQuickItemGrabResult : public QObject #endif #endif Q_INVOKABLE bool saveToFile(const QString &fileName) const; - Q_INVOKABLE bool saveToFile(const QUrl &fileName) const; + Q_REVISION(6, 2) Q_INVOKABLE bool saveToFile(const QUrl &fileName) const; protected: bool event(QEvent *) override; diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 5201f6fd72c..fbffde1c48b 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -125,6 +125,8 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcTransient) QT_END_NAMESPACE +#include "moc_qquickitemsmodule_p.cpp" + static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject *parent) { // When setting a parent (especially during dynamic object creation) in QML, @@ -194,4 +196,138 @@ void QQuickItemsModule::defineModule() qt_quickitems_defineModule(); } +/*! + \qmltype PointerEvent + \instantiates QPointerEvent + \inqmlmodule QtQuick + \brief QML equivalent for \l QPointerEvent. + + PointerEvent is the QML name of the QPointerEvent class. +*/ + +/*! + \qmltype PointerDevice + \instantiates QPointingDevice + \inqmlmodule QtQuick + \brief QML equivalent for \l QPointingDevice. + + PointerDevice is the QML name of the QPointingDevice class. + It has the same properties and enums as \l QPointingDevice. +*/ + +/*! + \qmlproperty enumeration PointerDevice::deviceType + + This property tells the type of device that generated a PointerEvent. + + Valid values are: + + \value PointerDevice.Unknown The device cannot be identified. + \value PointerDevice.Mouse A mouse. + \value PointerDevice.TouchScreen A touchscreen. + \value PointerDevice.TouchPad A touchpad or trackpad. + \value PointerDevice.Stylus A stylus on a graphics tablet. + \value PointerDevice.Airbrush An airbrush on a graphics tablet. + \value PointerDevice.Puck A digitizer with crosshairs, on a graphics tablet. + + \sa QInputDevice::DeviceType, PointerDeviceHandler::acceptedDevices +*/ + +/*! + \qmlproperty enumeration PointerDevice::pointerType + + This property tells what is interacting with the PointerDevice. + + There is some redundancy between this property and \l deviceType. + For example, if a touchscreen is used, then \c deviceType is + \c TouchScreen and \c pointerType is \c Finger. But on a graphics + tablet, it's often possible for both ends of the stylus to be used, + and programs need to distinguish them. + \l PointerDeviceHandler::acceptedDevices and + \l PointerDeviceHandler::acceptedPointerTypes can be used in combination + to filter the subset of events that a particular handler should react to. + + Valid values are: + + \value PointerDevice.Unknown The device cannot be identified. + \value PointerDevice.Generic A mouse or a device that emulates a mouse. + \value PointerDevice.Finger A finger on a touchscreen. + \value PointerDevice.Pen A stylus on a graphics tablet. + \value PointerDevice.Eraser An eraser on a graphics tablet. + \value PointerDevice.Cursor A digitizer with crosshairs, on a graphics tablet. + + \sa QPointingDevice::PointerType, PointerDeviceHandler::acceptedPointerTypes +*/ + +/*! + \qmlproperty int PointerDevice::maximumPoints + + This property tells the maximum number of simultaneous touch points + (fingers) that can be detected. +*/ + +/*! + \qmlproperty int PointerDevice::buttonCount + + This property tells the maximum number of on-device buttons that can be + detected. +*/ + +/*! + \qmltype pointingDeviceUniqueId + \instantiates QPointingDeviceUniqueId + \inqmlmodule QtQuick + \brief QML equivalent for \l QPointingDeviceUniqueId. + + pointingDeviceUniqueId is the QML name of the QPointingDeviceUniqueId class. +*/ + +/*! + \qmlproperty qint64 pointingDeviceUniqueId::numericId + + This property gives the numeric ID of the \l PointerDevice, if available; + otherwise it is \c -1. +*/ + +/*! + \qmlproperty pointingDeviceUniqueId PointerDevice::uniqueId + + This property may provide a unique ID for the device, if available. For + example, a graphics tablet stylus device may have a unique serial number. + + \sa eventPoint, QEventPoint::uniqueId() +*/ + +/*! + \qmlsignal PointerDevice::grabChanged(QtObject grabber, enumeration transition, PointerEvent event, eventPoint point) + + This signal is emitted when the \a grabber object gains or loses an + exclusive or passive grab of \a point during delivery of \a event. + The \a transition tells what happened, from the perspective of the + \c grabber object, which may be either an \l Item or an + \l {Qt Quick Input Handlers}{Input Handler}. + + Valid values for \a transition are: + + \value GrabExclusive + The \a grabber has taken primary responsibility for handling the \a point. + \value UngrabExclusive + The \a grabber has given up its previous exclusive grab. + \value CancelGrabExclusive + The exclusive grab of \a grabber has been taken over or cancelled. + \value GrabPassive + The \a grabber has acquired a passive grab, to monitor the \a point. + \value UngrabPassive + The \a grabber has given up its previous passive grab. + \value CancelGrabPassive + The previous passive grab has terminated abnormally. + + \note A grab transition from one object to another results in two signals, + to notify that one object has lost its grab, and to notify that there is + another grabber. In other cases, when transitioning to or from a non-grabbing + state, only one signal is emitted. + + \sa QPointerEvent::setExclusiveGrabber(), QPointerEvent::addPassiveGrabber(), QPointerEvent::removePassiveGrabber() +*/ + QT_END_NAMESPACE diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index f1336a91f6f..faa03fa9aee 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -57,8 +57,6 @@ FxViewItem::FxViewItem(QQuickItem *i, QQuickItemView *v, bool own, QQuickItemVie , view(v) , attached(attached) { - if (attached) // can be null for default components (see createComponentItem) - attached->setView(view); } QQuickItemViewChangeSet::QQuickItemViewChangeSet() @@ -290,8 +288,6 @@ void QQuickItemView::setDelegate(QQmlComponent *delegate) if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) { int oldCount = dataModel->count(); dataModel->setDelegate(delegate); - if (isComponentComplete()) - d->applyDelegateChange(); if (oldCount != dataModel->count()) emit countChanged(); } @@ -1785,7 +1781,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to) do { bufferPause.stop(); - if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) { + if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges() || currentChanges.active) { currentChanges.reset(); bufferedChanges.reset(); releaseVisibleItems(reusableFlag); @@ -1972,6 +1968,9 @@ void QQuickItemViewPrivate::layout() transitioner->resetTargetLists(); } + if (!currentItem) + updateCurrent(currentIndex); + runDelayedRemoveTransition = false; inLayout = false; } @@ -2504,12 +2503,29 @@ QQuickItem *QQuickItemViewPrivate::createComponentItem(QQmlComponent *component, item->setZ(zValue); QQml_setParent_noEvent(item, q->contentItem()); item->setParentItem(q->contentItem()); + + initializeComponentItem(item); } if (component) component->completeCreate(); return item; } +/*! + \internal + + Allows derived classes to do any initialization required for \a item + before completeCreate() is called on it. For example, any attached + properties required by the item can be set. + + This is similar to initItem(), but as that has logic specific to + delegate items, we use a separate function for non-delegates. +*/ +void QQuickItemViewPrivate::initializeComponentItem(QQuickItem *item) const +{ + Q_UNUSED(item); +} + void QQuickItemViewPrivate::updateTrackedItem() { Q_Q(QQuickItemView); diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h index 0bc2a6b7682..36c36f43e8f 100644 --- a/src/quick/items/qquickitemview_p_p.h +++ b/src/quick/items/qquickitemview_p_p.h @@ -76,7 +76,7 @@ class Q_AUTOTEST_EXPORT FxViewItem : public QQuickItemViewFxItem }; -class QQuickItemViewChangeSet +class Q_AUTOTEST_EXPORT QQuickItemViewChangeSet { public: QQuickItemViewChangeSet(); @@ -100,7 +100,7 @@ class QQuickItemViewChangeSet }; -class Q_AUTOTEST_EXPORT QQuickItemViewPrivate : public QQuickFlickablePrivate, public QQuickItemViewTransitionChangeListener, public QAnimationJobChangeListener +class Q_QUICK_AUTOTEST_EXPORT QQuickItemViewPrivate : public QQuickFlickablePrivate, public QQuickItemViewTransitionChangeListener, public QAnimationJobChangeListener { Q_DECLARE_PUBLIC(QQuickItemView) public: @@ -178,6 +178,7 @@ class Q_AUTOTEST_EXPORT QQuickItemViewPrivate : public QQuickFlickablePrivate, p QQuickItem *createHighlightItem() const; QQuickItem *createComponentItem(QQmlComponent *component, qreal zValue, bool createDefault = false) const; + virtual void initializeComponentItem(QQuickItem *) const; void updateCurrent(int modelIndex); void updateTrackedItem(); diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp index b7649c9952a..5342adaddf7 100644 --- a/src/quick/items/qquickitemviewtransition.cpp +++ b/src/quick/items/qquickitemviewtransition.cpp @@ -125,6 +125,8 @@ void QQuickItemViewTransitionJob::startTransition(QQuickItemViewTransitionableIt actions << QQuickStateAction(item->item, QLatin1String("x"), QVariant(to.x())); actions << QQuickStateAction(item->item, QLatin1String("y"), QVariant(to.y())); + actions[0].fromValue = item->itemX(); + actions[1].fromValue = item->itemY(); m_transitioner->runningJobs << this; QQuickTransitionManager::transition(actions, trans, item->item); } @@ -500,6 +502,37 @@ void QQuickItemViewTransitionableItem::startTransition(QQuickItemViewTransitione clearCurrentScheduledTransition(); } +void QQuickItemViewTransitionableItem::completeTransition(QQuickTransition *quickTransition) +{ + if (nextTransitionType == QQuickItemViewTransitioner::NoTransition) + return; + + if (!prepared) { + qWarning("QQuickViewItem::prepareTransition() not called!"); + return; + } + + if (!item) { + qWarning("No target for transition!"); + return; + } + + if (!transition || transition->m_type != nextTransitionType || transition->m_isTarget != isTransitionTarget) { + if (transition) + RETURN_IF_DELETED(transition->cancel()); + delete transition; + transition = new QQuickItemViewTransitionJob; + } + + QQuickStateOperation::ActionList actions; // not used + QList<QQmlProperty> after; // not used + QScopedPointer<QQuickTransitionInstance> instance( + quickTransition->prepare(actions, after, transition, item)); + RETURN_IF_DELETED(instance->complete()); + + clearCurrentScheduledTransition(); +} + void QQuickItemViewTransitionableItem::setNextTransition(QQuickItemViewTransitioner::TransitionType type, bool isTargetItem) { // Don't reset nextTransitionToSet - once it is set, it cannot be changed @@ -549,13 +582,15 @@ void QQuickItemViewTransitionableItem::stopTransition() { if (transition) RETURN_IF_DELETED(transition->cancel()); + delete transition; + transition = nullptr; clearCurrentScheduledTransition(); resetNextTransitionPos(); } QQuickViewTransitionAttached::QQuickViewTransitionAttached(QObject *parent) - : QObject(parent), m_item(nullptr), m_index(-1) + : QObject(parent), m_index(-1) { } /*! diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h index 43858db6889..253f3c6c708 100644 --- a/src/quick/items/qquickitemviewtransition_p.h +++ b/src/quick/items/qquickitemviewtransition_p.h @@ -157,6 +157,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickItemViewTransitionableItem bool prepareTransition(QQuickItemViewTransitioner *transitioner, int index, const QRectF &viewBounds); void startTransition(QQuickItemViewTransitioner *transitioner, int index); + void completeTransition(QQuickTransition *quickTransition); SelfDeletable m_selfDeletable; QPointF nextTransitionTo; @@ -225,7 +226,7 @@ class QQuickViewTransitionAttached : public QObject QList<int> m_targetIndexes; QList<QObject *> m_targetItems; - QQuickItem *m_item; + QPointer<QQuickItem> m_item; int m_index; }; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index b954f1b1077..9e7a8f48032 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -130,6 +130,8 @@ class QQuickListViewPrivate : public QQuickItemViewPrivate bool hasStickyHeader() const override; bool hasStickyFooter() const override; + void initializeComponentItem(QQuickItem *item) const override; + void changedVisibleIndex(int newIndex) override; void initializeCurrentItem() override; @@ -1573,6 +1575,14 @@ bool QQuickListViewPrivate::hasStickyFooter() const return footer && footerPositioning != QQuickListView::InlineFooter; } +void QQuickListViewPrivate::initializeComponentItem(QQuickItem *item) const +{ + QQuickListViewAttached *attached = static_cast<QQuickListViewAttached *>( + qmlAttachedPropertiesObject<QQuickListView>(item)); + if (attached) // can be null for default components (see createComponentItem) + attached->setView(const_cast<QQuickListView*>(q_func())); +} + void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) { @@ -1642,6 +1652,10 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte return; } + // update footer if all visible items have been removed + if (visibleItems.count() == 0) + updateFooter(); + correctFlick = false; fixupMode = moveReason == Mouse ? fixupMode : Immediate; bool strictHighlightRange = haveHighlightRange && highlightRange == QQuickListView::StrictlyEnforceRange; @@ -2199,6 +2213,10 @@ QQuickItemViewAttached *QQuickListViewPrivate::getAttachedObject(const QObject * \note While an item is in the pool, it might still be alive and respond to connected signals and bindings. + \note For an item to be pooled, it needs to be completely flicked out of the bounds + of the view, \e including the extra margins set with \l {ListView::}{cacheBuffer.} + Some items will also never be pooled or reused, such as \l currentItem. + The following example shows a delegate that animates a spinning rectangle. When it is pooled, the animation is temporarily paused: @@ -2465,15 +2483,13 @@ QQuickListView::~QQuickListView() Valid values for \c highlightRangeMode are: - \list - \li ListView.ApplyRange - the view attempts to maintain the highlight within the range. - However, the highlight can move outside of the range at the ends of the list or due - to mouse interaction. - \li ListView.StrictlyEnforceRange - the highlight never moves outside of the range. - The current item changes if a keyboard or mouse action would cause the highlight to move - outside of the range. - \li ListView.NoHighlightRange - this is the default value. - \endlist + \value ListView.ApplyRange the view attempts to maintain the highlight within the range. + However, the highlight can move outside of the range at the + ends of the list or due to mouse interaction. + \value ListView.StrictlyEnforceRange the highlight never moves outside of the range. + The current item changes if a keyboard or mouse action would + cause the highlight to move outside of the range. + \value ListView.NoHighlightRange this is the default value. */ void QQuickListView::setHighlightFollowsCurrentItem(bool autoHighlight) { @@ -2520,10 +2536,8 @@ void QQuickListView::setSpacing(qreal spacing) Possible values: - \list - \li ListView.Horizontal - Items are laid out horizontally - \li ListView.Vertical (default) - Items are laid out vertically - \endlist + \value ListView.Horizontal Items are laid out horizontally + \value ListView.Vertical (default) Items are laid out vertically \table \row @@ -2574,10 +2588,8 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation) Possible values: - \list - \li Qt.LeftToRight (default) - Items will be laid out from left to right. - \li Qt.RightToLeft - Items will be laid out from right to left. - \endlist + \value Qt.LeftToRight (default) Items will be laid out from left to right. + \value Qt.RightToLeft Items will be laid out from right to left. Setting this property has no effect if the \l orientation is Qt.Vertical. @@ -2603,10 +2615,8 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation) Possible values: - \list - \li ListView.TopToBottom (default) - Items are laid out from the top of the view down to the bottom of the view. - \li ListView.BottomToTop - Items are laid out from the bottom of the view up to the top of the view. - \endlist + \value ListView.TopToBottom (default) Items are laid out from the top of the view down to the bottom of the view. + \value ListView.BottomToTop Items are laid out from the bottom of the view up to the top of the view. Setting this property has no effect if the \l orientation is Qt.Horizontal. @@ -2714,35 +2724,35 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation) \c section.criteria holds the criteria for forming each section based on \c section.property. This value can be one of: - \list - \li ViewSection.FullString (default) - sections are created based on the - \c section.property value. - \li ViewSection.FirstCharacter - sections are created based on the first - character of the \c section.property value (for example, 'A', 'B', 'C' - sections, etc. for an address book) - \endlist + \value ViewSection.FullString (default) sections are created based on the + \c section.property value. + \value ViewSection.FirstCharacter sections are created based on the first character of + the \c section.property value (for example, + 'A', 'B', 'C' ... sections for an address book.) A case insensitive comparison is used when determining section boundaries. \c section.delegate holds the delegate component for each section. The default \l {QQuickItem::z}{stacking order} of section delegate instances - is \c 2. + is \c 2. If you declare a \c required property named "section" in it, + that property will contain the section's title. \c section.labelPositioning determines whether the current and/or next section labels stick to the start/end of the view, and whether the labels are shown inline. This value can be a combination of: - \list - \li ViewSection.InlineLabels - section labels are shown inline between - the item delegates separating sections (default). - \li ViewSection.CurrentLabelAtStart - the current section label sticks to the - start of the view as it is moved. - \li ViewSection.NextLabelAtEnd - the next section label (beyond all visible - sections) sticks to the end of the view as it is moved. \note Enabling - \c ViewSection.NextLabelAtEnd requires the view to scan ahead for the next - section, which has performance implications, especially for slower models. - \endlist + \value ViewSection.InlineLabels + (default) section labels are shown inline between the item delegates + separating sections. + \value ViewSection.CurrentLabelAtStart + the current section label sticks to the start of the view as it is moved. + \value ViewSection.NextLabelAtEnd + the next section label (beyond all visible sections) sticks to the end + of the view as it is moved. + \note Enabling \c ViewSection.NextLabelAtEnd requires the view to scan + ahead for the next section, which has performance implications, + especially for slower models. Each item in the list has attached properties named \c ListView.section, \c ListView.previousSection and \c ListView.nextSection. @@ -2893,18 +2903,14 @@ void QQuickListView::setHighlightResizeDuration(int duration) This property determines how the view scrolling will settle following a drag or flick. The possible values are: - \list - \li ListView.NoSnap (default) - the view stops anywhere within the visible area. - \li ListView.SnapToItem - the view settles with an item aligned with the start of - the view. - \li ListView.SnapOneItem - the view settles no more than one item away from the first - visible item at the time the mouse button is released. This mode is particularly - useful for moving one page at a time. When SnapOneItem is enabled, the ListView will - show a stronger affinity to neighboring items when movement occurs. For example, a - short drag that snaps back to the current item with SnapToItem might snap to a - neighboring item with SnapOneItem. - - \endlist + \value ListView.NoSnap (default) the view stops anywhere within the visible area. + \value ListView.SnapToItem the view settles with an item aligned with the start of the view. + \value ListView.SnapOneItem the view settles no more than one item away from the first + visible item at the time the mouse button is released. This mode is particularly + useful for moving one page at a time. When SnapOneItem is enabled, the ListView will + show a stronger affinity to neighboring items when movement occurs. For example, a + short drag that snaps back to the current item with SnapToItem might snap to a + neighboring item with SnapOneItem. \c snapMode does not affect the \l currentIndex. To update the \l currentIndex as the list is moved, set \l highlightRangeMode @@ -3743,8 +3749,10 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch item = createItem(it.index, QQmlIncubator::Synchronous); if (!item) return false; - if (it.removedAtIndex) + if (it.removedAtIndex) { + releaseItem(item, reusableFlag); continue; + } visibleItems.insert(index, item); if (index == 0) @@ -3827,21 +3835,17 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex /*! \qmlmethod QtQuick::ListView::positionViewAtIndex(int index, PositionMode mode) - Positions the view such that the \a index is at the position specified by - \a mode: - - \list - \li ListView.Beginning - position item at the top (or left for horizontal orientation) of the view. - \li ListView.Center - position item in the center of the view. - \li ListView.End - position item at bottom (or right for horizontal orientation) of the view. - \li ListView.Visible - if any part of the item is visible then take no action, otherwise - bring the item into view. - \li ListView.Contain - ensure the entire item is visible. If the item is larger than - the view the item is positioned at the top (or left for horizontal orientation) of the view. - \li ListView.SnapPosition - position the item at \l preferredHighlightBegin. This mode - is only valid if \l highlightRangeMode is StrictlyEnforceRange or snapping is enabled - via \l snapMode. - \endlist + Positions the view such that the \a index is at the position specified by \a mode: + + \value ListView.Beginning position item at the top (or left for horizontal orientation) of the view. + \value ListView.Center position item in the center of the view. + \value ListView.End position item at bottom (or right for horizontal orientation) of the view. + \value ListView.Visible if any part of the item is visible then take no action, otherwise + bring the item into view. + \value ListView.Contain ensure the entire item is visible. If the item is larger than the view, + the item is positioned at the top (or left for horizontal orientation) of the view. + \value ListView.SnapPosition position the item at \l preferredHighlightBegin. This mode is only valid + if \l highlightRangeMode is StrictlyEnforceRange or snapping is enabled via \l snapMode. If positioning the view at \a index would cause empty space to be displayed at the beginning or end of the view, the view will be positioned at the boundary. diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index d5a822c26fa..b1733b17919 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -197,9 +197,7 @@ qreal QQuickLoaderPrivate::getImplicitHeight() const \section2 Loader Sizing Behavior - If the source component is not an Item type, Loader does not - apply any special sizing rules. When used to load visual types, - Loader applies the following sizing rules: + When used to load visual types, Loader applies the following sizing rules: \list \li If an explicit size is not specified for the Loader, the Loader @@ -226,6 +224,8 @@ qreal QQuickLoaderPrivate::getImplicitHeight() const \li The red rectangle will be 50x50, centered in the root item. \endtable + If the source component is not an Item type, Loader does not apply any + special sizing rules. \section2 Receiving Signals from Loaded Objects @@ -650,9 +650,9 @@ void QQuickLoaderPrivate::setInitialState(QObject *obj) // does, then set the item's size now before bindings are // evaluated, otherwise we will end up resizing the item // later and triggering any affected bindings/anchors. - if (widthValid && !QQuickItemPrivate::get(item)->widthValid) + if (widthValid() && !QQuickItemPrivate::get(item)->widthValid()) item->setWidth(q->width()); - if (heightValid && !QQuickItemPrivate::get(item)->heightValid) + if (heightValid() && !QQuickItemPrivate::get(item)->heightValid()) item->setHeight(q->height()); item->setParentItem(q); } @@ -736,6 +736,9 @@ void QQuickLoaderPrivate::_q_sourceLoaded() return; } + if (!active) + return; + QQmlContext *creationContext = component->creationContext(); if (!creationContext) creationContext = qmlContext(q); itemContext = new QQmlContext(creationContext); @@ -801,7 +804,7 @@ void QQuickLoader::componentComplete() { Q_D(QQuickLoader); QQuickItem::componentComplete(); - if (active()) { + if (active() && (status() != Ready)) { if (d->loadingFromSource) d->createComponent(); d->load(); @@ -939,7 +942,7 @@ void QQuickLoaderPrivate::_q_updateSize(bool loaderGeometryChanged) } /*! - \qmlproperty object QtQuick::Loader::item + \qmlproperty QtObject QtQuick::Loader::item This property holds the top-level object that is currently loaded. Since \c {QtQuick 2.0}, Loader can load any object type. @@ -1038,9 +1041,15 @@ void QQuickLoaderPrivate::createComponent() const QQmlComponent::CompilationMode mode = asynchronous ? QQmlComponent::Asynchronous : QQmlComponent::PreferSynchronous; - QQmlContext *context = qmlContext(q); - component.setObject(new QQmlComponent( - context->engine(), context->resolvedUrl(source), mode, q), q); + if (QQmlContext *context = qmlContext(q)) { + if (QQmlEngine *engine = context->engine()) { + component.setObject(new QQmlComponent( + engine, context->resolvedUrl(source), mode, q), q); + return; + } + } + + qmlWarning(q) << "createComponent: Cannot find a QML engine."; } #include <moc_qquickloader_p.cpp> diff --git a/src/quick/items/qquickloader_p.h b/src/quick/items/qquickloader_p.h index dbe920c4f82..1d60f2845fd 100644 --- a/src/quick/items/qquickloader_p.h +++ b/src/quick/items/qquickloader_p.h @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE class QQuickLoaderPrivate; -class Q_AUTOTEST_EXPORT QQuickLoader : public QQuickImplicitSizeItem +class Q_QUICK_PRIVATE_EXPORT QQuickLoader : public QQuickImplicitSizeItem { Q_OBJECT diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index acccf762635..4977ddf44f3 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -808,7 +808,8 @@ void QQuickMouseArea::mouseReleaseEvent(QMouseEvent *event) QQuickWindow *w = window(); if (w && w->mouseGrabberItem() == this) ungrabMouse(); - setKeepMouseGrab(false); + if (!d->preventStealing) + setKeepMouseGrab(false); } } d->doubleClick = false; @@ -827,7 +828,8 @@ void QQuickMouseArea::mouseDoubleClickEvent(QMouseEvent *event) emit this->doubleClicked(&me); if (!me.isAccepted()) d->propagate(&me, QQuickMouseAreaPrivate::DoubleClick); - d->doubleClick = d->isDoubleClickConnected() || me.isAccepted(); + if (d->pressed) + d->doubleClick = d->isDoubleClickConnected() || me.isAccepted(); } QQuickItem::mouseDoubleClickEvent(event); } @@ -848,6 +850,9 @@ void QQuickMouseArea::hoverEnterEvent(QHoverEvent *event) emit mouseYChanged(&me); me.setPosition(d->lastPos); } + + // A MouseArea should not block hover events + event->ignore(); } void QQuickMouseArea::hoverMoveEvent(QHoverEvent *event) @@ -866,6 +871,9 @@ void QQuickMouseArea::hoverMoveEvent(QHoverEvent *event) me.setPosition(d->lastPos); emit positionChanged(&me); } + + // A MouseArea should not block hover events + event->ignore(); } void QQuickMouseArea::hoverLeaveEvent(QHoverEvent *event) @@ -875,6 +883,9 @@ void QQuickMouseArea::hoverLeaveEvent(QHoverEvent *event) QQuickItem::hoverLeaveEvent(event); else setHovered(false); + + // A MouseArea should not block hover events + event->ignore(); } #if QT_CONFIG(wheelevent) diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp index 642b5ca047a..d4b6e4c9632 100644 --- a/src/quick/items/qquickmultipointtoucharea.cpp +++ b/src/quick/items/qquickmultipointtoucharea.cpp @@ -40,11 +40,11 @@ #include "qquickmultipointtoucharea_p.h" #include <QtQuick/qquickwindow.h> #include <private/qsgadaptationlayer_p.h> -#include <private/qevent_p.h> #include <private/qquickitem_p.h> #include <private/qquickwindow_p.h> #include <private/qguiapplication_p.h> #include <QtGui/private/qevent_p.h> +#include <QtGui/private/qeventpoint_p.h> #include <QtGui/private/qpointingdevice_p.h> #include <QEvent> #include <QMouseEvent> @@ -570,7 +570,7 @@ void QQuickMultiPointTouchArea::grabGesture(QPointingDevice *dev) setKeepTouchGrab(true); } -void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) +void QQuickMultiPointTouchArea::updateTouchData(QEvent *event, RemapEventPoints remap) { bool ended = false; bool moved = false; @@ -578,6 +578,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) clearTouchLists(); QList<QEventPoint> touchPoints; + bool touchPointsFromEvent = false; QPointingDevice *dev = nullptr; switch (event->type()) { @@ -586,6 +587,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) case QEvent::TouchEnd: { QTouchEvent* te = static_cast<QTouchEvent*>(event); touchPoints = te->points(); + touchPointsFromEvent = true; dev = const_cast<QPointingDevice *>(te->pointingDevice()); break; } @@ -630,6 +632,8 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) } if (numTouchPoints >= _minimumTouchPoints && numTouchPoints <= _maximumTouchPoints) { for (QEventPoint &p : touchPoints) { + if (touchPointsFromEvent && remap == RemapEventPoints::ToLocal) + QMutableEventPoint::from(p).setPosition(mapFromScene(p.scenePosition())); QEventPoint::State touchPointState = p.state(); int id = p.id(); if (touchPointState & QEventPoint::State::Released) { @@ -683,7 +687,7 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) emit released(_releasedTouchPoints); if (moved) emit updated(_movedTouchPoints); - if (started) + if (started && !_pressedTouchPoints.isEmpty()) emit pressed(_pressedTouchPoints); if (ended || moved || started) emit touchUpdated(_touchPoints.values()); } @@ -728,12 +732,15 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QEventPoint *p) void QQuickMultiPointTouchArea::addTouchPoint(const QMouseEvent *e) { QQuickTouchPoint *dtp = nullptr; - for (QQuickTouchPoint *tp : qAsConst(_touchPrototypes)) + for (QQuickTouchPoint *tp : qAsConst(_touchPrototypes)) { if (!tp->inUse()) { tp->setInUse(true); dtp = tp; break; + } else if (_mouseTouchPoint == tp) { + return; // do not allow more than one touchpoint to react to the mouse (QTBUG-83662) } + } if (dtp == nullptr) dtp = new QQuickTouchPoint(false); @@ -971,12 +978,12 @@ bool QQuickMultiPointTouchArea::childMouseEventFilter(QQuickItem *receiver, QEve } if (!shouldFilter(event)) return false; - updateTouchData(event); + updateTouchData(event, RemapEventPoints::ToLocal); return _stealMouse; case QEvent::TouchEnd: { if (!shouldFilter(event)) return false; - updateTouchData(event); + updateTouchData(event, RemapEventPoints::ToLocal); ungrab(true); } break; diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h index 7b6426d3ab2..e1f2c559cee 100644 --- a/src/quick/items/qquickmultipointtoucharea_p.h +++ b/src/quick/items/qquickmultipointtoucharea_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <private/qtquickglobal_p.h> #include "qquickitem.h" #include "qevent.h" @@ -63,7 +64,7 @@ QT_BEGIN_NAMESPACE class QQuickMultiPointTouchArea; -class Q_AUTOTEST_EXPORT QQuickTouchPoint : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickTouchPoint : public QObject { Q_OBJECT Q_PROPERTY(int pointId READ pointId NOTIFY pointIdChanged) @@ -209,7 +210,7 @@ class QQuickGrabGestureEvent : public QObject QList<QObject*> _touchPoints; }; -class Q_AUTOTEST_EXPORT QQuickMultiPointTouchArea : public QQuickItem +class Q_QUICK_PRIVATE_EXPORT QQuickMultiPointTouchArea : public QQuickItem { Q_OBJECT @@ -277,7 +278,8 @@ class Q_AUTOTEST_EXPORT QQuickMultiPointTouchArea : public QQuickItem void updateTouchPoint(QQuickTouchPoint*, const QEventPoint*); void updateTouchPoint(QQuickTouchPoint *dtp, const QMouseEvent *e); - void updateTouchData(QEvent*); + enum class RemapEventPoints { No, ToLocal }; + void updateTouchData(QEvent*, RemapEventPoints remap = RemapEventPoints::No); bool sendMouseEvent(QMouseEvent *event); bool shouldFilter(QEvent *event); diff --git a/src/quick/items/qquickpainteditem.cpp b/src/quick/items/qquickpainteditem.cpp index 2cf26142c89..c24a6cbfdd3 100644 --- a/src/quick/items/qquickpainteditem.cpp +++ b/src/quick/items/qquickpainteditem.cpp @@ -83,6 +83,8 @@ class QQuickPaintedItemTextureProvider : public QSGTextureProvider \note It important to understand the performance implications such items can incur. See QQuickPaintedItem::RenderTarget and QQuickPaintedItem::renderTarget. + + \sa {Scene Graph - Painted Item}, {Writing QML Extensions with C++} */ /*! diff --git a/src/quick/items/qquickpalette.cpp b/src/quick/items/qquickpalette.cpp index a64b3094267..c2e3245011c 100644 --- a/src/quick/items/qquickpalette.cpp +++ b/src/quick/items/qquickpalette.cpp @@ -61,8 +61,8 @@ QT_BEGIN_NAMESPACE \ingroup qtquick-visual \brief The QQuickPalette class contains color groups for each QML item state. - A palette consists of three color groups: Active, Disabled, and Inactive. - Active color group is the default group, its colors are used for other groups + A palette consists of three color groups: \c active, \c disabled, and \c inactive. + The \c active color group is the default group: its colors are used for other groups if colors of these groups aren't explicitly specified. In the following example, color is applied for all color groups: @@ -104,18 +104,19 @@ QT_BEGIN_NAMESPACE \endcode It is also possible to specify colors like this: - \code - palette { - buttonText: "azure" - button: "khaki" - disabled { - buttonText: "lavender" - button: "coral" - } - } - \endcode - This approach is convenient when you need to specify a whole palette with all color groups. + \snippet qtquickcontrols-custom-palette-buttons.qml palette + + This approach is especially convenient when you need to specify a whole + palette with all color groups; but as with the other cases above, the + colors that are not specified are initialized from SystemPalette, or + potentially the \l {Styling Qt Quick Controls}{Qt Quick Controls style}, + if one is in use. + + \note Some Controls styles use some palette colors, but many styles use + independent colors. + + \sa Window::palette, Item::palette, Popup::palette, SystemPalette */ /*! @@ -334,3 +335,5 @@ bool QQuickPalette::isValidColorGroup(QPalette::ColorGroup groupTag, } QT_END_NAMESPACE + +#include "moc_qquickpalette_p.cpp" diff --git a/src/quick/items/qquickpaletteproviderprivatebase_p.h b/src/quick/items/qquickpaletteproviderprivatebase_p.h index b1b59583293..0219724e567 100644 --- a/src/quick/items/qquickpaletteproviderprivatebase_p.h +++ b/src/quick/items/qquickpaletteproviderprivatebase_p.h @@ -49,7 +49,7 @@ #include <QtQuick/private/qquickpalette_p.h> #include <QtQuick/private/qquickabstractpaletteprovider_p.h> - +#include <QtGui/qwindow.h> #include <QtQml/private/qlazilyallocated_p.h> QT_BEGIN_NAMESPACE @@ -150,6 +150,9 @@ class QQuickPaletteProviderPrivateBase : public QQuickAbstractPaletteProvider */ virtual void updateChildrenPalettes(const QPalette &parentPalette); +protected: + void setCurrentColorGroup(); + private: using PalettePtr = std::unique_ptr<QQuickPalette>; using Self = QQuickPaletteProviderPrivateBase<I, Impl>; @@ -160,7 +163,6 @@ class QQuickPaletteProviderPrivateBase : public QQuickAbstractPaletteProvider QQuickPalette *windowPalette() const; - void setCurrentColorGroup(); void connectItem(); @@ -334,9 +336,12 @@ template<class I, class Impl> void QQuickPaletteProviderPrivateBase<I, Impl>::setCurrentColorGroup() { if constexpr (!isRootWindow<I>()) { - if (paletteData()) { + if (providesPalette()) { const bool enabled = itemWithPalette()->isEnabled(); - paletteData()->setCurrentGroup(enabled ? QPalette::Active : QPalette::Disabled); + const auto window = itemWithPalette()->window(); + const bool active = window ? window->isActive() : true; + palette()->setCurrentGroup(enabled ? (active ? QPalette::Active : QPalette::Inactive) + : QPalette::Disabled); } } } diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index d862eba25b2..d86e4a46712 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -49,7 +49,8 @@ #include <private/qqmlchangeset_p.h> #include <QtQml/qqmlinfo.h> -#include <QtGui/qevent.h> + +#include <QtGui/private/qeventpoint_p.h> #include <QtGui/qevent.h> #include <QtGui/qguiapplication.h> #include <QtGui/qstylehints.h> @@ -145,7 +146,8 @@ QQuickItem *QQuickPathViewPrivate::getItem(int modelIndex, qreal z, bool async) item->setParentItem(q); requestedIndex = -1; QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - itemPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry); + itemPrivate->addItemChangeListener( + this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed); } inRequest = false; return item; @@ -198,11 +200,14 @@ void QQuickPathView::initItem(int index, QObject *object) void QQuickPathViewPrivate::releaseItem(QQuickItem *item) { - if (!item || !model) + if (!item) return; qCDebug(lcItemViewDelegateLifecycle) << "release" << item; QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - itemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Geometry); + itemPrivate->removeItemChangeListener( + this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed); + if (!model) + return; QQmlInstanceModel::ReleaseFlags flags = model->release(item); if (!flags) { // item was not destroyed, and we no longer reference it. @@ -923,18 +928,16 @@ QQuickItem *QQuickPathView::highlightItem() const Valid values for \c highlightRangeMode are: - \list - \li \e PathView.NoHighlightRange - no range is applied and the - highlight will move freely within the view. - \li \e PathView.ApplyRange - the view will attempt to maintain - the highlight within the range, however the highlight can - move outside of the range at the ends of the path or due to - a mouse interaction. - \li \e PathView.StrictlyEnforceRange - the highlight will never - move outside of the range. This means that the current item - will change if a keyboard or mouse action would cause the - highlight to move outside of the range. - \endlist + \value PathView.NoHighlightRange no range is applied: the highlight + will move freely within the view. + \value PathView.ApplyRange the view will attempt to maintain the highlight + within the range, however the highlight can move + outside of the range at the ends of the path or + due to a mouse interaction. + \value PathView.StrictlyEnforceRange the highlight will never move outside of the range. + This means that the current item will change if a + keyboard or mouse action would cause the highlight + to move outside of the range. The default value is \e PathView.StrictlyEnforceRange. @@ -1341,13 +1344,11 @@ void QQuickPathView::setCacheItemCount(int i) This property determines how the items will settle following a drag or flick. The possible values are: - \list - \li PathView.NoSnap (default) - the items stop anywhere along the path. - \li PathView.SnapToItem - the items settle with an item aligned with the \l preferredHighlightBegin. - \li PathView.SnapOneItem - the items settle no more than one item away from the item nearest + \value PathView.NoSnap (default) the items stop anywhere along the path. + \value PathView.SnapToItem the items settle with an item aligned with the \l preferredHighlightBegin. + \value PathView.SnapOneItem the items settle no more than one item away from the item nearest \l preferredHighlightBegin at the time the press is released. This mode is particularly useful for moving one page at a time. - \endlist \c snapMode does not affect the \l currentIndex. To update the \l currentIndex as the view is moved, set \l highlightRangeMode @@ -1377,12 +1378,10 @@ void QQuickPathView::setSnapMode(SnapMode mode) This property determines the direction in which items move when setting the current index. The possible values are: - \list - \li PathView.Shortest (default) - the items move in the direction that requires the least - movement, which could be either \c Negative or \c Positive. - \li PathView.Negative - the items move backwards towards their destination. - \li PathView.Positive - the items move forwards towards their destination. - \endlist + \value PathView.Shortest (default) the items move in the direction that requires the least + movement, which could be either \c Negative or \c Positive. + \value PathView.Negative the items move backwards towards their destination. + \value PathView.Positive the items move forwards towards their destination. For example, suppose that there are 5 items in the model, and \l currentIndex is \c 0. If currentIndex is set to \c 2, @@ -1418,15 +1417,13 @@ void QQuickPathView::setMovementDirection(QQuickPathView::MovementDirection dir) Positions the view such that the \a index is at the position specified by \a mode: - \list - \li PathView.Beginning - position item at the beginning of the path. - \li PathView.Center - position item in the center of the path. - \li PathView.End - position item at the end of the path. - \li PathView.Contain - ensure the item is positioned on the path. - \li PathView.SnapPosition - position the item at \l preferredHighlightBegin. This mode - is only valid if \l highlightRangeMode is StrictlyEnforceRange or snapping is enabled - via \l snapMode. - \endlist + \value PathView.Beginning position item at the beginning of the path. + \value PathView.Center position item in the center of the path. + \value PathView.End position item at the end of the path. + \value PathView.Contain ensure the item is positioned on the path. + \value PathView.SnapPosition position the item at \l preferredHighlightBegin. This mode + is only valid if \l highlightRangeMode is StrictlyEnforceRange or snapping is enabled + via \l snapMode. \b Note: methods should only be called after the Component has completed. To position the view at startup, this method should be called by Component.onCompleted. For diff --git a/src/quick/items/qquickpathview_p_p.h b/src/quick/items/qquickpathview_p_p.h index 274086ea7c8..b83cd95b951 100644 --- a/src/quick/items/qquickpathview_p_p.h +++ b/src/quick/items/qquickpathview_p_p.h @@ -88,6 +88,12 @@ class QQuickPathViewPrivate : public QQuickItemPrivate, public QQuickItemChangeL } } + void itemDestroyed(QQuickItem *item) override + { + if (!items.removeOne(item)) + itemCache.removeOne(item); + } + void scheduleLayout() { Q_Q(QQuickPathView); if (!layoutScheduled) { diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp index ed8506b4405..37458542d32 100644 --- a/src/quick/items/qquickpincharea.cpp +++ b/src/quick/items/qquickpincharea.cpp @@ -360,7 +360,7 @@ void QQuickPinchArea::touchEvent(QTouchEvent *event) void QQuickPinchArea::clearPinch(QTouchEvent *event) { Q_D(QQuickPinchArea); - qCDebug(lcPA, "clear: %lld touchpoints", d->touchPoints.count()); + qCDebug(lcPA, "clear: %" PRIdQSIZETYPE " touchpoints", d->touchPoints.count()); d->touchPoints.clear(); if (d->inPinch) { d->inPinch = false; @@ -390,12 +390,13 @@ void QQuickPinchArea::clearPinch(QTouchEvent *event) } } setKeepTouchGrab(false); + setKeepMouseGrab(false); } void QQuickPinchArea::cancelPinch(QTouchEvent *event) { Q_D(QQuickPinchArea); - qCDebug(lcPA, "cancel: %lld touchpoints", d->touchPoints.count()); + qCDebug(lcPA, "cancel: %" PRIdQSIZETYPE " touchpoints", d->touchPoints.count()); d->touchPoints.clear(); if (d->inPinch) { d->inPinch = false; @@ -431,6 +432,7 @@ void QQuickPinchArea::cancelPinch(QTouchEvent *event) event->setExclusiveGrabber(point, nullptr); } setKeepTouchGrab(false); + setKeepMouseGrab(false); } void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) @@ -440,6 +442,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) if (d->touchPoints.count() < 2) { // A pinch gesture is not occurring, so stealing the grab is permitted. setKeepTouchGrab(false); + setKeepMouseGrab(false); // During filtering, there's no need to hold a grab for one point, // because filtering happens for every event anyway. // But if we receive the event via direct delivery, and give up the grab, @@ -463,6 +466,8 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); pe.setPoint1(mapFromScene(d->lastPoint1)); pe.setPoint2(mapFromScene(d->lastPoint2)); + setKeepTouchGrab(false); + setKeepMouseGrab(false); emit pinchFinished(&pe); d->pinchStartDist = 0; d->pinchActivated = false; @@ -499,6 +504,8 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) d->initPinch = true; event->setExclusiveGrabber(touchPoint1, this); event->setExclusiveGrabber(touchPoint2, this); + setKeepTouchGrab(true); + setKeepMouseGrab(true); } if (d->pinchActivated && !d->pinchRejected) { const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); @@ -561,6 +568,9 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) event->setExclusiveGrabber(touchPoint1, this); event->setExclusiveGrabber(touchPoint2, this); setKeepTouchGrab(true); + // So that PinchArea works in PathView, grab mouse events too. + // We should be able to remove these setKeepMouseGrab calls when QTBUG-105567 is fixed. + setKeepMouseGrab(true); d->inPinch = true; if (d->pinch && d->pinch->target()) { auto targetParent = pinch()->target()->parentItem(); @@ -727,6 +737,8 @@ bool QQuickPinchArea::event(QEvent *event) clearPinch(nullptr); break; case Qt::ZoomNativeGesture: { + if (d->pinchRejected) + break; qreal scale = d->pinchLastScale * (1.0 + gesture->value()); QQuickPinchEvent pe(d->pinchStartCenter, scale, d->pinchLastAngle, 0.0); pe.setStartCenter(d->pinchStartCenter); @@ -744,7 +756,10 @@ bool QQuickPinchArea::event(QEvent *event) else emit pinchStarted(&pe); d->inPinch = true; - updatePinchTarget(); + if (pe.accepted()) + updatePinchTarget(); + else + d->pinchRejected = true; } break; case Qt::SmartZoomNativeGesture: { if (gesture->value() > 0.0 && d->pinch && d->pinch->target()) { @@ -768,6 +783,8 @@ bool QQuickPinchArea::event(QEvent *event) emit smartZoom(&pe); } break; case Qt::RotateNativeGesture: { + if (d->pinchRejected) + break; qreal angle = d->pinchLastAngle + gesture->value(); QQuickPinchEvent pe(d->pinchStartCenter, d->pinchLastScale, angle, 0.0); pe.setStartCenter(d->pinchStartCenter); @@ -786,7 +803,10 @@ bool QQuickPinchArea::event(QEvent *event) emit pinchStarted(&pe); d->inPinch = true; d->pinchRotation = angle; - updatePinchTarget(); + if (pe.accepted()) + updatePinchTarget(); + else + d->pinchRejected = true; } break; default: return QQuickItem::event(event); diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h index 124f0fe5d39..c100b800e0f 100644 --- a/src/quick/items/qquickpincharea_p.h +++ b/src/quick/items/qquickpincharea_p.h @@ -51,11 +51,13 @@ // We mean it. // +#include <private/qtquickglobal_p.h> + #include "qquickitem.h" QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQuickPinch : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickPinch : public QObject { Q_OBJECT @@ -194,7 +196,7 @@ class Q_AUTOTEST_EXPORT QQuickPinch : public QObject bool m_active; }; -class Q_AUTOTEST_EXPORT QQuickPinchEvent : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickPinchEvent : public QObject { Q_OBJECT @@ -266,7 +268,7 @@ class Q_AUTOTEST_EXPORT QQuickPinchEvent : public QObject class QQuickMouseEvent; class QQuickPinchAreaPrivate; -class Q_AUTOTEST_EXPORT QQuickPinchArea : public QQuickItem +class Q_QUICK_PRIVATE_EXPORT QQuickPinchArea : public QQuickItem { Q_OBJECT diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp index a8d050527b2..b02c696169b 100644 --- a/src/quick/items/qquickpositioners.cpp +++ b/src/quick/items/qquickpositioners.cpp @@ -1147,12 +1147,10 @@ QQuickRow::QQuickRow(QQuickItem *parent) Possible values: - \list - \li Qt.LeftToRight (default) - Items are laid out from left to right. If the width of the row is explicitly set, - the left anchor remains to the left of the row. - \li Qt.RightToLeft - Items are laid out from right to left. If the width of the row is explicitly set, - the right anchor remains to the right of the row. - \endlist + \value Qt.LeftToRight (default) Items are laid out from left to right. If the width of the row is + explicitly set, the left anchor remains to the left of the row. + \value Qt.RightToLeft Items are laid out from right to left. If the width of the row is + explicitly set, the right anchor remains to the right of the row. \sa Grid::layoutDirection, Flow::layoutDirection, {Qt Quick Examples - Right to Left} */ @@ -1697,7 +1695,7 @@ void QQuickGrid::doPositioning(QSizeF *contentSize) QQuickBasePositionerPrivate *d = static_cast<QQuickBasePositionerPrivate*>(QQuickBasePositionerPrivate::get(this)); int c = m_columns; int r = m_rows; - int numVisible = positionedItems.count(); + const int numVisible = positionedItems.count(); if (m_columns <= 0 && m_rows <= 0) { c = 4; @@ -1714,6 +1712,10 @@ void QQuickGrid::doPositioning(QSizeF *contentSize) return; //Nothing else to do } + if (numVisible > r * c) { + qmlWarning(this) << "Grid contains more visible items (" << numVisible << ") than rows*columns (" << r * c << ")"; + } + QList<qreal> maxColWidth; QList<qreal> maxRowHeight; int childIndex =0; diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h index 2c3aa674c61..1f2282a1cea 100644 --- a/src/quick/items/qquickpositioners_p.h +++ b/src/quick/items/qquickpositioners_p.h @@ -233,7 +233,7 @@ protected Q_SLOTS: Q_DECLARE_PRIVATE(QQuickBasePositioner) }; -class Q_AUTOTEST_EXPORT QQuickColumn : public QQuickBasePositioner +class Q_QUICK_PRIVATE_EXPORT QQuickColumn : public QQuickBasePositioner { Q_OBJECT QML_NAMED_ELEMENT(Column) @@ -249,7 +249,7 @@ class Q_AUTOTEST_EXPORT QQuickColumn : public QQuickBasePositioner }; class QQuickRowPrivate; -class Q_AUTOTEST_EXPORT QQuickRow: public QQuickBasePositioner +class Q_QUICK_PRIVATE_EXPORT QQuickRow: public QQuickBasePositioner { Q_OBJECT Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) @@ -277,7 +277,7 @@ class Q_AUTOTEST_EXPORT QQuickRow: public QQuickBasePositioner }; class QQuickGridPrivate; -class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner +class Q_QUICK_PRIVATE_EXPORT QQuickGrid : public QQuickBasePositioner { Q_OBJECT Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged) @@ -366,7 +366,7 @@ class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner }; class QQuickFlowPrivate; -class Q_AUTOTEST_EXPORT QQuickFlow: public QQuickBasePositioner +class Q_QUICK_PRIVATE_EXPORT QQuickFlow: public QQuickBasePositioner { Q_OBJECT Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged) diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp index ebcfe5bca19..a1063e59522 100644 --- a/src/quick/items/qquickrectangle.cpp +++ b/src/quick/items/qquickrectangle.cpp @@ -95,7 +95,7 @@ void QQuickPen::setWidth(qreal w) m_width = w; m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0)); static_cast<QQuickItem*>(parent())->update(); - emit penChanged(); + emit widthChanged(); } QColor QQuickPen::color() const @@ -108,7 +108,7 @@ void QQuickPen::setColor(const QColor &c) m_color = c; m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0)); static_cast<QQuickItem*>(parent())->update(); - emit penChanged(); + emit colorChanged(); } bool QQuickPen::pixelAligned() const @@ -123,7 +123,7 @@ void QQuickPen::setPixelAligned(bool aligned) m_aligned = aligned; m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0)); static_cast<QQuickItem*>(parent())->update(); - emit penChanged(); + emit pixelAlignedChanged(); } bool QQuickPen::isValid() const @@ -265,10 +265,9 @@ QQmlListProperty<QQuickGradientStop> QQuickGradient::stops() \since 5.12 Set this property to define the direction of the gradient. - \list - \li Gradient.Vertical - a vertical gradient - \li Gradient.Horizontal - a horizontal gradient - \endlist + + \value Gradient.Vertical a vertical gradient + \value Gradient.Horizontal a horizontal gradient The default is Gradient.Vertical. */ @@ -578,8 +577,13 @@ QSGNode *QQuickRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData if (d->pen && d->pen->isValid()) { rectangle->setPenColor(d->pen->color()); - rectangle->setPenWidth(d->pen->width()); - rectangle->setAligned(d->pen->pixelAligned()); + qreal penWidth = d->pen->width(); + if (d->pen->pixelAligned()) { + qreal dpr = window() ? window()->effectiveDevicePixelRatio() : 1.0; + penWidth = qRound(penWidth * dpr) / dpr; // Ensures integer width after dpr scaling + } + rectangle->setPenWidth(penWidth); + rectangle->setAligned(false); // width rounding already done, so the Node should not do it } else { rectangle->setPenWidth(0); } diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h index 8c0d1112415..f4e66ebeca7 100644 --- a/src/quick/items/qquickrectangle_p.h +++ b/src/quick/items/qquickrectangle_p.h @@ -63,9 +63,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPen : public QObject { Q_OBJECT - Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY penChanged) - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY penChanged) - Q_PROPERTY(bool pixelAligned READ pixelAligned WRITE setPixelAligned NOTIFY penChanged) + Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY widthChanged) + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) + Q_PROPERTY(bool pixelAligned READ pixelAligned WRITE setPixelAligned NOTIFY pixelAlignedChanged) QML_ANONYMOUS QML_ADDED_IN_VERSION(2, 0) public: @@ -83,7 +83,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPen : public QObject bool isValid() const; Q_SIGNALS: - void penChanged(); + void widthChanged(); + void colorChanged(); + void pixelAlignedChanged(); private: qreal m_width; diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index caf5a17dc60..2d48a39be85 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -84,11 +84,15 @@ QT_BEGIN_NAMESPACE possible in a hardware accelerated manner, unlike the performance-wise limited alternative of using QQuickWindow::grabWindow() - When using a QQuickRenderControl, the QQuickWindow does not have to be shown - or even created at all. This means there will not be an underlying native - window for it. Instead, the QQuickWindow instance is associated with the - render control, using the overload of the QQuickWindow constructor, and a - texture or image object specified via QQuickWindow::setRenderTarget(). + When using a QQuickRenderControl, the QQuickWindow must not be + \l{QWindow::show()}{shown} (it will not be visible on-screen) and there will + not be an underlying native window for it. Instead, the QQuickWindow instance + is associated with the render control object, using the overload of the + QQuickWindow constructor, and a texture or image object specified via + QQuickWindow::setRenderTarget(). The QQuickWindow object is still essential, + because it represents the Qt Quick scene and provides the bulk of the scene + management and event delivery mechanisms. It does not however act as a real + on-screen window from the windowing system's perspective. Management of the graphics devices, contexts, image and texture objects is up to the application. The device or context that will be used by Qt Quick must @@ -130,6 +134,12 @@ QT_BEGIN_NAMESPACE To send events, for example mouse or keyboard events, to the scene, use QCoreApplication::sendEvent() with the QQuickWindow instance as the receiver. + For key events it may be also necessary to set the focus manually on the + desired item. In practice this involves calling + \l{QQuickItem::forceActiveFocus()}{forceActiveFocus()} on the desired item, + for example the scene's root item, once it is associated with the scene (the + QQuickWindow). + \note In general QQuickRenderControl is supported in combination with all Qt Quick backends. However, some functionality, in particular grab(), may not be available in all cases. @@ -170,6 +180,14 @@ QQuickRenderControl::QQuickRenderControl(QObject *parent) { } +/*! + \internal +*/ +QQuickRenderControl::QQuickRenderControl(QQuickRenderControlPrivate &dd, QObject * parent) + : QObject(dd, parent) +{ +} + /*! Destroys the instance. Releases all scenegraph resources. @@ -204,7 +222,7 @@ void QQuickRenderControlPrivate::windowDestroyed() QQuickWindowPrivate::get(window)->animationController.reset(); #if QT_CONFIG(quick_shadereffect) - QSGRhiShaderEffectNode::cleanupMaterialTypeCache(); + QSGRhiShaderEffectNode::cleanupMaterialTypeCache(window); #endif window = nullptr; } @@ -312,6 +330,7 @@ bool QQuickRenderControl::initialize() params.initialSurfacePixelSize = d->window->size() * d->window->effectiveDevicePixelRatio(); params.maybeSurface = d->window; renderContext->initialize(¶ms); + d->initialized = true; } else { qWarning("QRhi is only compatible with default adaptation"); return false; @@ -518,7 +537,7 @@ void QQuickRenderControlPrivate::maybeUpdate() Reimplemented in subclasses to return the real window this render control is rendering into. - If \a offset in non-null, it is set to the offset of the control + If \a offset is non-null, it is set to the offset of the control inside the window. \note While not mandatory, reimplementing this function becomes essential for @@ -530,7 +549,7 @@ void QQuickRenderControlPrivate::maybeUpdate() /*! Returns the real window that \a win is being rendered to, if any. - If \a offset in non-null, it is set to the offset of the rendering + If \a offset is non-null, it is set to the offset of the rendering inside its window. */ @@ -544,6 +563,14 @@ QWindow *QQuickRenderControl::renderWindowFor(QQuickWindow *win, QPoint *offset) return nullptr; } +bool QQuickRenderControlPrivate::isRenderWindowFor(QQuickWindow *quickWin, const QWindow *renderWin) +{ + QQuickRenderControl *rc = QQuickWindowPrivate::get(quickWin)->renderControl; + if (rc) + return QQuickRenderControlPrivate::get(rc)->isRenderWindow(renderWin); + return false; +} + /*! \return the QQuickWindow this QQuickRenderControl is associated with. diff --git a/src/quick/items/qquickrendercontrol.h b/src/quick/items/qquickrendercontrol.h index 160aad73abf..3b1646c3f6e 100644 --- a/src/quick/items/qquickrendercontrol.h +++ b/src/quick/items/qquickrendercontrol.h @@ -80,6 +80,9 @@ class Q_QUICK_EXPORT QQuickRenderControl : public QObject QQuickWindow *window() const; +protected: + QQuickRenderControl(QQuickRenderControlPrivate &dd, QObject * parent); + Q_SIGNALS: void renderRequested(); void sceneChanged(); diff --git a/src/quick/items/qquickrendercontrol_p.h b/src/quick/items/qquickrendercontrol_p.h index 00d9c909d07..8349153df02 100644 --- a/src/quick/items/qquickrendercontrol_p.h +++ b/src/quick/items/qquickrendercontrol_p.h @@ -71,6 +71,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRenderControlPrivate : public QObjectPrivate return renderControl->d_func(); } + static bool isRenderWindowFor(QQuickWindow *quickWin, const QWindow *renderWin); + virtual bool isRenderWindow(const QWindow *w) { Q_UNUSED(w); return false; } + static void cleanup(); void windowDestroyed(); diff --git a/src/quick/items/qquickrepeater_p.h b/src/quick/items/qquickrepeater_p.h index 652651efb9a..b49b74757c2 100644 --- a/src/quick/items/qquickrepeater_p.h +++ b/src/quick/items/qquickrepeater_p.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE class QQmlChangeSet; class QQuickRepeaterPrivate; -class Q_AUTOTEST_EXPORT QQuickRepeater : public QQuickItem +class Q_QUICK_PRIVATE_EXPORT QQuickRepeater : public QQuickItem { Q_OBJECT diff --git a/src/quick/items/qquickscalegrid.cpp b/src/quick/items/qquickscalegrid.cpp index c2288cf220d..13b249d50fd 100644 --- a/src/quick/items/qquickscalegrid.cpp +++ b/src/quick/items/qquickscalegrid.cpp @@ -217,3 +217,5 @@ QString QQuickGridScaledImage::pixmapUrl() const } QT_END_NAMESPACE + +#include "moc_qquickscalegrid_p_p.cpp" diff --git a/src/quick/items/qquickscalegrid_p_p.h b/src/quick/items/qquickscalegrid_p_p.h index 1e3746161b7..6148b84067f 100644 --- a/src/quick/items/qquickscalegrid_p_p.h +++ b/src/quick/items/qquickscalegrid_p_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQuickScaleGrid : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickScaleGrid : public QObject { Q_OBJECT diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp index ffe8169381e..914ebd3047e 100644 --- a/src/quick/items/qquickscreen.cpp +++ b/src/quick/items/qquickscreen.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype Screen \instantiates QQuickScreenAttached - \inqmlmodule QtQuick.Window + \inqmlmodule QtQuick \ingroup qtquick-visual-utility \brief The Screen attached object provides information about the Screen an Item or Window is displayed on. @@ -75,6 +75,8 @@ QT_BEGIN_NAMESPACE Note that the Screen type is not valid at Component.onCompleted, because the Item or Window has not been displayed on a screen by this time. + + \sa {Qt Quick Examples - Window and Screen} */ /*! diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp index caabd541b66..43f9828acac 100644 --- a/src/quick/items/qquickshadereffect.cpp +++ b/src/quick/items/qquickshadereffect.cpp @@ -775,11 +775,9 @@ void QQuickShaderEffect::setMesh(const QVariant &mesh) This property defines which sides of the item should be visible. - \list - \li ShaderEffect.NoCulling - Both sides are visible - \li ShaderEffect.BackFaceCulling - only front side is visible - \li ShaderEffect.FrontFaceCulling - only back side is visible - \endlist + \value ShaderEffect.NoCulling Both sides are visible + \value ShaderEffect.BackFaceCulling only the front side is visible + \value ShaderEffect.FrontFaceCulling only the back side is visible The default is NoCulling. */ @@ -830,11 +828,9 @@ void QQuickShaderEffect::setSupportsAtlasTextures(bool supports) This property tells the current status of the shaders. - \list - \li ShaderEffect.Compiled - the shader program was successfully compiled and linked. - \li ShaderEffect.Uncompiled - the shader program has not yet been compiled. - \li ShaderEffect.Error - the shader program failed to compile or link. - \endlist + \value ShaderEffect.Compiled the shader program was successfully compiled and linked. + \value ShaderEffect.Uncompiled the shader program has not yet been compiled. + \value ShaderEffect.Error the shader program failed to compile or link. When setting the fragment or vertex shader source code, the status will become Uncompiled. The first time the ShaderEffect is rendered with new @@ -1165,6 +1161,8 @@ QSGNode *QQuickShaderEffectImpl::handleUpdatePaintNode(QSGNode *oldNode, QQuickI sd.fragment.shader = &m_shaders[Fragment]; sd.fragment.dirtyConstants = &m_dirtyConstants[Fragment]; sd.fragment.dirtyTextures = &m_dirtyTextures[Fragment]; + sd.materialTypeCacheKey = m_item->window(); + node->syncMaterial(&sd); if (m_dirty & QSGShaderEffectNode::DirtyShaderMesh) { @@ -1243,6 +1241,7 @@ bool QQuickShaderEffectImpl::updateUniformValue(const QByteArray &name, const QV sd.fragment.shader = &m_shaders[Fragment]; sd.fragment.dirtyConstants = &dirtyConstants[Fragment]; sd.fragment.dirtyTextures = {}; + sd.materialTypeCacheKey = m_item->window(); node->syncMaterial(&sd); @@ -1384,7 +1383,7 @@ bool QQuickShaderEffectImpl::updateShader(Shader shaderType, const QUrl &fileUrl // provided and monitored like with an application-provided shader. QSGGuiThreadShaderEffectManager::ShaderInfo::Variable v; v.name = QByteArrayLiteral("source"); - v.bindPoint = 0; // fake + v.bindPoint = 1; // fake, must match the default source bindPoint in qquickshadereffectnode.cpp v.type = texturesSeparate ? QSGGuiThreadShaderEffectManager::ShaderInfo::Texture : QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler; m_shaders[shaderType].shaderInfo.variables.append(v); @@ -1438,10 +1437,8 @@ void QQuickShaderEffectImpl::updateShaderVars(Shader shaderType) const int varCount = m_shaders[shaderType].shaderInfo.variables.count(); m_shaders[shaderType].varData.resize(varCount); - // Reuse signal mappers as much as possible since the mapping is based on - // the index and shader type which are both constant. - if (m_mappers[shaderType].count() < varCount) - m_mappers[shaderType].resize(varCount); + // Recreate signal mappers when the shader has changed. + clearMappers(shaderType); auto *engine = qmlEngine(m_item); QQmlPropertyCache *propCache = engine ? QQmlData::ensurePropertyCache(engine, m_item) : nullptr; @@ -1497,13 +1494,11 @@ void QQuickShaderEffectImpl::updateShaderVars(Shader shaderType) if (pd->notifyIndex() == -1) { qWarning("QQuickShaderEffect: property '%s' does not have notification method!", v.name.constData()); } else { - auto *&mapper = m_mappers[shaderType][i]; - if (!mapper) { - const int mappedId = indexToMappedId(shaderType, i); - mapper = new QtPrivate::EffectSlotMapper([this, mappedId](){ - this->propertyChanged(mappedId); - }); - } + const int mappedId = indexToMappedId(shaderType, i); + auto mapper = new QtPrivate::EffectSlotMapper([this, mappedId](){ + this->propertyChanged(mappedId); + }); + m_mappers[shaderType].append(mapper); mapper->setSignalIndex(m_itemMetaObject->property(propIdx).notifySignal().methodIndex()); Q_ASSERT(m_item->metaObject() == m_itemMetaObject); bool ok = QObjectPrivate::connectImpl(m_item, pd->notifyIndex(), m_item, nullptr, mapper, diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index 4f61d613091..d212ea63346 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -267,12 +267,10 @@ QSGTextureProvider *QQuickShaderEffectSource::textureProvider() const The default value is \c{ShaderEffectSource.ClampToEdge}. - \list - \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically - \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically - \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically - \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically - \endlist + \value ShaderEffectSource.ClampToEdge GL_CLAMP_TO_EDGE both horizontally and vertically + \value ShaderEffectSource.RepeatHorizontally GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically + \value ShaderEffectSource.RepeatVertically GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically + \value ShaderEffectSource.Repeat GL_REPEAT both horizontally and vertically \note Some OpenGL ES 2 implementations do not support the GL_REPEAT wrap mode with non-power-of-two textures. @@ -344,7 +342,6 @@ void QQuickShaderEffectSource::setSourceItem(QQuickItem *item) d->refFromEffectItem(m_hideSource); d->addItemChangeListener(this, QQuickItemPrivate::Geometry); connect(m_sourceItem, SIGNAL(destroyed(QObject*)), this, SLOT(sourceItemDestroyed(QObject*))); - connect(m_sourceItem, SIGNAL(parentChanged(QQuickItem*)), this, SLOT(sourceItemParentChanged(QQuickItem*))); } else { qWarning("ShaderEffectSource: sourceItem and ShaderEffectSource must both be children of the same window."); m_sourceItem = nullptr; @@ -364,13 +361,6 @@ void QQuickShaderEffectSource::sourceItemDestroyed(QObject *item) } -void QQuickShaderEffectSource::sourceItemParentChanged(QQuickItem *parent) -{ - if (!parent && m_texture) - m_texture->setItem(0); -} - - /*! \qmlproperty rect QtQuick::ShaderEffectSource::sourceRect @@ -427,11 +417,12 @@ void QQuickShaderEffectSource::setTextureSize(const QSize &size) source texture of a \l ShaderEffect. Depending on the OpenGL implementation, this property might allow you to save some texture memory. - \list - \li ShaderEffectSource.Alpha - GL_ALPHA - \li ShaderEffectSource.RGB - GL_RGB - \li ShaderEffectSource.RGBA - GL_RGBA - \endlist + \value ShaderEffectSource.RGBA8 GL_ALPHA + \value ShaderEffectSource.RGBA16F GL_RGB + \value ShaderEffectSource.RGBA32F GL_RGBA + \value ShaderEffectSource.Alpha Starting with Qt 6.0, this value is not in use and has the same effect as \c RGBA8 in practice. + \value ShaderEffectSource.RGB Starting with Qt 6.0, this value is not in use and has the same effect as \c RGBA8 in practice. + \value ShaderEffectSource.RGBA Starting with Qt 6.0, this value is not in use and has the same effect as \c RGBA8 in practice. \note Some OpenGL implementations do not support the GL_ALPHA format. */ @@ -565,11 +556,9 @@ void QQuickShaderEffectSource::setRecursive(bool enabled) such as those specified by ShaderEffect. Mirroring has no effect on the UI representation of the ShaderEffectSource item itself. - \list - \li ShaderEffectSource.NoMirroring - No mirroring - \li ShaderEffectSource.MirrorHorizontally - The generated texture is flipped along X-axis. - \li ShaderEffectSource.MirrorVertically - The generated texture is flipped along Y-axis. - \endlist + \value ShaderEffectSource.NoMirroring No mirroring + \value ShaderEffectSource.MirrorHorizontally The generated texture is flipped along X-axis. + \value ShaderEffectSource.MirrorVertically The generated texture is flipped along Y-axis. */ QQuickShaderEffectSource::TextureMirroring QQuickShaderEffectSource::textureMirroring() const diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h index 921038e49a9..fe419e59591 100644 --- a/src/quick/items/qquickshadereffectsource_p.h +++ b/src/quick/items/qquickshadereffectsource_p.h @@ -174,7 +174,6 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi private Q_SLOTS: void sourceItemDestroyed(QObject *item); void invalidateSceneGraph(); - void sourceItemParentChanged(QQuickItem *parent); protected: void releaseResources() override; diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp index e35c766ab67..ddc43c10ed9 100644 --- a/src/quick/items/qquickspriteengine.cpp +++ b/src/quick/items/qquickspriteengine.cpp @@ -352,6 +352,7 @@ void QQuickSpriteEngine::startAssemblingImage() return; m_loaded = false; m_errorsPrinted = false; + m_sprites.clear(); //This could also trigger the start of the image loading in Sprites, however that currently happens in Sprite::setSource diff --git a/src/quick/items/qquickspritesequence_p.h b/src/quick/items/qquickspritesequence_p.h index 39b536daae0..a1b137fef76 100644 --- a/src/quick/items/qquickspritesequence_p.h +++ b/src/quick/items/qquickspritesequence_p.h @@ -64,7 +64,7 @@ class QQuickSprite; class QQuickSpriteEngine; class QQuickSpriteSequencePrivate; class QSGSpriteNode; -class Q_AUTOTEST_EXPORT QQuickSpriteSequence : public QQuickItem +class Q_QUICK_PRIVATE_EXPORT QQuickSpriteSequence : public QQuickItem { Q_OBJECT Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged) diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp index 34c5b46892c..78d9cee7c00 100644 --- a/src/quick/items/qquickstateoperations.cpp +++ b/src/quick/items/qquickstateoperations.cpp @@ -359,8 +359,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions() actions << xa; } else { QQmlProperty property(d->target, QLatin1String("x")); - QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->xString.value, d->target, qmlContext(this)); - newBinding->setTarget(property); + auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->xString.value, d->target, qmlContext(this)); QQuickStateAction xa; xa.property = property; xa.toBinding = newBinding; @@ -378,8 +377,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions() actions << ya; } else { QQmlProperty property(d->target, QLatin1String("y")); - QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->yString.value, d->target, qmlContext(this)); - newBinding->setTarget(property); + auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->yString.value, d->target, qmlContext(this)); QQuickStateAction ya; ya.property = property; ya.toBinding = newBinding; @@ -397,8 +395,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions() actions << sa; } else { QQmlProperty property(d->target, QLatin1String("scale")); - QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->scaleString.value, d->target, qmlContext(this)); - newBinding->setTarget(property); + auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->scaleString.value, d->target, qmlContext(this)); QQuickStateAction sa; sa.property = property; sa.toBinding = newBinding; @@ -416,8 +413,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions() actions << ra; } else { QQmlProperty property(d->target, QLatin1String("rotation")); - QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->rotationString.value, d->target, qmlContext(this)); - newBinding->setTarget(property); + auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->rotationString.value, d->target, qmlContext(this)); QQuickStateAction ra; ra.property = property; ra.toBinding = newBinding; @@ -435,8 +431,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions() actions << wa; } else { QQmlProperty property(d->target, QLatin1String("width")); - QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->widthString.value, d->target, qmlContext(this)); - newBinding->setTarget(property); + auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->widthString, d->target, qmlContext(this)); QQuickStateAction wa; wa.property = property; wa.toBinding = newBinding; @@ -454,8 +449,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions() actions << ha; } else { QQmlProperty property(d->target, QLatin1String("height")); - QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->heightString.value, d->target, qmlContext(this)); - newBinding->setTarget(property); + auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->heightString, d->target, qmlContext(this)); QQuickStateAction ha; ha.property = property; ha.toBinding = newBinding; @@ -492,11 +486,13 @@ void QQuickParentChangePrivate::reverseRewindHelper(const std::unique_ptr<QQuick { if (!target || !snapshot) return; - target->setX(snapshot->x); - target->setY(snapshot->y); + + // leave existing bindings alive; new bindings are applied in applyBindings + // setPosition and setSize update the geometry without invalidating bindings + target->setPosition(QPointF(snapshot->x, snapshot->y)); + target->setSize(QSizeF(snapshot->width, snapshot->height)); + target->setScale(snapshot->scale); - target->setWidth(snapshot->width); - target->setHeight(snapshot->height); target->setRotation(snapshot->rotation); target->setParentItem(snapshot->parent); if (snapshot->stackBefore) @@ -573,7 +569,7 @@ void QQuickParentChange::rewind() The AnchorChanges type is used to modify the anchors of an item in a \l State. AnchorChanges cannot be used to modify the margins on an item. For this, use - PropertyChanges intead. + PropertyChanges instead. In the following example we change the top and bottom anchors of an item using AnchorChanges, and the top and bottom anchor margins using @@ -1106,35 +1102,59 @@ void QQuickAnchorChanges::reverse() QQuickAnchors::Anchors stateHAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Horizontal_Mask; QQuickAnchors::Anchors origHAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Horizontal_Mask; + const QRectF oldGeometry(d->target->position(), d->target->size()); bool stateSetWidth = (stateHAnchors && stateHAnchors != QQuickAnchors::LeftAnchor && stateHAnchors != QQuickAnchors::RightAnchor && stateHAnchors != QQuickAnchors::HCenterAnchor); + // in case of an additive AnchorChange, we _did_ end up modifying the width + stateSetWidth |= ((stateHAnchors & QQuickAnchors::LeftAnchor) && (origHAnchors & QQuickAnchors::RightAnchor)) || + ((stateHAnchors & QQuickAnchors::RightAnchor) && (origHAnchors & QQuickAnchors::LeftAnchor)); bool origSetWidth = (origHAnchors && origHAnchors != QQuickAnchors::LeftAnchor && origHAnchors != QQuickAnchors::RightAnchor && origHAnchors != QQuickAnchors::HCenterAnchor); - if (d->origWidth.isValid() && stateSetWidth && !origSetWidth) - d->target->setWidth(d->origWidth.value); + if (d->origWidth.isValid() && stateSetWidth && !origSetWidth && !qt_is_nan(d->origWidth)) { + targetPrivate->widthValidFlag = true; + if (targetPrivate->width != d->origWidth) + targetPrivate->width.setValueBypassingBindings(d->origWidth); + } bool stateSetHeight = (stateVAnchors && stateVAnchors != QQuickAnchors::TopAnchor && stateVAnchors != QQuickAnchors::BottomAnchor && stateVAnchors != QQuickAnchors::VCenterAnchor && stateVAnchors != QQuickAnchors::BaselineAnchor); + // in case of an additive AnchorChange, we _did_ end up modifying the height + stateSetHeight |= ((stateVAnchors & QQuickAnchors::TopAnchor) && (origVAnchors & QQuickAnchors::BottomAnchor)) || + ((stateVAnchors & QQuickAnchors::BottomAnchor) && (origVAnchors & QQuickAnchors::TopAnchor)); bool origSetHeight = (origVAnchors && origVAnchors != QQuickAnchors::TopAnchor && origVAnchors != QQuickAnchors::BottomAnchor && origVAnchors != QQuickAnchors::VCenterAnchor && origVAnchors != QQuickAnchors::BaselineAnchor); - if (d->origHeight.isValid() && stateSetHeight && !origSetHeight) - d->target->setHeight(d->origHeight.value); - - if (stateHAnchors && !origHAnchors) - d->target->setX(d->origX); + if (d->origHeight.isValid() && stateSetHeight && !origSetHeight && !qt_is_nan(d->origHeight)) { + targetPrivate->heightValidFlag = true; + if (targetPrivate->height != d->origHeight) + targetPrivate->height.setValueBypassingBindings(d->origHeight); + } - if (stateVAnchors && !origVAnchors) - d->target->setY(d->origY); + if (stateHAnchors && !origHAnchors && !qt_is_nan(d->origX) && d->origX != targetPrivate->x) + targetPrivate->x.setValueBypassingBindings(d->origX); + + if (stateVAnchors && !origVAnchors && !qt_is_nan(d->origY) && d->origY != targetPrivate->y) + targetPrivate->y.setValueBypassingBindings(d->origY); + + const QRectF newGeometry(d->target->position(), d->target->size()); + if (newGeometry != oldGeometry) { + QQuickItemPrivate::DirtyType dirtyFlags {}; + if (newGeometry.topLeft() != oldGeometry.topLeft()) + dirtyFlags = QQuickItemPrivate::DirtyType(dirtyFlags | QQuickItemPrivate::Position); + if (newGeometry.size() != oldGeometry.size()) + dirtyFlags = QQuickItemPrivate::DirtyType(dirtyFlags | QQuickItemPrivate::Size); + targetPrivate->dirty(dirtyFlags); + d->target->geometryChange(newGeometry, oldGeometry); + } } QQuickStateActionEvent::EventType QQuickAnchorChanges::type() const @@ -1198,9 +1218,9 @@ void QQuickAnchorChanges::saveOriginals() d->origBaselineBinding = QQmlPropertyPrivate::binding(d->baselineProp); QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target); - if (targetPrivate->widthValid) + if (targetPrivate->widthValid()) d->origWidth = d->target->width(); - if (targetPrivate->heightValid) + if (targetPrivate->heightValid()) d->origHeight = d->target->height(); d->origX = d->target->x(); d->origY = d->target->y(); @@ -1328,15 +1348,31 @@ void QQuickAnchorChanges::rewind() return; QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target); + const QRectF oldGeometry(d->target->position(), d->target->size()); + + // Restore previous values (but not previous bindings, i.e. anchors). + // Also, don't drop any new bindings. + if (!qt_is_nan(d->rewindX) && d->rewindX != targetPrivate->x) + targetPrivate->x.setValueBypassingBindings(d->rewindX); + if (!qt_is_nan(d->rewindY) && d->rewindY != targetPrivate->y) + targetPrivate->y.setValueBypassingBindings(d->rewindY); + + if (targetPrivate->widthValid() && !qt_is_nan(d->rewindWidth)) { + targetPrivate->widthValidFlag = true; + if (d->rewindWidth != targetPrivate->width) + targetPrivate->width.setValueBypassingBindings(d->rewindWidth); + } - //restore previous values (but not previous bindings, i.e. anchors) - d->target->setX(d->rewindX); - d->target->setY(d->rewindY); - if (targetPrivate->widthValid) { - d->target->setWidth(d->rewindWidth); + if (targetPrivate->heightValid() && !qt_is_nan(d->rewindHeight)) { + targetPrivate->heightValidFlag = true; + if (d->rewindHeight != targetPrivate->height) + targetPrivate->height.setValueBypassingBindings(d->rewindHeight); } - if (targetPrivate->heightValid) { - d->target->setHeight(d->rewindHeight); + + const QRectF newGeometry(d->target->position(), d->target->size()); + if (newGeometry != oldGeometry) { + targetPrivate->dirty(QQuickItemPrivate::Position); + d->target->geometryChange(newGeometry, oldGeometry); } } @@ -1373,7 +1409,6 @@ void QQuickAnchorChanges::saveTargetValues() d->toHeight = d->target->height(); } -#include <moc_qquickstateoperations_p.cpp> - QT_END_NAMESPACE +#include <moc_qquickstateoperations_p.cpp> diff --git a/src/quick/items/qquickstateoperations_p.h b/src/quick/items/qquickstateoperations_p.h index 44411c055d0..2f5077046ed 100644 --- a/src/quick/items/qquickstateoperations_p.h +++ b/src/quick/items/qquickstateoperations_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE class QQuickParentChangePrivate; -class Q_AUTOTEST_EXPORT QQuickParentChange : public QQuickStateOperation, public QQuickStateActionEvent +class Q_QUICK_PRIVATE_EXPORT QQuickParentChange : public QQuickStateOperation, public QQuickStateActionEvent { Q_OBJECT Q_DECLARE_PRIVATE(QQuickParentChange) @@ -128,7 +128,7 @@ class Q_AUTOTEST_EXPORT QQuickParentChange : public QQuickStateOperation, public class QQuickAnchorChanges; class QQuickAnchorSetPrivate; -class Q_AUTOTEST_EXPORT QQuickAnchorSet : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickAnchorSet : public QObject { Q_OBJECT @@ -183,7 +183,7 @@ class Q_AUTOTEST_EXPORT QQuickAnchorSet : public QObject }; class QQuickAnchorChangesPrivate; -class Q_AUTOTEST_EXPORT QQuickAnchorChanges : public QQuickStateOperation, public QQuickStateActionEvent +class Q_QUICK_PRIVATE_EXPORT QQuickAnchorChanges : public QQuickStateOperation, public QQuickStateActionEvent { Q_OBJECT Q_DECLARE_PRIVATE(QQuickAnchorChanges) diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 7ce92dc2e46..f8f56557ae1 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -190,7 +190,7 @@ \section1 Selecting items - You can add selection support to TableView by assigning a QSelectionModel to + You can add selection support to TableView by assigning an ItemSelectionModel to the \l selectionModel property. It will then use this model to control which delegate items should be shown as selected. For a delegate item to be shown as selected, it needs to contain the following property: @@ -207,6 +207,9 @@ depending on the \c selected property: \snippet qml/tableview/selectionmodel.qml 0 + + \note \l{Qt Quick Controls} offers a SelectionRectangle that can be used + to let the user select cells. */ /*! @@ -425,14 +428,15 @@ */ /*! - \qmlproperty QSelectionModel QtQuick::TableView::selectionModel + \qmlproperty ItemSelectionModel QtQuick::TableView::selectionModel + \since 6.2 This property can be set to control which delegate items should be shown as selected. If the delegate has a \c {required property bool selected} defined, TableView will keep it in sync with the selection state of the corresponding model item in the selection model. - \sa {Selecting items} + \sa {Selecting items}, SelectionRectangle */ /*! @@ -580,8 +584,8 @@ there is no setter function. This getter function is mostly useful if the TableView doesn't have a columnWidthProvider set, since otherwise you can call that function instead (which will work, even - for columns that are not currently visible. - If no columnWidthProvider is set, the height of a row will be + for columns that are not currently visible). + If no columnWidthProvider is set, the width of a column will be equal to its \l implicitColumnWidth(). \sa columnWidthProvider, implicitColumnWidth(), isColumnLoaded(), {Row heights and column widths} @@ -599,7 +603,7 @@ there is no setter function. This getter function is mostly useful if the TableView doesn't have a rowHeightProvider set, since otherwise you can call that function instead (which will work, even - for rows that are not currently visible. + for rows that are not currently visible). If no rowHeightProvider is set, the height of a row will be equal to its \l implicitRowHeight(). @@ -684,8 +688,6 @@ Q_LOGGING_CATEGORY(lcTableViewDelegateLifecycle, "qt.quick.tableview.lifecycle") #define Q_TABLEVIEW_ASSERT(cond, output) Q_ASSERT((cond) || [&](){ dumpTable(); qWarning() << "output:" << output; return false;}()) static const Qt::Edge allTableEdges[] = { Qt::LeftEdge, Qt::RightEdge, Qt::TopEdge, Qt::BottomEdge }; -static const int kEdgeIndexNotSet = -2; -static const int kEdgeIndexAtEnd = -3; static const char* kRequiredProperty = "_qt_isrequiredpropery_selected"; @@ -787,8 +789,12 @@ void QQuickTableViewPrivate::setSelectionStartPos(const QPointF &pos) { if (loadedItems.isEmpty()) return; - if (!selectionModel) + if (!selectionModel) { + if (warnNoSelectionModel) + qmlWarning(q_func()) << "Cannot set selection: no SelectionModel assigned!"; + warnNoSelectionModel = false; return; + } const QAbstractItemModel *qaim = selectionModel->model(); if (!qaim) return; @@ -813,8 +819,12 @@ void QQuickTableViewPrivate::setSelectionEndPos(const QPointF &pos) { if (loadedItems.isEmpty()) return; - if (!selectionModel) + if (!selectionModel) { + if (warnNoSelectionModel) + qmlWarning(q_func()) << "Cannot set selection: no SelectionModel assigned!"; + warnNoSelectionModel = false; return; + } const QAbstractItemModel *qaim = selectionModel->model(); if (!qaim) return; @@ -1583,21 +1593,22 @@ void QQuickTableViewPrivate::forceLayout() const QSize actualTableSize = calculateTableSize(); if (tableSize != actualTableSize) { - // This can happen if the app is calling forceLayout while - // the model is updated, but before we're notified about it. - rebuildOptions = RebuildOption::All; - } else { - // Resizing a column (or row) can result in the table going from being - // e.g completely inside the viewport to go outside. And in the latter - // case, the user needs to be able to scroll the viewport, also if - // flags such as Flickable.StopAtBounds is in use. So we need to - // update contentWidth/Height to support that case. - rebuildOptions = RebuildOption::LayoutOnly - | RebuildOption::CalculateNewContentWidth - | RebuildOption::CalculateNewContentHeight - | checkForVisibilityChanges(); + // The table size will have changed if forceLayout is called after + // the row count in the model has changed, but before we received + // a rowsInsertedCallback about it (and vice versa for columns). + rebuildOptions |= RebuildOption::ViewportOnly; } + // Resizing a column (or row) can result in the table going from being + // e.g completely inside the viewport to go outside. And in the latter + // case, the user needs to be able to scroll the viewport, also if + // flags such as Flickable.StopAtBounds is in use. So we need to + // update contentWidth/Height to support that case. + rebuildOptions |= RebuildOption::LayoutOnly + | RebuildOption::CalculateNewContentWidth + | RebuildOption::CalculateNewContentHeight + | checkForVisibilityChanges(); + scheduleRebuildTable(rebuildOptions); auto rootView = rootSyncView(); @@ -2328,16 +2339,31 @@ void QQuickTableViewPrivate::processRebuildTable() if (rebuildState == RebuildState::LayoutTable) { layoutAfterLoadingInitialTable(); + loadAndUnloadVisibleEdges(); + if (!moveToNextRebuildState()) + return; + } + + if (rebuildState == RebuildState::CancelOvershootBottomRight) { + cancelOvershootBottomRight(); + loadAndUnloadVisibleEdges(); if (!moveToNextRebuildState()) return; } - if (rebuildState == RebuildState::LoadAndUnloadAfterLayout) { + if (rebuildState == RebuildState::CancelOvershootTopLeft) { + cancelOvershootTopLeft(); loadAndUnloadVisibleEdges(); if (!moveToNextRebuildState()) return; } + if (rebuildState == RebuildState::UpdateContentSize) { + updateContentSize(); + if (!moveToNextRebuildState()) + return; + } + const bool preload = (rebuildOptions & RebuildOption::All && reusableFlag == QQmlTableInstanceModel::Reusable); @@ -2581,23 +2607,31 @@ void QQuickTableViewPrivate::loadInitialTable() loadAndUnloadVisibleEdges(); } -void QQuickTableViewPrivate::layoutAfterLoadingInitialTable() +void QQuickTableViewPrivate::updateContentSize() { - clearEdgeSizeCache(); - relayoutTableItems(); - syncLoadedTableRectFromLoadedTable(); - - if (rebuildOptions.testFlag(RebuildOption::CalculateNewContentWidth) || allColumnsLoaded()) { + const bool allColumnsLoaded = atTableEnd(Qt::LeftEdge) && atTableEnd(Qt::RightEdge); + if (rebuildOptions.testFlag(RebuildOption::CalculateNewContentWidth) || allColumnsLoaded) { updateAverageColumnWidth(); updateContentWidth(); } - if (rebuildOptions.testFlag(RebuildOption::CalculateNewContentHeight) || allRowsLoaded()) { + const bool allRowsLoaded = atTableEnd(Qt::TopEdge) && atTableEnd(Qt::BottomEdge); + if (rebuildOptions.testFlag(RebuildOption::CalculateNewContentHeight) || allRowsLoaded) { updateAverageRowHeight(); updateContentHeight(); } updateExtents(); +} + +void QQuickTableViewPrivate::layoutAfterLoadingInitialTable() +{ + clearEdgeSizeCache(); + relayoutTableItems(); + syncLoadedTableRectFromLoadedTable(); + + updateContentSize(); + adjustViewportXAccordingToAlignment(); adjustViewportYAccordingToAlignment(); } @@ -2672,6 +2706,58 @@ void QQuickTableViewPrivate::adjustViewportYAccordingToAlignment() syncViewportRect(); } +void QQuickTableViewPrivate::cancelOvershootBottomRight() +{ + // After doing a layout with positioning specified, the table might end up in an + // overshooting state (meaning that the table is dragged beyond the bounds + // of the viewport, with the result that it will bounce back in once you touch it). + // This happens because the layouting might try to e.g position the last row in the + // model in the center of the viewport, which will leave a big blank space from the + // last row towards the bottom. + // This space will be detected by updateExtents(), which will adjust the extents so + // that the superfluous blank area ends up as an overshoot. But we shouldn't leave the + // table in an overshooting state after a rebuild, so we clamp it here so thatit's + // either aligned to the top/left or to the bottom/right of the viewport. + // An exception is if we're not rebuilding because of positionViewAtCell(), since + // the app is allowed to set contentX and contentY at start-up. A second exception is + // if this view is a sync child, since then we can end up with extra space at the end + // if our model has fewer rows/columns than the syncView. + const qreal blankSpaceRight = viewportRect.right() - loadedTableOuterRect.right(); + const qreal blankSpaceBottom = viewportRect.bottom() - loadedTableOuterRect.bottom(); + const bool positionVertically = rebuildOptions.testFlag(RebuildOption::PositionViewAtRow); + const bool positionHorizontally = rebuildOptions.testFlag(RebuildOption::PositionViewAtColumn); + + if (positionVertically && !syncVertically && viewportRect.top() > 0 && blankSpaceBottom > 0) { + qCDebug(lcTableViewDelegateLifecycle()) << "cancelling overshoot at bottom:" << blankSpaceBottom; + setLocalViewportY(viewportRect.y() - blankSpaceBottom); + syncViewportRect(); + } + + if (positionHorizontally && !syncHorizontally && viewportRect.left() > 0 && blankSpaceRight > 0) { + qCDebug(lcTableViewDelegateLifecycle()) << "cancelling overshoot at right:" << blankSpaceRight; + setLocalViewportX(viewportRect.x() - blankSpaceRight); + syncViewportRect(); + } +} + +void QQuickTableViewPrivate::cancelOvershootTopLeft() +{ + const bool positionVertically = rebuildOptions.testFlag(RebuildOption::PositionViewAtRow); + const bool positionHorizontally = rebuildOptions.testFlag(RebuildOption::PositionViewAtColumn); + + if (positionVertically && !syncVertically && viewportRect.top() < 0) { + qCDebug(lcTableViewDelegateLifecycle()) << "cancelling overshoot at top:" << viewportRect.top(); + setLocalViewportY(0); + syncViewportRect(); + } + + if (positionHorizontally && !syncHorizontally && viewportRect.left() < 0) { + qCDebug(lcTableViewDelegateLifecycle()) << "cancelling overshoot at left:" << viewportRect.left(); + setLocalViewportX(0); + syncViewportRect(); + } +} + void QQuickTableViewPrivate::unloadEdge(Qt::Edge edge) { Q_Q(QQuickTableView); @@ -2722,7 +2808,7 @@ void QQuickTableViewPrivate::unloadEdge(Qt::Edge edge) void QQuickTableViewPrivate::loadEdge(Qt::Edge edge, QQmlIncubator::IncubationMode incubationMode) { const int edgeIndex = nextVisibleEdgeIndexAroundLoadedTable(edge); - qCDebug(lcTableViewDelegateLifecycle) << edge << edgeIndex; + qCDebug(lcTableViewDelegateLifecycle) << edge << edgeIndex << q_func(); const auto visibleCells = edge & (Qt::LeftEdge | Qt::RightEdge) ? loadedRows.keys() : loadedColumns.keys(); @@ -3147,9 +3233,6 @@ QVariant QQuickTableViewPrivate::modelImpl() const void QQuickTableViewPrivate::setModelImpl(const QVariant &newModel) { - if (newModel == assignedModel) - return; - assignedModel = newModel; scheduleRebuildTable(QQuickTableViewPrivate::RebuildOption::All); emit q_func()->modelChanged(); @@ -3157,7 +3240,7 @@ void QQuickTableViewPrivate::setModelImpl(const QVariant &newModel) void QQuickTableViewPrivate::syncModel() { - if (modelVariant == assignedModel) + if (compareModel(modelVariant, assignedModel)) return; if (model) { @@ -3223,11 +3306,25 @@ void QQuickTableViewPrivate::syncSyncView() if (syncHorizontally) { q->setColumnSpacing(syncView->columnSpacing()); updateContentWidth(); + + if (syncView->leftColumn() != q->leftColumn()) { + // The left column is no longer the same as the left + // column in syncView. This requires a rebuild. + scheduledRebuildOptions |= QQuickTableViewPrivate::RebuildOption::CalculateNewTopLeftColumn; + scheduledRebuildOptions.setFlag(RebuildOption::ViewportOnly); + } } if (syncVertically) { q->setRowSpacing(syncView->rowSpacing()); updateContentHeight(); + + if (syncView->topRow() != q->topRow()) { + // The top row is no longer the same as the top + // row in syncView. This requires a rebuild. + scheduledRebuildOptions |= QQuickTableViewPrivate::RebuildOption::CalculateNewTopLeftRow; + scheduledRebuildOptions.setFlag(RebuildOption::ViewportOnly); + } } if (syncView && loadedItems.isEmpty() && !tableSize.isEmpty()) { @@ -3399,6 +3496,13 @@ void QQuickTableViewPrivate::modelResetCallback() scheduleRebuildTable(RebuildOption::All); } +bool QQuickTableViewPrivate::compareModel(const QVariant& model1, const QVariant& model2) const +{ + return (model1 == model2 || + (model1.userType() == qMetaTypeId<QJSValue>() && model2.userType() == qMetaTypeId<QJSValue>() && + model1.value<QJSValue>().strictlyEquals(model2.value<QJSValue>()))); +} + void QQuickTableViewPrivate::scheduleRebuildIfFastFlick() { Q_Q(QQuickTableView); @@ -3453,10 +3557,26 @@ void QQuickTableViewPrivate::setLocalViewportY(qreal contentY) void QQuickTableViewPrivate::syncViewportRect() { - // Sync viewportRect so that it contains the actual geometry of the viewport + // Sync viewportRect so that it contains the actual geometry of the viewport. + // Since the column (and row) size of a sync child is decided by the column size + // of its sync view, the viewport width of a sync view needs to be the maximum of + // the sync views width, and its sync childrens width. This to ensure that no sync + // child loads a column which is not yet loaded by the sync view, since then the + // implicit column size cannot be resolved. Q_Q(QQuickTableView); - viewportRect = QRectF(q->contentX(), q->contentY(), q->width(), q->height()); - qCDebug(lcTableViewDelegateLifecycle) << viewportRect; + + qreal w = q->width(); + qreal h = q->height(); + + for (auto syncChild : std::as_const(syncChildren)) { + auto syncChild_d = syncChild->d_func(); + if (syncChild_d->syncHorizontally) + w = qMax(w, syncChild->width()); + if (syncChild_d->syncHorizontally) + h = qMax(h, syncChild->height()); + } + + viewportRect = QRectF(q->contentX(), q->contentY(), w, h); } void QQuickTableViewPrivate::syncViewportPosRecursive() @@ -3612,6 +3732,9 @@ QVariant QQuickTableView::model() const void QQuickTableView::setModel(const QVariant &newModel) { + if (d_func()->compareModel(newModel, d_func()->assignedModel)) + return; + return d_func()->setModelImpl(newModel); } @@ -4151,3 +4274,5 @@ QQuickTableSectionSizeProviderPrivate::~QQuickTableSectionSizeProviderPrivate() #include "moc_qquicktableview_p.cpp" QT_END_NAMESPACE + +#include "moc_qquicktableview_p_p.cpp" diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h index 76d5c152dae..3f969ab195b 100644 --- a/src/quick/items/qquicktableview_p_p.h +++ b/src/quick/items/qquicktableview_p_p.h @@ -71,6 +71,8 @@ Q_DECLARE_LOGGING_CATEGORY(lcTableViewDelegateLifecycle) static const qreal kDefaultRowHeight = 50; static const qreal kDefaultColumnWidth = 50; +static const int kEdgeIndexNotSet = -2; +static const int kEdgeIndexAtEnd = -3; class FxTableItem; class QQuickTableSectionSizeProviderPrivate; @@ -201,7 +203,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTableViewPrivate : public QQuickFlickablePriv LoadInitalTable, VerifyTable, LayoutTable, - LoadAndUnloadAfterLayout, + CancelOvershootBottomRight, + CancelOvershootTopLeft, + UpdateContentSize, PreloadColumns, PreloadRows, MovePreloadedItemsToPool, @@ -245,7 +249,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTableViewPrivate : public QQuickFlickablePriv // When the applications assignes a new model or delegate to the view, we keep them // around until we're ready to take them into use (syncWithPendingChanges). QVariant assignedModel = QVariant(int(0)); - QQmlComponent *assignedDelegate = nullptr; + QQmlGuard<QQmlComponent> assignedDelegate; // loadedRows/Columns describes the rows and columns that are currently loaded (from top left // row/column to bottom right row/column). loadedTableOuterRect describes the actual @@ -288,6 +292,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTableViewPrivate : public QQuickFlickablePriv // Consider making it public. bool isTransposed = false; + bool warnNoSelectionModel = true; + QJSValue rowHeightProvider; QJSValue columnWidthProvider; QQuickTableSectionSizeProvider rowHeights; @@ -396,6 +402,9 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTableViewPrivate : public QQuickFlickablePriv int nextVisibleEdgeIndex(Qt::Edge edge, int startIndex); int nextVisibleEdgeIndexAroundLoadedTable(Qt::Edge edge); + inline bool atTableEnd(Qt::Edge edge) { + return nextVisibleEdgeIndexAroundLoadedTable(edge) == kEdgeIndexAtEnd; + } bool allColumnsLoaded(); bool allRowsLoaded(); inline int edgeToArrayIndex(Qt::Edge edge); @@ -432,8 +441,13 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTableViewPrivate : public QQuickFlickablePriv void adjustViewportXAccordingToAlignment(); void adjustViewportYAccordingToAlignment(); + void cancelOvershootBottomRight(); + void cancelOvershootTopLeft(); + void scheduleRebuildTable(QQuickTableViewPrivate::RebuildOptions options); + void updateContentSize(); + QTypeRevision resolveImportVersion(); void createWrapperModel(); @@ -463,6 +477,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTableViewPrivate : public QQuickFlickablePriv void columnsRemovedCallback(const QModelIndex &parent, int begin, int end); void layoutChangedCallback(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint); void modelResetCallback(); + bool compareModel(const QVariant& model1, const QVariant& model2) const; void scheduleRebuildIfFastFlick(); void setLocalViewportX(qreal contentX); diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 379fef77229..ce2010e4898 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -764,11 +764,15 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline) const bool pixelSize = font.pixelSize() != -1; QString layoutText = layout.text(); - int largeFont = pixelSize ? font.pixelSize() : font.pointSize(); - int smallFont = fontSizeMode() != QQuickText::FixedSize - ? qMin(pixelSize ? minimumPixelSize() : minimumPointSize(), largeFont) - : largeFont; - int scaledFontSize = largeFont; + const qreal minimumSize = pixelSize + ? static_cast<qreal>(minimumPixelSize()) + : minimumPointSize(); + qreal largeFont = pixelSize ? font.pixelSize() : font.pointSizeF(); + qreal smallFont = fontSizeMode() != QQuickText::FixedSize + ? qMin<qreal>(minimumSize, largeFont) + : largeFont; + qreal scaledFontSize = largeFont; + const qreal sizeFittingThreshold(0.01); bool widthChanged = false; widthExceeded = availableWidth() <= 0 && (singlelineElide || canWrap || horizontalFit); @@ -797,7 +801,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline) if (pixelSize) scaledFont.setPixelSize(scaledFontSize); else - scaledFont.setPointSize(scaledFontSize); + scaledFont.setPointSizeF(scaledFontSize); if (layout.font() != scaledFont) layout.setFont(scaledFont); } @@ -967,7 +971,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline) const qreal availWidth = availableWidth(); const qreal availHeight = availableHeight(); - lineWidth = q->widthValid() && availWidth > 0 ? availWidth : naturalWidth; + lineWidth = q->widthValid() && q->width() > 0 ? availWidth : naturalWidth; maxHeight = q->heightValid() ? availHeight : FLT_MAX; // If the width of the item has changed and it's possible the result of wrapping, @@ -1061,40 +1065,45 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline) if (!horizontalFit && !verticalFit) break; + // Can't find a better fit + if (qFuzzyCompare(smallFont, largeFont)) + break; + // Try and find a font size that better fits the dimensions of the element. if (horizontalFit) { if (unelidedRect.width() > lineWidth || (!verticalFit && wrapped)) { widthExceeded = true; - largeFont = scaledFontSize - 1; - if (smallFont > largeFont) - break; + largeFont = scaledFontSize; + scaledFontSize = (smallFont + largeFont) / 2; - if (pixelSize) - scaledFont.setPixelSize(scaledFontSize); - else - scaledFont.setPointSize(scaledFontSize); + continue; } else if (!verticalFit) { smallFont = scaledFontSize; - if (smallFont == largeFont) + + // Check to see if the current scaledFontSize is acceptable + if ((largeFont - smallFont) < sizeFittingThreshold) break; - scaledFontSize = (smallFont + largeFont + 1) / 2; + + scaledFontSize = (smallFont + largeFont) / 2; } } if (verticalFit) { if (truncateHeight || unelidedRect.height() > maxHeight) { heightExceeded = true; - largeFont = scaledFontSize - 1; - if (smallFont > largeFont) - break; + largeFont = scaledFontSize; + scaledFontSize = (smallFont + largeFont) / 2; } else { smallFont = scaledFontSize; - if (smallFont == largeFont) + + // Check to see if the current scaledFontSize is acceptable + if ((largeFont - smallFont) < sizeFittingThreshold) break; - scaledFontSize = (smallFont + largeFont + 1) / 2; + + scaledFontSize = (smallFont + largeFont) / 2; } } } @@ -1153,12 +1162,6 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline) elideLayout->setFont(layout.font()); elideLayout->setTextOption(layout.textOption()); -#if QT_CONFIG(translation) - if (QQmlDebugTranslationService *service - = QQmlDebugConnector::service<QQmlDebugTranslationService>()) { - elideText = service->foundElidedText(q, layoutText, elideText); - } -#endif //QT_CONFIG(translation) elideLayout->setText(elideText); elideLayout->beginLayout(); @@ -1480,17 +1483,16 @@ QQuickText::~QQuickText() The requested weight of the font. The weight requested must be an integer between 1 and 1000, or one of the predefined values: - \list - \li Font.Thin - \li Font.Light - \li Font.ExtraLight - \li Font.Normal - the default - \li Font.Medium - \li Font.DemiBold - \li Font.Bold - \li Font.ExtraBold - \li Font.Black - \endlist + + \value Font.Thin 100 + \value Font.ExtraLight 200 + \value Font.Light 300 + \value Font.Normal 400 (default) + \value Font.Medium 500 + \value Font.DemiBold 600 + \value Font.Bold 700 + \value Font.ExtraBold 800 + \value Font.Black 900 \qml Text { text: "Hello"; font.weight: Font.DemiBold } @@ -1554,13 +1556,12 @@ QQuickText::~QQuickText() Sets the capitalization for the text. - \list - \li Font.MixedCase - This is the normal text rendering option where no capitalization change is applied. - \li Font.AllUppercase - This alters the text to be rendered in all uppercase type. - \li Font.AllLowercase - This alters the text to be rendered in all lowercase type. - \li Font.SmallCaps - This alters the text to be rendered in small-caps type. - \li Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character. - \endlist + \value Font.MixedCase the normal case: no capitalization change is applied + \value Font.AllUppercase alters the text to be rendered in all uppercase type + \value Font.AllLowercase alters the text to be rendered in all lowercase type + \value Font.SmallCaps alters the text to be rendered in small-caps type + \value Font.Capitalize alters the text to be rendered with the first character of + each word as an uppercase character \qml Text { text: "Hello"; font.capitalization: Font.AllLowercase } @@ -1577,23 +1578,21 @@ QQuickText::~QQuickText() \note This property only has an effect when used together with render type Text.NativeRendering. - \list - \value Font.PreferDefaultHinting - Use the default hinting level for the target platform. - \value Font.PreferNoHinting - If possible, render text without hinting the outlines + \value Font.PreferDefaultHinting Use the default hinting level for the target platform. + \value Font.PreferNoHinting If possible, render text without hinting the outlines of the glyphs. The text layout will be typographically accurate, using the same metrics as are used e.g. when printing. - \value Font.PreferVerticalHinting - If possible, render text with no horizontal hinting, + \value Font.PreferVerticalHinting If possible, render text with no horizontal hinting, but align glyphs to the pixel grid in the vertical direction. The text will appear crisper on displays where the density is too low to give an accurate rendering of the glyphs. But since the horizontal metrics of the glyphs are unhinted, the text's layout will be scalable to higher density devices (such as printers) without impacting details such as line breaks. - \value Font.PreferFullHinting - If possible, render text with hinting in both horizontal and + \value Font.PreferFullHinting If possible, render text with hinting in both horizontal and vertical directions. The text will be altered to optimize legibility on the target device, but since the metrics will depend on the target size of the text, the positions of glyphs, line breaks, and other typographical detail will not scale, meaning that a text layout may look different on devices with different pixel densities. - \endlist \qml Text { text: "Hello"; renderType: Text.NativeRendering; font.hintingPreference: Font.PreferVerticalHinting } @@ -1835,12 +1834,11 @@ void QQuickText::setLinkColor(const QColor &color) Set an additional text style. Supported text styles are: - \list - \li Text.Normal - the default - \li Text.Outline - \li Text.Raised - \li Text.Sunken - \endlist + + \value Text.Normal - the default + \value Text.Outline + \value Text.Raised + \value Text.Sunken \qml Row { @@ -2040,12 +2038,17 @@ void QQuickText::setVAlign(VAlignment align) Set this property to wrap the text to the Text item's width. The text will only wrap if an explicit width has been set. wrapMode can be one of: - \list - \li Text.NoWrap (default) - no wrapping will be performed. If the text contains insufficient newlines, then \l contentWidth will exceed a set width. - \li Text.WordWrap - wrapping is done on word boundaries only. If a word is too long, \l contentWidth will exceed a set width. - \li Text.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word. - \li Text.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word. - \endlist + \value Text.NoWrap + (default) no wrapping will be performed. If the text contains + insufficient newlines, then \l contentWidth will exceed a set width. + \value Text.WordWrap + wrapping is done on word boundaries only. If a word is too long, + \l contentWidth will exceed a set width. + \value Text.WrapAnywhere + wrapping is done at any point on a line, even if it occurs in the middle of a word. + \value Text.Wrap + if possible, wrapping occurs at a word boundary; otherwise it will occur + at the appropriate point on the line, even in the middle of a word. */ QQuickText::WrapMode QQuickText::wrapMode() const { @@ -2244,12 +2247,11 @@ void QQuickText::setTextFormat(TextFormat format) This property cannot be used with rich text. Eliding can be: - \list - \li Text.ElideNone - the default - \li Text.ElideLeft - \li Text.ElideMiddle - \li Text.ElideRight - \endlist + + \value Text.ElideNone - the default + \value Text.ElideLeft + \value Text.ElideMiddle + \value Text.ElideRight If this property is set to Text.ElideRight, it can be used with \l {wrapMode}{wrapped} text. The text will only elide if \c maximumLineCount, or \c height has been set. @@ -2416,21 +2418,23 @@ void QQuickText::geometryChange(const QRectF &newGeometry, const QRectF &oldGeom goto geomChangeDone; if (!(widthChanged || widthMaximum) && !d->isLineLaidOutConnected()) { // only height has changed - if (newGeometry.height() > oldGeometry.height()) { - if (!d->heightExceeded && !qFuzzyIsNull(oldGeometry.height())) { - // Height is adequate and growing, and it wasn't 0 previously. - goto geomChangeDone; - } - if (d->lineCount == d->maximumLineCount()) // Reached maximum line and height is growing. - goto geomChangeDone; - } else if (newGeometry.height() < oldGeometry.height()) { - if (d->lineCount < 2 && !verticalScale && newGeometry.height() > 0) // A single line won't be truncated until the text is 0 height. - goto geomChangeDone; - - if (!verticalScale // no scaling, no eliding, and either unwrapped, or no maximum line count. - && d->elideMode != QQuickText::ElideRight - && !(d->maximumLineCountValid && d->widthExceeded)) { - goto geomChangeDone; + if (!verticalPositionChanged) { + if (newGeometry.height() > oldGeometry.height()) { + if (!d->heightExceeded && !qFuzzyIsNull(oldGeometry.height())) { + // Height is adequate and growing, and it wasn't 0 previously. + goto geomChangeDone; + } + if (d->lineCount == d->maximumLineCount()) // Reached maximum line and height is growing. + goto geomChangeDone; + } else if (newGeometry.height() < oldGeometry.height()) { + if (d->lineCount < 2 && !verticalScale && newGeometry.height() > 0) // A single line won't be truncated until the text is 0 height. + goto geomChangeDone; + + if (!verticalScale // no scaling, no eliding, and either unwrapped, or no maximum line count. + && d->elideMode != QQuickText::ElideRight + && !(d->maximumLineCountValid && d->widthExceeded)) { + goto geomChangeDone; + } } } } else if (!heightChanged && widthMaximum) { @@ -2606,11 +2610,9 @@ void QQuickText::setLineHeight(qreal lineHeight) This property determines how the line height is specified. The possible values are: - \list - \li Text.ProportionalHeight (default) - this sets the spacing proportional to the - line (as a multiplier). For example, set to 2 for double spacing. - \li Text.FixedHeight - this sets the line height to a fixed line height (in pixels). - \endlist + \value Text.ProportionalHeight (default) sets the spacing proportional to the line + (as a multiplier). For example, set to 2 for double spacing. + \value Text.FixedHeight sets the line height to a fixed line height (in pixels). */ QQuickText::LineHeightMode QQuickText::lineHeightMode() const { @@ -2638,16 +2640,16 @@ void QQuickText::setLineHeightMode(LineHeightMode mode) This property specifies how the font size of the displayed text is determined. The possible values are: - \list - \li Text.FixedSize (default) - The size specified by \l font.pixelSize - or \l font.pointSize is used. - \li Text.HorizontalFit - The largest size up to the size specified that fits - within the width of the item without wrapping is used. - \li Text.VerticalFit - The largest size up to the size specified that fits - the height of the item is used. - \li Text.Fit - The largest size up to the size specified that fits within the - width and height of the item is used. - \endlist + \value Text.FixedSize + (default) The size specified by \l font.pixelSize or \l font.pointSize is used. + \value Text.HorizontalFit + The largest size up to the size specified that fits within the width of the item + without wrapping is used. + \value Text.VerticalFit + The largest size up to the size specified that fits the height of the item is used. + \value Text.Fit + The largest size up to the size specified that fits within the width and height + of the item is used. The font size of fitted text has a minimum bound specified by the minimumPointSize or minimumPixelSize property and maximum bound specified @@ -2958,7 +2960,7 @@ void QQuickTextPrivate::processHoverEvent(QHoverEvent *event) emit q->linkHovered(extra->hoveredLink); } } - event->setAccepted(!link.isEmpty()); + event->ignore(); } void QQuickText::hoverEnterEvent(QHoverEvent *event) @@ -2981,6 +2983,7 @@ void QQuickText::hoverLeaveEvent(QHoverEvent *event) /*! \qmlproperty int QtQuick::Text::renderTypeQuality + \since 6.0 Override the default rendering type quality for this component. This is a low-level customization which can be ignored in most cases. It currently only has an effect @@ -2994,13 +2997,11 @@ void QQuickText::hoverLeaveEvent(QHoverEvent *event) The \c renderTypeQuality may be any integer over 0, or one of the following predefined values - \list - \li Text.DefaultRenderTypeQuality (default) = -1 - \li Text.LowRenderTypeQuality = 26 - \li Text.NormalRenderTypeQuality = 52 - \li Text.HighRenderTypeQuality = 104 - \li Text.VeryHighRenderTypeQuality = 208 - \endlist + \value Text.DefaultRenderTypeQuality -1 (default) + \value Text.LowRenderTypeQuality 26 + \value Text.NormalRenderTypeQuality 52 + \value Text.HighRenderTypeQuality 104 + \value Text.VeryHighRenderTypeQuality 208 */ int QQuickText::renderTypeQuality() const { @@ -3029,12 +3030,11 @@ void QQuickText::setRenderTypeQuality(int renderTypeQuality) Override the default rendering type for this component. Supported render types are: - \list - \li Text.QtRendering - \li Text.NativeRendering - \endlist - Select Text.NativeRendering if you prefer text to look native on the target platform and do + \value Text.QtRendering Text is rendered using a scalable distance field for each glyph. + \value Text.NativeRendering Text is rendered using a platform-specific technique. + + Select \c Text.NativeRendering if you prefer text to look native on the target platform and do not require advanced features such as transformation of the text. Using such features in combination with the NativeRendering render type will lend poor and sometimes pixelated results. diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h index 304b82b9141..13d8579017c 100644 --- a/src/quick/items/qquicktext_p.h +++ b/src/quick/items/qquicktext_p.h @@ -339,6 +339,8 @@ private Q_SLOTS: Q_DECLARE_PRIVATE(QQuickText) }; +Q_DECLARE_MIXED_ENUM_OPERATORS_SYMMETRIC(int, QQuickText::HAlignment, QQuickText::VAlignment) + class QTextLine; class QQuickTextLine : public QObject { diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp index 6468760b8ef..b09c45246d7 100644 --- a/src/quick/items/qquicktextcontrol.cpp +++ b/src/quick/items/qquicktextcontrol.cpp @@ -821,11 +821,7 @@ void QQuickTextControl::setHtml(const QString &text) void QQuickTextControlPrivate::keyReleaseEvent(QKeyEvent *e) { - if (e->key() == Qt::Key_Back) { - e->ignore(); - return; - } - return; + e->ignore(); } void QQuickTextControlPrivate::keyPressEvent(QKeyEvent *e) diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 32a27661ea1..41fbcc7c482 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -235,17 +235,16 @@ QString QQuickTextEdit::text() const The requested weight of the font. The weight requested must be an integer between 1 and 1000, or one of the predefined values: - \list - \li Font.Thin - \li Font.Light - \li Font.ExtraLight - \li Font.Normal - the default - \li Font.Medium - \li Font.DemiBold - \li Font.Bold - \li Font.ExtraBold - \li Font.Black - \endlist + + \value Font.Thin 100 + \value Font.ExtraLight 200 + \value Font.Light 300 + \value Font.Normal 400 (default) + \value Font.Medium 500 + \value Font.DemiBold 600 + \value Font.Bold 700 + \value Font.ExtraBold 800 + \value Font.Black 900 \qml TextEdit { text: "Hello"; font.weight: Font.DemiBold } @@ -310,13 +309,12 @@ QString QQuickTextEdit::text() const Sets the capitalization for the text. - \list - \li Font.MixedCase - This is the normal text rendering option where no capitalization change is applied. - \li Font.AllUppercase - This alters the text to be rendered in all uppercase type. - \li Font.AllLowercase - This alters the text to be rendered in all lowercase type. - \li Font.SmallCaps - This alters the text to be rendered in small-caps type. - \li Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character. - \endlist + \value Font.MixedCase no capitalization change is applied + \value Font.AllUppercase alters the text to be rendered in all uppercase type + \value Font.AllLowercase alters the text to be rendered in all lowercase type + \value Font.SmallCaps alters the text to be rendered in small-caps type + \value Font.Capitalize alters the text to be rendered with the first character of + each word as an uppercase character \qml TextEdit { text: "Hello"; font.capitalization: Font.AllLowercase } @@ -333,23 +331,21 @@ QString QQuickTextEdit::text() const \note This property only has an effect when used together with render type TextEdit.NativeRendering. - \list - \value Font.PreferDefaultHinting - Use the default hinting level for the target platform. - \value Font.PreferNoHinting - If possible, render text without hinting the outlines + \value Font.PreferDefaultHinting Use the default hinting level for the target platform. + \value Font.PreferNoHinting If possible, render text without hinting the outlines of the glyphs. The text layout will be typographically accurate, using the same metrics as are used e.g. when printing. - \value Font.PreferVerticalHinting - If possible, render text with no horizontal hinting, + \value Font.PreferVerticalHinting If possible, render text with no horizontal hinting, but align glyphs to the pixel grid in the vertical direction. The text will appear crisper on displays where the density is too low to give an accurate rendering of the glyphs. But since the horizontal metrics of the glyphs are unhinted, the text's layout will be scalable to higher density devices (such as printers) without impacting details such as line breaks. - \value Font.PreferFullHinting - If possible, render text with hinting in both horizontal and + \value Font.PreferFullHinting If possible, render text with hinting in both horizontal and vertical directions. The text will be altered to optimize legibility on the target device, but since the metrics will depend on the target size of the text, the positions of glyphs, line breaks, and other typographical detail will not scale, meaning that a text layout may look different on devices with different pixel densities. - \endlist \qml TextEdit { text: "Hello"; renderType: TextEdit.NativeRendering; font.hintingPreference: Font.PreferVerticalHinting } @@ -400,7 +396,12 @@ QString QQuickTextEdit::text() const remarkably better performance for modifying especially large rich text content. - \sa clear(), textFormat + Note that some keyboards use a predictive function. In this case, + the text being composed by the input method is not part of this property. + The part of the text related to the predictions is underlined and stored in + the \l preeditText property. + + \sa clear(), preeditText, textFormat */ void QQuickTextEdit::setText(const QString &text) { @@ -432,6 +433,11 @@ void QQuickTextEdit::setText(const QString &text) \since 5.7 This property contains partial text input from an input method. + + To turn off partial text that results from predictions, set the \c Qt.ImhNoPredictiveText + flag in inputMethodHints. + + \sa inputMethodHints */ QString QQuickTextEdit::preeditText() const { @@ -519,12 +525,11 @@ void QQuickTextEdit::setTextFormat(TextFormat format) Override the default rendering type for this component. Supported render types are: - \list - \li Text.QtRendering - \li Text.NativeRendering - \endlist - Select Text.NativeRendering if you prefer text to look native on the target platform and do + \value TextEdit.QtRendering Text is rendered using a scalable distance field for each glyph. + \value TextEdit.NativeRendering Text is rendered using a platform-specific technique. + + Select \c TextEdit.NativeRendering if you prefer text to look native on the target platform and do not require advanced features such as transformation of the text. Using such features in combination with the NativeRendering render type will lend poor and sometimes pixelated results. @@ -674,19 +679,21 @@ void QQuickTextEdit::setSelectedTextColor(const QColor &color) the left. Valid values for \c horizontalAlignment are: - \list - \li TextEdit.AlignLeft (default) - \li TextEdit.AlignRight - \li TextEdit.AlignHCenter - \li TextEdit.AlignJustify - \endlist + + \value TextEdit.AlignLeft + left alignment with ragged edges on the right (default) + \value TextEdit.AlignRight + align each line to the right with ragged edges on the left + \value TextEdit.AlignHCenter + align each line to the center + \value TextEdit.AlignJustify + align each line to both right and left, spreading out words as necessary Valid values for \c verticalAlignment are: - \list - \li TextEdit.AlignTop (default) - \li TextEdit.AlignBottom - \li TextEdit.AlignVCenter - \endlist + + \value TextEdit.AlignTop start at the top of the item (default) + \value TextEdit.AlignBottom align the last line to the bottom and other lines above + \value TextEdit.AlignVCenter align the center vertically When using the attached property LayoutMirroring::enabled to mirror application layouts, the horizontal alignment of text will also be mirrored. However, the property @@ -901,20 +908,26 @@ void QQuickTextEdit::setVAlign(QQuickTextEdit::VAlignment alignment) moveCursorDelegate(); emit verticalAlignmentChanged(d->vAlign); } + /*! \qmlproperty enumeration QtQuick::TextEdit::wrapMode Set this property to wrap the text to the TextEdit item's width. The text will only wrap if an explicit width has been set. - \list - \li TextEdit.NoWrap - no wrapping will be performed. If the text contains insufficient newlines, then implicitWidth will exceed a set width. - \li TextEdit.WordWrap - wrapping is done on word boundaries only. If a word is too long, implicitWidth will exceed a set width. - \li TextEdit.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word. - \li TextEdit.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word. - \endlist + \value TextEdit.NoWrap + (default) no wrapping will be performed. If the text contains insufficient newlines, + \l {Item::}{implicitWidth} will exceed a set width. + \value TextEdit.WordWrap + wrapping is done on word boundaries only. If a word is too long, + \l {Item::}{implicitWidth} will exceed a set width. + \value TextEdit.WrapAnywhere + wrapping is done at any point on a line, even if it occurs in the middle of a word. + \value TextEdit.Wrap + if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate + point on the line, even in the middle of a word. - The default is TextEdit.NoWrap. If you set a width, consider using TextEdit.Wrap. + The default is \c TextEdit.NoWrap. If you set a width, consider using \c TextEdit.Wrap. */ QQuickTextEdit::WrapMode QQuickTextEdit::wrapMode() const { @@ -1091,13 +1104,12 @@ int QQuickTextEdit::positionAt(qreal x, qreal y) const The selection mode specifies whether the selection is updated on a per character or a per word basis. If not specified the selection mode will default to \c {TextEdit.SelectCharacters}. - \list - \li TextEdit.SelectCharacters - Sets either the selectionStart or selectionEnd (whichever was at - the previous cursor position) to the specified position. - \li TextEdit.SelectWords - Sets the selectionStart and selectionEnd to include all - words between the specified position and the previous cursor position. Words partially in the - range are included. - \endlist + \value TextEdit.SelectCharacters + Sets either the selectionStart or selectionEnd (whichever was at the previous cursor position) + to the specified position. + \value TextEdit.SelectWords + Sets the selectionStart and selectionEnd to include all words between the specified position + and the previous cursor position. Words partially in the range are included. For example, take this sequence of calls: @@ -1203,7 +1215,15 @@ void QQuickTextEdit::setCursorVisible(bool on) /*! \qmlproperty int QtQuick::TextEdit::cursorPosition - The position of the cursor in the TextEdit. + The position of the cursor in the TextEdit. The cursor is positioned between + characters. + + \note The \e characters in this case refer to the string of \l QChar objects, + therefore 16-bit Unicode characters, and the position is considered an index + into this string. This does not necessarily correspond to individual graphemes + in the writing system, as a single grapheme may be represented by multiple + Unicode characters, such as in the case of surrogate pairs, linguistic + ligatures or diacritics. */ int QQuickTextEdit::cursorPosition() const { @@ -1387,38 +1407,31 @@ void QQuickTextEdit::setTextMargin(qreal margin) Flags that alter behaviour are: - \list - \li Qt.ImhHiddenText - Characters should be hidden, as is typically used when entering passwords. - \li Qt.ImhSensitiveData - Typed text should not be stored by the active input method - in any persistent storage like predictive user dictionary. - \li Qt.ImhNoAutoUppercase - The input method should not try to automatically switch to upper case - when a sentence ends. - \li Qt.ImhPreferNumbers - Numbers are preferred (but not required). - \li Qt.ImhPreferUppercase - Upper case letters are preferred (but not required). - \li Qt.ImhPreferLowercase - Lower case letters are preferred (but not required). - \li Qt.ImhNoPredictiveText - Do not use predictive text (i.e. dictionary lookup) while typing. - - \li Qt.ImhDate - The text editor functions as a date field. - \li Qt.ImhTime - The text editor functions as a time field. - \endlist + \value Qt.ImhHiddenText Characters should be hidden, as is typically used when entering passwords. + \value Qt.ImhSensitiveData Typed text should not be stored by the active input method + in any persistent storage like predictive user dictionary. + \value Qt.ImhNoAutoUppercase The input method should not try to automatically switch to + upper case when a sentence ends. + \value Qt.ImhPreferNumbers Numbers are preferred (but not required). + \value Qt.ImhPreferUppercase Upper case letters are preferred (but not required). + \value Qt.ImhPreferLowercase Lower case letters are preferred (but not required). + \value Qt.ImhNoPredictiveText Do not use predictive text (i.e. dictionary lookup) while typing. + \value Qt.ImhDate The text editor functions as a date field. + \value Qt.ImhTime The text editor functions as a time field. Flags that restrict input (exclusive flags) are: - \list - \li Qt.ImhDigitsOnly - Only digits are allowed. - \li Qt.ImhFormattedNumbersOnly - Only number input is allowed. This includes decimal point and minus sign. - \li Qt.ImhUppercaseOnly - Only upper case letter input is allowed. - \li Qt.ImhLowercaseOnly - Only lower case letter input is allowed. - \li Qt.ImhDialableCharactersOnly - Only characters suitable for phone dialing are allowed. - \li Qt.ImhEmailCharactersOnly - Only characters suitable for email addresses are allowed. - \li Qt.ImhUrlCharactersOnly - Only characters suitable for URLs are allowed. - \endlist + \value Qt.ImhDigitsOnly Only digits are allowed. + \value Qt.ImhFormattedNumbersOnly Only number input is allowed. This includes decimal point and minus sign. + \value Qt.ImhUppercaseOnly Only upper case letter input is allowed. + \value Qt.ImhLowercaseOnly Only lower case letter input is allowed. + \value Qt.ImhDialableCharactersOnly Only characters suitable for phone dialing are allowed. + \value Qt.ImhEmailCharactersOnly Only characters suitable for email addresses are allowed. + \value Qt.ImhUrlCharactersOnly Only characters suitable for URLs are allowed. Masks: - \list - \li Qt.ImhExclusiveInputMask - This mask yields nonzero if any of the exclusive flags are used. - \endlist + \value Qt.ImhExclusiveInputMask This mask yields nonzero if any of the exclusive flags are used. */ Qt::InputMethodHints QQuickTextEdit::inputMethodHints() const @@ -1566,10 +1579,8 @@ void QQuickTextEdit::setSelectByMouse(bool on) Specifies how text should be selected using a mouse. - \list - \li TextEdit.SelectCharacters - The selection is updated with individual characters. (Default) - \li TextEdit.SelectWords - The selection is updated with whole words. - \endlist + \value TextEdit.SelectCharacters (default) The selection is updated with individual characters. + \value TextEdit.SelectWords The selection is updated with whole words. This property only applies when \l selectByMouse is true. */ @@ -2959,6 +2970,7 @@ void QQuickTextEdit::hoverEnterEvent(QHoverEvent *event) Q_D(QQuickTextEdit); if (d->isLinkHoveredConnected()) d->control->processEvent(event, QPointF(-d->xoff, -d->yoff)); + event->ignore(); } void QQuickTextEdit::hoverMoveEvent(QHoverEvent *event) @@ -2966,6 +2978,7 @@ void QQuickTextEdit::hoverMoveEvent(QHoverEvent *event) Q_D(QQuickTextEdit); if (d->isLinkHoveredConnected()) d->control->processEvent(event, QPointF(-d->xoff, -d->yoff)); + event->ignore(); } void QQuickTextEdit::hoverLeaveEvent(QHoverEvent *event) @@ -2973,6 +2986,7 @@ void QQuickTextEdit::hoverLeaveEvent(QHoverEvent *event) Q_D(QQuickTextEdit); if (d->isLinkHoveredConnected()) d->control->processEvent(event, QPointF(-d->xoff, -d->yoff)); + event->ignore(); } /*! diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h index 41245f904e3..7b43a847c16 100644 --- a/src/quick/items/qquicktextedit_p.h +++ b/src/quick/items/qquicktextedit_p.h @@ -422,6 +422,8 @@ private Q_SLOTS: Q_DECLARE_PRIVATE(QQuickTextEdit) }; +Q_DECLARE_MIXED_ENUM_OPERATORS_SYMMETRIC(int, QQuickTextEdit::HAlignment, QQuickTextEdit::VAlignment) + QT_END_NAMESPACE QML_DECLARE_TYPE(QQuickTextEdit) diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index f0cb66fa40e..f41ab2f626f 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -125,7 +125,13 @@ void QQuickTextInput::componentComplete() The text in the TextInput. - \sa clear() + Note that some keyboards use a predictive function. In this case, + the text being composed by the input method is not part of this property. + The part of the text related to the predictions is underlined and stored in + the \l preeditText property. To get whole text displayed in the TextInput + use \l displayText property. + + \sa clear(), displayText, preeditText */ QString QQuickTextInput::text() const { @@ -155,12 +161,11 @@ void QQuickTextInput::setText(const QString &s) Override the default rendering type for this component. Supported render types are: - \list - \li Text.QtRendering - \li Text.NativeRendering - \endlist - Select Text.NativeRendering if you prefer text to look native on the target platform and do + \value TextInput.QtRendering Text is rendered using a scalable distance field for each glyph. + \value TextInput.NativeRendering Text is rendered using a platform-specific technique. + + Select \c TextInput.NativeRendering if you prefer text to look native on the target platform and do not require advanced features such as transformation of the text. Using such features in combination with the NativeRendering render type will lend poor and sometimes pixelated results. @@ -259,17 +264,16 @@ QString QQuickTextInputPrivate::realText() const The requested weight of the font. The weight requested must be an integer between 1 and 1000, or one of the predefined values: - \list - \li Font.Thin - \li Font.Light - \li Font.ExtraLight - \li Font.Normal - the default - \li Font.Medium - \li Font.DemiBold - \li Font.Bold - \li Font.ExtraBold - \li Font.Black - \endlist + + \value Font.Thin 100 + \value Font.ExtraLight 200 + \value Font.Light 300 + \value Font.Normal 400 (default) + \value Font.Medium 500 + \value Font.DemiBold 600 + \value Font.Bold 700 + \value Font.ExtraBold 800 + \value Font.Black 900 \qml TextInput { text: "Hello"; font.weight: Font.DemiBold } @@ -333,13 +337,12 @@ QString QQuickTextInputPrivate::realText() const Sets the capitalization for the text. - \list - \li Font.MixedCase - This is the normal text rendering option where no capitalization change is applied. - \li Font.AllUppercase - This alters the text to be rendered in all uppercase type. - \li Font.AllLowercase - This alters the text to be rendered in all lowercase type. - \li Font.SmallCaps - This alters the text to be rendered in small-caps type. - \li Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character. - \endlist + \value Font.MixedCase the normal case: no capitalization change is applied + \value Font.AllUppercase alters the text to be rendered in all uppercase type + \value Font.AllLowercase alters the text to be rendered in all lowercase type + \value Font.SmallCaps alters the text to be rendered in small-caps type + \value Font.Capitalize alters the text to be rendered with the first character of + each word as an uppercase character \qml TextInput { text: "Hello"; font.capitalization: Font.AllLowercase } @@ -356,23 +359,21 @@ QString QQuickTextInputPrivate::realText() const \note This property only has an effect when used together with render type TextInput.NativeRendering. - \list - \value Font.PreferDefaultHinting - Use the default hinting level for the target platform. - \value Font.PreferNoHinting - If possible, render text without hinting the outlines + \value Font.PreferDefaultHinting Use the default hinting level for the target platform. + \value Font.PreferNoHinting If possible, render text without hinting the outlines of the glyphs. The text layout will be typographically accurate, using the same metrics as are used e.g. when printing. - \value Font.PreferVerticalHinting - If possible, render text with no horizontal hinting, + \value Font.PreferVerticalHinting If possible, render text with no horizontal hinting, but align glyphs to the pixel grid in the vertical direction. The text will appear crisper on displays where the density is too low to give an accurate rendering of the glyphs. But since the horizontal metrics of the glyphs are unhinted, the text's layout will be scalable to higher density devices (such as printers) without impacting details such as line breaks. - \value Font.PreferFullHinting - If possible, render text with hinting in both horizontal and + \value Font.PreferFullHinting If possible, render text with hinting in both horizontal and vertical directions. The text will be altered to optimize legibility on the target device, but since the metrics will depend on the target size of the text, the positions of glyphs, line breaks, and other typographical detail will not scale, meaning that a text layout may look different on devices with different pixel densities. - \endlist \qml TextInput { text: "Hello"; renderType: TextInput.NativeRendering; font.hintingPreference: Font.PreferVerticalHinting } @@ -517,8 +518,16 @@ void QQuickTextInput::setSelectedTextColor(const QColor &color) } /*! - \qmlproperty enumeration QtQuick::TextInput::horizontalAlignment \qmlproperty enumeration QtQuick::TextInput::effectiveHorizontalAlignment + \readonly + + When using the attached property LayoutMirroring::enabled to mirror application + layouts, the horizontal alignment of text will also be mirrored. However, the property + \l horizontalAlignment will remain unchanged. To query the effective horizontal alignment + of TextInput, use the read-only property \c effectiveHorizontalAlignment. +*/ +/*! + \qmlproperty enumeration QtQuick::TextInput::horizontalAlignment \qmlproperty enumeration QtQuick::TextInput::verticalAlignment Sets the horizontal alignment of the text within the TextInput item's @@ -541,7 +550,7 @@ void QQuickTextInput::setSelectedTextColor(const QColor &color) When using the attached property LayoutMirroring::enabled to mirror application layouts, the horizontal alignment of text will also be mirrored. However, the property \c horizontalAlignment will remain unchanged. To query the effective horizontal alignment - of TextInput, use the read-only property \c effectiveHorizontalAlignment. + of TextInput, use the read-only property \l effectiveHorizontalAlignment. */ QQuickTextInput::HAlignment QQuickTextInput::hAlign() const { @@ -680,12 +689,17 @@ void QQuickTextInput::setVAlign(QQuickTextInput::VAlignment alignment) Set this property to wrap the text to the TextInput item's width. The text will only wrap if an explicit width has been set. - \list - \li TextInput.NoWrap - no wrapping will be performed. If the text contains insufficient newlines, then implicitWidth will exceed a set width. - \li TextInput.WordWrap - wrapping is done on word boundaries only. If a word is too long, implicitWidth will exceed a set width. - \li TextInput.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word. - \li TextInput.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word. - \endlist + \value TextInput.NoWrap + (default) no wrapping will be performed. If the text contains + insufficient newlines, then \l contentWidth will exceed a set width. + \value TextInput.WordWrap + wrapping is done on word boundaries only. If a word is too long, + \l contentWidth will exceed a set width. + \value TextInput.WrapAnywhere + wrapping is done at any point on a line, even if it occurs in the middle of a word. + \value TextInput.Wrap + if possible, wrapping occurs at a word boundary; otherwise it will occur + at the appropriate point on the line, even in the middle of a word. The default is TextInput.NoWrap. If you set a width, consider using TextInput.Wrap. */ @@ -830,7 +844,20 @@ void QQuickTextInput::setCursorVisible(bool on) /*! \qmlproperty int QtQuick::TextInput::cursorPosition - The position of the cursor in the TextInput. + The position of the cursor in the TextInput. The cursor is positioned between + characters. + + \note The \e characters in this case refer to the string of \l QChar objects, + therefore 16-bit Unicode characters, and the position is considered an index + into this string. This does not necessarily correspond to individual graphemes + in the writing system, as a single grapheme may be represented by multiple + Unicode characters, such as in the case of surrogate pairs, linguistic + ligatures or diacritics. + + \l displayText is different if echoMode is set to \l TextInput.Password: then + each passwordMaskCharacter is a "narrow" character + (the cursorPosition always moves by 1), even if the text in the TextInput is not. + */ int QQuickTextInput::cursorPosition() const { @@ -848,6 +875,7 @@ void QQuickTextInput::setCursorPosition(int cp) /*! \qmlproperty rectangle QtQuick::TextInput::cursorRectangle + \readonly The rectangle where the standard text cursor is rendered within the text input. Read only. @@ -889,6 +917,7 @@ QRectF QQuickTextInput::cursorRectangle() const This property is read-only. To change the selection, use select(start,end), selectAll(), or selectWord(). + \readonly \sa selectionEnd, cursorPosition, selectedText */ int QQuickTextInput::selectionStart() const @@ -904,6 +933,7 @@ int QQuickTextInput::selectionStart() const This property is read-only. To change the selection, use select(start,end), selectAll(), or selectWord(). + \readonly \sa selectionStart, cursorPosition, selectedText */ int QQuickTextInput::selectionEnd() const @@ -934,6 +964,7 @@ void QQuickTextInput::select(int start, int end) /*! \qmlproperty string QtQuick::TextInput::selectedText + \readonly This read-only property provides the text currently selected in the text input. @@ -1151,6 +1182,7 @@ void QQuickTextInput::setInputMask(const QString &im) /*! \qmlproperty bool QtQuick::TextInput::acceptableInput + \readonly This property is always true unless a validator or input mask has been set. If a validator or input mask has been set, this property will only be true @@ -1210,14 +1242,13 @@ Qt::InputMethodHints QQuickTextInputPrivate::effectiveInputMethodHints() const \qmlproperty enumeration QtQuick::TextInput::echoMode Specifies how the text should be displayed in the TextInput. - \list - \li TextInput.Normal - Displays the text as it is. (Default) - \li TextInput.Password - Displays platform-dependent password mask - characters instead of the actual characters. - \li TextInput.NoEcho - Displays nothing. - \li TextInput.PasswordEchoOnEdit - Displays characters as they are entered - while editing, otherwise identical to \c TextInput.Password. - \endlist + + \value TextInput.Normal Displays the text as it is. (Default) + \value TextInput.Password Displays platform-dependent password mask + characters instead of the actual characters. + \value TextInput.NoEcho Displays nothing. + \value TextInput.PasswordEchoOnEdit Displays characters as they are entered + while editing, otherwise identical to \c TextInput.Password. */ QQuickTextInput::EchoMode QQuickTextInput::echoMode() const { @@ -1258,40 +1289,31 @@ void QQuickTextInput::setEchoMode(QQuickTextInput::EchoMode echo) Flags that alter behaviour are: - \list - \li Qt.ImhHiddenText - Characters should be hidden, as is typically used when entering passwords. - This is automatically set when setting echoMode to \c TextInput.Password. - \li Qt.ImhSensitiveData - Typed text should not be stored by the active input method - in any persistent storage like predictive user dictionary. - \li Qt.ImhNoAutoUppercase - The input method should not try to automatically switch to upper case - when a sentence ends. - \li Qt.ImhPreferNumbers - Numbers are preferred (but not required). - \li Qt.ImhPreferUppercase - Upper case letters are preferred (but not required). - \li Qt.ImhPreferLowercase - Lower case letters are preferred (but not required). - \li Qt.ImhNoPredictiveText - Do not use predictive text (i.e. dictionary lookup) while typing. - - \li Qt.ImhDate - The text editor functions as a date field. - \li Qt.ImhTime - The text editor functions as a time field. - \li Qt.ImhMultiLine - The text editor doesn't close software input keyboard when Return or Enter key is pressed (since QtQuick 2.4). - \endlist + \value Qt.ImhHiddenText Characters should be hidden, as is typically used when entering passwords. + \value Qt.ImhSensitiveData Typed text should not be stored by the active input method + in any persistent storage like predictive user dictionary. + \value Qt.ImhNoAutoUppercase The input method should not try to automatically switch to + upper case when a sentence ends. + \value Qt.ImhPreferNumbers Numbers are preferred (but not required). + \value Qt.ImhPreferUppercase Upper case letters are preferred (but not required). + \value Qt.ImhPreferLowercase Lower case letters are preferred (but not required). + \value Qt.ImhNoPredictiveText Do not use predictive text (i.e. dictionary lookup) while typing. + \value Qt.ImhDate The text editor functions as a date field. + \value Qt.ImhTime The text editor functions as a time field. Flags that restrict input (exclusive flags) are: - \list - \li Qt.ImhDigitsOnly - Only digits are allowed. - \li Qt.ImhFormattedNumbersOnly - Only number input is allowed. This includes decimal point and minus sign. - \li Qt.ImhUppercaseOnly - Only upper case letter input is allowed. - \li Qt.ImhLowercaseOnly - Only lower case letter input is allowed. - \li Qt.ImhDialableCharactersOnly - Only characters suitable for phone dialing are allowed. - \li Qt.ImhEmailCharactersOnly - Only characters suitable for email addresses are allowed. - \li Qt.ImhUrlCharactersOnly - Only characters suitable for URLs are allowed. - \endlist + \value Qt.ImhDigitsOnly Only digits are allowed. + \value Qt.ImhFormattedNumbersOnly Only number input is allowed. This includes decimal point and minus sign. + \value Qt.ImhUppercaseOnly Only upper case letter input is allowed. + \value Qt.ImhLowercaseOnly Only lower case letter input is allowed. + \value Qt.ImhDialableCharactersOnly Only characters suitable for phone dialing are allowed. + \value Qt.ImhEmailCharactersOnly Only characters suitable for email addresses are allowed. + \value Qt.ImhUrlCharactersOnly Only characters suitable for URLs are allowed. Masks: - \list - \li Qt.ImhExclusiveInputMask - This mask yields nonzero if any of the exclusive flags are used. - \endlist + \value Qt.ImhExclusiveInputMask This mask yields nonzero if any of the exclusive flags are used. */ Qt::InputMethodHints QQuickTextInput::inputMethodHints() const @@ -1584,7 +1606,7 @@ void QQuickTextInput::mousePressEvent(QMouseEvent *event) d->moveCursor(cursor, mark); if (d->focusOnPress && !qGuiApp->styleHints()->setFocusOnTouchRelease()) - ensureActiveFocus(); + ensureActiveFocus(Qt::MouseFocusReason); event->setAccepted(true); } @@ -1636,7 +1658,7 @@ void QQuickTextInput::mouseReleaseEvent(QMouseEvent *event) #endif if (d->focusOnPress && qGuiApp->styleHints()->setFocusOnTouchRelease()) - ensureActiveFocus(); + ensureActiveFocus(Qt::MouseFocusReason); if (!event->isAccepted()) QQuickImplicitSizeItem::mouseReleaseEvent(event); @@ -1871,10 +1893,10 @@ void QQuickTextInput::invalidateFontCaches() d->m_textLayout.engine()->resetFontEngineCache(); } -void QQuickTextInput::ensureActiveFocus() +void QQuickTextInput::ensureActiveFocus(Qt::FocusReason reason) { bool hadActiveFocus = hasActiveFocus(); - forceActiveFocus(); + forceActiveFocus(reason); #if QT_CONFIG(im) Q_D(QQuickTextInput); // re-open input panel on press if already focused @@ -2001,6 +2023,8 @@ QVariant QQuickTextInput::inputMethodQuery(Qt::InputMethodQuery property, const if (argument.isValid()) return QVariant(QStringView{d->m_text}.left(d->m_cursor).right(argument.toInt()).toString()); return QVariant(d->m_text.left(d->m_cursor)); + case Qt::ImReadOnly: + return QVariant(d->m_readOnly); default: return QQuickItem::inputMethodQuery(property); } @@ -2104,7 +2128,7 @@ void QQuickTextInput::undo() { Q_D(QQuickTextInput); if (!d->m_readOnly) { - d->resetInputMethod(); + d->cancelInput(); d->internalUndo(); d->finishChange(-1, true); } @@ -2120,7 +2144,7 @@ void QQuickTextInput::redo() { Q_D(QQuickTextInput); if (!d->m_readOnly) { - d->resetInputMethod(); + d->cancelInput(); d->internalRedo(); d->finishChange(); } @@ -2373,7 +2397,10 @@ QString QQuickTextInput::displayText() const This property contains partial text input from an input method. - \sa displayText + To turn off partial text that results from predictions, set the \c Qt.ImhNoPredictiveText + flag in inputMethodHints. + + \sa displayText, inputMethodHints */ QString QQuickTextInput::preeditText() const { @@ -2411,10 +2438,8 @@ void QQuickTextInput::setSelectByMouse(bool on) Specifies how text should be selected using a mouse. - \list - \li TextInput.SelectCharacters - The selection is updated with individual characters. (Default) - \li TextInput.SelectWords - The selection is updated with whole words. - \endlist + \value TextInput.SelectCharacters (default) The selection is updated with individual characters. + \value TextInput.SelectWords The selection is updated with whole words. This property only applies when \l selectByMouse is true. */ @@ -2458,6 +2483,7 @@ void QQuickTextInput::setPersistentSelection(bool on) /*! \qmlproperty bool QtQuick::TextInput::canPaste + \readonly Returns true if the TextInput is writable and the content of the clipboard is suitable for pasting into the TextInput. @@ -2479,6 +2505,7 @@ bool QQuickTextInput::canPaste() const /*! \qmlproperty bool QtQuick::TextInput::canUndo + \readonly Returns true if the TextInput is writable and there are previous operations that can be undone. @@ -2492,6 +2519,7 @@ bool QQuickTextInput::canUndo() const /*! \qmlproperty bool QtQuick::TextInput::canRedo + \readonly Returns true if the TextInput is writable and there are \l {undo}{undone} operations that can be redone. @@ -2505,6 +2533,7 @@ bool QQuickTextInput::canRedo() const /*! \qmlproperty real QtQuick::TextInput::contentWidth + \readonly Returns the width of the text, including the width past the width which is covered due to insufficient wrapping if \l wrapMode is set. @@ -2518,6 +2547,7 @@ qreal QQuickTextInput::contentWidth() const /*! \qmlproperty real QtQuick::TextInput::contentHeight + \readonly Returns the height of the text, including the height past the height that is covered if the text does not fit within the set height. @@ -2549,13 +2579,12 @@ void QQuickTextInput::moveCursorSelection(int position) The selection mode specifies whether the selection is updated on a per character or a per word basis. If not specified the selection mode will default to \c {TextInput.SelectCharacters}. - \list - \li TextInput.SelectCharacters - Sets either the selectionStart or selectionEnd (whichever was at - the previous cursor position) to the specified position. - \li TextInput.SelectWords - Sets the selectionStart and selectionEnd to include all - words between the specified position and the previous cursor position. Words partially in the - range are included. - \endlist + \value TextInput.SelectCharacters + Sets either the selectionStart or selectionEnd (whichever was at the previous cursor position) + to the specified position. + \value TextInput.SelectWords + Sets the selectionStart and selectionEnd to include all words between the specified position + and the previous cursor position. Words partially in the range are included. For example, take this sequence of calls: @@ -2681,7 +2710,7 @@ void QQuickTextInput::focusOutEvent(QFocusEvent *event) /*! \qmlproperty bool QtQuick::TextInput::inputMethodComposing - + \readonly This property holds whether the TextInput has partial text input from an input method. @@ -2747,11 +2776,13 @@ void QQuickTextInputPrivate::init() m_inputControl = new QInputControl(QInputControl::LineEdit, q); } -void QQuickTextInputPrivate::resetInputMethod() +void QQuickTextInputPrivate::cancelInput() { +#if QT_CONFIG(im) Q_Q(QQuickTextInput); if (!m_readOnly && q->hasActiveFocus() && qGuiApp) - QGuiApplication::inputMethod()->reset(); + cancelPreedit(); +#endif // im } void QQuickTextInput::updateCursorRectangle(bool scroll) @@ -3459,7 +3490,12 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event) for (int i = 0; i < event->attributes().size(); ++i) { const QInputMethodEvent::Attribute &a = event->attributes().at(i); if (a.type == QInputMethodEvent::Selection) { - m_cursor = qBound(0, a.start + a.length, m_text.length()); + // If we already called internalInsert(), the cursor position will + // already be adjusted correctly. The attribute.start does + // not seem to take the mask into account, so it will reset cursor + // to an invalid position in such case. + if (!cursorPositionChanged) + m_cursor = qBound(0, a.start + a.length, m_text.length()); if (a.length) { m_selstart = qMax(0, qMin(a.start, m_text.length())); m_selend = m_cursor; @@ -4696,7 +4732,7 @@ void QQuickTextInput::ensureVisible(int position) void QQuickTextInput::clear() { Q_D(QQuickTextInput); - d->resetInputMethod(); + d->cancelInput(); d->clear(); } diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h index ee06eb88e7a..031b4780db6 100644 --- a/src/quick/items/qquicktextinput_p.h +++ b/src/quick/items/qquicktextinput_p.h @@ -362,7 +362,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem private: void invalidateFontCaches(); - void ensureActiveFocus(); + void ensureActiveFocus(Qt::FocusReason reason); protected: QQuickTextInput(QQuickTextInputPrivate &dd, QQuickItem *parent = nullptr); diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h index b4561556aa4..1fecd7f9dff 100644 --- a/src/quick/items/qquicktextinput_p_p.h +++ b/src/quick/items/qquicktextinput_p_p.h @@ -173,7 +173,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeI } void init(); - void resetInputMethod(); + void cancelInput(); void startCreatingCursor(); void ensureVisible(int position, int preeditCursor = 0, int preeditLength = 0); void updateHorizontalScroll(); diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp index b3401200c8e..763607f7307 100644 --- a/src/quick/items/qquicktextnodeengine.cpp +++ b/src/quick/items/qquicktextnodeengine.cpp @@ -209,10 +209,7 @@ void QQuickTextNodeEngine::addTextDecorations(const QVarLengthArray<TextDecorati { QRectF &rect = textDecoration.rect; - rect.setY(qRound(rect.y() - + m_currentLine.ascent() - + (m_currentLine.leadingIncluded() ? m_currentLine.leading() : qreal(0.0f)) - + offset)); + rect.setY(qRound(rect.y() + m_currentLine.ascent() + offset)); rect.setHeight(thickness); } diff --git a/src/quick/items/qquicktranslate_p.h b/src/quick/items/qquicktranslate_p.h index 9832989e73c..1853f2f9c64 100644 --- a/src/quick/items/qquicktranslate_p.h +++ b/src/quick/items/qquicktranslate_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <private/qtquickglobal_p.h> #include "qquickitem.h" #include <QtGui/qmatrix4x4.h> @@ -58,7 +59,7 @@ QT_BEGIN_NAMESPACE class QQuickTranslatePrivate; -class Q_AUTOTEST_EXPORT QQuickTranslate : public QQuickTransform +class Q_QUICK_PRIVATE_EXPORT QQuickTranslate : public QQuickTransform { Q_OBJECT @@ -89,7 +90,7 @@ class Q_AUTOTEST_EXPORT QQuickTranslate : public QQuickTransform }; class QQuickScalePrivate; -class Q_AUTOTEST_EXPORT QQuickScale : public QQuickTransform +class Q_QUICK_PRIVATE_EXPORT QQuickScale : public QQuickTransform { Q_OBJECT @@ -129,7 +130,7 @@ class Q_AUTOTEST_EXPORT QQuickScale : public QQuickTransform }; class QQuickRotationPrivate; -class Q_AUTOTEST_EXPORT QQuickRotation : public QQuickTransform +class Q_QUICK_PRIVATE_EXPORT QQuickRotation : public QQuickTransform { Q_OBJECT @@ -164,7 +165,7 @@ class Q_AUTOTEST_EXPORT QQuickRotation : public QQuickTransform }; class QQuickMatrix4x4Private; -class Q_AUTOTEST_EXPORT QQuickMatrix4x4 : public QQuickTransform +class Q_QUICK_PRIVATE_EXPORT QQuickMatrix4x4 : public QQuickTransform { Q_OBJECT diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index e6bfde66ae8..a08f46a1b4b 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -436,12 +436,13 @@ void QQuickWindow::physicalDpiChanged() void QQuickWindow::handleScreenChanged(QScreen *screen) { Q_D(QQuickWindow); + // we connected to the initial screen in QQuickWindowPrivate::init, but the screen changed disconnect(d->physicalDpiChangedConnection); if (screen) { physicalDpiChanged(); // When physical DPI changes on the same screen, either the resolution or the device pixel // ratio changed. We must check what it is. Device pixel ratio does not have its own - // ...Changed() signal. + // ...Changed() signal. Reconnect, same as in QQuickWindowPrivate::init. d->physicalDpiChangedConnection = connect(screen, &QScreen::physicalDotsPerInchChanged, this, &QQuickWindow::physicalDpiChanged); } @@ -482,18 +483,14 @@ void forceUpdate(QQuickItem *item) forceUpdate(items.at(i)); } -void QQuickWindowRenderTarget::reset(QRhi *rhi, QSGRenderer *renderer) +void QQuickWindowRenderTarget::reset(QRhi *rhi) { - if (rhi) { - if (renderer) - renderer->invalidatePipelineCacheDependency(rpDesc); - if (owns) { - delete renderTarget; - delete rpDesc; - delete texture; - delete renderBuffer; - delete depthStencil; - } + if (rhi && owns) { + delete renderTarget; + delete rpDesc; + delete texture; + delete renderBuffer; + delete depthStencil; } renderTarget = nullptr; @@ -513,7 +510,7 @@ void QQuickWindowPrivate::ensureCustomRenderTarget() redirect.renderTargetDirty = false; - redirect.rt.reset(rhi, renderer); + redirect.rt.reset(rhi); // a default constructed QQuickRenderTarget means no redirection if (customRenderTarget.isNull()) @@ -722,7 +719,7 @@ QQuickWindowPrivate::QQuickWindowPrivate() QQuickWindowPrivate::~QQuickWindowPrivate() { inDestructor = true; - redirect.rt.reset(rhi, renderer); + redirect.rt.reset(rhi); if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>()) service->removeWindow(q_func()); deliveryAgent = nullptr; @@ -766,8 +763,13 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control) Q_ASSERT(windowManager || renderControl); - if (QScreen *screen = q->screen()) - devicePixelRatio = screen->devicePixelRatio(); + if (QScreen *screen = q->screen()) { + devicePixelRatio = screen->devicePixelRatio(); + // if the screen changes, then QQuickWindow::handleScreenChanged disconnects + // and connects to the new screen + physicalDpiChangedConnection = QObject::connect(screen, &QScreen::physicalDotsPerInchChanged, + q, &QQuickWindow::physicalDpiChanged); + } QSGContext *sg; if (renderControl) { @@ -878,14 +880,6 @@ void QQuickWindowPrivate::cleanup(QSGNode *n) The Window object creates a new top-level window for a Qt Quick scene. It automatically sets up the window for use with \c {QtQuick} graphical types. - To use this type, you will need to import the module with the following line: - \code - import QtQuick - \endcode - - Omitting this import will allow you to have a QML environment without - access to window system features. - A Window can be declared inside an Item or inside another Window; in that case the inner Window will automatically become "transient for" the outer Window: that is, most platforms will show it centered upon the outer window @@ -901,9 +895,23 @@ void QQuickWindowPrivate::cleanup(QSGNode *n) When the user attempts to close a window, the \l closing signal will be emitted. You can force the window to stay open (for example to prompt the - user to save changes) by writing an \c onClosing handler and setting - \c {close.accepted = false}. + user to save changes) by writing an \c onClosing handler that sets + \c {close.accepted = false} unless it's safe to close the window (for example, + because there are no more unsaved changes). + + \code + onClosing: (close) => { + if (document.changed) { + close.accepted = false + confirmExitPopup.open() + } + } + + // The confirmExitPopup allows user to save or discard the document, + // or to cancel the closing. + \endcode */ + /*! \class QQuickWindow \since 5.0 @@ -1088,7 +1096,11 @@ QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent) } /*! - \internal + Constructs a window for displaying a QML scene, whose rendering will + be controlled by the \a control object. + Please refer to QQuickRenderControl's documentation for more information. + + \since 5.4 */ QQuickWindow::QQuickWindow(QQuickRenderControl *control) : QWindow(*(new QQuickWindowPrivate), nullptr) @@ -1312,6 +1324,8 @@ QQuickItem *QQuickWindow::contentItem() const \brief The item which currently has active focus or \c null if there is no item with active focus. + + \sa QQuickItem::forceActiveFocus(), {Keyboard Focus in Qt Quick} */ QQuickItem *QQuickWindow::activeFocusItem() const { @@ -1343,6 +1357,38 @@ bool QQuickWindow::event(QEvent *e) // bypass QWindow::event dispatching of input events: deliveryAgent takes care of it QQuickDeliveryAgent *da = d->deliveryAgent; if (e->isPointerEvent()) { + /* + We can't bypass the virtual functions like mousePressEvent() tabletEvent() etc., + for the sake of code that subclasses QQuickWindow and overrides them, even though + we no longer need them as entry points for Qt Quick event delivery. + So dispatch to them now, ahead of normal delivery, and stop them from calling + back into this function if they were called from here (avoid recursion). + It could also be that user code expects them to work as entry points, too; + in that case, windowEventDispatch _won't_ be set, so the event comes here and + we'll dispatch it further below. + */ + if (d->windowEventDispatch) + return false; + { + const bool wasAccepted = e->isAccepted(); + QBoolBlocker windowEventDispatchGuard(d->windowEventDispatch, true); + qCDebug(lcPtr) << "dispatching to window functions in case of override" << e; + QWindow::event(e); + if (e->isAccepted() && !wasAccepted) + return true; + } + /* + QQuickWindow does not override touchEvent(). If the application has a subclass + of QQuickWindow which allows the event to remain accepted, it means they want + to stop propagation here, so return early (below). But otherwise we will call + QWindow::touchEvent(), which will ignore(); in that case, we need to continue + with the usual delivery below, so we need to undo the ignore(). + */ + auto pe = static_cast<QPointerEvent *>(e); + if (QQuickDeliveryAgentPrivate::isTouchEvent(pe)) + e->accept(); + // end of dispatch to user-overridden virtual window functions + /* When delivering update and release events to existing grabbers, use the subscene delivery agent, if any. A possible scenario: @@ -1356,7 +1402,6 @@ bool QQuickWindow::event(QEvent *e) With single-point events (mouse, or only one finger) it's simplified: there can only be one subscene of interest; for (pt : pe->points()) would only iterate once, so we might as well skip that logic. */ - auto pe = static_cast<QPointerEvent *>(e); if (pe->pointCount()) { if (QQuickDeliveryAgentPrivate::subsceneAgentsExist) { bool ret = false; @@ -1494,6 +1539,7 @@ bool QQuickWindow::event(QEvent *e) return true; break; case QEvent::LanguageChange: + case QEvent::LocaleChange: if (d->contentItem) QCoreApplication::sendEvent(d->contentItem, e); break; @@ -1512,6 +1558,10 @@ bool QQuickWindow::event(QEvent *e) case QEvent::WindowDeactivate: if (auto da = d->deliveryAgentPrivate()) da->handleWindowDeactivate(this); + Q_FALLTHROUGH(); + case QEvent::WindowActivate: + if (d->contentItem) + QCoreApplication::sendEvent(d->contentItem, e); break; default: break; @@ -1522,13 +1572,18 @@ bool QQuickWindow::event(QEvent *e) else if (e->type() == QEvent::Type(QQuickWindowPrivate::TriggerContextCreationFailure)) d->windowManager->handleContextCreationFailure(this); - return QWindow::event(e); + if (e->isPointerEvent()) + return true; + else + return QWindow::event(e); } /*! \reimp */ void QQuickWindow::keyPressEvent(QKeyEvent *e) { Q_D(QQuickWindow); + if (d->windowEventDispatch) + return; auto da = d->deliveryAgentPrivate(); Q_ASSERT(da); da->deliverKeyEvent(e); @@ -1538,6 +1593,8 @@ void QQuickWindow::keyPressEvent(QKeyEvent *e) void QQuickWindow::keyReleaseEvent(QKeyEvent *e) { Q_D(QQuickWindow); + if (d->windowEventDispatch) + return; auto da = d->deliveryAgentPrivate(); Q_ASSERT(da); da->deliverKeyEvent(e); @@ -1548,6 +1605,8 @@ void QQuickWindow::keyReleaseEvent(QKeyEvent *e) void QQuickWindow::wheelEvent(QWheelEvent *event) { Q_D(QQuickWindow); + if (d->windowEventDispatch) + return; auto da = d->deliveryAgentPrivate(); Q_ASSERT(da); da->deliverSinglePointEventUntilAccepted(event); @@ -1559,6 +1618,8 @@ void QQuickWindow::wheelEvent(QWheelEvent *event) void QQuickWindow::tabletEvent(QTabletEvent *event) { Q_D(QQuickWindow); + if (d->windowEventDispatch) + return; auto da = d->deliveryAgentPrivate(); Q_ASSERT(da); da->deliverPointerEvent(event); @@ -1569,6 +1630,8 @@ void QQuickWindow::tabletEvent(QTabletEvent *event) void QQuickWindow::mousePressEvent(QMouseEvent *event) { Q_D(QQuickWindow); + if (d->windowEventDispatch) + return; auto da = d->deliveryAgentPrivate(); Q_ASSERT(da); da->handleMouseEvent(event); @@ -1577,6 +1640,8 @@ void QQuickWindow::mousePressEvent(QMouseEvent *event) void QQuickWindow::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickWindow); + if (d->windowEventDispatch) + return; auto da = d->deliveryAgentPrivate(); Q_ASSERT(da); da->handleMouseEvent(event); @@ -1585,6 +1650,8 @@ void QQuickWindow::mouseMoveEvent(QMouseEvent *event) void QQuickWindow::mouseDoubleClickEvent(QMouseEvent *event) { Q_D(QQuickWindow); + if (d->windowEventDispatch) + return; auto da = d->deliveryAgentPrivate(); Q_ASSERT(da); da->handleMouseEvent(event); @@ -1593,6 +1660,8 @@ void QQuickWindow::mouseDoubleClickEvent(QMouseEvent *event) void QQuickWindow::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickWindow); + if (d->windowEventDispatch) + return; auto da = d->deliveryAgentPrivate(); Q_ASSERT(da); da->handleMouseEvent(event); @@ -1661,6 +1730,12 @@ QPair<QQuickItem*, QQuickPointerHandler*> QQuickWindowPrivate::findCursorItemAnd } #endif +void QQuickWindowPrivate::clearFocusObject() +{ + if (auto da = deliveryAgentPrivate()) + da->clearFocusObject(); +} + /*! \qmlproperty list<Object> Window::data \qmldefault @@ -1776,7 +1851,7 @@ void QQuickWindowPrivate::cleanupNodesOnShutdown(QQuickItem *item) p->dirty(QQuickItemPrivate::Window); } - // Qt 6: Make invalidateSceneGraph a virtual member of QQuickItem + // Qt 7: Make invalidateSceneGraph a virtual member of QQuickItem if (p->flags & QQuickItem::ItemHasContents) { const QMetaObject *mo = item->metaObject(); int index = mo->indexOfSlot("invalidateSceneGraph()"); @@ -1989,9 +2064,6 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item) // desired list is shorter. QSGNode *groupNode = itemPriv->childContainerNode(); QSGNode *currentNode = groupNode->firstChild(); - int added = 0; - int removed = 0; - int replaced = 0; QSGNode *desiredNode = nullptr; while (currentNode && (desiredNode = fetchNextNode(itemPriv, ii, fetchedPaintNode))) { @@ -2004,7 +2076,6 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item) desiredNode->parent()->removeChildNode(desiredNode); groupNode->insertChildNodeAfter(desiredNode, currentNode); groupNode->removeChildNode(currentNode); - replaced++; // since we just replaced currentNode, we also need to reset // the pointer. @@ -2023,7 +2094,6 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item) if (desiredNode->parent()) desiredNode->parent()->removeChildNode(desiredNode); groupNode->appendChildNode(desiredNode); - added++; } } else if (currentNode) { // on the other hand, if we processed less than our current node @@ -2033,7 +2103,6 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item) QSGNode *node = currentNode->nextSibling(); groupNode->removeChildNode(currentNode); currentNode = node; - removed++; } } } @@ -2479,7 +2548,7 @@ QImage QQuickWindow::grabWindow() { Q_D(QQuickWindow); - if (!isVisible() && !d->renderControl) { + if (!d->isRenderable() && !d->renderControl) { // backends like software can grab regardless of the window state if (d->windowManager && (d->windowManager->flags() & QSGRenderLoop::SupportsGrabWithoutExpose)) return d->windowManager->grab(this); @@ -3200,10 +3269,12 @@ void QQuickWindow::endExternalCommands() whether it's a dialog, popup, or a regular window, and whether it should have a title bar, etc. - The flags which you read from this property might differ from the ones + The flags that you read from this property might differ from the ones that you set if the requested flags could not be fulfilled. - \sa Qt::WindowFlags + \snippet qml/splashWindow.qml entire + + \sa Qt::WindowFlags, {Qt Quick Examples - Window and Screen} */ /*! @@ -3234,6 +3305,11 @@ void QQuickWindow::endExternalCommands() The (x,y) position is relative to the \l Screen if there is only one, or to the virtual desktop (arrangement of multiple screens). + \note Not all windowing systems support setting or querying top level + window positions. On such a system, programmatically moving windows + may not have any effect, and artificial values may be returned for + the current positions, such as \c QPoint(0, 0). + \qml Window { x: 100; y: 100; width: 100; height: 100 } \endqml @@ -3274,6 +3350,7 @@ void QQuickWindow::endExternalCommands() */ /*! + \keyword qml-window-visibility-prop \qmlproperty QWindow::Visibility Window::visibility The screen-occupation state of the window. @@ -3287,15 +3364,18 @@ void QQuickWindow::endExternalCommands() visibility property you will always get the actual state, never \c AutomaticVisibility. - When a window is not visible its visibility is Hidden, and setting + When a window is not visible, its visibility is \c Hidden, and setting visibility to \l {QWindow::}{Hidden} is the same as setting \l visible to \c false. - \sa visible + \snippet qml/windowVisibility.qml entire + + \sa visible, {Qt Quick Examples - Window and Screen} \since 5.1 */ /*! \qmlattachedproperty QWindow::Visibility Window::visibility + \readonly \since 5.4 This attached property holds whether the window is currently shown @@ -3303,7 +3383,7 @@ void QQuickWindow::endExternalCommands() hidden. The \c Window attached property can be attached to any Item. If the item is not shown in any window, the value will be \l {QWindow::}{Hidden}. - \sa visible, visibility + \sa visible, {qml-window-visibility-prop}{visibility} */ /*! @@ -3395,17 +3475,8 @@ void QQuickWindow::endExternalCommands() Item or Window within which it was declared, you can remove that relationship by setting \c transientParent to \c null: - \qml - import QtQuick.Window 2.13 - - Window { - // visible is false by default - Window { - transientParent: null - visible: true - } - } - \endqml + \snippet qml/nestedWindowTransientParent.qml 0 + \snippet qml/nestedWindowTransientParent.qml 1 In order to cause the window to be centered above its transient parent by default, depending on the window manager, it may also be necessary to set @@ -3451,6 +3522,9 @@ void QQuickWindow::endExternalCommands() The active status of the window. + \snippet qml/windowPalette.qml declaration-and-color + \snippet qml/windowPalette.qml closing-brace + \sa requestActivate() */ @@ -3464,14 +3538,7 @@ void QQuickWindow::endExternalCommands() Here is an example which changes a label to show the active state of the window in which it is shown: - \qml - import QtQuick 2.4 - import QtQuick.Window 2.2 - - Text { - text: Window.active ? "active" : "inactive" - } - \endqml + \snippet qml/windowActiveAttached.qml entire */ /*! @@ -3769,7 +3836,7 @@ QSGRendererInterface *QQuickWindow::rendererInterface() const graphics API based on the platform and other conditions, set \a api to QSGRendererInterface::Unknown. - \since 5.8 + \since 6.0 */ void QQuickWindow::setGraphicsApi(QSGRendererInterface::GraphicsApi api) { @@ -4071,7 +4138,7 @@ void QQuickWindow::setTextRenderType(QQuickWindow::TextRenderType renderType) /*! \since 6.0 - \qmlproperty QQuickPalette Window::palette + \qmlproperty Palette Window::palette This property holds the palette currently set for the window. @@ -4079,11 +4146,12 @@ void QQuickWindow::setTextRenderType(QQuickWindow::TextRenderType renderType) palette which serves as a default for all application windows. You can also set the default palette for windows by passing a custom palette to QGuiApplication::setPalette(), before loading any QML. - ApplicationWindow propagates explicit palette properties to child controls. If you change a specific - property on the window's palette, that property propagates to all child controls in the window, + Window propagates explicit palette properties to child items and controls, overriding any system defaults for that property. - \sa Item::palette, Popup::palette, QQuickColorGroup + \snippet qml/windowPalette.qml entire + + \sa Item::palette, Popup::palette, ColorGroup, SystemPalette //! internal \sa QQuickAbstractPaletteProvider, QQuickPalette */ diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index cd39bc13d35..48878b057d1 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -65,6 +65,7 @@ class QQuickRenderControl; class QSGRectangleNode; class QSGImageNode; class QSGNinePatchNode; +class QQuickPalette; class QQuickRenderTarget; class QQuickGraphicsDevice; class QQuickGraphicsConfiguration; @@ -76,6 +77,8 @@ class Q_QUICK_EXPORT QQuickWindow : public QWindow Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT) Q_PROPERTY(QQuickItem* activeFocusItem READ activeFocusItem NOTIFY activeFocusItemChanged REVISION(2, 1)) + Q_PRIVATE_PROPERTY(QQuickWindow::d_func(), QQuickPalette *palette READ palette WRITE setPalette + RESET resetPalette NOTIFY paletteChanged REVISION(6, 2)) QDOC_PROPERTY(QWindow* transientParent READ transientParent WRITE setTransientParent NOTIFY transientParentChanged) Q_CLASSINFO("DefaultProperty", "data") Q_DECLARE_PRIVATE(QQuickWindow) diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 73424242516..3b442499bb7 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -110,7 +110,7 @@ public Q_SLOTS: class QQuickWindowRenderTarget { public: - void reset(QRhi *rhi, QSGRenderer *renderer); + void reset(QRhi *rhi); QRhiRenderTarget *renderTarget = nullptr; QRhiRenderPassDescriptor *rpDesc = nullptr; QRhiTexture *texture = nullptr; @@ -161,6 +161,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowPrivate QPair<QQuickItem*, QQuickPointerHandler*> findCursorItemAndHandler(QQuickItem *item, const QPointF &scenePos) const; #endif + void clearFocusObject() override; + void dirtyItem(QQuickItem *); void cleanup(QSGNode *); @@ -249,9 +251,18 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowPrivate void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason) { deliveryAgentPrivate()->clearFocusInScope(scope, item, reason); } void handleTouchEvent(QTouchEvent *e) - { deliveryAgentPrivate()->handleTouchEvent(e); } + { + // setup currentEventDeliveryAgent like in QQuickDeliveryAgent::event + QQuickDeliveryAgentPrivate::currentEventDeliveryAgent = deliveryAgentPrivate()->q_func(); + deliveryAgentPrivate()->handleTouchEvent(e); + QQuickDeliveryAgentPrivate::currentEventDeliveryAgent = nullptr; + } void handleMouseEvent(QMouseEvent *e) - { deliveryAgentPrivate()->handleMouseEvent(e); } + { + QQuickDeliveryAgentPrivate::currentEventDeliveryAgent = deliveryAgentPrivate()->q_func(); + deliveryAgentPrivate()->handleMouseEvent(e); + QQuickDeliveryAgentPrivate::currentEventDeliveryAgent = nullptr; + } // ^^^ currently in use in Controls 2; TODO remove // data property @@ -287,6 +298,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowPrivate uint hasActiveSwapchain : 1; uint hasRenderableSwapchain : 1; uint swapchainJustBecameRenderable : 1; + bool windowEventDispatch = false; private: static void cleanupNodesOnShutdown(QQuickItem *); diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index 7d7cf202109..68e9d7df90b 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -69,6 +69,7 @@ void QQuickWindowQmlImpl::setVisible(bool visible) { Q_D(QQuickWindowQmlImpl); d->visible = visible; + d->visibleExplicitlySet = true; if (d->complete && (!transientParent() || transientParentVisible())) QQuickWindow::setVisible(visible); } @@ -148,7 +149,8 @@ void QQuickWindowQmlImpl::setWindowVisibility() // We have deferred window creation until we have the full picture of what // the user wanted in terms of window state, geometry, visibility, etc. - if ((d->visibility == Hidden && d->visible) || (d->visibility > AutomaticVisibility && !d->visible)) { + if (d->visibleExplicitlySet && ((d->visibility == Hidden && d->visible) || + (d->visibility > AutomaticVisibility && !d->visible))) { QQmlData *data = QQmlData::get(this); Q_ASSERT(data && data->context); diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h index 7177469b55a..c1cd48f964e 100644 --- a/src/quick/items/qquickwindowmodule_p.h +++ b/src/quick/items/qquickwindowmodule_p.h @@ -74,7 +74,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImpl : public QQuickWindow, public Q Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) - Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged) + Q_PROPERTY(QWindow::Visibility visibility READ visibility WRITE setVisibility NOTIFY + visibilityChanged) Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION(2, 3)) QML_ATTACHED(QQuickWindowAttached) QML_NAMED_ELEMENT(Window) @@ -84,7 +85,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImpl : public QQuickWindow, public Q QQuickWindowQmlImpl(QWindow *parent = nullptr); void setVisible(bool visible); - void setVisibility(Visibility visibility); + void setVisibility(QWindow::Visibility visibility); QObject *screen() const; void setScreen(QObject *screen); diff --git a/src/quick/items/qquickwindowmodule_p_p.h b/src/quick/items/qquickwindowmodule_p_p.h index 4e94a4e43de..cce893ac256 100644 --- a/src/quick/items/qquickwindowmodule_p_p.h +++ b/src/quick/items/qquickwindowmodule_p_p.h @@ -62,6 +62,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImplPrivate : public QQuickWindowPri bool complete = false; bool visible = false; + bool visibleExplicitlySet = false; QQuickWindow::Visibility visibility = QQuickWindow::AutomaticVisibility; QV4::PersistentValue rootItemMarker; }; diff --git a/src/quick/qtquickglobal_p.h b/src/quick/qtquickglobal_p.h index 797d9f169a9..0ef394e7390 100644 --- a/src/quick/qtquickglobal_p.h +++ b/src/quick/qtquickglobal_p.h @@ -72,6 +72,36 @@ Q_DECLARE_LOGGING_CATEGORY(lcMouse) Q_DECLARE_LOGGING_CATEGORY(lcFocus) Q_DECLARE_LOGGING_CATEGORY(lcDirty) +/* + This is needed for QuickTestUtils. Q_AUTOTEST_EXPORT checks QT_BUILDING_QT + (amongst others) to see if it should export symbols. Until QuickTestUtils + was introduced, this was enough, as there weren't any intermediate test + helper libraries that used a Qt library and were in turn used by tests. + + Taking QQuickItemViewPrivate as an example: previously it was using + Q_AUTOTEST_EXPORT. Since QuickTestUtils is a Qt library (albeit a private + one), QT_BUILDING_QT was true and so Q_AUTOTEST_EXPORT evaluated to an + export. However, QQuickItemViewPrivate was already exported by the Quick + library, so we would get errors like this: + + Qt6Quickd.lib(Qt6Quickd.dll) : error LNK2005: "public: static class + QQuickItemViewPrivate * __cdecl QQuickItemViewPrivate::get(class QQuickItemView *)" + (?get@QQuickItemViewPrivate@@SAPEAV1@PEAVQQuickItemView@@@Z) already defined + in Qt6QuickTestUtilsd.lib(viewtestutils.cpp.obj) + + So, to account for the special case of QuickTestUtils, we need to be more + specific about which part of Qt we're building; instead of checking if we're + building any Qt library at all, check if we're building the Quick library, + and only then export. +*/ +#if defined(QT_BUILD_INTERNAL) && defined(QT_BUILD_QUICK_LIB) && defined(QT_SHARED) +# define Q_QUICK_AUTOTEST_EXPORT Q_DECL_EXPORT +#elif defined(QT_BUILD_INTERNAL) && defined(QT_SHARED) +# define Q_QUICK_AUTOTEST_EXPORT Q_DECL_IMPORT +#else +# define Q_QUICK_AUTOTEST_EXPORT +#endif + QT_END_NAMESPACE #endif // QTQUICKGLOBAL_P_H diff --git a/src/quick/qtquickplugin.cpp b/src/quick/qtquickplugin.cpp index e4ceee15a9b..eeca8eac5e6 100644 --- a/src/quick/qtquickplugin.cpp +++ b/src/quick/qtquickplugin.cpp @@ -42,6 +42,9 @@ QT_BEGIN_NAMESPACE +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick); +Q_GHS_KEEP_REFERENCE(QQuick_initializeModule); + class QtQuick2Plugin : public QQmlEngineExtensionPlugin { Q_OBJECT diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp index 4ddef6b4c27..a9299ff17e2 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp @@ -143,6 +143,18 @@ void QSGSoftwareRenderContext::initializeIfNeeded() void QSGSoftwareRenderContext::invalidate() { + qDeleteAll(m_texturesToDelete); + m_texturesToDelete.clear(); + + qDeleteAll(m_textures); + m_textures.clear(); + + qDeleteAll(m_fontEnginesToClean); + m_fontEnginesToClean.clear(); + + qDeleteAll(m_glyphCaches); + m_glyphCaches.clear(); + m_sg->renderContextInvalidated(this); emit invalidated(); } diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp index e76baaa632e..30b4d7aa477 100644 --- a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp @@ -173,3 +173,5 @@ QSGTexture *Texture::removedFromAtlas(QRhiResourceUpdateBatch *) const } QT_END_NAMESPACE + +#include "moc_qsgcompressedatlastexture_p.cpp" diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp index 46dc6c5507c..d5d22f3677c 100644 --- a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp @@ -377,19 +377,20 @@ void QSGCompressedTexture::commitTextureOperations(QRhi *rhi, QRhiResourceUpdate return; } - QRhiTexture::Flags texFlags; - if (fmt.isSRGB) - texFlags |= QRhiTexture::sRGB; + if (!m_texture) { + QRhiTexture::Flags texFlags; + if (fmt.isSRGB) + texFlags |= QRhiTexture::sRGB; - if (!rhi->isTextureFormatSupported(fmt.rhiFormat, texFlags)) { - qWarning("Unsupported compressed format 0x%x", m_textureData.glInternalFormat()); - return; - } + if (!rhi->isTextureFormatSupported(fmt.rhiFormat, texFlags)) { + qCDebug(QSG_LOG_TEXTUREIO, "Compressed texture format possibly unsupported: 0x%x", + m_textureData.glInternalFormat()); + } - if (!m_texture) { m_texture = rhi->newTexture(fmt.rhiFormat, m_size, 1, texFlags); if (!m_texture->create()) { - qWarning("Failed to create QRhiTexture for compressed data"); + qWarning("Failed to create QRhiTexture for compressed data with format 0x%x", + m_textureData.glInternalFormat()); delete m_texture; m_texture = nullptr; return; @@ -466,3 +467,5 @@ QSize QSGCompressedTextureFactory::textureSize() const } QT_END_NAMESPACE + +#include "moc_qsgcompressedtexture_p.cpp" diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp b/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp index 6f14d5abff3..05a952bc9f6 100644 --- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp @@ -377,3 +377,5 @@ void QSGAbstractRenderer::renderSceneInline() } QT_END_NAMESPACE + +#include "moc_qsgabstractrenderer_p.cpp" diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 6d6b2aca234..ab70d8e09fb 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -299,23 +299,23 @@ void ShaderManager::invalidated() qDeleteAll(rewrittenShaders); rewrittenShaders.clear(); - qDeleteAll(srbCache); - srbCache.clear(); - qDeleteAll(pipelineCache); pipelineCache.clear(); + + qDeleteAll(srbPool); + srbPool.clear(); } void ShaderManager::clearCachedRendererData() { - for (ShaderManager::Shader *sms : stockShaders) { + for (ShaderManager::Shader *sms : qAsConst(stockShaders)) { QSGMaterialShader *s = sms->programRhi.program; if (s) { QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s); sd->clearCachedRendererData(); } } - for (ShaderManager::Shader *sms : rewrittenShaders) { + for (ShaderManager::Shader *sms : qAsConst(rewrittenShaders)) { QSGMaterialShader *s = sms->programRhi.program; if (s) { QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s); @@ -324,24 +324,6 @@ void ShaderManager::clearCachedRendererData() } } -QRhiShaderResourceBindings *ShaderManager::srb(const ShaderResourceBindingList &bindings) -{ - auto it = srbCache.constFind(bindings); - if (it != srbCache.constEnd()) - return *it; - - QRhiShaderResourceBindings *srb = context->rhi()->newShaderResourceBindings(); - srb->setBindings(bindings.cbegin(), bindings.cend()); - if (srb->create()) { - srbCache.insert(bindings, srb); - } else { - qWarning("Failed to build srb"); - delete srb; - srb = nullptr; - } - return srb; -} - void qsg_dumpShadowRoots(BatchRootInfo *i, int indent) { static int extraIndent = 0; @@ -918,7 +900,7 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx, QSGRendererInterface::RenderMod // The shader manager is shared between renderers (think for example Item // layers that create a new Renderer each) with the same rendercontext (and // so same QRhi). - m_shaderManager = ctx->findChild<ShaderManager *>(QStringLiteral("__qt_ShaderManager"), Qt::FindDirectChildrenOnly); + m_shaderManager = ctx->findChild<ShaderManager *>(QString(), Qt::FindDirectChildrenOnly); if (!m_shaderManager) { m_shaderManager = new ShaderManager(ctx); m_shaderManager->setObjectName(QStringLiteral("__qt_ShaderManager")); @@ -928,17 +910,17 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx, QSGRendererInterface::RenderMod m_batchNodeThreshold = qt_sg_envInt("QSG_RENDERER_BATCH_NODE_THRESHOLD", 64); m_batchVertexThreshold = qt_sg_envInt("QSG_RENDERER_BATCH_VERTEX_THRESHOLD", 1024); + m_srbPoolThreshold = qt_sg_envInt("QSG_RENDERER_SRB_POOL_THRESHOLD", 1024); if (Q_UNLIKELY(debug_build() || debug_render())) { - qDebug("Batch thresholds: nodes: %d vertices: %d", - m_batchNodeThreshold, m_batchVertexThreshold); + qDebug("Batch thresholds: nodes: %d vertices: %d Srb pool threshold: %d", + m_batchNodeThreshold, m_batchVertexThreshold, m_srbPoolThreshold); } } static void qsg_wipeBuffer(Buffer *buffer) { - if (buffer->buf) - delete buffer->buf; + delete buffer->buf; // The free here is ok because we're in one of two situations. // 1. We're using the upload pool in which case unmap will have set the @@ -961,11 +943,6 @@ static void qsg_wipeBatch(Batch *batch, bool separateIndexBuffer) Renderer::~Renderer() { if (m_rhi) { - // If setExternalRenderPassDescriptor() was called, we have to - // aggressively invalidate to prevent an object, the lifetime of which - // we have no control over, staying in the (per-window) caches. - invalidatePipelineCacheDependency(m_external_rp_desc); - // Clean up batches and buffers const bool separateIndexBuffer = m_context->separateIndexBuffer(); for (int i = 0; i < m_opaqueBatches.size(); ++i) @@ -976,17 +953,18 @@ Renderer::~Renderer() qsg_wipeBatch(m_batchPool.at(i), separateIndexBuffer); } - for (Node *n : qAsConst(m_nodes)) + for (Node *n : qAsConst(m_nodes)) { + if (n->type() == QSGNode::GeometryNodeType) { + Element *e = n->element(); + if (!e->removed) + m_elementsToDelete.add(e); + } m_nodeAllocator.release(n); + } // Remaining elements... - for (int i=0; i<m_elementsToDelete.size(); ++i) { - Element *e = m_elementsToDelete.at(i); - if (e->isRenderNode) - delete static_cast<RenderNodeElement *>(e); - else - m_elementAllocator.release(e); - } + for (int i=0; i<m_elementsToDelete.size(); ++i) + releaseElement(m_elementsToDelete.at(i), true); destroyGraphicsResources(); @@ -1017,6 +995,9 @@ void Renderer::releaseCachedResources() m_dummyTexture = nullptr; m_rhi->releaseCachedResources(); + + m_vertexUploadPool.resize(0); + m_indexUploadPool.resize(0); } void Renderer::invalidateAndRecycleBatch(Batch *b) @@ -1055,8 +1036,11 @@ void Renderer::unmap(Buffer *buffer, bool isIndexBuf) buffer->buf = m_rhi->newBuffer(QRhiBuffer::Immutable, isIndexBuf ? QRhiBuffer::IndexBuffer : QRhiBuffer::VertexBuffer, buffer->size); - if (!buffer->buf->create()) + if (!buffer->buf->create()) { qWarning("Failed to build vertex/index buffer of size %d", buffer->size); + delete buffer->buf; + buffer->buf = nullptr; + } } else { bool needsRebuild = false; if (buffer->buf->size() < buffer->size) { @@ -1070,16 +1054,23 @@ void Renderer::unmap(Buffer *buffer, bool isIndexBuf) buffer->nonDynamicChangeCount = 0; needsRebuild = true; } - if (needsRebuild) - buffer->buf->create(); + if (needsRebuild) { + if (!buffer->buf->create()) { + qWarning("Failed to (re)build vertex/index buffer of size %d", buffer->size); + delete buffer->buf; + buffer->buf = nullptr; + } + } } - if (buffer->buf->type() != QRhiBuffer::Dynamic) { - m_resourceUpdates->uploadStaticBuffer(buffer->buf, - 0, buffer->size, buffer->data); - buffer->nonDynamicChangeCount += 1; - } else { - m_resourceUpdates->updateDynamicBuffer(buffer->buf, 0, buffer->size, - buffer->data); + if (buffer->buf) { + if (buffer->buf->type() != QRhiBuffer::Dynamic) { + m_resourceUpdates->uploadStaticBuffer(buffer->buf, + 0, buffer->size, buffer->data); + buffer->nonDynamicChangeCount += 1; + } else { + m_resourceUpdates->updateDynamicBuffer(buffer->buf, 0, buffer->size, + buffer->data); + } } if (m_visualizer->mode() == Visualizer::VisualizeNothing) buffer->data = nullptr; @@ -2629,10 +2620,29 @@ static inline bool needsBlendConstant(QRhiGraphicsPipeline::BlendFactor f) bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms, bool depthPostPass) { - // In unmerged batches the srbs in the elements are all compatible - // layout-wise. Note the key's == and qHash implementations: the rp desc and - // srb are tested for (layout) compatibility, not pointer equality. - const GraphicsPipelineStateKey k { m_gstate, sms, renderPassDescriptor(), e->srb }; + // Note the key's == and qHash implementations: the renderpass descriptor + // and srb are tested for compatibility, not pointer equality. + // + // We do not store the srb pointer itself because the ownership stays with + // the Element and that can go away more often that we would like it + // to. (think scrolling a list view, constantly dropping and creating new + // nodes) Rather, use an opaque blob of a few uints and store and compare + // that. This works because once the pipeline is built, we will always call + // setShaderResources with an explicitly specified srb which is fine even if + // e->srb we used here to bake the pipeline is already gone by that point. + // + // A typical QSGMaterial's serialized srb layout is 8 uints. (uniform buffer + // + texture, 4 fields each) Regardless, using an implicitly shared + // container is essential here. (won't detach so no more allocs and copies + // are done, unless the Element decides to rebake the srb with a different + // layout - but then the detach is exactly what we need) + // + // Same story for the renderpass descriptor: the object can go away but + // that's fine because that has no effect on an already built pipeline, and + // for comparison we only rely on the serialized blob in order decide if the + // render target is compatible with the pipeline. + + const GraphicsPipelineStateKey k = GraphicsPipelineStateKey::create(m_gstate, sms, renderPassDescriptor(), e->srb); // Note: dynamic state (viewport rect, scissor rect, stencil ref, blend // constant) is never a part of GraphicsState/QRhiGraphicsPipeline. @@ -2826,8 +2836,8 @@ static void materialToRendererGraphicsState(GraphicsState *dst, void Renderer::updateMaterialDynamicData(ShaderManager::Shader *sms, QSGMaterialShader::RenderState &renderState, QSGMaterial *material, - ShaderManager::ShaderResourceBindingList *bindings, const Batch *batch, + Element *e, int ubufOffset, int ubufRegionSize) { @@ -2835,6 +2845,8 @@ void Renderer::updateMaterialDynamicData(ShaderManager::Shader *sms, QSGMaterialShader *shader = sms->programRhi.program; QSGMaterialShaderPrivate *pd = QSGMaterialShaderPrivate::get(shader); + QVarLengthArray<QRhiShaderResourceBinding, 8> bindings; + if (pd->ubufBinding >= 0) { m_current_uniform_data = &pd->masterUniformData; const bool changed = shader->updateUniformData(renderState, material, m_currentMaterial); @@ -2843,11 +2855,11 @@ void Renderer::updateMaterialDynamicData(ShaderManager::Shader *sms, if (changed || !batch->ubufDataValid) m_resourceUpdates->updateDynamicBuffer(batch->ubuf, ubufOffset, ubufRegionSize, pd->masterUniformData.constData()); - bindings->append(QRhiShaderResourceBinding::uniformBuffer(pd->ubufBinding, - pd->ubufStages, - batch->ubuf, - ubufOffset, - ubufRegionSize)); + bindings.append(QRhiShaderResourceBinding::uniformBuffer(pd->ubufBinding, + pd->ubufStages, + batch->ubuf, + ubufOffset, + ubufRegionSize)); } for (int binding = 0; binding < QSGMaterialShaderPrivate::MAX_SHADER_RESOURCE_BINDINGS; ++binding) { @@ -2901,17 +2913,92 @@ void Renderer::updateMaterialDynamicData(ShaderManager::Shader *sms, if (!texture) texture = dummyTexture(); QRhiSampler *sampler = pd->samplerBindingTable[binding]; - bindings->append(QRhiShaderResourceBinding::sampledTexture(binding, - stages, - texture, - sampler)); + bindings.append(QRhiShaderResourceBinding::sampledTexture(binding, + stages, + texture, + sampler)); } } #ifndef QT_NO_DEBUG - if (bindings->isEmpty()) + if (bindings.isEmpty()) qWarning("No shader resources for material %p, this is odd.", material); #endif + + enum class SrbAction { + Unknown, + DoNothing, + UpdateResources, + Rebake + } srbAction = SrbAction::Unknown; + + // First, if the Element has no srb created at all, then try to find an existing, + // currently unused srb that is layout-compatible with our binding list. + if (!e->srb) { + // reuse a QVector as our work area, thus possibly reusing the underlying allocation too + QVector<quint32> &layoutDesc(m_shaderManager->srbLayoutDescSerializeWorkspace); + layoutDesc.clear(); + QRhiShaderResourceBinding::serializeLayoutDescription(bindings.cbegin(), bindings.cend(), std::back_inserter(layoutDesc)); + e->srb = m_shaderManager->srbPool.take(layoutDesc); + if (e->srb) { + // Here we know layout compatibility is satisfied, but do not spend time on full + // comparison. The chance of getting an srb that refers to the same resources + // (buffer, textures) is low in practice. So reuse, but write new resources. + srbAction = SrbAction::UpdateResources; + } + } + + // If the Element had an existing srb, investigate: + // - It may be used as-is (when nothing changed in the scene regarding this node compared to the previous frame). + // - Otherwise it may be able to go with a lightweight update (replace resources, binding list layout is the same). + // - If all else fails rebake the full thing, meaning we reuse the memory allocation but will recreate everything underneath. + if (srbAction == SrbAction::Unknown && e->srb) { + if (std::equal(e->srb->cbeginBindings(), e->srb->cendBindings(), bindings.cbegin(), bindings.cend())) { + srbAction = SrbAction::DoNothing; + } else if (std::equal(e->srb->cbeginBindings(), e->srb->cendBindings(), bindings.cbegin(), bindings.cend(), + [](const auto &a, const auto &b) { return a.isLayoutCompatible(b); })) + { + srbAction = SrbAction::UpdateResources; + } else { + srbAction = SrbAction::Rebake; + } + } + + // If the Element had no srb associated at all and could not find a layout-compatible + // one from the pool, then create a whole new object. + if (!e->srb) { + e->srb = m_rhi->newShaderResourceBindings(); + srbAction = SrbAction::Rebake; + } + + Q_ASSERT(srbAction != SrbAction::Unknown && e->srb); + + switch (srbAction) { + case SrbAction::DoNothing: + break; + case SrbAction::UpdateResources: + { + e->srb->setBindings(bindings.cbegin(), bindings.cend()); + QRhiShaderResourceBindings::UpdateFlags flags; + // Due to the way the binding list is built up above, if we have a uniform buffer + // at binding point 0 (or none at all) then the sampledTexture bindings are added + // with increasing binding points afterwards, so the list is already sorted based + // on the binding points, thus we can save some time by telling the QRhi backend + // not to sort again. + if (pd->ubufBinding <= 0 || bindings.count() <= 1) + flags |= QRhiShaderResourceBindings::BindingsAreSorted; + + e->srb->updateResources(flags); + } + break; + case SrbAction::Rebake: + e->srb->setBindings(bindings.cbegin(), bindings.cend()); + if (!e->srb->create()) + qWarning("Failed to build srb"); + break; + default: + Q_ASSERT_X(false, "updateMaterialDynamicData", "No srb action set, this cannot happen"); + } } void Renderer::updateMaterialStaticData(ShaderManager::Shader *sms, @@ -3029,8 +3116,7 @@ bool Renderer::prepareRenderMergedBatch(Batch *batch, PreparedRenderBatch *rende bool pendingGStatePop = false; updateMaterialStaticData(sms, renderState, material, batch, &pendingGStatePop); - ShaderManager::ShaderResourceBindingList bindings; - updateMaterialDynamicData(sms, renderState, material, &bindings, batch, 0, ubufSize); + updateMaterialDynamicData(sms, renderState, material, batch, e, 0, ubufSize); #ifndef QT_NO_DEBUG if (qsg_test_and_clear_material_failure()) { @@ -3045,8 +3131,6 @@ bool Renderer::prepareRenderMergedBatch(Batch *batch, PreparedRenderBatch *rende } #endif - e->srb = m_shaderManager->srb(bindings); - m_gstate.drawMode = QSGGeometry::DrawingMode(g->drawingMode()); m_gstate.lineWidth = g->lineWidth(); @@ -3103,6 +3187,9 @@ void Renderer::checkLineWidth(QSGGeometry *g) void Renderer::renderMergedBatch(PreparedRenderBatch *renderBatch, bool depthPostPass) { const Batch *batch = renderBatch->batch; + if (!batch->vbo.buf || !batch->ibo.buf) + return; + Element *e = batch->first; QSGGeometryNode *gn = e->node; QSGGeometry *g = gn->geometry(); @@ -3164,7 +3251,7 @@ bool Renderer::prepareRenderUnmergedBatch(Batch *batch, PreparedRenderBatch *ren // unmerged batch since the material (and so the shaders) is the same. QSGGeometry *g = gn->geometry(); QSGMaterial *material = gn->activeMaterial(); - ShaderManager::Shader *sms = m_shaderManager->prepareMaterialNoRewrite(material, g); + ShaderManager::Shader *sms = m_shaderManager->prepareMaterialNoRewrite(material, g, m_renderMode); if (!sms) return false; @@ -3232,9 +3319,7 @@ bool Renderer::prepareRenderUnmergedBatch(Batch *batch, PreparedRenderBatch *ren } QSGMaterialShader::RenderState renderState = state(QSGMaterialShader::RenderState::DirtyStates(int(dirty))); - ShaderManager::ShaderResourceBindingList bindings; - updateMaterialDynamicData(sms, renderState, - material, &bindings, batch, ubufOffset, ubufSize); + updateMaterialDynamicData(sms, renderState, material, batch, e, ubufOffset, ubufSize); #ifndef QT_NO_DEBUG if (qsg_test_and_clear_material_failure()) { @@ -3246,8 +3331,6 @@ bool Renderer::prepareRenderUnmergedBatch(Batch *batch, PreparedRenderBatch *ren } #endif - e->srb = m_shaderManager->srb(bindings); - ubufOffset += aligned(ubufSize, m_ubufAlignment); const QSGGeometry::DrawingMode prevDrawMode = m_gstate.drawMode; @@ -3302,8 +3385,10 @@ bool Renderer::prepareRenderUnmergedBatch(Batch *batch, PreparedRenderBatch *ren void Renderer::renderUnmergedBatch(PreparedRenderBatch *renderBatch, bool depthPostPass) { const Batch *batch = renderBatch->batch; + if (!batch->vbo.buf) + return; + Element *e = batch->first; - QSGGeometryNode *gn = e->node; if (batch->clipState.type & ClipState::StencilClip) enqueueStencilDraw(batch); @@ -3313,8 +3398,7 @@ void Renderer::renderUnmergedBatch(PreparedRenderBatch *renderBatch, bool depthP QRhiCommandBuffer *cb = commandBuffer(); while (e) { - gn = e->node; - QSGGeometry *g = gn->geometry(); + QSGGeometry *g = e->node->geometry(); checkLineWidth(g); const int effectiveIndexSize = m_uint32IndexForRhi ? sizeof(quint32) : g->sizeOfIndex(); @@ -3322,11 +3406,13 @@ void Renderer::renderUnmergedBatch(PreparedRenderBatch *renderBatch, bool depthP const QRhiCommandBuffer::VertexInput vbufBinding(batch->vbo.buf, vOffset); if (g->indexCount()) { - cb->setVertexInput(VERTEX_BUFFER_BINDING, 1, &vbufBinding, - batch->ibo.buf, iOffset, - effectiveIndexSize == sizeof(quint32) ? QRhiCommandBuffer::IndexUInt32 - : QRhiCommandBuffer::IndexUInt16); - cb->drawIndexed(g->indexCount()); + if (batch->ibo.buf) { + cb->setVertexInput(VERTEX_BUFFER_BINDING, 1, &vbufBinding, + batch->ibo.buf, iOffset, + effectiveIndexSize == sizeof(quint32) ? QRhiCommandBuffer::IndexUInt32 + : QRhiCommandBuffer::IndexUInt16); + cb->drawIndexed(g->indexCount()); + } } else { cb->setVertexInput(VERTEX_BUFFER_BINDING, 1, &vbufBinding); cb->draw(g->vertexCount()); @@ -3372,6 +3458,26 @@ void Renderer::setGraphicsPipeline(QRhiCommandBuffer *cb, const Batch *batch, El cb->setShaderResources(e->srb); } +void Renderer::releaseElement(Element *e, bool inDestructor) +{ + if (e->isRenderNode) { + delete static_cast<RenderNodeElement *>(e); + } else { + if (e->srb) { + if (!inDestructor) { + if (m_shaderManager->srbPool.count() < m_srbPoolThreshold) + m_shaderManager->srbPool.insert(e->srb->serializedLayoutDescription(), e->srb); + else + delete e->srb; + } else { + delete e->srb; + } + e->srb = nullptr; + } + m_elementAllocator.release(e); + } +} + void Renderer::deleteRemovedElements() { if (!m_elementsToDelete.size()) @@ -3388,13 +3494,9 @@ void Renderer::deleteRemovedElements() *e = nullptr; } - for (int i=0; i<m_elementsToDelete.size(); ++i) { - Element *e = m_elementsToDelete.at(i); - if (e->isRenderNode) - delete static_cast<RenderNodeElement *>(e); - else - m_elementAllocator.release(e); - } + for (int i=0; i<m_elementsToDelete.size(); ++i) + releaseElement(m_elementsToDelete.at(i)); + m_elementsToDelete.reset(); } @@ -3903,22 +4005,6 @@ bool Renderer::hasVisualizationModeWithContinuousUpdate() const return m_visualizer->mode() == Visualizer::VisualizeOverdraw; } -void Renderer::invalidatePipelineCacheDependency(QRhiRenderPassDescriptor *rpDesc) -{ - if (!rpDesc) - return; - - for (auto it = m_shaderManager->pipelineCache.begin(); it != m_shaderManager->pipelineCache.end(); ) { - if (it.key().compatibleRenderPassDescriptor == rpDesc) { - QRhiGraphicsPipeline *ps = it.value(); - it = m_shaderManager->pipelineCache.erase(it); - ps->deleteLater(); // QRhi takes care of it in endFrame() - } else { - ++it; - } - } -} - bool operator==(const GraphicsState &a, const GraphicsState &b) noexcept { return a.depthTest == b.depthTest @@ -3960,8 +4046,8 @@ bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKe { return a.state == b.state && a.sms->programRhi.program == b.sms->programRhi.program - && a.compatibleRenderPassDescriptor->isCompatible(b.compatibleRenderPassDescriptor) - && a.layoutCompatibleSrb->isLayoutCompatible(b.layoutCompatibleSrb); + && a.renderTargetDescription == b.renderTargetDescription + && a.srbLayoutDescription == b.srbLayoutDescription; } bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) noexcept @@ -3971,8 +4057,10 @@ bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKe size_t qHash(const GraphicsPipelineStateKey &k, size_t seed) noexcept { - // no srb and rp included due to their special comparison semantics and lack of hash keys - return qHash(k.state, seed) + qHash(k.sms->programRhi.program, seed); + return qHash(k.state, seed) + ^ qHash(k.sms->programRhi.program) + ^ k.extra.renderTargetDescriptionHash + ^ k.extra.srbLayoutDescriptionHash; } Visualizer::Visualizer(Renderer *renderer) diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index a42c41304f7..241f5748b66 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -652,8 +652,21 @@ struct GraphicsPipelineStateKey { GraphicsState state; const ShaderManagerShader *sms; - const QRhiRenderPassDescriptor *compatibleRenderPassDescriptor; - const QRhiShaderResourceBindings *layoutCompatibleSrb; + QVector<quint32> renderTargetDescription; + QVector<quint32> srbLayoutDescription; + struct { + size_t renderTargetDescriptionHash; + size_t srbLayoutDescriptionHash; + } extra; + static GraphicsPipelineStateKey create(const GraphicsState &state, + const ShaderManagerShader *sms, + const QRhiRenderPassDescriptor *rpDesc, + const QRhiShaderResourceBindings *srb) + { + const QVector<quint32> rtDesc = rpDesc->serializedFormat(); + const QVector<quint32> srbDesc = srb->serializedLayoutDescription(); + return { state, sms, rtDesc, srbDesc, { qHash(rtDesc), qHash(srbDesc) } }; + } }; bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) noexcept; @@ -687,11 +700,11 @@ class ShaderManager : public QObject void clearCachedRendererData(); - using ShaderResourceBindingList = QVarLengthArray<QRhiShaderResourceBinding, 8>; - QRhiShaderResourceBindings *srb(const ShaderResourceBindingList &bindings); - QHash<GraphicsPipelineStateKey, QRhiGraphicsPipeline *> pipelineCache; + QMultiHash<QVector<quint32>, QRhiShaderResourceBindings *> srbPool; + QVector<quint32> srbLayoutDescSerializeWorkspace; + public Q_SLOTS: void invalidated(); @@ -705,8 +718,6 @@ public Q_SLOTS: QHash<ShaderKey, Shader *> stockShaders; QSGDefaultRenderContext *context; - - QHash<ShaderResourceBindingList, QRhiShaderResourceBindings *> srbCache; }; struct RenderPassState @@ -822,8 +833,7 @@ class Q_QUICK_PRIVATE_EXPORT Renderer : public QSGRenderer bool ensurePipelineState(Element *e, const ShaderManager::Shader *sms, bool depthPostPass = false); QRhiTexture *dummyTexture(); void updateMaterialDynamicData(ShaderManager::Shader *sms, QSGMaterialShader::RenderState &renderState, - QSGMaterial *material, ShaderManager::ShaderResourceBindingList *bindings, - const Batch *batch, int ubufOffset, int ubufRegionSize); + QSGMaterial *material, const Batch *batch, Element *e, int ubufOffset, int ubufRegionSize); void updateMaterialStaticData(ShaderManager::Shader *sms, QSGMaterialShader::RenderState &renderState, QSGMaterial *material, Batch *batch, bool *gstateChanged); void checkLineWidth(QSGGeometry *g); @@ -858,12 +868,11 @@ class Q_QUICK_PRIVATE_EXPORT Renderer : public QSGRenderer inline Batch *newBatch(); void invalidateAndRecycleBatch(Batch *b); + void releaseElement(Element *e, bool inDestructor = false); void setVisualizationMode(const QByteArray &mode) override; bool hasVisualizationModeWithContinuousUpdate() const override; - void invalidatePipelineCacheDependency(QRhiRenderPassDescriptor *rpDesc) override; - QSGDefaultRenderContext *m_context; QSGRendererInterface::RenderMode m_renderMode; QSet<Node *> m_taggedRoots; @@ -893,6 +902,7 @@ class Q_QUICK_PRIVATE_EXPORT Renderer : public QSGRenderer int m_batchNodeThreshold; int m_batchVertexThreshold; + int m_srbPoolThreshold; Visualizer *m_visualizer; diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp index c8ecf49767d..571cdf806de 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.cpp +++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp @@ -406,8 +406,10 @@ const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_ColoredPoint2D() Geometry objects are constructed by default with DrawTriangleStrip as the drawing mode. - The attribute structure is assumed to be POD and the geometry object - assumes this will not go away. There is no memory management involved. + \note \a attributes and the \l Attribute objects referenced by it must + stay valid for the entire lifetime of the QSGGeometry. + QSGGeometry stores a reference to \a attributes and does not delete + the \l Attribute objects. */ QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes, @@ -530,13 +532,18 @@ const void *QSGGeometry::indexData() const Specifies the drawing mode, also called primitive topology. + \note Starting with Qt 6 the scene graph only exposes topologies that are + supported across all the supported 3D graphics APIs. As a result, the + values \c DrawLineLoop and \c DrawTriangleFan are no longer supported at + run time in Qt 6, even though the enum values themselves are still present. + \value DrawPoints \value DrawLines - \value DrawLineLoop + \omitvalue DrawLineLoop \value DrawLineStrip \value DrawTriangles \value DrawTriangleStrip - \value DrawTriangleFan + \omitvalue DrawTriangleFan */ /*! @@ -570,10 +577,10 @@ void QSGGeometry::setDrawingMode(unsigned int mode) } /*! - Gets the current line or point width or to be used for this - geometry. This property only applies to line width when the drawingMode - is DrawLines, DarwLineStrip, or DrawLineLoop. When supported, it also - applies to point size when the drawingMode is DrawPoints. + Gets the current line or point width or to be used for this geometry. This + property only applies to line width when the drawingMode is DrawLines or + DrawLineStrip. When supported, it also applies to point size when the + drawingMode is DrawPoints. The default value is \c 1.0 @@ -592,10 +599,10 @@ float QSGGeometry::lineWidth() const } /*! - Sets the line or point width to be used for this geometry to \a - width. This property only applies to line width when the drawingMode is - DrawLines, DrawLineStrip, or DrawLineLoop. When supported, it also - applies to point size when the drawingMode is DrawPoints. + Sets the line or point width to be used for this geometry to \a width. This + property only applies to line width when the drawingMode is DrawLines or + DrawLineStrip. When supported, it also applies to point size when the + drawingMode is DrawPoints. \note Support for point and line drawing may be limited at run time, depending on the platform and graphics API. For example, some APIs do diff --git a/src/quick/scenegraph/coreapi/qsggeometry.h b/src/quick/scenegraph/coreapi/qsggeometry.h index 060d896b3cf..82b930edf20 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.h +++ b/src/quick/scenegraph/coreapi/qsggeometry.h @@ -201,6 +201,7 @@ class Q_QUICK_EXPORT QSGGeometry void setLineWidth(float w); private: + Q_DISABLE_COPY_MOVE(QSGGeometry) friend class QSGGeometryData; int m_drawing_mode; diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp index e22ffa10d24..46637b326eb 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.cpp +++ b/src/quick/scenegraph/coreapi/qsgnode.cpp @@ -78,8 +78,8 @@ static void qt_print_node_count() insertChildNodeAfter(). The order of nodes is important as geometry nodes are rendered according to their ordering in the scene graph. - The scene graph nodes contains a mechanism to describe which - parts of the scene has changed. This includes the combined matrices, + The scene graph nodes contain a mechanism that describes which + parts of the scene have changed. This includes the combined matrices, accumulated opacity, changes to the node hierarchy, and so on. This information can be used for optimizations inside the scene graph renderer. For the renderer to properly render the nodes, it is important that users diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index 4b3cd9f2c1c..277e5b8482d 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -55,7 +55,7 @@ int qt_sg_envInt(const char *name, int defaultValue) if (Q_LIKELY(!qEnvironmentVariableIsSet(name))) return defaultValue; bool ok = false; - int value = qgetenv(name).toInt(&ok); + int value = qEnvironmentVariableIntValue(name, &ok); return ok ? value : defaultValue; } @@ -98,7 +98,6 @@ QSGRenderer::QSGRenderer(QSGRenderContext *context) , m_rt(nullptr) , m_cb(nullptr) , m_rp_desc(nullptr) - , m_external_rp_desc(nullptr) , m_node_updater(nullptr) , m_changed_emitted(false) , m_is_rendering(false) diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h index 31f00dc7384..9f1ab6a99b3 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h @@ -97,7 +97,6 @@ class Q_QUICK_PRIVATE_EXPORT QSGRenderer : public QSGAbstractRenderer virtual void setVisualizationMode(const QByteArray &) { } virtual bool hasVisualizationModeWithContinuousUpdate() const { return false; } virtual void releaseCachedResources() { } - virtual void invalidatePipelineCacheDependency(QRhiRenderPassDescriptor *) { } void clearChangedFlag() { m_changed_emitted = false; } @@ -116,15 +115,8 @@ class Q_QUICK_PRIVATE_EXPORT QSGRenderer : public QSGAbstractRenderer QRhiRenderPassDescriptor *renderPassDescriptor() const { return m_rp_desc; } void setExternalRenderPassDescriptor(QRhiRenderPassDescriptor *rpDesc) { - if (m_external_rp_desc) { - // Changes will be rare in practice - one has to construct a - // dynamic Quick 3D scene with reparenting involved for that. Play - // nice nonetheless and invalidate as soon as possible. - if (m_external_rp_desc != rpDesc) - invalidatePipelineCacheDependency(m_external_rp_desc); - } - m_rp_desc = rpDesc; - m_external_rp_desc = rpDesc; + // no differentiation needed anymore + setRenderPassDescriptor(rpDesc); } void setRenderPassRecordingCallbacks(QSGRenderContext::RenderPassCallback start, @@ -162,7 +154,6 @@ class Q_QUICK_PRIVATE_EXPORT QSGRenderer : public QSGAbstractRenderer QRhiRenderTarget *m_rt; QRhiCommandBuffer *m_cb; QRhiRenderPassDescriptor *m_rp_desc; - QRhiRenderPassDescriptor *m_external_rp_desc; struct { QSGRenderContext::RenderPassCallback start = nullptr; QSGRenderContext::RenderPassCallback end = nullptr; diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp index ec8e3dda570..2344f27b633 100644 --- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp +++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp @@ -85,17 +85,15 @@ QSGRenderNodePrivate::QSGRenderNodePrivate() mask where each bit represents graphics states changed by the \l render() function: - \list - \li DepthState - depth write mask, depth test enabled, depth comparison function - \li StencilState - stencil write masks, stencil test enabled, stencil operations, - stencil comparison functions - \li ScissorState - scissor enabled, scissor test enabled - \li ColorState - clear color, color write mask - \li BlendState - blend enabled, blend function - \li CullState - front face, cull face enabled - \li ViewportState - viewport - \li RenderTargetState - render target - \endlist + \value DepthState depth write mask, depth test enabled, depth comparison function + \value StencilState stencil write masks, stencil test enabled, stencil operations, + stencil comparison functions + \value ScissorState scissor enabled, scissor test enabled + \value ColorState clear color, color write mask + \value BlendState blend enabled, blend function + \value CullState front face, cull face enabled + \value ViewportState viewport + \value RenderTargetState render target With APIs other than OpenGL, the only relevant values are the ones that correspond to dynamic state changes recorded on the command list/buffer. @@ -239,13 +237,14 @@ void QSGRenderNode::prepare() Assume nothing about the pipelines and dynamic states bound on the command list/buffer when this function is called. - With some graphics APIs it can be necessary to also connect to the - QQuickWindow::beforeRendering() signal, because that is emitted before - recording the beginning of a renderpass on the command buffer - (vkCmdBeginRenderPass with Vulkan, or starting to encode via - MTLRenderCommandEncoder in case of Metal). Recording copy operations cannot - be done inside render() with such APIs. Rather, do it in the slot connected - (with DirectConnection) to the beforeRendering signal. + With some graphics APIs it can be necessary to reimplement prepare() in + addition, or alternatively connect to the QQuickWindow::beforeRendering() + signal. These are called/emitted before recording the beginning of a + renderpass on the command buffer (vkCmdBeginRenderPass with Vulkan, or + starting to encode via MTLRenderCommandEncoder in case of Metal. Recording + copy operations cannot be done inside render() with such APIs. Rather, do + such operations either in prepare() or the slot connected to + beforeRendering (with DirectConnection). \sa QSGRendererInterface, QQuickWindow::rendererInterface() */ diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp index d1a777995ac..b79999c3ead 100644 --- a/src/quick/scenegraph/coreapi/qsgtexture.cpp +++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp @@ -43,6 +43,7 @@ #include <private/qsgmaterialshader_p.h> #include <private/qquickitem_p.h> // qquickwindow_p.h cannot be included on its own due to template nonsense #include <private/qquickwindow_p.h> +#include <QtCore/private/qnativeinterface_p.h> #include <QtGui/private/qrhi_p.h> #if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && defined(__GLIBC__) @@ -715,6 +716,7 @@ namespace QNativeInterface { \inmodule QtQuick \ingroup native-interfaces \ingroup native-interfaces-qsgtexture + \inheaderfile QSGTexture \brief Provides access to and enables adopting OpenGL texture objects. \since 6.0 */ @@ -815,6 +817,7 @@ namespace QNativeInterface { \inmodule QtQuick \ingroup native-interfaces \ingroup native-interfaces-qsgtexture + \inheaderfile QSGTexture \brief Provides access to and enables adopting Direct3D 11 texture objects. \since 6.0 */ @@ -875,6 +878,7 @@ namespace QNativeInterface { \inmodule QtQuick \ingroup native-interfaces \ingroup native-interfaces-qsgtexture + \inheaderfile QSGTexture \brief Provides access to and enables adopting Metal texture objects. \since 6.0 */ @@ -922,6 +926,7 @@ namespace QNativeInterface { \inmodule QtQuick \ingroup native-interfaces \ingroup native-interfaces-qsgtexture + \inheaderfile QSGTexture \brief Provides access to and enables adopting Vulkan image objects. \since 6.0 */ @@ -990,29 +995,27 @@ VkImageLayout QSGTexturePlatformVulkan::nativeImageLayout() const } #endif // vulkan -template<> -Q_NATIVE_INTERFACE_EXPORT void * -QNativeInterface::Private::resolveInterface(const QSGTexture *that, const char *name, int revision) +void *QSGTexture::resolveInterface(const char *name, int revision) const { using namespace QNativeInterface; - Q_UNUSED(that); Q_UNUSED(name); Q_UNUSED(revision); - auto *texturePrivate = QSGTexturePrivate::get(const_cast<QSGTexture*>(that)); - Q_UNUSED(texturePrivate); + Q_D(const QSGTexture); + auto *dd = const_cast<QSGTexturePrivate *>(d); + Q_UNUSED(dd); #if QT_CONFIG(vulkan) - QT_NATIVE_INTERFACE_RETURN_IF(QSGVulkanTexture, &texturePrivate->m_vulkanTextureAccessor); + QT_NATIVE_INTERFACE_RETURN_IF(QSGVulkanTexture, &dd->m_vulkanTextureAccessor); #endif #if defined(__OBJC__) - QT_NATIVE_INTERFACE_RETURN_IF(QSGMetalTexture, &texturePrivate->m_metalTextureAccessor); + QT_NATIVE_INTERFACE_RETURN_IF(QSGMetalTexture, &dd->m_metalTextureAccessor); #endif #if defined(Q_OS_WIN) - QT_NATIVE_INTERFACE_RETURN_IF(QSGD3D11Texture, &texturePrivate->m_d3d11TextureAccessor); + QT_NATIVE_INTERFACE_RETURN_IF(QSGD3D11Texture, &dd->m_d3d11TextureAccessor); #endif #if QT_CONFIG(opengl) - QT_NATIVE_INTERFACE_RETURN_IF(QSGOpenGLTexture, &texturePrivate->m_openglTextureAccessor); + QT_NATIVE_INTERFACE_RETURN_IF(QSGOpenGLTexture, &dd->m_openglTextureAccessor); #endif return nullptr; diff --git a/src/quick/scenegraph/coreapi/qsgtexture.h b/src/quick/scenegraph/coreapi/qsgtexture.h index 5492b04e117..b549d82fa03 100644 --- a/src/quick/scenegraph/coreapi/qsgtexture.h +++ b/src/quick/scenegraph/coreapi/qsgtexture.h @@ -112,7 +112,7 @@ class Q_QUICK_EXPORT QSGTexture : public QObject inline QRectF convertToNormalizedSourceRect(const QRectF &rect) const; - QT_DECLARE_NATIVE_INTERFACE_ACCESSOR + QT_DECLARE_NATIVE_INTERFACE_ACCESSOR(QSGTexture) protected: QSGTexture(QSGTexturePrivate &dd); diff --git a/src/quick/scenegraph/coreapi/qsgtexture_mac.mm b/src/quick/scenegraph/coreapi/qsgtexture_mac.mm index 9d009eb5cb9..7ead16f14fe 100644 --- a/src/quick/scenegraph/coreapi/qsgtexture_mac.mm +++ b/src/quick/scenegraph/coreapi/qsgtexture_mac.mm @@ -41,6 +41,7 @@ #include "qsgtexture_platform.h" #include <private/qquickitem_p.h> #include <private/qquickwindow_p.h> +#include <QtCore/private/qnativeinterface_p.h> #include <QtGui/private/qrhi_p.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index ee0dc959454..c3d286ee9db 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -353,6 +353,7 @@ class Q_QUICK_PRIVATE_EXPORT QSGShaderEffectNode : public QObject, public QSGVis }; ShaderSyncData vertex; ShaderSyncData fragment; + void *materialTypeCacheKey; }; // Each ShaderEffect item has one node (render thread) and one manager (gui thread). @@ -463,9 +464,9 @@ class Q_QUICK_PRIVATE_EXPORT QSGDistanceFieldGlyphCache { return pixelSize / baseFontSize(); } - int distanceFieldRadius() const + qreal distanceFieldRadius() const { - return QT_DISTANCEFIELD_RADIUS(m_doubleGlyphResolution) / QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution); + return QT_DISTANCEFIELD_RADIUS(m_doubleGlyphResolution) / qreal(QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution)); } int glyphCount() const { return m_glyphCount; } bool doubleGlyphResolution() const { return m_doubleGlyphResolution; } diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index 578b5ab2f21..df0592cad15 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp @@ -111,6 +111,18 @@ QSGTextMaskRhiShader::QSGTextMaskRhiShader(QFontEngine::GlyphFormat glyphFormat) QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/textmask.frag.qsb")); } +enum UbufOffset { + ModelViewMatrixOffset = 0, + ProjectionMatrixOffset = ModelViewMatrixOffset + 64, + ColorOffset = ProjectionMatrixOffset + 64, + TextureScaleOffset = ColorOffset + 16, + DprOffset = TextureScaleOffset + 8, + + // + 1 float padding (vec4 must be aligned to 16) + StyleColorOffset = DprOffset + 4 + 4, + ShiftOffset = StyleColorOffset + 16 +}; + bool QSGTextMaskRhiShader::updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) { @@ -126,11 +138,14 @@ bool QSGTextMaskRhiShader::updateUniformData(RenderState &state, bool changed = false; QByteArray *buf = state.uniformData(); - Q_ASSERT(buf->size() >= 92); + Q_ASSERT(buf->size() >= DprOffset + 4); if (state.isMatrixDirty()) { - const QMatrix4x4 m = state.combinedMatrix(); - memcpy(buf->data(), m.constData(), 64); + const QMatrix4x4 mv = state.modelViewMatrix(); + memcpy(buf->data() + ModelViewMatrixOffset, mv.constData(), 64); + const QMatrix4x4 p = state.projectionMatrix(); + memcpy(buf->data() + ProjectionMatrixOffset, p.constData(), 64); + changed = true; } @@ -139,13 +154,13 @@ bool QSGTextMaskRhiShader::updateUniformData(RenderState &state, if (updated || !oldMat || oldRtex != newRtex) { const QVector2D textureScale = QVector2D(1.0f / mat->rhiGlyphCache()->width(), 1.0f / mat->rhiGlyphCache()->height()); - memcpy(buf->data() + 64 + 16, &textureScale, 8); + memcpy(buf->data() + TextureScaleOffset, &textureScale, 8); changed = true; } if (!oldMat) { float dpr = state.devicePixelRatio(); - memcpy(buf->data() + 64 + 16 + 8, &dpr, 4); + memcpy(buf->data() + DprOffset, &dpr, 4); } // move texture uploads/copies onto the renderer's soon-to-be-committed list @@ -193,11 +208,11 @@ bool QSG8BitTextMaskRhiShader::updateUniformData(RenderState &state, QSGTextMaskMaterial *oldMat = static_cast<QSGTextMaskMaterial *>(oldMaterial); QByteArray *buf = state.uniformData(); - Q_ASSERT(buf->size() >= 80); + Q_ASSERT(buf->size() >= ColorOffset + 16); if (oldMat == nullptr || mat->color() != oldMat->color() || state.isOpacityDirty()) { const QVector4D color = qsg_premultiply(mat->color(), state.opacity()); - memcpy(buf->data() + 64, &color, 16); + memcpy(buf->data() + ColorOffset, &color, 16); changed = true; } @@ -236,12 +251,12 @@ bool QSG24BitTextMaskRhiShader::updateUniformData(RenderState &state, QSGTextMaskMaterial *oldMat = static_cast<QSGTextMaskMaterial *>(oldMaterial); QByteArray *buf = state.uniformData(); - Q_ASSERT(buf->size() >= 92); + Q_ASSERT(buf->size() >= ColorOffset + 16); if (oldMat == nullptr || mat->color() != oldMat->color() || state.isOpacityDirty()) { // shader takes vec4 but uses alpha only; coloring happens via the blend constant const QVector4D color = qsg_premultiply(mat->color(), state.opacity()); - memcpy(buf->data() + 64, &color, 16); + memcpy(buf->data() + ColorOffset, &color, 16); changed = true; } @@ -259,7 +274,8 @@ bool QSG24BitTextMaskRhiShader::updateGraphicsPipelineState(RenderState &state, ps->srcColor = GraphicsPipelineState::ConstantColor; ps->dstColor = GraphicsPipelineState::OneMinusSrcColor; - QVector4D color = qsg_premultiply(mat->color(), state.opacity()); + QVector4D color = mat->color(); + // if (useSRGB()) // color = qt_sRGB_to_linear_RGB(color); @@ -291,12 +307,12 @@ bool QSG32BitColorTextRhiShader::updateUniformData(RenderState &state, QSGTextMaskMaterial *oldMat = static_cast<QSGTextMaskMaterial *>(oldMaterial); QByteArray *buf = state.uniformData(); - Q_ASSERT(buf->size() >= 92); + Q_ASSERT(buf->size() >= ColorOffset + 16); if (oldMat == nullptr || mat->color() != oldMat->color() || state.isOpacityDirty()) { // shader takes vec4 but uses alpha only const QVector4D color(0, 0, 0, mat->color().w() * state.opacity()); - memcpy(buf->data() + 64, &color, 16); + memcpy(buf->data() + ColorOffset, &color, 16); changed = true; } @@ -332,20 +348,17 @@ bool QSGStyledTextRhiShader::updateUniformData(RenderState &state, QSGStyledTextMaterial *oldMat = static_cast<QSGStyledTextMaterial *>(oldMaterial); QByteArray *buf = state.uniformData(); - Q_ASSERT(buf->size() >= 120); - - // matrix..dpr + 1 float padding (vec4 must be aligned to 16) - const int startOffset = 64 + 16 + 8 + 4 + 4; + Q_ASSERT(buf->size() >= ShiftOffset + 8); if (oldMat == nullptr || mat->styleColor() != oldMat->styleColor() || state.isOpacityDirty()) { const QVector4D styleColor = qsg_premultiply(mat->styleColor(), state.opacity()); - memcpy(buf->data() + startOffset, &styleColor, 16); + memcpy(buf->data() + StyleColorOffset, &styleColor, 16); changed = true; } if (oldMat == nullptr || oldMat->styleShift() != mat->styleShift()) { const QVector2D v = mat->styleShift(); - memcpy(buf->data() + startOffset + 16, &v, 8); + memcpy(buf->data() + ShiftOffset, &v, 8); changed = true; } @@ -444,7 +457,7 @@ void QSGTextMaskMaterial::updateCache(QFontEngine::GlyphFormat glyphFormat) QColor color = glyphFormat == QFontEngine::Format_ARGB ? QColor::fromRgbF(m_color.x(), m_color.y(), m_color.z(), m_color.w()) : QColor(); m_glyphCache = fontEngine->glyphCache(cacheKey, glyphFormat, glyphCacheTransform, color); if (!m_glyphCache || int(m_glyphCache->glyphFormat()) != glyphFormat) { - m_glyphCache = new QSGRhiTextureGlyphCache(m_rhi, glyphFormat, glyphCacheTransform, color); + m_glyphCache = new QSGRhiTextureGlyphCache(m_rc, glyphFormat, glyphCacheTransform, color); fontEngine->setGlyphCache(cacheKey, m_glyphCache.data()); m_rc->registerFontengineForCleanup(fontEngine); } @@ -470,8 +483,12 @@ void QSGTextMaskMaterial::populate(const QPointF &p, QTextureGlyphCache *cache = glyphCache(); QRawFontPrivate *fontD = QRawFontPrivate::get(m_font); - cache->populate(fontD->fontEngine, glyphIndexes.size(), glyphIndexes.constData(), - fixedPointPositions.data()); + cache->populate(fontD->fontEngine, + glyphIndexes.size(), + glyphIndexes.constData(), + fixedPointPositions.data(), + QPainter::RenderHints(), + true); cache->fillInPendingGlyphs(); int margin = fontD->fontEngine->glyphMargin(cache->glyphFormat()); @@ -491,9 +508,11 @@ void QSGTextMaskMaterial::populate(const QPointF &p, bool supportsSubPixelPositions = fontD->fontEngine->supportsHorizontalSubPixelPositions(); for (int i=0; i<glyphIndexes.size(); ++i) { QPointF glyphPosition = glyphPositions.at(i) + position; + QFixedPoint fixedPointPosition = fixedPointPositions.at(i); + QFixed subPixelPosition; if (supportsSubPixelPositions) - subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPosition.x())); + subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(fixedPointPosition.x.toReal() * glyphCacheScaleX)); QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), QFixedPoint(subPixelPosition, 0)); diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp index 1b2dbab84f8..8579cb5e2af 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -64,6 +64,7 @@ QSGDefaultRenderContext::QSGDefaultRenderContext(QSGContext *context) , m_currentFrameRenderPass(nullptr) , m_separateIndexBuffer(false) , m_useDepthBufferFor2D(true) + , m_glyphCacheResourceUpdates(nullptr) { } @@ -89,6 +90,8 @@ void QSGDefaultRenderContext::initialize(const QSGRenderContext::InitParams *par // unlike OpenGL (and like WebGL), QRhi does not guarantee buffer usage types can be mixed m_separateIndexBuffer = true; + m_glyphCacheResourceUpdates = nullptr; + m_sg->renderContextInitialized(this); emit initialized(); @@ -140,10 +143,11 @@ void QSGDefaultRenderContext::invalidate() } m_fontEnginesToClean.clear(); - qDeleteAll(m_glyphCaches); m_glyphCaches.clear(); + releaseGlyphCacheResourceUpdates(); + m_rhi = nullptr; if (m_sg) @@ -296,13 +300,34 @@ QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(con QString key = fontKey(font, renderTypeQuality); QSGDistanceFieldGlyphCache *cache = m_glyphCaches.value(key, 0); if (!cache) { - cache = new QSGRhiDistanceFieldGlyphCache(m_rhi, font, renderTypeQuality); + cache = new QSGRhiDistanceFieldGlyphCache(this, font, renderTypeQuality); m_glyphCaches.insert(key, cache); } return cache; } +QRhiResourceUpdateBatch *QSGDefaultRenderContext::maybeGlyphCacheResourceUpdates() +{ + return m_glyphCacheResourceUpdates; +} + +QRhiResourceUpdateBatch *QSGDefaultRenderContext::glyphCacheResourceUpdates() +{ + if (!m_glyphCacheResourceUpdates) + m_glyphCacheResourceUpdates = m_rhi->nextResourceUpdateBatch(); + + return m_glyphCacheResourceUpdates; +} + +void QSGDefaultRenderContext::releaseGlyphCacheResourceUpdates() +{ + if (m_glyphCacheResourceUpdates) { + m_glyphCacheResourceUpdates->release(); + m_glyphCacheResourceUpdates = nullptr; + } +} + QT_END_NAMESPACE #include "moc_qsgdefaultrendercontext_p.cpp" diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h index 002513c0e4c..e96bf045b52 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h +++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h @@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE class QRhi; class QRhiCommandBuffer; class QRhiRenderPassDescriptor; +class QRhiResourceUpdateBatch; class QSGMaterialShader; class QSurface; @@ -143,6 +144,10 @@ class Q_QUICK_PRIVATE_EXPORT QSGDefaultRenderContext : public QSGRenderContext return m_currentDevicePixelRatio; } + QRhiResourceUpdateBatch *maybeGlyphCacheResourceUpdates(); + QRhiResourceUpdateBatch *glyphCacheResourceUpdates(); + void releaseGlyphCacheResourceUpdates(); + protected: static QString fontKey(const QRawFont &font, int renderTypeQuality); @@ -156,6 +161,7 @@ class Q_QUICK_PRIVATE_EXPORT QSGDefaultRenderContext : public QSGRenderContext qreal m_currentDevicePixelRatio; bool m_separateIndexBuffer; bool m_useDepthBufferFor2D; + QRhiResourceUpdateBatch *m_glyphCacheResourceUpdates; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp index 8ac112b1064..4c6589d1f9a 100644 --- a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp +++ b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp @@ -43,6 +43,10 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcSgText, "qt.scenegraph.text") + +qint64 QSGDistanceFieldGlyphNode::m_totalAllocation = 0; + QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode(QSGRenderContext *context) : m_glyphNodeType(RootGlyphNode) , m_context(context) @@ -135,6 +139,9 @@ void QSGDistanceFieldGlyphNode::setGlyphs(const QPointF &position, const QGlyphR const QVector<quint32> glyphIndexes = m_glyphs.glyphIndexes(); for (int i = 0; i < glyphIndexes.count(); ++i) m_allGlyphIndexesLookup.insert(glyphIndexes.at(i)); + qCDebug(lcSgText, "inserting %" PRIdQSIZETYPE " glyphs, %" PRIdQSIZETYPE " unique", + glyphIndexes.count(), + m_allGlyphIndexesLookup.count()); } void QSGDistanceFieldGlyphNode::setStyle(QQuickText::TextStyle style) @@ -198,8 +205,7 @@ void QSGDistanceFieldGlyphNode::updateGeometry() QSGGeometry *g = geometry(); Q_ASSERT(g->indexType() == QSGGeometry::UnsignedShortType); - - QHash<const QSGDistanceFieldGlyphCache::Texture *, GlyphInfo> glyphsInOtherTextures; + m_glyphsInOtherTextures.clear(); const QVector<quint32> indexes = m_glyphs.glyphIndexes(); const QVector<QPointF> positions = m_glyphs.positions(); @@ -208,9 +214,12 @@ void QSGDistanceFieldGlyphNode::updateGeometry() // The template parameters here are assuming that most strings are short, 64 // characters or less. QVarLengthArray<QSGGeometry::TexturedPoint2D, 256> vp; - vp.reserve(indexes.size() * 4); QVarLengthArray<ushort, 384> ip; - ip.reserve(indexes.size() * 6); + const qsizetype maxIndexCount = (std::numeric_limits<quint16>::max() - 1) / 4; // 16383 (see below: 0xFFFF is not allowed) + const qsizetype maxVertexCount = maxIndexCount * 4; // 65532 + const auto likelyGlyphCount = qMin(indexes.size(), maxIndexCount); + vp.reserve(likelyGlyphCount * 4); + ip.reserve(likelyGlyphCount * 6); qreal maxTexMargin = m_glyph_cache->distanceFieldRadius(); qreal fontScale = m_glyph_cache->fontScale(fontPixelSize); @@ -236,15 +245,20 @@ void QSGDistanceFieldGlyphNode::updateGeometry() // As we use UNSIGNED_SHORT indexing in the geometry, we overload the // "glyphsInOtherTextures" concept as overflow for if there are more - // than 65535 vertices to render which would otherwise exceed the + // than 65532 vertices to render, which would otherwise exceed the // maximum index size. (leave 0xFFFF unused in order not to clash with - // primitive restart) This will cause sub-nodes to be recursively - // created to handle any number of glyphs. - if (m_texture != texture || vp.size() >= 65535) { - if (texture->texture) { - GlyphInfo &glyphInfo = glyphsInOtherTextures[texture]; + // primitive restart) This will cause sub-nodes to be + // created to handle any number of glyphs. But only the RootGlyphNode + // needs to do this classification; from the perspective of a SubGlyphNode, + // it's already done, and m_glyphs contains only pointers to ranges of + // indices and positions that the RootGlyphNode is storing. + if (m_texture != texture || vp.size() >= maxVertexCount) { + if (m_glyphNodeType == RootGlyphNode && texture->texture) { + GlyphInfo &glyphInfo = m_glyphsInOtherTextures[texture]; glyphInfo.indexes.append(glyphIndex); glyphInfo.positions.append(position); + } else if (vp.size() >= maxVertexCount && m_glyphNodeType == SubGlyphNode) { + break; // out of this loop over indices, because we won't add any more vertices } continue; } @@ -303,26 +317,38 @@ void QSGDistanceFieldGlyphNode::updateGeometry() ip.append(o + 0); } - QHash<const QSGDistanceFieldGlyphCache::Texture *, GlyphInfo>::const_iterator ite = glyphsInOtherTextures.constBegin(); - while (ite != glyphsInOtherTextures.constEnd()) { - QGlyphRun subNodeGlyphRun(m_glyphs); - subNodeGlyphRun.setGlyphIndexes(ite->indexes); - subNodeGlyphRun.setPositions(ite->positions); - - QSGDistanceFieldGlyphNode *subNode = new QSGDistanceFieldGlyphNode(m_context); - subNode->setGlyphNodeType(SubGlyphNode); - subNode->setColor(m_color); - subNode->setStyle(m_style); - subNode->setStyleColor(m_styleColor); - subNode->setPreferredAntialiasingMode(m_antialiasingMode); - subNode->setGlyphs(m_originalPosition, subNodeGlyphRun); - subNode->update(); - subNode->updateGeometry(); // we have to explicitly call this now as preprocess won't be called before it's rendered - appendChildNode(subNode); - - ++ite; + if (m_glyphNodeType == SubGlyphNode) { + Q_ASSERT(m_glyphsInOtherTextures.isEmpty()); + } else { + if (!m_glyphsInOtherTextures.isEmpty()) + qCDebug(lcSgText, "%" PRIdQSIZETYPE " 'other' textures", m_glyphsInOtherTextures.count()); + QHash<const QSGDistanceFieldGlyphCache::Texture *, GlyphInfo>::const_iterator ite = m_glyphsInOtherTextures.constBegin(); + while (ite != m_glyphsInOtherTextures.constEnd()) { + QGlyphRun subNodeGlyphRun(m_glyphs); + for (int i = 0; i < ite->indexes.count(); i += maxIndexCount) { + int len = qMin(maxIndexCount, ite->indexes.count() - i); + subNodeGlyphRun.setRawData(ite->indexes.constData() + i, ite->positions.constData() + i, len); + qCDebug(lcSgText) << "subNodeGlyphRun has" << len << "positions:" + << *(ite->positions.constData() + i) << "->" << *(ite->positions.constData() + i + len - 1); + + QSGDistanceFieldGlyphNode *subNode = new QSGDistanceFieldGlyphNode(m_context); + subNode->setGlyphNodeType(SubGlyphNode); + subNode->setColor(m_color); + subNode->setStyle(m_style); + subNode->setStyleColor(m_styleColor); + subNode->setPreferredAntialiasingMode(m_antialiasingMode); + subNode->setGlyphs(m_originalPosition, subNodeGlyphRun); + subNode->update(); + subNode->updateGeometry(); // we have to explicitly call this now as preprocess won't be called before it's rendered + appendChildNode(subNode); + } + ++ite; + } } + m_totalAllocation += vp.size() * sizeof(QSGGeometry::TexturedPoint2D) + ip.size() * sizeof(quint16); + qCDebug(lcSgText) << "allocating for" << vp.size() << "vtx (reserved" << likelyGlyphCount * 4 << "):" << vp.size() * sizeof(QSGGeometry::TexturedPoint2D) + << "bytes;" << ip.size() << "idx:" << ip.size() * sizeof(quint16) << "bytes; total bytes so far" << m_totalAllocation; g->allocate(vp.size(), ip.size()); memcpy(g->vertexDataAsTexturedPoint2D(), vp.constData(), vp.size() * sizeof(QSGGeometry::TexturedPoint2D)); memcpy(g->indexDataAsUShort(), ip.constData(), ip.size() * sizeof(quint16)); diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h index 2b2975ccb36..e7655f502d9 100644 --- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h +++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h @@ -115,9 +115,13 @@ class QSGDistanceFieldGlyphNode : public QSGGlyphNode, public QSGDistanceFieldGl QVector<QPointF> positions; }; QSet<quint32> m_allGlyphIndexesLookup; + // m_glyphs holds pointers to the GlyphInfo.indexes and positions arrays, so we need to hold on to them + QHash<const QSGDistanceFieldGlyphCache::Texture *, GlyphInfo> m_glyphsInOtherTextures; uint m_dirtyGeometry: 1; uint m_dirtyMaterial: 1; + + static qint64 m_totalAllocation; // all SG glyph vertices and indices; only for qCDebug metrics }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 077814b1f44..443afb00ac9 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -357,10 +357,6 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window) rhi->makeThreadLocalNativeContextCurrent(); } -#if QT_CONFIG(quick_shadereffect) - QSGRhiShaderEffectNode::cleanupMaterialTypeCache(); -#endif - if (d->swapchain) { if (window->handle()) { // We get here when exiting via QCoreApplication::quit() instead of @@ -373,6 +369,11 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window) } d->cleanupNodesOnShutdown(); + +#if QT_CONFIG(quick_shadereffect) + QSGRhiShaderEffectNode::cleanupMaterialTypeCache(window); +#endif + if (m_windows.size() == 0) { rc->invalidate(); d->rhi = nullptr; @@ -409,17 +410,6 @@ void QSGGuiThreadRenderLoop::handleDeviceLoss() void QSGGuiThreadRenderLoop::releaseSwapchain(QQuickWindow *window) { QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window); - - // Unlike the threaded render loop, this one reuses the same rendercontext - // for all QQuickWindows for the entire lifetime of the render loop. (and - // even if it wouldn't, special cases like destroy() - show() on the - // QQuickWindow still needed this) - // Therefore the renderer, if there is one, needs to be notified about the - // destruction of certain resources because they may be referenced from - // per-rendercontext data structures. - if (wd->renderer) - wd->renderer->invalidatePipelineCacheDependency(wd->rpDescForSwapchain); - delete wd->rpDescForSwapchain; wd->rpDescForSwapchain = nullptr; delete wd->swapchain; @@ -452,7 +442,7 @@ bool QSGGuiThreadRenderLoop::ensureRhi(QQuickWindow *window, WindowData &data) { QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window); QSGRhiSupport *rhiSupport = QSGRhiSupport::instance(); - bool current = false; + bool ok = rhi != nullptr; if (!rhi) { // This block below handles both the initial QRhi initialization and @@ -473,7 +463,9 @@ bool QSGGuiThreadRenderLoop::ensureRhi(QQuickWindow *window, WindowData &data) data.rhiDeviceLost = false; - current = true; + ok = true; + // We need to guarantee that sceneGraphInitialized is + // emitted with a context current, if running with OpenGL. rhi->makeThreadLocalNativeContextCurrent(); // The sample count cannot vary between windows as we use the same @@ -493,16 +485,8 @@ bool QSGGuiThreadRenderLoop::ensureRhi(QQuickWindow *window, WindowData &data) data.rhiDoomed = true; handleContextCreationFailure(window); } - // otherwise no error, will retry on a subsequent rendering attempt + // otherwise no error, just return false so that we will retry on a subsequent rendering attempt } - } else { - current = true; - // With the rhi making the (OpenGL) context current serves only one - // purpose: to enable external OpenGL rendering connected to one of - // the QQuickWindow signals (beforeSynchronizing, beforeRendering, - // etc.) to function like it did on the direct OpenGL path. For our - // own rendering this call would not be necessary. - rhi->makeThreadLocalNativeContextCurrent(); } if (rhi && !cd->swapchain) { @@ -551,7 +535,7 @@ bool QSGGuiThreadRenderLoop::ensureRhi(QQuickWindow *window, WindowData &data) window->installEventFilter(this); } - return current; + return ok; } void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) @@ -665,6 +649,12 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) } } + // Enable external OpenGL rendering connected to one of the + // QQuickWindow signals (beforeSynchronizing, beforeRendering, + // etc.) to function like it did on the direct OpenGL path, + // i.e. ensure there is a context current, just in case. + rhi->makeThreadLocalNativeContextCurrent(); + cd->syncSceneGraph(); if (lastDirtyWindow) rc->endSync(); @@ -775,6 +765,7 @@ QImage QSGGuiThreadRenderLoop::grab(QQuickWindow *window) // renderWindow() so one cannot get to grab() without having done at least // one on-screen frame. cd->rhi->beginFrame(cd->swapchain); + rhi->makeThreadLocalNativeContextCurrent(); // for custom GL rendering before/during/after sync cd->syncSceneGraph(); cd->renderSceneGraph(window->size()); QImage image = QSGRhiSupport::instance()->grabAndBlockInCurrentFrame(rhi, cd->swapchain->currentFrameCommandBuffer()); diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp index a715092b190..b139c3428a2 100644 --- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp @@ -39,6 +39,7 @@ #include "qsgrhidistancefieldglyphcache_p.h" #include "qsgcontext_p.h" +#include "qsgdefaultrendercontext_p.h" #include <QtGui/private/qdistancefield_p.h> #include <QtCore/qelapsedtimer.h> #include <QtQml/private/qqmlglobal_p.h> @@ -54,11 +55,12 @@ DEFINE_BOOL_CONFIG_OPTION(qsgPreferFullSizeGlyphCacheTextures, QSG_PREFER_FULLSI # define QSG_RHI_DISTANCEFIELD_GLYPH_CACHE_PADDING 2 #endif -QSGRhiDistanceFieldGlyphCache::QSGRhiDistanceFieldGlyphCache(QRhi *rhi, +QSGRhiDistanceFieldGlyphCache::QSGRhiDistanceFieldGlyphCache(QSGDefaultRenderContext *rc, const QRawFont &font, int renderTypeQuality) : QSGDistanceFieldGlyphCache(font, renderTypeQuality) - , m_rhi(rhi) + , m_rc(rc) + , m_rhi(rc->rhi()) { // Load a pregenerated cache if the font contains one loadPregeneratedCache(font); @@ -66,13 +68,19 @@ QSGRhiDistanceFieldGlyphCache::QSGRhiDistanceFieldGlyphCache(QRhi *rhi, QSGRhiDistanceFieldGlyphCache::~QSGRhiDistanceFieldGlyphCache() { - for (int i = 0; i < m_textures.count(); ++i) - delete m_textures[i].texture; + // A plain delete should work, but just in case commitResourceUpdates was + // not called and something is enqueued on the update batch for a texture, + // defer until the end of the frame. + for (int i = 0; i < m_textures.count(); ++i) { + if (m_textures[i].texture) + m_textures[i].texture->deleteLater(); + } delete m_areaAllocator; // should be empty, but just in case - qDeleteAll(m_pendingDispose); + for (QRhiTexture *t : qAsConst(m_pendingDispose)) + t->deleteLater(); } void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs) @@ -88,8 +96,8 @@ void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs) int padding = QSG_RHI_DISTANCEFIELD_GLYPH_CACHE_PADDING; QRectF boundingRect = glyphData(glyphIndex).boundingRect; - int glyphWidth = qCeil(boundingRect.width()) + distanceFieldRadius() * 2; - int glyphHeight = qCeil(boundingRect.height()) + distanceFieldRadius() * 2; + int glyphWidth = qCeil(boundingRect.width() + distanceFieldRadius() * 2); + int glyphHeight = qCeil(boundingRect.height() + distanceFieldRadius() * 2); QSize glyphSize(glyphWidth + padding * 2, glyphHeight + padding * 2); QRect alloc = m_areaAllocator->allocate(glyphSize); @@ -100,8 +108,8 @@ void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs) TexCoord unusedCoord = glyphTexCoord(unusedGlyph); QRectF unusedGlyphBoundingRect = glyphData(unusedGlyph).boundingRect; - int unusedGlyphWidth = qCeil(unusedGlyphBoundingRect.width()) + distanceFieldRadius() * 2; - int unusedGlyphHeight = qCeil(unusedGlyphBoundingRect.height()) + distanceFieldRadius() * 2; + int unusedGlyphWidth = qCeil(unusedGlyphBoundingRect.width() + distanceFieldRadius() * 2); + int unusedGlyphHeight = qCeil(unusedGlyphBoundingRect.height() + distanceFieldRadius() * 2); m_areaAllocator->deallocate(QRect(unusedCoord.x - padding, unusedCoord.y - padding, padding * 2 + unusedGlyphWidth, @@ -178,15 +186,13 @@ void QSGRhiDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &gly texInfo->uploads.append(QRhiTextureUploadEntry(0, 0, subresDesc)); } - if (!m_resourceUpdates) - m_resourceUpdates = m_rhi->nextResourceUpdateBatch(); - + QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates(); for (int i = 0; i < glyphs.size(); ++i) { TextureInfo *texInfo = m_glyphsTexture.value(glyphs.at(i).glyph()); if (!texInfo->uploads.isEmpty()) { QRhiTextureUploadDescription desc; desc.setEntries(texInfo->uploads.cbegin(), texInfo->uploads.cend()); - m_resourceUpdates->uploadTexture(texInfo->texture, desc); + resourceUpdates->uploadTexture(texInfo->texture, desc); texInfo->uploads.clear(); } } @@ -229,12 +235,10 @@ void QSGRhiDistanceFieldGlyphCache::createTexture(TextureInfo *texInfo, texInfo->texture = m_rhi->newTexture(QRhiTexture::RED_OR_ALPHA8, QSize(width, height), 1, QRhiTexture::UsedAsTransferSource); if (texInfo->texture->create()) { - if (!m_resourceUpdates) - m_resourceUpdates = m_rhi->nextResourceUpdateBatch(); - + QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates(); QRhiTextureSubresourceUploadDescription subresDesc(pixels, width * height); subresDesc.setSourceSize(QSize(width, height)); - m_resourceUpdates->uploadTexture(texInfo->texture, QRhiTextureUploadEntry(0, 0, subresDesc)); + resourceUpdates->uploadTexture(texInfo->texture, QRhiTextureUploadEntry(0, 0, subresDesc)); } else { qWarning("Failed to create distance field glyph cache"); } @@ -257,17 +261,15 @@ void QSGRhiDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int widt updateRhiTexture(oldTexture, texInfo->texture, texInfo->size); - if (!m_resourceUpdates) - m_resourceUpdates = m_rhi->nextResourceUpdateBatch(); - + QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates(); if (useTextureResizeWorkaround()) { QRhiTextureSubresourceUploadDescription subresDesc(texInfo->image.constBits(), oldWidth * oldHeight); subresDesc.setSourceSize(QSize(oldWidth, oldHeight)); - m_resourceUpdates->uploadTexture(texInfo->texture, QRhiTextureUploadEntry(0, 0, subresDesc)); + resourceUpdates->uploadTexture(texInfo->texture, QRhiTextureUploadEntry(0, 0, subresDesc)); texInfo->image = texInfo->image.copy(0, 0, width, height); } else { - m_resourceUpdates->copyTexture(texInfo->texture, oldTexture); + resourceUpdates->copyTexture(texInfo->texture, oldTexture); } m_pendingDispose.insert(oldTexture); @@ -447,7 +449,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) const char *textureRecord = allocatorData; for (int i = 0; i < textureCount; ++i, textureRecord += Qtdf::TextureRecordSize) { - if (textureRecord + Qtdf::TextureRecordSize > qtdfTableEnd) { + if (qtdfTableEnd - textureRecord < Qtdf::TextureRecordSize) { qWarning("qtdf table too small in font '%s'.", qPrintable(font.familyName())); return false; @@ -463,7 +465,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) const char *glyphRecord = textureRecord; for (quint32 i = 0; i < glyphCount; ++i, glyphRecord += Qtdf::GlyphRecordSize) { - if (glyphRecord + Qtdf::GlyphRecordSize > qtdfTableEnd) { + if (qtdfTableEnd - glyphRecord < Qtdf:: GlyphRecordSize) { qWarning("qtdf table too small in font '%s'.", qPrintable(font.familyName())); return false; @@ -513,8 +515,8 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) int width = texInfo->allocatedArea.width(); int height = texInfo->allocatedArea.height(); - qint64 size = width * height; - if (reinterpret_cast<const char *>(textureData + size) > qtdfTableEnd) { + qint64 size = qint64(width) * height; + if (qtdfTableEnd - reinterpret_cast<const char *>(textureData) < size) { qWarning("qtdf table too small in font '%s'.", qPrintable(font.familyName())); return false; @@ -547,14 +549,13 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) void QSGRhiDistanceFieldGlyphCache::commitResourceUpdates(QRhiResourceUpdateBatch *mergeInto) { - if (m_resourceUpdates) { - mergeInto->merge(m_resourceUpdates); - m_resourceUpdates->release(); - m_resourceUpdates = nullptr; + if (QRhiResourceUpdateBatch *resourceUpdates = m_rc->maybeGlyphCacheResourceUpdates()) { + mergeInto->merge(resourceUpdates); + m_rc->releaseGlyphCacheResourceUpdates(); } // now let's assume the resource updates will be committed in this frame - for (QRhiTexture *t : m_pendingDispose) + for (QRhiTexture *t : qAsConst(m_pendingDispose)) t->deleteLater(); // will be deleted after the frame is submitted -> safe m_pendingDispose.clear(); @@ -604,7 +605,8 @@ void QSGRhiDistanceFieldGlyphCache::saveTexture(QRhiTexture *texture, const QStr }; QRhiReadbackDescription rb(texture); - m_resourceUpdates->readBackTexture(rb, rbResult); + QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates(); + resourceUpdates->readBackTexture(rb, rbResult); } #endif diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h index 48d666e7e22..965b496e480 100644 --- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h +++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h @@ -57,10 +57,12 @@ QT_BEGIN_NAMESPACE +class QSGDefaultRenderContext; + class Q_QUICK_PRIVATE_EXPORT QSGRhiDistanceFieldGlyphCache : public QSGDistanceFieldGlyphCache { public: - QSGRhiDistanceFieldGlyphCache(QRhi *rhi, const QRawFont &font, int renderTypeQuality); + QSGRhiDistanceFieldGlyphCache(QSGDefaultRenderContext *rc, const QRawFont &font, int renderTypeQuality); virtual ~QSGRhiDistanceFieldGlyphCache(); void requestGlyphs(const QSet<glyph_t> &glyphs) override; @@ -114,11 +116,11 @@ class Q_QUICK_PRIVATE_EXPORT QSGRhiDistanceFieldGlyphCache : public QSGDistanceF return &m_textures[index]; } + QSGDefaultRenderContext *m_rc; QRhi *m_rhi; mutable int m_maxTextureSize = 0; int m_maxTextureCount = 3; QSGAreaAllocator *m_areaAllocator = nullptr; - QRhiResourceUpdateBatch *m_resourceUpdates = nullptr; QList<TextureInfo> m_textures; QHash<glyph_t, TextureInfo *> m_glyphsTexture; QSet<glyph_t> m_unusedGlyphs; diff --git a/src/quick/scenegraph/qsgrhilayer.cpp b/src/quick/scenegraph/qsgrhilayer.cpp index cef9737fd8f..849ed7d49f9 100644 --- a/src/quick/scenegraph/qsgrhilayer.cpp +++ b/src/quick/scenegraph/qsgrhilayer.cpp @@ -214,12 +214,8 @@ void QSGRhiLayer::releaseResources() delete m_rt; m_rt = nullptr; - if (m_rtRp) { - if (m_renderer) - m_renderer->invalidatePipelineCacheDependency(m_rtRp); - delete m_rtRp; - m_rtRp = nullptr; - } + delete m_rtRp; + m_rtRp = nullptr; delete m_ds; m_ds = nullptr; diff --git a/src/quick/scenegraph/qsgrhishadereffectnode.cpp b/src/quick/scenegraph/qsgrhishadereffectnode.cpp index 9868a7b0f47..5575731675f 100644 --- a/src/quick/scenegraph/qsgrhishadereffectnode.cpp +++ b/src/quick/scenegraph/qsgrhishadereffectnode.cpp @@ -47,6 +47,7 @@ #include <QQmlFile> #include <QFile> #include <QFileSelector> +#include <QMutexLocker> QT_BEGIN_NAMESPACE @@ -116,6 +117,12 @@ void QSGRhiShaderLinker::feedSamplers(const QSGShaderEffectNode::ShaderData &sha const QSGShaderEffectNode::VariableData &vd(shader.varData.at(i)); if (var.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler) { Q_ASSERT(vd.specialType == QSGShaderEffectNode::VariableData::Source); + +#ifndef QT_NO_DEBUG + int existingBindPoint = m_samplerNameMap.value(var.name, -1); + Q_ASSERT(existingBindPoint < 0 || existingBindPoint == var.bindPoint); +#endif + m_samplers.insert(var.bindPoint, vd.value); m_samplerNameMap.insert(var.name, var.bindPoint); } @@ -124,6 +131,12 @@ void QSGRhiShaderLinker::feedSamplers(const QSGShaderEffectNode::ShaderData &sha for (int idx : *dirtyIndices) { const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &var(shader.shaderInfo.variables.at(idx)); const QSGShaderEffectNode::VariableData &vd(shader.varData.at(idx)); + +#ifndef QT_NO_DEBUG + int existingBindPoint = m_samplerNameMap.value(var.name, -1); + Q_ASSERT(existingBindPoint < 0 || existingBindPoint == var.bindPoint); +#endif + m_samplers.insert(var.bindPoint, vd.value); m_samplerNameMap.insert(var.name, var.bindPoint); } @@ -207,7 +220,8 @@ QSGMaterialType *QSGRhiShaderMaterialTypeCache::get(const QShader &vs, const QSh return t; } -static QSGRhiShaderMaterialTypeCache shaderMaterialTypeCache; +static QHash<void *, QSGRhiShaderMaterialTypeCache> shaderMaterialTypeCache; +static QMutex shaderMaterialTypeCacheMutex; class QSGRhiShaderEffectMaterialShader : public QSGMaterialShader { @@ -576,9 +590,9 @@ void QSGRhiShaderEffectMaterial::updateTextureProviders(bool layoutChange) } QSGRhiShaderEffectNode::QSGRhiShaderEffectNode(QSGDefaultRenderContext *rc) - : m_rc(rc), - m_material(this) + : m_material(this) { + Q_UNUSED(rc); setFlag(UsePreprocess, true); setMaterial(&m_material); } @@ -657,7 +671,12 @@ void QSGRhiShaderEffectNode::syncMaterial(SyncData *syncData) m_material.m_fragmentShader = defaultFragmentShader; } - m_material.m_materialType = shaderMaterialTypeCache.get(m_material.m_vertexShader, m_material.m_fragmentShader); + { + QMutexLocker lock(&shaderMaterialTypeCacheMutex); + m_material.m_materialType = shaderMaterialTypeCache[syncData->materialTypeCacheKey].get(m_material.m_vertexShader, + m_material.m_fragmentShader); + } + m_material.m_linker.reset(m_material.m_vertexShader, m_material.m_fragmentShader); if (m_material.m_hasCustomVertexShader) { @@ -775,9 +794,10 @@ void QSGRhiShaderEffectNode::preprocess() } } -void QSGRhiShaderEffectNode::cleanupMaterialTypeCache() +void QSGRhiShaderEffectNode::cleanupMaterialTypeCache(void *materialTypeCacheKey) { - shaderMaterialTypeCache.reset(); + QMutexLocker lock(&shaderMaterialTypeCacheMutex); + shaderMaterialTypeCache[materialTypeCacheKey].reset(); } bool QSGRhiGuiThreadShaderEffectManager::hasSeparateSamplerAndTextureObjects() const @@ -805,7 +825,12 @@ void QSGRhiGuiThreadShaderEffectManager::prepareShaderCode(ShaderInfo::Type type const QString fn = m_fileSelector->select(QQmlFile::urlToLocalFileOrQrc(src)); const QShader s = loadShaderFromFile(fn); if (!s.isValid()) { - qWarning("ShaderEffect: Failed to deserialize QShader from %s", qPrintable(fn)); + qWarning("ShaderEffect: Failed to deserialize QShader from %s. " + "Either the filename is incorrect, or it is not a valid .qsb file. " + "In Qt 6 shaders must be preprocessed using the Qt Shader Tools infrastructure. " + "The vertexShader and fragmentShader properties are now URLs that are expected to point to .qsb files generated by the qsb tool. " + "See https://doc.qt.io/qt-6/qtshadertools-index.html for more information.", + qPrintable(fn)); m_status = Error; emit shaderCodePrepared(false, typeHint, src, result); emit logAndStatusChanged(); @@ -878,3 +903,5 @@ bool QSGRhiGuiThreadShaderEffectManager::reflect(ShaderInfo *result) } QT_END_NAMESPACE + +#include "moc_qsgrhishadereffectnode_p.cpp" diff --git a/src/quick/scenegraph/qsgrhishadereffectnode_p.h b/src/quick/scenegraph/qsgrhishadereffectnode_p.h index 0bef0d571d2..f60c5c8895f 100644 --- a/src/quick/scenegraph/qsgrhishadereffectnode_p.h +++ b/src/quick/scenegraph/qsgrhishadereffectnode_p.h @@ -135,14 +135,13 @@ class QSGRhiShaderEffectNode : public QSGShaderEffectNode void syncMaterial(SyncData *syncData) override; void preprocess() override; - static void cleanupMaterialTypeCache(); + static void cleanupMaterialTypeCache(void *materialTypeCacheKey); private Q_SLOTS: void handleTextureChange(); void handleTextureProviderDestroyed(QObject *object); private: - QSGDefaultRenderContext *m_rc; QSGRhiShaderEffectMaterial m_material; }; diff --git a/src/quick/scenegraph/qsgrhitextureglyphcache.cpp b/src/quick/scenegraph/qsgrhitextureglyphcache.cpp index 1ec7e0c92d0..e46a2d9556c 100644 --- a/src/quick/scenegraph/qsgrhitextureglyphcache.cpp +++ b/src/quick/scenegraph/qsgrhitextureglyphcache.cpp @@ -38,15 +38,18 @@ ****************************************************************************/ #include "qsgrhitextureglyphcache_p.h" +#include "qsgdefaultrendercontext_p.h" #include <qrgb.h> #include <private/qdrawhelper_p.h> QT_BEGIN_NAMESPACE -QSGRhiTextureGlyphCache::QSGRhiTextureGlyphCache(QRhi *rhi, QFontEngine::GlyphFormat format, const QTransform &matrix, +QSGRhiTextureGlyphCache::QSGRhiTextureGlyphCache(QSGDefaultRenderContext *rc, + QFontEngine::GlyphFormat format, const QTransform &matrix, const QColor &color) : QImageTextureGlyphCache(format, matrix, color), - m_rhi(rhi) + m_rc(rc), + m_rhi(rc->rhi()) { // Some OpenGL implementations, for instance macOS, have issues with // GL_ALPHA render targets. Similarly, BGRA may be problematic on GLES 2.0. @@ -56,13 +59,15 @@ QSGRhiTextureGlyphCache::QSGRhiTextureGlyphCache(QRhi *rhi, QFontEngine::GlyphFo QSGRhiTextureGlyphCache::~QSGRhiTextureGlyphCache() { - if (m_resourceUpdates) - m_resourceUpdates->release(); - - delete m_texture; + // A plain delete should work, but just in case commitResourceUpdates was + // not called and something is enqueued on the update batch for m_texture, + // defer until the end of the frame. + if (m_texture) + m_texture->deleteLater(); // should be empty, but just in case - qDeleteAll(m_pendingDispose); + for (QRhiTexture *t : qAsConst(m_pendingDispose)) + t->deleteLater(); } QRhiTexture *QSGRhiTextureGlyphCache::createEmptyTexture(QRhiTexture::Format format) @@ -73,8 +78,7 @@ QRhiTexture *QSGRhiTextureGlyphCache::createEmptyTexture(QRhiTexture::Format for return nullptr; } - if (!m_resourceUpdates) - m_resourceUpdates = m_rhi->nextResourceUpdateBatch(); + QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates(); // The new texture must be cleared to 0 always, this cannot be avoided // otherwise artifacts will occur around the glyphs. @@ -85,7 +89,7 @@ QRhiTexture *QSGRhiTextureGlyphCache::createEmptyTexture(QRhiTexture::Format for data.fill(0, m_size.width() * m_size.height() * 4); QRhiTextureSubresourceUploadDescription subresDesc(data.constData(), data.size()); subresDesc.setSourceSize(m_size); - m_resourceUpdates->uploadTexture(t, QRhiTextureUploadEntry(0, 0, subresDesc)); + resourceUpdates->uploadTexture(t, QRhiTextureUploadEntry(0, 0, subresDesc)); return t; } @@ -116,11 +120,9 @@ void QSGRhiTextureGlyphCache::resizeTextureData(int width, int height) if (!t) return; - if (!m_resourceUpdates) - m_resourceUpdates = m_rhi->nextResourceUpdateBatch(); - + QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates(); if (m_resizeWithTextureCopy) { - m_resourceUpdates->copyTexture(t, m_texture); + resourceUpdates->copyTexture(t, m_texture); } else { QImageTextureGlyphCache::resizeTextureData(width, height); QImage img = image(); @@ -128,7 +130,7 @@ void QSGRhiTextureGlyphCache::resizeTextureData(int width, int height) QRhiTextureSubresourceUploadDescription subresDesc(img); const QSize oldSize = m_texture->pixelSize(); subresDesc.setSourceSize(QSize(qMin(oldSize.width(), width), qMin(oldSize.height(), height))); - m_resourceUpdates->uploadTexture(t, QRhiTextureUploadEntry(0, 0, subresDesc)); + resourceUpdates->uploadTexture(t, QRhiTextureUploadEntry(0, 0, subresDesc)); } m_pendingDispose.insert(m_texture); @@ -222,18 +224,19 @@ void QSGRhiTextureGlyphCache::endFillTexture() return; } - if (!m_resourceUpdates) - m_resourceUpdates = m_rhi->nextResourceUpdateBatch(); - + QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates(); QRhiTextureUploadDescription desc; desc.setEntries(m_uploads.cbegin(), m_uploads.cend()); - m_resourceUpdates->uploadTexture(m_texture, desc); + resourceUpdates->uploadTexture(m_texture, desc); m_uploads.clear(); } int QSGRhiTextureGlyphCache::glyphPadding() const { - return 1; + if (m_format == QFontEngine::Format_Mono) + return 8; + else + return 1; } int QSGRhiTextureGlyphCache::maxTextureWidth() const @@ -251,14 +254,13 @@ int QSGRhiTextureGlyphCache::maxTextureHeight() const void QSGRhiTextureGlyphCache::commitResourceUpdates(QRhiResourceUpdateBatch *mergeInto) { - if (m_resourceUpdates) { - mergeInto->merge(m_resourceUpdates); - m_resourceUpdates->release(); - m_resourceUpdates = nullptr; + if (QRhiResourceUpdateBatch *resourceUpdates = m_rc->maybeGlyphCacheResourceUpdates()) { + mergeInto->merge(resourceUpdates); + m_rc->releaseGlyphCacheResourceUpdates(); } // now let's assume the resource updates will be committed in this frame - for (QRhiTexture *t : m_pendingDispose) + for (QRhiTexture *t : qAsConst(m_pendingDispose)) t->deleteLater(); // will be deleted after the frame is submitted -> safe m_pendingDispose.clear(); diff --git a/src/quick/scenegraph/qsgrhitextureglyphcache_p.h b/src/quick/scenegraph/qsgrhitextureglyphcache_p.h index c3964ee09f8..093d5424c89 100644 --- a/src/quick/scenegraph/qsgrhitextureglyphcache_p.h +++ b/src/quick/scenegraph/qsgrhitextureglyphcache_p.h @@ -56,10 +56,13 @@ QT_BEGIN_NAMESPACE +class QSGDefaultRenderContext; + class QSGRhiTextureGlyphCache : public QImageTextureGlyphCache { public: - QSGRhiTextureGlyphCache(QRhi *rhi, QFontEngine::GlyphFormat format, const QTransform &matrix, + QSGRhiTextureGlyphCache(QSGDefaultRenderContext *rc, + QFontEngine::GlyphFormat format, const QTransform &matrix, const QColor &color = QColor()); ~QSGRhiTextureGlyphCache(); @@ -86,9 +89,9 @@ class QSGRhiTextureGlyphCache : public QImageTextureGlyphCache void prepareGlyphImage(QImage *img); QRhiTexture *createEmptyTexture(QRhiTexture::Format format); + QSGDefaultRenderContext *m_rc; QRhi *m_rhi; bool m_resizeWithTextureCopy; - QRhiResourceUpdateBatch *m_resourceUpdates = nullptr; QRhiTexture *m_texture = nullptr; QSize m_size; bool m_bgra = false; diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 8a0202ede98..45639ba93ba 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -285,7 +285,7 @@ class QSGRenderThread : public QThread , stopEventProcessing(false) { sgrc = static_cast<QSGDefaultRenderContext *>(renderContext); -#if defined(Q_OS_QNX) && defined(Q_PROCESSOR_X86) +#if (defined(Q_OS_QNX) && defined(Q_PROCESSOR_X86)) || defined(Q_OS_INTEGRITY) // The SDP 6.6.0 x86 MESA driver requires a larger stack than the default. setStackSize(1024 * 1024); #endif @@ -444,11 +444,11 @@ bool QSGRenderThread::event(QEvent *e) if (ce->window) { if (rhi) { QQuickWindowPrivate *cd = QQuickWindowPrivate::get(ce->window); - cd->rhi->makeThreadLocalNativeContextCurrent(); // The assumption is that the swapchain is usable, because on // expose the thread starts up and renders a frame so one cannot // get here without having done at least one on-screen frame. cd->rhi->beginFrame(cd->swapchain); + cd->rhi->makeThreadLocalNativeContextCurrent(); // for custom GL rendering before/during/after sync cd->syncSceneGraph(); sgrc->endSync(); cd->renderSceneGraph(ce->window->size()); @@ -511,27 +511,19 @@ void QSGRenderThread::invalidateGraphics(QQuickWindow *window, bool inDestructor return; } - bool wipeSG = inDestructor || !window->isPersistentSceneGraph(); bool wipeGraphics = inDestructor || (wipeSG && !window->isPersistentGraphics()); - bool current = true; - if (rhi) - rhi->makeThreadLocalNativeContextCurrent(); - - if (Q_UNLIKELY(!current)) { - qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- cleanup without an OpenGL context"); - } + rhi->makeThreadLocalNativeContextCurrent(); QQuickWindowPrivate *dd = QQuickWindowPrivate::get(window); -#if QT_CONFIG(quick_shadereffect) - QSGRhiShaderEffectNode::cleanupMaterialTypeCache(); -#endif - // The canvas nodes must be cleaned up regardless if we are in the destructor.. if (wipeSG) { dd->cleanupNodesOnShutdown(); +#if QT_CONFIG(quick_shadereffect) + QSGRhiShaderEffectNode::cleanupMaterialTypeCache(window); +#endif } else { qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent SG, avoiding cleanup"); return; @@ -558,6 +550,7 @@ void QSGRenderThread::invalidateGraphics(QQuickWindow *window, bool inDestructor } QSGRhiSupport::instance()->destroyRhi(rhi); rhi = nullptr; + dd->rhi = nullptr; qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- QRhi destroyed"); } else { qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent GL, avoiding cleanup"); @@ -575,7 +568,7 @@ void QSGRenderThread::sync(bool inExpose) Q_ASSERT_X(wm->m_lockedForSync, "QSGRenderThread::sync()", "sync triggered on bad terms as gui is not already locked..."); - bool current = true; + bool canSync = true; if (rhi) { if (windowSize.width() > 0 && windowSize.height() > 0) { // With the rhi making the (OpenGL) context current serves only one @@ -587,12 +580,12 @@ void QSGRenderThread::sync(bool inExpose) } else { // Zero size windows do not initialize a swapchain and // rendercontext. So no sync or render can be done then. - current = false; + canSync = false; } } else { - current = false; + canSync = false; } - if (current) { + if (canSync) { QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); bool hadRenderer = d->renderer != nullptr; // If the scene graph was touched since the last sync() make sure it sends the @@ -774,16 +767,15 @@ void QSGRenderThread::syncAndRender() d->animationController->unlock(); } - bool current = true; // Zero size windows do not initialize a swapchain and // rendercontext. So no sync or render can be done then. - if (d->renderer && windowSize.width() > 0 && windowSize.height() > 0 && rhi) - rhi->makeThreadLocalNativeContextCurrent(); - else - current = false; + const bool canRender = d->renderer && cd->swapchain && windowSize.width() > 0 && windowSize.height() > 0; + + if (canRender) { + if (!syncRequested) // else this was already done in sync() + rhi->makeThreadLocalNativeContextCurrent(); - if (current) { - d->renderSceneGraph(windowSize, rhi ? cd->swapchain->currentPixelSize() : QSize()); + d->renderSceneGraph(windowSize, cd->swapchain->currentPixelSize()); if (profileFrames) renderTime = threadTimer.nsecsElapsed(); @@ -821,7 +813,7 @@ void QSGRenderThread::syncAndRender() // beforeFrameBegin - afterFrameEnd must always come in pairs; if there was // no before due to 0 size then there shouldn't be an after either - if (current) + if (canRender) emit window->afterFrameEnd(); // Though it would be more correct to put this block directly after @@ -915,6 +907,8 @@ void QSGRenderThread::ensureRhi() } } if (!sgrc->rhi() && windowSize.width() > 0 && windowSize.height() > 0) { + // We need to guarantee that sceneGraphInitialized is emitted + // with a context current, if running with OpenGL. rhi->makeThreadLocalNativeContextCurrent(); QSGDefaultRenderContext::InitParams rcParams; rcParams.rhi = rhi; @@ -1192,20 +1186,6 @@ void QSGThreadedRenderLoop::windowDestroyed(QQuickWindow *window) void QSGThreadedRenderLoop::releaseSwapchain(QQuickWindow *window) { QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window); - - // Counterintuitive, because this is not needed under normal circumstances - // due to the render loop using a dedicated rendercontext per thread, so - // per window. Problem is, there are cases like calling destroy(); show(); - // on the QQuickWindow. (and we get here on SurfaceAboutToBeDestroyed, i.e. - // from destroy()) - // - // That means recreating the native window and all the related graphics - // infrastructure, but the rendercontext stays around. So still have to - // notify the renderer to invalidate the relevant objects in the caches. - // - if (wd->renderer) - wd->renderer->invalidatePipelineCacheDependency(wd->rpDescForSwapchain); - delete wd->rpDescForSwapchain; wd->rpDescForSwapchain = nullptr; delete wd->swapchain; diff --git a/src/quick/scenegraph/shaders_ng/24bittextmask.frag b/src/quick/scenegraph/shaders_ng/24bittextmask.frag index bc3826a9242..49023666ce9 100644 --- a/src/quick/scenegraph/shaders_ng/24bittextmask.frag +++ b/src/quick/scenegraph/shaders_ng/24bittextmask.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; @@ -6,8 +9,9 @@ layout(location = 0) out vec4 fragColor; layout(binding = 1) uniform sampler2D _qt_texture; layout(std140, binding = 0) uniform buf { - mat4 matrix; - vec4 color; // only alpha is used, but must be vec4 due to layout compat + mat4 modelViewMatrix; + mat4 projectionMatrix; + vec4 color; vec2 textureScale; float dpr; } ubuf; diff --git a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag index 63e445f90bb..000adb619e7 100644 --- a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag +++ b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; @@ -6,8 +9,9 @@ layout(location = 0) out vec4 fragColor; layout(binding = 1) uniform sampler2D _qt_texture; layout(std140, binding = 0) uniform buf { - mat4 matrix; - vec4 color; // only alpha is used, but must be vec4 due to layout compat + mat4 modelViewMatrix; + mat4 projectionMatrix; + vec4 color; vec2 textureScale; float dpr; } ubuf; diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask.frag b/src/quick/scenegraph/shaders_ng/8bittextmask.frag index 6304e821ffe..9507728803f 100644 --- a/src/quick/scenegraph/shaders_ng/8bittextmask.frag +++ b/src/quick/scenegraph/shaders_ng/8bittextmask.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; @@ -6,7 +9,8 @@ layout(location = 0) out vec4 fragColor; layout(binding = 1) uniform sampler2D _qt_texture; layout(std140, binding = 0) uniform buf { - mat4 matrix; + mat4 modelViewMatrix; + mat4 projectionMatrix; vec4 color; vec2 textureScale; float dpr; diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag index 0d0fa1cd3a4..9c0f36b81f5 100644 --- a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag +++ b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; @@ -6,7 +9,8 @@ layout(location = 0) out vec4 fragColor; layout(binding = 1) uniform sampler2D _qt_texture; layout(std140, binding = 0) uniform buf { - mat4 matrix; + mat4 modelViewMatrix; + mat4 projectionMatrix; vec4 color; vec2 textureScale; float dpr; diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag index b1551d8ef4f..9e89d17219b 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag +++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag index 7c6bd9a4936..4fe30b69ee7 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag +++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a_fwidth.frag b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a_fwidth.frag index 30ec465791f..4dc7432e44f 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a_fwidth.frag +++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a_fwidth.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_fwidth.frag b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_fwidth.frag index 511bffb09ab..44aea6b979a 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_fwidth.frag +++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_fwidth.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag index aa3390094b0..320c19973b8 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag +++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag index ab3a5f63ff7..0ddd1b40d1a 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag +++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a_fwidth.frag b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a_fwidth.frag index 8f528fea1e3..8b124213a4a 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a_fwidth.frag +++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a_fwidth.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_fwidth.frag b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_fwidth.frag index a71cc1d9b0a..40f519636ed 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_fwidth.frag +++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_fwidth.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext.frag b/src/quick/scenegraph/shaders_ng/distancefieldtext.frag index d594207567d..a86f68c8cb8 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldtext.frag +++ b/src/quick/scenegraph/shaders_ng/distancefieldtext.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag b/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag index bb807d86d81..449647561fa 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag +++ b/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext_a_fwidth.frag b/src/quick/scenegraph/shaders_ng/distancefieldtext_a_fwidth.frag index 1aa1175b573..534ec9208c6 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldtext_a_fwidth.frag +++ b/src/quick/scenegraph/shaders_ng/distancefieldtext_a_fwidth.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext_fwidth.frag b/src/quick/scenegraph/shaders_ng/distancefieldtext_fwidth.frag index a698c195501..04886d6b125 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldtext_fwidth.frag +++ b/src/quick/scenegraph/shaders_ng/distancefieldtext_fwidth.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/flatcolor.frag b/src/quick/scenegraph/shaders_ng/flatcolor.frag index 3a677b7c93f..cac8f1fb178 100644 --- a/src/quick/scenegraph/shaders_ng/flatcolor.frag +++ b/src/quick/scenegraph/shaders_ng/flatcolor.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) out vec4 fragColor; diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag index 723227a04d6..19dce21aa45 100644 --- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag +++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag index a9d56f63800..0cfe63edbf7 100644 --- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag +++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag index 08b2ce5187f..343e93f54f7 100644 --- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag +++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec3 sampleNearLeft; diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag index ef9407491b2..e5aef90fda3 100644 --- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag +++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec3 sampleNearLeft; diff --git a/src/quick/scenegraph/shaders_ng/opaquetexture.frag b/src/quick/scenegraph/shaders_ng/opaquetexture.frag index 2cd2175f874..18dd7e0fcbd 100644 --- a/src/quick/scenegraph/shaders_ng/opaquetexture.frag +++ b/src/quick/scenegraph/shaders_ng/opaquetexture.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 qt_TexCoord; diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.frag b/src/quick/scenegraph/shaders_ng/outlinedtext.frag index 947d161a509..6a5e1aa28b3 100644 --- a/src/quick/scenegraph/shaders_ng/outlinedtext.frag +++ b/src/quick/scenegraph/shaders_ng/outlinedtext.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; @@ -11,11 +14,12 @@ layout(location = 0) out vec4 fragColor; layout(binding = 1) uniform sampler2D _qt_texture; layout(std140, binding = 0) uniform buf { - // must match styledtext - mat4 matrix; + mat4 modelViewMatrix; + mat4 projectionMatrix; vec4 color; vec2 textureScale; float dpr; + // the above must stay compatible with textmask/8bittextmask vec4 styleColor; vec2 shift; } ubuf; diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.vert b/src/quick/scenegraph/shaders_ng/outlinedtext.vert index 023f9dfdc26..4068e42f28c 100644 --- a/src/quick/scenegraph/shaders_ng/outlinedtext.vert +++ b/src/quick/scenegraph/shaders_ng/outlinedtext.vert @@ -10,11 +10,12 @@ layout(location = 3) out vec2 sCoordLeft; layout(location = 4) out vec2 sCoordRight; layout(std140, binding = 0) uniform buf { - // must match styledtext - mat4 matrix; + mat4 modelViewMatrix; + mat4 projectionMatrix; vec4 color; vec2 textureScale; float dpr; + // the above must stay compatible with textmask/8bittextmask vec4 styleColor; vec2 shift; } ubuf; @@ -28,6 +29,6 @@ void main() sCoordDown = (tCoord - vec2(0.0, 1.0)) * ubuf.textureScale; sCoordLeft = (tCoord - vec2(-1.0, 0.0)) * ubuf.textureScale; sCoordRight = (tCoord - vec2(1.0, 0.0)) * ubuf.textureScale; - vec3 dprSnapPos = floor(vCoord.xyz * ubuf.dpr + 0.5) / ubuf.dpr; - gl_Position = ubuf.matrix * vec4(dprSnapPos, vCoord.w); + vec4 xformed = ubuf.modelViewMatrix * vCoord; + gl_Position = ubuf.projectionMatrix * vec4(floor(xformed.xyz * ubuf.dpr + 0.5) / ubuf.dpr, xformed.w); } diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag index 5b7bd9ca820..853f08e8ee8 100644 --- a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag +++ b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; @@ -11,11 +14,12 @@ layout(location = 0) out vec4 fragColor; layout(binding = 1) uniform sampler2D _qt_texture; layout(std140, binding = 0) uniform buf { - // must match styledtext - mat4 matrix; + mat4 modelViewMatrix; + mat4 projectionMatrix; vec4 color; vec2 textureScale; float dpr; + // the above must stay compatible with textmask/8bittextmask vec4 styleColor; vec2 shift; } ubuf; diff --git a/src/quick/scenegraph/shaders_ng/shadereffect.frag b/src/quick/scenegraph/shaders_ng/shadereffect.frag index bde493f6cee..ef4bbe78f30 100644 --- a/src/quick/scenegraph/shaders_ng/shadereffect.frag +++ b/src/quick/scenegraph/shaders_ng/shadereffect.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 qt_TexCoord0; diff --git a/src/quick/scenegraph/shaders_ng/smoothcolor.frag b/src/quick/scenegraph/shaders_ng/smoothcolor.frag index ede283be0c7..314a387922b 100644 --- a/src/quick/scenegraph/shaders_ng/smoothcolor.frag +++ b/src/quick/scenegraph/shaders_ng/smoothcolor.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec4 color; diff --git a/src/quick/scenegraph/shaders_ng/smoothtexture.frag b/src/quick/scenegraph/shaders_ng/smoothtexture.frag index b06764ad953..a7ddc57535e 100644 --- a/src/quick/scenegraph/shaders_ng/smoothtexture.frag +++ b/src/quick/scenegraph/shaders_ng/smoothtexture.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 texCoord; diff --git a/src/quick/scenegraph/shaders_ng/sprite.frag b/src/quick/scenegraph/shaders_ng/sprite.frag index 338f5e957ee..846958c71ce 100644 --- a/src/quick/scenegraph/shaders_ng/sprite.frag +++ b/src/quick/scenegraph/shaders_ng/sprite.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec4 fTexS; diff --git a/src/quick/scenegraph/shaders_ng/stencilclip.frag b/src/quick/scenegraph/shaders_ng/stencilclip.frag index 3f6222389d2..ec4d3a05b16 100644 --- a/src/quick/scenegraph/shaders_ng/stencilclip.frag +++ b/src/quick/scenegraph/shaders_ng/stencilclip.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) out vec4 fragColor; diff --git a/src/quick/scenegraph/shaders_ng/styledtext.frag b/src/quick/scenegraph/shaders_ng/styledtext.frag index 0b16396037f..df14c09aed1 100644 --- a/src/quick/scenegraph/shaders_ng/styledtext.frag +++ b/src/quick/scenegraph/shaders_ng/styledtext.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; @@ -8,7 +11,8 @@ layout(location = 0) out vec4 fragColor; layout(binding = 1) uniform sampler2D _qt_texture; layout(std140, binding = 0) uniform buf { - mat4 matrix; + mat4 modelViewMatrix; + mat4 projectionMatrix; vec4 color; vec2 textureScale; float dpr; diff --git a/src/quick/scenegraph/shaders_ng/styledtext.vert b/src/quick/scenegraph/shaders_ng/styledtext.vert index beadf07c79c..271dae8d8a6 100644 --- a/src/quick/scenegraph/shaders_ng/styledtext.vert +++ b/src/quick/scenegraph/shaders_ng/styledtext.vert @@ -7,7 +7,8 @@ layout(location = 0) out vec2 sampleCoord; layout(location = 1) out vec2 shiftedSampleCoord; layout(std140, binding = 0) uniform buf { - mat4 matrix; + mat4 modelViewMatrix; + mat4 projectionMatrix; vec4 color; vec2 textureScale; float dpr; @@ -22,6 +23,6 @@ void main() { sampleCoord = tCoord * ubuf.textureScale; shiftedSampleCoord = (tCoord - ubuf.shift) * ubuf.textureScale; - vec3 dprSnapPos = floor(vCoord.xyz * ubuf.dpr + 0.5) / ubuf.dpr; - gl_Position = ubuf.matrix * vec4(dprSnapPos, vCoord.w); + vec4 xformed = ubuf.modelViewMatrix * vCoord; + gl_Position = ubuf.projectionMatrix * vec4(floor(xformed.xyz * ubuf.dpr + 0.5) / ubuf.dpr, xformed.w); } diff --git a/src/quick/scenegraph/shaders_ng/styledtext_a.frag b/src/quick/scenegraph/shaders_ng/styledtext_a.frag index b6731378956..eda1062f2df 100644 --- a/src/quick/scenegraph/shaders_ng/styledtext_a.frag +++ b/src/quick/scenegraph/shaders_ng/styledtext_a.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; @@ -8,7 +11,8 @@ layout(location = 0) out vec4 fragColor; layout(binding = 1) uniform sampler2D _qt_texture; layout(std140, binding = 0) uniform buf { - mat4 matrix; + mat4 modelViewMatrix; + mat4 projectionMatrix; vec4 color; vec2 textureScale; float dpr; diff --git a/src/quick/scenegraph/shaders_ng/textmask.frag b/src/quick/scenegraph/shaders_ng/textmask.frag index 518d5c965f9..49023666ce9 100644 --- a/src/quick/scenegraph/shaders_ng/textmask.frag +++ b/src/quick/scenegraph/shaders_ng/textmask.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 sampleCoord; @@ -6,7 +9,8 @@ layout(location = 0) out vec4 fragColor; layout(binding = 1) uniform sampler2D _qt_texture; layout(std140, binding = 0) uniform buf { - mat4 matrix; + mat4 modelViewMatrix; + mat4 projectionMatrix; vec4 color; vec2 textureScale; float dpr; diff --git a/src/quick/scenegraph/shaders_ng/textmask.vert b/src/quick/scenegraph/shaders_ng/textmask.vert index 9d80d5dadb6..e0b3c01bcea 100644 --- a/src/quick/scenegraph/shaders_ng/textmask.vert +++ b/src/quick/scenegraph/shaders_ng/textmask.vert @@ -6,7 +6,8 @@ layout(location = 1) in vec2 tCoord; layout(location = 0) out vec2 sampleCoord; layout(std140, binding = 0) uniform buf { - mat4 matrix; + mat4 modelViewMatrix; + mat4 projectionMatrix; vec4 color; vec2 textureScale; float dpr; @@ -17,6 +18,6 @@ out gl_PerVertex { vec4 gl_Position; }; void main() { sampleCoord = tCoord * ubuf.textureScale; - vec3 dprSnapPos = floor(vCoord.xyz * ubuf.dpr + 0.5) / ubuf.dpr; - gl_Position = ubuf.matrix * vec4(dprSnapPos, vCoord.w); + vec4 xformed = ubuf.modelViewMatrix * vCoord; + gl_Position = ubuf.projectionMatrix * vec4(floor(xformed.xyz * ubuf.dpr + 0.5) / ubuf.dpr, xformed.w); } diff --git a/src/quick/scenegraph/shaders_ng/texture.frag b/src/quick/scenegraph/shaders_ng/texture.frag index bd22f817e03..d4be87ec292 100644 --- a/src/quick/scenegraph/shaders_ng/texture.frag +++ b/src/quick/scenegraph/shaders_ng/texture.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 qt_TexCoord; diff --git a/src/quick/scenegraph/shaders_ng/vertexcolor.frag b/src/quick/scenegraph/shaders_ng/vertexcolor.frag index ede283be0c7..314a387922b 100644 --- a/src/quick/scenegraph/shaders_ng/vertexcolor.frag +++ b/src/quick/scenegraph/shaders_ng/vertexcolor.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec4 color; diff --git a/src/quick/scenegraph/shaders_ng/visualization.frag b/src/quick/scenegraph/shaders_ng/visualization.frag index 29f718fe5d5..378afc20882 100644 --- a/src/quick/scenegraph/shaders_ng/visualization.frag +++ b/src/quick/scenegraph/shaders_ng/visualization.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 pos; diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp index d97d48c78d5..fc1b3aec24b 100644 --- a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp +++ b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp @@ -206,13 +206,11 @@ void QSGDefaultPainterNode::updateRenderTarget() m_image = QImage(m_textureSize, QImage::Format_ARGB32_Premultiplied); m_image.fill(Qt::transparent); - QSGPainterTexture *texture = new QSGPainterTexture; - texture->setOwnsTexture(true); - texture->setTextureSize(m_textureSize); - if (m_texture) - delete m_texture; - - m_texture = texture; + if (!m_texture) { + m_texture = new QSGPainterTexture; + m_texture->setOwnsTexture(true); + } + m_texture->setTextureSize(m_textureSize); } void QSGDefaultPainterNode::setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target) diff --git a/src/quick/scenegraph/util/qsgplaintexture.cpp b/src/quick/scenegraph/util/qsgplaintexture.cpp index 6e59f9e6070..128094cc946 100644 --- a/src/quick/scenegraph/util/qsgplaintexture.cpp +++ b/src/quick/scenegraph/util/qsgplaintexture.cpp @@ -231,7 +231,12 @@ void QSGPlainTexture::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch } } - bool needsRebuild = m_texture && m_texture->pixelSize() != m_texture_size; + bool needsRebuild = false; + + if (m_texture && m_texture->pixelSize() != m_texture_size) { + m_texture->setPixelSize(m_texture_size); + needsRebuild = true; + } if (mipmappingChanged) { QRhiTexture::Flags f = m_texture->flags(); @@ -276,3 +281,5 @@ void QSGPlainTexture::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch } QT_END_NAMESPACE + +#include "moc_qsgplaintexture_p.cpp" diff --git a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp index d60b77ce2e6..2a7be48d3d7 100644 --- a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp @@ -57,7 +57,7 @@ int qt_sg_envInt(const char *name, int defaultValue); static QElapsedTimer qsg_renderer_timer; -DEFINE_BOOL_CONFIG_OPTION(qsgDisableCompressedAtlas, QSG_DISABLE_COMPRESSED_ATLAS) +DEFINE_BOOL_CONFIG_OPTION(qsgEnableCompressedAtlas, QSG_ENABLE_COMPRESSED_ATLAS) namespace QSGRhiAtlasTexture { @@ -124,7 +124,7 @@ QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel) QSGTexture *Manager::create(const QSGCompressedTextureFactory *factory) { QSGTexture *t = nullptr; - if (qsgDisableCompressedAtlas() || !factory->textureData()->isValid()) + if (!qsgEnableCompressedAtlas() || !factory->textureData()->isValid()) return t; unsigned int format = factory->textureData()->glInternalFormat(); diff --git a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp index 8dbfcad38b8..b8f0f336f20 100644 --- a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp +++ b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp @@ -292,7 +292,7 @@ void QSGSimpleTextureNode::setTextureCoordinatesTransform(QSGSimpleTextureNode:: return; d->texCoordMode = mode; qsgsimpletexturenode_update(&m_geometry, texture(), m_rect, d->sourceRect, d->texCoordMode); - markDirty(DirtyMaterial); + markDirty(DirtyGeometry | DirtyMaterial); } /*! diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp index 0573cd8966a..82cdd03acc5 100644 --- a/src/quick/scenegraph/util/qsgtexturematerial.cpp +++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp @@ -81,6 +81,10 @@ void QSGOpaqueTextureMaterialRhiShader::updateSampledImage(RenderState &state, i Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type()); QSGOpaqueTextureMaterial *tx = static_cast<QSGOpaqueTextureMaterial *>(newMaterial); QSGTexture *t = tx->texture(); + if (!t) { + *texture = nullptr; + return; + } t->setFiltering(tx->filtering()); t->setMipmapFiltering(tx->mipmapFiltering()); diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index 28cea4b93da..af60f5b02b7 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -1664,14 +1664,16 @@ void QQuickRotationAnimation::setTo(qreal t) Possible values are: - \list - \li RotationAnimation.Numerical (default) - Rotate by linearly interpolating between the two numbers. - A rotation from 10 to 350 will rotate 340 degrees clockwise. - \li RotationAnimation.Clockwise - Rotate clockwise between the two values - \li RotationAnimation.Counterclockwise - Rotate counterclockwise between the two values - \li RotationAnimation.Shortest - Rotate in the direction that produces the shortest animation path. - A rotation from 10 to 350 will rotate 20 degrees counterclockwise. - \endlist + \value RotationAnimation.Numerical + (default) Rotate by linearly interpolating between the two numbers. + A rotation from \c 10 to \c 350 will rotate 340 degrees clockwise. + \value RotationAnimation.Clockwise + Rotate clockwise between the two values + \value RotationAnimation.Counterclockwise + Rotate counterclockwise between the two values + \value RotationAnimation.Shortest + Rotate in the direction that produces the shortest animation path. + A rotation from \c 10 to \c 350 will rotate \c 20 degrees counterclockwise. */ QQuickRotationAnimation::RotationDirection QQuickRotationAnimation::direction() const { @@ -2019,8 +2021,9 @@ void QQuickBulkValueAnimator::updateCurrentTime(int currentTime) void QQuickBulkValueAnimator::topLevelAnimationLoopChanged() { - //check for new from every top-level loop (when the top level animation is started and all subsequent loops) - if (fromIsSourced) + // Check for new "from" value only when animation has one loop. + // Otherwise use the initial "from" value for every iteration. + if (m_loopCount == 1 && fromIsSourced) *fromIsSourced = false; QAbstractAnimationJob::topLevelAnimationLoopChanged(); } @@ -2564,7 +2567,38 @@ void QQuickPropertyAnimation::setProperties(const QString &prop) QQmlListProperty<QObject> QQuickPropertyAnimation::targets() { Q_D(QQuickPropertyAnimation); - return QQmlListProperty<QObject>(this, &(d->targets)); + using ListPtr = QList<QPointer<QObject>> *; + using LP = QQmlListProperty<QObject>; + LP::AppendFunction appendFn = [](LP *prop, QObject *value) + { + static_cast<ListPtr>(prop->data)->append(value); + }; + LP::CountFunction countFn = [](LP *prop) + { + return static_cast<ListPtr>(prop->data)->size(); + }; + + LP::AtFunction atFn = [](LP *prop, qsizetype index) -> QObject * + { + return static_cast<ListPtr>(prop->data)->at(index); + }; + + LP::ClearFunction clearFN = [](LP *prop) + { + return static_cast<ListPtr>(prop->data)->clear(); + }; + + LP::ReplaceFunction replaceFn = [](LP *prop, qsizetype index, QObject *value) + { + static_cast<ListPtr>(prop->data)->replace(index, value); + }; + + LP::RemoveLastFunction removeLastFn = [](LP *prop) + { + static_cast<ListPtr>(prop->data)->removeLast(); + }; + + return QQmlListProperty<QObject>(this, &(d->targets), appendFn, countFn, atFn, clearFN, replaceFn, removeLastFn); } /*! @@ -2636,7 +2670,7 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA if (!d->propertyName.isEmpty()) props << d->propertyName; - QList<QObject*> targets = d->targets; + QList<QPointer<QObject>> targets = d->targets; if (d->target) targets.append(d->target); @@ -2665,10 +2699,14 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA for (int i = 0; i < props.count(); ++i) { for (int j = 0; j < targets.count(); ++j) { + const auto& guarded = targets.at(j); + if (guarded.isNull()) + continue; + QObject *target = guarded.get(); QQuickStateAction myAction; QString errorMessage; const QString &propertyName = props.at(i); - myAction.property = d->createProperty(targets.at(j), propertyName, this, &errorMessage); + myAction.property = d->createProperty(target, propertyName, this, &errorMessage); if (myAction.property.isValid()) { if (usingDefaultProperties) successfullyCreatedDefaultProperty = true; diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h index b37680e92ab..97bf156d0da 100644 --- a/src/quick/util/qquickanimation_p_p.h +++ b/src/quick/util/qquickanimation_p_p.h @@ -125,7 +125,7 @@ class QQuickBulkValueUpdater }; //animates QQuickBulkValueUpdater (assumes start and end values will be reals or compatible) -class Q_AUTOTEST_EXPORT QQuickBulkValueAnimator : public QAbstractAnimationJob +class Q_QUICK_AUTOTEST_EXPORT QQuickBulkValueAnimator : public QAbstractAnimationJob { Q_DISABLE_COPY(QQuickBulkValueAnimator) public: @@ -279,7 +279,7 @@ class QQuickPropertyAnimationPrivate : public QQuickAbstractAnimationPrivate QObject *target; QString propertyName; QString properties; - QList<QObject *> targets; + QList<QPointer<QObject>> targets; QList<QObject *> exclude; QString defaultProperties; diff --git a/src/quick/util/qquickanimationcontroller_p.h b/src/quick/util/qquickanimationcontroller_p.h index de308735ef5..46daf0b98fd 100644 --- a/src/quick/util/qquickanimationcontroller_p.h +++ b/src/quick/util/qquickanimationcontroller_p.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE class QQuickAnimationControllerPrivate; -class Q_AUTOTEST_EXPORT QQuickAnimationController : public QObject, public QQmlParserStatus +class Q_QUICK_PRIVATE_EXPORT QQuickAnimationController : public QObject, public QQmlParserStatus { Q_OBJECT Q_INTERFACES(QQmlParserStatus) diff --git a/src/quick/util/qquickanimator.cpp b/src/quick/util/qquickanimator.cpp index cea23f374e1..1ee46cba008 100644 --- a/src/quick/util/qquickanimator.cpp +++ b/src/quick/util/qquickanimator.cpp @@ -484,14 +484,16 @@ QQuickAnimatorJob *QQuickRotationAnimator::createJob() const { Possible values are: - \list - \li RotationAnimator.Numerical (default) - Rotate by linearly interpolating between the two numbers. - A rotation from 10 to 350 will rotate 340 degrees clockwise. - \li RotationAnimator.Clockwise - Rotate clockwise between the two values - \li RotationAnimator.Counterclockwise - Rotate counterclockwise between the two values - \li RotationAnimator.Shortest - Rotate in the direction that produces the shortest animation path. - A rotation from 10 to 350 will rotate 20 degrees counterclockwise. - \endlist + \value RotationAnimator.Numerical + (default) Rotate by linearly interpolating between the two numbers. + A rotation from 10 to 350 will rotate 340 degrees clockwise. + \value RotationAnimator.Clockwise + Rotate clockwise between the two values + \value RotationAnimator.Counterclockwise + Rotate counterclockwise between the two values + \value RotationAnimator.Shortest + Rotate in the direction that produces the shortest animation path. + A rotation from 10 to 350 will rotate 20 degrees counterclockwise. */ void QQuickRotationAnimator::setDirection(RotationDirection dir) { diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index e18e31c023f..bdb47653df1 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -280,6 +280,17 @@ qreal QQuickAnimatorJob::progress(int time) const return m_easing.valueForProgress((m_duration == 0) ? qreal(1) : qreal(time) / qreal(m_duration)); } +void QQuickAnimatorJob::boundValue() +{ + qreal rangeMin = m_from; + qreal rangeMax = m_to; + if (m_from > m_to) { + rangeMax = m_from; + rangeMin = m_to; + } + m_value = qBound(rangeMin, m_value, rangeMax); +} + qreal QQuickAnimatorJob::value() const { qreal value = m_to; @@ -383,11 +394,12 @@ void QQuickTransformAnimatorJob::Helper::sync() wasSynced = true; } + // We update the node before checking on dirty, as the node might have changed without the animator running + node = d->itemNode(); + if (dirty == 0) return; - node = d->itemNode(); - if (dirty & QQuickItemPrivate::Position) { dx = item->x(); dy = item->y(); diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h index 2aa0e1a380c..171c0b302fc 100644 --- a/src/quick/util/qquickanimatorjob_p.h +++ b/src/quick/util/qquickanimatorjob_p.h @@ -120,10 +120,16 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnimatorJob : public QAbstractAnimationJob virtual void setTarget(QQuickItem *target); QQuickItem *target() const { return m_target; } - void setFrom(qreal from) { m_from = from; } + void setFrom(qreal from) { + m_from = from; + boundValue(); + } qreal from() const { return m_from; } - void setTo(qreal to) { m_to = to; } + void setTo(qreal to) { + m_to = to; + boundValue(); + } qreal to() const { return m_to; } void setDuration(int duration) { m_duration = duration; } @@ -169,6 +175,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnimatorJob : public QAbstractAnimationJob void debugAnimation(QDebug d) const override; qreal progress(int time) const; + void boundValue(); QPointer<QQuickItem> m_target; QQuickAnimatorController *m_controller; diff --git a/src/quick/util/qquickapplication.cpp b/src/quick/util/qquickapplication.cpp index fa67823824d..62e792199d8 100644 --- a/src/quick/util/qquickapplication.cpp +++ b/src/quick/util/qquickapplication.cpp @@ -50,11 +50,177 @@ QT_BEGIN_NAMESPACE -/* - This object and its properties are documented as part of the Qt object, - in qqmlengine.cpp +/*! + \qmltype Application + \instantiates QQuickApplication + \inqmlmodule QtQuick + //! once exposed: \inherits CoreApplication? + //! TODO: \ingroup ? + + \brief Provides access to global application + state properties shared by many QML components. + + The Application singleton exposes a subset of QApplication's properties to + QML applications. + + It also provides an aboutToQuit() signal, which is the same as + QCoreApplication::aboutToQuit(). + + \qml + import QtQuick + + Window { + id: root + visible: true + width: 800 + height: 680 + + title: `${Application.name} (${Application.version})` + + Connections { + target: Application + function onAboutToQuit() { + console.log("Bye!") + } + } + } + \endqml + + \sa SystemPalette +*/ + +/*! + \qmlproperty bool Application::active + \deprecated [5.2] + + Returns whether the application is active. + Use Application.state == Qt.ApplicationActive instead +*/ + +/*! + \qmlproperty Qt::ApplicationState Application::state + + This property represents the current state of the application. + + \qml + Timer { + interval: 1000; repeat: true + active: Application.state === Qt.Qt.ApplicationActive + onTriggered: imageFetcher.fetchLatestImages() + } + \endqml +*/ + +/*! + \qmlproperty Qt::LayoutDirection Application::layoutDirection + + This read-only property can be used to query the default layout + direction of the application. On system start-up, the default layout + direction depends on the application's language. The property has a + value of \c Qt.RightToLeft in locales where text and graphic elements + are read from right to left, and \c Qt.LeftToRight where the reading + direction flows from left to right. You can bind to this property to + customize your application layouts to support both layout directions. + + \qml + RowLayout { + layoutDirection: Application.layoutDirection + } + \endqml +*/ + +/*! + \qmlproperty bool Application::supportsMultipleWindows + + Returns \c true if the platform supports multiple windows. Some embedded + platforms do not support multiple windows, for example. + */ + +/*! + \qmlproperty QFont Application::font + Returns the default application font as returned by + \l QGuiApplication::font(). */ + +/*! + \qmlproperty QString Application::displayName + + This property represents the application display name set on the + QGuiApplication instance. This property can be written to in order to set + the application display name. + + \qml + Binding { + target: Application + property: "displayName" + value: "My Awesome Application" + } + \endqml +*/ + +/*! + \qmlproperty QQmlListProperty<QQuickScreenInfo> Application::screens + + An array containing the descriptions of all connected screens. The + elements of the array are objects with the same properties as the + \l{Screen} attached object. In practice the array corresponds to the screen + list returned by QGuiApplication::screens(). In addition to examining + properties like name, width, height, etc., the array elements can also be + assigned to the screen property of Window items, thus serving as an + alternative to the C++ side's QWindow::setScreen(). + + \sa Screen, Window, {Window::screen}{Window.screen} +*/ + +/* The following properties are from QQmlApplication. + ### Document those in QQmlApplication instead once it is exposed +*/ + +/*! + \qmlproperty QStringList Application::arguments + + This is a string list of the arguments the executable was invoked with. + */ + +/*! + \qmlproperty QString Application::name + + This is the application name set on the QCoreApplication instance. This + property can be written to in order to set the application name. + */ + +/*! + \qmlproperty QString Application::version + + This is the application version set on the QCoreApplication instance. This + property can be written to in order to set the application version. + */ + +/*! + \qmlproperty QString Application::organization + + This is the organization name set on the QCoreApplication instance. + This property can be written to in order to set the organization name. + */ + +/*! + \qmlproperty QString Application::domain + + This is the organization domain set on the QCoreApplication instance. + This property can be written to in order to set the organization domain. + */ + +/*! + \qmlsignal Application::aboutToQuit() + + This signal is emitted when the application is about to quit the main + event loop. The signal is particularly useful if your application has to + do some last-second cleanup. User interaction is not possible in this state. + For more information, see \l {Window::closing()}{Window.closing}. + + \sa QCoreApplication::aboutToQuit +*/ QQuickApplication::QQuickApplication(QObject *parent) : QQmlApplication(parent) { @@ -69,6 +235,7 @@ QQuickApplication::QQuickApplication(QObject *parent) connect(guiApp, &QGuiApplication::applicationDisplayNameChanged, this, &QQuickApplication::displayNameChanged); + connect(guiApp, &QGuiApplication::primaryScreenChanged, this, &QQuickApplication::updateScreens); connect(guiApp, &QGuiApplication::screenAdded, this, &QQuickApplication::updateScreens); connect(guiApp, &QGuiApplication::screenRemoved, this, &QQuickApplication::updateScreens); updateScreens(); diff --git a/src/quick/util/qquickapplication_p.h b/src/quick/util/qquickapplication_p.h index 634b9b4aad1..dd67b4b11de 100644 --- a/src/quick/util/qquickapplication_p.h +++ b/src/quick/util/qquickapplication_p.h @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQuickApplication : public QQmlApplication +class Q_QUICK_PRIVATE_EXPORT QQuickApplication : public QQmlApplication { Q_OBJECT Q_PROPERTY(bool active READ active NOTIFY activeChanged) // deprecated, use 'state' instead diff --git a/src/quick/util/qquickbehavior.cpp b/src/quick/util/qquickbehavior.cpp index eeda609816f..402c23e2afd 100644 --- a/src/quick/util/qquickbehavior.cpp +++ b/src/quick/util/qquickbehavior.cpp @@ -109,8 +109,13 @@ class UntypedProxyProperty : public QUntypedPropertyData const QUntypedPropertyBinding &binding) { auto This = static_cast<UntypedProxyProperty *>(d); - if (binding.valueMetaType() != This->type()) + const QMetaType type = This->type(); + if (binding.valueMetaType() != type) return {}; + + // We want to notify in any case here because the target property should be set + // even if our proxy binding results in the default value. + QPropertyBindingPrivate::get(binding)->scheduleNotify(); return This->m_bindingData.setBinding(binding, reinterpret_cast<QUntypedPropertyData *>( This->m_storage.data())); diff --git a/src/quick/util/qquickdeliveryagent.cpp b/src/quick/util/qquickdeliveryagent.cpp index 2b649d01cf9..7a6905b5dea 100644 --- a/src/quick/util/qquickdeliveryagent.cpp +++ b/src/quick/util/qquickdeliveryagent.cpp @@ -39,6 +39,7 @@ #include <QtCore/qdebug.h> #include <QtGui/private/qevent_p.h> +#include <QtGui/private/qeventpoint_p.h> #include <QtGui/private/qguiapplication_p.h> #include <QtGui/qpa/qplatformtheme.h> #include <QtQml/private/qabstractanimationjob_p.h> @@ -49,7 +50,7 @@ #include <QtQuick/private/qquickdrag_p.h> #endif #include <QtQuick/private/qquickprofiler_p.h> -#include <QtQuick/qquickrendercontrol.h> +#include <QtQuick/private/qquickrendercontrol_p.h> #include <QtQuick/private/qquickwindow_p.h> QT_BEGIN_NAMESPACE @@ -81,6 +82,7 @@ void QQuickDeliveryAgentPrivate::touchToMouseEvent(QEvent::Type type, const QEve (type == QEvent::MouseButtonRelease ? Qt::NoButton : Qt::LeftButton), touchEvent->modifiers(), Qt::MouseEventSynthesizedByQt); ret.setAccepted(true); // this now causes the persistent touchpoint to be accepted too + ret.setTimestamp(touchEvent->timestamp()); *mouseEvent = ret; } @@ -224,11 +226,7 @@ bool QQuickDeliveryAgentPrivate::deliverTouchAsMouse(QQuickItem *item, QTouchEve QPointF last = lastMousePosition; lastMousePosition = me.scenePosition(); - bool accepted = me.isAccepted(); - bool delivered = deliverHoverEvent(rootItem, me.scenePosition(), last, me.modifiers(), me.timestamp(), accepted); - // take care of any exits - if (!delivered) - clearHover(me.timestamp()); + deliverHoverEvent(me.scenePosition(), last, me.modifiers(), me.timestamp()); break; } } else if (p.state() & QEventPoint::State::Released) { @@ -241,7 +239,7 @@ bool QQuickDeliveryAgentPrivate::deliverTouchAsMouse(QQuickItem *item, QTouchEve if (item->acceptHoverEvents() && p.globalPosition() != QGuiApplicationPrivate::lastCursorPosition) { QPointF localMousePos(qInf(), qInf()); if (QWindow *w = item->window()) - localMousePos = item->mapFromScene(w->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition.toPoint())); + localMousePos = item->mapFromScene(w->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition)); QMouseEvent mm(QEvent::MouseMove, localMousePos, QGuiApplicationPrivate::lastCursorPosition, Qt::NoButton, Qt::NoButton, event.modifiers()); QCoreApplication::sendEvent(item, &mm); @@ -320,7 +318,7 @@ void QQuickDeliveryAgentPrivate::translateTouchEvent(QTouchEvent *touchEvent) static inline bool windowHasFocus(QQuickWindow *win) { const QWindow *focusWindow = QGuiApplication::focusWindow(); - return win == focusWindow || QQuickRenderControl::renderWindowFor(win) == focusWindow; + return win == focusWindow || QQuickRenderControlPrivate::isRenderWindowFor(win, focusWindow) || !focusWindow; } #ifdef Q_OS_WEBOS @@ -403,7 +401,9 @@ void QQuickDeliveryAgentPrivate::setFocusInScope(QQuickItem *scope, QQuickItem * if (item != rootItem && !(options & DontChangeSubFocusItem)) { QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem; if (oldSubFocusItem) { - QQuickItemPrivate::get(oldSubFocusItem)->focus = false; + QQuickItemPrivate *priv = QQuickItemPrivate::get(oldSubFocusItem); + priv->focus = false; + priv->notifyChangeListeners(QQuickItemPrivate::Focus, &QQuickItemChangeListener::itemFocusChanged, oldSubFocusItem, reason); changed << oldSubFocusItem; } @@ -419,6 +419,7 @@ void QQuickDeliveryAgentPrivate::setFocusInScope(QQuickItem *scope, QQuickItem * #endif ) { itemPrivate->focus = true; + itemPrivate->notifyChangeListeners(QQuickItemPrivate::Focus, &QQuickItemChangeListener::itemFocusChanged, item, reason); changed << item; } } @@ -458,7 +459,7 @@ void QQuickDeliveryAgentPrivate::setFocusInScope(QQuickItem *scope, QQuickItem * emit rootItem->window()->focusObjectChanged(activeFocusItem); if (!changed.isEmpty()) - notifyFocusChangesRecur(changed.data(), changed.count() - 1); + notifyFocusChangesRecur(changed.data(), changed.count() - 1, reason); if (isSubsceneAgent) { auto da = QQuickWindowPrivate::get(rootItem->window())->deliveryAgent; qCDebug(lcFocus) << " delegating setFocusInScope to" << da; @@ -520,14 +521,18 @@ void QQuickDeliveryAgentPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem if (item != rootItem && !(options & DontChangeSubFocusItem)) { QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem; if (oldSubFocusItem && !(options & DontChangeFocusProperty)) { - QQuickItemPrivate::get(oldSubFocusItem)->focus = false; + QQuickItemPrivate *priv = QQuickItemPrivate::get(oldSubFocusItem); + priv->focus = false; + priv->notifyChangeListeners(QQuickItemPrivate::Focus, &QQuickItemChangeListener::itemFocusChanged, oldSubFocusItem, reason); changed << oldSubFocusItem; } QQuickItemPrivate::get(item)->updateSubFocusItem(scope, false); } else if (!(options & DontChangeFocusProperty)) { - QQuickItemPrivate::get(item)->focus = false; + QQuickItemPrivate *priv = QQuickItemPrivate::get(item); + priv->focus = false; + priv->notifyChangeListeners(QQuickItemPrivate::Focus, &QQuickItemChangeListener::itemFocusChanged, item, reason); changed << item; } @@ -554,8 +559,12 @@ void QQuickDeliveryAgentPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem emit rootItem->window()->focusObjectChanged(activeFocusItem); if (!changed.isEmpty()) - notifyFocusChangesRecur(changed.data(), changed.count() - 1); - + notifyFocusChangesRecur(changed.data(), changed.count() - 1, reason); + if (isSubsceneAgent) { + auto da = QQuickWindowPrivate::get(rootItem->window())->deliveryAgent; + qCDebug(lcFocus) << " delegating clearFocusInScope to" << da; + QQuickWindowPrivate::get(rootItem->window())->deliveryAgentPrivate()->clearFocusInScope(da->rootItem(), item, reason, options); + } if (oldActiveFocusItem == activeFocusItem) qCDebug(lcFocus) << "activeFocusItem remains" << activeFocusItem << "in" << q; else @@ -570,27 +579,29 @@ void QQuickDeliveryAgentPrivate::clearFocusObject() clearFocusInScope(rootItem, QQuickItemPrivate::get(rootItem)->subFocusItem, Qt::OtherFocusReason); } -void QQuickDeliveryAgentPrivate::notifyFocusChangesRecur(QQuickItem **items, int remaining) +void QQuickDeliveryAgentPrivate::notifyFocusChangesRecur(QQuickItem **items, int remaining, Qt::FocusReason reason) { QPointer<QQuickItem> item(*items); - if (remaining) - notifyFocusChangesRecur(items + 1, remaining - 1); - if (item) { QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); if (itemPrivate->notifiedFocus != itemPrivate->focus) { itemPrivate->notifiedFocus = itemPrivate->focus; + itemPrivate->notifyChangeListeners(QQuickItemPrivate::Focus, &QQuickItemChangeListener::itemFocusChanged, item, reason); emit item->focusChanged(itemPrivate->focus); } if (item && itemPrivate->notifiedActiveFocus != itemPrivate->activeFocus) { itemPrivate->notifiedActiveFocus = itemPrivate->activeFocus; itemPrivate->itemChange(QQuickItem::ItemActiveFocusHasChanged, itemPrivate->activeFocus); + itemPrivate->notifyChangeListeners(QQuickItemPrivate::Focus, &QQuickItemChangeListener::itemFocusChanged, item, reason); emit item->activeFocusChanged(itemPrivate->activeFocus); } } + + if (remaining) + notifyFocusChangesRecur(items + 1, remaining - 1, reason); } bool QQuickDeliveryAgentPrivate::clearHover(ulong timestamp) @@ -602,15 +613,19 @@ bool QQuickDeliveryAgentPrivate::clearHover(ulong timestamp) if (!window) return false; - QPointF pos = window->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition.toPoint()); + const QPointF lastPos = window->mapFromGlobal(QGuiApplicationPrivate::lastCursorPosition); + const auto modifiers = QGuiApplication::keyboardModifiers(); + const bool clearHover = true; - bool accepted = false; - for (QQuickItem* item : qAsConst(hoverItems)) { + for (auto hoverItem : hoverItems) { + auto item = hoverItem.first; if (item) - accepted = sendHoverEvent(QEvent::HoverLeave, item, pos, pos, QGuiApplication::keyboardModifiers(), timestamp) || accepted; + deliverHoverEventToItem(item, lastPos, lastPos, modifiers, timestamp, clearHover); } + hoverItems.clear(); - return accepted; + + return true; } void QQuickDeliveryAgentPrivate::updateFocusItemTransform() @@ -710,17 +725,16 @@ bool QQuickDeliveryAgent::event(QEvent *ev) case QEvent::HoverLeave: case QEvent::HoverMove: { QHoverEvent *he = static_cast<QHoverEvent*>(ev); - bool accepted = he->isAccepted(); - bool delivered = d->deliverHoverEvent(d->rootItem, he->scenePosition(), + bool accepted = d->deliverHoverEvent(he->scenePosition(), he->points().first().sceneLastPosition(), - he->modifiers(), he->timestamp(), accepted); + he->modifiers(), he->timestamp()); d->lastMousePosition = he->scenePosition(); he->setAccepted(accepted); #if QT_CONFIG(cursor) QQuickWindowPrivate::get(d->rootItem->window())->updateCursor(d->sceneTransform ? d->sceneTransform->map(he->scenePosition()) : he->scenePosition(), d->rootItem); #endif - return delivered; + return accepted; } case QEvent::TouchBegin: case QEvent::TouchUpdate: @@ -742,16 +756,15 @@ bool QQuickDeliveryAgent::event(QEvent *ev) if (!d->rootItem) return false; QEnterEvent *enter = static_cast<QEnterEvent*>(ev); - bool accepted = enter->isAccepted(); - bool delivered = d->deliverHoverEvent(d->rootItem, enter->scenePosition(), + bool accepted = d->deliverHoverEvent(enter->scenePosition(), enter->points().first().sceneLastPosition(), - enter->modifiers(), enter->timestamp(), accepted); + enter->modifiers(), enter->timestamp()); d->lastMousePosition = enter->scenePosition(); enter->setAccepted(accepted); #if QT_CONFIG(cursor) QQuickWindowPrivate::get(d->rootItem->window())->updateCursor(enter->scenePosition(), d->rootItem); #endif - return delivered; + return accepted; } case QEvent::Leave: d->clearHover(); @@ -933,12 +946,16 @@ bool QQuickDeliveryAgentPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *i const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, ulong timestamp) { - const QTransform transform = QQuickItemPrivate::get(item)->windowToItemTransform(); - - //create copy of event + auto itemPrivate = QQuickItemPrivate::get(item); + const QTransform transform = itemPrivate->windowToItemTransform(); QHoverEvent hoverEvent(type, transform.map(scenePos), transform.map(lastScenePos), modifiers); hoverEvent.setTimestamp(timestamp); hoverEvent.setAccepted(true); + const QTransform transformToGlobal = itemPrivate->windowToGlobalTransform(); + QMutableEventPoint &point = QMutableEventPoint::from(hoverEvent.point(0)); + point.setScenePosition(scenePos); + point.setGlobalPosition(transformToGlobal.map(scenePos)); + point.setGlobalLastPosition(transformToGlobal.map(lastScenePos)); hasFiltered.clear(); if (sendFilteredMouseEvent(&hoverEvent, item, item->parentItem())) @@ -949,95 +966,233 @@ bool QQuickDeliveryAgentPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *i return hoverEvent.isAccepted(); } +/*! \internal + Delivers a hover event at \a scenePos to the whole scene or subscene + that this DeliveryAgent is responsible for. Returns \c true if + delivery is "done". +*/ // TODO later: specify the device in case of multi-mouse scenario, or mouse and tablet both in use -bool QQuickDeliveryAgentPrivate::deliverHoverEvent(QQuickItem *item, const QPointF &scenePos, const QPointF &lastScenePos, - Qt::KeyboardModifiers modifiers, ulong timestamp, bool &accepted) -{ - Q_Q(QQuickDeliveryAgent); - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - const QPointF itemPos = item->mapFromScene(sceneTransform ? sceneTransform->map(scenePos) : scenePos); - - if ((itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape || item == rootItem) && !item->contains(itemPos)) +bool QQuickDeliveryAgentPrivate::deliverHoverEvent( + const QPointF &scenePos, const QPointF &lastScenePos, + Qt::KeyboardModifiers modifiers, ulong timestamp) +{ + // The first time this function is called, hoverItems is empty. + // We then call deliverHoverEventRecursive from the rootItem, and + // populate the list with all the children and grandchildren that + // we find that should receive hover events (in addition to sending + // hover events to them and their HoverHandlers). We also set the + // hoverId for each item to the currentHoverId. + // The next time this function is called, we bump currentHoverId, + // and call deliverHoverEventRecursive once more. + // When that call returns, the list will contain the items that + // were hovered the first time, as well as the items that were hovered + // this time. But only the items that were hovered this time + // will have their hoverId equal to currentHoverId; the ones we didn't + // visit will still have an old hoverId. We can therefore go through the + // list at the end of this function and look for items with an old hoverId, + // remove them from the list, and update their state accordingly. + + const bool subtreeHoverEnabled = QQuickItemPrivate::get(rootItem)->subtreeHoverEnabled; + const bool itemsWasHovered = !hoverItems.isEmpty(); + + if (!subtreeHoverEnabled && !itemsWasHovered) return false; - if (Q_UNLIKELY(lcHoverTrace().isDebugEnabled())) { - if (lastScenePos == scenePos) - qCDebug(lcHoverTrace) << q << scenePos << "(unchanged)" << "," << itemPos << "in" << item << "subtreeHoverEnabled" << itemPrivate->subtreeHoverEnabled; - else - qCDebug(lcHoverTrace) << q << lastScenePos << "->" << scenePos << "," << itemPos << "in" << item << ", subtreeHoverEnabled" << itemPrivate->subtreeHoverEnabled; + currentHoverId++; + + if (subtreeHoverEnabled) { + hoveredLeafItemFound = false; + deliverHoverEventRecursive(rootItem, scenePos, lastScenePos, modifiers, timestamp); } - if (itemPrivate->subtreeHoverEnabled) { - QList<QQuickItem *> children = itemPrivate->paintOrderChildItems(); - for (int ii = children.count() - 1; ii >= 0; --ii) { - QQuickItem *child = children.at(ii); - if (!child->isVisible() || QQuickItemPrivate::get(child)->culled) - continue; - if (!child->isEnabled() && !QQuickItemPrivate::get(child)->subtreeHoverEnabled) - continue; - if (deliverHoverEvent(child, scenePos, lastScenePos, modifiers, timestamp, accepted)) - return true; + + // Prune the list for items that are no longer hovered + for (auto it = hoverItems.begin(); it != hoverItems.end();) { + auto item = (*it).first.data(); + auto hoverId = (*it).second; + if (hoverId == currentHoverId) { + // Still being hovered + it++; + } else { + // No longer hovered. If hoverId is 0, it means that we have sent a HoverLeave + // event to the item already, and it can just be removed from the list. Note that + // the item can have been deleted as well. + if (item && hoverId != 0) { + const bool clearHover = true; + deliverHoverEventToItem(item, scenePos, lastScenePos, modifiers, timestamp, clearHover); + } + it = hoverItems.erase(it); } } - if (itemPrivate->hasPointerHandlers()) { - QMouseEvent hoverEvent(QEvent::MouseMove, itemPos, scenePos, - itemPrivate->window->mapToGlobal(scenePos), Qt::NoButton, Qt::NoButton, modifiers); - ensureDeviceConnected(hoverEvent.pointingDevice()); - hoverEvent.setTimestamp(timestamp); - hoverEvent.setAccepted(true); - for (QQuickPointerHandler *h : itemPrivate->extra->pointerHandlers) - if (QQuickHoverHandler *hh = qmlobject_cast<QQuickHoverHandler *>(h)) - hh->handlePointerEvent(&hoverEvent); + const bool itemsAreHovered = !hoverItems.isEmpty(); + return itemsWasHovered || itemsAreHovered; +} + +/*! \internal + Delivers a hover event at \a scenePos to \a item and all its children. + The children get it first. As soon as any item allows the event to remain + accepted, recursion stops. Returns \c true in that case, or \c false if the + event is rejected. + + Each item that has hover enabled (from setAcceptHoverEvents()) has the + QQuickItemPrivate::hoverEnabled flag set. This only controls whether we + should send hover events to the item itself. (HoverHandlers no longer set + this flag.) When an item has hoverEnabled set, all its ancestors have the + QQuickItemPrivate::subtreeHoverEnabled set. This function will + follow the subtrees that have subtreeHoverEnabled by recursing into each + child with that flag set. And for each child (in addition to the item + itself) that also has hoverEnabled set, we call deliverHoverEventToItem() + to actually deliver the event to it. The item can then choose to accept or + reject the event. This is only for control over whether we stop propagation + or not: an item can reject the event, but at the same time be hovered (and + therefore in hoverItems). By accepting the event, the item will effectivly + end up as the only one hovered. Any other HoverHandler that may be a child + of an item that is stacked underneath, will not. Note that since siblings + can overlap, there can be more than one leaf item under the mouse. + + Note that HoverHandler doesn't set the hoverEnabled flag on the parent item. + But still, adding a HoverHandler to an item will set its subtreeHoverEnabled flag. + So all the propagation logic described above will otherwise be the same. + But the hoverEnabled flag can be used to resolve if subtreeHoverEnabled is on + because the application explicitly requested it (setAcceptHoverEvents()), or + indirectly, because the item has HoverHandlers. + + For legacy reasons (Qt 6.1), as soon as we find a leaf item that has hover + enabled, and therefore receives the event, we stop recursing into the remaining + siblings (even if the event was ignored). This means that we only allow hover + events to propagate up the direct parent-child hierarchy, and not to siblings. + However, if the first candidate HoverHandler is disabled, delivery continues + to the next one, which may be a sibling (QTBUG-106548). +*/ +bool QQuickDeliveryAgentPrivate::deliverHoverEventRecursive( + QQuickItem *item, const QPointF &scenePos, const QPointF &lastScenePos, + Qt::KeyboardModifiers modifiers, ulong timestamp) +{ + + const QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + const QList<QQuickItem *> children = itemPrivate->paintOrderChildItems(); + + for (int ii = children.count() - 1; ii >= 0; --ii) { + QQuickItem *child = children.at(ii); + const QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child); + + if (!child->isVisible() || childPrivate->culled) + continue; + if (!child->isEnabled() && !childPrivate->subtreeHoverEnabled) + continue; + if (childPrivate->flags & QQuickItem::ItemClipsChildrenToShape) { + const QPointF localPos = child->mapFromScene(scenePos); + if (!child->contains(localPos)) + continue; + } + + // Recurse into the child + const bool accepted = deliverHoverEventRecursive(child, scenePos, lastScenePos, modifiers, timestamp); + if (accepted) { + // Stop propagation / recursion + return true; + } + if (hoveredLeafItemFound) { + // Don't propagate to siblings, only to ancestors + break; + } } - if (itemPrivate->hoverEnabled && item->contains(itemPos)) { - if (!hoverItems.isEmpty() && hoverItems.at(0) == item) { - //move + // All decendants have been visited. + // Now deliver the event to the item + return deliverHoverEventToItem(item, scenePos, lastScenePos, modifiers, timestamp, false); + + // Continue propagation / recursion + return false; +} + +/*! \internal + Delivers a hover event at \a scenePos to \a item and its HoverHandlers if any. + Returns \c true if the event remains accepted, \c false if rejected. + + If \a clearHover is \c true, it will be sent as a QEvent::HoverLeave event, + and the item and its handlers are expected to transition into their non-hovered + states even if the position still indicates that the mouse is inside. +*/ +bool QQuickDeliveryAgentPrivate::deliverHoverEventToItem( + QQuickItem *item, const QPointF &scenePos, const QPointF &lastScenePos, + Qt::KeyboardModifiers modifiers, ulong timestamp, bool clearHover) +{ + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + const QPointF localPos = item->mapFromScene(scenePos); + const QPointF globalPos = item->mapToGlobal(localPos); + const bool isHovering = item->contains(localPos); + const bool wasHovering = hoverItems.contains(item); + + qCDebug(lcHoverTrace) << "item:" << item << "scene pos:" << scenePos << "localPos:" << localPos + << "wasHovering:" << wasHovering << "isHovering:" << isHovering; + + bool accepted = false; + + // Start by sending out enter/move/leave events to the item. + // Note that hoverEnabled only controls if we should send out hover events to the + // item itself. HoverHandlers are not included, and are dealt with separately below. + if (itemPrivate->hoverEnabled && isHovering && !clearHover) { + // Add the item to the list of hovered items (if it doesn't exist there + // from before), and update hoverId to mark that it's (still) hovered. + // Also set hoveredLeafItemFound, so that only propagate in a straight + // line towards the root from now on. + hoveredLeafItemFound = true; + hoverItems[item] = currentHoverId; + if (wasHovering) accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, timestamp); - } else { - QList<QQuickItem *> itemsToHover; - QQuickItem* parent = item; - itemsToHover << item; - while ((parent = parent->parentItem())) - itemsToHover << parent; - - // Leaving from previous hovered items until we reach the item or one of its ancestors. - while (!hoverItems.isEmpty() && !itemsToHover.contains(hoverItems.at(0))) { - QQuickItem *hoverLeaveItem = hoverItems.takeFirst(); - if (hoverLeaveItem) - sendHoverEvent(QEvent::HoverLeave, hoverLeaveItem, scenePos, lastScenePos, modifiers, timestamp); + else + accepted = sendHoverEvent(QEvent::HoverEnter, item, scenePos, lastScenePos, modifiers, timestamp); + } else if (wasHovering) { + // A leave should never stop propagation + hoverItems[item] = 0; + sendHoverEvent(QEvent::HoverLeave, item, scenePos, lastScenePos, modifiers, timestamp); + } + + if (!itemPrivate->hasPointerHandlers()) + return accepted; + + // Next, send out hover events to the hover handlers. + // If the item didn't accept the hover event, 'accepted' is now false. + // Otherwise it's true, and then it should stay the way regardless of + // whether or not the hoverhandlers themselves are hovered. + // Note that since a HoverHandler can have a margin, a HoverHandler + // can be hovered even if the item itself is not. + + if (clearHover) { + // Note: a leave should never stop propagation + QHoverEvent hoverEvent(QEvent::HoverLeave, scenePos, lastScenePos, modifiers); + hoverEvent.setTimestamp(timestamp); + + for (QQuickPointerHandler *h : itemPrivate->extra->pointerHandlers) { + if (QQuickHoverHandler *hh = qmlobject_cast<QQuickHoverHandler *>(h)) { + if (!hh->isHovered()) + continue; + hoverEvent.setAccepted(true); + QCoreApplication::sendEvent(hh, &hoverEvent); } + } + } else { + QMouseEvent hoverEvent(QEvent::MouseMove, localPos, scenePos, globalPos, Qt::NoButton, Qt::NoButton, modifiers); + hoverEvent.setTimestamp(timestamp); - if (!hoverItems.isEmpty() && hoverItems.at(0) == item) {//Not entering a new Item - // ### Shouldn't we send moves for the parent items as well? - accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, timestamp); - } else { - // Enter items that are not entered yet. - int startIdx = -1; - if (!hoverItems.isEmpty()) - startIdx = itemsToHover.indexOf(hoverItems.at(0)) - 1; - if (startIdx == -1) - startIdx = itemsToHover.count() - 1; - - for (int i = startIdx; i >= 0; i--) { - QQuickItem *itemToHover = itemsToHover.at(i); - QQuickItemPrivate *itemToHoverPrivate = QQuickItemPrivate::get(itemToHover); - // The item may be about to be deleted or reparented to another window - // due to another hover event delivered in this function. If that is the - // case, sending a hover event here will cause a crash or other bad - // behavior when the leave event is generated. Checking - // itemToHoverPrivate->window here prevents that case. - if (itemToHoverPrivate->window == itemPrivate->window && itemToHoverPrivate->hoverEnabled) { - hoverItems.prepend(itemToHover); - sendHoverEvent(QEvent::HoverEnter, itemToHover, scenePos, lastScenePos, modifiers, timestamp); - } + for (QQuickPointerHandler *h : itemPrivate->extra->pointerHandlers) { + if (QQuickHoverHandler *hh = qmlobject_cast<QQuickHoverHandler *>(h)) { + if (!hh->enabled()) + continue; + hoverEvent.setAccepted(true); + hh->handlePointerEvent(&hoverEvent); + if (hh->isHovered()) { + // Mark the whole item as updated, even if only the handler is + // actually in a hovered state (because of HoverHandler.margins) + hoveredLeafItemFound = true; + hoverItems[item] = currentHoverId; } } } - return true; } - return false; + return accepted; } // Simple delivery of non-mouse, non-touch Pointer Events: visit the items and handlers @@ -1078,6 +1233,8 @@ bool QQuickDeliveryAgentPrivate::deliverTouchCancelEvent(QTouchEvent *event) const_cast<QPointingDevicePrivate *>(QPointingDevicePrivate::get(event->pointingDevice()))-> sendTouchCancelEvent(event); + cancelTouchMouseSynthesis(); + return true; } @@ -1088,6 +1245,7 @@ void QQuickDeliveryAgentPrivate::deliverDelayedTouchEvent() // event loop recursions (e.g if it the touch starts a dnd session). QScopedPointer<QTouchEvent> e(delayedTouch.take()); qCDebug(lcTouchCmprs) << "delivering" << e.data(); + compressedTouchCount = 0; deliverPointerEvent(e.data()); } @@ -1178,6 +1336,15 @@ bool QQuickDeliveryAgentPrivate::anyPointGrabbed(const QPointerEvent *ev) return false; } +bool QQuickDeliveryAgentPrivate::allPointsGrabbed(const QPointerEvent *ev) +{ + for (const auto &point : ev->points()) { + if (!ev->exclusiveGrabber(point) && ev->passiveGrabbers(point).isEmpty()) + return false; + } + return true; +} + bool QQuickDeliveryAgentPrivate::isMouseEvent(const QPointerEvent *ev) { switch (ev->type()) { @@ -1244,10 +1411,40 @@ QQuickPointingDeviceExtra *QQuickDeliveryAgentPrivate::deviceExtra(const QInputD return extra; } +/*! + \internal + This function is called from handleTouchEvent() in case a series of touch + events containing only \c Updated and \c Stationary points arrives within a + short period of time. (Some touchscreens are more "jittery" than others.) + + It would be a waste of CPU time to deliver events and have items in the + scene getting modified more often than once per frame; so here we try to + coalesce the series of updates into a single event containing all updates + that occur within one frame period, and deliverDelayedTouchEvent() is + called from flushFrameSynchronousEvents() to send that single event. This + is the reason why touch compression lives here so far, instead of in a + lower layer: the render loop updates the scene in sync with the screen's + vsync, and flushFrameSynchronousEvents() is called from there (for example + from QSGThreadedRenderLoop::polishAndSync(), and equivalent places in other + render loops). It would be preferable to move this code down to a lower + level eventually, though, because it's not fundamentally a Qt Quick concern. + + This optimization can be turned off by setting the environment variable + \c QML_NO_TOUCH_COMPRESSION. + + Returns \c true if "done", \c false if the caller needs to finish the + \a event delivery. +*/ bool QQuickDeliveryAgentPrivate::compressTouchEvent(QTouchEvent *event) { + // If this is a subscene agent, don't store any events, because + // flushFrameSynchronousEvents() is only called on the window's DA. + if (isSubsceneAgent) + return false; + QEventPoint::States states = event->touchPointStates(); if (states.testFlag(QEventPoint::State::Pressed) || states.testFlag(QEventPoint::State::Released)) { + qCDebug(lcTouchCmprs) << "no compression" << event; // we can only compress an event that doesn't include any pressed or released points return false; } @@ -1255,7 +1452,12 @@ bool QQuickDeliveryAgentPrivate::compressTouchEvent(QTouchEvent *event) if (!delayedTouch) { delayedTouch.reset(new QMutableTouchEvent(event->type(), event->pointingDevice(), event->modifiers(), event->points())); delayedTouch->setTimestamp(event->timestamp()); - qCDebug(lcTouchCmprs) << "delayed" << delayedTouch.data(); + for (qsizetype i = 0; i < delayedTouch->pointCount(); ++i) { + auto &tp = delayedTouch->point(i); + QMutableEventPoint::from(tp).detach(); + } + ++compressedTouchCount; + qCDebug(lcTouchCmprs) << "delayed" << compressedTouchCount << delayedTouch.data(); if (QQuickWindow *window = rootItem->window()) window->maybeUpdate(); return true; @@ -1289,7 +1491,14 @@ bool QQuickDeliveryAgentPrivate::compressTouchEvent(QTouchEvent *event) // TODO optimize, or move event compression elsewhere delayedTouch.reset(new QMutableTouchEvent(event->type(), event->pointingDevice(), event->modifiers(), tpts)); delayedTouch->setTimestamp(event->timestamp()); - qCDebug(lcTouchCmprs) << "coalesced" << delayedTouch.data(); + for (qsizetype i = 0; i < delayedTouch->pointCount(); ++i) { + auto &tp = delayedTouch->point(i); + QMutableEventPoint::from(tp).detach(); + } + ++compressedTouchCount; + qCDebug(lcTouchCmprs) << "coalesced" << compressedTouchCount << delayedTouch.data(); + if (QQuickWindow *window = rootItem->window()) + window->maybeUpdate(); return true; } } @@ -1374,16 +1583,11 @@ void QQuickDeliveryAgentPrivate::handleMouseEvent(QMouseEvent *event) #if QT_CONFIG(cursor) QQuickWindowPrivate::get(rootItem->window())->updateCursor(event->scenePosition()); #endif + const QPointF last = lastMousePosition.isNull() ? event->scenePosition() : lastMousePosition; + lastMousePosition = event->scenePosition(); + qCDebug(lcHoverTrace) << q << "mouse pos" << last << "->" << lastMousePosition; if (!event->points().count() || !event->exclusiveGrabber(event->point(0))) { - QPointF last = lastMousePosition.isNull() ? event->scenePosition() : lastMousePosition; - lastMousePosition = event->scenePosition(); - qCDebug(lcHoverTrace) << q << "mouse pos" << last << "->" << lastMousePosition << event; - bool accepted = event->isAccepted(); - bool delivered = deliverHoverEvent(rootItem, event->scenePosition(), last, event->modifiers(), event->timestamp(), accepted); - if (!delivered) { - //take care of any exits - accepted = clearHover(event->timestamp()); - } + bool accepted = deliverHoverEvent(event->scenePosition(), last, event->modifiers(), event->timestamp()); event->setAccepted(accepted); } deliverPointerEvent(event); @@ -1422,15 +1626,13 @@ void QQuickDeliveryAgentPrivate::flushFrameSynchronousEvents(QQuickWindow *win) // TODO do this for each known mouse device or come up with a different strategy if (frameSynchronousHoverEnabled && !win->mouseGrabberItem() && !lastMousePosition.isNull() && QQuickWindowPrivate::get(win)->dirtyItemList) { - bool accepted = false; - qCDebug(lcHoverTrace) << q << "delivering frame-sync hover to root"; - bool delivered = deliverHoverEvent(rootItem, lastMousePosition, lastMousePosition, QGuiApplication::keyboardModifiers(), 0, accepted); - if (!delivered) - clearHover(); // take care of any exits + qCDebug(lcHoverTrace) << q << "delivering frame-sync hover to root @" << lastMousePosition; + deliverHoverEvent(lastMousePosition, lastMousePosition, QGuiApplication::keyboardModifiers(), 0); qCDebug(lcHoverTrace) << q << "frame-sync hover delivery done"; } #endif - if (Q_UNLIKELY(QQuickDeliveryAgentPrivate::currentEventDeliveryAgent != q)) + if (Q_UNLIKELY(QQuickDeliveryAgentPrivate::currentEventDeliveryAgent && + QQuickDeliveryAgentPrivate::currentEventDeliveryAgent != q)) qCWarning(lcPtr, "detected interleaved frame-sync and actual events"); QQuickDeliveryAgentPrivate::currentEventDeliveryAgent = deliveringAgent; } @@ -1510,17 +1712,19 @@ void QQuickDeliveryAgentPrivate::onGrabChanged(QObject *grabber, QPointingDevice } if (currentEventDeliveryAgent == q && event && event->device()) { - auto epd = QPointingDevicePrivate::get(const_cast<QPointingDevice*>(event->pointingDevice()))->queryPointById(point.id()); - Q_ASSERT(epd); switch (transition) { case QPointingDevice::GrabPassive: { + auto epd = QPointingDevicePrivate::get(const_cast<QPointingDevice*>(event->pointingDevice()))->queryPointById(point.id()); + Q_ASSERT(epd); QPointingDevicePrivate::setPassiveGrabberContext(epd, grabber, q); qCDebug(lcPtr) << "remembering that" << q << "handles point" << point.id() << "after" << transition; } break; - case QPointingDevice::GrabExclusive: + case QPointingDevice::GrabExclusive: { + auto epd = QPointingDevicePrivate::get(const_cast<QPointingDevice*>(event->pointingDevice()))->queryPointById(point.id()); + Q_ASSERT(epd); epd->exclusiveGrabberContext = q; qCDebug(lcPtr) << "remembering that" << q << "handles point" << point.id() << "after" << transition; - break; + } break; case QPointingDevice::CancelGrabExclusive: case QPointingDevice::UngrabExclusive: // taken care of in QPointingDevicePrivate::setExclusiveGrabber(,,nullptr), removeExclusiveGrabber() @@ -1594,9 +1798,17 @@ void QQuickDeliveryAgentPrivate::deliverPointerEvent(QPointerEvent *event) if (event->isEndEvent()) deliverPressOrReleaseEvent(event, true); - // failsafe: never allow touch->mouse synthesis to persist after release - if (event->isEndEvent() && isTouchEvent(event)) - cancelTouchMouseSynthesis(); + // failsafe: never allow touch->mouse synthesis to persist after all touchpoints are released, + // or after the touchmouse is released + if (isTouchEvent(event) && touchMouseId >= 0) { + if (static_cast<QTouchEvent *>(event)->touchPointStates() == QEventPoint::State::Released) { + cancelTouchMouseSynthesis(); + } else { + auto touchMousePoint = event->pointById(touchMouseId); + if (touchMousePoint && touchMousePoint->state() == QEventPoint::State::Released) + cancelTouchMouseSynthesis(); + } + } eventsInDelivery.pop(); if (sceneTransform) { @@ -1623,7 +1835,7 @@ QVector<QQuickItem *> QQuickDeliveryAgentPrivate::pointerTargets(QQuickItem *ite qCDebug(lcPtrLoc) << q << "point" << point.id() << point.scenePosition() << "->" << itemPos << ": relevant?" << relevant << "to" << item << point; // if the item clips, we can potentially return early if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) { - if (!relevant) + if (!item->clipRect().contains(itemPos)) return targets; } @@ -1648,7 +1860,8 @@ QVector<QQuickItem *> QQuickDeliveryAgentPrivate::pointerTargets(QQuickItem *ite for (int ii = children.count() - 1; ii >= 0; --ii) { QQuickItem *child = children.at(ii); auto childPrivate = QQuickItemPrivate::get(child); - if (!child->isVisible() || !child->isEnabled() || childPrivate->culled) + if (!child->isVisible() || !child->isEnabled() || childPrivate->culled || + (child != item && childPrivate->extra.isAllocated() && childPrivate->extra->subsceneDeliveryAgent)) continue; if (child != item) @@ -1737,7 +1950,7 @@ void QQuickDeliveryAgentPrivate::deliverUpdatedPoints(QPointerEvent *event) return; // If some points weren't grabbed, deliver only to non-grabber PointerHandlers in reverse paint order - if (!event->allPointsGrabbed()) { + if (!allPointsGrabbed(event)) { QVector<QQuickItem *> targetItems; for (auto &point : event->points()) { // Presses were delivered earlier; not the responsibility of deliverUpdatedTouchPoints. @@ -1757,7 +1970,7 @@ void QQuickDeliveryAgentPrivate::deliverUpdatedPoints(QPointerEvent *event) QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); localizePointerEvent(event, item); itemPrivate->handlePointerEvent(event, true); // avoid re-delivering to grabbers - if (event->allPointsGrabbed()) + if (allPointsGrabbed(event)) break; } } @@ -1905,30 +2118,23 @@ void QQuickDeliveryAgentPrivate::deliverMatchingPointsToItem(QQuickItem *item, b if (item->acceptTouchEvents()) { qCDebug(lcTouch) << "considering delivering" << &touchEvent << " to " << item; - // If any parent filters the event, we're done. - hasFiltered.clear(); - if (sendFilteredPointerEvent(&touchEvent, item)) - return; - // Deliver the touch event to the given item qCDebug(lcTouch) << "actually delivering" << &touchEvent << " to " << item; QCoreApplication::sendEvent(item, &touchEvent); eventAccepted = touchEvent.isAccepted(); - } else if (Q_LIKELY(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents))) { + } else { // If the touch event wasn't accepted, synthesize a mouse event and see if the item wants it. - if (!eventAccepted && (itemPrivate->acceptedMouseButtons() & Qt::LeftButton)) { - // send mouse event - if (deliverTouchAsMouse(item, &touchEvent)) - eventAccepted = true; - } + if (Q_LIKELY(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)) && + !eventAccepted && (itemPrivate->acceptedMouseButtons() & Qt::LeftButton)) + deliverTouchAsMouse(item, &touchEvent); + return; } + Q_ASSERT(item->acceptTouchEvents()); // else we would've returned early above if (eventAccepted) { - // If the touch was accepted (regardless by whom or in what form), - // update accepted new points. bool isPressOrRelease = pointerEvent->isBeginEvent() || pointerEvent->isEndEvent(); for (int i = 0; i < touchEvent.pointCount(); ++i) { - auto &point = QMutableEventPoint::from(touchEvent.point(i)); + auto &point = touchEvent.point(i); // legacy-style delivery: if the item doesn't reject the event, that means it handled ALL the points point.setAccepted(); // but don't let the root of a subscene implicitly steal the grab from some other item (such as one of its children) @@ -1952,6 +2158,7 @@ void QQuickDeliveryAgentPrivate::deliverMatchingPointsToItem(QQuickItem *item, b #if QT_CONFIG(quick_draganddrop) void QQuickDeliveryAgentPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QEvent *event) { + QObject *formerTarget = grabber->target(); grabber->resetTarget(); QQuickDragGrabber::iterator grabItem = grabber->begin(); if (grabItem != grabber->end()) { @@ -1977,6 +2184,7 @@ void QQuickDeliveryAgentPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QE QDragLeaveEvent leaveEvent; for (; grabItem != grabber->end(); grabItem = grabber->release(grabItem)) QCoreApplication::sendEvent(**grabItem, &leaveEvent); + grabber->ignoreList().clear(); return; } else { QDragMoveEvent *moveEvent = static_cast<QDragMoveEvent *>(event); @@ -1995,7 +2203,8 @@ void QQuickDeliveryAgentPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QE moveEvent->buttons(), moveEvent->modifiers()); QQuickDropEventEx::copyActions(&enterEvent, *moveEvent); - event->setAccepted(deliverDragEvent(grabber, rootItem, &enterEvent, ¤tGrabItems)); + event->setAccepted(deliverDragEvent(grabber, rootItem, &enterEvent, ¤tGrabItems, + formerTarget)); for (grabItem = grabber->begin(); grabItem != grabber->end(); ++grabItem) { int i = currentGrabItems.indexOf(**grabItem); @@ -2033,10 +2242,14 @@ void QQuickDeliveryAgentPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QE e->modifiers()); QQuickDropEventEx::copyActions(&enterEvent, *e); event->setAccepted(deliverDragEvent(grabber, rootItem, &enterEvent)); + } else { + grabber->ignoreList().clear(); } } -bool QQuickDeliveryAgentPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickItem *item, QDragMoveEvent *event, QVarLengthArray<QQuickItem*, 64> *currentGrabItems) +bool QQuickDeliveryAgentPrivate::deliverDragEvent( + QQuickDragGrabber *grabber, QQuickItem *item, QDragMoveEvent *event, + QVarLengthArray<QQuickItem *, 64> *currentGrabItems, QObject *formerTarget) { QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); if (!item->isVisible() || !item->isEnabled() || QQuickItemPrivate::get(item)->culled) @@ -2044,8 +2257,13 @@ bool QQuickDeliveryAgentPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQ QPointF p = item->mapFromScene(event->position().toPoint()); bool itemContained = item->contains(p); - if (!itemContained && itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) { - return false; + const int itemIndex = grabber->ignoreList().indexOf(item); + if (!itemContained) { + if (itemIndex >= 0) + grabber->ignoreList().remove(itemIndex); + + if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) + return false; } QDragEnterEvent enterEvent( @@ -2061,7 +2279,7 @@ bool QQuickDeliveryAgentPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQ for (int ii = children.count() - 1; ii >= 0; --ii) { if (children.at(ii)->z() < 0) continue; - if (deliverDragEvent(grabber, children.at(ii), &enterEvent, currentGrabItems)) + if (deliverDragEvent(grabber, children.at(ii), &enterEvent, currentGrabItems, formerTarget)) return true; } @@ -2075,13 +2293,24 @@ bool QQuickDeliveryAgentPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQ } if (event->type() == QEvent::DragMove || itemPrivate->flags & QQuickItem::ItemAcceptsDrops) { - QDragMoveEvent translatedEvent( - p.toPoint(), - event->possibleActions(), - event->mimeData(), - event->buttons(), - event->modifiers(), - event->type()); + if (event->type() == QEvent::DragEnter) { + if (formerTarget) { + QQuickItem *formerTargetItem = qobject_cast<QQuickItem *>(formerTarget); + if (formerTargetItem && currentGrabItems) { + QDragLeaveEvent leaveEvent; + QCoreApplication::sendEvent(formerTarget, &leaveEvent); + + // Remove the item from the currentGrabItems so a leave event won't be generated + // later on + currentGrabItems->removeAll(formerTarget); + } + } else if (itemIndex >= 0) { + return false; + } + } + + QDragMoveEvent translatedEvent(p.toPoint(), event->possibleActions(), event->mimeData(), + event->buttons(), event->modifiers(), event->type()); QQuickDropEventEx::copyActions(&translatedEvent, *event); translatedEvent.setAccepted(event->isAccepted()); QCoreApplication::sendEvent(item, &translatedEvent); @@ -2092,6 +2321,8 @@ bool QQuickDeliveryAgentPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQ grabber->grab(item); grabber->setTarget(item); return true; + } else if (itemIndex < 0) { + grabber->ignoreList().append(item); } } else { return true; @@ -2103,7 +2334,7 @@ bool QQuickDeliveryAgentPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQ for (int ii = children.count() - 1; ii >= 0; --ii) { if (children.at(ii)->z() >= 0) continue; - if (deliverDragEvent(grabber, children.at(ii), &enterEvent, currentGrabItems)) + if (deliverDragEvent(grabber, children.at(ii), &enterEvent, currentGrabItems, formerTarget)) return true; } @@ -2167,8 +2398,11 @@ bool QQuickDeliveryAgentPrivate::sendFilteredPointerEventImpl(QPointerEvent *eve if (filteringParent->childMouseEventFilter(receiver, &filteringParentTouchEvent)) { qCDebug(lcTouch) << "touch event intercepted by childMouseEventFilter of " << filteringParent; skipDelivery.append(filteringParent); - for (auto point : filteringParentTouchEvent.points()) - event->setExclusiveGrabber(point, filteringParent); + for (auto point : filteringParentTouchEvent.points()) { + const QQuickItem *exclusiveGrabber = qobject_cast<const QQuickItem *>(event->exclusiveGrabber(point)); + if (!exclusiveGrabber || !exclusiveGrabber->keepTouchGrab()) + event->setExclusiveGrabber(point, filteringParent); + } return true; } else if (Q_LIKELY(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)) && !filteringParent->acceptTouchEvents()) { diff --git a/src/quick/util/qquickdeliveryagent_p_p.h b/src/quick/util/qquickdeliveryagent_p_p.h index 0d7d5fb71de..ed1ec864810 100644 --- a/src/quick/util/qquickdeliveryagent_p_p.h +++ b/src/quick/util/qquickdeliveryagent_p_p.h @@ -76,8 +76,8 @@ struct QQuickPointingDeviceExtra { class Q_QUICK_PRIVATE_EXPORT QQuickDeliveryAgentPrivate : public QObjectPrivate { - Q_DECLARE_PUBLIC(QQuickDeliveryAgent) public: + Q_DECLARE_PUBLIC(QQuickDeliveryAgent) QQuickDeliveryAgentPrivate(QQuickItem *root); ~QQuickDeliveryAgentPrivate(); @@ -95,7 +95,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDeliveryAgentPrivate : public QObjectPrivate void setFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = { }); void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = { }); - static void notifyFocusChangesRecur(QQuickItem **item, int remaining); + static void notifyFocusChangesRecur(QQuickItem **item, int remaining, Qt::FocusReason reason); void clearFocusObject(); void updateFocusItemTransform(); @@ -105,19 +105,22 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDeliveryAgentPrivate : public QObjectPrivate #endif QQuickItem *lastUngrabbed = nullptr; QStack<QPointerEvent *> eventsInDelivery; - QList<QPointer<QQuickItem>> hoverItems; + QFlatMap<QPointer<QQuickItem>, uint> hoverItems; QVector<QQuickItem *> hasFiltered; // during event delivery to a single receiver, the filtering parents for which childMouseEventFilter was already called QVector<QQuickItem *> skipDelivery; // during delivery of one event to all receivers, Items to which we know delivery is no longer necessary QScopedPointer<QMutableTouchEvent> delayedTouch; QList<const QPointingDevice *> knownPointingDevices; + uint currentHoverId = 0; #if QT_CONFIG(wheelevent) uint lastWheelEventAccepted = 0; #endif + uchar compressedTouchCount = 0; bool allowChildEventFiltering = true; bool allowDoubleClick = true; bool frameSynchronousHoverEnabled = true; + bool hoveredLeafItemFound = false; bool isSubsceneAgent = false; static bool subsceneAgentsExist; @@ -169,6 +172,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDeliveryAgentPrivate : public QObjectPrivate static void localizePointerEvent(QPointerEvent *ev, const QQuickItem *dest); QList<QObject *> exclusiveGrabbers(QPointerEvent *ev); static bool anyPointGrabbed(const QPointerEvent *ev); + static bool allPointsGrabbed(const QPointerEvent *ev); static bool isMouseEvent(const QPointerEvent *ev); static bool isHoverEvent(const QPointerEvent *ev); static bool isTouchEvent(const QPointerEvent *ev); @@ -189,14 +193,18 @@ class Q_QUICK_PRIVATE_EXPORT QQuickDeliveryAgentPrivate : public QObjectPrivate QVector<QQuickItem *> mergePointerTargets(const QVector<QQuickItem *> &list1, const QVector<QQuickItem *> &list2) const; // hover delivery - bool deliverHoverEvent(QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, ulong timestamp, bool &accepted); + bool deliverHoverEvent(const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, ulong timestamp); + bool deliverHoverEventRecursive(QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, ulong timestamp); + bool deliverHoverEventToItem(QQuickItem *item, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, ulong timestamp, bool clearHover); bool sendHoverEvent(QEvent::Type, QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, ulong timestamp); bool clearHover(ulong timestamp = 0); #if QT_CONFIG(quick_draganddrop) void deliverDragEvent(QQuickDragGrabber *, QEvent *); - bool deliverDragEvent(QQuickDragGrabber *, QQuickItem *, QDragMoveEvent *, QVarLengthArray<QQuickItem*, 64> *currentGrabItems = nullptr); + bool deliverDragEvent(QQuickDragGrabber *, QQuickItem *, QDragMoveEvent *, + QVarLengthArray<QQuickItem *, 64> *currentGrabItems = nullptr, + QObject *formerTarget = nullptr); #endif static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold = -1); diff --git a/src/quick/util/qquickfontloader.cpp b/src/quick/util/qquickfontloader.cpp index e3915723fa7..0f1d766a118 100644 --- a/src/quick/util/qquickfontloader.cpp +++ b/src/quick/util/qquickfontloader.cpp @@ -423,12 +423,11 @@ QString QQuickFontLoader::name() const \qmlproperty enumeration QtQuick::FontLoader::status This property holds the status of font loading. It can be one of: - \list - \li FontLoader.Null - no font has been set - \li FontLoader.Ready - the font has been loaded - \li FontLoader.Loading - the font is currently being loaded - \li FontLoader.Error - an error occurred while loading the font - \endlist + + \value FontLoader.Null no font has been set + \value FontLoader.Ready the font has been loaded + \value FontLoader.Loading the font is currently being loaded + \value FontLoader.Error an error occurred while loading the font Use this status to provide an update or respond to the status change in some way. For example, you could: diff --git a/src/quick/util/qquickfontloader_p.h b/src/quick/util/qquickfontloader_p.h index bc7046e8082..3f88ef21ad6 100644 --- a/src/quick/util/qquickfontloader_p.h +++ b/src/quick/util/qquickfontloader_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <private/qtquickglobal_p.h> #include <qqml.h> #include <QtCore/qobject.h> @@ -59,7 +60,7 @@ QT_BEGIN_NAMESPACE class QQuickFontLoaderPrivate; -class Q_AUTOTEST_EXPORT QQuickFontLoader : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickFontLoader : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QQuickFontLoader) diff --git a/src/quick/util/qquickfontmetrics.cpp b/src/quick/util/qquickfontmetrics.cpp index ed9759d25fb..b365ade5db4 100644 --- a/src/quick/util/qquickfontmetrics.cpp +++ b/src/quick/util/qquickfontmetrics.cpp @@ -280,8 +280,8 @@ qreal QQuickFontMetrics::lineWidth() const string should be drawn. This method is offered as an imperative alternative to the - \l {QQuickTextMetrics::advanceWidth}{advanceWidth} property of - \l {QQuickTextMetrics::advanceWidth}{TextMetrics}. + \l {QtQuick::TextMetrics::advanceWidth}{advanceWidth} property of + TextMetrics. \sa {QFontMetricsF::horizontalAdvance()}, {QFontMetricsF::height()} */ @@ -297,8 +297,8 @@ qreal QQuickFontMetrics::advanceWidth(const QString &text) const specified by \a text. This method is offered as an imperative alternative to the - \l {QQuickTextMetrics::boundingRect}{boundingRect} property of - \l {QQuickTextMetrics::boundingRect}{TextMetrics}. + \l {QtQuick::TextMetrics::boundingRect}{boundingRect} property of + TextMetrics. \sa {QFontMetricsF::boundingRect()}, tightBoundingRect() */ @@ -314,8 +314,8 @@ QRectF QQuickFontMetrics::boundingRect(const QString &text) const string specified by \a text. This method is offered as an imperative alternative to the - \l {QQuickTextMetrics::tightBoundingRect}{tightBoundingRect} property of - \l {QQuickTextMetrics::tightBoundingRect}{TextMetrics}. + \l {QtQuick::TextMetrics::tightBoundingRect}{tightBoundingRect} property of + TextMetrics. \sa {QFontMetricsF::tightBoundingRect()}, boundingRect() */ @@ -338,8 +338,8 @@ QRectF QQuickFontMetrics::tightBoundingRect(const QString &text) const \l {Qt::TextShowMnemonic}. This method is offered as an imperative alternative to the - \l {QQuickTextMetrics::elidedText}{elidedText} property of - \l {QQuickTextMetrics::elidedText}{TextMetrics}. + \l {QtQuick::TextMetrics::elidedText}{elidedText} property of + TextMetrics. \sa Qt::TextElideMode, QFontMetricsF::elidedText() */ diff --git a/src/quick/util/qquickfontmetrics_p.h b/src/quick/util/qquickfontmetrics_p.h index 59f4aa83559..9784af32453 100644 --- a/src/quick/util/qquickfontmetrics_p.h +++ b/src/quick/util/qquickfontmetrics_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <private/qtquickglobal_p.h> #include <qqml.h> #include <QtGui/QFontMetricsF> @@ -60,7 +61,7 @@ QT_BEGIN_NAMESPACE class QFont; -class Q_AUTOTEST_EXPORT QQuickFontMetrics : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickFontMetrics : public QObject { Q_OBJECT diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp index b885f0406aa..3edce109479 100644 --- a/src/quick/util/qquickimageprovider.cpp +++ b/src/quick/util/qquickimageprovider.cpp @@ -469,7 +469,7 @@ QQuickTextureFactory *QQuickImageProvider::requestTexture(const QString &id, QSi \class QQuickAsyncImageProvider \since 5.6 \inmodule QtQuick - \brief The QQuickAsyncImageProvider class provides an interface for for asynchronous control of QML image requests. + \brief The QQuickAsyncImageProvider class provides an interface for asynchronous control of QML image requests. See the \l {imageresponseprovider}{Image Response Provider Example} for a complete implementation. @@ -681,14 +681,21 @@ QQuickImageResponse *QQuickImageProviderWithOptions::requestImageResponse(const and \a options. If the calculation otherwise concludes that scaled loading is not recommended, an invalid size is returned. */ -QSize QQuickImageProviderWithOptions::loadSize(const QSize &originalSize, const QSize &requestedSize, const QByteArray &format, const QQuickImageProviderOptions &options) +QSize QQuickImageProviderWithOptions::loadSize(const QSize &originalSize, const QSize &requestedSize, const QByteArray &format, const QQuickImageProviderOptions &options, + qreal devicePixelRatio) { QSize res; - if ((requestedSize.width() <= 0 && requestedSize.height() <= 0) || originalSize.isEmpty()) + const bool formatIsScalable = (format == "svg" || format == "svgz" || format == "pdf"); + const bool noRequestedSize = requestedSize.width() <= 0 && requestedSize.height() <= 0; + if ((noRequestedSize && !formatIsScalable) || originalSize.isEmpty()) return res; + // If no sourceSize was set and we're loading an SVG, ensure that we provide + // a default size that accounts for DPR so that the image isn't blurry. + if (noRequestedSize && formatIsScalable) + return originalSize * devicePixelRatio; + const bool preserveAspectCropOrFit = options.preserveAspectRatioCrop() || options.preserveAspectRatioFit(); - const bool formatIsScalable = (format == "svg" || format == "svgz" || format == "pdf"); if (!preserveAspectCropOrFit && formatIsScalable && !requestedSize.isEmpty()) return requestedSize; diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp index c2ef00e0644..db3654154d6 100644 --- a/src/quick/util/qquickpath.cpp +++ b/src/quick/util/qquickpath.cpp @@ -2685,22 +2685,21 @@ void QQuickPathMultiline::addToPath(QPainterPath &path, const QQuickPathData &) */ /*! - \qmlproperty enumeration QtQuick::PathText::font.weight + \qmlproperty int QtQuick::PathText::font.weight Sets the font's weight. The weight can be one of: - \list - \li Font.Thin - \li Font.Light - \li Font.ExtraLight - \li Font.Normal - the default - \li Font.Medium - \li Font.DemiBold - \li Font.Bold - \li Font.ExtraBold - \li Font.Black - \endlist + + \value Font.Thin 100 + \value Font.ExtraLight 200 + \value Font.Light 300 + \value Font.Normal 400 (default) + \value Font.Medium 500 + \value Font.DemiBold 600 + \value Font.Bold 700 + \value Font.ExtraBold 800 + \value Font.Black 900 \qml PathText { text: "Hello"; font.weight: Font.DemiBold } @@ -2764,13 +2763,12 @@ void QQuickPathMultiline::addToPath(QPainterPath &path, const QQuickPathData &) Sets the capitalization for the text. - \list - \li Font.MixedCase - This is the normal text rendering option where no capitalization change is applied. - \li Font.AllUppercase - This alters the text to be rendered in all uppercase type. - \li Font.AllLowercase - This alters the text to be rendered in all lowercase type. - \li Font.SmallCaps - This alters the text to be rendered in small-caps type. - \li Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character. - \endlist + \value Font.MixedCase no capitalization change is applied + \value Font.AllUppercase alters the text to be rendered in all uppercase type + \value Font.AllLowercase alters the text to be rendered in all lowercase type + \value Font.SmallCaps alters the text to be rendered in small-caps type + \value Font.Capitalize alters the text to be rendered with the first character of + each word as an uppercase character \qml PathText { text: "Hello"; font.capitalization: Font.AllLowercase } diff --git a/src/quick/util/qquickpathinterpolator_p.h b/src/quick/util/qquickpathinterpolator_p.h index 70fb0935e85..76e395539db 100644 --- a/src/quick/util/qquickpathinterpolator_p.h +++ b/src/quick/util/qquickpathinterpolator_p.h @@ -61,7 +61,7 @@ QT_REQUIRE_CONFIG(quick_path); QT_BEGIN_NAMESPACE class QQuickPath; -class Q_AUTOTEST_EXPORT QQuickPathInterpolator : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickPathInterpolator : public QObject { Q_OBJECT Q_PROPERTY(QQuickPath *path READ path WRITE setPath NOTIFY pathChanged) diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 1550e7e65df..0513b477d49 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -419,7 +419,8 @@ static void maybeRemoveAlpha(QImage *image) static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize, int *frameCount, const QRect &requestRegion, const QSize &requestSize, const QQuickImageProviderOptions &providerOptions, - QQuickImageProviderOptions::AutoTransform *appliedTransform = nullptr, int frame = 0) + QQuickImageProviderOptions::AutoTransform *appliedTransform = nullptr, int frame = 0, + qreal devicePixelRatio = 1.0) { QImageReader imgio(dev); if (providerOptions.autoTransform() != QQuickImageProviderOptions::UsePluginDefaultTransform) @@ -433,7 +434,7 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e if (frameCount) *frameCount = imgio.imageCount(); - QSize scSize = QQuickImageProviderWithOptions::loadSize(imgio.size(), requestSize, imgio.format(), providerOptions); + QSize scSize = QQuickImageProviderWithOptions::loadSize(imgio.size(), requestSize, imgio.format(), providerOptions, devicePixelRatio); if (scSize.isValid()) imgio.setScaledSize(scSize); if (!requestRegion.isNull()) @@ -1334,7 +1335,8 @@ void QQuickPixmapData::removeFromCache() static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url, const QRect &requestRegion, const QSize &requestSize, - const QQuickImageProviderOptions &providerOptions, int frame, bool *ok) + const QQuickImageProviderOptions &providerOptions, int frame, bool *ok, + qreal devicePixelRatio) { if (url.scheme() == QLatin1String("image")) { QSize readSize; @@ -1424,7 +1426,8 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q QImage image; QQuickImageProviderOptions::AutoTransform appliedTransform = providerOptions.autoTransform(); int frameCount; - if (readImage(url, &f, &image, &errorString, &readSize, &frameCount, requestRegion, requestSize, providerOptions, &appliedTransform, frame)) { + if (readImage(url, &f, &image, &errorString, &readSize, &frameCount, requestRegion, requestSize, + providerOptions, &appliedTransform, frame, devicePixelRatio)) { *ok = true; return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestRegion, requestSize, providerOptions, appliedTransform, frame, frameCount); @@ -1641,7 +1644,8 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QRect &reques } void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QRect &requestRegion, const QSize &requestSize, - QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame, int frameCount) + QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame, int frameCount, + qreal devicePixelRatio) { if (d) { d->declarativePixmaps.remove(this); @@ -1691,7 +1695,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QRect &reques if (!(options & QQuickPixmap::Asynchronous)) { bool ok = false; PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url)); - d = createPixmapDataSync(this, engine, url, requestRegion, requestSize, providerOptions, frame, &ok); + d = createPixmapDataSync(this, engine, url, requestRegion, requestSize, providerOptions, frame, &ok, devicePixelRatio); if (ok) { PIXMAP_PROFILE(pixmapLoadingFinished(url, QSize(width(), height()))); if (options & QQuickPixmap::Cache) diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h index 87724d6210a..5600443d31b 100644 --- a/src/quick/util/qquickpixmapcache_p.h +++ b/src/quick/util/qquickpixmapcache_p.h @@ -172,7 +172,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPixmap void load(QQmlEngine *, const QUrl &, const QRect &requestRegion, const QSize &requestSize); void load(QQmlEngine *, const QUrl &, const QRect &requestRegion, const QSize &requestSize, QQuickPixmap::Options options); void load(QQmlEngine *, const QUrl &, const QRect &requestRegion, const QSize &requestSize, - QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame = 0, int frameCount = 1); + QQuickPixmap::Options options, const QQuickImageProviderOptions &providerOptions, int frame = 0, int frameCount = 1, + qreal devicePixelRatio = 1.0); void clear(); void clear(QObject *); @@ -214,7 +215,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickImageProviderWithOptions : public QQuickAsync virtual QQuickTextureFactory *requestTexture(const QString &id, QSize *size, const QSize &requestedSize, const QQuickImageProviderOptions &options); virtual QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize, const QQuickImageProviderOptions &options); - static QSize loadSize(const QSize &originalSize, const QSize &requestedSize, const QByteArray &format, const QQuickImageProviderOptions &options); + static QSize loadSize(const QSize &originalSize, const QSize &requestedSize, const QByteArray &format, const QQuickImageProviderOptions &options, + qreal devicePixelRatio = 1.0); static QQuickImageProviderWithOptions *checkedCast(QQuickImageProvider *provider); }; diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index e7186d349e5..4b20912bf69 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -240,18 +240,22 @@ class QQuickPropertyChangesPrivate : public QQuickStateOperationPrivate void QQuickPropertyChangesParser::verifyList(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding) { - if (binding->type == QV4::CompiledData::Binding::Type_Object) { - error(compilationUnit->objectAt(binding->value.objectIndex), QQuickPropertyChanges::tr("PropertyChanges does not support creating state-specific objects.")); - return; - } - - if (binding->type == QV4::CompiledData::Binding::Type_GroupProperty - || binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { + switch (binding->type()) { + case QV4::CompiledData::Binding::Type_Object: + error(compilationUnit->objectAt(binding->value.objectIndex), + QQuickPropertyChanges::tr( + "PropertyChanges does not support creating state-specific objects.")); + break; + case QV4::CompiledData::Binding::Type_GroupProperty: + case QV4::CompiledData::Binding::Type_AttachedProperty: { const QV4::CompiledData::Object *subObj = compilationUnit->objectAt(binding->value.objectIndex); const QV4::CompiledData::Binding *subBinding = subObj->bindingTable(); - for (quint32 i = 0; i < subObj->nBindings; ++i, ++subBinding) { + for (quint32 i = 0; i < subObj->nBindings; ++i, ++subBinding) verifyList(compilationUnit, subBinding); - } + break; + } + default: + break; } } @@ -274,8 +278,9 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, QString propertyName = propertyPrefix + compilationUnit->stringAt(binding->propertyNameIndex); - if (binding->type == QV4::CompiledData::Binding::Type_GroupProperty - || binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { + switch (binding->type()) { + case QV4::CompiledData::Binding::Type_GroupProperty: + case QV4::CompiledData::Binding::Type_AttachedProperty: { QString pre = propertyName + QLatin1Char('.'); const QV4::CompiledData::Object *subObj = compilationUnit->objectAt(binding->value.objectIndex); const QV4::CompiledData::Binding *subBinding = subObj->bindingTable(); @@ -284,6 +289,9 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, } return; } + default: + break; + } if (propertyName.count() >= 3 && propertyName.at(0) == QLatin1Char('o') && @@ -303,7 +311,8 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, } } - if (binding->type == QV4::CompiledData::Binding::Type_Script || binding->isTranslationBinding()) { + if (binding->type() == QV4::CompiledData::Binding::Type_Script + || binding->isTranslationBinding()) { QUrl url = QUrl(); int line = -1; int column = -1; @@ -327,7 +336,7 @@ void QQuickPropertyChangesPrivate::decodeBinding(const QString &propertyPrefix, } QVariant var; - switch (binding->type) { + switch (binding->type()) { case QV4::CompiledData::Binding::Type_Script: case QV4::CompiledData::Binding::Type_Translation: case QV4::CompiledData::Binding::Type_TranslationById: diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp index fdd846adb60..ca3b653d83d 100644 --- a/src/quick/util/qquickshortcut.cpp +++ b/src/quick/util/qquickshortcut.cpp @@ -355,10 +355,11 @@ void QQuickShortcut::setAutoRepeat(bool repeat) This property holds the \l{Qt::ShortcutContext}{shortcut context}. Supported values are: - \list - \li \c Qt.WindowShortcut (default) - The shortcut is active when its parent item is in an active top-level window. - \li \c Qt.ApplicationShortcut - The shortcut is active when one of the application's windows are active. - \endlist + + \value Qt.WindowShortcut + (default) The shortcut is active when its parent item is in an active top-level window. + \value Qt.ApplicationShortcut + The shortcut is active when one of the application's windows are active. \qml Shortcut { diff --git a/src/quick/util/qquicksmoothedanimation.cpp b/src/quick/util/qquicksmoothedanimation.cpp index 254b1af0a29..264d022cae1 100644 --- a/src/quick/util/qquicksmoothedanimation.cpp +++ b/src/quick/util/qquicksmoothedanimation.cpp @@ -462,11 +462,12 @@ QAbstractAnimationJob* QQuickSmoothedAnimation::transition(QQuickStateActions &a Possible values are: - \list - \li SmoothedAnimation.Eased (default) - the animation will smoothly decelerate, and then reverse direction - \li SmoothedAnimation.Immediate - the animation will immediately begin accelerating in the reverse direction, beginning with a velocity of 0 - \li SmoothedAnimation.Sync - the property is immediately set to the target value - \endlist + \value SmoothedAnimation.Eased + (default) the animation will smoothly decelerate, and then reverse direction + \value SmoothedAnimation.Immediate + the animation will immediately begin accelerating in the reverse direction, beginning with a velocity of 0 + \value SmoothedAnimation.Sync + the property is immediately set to the target value */ QQuickSmoothedAnimation::ReversingMode QQuickSmoothedAnimation::reversingMode() const { @@ -569,4 +570,6 @@ void QQuickSmoothedAnimation::setMaximumEasingTime(int v) QT_END_NAMESPACE +#include "moc_qquicksmoothedanimation_p_p.cpp" + #include "moc_qquicksmoothedanimation_p.cpp" diff --git a/src/quick/util/qquicksmoothedanimation_p.h b/src/quick/util/qquicksmoothedanimation_p.h index 4a53a4406fc..9293b9aeff9 100644 --- a/src/quick/util/qquicksmoothedanimation_p.h +++ b/src/quick/util/qquicksmoothedanimation_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE class QQmlProperty; class QQuickSmoothedAnimationPrivate; -class Q_AUTOTEST_EXPORT QQuickSmoothedAnimation : public QQuickNumberAnimation +class Q_QUICK_PRIVATE_EXPORT QQuickSmoothedAnimation : public QQuickNumberAnimation { Q_OBJECT Q_DECLARE_PRIVATE(QQuickSmoothedAnimation) diff --git a/src/quick/util/qquickspringanimation_p.h b/src/quick/util/qquickspringanimation_p.h index c09806e0ec3..22ac06f619e 100644 --- a/src/quick/util/qquickspringanimation_p.h +++ b/src/quick/util/qquickspringanimation_p.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE class QQuickSpringAnimationPrivate; -class Q_AUTOTEST_EXPORT QQuickSpringAnimation : public QQuickNumberAnimation +class Q_QUICK_PRIVATE_EXPORT QQuickSpringAnimation : public QQuickNumberAnimation { Q_OBJECT Q_DECLARE_PRIVATE(QQuickSpringAnimation) diff --git a/src/quick/util/qquickstatechangescript.cpp b/src/quick/util/qquickstatechangescript.cpp index f971d7e551c..8e978a2943d 100644 --- a/src/quick/util/qquickstatechangescript.cpp +++ b/src/quick/util/qquickstatechangescript.cpp @@ -149,8 +149,6 @@ QQuickStateActionEvent::EventType QQuickStateChangeScript::type() const return Script; } - -#include <moc_qquickstatechangescript_p.cpp> - QT_END_NAMESPACE +#include <moc_qquickstatechangescript_p.cpp> diff --git a/src/quick/util/qquickstatechangescript_p.h b/src/quick/util/qquickstatechangescript_p.h index 62f49106069..292b989d86d 100644 --- a/src/quick/util/qquickstatechangescript_p.h +++ b/src/quick/util/qquickstatechangescript_p.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE class QQuickStateChangeScriptPrivate; -class Q_AUTOTEST_EXPORT QQuickStateChangeScript : public QQuickStateOperation, public QQuickStateActionEvent +class Q_QUICK_PRIVATE_EXPORT QQuickStateChangeScript : public QQuickStateOperation, public QQuickStateActionEvent { Q_OBJECT Q_DECLARE_PRIVATE(QQuickStateChangeScript) diff --git a/src/quick/util/qquickstategroup.cpp b/src/quick/util/qquickstategroup.cpp index b86333943c5..f2dc624f4ad 100644 --- a/src/quick/util/qquickstategroup.cpp +++ b/src/quick/util/qquickstategroup.cpp @@ -376,7 +376,25 @@ bool QQuickStateGroupPrivate::updateAutoState() QQuickState *state = states.at(ii); if (state->isWhenKnown()) { if (state->isNamed()) { - if (state->when()) { + bool whenValue = state->when(); + const QQmlProperty whenProp(state, u"when"_qs); + const auto potentialWhenBinding = QQmlAnyBinding::ofProperty(whenProp); + Q_ASSERT(!potentialWhenBinding.isUntypedPropertyBinding()); + + // if there is a binding, the value in when might not be up-to-date at this point + // so we manually re-evaluate the binding + QQmlAbstractBinding *abstractBinding = potentialWhenBinding.asAbstractBinding(); + if (abstractBinding && !abstractBinding->isValueTypeProxy()) { + QQmlBinding *binding = static_cast<QQmlBinding *>(abstractBinding); + if (binding->hasValidContext()) { + const auto boolType = QMetaType::fromType<bool>(); + const bool isUndefined = !binding->evaluate(&whenValue, boolType); + if (isUndefined) + whenValue = false; + } + } + + if (whenValue) { if (stateChangeDebug()) qWarning() << "Setting auto state due to expression"; if (currentState != state->name()) { diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp index 13ece608bed..f4021728919 100644 --- a/src/quick/util/qquickstyledtext.cpp +++ b/src/quick/util/qquickstyledtext.cpp @@ -583,10 +583,10 @@ bool QQuickStyledTextPrivate::parseFontAttributes(const QChar *&ch, const QStrin attr = parseAttribute(ch, textIn); if (attr.first == QLatin1String("color")) { valid = true; - format.setForeground(QColor(attr.second.toString())); + format.setForeground(QColor(attr.second)); } else if (attr.first == QLatin1String("size")) { valid = true; - int size = attr.second.toString().toInt(); + int size = attr.second.toInt(); if (attr.second.at(0) == QLatin1Char('-') || attr.second.at(0) == QLatin1Char('+')) size += 3; if (size >= 1 && size <= 7) diff --git a/src/quick/util/qquicksystempalette.cpp b/src/quick/util/qquicksystempalette.cpp index 191607a597c..01f72eab09c 100644 --- a/src/quick/util/qquicksystempalette.cpp +++ b/src/quick/util/qquicksystempalette.cpp @@ -63,8 +63,8 @@ class QQuickSystemPalettePrivate : public QObjectPrivate The SystemPalette type provides access to the Qt application palettes. This provides information about the standard colors used for application windows, buttons and other features. These colors - are grouped into three \e {color groups}: \c Active, \c Inactive, - and \c Disabled. See the QPalette documentation for details about + are grouped into three \e {color groups}: \c active, \c inactive, + and \c disabled. See the QPalette documentation for details about color groups and the properties provided by SystemPalette. This can be used to color items in a way that provides a more @@ -275,11 +275,9 @@ QColor QQuickSystemPalette::placeholderText() const The color group of the palette. This can be one of: - \list - \li SystemPalette.Active (default) - \li SystemPalette.Inactive - \li SystemPalette.Disabled - \endlist + \value SystemPalette.Active (default) QPalette::Active + \value SystemPalette.Inactive QPalette::Inactive + \value SystemPalette.Disabled QPalette::Disabled \sa QPalette::ColorGroup */ diff --git a/src/quick/util/qquicksystempalette_p.h b/src/quick/util/qquicksystempalette_p.h index 16825703633..f5040bcc74f 100644 --- a/src/quick/util/qquicksystempalette_p.h +++ b/src/quick/util/qquicksystempalette_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <private/qtquickglobal_p.h> #include <qqml.h> #include <QtCore/qobject.h> @@ -59,7 +60,7 @@ QT_BEGIN_NAMESPACE class QQuickSystemPalettePrivate; -class Q_AUTOTEST_EXPORT QQuickSystemPalette : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickSystemPalette : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QQuickSystemPalette) diff --git a/src/quick/util/qquicktextmetrics.cpp b/src/quick/util/qquicktextmetrics.cpp index 62d0e71662f..151d2848ebb 100644 --- a/src/quick/util/qquicktextmetrics.cpp +++ b/src/quick/util/qquicktextmetrics.cpp @@ -130,12 +130,10 @@ void QQuickTextMetrics::setText(const QString &text) This property holds the elide mode of the text. This determines the position in which the string is elided. The possible values are: - \list - \li \c Qt::ElideNone - No eliding; this is the default value. - \li \c Qt::ElideLeft - For example: "...World" - \li \c Qt::ElideMiddle - For example: "He...ld" - \li \c Qt::ElideRight - For example: "Hello..." - \endlist + \value Qt::ElideNone No eliding; this is the default value. + \value Qt::ElideLeft For example: "...World" + \value Qt::ElideMiddle For example: "He...ld" + \value Qt::ElideRight For example: "Hello..." \sa elideWidth, QFontMetrics::elidedText */ diff --git a/src/quick/util/qquicktextmetrics_p.h b/src/quick/util/qquicktextmetrics_p.h index 33c64073c27..4306da72587 100644 --- a/src/quick/util/qquicktextmetrics_p.h +++ b/src/quick/util/qquicktextmetrics_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <private/qtquickglobal_p.h> #include <qqml.h> #include <QtGui/QFontMetricsF> @@ -60,7 +61,7 @@ QT_BEGIN_NAMESPACE class QFont; -class Q_AUTOTEST_EXPORT QQuickTextMetrics : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickTextMetrics : public QObject { Q_OBJECT diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp index 7ec7c827eb4..949724e87c9 100644 --- a/src/quick/util/qquicktimeline.cpp +++ b/src/quick/util/qquicktimeline.cpp @@ -53,6 +53,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcTl, "qt.quick.timeline") + struct Update { Update(QQuickTimeLineValue *_g, qreal _v) : g(_g), v(_v) {} @@ -513,6 +515,7 @@ void QQuickTimeLine::reset(QQuickTimeLineValue &timeLineValue) qWarning() << "QQuickTimeLine: Cannot reset a QQuickTimeLineValue owned by another timeline."; return; } + qCDebug(lcTl) << static_cast<QObject*>(this) << timeLineValue.value(); remove(&timeLineValue); timeLineValue._t = nullptr; } @@ -954,3 +957,5 @@ QQuickTimeLineObject *QQuickTimeLineCallback::callbackObject() const } QT_END_NAMESPACE + +#include "moc_qquicktimeline_p_p.cpp" diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp index 9c55454c0e5..64394ee2854 100644 --- a/src/quick/util/qquicktransition.cpp +++ b/src/quick/util/qquicktransition.cpp @@ -82,6 +82,11 @@ QT_BEGIN_NAMESPACE values can be set to restrict the animations to only be applied when changing from one particular state to another. + Top-level animations within a transition are run in parallel. To run them + sequentially, define them within a SequentialAnimation: + + \snippet qml/transition-reversible.qml sequential animations + To define multiple Transitions, specify \l Item::transitions as a list: \snippet qml/transitions-list.qml list of transitions @@ -229,6 +234,12 @@ void QQuickTransitionInstance::stop() m_anim->stop(); } +void QQuickTransitionInstance::complete() +{ + if (m_anim) + m_anim->complete(); +} + bool QQuickTransitionInstance::isRunning() const { return m_anim && m_anim->state() == QAbstractAnimationJob::Running; diff --git a/src/quick/util/qquicktransition_p.h b/src/quick/util/qquicktransition_p.h index bfb7d758212..ed2ec705b25 100644 --- a/src/quick/util/qquicktransition_p.h +++ b/src/quick/util/qquicktransition_p.h @@ -73,6 +73,7 @@ class QQuickTransitionInstance : QAnimationJobChangeListener void start(); void stop(); + void complete(); bool isRunning() const; diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp index 97c1fcd0452..4de4201c7bf 100644 --- a/src/quick/util/qquicktransitionmanager.cpp +++ b/src/quick/util/qquicktransitionmanager.cpp @@ -140,8 +140,10 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list, for (const QQuickStateAction &action : qAsConst(applyList)) { if (action.toBinding) d->bindingsList << action; - if (action.fromBinding) - QQmlPropertyPrivate::removeBinding(action.property); // Disable current binding + if (action.fromBinding) { + auto property = action.property; + QQmlAnyBinding::removeBindingFrom(property); // Disable current binding + } if (action.event && action.event->changesBindings()) { //### assume isReversable()? d->bindingsList << action; action.event->clearBindings(); @@ -194,8 +196,10 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list, continue; } - if (action.toBinding) - QQmlPropertyPrivate::removeBinding(action.property); // Make sure this is disabled during the transition + if (action.toBinding) { + auto property = action.property; + QQmlAnyBinding::removeBindingFrom(property); // Make sure this is disabled during the transition + } QQmlPropertyPrivate::write(action.property, action.fromValue, QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding); } @@ -263,7 +267,8 @@ void QQuickTransitionManager::cancel() for (const QQuickStateAction &action : qAsConst(d->bindingsList)) { if (action.toBinding && action.deletableToBinding) { - QQmlPropertyPrivate::removeBinding(action.property); + auto property = action.property; + QQmlAnyBinding::removeBindingFrom(property); } else if (action.event) { //### what do we do here? } diff --git a/src/quick/util/qquickvalidator.cpp b/src/quick/util/qquickvalidator.cpp index c309460263a..efc98503895 100644 --- a/src/quick/util/qquickvalidator.cpp +++ b/src/quick/util/qquickvalidator.cpp @@ -56,6 +56,8 @@ QT_BEGIN_NAMESPACE interpret the number and will accept locale specific digits, group separators, and positive and negative signs. In addition, IntValidator is always guaranteed to accept a number formatted according to the "C" locale. + + \sa DoubleValidator, RegularExpressionValidator, {Validating Input Text} */ QQuickIntValidator::QQuickIntValidator(QObject *parent) @@ -131,6 +133,8 @@ void QQuickIntValidator::resetLocaleName() it is also rejected. If \l notation is DoubleValidator.ScientificNotation, and the input is not in the valid range, it is accecpted but invalid. The value may yet become valid by changing the exponent. + + \sa IntValidator, RegularExpressionValidator, {Validating Input Text} */ QQuickDoubleValidator::QQuickDoubleValidator(QObject *parent) @@ -192,12 +196,8 @@ void QQuickDoubleValidator::resetLocaleName() The possible values for this property are: - \list - \li DoubleValidator.StandardNotation - \li DoubleValidator.ScientificNotation (default) - \endlist - - If this property is set to DoubleValidator.ScientificNotation, the written number may have an exponent part (e.g. 1.5E-2). + \value DoubleValidator.StandardNotation only decimal numbers with optional sign (e.g. \c -0.015) + \value DoubleValidator.ScientificNotation (default) the written number may have an exponent part (e.g. \c 1.5E-2) */ /*! @@ -210,6 +210,8 @@ void QQuickDoubleValidator::resetLocaleName() The RegularExpressionValidator type provides a validator, that counts as valid any string which matches a specified regular expression. + + \sa IntValidator, DoubleValidator, {Validating Input Text} */ /*! \qmlproperty regularExpression QtQuick::RegularExpressionValidator::regularExpression diff --git a/src/quick/util/qquickvalidator_p.h b/src/quick/util/qquickvalidator_p.h index d0e3c9d7848..8347a4a32b3 100644 --- a/src/quick/util/qquickvalidator_p.h +++ b/src/quick/util/qquickvalidator_p.h @@ -51,13 +51,14 @@ // We mean it. // +#include <private/qtquickglobal_p.h> #include <QtGui/qvalidator.h> #include <QtQml/qqml.h> QT_BEGIN_NAMESPACE #if QT_CONFIG(validator) -class Q_AUTOTEST_EXPORT QQuickIntValidator : public QIntValidator +class Q_QUICK_PRIVATE_EXPORT QQuickIntValidator : public QIntValidator { Q_OBJECT Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged) @@ -74,7 +75,7 @@ class Q_AUTOTEST_EXPORT QQuickIntValidator : public QIntValidator void localeNameChanged(); }; -class Q_AUTOTEST_EXPORT QQuickDoubleValidator : public QDoubleValidator +class Q_QUICK_PRIVATE_EXPORT QQuickDoubleValidator : public QDoubleValidator { Q_OBJECT Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged) diff --git a/src/quickcontrols2/CMakeLists.txt b/src/quickcontrols2/CMakeLists.txt new file mode 100644 index 00000000000..1e04587af01 --- /dev/null +++ b/src/quickcontrols2/CMakeLists.txt @@ -0,0 +1,85 @@ +##################################################################### +## QuickControls2 Module: +##################################################################### + +qt_internal_add_qml_module(QuickControls2 + URI "QtQuick.Controls" + VERSION "${PROJECT_VERSION}" + PAST_MAJOR_VERSIONS 2 + DESIGNER_SUPPORTED + CLASS_NAME QtQuickControls2Plugin + PLUGIN_TARGET qtquickcontrols2plugin + IMPORTS + QtQuick.Controls.impl/auto + OPTIONAL_IMPORTS + QtQuick.Controls.Basic/auto + QtQuick.Controls.Fusion/auto + QtQuick.Controls.Material/auto + QtQuick.Controls.Imagine/auto + QtQuick.Controls.Universal/auto + QtQuick.Controls.Windows/auto + QtQuick.Controls.macOS/auto + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + SOURCES + qquickstyle.cpp qquickstyle.h qquickstyle_p.h + qquickstyleplugin.cpp qquickstyleplugin_p.h + qtquickcontrols2global.h + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickPrivate + Qt::QuickTemplates2 + Qt::QuickTemplates2Private + PUBLIC_LIBRARIES + Qt::Core + Qt::Gui + Qt::Quick +) + +qt_internal_extend_target(qtquickcontrols2plugin + SOURCES + qtquickcontrols2plugin.cpp + LIBRARIES + Qt::QuickControls2ImplPrivate + Qt::QuickControls2Private + Qt::QuickTemplates2Private +) + +if(QT_FEATURE_quick_designer) + add_subdirectory(designer) +endif() + +add_subdirectory(basic) +add_subdirectory(fusion) +add_subdirectory(imagine) +add_subdirectory(material) +add_subdirectory(universal) + +if(MACOS) + add_subdirectory(macos) +endif() + +if(WIN32) + add_subdirectory(windows) +endif() + +qt_internal_add_docs(QuickControls2 + doc/qtquickcontrols.qdocconf +) + +# Make the doc files available to Creator's locator. +file(GLOB doc_files + "${CMAKE_CURRENT_SOURCE_DIR}/doc/snippets/*.qml" + "${CMAKE_CURRENT_SOURCE_DIR}/doc/src/*.qdoc" + "${CMAKE_CURRENT_SOURCE_DIR}/doc/src/templates/*.qdoc" +) +target_sources(QuickControls2 + PRIVATE + ${doc_files} + doc/qtquickcontrols.qdocconf +) diff --git a/src/quickcontrols2/basic/AbstractButton.qml b/src/quickcontrols2/basic/AbstractButton.qml new file mode 100644 index 00000000000..a4855c2197e --- /dev/null +++ b/src/quickcontrols2/basic/AbstractButton.qml @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.AbstractButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) +} diff --git a/src/quickcontrols2/basic/Action.qml b/src/quickcontrols2/basic/Action.qml new file mode 100644 index 00000000000..bb66fc8fb58 --- /dev/null +++ b/src/quickcontrols2/basic/Action.qml @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Action { } diff --git a/src/quickcontrols2/basic/ActionGroup.qml b/src/quickcontrols2/basic/ActionGroup.qml new file mode 100644 index 00000000000..70170f0e4eb --- /dev/null +++ b/src/quickcontrols2/basic/ActionGroup.qml @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ActionGroup { } diff --git a/src/quickcontrols2/basic/ApplicationWindow.qml b/src/quickcontrols2/basic/ApplicationWindow.qml new file mode 100644 index 00000000000..ac50d5fa794 --- /dev/null +++ b/src/quickcontrols2/basic/ApplicationWindow.qml @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ApplicationWindow { + id: window + + color: window.palette.window +} diff --git a/src/quickcontrols2/basic/BusyIndicator.qml b/src/quickcontrols2/basic/BusyIndicator.qml new file mode 100644 index 00000000000..0c51c9a2804 --- /dev/null +++ b/src/quickcontrols2/basic/BusyIndicator.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.Basic.impl +import QtQuick.Templates as T + +T.BusyIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + + contentItem: BusyIndicatorImpl { + implicitWidth: 48 + implicitHeight: 48 + + pen: control.palette.dark + fill: control.palette.dark + + running: control.running + opacity: control.running ? 1 : 0 + Behavior on opacity { OpacityAnimator { duration: 250 } } + } +} diff --git a/src/quickcontrols2/basic/Button.qml b/src/quickcontrols2/basic/Button.qml new file mode 100644 index 00000000000..f657a0d2437 --- /dev/null +++ b/src/quickcontrols2/basic/Button.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.Button { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + horizontalPadding: padding + 2 + spacing: 6 + + icon.width: 24 + icon.height: 24 + icon.color: control.checked || control.highlighted ? control.palette.brightText : + control.flat && !control.down ? (control.visualFocus ? control.palette.highlight : control.palette.windowText) : control.palette.buttonText + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.checked || control.highlighted ? control.palette.brightText : + control.flat && !control.down ? (control.visualFocus ? control.palette.highlight : control.palette.windowText) : control.palette.buttonText + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + visible: !control.flat || control.down || control.checked || control.highlighted + color: Color.blend(control.checked || control.highlighted ? control.palette.dark : control.palette.button, + control.palette.mid, control.down ? 0.5 : 0.0) + border.color: control.palette.highlight + border.width: control.visualFocus ? 2 : 0 + } +} diff --git a/src/quickcontrols2/basic/ButtonGroup.qml b/src/quickcontrols2/basic/ButtonGroup.qml new file mode 100644 index 00000000000..fadc538a496 --- /dev/null +++ b/src/quickcontrols2/basic/ButtonGroup.qml @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ButtonGroup { } diff --git a/src/quickcontrols2/basic/CMakeLists.txt b/src/quickcontrols2/basic/CMakeLists.txt new file mode 100644 index 00000000000..b871284b99d --- /dev/null +++ b/src/quickcontrols2/basic/CMakeLists.txt @@ -0,0 +1,171 @@ +##################################################################### +## qtquickcontrols2basicstyleplugin Plugin: +##################################################################### + +set(qml_files + "AbstractButton.qml" + "Action.qml" + "ActionGroup.qml" + "ApplicationWindow.qml" + "BusyIndicator.qml" + "Button.qml" + "ButtonGroup.qml" + "CheckBox.qml" + "CheckDelegate.qml" + "ComboBox.qml" + "Container.qml" + "Control.qml" + "DelayButton.qml" + "Dial.qml" + "Dialog.qml" + "DialogButtonBox.qml" + "Drawer.qml" + "Frame.qml" + "GroupBox.qml" + "HorizontalHeaderView.qml" + "ItemDelegate.qml" + "Label.qml" + "Menu.qml" + "MenuBar.qml" + "MenuBarItem.qml" + "MenuItem.qml" + "MenuSeparator.qml" + "Page.qml" + "PageIndicator.qml" + "Pane.qml" + "Popup.qml" + "ProgressBar.qml" + "RadioButton.qml" + "RadioDelegate.qml" + "RangeSlider.qml" + "RoundButton.qml" + "ScrollBar.qml" + "ScrollIndicator.qml" + "ScrollView.qml" + "SelectionRectangle.qml" + "Slider.qml" + "SpinBox.qml" + "SplitView.qml" + "StackView.qml" + "SwipeDelegate.qml" + "Switch.qml" + "SwitchDelegate.qml" + "SwipeView.qml" + "TabBar.qml" + "TabButton.qml" + "TextArea.qml" + "TextField.qml" + "ToolBar.qml" + "ToolButton.qml" + "ToolSeparator.qml" + "ToolTip.qml" + "Tumbler.qml" + "VerticalHeaderView.qml" +) +set_source_files_properties(Action.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.3;6.0" +) +set_source_files_properties(ActionGroup.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.3;6.0" +) +set_source_files_properties(DelayButton.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.2;6.0" +) +set_source_files_properties(Dialog.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(DialogButtonBox.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(HorizontalHeaderView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.15;6.0" +) +set_source_files_properties(MenuBar.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.3;6.0" +) +set_source_files_properties(MenuBarItem.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.3;6.0" +) +set_source_files_properties(MenuSeparator.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(RoundButton.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(ScrollView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.2;6.0" +) +set_source_files_properties(SelectionRectangle.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "6.2" +) +set_source_files_properties(SplitView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.13;6.0" +) +set_source_files_properties(ToolSeparator.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(VerticalHeaderView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.15;6.0" +) + +qt_internal_add_qml_module(qtquickcontrols2basicstyleplugin + URI "QtQuick.Controls.Basic" + VERSION "${PROJECT_VERSION}" + PAST_MAJOR_VERSIONS 2 + CLASS_NAME QtQuickControls2BasicStylePlugin + PLUGIN_TARGET qtquickcontrols2basicstyleplugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + SOURCES + qquickbasicstyle.cpp qquickbasicstyle_p.h + qquickbasictheme.cpp qquickbasictheme_p.h + qtquickcontrols2basicstyleplugin.cpp + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2Private + Qt::QuickPrivate + Qt::QuickTemplates2Private +) + +# Resources: +set(qtquickcontrols2basicstyleplugin_resource_files + "images/arrow-indicator.png" + "images/arrow-indicator@2x.png" + "images/arrow-indicator@3x.png" + "images/arrow-indicator@4x.png" + "images/check.png" + "images/check@2x.png" + "images/check@3x.png" + "images/check@4x.png" + "images/dial-indicator.png" + "images/dial-indicator@2x.png" + "images/dial-indicator@3x.png" + "images/dial-indicator@4x.png" + "images/double-arrow.png" + "images/double-arrow@2x.png" + "images/double-arrow@3x.png" + "images/double-arrow@4x.png" + "images/drop-indicator.png" + "images/drop-indicator@2x.png" + "images/drop-indicator@3x.png" + "images/drop-indicator@4x.png" +) + +qt_internal_add_resource(qtquickcontrols2basicstyleplugin "qtquickcontrols2basicstyleplugin" + PREFIX + "/qt-project.org/imports/QtQuick/Controls/Basic" + FILES + ${qtquickcontrols2basicstyleplugin_resource_files} +) + +add_subdirectory(impl) + +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2basicstyleplugin + qtquickcontrols2basicstyleimplplugin) diff --git a/src/quickcontrols2/basic/CheckBox.qml b/src/quickcontrols2/basic/CheckBox.qml new file mode 100644 index 00000000000..6465460d339 --- /dev/null +++ b/src/quickcontrols2/basic/CheckBox.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl + +T.CheckBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + // keep in sync with CheckDelegate.qml (shared CheckIndicator.qml was removed for performance reasons) + indicator: Rectangle { + implicitWidth: 28 + implicitHeight: 28 + + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + color: control.down ? control.palette.light : control.palette.base + border.width: control.visualFocus ? 2 : 1 + border.color: control.visualFocus ? control.palette.highlight : control.palette.mid + + ColorImage { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + defaultColor: "#353637" + color: control.palette.text + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png" + visible: control.checkState === Qt.Checked + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 16 + height: 3 + color: control.palette.text + visible: control.checkState === Qt.PartiallyChecked + } + } + + contentItem: CheckLabel { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.palette.windowText + } +} diff --git a/src/quickcontrols2/basic/CheckDelegate.qml b/src/quickcontrols2/basic/CheckDelegate.qml new file mode 100644 index 00000000000..1a1827e30cd --- /dev/null +++ b/src/quickcontrols2/basic/CheckDelegate.qml @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl + +T.CheckDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 12 + spacing: 12 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.text + + contentItem: IconLabel { + leftPadding: control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: !control.mirrored ? control.indicator.width + control.spacing : 0 + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.palette.text + } + + // keep in sync with CheckBox.qml (shared CheckIndicator.qml was removed for performance reasons) + indicator: Rectangle { + implicitWidth: 28 + implicitHeight: 28 + + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + color: control.down ? control.palette.light : control.palette.base + border.width: control.visualFocus ? 2 : 1 + border.color: control.visualFocus ? control.palette.highlight : control.palette.mid + + ColorImage { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + defaultColor: "#353637" + color: control.palette.text + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png" + visible: control.checkState === Qt.Checked + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 16 + height: 3 + color: control.palette.text + visible: control.checkState === Qt.PartiallyChecked + } + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + visible: control.down || control.highlighted + color: control.down ? control.palette.midlight : control.palette.light + } +} diff --git a/src/quickcontrols2/basic/ComboBox.qml b/src/quickcontrols2/basic/ComboBox.qml new file mode 100644 index 00000000000..6a1924ed102 --- /dev/null +++ b/src/quickcontrols2/basic/ComboBox.qml @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ComboBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + + delegate: ItemDelegate { + width: ListView.view.width + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData + palette.text: control.palette.text + palette.highlightedText: control.palette.highlightedText + font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal + highlighted: control.highlightedIndex === index + hoverEnabled: control.hoverEnabled + } + + indicator: ColorImage { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + color: control.palette.dark + defaultColor: "#353637" + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/double-arrow.png" + opacity: enabled ? 1 : 0.3 + } + + contentItem: T.TextField { + leftPadding: !control.mirrored ? 12 : control.editable && activeFocus ? 3 : 1 + rightPadding: control.mirrored ? 12 : control.editable && activeFocus ? 3 : 1 + topPadding: 6 - control.padding + bottomPadding: 6 - control.padding + + text: control.editable ? control.editText : control.displayText + + enabled: control.editable + autoScroll: control.editable + readOnly: control.down + inputMethodHints: control.inputMethodHints + validator: control.validator + selectByMouse: control.selectTextByMouse + + font: control.font + color: control.editable ? control.palette.text : control.palette.buttonText + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + verticalAlignment: Text.AlignVCenter + + background: Rectangle { + visible: control.enabled && control.editable && !control.flat + border.width: parent && parent.activeFocus ? 2 : 1 + border.color: parent && parent.activeFocus ? control.palette.highlight : control.palette.button + color: control.palette.base + } + } + + background: Rectangle { + implicitWidth: 140 + implicitHeight: 40 + + color: control.down ? control.palette.mid : control.palette.button + border.color: control.palette.highlight + border.width: !control.editable && control.visualFocus ? 2 : 0 + visible: !control.flat || control.down + } + + popup: T.Popup { + y: control.height + width: control.width + height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin) + topMargin: 6 + bottomMargin: 6 + + contentItem: ListView { + clip: true + implicitHeight: contentHeight + model: control.delegateModel + currentIndex: control.highlightedIndex + highlightMoveDuration: 0 + + Rectangle { + z: 10 + width: parent.width + height: parent.height + color: "transparent" + border.color: control.palette.mid + } + + T.ScrollIndicator.vertical: ScrollIndicator { } + } + + background: Rectangle { + color: control.palette.window + } + } +} diff --git a/src/quickcontrols2/basic/Container.qml b/src/quickcontrols2/basic/Container.qml new file mode 100644 index 00000000000..939190755c7 --- /dev/null +++ b/src/quickcontrols2/basic/Container.qml @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Container { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) +} diff --git a/src/quickcontrols2/basic/Control.qml b/src/quickcontrols2/basic/Control.qml new file mode 100644 index 00000000000..7a68a43166d --- /dev/null +++ b/src/quickcontrols2/basic/Control.qml @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Control { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) +} diff --git a/src/quickcontrols2/basic/DelayButton.qml b/src/quickcontrols2/basic/DelayButton.qml new file mode 100644 index 00000000000..367384c0316 --- /dev/null +++ b/src/quickcontrols2/basic/DelayButton.qml @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.DelayButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + horizontalPadding: padding + 2 + + transition: Transition { + NumberAnimation { + duration: control.delay * (control.pressed ? 1.0 - control.progress : 0.3 * control.progress) + } + } + + contentItem: ItemGroup { + ClippedText { + clip: control.progress > 0 + clipX: -control.leftPadding + control.progress * control.width + clipWidth: (1.0 - control.progress) * control.width + visible: control.progress < 1 + + text: control.text + font: control.font + opacity: enabled ? 1 : 0.3 + color: control.palette.buttonText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + ClippedText { + clip: control.progress > 0 + clipX: -control.leftPadding + clipWidth: control.progress * control.width + visible: control.progress > 0 + + text: control.text + font: control.font + opacity: enabled ? 1 : 0.3 + color: control.palette.brightText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: Color.blend(control.palette.button, control.palette.mid, control.down ? 0.5 : 0.0) + border.color: control.palette.highlight + border.width: control.visualFocus ? 2 : 0 + + PaddedRectangle { + padding: control.visualFocus ? 2 : 0 + width: control.progress * parent.width + height: parent.height + color: Color.blend(control.palette.dark, control.palette.mid, control.down ? 0.5 : 0.0) + } + } +} diff --git a/src/quickcontrols2/basic/Dial.qml b/src/quickcontrols2/basic/Dial.qml new file mode 100644 index 00000000000..8450e9f9e5c --- /dev/null +++ b/src/quickcontrols2/basic/Dial.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Controls.Basic.impl +import QtQuick.Templates as T + +T.Dial { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + background: DialImpl { + implicitWidth: 184 + implicitHeight: 184 + color: control.visualFocus ? control.palette.highlight : control.palette.dark + progress: control.position + opacity: control.enabled ? 1 : 0.3 + } + + handle: ColorImage { + x: control.background.x + control.background.width / 2 - width / 2 + y: control.background.y + control.background.height / 2 - height / 2 + width: 14 + height: 10 + defaultColor: "#353637" + color: control.visualFocus ? control.palette.highlight : control.palette.dark + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/dial-indicator.png" + antialiasing: true + opacity: control.enabled ? 1 : 0.3 + transform: [ + Translate { + y: -Math.min(control.background.width, control.background.height) * 0.4 + control.handle.height / 2 + }, + Rotation { + angle: control.angle + origin.x: control.handle.width / 2 + origin.y: control.handle.height / 2 + } + ] + } +} diff --git a/src/quickcontrols2/basic/Dialog.qml b/src/quickcontrols2/basic/Dialog.qml new file mode 100644 index 00000000000..1f2b4fbb6a8 --- /dev/null +++ b/src/quickcontrols2/basic/Dialog.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl + +T.Dialog { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + padding: 12 + + background: Rectangle { + color: control.palette.window + border.color: control.palette.dark + } + + header: Label { + text: control.title + visible: control.title + elide: Label.ElideRight + font.bold: true + padding: 12 + background: Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 1 + color: control.palette.window + } + } + + footer: DialogButtonBox { + visible: count > 0 + } + + T.Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + T.Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } +} diff --git a/src/quickcontrols2/basic/DialogButtonBox.qml b/src/quickcontrols2/basic/DialogButtonBox.qml new file mode 100644 index 00000000000..f69944852cb --- /dev/null +++ b/src/quickcontrols2/basic/DialogButtonBox.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.DialogButtonBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + (control.count === 1 ? implicitContentWidth * 2 : implicitContentWidth) + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + contentWidth: contentItem.contentWidth + + spacing: 1 + padding: 12 + alignment: count === 1 ? Qt.AlignRight : undefined + + delegate: Button { + width: control.count === 1 ? control.availableWidth / 2 : undefined + } + + contentItem: ListView { + implicitWidth: contentWidth + model: control.contentModel + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + } + + background: Rectangle { + implicitHeight: 40 + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + color: control.palette.window + } +} diff --git a/src/quickcontrols2/basic/Drawer.qml b/src/quickcontrols2/basic/Drawer.qml new file mode 100644 index 00000000000..0d286f9910f --- /dev/null +++ b/src/quickcontrols2/basic/Drawer.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.Drawer { + id: control + + parent: T.Overlay.overlay + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: control.edge === Qt.BottomEdge + leftPadding: control.edge === Qt.RightEdge + rightPadding: control.edge === Qt.LeftEdge + bottomPadding: control.edge === Qt.TopEdge + + enter: Transition { SmoothedAnimation { velocity: 5 } } + exit: Transition { SmoothedAnimation { velocity: 5 } } + + background: Rectangle { + color: control.palette.window + Rectangle { + readonly property bool horizontal: control.edge === Qt.LeftEdge || control.edge === Qt.RightEdge + width: horizontal ? 1 : parent.width + height: horizontal ? parent.height : 1 + color: control.palette.dark + x: control.edge === Qt.LeftEdge ? parent.width - 1 : 0 + y: control.edge === Qt.TopEdge ? parent.height - 1 : 0 + } + } + + T.Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + T.Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } +} diff --git a/src/quickcontrols2/basic/Frame.qml b/src/quickcontrols2/basic/Frame.qml new file mode 100644 index 00000000000..22f29806129 --- /dev/null +++ b/src/quickcontrols2/basic/Frame.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.Frame { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 12 + + background: Rectangle { + color: "transparent" + border.color: control.palette.mid + } +} diff --git a/src/quickcontrols2/basic/GroupBox.qml b/src/quickcontrols2/basic/GroupBox.qml new file mode 100644 index 00000000000..27ff8ce6e42 --- /dev/null +++ b/src/quickcontrols2/basic/GroupBox.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.GroupBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitLabelWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: 6 + padding: 12 + topPadding: padding + (implicitLabelWidth > 0 ? implicitLabelHeight + spacing : 0) + + label: Text { + x: control.leftPadding + width: control.availableWidth + + text: control.title + font: control.font + color: control.palette.windowText + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + background: Rectangle { + y: control.topPadding - control.bottomPadding + width: parent.width + height: parent.height - control.topPadding + control.bottomPadding + + color: "transparent" + border.color: control.palette.mid + } +} diff --git a/src/quickcontrols2/basic/HorizontalHeaderView.qml b/src/quickcontrols2/basic/HorizontalHeaderView.qml new file mode 100644 index 00000000000..e52145932fe --- /dev/null +++ b/src/quickcontrols2/basic/HorizontalHeaderView.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.HorizontalHeaderView { + id: control + + implicitWidth: syncView ? syncView.width : 0 + implicitHeight: contentHeight + + delegate: Rectangle { + // Qt6: add cellPadding (and font etc) as public API in headerview + readonly property real cellPadding: 8 + + implicitWidth: text.implicitWidth + (cellPadding * 2) + implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2)) + color: "#f6f6f6" + border.color: "#e4e4e4" + + Text { + id: text + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] + : model[control.textRole]) + : modelData + width: parent.width + height: parent.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: "#ff26282a" + } + } +} diff --git a/src/quickcontrols2/basic/ItemDelegate.qml b/src/quickcontrols2/basic/ItemDelegate.qml new file mode 100644 index 00000000000..3a1cb298b9f --- /dev/null +++ b/src/quickcontrols2/basic/ItemDelegate.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ItemDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 12 + spacing: 8 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.text + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.highlighted ? control.palette.highlightedText : control.palette.text + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + visible: control.down || control.highlighted || control.visualFocus + color: Color.blend(control.down ? control.palette.midlight : control.palette.light, + control.palette.highlight, control.visualFocus ? 0.15 : 0.0) + } +} diff --git a/src/quickcontrols2/basic/Label.qml b/src/quickcontrols2/basic/Label.qml new file mode 100644 index 00000000000..9d7dfdfdf01 --- /dev/null +++ b/src/quickcontrols2/basic/Label.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.Label { + id: control + + color: control.palette.windowText + linkColor: control.palette.link +} diff --git a/src/quickcontrols2/basic/Menu.qml b/src/quickcontrols2/basic/Menu.qml new file mode 100644 index 00000000000..bee89f94bb0 --- /dev/null +++ b/src/quickcontrols2/basic/Menu.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.Menu { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + margins: 0 + overlap: 1 + + delegate: MenuItem { } + + contentItem: ListView { + implicitHeight: contentHeight + model: control.contentModel + interactive: contentHeight + control.topPadding + control.bottomPadding > control.height + clip: true + currentIndex: control.currentIndex + + ScrollIndicator.vertical: ScrollIndicator {} + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 40 + color: control.palette.window + border.color: control.palette.dark + } + + T.Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + T.Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } +} diff --git a/src/quickcontrols2/basic/MenuBar.qml b/src/quickcontrols2/basic/MenuBar.qml new file mode 100644 index 00000000000..79199d121f7 --- /dev/null +++ b/src/quickcontrols2/basic/MenuBar.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl + +T.MenuBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + delegate: MenuBarItem { } + + contentItem: Row { + spacing: control.spacing + Repeater { + model: control.contentModel + } + } + + background: Rectangle { + implicitHeight: 40 + color: control.palette.button + } +} diff --git a/src/quickcontrols2/basic/MenuBarItem.qml b/src/quickcontrols2/basic/MenuBarItem.qml new file mode 100644 index 00000000000..e7fd1c0bead --- /dev/null +++ b/src/quickcontrols2/basic/MenuBarItem.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl + +T.MenuBarItem { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 6 + padding: 6 + leftPadding: 12 + rightPadding: 16 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.buttonText + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.palette.buttonText + } + + background: Rectangle { + implicitWidth: 40 + implicitHeight: 40 + color: control.down || control.highlighted ? control.palette.mid : "transparent" + } +} diff --git a/src/quickcontrols2/basic/MenuItem.qml b/src/quickcontrols2/basic/MenuItem.qml new file mode 100644 index 00000000000..ab1f12f5a90 --- /dev/null +++ b/src/quickcontrols2/basic/MenuItem.qml @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.MenuItem { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.windowText + + contentItem: IconLabel { + readonly property real arrowPadding: control.subMenu && control.arrow ? control.arrow.width + control.spacing : 0 + readonly property real indicatorPadding: control.checkable && control.indicator ? control.indicator.width + control.spacing : 0 + leftPadding: !control.mirrored ? indicatorPadding : arrowPadding + rightPadding: control.mirrored ? indicatorPadding : arrowPadding + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.palette.windowText + } + + indicator: ColorImage { + x: control.mirrored ? control.width - width - control.rightPadding : control.leftPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + visible: control.checked + source: control.checkable ? "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png" : "" + color: control.palette.windowText + defaultColor: "#353637" + } + + arrow: ColorImage { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + visible: control.subMenu + mirror: control.mirrored + source: control.subMenu ? "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/arrow-indicator.png" : "" + color: control.palette.windowText + defaultColor: "#353637" + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 40 + x: 1 + y: 1 + width: control.width - 2 + height: control.height - 2 + color: control.down ? control.palette.midlight : control.highlighted ? control.palette.light : "transparent" + } +} diff --git a/src/quickcontrols2/basic/MenuSeparator.qml b/src/quickcontrols2/basic/MenuSeparator.qml new file mode 100644 index 00000000000..bc17dc391ff --- /dev/null +++ b/src/quickcontrols2/basic/MenuSeparator.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.MenuSeparator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 2 + verticalPadding: padding + 4 + + contentItem: Rectangle { + implicitWidth: 188 + implicitHeight: 1 + color: control.palette.mid + } +} diff --git a/src/quickcontrols2/basic/Page.qml b/src/quickcontrols2/basic/Page.qml new file mode 100644 index 00000000000..ff75ee4ef4d --- /dev/null +++ b/src/quickcontrols2/basic/Page.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.Page { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + background: Rectangle { + color: control.palette.window + } +} diff --git a/src/quickcontrols2/basic/PageIndicator.qml b/src/quickcontrols2/basic/PageIndicator.qml new file mode 100644 index 00000000000..7197333ca70 --- /dev/null +++ b/src/quickcontrols2/basic/PageIndicator.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.PageIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + delegate: Rectangle { + implicitWidth: 8 + implicitHeight: 8 + + radius: width / 2 + color: control.palette.dark + + opacity: index === control.currentIndex ? 0.95 : pressed ? 0.7 : 0.45 + + required property int index + + Behavior on opacity { OpacityAnimator { duration: 100 } } + } + + contentItem: Row { + spacing: control.spacing + + Repeater { + model: control.count + delegate: control.delegate + } + } +} diff --git a/src/quickcontrols2/basic/Pane.qml b/src/quickcontrols2/basic/Pane.qml new file mode 100644 index 00000000000..181db9e44f8 --- /dev/null +++ b/src/quickcontrols2/basic/Pane.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.Pane { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 12 + + background: Rectangle { + color: control.palette.window + } +} diff --git a/src/quickcontrols2/basic/Popup.qml b/src/quickcontrols2/basic/Popup.qml new file mode 100644 index 00000000000..720483d97fa --- /dev/null +++ b/src/quickcontrols2/basic/Popup.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.Popup { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 12 + + background: Rectangle { + color: control.palette.window + border.color: control.palette.dark + } + + T.Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + T.Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } +} diff --git a/src/quickcontrols2/basic/ProgressBar.qml b/src/quickcontrols2/basic/ProgressBar.qml new file mode 100644 index 00000000000..a49538d100b --- /dev/null +++ b/src/quickcontrols2/basic/ProgressBar.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Basic.impl + +T.ProgressBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + contentItem: ProgressBarImpl { + implicitHeight: 6 + implicitWidth: 116 + scale: control.mirrored ? -1 : 1 + progress: control.position + indeterminate: control.visible && control.indeterminate + color: control.palette.dark + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 6 + y: (control.height - height) / 2 + height: 6 + + color: control.palette.midlight + } +} diff --git a/src/quickcontrols2/basic/RadioButton.qml b/src/quickcontrols2/basic/RadioButton.qml new file mode 100644 index 00000000000..adb914357d9 --- /dev/null +++ b/src/quickcontrols2/basic/RadioButton.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.RadioButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + // keep in sync with RadioDelegate.qml (shared RadioIndicator.qml was removed for performance reasons) + indicator: Rectangle { + implicitWidth: 28 + implicitHeight: 28 + + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + radius: width / 2 + color: control.down ? control.palette.light : control.palette.base + border.width: control.visualFocus ? 2 : 1 + border.color: control.visualFocus ? control.palette.highlight : control.palette.mid + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 20 + height: 20 + radius: width / 2 + color: control.palette.text + visible: control.checked + } + } + + contentItem: CheckLabel { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.palette.windowText + } +} diff --git a/src/quickcontrols2/basic/RadioDelegate.qml b/src/quickcontrols2/basic/RadioDelegate.qml new file mode 100644 index 00000000000..69be290c72a --- /dev/null +++ b/src/quickcontrols2/basic/RadioDelegate.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.RadioDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 12 + spacing: 12 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.text + + contentItem: IconLabel { + leftPadding: control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: !control.mirrored ? control.indicator.width + control.spacing : 0 + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.palette.text + } + + // keep in sync with RadioButton.qml (shared RadioIndicator.qml was removed for performance reasons) + indicator: Rectangle { + implicitWidth: 28 + implicitHeight: 28 + + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + radius: width / 2 + color: control.down ? control.palette.light : control.palette.base + border.width: control.visualFocus ? 2 : 1 + border.color: control.visualFocus ? control.palette.highlight : control.palette.mid + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 20 + height: 20 + radius: width / 2 + color: control.palette.text + visible: control.checked + } + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + visible: control.down || control.highlighted + color: control.down ? control.palette.midlight : control.palette.light + } +} diff --git a/src/quickcontrols2/basic/RangeSlider.qml b/src/quickcontrols2/basic/RangeSlider.qml new file mode 100644 index 00000000000..e47cbd524ba --- /dev/null +++ b/src/quickcontrols2/basic/RangeSlider.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.RangeSlider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + first.implicitHandleWidth + leftPadding + rightPadding, + second.implicitHandleWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + first.implicitHandleHeight + topPadding + bottomPadding, + second.implicitHandleHeight + topPadding + bottomPadding) + + padding: 6 + + first.handle: Rectangle { + x: control.leftPadding + (control.horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height)) + implicitWidth: 28 + implicitHeight: 28 + radius: width / 2 + border.width: activeFocus ? 2 : 1 + border.color: activeFocus ? control.palette.highlight : control.enabled ? control.palette.mid : control.palette.midlight + color: control.first.pressed ? control.palette.light : control.palette.window + } + + second.handle: Rectangle { + x: control.leftPadding + (control.horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height)) + implicitWidth: 28 + implicitHeight: 28 + radius: width / 2 + border.width: activeFocus ? 2 : 1 + border.color: activeFocus ? control.palette.highlight : control.enabled ? control.palette.mid : control.palette.midlight + color: control.second.pressed ? control.palette.light : control.palette.window + } + + background: Rectangle { + x: control.leftPadding + (control.horizontal ? 0 : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : 0) + implicitWidth: control.horizontal ? 200 : 6 + implicitHeight: control.horizontal ? 6 : 200 + width: control.horizontal ? control.availableWidth : implicitWidth + height: control.horizontal ? implicitHeight : control.availableHeight + radius: 3 + color: control.palette.midlight + scale: control.horizontal && control.mirrored ? -1 : 1 + + Rectangle { + x: control.horizontal ? control.first.position * parent.width + 3 : 0 + y: control.horizontal ? 0 : control.second.visualPosition * parent.height + 3 + width: control.horizontal ? control.second.position * parent.width - control.first.position * parent.width - 6 : 6 + height: control.horizontal ? 6 : control.second.position * parent.height - control.first.position * parent.height - 6 + + color: control.palette.dark + } + } +} diff --git a/src/quickcontrols2/basic/RoundButton.qml b/src/quickcontrols2/basic/RoundButton.qml new file mode 100644 index 00000000000..6ab810fd9ea --- /dev/null +++ b/src/quickcontrols2/basic/RoundButton.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.RoundButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 24 + icon.height: 24 + icon.color: control.checked || control.highlighted ? control.palette.brightText : + control.flat && !control.down ? (control.visualFocus ? control.palette.highlight : control.palette.windowText) : control.palette.buttonText + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.checked || control.highlighted ? control.palette.brightText : + control.flat && !control.down ? (control.visualFocus ? control.palette.highlight : control.palette.windowText) : control.palette.buttonText + } + + background: Rectangle { + implicitWidth: 40 + implicitHeight: 40 + radius: control.radius + opacity: enabled ? 1 : 0.3 + visible: !control.flat || control.down || control.checked || control.highlighted + color: Color.blend(control.checked || control.highlighted ? control.palette.dark : control.palette.button, + control.palette.mid, control.down ? 0.5 : 0.0) + border.color: control.palette.highlight + border.width: control.visualFocus ? 2 : 0 + } +} diff --git a/src/quickcontrols2/basic/ScrollBar.qml b/src/quickcontrols2/basic/ScrollBar.qml new file mode 100644 index 00000000000..f3c06ef1fc1 --- /dev/null +++ b/src/quickcontrols2/basic/ScrollBar.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ScrollBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 2 + visible: control.policy !== T.ScrollBar.AlwaysOff + minimumSize: orientation === Qt.Horizontal ? height / width : width / height + + contentItem: Rectangle { + implicitWidth: control.interactive ? 6 : 2 + implicitHeight: control.interactive ? 6 : 2 + + radius: width / 2 + color: control.pressed ? control.palette.dark : control.palette.mid + opacity: 0.0 + + states: State { + name: "active" + when: control.policy === T.ScrollBar.AlwaysOn || (control.active && control.size < 1.0) + PropertyChanges { target: control.contentItem; opacity: 0.75 } + } + + transitions: Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 450 } + NumberAnimation { target: control.contentItem; duration: 200; property: "opacity"; to: 0.0 } + } + } + } +} diff --git a/src/quickcontrols2/basic/ScrollIndicator.qml b/src/quickcontrols2/basic/ScrollIndicator.qml new file mode 100644 index 00000000000..dcb23d65366 --- /dev/null +++ b/src/quickcontrols2/basic/ScrollIndicator.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ScrollIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 2 + + contentItem: Rectangle { + implicitWidth: 2 + implicitHeight: 2 + + color: control.palette.mid + visible: control.size < 1.0 + opacity: 0.0 + + states: State { + name: "active" + when: control.active + PropertyChanges { target: control.contentItem; opacity: 0.75 } + } + + transitions: [ + Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 450 } + NumberAnimation { target: control.contentItem; duration: 200; property: "opacity"; to: 0.0 } + } + } + ] + } +} diff --git a/src/quickcontrols2/basic/ScrollView.qml b/src/quickcontrols2/basic/ScrollView.qml new file mode 100644 index 00000000000..43c4e428c62 --- /dev/null +++ b/src/quickcontrols2/basic/ScrollView.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ScrollView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + ScrollBar.vertical: ScrollBar { + parent: control + x: control.mirrored ? 0 : control.width - width + y: control.topPadding + height: control.availableHeight + active: control.ScrollBar.horizontal.active + } + + ScrollBar.horizontal: ScrollBar { + parent: control + x: control.leftPadding + y: control.height - height + width: control.availableWidth + active: control.ScrollBar.vertical.active + } +} diff --git a/src/quickcontrols2/basic/SelectionRectangle.qml b/src/quickcontrols2/basic/SelectionRectangle.qml new file mode 100644 index 00000000000..060fb909d88 --- /dev/null +++ b/src/quickcontrols2/basic/SelectionRectangle.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Shapes +import QtQuick.Templates as T + +T.SelectionRectangle { + id: control + + topLeftHandle: Handle {} + bottomRightHandle: Handle {} + + component Handle : Rectangle { + id: handle + width: 28 + height: width + radius: width / 2 + color: SelectionRectangle.dragging ? control.palette.light : control.palette.window + border.width: 1 + border.color: control.enabled ? control.palette.mid : control.palette.midlight + visible: SelectionRectangle.control.active + + property Item control: SelectionRectangle.control + } + +} diff --git a/src/quickcontrols2/basic/Slider.qml b/src/quickcontrols2/basic/Slider.qml new file mode 100644 index 00000000000..425f4975fd4 --- /dev/null +++ b/src/quickcontrols2/basic/Slider.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.Slider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitHandleWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitHandleHeight + topPadding + bottomPadding) + + padding: 6 + + handle: Rectangle { + x: control.leftPadding + (control.horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) + implicitWidth: 28 + implicitHeight: 28 + radius: width / 2 + color: control.pressed ? control.palette.light : control.palette.window + border.width: control.visualFocus ? 2 : 1 + border.color: control.visualFocus ? control.palette.highlight : control.enabled ? control.palette.mid : control.palette.midlight + } + + background: Rectangle { + x: control.leftPadding + (control.horizontal ? 0 : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : 0) + implicitWidth: control.horizontal ? 200 : 6 + implicitHeight: control.horizontal ? 6 : 200 + width: control.horizontal ? control.availableWidth : implicitWidth + height: control.horizontal ? implicitHeight : control.availableHeight + radius: 3 + color: control.palette.midlight + scale: control.horizontal && control.mirrored ? -1 : 1 + + Rectangle { + y: control.horizontal ? 0 : control.visualPosition * parent.height + width: control.horizontal ? control.position * parent.width : 6 + height: control.horizontal ? 6 : control.position * parent.height + + radius: 3 + color: control.palette.dark + } + } +} diff --git a/src/quickcontrols2/basic/SpinBox.qml b/src/quickcontrols2/basic/SpinBox.qml new file mode 100644 index 00000000000..f992e7c9bad --- /dev/null +++ b/src/quickcontrols2/basic/SpinBox.qml @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.SpinBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentItem.implicitWidth + 2 * padding + + up.implicitIndicatorWidth + + down.implicitIndicatorWidth) + implicitHeight: Math.max(implicitContentHeight + topPadding + bottomPadding, + implicitBackgroundHeight, + up.implicitIndicatorHeight, + down.implicitIndicatorHeight) + + padding: 6 + leftPadding: padding + (control.mirrored ? (up.indicator ? up.indicator.width : 0) : (down.indicator ? down.indicator.width : 0)) + rightPadding: padding + (control.mirrored ? (down.indicator ? down.indicator.width : 0) : (up.indicator ? up.indicator.width : 0)) + + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + + contentItem: TextInput { + z: 2 + text: control.displayText + + font: control.font + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + + readOnly: !control.editable + validator: control.validator + inputMethodHints: control.inputMethodHints + + Rectangle { + x: -6 - (control.down.indicator ? 1 : 0) + y: -6 + width: control.width - (control.up.indicator ? control.up.indicator.width - 1 : 0) - (control.down.indicator ? control.down.indicator.width - 1 : 0) + height: control.height + visible: control.activeFocus + color: "transparent" + border.color: control.palette.highlight + border.width: 2 + } + } + + up.indicator: Rectangle { + x: control.mirrored ? 0 : control.width - width + height: control.height + implicitWidth: 40 + implicitHeight: 40 + color: control.up.pressed ? control.palette.mid : control.palette.button + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: parent.width / 3 + height: 2 + color: enabled ? control.palette.buttonText : control.palette.mid + } + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 2 + height: parent.width / 3 + color: enabled ? control.palette.buttonText : control.palette.mid + } + } + + down.indicator: Rectangle { + x: control.mirrored ? parent.width - width : 0 + height: control.height + implicitWidth: 40 + implicitHeight: 40 + color: control.down.pressed ? control.palette.mid : control.palette.button + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: parent.width / 3 + height: 2 + color: enabled ? control.palette.buttonText : control.palette.mid + } + } + + background: Rectangle { + implicitWidth: 140 + color: enabled ? control.palette.base : control.palette.button + border.color: control.palette.button + } +} diff --git a/src/quickcontrols2/basic/SplitView.qml b/src/quickcontrols2/basic/SplitView.qml new file mode 100644 index 00000000000..66d24743ebc --- /dev/null +++ b/src/quickcontrols2/basic/SplitView.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl + +T.SplitView { + id: control + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + handle: Rectangle { + implicitWidth: control.orientation === Qt.Horizontal ? 6 : control.width + implicitHeight: control.orientation === Qt.Horizontal ? control.height : 6 + color: T.SplitHandle.pressed ? control.palette.mid + : (T.SplitHandle.hovered ? control.palette.midlight : control.palette.button) + } +} diff --git a/src/quickcontrols2/basic/StackView.qml b/src/quickcontrols2/basic/StackView.qml new file mode 100644 index 00000000000..cbf13f36371 --- /dev/null +++ b/src/quickcontrols2/basic/StackView.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.StackView { + id: control + + popEnter: Transition { + XAnimator { from: (control.mirrored ? -1 : 1) * -control.width; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + + popExit: Transition { + XAnimator { from: 0; to: (control.mirrored ? -1 : 1) * control.width; duration: 400; easing.type: Easing.OutCubic } + } + + pushEnter: Transition { + XAnimator { from: (control.mirrored ? -1 : 1) * control.width; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + + pushExit: Transition { + XAnimator { from: 0; to: (control.mirrored ? -1 : 1) * -control.width; duration: 400; easing.type: Easing.OutCubic } + } + + replaceEnter: Transition { + XAnimator { from: (control.mirrored ? -1 : 1) * control.width; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + + replaceExit: Transition { + XAnimator { from: 0; to: (control.mirrored ? -1 : 1) * -control.width; duration: 400; easing.type: Easing.OutCubic } + } +} diff --git a/src/quickcontrols2/basic/SwipeDelegate.qml b/src/quickcontrols2/basic/SwipeDelegate.qml new file mode 100644 index 00000000000..f8209a1ea0c --- /dev/null +++ b/src/quickcontrols2/basic/SwipeDelegate.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.SwipeDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 12 + spacing: 12 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.text + + swipe.transition: Transition { SmoothedAnimation { velocity: 3; easing.type: Easing.InOutCubic } } + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.palette.text + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: Color.blend(control.down ? control.palette.midlight : control.palette.light, + control.palette.highlight, control.visualFocus ? 0.15 : 0.0) + } +} diff --git a/src/quickcontrols2/basic/SwipeView.qml b/src/quickcontrols2/basic/SwipeView.qml new file mode 100644 index 00000000000..6ce4ee6ca27 --- /dev/null +++ b/src/quickcontrols2/basic/SwipeView.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwipeView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + contentItem: ListView { + model: control.contentModel + interactive: control.interactive + currentIndex: control.currentIndex + focus: control.focus + + spacing: control.spacing + orientation: control.orientation + snapMode: ListView.SnapOneItem + boundsBehavior: Flickable.StopAtBounds + + highlightRangeMode: ListView.StrictlyEnforceRange + preferredHighlightBegin: 0 + preferredHighlightEnd: 0 + highlightMoveDuration: 250 + maximumFlickVelocity: 4 * (control.orientation === Qt.Horizontal ? width : height) + } +} diff --git a/src/quickcontrols2/basic/Switch.qml b/src/quickcontrols2/basic/Switch.qml new file mode 100644 index 00000000000..0d919f9e974 --- /dev/null +++ b/src/quickcontrols2/basic/Switch.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl + +T.Switch { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + indicator: PaddedRectangle { + implicitWidth: 56 + implicitHeight: 28 + + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + radius: 8 + leftPadding: 0 + rightPadding: 0 + padding: (height - 16) / 2 + color: control.checked ? control.palette.dark : control.palette.midlight + + Rectangle { + x: Math.max(0, Math.min(parent.width - width, control.visualPosition * parent.width - (width / 2))) + y: (parent.height - height) / 2 + width: 28 + height: 28 + radius: 16 + color: control.down ? control.palette.light : control.palette.window + border.width: control.visualFocus ? 2 : 1 + border.color: control.visualFocus ? control.palette.highlight : control.enabled ? control.palette.mid : control.palette.midlight + + Behavior on x { + enabled: !control.down + SmoothedAnimation { velocity: 200 } + } + } + } + + contentItem: CheckLabel { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.palette.windowText + } +} diff --git a/src/quickcontrols2/basic/SwitchDelegate.qml b/src/quickcontrols2/basic/SwitchDelegate.qml new file mode 100644 index 00000000000..8203e107c12 --- /dev/null +++ b/src/quickcontrols2/basic/SwitchDelegate.qml @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl + +T.SwitchDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 12 + spacing: 12 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.text + + indicator: PaddedRectangle { + implicitWidth: 56 + implicitHeight: 28 + + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + radius: 8 + leftPadding: 0 + rightPadding: 0 + padding: (height - 16) / 2 + color: control.checked ? control.palette.dark : control.palette.midlight + + Rectangle { + x: Math.max(0, Math.min(parent.width - width, control.visualPosition * parent.width - (width / 2))) + y: (parent.height - height) / 2 + width: 28 + height: 28 + radius: 16 + color: control.down ? control.palette.light : control.palette.window + border.width: control.visualFocus ? 2 : 1 + border.color: control.visualFocus ? control.palette.highlight : control.enabled ? control.palette.mid : control.palette.midlight + + Behavior on x { + enabled: !control.down + SmoothedAnimation { velocity: 200 } + } + } + } + + contentItem: IconLabel { + leftPadding: control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: !control.mirrored ? control.indicator.width + control.spacing : 0 + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.palette.text + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + visible: control.down || control.highlighted + color: control.down ? control.palette.midlight : control.palette.light + } +} diff --git a/src/quickcontrols2/basic/TabBar.qml b/src/quickcontrols2/basic/TabBar.qml new file mode 100644 index 00000000000..f1b11ac297b --- /dev/null +++ b/src/quickcontrols2/basic/TabBar.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TabBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: 1 + + contentItem: ListView { + model: control.contentModel + currentIndex: control.currentIndex + + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + flickableDirection: Flickable.AutoFlickIfNeeded + snapMode: ListView.SnapToItem + + highlightMoveDuration: 0 + highlightRangeMode: ListView.ApplyRange + preferredHighlightBegin: 40 + preferredHighlightEnd: width - 40 + } + + background: Rectangle { + color: control.palette.window + } +} diff --git a/src/quickcontrols2/basic/TabButton.qml b/src/quickcontrols2/basic/TabButton.qml new file mode 100644 index 00000000000..5e38f69c5f7 --- /dev/null +++ b/src/quickcontrols2/basic/TabButton.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.TabButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 24 + icon.height: 24 + icon.color: checked ? control.palette.windowText : control.palette.brightText + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.checked ? control.palette.windowText : control.palette.brightText + } + + background: Rectangle { + implicitHeight: 40 + color: Color.blend(control.checked ? control.palette.window : control.palette.dark, + control.palette.mid, control.down ? 0.5 : 0.0) + } +} diff --git a/src/quickcontrols2/basic/TextArea.qml b/src/quickcontrols2/basic/TextArea.qml new file mode 100644 index 00000000000..99d73362d4e --- /dev/null +++ b/src/quickcontrols2/basic/TextArea.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.TextArea { + id: control + + implicitWidth: Math.max(contentWidth + leftPadding + rightPadding, + implicitBackgroundWidth + leftInset + rightInset, + placeholder.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(contentHeight + topPadding + bottomPadding, + implicitBackgroundHeight + topInset + bottomInset, + placeholder.implicitHeight + topPadding + bottomPadding) + + padding: 6 + leftPadding: padding + 4 + + color: control.palette.text + placeholderTextColor: control.palette.placeholderText + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + verticalAlignment: control.verticalAlignment + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + elide: Text.ElideRight + renderType: control.renderType + } +} diff --git a/src/quickcontrols2/basic/TextField.qml b/src/quickcontrols2/basic/TextField.qml new file mode 100644 index 00000000000..2833916eda3 --- /dev/null +++ b/src/quickcontrols2/basic/TextField.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.TextField { + id: control + + implicitWidth: implicitBackgroundWidth + leftInset + rightInset + || Math.max(contentWidth, placeholder.implicitWidth) + leftPadding + rightPadding + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding, + placeholder.implicitHeight + topPadding + bottomPadding) + + padding: 6 + leftPadding: padding + 4 + + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + placeholderTextColor: control.palette.placeholderText + verticalAlignment: TextInput.AlignVCenter + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + verticalAlignment: control.verticalAlignment + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + elide: Text.ElideRight + renderType: control.renderType + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 40 + border.width: control.activeFocus ? 2 : 1 + color: control.palette.base + border.color: control.activeFocus ? control.palette.highlight : control.palette.mid + } +} diff --git a/src/quickcontrols2/basic/ToolBar.qml b/src/quickcontrols2/basic/ToolBar.qml new file mode 100644 index 00000000000..1d21c51d099 --- /dev/null +++ b/src/quickcontrols2/basic/ToolBar.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ToolBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + background: Rectangle { + implicitHeight: 40 + color: control.palette.button + } +} diff --git a/src/quickcontrols2/basic/ToolButton.qml b/src/quickcontrols2/basic/ToolButton.qml new file mode 100644 index 00000000000..8a4f8097be7 --- /dev/null +++ b/src/quickcontrols2/basic/ToolButton.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ToolButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 24 + icon.height: 24 + icon.color: visualFocus ? control.palette.highlight : control.palette.buttonText + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.visualFocus ? control.palette.highlight : control.palette.buttonText + } + + background: Rectangle { + implicitWidth: 40 + implicitHeight: 40 + + opacity: control.down ? 1.0 : 0.5 + color: control.down || control.checked || control.highlighted ? control.palette.mid : control.palette.button + } +} diff --git a/src/quickcontrols2/basic/ToolSeparator.qml b/src/quickcontrols2/basic/ToolSeparator.qml new file mode 100644 index 00000000000..e35aca0af1f --- /dev/null +++ b/src/quickcontrols2/basic/ToolSeparator.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ToolSeparator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: vertical ? 6 : 2 + verticalPadding: vertical ? 2 : 6 + + contentItem: Rectangle { + implicitWidth: control.vertical ? 1 : 30 + implicitHeight: control.vertical ? 30 : 1 + color: control.palette.mid + } +} diff --git a/src/quickcontrols2/basic/ToolTip.qml b/src/quickcontrols2/basic/ToolTip.qml new file mode 100644 index 00000000000..9d10f7fa4bb --- /dev/null +++ b/src/quickcontrols2/basic/ToolTip.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ToolTip { + id: control + + x: parent ? (parent.width - implicitWidth) / 2 : 0 + y: -implicitHeight - 3 + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + margins: 6 + padding: 6 + + closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnReleaseOutsideParent + + contentItem: Text { + text: control.text + font: control.font + wrapMode: Text.Wrap + color: control.palette.toolTipText + } + + background: Rectangle { + border.color: control.palette.dark + color: control.palette.toolTipBase + } +} diff --git a/src/quickcontrols2/basic/Tumbler.qml b/src/quickcontrols2/basic/Tumbler.qml new file mode 100644 index 00000000000..e687783785b --- /dev/null +++ b/src/quickcontrols2/basic/Tumbler.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.Tumbler { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + delegate: Text { + text: modelData + color: control.visualFocus ? control.palette.highlight : control.palette.text + font: control.font + opacity: 1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2) + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + // We use required property here to satisfy qmllint, but that means + // we also need to declare the index for the attached properties + // (see QQuickTumblerAttachedPrivate::init). + required property var modelData + required property int index + } + + contentItem: TumblerView { + implicitWidth: 60 + implicitHeight: 200 + model: control.model + delegate: control.delegate + path: Path { + startX: control.contentItem.width / 2 + startY: -control.contentItem.delegateHeight / 2 + PathLine { + x: control.contentItem.width / 2 + y: (control.visibleItemCount + 1) * control.contentItem.delegateHeight - control.contentItem.delegateHeight / 2 + } + } + + property real delegateHeight: control.availableHeight / control.visibleItemCount + } +} diff --git a/src/quickcontrols2/basic/VerticalHeaderView.qml b/src/quickcontrols2/basic/VerticalHeaderView.qml new file mode 100644 index 00000000000..7c057e01e24 --- /dev/null +++ b/src/quickcontrols2/basic/VerticalHeaderView.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.VerticalHeaderView { + id: control + + implicitWidth: contentWidth + implicitHeight: syncView ? syncView.height : 0 + + delegate: Rectangle { + // Qt6: add cellPadding (and font etc) as public API in headerview + readonly property real cellPadding: 8 + + implicitWidth: Math.max(control.width, text.implicitWidth + (cellPadding * 2)) + implicitHeight: text.implicitHeight + (cellPadding * 2) + color: "#f6f6f6" + border.color: "#e4e4e4" + + Text { + id: text + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] + : model[control.textRole]) + : modelData + width: parent.width + height: parent.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: "#ff26282a" + } + } +} diff --git a/src/quickcontrols2/basic/basic.pri b/src/quickcontrols2/basic/basic.pri new file mode 100644 index 00000000000..dcea52c73f9 --- /dev/null +++ b/src/quickcontrols2/basic/basic.pri @@ -0,0 +1,67 @@ +HEADERS += \ + $$PWD/qquickbasicstyle_p.h \ + $$PWD/qquickbasictheme_p.h + +SOURCES += \ + $$PWD/qquickbasicstyle.cpp \ + $$PWD/qquickbasictheme.cpp + +QML_FILES += \ + $$PWD/AbstractButton.qml \ + $$PWD/Action.qml \ + $$PWD/ActionGroup.qml \ + $$PWD/ApplicationWindow.qml \ + $$PWD/BusyIndicator.qml \ + $$PWD/Button.qml \ + $$PWD/ButtonGroup.qml \ + $$PWD/CheckBox.qml \ + $$PWD/CheckDelegate.qml \ + $$PWD/ComboBox.qml \ + $$PWD/Container.qml \ + $$PWD/Control.qml \ + $$PWD/DelayButton.qml \ + $$PWD/Dial.qml \ + $$PWD/Dialog.qml \ + $$PWD/DialogButtonBox.qml \ + $$PWD/Drawer.qml \ + $$PWD/Frame.qml \ + $$PWD/GroupBox.qml \ + $$PWD/HorizontalHeaderView.qml \ + $$PWD/ItemDelegate.qml \ + $$PWD/Label.qml \ + $$PWD/Menu.qml \ + $$PWD/MenuBar.qml \ + $$PWD/MenuBarItem.qml \ + $$PWD/MenuItem.qml \ + $$PWD/MenuSeparator.qml \ + $$PWD/Page.qml \ + $$PWD/PageIndicator.qml \ + $$PWD/Pane.qml \ + $$PWD/Popup.qml \ + $$PWD/ProgressBar.qml \ + $$PWD/RadioButton.qml \ + $$PWD/RadioDelegate.qml \ + $$PWD/RangeSlider.qml \ + $$PWD/RoundButton.qml \ + $$PWD/ScrollBar.qml \ + $$PWD/ScrollIndicator.qml \ + $$PWD/ScrollView.qml \ + $$PWD/SelectionRectangle.qml \ + $$PWD/Slider.qml \ + $$PWD/SpinBox.qml \ + $$PWD/SplitView.qml \ + $$PWD/StackView.qml \ + $$PWD/SwipeDelegate.qml \ + $$PWD/Switch.qml \ + $$PWD/SwitchDelegate.qml \ + $$PWD/SwipeView.qml \ + $$PWD/TabBar.qml \ + $$PWD/TabButton.qml \ + $$PWD/TextArea.qml \ + $$PWD/TextField.qml \ + $$PWD/ToolBar.qml \ + $$PWD/ToolButton.qml \ + $$PWD/ToolSeparator.qml \ + $$PWD/ToolTip.qml \ + $$PWD/Tumbler.qml \ + $$PWD/VerticalHeaderView.qml diff --git a/src/quickcontrols2/basic/images/arrow-indicator.png b/src/quickcontrols2/basic/images/arrow-indicator.png new file mode 100644 index 00000000000..d833d52c40a Binary files /dev/null and b/src/quickcontrols2/basic/images/arrow-indicator.png differ diff --git a/src/quickcontrols2/basic/images/arrow-indicator@2x.png b/src/quickcontrols2/basic/images/arrow-indicator@2x.png new file mode 100644 index 00000000000..55c7940a51b Binary files /dev/null and b/src/quickcontrols2/basic/images/arrow-indicator@2x.png differ diff --git a/src/quickcontrols2/basic/images/arrow-indicator@3x.png b/src/quickcontrols2/basic/images/arrow-indicator@3x.png new file mode 100644 index 00000000000..c7067c5cd0b Binary files /dev/null and b/src/quickcontrols2/basic/images/arrow-indicator@3x.png differ diff --git a/src/quickcontrols2/basic/images/arrow-indicator@4x.png b/src/quickcontrols2/basic/images/arrow-indicator@4x.png new file mode 100644 index 00000000000..4c5cf3515a1 Binary files /dev/null and b/src/quickcontrols2/basic/images/arrow-indicator@4x.png differ diff --git a/src/quickcontrols2/basic/images/check.png b/src/quickcontrols2/basic/images/check.png new file mode 100644 index 00000000000..479a84428da Binary files /dev/null and b/src/quickcontrols2/basic/images/check.png differ diff --git a/src/quickcontrols2/basic/images/check@2x.png b/src/quickcontrols2/basic/images/check@2x.png new file mode 100644 index 00000000000..79663c0b039 Binary files /dev/null and b/src/quickcontrols2/basic/images/check@2x.png differ diff --git a/src/quickcontrols2/basic/images/check@3x.png b/src/quickcontrols2/basic/images/check@3x.png new file mode 100644 index 00000000000..fd0135abe26 Binary files /dev/null and b/src/quickcontrols2/basic/images/check@3x.png differ diff --git a/src/quickcontrols2/basic/images/check@4x.png b/src/quickcontrols2/basic/images/check@4x.png new file mode 100644 index 00000000000..e7e0b64044d Binary files /dev/null and b/src/quickcontrols2/basic/images/check@4x.png differ diff --git a/src/quickcontrols2/basic/images/dial-indicator.png b/src/quickcontrols2/basic/images/dial-indicator.png new file mode 100644 index 00000000000..92357c51d40 Binary files /dev/null and b/src/quickcontrols2/basic/images/dial-indicator.png differ diff --git a/src/quickcontrols2/basic/images/dial-indicator@2x.png b/src/quickcontrols2/basic/images/dial-indicator@2x.png new file mode 100644 index 00000000000..f436443b0a2 Binary files /dev/null and b/src/quickcontrols2/basic/images/dial-indicator@2x.png differ diff --git a/src/quickcontrols2/basic/images/dial-indicator@3x.png b/src/quickcontrols2/basic/images/dial-indicator@3x.png new file mode 100644 index 00000000000..d883045bcb0 Binary files /dev/null and b/src/quickcontrols2/basic/images/dial-indicator@3x.png differ diff --git a/src/quickcontrols2/basic/images/dial-indicator@4x.png b/src/quickcontrols2/basic/images/dial-indicator@4x.png new file mode 100644 index 00000000000..794777128b5 Binary files /dev/null and b/src/quickcontrols2/basic/images/dial-indicator@4x.png differ diff --git a/src/quickcontrols2/basic/images/double-arrow.png b/src/quickcontrols2/basic/images/double-arrow.png new file mode 100644 index 00000000000..3ecd7f89f3d Binary files /dev/null and b/src/quickcontrols2/basic/images/double-arrow.png differ diff --git a/src/quickcontrols2/basic/images/double-arrow@2x.png b/src/quickcontrols2/basic/images/double-arrow@2x.png new file mode 100644 index 00000000000..eeb03e28471 Binary files /dev/null and b/src/quickcontrols2/basic/images/double-arrow@2x.png differ diff --git a/src/quickcontrols2/basic/images/double-arrow@3x.png b/src/quickcontrols2/basic/images/double-arrow@3x.png new file mode 100644 index 00000000000..f0662d20260 Binary files /dev/null and b/src/quickcontrols2/basic/images/double-arrow@3x.png differ diff --git a/src/quickcontrols2/basic/images/double-arrow@4x.png b/src/quickcontrols2/basic/images/double-arrow@4x.png new file mode 100644 index 00000000000..10891e91338 Binary files /dev/null and b/src/quickcontrols2/basic/images/double-arrow@4x.png differ diff --git a/src/quickcontrols2/basic/images/drop-indicator.png b/src/quickcontrols2/basic/images/drop-indicator.png new file mode 100644 index 00000000000..80c1d958e31 Binary files /dev/null and b/src/quickcontrols2/basic/images/drop-indicator.png differ diff --git a/src/quickcontrols2/basic/images/drop-indicator@2x.png b/src/quickcontrols2/basic/images/drop-indicator@2x.png new file mode 100644 index 00000000000..6e0f228c54c Binary files /dev/null and b/src/quickcontrols2/basic/images/drop-indicator@2x.png differ diff --git a/src/quickcontrols2/basic/images/drop-indicator@3x.png b/src/quickcontrols2/basic/images/drop-indicator@3x.png new file mode 100644 index 00000000000..199752fbf8c Binary files /dev/null and b/src/quickcontrols2/basic/images/drop-indicator@3x.png differ diff --git a/src/quickcontrols2/basic/images/drop-indicator@4x.png b/src/quickcontrols2/basic/images/drop-indicator@4x.png new file mode 100644 index 00000000000..58311fbe2aa Binary files /dev/null and b/src/quickcontrols2/basic/images/drop-indicator@4x.png differ diff --git a/src/quickcontrols2/basic/impl/CMakeLists.txt b/src/quickcontrols2/basic/impl/CMakeLists.txt new file mode 100644 index 00000000000..2b937ae2868 --- /dev/null +++ b/src/quickcontrols2/basic/impl/CMakeLists.txt @@ -0,0 +1,25 @@ +##################################################################### +## qtquickcontrols2basicstyleimplplugin Plugin: +##################################################################### + +qt_internal_add_qml_module(qtquickcontrols2basicstyleimplplugin + URI "QtQuick.Controls.Basic.impl" + VERSION "${PROJECT_VERSION}" + CLASS_NAME QtQuickControls2BasicStyleImplPlugin + PLUGIN_TARGET qtquickcontrols2basicstyleimplplugin + NO_PLUGIN_OPTIONAL + SOURCES + qquickbasicbusyindicator.cpp qquickbasicbusyindicator_p.h + qquickbasicdial.cpp qquickbasicdial_p.h + qquickbasicprogressbar.cpp qquickbasicprogressbar_p.h + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::QmlPrivate + Qt::QuickControls2ImplPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private +) diff --git a/src/quickcontrols2/basic/impl/qquickbasicbusyindicator.cpp b/src/quickcontrols2/basic/impl/qquickbasicbusyindicator.cpp new file mode 100644 index 00000000000..b497f57f70f --- /dev/null +++ b/src/quickcontrols2/basic/impl/qquickbasicbusyindicator.cpp @@ -0,0 +1,225 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickbasicbusyindicator_p.h" + +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> +#include <QtQuickControls2Impl/private/qquickanimatednode_p.h> + +QT_BEGIN_NAMESPACE + +static const int CircleCount = 10; +static const int TotalDuration = 100 * CircleCount * 2; +static const QRgb TransparentColor = 0x00000000; + +static QPointF moveCircle(const QPointF &pos, qreal rotation, qreal distance) +{ + return pos - QTransform().rotate(rotation).map(QPointF(0, distance)); +} + +class QQuickBasicBusyIndicatorNode : public QQuickAnimatedNode +{ +public: + QQuickBasicBusyIndicatorNode(QQuickBasicBusyIndicator *item); + + void updateCurrentTime(int time) override; + void sync(QQuickItem *item) override; + +private: + QColor m_pen; + QColor m_fill; +}; + +QQuickBasicBusyIndicatorNode::QQuickBasicBusyIndicatorNode(QQuickBasicBusyIndicator *item) + : QQuickAnimatedNode(item) +{ + setLoopCount(Infinite); + setDuration(TotalDuration); + setCurrentTime(item->elapsed()); + + for (int i = 0; i < CircleCount; ++i) { + QSGTransformNode *transformNode = new QSGTransformNode; + appendChildNode(transformNode); + + QQuickItemPrivate *d = QQuickItemPrivate::get(item); + QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode(); + rectNode->setAntialiasing(true); + transformNode->appendChildNode(rectNode); + } +} + +void QQuickBasicBusyIndicatorNode::updateCurrentTime(int time) +{ + const qreal percentageComplete = time / qreal(TotalDuration); + const qreal firstPhaseProgress = percentageComplete <= 0.5 ? percentageComplete * 2 : 0; + const qreal secondPhaseProgress = percentageComplete > 0.5 ? (percentageComplete - 0.5) * 2 : 0; + + QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(firstChild()); + Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType); + for (int i = 0; i < CircleCount; ++i) { + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode*>(transformNode->firstChild()); + Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); + + const bool fill = (firstPhaseProgress > qreal(i) / CircleCount) || (secondPhaseProgress > 0 && secondPhaseProgress < qreal(i) / CircleCount); + rectNode->setColor(fill ? m_fill : QColor::fromRgba(TransparentColor)); + rectNode->setPenColor(m_pen); + rectNode->setPenWidth(1); + rectNode->update(); + + transformNode = static_cast<QSGTransformNode*>(transformNode->nextSibling()); + } +} + +void QQuickBasicBusyIndicatorNode::sync(QQuickItem *item) +{ + const qreal w = item->width(); + const qreal h = item->height(); + const qreal sz = qMin(w, h); + const qreal dx = (w - sz) / 2; + const qreal dy = (h - sz) / 2; + const int circleRadius = sz / 12; + + m_pen = static_cast<QQuickBasicBusyIndicator *>(item)->pen(); + m_fill = static_cast<QQuickBasicBusyIndicator *>(item)->fill(); + + QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(firstChild()); + for (int i = 0; i < CircleCount; ++i) { + Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType); + + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild()); + Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); + + QPointF pos = QPointF(sz / 2 - circleRadius, sz / 2 - circleRadius); + pos = moveCircle(pos, 360.0 / CircleCount * i, sz / 2 - circleRadius); + + QMatrix4x4 m; + m.translate(dx + pos.x(), dy + pos.y()); + transformNode->setMatrix(m); + + rectNode->setRect(QRectF(QPointF(), QSizeF(circleRadius * 2, circleRadius * 2))); + rectNode->setRadius(circleRadius); + + transformNode = static_cast<QSGTransformNode *>(transformNode->nextSibling()); + } +} + +QQuickBasicBusyIndicator::QQuickBasicBusyIndicator(QQuickItem *parent) : + QQuickItem(parent) +{ + setFlag(ItemHasContents); +} + +QColor QQuickBasicBusyIndicator::pen() const +{ + return m_pen; +} + +void QQuickBasicBusyIndicator::setPen(const QColor &pen) +{ + if (pen == m_pen) + return; + + m_pen = pen; + update(); +} + +QColor QQuickBasicBusyIndicator::fill() const +{ + return m_fill; +} + +void QQuickBasicBusyIndicator::setFill(const QColor &fill) +{ + if (fill == m_fill) + return; + + m_fill = fill; + update(); +} + +bool QQuickBasicBusyIndicator::isRunning() const +{ + return isVisible(); +} + +void QQuickBasicBusyIndicator::setRunning(bool running) +{ + if (running) + setVisible(true); +} + +int QQuickBasicBusyIndicator::elapsed() const +{ + return m_elapsed; +} + +void QQuickBasicBusyIndicator::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + switch (change) { + case ItemOpacityHasChanged: + if (qFuzzyIsNull(data.realValue)) + setVisible(false); + break; + case ItemVisibleHasChanged: + update(); + break; + default: + break; + } +} + +QSGNode *QQuickBasicBusyIndicator::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) +{ + QQuickBasicBusyIndicatorNode *node = static_cast<QQuickBasicBusyIndicatorNode *>(oldNode); + if (isRunning() && width() > 0 && height() > 0) { + if (!node) { + node = new QQuickBasicBusyIndicatorNode(this); + node->start(); + } + node->sync(this); + } else { + m_elapsed = node ? node->currentTime() : 0; + delete node; + node = nullptr; + } + return node; +} + +QT_END_NAMESPACE + +#include "moc_qquickbasicbusyindicator_p.cpp" diff --git a/src/quickcontrols2/basic/impl/qquickbasicbusyindicator_p.h b/src/quickcontrols2/basic/impl/qquickbasicbusyindicator_p.h new file mode 100644 index 00000000000..7eea6656750 --- /dev/null +++ b/src/quickcontrols2/basic/impl/qquickbasicbusyindicator_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDEFAULTBUSYINDICATOR_P_H +#define QQUICKDEFAULTBUSYINDICATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtGui/qcolor.h> + +QT_BEGIN_NAMESPACE + +class QQuickBasicBusyIndicator : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QColor pen READ pen WRITE setPen FINAL) + Q_PROPERTY(QColor fill READ fill WRITE setFill FINAL) + Q_PROPERTY(bool running READ isRunning WRITE setRunning) + QML_NAMED_ELEMENT(BusyIndicatorImpl) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickBasicBusyIndicator(QQuickItem *parent = nullptr); + + QColor pen() const; + void setPen(const QColor &pen); + + QColor fill() const; + void setFill(const QColor &fill); + + bool isRunning() const; + void setRunning(bool running); + + int elapsed() const; + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override; + +private: + int m_elapsed = 0; + QColor m_pen; + QColor m_fill; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickBasicBusyIndicator) + +#endif // QQUICKDEFAULTBUSYINDICATOR_P_H diff --git a/src/quickcontrols2/basic/impl/qquickbasicdial.cpp b/src/quickcontrols2/basic/impl/qquickbasicdial.cpp new file mode 100644 index 00000000000..df6626e2e87 --- /dev/null +++ b/src/quickcontrols2/basic/impl/qquickbasicdial.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickbasicdial_p.h" + +#include <QtCore/qmath.h> +#include <QtGui/qpainter.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +QQuickBasicDial::QQuickBasicDial(QQuickItem *parent) : + QQuickPaintedItem(parent) +{ +} + +qreal QQuickBasicDial::progress() const +{ + return m_progress; +} + +void QQuickBasicDial::setProgress(qreal progress) +{ + if (progress == m_progress) + return; + + m_progress = progress; + update(); +} + +QColor QQuickBasicDial::color() const +{ + return m_color; +} + +void QQuickBasicDial::setColor(const QColor &color) +{ + if (color == m_color) + return; + + m_color = color; + update(); +} + +void QQuickBasicDial::paint(QPainter *painter) +{ + if (width() <= 0 || height() <= 0) + return; + + QPen pen(m_color); + pen.setWidth(8); + pen.setCapStyle(Qt::FlatCap); + painter->setPen(pen); + + const QRectF bounds = boundingRect(); + const qreal smallest = qMin(bounds.width(), bounds.height()); + QRectF rect = QRectF(pen.widthF() / 2.0 + 1, pen.widthF() / 2.0 + 1, smallest - pen.widthF() - 2, smallest - pen.widthF() - 2); + rect.moveCenter(bounds.center()); + + // Make sure the arc is aligned to whole pixels. + if (rect.x() - int(rect.x()) > 0) + rect.setX(qCeil(rect.x())); + if (rect.y() - int(rect.y()) > 0) + rect.setY(qCeil(rect.y())); + if (rect.width() - int(rect.width()) > 0) + rect.setWidth(qFloor(rect.width())); + if (rect.height() - int(rect.height()) > 0) + rect.setHeight(qFloor(rect.height())); + + painter->setRenderHint(QPainter::Antialiasing); + + const qreal startAngle = (140 + 90); + const qreal spanAngle = (m_progress * 280) * -1; + QPainterPath path; + path.arcMoveTo(rect, startAngle); + path.arcTo(rect, startAngle, spanAngle); + painter->drawPath(path); + + rect.adjust(-pen.widthF() / 2.0, -pen.widthF() / 2.0, pen.widthF() / 2.0, pen.widthF() / 2.0); + pen.setWidth(1); + painter->setPen(pen); + + path = QPainterPath(); + path.arcMoveTo(rect, 0); + path.arcTo(rect, 0, 360); + painter->drawPath(path); +} + +QT_END_NAMESPACE + +#include "moc_qquickbasicdial_p.cpp" diff --git a/src/quickcontrols2/basic/impl/qquickbasicdial_p.h b/src/quickcontrols2/basic/impl/qquickbasicdial_p.h new file mode 100644 index 00000000000..bd9bbb72018 --- /dev/null +++ b/src/quickcontrols2/basic/impl/qquickbasicdial_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDEFAULTDIAL_P_H +#define QQUICKDEFAULTDIAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qcolor.h> +#include <QtQuick/qquickpainteditem.h> + +QT_BEGIN_NAMESPACE + +class QQuickBasicDial : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(qreal progress READ progress WRITE setProgress FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + QML_NAMED_ELEMENT(DialImpl) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickBasicDial(QQuickItem *parent = nullptr); + + qreal progress() const; + void setProgress(qreal progress); + + QColor color() const; + void setColor(const QColor &color); + + void paint(QPainter *painter) override; + +private: + qreal m_progress = 0; + QColor m_color = Qt::black; +}; + +QT_END_NAMESPACE + +#endif // QQUICKDEFAULTDIAL_P_H diff --git a/src/quickcontrols2/basic/impl/qquickbasicprogressbar.cpp b/src/quickcontrols2/basic/impl/qquickbasicprogressbar.cpp new file mode 100644 index 00000000000..c492b1a9209 --- /dev/null +++ b/src/quickcontrols2/basic/impl/qquickbasicprogressbar.cpp @@ -0,0 +1,282 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickbasicprogressbar_p.h" + +#include <QtCore/qeasingcurve.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> +#include <QtQuickControls2Impl/private/qquickanimatednode_p.h> + +QT_BEGIN_NAMESPACE + +static const int Blocks = 4; +static const int BlockWidth = 16; +static const int BlockRestingSpacing = 4; +static const int BlockMovingSpacing = 48; +static const int BlockSpan = Blocks * (BlockWidth + BlockRestingSpacing) - BlockRestingSpacing; +static const int TotalDuration = 4000; +static const int SecondPhaseStart = TotalDuration * 0.4; +static const int ThirdPhaseStart = TotalDuration * 0.6; + +static inline qreal blockStartX(int blockIndex) +{ + return ((blockIndex + 1) * -BlockWidth) - (blockIndex * BlockMovingSpacing); +} + +static inline qreal blockRestX(int blockIndex, qreal availableWidth) +{ + const qreal spanRightEdgePos = availableWidth / 2 + BlockSpan / 2.0; + return spanRightEdgePos - (blockIndex + 1) * BlockWidth - (blockIndex * BlockRestingSpacing); +} + +static inline qreal blockEndX(int blockIndex, qreal availableWidth) +{ + return availableWidth - blockStartX(Blocks - 1 - blockIndex) - BlockWidth; +} + +class QQuickBasicProgressBarNode : public QQuickAnimatedNode +{ +public: + QQuickBasicProgressBarNode(QQuickBasicProgressBar *item); + + void updateCurrentTime(int time) override; + void sync(QQuickItem *item) override; + +private: + bool m_indeterminate = false; + qreal m_pixelsPerSecond = 0; +}; + +QQuickBasicProgressBarNode::QQuickBasicProgressBarNode(QQuickBasicProgressBar *item) + : QQuickAnimatedNode(item), + m_pixelsPerSecond(item->width()) +{ + setLoopCount(Infinite); + setDuration(TotalDuration); +} + +void QQuickBasicProgressBarNode::updateCurrentTime(int time) +{ + QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(firstChild()); + for (int i = 0; i < Blocks; ++i) { + Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType); + + QMatrix4x4 m; + const qreal restX = blockRestX(i, m_pixelsPerSecond); + const qreal timeInSeconds = time / 1000.0; + + if (time < SecondPhaseStart) { + // Move into the resting position for the first phase. + QEasingCurve easingCurve(QEasingCurve::InQuad); + const qreal easedCompletion = easingCurve.valueForProgress(time / qreal(SecondPhaseStart)); + const qreal distance = m_pixelsPerSecond * (easedCompletion * (SecondPhaseStart / 1000.0)); + const qreal position = blockStartX(i) + distance; + const qreal destination = restX; + m.translate(qMin(position, destination), 0); + } else if (time < ThirdPhaseStart) { + // Stay in the same position for the second phase. + m.translate(restX, 0); + } else { + // Move out of view for the third phase. + const int thirdPhaseSubKickoff = (BlockMovingSpacing / m_pixelsPerSecond) * 1000; + const int subphase = (time - ThirdPhaseStart) / thirdPhaseSubKickoff; + // If we're not at this subphase yet, don't try to animate movement, + // because it will be incorrect. + if (subphase < i) + return; + + const qreal timeSinceSecondPhase = timeInSeconds - (ThirdPhaseStart / 1000.0); + // We only want to start keeping track of time once our subphase has started, + // otherwise we move too much because we account for time that has already elapsed. + // For example, if we were 60 milliseconds into the third subphase: + // + // 0 ..... 1 ..... 2 ... + // 100 100 60 + // + // i == 0, timeSinceOurKickoff == 260 + // i == 1, timeSinceOurKickoff == 160 + // i == 2, timeSinceOurKickoff == 60 + const qreal timeSinceOurKickoff = timeSinceSecondPhase - (thirdPhaseSubKickoff / 1000.0 * i); + const qreal position = restX + (m_pixelsPerSecond * (timeSinceOurKickoff)); + const qreal destination = blockEndX(i, m_pixelsPerSecond); + m.translate(qMin(position, destination), 0); + } + + transformNode->setMatrix(m); + + transformNode = static_cast<QSGTransformNode*>(transformNode->nextSibling()); + } +} + +void QQuickBasicProgressBarNode::sync(QQuickItem *item) +{ + QQuickBasicProgressBar *bar = static_cast<QQuickBasicProgressBar *>(item); + if (m_indeterminate != bar->isIndeterminate()) { + m_indeterminate = bar->isIndeterminate(); + if (m_indeterminate) + start(); + else + stop(); + } + m_pixelsPerSecond = item->width(); + + QQuickItemPrivate *d = QQuickItemPrivate::get(item); + + QMatrix4x4 m; + m.translate(0, (item->height() - item->implicitHeight()) / 2); + setMatrix(m); + + if (m_indeterminate) { + if (childCount() != Blocks) { + // This was previously a regular progress bar; remove the old nodes. + removeAllChildNodes(); + } + + QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(firstChild()); + for (int i = 0; i < Blocks; ++i) { + if (!transformNode) { + transformNode = new QSGTransformNode; + appendChildNode(transformNode); + } + + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode*>(transformNode->firstChild()); + if (!rectNode) { + rectNode = d->sceneGraphContext()->createInternalRectangleNode(); + rectNode->setColor(bar->color()); + transformNode->appendChildNode(rectNode); + } + + QMatrix4x4 m; + m.translate(blockStartX(i), 0); + transformNode->setMatrix(m); + + rectNode->setRect(QRectF(QPointF(0, 0), QSizeF(BlockWidth, item->implicitHeight()))); + rectNode->update(); + + transformNode = static_cast<QSGTransformNode *>(transformNode->nextSibling()); + } + } else { + if (childCount() > 1) { + // This was previously an indeterminate progress bar; remove the old nodes. + removeAllChildNodes(); + } + + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(firstChild()); + if (!rectNode) { + rectNode = d->sceneGraphContext()->createInternalRectangleNode(); + rectNode->setColor(bar->color()); + appendChildNode(rectNode); + } + + rectNode->setRect(QRectF(QPointF(0, 0), QSizeF(bar->progress() * item->width(), item->implicitHeight()))); + rectNode->update(); + } +} + +QQuickBasicProgressBar::QQuickBasicProgressBar(QQuickItem *parent) : + QQuickItem(parent) +{ + setFlag(ItemHasContents); +} + +qreal QQuickBasicProgressBar::progress() const +{ + return m_progress; +} + +void QQuickBasicProgressBar::setProgress(qreal progress) +{ + if (progress == m_progress) + return; + + m_progress = progress; + update(); +} + +bool QQuickBasicProgressBar::isIndeterminate() const +{ + return m_indeterminate; +} + +void QQuickBasicProgressBar::setIndeterminate(bool indeterminate) +{ + if (indeterminate == m_indeterminate) + return; + + m_indeterminate = indeterminate; + setClip(m_indeterminate); + update(); +} + +QColor QQuickBasicProgressBar::color() const +{ + return m_color; +} + +void QQuickBasicProgressBar::setColor(const QColor &color) +{ + if (color == m_color) + return; + + m_color = color; + update(); +} + +void QQuickBasicProgressBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + if (change == ItemVisibleHasChanged) + update(); +} + +QSGNode *QQuickBasicProgressBar::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) +{ + QQuickBasicProgressBarNode *node = static_cast<QQuickBasicProgressBarNode *>(oldNode); + if (isVisible() && width() > 0 && height() > 0) { + if (!node) + node = new QQuickBasicProgressBarNode(this); + node->sync(this); + } else { + delete node; + node = nullptr; + } + return node; +} + +QT_END_NAMESPACE + +#include "moc_qquickbasicprogressbar_p.cpp" diff --git a/src/quickcontrols2/basic/impl/qquickbasicprogressbar_p.h b/src/quickcontrols2/basic/impl/qquickbasicprogressbar_p.h new file mode 100644 index 00000000000..1d853ecb413 --- /dev/null +++ b/src/quickcontrols2/basic/impl/qquickbasicprogressbar_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDEFAULTPROGRESSBAR_P_H +#define QQUICKDEFAULTPROGRESSBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtGui/qcolor.h> + +QT_BEGIN_NAMESPACE + +class QQuickBasicProgressBar : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate FINAL) + Q_PROPERTY(qreal progress READ progress WRITE setProgress FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + QML_NAMED_ELEMENT(ProgressBarImpl) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickBasicProgressBar(QQuickItem *parent = nullptr); + + bool isIndeterminate() const; + void setIndeterminate(bool indeterminate); + + qreal progress() const; + void setProgress(qreal progress); + + QColor color() const; + void setColor(const QColor &color); + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override; + +private: + qreal m_progress = 0; + bool m_indeterminate = false; + QColor m_color; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickBasicProgressBar) + +#endif // QQUICKDEFAULTPROGRESSBAR_P_H diff --git a/src/quickcontrols2/basic/qquickbasicstyle.cpp b/src/quickcontrols2/basic/qquickbasicstyle.cpp new file mode 100644 index 00000000000..0cf82bb01b2 --- /dev/null +++ b/src/quickcontrols2/basic/qquickbasicstyle.cpp @@ -0,0 +1,248 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickbasicstyle_p.h" + +QT_BEGIN_NAMESPACE + +QQuickBasicStyle::QQuickBasicStyle(QObject *parent) : + QObject(parent) +{ +} + +QColor QQuickBasicStyle::backgroundColor() const +{ + return QColor::fromRgba(0xFFFFFFFF); +} + +QColor QQuickBasicStyle::overlayModalColor() const +{ + return QColor::fromRgba(0x7F28282A); +} + +QColor QQuickBasicStyle::overlayDimColor() const +{ + return QColor::fromRgba(0x1F28282A); +} + +QColor QQuickBasicStyle::textColor() const +{ + return QColor::fromRgba(0xFF353637); +} + +QColor QQuickBasicStyle::textDarkColor() const +{ + return QColor::fromRgba(0xFF26282A); +} + +QColor QQuickBasicStyle::textLightColor() const +{ + return QColor::fromRgba(0xFFFFFFFF); +} + +QColor QQuickBasicStyle::textLinkColor() const +{ + return QColor::fromRgba(0xFF45A7D7); +} + +QColor QQuickBasicStyle::textSelectionColor() const +{ + return QColor::fromRgba(0xFFFDDD5C); +} + +QColor QQuickBasicStyle::textDisabledColor() const +{ + return QColor::fromRgba(0xFFBDBEBF); +} + +QColor QQuickBasicStyle::textDisabledLightColor() const +{ + return QColor::fromRgba(0xFFC2C2C2); +} + +QColor QQuickBasicStyle::textPlaceholderColor() const +{ + return QColor::fromRgba(0xFF777777); +} + +QColor QQuickBasicStyle::focusColor() const +{ + return QColor::fromRgba(0xFF0066FF); +} + +QColor QQuickBasicStyle::focusLightColor() const +{ + return QColor::fromRgba(0xFFF0F6FF); +} + +QColor QQuickBasicStyle::focusPressedColor() const +{ + return QColor::fromRgba(0xFFCCE0FF); +} + +QColor QQuickBasicStyle::buttonColor() const +{ + return QColor::fromRgba(0xFFE0E0E0); +} + +QColor QQuickBasicStyle::buttonPressedColor() const +{ + return QColor::fromRgba(0xFFD0D0D0); +} + +QColor QQuickBasicStyle::buttonCheckedColor() const +{ + return QColor::fromRgba(0xFF353637); +} + +QColor QQuickBasicStyle::buttonCheckedPressedColor() const +{ + return QColor::fromRgba(0xFF585A5C); +} + +QColor QQuickBasicStyle::buttonCheckedFocusColor() const +{ + return QColor::fromRgba(0xFF599BFF); +} + +QColor QQuickBasicStyle::toolButtonColor() const +{ + return QColor::fromRgba(0x33333333); +} + +QColor QQuickBasicStyle::tabButtonColor() const +{ + return QColor::fromRgba(0xFF353637); +} + +QColor QQuickBasicStyle::tabButtonPressedColor() const +{ + return QColor::fromRgba(0xFF585A5C); +} + +QColor QQuickBasicStyle::tabButtonCheckedPressedColor() const +{ + return QColor::fromRgba(0xFFE4E4E4); +} + +QColor QQuickBasicStyle::delegateColor() const +{ + return QColor::fromRgba(0xFFEEEEEE); +} + +QColor QQuickBasicStyle::delegatePressedColor() const +{ + return QColor::fromRgba(0xFFBDBEBF); +} + +QColor QQuickBasicStyle::delegateFocusColor() const +{ + return QColor::fromRgba(0xFFE5EFFF); +} + +QColor QQuickBasicStyle::indicatorPressedColor() const +{ + return QColor::fromRgba(0xFFF6F6F6); +} + +QColor QQuickBasicStyle::indicatorDisabledColor() const +{ + return QColor::fromRgba(0xFFFDFDFD); +} + +QColor QQuickBasicStyle::indicatorFrameColor() const +{ + return QColor::fromRgba(0xFF909090); +} + +QColor QQuickBasicStyle::indicatorFramePressedColor() const +{ + return QColor::fromRgba(0xFF808080); +} + +QColor QQuickBasicStyle::indicatorFrameDisabledColor() const +{ + return QColor::fromRgba(0xFFD6D6D6); +} + +QColor QQuickBasicStyle::frameDarkColor() const +{ + return QColor::fromRgba(0xFF353637); +} + +QColor QQuickBasicStyle::frameLightColor() const +{ + return QColor::fromRgba(0xFFBDBEBF); +} + +QColor QQuickBasicStyle::scrollBarColor() const +{ + return QColor::fromRgba(0xFFBDBEBF); +} + +QColor QQuickBasicStyle::scrollBarPressedColor() const +{ + return QColor::fromRgba(0xFF28282A); +} + +QColor QQuickBasicStyle::progressBarColor() const +{ + return QColor::fromRgba(0xFFE4E4E4); +} + +QColor QQuickBasicStyle::pageIndicatorColor() const +{ + return QColor::fromRgba(0xFF28282A); +} + +QColor QQuickBasicStyle::separatorColor() const +{ + return QColor::fromRgba(0xFFCCCCCC); +} + +QColor QQuickBasicStyle::disabledDarkColor() const +{ + return QColor::fromRgba(0xFF353637); +} + +QColor QQuickBasicStyle::disabledLightColor() const +{ + return QColor::fromRgba(0xFFBDBEBF); +} + +QT_END_NAMESPACE + +#include "moc_qquickbasicstyle_p.cpp" diff --git a/src/quickcontrols2/basic/qquickbasicstyle_p.h b/src/quickcontrols2/basic/qquickbasicstyle_p.h new file mode 100644 index 00000000000..3f3d84b8f3b --- /dev/null +++ b/src/quickcontrols2/basic/qquickbasicstyle_p.h @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKBASICSTYLE_P_H +#define QQUICKBASICSTYLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtGui/qcolor.h> +#include <QtQml/qqml.h> + +QT_BEGIN_NAMESPACE + +class QQuickBasicStyle : public QObject +{ + Q_OBJECT + Q_PROPERTY(QColor backgroundColor READ backgroundColor CONSTANT FINAL) + Q_PROPERTY(QColor overlayModalColor READ overlayModalColor CONSTANT FINAL) + Q_PROPERTY(QColor overlayDimColor READ overlayDimColor CONSTANT FINAL) + Q_PROPERTY(QColor textColor READ textColor CONSTANT FINAL) + Q_PROPERTY(QColor textDarkColor READ textDarkColor CONSTANT FINAL) + Q_PROPERTY(QColor textLightColor READ textLightColor CONSTANT FINAL) + Q_PROPERTY(QColor textLinkColor READ textLinkColor CONSTANT FINAL) + Q_PROPERTY(QColor textSelectionColor READ textSelectionColor CONSTANT FINAL) + Q_PROPERTY(QColor textDisabledColor READ textDisabledColor CONSTANT FINAL) + Q_PROPERTY(QColor textDisabledLightColor READ textDisabledLightColor CONSTANT FINAL) + Q_PROPERTY(QColor textPlaceholderColor READ textPlaceholderColor CONSTANT FINAL) + Q_PROPERTY(QColor focusColor READ focusColor CONSTANT FINAL) + Q_PROPERTY(QColor focusLightColor READ focusLightColor CONSTANT FINAL) + Q_PROPERTY(QColor focusPressedColor READ focusPressedColor CONSTANT FINAL) + Q_PROPERTY(QColor buttonColor READ buttonColor CONSTANT FINAL) + Q_PROPERTY(QColor buttonPressedColor READ buttonPressedColor CONSTANT FINAL) + Q_PROPERTY(QColor buttonCheckedColor READ buttonCheckedColor CONSTANT FINAL) + Q_PROPERTY(QColor buttonCheckedPressedColor READ buttonCheckedPressedColor CONSTANT FINAL) + Q_PROPERTY(QColor buttonCheckedFocusColor READ buttonCheckedFocusColor CONSTANT FINAL) + Q_PROPERTY(QColor toolButtonColor READ toolButtonColor CONSTANT FINAL) + Q_PROPERTY(QColor tabButtonColor READ tabButtonColor CONSTANT FINAL) + Q_PROPERTY(QColor tabButtonPressedColor READ tabButtonPressedColor CONSTANT FINAL) + Q_PROPERTY(QColor tabButtonCheckedPressedColor READ tabButtonCheckedPressedColor CONSTANT FINAL) + Q_PROPERTY(QColor delegateColor READ delegateColor CONSTANT FINAL) + Q_PROPERTY(QColor delegatePressedColor READ delegatePressedColor CONSTANT FINAL) + Q_PROPERTY(QColor delegateFocusColor READ delegateFocusColor CONSTANT FINAL) + Q_PROPERTY(QColor indicatorPressedColor READ indicatorPressedColor CONSTANT FINAL) + Q_PROPERTY(QColor indicatorDisabledColor READ indicatorDisabledColor CONSTANT FINAL) + Q_PROPERTY(QColor indicatorFrameColor READ indicatorFrameColor CONSTANT FINAL) + Q_PROPERTY(QColor indicatorFramePressedColor READ indicatorFramePressedColor CONSTANT FINAL) + Q_PROPERTY(QColor indicatorFrameDisabledColor READ indicatorFrameDisabledColor CONSTANT FINAL) + Q_PROPERTY(QColor frameDarkColor READ frameDarkColor CONSTANT FINAL) + Q_PROPERTY(QColor frameLightColor READ frameLightColor CONSTANT FINAL) + Q_PROPERTY(QColor scrollBarColor READ scrollBarColor CONSTANT FINAL) + Q_PROPERTY(QColor scrollBarPressedColor READ scrollBarPressedColor CONSTANT FINAL) + Q_PROPERTY(QColor progressBarColor READ progressBarColor CONSTANT FINAL) + Q_PROPERTY(QColor pageIndicatorColor READ pageIndicatorColor CONSTANT FINAL) + Q_PROPERTY(QColor separatorColor READ separatorColor CONSTANT FINAL) + Q_PROPERTY(QColor disabledDarkColor READ disabledDarkColor CONSTANT FINAL) + Q_PROPERTY(QColor disabledLightColor READ disabledLightColor CONSTANT FINAL) + QML_NAMED_ELEMENT(Basic) + QML_SINGLETON + QML_ADDED_IN_VERSION(2, 1) + +public: + explicit QQuickBasicStyle(QObject *parent = nullptr); + + QColor backgroundColor() const; + QColor overlayModalColor() const; + QColor overlayDimColor() const; + QColor textColor() const; + QColor textDarkColor() const; + QColor textLightColor() const; + QColor textLinkColor() const; + QColor textSelectionColor() const; + QColor textDisabledColor() const; + QColor textDisabledLightColor() const; + QColor textPlaceholderColor() const; + QColor focusColor() const; + QColor focusLightColor() const; + QColor focusPressedColor() const; + QColor buttonColor() const; + QColor buttonPressedColor() const; + QColor buttonCheckedColor() const; + QColor buttonCheckedPressedColor() const; + QColor buttonCheckedFocusColor() const; + QColor toolButtonColor() const; + QColor tabButtonColor() const; + QColor tabButtonPressedColor() const; + QColor tabButtonCheckedPressedColor() const; + QColor delegateColor() const; + QColor delegatePressedColor() const; + QColor delegateFocusColor() const; + QColor indicatorPressedColor() const; + QColor indicatorDisabledColor() const; + QColor indicatorFrameColor() const; + QColor indicatorFramePressedColor() const; + QColor indicatorFrameDisabledColor() const; + QColor frameDarkColor() const; + QColor frameLightColor() const; + QColor scrollBarColor() const; + QColor scrollBarPressedColor() const; + QColor progressBarColor() const; + QColor pageIndicatorColor() const; + QColor separatorColor() const; + QColor disabledDarkColor() const; + QColor disabledLightColor() const; +}; + +QT_END_NAMESPACE + +#endif // QQUICKBASICSTYLE_P_H diff --git a/src/quickcontrols2/basic/qquickbasictheme.cpp b/src/quickcontrols2/basic/qquickbasictheme.cpp new file mode 100644 index 00000000000..c65a7bc1c47 --- /dev/null +++ b/src/quickcontrols2/basic/qquickbasictheme.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickbasictheme_p.h" + +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +QT_BEGIN_NAMESPACE + +void QQuickBasicTheme::initialize(QQuickTheme *theme) +{ + QPalette systemPalette; + + systemPalette.setColor(QPalette::Base, QColor::fromRgba(0xFFFFFFFF)); + systemPalette.setColor(QPalette::Disabled, QPalette::Base, QColor::fromRgba(0xFFD6D6D6)); + + systemPalette.setColor(QPalette::Button, QColor::fromRgba(0xFFE0E0E0)); + + systemPalette.setColor(QPalette::ButtonText, QColor::fromRgba(0xFF26282A)); + systemPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor::fromRgba(0x4D26282A)); + + systemPalette.setColor(QPalette::BrightText, QColor::fromRgba(0xFFFFFFFF)); + systemPalette.setColor(QPalette::Disabled, QPalette::BrightText, QColor::fromRgba(0x4DFFFFFF)); + + systemPalette.setColor(QPalette::Dark, QColor::fromRgba(0xFF353637)); + + systemPalette.setColor(QPalette::Highlight, QColor::fromRgba(0xFF0066FF)); + systemPalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor::fromRgba(0xFFF0F6FF)); + + systemPalette.setColor(QPalette::HighlightedText, QColor::fromRgba(0xFF090909)); + + systemPalette.setColor(QPalette::Light, QColor::fromRgba(0xFFF6F6F6)); + + systemPalette.setColor(QPalette::Link, QColor::fromRgba(0xFF45A7D7)); + + systemPalette.setColor(QPalette::Mid, QColor::fromRgba(0xFFBDBDBD)); + + systemPalette.setColor(QPalette::Midlight, QColor::fromRgba(0xFFE4E4E4)); + + systemPalette.setColor(QPalette::Text, QColor::fromRgba(0xFF353637)); + systemPalette.setColor(QPalette::Disabled, QPalette::Text, QColor::fromRgba(0x7F353637)); + + systemPalette.setColor(QPalette::Shadow, QColor::fromRgba(0xFF28282A)); + + systemPalette.setColor(QPalette::ToolTipBase, QColor::fromRgba(0xFFFFFFFF)); + systemPalette.setColor(QPalette::ToolTipText, QColor::fromRgba(0xFF000000)); + + systemPalette.setColor(QPalette::Window, QColor::fromRgba(0xFFFFFFFF)); + + systemPalette.setColor(QPalette::WindowText, QColor::fromRgba(0xFF26282A)); + systemPalette.setColor(QPalette::Disabled, QPalette::WindowText, QColor::fromRgba(0xFFBDBEBF)); + + systemPalette.setColor(QPalette::PlaceholderText, QColor::fromRgba(0x88353637)); + + theme->setPalette(QQuickTheme::System, systemPalette); +} + +QT_END_NAMESPACE diff --git a/src/quickcontrols2/basic/qquickbasictheme_p.h b/src/quickcontrols2/basic/qquickbasictheme_p.h new file mode 100644 index 00000000000..a0a299535af --- /dev/null +++ b/src/quickcontrols2/basic/qquickbasictheme_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKBASICTHEME_P_H +#define QQUICKBASICTHEME_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +class QQuickTheme; + +class QQuickBasicTheme +{ +public: + static void initialize(QQuickTheme *theme); +}; + +QT_END_NAMESPACE + +#endif // QQUICKBASICTHEME_P_H diff --git a/src/quickcontrols2/basic/qtquickcontrols2basicstyleplugin.cpp b/src/quickcontrols2/basic/qtquickcontrols2basicstyleplugin.cpp new file mode 100644 index 00000000000..ff7c3a5d636 --- /dev/null +++ b/src/quickcontrols2/basic/qtquickcontrols2basicstyleplugin.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickbasicstyle_p.h" +#include "qquickbasictheme_p.h" + +#include <QtQuickControls2/private/qquickstyleplugin_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +extern void qml_register_types_QtQuick_Controls_Basic(); +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Controls_Basic); + +QT_BEGIN_NAMESPACE + +class QtQuickControls2BasicStylePlugin: public QQuickStylePlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtQuickControls2BasicStylePlugin(QObject *parent = nullptr); + + QString name() const override; + void initializeTheme(QQuickTheme *theme) override; + + QQuickBasicTheme theme; +}; + +QtQuickControls2BasicStylePlugin::QtQuickControls2BasicStylePlugin(QObject *parent) : QQuickStylePlugin(parent) +{ + volatile auto registration = &qml_register_types_QtQuick_Controls_Basic; + Q_UNUSED(registration); +} + +QString QtQuickControls2BasicStylePlugin::name() const +{ + return QStringLiteral("Basic"); +} + +void QtQuickControls2BasicStylePlugin::initializeTheme(QQuickTheme *theme) +{ + this->theme.initialize(theme); +} + +QT_END_NAMESPACE + +#include "qtquickcontrols2basicstyleplugin.moc" diff --git a/src/quickcontrols2/basic/qtquickcontrols2basicstyleplugin.qrc b/src/quickcontrols2/basic/qtquickcontrols2basicstyleplugin.qrc new file mode 100644 index 00000000000..27fd6ac2d45 --- /dev/null +++ b/src/quickcontrols2/basic/qtquickcontrols2basicstyleplugin.qrc @@ -0,0 +1,24 @@ +<RCC> + <qresource prefix="/qt-project.org/imports/QtQuick/Controls/Basic"> + <file>images/arrow-indicator.png</file> + <file>images/arrow-indicator@2x.png</file> + <file>images/arrow-indicator@3x.png</file> + <file>images/arrow-indicator@4x.png</file> + <file>images/check.png</file> + <file>images/check@2x.png</file> + <file>images/check@3x.png</file> + <file>images/check@4x.png</file> + <file>images/dial-indicator.png</file> + <file>images/dial-indicator@2x.png</file> + <file>images/dial-indicator@3x.png</file> + <file>images/dial-indicator@4x.png</file> + <file>images/drop-indicator.png</file> + <file>images/drop-indicator@2x.png</file> + <file>images/drop-indicator@3x.png</file> + <file>images/drop-indicator@4x.png</file> + <file>images/double-arrow.png</file> + <file>images/double-arrow@2x.png</file> + <file>images/double-arrow@3x.png</file> + <file>images/double-arrow@4x.png</file> + </qresource> +</RCC> diff --git a/src/quickcontrols2/configure.cmake b/src/quickcontrols2/configure.cmake new file mode 100644 index 00000000000..f996cf2884f --- /dev/null +++ b/src/quickcontrols2/configure.cmake @@ -0,0 +1,62 @@ + + +#### Inputs + + + +#### Libraries + + + +#### Tests + + + +#### Features + +qt_feature("quickcontrols2-basic" PRIVATE + LABEL "Basic" +) +qt_feature("quickcontrols2-fusion" PRIVATE + SECTION "Quick Controls 2" + LABEL "Fusion" + PURPOSE "Provides the platform agnostic desktop-oriented Fusion style." + CONDITION QT_FEATURE_quickcontrols2_basic +) +qt_feature("quickcontrols2-imagine" PRIVATE + SECTION "Quick Controls 2" + LABEL "Imagine" + PURPOSE "Provides a style based on configurable image assets." + CONDITION QT_FEATURE_quickcontrols2_basic +) +qt_feature("quickcontrols2-material" PRIVATE + SECTION "Quick Controls 2" + LABEL "Material" + PURPOSE "Provides a style based on the Material Design guidelines." + CONDITION QT_FEATURE_quickcontrols2_basic +) +qt_feature("quickcontrols2-universal" PRIVATE + SECTION "Quick Controls 2" + LABEL "Universal" + PURPOSE "Provides a style based on the Universal Design guidelines." + CONDITION QT_FEATURE_quickcontrols2_basic +) +qt_feature("quickcontrols2-macos" PRIVATE + SECTION "Quick Controls 2" + LABEL "macOS" + PURPOSE "Provides a native macOS desktop style." + CONDITION QT_FEATURE_quickcontrols2_basic +) +qt_feature("quickcontrols2-windows" PRIVATE + SECTION "Quick Controls 2" + LABEL "Windows" + PURPOSE "Provides a native Windows desktop style." + CONDITION QT_FEATURE_quickcontrols2_basic +) +qt_configure_add_summary_section(NAME "Qt Quick Controls 2") +qt_configure_add_summary_entry( + TYPE "featureList" + ARGS "quickcontrols2-basic quickcontrols2-fusion quickcontrols2-imagine quickcontrols2-material quickcontrols2-universal quickcontrols2-macos quickcontrols2-windows" + MESSAGE "Styles" +) +qt_configure_end_summary_section() # end of "Qt Quick Controls 2" section diff --git a/src/quickcontrols2/designer/AbstractButtonSection.qml b/src/quickcontrols2/designer/AbstractButtonSection.qml new file mode 100644 index 00000000000..2ccb82312b1 --- /dev/null +++ b/src/quickcontrols2/designer/AbstractButtonSection.qml @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Section { + caption: qsTr("AbstractButton") + + SectionLayout { + Label { + text: qsTr("Text") + tooltip: qsTr("The text displayed on the button.") + } + SecondColumnLayout { + LineEdit { + backendValue: backendValues.text + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Display") + tooltip: qsTr("Determines how the icon and text are displayed within the button.") + disabledState: !backendValues.display.isAvailable + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.display + model: [ "IconOnly", "TextOnly", "TextBesideIcon" ] + scope: "AbstractButton" + Layout.fillWidth: true + enabled: backendValue.isAvailable + } + } + + Label { + visible: checkable + text: qsTr("Checkable") + tooltip: qsTr("Whether the button is checkable.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.checkable.valueToString + backendValue: backendValues.checkable + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Checked") + tooltip: qsTr("Whether the button is checked.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.checked.valueToString + backendValue: backendValues.checked + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Exclusive") + tooltip: qsTr("Whether the button is exclusive.") + disabledState: !backendValues.autoExclusive.isAvailable + } + SecondColumnLayout { + CheckBox { + text: backendValues.autoExclusive.valueToString + backendValue: backendValues.autoExclusive + Layout.fillWidth: true + enabled: backendValue.isAvailable + } + } + + Label { + text: qsTr("Auto-Repeat") + tooltip: qsTr("Whether the button repeats pressed(), released() and clicked() signals while the button is pressed and held down.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.autoRepeat.valueToString + backendValue: backendValues.autoRepeat + Layout.fillWidth: true + } + } + } +} diff --git a/src/quickcontrols2/designer/BusyIndicatorSpecifics.qml b/src/quickcontrols2/designer/BusyIndicatorSpecifics.qml new file mode 100644 index 00000000000..7b2899d3049 --- /dev/null +++ b/src/quickcontrols2/designer/BusyIndicatorSpecifics.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("BusyIndicator") + + SectionLayout { + Label { + text: qsTr("Running") + tooltip: qsTr("Whether the busy indicator is currently indicating activity.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.running.valueToString + backendValue: backendValues.running + Layout.fillWidth: true + } + } + } + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/ButtonSection.qml b/src/quickcontrols2/designer/ButtonSection.qml new file mode 100644 index 00000000000..ff70d52c6f4 --- /dev/null +++ b/src/quickcontrols2/designer/ButtonSection.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Section { + id: section + caption: qsTr("Button") + + SectionLayout { + + Label { + text: qsTr("Flat") + tooltip: qsTr("Whether the button is flat.") + disabledState: !backendValues.flat.isAvailable + } + SecondColumnLayout { + CheckBox { + text: backendValues.flat.valueToString + backendValue: backendValues.flat + Layout.fillWidth: true + enabled: backendValue.isAvailable + } + } + Label { + text: qsTr("Highlighted") + tooltip: qsTr("Whether the button is highlighted.") + disabledState: !backendValues.highlighted.isAvailable + } + SecondColumnLayout { + CheckBox { + text: backendValues.highlighted.valueToString + backendValue: backendValues.highlighted + Layout.fillWidth: true + enabled: backendValue.isAvailable + } + } + } +} diff --git a/src/quickcontrols2/designer/ButtonSpecifics.qml b/src/quickcontrols2/designer/ButtonSpecifics.qml new file mode 100644 index 00000000000..5a46e72aff1 --- /dev/null +++ b/src/quickcontrols2/designer/ButtonSpecifics.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + ButtonSection { + width: parent.width + } + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/CMakeLists.txt b/src/quickcontrols2/designer/CMakeLists.txt new file mode 100644 index 00000000000..a62461ed755 --- /dev/null +++ b/src/quickcontrols2/designer/CMakeLists.txt @@ -0,0 +1,61 @@ +file(GLOB_RECURSE __aux_qml_glob_files + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + "images/*.png" +) +qt_path_join(images_destination ${QT_INSTALL_DIR} "${INSTALL_QMLDIR}/QtQuick/Controls/designer/images") +qt_copy_or_install( + FILES + ${__aux_qml_glob_files} + DESTINATION "${images_destination}" +) +qt_path_join(destination ${QT_INSTALL_DIR} "${INSTALL_QMLDIR}/QtQuick/Controls/designer") +qt_copy_or_install( + FILES + AbstractButtonSection.qml + BusyIndicatorSpecifics.qml + ButtonSection.qml + ButtonSpecifics.qml + CheckBoxSpecifics.qml + CheckDelegateSpecifics.qml + CheckSection.qml + ComboBoxSpecifics.qml + ContainerSection.qml + ControlSection.qml + ControlSpecifics.qml + DelayButtonSpecifics.qml + DialSpecifics.qml + FrameSpecifics.qml + GroupBoxSpecifics.qml + InsetSection.qml + ItemDelegateSection.qml + ItemDelegateSpecifics.qml + LabelSpecifics.qml + PaddingSection.qml + PageIndicatorSpecifics.qml + PageSpecifics.qml + PaneSection.qml + PaneSpecifics.qml + ProgressBarSpecifics.qml + RadioButtonSpecifics.qml + RadioDelegateSpecifics.qml + RangeSliderSpecifics.qml + RoundButtonSpecifics.qml + ScrollViewSpecifics.qml + SliderSpecifics.qml + SpinBoxSpecifics.qml + StackViewSpecifics.qml + SwipeDelegateSpecifics.qml + SwipeViewSpecifics.qml + SwitchDelegateSpecifics.qml + SwitchSpecifics.qml + TabBarSpecifics.qml + TabButtonSpecifics.qml + TextAreaSpecifics.qml + TextFieldSpecifics.qml + ToolBarSpecifics.qml + ToolButtonSpecifics.qml + ToolSeparatorSpecifics.qml + TumblerSpecifics.qml + qtquickcontrols2.metainfo + DESTINATION "${destination}" +) diff --git a/src/quickcontrols2/designer/CheckBoxSpecifics.qml b/src/quickcontrols2/designer/CheckBoxSpecifics.qml new file mode 100644 index 00000000000..d3aae9b679d --- /dev/null +++ b/src/quickcontrols2/designer/CheckBoxSpecifics.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + CheckSection { + width: parent.width + caption: qsTr("CheckBox") + } + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/CheckDelegateSpecifics.qml b/src/quickcontrols2/designer/CheckDelegateSpecifics.qml new file mode 100644 index 00000000000..8014480cd52 --- /dev/null +++ b/src/quickcontrols2/designer/CheckDelegateSpecifics.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + CheckSection { + width: parent.width + caption: qsTr("CheckDelegate") + } + + ItemDelegateSection { + width: parent.width + } + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/CheckSection.qml b/src/quickcontrols2/designer/CheckSection.qml new file mode 100644 index 00000000000..0f49fa25afd --- /dev/null +++ b/src/quickcontrols2/designer/CheckSection.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Section { + SectionLayout { + Label { + text: qsTr("Check State") + tooltip: qsTr("The current check state.") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.checkState + model: [ "Unchecked", "PartiallyChecked", "Checked" ] + scope: "Qt" + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Tri-state") + tooltip: qsTr("Whether the checkbox has three states.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.tristate.valueToString + backendValue: backendValues.tristate + Layout.fillWidth: true + } + } + } +} diff --git a/src/quickcontrols2/designer/ComboBoxSpecifics.qml b/src/quickcontrols2/designer/ComboBoxSpecifics.qml new file mode 100644 index 00000000000..810f19b5ff1 --- /dev/null +++ b/src/quickcontrols2/designer/ComboBoxSpecifics.qml @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("ComboBox") + + SectionLayout { + Label { + text: qsTr("Text Role") + tooltip: qsTr("The model role used for displaying text.") + } + SecondColumnLayout { + LineEdit { + backendValue: backendValues.textRole + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Current") + tooltip: qsTr("The index of the current item.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.currentIndex + Layout.fillWidth: true + } + } + Label { + text: qsTr("Editable") + tooltip: qsTr("Whether the combo box is editable.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.editable.valueToString + backendValue: backendValues.editable + Layout.fillWidth: true + } + } + Label { + text: qsTr("Flat") + tooltip: qsTr("Whether the combo box button is flat.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.flat.valueToString + backendValue: backendValues.flat + Layout.fillWidth: true + } + } + Label { + text: qsTr("DisplayText") + tooltip: qsTr("Holds the text that is displayed on the combo box button.") + } + SecondColumnLayout { + LineEdit { + backendValue: backendValues.displayText + Layout.fillWidth: true + } + } + } + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/ContainerSection.qml b/src/quickcontrols2/designer/ContainerSection.qml new file mode 100644 index 00000000000..15d1ddf598b --- /dev/null +++ b/src/quickcontrols2/designer/ContainerSection.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Section { + caption: qsTr("Container") + + SectionLayout { + Label { + text: qsTr("Current") + tooltip: qsTr("The index of the current item.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.currentIndex + Layout.fillWidth: true + } + } + } +} diff --git a/src/quickcontrols2/designer/ControlSection.qml b/src/quickcontrols2/designer/ControlSection.qml new file mode 100644 index 00000000000..12033eeaa34 --- /dev/null +++ b/src/quickcontrols2/designer/ControlSection.qml @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Section { + caption: qsTr("Control") + + SectionLayout { + Label { + text: qsTr("Enabled") + tooltip: qsTr("Whether the control is enabled.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.enabled.valueToString + backendValue: backendValues.enabled + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Focus Policy") + tooltip: qsTr("Focus policy of the control.") + disabledState: !backendValues.focusPolicy.isAvailable + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.focusPolicy + model: [ "TabFocus", "ClickFocus", "StrongFocus", "WheelFocus", "NoFocus" ] + scope: "Qt" + Layout.fillWidth: true + enabled: backendValue.isAvailable + } + } + + Label { + text: qsTr("Hover") + tooltip: qsTr("Whether control accepts hover events.") + disabledState: !backendValues.hoverEnabled.isAvailable + } + SecondColumnLayout { + CheckBox { + text: backendValues.hoverEnabled.valueToString + backendValue: backendValues.hoverEnabled + Layout.fillWidth: true + enabled: backendValue.isAvailable + } + } + + Label { + text: qsTr("Spacing") + tooltip: qsTr("Spacing between internal elements of the control.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.spacing + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Wheel") + tooltip: qsTr("Whether control accepts wheel events.") + disabledState: !backendValues.wheelEnabled.isAvailable + } + SecondColumnLayout { + CheckBox { + text: backendValues.wheelEnabled.valueToString + backendValue: backendValues.wheelEnabled + Layout.fillWidth: true + enabled: backendValue.isAvailable + } + } + } +} diff --git a/src/quickcontrols2/designer/ControlSpecifics.qml b/src/quickcontrols2/designer/ControlSpecifics.qml new file mode 100644 index 00000000000..3937437b5ed --- /dev/null +++ b/src/quickcontrols2/designer/ControlSpecifics.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/DelayButtonSpecifics.qml b/src/quickcontrols2/designer/DelayButtonSpecifics.qml new file mode 100644 index 00000000000..024fe589d71 --- /dev/null +++ b/src/quickcontrols2/designer/DelayButtonSpecifics.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("DelayButton") + + SectionLayout { + Label { + text: qsTr("Delay") + tooltip: qsTr("The delay in milliseconds.") + } + SecondColumnLayout { + SpinBox { + minimumValue: 0 + maximumValue: 9999999 + decimals: 0 + stepSize: 1 + backendValue: backendValues.delay + Layout.fillWidth: true + } + } + } + } + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/DialSpecifics.qml b/src/quickcontrols2/designer/DialSpecifics.qml new file mode 100644 index 00000000000..026cb2b1b02 --- /dev/null +++ b/src/quickcontrols2/designer/DialSpecifics.qml @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("Dial") + + SectionLayout { + Label { + text: qsTr("Value") + tooltip: qsTr("The current value of the dial.") + } + SecondColumnLayout { + SpinBox { + minimumValue: Math.min(backendValues.from.value, backendValues.to.value) + maximumValue: Math.max(backendValues.from.value, backendValues.to.value) + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.value + Layout.fillWidth: true + } + } + + Label { + text: qsTr("From") + tooltip: qsTr("The starting value of the dial range.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.from + Layout.fillWidth: true + } + } + + Label { + text: qsTr("To") + tooltip: qsTr("The ending value of the dial range.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.to + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Step Size") + tooltip: qsTr("The step size of the dial.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.stepSize + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Snap Mode") + tooltip: qsTr("The snap mode of the dial.") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.snapMode + model: [ "NoSnap", "SnapOnRelease", "SnapAlways" ] + scope: "Dial" + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Live") + tooltip: qsTr("Whether the dial provides live value updates.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.live.valueToString + backendValue: backendValues.live + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Input Mode") + tooltip: qsTr("How the dial tracks movement.") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.inputMode + model: [ "Circular", "Horizontal", "Vertical" ] + scope: "Dial" + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Wrap") + tooltip: qsTr("Whether the dial wraps when dragged.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.wrap.valueToString + backendValue: backendValues.wrap + Layout.fillWidth: true + } + } + } + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/FrameSpecifics.qml b/src/quickcontrols2/designer/FrameSpecifics.qml new file mode 100644 index 00000000000..36739956596 --- /dev/null +++ b/src/quickcontrols2/designer/FrameSpecifics.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + PaneSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/GroupBoxSpecifics.qml b/src/quickcontrols2/designer/GroupBoxSpecifics.qml new file mode 100644 index 00000000000..f808b00103b --- /dev/null +++ b/src/quickcontrols2/designer/GroupBoxSpecifics.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("GroupBox") + + SectionLayout { + Label { + text: qsTr("Title") + tooltip: qsTr("The title of the group box.") + } + SecondColumnLayout { + LineEdit { + backendValue: backendValues.title + Layout.fillWidth: true + } + } + } + } + + PaneSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/InsetSection.qml b/src/quickcontrols2/designer/InsetSection.qml new file mode 100644 index 00000000000..45a4df4fcc8 --- /dev/null +++ b/src/quickcontrols2/designer/InsetSection.qml @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Section { + caption: qsTr("Inset") + + SectionLayout { + Label { + text: qsTr("Vertical") + } + SecondColumnLayout { + Label { + text: qsTr("Top") + tooltip: qsTr("Top inset for the background.") + width: 42 + } + SpinBox { + maximumValue: 10000 + minimumValue: -10000 + realDragRange: 5000 + decimals: 0 + backendValue: backendValues.topInset + Layout.fillWidth: true + } + Item { + width: 4 + height: 4 + } + + Label { + text: qsTr("Bottom") + tooltip: qsTr("Bottom inset for the background.") + width: 42 + } + SpinBox { + maximumValue: 10000 + minimumValue: -10000 + realDragRange: 5000 + decimals: 0 + backendValue: backendValues.bottomInset + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Horizontal") + } + SecondColumnLayout { + Label { + text: qsTr("Left") + tooltip: qsTr("Left inset for the background.") + width: 42 + } + SpinBox { + maximumValue: 10000 + minimumValue: -10000 + realDragRange: 5000 + decimals: 0 + backendValue: backendValues.leftInset + Layout.fillWidth: true + } + Item { + width: 4 + height: 4 + } + + Label { + text: qsTr("Right") + tooltip: qsTr("Right inset for the background.") + width: 42 + } + SpinBox { + maximumValue: 10000 + minimumValue: -10000 + realDragRange: 5000 + decimals: 0 + backendValue: backendValues.rightInset + Layout.fillWidth: true + } + } + } +} diff --git a/src/quickcontrols2/designer/ItemDelegateSection.qml b/src/quickcontrols2/designer/ItemDelegateSection.qml new file mode 100644 index 00000000000..448a20d99d9 --- /dev/null +++ b/src/quickcontrols2/designer/ItemDelegateSection.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Section { + id: section + caption: qsTr("ItemDelegate") + + SectionLayout { + Label { + text: qsTr("Highlighted") + tooltip: qsTr("Whether the delegate is highlighted.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.highlighted.valueToString + backendValue: backendValues.highlighted + Layout.fillWidth: true + } + } + } +} diff --git a/src/quickcontrols2/designer/ItemDelegateSpecifics.qml b/src/quickcontrols2/designer/ItemDelegateSpecifics.qml new file mode 100644 index 00000000000..1757521dd8b --- /dev/null +++ b/src/quickcontrols2/designer/ItemDelegateSpecifics.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + ItemDelegateSection { + width: parent.width + } + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/LabelSpecifics.qml b/src/quickcontrols2/designer/LabelSpecifics.qml new file mode 100644 index 00000000000..569b44c8da7 --- /dev/null +++ b/src/quickcontrols2/designer/LabelSpecifics.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + StandardTextSection { + width: parent.width + showIsWrapping: true + showFormatProperty: true + showVerticalAlignment: true + } + + Section { + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr("Text Color") + + ColorEditor { + caption: qsTr("Text Color") + backendValue: backendValues.color + supportGradient: false + } + } + + Section { + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr("Style Color") + + ColorEditor { + caption: qsTr("Style Color") + backendValue: backendValues.styleColor + supportGradient: false + } + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } + + InsetSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/PaddingSection.qml b/src/quickcontrols2/designer/PaddingSection.qml new file mode 100644 index 00000000000..325c5698e00 --- /dev/null +++ b/src/quickcontrols2/designer/PaddingSection.qml @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Section { + caption: qsTr("Padding") + + SectionLayout { + Label { + text: qsTr("Top") + tooltip: qsTr("Padding between the content and the top edge of the control.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.topPadding + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Left") + tooltip: qsTr("Padding between the content and the left edge of the control.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.leftPadding + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Right") + tooltip: qsTr("Padding between the content and the right edge of the control.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.rightPadding + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Bottom") + tooltip: qsTr("Padding between the content and the bottom edge of the control.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.bottomPadding + Layout.fillWidth: true + } + } + } +} diff --git a/src/quickcontrols2/designer/PageIndicatorSpecifics.qml b/src/quickcontrols2/designer/PageIndicatorSpecifics.qml new file mode 100644 index 00000000000..c73652e951d --- /dev/null +++ b/src/quickcontrols2/designer/PageIndicatorSpecifics.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("PageIndicator") + + SectionLayout { + Label { + text: qsTr("Count") + tooltip: qsTr("The number of pages.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.count + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Current") + tooltip: qsTr("The index of the current page.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.currentIndex + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Interactive") + tooltip: qsTr("Whether the control is interactive.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.interactive.valueToString + backendValue: backendValues.interactive + Layout.fillWidth: true + } + } + } + } + + ControlSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/PageSpecifics.qml b/src/quickcontrols2/designer/PageSpecifics.qml new file mode 100644 index 00000000000..965ed655e78 --- /dev/null +++ b/src/quickcontrols2/designer/PageSpecifics.qml @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("Page") + + SectionLayout { + Label { + text: qsTr("Title") + tooltip: qsTr("Title of the page.") + } + SecondColumnLayout { + LineEdit { + backendValue: backendValues.title + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Content Width") + tooltip: qsTr("Content height used for calculating the total implicit width.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.contentWidth + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Content Height") + tooltip: qsTr("Content height used for calculating the total implicit height.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.contentHeight + Layout.fillWidth: true + } + } + } + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/PaneSection.qml b/src/quickcontrols2/designer/PaneSection.qml new file mode 100644 index 00000000000..9dcc2097a93 --- /dev/null +++ b/src/quickcontrols2/designer/PaneSection.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Section { + caption: qsTr("Pane") + + SectionLayout { + Label { + text: qsTr("Content Width") + tooltip: qsTr("Content height used for calculating the total implicit width.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.contentWidth + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Content Height") + tooltip: qsTr("Content height used for calculating the total implicit height.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.contentHeight + Layout.fillWidth: true + } + } + } +} diff --git a/src/quickcontrols2/designer/PaneSpecifics.qml b/src/quickcontrols2/designer/PaneSpecifics.qml new file mode 100644 index 00000000000..36739956596 --- /dev/null +++ b/src/quickcontrols2/designer/PaneSpecifics.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + PaneSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/ProgressBarSpecifics.qml b/src/quickcontrols2/designer/ProgressBarSpecifics.qml new file mode 100644 index 00000000000..14f879255c6 --- /dev/null +++ b/src/quickcontrols2/designer/ProgressBarSpecifics.qml @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("ProgressBar") + + SectionLayout { + Label { + text: qsTr("Indeterminate") + tooltip: qsTr("Whether the progress is indeterminate.") + disabledState: !backendValues.indeterminate.isAvailable + } + SecondColumnLayout { + CheckBox { + text: backendValues.indeterminate.valueToString + backendValue: backendValues.indeterminate + Layout.fillWidth: true + enabled: backendValue.isAvailable + } + } + + Label { + text: qsTr("Value") + tooltip: qsTr("The current value of the progress.") + } + SecondColumnLayout { + SpinBox { + minimumValue: Math.min(backendValues.from.value, backendValues.to.value) + maximumValue: Math.max(backendValues.from.value, backendValues.to.value) + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.value + Layout.fillWidth: true + } + } + + Label { + text: qsTr("From") + tooltip: qsTr("The starting value for the progress.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.from + Layout.fillWidth: true + } + } + + Label { + text: qsTr("To") + tooltip: qsTr("The ending value for the progress.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.to + Layout.fillWidth: true + } + } + } + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/RadioButtonSpecifics.qml b/src/quickcontrols2/designer/RadioButtonSpecifics.qml new file mode 100644 index 00000000000..df0af7e748d --- /dev/null +++ b/src/quickcontrols2/designer/RadioButtonSpecifics.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/RadioDelegateSpecifics.qml b/src/quickcontrols2/designer/RadioDelegateSpecifics.qml new file mode 100644 index 00000000000..1757521dd8b --- /dev/null +++ b/src/quickcontrols2/designer/RadioDelegateSpecifics.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + ItemDelegateSection { + width: parent.width + } + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/RangeSliderSpecifics.qml b/src/quickcontrols2/designer/RangeSliderSpecifics.qml new file mode 100644 index 00000000000..577033ed80c --- /dev/null +++ b/src/quickcontrols2/designer/RangeSliderSpecifics.qml @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("RangeSlider") + + SectionLayout { + Label { + text: qsTr("First Value") + tooltip: qsTr("The value of the first range slider handle.") + } + SecondColumnLayout { + SpinBox { + minimumValue: Math.min(backendValues.from.value, backendValues.to.value) + maximumValue: Math.max(backendValues.from.value, backendValues.to.value) + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.first_value + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Second Value") + tooltip: qsTr("The value of the second range slider handle.") + } + SecondColumnLayout { + SpinBox { + minimumValue: Math.min(backendValues.from.value, backendValues.to.value) + maximumValue: Math.max(backendValues.from.value, backendValues.to.value) + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.second_value + Layout.fillWidth: true + } + } + + Label { + text: qsTr("From") + tooltip: qsTr("The starting value of the range slider range.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.from + Layout.fillWidth: true + } + } + + Label { + text: qsTr("To") + tooltip: qsTr("The ending value of the range slider range.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.to + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Step Size") + tooltip: qsTr("The step size of the range slider.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.stepSize + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Snap Mode") + tooltip: qsTr("The snap mode of the range slider.") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.snapMode + model: [ "NoSnap", "SnapOnRelease", "SnapAlways" ] + scope: "RangeSlider" + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Orientation") + tooltip: qsTr("The orientation of the range slider.") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.orientation + model: [ "Horizontal", "Vertical" ] + scope: "Qt" + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Live") + tooltip: qsTr("Whether the range slider provides live value updates.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.live.valueToString + backendValue: backendValues.live + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Touch drag threshold") + tooltip: qsTr("The threshold (in logical pixels) at which a touch drag event will be initiated.") + } + SecondColumnLayout { + SpinBox { + minimumValue: 0 + maximumValue: 10000 + decimals: 0 + backendValue: backendValues.touchDragThreshold + Layout.fillWidth: true + } + } + } + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/RoundButtonSpecifics.qml b/src/quickcontrols2/designer/RoundButtonSpecifics.qml new file mode 100644 index 00000000000..58d34689527 --- /dev/null +++ b/src/quickcontrols2/designer/RoundButtonSpecifics.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("RoundButton") + + SectionLayout { + Label { + text: qsTr("Radius") + tooltip: qsTr("Radius of the button.") + } + SecondColumnLayout { + SpinBox { + minimumValue: 0 + maximumValue: 10000 + decimals: 0 + backendValue: backendValues.radius + Layout.fillWidth: true + } + } + } + } + + ButtonSection { + width: parent.width + } + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/ScrollViewSpecifics.qml b/src/quickcontrols2/designer/ScrollViewSpecifics.qml new file mode 100644 index 00000000000..ae525b747c8 --- /dev/null +++ b/src/quickcontrols2/designer/ScrollViewSpecifics.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("ScrollView") + + SectionLayout { + Label { + text: qsTr("Content Width") + tooltip: qsTr("Content height used for calculating the total implicit width.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.contentWidth + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Content Height") + tooltip: qsTr("Content height used for calculating the total implicit height.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.contentHeight + Layout.fillWidth: true + } + } + } + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/SliderSpecifics.qml b/src/quickcontrols2/designer/SliderSpecifics.qml new file mode 100644 index 00000000000..3af2054025f --- /dev/null +++ b/src/quickcontrols2/designer/SliderSpecifics.qml @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("Slider") + + SectionLayout { + Label { + text: qsTr("Value") + tooltip: qsTr("The current value of the slider.") + } + SecondColumnLayout { + SpinBox { + minimumValue: Math.min(backendValues.from.value, backendValues.to.value) + maximumValue: Math.max(backendValues.from.value, backendValues.to.value) + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.value + Layout.fillWidth: true + } + } + + Label { + text: qsTr("From") + tooltip: qsTr("The starting value of the slider range.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.from + Layout.fillWidth: true + } + } + + Label { + text: qsTr("To") + tooltip: qsTr("The ending value of the slider range.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.to + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Step Size") + tooltip: qsTr("The step size of the slider.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + stepSize: 0.1 + backendValue: backendValues.stepSize + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Snap Mode") + tooltip: qsTr("The snap mode of the slider.") + disabledState: !backendValues.snapMode.isAvailable + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.snapMode + model: [ "NoSnap", "SnapOnRelease", "SnapAlways" ] + scope: "Slider" + Layout.fillWidth: true + enabled: backendValue.isAvailable + } + } + + Label { + text: qsTr("Orientation") + tooltip: qsTr("The orientation of the slider.") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.orientation + model: [ "Horizontal", "Vertical" ] + scope: "Qt" + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Live") + tooltip: qsTr("Whether the slider provides live value updates.") + disabledState: !backendValues.live.isAvailable + } + SecondColumnLayout { + CheckBox { + text: backendValues.live.valueToString + backendValue: backendValues.live + Layout.fillWidth: true + enabled: backendValue.isAvailable + } + } + + Label { + text: qsTr("Touch drag threshold") + tooltip: qsTr("The threshold (in logical pixels) at which a touch drag event will be initiated.") + disabledState: !backendValues.touchDragThreshold.isAvailable + } + SecondColumnLayout { + SpinBox { + minimumValue: 0 + maximumValue: 10000 + decimals: 0 + backendValue: backendValues.touchDragThreshold + Layout.fillWidth: true + enabled: backendValue.isAvailable + } + } + } + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/SpinBoxSpecifics.qml b/src/quickcontrols2/designer/SpinBoxSpecifics.qml new file mode 100644 index 00000000000..9c07e8c524a --- /dev/null +++ b/src/quickcontrols2/designer/SpinBoxSpecifics.qml @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("SpinBox") + + SectionLayout { + Label { + text: qsTr("Value") + tooltip: qsTr("The current value of the spinbox.") + } + SecondColumnLayout { + SpinBox { + minimumValue: Math.min(backendValues.from.value, backendValues.to.value) + maximumValue: Math.max(backendValues.from.value, backendValues.to.value) + decimals: 2 + backendValue: backendValues.value + Layout.fillWidth: true + } + } + + Label { + text: qsTr("From") + tooltip: qsTr("The starting value of the spinbox range.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + backendValue: backendValues.from + Layout.fillWidth: true + } + } + + Label { + text: qsTr("To") + tooltip: qsTr("The ending value of the spinbox range.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + backendValue: backendValues.to + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Step Size") + tooltip: qsTr("The step size of the spinbox.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 2 + backendValue: backendValues.stepSize + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Editable") + tooltip: qsTr("Whether the spinbox is editable.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.editable.valueToString + backendValue: backendValues.editable + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Wrap") + tooltip: qsTr("Whether the spinbox wraps.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.wrap.valueToString + backendValue: backendValues.wrap + Layout.fillWidth: true + } + } + } + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/StackViewSpecifics.qml b/src/quickcontrols2/designer/StackViewSpecifics.qml new file mode 100644 index 00000000000..3937437b5ed --- /dev/null +++ b/src/quickcontrols2/designer/StackViewSpecifics.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/SwipeDelegateSpecifics.qml b/src/quickcontrols2/designer/SwipeDelegateSpecifics.qml new file mode 100644 index 00000000000..1757521dd8b --- /dev/null +++ b/src/quickcontrols2/designer/SwipeDelegateSpecifics.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + ItemDelegateSection { + width: parent.width + } + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/SwipeViewSpecifics.qml b/src/quickcontrols2/designer/SwipeViewSpecifics.qml new file mode 100644 index 00000000000..a28a2917815 --- /dev/null +++ b/src/quickcontrols2/designer/SwipeViewSpecifics.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("SwipeView") + + SectionLayout { + Label { + text: qsTr("Interactive") + tooltip: qsTr("Whether the view is interactive.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.interactive.valueToString + backendValue: backendValues.interactive + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Orientation") + tooltip: qsTr("Orientation of the view.") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.orientation + model: [ "Horizontal", "Vertical" ] + scope: "Qt" + Layout.fillWidth: true + } + } + } + } + + ContainerSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/SwitchDelegateSpecifics.qml b/src/quickcontrols2/designer/SwitchDelegateSpecifics.qml new file mode 100644 index 00000000000..4236de67724 --- /dev/null +++ b/src/quickcontrols2/designer/SwitchDelegateSpecifics.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + ItemDelegateSection { + width: parent.width + } + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/SwitchSpecifics.qml b/src/quickcontrols2/designer/SwitchSpecifics.qml new file mode 100644 index 00000000000..df0af7e748d --- /dev/null +++ b/src/quickcontrols2/designer/SwitchSpecifics.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/TabBarSpecifics.qml b/src/quickcontrols2/designer/TabBarSpecifics.qml new file mode 100644 index 00000000000..6f02cdaac2e --- /dev/null +++ b/src/quickcontrols2/designer/TabBarSpecifics.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("TabBar") + + SectionLayout { + Label { + text: qsTr("Position") + tooltip: qsTr("Position of the tabbar.") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.position + model: [ "Header", "Footer" ] + scope: "TabBar" + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Content Width") + tooltip: qsTr("Content height used for calculating the total implicit width.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.contentWidth + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Content Height") + tooltip: qsTr("Content height used for calculating the total implicit height.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.contentHeight + Layout.fillWidth: true + } + } + } + } + + ContainerSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/TabButtonSpecifics.qml b/src/quickcontrols2/designer/TabButtonSpecifics.qml new file mode 100644 index 00000000000..df0af7e748d --- /dev/null +++ b/src/quickcontrols2/designer/TabButtonSpecifics.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/TextAreaSpecifics.qml b/src/quickcontrols2/designer/TextAreaSpecifics.qml new file mode 100644 index 00000000000..785d7a5017f --- /dev/null +++ b/src/quickcontrols2/designer/TextAreaSpecifics.qml @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("TextArea") + + SectionLayout { + Label { + text: qsTr("Placeholder") + tooltip: qsTr("Placeholder text displayed when the editor is empty.") + } + SecondColumnLayout { + LineEdit { + backendValue: backendValues.placeholderText + Layout.fillWidth: true + } + + } + + Label { + text: qsTr("Hover") + tooltip: qsTr("Whether text area accepts hover events.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.hoverEnabled.valueToString + backendValue: backendValues.hoverEnabled + Layout.fillWidth: true + } + } + } + } + + Section { + width: parent.width + caption: qsTr("Placeholder Text Color") + + ColorEditor { + caption: qsTr("Placeholder Text Color") + backendValue: backendValues.placeholderTextColor + supportGradient: false + } + } + + StandardTextSection { + width: parent.width + showIsWrapping: true + showFormatProperty: true + showVerticalAlignment: true + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } + + InsetSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/TextFieldSpecifics.qml b/src/quickcontrols2/designer/TextFieldSpecifics.qml new file mode 100644 index 00000000000..33a90f2ae84 --- /dev/null +++ b/src/quickcontrols2/designer/TextFieldSpecifics.qml @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("TextField") + + SectionLayout { + Label { + text: qsTr("Placeholder") + tooltip: qsTr("Placeholder text displayed when the editor is empty.") + } + SecondColumnLayout { + LineEdit { + backendValue: backendValues.placeholderText + Layout.fillWidth: true + } + + } + + Label { + text: qsTr("Hover") + tooltip: qsTr("Whether text field accepts hover events.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.hoverEnabled.valueToString + backendValue: backendValues.hoverEnabled + Layout.fillWidth: true + } + } + } + } + + Section { + width: parent.width + caption: qsTr("Placeholder Text Color") + + ColorEditor { + caption: qsTr("Placeholder Text Color") + backendValue: backendValues.placeholderTextColor + supportGradient: false + } + } + + StandardTextSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } + + InsetSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/ToolBarSpecifics.qml b/src/quickcontrols2/designer/ToolBarSpecifics.qml new file mode 100644 index 00000000000..2b1b17d2bbf --- /dev/null +++ b/src/quickcontrols2/designer/ToolBarSpecifics.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("ToolBar") + + SectionLayout { + Label { + text: qsTr("Position") + tooltip: qsTr("Position of the toolbar.") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.position + model: [ "Header", "Footer" ] + scope: "ToolBar" + Layout.fillWidth: true + } + } + } + } + + PaneSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/ToolButtonSpecifics.qml b/src/quickcontrols2/designer/ToolButtonSpecifics.qml new file mode 100644 index 00000000000..5a46e72aff1 --- /dev/null +++ b/src/quickcontrols2/designer/ToolButtonSpecifics.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + ButtonSection { + width: parent.width + } + + AbstractButtonSection { + width: parent.width + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/ToolSeparatorSpecifics.qml b/src/quickcontrols2/designer/ToolSeparatorSpecifics.qml new file mode 100644 index 00000000000..a62147ecafc --- /dev/null +++ b/src/quickcontrols2/designer/ToolSeparatorSpecifics.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("ToolSeparator") + + SectionLayout { + Label { + text: qsTr("Orientation") + tooltip: qsTr("The orientation of the separator.") + } + SecondColumnLayout { + ComboBox { + backendValue: backendValues.orientation + model: [ "Horizontal", "Vertical" ] + scope: "Qt" + Layout.fillWidth: true + } + } + } + } + + ControlSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/TumblerSpecifics.qml b/src/quickcontrols2/designer/TumblerSpecifics.qml new file mode 100644 index 00000000000..25fb9275813 --- /dev/null +++ b/src/quickcontrols2/designer/TumblerSpecifics.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import HelperWidgets +import QtQuick.Layouts + +Column { + width: parent.width + + Section { + width: parent.width + caption: qsTr("Tumbler") + + SectionLayout { + Label { + text: qsTr("Visible Count") + tooltip: qsTr("The count of visible items.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.visibleItemCount + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Current") + tooltip: qsTr("The index of the current item.") + } + SecondColumnLayout { + SpinBox { + maximumValue: 9999999 + minimumValue: -9999999 + decimals: 0 + backendValue: backendValues.currentIndex + Layout.fillWidth: true + } + } + + Label { + text: qsTr("Wrap") + tooltip: qsTr("Whether the tumbler wrap.") + } + SecondColumnLayout { + CheckBox { + text: backendValues.wrap.valueToString + backendValue: backendValues.wrap + Layout.fillWidth: true + } + } + } + } + + ControlSection { + width: parent.width + } + + FontSection { + width: parent.width + } + + PaddingSection { + width: parent.width + } +} diff --git a/src/quickcontrols2/designer/designer.pri b/src/quickcontrols2/designer/designer.pri new file mode 100644 index 00000000000..6692b203162 --- /dev/null +++ b/src/quickcontrols2/designer/designer.pri @@ -0,0 +1,52 @@ +AUX_QML_FILES += \ + $$PWD/qtquickcontrols2.metainfo + +AUX_QML_FILES += \ + $$PWD/AbstractButtonSection.qml \ + $$PWD/BusyIndicatorSpecifics.qml \ + $$PWD/ButtonSection.qml \ + $$PWD/ButtonSpecifics.qml \ + $$PWD/CheckBoxSpecifics.qml \ + $$PWD/CheckDelegateSpecifics.qml \ + $$PWD/CheckSection.qml \ + $$PWD/ComboBoxSpecifics.qml \ + $$PWD/ContainerSection.qml \ + $$PWD/ControlSection.qml \ + $$PWD/ControlSpecifics.qml \ + $$PWD/DelayButtonSpecifics.qml \ + $$PWD/DialSpecifics.qml \ + $$PWD/FrameSpecifics.qml \ + $$PWD/GroupBoxSpecifics.qml \ + $$PWD/InsetSection.qml \ + $$PWD/ItemDelegateSection.qml \ + $$PWD/ItemDelegateSpecifics.qml \ + $$PWD/LabelSpecifics.qml \ + $$PWD/PaddingSection.qml \ + $$PWD/PageSpecifics.qml \ + $$PWD/PageIndicatorSpecifics.qml \ + $$PWD/PaneSection.qml \ + $$PWD/PaneSpecifics.qml \ + $$PWD/ProgressBarSpecifics.qml \ + $$PWD/RadioButtonSpecifics.qml \ + $$PWD/RadioDelegateSpecifics.qml \ + $$PWD/RangeSliderSpecifics.qml \ + $$PWD/RoundButtonSpecifics.qml \ + $$PWD/ScrollViewSpecifics.qml \ + $$PWD/SliderSpecifics.qml \ + $$PWD/SpinBoxSpecifics.qml \ + $$PWD/StackViewSpecifics.qml \ + $$PWD/SwipeDelegateSpecifics.qml \ + $$PWD/SwipeViewSpecifics.qml \ + $$PWD/SwitchSpecifics.qml \ + $$PWD/SwitchDelegateSpecifics.qml \ + $$PWD/TabBarSpecifics.qml \ + $$PWD/TabButtonSpecifics.qml \ + $$PWD/TextAreaSpecifics.qml \ + $$PWD/TextFieldSpecifics.qml \ + $$PWD/ToolBarSpecifics.qml \ + $$PWD/ToolButtonSpecifics.qml \ + $$PWD/ToolSeparatorSpecifics.qml \ + $$PWD/TumblerSpecifics.qml + +AUX_QML_FILES += \ + $$files($$PWD/images/*.png) diff --git a/src/quickcontrols2/designer/images/busyindicator-icon.png b/src/quickcontrols2/designer/images/busyindicator-icon.png new file mode 100644 index 00000000000..666d1ed93f7 Binary files /dev/null and b/src/quickcontrols2/designer/images/busyindicator-icon.png differ diff --git a/src/quickcontrols2/designer/images/busyindicator-icon16.png b/src/quickcontrols2/designer/images/busyindicator-icon16.png new file mode 100644 index 00000000000..5aa57d7f488 Binary files /dev/null and b/src/quickcontrols2/designer/images/busyindicator-icon16.png differ diff --git a/src/quickcontrols2/designer/images/busyindicator-icon@2x.png b/src/quickcontrols2/designer/images/busyindicator-icon@2x.png new file mode 100644 index 00000000000..bb2278ff899 Binary files /dev/null and b/src/quickcontrols2/designer/images/busyindicator-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/button-icon.png b/src/quickcontrols2/designer/images/button-icon.png new file mode 100644 index 00000000000..c44909f6dde Binary files /dev/null and b/src/quickcontrols2/designer/images/button-icon.png differ diff --git a/src/quickcontrols2/designer/images/button-icon16.png b/src/quickcontrols2/designer/images/button-icon16.png new file mode 100644 index 00000000000..5c921deb136 Binary files /dev/null and b/src/quickcontrols2/designer/images/button-icon16.png differ diff --git a/src/quickcontrols2/designer/images/button-icon@2x.png b/src/quickcontrols2/designer/images/button-icon@2x.png new file mode 100644 index 00000000000..f90a1ba7dce Binary files /dev/null and b/src/quickcontrols2/designer/images/button-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/checkbox-icon.png b/src/quickcontrols2/designer/images/checkbox-icon.png new file mode 100644 index 00000000000..ee669b3a888 Binary files /dev/null and b/src/quickcontrols2/designer/images/checkbox-icon.png differ diff --git a/src/quickcontrols2/designer/images/checkbox-icon16.png b/src/quickcontrols2/designer/images/checkbox-icon16.png new file mode 100644 index 00000000000..8d89eab8413 Binary files /dev/null and b/src/quickcontrols2/designer/images/checkbox-icon16.png differ diff --git a/src/quickcontrols2/designer/images/checkbox-icon@2x.png b/src/quickcontrols2/designer/images/checkbox-icon@2x.png new file mode 100644 index 00000000000..51c5601de02 Binary files /dev/null and b/src/quickcontrols2/designer/images/checkbox-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/combobox-icon.png b/src/quickcontrols2/designer/images/combobox-icon.png new file mode 100644 index 00000000000..2d31b17c65f Binary files /dev/null and b/src/quickcontrols2/designer/images/combobox-icon.png differ diff --git a/src/quickcontrols2/designer/images/combobox-icon16.png b/src/quickcontrols2/designer/images/combobox-icon16.png new file mode 100644 index 00000000000..15fc3505ba2 Binary files /dev/null and b/src/quickcontrols2/designer/images/combobox-icon16.png differ diff --git a/src/quickcontrols2/designer/images/combobox-icon@2x.png b/src/quickcontrols2/designer/images/combobox-icon@2x.png new file mode 100644 index 00000000000..5f82390596b Binary files /dev/null and b/src/quickcontrols2/designer/images/combobox-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/delaybutton-icon.png b/src/quickcontrols2/designer/images/delaybutton-icon.png new file mode 100644 index 00000000000..5a55bd9f77a Binary files /dev/null and b/src/quickcontrols2/designer/images/delaybutton-icon.png differ diff --git a/src/quickcontrols2/designer/images/delaybutton-icon16.png b/src/quickcontrols2/designer/images/delaybutton-icon16.png new file mode 100644 index 00000000000..cd21394e465 Binary files /dev/null and b/src/quickcontrols2/designer/images/delaybutton-icon16.png differ diff --git a/src/quickcontrols2/designer/images/delaybutton-icon@2x.png b/src/quickcontrols2/designer/images/delaybutton-icon@2x.png new file mode 100644 index 00000000000..7beee2fab0e Binary files /dev/null and b/src/quickcontrols2/designer/images/delaybutton-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/dial-icon.png b/src/quickcontrols2/designer/images/dial-icon.png new file mode 100644 index 00000000000..b3b63e35235 Binary files /dev/null and b/src/quickcontrols2/designer/images/dial-icon.png differ diff --git a/src/quickcontrols2/designer/images/dial-icon16.png b/src/quickcontrols2/designer/images/dial-icon16.png new file mode 100644 index 00000000000..8d8c7c09b05 Binary files /dev/null and b/src/quickcontrols2/designer/images/dial-icon16.png differ diff --git a/src/quickcontrols2/designer/images/dial-icon@2x.png b/src/quickcontrols2/designer/images/dial-icon@2x.png new file mode 100644 index 00000000000..22547a16b83 Binary files /dev/null and b/src/quickcontrols2/designer/images/dial-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/frame-icon.png b/src/quickcontrols2/designer/images/frame-icon.png new file mode 100644 index 00000000000..32abc8bf1e6 Binary files /dev/null and b/src/quickcontrols2/designer/images/frame-icon.png differ diff --git a/src/quickcontrols2/designer/images/frame-icon16.png b/src/quickcontrols2/designer/images/frame-icon16.png new file mode 100644 index 00000000000..e5b65ad53bb Binary files /dev/null and b/src/quickcontrols2/designer/images/frame-icon16.png differ diff --git a/src/quickcontrols2/designer/images/frame-icon@2x.png b/src/quickcontrols2/designer/images/frame-icon@2x.png new file mode 100644 index 00000000000..8b876f38ec8 Binary files /dev/null and b/src/quickcontrols2/designer/images/frame-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/groupbox-icon.png b/src/quickcontrols2/designer/images/groupbox-icon.png new file mode 100644 index 00000000000..5542ecf8bf7 Binary files /dev/null and b/src/quickcontrols2/designer/images/groupbox-icon.png differ diff --git a/src/quickcontrols2/designer/images/groupbox-icon16.png b/src/quickcontrols2/designer/images/groupbox-icon16.png new file mode 100644 index 00000000000..9cf4324819f Binary files /dev/null and b/src/quickcontrols2/designer/images/groupbox-icon16.png differ diff --git a/src/quickcontrols2/designer/images/groupbox-icon@2x.png b/src/quickcontrols2/designer/images/groupbox-icon@2x.png new file mode 100644 index 00000000000..80dab3c716a Binary files /dev/null and b/src/quickcontrols2/designer/images/groupbox-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/itemdelegate-icon.png b/src/quickcontrols2/designer/images/itemdelegate-icon.png new file mode 100644 index 00000000000..822cf3e7b8b Binary files /dev/null and b/src/quickcontrols2/designer/images/itemdelegate-icon.png differ diff --git a/src/quickcontrols2/designer/images/itemdelegate-icon16.png b/src/quickcontrols2/designer/images/itemdelegate-icon16.png new file mode 100644 index 00000000000..b3ed007a0e3 Binary files /dev/null and b/src/quickcontrols2/designer/images/itemdelegate-icon16.png differ diff --git a/src/quickcontrols2/designer/images/itemdelegate-icon@2x.png b/src/quickcontrols2/designer/images/itemdelegate-icon@2x.png new file mode 100644 index 00000000000..cb81308ff8d Binary files /dev/null and b/src/quickcontrols2/designer/images/itemdelegate-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/label-icon.png b/src/quickcontrols2/designer/images/label-icon.png new file mode 100644 index 00000000000..788bef078ce Binary files /dev/null and b/src/quickcontrols2/designer/images/label-icon.png differ diff --git a/src/quickcontrols2/designer/images/label-icon16.png b/src/quickcontrols2/designer/images/label-icon16.png new file mode 100644 index 00000000000..b68d3845685 Binary files /dev/null and b/src/quickcontrols2/designer/images/label-icon16.png differ diff --git a/src/quickcontrols2/designer/images/label-icon@2x.png b/src/quickcontrols2/designer/images/label-icon@2x.png new file mode 100644 index 00000000000..7001413d3b0 Binary files /dev/null and b/src/quickcontrols2/designer/images/label-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/page-icon.png b/src/quickcontrols2/designer/images/page-icon.png new file mode 100644 index 00000000000..b5ac87e8991 Binary files /dev/null and b/src/quickcontrols2/designer/images/page-icon.png differ diff --git a/src/quickcontrols2/designer/images/page-icon16.png b/src/quickcontrols2/designer/images/page-icon16.png new file mode 100644 index 00000000000..bc6810b6053 Binary files /dev/null and b/src/quickcontrols2/designer/images/page-icon16.png differ diff --git a/src/quickcontrols2/designer/images/page-icon@2x.png b/src/quickcontrols2/designer/images/page-icon@2x.png new file mode 100644 index 00000000000..23db032f4ab Binary files /dev/null and b/src/quickcontrols2/designer/images/page-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/pageindicator-icon.png b/src/quickcontrols2/designer/images/pageindicator-icon.png new file mode 100644 index 00000000000..edb6b377bbd Binary files /dev/null and b/src/quickcontrols2/designer/images/pageindicator-icon.png differ diff --git a/src/quickcontrols2/designer/images/pageindicator-icon16.png b/src/quickcontrols2/designer/images/pageindicator-icon16.png new file mode 100644 index 00000000000..0fb8967564c Binary files /dev/null and b/src/quickcontrols2/designer/images/pageindicator-icon16.png differ diff --git a/src/quickcontrols2/designer/images/pageindicator-icon@2x.png b/src/quickcontrols2/designer/images/pageindicator-icon@2x.png new file mode 100644 index 00000000000..7be0ee813ba Binary files /dev/null and b/src/quickcontrols2/designer/images/pageindicator-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/pane-icon.png b/src/quickcontrols2/designer/images/pane-icon.png new file mode 100644 index 00000000000..62ebe487ffe Binary files /dev/null and b/src/quickcontrols2/designer/images/pane-icon.png differ diff --git a/src/quickcontrols2/designer/images/pane-icon16.png b/src/quickcontrols2/designer/images/pane-icon16.png new file mode 100644 index 00000000000..2b8048441c3 Binary files /dev/null and b/src/quickcontrols2/designer/images/pane-icon16.png differ diff --git a/src/quickcontrols2/designer/images/pane-icon@2x.png b/src/quickcontrols2/designer/images/pane-icon@2x.png new file mode 100644 index 00000000000..55bb116a699 Binary files /dev/null and b/src/quickcontrols2/designer/images/pane-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/progressbar-icon.png b/src/quickcontrols2/designer/images/progressbar-icon.png new file mode 100644 index 00000000000..a023f73c30f Binary files /dev/null and b/src/quickcontrols2/designer/images/progressbar-icon.png differ diff --git a/src/quickcontrols2/designer/images/progressbar-icon16.png b/src/quickcontrols2/designer/images/progressbar-icon16.png new file mode 100644 index 00000000000..6fede21d8c2 Binary files /dev/null and b/src/quickcontrols2/designer/images/progressbar-icon16.png differ diff --git a/src/quickcontrols2/designer/images/progressbar-icon@2x.png b/src/quickcontrols2/designer/images/progressbar-icon@2x.png new file mode 100644 index 00000000000..00694003356 Binary files /dev/null and b/src/quickcontrols2/designer/images/progressbar-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/radiobutton-icon.png b/src/quickcontrols2/designer/images/radiobutton-icon.png new file mode 100644 index 00000000000..d38170e22f7 Binary files /dev/null and b/src/quickcontrols2/designer/images/radiobutton-icon.png differ diff --git a/src/quickcontrols2/designer/images/radiobutton-icon16.png b/src/quickcontrols2/designer/images/radiobutton-icon16.png new file mode 100644 index 00000000000..07b46a8ab08 Binary files /dev/null and b/src/quickcontrols2/designer/images/radiobutton-icon16.png differ diff --git a/src/quickcontrols2/designer/images/radiobutton-icon@2x.png b/src/quickcontrols2/designer/images/radiobutton-icon@2x.png new file mode 100644 index 00000000000..4bbddda4b25 Binary files /dev/null and b/src/quickcontrols2/designer/images/radiobutton-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/rangeslider-icon.png b/src/quickcontrols2/designer/images/rangeslider-icon.png new file mode 100644 index 00000000000..1c4c7b29487 Binary files /dev/null and b/src/quickcontrols2/designer/images/rangeslider-icon.png differ diff --git a/src/quickcontrols2/designer/images/rangeslider-icon16.png b/src/quickcontrols2/designer/images/rangeslider-icon16.png new file mode 100644 index 00000000000..3be4624ddd4 Binary files /dev/null and b/src/quickcontrols2/designer/images/rangeslider-icon16.png differ diff --git a/src/quickcontrols2/designer/images/rangeslider-icon@2x.png b/src/quickcontrols2/designer/images/rangeslider-icon@2x.png new file mode 100644 index 00000000000..aee69b3302f Binary files /dev/null and b/src/quickcontrols2/designer/images/rangeslider-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/roundbutton-icon.png b/src/quickcontrols2/designer/images/roundbutton-icon.png new file mode 100644 index 00000000000..d4b470dc25b Binary files /dev/null and b/src/quickcontrols2/designer/images/roundbutton-icon.png differ diff --git a/src/quickcontrols2/designer/images/roundbutton-icon16.png b/src/quickcontrols2/designer/images/roundbutton-icon16.png new file mode 100644 index 00000000000..f6f3666639e Binary files /dev/null and b/src/quickcontrols2/designer/images/roundbutton-icon16.png differ diff --git a/src/quickcontrols2/designer/images/roundbutton-icon@2x.png b/src/quickcontrols2/designer/images/roundbutton-icon@2x.png new file mode 100644 index 00000000000..4553e165e75 Binary files /dev/null and b/src/quickcontrols2/designer/images/roundbutton-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/scrollview-icon.png b/src/quickcontrols2/designer/images/scrollview-icon.png new file mode 100644 index 00000000000..5ef73ff19f5 Binary files /dev/null and b/src/quickcontrols2/designer/images/scrollview-icon.png differ diff --git a/src/quickcontrols2/designer/images/scrollview-icon16.png b/src/quickcontrols2/designer/images/scrollview-icon16.png new file mode 100644 index 00000000000..f8ca7a36853 Binary files /dev/null and b/src/quickcontrols2/designer/images/scrollview-icon16.png differ diff --git a/src/quickcontrols2/designer/images/scrollview-icon@2x.png b/src/quickcontrols2/designer/images/scrollview-icon@2x.png new file mode 100644 index 00000000000..0eb7f9665ec Binary files /dev/null and b/src/quickcontrols2/designer/images/scrollview-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/slider-icon.png b/src/quickcontrols2/designer/images/slider-icon.png new file mode 100644 index 00000000000..bd0a9729bea Binary files /dev/null and b/src/quickcontrols2/designer/images/slider-icon.png differ diff --git a/src/quickcontrols2/designer/images/slider-icon16.png b/src/quickcontrols2/designer/images/slider-icon16.png new file mode 100644 index 00000000000..a08622df89c Binary files /dev/null and b/src/quickcontrols2/designer/images/slider-icon16.png differ diff --git a/src/quickcontrols2/designer/images/slider-icon@2x.png b/src/quickcontrols2/designer/images/slider-icon@2x.png new file mode 100644 index 00000000000..93842e4cdde Binary files /dev/null and b/src/quickcontrols2/designer/images/slider-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/spinbox-icon.png b/src/quickcontrols2/designer/images/spinbox-icon.png new file mode 100644 index 00000000000..37277c5e43c Binary files /dev/null and b/src/quickcontrols2/designer/images/spinbox-icon.png differ diff --git a/src/quickcontrols2/designer/images/spinbox-icon16.png b/src/quickcontrols2/designer/images/spinbox-icon16.png new file mode 100644 index 00000000000..f88711dd25f Binary files /dev/null and b/src/quickcontrols2/designer/images/spinbox-icon16.png differ diff --git a/src/quickcontrols2/designer/images/spinbox-icon@2x.png b/src/quickcontrols2/designer/images/spinbox-icon@2x.png new file mode 100644 index 00000000000..b62a3bad512 Binary files /dev/null and b/src/quickcontrols2/designer/images/spinbox-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/stackview-icon.png b/src/quickcontrols2/designer/images/stackview-icon.png new file mode 100644 index 00000000000..a6ced34925b Binary files /dev/null and b/src/quickcontrols2/designer/images/stackview-icon.png differ diff --git a/src/quickcontrols2/designer/images/stackview-icon16.png b/src/quickcontrols2/designer/images/stackview-icon16.png new file mode 100644 index 00000000000..0f19d0efa3e Binary files /dev/null and b/src/quickcontrols2/designer/images/stackview-icon16.png differ diff --git a/src/quickcontrols2/designer/images/stackview-icon@2x.png b/src/quickcontrols2/designer/images/stackview-icon@2x.png new file mode 100644 index 00000000000..9b5ef9517bd Binary files /dev/null and b/src/quickcontrols2/designer/images/stackview-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/swipeview-icon.png b/src/quickcontrols2/designer/images/swipeview-icon.png new file mode 100644 index 00000000000..031cb27c367 Binary files /dev/null and b/src/quickcontrols2/designer/images/swipeview-icon.png differ diff --git a/src/quickcontrols2/designer/images/swipeview-icon16.png b/src/quickcontrols2/designer/images/swipeview-icon16.png new file mode 100644 index 00000000000..446c4696900 Binary files /dev/null and b/src/quickcontrols2/designer/images/swipeview-icon16.png differ diff --git a/src/quickcontrols2/designer/images/swipeview-icon@2x.png b/src/quickcontrols2/designer/images/swipeview-icon@2x.png new file mode 100644 index 00000000000..0ccb978c469 Binary files /dev/null and b/src/quickcontrols2/designer/images/swipeview-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/switch-icon.png b/src/quickcontrols2/designer/images/switch-icon.png new file mode 100644 index 00000000000..e0181592860 Binary files /dev/null and b/src/quickcontrols2/designer/images/switch-icon.png differ diff --git a/src/quickcontrols2/designer/images/switch-icon16.png b/src/quickcontrols2/designer/images/switch-icon16.png new file mode 100644 index 00000000000..9abd2756592 Binary files /dev/null and b/src/quickcontrols2/designer/images/switch-icon16.png differ diff --git a/src/quickcontrols2/designer/images/switch-icon@2x.png b/src/quickcontrols2/designer/images/switch-icon@2x.png new file mode 100644 index 00000000000..787f54ca41f Binary files /dev/null and b/src/quickcontrols2/designer/images/switch-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/textarea-icon.png b/src/quickcontrols2/designer/images/textarea-icon.png new file mode 100644 index 00000000000..f1b2dc0f84d Binary files /dev/null and b/src/quickcontrols2/designer/images/textarea-icon.png differ diff --git a/src/quickcontrols2/designer/images/textarea-icon16.png b/src/quickcontrols2/designer/images/textarea-icon16.png new file mode 100644 index 00000000000..4afc1fbab56 Binary files /dev/null and b/src/quickcontrols2/designer/images/textarea-icon16.png differ diff --git a/src/quickcontrols2/designer/images/textarea-icon@2x.png b/src/quickcontrols2/designer/images/textarea-icon@2x.png new file mode 100644 index 00000000000..c32ecc71a9a Binary files /dev/null and b/src/quickcontrols2/designer/images/textarea-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/textfield-icon.png b/src/quickcontrols2/designer/images/textfield-icon.png new file mode 100644 index 00000000000..ba5537acefe Binary files /dev/null and b/src/quickcontrols2/designer/images/textfield-icon.png differ diff --git a/src/quickcontrols2/designer/images/textfield-icon16.png b/src/quickcontrols2/designer/images/textfield-icon16.png new file mode 100644 index 00000000000..c4a62a6582b Binary files /dev/null and b/src/quickcontrols2/designer/images/textfield-icon16.png differ diff --git a/src/quickcontrols2/designer/images/textfield-icon@2x.png b/src/quickcontrols2/designer/images/textfield-icon@2x.png new file mode 100644 index 00000000000..e05fd41b9a4 Binary files /dev/null and b/src/quickcontrols2/designer/images/textfield-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/toolbar-icon.png b/src/quickcontrols2/designer/images/toolbar-icon.png new file mode 100644 index 00000000000..5cb5b2e1af1 Binary files /dev/null and b/src/quickcontrols2/designer/images/toolbar-icon.png differ diff --git a/src/quickcontrols2/designer/images/toolbar-icon16.png b/src/quickcontrols2/designer/images/toolbar-icon16.png new file mode 100644 index 00000000000..569373afa13 Binary files /dev/null and b/src/quickcontrols2/designer/images/toolbar-icon16.png differ diff --git a/src/quickcontrols2/designer/images/toolbar-icon@2x.png b/src/quickcontrols2/designer/images/toolbar-icon@2x.png new file mode 100644 index 00000000000..fd9e6ceebcc Binary files /dev/null and b/src/quickcontrols2/designer/images/toolbar-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/toolbutton-icon.png b/src/quickcontrols2/designer/images/toolbutton-icon.png new file mode 100644 index 00000000000..3298f695190 Binary files /dev/null and b/src/quickcontrols2/designer/images/toolbutton-icon.png differ diff --git a/src/quickcontrols2/designer/images/toolbutton-icon16.png b/src/quickcontrols2/designer/images/toolbutton-icon16.png new file mode 100644 index 00000000000..9ab7861c25f Binary files /dev/null and b/src/quickcontrols2/designer/images/toolbutton-icon16.png differ diff --git a/src/quickcontrols2/designer/images/toolbutton-icon@2x.png b/src/quickcontrols2/designer/images/toolbutton-icon@2x.png new file mode 100644 index 00000000000..e5958cded3f Binary files /dev/null and b/src/quickcontrols2/designer/images/toolbutton-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/toolseparator-icon.png b/src/quickcontrols2/designer/images/toolseparator-icon.png new file mode 100644 index 00000000000..5e99f06f2ef Binary files /dev/null and b/src/quickcontrols2/designer/images/toolseparator-icon.png differ diff --git a/src/quickcontrols2/designer/images/toolseparator-icon16.png b/src/quickcontrols2/designer/images/toolseparator-icon16.png new file mode 100644 index 00000000000..68f22c5df1b Binary files /dev/null and b/src/quickcontrols2/designer/images/toolseparator-icon16.png differ diff --git a/src/quickcontrols2/designer/images/toolseparator-icon@2x.png b/src/quickcontrols2/designer/images/toolseparator-icon@2x.png new file mode 100644 index 00000000000..549c11c67cf Binary files /dev/null and b/src/quickcontrols2/designer/images/toolseparator-icon@2x.png differ diff --git a/src/quickcontrols2/designer/images/tumbler-icon.png b/src/quickcontrols2/designer/images/tumbler-icon.png new file mode 100644 index 00000000000..98eb8232a26 Binary files /dev/null and b/src/quickcontrols2/designer/images/tumbler-icon.png differ diff --git a/src/quickcontrols2/designer/images/tumbler-icon16.png b/src/quickcontrols2/designer/images/tumbler-icon16.png new file mode 100644 index 00000000000..ff5f95cf327 Binary files /dev/null and b/src/quickcontrols2/designer/images/tumbler-icon16.png differ diff --git a/src/quickcontrols2/designer/images/tumbler-icon@2x.png b/src/quickcontrols2/designer/images/tumbler-icon@2x.png new file mode 100644 index 00000000000..236abf0cfe2 Binary files /dev/null and b/src/quickcontrols2/designer/images/tumbler-icon@2x.png differ diff --git a/src/quickcontrols2/designer/qtquickcontrols2.metainfo b/src/quickcontrols2/designer/qtquickcontrols2.metainfo new file mode 100644 index 00000000000..d27f1b9004c --- /dev/null +++ b/src/quickcontrols2/designer/qtquickcontrols2.metainfo @@ -0,0 +1,522 @@ +MetaInfo { + Type { + name: "QtQuick.Controls.BusyIndicator" + icon: "images/busyindicator-icon16.png" + + ItemLibraryEntry { + name: "Busy Indicator" + category: "Qt Quick - Controls 2" + libraryIcon: "images/busyindicator-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + } + } + + Type { + name: "QtQuick.Controls.Button" + icon: "images/button-icon16.png" + + ItemLibraryEntry { + name: "Button" + category: "Qt Quick - Controls 2" + libraryIcon: "images/button-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "text"; type: "binding"; value: "qsTr(\"Button\")" } + } + } + + Type { + name: "QtQuick.Controls.CheckBox" + icon: "images/checkbox-icon16.png" + + ItemLibraryEntry { + name: "Check Box" + category: "Qt Quick - Controls 2" + libraryIcon: "images/checkbox-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "text"; type: "binding"; value: "qsTr(\"Check Box\")" } + } + } + + Type { + name: "QtQuick.Controls.CheckDelegate" + icon: "images/checkbox-icon16.png" + + ItemLibraryEntry { + name: "Check Delegate" + category: "Qt Quick - Controls 2" + libraryIcon: "images/checkbox-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "text"; type: "binding"; value: "qsTr(\"Check Delegate\")" } + } + } + + Type { + name: "QtQuick.Controls.ComboBox" + icon: "images/combobox-icon16.png" + + ItemLibraryEntry { + name: "Combo Box" + category: "Qt Quick - Controls 2" + libraryIcon: "images/combobox-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + } + } + + Type { + name: "QtQuick.Controls.DelayButton" + icon: "images/button-icon16.png" + + ItemLibraryEntry { + name: "Delay Button" + category: "Qt Quick - Controls 2" + libraryIcon: "images/delaybutton-icon.png" + version: "2.2" + requiredImport: "QtQuick.Controls" + + Property { name: "text"; type: "binding"; value: "qsTr(\"Delay Button\")" } + } + } + + Type { + name: "QtQuick.Controls.Dial" + icon: "images/dial-icon16.png" + + ItemLibraryEntry { + name: "Dial" + category: "Qt Quick - Controls 2" + libraryIcon: "images/dial-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + } + } + + Type { + name: "QtQuick.Controls.Frame" + icon: "images/frame-icon16.png" + + ItemLibraryEntry { + name: "Frame" + category: "Qt Quick - Controls 2" + libraryIcon: "images/frame-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + } + } + + Type { + name: "QtQuick.Controls.GroupBox" + icon: "images/groupbox-icon16.png" + + ItemLibraryEntry { + name: "Group Box" + category: "Qt Quick - Controls 2" + libraryIcon: "images/groupbox-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + Property { name: "title"; type: "binding"; value: "qsTr(\"Group Box\")" } + } + } + + Type { + name: "QtQuick.Controls.ItemDelegate" + icon: "images/itemdelegate-icon16.png" + + ItemLibraryEntry { + name: "Item Delegate" + category: "Qt Quick - Controls 2" + libraryIcon: "images/itemdelegate-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "text"; type: "binding"; value: "qsTr(\"Item Delegate\")" } + } + } + + Type { + name: "QtQuick.Controls.Label" + icon: "images/label-icon16.png" + + ItemLibraryEntry { + name: "Label" + category: "Qt Quick - Controls 2" + libraryIcon: "images/label-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "text"; type: "binding"; value: "qsTr(\"Label\")" } + } + } + + Type { + name: "QtQuick.Controls.Page" + icon: "images/page-icon16.png" + + ItemLibraryEntry { + name: "Page" + category: "Qt Quick - Controls 2" + libraryIcon: "images/page-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + } + } + + Type { + name: "QtQuick.Controls.PageIndicator" + icon: "images/pageindicator-icon16.png" + + ItemLibraryEntry { + name: "Page Indicator" + category: "Qt Quick - Controls 2" + libraryIcon: "images/pageindicator-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "count"; type: "int"; value: 3 } + } + } + + Type { + name: "QtQuick.Controls.Pane" + icon: "images/pane-icon16.png" + + ItemLibraryEntry { + name: "Pane" + category: "Qt Quick - Controls 2" + libraryIcon: "images/pane-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + } + } + + Type { + name: "QtQuick.Controls.ProgressBar" + icon: "images/progressbar-icon16.png" + + ItemLibraryEntry { + name: "Progress Bar" + category: "Qt Quick - Controls 2" + libraryIcon: "images/progressbar-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "value"; type: "real"; value: 0.5 } + } + } + + Type { + name: "QtQuick.Controls.RadioButton" + icon: "images/radiobutton-icon16.png" + + ItemLibraryEntry { + name: "Radio Button" + category: "Qt Quick - Controls 2" + libraryIcon: "images/radiobutton-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "text"; type: "binding"; value: "qsTr(\"Radio Button\")" } + } + } + + Type { + name: "QtQuick.Controls.RadioDelegate" + icon: "images/radiobutton-icon16.png" + + ItemLibraryEntry { + name: "Radio Delegate" + category: "Qt Quick - Controls 2" + libraryIcon: "images/radiobutton-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "text"; type: "binding"; value: "qsTr(\"Radio Delegate\")" } + } + } + + Type { + name: "QtQuick.Controls.RangeSlider" + icon: "images/rangeslider-icon16.png" + + ItemLibraryEntry { + name: "Range Slider" + category: "Qt Quick - Controls 2" + libraryIcon: "images/rangeslider-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "first.value"; type: "real"; value: 0.25 } + Property { name: "second.value"; type: "real"; value: 0.75 } + } + } + + Type { + name: "QtQuick.Controls.RoundButton" + icon: "images/roundbutton-icon16.png" + + ItemLibraryEntry { + name: "Round Button" + category: "Qt Quick - Controls 2" + libraryIcon: "images/roundbutton-icon.png" + version: "2.1" + requiredImport: "QtQuick.Controls" + Property { name: "text"; type: "string"; value: "+" } + } + } + + Type { + name: "QtQuick.Controls.Slider" + icon: "images/slider-icon16.png" + + ItemLibraryEntry { + name: "Slider" + category: "Qt Quick - Controls 2" + libraryIcon: "images/slider-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "value"; type: "real"; value: 0.5 } + } + } + + Type { + name: "QtQuick.Controls.SpinBox" + icon: "images/spinbox-icon16.png" + + ItemLibraryEntry { + name: "Spin Box" + category: "Qt Quick - Controls 2" + libraryIcon: "images/spinbox-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + } + } + + Type { + name: "QtQuick.Controls.ScrollView" + icon: "images/scrollview-icon16.png" + + ItemLibraryEntry { + name: "Scroll View" + category: "Qt Quick - Controls 2" + libraryIcon: "images/scrollview-icon.png" + version: "2.2" + requiredImport: "QtQuick.Controls" + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + } + } + + Type { + name: "QtQuick.Controls.StackView" + icon: "images/stackview-icon16.png" + + ItemLibraryEntry { + name: "Stack View" + category: "Qt Quick - Controls 2" + libraryIcon: "images/stackview-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + } + } + + Type { + name: "QtQuick.Controls.SwipeDelegate" + icon: "images/itemdelegate-icon16.png" + + ItemLibraryEntry { + name: "Swipe Delegate" + category: "Qt Quick - Controls 2" + libraryIcon: "images/itemdelegate-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "text"; type: "binding"; value: "qsTr(\"Swipe Delegate\")" } + } + } + + Type { + name: "QtQuick.Controls.SwipeView" + icon: "images/swipeview-icon16.png" + + ItemLibraryEntry { + name: "Swipe View" + category: "Qt Quick - Controls 2" + libraryIcon: "images/swipeview-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + } + } + + Type { + name: "QtQuick.Controls.Switch" + icon: "images/switch-icon16.png" + + ItemLibraryEntry { + name: "Switch" + category: "Qt Quick - Controls 2" + libraryIcon: "images/switch-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "text"; type: "binding"; value: "qsTr(\"Switch\")" } + } + } + + Type { + name: "QtQuick.Controls.SwitchDelegate" + icon: "images/switch-icon16.png" + + ItemLibraryEntry { + name: "Switch Delegate" + category: "Qt Quick - Controls 2" + libraryIcon: "images/switch-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "text"; type: "binding"; value: "qsTr(\"Switch Delegate\")" } + } + } + + Type { + name: "QtQuick.Controls.TabBar" + icon: "images/toolbar-icon16.png" + + ItemLibraryEntry { + name: "Tab Bar" + category: "Qt Quick - Controls 2" + libraryIcon: "images/toolbar-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + Property { name: "width"; type: "int"; value: 240 } + } + } + + Type { + name: "QtQuick.Controls.TabButton" + icon: "images/toolbutton-icon16.png" + + ItemLibraryEntry { + name: "Tab Button" + category: "Qt Quick - Controls 2" + libraryIcon: "images/toolbutton-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + Property { name: "text"; type: "binding"; value: "qsTr(\"Tab Button\")" } + } + } + + Type { + name: "QtQuick.Controls.TextArea" + icon: "images/textarea-icon16.png" + + ItemLibraryEntry { + name: "Text Area" + category: "Qt Quick - Controls 2" + libraryIcon: "images/textarea-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "placeholderText"; type: "binding"; value: "qsTr(\"Text Area\")" } + } + } + + Type { + name: "QtQuick.Controls.TextField" + icon: "images/textfield-icon16.png" + + ItemLibraryEntry { + name: "Text Field" + category: "Qt Quick - Controls 2" + libraryIcon: "images/textfield-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "placeholderText"; type: "binding"; value: "qsTr(\"Text Field\")" } + } + } + + Type { + name: "QtQuick.Controls.ToolBar" + icon: "images/toolbar-icon16.png" + + ItemLibraryEntry { + name: "Tool Bar" + category: "Qt Quick - Controls 2" + libraryIcon: "images/toolbar-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "width"; type: "int"; value: 360 } + } + } + + Type { + name: "QtQuick.Controls.ToolButton" + icon: "images/toolbutton-icon16.png" + + ItemLibraryEntry { + name: "Tool Button" + category: "Qt Quick - Controls 2" + libraryIcon: "images/toolbutton-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "text"; type: "binding"; value: "qsTr(\"Tool Button\")" } + } + } + + Type { + name: "QtQuick.Controls.ToolSeparator" + icon: "images/toolseparator-icon16.png" + + ItemLibraryEntry { + name: "Tool Separator" + category: "Qt Quick - Controls 2" + libraryIcon: "images/toolseparator-icon.png" + version: "2.1" + requiredImport: "QtQuick.Controls" + } + } + + Type { + name: "QtQuick.Controls.Tumbler" + icon: "images/tumbler-icon16.png" + + ItemLibraryEntry { + name: "Tumbler" + category: "Qt Quick - Controls 2" + libraryIcon: "images/tumbler-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + Property { name: "model"; type: "int"; value: "10" } + } + } +} diff --git a/src/quickcontrols2/doc/doc.pri b/src/quickcontrols2/doc/doc.pri new file mode 100644 index 00000000000..4bd8bd95df9 --- /dev/null +++ b/src/quickcontrols2/doc/doc.pri @@ -0,0 +1,6 @@ +QMAKE_DOCS = $$PWD/qtquickcontrols.qdocconf + +OTHER_FILES += \ + $$files($$PWD/snippets/*.qml) \ + $$files($$PWD/src/*.qdoc) \ + $$files($$PWD/src/templates/*.qdoc) diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-applicationwindow-wireframe.png b/src/quickcontrols2/doc/images/qtquickcontrols2-applicationwindow-wireframe.png new file mode 100644 index 00000000000..f31378004a5 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-applicationwindow-wireframe.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-basic-thumbnail.png b/src/quickcontrols2/doc/images/qtquickcontrols2-basic-thumbnail.png new file mode 100644 index 00000000000..e971a7aaecc Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-basic-thumbnail.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-basic.png b/src/quickcontrols2/doc/images/qtquickcontrols2-basic.png new file mode 100644 index 00000000000..099db170385 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-basic.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-busyindicator-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-busyindicator-custom.png new file mode 100644 index 00000000000..fefae223efe Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-busyindicator-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-busyindicator.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-busyindicator.gif new file mode 100644 index 00000000000..653d200f3c6 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-busyindicator.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-busyindicator.png b/src/quickcontrols2/doc/images/qtquickcontrols2-busyindicator.png new file mode 100644 index 00000000000..4be09579bb6 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-busyindicator.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-button-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-button-custom.png new file mode 100644 index 00000000000..46d3e3eb5e9 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-button-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-button-flat.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-button-flat.gif new file mode 100644 index 00000000000..e2bd8b6fcf9 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-button-flat.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-button-highlighted.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-button-highlighted.gif new file mode 100644 index 00000000000..7de076d3d05 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-button-highlighted.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-button-icononly.png b/src/quickcontrols2/doc/images/qtquickcontrols2-button-icononly.png new file mode 100644 index 00000000000..9c8dd0f43fb Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-button-icononly.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-button-textbesideicon.png b/src/quickcontrols2/doc/images/qtquickcontrols2-button-textbesideicon.png new file mode 100644 index 00000000000..3dc64fb92b0 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-button-textbesideicon.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-button-textonly.png b/src/quickcontrols2/doc/images/qtquickcontrols2-button-textonly.png new file mode 100644 index 00000000000..737beb165fe Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-button-textonly.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-button-textundericon.png b/src/quickcontrols2/doc/images/qtquickcontrols2-button-textundericon.png new file mode 100644 index 00000000000..37c40c7c667 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-button-textundericon.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-button.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-button.gif new file mode 100644 index 00000000000..10d626a331a Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-button.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-checkbox-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-checkbox-custom.png new file mode 100644 index 00000000000..c6c3d1bcbd2 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-checkbox-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-checkbox-group.png b/src/quickcontrols2/doc/images/qtquickcontrols2-checkbox-group.png new file mode 100644 index 00000000000..d5a0d51be65 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-checkbox-group.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-checkbox-tristate.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-checkbox-tristate.gif new file mode 100644 index 00000000000..56a15867954 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-checkbox-tristate.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-checkbox.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-checkbox.gif new file mode 100644 index 00000000000..d70c0ee4b9c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-checkbox.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-checkdelegate-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-checkdelegate-custom.png new file mode 100644 index 00000000000..c0dd06892cb Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-checkdelegate-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-checkdelegate-tristate.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-checkdelegate-tristate.gif new file mode 100644 index 00000000000..8d058d6c54a Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-checkdelegate-tristate.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-checkdelegate.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-checkdelegate.gif new file mode 100644 index 00000000000..da3fab98a45 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-checkdelegate.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-combobox-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-combobox-custom.png new file mode 100644 index 00000000000..4f7206dc785 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-combobox-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-combobox-delegate.png b/src/quickcontrols2/doc/images/qtquickcontrols2-combobox-delegate.png new file mode 100644 index 00000000000..cf31064895c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-combobox-delegate.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-combobox-popup.png b/src/quickcontrols2/doc/images/qtquickcontrols2-combobox-popup.png new file mode 100644 index 00000000000..cf31064895c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-combobox-popup.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-combobox.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-combobox.gif new file mode 100644 index 00000000000..966a2d4ae51 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-combobox.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-control.png b/src/quickcontrols2/doc/images/qtquickcontrols2-control.png new file mode 100644 index 00000000000..0f004a89dd1 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-control.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-control.svg b/src/quickcontrols2/doc/images/qtquickcontrols2-control.svg new file mode 100644 index 00000000000..4b2057d197e --- /dev/null +++ b/src/quickcontrols2/doc/images/qtquickcontrols2-control.svg @@ -0,0 +1,936 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="760" + height="580" + viewBox="0 0 759.99997 579.99999" + id="svg2" + version="1.1" + inkscape:version="0.92.3 (2405546, 2018-03-11)" + sodipodi:docname="qtquickcontrols2-control.svg" + inkscape:export-filename="/home/jpnurmi/Projects/qt-dev/qtquickcontrols2/src/imports/controls/doc/images/qtquickcontrols2-control.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <defs + id="defs4"> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="Arrow1Mstart" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mstart" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4191" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="matrix(0.4,0,0,0.4,4,0)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="Arrow2Mend" + orient="auto" + refY="0" + refX="0" + id="Arrow2Mend" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4212" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + transform="scale(-0.6)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-2" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4318-4" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-9" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4327-1" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-3" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-9" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-0" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-5" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-9" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-2" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-1" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-2" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-9-6" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-2-2" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-1-1" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-2-7" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-2-5" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4318-4-7" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-9-4" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4327-1-1" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-1" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-8" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-96" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-4" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-9-6-4" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-2-2-7" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-1-1-6" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-2-7-8" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-2-5-6" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4318-4-7-2" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-9-4-8" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4327-1-1-9" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-2-5-6-9" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4318-4-7-2-6" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-9-4-8-4" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4327-1-1-9-8" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-1-7" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-8-9" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-96-7" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-4-4" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-2-5-6-9-1" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4318-4-7-2-6-7" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-9-4-8-4-0" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4327-1-1-9-8-6" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-1-9" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-8-3" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-96-3" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-4-46" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-2-5-6-9-5" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4318-4-7-2-6-6" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-9-4-8-4-1" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4327-1-1-9-8-7" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-1-9-7" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-8-3-7" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-96-3-2" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-4-46-3" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-2-5-6-9-5-8" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4318-4-7-2-6-6-1" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-9-4-8-4-1-3" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4327-1-1-9-8-7-6" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" /> + </marker> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.4142136" + inkscape:cx="138.75529" + inkscape:cy="425.28174" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="3840" + inkscape:window-height="2031" + inkscape:window-x="0" + inkscape:window-y="55" + inkscape:window-maximized="1" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + units="px" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(91.482322,-32.9581)"> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.05102265;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect4136" + width="518.94897" + height="298.94897" + x="29.043194" + y="193.48361" /> + <rect + style="fill:#ffd5d5;fill-opacity:1;stroke:none;stroke-width:0.83021182;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect4136-3" + width="440" + height="220" + x="68.517685" + y="232.9581" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff2a2a;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(1.1690183,0,0,1.1690183,115.80023,-231.31953)"><flowRegion + id="flowRegion4140" + style="fill:#ff2a2a"><rect + id="rect4142" + width="129.78784" + height="31.668232" + x="-34.519978" + y="400.22751" + style="font-size:15.41801071px;fill:#ff2a2a" /></flowRegion><flowPara + id="flowPara4144" + style="font-size:20.55734825px;line-height:1.25;fill:#ff2a2a">Background</flowPara><flowPara + id="flowPara4146" + style="font-size:20.55734825px;line-height:1.25;fill:#ff2a2a"> </flowPara></flowRoot> <rect + style="fill:#d7e3f4;fill-opacity:1;stroke:none;stroke-width:22.32431984;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.58381503" + id="rect4148" + width="360" + height="140" + x="108.51768" + y="272.95813" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0055d4;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,184.57261,41.294224)"><flowRegion + id="flowRegion4140-6" + style="fill:#0055d4"><rect + id="rect4142-6" + width="334.36047" + height="80.812172" + x="42.426407" + y="481.62601" + style="font-size:40px;fill:#0055d4" /></flowRegion><flowPara + id="flowPara4146-6" + style="font-size:40px;line-height:1.25;fill:#0055d4">Content item</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-1" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,247.75903,220.21488)"><flowRegion + id="flowRegion4140-6-9"><rect + id="rect4142-6-0" + width="270.72089" + height="68.690361" + x="42.426407" + y="481.62601" + style="font-size:25px;fill:#000000" /></flowRegion><flowPara + id="flowPara4146-6-2" + style="font-size:17.5px;line-height:1.25">Width</flowPara></flowRoot> <path + style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.93053311;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-3);marker-end:url(#TriangleOutL-0)" + d="M 33.168982,505.52033 H 543.32948" + id="path4179-8" + inkscape:connector-curvature="0" /> + <path + style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-9);marker-end:url(#TriangleOutL-1)" + d="M 16.517683,487.33858 V 198.57762" + id="path4179-9" + inkscape:connector-curvature="0" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6-1-7" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,-50.003525,47.195824)"><flowRegion + id="flowRegion4140-6-9-7"><rect + id="rect4142-6-0-5" + width="270.72089" + height="68.690361" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#000000" /></flowRegion><flowPara + id="flowPara4146-6-2-9" + style="font-size:17.5px;line-height:1.25;fill:#000000">Height</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-3" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,206.65956,-144.78636)"><flowRegion + id="flowRegion4140-6-67"><rect + id="rect4142-6-5" + width="334.36047" + height="80.812172" + x="42.426407" + y="481.62601" + style="font-size:60px;fill:#000000" /></flowRegion><flowPara + style="font-size:60px;line-height:1.25" + id="flowPara14323">Popup</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#0055d4;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,41.217752,149.93493)"><flowRegion + id="flowRegion4140-6-6-4-6" + style="text-align:center;text-anchor:middle;fill:#0055d4"><rect + id="rect4142-6-1-4-2" + width="252.53812" + height="61.619293" + x="42.426407" + y="481.62601" + style="font-size:17.5px;text-align:center;text-anchor:middle;fill:#0055d4" /></flowRegion><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#0055d4" + id="flowPara10048-9">Bottom</flowPara><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#0055d4" + id="flowPara5290">padding</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-1" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0055d4;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,384.82399,-69.046412)"><flowRegion + id="flowRegion4140-6-6-4-6-2" + style="fill:#0055d4"><rect + id="rect4142-6-1-4-2-7" + width="71.826065" + height="43.785866" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#0055d4" /></flowRegion><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#0055d4" + id="flowPara10048-9-0">Top</flowPara><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#0055d4" + id="flowPara4830">padding</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-9" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0055d4;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,458.14041,-0.80935844)"><flowRegion + id="flowRegion4140-6-6-4-6-3" + style="fill:#0055d4"><rect + id="rect4142-6-1-4-2-6" + width="81.109558" + height="93.762154" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#0055d4" /></flowRegion><flowPara + style="font-size:17.5px;line-height:125%;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#0055d4" + id="flowPara4386">Right padding</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-9-2" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0055d4;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,19.173452,87.133114)"><flowRegion + id="flowRegion4140-6-6-4-6-3-5" + style="fill:#0055d4"><rect + id="rect4142-6-1-4-2-6-4" + width="81.109558" + height="93.762154" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#0055d4" /></flowRegion><flowPara + style="font-size:17.02554321px;line-height:125%;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#0055d4" + id="flowPara4386-0">Left padding</flowPara></flowRoot> <path + style="fill:#ff2a2a;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:0.87824047;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-9-6);marker-end:url(#TriangleOutL-1-1)" + d="M 72.916183,227.96278 V 198.98852" + id="path4179-9-8" + inkscape:connector-curvature="0" /> + <path + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:0.87323481;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-2-5);marker-end:url(#TriangleOutL-9-4)" + d="M 34.529058,238.58445 H 63.562954" + id="path4179-7-8" + inkscape:connector-curvature="0" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-1-5" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff2a2a;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,47.895402,-88.000508)"><flowRegion + id="flowRegion4140-6-6-4-6-2-9" + style="fill:#ff2a2a"><rect + id="rect4142-6-1-4-2-7-7" + width="66.476036" + height="55.080368" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#ff2a2a" /></flowRegion><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ff2a2a" + id="flowPara11237">Top inset</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-9-2-3" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff2a2a;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,0.4414194,-43.952242)"><flowRegion + id="flowRegion4140-6-6-4-6-3-5-8" + style="fill:#ff2a2a"><rect + id="rect4142-6-1-4-2-6-4-8" + width="75.759529" + height="93.167732" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#ff2a2a" /></flowRegion><flowPara + style="font-size:17.02554321px;line-height:125%;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ff2a2a" + id="flowPara4386-0-3">Left inset</flowPara></flowRoot> <path + style="fill:#0055d4;fill-rule:evenodd;stroke:#0055d4;stroke-width:0.97500122;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-1);marker-end:url(#TriangleOutL-96)" + d="M 462.28757,267.38769 V 199.50991" + id="path4179-3" + inkscape:connector-curvature="0" /> + <path + style="fill:#ff2a2a;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:0.87794411;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-9-6-4);marker-end:url(#TriangleOutL-1-1-6)" + d="M 504.22784,486.94146 V 457.98675" + id="path4179-9-8-9" + inkscape:connector-curvature="0" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-1-5-0" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff2a2a;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,424.36985,170.98794)"><flowRegion + id="flowRegion4140-6-6-4-6-2-9-6" + style="fill:#ff2a2a"><rect + id="rect4142-6-1-4-2-7-7-8" + width="91.442841" + height="44.974762" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#ff2a2a" /></flowRegion><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ff2a2a" + id="flowPara11237-7">Bottom inset</flowPara></flowRoot> <path + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:0.87314719;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-2-5-6);marker-end:url(#TriangleOutL-9-4-8)" + d="M 513.47562,448.6218 H 542.5037" + id="path4179-7-8-6" + inkscape:connector-curvature="0" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-9-2-3-0" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff2a2a;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,479.24023,126.32002)"><flowRegion + id="flowRegion4140-6-6-4-6-3-5-8-7" + style="fill:#ff2a2a"><rect + id="rect4142-6-1-4-2-6-4-8-0" + width="75.759529" + height="93.167732" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#ff2a2a" /></flowRegion><flowPara + style="font-size:17.02554321px;line-height:125%;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ff2a2a" + id="flowPara3807">Right inset</flowPara></flowRoot> <path + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.05938387;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-2-5-6-9);marker-end:url(#TriangleOutL-9-4-8-4)" + d="m 474.52523,278.31524 h 66.93934" + id="path4179-7-8-6-0" + inkscape:connector-curvature="0" /> + <path + style="fill:#0055d4;fill-rule:evenodd;stroke:#0055d4;stroke-width:0.97513783;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-1-7);marker-end:url(#TriangleOutL-96-7)" + d="M 114.58911,486.37854 V 418.48175" + id="path4179-3-9" + inkscape:connector-curvature="0" /> + <path + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.05900466;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-2-5-6-9-1);marker-end:url(#TriangleOutL-9-4-8-4-0)" + d="M 35.582232,406.88667 H 102.47366" + id="path4179-7-8-6-0-0" + inkscape:connector-curvature="0" /> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.38;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect4136-9" + width="638.62036" + height="418.6203" + x="-30.792475" + y="133.64795" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6-3-8" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,192.12072,-213.92909)"><flowRegion + id="flowRegion4140-6-67-1"><rect + id="rect4142-6-5-6" + width="334.36047" + height="80.812172" + x="42.426407" + y="481.62601" + style="font-size:60px;fill:#000000" /></flowRegion><flowPara + style="font-size:60px;line-height:1.25" + id="flowPara14323-3">Window</flowPara></flowRoot> <path + style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.83036995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-1-9);marker-end:url(#TriangleOutL-96-3)" + d="M 16.507747,188.209 V 138.97553" + id="path4179-3-1" + inkscape:connector-curvature="0" /> + <path + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.90094262;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-2-5-6-9-5);marker-end:url(#TriangleOutL-9-4-8-4-1)" + d="m 553.67227,505.52244 h 48.41379" + id="path4179-7-8-6-0-2" + inkscape:connector-curvature="0" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-1-2" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,-53.285062,-138.90295)"><flowRegion + id="flowRegion4140-6-6-4-6-2-92" + style="fill:#000000"><rect + id="rect4142-6-1-4-2-7-8" + width="71.826065" + height="43.785866" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#000000" /></flowRegion><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#000000" + id="flowPara10048-9-0-1">Top</flowPara><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#000000" + id="flowPara4830-2">margin</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-1-2-4" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,530.78767,225.71855)"><flowRegion + id="flowRegion4140-6-6-4-6-2-92-7" + style="fill:#000000"><rect + id="rect4142-6-1-4-2-7-8-8" + width="71.826065" + height="43.785866" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#000000" /></flowRegion><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#000000" + id="flowPara10048-9-0-1-6">Right</flowPara><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#000000" + id="flowPara4830-2-3">margin</flowPara></flowRoot> <path + style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.83036995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-1-9-7);marker-end:url(#TriangleOutL-96-3-2)" + d="M 16.459117,546.78218 V 497.54871" + id="path4179-3-1-7" + inkscape:connector-curvature="0" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-1-2-2" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,-0.06072146,225.50386)"><flowRegion + id="flowRegion4140-6-6-4-6-2-92-5" + style="fill:#000000"><rect + id="rect4142-6-1-4-2-7-8-3" + width="71.826065" + height="43.785866" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#000000" /></flowRegion><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#000000" + id="flowPara10048-9-0-1-7">Bottom</flowPara><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#000000" + id="flowPara4830-2-6">margin</flowPara></flowRoot> <path + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.89733517;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-2-5-6-9-5-8);marker-end:url(#TriangleOutL-9-4-8-4-1-3)" + d="M -25.075855,505.54405 H 22.951007" + id="path4179-7-8-6-0-2-4" + inkscape:connector-curvature="0" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-1-2-2-0" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,-55.529842,180.17847)"><flowRegion + id="flowRegion4140-6-6-4-6-2-92-5-3" + style="fill:#000000"><rect + id="rect4142-6-1-4-2-7-8-3-5" + width="71.826065" + height="43.785866" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#000000" /></flowRegion><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#000000" + id="flowPara10048-9-0-1-7-8">Left</flowPara><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#000000" + id="flowPara4830-2-6-5">margin</flowPara></flowRoot> </g> +</svg> diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-customize-buttons.png b/src/quickcontrols2/doc/images/qtquickcontrols2-customize-buttons.png new file mode 100644 index 00000000000..551e8a0cf7c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-customize-buttons.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-delaybutton-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-delaybutton-custom.png new file mode 100644 index 00000000000..a7bd7c19d84 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-delaybutton-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-delaybutton.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-delaybutton.gif new file mode 100644 index 00000000000..16a198f9cb4 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-delaybutton.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-dial-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-dial-custom.png new file mode 100644 index 00000000000..6312c999333 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-dial-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-dial-handle.png b/src/quickcontrols2/doc/images/qtquickcontrols2-dial-handle.png new file mode 100644 index 00000000000..9e22b2e7093 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-dial-handle.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-dial-inputMode.svgz b/src/quickcontrols2/doc/images/qtquickcontrols2-dial-inputMode.svgz new file mode 100644 index 00000000000..005ab7b331b Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-dial-inputMode.svgz differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-dial-inputmode.png b/src/quickcontrols2/doc/images/qtquickcontrols2-dial-inputmode.png new file mode 100644 index 00000000000..5bbc41a49c3 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-dial-inputmode.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-dial-no-wrap.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-dial-no-wrap.gif new file mode 100644 index 00000000000..24f6790b6de Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-dial-no-wrap.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-dial-wrap.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-dial-wrap.gif new file mode 100644 index 00000000000..cfb1fb5b10a Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-dial-wrap.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-dial.png b/src/quickcontrols2/doc/images/qtquickcontrols2-dial.png new file mode 100644 index 00000000000..71c54113b75 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-dial.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-dialogbuttonbox-attached.png b/src/quickcontrols2/doc/images/qtquickcontrols2-dialogbuttonbox-attached.png new file mode 100644 index 00000000000..c17f38ac0c3 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-dialogbuttonbox-attached.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-dialogbuttonbox.png b/src/quickcontrols2/doc/images/qtquickcontrols2-dialogbuttonbox.png new file mode 100644 index 00000000000..33b5f45f4f5 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-dialogbuttonbox.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-drawer-expanded-wireframe.png b/src/quickcontrols2/doc/images/qtquickcontrols2-drawer-expanded-wireframe.png new file mode 100644 index 00000000000..0c92f865874 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-drawer-expanded-wireframe.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-drawer-wireframe.png b/src/quickcontrols2/doc/images/qtquickcontrols2-drawer-wireframe.png new file mode 100644 index 00000000000..74806f17b77 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-drawer-wireframe.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-drawer.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-drawer.gif new file mode 100644 index 00000000000..736f34f66f1 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-drawer.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-frame-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-frame-custom.png new file mode 100644 index 00000000000..f628b20c20a Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-frame-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-frame.png b/src/quickcontrols2/doc/images/qtquickcontrols2-frame.png new file mode 100644 index 00000000000..e3cb31dc71a Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-frame.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-fusion-palettes.png b/src/quickcontrols2/doc/images/qtquickcontrols2-fusion-palettes.png new file mode 100644 index 00000000000..d8061161670 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-fusion-palettes.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-fusion-thumbnail.png b/src/quickcontrols2/doc/images/qtquickcontrols2-fusion-thumbnail.png new file mode 100644 index 00000000000..c270c6efbab Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-fusion-thumbnail.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-fusion-violet.png b/src/quickcontrols2/doc/images/qtquickcontrols2-fusion-violet.png new file mode 100644 index 00000000000..99e5b597866 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-fusion-violet.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-fusion.png b/src/quickcontrols2/doc/images/qtquickcontrols2-fusion.png new file mode 100644 index 00000000000..7119ef225d2 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-fusion.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-groupbox-checkable.png b/src/quickcontrols2/doc/images/qtquickcontrols2-groupbox-checkable.png new file mode 100644 index 00000000000..820ad79c80b Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-groupbox-checkable.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-groupbox-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-groupbox-custom.png new file mode 100644 index 00000000000..029679ced08 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-groupbox-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-groupbox-label.png b/src/quickcontrols2/doc/images/qtquickcontrols2-groupbox-label.png new file mode 100644 index 00000000000..c26795a7a76 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-groupbox-label.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-groupbox.png b/src/quickcontrols2/doc/images/qtquickcontrols2-groupbox.png new file mode 100644 index 00000000000..ea2f9ea5c5e Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-groupbox.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-4x.png b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-4x.png new file mode 100644 index 00000000000..bab99a5e557 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-4x.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-inset-boundaries.png b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-inset-boundaries.png new file mode 100644 index 00000000000..c42df81edcb Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-inset-boundaries.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-inset.png b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-inset.png new file mode 100644 index 00000000000..0627d085901 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-inset.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-resized-padding.png b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-resized-padding.png new file mode 100644 index 00000000000..0a606c9926e Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-resized-padding.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-resized-stretchable.png b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-resized-stretchable.png new file mode 100644 index 00000000000..9598b13a1c0 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-resized-stretchable.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-size.png b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-size.png new file mode 100644 index 00000000000..db6453758fe Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch-size.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch.svgz b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch.svgz new file mode 100644 index 00000000000..5a1a1094d19 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-9-patch.svgz differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-customization-dark.png b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-customization-dark.png new file mode 100644 index 00000000000..144ac97c87c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-customization-dark.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-customization.svgz b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-customization.svgz new file mode 100644 index 00000000000..fb8305638b2 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-customization.svgz differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-thumbnail.png b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-thumbnail.png new file mode 100644 index 00000000000..ecf2bb163dd Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine-thumbnail.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-imagine.png b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine.png new file mode 100644 index 00000000000..ffe2c267b2b Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-imagine.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-itemdelegate-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-itemdelegate-custom.png new file mode 100644 index 00000000000..35f8892f163 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-itemdelegate-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-itemdelegate.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-itemdelegate.gif new file mode 100644 index 00000000000..dccb6efcdbc Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-itemdelegate.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-itemdelegate.png b/src/quickcontrols2/doc/images/qtquickcontrols2-itemdelegate.png new file mode 100644 index 00000000000..7242f343a04 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-itemdelegate.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-label-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-label-custom.png new file mode 100644 index 00000000000..5730ff23bf2 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-label-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-label.png b/src/quickcontrols2/doc/images/qtquickcontrols2-label.png new file mode 100644 index 00000000000..0bafcf86020 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-label.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-macos-dark.png b/src/quickcontrols2/doc/images/qtquickcontrols2-macos-dark.png new file mode 100644 index 00000000000..97d8a5a4e72 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-macos-dark.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-macos-light.png b/src/quickcontrols2/doc/images/qtquickcontrols2-macos-light.png new file mode 100644 index 00000000000..4a598ad498c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-macos-light.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-macos-thumbnail.png b/src/quickcontrols2/doc/images/qtquickcontrols2-macos-thumbnail.png new file mode 100644 index 00000000000..57fd98d63a7 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-macos-thumbnail.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-material-accent.png b/src/quickcontrols2/doc/images/qtquickcontrols2-material-accent.png new file mode 100644 index 00000000000..a85afc68ede Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-material-accent.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-material-attributes.png b/src/quickcontrols2/doc/images/qtquickcontrols2-material-attributes.png new file mode 100644 index 00000000000..bb54071d79c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-material-attributes.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-material-background.png b/src/quickcontrols2/doc/images/qtquickcontrols2-material-background.png new file mode 100644 index 00000000000..62028f523c9 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-material-background.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-material-dark.png b/src/quickcontrols2/doc/images/qtquickcontrols2-material-dark.png new file mode 100644 index 00000000000..f6e45b3b1c7 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-material-dark.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-material-elevation.png b/src/quickcontrols2/doc/images/qtquickcontrols2-material-elevation.png new file mode 100644 index 00000000000..d152f14529e Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-material-elevation.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-material-foreground.png b/src/quickcontrols2/doc/images/qtquickcontrols2-material-foreground.png new file mode 100644 index 00000000000..0d0e1b651a3 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-material-foreground.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-material-light.png b/src/quickcontrols2/doc/images/qtquickcontrols2-material-light.png new file mode 100644 index 00000000000..c9abe2cb8bd Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-material-light.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-material-purple.png b/src/quickcontrols2/doc/images/qtquickcontrols2-material-purple.png new file mode 100644 index 00000000000..b955736b0b0 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-material-purple.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-material-theme.png b/src/quickcontrols2/doc/images/qtquickcontrols2-material-theme.png new file mode 100644 index 00000000000..1d09a82580c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-material-theme.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-material-thumbnail.png b/src/quickcontrols2/doc/images/qtquickcontrols2-material-thumbnail.png new file mode 100644 index 00000000000..d758ff18033 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-material-thumbnail.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-material-variant-dense.png b/src/quickcontrols2/doc/images/qtquickcontrols2-material-variant-dense.png new file mode 100644 index 00000000000..02f39b78852 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-material-variant-dense.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-material-variant-normal.png b/src/quickcontrols2/doc/images/qtquickcontrols2-material-variant-normal.png new file mode 100644 index 00000000000..c1e366c5317 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-material-variant-normal.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-menu-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-menu-custom.png new file mode 100644 index 00000000000..922bf591b59 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-menu-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-menu.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-menu.gif new file mode 100644 index 00000000000..93a873a33ae Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-menu.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-menu.png b/src/quickcontrols2/doc/images/qtquickcontrols2-menu.png new file mode 100644 index 00000000000..926c33eed27 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-menu.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-menubar-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-menubar-custom.png new file mode 100644 index 00000000000..b6007e466d9 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-menubar-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-menubar.png b/src/quickcontrols2/doc/images/qtquickcontrols2-menubar.png new file mode 100644 index 00000000000..873b7a19609 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-menubar.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-menuseparator-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-menuseparator-custom.png new file mode 100644 index 00000000000..78635b9c885 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-menuseparator-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-menuseparator.png b/src/quickcontrols2/doc/images/qtquickcontrols2-menuseparator.png new file mode 100644 index 00000000000..35307817f6e Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-menuseparator.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-page-wireframe.png b/src/quickcontrols2/doc/images/qtquickcontrols2-page-wireframe.png new file mode 100644 index 00000000000..f612c243c4e Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-page-wireframe.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-pageindicator-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-pageindicator-custom.png new file mode 100644 index 00000000000..a767a51aa0d Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-pageindicator-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-pageindicator-delegate.png b/src/quickcontrols2/doc/images/qtquickcontrols2-pageindicator-delegate.png new file mode 100644 index 00000000000..95acde70cf4 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-pageindicator-delegate.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-pageindicator.png b/src/quickcontrols2/doc/images/qtquickcontrols2-pageindicator.png new file mode 100644 index 00000000000..e2a0a157f64 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-pageindicator.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-pane-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-pane-custom.png new file mode 100644 index 00000000000..03a0369f566 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-pane-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-pane.png b/src/quickcontrols2/doc/images/qtquickcontrols2-pane.png new file mode 100644 index 00000000000..3801cc3efb3 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-pane.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-popup-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-popup-custom.png new file mode 100644 index 00000000000..cb7813d3870 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-popup-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-popup-settings.png b/src/quickcontrols2/doc/images/qtquickcontrols2-popup-settings.png new file mode 100644 index 00000000000..5122158ef42 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-popup-settings.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-popup-transformorigin.png b/src/quickcontrols2/doc/images/qtquickcontrols2-popup-transformorigin.png new file mode 100644 index 00000000000..16d26177861 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-popup-transformorigin.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-popup.png b/src/quickcontrols2/doc/images/qtquickcontrols2-popup.png new file mode 100644 index 00000000000..8fc424a854a Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-popup.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-popup.svg b/src/quickcontrols2/doc/images/qtquickcontrols2-popup.svg new file mode 100644 index 00000000000..e39f3dce214 --- /dev/null +++ b/src/quickcontrols2/doc/images/qtquickcontrols2-popup.svg @@ -0,0 +1,712 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="640" + height="420" + viewBox="0 0 639.99997 419.99999" + id="svg2" + version="1.1" + inkscape:version="0.92.3 (2405546, 2018-03-11)" + sodipodi:docname="qtquickcontrols2-control.svg" + inkscape:export-filename="/home/jpnurmi/Projects/qt-dev/qtquickcontrols2/src/imports/controls/doc/images/qtquickcontrols2-control.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <defs + id="defs4"> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="Arrow1Mstart" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mstart" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4191" + d="M 0,0 5,-5 -12.5,0 5,5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="matrix(0.4,0,0,0.4,4,0)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="Arrow2Mend" + orient="auto" + refY="0" + refX="0" + id="Arrow2Mend" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4212" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + transform="scale(-0.6)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-2" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4318-4" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-9" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4327-1" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-3" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-9" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-0" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-5" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-9" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-2" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-1" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-2" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-9-6" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-2-2" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-1-1" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-2-7" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-2-5" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4318-4-7" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-9-4" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4327-1-1" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-1" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-8" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-96" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-4" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-9-6-4" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-2-2-7" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-1-1-6" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-2-7-8" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-2-5-6" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4318-4-7-2" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-9-4-8" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4327-1-1-9" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-2-5-6-9" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4318-4-7-2-6" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-9-4-8-4" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4327-1-1-9-8" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-1-7" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4318-8-9" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-96-7" + style="overflow:visible" + inkscape:isstock="true"> + <path + id="path4327-4-4" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="TriangleInL" + orient="auto" + refY="0" + refX="0" + id="TriangleInL-2-5-6-9-1" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4318-4-7-2-6-7" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(-0.8)" /> + </marker> + <marker + inkscape:stockid="TriangleOutL" + orient="auto" + refY="0" + refX="0" + id="TriangleOutL-9-4-8-4-0" + style="overflow:visible" + inkscape:isstock="true"> + <path + inkscape:connector-curvature="0" + id="path4327-1-1-9-8-6" + d="M 5.77,0 -2.88,5 V -5 Z" + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.00000003pt;stroke-opacity:1" + transform="scale(0.8)" /> + </marker> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2.8284271" + inkscape:cx="328.65009" + inkscape:cy="205.42326" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="3840" + inkscape:window-height="2031" + inkscape:window-x="0" + inkscape:window-y="55" + inkscape:window-maximized="1" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + units="px" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(91.482322,-192.9581)"> + <rect + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.05102265;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect4136" + width="518.94897" + height="298.94897" + x="-30.956812" + y="253.48361" /> + <rect + style="fill:#ffd5d5;fill-opacity:1;stroke:none;stroke-width:0.83021182;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect4136-3" + width="440" + height="220" + x="8.5176783" + y="292.9581" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff2a2a;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(1.1690183,0,0,1.1690183,55.80022,-171.31953)"><flowRegion + id="flowRegion4140" + style="fill:#ff2a2a"><rect + id="rect4142" + width="129.78784" + height="31.668232" + x="-34.519978" + y="400.22751" + style="font-size:15.41801071px;fill:#ff2a2a" /></flowRegion><flowPara + id="flowPara4144" + style="font-size:20.55734825px;line-height:1.25;fill:#ff2a2a">Background</flowPara><flowPara + id="flowPara4146" + style="font-size:20.55734825px;line-height:1.25;fill:#ff2a2a"> </flowPara></flowRoot> <rect + style="fill:#d7e3f4;fill-opacity:1;stroke:none;stroke-width:22.32431984;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.58381503" + id="rect4148" + width="360" + height="140" + x="48.517677" + y="332.95813" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0055d4;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,124.5726,101.29422)"><flowRegion + id="flowRegion4140-6" + style="fill:#0055d4"><rect + id="rect4142-6" + width="334.36047" + height="80.812172" + x="42.426407" + y="481.62601" + style="font-size:40px;fill:#0055d4" /></flowRegion><flowPara + id="flowPara4146-6" + style="font-size:40px;line-height:1.25;fill:#0055d4">Content item</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-1" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,187.75902,280.21488)"><flowRegion + id="flowRegion4140-6-9"><rect + id="rect4142-6-0" + width="270.72089" + height="68.690361" + x="42.426407" + y="481.62601" + style="font-size:25px;fill:#000000" /></flowRegion><flowPara + id="flowPara4146-6-2" + style="font-size:17.5px;line-height:1.25">Width</flowPara></flowRoot> <path + style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.93053311;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-3);marker-end:url(#TriangleOutL-0)" + d="M -26.831023,563.52033 H 483.32947" + id="path4179-8" + inkscape:connector-curvature="0" /> + <path + style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-9);marker-end:url(#TriangleOutL-1)" + d="M -41.482322,547.33858 V 258.57762" + id="path4179-9" + inkscape:connector-curvature="0" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6-1-7" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,-110.00353,107.19582)"><flowRegion + id="flowRegion4140-6-9-7"><rect + id="rect4142-6-0-5" + width="270.72089" + height="68.690361" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#000000" /></flowRegion><flowPara + id="flowPara4146-6-2-9" + style="font-size:17.5px;line-height:1.25;fill:#000000">Height</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-3" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,138.50125,-84.786365)"><flowRegion + id="flowRegion4140-6-67"><rect + id="rect4142-6-5" + width="334.36047" + height="80.812172" + x="42.426407" + y="481.62601" + style="font-size:60px;fill:#000000" /></flowRegion><flowPara + id="flowPara4146-6-3" + style="font-size:60px;line-height:1.25">Control</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#0055d4;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,-18.782253,209.93493)"><flowRegion + id="flowRegion4140-6-6-4-6" + style="text-align:center;text-anchor:middle;fill:#0055d4"><rect + id="rect4142-6-1-4-2" + width="252.53812" + height="61.619293" + x="42.426407" + y="481.62601" + style="font-size:17.5px;text-align:center;text-anchor:middle;fill:#0055d4" /></flowRegion><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#0055d4" + id="flowPara10048-9">Bottom</flowPara><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#0055d4" + id="flowPara5290">padding</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-1" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0055d4;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,324.82398,-9.0464154)"><flowRegion + id="flowRegion4140-6-6-4-6-2" + style="fill:#0055d4"><rect + id="rect4142-6-1-4-2-7" + width="71.826065" + height="43.785866" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#0055d4" /></flowRegion><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#0055d4" + id="flowPara10048-9-0">Top</flowPara><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#0055d4" + id="flowPara4830">padding</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-9" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0055d4;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,398.1404,59.190638)"><flowRegion + id="flowRegion4140-6-6-4-6-3" + style="fill:#0055d4"><rect + id="rect4142-6-1-4-2-6" + width="81.109558" + height="93.762154" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#0055d4" /></flowRegion><flowPara + style="font-size:17.5px;line-height:125%;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#0055d4" + id="flowPara4386">Right padding</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-9-2" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0055d4;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,-40.826553,147.13311)"><flowRegion + id="flowRegion4140-6-6-4-6-3-5" + style="fill:#0055d4"><rect + id="rect4142-6-1-4-2-6-4" + width="81.109558" + height="93.762154" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#0055d4" /></flowRegion><flowPara + style="font-size:17.02554321px;line-height:125%;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#0055d4" + id="flowPara4386-0">Left padding</flowPara></flowRoot> <path + style="fill:#ff2a2a;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:0.87824047;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-9-6);marker-end:url(#TriangleOutL-1-1)" + d="M 12.916178,287.96278 V 258.98852" + id="path4179-9-8" + inkscape:connector-curvature="0" /> + <path + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:0.87323481;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-2-5);marker-end:url(#TriangleOutL-9-4)" + d="M -25.470947,298.58445 H 3.5629489" + id="path4179-7-8" + inkscape:connector-curvature="0" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-1-5" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff2a2a;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,-12.104603,-28.000512)"><flowRegion + id="flowRegion4140-6-6-4-6-2-9" + style="fill:#ff2a2a"><rect + id="rect4142-6-1-4-2-7-7" + width="66.476036" + height="55.080368" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#ff2a2a" /></flowRegion><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ff2a2a" + id="flowPara11237">Top inset</flowPara></flowRoot> <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-9-2-3" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff2a2a;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,-59.558586,16.047754)"><flowRegion + id="flowRegion4140-6-6-4-6-3-5-8" + style="fill:#ff2a2a"><rect + id="rect4142-6-1-4-2-6-4-8" + width="75.759529" + height="93.167732" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#ff2a2a" /></flowRegion><flowPara + style="font-size:17.02554321px;line-height:125%;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ff2a2a" + id="flowPara4386-0-3">Left inset</flowPara></flowRoot> <path + style="fill:#0055d4;fill-rule:evenodd;stroke:#0055d4;stroke-width:0.97500122;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-1);marker-end:url(#TriangleOutL-96)" + d="M 402.28756,327.38769 V 259.50991" + id="path4179-3" + inkscape:connector-curvature="0" /> + <path + style="fill:#ff2a2a;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:0.87794411;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-9-6-4);marker-end:url(#TriangleOutL-1-1-6)" + d="M 444.22783,546.94146 V 517.98675" + id="path4179-9-8-9" + inkscape:connector-curvature="0" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-1-5-0" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff2a2a;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,364.36984,230.98794)"><flowRegion + id="flowRegion4140-6-6-4-6-2-9-6" + style="fill:#ff2a2a"><rect + id="rect4142-6-1-4-2-7-7-8" + width="91.442841" + height="44.974762" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#ff2a2a" /></flowRegion><flowPara + style="font-size:17.5px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ff2a2a" + id="flowPara11237-7">Bottom inset</flowPara></flowRoot> <path + style="fill:#ff2a2a;fill-opacity:1;fill-rule:evenodd;stroke:#ff2a2a;stroke-width:0.87314719;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-2-5-6);marker-end:url(#TriangleOutL-9-4-8)" + d="m 453.47561,508.6218 h 29.02808" + id="path4179-7-8-6" + inkscape:connector-curvature="0" /> + <flowRoot + xml:space="preserve" + id="flowRoot4138-6-2-7-5-9-2-3-0" + style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ff2a2a;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + transform="matrix(0.6007979,0,0,0.6007979,419.24022,186.32002)"><flowRegion + id="flowRegion4140-6-6-4-6-3-5-8-7" + style="fill:#ff2a2a"><rect + id="rect4142-6-1-4-2-6-4-8-0" + width="75.759529" + height="93.167732" + x="42.426407" + y="481.62601" + style="font-size:17.5px;fill:#ff2a2a" /></flowRegion><flowPara + style="font-size:17.02554321px;line-height:125%;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ff2a2a" + id="flowPara3807">Right inset</flowPara></flowRoot> <path + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.05938387;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-2-5-6-9);marker-end:url(#TriangleOutL-9-4-8-4)" + d="m 414.52522,338.31524 h 66.93934" + id="path4179-7-8-6-0" + inkscape:connector-curvature="0" /> + <path + style="fill:#0055d4;fill-rule:evenodd;stroke:#0055d4;stroke-width:0.97513783;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-1-7);marker-end:url(#TriangleOutL-96-7)" + d="M 54.589106,546.37854 V 478.48175" + id="path4179-3-9" + inkscape:connector-curvature="0" /> + <path + style="fill:#0055d4;fill-opacity:1;fill-rule:evenodd;stroke:#0055d4;stroke-width:1.05900466;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInL-2-5-6-9-1);marker-end:url(#TriangleOutL-9-4-8-4-0)" + d="M -24.417773,466.88667 H 42.473651" + id="path4179-7-8-6-0-0" + inkscape:connector-curvature="0" /> + </g> +</svg> diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-progressbar-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-progressbar-custom.png new file mode 100644 index 00000000000..9d73df2c259 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-progressbar-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-progressbar-indeterminate.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-progressbar-indeterminate.gif new file mode 100644 index 00000000000..d6756d16fd5 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-progressbar-indeterminate.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-progressbar.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-progressbar.gif new file mode 100644 index 00000000000..49af5f45a1b Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-progressbar.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-radiobutton-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-radiobutton-custom.png new file mode 100644 index 00000000000..5c85179f70b Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-radiobutton-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-radiobutton.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-radiobutton.gif new file mode 100644 index 00000000000..4cbf3ed9d68 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-radiobutton.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-radiodelegate-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-radiodelegate-custom.png new file mode 100644 index 00000000000..7d32699bf9c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-radiodelegate-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-radiodelegate.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-radiodelegate.gif new file mode 100644 index 00000000000..b6afd6fe6a4 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-radiodelegate.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-rangeslider-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-rangeslider-custom.png new file mode 100644 index 00000000000..47379a300d3 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-rangeslider-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-rangeslider.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-rangeslider.gif new file mode 100644 index 00000000000..db565b0a931 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-rangeslider.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-roundbutton.png b/src/quickcontrols2/doc/images/qtquickcontrols2-roundbutton.png new file mode 100644 index 00000000000..4dce37f2394 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-roundbutton.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-custom.png new file mode 100644 index 00000000000..690bc8beef6 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-non-attached.png b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-non-attached.png new file mode 100644 index 00000000000..eba363dda2d Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-non-attached.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-nosnap.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-nosnap.gif new file mode 100644 index 00000000000..f61ac5b46a3 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-nosnap.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-snapalways.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-snapalways.gif new file mode 100644 index 00000000000..438d4a33184 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-snapalways.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-snaponrelease.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-snaponrelease.gif new file mode 100644 index 00000000000..c2fa67b027d Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar-snaponrelease.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar.gif new file mode 100644 index 00000000000..ed3ab607d9f Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollbar.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-scrollindicator-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollindicator-custom.png new file mode 100644 index 00000000000..b1183bc52a2 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollindicator-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-scrollindicator-non-attached.png b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollindicator-non-attached.png new file mode 100644 index 00000000000..a61e0487436 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollindicator-non-attached.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-scrollindicator.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollindicator.gif new file mode 100644 index 00000000000..73007820f87 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollindicator.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-scrollview-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollview-custom.png new file mode 100644 index 00000000000..8f4bd928634 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollview-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-scrollview-wireframe.png b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollview-wireframe.png new file mode 100644 index 00000000000..8a39056aa99 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollview-wireframe.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-scrollview.png b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollview.png new file mode 100644 index 00000000000..1a4039e1fdc Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-scrollview.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-selectionrectangle.png b/src/quickcontrols2/doc/images/qtquickcontrols2-selectionrectangle.png new file mode 100644 index 00000000000..69e47b29095 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-selectionrectangle.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-slider-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-slider-custom.png new file mode 100644 index 00000000000..dbbacb343f4 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-slider-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-slider-handle.png b/src/quickcontrols2/doc/images/qtquickcontrols2-slider-handle.png new file mode 100644 index 00000000000..5450d574807 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-slider-handle.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-slider-nosnap.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-slider-nosnap.gif new file mode 100644 index 00000000000..ab233c5b931 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-slider-nosnap.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-slider-snapalways.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-slider-snapalways.gif new file mode 100644 index 00000000000..8eb4011fb50 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-slider-snapalways.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-slider-snaponrelease.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-slider-snaponrelease.gif new file mode 100644 index 00000000000..f3b1d5c7a93 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-slider-snaponrelease.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-slider.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-slider.gif new file mode 100644 index 00000000000..2ee56334e02 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-slider.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-custom.png new file mode 100644 index 00000000000..d1e883fc56a Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-double.png b/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-double.png new file mode 100644 index 00000000000..d3f5876c4a3 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-double.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-down.png b/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-down.png new file mode 100644 index 00000000000..1d5dcf7b444 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-down.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-textual.png b/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-textual.png new file mode 100644 index 00000000000..5513d6e67dd Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-textual.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-up.png b/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-up.png new file mode 100644 index 00000000000..1ee1c4798eb Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox-up.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox.png b/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox.png new file mode 100644 index 00000000000..835bb1d67dc Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-spinbox.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-splitview-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-splitview-custom.png new file mode 100644 index 00000000000..da820ccafee Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-splitview-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-custom.png new file mode 100644 index 00000000000..5ee6049e746 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-pop.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-pop.gif new file mode 100644 index 00000000000..1971c2e004c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-pop.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-push.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-push.gif new file mode 100644 index 00000000000..0218cc0f2fe Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-push.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-replace.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-replace.gif new file mode 100644 index 00000000000..63a6b2b4b5c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-replace.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-unwind.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-unwind.gif new file mode 100644 index 00000000000..28c051d8665 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-unwind.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-visible.png b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-visible.png new file mode 100644 index 00000000000..d937b417e60 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-visible.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-wireframe.png b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-wireframe.png new file mode 100644 index 00000000000..f28b5c67ded Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-stackview-wireframe.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-styles.png b/src/quickcontrols2/doc/images/qtquickcontrols2-styles.png new file mode 100644 index 00000000000..992dd47eba5 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-styles.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-swipedelegate-behind.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-swipedelegate-behind.gif new file mode 100644 index 00000000000..97d6a592775 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-swipedelegate-behind.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-swipedelegate-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-swipedelegate-custom.png new file mode 100644 index 00000000000..5813b73cf49 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-swipedelegate-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-swipedelegate-leading-trailing.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-swipedelegate-leading-trailing.gif new file mode 100644 index 00000000000..0641bd14008 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-swipedelegate-leading-trailing.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-swipedelegate.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-swipedelegate.gif new file mode 100644 index 00000000000..86c380b7b39 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-swipedelegate.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-swipeview-indicator.png b/src/quickcontrols2/doc/images/qtquickcontrols2-swipeview-indicator.png new file mode 100644 index 00000000000..998ec9f7c98 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-swipeview-indicator.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-swipeview-wireframe.png b/src/quickcontrols2/doc/images/qtquickcontrols2-swipeview-wireframe.png new file mode 100644 index 00000000000..3cc2b83c4b9 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-swipeview-wireframe.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-swipeview.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-swipeview.gif new file mode 100644 index 00000000000..4af26c10588 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-swipeview.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-switch-checked.png b/src/quickcontrols2/doc/images/qtquickcontrols2-switch-checked.png new file mode 100644 index 00000000000..7a0cde1bad5 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-switch-checked.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-switch-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-switch-custom.png new file mode 100644 index 00000000000..6d535ef96fc Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-switch-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-switch.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-switch.gif new file mode 100644 index 00000000000..5f956304a0b Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-switch.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-switch.png b/src/quickcontrols2/doc/images/qtquickcontrols2-switch.png new file mode 100644 index 00000000000..7f613f3343a Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-switch.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-switchdelegate-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-switchdelegate-custom.png new file mode 100644 index 00000000000..f5337e2c83c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-switchdelegate-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-switchdelegate.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-switchdelegate.gif new file mode 100644 index 00000000000..950b10731f4 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-switchdelegate.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar-custom.png new file mode 100644 index 00000000000..8c8e4accd86 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar-explicit.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar-explicit.png new file mode 100644 index 00000000000..b1de5f715e2 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar-explicit.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar-flickable.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar-flickable.png new file mode 100644 index 00000000000..0c253f82d5d Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar-flickable.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar-wireframe.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar-wireframe.png new file mode 100644 index 00000000000..35a64ae2853 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar-wireframe.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar.gif new file mode 100644 index 00000000000..31db1f9e7cb Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar.png new file mode 100644 index 00000000000..9f113497db6 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbar.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tabbutton.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbutton.png new file mode 100644 index 00000000000..3df2f531471 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tabbutton.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-textarea-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-textarea-custom.png new file mode 100644 index 00000000000..6220a13f395 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-textarea-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-textarea-scrollable.png b/src/quickcontrols2/doc/images/qtquickcontrols2-textarea-scrollable.png new file mode 100644 index 00000000000..ae868a27dab Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-textarea-scrollable.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-textarea.png b/src/quickcontrols2/doc/images/qtquickcontrols2-textarea.png new file mode 100644 index 00000000000..fc221bd7578 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-textarea.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-textfield-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-textfield-custom.png new file mode 100644 index 00000000000..91023170655 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-textfield-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-textfield-disabled.png b/src/quickcontrols2/doc/images/qtquickcontrols2-textfield-disabled.png new file mode 100644 index 00000000000..b143d210531 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-textfield-disabled.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-textfield-focused.png b/src/quickcontrols2/doc/images/qtquickcontrols2-textfield-focused.png new file mode 100644 index 00000000000..de7f9599c9e Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-textfield-focused.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-textfield-normal.png b/src/quickcontrols2/doc/images/qtquickcontrols2-textfield-normal.png new file mode 100644 index 00000000000..4229c706ad7 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-textfield-normal.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-textfield.png b/src/quickcontrols2/doc/images/qtquickcontrols2-textfield.png new file mode 100644 index 00000000000..a008383a002 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-textfield.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-toolbar-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-toolbar-custom.png new file mode 100644 index 00000000000..425e5f8c64e Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-toolbar-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-toolbar.png b/src/quickcontrols2/doc/images/qtquickcontrols2-toolbar.png new file mode 100644 index 00000000000..e5a33eee9ad Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-toolbar.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-toolbutton-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-toolbutton-custom.png new file mode 100644 index 00000000000..b78269d087b Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-toolbutton-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-toolbutton.png b/src/quickcontrols2/doc/images/qtquickcontrols2-toolbutton.png new file mode 100644 index 00000000000..610c1a7cb4d Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-toolbutton.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-toolseparator-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-toolseparator-custom.png new file mode 100644 index 00000000000..6703eeba53c Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-toolseparator-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-toolseparator.png b/src/quickcontrols2/doc/images/qtquickcontrols2-toolseparator.png new file mode 100644 index 00000000000..88ced12361e Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-toolseparator.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip-delay.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip-delay.png new file mode 100644 index 00000000000..59813835b4d Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip-delay.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip-hover.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip-hover.png new file mode 100644 index 00000000000..62a9cf844be Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip-hover.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip-pressandhold.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip-pressandhold.png new file mode 100644 index 00000000000..62a9cf844be Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip-pressandhold.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip-slider.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip-slider.png new file mode 100644 index 00000000000..a15e723a02b Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip-slider.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip.png new file mode 100644 index 00000000000..4238d52a779 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tooltip.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tumbler-custom.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tumbler-custom.png new file mode 100644 index 00000000000..bbfa9b0cefd Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tumbler-custom.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tumbler-delegate.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tumbler-delegate.png new file mode 100644 index 00000000000..a28da93e462 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tumbler-delegate.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tumbler-wrap.gif b/src/quickcontrols2/doc/images/qtquickcontrols2-tumbler-wrap.gif new file mode 100644 index 00000000000..8f59eedcc78 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tumbler-wrap.gif differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-tumbler.png b/src/quickcontrols2/doc/images/qtquickcontrols2-tumbler.png new file mode 100644 index 00000000000..38339dfa251 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-tumbler.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-universal-accent.png b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-accent.png new file mode 100644 index 00000000000..e1d74f7a919 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-accent.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-universal-attributes.png b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-attributes.png new file mode 100644 index 00000000000..7a7ef347fce Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-attributes.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-universal-background.png b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-background.png new file mode 100644 index 00000000000..4f1bfbd2846 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-background.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-universal-button.png b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-button.png new file mode 100644 index 00000000000..6c764ec97e5 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-button.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-universal-dark.png b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-dark.png new file mode 100644 index 00000000000..952651dca07 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-dark.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-universal-foreground.png b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-foreground.png new file mode 100644 index 00000000000..b0ecf23a9e0 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-foreground.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-universal-light.png b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-light.png new file mode 100644 index 00000000000..e65447a4c55 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-light.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-universal-theme.png b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-theme.png new file mode 100644 index 00000000000..d1281346365 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-theme.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-universal-thumbnail.png b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-thumbnail.png new file mode 100644 index 00000000000..db7fe5b076d Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-thumbnail.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-universal-violet.png b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-violet.png new file mode 100644 index 00000000000..ec459457a88 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-universal-violet.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-windows-thumbnail.png b/src/quickcontrols2/doc/images/qtquickcontrols2-windows-thumbnail.png new file mode 100644 index 00000000000..15408d3bbaa Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-windows-thumbnail.png differ diff --git a/src/quickcontrols2/doc/images/qtquickcontrols2-windows.png b/src/quickcontrols2/doc/images/qtquickcontrols2-windows.png new file mode 100644 index 00000000000..324a03412d2 Binary files /dev/null and b/src/quickcontrols2/doc/images/qtquickcontrols2-windows.png differ diff --git a/src/quickcontrols2/doc/manifest-meta.qdocconf b/src/quickcontrols2/doc/manifest-meta.qdocconf new file mode 100644 index 00000000000..5626aca067d --- /dev/null +++ b/src/quickcontrols2/doc/manifest-meta.qdocconf @@ -0,0 +1,32 @@ +# Additional meta information (attributes for matched entries, as well as tags) +# to be added to manifest.xml files. +# +# manifestmeta.filters = <filter1>,<filter2>,... +# +# manifestmeta.<filter>.names = <Module1>/<name1>,<Module2>/<name2>,.. +# manifestmeta.<filter>.attributes = <attribute1:value1>,<attribute2:value2>,.. +# manifestmeta.<filter>.tags = <tag1>,<tag2>,.. +# +# <filter>.names specify all the module/name combinations to apply the +# attributes/tags to. You can use simple wildcard matching by appending +# '*' at the end of name. +# +# Note: You cannot use operators (+, =, -) in the names. +# +# Examples: add a 'isHighlighted' attribute for two 'Analog Clock' examples, +# add a 'database' tag for QtSql examples, and a 'qt5' tag for all examples +# +# manifestmeta.filters = highlighted sql global +# +# manifestmeta.highlighted.names = "QtGui/Analog Clock Window Example" \ +# "QtWidgets/Analog Clock Example" +# manifestmeta.highlighted.attributes = isHighlighted:true +# +# manifestmeta.sql.names = "QtSql/*" +# manifestmeta.sql.tags = database +# +# manifestmeta.global.names = * +# manifestmeta.global.tags = qt5 + +manifestmeta.highlighted.names = "QtQuickControls/Qt Quick Controls - Gallery" \ + "QtQuickControls/Qt Quick Controls - Text Editor" diff --git a/src/quickcontrols2/doc/qtquickcontrols.qdocconf b/src/quickcontrols2/doc/qtquickcontrols.qdocconf new file mode 100644 index 00000000000..3078730cbb7 --- /dev/null +++ b/src/quickcontrols2/doc/qtquickcontrols.qdocconf @@ -0,0 +1,104 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) +include($QT_INSTALL_DOCS/config/exampleurl-qtquickcontrols2.qdocconf) +include(manifest-meta.qdocconf) + +moduleheader = QtQuickControls2 + +project = QtQuickControls +description = Qt Quick Controls Reference Documentation +version = $QT_VERSION + +qhp.projects = QtQuickControls + +qhp.QtQuickControls.file = qtquickcontrols.qhp +qhp.QtQuickControls.namespace = org.qt-project.qtquickcontrols.$QT_VERSION_TAG +qhp.QtQuickControls.virtualFolder = qtquickcontrols +qhp.QtQuickControls.indexTitle = Qt Quick Controls +qhp.QtQuickControls.indexRoot = + +qhp.QtQuickControls.filterAttributes = qtquickcontrols $QT_VERSION qtrefdoc +qhp.QtQuickControls.customFilters.Qt.name = QtQuickControls $QT_VERSION +qhp.QtQuickControls.customFilters.Qt.filterAttributes = qtquickcontrols $QT_VERSION + +qhp.QtQuickControls.subprojects = qmltypes classes examples +qhp.QtQuickControls.subprojects.qmltypes.title = QML Types +qhp.QtQuickControls.subprojects.qmltypes.indexTitle = Qt Quick Controls QML Types +qhp.QtQuickControls.subprojects.qmltypes.selectors = qmlclass +qhp.QtQuickControls.subprojects.qmltypes.sortPages = true +qhp.QtQuickControls.subprojects.classes.title = C++ Classes +qhp.QtQuickControls.subprojects.classes.indexTitle = Qt Quick Controls C++ Classes +qhp.QtQuickControls.subprojects.classes.selectors = class fake:headerfile +qhp.QtQuickControls.subprojects.classes.sortPages = true +qhp.QtQuickControls.subprojects.examples.title = Examples +qhp.QtQuickControls.subprojects.examples.indexTitle = Qt Quick Controls Examples +qhp.QtQuickControls.subprojects.examples.selectors = fake:example + +depends = qtcore qtgui qtdoc qtqml qtqmlmodels qtquick qtsql qtwidgets qtlabsplatform qmake qtcmake + +# Specify the install path under QT_INSTALL_EXAMPLES +# Note: paths passed to \example command must contain the parent directory, e.g. +# \example controls/tabs +exampledirs += ../../../examples/quickcontrols2 \ + ../../quicktemplates2 \ + snippets + +examples.fileextensions += "*.conf" + +examplesinstallpath = quickcontrols2 + +headerdirs += ../../quicktemplates2 \ + .. + +sourcedirs += ../../quicktemplates2 \ + .. \ + ../../quicktemplates2/doc/src \ + src + +# Exclude .qml files from the doc build to prevent conflicts with .qml files +# in style-specific directories; all types are documented in .cpp/.qdoc files +sources.fileextensions = "*.c++ *.cc *.cpp *.cxx *.mm *.qdoc" + +imagedirs += images \ + .. + +navigation.landingpage = "Qt Quick Controls" +navigation.qmltypespage = "Qt Quick Controls QML Types" +navigation.cppclassespage = "Qt Quick Controls C++ Classes" + +tagfile = qtquickcontrols.tags + +# \styleimport {QtQuick.Controls.Universal 2.0} +macro.styleimport.HTML = "<table class=\"alignedsummary\"><tbody><tr><td class=\"memItemLeft rightAlign topAlign\"> Import Statement:</td><td class=\"memItemRight bottomAlign\"> import \1</td></tr><tr><td class=\"memItemLeft rightAlign topAlign\"> Since:</td><td class=\"memItemRight bottomAlign\"> \2</td></tr></tbody></table>" + +# \styleproperty {Universal.accent} {enumeration} {html-target-id} +# \target html-target-id +# This property holds ... +# (empty line) +# \endstyleproperty +macro.styleproperty.HTML = "<div class=\"qmlproto\"><table class=\"qmlname\"><tbody><tr valign=\"top\" class=\"odd\" id=\"\3\"><td class=\"tblQmlPropNode\"><p><span class=\"name\">\1</span> : <span class=\"type\">\2</span></p></td></tr></tbody></table></div>" +macro.endstyleproperty = "\\br" + +# \stylemethod {returntype} {methodname} {argtype} {argname} {html-target-id} +# \target html-target-id +# This property holds ... +# (empty line) +# \endstylemethod +macro.stylemethod.HTML = "<div class=\"qmlproto\"><table class=\"qmlname\"><tbody><tr valign=\"top\" class=\"odd\" id=\"\5\"><td class=\"tblQmlFuncNode\"><p><span class=\"type\">\1</span> <span class=\"name\">\2</span>(<span class="type">\3</span> <i>\4</i>)</p></td></tr></tbody></table></div>" +macro.endstylemethod = "\\br" + +# \stylemethod2 {returntype} {methodname} {arg1type} {arg1name} {arg2type} {arg2name} {html-target-id} +# \target html-target-id +# This method returns ... +# (empty line) +# \endstylemethod2 +macro.stylemethod2.HTML = "<div class=\"qmlproto\"><table class=\"qmlname\"><tbody><tr valign=\"top\" class=\"odd\" id=\"\7\"><td class=\"tblQmlFuncNode\"><p><span class=\"type\">\1</span> <span class=\"name\">\2</span>(<span class="type">\3</span> <i>\4</i>, <span class="type">\5</span> <i>\6</i>)</p></td></tr></tbody></table></div>" +macro.endstylemethod2 = "\\br" + +# \stylecolor {#6A00FF} {(default)} +macro.stylecolor.HTML = "<div style=\"padding:10px;color:#fff;background:\1;\">\1 \2</div>" + +macro.nbsp.HTML = " " + +#Add output suffix to the html filenames +outputsuffixes = QML +outputsuffixes.QML = 2 diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols-custom-palette-buttons.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols-custom-palette-buttons.qml new file mode 100644 index 00000000000..82180fe4653 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols-custom-palette-buttons.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![entire] +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + visible: true + + //![palette] + palette { + buttonText: "red" + button: "khaki" + + disabled { + buttonText: "lavender" + button: "coral" + } + } + //![palette] + + ColumnLayout { + id: layout + anchors.fill: parent + anchors.margins: 3 + Button { + text: qsTr("Disabled button") + enabled: false + } + + Button { + text: qsTr("Enabled button") + } + + TextField { + Layout.fillWidth: true + placeholderText: "type something here" + } + } +} +//![entire] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-action.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-action.qml new file mode 100644 index 00000000000..1b65a824b07 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-action.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + //! [action] + Action { + id: copyAction + text: qsTr("&Copy") + icon.name: "edit-copy" + shortcut: StandardKey.Copy + onTriggered: window.activeFocusItem.copy() + } + //! [action] + + //! [toolbutton] + ToolButton { + id: toolButton + action: copyAction + } + //! [toolbutton] + + //! [menuitem] + MenuItem { + id: menuItem + action: copyAction + text: qsTr("&Copy selected Text") + } + //! [menuitem] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-busyindicator-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-busyindicator-custom.qml new file mode 100644 index 00000000000..8a654deb545 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-busyindicator-custom.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +BusyIndicator { + id: control + + contentItem: Item { + implicitWidth: 64 + implicitHeight: 64 + + Item { + id: item + x: parent.width / 2 - 32 + y: parent.height / 2 - 32 + width: 64 + height: 64 + opacity: control.running ? 1 : 0 + + Behavior on opacity { + OpacityAnimator { + duration: 250 + } + } + + RotationAnimator { + target: item + running: control.visible && control.running + from: 0 + to: 360 + loops: Animation.Infinite + duration: 1250 + } + + Repeater { + id: repeater + model: 6 + + Rectangle { + id: delegate + x: item.width / 2 - width / 2 + y: item.height / 2 - height / 2 + implicitWidth: 10 + implicitHeight: 10 + radius: 5 + color: "#21be2b" + + required property int index + + transform: [ + Translate { + y: -Math.min(item.width, item.height) * 0.5 + 5 + }, + Rotation { + angle: delegate.index / repeater.count * 360 + origin.x: 5 + origin.y: 5 + } + ] + } + } + } + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-button-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-button-custom.qml new file mode 100644 index 00000000000..095657b5a6c --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-button-custom.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +Button { + id: control + text: qsTr("Button") + + contentItem: Text { + text: control.text + font: control.font + opacity: enabled ? 1.0 : 0.3 + color: control.down ? "#17a81a" : "#21be2b" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + opacity: enabled ? 1 : 0.3 + border.color: control.down ? "#17a81a" : "#21be2b" + border.width: 1 + radius: 2 + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-button-icononly.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-button-icononly.qml new file mode 100644 index 00000000000..d74000052be --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-button-icononly.qml @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Button { + icon.source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png" + display: Button.IconOnly +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-button-textbesideicon.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-button-textbesideicon.qml new file mode 100644 index 00000000000..3e2aa619d0f --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-button-textbesideicon.qml @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Button { + text: "Button" + icon.source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png" + display: Button.TextBesideIcon +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-button-textonly.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-button-textonly.qml new file mode 100644 index 00000000000..59054f7714c --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-button-textonly.qml @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Button { + text: "Button" + display: Button.TextOnly +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-checkbox-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-checkbox-custom.qml new file mode 100644 index 00000000000..93ebe46dcae --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-checkbox-custom.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +CheckBox { + id: control + text: qsTr("CheckBox") + checked: true + + indicator: Rectangle { + implicitWidth: 26 + implicitHeight: 26 + x: control.leftPadding + y: parent.height / 2 - height / 2 + radius: 3 + border.color: control.down ? "#17a81a" : "#21be2b" + + Rectangle { + width: 14 + height: 14 + x: 6 + y: 6 + radius: 2 + color: control.down ? "#17a81a" : "#21be2b" + visible: control.checked + } + } + + contentItem: Text { + text: control.text + font: control.font + opacity: enabled ? 1.0 : 0.3 + color: control.down ? "#17a81a" : "#21be2b" + verticalAlignment: Text.AlignVCenter + leftPadding: control.indicator.width + control.spacing + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-checkbox-group.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-checkbox-group.qml new file mode 100644 index 00000000000..c5032165865 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-checkbox-group.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +Column { + ButtonGroup { + id: childGroup + exclusive: false + checkState: parentBox.checkState + } + + CheckBox { + id: parentBox + text: qsTr("Parent") + checkState: childGroup.checkState + } + + CheckBox { + checked: true + text: qsTr("Child 1") + leftPadding: indicator.width + ButtonGroup.group: childGroup + } + + CheckBox { + text: qsTr("Child 2") + leftPadding: indicator.width + ButtonGroup.group: childGroup + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-checkdelegate-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-checkdelegate-custom.qml new file mode 100644 index 00000000000..91970f529f5 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-checkdelegate-custom.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +CheckDelegate { + id: control + text: qsTr("CheckDelegate") + checked: true + + contentItem: Text { + rightPadding: control.indicator.width + control.spacing + text: control.text + font: control.font + opacity: enabled ? 1.0 : 0.3 + color: control.down ? "#17a81a" : "#21be2b" + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + indicator: Rectangle { + implicitWidth: 26 + implicitHeight: 26 + x: control.width - width - control.rightPadding + y: control.topPadding + control.availableHeight / 2 - height / 2 + radius: 3 + color: "transparent" + border.color: control.down ? "#17a81a" : "#21be2b" + + Rectangle { + width: 14 + height: 14 + x: 6 + y: 6 + radius: 2 + color: control.down ? "#17a81a" : "#21be2b" + visible: control.checked + } + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + visible: control.down || control.highlighted + color: control.down ? "#bdbebf" : "#eeeeee" + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-accepted.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-accepted.qml new file mode 100644 index 00000000000..b420e3a572f --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-accepted.qml @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [combobox] +ComboBox { + editable: true + model: ListModel { + id: model + ListElement { text: "Banana" } + ListElement { text: "Apple" } + ListElement { text: "Coconut" } + } + onAccepted: { + if (find(editText) === -1) + model.append({text: editText}) + } +} +//! [combobox] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-custom.qml new file mode 100644 index 00000000000..08eeae905e7 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-custom.qml @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +ComboBox { + id: control + model: ["First", "Second", "Third"] + + delegate: ItemDelegate { + width: control.width + contentItem: Text { + text: control.textRole + ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) + : modelData + color: "#21be2b" + font: control.font + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + highlighted: control.highlightedIndex === index + } + + indicator: Canvas { + id: canvas + x: control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + width: 12 + height: 8 + contextType: "2d" + + Connections { + target: control + function onPressedChanged() { canvas.requestPaint(); } + } + + onPaint: { + context.reset(); + context.moveTo(0, 0); + context.lineTo(width, 0); + context.lineTo(width / 2, height); + context.closePath(); + context.fillStyle = control.pressed ? "#17a81a" : "#21be2b"; + context.fill(); + } + } + + contentItem: Text { + leftPadding: 0 + rightPadding: control.indicator.width + control.spacing + + text: control.displayText + font: control.font + color: control.pressed ? "#17a81a" : "#21be2b" + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + implicitWidth: 120 + implicitHeight: 40 + border.color: control.pressed ? "#17a81a" : "#21be2b" + border.width: control.visualFocus ? 2 : 1 + radius: 2 + } + + popup: Popup { + y: control.height - 1 + width: control.width + implicitHeight: contentItem.implicitHeight + padding: 1 + + contentItem: ListView { + clip: true + implicitHeight: contentHeight + model: control.popup.visible ? control.delegateModel : null + currentIndex: control.highlightedIndex + + ScrollIndicator.vertical: ScrollIndicator { } + } + + background: Rectangle { + border.color: "#21be2b" + radius: 2 + } + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-find.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-find.qml new file mode 100644 index 00000000000..c14ebbbe1fd --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-find.qml @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [find] +ComboBox { + model: ListModel { + ListElement { text: "Banana" } + ListElement { text: "Apple" } + ListElement { text: "Coconut" } + } + Component.onCompleted: currentIndex = find("Coconut") +} +//! [find] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-popup.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-popup.qml new file mode 100644 index 00000000000..4aea1888bef --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-popup.qml @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls + +ComboBox { +//! [closePolicy] + popup.closePolicy: Popup.CloseOnEscape +//! [closePolicy] +//! [modal] + popup.modal: true +//! [modal] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-textat.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-textat.qml new file mode 100644 index 00000000000..524886d06ba --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-textat.qml @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [textat] +ComboBox { + model: ListModel { + ListElement { text: "Banana" } + ListElement { text: "Apple" } + ListElement { text: "Coconut" } + } + onActivated: (index) => { print(textAt(index)) } +} +//! [textat] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-valuerole.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-valuerole.qml new file mode 100644 index 00000000000..a4c40c0f0b4 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-combobox-valuerole.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [file] +ApplicationWindow { + width: 640 + height: 480 + visible: true + + // Used as an example of a backend - this would usually be + // e.g. a C++ type exposed to QML. + QtObject { + id: backend + property int modifier + } + + ComboBox { + textRole: "text" + valueRole: "value" + // When an item is selected, update the backend. + onActivated: backend.modifier = currentValue + // Set the initial currentIndex to the value stored in the backend. + Component.onCompleted: currentIndex = indexOfValue(backend.modifier) + model: [ + { value: Qt.NoModifier, text: qsTr("No modifier") }, + { value: Qt.ShiftModifier, text: qsTr("Shift") }, + { value: Qt.ControlModifier, text: qsTr("Control") } + ] + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-delaybutton-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-delaybutton-custom.qml new file mode 100644 index 00000000000..0b86f1d0026 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-delaybutton-custom.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +DelayButton { + id: control + checked: true + text: qsTr("Delay\nButton") + + contentItem: Text { + text: control.text + font: control.font + opacity: enabled ? 1.0 : 0.3 + color: "white" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 100 + opacity: enabled ? 1 : 0.3 + color: control.down ? "#17a81a" : "#21be2b" + radius: size / 2 + + readonly property real size: Math.min(control.width, control.height) + width: size + height: size + anchors.centerIn: parent + + Canvas { + id: canvas + anchors.fill: parent + + Connections { + target: control + function onProgressChanged() { canvas.requestPaint(); } + } + + onPaint: { + var ctx = getContext("2d") + ctx.clearRect(0, 0, width, height) + ctx.strokeStyle = "white" + ctx.lineWidth = parent.size / 20 + ctx.beginPath() + var startAngle = Math.PI / 5 * 3 + var endAngle = startAngle + control.progress * Math.PI / 5 * 9 + ctx.arc(width / 2, height / 2, width / 2 - ctx.lineWidth / 2 - 2, startAngle, endAngle) + ctx.stroke() + } + } + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-dial-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-dial-custom.qml new file mode 100644 index 00000000000..170e9ccf094 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-dial-custom.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +Dial { + id: control + background: Rectangle { + x: control.width / 2 - width / 2 + y: control.height / 2 - height / 2 + width: Math.max(64, Math.min(control.width, control.height)) + height: width + color: "transparent" + radius: width / 2 + border.color: control.pressed ? "#17a81a" : "#21be2b" + opacity: control.enabled ? 1 : 0.3 + } + + handle: Rectangle { + id: handleItem + x: control.background.x + control.background.width / 2 - width / 2 + y: control.background.y + control.background.height / 2 - height / 2 + width: 16 + height: 16 + color: control.pressed ? "#17a81a" : "#21be2b" + radius: 8 + antialiasing: true + opacity: control.enabled ? 1 : 0.3 + transform: [ + Translate { + y: -Math.min(control.background.width, control.background.height) * 0.4 + handleItem.height / 2 + }, + Rotation { + angle: control.angle + origin.x: handleItem.width / 2 + origin.y: handleItem.height / 2 + } + ] + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialog-modal.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialog-modal.qml new file mode 100644 index 00000000000..d60e4e309b0 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialog-modal.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: dialog.implicitWidth + height: dialog.implicitHeight +//! [1] +Dialog { + id: dialog + modal: true + standardButtons: Dialog.Ok +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialog-modeless.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialog-modeless.qml new file mode 100644 index 00000000000..6acb74e59c2 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialog-modeless.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: dialog.implicitWidth + height: dialog.implicitHeight +//! [1] +Dialog { + id: dialog + modal: false + standardButtons: Dialog.Ok +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialog.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialog.qml new file mode 100644 index 00000000000..13fbb0e8437 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialog.qml @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: dialog.implicitWidth + height: dialog.implicitHeight +//! [1] +Dialog { + id: dialog + title: "Title" + standardButtons: Dialog.Ok | Dialog.Cancel + + onAccepted: console.log("Ok clicked") + onRejected: console.log("Cancel clicked") +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialogbuttonbox-attached.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialogbuttonbox-attached.qml new file mode 100644 index 00000000000..45a0b9e9203 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialogbuttonbox-attached.qml @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +DialogButtonBox { + Button { + text: qsTr("Save") + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + } + Button { + text: qsTr("Close") + DialogButtonBox.buttonRole: DialogButtonBox.DestructiveRole + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialogbuttonbox.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialogbuttonbox.qml new file mode 100644 index 00000000000..bcfd405b125 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-dialogbuttonbox.qml @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +DialogButtonBox { + standardButtons: DialogButtonBox.Ok | DialogButtonBox.Cancel + + onAccepted: console.log("Ok clicked") + onRejected: console.log("Cancel clicked") +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-frame-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-frame-custom.qml new file mode 100644 index 00000000000..798f95da13c --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-frame-custom.qml @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +Frame { + background: Rectangle { + color: "transparent" + border.color: "#21be2b" + radius: 2 + } + + Label { + text: qsTr("Content goes here!") + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-frame.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-frame.qml new file mode 100644 index 00000000000..71b9b310d4f --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-frame.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +//! [1] +Frame { + ColumnLayout { + anchors.fill: parent + CheckBox { text: qsTr("E-mail") } + CheckBox { text: qsTr("Calendar") } + CheckBox { text: qsTr("Contacts") } + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-groupbox-checkable.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-groupbox-checkable.qml new file mode 100644 index 00000000000..91689d9fae6 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-groupbox-checkable.qml @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +//! [1] +GroupBox { + label: CheckBox { + id: checkBox + checked: true + text: qsTr("Synchronize") + } + + ColumnLayout { + anchors.fill: parent + enabled: checkBox.checked + CheckBox { text: qsTr("E-mail") } + CheckBox { text: qsTr("Calendar") } + CheckBox { text: qsTr("Contacts") } + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-groupbox-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-groupbox-custom.qml new file mode 100644 index 00000000000..e3355b2337d --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-groupbox-custom.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +GroupBox { + id: control + title: qsTr("GroupBox") + + background: Rectangle { + y: control.topPadding - control.bottomPadding + width: parent.width + height: parent.height - control.topPadding + control.bottomPadding + color: "transparent" + border.color: "#21be2b" + radius: 2 + } + + label: Label { + x: control.leftPadding + width: control.availableWidth + text: control.title + color: "#21be2b" + elide: Text.ElideRight + } + + Label { + text: qsTr("Content goes here!") + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-groupbox.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-groupbox.qml new file mode 100644 index 00000000000..e9f1c7dcc00 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-groupbox.qml @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +//! [1] +GroupBox { + title: qsTr("Synchronize") + ColumnLayout { + anchors.fill: parent + CheckBox { text: qsTr("E-mail") } + CheckBox { text: qsTr("Calendar") } + CheckBox { text: qsTr("Contacts") } + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-headerview-simple.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-headerview-simple.qml new file mode 100644 index 00000000000..6878904f3ca --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-headerview-simple.qml @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![file] +import QtQuick +import QtQuick.Controls +import Qt.labs.qmlmodels + +ApplicationWindow { + visible: true + width: 640 + height: 480 + + //! [horizontal] + HorizontalHeaderView { + id: horizontalHeader + syncView: tableView + anchors.left: tableView.left + } + //! [horizontal] + + //! [vertical] + VerticalHeaderView { + id: verticalHeader + syncView: tableView + anchors.top: tableView.top + } + //! [vertical] + + TableView { + id: tableView + anchors.fill: parent + anchors.topMargin: horizontalHeader.height + anchors.leftMargin: verticalHeader.width + columnSpacing: 1 + rowSpacing: 1 + clip: true + + model: TableModel { + TableModelColumn { display: "name" } + TableModelColumn { display: "color" } + + rows: [ + { + "name": "cat", + "color": "black" + }, + { + "name": "dog", + "color": "brown" + }, + { + "name": "bird", + "color": "white" + } + ] + } + + delegate: Rectangle { + implicitWidth: 100 + implicitHeight: 50 + border.width: 1 + + Text { + text: display + anchors.centerIn: parent + } + } + } +} + +//![file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-itemdelegate-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-itemdelegate-custom.qml new file mode 100644 index 00000000000..fd52b46f322 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-itemdelegate-custom.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +ItemDelegate { + id: control + text: qsTr("ItemDelegate") + + contentItem: Text { + rightPadding: control.spacing + text: control.text + font: control.font + color: control.enabled ? (control.down ? "#17a81a" : "#21be2b") : "#bdbebf" + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + opacity: enabled ? 1 : 0.3 + color: control.down ? "#dddedf" : "#eeeeee" + + Rectangle { + width: parent.width + height: 1 + color: control.down ? "#17a81a" : "#21be2b" + anchors.bottom: parent.bottom + } + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-itemdelegate.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-itemdelegate.qml new file mode 100644 index 00000000000..dbc108e7ab9 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-itemdelegate.qml @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +ListView { + width: 160 + height: 240 + + model: Qt.fontFamilies() + + delegate: ItemDelegate { + text: modelData + width: parent.width + onClicked: console.log("clicked:", modelData) + + required property string modelData + } + + ScrollIndicator.vertical: ScrollIndicator { } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-label-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-label-custom.qml new file mode 100644 index 00000000000..cc88d00f420 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-label-custom.qml @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +Label { + text: qsTr("Label") + color: "#21be2b" +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-label.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-label.qml new file mode 100644 index 00000000000..c492af50d4f --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-label.qml @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +Label { + text: "Label" +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-accent.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-accent.qml new file mode 100644 index 00000000000..aa4c62b8e57 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-accent.qml @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material + +Pane { + padding: 4 + +//! [1] +Button { + text: qsTr("Button") + highlighted: true + Material.accent: Material.Orange +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-background.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-background.qml new file mode 100644 index 00000000000..f64e48d225a --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-background.qml @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material + +Pane { + padding: 4 + +//! [1] +Button { + text: qsTr("Button") + highlighted: true + Material.background: Material.Teal +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-elevation.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-elevation.qml new file mode 100644 index 00000000000..f9e189f17a1 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-elevation.qml @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material + +Pane { + contentWidth: 120 + contentHeight: 120 + padding: 10 + bottomPadding: 20 + +//! [1] +Pane { + width: 120 + height: 120 + + Material.elevation: 6 + + Label { + text: qsTr("I'm a card!") + anchors.centerIn: parent + } +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-foreground.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-foreground.qml new file mode 100644 index 00000000000..070576f541a --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-foreground.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material + +Pane { + padding: 4 + +//! [1] +Button { + text: qsTr("Button") + Material.foreground: Material.Pink +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-theme.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-theme.qml new file mode 100644 index 00000000000..586433c3697 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-theme.qml @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material + +Pane { + padding: 10 + +//! [1] +Pane { + Material.theme: Material.Dark + + Button { + text: qsTr("Button") + } +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-variant.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-variant.qml new file mode 100644 index 00000000000..df0a617f05b --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-material-variant.qml @@ -0,0 +1,213 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts + +Pane { + id: root + implicitWidth: 400 + implicitHeight: 600 + padding: 10 + + readonly property color measurementColor: "darkorange" + readonly property int barLeftMargin: 10 + readonly property int textTopMargin: 12 + + Component { + id: measurementComponent + + Rectangle { + color: root.measurementColor + width: 1 + height: parent.height + + Rectangle { + width: 5 + height: 1 + color: root.measurementColor + anchors.horizontalCenter: parent.horizontalCenter + } + + Rectangle { + width: 5 + height: 1 + color: root.measurementColor + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + } + + Text { + x: 8 + text: parent.height + height: parent.height + color: root.measurementColor + verticalAlignment: Text.AlignVCenter + } + } + } + + ColumnLayout { + anchors.fill: parent + spacing: 20 + + ColumnLayout { + spacing: root.textTopMargin + + Button { + id: button + text: qsTr("Button") + + Loader { + sourceComponent: measurementComponent + height: parent.height + anchors.left: parent.right + anchors.leftMargin: root.barLeftMargin + } + + } + Text { + text: "Roboto " + button.font.pixelSize + color: root.measurementColor + } + } + + ColumnLayout { + spacing: root.textTopMargin + + ItemDelegate { + id: itemDelegate + text: qsTr("ItemDelegate") + + Loader { + sourceComponent: measurementComponent + height: parent.height + anchors.left: parent.right + anchors.leftMargin: root.barLeftMargin + } + + } + Text { + text: "Roboto " + itemDelegate.font.pixelSize + color: root.measurementColor + } + } + + ColumnLayout { + spacing: root.textTopMargin + + CheckDelegate { + id: checkDelegate + text: qsTr("CheckDelegate") + + Loader { + sourceComponent: measurementComponent + height: parent.height + anchors.left: parent.right + anchors.leftMargin: root.barLeftMargin + } + + } + Text { + text: "Roboto " + checkDelegate.font.pixelSize + color: root.measurementColor + } + } + + ColumnLayout { + spacing: root.textTopMargin + + RadioDelegate { + id: radioDelegate + text: qsTr("RadioDelegate") + + Loader { + sourceComponent: measurementComponent + height: parent.height + anchors.left: parent.right + anchors.leftMargin: root.barLeftMargin + } + + } + Text { + text: "Roboto " + radioDelegate.font.pixelSize + color: root.measurementColor + } + } + + ColumnLayout { + spacing: root.textTopMargin + + ComboBox { + id: comboBox + model: [ qsTr("ComboBox") ] + + Loader { + sourceComponent: measurementComponent + height: parent.height + anchors.left: parent.right + anchors.leftMargin: root.barLeftMargin + } + + } + Text { + text: "Roboto " + comboBox.font.pixelSize + color: root.measurementColor + } + } + + ColumnLayout { + spacing: root.textTopMargin + + Item { + implicitWidth: groupBox.implicitWidth + implicitHeight: groupBox.implicitHeight + + GroupBox { + id: groupBox + title: qsTr("GroupBox") + } + Loader { + sourceComponent: measurementComponent + height: parent.height + anchors.left: parent.right + anchors.leftMargin: root.barLeftMargin + } + } + Text { + text: "Roboto " + groupBox.font.pixelSize + color: root.measurementColor + } + } + + Item { + Layout.fillHeight: true + } + } +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-menu-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-menu-custom.qml new file mode 100644 index 00000000000..3e766e8a7a4 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-menu-custom.qml @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: menu.width + height: menu.height + visible: true + + Component.onCompleted: menu.popup(menu.itemAt(1)) + +// Indent it like this so that the indenting in the generated doc is normal. +Menu { + id: menu + + Action { text: qsTr("Tool Bar"); checkable: true } + Action { text: qsTr("Side Bar"); checkable: true; checked: true } + Action { text: qsTr("Status Bar"); checkable: true; checked: true } + + MenuSeparator { + contentItem: Rectangle { + implicitWidth: 200 + implicitHeight: 1 + color: "#21be2b" + } + } + + Menu { + title: qsTr("Advanced") + // ... + } + + topPadding: 2 + bottomPadding: 2 + + delegate: MenuItem { + id: menuItem + implicitWidth: 200 + implicitHeight: 40 + + arrow: Canvas { + x: parent.width - width + implicitWidth: 40 + implicitHeight: 40 + visible: menuItem.subMenu + onPaint: { + var ctx = getContext("2d") + ctx.fillStyle = menuItem.highlighted ? "#ffffff" : "#21be2b" + ctx.moveTo(15, 15) + ctx.lineTo(width - 15, height / 2) + ctx.lineTo(15, height - 15) + ctx.closePath() + ctx.fill() + } + } + + indicator: Item { + implicitWidth: 40 + implicitHeight: 40 + Rectangle { + width: 26 + height: 26 + anchors.centerIn: parent + visible: menuItem.checkable + border.color: "#21be2b" + radius: 3 + Rectangle { + width: 14 + height: 14 + anchors.centerIn: parent + visible: menuItem.checked + color: "#21be2b" + radius: 2 + } + } + } + + contentItem: Text { + leftPadding: menuItem.indicator.width + rightPadding: menuItem.arrow.width + text: menuItem.text + font: menuItem.font + opacity: enabled ? 1.0 : 0.3 + color: menuItem.highlighted ? "#ffffff" : "#21be2b" + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 40 + opacity: enabled ? 1 : 0.3 + color: menuItem.highlighted ? "#21be2b" : "transparent" + } + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 40 + color: "#ffffff" + border.color: "#21be2b" + radius: 2 + } +} +} //! [eof] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-menubar-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-menubar-custom.qml new file mode 100644 index 00000000000..4b3d641e21a --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-menubar-custom.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + visible: true + width: menuBar.implicitWidth + height: menuBar.height + + Component.onCompleted: menuBar.itemAt(1).highlighted = true + + header: + +// Indent it like this so that the indenting in the generated doc is normal. +MenuBar { + id: menuBar + + Menu { title: qsTr("File") } + Menu { title: qsTr("Edit") } + Menu { title: qsTr("View") } + Menu { title: qsTr("Help") } + + delegate: MenuBarItem { + id: menuBarItem + + contentItem: Text { + text: menuBarItem.text + font: menuBarItem.font + opacity: enabled ? 1.0 : 0.3 + color: menuBarItem.highlighted ? "#ffffff" : "#21be2b" + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + implicitWidth: 40 + implicitHeight: 40 + opacity: enabled ? 1 : 0.3 + color: menuBarItem.highlighted ? "#21be2b" : "transparent" + } + } + + background: Rectangle { + implicitWidth: 40 + implicitHeight: 40 + color: "#ffffff" + + Rectangle { + color: "#21be2b" + width: parent.width + height: 1 + anchors.bottom: parent.bottom + } + } +} +} //! [eof] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-menubar.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-menubar.qml new file mode 100644 index 00000000000..7ae22ae8c2d --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-menubar.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [begin] +ApplicationWindow { + id: window + width: 320 + height: 260 + visible: true + + //! [skipfrom] + Component.onCompleted: { + menuBar.itemAt(0).triggered() + menuBar.itemAt(0).menu.itemAt(2).highlighted = true + } + //! [skipto] + + menuBar: MenuBar { + Menu { + title: qsTr("&File") + Action { text: qsTr("&New...") } + Action { text: qsTr("&Open...") } + Action { text: qsTr("&Save") } + Action { text: qsTr("Save &As...") } + MenuSeparator { } + Action { text: qsTr("&Quit") } + } + Menu { + title: qsTr("&Edit") + Action { text: qsTr("Cu&t") } + Action { text: qsTr("&Copy") } + Action { text: qsTr("&Paste") } + } + Menu { + title: qsTr("&Help") + Action { text: qsTr("&About") } + } + } +} +//! [end] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-menuseparator-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-menuseparator-custom.qml new file mode 100644 index 00000000000..fa7fa14a445 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-menuseparator-custom.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +Item { + id: window + width: menu.contentItem.width + height: menu.contentItem.height + visible: true + +// Indent it like this so that the indenting in the generated doc is normal. +Menu { + id: menu + contentItem.parent: window + + MenuItem { + text: qsTr("New...") + } + MenuItem { + text: qsTr("Open...") + } + MenuItem { + text: qsTr("Save") + } + + MenuSeparator { + padding: 0 + topPadding: 12 + bottomPadding: 12 + contentItem: Rectangle { + implicitWidth: 200 + implicitHeight: 1 + color: "#1E000000" + } + } + + MenuItem { + text: qsTr("Exit") + } +} +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-menuseparator.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-menuseparator.qml new file mode 100644 index 00000000000..cd5d5441554 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-menuseparator.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +Item { + id: window + width: menu.contentItem.width + height: menu.contentItem.height + visible: true + +// Indent it like this so that the indenting in the generated doc is normal. +Menu { + id: menu + contentItem.parent: window + + MenuItem { + text: qsTr("New...") + } + MenuItem { + text: qsTr("Open...") + } + MenuItem { + text: qsTr("Save") + } + + MenuSeparator {} + + MenuItem { + text: qsTr("Exit") + } +} +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-overlay-modal.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-overlay-modal.qml new file mode 100644 index 00000000000..9751f05781b --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-overlay-modal.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Window + +Item { + id: root + width: 200 + height: 200 + + Binding { + target: popup + property: "visible" + value: root.Window.active + } +//! [1] +Popup { + id: popup + width: 400 + height: 400 + modal: true + visible: true + + Overlay.modal: Rectangle { + color: "#aacfdbe7" + } +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-overlay-modeless.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-overlay-modeless.qml new file mode 100644 index 00000000000..a4951d1386a --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-overlay-modeless.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Window + +Item { + id: root + width: 200 + height: 200 + + Binding { + target: popup + property: "visible" + value: root.Window.active + } +//! [1] +Popup { + id: popup + width: 400 + height: 400 + dim: true + visible: true + + Overlay.modeless: Rectangle { + color: "#aacfdbe7" + } +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-overview.cmake b/src/quickcontrols2/doc/snippets/qtquickcontrols2-overview.cmake new file mode 100644 index 00000000000..b643e2c21da --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-overview.cmake @@ -0,0 +1,4 @@ +#! [0] +find_package(Qt6 REQUIRED COMPONENTS QuickControls2) +target_link_libraries(mytarget PRIVATE Qt6::QuickControls2) +#! [0] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-pageindicator-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-pageindicator-custom.qml new file mode 100644 index 00000000000..2ca92cb4271 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-pageindicator-custom.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +PageIndicator { + id: control + count: 5 + currentIndex: 2 + + delegate: Rectangle { + implicitWidth: 8 + implicitHeight: 8 + + radius: width / 2 + color: "#21be2b" + + opacity: index === control.currentIndex ? 0.95 : pressed ? 0.7 : 0.45 + + required property int index + + Behavior on opacity { + OpacityAnimator { + duration: 100 + } + } + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-pageindicator-interactive.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-pageindicator-interactive.qml new file mode 100644 index 00000000000..8f2221ee4e3 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-pageindicator-interactive.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls + +Pane { +//! [1] +SwipeView { + id: view + currentIndex: pageIndicator.currentIndex + anchors.fill: parent + + Page { + title: qsTr("Home") + } + Page { + title: qsTr("Discover") + } + Page { + title: qsTr("Activity") + } +} + +PageIndicator { + id: pageIndicator + interactive: true + count: view.count + currentIndex: view.currentIndex + + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-pageindicator.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-pageindicator.qml new file mode 100644 index 00000000000..b3912efe7a5 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-pageindicator.qml @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick +import QtQuick.Controls + +//! [1] +PageIndicator { + count: 5 + currentIndex: 2 +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-pane-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-pane-custom.qml new file mode 100644 index 00000000000..855423c4c20 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-pane-custom.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +Pane { + background: Rectangle { + color: "#eeeeee" + } + + Label { + text: qsTr("Content goes here!") + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-pane.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-pane.qml new file mode 100644 index 00000000000..a8c8672e773 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-pane.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +//! [1] +Pane { + ColumnLayout { + anchors.fill: parent + CheckBox { text: qsTr("E-mail") } + CheckBox { text: qsTr("Calendar") } + CheckBox { text: qsTr("Contacts") } + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-popup-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-popup-custom.qml new file mode 100644 index 00000000000..ad5481e34d2 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-popup-custom.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Window + +Item { + id: root + width: 200 + height: 200 + + Binding { + target: popup + property: "visible" + value: root.Window.active + } +//! [1] +Popup { + id: popup + background: Rectangle { + implicitWidth: 200 + implicitHeight: 200 + border.color: "#444" + } + contentItem: Column {} +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-popup.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-popup.qml new file mode 100644 index 00000000000..76ec20cdb21 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-popup.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { +//! [centerIn] +ApplicationWindow { + id: window + // ... + + Pane { + // ... + + Popup { + anchors.centerIn: Overlay.overlay + } + } +} +//! [centerIn] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-progressbar-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-progressbar-custom.qml new file mode 100644 index 00000000000..d96161577b2 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-progressbar-custom.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +ProgressBar { + id: control + value: 0.5 + padding: 2 + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 6 + color: "#e6e6e6" + radius: 3 + } + + contentItem: Item { + implicitWidth: 200 + implicitHeight: 4 + + Rectangle { + width: control.visualPosition * parent.width + height: parent.height + radius: 2 + color: "#17a81a" + } + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-radiobutton-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-radiobutton-custom.qml new file mode 100644 index 00000000000..b33ce6b6d92 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-radiobutton-custom.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +RadioButton { + id: control + text: qsTr("RadioButton") + checked: true + + indicator: Rectangle { + implicitWidth: 26 + implicitHeight: 26 + x: control.leftPadding + y: parent.height / 2 - height / 2 + radius: 13 + border.color: control.down ? "#17a81a" : "#21be2b" + + Rectangle { + width: 14 + height: 14 + x: 6 + y: 6 + radius: 7 + color: control.down ? "#17a81a" : "#21be2b" + visible: control.checked + } + } + + contentItem: Text { + text: control.text + font: control.font + opacity: enabled ? 1.0 : 0.3 + color: control.down ? "#17a81a" : "#21be2b" + verticalAlignment: Text.AlignVCenter + leftPadding: control.indicator.width + control.spacing + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-radiodelegate-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-radiodelegate-custom.qml new file mode 100644 index 00000000000..ed3dae678a7 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-radiodelegate-custom.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +RadioDelegate { + id: control + text: qsTr("RadioDelegate") + checked: true + + contentItem: Text { + rightPadding: control.indicator.width + control.spacing + text: control.text + font: control.font + opacity: enabled ? 1.0 : 0.3 + color: control.down ? "#17a81a" : "#21be2b" + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + indicator: Rectangle { + implicitWidth: 26 + implicitHeight: 26 + x: control.width - width - control.rightPadding + y: parent.height / 2 - height / 2 + radius: 13 + color: "transparent" + border.color: control.down ? "#17a81a" : "#21be2b" + + Rectangle { + width: 14 + height: 14 + x: 6 + y: 6 + radius: 7 + color: control.down ? "#17a81a" : "#21be2b" + visible: control.checked + } + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + visible: control.down || control.highlighted + color: control.down ? "#bdbebf" : "#eeeeee" + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-rangeslider-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-rangeslider-custom.qml new file mode 100644 index 00000000000..fcddc400673 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-rangeslider-custom.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +RangeSlider { + id: control + first.value: 0.25 + second.value: 0.75 + + background: Rectangle { + x: control.leftPadding + y: control.topPadding + control.availableHeight / 2 - height / 2 + implicitWidth: 200 + implicitHeight: 4 + width: control.availableWidth + height: implicitHeight + radius: 2 + color: "#bdbebf" + + Rectangle { + x: control.first.visualPosition * parent.width + width: control.second.visualPosition * parent.width - x + height: parent.height + color: "#21be2b" + radius: 2 + } + } + + first.handle: Rectangle { + x: control.leftPadding + control.first.visualPosition * (control.availableWidth - width) + y: control.topPadding + control.availableHeight / 2 - height / 2 + implicitWidth: 26 + implicitHeight: 26 + radius: 13 + color: control.first.pressed ? "#f0f0f0" : "#f6f6f6" + border.color: "#bdbebf" + } + + second.handle: Rectangle { + x: control.leftPadding + control.second.visualPosition * (control.availableWidth - width) + y: control.topPadding + control.availableHeight / 2 - height / 2 + implicitWidth: 26 + implicitHeight: 26 + radius: 13 + color: control.second.pressed ? "#f0f0f0" : "#f6f6f6" + border.color: "#bdbebf" + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-roundbutton.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-roundbutton.qml new file mode 100644 index 00000000000..201ee24403d --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-roundbutton.qml @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +RoundButton { + text: "\u2713" // Unicode Character 'CHECK MARK' + onClicked: textArea.readOnly = true +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollbar-active.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollbar-active.qml new file mode 100644 index 00000000000..bd417955e4f --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollbar-active.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: 100 + height: 100 + + //! [1] + Flickable { + anchors.fill: parent + + contentWidth: parent.width * 2 + contentHeight: parent.height * 2 + + ScrollBar.horizontal: ScrollBar { id: hbar; active: vbar.active } + ScrollBar.vertical: ScrollBar { id: vbar; active: hbar.active } + } + //! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollbar-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollbar-custom.qml new file mode 100644 index 00000000000..50db35f97b9 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollbar-custom.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +ScrollBar { + id: control + size: 0.3 + position: 0.2 + active: true + orientation: Qt.Vertical + + contentItem: Rectangle { + implicitWidth: 6 + implicitHeight: 100 + radius: width / 2 + color: control.pressed ? "#81e889" : "#c2f4c6" + // Hide the ScrollBar when it's not needed. + opacity: control.policy === ScrollBar.AlwaysOn || (control.active && control.size < 1.0) ? 0.75 : 0 + + // Animate the changes in opacity (default duration is 250 ms). + Behavior on opacity { + NumberAnimation {} + } + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollbar-non-attached.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollbar-non-attached.qml new file mode 100644 index 00000000000..7ca66615572 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollbar-non-attached.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: 200 + height: 200 + +//! [1] +Rectangle { + id: frame + clip: true + width: 160 + height: 160 + border.color: "black" + anchors.centerIn: parent + + Text { + id: content + text: "ABC" + font.pixelSize: 160 + x: -hbar.position * width + y: -vbar.position * height + } + + ScrollBar { + id: vbar + hoverEnabled: true + active: hovered || pressed + orientation: Qt.Vertical + size: frame.height / content.height + anchors.top: parent.top + anchors.right: parent.right + anchors.bottom: parent.bottom + } + + ScrollBar { + id: hbar + hoverEnabled: true + active: hovered || pressed + orientation: Qt.Horizontal + size: frame.width / content.width + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + } +} +//! [1] + +Component.onCompleted: { + hbar.active = true + vbar.active = true +} +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollbar-policy.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollbar-policy.qml new file mode 100644 index 00000000000..c608dac44a1 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollbar-policy.qml @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +Flickable { + contentHeight: 2000 + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AlwaysOn + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollindicator-active.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollindicator-active.qml new file mode 100644 index 00000000000..719b9393f1d --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollindicator-active.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: 100 + height: 100 + + //! [1] + Flickable { + anchors.fill: parent + + contentWidth: parent.width * 2 + contentHeight: parent.height * 2 + + ScrollIndicator.horizontal: ScrollIndicator { id: hbar; active: vbar.active } + ScrollIndicator.vertical: ScrollIndicator { id: vbar; active: hbar.active } + } + //! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollindicator-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollindicator-custom.qml new file mode 100644 index 00000000000..b18d391c4d7 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollindicator-custom.qml @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +ScrollIndicator { + id: control + size: 0.3 + position: 0.2 + active: true + orientation: Qt.Vertical + + contentItem: Rectangle { + implicitWidth: 2 + implicitHeight: 100 + color: "#c2f4c6" + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollindicator-non-attached.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollindicator-non-attached.qml new file mode 100644 index 00000000000..0d6c4529dd3 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollindicator-non-attached.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: 200 + height: 200 + +//! [1] +Rectangle { + id: frame + clip: true + width: 160 + height: 160 + border.color: "black" + anchors.centerIn: parent + + Text { + id: content + text: "ABC" + font.pixelSize: 169 + + MouseArea { + id: mouseArea + drag.target: content + drag.minimumX: frame.width - width + drag.minimumY: frame.height - height + drag.maximumX: 0 + drag.maximumY: 0 + anchors.fill: content + } + } + + ScrollIndicator { + id: verticalIndicator + active: mouseArea.pressed + orientation: Qt.Vertical + size: frame.height / content.height + position: -content.y / content.height + anchors { top: parent.top; right: parent.right; bottom: parent.bottom } + } + + ScrollIndicator { + id: horizontalIndicator + active: mouseArea.pressed + orientation: Qt.Horizontal + size: frame.width / content.width + position: -content.x / content.width + anchors { left: parent.left; right: parent.right; bottom: parent.bottom } + } +} +//! [1] + +Component.onCompleted: { + horizontalIndicator.active = true; + verticalIndicator.active = true; +} +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview-custom.qml new file mode 100644 index 00000000000..1a80d263b78 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview-custom.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: 200 + height: 200 + + Binding { + target: control.ScrollBar.horizontal + property: "active" + value: true + } + + Binding { + target: control.ScrollBar.vertical + property: "active" + value: true + } + +//! [file] +ScrollView { + id: control + + width: 200 + height: 200 + focus: true + + Label { + text: "ABC" + font.pixelSize: 224 + } + + ScrollBar.vertical: ScrollBar { + parent: control + x: control.mirrored ? 0 : control.width - width + y: control.topPadding + height: control.availableHeight + active: control.ScrollBar.horizontal.active + } + + ScrollBar.horizontal: ScrollBar { + parent: control + x: control.leftPadding + y: control.height - height + width: control.availableWidth + active: control.ScrollBar.vertical.active + } + + background: Rectangle { + border.color: control.activeFocus ? "#21be2b" : "#bdbebf" + } +} +//! [file] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview-interactive.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview-interactive.qml new file mode 100644 index 00000000000..8386172035b --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview-interactive.qml @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [file] +ScrollView { + // ... + ScrollBar.horizontal.interactive: true + ScrollBar.vertical.interactive: true +} +//! [file] + diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview-listview.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview-listview.qml new file mode 100644 index 00000000000..bc1b11bd088 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview-listview.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + id: root + width: 200 + height: 200 + + Binding { + target: root.children[0].ScrollBar.horizontal + property: "active" + value: true + } + + Binding { + target: root.children[0].ScrollBar.vertical + property: "active" + value: true + } + +//! [file] +ScrollView { + width: 200 + height: 200 + + ListView { + model: 20 + delegate: ItemDelegate { + text: "Item " + index + + required property int index + } + } +} +//! [file] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview-policy.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview-policy.qml new file mode 100644 index 00000000000..78098eaaa6d --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview-policy.qml @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [file] +ScrollView { + // ... + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + ScrollBar.vertical.policy: ScrollBar.AlwaysOn +} +//! [file] + diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview.qml new file mode 100644 index 00000000000..c96ae1ed89f --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-scrollview.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Rectangle { + id: root + width: 200 + height: 200 + border.color: "#ddd" + + Binding { + target: root.children[0].ScrollBar.horizontal + property: "active" + value: true + } + + Binding { + target: root.children[0].ScrollBar.vertical + property: "active" + value: true + } + +//! [file] +ScrollView { + width: 200 + height: 200 + + Label { + text: "ABC" + font.pixelSize: 224 + } +} +//! [file] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-selectionrectangle.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-selectionrectangle.qml new file mode 100644 index 00000000000..c8668324327 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-selectionrectangle.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtQml.Models +import Qt.labs.qmlmodels + +Window { + width: 480 + height: 640 + visible: true + visibility: Window.AutomaticVisibility + +//![0] + TableView { + id: tableView + anchors.fill: parent + clip: true + + model: TableModel { + TableModelColumn { display: "name" } + rows: [ { "name": "Harry" }, { "name": "Hedwig" } ] + } + + selectionModel: ItemSelectionModel { + model: tableView.model + } + + delegate: Rectangle { + implicitWidth: 100 + implicitHeight: 30 + color: selected ? "blue" : "lightgray" + + required property bool selected + + Text { text: display } + } + } + + SelectionRectangle { + target: tableView + } +//![0] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-slider-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-slider-custom.qml new file mode 100644 index 00000000000..c3d7f4b2d1e --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-slider-custom.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +Slider { + id: control + value: 0.5 + + background: Rectangle { + x: control.leftPadding + y: control.topPadding + control.availableHeight / 2 - height / 2 + implicitWidth: 200 + implicitHeight: 4 + width: control.availableWidth + height: implicitHeight + radius: 2 + color: "#bdbebf" + + Rectangle { + width: control.visualPosition * parent.width + height: parent.height + color: "#21be2b" + radius: 2 + } + } + + handle: Rectangle { + x: control.leftPadding + control.visualPosition * (control.availableWidth - width) + y: control.topPadding + control.availableHeight / 2 - height / 2 + implicitWidth: 26 + implicitHeight: 26 + radius: 13 + color: control.pressed ? "#f0f0f0" : "#f6f6f6" + border.color: "#bdbebf" + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-spinbox-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-spinbox-custom.qml new file mode 100644 index 00000000000..89f6244f70b --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-spinbox-custom.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +SpinBox { + id: control + value: 50 + editable: true + + contentItem: TextInput { + z: 2 + text: control.textFromValue(control.value, control.locale) + + font: control.font + color: "#21be2b" + selectionColor: "#21be2b" + selectedTextColor: "#ffffff" + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + + readOnly: !control.editable + validator: control.validator + inputMethodHints: Qt.ImhFormattedNumbersOnly + } + + up.indicator: Rectangle { + x: control.mirrored ? 0 : parent.width - width + height: parent.height + implicitWidth: 40 + implicitHeight: 40 + color: control.up.pressed ? "#e4e4e4" : "#f6f6f6" + border.color: enabled ? "#21be2b" : "#bdbebf" + + Text { + text: "+" + font.pixelSize: control.font.pixelSize * 2 + color: "#21be2b" + anchors.fill: parent + fontSizeMode: Text.Fit + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + down.indicator: Rectangle { + x: control.mirrored ? parent.width - width : 0 + height: parent.height + implicitWidth: 40 + implicitHeight: 40 + color: control.down.pressed ? "#e4e4e4" : "#f6f6f6" + border.color: enabled ? "#21be2b" : "#bdbebf" + + Text { + text: "-" + font.pixelSize: control.font.pixelSize * 2 + color: "#21be2b" + anchors.fill: parent + fontSizeMode: Text.Fit + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + background: Rectangle { + implicitWidth: 140 + border.color: "#bdbebf" + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-spinbox-double.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-spinbox-double.qml new file mode 100644 index 00000000000..852ee5be6f4 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-spinbox-double.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +SpinBox { + id: spinbox + from: 0 + value: 110 + to: 100 * 100 + stepSize: 100 + anchors.centerIn: parent + + property int decimals: 2 + property real realValue: value / 100 + + validator: DoubleValidator { + bottom: Math.min(spinbox.from, spinbox.to) + top: Math.max(spinbox.from, spinbox.to) + } + + textFromValue: function(value, locale) { + return Number(value / 100).toLocaleString(locale, 'f', spinbox.decimals) + } + + valueFromText: function(text, locale) { + return Number.fromLocaleString(locale, text) * 100 + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-spinbox-textual.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-spinbox-textual.qml new file mode 100644 index 00000000000..ba3b133c14c --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-spinbox-textual.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +SpinBox { + id: spinBox + from: 0 + to: items.length - 1 + value: 1 // "Medium" + + property var items: ["Small", "Medium", "Large"] + + validator: RegularExpressionValidator { + regularExpression: new RegExp("(Small|Medium|Large)", "i") + } + + textFromValue: function(value) { + return items[value]; + } + + valueFromText: function(text) { + for (var i = 0; i < items.length; ++i) { + if (items[i].toLowerCase().indexOf(text.toLowerCase()) === 0) + return i + } + return spinBox.value + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-spinbox.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-spinbox.qml new file mode 100644 index 00000000000..8772274969a --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-spinbox.qml @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +SpinBox { + value: 50 +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-splitview-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-splitview-custom.qml new file mode 100644 index 00000000000..570c3acd33b --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-splitview-custom.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: 200 + height: 100 + + //! [1] + SplitView { + id: splitView + anchors.fill: parent + + handle: Rectangle { + implicitWidth: 4 + implicitHeight: 4 + color: SplitHandle.pressed ? "#81e889" + : (SplitHandle.hovered ? Qt.lighter("#c2f4c6", 1.1) : "#c2f4c6") + } + + Rectangle { + implicitWidth: 150 + color: "#444" + } + Rectangle { + implicitWidth: 50 + color: "#666" + } + } + //! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-splitview-handle-containmentmask.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-splitview-handle-containmentmask.qml new file mode 100644 index 00000000000..da410c02e08 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-splitview-handle-containmentmask.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: 200 + height: 100 + + //! [1] + SplitView { + id: splitView + anchors.fill: parent + + handle: Rectangle { + id: handleDelegate + implicitWidth: 4 + implicitHeight: 4 + color: SplitHandle.pressed ? "#81e889" + : (SplitHandle.hovered ? Qt.lighter("#c2f4c6", 1.1) : "#c2f4c6") + + containmentMask: Item { + x: (handleDelegate.width - width) / 2 + width: 64 + height: splitView.height + } + } + + Rectangle { + implicitWidth: 150 + color: "#444" + } + Rectangle { + implicitWidth: 50 + color: "#666" + } + } + //! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-stackview-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-stackview-custom.qml new file mode 100644 index 00000000000..64cdb3ceb90 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-stackview-custom.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +StackView { + id: control + + popEnter: Transition { + XAnimator { + from: (control.mirrored ? -1 : 1) * -control.width + to: 0 + duration: 400 + easing.type: Easing.OutCubic + } + } + + popExit: Transition { + XAnimator { + from: 0 + to: (control.mirrored ? -1 : 1) * control.width + duration: 400 + easing.type: Easing.OutCubic + } + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-stackview-visible.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-stackview-visible.qml new file mode 100644 index 00000000000..0e1a0dd495c --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-stackview-visible.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +StackView { + id: stackView + property real offset: 10 + width: 100; height: 100 + + initialItem: Component { + id: page + Rectangle { + property real pos: StackView.index * stackView.offset + property real hue: Math.random() + color: Qt.hsla(hue, 0.5, 0.8, 0.6) + border.color: Qt.hsla(hue, 0.5, 0.5, 0.9) + StackView.visible: true + } + } + + pushEnter: Transition { + id: pushEnter + ParallelAnimation { + PropertyAction { property: "x"; value: pushEnter.ViewTransition.item.pos } + NumberAnimation { properties: "y"; from: pushEnter.ViewTransition.item.pos + stackView.offset; to: pushEnter.ViewTransition.item.pos; duration: 400; easing.type: Easing.OutCubic } + NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 400; easing.type: Easing.OutCubic } + } + } + popExit: Transition { + id: popExit + ParallelAnimation { + PropertyAction { property: "x"; value: popExit.ViewTransition.item.pos } + NumberAnimation { properties: "y"; from: popExit.ViewTransition.item.pos; to: popExit.ViewTransition.item.pos + stackView.offset; duration: 400; easing.type: Easing.OutCubic } + NumberAnimation { property: "opacity"; from: 1; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + } + + pushExit: Transition { + id: pushExit + PropertyAction { property: "x"; value: pushExit.ViewTransition.item.pos } + PropertyAction { property: "y"; value: pushExit.ViewTransition.item.pos } + } + popEnter: Transition { + id: popEnter + PropertyAction { property: "x"; value: popEnter.ViewTransition.item.pos } + PropertyAction { property: "y"; value: popEnter.ViewTransition.item.pos } + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate-custom.qml new file mode 100644 index 00000000000..c89b96a42f2 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate-custom.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +SwipeDelegate { + id: control + text: qsTr("SwipeDelegate") + + Component { + id: component + + Rectangle { + color: SwipeDelegate.pressed ? "#333" : "#444" + width: parent.width + height: parent.height + clip: true + + Label { + text: qsTr("Press me!") + color: "#21be2b" + anchors.centerIn: parent + } + } + } + + swipe.left: component + swipe.right: component + + contentItem: Text { + text: control.text + font: control.font + color: control.enabled ? (control.down ? "#17a81a" : "#21be2b") : "#bdbebf" + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + + Behavior on x { + enabled: !control.down + NumberAnimation { + easing.type: Easing.InOutCubic + duration: 400 + } + } + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate-transition.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate-transition.qml new file mode 100644 index 00000000000..dc0d58a2cad --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate-transition.qml @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +SwipeDelegate { + swipe.transition: Transition { + SmoothedAnimation { velocity: 3; easing.type: Easing.InOutCubic } + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate.qml new file mode 100644 index 00000000000..866e7114810 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipedelegate.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +ListView { + id: listView + anchors.fill: parent + model: ListModel { + ListElement { sender: "Bob Bobbleton"; title: "How are you going?" } + ListElement { sender: "Rug Emporium"; title: "SALE! All rugs MUST go!" } + ListElement { sender: "Electric Co."; title: "Electricity bill 15/07/2016 overdue" } + ListElement { sender: "Tips"; title: "Five ways this tip will save your life" } + } + delegate: SwipeDelegate { + id: swipeDelegate + text: sender + " - " + title + width: listView.width + + required property string sender + required property string title + required property int index + + ListView.onRemove: SequentialAnimation { + PropertyAction { + target: swipeDelegate + property: "ListView.delayRemove" + value: true + } + NumberAnimation { + target: swipeDelegate + property: "height" + to: 0 + easing.type: Easing.InOutQuad + } + PropertyAction { + target: swipeDelegate + property: "ListView.delayRemove" + value: false + } + } + + swipe.right: Label { + id: deleteLabel + text: qsTr("Delete") + color: "white" + verticalAlignment: Label.AlignVCenter + padding: 12 + height: parent.height + anchors.right: parent.right + + SwipeDelegate.onClicked: listView.model.remove(index) + + background: Rectangle { + color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato" + } + } + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipeview-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipeview-custom.qml new file mode 100644 index 00000000000..b8cddb315af --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipeview-custom.qml @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +SwipeView { + id: control + + background: Rectangle { + color: "#eeeeee" + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipeview-indicator.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipeview-indicator.qml new file mode 100644 index 00000000000..98b381f14ee --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-swipeview-indicator.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: 200 + height: 320 + + //! [1] + SwipeView { + id: view + + currentIndex: 1 + anchors.fill: parent + + Item { + id: firstPage + } + Item { + id: secondPage + } + Item { + id: thirdPage + } + } + + PageIndicator { + id: indicator + + count: view.count + currentIndex: view.currentIndex + + anchors.bottom: view.bottom + anchors.horizontalCenter: parent.horizontalCenter + } + //! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-switch-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-switch-custom.qml new file mode 100644 index 00000000000..9adccbed2f5 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-switch-custom.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +Switch { + id: control + text: qsTr("Switch") + + indicator: Rectangle { + implicitWidth: 48 + implicitHeight: 26 + x: control.leftPadding + y: parent.height / 2 - height / 2 + radius: 13 + color: control.checked ? "#17a81a" : "#ffffff" + border.color: control.checked ? "#17a81a" : "#cccccc" + + Rectangle { + x: control.checked ? parent.width - width : 0 + width: 26 + height: 26 + radius: 13 + color: control.down ? "#cccccc" : "#ffffff" + border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999" + } + } + + contentItem: Text { + text: control.text + font: control.font + opacity: enabled ? 1.0 : 0.3 + color: control.down ? "#17a81a" : "#21be2b" + verticalAlignment: Text.AlignVCenter + leftPadding: control.indicator.width + control.spacing + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-switchdelegate-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-switchdelegate-custom.qml new file mode 100644 index 00000000000..bea35f29ea7 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-switchdelegate-custom.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +SwitchDelegate { + id: control + text: qsTr("SwitchDelegate") + checked: true + + contentItem: Text { + rightPadding: control.indicator.width + control.spacing + text: control.text + font: control.font + opacity: enabled ? 1.0 : 0.3 + color: control.down ? "#17a81a" : "#21be2b" + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + indicator: Rectangle { + implicitWidth: 48 + implicitHeight: 26 + x: control.width - width - control.rightPadding + y: parent.height / 2 - height / 2 + radius: 13 + color: control.checked ? "#17a81a" : "transparent" + border.color: control.checked ? "#17a81a" : "#cccccc" + + Rectangle { + x: control.checked ? parent.width - width : 0 + width: 26 + height: 26 + radius: 13 + color: control.down ? "#cccccc" : "#ffffff" + border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999" + } + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + visible: control.down || control.highlighted + color: control.down ? "#bdbebf" : "#eeeeee" + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbar-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbar-custom.qml new file mode 100644 index 00000000000..eba48256320 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbar-custom.qml @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +TabBar { + id: control + + background: Rectangle { + color: "#eeeeee" + } + + TabButton { + text: qsTr("Home") + } + TabButton { + text: qsTr("Discover") + } + TabButton { + text: qsTr("Activity") + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbar-explicit.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbar-explicit.qml new file mode 100644 index 00000000000..5f5482551f6 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbar-explicit.qml @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: 360 + height: childrenRect.height + +//! [1] +TabBar { + width: parent.width + TabButton { + text: "First" + width: implicitWidth + } + TabButton { + text: "Second" + width: implicitWidth + } + TabButton { + text: "Third" + width: implicitWidth + } +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbar-flickable.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbar-flickable.qml new file mode 100644 index 00000000000..8e41bbf0cac --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbar-flickable.qml @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: 360 + height: bar.height + +//! [1] +TabBar { + id: bar + width: parent.width + + Repeater { + model: ["First", "Second", "Third", "Fourth", "Fifth"] + + TabButton { + text: modelData + width: Math.max(100, bar.width / 5) + } + } +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbar.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbar.qml new file mode 100644 index 00000000000..7a02f37521a --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbar.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +Column { + width: 300 + + //! [1] + TabBar { + id: bar + width: parent.width + TabButton { + text: qsTr("Home") + } + TabButton { + text: qsTr("Discover") + } + TabButton { + text: qsTr("Activity") + } + } + + StackLayout { + width: parent.width + currentIndex: bar.currentIndex + Item { + id: homeTab + } + Item { + id: discoverTab + } + Item { + id: activityTab + } + } + //! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbutton.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbutton.qml new file mode 100644 index 00000000000..e7240db4dc2 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tabbutton.qml @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +TabBar { + TabButton { + text: qsTr("Home") + } + TabButton { + text: qsTr("Discover") + } + TabButton { + text: qsTr("Activity") + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-textarea-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-textarea-custom.qml new file mode 100644 index 00000000000..e4f1b397d49 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-textarea-custom.qml @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +TextArea { + id: control + placeholderText: qsTr("Enter description") + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 40 + border.color: control.enabled ? "#21be2b" : "transparent" + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-textarea-scrollable.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-textarea-scrollable.qml new file mode 100644 index 00000000000..52d9996e9b1 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-textarea-scrollable.qml @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + width: 100 + height: 100 + + Binding { target: view.ScrollBar.vertical; property: "active"; value: true } + + //! [1] + ScrollView { + id: view + anchors.fill: parent + + TextArea { + text: "TextArea\n...\n...\n...\n...\n...\n...\n" + } + } + //! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-textfield-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-textfield-custom.qml new file mode 100644 index 00000000000..8f1aba233eb --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-textfield-custom.qml @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +TextField { + id: control + placeholderText: qsTr("Enter description") + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 40 + color: control.enabled ? "transparent" : "#353637" + border.color: control.enabled ? "#21be2b" : "transparent" + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-textfield-disabled.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-textfield-disabled.qml new file mode 100644 index 00000000000..3d92b647606 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-textfield-disabled.qml @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +TextField { + width: 80 + text: "Disabled" + enabled: false +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-textfield-focused.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-textfield-focused.qml new file mode 100644 index 00000000000..f2761988573 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-textfield-focused.qml @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +TextField { + width: 80 + text: "Focused" + focus: true +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-textfield-normal.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-textfield-normal.qml new file mode 100644 index 00000000000..c9208c0e8fd --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-textfield-normal.qml @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +TextField { + width: 80 + text: "Normal" +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolbar-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolbar-custom.qml new file mode 100644 index 00000000000..2cb9d0c5c7a --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolbar-custom.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +//! [file] +ToolBar { + id: control + + background: Rectangle { + implicitHeight: 40 + color: "#eeeeee" + + Rectangle { + width: parent.width + height: 1 + anchors.bottom: parent.bottom + color: "transparent" + border.color: "#21be2b" + } + } + + RowLayout { + anchors.fill: parent + ToolButton { + text: qsTr("Undo") + } + ToolButton { + text: qsTr("Redo") + } + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolbar.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolbar.qml new file mode 100644 index 00000000000..52445d93d79 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolbar.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +Item { + id: root + width: children[0].implicitWidth * 2 + height: children[0].implicitHeight + Binding { + target: root.children[0] + property: "width" + value: root.width + } +//! [1] +ToolBar { + RowLayout { + anchors.fill: parent + ToolButton { + text: qsTr("‹") + onClicked: stack.pop() + } + Label { + text: "Title" + elide: Label.ElideRight + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + Layout.fillWidth: true + } + ToolButton { + text: qsTr("⋮") + onClicked: menu.open() + } + } +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolbutton-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolbutton-custom.qml new file mode 100644 index 00000000000..8eb27430da8 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolbutton-custom.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +ToolButton { + id: control + text: qsTr("ToolButton") + width: 120 + + contentItem: Text { + text: control.text + font: control.font + opacity: enabled ? 1.0 : 0.3 + color: control.down ? "#17a81a" : "#21be2b" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + implicitWidth: 40 + implicitHeight: 40 + color: Qt.darker("#33333333", control.enabled && (control.checked || control.highlighted) ? 1.5 : 1.0) + opacity: enabled ? 1 : 0.3 + visible: control.down || (control.enabled && (control.checked || control.highlighted)) + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolseparator-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolseparator-custom.qml new file mode 100644 index 00000000000..f630256dd9c --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolseparator-custom.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Window +import QtQuick.Controls + +//! [file] +ToolBar { + RowLayout { + anchors.fill: parent + + ToolButton { + text: qsTr("Action 1") + } + ToolButton { + text: qsTr("Action 2") + } + + ToolSeparator { + padding: vertical ? 10 : 2 + topPadding: vertical ? 2 : 10 + bottomPadding: vertical ? 2 : 10 + + contentItem: Rectangle { + implicitWidth: parent.vertical ? 1 : 24 + implicitHeight: parent.vertical ? 24 : 1 + color: "#c3c3c3" + } + } + + ToolButton { + text: qsTr("Action 3") + } + ToolButton { + text: qsTr("Action 4") + } + + Item { + Layout.fillWidth: true + } + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolseparator.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolseparator.qml new file mode 100644 index 00000000000..514b97fa688 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-toolseparator.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Window +import QtQuick.Controls + +//! [1] +ToolBar { + RowLayout { + anchors.fill: parent + + ToolButton { + text: qsTr("Action 1") + } + ToolButton { + text: qsTr("Action 2") + } + + ToolSeparator {} + + ToolButton { + text: qsTr("Action 3") + } + ToolButton { + text: qsTr("Action 4") + } + + ToolSeparator {} + + ToolButton { + text: qsTr("Action 5") + } + ToolButton { + text: qsTr("Action 6") + } + + Item { + Layout.fillWidth: true + } + } +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip-custom.qml new file mode 100644 index 00000000000..7b40c974b65 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip-custom.qml @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +Item { +ToolTip { + id: control + text: qsTr("A descriptive tool tip of what the button does") + + contentItem: Text { + text: control.text + font: control.font + color: "#21be2b" + } + + background: Rectangle { + border.color: "#21be2b" + } +} +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip-hover.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip-hover.qml new file mode 100644 index 00000000000..6d1ee4c41bb --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip-hover.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +Button { + text: qsTr("Button") + hoverEnabled: true + + ToolTip.delay: 1000 + ToolTip.timeout: 5000 + ToolTip.visible: hovered + ToolTip.text: qsTr("This tool tip is shown after hovering the button for a second.") +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip-pressandhold.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip-pressandhold.qml new file mode 100644 index 00000000000..cea495538b8 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip-pressandhold.qml @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [1] +Button { + text: qsTr("Button") + + ToolTip.visible: pressed + ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval + ToolTip.text: qsTr("This tool tip is shown after pressing and holding the button down.") +} +//! [1] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip-slider.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip-slider.qml new file mode 100644 index 00000000000..5f408224579 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip-slider.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Item { + id: root + width: slider.width + height: slider.height * 2.0 + + Binding { target: slider.anchors; property: "centerIn"; value: root } + Binding { target: slider.anchors; property: "verticalCenterOffset"; value: slider.height / 2 } + Binding { target: slider; property: "pressed"; value: root.Window.active } + + //! [1] + Slider { + id: slider + value: 0.5 + + ToolTip { + parent: slider.handle + visible: slider.pressed + text: slider.value.toFixed(1) + } + } + //! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip.qml new file mode 100644 index 00000000000..72eaaba5fad --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tooltip.qml @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Item { + id: root + width: 360 + height: button.height * 2 + + property Button button: children[0] + + Binding { target: root.button; property: "down"; value: root.Window.active } + Binding { target: root.button.anchors; property: "bottom"; value: root.bottom } + Binding { target: root.button.anchors; property: "horizontalCenter"; value: root.horizontalCenter } + + //! [1] + Button { + text: qsTr("Save") + + ToolTip.visible: down + ToolTip.text: qsTr("Save the active project") + } + //! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tumbler-custom.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tumbler-custom.qml new file mode 100644 index 00000000000..ee637d23be9 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tumbler-custom.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [file] +import QtQuick +import QtQuick.Controls + +Tumbler { + id: control + model: 15 + + background: Item { + Rectangle { + opacity: control.enabled ? 0.2 : 0.1 + border.color: "#000000" + width: parent.width + height: 1 + anchors.top: parent.top + } + + Rectangle { + opacity: control.enabled ? 0.2 : 0.1 + border.color: "#000000" + width: parent.width + height: 1 + anchors.bottom: parent.bottom + } + } + + delegate: Text { + text: qsTr("Item %1").arg(modelData + 1) + font: control.font + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + opacity: 1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2) + + required property var modelData + required property int index + } + + Rectangle { + anchors.horizontalCenter: control.horizontalCenter + y: control.height * 0.4 + width: 40 + height: 1 + color: "#21be2b" + } + + Rectangle { + anchors.horizontalCenter: control.horizontalCenter + y: control.height * 0.6 + width: 40 + height: 1 + color: "#21be2b" + } +} +//! [file] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tumbler-listView.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tumbler-listView.qml new file mode 100644 index 00000000000..54ce78afd39 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tumbler-listView.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [contentItem] +Tumbler { + id: tumbler + + contentItem: ListView { + model: tumbler.model + delegate: tumbler.delegate + + snapMode: ListView.SnapToItem + highlightRangeMode: ListView.StrictlyEnforceRange + preferredHighlightBegin: height / 2 - (height / tumbler.visibleItemCount / 2) + preferredHighlightEnd: height / 2 + (height / tumbler.visibleItemCount / 2) + clip: true + } +} +//! [contentItem] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tumbler-pathView.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tumbler-pathView.qml new file mode 100644 index 00000000000..408b7479205 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tumbler-pathView.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +//! [contentItem] +Tumbler { + id: tumbler + + contentItem: PathView { + id: pathView + model: tumbler.model + delegate: tumbler.delegate + clip: true + pathItemCount: tumbler.visibleItemCount + 1 + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + dragMargin: width / 2 + + path: Path { + startX: pathView.width / 2 + startY: -pathView.delegateHeight / 2 + PathLine { + x: pathView.width / 2 + y: pathView.pathItemCount * pathView.delegateHeight - pathView.delegateHeight / 2 + } + } + + property real delegateHeight: tumbler.availableHeight / tumbler.visibleItemCount + } +} +//! [contentItem] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-tumbler-timePicker.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tumbler-timePicker.qml new file mode 100644 index 00000000000..d9edb2cb006 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-tumbler-timePicker.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [tumbler] +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Rectangle { + width: frame.implicitWidth + 10 + height: frame.implicitHeight + 10 + + function formatText(count, modelData) { + var data = count === 12 ? modelData + 1 : modelData; + return data.toString().length < 2 ? "0" + data : data; + } + + FontMetrics { + id: fontMetrics + } + + Component { + id: delegateComponent + + Label { + text: formatText(Tumbler.tumbler.count, modelData) + opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2) + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pixelSize: fontMetrics.font.pixelSize * 1.25 + } + } + + Frame { + id: frame + padding: 0 + anchors.centerIn: parent + + Row { + id: row + + Tumbler { + id: hoursTumbler + model: 12 + delegate: delegateComponent + } + + Tumbler { + id: minutesTumbler + model: 60 + delegate: delegateComponent + } + + Tumbler { + id: amPmTumbler + model: ["AM", "PM"] + delegate: delegateComponent + } + } + } +} +//! [tumbler] diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-universal-accent.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-universal-accent.qml new file mode 100644 index 00000000000..f429359e4f7 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-universal-accent.qml @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Universal + +Pane { + padding: 10 + +//! [1] +Button { + text: qsTr("Button") + highlighted: true + Universal.accent: Universal.Orange +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-universal-background.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-universal-background.qml new file mode 100644 index 00000000000..558618e65e1 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-universal-background.qml @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Universal + +Pane { + padding: 10 + +//! [1] +Pane { + Universal.background: Universal.Steel + + Button { + text: qsTr("Button") + } +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-universal-foreground.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-universal-foreground.qml new file mode 100644 index 00000000000..39a292d88b0 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-universal-foreground.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Universal + +Pane { + padding: 10 + +//! [1] +Button { + text: qsTr("Button") + Universal.foreground: Universal.Pink +} +//! [1] +} diff --git a/src/quickcontrols2/doc/snippets/qtquickcontrols2-universal-theme.qml b/src/quickcontrols2/doc/snippets/qtquickcontrols2-universal-theme.qml new file mode 100644 index 00000000000..b55bf188bf2 --- /dev/null +++ b/src/quickcontrols2/doc/snippets/qtquickcontrols2-universal-theme.qml @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Universal + +Pane { + padding: 10 + +//! [1] +Pane { + Universal.theme: Universal.Dark + + Button { + text: qsTr("Button") + } +} +//! [1] +} diff --git a/src/quickcontrols2/doc/src/external-pages.qdoc b/src/quickcontrols2/doc/src/external-pages.qdoc new file mode 100644 index 00000000000..0500579818f --- /dev/null +++ b/src/quickcontrols2/doc/src/external-pages.qdoc @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \externalpage https://doc.qt.io/qt-5/qtquickcontrols2-differences.html + \title Qt 5.15: Qt Quick Controls vs Qt Quick Controls 1 +*/ + +/*! + \externalpage https://doc.qt.io/qtcreator/creator-project-creating.html#selecting-project-type + \title Qt Creator: Project Types +*/ diff --git a/src/quickcontrols2/doc/src/includes/container-currentindex.qdocinc b/src/quickcontrols2/doc/src/includes/container-currentindex.qdocinc new file mode 100644 index 00000000000..9fcf43e168a --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/container-currentindex.qdocinc @@ -0,0 +1,9 @@ +//! [file] +When \1 is paired with another container such as \l \2, it is +necessary to make a two-way binding between the +\l {Container::}{currentIndex} property +of each control. To do this without breaking bindings, avoid setting +\c currentIndex directly, and instead use +\l {Container::}{setCurrentIndex()}, for example. +See \l {Managing the Current Index} for more information. +//! [file] diff --git a/src/quickcontrols2/doc/src/includes/customize-button-background.qdocinc b/src/quickcontrols2/doc/src/includes/customize-button-background.qdocinc new file mode 100644 index 00000000000..0acad02d38a --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/customize-button-background.qdocinc @@ -0,0 +1,25 @@ +//! [file] +\qml +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + visible: true + + Button { + id: button + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: button.down ? "#d6d6d6" : "#f6f6f6" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } +} +\endqml +//! [file] diff --git a/src/quickcontrols2/doc/src/includes/customizing-native-styles.qdocinc b/src/quickcontrols2/doc/src/includes/customizing-native-styles.qdocinc new file mode 100644 index 00000000000..e1feacaa49b --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/customizing-native-styles.qdocinc @@ -0,0 +1,14 @@ +It is instead recommended to always base a customized control on top of a single style +that is available on all platforms, e.g \l {Basic Style}, \l {Fusion Style}, \l {Imagine Style}, +\l {Material Style}, \l {Universal Style}. By doing so, you are guaranteed that it will +always look the same, regardless of which style the application is run with. For example: + +\code + import QtQuick.Controls.Basic as Basic + + Basic.SpinBox { + background: Rectangle { /* ... */ } + } +\endcode + +\b {See also} \l {Styling Qt Quick Controls} diff --git a/src/quickcontrols2/doc/src/includes/inputmethodhints.qdocinc b/src/quickcontrols2/doc/src/includes/inputmethodhints.qdocinc new file mode 100644 index 00000000000..73710e1e152 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/inputmethodhints.qdocinc @@ -0,0 +1,38 @@ +//! [flags] +The value is a bit-wise combination of flags or \c Qt.ImhNone if no hints are set. + +Flags that alter behavior are: + +\list +\li Qt.ImhHiddenText - Characters should be hidden, as is typically used when entering passwords. +\li Qt.ImhSensitiveData - Typed text should not be stored by the active input method + in any persistent storage like predictive user dictionary. +\li Qt.ImhNoAutoUppercase - The input method should not try to automatically switch to upper case + when a sentence ends. +\li Qt.ImhPreferNumbers - Numbers are preferred (but not required). +\li Qt.ImhPreferUppercase - Upper case letters are preferred (but not required). +\li Qt.ImhPreferLowercase - Lower case letters are preferred (but not required). +\li Qt.ImhNoPredictiveText - Do not use predictive text (i.e. dictionary lookup) while typing. + +\li Qt.ImhDate - The text editor functions as a date field. +\li Qt.ImhTime - The text editor functions as a time field. +\endlist + +Flags that restrict input (exclusive flags) are: + +\list +\li Qt.ImhDigitsOnly - Only digits are allowed. +\li Qt.ImhFormattedNumbersOnly - Only number input is allowed. This includes decimal point and minus sign. +\li Qt.ImhUppercaseOnly - Only upper case letter input is allowed. +\li Qt.ImhLowercaseOnly - Only lower case letter input is allowed. +\li Qt.ImhDialableCharactersOnly - Only characters suitable for phone dialing are allowed. +\li Qt.ImhEmailCharactersOnly - Only characters suitable for email addresses are allowed. +\li Qt.ImhUrlCharactersOnly - Only characters suitable for URLs are allowed. +\endlist + +Masks: + +\list +\li Qt.ImhExclusiveInputMask - This mask yields nonzero if any of the exclusive flags are used. +\endlist +//! [flags] diff --git a/src/quickcontrols2/doc/src/includes/qquickcombobox.qdocinc b/src/quickcontrols2/doc/src/includes/qquickcombobox.qdocinc new file mode 100644 index 00000000000..5e19f5f1f46 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickcombobox.qdocinc @@ -0,0 +1,6 @@ +//! [functions-after-component-completion] + +\note This function can only be used after +\l {Component::completed()}{Component.completed()} is emitted for the ComboBox. + +//! [functions-after-component-completion] diff --git a/src/quickcontrols2/doc/src/includes/qquickcontrol-background.qdocinc b/src/quickcontrols2/doc/src/includes/qquickcontrol-background.qdocinc new file mode 100644 index 00000000000..02d92de07cf --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickcontrol-background.qdocinc @@ -0,0 +1,13 @@ +//! [notes] + +\note If the background item has no explicit size specified, it automatically + follows the control's size. In most cases, there is no need to specify + width or height for a background item. + +\note Most controls use the implicit size of the background item to calculate +the implicit size of the control itself. If you replace the background item +with a custom one, you should also consider providing a sensible implicit +size for it (unless it is an item like \l Image which has its own implicit +size). + +//! [notes] diff --git a/src/quickcontrols2/doc/src/includes/qquickcontrol-focusreason.qdocinc b/src/quickcontrols2/doc/src/includes/qquickcontrol-focusreason.qdocinc new file mode 100644 index 00000000000..b69e9e60ec1 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickcontrol-focusreason.qdocinc @@ -0,0 +1,15 @@ +This property holds the reason of the last focus change. + +\note This property does not indicate whether the control has \l {Item::activeFocus} + {active focus}, but the reason why the control either gained or lost focus. + +\value Qt.MouseFocusReason A mouse action occurred. +\value Qt.TabFocusReason The Tab key was pressed. +\value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab. +\value Qt.ActiveWindowFocusReason The window system made this window either active or inactive. +\value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus. +\value Qt.ShortcutFocusReason The user typed a label's buddy shortcut +\value Qt.MenuBarFocusReason The menu bar took focus. +\value Qt.OtherFocusReason Another reason, usually application-specific. + +\sa Item::activeFocus diff --git a/src/quickcontrols2/doc/src/includes/qquickdial.qdocinc b/src/quickcontrols2/doc/src/includes/qquickdial.qdocinc new file mode 100644 index 00000000000..3370b3d8f39 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickdial.qdocinc @@ -0,0 +1,13 @@ +//! [inputMode] +Dial supports three \l {inputMode}{input modes}: \c Dial.Circular, +\c Dial.Horizontal and \c Dial.Vertical. The circular input mode operates on an +absolute input system, where the position of the cursor within the dial +directly reflects its value. The horizontal and vertical input modes use a +relative input system, where changes in the cursor's position are "added" to +the value of the dial. + +The following image illustrates the directions in which the various input modes +track movement: + +\image qtquickcontrols2-dial-inputmode.png +//! [inputMode] diff --git a/src/quickcontrols2/doc/src/includes/qquickheaderview.qdocinc b/src/quickcontrols2/doc/src/includes/qquickheaderview.qdocinc new file mode 100644 index 00000000000..7e12f53a6d7 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickheaderview.qdocinc @@ -0,0 +1,76 @@ +//! [detailed-description] +A \1 provides a styled table header. +It can either be used as an independent view or header for a \l TableView. + +You can add a header for a TableView by assigning a \1 +to the \l {TableView::syncView} property. The header and the table will +then be kept in sync while flicking. + +By default, \1 displays +\l {QAbstractItemModel::headerData()}{header data} +from the \l {TableView::syncView}{sync view's} \l {TableView::model}{model}. +If you don't wish to use this model, you can assign a different model to the +\l {TableView::model}{model} property. If you assign a model that is a +QAbstractItemModel, its header data will be used. Otherwise the data in +the model will be used directly (for example, if you assign a model that +is simply an array of strings). + +By default, \l textRole is set to \c "display", meaning that data from the +model's \l {Qt::ItemDataRole}{Qt::DisplayRole} will be used. You can set +this to another role name in order to have that data displayed instead. + +The application is responsible for placing the header at the +correct location in the scene. You can add as many headers as you +want to a single TableView, which can be useful if you for example want +to place headers on all four sides of the table. + +The following snippet shows how you can add a horizontal and vertical header +view to a table view: + +\snippet qtquickcontrols-headerview.qml 0 + +A \1 will have +\l {TableView::resizableColumns}{resizableColumns} set to \c true by default. +//! [detailed-description] + +//! [syncView] +This property holds the TableView to synchronize with. + +Once this property is bound to another TableView, both header and table +will synchronize with regard to column widths, column spacing, and flicking +\1. + +If the \l model is not explicitly set, then the header will use the syncView's +model to label the columns. + +\sa model TableView +//! [syncView] + +//! [model] +This property holds the model providing data for the \1 header view. + +When model is not explicitly set, the header will use the syncView's +model once syncView is set. + +If model is a QAbstractTableModel, its \1 headerData() will +be accessed. + +If model is a QAbstractItemModel other than QAbstractTableModel, model's data() +will be accessed. + +Otherwise, the behavior is same as setting TableView::model. + +\sa TableView {TableView::model} {model} QAbstractTableModel +//! [model] + +//! [textRole] +This property holds the model role used to display text in each header cell. + +When the model has multiple roles, textRole can be set to determine which +role should be displayed. + +If model is a QAbstractItemModel then it will default to "display"; otherwise +it is empty. + +\sa QAbstractItemModel::roleNames() +//! [textRole] diff --git a/src/quickcontrols2/doc/src/includes/qquickicon.qdocinc b/src/quickcontrols2/doc/src/includes/qquickicon.qdocinc new file mode 100644 index 00000000000..eadaea5983f --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickicon.qdocinc @@ -0,0 +1,52 @@ +//! [grouped-properties] +\table +\header + \li Name + \li Description +\row + \li name + \li This property holds the name of the icon to use. + + The icon will be loaded from the platform theme. If the icon is found + in the theme, it will always be used; even if \l icon.source is also set. + If the icon is not found, \l icon.source will be used instead. + + For more information on theme icons, see \l {QIcon::fromTheme()}. +\row + \li source + \li This property holds the name of the icon to use. + + The icon will be loaded as a regular image. + + If \l icon.name is set and refers to a valid theme icon, it will always + be used instead of this property. +\row + \li width + \li This property holds the width of the icon. + + The icon's width will never exceed this value, though it will + shrink when necessary. +\row + \li height + \li This property holds the height of the icon. + + The icon's height will never exceed this value, though it will + shrink when necessary. +\row + \li color + \li This property holds the color of the icon. + + The icon is tinted with the specified color, unless the color is + set to \c "transparent". + +\row + \li cache + \li This property specifies whether the icon should be cached. + + The default value is true. + + For more information, see \l {Image::}{cache}. + + This property was introduced in QtQuick.Controls 2.13. +\endtable +//! [grouped-properties] diff --git a/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc b/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc new file mode 100644 index 00000000000..36297e90804 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc @@ -0,0 +1,59 @@ +//! [conf] +\table + \header + \li Variable + \li Description + \row + \li \c Path + \li Specifies the \l {imagine-path-attached-prop}{path} to the directory that contains + the Imagine style assets. If not specified, the built-in assets are used. + + For example, to specify a path to a directory stored in the + \l {The Qt Resource System}{resource system}: + + \badcode + [Imagine] + Path=:/imagine-assets + \endcode + + To specify a relative path to a local directory: + + \badcode + [Imagine] + Path=imagine-assets + \endcode + + \note Due to a technical limitation, the path should not be named + \e "imagine" if it is relative to the \c qtquickcontrols2.conf file. +\endtable +//! [conf] + +//! [env] +\table + \header + \li Variable + \li Description + \row + \li \c QT_QUICK_CONTROLS_IMAGINE_PATH + \li Specifies the path to the directory that contains the Imagine style assets. + If not specified, the built-in assets are used. + + For example, to specify a path to a directory stored in the + \l {The Qt Resource System}{resource system}: + + \badcode + QT_QUICK_CONTROLS_IMAGINE_PATH=:/imagine-assets + \endcode + + To specify a relative path to a local directory: + + \badcode + QT_QUICK_CONTROLS_IMAGINE_PATH=imagine-assets + \endcode + + \note Due to a technical limitation, the path should not be named + \e "imagine" if it is relative to the \c qtquickcontrols2.conf file. + \li \c QT_QUICK_CONTROLS_IMAGINE_SMOOTH + \li Set to \c 1 to enable smooth scaling for 9-patch images. +\endtable +//! [env] diff --git a/src/quickcontrols2/doc/src/includes/qquickmaterialstyle.qdocinc b/src/quickcontrols2/doc/src/includes/qquickmaterialstyle.qdocinc new file mode 100644 index 00000000000..72c97bb6393 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickmaterialstyle.qdocinc @@ -0,0 +1,79 @@ +//! [conf] +\table + \header + \li Variable + \li Description + \row + \li \c Theme + \li Specifies the default \l {material-theme-attached-prop}{Material theme}. + The value can be one of the available themes, for example \c "Dark". + \row + \li \c Variant + \li Specifies the Material variant. The Material Design has two + variants: a normal variant designed for touch devices, and a dense + variant for desktop. The dense variant uses smaller sizes for + controls and their fonts. + + The value can be \c "Normal" or \c "Dense". + \row + \li \c Accent + \li Specifies the default \l {material-accent-attached-prop}{Material accent color}. + The value can be any \l {colorbasictypedocs}{color}, but it is recommended to use + one of the \l {pre-defined Material colors}, for example \c "Teal". + \row + \li \c Primary + \li Specifies the default \l {material-primary-attached-prop}{Material primary color}. + The value can be any \l {colorbasictypedocs}{color}, but it is recommended to use + one of the \l {pre-defined Material colors}, for example \c "BlueGrey". + \row + \li \c Foreground + \li Specifies the default \l {material-foreground-attached-prop}{Material foreground color}. + The value can be any \l {colorbasictypedocs}{color}, or one of the \l {pre-defined Material colors}, + for example \c "Brown". + \row + \li \c Background + \li Specifies the default \l {material-background-attached-prop}{Material background color}. + The value can be any \l {colorbasictypedocs}{color}, or one of the \l {pre-defined Material colors}, + for example \c "Grey". +\endtable +//! [conf] + +//! [env] +\table + \header + \li Variable + \li Description + \row + \li \c QT_QUICK_CONTROLS_MATERIAL_THEME + \li Specifies the default \l {material-theme-attached-prop}{Material theme}. + The value can be one of the available themes, for example \c "Dark". + \row + \li \c QT_QUICK_CONTROLS_MATERIAL_VARIANT + \li Specifies the Material variant. The Material Design has two + variants: a normal variant designed for touch devices, and a dense + variant for desktop. The dense variant uses smaller sizes for + controls and their fonts. + + The value can be \c "Normal" or \c "Dense". + \row + \li \c QT_QUICK_CONTROLS_MATERIAL_ACCENT + \li Specifies the default \l {material-accent-attached-prop}{Material accent color}. + The value can be any \l {colorbasictypedocs}{color}, but it is recommended to use + one of the \l {pre-defined Material colors}, for example \c "Teal". + \row + \li \c QT_QUICK_CONTROLS_MATERIAL_PRIMARY + \li Specifies the default \l {material-primary-attached-prop}{Material primary color}. + The value can be any \l {colorbasictypedocs}{color}, but it is recommended to use + one of the \l {pre-defined Material colors}, for example \c "BlueGrey". + \row + \li \c QT_QUICK_CONTROLS_MATERIAL_FOREGROUND + \li Specifies the default \l {material-foreground-attached-prop}{Material foreground color}. + The value can be any \l {colorbasictypedocs}{color}, or one of the \l {pre-defined Material colors}, + for example \c "Brown". + \row + \li \c QT_QUICK_CONTROLS_MATERIAL_BACKGROUND + \li Specifies the default \l {material-background-attached-prop}{Material background color}. + The value can be any \l {colorbasictypedocs}{color}, or one of the \l {pre-defined Material colors}, + for example \c "Grey". +\endtable +//! [env] diff --git a/src/quickcontrols2/doc/src/includes/qquickoverlay-popup-parent.qdocinc b/src/quickcontrols2/doc/src/includes/qquickoverlay-popup-parent.qdocinc new file mode 100644 index 00000000000..5562f6a0395 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickoverlay-popup-parent.qdocinc @@ -0,0 +1,20 @@ +The following example uses the attached \l {Overlay::overlay}{Overlay.overlay} +property to position a popup in the center of the window, despite the position +of the button that opens the popup: + +\code +Button { + onClicked: popup.open() + + Popup { + id: popup + + parent: Overlay.overlay + + x: Math.round((parent.width - width) / 2) + y: Math.round((parent.height - height) / 2) + width: 100 + height: 100 + } +} +\endcode diff --git a/src/quickcontrols2/doc/src/includes/qquickpopup-padding.qdocinc b/src/quickcontrols2/doc/src/includes/qquickpopup-padding.qdocinc new file mode 100644 index 00000000000..31f5d2db026 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickpopup-padding.qdocinc @@ -0,0 +1,10 @@ +//! [padding] + +The padding properties are used to control the geometry of the +\l {contentItem}{content item}. + +Popup uses the same approach to padding as \l {Control::padding}{Control}. +For a visual explanation of the padding system, see the \l {Control Layout} +section of the documentation. + +//! [padding] diff --git a/src/quickcontrols2/doc/src/includes/qquickstackview.qdocinc b/src/quickcontrols2/doc/src/includes/qquickstackview.qdocinc new file mode 100644 index 00000000000..20c9bdc3690 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickstackview.qdocinc @@ -0,0 +1,5 @@ +//! [pop-ownership] +Only items that StackView created itself (from a \l Component or \l [QML] +url) will be destroyed when popped. See \l {Item Ownership} for more +information. +//! [pop-ownership] diff --git a/src/quickcontrols2/doc/src/includes/qquickswipedelegate-interaction.qdocinc b/src/quickcontrols2/doc/src/includes/qquickswipedelegate-interaction.qdocinc new file mode 100644 index 00000000000..05aeadb6541 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickswipedelegate-interaction.qdocinc @@ -0,0 +1,5 @@ +Both interactive and non-interactive items can be used here. Normal +event handling rules apply; if an interactive control like \l Button +is used, interaction signals of SwipeDelegate such as +\l {AbstractButton::}{clicked()} will not get emitted if the button +is clicked. diff --git a/src/quickcontrols2/doc/src/includes/qquickswitch.qdocinc b/src/quickcontrols2/doc/src/includes/qquickswitch.qdocinc new file mode 100644 index 00000000000..985f85d9796 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickswitch.qdocinc @@ -0,0 +1,28 @@ +//! [position] + +This property holds the logical position of the thumb indicator. + +The position is expressed as a fraction of the indicator's size, in the range +\c 0.0 - \c 1.0. The position can be used for example to determine whether +the thumb has been dragged past the halfway point. For visualizing a thumb +indicator, the right-to-left aware \l visualPosition should be used instead. + +\sa visualPosition + +//! [position] + + +//! [visualPosition] + +This property holds the visual position of the thumb indicator. + +The position is expressed as a fraction of the indicator's size, in the range +\c 0.0 - \c 1.0. When the control is \l {Control::mirrored}{mirrored}, the +value is equal to \c {1.0 - position}. This makes the value suitable for +visualizing the thumb indicator taking right-to-left support into account. +In order to for example determine whether the thumb has been dragged past +the halfway point, the logical \l position should be used instead. + +\sa position + +//! [visualPosition] diff --git a/src/quickcontrols2/doc/src/includes/qquicktooltip.qdocinc b/src/quickcontrols2/doc/src/includes/qquicktooltip.qdocinc new file mode 100644 index 00000000000..0046a2d8b09 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquicktooltip.qdocinc @@ -0,0 +1,6 @@ +//! [customize-note] +\note to customize the \l {Attached Tool Tips}{attached ToolTip}, it +must be provided as part of +\l {Creating a Custom Style}{your own style}. To do a one-off +customization of a \c ToolTip, see \l {Custom Tool Tips}. +//! [customize-note] diff --git a/src/quickcontrols2/doc/src/includes/qquickuniversalstyle.qdocinc b/src/quickcontrols2/doc/src/includes/qquickuniversalstyle.qdocinc new file mode 100644 index 00000000000..a7ecbaef095 --- /dev/null +++ b/src/quickcontrols2/doc/src/includes/qquickuniversalstyle.qdocinc @@ -0,0 +1,53 @@ +//! [conf] +\table + \header + \li Variable + \li Description + \row + \li \c Theme + \li Specifies the default \l {universal-theme-attached-prop}{Universal theme}. + The value can be one of the available themes, for example \c "Dark". + \row + \li \c Accent + \li Specifies the default \l {universal-accent-attached-prop}{Universal accent color}. + The value can be any \l {colorbasictypedocs}{color}, but it is recommended to use + one of the \l {pre-defined Universal colors}, for example \c "Violet". + \row + \li \c Foreground + \li Specifies the default \l {universal-foreground-attached-prop}{Universal foreground color}. + The value can be any \l {colorbasictypedocs}{color}, or one of the \l {pre-defined Universal colors}, + for example \c "Brown". + \row + \li \c Background + \li Specifies the default \l {universal-background-attached-prop}{Universal background color}. + The value can be any \l {colorbasictypedocs}{color}, or one of the \l {pre-defined Universal colors}, + for example \c "Steel". +\endtable +//! [conf] + +//! [env] +\table + \header + \li Variable + \li Description + \row + \li \c QT_QUICK_CONTROLS_UNIVERSAL_THEME + \li Specifies the default \l {universal-theme-attached-prop}{Universal theme}. + The value can be one of the available themes, for example \c "Dark". + \row + \li \c QT_QUICK_CONTROLS_UNIVERSAL_ACCENT + \li Specifies the default \l {universal-accent-attached-prop}{Universal accent color}. + The value can be any \l {colorbasictypedocs}{color}, but it is recommended to use + one of the \l {pre-defined Universal colors}, for example \c "Violet". + \row + \li \c QT_QUICK_CONTROLS_UNIVERSAL_FOREGROUND + \li Specifies the default \l {universal-foreground-attached-prop}{Universal foreground color}. + The value can be any \l {colorbasictypedocs}{color}, or one of the \l {pre-defined Universal colors}, + for example \c "Brown". + \row + \li \c QT_QUICK_CONTROLS_UNIVERSAL_BACKGROUND + \li Specifies the default \l {universal-background-attached-prop}{Universal background color}. + The value can be any \l {colorbasictypedocs}{color}, or one of the \l {pre-defined Universal colors}, + for example \c "Steel". +\endtable +//! [env] diff --git a/src/quickcontrols2/doc/src/qt6-changes.qdoc b/src/quickcontrols2/doc/src/qt6-changes.qdoc new file mode 100644 index 00000000000..61b80b38391 --- /dev/null +++ b/src/quickcontrols2/doc/src/qt6-changes.qdoc @@ -0,0 +1,305 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols-changes-qt6.html + \title Changes to Qt Quick Controls + \ingroup changes-qt-5-to-6 + \brief Migrate Qt Quick Controls to Qt 6. + + Qt 6 is a result of the conscious effort to make the framework more + efficient and easy to use. + + We try to maintain compatibility for all the public APIs in each release. + Some changes were inevitable in an effort to make Qt a better framework. + + In this topic we summarize those changes in Qt Quick Controls, and provide + guidance to handle them. + + \section1 Migrating from Qt Quick Controls 1 + + Qt Quick Controls 1 was deprecated in Qt 5.11 and is removed from + Qt 6.0. Use Qt Quick Controls (previously known as Qt Quick Controls 2) + instead. For more information, refer to the + \l{Qt 5.15: Qt Quick Controls vs Qt Quick Controls 1} topic in the Qt 5 + documentation. + + \section1 Type registration changes + + Qt Quick Controls has undergone some large, mostly internal changes in Qt + 6. By making use of the improved type registration introduced in Qt 5.15, + we pave the way for compilation of the module's QML files to C++ and enable + tooling to become more effective. In particular, Qt Creator's QML code + model should have a more complete picture of types, making its completion + and error checking of Qt Quick Controls code more reliable. Static analysis + tools like qmllint and qmlformat also benefit by becoming aware of the + types that are now declared at compile time in C++. + + As a result of these changes, some things are done a little differently. + + \section2 Custom styles are now proper QML modules + + To enable compile time type registration, each Qt Quick Controls style is + now a proper QML module. Previously, a single \c Button.qml was sufficient + to create your own style. While convenient, this required some non-standard + API, which in turn required adaptation in tooling like Qt Designer. + + Now, all QML types that a style implements must be declared in that style's + qmldir file: + + \code + module MyStyle + Button 1.0 Button.qml + \endcode + + \omit + TODO: Once we have documentation for the CMake function qt6_add_qml_module, + this would be a good place to link to it, stating that you don't have to + manually write the qmldir files. + \endomit + + By unifying this with the rest of the QML world, styles become more + familiar to developers and hopefully easier to understand for beginners. As + a consequence, the following API had to be removed: + + \list + \li QQuickStyle::addStylePath() + \li QQuickStyle::availableStyles() + \li QQuickStyle::path() + \li QQuickStyle::stylePathList() + \li QT_QUICK_CONTROLS_STYLE_PATH + \endlist + + Now that the styles are required to be found in the QML engine's import + path like any other QML module, it is no longer necessary or possible to + support this API. + + \section3 Style names + + In addition, there is now only one valid, case-sensitive form for style + names: "Material", "MyStyle", and so on. That is: the style name must + exactly match the name of the QML module. This also applies to file + selectors, where previously, all style names were lower case. For example, + where the following was a valid structure for a Qt 5 project: + + \badcode + MyProject + ├── main.qml + ├── HomePage.qml + └── +material + └───HomePage.qml + \endcode + + In Qt 6, \c +material becomes \c +Material: + + \badcode + MyProject + ├── main.qml + ├── HomePage.qml + └── +Material + └───HomePage.qml + \endcode + + All of the existing ways to \l {Using Styles in Qt Quick Controls}{run an + application with a specific style} are still supported. + + \section2 Runtime and compile time style selection + + Importing a style now has extra meaning due to the way that imports work + internally. Previously, importing \c QtQuick.Controls would register the + control types from the current style with the QML engine: + + \qml + import QtQuick.Controls + \endqml + + We refer to this as runtime style selection, as the style is selected at + runtime. + + Explicitly importing \c QtQuick.Controls.Material would then simply expose + any extra API provided by that style (for example, the attached Material + type): + + \qml + import QtQuick.Controls.Material + \endqml + + Now, explicitly importing a style does both. + + This effectively means that the control types (like Button) from the last + imported style will be used. We refer to this as compile time style + selection. + + This has implications for existing code. Namely, if your application + supports more than one style, move these imports into their own QML files + that are file-selected. + + For example, if you have the following \c main.qml: + + \qml + import QtQuick.Controls + import QtQuick.Controls.Material + import QtQuick.Controls.Universal + + ApplicationWindow { + width: 600 + height: 400 + visible: true + + Material.theme: darkMode ? Material.Dark : Material.Light + Universal.theme: darkMode ? Universal.Dark : Universal.Light + + // Child items, etc. + } + \endqml + + You can move the common code into a "base" component: + + \qml + // MainWindow.qml + + import QtQuick.Controls + + ApplicationWindow {} + \endqml + + Then, add a \c +Material subdirectory, and in it, add the Material-specific code into \c MainWindow.qml: + + \qml + // +Material/MainWindow.qml + + import QtQuick.Controls.Material + + ApplicationWindow { + Material.theme: darkMode ? Material.Dark : Material.Light + } + \endqml + + Do the same for Universal: + + \qml + // +Universal/MainWindow.qml + + import QtQuick.Controls.Universal + + ApplicationWindow { + Universal.theme: darkMode ? Universal.Dark : Universal.Light + } + \endqml + + Then, in \c main.qml: + + \qml + import QtQuick.Controls + + MainWindow { + width: 600 + height: 400 + visible: true + + // Child items, etc. + } + \endqml + + See also: \l {Using File Selectors with Qt Quick Controls}. + + \section1 Default Style + + The Default style was renamed to "Basic", as it is no longer the default + style. Instead, the default style is now chosen based on the platform + that Qt was built for: + + \list + \li Android: \l {Material Style} + \li Linux: \l {Fusion Style} + \li macOS: \l {macos Style} + \li Windows: \l {Windows Style} + \li All other platforms: \l {Basic Style} + \endlist + + Therefore, applications that didn't specify a style in Qt 5 and have customized + controls should \l {Using Styles in Qt Quick Controls}{explicitly specify} + the Basic style in Qt 6 to ensure that those controls look and behave as + they did with Qt 5. + + \section1 Palette + + The palette API was moved to QQuickItem. The various APIs that use palettes + in Qt Quick Controls are unchanged. + + \section1 Controls + + \section2 Changes to ApplicationWindow + + The deprecated overlay properties and attached API were removed. Use the + \l Overlay attached type instead. + + \section2 Changes to ComboBox + + The \l {ComboBox::}{pressed} property is now read-only. To modify the + visual pressed state of a ComboBox, use the \l {ComboBox::}{down} property + instead. + + \section2 Changes to Container + + The deprecated \c removeItem(var) function was removed. + \l {Container::}{removeItem(Item)} or \l {Container::}{takeItem(int)} can + be used instead. + + \section2 Changes to Dialog + + \l {Dialog}'s \l {Dialog::}{accepted()} and \l {Dialog::}{rejected()} + signals are now emitted before \l {Popup::}{closed()} when calling + \l {Dialog::}{done()}, \l {Dialog::}{accept()} and \l {Dialog::}{reject()}. + + \section2 Changes to Menu + + The deprecated \c removeItem(var) function was removed. + \l {Menu::}{removeItem(Item)} or \l {Menu::}{takeItem(int)} can be used + instead. + + \section2 Changes to ToolTip + + \l {ToolTip}'s timeout now begins only after \l {Popup::}{opened()} has + been emitted. This results in tooltips with enter transitions being visible + for the entire duration of the timeout property. This means that they are + visible slightly longer than they were before, so it may be worthwhile to + visually check tooltips in your application and adjust timeouts if + necessary. + + \section2 Changes to StackView + + The StackView.Transition enum value was deprecated. The operation argument + can be omitted in order to use the default transition for any given + operation. + + \section2 Changes to Tumbler + + \l {Item::}{implicitWidth} and \l {Item::}{implicitHeight} must now be + provided for \l {Tumbler}'s \l {Control::}{contentItem}, making it + consistent with all other controls. +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-basic.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-basic.qdoc new file mode 100644 index 00000000000..ee8d3ce4dde --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-basic.qdoc @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-basic.html + \title Basic Style + + The Basic style is a basic all-round style. + + The Basic style is a simple and light-weight style that offers the maximum + performance for Qt Quick Controls. It is built with a minimal amount of Qt + Quick primitives, and keeps animations and transitions to the minimum. + + \image qtquickcontrols2-basic.png + + The style is selected by default when running Qt Quick Controls applications. + It is built into the module's resources, so by default it is shipped with + any application that depends on the Qt Quick Controls module + + \note The Basic style is used as a fallback for other styles. If a style + does not implement a certain control, the Basic style implementation of + that control is selected. + + \b {See also} \l {Material Style}, \l {Universal Style} + + \section1 Related Information + + \list + \li \l{Styling Qt Quick Controls} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-buttons.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-buttons.qdoc new file mode 100644 index 00000000000..6a4c5926099 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-buttons.qdoc @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-buttons.html + \title Button Controls + \ingroup qtquickcontrols2-guidelines + \brief Guidelines for button controls + + Qt Quick Controls offers a selection of button-like controls. + + \annotatedlist qtquickcontrols2-buttons + + Each type of button has its own specific use case. The following + sections offer guidelines for choosing the appropriate type of button, + depending on the use case. + + \section1 Button Control + + \l Button is a clickable control that starts an action, or opens or + closes a popup. A button usually has a text label but it can also + contain an icon. + + Button is a very suitable control when a popup or dialog needs + to perform an action. The most common examples are Apply, Cancel, + Save, Close and Help. + + \image qtquickcontrols2-button.gif + + Recommendations: + + \list + \li The button's text should be a verb describing the action, or a noun matching + the title of the popup that will be opened. + \li Don't use a button to set state. \l Switch is more suitable for that. + \li Use the default font unless you have UI guidelines specifying otherwise. + \li If the text is localized, consider the influence of a longer text on the layout. + \endlist + + \b {See also} \l Button and \l AbstractButton + + \section1 CheckBox Control + + \image qtquickcontrols2-checkbox.gif + + \l CheckBox is used to build multi-selection option lists. Any number of + options can be selected, including none, but the options should + not be mutually exclusive. + + Use a single CheckBox for a yes/no choice, such as when you have + to accept the terms of service agreement in a form. + + For a single yes/no choice, it is also possible to use a switch. If the choice + concerns an option, it is best to use a CheckBox. If it concerns action to + be taken, a switch is recommended. + + When options can be grouped, you can use a partially checked CheckBox to + represent the whole group. Use the checkbox's + \l {CheckBox::checkState}{partially checked state} when a user selects + some, but not all, sub-items in the group. + + The three availables check states are: checked, partially checked and + unchecked. + + The checkable options are often listed vertically. + + Recommendations: + \list + \li The checkbox label should be a statement that the check mark makes true, + and that the absence of a check mark makes false. + \li The checkbox label should not contain a negative statement. + \li Use the default font, unless you have UI guidelines specifying otherwise. + \li If the text is localized, consider the influence of a longer text on the layout. + \endlist + + \b {See also} \l CheckBox + + \section1 DelayButton Control + + \l DelayButton is a button that incorporates a delay before triggering an action. + This delay prevents accidental presses. + + \image qtquickcontrols2-delaybutton.gif + + Recommendations: + \list + \li Use in touch user interfaces. + \li Use for actions that must be triggered with care. + \endlist + + \b {See also} \l Button and \l AbstractButton + + \section1 RadioButton Control + + \image qtquickcontrols2-radiobutton.gif + + \l RadioButton is used to select only one option from a set of options. + Selecting one option automatically deselects the one selected before. + + If there are only two mutually exclusive options, combine them into a + single checkbox or a switch. + + Recommendations: + + \list + \li Limit the label text to one line. + \li Ensure that a sensible default option is checked. + \li List RadioButton options vertically. + \li If the text is localized, consider the influence of a longer text on the layout. + \li Use the default font, unless you have UI guidelines that specify otherwise. + \li Just like with CheckBox, do not make the list too large. + \li In order to avoid confusion, do not put two groups of radio buttons next to each + other. + \endlist + + \b {See also} \l RadioButton + + \section1 RoundButton Control + + \l RoundButton is a clickable control that starts an action, or opens or + closes a popup. A round button with a square image icon or one-letter font + icon is circular. A circular RoundButton takes less space than a normal + \l Button, and can also be used as a floating action button. + + \image qtquickcontrols2-roundbutton.png + + Recommendations: + + \list + \li Keep labels short and concise. + \li If the text is localized, consider the influence of a longer text on the layout. + \endlist + + \b {See also} \l RoundButton + + \section1 Switch Control + + \image qtquickcontrols2-switch.png + + \l Switch represents a physical switch that allows users to choose between an "on" + or "off" state. + Use a switch for binary operations that take effect immediately after it has been + switched on. For example, a switch to turn WIFI on or off. + + Recommendations: + + \list + \li Keep labels short and concise. + \li If the text is localized, consider the influence of a longer text on the layout. + \endlist + + \b {See also} \l Switch + + \section1 ToolButton Control + + \image qtquickcontrols2-toolbutton.png + + \l ToolButton is nearly identical to \l Button, but it has a graphical + appearance that makes it more suitable for insertion into a \l ToolBar. + + \b {See also} \l ToolButton + + \section1 Related Information + \list + \li \l {Qt Quick Controls Guidelines} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-configuration.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-configuration.qdoc new file mode 100644 index 00000000000..8ac2b2759ab --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-configuration.qdoc @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-configuration.html + \keyword Qt Quick Controls Configuration File + \title Qt Quick Controls Configuration File + \keyword Qt Quick Controls 2 Configuration File + + Qt Quick Controls support a special configuration file, \c qtquickcontrols2.conf, + which is built into an application's resources. + + The configuration file can specify the preferred style and certain style-specific + attributes. The following example specifies that the preferred style is the \l {Material style}. + Furthermore, when the application is run with the Material style, its theme is light and the + accent and primary colors are teal and blue grey, respectively. However, if the application + is run with the \l {Universal style} instead, the accent color is red and the appropriate theme + is chosen based on the system theme colors. + + \code + [Controls] + Style=Material + + [Universal] + Theme=System + Accent=Red + + [Material] + Theme=Light + Accent=Teal + Primary=BlueGrey + \endcode + + It is possible to specify a custom location for the configuration file with + the \l {Supported Environment Variables in Qt Quick Controls} + {QT_QUICK_CONTROLS_CONF} environment variable. + + \section1 Controls Section + + The following values can be specified in a \c Controls section of the + configuration file: + + \table + \header + \li Variable + \li Description + \row + \li \c Style + \li Specifies the style to run the application with. + The value can be the name of one of the \l {Available Styles}{built-in styles} + or a \l {Creating a Custom Style}{custom style}. + \row + \li \c FallbackStyle + \li Specifies the style to use for controls that are not implemented. + The style must be one of the \l {Available Styles}{built-in styles}. + By default, the \l {Basic Style}{Basic} style is used. + \endtable + + \section1 Imagine Section + + The following table lists values that can be used to configure the + \l {Imagine style} in an \c Imagine section of the configuration file: + + \include qquickimaginestyle.qdocinc conf + + \section1 Material Section + + The following table lists values that can be used to configure the + \l {Material style} in a \c Material section of the configuration file: + + \include qquickmaterialstyle.qdocinc conf + + \section1 Universal Section + + The following table lists values that can be used to configure the + \l {Universal style} in a \c Universal section of the configuration file: + + \include qquickuniversalstyle.qdocinc conf + + \section1 Font Configuration + + The default \l {Control::font}{font} can be specified in a \c Font sub-group + in each style's section in the configuration file. The \c Font sub-group can + be defined in two alternative ways: + + \code + [Basic] + Font\Family=Open Sans + Font\PixelSize=20 + + [Material\Font] + Family=Open Sans + PixelSize=20 + \endcode + + Supported font attributes: + \table + \header + \li Variable + \li Description + \row + \li \c Family + \li The \l {QFont::family}{font family}. + \row + \li \c PointSize + \li The \l {QFont::pointSizeF}{point size}. + \row + \li \c PixelSize + \li The \l {QFont::pixelSize}{pixel size}. + \row + \li \c StyleHint + \li The \l {QFont::styleHint}{style hint}. + Available values: \c SansSerif, \c Helvetica, \c Serif, \c Times, \c TypeWriter, \c Courier, + \c OldEnglish, \c Decorative, \c Monospace, \c Fantasy, \c Cursive. + \row + \li \c Weight + \li The \l {QFont::}{weight}. Qt uses a weighting scale from \c 1 to \c 1000 compatible with OpenType. A weight of \c 1 will be thin, + whilst \c 1000 will be extremely black. + Available pre-defined weights: \c Thin (100), \c ExtraLight (200), \c Light (300), \c Normal (400), + \c Medium (500), \c DemiBold (600), \c Bold (700), \c ExtraBold (800), + \c Black (900). + \row + \li \c Style + \li The \l {QFont::}{style}. + Available values: \c StyleNormal, \c StyleItalic, \c StyleOblique. + \endtable + + \section1 Palette Configuration + + The default \c palette can be configured for each style using the + \c Palette sub-group in the configuration file. The \c Palette sub-group can be + defined in two alternative ways: + + \code + [Fusion] + Palette\Window=#dedede + Palette\WindowText=#212121 + \endcode + + or: + \code + [Fusion\Palette] + Window=#dedede + WindowText=#212121 + \endcode + + See \l [QtQuick]{Palette} QML type for more information. + + \section1 Using the Configuration File in a Project + + In order to make it possible for Qt Quick Controls to find the configuration file, + it must be built into application's resources using the \l {The Qt Resource System}. + Here's an example \c .qrc file: + + \code + <!DOCTYPE RCC><RCC version="1.0"> + <qresource prefix="/"> + <file>qtquickcontrols2.conf</file> + </qresource> + </RCC> + \endcode + + \note Qt Quick Controls uses a file selector to load the configuration file. It + is possible to provide a different configuration file for different platforms and + locales. See \l QFileSelector documentation for more details. + + Finally, the \c .qrc file must be listed in the application's \c .pro file so that + the build system knows about it. For example: + + \code + RESOURCES = application.qrc + \endcode + + \section1 Related Information + + \list + \li \l{Styling Qt Quick Controls} + \li \l{Supported Environment Variables in Qt Quick Controls} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-containers.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-containers.qdoc new file mode 100644 index 00000000000..81e24c2698c --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-containers.qdoc @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-containers.html + \title Container Controls + \ingroup qtquickcontrols2-guidelines + \brief Guidelines for container controls + + Qt Quick Controls offers a selection of container-like controls. + + \annotatedlist qtquickcontrols2-containers + + Each type of container can be used to group a set of controls together. + The following sections offer guidelines for choosing the appropriate type + of container, depending on the use case. + + \section1 ApplicationWindow Control + + \image qtquickcontrols2-applicationwindow-wireframe.png + + \l ApplicationWindow creates the root window of an application, and makes + it easy to add an optional header and footer to that window. + + \section1 Frame Control + + \image qtquickcontrols2-frame.png + + \l Frame is used to layout a logical group of controls together, within + a visual frame. + + \section1 GroupBox Control + + \image qtquickcontrols2-groupbox.png + + \l GroupBox is used to layout a logical group of controls together, + within a titled visual frame. + + \section1 Page Control + + \image qtquickcontrols2-page-wireframe.png + + \l Page provides page-specific header and footer items. + It is perfectly possible to use ApplicationWindow for setting the header + and the footer, but if you have a header and footer which varies per + screen, then it is better to use \l Page. + + \section1 Pane Control + + \image qtquickcontrols2-pane.png + + \l Pane provides a background color that matches with the application + style and theme. Pane does not provide a layout of its own, but requires + you to position its contents, for instance by using a \l RowLayout or + a \l ColumnLayout. + + \section1 ScrollView Control + + \image qtquickcontrols2-scrollview-wireframe.png + + \l ScrollView provides scrolling for user-defined content. + + \section1 StackView Control + + \image qtquickcontrols2-stackview-wireframe.png + + \l StackView organizes content pages into a stack using a last-in-first-out + principle: the last item to be "pushed" onto the stack is the first one to + be removed, and the top-most item is always the one that is visible. + + \section1 SwipeView Control + + \image qtquickcontrols2-swipeview-wireframe.png + + \l SwipeView organizes content pages into a swipable strip. + + \section1 TabBar Control + + \image qtquickcontrols2-tabbar-wireframe.png + + \l TabBar organizes content pages into tabs. + + \section1 ToolBar Control + + \image qtquickcontrols2-toolbar.png + + \l ToolBar is a container of application-wide and context-sensitive + actions and controls. +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-cppclasses.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-cppclasses.qdoc new file mode 100644 index 00000000000..293ac6de4e1 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-cppclasses.qdoc @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \module QtQuickControls2 + \keyword Qt Quick Controls C++ Classes + \title Qt Quick Controls C++ Classes + \keyword Qt Quick Controls 2 C++ Classes + \ingroup modules + \qtcmakepackage QuickControls2 + \qtvariable quickcontrols2 + + \brief Provides classes for setting up the controls from C++. + + The C++ types can be included into your application using the following + include statement: + + \code + #include <QtQuickControls2> + \endcode + + \note If you are using a few classes from this module, we recommend including + those specific classes only instead of the module. + + To link against the corresponding C++ libraries, add the following to your + qmake project file: + + \code + QT += quickcontrols2 + \endcode + + The \l{Qt Quick Controls} page contains information about how to use the + module. +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-customize.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-customize.qdoc new file mode 100644 index 00000000000..8207b32ab71 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-customize.qdoc @@ -0,0 +1,1057 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-customize.html + \keyword Customizing Qt Quick Controls 2 + \title Customizing Qt Quick Controls + \brief A set of UI controls to create user interfaces in Qt Quick + + Qt Quick Controls consist of a hierarchy (tree) of items. In order to + provide a custom look and feel, the default QML implementation of each + item can be replaced with a custom one. + + \section1 Customizing a Control + + Sometimes you'll want to create a "one-off" look for a specific part of + your UI, and use a complete style everywhere else. Perhaps you're happy + with the style you're using, but there's a certain button that has some + special significance. + + The first way to create this button is to simply define it in-place, + wherever it is needed. For example, perhaps you're not satisfied with the + Basic style's Button having square corners. To make them rounded, you + can override the \l {Control::}{background} item and set the radius + property of Rectangle: + + \include customize-button-background.qdocinc file + + \note as the different items that make up a control in any given style are + designed to work together, it may be necessary to override other items to + get the look you're after. In addition, not all styles can be customized. + See the note in \l {Customization Reference} for more information. + + The second way to create the button is good if you plan to use your rounded + button in several places. It involves moving the code into its own QML file + within your project. + + For this approach, we'll copy the background code from the Basic style's + \c Button.qml. This file can be found in the following path in your Qt + installation: + + \c {$QTDIR/qml/QtQuick/Controls/Basic/Button.qml} + + After doing that, we'll simply add the following line: + + \code + radius: 4 + \endcode + + To avoid confusion with the controls in the + module itself, we'll call the file \c MyButton.qml. To use the control in + your application, refer to it by its filename: + + \qml + import QtQuick.Controls + + ApplicationWindow { + MyButton { + text: qsTr("A Special Button") + } + } + \endqml + + The third way to create the button is a bit more structured, both in terms + of where the file sits in the file system and how it is used in QML. First, + copy an existing file as you did above, but this time, put it into a + subfolder in your project named (for example) \c controls. To use the + control, first import the folder into a namespace: + + \qml + import QtQuick.Controls + import "controls" as MyControls + + ApplicationWindow { + MyControls.Button { + text: qsTr("A Special Button") + } + } + \endqml + + As you now have the \c MyControls namespace, you can name the controls after + their actual counterparts in the Qt Quick Controls module. You can repeat + this process for any control that you wish to add. + + An added benefit of these three methods is that it's not necessary to + implement the template from scratch. + + \note the three approaches mentioned here do not work for customizing the + attached \l ToolTip, as that is a shared item created internally. To do + a one-off customization of a \c ToolTip, see \l {Custom Tool Tips}. To + customize the attached \c ToolTip, it must be provided as part of + \l {Creating a Custom Style}{your own style}. + + \section1 Creating a Custom Style + + There are several ways to go about creating your own styles. Below, we'll + explain the various approaches. + + \section2 Definition of a Style + + In Qt Quick Controls, a style is essentially a set of QML files within a + single directory. There are four requirements for a style to be + \l {Using Styles in Qt Quick Controls}{usable}: + + \list + \li At least one QML file whose name matches a control (for example, + \c Button.qml) must exist. + \li Each QML file must contain the relevant type from the \l {Qt Quick Templates 2} + {QtQuick.Templates} import as the root item. For example, + Button.qml must contain a Button template as its root item. + + If we instead used the corresponding type from the \l {Qt Quick Controls} + {QtQuick.Controls} import as we did in the previous section, it would not work: + the control we were defining would try to derive from itself. + \li A \l {Module Definition qmldir Files}{qmldir} file must exist alongside + the QML file(s). Below is an example of a simple \c qmldir file for a style that + provides a button: + + \badcode + module MyStyle + Button 2.15 Button.qml + \endcode + + If you're using \l {Compile-Time Style Selection}{compile-time style + selection}, the qmldir should also import the fallback style: + + \badcode + # ... + import QtQuick.Controls.Basic auto + \endcode + + This can also be done for \l {Run-Time Style Selection}{run-time style selection} + instead of using, for example, \l QQuickStyle::setFallbackStyle(). + + The directory structure for such a style looks like this: + + \badcode + MyStyle + ├─── Button.qml + └─── qmldir + \endcode + \li The files must be in a directory that is findable via the \l {QML Import Path}. + + For example, if the path to \e MyStyle directory mentioned above was + \c /home/user/MyApp/MyStyle, then \c /home/user/MyApp must be added to + the QML import path. + + To \l {Using Styles in Qt Quick Controls}{use} \e MyStyle in \e MyApp, + refer to it by name: + + \list + \li \c {./MyApp -style MyStyle} + \endlist + + The style name must match the casing of the style directory; passing + \e mystyle or \e MYSTYLE is not supported. + \endlist + + By default, the styling system uses the Basic style as a fallback for + controls that aren't implemented. To customize or extend any other built-in + style, it is possible to specify a different fallback style using + \l[QtQuickControls2]{QQuickStyle}. + + What this means is that you can implement as many controls as you like for + your custom style, and place them almost anywhere. It also allows users to + create their own styles for your application. + + \section3 Previewing Custom Styles in Qt Quick Designer + + Using the approach above, it is possible to preview a custom style + in Qt Quick Designer. In order to do so, + ensure that the project has a + \l {Qt Quick Controls Configuration File}{qtquickcontrols2.conf} file, + and that the following entry exists: + + \badcode + [Controls] + Style=MyStyle + \endcode + + For more information, take a look at the + \l {Qt Quick Controls - Flat Style}{Flat Style example}. + + \section2 Style-specific C++ Extensions + + Sometimes you may need to use C++ to extend your custom style. There are two + ways to expose such types to QML: + + \list + \li If the style that uses the type is the only style used by an application, + it's enough to register it with the QML engine via qmlRegisterType(): + + \code + qmlRegisterType<ACoolCppItem>("MyApp", 1, 0, "ACoolItem"); + \endcode + + See \l {Using C++ Data From QML} for more information about this. + \li If the style that uses the type is one of many styles used by an + application, it may be better to only register it when necessary. This + is the point at which it would make sense to implement your own + \l {Creating C++ Plugins for QML}{QML plugin}. + + Using a plugin as part of your style is not that much different from + using a set of QML files. The only difference is that the plugin and + its \c qmldir file must be present in the same directory as the QML + files. + \endlist + + \section3 Considerations for custom styles + + When implementing your own style and customizing controls, there are some + points to keep in mind to ensure that your application is as performant as + possible. + + \section4 Avoid assigning an id to styles' implementations of item delegates + + As explained in \l {Definition of a Style}, when you implement your + own style for a control, you start off with the relevant template for + that control. For example, a style's \c Button.qml will be structured + similarly to this: + + \qml + T.Button { + // ... + + background: Rectangle { + // ... + } + + contentItem: Text { + // ... + } + + // ... + } + \endqml + + When you use a Button in your application, the \c background and + \c contentItem items will be created and parented to the root \c Button + item: + + \qml + // Creates the Button root item, the Rectangle background, + // and the Text contentItem. + Button { + text: qsTr("Confirm") + } + \endqml + + Suppose you then needed to do a one-off customization of the Button (as + explained in \l {Customizing a Control}): + + \include customize-button-background.qdocinc file + + In QML, this would normally result in both the default \c background + implementation and the one-off, custom \c background items being created. + Qt Quick Controls uses a technique that avoids creating both items, and + instead only creates the custom \c background, greatly improving the + creation performance of controls. + + This technique relies on the absence of an \l {The id Attribute}{id} in the + style's implementation of that item. If an id is assigned, the technique + cannot work, and both items will be created. For example, it can be + tempting to assign an id to the \c background or \c contentItem so that + other objects within the file can refer to those items: + + \qml + T.Button { + // ... + + background: Rectangle { + id: backgroundRect + // ... + } + + contentItem: Text { + // Use backgroundRect in some way... + } + + // ... + } + \endqml + + With this code, every time a Button instance with a customized background + is created, both backgrounds will be created, resulting in sub-optimal + creation performance. + + Prior to Qt 5.15, the old, unused background would be deleted to release + the resources associated with it. However, as the control does not own the + items, it should not delete them. As of Qt 5.15, old items are no longer + deleted, and so the \c backgroundRect item will live longer than it needs + to—typically until the application exits. Although the old item will be + hidden, visually unparented from the control, and removed from the + accessibility tree, it is important to keep the creation time and memory + usage of these unused items in mind when assigning an id in this context. + + \section4 Avoid imperative assignments of custom items + + The technique mentioned in the section above only works when an item is + \l {Prefer Declarative Bindings Over Imperative Assignments}{declaratively} + assigned for the first time, and so imperative assignments will result in + orphaned items. Always use declarative bindings to assign custom items + when possible. + + \section4 Don't import QtQuick.Controls in QML implementations + + When writing the QML for your style's implementation of a control, + it's important not to import \c {QtQuick.Controls}. Doing so will + prevent the QML from being compiled by the QML compiler. + + \section4 Implement types used by other types + + Suppose you were using ScrollViews in your application, and decided that + you want to customize their scroll bars. It is tempting to just implement a + custom ScrollBar.qml and have ScrollView pick up the customized ScrollBar + automatically. However, this will not work. You must implement both + ScrollBar.qml \e and ScrollView.qml. + + \section3 Attached properties + + It is common for a style to have certain properties or attributes that + apply to all controls. \l {Attached Properties and Attached Signal + Handlers}{Attached properties} are a great way of extending an item in QML + without having to modify any existing C++ belonging to that item. For + example, both the \l {Material Style}{Material} and \l {Universal + Style}{Universal} styles have an attached theme property that controls + whether an item and its children will be rendered in a light or dark theme. + + As an example, let's add an attached property that controls elevation. Our + style will illustrate the elevation with a drop shadow; the higher the + elevation, the larger the shadow. + + The first step is to \l {Qt Creator: Project Types}{create a new Qt Quick + Controls application} in Qt Creator. After that, we + \l {Qt Creator: Creating C++ Classes}{add a C++ type} that stores the elevation. Since + the type will be used for every control supported by our style, and because + we may wish to add other attached properties later on, we'll call it + MyStyle. Here is \c MyStyle.h: + + \code + #ifndef MYSTYLE_H + #define MYSTYLE_H + + #include <QObject> + #include <QtQml> + + class MyStyle : public QObject + { + Q_OBJECT + Q_PROPERTY(int elevation READ elevation WRITE setElevation NOTIFY elevationChanged) + + public: + explicit MyStyle(QObject *parent = nullptr); + + static MyStyle *qmlAttachedProperties(QObject *object); + + int elevation() const; + void setElevation(int elevation); + + signals: + void elevationChanged(); + + private: + int m_elevation; + }; + + QML_DECLARE_TYPEINFO(MyStyle, QML_HAS_ATTACHED_PROPERTIES) + + #endif // MYSTYLE_H + \endcode + + \c MyStyle.cpp: + + \code + #include "mystyle.h" + + MyStyle::MyStyle(QObject *parent) : + QObject(parent), + m_elevation(0) + { + } + + MyStyle *MyStyle::qmlAttachedProperties(QObject *object) + { + return new MyStyle(object); + } + + int MyStyle::elevation() const + { + return m_elevation; + } + + void MyStyle::setElevation(int elevation) + { + if (elevation == m_elevation) + return; + + m_elevation = elevation; + emit elevationChanged(); + } + \endcode + + The \c MyStyle type is special in the sense that it shouldn't be + instantiated, but rather used for its attached properties. For that reason, + we register it in the following manner in \c main.cpp: + + \code + #include <QGuiApplication> + #include <QQmlApplicationEngine> + + #include "mystyle.h" + + int main(int argc, char *argv[]) + { + QGuiApplication app(argc, argv); + + qmlRegisterUncreatableType<MyStyle>("MyStyle", 1, 0, "MyStyle", "MyStyle is an attached property"); + + QQmlApplicationEngine engine; + // Make the directory containing our style known to the QML engine. + engine.addImportPath(":/"); + engine.load(QUrl(QLatin1String("qrc:/main.qml"))); + + return app.exec(); + } + \endcode + + We then copy \c Button.qml from the Basic style in + \c {$QTDIR/qml/QtQuick/Controls/Basic/} into a new \c myproject folder in our + project directory. Add the newly copied \c Button.qml to \c qml.qrc, which is + the resource file that contains our QML files. + + Next, we add a drop shadow to the \l {Control::}{background} delegate of + the Button: + + \code + // ... + import QtGraphicalEffects + import MyStyle + // ... + + background: Rectangle { + // ... + + layer.enabled: control.enabled && control.MyStyle.elevation > 0 + layer.effect: DropShadow { + verticalOffset: 1 + color: control.visualFocus ? "#330066ff" : "#aaaaaa" + samples: control.MyStyle.elevation + spread: 0.5 + } + } + \endcode + + Note that we: + + \list + \li Don't bother using the drop shadow when the elevation is \c 0 + \li Change the shadow's color depending on whether or not the button has + focus + \li Make the size of the shadow depend on the elevation + \endlist + + To try out the attached property, we create a \l Row with two Buttons in + \c main.qml: + + \qml + import QtQuick + import QtQuick.Controls + + import MyStyle 1.0 + + ApplicationWindow { + id: window + width: 400 + height: 400 + visible: true + + Row { + spacing: 20 + anchors.centerIn: parent + + Button { + text: "Button 1" + } + Button { + text: "Button 2" + MyStyle.elevation: 10 + } + } + } + \endqml + + One button has no elevation, and the other has an elevation of \c 10. + + With that in place, we can run our example. To tell the application to + use our new style, we pass \c {-style MyStyle} as an application + argument, but there are \l {Using Styles in Qt Quick Controls}{many + ways} to specify the style to use. + + The end result: + + \image qtquickcontrols2-customize-buttons.png + + Note that the \c {import MyStyle 1.0} statement is only necessary + because we are using the attached property belonging to \c MyStyle. + Both buttons will use our custom style, even if we were to remove the + import. + + \section1 Customization Reference + + The following snippets present examples where the Basic style's controls + have been customized using the same approach as the + \l {Customizing a Control} section. The code can be used as a starting + point to implement a custom look and feel. + + \note The \l {macOS Style}{macOS} and \l {Windows Style}{Windows} styles + are not suitable for customizing. + \include customizing-native-styles.qdocinc + + \section2 Customizing ApplicationWindow + + ApplicationWindow consists of one visual item: + \l {ApplicationWindow::background}{background}. + + \code + import QtQuick + import QtQuick.Controls + + ApplicationWindow { + visible: true + + background: Rectangle { + gradient: Gradient { + GradientStop { position: 0; color: "#ffffff" } + GradientStop { position: 1; color: "#c1bbf9" } + } + } + } + \endcode + + + \section2 Customizing BusyIndicator + + BusyIndicator consists of two visual items: \l {Control::background}{background} + and \l {Control::contentItem}{contentItem}. + + \image qtquickcontrols2-busyindicator-custom.png + + \snippet qtquickcontrols2-busyindicator-custom.qml file + + + \section2 Customizing Button + + Button consists of two visual items: \l {Control::background}{background} + and \l {Control::contentItem}{content item}. + + \image qtquickcontrols2-button-custom.png + + \snippet qtquickcontrols2-button-custom.qml file + + + \section2 Customizing CheckBox + + CheckBox consists of three visual items: \l {Control::background}{background}, + \l {Control::contentItem}{contentItem} and \l {AbstractButton::indicator}{indicator}. + + \image qtquickcontrols2-checkbox-custom.png + + \snippet qtquickcontrols2-checkbox-custom.qml file + + \section2 Customizing CheckDelegate + + CheckDelegate consists of three visual items: \l {Control::background}{background}, + \l {Control::contentItem}{contentItem} and \l {AbstractButton::indicator}{indicator}. + + \image qtquickcontrols2-checkdelegate-custom.png + + \snippet qtquickcontrols2-checkdelegate-custom.qml file + + + \section2 Customizing ComboBox + + ComboBox consists of \l {Control::background}{background}, + \l {Control::contentItem}{content item}, \l {ComboBox::popup}{popup}, + \l {ComboBox::indicator}{indicator}, and \l {ComboBox::delegate}{delegate}. + + \image qtquickcontrols2-combobox-custom.png + + \snippet qtquickcontrols2-combobox-custom.qml file + + As explained in \l {ComboBox Model Roles}, ComboBox supports multiple + types of models. If you know that your ComboBox instances will only + ever use one particular type of model, then it is possible to simplify + the code above. + + For example, if your models will only ever be derived from + \l QAbstractItemModel and have more than one role, the following + binding is sufficient: + + \code + text: model[control.textRole] + \endcode + + However, if you want to support all standard models, the more complex + binding is necessary, and is explained in detail below. + + \quotefromfile qtquickcontrols2-combobox-custom.qml + \skipto control.textRole + \printto Array.isArray + + The first line checks if the \l {ComboBox::}{textRole} property has + been set. It is only necessary to set this property if the model + has more than one role. + + \printline Array.isArray + + If \c textRole has been set, the next step is to check if the model + is an array. + + If it is an array, the \c modelData context property will be available, + and so it must be used. Square bracket notation is used to access + the property of modelData since the property name is not known ahead + of time. + + If it is not an array, the \c model context property must be used + instead. + + \printline modelData + + Finally, if \c textRole has not been set, then the model only has one + role, and so it is sufficient to use the value of \c modelData. + + \section2 Customizing DelayButton + + DelayButton consists of two visual items: \l {Control::background}{background} + and \l {Control::contentItem}{content item}. + + \image qtquickcontrols2-delaybutton-custom.png + + \snippet qtquickcontrols2-delaybutton-custom.qml file + + + \section2 Customizing Dial + + Dial consists of two visual items: \l {Control::background}{background} + and \l {Dial::handle}{handle}. + + \image qtquickcontrols2-dial-custom.png + + \snippet qtquickcontrols2-dial-custom.qml file + + + \section2 Customizing Drawer + + Drawer can have a visual \l {Control::background}{background} + item. + + \code + background: Rectangle { + Rectangle { + x: parent.width - 1 + width: 1 + height: parent.height + color: "#21be2b" + } + } + \endcode + + + \section2 Customizing Frame + + Frame consists of one visual item: \l {Control::background}{background}. + + \image qtquickcontrols2-frame-custom.png + + \snippet qtquickcontrols2-frame-custom.qml file + + + \section2 Customizing GroupBox + + GroupBox consists of two visual items: \l {Control::background}{background} + and \l {GroupBox::label}{label}. + + \image qtquickcontrols2-groupbox-custom.png + + \snippet qtquickcontrols2-groupbox-custom.qml file + + + \section2 Customizing ItemDelegate + + ItemDelegate consists of two visual items: \l {Control::background}{background} + and \l {Control::contentItem}{content item}. + + \image qtquickcontrols2-itemdelegate-custom.png + + \snippet qtquickcontrols2-itemdelegate-custom.qml file + + + \section2 Customizing Label + + Label can have a visual \l {Label::background}{background} item. + + \image qtquickcontrols2-label-custom.png + + \snippet qtquickcontrols2-label-custom.qml file + + + \section2 Customizing Menu + + \list + \li \l Menu consists of a visual \l {Popup::background}{background} item. + \li \l MenuItem consists of four visual items: \l {Control::background}{background}, + \l {Control::contentItem}{content item}, \l {AbstractButton::}{indicator}, and + \l {MenuItem::}{arrow}. + \li \l MenuSeparator consists of a visual \l {Control::background}{background} and + \l {Control::contentItem}{content item}. + \endlist + + \image qtquickcontrols2-menu-custom.png + + \quotefromfile qtquickcontrols2-menu-custom.qml + \skipto import QtQuick + \printuntil import QtQuick.Controls + \skipto Menu + \printto eof + + + \section2 Customizing MenuBar + + MenuBar can have a visual \l {Control::background}{background} item, + and MenuBarItem consists of two visual items: \l {Control::background} + {background} and \l {Control::contentItem}{content item}. + + \image qtquickcontrols2-menubar-custom.png + + \quotefromfile qtquickcontrols2-menubar-custom.qml + \skipto import QtQuick + \printuntil import QtQuick.Controls + \skipto MenuBar + \printto eof + + + \section2 Customizing PageIndicator + + PageIndicator consists of a \l {Control::background}{background}, \l {Control::contentItem}{content item}, and \l {PageIndicator::delegate}{delegate}. + + \image qtquickcontrols2-pageindicator-custom.png + + \snippet qtquickcontrols2-pageindicator-custom.qml file + + + \section2 Customizing Pane + + Pane consists of a \l {Control::background}{background}. + + \image qtquickcontrols2-pane-custom.png + + \snippet qtquickcontrols2-pane-custom.qml file + + + \section2 Customizing Popup + + Popup consists of a \l {Popup::background}{background} and + \l {Popup::contentItem}{content item}. + + \image qtquickcontrols2-popup-custom.png + + \quotefromfile qtquickcontrols2-popup-custom.qml + \skipto import QtQuick + \printuntil import QtQuick.Controls + \codeline + \skipto Popup + \printuntil { + \printuntil } + \printuntil } + \printuntil } + + + \section2 Customizing ProgressBar + + ProgressBar consists of two visual items: \l {Control::background}{background} + and \l {Control::contentItem}{content item}. + + \image qtquickcontrols2-progressbar-custom.png + + \snippet qtquickcontrols2-progressbar-custom.qml file + + + \section2 Customizing RadioButton + + RadioButton consists of three visual items: \l {Control::background}{background}, + \l {Control::contentItem}{content item} and \l {AbstractButton::indicator}{indicator}. + + \image qtquickcontrols2-radiobutton-custom.png + + \snippet qtquickcontrols2-radiobutton-custom.qml file + + + \section2 Customizing RadioDelegate + + RadioDelegate consists of three visual items: \l {Control::background}{background}, + \l {Control::contentItem}{contentItem} and \l {AbstractButton::indicator}{indicator}. + + \image qtquickcontrols2-radiodelegate-custom.png + + \snippet qtquickcontrols2-radiodelegate-custom.qml file + + + \section2 Customizing RangeSlider + + RangeSlider consists of three visual items: + \l {Control::background}{background}, + \l {RangeSlider::first}{first.handle} and + \l {RangeSlider::second.handle}{second.handle}. + + \image qtquickcontrols2-rangeslider-custom.png + + \snippet qtquickcontrols2-rangeslider-custom.qml file + + + \section2 Customizing RoundButton + + RoundButton can be customized in the same manner as + \l {Customizing Button}{Button}. + + + \section2 Customizing ScrollBar + + ScrollBar consists of two visual items: \l {Control::background}{background} + and \l {Control::contentItem}{content item}. + + \image qtquickcontrols2-scrollbar-custom.png + + \snippet qtquickcontrols2-scrollbar-custom.qml file + + + \section2 Customizing ScrollIndicator + + ScrollIndicator consists of two visual items: \l {Control::background}{background} + and \l {Control::contentItem}{content item}. + + \image qtquickcontrols2-scrollindicator-custom.png + + \snippet qtquickcontrols2-scrollindicator-custom.qml file + + + \section2 Customizing ScrollView + + ScrollView consists of a \l {Control::background}{background} item, + and horizontal and vertical scroll bars. + + \image qtquickcontrols2-scrollview-custom.png + + \snippet qtquickcontrols2-scrollview-custom.qml file + + + \section2 Customizing Slider + + Slider consists of two visual items: \l {Control::background}{background}, + and \l {Slider::handle}{handle}. + + \image qtquickcontrols2-slider-custom.png + + \snippet qtquickcontrols2-slider-custom.qml file + + + \section2 Customizing SpinBox + + SpinBox consists of four visual items: \l {Control::background}{background}, + \l {Control::contentItem}{contentItem}, \l {SpinBox::up.indicator}{up indicator}, + and \l {SpinBox::down.indicator}{down indicator}. + + \image qtquickcontrols2-spinbox-custom.png + + \snippet qtquickcontrols2-spinbox-custom.qml file + + + \section2 Customizing SplitView + + SplitView consists of a visual \l {SplitView::handle}{handle} delegate. + + \image qtquickcontrols2-splitview-custom.png + + \snippet qtquickcontrols2-splitview-custom.qml 1 + + + \section2 Customizing StackView + + StackView can have a visual \l {Control::background}{background} + item, and it allows customizing the transitions that are used for + push, pop, and replace operations. + + \snippet qtquickcontrols2-stackview-custom.qml file + + + \section2 Customizing SwipeDelegate + + SwipeDelegate consists of six visual items: \l {Control::background}{background}, + \l {Control::contentItem}{content item}, \l {AbstractButton::indicator}{indicator}, + \c swipe.left, \c swipe.right, and \c swipe.behind. + + \image qtquickcontrols2-swipedelegate-custom.png + + \snippet qtquickcontrols2-swipedelegate-custom.qml file + + + \section2 Customizing SwipeView + + SwipeView can have a visual \l {Control::background}{background} + item. The navigation is implemented by the \l {Control::contentItem} + {content item}. + + \snippet qtquickcontrols2-swipeview-custom.qml file + + + \section2 Customizing Switch + + Switch consists of three visual items: \l {Control::background}{background}, + \l {Control::contentItem}{content item} and \l {AbstractButton::indicator}{indicator}. + + \image qtquickcontrols2-switch-custom.png + + \snippet qtquickcontrols2-switch-custom.qml file + + \section2 Customizing SwitchDelegate + + SwitchDelegate consists of three visual items: \l {Control::background}{background}, + \l {Control::contentItem}{contentItem} and \l {AbstractButton::indicator}{indicator}. + + \image qtquickcontrols2-switchdelegate-custom.png + + \snippet qtquickcontrols2-switchdelegate-custom.qml file + + + \section2 Customizing TabBar + + TabBar consists of two visual items: \l {Control::background}{background}, + and \l {Control::contentItem}{contentItem}. + + \image qtquickcontrols2-tabbar-custom.png + + \snippet qtquickcontrols2-tabbar-custom.qml file + + + \section2 Customizing TabButton + + TabButton can be customized in the same manner as + \l {Customizing Button}{Button}. + + + \section2 Customizing TextArea + + TextArea consists of a \l {TextArea::background}{background} item. + + \image qtquickcontrols2-textarea-custom.png + + \snippet qtquickcontrols2-textarea-custom.qml file + + + \section2 Customizing TextField + + TextField consists of a \l {TextField::background}{background} item. + + \image qtquickcontrols2-textfield-custom.png + + \snippet qtquickcontrols2-textfield-custom.qml file + + + \section2 Customizing ToolBar + + ToolBar consists of one visual item: \l {Control::background}{background}. + + \image qtquickcontrols2-toolbar-custom.png + + \snippet qtquickcontrols2-toolbar-custom.qml file + + + \section2 Customizing ToolButton + + ToolButton consists of two visual items: \l {Control::background}{background} + and \l {Control::contentItem}{content item}. + + \image qtquickcontrols2-toolbutton-custom.png + + \snippet qtquickcontrols2-toolbutton-custom.qml file + + + \section2 Customizing ToolSeparator + + ToolSeparator consists of two visual items: \l {Control::background}{background} + and \l {Control::contentItem}{content item}. + + \image qtquickcontrols2-toolseparator-custom.png + + \snippet qtquickcontrols2-toolseparator-custom.qml file + + + \section2 Customizing ToolTip + + ToolTip consists of two visual items: \l {Popup::background}{background} + and \l {Popup::contentItem}{content item}. + + \quotefromfile qtquickcontrols2-tooltip-custom.qml + \skipto import QtQuick + \printuntil import QtQuick.Controls + \skipto ToolTip + \printuntil } + \printuntil } + \printuntil } + + \include qquicktooltip.qdocinc customize-note + + \section2 Customizing Tumbler + + Tumbler consists of three visual items: + \l {Control::background}{background}, + \l {Control::contentItem}{contentItem}, and + \l {Tumbler::delegate}{delegate}. + + \image qtquickcontrols2-tumbler-custom.png + + \snippet qtquickcontrols2-tumbler-custom.qml file + + If you want to define your own contentItem, use either a \l ListView or + \l PathView as the root item. For a wrapping Tumbler, use PathView: + + \snippet qtquickcontrols2-tumbler-pathView.qml contentItem + + For a non-wrapping Tumbler, use ListView: + + \snippet qtquickcontrols2-tumbler-listView.qml contentItem +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-delegates.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-delegates.qdoc new file mode 100644 index 00000000000..a3883b1f1df --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-delegates.qdoc @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-delegates.html + \title Delegate Controls + \ingroup qtquickcontrols2-guidelines + \brief Guidelines for delegate controls + + Qt Quick Controls offers a selection of controls that are used as + delegates in views. + + \annotatedlist qtquickcontrols2-delegates + + Each type of delegate has its own specific target use case. The following + sections offer guidelines for choosing the appropriate type of delegate, + depending on the use case. + + \section1 CheckDelegate Control + + \image qtquickcontrols2-checkdelegate.gif + + \l CheckDelegate presents a checkable control that can be toggled on + (checked) or off (unchecked). Check delegates are typically used to + select one or more options from a set of options. + + \b {See also} \l {CheckBox Control}. + + \section1 ItemDelegate Control + + \image qtquickcontrols2-itemdelegate.gif + + \l ItemDelegate presents a checkable control that can be pressed and + clicked by the user. + + \section1 RadioDelegate Control + + \image qtquickcontrols2-radiodelegate.gif + + \l RadioDelegate presents a checkable control that can be toggled on + (checked) or off (unchecked). Radio delegates are typically used to select + one option from a set of options. + + \b {See also} \l {RadioButton Control}. + + \section1 SwipeDelegate Control + + \image qtquickcontrols2-swipedelegate.gif + + \l SwipeDelegate presents a view item that can be swiped left or right to + expose more options or information. + + \section1 SwitchDelegate Control + + \image qtquickcontrols2-switchdelegate.gif + + \l SwitchDelegate presents a switchable delegate that can be toggled on or off. + + \b {See also} \l {Switch Control}. + + \section1 Related Information + \list + \li \l {Qt Quick Controls Guidelines} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-deployment.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-deployment.qdoc new file mode 100644 index 00000000000..a84d0d8790f --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-deployment.qdoc @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-deployment.html + \title Deploying Qt Quick Controls Applications + + Deployment of Qt Quick Controls applications is very similar to + deployment of other types of Qt applications. However, there are a few + factors to consider. + + \section1 Deploying an Application with Several Styles + + Suppose you have an application that will be deployed to both Android and + Windows devices. To ensure that only the minimum set of files that are + necessary for the application to run are deployed to each device, you can + use file selectors. For example, your directory structure could look like + this: + + \code + resources.qrc + main.qml + +windows/MyPage.qml + +windows/qtquickcontrols2.conf + +android/MyPage.qml + +android/qtquickcontrols2.conf + \endcode + + In the project above, \c main.qml would import \c QtQuick.Controls, for + example, but shouldn't import, say, \c QtQuick.Controls.Material. Any code + that is style-specific is moved out into separate files; just as we've done + for \c MyPage.qml. + + The \c +windows/qtquickcontrols2.conf file would contain configuration + options specific to the Universal style: + + \code + [Controls] + Style=Universal + + [Universal] + Theme=Dark + Accent=Red + \endcode + + The \c +android/qtquickcontrols2.conf file would contain configuration + options specific to the Material style: + + \code + [Controls] + Style=Material + + [Material] + Theme=Light + Accent=Brown + \endcode + + \section1 Static Builds + + For dynamically built applications, it is not necessary to import a + specific style that should be usable by that application. For statically + built applications, Qt's build system must be involved to ensure that + QML plugins function as expected. Specifically, \c qmake uses + \c qmlimportscanner to scan the QML files in your application for import + statements. For this reason, any styles that should be usable by a + statically built application must explicitly import that style. Where the + import occurs is up to the developer, but it is recommended to follow the + approach mentioned in the \l {Deploying an Application with Several Styles} + section, so that only the minimum set of files that are necessary for a + particular device are deployed. + + \sa {Deploying Qt Applications}, {Using Styles in Qt Quick Controls} +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-environment.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-environment.qdoc new file mode 100644 index 00000000000..4484acf3928 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-environment.qdoc @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-environment.html + \title Supported Environment Variables in Qt Quick Controls + + This page contains a list of all environment variables that Qt Quick Controls + supports. The environment variables are primarily meant for testing purposes, but + they can also be used to set system-wide defaults. + + \table + \header + \li Variable + \li Description + \row + \li \c QT_QUICK_CONTROLS_STYLE + \li Specifies the default \l {Styling Qt Quick Controls}{Qt Quick Controls style}. + The value can be either one of the built-in styles, for example \c "Material", + or a custom style such as \c "MyStyle". + \row + \li \c QT_QUICK_CONTROLS_FALLBACK_STYLE + \li Specifies a fallback style for \l {Creating a Custom Style}{custom styles}. + The value can be one of the built-in styles, for example \c "Material", + \row + \li \c QT_QUICK_CONTROLS_CONF + \li Specifies the location of the \l {Qt Quick Controls configuration file}. + By default, the configuration file is loaded from the application's + resources in \c ":/qtquickcontrols2.conf". + \row + \li \c QT_QUICK_CONTROLS_HOVER_ENABLED + \li Specifies whether Qt Quick Controls use \l {Control::hoverEnabled}{hover effects}. + The value can be set to \c 0 or \c 1 to disable or enable hover effects, respectively. + \endtable + + \l {Imagine style} specific environment variables: + + \include qquickimaginestyle.qdocinc env + + \l {Material style} specific environment variables: + + \include qquickmaterialstyle.qdocinc env + + \l {Universal style} specific environment variables: + + \include qquickuniversalstyle.qdocinc env + + \section1 Related Information + + \list + \li \l{Styling Qt Quick Controls} + \li \l{Qt Quick Controls Configuration File} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-examples.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-examples.qdoc new file mode 100644 index 00000000000..2924114f3b8 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-examples.qdoc @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \group qtquickcontrols2-examples + \ingroup all-examples + \keyword Qt Quick Controls Examples + \title Qt Quick Controls Examples + \keyword Qt Quick Controls 2 Examples + \brief A collection of examples for \l {Qt Quick Controls} + + These examples demonstrate creating user interfaces using \l {Qt Quick Controls}. +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-fileselectors.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-fileselectors.qdoc new file mode 100644 index 00000000000..4c782de100d --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-fileselectors.qdoc @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-fileselectors.html + \title Using File Selectors with Qt Quick Controls + + \l {QFileSelector}{File selectors} provide a convenient way of selecting + file variants. Qt offers the platform name and the locale as built-in + selectors. Qt Quick Controls extends the built-in selectors with the name + (lowercase) of the style that an application is running with. + + By using file selectors, style-specific tweaks can be applied without + creating a hard dependency to a style. From the available file variants, + only the selected QML file is loaded by the QML engine. Each file variant + can assume the context, that is, a specific style. This typically leads + to some code duplication, but on the other hand, cuts the aforementioned + hard dependency to the style, and leads to simpler and more efficient + QML code. + + The following example demonstrates a custom rounded button that has a + styled drop shadow in the \l {Material Style}{Material style}, and looks + flat in other styles. The files are organized so that the Material version + of \c CustomButton.qml is placed into a \c +Material sub-directory. + + \code + :/main.qml + :/CustomButton.qml + :/+Material/CustomButton.qml + \endcode + + By default, \c main.qml will use \c CustomButton.qml for the \c CustomButton + type. However, when the application is run with the Material style, the + \c Material selector will be present and the \c +Material/CustomButton.qml + version will be used instead. + + \code + // main.qml + import QtQuick + import QtQuick.Controls + + ApplicationWindow { + id: window + visible: true + + CustomButton { + text: "Button" + anchors.centerIn: parent + } + } + \endcode + + The base implementation of the custom button is a simple rounded + flat button. + + \code + // CustomButton.qml + import QtQuick + import QtQuick.Controls + + Button { + id: control + + background: Rectangle { + radius: width / 2 + implicitWidth: 36 + implicitHeight: 36 + color: control.pressed ? "#ccc" : "#eee" + } + } + \endcode + + The Material style's implementation of the custom button imports the + Material style, requests a dark theme to get light text, and creates + a drop shadow for the background. + + \code + // +Material/CustomButton.qml + import QtQuick + import QtGraphicalEffects + import QtQuick.Controls + import QtQuick.Controls.Material + + Button { + id: control + + Material.theme: Material.Dark + + background: Rectangle { + implicitWidth: 48 + implicitHeight: 48 + color: Material.accentColor + radius: width / 2 + + layer.enabled: control.enabled + layer.effect: DropShadow { + verticalOffset: 1 + color: Material.dropShadowColor + samples: control.pressed ? 20 : 10 + spread: 0.5 + } + } + } + \endcode + + \note It is recommended to use \l QQmlApplicationEngine, which internally + creates a \l QQmlFileSelector instance. This is all that is needed to take + QML file selectors into use. + + \section1 Related Information + \list + \li \l {QFileSelector} + \li \l {QQmlFileSelector} + \li \l {Styling Qt Quick Controls} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-focus.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-focus.qdoc new file mode 100644 index 00000000000..77bc9883b97 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-focus.qdoc @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-focus.html + \keyword Focus Management in Qt Quick Controls 2 + \title Focus Management in Qt Quick Controls + \brief Overview of focus handling with Qt Quick Controls + + Qt Quick Controls follows the standard + \l {Keyboard Focus in Qt Quick}{Qt Quick focus system}, while also + providing some added convenience. For example, the + \l {Control::}{focusPolicy} property can be used to control the ways in + which a control receives focus. + + \section1 Focus Scope Controls + + Qt Quick Controls offers a selection of controls that act as + \l {Acquiring Focus and Focus Scopes}{focus scopes}: + + \annotatedlist qtquickcontrols2-focusscopes + + \sa {Keyboard Focus in Qt Quick} +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-fusion.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-fusion.qdoc new file mode 100644 index 00000000000..ca67985f8de --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-fusion.qdoc @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-fusion.html + \title Fusion Style + + The Fusion style is a desktop-oriented style. + + The Fusion style is a platform-agnostic style that offers a desktop-oriented + look and feel. It implements the same design language as the + \l {Qt Widget Gallery}{Fusion style for Qt Widgets}. + + \image qtquickcontrols2-fusion.png + + To run an application with the Fusion style, see + \l {Using Styles in Qt Quick Controls}. + + \note The Fusion style is not a native desktop style. The style runs on any + platform, and looks similar everywhere. Minor differences may occur due to + differences in the standard system palettes, available fonts, and font + rendering engines. + + \section2 Customization + + The Fusion style uses the standard system \l[QtQuick]{Palette} + to provide colors that match the desktop environment. + + \image qtquickcontrols2-fusion-palettes.png + + Custom palettes can be specified for any control, + \l{Popup::palette}{popup}, or \l{Window::palette}{application window}. + Explicit palette attributes are automatically propagated from parent to children, + overriding any system defaults for that attribute. In the following example, + the window and all three switches appear with a violet highlight color: + + \table + \row + \li + \qml + import QtQuick 2.12 + import QtQuick.Controls 2.12 + + ApplicationWindow { + visible: true + + palette.highlight: "violet" + + Column { + anchors.centerIn: parent + + Switch { text: qsTr("First"); checked: true } + Switch { text: qsTr("Second"); checked: true } + Switch { text: qsTr("Third") } + } + } + \endqml + \li + \image qtquickcontrols2-fusion-violet.png + \endtable + + \b {See also} \l {Basic Style}, \l {Material Style}, \l {Universal Style} + + \section1 Related Information + + \list + \li \l{Styling Qt Quick Controls} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-gettingstarted.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-gettingstarted.qdoc new file mode 100644 index 00000000000..09209d21155 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-gettingstarted.qdoc @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-gettingstarted.html + \keyword Getting Started with Qt Quick Controls 2 + \title Getting Started with Qt Quick Controls + + A basic example of a QML file that makes use of controls is shown here: + + \qml + import QtQuick + import QtQuick.Controls + + ApplicationWindow { + title: "My Application" + width: 640 + height: 480 + visible: true + + Button { + text: "Push Me" + anchors.centerIn: parent + } + } + \endqml + + \section1 Setting Up Controls from C++ + + Although QQuickView has traditionally been used to display QML files in a + C++ application, doing this means you can only set window properties from + C++. + + With Qt Quick Controls, declare an ApplicationWindow as the root item of + your application and launch it by using QQmlApplicationEngine instead. + This ensures that you can control top level window properties from QML. + + A basic example of a source file that makes use of controls is shown here: + + \code + #include <QGuiApplication> + #include <QQmlApplicationEngine> + + int main(int argc, char *argv[]) + { + QGuiApplication app(argc, argv); + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + return app.exec(); + } + \endcode + + \section2 Using C++ Data From QML + + If you need to register a C++ class to use from QML, you can call + qmlRegisterType() before declaring your QQmlApplicationEngine. + See \l [QtQml] {Defining QML Types from C++} for more information. + + If you need to expose data to QML components, you need to make them + available to the context of the current QML engine. See QQmlContext for + more information. +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-guidelines.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-guidelines.qdoc new file mode 100644 index 00000000000..83d6db93fe5 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-guidelines.qdoc @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-guidelines.html + \keyword Qt Quick Controls Guidelines + \title Qt Quick Controls Guidelines + \keyword Qt Quick Controls 2 Guidelines + + Qt Quick Controls offers a selection of controls that can be used to + build complete interfaces in Qt Quick. + + Below you will find practical guidelines on how and when to use + the controls. + + \annotatedlist qtquickcontrols2-guidelines + + \section1 Related Information + \list + \li \l{Qt Quick Controls QML Types}{All Qt Quick Controls QML Types} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-icons.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-icons.qdoc new file mode 100644 index 00000000000..e043aa05d05 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-icons.qdoc @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-icons.html + \keyword Icons in Qt Quick Controls 2 + \title Icons in Qt Quick Controls + + Qt Quick Controls comes with support for icons since Qt 5.10. This means, + Buttons, item delegates, and menu items are now capable of presenting an + icon in addition to a text label. + + \section1 Using Icons + + \l {AbstractButton::icon}{AbstractButton} and \l {Action::icon}{Action} provide + the following properties through which icons can be set: + \list + \li \c icon.name + \li \c icon.source + \li \c icon.width + \li \c icon.height + \li \c icon.color + \li \c icon.cache + \endlist + + Theme icons are referenced by a name, and regular icons by a source URL. Both + \c icon.name and \c icon.source can be set to ensure that an icon will always + be found. If the icon is found in the theme, it will always be used; even if + \c icon.source is also set. If the icon is not found in the theme, \c icon.source + will be used instead. + + \code + Button { + icon.name: "edit-cut" + icon.source: "images/cut.png" + } + \endcode + + Each \l {Styling Qt Quick Controls}{Qt Quick Controls 2 style} requests a + default icon size and color according to their guidelines, but it is possible + to override these by setting the \c icon.width, \c icon.height, and \c icon.color + properties. + + The image that is loaded by an icon whose \c width and \c height are not set + depends on the type of icon in use. For theme icons, the closest available size + will be chosen. For regular icons, the behavior is the same as the \l {Image::} + {sourceSize} property of \l Image. + + The icon color is specified by default so that it matches the text color in + different states. In order to use an icon with the original colors, set the + color to \c "transparent". + + \code + Button { + icon.color: "transparent" + icon.source: "images/logo.png" + } + \endcode + + For buttons, the \l {AbstractButton::}{display} property can be used to control + how the icon and text are displayed within the button. + + The \c icon.cache property controls whether or not the icon image is cached. + For more information, see \l {Image::}{cache}. + + \section1 Icon Themes + + Compliant icon themes must follow the freedesktop icon theme specification, + which can be obtained here: \l {http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html}. + + Traditionally, only Linux and UNIX support icon themes on the platform level, + but it is possible to bundle a compliant icon theme in an application to use + themed icons on any platform. + + The default \l {QIcon::themeSearchPaths()}{icon theme search paths} depend on + the platform. On Linux and UNIX, the search path will use the \c XDG_DATA_DIRS + environment variable if available. All platforms have the resource directory + \c :/icons as a fallback. Custom icon theme search paths can be set with + \l QIcon::setThemeSearchPaths(). + + The following example bundles an icon theme called \e mytheme into the application's + resources using \l {The Qt Resource System}{Qt's resource system}. + + \badcode + <RCC> + <qresource prefix="/"> + <file>icons/mytheme/index.theme</file> + <file>icons/mytheme/32x32/myicon.png</file> + <file>icons/mytheme/32x32@2/myicon.png</file> + </qresource> + </RCC> + \endcode + + The \c index.theme file describes the general attributes of the icon theme, and + lists the available theme icon directories: + + \badcode + [Icon Theme] + Name=mytheme + Comment=My Icon Theme + + Directories=32x32,32x32@2 + + [32x32] + Size=32 + Type=Fixed + + [32x32@2] + Size=32 + Scale=2 + Type=Fixed + \endcode + + In order to use the bundled icon theme, an application should call \l QIcon::setThemeName() + before loading the main QML file: + + \code + #include <QGuiApplication> + #include <QQmlApplicationEngine> + #include <QIcon> + + int main(int argc, char *argv[]) + { + QGuiApplication app(argc, argv); + + QIcon::setThemeName("mytheme"); // <-- + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + return app.exec(); + } + \endcode + + Now it is possible to use named icons from the bundled icon theme without having + to specify any fallback source: + + \code + Button { + icon.name: "myicon" + } + \endcode + + The \l {Qt Quick Controls - Gallery}{Gallery example} and \l {Qt Quick Controls 2 - Wearable Demo} + {Wearable Demo} provide complete runnable applications with a bundled icon theme. +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-imagine.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-imagine.qdoc new file mode 100644 index 00000000000..d2dcb9be5c0 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-imagine.qdoc @@ -0,0 +1,2535 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-imagine.html + \title Imagine Style + + The Imagine Style is based on configurable image assets. \l{detailed-desc-imagine}{More...} + + \styleimport {QtQuick.Controls.Imagine 2.12} {Qt 5.10} + + \section1 Attached Properties + + \list + \li \l {imagine-path-attached-prop}{\b path} : string + \endlist + + \section1 Detailed Description + \target detailed-desc-imagine + + The Imagine style is based on image assets. The style comes with a default + set of images, but the images can be easily changed by providing a directory + with images using a predefined naming convention. + + \image qtquickcontrols2-imagine.png + \caption The Imagine style with the default images + + To run an application with the Imagine style, see + \l {Using Styles in Qt Quick Controls}. + + \section2 File Names + + The image files are named using the following convention: + + \c <control>-<element>-<states> + + The \c <control> and \c <element> sections are mandatory, but the + \c <states> section is optional. For example, if a single file named + \c "button-background.9.png" is provided for \l {Button}, it will be used + for every state that \c Button supports. It is up to the developer to + decide the set of states that they will provide images for. However, it + is recommended to provide images for the most common control states where + possible, such as \c disabled, \c pressed, etc. This will ensure that + interactive controls visually behave as the end user would expect them to. + + \section2 Element Reference + + The following table lists which elements are supported for each control, + along with the possible states for that element, and the file extension + that it expects. An element is an image that represents a certain visual + part of the control. For example, \c {Button}'s \c "background" element + represents its \l {Control::}{background}. + + \table + \header + \li Control + \li Element + \li States + \li Extension + \row + \li \l ApplicationWindow + \li background + \li active + \li .9.png (or .png) + \row + \li \l BusyIndicator + \li animation + \li disabled, running, mirrored, hovered + \li .webp + \row + \li + \li background + \li same as above + \li .webp + \row + \li \l Button + \li background + \li disabled, pressed, checked, checkable, focused, highlighted, flat, mirrored, hovered + \li .9.png + \row + \li \l CheckBox + \li background + \li disabled, pressed, checked, partially-checked, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li indicator + \li same as above + \li .png + \row + \li \l CheckDelegate + \li background + \li disabled, pressed, checked, partially-checked, focused, highlighted, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li indicator + \li same as above + \li .png + \row + \li \l ComboBox + \li background + \li disabled, pressed, editable, open, focused, mirrored, hovered, flat + \li .9.png (or .png) + \row + \li + \li indicator + \li same as above + \li .png + \row + \li + \li popup + \li same as above + \li .9.png (or .png) + \row + \li \l DelayButton + \li background + \li disabled, pressed, checked, checkable, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li progress + \li same as above + \li .9.png (or .png) + \row + \li + \li mask + \li same as above + \li .9.png (or .png) + \row + \li \l Dial + \li background + \li disabled, pressed, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li handle + \li same as above + \li .9.png (or .png) + \row + \li \l Dialog + \li background + \li modal, dim + \li .9.png (or .png) + \row + \li + \li title + \li same as above + \li .9.png (or .png) + \row + \li + \li overlay + \li modal + \li .9.png (or .png) + \row + \li \l DialogButtonBox + \li background + \li disabled, mirrored + \li .9.png (or .png) + \row + \li \l Drawer + \li background + \li modal, dim, top, left, right, bottom + \li .9.png (or .png) + \row + \li + \li overlay + \li modal + \li .9.png (or .png) + \row + \li \l Frame + \li background + \li disabled, mirrored + \li .9.png (or .png) + \row + \li \l GroupBox + \li background + \li disabled, mirrored + \li .9.png (or .png) + \row + \li + \li title + \li same as above + \li .9.png (or .png) + \row + \li \l ItemDelegate + \li background + \li disabled, pressed, focused, highlighted, mirrored, hovered + \li .9.png (or .png) + \row + \li \l Label + \li background + \li disabled, mirrored, hovered + \li .9.png (or .png) + \row + \li \l Menu + \li background + \li modal, dim + \li .9.png (or .png) + \row + \li + \li overlay + \li modal + \li .9.png (or .png) + \row + \li \l MenuItem + \li arrow + \li disabled, pressed, checked, focused, highlighted, mirrored, hovered + \li .png + \row + \li + \li background + \li same as above + \li .9.png (or .png) + \row + \li + \li indicator + \li same as above + \li .png + \row + \li \l MenuSeparator + \li background + \li disabled, mirrored + \li .9.png (or .png) + \row + \li + \li separator + \li same as above + \li .9.png (or .png) + \row + \li \l Page + \li background + \li disabled, mirrored + \li .9.png (or .png) + \row + \li \l PageIndicator + \li background + \li disabled, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li delegate + \li disabled, pressed, current, mirrored, hovered + \li .png + \row + \li \l Pane + \li background + \li disabled, mirrored + \li .9.png (or .png) + \row + \li \l Popup + \li background + \li modal, dim + \li .9.png (or .png) + \row + \li + \li overlay + \li modal + \li .9.png (or .png) + \row + \li \l ProgressBar + \li animation + \li disabled, mirrored, hovered + \li .png + \row + \li + \li background + \li disabled, indeterminate, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li mask + \li same as above + \li .9.png (or .png) + \row + \li + \li progress + \li same as above + \li .9.png (or .png) + \row + \li \l RadioButton + \li background + \li disabled, pressed, checked, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li indicator + \li same as above + \li .png + \row + \li \l RadioDelegate + \li background + \li disabled, pressed, checked, focused, highlighted, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li indicator + \li same as above + \li .png + \row + \li \l RangeSlider + \li background + \li vertical, horizontal, disabled, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li \l RangeSlider + \li progress + \li same as above + \li .9.png (or .png) + \row + \li + \li handle + \li first, second, vertical, horizontal, disabled, pressed, focused, mirrored, hovered + \li .png + \row + \li \l RoundButton + \li background + \li disabled, pressed, checked, checkable, focused, highlighted, flat, mirrored, hovered + \li .9.png (or .png) + \row + \li \l ScrollBar + \li background + \li vertical, horizontal, disabled, interactive, pressed, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li handle + \li same as above + \li .9.png (or .png) + \row + \li \l ScrollIndicator + \li background + \li vertical, horizontal, disabled, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li handle + \li same as above + \li .9.png (or .png) + \row + \li \l ScrollView + \li background + \li disabled, mirrored + \li .9.png (or .png) + \row + \li \l Slider + \li background + \li vertical, horizontal, disabled, pressed, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li handle + \li same as above + \li .9.png (or .png) + \row + \li + \li progress + \li same as above + \li .9.png (or .png) + \row + \li \l SpinBox + \li background + \li disabled, editable, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li editor + \li disabled, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li indicator + \li up, down, disabled, editable, pressed, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li \l StackView + \li background + \li disabled, mirrored + \li .9.png (or .png) + \row + \li \l SwipeDelegate + \li background + \li disabled, pressed, focused, highlighted, mirrored, hovered + \li .9.png (or .png) + \row + \li \l SwipeView + \li background + \li vertical, horizontal, disabled, interactive, focused, mirrored + \li .9.png (or .png) + \row + \li \l Switch + \li background + \li disabled, pressed, checked, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li handle + \li same as above + \li .9.png (or .png) + \row + \li + \li indicator + \li same as above + \li .9.png (or .png) + \row + \li \l SwitchDelegate + \li background + \li disabled, pressed, checked, focused, highlighted, mirrored, hovered + \li .9.png (or .png) + \row + \li + \li handle + \li same as above + \li .9.png (or .png) + \row + \li + \li indicator + \li same as above + \li .9.png (or .png) + \row + \li \l TabBar + \li background + \li disabled, header, footer, mirrored + \li .9.png (or .png) + \row + \li \l TabButton + \li background + \li disabled, pressed, checked, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li \l TextArea + \li background + \li disabled, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li \l TextField + \li background + \li disabled, focused, mirrored, hovered + \li .9.png (or .png) + \row + \li \l ToolBar + \li background + \li disabled, header, footer, mirrored + \li .9.png (or .png) + \row + \li \l ToolButton + \li background + \li disabled, pressed, checked, checkable, focused, highlighted, flat, mirrored, hovered + \li .9.png (or .png) + \row + \li \l ToolSeparator + \li background + \li vertical, horizontal, disabled, mirrored + \li .9.png (or .png) + \row + \li + \li separator + \li same as above + \li .9.png (or .png) + \row + \li \l ToolTip + \li background + \li + \li .9.png (or .png) + \row + \li \l Tumbler + \li background + \li disabled, focused, mirrored, hovered + \li .9.png (or .png) + \endtable + + \section2 Asset Examples + + The following table lists examples of assets (taken from the + \l {https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quickcontrols2/imagine/images} + {default Imagine style assets}) for all controls. The list is not + exhaustive, as not all elements need assets, but it can be used as a guide + when creating your own assets. + + The template that these assets were \l {Exporting 9-Patch Images} + {exported from} is available as a + \l {https://code.qt.io/cgit/qt/qtdeclarative.git/plain/src/quickcontrols2/imagine/design/imagine.sketch} + {Sketch project}. + + \table + \header + \li Control + \li Element + \li States + \li Asset + \li Notes + \row + \li \l ApplicationWindow + \li background + \li + \li \image imagine/images/applicationwindow-background.png + \li \l {sup1}{See footnote} \sup 1 + \row + \li + \li overlay + \li + \li \image imagine/images/applicationwindow-overlay.png + \li \l {sup1}{See footnote} \sup 1 + \row + \li + \li overlay + \li modal + \li \image imagine/images/applicationwindow-overlay-modal.png + \li \l {sup1}{See footnote} \sup 1 + \row + \li \l Button + \li background + \li + \li \image imagine/images/button-background.9.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/button-background-disabled.9.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/button-background-focused.9.png + \li + \row + \li + \li background + \li pressed + \li \image imagine/images/button-background-pressed.9.png + \li + \row + \li + \li background + \li checked + \li \image imagine/images/button-background-checked.9.png + \li + \row + \li + \li background + \li checked, disabled + \li \image imagine/images/button-background-checked-disabled.9.png + \li + \row + \li + \li background + \li checked, focused + \li \image imagine/images/button-background-checked-focused.9.png + \li + \row + \li + \li background + \li checked, hovered + \li \image imagine/images/button-background-checked-hovered.9.png + \li + \row + \li + \li background + \li highlighted + \li \image imagine/images/button-background-highlighted.9.png + \li + \row + \li + \li background + \li highlighted, disabled + \li \image imagine/images/button-background-highlighted-disabled.9.png + \li + \row + \li + \li background + \li highlighted, focused + \li \image imagine/images/button-background-highlighted-focused.9.png + \li + \row + \li + \li background + \li highlighted, hovered + \li \image imagine/images/button-background-highlighted-hovered.9.png + \li + \row + \li + \li background + \li highlighted, pressed + \li \image imagine/images/button-background-highlighted-pressed.9.png + \li + \row + \li + \li background + \li highlighted, checked + \li \image imagine/images/button-background-highlighted-checked.9.png + \li + \row + \li + \li background + \li hovered + \li \image imagine/images/button-background-hovered.9.png + \li + \row + \li + \li background + \li flat + \li \image imagine/images/button-background-flat.9.png + \li + \row + \li + \li background + \li flat, disabled + \li \image imagine/images/button-background-flat-disabled.9.png + \li + \row + \li + \li background + \li flat, hovered + \li \image imagine/images/button-background-flat-hovered.9.png + \li + \row + \li + \li background + \li flat, pressed + \li \image imagine/images/button-background-flat-pressed.9.png + \li + \row + \li + \li background + \li flat, checked + \li \image imagine/images/button-background-flat-checked.9.png + \li + \row + \li \l CheckBox + \li indicator + \li + \li \image imagine/images/checkbox-indicator.png + \li + \row + \li + \li indicator + \li disabled + \li \image imagine/images/checkbox-indicator-disabled.png + \li + \row + \li + \li indicator + \li pressed + \li \image imagine/images/checkbox-indicator-pressed.png + \li + \row + \li + \li indicator + \li checked + \li \image imagine/images/checkbox-indicator-checked.png + \li + \row + \li + \li indicator + \li checked, pressed + \li \image imagine/images/checkbox-indicator-checked-pressed.png + \li + \row + \li + \li indicator + \li checked, hovered + \li \image imagine/images/checkbox-indicator-checked-hovered.png + \li + \row + \li + \li indicator + \li checked, focused + \li \image imagine/images/checkbox-indicator-checked-focused.png + \li + \row + \li + \li indicator + \li partially, checked + \li \image imagine/images/checkbox-indicator-partially-checked.png + \li + \row + \li + \li indicator + \li partially, checked, pressed + \li \image imagine/images/checkbox-indicator-partially-checked-pressed.png + \li + \row + \li + \li indicator + \li partially, checked, focused + \li \image imagine/images/checkbox-indicator-partially-checked-focused.png + \li + \row + \li + \li indicator + \li partially, checked, hovered + \li \image imagine/images/checkbox-indicator-partially-checked-hovered.png + \li + \row + \li + \li indicator + \li focused + \li \image imagine/images/checkbox-indicator-focused.png + \li + \row + \li + \li indicator + \li hovered + \li \image imagine/images/checkbox-indicator-hovered.png + \li + \row + \li \l CheckDelegate + \li background + \li + \li \image imagine/images/checkdelegate-background.9.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/checkdelegate-background-disabled.9.png + \li + \row + \li + \li background + \li pressed + \li \image imagine/images/checkdelegate-background-pressed.9.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/checkdelegate-background-focused.9.png + \li + \row + \li + \li background + \li hovered + \li \image imagine/images/checkdelegate-background-hovered.9.png + \li + \row + \li + \li indicator + \li + \li \image imagine/images/checkdelegate-indicator.png + \li + \row + \li + \li indicator + \li disabled + \li \image imagine/images/checkdelegate-indicator-disabled.png + \li + \row + \li + \li indicator + \li pressed + \li \image imagine/images/checkdelegate-indicator-pressed.png + \li + \row + \li + \li indicator + \li checked + \li \image imagine/images/checkdelegate-indicator-checked.png + \li + \row + \li + \li indicator + \li checked, pressed + \li \image imagine/images/checkdelegate-indicator-checked-pressed.png + \li + \row + \li + \li indicator + \li checked, focused + \li \image imagine/images/checkdelegate-indicator-checked-focused.png + \li + \row + \li + \li indicator + \li checked, hovered + \li \image imagine/images/checkdelegate-indicator-checked-hovered.png + \li + \row + \li + \li indicator + \li focused + \li \image imagine/images/checkdelegate-indicator-focused.png + \li + \row + \li + \li indicator + \li hovered + \li \image imagine/images/checkdelegate-indicator-hovered.png + \li + \row + \li + \li indicator + \li partially, checked + \li \image imagine/images/checkdelegate-indicator-partially-checked.png + \li + \row + \li + \li indicator + \li partially, checked, pressed + \li \image imagine/images/checkdelegate-indicator-partially-checked-pressed.png + \li + \row + \li + \li indicator + \li partially, checked, focused + \li \image imagine/images/checkdelegate-indicator-partially-checked-focused.png + \li + \row + \li + \li indicator + \li partially, checked, hovered + \li \image imagine/images/checkdelegate-indicator-partially-checked-hovered.png + \li + \row + \li + \li indicator + \li hovered + \li \image imagine/images/checkdelegate-indicator-hovered.png + \li + \row + \li \l ComboBox + \li background + \li + \li \image imagine/images/combobox-background.9.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/combobox-background-disabled.9.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/combobox-background-focused.9.png + \li + \row + \li + \li background + \li hovered + \li \image imagine/images/combobox-background-hovered.9.png + \li + \row + \li + \li background + \li pressed + \li \image imagine/images/combobox-background-pressed.9.png + \li + \row + \li + \li background + \li open + \li \image imagine/images/combobox-background-open.9.png + \li + \row + \li + \li background + \li editable + \li \image imagine/images/combobox-background-editable.9.png + \li + \row + \li + \li background + \li editable, focused + \li \image imagine/images/combobox-background-editable-focused.9.png + \li + \row + \li + \li background + \li editable, disabled + \li \image imagine/images/combobox-background-editable-disabled.9.png + \li + \row + \li + \li indicator + \li + \li \image imagine/images/combobox-indicator.png + \li + \row + \li + \li indicator + \li disabled + \li \image imagine/images/combobox-indicator-disabled.png + \li + \row + \li + \li indicator + \li editable + \li \image imagine/images/combobox-indicator-editable.png + \li + \row + \li + \li indicator + \li editable, disabled + \li \image imagine/images/combobox-indicator-editable-disabled.png + \li + \row + \li + \li indicator + \li editable, mirrored + \li \image imagine/images/combobox-indicator-editable-mirrored.png + \li + \row + \li + \li indicator + \li editable, mirrored, disabled + \li \image imagine/images/combobox-indicator-editable-mirrored-disabled.png + \li + \row + \li + \li popup + \li + \li \image imagine/images/combobox-popup.9.png + \li + \row + \li \l DelayButton + \li background + \li + \li \image imagine/images/delaybutton-background.9.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/delaybutton-background-disabled.9.png + \li + \row + \li + \li background + \li disabled, checked + \li \image imagine/images/delaybutton-background-disabled-checked.9.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/delaybutton-background-focused.9.png + \li + \row + \li + \li background + \li pressed + \li \image imagine/images/delaybutton-background-pressed.9.png + \li + \row + \li + \li background + \li checked + \li \image imagine/images/delaybutton-background-checked.9.png + \li + \row + \li + \li background + \li checked, focused + \li \image imagine/images/delaybutton-background-checked-focused.9.png + \li + \row + \li + \li background + \li checked, hovered + \li \image imagine/images/delaybutton-background-checked-hovered.9.png + \li + \row + \li + \li background + \li hovered + \li \image imagine/images/delaybutton-background-hovered.9.png + \li + \row + \li + \li progress + \li + \li \image imagine/images/delaybutton-progress.9.png + \li + \row + \li + \li progress + \li disabled + \li \image imagine/images/delaybutton-progress-disabled.9.png + \li + \row + \li + \li mask + \li + \li \image imagine/images/delaybutton-mask.9.png + \li + \row + \li \l Dial + \li background + \li + \li \image imagine/images/dial-background.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/dial-background-disabled.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/dial-background-focused.png + \li + \row + \li + \li handle + \li + \li \image imagine/images/dial-handle.png + \li + \row + \li + \li handle + \li disabled + \li \image imagine/images/dial-handle-disabled.png + \li + \row + \li + \li handle + \li focused + \li \image imagine/images/dial-handle-focused.png + \li + \row + \li + \li handle + \li focused, pressed + \li \image imagine/images/dial-handle-focused-pressed.png + \li + \row + \li + \li handle + \li focused, hovered + \li \image imagine/images/dial-handle-focused-hovered.png + \li + \row + \li + \li handle + \li pressed + \li \image imagine/images/dial-handle-pressed.png + \li + \row + \li + \li handle + \li hovered + \li \image imagine/images/dial-handle-hovered.png + \li + \row + \li \l Dialog + \li background + \li + \li \image imagine/images/dialog-background.9.png + \li + \row + \li + \li overlay + \li + \li \image imagine/images/dialog-overlay.png + \li \l {sup1}{See footnote} \sup 1 + \row + \li + \li overlay + \li modal + \li \image imagine/images/dialog-overlay-modal.png + \li \l {sup1}{See footnote} \sup 1 + \row + \li \l DialogButtonBox + \li background + \li + \li \image imagine/images/dialogbuttonbox-background.9.png + \li + \row + \li \l Drawer + \li background + \li left + \li \image imagine/images/drawer-background-left.9.png + \li + \row + \li + \li background + \li right + \li \image imagine/images/drawer-background-right.9.png + \li + \row + \li + \li background + \li top + \li \image imagine/images/drawer-background-top.9.png + \li + \row + \li + \li background + \li bottom + \li \image imagine/images/drawer-background-bottom.9.png + \li + \row + \li + \li overlay + \li + \li \image imagine/images/drawer-overlay.png + \li \l {sup1}{See footnote} \sup 1 + \row + \li + \li overlay + \li modal + \li \image imagine/images/drawer-overlay-modal.png + \li \l {sup1}{See footnote} \sup 1 + \row + \li \l Frame + \li background + \li + \li \image imagine/images/frame-background.9.png + \li + \row + \li \l GroupBox + \li background + \li + \li \image imagine/images/groupbox-background.9.png + \li + \row + \li + \li title + \li + \li \image imagine/images/groupbox-title.9.png + \li + \row + \li \l ItemDelegate + \li background + \li + \li \image imagine/images/itemdelegate-background.9.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/itemdelegate-background-disabled.9.png + \li + \row + \li + \li background + \li pressed + \li \image imagine/images/itemdelegate-background-pressed.9.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/itemdelegate-background-focused.9.png + \li + \row + \li + \li background + \li hovered + \li \image imagine/images/itemdelegate-background-hovered.9.png + \li + \row + \li + \li background + \li highlighted + \li \image imagine/images/itemdelegate-background-highlighted.9.png + \li + \row + \li \l Menu + \li background + \li + \li \image imagine/images/menu-background.9.png + \li + \row + \li \l MenuItem + \li background + \li + \li \image imagine/images/menuitem-background.9.png + \li + \row + \li + \li background + \li highlighted + \li \image imagine/images/menuitem-background-highlighted.9.png + \li + \row + \li + \li arrow + \li + \li \image imagine/images/menuitem-arrow.png + \li + \row + \li + \li arrow + \li mirrored + \li \image imagine/images/menuitem-arrow-mirrored.png + \li + \row + \li + \li arrow + \li disabled + \li \image imagine/images/menuitem-arrow-disabled.png + \li + \row + \li + \li arrow + \li mirrored, disabled + \li \image imagine/images/menuitem-arrow-mirrored-disabled.png + \li + \row + \li + \li indicator + \li + \li \image imagine/images/menuitem-indicator.png + \li + \row + \li + \li indicator + \li disabled + \li \image imagine/images/menuitem-indicator-disabled.png + \li + \row + \li + \li indicator + \li pressed + \li \image imagine/images/menuitem-indicator-pressed.png + \li + \row + \li + \li indicator + \li checked + \li \image imagine/images/menuitem-indicator-checked.png + \li + \row + \li + \li indicator + \li checked, pressed + \li \image imagine/images/menuitem-indicator-checked-pressed.png + \li + \row + \li + \li indicator + \li checked, focused + \li \image imagine/images/menuitem-indicator-checked-focused.png + \li + \row + \li + \li indicator + \li checked, hovered + \li \image imagine/images/menuitem-indicator-checked-hovered.png + \li + \row + \li + \li indicator + \li focused + \li \image imagine/images/menuitem-indicator-focused.png + \li + \row + \li + \li indicator + \li hovered + \li \image imagine/images/menuitem-indicator-hovered.png + \li + \row + \li \l MenuSeparator + \li separator + \li + \li \image imagine/images/menuseparator-separator.9.png + \li + \row + \li \l Page + \li background + \li + \li \image imagine/images/page-background.png + \li \l {sup1}{See footnote} \sup 1 + \row + \li \l PageIndicator + \li delegate + \li + \li \image imagine/images/pageindicator-delegate.png + \li + \row + \li + \li delegate + \li disabled + \li \image imagine/images/pageindicator-delegate-disabled.png + \li + \row + \li + \li delegate + \li disabled, current + \li \image imagine/images/pageindicator-delegate-disabled-current.png + \li + \row + \li + \li delegate + \li pressed + \li \image imagine/images/pageindicator-delegate-pressed.png + \li + \row + \li + \li delegate + \li current + \li \image imagine/images/pageindicator-delegate-current.png + \li + \row + \li \l Pane + \li background + \li + \li \image imagine/images/pane-background.9.png + \li + \row + \li \l Popup + \li background + \li + \li \image imagine/images/popup-background.9.png + \li \l {sup1}{See footnote} \sup 1 + \row + \li + \li overlay + \li + \li \image imagine/images/popup-overlay.png + \li \l {sup1}{See footnote} \sup 1 + \row + \li + \li overlay + \li modal + \li \image imagine/images/popup-overlay-modal.png + \li + \row + \li \l ProgressBar + \li background + \li + \li \image imagine/images/progressbar-background.9.png + \li + \row + \li + \li progress + \li + \li \image imagine/images/progressbar-progress.png + \li + \row + \li + \li mask + \li + \li \image imagine/images/progressbar-mask.9.png + \li + \row + \li \l RadioButton + \li indicator + \li + \li \image imagine/images/radiobutton-indicator.png + \li + \row + \li + \li indicator + \li disabled + \li \image imagine/images/radiobutton-indicator-disabled.png + \li + \row + \li + \li indicator + \li pressed + \li \image imagine/images/radiobutton-indicator-pressed.png + \li + \row + \li + \li indicator + \li checked + \li \image imagine/images/radiobutton-indicator-checked.png + \li + \row + \li + \li indicator + \li checked, focused + \li \image imagine/images/radiobutton-indicator-checked-focused.png + \li + \row + \li + \li indicator + \li checked, hovered + \li \image imagine/images/radiobutton-indicator-checked-hovered.png + \li + \row + \li + \li indicator + \li checked, pressed + \li \image imagine/images/radiobutton-indicator-checked-pressed.png + \li + \row + \li + \li indicator + \li focused + \li \image imagine/images/radiobutton-indicator-focused.png + \li + \row + \li + \li indicator + \li hovered + \li \image imagine/images/radiobutton-indicator-hovered.png + \li + \row + \li \l RadioDelegate + \li background + \li + \li \image imagine/images/radiodelegate-background.9.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/radiodelegate-background-disabled.9.png + \li + \row + \li + \li background + \li pressed + \li \image imagine/images/radiodelegate-background-pressed.9.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/radiodelegate-background-focused.9.png + \li + \row + \li + \li background + \li hovered + \li \image imagine/images/radiodelegate-background-hovered.9.png + \li + \row + \li + \li indicator + \li + \li \image imagine/images/radiodelegate-indicator.png + \li + \row + \li + \li indicator + \li disabled + \li \image imagine/images/radiodelegate-indicator-disabled.png + \li + \row + \li + \li indicator + \li pressed + \li \image imagine/images/radiodelegate-indicator-pressed.png + \li + \row + \li + \li indicator + \li checked + \li \image imagine/images/radiodelegate-indicator-checked.png + \li + \row + \li + \li indicator + \li checked, focused + \li \image imagine/images/radiodelegate-indicator-checked-focused.png + \li + \row + \li + \li indicator + \li checked, hovered + \li \image imagine/images/radiodelegate-indicator-checked-hovered.png + \li + \row + \li + \li indicator + \li checked, pressed + \li \image imagine/images/radiodelegate-indicator-checked-pressed.png + \li + \row + \li + \li indicator + \li focused + \li \image imagine/images/radiodelegate-indicator-focused.png + \li + \row + \li + \li indicator + \li hovered + \li \image imagine/images/radiodelegate-indicator-hovered.png + \li + \row + \li \l RangeSlider + \li background + \li vertical + \li \image imagine/images/rangeslider-background-vertical.9.png + \li + \row + \li + \li background + \li horizontal + \li \image imagine/images/rangeslider-background-horizontal.9.png + \li + \row + \li + \li progress + \li vertical + \li \image imagine/images/rangeslider-progress-vertical.9.png + \li + \row + \li + \li progress + \li vertical, disabled + \li \image imagine/images/rangeslider-progress-vertical-disabled.9.png + \li + \row + \li + \li progress + \li horizontal + \li \image imagine/images/rangeslider-progress-horizontal.9.png + \li + \row + \li + \li progress + \li horizontal, disabled + \li \image imagine/images/rangeslider-progress-horizontal-disabled.9.png + \li + \row + \li + \li handle + \li + \li \image imagine/images/rangeslider-handle.png + \li + \row + \li + \li handle + \li disabled + \li \image imagine/images/rangeslider-handle-disabled.png + \li + \row + \li + \li handle + \li focused + \li \image imagine/images/rangeslider-handle-focused.png + \li + \row + \li + \li handle + \li focused, hovered + \li \image imagine/images/rangeslider-handle-focused-hovered.png + \li + \row + \li + \li handle + \li focused, pressed + \li \image imagine/images/rangeslider-handle-focused-pressed.png + \li + \row + \li + \li handle + \li hovered + \li \image imagine/images/rangeslider-handle-hovered.png + \li + \row + \li + \li handle + \li pressed + \li \image imagine/images/rangeslider-handle-pressed.png + \li + \row + \li \l RoundButton + \li background + \li + \li \image imagine/images/roundbutton-background.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/roundbutton-background-disabled.png + \li + \row + \li + \li background + \li disabled, checked + \li \image imagine/images/roundbutton-background-disabled-checked.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/roundbutton-background-focused.png + \li + \row + \li + \li background + \li pressed + \li \image imagine/images/roundbutton-background-pressed.png + \li + \row + \li + \li background + \li checked + \li \image imagine/images/roundbutton-background-checked.png + \li + \row + \li + \li background + \li checked, focused + \li \image imagine/images/roundbutton-background-checked-focused.png + \li + \row + \li + \li background + \li checked, hovered + \li \image imagine/images/roundbutton-background-checked-hovered.png + \li + \row + \li + \li background + \li highlighted + \li \image imagine/images/roundbutton-background-highlighted.png + \li + \row + \li + \li background + \li highlighted, pressed + \li \image imagine/images/roundbutton-background-highlighted-pressed.png + \li + \row + \li + \li background + \li highlighted, focused + \li \image imagine/images/roundbutton-background-highlighted-focused.png + \li + \row + \li + \li background + \li highlighted, hovered + \li \image imagine/images/roundbutton-background-highlighted-hovered.png + \li + \row + \li + \li background + \li hovered + \li \image imagine/images/roundbutton-background-hovered.png + \li + \row + \li \l ScrollBar + \li handle + \li + \li \image imagine/images/scrollbar-handle.png + \li + \row + \li + \li handle + \li disabled + \li \image imagine/images/scrollbar-handle-disabled.png + \li + \row + \li + \li handle + \li interactive + \li \image imagine/images/scrollbar-handle-interactive.png + \li + \row + \li + \li handle + \li interactive, disabled + \li \image imagine/images/scrollbar-handle-interactive-disabled.png + \li + \row + \li + \li handle + \li interactive, pressed + \li \image imagine/images/scrollbar-handle-interactive-pressed.png + \li + \row + \li + \li handle + \li interactive, hovered + \li \image imagine/images/scrollbar-handle-interactive-hovered.png + \li + \row + \li \l ScrollIndicator + \li handle + \li + \li \image imagine/images/scrollindicator-handle.png + \li + \row + \li \l Slider + \li background + \li vertical + \li \image imagine/images/slider-background-vertical.9.png + \li + \row + \li + \li background + \li horizontal + \li \image imagine/images/slider-background-horizontal.9.png + \li + \row + \li + \li progress + \li vertical + \li \image imagine/images/slider-progress-vertical.9.png + \li + \row + \li + \li progress + \li vertical, disabled + \li \image imagine/images/slider-progress-vertical-disabled.9.png + \li + \row + \li + \li progress + \li horizontal + \li \image imagine/images/slider-progress-horizontal.9.png + \li + \row + \li + \li progress + \li horizontal, disabled + \li \image imagine/images/slider-progress-horizontal-disabled.9.png + \li + \row + \li + \li handle + \li + \li \image imagine/images/slider-handle.png + \li + \row + \li + \li handle + \li disabled + \li \image imagine/images/slider-handle-disabled.png + \li + \row + \li + \li handle + \li focused + \li \image imagine/images/slider-handle-focused.png + \li + \row + \li + \li handle + \li focused, hovered + \li \image imagine/images/slider-handle-focused-hovered.png + \li + \row + \li + \li handle + \li focused, pressed + \li \image imagine/images/slider-handle-focused-pressed.png + \li + \row + \li + \li handle + \li hovered + \li \image imagine/images/slider-handle-hovered.png + \li + \row + \li + \li handle + \li pressed + \li \image imagine/images/slider-handle-pressed.png + \li + \row + \li \l SpinBox + \li background + \li + \li \image imagine/images/spinbox-background.9.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/spinbox-background-disabled.9.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/spinbox-background-focused.9.png + \li + \row + \li + \li background + \li editable + \li \image imagine/images/spinbox-background-editable.9.png + \li + \row + \li + \li indicator + \li up + \li \image imagine/images/spinbox-indicator-up.9.png + \li + \row + \li + \li indicator + \li up, disabled + \li \image imagine/images/spinbox-indicator-up-disabled.9.png + \li + \row + \li + \li indicator + \li up, pressed + \li \image imagine/images/spinbox-indicator-up-pressed.9.png + \li + \row + \li + \li indicator + \li up, focused + \li \image imagine/images/spinbox-indicator-up-focused.9.png + \li + \row + \li + \li indicator + \li up, mirrored + \li \image imagine/images/spinbox-indicator-up-mirrored.9.png + \li + \row + \li + \li indicator + \li up, hovered + \li \image imagine/images/spinbox-indicator-up-hovered.9.png + \li + \row + \li + \li indicator + \li up, editable + \li \image imagine/images/spinbox-indicator-up-editable.9.png + \li + \row + \li + \li indicator + \li up, editable, pressed + \li \image imagine/images/spinbox-indicator-up-editable-pressed.9.png + \li + \row + \li + \li indicator + \li up, editable, focused + \li \image imagine/images/spinbox-indicator-up-editable-focused.9.png + \li + \row + \li + \li indicator + \li up, editable, mirrored + \li \image imagine/images/spinbox-indicator-up-editable-mirrored.9.png + \li + \row + \li + \li indicator + \li up, editable, hovered + \li \image imagine/images/spinbox-indicator-up-editable-hovered.9.png + \li + \row + \li + \li indicator + \li down + \li \image imagine/images/spinbox-indicator-down.9.png + \li + \row + \li + \li indicator + \li down, disabled + \li \image imagine/images/spinbox-indicator-down-disabled.9.png + \li + \row + \li + \li indicator + \li down, pressed + \li \image imagine/images/spinbox-indicator-down-pressed.9.png + \li + \row + \li + \li indicator + \li down, focused + \li \image imagine/images/spinbox-indicator-down-focused.9.png + \li + \row + \li + \li indicator + \li down, mirrored + \li \image imagine/images/spinbox-indicator-down-mirrored.9.png + \li + \row + \li + \li indicator + \li down, hovered + \li \image imagine/images/spinbox-indicator-down-hovered.9.png + \li + \row + \li + \li indicator + \li down, editable + \li \image imagine/images/spinbox-indicator-down-editable.9.png + \li + \row + \li + \li indicator + \li down, editable, pressed + \li \image imagine/images/spinbox-indicator-down-editable-pressed.9.png + \li + \row + \li + \li indicator + \li down, editable, focused + \li \image imagine/images/spinbox-indicator-down-editable-focused.9.png + \li + \row + \li + \li indicator + \li down, editable, mirrored + \li \image imagine/images/spinbox-indicator-down-editable-mirrored.9.png + \li + \row + \li + \li indicator + \li down, editable, hovered + \li \image imagine/images/spinbox-indicator-down-editable-hovered.9.png + \li + \row + \li \l SwipeDelegate + \li background + \li + \li \image imagine/images/swipedelegate-background.9.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/swipedelegate-background-disabled.9.png + \li + \row + \li + \li background + \li pressed + \li \image imagine/images/swipedelegate-background-pressed.9.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/swipedelegate-background-focused.9.png + \li + \row + \li + \li background + \li hovered + \li \image imagine/images/swipedelegate-background-hovered.9.png + \li + \row + \li \l Switch + \li indicator + \li + \li \image imagine/images/switch-indicator.png + \li + \row + \li + \li indicator + \li disabled + \li \image imagine/images/switch-indicator-disabled.png + \li + \row + \li + \li indicator + \li pressed + \li \image imagine/images/switch-indicator-pressed.png + \li + \row + \li + \li indicator + \li checked + \li \image imagine/images/switch-indicator-checked.png + \li + \row + \li + \li indicator + \li checked, focused + \li \image imagine/images/switch-indicator-checked-focused.png + \li + \row + \li + \li indicator + \li checked, hovered + \li \image imagine/images/switch-indicator-checked-hovered.png + \li + \row + \li + \li indicator + \li checked, pressed + \li \image imagine/images/switch-indicator-checked-pressed.png + \li + \row + \li + \li indicator + \li focused + \li \image imagine/images/switch-indicator-focused.png + \li + \row + \li + \li indicator + \li hovered + \li \image imagine/images/switch-indicator-hovered.png + \li + \row + \li + \li handle + \li + \li \image imagine/images/switch-handle.png + \li + \row + \li + \li handle + \li disabled + \li \image imagine/images/switch-handle-disabled.png + \li + \row + \li + \li handle + \li pressed + \li \image imagine/images/switch-handle-pressed.png + \li + \row + \li \l SwitchDelegate + \li background + \li + \li \image imagine/images/switchdelegate-background.9.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/switchdelegate-background-disabled.9.png + \li + \row + \li + \li background + \li pressed + \li \image imagine/images/switchdelegate-background-pressed.9.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/switchdelegate-background-focused.9.png + \li + \row + \li + \li background + \li hovered + \li \image imagine/images/switchdelegate-background-hovered.9.png + \li + \row + \li + \li indicator + \li + \li \image imagine/images/switchdelegate-indicator.png + \li + \row + \li + \li indicator + \li disabled + \li \image imagine/images/switchdelegate-indicator-disabled.png + \li + \row + \li + \li indicator + \li pressed + \li \image imagine/images/switchdelegate-indicator-pressed.png + \li + \row + \li + \li indicator + \li checked + \li \image imagine/images/switchdelegate-indicator-checked.png + \li + \row + \li + \li indicator + \li checked, focused + \li \image imagine/images/switchdelegate-indicator-checked-focused.png + \li + \row + \li + \li indicator + \li checked, hovered + \li \image imagine/images/switchdelegate-indicator-checked-hovered.png + \li + \row + \li + \li indicator + \li checked, pressed + \li \image imagine/images/switchdelegate-indicator-checked-pressed.png + \li + \row + \li + \li indicator + \li focused + \li \image imagine/images/switchdelegate-indicator-focused.png + \li + \row + \li + \li indicator + \li hovered + \li \image imagine/images/switchdelegate-indicator-hovered.png + \li + \row + \li + \li handle + \li + \li \image imagine/images/switchdelegate-handle.png + \li + \row + \li + \li handle + \li disabled + \li \image imagine/images/switchdelegate-handle-disabled.png + \li + \row + \li \l TabBar + \li background + \li + \li \image imagine/images/tabbar-background.png + \li + \row + \li \l TabButton + \li background + \li + \li \image imagine/images/tabbutton-background.9.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/tabbutton-background-disabled.9.png + \li + \row + \li + \li background + \li pressed + \li \image imagine/images/tabbutton-background-pressed.9.png + \li + \row + \li + \li background + \li checked + \li \image imagine/images/tabbutton-background-checked.9.png + \li + \row + \li + \li background + \li hovered + \li \image imagine/images/tabbutton-background-hovered.9.png + \li + \row + \li + \li background + \li disabled, checked + \li \image imagine/images/tabbutton-background-disabled-checked.9.png + \li + \row + \li \l TextArea + \li background + \li + \li \image imagine/images/textarea-background.9.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/textarea-background-disabled.9.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/textarea-background-focused.9.png + \li + \row + \li \l TextField + \li background + \li + \li \image imagine/images/textfield-background.9.png + \li + \row + \li + \li background + \li disabled + \li \image imagine/images/textfield-background-disabled.9.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/textfield-background-focused.9.png + \li + \row + \li \l ToolBar + \li background + \li + \li \image imagine/images/toolbar-background.png + \li + \row + \li \l ToolButton + \li background + \li + \li \image imagine/images/toolbutton-background.9.png + \li + \row + \li + \li background + \li disabled, checked + \li \image imagine/images/toolbutton-background-disabled-checked.9.png + \li + \row + \li + \li background + \li focused + \li \image imagine/images/toolbutton-background-focused.9.png + \li + \row + \li + \li background + \li pressed + \li \image imagine/images/toolbutton-background-pressed.9.png + \li + \row + \li + \li background + \li checked + \li \image imagine/images/toolbutton-background-checked.9.png + \li + \row + \li + \li background + \li checked, focused + \li \image imagine/images/toolbutton-background-checked-focused.9.png + \li + \row + \li + \li background + \li checked, hovered + \li \image imagine/images/toolbutton-background-checked-hovered.9.png + \li + \row + \li + \li background + \li hovered + \li \image imagine/images/toolbutton-background-hovered.9.png + \li + \row + \li \l ToolSeparator + \li separator + \li horizontal + \li \image imagine/images/toolseparator-separator-horizontal.9.png + \li + \row + \li + \li separator + \li vertical + \li \image imagine/images/toolseparator-separator-vertical.9.png + \li + \row + \li \l ToolTip + \li background + \li + \li \image imagine/images/tooltip-background.9.png + \li + \endtable + + \target sup1 + \sup 1 A 1x1 image containing one color, stretched to fill the control. + + \section2 9-Patch Images + + The Imagine style uses \l + {https://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch}{9-patch + images} in order to give designers control over how a particular element + responds to being resized. Here is an example of a 9-patch image that + represents a \l {Button}'s \l {Control::}{background}, alongside a + magnified version (to make it easier to see the 9-patch lines): + + \image qtquickcontrols2-imagine-9-patch-4x.png + + The content of the image is 44 pixels wide by 32 pixels high. Every 9-patch + image needs a one pixel thick line (collectively referred to as + "9-patch lines") around every side, so the actual size of the image becomes + 46 pixels wide by 34 pixels high. Note that the 9-patch lines must be one + pixel thick regardless of the target DPI of the image. For example, + the 9-patch lines for button-background.9.png and button-background@2x.9.png + must both be one pixel thick. + + The 9-patch lines must be black, and the remaining areas must be transparent + or white: + + \image qtquickcontrols2-imagine-9-patch-size.png + + \section3 Stretchable Areas + + The 9-patch lines on the top and left edges determine which parts of the + image are stretched when it is resized. + + Below are examples of the 9-patch image being resized to one and a half + times its original size in various dimensions: + + \image qtquickcontrols2-imagine-9-patch-resized-stretchable.png + + Notice how the the rounded corners keep their original size, as they are + outside the range of the lines. + + \section3 Padding Areas + + The 9-patch lines on the right and bottom edges determine how much space + is available for the control's \l {Control::}{contentItem}, which means it + can also be thought of as controlling the \l {Control::}{padding}. For a + diagram that illustrates padding, see \l {Control Layout}. + + Below are more examples of the 9-patch image being resized, but this time + demonstrating how the padding 9-patch lines work. + + \image qtquickcontrols2-imagine-9-patch-resized-padding.png + + The \c contentItem can take up as much space as it needs within the shaded + areas. If the padding lines are left out, the \c contentItem will take as + much space as it needs without exceeding the stretchable areas. + + \section3 Inset Areas + + In some cases it is necessary for a control to have a drop shadow, for + example. However, if we were to add a drop shadow to the button above, it + would affect its size, which presents problems for both layouting and + mouse/touch input boundaries. + + Inset areas accounts for this by telling the control that a certain area of + the 9-patch image should go outside of the control: + + \image qtquickcontrols2-imagine-9-patch-inset.png + + In the image below, the dashed line represents the button's clickable area, + as well as the space that it will take up in a layout. The shadow is marked + by the striped area behind it: + + \image qtquickcontrols2-imagine-9-patch-inset-boundaries.png + + \section3 Exporting 9-Patch Images + + Various vector and bitmap editors can be used to create 9-patch images + suitable for use with the Imagine style. The following sections briefly + explain the export process for each editor, and the last section explains + how to ensure the exported images are 9-patch-conformant. + + \section4 Affinity Designer + + See Affinity's \l {https://affinity.help/publisher/en-US.lproj/pages/Publishing/exportSettings.html} + {Export Settings} documentation. + + \section4 Adobe Illustrator + + See Adobe's + \l {https://helpx.adobe.com/in/illustrator/using/collect-assets-export-for-screens.html#panel} + {Asset Export panel} documentation. + + \section4 Adobe Photoshop + + See Adobe's + \l {https://helpx.adobe.com/photoshop/using/generate-assets-layers.html} + {Generate image assets from layers} documentation. + + \section4 Inkscape + + The \l {https://github.com/mitchcurtis/inkscape-9-patch-export} + {Inkscape 9-Patch Export Extension} can be used to export assets with + Inkscape. + + \section4 Sketch + + See Sketch's \l {https://sketchapp.com/docs/exporting/}{Exporting} documentation. + + Qt Quick Controls also provides a + \l {http://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quickcontrols2/imagine/design} + {plugin} for Sketch that automatically fixes the thickness of the 9-patch lines + after the assets are exported. To install this file, double-click on it. + Once Sketch has confirmed that the 9-patch export plugin has been installed, + the plugin will automatically process images when they are exported. + + \section4 Fixing 9-Patch Lines + + When exporting 9-patch images in several DPI variants (\c {@2x}, \c {@3x}, + etc.), the 9-patch lines will typically be scaled up along with the image. + There are several ways to fix this, but perhaps the simplest approach is + to use \l {https://www.imagemagick.org/script/mogrify.php}{ImageMagick's mogrify} + tool. The tool has a \c -shave feature that can be used to crop the image + to reduce the thickness of the 9-patch lines: + + \badcode + mogrify -shave 1x1 -path path/to/images *@2x.9.png + mogrify -shave 2x2 -path path/to/images *@3x.9.png + mogrify -shave 3x3 -path path/to/images *@4x.9.png + \endcode + + Regular DPI images (those without the \c @Nx prefix) are not affected, so it + is only necessary to run the command on images intended for high DPI displays. + + \section2 Animated Images + + The \l {https://developers.google.com/speed/webp/}{WebP} and GIF animated + image formats are supported by the Imagine style. + + \section2 Customization + + \section3 Path + + The Imagine style allows customizing the \l {imagine-path-attached-prop}{path} + that is used to do the image asset selection. The path can be specified for any + window or item, and it automatically propagates to children in the same manner as + \l {Control::font}{fonts}. In the following example, the window and all three radio + buttons appear with dark image assets (files that are located in "qrc:/themes/dark"). + + \table + \row + \li + \qml + import QtQuick 2.12 + import QtQuick.Controls 2.12 + import QtQuick.Controls.Imagine 2.12 + + ApplicationWindow { + visible: true + + Imagine.path: "qrc:/themes/dark" + + Column { + anchors.centerIn: parent + + RadioButton { text: qsTr("Small") } + RadioButton { text: qsTr("Medium"); checked: true } + RadioButton { text: qsTr("Large") } + } + } + \endqml + \li + \image qtquickcontrols2-imagine-customization-dark.png + \endtable + + In addition to specifying the path in QML, it is also possible to specify + it via an \l {imagine-customization-environment-variable}{environment variable} + or in a \l {imagine-customization-configuration-file}{configuration file}. + Attributes specified in QML take precedence over all other methods. + + \section4 Configuration File + \target imagine-customization-configuration-file + + \include qquickimaginestyle.qdocinc conf + + See \l {Qt Quick Controls Configuration File} for more details about the + configuration file. + + \section4 Environment Variables + \target imagine-customization-environment-variable + + \include qquickimaginestyle.qdocinc env + + See \l {Supported Environment Variables in Qt Quick Controls} for the full + list of supported environment variables. + + \section3 Palette + + The Imagine style supports palette customization via the \l {Item::}{palette} + property and the \l {Palette Configuration}{qtquickcontrols2.conf} file. + As with other styles, the exact \l[QML]{Palette}{palette roles} + that the Imagine style uses are style-dependent. However, as most of the visual + appearance of controls (for example: backgrounds) are managed through image assets, + only the roles that are typically used for text will have an effect. + + \section3 Font + + Custom fonts can be set via the \l {Control::}{font} property and the + \l {Font Configuration}{configuration} file. + + \section2 Dependency + + The Imagine style must be separately imported to gain access to the + attributes that are specific to the Imagine style. It should be noted + that regardless of the references to the Imagine style, the same + application code runs with any other style. Imagine-specific attributes + only have an effect when the application is run with the Imagine style. + + If the Imagine style is imported in a QML file that is always loaded, the + Imagine style must be deployed with the application in order to be able + to run the application regardless of which style the application is run with. + By using \l {Using File Selectors with Qt Quick Controls}{file selectors}, + style-specific tweaks can be applied without creating a hard dependency to + a style. + + \b {See also} \l {Styling Qt Quick Controls} + + \section1 Attached Property Documentation + + \styleproperty {Imagine.path} {string} {imagine-path-attached-prop} + \target imagine-path-attached-prop + This attached property holds the path to the image assets... + + \code + Button { + Imagine.path: "qrc:/themes/dark" + } + \endcode + + \endstyleproperty + + \section1 Related Information + + \list + \li \l{Styling Qt Quick Controls} + \li \l{Qt Quick Controls - Imagine Style Example: Automotive}{Automotive Example} + \li \l{Qt Quick Controls - Imagine Style Example: Music Player}{Music Player Example} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-index.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-index.qdoc new file mode 100644 index 00000000000..6de9fa228e9 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-index.qdoc @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols-index.html + \keyword Qt Quick Controls 2 + \title Qt Quick Controls + + \brief Provides a set of UI controls for Qt Quick. + + Qt Quick Controls provides a set of controls that can be used + to build complete interfaces in Qt Quick. The module was introduced + in Qt 5.7. + + \image qtquickcontrols2-styles.png + + Qt Quick Controls comes with a selection customizable styles. + See \l {Styling Qt Quick Controls} for more details. + + + \section1 Using the Module + + \section2 QML API + + The \l{Qt Quick Controls QML Types}{QML types} can be imported into your + application using the following import statement in your \c {.qml} file: + + \qml + import QtQuick.Controls + \endqml + + \section2 C++ API + + Using the \l{Qt Quick Controls C++ Classes}{C++ API} requires linking against the module library, + either directly or through other dependencies. + Several build tools have dedicated support for this, including CMake and qmake. + + \section3 Building with CMake + Use the \c find_package() command to locate the needed module components in the Qt6 package: + + \snippet qtquickcontrols2-overview.cmake 0 + + See also the \l{Build with CMake} overview. + + \section3 Building with qmake + To configure the module for building with qmake, + add the module as a value of the QT variable in the project's .pro file: + + \code + QT += quickcontrols2 + \endcode + + \section2 Building From Source + + The \b{Qt Image Formats} module is recommended, but not + required. It provides support for the \c {.webp} format used by the + \l {Animated Images}{Imagine style}. + + \section1 Versions + + Qt Quick Controls 2.0 was introduced in Qt 5.7. Subsequent minor Qt releases + increment the import version of the Qt Quick Controls modules by one, + until Qt 5.12, where the import versions match Qt's minor version. + + In Qt 6, both the major and minor versions match, and version numbers may + be omitted from imports in QML. If the version is omitted, the latest + version will be used. + + The experimental Qt Labs modules use import version 1.0. + + \table + \header + \li \c Qt + \li \l {Qt Quick QML Types}{\c QtQuick} + \li \l {Qt Quick Controls QML Types}{\c QtQuick.Controls},\br + \l {Material Style}{\c QtQuick.Controls.Material},\br + \l {Universal Style}{\c QtQuick.Controls.Universal},\br + \l {Qt Quick Templates 2 QML Types}{\c QtQuick.Templates} + \li \l {Qt Labs Platform QML Types}{\c Qt.labs.platform} + \row + \li 5.7 + \li 2.7 + \li 2.0 + \li 1.0 + \row + \li 5.8 + \li 2.8 + \li 2.1 + \li 1.0 + \row + \li 5.9 + \li 2.9 + \li 2.2 + \li 1.0 + \row + \li 5.10 + \li 2.10 + \li 2.3 + \li 1.0 + \row + \li 5.11 + \li 2.11 + \li 2.4 + \li 1.0 + \row + \li 5.12 + \li 2.12 + \li 2.12 + \li 1.0 + \row + \li 6.0 + \li 6.0 + \li 6.0 + \li 1.0 + \row + \li ... + \li ... + \li ... + \li ... + \endtable + + \section1 Module Evolution + + Qt Quick Controls was originally written with touch interfaces as the primary focus. + While it is already possible to develop desktop interfaces, work is ongoing to + provide a more native look and feel. + + \l{Changes to Qt Quick Controls} lists important changes in the + module API and functionality that were done for the Qt 6 series of Qt. + + \section1 License and Attributions + + Qt Quick Controls 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. + + Furthermore Qt Quick Controls potentially contains third party + modules under following permissive licenses: + + \generatelist{groupsbymodule attributions-qtquickcontrols} + + \section1 Topics + + \list + \li \l{Getting Started with Qt Quick Controls}{Getting Started} + \li \l{Qt Quick Controls Guidelines}{Guidelines} + \li \l{Styling Qt Quick Controls}{Styling} + \li \l{Icons in Qt Quick Controls}{Icons} + \li \l{Customizing Qt Quick Controls}{Customization} + \li \l{Using File Selectors with Qt Quick Controls}{Using File Selectors} + \li \l{Deploying Qt Quick Controls Applications}{Deployment} + \li \l{Qt Quick Controls Configuration File}{Configuration File} + \li \l{Supported Environment Variables in Qt Quick Controls}{Environment Variables} + \endlist + + \section1 Reference + + \list + \li \l{Qt Quick Controls QML Types}{QML Types} + \li \l{Qt Quick Controls C++ Classes}{C++ Classes} + \endlist + + \section1 Examples + + \list + \li \l{Qt Quick Controls - Gallery}{Gallery} + \li \l{Qt Quick Controls - Chat Tutorial}{Chat Tutorial} + \li \l{Qt Quick Controls - Text Editor}{Text Editor} + \li \l{Qt Quick Controls - Wearable Demo}{Wearable Demo} + \li \l{Qt Quick Controls - Imagine Style Example: Automotive}{Automotive Example} + \li \l{Qt Quick Controls - Imagine Style Example: Music Player}{Music Player Example} + \li \l{Qt Quick Controls Examples}{All Examples} + \endlist + + \section1 Related Modules + + \list + \li \l{Qt Quick} + \li \l{Qt Quick Layouts} + \li \l{Qt Quick Templates 2} + \li \l{Qt Labs Platform} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-indicators.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-indicators.qdoc new file mode 100644 index 00000000000..9f9e357bc66 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-indicators.qdoc @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-indicators.html + \title Indicator Controls + \ingroup qtquickcontrols2-guidelines + \brief Guidelines for indicator controls + + Qt Quick Controls offers a selection of indicator-like controls. + + \annotatedlist qtquickcontrols2-indicators + + Each type of indicator has its own specific target use case. The following + sections offer guidelines for choosing the appropriate type of indicator, + depending on the use case. + + \section1 BusyIndicator Control + + \image qtquickcontrols2-busyindicator.png + + BusyIndicator can be used to show that an operation is in progress, + and that the UI has to wait for the operation to complete. + + \section1 PageIndicator Control + + \image qtquickcontrols2-pageindicator.png + + \l PageIndicator is used to indicate the currently active page in + a container of multiple pages. + + \section1 ProgressBar Control + + \image qtquickcontrols2-progressbar.gif + + \l ProgressBar indicates the progress of an operation. The value should be + updated regularly. + + \section1 ScrollBar Control + + \image qtquickcontrols2-scrollbar.gif + + \l ScrollBar is an interactive bar that indicates the current scroll + position, and can be used to scroll to a specific position in a + \l Flickable. + + \section1 ScrollIndicator Control + + \image qtquickcontrols2-scrollindicator.gif + + \l ScrollIndicator is a non-interactive indicator that indicates the + current scroll position, and can be used to scroll to a specific position in a + \l {Flickable}. + + \section1 Related Information + \list + \li \l {Qt Quick Controls Guidelines} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-input.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-input.qdoc new file mode 100644 index 00000000000..6bc037e0077 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-input.qdoc @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-input.html + \title Input Controls + \ingroup qtquickcontrols2-guidelines + \brief Guidelines for input controls + + Qt Quick Controls offers a variety of input controls for both numeric + and textual input. + + \annotatedlist qtquickcontrols2-input + + Each type of input control has its own specific target use case. The + following sections offer guidelines for choosing the appropriate type + of input control, depending on the use case. + + \section1 ComboBox Control + + \image qtquickcontrols2-combobox.gif + + \l ComboBox is used to select a value from a static multiple-line drop-down list. + It is not possible to add new values, and only one option can be selected. + + Recommendations: + \list + \li If the number of values is very large, consider applying a filter. + \li If the list is very limited, consider using RadioButton. This has the + advantage that the user can see all options at the same time. + \li Select a default value, the value that will be chosen most often. + \endlist + + \b {See also} \l {CheckBox Control}, \l {Tumbler Control}. + + \section1 Dial Control + + \image qtquickcontrols2-dial.png + + \l Dial is similar to a traditional dial knob that is found on devices such + as stereos or industrial equipment. + + The dial is rotated by clicking and dragging, with the handle indicating the + value of the dial. + + For applications where fast input is important, the circular + \l {Dial::inputMode}{input mode} is useful, as clicking on the dial will + move it directly to that position. + + For applications where precise input is important, the horizontal and + vertical input modes are recommended, as these allow small adjustments to + be made relative to where the dial is clicked. These modes are also better + for dials where large jumps in values could be unsafe, such as a dial that + controls audio volume. + + \b {See also} \l {Tumbler Control}. + + \section1 TextArea Control + + \image qtquickcontrols2-textarea.png + + \l TextArea is a multi-line text editor. + + \section1 TextField Control + + \image qtquickcontrols2-textfield.png + + \l TextField is a single line text editor. + + \b {See also} \l {Tumbler Control}. + + \section1 Slider Control + + \image qtquickcontrols2-slider.gif + + \l Slider is used to select a value by sliding a handle along a track. + + \section1 RangeSlider Control + + \image qtquickcontrols2-rangeslider.gif + + \l RangeSlider is used to select a range specified by two values, + by sliding each handle along a track. + + \b {See also} \l {Slider Control}. + + \section1 Tumbler Control + + \image qtquickcontrols2-tumbler.png + + \l Tumbler is a spinnable wheel of items that can be selected. + + \b {See also} \l {ComboBox Control}. + + \section1 Related Information + \list + \li \l {Qt Quick Controls Guidelines} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-macos.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-macos.qdoc new file mode 100644 index 00000000000..79cf62a92bd --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-macos.qdoc @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-macOS.html + \title macOS Style + + The macOS style is a style that looks native on macOS. + \l {detailed-desc-macOS}{More...} + + \styleimport {QtQuick.Controls.macOS} {Qt 6.0} + + \target detailed-desc-macOS + + The macOS style is a style that looks native on macOS. The controls are drawn run-time using + native frameworks, and is therefore only available for applications running on macOS. + + \note Be aware that the apperance of this style can change from one minor Qt version to the + next, to better blend in with native applications on the platform. + + \table + \row + \li \image qtquickcontrols2-macos-light.png + \caption The macOS style in light theme + \li \image qtquickcontrols2-macos-dark.png + \caption The macOS style in dark theme + \endtable + + To run an application with the macOS style, see + \l {Using Styles in Qt Quick Controls}. + + \section2 Current state + + The macOS style is under development, and some controls are not yet supported. Those + controls are: \l BusyIndicator, \l DelayButton, \l PageIndicator, \l RangeSlider, \l Switch, \l TabBar and + \l Tumbler. Those will fall back to use the \l {Fusion Style}. + + \section2 Customization + + The goal of the macOS style is to for the controls look and feel as similar as possible to the + native controls in UIKit. The style will follow the theme and colors configured globally from + System Preferences, and does not come with a separate customization API on top of that. + + \note The macOS style is not suitable for \l {Customizing Qt Quick Controls}{customizing}. + The main reason is that it sometimes draw both the contents and the background + onto a single background item, which will not look good together with a custom contentItem. + It also tends to use padding and inset values that are different from the other styles. + \include customizing-native-styles.qdocinc +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-material.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-material.qdoc new file mode 100644 index 00000000000..f08c5ec3ba3 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-material.qdoc @@ -0,0 +1,404 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-material.html + \title Material Style + + The Material Style is based on the Google Material Design Guidelines. + \l{detailed-desc-material}{More...} + + \styleimport {QtQuick.Controls.Material 2.12} {Qt 5.7} + + \section1 Attached Properties + + \list + \li \l {material-accent-attached-prop}{\b accent} : color + \li \l {material-background-attached-prop}{\b background} : color + \li \l {material-elevation-attached-prop}{\b elevation} : int + \li \l {material-foreground-attached-prop}{\b foreground} : color + \li \l {material-primary-attached-prop}{\b primary} : color + \li \l {material-theme-attached-prop}{\b theme} : enumeration + \endlist + + \section1 Attached Methods + + \list + \li color \l {material-color-attached-method}{\b color}(enumeration predefined, enumeration shade) + \endlist + + \section1 Detailed Description + \target detailed-desc-material + + The Material style is based on the \l {https://www.google.com/design/spec/material-design/introduction.html} + {Google Material Design Guidelines}. It allows for a unified experience + across platforms and device sizes. + + \table + \row + \li \image qtquickcontrols2-material-light.png + \caption The Material style in light theme + \li \image qtquickcontrols2-material-dark.png + \caption The Material style in dark theme + \endtable + + To run an application with the Material style, see + \l {Using Styles in Qt Quick Controls}. + + \note The Material style is not a native Android style. The Material + style is a 100% cross-platform Qt Quick Controls style implementation that + follows the Google Material Design Guidelines. The style runs on any + platform, and looks more or less identical everywhere. Minor differences + may occur due to differences in available system fonts and font rendering + engines. + + \section2 Customization + + The Material style allows customizing five attributes, \l {material-theme-attached-prop}{theme}, + \l {material-primary-attached-prop}{primary}, \l {material-accent-attached-prop}{accent}, + \l {material-foreground-attached-prop}{foreground}, and \l {material-background-attached-prop}{background}. + + \image qtquickcontrols2-material-attributes.png + + All attributes can be specified for any window or item, and they automatically + propagate to children in the same manner as \l {Control::font}{fonts}. In the + following example, the window and all three radio buttons appear in the dark + theme using a purple accent color: + + \table + \row + \li + \qml + import QtQuick 2.12 + import QtQuick.Controls 2.12 + import QtQuick.Controls.Material 2.12 + + ApplicationWindow { + visible: true + + Material.theme: Material.Dark + Material.accent: Material.Purple + + Column { + anchors.centerIn: parent + + RadioButton { text: qsTr("Small") } + RadioButton { text: qsTr("Medium"); checked: true } + RadioButton { text: qsTr("Large") } + } + } + \endqml + \li + \image qtquickcontrols2-material-purple.png + \endtable + + In addition to specifying the attributes in QML, it is also possible to + specify them via environment variables or in a configuration file. Attributes + specified in QML take precedence over all other methods. + + \section3 Configuration File + + \include qquickmaterialstyle.qdocinc conf + + See \l {Qt Quick Controls Configuration File} for more details about the + configuration file. + + \section3 Environment Variables + + \include qquickmaterialstyle.qdocinc env + + See \l {Supported Environment Variables in Qt Quick Controls} for the full + list of supported environment variables. + + \section2 Dependency + + The Material style must be separately imported to gain access to the + attributes that are specific to the Material style. It should be noted + that regardless of the references to the Material style, the same + application code runs with any other style. Material-specific attributes + only have an effect when the application is run with the Material style. + + If the Material style is imported in a QML file that is always loaded, the + Material style must be deployed with the application in order to be able + to run the application regardless of which style the application is run with. + By using \l {Using File Selectors with Qt Quick Controls}{file selectors}, + style-specific tweaks can be applied without creating a hard dependency to + a style. + + \section2 Pre-defined Material Colors + + Even though primary and accent can be any \l {colorbasictypedocs}{color}, it + is recommended to use one of the pre-defined colors that have been designed + to work well with the rest of the Material style palette: + + Available pre-defined colors: + \value Material.Red \stylecolor {#F44336} {} + \value Material.Pink \stylecolor {#E91E63} {(default accent)} + \value Material.Purple \stylecolor {#9C27B0} {} + \value Material.DeepPurple \stylecolor {#673AB7} {} + \value Material.Indigo \stylecolor {#3F51B5} {(default primary)} + \value Material.Blue \stylecolor {#2196F3} {} + \value Material.LightBlue \stylecolor {#03A9F4} {} + \value Material.Cyan \stylecolor {#00BCD4} {} + \value Material.Teal \stylecolor {#009688} {} + \value Material.Green \stylecolor {#4CAF50} {} + \value Material.LightGreen \stylecolor {#8BC34A} {} + \value Material.Lime \stylecolor {#CDDC39} {} + \value Material.Yellow \stylecolor {#FFEB3B} {} + \value Material.Amber \stylecolor {#FFC107} {} + \value Material.Orange \stylecolor {#FF9800} {} + \value Material.DeepOrange \stylecolor {#FF5722} {} + \value Material.Brown \stylecolor {#795548} {} + \value Material.Grey \stylecolor {#9E9E9E} {} + \value Material.BlueGrey \stylecolor {#607D8B} {} + + When the dark theme is in use, different \l {Pre-defined Shades}{shades} of + the pre-defined colors are used by default: + + \value Material.Red \stylecolor {#EF9A9A} {} + \value Material.Pink \stylecolor {#F48FB1} {(default accent)} + \value Material.Purple \stylecolor {#CE93D8} {} + \value Material.DeepPurple \stylecolor {#B39DDB} {} + \value Material.Indigo \stylecolor {#9FA8DA} {(default primary)} + \value Material.Blue \stylecolor {#90CAF9} {} + \value Material.LightBlue \stylecolor {#81D4FA} {} + \value Material.Cyan \stylecolor {#80DEEA} {} + \value Material.Teal \stylecolor {#80CBC4} {} + \value Material.Green \stylecolor {#A5D6A7} {} + \value Material.LightGreen \stylecolor {#C5E1A5} {} + \value Material.Lime \stylecolor {#E6EE9C} {} + \value Material.Yellow \stylecolor {#FFF59D} {} + \value Material.Amber \stylecolor {#FFE082} {} + \value Material.Orange \stylecolor {#FFCC80} {} + \value Material.DeepOrange \stylecolor {#FFAB91} {} + \value Material.Brown \stylecolor {#BCAAA4} {} + \value Material.Grey \stylecolor {#EEEEEE} {} + \value Material.BlueGrey \stylecolor {#B0BEC5} {} + + \section2 Pre-defined Shades + + There are several different + \l {https://material.google.com/style/color.html#color-color-palette}{shades} + of each \l {Pre-defined Material Colors}{pre-defined color} that can be passed + to the \l {material-color-attached-method}{Material.color()} function: + \value Material.Shade50 + \value Material.Shade100 + \value Material.Shade200 + \value Material.Shade300 + \value Material.Shade400 + \value Material.Shade500 + \value Material.Shade600 + \value Material.Shade700 + \value Material.Shade800 + \value Material.Shade900 + \value Material.ShadeA100 + \value Material.ShadeA200 + \value Material.ShadeA400 + \value Material.ShadeA700 + + \b {See also} \l {Basic Style}, \l {Universal Style} + + \section2 Variants + + The Material style also supports a dense variant, where controls like + buttons and delegates are smaller in height and use smaller font sizes. + It is recommended to use the dense variant on desktop platforms, where + a mouse and keyboard allow more precise and flexible user interaction. + + To use the dense variant, either set the + \c QT_QUICK_CONTROLS_MATERIAL_VARIANT environment variable to \c Dense, + or specify \c Variant=Dense in the + \l {Qt Quick Controls Configuration File}{qtquickcontrols2.conf} file. + The default value in both cases is \c Normal. + + The following images illustrate the differences between some of the + controls when using the normal and dense variants: + + \table + \row + \li + \image qtquickcontrols2-material-variant-normal.png + \li + \image qtquickcontrols2-material-variant-dense.png + \endtable + + Note that the heights shown above may vary based on differences in fonts + across platforms. + + \section1 Attached Property Documentation + + \styleproperty {Material.accent} {color} {material-accent-attached-prop} + \target material-accent-attached-prop + This attached property holds the accent color of the theme. The property + can be attached to any window or item. The value is propagated to children. + + The default value is \c Material.Pink. + + In the following example, the accent color of the highlighted button is + changed to \c Material.Orange: + + \table + \row + \li + \snippet qtquickcontrols2-material-accent.qml 1 + \li + \image qtquickcontrols2-material-accent.png + \endtable + + \note Even though the accent can be any \l {colorbasictypedocs}{color}, it is + recommended to use one of the \l {pre-defined Material colors} that have been + designed to work well with the rest of the Material style palette. + + \endstyleproperty + + \styleproperty {Material.background} {color} {material-background-attached-prop} + \target material-background-attached-prop + This attached property holds the background color of the theme. The property + can be attached to any window or item. The value is propagated to children. + + The default value is theme-specific (light or dark). + + In the following example, the background color of the button is changed to + \c Material.Teal: + + \table + \row + \li + \snippet qtquickcontrols2-material-background.qml 1 + \li + \image qtquickcontrols2-material-background.png + \endtable + + \endstyleproperty + + \styleproperty {Material.elevation} {int} {material-elevation-attached-prop} + \target material-elevation-attached-prop + This attached property holds the elevation of the control. The higher the + elevation, the deeper the shadow. The property can be attached to any control, + but not all controls visualize elevation. + + The default value is control-specific. + + In the following example, the elevation of the pane is set to \c 6 + in order to achieve the look of an + \l {https://material.google.com/components/cards.html}{elevated card}: + + \table + \row + \li + \snippet qtquickcontrols2-material-elevation.qml 1 + \li + \image qtquickcontrols2-material-elevation.png + \endtable + + \endstyleproperty + + \styleproperty {Material.foreground} {color} {material-foreground-attached-prop} + \target material-foreground-attached-prop + This attached property holds the foreground color of the theme. The property + can be attached to any window or item. The value is propagated to children. + + The default value is theme-specific (light or dark). + + In the following example, the foreground color of the button is set to \c + Material.Pink: + + \table + \row + \li + \snippet qtquickcontrols2-material-foreground.qml 1 + \li + \image qtquickcontrols2-material-foreground.png + \endtable + + \endstyleproperty + + \styleproperty {Material.primary} {color} {material-primary-attached-prop} + \target material-primary-attached-prop + This attached property holds the primary color of the theme. The property + can be attached to any window or item. The value is propagated to children. + + The primary color is used as the background color of ToolBar by default. + + The default value is \c Material.Indigo. + + \note Even though the primary can be any \l {colorbasictypedocs}{color}, it is + recommended to use one of the \l {pre-defined Material colors} that have been + designed to work well with the rest of the Material style palette. + + \endstyleproperty + + \styleproperty {Material.theme} {enumeration} {material-theme-attached-prop} + \target material-theme-attached-prop + This attached property holds whether the theme is light or dark. The property + can be attached to any window or item. The value is propagated to children. + + Available themes: + \value Material.Light Light theme (default) + \value Material.Dark Dark theme + \value Material.System System theme + + Setting the theme to \c System chooses either the light or dark theme based + on the system theme colors. However, when reading the value of the theme + property, the value is never \c System, but the actual theme. + + In the following example, the theme for both the pane and the button is set + to \c Material.Dark: + + \table + \row + \li + \snippet qtquickcontrols2-material-theme.qml 1 + \li + \image qtquickcontrols2-material-theme.png + \endtable + + \endstyleproperty + + \section1 Attached Method Documentation + + \stylemethod2 {color} {color} {enumeration} {predefined} {enumeration} {shade} {material-color-attached-method} + \target material-color-attached-method + This attached method returns the effective color value of the specified + \l {pre-defined Material colors}{pre-defined Material color} combined with + the given \l {pre-defined shades}{shade}. If omitted, the shade argument + defaults to \c Material.Shade500. + + \qml + Rectangle { + color: Material.color(Material.Red) + } + \endqml + + \endstylemethod2 + + \section1 Related Information + + \list + \li \l{Styling Qt Quick Controls} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-menus.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-menus.qdoc new file mode 100644 index 00000000000..43db20927c6 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-menus.qdoc @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-menus.html + \title Menu Controls + \ingroup qtquickcontrols2-guidelines + \brief Guidelines for menu controls + + \annotatedlist qtquickcontrols2-menus + + Each type of menu control has its own specific target use case. The + following sections offer guidelines for choosing the appropriate type + of menu control, depending on the use case. + + \section1 Menu Control + + \image qtquickcontrols2-menu.png + + \l Menu control can be used for context menus; for example, after + right-clicking. It can also be used for popup menus; for example, a + menu that is shown after clicking a button. + + \l MenuItem is an item in the Menu control. Each item in a menu: + \list + \li displays text to the user + \li allows checking/unchecking + \li is highlighted (for example, on keyboard navigation) + \li performs some action on activation + \endlist + + \section1 MenuBar Control + + \image qtquickcontrols2-menubar.png + + \l MenuBar control can be used for window menu bars. + + \l MenuBarItem is an item in the MenuBar control. Each item in a menu bar: + \list + \li displays text to the user + \li is highlighted (for example, on keyboard navigation) + \li pops up the respective menu on activation + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-navigation.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-navigation.qdoc new file mode 100644 index 00000000000..95928d13421 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-navigation.qdoc @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-navigation.html + \title Navigation Controls + \ingroup qtquickcontrols2-guidelines + \brief Guidelines for navigation controls + + Qt Quick Controls offers a selection of navigation models. + + \annotatedlist qtquickcontrols2-navigation + + The following sections offer guidelines for choosing the appropriate type + of navigation model, depending on the use case. + + \section1 StackView Control + + \image qtquickcontrols2-stackview-wireframe.png + + \l StackView provides a stack-based navigation model which can be used + with a set of interlinked pages. StackView works according to a last-in + first-out principle: the page pushed last on the stack is the one visible. + Popping a page removes the last page and makes the previous one visible. + + \section1 SwipeView Control + + \image qtquickcontrols2-swipeview-wireframe.png + + \l SwipeView provides a navigation model that simplifies horizontal paged + scrolling. The page indicator on the bottom shows which is the presently + active page. + + \section1 TabBar Control + + \image qtquickcontrols2-tabbar-wireframe.png + + \l TabBar is a bar with icons or text that allows the user to switch + between different subtasks, views, or modes. + + \section1 TabButton Control + + \image qtquickcontrols2-tabbutton.png + + \l TabButton is a button with a layout suitable for a TabBar control. +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-popups.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-popups.qdoc new file mode 100644 index 00000000000..c26b4c4bf1d --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-popups.qdoc @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-popups.html + \title Popup Controls + \ingroup qtquickcontrols2-guidelines + \brief Guidelines for popup controls + + \annotatedlist qtquickcontrols2-popups + + Each type of popup control has its own specific target use case. The + following sections offer guidelines for choosing the appropriate type + of popup control, depending on the use case. + + \section1 Drawer Control + + \image qtquickcontrols2-drawer-expanded-wireframe.png + + \l Drawer provides a swipe-based side panel, similar to those often used + in touch interfaces to provide a central location for navigation. + + The drawer can be positioned at any of the four edges of the screen. It allows + the user to add navigation without taking up valuable screen space. The user can + show and hide the drawer at any time with a simple swipe movement. + + \section1 Menu Control + + \image qtquickcontrols2-menu.png + + The \l Menu control displays a vertical list of items that can be selected. It can + be used for offering a list of actions that can be taken in a given context. + + \b {See also} \l {Drawer Control}. + + \section1 Popup Control + + \image qtquickcontrols2-popup-settings.png + + A \l Popup displays content over other application content. + It prompts the user to make a decision or enter information. + + Popups can be modal or non-modal. A modal popup blocks users from interacting + with the application until they have made a choice and closed the popup. + + A popup can be used for: + + \list + \li communicating a message to the user that they must read and acknowledge. + \li displaying an error message. + \li prompting the user to make a choice and/or enter a value. + \endlist + + \section1 ToolTip Control + + \image qtquickcontrols2-tooltip.png + + \l ToolTip shows a short piece of text that informs the user of a control's + function. It is typically placed above or below the parent control. + + Recommendations: + \list + \li Use a tooltip if a control has little or no descriptive text, or needs + a short explanation. + \li Use a tooltip only if the information on a particular control is not + available elsewhere in the screen. + \li Keep the tooltip text short so that it does not cover other content + while being displayed. + \endlist + + \section1 Related Information + \list + \li \l {Qt Quick Controls Guidelines} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-qmltypes.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-qmltypes.qdoc new file mode 100644 index 00000000000..7e8d4a06c1b --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-qmltypes.qdoc @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \qmlmodule QtQuick.Controls + \keyword Qt Quick Controls QML Types + \title Qt Quick Controls QML Types + \keyword Qt Quick Controls 2 QML Types + \ingroup qmlmodules + \brief Provides QML types for user interfaces (Qt Quick Controls). + + \l{Qt Quick Controls} provides QML types for creating user interfaces. + These QML types work in conjunction with \l{Qt Quick} and + \l{Qt Quick Layouts}. + + Qt Quick Controls QML types can be imported into your application + using the following import statement in your .qml file: + + \qml + import QtQuick.Controls + \endqml + + \section1 QML Types + \generatelist {qmltypesbymodule QtQuick.Controls} + \noautolist + + \section1 Using Qt Quick Controls types in property declarations + + As mentioned in \l {Qt Quick Templates 2 QML Types}, each type in Qt Quick + Controls is backed by a C++ "template" type. These types are \l {Qt Quick + Templates 2}{non-visual implementations of controls' logic and behavior}. + + For example, the \l Menu type's API and behavior is defined by the C++ + type in Qt Quick Templates. Each \l {Definition of a Style}{style} that + wants to provide a Menu must have a Menu.qml available, and the root + item in that file must be the Menu from Qt Quick Templates. When you + import QtQuick.Controls and create a Menu in QML, the type you get is + actually the QML Menu defined by the style's Menu.qml. + + In order to use a control as the type in a property declaration, you should + use the corresponding type from Qt Quick Templates. For example, suppose + you had a \c PopupOpener component, which was a Button that opened a + Popup: + + \qml + // PopupButton.qml + import QtQuick.Controls + + Button { + required property Popup popup + + onClicked: popup.open() + } + + // main.qml + PopupButton { + popup: saveChangesDialog + } + + Dialog { + id: saveChangesDialog + + // ... + } + \endqml + + Running this code will result in an error: + + \badcode + Unable to assign Dialog_QMLTYPE to Popup_QMLTYPE + \endcode + + This is because of the inheritance hierarchy: + + \badcode + Popup (C++ type in QtQuick.Templates) + │ └── Popup (QML type in QtQuick.Controls) + └── Dialog (C++ type in QtQuick.Templates) + └── Dialog (QML type in QtQuick.Controls) + \endcode + + Dialog from \c QtQuick.Controls does not derive from the Popup from + \c QtQuick.Controls, but from \c QtQuick.Templates. + + Instead, use the Popup from Qt Quick Templates as the property type: + + \qml + // PopupButton.qml + import QtQuick.Controls + import QtQuick.Templates as T + + Button { + required property T.Popup popup + + onClicked: popup.open() + } + \endqml + + For more information on the Qt Quick Controls module, see the + \l {Qt Quick Controls} module documentation. + + \section1 Related Information + \list + \li \l {Qt Quick Controls Guidelines} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-separators.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-separators.qdoc new file mode 100644 index 00000000000..481a744ed05 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-separators.qdoc @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-separators.html + \title Separator Controls + \ingroup qtquickcontrols2-guidelines + \brief Guidelines for separator controls + + Qt Quick Controls offers a selection of separators. + + \annotatedlist qtquickcontrols2-separators + + Each type of separator has its own specific use case. The following + sections offer guidelines for choosing the appropriate type of separator, + depending on the use case. + + \section1 MenuSeparator Control + + \image qtquickcontrols2-menuseparator.png + + \l MenuSeparator should be used to separate items (typically MenuItem + controls) in a Menu. Grouping related menu items together makes it easier + for the user to interact with the menu. For example, a typical desktop + user interface might have \c Undo and \c Redo items in one group, and + \c Cut, \c Copy and \c Paste in another. + + \section1 ToolSeparator Control + + \image qtquickcontrols2-toolseparator.png + + \l ToolSeparator should be used to separate items (typically ToolButton + controls) in a ToolBar. It can be used in horizontal or vertical toolbars. + + \section1 Related Information + \list + \li \l {Qt Quick Controls Guidelines} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-styles.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-styles.qdoc new file mode 100644 index 00000000000..4273c472646 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-styles.qdoc @@ -0,0 +1,221 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-styles.html + \title Styling Qt Quick Controls + + \section1 Available Styles + + Qt Quick Controls comes with a selection of styles. + + \section2 Basic Style + + \image qtquickcontrols2-basic-thumbnail.png + The \l {Basic Style} is a simple and light-weight all-round style that offers + the maximum performance for Qt Quick Controls. + + \section2 Fusion Style + + \image qtquickcontrols2-fusion-thumbnail.png + The \l {Fusion Style} is a platform-agnostic style that offers a desktop-oriented + look and feel for Qt Quick Controls. + + \section2 Imagine Style + + \image qtquickcontrols2-imagine-thumbnail.png + The \l {Imagine Style} is based on image assets. The style comes with a default + set of images which can easily be changed by providing a directory + with images using a predefined naming convention. + + \section2 macOS Style + + \image qtquickcontrols2-macos-thumbnail.png + The \l {macOS Style} is a native-looking style for macOS. + \note this style is only available for applications running on macOS. + + \section2 Material Style + + \image qtquickcontrols2-material-thumbnail.png + The \l {Material Style} offers an appealing design based on the + \l {https://www.google.com/design/spec/material-design/introduction.html} + {Google Material Design Guidelines}, but requires more system resources than + the Basic style. + + \section2 Universal Style + + \image qtquickcontrols2-universal-thumbnail.png + The \l {Universal Style} offers an appealing design based on the + \l {https://dev.windows.com/design}{Microsoft Universal Design Guidelines}, + but requires more system resources than the Basic style. + + \section2 Windows Style + + \image qtquickcontrols2-windows-thumbnail.png + The \l {Windows Style} is a native-looking style for Windows. + \note this style is only available for applications running on Windows. + + \section1 Using Styles in Qt Quick Controls + + \section2 Default Styles + + If no style is explicitly set, a default style will be used. The style that + is used depends on the operating system: + + \list + \li Android: \l {Material Style} + \li Linux: \l {Fusion Style} + \li macOS: \l {macOS Style} + \li Windows: \l {Windows Style} + \endlist + + For all other operating systems, the \l {Basic Style} is used. + + \section2 Compile-Time Style Selection + + Compile-time style selection is a way of specifying a style to use by + importing it in QML. For example, to import the Material style: + + \qml + import QtQuick.Controls.Material + + ApplicationWindow { + // ... + } + \endqml + + Notice that QtQuick.Controls (which is responsible for run-time style + selection) is not imported. The fallback style is specified by the qmldir + of the style: + + \badcode + module QtQuick.Controls.Material + # ... + import QtQuick.Controls.Basic auto + \endcode + + The benefit of compile-time style selection is that the QtQuick.Controls plugin + is not used and therefore does not need to be deployed with the application. + + Explicit imports are also necessary if your application is built + \l {Static Builds}{statically}. + + \section2 Run-Time Style Selection + + Run-time style selection is a way of specifying a style to use by importing + \c QtQuick.Controls: + + \qml + import QtQuick.Controls + \endqml + + The QtQuick.Controls plugin will import the style and fallback + style that were set at runtime via one of the following approaches: + + \list + \li \l[CPP]{QQuickStyle::setStyle()} + \li The \c -style command line argument + \li The \c QT_QUICK_CONTROLS_STYLE environment variable + \li The \c qtquickcontrols2.conf configuration file + \endlist + + The priority of these approaches follows the order they are listed, + from highest to lowest. That is, using \c QQuickStyle to set the style will + always take priority over using the command line argument, for example. + + The benefit of run-time style selection is that a single application binary + can support multiple styles, meaning that the end user can choose which + style to run the application with. + + \section3 Using QQuickStyle in C++ + + \l[CPP]{QQuickStyle} provides C++ API for configuring a specific + style. The following example runs a Qt Quick Controls application + with the Material style: + + \code + QQuickStyle::setStyle("Material"); + \endcode + + See the detailed description of \l[CPP]{QQuickStyle} for more + details. + + \section3 Command line argument + + Passing a \c -style command line argument is the convenient way to test different + styles. It takes precedence over the other methods listed below. The following + example runs a Qt Quick Controls application with the Material style: + + \code + ./app -style material + \endcode + + \section3 Environment variable + + Setting the \c QT_QUICK_CONTROLS_STYLE environment variable can be used to set + a system-wide style preference. It takes precedence over the configuration file + mentioned below. The following example runs a Qt Quick Controls application with + the Universal style: + + \code + QT_QUICK_CONTROLS_STYLE=universal ./app + \endcode + + See \l {Supported Environment Variables in Qt Quick Controls} for the full list + of supported environment variables. + + \section3 Configuration file + + Qt Quick Controls support a special configuration file, \c :/qtquickcontrols2.conf, + that is built into an application's resources. + + The configuration file can specify the preferred style (may be overridden by either + of the methods described earlier) and certain style-specific attributes. The following + example specifies that the preferred style is the Material style. + + \code + [Controls] + Style=Material + \endcode + + See \l {Qt Quick Controls Configuration File} for more details about the + configuration file. + + \section1 Related Information + \list + \li \l {Basic Style} + \li \l {Fusion Style} + \li \l {Imagine Style} + \li \l {Material Style} + \li \l {Universal Style} + \li \l {Customizing Qt Quick Controls} + \li \l {Using File Selectors with Qt Quick Controls} + \li \l {Deploying Qt Quick Controls Applications} + \li \l {Qt Quick Controls Configuration File} + \li \l {Supported Environment Variables in Qt Quick Controls} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-universal.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-universal.qdoc new file mode 100644 index 00000000000..72267050680 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-universal.qdoc @@ -0,0 +1,288 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-universal.html + \title Universal Style + + The Universal Style is based on the Microsoft Universal Design Guidelines. + \l {detailed-desc-universal}{More...} + + \styleimport {QtQuick.Controls.Universal 2.12} {Qt 5.7} + + \section1 Attached Properties + + \list + \li \l {universal-accent-attached-prop}{\b accent} : color + \li \l {universal-background-attached-prop}{\b background} : color + \li \l {universal-foreground-attached-prop}{\b foreground} : color + \li \l {universal-theme-attached-prop}{\b theme} : enumeration + \endlist + + \section1 Attached Methods + + \list + \li color \l {color-attached-method}{\b color}(enumeration predefined) + \endlist + + \section1 Detailed Description + \target detailed-desc-universal + + The Universal style is a device-agnostic style based on the + \l {https://dev.windows.com/design}{Microsoft Universal Design Guidelines}. + The Universal style has been designed to look good on all devices, from + phones and tablets to PCs. + + \table + \row + \li \image qtquickcontrols2-universal-light.png + \caption The Universal style in light theme + \li \image qtquickcontrols2-universal-dark.png + \caption The Universal style in dark theme + \endtable + + To run an application with the Universal style, see + \l {Using Styles in Qt Quick Controls}. + + \note The Universal style is not a native Windows 10 style. The Universal + style is a 100% cross-platform Qt Quick Controls style implementation that + follows the Microsoft Universal Design Guidelines. The style runs on any + platform, and looks more or less identical everywhere. Minor differences + may occur due to differences in available system fonts and font rendering + engines. + + \section2 Customization + + The Universal style allows customizing four attributes, \l {universal-theme-attached-prop}{theme}, + \l {universal-accent-attached-prop}{accent}, \l {universal-foreground-attached-prop}{foreground}, and + \l {universal-background-attached-prop}{background}. + + \image qtquickcontrols2-universal-attributes.png + + Both attributes can be specified for any window or item, and they automatically + propagate to children in the same manner as \l {Control::font}{fonts}. In the + following example, the window and all three radio buttons appear in the dark + theme using a violet accent color: + + \table + \row + \li + \qml + import QtQuick 2.12 + import QtQuick.Controls 2.12 + import QtQuick.Controls.Universal 2.12 + + ApplicationWindow { + visible: true + + Universal.theme: Universal.Dark + Universal.accent: Universal.Violet + + Column { + anchors.centerIn: parent + + RadioButton { text: qsTr("Small") } + RadioButton { text: qsTr("Medium"); checked: true } + RadioButton { text: qsTr("Large") } + } + } + \endqml + \li + \image qtquickcontrols2-universal-violet.png + \endtable + + In addition to specifying the attributes in QML, it is also possible to + specify them via environment variables or in a configuration file. Attributes + specified in QML take precedence over all other methods. + + \section3 Configuration File + + \include qquickuniversalstyle.qdocinc conf + + See \l {Qt Quick Controls Configuration File} for more details about the + configuration file. + + \section3 Environment Variables + + \include qquickuniversalstyle.qdocinc env + + See \l {Supported Environment Variables in Qt Quick Controls} for the full + list of supported environment variables. + + \section2 Dependency + + The Universal style must be separately imported to gain access to the + attributes that are specific to the Universal style. It should be noted + that regardless of the references to the Universal style, the same + application code runs with any other style. Universal-specific attributes + only have an effect when the application is run with the Universal style. + + If the Universal style is imported in a QML file that is always loaded, the + Universal style must be deployed with the application in order to be able + to run the application regardless of which style the application is run with. + By using \l {Using File Selectors with Qt Quick Controls}{file selectors}, + style-specific tweaks can be applied without creating a hard dependency to + a style. + + \section2 Pre-defined Universal Colors + + Available pre-defined colors: + \value Universal.Lime \stylecolor {#A4C400} {} + \value Universal.Green \stylecolor {#60A917} {} + \value Universal.Emerald \stylecolor {#008A00} {} + \value Universal.Teal \stylecolor {#00ABA9} {} + \value Universal.Cyan \stylecolor {#1BA1E2} {} + \value Universal.Cobalt \stylecolor {#3E65FF} {(default accent)} + \value Universal.Indigo \stylecolor {#6A00FF} {} + \value Universal.Violet \stylecolor {#AA00FF} {} + \value Universal.Pink \stylecolor {#F472D0} {} + \value Universal.Magenta \stylecolor {#D80073} {} + \value Universal.Crimson \stylecolor {#A20025} {} + \value Universal.Red \stylecolor {#E51400} {} + \value Universal.Orange \stylecolor {#FA6800} {} + \value Universal.Amber \stylecolor {#F0A30A} {} + \value Universal.Yellow \stylecolor {#E3C800} {} + \value Universal.Brown \stylecolor {#825A2C} {} + \value Universal.Olive \stylecolor {#6D8764} {} + \value Universal.Steel \stylecolor {#647687} {} + \value Universal.Mauve \stylecolor {#76608A} {} + \value Universal.Taupe \stylecolor {#87794E} {} + + \b {See also} \l {Basic Style}, \l {Material Style} + + \section1 Attached Property Documentation + + \styleproperty {Universal.accent} {color} {universal-accent-attached-prop} + \target universal-accent-attached-prop + This attached property holds the accent color of the theme. The property + can be attached to any window or item. The value is propagated to children. + + The default value is \c Universal.Cobalt. + + In the following example, the accent color of the highlighted button is + changed to \c Universal.Orange: + + \table + \row + \li + \snippet qtquickcontrols2-universal-accent.qml 1 + \li + \image qtquickcontrols2-universal-accent.png + \endtable + + \note Even though the accent can be any \l {colorbasictypedocs}{color}, it is + recommended to use one of the \l {pre-defined Universal colors} that have been + designed to work well with the rest of the Universal style palette. + + \endstyleproperty + + \styleproperty {Universal.background} {color} {universal-background-attached-prop} + \target universal-background-attached-prop + This attached property holds the background color of the theme. The property + can be attached to any window or item. The value is propagated to children. + + The default value is theme-specific (light or dark). + + In the following example, the background color of the pane is changed to + \c Universal.Steel: + + \table + \row + \li + \snippet qtquickcontrols2-universal-background.qml 1 + \li + \image qtquickcontrols2-universal-background.png + \endtable + + \endstyleproperty + + \styleproperty {Universal.foreground} {color} {universal-foreground-attached-prop} + \target universal-foreground-attached-prop + This attached property holds the foreground color of the theme. The property + can be attached to any window or item. The value is propagated to children. + + The default value is theme-specific (light or dark). + + In the following example, the foreground color of the button is set to \c + Universal.Pink: + + \table + \row + \li + \snippet qtquickcontrols2-universal-foreground.qml 1 + \li + \image qtquickcontrols2-universal-foreground.png + \endtable + + \styleproperty {Universal.theme} {enumeration} {universal-theme-attached-prop} + \target universal-theme-attached-prop + This attached property holds whether the theme is light or dark. The property + can be attached to any window or item. The value is propagated to children. + + Available themes: + \value Universal.Light Light theme (default) + \value Universal.Dark Dark theme + \value Universal.System System theme + + Setting the theme to \c System chooses either the light or dark theme based + on the system theme colors. However, when reading the value of the theme + property, the value is never \c System, but the actual theme. + + In the following example, the theme for both the pane and the button is set + to \c Universal.Dark: + + \table + \row + \li + \snippet qtquickcontrols2-universal-theme.qml 1 + \li + \image qtquickcontrols2-universal-theme.png + \endtable + + \endstyleproperty + + \section1 Attached Method Documentation + + \stylemethod {color} {color} {enumeration} {predefined} {color-attached-method} + \target color-attached-method + This attached method returns the effective color value of the specified + \l {pre-defined Universal colors}{pre-defined Universal color}. + + \qml + Rectangle { + color: Universal.color(Universal.Red) + } + \endqml + + \endstylemethod + + \section1 Related Information + + \list + \li \l{Styling Qt Quick Controls} + \endlist +*/ diff --git a/src/quickcontrols2/doc/src/qtquickcontrols2-windows.qdoc b/src/quickcontrols2/doc/src/qtquickcontrols2-windows.qdoc new file mode 100644 index 00000000000..e5e12e712c7 --- /dev/null +++ b/src/quickcontrols2/doc/src/qtquickcontrols2-windows.qdoc @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickcontrols2-Windows.html + \title Windows Style + + The Windows style is a style that looks native on Windows. + \l {detailed-desc-Windows}{More...} + + \styleimport {QtQuick.Controls.Windows} {Qt 6.0} + + \target detailed-desc-Windows + + The Windows style is a style that looks native on Windows. The controls are drawn run-time using + native libraries, and is therefore only available for applications running on Windows. + + \note Be aware that the apperance of this style can change from one minor Qt version to the + next, to better blend in with native applications on the platform. + + \table + \row + \li \image qtquickcontrols2-windows.png + \caption The Windows style + \endtable + + To run an application with the Windows style, see + \l {Using Styles in Qt Quick Controls}. + + \section2 Current state + + The Windows style is under development, and some controls are not yet supported. Those + controls are: \l BusyIndicator, \l DelayButton, \l PageIndicator, \l RangeSlider, \l Switch, \l TabBar and + \l Tumbler. Those will fall back to use the \l {Fusion Style}. + + \section2 Customization + + The goal of the Windows style is to for the controls look and feel as similar as possible to the + native controls on Windows. The style will follow the theme and colors configured globally from + Windows Settings, and does not come with a separate customization API on top of that. + + \note The Windows style is not suitable for \l {Customizing Qt Quick Controls}{customizing}. + The main reason is that it sometimes draw both the contents and the background + onto a single background item, which will not look good together with a custom contentItem. + It also tends to use padding and inset values that are different from the other styles. + \include customizing-native-styles.qdocinc +*/ diff --git a/src/quickcontrols2/fusion/ApplicationWindow.qml b/src/quickcontrols2/fusion/ApplicationWindow.qml new file mode 100644 index 00000000000..090d361c025 --- /dev/null +++ b/src/quickcontrols2/fusion/ApplicationWindow.qml @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Templates as T +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ApplicationWindow { + id: window + + color: window.palette.window +} diff --git a/src/quickcontrols2/fusion/BusyIndicator.qml b/src/quickcontrols2/fusion/BusyIndicator.qml new file mode 100644 index 00000000000..ed63782ba7d --- /dev/null +++ b/src/quickcontrols2/fusion/BusyIndicator.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.BusyIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + + contentItem: BusyIndicatorImpl { + implicitWidth: 28 + implicitHeight: 28 + color: control.palette.text + + running: control.running + opacity: control.running ? 1 : 0 + Behavior on opacity { OpacityAnimator { duration: 250 } } + + RotationAnimator on rotation { + running: control.running || control.contentItem.visible + from: 0 + to: 360 + duration: 1000 + loops: Animation.Infinite + } + } +} diff --git a/src/quickcontrols2/fusion/Button.qml b/src/quickcontrols2/fusion/Button.qml new file mode 100644 index 00000000000..22ce958f899 --- /dev/null +++ b/src/quickcontrols2/fusion/Button.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Button { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 4 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.palette.buttonText + } + + background: ButtonPanel { + implicitWidth: 80 + implicitHeight: 24 + + control: control + visible: !control.flat || control.down || control.checked || control.highlighted || control.visualFocus + || (enabled && control.hovered) + } +} diff --git a/src/quickcontrols2/fusion/CMakeLists.txt b/src/quickcontrols2/fusion/CMakeLists.txt new file mode 100644 index 00000000000..96f04498360 --- /dev/null +++ b/src/quickcontrols2/fusion/CMakeLists.txt @@ -0,0 +1,145 @@ +##################################################################### +## qtquickcontrols2fusionstyleplugin Plugin: +##################################################################### + +set(qml_files + "ApplicationWindow.qml" + "BusyIndicator.qml" + "Button.qml" + "CheckBox.qml" + "CheckDelegate.qml" + "ComboBox.qml" + "DelayButton.qml" + "Dial.qml" + "Dialog.qml" + "DialogButtonBox.qml" + "Drawer.qml" + "Frame.qml" + "GroupBox.qml" + "HorizontalHeaderView.qml" + "ItemDelegate.qml" + "Label.qml" + "Menu.qml" + "MenuBar.qml" + "MenuBarItem.qml" + "MenuItem.qml" + "MenuSeparator.qml" + "Page.qml" + "PageIndicator.qml" + "Pane.qml" + "Popup.qml" + "ProgressBar.qml" + "RadioButton.qml" + "RadioDelegate.qml" + "RangeSlider.qml" + "RoundButton.qml" + "ScrollBar.qml" + "ScrollView.qml" + "ScrollIndicator.qml" + "SelectionRectangle.qml" + "Slider.qml" + "SpinBox.qml" + "SplitView.qml" + "SwipeDelegate.qml" + "SwitchDelegate.qml" + "Switch.qml" + "TabBar.qml" + "TabButton.qml" + "TextArea.qml" + "TextField.qml" + "ToolBar.qml" + "ToolButton.qml" + "ToolSeparator.qml" + "ToolTip.qml" + "Tumbler.qml" + "VerticalHeaderView.qml" +) +set_source_files_properties(DelayButton.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.2;6.0" +) +set_source_files_properties(Dialog.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(DialogButtonBox.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(HorizontalHeaderView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.15;6.0" +) +set_source_files_properties(MenuBar.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.3;6.0" +) +set_source_files_properties(MenuBarItem.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.3;6.0" +) +set_source_files_properties(MenuSeparator.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(RoundButton.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(SplitView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.13;6.0" +) +set_source_files_properties(ToolSeparator.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(VerticalHeaderView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.15;6.0" +) + +qt_internal_add_qml_module(qtquickcontrols2fusionstyleplugin + URI "QtQuick.Controls.Fusion" + VERSION "${PROJECT_VERSION}" + PAST_MAJOR_VERSIONS 2 + CLASS_NAME QtQuickControls2FusionStylePlugin + IMPORTS + QtQuick.Controls.Basic/auto + PLUGIN_TARGET qtquickcontrols2fusionstyleplugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + SOURCES + qquickfusionstyle.cpp qquickfusionstyle_p.h + qquickfusiontheme.cpp qquickfusiontheme_p.h + qtquickcontrols2fusionstyleplugin.cpp + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2Private + Qt::QuickPrivate + Qt::QuickTemplates2Private +) + +qt_internal_add_resource(qtquickcontrols2fusionstyleplugin "qtquickcontrols2fusionstyle" + PREFIX + "/qt-project.org/imports/QtQuick/Controls/Fusion" + FILES + "images/arrow.png" + "images/arrow@2x.png" + "images/arrow@3x.png" + "images/arrow@4x.png" + "images/checkmark.png" + "images/checkmark@2x.png" + "images/checkmark@3x.png" + "images/checkmark@4x.png" + "images/progressmask.png" + "images/progressmask@2x.png" + "images/progressmask@3x.png" + "images/progressmask@4x.png" +) + +add_subdirectory(impl) + +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2fusionstyleplugin quickwindow) +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2fusionstyleplugin + qtquickcontrols2fusionstyleimplplugin) + +# Basic style is the required fallback style. +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2fusionstyleplugin + qtquickcontrols2basicstyleplugin) diff --git a/src/quickcontrols2/fusion/CheckBox.qml b/src/quickcontrols2/fusion/CheckBox.qml new file mode 100644 index 00000000000..ed49a1447ed --- /dev/null +++ b/src/quickcontrols2/fusion/CheckBox.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.CheckBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + indicator: CheckIndicator { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.palette.windowText + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } +} diff --git a/src/quickcontrols2/fusion/CheckDelegate.qml b/src/quickcontrols2/fusion/CheckDelegate.qml new file mode 100644 index 00000000000..93c087e42c6 --- /dev/null +++ b/src/quickcontrols2/fusion/CheckDelegate.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.CheckDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + leftPadding: control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: !control.mirrored ? control.indicator.width + control.spacing : 0 + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + indicator: CheckIndicator { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + control: control + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 20 + color: control.down ? Fusion.buttonColor(control.palette, false, true, true) + : control.highlighted ? Fusion.highlight(control.palette) : control.palette.base + } +} diff --git a/src/quickcontrols2/fusion/ComboBox.qml b/src/quickcontrols2/fusion/ComboBox.qml new file mode 100644 index 00000000000..dfe21f708fc --- /dev/null +++ b/src/quickcontrols2/fusion/ComboBox.qml @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ComboBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + + delegate: MenuItem { + width: ListView.view.width + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData + font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal + highlighted: control.highlightedIndex === index + hoverEnabled: control.hoverEnabled + } + + indicator: ColorImage { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + color: control.editable ? control.palette.text : control.palette.buttonText + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/arrow.png" + width: 20 + fillMode: Image.Pad + } + + contentItem: T.TextField { + topPadding: 4 + leftPadding: 4 - control.padding + rightPadding: 4 - control.padding + bottomPadding: 4 + + text: control.editable ? control.editText : control.displayText + + enabled: control.editable + autoScroll: control.editable + readOnly: control.down + inputMethodHints: control.inputMethodHints + validator: control.validator + selectByMouse: control.selectTextByMouse + + font: control.font + color: control.editable ? control.palette.text : control.palette.buttonText + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + verticalAlignment: Text.AlignVCenter + + background: PaddedRectangle { + clip: true + radius: 2 + padding: 1 + leftPadding: control.mirrored ? -2 : padding + rightPadding: !control.mirrored ? -2 : padding + color: control.palette.base + visible: control.editable && !control.flat + + Rectangle { + x: parent.width - width + y: 1 + width: 1 + height: parent.height - 2 + color: Fusion.buttonOutline(control.palette, control.activeFocus, control.enabled) + } + + Rectangle { + x: 1 + y: 1 + width: parent.width - 3 + height: 1 + color: Fusion.topShadow + } + } + + Rectangle { + x: 1 - control.leftPadding + y: 1 + width: control.width - 2 + height: control.height - 2 + color: "transparent" + border.color: Color.transparent(Fusion.highlightedOutline(control.palette), 40 / 255) + visible: control.activeFocus + radius: 1.7 + } + } + + background: ButtonPanel { + implicitWidth: 120 + implicitHeight: 24 + + control: control + visible: !control.flat || control.down + // ### TODO: fix control.contentItem.activeFocus + highlighted: control.visualFocus || control.contentItem.activeFocus + } + + popup: T.Popup { + width: control.width + height: Math.min(contentItem.implicitHeight + 2, control.Window.height - topMargin - bottomMargin) + topMargin: 6 + bottomMargin: 6 + padding: 1 + + contentItem: ListView { + clip: true + implicitHeight: contentHeight + model: control.delegateModel + currentIndex: control.highlightedIndex + highlightRangeMode: ListView.ApplyRange + highlightMoveDuration: 0 + + T.ScrollBar.vertical: ScrollBar { } + } + + background: Rectangle { + color: control.popup.palette.window + border.color: Fusion.outline(control.palette) + + Rectangle { + z: -1 + x: 1; y: 1 + width: parent.width + height: parent.height + color: control.palette.shadow + opacity: 0.2 + } + } + } +} diff --git a/src/quickcontrols2/fusion/DelayButton.qml b/src/quickcontrols2/fusion/DelayButton.qml new file mode 100644 index 00000000000..239ee6c8611 --- /dev/null +++ b/src/quickcontrols2/fusion/DelayButton.qml @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.DelayButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + + transition: Transition { + NumberAnimation { + duration: control.delay * (control.pressed ? 1.0 - control.progress : 0.3 * control.progress) + } + } + + contentItem: ItemGroup { + ClippedText { + clip: control.progress > 0 + clipX: -control.leftPadding + (control.mirrored ? 0 : control.progress * control.width) + clipWidth: control.width + visible: control.mirrored ? control.progress > 0 : control.progress < 1 + + text: control.text + font: control.font + color: control.mirrored ? control.palette.brightText : control.palette.buttonText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + ClippedText { + clip: control.progress > 0 + clipX: -control.leftPadding + clipWidth: (control.mirrored ? 1.0 - control.progress : control.progress) * control.width + visible: control.mirrored ? control.progress < 1 : control.progress > 0 + + text: control.text + font: control.font + color: control.mirrored ? control.palette.buttonText : control.palette.brightText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + } + + background: ButtonPanel { + implicitWidth: 80 + implicitHeight: 24 + + control: control + highlighted: false + scale: control.mirrored ? -1 : 1 + + Rectangle { + width: control.progress * parent.width + height: parent.height + + radius: 2 + border.color: Qt.darker(Fusion.highlight(control.palette), 1.4) + gradient: Gradient { + GradientStop { + position: 0 + color: Qt.lighter(Fusion.highlight(control.palette), 1.2) + } + GradientStop { + position: 1 + color: Fusion.highlight(control.palette) + } + } + } + } +} diff --git a/src/quickcontrols2/fusion/Dial.qml b/src/quickcontrols2/fusion/Dial.qml new file mode 100644 index 00000000000..71bab3a7882 --- /dev/null +++ b/src/quickcontrols2/fusion/Dial.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Dial { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + background: DialImpl { + implicitWidth: 100 + implicitHeight: 100 + highlight: control.visualFocus + } + + handle: KnobImpl { + x: control.background.x + control.background.width / 2 - width / 2 + y: control.background.y + control.background.height / 2 - height / 2 + width: control.width / 7 + height: control.height / 7 + transform: [ + Translate { + y: -Math.min(control.background.width, control.background.height) * 0.42 + control.handle.height + }, + Rotation { + angle: control.angle + origin.x: control.handle.width / 2 + origin.y: control.handle.height / 2 + } + ] + } +} diff --git a/src/quickcontrols2/fusion/Dialog.qml b/src/quickcontrols2/fusion/Dialog.qml new file mode 100644 index 00000000000..af7fa4925b6 --- /dev/null +++ b/src/quickcontrols2/fusion/Dialog.qml @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Dialog { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + padding: 6 + + background: Rectangle { + color: control.palette.window + border.color: control.palette.mid + radius: 2 + + Rectangle { + z: -1 + x: 1; y: 1 + width: parent.width + height: parent.height + color: control.palette.shadow + opacity: 0.2 + radius: 2 + } + } + + header: Label { + text: control.title + visible: control.title + elide: Label.ElideRight + font.bold: true + padding: 6 + background: Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 1 + color: control.palette.window + radius: 2 + } + } + + footer: DialogButtonBox { + visible: count > 0 + } + + T.Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + T.Overlay.modeless: Rectangle { + color: Fusion.topShadow + } +} diff --git a/src/quickcontrols2/fusion/DialogButtonBox.qml b/src/quickcontrols2/fusion/DialogButtonBox.qml new file mode 100644 index 00000000000..a99f142ff53 --- /dev/null +++ b/src/quickcontrols2/fusion/DialogButtonBox.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.DialogButtonBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: 6 + padding: 6 + alignment: Qt.AlignRight + + delegate: Button { } + + contentItem: ListView { + implicitWidth: contentWidth + model: control.contentModel + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + } + + background: Rectangle { + implicitHeight: 32 + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + color: control.palette.window + radius: 2 + } +} diff --git a/src/quickcontrols2/fusion/Drawer.qml b/src/quickcontrols2/fusion/Drawer.qml new file mode 100644 index 00000000000..85268b5027a --- /dev/null +++ b/src/quickcontrols2/fusion/Drawer.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Drawer { + id: control + + parent: T.Overlay.overlay + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: control.edge === Qt.BottomEdge + leftPadding: control.edge === Qt.RightEdge + rightPadding: control.edge === Qt.LeftEdge + bottomPadding: control.edge === Qt.TopEdge + + enter: Transition { SmoothedAnimation { velocity: 5 } } + exit: Transition { SmoothedAnimation { velocity: 5 } } + + background: Rectangle { + color: control.palette.window + readonly property bool horizontal: control.edge === Qt.LeftEdge || control.edge === Qt.RightEdge + Rectangle { + width: parent.horizontal ? 1 : parent.width + height: parent.horizontal ? parent.height : 1 + color: control.palette.mid + x: control.edge === Qt.LeftEdge ? parent.width - 1 : 0 + y: control.edge === Qt.TopEdge ? parent.height - 1 : 0 + } + Rectangle { + width: parent.horizontal ? 1 : parent.width + height: parent.horizontal ? parent.height : 1 + color: control.palette.shadow + opacity: 0.2 + x: control.edge === Qt.LeftEdge ? parent.width : 0 + y: control.edge === Qt.TopEdge ? parent.height : 0 + } + } + + T.Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + T.Overlay.modeless: Rectangle { + color: Fusion.topShadow + } +} diff --git a/src/quickcontrols2/fusion/Frame.qml b/src/quickcontrols2/fusion/Frame.qml new file mode 100644 index 00000000000..1e1916f1234 --- /dev/null +++ b/src/quickcontrols2/fusion/Frame.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Frame { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 9 + + background: Rectangle { + color: "transparent" + border.color: Qt.lighter(Fusion.outline(control.palette), 1.08) + } +} diff --git a/src/quickcontrols2/fusion/GroupBox.qml b/src/quickcontrols2/fusion/GroupBox.qml new file mode 100644 index 00000000000..943a242709b --- /dev/null +++ b/src/quickcontrols2/fusion/GroupBox.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.GroupBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitLabelWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: 6 + padding: 9 + topPadding: padding + (implicitLabelWidth > 0 ? implicitLabelHeight + spacing : 0) + + label: Text { + x: control.leftPadding + width: control.availableWidth + + text: control.title + font: control.font + color: control.palette.windowText + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + background: Rectangle { + y: control.topPadding - control.bottomPadding + width: parent.width + height: parent.height - control.topPadding + control.bottomPadding + + radius: 2 + color: Color.transparent("black", 3 / 255) + border.color: Qt.lighter(Fusion.outline(control.palette), 1.08) + } +} diff --git a/src/quickcontrols2/fusion/HorizontalHeaderView.qml b/src/quickcontrols2/fusion/HorizontalHeaderView.qml new file mode 100644 index 00000000000..76f42b29858 --- /dev/null +++ b/src/quickcontrols2/fusion/HorizontalHeaderView.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.HorizontalHeaderView { + id: control + + implicitWidth: syncView ? syncView.width : 0 + implicitHeight: contentHeight + + delegate: Rectangle { + // Qt6: add cellPadding (and font etc) as public API in headerview + readonly property real cellPadding: 8 + + implicitWidth: text.implicitWidth + (cellPadding * 2) + implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2)) + border.color: "#cacaca" + + gradient: Gradient { + GradientStop { + position: 0 + color: "#fbfbfb" + } + GradientStop { + position: 1 + color: "#e0dfe0" + } + } + + Text { + id: text + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] + : model[control.textRole]) + : modelData + width: parent.width + height: parent.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: "#ff26282a" + } + } +} diff --git a/src/quickcontrols2/fusion/ItemDelegate.qml b/src/quickcontrols2/fusion/ItemDelegate.qml new file mode 100644 index 00000000000..12154d2f4b6 --- /dev/null +++ b/src/quickcontrols2/fusion/ItemDelegate.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ItemDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 20 + color: control.down ? Fusion.buttonColor(control.palette, false, true, true) + : control.highlighted ? Fusion.highlight(control.palette) : control.palette.base + } +} diff --git a/src/quickcontrols2/fusion/Label.qml b/src/quickcontrols2/fusion/Label.qml new file mode 100644 index 00000000000..55db94f9c55 --- /dev/null +++ b/src/quickcontrols2/fusion/Label.qml @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Label { + id: control + + color: control.palette.windowText + linkColor: control.palette.link +} diff --git a/src/quickcontrols2/fusion/Menu.qml b/src/quickcontrols2/fusion/Menu.qml new file mode 100644 index 00000000000..d56860d43e1 --- /dev/null +++ b/src/quickcontrols2/fusion/Menu.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl +import QtQuick.Window + +T.Menu { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + margins: 0 + padding: 1 + overlap: 2 + + delegate: MenuItem { } + + contentItem: ListView { + implicitHeight: contentHeight + model: control.contentModel + interactive: contentHeight + control.topPadding + control.bottomPadding > control.height + clip: true + currentIndex: control.currentIndex + + ScrollIndicator.vertical: ScrollIndicator {} + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 20 + + color: control.palette.base + border.color: Fusion.outline(control.palette) + + Rectangle { + z: -1 + x: 1; y: 1 + width: parent.width + height: parent.height + color: control.palette.shadow + opacity: 0.2 + } + } + + T.Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + T.Overlay.modeless: Rectangle { + color: Fusion.topShadow + } +} diff --git a/src/quickcontrols2/fusion/MenuBar.qml b/src/quickcontrols2/fusion/MenuBar.qml new file mode 100644 index 00000000000..7b6a628dddd --- /dev/null +++ b/src/quickcontrols2/fusion/MenuBar.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.MenuBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + delegate: MenuBarItem { } + + contentItem: Row { + spacing: control.spacing + Repeater { + model: control.contentModel + } + } + + background: Rectangle { + implicitHeight: 20 + + color: control.palette.window + + Rectangle { + y: parent.height - height + width: parent.width + height: 1 + color: Fusion.mergedColors(Qt.darker(control.palette.window, 1.2), + Qt.lighter(Fusion.outline(control.palette), 1.4), 60) + } + } +} diff --git a/src/quickcontrols2/fusion/MenuBarItem.qml b/src/quickcontrols2/fusion/MenuBarItem.qml new file mode 100644 index 00000000000..336fca0cd68 --- /dev/null +++ b/src/quickcontrols2/fusion/MenuBarItem.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.MenuBarItem { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.down || control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + background: Rectangle { + implicitWidth: 20 + implicitHeight: 20 + + color: Fusion.highlight(control.palette) + visible: control.down || control.highlighted + } +} diff --git a/src/quickcontrols2/fusion/MenuItem.qml b/src/quickcontrols2/fusion/MenuItem.qml new file mode 100644 index 00000000000..79468f9da86 --- /dev/null +++ b/src/quickcontrols2/fusion/MenuItem.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.MenuItem { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + readonly property real arrowPadding: control.subMenu && control.arrow ? control.arrow.width + control.spacing : 0 + readonly property real indicatorPadding: control.checkable && control.indicator ? control.indicator.width + control.spacing : 0 + leftPadding: !control.mirrored ? indicatorPadding : arrowPadding + rightPadding: control.mirrored ? indicatorPadding : arrowPadding + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.down || control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + arrow: ColorImage { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + width: 20 + + visible: control.subMenu + rotation: control.mirrored ? 90 : -90 + color: control.down || control.hovered || control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/arrow.png" + fillMode: Image.Pad + } + + indicator: CheckIndicator { + x: control.mirrored ? control.width - width - control.rightPadding : control.leftPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + control: control + visible: control.checkable + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 20 + + color: Fusion.highlight(control.palette) + visible: control.down || control.highlighted + } +} diff --git a/src/quickcontrols2/fusion/MenuSeparator.qml b/src/quickcontrols2/fusion/MenuSeparator.qml new file mode 100644 index 00000000000..b8be640b64c --- /dev/null +++ b/src/quickcontrols2/fusion/MenuSeparator.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.MenuSeparator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 5 + verticalPadding: 1 + + contentItem: Rectangle { + implicitWidth: 188 + implicitHeight: 1 + color: Qt.lighter(Fusion.darkShade, 1.06) + } +} diff --git a/src/quickcontrols2/fusion/Page.qml b/src/quickcontrols2/fusion/Page.qml new file mode 100644 index 00000000000..bf47e23155d --- /dev/null +++ b/src/quickcontrols2/fusion/Page.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Page { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + background: Rectangle { + color: control.palette.window + } +} diff --git a/src/quickcontrols2/fusion/PageIndicator.qml b/src/quickcontrols2/fusion/PageIndicator.qml new file mode 100644 index 00000000000..0c556cc2ac5 --- /dev/null +++ b/src/quickcontrols2/fusion/PageIndicator.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.PageIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 4 + spacing: 4 + + delegate: Rectangle { + implicitWidth: 6 + implicitHeight: 6 + + radius: width / 2 + color: control.palette.shadow + + opacity: index === currentIndex ? 0.95 : pressed ? 0.75 : 0.45 + + required property int index + + Behavior on opacity { OpacityAnimator { duration: 100 } } + } + + contentItem: Row { + spacing: control.spacing + + Repeater { + model: control.count + delegate: control.delegate + } + } +} diff --git a/src/quickcontrols2/fusion/Pane.qml b/src/quickcontrols2/fusion/Pane.qml new file mode 100644 index 00000000000..9cc4991788e --- /dev/null +++ b/src/quickcontrols2/fusion/Pane.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Pane { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 9 + + background: Rectangle { + color: control.palette.window + } +} diff --git a/src/quickcontrols2/fusion/Popup.qml b/src/quickcontrols2/fusion/Popup.qml new file mode 100644 index 00000000000..f77ea1d196f --- /dev/null +++ b/src/quickcontrols2/fusion/Popup.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Popup { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 6 + + background: Rectangle { + color: control.palette.window + border.color: control.palette.mid + radius: 2 + } + + T.Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + T.Overlay.modeless: Rectangle { + color: Fusion.topShadow + } +} diff --git a/src/quickcontrols2/fusion/ProgressBar.qml b/src/quickcontrols2/fusion/ProgressBar.qml new file mode 100644 index 00000000000..0ad6b4834a2 --- /dev/null +++ b/src/quickcontrols2/fusion/ProgressBar.qml @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ProgressBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + contentItem: Item { + implicitWidth: 120 + implicitHeight: 24 + scale: control.mirrored ? -1 : 1 + + Rectangle { + height: parent.height + width: (control.indeterminate ? 1.0 : control.position) * parent.width + + radius: 2 + border.color: Qt.darker(Fusion.highlight(control.palette), 1.4) + gradient: Gradient { + GradientStop { + position: 0 + color: Qt.lighter(Fusion.highlight(control.palette), 1.2) + } + GradientStop { + position: 1 + color: Fusion.highlight(control.palette) + } + } + } + + Item { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + visible: control.indeterminate + clip: true + + ColorImage { + width: Math.ceil(parent.width / implicitWidth + 1) * implicitWidth + height: parent.height + + mirror: control.mirrored + fillMode: Image.TileHorizontally + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/progressmask.png" + color: Color.transparent(Qt.lighter(Fusion.highlight(control.palette), 1.2), 160 / 255) + + visible: control.indeterminate + NumberAnimation on x { + running: control.indeterminate && control.visible + from: -31 // progressmask.png width + to: 0 + loops: Animation.Infinite + duration: 750 + } + } + } + } + + background: Rectangle { + implicitWidth: 120 + implicitHeight: 24 + + radius: 2 + color: control.palette.base + border.color: Fusion.outline(control.palette) + + Rectangle { + x: 1; y: 1; height: 1 + width: parent.width - 2 + color: Fusion.topShadow + } + } +} diff --git a/src/quickcontrols2/fusion/RadioButton.qml b/src/quickcontrols2/fusion/RadioButton.qml new file mode 100644 index 00000000000..c7796411b39 --- /dev/null +++ b/src/quickcontrols2/fusion/RadioButton.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.RadioButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + indicator: RadioIndicator { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.palette.windowText + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } +} diff --git a/src/quickcontrols2/fusion/RadioDelegate.qml b/src/quickcontrols2/fusion/RadioDelegate.qml new file mode 100644 index 00000000000..4c0d936c00b --- /dev/null +++ b/src/quickcontrols2/fusion/RadioDelegate.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.RadioDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + leftPadding: control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: !control.mirrored ? control.indicator.width + control.spacing : 0 + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + indicator: RadioIndicator { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + control: control + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 20 + color: control.down ? Fusion.buttonColor(control.palette, false, true, true) + : control.highlighted ? Fusion.highlight(control.palette) : control.palette.base + } +} diff --git a/src/quickcontrols2/fusion/RangeSlider.qml b/src/quickcontrols2/fusion/RangeSlider.qml new file mode 100644 index 00000000000..418bac77d16 --- /dev/null +++ b/src/quickcontrols2/fusion/RangeSlider.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.RangeSlider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + Math.max(first.implicitHandleWidth, + second.implicitHandleWidth) + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + Math.max(first.implicitHandleHeight, + second.implicitHandleHeight) + topPadding + bottomPadding) + + first.handle: SliderHandle { + x: control.leftPadding + Math.round(control.horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + Math.round(control.horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height)) + + palette: control.palette + pressed: control.first.pressed + hovered: control.first.hovered + vertical: control.vertical + visualFocus: activeFocus + } + + second.handle: SliderHandle { + x: control.leftPadding + Math.round(control.horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + Math.round(control.horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height)) + + palette: control.palette + pressed: control.second.pressed + hovered: control.second.hovered + vertical: control.vertical + visualFocus: activeFocus + } + + background: SliderGroove { + control: control + offset: control.first.position + progress: control.second.position + visualProgress: control.second.visualPosition + } +} diff --git a/src/quickcontrols2/fusion/RoundButton.qml b/src/quickcontrols2/fusion/RoundButton.qml new file mode 100644 index 00000000000..3fa54367cf0 --- /dev/null +++ b/src/quickcontrols2/fusion/RoundButton.qml @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.RoundButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.palette.buttonText + } + + background: Rectangle { + implicitWidth: 32 + implicitHeight: 32 + visible: !control.flat || control.down || control.checked + + gradient: Gradient { + GradientStop { + position: 0 + color: control.down || control.checked + ? Fusion.buttonColor(control.palette, control.highlighted, control.down || control.checked, control.enabled && control.hovered) + : Fusion.gradientStart(Fusion.buttonColor(control.palette, control.highlighted, control.down, control.enabled && control.hovered)) + } + GradientStop { + position: 1 + color: control.down || control.checked + ? Fusion.buttonColor(control.palette, control.highlighted, control.down || control.checked, control.enabled && control.hovered) + : Fusion.gradientStop(Fusion.buttonColor(control.palette, control.highlighted, control.down, control.enabled && control.hovered)) + } + } + + radius: control.radius + border.color: Fusion.buttonOutline(control.palette, control.highlighted || control.visualFocus, control.enabled) + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + border.color: Fusion.innerContrastLine + color: "transparent" + radius: control.radius + } + } +} diff --git a/src/quickcontrols2/fusion/ScrollBar.qml b/src/quickcontrols2/fusion/ScrollBar.qml new file mode 100644 index 00000000000..5221e0dffff --- /dev/null +++ b/src/quickcontrols2/fusion/ScrollBar.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ScrollBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 2 + visible: control.policy !== T.ScrollBar.AlwaysOff + minimumSize: orientation === Qt.Horizontal ? height / width : width / height + + contentItem: Rectangle { + implicitWidth: control.interactive ? 6 : 2 + implicitHeight: control.interactive ? 6 : 2 + + radius: width / 2 + color: control.pressed ? control.palette.dark : control.palette.mid + opacity: 0.0 + + states: State { + name: "active" + when: control.policy === T.ScrollBar.AlwaysOn || (control.active && control.size < 1.0) + PropertyChanges { target: control.contentItem; opacity: 0.75 } + } + + transitions: Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 450 } + NumberAnimation { target: control.contentItem; duration: 200; property: "opacity"; to: 0.0 } + } + } + } +} diff --git a/src/quickcontrols2/fusion/ScrollIndicator.qml b/src/quickcontrols2/fusion/ScrollIndicator.qml new file mode 100644 index 00000000000..bf386f6c32d --- /dev/null +++ b/src/quickcontrols2/fusion/ScrollIndicator.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ScrollIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 2 + + contentItem: Rectangle { + implicitWidth: 2 + implicitHeight: 2 + + color: control.palette.mid + visible: control.size < 1.0 + opacity: 0.0 + + states: State { + name: "active" + when: control.active + PropertyChanges { target: control.contentItem; opacity: 0.75 } + } + + transitions: [ + Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 450 } + NumberAnimation { target: control.contentItem; duration: 200; property: "opacity"; to: 0.0 } + } + } + ] + } +} diff --git a/src/quickcontrols2/fusion/ScrollView.qml b/src/quickcontrols2/fusion/ScrollView.qml new file mode 100644 index 00000000000..a6bba9de05a --- /dev/null +++ b/src/quickcontrols2/fusion/ScrollView.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ScrollView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + ScrollBar.vertical: ScrollBar { + parent: control + x: control.mirrored ? 0 : control.width - width + y: control.topPadding + height: control.availableHeight + active: control.ScrollBar.horizontal.active + } + + ScrollBar.horizontal: ScrollBar { + parent: control + x: control.leftPadding + y: control.height - height + width: control.availableWidth + active: control.ScrollBar.vertical.active + } +} diff --git a/src/quickcontrols2/fusion/SelectionRectangle.qml b/src/quickcontrols2/fusion/SelectionRectangle.qml new file mode 100644 index 00000000000..2e6393a07e5 --- /dev/null +++ b/src/quickcontrols2/fusion/SelectionRectangle.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.SelectionRectangle { + id: control + + topLeftHandle: Item { + width: 20 + height: 20 + visible: SelectionRectangle.control.active + // This item is deliberately empty. Selection handles don't feel at home + // for this style. But we provide an invisible handle that the user can + // drag on. + } + + bottomRightHandle: Item { + width: 20 + height: 20 + visible: SelectionRectangle.control.active + // This item is deliberately empty. Selection handles don't feel at home + // for this style. But we provide an invisible handle that the user can + // drag on. + } +} diff --git a/src/quickcontrols2/fusion/Slider.qml b/src/quickcontrols2/fusion/Slider.qml new file mode 100644 index 00000000000..4e20dcfc598 --- /dev/null +++ b/src/quickcontrols2/fusion/Slider.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Slider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitHandleWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitHandleHeight + topPadding + bottomPadding) + + handle: SliderHandle { + x: control.leftPadding + Math.round(control.horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + Math.round(control.horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) + + palette: control.palette + pressed: control.pressed + hovered: control.hovered + vertical: control.vertical + visualFocus: control.visualFocus + } + + background: SliderGroove { + control: control + progress: control.position + visualProgress: control.visualPosition + } +} diff --git a/src/quickcontrols2/fusion/SpinBox.qml b/src/quickcontrols2/fusion/SpinBox.qml new file mode 100644 index 00000000000..4ed18f39d6a --- /dev/null +++ b/src/quickcontrols2/fusion/SpinBox.qml @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.SpinBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentItem.implicitWidth + 2 * padding + + Math.max(up.implicitIndicatorWidth, + down.implicitIndicatorWidth)) + implicitHeight: Math.max(implicitContentHeight + topPadding + bottomPadding, + implicitBackgroundHeight, + up.implicitIndicatorHeight + + down.implicitIndicatorHeight) + + padding: 4 + leftPadding: padding + (control.mirrored ? (up.indicator ? up.indicator.width : 0) : (down.indicator ? down.indicator.width : 0)) + rightPadding: padding + (control.mirrored ? (down.indicator ? down.indicator.width : 0) : (up.indicator ? up.indicator.width : 0)) + + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + + contentItem: TextInput { + z: 2 + text: control.displayText + + font: control.font + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + + readOnly: !control.editable + validator: control.validator + inputMethodHints: control.inputMethodHints + } + + up.indicator: PaddedRectangle { + x: control.mirrored ? 1 : control.width - width - 1 + y: 1 + height: control.height / 2 - 1 + implicitWidth: 16 + implicitHeight: 10 + + radius: 1.7 + clip: true + topPadding: -2 + leftPadding: -2 + color: control.up.pressed ? Fusion.buttonColor(control.palette, false, true, true) : "transparent" + + ColorImage { + scale: -1 + width: parent.width + height: parent.height + opacity: enabled ? 1.0 : 0.5 + color: control.palette.buttonText + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/arrow.png" + fillMode: Image.Pad + } + } + + down.indicator: PaddedRectangle { + x: control.mirrored ? 1 : control.width - width - 1 + y: control.height - height - 1 + height: control.height / 2 - 1 + implicitWidth: 16 + implicitHeight: 10 + + radius: 1.7 + clip: true + topPadding: -2 + leftPadding: -2 + color: control.down.pressed ? Fusion.buttonColor(control.palette, false, true, true) : "transparent" + + ColorImage { + width: parent.width + height: parent.height + opacity: enabled ? 1.0 : 0.5 + color: control.palette.buttonText + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/arrow.png" + fillMode: Image.Pad + } + } + + background: Rectangle { + implicitWidth: 120 + implicitHeight: 24 + + radius: 2 + color: control.palette.base + border.color: control.activeFocus ? Fusion.highlightedOutline(control.palette) : Fusion.outline(control.palette) + + Rectangle { + x: 2 + y: 1 + width: parent.width - 4 + height: 1 + color: Fusion.topShadow + } + + Rectangle { + x: control.mirrored ? 1 : parent.width - width - 1 + y: 1 + width: Math.max(control.up.indicator ? control.up.indicator.width : 0, + control.down.indicator ? control.down.indicator.width : 0) + 1 + height: parent.height - 2 + + radius: 2 + gradient: Gradient { + GradientStop { + position: 0 + color: Fusion.gradientStart(Fusion.buttonColor(control.palette, control.visualFocus, false, control.up.hovered || control.down.hovered)) + } + GradientStop { + position: 1 + color: Fusion.gradientStop(Fusion.buttonColor(control.palette, control.visualFocus, false, control.up.hovered || control.down.hovered)) + } + } + + Rectangle { + x: control.mirrored ? parent.width - 1 : 0 + height: parent.height + width: 1 + color: Fusion.outline(control.palette) + } + } + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + color: "transparent" + border.color: Color.transparent(Fusion.highlightedOutline(control.palette), 40 / 255) + visible: control.activeFocus + radius: 1.7 + } + } +} diff --git a/src/quickcontrols2/fusion/SplitView.qml b/src/quickcontrols2/fusion/SplitView.qml new file mode 100644 index 00000000000..9698b82133b --- /dev/null +++ b/src/quickcontrols2/fusion/SplitView.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion + +T.SplitView { + id: control + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + handle: Rectangle { + implicitWidth: control.orientation === Qt.Horizontal ? 2 : control.width + implicitHeight: control.orientation === Qt.Horizontal ? control.height : 2 + color: T.SplitHandle.pressed ? control.palette.dark + : (enabled && T.SplitHandle.hovered ? control.palette.midlight : control.palette.mid) + } +} diff --git a/src/quickcontrols2/fusion/SwipeDelegate.qml b/src/quickcontrols2/fusion/SwipeDelegate.qml new file mode 100644 index 00000000000..ac840f64e8b --- /dev/null +++ b/src/quickcontrols2/fusion/SwipeDelegate.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.SwipeDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + swipe.transition: Transition { SmoothedAnimation { velocity: 3; easing.type: Easing.InOutCubic } } + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 20 + color: control.down ? Fusion.buttonColor(control.palette, false, true, true) + : control.highlighted ? Fusion.highlight(control.palette) : control.palette.base + } +} diff --git a/src/quickcontrols2/fusion/Switch.qml b/src/quickcontrols2/fusion/Switch.qml new file mode 100644 index 00000000000..2e31535b3dd --- /dev/null +++ b/src/quickcontrols2/fusion/Switch.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Switch { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + indicator: SwitchIndicator { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.palette.text + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } +} diff --git a/src/quickcontrols2/fusion/SwitchDelegate.qml b/src/quickcontrols2/fusion/SwitchDelegate.qml new file mode 100644 index 00000000000..0439b0cfa58 --- /dev/null +++ b/src/quickcontrols2/fusion/SwitchDelegate.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.SwitchDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + indicator: SwitchIndicator { + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: IconLabel { + leftPadding: control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: !control.mirrored ? control.indicator.width + control.spacing : 0 + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 20 + color: control.down ? Fusion.buttonColor(control.palette, false, true, true) + : control.highlighted ? Fusion.highlight(control.palette) : control.palette.base + } +} diff --git a/src/quickcontrols2/fusion/TabBar.qml b/src/quickcontrols2/fusion/TabBar.qml new file mode 100644 index 00000000000..e0933653470 --- /dev/null +++ b/src/quickcontrols2/fusion/TabBar.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.TabBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: -1 + + contentItem: ListView { + model: control.contentModel + currentIndex: control.currentIndex + + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + flickableDirection: Flickable.AutoFlickIfNeeded + snapMode: ListView.SnapToItem + + highlightMoveDuration: 0 + highlightRangeMode: ListView.ApplyRange + preferredHighlightBegin: 40 + preferredHighlightEnd: width - 40 + } + + background: Item { + implicitHeight: 21 + + Rectangle { + width: parent.width + height: 1 + y: control.position === T.TabBar.Header ? parent.height - 1 : 0 + color: Fusion.outline(control.palette) + } + } +} diff --git a/src/quickcontrols2/fusion/TabButton.qml b/src/quickcontrols2/fusion/TabButton.qml new file mode 100644 index 00000000000..161a7b02574 --- /dev/null +++ b/src/quickcontrols2/fusion/TabButton.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.TabButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 2 + horizontalPadding: 4 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + z: checked + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.palette.buttonText + } + + background: Rectangle { + y: control.checked || control.TabBar.position !== T.TabBar.Header ? 0 : 2 + implicitHeight: 21 + height: control.height - (control.checked ? 0 : 2) + + border.color: Qt.lighter(Fusion.outline(control.palette), 1.1) + + gradient: Gradient { + GradientStop { + position: 0 + color: control.checked ? Qt.lighter(Fusion.tabFrameColor(control.palette), 1.04) + : Qt.darker(Fusion.tabFrameColor(control.palette), 1.08) + } + GradientStop { + position: control.checked ? 0 : 0.85 + color: control.checked ? Qt.lighter(Fusion.tabFrameColor(control.palette), 1.04) + : Qt.darker(Fusion.tabFrameColor(control.palette), 1.08) + } + GradientStop { + position: 1 + color: control.checked ? Fusion.tabFrameColor(control.palette) + : Qt.darker(Fusion.tabFrameColor(control.palette), 1.16) + } + } + } +} diff --git a/src/quickcontrols2/fusion/TextArea.qml b/src/quickcontrols2/fusion/TextArea.qml new file mode 100644 index 00000000000..5346aad1048 --- /dev/null +++ b/src/quickcontrols2/fusion/TextArea.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.TextArea { + id: control + + implicitWidth: Math.max(contentWidth + leftPadding + rightPadding, + implicitBackgroundWidth + leftInset + rightInset, + placeholder.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(contentHeight + topPadding + bottomPadding, + implicitBackgroundHeight + topInset + bottomInset, + placeholder.implicitHeight + topPadding + bottomPadding) + + padding: 6 + leftPadding: padding + 4 + + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + placeholderTextColor: control.palette.placeholderText + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + verticalAlignment: control.verticalAlignment + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + elide: Text.ElideRight + renderType: control.renderType + } +} diff --git a/src/quickcontrols2/fusion/TextField.qml b/src/quickcontrols2/fusion/TextField.qml new file mode 100644 index 00000000000..d99c3664f2b --- /dev/null +++ b/src/quickcontrols2/fusion/TextField.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.TextField { + id: control + + implicitWidth: implicitBackgroundWidth + leftInset + rightInset + || Math.max(contentWidth, placeholder.implicitWidth) + leftPadding + rightPadding + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding, + placeholder.implicitHeight + topPadding + bottomPadding) + + padding: 4 + + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + placeholderTextColor: control.palette.placeholderText + verticalAlignment: TextInput.AlignVCenter + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + verticalAlignment: control.verticalAlignment + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + elide: Text.ElideRight + renderType: control.renderType + } + + background: Rectangle { + implicitWidth: 120 + implicitHeight: 24 + + radius: 2 + color: control.palette.base + border.color: control.activeFocus ? Fusion.highlightedOutline(control.palette) : Fusion.outline(control.palette) + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + color: "transparent" + border.color: Color.transparent(Fusion.highlightedOutline(control.palette), 40 / 255) + visible: control.activeFocus + radius: 1.7 + } + + Rectangle { + x: 2 + y: 1 + width: parent.width - 4 + height: 1 + color: Fusion.topShadow + } + } +} diff --git a/src/quickcontrols2/fusion/ToolBar.qml b/src/quickcontrols2/fusion/ToolBar.qml new file mode 100644 index 00000000000..747a292dc82 --- /dev/null +++ b/src/quickcontrols2/fusion/ToolBar.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ToolBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + horizontalPadding: 6 + topPadding: control.position === T.ToolBar.Footer ? 1 : 0 + bottomPadding: control.position === T.ToolBar.Header ? 1 : 0 + + background: Rectangle { + implicitHeight: 26 + + gradient: Gradient { + GradientStop { + position: 0 + color: Qt.lighter(control.palette.window, 1.04) + } + GradientStop { + position: 1 + color: control.palette.window + } + } + + Rectangle { + width: parent.width + height: 1 + color: control.position === T.ToolBar.Header ? Fusion.lightShade : Fusion.darkShade + } + + Rectangle { + y: parent.height - height + width: parent.width + height: 1 + color: control.position === T.ToolBar.Header ? Fusion.darkShade : Fusion.lightShade + } + } +} diff --git a/src/quickcontrols2/fusion/ToolButton.qml b/src/quickcontrols2/fusion/ToolButton.qml new file mode 100644 index 00000000000..8b25fbe8618 --- /dev/null +++ b/src/quickcontrols2/fusion/ToolButton.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ToolButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.palette.buttonText + } + + background: ButtonPanel { + implicitWidth: 20 + implicitHeight: 20 + + control: control + visible: control.down || control.checked || control.highlighted || control.visualFocus + || (enabled && control.hovered) + } +} diff --git a/src/quickcontrols2/fusion/ToolSeparator.qml b/src/quickcontrols2/fusion/ToolSeparator.qml new file mode 100644 index 00000000000..a325af6d48d --- /dev/null +++ b/src/quickcontrols2/fusion/ToolSeparator.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ToolSeparator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: vertical ? 6 : 2 + verticalPadding: vertical ? 2 : 6 + + contentItem: Rectangle { + implicitWidth: control.vertical ? 2 : 8 + implicitHeight: control.vertical ? 8 : 2 + color: Qt.darker(control.palette.window, 1.1) + + Rectangle { + x: 1 + width: 1 + height: parent.height + color: Qt.lighter(control.palette.window, 1.1) + } + } +} diff --git a/src/quickcontrols2/fusion/ToolTip.qml b/src/quickcontrols2/fusion/ToolTip.qml new file mode 100644 index 00000000000..90e0c268a14 --- /dev/null +++ b/src/quickcontrols2/fusion/ToolTip.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ToolTip { + id: control + + x: parent ? (parent.width - implicitWidth) / 2 : 0 + y: -implicitHeight - 3 + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + margins: 6 + padding: 6 + + closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnReleaseOutsideParent + + contentItem: Text { + text: control.text + font: control.font + wrapMode: Text.Wrap + color: control.palette.toolTipText + } + + background: Rectangle { + color: control.palette.toolTipBase + border.color: control.palette.toolTipText + + Rectangle { + z: -1 + x: 1; y: 1 + width: parent.width + height: parent.height + color: control.palette.shadow + opacity: 0.5 + } + } +} diff --git a/src/quickcontrols2/fusion/Tumbler.qml b/src/quickcontrols2/fusion/Tumbler.qml new file mode 100644 index 00000000000..77ab18fe705 --- /dev/null +++ b/src/quickcontrols2/fusion/Tumbler.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Tumbler { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + delegate: Text { + text: modelData + color: control.palette.windowText + font: control.font + opacity: (1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2)) * (control.enabled ? 1 : 0.6) + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + required property var modelData + required property int index + } + + contentItem: TumblerView { + implicitWidth: 60 + implicitHeight: 200 + model: control.model + delegate: control.delegate + path: Path { + startX: control.contentItem.width / 2 + startY: -control.contentItem.delegateHeight / 2 + PathLine { + x: control.contentItem.width / 2 + y: (control.visibleItemCount + 1) * control.contentItem.delegateHeight - control.contentItem.delegateHeight / 2 + } + } + + property real delegateHeight: control.availableHeight / control.visibleItemCount + } +} diff --git a/src/quickcontrols2/fusion/VerticalHeaderView.qml b/src/quickcontrols2/fusion/VerticalHeaderView.qml new file mode 100644 index 00000000000..3da51290043 --- /dev/null +++ b/src/quickcontrols2/fusion/VerticalHeaderView.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.VerticalHeaderView { + id: control + + implicitWidth: contentWidth + implicitHeight: syncView ? syncView.height : 0 + + delegate: Rectangle { + // Qt6: add cellPadding (and font etc) as public API in headerview + readonly property real cellPadding: 8 + + implicitWidth: Math.max(control.width, text.implicitWidth + (cellPadding * 2)) + implicitHeight: text.implicitHeight + (cellPadding * 2) + border.color: "#cacaca" + + gradient: Gradient { + GradientStop { + position: 0 + color: "#fbfbfb" + } + GradientStop { + position: 1 + color: "#e0dfe0" + } + } + + Text { + id: text + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] + : model[control.textRole]) + : modelData + width: parent.width + height: parent.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: "#ff26282a" + } + } +} diff --git a/src/quickcontrols2/fusion/fusion.pri b/src/quickcontrols2/fusion/fusion.pri new file mode 100644 index 00000000000..135675e2b59 --- /dev/null +++ b/src/quickcontrols2/fusion/fusion.pri @@ -0,0 +1,59 @@ +HEADERS += \ + $$PWD/qquickfusionstyle_p.h \ + $$PWD/qquickfusiontheme_p.h + +SOURCES += \ + $$PWD/qquickfusionstyle.cpp \ + $$PWD/qquickfusiontheme.cpp + +QML_FILES += \ + $$PWD/ApplicationWindow.qml \ + $$PWD/BusyIndicator.qml \ + $$PWD/Button.qml \ + $$PWD/CheckBox.qml \ + $$PWD/CheckDelegate.qml \ + $$PWD/ComboBox.qml \ + $$PWD/DelayButton.qml \ + $$PWD/Dial.qml \ + $$PWD/Dialog.qml \ + $$PWD/DialogButtonBox.qml \ + $$PWD/Drawer.qml \ + $$PWD/Frame.qml \ + $$PWD/GroupBox.qml \ + $$PWD/HorizontalHeaderView.qml \ + $$PWD/ItemDelegate.qml \ + $$PWD/Label.qml \ + $$PWD/Menu.qml \ + $$PWD/MenuBar.qml \ + $$PWD/MenuBarItem.qml \ + $$PWD/MenuItem.qml \ + $$PWD/MenuSeparator.qml \ + $$PWD/Page.qml \ + $$PWD/PageIndicator.qml \ + $$PWD/Pane.qml \ + $$PWD/Popup.qml \ + $$PWD/ProgressBar.qml \ + $$PWD/RadioButton.qml \ + $$PWD/RadioDelegate.qml \ + $$PWD/RangeSlider.qml \ + $$PWD/RoundButton.qml \ + $$PWD/ScrollBar.qml \ + $$PWD/ScrollView.qml \ + $$PWD/ScrollIndicator.qml \ + $$PWD/SelectionRectangle.qml \ + $$PWD/Slider.qml \ + $$PWD/SpinBox.qml \ + $$PWD/SplitView.qml \ + $$PWD/SwipeDelegate.qml \ + $$PWD/SwitchDelegate.qml \ + $$PWD/Switch.qml \ + $$PWD/TabBar.qml \ + $$PWD/TabButton.qml \ + $$PWD/TextArea.qml \ + $$PWD/TextField.qml \ + $$PWD/ToolBar.qml \ + $$PWD/ToolButton.qml \ + $$PWD/ToolSeparator.qml \ + $$PWD/ToolTip.qml \ + $$PWD/Tumbler.qml \ + $$PWD/VerticalHeaderView.qml diff --git a/src/quickcontrols2/fusion/images/arrow.png b/src/quickcontrols2/fusion/images/arrow.png new file mode 100644 index 00000000000..97ef0238e5d Binary files /dev/null and b/src/quickcontrols2/fusion/images/arrow.png differ diff --git a/src/quickcontrols2/fusion/images/arrow.svg b/src/quickcontrols2/fusion/images/arrow.svg new file mode 100644 index 00000000000..44383924954 --- /dev/null +++ b/src/quickcontrols2/fusion/images/arrow.svg @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="10" + height="6" + viewBox="0 0 10 6" + id="svg2" + version="1.1" + inkscape:version="0.91 r13725" + inkscape:export-filename="/Users/jpnurmi/Downloads/arrow@4x.png" + inkscape:export-xdpi="360" + inkscape:export-ydpi="360" + sodipodi:docname="arrow.svg"> + <defs + id="defs4" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="31.678384" + inkscape:cx="7.9810383" + inkscape:cy="3.0344775" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + units="px" + inkscape:snap-to-guides="true" + inkscape:snap-page="true" + inkscape:window-width="1440" + inkscape:window-height="851" + inkscape:window-x="0" + inkscape:window-y="1" + inkscape:window-maximized="1"> + <inkscape:grid + type="xygrid" + id="grid3336" /> + </sodipodi:namedview> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-1046.3622)"> + <path + transform="matrix(1.2371791,0,0,0.85714284,1.0769252,150.19463)" + style="fill:#000000;fill-opacity:0.7254902" + inkscape:transform-center-y="1.4999605" + d="m 3.1709837,1051.3622 -3.2331616,-4.6667 6.4663233,0 z" + id="path3365" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccc" /> + </g> +</svg> diff --git a/src/quickcontrols2/fusion/images/arrow@2x.png b/src/quickcontrols2/fusion/images/arrow@2x.png new file mode 100644 index 00000000000..9bfc4e6eedb Binary files /dev/null and b/src/quickcontrols2/fusion/images/arrow@2x.png differ diff --git a/src/quickcontrols2/fusion/images/arrow@3x.png b/src/quickcontrols2/fusion/images/arrow@3x.png new file mode 100644 index 00000000000..6fd9c988dc0 Binary files /dev/null and b/src/quickcontrols2/fusion/images/arrow@3x.png differ diff --git a/src/quickcontrols2/fusion/images/arrow@4x.png b/src/quickcontrols2/fusion/images/arrow@4x.png new file mode 100644 index 00000000000..f5e1e66a1d9 Binary files /dev/null and b/src/quickcontrols2/fusion/images/arrow@4x.png differ diff --git a/src/quickcontrols2/fusion/images/checkmark.png b/src/quickcontrols2/fusion/images/checkmark.png new file mode 100644 index 00000000000..deb30419d01 Binary files /dev/null and b/src/quickcontrols2/fusion/images/checkmark.png differ diff --git a/src/quickcontrols2/fusion/images/checkmark.svg b/src/quickcontrols2/fusion/images/checkmark.svg new file mode 100644 index 00000000000..f1afdc4f9ff --- /dev/null +++ b/src/quickcontrols2/fusion/images/checkmark.svg @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="14" + height="14" + viewBox="0 0 14 14" + id="svg3386" + version="1.1" + inkscape:version="0.91 r13725" + inkscape:export-filename="/Users/jpnurmi/Downloads/checkmark@4x.png" + inkscape:export-xdpi="360" + inkscape:export-ydpi="360" + sodipodi:docname="checkmark.svg"> + <defs + id="defs3388" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="32" + inkscape:cx="1.9865044" + inkscape:cy="6.0706667" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + units="px" + inkscape:snap-page="true" + inkscape:snap-grids="true" + inkscape:snap-to-guides="true" + inkscape:window-width="1440" + inkscape:window-height="851" + inkscape:window-x="0" + inkscape:window-y="1" + inkscape:window-maximized="1" /> + <metadata + id="metadata3391"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-1038.3622)"> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 5,1045.3622 2,4 2.5,-8" + id="path4198" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccc" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90" /> + </g> +</svg> diff --git a/src/quickcontrols2/fusion/images/checkmark@2x.png b/src/quickcontrols2/fusion/images/checkmark@2x.png new file mode 100644 index 00000000000..f80de0a4256 Binary files /dev/null and b/src/quickcontrols2/fusion/images/checkmark@2x.png differ diff --git a/src/quickcontrols2/fusion/images/checkmark@3x.png b/src/quickcontrols2/fusion/images/checkmark@3x.png new file mode 100644 index 00000000000..c095eed18a3 Binary files /dev/null and b/src/quickcontrols2/fusion/images/checkmark@3x.png differ diff --git a/src/quickcontrols2/fusion/images/checkmark@4x.png b/src/quickcontrols2/fusion/images/checkmark@4x.png new file mode 100644 index 00000000000..e58c7b4df4e Binary files /dev/null and b/src/quickcontrols2/fusion/images/checkmark@4x.png differ diff --git a/src/quickcontrols2/fusion/images/progressmask.png b/src/quickcontrols2/fusion/images/progressmask.png new file mode 100644 index 00000000000..a354377c4a5 Binary files /dev/null and b/src/quickcontrols2/fusion/images/progressmask.png differ diff --git a/src/quickcontrols2/fusion/images/progressmask.svg b/src/quickcontrols2/fusion/images/progressmask.svg new file mode 100644 index 00000000000..a0dfc4269d5 --- /dev/null +++ b/src/quickcontrols2/fusion/images/progressmask.svg @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="31" + height="22" + viewBox="0 0 8.202083 5.8208335" + version="1.1" + id="svg8" + inkscape:export-filename="/home/jpnurmi/Projects/qt-dev/qtquickcontrols2/src/imports/controls/fusion/images/progressmask@4x.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384" + inkscape:version="0.92.1 r" + sodipodi:docname="progressmask.svg"> + <defs + id="defs2" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="15.839192" + inkscape:cx="61.144853" + inkscape:cy="14.574824" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + showgrid="false" + units="px" + inkscape:pagecheckerboard="true" + inkscape:window-width="3840" + inkscape:window-height="2031" + inkscape:window-x="0" + inkscape:window-y="55" + inkscape:window-maximized="1" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-291.17915)"> + <path + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:4.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 0,296.99998 4.7625,-5.82083" + id="path4485" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:4.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 8.2020833,296.99998 4.7624997,-5.82083" + id="path4485-3" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + </g> +</svg> diff --git a/src/quickcontrols2/fusion/images/progressmask@2x.png b/src/quickcontrols2/fusion/images/progressmask@2x.png new file mode 100644 index 00000000000..69476bf4a07 Binary files /dev/null and b/src/quickcontrols2/fusion/images/progressmask@2x.png differ diff --git a/src/quickcontrols2/fusion/images/progressmask@3x.png b/src/quickcontrols2/fusion/images/progressmask@3x.png new file mode 100644 index 00000000000..00a1c09d87b Binary files /dev/null and b/src/quickcontrols2/fusion/images/progressmask@3x.png differ diff --git a/src/quickcontrols2/fusion/images/progressmask@4x.png b/src/quickcontrols2/fusion/images/progressmask@4x.png new file mode 100644 index 00000000000..263110d5fe3 Binary files /dev/null and b/src/quickcontrols2/fusion/images/progressmask@4x.png differ diff --git a/src/quickcontrols2/fusion/impl/ButtonPanel.qml b/src/quickcontrols2/fusion/impl/ButtonPanel.qml new file mode 100644 index 00000000000..6d64df8f78c --- /dev/null +++ b/src/quickcontrols2/fusion/impl/ButtonPanel.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +Rectangle { + id: panel + + property Item control + property bool highlighted: control.highlighted + + visible: !control.flat || control.down || control.checked + + color: Fusion.buttonColor(control.palette, panel.highlighted, control.down || control.checked, + enabled && control.hovered) + gradient: control.down || control.checked ? null : buttonGradient + + Gradient { + id: buttonGradient + GradientStop { + position: 0 + color: Fusion.gradientStart(Fusion.buttonColor(panel.control.palette, panel.highlighted, + panel.control.down, panel.enabled && panel.control.hovered)) + } + GradientStop { + position: 1 + color: Fusion.gradientStop(Fusion.buttonColor(panel.control.palette, panel.highlighted, + panel.control.down, panel.enabled && panel.control.hovered)) + } + } + + radius: 2 + border.color: Fusion.buttonOutline(control.palette, panel.highlighted || control.visualFocus, control.enabled) + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + border.color: Fusion.innerContrastLine + color: "transparent" + radius: 2 + } +} diff --git a/src/quickcontrols2/fusion/impl/CMakeLists.txt b/src/quickcontrols2/fusion/impl/CMakeLists.txt new file mode 100644 index 00000000000..1aaebf266f5 --- /dev/null +++ b/src/quickcontrols2/fusion/impl/CMakeLists.txt @@ -0,0 +1,39 @@ +##################################################################### +## qtquickcontrols2fusionstyleimplplugin Plugin: +##################################################################### + +set(qml_files + "ButtonPanel.qml" + "CheckIndicator.qml" + "RadioIndicator.qml" + "SliderGroove.qml" + "SliderHandle.qml" + "SwitchIndicator.qml" +) + +qt_internal_add_qml_module(qtquickcontrols2fusionstyleimplplugin + URI "QtQuick.Controls.Fusion.impl" + VERSION "${PROJECT_VERSION}" + PAST_MAJOR_VERSIONS 2 + CLASS_NAME QtQuickControls2FusionStyleImplPlugin + DEPENDENCIES + QtQuick/auto + PLUGIN_TARGET qtquickcontrols2fusionstyleimplplugin + NO_PLUGIN_OPTIONAL + SOURCES + qquickfusionbusyindicator.cpp qquickfusionbusyindicator_p.h + qquickfusiondial.cpp qquickfusiondial_p.h + qquickfusionknob.cpp qquickfusionknob_p.h + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::QmlPrivate + Qt::QuickControls2ImplPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private +) diff --git a/src/quickcontrols2/fusion/impl/CheckIndicator.qml b/src/quickcontrols2/fusion/impl/CheckIndicator.qml new file mode 100644 index 00000000000..3a083653f50 --- /dev/null +++ b/src/quickcontrols2/fusion/impl/CheckIndicator.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +Rectangle { + id: indicator + + property Item control + readonly property color pressedColor: Fusion.mergedColors(control.palette.base, control.palette.windowText, 85) + readonly property color checkMarkColor: Qt.darker(control.palette.text, 1.2) + + implicitWidth: 14 + implicitHeight: 14 + + color: control.down ? indicator.pressedColor : control.palette.base + border.color: control.visualFocus ? Fusion.highlightedOutline(control.palette) + : Qt.lighter(Fusion.outline(control.palette), 1.1) + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: 1 + color: Fusion.topShadow + visible: indicator.control.enabled && !indicator.control.down + } + + ColorImage { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + color: Color.transparent(indicator.checkMarkColor, 210 / 255) + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/checkmark.png" + visible: indicator.control.checkState === Qt.Checked || (indicator.control.checked && indicator.control.checkState === undefined) + } + + Rectangle { + x: 3; y: 3 + width: parent.width - 6 + height: parent.width - 6 + + visible: indicator.control.checkState === Qt.PartiallyChecked + + gradient: Gradient { + GradientStop { + position: 0 + color: Color.transparent(indicator.checkMarkColor, 80 / 255) + } + GradientStop { + position: 1 + color: Color.transparent(indicator.checkMarkColor, 140 / 255) + } + } + border.color: Color.transparent(indicator.checkMarkColor, 180 / 255) + } +} diff --git a/src/quickcontrols2/fusion/impl/RadioIndicator.qml b/src/quickcontrols2/fusion/impl/RadioIndicator.qml new file mode 100644 index 00000000000..d459a2e84f1 --- /dev/null +++ b/src/quickcontrols2/fusion/impl/RadioIndicator.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +Rectangle { + id: indicator + + property Item control + readonly property color pressedColor: Fusion.mergedColors(control.palette.base, control.palette.windowText, 85) + readonly property color checkMarkColor: Qt.darker(control.palette.text, 1.2) + + implicitWidth: 14 + implicitHeight: 14 + + radius: width / 2 + color: control.down ? indicator.pressedColor : control.palette.base + border.color: control.visualFocus ? Fusion.highlightedOutline(control.palette) + : Qt.darker(control.palette.window, 1.5) + + Rectangle { + y: 1 + width: parent.width + height: parent.height - 1 + radius: width / 2 + color: "transparent" + border.color: Fusion.topShadow + visible: indicator.control.enabled && !indicator.control.down + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: parent.width / 2.32 + height: parent.height / 2.32 + radius: width / 2 + color: Color.transparent(indicator.checkMarkColor, 180 / 255) + border.color: Color.transparent(indicator.checkMarkColor, 200 / 255) + visible: indicator.control.checked + } +} diff --git a/src/quickcontrols2/fusion/impl/SliderGroove.qml b/src/quickcontrols2/fusion/impl/SliderGroove.qml new file mode 100644 index 00000000000..76b7156a85d --- /dev/null +++ b/src/quickcontrols2/fusion/impl/SliderGroove.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +Rectangle { + id: groove + + property Item control + property real offset + property real progress + property real visualProgress + + x: control.horizontal ? 0 : (control.availableWidth - width) / 2 + y: control.horizontal ? (control.availableHeight - height) / 2 : 0 + + implicitWidth: control.horizontal ? 160 : 5 + implicitHeight: control.horizontal ? 5 : 160 + width: control.horizontal ? control.availableWidth : implicitWidth + height: control.horizontal ? implicitHeight : control.availableHeight + + radius: 2 + border.color: Fusion.outline(control.palette) + scale: control.horizontal && control.mirrored ? -1 : 1 + + gradient: Gradient { + GradientStop { + position: 0 + color: Qt.darker(Fusion.grooveColor(groove.control.palette), 1.1) + } + GradientStop { + position: 1 + color: Qt.lighter(Fusion.grooveColor(groove.control.palette), 1.1) + } + } + + Rectangle { + x: groove.control.horizontal ? groove.offset * parent.width : 0 + y: groove.control.horizontal ? 0 : groove.visualProgress * parent.height + width: groove.control.horizontal ? groove.progress * parent.width - groove.offset * parent.width : 5 + height: groove.control.horizontal ? 5 : groove.progress * parent.height - groove.offset * parent.height + + radius: 2 + border.color: Qt.darker(Fusion.highlightedOutline(groove.control.palette), 1.1) + + gradient: Gradient { + GradientStop { + position: 0 + color: Fusion.highlight(groove.control.palette) + } + GradientStop { + position: 1 + color: Qt.lighter(Fusion.highlight(groove.control.palette), 1.2) + } + } + } +} diff --git a/src/quickcontrols2/fusion/impl/SliderHandle.qml b/src/quickcontrols2/fusion/impl/SliderHandle.qml new file mode 100644 index 00000000000..80b0e4db9c6 --- /dev/null +++ b/src/quickcontrols2/fusion/impl/SliderHandle.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +Rectangle { + id: handle + + property var palette + property bool pressed + property bool hovered + property bool vertical + property bool visualFocus + + implicitWidth: 13 + implicitHeight: 13 + + gradient: Gradient { + GradientStop { + position: 0 + color: Fusion.gradientStart(Fusion.buttonColor(handle.palette, handle.visualFocus, + handle.pressed, handle.enabled && handle.hovered)) + } + GradientStop { + position: 1 + color: Fusion.gradientStop(Fusion.buttonColor(handle.palette, handle.visualFocus, + handle.pressed, handle.enabled && handle.hovered)) + } + } + rotation: handle.vertical ? -90 : 0 + border.width: 1 + border.color: "transparent" + radius: 2 + + Rectangle { + width: parent.width + height: parent.height + border.color: handle.visualFocus ? Fusion.highlightedOutline(handle.palette) : Fusion.outline(handle.palette) + color: "transparent" + radius: 2 + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + border.color: Fusion.innerContrastLine + color: "transparent" + radius: 2 + } + } +} diff --git a/src/quickcontrols2/fusion/impl/SwitchIndicator.qml b/src/quickcontrols2/fusion/impl/SwitchIndicator.qml new file mode 100644 index 00000000000..f54737816c1 --- /dev/null +++ b/src/quickcontrols2/fusion/impl/SwitchIndicator.qml @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +Rectangle { + id: indicator + + property T.AbstractButton control + readonly property color pressedColor: Fusion.mergedColors(control.palette.base, control.palette.windowText, 85) + readonly property color checkMarkColor: Qt.darker(control.palette.text, 1.2) + + implicitWidth: 40 + implicitHeight: 16 + + radius: 2 + border.color: Fusion.outline(control.palette) + + gradient: Gradient { + GradientStop { + position: 0 + color: Qt.darker(Fusion.grooveColor(indicator.control.palette), 1.1) + } + GradientStop { + position: 1 + color: Qt.lighter(Fusion.grooveColor(indicator.control.palette), 1.1) + } + } + + Rectangle { + x: indicator.control.mirrored ? handle.x : 0 + width: indicator.control.mirrored ? parent.width - handle.x : handle.x + handle.width + height: parent.height + + opacity: indicator.control.checked ? 1 : 0 + Behavior on opacity { + enabled: !indicator.control.down + NumberAnimation { duration: 80 } + } + + radius: 2 + border.color: Qt.darker(Fusion.highlightedOutline(indicator.control.palette), 1.1) + border.width: indicator.control.enabled ? 1 : 0 + + gradient: Gradient { + GradientStop { + position: 0 + color: Fusion.highlight(indicator.control.palette) + } + GradientStop { + position: 1 + color: Qt.lighter(Fusion.highlight(indicator.control.palette), 1.2) + } + } + } + + Rectangle { + id: handle + x: Math.max(0, Math.min(parent.width - width, indicator.control.visualPosition * parent.width - (width / 2))) + y: (parent.height - height) / 2 + width: 20 + height: 16 + radius: 2 + + gradient: Gradient { + GradientStop { + position: 0 + color: Fusion.gradientStart(Fusion.buttonColor(indicator.control.palette, + indicator.control.visualFocus, indicator.control.pressed, indicator.enabled && indicator.control.hovered)) + } + GradientStop { + position: 1 + color: Fusion.gradientStop(Fusion.buttonColor(indicator.control.palette, + indicator.control.visualFocus, indicator.control.pressed, indicator.enabled && indicator.control.hovered)) + } + } + border.width: 1 + border.color: "transparent" + + Rectangle { + width: parent.width + height: parent.height + border.color: indicator.control.visualFocus ? Fusion.highlightedOutline(indicator.control.palette) : Fusion.outline(indicator.control.palette) + color: "transparent" + radius: 2 + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + border.color: Fusion.innerContrastLine + color: "transparent" + radius: 2 + } + } + + Behavior on x { + enabled: !indicator.control.down + SmoothedAnimation { velocity: 200 } + } + } +} diff --git a/src/quickcontrols2/fusion/impl/qquickfusionbusyindicator.cpp b/src/quickcontrols2/fusion/impl/qquickfusionbusyindicator.cpp new file mode 100644 index 00000000000..3c30045ad90 --- /dev/null +++ b/src/quickcontrols2/fusion/impl/qquickfusionbusyindicator.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfusionbusyindicator_p.h" + +#include <QtGui/qpainter.h> + +QT_BEGIN_NAMESPACE + +QQuickFusionBusyIndicator::QQuickFusionBusyIndicator(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ +} + +QColor QQuickFusionBusyIndicator::color() const +{ + return m_color; +} + +void QQuickFusionBusyIndicator::setColor(const QColor &color) +{ + if (color == m_color) + return; + + m_color = color; + update(); +} + +bool QQuickFusionBusyIndicator::isRunning() const +{ + return isVisible(); +} + +void QQuickFusionBusyIndicator::setRunning(bool running) +{ + if (running) { + setVisible(true); + update(); + } +} + +void QQuickFusionBusyIndicator::paint(QPainter *painter) +{ + const qreal w = width(); + const qreal h = height(); + if (w <= 0 || h <= 0 || !isRunning()) + return; + + const qreal sz = qMin(w, h); + const qreal dx = (w - sz) / 2; + const qreal dy = (h - sz) / 2; + const int hpw = qRound(qMax(qreal(1), sz / 14)) & -1; + const int pw = 2 * hpw; + const QRectF bounds(dx + hpw, dy + hpw, sz - pw - 1, sz - pw - 1); + + QConicalGradient gradient; + gradient.setCenter(QPointF(dx + sz / 2, dy + sz / 2)); + gradient.setColorAt(0, m_color); + gradient.setColorAt(0.1, m_color); + gradient.setColorAt(1, Qt::transparent); + + painter->translate(0.5, 0.5); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(QPen(gradient, pw, Qt::SolidLine)); + painter->drawArc(bounds, 0, 360 * 16); + painter->setPen(QPen(m_color, pw, Qt::SolidLine, Qt::RoundCap)); + painter->drawArc(bounds, 0, 20 * 16); +} + +void QQuickFusionBusyIndicator::itemChange(ItemChange change, const ItemChangeData &data) +{ + QQuickPaintedItem::itemChange(change, data); + + if (change == ItemOpacityHasChanged && qFuzzyIsNull(data.realValue)) + setVisible(false); +} + +QT_END_NAMESPACE + +#include "moc_qquickfusionbusyindicator_p.cpp" diff --git a/src/quickcontrols2/fusion/impl/qquickfusionbusyindicator_p.h b/src/quickcontrols2/fusion/impl/qquickfusionbusyindicator_p.h new file mode 100644 index 00000000000..5aeea6c4884 --- /dev/null +++ b/src/quickcontrols2/fusion/impl/qquickfusionbusyindicator_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFUSIONBUSYINDICATOR_P_H +#define QQUICKFUSIONBUSYINDICATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qcolor.h> +#include <QtQuick/qquickpainteditem.h> + +QT_BEGIN_NAMESPACE + +class QQuickFusionBusyIndicator : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + Q_PROPERTY(bool running READ isRunning WRITE setRunning) + QML_NAMED_ELEMENT(BusyIndicatorImpl) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickFusionBusyIndicator(QQuickItem *parent = nullptr); + + QColor color() const; + void setColor(const QColor &color); + + bool isRunning() const; + void setRunning(bool running); + + void paint(QPainter *painter) override; + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + +private: + QColor m_color; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFUSIONBUSYINDICATOR_P_H diff --git a/src/quickcontrols2/fusion/impl/qquickfusiondial.cpp b/src/quickcontrols2/fusion/impl/qquickfusiondial.cpp new file mode 100644 index 00000000000..86d3652c1f5 --- /dev/null +++ b/src/quickcontrols2/fusion/impl/qquickfusiondial.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfusiondial_p.h" + +#include <QtGui/qpainter.h> +#include <QtGui/private/qmath_p.h> +#include <QtQuick/private/qquickpalette_p.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +QQuickFusionDial::QQuickFusionDial(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ +} + +bool QQuickFusionDial::highlight() const +{ + return m_highlight; +} + +void QQuickFusionDial::setHighlight(bool highlight) +{ + if (m_highlight == highlight) + return; + + m_highlight = highlight; + update(); +} + +// based on QStyleHelper::drawDial() +void QQuickFusionDial::paint(QPainter *painter) +{ + const int width = QQuickItem::width(); + const int height = QQuickItem::height(); + if (width <= 0 || height <= 0 || !isVisible()) + return; + + QColor buttonColor = QQuickItemPrivate::get(this)->palette()->button(); + const bool enabled = isEnabled(); + qreal r = qMin(width, height) / 2.0; + r -= r/50; + const qreal penSize = r/20.0; + + painter->setRenderHint(QPainter::Antialiasing); + + const qreal d_ = r / 6; + const qreal dx = d_ + (width - 2 * r) / 2 + 1; + const qreal dy = d_ + (height - 2 * r) / 2 + 1; + + QRectF br = QRectF(dx + 0.5, dy + 0.5, + int(r * 2 - 2 * d_ - 2), + int(r * 2 - 2 * d_ - 2)); + buttonColor.setHsv(buttonColor .hue(), + qMin(140, buttonColor .saturation()), + qMax(180, buttonColor.value())); + + if (enabled) { + // Drop shadow + qreal shadowSize = qMax(1.0, penSize/2.0); + QRectF shadowRect= br.adjusted(-2*shadowSize, -2*shadowSize, + 2*shadowSize, 2*shadowSize); + QRadialGradient shadowGradient(shadowRect.center().x(), + shadowRect.center().y(), shadowRect.width()/2.0, + shadowRect.center().x(), shadowRect.center().y()); + shadowGradient.setColorAt(qreal(0.91), QColor(0, 0, 0, 40)); + shadowGradient.setColorAt(qreal(1.0), Qt::transparent); + painter->setBrush(shadowGradient); + painter->setPen(Qt::NoPen); + painter->translate(shadowSize, shadowSize); + painter->drawEllipse(shadowRect); + painter->translate(-shadowSize, -shadowSize); + + // Main gradient + QRadialGradient gradient(br.center().x() - br.width()/3, dy, + br.width()*1.3, br.center().x(), + br.center().y() - br.height()/2); + gradient.setColorAt(0, buttonColor.lighter(110)); + gradient.setColorAt(qreal(0.5), buttonColor); + gradient.setColorAt(qreal(0.501), buttonColor.darker(102)); + gradient.setColorAt(1, buttonColor.darker(115)); + painter->setBrush(gradient); + } else { + painter->setBrush(Qt::NoBrush); + } + + painter->setPen(QPen(buttonColor.darker(280))); + painter->drawEllipse(br); + painter->setBrush(Qt::NoBrush); + painter->setPen(buttonColor.lighter(110)); + painter->drawEllipse(br.adjusted(1, 1, -1, -1)); + + if (m_highlight) { + QColor highlight = QQuickItemPrivate::get(this)->palette()->highlight(); + highlight.setHsv(highlight.hue(), + qMin(160, highlight.saturation()), + qMax(230, highlight.value())); + highlight.setAlpha(127); + painter->setPen(QPen(highlight, 2.0)); + painter->setBrush(Qt::NoBrush); + painter->drawEllipse(br.adjusted(-1, -1, 1, 1)); + } +} + +QT_END_NAMESPACE + +#include "moc_qquickfusiondial_p.cpp" diff --git a/src/quickcontrols2/fusion/impl/qquickfusiondial_p.h b/src/quickcontrols2/fusion/impl/qquickfusiondial_p.h new file mode 100644 index 00000000000..c320527a4e2 --- /dev/null +++ b/src/quickcontrols2/fusion/impl/qquickfusiondial_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFUSIONDIAL_P_H +#define QQUICKFUSIONDIAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickpainteditem.h> + +QT_BEGIN_NAMESPACE + +class QQuickFusionDial : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(bool highlight READ highlight WRITE setHighlight FINAL) + QML_NAMED_ELEMENT(DialImpl) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickFusionDial(QQuickItem *parent = nullptr); + + bool highlight() const; + void setHighlight(bool highlight); + + void paint(QPainter *painter) override; + +private: + bool m_highlight = false; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFUSIONDIAL_P_H diff --git a/src/quickcontrols2/fusion/impl/qquickfusionknob.cpp b/src/quickcontrols2/fusion/impl/qquickfusionknob.cpp new file mode 100644 index 00000000000..0b520e43ba4 --- /dev/null +++ b/src/quickcontrols2/fusion/impl/qquickfusionknob.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfusionknob_p.h" + +#include <QtCore/qmath.h> +#include <QtGui/qpainter.h> +#include <QtQuick/private/qquickpalette_p.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +QQuickFusionKnob::QQuickFusionKnob(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ + connect(this, &QQuickItem::paletteChanged, this, [this](){ update(); }); +} + +// extracted from QStyleHelper::drawDial() +void QQuickFusionKnob::paint(QPainter *painter) +{ + const qreal w = width(); + const qreal h = height(); + if (w <= 0 || h <= 0) + return; + + QColor color = QQuickItemPrivate::get(this)->palette()->button(); + color.setHsv(color.hue(), + qMin(140, color .saturation()), + qMax(180, color.value())); + color = color.lighter(104); + color.setAlphaF(0.8f); + + const qreal sz = qMin(w, h); + QRectF rect(0, 0, sz, sz); + rect.moveCenter(QPointF(w / 2.0, h / 2.0)); + const QPointF center = rect.center(); + + QRadialGradient gradient(center.x() + rect.width() / 2, + center.y() + rect.width(), + rect.width() * 2, + center.x(), center.y()); + gradient.setColorAt(1, color.darker(140)); + gradient.setColorAt(qreal(0.4), color.darker(120)); + gradient.setColorAt(0, color.darker(110)); + + painter->setRenderHint(QPainter::Antialiasing); + painter->setBrush(gradient); + painter->setPen(QColor(255, 255, 255, 150)); + painter->drawEllipse(rect); + painter->setPen(QColor(0, 0, 0, 80)); + painter->drawEllipse(rect.adjusted(1, 1, -1, -1)); +} + +QT_END_NAMESPACE + +#include "moc_qquickfusionknob_p.cpp" diff --git a/src/quickcontrols2/fusion/impl/qquickfusionknob_p.h b/src/quickcontrols2/fusion/impl/qquickfusionknob_p.h new file mode 100644 index 00000000000..b9b9c3776dc --- /dev/null +++ b/src/quickcontrols2/fusion/impl/qquickfusionknob_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFUSIONKNOB_P_H +#define QQUICKFUSIONKNOB_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickpainteditem.h> + +QT_BEGIN_NAMESPACE + +class QQuickFusionKnob : public QQuickPaintedItem +{ + Q_OBJECT + QML_NAMED_ELEMENT(KnobImpl) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickFusionKnob(QQuickItem *parent = nullptr); + + void paint(QPainter *painter) override; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFUSIONKNOB_P_H diff --git a/src/quickcontrols2/fusion/qquickfusionstyle.cpp b/src/quickcontrols2/fusion/qquickfusionstyle.cpp new file mode 100644 index 00000000000..f2e8f8236b0 --- /dev/null +++ b/src/quickcontrols2/fusion/qquickfusionstyle.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfusionstyle_p.h" + +#include <QtGui/qcolor.h> +#include <QtGui/qpalette.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtGui/private/qguiapplication_p.h> + +#include <QtQuick/private/qquickpalette_p.h> + +QT_BEGIN_NAMESPACE + +QQuickFusionStyle::QQuickFusionStyle(QObject *parent) + : QObject(parent) +{ +} + +QColor QQuickFusionStyle::lightShade() +{ + return QColor(255, 255, 255, 90); +} + +QColor QQuickFusionStyle::darkShade() +{ + return QColor(0, 0, 0, 60); +} + +QColor QQuickFusionStyle::topShadow() +{ + return QColor(0, 0, 0, 18); +} + +QColor QQuickFusionStyle::innerContrastLine() +{ + return QColor(255, 255, 255, 30); +} + +QColor QQuickFusionStyle::highlight(QQuickPalette *palette) +{ + return palette->highlight(); +} + +QColor QQuickFusionStyle::highlightedText(QQuickPalette *palette) +{ + return palette->highlightedText(); +} + +QColor QQuickFusionStyle::outline(QQuickPalette *palette) +{ + return palette->window().darker(140); +} + +QColor QQuickFusionStyle::highlightedOutline(QQuickPalette *palette) +{ + QColor highlightedOutline = highlight(palette).darker(125); + if (highlightedOutline.value() > 160) + highlightedOutline.setHsl(highlightedOutline.hue(), highlightedOutline.saturation(), 160); + return highlightedOutline; +} + +QColor QQuickFusionStyle::tabFrameColor(QQuickPalette *palette) +{ + return buttonColor(palette).lighter(104); +} + +QColor QQuickFusionStyle::buttonColor(QQuickPalette *palette, bool highlighted, bool down, bool hovered) +{ + QColor buttonColor = palette->button(); + int val = qGray(buttonColor.rgb()); + buttonColor = buttonColor.lighter(100 + qMax(1, (180 - val)/6)); + buttonColor.setHsv(buttonColor.hue(), int(buttonColor.saturation() * 0.75), buttonColor.value()); + if (highlighted) + buttonColor = mergedColors(buttonColor, highlightedOutline(palette).lighter(130), 90); + if (!hovered) + buttonColor = buttonColor.darker(104); + if (down) + buttonColor = buttonColor.darker(110); + return buttonColor; +} + +QColor QQuickFusionStyle::buttonOutline(QQuickPalette *palette, bool highlighted, bool enabled) +{ + QColor darkOutline = enabled && highlighted ? highlightedOutline(palette) : outline(palette); + return !enabled ? darkOutline.lighter(115) : darkOutline; +} + +QColor QQuickFusionStyle::gradientStart(const QColor &baseColor) +{ + return baseColor.lighter(124); +} + +QColor QQuickFusionStyle::gradientStop(const QColor &baseColor) +{ + return baseColor.lighter(102); +} + +QColor QQuickFusionStyle::mergedColors(const QColor &colorA, const QColor &colorB, int factor) +{ + const int maxFactor = 100; + QColor tmp = colorA; + tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor); + tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor); + tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor); + return tmp; +} + +QColor QQuickFusionStyle::grooveColor(QQuickPalette *palette) +{ + QColor color = buttonColor(palette); + color.setHsv(color.hue(), + qMin(255, color.saturation()), + qMin<int>(255, color.value() * 0.9)); + return color; +} + +QT_END_NAMESPACE + +#include "moc_qquickfusionstyle_p.cpp" diff --git a/src/quickcontrols2/fusion/qquickfusionstyle_p.h b/src/quickcontrols2/fusion/qquickfusionstyle_p.h new file mode 100644 index 00000000000..c609e9c6a6f --- /dev/null +++ b/src/quickcontrols2/fusion/qquickfusionstyle_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFUSIONSTYLE_P_H +#define QQUICKFUSIONSTYLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtGui/qcolor.h> +#include <QtQml/qqml.h> +#include <QtQuick/private/qquickpalette_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickFusionStyle : public QObject +{ + Q_OBJECT + Q_PROPERTY(QColor lightShade READ lightShade CONSTANT) + Q_PROPERTY(QColor darkShade READ darkShade CONSTANT) + Q_PROPERTY(QColor topShadow READ topShadow CONSTANT) + Q_PROPERTY(QColor innerContrastLine READ innerContrastLine CONSTANT) + QML_NAMED_ELEMENT(Fusion) + QML_SINGLETON + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickFusionStyle(QObject *parent = nullptr); + + static QColor lightShade(); + static QColor darkShade(); + static QColor topShadow(); + static QColor innerContrastLine(); + + Q_INVOKABLE static QColor highlight(QQuickPalette *palette); + Q_INVOKABLE static QColor highlightedText(QQuickPalette *palette); + Q_INVOKABLE static QColor outline(QQuickPalette *palette); + Q_INVOKABLE static QColor highlightedOutline(QQuickPalette *palette); + Q_INVOKABLE static QColor tabFrameColor(QQuickPalette *palette); + Q_INVOKABLE static QColor buttonColor(QQuickPalette *palette, bool highlighted = false, bool down = false, bool hovered = false); + Q_INVOKABLE static QColor buttonOutline(QQuickPalette *palette, bool highlighted = false, bool enabled = true); + Q_INVOKABLE static QColor gradientStart(const QColor &baseColor); + Q_INVOKABLE static QColor gradientStop(const QColor &baseColor); + Q_INVOKABLE static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50); + Q_INVOKABLE static QColor grooveColor(QQuickPalette *palette); +}; + +QT_END_NAMESPACE + +#endif // QQUICKFUSIONSTYLE_P_H diff --git a/src/quickcontrols2/fusion/qquickfusiontheme.cpp b/src/quickcontrols2/fusion/qquickfusiontheme.cpp new file mode 100644 index 00000000000..29d2ed1ab25 --- /dev/null +++ b/src/quickcontrols2/fusion/qquickfusiontheme.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfusiontheme_p.h" + +#include <QtQuickTemplates2/private/qquicktheme_p.h> +#include <QtQuickControls2/private/qquickstyle_p.h> + +QT_BEGIN_NAMESPACE + +void QQuickFusionTheme::initialize(QQuickTheme *theme) +{ + const bool isDarkSystemTheme = QQuickStylePrivate::isDarkSystemTheme(); + QPalette systemPalette; + systemPalette.setColor(QPalette::Active, QPalette::ButtonText, + isDarkSystemTheme ? QColor::fromRgb(0xe7e7e7) : QColor::fromRgb(0x252525)); + systemPalette.setColor(QPalette::Inactive, QPalette::ButtonText, + isDarkSystemTheme ? QColor::fromRgb(0xe7e7e7) : QColor::fromRgb(0x252525)); + systemPalette.setColor(QPalette::Disabled, QPalette::ButtonText, + isDarkSystemTheme ? QColor::fromRgb(0x777777) : QColor::fromRgb(0xb6b6b6)); + theme->setPalette(QQuickTheme::System, systemPalette); +} + +QT_END_NAMESPACE diff --git a/src/quickcontrols2/fusion/qquickfusiontheme_p.h b/src/quickcontrols2/fusion/qquickfusiontheme_p.h new file mode 100644 index 00000000000..814c1919616 --- /dev/null +++ b/src/quickcontrols2/fusion/qquickfusiontheme_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFUSIONTHEME_P_H +#define QQUICKFUSIONTHEME_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +class QQuickTheme; + +class QQuickFusionTheme +{ +public: + static void initialize(QQuickTheme *theme); +}; + +QT_END_NAMESPACE + +#endif // QQUICKFUSIONTHEME_P_H diff --git a/src/quickcontrols2/fusion/qtquickcontrols2fusionstyle.qrc b/src/quickcontrols2/fusion/qtquickcontrols2fusionstyle.qrc new file mode 100644 index 00000000000..0a9e195a293 --- /dev/null +++ b/src/quickcontrols2/fusion/qtquickcontrols2fusionstyle.qrc @@ -0,0 +1,16 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="qt-project.org/imports/QtQuick/Controls/Fusion"> + <file>images/arrow.png</file> + <file>images/arrow@2x.png</file> + <file>images/arrow@3x.png</file> + <file>images/arrow@4x.png</file> + <file>images/checkmark.png</file> + <file>images/checkmark@2x.png</file> + <file>images/checkmark@3x.png</file> + <file>images/checkmark@4x.png</file> + <file>images/progressmask.png</file> + <file>images/progressmask@2x.png</file> + <file>images/progressmask@3x.png</file> + <file>images/progressmask@4x.png</file> +</qresource> +</RCC> diff --git a/src/quickcontrols2/fusion/qtquickcontrols2fusionstyleplugin.cpp b/src/quickcontrols2/fusion/qtquickcontrols2fusionstyleplugin.cpp new file mode 100644 index 00000000000..9d6516a1e84 --- /dev/null +++ b/src/quickcontrols2/fusion/qtquickcontrols2fusionstyleplugin.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfusionstyle_p.h" +#include "qquickfusiontheme_p.h" + +#include <QtQml/qqml.h> +#include <QtQuickControls2/private/qquickstyleplugin_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +extern void qml_register_types_QtQuick_Controls_Fusion(); +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Controls_Fusion); + +QT_BEGIN_NAMESPACE + +class QtQuickControls2FusionStylePlugin : public QQuickStylePlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtQuickControls2FusionStylePlugin(QObject *parent = nullptr); + + QString name() const override; + void initializeTheme(QQuickTheme *theme) override; + + QQuickFusionTheme theme; +}; + +QtQuickControls2FusionStylePlugin::QtQuickControls2FusionStylePlugin(QObject *parent) : QQuickStylePlugin(parent) +{ + volatile auto registration = &qml_register_types_QtQuick_Controls_Fusion; + Q_UNUSED(registration); +} + +QString QtQuickControls2FusionStylePlugin::name() const +{ + return QStringLiteral("Fusion"); +} + +void QtQuickControls2FusionStylePlugin::initializeTheme(QQuickTheme *theme) +{ + this->theme.initialize(theme); +} + +QT_END_NAMESPACE + +#include "qtquickcontrols2fusionstyleplugin.moc" diff --git a/src/quickcontrols2/imagine/ApplicationWindow.qml b/src/quickcontrols2/imagine/ApplicationWindow.qml new file mode 100644 index 00000000000..b54527eb9e7 --- /dev/null +++ b/src/quickcontrols2/imagine/ApplicationWindow.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.ApplicationWindow { + id: window + + background: NinePatchImage { + width: window.width + height: window.height + + source: Imagine.url + "applicationwindow-background" + NinePatchImageSelector on source { + states: [ + {"active": window.active} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/BusyIndicator.qml b/src/quickcontrols2/imagine/BusyIndicator.qml new file mode 100644 index 00000000000..c0fa8e515e2 --- /dev/null +++ b/src/quickcontrols2/imagine/BusyIndicator.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.BusyIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + contentItem: AnimatedImage { + opacity: control.running ? 1 : 0 + playing: control.running || opacity > 0 + visible: control.running || opacity > 0 + Behavior on opacity { OpacityAnimator { duration: 250 } } + + source: Imagine.url + "busyindicator-animation" + AnimatedImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"running": control.running}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + background: NinePatchImage { + source: Imagine.url + "busyindicator-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"running": control.running}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/Button.qml b/src/quickcontrols2/imagine/Button.qml new file mode 100644 index 00000000000..3287202f5e8 --- /dev/null +++ b/src/quickcontrols2/imagine/Button.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.Button { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + spacing: 6 // ### + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + icon.width: 24 + icon.height: 24 + icon.color: control.enabled && control.flat && control.highlighted ? control.palette.highlight + : control.enabled && (control.down || control.checked || control.highlighted) && !control.flat + ? control.palette.brightText : control.flat ? control.palette.windowText : control.palette.buttonText + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.enabled && control.flat && control.highlighted ? control.palette.highlight + : control.enabled && (control.down || control.checked || control.highlighted) && !control.flat + ? control.palette.brightText : control.flat ? control.palette.windowText : control.palette.buttonText + } + + background: NinePatchImage { + source: Imagine.url + "button-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"checkable": control.checkable}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"flat": control.flat}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/CMakeLists.txt b/src/quickcontrols2/imagine/CMakeLists.txt new file mode 100644 index 00000000000..e1348f1dee4 --- /dev/null +++ b/src/quickcontrols2/imagine/CMakeLists.txt @@ -0,0 +1,145 @@ +##################################################################### +## qtquickcontrols2imaginestyleplugin Plugin: +##################################################################### + +set(qml_files + "ApplicationWindow.qml" + "BusyIndicator.qml" + "Button.qml" + "CheckBox.qml" + "CheckDelegate.qml" + "ComboBox.qml" + "DelayButton.qml" + "Dial.qml" + "Dialog.qml" + "DialogButtonBox.qml" + "Drawer.qml" + "Frame.qml" + "GroupBox.qml" + "HorizontalHeaderView.qml" + "ItemDelegate.qml" + "Label.qml" + "Menu.qml" + "MenuItem.qml" + "MenuSeparator.qml" + "PageIndicator.qml" + "Page.qml" + "Pane.qml" + "Popup.qml" + "ProgressBar.qml" + "RadioButton.qml" + "RadioDelegate.qml" + "RangeSlider.qml" + "RoundButton.qml" + "ScrollView.qml" + "ScrollBar.qml" + "ScrollIndicator.qml" + "SelectionRectangle.qml" + "Slider.qml" + "SpinBox.qml" + "SplitView.qml" + "StackView.qml" + "SwipeDelegate.qml" + "SwipeView.qml" + "Switch.qml" + "SwitchDelegate.qml" + "TextField.qml" + "TextArea.qml" + "TabBar.qml" + "TabButton.qml" + "ToolBar.qml" + "ToolButton.qml" + "ToolSeparator.qml" + "ToolTip.qml" + "Tumbler.qml" + "VerticalHeaderView.qml" +) +set_source_files_properties(DelayButton.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.2;6.0" +) +set_source_files_properties(Dialog.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(DialogButtonBox.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(HorizontalHeaderView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.15;6.0" +) +set_source_files_properties(MenuSeparator.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(RoundButton.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(SplitView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.13;6.0" +) +set_source_files_properties(ToolSeparator.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(VerticalHeaderView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.15;6.0" +) + +qt_internal_add_qml_module(qtquickcontrols2imaginestyleplugin + URI "QtQuick.Controls.Imagine" + VERSION "${PROJECT_VERSION}" + PAST_MAJOR_VERSIONS 2 + CLASS_NAME QtQuickControls2ImagineStylePlugin + IMPORTS + QtQuick.Controls.Basic/auto + PLUGIN_TARGET qtquickcontrols2imaginestyleplugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + SOURCES + qquickimaginestyle.cpp qquickimaginestyle_p.h + qquickimaginetheme.cpp qquickimaginetheme_p.h + qtquickcontrols2imaginestyleplugin.cpp + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2ImplPrivate + Qt::QuickControls2Private + Qt::QuickPrivate + Qt::QuickTemplates2Private +) + +file(GLOB resource_glob_0 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "images/*.png") +foreach(file IN LISTS resource_glob_0) + set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}") +endforeach() + +file(GLOB resource_glob_1 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "images/*.webp") +foreach(file IN LISTS resource_glob_1) + set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}") +endforeach() + +# Resources: +set(qmake_qtquickcontrols2imaginestyleplugin_resource_files + ${resource_glob_0} + ${resource_glob_1} +) + +qt_internal_add_resource(qtquickcontrols2imaginestyleplugin "qmake_qtquickcontrols2imaginestyleplugin" + PREFIX + "/qt-project.org/imports/QtQuick/Controls/Imagine" + FILES + ${qmake_qtquickcontrols2imaginestyleplugin_resource_files} +) + +add_subdirectory(impl) + +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2imaginestyleplugin quickwindow) +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2imaginestyleplugin + qtquickcontrols2imaginestyleimplplugin) + +# Basic style is the required fallback style. +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2imaginestyleplugin + qtquickcontrols2basicstyleplugin) diff --git a/src/quickcontrols2/imagine/CheckBox.qml b/src/quickcontrols2/imagine/CheckBox.qml new file mode 100644 index 00000000000..25ffee6197f --- /dev/null +++ b/src/quickcontrols2/imagine/CheckBox.qml @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.CheckBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 6 // ### + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + indicator: Image { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + source: Imagine.url + "checkbox-indicator" + ImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checkState === Qt.Checked}, + {"partially-checked": control.checkState === Qt.PartiallyChecked}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.palette.windowText + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + background: NinePatchImage { + source: Imagine.url + "checkbox-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checkState === Qt.Checked}, + {"partially-checked": control.checkState === Qt.PartiallyChecked}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/CheckDelegate.qml b/src/quickcontrols2/imagine/CheckDelegate.qml new file mode 100644 index 00000000000..4b98ddf9009 --- /dev/null +++ b/src/quickcontrols2/imagine/CheckDelegate.qml @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.CheckDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 // ### + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.text + + indicator: Image { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + source: Imagine.url + "checkdelegate-indicator" + ImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checkState === Qt.Checked}, + {"partially-checked": control.checkState === Qt.PartiallyChecked}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + contentItem: IconLabel { + leftPadding: control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: !control.mirrored ? control.indicator.width + control.spacing : 0 + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.palette.text + } + + background: NinePatchImage { + source: Imagine.url + "checkdelegate-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checkState === Qt.Checked}, + {"partially-checked": control.checkState === Qt.PartiallyChecked}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/ComboBox.qml b/src/quickcontrols2/imagine/ComboBox.qml new file mode 100644 index 00000000000..45ce8fb38e0 --- /dev/null +++ b/src/quickcontrols2/imagine/ComboBox.qml @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.ComboBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + (background ? background.leftPadding + background.rightPadding : 0)) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + Math.max(implicitContentHeight, + implicitIndicatorHeight) + (background ? background.topPadding + background.bottomPadding : 0)) + + leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + delegate: ItemDelegate { + width: ListView.view.width + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData + font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal + highlighted: control.highlightedIndex === index + hoverEnabled: control.hoverEnabled + } + + indicator: Image { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + + source: Imagine.url + "combobox-indicator" + ImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.pressed}, + {"editable": control.editable}, + {"open": control.down}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered}, + {"flat": control.flat} + ] + } + } + + contentItem: T.TextField { + topPadding: control.background ? control.background.topPadding : 0 + leftPadding: control.background ? control.background.leftPadding : 0 + rightPadding: control.background ? control.background.rightPadding : 0 + bottomPadding: control.background ? control.background.bottomPadding : 0 + + text: control.editable ? control.editText : control.displayText + + enabled: control.editable + autoScroll: control.editable + readOnly: control.down + inputMethodHints: control.inputMethodHints + validator: control.validator + selectByMouse: control.selectTextByMouse + + font: control.font + color: control.flat ? control.palette.windowText : control.editable ? control.palette.text : control.palette.buttonText + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + verticalAlignment: Text.AlignVCenter + } + + background: NinePatchImage { + source: Imagine.url + "combobox-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.pressed}, + {"editable": control.editable}, + {"open": control.down}, + {"focused": control.visualFocus || (control.editable && control.activeFocus)}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered}, + {"flat": control.flat} + ] + } + } + + popup: T.Popup { + width: control.width + height: Math.min(contentItem.implicitHeight + topPadding + bottomPadding, control.Window.height - topMargin - bottomMargin) + + topMargin: background.topInset + bottomMargin: background.bottomInset + + topPadding: background.topPadding + leftPadding: background.leftPadding + rightPadding: background.rightPadding + bottomPadding: background.bottomPadding + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + palette.text: control.palette.text + palette.highlight: control.palette.highlight + palette.highlightedText: control.palette.highlightedText + palette.windowText: control.palette.windowText + palette.buttonText: control.palette.buttonText + + contentItem: ListView { + clip: true + implicitHeight: contentHeight + model: control.delegateModel + currentIndex: control.highlightedIndex + highlightMoveDuration: 0 + + T.ScrollIndicator.vertical: ScrollIndicator { } + } + + background: NinePatchImage { + source: Imagine.url + "combobox-popup" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.pressed}, + {"editable": control.editable}, + {"focused": control.visualFocus || (control.editable && control.activeFocus)}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered}, + {"flat": control.flat} + ] + } + } + } +} diff --git a/src/quickcontrols2/imagine/DelayButton.qml b/src/quickcontrols2/imagine/DelayButton.qml new file mode 100644 index 00000000000..145b3383b59 --- /dev/null +++ b/src/quickcontrols2/imagine/DelayButton.qml @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.DelayButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + transition: Transition { + NumberAnimation { + duration: control.delay * (control.pressed ? 1.0 - control.progress : 0.3 * control.progress) + } + } + + contentItem: Text { + text: control.text + font: control.font + color: control.palette.buttonText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: NinePatchImage { + source: control.Imagine.url + "delaybutton-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + + readonly property NinePatchImage progress: NinePatchImage { + parent: control.background + width: control.progress * parent.width + height: parent.height + visible: false + + source: control.Imagine.url + "delaybutton-progress" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + readonly property NinePatchImage mask: NinePatchImage { + width: control.background.width + height: control.background.height + visible: false + + source: control.Imagine.url + "delaybutton-mask" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + readonly property OpacityMask effect: OpacityMask { + parent: control.background + width: source.width + height: source.height + source: control.background.progress + + maskSource: ShaderEffectSource { + sourceItem: control.background.mask + sourceRect: Qt.rect(0, 0, control.background.effect.width, control.background.effect.height) + } + } + } +} diff --git a/src/quickcontrols2/imagine/Dial.qml b/src/quickcontrols2/imagine/Dial.qml new file mode 100644 index 00000000000..aa4f5bc76f7 --- /dev/null +++ b/src/quickcontrols2/imagine/Dial.qml @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.Dial { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + (handle ? handle.implicitWidth : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + (handle ? handle.implicitHeight : 0) + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + handle: Image { + x: control.background.x + control.background.width / 2 - width / 2 + y: control.background.y + control.background.height / 2 - height / 2 + + source: Imagine.url + "dial-handle" + ImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.pressed}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + + transform: [ + Translate { + y: -Math.min(control.background.width, control.background.height) * 0.4 + control.handle.height / 2 + }, + Rotation { + angle: control.angle + origin.x: control.handle.width / 2 + origin.y: control.handle.height / 2 + } + ] + } + + background: NinePatchImage { + x: control.width / 2 - width / 2 + y: control.height / 2 - height / 2 + width: Math.max(64, Math.min(control.width, control.height)) + height: width + fillMode: Image.PreserveAspectFit + + source: Imagine.url + "dial-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.pressed}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/Dialog.qml b/src/quickcontrols2/imagine/Dialog.qml new file mode 100644 index 00000000000..b788cc3ca98 --- /dev/null +++ b/src/quickcontrols2/imagine/Dialog.qml @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.Dialog { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + background: NinePatchImage { + source: Imagine.url + "dialog-background" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + + header: Label { + text: control.title + visible: control.title + elide: Label.ElideRight + font.bold: true + padding: 12 + + background: NinePatchImage { + width: parent.width + height: parent.height + + source: Imagine.url + "dialog-title" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + } + + footer: DialogButtonBox { + visible: count > 0 + } + + T.Overlay.modal: NinePatchImage { + source: Imagine.url + "dialog-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": true} + ] + } + } + + T.Overlay.modeless: NinePatchImage { + source: Imagine.url + "dialog-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": false} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/DialogButtonBox.qml b/src/quickcontrols2/imagine/DialogButtonBox.qml new file mode 100644 index 00000000000..bdd956f1662 --- /dev/null +++ b/src/quickcontrols2/imagine/DialogButtonBox.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.DialogButtonBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + (control.count === 1 ? contentWidth * 2 : contentWidth) + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + spacing: 6 + + delegate: Button { + width: control.count === 1 ? control.availableWidth / 2 : undefined + flat: true + } + + contentItem: ListView { + implicitWidth: contentWidth + model: control.contentModel + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + } + + background: NinePatchImage { + source: Imagine.url + "dialogbuttonbox-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/Drawer.qml b/src/quickcontrols2/imagine/Drawer.qml new file mode 100644 index 00000000000..414516d3072 --- /dev/null +++ b/src/quickcontrols2/imagine/Drawer.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.Drawer { + id: control + + parent: T.Overlay.overlay + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + enter: Transition { SmoothedAnimation { velocity: 5 } } + exit: Transition { SmoothedAnimation { velocity: 5 } } + + background: NinePatchImage { + source: Imagine.url + "drawer-background" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim}, + {"top": control.edge === Qt.TopEdge}, + {"left": control.edge === Qt.LeftEdge}, + {"right": control.edge === Qt.RightEdge}, + {"bottom": control.edge === Qt.BottomEdge} + ] + } + } + + T.Overlay.modal: NinePatchImage { + source: Imagine.url + "drawer-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": true} + ] + } + } + + T.Overlay.modeless: NinePatchImage { + source: Imagine.url + "drawer-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": false} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/Frame.qml b/src/quickcontrols2/imagine/Frame.qml new file mode 100644 index 00000000000..7ba93dbceba --- /dev/null +++ b/src/quickcontrols2/imagine/Frame.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.Frame { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + background: NinePatchImage { + source: Imagine.url + "frame-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/GroupBox.qml b/src/quickcontrols2/imagine/GroupBox.qml new file mode 100644 index 00000000000..3fc99d97e11 --- /dev/null +++ b/src/quickcontrols2/imagine/GroupBox.qml @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.GroupBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitLabelWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: ((background as NinePatchImage)?.topPadding ?? 0) + (implicitLabelWidth > 0 ? implicitLabelHeight + spacing : 0) + leftPadding: ((background as NinePatchImage)?.leftPadding ?? 0) + rightPadding: ((background as NinePatchImage)?.rightPadding ?? 0) + bottomPadding: ((background as NinePatchImage)?.bottomPadding ?? 0) + + label: Label { + width: control.width + + topPadding: background.topPadding + leftPadding: background.leftPadding + rightPadding: background.rightPadding + bottomPadding: background.bottomPadding + + text: control.title + font: control.font + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + + color: control.palette.windowText + + background: NinePatchImage { + width: parent.width + height: parent.height + + source: Imagine.url + "groupbox-title" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored} + ] + } + } + } + + background: NinePatchImage { + x: -leftInset + y: control.topPadding - control.bottomPadding - topInset + width: control.width + leftInset + rightInset + height: control.height + topInset + bottomInset - control.topPadding + control.bottomPadding + + source: Imagine.url + "groupbox-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/HorizontalHeaderView.qml b/src/quickcontrols2/imagine/HorizontalHeaderView.qml new file mode 100644 index 00000000000..e52145932fe --- /dev/null +++ b/src/quickcontrols2/imagine/HorizontalHeaderView.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.HorizontalHeaderView { + id: control + + implicitWidth: syncView ? syncView.width : 0 + implicitHeight: contentHeight + + delegate: Rectangle { + // Qt6: add cellPadding (and font etc) as public API in headerview + readonly property real cellPadding: 8 + + implicitWidth: text.implicitWidth + (cellPadding * 2) + implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2)) + color: "#f6f6f6" + border.color: "#e4e4e4" + + Text { + id: text + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] + : model[control.textRole]) + : modelData + width: parent.width + height: parent.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: "#ff26282a" + } + } +} diff --git a/src/quickcontrols2/imagine/ItemDelegate.qml b/src/quickcontrols2/imagine/ItemDelegate.qml new file mode 100644 index 00000000000..d0f7b29db03 --- /dev/null +++ b/src/quickcontrols2/imagine/ItemDelegate.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.ItemDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 // ### + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.text + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.palette.text + } + + background: NinePatchImage { + source: Imagine.url + "itemdelegate-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/Label.qml b/src/quickcontrols2/imagine/Label.qml new file mode 100644 index 00000000000..da41e7065a5 --- /dev/null +++ b/src/quickcontrols2/imagine/Label.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.Label { + id: control + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + color: control.palette.windowText + linkColor: control.palette.link + + background: NinePatchImage { + source: Imagine.url + "label-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/Menu.qml b/src/quickcontrols2/imagine/Menu.qml new file mode 100644 index 00000000000..ec73df6afd2 --- /dev/null +++ b/src/quickcontrols2/imagine/Menu.qml @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl +import QtQuick.Window + +T.Menu { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topMargin: background ? background.topInset : 0 + leftMargin: background ? background.leftInset : 0 + rightMargin: background ? background.rightInset : 0 + bottomMargin: background ? background.bottomInset : 0 + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + delegate: MenuItem { } + + contentItem: ListView { + implicitHeight: contentHeight + model: control.contentModel + interactive: contentHeight + control.topPadding + control.bottomPadding > control.height + clip: true + currentIndex: control.currentIndex + + T.ScrollIndicator.vertical: ScrollIndicator { } + } + + background: NinePatchImage { + source: Imagine.url + "menu-background" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + + T.Overlay.modal: NinePatchImage { + source: Imagine.url + "menu-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": true} + ] + } + } + + T.Overlay.modeless: NinePatchImage { + source: Imagine.url + "menu-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": false} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/MenuItem.qml b/src/quickcontrols2/imagine/MenuItem.qml new file mode 100644 index 00000000000..c17c0ba7b1c --- /dev/null +++ b/src/quickcontrols2/imagine/MenuItem.qml @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.MenuItem { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 6 // ### + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.windowText + + contentItem: IconLabel { + readonly property real arrowPadding: control.subMenu && control.arrow ? control.arrow.width + control.spacing : 0 + readonly property real indicatorPadding: control.checkable && control.indicator ? control.indicator.width + control.spacing : 0 + leftPadding: !control.mirrored ? indicatorPadding : arrowPadding + rightPadding: control.mirrored ? indicatorPadding : arrowPadding + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.palette.windowText + } + + arrow: Image { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + visible: control.subMenu + source: Imagine.url + "menuitem-arrow" + ImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + indicator: Image { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + visible: control.checkable + source: Imagine.url + "menuitem-indicator" + ImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + background: NinePatchImage { + source: Imagine.url + "menuitem-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/MenuSeparator.qml b/src/quickcontrols2/imagine/MenuSeparator.qml new file mode 100644 index 00000000000..42d1812fa55 --- /dev/null +++ b/src/quickcontrols2/imagine/MenuSeparator.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.MenuSeparator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + contentItem: NinePatchImage { + source: Imagine.url + "menuseparator-separator" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored} + ] + } + } + + background: NinePatchImage { + source: Imagine.url + "menuseparator-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/Page.qml b/src/quickcontrols2/imagine/Page.qml new file mode 100644 index 00000000000..1b77112f3d5 --- /dev/null +++ b/src/quickcontrols2/imagine/Page.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.Page { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + background: NinePatchImage { + source: Imagine.url + "page-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/PageIndicator.qml b/src/quickcontrols2/imagine/PageIndicator.qml new file mode 100644 index 00000000000..7f576c5d054 --- /dev/null +++ b/src/quickcontrols2/imagine/PageIndicator.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.PageIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + delegate: Image { + source: Imagine.url + "pageindicator-delegate" + ImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": pressed}, + {"current": index === control.currentIndex}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} // ### TODO: context property + ] + } + } + + contentItem: Row { + spacing: control.spacing + + Repeater { + model: control.count + delegate: control.delegate + } + } + + background: NinePatchImage { + source: Imagine.url + "pageindicator-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/Pane.qml b/src/quickcontrols2/imagine/Pane.qml new file mode 100644 index 00000000000..4fdfaa18cee --- /dev/null +++ b/src/quickcontrols2/imagine/Pane.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.Pane { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + background: NinePatchImage { + source: Imagine.url + "pane-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/Popup.qml b/src/quickcontrols2/imagine/Popup.qml new file mode 100644 index 00000000000..bc7e544be7f --- /dev/null +++ b/src/quickcontrols2/imagine/Popup.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.Popup { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : undefined + leftPadding: background ? background.leftPadding : undefined + rightPadding: background ? background.rightPadding : undefined + bottomPadding: background ? background.bottomPadding : undefined + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + background: NinePatchImage { + source: Imagine.url + "popup-background" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + + T.Overlay.modal: NinePatchImage { + source: Imagine.url + "popup-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": true} + ] + } + } + + T.Overlay.modeless: NinePatchImage { + source: Imagine.url + "popup-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": false} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/ProgressBar.qml b/src/quickcontrols2/imagine/ProgressBar.qml new file mode 100644 index 00000000000..12ef501e720 --- /dev/null +++ b/src/quickcontrols2/imagine/ProgressBar.qml @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.ProgressBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + contentItem: Item { + implicitWidth: control.indeterminate ? animation.implicitWidth || progress.implicitWidth : progress.implicitWidth + implicitHeight: control.indeterminate ? animation.implicitHeight || progress.implicitHeight : progress.implicitHeight + scale: control.mirrored ? -1 : 1 + + readonly property bool hasMask: mask.status !== Image.Null + + readonly property NinePatchImage progress: NinePatchImage { + parent: control.contentItem + width: control.position * parent.width + height: parent.height + visible: !control.indeterminate && !control.contentItem.hasMask + + source: Imagine.url + "progressbar-progress" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"indeterminate": control.indeterminate}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + readonly property AnimatedImage animation: AnimatedImage { + parent: control.contentItem + width: parent.width + height: parent.height + playing: control.indeterminate + visible: control.indeterminate && !control.contentItem.hasMask + + source: Imagine.url + "progressbar-animation" + AnimatedImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + readonly property NinePatchImage mask: NinePatchImage { + width: control.availableWidth + height: control.availableHeight + visible: false + + source: Imagine.url + "progressbar-mask" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"indeterminate": control.indeterminate}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + readonly property OpacityMask effect: OpacityMask { + parent: control.contentItem + width: source.width + height: source.height + source: control.indeterminate ? control.contentItem.animation : control.contentItem.progress + + maskSource: ShaderEffectSource { + sourceItem: control.contentItem.mask + sourceRect: Qt.rect(0, 0, control.contentItem.effect.width, control.contentItem.effect.height) + } + } + } + + background: NinePatchImage { + source: Imagine.url + "progressbar-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"indeterminate": control.indeterminate}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/RadioButton.qml b/src/quickcontrols2/imagine/RadioButton.qml new file mode 100644 index 00000000000..8c915443d14 --- /dev/null +++ b/src/quickcontrols2/imagine/RadioButton.qml @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.RadioButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 6 // ### + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + indicator: Image { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + source: Imagine.url + "radiobutton-indicator" + ImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.palette.windowText + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + background: NinePatchImage { + source: Imagine.url + "radiobutton-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/RadioDelegate.qml b/src/quickcontrols2/imagine/RadioDelegate.qml new file mode 100644 index 00000000000..b322e332c3d --- /dev/null +++ b/src/quickcontrols2/imagine/RadioDelegate.qml @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.RadioDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 // ### + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.text + + indicator: Image { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + source: Imagine.url + "radiodelegate-indicator" + ImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + contentItem: IconLabel { + leftPadding: control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: !control.mirrored ? control.indicator.width + control.spacing : 0 + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.palette.text + } + + background: NinePatchImage { + source: Imagine.url + "radiodelegate-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/RangeSlider.qml b/src/quickcontrols2/imagine/RangeSlider.qml new file mode 100644 index 00000000000..6526bb60fd0 --- /dev/null +++ b/src/quickcontrols2/imagine/RangeSlider.qml @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.RangeSlider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + first.implicitHandleWidth + leftPadding + rightPadding, + second.implicitHandleWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + first.implicitHandleHeight + topPadding + bottomPadding, + second.implicitHandleHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + first.handle: Image { + x: control.leftPadding + (control.horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height)) + + source: control.Imagine.url + "rangeslider-handle" + ImageSelector on source { + states: [ + {"first": true}, + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"pressed": control.first.pressed}, + {"focused": control.first.handle.activeFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.first.hovered} + ] + } + } + + second.handle: Image { + x: control.leftPadding + (control.horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height)) + + source: control.Imagine.url + "rangeslider-handle" + ImageSelector on source { + states: [ + {"second": true}, + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"pressed": control.second.pressed}, + {"focused": control.second.handle.activeFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.second.hovered} + ] + } + } + + background: NinePatchImage { + scale: control.horizontal && control.mirrored ? -1 : 1 + + source: control.Imagine.url + "rangeslider-background" + NinePatchImageSelector on source { + states: [ + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + + NinePatchImage { + x: control.horizontal ? control.first.handle.width / 2 + control.first.position * (parent.width - control.first.handle.width) : (parent.width - width) / 2 + y: control.horizontal ? (parent.height - height) / 2 : control.first.handle.height / 2 + control.second.visualPosition * (parent.height - control.first.handle.height) + width: control.horizontal ? control.second.position * (parent.width - control.first.handle.width) - control.first.position * (parent.width - control.first.handle.width) : parent.width + height: control.vertical ? control.second.position * (parent.height - control.first.handle.height) - control.first.position * (parent.height - control.first.handle.height): parent.height + + source: control.Imagine.url + "rangeslider-progress" + NinePatchImageSelector on source { + states: [ + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + } +} diff --git a/src/quickcontrols2/imagine/RoundButton.qml b/src/quickcontrols2/imagine/RoundButton.qml new file mode 100644 index 00000000000..2485266740d --- /dev/null +++ b/src/quickcontrols2/imagine/RoundButton.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.RoundButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + icon.width: 24 + icon.height: 24 + icon.color: control.enabled && control.flat && control.highlighted ? control.palette.highlight + : control.enabled && (control.down || control.checked || control.highlighted) && !control.flat + ? control.palette.brightText : control.flat ? control.palette.windowText : control.palette.buttonText + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.enabled && control.flat && control.highlighted ? control.palette.highlight + : control.enabled && (control.down || control.checked || control.highlighted) && !control.flat + ? control.palette.brightText : control.flat ? control.palette.windowText : control.palette.buttonText + } + + background: NinePatchImage { + // ### TODO: radius? + source: Imagine.url + "roundbutton-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"checkable": control.checkable}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"flat": control.flat}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/ScrollBar.qml b/src/quickcontrols2/imagine/ScrollBar.qml new file mode 100644 index 00000000000..69d7cd59715 --- /dev/null +++ b/src/quickcontrols2/imagine/ScrollBar.qml @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.ScrollBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + visible: control.policy !== T.ScrollBar.AlwaysOff + minimumSize: orientation === Qt.Horizontal ? height / width : width / height + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + contentItem: NinePatchImage { + width: control.availableWidth + height: control.availableHeight + + source: Imagine.url + "scrollbar-handle" + NinePatchImageSelector on source { + states: [ + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"interactive": control.interactive}, + {"pressed": control.pressed}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + opacity: 0.0 + } + + background: NinePatchImage { + source: Imagine.url + "scrollbar-background" + NinePatchImageSelector on source { + states: [ + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"interactive": control.interactive}, + {"pressed": control.pressed}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + opacity: 0.0 + } + + states: [ + State { + name: "active" + when: control.policy === T.ScrollBar.AlwaysOn || (control.active && control.size < 1.0) + } + ] + + transitions: [ + Transition { + to: "active" + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 1.0 } + }, + Transition { + from: "active" + SequentialAnimation { + PropertyAction{ targets: [control.contentItem, control.background]; property: "opacity"; value: 1.0 } + PauseAnimation { duration: 3000 } + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 0.0 } + } + } + ] +} diff --git a/src/quickcontrols2/imagine/ScrollIndicator.qml b/src/quickcontrols2/imagine/ScrollIndicator.qml new file mode 100644 index 00000000000..14fb507cec7 --- /dev/null +++ b/src/quickcontrols2/imagine/ScrollIndicator.qml @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.ScrollIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + contentItem: NinePatchImage { + width: control.availableWidth + height: control.availableHeight + + source: Imagine.url + "scrollindicator-handle" + NinePatchImageSelector on source { + states: [ + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + opacity: 0.0 + } + + background: NinePatchImage { + source: Imagine.url + "scrollindicator-background" + NinePatchImageSelector on source { + states: [ + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + opacity: 0.0 + } + + states: [ + State { + name: "active" + when: (control.active && control.size < 1.0) + } + ] + + transitions: [ + Transition { + to: "active" + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 1.0 } + }, + Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 5000 } + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 0.0 } + } + } + ] +} diff --git a/src/quickcontrols2/imagine/ScrollView.qml b/src/quickcontrols2/imagine/ScrollView.qml new file mode 100644 index 00000000000..80427e9d271 --- /dev/null +++ b/src/quickcontrols2/imagine/ScrollView.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.ScrollView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + T.ScrollBar.vertical: ScrollBar { + parent: control + x: control.mirrored ? 0 : control.width - width + y: control.topPadding + height: control.availableHeight + active: control.T.ScrollBar.horizontal.active + } + + T.ScrollBar.horizontal: ScrollBar { + parent: control + x: control.leftPadding + y: control.height - height + width: control.availableWidth + active: control.T.ScrollBar.vertical.active + } + + background: NinePatchImage { + source: Imagine.path + "scrollview-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/SelectionRectangle.qml b/src/quickcontrols2/imagine/SelectionRectangle.qml new file mode 100644 index 00000000000..2dbce02b635 --- /dev/null +++ b/src/quickcontrols2/imagine/SelectionRectangle.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.SelectionRectangle { + id: control + + topLeftHandle: handle + bottomRightHandle: handle + + Component { + id: handle + Image { + id: image + source: Imagine.url + "slider-handle" + visible: SelectionRectangle.control.active + ImageSelector on source { + states: [ + {"vertical": false}, + {"horizontal": true}, + {"disabled": false}, + {"pressed": tapHandler.pressed || image.SelectionRectangle.dragging}, + {"focused": true}, + {"mirrored": false}, + {"hovered": hoverHandler.hovered} + ] + } + + HoverHandler { + id: hoverHandler + } + + TapHandler { + id: tapHandler + } + } + } +} diff --git a/src/quickcontrols2/imagine/Slider.qml b/src/quickcontrols2/imagine/Slider.qml new file mode 100644 index 00000000000..08b81e23698 --- /dev/null +++ b/src/quickcontrols2/imagine/Slider.qml @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.Slider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitHandleWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitHandleHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + handle: Image { + x: Math.round(control.leftPadding + (control.horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2)) + y: Math.round(control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height))) + + source: control.Imagine.url + "slider-handle" + ImageSelector on source { + states: [ + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"pressed": control.pressed}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + + background: NinePatchImage { + scale: control.horizontal && control.mirrored ? -1 : 1 + + source: control.Imagine.url + "slider-background" + NinePatchImageSelector on source { + states: [ + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + + NinePatchImage { + x: control.horizontal ? 0 : (parent.width - width) / 2 + y: control.horizontal + ? (parent.height - height) / 2 + : control.handle.height / 2 + control.visualPosition * (parent.height - control.handle.height) + width: control.horizontal + ? control.handle.width / 2 + control.position * (parent.width - control.handle.width) + : parent.width + height: control.vertical + ? control.handle.height / 2 + control.position * (parent.height - control.handle.height) + : parent.height + + source: control.Imagine.url + "slider-progress" + NinePatchImageSelector on source { + states: [ + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + } +} diff --git a/src/quickcontrols2/imagine/SpinBox.qml b/src/quickcontrols2/imagine/SpinBox.qml new file mode 100644 index 00000000000..ba61354faee --- /dev/null +++ b/src/quickcontrols2/imagine/SpinBox.qml @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.SpinBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentItem.implicitWidth + 2 * padding + + up.implicitIndicatorWidth + + down.implicitIndicatorWidth) + implicitHeight: Math.max(implicitContentHeight + topPadding + bottomPadding, + implicitBackgroundHeight, + up.implicitIndicatorHeight, + down.implicitIndicatorHeight) + + topPadding: background ? background.topPadding : 0 + leftPadding: (background ? background.leftPadding : 0) + (control.mirrored ? (up.indicator ? up.indicator.width : 0) : (down.indicator ? down.indicator.width : 0)) + rightPadding: (background ? background.rightPadding : 0) + (control.mirrored ? (down.indicator ? down.indicator.width : 0) : (up.indicator ? up.indicator.width : 0)) + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + + contentItem: TextInput { + z: 2 + text: control.displayText + opacity: control.enabled ? 1 : 0.3 + + font: control.font + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + + readOnly: !control.editable + validator: control.validator + inputMethodHints: control.inputMethodHints + + NinePatchImage { + z: -1 + width: control.width + height: control.height + visible: control.editable + + source: Imagine.url + "spinbox-editor" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"focused": control.activeFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } + } + + up.indicator: NinePatchImage { + x: control.mirrored ? 0 : control.width - width + height: control.height + + source: Imagine.url + "spinbox-indicator" + NinePatchImageSelector on source { + states: [ + {"up": true}, + {"disabled": !control.up.indicator.enabled}, + {"editable": control.editable}, + {"pressed": control.up.pressed}, + {"focused": control.activeFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.up.hovered} + ] + } + } + + down.indicator: NinePatchImage { + x: control.mirrored ? control.width - width : 0 + height: control.height + + source: Imagine.url + "spinbox-indicator" + NinePatchImageSelector on source { + states: [ + {"down": true}, + {"disabled": !control.down.indicator.enabled}, + {"editable": control.editable}, + {"pressed": control.down.pressed}, + {"focused": control.activeFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.down.hovered} + ] + } + } + + background: NinePatchImage { + source: Imagine.url + "spinbox-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"editable": control.editable}, + {"focused": control.activeFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/SplitView.qml b/src/quickcontrols2/imagine/SplitView.qml new file mode 100644 index 00000000000..36e1b2134a4 --- /dev/null +++ b/src/quickcontrols2/imagine/SplitView.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.SplitView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + handle: NinePatchImage { + source: Imagine.url + "splitview-handle" + NinePatchImageSelector on source { + states: [ + {"vertical": control.orientation === Qt.Vertical}, + {"horizontal":control.orientation === Qt.Horizontal}, + {"disabled": !control.enabled}, + {"pressed": T.SplitHandle.pressed}, + {"mirrored": control.mirrored}, + {"hovered": T.SplitHandle.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/StackView.qml b/src/quickcontrols2/imagine/StackView.qml new file mode 100644 index 00000000000..a9ddac66d6d --- /dev/null +++ b/src/quickcontrols2/imagine/StackView.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.StackView { + id: control + + implicitWidth: implicitBackgroundWidth + implicitHeight: implicitBackgroundHeight + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + popEnter: Transition { + XAnimator { from: (control.mirrored ? -1 : 1) * -control.width; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + + popExit: Transition { + XAnimator { from: 0; to: (control.mirrored ? -1 : 1) * control.width; duration: 400; easing.type: Easing.OutCubic } + } + + pushEnter: Transition { + XAnimator { from: (control.mirrored ? -1 : 1) * control.width; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + + pushExit: Transition { + XAnimator { from: 0; to: (control.mirrored ? -1 : 1) * -control.width; duration: 400; easing.type: Easing.OutCubic } + } + + replaceEnter: Transition { + XAnimator { from: (control.mirrored ? -1 : 1) * control.width; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + + replaceExit: Transition { + XAnimator { from: 0; to: (control.mirrored ? -1 : 1) * -control.width; duration: 400; easing.type: Easing.OutCubic } + } + + background: NinePatchImage { + source: Imagine.url + "stackview-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"mirrored": control.mirrored} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/SwipeDelegate.qml b/src/quickcontrols2/imagine/SwipeDelegate.qml new file mode 100644 index 00000000000..05e9e7d4a92 --- /dev/null +++ b/src/quickcontrols2/imagine/SwipeDelegate.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.SwipeDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 // ### + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.text + + swipe.transition: Transition { SmoothedAnimation { velocity: 3; easing.type: Easing.InOutCubic } } + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.palette.text + } + + background: NinePatchImage { + source: Imagine.url + "swipedelegate-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/SwipeView.qml b/src/quickcontrols2/imagine/SwipeView.qml new file mode 100644 index 00000000000..12cafbb8158 --- /dev/null +++ b/src/quickcontrols2/imagine/SwipeView.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.SwipeView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + contentItem: ListView { + model: control.contentModel + interactive: control.interactive + currentIndex: control.currentIndex + focus: control.focus + + spacing: control.spacing + orientation: control.orientation + snapMode: ListView.SnapOneItem + boundsBehavior: Flickable.StopAtBounds + + highlightRangeMode: ListView.StrictlyEnforceRange + preferredHighlightBegin: 0 + preferredHighlightEnd: 0 + highlightMoveDuration: 250 + } + + background: NinePatchImage { + source: Imagine.url + "swipeview-background" + NinePatchImageSelector on source { + states: [ + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"interactive": control.interactive}, + {"focused": control.contentItem.activeFocus}, + {"mirrored": control.mirrored} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/Switch.qml b/src/quickcontrols2/imagine/Switch.qml new file mode 100644 index 00000000000..a7d83998ae6 --- /dev/null +++ b/src/quickcontrols2/imagine/Switch.qml @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.Switch { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 6 // ### + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + indicator: NinePatchImage { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + width: Math.max(implicitWidth, handle.leftPadding && handle.rightPadding ? handle.implicitWidth : 2 * handle.implicitWidth) + height: Math.max(implicitHeight, handle.implicitHeight) + + source: control.Imagine.url + "switch-indicator" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + + property NinePatchImage handle: NinePatchImage { + readonly property real minPos: parent.leftPadding - leftPadding + readonly property real maxPos: parent.width - width + rightPadding - parent.rightPadding + readonly property real dragPos: control.visualPosition * parent.width - (width / 2) + + parent: control.indicator + + x: Math.max(minPos, Math.min(maxPos, control.visualPosition * parent.width - (width / 2))) + y: (parent.height - height) / 2 + + source: control.Imagine.url + "switch-handle" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + + Behavior on x { + enabled: !control.down + SmoothedAnimation { velocity: 200 } + } + } + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.palette.windowText + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + background: NinePatchImage { + source: control.Imagine.url + "switch-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/SwitchDelegate.qml b/src/quickcontrols2/imagine/SwitchDelegate.qml new file mode 100644 index 00000000000..4c29ecd8598 --- /dev/null +++ b/src/quickcontrols2/imagine/SwitchDelegate.qml @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.SwitchDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 // ### + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.text + + indicator: NinePatchImage { + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + width: Math.max(implicitWidth, handle.leftPadding && handle.rightPadding ? handle.implicitWidth : 2 * handle.implicitWidth) + height: Math.max(implicitHeight, handle.implicitHeight) + + source: control.Imagine.url + "switchdelegate-indicator" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + + property NinePatchImage handle: NinePatchImage { + readonly property real minPos: parent.leftPadding - leftPadding + readonly property real maxPos: parent.width - width + rightPadding - parent.rightPadding + readonly property real dragPos: control.visualPosition * parent.width - (width / 2) + + parent: control.indicator + + x: Math.max(minPos, Math.min(maxPos, control.visualPosition * parent.width - (width / 2))) + y: (parent.height - height) / 2 + + source: control.Imagine.url + "switchdelegate-handle" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + + Behavior on x { + enabled: !control.down + SmoothedAnimation { velocity: 200 } + } + } + } + + contentItem: IconLabel { + leftPadding: control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: !control.mirrored ? control.indicator.width + control.spacing : 0 + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.palette.text + } + + background: NinePatchImage { + source: control.Imagine.url + "switchdelegate-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/TabBar.qml b/src/quickcontrols2/imagine/TabBar.qml new file mode 100644 index 00000000000..26c30e926eb --- /dev/null +++ b/src/quickcontrols2/imagine/TabBar.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.TabBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + contentItem: ListView { + model: control.contentModel + currentIndex: control.currentIndex + + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + flickableDirection: Flickable.AutoFlickIfNeeded + snapMode: ListView.SnapToItem + + highlightMoveDuration: 0 + highlightRangeMode: ListView.ApplyRange + preferredHighlightBegin: 48 + preferredHighlightEnd: width - 48 + } + + background: NinePatchImage { + source: Imagine.url + "tabbar-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"header": control.position === T.TabBar.Header }, + {"footer": control.position === T.TabBar.Footer }, + {"mirrored": control.mirrored} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/TabButton.qml b/src/quickcontrols2/imagine/TabButton.qml new file mode 100644 index 00000000000..dff0024779a --- /dev/null +++ b/src/quickcontrols2/imagine/TabButton.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.TabButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + spacing: 6 // ### + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.buttonText + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.palette.buttonText + } + + background: NinePatchImage { + source: Imagine.url + "tabbutton-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/TextArea.qml b/src/quickcontrols2/imagine/TextArea.qml new file mode 100644 index 00000000000..1309d7793a8 --- /dev/null +++ b/src/quickcontrols2/imagine/TextArea.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.TextArea { + id: control + + implicitWidth: Math.max(contentWidth + leftPadding + rightPadding, + implicitBackgroundWidth + leftInset + rightInset, + placeholder.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(contentHeight + topPadding + bottomPadding, + implicitBackgroundHeight + topInset + bottomInset, + placeholder.implicitHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + verticalAlignment: Qt.AlignVCenter + placeholderTextColor: control.palette.placeholderText + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + verticalAlignment: control.verticalAlignment + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + elide: Text.ElideRight + renderType: control.renderType + } + + background: NinePatchImage { + source: Imagine.url + "textarea-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"focused": control.activeFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/TextField.qml b/src/quickcontrols2/imagine/TextField.qml new file mode 100644 index 00000000000..f2ae0ff8c35 --- /dev/null +++ b/src/quickcontrols2/imagine/TextField.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.TextField { + id: control + + implicitWidth: implicitBackgroundWidth + leftInset + rightInset + || Math.max(contentWidth, placeholder.implicitWidth) + leftPadding + rightPadding + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding, + placeholder.implicitHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + placeholderTextColor: control.palette.placeholderText + verticalAlignment: Qt.AlignVCenter + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + verticalAlignment: control.verticalAlignment + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + elide: Text.ElideRight + renderType: control.renderType + } + + background: NinePatchImage { + source: Imagine.url + "textfield-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"focused": control.activeFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/ToolBar.qml b/src/quickcontrols2/imagine/ToolBar.qml new file mode 100644 index 00000000000..4a343e3c038 --- /dev/null +++ b/src/quickcontrols2/imagine/ToolBar.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.ToolBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + background: NinePatchImage { + source: Imagine.url + "toolbar-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"header": control.position === T.ToolBar.Header }, + {"footer": control.position === T.ToolBar.Footer }, + {"mirrored": control.mirrored} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/ToolButton.qml b/src/quickcontrols2/imagine/ToolButton.qml new file mode 100644 index 00000000000..5c70693ac94 --- /dev/null +++ b/src/quickcontrols2/imagine/ToolButton.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.ToolButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + spacing: 6 // ### + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.buttonText + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.palette.buttonText + } + + background: NinePatchImage { + source: Imagine.url + "toolbutton-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"pressed": control.down}, + {"checked": control.checked}, + {"checkable": control.checkable}, + {"focused": control.visualFocus}, + {"highlighted": control.highlighted}, + {"flat": control.flat}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/ToolSeparator.qml b/src/quickcontrols2/imagine/ToolSeparator.qml new file mode 100644 index 00000000000..962c14c7415 --- /dev/null +++ b/src/quickcontrols2/imagine/ToolSeparator.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.ToolSeparator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + contentItem: NinePatchImage { + source: Imagine.url + "toolseparator-separator" + NinePatchImageSelector on source { + states: [ + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"mirrored": control.mirrored} + ] + } + } + + background: NinePatchImage { + source: Imagine.url + "toolseparator-background" + NinePatchImageSelector on source { + states: [ + {"vertical": control.vertical}, + {"horizontal": control.horizontal}, + {"disabled": !control.enabled}, + {"mirrored": control.mirrored} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/ToolTip.qml b/src/quickcontrols2/imagine/ToolTip.qml new file mode 100644 index 00000000000..f52614000ee --- /dev/null +++ b/src/quickcontrols2/imagine/ToolTip.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.ToolTip { + id: control + + x: parent ? (parent.width - implicitWidth) / 2 : 0 - (background ? background.leftInset : 0) + y: -implicitHeight - (background ? background.topInset : 0) + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topMargin: background ? background.topInset : 0 + leftMargin: background ? background.leftInset : 0 + rightMargin: background ? background.rightInset : 0 + bottomMargin: background ? background.bottomInset : 0 + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnReleaseOutsideParent + + contentItem: Text { + text: control.text + font: control.font + wrapMode: Text.Wrap + color: control.palette.toolTipText + } + + background: NinePatchImage { + source: Imagine.url + "tooltip-background" + NinePatchImageSelector on source { + states: [ + // ### + ] + } + } +} diff --git a/src/quickcontrols2/imagine/Tumbler.qml b/src/quickcontrols2/imagine/Tumbler.qml new file mode 100644 index 00000000000..6cd78fb6cc1 --- /dev/null +++ b/src/quickcontrols2/imagine/Tumbler.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +T.Tumbler { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + delegate: Text { + text: modelData + font: control.font + color: control.palette.text + opacity: (1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2)) * (control.enabled ? 1 : 0.6) + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + required property var modelData + required property int index + } + + contentItem: TumblerView { + implicitWidth: 60 + implicitHeight: 200 + model: control.model + delegate: control.delegate + path: Path { + startX: control.contentItem.width / 2 + startY: -control.contentItem.delegateHeight / 2 + PathLine { + x: control.contentItem.width / 2 + y: (control.visibleItemCount + 1) * control.contentItem.delegateHeight - control.contentItem.delegateHeight / 2 + } + } + + property real delegateHeight: control.availableHeight / control.visibleItemCount + } + + background: NinePatchImage { + source: Imagine.url + "tumbler-background" + NinePatchImageSelector on source { + states: [ + {"disabled": !control.enabled}, + {"focused": control.visualFocus}, + {"mirrored": control.mirrored}, + {"hovered": control.enabled && control.hovered} + ] + } + } +} diff --git a/src/quickcontrols2/imagine/VerticalHeaderView.qml b/src/quickcontrols2/imagine/VerticalHeaderView.qml new file mode 100644 index 00000000000..7c057e01e24 --- /dev/null +++ b/src/quickcontrols2/imagine/VerticalHeaderView.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.VerticalHeaderView { + id: control + + implicitWidth: contentWidth + implicitHeight: syncView ? syncView.height : 0 + + delegate: Rectangle { + // Qt6: add cellPadding (and font etc) as public API in headerview + readonly property real cellPadding: 8 + + implicitWidth: Math.max(control.width, text.implicitWidth + (cellPadding * 2)) + implicitHeight: text.implicitHeight + (cellPadding * 2) + color: "#f6f6f6" + border.color: "#e4e4e4" + + Text { + id: text + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] + : model[control.textRole]) + : modelData + width: parent.width + height: parent.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: "#ff26282a" + } + } +} diff --git a/src/quickcontrols2/imagine/design/9-patch-export.sketchplugin/Contents/Sketch/9-patch-export.js b/src/quickcontrols2/imagine/design/9-patch-export.sketchplugin/Contents/Sketch/9-patch-export.js new file mode 100644 index 00000000000..a7f9a4598de --- /dev/null +++ b/src/quickcontrols2/imagine/design/9-patch-export.sketchplugin/Contents/Sketch/9-patch-export.js @@ -0,0 +1,24 @@ +// 9-patch export +// +// This plugin crops upscaled 9-patch PNG assets when exported from Sketch, +// to ensure that 9-patch borders remain 1px wide when upscaled. +// +function onExportSlices(context) { + var exports = context.actionContext.exports; + for (var i = 0; i < exports.count(); ++i) { + var name = exports[i].request.name(); + var scale = exports[i].request.scale(); + if (scale > 1 && name.endsWith(".9")) + cropAsset(exports[i].path, scale - 1); + } +} + +function cropAsset(path, inset) { + var url = NSURL.fileURLWithPath(path); + var img = CIImage.imageWithContentsOfURL(url); + var rect = NSInsetRect(img.extent(), inset, inset); + var cropped = img.imageByCroppingToRect(rect); + var rep = NSBitmapImageRep.alloc().initWithCIImage(cropped); + var data = rep.PNGRepresentationWithInterlaced(false); + data.writeToFile(path); +} diff --git a/src/quickcontrols2/imagine/design/9-patch-export.sketchplugin/Contents/Sketch/manifest.json b/src/quickcontrols2/imagine/design/9-patch-export.sketchplugin/Contents/Sketch/manifest.json new file mode 100644 index 00000000000..40807aa3d5d --- /dev/null +++ b/src/quickcontrols2/imagine/design/9-patch-export.sketchplugin/Contents/Sketch/manifest.json @@ -0,0 +1,19 @@ +{ + "name" : "9-patch export", + "description" : "Crops upscaled 9-patch PNG assets when exported from Sketch.", + "version" : "0.1", + "identifier" : "org.qt-project.sketch.9-patch-export", + "author" : "The Qt Project", + "commands" : [ + { + "name" : "9-patch export", + "identifier" : "9-patch-export", + "script" : "9-patch-export.js", + "handlers" : { + "actions" : { + "ExportSlices": "onExportSlices", + }, + }, + }, + ], +} diff --git a/src/quickcontrols2/imagine/design/imagine.sketch b/src/quickcontrols2/imagine/design/imagine.sketch new file mode 100644 index 00000000000..f3535b372bc Binary files /dev/null and b/src/quickcontrols2/imagine/design/imagine.sketch differ diff --git a/src/quickcontrols2/imagine/images/applicationwindow-background.png b/src/quickcontrols2/imagine/images/applicationwindow-background.png new file mode 100644 index 00000000000..2d8d70f2880 Binary files /dev/null and b/src/quickcontrols2/imagine/images/applicationwindow-background.png differ diff --git a/src/quickcontrols2/imagine/images/applicationwindow-background@2x.png b/src/quickcontrols2/imagine/images/applicationwindow-background@2x.png new file mode 100644 index 00000000000..18fbaa4c63f Binary files /dev/null and b/src/quickcontrols2/imagine/images/applicationwindow-background@2x.png differ diff --git a/src/quickcontrols2/imagine/images/applicationwindow-background@3x.png b/src/quickcontrols2/imagine/images/applicationwindow-background@3x.png new file mode 100644 index 00000000000..241232b1e04 Binary files /dev/null and b/src/quickcontrols2/imagine/images/applicationwindow-background@3x.png differ diff --git a/src/quickcontrols2/imagine/images/applicationwindow-background@4x.png b/src/quickcontrols2/imagine/images/applicationwindow-background@4x.png new file mode 100644 index 00000000000..8eb1b1ecc13 Binary files /dev/null and b/src/quickcontrols2/imagine/images/applicationwindow-background@4x.png differ diff --git a/src/quickcontrols2/imagine/images/applicationwindow-overlay-modal.png b/src/quickcontrols2/imagine/images/applicationwindow-overlay-modal.png new file mode 100644 index 00000000000..d4a43d1c705 Binary files /dev/null and b/src/quickcontrols2/imagine/images/applicationwindow-overlay-modal.png differ diff --git a/src/quickcontrols2/imagine/images/applicationwindow-overlay-modal@2x.png b/src/quickcontrols2/imagine/images/applicationwindow-overlay-modal@2x.png new file mode 100644 index 00000000000..c9a8f4124bd Binary files /dev/null and b/src/quickcontrols2/imagine/images/applicationwindow-overlay-modal@2x.png differ diff --git a/src/quickcontrols2/imagine/images/applicationwindow-overlay-modal@3x.png b/src/quickcontrols2/imagine/images/applicationwindow-overlay-modal@3x.png new file mode 100644 index 00000000000..4a1084a9190 Binary files /dev/null and b/src/quickcontrols2/imagine/images/applicationwindow-overlay-modal@3x.png differ diff --git a/src/quickcontrols2/imagine/images/applicationwindow-overlay-modal@4x.png b/src/quickcontrols2/imagine/images/applicationwindow-overlay-modal@4x.png new file mode 100644 index 00000000000..b92e600daee Binary files /dev/null and b/src/quickcontrols2/imagine/images/applicationwindow-overlay-modal@4x.png differ diff --git a/src/quickcontrols2/imagine/images/applicationwindow-overlay.png b/src/quickcontrols2/imagine/images/applicationwindow-overlay.png new file mode 100644 index 00000000000..b7da23c00fe Binary files /dev/null and b/src/quickcontrols2/imagine/images/applicationwindow-overlay.png differ diff --git a/src/quickcontrols2/imagine/images/applicationwindow-overlay@2x.png b/src/quickcontrols2/imagine/images/applicationwindow-overlay@2x.png new file mode 100644 index 00000000000..23828d5a1cf Binary files /dev/null and b/src/quickcontrols2/imagine/images/applicationwindow-overlay@2x.png differ diff --git a/src/quickcontrols2/imagine/images/applicationwindow-overlay@3x.png b/src/quickcontrols2/imagine/images/applicationwindow-overlay@3x.png new file mode 100644 index 00000000000..d9d53828675 Binary files /dev/null and b/src/quickcontrols2/imagine/images/applicationwindow-overlay@3x.png differ diff --git a/src/quickcontrols2/imagine/images/applicationwindow-overlay@4x.png b/src/quickcontrols2/imagine/images/applicationwindow-overlay@4x.png new file mode 100644 index 00000000000..a76c1a3a71d Binary files /dev/null and b/src/quickcontrols2/imagine/images/applicationwindow-overlay@4x.png differ diff --git a/src/quickcontrols2/imagine/images/busyindicator-animation.webp b/src/quickcontrols2/imagine/images/busyindicator-animation.webp new file mode 100644 index 00000000000..ebf04c4a0c6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/busyindicator-animation.webp differ diff --git a/src/quickcontrols2/imagine/images/busyindicator-animation@2x.webp b/src/quickcontrols2/imagine/images/busyindicator-animation@2x.webp new file mode 100644 index 00000000000..43805a0bdc5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/busyindicator-animation@2x.webp differ diff --git a/src/quickcontrols2/imagine/images/busyindicator-animation@3x.webp b/src/quickcontrols2/imagine/images/busyindicator-animation@3x.webp new file mode 100644 index 00000000000..b700b81f83b Binary files /dev/null and b/src/quickcontrols2/imagine/images/busyindicator-animation@3x.webp differ diff --git a/src/quickcontrols2/imagine/images/busyindicator-animation@4x.webp b/src/quickcontrols2/imagine/images/busyindicator-animation@4x.webp new file mode 100644 index 00000000000..bfaa8df9214 Binary files /dev/null and b/src/quickcontrols2/imagine/images/busyindicator-animation@4x.webp differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked-disabled.9.png b/src/quickcontrols2/imagine/images/button-background-checked-disabled.9.png new file mode 100644 index 00000000000..8196289cc28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked-disabled@2x.9.png b/src/quickcontrols2/imagine/images/button-background-checked-disabled@2x.9.png new file mode 100644 index 00000000000..76cd44908b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked-disabled@3x.9.png b/src/quickcontrols2/imagine/images/button-background-checked-disabled@3x.9.png new file mode 100644 index 00000000000..8bd6259a475 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked-disabled@4x.9.png b/src/quickcontrols2/imagine/images/button-background-checked-disabled@4x.9.png new file mode 100644 index 00000000000..3e08152013b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked-focused.9.png b/src/quickcontrols2/imagine/images/button-background-checked-focused.9.png new file mode 100644 index 00000000000..e3d14e9954b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked-focused@2x.9.png b/src/quickcontrols2/imagine/images/button-background-checked-focused@2x.9.png new file mode 100644 index 00000000000..ebc74b4a34e Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked-focused@3x.9.png b/src/quickcontrols2/imagine/images/button-background-checked-focused@3x.9.png new file mode 100644 index 00000000000..75834723040 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked-focused@4x.9.png b/src/quickcontrols2/imagine/images/button-background-checked-focused@4x.9.png new file mode 100644 index 00000000000..9b570f4d152 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked-hovered.9.png b/src/quickcontrols2/imagine/images/button-background-checked-hovered.9.png new file mode 100644 index 00000000000..e3d14e9954b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked-hovered@2x.9.png b/src/quickcontrols2/imagine/images/button-background-checked-hovered@2x.9.png new file mode 100644 index 00000000000..ebc74b4a34e Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked-hovered@3x.9.png b/src/quickcontrols2/imagine/images/button-background-checked-hovered@3x.9.png new file mode 100644 index 00000000000..75834723040 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked-hovered@4x.9.png b/src/quickcontrols2/imagine/images/button-background-checked-hovered@4x.9.png new file mode 100644 index 00000000000..9b570f4d152 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked.9.png b/src/quickcontrols2/imagine/images/button-background-checked.9.png new file mode 100644 index 00000000000..d0942509f7c Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked@2x.9.png b/src/quickcontrols2/imagine/images/button-background-checked@2x.9.png new file mode 100644 index 00000000000..c38bcd026f0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked@3x.9.png b/src/quickcontrols2/imagine/images/button-background-checked@3x.9.png new file mode 100644 index 00000000000..80889bf8017 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-checked@4x.9.png b/src/quickcontrols2/imagine/images/button-background-checked@4x.9.png new file mode 100644 index 00000000000..05de8377efd Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-checked@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-disabled.9.png b/src/quickcontrols2/imagine/images/button-background-disabled.9.png new file mode 100644 index 00000000000..8196289cc28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-disabled@2x.9.png b/src/quickcontrols2/imagine/images/button-background-disabled@2x.9.png new file mode 100644 index 00000000000..76cd44908b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-disabled@3x.9.png b/src/quickcontrols2/imagine/images/button-background-disabled@3x.9.png new file mode 100644 index 00000000000..8bd6259a475 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-disabled@4x.9.png b/src/quickcontrols2/imagine/images/button-background-disabled@4x.9.png new file mode 100644 index 00000000000..3e08152013b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-checked-pressed.9.png b/src/quickcontrols2/imagine/images/button-background-flat-checked-pressed.9.png new file mode 100644 index 00000000000..8196289cc28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-checked-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-checked-pressed@2x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-checked-pressed@2x.9.png new file mode 100644 index 00000000000..76cd44908b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-checked-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-checked-pressed@3x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-checked-pressed@3x.9.png new file mode 100644 index 00000000000..8bd6259a475 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-checked-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-checked-pressed@4x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-checked-pressed@4x.9.png new file mode 100644 index 00000000000..3e08152013b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-checked-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-checked.9.png b/src/quickcontrols2/imagine/images/button-background-flat-checked.9.png new file mode 100644 index 00000000000..8196289cc28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-checked.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-checked@2x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-checked@2x.9.png new file mode 100644 index 00000000000..76cd44908b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-checked@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-checked@3x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-checked@3x.9.png new file mode 100644 index 00000000000..8bd6259a475 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-checked@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-checked@4x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-checked@4x.9.png new file mode 100644 index 00000000000..3e08152013b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-checked@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-disabled.9.png b/src/quickcontrols2/imagine/images/button-background-flat-disabled.9.png new file mode 100644 index 00000000000..59907409c49 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-disabled@2x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-disabled@2x.9.png new file mode 100644 index 00000000000..d66acd9c482 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-disabled@3x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-disabled@3x.9.png new file mode 100644 index 00000000000..89b8c353577 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-disabled@4x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-disabled@4x.9.png new file mode 100644 index 00000000000..d3a675cfe73 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-highlighted-checked.9.png b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-checked.9.png new file mode 100644 index 00000000000..8196289cc28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-checked.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-highlighted-checked@2x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-checked@2x.9.png new file mode 100644 index 00000000000..76cd44908b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-checked@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-highlighted-checked@3x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-checked@3x.9.png new file mode 100644 index 00000000000..8bd6259a475 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-checked@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-highlighted-checked@4x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-checked@4x.9.png new file mode 100644 index 00000000000..3e08152013b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-checked@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-highlighted-pressed.9.png b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-pressed.9.png new file mode 100644 index 00000000000..8196289cc28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-highlighted-pressed@2x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-pressed@2x.9.png new file mode 100644 index 00000000000..76cd44908b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-highlighted-pressed@3x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-pressed@3x.9.png new file mode 100644 index 00000000000..8bd6259a475 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-highlighted-pressed@4x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-pressed@4x.9.png new file mode 100644 index 00000000000..3e08152013b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-highlighted-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-highlighted.9.png b/src/quickcontrols2/imagine/images/button-background-flat-highlighted.9.png new file mode 100644 index 00000000000..59907409c49 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-highlighted.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-highlighted@2x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-highlighted@2x.9.png new file mode 100644 index 00000000000..d66acd9c482 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-highlighted@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-highlighted@3x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-highlighted@3x.9.png new file mode 100644 index 00000000000..89b8c353577 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-highlighted@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-highlighted@4x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-highlighted@4x.9.png new file mode 100644 index 00000000000..d3a675cfe73 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-highlighted@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-hovered.9.png b/src/quickcontrols2/imagine/images/button-background-flat-hovered.9.png new file mode 100644 index 00000000000..8196289cc28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-hovered@2x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-hovered@2x.9.png new file mode 100644 index 00000000000..76cd44908b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-hovered@3x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-hovered@3x.9.png new file mode 100644 index 00000000000..8bd6259a475 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-hovered@4x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-hovered@4x.9.png new file mode 100644 index 00000000000..3e08152013b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-pressed.9.png b/src/quickcontrols2/imagine/images/button-background-flat-pressed.9.png new file mode 100644 index 00000000000..8196289cc28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-pressed@2x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-pressed@2x.9.png new file mode 100644 index 00000000000..76cd44908b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-pressed@3x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-pressed@3x.9.png new file mode 100644 index 00000000000..8bd6259a475 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat-pressed@4x.9.png b/src/quickcontrols2/imagine/images/button-background-flat-pressed@4x.9.png new file mode 100644 index 00000000000..3e08152013b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat.9.png b/src/quickcontrols2/imagine/images/button-background-flat.9.png new file mode 100644 index 00000000000..59907409c49 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat@2x.9.png b/src/quickcontrols2/imagine/images/button-background-flat@2x.9.png new file mode 100644 index 00000000000..d66acd9c482 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat@3x.9.png b/src/quickcontrols2/imagine/images/button-background-flat@3x.9.png new file mode 100644 index 00000000000..89b8c353577 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-flat@4x.9.png b/src/quickcontrols2/imagine/images/button-background-flat@4x.9.png new file mode 100644 index 00000000000..d3a675cfe73 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-flat@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-focused.9.png b/src/quickcontrols2/imagine/images/button-background-focused.9.png new file mode 100644 index 00000000000..42e40e60821 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-focused@2x.9.png b/src/quickcontrols2/imagine/images/button-background-focused@2x.9.png new file mode 100644 index 00000000000..90dc70bfe08 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-focused@3x.9.png b/src/quickcontrols2/imagine/images/button-background-focused@3x.9.png new file mode 100644 index 00000000000..2ed2340cb08 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-focused@4x.9.png b/src/quickcontrols2/imagine/images/button-background-focused@4x.9.png new file mode 100644 index 00000000000..e1428e37eb4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-checked.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-checked.9.png new file mode 100644 index 00000000000..7a2a401106b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-checked.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-checked@2x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-checked@2x.9.png new file mode 100644 index 00000000000..05b2f21423c Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-checked@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-checked@3x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-checked@3x.9.png new file mode 100644 index 00000000000..8c22e1f32ad Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-checked@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-checked@4x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-checked@4x.9.png new file mode 100644 index 00000000000..c5617f0e0df Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-checked@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-disabled.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-disabled.9.png new file mode 100644 index 00000000000..8196289cc28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-disabled@2x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-disabled@2x.9.png new file mode 100644 index 00000000000..76cd44908b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-disabled@3x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-disabled@3x.9.png new file mode 100644 index 00000000000..8bd6259a475 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-disabled@4x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-disabled@4x.9.png new file mode 100644 index 00000000000..3e08152013b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-focused.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-focused.9.png new file mode 100644 index 00000000000..3ea580e01fe Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-focused@2x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-focused@2x.9.png new file mode 100644 index 00000000000..effcce1f427 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-focused@3x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-focused@3x.9.png new file mode 100644 index 00000000000..502ac68999c Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-focused@4x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-focused@4x.9.png new file mode 100644 index 00000000000..3243231ef70 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-hovered.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-hovered.9.png new file mode 100644 index 00000000000..3ea580e01fe Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-hovered@2x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-hovered@2x.9.png new file mode 100644 index 00000000000..effcce1f427 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-hovered@3x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-hovered@3x.9.png new file mode 100644 index 00000000000..502ac68999c Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-hovered@4x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-hovered@4x.9.png new file mode 100644 index 00000000000..3243231ef70 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-pressed.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-pressed.9.png new file mode 100644 index 00000000000..7a2a401106b Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-pressed@2x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-pressed@2x.9.png new file mode 100644 index 00000000000..05b2f21423c Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-pressed@3x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-pressed@3x.9.png new file mode 100644 index 00000000000..8c22e1f32ad Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted-pressed@4x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted-pressed@4x.9.png new file mode 100644 index 00000000000..c5617f0e0df Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted.9.png new file mode 100644 index 00000000000..7761595fcdc Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted@2x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted@2x.9.png new file mode 100644 index 00000000000..8bb42c45af5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted@3x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted@3x.9.png new file mode 100644 index 00000000000..8c23c021a57 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-highlighted@4x.9.png b/src/quickcontrols2/imagine/images/button-background-highlighted@4x.9.png new file mode 100644 index 00000000000..365cd0489dc Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-highlighted@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-hovered.9.png b/src/quickcontrols2/imagine/images/button-background-hovered.9.png new file mode 100644 index 00000000000..42e40e60821 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-hovered@2x.9.png b/src/quickcontrols2/imagine/images/button-background-hovered@2x.9.png new file mode 100644 index 00000000000..90dc70bfe08 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-hovered@3x.9.png b/src/quickcontrols2/imagine/images/button-background-hovered@3x.9.png new file mode 100644 index 00000000000..2ed2340cb08 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-hovered@4x.9.png b/src/quickcontrols2/imagine/images/button-background-hovered@4x.9.png new file mode 100644 index 00000000000..e1428e37eb4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-pressed.9.png b/src/quickcontrols2/imagine/images/button-background-pressed.9.png new file mode 100644 index 00000000000..d0942509f7c Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-pressed@2x.9.png b/src/quickcontrols2/imagine/images/button-background-pressed@2x.9.png new file mode 100644 index 00000000000..c38bcd026f0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-pressed@3x.9.png b/src/quickcontrols2/imagine/images/button-background-pressed@3x.9.png new file mode 100644 index 00000000000..80889bf8017 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background-pressed@4x.9.png b/src/quickcontrols2/imagine/images/button-background-pressed@4x.9.png new file mode 100644 index 00000000000..05de8377efd Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background.9.png b/src/quickcontrols2/imagine/images/button-background.9.png new file mode 100644 index 00000000000..6f1daed8314 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background@2x.9.png b/src/quickcontrols2/imagine/images/button-background@2x.9.png new file mode 100644 index 00000000000..4a2507f5351 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background@3x.9.png b/src/quickcontrols2/imagine/images/button-background@3x.9.png new file mode 100644 index 00000000000..4f13b4ef55c Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/button-background@4x.9.png b/src/quickcontrols2/imagine/images/button-background@4x.9.png new file mode 100644 index 00000000000..0e1ab4524e4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/button-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked-focused.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-focused.png new file mode 100644 index 00000000000..d55a5204265 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-focused.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked-focused@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-focused@2x.png new file mode 100644 index 00000000000..7289f63949b Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked-focused@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-focused@3x.png new file mode 100644 index 00000000000..02d6cdf2054 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked-focused@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-focused@4x.png new file mode 100644 index 00000000000..3f074dbfa93 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked-hovered.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-hovered.png new file mode 100644 index 00000000000..d55a5204265 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked-hovered@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-hovered@2x.png new file mode 100644 index 00000000000..7289f63949b Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked-hovered@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-hovered@3x.png new file mode 100644 index 00000000000..02d6cdf2054 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked-hovered@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-hovered@4x.png new file mode 100644 index 00000000000..3f074dbfa93 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked-pressed.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-pressed.png new file mode 100644 index 00000000000..9c03d096e43 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked-pressed@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-pressed@2x.png new file mode 100644 index 00000000000..680ba3efcad Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked-pressed@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-pressed@3x.png new file mode 100644 index 00000000000..974205de54a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked-pressed@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-pressed@4x.png new file mode 100644 index 00000000000..2c8b6aabf4c Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked.png new file mode 100644 index 00000000000..598b163aaad Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked@2x.png new file mode 100644 index 00000000000..06382264f9d Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked@3x.png new file mode 100644 index 00000000000..12a32dcd204 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-checked@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-checked@4x.png new file mode 100644 index 00000000000..4bc6701d65c Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-checked@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-disabled.png b/src/quickcontrols2/imagine/images/checkbox-indicator-disabled.png new file mode 100644 index 00000000000..0a499f8f2d2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-disabled@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-disabled@2x.png new file mode 100644 index 00000000000..db652c5ac9c Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-disabled@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-disabled@3x.png new file mode 100644 index 00000000000..482f045d322 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-disabled@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-disabled@4x.png new file mode 100644 index 00000000000..a386e272519 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-focused.png b/src/quickcontrols2/imagine/images/checkbox-indicator-focused.png new file mode 100644 index 00000000000..c5eb85276dd Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-focused.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-focused@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-focused@2x.png new file mode 100644 index 00000000000..8496fb1a88a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-focused@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-focused@3x.png new file mode 100644 index 00000000000..30849fd0f0a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-focused@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-focused@4x.png new file mode 100644 index 00000000000..55ce7c0c1b0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-hovered.png b/src/quickcontrols2/imagine/images/checkbox-indicator-hovered.png new file mode 100644 index 00000000000..c5eb85276dd Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-hovered@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-hovered@2x.png new file mode 100644 index 00000000000..8496fb1a88a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-hovered@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-hovered@3x.png new file mode 100644 index 00000000000..30849fd0f0a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-hovered@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-hovered@4x.png new file mode 100644 index 00000000000..55ce7c0c1b0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-focused.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-focused.png new file mode 100644 index 00000000000..cd07b1ccb30 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-focused.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-focused@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-focused@2x.png new file mode 100644 index 00000000000..acae6afffe7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-focused@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-focused@3x.png new file mode 100644 index 00000000000..1e8d2c45750 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-focused@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-focused@4x.png new file mode 100644 index 00000000000..577017c4c90 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-hovered.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-hovered.png new file mode 100644 index 00000000000..cd07b1ccb30 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-hovered@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-hovered@2x.png new file mode 100644 index 00000000000..acae6afffe7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-hovered@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-hovered@3x.png new file mode 100644 index 00000000000..1e8d2c45750 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-hovered@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-hovered@4x.png new file mode 100644 index 00000000000..577017c4c90 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-pressed.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-pressed.png new file mode 100644 index 00000000000..928706ab274 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-pressed@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-pressed@2x.png new file mode 100644 index 00000000000..3645d78a21f Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-pressed@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-pressed@3x.png new file mode 100644 index 00000000000..ade63bd04b5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-pressed@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-pressed@4x.png new file mode 100644 index 00000000000..cd73617e3cb Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked.png new file mode 100644 index 00000000000..e404a4e3c82 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked@2x.png new file mode 100644 index 00000000000..2d0f51767a3 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked@3x.png new file mode 100644 index 00000000000..4b9777b7ea4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked@4x.png new file mode 100644 index 00000000000..e0f67e9894e Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-partially-checked@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-pressed.png b/src/quickcontrols2/imagine/images/checkbox-indicator-pressed.png new file mode 100644 index 00000000000..a1baaf903e4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-pressed@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-pressed@2x.png new file mode 100644 index 00000000000..81a7c3647a8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-pressed@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-pressed@3x.png new file mode 100644 index 00000000000..9325de38cb5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator-pressed@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator-pressed@4x.png new file mode 100644 index 00000000000..c93b8fb8a3e Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator.png b/src/quickcontrols2/imagine/images/checkbox-indicator.png new file mode 100644 index 00000000000..2b3e2323d72 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator@2x.png b/src/quickcontrols2/imagine/images/checkbox-indicator@2x.png new file mode 100644 index 00000000000..ce8985dbb13 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator@3x.png b/src/quickcontrols2/imagine/images/checkbox-indicator@3x.png new file mode 100644 index 00000000000..2968731dd7e Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkbox-indicator@4x.png b/src/quickcontrols2/imagine/images/checkbox-indicator@4x.png new file mode 100644 index 00000000000..ea8da284986 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkbox-indicator@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-disabled.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-disabled.9.png new file mode 100644 index 00000000000..23570729d68 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-disabled@2x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-disabled@2x.9.png new file mode 100644 index 00000000000..c7abb65c3f9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-disabled@3x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-disabled@3x.9.png new file mode 100644 index 00000000000..46b84d7da48 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-disabled@4x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-disabled@4x.9.png new file mode 100644 index 00000000000..f4dfd338f9c Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-focused.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-focused.9.png new file mode 100644 index 00000000000..6ae574d55a6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-focused@2x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-focused@2x.9.png new file mode 100644 index 00000000000..6b61562c14d Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-focused@3x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-focused@3x.9.png new file mode 100644 index 00000000000..e46c0bf1d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-focused@4x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-focused@4x.9.png new file mode 100644 index 00000000000..010444e8e1d Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-highlighted.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-highlighted.9.png new file mode 100644 index 00000000000..e79d8e1d015 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-highlighted.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-highlighted@2x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-highlighted@2x.9.png new file mode 100644 index 00000000000..ea68d35fc4a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-highlighted@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-highlighted@3x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-highlighted@3x.9.png new file mode 100644 index 00000000000..6d61041599f Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-highlighted@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-highlighted@4x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-highlighted@4x.9.png new file mode 100644 index 00000000000..590cca96a17 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-highlighted@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-hovered.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-hovered.9.png new file mode 100644 index 00000000000..b8749743d0e Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-hovered@2x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-hovered@2x.9.png new file mode 100644 index 00000000000..5a136a0ca9b Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-hovered@3x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-hovered@3x.9.png new file mode 100644 index 00000000000..f47a366b7bb Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-hovered@4x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-hovered@4x.9.png new file mode 100644 index 00000000000..9ecb680f20c Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-pressed.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-pressed.9.png new file mode 100644 index 00000000000..6ae574d55a6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-pressed@2x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-pressed@2x.9.png new file mode 100644 index 00000000000..6b61562c14d Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-pressed@3x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-pressed@3x.9.png new file mode 100644 index 00000000000..e46c0bf1d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background-pressed@4x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background-pressed@4x.9.png new file mode 100644 index 00000000000..010444e8e1d Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background.9.png new file mode 100644 index 00000000000..b8749743d0e Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background@2x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background@2x.9.png new file mode 100644 index 00000000000..5a136a0ca9b Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background@3x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background@3x.9.png new file mode 100644 index 00000000000..f47a366b7bb Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-background@4x.9.png b/src/quickcontrols2/imagine/images/checkdelegate-background@4x.9.png new file mode 100644 index 00000000000..9ecb680f20c Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-focused.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-focused.png new file mode 100644 index 00000000000..d55a5204265 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-focused.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-focused@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-focused@2x.png new file mode 100644 index 00000000000..7289f63949b Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-focused@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-focused@3x.png new file mode 100644 index 00000000000..02d6cdf2054 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-focused@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-focused@4x.png new file mode 100644 index 00000000000..3f074dbfa93 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-hovered.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-hovered.png new file mode 100644 index 00000000000..d55a5204265 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-hovered@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-hovered@2x.png new file mode 100644 index 00000000000..7289f63949b Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-hovered@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-hovered@3x.png new file mode 100644 index 00000000000..02d6cdf2054 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-hovered@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-hovered@4x.png new file mode 100644 index 00000000000..3f074dbfa93 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-pressed.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-pressed.png new file mode 100644 index 00000000000..9c03d096e43 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-pressed@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-pressed@2x.png new file mode 100644 index 00000000000..680ba3efcad Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-pressed@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-pressed@3x.png new file mode 100644 index 00000000000..974205de54a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-pressed@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-pressed@4x.png new file mode 100644 index 00000000000..2c8b6aabf4c Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked.png new file mode 100644 index 00000000000..598b163aaad Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked@2x.png new file mode 100644 index 00000000000..06382264f9d Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked@3x.png new file mode 100644 index 00000000000..12a32dcd204 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked@4x.png new file mode 100644 index 00000000000..4bc6701d65c Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-checked@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-disabled.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-disabled.png new file mode 100644 index 00000000000..0a499f8f2d2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-disabled@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-disabled@2x.png new file mode 100644 index 00000000000..db652c5ac9c Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-disabled@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-disabled@3x.png new file mode 100644 index 00000000000..482f045d322 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-disabled@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-disabled@4x.png new file mode 100644 index 00000000000..a386e272519 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-focused.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-focused.png new file mode 100644 index 00000000000..c5eb85276dd Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-focused.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-focused@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-focused@2x.png new file mode 100644 index 00000000000..8496fb1a88a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-focused@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-focused@3x.png new file mode 100644 index 00000000000..30849fd0f0a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-focused@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-focused@4x.png new file mode 100644 index 00000000000..55ce7c0c1b0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-hovered.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-hovered.png new file mode 100644 index 00000000000..c5eb85276dd Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-hovered@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-hovered@2x.png new file mode 100644 index 00000000000..8496fb1a88a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-hovered@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-hovered@3x.png new file mode 100644 index 00000000000..30849fd0f0a Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-hovered@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-hovered@4x.png new file mode 100644 index 00000000000..55ce7c0c1b0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-focused.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-focused.png new file mode 100644 index 00000000000..cd07b1ccb30 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-focused.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-focused@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-focused@2x.png new file mode 100644 index 00000000000..acae6afffe7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-focused@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-focused@3x.png new file mode 100644 index 00000000000..1e8d2c45750 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-focused@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-focused@4x.png new file mode 100644 index 00000000000..577017c4c90 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-hovered.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-hovered.png new file mode 100644 index 00000000000..cd07b1ccb30 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-hovered@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-hovered@2x.png new file mode 100644 index 00000000000..acae6afffe7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-hovered@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-hovered@3x.png new file mode 100644 index 00000000000..1e8d2c45750 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-hovered@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-hovered@4x.png new file mode 100644 index 00000000000..577017c4c90 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-pressed.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-pressed.png new file mode 100644 index 00000000000..928706ab274 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-pressed@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-pressed@2x.png new file mode 100644 index 00000000000..3645d78a21f Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-pressed@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-pressed@3x.png new file mode 100644 index 00000000000..ade63bd04b5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-pressed@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-pressed@4x.png new file mode 100644 index 00000000000..cd73617e3cb Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked.png new file mode 100644 index 00000000000..e404a4e3c82 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked@2x.png new file mode 100644 index 00000000000..2d0f51767a3 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked@3x.png new file mode 100644 index 00000000000..4b9777b7ea4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked@4x.png new file mode 100644 index 00000000000..e0f67e9894e Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-partially-checked@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-pressed.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-pressed.png new file mode 100644 index 00000000000..a1baaf903e4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-pressed@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-pressed@2x.png new file mode 100644 index 00000000000..81a7c3647a8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-pressed@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-pressed@3x.png new file mode 100644 index 00000000000..9325de38cb5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator-pressed@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator-pressed@4x.png new file mode 100644 index 00000000000..c93b8fb8a3e Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator.png new file mode 100644 index 00000000000..2b3e2323d72 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator@2x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator@2x.png new file mode 100644 index 00000000000..ce8985dbb13 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator@2x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator@3x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator@3x.png new file mode 100644 index 00000000000..2968731dd7e Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator@3x.png differ diff --git a/src/quickcontrols2/imagine/images/checkdelegate-indicator@4x.png b/src/quickcontrols2/imagine/images/checkdelegate-indicator@4x.png new file mode 100644 index 00000000000..ea8da284986 Binary files /dev/null and b/src/quickcontrols2/imagine/images/checkdelegate-indicator@4x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-disabled.9.png b/src/quickcontrols2/imagine/images/combobox-background-disabled.9.png new file mode 100644 index 00000000000..a91b4b55196 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-disabled@2x.9.png b/src/quickcontrols2/imagine/images/combobox-background-disabled@2x.9.png new file mode 100644 index 00000000000..570b990c9b5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-disabled@3x.9.png b/src/quickcontrols2/imagine/images/combobox-background-disabled@3x.9.png new file mode 100644 index 00000000000..b0f9b9c4ce3 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-disabled@4x.9.png b/src/quickcontrols2/imagine/images/combobox-background-disabled@4x.9.png new file mode 100644 index 00000000000..6e810f75924 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-editable-disabled.9.png b/src/quickcontrols2/imagine/images/combobox-background-editable-disabled.9.png new file mode 100644 index 00000000000..e192afb8a17 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-editable-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-editable-disabled@2x.9.png b/src/quickcontrols2/imagine/images/combobox-background-editable-disabled@2x.9.png new file mode 100644 index 00000000000..58a0f6e9a32 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-editable-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-editable-disabled@3x.9.png b/src/quickcontrols2/imagine/images/combobox-background-editable-disabled@3x.9.png new file mode 100644 index 00000000000..cd6f226b332 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-editable-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-editable-disabled@4x.9.png b/src/quickcontrols2/imagine/images/combobox-background-editable-disabled@4x.9.png new file mode 100644 index 00000000000..ff9103b091a Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-editable-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-editable-focused.9.png b/src/quickcontrols2/imagine/images/combobox-background-editable-focused.9.png new file mode 100644 index 00000000000..a0f079bc47a Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-editable-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-editable-focused@2x.9.png b/src/quickcontrols2/imagine/images/combobox-background-editable-focused@2x.9.png new file mode 100644 index 00000000000..83cb503f89b Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-editable-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-editable-focused@3x.9.png b/src/quickcontrols2/imagine/images/combobox-background-editable-focused@3x.9.png new file mode 100644 index 00000000000..4cf96edf90e Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-editable-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-editable-focused@4x.9.png b/src/quickcontrols2/imagine/images/combobox-background-editable-focused@4x.9.png new file mode 100644 index 00000000000..5823de804f7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-editable-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-editable.9.png b/src/quickcontrols2/imagine/images/combobox-background-editable.9.png new file mode 100644 index 00000000000..8edac13208d Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-editable.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-editable@2x.9.png b/src/quickcontrols2/imagine/images/combobox-background-editable@2x.9.png new file mode 100644 index 00000000000..15e465f12a8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-editable@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-editable@3x.9.png b/src/quickcontrols2/imagine/images/combobox-background-editable@3x.9.png new file mode 100644 index 00000000000..910b48d2c65 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-editable@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-editable@4x.9.png b/src/quickcontrols2/imagine/images/combobox-background-editable@4x.9.png new file mode 100644 index 00000000000..ff0f64118ef Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-editable@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-focused.9.png b/src/quickcontrols2/imagine/images/combobox-background-focused.9.png new file mode 100644 index 00000000000..a3865fa698e Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-focused@2x.9.png b/src/quickcontrols2/imagine/images/combobox-background-focused@2x.9.png new file mode 100644 index 00000000000..fc49f4b824f Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-focused@3x.9.png b/src/quickcontrols2/imagine/images/combobox-background-focused@3x.9.png new file mode 100644 index 00000000000..b432b4ec543 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-focused@4x.9.png b/src/quickcontrols2/imagine/images/combobox-background-focused@4x.9.png new file mode 100644 index 00000000000..15862059989 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-hovered.9.png b/src/quickcontrols2/imagine/images/combobox-background-hovered.9.png new file mode 100644 index 00000000000..a3865fa698e Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-hovered@2x.9.png b/src/quickcontrols2/imagine/images/combobox-background-hovered@2x.9.png new file mode 100644 index 00000000000..fc49f4b824f Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-hovered@3x.9.png b/src/quickcontrols2/imagine/images/combobox-background-hovered@3x.9.png new file mode 100644 index 00000000000..b432b4ec543 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-hovered@4x.9.png b/src/quickcontrols2/imagine/images/combobox-background-hovered@4x.9.png new file mode 100644 index 00000000000..15862059989 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-open.9.png b/src/quickcontrols2/imagine/images/combobox-background-open.9.png new file mode 100644 index 00000000000..1be84403366 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-open.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-open@2x.9.png b/src/quickcontrols2/imagine/images/combobox-background-open@2x.9.png new file mode 100644 index 00000000000..95f7cd6d8a4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-open@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-open@3x.9.png b/src/quickcontrols2/imagine/images/combobox-background-open@3x.9.png new file mode 100644 index 00000000000..2f71271ce80 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-open@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-open@4x.9.png b/src/quickcontrols2/imagine/images/combobox-background-open@4x.9.png new file mode 100644 index 00000000000..17f6f2ce11e Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-open@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-pressed.9.png b/src/quickcontrols2/imagine/images/combobox-background-pressed.9.png new file mode 100644 index 00000000000..1be84403366 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-pressed@2x.9.png b/src/quickcontrols2/imagine/images/combobox-background-pressed@2x.9.png new file mode 100644 index 00000000000..95f7cd6d8a4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-pressed@3x.9.png b/src/quickcontrols2/imagine/images/combobox-background-pressed@3x.9.png new file mode 100644 index 00000000000..2f71271ce80 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background-pressed@4x.9.png b/src/quickcontrols2/imagine/images/combobox-background-pressed@4x.9.png new file mode 100644 index 00000000000..17f6f2ce11e Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background.9.png b/src/quickcontrols2/imagine/images/combobox-background.9.png new file mode 100644 index 00000000000..4ed8ddc36fd Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background@2x.9.png b/src/quickcontrols2/imagine/images/combobox-background@2x.9.png new file mode 100644 index 00000000000..1d7a88943af Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background@3x.9.png b/src/quickcontrols2/imagine/images/combobox-background@3x.9.png new file mode 100644 index 00000000000..313630f85c7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-background@4x.9.png b/src/quickcontrols2/imagine/images/combobox-background@4x.9.png new file mode 100644 index 00000000000..be63d56ea0e Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-disabled.png b/src/quickcontrols2/imagine/images/combobox-indicator-disabled.png new file mode 100644 index 00000000000..761537f9c47 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-disabled@2x.png b/src/quickcontrols2/imagine/images/combobox-indicator-disabled@2x.png new file mode 100644 index 00000000000..322b7b68372 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-disabled@3x.png b/src/quickcontrols2/imagine/images/combobox-indicator-disabled@3x.png new file mode 100644 index 00000000000..73feec349d7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-disabled@4x.png b/src/quickcontrols2/imagine/images/combobox-indicator-disabled@4x.png new file mode 100644 index 00000000000..910c4d3d216 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable-disabled.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable-disabled.png new file mode 100644 index 00000000000..4399b6aab5a Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable-disabled@2x.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable-disabled@2x.png new file mode 100644 index 00000000000..e45a2ad125b Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable-disabled@3x.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable-disabled@3x.png new file mode 100644 index 00000000000..23f74b10ea3 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable-disabled@4x.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable-disabled@4x.png new file mode 100644 index 00000000000..db495899a87 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored-disabled.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored-disabled.png new file mode 100644 index 00000000000..2e954ae99e6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored-disabled@2x.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored-disabled@2x.png new file mode 100644 index 00000000000..252a5e37d55 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored-disabled@3x.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored-disabled@3x.png new file mode 100644 index 00000000000..6d939a93f6f Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored-disabled@4x.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored-disabled@4x.png new file mode 100644 index 00000000000..00a21ebdfb1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored.png new file mode 100644 index 00000000000..ad529912126 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored@2x.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored@2x.png new file mode 100644 index 00000000000..70b995c1351 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored@2x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored@3x.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored@3x.png new file mode 100644 index 00000000000..9b865377273 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored@3x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored@4x.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored@4x.png new file mode 100644 index 00000000000..b4f7ae25d33 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable-mirrored@4x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable.png new file mode 100644 index 00000000000..e053109f10b Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable@2x.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable@2x.png new file mode 100644 index 00000000000..b8dfd6fe0e7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable@2x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable@3x.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable@3x.png new file mode 100644 index 00000000000..2cdee7a8f81 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable@3x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator-editable@4x.png b/src/quickcontrols2/imagine/images/combobox-indicator-editable@4x.png new file mode 100644 index 00000000000..2569b4aef0f Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator-editable@4x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator.png b/src/quickcontrols2/imagine/images/combobox-indicator.png new file mode 100644 index 00000000000..cc32f2a2720 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator@2x.png b/src/quickcontrols2/imagine/images/combobox-indicator@2x.png new file mode 100644 index 00000000000..57ea3f3082b Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator@2x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator@3x.png b/src/quickcontrols2/imagine/images/combobox-indicator@3x.png new file mode 100644 index 00000000000..384f8152db5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator@3x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-indicator@4x.png b/src/quickcontrols2/imagine/images/combobox-indicator@4x.png new file mode 100644 index 00000000000..f326c03b4b6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-indicator@4x.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-popup.9.png b/src/quickcontrols2/imagine/images/combobox-popup.9.png new file mode 100644 index 00000000000..7344cdf6db4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-popup.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-popup@2x.9.png b/src/quickcontrols2/imagine/images/combobox-popup@2x.9.png new file mode 100644 index 00000000000..00c88c7d592 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-popup@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-popup@3x.9.png b/src/quickcontrols2/imagine/images/combobox-popup@3x.9.png new file mode 100644 index 00000000000..82d911ed666 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-popup@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/combobox-popup@4x.9.png b/src/quickcontrols2/imagine/images/combobox-popup@4x.9.png new file mode 100644 index 00000000000..98db30af661 Binary files /dev/null and b/src/quickcontrols2/imagine/images/combobox-popup@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-checked-focused.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-checked-focused.9.png new file mode 100644 index 00000000000..e3d14e9954b Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-checked-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-checked-focused@2x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-checked-focused@2x.9.png new file mode 100644 index 00000000000..ebc74b4a34e Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-checked-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-checked-focused@3x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-checked-focused@3x.9.png new file mode 100644 index 00000000000..75834723040 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-checked-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-checked-focused@4x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-checked-focused@4x.9.png new file mode 100644 index 00000000000..9b570f4d152 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-checked-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-checked-hovered.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-checked-hovered.9.png new file mode 100644 index 00000000000..e3d14e9954b Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-checked-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-checked-hovered@2x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-checked-hovered@2x.9.png new file mode 100644 index 00000000000..ebc74b4a34e Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-checked-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-checked-hovered@3x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-checked-hovered@3x.9.png new file mode 100644 index 00000000000..75834723040 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-checked-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-checked-hovered@4x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-checked-hovered@4x.9.png new file mode 100644 index 00000000000..9b570f4d152 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-checked-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-checked.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-checked.9.png new file mode 100644 index 00000000000..d0942509f7c Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-checked.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-checked@2x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-checked@2x.9.png new file mode 100644 index 00000000000..c38bcd026f0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-checked@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-checked@3x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-checked@3x.9.png new file mode 100644 index 00000000000..80889bf8017 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-checked@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-checked@4x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-checked@4x.9.png new file mode 100644 index 00000000000..05de8377efd Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-checked@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-disabled-checked.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-disabled-checked.9.png new file mode 100644 index 00000000000..8196289cc28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-disabled-checked.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-disabled-checked@2x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-disabled-checked@2x.9.png new file mode 100644 index 00000000000..76cd44908b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-disabled-checked@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-disabled-checked@3x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-disabled-checked@3x.9.png new file mode 100644 index 00000000000..8bd6259a475 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-disabled-checked@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-disabled-checked@4x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-disabled-checked@4x.9.png new file mode 100644 index 00000000000..3e08152013b Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-disabled-checked@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-disabled.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-disabled.9.png new file mode 100644 index 00000000000..8196289cc28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-disabled@2x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-disabled@2x.9.png new file mode 100644 index 00000000000..76cd44908b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-disabled@3x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-disabled@3x.9.png new file mode 100644 index 00000000000..8bd6259a475 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-disabled@4x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-disabled@4x.9.png new file mode 100644 index 00000000000..3e08152013b Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-focused.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-focused.9.png new file mode 100644 index 00000000000..294ff8bda60 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-focused@2x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-focused@2x.9.png new file mode 100644 index 00000000000..48e2bbcb561 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-focused@3x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-focused@3x.9.png new file mode 100644 index 00000000000..0981eb2ac5c Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-focused@4x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-focused@4x.9.png new file mode 100644 index 00000000000..4ae48bfa36d Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-hovered.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-hovered.9.png new file mode 100644 index 00000000000..42e40e60821 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-hovered@2x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-hovered@2x.9.png new file mode 100644 index 00000000000..90dc70bfe08 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-hovered@3x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-hovered@3x.9.png new file mode 100644 index 00000000000..2ed2340cb08 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-hovered@4x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-hovered@4x.9.png new file mode 100644 index 00000000000..e1428e37eb4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-pressed.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-pressed.9.png new file mode 100644 index 00000000000..d0942509f7c Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-pressed@2x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-pressed@2x.9.png new file mode 100644 index 00000000000..c38bcd026f0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-pressed@3x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-pressed@3x.9.png new file mode 100644 index 00000000000..80889bf8017 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background-pressed@4x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background-pressed@4x.9.png new file mode 100644 index 00000000000..05de8377efd Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background.9.png b/src/quickcontrols2/imagine/images/delaybutton-background.9.png new file mode 100644 index 00000000000..6f1daed8314 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background@2x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background@2x.9.png new file mode 100644 index 00000000000..4a2507f5351 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background@3x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background@3x.9.png new file mode 100644 index 00000000000..4f13b4ef55c Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-background@4x.9.png b/src/quickcontrols2/imagine/images/delaybutton-background@4x.9.png new file mode 100644 index 00000000000..0e1ab4524e4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-mask.9.png b/src/quickcontrols2/imagine/images/delaybutton-mask.9.png new file mode 100644 index 00000000000..76d3967d048 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-mask.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-mask@2x.9.png b/src/quickcontrols2/imagine/images/delaybutton-mask@2x.9.png new file mode 100644 index 00000000000..b8db224cc22 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-mask@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-mask@3x.9.png b/src/quickcontrols2/imagine/images/delaybutton-mask@3x.9.png new file mode 100644 index 00000000000..3bff2c15ae4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-mask@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-mask@4x.9.png b/src/quickcontrols2/imagine/images/delaybutton-mask@4x.9.png new file mode 100644 index 00000000000..045c7fac88f Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-mask@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-progress-disabled.9.png b/src/quickcontrols2/imagine/images/delaybutton-progress-disabled.9.png new file mode 100644 index 00000000000..5c209c9c6b7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-progress-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-progress-disabled@2x.9.png b/src/quickcontrols2/imagine/images/delaybutton-progress-disabled@2x.9.png new file mode 100644 index 00000000000..0ef11a8d3ce Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-progress-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-progress-disabled@3x.9.png b/src/quickcontrols2/imagine/images/delaybutton-progress-disabled@3x.9.png new file mode 100644 index 00000000000..f3f8e547961 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-progress-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-progress-disabled@4x.9.png b/src/quickcontrols2/imagine/images/delaybutton-progress-disabled@4x.9.png new file mode 100644 index 00000000000..b24f50e6694 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-progress-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-progress.9.png b/src/quickcontrols2/imagine/images/delaybutton-progress.9.png new file mode 100644 index 00000000000..4dd3aec5fe8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-progress.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-progress@2x.9.png b/src/quickcontrols2/imagine/images/delaybutton-progress@2x.9.png new file mode 100644 index 00000000000..cd422076e33 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-progress@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-progress@3x.9.png b/src/quickcontrols2/imagine/images/delaybutton-progress@3x.9.png new file mode 100644 index 00000000000..08610300be1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-progress@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/delaybutton-progress@4x.9.png b/src/quickcontrols2/imagine/images/delaybutton-progress@4x.9.png new file mode 100644 index 00000000000..24cc19ba0a8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/delaybutton-progress@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/dial-background-disabled.png b/src/quickcontrols2/imagine/images/dial-background-disabled.png new file mode 100644 index 00000000000..d7c4f847cea Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-background-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/dial-background-disabled@2x.png b/src/quickcontrols2/imagine/images/dial-background-disabled@2x.png new file mode 100644 index 00000000000..56b085df96d Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-background-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-background-disabled@3x.png b/src/quickcontrols2/imagine/images/dial-background-disabled@3x.png new file mode 100644 index 00000000000..4f1e17e7a91 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-background-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-background-disabled@4x.png b/src/quickcontrols2/imagine/images/dial-background-disabled@4x.png new file mode 100644 index 00000000000..4aacbf82229 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-background-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-background-focused.png b/src/quickcontrols2/imagine/images/dial-background-focused.png new file mode 100644 index 00000000000..fc53d5c4072 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-background-focused.png differ diff --git a/src/quickcontrols2/imagine/images/dial-background-focused@2x.png b/src/quickcontrols2/imagine/images/dial-background-focused@2x.png new file mode 100644 index 00000000000..6b547a172d8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-background-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-background-focused@3x.png b/src/quickcontrols2/imagine/images/dial-background-focused@3x.png new file mode 100644 index 00000000000..7b8a2582adf Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-background-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-background-focused@4x.png b/src/quickcontrols2/imagine/images/dial-background-focused@4x.png new file mode 100644 index 00000000000..406f46b591d Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-background-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-background.png b/src/quickcontrols2/imagine/images/dial-background.png new file mode 100644 index 00000000000..58aa09edb27 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-background.png differ diff --git a/src/quickcontrols2/imagine/images/dial-background@2x.png b/src/quickcontrols2/imagine/images/dial-background@2x.png new file mode 100644 index 00000000000..87cd9a0f6b3 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-background@2x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-background@3x.png b/src/quickcontrols2/imagine/images/dial-background@3x.png new file mode 100644 index 00000000000..103fb46107b Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-background@3x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-background@4x.png b/src/quickcontrols2/imagine/images/dial-background@4x.png new file mode 100644 index 00000000000..c290f84a8fe Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-background@4x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-disabled.png b/src/quickcontrols2/imagine/images/dial-handle-disabled.png new file mode 100644 index 00000000000..a93fd0f2b67 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-disabled@2x.png b/src/quickcontrols2/imagine/images/dial-handle-disabled@2x.png new file mode 100644 index 00000000000..2cd536be06e Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-disabled@3x.png b/src/quickcontrols2/imagine/images/dial-handle-disabled@3x.png new file mode 100644 index 00000000000..56b9fe06dbc Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-disabled@4x.png b/src/quickcontrols2/imagine/images/dial-handle-disabled@4x.png new file mode 100644 index 00000000000..5098d6887c5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-focused-hovered.png b/src/quickcontrols2/imagine/images/dial-handle-focused-hovered.png new file mode 100644 index 00000000000..2a143f2afb6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-focused-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-focused-hovered@2x.png b/src/quickcontrols2/imagine/images/dial-handle-focused-hovered@2x.png new file mode 100644 index 00000000000..24dfee82846 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-focused-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-focused-hovered@3x.png b/src/quickcontrols2/imagine/images/dial-handle-focused-hovered@3x.png new file mode 100644 index 00000000000..16e128d5cc5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-focused-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-focused-hovered@4x.png b/src/quickcontrols2/imagine/images/dial-handle-focused-hovered@4x.png new file mode 100644 index 00000000000..b4523acb70b Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-focused-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-focused-pressed.png b/src/quickcontrols2/imagine/images/dial-handle-focused-pressed.png new file mode 100644 index 00000000000..d43971ff4d0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-focused-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-focused-pressed@2x.png b/src/quickcontrols2/imagine/images/dial-handle-focused-pressed@2x.png new file mode 100644 index 00000000000..caa2376e9b0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-focused-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-focused-pressed@3x.png b/src/quickcontrols2/imagine/images/dial-handle-focused-pressed@3x.png new file mode 100644 index 00000000000..c291388316f Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-focused-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-focused-pressed@4x.png b/src/quickcontrols2/imagine/images/dial-handle-focused-pressed@4x.png new file mode 100644 index 00000000000..50ff1c8bf47 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-focused-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-focused.png b/src/quickcontrols2/imagine/images/dial-handle-focused.png new file mode 100644 index 00000000000..d2733474b94 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-focused.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-focused@2x.png b/src/quickcontrols2/imagine/images/dial-handle-focused@2x.png new file mode 100644 index 00000000000..c7bc8f743be Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-focused@3x.png b/src/quickcontrols2/imagine/images/dial-handle-focused@3x.png new file mode 100644 index 00000000000..c0dcd94535f Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-focused@4x.png b/src/quickcontrols2/imagine/images/dial-handle-focused@4x.png new file mode 100644 index 00000000000..b9d2234c3fc Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-hovered.png b/src/quickcontrols2/imagine/images/dial-handle-hovered.png new file mode 100644 index 00000000000..f5d0ac6f7fd Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-hovered@2x.png b/src/quickcontrols2/imagine/images/dial-handle-hovered@2x.png new file mode 100644 index 00000000000..da23baaa909 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-hovered@3x.png b/src/quickcontrols2/imagine/images/dial-handle-hovered@3x.png new file mode 100644 index 00000000000..7287a41923b Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-hovered@4x.png b/src/quickcontrols2/imagine/images/dial-handle-hovered@4x.png new file mode 100644 index 00000000000..9f6982dd566 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-pressed.png b/src/quickcontrols2/imagine/images/dial-handle-pressed.png new file mode 100644 index 00000000000..3b98e1245cb Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-pressed@2x.png b/src/quickcontrols2/imagine/images/dial-handle-pressed@2x.png new file mode 100644 index 00000000000..454e73644db Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-pressed@3x.png b/src/quickcontrols2/imagine/images/dial-handle-pressed@3x.png new file mode 100644 index 00000000000..794516da1ea Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle-pressed@4x.png b/src/quickcontrols2/imagine/images/dial-handle-pressed@4x.png new file mode 100644 index 00000000000..211b1135bec Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle.png b/src/quickcontrols2/imagine/images/dial-handle.png new file mode 100644 index 00000000000..652b82d30e7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle@2x.png b/src/quickcontrols2/imagine/images/dial-handle@2x.png new file mode 100644 index 00000000000..3c86a59bff8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle@2x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle@3x.png b/src/quickcontrols2/imagine/images/dial-handle@3x.png new file mode 100644 index 00000000000..cbfcdbcdc65 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle@3x.png differ diff --git a/src/quickcontrols2/imagine/images/dial-handle@4x.png b/src/quickcontrols2/imagine/images/dial-handle@4x.png new file mode 100644 index 00000000000..2872e006fa9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dial-handle@4x.png differ diff --git a/src/quickcontrols2/imagine/images/dialog-background.9.png b/src/quickcontrols2/imagine/images/dialog-background.9.png new file mode 100644 index 00000000000..c842b5ff586 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialog-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/dialog-background@2x.9.png b/src/quickcontrols2/imagine/images/dialog-background@2x.9.png new file mode 100644 index 00000000000..ca23df1f0d9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialog-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/dialog-background@3x.9.png b/src/quickcontrols2/imagine/images/dialog-background@3x.9.png new file mode 100644 index 00000000000..46cd4065363 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialog-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/dialog-background@4x.9.png b/src/quickcontrols2/imagine/images/dialog-background@4x.9.png new file mode 100644 index 00000000000..3da74119cc2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialog-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/dialog-overlay-modal.png b/src/quickcontrols2/imagine/images/dialog-overlay-modal.png new file mode 100644 index 00000000000..d4a43d1c705 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialog-overlay-modal.png differ diff --git a/src/quickcontrols2/imagine/images/dialog-overlay-modal@2x.png b/src/quickcontrols2/imagine/images/dialog-overlay-modal@2x.png new file mode 100644 index 00000000000..c9a8f4124bd Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialog-overlay-modal@2x.png differ diff --git a/src/quickcontrols2/imagine/images/dialog-overlay-modal@3x.png b/src/quickcontrols2/imagine/images/dialog-overlay-modal@3x.png new file mode 100644 index 00000000000..4a1084a9190 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialog-overlay-modal@3x.png differ diff --git a/src/quickcontrols2/imagine/images/dialog-overlay-modal@4x.png b/src/quickcontrols2/imagine/images/dialog-overlay-modal@4x.png new file mode 100644 index 00000000000..b92e600daee Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialog-overlay-modal@4x.png differ diff --git a/src/quickcontrols2/imagine/images/dialog-overlay.png b/src/quickcontrols2/imagine/images/dialog-overlay.png new file mode 100644 index 00000000000..b7da23c00fe Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialog-overlay.png differ diff --git a/src/quickcontrols2/imagine/images/dialog-overlay@2x.png b/src/quickcontrols2/imagine/images/dialog-overlay@2x.png new file mode 100644 index 00000000000..23828d5a1cf Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialog-overlay@2x.png differ diff --git a/src/quickcontrols2/imagine/images/dialog-overlay@3x.png b/src/quickcontrols2/imagine/images/dialog-overlay@3x.png new file mode 100644 index 00000000000..d9d53828675 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialog-overlay@3x.png differ diff --git a/src/quickcontrols2/imagine/images/dialog-overlay@4x.png b/src/quickcontrols2/imagine/images/dialog-overlay@4x.png new file mode 100644 index 00000000000..a76c1a3a71d Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialog-overlay@4x.png differ diff --git a/src/quickcontrols2/imagine/images/dialogbuttonbox-background.9.png b/src/quickcontrols2/imagine/images/dialogbuttonbox-background.9.png new file mode 100644 index 00000000000..4b080c7f8ba Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialogbuttonbox-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/dialogbuttonbox-background@2x.9.png b/src/quickcontrols2/imagine/images/dialogbuttonbox-background@2x.9.png new file mode 100644 index 00000000000..38306bea932 Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialogbuttonbox-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/dialogbuttonbox-background@3x.9.png b/src/quickcontrols2/imagine/images/dialogbuttonbox-background@3x.9.png new file mode 100644 index 00000000000..66afaabe22c Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialogbuttonbox-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/dialogbuttonbox-background@4x.9.png b/src/quickcontrols2/imagine/images/dialogbuttonbox-background@4x.9.png new file mode 100644 index 00000000000..7d0db539c1f Binary files /dev/null and b/src/quickcontrols2/imagine/images/dialogbuttonbox-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-bottom.9.png b/src/quickcontrols2/imagine/images/drawer-background-bottom.9.png new file mode 100644 index 00000000000..023d8bf8068 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-bottom.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-bottom@2x.9.png b/src/quickcontrols2/imagine/images/drawer-background-bottom@2x.9.png new file mode 100644 index 00000000000..6b229ce9e70 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-bottom@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-bottom@3x.9.png b/src/quickcontrols2/imagine/images/drawer-background-bottom@3x.9.png new file mode 100644 index 00000000000..c61118b6513 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-bottom@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-bottom@4x.9.png b/src/quickcontrols2/imagine/images/drawer-background-bottom@4x.9.png new file mode 100644 index 00000000000..08b2e25f308 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-bottom@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-left.9.png b/src/quickcontrols2/imagine/images/drawer-background-left.9.png new file mode 100644 index 00000000000..5145a3a3f9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-left.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-left@2x.9.png b/src/quickcontrols2/imagine/images/drawer-background-left@2x.9.png new file mode 100644 index 00000000000..95a80ab5303 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-left@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-left@3x.9.png b/src/quickcontrols2/imagine/images/drawer-background-left@3x.9.png new file mode 100644 index 00000000000..bd330b7f8e0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-left@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-left@4x.9.png b/src/quickcontrols2/imagine/images/drawer-background-left@4x.9.png new file mode 100644 index 00000000000..10f0702a11f Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-left@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-right.9.png b/src/quickcontrols2/imagine/images/drawer-background-right.9.png new file mode 100644 index 00000000000..37afb734658 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-right.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-right@2x.9.png b/src/quickcontrols2/imagine/images/drawer-background-right@2x.9.png new file mode 100644 index 00000000000..cfbc8f35a24 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-right@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-right@3x.9.png b/src/quickcontrols2/imagine/images/drawer-background-right@3x.9.png new file mode 100644 index 00000000000..9a49b6d5305 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-right@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-right@4x.9.png b/src/quickcontrols2/imagine/images/drawer-background-right@4x.9.png new file mode 100644 index 00000000000..564057760ae Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-right@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-top.9.png b/src/quickcontrols2/imagine/images/drawer-background-top.9.png new file mode 100644 index 00000000000..56da059ff97 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-top.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-top@2x.9.png b/src/quickcontrols2/imagine/images/drawer-background-top@2x.9.png new file mode 100644 index 00000000000..976671ce591 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-top@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-top@3x.9.png b/src/quickcontrols2/imagine/images/drawer-background-top@3x.9.png new file mode 100644 index 00000000000..7c07deba341 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-top@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-background-top@4x.9.png b/src/quickcontrols2/imagine/images/drawer-background-top@4x.9.png new file mode 100644 index 00000000000..e3b1edf7c2a Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-background-top@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-overlay-modal.png b/src/quickcontrols2/imagine/images/drawer-overlay-modal.png new file mode 100644 index 00000000000..d4a43d1c705 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-overlay-modal.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-overlay-modal@2x.png b/src/quickcontrols2/imagine/images/drawer-overlay-modal@2x.png new file mode 100644 index 00000000000..c9a8f4124bd Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-overlay-modal@2x.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-overlay-modal@3x.png b/src/quickcontrols2/imagine/images/drawer-overlay-modal@3x.png new file mode 100644 index 00000000000..4a1084a9190 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-overlay-modal@3x.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-overlay-modal@4x.png b/src/quickcontrols2/imagine/images/drawer-overlay-modal@4x.png new file mode 100644 index 00000000000..b92e600daee Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-overlay-modal@4x.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-overlay.png b/src/quickcontrols2/imagine/images/drawer-overlay.png new file mode 100644 index 00000000000..b7da23c00fe Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-overlay.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-overlay@2x.png b/src/quickcontrols2/imagine/images/drawer-overlay@2x.png new file mode 100644 index 00000000000..23828d5a1cf Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-overlay@2x.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-overlay@3x.png b/src/quickcontrols2/imagine/images/drawer-overlay@3x.png new file mode 100644 index 00000000000..d9d53828675 Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-overlay@3x.png differ diff --git a/src/quickcontrols2/imagine/images/drawer-overlay@4x.png b/src/quickcontrols2/imagine/images/drawer-overlay@4x.png new file mode 100644 index 00000000000..a76c1a3a71d Binary files /dev/null and b/src/quickcontrols2/imagine/images/drawer-overlay@4x.png differ diff --git a/src/quickcontrols2/imagine/images/frame-background.9.png b/src/quickcontrols2/imagine/images/frame-background.9.png new file mode 100644 index 00000000000..8674059de82 Binary files /dev/null and b/src/quickcontrols2/imagine/images/frame-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/frame-background@2x.9.png b/src/quickcontrols2/imagine/images/frame-background@2x.9.png new file mode 100644 index 00000000000..196614964a1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/frame-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/frame-background@3x.9.png b/src/quickcontrols2/imagine/images/frame-background@3x.9.png new file mode 100644 index 00000000000..07d644be964 Binary files /dev/null and b/src/quickcontrols2/imagine/images/frame-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/frame-background@4x.9.png b/src/quickcontrols2/imagine/images/frame-background@4x.9.png new file mode 100644 index 00000000000..8bf47d2a88d Binary files /dev/null and b/src/quickcontrols2/imagine/images/frame-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/groupbox-background.9.png b/src/quickcontrols2/imagine/images/groupbox-background.9.png new file mode 100644 index 00000000000..8674059de82 Binary files /dev/null and b/src/quickcontrols2/imagine/images/groupbox-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/groupbox-background@2x.9.png b/src/quickcontrols2/imagine/images/groupbox-background@2x.9.png new file mode 100644 index 00000000000..196614964a1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/groupbox-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/groupbox-background@3x.9.png b/src/quickcontrols2/imagine/images/groupbox-background@3x.9.png new file mode 100644 index 00000000000..07d644be964 Binary files /dev/null and b/src/quickcontrols2/imagine/images/groupbox-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/groupbox-background@4x.9.png b/src/quickcontrols2/imagine/images/groupbox-background@4x.9.png new file mode 100644 index 00000000000..8bf47d2a88d Binary files /dev/null and b/src/quickcontrols2/imagine/images/groupbox-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/groupbox-title.9.png b/src/quickcontrols2/imagine/images/groupbox-title.9.png new file mode 100644 index 00000000000..e85e0cb1359 Binary files /dev/null and b/src/quickcontrols2/imagine/images/groupbox-title.9.png differ diff --git a/src/quickcontrols2/imagine/images/groupbox-title@2x.9.png b/src/quickcontrols2/imagine/images/groupbox-title@2x.9.png new file mode 100644 index 00000000000..d5359d857df Binary files /dev/null and b/src/quickcontrols2/imagine/images/groupbox-title@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/groupbox-title@3x.9.png b/src/quickcontrols2/imagine/images/groupbox-title@3x.9.png new file mode 100644 index 00000000000..0e4b5c9f9f1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/groupbox-title@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/groupbox-title@4x.9.png b/src/quickcontrols2/imagine/images/groupbox-title@4x.9.png new file mode 100644 index 00000000000..908dfe6b909 Binary files /dev/null and b/src/quickcontrols2/imagine/images/groupbox-title@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-disabled.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-disabled.9.png new file mode 100644 index 00000000000..23570729d68 Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-disabled@2x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-disabled@2x.9.png new file mode 100644 index 00000000000..c7abb65c3f9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-disabled@3x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-disabled@3x.9.png new file mode 100644 index 00000000000..46b84d7da48 Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-disabled@4x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-disabled@4x.9.png new file mode 100644 index 00000000000..f4dfd338f9c Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-focused.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-focused.9.png new file mode 100644 index 00000000000..6ae574d55a6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-focused@2x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-focused@2x.9.png new file mode 100644 index 00000000000..6b61562c14d Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-focused@3x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-focused@3x.9.png new file mode 100644 index 00000000000..e46c0bf1d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-focused@4x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-focused@4x.9.png new file mode 100644 index 00000000000..010444e8e1d Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-highlighted.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-highlighted.9.png new file mode 100644 index 00000000000..e79d8e1d015 Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-highlighted.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-highlighted@2x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-highlighted@2x.9.png new file mode 100644 index 00000000000..ea68d35fc4a Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-highlighted@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-highlighted@3x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-highlighted@3x.9.png new file mode 100644 index 00000000000..6d61041599f Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-highlighted@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-highlighted@4x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-highlighted@4x.9.png new file mode 100644 index 00000000000..590cca96a17 Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-highlighted@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-hovered.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-hovered.9.png new file mode 100644 index 00000000000..b8749743d0e Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-hovered@2x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-hovered@2x.9.png new file mode 100644 index 00000000000..5a136a0ca9b Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-hovered@3x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-hovered@3x.9.png new file mode 100644 index 00000000000..f47a366b7bb Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-hovered@4x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-hovered@4x.9.png new file mode 100644 index 00000000000..9ecb680f20c Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-pressed.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-pressed.9.png new file mode 100644 index 00000000000..6ae574d55a6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-pressed@2x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-pressed@2x.9.png new file mode 100644 index 00000000000..6b61562c14d Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-pressed@3x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-pressed@3x.9.png new file mode 100644 index 00000000000..e46c0bf1d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background-pressed@4x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background-pressed@4x.9.png new file mode 100644 index 00000000000..010444e8e1d Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background.9.png new file mode 100644 index 00000000000..b8749743d0e Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background@2x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background@2x.9.png new file mode 100644 index 00000000000..5a136a0ca9b Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background@3x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background@3x.9.png new file mode 100644 index 00000000000..f47a366b7bb Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/itemdelegate-background@4x.9.png b/src/quickcontrols2/imagine/images/itemdelegate-background@4x.9.png new file mode 100644 index 00000000000..9ecb680f20c Binary files /dev/null and b/src/quickcontrols2/imagine/images/itemdelegate-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/menu-background.9.png b/src/quickcontrols2/imagine/images/menu-background.9.png new file mode 100644 index 00000000000..3195fbc336a Binary files /dev/null and b/src/quickcontrols2/imagine/images/menu-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/menu-background@2x.9.png b/src/quickcontrols2/imagine/images/menu-background@2x.9.png new file mode 100644 index 00000000000..454c347ced5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menu-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/menu-background@3x.9.png b/src/quickcontrols2/imagine/images/menu-background@3x.9.png new file mode 100644 index 00000000000..32ed60860ff Binary files /dev/null and b/src/quickcontrols2/imagine/images/menu-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/menu-background@4x.9.png b/src/quickcontrols2/imagine/images/menu-background@4x.9.png new file mode 100644 index 00000000000..948cc3e95f0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menu-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow-disabled.png b/src/quickcontrols2/imagine/images/menuitem-arrow-disabled.png new file mode 100644 index 00000000000..6cad53f6c80 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow-disabled@2x.png b/src/quickcontrols2/imagine/images/menuitem-arrow-disabled@2x.png new file mode 100644 index 00000000000..bad6fe8c0fc Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow-disabled@3x.png b/src/quickcontrols2/imagine/images/menuitem-arrow-disabled@3x.png new file mode 100644 index 00000000000..da420091a94 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow-disabled@4x.png b/src/quickcontrols2/imagine/images/menuitem-arrow-disabled@4x.png new file mode 100644 index 00000000000..2d8e44e2f6f Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored-disabled.png b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored-disabled.png new file mode 100644 index 00000000000..44ac2771452 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored-disabled@2x.png b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored-disabled@2x.png new file mode 100644 index 00000000000..71a9b88a80c Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored-disabled@3x.png b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored-disabled@3x.png new file mode 100644 index 00000000000..1e03f2156e6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored-disabled@4x.png b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored-disabled@4x.png new file mode 100644 index 00000000000..0f85b409d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored.png b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored.png new file mode 100644 index 00000000000..4ac1160bf2d Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored@2x.png b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored@2x.png new file mode 100644 index 00000000000..79b089b6543 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored@3x.png b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored@3x.png new file mode 100644 index 00000000000..aeb191fdd58 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored@4x.png b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored@4x.png new file mode 100644 index 00000000000..139fab35e0d Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow-mirrored@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow.png b/src/quickcontrols2/imagine/images/menuitem-arrow.png new file mode 100644 index 00000000000..edf1f6bd1ae Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow@2x.png b/src/quickcontrols2/imagine/images/menuitem-arrow@2x.png new file mode 100644 index 00000000000..8e6292653ee Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow@3x.png b/src/quickcontrols2/imagine/images/menuitem-arrow@3x.png new file mode 100644 index 00000000000..0cef53acf58 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-arrow@4x.png b/src/quickcontrols2/imagine/images/menuitem-arrow@4x.png new file mode 100644 index 00000000000..dbdc83bc161 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-arrow@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-background-highlighted.9.png b/src/quickcontrols2/imagine/images/menuitem-background-highlighted.9.png new file mode 100644 index 00000000000..7b8fa0f42fc Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-background-highlighted.9.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-background-highlighted@2x.9.png b/src/quickcontrols2/imagine/images/menuitem-background-highlighted@2x.9.png new file mode 100644 index 00000000000..9edc30793b7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-background-highlighted@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-background-highlighted@3x.9.png b/src/quickcontrols2/imagine/images/menuitem-background-highlighted@3x.9.png new file mode 100644 index 00000000000..183f6194bac Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-background-highlighted@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-background-highlighted@4x.9.png b/src/quickcontrols2/imagine/images/menuitem-background-highlighted@4x.9.png new file mode 100644 index 00000000000..0a1ab8637d5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-background-highlighted@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-background.9.png b/src/quickcontrols2/imagine/images/menuitem-background.9.png new file mode 100644 index 00000000000..aab131eddf2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-background@2x.9.png b/src/quickcontrols2/imagine/images/menuitem-background@2x.9.png new file mode 100644 index 00000000000..c46938c4d87 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-background@3x.9.png b/src/quickcontrols2/imagine/images/menuitem-background@3x.9.png new file mode 100644 index 00000000000..bac1a83f7fe Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-background@4x.9.png b/src/quickcontrols2/imagine/images/menuitem-background@4x.9.png new file mode 100644 index 00000000000..ba77504c272 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked-focused.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-focused.png new file mode 100644 index 00000000000..d55a5204265 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-focused.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked-focused@2x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-focused@2x.png new file mode 100644 index 00000000000..7289f63949b Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked-focused@3x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-focused@3x.png new file mode 100644 index 00000000000..02d6cdf2054 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked-focused@4x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-focused@4x.png new file mode 100644 index 00000000000..3f074dbfa93 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked-hovered.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-hovered.png new file mode 100644 index 00000000000..d55a5204265 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked-hovered@2x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-hovered@2x.png new file mode 100644 index 00000000000..7289f63949b Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked-hovered@3x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-hovered@3x.png new file mode 100644 index 00000000000..02d6cdf2054 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked-hovered@4x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-hovered@4x.png new file mode 100644 index 00000000000..3f074dbfa93 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked-pressed.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-pressed.png new file mode 100644 index 00000000000..9c03d096e43 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked-pressed@2x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-pressed@2x.png new file mode 100644 index 00000000000..680ba3efcad Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked-pressed@3x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-pressed@3x.png new file mode 100644 index 00000000000..974205de54a Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked-pressed@4x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-pressed@4x.png new file mode 100644 index 00000000000..2c8b6aabf4c Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked.png new file mode 100644 index 00000000000..598b163aaad Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked@2x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked@2x.png new file mode 100644 index 00000000000..06382264f9d Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked@3x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked@3x.png new file mode 100644 index 00000000000..12a32dcd204 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-checked@4x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-checked@4x.png new file mode 100644 index 00000000000..4bc6701d65c Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-checked@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-disabled.png b/src/quickcontrols2/imagine/images/menuitem-indicator-disabled.png new file mode 100644 index 00000000000..0a499f8f2d2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-disabled@2x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-disabled@2x.png new file mode 100644 index 00000000000..db652c5ac9c Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-disabled@3x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-disabled@3x.png new file mode 100644 index 00000000000..482f045d322 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-disabled@4x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-disabled@4x.png new file mode 100644 index 00000000000..a386e272519 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-focused.png b/src/quickcontrols2/imagine/images/menuitem-indicator-focused.png new file mode 100644 index 00000000000..c5eb85276dd Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-focused.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-focused@2x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-focused@2x.png new file mode 100644 index 00000000000..8496fb1a88a Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-focused@3x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-focused@3x.png new file mode 100644 index 00000000000..30849fd0f0a Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-focused@4x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-focused@4x.png new file mode 100644 index 00000000000..55ce7c0c1b0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-hovered.png b/src/quickcontrols2/imagine/images/menuitem-indicator-hovered.png new file mode 100644 index 00000000000..c5eb85276dd Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-hovered@2x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-hovered@2x.png new file mode 100644 index 00000000000..8496fb1a88a Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-hovered@3x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-hovered@3x.png new file mode 100644 index 00000000000..30849fd0f0a Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-hovered@4x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-hovered@4x.png new file mode 100644 index 00000000000..55ce7c0c1b0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-pressed.png b/src/quickcontrols2/imagine/images/menuitem-indicator-pressed.png new file mode 100644 index 00000000000..a1baaf903e4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-pressed@2x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-pressed@2x.png new file mode 100644 index 00000000000..81a7c3647a8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-pressed@3x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-pressed@3x.png new file mode 100644 index 00000000000..9325de38cb5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator-pressed@4x.png b/src/quickcontrols2/imagine/images/menuitem-indicator-pressed@4x.png new file mode 100644 index 00000000000..c93b8fb8a3e Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator.png b/src/quickcontrols2/imagine/images/menuitem-indicator.png new file mode 100644 index 00000000000..2b3e2323d72 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator@2x.png b/src/quickcontrols2/imagine/images/menuitem-indicator@2x.png new file mode 100644 index 00000000000..ce8985dbb13 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator@2x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator@3x.png b/src/quickcontrols2/imagine/images/menuitem-indicator@3x.png new file mode 100644 index 00000000000..2968731dd7e Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator@3x.png differ diff --git a/src/quickcontrols2/imagine/images/menuitem-indicator@4x.png b/src/quickcontrols2/imagine/images/menuitem-indicator@4x.png new file mode 100644 index 00000000000..ea8da284986 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuitem-indicator@4x.png differ diff --git a/src/quickcontrols2/imagine/images/menuseparator-separator.9.png b/src/quickcontrols2/imagine/images/menuseparator-separator.9.png new file mode 100644 index 00000000000..b8825b99cae Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuseparator-separator.9.png differ diff --git a/src/quickcontrols2/imagine/images/menuseparator-separator@2x.9.png b/src/quickcontrols2/imagine/images/menuseparator-separator@2x.9.png new file mode 100644 index 00000000000..3e5a023d76c Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuseparator-separator@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/menuseparator-separator@3x.9.png b/src/quickcontrols2/imagine/images/menuseparator-separator@3x.9.png new file mode 100644 index 00000000000..abe775c7a33 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuseparator-separator@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/menuseparator-separator@4x.9.png b/src/quickcontrols2/imagine/images/menuseparator-separator@4x.9.png new file mode 100644 index 00000000000..164c8e3e226 Binary files /dev/null and b/src/quickcontrols2/imagine/images/menuseparator-separator@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/page-background.png b/src/quickcontrols2/imagine/images/page-background.png new file mode 100644 index 00000000000..2d8d70f2880 Binary files /dev/null and b/src/quickcontrols2/imagine/images/page-background.png differ diff --git a/src/quickcontrols2/imagine/images/page-background@2x.png b/src/quickcontrols2/imagine/images/page-background@2x.png new file mode 100644 index 00000000000..18fbaa4c63f Binary files /dev/null and b/src/quickcontrols2/imagine/images/page-background@2x.png differ diff --git a/src/quickcontrols2/imagine/images/page-background@3x.png b/src/quickcontrols2/imagine/images/page-background@3x.png new file mode 100644 index 00000000000..241232b1e04 Binary files /dev/null and b/src/quickcontrols2/imagine/images/page-background@3x.png differ diff --git a/src/quickcontrols2/imagine/images/page-background@4x.png b/src/quickcontrols2/imagine/images/page-background@4x.png new file mode 100644 index 00000000000..8eb1b1ecc13 Binary files /dev/null and b/src/quickcontrols2/imagine/images/page-background@4x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-current.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-current.png new file mode 100644 index 00000000000..dc96d723262 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-current.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-current@2x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-current@2x.png new file mode 100644 index 00000000000..3e0d794fd52 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-current@2x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-current@3x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-current@3x.png new file mode 100644 index 00000000000..397501a7db1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-current@3x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-current@4x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-current@4x.png new file mode 100644 index 00000000000..f741a8963b3 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-current@4x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled-current.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled-current.png new file mode 100644 index 00000000000..848d4351a35 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled-current.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled-current@2x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled-current@2x.png new file mode 100644 index 00000000000..65b5a9d42fa Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled-current@2x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled-current@3x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled-current@3x.png new file mode 100644 index 00000000000..99e3b644aac Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled-current@3x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled-current@4x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled-current@4x.png new file mode 100644 index 00000000000..f1801fffef8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled-current@4x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled.png new file mode 100644 index 00000000000..848d4351a35 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled@2x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled@2x.png new file mode 100644 index 00000000000..65b5a9d42fa Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled@3x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled@3x.png new file mode 100644 index 00000000000..99e3b644aac Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled@4x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled@4x.png new file mode 100644 index 00000000000..f1801fffef8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-pressed.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-pressed.png new file mode 100644 index 00000000000..dc96d723262 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-pressed@2x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-pressed@2x.png new file mode 100644 index 00000000000..3e0d794fd52 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-pressed@3x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-pressed@3x.png new file mode 100644 index 00000000000..397501a7db1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate-pressed@4x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate-pressed@4x.png new file mode 100644 index 00000000000..f741a8963b3 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate.png b/src/quickcontrols2/imagine/images/pageindicator-delegate.png new file mode 100644 index 00000000000..84d23cd1aed Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate@2x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate@2x.png new file mode 100644 index 00000000000..0e706372c2d Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate@2x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate@3x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate@3x.png new file mode 100644 index 00000000000..85af5a4e4b7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate@3x.png differ diff --git a/src/quickcontrols2/imagine/images/pageindicator-delegate@4x.png b/src/quickcontrols2/imagine/images/pageindicator-delegate@4x.png new file mode 100644 index 00000000000..0aacbab1a90 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pageindicator-delegate@4x.png differ diff --git a/src/quickcontrols2/imagine/images/pane-background.9.png b/src/quickcontrols2/imagine/images/pane-background.9.png new file mode 100644 index 00000000000..658f4863ea1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pane-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/pane-background@2x.9.png b/src/quickcontrols2/imagine/images/pane-background@2x.9.png new file mode 100644 index 00000000000..a84ac04a1fc Binary files /dev/null and b/src/quickcontrols2/imagine/images/pane-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/pane-background@3x.9.png b/src/quickcontrols2/imagine/images/pane-background@3x.9.png new file mode 100644 index 00000000000..2b1c4da9de0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pane-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/pane-background@4x.9.png b/src/quickcontrols2/imagine/images/pane-background@4x.9.png new file mode 100644 index 00000000000..90295db4122 Binary files /dev/null and b/src/quickcontrols2/imagine/images/pane-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/popup-background.9.png b/src/quickcontrols2/imagine/images/popup-background.9.png new file mode 100644 index 00000000000..c842b5ff586 Binary files /dev/null and b/src/quickcontrols2/imagine/images/popup-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/popup-background@2x.9.png b/src/quickcontrols2/imagine/images/popup-background@2x.9.png new file mode 100644 index 00000000000..ca23df1f0d9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/popup-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/popup-background@3x.9.png b/src/quickcontrols2/imagine/images/popup-background@3x.9.png new file mode 100644 index 00000000000..46cd4065363 Binary files /dev/null and b/src/quickcontrols2/imagine/images/popup-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/popup-background@4x.9.png b/src/quickcontrols2/imagine/images/popup-background@4x.9.png new file mode 100644 index 00000000000..3da74119cc2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/popup-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/popup-overlay-modal.png b/src/quickcontrols2/imagine/images/popup-overlay-modal.png new file mode 100644 index 00000000000..d4a43d1c705 Binary files /dev/null and b/src/quickcontrols2/imagine/images/popup-overlay-modal.png differ diff --git a/src/quickcontrols2/imagine/images/popup-overlay-modal@2x.png b/src/quickcontrols2/imagine/images/popup-overlay-modal@2x.png new file mode 100644 index 00000000000..c9a8f4124bd Binary files /dev/null and b/src/quickcontrols2/imagine/images/popup-overlay-modal@2x.png differ diff --git a/src/quickcontrols2/imagine/images/popup-overlay-modal@3x.png b/src/quickcontrols2/imagine/images/popup-overlay-modal@3x.png new file mode 100644 index 00000000000..4a1084a9190 Binary files /dev/null and b/src/quickcontrols2/imagine/images/popup-overlay-modal@3x.png differ diff --git a/src/quickcontrols2/imagine/images/popup-overlay-modal@4x.png b/src/quickcontrols2/imagine/images/popup-overlay-modal@4x.png new file mode 100644 index 00000000000..b92e600daee Binary files /dev/null and b/src/quickcontrols2/imagine/images/popup-overlay-modal@4x.png differ diff --git a/src/quickcontrols2/imagine/images/popup-overlay.png b/src/quickcontrols2/imagine/images/popup-overlay.png new file mode 100644 index 00000000000..b7da23c00fe Binary files /dev/null and b/src/quickcontrols2/imagine/images/popup-overlay.png differ diff --git a/src/quickcontrols2/imagine/images/popup-overlay@2x.png b/src/quickcontrols2/imagine/images/popup-overlay@2x.png new file mode 100644 index 00000000000..23828d5a1cf Binary files /dev/null and b/src/quickcontrols2/imagine/images/popup-overlay@2x.png differ diff --git a/src/quickcontrols2/imagine/images/popup-overlay@3x.png b/src/quickcontrols2/imagine/images/popup-overlay@3x.png new file mode 100644 index 00000000000..d9d53828675 Binary files /dev/null and b/src/quickcontrols2/imagine/images/popup-overlay@3x.png differ diff --git a/src/quickcontrols2/imagine/images/popup-overlay@4x.png b/src/quickcontrols2/imagine/images/popup-overlay@4x.png new file mode 100644 index 00000000000..a76c1a3a71d Binary files /dev/null and b/src/quickcontrols2/imagine/images/popup-overlay@4x.png differ diff --git a/src/quickcontrols2/imagine/images/progressbar-animation.webp b/src/quickcontrols2/imagine/images/progressbar-animation.webp new file mode 100644 index 00000000000..51c35c88233 Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-animation.webp differ diff --git a/src/quickcontrols2/imagine/images/progressbar-animation@2x.webp b/src/quickcontrols2/imagine/images/progressbar-animation@2x.webp new file mode 100644 index 00000000000..ee1206302a9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-animation@2x.webp differ diff --git a/src/quickcontrols2/imagine/images/progressbar-animation@3x.webp b/src/quickcontrols2/imagine/images/progressbar-animation@3x.webp new file mode 100644 index 00000000000..c2f94a74a14 Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-animation@3x.webp differ diff --git a/src/quickcontrols2/imagine/images/progressbar-animation@4x.webp b/src/quickcontrols2/imagine/images/progressbar-animation@4x.webp new file mode 100644 index 00000000000..d49657e9346 Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-animation@4x.webp differ diff --git a/src/quickcontrols2/imagine/images/progressbar-background.9.png b/src/quickcontrols2/imagine/images/progressbar-background.9.png new file mode 100644 index 00000000000..e1760070b34 Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/progressbar-background@2x.9.png b/src/quickcontrols2/imagine/images/progressbar-background@2x.9.png new file mode 100644 index 00000000000..e69922d57e6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/progressbar-background@3x.9.png b/src/quickcontrols2/imagine/images/progressbar-background@3x.9.png new file mode 100644 index 00000000000..b3c43205c39 Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/progressbar-background@4x.9.png b/src/quickcontrols2/imagine/images/progressbar-background@4x.9.png new file mode 100644 index 00000000000..905bdc328f8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/progressbar-mask.9.png b/src/quickcontrols2/imagine/images/progressbar-mask.9.png new file mode 100644 index 00000000000..35a47dc807c Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-mask.9.png differ diff --git a/src/quickcontrols2/imagine/images/progressbar-mask@2x.9.png b/src/quickcontrols2/imagine/images/progressbar-mask@2x.9.png new file mode 100644 index 00000000000..23ed1a8cf11 Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-mask@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/progressbar-mask@3x.9.png b/src/quickcontrols2/imagine/images/progressbar-mask@3x.9.png new file mode 100644 index 00000000000..25bc843e3aa Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-mask@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/progressbar-mask@4x.9.png b/src/quickcontrols2/imagine/images/progressbar-mask@4x.9.png new file mode 100644 index 00000000000..645ff201791 Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-mask@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/progressbar-progress.png b/src/quickcontrols2/imagine/images/progressbar-progress.png new file mode 100644 index 00000000000..bb31dc9b14e Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-progress.png differ diff --git a/src/quickcontrols2/imagine/images/progressbar-progress@2x.png b/src/quickcontrols2/imagine/images/progressbar-progress@2x.png new file mode 100644 index 00000000000..6bb464c90be Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-progress@2x.png differ diff --git a/src/quickcontrols2/imagine/images/progressbar-progress@3x.png b/src/quickcontrols2/imagine/images/progressbar-progress@3x.png new file mode 100644 index 00000000000..d514c727721 Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-progress@3x.png differ diff --git a/src/quickcontrols2/imagine/images/progressbar-progress@4x.png b/src/quickcontrols2/imagine/images/progressbar-progress@4x.png new file mode 100644 index 00000000000..abc8fa6753c Binary files /dev/null and b/src/quickcontrols2/imagine/images/progressbar-progress@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-focused.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-focused.png new file mode 100644 index 00000000000..2f9e5e18e97 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-focused.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-focused@2x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-focused@2x.png new file mode 100644 index 00000000000..47ec5534230 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-focused@3x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-focused@3x.png new file mode 100644 index 00000000000..26cdebf8179 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-focused@4x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-focused@4x.png new file mode 100644 index 00000000000..708e286ea75 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-hovered.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-hovered.png new file mode 100644 index 00000000000..2f9e5e18e97 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-hovered@2x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-hovered@2x.png new file mode 100644 index 00000000000..47ec5534230 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-hovered@3x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-hovered@3x.png new file mode 100644 index 00000000000..26cdebf8179 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-hovered@4x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-hovered@4x.png new file mode 100644 index 00000000000..708e286ea75 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-pressed.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-pressed.png new file mode 100644 index 00000000000..1e5ebca46a7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-pressed@2x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-pressed@2x.png new file mode 100644 index 00000000000..6eaae9bf3e1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-pressed@3x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-pressed@3x.png new file mode 100644 index 00000000000..e54a1624d98 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-pressed@4x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-pressed@4x.png new file mode 100644 index 00000000000..7a7850bada0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked.png new file mode 100644 index 00000000000..83c85623792 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked@2x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked@2x.png new file mode 100644 index 00000000000..4bdeb4566e8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked@3x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked@3x.png new file mode 100644 index 00000000000..2230a8ce096 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-checked@4x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked@4x.png new file mode 100644 index 00000000000..e3dce04e568 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-checked@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-disabled.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-disabled.png new file mode 100644 index 00000000000..05b8bfcadb7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-disabled@2x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-disabled@2x.png new file mode 100644 index 00000000000..e26fa5de819 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-disabled@3x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-disabled@3x.png new file mode 100644 index 00000000000..c47e8c7d13b Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-disabled@4x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-disabled@4x.png new file mode 100644 index 00000000000..bc66dde78df Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-focused.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-focused.png new file mode 100644 index 00000000000..3001638d37c Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-focused.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-focused@2x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-focused@2x.png new file mode 100644 index 00000000000..b98907149e6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-focused@3x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-focused@3x.png new file mode 100644 index 00000000000..b6221277d94 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-focused@4x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-focused@4x.png new file mode 100644 index 00000000000..49ae2206ba8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-hovered.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-hovered.png new file mode 100644 index 00000000000..3001638d37c Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-hovered@2x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-hovered@2x.png new file mode 100644 index 00000000000..b98907149e6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-hovered@3x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-hovered@3x.png new file mode 100644 index 00000000000..b6221277d94 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-hovered@4x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-hovered@4x.png new file mode 100644 index 00000000000..49ae2206ba8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-pressed.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-pressed.png new file mode 100644 index 00000000000..76c7b4ed7bd Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-pressed@2x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-pressed@2x.png new file mode 100644 index 00000000000..d5d4cac6d16 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-pressed@3x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-pressed@3x.png new file mode 100644 index 00000000000..ca2a1ed169f Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator-pressed@4x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator-pressed@4x.png new file mode 100644 index 00000000000..1cb753d72f8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator.png b/src/quickcontrols2/imagine/images/radiobutton-indicator.png new file mode 100644 index 00000000000..c05d4bfc054 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator@2x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator@2x.png new file mode 100644 index 00000000000..62744d27265 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator@3x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator@3x.png new file mode 100644 index 00000000000..fa5d241e708 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiobutton-indicator@4x.png b/src/quickcontrols2/imagine/images/radiobutton-indicator@4x.png new file mode 100644 index 00000000000..7db85e94324 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiobutton-indicator@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-disabled.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-disabled.9.png new file mode 100644 index 00000000000..23570729d68 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-disabled@2x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-disabled@2x.9.png new file mode 100644 index 00000000000..c7abb65c3f9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-disabled@3x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-disabled@3x.9.png new file mode 100644 index 00000000000..46b84d7da48 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-disabled@4x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-disabled@4x.9.png new file mode 100644 index 00000000000..f4dfd338f9c Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-focused.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-focused.9.png new file mode 100644 index 00000000000..6ae574d55a6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-focused@2x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-focused@2x.9.png new file mode 100644 index 00000000000..6b61562c14d Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-focused@3x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-focused@3x.9.png new file mode 100644 index 00000000000..e46c0bf1d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-focused@4x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-focused@4x.9.png new file mode 100644 index 00000000000..010444e8e1d Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-highlighted.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-highlighted.9.png new file mode 100644 index 00000000000..e79d8e1d015 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-highlighted.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-highlighted@2x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-highlighted@2x.9.png new file mode 100644 index 00000000000..ea68d35fc4a Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-highlighted@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-highlighted@3x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-highlighted@3x.9.png new file mode 100644 index 00000000000..6d61041599f Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-highlighted@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-highlighted@4x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-highlighted@4x.9.png new file mode 100644 index 00000000000..590cca96a17 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-highlighted@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-hovered.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-hovered.9.png new file mode 100644 index 00000000000..b8749743d0e Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-hovered@2x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-hovered@2x.9.png new file mode 100644 index 00000000000..5a136a0ca9b Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-hovered@3x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-hovered@3x.9.png new file mode 100644 index 00000000000..f47a366b7bb Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-hovered@4x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-hovered@4x.9.png new file mode 100644 index 00000000000..9ecb680f20c Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-pressed.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-pressed.9.png new file mode 100644 index 00000000000..6ae574d55a6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-pressed@2x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-pressed@2x.9.png new file mode 100644 index 00000000000..6b61562c14d Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-pressed@3x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-pressed@3x.9.png new file mode 100644 index 00000000000..e46c0bf1d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background-pressed@4x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background-pressed@4x.9.png new file mode 100644 index 00000000000..010444e8e1d Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background.9.png new file mode 100644 index 00000000000..b8749743d0e Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background@2x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background@2x.9.png new file mode 100644 index 00000000000..5a136a0ca9b Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background@3x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background@3x.9.png new file mode 100644 index 00000000000..f47a366b7bb Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-background@4x.9.png b/src/quickcontrols2/imagine/images/radiodelegate-background@4x.9.png new file mode 100644 index 00000000000..9ecb680f20c Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-focused.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-focused.png new file mode 100644 index 00000000000..2f9e5e18e97 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-focused.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-focused@2x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-focused@2x.png new file mode 100644 index 00000000000..47ec5534230 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-focused@3x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-focused@3x.png new file mode 100644 index 00000000000..26cdebf8179 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-focused@4x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-focused@4x.png new file mode 100644 index 00000000000..708e286ea75 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-hovered.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-hovered.png new file mode 100644 index 00000000000..2f9e5e18e97 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-hovered@2x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-hovered@2x.png new file mode 100644 index 00000000000..47ec5534230 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-hovered@3x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-hovered@3x.png new file mode 100644 index 00000000000..26cdebf8179 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-hovered@4x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-hovered@4x.png new file mode 100644 index 00000000000..708e286ea75 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-pressed.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-pressed.png new file mode 100644 index 00000000000..1e5ebca46a7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-pressed@2x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-pressed@2x.png new file mode 100644 index 00000000000..6eaae9bf3e1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-pressed@3x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-pressed@3x.png new file mode 100644 index 00000000000..e54a1624d98 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-pressed@4x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-pressed@4x.png new file mode 100644 index 00000000000..7a7850bada0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked.png new file mode 100644 index 00000000000..83c85623792 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked@2x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked@2x.png new file mode 100644 index 00000000000..4bdeb4566e8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked@3x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked@3x.png new file mode 100644 index 00000000000..2230a8ce096 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked@4x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked@4x.png new file mode 100644 index 00000000000..e3dce04e568 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-checked@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-disabled.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-disabled.png new file mode 100644 index 00000000000..05b8bfcadb7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-disabled@2x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-disabled@2x.png new file mode 100644 index 00000000000..e26fa5de819 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-disabled@3x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-disabled@3x.png new file mode 100644 index 00000000000..c47e8c7d13b Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-disabled@4x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-disabled@4x.png new file mode 100644 index 00000000000..bc66dde78df Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-focused.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-focused.png new file mode 100644 index 00000000000..3001638d37c Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-focused.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-focused@2x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-focused@2x.png new file mode 100644 index 00000000000..b98907149e6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-focused@3x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-focused@3x.png new file mode 100644 index 00000000000..b6221277d94 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-focused@4x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-focused@4x.png new file mode 100644 index 00000000000..49ae2206ba8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-hovered.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-hovered.png new file mode 100644 index 00000000000..3001638d37c Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-hovered@2x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-hovered@2x.png new file mode 100644 index 00000000000..b98907149e6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-hovered@3x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-hovered@3x.png new file mode 100644 index 00000000000..b6221277d94 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-hovered@4x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-hovered@4x.png new file mode 100644 index 00000000000..49ae2206ba8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-pressed.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-pressed.png new file mode 100644 index 00000000000..76c7b4ed7bd Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-pressed@2x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-pressed@2x.png new file mode 100644 index 00000000000..d5d4cac6d16 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-pressed@3x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-pressed@3x.png new file mode 100644 index 00000000000..ca2a1ed169f Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator-pressed@4x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator-pressed@4x.png new file mode 100644 index 00000000000..1cb753d72f8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator.png new file mode 100644 index 00000000000..c05d4bfc054 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator@2x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator@2x.png new file mode 100644 index 00000000000..62744d27265 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator@2x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator@3x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator@3x.png new file mode 100644 index 00000000000..fa5d241e708 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator@3x.png differ diff --git a/src/quickcontrols2/imagine/images/radiodelegate-indicator@4x.png b/src/quickcontrols2/imagine/images/radiodelegate-indicator@4x.png new file mode 100644 index 00000000000..7db85e94324 Binary files /dev/null and b/src/quickcontrols2/imagine/images/radiodelegate-indicator@4x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-background-horizontal.9.png b/src/quickcontrols2/imagine/images/rangeslider-background-horizontal.9.png new file mode 100644 index 00000000000..c4e957ad1b9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-background-horizontal.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-background-horizontal@2x.9.png b/src/quickcontrols2/imagine/images/rangeslider-background-horizontal@2x.9.png new file mode 100644 index 00000000000..6d8391130b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-background-horizontal@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-background-horizontal@3x.9.png b/src/quickcontrols2/imagine/images/rangeslider-background-horizontal@3x.9.png new file mode 100644 index 00000000000..6b2e634c979 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-background-horizontal@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-background-horizontal@4x.9.png b/src/quickcontrols2/imagine/images/rangeslider-background-horizontal@4x.9.png new file mode 100644 index 00000000000..969c791a380 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-background-horizontal@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-background-vertical.9.png b/src/quickcontrols2/imagine/images/rangeslider-background-vertical.9.png new file mode 100644 index 00000000000..f76e0b21f28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-background-vertical.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-background-vertical@2x.9.png b/src/quickcontrols2/imagine/images/rangeslider-background-vertical@2x.9.png new file mode 100644 index 00000000000..fecd0ab2baf Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-background-vertical@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-background-vertical@3x.9.png b/src/quickcontrols2/imagine/images/rangeslider-background-vertical@3x.9.png new file mode 100644 index 00000000000..77a9c830a5b Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-background-vertical@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-background-vertical@4x.9.png b/src/quickcontrols2/imagine/images/rangeslider-background-vertical@4x.9.png new file mode 100644 index 00000000000..f1613684c09 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-background-vertical@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-disabled.png b/src/quickcontrols2/imagine/images/rangeslider-handle-disabled.png new file mode 100644 index 00000000000..4934fb77c5a Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-disabled@2x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-disabled@2x.png new file mode 100644 index 00000000000..451b719e600 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-disabled@3x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-disabled@3x.png new file mode 100644 index 00000000000..1daffca729f Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-disabled@4x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-disabled@4x.png new file mode 100644 index 00000000000..64830707109 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-focused-hovered.png b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-hovered.png new file mode 100644 index 00000000000..c2958f1b3d5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-focused-hovered@2x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-hovered@2x.png new file mode 100644 index 00000000000..12a4d1f83f2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-focused-hovered@3x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-hovered@3x.png new file mode 100644 index 00000000000..1696ac95078 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-focused-hovered@4x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-hovered@4x.png new file mode 100644 index 00000000000..e1d1305623c Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-focused-pressed.png b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-pressed.png new file mode 100644 index 00000000000..c2958f1b3d5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-focused-pressed@2x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-pressed@2x.png new file mode 100644 index 00000000000..12a4d1f83f2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-focused-pressed@3x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-pressed@3x.png new file mode 100644 index 00000000000..1696ac95078 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-focused-pressed@4x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-pressed@4x.png new file mode 100644 index 00000000000..e1d1305623c Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-focused-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-focused.png b/src/quickcontrols2/imagine/images/rangeslider-handle-focused.png new file mode 100644 index 00000000000..bdf8239a461 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-focused.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-focused@2x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-focused@2x.png new file mode 100644 index 00000000000..9f887c5ea19 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-focused@3x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-focused@3x.png new file mode 100644 index 00000000000..8042d4c2a2d Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-focused@4x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-focused@4x.png new file mode 100644 index 00000000000..e7e68c47e3d Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-hovered.png b/src/quickcontrols2/imagine/images/rangeslider-handle-hovered.png new file mode 100644 index 00000000000..4934fb77c5a Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-hovered@2x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-hovered@2x.png new file mode 100644 index 00000000000..451b719e600 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-hovered@3x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-hovered@3x.png new file mode 100644 index 00000000000..1daffca729f Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-hovered@4x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-hovered@4x.png new file mode 100644 index 00000000000..64830707109 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-pressed.png b/src/quickcontrols2/imagine/images/rangeslider-handle-pressed.png new file mode 100644 index 00000000000..4934fb77c5a Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-pressed@2x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-pressed@2x.png new file mode 100644 index 00000000000..451b719e600 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-pressed@3x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-pressed@3x.png new file mode 100644 index 00000000000..1daffca729f Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle-pressed@4x.png b/src/quickcontrols2/imagine/images/rangeslider-handle-pressed@4x.png new file mode 100644 index 00000000000..64830707109 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle.png b/src/quickcontrols2/imagine/images/rangeslider-handle.png new file mode 100644 index 00000000000..fd72dedfb05 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle@2x.png b/src/quickcontrols2/imagine/images/rangeslider-handle@2x.png new file mode 100644 index 00000000000..57eed9f8aee Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle@2x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle@3x.png b/src/quickcontrols2/imagine/images/rangeslider-handle@3x.png new file mode 100644 index 00000000000..e217a6444f8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle@3x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-handle@4x.png b/src/quickcontrols2/imagine/images/rangeslider-handle@4x.png new file mode 100644 index 00000000000..c212b59f559 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-handle@4x.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal-disabled.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal-disabled.9.png new file mode 100644 index 00000000000..7f7e6b935aa Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal-disabled@2x.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal-disabled@2x.9.png new file mode 100644 index 00000000000..cbf6fb6352b Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal-disabled@3x.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal-disabled@3x.9.png new file mode 100644 index 00000000000..643776b8c95 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal-disabled@4x.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal-disabled@4x.9.png new file mode 100644 index 00000000000..d64acb904d4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal.9.png new file mode 100644 index 00000000000..43192f54162 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal@2x.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal@2x.9.png new file mode 100644 index 00000000000..ebbbbf82f8b Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal@3x.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal@3x.9.png new file mode 100644 index 00000000000..0a029b53e46 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal@4x.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal@4x.9.png new file mode 100644 index 00000000000..a13541691a9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-horizontal@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-vertical-disabled.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical-disabled.9.png new file mode 100644 index 00000000000..a4edafc971b Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-vertical-disabled@2x.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical-disabled@2x.9.png new file mode 100644 index 00000000000..8c38226e611 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-vertical-disabled@3x.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical-disabled@3x.9.png new file mode 100644 index 00000000000..a939bffde86 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-vertical-disabled@4x.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical-disabled@4x.9.png new file mode 100644 index 00000000000..9f653770e24 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-vertical.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical.9.png new file mode 100644 index 00000000000..d3e877fc342 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-vertical@2x.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical@2x.9.png new file mode 100644 index 00000000000..7790050e644 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-vertical@3x.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical@3x.9.png new file mode 100644 index 00000000000..039d198751c Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/rangeslider-progress-vertical@4x.9.png b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical@4x.9.png new file mode 100644 index 00000000000..b3051d1f467 Binary files /dev/null and b/src/quickcontrols2/imagine/images/rangeslider-progress-vertical@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-checked-focused.png b/src/quickcontrols2/imagine/images/roundbutton-background-checked-focused.png new file mode 100644 index 00000000000..032a7caa657 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-checked-focused.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-checked-focused@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background-checked-focused@2x.png new file mode 100644 index 00000000000..a2944b6ac8b Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-checked-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-checked-focused@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background-checked-focused@3x.png new file mode 100644 index 00000000000..ffd4d210c4b Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-checked-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-checked-focused@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background-checked-focused@4x.png new file mode 100644 index 00000000000..35a41fc5023 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-checked-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-checked-hovered.png b/src/quickcontrols2/imagine/images/roundbutton-background-checked-hovered.png new file mode 100644 index 00000000000..032a7caa657 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-checked-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-checked-hovered@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background-checked-hovered@2x.png new file mode 100644 index 00000000000..a2944b6ac8b Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-checked-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-checked-hovered@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background-checked-hovered@3x.png new file mode 100644 index 00000000000..ffd4d210c4b Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-checked-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-checked-hovered@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background-checked-hovered@4x.png new file mode 100644 index 00000000000..35a41fc5023 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-checked-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-checked.png b/src/quickcontrols2/imagine/images/roundbutton-background-checked.png new file mode 100644 index 00000000000..d57d3894fa1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-checked.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-checked@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background-checked@2x.png new file mode 100644 index 00000000000..7c374528184 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-checked@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-checked@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background-checked@3x.png new file mode 100644 index 00000000000..b0e0b9bebdd Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-checked@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-checked@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background-checked@4x.png new file mode 100644 index 00000000000..748864efb34 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-checked@4x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-disabled-checked.png b/src/quickcontrols2/imagine/images/roundbutton-background-disabled-checked.png new file mode 100644 index 00000000000..e26fa5de819 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-disabled-checked.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-disabled-checked@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background-disabled-checked@2x.png new file mode 100644 index 00000000000..bc66dde78df Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-disabled-checked@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-disabled-checked@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background-disabled-checked@3x.png new file mode 100644 index 00000000000..a0c5f9ad4fc Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-disabled-checked@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-disabled-checked@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background-disabled-checked@4x.png new file mode 100644 index 00000000000..190210c8f8a Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-disabled-checked@4x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-disabled.png b/src/quickcontrols2/imagine/images/roundbutton-background-disabled.png new file mode 100644 index 00000000000..e26fa5de819 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-disabled@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background-disabled@2x.png new file mode 100644 index 00000000000..bc66dde78df Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-disabled@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background-disabled@3x.png new file mode 100644 index 00000000000..a0c5f9ad4fc Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-disabled@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background-disabled@4x.png new file mode 100644 index 00000000000..190210c8f8a Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-focused.png b/src/quickcontrols2/imagine/images/roundbutton-background-focused.png new file mode 100644 index 00000000000..832955c4e1e Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-focused.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-focused@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background-focused@2x.png new file mode 100644 index 00000000000..bb1ed2ac4b7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-focused@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background-focused@3x.png new file mode 100644 index 00000000000..cbf02913215 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-focused@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background-focused@4x.png new file mode 100644 index 00000000000..1c765dee15a Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-focused.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-focused.png new file mode 100644 index 00000000000..269a9d52d55 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-focused.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-focused@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-focused@2x.png new file mode 100644 index 00000000000..bd79565126f Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-focused@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-focused@3x.png new file mode 100644 index 00000000000..5ed0f662b43 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-focused@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-focused@4x.png new file mode 100644 index 00000000000..5bbb8e7afbd Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-hovered.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-hovered.png new file mode 100644 index 00000000000..269a9d52d55 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-hovered@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-hovered@2x.png new file mode 100644 index 00000000000..bd79565126f Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-hovered@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-hovered@3x.png new file mode 100644 index 00000000000..5ed0f662b43 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-hovered@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-hovered@4x.png new file mode 100644 index 00000000000..5bbb8e7afbd Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-pressed.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-pressed.png new file mode 100644 index 00000000000..a0fa8df033f Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-pressed@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-pressed@2x.png new file mode 100644 index 00000000000..3082a1d9c6c Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-pressed@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-pressed@3x.png new file mode 100644 index 00000000000..d32e8af040b Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-pressed@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-pressed@4x.png new file mode 100644 index 00000000000..f4916e0bca2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted.png new file mode 100644 index 00000000000..f90e29f9cf2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted@2x.png new file mode 100644 index 00000000000..7dce11b40d1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted@3x.png new file mode 100644 index 00000000000..436abbddce6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-highlighted@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted@4x.png new file mode 100644 index 00000000000..e728d6fa1c2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-highlighted@4x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-hovered.png b/src/quickcontrols2/imagine/images/roundbutton-background-hovered.png new file mode 100644 index 00000000000..832955c4e1e Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-hovered@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background-hovered@2x.png new file mode 100644 index 00000000000..bb1ed2ac4b7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-hovered@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background-hovered@3x.png new file mode 100644 index 00000000000..cbf02913215 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-hovered@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background-hovered@4x.png new file mode 100644 index 00000000000..1c765dee15a Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-pressed.png b/src/quickcontrols2/imagine/images/roundbutton-background-pressed.png new file mode 100644 index 00000000000..d57d3894fa1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-pressed@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background-pressed@2x.png new file mode 100644 index 00000000000..7c374528184 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-pressed@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background-pressed@3x.png new file mode 100644 index 00000000000..b0e0b9bebdd Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background-pressed@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background-pressed@4x.png new file mode 100644 index 00000000000..748864efb34 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background.png b/src/quickcontrols2/imagine/images/roundbutton-background.png new file mode 100644 index 00000000000..d5d4cac6d16 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background@2x.png b/src/quickcontrols2/imagine/images/roundbutton-background@2x.png new file mode 100644 index 00000000000..1cb753d72f8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background@2x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background@3x.png b/src/quickcontrols2/imagine/images/roundbutton-background@3x.png new file mode 100644 index 00000000000..6cc304bf420 Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background@3x.png differ diff --git a/src/quickcontrols2/imagine/images/roundbutton-background@4x.png b/src/quickcontrols2/imagine/images/roundbutton-background@4x.png new file mode 100644 index 00000000000..56ea82f6dee Binary files /dev/null and b/src/quickcontrols2/imagine/images/roundbutton-background@4x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-disabled.png b/src/quickcontrols2/imagine/images/scrollbar-handle-disabled.png new file mode 100644 index 00000000000..b0b95bed994 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-disabled@2x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-disabled@2x.png new file mode 100644 index 00000000000..8ab854b0a30 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-disabled@3x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-disabled@3x.png new file mode 100644 index 00000000000..f3c97231f59 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-disabled@4x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-disabled@4x.png new file mode 100644 index 00000000000..325469b8d89 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-disabled.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-disabled.png new file mode 100644 index 00000000000..236002fff64 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-disabled@2x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-disabled@2x.png new file mode 100644 index 00000000000..abc3d2c05c0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-disabled@3x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-disabled@3x.png new file mode 100644 index 00000000000..e215cf5b7aa Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-disabled@4x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-disabled@4x.png new file mode 100644 index 00000000000..c6ec0520bd5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-hovered.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-hovered.png new file mode 100644 index 00000000000..19b48f1d49e Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-hovered@2x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-hovered@2x.png new file mode 100644 index 00000000000..8f5abb8494b Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-hovered@3x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-hovered@3x.png new file mode 100644 index 00000000000..73963d754cd Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-hovered@4x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-hovered@4x.png new file mode 100644 index 00000000000..04d6131ec94 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-pressed.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-pressed.png new file mode 100644 index 00000000000..f48f514df28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-pressed@2x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-pressed@2x.png new file mode 100644 index 00000000000..e31820add9c Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-pressed@3x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-pressed@3x.png new file mode 100644 index 00000000000..278ba900073 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-pressed@4x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-pressed@4x.png new file mode 100644 index 00000000000..01e4e5c85ba Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive.png new file mode 100644 index 00000000000..fd7832a6aae Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive@2x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive@2x.png new file mode 100644 index 00000000000..bd63a1b1e8f Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive@2x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive@3x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive@3x.png new file mode 100644 index 00000000000..3145295446e Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive@3x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle-interactive@4x.png b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive@4x.png new file mode 100644 index 00000000000..6db4d81da94 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle-interactive@4x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle.png b/src/quickcontrols2/imagine/images/scrollbar-handle.png new file mode 100644 index 00000000000..255f6c4d603 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle@2x.png b/src/quickcontrols2/imagine/images/scrollbar-handle@2x.png new file mode 100644 index 00000000000..2b69cef6a32 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle@2x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle@3x.png b/src/quickcontrols2/imagine/images/scrollbar-handle@3x.png new file mode 100644 index 00000000000..6fdfa487d06 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle@3x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollbar-handle@4x.png b/src/quickcontrols2/imagine/images/scrollbar-handle@4x.png new file mode 100644 index 00000000000..cc3205f125b Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollbar-handle@4x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollindicator-handle.png b/src/quickcontrols2/imagine/images/scrollindicator-handle.png new file mode 100644 index 00000000000..255f6c4d603 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollindicator-handle.png differ diff --git a/src/quickcontrols2/imagine/images/scrollindicator-handle@2x.png b/src/quickcontrols2/imagine/images/scrollindicator-handle@2x.png new file mode 100644 index 00000000000..2b69cef6a32 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollindicator-handle@2x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollindicator-handle@3x.png b/src/quickcontrols2/imagine/images/scrollindicator-handle@3x.png new file mode 100644 index 00000000000..6fdfa487d06 Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollindicator-handle@3x.png differ diff --git a/src/quickcontrols2/imagine/images/scrollindicator-handle@4x.png b/src/quickcontrols2/imagine/images/scrollindicator-handle@4x.png new file mode 100644 index 00000000000..cc3205f125b Binary files /dev/null and b/src/quickcontrols2/imagine/images/scrollindicator-handle@4x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-background-horizontal.9.png b/src/quickcontrols2/imagine/images/slider-background-horizontal.9.png new file mode 100644 index 00000000000..c4e957ad1b9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-background-horizontal.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-background-horizontal@2x.9.png b/src/quickcontrols2/imagine/images/slider-background-horizontal@2x.9.png new file mode 100644 index 00000000000..6d8391130b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-background-horizontal@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-background-horizontal@3x.9.png b/src/quickcontrols2/imagine/images/slider-background-horizontal@3x.9.png new file mode 100644 index 00000000000..6b2e634c979 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-background-horizontal@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-background-horizontal@4x.9.png b/src/quickcontrols2/imagine/images/slider-background-horizontal@4x.9.png new file mode 100644 index 00000000000..969c791a380 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-background-horizontal@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-background-vertical.9.png b/src/quickcontrols2/imagine/images/slider-background-vertical.9.png new file mode 100644 index 00000000000..f76e0b21f28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-background-vertical.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-background-vertical@2x.9.png b/src/quickcontrols2/imagine/images/slider-background-vertical@2x.9.png new file mode 100644 index 00000000000..fecd0ab2baf Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-background-vertical@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-background-vertical@3x.9.png b/src/quickcontrols2/imagine/images/slider-background-vertical@3x.9.png new file mode 100644 index 00000000000..77a9c830a5b Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-background-vertical@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-background-vertical@4x.9.png b/src/quickcontrols2/imagine/images/slider-background-vertical@4x.9.png new file mode 100644 index 00000000000..f1613684c09 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-background-vertical@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-disabled.png b/src/quickcontrols2/imagine/images/slider-handle-disabled.png new file mode 100644 index 00000000000..4934fb77c5a Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-disabled@2x.png b/src/quickcontrols2/imagine/images/slider-handle-disabled@2x.png new file mode 100644 index 00000000000..451b719e600 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-disabled@3x.png b/src/quickcontrols2/imagine/images/slider-handle-disabled@3x.png new file mode 100644 index 00000000000..1daffca729f Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-disabled@4x.png b/src/quickcontrols2/imagine/images/slider-handle-disabled@4x.png new file mode 100644 index 00000000000..64830707109 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-focused-hovered.png b/src/quickcontrols2/imagine/images/slider-handle-focused-hovered.png new file mode 100644 index 00000000000..c2958f1b3d5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-focused-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-focused-hovered@2x.png b/src/quickcontrols2/imagine/images/slider-handle-focused-hovered@2x.png new file mode 100644 index 00000000000..12a4d1f83f2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-focused-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-focused-hovered@3x.png b/src/quickcontrols2/imagine/images/slider-handle-focused-hovered@3x.png new file mode 100644 index 00000000000..1696ac95078 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-focused-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-focused-hovered@4x.png b/src/quickcontrols2/imagine/images/slider-handle-focused-hovered@4x.png new file mode 100644 index 00000000000..e1d1305623c Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-focused-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-focused-pressed.png b/src/quickcontrols2/imagine/images/slider-handle-focused-pressed.png new file mode 100644 index 00000000000..c2958f1b3d5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-focused-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-focused-pressed@2x.png b/src/quickcontrols2/imagine/images/slider-handle-focused-pressed@2x.png new file mode 100644 index 00000000000..12a4d1f83f2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-focused-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-focused-pressed@3x.png b/src/quickcontrols2/imagine/images/slider-handle-focused-pressed@3x.png new file mode 100644 index 00000000000..1696ac95078 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-focused-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-focused-pressed@4x.png b/src/quickcontrols2/imagine/images/slider-handle-focused-pressed@4x.png new file mode 100644 index 00000000000..e1d1305623c Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-focused-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-focused.png b/src/quickcontrols2/imagine/images/slider-handle-focused.png new file mode 100644 index 00000000000..bdf8239a461 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-focused.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-focused@2x.png b/src/quickcontrols2/imagine/images/slider-handle-focused@2x.png new file mode 100644 index 00000000000..9f887c5ea19 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-focused@3x.png b/src/quickcontrols2/imagine/images/slider-handle-focused@3x.png new file mode 100644 index 00000000000..8042d4c2a2d Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-focused@4x.png b/src/quickcontrols2/imagine/images/slider-handle-focused@4x.png new file mode 100644 index 00000000000..e7e68c47e3d Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-hovered.png b/src/quickcontrols2/imagine/images/slider-handle-hovered.png new file mode 100644 index 00000000000..4934fb77c5a Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-hovered@2x.png b/src/quickcontrols2/imagine/images/slider-handle-hovered@2x.png new file mode 100644 index 00000000000..451b719e600 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-hovered@3x.png b/src/quickcontrols2/imagine/images/slider-handle-hovered@3x.png new file mode 100644 index 00000000000..1daffca729f Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-hovered@4x.png b/src/quickcontrols2/imagine/images/slider-handle-hovered@4x.png new file mode 100644 index 00000000000..64830707109 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-pressed.png b/src/quickcontrols2/imagine/images/slider-handle-pressed.png new file mode 100644 index 00000000000..4934fb77c5a Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-pressed@2x.png b/src/quickcontrols2/imagine/images/slider-handle-pressed@2x.png new file mode 100644 index 00000000000..451b719e600 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-pressed@3x.png b/src/quickcontrols2/imagine/images/slider-handle-pressed@3x.png new file mode 100644 index 00000000000..1daffca729f Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle-pressed@4x.png b/src/quickcontrols2/imagine/images/slider-handle-pressed@4x.png new file mode 100644 index 00000000000..64830707109 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle.png b/src/quickcontrols2/imagine/images/slider-handle.png new file mode 100644 index 00000000000..fd72dedfb05 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle@2x.png b/src/quickcontrols2/imagine/images/slider-handle@2x.png new file mode 100644 index 00000000000..57eed9f8aee Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle@2x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle@3x.png b/src/quickcontrols2/imagine/images/slider-handle@3x.png new file mode 100644 index 00000000000..e217a6444f8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle@3x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-handle@4x.png b/src/quickcontrols2/imagine/images/slider-handle@4x.png new file mode 100644 index 00000000000..c212b59f559 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-handle@4x.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-horizontal-disabled.9.png b/src/quickcontrols2/imagine/images/slider-progress-horizontal-disabled.9.png new file mode 100644 index 00000000000..7f7e6b935aa Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-horizontal-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-horizontal-disabled@2x.9.png b/src/quickcontrols2/imagine/images/slider-progress-horizontal-disabled@2x.9.png new file mode 100644 index 00000000000..cbf6fb6352b Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-horizontal-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-horizontal-disabled@3x.9.png b/src/quickcontrols2/imagine/images/slider-progress-horizontal-disabled@3x.9.png new file mode 100644 index 00000000000..643776b8c95 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-horizontal-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-horizontal-disabled@4x.9.png b/src/quickcontrols2/imagine/images/slider-progress-horizontal-disabled@4x.9.png new file mode 100644 index 00000000000..d64acb904d4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-horizontal-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-horizontal.9.png b/src/quickcontrols2/imagine/images/slider-progress-horizontal.9.png new file mode 100644 index 00000000000..43192f54162 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-horizontal.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-horizontal@2x.9.png b/src/quickcontrols2/imagine/images/slider-progress-horizontal@2x.9.png new file mode 100644 index 00000000000..ebbbbf82f8b Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-horizontal@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-horizontal@3x.9.png b/src/quickcontrols2/imagine/images/slider-progress-horizontal@3x.9.png new file mode 100644 index 00000000000..0a029b53e46 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-horizontal@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-horizontal@4x.9.png b/src/quickcontrols2/imagine/images/slider-progress-horizontal@4x.9.png new file mode 100644 index 00000000000..a13541691a9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-horizontal@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-vertical-disabled.9.png b/src/quickcontrols2/imagine/images/slider-progress-vertical-disabled.9.png new file mode 100644 index 00000000000..a4edafc971b Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-vertical-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-vertical-disabled@2x.9.png b/src/quickcontrols2/imagine/images/slider-progress-vertical-disabled@2x.9.png new file mode 100644 index 00000000000..8c38226e611 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-vertical-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-vertical-disabled@3x.9.png b/src/quickcontrols2/imagine/images/slider-progress-vertical-disabled@3x.9.png new file mode 100644 index 00000000000..a939bffde86 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-vertical-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-vertical-disabled@4x.9.png b/src/quickcontrols2/imagine/images/slider-progress-vertical-disabled@4x.9.png new file mode 100644 index 00000000000..9f653770e24 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-vertical-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-vertical.9.png b/src/quickcontrols2/imagine/images/slider-progress-vertical.9.png new file mode 100644 index 00000000000..d3e877fc342 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-vertical.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-vertical@2x.9.png b/src/quickcontrols2/imagine/images/slider-progress-vertical@2x.9.png new file mode 100644 index 00000000000..7790050e644 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-vertical@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-vertical@3x.9.png b/src/quickcontrols2/imagine/images/slider-progress-vertical@3x.9.png new file mode 100644 index 00000000000..039d198751c Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-vertical@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/slider-progress-vertical@4x.9.png b/src/quickcontrols2/imagine/images/slider-progress-vertical@4x.9.png new file mode 100644 index 00000000000..b3051d1f467 Binary files /dev/null and b/src/quickcontrols2/imagine/images/slider-progress-vertical@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background-disabled.9.png b/src/quickcontrols2/imagine/images/spinbox-background-disabled.9.png new file mode 100644 index 00000000000..7baaeec525e Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background-disabled@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-background-disabled@2x.9.png new file mode 100644 index 00000000000..e0d59070348 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background-disabled@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-background-disabled@3x.9.png new file mode 100644 index 00000000000..24b3054ded7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background-disabled@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-background-disabled@4x.9.png new file mode 100644 index 00000000000..8ac4740a7b1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background-editable.9.png b/src/quickcontrols2/imagine/images/spinbox-background-editable.9.png new file mode 100644 index 00000000000..995c8276594 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background-editable.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background-editable@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-background-editable@2x.9.png new file mode 100644 index 00000000000..42c9dd6ba21 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background-editable@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background-editable@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-background-editable@3x.9.png new file mode 100644 index 00000000000..4ee974a1442 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background-editable@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background-editable@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-background-editable@4x.9.png new file mode 100644 index 00000000000..59b00915396 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background-editable@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background-focused.9.png b/src/quickcontrols2/imagine/images/spinbox-background-focused.9.png new file mode 100644 index 00000000000..27751eacc8b Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background-focused@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-background-focused@2x.9.png new file mode 100644 index 00000000000..1692578f6cd Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background-focused@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-background-focused@3x.9.png new file mode 100644 index 00000000000..4c44c1bbbc3 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background-focused@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-background-focused@4x.9.png new file mode 100644 index 00000000000..f8632bf2f8a Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background.9.png b/src/quickcontrols2/imagine/images/spinbox-background.9.png new file mode 100644 index 00000000000..ae8b043beb3 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-background@2x.9.png new file mode 100644 index 00000000000..eaae097e2f2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-background@3x.9.png new file mode 100644 index 00000000000..d8add8117c1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-background@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-background@4x.9.png new file mode 100644 index 00000000000..d954febfc23 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-disabled.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-disabled.9.png new file mode 100644 index 00000000000..b3953398d8d Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-disabled@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-disabled@2x.9.png new file mode 100644 index 00000000000..18e2ca65d41 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-disabled@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-disabled@3x.9.png new file mode 100644 index 00000000000..ed6674b47b3 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-disabled@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-disabled@4x.9.png new file mode 100644 index 00000000000..0da2cf93ff2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-focused.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-focused.9.png new file mode 100644 index 00000000000..46220a8ebe9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-focused@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-focused@2x.9.png new file mode 100644 index 00000000000..b8ebb7b7eb0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-focused@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-focused@3x.9.png new file mode 100644 index 00000000000..10561d8dbbd Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-focused@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-focused@4x.9.png new file mode 100644 index 00000000000..ccd09d69a58 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-hovered.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-hovered.9.png new file mode 100644 index 00000000000..46220a8ebe9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-hovered@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-hovered@2x.9.png new file mode 100644 index 00000000000..b8ebb7b7eb0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-hovered@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-hovered@3x.9.png new file mode 100644 index 00000000000..10561d8dbbd Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-hovered@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-hovered@4x.9.png new file mode 100644 index 00000000000..ccd09d69a58 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-focused.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-focused.9.png new file mode 100644 index 00000000000..23842de4e6e Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-focused@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-focused@2x.9.png new file mode 100644 index 00000000000..e50789323aa Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-focused@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-focused@3x.9.png new file mode 100644 index 00000000000..7edec0c9b3a Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-focused@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-focused@4x.9.png new file mode 100644 index 00000000000..f6e5ff8201a Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-hovered.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-hovered.9.png new file mode 100644 index 00000000000..23842de4e6e Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-hovered@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-hovered@2x.9.png new file mode 100644 index 00000000000..e50789323aa Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-hovered@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-hovered@3x.9.png new file mode 100644 index 00000000000..7edec0c9b3a Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-hovered@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-hovered@4x.9.png new file mode 100644 index 00000000000..f6e5ff8201a Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-pressed.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-pressed.9.png new file mode 100644 index 00000000000..b6917a036bc Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-pressed@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-pressed@2x.9.png new file mode 100644 index 00000000000..8999d3e4416 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-pressed@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-pressed@3x.9.png new file mode 100644 index 00000000000..77aa004465a Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-pressed@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-pressed@4x.9.png new file mode 100644 index 00000000000..4f2fd261aba Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored.9.png new file mode 100644 index 00000000000..3c3da5b1a17 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored@2x.9.png new file mode 100644 index 00000000000..e0760e07cd4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored@3x.9.png new file mode 100644 index 00000000000..c37080f5b87 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored@4x.9.png new file mode 100644 index 00000000000..bdc248231a7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-mirrored@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-pressed.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-pressed.9.png new file mode 100644 index 00000000000..65f2821bcd2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-pressed@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-pressed@2x.9.png new file mode 100644 index 00000000000..010dd9d0bbc Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-pressed@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-pressed@3x.9.png new file mode 100644 index 00000000000..f647f489d2b Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-pressed@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-pressed@4x.9.png new file mode 100644 index 00000000000..db0486d1fc4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable.9.png new file mode 100644 index 00000000000..c3207f311b8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable@2x.9.png new file mode 100644 index 00000000000..c8c2630e83d Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable@3x.9.png new file mode 100644 index 00000000000..d0a6c81816e Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable@4x.9.png new file mode 100644 index 00000000000..40e897623be Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-editable@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-focused.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-focused.9.png new file mode 100644 index 00000000000..6ad31bb0e28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-focused@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-focused@2x.9.png new file mode 100644 index 00000000000..6cc60b4b54d Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-focused@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-focused@3x.9.png new file mode 100644 index 00000000000..722c7ec7088 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-focused@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-focused@4x.9.png new file mode 100644 index 00000000000..64fa4ab6c04 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-hovered.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-hovered.9.png new file mode 100644 index 00000000000..6ad31bb0e28 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-hovered@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-hovered@2x.9.png new file mode 100644 index 00000000000..6cc60b4b54d Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-hovered@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-hovered@3x.9.png new file mode 100644 index 00000000000..722c7ec7088 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-hovered@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-hovered@4x.9.png new file mode 100644 index 00000000000..64fa4ab6c04 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-disabled.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-disabled.9.png new file mode 100644 index 00000000000..ac7da20e656 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-disabled@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-disabled@2x.9.png new file mode 100644 index 00000000000..a12f3615357 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-disabled@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-disabled@3x.9.png new file mode 100644 index 00000000000..de11317bc1a Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-disabled@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-disabled@4x.9.png new file mode 100644 index 00000000000..8be41f3898b Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-focused.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-focused.9.png new file mode 100644 index 00000000000..6b6e5264363 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-focused@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-focused@2x.9.png new file mode 100644 index 00000000000..e0c36da35d2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-focused@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-focused@3x.9.png new file mode 100644 index 00000000000..ca2389dac44 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-focused@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-focused@4x.9.png new file mode 100644 index 00000000000..7e6c5474199 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-hovered.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-hovered.9.png new file mode 100644 index 00000000000..6b6e5264363 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-hovered@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-hovered@2x.9.png new file mode 100644 index 00000000000..e0c36da35d2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-hovered@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-hovered@3x.9.png new file mode 100644 index 00000000000..ca2389dac44 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-hovered@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-hovered@4x.9.png new file mode 100644 index 00000000000..7e6c5474199 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-pressed.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-pressed.9.png new file mode 100644 index 00000000000..d756679febd Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-pressed@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-pressed@2x.9.png new file mode 100644 index 00000000000..e49c7e89858 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-pressed@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-pressed@3x.9.png new file mode 100644 index 00000000000..6041ffdcc0c Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-pressed@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-pressed@4x.9.png new file mode 100644 index 00000000000..e23dda155e0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored.9.png new file mode 100644 index 00000000000..58be2120327 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored@2x.9.png new file mode 100644 index 00000000000..709a1ab6c6a Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored@3x.9.png new file mode 100644 index 00000000000..ee5b5b82257 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored@4x.9.png new file mode 100644 index 00000000000..1e88d44dbac Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-mirrored@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-pressed.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-pressed.9.png new file mode 100644 index 00000000000..9703314b47a Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-pressed@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-pressed@2x.9.png new file mode 100644 index 00000000000..173eccfbe33 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-pressed@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-pressed@3x.9.png new file mode 100644 index 00000000000..77737c7593a Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down-pressed@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down-pressed@4x.9.png new file mode 100644 index 00000000000..6a2bb865cb9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down.9.png new file mode 100644 index 00000000000..a6c9679a43c Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down@2x.9.png new file mode 100644 index 00000000000..bd14cdbbfca Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down@3x.9.png new file mode 100644 index 00000000000..02d18c1d8e4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-down@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-down@4x.9.png new file mode 100644 index 00000000000..9ec1bf0459e Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-down@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-disabled.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-disabled.9.png new file mode 100644 index 00000000000..5fe5ab6ad55 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-disabled@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-disabled@2x.9.png new file mode 100644 index 00000000000..f7a2a5d56d0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-disabled@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-disabled@3x.9.png new file mode 100644 index 00000000000..3244c93f141 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-disabled@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-disabled@4x.9.png new file mode 100644 index 00000000000..82482005597 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-focused.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-focused.9.png new file mode 100644 index 00000000000..d291c50a76e Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-focused@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-focused@2x.9.png new file mode 100644 index 00000000000..06e27b1b8eb Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-focused@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-focused@3x.9.png new file mode 100644 index 00000000000..34b43735588 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-focused@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-focused@4x.9.png new file mode 100644 index 00000000000..4a95cca469c Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-hovered.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-hovered.9.png new file mode 100644 index 00000000000..d291c50a76e Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-hovered@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-hovered@2x.9.png new file mode 100644 index 00000000000..06e27b1b8eb Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-hovered@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-hovered@3x.9.png new file mode 100644 index 00000000000..34b43735588 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-hovered@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-hovered@4x.9.png new file mode 100644 index 00000000000..4a95cca469c Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-focused.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-focused.9.png new file mode 100644 index 00000000000..a98d5a1d427 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-focused@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-focused@2x.9.png new file mode 100644 index 00000000000..4b8458600a5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-focused@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-focused@3x.9.png new file mode 100644 index 00000000000..da241c07ae4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-focused@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-focused@4x.9.png new file mode 100644 index 00000000000..d1333671ffe Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-hovered.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-hovered.9.png new file mode 100644 index 00000000000..a98d5a1d427 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-hovered@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-hovered@2x.9.png new file mode 100644 index 00000000000..4b8458600a5 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-hovered@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-hovered@3x.9.png new file mode 100644 index 00000000000..da241c07ae4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-hovered@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-hovered@4x.9.png new file mode 100644 index 00000000000..d1333671ffe Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-pressed.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-pressed.9.png new file mode 100644 index 00000000000..793e009d828 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-pressed@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-pressed@2x.9.png new file mode 100644 index 00000000000..aca00c57c03 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-pressed@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-pressed@3x.9.png new file mode 100644 index 00000000000..a49b95498c9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-pressed@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-pressed@4x.9.png new file mode 100644 index 00000000000..e0814f3be37 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored.9.png new file mode 100644 index 00000000000..ac4c46d1843 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored@2x.9.png new file mode 100644 index 00000000000..b1c335ee536 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored@3x.9.png new file mode 100644 index 00000000000..3f0d9f2f25a Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored@4x.9.png new file mode 100644 index 00000000000..cac6eca867d Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-mirrored@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-pressed.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-pressed.9.png new file mode 100644 index 00000000000..87a1ae7a9a1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-pressed@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-pressed@2x.9.png new file mode 100644 index 00000000000..95c5ea063d1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-pressed@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-pressed@3x.9.png new file mode 100644 index 00000000000..3ed6cddfb8d Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-pressed@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-pressed@4x.9.png new file mode 100644 index 00000000000..8f5e3f02bd7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable.9.png new file mode 100644 index 00000000000..b3cc7bea02d Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable@2x.9.png new file mode 100644 index 00000000000..51313f5953d Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable@3x.9.png new file mode 100644 index 00000000000..8db540f593a Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable@4x.9.png new file mode 100644 index 00000000000..310400a2b54 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-editable@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-focused.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-focused.9.png new file mode 100644 index 00000000000..d88bd00d224 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-focused@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-focused@2x.9.png new file mode 100644 index 00000000000..77dbb52a6a7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-focused@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-focused@3x.9.png new file mode 100644 index 00000000000..0739b1b173e Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-focused@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-focused@4x.9.png new file mode 100644 index 00000000000..d53ee543e37 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-hovered.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-hovered.9.png new file mode 100644 index 00000000000..d88bd00d224 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-hovered@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-hovered@2x.9.png new file mode 100644 index 00000000000..77dbb52a6a7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-hovered@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-hovered@3x.9.png new file mode 100644 index 00000000000..0739b1b173e Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-hovered@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-hovered@4x.9.png new file mode 100644 index 00000000000..d53ee543e37 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-disabled.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-disabled.9.png new file mode 100644 index 00000000000..53f6d7e59c9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-disabled@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-disabled@2x.9.png new file mode 100644 index 00000000000..7c7bb214afa Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-disabled@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-disabled@3x.9.png new file mode 100644 index 00000000000..5a69027cf39 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-disabled@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-disabled@4x.9.png new file mode 100644 index 00000000000..fe2171a5463 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-focused.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-focused.9.png new file mode 100644 index 00000000000..cf31f936682 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-focused@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-focused@2x.9.png new file mode 100644 index 00000000000..48b8861eacc Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-focused@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-focused@3x.9.png new file mode 100644 index 00000000000..d6a417202b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-focused@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-focused@4x.9.png new file mode 100644 index 00000000000..e0c7e374adb Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-hovered.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-hovered.9.png new file mode 100644 index 00000000000..cf31f936682 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-hovered@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-hovered@2x.9.png new file mode 100644 index 00000000000..48b8861eacc Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-hovered@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-hovered@3x.9.png new file mode 100644 index 00000000000..d6a417202b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-hovered@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-hovered@4x.9.png new file mode 100644 index 00000000000..e0c7e374adb Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-pressed.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-pressed.9.png new file mode 100644 index 00000000000..4548cddd91d Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-pressed@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-pressed@2x.9.png new file mode 100644 index 00000000000..c5fb9d1b3d4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-pressed@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-pressed@3x.9.png new file mode 100644 index 00000000000..ffbe520a19e Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-pressed@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-pressed@4x.9.png new file mode 100644 index 00000000000..784f9bee964 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored.9.png new file mode 100644 index 00000000000..f26794570d7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored@2x.9.png new file mode 100644 index 00000000000..7f07e625adc Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored@3x.9.png new file mode 100644 index 00000000000..0b060816ec6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored@4x.9.png new file mode 100644 index 00000000000..df76dfcec13 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-mirrored@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-pressed.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-pressed.9.png new file mode 100644 index 00000000000..cbba897fc40 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-pressed@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-pressed@2x.9.png new file mode 100644 index 00000000000..a49e11fa4e6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-pressed@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-pressed@3x.9.png new file mode 100644 index 00000000000..720e4543263 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up-pressed@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up-pressed@4x.9.png new file mode 100644 index 00000000000..46333e3df8f Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up.9.png new file mode 100644 index 00000000000..67cbe4345bf Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up@2x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up@2x.9.png new file mode 100644 index 00000000000..8e804b8735b Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up@3x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up@3x.9.png new file mode 100644 index 00000000000..15baec74c86 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/spinbox-indicator-up@4x.9.png b/src/quickcontrols2/imagine/images/spinbox-indicator-up@4x.9.png new file mode 100644 index 00000000000..7112de67e37 Binary files /dev/null and b/src/quickcontrols2/imagine/images/spinbox-indicator-up@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle-disabled.png b/src/quickcontrols2/imagine/images/splitview-handle-disabled.png new file mode 100644 index 00000000000..8ab854b0a30 Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle-disabled@2x.png b/src/quickcontrols2/imagine/images/splitview-handle-disabled@2x.png new file mode 100644 index 00000000000..325469b8d89 Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle-disabled@3x.png b/src/quickcontrols2/imagine/images/splitview-handle-disabled@3x.png new file mode 100644 index 00000000000..5357e847835 Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle-disabled@4x.png b/src/quickcontrols2/imagine/images/splitview-handle-disabled@4x.png new file mode 100644 index 00000000000..e215cf5b7aa Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle-hovered.png b/src/quickcontrols2/imagine/images/splitview-handle-hovered.png new file mode 100644 index 00000000000..429d55081f7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle-hovered@2x.png b/src/quickcontrols2/imagine/images/splitview-handle-hovered@2x.png new file mode 100644 index 00000000000..6f17b06ef32 Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle-hovered@3x.png b/src/quickcontrols2/imagine/images/splitview-handle-hovered@3x.png new file mode 100644 index 00000000000..11dcfa261c7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle-hovered@4x.png b/src/quickcontrols2/imagine/images/splitview-handle-hovered@4x.png new file mode 100644 index 00000000000..73963d754cd Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle-pressed.png b/src/quickcontrols2/imagine/images/splitview-handle-pressed.png new file mode 100644 index 00000000000..6e00db20e66 Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle-pressed@2x.png b/src/quickcontrols2/imagine/images/splitview-handle-pressed@2x.png new file mode 100644 index 00000000000..e1392de62ba Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle-pressed@3x.png b/src/quickcontrols2/imagine/images/splitview-handle-pressed@3x.png new file mode 100644 index 00000000000..ff6a397f694 Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle-pressed@4x.png b/src/quickcontrols2/imagine/images/splitview-handle-pressed@4x.png new file mode 100644 index 00000000000..278ba900073 Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle.png b/src/quickcontrols2/imagine/images/splitview-handle.png new file mode 100644 index 00000000000..2b69cef6a32 Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle@2x.png b/src/quickcontrols2/imagine/images/splitview-handle@2x.png new file mode 100644 index 00000000000..cc3205f125b Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle@2x.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle@3x.png b/src/quickcontrols2/imagine/images/splitview-handle@3x.png new file mode 100644 index 00000000000..b8be2b4d8fe Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle@3x.png differ diff --git a/src/quickcontrols2/imagine/images/splitview-handle@4x.png b/src/quickcontrols2/imagine/images/splitview-handle@4x.png new file mode 100644 index 00000000000..3145295446e Binary files /dev/null and b/src/quickcontrols2/imagine/images/splitview-handle@4x.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-disabled.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-disabled.9.png new file mode 100644 index 00000000000..23570729d68 Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-disabled@2x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-disabled@2x.9.png new file mode 100644 index 00000000000..c7abb65c3f9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-disabled@3x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-disabled@3x.9.png new file mode 100644 index 00000000000..46b84d7da48 Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-disabled@4x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-disabled@4x.9.png new file mode 100644 index 00000000000..f4dfd338f9c Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-focused.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-focused.9.png new file mode 100644 index 00000000000..6ae574d55a6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-focused@2x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-focused@2x.9.png new file mode 100644 index 00000000000..6b61562c14d Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-focused@3x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-focused@3x.9.png new file mode 100644 index 00000000000..e46c0bf1d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-focused@4x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-focused@4x.9.png new file mode 100644 index 00000000000..010444e8e1d Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-highlighted.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-highlighted.9.png new file mode 100644 index 00000000000..e79d8e1d015 Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-highlighted.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-highlighted@2x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-highlighted@2x.9.png new file mode 100644 index 00000000000..ea68d35fc4a Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-highlighted@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-highlighted@3x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-highlighted@3x.9.png new file mode 100644 index 00000000000..6d61041599f Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-highlighted@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-highlighted@4x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-highlighted@4x.9.png new file mode 100644 index 00000000000..590cca96a17 Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-highlighted@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-hovered.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-hovered.9.png new file mode 100644 index 00000000000..b8749743d0e Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-hovered@2x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-hovered@2x.9.png new file mode 100644 index 00000000000..5a136a0ca9b Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-hovered@3x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-hovered@3x.9.png new file mode 100644 index 00000000000..f47a366b7bb Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-hovered@4x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-hovered@4x.9.png new file mode 100644 index 00000000000..9ecb680f20c Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-pressed.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-pressed.9.png new file mode 100644 index 00000000000..6ae574d55a6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-pressed@2x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-pressed@2x.9.png new file mode 100644 index 00000000000..6b61562c14d Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-pressed@3x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-pressed@3x.9.png new file mode 100644 index 00000000000..e46c0bf1d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background-pressed@4x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background-pressed@4x.9.png new file mode 100644 index 00000000000..010444e8e1d Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background.9.png new file mode 100644 index 00000000000..b8749743d0e Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background@2x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background@2x.9.png new file mode 100644 index 00000000000..5a136a0ca9b Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background@3x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background@3x.9.png new file mode 100644 index 00000000000..f47a366b7bb Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/swipedelegate-background@4x.9.png b/src/quickcontrols2/imagine/images/swipedelegate-background@4x.9.png new file mode 100644 index 00000000000..9ecb680f20c Binary files /dev/null and b/src/quickcontrols2/imagine/images/swipedelegate-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switch-handle-disabled.png b/src/quickcontrols2/imagine/images/switch-handle-disabled.png new file mode 100644 index 00000000000..595dd5465da Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-handle-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/switch-handle-disabled@2x.png b/src/quickcontrols2/imagine/images/switch-handle-disabled@2x.png new file mode 100644 index 00000000000..5be736aafa0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-handle-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-handle-disabled@3x.png b/src/quickcontrols2/imagine/images/switch-handle-disabled@3x.png new file mode 100644 index 00000000000..c8002ca3d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-handle-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-handle-disabled@4x.png b/src/quickcontrols2/imagine/images/switch-handle-disabled@4x.png new file mode 100644 index 00000000000..00e70c1ba50 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-handle-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-handle-pressed.png b/src/quickcontrols2/imagine/images/switch-handle-pressed.png new file mode 100644 index 00000000000..595dd5465da Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-handle-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/switch-handle-pressed@2x.png b/src/quickcontrols2/imagine/images/switch-handle-pressed@2x.png new file mode 100644 index 00000000000..5be736aafa0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-handle-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-handle-pressed@3x.png b/src/quickcontrols2/imagine/images/switch-handle-pressed@3x.png new file mode 100644 index 00000000000..c8002ca3d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-handle-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-handle-pressed@4x.png b/src/quickcontrols2/imagine/images/switch-handle-pressed@4x.png new file mode 100644 index 00000000000..00e70c1ba50 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-handle-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-handle.png b/src/quickcontrols2/imagine/images/switch-handle.png new file mode 100644 index 00000000000..15649c34c79 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-handle.png differ diff --git a/src/quickcontrols2/imagine/images/switch-handle@2x.png b/src/quickcontrols2/imagine/images/switch-handle@2x.png new file mode 100644 index 00000000000..04f84ed9206 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-handle@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-handle@3x.png b/src/quickcontrols2/imagine/images/switch-handle@3x.png new file mode 100644 index 00000000000..e0cfb637181 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-handle@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-handle@4x.png b/src/quickcontrols2/imagine/images/switch-handle@4x.png new file mode 100644 index 00000000000..73fa381a4a2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-handle@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked-focused.png b/src/quickcontrols2/imagine/images/switch-indicator-checked-focused.png new file mode 100644 index 00000000000..7f5ba5dfc4f Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked-focused.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked-focused@2x.png b/src/quickcontrols2/imagine/images/switch-indicator-checked-focused@2x.png new file mode 100644 index 00000000000..a0090df49f8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked-focused@3x.png b/src/quickcontrols2/imagine/images/switch-indicator-checked-focused@3x.png new file mode 100644 index 00000000000..0c7e5264591 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked-focused@4x.png b/src/quickcontrols2/imagine/images/switch-indicator-checked-focused@4x.png new file mode 100644 index 00000000000..3a5e1d36ca7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked-hovered.png b/src/quickcontrols2/imagine/images/switch-indicator-checked-hovered.png new file mode 100644 index 00000000000..7f5ba5dfc4f Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked-hovered@2x.png b/src/quickcontrols2/imagine/images/switch-indicator-checked-hovered@2x.png new file mode 100644 index 00000000000..a0090df49f8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked-hovered@3x.png b/src/quickcontrols2/imagine/images/switch-indicator-checked-hovered@3x.png new file mode 100644 index 00000000000..0c7e5264591 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked-hovered@4x.png b/src/quickcontrols2/imagine/images/switch-indicator-checked-hovered@4x.png new file mode 100644 index 00000000000..3a5e1d36ca7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked-pressed.png b/src/quickcontrols2/imagine/images/switch-indicator-checked-pressed.png new file mode 100644 index 00000000000..ecbc552a170 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked-pressed@2x.png b/src/quickcontrols2/imagine/images/switch-indicator-checked-pressed@2x.png new file mode 100644 index 00000000000..07fe7241d8e Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked-pressed@3x.png b/src/quickcontrols2/imagine/images/switch-indicator-checked-pressed@3x.png new file mode 100644 index 00000000000..8c65c27f4e6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked-pressed@4x.png b/src/quickcontrols2/imagine/images/switch-indicator-checked-pressed@4x.png new file mode 100644 index 00000000000..f6a1e476587 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked.png b/src/quickcontrols2/imagine/images/switch-indicator-checked.png new file mode 100644 index 00000000000..2b7265cd0f1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked@2x.png b/src/quickcontrols2/imagine/images/switch-indicator-checked@2x.png new file mode 100644 index 00000000000..6ec88c7fc8a Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked@3x.png b/src/quickcontrols2/imagine/images/switch-indicator-checked@3x.png new file mode 100644 index 00000000000..48c979856af Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-checked@4x.png b/src/quickcontrols2/imagine/images/switch-indicator-checked@4x.png new file mode 100644 index 00000000000..e9f81807daf Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-checked@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-disabled.png b/src/quickcontrols2/imagine/images/switch-indicator-disabled.png new file mode 100644 index 00000000000..9cfab791977 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-disabled@2x.png b/src/quickcontrols2/imagine/images/switch-indicator-disabled@2x.png new file mode 100644 index 00000000000..3bbbb8dfbc8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-disabled@3x.png b/src/quickcontrols2/imagine/images/switch-indicator-disabled@3x.png new file mode 100644 index 00000000000..80d9a74685c Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-disabled@4x.png b/src/quickcontrols2/imagine/images/switch-indicator-disabled@4x.png new file mode 100644 index 00000000000..9ee7bfabbc8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-focused.png b/src/quickcontrols2/imagine/images/switch-indicator-focused.png new file mode 100644 index 00000000000..4867bcac54c Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-focused.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-focused@2x.png b/src/quickcontrols2/imagine/images/switch-indicator-focused@2x.png new file mode 100644 index 00000000000..d833a0cdb47 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-focused@3x.png b/src/quickcontrols2/imagine/images/switch-indicator-focused@3x.png new file mode 100644 index 00000000000..a632b6ae1c8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-focused@4x.png b/src/quickcontrols2/imagine/images/switch-indicator-focused@4x.png new file mode 100644 index 00000000000..b5affab7728 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-hovered.png b/src/quickcontrols2/imagine/images/switch-indicator-hovered.png new file mode 100644 index 00000000000..4867bcac54c Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-hovered@2x.png b/src/quickcontrols2/imagine/images/switch-indicator-hovered@2x.png new file mode 100644 index 00000000000..d833a0cdb47 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-hovered@3x.png b/src/quickcontrols2/imagine/images/switch-indicator-hovered@3x.png new file mode 100644 index 00000000000..a632b6ae1c8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-hovered@4x.png b/src/quickcontrols2/imagine/images/switch-indicator-hovered@4x.png new file mode 100644 index 00000000000..b5affab7728 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-pressed.png b/src/quickcontrols2/imagine/images/switch-indicator-pressed.png new file mode 100644 index 00000000000..4fbbc060e8d Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-pressed@2x.png b/src/quickcontrols2/imagine/images/switch-indicator-pressed@2x.png new file mode 100644 index 00000000000..7939f943e54 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-pressed@3x.png b/src/quickcontrols2/imagine/images/switch-indicator-pressed@3x.png new file mode 100644 index 00000000000..adcbe45bb72 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator-pressed@4x.png b/src/quickcontrols2/imagine/images/switch-indicator-pressed@4x.png new file mode 100644 index 00000000000..74c0c77e6f1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator.png b/src/quickcontrols2/imagine/images/switch-indicator.png new file mode 100644 index 00000000000..b6b4f1cd798 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator@2x.png b/src/quickcontrols2/imagine/images/switch-indicator@2x.png new file mode 100644 index 00000000000..bfeedeb720f Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator@3x.png b/src/quickcontrols2/imagine/images/switch-indicator@3x.png new file mode 100644 index 00000000000..19e5ba2ca79 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switch-indicator@4x.png b/src/quickcontrols2/imagine/images/switch-indicator@4x.png new file mode 100644 index 00000000000..9345cd4fdb4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switch-indicator@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-disabled.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-disabled.9.png new file mode 100644 index 00000000000..23570729d68 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-disabled@2x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-disabled@2x.9.png new file mode 100644 index 00000000000..c7abb65c3f9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-disabled@3x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-disabled@3x.9.png new file mode 100644 index 00000000000..46b84d7da48 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-disabled@4x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-disabled@4x.9.png new file mode 100644 index 00000000000..f4dfd338f9c Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-focused.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-focused.9.png new file mode 100644 index 00000000000..6ae574d55a6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-focused@2x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-focused@2x.9.png new file mode 100644 index 00000000000..6b61562c14d Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-focused@3x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-focused@3x.9.png new file mode 100644 index 00000000000..e46c0bf1d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-focused@4x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-focused@4x.9.png new file mode 100644 index 00000000000..010444e8e1d Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-hovered.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-hovered.9.png new file mode 100644 index 00000000000..b8749743d0e Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-hovered@2x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-hovered@2x.9.png new file mode 100644 index 00000000000..5a136a0ca9b Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-hovered@3x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-hovered@3x.9.png new file mode 100644 index 00000000000..f47a366b7bb Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-hovered@4x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-hovered@4x.9.png new file mode 100644 index 00000000000..9ecb680f20c Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-pressed.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-pressed.9.png new file mode 100644 index 00000000000..6ae574d55a6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-pressed@2x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-pressed@2x.9.png new file mode 100644 index 00000000000..6b61562c14d Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-pressed@3x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-pressed@3x.9.png new file mode 100644 index 00000000000..e46c0bf1d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background-pressed@4x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background-pressed@4x.9.png new file mode 100644 index 00000000000..010444e8e1d Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background.9.png new file mode 100644 index 00000000000..b8749743d0e Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background@2x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background@2x.9.png new file mode 100644 index 00000000000..5a136a0ca9b Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background@3x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background@3x.9.png new file mode 100644 index 00000000000..f47a366b7bb Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-background@4x.9.png b/src/quickcontrols2/imagine/images/switchdelegate-background@4x.9.png new file mode 100644 index 00000000000..9ecb680f20c Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-handle-disabled.png b/src/quickcontrols2/imagine/images/switchdelegate-handle-disabled.png new file mode 100644 index 00000000000..595dd5465da Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-handle-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-handle-disabled@2x.png b/src/quickcontrols2/imagine/images/switchdelegate-handle-disabled@2x.png new file mode 100644 index 00000000000..5be736aafa0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-handle-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-handle-disabled@3x.png b/src/quickcontrols2/imagine/images/switchdelegate-handle-disabled@3x.png new file mode 100644 index 00000000000..c8002ca3d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-handle-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-handle-disabled@4x.png b/src/quickcontrols2/imagine/images/switchdelegate-handle-disabled@4x.png new file mode 100644 index 00000000000..00e70c1ba50 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-handle-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-handle-pressed.png b/src/quickcontrols2/imagine/images/switchdelegate-handle-pressed.png new file mode 100644 index 00000000000..595dd5465da Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-handle-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-handle-pressed@2x.png b/src/quickcontrols2/imagine/images/switchdelegate-handle-pressed@2x.png new file mode 100644 index 00000000000..5be736aafa0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-handle-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-handle-pressed@3x.png b/src/quickcontrols2/imagine/images/switchdelegate-handle-pressed@3x.png new file mode 100644 index 00000000000..c8002ca3d9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-handle-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-handle-pressed@4x.png b/src/quickcontrols2/imagine/images/switchdelegate-handle-pressed@4x.png new file mode 100644 index 00000000000..00e70c1ba50 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-handle-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-handle.png b/src/quickcontrols2/imagine/images/switchdelegate-handle.png new file mode 100644 index 00000000000..15649c34c79 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-handle.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-handle@2x.png b/src/quickcontrols2/imagine/images/switchdelegate-handle@2x.png new file mode 100644 index 00000000000..04f84ed9206 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-handle@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-handle@3x.png b/src/quickcontrols2/imagine/images/switchdelegate-handle@3x.png new file mode 100644 index 00000000000..e0cfb637181 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-handle@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-handle@4x.png b/src/quickcontrols2/imagine/images/switchdelegate-handle@4x.png new file mode 100644 index 00000000000..73fa381a4a2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-handle@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-focused.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-focused.png new file mode 100644 index 00000000000..7f5ba5dfc4f Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-focused.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-focused@2x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-focused@2x.png new file mode 100644 index 00000000000..a0090df49f8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-focused@3x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-focused@3x.png new file mode 100644 index 00000000000..0c7e5264591 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-focused@4x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-focused@4x.png new file mode 100644 index 00000000000..3a5e1d36ca7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-hovered.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-hovered.png new file mode 100644 index 00000000000..7f5ba5dfc4f Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-hovered@2x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-hovered@2x.png new file mode 100644 index 00000000000..a0090df49f8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-hovered@3x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-hovered@3x.png new file mode 100644 index 00000000000..0c7e5264591 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-hovered@4x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-hovered@4x.png new file mode 100644 index 00000000000..3a5e1d36ca7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-pressed.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-pressed.png new file mode 100644 index 00000000000..ecbc552a170 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-pressed@2x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-pressed@2x.png new file mode 100644 index 00000000000..07fe7241d8e Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-pressed@3x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-pressed@3x.png new file mode 100644 index 00000000000..8c65c27f4e6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-pressed@4x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-pressed@4x.png new file mode 100644 index 00000000000..f6a1e476587 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked.png new file mode 100644 index 00000000000..2b7265cd0f1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked@2x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked@2x.png new file mode 100644 index 00000000000..6ec88c7fc8a Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked@3x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked@3x.png new file mode 100644 index 00000000000..48c979856af Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked@4x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked@4x.png new file mode 100644 index 00000000000..e9f81807daf Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-checked@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-disabled.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-disabled.png new file mode 100644 index 00000000000..9cfab791977 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-disabled.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-disabled@2x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-disabled@2x.png new file mode 100644 index 00000000000..3bbbb8dfbc8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-disabled@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-disabled@3x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-disabled@3x.png new file mode 100644 index 00000000000..80d9a74685c Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-disabled@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-disabled@4x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-disabled@4x.png new file mode 100644 index 00000000000..9ee7bfabbc8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-disabled@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-focused.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-focused.png new file mode 100644 index 00000000000..4867bcac54c Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-focused.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-focused@2x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-focused@2x.png new file mode 100644 index 00000000000..d833a0cdb47 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-focused@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-focused@3x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-focused@3x.png new file mode 100644 index 00000000000..a632b6ae1c8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-focused@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-focused@4x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-focused@4x.png new file mode 100644 index 00000000000..b5affab7728 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-focused@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-hovered.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-hovered.png new file mode 100644 index 00000000000..4867bcac54c Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-hovered.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-hovered@2x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-hovered@2x.png new file mode 100644 index 00000000000..d833a0cdb47 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-hovered@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-hovered@3x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-hovered@3x.png new file mode 100644 index 00000000000..a632b6ae1c8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-hovered@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-hovered@4x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-hovered@4x.png new file mode 100644 index 00000000000..b5affab7728 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-hovered@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-pressed.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-pressed.png new file mode 100644 index 00000000000..4fbbc060e8d Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-pressed.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-pressed@2x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-pressed@2x.png new file mode 100644 index 00000000000..7939f943e54 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-pressed@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-pressed@3x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-pressed@3x.png new file mode 100644 index 00000000000..adcbe45bb72 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-pressed@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator-pressed@4x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator-pressed@4x.png new file mode 100644 index 00000000000..74c0c77e6f1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator-pressed@4x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator.png new file mode 100644 index 00000000000..b6b4f1cd798 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator@2x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator@2x.png new file mode 100644 index 00000000000..bfeedeb720f Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator@2x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator@3x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator@3x.png new file mode 100644 index 00000000000..19e5ba2ca79 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator@3x.png differ diff --git a/src/quickcontrols2/imagine/images/switchdelegate-indicator@4x.png b/src/quickcontrols2/imagine/images/switchdelegate-indicator@4x.png new file mode 100644 index 00000000000..9345cd4fdb4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/switchdelegate-indicator@4x.png differ diff --git a/src/quickcontrols2/imagine/images/tabbar-background.png b/src/quickcontrols2/imagine/images/tabbar-background.png new file mode 100644 index 00000000000..002efdedde6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbar-background.png differ diff --git a/src/quickcontrols2/imagine/images/tabbar-background@2x.png b/src/quickcontrols2/imagine/images/tabbar-background@2x.png new file mode 100644 index 00000000000..aaa1cbaf4b0 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbar-background@2x.png differ diff --git a/src/quickcontrols2/imagine/images/tabbar-background@3x.png b/src/quickcontrols2/imagine/images/tabbar-background@3x.png new file mode 100644 index 00000000000..c4eb9e1f02a Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbar-background@3x.png differ diff --git a/src/quickcontrols2/imagine/images/tabbar-background@4x.png b/src/quickcontrols2/imagine/images/tabbar-background@4x.png new file mode 100644 index 00000000000..4a4e234a6a1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbar-background@4x.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-checked.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-checked.9.png new file mode 100644 index 00000000000..d2f0fa76a68 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-checked.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-checked@2x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-checked@2x.9.png new file mode 100644 index 00000000000..bee13292020 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-checked@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-checked@3x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-checked@3x.9.png new file mode 100644 index 00000000000..70afb7d3378 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-checked@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-checked@4x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-checked@4x.9.png new file mode 100644 index 00000000000..3a2015c4640 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-checked@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-disabled-checked.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-disabled-checked.9.png new file mode 100644 index 00000000000..a6d3011bd9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-disabled-checked.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-disabled-checked@2x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-disabled-checked@2x.9.png new file mode 100644 index 00000000000..8ebfa026862 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-disabled-checked@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-disabled-checked@3x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-disabled-checked@3x.9.png new file mode 100644 index 00000000000..1d5a1d51493 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-disabled-checked@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-disabled-checked@4x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-disabled-checked@4x.9.png new file mode 100644 index 00000000000..f06dc55f9b1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-disabled-checked@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-disabled.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-disabled.9.png new file mode 100644 index 00000000000..a6d3011bd9a Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-disabled@2x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-disabled@2x.9.png new file mode 100644 index 00000000000..8ebfa026862 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-disabled@3x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-disabled@3x.9.png new file mode 100644 index 00000000000..1d5a1d51493 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-disabled@4x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-disabled@4x.9.png new file mode 100644 index 00000000000..f06dc55f9b1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-hovered.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-hovered.9.png new file mode 100644 index 00000000000..3f945184f89 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-hovered@2x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-hovered@2x.9.png new file mode 100644 index 00000000000..8a19720a2a6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-hovered@3x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-hovered@3x.9.png new file mode 100644 index 00000000000..eadcf45714b Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-hovered@4x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-hovered@4x.9.png new file mode 100644 index 00000000000..8bf8e992aa7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-pressed.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-pressed.9.png new file mode 100644 index 00000000000..d48733ed81b Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-pressed@2x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-pressed@2x.9.png new file mode 100644 index 00000000000..fbbaad7bec7 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-pressed@3x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-pressed@3x.9.png new file mode 100644 index 00000000000..3a0ba70e633 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background-pressed@4x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background-pressed@4x.9.png new file mode 100644 index 00000000000..c04f124e5ea Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background.9.png b/src/quickcontrols2/imagine/images/tabbutton-background.9.png new file mode 100644 index 00000000000..2266c72223b Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background@2x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background@2x.9.png new file mode 100644 index 00000000000..b7adb7adc31 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background@3x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background@3x.9.png new file mode 100644 index 00000000000..d8f4eae55f1 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tabbutton-background@4x.9.png b/src/quickcontrols2/imagine/images/tabbutton-background@4x.9.png new file mode 100644 index 00000000000..066d35b38ca Binary files /dev/null and b/src/quickcontrols2/imagine/images/tabbutton-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textarea-background-disabled.9.png b/src/quickcontrols2/imagine/images/textarea-background-disabled.9.png new file mode 100644 index 00000000000..97d48f8c00d Binary files /dev/null and b/src/quickcontrols2/imagine/images/textarea-background-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/textarea-background-disabled@2x.9.png b/src/quickcontrols2/imagine/images/textarea-background-disabled@2x.9.png new file mode 100644 index 00000000000..f9ea1d49dd4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textarea-background-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textarea-background-disabled@3x.9.png b/src/quickcontrols2/imagine/images/textarea-background-disabled@3x.9.png new file mode 100644 index 00000000000..04e7ef6f074 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textarea-background-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textarea-background-disabled@4x.9.png b/src/quickcontrols2/imagine/images/textarea-background-disabled@4x.9.png new file mode 100644 index 00000000000..feaaa3bcbcf Binary files /dev/null and b/src/quickcontrols2/imagine/images/textarea-background-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textarea-background-focused.9.png b/src/quickcontrols2/imagine/images/textarea-background-focused.9.png new file mode 100644 index 00000000000..1d73acfa0a9 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textarea-background-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/textarea-background-focused@2x.9.png b/src/quickcontrols2/imagine/images/textarea-background-focused@2x.9.png new file mode 100644 index 00000000000..5be4cd6f8c3 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textarea-background-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textarea-background-focused@3x.9.png b/src/quickcontrols2/imagine/images/textarea-background-focused@3x.9.png new file mode 100644 index 00000000000..6ba3e24610c Binary files /dev/null and b/src/quickcontrols2/imagine/images/textarea-background-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textarea-background-focused@4x.9.png b/src/quickcontrols2/imagine/images/textarea-background-focused@4x.9.png new file mode 100644 index 00000000000..366aa5112ff Binary files /dev/null and b/src/quickcontrols2/imagine/images/textarea-background-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textarea-background.9.png b/src/quickcontrols2/imagine/images/textarea-background.9.png new file mode 100644 index 00000000000..0b9ca9f3ecb Binary files /dev/null and b/src/quickcontrols2/imagine/images/textarea-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/textarea-background@2x.9.png b/src/quickcontrols2/imagine/images/textarea-background@2x.9.png new file mode 100644 index 00000000000..a806ed1b11e Binary files /dev/null and b/src/quickcontrols2/imagine/images/textarea-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textarea-background@3x.9.png b/src/quickcontrols2/imagine/images/textarea-background@3x.9.png new file mode 100644 index 00000000000..547ef33c417 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textarea-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textarea-background@4x.9.png b/src/quickcontrols2/imagine/images/textarea-background@4x.9.png new file mode 100644 index 00000000000..b759b1e80ba Binary files /dev/null and b/src/quickcontrols2/imagine/images/textarea-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textfield-background-disabled.9.png b/src/quickcontrols2/imagine/images/textfield-background-disabled.9.png new file mode 100644 index 00000000000..312a1294d12 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textfield-background-disabled.9.png differ diff --git a/src/quickcontrols2/imagine/images/textfield-background-disabled@2x.9.png b/src/quickcontrols2/imagine/images/textfield-background-disabled@2x.9.png new file mode 100644 index 00000000000..2c6c7e9165d Binary files /dev/null and b/src/quickcontrols2/imagine/images/textfield-background-disabled@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textfield-background-disabled@3x.9.png b/src/quickcontrols2/imagine/images/textfield-background-disabled@3x.9.png new file mode 100644 index 00000000000..1d1aca71775 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textfield-background-disabled@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textfield-background-disabled@4x.9.png b/src/quickcontrols2/imagine/images/textfield-background-disabled@4x.9.png new file mode 100644 index 00000000000..ed93182a706 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textfield-background-disabled@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textfield-background-focused.9.png b/src/quickcontrols2/imagine/images/textfield-background-focused.9.png new file mode 100644 index 00000000000..1251f4e4ccf Binary files /dev/null and b/src/quickcontrols2/imagine/images/textfield-background-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/textfield-background-focused@2x.9.png b/src/quickcontrols2/imagine/images/textfield-background-focused@2x.9.png new file mode 100644 index 00000000000..d535e8bc98f Binary files /dev/null and b/src/quickcontrols2/imagine/images/textfield-background-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textfield-background-focused@3x.9.png b/src/quickcontrols2/imagine/images/textfield-background-focused@3x.9.png new file mode 100644 index 00000000000..9fca3bb2395 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textfield-background-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textfield-background-focused@4x.9.png b/src/quickcontrols2/imagine/images/textfield-background-focused@4x.9.png new file mode 100644 index 00000000000..a275a52e893 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textfield-background-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textfield-background.9.png b/src/quickcontrols2/imagine/images/textfield-background.9.png new file mode 100644 index 00000000000..7ea60968800 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textfield-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/textfield-background@2x.9.png b/src/quickcontrols2/imagine/images/textfield-background@2x.9.png new file mode 100644 index 00000000000..0a4c3f2a9f4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textfield-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textfield-background@3x.9.png b/src/quickcontrols2/imagine/images/textfield-background@3x.9.png new file mode 100644 index 00000000000..e8552741871 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textfield-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/textfield-background@4x.9.png b/src/quickcontrols2/imagine/images/textfield-background@4x.9.png new file mode 100644 index 00000000000..29ef5bb9d23 Binary files /dev/null and b/src/quickcontrols2/imagine/images/textfield-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbar-background.png b/src/quickcontrols2/imagine/images/toolbar-background.png new file mode 100644 index 00000000000..9c67cf27023 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbar-background.png differ diff --git a/src/quickcontrols2/imagine/images/toolbar-background@2x.png b/src/quickcontrols2/imagine/images/toolbar-background@2x.png new file mode 100644 index 00000000000..b0602519a76 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbar-background@2x.png differ diff --git a/src/quickcontrols2/imagine/images/toolbar-background@3x.png b/src/quickcontrols2/imagine/images/toolbar-background@3x.png new file mode 100644 index 00000000000..7f227ca343d Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbar-background@3x.png differ diff --git a/src/quickcontrols2/imagine/images/toolbar-background@4x.png b/src/quickcontrols2/imagine/images/toolbar-background@4x.png new file mode 100644 index 00000000000..4788ecc743d Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbar-background@4x.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-checked-focused.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-checked-focused.9.png new file mode 100644 index 00000000000..287a2872de4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-checked-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-checked-focused@2x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-checked-focused@2x.9.png new file mode 100644 index 00000000000..aa844165618 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-checked-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-checked-focused@3x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-checked-focused@3x.9.png new file mode 100644 index 00000000000..8c6822555b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-checked-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-checked-focused@4x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-checked-focused@4x.9.png new file mode 100644 index 00000000000..89bdd096f84 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-checked-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-checked-hovered.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-checked-hovered.9.png new file mode 100644 index 00000000000..287a2872de4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-checked-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-checked-hovered@2x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-checked-hovered@2x.9.png new file mode 100644 index 00000000000..aa844165618 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-checked-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-checked-hovered@3x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-checked-hovered@3x.9.png new file mode 100644 index 00000000000..8c6822555b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-checked-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-checked-hovered@4x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-checked-hovered@4x.9.png new file mode 100644 index 00000000000..89bdd096f84 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-checked-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-checked.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-checked.9.png new file mode 100644 index 00000000000..287a2872de4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-checked.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-checked@2x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-checked@2x.9.png new file mode 100644 index 00000000000..aa844165618 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-checked@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-checked@3x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-checked@3x.9.png new file mode 100644 index 00000000000..8c6822555b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-checked@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-checked@4x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-checked@4x.9.png new file mode 100644 index 00000000000..89bdd096f84 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-checked@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-disabled-checked.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-disabled-checked.9.png new file mode 100644 index 00000000000..287a2872de4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-disabled-checked.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-disabled-checked@2x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-disabled-checked@2x.9.png new file mode 100644 index 00000000000..aa844165618 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-disabled-checked@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-disabled-checked@3x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-disabled-checked@3x.9.png new file mode 100644 index 00000000000..8c6822555b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-disabled-checked@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-disabled-checked@4x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-disabled-checked@4x.9.png new file mode 100644 index 00000000000..89bdd096f84 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-disabled-checked@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-focused.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-focused.9.png new file mode 100644 index 00000000000..287a2872de4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-focused.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-focused@2x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-focused@2x.9.png new file mode 100644 index 00000000000..aa844165618 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-focused@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-focused@3x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-focused@3x.9.png new file mode 100644 index 00000000000..8c6822555b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-focused@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-focused@4x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-focused@4x.9.png new file mode 100644 index 00000000000..89bdd096f84 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-focused@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-hovered.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-hovered.9.png new file mode 100644 index 00000000000..287a2872de4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-hovered.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-hovered@2x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-hovered@2x.9.png new file mode 100644 index 00000000000..aa844165618 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-hovered@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-hovered@3x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-hovered@3x.9.png new file mode 100644 index 00000000000..8c6822555b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-hovered@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-hovered@4x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-hovered@4x.9.png new file mode 100644 index 00000000000..89bdd096f84 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-hovered@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-pressed.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-pressed.9.png new file mode 100644 index 00000000000..287a2872de4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-pressed.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-pressed@2x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-pressed@2x.9.png new file mode 100644 index 00000000000..aa844165618 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-pressed@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-pressed@3x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-pressed@3x.9.png new file mode 100644 index 00000000000..8c6822555b2 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-pressed@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background-pressed@4x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background-pressed@4x.9.png new file mode 100644 index 00000000000..89bdd096f84 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background-pressed@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background.9.png b/src/quickcontrols2/imagine/images/toolbutton-background.9.png new file mode 100644 index 00000000000..5a72a62128c Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background@2x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background@2x.9.png new file mode 100644 index 00000000000..688a071a84c Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background@3x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background@3x.9.png new file mode 100644 index 00000000000..64375a7e5b6 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolbutton-background@4x.9.png b/src/quickcontrols2/imagine/images/toolbutton-background@4x.9.png new file mode 100644 index 00000000000..96004a103c4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolbutton-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolseparator-separator-horizontal.9.png b/src/quickcontrols2/imagine/images/toolseparator-separator-horizontal.9.png new file mode 100644 index 00000000000..75e3e662298 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolseparator-separator-horizontal.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolseparator-separator-horizontal@2x.9.png b/src/quickcontrols2/imagine/images/toolseparator-separator-horizontal@2x.9.png new file mode 100644 index 00000000000..3662dec9441 Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolseparator-separator-horizontal@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolseparator-separator-horizontal@3x.9.png b/src/quickcontrols2/imagine/images/toolseparator-separator-horizontal@3x.9.png new file mode 100644 index 00000000000..2771470175f Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolseparator-separator-horizontal@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolseparator-separator-horizontal@4x.9.png b/src/quickcontrols2/imagine/images/toolseparator-separator-horizontal@4x.9.png new file mode 100644 index 00000000000..deeda9f5fdc Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolseparator-separator-horizontal@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolseparator-separator-vertical.9.png b/src/quickcontrols2/imagine/images/toolseparator-separator-vertical.9.png new file mode 100644 index 00000000000..5b607aaf5ce Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolseparator-separator-vertical.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolseparator-separator-vertical@2x.9.png b/src/quickcontrols2/imagine/images/toolseparator-separator-vertical@2x.9.png new file mode 100644 index 00000000000..f5a11e0467e Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolseparator-separator-vertical@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolseparator-separator-vertical@3x.9.png b/src/quickcontrols2/imagine/images/toolseparator-separator-vertical@3x.9.png new file mode 100644 index 00000000000..c957280f37f Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolseparator-separator-vertical@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/toolseparator-separator-vertical@4x.9.png b/src/quickcontrols2/imagine/images/toolseparator-separator-vertical@4x.9.png new file mode 100644 index 00000000000..c888689df7e Binary files /dev/null and b/src/quickcontrols2/imagine/images/toolseparator-separator-vertical@4x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tooltip-background.9.png b/src/quickcontrols2/imagine/images/tooltip-background.9.png new file mode 100644 index 00000000000..2e0dc67c3ec Binary files /dev/null and b/src/quickcontrols2/imagine/images/tooltip-background.9.png differ diff --git a/src/quickcontrols2/imagine/images/tooltip-background@2x.9.png b/src/quickcontrols2/imagine/images/tooltip-background@2x.9.png new file mode 100644 index 00000000000..dd5609982fb Binary files /dev/null and b/src/quickcontrols2/imagine/images/tooltip-background@2x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tooltip-background@3x.9.png b/src/quickcontrols2/imagine/images/tooltip-background@3x.9.png new file mode 100644 index 00000000000..fed465427e8 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tooltip-background@3x.9.png differ diff --git a/src/quickcontrols2/imagine/images/tooltip-background@4x.9.png b/src/quickcontrols2/imagine/images/tooltip-background@4x.9.png new file mode 100644 index 00000000000..9bc964908f4 Binary files /dev/null and b/src/quickcontrols2/imagine/images/tooltip-background@4x.9.png differ diff --git a/src/quickcontrols2/imagine/imagine.pri b/src/quickcontrols2/imagine/imagine.pri new file mode 100644 index 00000000000..18a2ee6f92f --- /dev/null +++ b/src/quickcontrols2/imagine/imagine.pri @@ -0,0 +1,59 @@ +HEADERS += \ + $$PWD/qquickimaginestyle_p.h \ + $$PWD/qquickimaginetheme_p.h + +SOURCES += \ + $$PWD/qquickimaginestyle.cpp \ + $$PWD/qquickimaginetheme.cpp + +QML_FILES += \ + $$PWD/ApplicationWindow.qml \ + $$PWD/BusyIndicator.qml \ + $$PWD/Button.qml \ + $$PWD/CheckBox.qml \ + $$PWD/CheckDelegate.qml \ + $$PWD/ComboBox.qml \ + $$PWD/DelayButton.qml \ + $$PWD/Dial.qml \ + $$PWD/Dialog.qml \ + $$PWD/DialogButtonBox.qml \ + $$PWD/Drawer.qml \ + $$PWD/Frame.qml \ + $$PWD/GroupBox.qml \ + $$PWD/HorizontalHeaderView.qml \ + $$PWD/ItemDelegate.qml \ + $$PWD/Label.qml \ + $$PWD/Menu.qml \ + $$PWD/MenuItem.qml \ + $$PWD/MenuSeparator.qml \ + $$PWD/PageIndicator.qml \ + $$PWD/Page.qml \ + $$PWD/Pane.qml \ + $$PWD/Popup.qml \ + $$PWD/ProgressBar.qml \ + $$PWD/RadioButton.qml \ + $$PWD/RadioDelegate.qml \ + $$PWD/RangeSlider.qml \ + $$PWD/RoundButton.qml \ + $$PWD/ScrollView.qml \ + $$PWD/ScrollBar.qml \ + $$PWD/ScrollIndicator.qml \ + $$PWD/SelectionRectangle.qml \ + $$PWD/Slider.qml \ + $$PWD/SpinBox.qml \ + $$PWD/SplitView.qml \ + $$PWD/StackView.qml \ + $$PWD/SwipeDelegate.qml \ + $$PWD/SwipeView.qml \ + $$PWD/Switch.qml \ + $$PWD/SwitchDelegate.qml \ + $$PWD/TextField.qml \ + $$PWD/TextArea.qml \ + $$PWD/TabBar.qml \ + $$PWD/TabButton.qml \ + $$PWD/ToolBar.qml \ + $$PWD/ToolButton.qml \ + $$PWD/ToolSeparator.qml \ + $$PWD/ToolTip.qml \ + $$PWD/Tumbler.qml \ + $$PWD/VerticalHeaderView.qml diff --git a/src/quickcontrols2/imagine/impl/CMakeLists.txt b/src/quickcontrols2/imagine/impl/CMakeLists.txt new file mode 100644 index 00000000000..7c576dbad69 --- /dev/null +++ b/src/quickcontrols2/imagine/impl/CMakeLists.txt @@ -0,0 +1,44 @@ +##################################################################### +## qtquickcontrols2imaginestyleimplplugin Plugin: +##################################################################### + +set(qml_files + "OpacityMask.qml" +) + +qt_internal_add_qml_module(qtquickcontrols2imaginestyleimplplugin + URI "QtQuick.Controls.Imagine.impl" + VERSION "${PROJECT_VERSION}" + CLASS_NAME QtQuickControls2ImagineStyleImplPlugin + PLUGIN_TARGET qtquickcontrols2imaginestyleimplplugin + NO_PLUGIN_OPTIONAL + SOURCES + qquickimageselector.cpp qquickimageselector_p.h + qquickninepatchimage.cpp qquickninepatchimage_p.h + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::QmlPrivate + Qt::QuickControls2ImplPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private +) + +# Resources: +set(qmake_qtquickcontrols2imaginestyleimplplugin_resource_files + "shaders/+glslcore/OpacityMask.frag" + "shaders/+qsb/OpacityMask.frag" + "shaders/OpacityMask.frag" +) + +qt_internal_add_resource(qtquickcontrols2imaginestyleimplplugin "qmake_qtquickcontrols2imaginestyleimplplugin" + PREFIX + "qt-project.org/imports/QtQuick/Controls/Imagine/impl" + FILES + ${qmake_qtquickcontrols2imaginestyleimplplugin_resource_files} +) diff --git a/src/quickcontrols2/imagine/impl/OpacityMask.qml b/src/quickcontrols2/imagine/impl/OpacityMask.qml new file mode 100644 index 00000000000..26663a1b538 --- /dev/null +++ b/src/quickcontrols2/imagine/impl/OpacityMask.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +/* + A cross-graphics API implementation of QtGraphicalEffects' OpacityMask. + */ +Item { + id: rootItem + + property variant source + property variant maskSource + property bool cached: false + + ShaderEffectSource { + id: cacheItem + anchors.fill: parent + visible: rootItem.cached + smooth: true + sourceItem: shaderItem + live: true + hideSource: visible + } + + ShaderEffect { + id: shaderItem + property variant source: rootItem.source + property variant maskSource: rootItem.maskSource + + anchors.fill: parent + + fragmentShader: "qrc:/qt-project.org/imports/QtQuick/Controls/Imagine/impl/shaders/OpacityMask.frag" + } +} diff --git a/src/quickcontrols2/imagine/impl/qquickimageselector.cpp b/src/quickcontrols2/imagine/impl/qquickimageselector.cpp new file mode 100644 index 00000000000..dcb7738c4fc --- /dev/null +++ b/src/quickcontrols2/imagine/impl/qquickimageselector.cpp @@ -0,0 +1,338 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickimageselector_p.h" + +#include <QtCore/qdir.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qcache.h> +#include <QtCore/qloggingcategory.h> +#include <QtCore/qfileselector.h> +#include <QtQml/qqmlfile.h> +#include <QtQml/private/qqmlproperty_p.h> +#include <algorithm> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcQtQuickControlsImagine, "qt.quick.controls.imagine") + +static const int DEFAULT_CACHE = 500; + +static inline int cacheSize() +{ + static bool ok = false; + static const int size = qEnvironmentVariableIntValue("QT_QUICK_CONTROLS_IMAGINE_CACHE", &ok); + return ok ? size : DEFAULT_CACHE; +} + +// input: [focused, pressed] +// => [[focused, pressed], [pressed, focused], [focused], [pressed]] +static QList<QStringList> permutations(const QStringList &input, int count = -1) +{ + if (count == -1) + count = input.count(); + + QList<QStringList> output; + for (int i = 0; i < input.count(); ++i) { + QStringList sub = input.mid(i, count); + + if (count > 1) { + if (i + count > input.count()) + sub += input.mid(0, count - i + 1); + + std::sort(sub.begin(), sub.end()); + do { + if (!sub.isEmpty()) + output += sub; + } while (std::next_permutation(sub.begin(), sub.end())); + } else { + output += sub; + } + + if (count == input.count()) + break; + } + + if (count > 1) + output += permutations(input, --count); + + return output; +} + +static QString findFile(const QDir &dir, const QString &baseName, const QStringList &extensions) +{ + for (const QString &ext : extensions) { + QString filePath = dir.filePath(baseName + QLatin1Char('.') + ext); + if (QFile::exists(filePath)) + return QFileSelector().select(filePath); + } + // return an empty string to indicate that the lookup has been done + // even if no matching asset was found + return QLatin1String(""); +} + +QQuickImageSelector::QQuickImageSelector(QObject *parent) + : QObject(parent), + m_cache(cacheSize() > 0) +{ +} + +QUrl QQuickImageSelector::source() const +{ + return m_source; +} + +void QQuickImageSelector::setSource(const QUrl &source) +{ + if (m_property.isValid()) + QQmlPropertyPrivate::write(m_property, source, QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding); + if (m_source == source) + return; + + m_source = source; + emit sourceChanged(); +} + +QString QQuickImageSelector::name() const +{ + return m_name; +} + +void QQuickImageSelector::setName(const QString &name) +{ + if (m_name == name) + return; + + m_name = name; + if (m_complete) + updateSource(); +} + +QString QQuickImageSelector::path() const +{ + return m_path; +} + +void QQuickImageSelector::setPath(const QString &path) +{ + if (m_path == path) + return; + + m_path = path; + if (m_complete) + updateSource(); +} + +QVariantList QQuickImageSelector::states() const +{ + return m_allStates; +} + +void QQuickImageSelector::setStates(const QVariantList &states) +{ + if (m_allStates == states) + return; + + m_allStates = states; + if (updateActiveStates() && m_complete) + updateSource(); +} + +QString QQuickImageSelector::separator() const +{ + return m_separator; +} + +void QQuickImageSelector::setSeparator(const QString &separator) +{ + if (m_separator == separator) + return; + + m_separator = separator; + if (m_complete) + updateSource(); +} + +bool QQuickImageSelector::cache() const +{ + return m_cache; +} + +void QQuickImageSelector::setCache(bool cache) +{ + m_cache = cache; +} + +void QQuickImageSelector::write(const QVariant &value) +{ + setUrl(value.toUrl()); +} + +void QQuickImageSelector::setTarget(const QQmlProperty &property) +{ + m_property = property; +} + +void QQuickImageSelector::classBegin() +{ +} + +void QQuickImageSelector::componentComplete() +{ + setUrl(m_property.read().toUrl()); + m_complete = true; + updateSource(); +} + +QStringList QQuickImageSelector::fileExtensions() const +{ + static const QStringList extensions = QStringList() << QStringLiteral("png"); + return extensions; +} + +QString QQuickImageSelector::cacheKey() const +{ + if (!m_cache) + return QString(); + + return m_path + m_name + m_activeStates.join(m_separator); +} + +void QQuickImageSelector::updateSource() +{ + static QCache<QString, QString> cache(cacheSize()); + + const QString key = cacheKey(); + + QString bestFilePath; + + if (m_cache) { + QString *cachedPath = cache.object(key); + if (cachedPath) + bestFilePath = *cachedPath; + } + + // note: a cached file path may be empty + if (bestFilePath.isNull()) { + QDir dir(m_path); + int bestScore = -1; + + const QStringList extensions = fileExtensions(); + + const QList<QStringList> statePerms = permutations(m_activeStates); + for (const QStringList &perm : statePerms) { + const QString filePath = findFile(dir, m_name + m_separator + perm.join(m_separator), extensions); + if (!filePath.isEmpty()) { + int score = calculateScore(perm); + if (score > bestScore) { + bestScore = score; + bestFilePath = filePath; + } + } + } + + if (bestFilePath.isEmpty()) + bestFilePath = findFile(dir, m_name, extensions); + + if (m_cache) + cache.insert(key, new QString(bestFilePath)); + } + + qCDebug(lcQtQuickControlsImagine) << m_name << m_activeStates << "->" << bestFilePath; + + if (bestFilePath.startsWith(QLatin1Char(':'))) + setSource(QUrl(QLatin1String("qrc") + bestFilePath)); + else + setSource(QUrl::fromLocalFile(bestFilePath)); +} + +void QQuickImageSelector::setUrl(const QUrl &url) +{ + QFileInfo fileInfo(QQmlFile::urlToLocalFileOrQrc(url)); + setName(fileInfo.fileName()); + setPath(fileInfo.path()); +} + +bool QQuickImageSelector::updateActiveStates() +{ + QStringList active; + for (const QVariant &v : qAsConst(m_allStates)) { + const QVariantMap state = v.toMap(); + if (state.isEmpty()) + continue; + auto it = state.begin(); + if (it.value().toBool()) + active += it.key(); + } + + if (m_activeStates == active) + return false; + + m_activeStates = active; + return true; +} + +int QQuickImageSelector::calculateScore(const QStringList &states) const +{ + int score = 0; + for (int i = 0; i < states.count(); ++i) + score += (m_activeStates.count() - m_activeStates.indexOf(states.at(i))) << 1; + return score; +} + +QQuickNinePatchImageSelector::QQuickNinePatchImageSelector(QObject *parent) + : QQuickImageSelector(parent) +{ +} + +QStringList QQuickNinePatchImageSelector::fileExtensions() const +{ + static const QStringList extensions = QStringList() << QStringLiteral("9.png") << QStringLiteral("png"); + return extensions; +} + +QQuickAnimatedImageSelector::QQuickAnimatedImageSelector(QObject *parent) + : QQuickImageSelector(parent) +{ +} + +QStringList QQuickAnimatedImageSelector::fileExtensions() const +{ + static const QStringList extensions = QStringList() << QStringLiteral("webp") << QStringLiteral("gif"); + return extensions; +} + +QT_END_NAMESPACE diff --git a/src/quickcontrols2/imagine/impl/qquickimageselector_p.h b/src/quickcontrols2/imagine/impl/qquickimageselector_p.h new file mode 100644 index 00000000000..351caefbef8 --- /dev/null +++ b/src/quickcontrols2/imagine/impl/qquickimageselector_p.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKIMAGESELECTOR_P_H +#define QQUICKIMAGESELECTOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qurl.h> +#include <QtCore/qobject.h> +#include <QtCore/qvariant.h> +#include <QtQml/qqmlproperty.h> +#include <QtQml/qqmlparserstatus.h> +#include <QtQml/private/qqmlpropertyvalueinterceptor_p.h> +#include <QtQml/qqmlproperty.h> +#include <QtQml/qqml.h> + +QT_BEGIN_NAMESPACE + +class QQuickImageSelector : public QObject, public QQmlParserStatus, public QQmlPropertyValueInterceptor +{ + Q_OBJECT + Q_PROPERTY(QUrl source READ source NOTIFY sourceChanged FINAL) + Q_PROPERTY(QString name READ name WRITE setName FINAL) + Q_PROPERTY(QString path READ path WRITE setPath FINAL) + Q_PROPERTY(QVariantList states READ states WRITE setStates FINAL) + Q_PROPERTY(QString separator READ separator WRITE setSeparator FINAL) + Q_PROPERTY(bool cache READ cache WRITE setCache FINAL) + Q_INTERFACES(QQmlParserStatus QQmlPropertyValueInterceptor) + QML_NAMED_ELEMENT(ImageSelector) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickImageSelector(QObject *parent = nullptr); + + QUrl source() const; + void setSource(const QUrl &source); + + QString name() const; + void setName(const QString &name); + + QString path() const; + void setPath(const QString &path); + + QVariantList states() const; + void setStates(const QVariantList &states); + + QString separator() const; + void setSeparator(const QString &separator); + + bool cache() const; + void setCache(bool cache); + + void write(const QVariant &value) override; + void setTarget(const QQmlProperty &property) override; + +Q_SIGNALS: + void sourceChanged(); + +protected: + void classBegin() override; + void componentComplete() override; + + virtual QStringList fileExtensions() const; + + QString cacheKey() const; + void updateSource(); + void setUrl(const QUrl &url); + bool updateActiveStates(); + int calculateScore(const QStringList &states) const; + +private: + bool m_cache = false; + bool m_complete = false; + QUrl m_source; + QString m_path; + QString m_name; + QString m_separator = QLatin1String("-"); + QVariantList m_allStates; + QStringList m_activeStates; + QQmlProperty m_property; +}; + +class QQuickNinePatchImageSelector : public QQuickImageSelector +{ + Q_OBJECT + QML_NAMED_ELEMENT(NinePatchImageSelector) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickNinePatchImageSelector(QObject *parent = nullptr); + +protected: + QStringList fileExtensions() const override; +}; + +class QQuickAnimatedImageSelector : public QQuickImageSelector +{ + Q_OBJECT + QML_NAMED_ELEMENT(AnimatedImageSelector) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickAnimatedImageSelector(QObject *parent = nullptr); + +protected: + QStringList fileExtensions() const override; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickImageSelector) +QML_DECLARE_TYPE(QQuickAnimatedImageSelector) + +#endif // QQUICKIMAGESELECTOR_P_H diff --git a/src/quickcontrols2/imagine/impl/qquickninepatchimage.cpp b/src/quickcontrols2/imagine/impl/qquickninepatchimage.cpp new file mode 100644 index 00000000000..00be6299453 --- /dev/null +++ b/src/quickcontrols2/imagine/impl/qquickninepatchimage.cpp @@ -0,0 +1,513 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickninepatchimage_p.h" + +#include <QtCore/qfileinfo.h> +#include <QtQuick/qsggeometry.h> +#include <QtQuick/qsgtexturematerial.h> +#include <QtQuick/private/qsgnode_p.h> +#include <QtQuick/private/qquickimage_p_p.h> + +QT_BEGIN_NAMESPACE + +struct QQuickNinePatchData +{ + QList<qreal> coordsForSize(qreal count) const; + + inline bool isNull() const { return data.isEmpty(); } + inline int count() const { return data.size(); } + inline qreal at(int index) const { return data.at(index); } + inline qreal size() const { return data.last(); } + + void fill(const QList<qreal> &coords, qreal count); + void clear(); + +private: + bool inverted = false; + QList<qreal> data; +}; + +QList<qreal> QQuickNinePatchData::coordsForSize(qreal size) const +{ + // n = number of stretchable sections + // We have to compensate when adding 0 and/or + // the source image width to the divs vector. + const int l = data.size(); + const int n = (inverted ? l - 1 : l) / 2; + const qreal stretch = (size - data.last()) / n; + + QList<qreal> coords; + coords.reserve(l); + coords.append(0); + + bool stretched = !inverted; + for (int i = 1; i < l; ++i) { + qreal advance = data[i] - data[i - 1]; + if (stretched) + advance += stretch; + coords.append(coords.last() + advance); + + stretched = !stretched; + } + + return coords; +} + +/* + Adds the 0 index coordinate if appropriate, and the one at "size". +*/ +void QQuickNinePatchData::fill(const QList<qreal> &coords, qreal size) +{ + data.clear(); + inverted = coords.isEmpty() || coords.first() != 0; + + // Reserve an extra item in case we need to add the image width/height + if (inverted) { + data.reserve(coords.size() + 2); + data.append(0); + } else { + data.reserve(coords.size() + 1); + } + + data += coords; + data.append(size); +} + +void QQuickNinePatchData::clear() +{ + data.clear(); +} + +class QQuickNinePatchNode : public QSGGeometryNode +{ +public: + QQuickNinePatchNode(); + ~QQuickNinePatchNode(); + + void initialize(QSGTexture *texture, const QSizeF &targetSize, const QSize &sourceSize, + const QQuickNinePatchData &xDivs, const QQuickNinePatchData &yDivs, qreal dpr); + +private: + QSGGeometry m_geometry; + QSGTextureMaterial m_material; +}; + +QQuickNinePatchNode::QQuickNinePatchNode() + : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) +{ + m_geometry.setDrawingMode(QSGGeometry::DrawTriangles); + setGeometry(&m_geometry); + setMaterial(&m_material); +} + +QQuickNinePatchNode::~QQuickNinePatchNode() +{ + delete m_material.texture(); +} + +void QQuickNinePatchNode::initialize(QSGTexture *texture, const QSizeF &targetSize, const QSize &sourceSize, + const QQuickNinePatchData &xDivs, const QQuickNinePatchData &yDivs, qreal dpr) +{ + delete m_material.texture(); + m_material.setTexture(texture); + + const int xlen = xDivs.count(); + const int ylen = yDivs.count(); + + if (xlen > 0 && ylen > 0) { + const int quads = (xlen - 1) * (ylen - 1); + static const int verticesPerQuad = 6; + m_geometry.allocate(xlen * ylen, verticesPerQuad * quads); + + QSGGeometry::TexturedPoint2D *vertices = m_geometry.vertexDataAsTexturedPoint2D(); + QList<qreal> xCoords = xDivs.coordsForSize(targetSize.width()); + QList<qreal> yCoords = yDivs.coordsForSize(targetSize.height()); + + for (int y = 0; y < ylen; ++y) { + for (int x = 0; x < xlen; ++x, ++vertices) + vertices->set(xCoords[x] / dpr, yCoords[y] / dpr, + xDivs.at(x) / sourceSize.width(), + yDivs.at(y) / sourceSize.height()); + } + + quint16 *indices = m_geometry.indexDataAsUShort(); + int n = quads; + for (int q = 0; n--; ++q) { + if ((q + 1) % xlen == 0) // next row + ++q; + // Bottom-left half quad triangle + indices[0] = q; + indices[1] = q + xlen; + indices[2] = q + xlen + 1; + + // Top-right half quad triangle + indices[3] = q; + indices[4] = q + xlen + 1; + indices[5] = q + 1; + + indices += verticesPerQuad; + } + } + + markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial); +} + +class QQuickNinePatchImagePrivate : public QQuickImagePrivate +{ + Q_DECLARE_PUBLIC(QQuickNinePatchImage) + +public: + void updatePatches(); + void updatePaddings(const QSizeF &size, const QList<qreal> &horizontal, const QList<qreal> &vertical); + void updateInsets(const QList<qreal> &horizontal, const QList<qreal> &vertical); + + bool resetNode = false; + qreal topPadding = 0; + qreal leftPadding = 0; + qreal rightPadding = 0; + qreal bottomPadding = 0; + qreal topInset = 0; + qreal leftInset = 0; + qreal rightInset = 0; + qreal bottomInset = 0; + + QImage ninePatch; + QQuickNinePatchData xDivs; + QQuickNinePatchData yDivs; +}; + +/* + Examines each pixel in a horizontal or vertical (if offset is equal to the image's width) + line, storing the start and end index ("coordinate") of each 9-patch line. + + For instance, in the 7x3 (9x5 actual size) 9-patch image below, which has no horizontal + stretchable area, it would return {}: + + +-----+ + | | + +-----+ + + If indices 3 to 5 were marked, it would return {2, 5}: + + xxx + +-----+ + | | + +-----+ + + If indices 3 and 5 were marked, it would store {0, 2, 3, 4, 5, 7}: + + x x + +-----+ + | | + +-----+ +*/ +static QList<qreal> readCoords(const QRgb *data, int from, int count, int offset, QRgb color) +{ + int p1 = -1; + QList<qreal> coords; + for (int i = 0; i < count; ++i) { + int p2 = from + i * offset; + if (data[p2] == color) { + // colored pixel + if (p1 == -1) { + // This is the start of a 9-patch line. + p1 = i; + } + } else { + // empty pixel + if (p1 != -1) { + // This is the end of a 9-patch line; add the start and end indices as coordinates... + coords << p1 << i; + // ... and reset p1 so that we can search for the next one. + p1 = -1; + } + } + } + return coords; +} + +/* + Called whenever a 9-patch image is set as the image's source. + + Reads the 9-patch lines from the source image and sets the + inset and padding properties accordingly. +*/ +void QQuickNinePatchImagePrivate::updatePatches() +{ + if (ninePatch.isNull()) + return; + + int w = ninePatch.width(); + int h = ninePatch.height(); + const QRgb *data = reinterpret_cast<const QRgb *>(ninePatch.constBits()); + + const QRgb black = qRgb(0,0,0); + const QRgb red = qRgb(255,0,0); + + xDivs.fill(readCoords(data, 1, w - 1, 1, black), w - 2); // top left -> top right + yDivs.fill(readCoords(data, w, h - 1, w, black), h - 2); // top left -> bottom left + + QList<qreal> hInsets = readCoords(data, (h - 1) * w + 1, w - 1, 1, red); // bottom left -> bottom right + QList<qreal> vInsets = readCoords(data, 2 * w - 1, h - 1, w, red); // top right -> bottom right + updateInsets(hInsets, vInsets); + + const QSizeF sz(w - leftInset - rightInset, h - topInset - bottomInset); + QList<qreal> hPaddings = readCoords(data, (h - 1) * w + leftInset + 1, sz.width() - 2, 1, black); // bottom left -> bottom right + QList<qreal> vPaddings = readCoords(data, (2 + topInset) * w - 1, sz.height() - 2, w, black); // top right -> bottom right + updatePaddings(sz, hPaddings, vPaddings); +} + +void QQuickNinePatchImagePrivate::updatePaddings(const QSizeF &size, const QList<qreal> &horizontal, const QList<qreal> &vertical) +{ + Q_Q(QQuickNinePatchImage); + qreal oldTopPadding = topPadding; + qreal oldLeftPadding = leftPadding; + qreal oldRightPadding = rightPadding; + qreal oldBottomPadding = bottomPadding; + + if (horizontal.count() >= 2) { + leftPadding = horizontal.first(); + rightPadding = size.width() - horizontal.last() - 2; + } else { + leftPadding = 0; + rightPadding = 0; + } + + if (vertical.count() >= 2) { + topPadding = vertical.first(); + bottomPadding = size.height() - vertical.last() - 2; + } else { + topPadding = 0; + bottomPadding = 0; + } + + if (!qFuzzyCompare(oldTopPadding, topPadding)) + emit q->topPaddingChanged(); + if (!qFuzzyCompare(oldBottomPadding, bottomPadding)) + emit q->bottomPaddingChanged(); + if (!qFuzzyCompare(oldLeftPadding, leftPadding)) + emit q->leftPaddingChanged(); + if (!qFuzzyCompare(oldRightPadding, rightPadding)) + emit q->rightPaddingChanged(); +} + +void QQuickNinePatchImagePrivate::updateInsets(const QList<qreal> &horizontal, const QList<qreal> &vertical) +{ + Q_Q(QQuickNinePatchImage); + qreal oldTopInset = topInset; + qreal oldLeftInset = leftInset; + qreal oldRightInset = rightInset; + qreal oldBottomInset = bottomInset; + + if (horizontal.count() >= 2 && horizontal.first() == 0) + leftInset = horizontal.at(1); + else + leftInset = 0; + + if (horizontal.count() == 2 && horizontal.first() > 0) + rightInset = horizontal.last() - horizontal.first(); + else if (horizontal.count() == 4) + rightInset = horizontal.last() - horizontal.at(2); + else + rightInset = 0; + + if (vertical.count() >= 2 && vertical.first() == 0) + topInset = vertical.at(1); + else + topInset = 0; + + if (vertical.count() == 2 && vertical.first() > 0) + bottomInset = vertical.last() - vertical.first(); + else if (vertical.count() == 4) + bottomInset = vertical.last() - vertical.at(2); + else + bottomInset = 0; + + if (!qFuzzyCompare(oldTopInset, topInset)) + emit q->topInsetChanged(); + if (!qFuzzyCompare(oldBottomInset, bottomInset)) + emit q->bottomInsetChanged(); + if (!qFuzzyCompare(oldLeftInset, leftInset)) + emit q->leftInsetChanged(); + if (!qFuzzyCompare(oldRightInset, rightInset)) + emit q->rightInsetChanged(); +} + +QQuickNinePatchImage::QQuickNinePatchImage(QQuickItem *parent) + : QQuickImage(*(new QQuickNinePatchImagePrivate), parent) +{ + Q_D(QQuickNinePatchImage); + d->smooth = qEnvironmentVariableIntValue("QT_QUICK_CONTROLS_IMAGINE_SMOOTH"); +} + +qreal QQuickNinePatchImage::topPadding() const +{ + Q_D(const QQuickNinePatchImage); + return d->topPadding / d->devicePixelRatio; +} + +qreal QQuickNinePatchImage::leftPadding() const +{ + Q_D(const QQuickNinePatchImage); + return d->leftPadding / d->devicePixelRatio; +} + +qreal QQuickNinePatchImage::rightPadding() const +{ + Q_D(const QQuickNinePatchImage); + return d->rightPadding / d->devicePixelRatio; +} + +qreal QQuickNinePatchImage::bottomPadding() const +{ + Q_D(const QQuickNinePatchImage); + return d->bottomPadding / d->devicePixelRatio; +} + +qreal QQuickNinePatchImage::topInset() const +{ + Q_D(const QQuickNinePatchImage); + return d->topInset / d->devicePixelRatio; +} + +qreal QQuickNinePatchImage::leftInset() const +{ + Q_D(const QQuickNinePatchImage); + return d->leftInset / d->devicePixelRatio; +} + +qreal QQuickNinePatchImage::rightInset() const +{ + Q_D(const QQuickNinePatchImage); + return d->rightInset / d->devicePixelRatio; +} + +qreal QQuickNinePatchImage::bottomInset() const +{ + Q_D(const QQuickNinePatchImage); + return d->bottomInset / d->devicePixelRatio; +} + +void QQuickNinePatchImage::pixmapChange() +{ + Q_D(QQuickNinePatchImage); + if (QFileInfo(d->url.fileName()).completeSuffix().toLower() == QLatin1String("9.png")) { + // Keep resetNode if it is already set, we do not want to miss an + // ImageNode->NinePatchNode change. Without this there's a chance one gets + // an incorrect cast on oldNode every once in a while with source changes. + if (!d->resetNode) + d->resetNode = d->ninePatch.isNull(); + + d->ninePatch = d->pix.image(); + if (d->ninePatch.depth() != 32) + d->ninePatch = d->ninePatch.convertToFormat(QImage::Format_ARGB32); + + int w = d->ninePatch.width(); + int h = d->ninePatch.height(); + d->pix.setImage(QImage(d->ninePatch.constBits() + 4 * (w + 1), w - 2, h - 2, d->ninePatch.bytesPerLine(), d->ninePatch.format())); + + d->updatePatches(); + } else { + /* + Only change resetNode when it's false; i.e. when no reset is pending. + updatePaintNode() will take care of setting it to false if it's true. + + Consider the following changes in source: + + normal.png => press.9.png => normal.png => focus.png + + If the last two events happen quickly, pixmapChange() can be called + twice with no call to updatePaintNode() inbetween. On the first call, + resetNode will be true (because ninePatch is not null since it is still + in the process of going from a 9-patch image to a regular image), + and on the second call, resetNode would be false if we didn't have this check. + This results in the oldNode never being deleted, and QQuickImage + tries to static_cast a QQuickNinePatchImage to a QSGInternalImageNode. + */ + if (!d->resetNode) + d->resetNode = !d->ninePatch.isNull(); + d->ninePatch = QImage(); + } + QQuickImage::pixmapChange(); +} + +QSGNode *QQuickNinePatchImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) +{ + Q_D(QQuickNinePatchImage); + Q_UNUSED(data); + + if (d->resetNode) { + delete oldNode; + oldNode = nullptr; + d->resetNode = false; + } + + if (d->ninePatch.isNull()) + return QQuickImage::updatePaintNode(oldNode, data); + + QSizeF sz = size(); + QImage image = d->pix.image(); + if (!sz.isValid() || image.isNull()) { + if (d->provider) + d->provider->updateTexture(nullptr); + delete oldNode; + return nullptr; + } + + QQuickNinePatchNode *patchNode = static_cast<QQuickNinePatchNode *>(oldNode); + if (!patchNode) + patchNode = new QQuickNinePatchNode; + +#ifdef QSG_RUNTIME_DESCRIPTION + qsgnode_set_description(patchNode, QString::fromLatin1("QQuickNinePatchImage: '%1'").arg(d->url.toString())); +#endif + + // The image may wrap non-owned data (due to pixmapChange). Ensure we never + // pass such an image to the scenegraph, because with a separate render + // thread the data may become invalid (in a subsequent pixmapChange on the + // gui thread) by the time the renderer gets to do something with the QImage + // passed in here. + image.detach(); + + QSGTexture *texture = window()->createTextureFromImage(image); + patchNode->initialize(texture, sz * d->devicePixelRatio, image.size(), d->xDivs, d->yDivs, d->devicePixelRatio); + auto patchNodeMaterial = static_cast<QSGTextureMaterial *>(patchNode->material()); + patchNodeMaterial->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest); + return patchNode; +} + +QT_END_NAMESPACE diff --git a/src/quickcontrols2/imagine/impl/qquickninepatchimage_p.h b/src/quickcontrols2/imagine/impl/qquickninepatchimage_p.h new file mode 100644 index 00000000000..78cc3068853 --- /dev/null +++ b/src/quickcontrols2/imagine/impl/qquickninepatchimage_p.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKNINEPATCHIMAGE_P_H +#define QQUICKNINEPATCHIMAGE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquickimage_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickNinePatchImagePrivate; + +class QQuickNinePatchImage : public QQuickImage +{ + Q_OBJECT + Q_PROPERTY(qreal topPadding READ topPadding NOTIFY topPaddingChanged FINAL) + Q_PROPERTY(qreal leftPadding READ leftPadding NOTIFY leftPaddingChanged FINAL) + Q_PROPERTY(qreal rightPadding READ rightPadding NOTIFY rightPaddingChanged FINAL) + Q_PROPERTY(qreal bottomPadding READ bottomPadding NOTIFY bottomPaddingChanged FINAL) + Q_PROPERTY(qreal topInset READ topInset NOTIFY topInsetChanged FINAL) + Q_PROPERTY(qreal leftInset READ leftInset NOTIFY leftInsetChanged FINAL) + Q_PROPERTY(qreal rightInset READ rightInset NOTIFY rightInsetChanged FINAL) + Q_PROPERTY(qreal bottomInset READ bottomInset NOTIFY bottomInsetChanged FINAL) + QML_NAMED_ELEMENT(NinePatchImage) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickNinePatchImage(QQuickItem *parent = nullptr); + + qreal topPadding() const; + qreal leftPadding() const; + qreal rightPadding() const; + qreal bottomPadding() const; + + qreal topInset() const; + qreal leftInset() const; + qreal rightInset() const; + qreal bottomInset() const; + +Q_SIGNALS: + void topPaddingChanged(); + void leftPaddingChanged(); + void rightPaddingChanged(); + void bottomPaddingChanged(); + + void topInsetChanged(); + void leftInsetChanged(); + void rightInsetChanged(); + void bottomInsetChanged(); + +protected: + void pixmapChange() override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) override; + +private: + Q_DISABLE_COPY(QQuickNinePatchImage) + Q_DECLARE_PRIVATE(QQuickNinePatchImage) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickNinePatchImage) + +#endif // QQUICKNINEPATCHIMAGE_P_H diff --git a/src/quickcontrols2/imagine/impl/shaders/+glslcore/OpacityMask.frag b/src/quickcontrols2/imagine/impl/shaders/+glslcore/OpacityMask.frag new file mode 100644 index 00000000000..529e269614a --- /dev/null +++ b/src/quickcontrols2/imagine/impl/shaders/+glslcore/OpacityMask.frag @@ -0,0 +1,13 @@ +#version 150 + +uniform float qt_Opacity; +uniform sampler2D source; +uniform sampler2D maskSource; + +in vec2 qt_TexCoord0; +out vec4 fragColor; + +void main() +{ + fragColor = texture(source, qt_TexCoord0.st) * (texture(maskSource, qt_TexCoord0.st).a) * qt_Opacity; +} diff --git a/src/quickcontrols2/imagine/impl/shaders/+qsb/OpacityMask.frag b/src/quickcontrols2/imagine/impl/shaders/+qsb/OpacityMask.frag new file mode 100644 index 00000000000..331b30b8073 Binary files /dev/null and b/src/quickcontrols2/imagine/impl/shaders/+qsb/OpacityMask.frag differ diff --git a/src/quickcontrols2/imagine/impl/shaders/OpacityMask.frag b/src/quickcontrols2/imagine/impl/shaders/OpacityMask.frag new file mode 100644 index 00000000000..84f9bc3ee6a --- /dev/null +++ b/src/quickcontrols2/imagine/impl/shaders/OpacityMask.frag @@ -0,0 +1,7 @@ +varying highp vec2 qt_TexCoord0; +uniform highp float qt_Opacity; +uniform lowp sampler2D source; +uniform lowp sampler2D maskSource; +void main(void) { + gl_FragColor = texture2D(source, qt_TexCoord0.st) * (texture2D(maskSource, qt_TexCoord0.st).a) * qt_Opacity; +} diff --git a/src/quickcontrols2/imagine/impl/shaders/OpacityMask_rhi.frag b/src/quickcontrols2/imagine/impl/shaders/OpacityMask_rhi.frag new file mode 100644 index 00000000000..9ae32499788 --- /dev/null +++ b/src/quickcontrols2/imagine/impl/shaders/OpacityMask_rhi.frag @@ -0,0 +1,17 @@ +#version 440 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +} ubuf; + +layout(binding = 1) uniform sampler2D source; +layout(binding = 2) uniform sampler2D maskSource; + +void main() +{ + fragColor = texture(source, qt_TexCoord0.st) * (texture(maskSource, qt_TexCoord0.st).a) * ubuf.qt_Opacity; +} diff --git a/src/quickcontrols2/imagine/impl/shaders/compile.bat b/src/quickcontrols2/imagine/impl/shaders/compile.bat new file mode 100644 index 00000000000..8f16d7acf02 --- /dev/null +++ b/src/quickcontrols2/imagine/impl/shaders/compile.bat @@ -0,0 +1,40 @@ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Copyright (C) 2020 The Qt Company Ltd. +:: Contact: https://www.qt.io/licensing/ +:: +:: This file is part of the QtQuick module 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$ +:: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -o +qsb/OpacityMask.frag OpacityMask_rhi.frag diff --git a/src/quickcontrols2/imagine/qquickimaginestyle.cpp b/src/quickcontrols2/imagine/qquickimaginestyle.cpp new file mode 100644 index 00000000000..6152b66285d --- /dev/null +++ b/src/quickcontrols2/imagine/qquickimaginestyle.cpp @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickimaginestyle_p.h" + +#include <QtCore/qsettings.h> +#include <QtQuickControls2/private/qquickstyle_p.h> + +QT_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC_WITH_ARGS(QString, GlobalPath, (QLatin1String("qrc:/qt-project.org/imports/QtQuick/Controls/Imagine/images/"))) + +static QString ensureSlash(const QString &path) +{ + const QChar slash = QLatin1Char('/'); + return path.endsWith(slash) ? path : path + slash; +} + +QQuickImagineStyle::QQuickImagineStyle(QObject *parent) + : QQuickAttachedObject(parent), + m_path(*GlobalPath()) +{ + init(); +} + +QQuickImagineStyle *QQuickImagineStyle::qmlAttachedProperties(QObject *object) +{ + return new QQuickImagineStyle(object); +} + +QString QQuickImagineStyle::path() const +{ + return m_path; +} + +void QQuickImagineStyle::setPath(const QString &path) +{ + m_explicitPath = true; + if (m_path == path) + return; + + m_path = path; + propagatePath(); + + emit pathChanged(); +} + +void QQuickImagineStyle::inheritPath(const QString &path) +{ + if (m_explicitPath || m_path == path) + return; + + m_path = path; + propagatePath(); + emit pathChanged(); +} + +void QQuickImagineStyle::propagatePath() +{ + const auto styles = attachedChildren(); + for (QQuickAttachedObject *child : styles) { + QQuickImagineStyle *imagine = qobject_cast<QQuickImagineStyle *>(child); + if (imagine) + imagine->inheritPath(m_path); + } +} + +void QQuickImagineStyle::resetPath() +{ + if (!m_explicitPath) + return; + + m_explicitPath = false; + QQuickImagineStyle *imagine = qobject_cast<QQuickImagineStyle *>(attachedParent()); + inheritPath(imagine ? imagine->path() : *GlobalPath()); +} + +QUrl QQuickImagineStyle::url() const +{ + // Using ApplicationWindow as an example, its NinePatchImage url + // was previously assigned like this: + // + // soruce: Imagine.path + "applicationwindow-background" + // + // If Imagine.path is set to ":/images" by the user, then the final URL would be: + // + // QUrl("file:///home/user/qt/qtbase/qml/QtQuick/Controls/Imagine/:/images/applicationwindow-background") + // + // To ensure that the correct URL is constructed, we do it ourselves here, + // and then the control QML files use the "url" property instead. + const QString path = ensureSlash(m_path); + if (path.startsWith(QLatin1String("qrc"))) + return QUrl(path); + + if (path.startsWith(QLatin1String(":/"))) + return QUrl(QLatin1String("qrc") + path); + + return QUrl::fromLocalFile(path); +} + +void QQuickImagineStyle::attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent) +{ + Q_UNUSED(oldParent); + QQuickImagineStyle *imagine = qobject_cast<QQuickImagineStyle *>(newParent); + if (imagine) + inheritPath(imagine->path()); +} + +static QByteArray resolveSetting(const QByteArray &env, const QSharedPointer<QSettings> &settings, const QString &name) +{ + QByteArray value = qgetenv(env); +#if QT_CONFIG(settings) + if (value.isNull() && !settings.isNull()) + value = settings->value(name).toByteArray(); +#endif + return value; +} + +void QQuickImagineStyle::init() +{ + static bool globalsInitialized = false; + if (!globalsInitialized) { + QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(QStringLiteral("Imagine")); + + QString path = QString::fromUtf8(resolveSetting("QT_QUICK_CONTROLS_IMAGINE_PATH", settings, QStringLiteral("Path"))); + if (!path.isEmpty()) + *GlobalPath() = m_path = ensureSlash(path); + + globalsInitialized = true; + } + + QQuickAttachedObject::init(); // TODO: lazy init? +} + +QT_END_NAMESPACE + +#include "moc_qquickimaginestyle_p.cpp" diff --git a/src/quickcontrols2/imagine/qquickimaginestyle_p.h b/src/quickcontrols2/imagine/qquickimaginestyle_p.h new file mode 100644 index 00000000000..212096b93b6 --- /dev/null +++ b/src/quickcontrols2/imagine/qquickimaginestyle_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKIMAGINESTYLE_P_H +#define QQUICKIMAGINESTYLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qvariant.h> +#include <QtQml/qqml.h> +#include <QtQuickControls2Impl/private/qquickattachedobject_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickImagineStyle : public QQuickAttachedObject +{ + Q_OBJECT + Q_PROPERTY(QString path READ path WRITE setPath RESET resetPath NOTIFY pathChanged FINAL) + Q_PROPERTY(QUrl url READ url NOTIFY pathChanged FINAL) + QML_NAMED_ELEMENT(Imagine) + QML_ATTACHED(QQuickImagineStyle) + QML_UNCREATABLE("") + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickImagineStyle(QObject *parent = nullptr); + + static QQuickImagineStyle *qmlAttachedProperties(QObject *object); + + QString path() const; + void setPath(const QString &path); + void inheritPath(const QString &path); + void propagatePath(); + void resetPath(); + + QUrl url() const; + +Q_SIGNALS: + void pathChanged(); + +protected: + void attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent) override; + +private: + void init(); + + bool m_explicitPath = false; + QString m_path; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPEINFO(QQuickImagineStyle, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKIMAGINESTYLE_P_H diff --git a/src/quickcontrols2/imagine/qquickimaginetheme.cpp b/src/quickcontrols2/imagine/qquickimaginetheme.cpp new file mode 100644 index 00000000000..7bae036a832 --- /dev/null +++ b/src/quickcontrols2/imagine/qquickimaginetheme.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickimaginetheme_p.h" + +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +QT_BEGIN_NAMESPACE + +void QQuickImagineTheme::initialize(QQuickTheme *theme) +{ + QFont systemFont; + systemFont.setFamilies(QStringList{QLatin1String("Open Sans")}); + theme->setFont(QQuickTheme::System, systemFont); + + const QColor accentColor = QColor::fromRgb(0x4fc1e9); + const QColor windowTextColor = QColor::fromRgb(0x434a54); + const QColor disabledWindowTextColor = QColor::fromRgb(0xccd1d9); + + QPalette systemPalette; + systemPalette.setColor(QPalette::ButtonText, Qt::white); + systemPalette.setColor(QPalette::BrightText, Qt::white); + systemPalette.setColor(QPalette::Highlight, accentColor); + systemPalette.setColor(QPalette::HighlightedText, Qt::white); + systemPalette.setColor(QPalette::Text, windowTextColor); + systemPalette.setColor(QPalette::ToolTipText, Qt::white); + systemPalette.setColor(QPalette::WindowText, windowTextColor); + systemPalette.setColor(QPalette::Disabled, QPalette::Text, disabledWindowTextColor); + systemPalette.setColor(QPalette::Disabled, QPalette::WindowText, disabledWindowTextColor); + theme->setPalette(QQuickTheme::System, systemPalette); +} + +QT_END_NAMESPACE diff --git a/src/quickcontrols2/imagine/qquickimaginetheme_p.h b/src/quickcontrols2/imagine/qquickimaginetheme_p.h new file mode 100644 index 00000000000..d3d43074af8 --- /dev/null +++ b/src/quickcontrols2/imagine/qquickimaginetheme_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKIMAGINETHEME_P_H +#define QQUICKIMAGINETHEME_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +class QQuickTheme; + +class QQuickImagineTheme +{ +public: + static void initialize(QQuickTheme *theme); +}; + +QT_END_NAMESPACE + +#endif // QQUICKIMAGINETHEME_P_H diff --git a/src/quickcontrols2/imagine/qtquickcontrols2imaginestyleplugin.cpp b/src/quickcontrols2/imagine/qtquickcontrols2imaginestyleplugin.cpp new file mode 100644 index 00000000000..43d04ce8c26 --- /dev/null +++ b/src/quickcontrols2/imagine/qtquickcontrols2imaginestyleplugin.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickimaginestyle_p.h" +#include "qquickimaginetheme_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtQml/qqml.h> +#include <QtQuickControls2/private/qquickstyleplugin_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +extern void qml_register_types_QtQuick_Controls_Imagine(); +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Controls_Imagine); + +QT_BEGIN_NAMESPACE + +class QtQuickControls2ImagineStylePlugin : public QQuickStylePlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtQuickControls2ImagineStylePlugin(QObject *parent = nullptr); + + QString name() const override; + void initializeTheme(QQuickTheme *theme) override; + + QQuickImagineTheme theme; +}; + +QtQuickControls2ImagineStylePlugin::QtQuickControls2ImagineStylePlugin(QObject *parent) : QQuickStylePlugin(parent) +{ + volatile auto registration = &qml_register_types_QtQuick_Controls_Imagine; + Q_UNUSED(registration); +} + +QString QtQuickControls2ImagineStylePlugin::name() const +{ + return QStringLiteral("Imagine"); +} + +void QtQuickControls2ImagineStylePlugin::initializeTheme(QQuickTheme *theme) +{ + this->theme.initialize(theme); +} + +QT_END_NAMESPACE + +#include "qtquickcontrols2imaginestyleplugin.moc" diff --git a/src/quickcontrols2/macos/Button.qml b/src/quickcontrols2/macos/Button.qml new file mode 100644 index 00000000000..bddaa89ca4f --- /dev/null +++ b/src/quickcontrols2/macos/Button.qml @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultButton { + id: control + readonly property Item __focusFrameTarget: control + + font.pixelSize: background.styleFont(control).pixelSize +} diff --git a/src/quickcontrols2/macos/CMakeLists.txt b/src/quickcontrols2/macos/CMakeLists.txt new file mode 100644 index 00000000000..ef608b44601 --- /dev/null +++ b/src/quickcontrols2/macos/CMakeLists.txt @@ -0,0 +1,55 @@ +##################################################################### +## qtquickcontrols2macosstyleplugin Plugin: +##################################################################### + +set(qml_files + "Button.qml" + "Slider.qml" + "GroupBox.qml" + "CheckBox.qml" + "RadioButton.qml" + "SelectionRectangle.qml" + "SpinBox.qml" + "TextField.qml" + "Frame.qml" + "TextArea.qml" + "ComboBox.qml" + "ScrollView.qml" + "ScrollBar.qml" + "ProgressBar.qml" + "Dial.qml" +) + +qt_internal_add_qml_module(qtquickcontrols2macosstyleplugin + URI "QtQuick.Controls.macOS" + VERSION "${PROJECT_VERSION}" + CLASS_NAME QtQuickControls2MacOSStylePlugin + IMPORTS + QtQuick.Controls.Fusion/auto + PAST_MAJOR_VERSIONS 2 + PLUGIN_TARGET qtquickcontrols2macosstyleplugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + SOURCES + qtquickcontrols2macosstyleplugin.cpp + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2Private + Qt::QuickPrivate + Qt::QuickTemplates2Private +) + +# Native style is a dependency of the macOS style. +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2macosstyleplugin + qtquickcontrols2nativestyleplugin) + +# Fusion style is the required fallback style. +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2macosstyleplugin + qtquickcontrols2fusionstyleplugin) diff --git a/src/quickcontrols2/macos/CheckBox.qml b/src/quickcontrols2/macos/CheckBox.qml new file mode 100644 index 00000000000..71c880a72e9 --- /dev/null +++ b/src/quickcontrols2/macos/CheckBox.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultCheckBox { + id: control + readonly property Item __focusFrameTarget: indicator + readonly property Item __focusFrameStyleItem: indicator + + font.pixelSize: indicator.styleFont(control).pixelSize +} diff --git a/src/quickcontrols2/macos/ComboBox.qml b/src/quickcontrols2/macos/ComboBox.qml new file mode 100644 index 00000000000..798148e65f9 --- /dev/null +++ b/src/quickcontrols2/macos/ComboBox.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultComboBox { + id: control + readonly property Item __focusFrameTarget: control + font.pixelSize: background.styleFont(control).pixelSize + + contentItem: T.TextField { + implicitWidth: contentWidth + implicitHeight: contentHeight + text: control.editable ? control.editText : control.displayText + + enabled: control.editable + autoScroll: control.editable + readOnly: control.down + inputMethodHints: control.inputMethodHints + validator: control.validator + selectByMouse: control.selectTextByMouse + + font: control.font + color: control.editable ? control.palette.text : control.palette.buttonText + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + verticalAlignment: Text.AlignVCenter + + readonly property Item __focusFrameControl: control + } +} diff --git a/src/quickcontrols2/macos/Dial.qml b/src/quickcontrols2/macos/Dial.qml new file mode 100644 index 00000000000..1628bae6332 --- /dev/null +++ b/src/quickcontrols2/macos/Dial.qml @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultDial { + id: control + font.pixelSize: background.styleFont(control).pixelSize +} diff --git a/src/quickcontrols2/macos/Frame.qml b/src/quickcontrols2/macos/Frame.qml new file mode 100644 index 00000000000..f16a0835171 --- /dev/null +++ b/src/quickcontrols2/macos/Frame.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultFrame { +} diff --git a/src/quickcontrols2/macos/GroupBox.qml b/src/quickcontrols2/macos/GroupBox.qml new file mode 100644 index 00000000000..c066a1577a2 --- /dev/null +++ b/src/quickcontrols2/macos/GroupBox.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultGroupBox { + id: control + font.pixelSize: background.styleFont(control).pixelSize + label: Item { + readonly property point labelPos : control.__nativeBackground + ? background.labelPos + : Qt.point(0,0) + x: labelPos.x + background.x + y: labelPos.y + background.y - groupBoxPadding.top + width: children[0].implicitWidth + height: children[0].implicitHeight + Text { + width: parent.width + height: parent.height + text: control.title + font: control.font + color: control.palette.windowText + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + } +} diff --git a/src/quickcontrols2/macos/ProgressBar.qml b/src/quickcontrols2/macos/ProgressBar.qml new file mode 100644 index 00000000000..d9c5c02f4f8 --- /dev/null +++ b/src/quickcontrols2/macos/ProgressBar.qml @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultProgressBar { + id: control + font.pixelSize: background.styleFont(control).pixelSize +} diff --git a/src/quickcontrols2/macos/RadioButton.qml b/src/quickcontrols2/macos/RadioButton.qml new file mode 100644 index 00000000000..38aabae7f59 --- /dev/null +++ b/src/quickcontrols2/macos/RadioButton.qml @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultRadioButton { + id: control + readonly property Item __focusFrameTarget: indicator + readonly property Item __focusFrameStyleItem: indicator + font.pixelSize: indicator.styleFont(control).pixelSize +} diff --git a/src/quickcontrols2/macos/ScrollBar.qml b/src/quickcontrols2/macos/ScrollBar.qml new file mode 100644 index 00000000000..64992346b76 --- /dev/null +++ b/src/quickcontrols2/macos/ScrollBar.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultScrollBar { + id: controlRoot + font.pixelSize: background.styleFont(controlRoot).pixelSize + + contentItem: NativeStyle.ScrollBar { + control: controlRoot + subControl: NativeStyle.ScrollBar.Handle + overrideState: NativeStyle.ScrollBar.NeverHovered + } + + NativeStyle.ScrollBar { + // Fade a hovered-looking version of the handle + // on top of the default handle when hovering it + x: contentItem.x + y: contentItem.y + width: contentItem.width + height: contentItem.height + control: controlRoot + subControl: NativeStyle.ScrollBar.Handle + overrideState: NativeStyle.StyleItem.AlwaysHovered + opacity: controlRoot.hovered || control.pressed ? 1 : 0 + visible: contentItem instanceof NativeStyle.StyleItem + Behavior on opacity { NumberAnimation { duration: contentItem.transitionDuration } } + } + +} diff --git a/src/quickcontrols2/macos/ScrollView.qml b/src/quickcontrols2/macos/ScrollView.qml new file mode 100644 index 00000000000..954c5d8aed6 --- /dev/null +++ b/src/quickcontrols2/macos/ScrollView.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.ScrollView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + rightPadding: ScrollBar.vertical.visible ? ScrollBar.vertical.width : 0 + bottomPadding: ScrollBar.horizontal.visible ? ScrollBar.horizontal.height : 0 + + ScrollBar.vertical: ScrollBar { + parent: control + x: control.mirrored ? 0 : control.width - width + y: 0 + height: control.height - (control.ScrollBar.horizontal.visible ? control.ScrollBar.horizontal.height : 0) + active: control.ScrollBar.horizontal.active + + NativeStyle.ScrollViewCorner { + y: parent.height + control: control + visible: control.ScrollBar.horizontal.visible + useNinePatchImage: false + } + } + + ScrollBar.horizontal: ScrollBar { + parent: control + x: 0 + y: control.height - height + width: control.width - (control.ScrollBar.vertical.visible ? control.ScrollBar.vertical.width : 0) + active: control.ScrollBar.vertical.active + } +} diff --git a/src/quickcontrols2/macos/SelectionRectangle.qml b/src/quickcontrols2/macos/SelectionRectangle.qml new file mode 100644 index 00000000000..d54b6e9b429 --- /dev/null +++ b/src/quickcontrols2/macos/SelectionRectangle.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Shapes + +T.SelectionRectangle { + id: control + + topLeftHandle: Item { + width: 20 + height: 20 + visible: SelectionRectangle.control.active + // This item is deliberately empty. Selection handles don't feel at home + // for this style. But we provide an invisible handle that the user can + // drag on. + } + + bottomRightHandle: Item { + width: 20 + height: 20 + visible: SelectionRectangle.control.active + // This item is deliberately empty. Selection handles don't feel at home + // for this style. But we provide an invisible handle that the user can + // drag on. + } + +} diff --git a/src/quickcontrols2/macos/Slider.qml b/src/quickcontrols2/macos/Slider.qml new file mode 100644 index 00000000000..c4c1a8aa363 --- /dev/null +++ b/src/quickcontrols2/macos/Slider.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultSlider { + id: control + readonly property Item __focusFrameTarget: handle + readonly property Item __focusFrameStyleItem: handle + font.pixelSize: background.styleFont(control).pixelSize + + background: NativeStyle.Slider { + control: control + subControl: NativeStyle.Slider.Groove | NativeStyle.Slider.Handle + // We normally cannot use a nine patch image for the + // groove if we draw tickmarks (since then the scaling + // would scale the tickmarks too). The groove might + // also use a different background color before, and + // after, the handle. + useNinePatchImage: false + } + + handle: NativeStyle.Slider { + // The handle is hidden, since it will be drawn as a part + // of the background. But will still needs it to be here so + // that we can place the focus rect correctly. + visible: false + + control: control + subControl: NativeStyle.Slider.Handle + x: control.leftPadding + (control.horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) + useNinePatchImage: false + } +} diff --git a/src/quickcontrols2/macos/SpinBox.qml b/src/quickcontrols2/macos/SpinBox.qml new file mode 100644 index 00000000000..8816d0ce673 --- /dev/null +++ b/src/quickcontrols2/macos/SpinBox.qml @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.SpinBox { + id: control + + property bool __nativeBackground: background instanceof NativeStyle.StyleItem + property bool nativeIndicators: up.indicator.hasOwnProperty("_qt_default") + && down.indicator.hasOwnProperty("_qt_default") + + font.pixelSize: background.styleFont(control).pixelSize + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + 90 /* minimum */ ) + implicitHeight: Math.max(implicitBackgroundHeight, up.implicitIndicatorHeight + down.implicitIndicatorHeight) + + topInset + bottomInset + + spacing: 2 + + // Push the background right to make room for the indicators + rightInset: nativeIndicators ? up.implicitIndicatorWidth + spacing : 0 + + leftPadding: __nativeBackground ? background.contentPadding.left: 0 + topPadding: __nativeBackground ? background.contentPadding.top: 0 + rightPadding: (__nativeBackground ? background.contentPadding.right : 0) + rightInset + bottomPadding: __nativeBackground ? background.contentPadding.bottom: 0 + + readonly property Item __focusFrameTarget: contentItem + + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + + contentItem: TextInput { + text: control.displayText + font: control.font + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + horizontalAlignment: Qt.AlignLeft + verticalAlignment: Qt.AlignVCenter + + topPadding: 2 + bottomPadding: 2 + leftPadding: 10 + rightPadding: 10 + + readOnly: !control.editable + validator: control.validator + inputMethodHints: control.inputMethodHints + + readonly property Item __focusFrameControl: control + } + + NativeStyle.SpinBox { + id: upAndDown + control: control + subControl: NativeStyle.SpinBox.Up + visible: nativeIndicators + x: up.indicator.x + y: up.indicator.y + useNinePatchImage: false + } + + up.indicator: Item { + x: parent.width - width + y: (parent.height / 2) - height + implicitWidth: upAndDown.width + implicitHeight: upAndDown.height / 2 + property bool _qt_default + } + + down.indicator: Item { + x: parent.width - width + y: up.indicator.y + upAndDown.height / 2 + implicitWidth: upAndDown.width + implicitHeight: upAndDown.height / 2 + property bool _qt_default + } + + background: NativeStyle.SpinBox { + control: control + subControl: NativeStyle.SpinBox.Frame + contentWidth: contentItem.implicitWidth + contentHeight: contentItem.implicitHeight + } +} diff --git a/src/quickcontrols2/macos/TextArea.qml b/src/quickcontrols2/macos/TextArea.qml new file mode 100644 index 00000000000..f6b883038b2 --- /dev/null +++ b/src/quickcontrols2/macos/TextArea.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultTextArea { +} diff --git a/src/quickcontrols2/macos/TextField.qml b/src/quickcontrols2/macos/TextField.qml new file mode 100644 index 00000000000..36567616c1b --- /dev/null +++ b/src/quickcontrols2/macos/TextField.qml @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultTextField { + id: control + readonly property Item __focusFrameTarget: control + font.pixelSize: background.styleFont(control).pixelSize +} diff --git a/src/quickcontrols2/macos/macos.pri b/src/quickcontrols2/macos/macos.pri new file mode 100644 index 00000000000..4aa939e03a8 --- /dev/null +++ b/src/quickcontrols2/macos/macos.pri @@ -0,0 +1,16 @@ +QML_FILES += \ + $$PWD/Button.qml \ + $$PWD/Slider.qml \ + $$PWD/GroupBox.qml \ + $$PWD/CheckBox.qml \ + $$PWD/RadioButton.qml \ + $$PWD/SelectionRectangle.qml \ + $$PWD/SpinBox.qml \ + $$PWD/TextField.qml \ + $$PWD/Frame.qml \ + $$PWD/TextArea.qml \ + $$PWD/ComboBox.qml \ + $$PWD/ScrollView.qml \ + $$PWD/ScrollBar.qml \ + $$PWD/ProgressBar.qml \ + $$PWD/Dial.qml \ diff --git a/src/quickcontrols2/macos/qtquickcontrols2macosstyleplugin.cpp b/src/quickcontrols2/macos/qtquickcontrols2macosstyleplugin.cpp new file mode 100644 index 00000000000..adec72bb2c8 --- /dev/null +++ b/src/quickcontrols2/macos/qtquickcontrols2macosstyleplugin.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQml/qqml.h> +#include <QtQuickControls2/private/qquickstyleplugin_p.h> +#include <QtQuickControls2/qquickstyle.h> + +extern void qml_register_types_QtQuick_Controls_macOS(); +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Controls_macOS); + +QT_BEGIN_NAMESPACE + +class QtQuickControls2MacOSStylePlugin : public QQuickStylePlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtQuickControls2MacOSStylePlugin(QObject *parent = nullptr); + QString name() const override; + void initializeTheme(QQuickTheme *theme) override; +}; + + +QtQuickControls2MacOSStylePlugin::QtQuickControls2MacOSStylePlugin(QObject *parent): + QQuickStylePlugin(parent) +{ + volatile auto registration = &qml_register_types_QtQuick_Controls_macOS; + Q_UNUSED(registration); +} + +QString QtQuickControls2MacOSStylePlugin::name() const +{ + return QStringLiteral("macOS"); +} + +void QtQuickControls2MacOSStylePlugin::initializeTheme(QQuickTheme */*theme*/) +{ +} + +QT_END_NAMESPACE + +#include "qtquickcontrols2macosstyleplugin.moc" diff --git a/src/quickcontrols2/material/ApplicationWindow.qml b/src/quickcontrols2/material/ApplicationWindow.qml new file mode 100644 index 00000000000..82a0da8b3a5 --- /dev/null +++ b/src/quickcontrols2/material/ApplicationWindow.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Templates as T +import QtQuick.Controls.Material + +T.ApplicationWindow { + id: window + + color: Material.backgroundColor +} diff --git a/src/quickcontrols2/material/BusyIndicator.qml b/src/quickcontrols2/material/BusyIndicator.qml new file mode 100644 index 00000000000..621b2b434a9 --- /dev/null +++ b/src/quickcontrols2/material/BusyIndicator.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.BusyIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + + contentItem: BusyIndicatorImpl { + implicitWidth: control.Material.touchTarget + implicitHeight: control.Material.touchTarget + color: control.Material.accentColor + + running: control.running + opacity: control.running ? 1 : 0 + Behavior on opacity { OpacityAnimator { duration: 250 } } + } +} diff --git a/src/quickcontrols2/material/Button.qml b/src/quickcontrols2/material/Button.qml new file mode 100644 index 00000000000..80454c6493a --- /dev/null +++ b/src/quickcontrols2/material/Button.qml @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.Button { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topInset: 6 + bottomInset: 6 + padding: 12 + horizontalPadding: padding - 4 + spacing: 6 + + icon.width: 24 + icon.height: 24 + icon.color: !enabled ? Material.hintTextColor : + flat && highlighted ? Material.accentColor : + highlighted ? Material.primaryHighlightedTextColor : Material.foreground + + Material.elevation: flat ? control.down || (enabled && control.hovered) ? 2 : 0 + : control.down ? 8 : 2 + Material.background: flat ? "transparent" : undefined + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: !control.enabled ? control.Material.hintTextColor : + control.flat && control.highlighted ? control.Material.accentColor : + control.highlighted ? control.Material.primaryHighlightedTextColor : control.Material.foreground + } + + background: Rectangle { + implicitWidth: 64 + implicitHeight: control.Material.buttonHeight + + radius: 2 + color: !control.enabled ? control.Material.buttonDisabledColor : + control.highlighted ? (control.checked ? control.Material.highlightedCheckedButtonColor : + control.Material.highlightedButtonColor) : control.Material.buttonColor + + PaddedRectangle { + y: parent.height - 4 + width: parent.width + height: 4 + radius: 2 + topPadding: -2 + clip: true + visible: control.checkable && (!control.highlighted || control.flat) + color: control.checked && control.enabled ? control.Material.accentColor : control.Material.secondaryTextColor + } + + // The layer is disabled when the button color is transparent so you can do + // Material.background: "transparent" and get a proper flat button without needing + // to set Material.elevation as well + layer.enabled: control.enabled && control.Material.buttonColor.a > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + + Ripple { + clipRadius: 2 + width: parent.width + height: parent.height + pressed: control.pressed + anchor: control + active: enabled && (control.down || control.visualFocus || control.hovered) + color: control.flat && control.highlighted ? control.Material.highlightedRippleColor : control.Material.rippleColor + } + } +} diff --git a/src/quickcontrols2/material/CMakeLists.txt b/src/quickcontrols2/material/CMakeLists.txt new file mode 100644 index 00000000000..cd2a71c508f --- /dev/null +++ b/src/quickcontrols2/material/CMakeLists.txt @@ -0,0 +1,152 @@ +##################################################################### +## qtquickcontrols2materialstyleplugin Plugin: +##################################################################### + +set(qml_files + "ApplicationWindow.qml" + "BusyIndicator.qml" + "Button.qml" + "CheckBox.qml" + "CheckDelegate.qml" + "ComboBox.qml" + "DelayButton.qml" + "Dial.qml" + "Dialog.qml" + "DialogButtonBox.qml" + "Drawer.qml" + "Frame.qml" + "GroupBox.qml" + "HorizontalHeaderView.qml" + "ItemDelegate.qml" + "Label.qml" + "Menu.qml" + "MenuBar.qml" + "MenuBarItem.qml" + "MenuItem.qml" + "MenuSeparator.qml" + "Page.qml" + "PageIndicator.qml" + "Pane.qml" + "Popup.qml" + "ProgressBar.qml" + "RadioButton.qml" + "RadioDelegate.qml" + "RangeSlider.qml" + "RoundButton.qml" + "ScrollView.qml" + "ScrollBar.qml" + "ScrollIndicator.qml" + "SelectionRectangle.qml" + "Slider.qml" + "SpinBox.qml" + "SplitView.qml" + "StackView.qml" + "SwipeDelegate.qml" + "SwipeView.qml" + "Switch.qml" + "SwitchDelegate.qml" + "TabBar.qml" + "TabButton.qml" + "TextArea.qml" + "TextField.qml" + "ToolBar.qml" + "ToolButton.qml" + "ToolSeparator.qml" + "ToolTip.qml" + "Tumbler.qml" + "VerticalHeaderView.qml" +) +set_source_files_properties(DelayButton.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.2;6.0" +) +set_source_files_properties(Dialog.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(DialogButtonBox.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(HorizontalHeaderView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.15;6.0" +) +set_source_files_properties(MenuBar.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.3;6.0" +) +set_source_files_properties(MenuBarItem.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.3;6.0" +) +set_source_files_properties(MenuSeparator.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(RoundButton.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(SplitView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.13;6.0" +) +set_source_files_properties(ToolSeparator.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(VerticalHeaderView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.15;6.0" +) + +qt_internal_add_qml_module(qtquickcontrols2materialstyleplugin + URI "QtQuick.Controls.Material" + VERSION "${PROJECT_VERSION}" + PAST_MAJOR_VERSIONS 2 + CLASS_NAME QtQuickControls2MaterialStylePlugin + IMPORTS + QtQuick.Controls.Basic/auto + PLUGIN_TARGET qtquickcontrols2materialstyleplugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + SOURCES + qquickmaterialstyle.cpp qquickmaterialstyle_p.h + qquickmaterialtheme.cpp qquickmaterialtheme_p.h + qtquickcontrols2materialstyleplugin.cpp + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2ImplPrivate + Qt::QuickControls2Private + Qt::QuickPrivate + Qt::QuickTemplates2Private +) + +qt_internal_add_resource(qtquickcontrols2materialstyleplugin "qtquickcontrols2materialstyleplugin" + PREFIX + "/qt-project.org/imports/QtQuick/Controls/Material" + FILES + "images/arrow-indicator.png" + "images/arrow-indicator@2x.png" + "images/arrow-indicator@3x.png" + "images/arrow-indicator@4x.png" + "images/check.png" + "images/check@2x.png" + "images/check@3x.png" + "images/check@4x.png" + "images/drop-indicator.png" + "images/drop-indicator@2x.png" + "images/drop-indicator@3x.png" + "images/drop-indicator@4x.png" + "shaders/+glslcore/RectangularGlow.frag" + "shaders/+hlsl/RectangularGlow.frag" + "shaders/+qsb/RectangularGlow.frag" + "shaders/RectangularGlow.frag" +) + +add_subdirectory(impl) + +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2materialstyleplugin quickwindow) +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2materialstyleplugin + qtquickcontrols2materialstyleimplplugin) + +# Basic style is the required fallback style. +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2materialstyleplugin + qtquickcontrols2basicstyleplugin) diff --git a/src/quickcontrols2/material/CheckBox.qml b/src/quickcontrols2/material/CheckBox.qml new file mode 100644 index 00000000000..02f195cad6d --- /dev/null +++ b/src/quickcontrols2/material/CheckBox.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.CheckBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 8 + padding: 8 + verticalPadding: padding + 7 + + indicator: CheckIndicator { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + + Ripple { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 28; height: 28 + + z: -1 + anchor: control + pressed: control.pressed + active: enabled && (control.down || control.visualFocus || control.hovered) + color: control.checked ? control.Material.highlightedRippleColor : control.Material.rippleColor + } + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } +} diff --git a/src/quickcontrols2/material/CheckDelegate.qml b/src/quickcontrols2/material/CheckDelegate.qml new file mode 100644 index 00000000000..15bf74fbf96 --- /dev/null +++ b/src/quickcontrols2/material/CheckDelegate.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.CheckDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 16 + verticalPadding: 8 + spacing: 16 + + icon.width: 24 + icon.height: 24 + icon.color: enabled ? Material.foreground : Material.hintTextColor + + indicator: CheckIndicator { + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: IconLabel { + leftPadding: !control.mirrored ? 0 : control.indicator.width + control.spacing + rightPadding: control.mirrored ? 0 : control.indicator.width + control.spacing + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + } + + background: Rectangle { + implicitHeight: control.Material.delegateHeight + + color: control.highlighted ? control.Material.listHighlightColor : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + pressed: control.pressed + anchor: control + active: enabled && (control.down || control.visualFocus || control.hovered) + color: control.Material.rippleColor + } + } +} diff --git a/src/quickcontrols2/material/ComboBox.qml b/src/quickcontrols2/material/ComboBox.qml new file mode 100644 index 00000000000..6f09ae3ce37 --- /dev/null +++ b/src/quickcontrols2/material/ComboBox.qml @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls.impl +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.ComboBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + topInset: 6 + bottomInset: 6 + + leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + + Material.elevation: flat ? control.pressed || (enabled && control.hovered) ? 2 : 0 + : control.pressed ? 8 : 2 + Material.background: flat ? "transparent" : undefined + Material.foreground: flat ? undefined : Material.primaryTextColor + + delegate: MenuItem { + width: ListView.view.width + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData + Material.foreground: control.currentIndex === index ? ListView.view.contentItem.Material.accent : ListView.view.contentItem.Material.foreground + highlighted: control.highlightedIndex === index + hoverEnabled: control.hoverEnabled + } + + indicator: ColorImage { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Material/images/drop-indicator.png" + } + + contentItem: T.TextField { + padding: 6 + leftPadding: control.editable ? 2 : control.mirrored ? 0 : 12 + rightPadding: control.editable ? 2 : control.mirrored ? 12 : 0 + + text: control.editable ? control.editText : control.displayText + + enabled: control.editable + autoScroll: control.editable + readOnly: control.down + inputMethodHints: control.inputMethodHints + validator: control.validator + selectByMouse: control.selectTextByMouse + + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + selectionColor: control.Material.accentColor + selectedTextColor: control.Material.primaryHighlightedTextColor + verticalAlignment: Text.AlignVCenter + + cursorDelegate: CursorDelegate { } + } + + background: Rectangle { + implicitWidth: 120 + implicitHeight: control.Material.buttonHeight + + radius: control.flat ? 0 : 2 + color: !control.editable ? control.Material.dialogColor : "transparent" + + layer.enabled: control.enabled && !control.editable && control.Material.background.a > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + + Rectangle { + visible: control.editable + y: parent.y + control.baselineOffset + width: parent.width + height: control.activeFocus ? 2 : 1 + color: control.editable && control.activeFocus ? control.Material.accentColor : control.Material.hintTextColor + } + + Ripple { + clip: control.flat + clipRadius: control.flat ? 0 : 2 + x: control.editable && control.indicator ? control.indicator.x : 0 + width: control.editable && control.indicator ? control.indicator.width : parent.width + height: parent.height + pressed: control.pressed + anchor: control.editable && control.indicator ? control.indicator : control + active: enabled && (control.pressed || control.visualFocus || control.hovered) + color: control.Material.rippleColor + } + } + + popup: T.Popup { + y: control.editable ? control.height - 5 : 0 + width: control.width + height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin) + transformOrigin: Item.Top + topMargin: 12 + bottomMargin: 12 + + Material.theme: control.Material.theme + Material.accent: control.Material.accent + Material.primary: control.Material.primary + + enter: Transition { + // grow_fade_in + NumberAnimation { property: "scale"; from: 0.9; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 0.0; easing.type: Easing.OutCubic; duration: 150 } + } + + exit: Transition { + // shrink_fade_out + NumberAnimation { property: "scale"; to: 0.9; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; to: 0.0; easing.type: Easing.OutCubic; duration: 150 } + } + + contentItem: ListView { + clip: true + implicitHeight: contentHeight + model: control.delegateModel + currentIndex: control.highlightedIndex + highlightMoveDuration: 0 + + T.ScrollIndicator.vertical: ScrollIndicator { } + } + + background: Rectangle { + radius: 2 + color: parent.Material.dialogColor + + layer.enabled: control.enabled + layer.effect: ElevationEffect { + elevation: 8 + } + } + } +} diff --git a/src/quickcontrols2/material/DelayButton.qml b/src/quickcontrols2/material/DelayButton.qml new file mode 100644 index 00000000000..57d1d2733a3 --- /dev/null +++ b/src/quickcontrols2/material/DelayButton.qml @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.DelayButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topInset: 6 + bottomInset: 6 + padding: 12 + horizontalPadding: padding - 4 + + Material.elevation: control.down ? 8 : 2 + + transition: Transition { + NumberAnimation { + duration: control.delay * (control.pressed ? 1.0 - control.progress : 0.3 * control.progress) + } + } + + contentItem: Text { + text: control.text + font: control.font + color: !control.enabled ? control.Material.hintTextColor : control.Material.foreground + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + // TODO: Add a proper ripple/ink effect for mouse/touch input and focus state + background: Rectangle { + implicitWidth: 64 + implicitHeight: control.Material.buttonHeight + + radius: 2 + color: !control.enabled ? control.Material.buttonDisabledColor : control.Material.buttonColor + + PaddedRectangle { + y: parent.height - 4 + width: parent.width + height: 4 + radius: 2 + topPadding: -2 + clip: true + color: control.checked && control.enabled ? control.Material.accentColor : control.Material.secondaryTextColor + + PaddedRectangle { + width: parent.width * control.progress + height: 4 + radius: 2 + topPadding: -2 + rightPadding: Math.max(-2, width - parent.width) + clip: true + color: control.Material.accentColor + } + } + + layer.enabled: control.enabled && control.Material.buttonColor.a > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + + Ripple { + clipRadius: 2 + width: parent.width + height: parent.height + pressed: control.pressed + anchor: control + active: enabled && (control.down || control.visualFocus || control.hovered) + color: control.Material.rippleColor + } + } +} diff --git a/src/quickcontrols2/material/Dial.qml b/src/quickcontrols2/material/Dial.qml new file mode 100644 index 00000000000..2731436f605 --- /dev/null +++ b/src/quickcontrols2/material/Dial.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.Dial { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 100 + + x: control.width / 2 - width / 2 + y: control.height / 2 - height / 2 + width: Math.max(64, Math.min(control.width, control.height)) + height: width + color: "transparent" + radius: width / 2 + + border.color: control.enabled ? control.Material.accentColor : control.Material.hintTextColor + } + + handle: SliderHandle { + x: control.background.x + control.background.width / 2 - width / 2 + y: control.background.y + control.background.height / 2 - height / 2 + transform: [ + Translate { + y: -control.background.height * 0.4 + control.handle.height / 2 + }, + Rotation { + angle: control.angle + origin.x: control.handle.width / 2 + origin.y: control.handle.height / 2 + } + ] + implicitWidth: 10 + implicitHeight: 10 + + value: control.value + handleHasFocus: control.visualFocus + handlePressed: control.pressed + handleHovered: control.hovered + } +} diff --git a/src/quickcontrols2/material/Dialog.qml b/src/quickcontrols2/material/Dialog.qml new file mode 100644 index 00000000000..1cb7f8c1864 --- /dev/null +++ b/src/quickcontrols2/material/Dialog.qml @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.Dialog { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + padding: 24 + topPadding: 20 + + Material.elevation: 24 + + enter: Transition { + // grow_fade_in + NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; easing.type: Easing.OutCubic; duration: 150 } + } + + exit: Transition { + // shrink_fade_out + NumberAnimation { property: "scale"; from: 1.0; to: 0.9; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 } + } + + background: Rectangle { + radius: 2 + color: control.Material.dialogColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } + + header: Label { + text: control.title + visible: control.title + elide: Label.ElideRight + padding: 24 + bottomPadding: 0 + // TODO: QPlatformTheme::TitleBarFont + font.bold: true + font.pixelSize: 16 + background: PaddedRectangle { + radius: 2 + color: control.Material.dialogColor + bottomPadding: -2 + clip: true + } + } + + footer: DialogButtonBox { + visible: count > 0 + } + + T.Overlay.modal: Rectangle { + color: control.Material.backgroundDimColor + Behavior on opacity { NumberAnimation { duration: 150 } } + } + + T.Overlay.modeless: Rectangle { + color: control.Material.backgroundDimColor + Behavior on opacity { NumberAnimation { duration: 150 } } + } +} diff --git a/src/quickcontrols2/material/DialogButtonBox.qml b/src/quickcontrols2/material/DialogButtonBox.qml new file mode 100644 index 00000000000..fac209c87b3 --- /dev/null +++ b/src/quickcontrols2/material/DialogButtonBox.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.DialogButtonBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: 8 + padding: 8 + verticalPadding: 2 + alignment: Qt.AlignRight + buttonLayout: T.DialogButtonBox.AndroidLayout + + Material.foreground: Material.accent + + delegate: Button { flat: true } + + contentItem: ListView { + implicitWidth: contentWidth + model: control.contentModel + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + } + + background: PaddedRectangle { + implicitHeight: control.Material.dialogButtonBoxHeight + radius: 2 + color: control.Material.dialogColor + // Rounded corners should be only at the top or at the bottom + topPadding: control.position === T.DialogButtonBox.Footer ? -2 : 0 + bottomPadding: control.position === T.DialogButtonBox.Header ? -2 : 0 + clip: true + } +} diff --git a/src/quickcontrols2/material/Drawer.qml b/src/quickcontrols2/material/Drawer.qml new file mode 100644 index 00000000000..93c4bf5698c --- /dev/null +++ b/src/quickcontrols2/material/Drawer.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.Drawer { + id: control + + parent: T.Overlay.overlay + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: !dim && edge === Qt.BottomEdge && Material.elevation === 0 + leftPadding: !dim && edge === Qt.RightEdge && Material.elevation === 0 + rightPadding: !dim && edge === Qt.LeftEdge && Material.elevation === 0 + bottomPadding: !dim && edge === Qt.TopEdge && Material.elevation === 0 + + enter: Transition { SmoothedAnimation { velocity: 5 } } + exit: Transition { SmoothedAnimation { velocity: 5 } } + + Material.elevation: !interactive && !dim ? 0 : 16 + + background: Rectangle { + color: control.Material.dialogColor + + Rectangle { + readonly property bool horizontal: control.edge === Qt.LeftEdge || control.edge === Qt.RightEdge + width: horizontal ? 1 : parent.width + height: horizontal ? parent.height : 1 + color: control.Material.dividerColor + x: control.edge === Qt.LeftEdge ? parent.width - 1 : 0 + y: control.edge === Qt.TopEdge ? parent.height - 1 : 0 + visible: !control.dim && control.Material.elevation === 0 + } + + layer.enabled: control.position > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + fullHeight: true + } + } + + T.Overlay.modal: Rectangle { + color: control.Material.backgroundDimColor + Behavior on opacity { NumberAnimation { duration: 150 } } + } + + T.Overlay.modeless: Rectangle { + color: control.Material.backgroundDimColor + Behavior on opacity { NumberAnimation { duration: 150 } } + } +} diff --git a/src/quickcontrols2/material/Frame.qml b/src/quickcontrols2/material/Frame.qml new file mode 100644 index 00000000000..8626f7661ad --- /dev/null +++ b/src/quickcontrols2/material/Frame.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.Frame { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 12 + verticalPadding: Material.frameVerticalPadding + + background: Rectangle { + radius: 2 + color: control.Material.elevation > 0 ? control.Material.backgroundColor : "transparent" + border.color: control.Material.frameColor + + layer.enabled: control.enabled && control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } +} diff --git a/src/quickcontrols2/material/GroupBox.qml b/src/quickcontrols2/material/GroupBox.qml new file mode 100644 index 00000000000..4a27b83241b --- /dev/null +++ b/src/quickcontrols2/material/GroupBox.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.GroupBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitLabelWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: 6 + padding: 12 + topPadding: Material.frameVerticalPadding + (implicitLabelWidth > 0 ? implicitLabelHeight + spacing : 0) + bottomPadding: Material.frameVerticalPadding + + label: Text { + x: control.leftPadding + width: control.availableWidth + + text: control.title + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + background: Rectangle { + y: control.topPadding - control.bottomPadding + width: parent.width + height: parent.height - control.topPadding + control.bottomPadding + + radius: 2 + color: control.Material.elevation > 0 ? control.Material.backgroundColor : "transparent" + border.color: control.Material.frameColor + + layer.enabled: control.enabled && control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } +} diff --git a/src/quickcontrols2/material/HorizontalHeaderView.qml b/src/quickcontrols2/material/HorizontalHeaderView.qml new file mode 100644 index 00000000000..d2608c76bc5 --- /dev/null +++ b/src/quickcontrols2/material/HorizontalHeaderView.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.HorizontalHeaderView { + id: control + + implicitWidth: syncView ? syncView.width : 0 + implicitHeight: contentHeight + + delegate: Rectangle { + // Qt6: add cellPadding (and font etc) as public API in headerview + readonly property real cellPadding: 8 + + implicitWidth: text.implicitWidth + (cellPadding * 2) + implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2)) + color: control.Material.backgroundColor + + Text { + id: text + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] + : model[control.textRole]) + : modelData + width: parent.width + height: parent.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: enabled ? control.Material.foreground : control.Material.hintTextColor + } + } +} diff --git a/src/quickcontrols2/material/ItemDelegate.qml b/src/quickcontrols2/material/ItemDelegate.qml new file mode 100644 index 00000000000..4230bccf2f5 --- /dev/null +++ b/src/quickcontrols2/material/ItemDelegate.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.ItemDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 16 + verticalPadding: 8 + spacing: 16 + + icon.width: 24 + icon.height: 24 + icon.color: enabled ? Material.foreground : Material.hintTextColor + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + } + + background: Rectangle { + implicitHeight: control.Material.delegateHeight + + color: control.highlighted ? control.Material.listHighlightColor : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + pressed: control.pressed + anchor: control + active: enabled && (control.down || control.visualFocus || control.hovered) + color: control.Material.rippleColor + } + } +} diff --git a/src/quickcontrols2/material/LICENSE_ANGULARJS.txt b/src/quickcontrols2/material/LICENSE_ANGULARJS.txt new file mode 100644 index 00000000000..c1f2a826bbf --- /dev/null +++ b/src/quickcontrols2/material/LICENSE_ANGULARJS.txt @@ -0,0 +1,19 @@ +Copyright (c) 2014-2016 Google, Inc. http://angularjs.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/quickcontrols2/material/Label.qml b/src/quickcontrols2/material/Label.qml new file mode 100644 index 00000000000..77e85f4297c --- /dev/null +++ b/src/quickcontrols2/material/Label.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material + +T.Label { + id: control + + color: enabled ? Material.foreground : Material.hintTextColor + linkColor: Material.accentColor +} diff --git a/src/quickcontrols2/material/Menu.qml b/src/quickcontrols2/material/Menu.qml new file mode 100644 index 00000000000..df11e0ebf0f --- /dev/null +++ b/src/quickcontrols2/material/Menu.qml @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import QtQuick.Window + +T.Menu { + id: control + + Material.elevation: 8 + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + margins: 0 + verticalPadding: 8 + + transformOrigin: !cascade ? Item.Top : (mirrored ? Item.TopRight : Item.TopLeft) + + delegate: MenuItem { } + + enter: Transition { + // grow_fade_in + NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; easing.type: Easing.OutCubic; duration: 150 } + } + + exit: Transition { + // shrink_fade_out + NumberAnimation { property: "scale"; from: 1.0; to: 0.9; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 } + } + + contentItem: ListView { + implicitHeight: contentHeight + + model: control.contentModel + interactive: contentHeight + control.topPadding + control.bottomPadding > control.height + clip: true + currentIndex: control.currentIndex + + ScrollIndicator.vertical: ScrollIndicator {} + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: control.Material.menuItemHeight + + radius: 3 + color: control.Material.dialogColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } + + T.Overlay.modal: Rectangle { + color: control.Material.backgroundDimColor + Behavior on opacity { NumberAnimation { duration: 150 } } + } + + T.Overlay.modeless: Rectangle { + color: control.Material.backgroundDimColor + Behavior on opacity { NumberAnimation { duration: 150 } } + } +} diff --git a/src/quickcontrols2/material/MenuBar.qml b/src/quickcontrols2/material/MenuBar.qml new file mode 100644 index 00000000000..a0c3bd3fc59 --- /dev/null +++ b/src/quickcontrols2/material/MenuBar.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.MenuBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + delegate: MenuBarItem { } + + contentItem: Row { + spacing: control.spacing + Repeater { + model: control.contentModel + } + } + + background: Rectangle { + implicitHeight: 40 + color: control.Material.dialogColor + } +} diff --git a/src/quickcontrols2/material/MenuBarItem.qml b/src/quickcontrols2/material/MenuBarItem.qml new file mode 100644 index 00000000000..f1d4e87d8a1 --- /dev/null +++ b/src/quickcontrols2/material/MenuBarItem.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.MenuBarItem { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 16 + verticalPadding: 12 + spacing: 16 + + icon.width: 24 + icon.height: 24 + icon.color: enabled ? Material.foreground : Material.hintTextColor + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + } + + background: Rectangle { + implicitWidth: 40 + implicitHeight: 40 + color: control.highlighted ? control.Material.listHighlightColor : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + pressed: control.pressed + anchor: control + active: control.down || control.highlighted + color: control.Material.rippleColor + } + } +} diff --git a/src/quickcontrols2/material/MenuItem.qml b/src/quickcontrols2/material/MenuItem.qml new file mode 100644 index 00000000000..fab2de2696c --- /dev/null +++ b/src/quickcontrols2/material/MenuItem.qml @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.MenuItem { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 16 + verticalPadding: Material.menuItemVerticalPadding + spacing: 16 + + icon.width: 24 + icon.height: 24 + icon.color: enabled ? Material.foreground : Material.hintTextColor + + indicator: CheckIndicator { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + visible: control.checkable + control: control + checkState: control.checked ? Qt.Checked : Qt.Unchecked + } + + arrow: ColorImage { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + + visible: control.subMenu + mirror: control.mirrored + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Material/images/arrow-indicator.png" + } + + contentItem: IconLabel { + readonly property real arrowPadding: control.subMenu && control.arrow ? control.arrow.width + control.spacing : 0 + readonly property real indicatorPadding: control.checkable && control.indicator ? control.indicator.width + control.spacing : 0 + leftPadding: !control.mirrored ? indicatorPadding : arrowPadding + rightPadding: control.mirrored ? indicatorPadding : arrowPadding + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: control.Material.menuItemHeight + color: control.highlighted ? control.Material.listHighlightColor : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + pressed: control.pressed + anchor: control + active: control.down || control.highlighted + color: control.Material.rippleColor + } + } +} diff --git a/src/quickcontrols2/material/MenuSeparator.qml b/src/quickcontrols2/material/MenuSeparator.qml new file mode 100644 index 00000000000..08a33ffe15b --- /dev/null +++ b/src/quickcontrols2/material/MenuSeparator.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material + +T.MenuSeparator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + verticalPadding: 8 + + contentItem: Rectangle { + implicitWidth: 200 + implicitHeight: 1 + color: control.Material.dividerColor + } +} diff --git a/src/quickcontrols2/material/Page.qml b/src/quickcontrols2/material/Page.qml new file mode 100644 index 00000000000..711fac2ddbd --- /dev/null +++ b/src/quickcontrols2/material/Page.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material + +T.Page { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + background: Rectangle { + color: control.Material.backgroundColor + } +} diff --git a/src/quickcontrols2/material/PageIndicator.qml b/src/quickcontrols2/material/PageIndicator.qml new file mode 100644 index 00000000000..161b7b2d833 --- /dev/null +++ b/src/quickcontrols2/material/PageIndicator.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material + +T.PageIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + delegate: Rectangle { + implicitWidth: 8 + implicitHeight: 8 + + radius: width / 2 + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + + // qmllint disable unqualified + // We can't make "pressed" a required property, as QQuickPageIndicator doesn't create + // the delegates, and so it can't set it as an initial property. + opacity: index === control.currentIndex ? 0.95 : pressed ? 0.7 : 0.45 + + required property int index + + Behavior on opacity { OpacityAnimator { duration: 100 } } + } + + contentItem: Row { + spacing: control.spacing + + Repeater { + model: control.count + delegate: control.delegate + } + } +} diff --git a/src/quickcontrols2/material/Pane.qml b/src/quickcontrols2/material/Pane.qml new file mode 100644 index 00000000000..055a8d236db --- /dev/null +++ b/src/quickcontrols2/material/Pane.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.Pane { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 12 + + background: Rectangle { + color: control.Material.backgroundColor + radius: control.Material.elevation > 0 ? 2 : 0 + + layer.enabled: control.enabled && control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } +} diff --git a/src/quickcontrols2/material/Popup.qml b/src/quickcontrols2/material/Popup.qml new file mode 100644 index 00000000000..cb5b62ece74 --- /dev/null +++ b/src/quickcontrols2/material/Popup.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.Popup { + id: control + + Material.elevation: 24 + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 12 + + enter: Transition { + // grow_fade_in + NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; easing.type: Easing.OutCubic; duration: 150 } + } + + exit: Transition { + // shrink_fade_out + NumberAnimation { property: "scale"; from: 1.0; to: 0.9; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 } + } + + background: Rectangle { + radius: 2 + color: control.Material.dialogColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } + + T.Overlay.modal: Rectangle { + color: control.Material.backgroundDimColor + Behavior on opacity { NumberAnimation { duration: 150 } } + } + + T.Overlay.modeless: Rectangle { + color: control.Material.backgroundDimColor + Behavior on opacity { NumberAnimation { duration: 150 } } + } +} diff --git a/src/quickcontrols2/material/ProgressBar.qml b/src/quickcontrols2/material/ProgressBar.qml new file mode 100644 index 00000000000..dd4fae0e364 --- /dev/null +++ b/src/quickcontrols2/material/ProgressBar.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.ProgressBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + contentItem: ProgressBarImpl { + implicitHeight: 4 + + scale: control.mirrored ? -1 : 1 + color: control.Material.accentColor + progress: control.position + indeterminate: control.visible && control.indeterminate + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 4 + y: (control.height - height) / 2 + height: 4 + + color: Qt.rgba(control.Material.accentColor.r, control.Material.accentColor.g, control.Material.accentColor.b, 0.25) + } +} diff --git a/src/quickcontrols2/material/RadioButton.qml b/src/quickcontrols2/material/RadioButton.qml new file mode 100644 index 00000000000..664cb19ecdf --- /dev/null +++ b/src/quickcontrols2/material/RadioButton.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.RadioButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 8 + padding: 8 + verticalPadding: padding + 6 + + indicator: RadioIndicator { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + + Ripple { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 28; height: 28 + + z: -1 + anchor: control + pressed: control.pressed + active: control.down || control.visualFocus || control.hovered + color: control.checked ? control.Material.highlightedRippleColor : control.Material.rippleColor + } + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } +} diff --git a/src/quickcontrols2/material/RadioDelegate.qml b/src/quickcontrols2/material/RadioDelegate.qml new file mode 100644 index 00000000000..334e570bbfa --- /dev/null +++ b/src/quickcontrols2/material/RadioDelegate.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.RadioDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 16 + verticalPadding: 8 + spacing: 16 + + icon.width: 24 + icon.height: 24 + icon.color: enabled ? Material.foreground : Material.hintTextColor + + indicator: RadioIndicator { + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: IconLabel { + leftPadding: !control.mirrored ? 0 : control.indicator.width + control.spacing + rightPadding: control.mirrored ? 0 : control.indicator.width + control.spacing + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + } + + background: Rectangle { + implicitHeight: control.Material.delegateHeight + + color: control.highlighted ? control.Material.listHighlightColor : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + pressed: control.pressed + anchor: control + active: control.down || control.visualFocus || control.hovered + color: control.Material.rippleColor + } + } +} diff --git a/src/quickcontrols2/material/RangeSlider.qml b/src/quickcontrols2/material/RangeSlider.qml new file mode 100644 index 00000000000..a6bb0c69a21 --- /dev/null +++ b/src/quickcontrols2/material/RangeSlider.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.RangeSlider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + first.implicitHandleWidth + leftPadding + rightPadding, + second.implicitHandleWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + first.implicitHandleHeight + topPadding + bottomPadding, + second.implicitHandleHeight + topPadding + bottomPadding) + + padding: 6 + + first.handle: SliderHandle { + x: control.leftPadding + (control.horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height)) + value: control.first.value + handleHasFocus: activeFocus + handlePressed: control.first.pressed + handleHovered: control.first.hovered + } + + second.handle: SliderHandle { + x: control.leftPadding + (control.horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height)) + value: control.second.value + handleHasFocus: activeFocus + handlePressed: control.second.pressed + handleHovered: control.second.hovered + } + + background: Rectangle { + x: control.leftPadding + (control.horizontal ? 0 : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : 0) + implicitWidth: control.horizontal ? 200 : 48 + implicitHeight: control.horizontal ? 48 : 200 + width: control.horizontal ? control.availableWidth : 4 + height: control.horizontal ? 4 : control.availableHeight + scale: control.horizontal && control.mirrored ? -1 : 1 + color: control.enabled ? Color.transparent(control.Material.accentColor, 0.33) : control.Material.sliderDisabledColor + + Rectangle { + x: control.horizontal ? control.first.position * parent.width : 0 + y: control.horizontal ? 0 : control.second.visualPosition * parent.height + width: control.horizontal ? control.second.position * parent.width - control.first.position * parent.width : 4 + height: control.horizontal ? 4 : control.second.position * parent.height - control.first.position * parent.height + + color: control.enabled ? control.Material.accentColor : control.Material.sliderDisabledColor + } + } +} diff --git a/src/quickcontrols2/material/RoundButton.qml b/src/quickcontrols2/material/RoundButton.qml new file mode 100644 index 00000000000..ff54b2699b4 --- /dev/null +++ b/src/quickcontrols2/material/RoundButton.qml @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.RoundButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + topInset: 6 + leftInset: 6 + rightInset: 6 + bottomInset: 6 + padding: 12 + spacing: 6 + + icon.width: 24 + icon.height: 24 + icon.color: !enabled ? Material.hintTextColor : + flat && highlighted ? Material.accentColor : + highlighted ? Material.primaryHighlightedTextColor : Material.foreground + + Material.elevation: flat ? control.down || control.hovered ? 2 : 0 + : control.down ? 12 : 6 + Material.background: flat ? "transparent" : undefined + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: !control.enabled ? control.Material.hintTextColor : + control.flat && control.highlighted ? control.Material.accentColor : + control.highlighted ? control.Material.primaryHighlightedTextColor : control.Material.foreground + } + + // TODO: Add a proper ripple/ink effect for mouse/touch input and focus state + background: Rectangle { + implicitWidth: control.Material.buttonHeight + implicitHeight: control.Material.buttonHeight + + radius: control.radius + color: !control.enabled ? control.Material.buttonDisabledColor + : control.checked || control.highlighted ? control.Material.highlightedButtonColor : control.Material.buttonColor + + Rectangle { + width: parent.width + height: parent.height + radius: control.radius + visible: enabled && (control.hovered || control.visualFocus) + color: control.Material.rippleColor + } + + Rectangle { + width: parent.width + height: parent.height + radius: control.radius + visible: control.down + color: control.Material.rippleColor + } + + // The layer is disabled when the button color is transparent so that you can do + // Material.background: "transparent" and get a proper flat button without needing + // to set Material.elevation as well + layer.enabled: control.enabled && control.Material.buttonColor.a > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } +} diff --git a/src/quickcontrols2/material/ScrollBar.qml b/src/quickcontrols2/material/ScrollBar.qml new file mode 100644 index 00000000000..e89452174cc --- /dev/null +++ b/src/quickcontrols2/material/ScrollBar.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material + +T.ScrollBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: control.interactive ? 1 : 2 + visible: control.policy !== T.ScrollBar.AlwaysOff + minimumSize: orientation === Qt.Horizontal ? height / width : width / height + + contentItem: Rectangle { + implicitWidth: control.interactive ? 13 : 4 + implicitHeight: control.interactive ? 13 : 4 + + color: control.pressed ? control.Material.scrollBarPressedColor : + control.interactive && control.hovered ? control.Material.scrollBarHoveredColor : control.Material.scrollBarColor + opacity: 0.0 + } + + background: Rectangle { + implicitWidth: control.interactive ? 16 : 4 + implicitHeight: control.interactive ? 16 : 4 + color: "#0e000000" + opacity: 0.0 + visible: control.interactive + } + + states: State { + name: "active" + when: control.policy === T.ScrollBar.AlwaysOn || (control.active && control.size < 1.0) + } + + transitions: [ + Transition { + to: "active" + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 1.0 } + }, + Transition { + from: "active" + SequentialAnimation { + PropertyAction{ targets: [control.contentItem, control.background]; property: "opacity"; value: 1.0 } + PauseAnimation { duration: 2450 } + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 0.0 } + } + } + ] +} diff --git a/src/quickcontrols2/material/ScrollIndicator.qml b/src/quickcontrols2/material/ScrollIndicator.qml new file mode 100644 index 00000000000..bc81c630ee5 --- /dev/null +++ b/src/quickcontrols2/material/ScrollIndicator.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material + +T.ScrollIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 2 + + contentItem: Rectangle { + implicitWidth: 4 + implicitHeight: 4 + + color: control.Material.scrollBarColor + visible: control.size < 1.0 + opacity: 0.0 + + states: State { + name: "active" + when: control.active + PropertyChanges { target: control.contentItem; opacity: 0.75 } + } + + transitions: [ + Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 450 } + NumberAnimation { target: control.contentItem; duration: 200; property: "opacity"; to: 0.0 } + } + } + ] + } +} diff --git a/src/quickcontrols2/material/ScrollView.qml b/src/quickcontrols2/material/ScrollView.qml new file mode 100644 index 00000000000..a6bba9de05a --- /dev/null +++ b/src/quickcontrols2/material/ScrollView.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ScrollView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + ScrollBar.vertical: ScrollBar { + parent: control + x: control.mirrored ? 0 : control.width - width + y: control.topPadding + height: control.availableHeight + active: control.ScrollBar.horizontal.active + } + + ScrollBar.horizontal: ScrollBar { + parent: control + x: control.leftPadding + y: control.height - height + width: control.availableWidth + active: control.ScrollBar.vertical.active + } +} diff --git a/src/quickcontrols2/material/SelectionRectangle.qml b/src/quickcontrols2/material/SelectionRectangle.qml new file mode 100644 index 00000000000..f31057dc7bf --- /dev/null +++ b/src/quickcontrols2/material/SelectionRectangle.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.SelectionRectangle { + id: control + + topLeftHandle: handle + bottomRightHandle: handle + + Component { + id: handle + SliderHandle { + palette: SelectionRectangle.control.palette + handlePressed: tapHandler.pressed || SelectionRectangle.dragging + handleHovered: hoverHandler.hovered + visible: SelectionRectangle.control.active + + HoverHandler { + id: hoverHandler + } + + TapHandler { + id: tapHandler + } + } + } +} diff --git a/src/quickcontrols2/material/Slider.qml b/src/quickcontrols2/material/Slider.qml new file mode 100644 index 00000000000..2a36673434d --- /dev/null +++ b/src/quickcontrols2/material/Slider.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.Slider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitHandleWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitHandleHeight + topPadding + bottomPadding) + + padding: 6 + + handle: SliderHandle { + x: control.leftPadding + (control.horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) + value: control.value + handleHasFocus: control.visualFocus + handlePressed: control.pressed + handleHovered: control.hovered + } + + background: Rectangle { + x: control.leftPadding + (control.horizontal ? 0 : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : 0) + implicitWidth: control.horizontal ? 200 : 48 + implicitHeight: control.horizontal ? 48 : 200 + width: control.horizontal ? control.availableWidth : 4 + height: control.horizontal ? 4 : control.availableHeight + scale: control.horizontal && control.mirrored ? -1 : 1 + color: control.enabled ? Color.transparent(control.Material.accentColor, 0.33) : control.Material.sliderDisabledColor + + Rectangle { + x: control.horizontal ? 0 : (parent.width - width) / 2 + y: control.horizontal ? (parent.height - height) / 2 : control.visualPosition * parent.height + width: control.horizontal ? control.position * parent.width : 4 + height: control.horizontal ? 4 : control.position * parent.height + + color: control.enabled ? control.Material.accentColor : control.Material.sliderDisabledColor + } + } +} diff --git a/src/quickcontrols2/material/SpinBox.qml b/src/quickcontrols2/material/SpinBox.qml new file mode 100644 index 00000000000..9ea6fd92606 --- /dev/null +++ b/src/quickcontrols2/material/SpinBox.qml @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.SpinBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentItem.implicitWidth + + up.implicitIndicatorWidth + + down.implicitIndicatorWidth) + implicitHeight: Math.max(implicitContentHeight + topPadding + bottomPadding, + implicitBackgroundHeight, + up.implicitIndicatorHeight, + down.implicitIndicatorHeight) + + spacing: 6 + topPadding: 8 + bottomPadding: 16 + leftPadding: (control.mirrored ? (up.indicator ? up.indicator.width : 0) : (down.indicator ? down.indicator.width : 0)) + rightPadding: (control.mirrored ? (down.indicator ? down.indicator.width : 0) : (up.indicator ? up.indicator.width : 0)) + + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + + contentItem: TextInput { + text: control.displayText + + font: control.font + color: enabled ? control.Material.foreground : control.Material.hintTextColor + selectionColor: control.Material.textSelectionColor + selectedTextColor: control.Material.foreground + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + + cursorDelegate: CursorDelegate { } + + readOnly: !control.editable + validator: control.validator + inputMethodHints: control.inputMethodHints + } + + up.indicator: Item { + x: control.mirrored ? 0 : control.width - width + implicitWidth: control.Material.touchTarget + implicitHeight: control.Material.touchTarget + height: control.height + width: height + + Ripple { + clipRadius: 2 + x: control.spacing + y: control.spacing + width: parent.width - 2 * control.spacing + height: parent.height - 2 * control.spacing + pressed: control.up.pressed + active: control.up.pressed || control.up.hovered || control.visualFocus + color: control.Material.rippleColor + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: Math.min(parent.width / 3, parent.height / 3) + height: 2 + color: enabled ? control.Material.foreground : control.Material.spinBoxDisabledIconColor + } + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 2 + height: Math.min(parent.width / 3, parent.height / 3) + color: enabled ? control.Material.foreground : control.Material.spinBoxDisabledIconColor + } + } + + down.indicator: Item { + x: control.mirrored ? control.width - width : 0 + implicitWidth: control.Material.touchTarget + implicitHeight: control.Material.touchTarget + height: control.height + width: height + + Ripple { + clipRadius: 2 + x: control.spacing + y: control.spacing + width: parent.width - 2 * control.spacing + height: parent.height - 2 * control.spacing + pressed: control.down.pressed + active: control.down.pressed || control.down.hovered || control.visualFocus + color: control.Material.rippleColor + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: parent.width / 3 + height: 2 + color: enabled ? control.Material.foreground : control.Material.spinBoxDisabledIconColor + } + } + + background: Item { + implicitWidth: 192 + implicitHeight: control.Material.touchTarget + + Rectangle { + x: parent.width / 2 - width / 2 + y: parent.y + parent.height - height - control.bottomPadding / 2 + width: control.availableWidth + height: control.activeFocus ? 2 : 1 + color: control.activeFocus ? control.Material.accentColor : control.Material.hintTextColor + } + } +} diff --git a/src/quickcontrols2/material/SplitView.qml b/src/quickcontrols2/material/SplitView.qml new file mode 100644 index 00000000000..95556cd0912 --- /dev/null +++ b/src/quickcontrols2/material/SplitView.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material + +T.SplitView { + id: control + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + handle: Rectangle { + implicitWidth: control.orientation === Qt.Horizontal ? 6 : control.width + implicitHeight: control.orientation === Qt.Horizontal ? control.height : 6 + color: T.SplitHandle.pressed ? control.Material.background + : Qt.lighter(control.Material.background, T.SplitHandle.hovered ? 1.2 : 1.1) + + Rectangle { + color: control.Material.secondaryTextColor + width: control.orientation === Qt.Horizontal ? thickness : length + height: control.orientation === Qt.Horizontal ? length : thickness + radius: thickness + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + property int length: parent.T.SplitHandle.pressed ? 3 : 8 + readonly property int thickness: parent.T.SplitHandle.pressed ? 3 : 1 + + Behavior on length { + NumberAnimation { + duration: 100 + } + } + } + } +} diff --git a/src/quickcontrols2/material/StackView.qml b/src/quickcontrols2/material/StackView.qml new file mode 100644 index 00000000000..4c3e6749ac1 --- /dev/null +++ b/src/quickcontrols2/material/StackView.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material + +T.StackView { + id: control + + popEnter: Transition { + // slide_in_left + NumberAnimation { property: "x"; from: (control.mirrored ? -0.5 : 0.5) * -control.width; to: 0; duration: 200; easing.type: Easing.OutCubic } + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 200; easing.type: Easing.OutCubic } + } + + popExit: Transition { + // slide_out_right + NumberAnimation { property: "x"; from: 0; to: (control.mirrored ? -0.5 : 0.5) * control.width; duration: 200; easing.type: Easing.OutCubic } + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 200; easing.type: Easing.OutCubic } + } + + pushEnter: Transition { + // slide_in_right + NumberAnimation { property: "x"; from: (control.mirrored ? -0.5 : 0.5) * control.width; to: 0; duration: 200; easing.type: Easing.OutCubic } + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 200; easing.type: Easing.OutCubic } + } + + pushExit: Transition { + // slide_out_left + NumberAnimation { property: "x"; from: 0; to: (control.mirrored ? -0.5 : 0.5) * -control.width; duration: 200; easing.type: Easing.OutCubic } + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 200; easing.type: Easing.OutCubic } + } + + replaceEnter: Transition { + // slide_in_right + NumberAnimation { property: "x"; from: (control.mirrored ? -0.5 : 0.5) * control.width; to: 0; duration: 200; easing.type: Easing.OutCubic } + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 200; easing.type: Easing.OutCubic } + } + + replaceExit: Transition { + // slide_out_left + NumberAnimation { property: "x"; from: 0; to: (control.mirrored ? -0.5 : 0.5) * -control.width; duration: 200; easing.type: Easing.OutCubic } + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 200; easing.type: Easing.OutCubic } + } +} diff --git a/src/quickcontrols2/material/SwipeDelegate.qml b/src/quickcontrols2/material/SwipeDelegate.qml new file mode 100644 index 00000000000..f5e103c0d99 --- /dev/null +++ b/src/quickcontrols2/material/SwipeDelegate.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.SwipeDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 16 + verticalPadding: 8 + spacing: 16 + + icon.width: 24 + icon.height: 24 + icon.color: enabled ? Material.foreground : Material.hintTextColor + + swipe.transition: Transition { SmoothedAnimation { velocity: 3; easing.type: Easing.InOutCubic } } + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + } + + background: Rectangle { + implicitHeight: control.Material.delegateHeight + + color: control.Material.backgroundColor + + Rectangle { + width: parent.width + height: parent.height + visible: control.highlighted + color: control.Material.listHighlightColor + } + + Ripple { + width: parent.width + height: parent.height + + clip: visible + pressed: control.pressed + anchor: control + active: enabled && (control.down || control.visualFocus || control.hovered) + color: control.Material.rippleColor + enabled: control.swipe.position === 0 + } + } +} diff --git a/src/quickcontrols2/material/SwipeView.qml b/src/quickcontrols2/material/SwipeView.qml new file mode 100644 index 00000000000..cd4da229c25 --- /dev/null +++ b/src/quickcontrols2/material/SwipeView.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material + +T.SwipeView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + contentItem: ListView { + model: control.contentModel + interactive: control.interactive + currentIndex: control.currentIndex + focus: control.focus + + spacing: control.spacing + orientation: control.orientation + snapMode: ListView.SnapOneItem + boundsBehavior: Flickable.StopAtBounds + + highlightRangeMode: ListView.StrictlyEnforceRange + preferredHighlightBegin: 0 + preferredHighlightEnd: 0 + highlightMoveDuration: 250 + maximumFlickVelocity: 4 * (control.orientation === Qt.Horizontal ? width : height) + } +} diff --git a/src/quickcontrols2/material/Switch.qml b/src/quickcontrols2/material/Switch.qml new file mode 100644 index 00000000000..dc8a14347da --- /dev/null +++ b/src/quickcontrols2/material/Switch.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import QtQuick.Templates as T + +T.Switch { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 8 + spacing: 8 + + indicator: SwitchIndicator { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + + Ripple { + x: parent.handle.x + parent.handle.width / 2 - width / 2 + y: parent.handle.y + parent.handle.height / 2 - height / 2 + width: 28; height: 28 + pressed: control.pressed + active: enabled && (control.down || control.visualFocus || control.hovered) + color: control.checked ? control.Material.highlightedRippleColor : control.Material.rippleColor + } + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } +} diff --git a/src/quickcontrols2/material/SwitchDelegate.qml b/src/quickcontrols2/material/SwitchDelegate.qml new file mode 100644 index 00000000000..29e49032d8a --- /dev/null +++ b/src/quickcontrols2/material/SwitchDelegate.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.SwitchDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 16 + verticalPadding: Material.switchDelegateVerticalPadding + spacing: 16 + + icon.width: 24 + icon.height: 24 + icon.color: enabled ? Material.foreground : Material.hintTextColor + + indicator: SwitchIndicator { + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: IconLabel { + leftPadding: !control.mirrored ? 0 : control.indicator.width + control.spacing + rightPadding: control.mirrored ? 0 : control.indicator.width + control.spacing + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.enabled ? control.Material.foreground : control.Material.hintTextColor + } + + background: Rectangle { + implicitHeight: control.Material.delegateHeight + + color: control.highlighted ? control.Material.listHighlightColor : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + pressed: control.pressed + anchor: control + active: enabled && (control.down || control.visualFocus || control.hovered) + color: control.Material.rippleColor + } + } +} diff --git a/src/quickcontrols2/material/TabBar.qml b/src/quickcontrols2/material/TabBar.qml new file mode 100644 index 00000000000..9e9585f31b1 --- /dev/null +++ b/src/quickcontrols2/material/TabBar.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.TabBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: 1 + + contentItem: ListView { + model: control.contentModel + currentIndex: control.currentIndex + + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + flickableDirection: Flickable.AutoFlickIfNeeded + snapMode: ListView.SnapToItem + + highlightMoveDuration: 250 + highlightResizeDuration: 0 + highlightFollowsCurrentItem: true + highlightRangeMode: ListView.ApplyRange + preferredHighlightBegin: 48 + preferredHighlightEnd: width - 48 + + highlight: Item { + z: 2 + Rectangle { + height: 2 + width: parent.width + y: control.position === T.TabBar.Footer ? 0 : parent.height - height + color: control.Material.accentColor + } + } + } + + background: Rectangle { + color: control.Material.backgroundColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + fullWidth: true + } + } +} diff --git a/src/quickcontrols2/material/TabButton.qml b/src/quickcontrols2/material/TabButton.qml new file mode 100644 index 00000000000..40e10d9f330 --- /dev/null +++ b/src/quickcontrols2/material/TabButton.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.TabButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 12 + spacing: 6 + + icon.width: 24 + icon.height: 24 + icon.color: !enabled ? Material.hintTextColor : down || checked ? Material.accentColor : Material.foreground + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: !control.enabled ? control.Material.hintTextColor : control.down || control.checked ? control.Material.accentColor : control.Material.foreground + } + + background: Ripple { + implicitHeight: control.Material.touchTarget + + clip: true + pressed: control.pressed + anchor: control + active: enabled && (control.down || control.visualFocus || control.hovered) + color: control.Material.rippleColor + } +} diff --git a/src/quickcontrols2/material/TextArea.qml b/src/quickcontrols2/material/TextArea.qml new file mode 100644 index 00000000000..a213bd7ab08 --- /dev/null +++ b/src/quickcontrols2/material/TextArea.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.TextArea { + id: control + + implicitWidth: Math.max(contentWidth + leftPadding + rightPadding, + implicitBackgroundWidth + leftInset + rightInset, + placeholder.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(contentHeight + topPadding + bottomPadding, + implicitBackgroundHeight + topInset + bottomInset, + placeholder.implicitHeight + 1 + topPadding + bottomPadding) + + topPadding: 8 + bottomPadding: 16 + + color: enabled ? Material.foreground : Material.hintTextColor + selectionColor: Material.accentColor + selectedTextColor: Material.primaryHighlightedTextColor + placeholderTextColor: Material.hintTextColor + cursorDelegate: CursorDelegate { } + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + verticalAlignment: control.verticalAlignment + elide: Text.ElideRight + renderType: control.renderType + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + } + + background: Rectangle { + y: parent.height - height - control.bottomPadding / 2 + implicitWidth: 120 + height: control.activeFocus ? 2 : 1 + color: control.activeFocus ? control.Material.accentColor : control.Material.hintTextColor + } +} diff --git a/src/quickcontrols2/material/TextField.qml b/src/quickcontrols2/material/TextField.qml new file mode 100644 index 00000000000..3ca1881a947 --- /dev/null +++ b/src/quickcontrols2/material/TextField.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.TextField { + id: control + + implicitWidth: implicitBackgroundWidth + leftInset + rightInset + || Math.max(contentWidth, placeholder.implicitWidth) + leftPadding + rightPadding + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding, + placeholder.implicitHeight + topPadding + bottomPadding) + + topPadding: 8 + bottomPadding: 16 + + color: enabled ? Material.foreground : Material.hintTextColor + selectionColor: Material.accentColor + selectedTextColor: Material.primaryHighlightedTextColor + placeholderTextColor: Material.hintTextColor + verticalAlignment: TextInput.AlignVCenter + + cursorDelegate: CursorDelegate { } + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + verticalAlignment: control.verticalAlignment + elide: Text.ElideRight + renderType: control.renderType + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + } + + background: Rectangle { + y: control.height - height - control.bottomPadding + 8 + implicitWidth: 120 + height: control.activeFocus || (enabled && control.hovered) ? 2 : 1 + color: control.activeFocus ? control.Material.accentColor + : ((enabled && control.hovered) ? control.Material.primaryTextColor : control.Material.hintTextColor) + } +} diff --git a/src/quickcontrols2/material/ToolBar.qml b/src/quickcontrols2/material/ToolBar.qml new file mode 100644 index 00000000000..a1aa82bda5b --- /dev/null +++ b/src/quickcontrols2/material/ToolBar.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.ToolBar { + id: control + + Material.elevation: 4 + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + Material.foreground: Material.toolTextColor + + spacing: 16 + + background: Rectangle { + implicitHeight: 48 + color: control.Material.toolBarColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + fullWidth: true + } + } +} diff --git a/src/quickcontrols2/material/ToolButton.qml b/src/quickcontrols2/material/ToolButton.qml new file mode 100644 index 00000000000..be7ae332be4 --- /dev/null +++ b/src/quickcontrols2/material/ToolButton.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.ToolButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 24 + icon.height: 24 + icon.color: !enabled ? Material.hintTextColor : checked || highlighted ? Material.accent : Material.foreground + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: !control.enabled ? control.Material.hintTextColor : + control.checked || control.highlighted ? control.Material.accent : control.Material.foreground + } + + background: Ripple { + implicitWidth: control.Material.touchTarget + implicitHeight: control.Material.touchTarget + + readonly property bool square: control.contentItem.width <= control.contentItem.height + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + clip: !square + width: square ? parent.height / 2 : parent.width + height: square ? parent.height / 2 : parent.height + pressed: control.pressed + anchor: control + active: control.enabled && (control.down || control.visualFocus || control.hovered) + color: control.Material.rippleColor + } +} diff --git a/src/quickcontrols2/material/ToolSeparator.qml b/src/quickcontrols2/material/ToolSeparator.qml new file mode 100644 index 00000000000..3d084d2b9b3 --- /dev/null +++ b/src/quickcontrols2/material/ToolSeparator.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material + +T.ToolSeparator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + horizontalPadding: vertical ? 12 : 5 + verticalPadding: vertical ? 5 : 12 + + contentItem: Rectangle { + implicitWidth: control.vertical ? 1 : 38 + implicitHeight: control.vertical ? 38 : 1 + color: control.Material.hintTextColor + } +} diff --git a/src/quickcontrols2/material/ToolTip.qml b/src/quickcontrols2/material/ToolTip.qml new file mode 100644 index 00000000000..033e48a3fae --- /dev/null +++ b/src/quickcontrols2/material/ToolTip.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material + +T.ToolTip { + id: control + + x: parent ? (parent.width - implicitWidth) / 2 : 0 + y: -implicitHeight - 24 + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + margins: 12 + padding: 8 + horizontalPadding: padding + 8 + + closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnReleaseOutsideParent + + Material.theme: Material.Dark + + enter: Transition { + // toast_enter + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; easing.type: Easing.OutQuad; duration: 500 } + } + + exit: Transition { + // toast_exit + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.InQuad; duration: 500 } + } + + contentItem: Text { + text: control.text + font: control.font + wrapMode: Text.Wrap + color: control.Material.foreground + } + + background: Rectangle { + implicitHeight: control.Material.tooltipHeight + color: control.Material.tooltipColor + opacity: 0.9 + radius: 2 + } +} diff --git a/src/quickcontrols2/material/Tumbler.qml b/src/quickcontrols2/material/Tumbler.qml new file mode 100644 index 00000000000..18ae06cb769 --- /dev/null +++ b/src/quickcontrols2/material/Tumbler.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T +import QtQuick.Controls.Material + +T.Tumbler { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + delegate: Text { + text: modelData + color: control.Material.foreground + font: control.font + opacity: (1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2)) * (control.enabled ? 1 : 0.6) + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + required property var modelData + required property int index + } + + contentItem: TumblerView { + implicitWidth: 60 + implicitHeight: 200 + model: control.model + delegate: control.delegate + path: Path { + startX: control.contentItem.width / 2 + startY: -control.contentItem.delegateHeight / 2 + PathLine { + x: control.contentItem.width / 2 + y: (control.visibleItemCount + 1) * control.contentItem.delegateHeight - control.contentItem.delegateHeight / 2 + } + } + + property real delegateHeight: control.availableHeight / control.visibleItemCount + } +} diff --git a/src/quickcontrols2/material/VerticalHeaderView.qml b/src/quickcontrols2/material/VerticalHeaderView.qml new file mode 100644 index 00000000000..9769627ea51 --- /dev/null +++ b/src/quickcontrols2/material/VerticalHeaderView.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +T.VerticalHeaderView { + id: control + + implicitWidth: contentWidth + implicitHeight: syncView ? syncView.height : 0 + + delegate: Rectangle { + // Qt6: add cellPadding (and font etc) as public API in headerview + readonly property real cellPadding: 8 + + implicitWidth: Math.max(control.width, text.implicitWidth + (cellPadding * 2)) + implicitHeight: text.implicitHeight + (cellPadding * 2) + color: control.Material.backgroundColor + + Text { + id: text + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] + : model[control.textRole]) + : modelData + width: parent.width + height: parent.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: enabled ? control.Material.foreground : control.Material.hintTextColor + } + } +} diff --git a/src/quickcontrols2/material/images/arrow-indicator.png b/src/quickcontrols2/material/images/arrow-indicator.png new file mode 100644 index 00000000000..5a9780015bf Binary files /dev/null and b/src/quickcontrols2/material/images/arrow-indicator.png differ diff --git a/src/quickcontrols2/material/images/arrow-indicator.svg b/src/quickcontrols2/material/images/arrow-indicator.svg new file mode 100644 index 00000000000..1e7217c8553 --- /dev/null +++ b/src/quickcontrols2/material/images/arrow-indicator.svg @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="5" + height="10" + viewBox="0 0 5 10" + version="1.1" + id="svg2" + inkscape:version="0.91 r13725" + sodipodi:docname="arrow-indicator.svg"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="2560" + inkscape:window-height="1571" + id="namedview6" + showgrid="false" + inkscape:zoom="27.812867" + inkscape:cx="13.137558" + inkscape:cy="12.83583" + inkscape:window-x="0" + inkscape:window-y="55" + inkscape:window-maximized="1" + inkscape:current-layer="svg2" /> + <path + d="M 0,10 5,5 0,0 Z" + id="path4" + inkscape:connector-curvature="0" + style="fill:#757575" /> +</svg> diff --git a/src/quickcontrols2/material/images/arrow-indicator@2x.png b/src/quickcontrols2/material/images/arrow-indicator@2x.png new file mode 100644 index 00000000000..37ce3a957ea Binary files /dev/null and b/src/quickcontrols2/material/images/arrow-indicator@2x.png differ diff --git a/src/quickcontrols2/material/images/arrow-indicator@3x.png b/src/quickcontrols2/material/images/arrow-indicator@3x.png new file mode 100644 index 00000000000..57abd97295a Binary files /dev/null and b/src/quickcontrols2/material/images/arrow-indicator@3x.png differ diff --git a/src/quickcontrols2/material/images/arrow-indicator@4x.png b/src/quickcontrols2/material/images/arrow-indicator@4x.png new file mode 100644 index 00000000000..26d3d7c1f14 Binary files /dev/null and b/src/quickcontrols2/material/images/arrow-indicator@4x.png differ diff --git a/src/quickcontrols2/material/images/check.png b/src/quickcontrols2/material/images/check.png new file mode 100644 index 00000000000..756a43a579e Binary files /dev/null and b/src/quickcontrols2/material/images/check.png differ diff --git a/src/quickcontrols2/material/images/check@2x.png b/src/quickcontrols2/material/images/check@2x.png new file mode 100644 index 00000000000..9d1d6a32b61 Binary files /dev/null and b/src/quickcontrols2/material/images/check@2x.png differ diff --git a/src/quickcontrols2/material/images/check@3x.png b/src/quickcontrols2/material/images/check@3x.png new file mode 100644 index 00000000000..32ed72f0178 Binary files /dev/null and b/src/quickcontrols2/material/images/check@3x.png differ diff --git a/src/quickcontrols2/material/images/check@4x.png b/src/quickcontrols2/material/images/check@4x.png new file mode 100644 index 00000000000..1767cee6170 Binary files /dev/null and b/src/quickcontrols2/material/images/check@4x.png differ diff --git a/src/quickcontrols2/material/images/drop-indicator.png b/src/quickcontrols2/material/images/drop-indicator.png new file mode 100644 index 00000000000..93560f507a1 Binary files /dev/null and b/src/quickcontrols2/material/images/drop-indicator.png differ diff --git a/src/quickcontrols2/material/images/drop-indicator.svg b/src/quickcontrols2/material/images/drop-indicator.svg new file mode 100644 index 00000000000..94b5ca15148 --- /dev/null +++ b/src/quickcontrols2/material/images/drop-indicator.svg @@ -0,0 +1,5 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" version="1.1"> + <path d="M7,10l5,5,5-5z" fill="#757575"/> +</svg> diff --git a/src/quickcontrols2/material/images/drop-indicator@2x.png b/src/quickcontrols2/material/images/drop-indicator@2x.png new file mode 100644 index 00000000000..d32f81604c0 Binary files /dev/null and b/src/quickcontrols2/material/images/drop-indicator@2x.png differ diff --git a/src/quickcontrols2/material/images/drop-indicator@3x.png b/src/quickcontrols2/material/images/drop-indicator@3x.png new file mode 100644 index 00000000000..34c3e7d115d Binary files /dev/null and b/src/quickcontrols2/material/images/drop-indicator@3x.png differ diff --git a/src/quickcontrols2/material/images/drop-indicator@4x.png b/src/quickcontrols2/material/images/drop-indicator@4x.png new file mode 100644 index 00000000000..0613f6dd0d2 Binary files /dev/null and b/src/quickcontrols2/material/images/drop-indicator@4x.png differ diff --git a/src/quickcontrols2/material/impl/BoxShadow.qml b/src/quickcontrols2/material/impl/BoxShadow.qml new file mode 100644 index 00000000000..52894527808 --- /dev/null +++ b/src/quickcontrols2/material/impl/BoxShadow.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +/* + A implementation of CSS's box-shadow, used by ElevationEffect for a Material Design + elevation shadow effect. + */ +RectangularGlow { + // The 4 properties from CSS box-shadow, plus the inherited color property + property int offsetX + property int offsetY + property int blurRadius + property int spreadRadius + + // The source item the shadow is being applied to, used for correctly + // calculating the corner radious + property Item source + + property bool fullWidth + property bool fullHeight + + x: (parent.width - width)/2 + offsetX + y: (parent.height - height)/2 + offsetY + + implicitWidth: source ? source.width : parent.width + implicitHeight: source ? source.height : parent.height + + width: implicitWidth + 2 * spreadRadius + (fullWidth ? 2 * cornerRadius : 0) + height: implicitHeight + 2 * spreadRadius + (fullHeight ? 2 * cornerRadius : 0) + glowRadius: blurRadius/2 + spread: 0.05 + // qmllint disable unqualified + // Intentionally duck-typed (QTBUG-94807) + cornerRadius: blurRadius + (source && source.radius || 0) +} diff --git a/src/quickcontrols2/material/impl/CMakeLists.txt b/src/quickcontrols2/material/impl/CMakeLists.txt new file mode 100644 index 00000000000..16243e30366 --- /dev/null +++ b/src/quickcontrols2/material/impl/CMakeLists.txt @@ -0,0 +1,41 @@ +##################################################################### +## qtquickcontrols2materialstyleimplplugin Plugin: +##################################################################### + +set(qml_files + "BoxShadow.qml" + "CheckIndicator.qml" + "CursorDelegate.qml" + "ElevationEffect.qml" + "RadioIndicator.qml" + "RectangularGlow.qml" + "SliderHandle.qml" + "SwitchIndicator.qml" +) + +qt_internal_add_qml_module(qtquickcontrols2materialstyleimplplugin + URI "QtQuick.Controls.Material.impl" + VERSION "${PROJECT_VERSION}" + PAST_MAJOR_VERSIONS 2 + CLASS_NAME QtQuickControls2MaterialStyleImplPlugin + DEPENDENCIES + QtQuick/auto + PLUGIN_TARGET qtquickcontrols2materialstyleimplplugin + NO_PLUGIN_OPTIONAL + SOURCES + qquickmaterialbusyindicator.cpp qquickmaterialbusyindicator_p.h + qquickmaterialprogressbar.cpp qquickmaterialprogressbar_p.h + qquickmaterialripple.cpp qquickmaterialripple_p.h + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::QmlPrivate + Qt::QuickControls2ImplPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private +) diff --git a/src/quickcontrols2/material/impl/CheckIndicator.qml b/src/quickcontrols2/material/impl/CheckIndicator.qml new file mode 100644 index 00000000000..b6593fab8ae --- /dev/null +++ b/src/quickcontrols2/material/impl/CheckIndicator.qml @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +Rectangle { + id: indicatorItem + implicitWidth: 18 + implicitHeight: 18 + color: "transparent" + border.color: !control.enabled ? control.Material.hintTextColor + : checkState !== Qt.Unchecked ? control.Material.accentColor : control.Material.secondaryTextColor + border.width: checkState !== Qt.Unchecked ? width / 2 : 2 + radius: 2 + + property Item control + property int checkState: control.checkState + + Behavior on border.width { + NumberAnimation { + duration: 100 + easing.type: Easing.OutCubic + } + } + + Behavior on border.color { + ColorAnimation { + duration: 100 + easing.type: Easing.OutCubic + } + } + + // TODO: This needs to be transparent + Image { + id: checkImage + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 14 + height: 14 + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Material/images/check.png" + fillMode: Image.PreserveAspectFit + + scale: indicatorItem.checkState === Qt.Checked ? 1 : 0 + Behavior on scale { NumberAnimation { duration: 100 } } + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 12 + height: 3 + + scale: indicatorItem.checkState === Qt.PartiallyChecked ? 1 : 0 + Behavior on scale { NumberAnimation { duration: 100 } } + } + + states: [ + State { + name: "checked" + when: indicatorItem.checkState === Qt.Checked + }, + State { + name: "partiallychecked" + when: indicatorItem.checkState === Qt.PartiallyChecked + } + ] + + transitions: Transition { + SequentialAnimation { + NumberAnimation { + target: indicatorItem + property: "scale" + // Go down 2 pixels in size. + to: 1 - 2 / indicatorItem.width + duration: 120 + } + NumberAnimation { + target: indicatorItem + property: "scale" + to: 1 + duration: 120 + } + } + } +} diff --git a/src/quickcontrols2/material/impl/CursorDelegate.qml b/src/quickcontrols2/material/impl/CursorDelegate.qml new file mode 100644 index 00000000000..a913ab849d4 --- /dev/null +++ b/src/quickcontrols2/material/impl/CursorDelegate.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.Material + +Rectangle { + id: cursor + + color: parent.Material.accentColor + width: 2 + visible: parent.activeFocus && !parent.readOnly && parent.selectionStart === parent.selectionEnd + + Connections { + target: cursor.parent + function onCursorPositionChanged() { + // keep a moving cursor visible + cursor.opacity = 1 + timer.restart() + } + } + + Timer { + id: timer + running: cursor.parent.activeFocus && !cursor.parent.readOnly && interval != 0 + repeat: true + interval: Qt.styleHints.cursorFlashTime / 2 + onTriggered: cursor.opacity = !cursor.opacity ? 1 : 0 + // force the cursor visible when gaining focus + onRunningChanged: cursor.opacity = 1 + } +} diff --git a/src/quickcontrols2/material/impl/ElevationEffect.qml b/src/quickcontrols2/material/impl/ElevationEffect.qml new file mode 100644 index 00000000000..8a4e98e3205 --- /dev/null +++ b/src/quickcontrols2/material/impl/ElevationEffect.qml @@ -0,0 +1,279 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +/* + An effect for standard Material Design elevation shadows. Useful for using as \c layer.effect. + */ +Item { + id: effect + + /* + The source the effect is applied to. + */ + property var source + + /* + The elevation of the \l source Item. + */ + property int elevation: 0 + + /* + Set to \c true if the \l source Item is the same width as its parent and the shadow + should be full width instead of rounding around the corner of the Item. + + \sa fullHeight + */ + property bool fullWidth: false + + /* + Set to \c true if the \l source Item is the same height as its parent and the shadow + should be full height instead of rounding around the corner of the Item. + + \sa fullWidth + */ + property bool fullHeight: false + + /* + \internal + + The actual source Item the effect is applied to. + */ + readonly property Item sourceItem: source.sourceItem + + /* + * The following shadow values are taken from Angular Material + * + * The MIT License (MIT) + * + * Copyright (c) 2014-2016 Google, Inc. http://angularjs.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /* + \internal + + The shadows to use for each possible elevation. There are three shadows that when combined + make up the elevation. + */ + readonly property var _shadows: [ + [{offset: 0, blur: 0, spread: 0}, + {offset: 0, blur: 0, spread: 0}, + {offset: 0, blur: 0, spread: 0}], + + [{offset: 1, blur: 3, spread: 0}, + {offset: 1, blur: 1, spread: 0}, + {offset: 2, blur: 1, spread: -1}], + + [{offset: 1, blur: 5, spread: 0}, + {offset: 2, blur: 2, spread: 0}, + {offset: 3, blur: 1, spread: -2}], + + [{offset: 1, blur: 8, spread: 0}, + {offset: 3, blur: 4, spread: 0}, + {offset: 3, blur: 3, spread: -2}], + + [{offset: 2, blur: 4, spread: -1}, + {offset: 4, blur: 5, spread: 0}, + {offset: 1, blur: 10, spread: 0}], + + [{offset: 3, blur: 5, spread: -1}, + {offset: 5, blur: 8, spread: 0}, + {offset: 1, blur: 14, spread: 0}], + + [{offset: 3, blur: 5, spread: -1}, + {offset: 6, blur: 10, spread: 0}, + {offset: 1, blur: 18, spread: 0}], + + [{offset: 4, blur: 5, spread: -2}, + {offset: 7, blur: 10, spread: 1}, + {offset: 2, blur: 16, spread: 1}], + + [{offset: 5, blur: 5, spread: -3}, + {offset: 8, blur: 10, spread: 1}, + {offset: 3, blur: 14, spread: 2}], + + [{offset: 5, blur: 6, spread: -3}, + {offset: 9, blur: 12, spread: 1}, + {offset: 3, blur: 16, spread: 2}], + + [{offset: 6, blur: 6, spread: -3}, + {offset: 10, blur: 14, spread: 1}, + {offset: 4, blur: 18, spread: 3}], + + [{offset: 6, blur: 7, spread: -4}, + {offset: 11, blur: 15, spread: 1}, + {offset: 4, blur: 20, spread: 3}], + + [{offset: 7, blur: 8, spread: -4}, + {offset: 12, blur: 17, spread: 2}, + {offset: 5, blur: 22, spread: 4}], + + [{offset: 7, blur: 8, spread: -4}, + {offset: 13, blur: 19, spread: 2}, + {offset: 5, blur: 24, spread: 4}], + + [{offset: 7, blur: 9, spread: -4}, + {offset: 14, blur: 21, spread: 2}, + {offset: 5, blur: 26, spread: 4}], + + [{offset: 8, blur: 9, spread: -5}, + {offset: 15, blur: 22, spread: 2}, + {offset: 6, blur: 28, spread: 5}], + + [{offset: 8, blur: 10, spread: -5}, + {offset: 16, blur: 24, spread: 2}, + {offset: 6, blur: 30, spread: 5}], + + [{offset: 8, blur: 11, spread: -5}, + {offset: 17, blur: 26, spread: 2}, + {offset: 6, blur: 32, spread: 5}], + + [{offset: 9, blur: 11, spread: -5}, + {offset: 18, blur: 28, spread: 2}, + {offset: 7, blur: 34, spread: 6}], + + [{offset: 9, blur: 12, spread: -6}, + {offset: 19, blur: 29, spread: 2}, + {offset: 7, blur: 36, spread: 6}], + + [{offset: 10, blur: 13, spread: -6}, + {offset: 20, blur: 31, spread: 3}, + {offset: 8, blur: 38, spread: 7}], + + [{offset: 10, blur: 13, spread: -6}, + {offset: 21, blur: 33, spread: 3}, + {offset: 8, blur: 40, spread: 7}], + + [{offset: 10, blur: 14, spread: -6}, + {offset: 22, blur: 35, spread: 3}, + {offset: 8, blur: 42, spread: 7}], + + [{offset: 11, blur: 14, spread: -7}, + {offset: 23, blur: 36, spread: 3}, + {offset: 9, blur: 44, spread: 8}], + + [{offset: 11, blur: 15, spread: -7}, + {offset: 24, blur: 38, spread: 3}, + {offset: 9, blur: 46, spread: 8}] + ] + + /* + \internal + + The current shadow based on the elevation. + */ + readonly property var _shadow: _shadows[Math.max(0, Math.min(elevation, _shadows.length - 1))] + + // Nest the shadows and source view in two items rendered as a layer + // so the shadow is not clipped by the bounds of the source view + Item { + property int margin: -100 + + x: margin + y: margin + width: parent.width - 2 * margin + height: parent.height - 2 * margin + + // By rendering as a layer, the shadow will never show through the source item, + // even when the source item's opacity is less than 1 + layer.enabled: true + + // The box shadows automatically pick up the size of the source Item and not + // the size of the parent, so we don't need to worry about the extra padding + // in the parent Item + BoxShadow { + offsetY: effect._shadow[0].offset + blurRadius: effect._shadow[0].blur + spreadRadius: effect._shadow[0].spread + color: Qt.rgba(0,0,0, 0.2) + + fullWidth: effect.fullWidth + fullHeight: effect.fullHeight + source: effect.sourceItem + } + + BoxShadow { + offsetY: effect._shadow[1].offset + blurRadius: effect._shadow[1].blur + spreadRadius: effect._shadow[1].spread + color: Qt.rgba(0,0,0, 0.14) + + fullWidth: effect.fullWidth + fullHeight: effect.fullHeight + source: effect.sourceItem + } + + BoxShadow { + offsetY: effect._shadow[2].offset + blurRadius: effect._shadow[2].blur + spreadRadius: effect._shadow[2].spread + color: Qt.rgba(0,0,0, 0.12) + + fullWidth: effect.fullWidth + fullHeight: effect.fullHeight + source: effect.sourceItem + } + + ShaderEffect { + property alias source: effect.source + + x: (parent.width - width)/2 + y: (parent.height - height)/2 + width: effect.sourceItem.width + height: effect.sourceItem.height + } + } +} diff --git a/src/quickcontrols2/material/impl/RadioIndicator.qml b/src/quickcontrols2/material/impl/RadioIndicator.qml new file mode 100644 index 00000000000..ca14501c557 --- /dev/null +++ b/src/quickcontrols2/material/impl/RadioIndicator.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +Rectangle { + id: indicator + implicitWidth: 20 + implicitHeight: 20 + radius: width / 2 + border.width: 2 + border.color: !control.enabled ? control.Material.hintTextColor + : control.checked || control.down ? control.Material.accentColor : control.Material.secondaryTextColor + color: "transparent" + + property T.AbstractButton control + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 10 + height: 10 + radius: width / 2 + color: parent.border.color + visible: indicator.control.checked || indicator.control.down + } +} diff --git a/src/quickcontrols2/material/impl/RectangularGlow.qml b/src/quickcontrols2/material/impl/RectangularGlow.qml new file mode 100644 index 00000000000..b2337afc0b5 --- /dev/null +++ b/src/quickcontrols2/material/impl/RectangularGlow.qml @@ -0,0 +1,240 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +/* + A cross-graphics API implementation of QtGraphicalEffects' RectangularGlow. + */ +Item { + id: rootItem + + /* + This property defines how many pixels outside the item area are reached + by the glow. + + The value ranges from 0.0 (no glow) to inf (infinite glow). By default, + the property is set to \c 0.0. + + \table + \header + \li Output examples with different glowRadius values + \li + \li + \row + \li \image RectangularGlow_glowRadius1.png + \li \image RectangularGlow_glowRadius2.png + \li \image RectangularGlow_glowRadius3.png + \row + \li \b { glowRadius: 10 } + \li \b { glowRadius: 20 } + \li \b { glowRadius: 40 } + \row + \li \l spread: 0 + \li \l spread: 0 + \li \l spread: 0 + \row + \li \l color: #ffffff + \li \l color: #ffffff + \li \l color: #ffffff + \row + \li \l cornerRadius: 25 + \li \l cornerRadius: 25 + \li \l cornerRadius: 25 + \endtable + + */ + property real glowRadius: 0.0 + + /* + This property defines how large part of the glow color is strenghtened + near the source edges. + + The value ranges from 0.0 (no strenght increase) to 1.0 (maximum + strenght increase). By default, the property is set to \c 0.0. + + \table + \header + \li Output examples with different spread values + \li + \li + \row + \li \image RectangularGlow_spread1.png + \li \image RectangularGlow_spread2.png + \li \image RectangularGlow_spread3.png + \row + \li \b { spread: 0.0 } + \li \b { spread: 0.5 } + \li \b { spread: 1.0 } + \row + \li \l glowRadius: 20 + \li \l glowRadius: 20 + \li \l glowRadius: 20 + \row + \li \l color: #ffffff + \li \l color: #ffffff + \li \l color: #ffffff + \row + \li \l cornerRadius: 25 + \li \l cornerRadius: 25 + \li \l cornerRadius: 25 + \endtable + */ + property real spread: 0.0 + + /* + This property defines the RGBA color value which is used for the glow. + + By default, the property is set to \c "white". + + \table + \header + \li Output examples with different color values + \li + \li + \row + \li \image RectangularGlow_color1.png + \li \image RectangularGlow_color2.png + \li \image RectangularGlow_color3.png + \row + \li \b { color: #ffffff } + \li \b { color: #55ff55 } + \li \b { color: #5555ff } + \row + \li \l glowRadius: 20 + \li \l glowRadius: 20 + \li \l glowRadius: 20 + \row + \li \l spread: 0 + \li \l spread: 0 + \li \l spread: 0 + \row + \li \l cornerRadius: 25 + \li \l cornerRadius: 25 + \li \l cornerRadius: 25 + \endtable + */ + property color color: "white" + + /* + This property defines the corner radius that is used to draw a glow with + rounded corners. + + The value ranges from 0.0 to half of the effective width or height of + the glow, whichever is smaller. This can be calculated with: \c{ + min(width, height) / 2.0 + glowRadius} + + By default, the property is bound to glowRadius property. The glow + behaves as if the rectangle was blurred when adjusting the glowRadius + property. + + \table + \header + \li Output examples with different cornerRadius values + \li + \li + \row + \li \image RectangularGlow_cornerRadius1.png + \li \image RectangularGlow_cornerRadius2.png + \li \image RectangularGlow_cornerRadius3.png + \row + \li \b { cornerRadius: 0 } + \li \b { cornerRadius: 25 } + \li \b { cornerRadius: 50 } + \row + \li \l glowRadius: 20 + \li \l glowRadius: 20 + \li \l glowRadius: 20 + \row + \li \l spread: 0 + \li \l spread: 0 + \li \l spread: 0 + \row + \li \l color: #ffffff + \li \l color: #ffffff + \li \l color: #ffffff + \endtable + */ + property real cornerRadius: glowRadius + + /* + This property allows the effect output pixels to be cached in order to + improve the rendering performance. + + Every time the source or effect properties are changed, the pixels in + the cache must be updated. Memory consumption is increased, because an + extra buffer of memory is required for storing the effect output. + + It is recommended to disable the cache when the source or the effect + properties are animated. + + By default, the property is set to \c false. + */ + property bool cached: false + + ShaderEffectSource { + id: cacheItem + anchors.fill: shaderItem + visible: rootItem.cached + smooth: true + sourceItem: shaderItem + live: true + hideSource: visible + } + + ShaderEffect { + id: shaderItem + + x: (parent.width - width) / 2.0 + y: (parent.height - height) / 2.0 + width: parent.width + rootItem.glowRadius * 2 + cornerRadius * 2 + height: parent.height + rootItem.glowRadius * 2 + cornerRadius * 2 + + function clampedCornerRadius() { + var maxCornerRadius = Math.min(rootItem.width, rootItem.height) / 2 + rootItem.glowRadius; + return Math.max(0, Math.min(rootItem.cornerRadius, maxCornerRadius)) + } + + property color color: rootItem.color + property real inverseSpread: 1.0 - rootItem.spread + property real relativeSizeX: ((inverseSpread * inverseSpread) * rootItem.glowRadius + cornerRadius * 2.0) / width + property real relativeSizeY: relativeSizeX * (width / height) + property real spread: rootItem.spread / 2.0 + property real cornerRadius: clampedCornerRadius() + + fragmentShader: "qrc:/qt-project.org/imports/QtQuick/Controls/Material/shaders/RectangularGlow.frag" + } +} diff --git a/src/quickcontrols2/material/impl/SliderHandle.qml b/src/quickcontrols2/material/impl/SliderHandle.qml new file mode 100644 index 00000000000..ad22c4d9168 --- /dev/null +++ b/src/quickcontrols2/material/impl/SliderHandle.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +Item { + id: root + implicitWidth: initialSize + implicitHeight: initialSize + + property real value: 0 + property bool handleHasFocus: false + property bool handlePressed: false + property bool handleHovered: false + readonly property int initialSize: 13 + readonly property var control: parent + + Rectangle { + id: handleRect + width: parent.width + height: parent.height + radius: width / 2 + scale: root.handlePressed ? 1.5 : 1 + color: root.control.enabled ? root.control.Material.accentColor : root.control.Material.sliderDisabledColor + + Behavior on scale { + NumberAnimation { + duration: 250 + } + } + } + + Ripple { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 22; height: 22 + pressed: root.handlePressed + active: root.handlePressed || root.handleHasFocus || (enabled && root.handleHovered) + color: root.control.Material.highlightedRippleColor + } +} diff --git a/src/quickcontrols2/material/impl/SwitchIndicator.qml b/src/quickcontrols2/material/impl/SwitchIndicator.qml new file mode 100644 index 00000000000..9d29d0658bd --- /dev/null +++ b/src/quickcontrols2/material/impl/SwitchIndicator.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl + +Item { + id: indicator + implicitWidth: 38 + implicitHeight: 32 + + property T.AbstractButton control + property alias handle: handle + + Material.elevation: 1 + + Rectangle { + width: parent.width + height: 14 + radius: height / 2 + y: parent.height / 2 - height / 2 + color: indicator.control.enabled ? (indicator.control.checked ? indicator.control.Material.switchCheckedTrackColor : indicator.control.Material.switchUncheckedTrackColor) + : indicator.control.Material.switchDisabledTrackColor + } + + Rectangle { + id: handle + x: Math.max(0, Math.min(parent.width - width, indicator.control.visualPosition * parent.width - (width / 2))) + y: (parent.height - height) / 2 + width: 20 + height: 20 + radius: width / 2 + color: indicator.control.enabled ? (indicator.control.checked ? indicator.control.Material.switchCheckedHandleColor : indicator.control.Material.switchUncheckedHandleColor) + : indicator.control.Material.switchDisabledHandleColor + + Behavior on x { + enabled: !indicator.control.pressed + SmoothedAnimation { + duration: 300 + } + } + layer.enabled: indicator.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: indicator.Material.elevation + } + } +} diff --git a/src/quickcontrols2/material/impl/qquickmaterialbusyindicator.cpp b/src/quickcontrols2/material/impl/qquickmaterialbusyindicator.cpp new file mode 100644 index 00000000000..420927c6903 --- /dev/null +++ b/src/quickcontrols2/material/impl/qquickmaterialbusyindicator.cpp @@ -0,0 +1,247 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmaterialbusyindicator_p.h" + +#include <QtCore/qmath.h> +#include <QtCore/qeasingcurve.h> +#include <QtGui/qpainter.h> +#include <QtQuick/qsgimagenode.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuickControls2Impl/private/qquickanimatednode_p.h> + +QT_BEGIN_NAMESPACE + +/* + Relevant Android code: + + - core/res/res/anim/progress_indeterminate_rotation_material.xml contains + the rotation animation data. + - core/res/res/anim/progress_indeterminate_material.xml contains the trim + animation data. + - core/res/res/interpolator/trim_start_interpolator.xml and + core/res/res/interpolator/trim_end_interpolator.xml contain the start + and end trim path interpolators. + - addCommand() in core/java/android/util/PathParser.java has a list of the + different path commands available. +*/ + +static const int SpanAnimationDuration = 700; +static const int RotationAnimationDuration = SpanAnimationDuration * 6; +static const int TargetRotation = 720; +static const int OneDegree = 16; +static const qreal MinSweepSpan = 10 * OneDegree; +static const qreal MaxSweepSpan = 300 * OneDegree; + +class QQuickMaterialBusyIndicatorNode : public QQuickAnimatedNode +{ +public: + QQuickMaterialBusyIndicatorNode(QQuickMaterialBusyIndicator *item); + + void sync(QQuickItem *item) override; + +protected: + void updateCurrentTime(int time) override; + +private: + int m_lastStartAngle = 0; + int m_lastEndAngle = 0; + qreal m_width = 0; + qreal m_height = 0; + qreal m_devicePixelRatio = 1; + QColor m_color; +}; + +QQuickMaterialBusyIndicatorNode::QQuickMaterialBusyIndicatorNode(QQuickMaterialBusyIndicator *item) + : QQuickAnimatedNode(item) +{ + setLoopCount(Infinite); + setCurrentTime(item->elapsed()); + setDuration(RotationAnimationDuration); + + QSGImageNode *textureNode = item->window()->createImageNode(); + textureNode->setOwnsTexture(true); + appendChildNode(textureNode); + + // A texture seems to be required here, but we don't have one yet, as we haven't drawn anything, + // so just use a blank image. + QImage blankImage(item->width(), item->height(), QImage::Format_ARGB32_Premultiplied); + blankImage.fill(Qt::transparent); + textureNode->setTexture(item->window()->createTextureFromImage(blankImage)); +} + +void QQuickMaterialBusyIndicatorNode::updateCurrentTime(int time) +{ + const qreal w = m_width; + const qreal h = m_height; + const qreal size = qMin(w, h); + const qreal dx = (w - size) / 2; + const qreal dy = (h - size) / 2; + + QImage image(size * m_devicePixelRatio, size * m_devicePixelRatio, QImage::Format_ARGB32_Premultiplied); + image.fill(Qt::transparent); + + QPainter painter(&image); + painter.setRenderHint(QPainter::Antialiasing); + + QPen pen; + QSGImageNode *textureNode = static_cast<QSGImageNode *>(firstChild()); + pen.setColor(m_color); + pen.setWidth(qCeil(size / 12) * m_devicePixelRatio); + painter.setPen(pen); + + const qreal percentageComplete = time / qreal(RotationAnimationDuration); + const qreal spanPercentageComplete = (time % SpanAnimationDuration) / qreal(SpanAnimationDuration); + const int iteration = time / SpanAnimationDuration; + int startAngle = 0; + int endAngle = 0; + + if (iteration % 2 == 0) { + if (m_lastStartAngle > 360 * OneDegree) + m_lastStartAngle -= 360 * OneDegree; + + // The start angle is only affected by the rotation animation for the "grow" phase. + startAngle = m_lastStartAngle; + QEasingCurve angleCurve(QEasingCurve::OutQuad); + const qreal percentage = angleCurve.valueForProgress(spanPercentageComplete); + endAngle = m_lastStartAngle + MinSweepSpan + percentage * (MaxSweepSpan - MinSweepSpan); + m_lastEndAngle = endAngle; + } else { + // Both the start angle *and* the span are affected by the "shrink" phase. + QEasingCurve angleCurve(QEasingCurve::InQuad); + const qreal percentage = angleCurve.valueForProgress(spanPercentageComplete); + startAngle = m_lastEndAngle - MaxSweepSpan + percentage * (MaxSweepSpan - MinSweepSpan); + endAngle = m_lastEndAngle; + m_lastStartAngle = startAngle; + } + + const int halfPen = pen.width() / 2; + const QRectF arcBounds = QRectF(halfPen, halfPen, + m_devicePixelRatio * size - pen.width(), + m_devicePixelRatio * size - pen.width()); + // The current angle of the rotation animation. + const qreal rotation = OneDegree * percentageComplete * -TargetRotation; + startAngle -= rotation; + endAngle -= rotation; + const int angleSpan = endAngle - startAngle; + painter.drawArc(arcBounds, -startAngle, -angleSpan); + painter.end(); + + textureNode->setRect(QRectF(dx, dy, size, size)); + textureNode->setTexture(window()->createTextureFromImage(image)); +} + +void QQuickMaterialBusyIndicatorNode::sync(QQuickItem *item) +{ + QQuickMaterialBusyIndicator *indicator = static_cast<QQuickMaterialBusyIndicator *>(item); + m_color = indicator->color(); + m_width = indicator->width(); + m_height = indicator->height(); + m_devicePixelRatio = indicator->window()->effectiveDevicePixelRatio(); +} + +QQuickMaterialBusyIndicator::QQuickMaterialBusyIndicator(QQuickItem *parent) : + QQuickItem(parent) +{ + setFlag(ItemHasContents); +} + +QColor QQuickMaterialBusyIndicator::color() const +{ + return m_color; +} + +void QQuickMaterialBusyIndicator::setColor(const QColor &color) +{ + if (m_color == color) + return; + + m_color = color; + update(); +} + +bool QQuickMaterialBusyIndicator::isRunning() const +{ + return isVisible(); +} + +void QQuickMaterialBusyIndicator::setRunning(bool running) +{ + if (running) + setVisible(true); +} + +int QQuickMaterialBusyIndicator::elapsed() const +{ + return m_elapsed; +} + +void QQuickMaterialBusyIndicator::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + switch (change) { + case ItemOpacityHasChanged: + if (qFuzzyIsNull(data.realValue)) + setVisible(false); + break; + case ItemVisibleHasChanged: + update(); + break; + default: + break; + } +} + +QSGNode *QQuickMaterialBusyIndicator::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + QQuickMaterialBusyIndicatorNode *node = static_cast<QQuickMaterialBusyIndicatorNode *>(oldNode); + if (isRunning() && width() > 0 && height() > 0) { + if (!node) { + node = new QQuickMaterialBusyIndicatorNode(this); + node->start(); + } + node->sync(this); + } else { + m_elapsed = node ? node->currentTime() : 0; + delete node; + node = nullptr; + } + return node; +} + +QT_END_NAMESPACE + +#include "moc_qquickmaterialbusyindicator_p.cpp" diff --git a/src/quickcontrols2/material/impl/qquickmaterialbusyindicator_p.h b/src/quickcontrols2/material/impl/qquickmaterialbusyindicator_p.h new file mode 100644 index 00000000000..72aeaf66f13 --- /dev/null +++ b/src/quickcontrols2/material/impl/qquickmaterialbusyindicator_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMATERIALBUSYINDICATOR_P_H +#define QQUICKMATERIALBUSYINDICATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qcolor.h> +#include <QtQuick/qquickitem.h> + +QT_BEGIN_NAMESPACE + +class QQuickMaterialBusyIndicator : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + Q_PROPERTY(bool running READ isRunning WRITE setRunning FINAL) + QML_NAMED_ELEMENT(BusyIndicatorImpl) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickMaterialBusyIndicator(QQuickItem *parent = nullptr); + + QColor color() const; + void setColor(const QColor &color); + + bool isRunning() const; + void setRunning(bool running); + + int elapsed() const; + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override; + +private: + int m_elapsed = 0; + QColor m_color = Qt::black; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickMaterialBusyIndicator) + +#endif // QQUICKMATERIALBUSYINDICATOR_P_H diff --git a/src/quickcontrols2/material/impl/qquickmaterialprogressbar.cpp b/src/quickcontrols2/material/impl/qquickmaterialprogressbar.cpp new file mode 100644 index 00000000000..ae520360614 --- /dev/null +++ b/src/quickcontrols2/material/impl/qquickmaterialprogressbar.cpp @@ -0,0 +1,247 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmaterialprogressbar_p.h" + +#include <QtCore/qmath.h> +#include <QtCore/qeasingcurve.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> +#include <QtQuick/qsgrectanglenode.h> +#include <QtQuick/qsgimagenode.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuickControls2Impl/private/qquickanimatednode_p.h> + +QT_BEGIN_NAMESPACE + +static const int PauseDuration = 520; +static const int SlideDuration = 1240; +static const int TotalDuration = SlideDuration + PauseDuration; + +class QQuickMaterialProgressBarNode : public QQuickAnimatedNode +{ +public: + QQuickMaterialProgressBarNode(QQuickMaterialProgressBar *item); + + void updateCurrentTime(int time) override; + void sync(QQuickItem *item) override; + +private: + void moveNode(QSGTransformNode *node, const QRectF &geometry, qreal progress); + + bool m_indeterminate = false; + QEasingCurve m_easing = QEasingCurve::OutCubic; +}; + +QQuickMaterialProgressBarNode::QQuickMaterialProgressBarNode(QQuickMaterialProgressBar *item) + : QQuickAnimatedNode(item) +{ + setLoopCount(Infinite); + setDuration(TotalDuration); +} + +void QQuickMaterialProgressBarNode::updateCurrentTime(int time) +{ + QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild()); + Q_ASSERT(geometryNode->type() == QSGNode::GeometryNodeType); + const QRectF geometry = geometryNode->rect(); + + QSGTransformNode *firstNode = static_cast<QSGTransformNode *>(geometryNode->firstChild()); + if (firstNode) { + Q_ASSERT(firstNode->type() == QSGNode::TransformNodeType); + + const qreal progress = qMin<qreal>(1.0, static_cast<qreal>(time) / SlideDuration); + moveNode(static_cast<QSGTransformNode *>(firstNode), geometry, progress); + } + + QSGTransformNode *secondNode = static_cast<QSGTransformNode *>(geometryNode->lastChild()); + if (secondNode) { + Q_ASSERT(secondNode->type() == QSGNode::TransformNodeType); + + const qreal progress = qMax<qreal>(0.0, static_cast<qreal>(time - PauseDuration) / SlideDuration); + moveNode(static_cast<QSGTransformNode *>(secondNode), geometry, progress); + } +} + +void QQuickMaterialProgressBarNode::sync(QQuickItem *item) +{ + QQuickMaterialProgressBar *bar = static_cast<QQuickMaterialProgressBar *>(item); + if (m_indeterminate != bar->isIndeterminate()) { + m_indeterminate = bar->isIndeterminate(); + if (m_indeterminate) + start(); + else + stop(); + } + + QQuickItemPrivate *d = QQuickItemPrivate::get(item); + + QRectF bounds = item->boundingRect(); + bounds.setHeight(item->implicitHeight()); + bounds.moveTop((item->height() - bounds.height()) / 2.0); + + QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild()); + if (!geometryNode) { + geometryNode = item->window()->createRectangleNode(); + geometryNode->setColor(Qt::transparent); + appendChildNode(geometryNode); + } + geometryNode->setRect(bounds); + + const int count = m_indeterminate ? 2 : 1; + const qreal w = m_indeterminate ? 0 : bar->progress() * item->width(); + const QRectF rect(0, bounds.y(), w, bounds.height()); + + QSGNode *transformNode = geometryNode->firstChild(); + for (int i = 0; i < count; ++i) { + if (!transformNode) { + transformNode = new QSGTransformNode; + geometryNode->appendChildNode(transformNode); + + QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode(); + rectNode->setAntialiasing(true); + transformNode->appendChildNode(rectNode); + } + Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType); + static_cast<QSGTransformNode *>(transformNode)->setMatrix(QMatrix4x4()); + + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild()); + Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); + + rectNode->setRect(rect); + rectNode->setColor(bar->color()); + rectNode->update(); + + transformNode = transformNode->nextSibling(); + } + + while (transformNode) { + QSGNode *nextSibling = transformNode->nextSibling(); + delete transformNode; + transformNode = nextSibling; + } +} + +void QQuickMaterialProgressBarNode::moveNode(QSGTransformNode *transformNode, const QRectF &geometry, qreal progress) +{ + const qreal value = m_easing.valueForProgress(progress); + const qreal x = value * geometry.width(); + + QMatrix4x4 matrix; + matrix.translate(x, 0); + transformNode->setMatrix(matrix); + + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild()); + Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); + + QRectF r = geometry; + r.setWidth(value * (geometry.width() - x)); + rectNode->setRect(r); + rectNode->update(); +} + +QQuickMaterialProgressBar::QQuickMaterialProgressBar(QQuickItem *parent) + : QQuickItem(parent) +{ + setFlag(ItemHasContents); +} + +QColor QQuickMaterialProgressBar::color() const +{ + return m_color; +} + +void QQuickMaterialProgressBar::setColor(const QColor &color) +{ + if (color == m_color) + return; + + m_color = color; + update(); +} + +qreal QQuickMaterialProgressBar::progress() const +{ + return m_progress; +} + +void QQuickMaterialProgressBar::setProgress(qreal progress) +{ + if (progress == m_progress) + return; + + m_progress = progress; + update(); +} + +bool QQuickMaterialProgressBar::isIndeterminate() const +{ + return m_indeterminate; +} + +void QQuickMaterialProgressBar::setIndeterminate(bool indeterminate) +{ + if (indeterminate == m_indeterminate) + return; + + m_indeterminate = indeterminate; + update(); +} + +void QQuickMaterialProgressBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + if (change == ItemVisibleHasChanged) + update(); +} + +QSGNode *QQuickMaterialProgressBar::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) +{ + QQuickMaterialProgressBarNode *node = static_cast<QQuickMaterialProgressBarNode *>(oldNode); + if (isVisible() && width() > 0 && height() > 0) { + if (!node) + node = new QQuickMaterialProgressBarNode(this); + node->sync(this); + } else { + delete node; + node = nullptr; + } + return node; +} + +QT_END_NAMESPACE + +#include "moc_qquickmaterialprogressbar_p.cpp" diff --git a/src/quickcontrols2/material/impl/qquickmaterialprogressbar_p.h b/src/quickcontrols2/material/impl/qquickmaterialprogressbar_p.h new file mode 100644 index 00000000000..bf93812d083 --- /dev/null +++ b/src/quickcontrols2/material/impl/qquickmaterialprogressbar_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMATERIALPROGRESSBAR_P_H +#define QQUICKMATERIALPROGRESSBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qcolor.h> +#include <QtQuick/qquickitem.h> + +QT_BEGIN_NAMESPACE + +class QQuickMaterialProgressBar : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + Q_PROPERTY(qreal progress READ progress WRITE setProgress FINAL) + Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate FINAL) + QML_NAMED_ELEMENT(ProgressBarImpl) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickMaterialProgressBar(QQuickItem *parent = nullptr); + + QColor color() const; + void setColor(const QColor &color); + + qreal progress() const; + void setProgress(qreal progress); + + bool isIndeterminate() const; + void setIndeterminate(bool indeterminate); + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override; + +private: + QColor m_color = Qt::black; + qreal m_progress = 0.0; + bool m_indeterminate = false; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickMaterialProgressBar) + +#endif // QQUICKMATERIALPROGRESSBAR_P_H diff --git a/src/quickcontrols2/material/impl/qquickmaterialripple.cpp b/src/quickcontrols2/material/impl/qquickmaterialripple.cpp new file mode 100644 index 00000000000..48abd9db6f1 --- /dev/null +++ b/src/quickcontrols2/material/impl/qquickmaterialripple.cpp @@ -0,0 +1,444 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmaterialripple_p.h" + +#include <QtCore/qmath.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> +#include <QtQuickControls2Impl/private/qquickanimatednode_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p_p.h> + +QT_BEGIN_NAMESPACE + +namespace { + enum WavePhase { WaveEnter, WaveExit }; +} + +static const int RIPPLE_ENTER_DELAY = 80; +static const int OPACITY_ENTER_DURATION_FAST = 120; +static const int WAVE_OPACITY_DECAY_DURATION = 333; +static const qreal WAVE_TOUCH_DOWN_ACCELERATION = 1024.0; + +class QQuickMaterialRippleWaveNode : public QQuickAnimatedNode +{ +public: + QQuickMaterialRippleWaveNode(QQuickMaterialRipple *ripple); + + void exit(); + void updateCurrentTime(int time) override; + void sync(QQuickItem *item) override; + +private: + qreal m_from = 0; + qreal m_to = 0; + qreal m_value = 0; + WavePhase m_phase = WaveEnter; + QPointF m_anchor; + QRectF m_bounds; +}; + +QQuickMaterialRippleWaveNode::QQuickMaterialRippleWaveNode(QQuickMaterialRipple *ripple) + : QQuickAnimatedNode(ripple) +{ + start(qRound(1000.0 * qSqrt(ripple->diameter() / 2.0 / WAVE_TOUCH_DOWN_ACCELERATION))); + + QSGOpacityNode *opacityNode = new QSGOpacityNode; + appendChildNode(opacityNode); + + QQuickItemPrivate *d = QQuickItemPrivate::get(ripple); + QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode(); + rectNode->setAntialiasing(true); + opacityNode->appendChildNode(rectNode); +} + +void QQuickMaterialRippleWaveNode::exit() +{ + m_phase = WaveExit; + m_from = m_value; + setDuration(WAVE_OPACITY_DECAY_DURATION); + restart(); + connect(this, &QQuickAnimatedNode::stopped, this, &QObject::deleteLater); +} + +void QQuickMaterialRippleWaveNode::updateCurrentTime(int time) +{ + qreal p = 1.0; + if (duration() > 0) + p = time / static_cast<qreal>(duration()); + + m_value = m_from + (m_to - m_from) * p; + p = m_value / m_to; + + const qreal dx = (1.0 - p) * (m_anchor.x() - m_bounds.width() / 2); + const qreal dy = (1.0 - p) * (m_anchor.y() - m_bounds.height() / 2); + + QMatrix4x4 m; + m.translate(qRound((m_bounds.width() - m_value) / 2 + dx), + qRound((m_bounds.height() - m_value) / 2 + dy)); + setMatrix(m); + + QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(firstChild()); + Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType); + qreal opacity = 1.0; + if (m_phase == WaveExit) + opacity -= static_cast<qreal>(time) / WAVE_OPACITY_DECAY_DURATION; + opacityNode->setOpacity(opacity); + + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild()); + Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); + rectNode->setRect(QRectF(0, 0, m_value, m_value)); + rectNode->setRadius(m_value / 2); + rectNode->update(); +} + +void QQuickMaterialRippleWaveNode::sync(QQuickItem *item) +{ + QQuickMaterialRipple *ripple = static_cast<QQuickMaterialRipple *>(item); + m_to = ripple->diameter(); + m_anchor = ripple->anchorPoint(); + m_bounds = ripple->boundingRect(); + + QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(firstChild()); + Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType); + + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild()); + Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); + rectNode->setColor(ripple->color()); +} + +class QQuickMaterialRippleBackgroundNode : public QQuickAnimatedNode +{ + Q_OBJECT + +public: + QQuickMaterialRippleBackgroundNode(QQuickMaterialRipple *ripple); + + void updateCurrentTime(int time) override; + void sync(QQuickItem *item) override; + +private: + bool m_active = false; +}; + +QQuickMaterialRippleBackgroundNode::QQuickMaterialRippleBackgroundNode(QQuickMaterialRipple *ripple) + : QQuickAnimatedNode(ripple) +{ + setDuration(OPACITY_ENTER_DURATION_FAST); + + QSGOpacityNode *opacityNode = new QSGOpacityNode; + opacityNode->setOpacity(0.0); + appendChildNode(opacityNode); + + QQuickItemPrivate *d = QQuickItemPrivate::get(ripple); + QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode(); + rectNode->setAntialiasing(true); + opacityNode->appendChildNode(rectNode); +} + +void QQuickMaterialRippleBackgroundNode::updateCurrentTime(int time) +{ + qreal opacity = time / static_cast<qreal>(duration()); + if (!m_active) + opacity = 1.0 - opacity; + + QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(firstChild()); + Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType); + opacityNode->setOpacity(opacity); +} + +void QQuickMaterialRippleBackgroundNode::sync(QQuickItem *item) +{ + QQuickMaterialRipple *ripple = static_cast<QQuickMaterialRipple *>(item); + if (m_active != ripple->isActive()) { + m_active = ripple->isActive(); + setDuration(m_active ? OPACITY_ENTER_DURATION_FAST : WAVE_OPACITY_DECAY_DURATION); + restart(); + } + + QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(firstChild()); + Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType); + + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild()); + Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); + + const qreal w = ripple->width(); + const qreal h = ripple->height(); + const qreal sz = qSqrt(w * w + h * h); + + QMatrix4x4 matrix; + if (qFuzzyIsNull(ripple->clipRadius())) { + matrix.translate(qRound((w - sz) / 2), qRound((h - sz) / 2)); + rectNode->setRect(QRectF(0, 0, sz, sz)); + rectNode->setRadius(sz / 2); + } else { + rectNode->setRect(QRectF(0, 0, w, h)); + rectNode->setRadius(ripple->clipRadius()); + } + + setMatrix(matrix); + rectNode->setColor(ripple->color()); + rectNode->update(); +} + +QQuickMaterialRipple::QQuickMaterialRipple(QQuickItem *parent) + : QQuickItem(parent) +{ + setFlag(ItemHasContents); +} + +bool QQuickMaterialRipple::isActive() const +{ + return m_active; +} + +void QQuickMaterialRipple::setActive(bool active) +{ + if (active == m_active) + return; + + m_active = active; + update(); +} + +QColor QQuickMaterialRipple::color() const +{ + return m_color; +} + +void QQuickMaterialRipple::setColor(const QColor &color) +{ + if (m_color == color) + return; + + m_color = color; + update(); +} + +qreal QQuickMaterialRipple::clipRadius() const +{ + return m_clipRadius; +} + +void QQuickMaterialRipple::setClipRadius(qreal radius) +{ + if (qFuzzyCompare(m_clipRadius, radius)) + return; + + m_clipRadius = radius; + setClip(!qFuzzyIsNull(radius)); + update(); +} + +bool QQuickMaterialRipple::isPressed() const +{ + return m_pressed; +} + +void QQuickMaterialRipple::setPressed(bool pressed) +{ + if (pressed == m_pressed) + return; + + m_pressed = pressed; + + if (!isEnabled()) { + exitWave(); + return; + } + + if (pressed) { + if (m_trigger == Press) + prepareWave(); + else + exitWave(); + } else { + if (m_trigger == Release) + enterWave(); + else + exitWave(); + } +} + +QQuickMaterialRipple::Trigger QQuickMaterialRipple::trigger() const +{ + return m_trigger; +} + +void QQuickMaterialRipple::setTrigger(Trigger trigger) +{ + m_trigger = trigger; +} + +QPointF QQuickMaterialRipple::anchorPoint() const +{ + const QRectF bounds = boundingRect(); + const QPointF center = bounds.center(); + if (!m_anchor) + return center; + + QPointF anchorPoint = bounds.center(); + if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(m_anchor)) + anchorPoint = QQuickAbstractButtonPrivate::get(button)->pressPoint; + anchorPoint = mapFromItem(m_anchor, anchorPoint); + + // calculate whether the anchor point is within the ripple circle bounds, + // that is, whether waves should start expanding from the anchor point + const qreal r = qSqrt(bounds.width() * bounds.width() + bounds.height() * bounds.height()) / 2; + if (QLineF(center, anchorPoint).length() < r) + return anchorPoint; + + // if the anchor point is outside the ripple circle bounds, start expanding + // from the intersection point of the ripple circle and a line from its center + // to the the anchor point + const qreal p = qAtan2(anchorPoint.y() - center.y(), anchorPoint.x() - center.x()); + return QPointF(center.x() + r * qCos(p), center.y() + r * qSin(p)); +} + +QQuickItem *QQuickMaterialRipple::anchor() const +{ + return m_anchor; +} + +void QQuickMaterialRipple::setAnchor(QQuickItem *item) +{ + m_anchor = item; +} + +qreal QQuickMaterialRipple::diameter() const +{ + const qreal w = width(); + const qreal h = height(); + return qSqrt(w * w + h * h); +} + +void QQuickMaterialRipple::itemChange(ItemChange change, const ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); +} + +QSGNode *QQuickMaterialRipple::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + QQuickItemPrivate *d = QQuickItemPrivate::get(this); + QQuickDefaultClipNode *clipNode = d->clipNode(); + if (clipNode) { + // TODO: QTBUG-51894 + // clipNode->setRadius(m_clipRadius); + clipNode->setRect(boundingRect()); + clipNode->update(); + } + + QSGNode *container = oldNode; + if (!container) + container = new QSGNode; + + QQuickMaterialRippleBackgroundNode *backgroundNode = static_cast<QQuickMaterialRippleBackgroundNode *>(container->firstChild()); + if (!backgroundNode) { + backgroundNode = new QQuickMaterialRippleBackgroundNode(this); + backgroundNode->setObjectName(objectName()); + container->appendChildNode(backgroundNode); + } + backgroundNode->sync(this); + + // enter new waves + int i = m_waves; + QQuickMaterialRippleWaveNode *enterNode = static_cast<QQuickMaterialRippleWaveNode *>(backgroundNode->nextSibling()); + while (i-- > 0) { + if (!enterNode) { + enterNode = new QQuickMaterialRippleWaveNode(this); + container->appendChildNode(enterNode); + } + enterNode->sync(this); + enterNode = static_cast<QQuickMaterialRippleWaveNode *>(enterNode->nextSibling()); + } + + // exit old waves + int j = container->childCount() - 1 - m_waves; + while (j-- > 0) { + QQuickMaterialRippleWaveNode *exitNode = static_cast<QQuickMaterialRippleWaveNode *>(backgroundNode->nextSibling()); + if (exitNode) { + exitNode->exit(); + exitNode->sync(this); + } + } + + return container; +} + +void QQuickMaterialRipple::timerEvent(QTimerEvent *event) +{ + QQuickItem::timerEvent(event); + + if (event->timerId() == m_enterDelay) + enterWave(); +} + +void QQuickMaterialRipple::prepareWave() +{ + if (m_enterDelay <= 0) + m_enterDelay = startTimer(RIPPLE_ENTER_DELAY); +} + +void QQuickMaterialRipple::enterWave() +{ + if (m_enterDelay > 0) { + killTimer(m_enterDelay); + m_enterDelay = 0; + } + + ++m_waves; + update(); +} + +void QQuickMaterialRipple::exitWave() +{ + if (m_enterDelay > 0) { + killTimer(m_enterDelay); + m_enterDelay = 0; + } + + if (m_waves > 0) { + --m_waves; + update(); + } +} + +QT_END_NAMESPACE + +#include "moc_qquickmaterialripple_p.cpp" + +#include "qquickmaterialripple.moc" diff --git a/src/quickcontrols2/material/impl/qquickmaterialripple_p.h b/src/quickcontrols2/material/impl/qquickmaterialripple_p.h new file mode 100644 index 00000000000..517283896a8 --- /dev/null +++ b/src/quickcontrols2/material/impl/qquickmaterialripple_p.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMATERIALRIPPLE_P_H +#define QQUICKMATERIALRIPPLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtGui/qcolor.h> + +QT_BEGIN_NAMESPACE + +class QQuickMaterialRipple : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + Q_PROPERTY(qreal clipRadius READ clipRadius WRITE setClipRadius FINAL) + Q_PROPERTY(bool pressed READ isPressed WRITE setPressed FINAL) + Q_PROPERTY(bool active READ isActive WRITE setActive FINAL) + Q_PROPERTY(QQuickItem *anchor READ anchor WRITE setAnchor FINAL) + Q_PROPERTY(Trigger trigger READ trigger WRITE setTrigger FINAL) + QML_NAMED_ELEMENT(Ripple) + QML_ADDED_IN_VERSION(2, 0) + +public: + QQuickMaterialRipple(QQuickItem *parent = nullptr); + + QColor color() const; + void setColor(const QColor &color); + + qreal clipRadius() const; + void setClipRadius(qreal radius); + + bool isActive() const; + void setActive(bool active); + + bool isPressed() const; + void setPressed(bool pressed); + + enum Trigger { Press, Release }; + Q_ENUM (Trigger) + + Trigger trigger() const; + void setTrigger(Trigger trigger); + + QPointF anchorPoint() const; + + QQuickItem *anchor() const; + void setAnchor(QQuickItem *anchor); + + qreal diameter() const; + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override; + void timerEvent(QTimerEvent *event) override; + + void prepareWave(); + void enterWave(); + void exitWave(); + +private: + bool m_active = false; + bool m_pressed = false; + int m_waves = 0; + int m_enterDelay = 0; + Trigger m_trigger = Press; + qreal m_clipRadius = 0.0; + QColor m_color; + QQuickItem *m_anchor = nullptr; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickMaterialRipple) + +#endif // QQUICKMATERIALRIPPLE_P_H diff --git a/src/quickcontrols2/material/material.pri b/src/quickcontrols2/material/material.pri new file mode 100644 index 00000000000..2c17f71f650 --- /dev/null +++ b/src/quickcontrols2/material/material.pri @@ -0,0 +1,61 @@ +HEADERS += \ + $$PWD/qquickmaterialstyle_p.h \ + $$PWD/qquickmaterialtheme_p.h + +SOURCES += \ + $$PWD/qquickmaterialstyle.cpp \ + $$PWD/qquickmaterialtheme.cpp + +QML_FILES += \ + $$PWD/ApplicationWindow.qml \ + $$PWD/BusyIndicator.qml \ + $$PWD/Button.qml \ + $$PWD/CheckBox.qml \ + $$PWD/CheckDelegate.qml \ + $$PWD/ComboBox.qml \ + $$PWD/DelayButton.qml \ + $$PWD/Dial.qml \ + $$PWD/Dialog.qml \ + $$PWD/DialogButtonBox.qml \ + $$PWD/Drawer.qml \ + $$PWD/Frame.qml \ + $$PWD/GroupBox.qml \ + $$PWD/HorizontalHeaderView.qml \ + $$PWD/ItemDelegate.qml \ + $$PWD/Label.qml \ + $$PWD/Menu.qml \ + $$PWD/MenuBar.qml \ + $$PWD/MenuBarItem.qml \ + $$PWD/MenuItem.qml \ + $$PWD/MenuSeparator.qml \ + $$PWD/Page.qml \ + $$PWD/PageIndicator.qml \ + $$PWD/Pane.qml \ + $$PWD/Popup.qml \ + $$PWD/ProgressBar.qml \ + $$PWD/RadioButton.qml \ + $$PWD/RadioDelegate.qml \ + $$PWD/RangeSlider.qml \ + $$PWD/RoundButton.qml \ + $$PWD/ScrollView.qml \ + $$PWD/ScrollBar.qml \ + $$PWD/ScrollIndicator.qml \ + $$PWD/SelectionRectangle.qml \ + $$PWD/Slider.qml \ + $$PWD/SpinBox.qml \ + $$PWD/SplitView.qml \ + $$PWD/StackView.qml \ + $$PWD/SwipeDelegate.qml \ + $$PWD/SwipeView.qml \ + $$PWD/Switch.qml \ + $$PWD/SwitchDelegate.qml \ + $$PWD/TabBar.qml \ + $$PWD/TabButton.qml \ + $$PWD/TextArea.qml \ + $$PWD/TextField.qml \ + $$PWD/ToolBar.qml \ + $$PWD/ToolButton.qml \ + $$PWD/ToolSeparator.qml \ + $$PWD/ToolTip.qml \ + $$PWD/Tumbler.qml \ + $$PWD/VerticalHeaderView.qml diff --git a/src/quickcontrols2/material/qquickmaterialstyle.cpp b/src/quickcontrols2/material/qquickmaterialstyle.cpp new file mode 100644 index 00000000000..59851141db0 --- /dev/null +++ b/src/quickcontrols2/material/qquickmaterialstyle.cpp @@ -0,0 +1,1397 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmaterialstyle_p.h" + +#include <QtCore/qdebug.h> +#include <QtCore/qsettings.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuickControls2/private/qquickstyle_p.h> + +QT_BEGIN_NAMESPACE + +static const QRgb colors[][14] = { + // Red + { + 0xFFFFEBEE, // Shade50 + 0xFFFFCDD2, // Shade100 + 0xFFEF9A9A, // Shade200 + 0xFFE57373, // Shade300 + 0xFFEF5350, // Shade400 + 0xFFF44336, // Shade500 + 0xFFE53935, // Shade600 + 0xFFD32F2F, // Shade700 + 0xFFC62828, // Shade800 + 0xFFB71C1C, // Shade900 + 0xFFFF8A80, // ShadeA100 + 0xFFFF5252, // ShadeA200 + 0xFFFF1744, // ShadeA400 + 0xFFD50000 // ShadeA700 + }, + // Pink + { + 0xFFFCE4EC, // Shade50 + 0xFFF8BBD0, // Shade100 + 0xFFF48FB1, // Shade200 + 0xFFF06292, // Shade300 + 0xFFEC407A, // Shade400 + 0xFFE91E63, // Shade500 + 0xFFD81B60, // Shade600 + 0xFFC2185B, // Shade700 + 0xFFAD1457, // Shade800 + 0xFF880E4F, // Shade900 + 0xFFFF80AB, // ShadeA100 + 0xFFFF4081, // ShadeA200 + 0xFFF50057, // ShadeA400 + 0xFFC51162 // ShadeA700 + }, + // Purple + { + 0xFFF3E5F5, // Shade50 + 0xFFE1BEE7, // Shade100 + 0xFFCE93D8, // Shade200 + 0xFFBA68C8, // Shade300 + 0xFFAB47BC, // Shade400 + 0xFF9C27B0, // Shade500 + 0xFF8E24AA, // Shade600 + 0xFF7B1FA2, // Shade700 + 0xFF6A1B9A, // Shade800 + 0xFF4A148C, // Shade900 + 0xFFEA80FC, // ShadeA100 + 0xFFE040FB, // ShadeA200 + 0xFFD500F9, // ShadeA400 + 0xFFAA00FF // ShadeA700 + }, + // DeepPurple + { + 0xFFEDE7F6, // Shade50 + 0xFFD1C4E9, // Shade100 + 0xFFB39DDB, // Shade200 + 0xFF9575CD, // Shade300 + 0xFF7E57C2, // Shade400 + 0xFF673AB7, // Shade500 + 0xFF5E35B1, // Shade600 + 0xFF512DA8, // Shade700 + 0xFF4527A0, // Shade800 + 0xFF311B92, // Shade900 + 0xFFB388FF, // ShadeA100 + 0xFF7C4DFF, // ShadeA200 + 0xFF651FFF, // ShadeA400 + 0xFF6200EA // ShadeA700 + }, + // Indigo + { + 0xFFE8EAF6, // Shade50 + 0xFFC5CAE9, // Shade100 + 0xFF9FA8DA, // Shade200 + 0xFF7986CB, // Shade300 + 0xFF5C6BC0, // Shade400 + 0xFF3F51B5, // Shade500 + 0xFF3949AB, // Shade600 + 0xFF303F9F, // Shade700 + 0xFF283593, // Shade800 + 0xFF1A237E, // Shade900 + 0xFF8C9EFF, // ShadeA100 + 0xFF536DFE, // ShadeA200 + 0xFF3D5AFE, // ShadeA400 + 0xFF304FFE // ShadeA700 + }, + // Blue + { + 0xFFE3F2FD, // Shade50 + 0xFFBBDEFB, // Shade100 + 0xFF90CAF9, // Shade200 + 0xFF64B5F6, // Shade300 + 0xFF42A5F5, // Shade400 + 0xFF2196F3, // Shade500 + 0xFF1E88E5, // Shade600 + 0xFF1976D2, // Shade700 + 0xFF1565C0, // Shade800 + 0xFF0D47A1, // Shade900 + 0xFF82B1FF, // ShadeA100 + 0xFF448AFF, // ShadeA200 + 0xFF2979FF, // ShadeA400 + 0xFF2962FF // ShadeA700 + }, + // LightBlue + { + 0xFFE1F5FE, // Shade50 + 0xFFB3E5FC, // Shade100 + 0xFF81D4FA, // Shade200 + 0xFF4FC3F7, // Shade300 + 0xFF29B6F6, // Shade400 + 0xFF03A9F4, // Shade500 + 0xFF039BE5, // Shade600 + 0xFF0288D1, // Shade700 + 0xFF0277BD, // Shade800 + 0xFF01579B, // Shade900 + 0xFF80D8FF, // ShadeA100 + 0xFF40C4FF, // ShadeA200 + 0xFF00B0FF, // ShadeA400 + 0xFF0091EA // ShadeA700 + }, + // Cyan + { + 0xFFE0F7FA, // Shade50 + 0xFFB2EBF2, // Shade100 + 0xFF80DEEA, // Shade200 + 0xFF4DD0E1, // Shade300 + 0xFF26C6DA, // Shade400 + 0xFF00BCD4, // Shade500 + 0xFF00ACC1, // Shade600 + 0xFF0097A7, // Shade700 + 0xFF00838F, // Shade800 + 0xFF006064, // Shade900 + 0xFF84FFFF, // ShadeA100 + 0xFF18FFFF, // ShadeA200 + 0xFF00E5FF, // ShadeA400 + 0xFF00B8D4 // ShadeA700 + }, + // Teal + { + 0xFFE0F2F1, // Shade50 + 0xFFB2DFDB, // Shade100 + 0xFF80CBC4, // Shade200 + 0xFF4DB6AC, // Shade300 + 0xFF26A69A, // Shade400 + 0xFF009688, // Shade500 + 0xFF00897B, // Shade600 + 0xFF00796B, // Shade700 + 0xFF00695C, // Shade800 + 0xFF004D40, // Shade900 + 0xFFA7FFEB, // ShadeA100 + 0xFF64FFDA, // ShadeA200 + 0xFF1DE9B6, // ShadeA400 + 0xFF00BFA5 // ShadeA700 + }, + // Green + { + 0xFFE8F5E9, // Shade50 + 0xFFC8E6C9, // Shade100 + 0xFFA5D6A7, // Shade200 + 0xFF81C784, // Shade300 + 0xFF66BB6A, // Shade400 + 0xFF4CAF50, // Shade500 + 0xFF43A047, // Shade600 + 0xFF388E3C, // Shade700 + 0xFF2E7D32, // Shade800 + 0xFF1B5E20, // Shade900 + 0xFFB9F6CA, // ShadeA100 + 0xFF69F0AE, // ShadeA200 + 0xFF00E676, // ShadeA400 + 0xFF00C853 // ShadeA700 + }, + // LightGreen + { + 0xFFF1F8E9, // Shade50 + 0xFFDCEDC8, // Shade100 + 0xFFC5E1A5, // Shade200 + 0xFFAED581, // Shade300 + 0xFF9CCC65, // Shade400 + 0xFF8BC34A, // Shade500 + 0xFF7CB342, // Shade600 + 0xFF689F38, // Shade700 + 0xFF558B2F, // Shade800 + 0xFF33691E, // Shade900 + 0xFFCCFF90, // ShadeA100 + 0xFFB2FF59, // ShadeA200 + 0xFF76FF03, // ShadeA400 + 0xFF64DD17 // ShadeA700 + }, + // Lime + { + 0xFFF9FBE7, // Shade50 + 0xFFF0F4C3, // Shade100 + 0xFFE6EE9C, // Shade200 + 0xFFDCE775, // Shade300 + 0xFFD4E157, // Shade400 + 0xFFCDDC39, // Shade500 + 0xFFC0CA33, // Shade600 + 0xFFAFB42B, // Shade700 + 0xFF9E9D24, // Shade800 + 0xFF827717, // Shade900 + 0xFFF4FF81, // ShadeA100 + 0xFFEEFF41, // ShadeA200 + 0xFFC6FF00, // ShadeA400 + 0xFFAEEA00 // ShadeA700 + }, + // Yellow + { + 0xFFFFFDE7, // Shade50 + 0xFFFFF9C4, // Shade100 + 0xFFFFF59D, // Shade200 + 0xFFFFF176, // Shade300 + 0xFFFFEE58, // Shade400 + 0xFFFFEB3B, // Shade500 + 0xFFFDD835, // Shade600 + 0xFFFBC02D, // Shade700 + 0xFFF9A825, // Shade800 + 0xFFF57F17, // Shade900 + 0xFFFFFF8D, // ShadeA100 + 0xFFFFFF00, // ShadeA200 + 0xFFFFEA00, // ShadeA400 + 0xFFFFD600 // ShadeA700 + }, + // Amber + { + 0xFFFFF8E1, // Shade50 + 0xFFFFECB3, // Shade100 + 0xFFFFE082, // Shade200 + 0xFFFFD54F, // Shade300 + 0xFFFFCA28, // Shade400 + 0xFFFFC107, // Shade500 + 0xFFFFB300, // Shade600 + 0xFFFFA000, // Shade700 + 0xFFFF8F00, // Shade800 + 0xFFFF6F00, // Shade900 + 0xFFFFE57F, // ShadeA100 + 0xFFFFD740, // ShadeA200 + 0xFFFFC400, // ShadeA400 + 0xFFFFAB00 // ShadeA700 + }, + // Orange + { + 0xFFFFF3E0, // Shade50 + 0xFFFFE0B2, // Shade100 + 0xFFFFCC80, // Shade200 + 0xFFFFB74D, // Shade300 + 0xFFFFA726, // Shade400 + 0xFFFF9800, // Shade500 + 0xFFFB8C00, // Shade600 + 0xFFF57C00, // Shade700 + 0xFFEF6C00, // Shade800 + 0xFFE65100, // Shade900 + 0xFFFFD180, // ShadeA100 + 0xFFFFAB40, // ShadeA200 + 0xFFFF9100, // ShadeA400 + 0xFFFF6D00 // ShadeA700 + }, + // DeepOrange + { + 0xFFFBE9E7, // Shade50 + 0xFFFFCCBC, // Shade100 + 0xFFFFAB91, // Shade200 + 0xFFFF8A65, // Shade300 + 0xFFFF7043, // Shade400 + 0xFFFF5722, // Shade500 + 0xFFF4511E, // Shade600 + 0xFFE64A19, // Shade700 + 0xFFD84315, // Shade800 + 0xFFBF360C, // Shade900 + 0xFFFF9E80, // ShadeA100 + 0xFFFF6E40, // ShadeA200 + 0xFFFF3D00, // ShadeA400 + 0xFFDD2C00 // ShadeA700 + }, + // Brown + { + 0xFFEFEBE9, // Shade50 + 0xFFD7CCC8, // Shade100 + 0xFFBCAAA4, // Shade200 + 0xFFA1887F, // Shade300 + 0xFF8D6E63, // Shade400 + 0xFF795548, // Shade500 + 0xFF6D4C41, // Shade600 + 0xFF5D4037, // Shade700 + 0xFF4E342E, // Shade800 + 0xFF3E2723, // Shade900 + 0xFF000000, // ShadeA100 + 0xFF000000, // ShadeA200 + 0xFF000000, // ShadeA400 + 0xFF000000 // ShadeA700 + }, + // Grey + { + 0xFFFAFAFA, // Shade50 + 0xFFF5F5F5, // Shade100 + 0xFFEEEEEE, // Shade200 + 0xFFE0E0E0, // Shade300 + 0xFFBDBDBD, // Shade400 + 0xFF9E9E9E, // Shade500 + 0xFF757575, // Shade600 + 0xFF616161, // Shade700 + 0xFF424242, // Shade800 + 0xFF212121, // Shade900 + 0xFF000000, // ShadeA100 + 0xFF000000, // ShadeA200 + 0xFF000000, // ShadeA400 + 0xFF000000 // ShadeA700 + }, + // BlueGrey + { + 0xFFECEFF1, // Shade50 + 0xFFCFD8DC, // Shade100 + 0xFFB0BEC5, // Shade200 + 0xFF90A4AE, // Shade300 + 0xFF78909C, // Shade400 + 0xFF607D8B, // Shade500 + 0xFF546E7A, // Shade600 + 0xFF455A64, // Shade700 + 0xFF37474F, // Shade800 + 0xFF263238, // Shade900 + 0xFF000000, // ShadeA100 + 0xFF000000, // ShadeA200 + 0xFF000000, // ShadeA400 + 0xFF000000 // ShadeA700 + } +}; + +// If no value was inherited from a parent or explicitly set, the "global" values are used. +// The initial, default values of the globals are hard-coded here, but the environment +// variables and .conf file override them if specified. +static QQuickMaterialStyle::Theme globalTheme = QQuickMaterialStyle::Light; +static uint globalPrimary = QQuickMaterialStyle::Indigo; +static uint globalAccent = QQuickMaterialStyle::Pink; +static uint globalForeground = 0xDD000000; // primaryTextColorLight +static uint globalBackground = 0xFFFAFAFA; // backgroundColorLight +// These represent whether a global foreground/background was set. +// Each style's m_hasForeground/m_hasBackground are initialized to these values. +static bool hasGlobalForeground = false; +static bool hasGlobalBackground = false; +// These represent whether or not the global color value was specified as one of the +// values that QColor accepts, as opposed to one of the pre-defined colors like Red. +static bool globalPrimaryCustom = false; +static bool globalAccentCustom = false; +static bool globalForegroundCustom = true; +static bool globalBackgroundCustom = true; +// This is global because: +// 1) The theme needs access to it to determine font sizes. +// 2) There can only be one variant used for the whole application. +static QQuickMaterialStyle::Variant globalVariant = QQuickMaterialStyle::Normal; + +static const QRgb backgroundColorLight = 0xFFFAFAFA; +static const QRgb backgroundColorDark = 0xFF303030; +static const QRgb dialogColorLight = 0xFFFFFFFF; +static const QRgb dialogColorDark = 0xFF424242; +static const QRgb primaryTextColorLight = 0xDD000000; +static const QRgb primaryTextColorDark = 0xFFFFFFFF; +static const QRgb secondaryTextColorLight = 0x89000000; +static const QRgb secondaryTextColorDark = 0xB2FFFFFF; +static const QRgb hintTextColorLight = 0x60000000; +static const QRgb hintTextColorDark = 0x4CFFFFFF; +static const QRgb dividerColorLight = 0x1E000000; +static const QRgb dividerColorDark = 0x1EFFFFFF; +static const QRgb iconColorLight = 0x89000000; +static const QRgb iconColorDark = 0xFFFFFFFF; +static const QRgb iconDisabledColorLight = 0x42000000; +static const QRgb iconDisabledColorDark = 0x4CFFFFFF; +static const QRgb raisedButtonColorLight = 0xFFD6D7D7; +static const QRgb raisedButtonColorDark = 0x3FCCCCCC; +static const QRgb raisedButtonDisabledColorLight = dividerColorLight; +static const QRgb raisedButtonDisabledColorDark = dividerColorDark; +static const QRgb frameColorLight = hintTextColorLight; +static const QRgb frameColorDark = hintTextColorDark; +static const QRgb switchUncheckedTrackColorLight = 0x42000000; +static const QRgb switchUncheckedTrackColorDark = 0x4CFFFFFF; +static const QRgb switchDisabledTrackColorLight = 0x1E000000; +static const QRgb switchDisabledTrackColorDark = 0x19FFFFFF; +static const QRgb rippleColorLight = 0x10000000; +static const QRgb rippleColorDark = 0x20FFFFFF; +static const QRgb spinBoxDisabledIconColorLight = 0xFFCCCCCC; +static const QRgb spinBoxDisabledIconColorDark = 0xFF666666; +static const QRgb sliderDisabledColorLight = 0xFF9E9E9E; +static const QRgb sliderDisabledColorDark = 0xFF616161; + +static QQuickMaterialStyle::Theme effectiveTheme(QQuickMaterialStyle::Theme theme) +{ + if (theme == QQuickMaterialStyle::System) + theme = QQuickStylePrivate::isDarkSystemTheme() ? QQuickMaterialStyle::Dark : QQuickMaterialStyle::Light; + return theme; +} + +QQuickMaterialStyle::QQuickMaterialStyle(QObject *parent) : QQuickAttachedObject(parent), + m_customPrimary(globalPrimaryCustom), + m_customAccent(globalAccentCustom), + m_customForeground(globalForegroundCustom), + m_customBackground(globalBackgroundCustom), + m_hasForeground(hasGlobalForeground), + m_hasBackground(hasGlobalBackground), + m_theme(globalTheme), + m_primary(globalPrimary), + m_accent(globalAccent), + m_foreground(globalForeground), + m_background(globalBackground) +{ + QQuickAttachedObject::init(); +} + +QQuickMaterialStyle *QQuickMaterialStyle::qmlAttachedProperties(QObject *object) +{ + return new QQuickMaterialStyle(object); +} + +QQuickMaterialStyle::Theme QQuickMaterialStyle::theme() const +{ + return m_theme; +} + +void QQuickMaterialStyle::setTheme(Theme theme) +{ + if (theme == System) + theme = QQuickStylePrivate::isDarkSystemTheme() ? Dark : Light; + + m_explicitTheme = true; + if (m_theme == theme) + return; + + m_theme = theme; + propagateTheme(); + themeChange(); + if (!m_customAccent) + accentChange(); + if (!m_hasBackground) + backgroundChange(); + if (!m_hasForeground) + foregroundChange(); +} + +void QQuickMaterialStyle::inheritTheme(Theme theme) +{ + if (m_explicitTheme || m_theme == theme) + return; + + m_theme = theme; + propagateTheme(); + themeChange(); + if (!m_customAccent) + accentChange(); + if (!m_hasBackground) + backgroundChange(); + if (!m_hasForeground) + foregroundChange(); +} + +void QQuickMaterialStyle::propagateTheme() +{ + const auto styles = attachedChildren(); + for (QQuickAttachedObject *child : styles) { + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child); + if (material) + material->inheritTheme(m_theme); + } +} + +void QQuickMaterialStyle::resetTheme() +{ + if (!m_explicitTheme) + return; + + m_explicitTheme = false; + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(attachedParent()); + inheritTheme(material ? material->theme() : globalTheme); +} + +void QQuickMaterialStyle::themeChange() +{ + emit themeChanged(); + emit themeOrAccentChanged(); + emit primaryHighlightedTextColor(); + emit buttonColorChanged(); + emit buttonDisabledColorChanged(); + emit dialogColorChanged(); + emit tooltipColorChanged(); + emit toolBarColorChanged(); + emit toolTextColorChanged(); +} + +QVariant QQuickMaterialStyle::primary() const +{ + return primaryColor(); +} + +void QQuickMaterialStyle::setPrimary(const QVariant &var) +{ + QRgb primary = 0; + bool custom = false; + if (!variantToRgba(var, "primary", &primary, &custom)) + return; + + m_explicitPrimary = true; + if (m_primary == primary) + return; + + m_customPrimary = custom; + m_primary = primary; + propagatePrimary(); + primaryChange(); +} + +void QQuickMaterialStyle::inheritPrimary(uint primary, bool custom) +{ + if (m_explicitPrimary || m_primary == primary) + return; + + m_customPrimary = custom; + m_primary = primary; + propagatePrimary(); + primaryChange(); +} + +void QQuickMaterialStyle::propagatePrimary() +{ + const auto styles = attachedChildren(); + for (QQuickAttachedObject *child : styles) { + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child); + if (material) + material->inheritPrimary(m_primary, m_customPrimary); + } +} + +void QQuickMaterialStyle::resetPrimary() +{ + if (!m_explicitPrimary) + return; + + m_customPrimary = false; + m_explicitPrimary = false; + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(attachedParent()); + if (material) + inheritPrimary(material->m_primary, material->m_customPrimary); + else + inheritPrimary(globalPrimary, false); +} + +void QQuickMaterialStyle::primaryChange() +{ + emit primaryChanged(); + emit toolBarColorChanged(); + emit toolTextColorChanged(); +} + +QVariant QQuickMaterialStyle::accent() const +{ + return accentColor(); +} + +void QQuickMaterialStyle::setAccent(const QVariant &var) +{ + QRgb accent = 0; + bool custom = false; + if (!variantToRgba(var, "accent", &accent, &custom)) + return; + + m_explicitAccent = true; + if (m_accent == accent) + return; + + m_customAccent = custom; + m_accent = accent; + propagateAccent(); + accentChange(); +} + +void QQuickMaterialStyle::inheritAccent(uint accent, bool custom) +{ + if (m_explicitAccent || m_accent == accent) + return; + + m_customAccent = custom; + m_accent = accent; + propagateAccent(); + accentChange(); +} + +void QQuickMaterialStyle::propagateAccent() +{ + const auto styles = attachedChildren(); + for (QQuickAttachedObject *child : styles) { + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child); + if (material) + material->inheritAccent(m_accent, m_customAccent); + } +} + +void QQuickMaterialStyle::resetAccent() +{ + if (!m_explicitAccent) + return; + + m_customAccent = false; + m_explicitAccent = false; + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(attachedParent()); + if (material) + inheritAccent(material->m_accent, material->m_customAccent); + else + inheritAccent(globalAccent, false); +} + +void QQuickMaterialStyle::accentChange() +{ + emit accentChanged(); + emit themeOrAccentChanged(); + emit buttonColorChanged(); +} + +QVariant QQuickMaterialStyle::foreground() const +{ + if (!m_hasForeground) + return QColor::fromRgba(m_theme == Light ? primaryTextColorLight : primaryTextColorDark); + if (m_customForeground) + return QColor::fromRgba(m_foreground); + if (m_foreground > BlueGrey) + return QColor(); + return QColor::fromRgba(colors[m_foreground][Shade500]); +} + +void QQuickMaterialStyle::setForeground(const QVariant &var) +{ + QRgb foreground = 0; + bool custom = false; + if (!variantToRgba(var, "foreground", &foreground, &custom)) + return; + + m_hasForeground = true; + m_explicitForeground = true; + if (m_foreground == foreground) + return; + + m_customForeground = custom; + m_foreground = foreground; + propagateForeground(); + foregroundChange(); +} + +void QQuickMaterialStyle::inheritForeground(uint foreground, bool custom, bool has) +{ + if (m_explicitForeground || m_foreground == foreground) + return; + + m_hasForeground = has; + m_customForeground = custom; + m_foreground = foreground; + propagateForeground(); + foregroundChange(); +} + +void QQuickMaterialStyle::propagateForeground() +{ + const auto styles = attachedChildren(); + for (QQuickAttachedObject *child : styles) { + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child); + if (material) + material->inheritForeground(m_foreground, m_customForeground, m_hasForeground); + } +} + +void QQuickMaterialStyle::resetForeground() +{ + if (!m_explicitForeground) + return; + + m_hasForeground = false; + m_customForeground = false; + m_explicitForeground = false; + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(attachedParent()); + inheritForeground(material ? material->m_foreground : globalForeground, true, material ? material->m_hasForeground : false); +} + +void QQuickMaterialStyle::foregroundChange() +{ + emit foregroundChanged(); + emit primaryHighlightedTextColorChanged(); + // TODO: This causes a binding loop: see QTBUG-85699 and the comments on its fix +// emit toolTextColorChanged(); +} + +QVariant QQuickMaterialStyle::background() const +{ + return backgroundColor(); +} + +void QQuickMaterialStyle::setBackground(const QVariant &var) +{ + QRgb background = 0; + bool custom = false; + if (!variantToRgba(var, "background", &background, &custom)) + return; + + m_hasBackground = true; + m_explicitBackground = true; + if (m_background == background) + return; + + m_customBackground = custom; + m_background = background; + propagateBackground(); + backgroundChange(); +} + +void QQuickMaterialStyle::inheritBackground(uint background, bool custom, bool has) +{ + if (m_explicitBackground || m_background == background) + return; + + m_hasBackground = has; + m_customBackground = custom; + m_background = background; + propagateBackground(); + backgroundChange(); +} + +void QQuickMaterialStyle::propagateBackground() +{ + const auto styles = attachedChildren(); + for (QQuickAttachedObject *child : styles) { + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child); + if (material) + material->inheritBackground(m_background, m_customBackground, m_hasBackground); + } +} + +void QQuickMaterialStyle::resetBackground() +{ + if (!m_explicitBackground) + return; + + m_hasBackground = false; + m_customBackground = false; + m_explicitBackground = false; + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(attachedParent()); + inheritBackground(material ? material->m_background : globalBackground, true, material ? material->m_hasBackground : false); +} + +void QQuickMaterialStyle::backgroundChange() +{ + emit backgroundChanged(); + emit buttonColorChanged(); + emit dialogColorChanged(); + emit tooltipColorChanged(); + emit toolBarColorChanged(); +} + +int QQuickMaterialStyle::elevation() const +{ + return m_elevation; +} + +void QQuickMaterialStyle::setElevation(int elevation) +{ + if (m_elevation == elevation) + return; + + m_elevation = elevation; + elevationChange(); +} + +void QQuickMaterialStyle::resetElevation() +{ + setElevation(0); +} + +void QQuickMaterialStyle::elevationChange() +{ + emit elevationChanged(); + emit buttonDisabledColorChanged(); +} + +QColor QQuickMaterialStyle::primaryColor() const +{ + if (m_customPrimary) + return QColor::fromRgba(m_primary); + if (m_primary > BlueGrey) + return QColor(); + return colors[m_primary][Shade500]; +} + +QColor QQuickMaterialStyle::accentColor(Shade shade) const +{ + if (m_customAccent) + return shade == themeShade() ? QColor::fromRgba(m_accent) + : this->shade(QColor::fromRgba(m_accent), shade); + if (m_accent > BlueGrey) + return QColor(); + return colors[m_accent][shade]; +} + +QColor QQuickMaterialStyle::accentColor() const +{ + return accentColor(themeShade()); +} + +QColor QQuickMaterialStyle::backgroundColor(Shade shade) const +{ + if (!m_hasBackground) + return QColor::fromRgba(m_theme == Light ? backgroundColorLight : backgroundColorDark); + if (m_customBackground) + return shade == themeShade() ? QColor::fromRgba(m_background) + : this->shade(QColor::fromRgba(m_background), shade); + if (m_background > BlueGrey) + return QColor(); + return colors[m_background][shade]; +} + +QColor QQuickMaterialStyle::backgroundColor() const +{ + return backgroundColor(themeShade()); +} + +QColor QQuickMaterialStyle::primaryTextColor() const +{ + return QColor::fromRgba(m_theme == Light ? primaryTextColorLight : primaryTextColorDark); +} + +QColor QQuickMaterialStyle::primaryHighlightedTextColor() const +{ + if (m_explicitForeground) + return primaryTextColor(); + return QColor::fromRgba(primaryTextColorDark); +} + +QColor QQuickMaterialStyle::secondaryTextColor() const +{ + return QColor::fromRgba(m_theme == Light ? secondaryTextColorLight : secondaryTextColorDark); +} + +QColor QQuickMaterialStyle::hintTextColor() const +{ + return QColor::fromRgba(m_theme == Light ? hintTextColorLight : hintTextColorDark); +} + +QColor QQuickMaterialStyle::textSelectionColor() const +{ + QColor color = accentColor(); + color.setAlphaF(0.4f); + return color; +} + +QColor QQuickMaterialStyle::dropShadowColor() const +{ + return QColor::fromRgba(0x40000000); +} + +QColor QQuickMaterialStyle::dividerColor() const +{ + return QColor::fromRgba(m_theme == Light ? dividerColorLight : dividerColorDark); +} + +QColor QQuickMaterialStyle::iconColor() const +{ + return QColor::fromRgba(m_theme == Light ? iconColorLight : iconColorDark); +} + +QColor QQuickMaterialStyle::iconDisabledColor() const +{ + return QColor::fromRgba(m_theme == Light ? iconDisabledColorLight : iconDisabledColorDark); +} + +QColor QQuickMaterialStyle::buttonColor(bool highlighted, bool checked) const +{ + Shade shade = themeShade(); + + QColor color = Qt::transparent; + + if (m_explicitBackground) { + color = backgroundColor(shade); + } else if (highlighted) { + if (m_theme == Light) { + color = accentColor(shade); + if (checked) + color = color.lighter(); + } else { + // A highlighted + checked button should become darker. + color = accentColor(checked ? Shade100 : shade); + } + } else if (elevation() > 0) { + color = QColor::fromRgba(m_theme == Light ? raisedButtonColorLight + : raisedButtonColorDark); + } + + return color; +} + +QColor QQuickMaterialStyle::buttonColor() const +{ + return buttonColor(false); +} + +QColor QQuickMaterialStyle::buttonDisabledColor() const +{ + if (elevation() > 0) { + return QColor::fromRgba(m_theme == Light ? raisedButtonDisabledColorLight + : raisedButtonDisabledColorDark); + } else { + return Qt::transparent; + } +} + +QColor QQuickMaterialStyle::highlightedButtonColor() const +{ + return buttonColor(true); +} + +QColor QQuickMaterialStyle::highlightedCheckedButtonColor() const +{ + return buttonColor(true, true); +} + +QColor QQuickMaterialStyle::frameColor() const +{ + return QColor::fromRgba(m_theme == Light ? frameColorLight : frameColorDark); +} + +QColor QQuickMaterialStyle::rippleColor() const +{ + return QColor::fromRgba(m_theme == Light ? rippleColorLight : rippleColorDark); +} + +QColor QQuickMaterialStyle::highlightedRippleColor() const +{ + QColor pressColor = accentColor(); + pressColor.setAlpha(m_theme == Light ? 30 : 50); + return pressColor; +} + +QColor QQuickMaterialStyle::switchUncheckedTrackColor() const +{ + return QColor::fromRgba(m_theme == Light ? switchUncheckedTrackColorLight : switchUncheckedTrackColorDark); +} + +QColor QQuickMaterialStyle::switchCheckedTrackColor() const +{ + QColor trackColor(accentColor()); + trackColor.setAlphaF(0.5); + return trackColor; +} + +QColor QQuickMaterialStyle::switchUncheckedHandleColor() const +{ + return m_theme == Light ? color(Grey, Shade50) : color(Grey, Shade400); +} + +QColor QQuickMaterialStyle::switchCheckedHandleColor() const +{ + return m_theme == Light ? accentColor() : shade(accentColor(), Shade200); +} + +QColor QQuickMaterialStyle::switchDisabledTrackColor() const +{ + return QColor::fromRgba(m_theme == Light ? switchDisabledTrackColorLight : switchDisabledTrackColorDark); +} + +QColor QQuickMaterialStyle::switchDisabledHandleColor() const +{ + return m_theme == Light ? color(Grey, Shade400) : color(Grey, Shade800); +} + +QColor QQuickMaterialStyle::scrollBarColor() const +{ + return QColor::fromRgba(m_theme == Light ? 0x40000000 : 0x40FFFFFF); +} + +QColor QQuickMaterialStyle::scrollBarHoveredColor() const +{ + return QColor::fromRgba(m_theme == Light ? 0x60000000 : 0x60FFFFFF); +} + +QColor QQuickMaterialStyle::scrollBarPressedColor() const +{ + return QColor::fromRgba(m_theme == Light ? 0x80000000 : 0x80FFFFFF); +} + +QColor QQuickMaterialStyle::dialogColor() const +{ + if (m_hasBackground) + return backgroundColor(); + return QColor::fromRgba(m_theme == Light ? dialogColorLight : dialogColorDark); +} + +QColor QQuickMaterialStyle::backgroundDimColor() const +{ + return QColor::fromRgba(m_theme == Light ? 0x99303030 : 0x99fafafa); +} + +QColor QQuickMaterialStyle::listHighlightColor() const +{ + return QColor::fromRgba(m_theme == Light ? 0x1e000000 : 0x1effffff); +} + +QColor QQuickMaterialStyle::tooltipColor() const +{ + if (m_explicitBackground) + return backgroundColor(); + return color(Grey, Shade700); +} + +QColor QQuickMaterialStyle::toolBarColor() const +{ + if (m_explicitBackground) + return backgroundColor(); + return primaryColor(); +} + +QColor QQuickMaterialStyle::toolTextColor() const +{ + if (m_hasForeground || m_customPrimary) + return primaryTextColor(); + + switch (m_primary) { + case Red: + case Pink: + case Purple: + case DeepPurple: + case Indigo: + case Blue: + case Teal: + case DeepOrange: + case Brown: + case BlueGrey: + return QColor::fromRgba(primaryTextColorDark); + + case LightBlue: + case Cyan: + case Green: + case LightGreen: + case Lime: + case Yellow: + case Amber: + case Orange: + case Grey: + return QColor::fromRgba(primaryTextColorLight); + + default: + break; + } + + return primaryTextColor(); +} + +QColor QQuickMaterialStyle::spinBoxDisabledIconColor() const +{ + return QColor::fromRgba(m_theme == Light ? spinBoxDisabledIconColorLight : spinBoxDisabledIconColorDark); +} + +QColor QQuickMaterialStyle::sliderDisabledColor() const +{ + return QColor::fromRgba(m_theme == Light ? sliderDisabledColorLight : sliderDisabledColorDark); +} + +QColor QQuickMaterialStyle::color(QQuickMaterialStyle::Color color, QQuickMaterialStyle::Shade shade) const +{ + int count = sizeof(colors) / sizeof(colors[0]); + if (color < 0 || color >= count) + return QColor(); + + count = sizeof(colors[0]) / sizeof(colors[0][0]); + if (shade < 0 || shade >= count) + return QColor(); + + return colors[color][shade]; +} + +static QColor lighterShade(const QColor &color, qreal amount) +{ + QColor hsl = color.toHsl(); + hsl.setHslF(hsl.hueF(), hsl.saturationF(), qBound<qreal>(0.0, hsl.lightnessF() + amount, 1.0), color.alphaF()); + return hsl.convertTo(color.spec()); +} + +static QColor darkerShade(const QColor &color, qreal amount) +{ + QColor hsl = color.toHsl(); + hsl.setHslF(hsl.hueF(), hsl.saturationF(), qBound<qreal>(0.0, hsl.lightnessF() - amount, 1.0), color.alphaF()); + return hsl.convertTo(color.spec()); +} + +QQuickMaterialStyle::Shade QQuickMaterialStyle::themeShade() const +{ + return m_theme == Light ? Shade500 : Shade200; +} + +/* + * The following lightness values originate from the Material Design Color Generator project. + * + * The MIT License (MIT) + * + * Copyright (c) 2015 mbitson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// Returns the same color, if shade == themeShade() +QColor QQuickMaterialStyle::shade(const QColor &color, Shade shade) const +{ + switch (shade) { + case Shade50: + return lighterShade(color, m_theme == Light ? 0.52 : 0.26); + case Shade100: + return lighterShade(color, m_theme == Light ? 0.37 : 0.11); + case Shade200: + return m_theme == Light ? lighterShade(color, 0.26) : color; + case Shade300: + return m_theme == Light ? lighterShade(color, 0.12) : darkerShade(color, 0.14); + case Shade400: + return m_theme == Light ? lighterShade(color, 0.06) : darkerShade(color, 0.20); + case Shade500: + return m_theme == Light ? color : darkerShade(color, 0.26); + case Shade600: + return darkerShade(color, m_theme == Light ? 0.06 : 0.32); + case Shade700: + return darkerShade(color, m_theme == Light ? 0.12 : 0.38); + case Shade800: + return darkerShade(color, m_theme == Light ? 0.18 : 0.44); + case Shade900: + return darkerShade(color, m_theme == Light ? 0.24 : 0.50); + case ShadeA100: + return lighterShade(color, m_theme == Light ? 0.54 : 0.28); + case ShadeA200: + return lighterShade(color, m_theme == Light ? 0.37 : 0.11); + case ShadeA400: + return m_theme == Light ? lighterShade(color, 0.06) : darkerShade(color, 0.20); + case ShadeA700: + return darkerShade(color, m_theme == Light ? 0.12 : 0.38); + default: + Q_UNREACHABLE(); + return QColor(); + } +} + +int QQuickMaterialStyle::touchTarget() const +{ + // https://material.io/guidelines/components/buttons.html#buttons-style + return globalVariant == Dense ? 44 : 48; +} + +int QQuickMaterialStyle::buttonHeight() const +{ + // https://material.io/guidelines/components/buttons.html#buttons-style + return globalVariant == Dense ? 32 : 36; +} + +int QQuickMaterialStyle::delegateHeight() const +{ + // https://material.io/guidelines/components/lists.html#lists-specs + return globalVariant == Dense ? 40 : 48; +} + +int QQuickMaterialStyle::dialogButtonBoxHeight() const +{ + return globalVariant == Dense ? 48 : 52; +} + +int QQuickMaterialStyle::frameVerticalPadding() const +{ + return globalVariant == Dense ? 8 : 12; +} + +int QQuickMaterialStyle::menuItemHeight() const +{ + // https://material.io/guidelines/components/menus.html#menus-simple-menus + return globalVariant == Dense ? 32 : 48; +} + +int QQuickMaterialStyle::menuItemVerticalPadding() const +{ + return globalVariant == Dense ? 8 : 12; +} + +int QQuickMaterialStyle::switchDelegateVerticalPadding() const +{ + // SwitchDelegate's indicator is much larger than the others due to the shadow, + // so we must reduce its padding to ensure its implicitHeight is 40 when dense. + return globalVariant == Dense ? 4 : 8; +} + +int QQuickMaterialStyle::tooltipHeight() const +{ + // https://material.io/guidelines/components/tooltips.html + return globalVariant == Dense ? 22 : 32; +} + +QQuickMaterialStyle::Variant QQuickMaterialStyle::variant() +{ + return globalVariant; +} + +template <typename Enum> +static Enum toEnumValue(const QByteArray &value, bool *ok) +{ + QMetaEnum enumeration = QMetaEnum::fromType<Enum>(); + return static_cast<Enum>(enumeration.keyToValue(value, ok)); +} + +static QByteArray resolveSetting(const QByteArray &env, const QSharedPointer<QSettings> &settings, const QString &name) +{ + QByteArray value = qgetenv(env); +#if QT_CONFIG(settings) + if (value.isNull() && !settings.isNull()) + value = settings->value(name).toByteArray(); +#endif + return value; +} + +void QQuickMaterialStyle::initGlobals() +{ + QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(QStringLiteral("Material")); + + bool ok = false; + QByteArray themeValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_THEME", settings, QStringLiteral("Theme")); + Theme themeEnum = toEnumValue<Theme>(themeValue, &ok); + if (ok) + globalTheme = effectiveTheme(themeEnum); + else if (!themeValue.isEmpty()) + qWarning().nospace().noquote() << "Material: unknown theme value: " << themeValue; + + QByteArray variantValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_VARIANT", settings, QStringLiteral("Variant")); + Variant variantEnum = toEnumValue<Variant>(variantValue, &ok); + if (ok) + globalVariant = variantEnum; + else if (!variantValue.isEmpty()) + qWarning().nospace().noquote() << "Material: unknown variant value: " << variantValue; + + QByteArray primaryValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_PRIMARY", settings, QStringLiteral("Primary")); + Color primaryEnum = toEnumValue<Color>(primaryValue, &ok); + if (ok) { + globalPrimaryCustom = false; + globalPrimary = primaryEnum; + } else { + QColor color(primaryValue.constData()); + if (color.isValid()) { + globalPrimaryCustom = true; + globalPrimary = color.rgba(); + } else if (!primaryValue.isEmpty()) { + qWarning().nospace().noquote() << "Material: unknown primary value: " << primaryValue; + } + } + + QByteArray accentValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_ACCENT", settings, QStringLiteral("Accent")); + Color accentEnum = toEnumValue<Color>(accentValue, &ok); + if (ok) { + globalAccentCustom = false; + globalAccent = accentEnum; + } else if (!accentValue.isEmpty()) { + QColor color(accentValue.constData()); + if (color.isValid()) { + globalAccentCustom = true; + globalAccent = color.rgba(); + } else { + qWarning().nospace().noquote() << "Material: unknown accent value: " << accentValue; + } + } + + QByteArray foregroundValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_FOREGROUND", settings, QStringLiteral("Foreground")); + Color foregroundEnum = toEnumValue<Color>(foregroundValue, &ok); + if (ok) { + globalForegroundCustom = false; + globalForeground = foregroundEnum; + hasGlobalForeground = true; + } else if (!foregroundValue.isEmpty()) { + QColor color(foregroundValue.constData()); + if (color.isValid()) { + globalForegroundCustom = true; + globalForeground = color.rgba(); + hasGlobalForeground = true; + } else { + qWarning().nospace().noquote() << "Material: unknown foreground value: " << foregroundValue; + } + } + + QByteArray backgroundValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_BACKGROUND", settings, QStringLiteral("Background")); + Color backgroundEnum = toEnumValue<Color>(backgroundValue, &ok); + if (ok) { + globalBackgroundCustom = false; + globalBackground = backgroundEnum; + hasGlobalBackground = true; + } else if (!backgroundValue.isEmpty()) { + QColor color(backgroundValue.constData()); + if (color.isValid()) { + globalBackgroundCustom = true; + globalBackground = color.rgba(); + hasGlobalBackground = true; + } else { + qWarning().nospace().noquote() << "Material: unknown background value: " << backgroundValue; + } + } +} + +void QQuickMaterialStyle::attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent) +{ + Q_UNUSED(oldParent); + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(newParent); + if (material) { + inheritPrimary(material->m_primary, material->m_customPrimary); + inheritAccent(material->m_accent, material->m_customAccent); + inheritForeground(material->m_foreground, material->m_customForeground, material->m_hasForeground); + inheritBackground(material->m_background, material->m_customBackground, material->m_hasBackground); + inheritTheme(material->theme()); + } +} + +bool QQuickMaterialStyle::variantToRgba(const QVariant &var, const char *name, QRgb *rgba, bool *custom) const +{ + *custom = false; + if (var.metaType().id() == QMetaType::Int) { + int val = var.toInt(); + if (val > BlueGrey) { + qmlWarning(parent()) << "unknown Material." << name << " value: " << val; + return false; + } + *rgba = val; + } else { + int val = QMetaEnum::fromType<Color>().keyToValue(var.toByteArray()); + if (val != -1) { + *rgba = val; + } else { + QColor color(var.toString()); + if (!color.isValid()) { + qmlWarning(parent()) << "unknown Material." << name << " value: " << var.toString(); + return false; + } + *custom = true; + *rgba = color.rgba(); + } + } + return true; +} + +QT_END_NAMESPACE + +#include "moc_qquickmaterialstyle_p.cpp" diff --git a/src/quickcontrols2/material/qquickmaterialstyle_p.h b/src/quickcontrols2/material/qquickmaterialstyle_p.h new file mode 100644 index 00000000000..dea1805a567 --- /dev/null +++ b/src/quickcontrols2/material/qquickmaterialstyle_p.h @@ -0,0 +1,336 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMATERIALSTYLE_P_H +#define QQUICKMATERIALSTYLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qcolor.h> +#include <QtQuickControls2Impl/private/qquickattachedobject_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickMaterialStyle : public QQuickAttachedObject +{ + Q_OBJECT + Q_PROPERTY(Theme theme READ theme WRITE setTheme RESET resetTheme NOTIFY themeChanged FINAL) + Q_PROPERTY(QVariant primary READ primary WRITE setPrimary RESET resetPrimary NOTIFY primaryChanged FINAL) + Q_PROPERTY(QVariant accent READ accent WRITE setAccent RESET resetAccent NOTIFY accentChanged FINAL) + Q_PROPERTY(QVariant foreground READ foreground WRITE setForeground RESET resetForeground NOTIFY foregroundChanged FINAL) + Q_PROPERTY(QVariant background READ background WRITE setBackground RESET resetBackground NOTIFY backgroundChanged FINAL) + Q_PROPERTY(int elevation READ elevation WRITE setElevation RESET resetElevation NOTIFY elevationChanged FINAL) + + Q_PROPERTY(QColor primaryColor READ primaryColor NOTIFY primaryChanged FINAL) // TODO: remove? + Q_PROPERTY(QColor accentColor READ accentColor NOTIFY accentChanged FINAL) // TODO: remove? + Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY backgroundChanged FINAL) + Q_PROPERTY(QColor primaryTextColor READ primaryTextColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor primaryHighlightedTextColor READ primaryHighlightedTextColor NOTIFY primaryHighlightedTextColorChanged FINAL) + Q_PROPERTY(QColor secondaryTextColor READ secondaryTextColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor hintTextColor READ hintTextColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor textSelectionColor READ textSelectionColor NOTIFY themeOrAccentChanged FINAL) + Q_PROPERTY(QColor dropShadowColor READ dropShadowColor CONSTANT FINAL) + Q_PROPERTY(QColor dividerColor READ dividerColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor iconColor READ iconColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor iconDisabledColor READ iconDisabledColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor buttonColor READ buttonColor NOTIFY buttonColorChanged FINAL) + Q_PROPERTY(QColor buttonDisabledColor READ buttonDisabledColor NOTIFY buttonDisabledColorChanged FINAL) + Q_PROPERTY(QColor highlightedButtonColor READ highlightedButtonColor NOTIFY buttonColorChanged FINAL) + Q_PROPERTY(QColor highlightedCheckedButtonColor READ highlightedCheckedButtonColor NOTIFY buttonColorChanged FINAL REVISION(6, 2)) + Q_PROPERTY(QColor frameColor READ frameColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor rippleColor READ rippleColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor highlightedRippleColor READ highlightedRippleColor NOTIFY themeOrAccentChanged FINAL) + Q_PROPERTY(QColor switchUncheckedTrackColor READ switchUncheckedTrackColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor switchCheckedTrackColor READ switchCheckedTrackColor NOTIFY themeOrAccentChanged FINAL) + Q_PROPERTY(QColor switchUncheckedHandleColor READ switchUncheckedHandleColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor switchCheckedHandleColor READ switchCheckedHandleColor NOTIFY themeOrAccentChanged FINAL) + Q_PROPERTY(QColor switchDisabledTrackColor READ switchDisabledTrackColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor switchDisabledHandleColor READ switchDisabledHandleColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor scrollBarColor READ scrollBarColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor scrollBarHoveredColor READ scrollBarHoveredColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor scrollBarPressedColor READ scrollBarPressedColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor dialogColor READ dialogColor NOTIFY dialogColorChanged FINAL) + Q_PROPERTY(QColor backgroundDimColor READ backgroundDimColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor listHighlightColor READ listHighlightColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor tooltipColor READ tooltipColor NOTIFY tooltipColorChanged FINAL) + Q_PROPERTY(QColor toolBarColor READ toolBarColor NOTIFY toolBarColorChanged FINAL) + Q_PROPERTY(QColor toolTextColor READ toolTextColor NOTIFY toolTextColorChanged FINAL) + Q_PROPERTY(QColor spinBoxDisabledIconColor READ spinBoxDisabledIconColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor sliderDisabledColor READ sliderDisabledColor NOTIFY themeChanged FINAL REVISION(2, 15)) + + Q_PROPERTY(int touchTarget READ touchTarget CONSTANT FINAL) + Q_PROPERTY(int buttonHeight READ buttonHeight CONSTANT FINAL) + Q_PROPERTY(int delegateHeight READ delegateHeight CONSTANT FINAL) + Q_PROPERTY(int dialogButtonBoxHeight READ dialogButtonBoxHeight CONSTANT FINAL) + Q_PROPERTY(int frameVerticalPadding READ frameVerticalPadding CONSTANT FINAL) + Q_PROPERTY(int menuItemHeight READ menuItemHeight CONSTANT FINAL) + Q_PROPERTY(int menuItemVerticalPadding READ menuItemVerticalPadding CONSTANT FINAL) + Q_PROPERTY(int switchDelegateVerticalPadding READ switchDelegateVerticalPadding CONSTANT FINAL) + Q_PROPERTY(int tooltipHeight READ tooltipHeight CONSTANT FINAL) + + QML_NAMED_ELEMENT(Material) + QML_ATTACHED(QQuickMaterialStyle) + QML_UNCREATABLE("") + QML_ADDED_IN_VERSION(2, 0) + +public: + enum Theme { + Light, + Dark, + System + }; + + enum Variant { + Normal, + Dense + }; + + enum Color { + Red, + Pink, + Purple, + DeepPurple, + Indigo, + Blue, + LightBlue, + Cyan, + Teal, + Green, + LightGreen, + Lime, + Yellow, + Amber, + Orange, + DeepOrange, + Brown, + Grey, + BlueGrey + }; + + enum Shade { + Shade50, + Shade100, + Shade200, + Shade300, + Shade400, + Shade500, + Shade600, + Shade700, + Shade800, + Shade900, + ShadeA100, + ShadeA200, + ShadeA400, + ShadeA700, + }; + + Q_ENUM(Theme) + Q_ENUM(Variant) + Q_ENUM(Color) + Q_ENUM(Shade) + + explicit QQuickMaterialStyle(QObject *parent = nullptr); + + static QQuickMaterialStyle *qmlAttachedProperties(QObject *object); + + Theme theme() const; + void setTheme(Theme theme); + void inheritTheme(Theme theme); + void propagateTheme(); + void resetTheme(); + void themeChange(); + + QVariant primary() const; + void setPrimary(const QVariant &accent); + void inheritPrimary(uint primary, bool custom); + void propagatePrimary(); + void resetPrimary(); + void primaryChange(); + + QVariant accent() const; + void setAccent(const QVariant &accent); + void inheritAccent(uint accent, bool custom); + void propagateAccent(); + void resetAccent(); + void accentChange(); + + QVariant foreground() const; + void setForeground(const QVariant &foreground); + void inheritForeground(uint foreground, bool custom, bool has); + void propagateForeground(); + void resetForeground(); + void foregroundChange(); + + QVariant background() const; + void setBackground(const QVariant &background); + void inheritBackground(uint background, bool custom, bool has); + void propagateBackground(); + void resetBackground(); + void backgroundChange(); + + int elevation() const; + void setElevation(int elevation); + void resetElevation(); + void elevationChange(); + + QColor primaryColor() const; + QColor accentColor() const; + QColor backgroundColor() const; + QColor primaryTextColor() const; + QColor primaryHighlightedTextColor() const; + QColor secondaryTextColor() const; + QColor hintTextColor() const; + QColor textSelectionColor() const; + QColor dropShadowColor() const; + QColor dividerColor() const; + QColor iconColor() const; + QColor iconDisabledColor() const; + QColor buttonColor() const; + QColor buttonDisabledColor() const; + QColor highlightedButtonColor() const; + QColor highlightedCheckedButtonColor() const; + QColor highlightedButtonDisabledColor() const; + QColor frameColor() const; + QColor rippleColor() const; + QColor highlightedRippleColor() const; + QColor switchUncheckedTrackColor() const; + QColor switchCheckedTrackColor() const; + QColor switchUncheckedHandleColor() const; + QColor switchCheckedHandleColor() const; + QColor switchDisabledTrackColor() const; + QColor switchDisabledHandleColor() const; + QColor scrollBarColor() const; + QColor scrollBarHoveredColor() const; + QColor scrollBarPressedColor() const; + QColor dialogColor() const; + QColor backgroundDimColor() const; + QColor listHighlightColor() const; + QColor tooltipColor() const; + QColor toolBarColor() const; + QColor toolTextColor() const; + QColor spinBoxDisabledIconColor() const; + QColor sliderDisabledColor() const; + + Q_INVOKABLE QColor color(Color color, Shade shade = Shade500) const; + Q_INVOKABLE QColor shade(const QColor &color, Shade shade) const; + + int touchTarget() const; + int buttonHeight() const; + int delegateHeight() const; + int dialogButtonBoxHeight() const; + int frameVerticalPadding() const; + int menuItemHeight() const; + int menuItemVerticalPadding() const; + int switchDelegateVerticalPadding() const; + int tooltipHeight() const; + + static void initGlobals(); + + static Variant variant(); + +Q_SIGNALS: + void themeChanged(); + void primaryChanged(); + void accentChanged(); + void foregroundChanged(); + void backgroundChanged(); + void elevationChanged(); + + void themeOrAccentChanged(); + + void primaryHighlightedTextColorChanged(); + void buttonColorChanged(); + void buttonDisabledColorChanged(); + void dialogColorChanged(); + void tooltipColorChanged(); + void toolBarColorChanged(); + void toolTextColorChanged(); + +protected: + void attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent) override; + +private: + void init(); + bool variantToRgba(const QVariant &var, const char *name, QRgb *rgba, bool *custom) const; + + QColor backgroundColor(Shade shade) const; + QColor accentColor(Shade shade) const; + QColor buttonColor(bool highlighted, bool checked = false) const; + Shade themeShade() const; + + // These reflect whether a color value was explicitly set on the specific + // item that this attached style object represents. + bool m_explicitTheme = false; + bool m_explicitPrimary = false; + bool m_explicitAccent = false; + bool m_explicitForeground = false; + bool m_explicitBackground = false; + // These reflect whether the color value that was either inherited or + // explicitly set is in the form that QColor expects, rather than one of + // our pre-defined color enum values. + bool m_customPrimary = false; + bool m_customAccent = false; + bool m_customForeground = false; + bool m_customBackground = false; + // These will be true when this item has an explicit or inherited foreground/background + // color, or these colors were declared globally via settings (e.g. conf or env vars). + // Some color properties of the style will return different values depending on whether + // or not these are set. + bool m_hasForeground = false; + bool m_hasBackground = false; + // The actual values for this item, whether explicit, inherited or globally set. + Theme m_theme = Light; + uint m_primary = 0; + uint m_accent = 0; + uint m_foreground = 0; + uint m_background = 0; + int m_elevation = 0; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPEINFO(QQuickMaterialStyle, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKMATERIALSTYLE_P_H diff --git a/src/quickcontrols2/material/qquickmaterialtheme.cpp b/src/quickcontrols2/material/qquickmaterialtheme.cpp new file mode 100644 index 00000000000..aec9e23233d --- /dev/null +++ b/src/quickcontrols2/material/qquickmaterialtheme.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmaterialtheme_p.h" +#include "qquickmaterialstyle_p.h" + +#include <QtGui/qpa/qplatformdialoghelper.h> +#include <QtGui/qfont.h> +#include <QtGui/qfontinfo.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +QT_BEGIN_NAMESPACE + +void QQuickMaterialTheme::initialize(QQuickTheme *theme) +{ + QFont systemFont; + QFont buttonFont; + QFont toolTipFont; + QFont itemViewFont; + QFont listViewFont; + QFont menuItemFont; + QFont editorFont; + + QFont font; + font.setFamilies(QStringList{QLatin1String("Roboto")}); + QString family = QFontInfo(font).family(); + + if (family != QLatin1String("Roboto")) { + font.setFamilies(QStringList{QLatin1String("Noto")}); + family = QFontInfo(font).family(); + } + + if (family == QLatin1String("Roboto") || family == QLatin1String("Noto")) { + const QStringList families{family}; + systemFont.setFamilies(families); + buttonFont.setFamilies(families); + toolTipFont.setFamilies(families); + itemViewFont.setFamilies(families); + listViewFont.setFamilies(families); + menuItemFont.setFamilies(families); + editorFont.setFamilies(families); + } + + const bool dense = QQuickMaterialStyle::variant() == QQuickMaterialStyle::Dense; + systemFont.setPixelSize(dense ? 13 : 14); + theme->setFont(QQuickTheme::System, systemFont); + + // https://material.io/guidelines/components/buttons.html#buttons-style + buttonFont.setPixelSize(dense ? 13 : 14); + buttonFont.setCapitalization(QFont::AllUppercase); + buttonFont.setWeight(QFont::Medium); + theme->setFont(QQuickTheme::Button, buttonFont); + theme->setFont(QQuickTheme::TabBar, buttonFont); + theme->setFont(QQuickTheme::ToolBar, buttonFont); + + // https://material.io/guidelines/components/tooltips.html + toolTipFont.setPixelSize(dense ? 10 : 14); + toolTipFont.setWeight(QFont::Medium); + theme->setFont(QQuickTheme::ToolTip, toolTipFont); + + itemViewFont.setPixelSize(dense ? 13 : 14); + itemViewFont.setWeight(QFont::Medium); + theme->setFont(QQuickTheme::ItemView, itemViewFont); + + // https://material.io/guidelines/components/lists.html#lists-specs + listViewFont.setPixelSize(dense ? 13 : 16); + theme->setFont(QQuickTheme::ListView, listViewFont); + + menuItemFont.setPixelSize(dense ? 13 : 16); + theme->setFont(QQuickTheme::Menu, menuItemFont); + theme->setFont(QQuickTheme::MenuBar, menuItemFont); + theme->setFont(QQuickTheme::ComboBox, menuItemFont); + + editorFont.setPixelSize(dense ? 13 : 16); + theme->setFont(QQuickTheme::TextArea, editorFont); + theme->setFont(QQuickTheme::TextField, editorFont); + theme->setFont(QQuickTheme::SpinBox, editorFont); +} + +QT_END_NAMESPACE diff --git a/src/quickcontrols2/material/qquickmaterialtheme_p.h b/src/quickcontrols2/material/qquickmaterialtheme_p.h new file mode 100644 index 00000000000..9a1362b81cc --- /dev/null +++ b/src/quickcontrols2/material/qquickmaterialtheme_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMATERIALTHEME_P_H +#define QQUICKMATERIALTHEME_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +class QQuickTheme; + +class QQuickMaterialTheme +{ +public: + static void initialize(QQuickTheme *theme); +}; + +QT_END_NAMESPACE + +#endif // QQUICKMATERIALTHEME_P_H diff --git a/src/quickcontrols2/material/qt_attribution.json b/src/quickcontrols2/material/qt_attribution.json new file mode 100644 index 00000000000..85fdadf9e06 --- /dev/null +++ b/src/quickcontrols2/material/qt_attribution.json @@ -0,0 +1,13 @@ +{ + "Id": "shadow_angular_material", + "Name": "Shadow values from Angular Material", + "QDocModule": "qtquickcontrols", + "QtUsage": "Used in the Material Style of Qt Quick Controls 2.", + "Files": "ElevationEffect.qml", + "Description": "Shadow values for the elevation effect.", + "Homepage": "https://angularjs.org/", + "License": "MIT License", + "LicenseId": "MIT", + "LicenseFile": "LICENSE_ANGULARJS.txt", + "Copyright": "Copyright (c) 2014-2016 Google, Inc" +} diff --git a/src/quickcontrols2/material/qtquickcontrols2materialstyleplugin.cpp b/src/quickcontrols2/material/qtquickcontrols2materialstyleplugin.cpp new file mode 100644 index 00000000000..25807eecf7e --- /dev/null +++ b/src/quickcontrols2/material/qtquickcontrols2materialstyleplugin.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmaterialstyle_p.h" +#include "qquickmaterialtheme_p.h" + +#include <QtQuickControls2/private/qquickstyleplugin_p.h> +#include <QtQuickControls2Impl/private/qquickpaddedrectangle_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +extern void qml_register_types_QtQuick_Controls_Material(); +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Controls_Material); + +QT_BEGIN_NAMESPACE + +class QtQuickControls2MaterialStylePlugin : public QQuickStylePlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtQuickControls2MaterialStylePlugin(QObject *parent = nullptr); + + QString name() const override; + void initializeTheme(QQuickTheme *theme) override; + + QQuickMaterialTheme theme; +}; + +QtQuickControls2MaterialStylePlugin::QtQuickControls2MaterialStylePlugin(QObject *parent) : QQuickStylePlugin(parent) +{ + volatile auto registration = &qml_register_types_QtQuick_Controls_Material; + Q_UNUSED(registration); +} + +QString QtQuickControls2MaterialStylePlugin::name() const +{ + return QStringLiteral("Material"); +} + +void QtQuickControls2MaterialStylePlugin::initializeTheme(QQuickTheme *theme) +{ + QQuickMaterialStyle::initGlobals(); + this->theme.initialize(theme); +} + +QT_END_NAMESPACE + +#include "qtquickcontrols2materialstyleplugin.moc" diff --git a/src/quickcontrols2/material/qtquickcontrols2materialstyleplugin.qrc b/src/quickcontrols2/material/qtquickcontrols2materialstyleplugin.qrc new file mode 100644 index 00000000000..981960c4400 --- /dev/null +++ b/src/quickcontrols2/material/qtquickcontrols2materialstyleplugin.qrc @@ -0,0 +1,20 @@ +<RCC> + <qresource prefix="/qt-project.org/imports/QtQuick/Controls/Material"> + <file>images/arrow-indicator.png</file> + <file>images/arrow-indicator@2x.png</file> + <file>images/arrow-indicator@3x.png</file> + <file>images/arrow-indicator@4x.png</file> + <file>images/check.png</file> + <file>images/check@2x.png</file> + <file>images/check@3x.png</file> + <file>images/check@4x.png</file> + <file>images/drop-indicator.png</file> + <file>images/drop-indicator@2x.png</file> + <file>images/drop-indicator@3x.png</file> + <file>images/drop-indicator@4x.png</file> + <file>shaders/RectangularGlow.frag</file> + <file>shaders/+glslcore/RectangularGlow.frag</file> + <file>shaders/+hlsl/RectangularGlow.frag</file> + <file>shaders/+qsb/RectangularGlow.frag</file> + </qresource> +</RCC> diff --git a/src/quickcontrols2/material/shaders/+glslcore/RectangularGlow.frag b/src/quickcontrols2/material/shaders/+glslcore/RectangularGlow.frag new file mode 100644 index 00000000000..432d86b5d5f --- /dev/null +++ b/src/quickcontrols2/material/shaders/+glslcore/RectangularGlow.frag @@ -0,0 +1,25 @@ +#version 150 + +uniform float qt_Opacity; +uniform float relativeSizeX; +uniform float relativeSizeY; +uniform float spread; +uniform vec4 color; + +in vec2 qt_TexCoord0; +out vec4 fragColor; + +float linearstep(float e0, float e1, float x) +{ + return clamp((x - e0) / (e1 - e0), 0.0, 1.0); +} + +void main() +{ + float alpha = + smoothstep(0.0, relativeSizeX, 0.5 - abs(0.5 - qt_TexCoord0.x)) * + smoothstep(0.0, relativeSizeY, 0.5 - abs(0.5 - qt_TexCoord0.y)); + + float spreadMultiplier = linearstep(spread, 1.0 - spread, alpha); + fragColor = color * qt_Opacity * spreadMultiplier * spreadMultiplier; +} diff --git a/src/quickcontrols2/material/shaders/+hlsl/RectangularGlow.frag b/src/quickcontrols2/material/shaders/+hlsl/RectangularGlow.frag new file mode 100644 index 00000000000..69d9f852fb4 --- /dev/null +++ b/src/quickcontrols2/material/shaders/+hlsl/RectangularGlow.frag @@ -0,0 +1,21 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float relativeSizeX; + float relativeSizeY; + float spread; + float4 color; +} + +float linearstep(float e0, float e1, float x) { return clamp((x - e0) / (e1 - e0), 0.0, 1.0); } + +float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET +{ + float alpha = + smoothstep(0.0, relativeSizeX, 0.5 - abs(0.5 - coord.x)) * + smoothstep(0.0, relativeSizeY, 0.5 - abs(0.5 - coord.y)); + + float spreadMultiplier = linearstep(spread, 1.0 - spread, alpha); + return color * qt_Opacity * spreadMultiplier * spreadMultiplier; +} diff --git a/src/quickcontrols2/material/shaders/+qsb/RectangularGlow.frag b/src/quickcontrols2/material/shaders/+qsb/RectangularGlow.frag new file mode 100644 index 00000000000..5cfa2db6ed0 Binary files /dev/null and b/src/quickcontrols2/material/shaders/+qsb/RectangularGlow.frag differ diff --git a/src/quickcontrols2/material/shaders/RectangularGlow.frag b/src/quickcontrols2/material/shaders/RectangularGlow.frag new file mode 100644 index 00000000000..40bab5806cc --- /dev/null +++ b/src/quickcontrols2/material/shaders/RectangularGlow.frag @@ -0,0 +1,19 @@ +uniform highp float qt_Opacity; +uniform mediump float relativeSizeX; +uniform mediump float relativeSizeY; +uniform mediump float spread; +uniform lowp vec4 color; +varying highp vec2 qt_TexCoord0; + +highp float linearstep(highp float e0, highp float e1, highp float x) { + return clamp((x - e0) / (e1 - e0), 0.0, 1.0); +} + +void main() { + lowp float alpha = + smoothstep(0.0, relativeSizeX, 0.5 - abs(0.5 - qt_TexCoord0.x)) * + smoothstep(0.0, relativeSizeY, 0.5 - abs(0.5 - qt_TexCoord0.y)); + + highp float spreadMultiplier = linearstep(spread, 1.0 - spread, alpha); + gl_FragColor = color * qt_Opacity * spreadMultiplier * spreadMultiplier; +} diff --git a/src/quickcontrols2/material/shaders/RectangularGlow_rhi.frag b/src/quickcontrols2/material/shaders/RectangularGlow_rhi.frag new file mode 100644 index 00000000000..3e7d2dfe6fd --- /dev/null +++ b/src/quickcontrols2/material/shaders/RectangularGlow_rhi.frag @@ -0,0 +1,28 @@ +#version 440 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float relativeSizeX; + float relativeSizeY; + float spread; + vec4 color; +} ubuf; + +float linearstep(float e0, float e1, float x) +{ + return clamp((x - e0) / (e1 - e0), 0.0, 1.0); +} + +void main() +{ + float alpha = + smoothstep(0.0, ubuf.relativeSizeX, 0.5 - abs(0.5 - qt_TexCoord0.x)) * + smoothstep(0.0, ubuf.relativeSizeY, 0.5 - abs(0.5 - qt_TexCoord0.y)); + + float spreadMultiplier = linearstep(ubuf.spread, 1.0 - ubuf.spread, alpha); + fragColor = ubuf.color * ubuf.qt_Opacity * spreadMultiplier * spreadMultiplier; +} diff --git a/src/quickcontrols2/material/shaders/compile.bat b/src/quickcontrols2/material/shaders/compile.bat new file mode 100644 index 00000000000..e87efa7a6df --- /dev/null +++ b/src/quickcontrols2/material/shaders/compile.bat @@ -0,0 +1,40 @@ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Copyright (C) 2019 The Qt Company Ltd. +:: Contact: https://www.qt.io/licensing/ +:: +:: This file is part of the QtQuick module 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$ +:: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -o +qsb/RectangularGlow.frag RectangularGlow_rhi.frag diff --git a/src/quickcontrols2/qquickstyle.cpp b/src/quickcontrols2/qquickstyle.cpp new file mode 100644 index 00000000000..3ba0ad0610d --- /dev/null +++ b/src/quickcontrols2/qquickstyle.cpp @@ -0,0 +1,501 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyle.h" +#include "qquickstyle_p.h" + +#include <QtCore/qdir.h> +#include <QtCore/qfile.h> +#include <QtCore/qdebug.h> +#include <QtCore/qsettings.h> +#include <QtCore/qfileselector.h> +#include <QtCore/qlibraryinfo.h> +#include <QtCore/qloggingcategory.h> +#include <QtCore/qmetaobject.h> +#include <QtGui/qcolor.h> +#include <QtGui/qfont.h> +#include <QtGui/qpalette.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtQml/private/qqmlmetatype_p.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlfile.h> + +#include <functional> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcQtQuickControlsStyle, "qt.quick.controls.style") + +/*! + \class QQuickStyle + \brief The QQuickStyle class allows configuring the application style. + \inmodule QtQuickControls2 + \since 5.7 + + QQuickStyle provides API for querying and configuring the application + \l {Styling Qt Quick Controls}{styles} of Qt Quick Controls. + + \code + #include <QGuiApplication> + #include <QQmlApplicationEngine> + #include <QQuickStyle> + + int main(int argc, char *argv[]) + { + QGuiApplication app(argc, argv); + + QQuickStyle::setStyle("Material"); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/main.qml")); + + return app.exec(); + } + \endcode + + \note The style must be configured \b before loading QML that imports + Qt Quick Controls. It is not possible to change the style after the QML + types have been registered. + + \note QQuickStyle is not supported when using + \l {Compile-Time Style Selection}{compile-time style selection}. + + To create your own custom style, see \l {Creating a Custom Style}. Custom + styles do not need to implement all controls. By default, the styling + system uses the \l {Basic style} as a fallback for controls that a custom + style does not provide. It is possible to specify a different fallback + style to customize or extend one of the built-in styles. + + \code + QQuickStyle::setStyle("MyStyle"); + QQuickStyle::setFallbackStyle("Material"); + \endcode + + \sa {Styling Qt Quick Controls} +*/ + +struct QQuickStyleSpec +{ + QQuickStyleSpec() { } + + QString name() + { + if (!resolved) + resolve(); + return style.mid(style.lastIndexOf(QLatin1Char('/')) + 1); + } + + QString path() + { + if (!resolved) + resolve(); + QString s = style; + if (QQmlFile::isLocalFile(s)) + s = QQmlFile::urlToLocalFileOrQrc(s); + return s.left(s.lastIndexOf(QLatin1Char('/')) + 1); + } + + void setStyle(const QString &s) + { + qCDebug(lcQtQuickControlsStyle) << "style" << s << "set on QQuickStyleSpec"; + if (s.contains(QLatin1Char('/'))) { + qWarning() << "Style names must not contain paths; see the \"Definition of a Style\" documentation for more information"; + return; + } + + qCDebug(lcQtQuickControlsStyle) << "clearing resolved flag and resolving"; + style = s; + resolved = false; + resolve(); + } + + void setFallbackStyle(const QString &fallback, const QByteArray &method) + { + if (!fallback.isEmpty()) + qCDebug(lcQtQuickControlsStyle) << "fallback style" << fallback << "set on QQuickStyleSpec via" << method; + + fallbackStyle = fallback; + fallbackMethod = method; + } + + void resolve() + { + qCDebug(lcQtQuickControlsStyle) << "resolving style"; + + if (style.isEmpty()) + style = QGuiApplicationPrivate::styleOverride; + if (style.isEmpty()) + style = QString::fromLocal8Bit(qgetenv("QT_QUICK_CONTROLS_STYLE")); + if (fallbackStyle.isEmpty()) + setFallbackStyle(QString::fromLocal8Bit(qgetenv("QT_QUICK_CONTROLS_FALLBACK_STYLE")), "QT_QUICK_CONTROLS_FALLBACK_STYLE"); +#if QT_CONFIG(settings) + if (style.isEmpty() || fallbackStyle.isEmpty()) { + QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(QStringLiteral("Controls")); + if (settings) { + if (style.isEmpty()) + style = settings->value(QStringLiteral("Style")).toString(); + if (fallbackStyle.isEmpty()) + setFallbackStyle(settings->value(QStringLiteral("FallbackStyle")).toString(), ":/qtquickcontrols2.conf"); + } + } +#endif + + auto builtInStyleList = QQuickStylePrivate::builtInStyles(); + if (!fallbackStyle.isEmpty() && !builtInStyleList.contains(fallbackStyle)) { + qWarning().nospace().noquote() << fallbackMethod << ": the specified fallback style \"" << + fallbackStyle << "\" is not one of the built-in Qt Quick Controls 2 styles"; + fallbackStyle.clear(); + } + + // Find the config file. + resolveConfigFilePath(); + + usingDefaultStyle = false; + + if (style.isEmpty() || style.toLower() == QStringLiteral("default")) { + usingDefaultStyle = true; + style.clear(); + + qCDebug(lcQtQuickControlsStyle) << "no style (or Default) was specified;" + << "checking if we have an appropriate style for this platform"; + + // If these defaults are changed, ensure that the "Using Styles in Qt Quick Controls" + // section of qtquickcontrols2-styles.qdoc is updated. +#if defined(Q_OS_MACOS) + style = QLatin1String("macOS"); +#elif defined(Q_OS_WINDOWS) + style = QLatin1String("Windows"); +#elif defined(Q_OS_ANDROID) + style = QLatin1String("Material"); +#elif defined(Q_OS_LINUX) + style = QLatin1String("Fusion"); +#endif + if (!style.isEmpty()) + qCDebug(lcQtQuickControlsStyle) << "using" << style << "as a default"; + else + qCDebug(lcQtQuickControlsStyle) << "no appropriate style found; using Basic as a default"; + } + + // If it's still empty by this point, then it means we have no native style available for this platform, + // as is the case on e.g. embedded. In that case, we want to default to the Basic style, + // which is what effectiveStyleName() returns when "style" is empty. + custom = !builtInStyleList.contains(QQuickStylePrivate::effectiveStyleName(style)); + + resolved = true; + + qCDebug(lcQtQuickControlsStyle).nospace() << "done resolving:" + << "\n style=" << style + << "\n custom=" << custom + << "\n resolved=" << resolved + << "\n fallbackStyle=" << fallbackStyle + << "\n fallbackMethod=" << fallbackMethod + << "\n configFilePath=" << configFilePath; + } + + void reset() + { + qCDebug(lcQtQuickControlsStyle) << "resetting values to their defaults"; + + custom = false; + resolved = false; + usingDefaultStyle = false; + style.clear(); + fallbackStyle.clear(); + fallbackMethod.clear(); + configFilePath.clear(); + } + + QString resolveConfigFilePath() + { + if (configFilePath.isEmpty()) { + configFilePath = QFile::decodeName(qgetenv("QT_QUICK_CONTROLS_CONF")); + if (configFilePath.isEmpty() || !QFile::exists(configFilePath)) { + if (!configFilePath.isEmpty()) + qWarning("QT_QUICK_CONTROLS_CONF=%s: No such file", qPrintable(configFilePath)); + + configFilePath = QStringLiteral(":/qtquickcontrols2.conf"); + } + } + return configFilePath; + } + + // Is this a custom style defined by the user and not "built-in" style? + bool custom = false; + // Have we resolved the style yet? + bool resolved = false; + // Are we using the default style for this platform (because no style was specified)? + bool usingDefaultStyle = false; + // The name of the style. + QString style; + // The built-in style to use if the requested style cannot be found. + QString fallbackStyle; + // A description of the way in which fallbackStyle was set, used in e.g. warning messages shown to the user. + QByteArray fallbackMethod; + // The path to the qtquickcontrols2.conf file. + QString configFilePath; +}; + +Q_GLOBAL_STATIC(QQuickStyleSpec, styleSpec) + +/* + Note that most of these functions (with the exception of e.g. isResolved()) + should not be called before the style has been resolved, as it's only after + that happens that they will have been set. +*/ +QString QQuickStylePrivate::style() +{ + return styleSpec()->style; +} + +QString QQuickStylePrivate::effectiveStyleName(const QString &styleName) +{ + return !styleName.isEmpty() ? styleName : QLatin1String("Basic"); +} + +QString QQuickStylePrivate::fallbackStyle() +{ + return styleSpec()->fallbackStyle; +} + +bool QQuickStylePrivate::isCustomStyle() +{ + return styleSpec()->custom; +} + +bool QQuickStylePrivate::isResolved() +{ + return styleSpec()->resolved; +} + +bool QQuickStylePrivate::isUsingDefaultStyle() +{ + return styleSpec()->usingDefaultStyle; +} + +void QQuickStylePrivate::init() +{ + QQuickStyleSpec *spec = styleSpec(); + spec->resolve(); +} + +void QQuickStylePrivate::reset() +{ + if (styleSpec()) + styleSpec()->reset(); +} + +QString QQuickStylePrivate::configFilePath() +{ + return styleSpec()->resolveConfigFilePath(); +} + +QSharedPointer<QSettings> QQuickStylePrivate::settings(const QString &group) +{ +#ifndef QT_NO_SETTINGS + const QString filePath = QQuickStylePrivate::configFilePath(); + if (QFile::exists(filePath)) { + QFileSelector selector; + QSettings *settings = new QSettings(selector.select(filePath), QSettings::IniFormat); + if (!group.isEmpty()) + settings->beginGroup(group); + return QSharedPointer<QSettings>(settings); + } +#endif // QT_NO_SETTINGS + return QSharedPointer<QSettings>(); +} + +#if QT_CONFIG(settings) +static void readValue(const QSharedPointer<QSettings> &settings, const QString &name, std::function<void(const QVariant &)> setValue) +{ + const QVariant var = settings->value(name); + if (var.isValid()) + setValue(var); +} + +template <typename Enum> +static Enum toEnumValue(const QVariant &var) +{ + // ### TODO: expose QFont enums to the meta object system using Q_ENUM + //QMetaEnum enumeration = QMetaEnum::fromType<Enum>(); + //bool ok = false; + //int value = enumeration.keyToValue(var.toByteArray(), &ok); + //if (!ok) + // value = var.toInt(); + //return static_cast<Enum>(value); + + return static_cast<Enum>(var.toInt()); +} + +const QFont *QQuickStylePrivate::readFont(const QSharedPointer<QSettings> &settings) +{ + const QVariant var = settings->value(QStringLiteral("Font")); + if (var.isValid()) + return new QFont(var.value<QFont>()); + + QFont f; + settings->beginGroup(QStringLiteral("Font")); + readValue(settings, QStringLiteral("Family"), [&f](const QVariant &var) { f.setFamilies(QStringList{var.toString()}); }); + readValue(settings, QStringLiteral("PointSize"), [&f](const QVariant &var) { f.setPointSizeF(var.toReal()); }); + readValue(settings, QStringLiteral("PixelSize"), [&f](const QVariant &var) { f.setPixelSize(var.toInt()); }); + readValue(settings, QStringLiteral("StyleHint"), [&f](const QVariant &var) { f.setStyleHint(toEnumValue<QFont::StyleHint>(var.toInt())); }); + readValue(settings, QStringLiteral("Weight"), [&f](const QVariant &var) { f.setWeight(toEnumValue<QFont::Weight>(var)); }); + readValue(settings, QStringLiteral("Style"), [&f](const QVariant &var) { f.setStyle(toEnumValue<QFont::Style>(var.toInt())); }); + settings->endGroup(); + return new QFont(f); +} + +static void readColorGroup(const QSharedPointer<QSettings> &settings, QPalette::ColorGroup group, QPalette *palette) +{ + const QStringList keys = settings->childKeys(); + if (keys.isEmpty()) + return; + + static const int index = QPalette::staticMetaObject.indexOfEnumerator("ColorRole"); + Q_ASSERT(index != -1); + QMetaEnum metaEnum = QPalette::staticMetaObject.enumerator(index); + + for (const QString &key : keys) { + bool ok = false; + int role = metaEnum.keyToValue(key.toUtf8(), &ok); + if (ok) + palette->setColor(group, static_cast<QPalette::ColorRole>(role), settings->value(key).value<QColor>()); + } +} + +const QPalette *QQuickStylePrivate::readPalette(const QSharedPointer<QSettings> &settings) +{ + QPalette p; + settings->beginGroup(QStringLiteral("Palette")); + readColorGroup(settings, QPalette::All, &p); + + settings->beginGroup(QStringLiteral("Normal")); + readColorGroup(settings, QPalette::Normal, &p); + settings->endGroup(); + + settings->beginGroup(QStringLiteral("Disabled")); + readColorGroup(settings, QPalette::Disabled, &p); + settings->endGroup(); + return new QPalette(p); +} +#endif // QT_CONFIG(settings) + +bool QQuickStylePrivate::isDarkSystemTheme() +{ + const static bool dark = [](){ + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + return theme->appearance() == QPlatformTheme::Appearance::Dark; + return false; + }(); + return dark; +} + +QStringList QQuickStylePrivate::builtInStyles() +{ + return { + QLatin1String("Basic"), + QLatin1String("Fusion"), + QLatin1String("Imagine"), +#ifdef Q_OS_MACOS + QLatin1String("macOS"), +#endif + QLatin1String("Material"), + QLatin1String("Universal"), +#ifdef Q_OS_WINDOWS + QLatin1String("Windows") +#endif + }; +} + +/*! + Returns the name of the application style. + + \note The application style can be specified by passing a \c -style command + line argument. Therefore \c name() may not return a fully resolved + value if called before constructing a QGuiApplication. +*/ +QString QQuickStyle::name() +{ + return styleSpec()->name(); +} + +/*! + Sets the application style to \a style. + + \note The style must be configured \b before loading QML that imports Qt Quick Controls. + It is not possible to change the style after the QML types have been registered. + + \sa setFallbackStyle(), {Using Styles in Qt Quick Controls} +*/ +void QQuickStyle::setStyle(const QString &style) +{ + qCDebug(lcQtQuickControlsStyle) << "setStyle called with" << style; + + if (QQmlMetaType::matchingModuleVersion( + QStringLiteral("QtQuick.Controls"), QTypeRevision::fromVersion(2, 0)).isValid()) { + qWarning() << "ERROR: QQuickStyle::setStyle() must be called before loading QML that imports Qt Quick Controls 2."; + return; + } + + styleSpec()->setStyle(style); +} + +/*! + \since 5.8 + Sets the application fallback style to \a style. + + \note The fallback style must be the name of one of the built-in Qt Quick Controls styles, e.g. "Material". + + \note The style must be configured \b before loading QML that imports Qt Quick Controls. + It is not possible to change the style after the QML types have been registered. + + The fallback style can be also specified by setting the \c QT_QUICK_CONTROLS_FALLBACK_STYLE + \l {Supported Environment Variables in Qt Quick Controls}{environment variable}. + + \sa setStyle(), {Using Styles in Qt Quick Controls} +*/ +void QQuickStyle::setFallbackStyle(const QString &style) +{ + if (QQmlMetaType::matchingModuleVersion( + QStringLiteral("QtQuick.Controls"), QTypeRevision::fromVersion(2, 0)).isValid()) { + qWarning() << "ERROR: QQuickStyle::setFallbackStyle() must be called before loading QML that imports Qt Quick Controls 2."; + return; + } + + styleSpec()->setFallbackStyle(style, "QQuickStyle::setFallbackStyle()"); +} + +QT_END_NAMESPACE diff --git a/src/quickcontrols2/qquickstyle.h b/src/quickcontrols2/qquickstyle.h new file mode 100644 index 00000000000..e26ec90be3a --- /dev/null +++ b/src/quickcontrols2/qquickstyle.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLE_H +#define QQUICKSTYLE_H + +#include <QtCore/qurl.h> +#include <QtCore/qstring.h> +#include <QtQuickControls2/qtquickcontrols2global.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKCONTROLS2_EXPORT QQuickStyle +{ +public: + static QString name(); + static void setStyle(const QString &style); + static void setFallbackStyle(const QString &style); +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLE_H diff --git a/src/quickcontrols2/qquickstyle_p.h b/src/quickcontrols2/qquickstyle_p.h new file mode 100644 index 00000000000..31c7089379f --- /dev/null +++ b/src/quickcontrols2/qquickstyle_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLE_P_H +#define QQUICKSTYLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qsharedpointer.h> +#include <QtQuickControls2/qtquickcontrols2global.h> + +QT_BEGIN_NAMESPACE + +class QSettings; + +class Q_QUICKCONTROLS2_EXPORT QQuickStylePrivate +{ +public: + static QString style(); + static QString effectiveStyleName(const QString &styleName); + static QString fallbackStyle(); + static bool isCustomStyle(); + static bool isResolved(); + static bool isUsingDefaultStyle(); + static bool exists(); + static void init(); + static void reset(); + static QString configFilePath(); + static QSharedPointer<QSettings> settings(const QString &group = QString()); + static const QFont *readFont(const QSharedPointer<QSettings> &settings); + static const QPalette *readPalette(const QSharedPointer<QSettings> &settings); + static bool isDarkSystemTheme(); + static QStringList builtInStyles(); +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLE_P_H diff --git a/src/quickcontrols2/qquickstyleplugin.cpp b/src/quickcontrols2/qquickstyleplugin.cpp new file mode 100644 index 00000000000..b396508ebf7 --- /dev/null +++ b/src/quickcontrols2/qquickstyleplugin.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyle.h" +#include "qquickstyle_p.h" +#include "qquickstyleplugin_p.h" + +#include <QtCore/private/qfileselector_p.h> +#include <QtCore/qloggingcategory.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlfile.h> +#include <QtQml/private/qqmlmetatype_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p_p.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcStylePlugin, "qt.quick.controls.styleplugin") + +QQuickStylePlugin::QQuickStylePlugin(QObject *parent) + : QQmlExtensionPlugin(parent) +{ +} + +QQuickStylePlugin::~QQuickStylePlugin() +{ +} + +void QQuickStylePlugin::registerTypes(const char *uri) +{ + qCDebug(lcStylePlugin).nospace() << "registerTypes called with uri " << uri << "; plugin name is " << name(); + + const QTypeRevision latestControlsRevision = QQmlMetaType::latestModuleVersion(QLatin1String("QtQuick.Controls")); + // Use the private function because we don't want to cause resolve() to be called, + // as the logic that assigns a default style if one wasn't set would interfere with compile-time style selection. + QString styleName = QQuickStylePrivate::style(); + if (!latestControlsRevision.isValid() && styleName.isEmpty()) { + // The user hasn't imported QtQuick.Controls, nor set a style via the runtime methods. + qCDebug(lcStylePlugin).nospace() << uri << " imported before QtQuick.Controls; using compile-time style selection"; + QQuickStyle::setStyle(name()); + styleName = name(); + } + + // Even if this style plugin isn't for the style set by the user, + // we still want to create the theme object, because that function + // is also responsible for reading values from qtquickcontrols2.conf. + // So, even if a style doesn't have a QQuickTheme, it can still have + // values set for (e.g. fonts and palettes) in qtquickcontrols2.conf. + const QString effectiveCurrentStyleName = QQuickStylePrivate::effectiveStyleName(styleName); + auto theme = QQuickTheme::instance(); + if (!theme) { + qCDebug(lcStylePlugin) << "creating theme"; + theme = createTheme(effectiveCurrentStyleName); + } + + if (name() != effectiveCurrentStyleName) { + qCDebug(lcStylePlugin).nospace() << "theme does not belong to current style (" + << effectiveCurrentStyleName << "); not calling initializeTheme()"; + return; + } + + qCDebug(lcStylePlugin) << "theme has not yet been initialized; calling initializeTheme()"; + initializeTheme(theme); + + if (!styleName.isEmpty()) + QFileSelectorPrivate::addStatics(QStringList() << styleName); +} + +void QQuickStylePlugin::unregisterTypes() +{ + qCDebug(lcStylePlugin) << "unregisterTypes called; plugin name is" << name(); + if (!QQuickThemePrivate::instance) + return; + + // Not every style has a plugin - some styles are QML-only. So, we clean this + // stuff up when the first style plugin is unregistered rather than when the + // plugin for the current style is unregistered. + QQuickThemePrivate::instance.reset(); + QQuickStylePrivate::reset(); +} + +/*! + \internal + + Responsible for setting the font and palette settings that were specified in the + qtquickcontrols2.conf file. + + Style-specific settings (e.g. Variant=Dense) are read in the constructor of the + appropriate style plugin (e.g. QtQuickControls2MaterialStylePlugin). + + Implicit style-specific font and palette values are assigned in the relevant theme + (e.g. QQuickMaterialTheme). +*/ +QQuickTheme *QQuickStylePlugin::createTheme(const QString &name) +{ + qCDebug(lcStylePlugin) << "creating QQuickTheme instance to be initialized by style-specific theme of" << name; + + QQuickTheme *theme = new QQuickTheme; +#if QT_CONFIG(settings) + QQuickThemePrivate *p = QQuickThemePrivate::get(theme); + QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(name); + if (settings) { + p->defaultFont.reset(QQuickStylePrivate::readFont(settings)); + // Set the default font as the System scope, because that's what + // QQuickControlPrivate::parentFont() uses as its fallback if no + // parent item has a font explicitly set. QQuickControlPrivate::parentFont() + // is used as the starting point for font inheritance/resolution. + // The same goes for palettes below. + theme->setFont(QQuickTheme::System, *p->defaultFont); + + p->defaultPalette.reset(QQuickStylePrivate::readPalette(settings)); + theme->setPalette(QQuickTheme::System, *p->defaultPalette); + } +#endif + QQuickThemePrivate::instance.reset(theme); + return theme; +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleplugin_p.cpp" diff --git a/src/quickcontrols2/qquickstyleplugin_p.h b/src/quickcontrols2/qquickstyleplugin_p.h new file mode 100644 index 00000000000..0cc793a28dd --- /dev/null +++ b/src/quickcontrols2/qquickstyleplugin_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEPLUGIN_P_H +#define QQUICKSTYLEPLUGIN_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/qqmlextensionplugin.h> +#include <QtQuickControls2/qtquickcontrols2global.h> + +QT_BEGIN_NAMESPACE + +class QQuickTheme; + +class Q_QUICKCONTROLS2_EXPORT QQuickStylePlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + +public: + explicit QQuickStylePlugin(QObject *parent = nullptr); + ~QQuickStylePlugin(); + + virtual QString name() const = 0; + virtual void initializeTheme(QQuickTheme *theme) = 0; + + void registerTypes(const char *uri) override; + void unregisterTypes() override; + +private: + QQuickTheme *createTheme(const QString &name); + + Q_DISABLE_COPY(QQuickStylePlugin) +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEPLUGIN_P_H diff --git a/src/quickcontrols2/qt_cmdline.cmake b/src/quickcontrols2/qt_cmdline.cmake new file mode 100644 index 00000000000..b1e98c9ac85 --- /dev/null +++ b/src/quickcontrols2/qt_cmdline.cmake @@ -0,0 +1,6 @@ +qt_commandline_option(style-fusion TYPE boolean NAME quickcontrols2-fusion) +qt_commandline_option(style-imagine TYPE boolean NAME quickcontrols2-imagine) +qt_commandline_option(style-material TYPE boolean NAME quickcontrols2-material) +qt_commandline_option(style-universal TYPE boolean NAME quickcontrols2-universal) +qt_commandline_option(style-macos TYPE boolean NAME quickcontrols2-macos) +qt_commandline_option(style-windows TYPE boolean NAME quickcontrols2-windows) diff --git a/src/quickcontrols2/qtquickcontrols2global.h b/src/quickcontrols2/qtquickcontrols2global.h new file mode 100644 index 00000000000..e5f050ce1e7 --- /dev/null +++ b/src/quickcontrols2/qtquickcontrols2global.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTQUICKCONTROLS2GLOBAL_H +#define QTQUICKCONTROLS2GLOBAL_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +#ifndef QT_STATIC +# if defined(QT_BUILD_QUICKCONTROLS2_LIB) +# define Q_QUICKCONTROLS2_EXPORT Q_DECL_EXPORT +# else +# define Q_QUICKCONTROLS2_EXPORT Q_DECL_IMPORT +# endif +#else +# define Q_QUICKCONTROLS2_EXPORT +#endif + +QT_END_NAMESPACE + +Q_QUICKCONTROLS2_EXPORT void qml_register_types_QtQuick_Controls(); + +#endif // QTQUICKCONTROLS2GLOBAL_H diff --git a/src/quickcontrols2/qtquickcontrols2plugin.cpp b/src/quickcontrols2/qtquickcontrols2plugin.cpp new file mode 100644 index 00000000000..7b0f43ca656 --- /dev/null +++ b/src/quickcontrols2/qtquickcontrols2plugin.cpp @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/private/qfileselector_p.h> +#include <QtCore/qloggingcategory.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlextensionplugin.h> +#include <QtQuickTemplates2/private/qquicktheme_p_p.h> +#include <QtQuickControls2/private/qquickstyle_p.h> +#include <QtQuickControls2/private/qquickstyleplugin_p.h> +#include <QtQuickControls2/qquickstyle.h> +#include <QtQuickControls2/qtquickcontrols2global.h> + +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Controls); + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcQtQuickControls2Plugin, "qt.quick.controls.qtquickcontrols2plugin") + +class QtQuickControls2Plugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtQuickControls2Plugin(QObject *parent = nullptr); + ~QtQuickControls2Plugin(); + + void registerTypes(const char *uri) override; + void unregisterTypes() override; + +private: + // We store these because the style plugins can be unregistered before + // QtQuickControls2Plugin, and since QQuickStylePlugin calls QQuickStylePrivate::reset(), + // the style information can be lost when it comes time to call qmlUnregisterModuleImport(). + // It also avoids unnecessarily resolving the style after resetting it just to get the style + // name in unregisterTypes(). + bool customStyle = false; + QString registeredStyleUri; + QString registeredFallbackStyleUri; +}; + +static const char *qtQuickControlsUri = "QtQuick.Controls"; + +QString styleUri() +{ + const QString style = QQuickStyle::name(); + if (!QQuickStylePrivate::isCustomStyle()) { + // The style set is a built-in style. + const QString styleName = QQuickStylePrivate::effectiveStyleName(style); + return QString::fromLatin1("QtQuick.Controls.%1").arg(styleName); + } + + // This is a custom style, so just use the name as the import uri. + QString styleName = style; + if (styleName.startsWith(QLatin1String(":/"))) + styleName.remove(0, 2); + return styleName; +} + +QString fallbackStyleUri() +{ + // The fallback style must be a built-in style, so we don't need to check for custom styles here. + const QString fallbackStyle = QQuickStylePrivate::fallbackStyle(); + const QString fallbackStyleName = QQuickStylePrivate::effectiveStyleName(fallbackStyle); + return QString::fromLatin1("QtQuick.Controls.%1").arg(fallbackStyleName); +} + +QtQuickControls2Plugin::QtQuickControls2Plugin(QObject *parent) : QQmlExtensionPlugin(parent) +{ + volatile auto registration = &qml_register_types_QtQuick_Controls; + Q_UNUSED(registration); +} + +QtQuickControls2Plugin::~QtQuickControls2Plugin() +{ + // Intentionally empty: we use register/unregisterTypes() to do + // initialization and cleanup, as plugins are not unloaded on macOS. +} + +void QtQuickControls2Plugin::registerTypes(const char *uri) +{ + qCDebug(lcQtQuickControls2Plugin) << "registerTypes() called with uri" << uri; + + // It's OK that the style is resolved more than once; some accessors like name() cause it to be called, for example. + QQuickStylePrivate::init(); + + const QString styleName = QQuickStylePrivate::effectiveStyleName(QQuickStyle::name()); + const QString fallbackStyleName = QQuickStylePrivate::effectiveStyleName(QQuickStylePrivate::fallbackStyle()); + qCDebug(lcQtQuickControls2Plugin) << "style:" << QQuickStyle::name() << "effective style:" << styleName + << "fallback style:" << QQuickStylePrivate::fallbackStyle() << "effective fallback style:" << fallbackStyleName; + + // If the style is Basic, we don't need to register the fallback because the Basic style + // provides all controls. Also, if we didn't return early here, we can get an infinite import loop + // when the style is set to Basic. + if (styleName != fallbackStyleName && styleName != QLatin1String("Basic")) { + registeredFallbackStyleUri = ::fallbackStyleUri(); + qCDebug(lcQtQuickControls2Plugin) << "calling qmlRegisterModuleImport() to register fallback style with" + << " uri \"" << qtQuickControlsUri << "\" moduleMajor" << QQmlModuleImportModuleAny + << "import" << registeredFallbackStyleUri << "importMajor" << QQmlModuleImportAuto; + // The fallback style must be a built-in style, so we match the version number. + qmlRegisterModuleImport(qtQuickControlsUri, QQmlModuleImportModuleAny, registeredFallbackStyleUri.toUtf8().constData(), + QQmlModuleImportAuto, QQmlModuleImportAuto); + } + + // If the user imports QtQuick.Controls 2.15, and they're using the Material style, we should import version 2.15. + // However, if they import QtQuick.Controls 2.15, but are using a custom style, we want to use the latest version + // number of their style. + customStyle = QQuickStylePrivate::isCustomStyle(); + registeredStyleUri = ::styleUri(); + const int importMajor = !customStyle ? QQmlModuleImportAuto : QQmlModuleImportLatest; + qCDebug(lcQtQuickControls2Plugin).nospace() << "calling qmlRegisterModuleImport() to register primary style with" + << " uri \"" << qtQuickControlsUri << "\" moduleMajor " << importMajor + << " import " << registeredStyleUri << " importMajor " << importMajor; + qmlRegisterModuleImport(qtQuickControlsUri, QQmlModuleImportModuleAny, registeredStyleUri.toUtf8().constData(), importMajor); + + if (customStyle) + QFileSelectorPrivate::addStatics(QStringList() << styleName); +} + +void QtQuickControls2Plugin::unregisterTypes() +{ + qCDebug(lcQtQuickControls2Plugin) << "unregisterTypes() called"; + + if (!registeredFallbackStyleUri.isEmpty()) { + // We registered a fallback style, so now we need to unregister it. + qmlUnregisterModuleImport(qtQuickControlsUri, QQmlModuleImportModuleAny, registeredFallbackStyleUri.toUtf8().constData(), + QQmlModuleImportAuto, QQmlModuleImportAuto); + registeredFallbackStyleUri.clear(); + } + + const int importMajor = !customStyle ? QQmlModuleImportAuto : QQmlModuleImportLatest; + qmlUnregisterModuleImport(qtQuickControlsUri, QQmlModuleImportModuleAny, registeredStyleUri.toUtf8().constData(), importMajor); + customStyle = false; + registeredStyleUri.clear(); +} + +QT_END_NAMESPACE + +#include "qtquickcontrols2plugin.moc" diff --git a/src/quickcontrols2/universal/ApplicationWindow.qml b/src/quickcontrols2/universal/ApplicationWindow.qml new file mode 100644 index 00000000000..2ec9c565667 --- /dev/null +++ b/src/quickcontrols2/universal/ApplicationWindow.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Templates as T +import QtQuick.Controls.Universal +import QtQuick.Controls.Universal.impl + +T.ApplicationWindow { + id: window + + color: Universal.background + + FocusRectangle { + parent: window.activeFocusControl + width: parent ? parent.width : 0 + height: parent ? parent.height : 0 + visible: parent && !!parent.useSystemFocusVisuals && !!parent.visualFocus + } +} diff --git a/src/quickcontrols2/universal/BusyIndicator.qml b/src/quickcontrols2/universal/BusyIndicator.qml new file mode 100644 index 00000000000..0bd3ca038a0 --- /dev/null +++ b/src/quickcontrols2/universal/BusyIndicator.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal +import QtQuick.Controls.Universal.impl + +T.BusyIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + contentItem: BusyIndicatorImpl { + implicitWidth: 20 + implicitHeight: 20 + + readonly property real size: Math.min(control.availableWidth, control.availableHeight) + + count: size < 60 ? 5 : 6 // "Small" vs. "Large" + color: control.Universal.accent + visible: control.running + } +} diff --git a/src/quickcontrols2/universal/Button.qml b/src/quickcontrols2/universal/Button.qml new file mode 100644 index 00000000000..7dd2ff3464d --- /dev/null +++ b/src/quickcontrols2/universal/Button.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.Button { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 8 + verticalPadding: padding - 4 + spacing: 8 + + icon.width: 20 + icon.height: 20 + icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) + + property bool useSystemFocusVisuals: true + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) + } + + background: Rectangle { + implicitWidth: 32 + implicitHeight: 32 + + visible: !control.flat || control.down || control.checked || control.highlighted + color: control.down ? control.Universal.baseMediumLowColor : + control.enabled && (control.highlighted || control.checked) ? control.Universal.accent : + control.Universal.baseLowColor + + Rectangle { + width: parent.width + height: parent.height + color: "transparent" + visible: enabled && control.hovered + border.width: 2 // ButtonBorderThemeThickness + border.color: control.Universal.baseMediumLowColor + } + } +} diff --git a/src/quickcontrols2/universal/CMakeLists.txt b/src/quickcontrols2/universal/CMakeLists.txt new file mode 100644 index 00000000000..823954e409b --- /dev/null +++ b/src/quickcontrols2/universal/CMakeLists.txt @@ -0,0 +1,151 @@ +##################################################################### +## qtquickcontrols2universalstyleplugin Plugin: +##################################################################### + +set(qml_files + "ApplicationWindow.qml" + "BusyIndicator.qml" + "Button.qml" + "CheckBox.qml" + "CheckDelegate.qml" + "ComboBox.qml" + "DelayButton.qml" + "Dial.qml" + "Dialog.qml" + "DialogButtonBox.qml" + "Drawer.qml" + "Frame.qml" + "GroupBox.qml" + "HorizontalHeaderView.qml" + "ItemDelegate.qml" + "Label.qml" + "Menu.qml" + "MenuBar.qml" + "MenuBarItem.qml" + "MenuItem.qml" + "MenuSeparator.qml" + "Page.qml" + "PageIndicator.qml" + "Pane.qml" + "Popup.qml" + "ProgressBar.qml" + "RadioButton.qml" + "RadioDelegate.qml" + "RangeSlider.qml" + "RoundButton.qml" + "ScrollView.qml" + "ScrollBar.qml" + "ScrollIndicator.qml" + "SelectionRectangle.qml" + "Slider.qml" + "SpinBox.qml" + "SplitView.qml" + "StackView.qml" + "SwipeDelegate.qml" + "SwitchDelegate.qml" + "Switch.qml" + "TabBar.qml" + "TabButton.qml" + "TextArea.qml" + "TextField.qml" + "ToolBar.qml" + "ToolButton.qml" + "ToolSeparator.qml" + "ToolTip.qml" + "Tumbler.qml" + "VerticalHeaderView.qml" +) +set_source_files_properties(DelayButton.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.2;6.0" +) +set_source_files_properties(Dialog.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(DialogButtonBox.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(HorizontalHeaderView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.15;6.0" +) +set_source_files_properties(MenuBar.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.3;6.0" +) +set_source_files_properties(MenuBarItem.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.3;6.0" +) +set_source_files_properties(MenuSeparator.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(RoundButton.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(SplitView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.13;6.0" +) +set_source_files_properties(ToolSeparator.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(VerticalHeaderView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.15;6.0" +) + +qt_internal_add_qml_module(qtquickcontrols2universalstyleplugin + URI "QtQuick.Controls.Universal" + VERSION "${PROJECT_VERSION}" + PAST_MAJOR_VERSIONS 2 + CLASS_NAME QtQuickControls2UniversalStylePlugin + IMPORTS + QtQuick.Controls.Basic/auto + PLUGIN_TARGET qtquickcontrols2universalstyleplugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + SOURCES + qquickuniversalstyle.cpp qquickuniversalstyle_p.h + qquickuniversaltheme.cpp qquickuniversaltheme_p.h + qtquickcontrols2universalstyleplugin.cpp + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2ImplPrivate + Qt::QuickControls2Private + Qt::QuickPrivate + Qt::QuickTemplates2Private +) + +qt_internal_add_resource(qtquickcontrols2universalstyleplugin "qtquickcontrols2universalstyleplugin" + PREFIX + "/qt-project.org/imports/QtQuick/Controls/Universal" + FILES + "images/checkmark.png" + "images/checkmark@2x.png" + "images/checkmark@3x.png" + "images/checkmark@4x.png" + "images/downarrow.png" + "images/downarrow@2x.png" + "images/downarrow@3x.png" + "images/downarrow@4x.png" + "images/leftarrow.png" + "images/leftarrow@2x.png" + "images/leftarrow@3x.png" + "images/leftarrow@4x.png" + "images/rightarrow.png" + "images/rightarrow@2x.png" + "images/rightarrow@3x.png" + "images/rightarrow@4x.png" +) + +add_subdirectory(impl) + +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2universalstyleplugin quickwindow) +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2universalstyleplugin + qtquickcontrols2universalstyleimplplugin) + +# Basic style is the required fallback style. +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2universalstyleplugin + qtquickcontrols2basicstyleplugin) diff --git a/src/quickcontrols2/universal/CheckBox.qml b/src/quickcontrols2/universal/CheckBox.qml new file mode 100644 index 00000000000..ff35d372688 --- /dev/null +++ b/src/quickcontrols2/universal/CheckBox.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal +import QtQuick.Controls.Universal.impl + +T.CheckBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 8 + + property bool useSystemFocusVisuals: true + + indicator: CheckIndicator { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + + opacity: enabled ? 1.0 : 0.2 + color: control.Universal.foreground + } +} diff --git a/src/quickcontrols2/universal/CheckDelegate.qml b/src/quickcontrols2/universal/CheckDelegate.qml new file mode 100644 index 00000000000..26a6d923a23 --- /dev/null +++ b/src/quickcontrols2/universal/CheckDelegate.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal +import QtQuick.Controls.Universal.impl + +T.CheckDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 + + padding: 12 + topPadding: padding - 1 + bottomPadding: padding + 1 + + icon.width: 20 + icon.height: 20 + icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) + + indicator: CheckIndicator { + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: IconLabel { + leftPadding: !control.mirrored ? 0 : control.indicator.width + control.spacing + rightPadding: control.mirrored ? 0 : control.indicator.width + control.spacing + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) + } + + background: Rectangle { + visible: enabled && (control.down || control.highlighted || control.visualFocus || control.hovered) + color: control.down ? control.Universal.listMediumColor : + control.hovered ? control.Universal.listLowColor : control.Universal.altMediumLowColor + Rectangle { + width: parent.width + height: parent.height + visible: control.visualFocus || control.highlighted + color: control.Universal.accent + opacity: control.Universal.theme === Universal.Light ? 0.4 : 0.6 + } + + } +} diff --git a/src/quickcontrols2/universal/ComboBox.qml b/src/quickcontrols2/universal/ComboBox.qml new file mode 100644 index 00000000000..f2de4ec5621 --- /dev/null +++ b/src/quickcontrols2/universal/ComboBox.qml @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls.impl +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.ComboBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + + Universal.theme: editable && activeFocus ? Universal.Light : undefined + + delegate: ItemDelegate { + width: ListView.view.width + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData + font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal + highlighted: control.highlightedIndex === index + hoverEnabled: control.hoverEnabled + } + + indicator: ColorImage { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseMediumHighColor + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Universal/images/downarrow.png" + + Rectangle { + z: -1 + width: parent.width + height: parent.height + color: control.activeFocus ? control.Universal.accent : + control.pressed ? control.Universal.baseMediumLowColor : + control.hovered ? control.Universal.baseLowColor : "transparent" + visible: control.editable && !control.contentItem.hovered && (control.pressed || control.hovered) + opacity: control.activeFocus && !control.pressed ? 0.4 : 1.0 + } + } + + contentItem: T.TextField { + leftPadding: control.mirrored ? 1 : 12 + rightPadding: control.mirrored ? 10 : 1 + topPadding: 5 - control.topPadding + bottomPadding: 7 - control.bottomPadding + + text: control.editable ? control.editText : control.displayText + + enabled: control.editable + autoScroll: control.editable + readOnly: control.down + inputMethodHints: control.inputMethodHints + validator: control.validator + selectByMouse: control.selectTextByMouse + + font: control.font + color: !control.enabled ? control.Universal.chromeDisabledLowColor : + control.editable && control.activeFocus ? control.Universal.chromeBlackHighColor : control.Universal.foreground + selectionColor: control.Universal.accent + selectedTextColor: control.Universal.chromeWhiteColor + verticalAlignment: Text.AlignVCenter + } + + background: Rectangle { + implicitWidth: 120 + implicitHeight: 32 + + border.width: control.flat ? 0 : 2 // ComboBoxBorderThemeThickness + border.color: !control.enabled ? control.Universal.baseLowColor : + control.editable && control.activeFocus ? control.Universal.accent : + control.down ? control.Universal.baseMediumLowColor : + control.hovered ? control.Universal.baseMediumColor : control.Universal.baseMediumLowColor + color: !control.enabled ? control.Universal.baseLowColor : + control.down ? control.Universal.listMediumColor : + control.flat && control.hovered ? control.Universal.listLowColor : + control.editable && control.activeFocus ? control.Universal.background : control.Universal.altMediumLowColor + visible: !control.flat || control.pressed || control.hovered || control.visualFocus + + Rectangle { + x: 2 + y: 2 + width: parent.width - 4 + height: parent.height - 4 + + visible: control.visualFocus && !control.editable + color: control.Universal.accent + opacity: control.Universal.theme === Universal.Light ? 0.4 : 0.6 + } + } + + popup: T.Popup { + width: control.width + height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin) + topMargin: 8 + bottomMargin: 8 + + Universal.theme: control.Universal.theme + Universal.accent: control.Universal.accent + + contentItem: ListView { + clip: true + implicitHeight: contentHeight + model: control.delegateModel + currentIndex: control.highlightedIndex + highlightMoveDuration: 0 + + T.ScrollIndicator.vertical: ScrollIndicator { } + } + + background: Rectangle { + color: control.Universal.chromeMediumLowColor + border.color: control.Universal.chromeHighColor + border.width: 1 // FlyoutBorderThemeThickness + } + } +} diff --git a/src/quickcontrols2/universal/DelayButton.qml b/src/quickcontrols2/universal/DelayButton.qml new file mode 100644 index 00000000000..a30f04b7f78 --- /dev/null +++ b/src/quickcontrols2/universal/DelayButton.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.DelayButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 8 + verticalPadding: padding - 4 + + property bool useSystemFocusVisuals: true + + transition: Transition { + NumberAnimation { + duration: control.delay * (control.pressed ? 1.0 - control.progress : 0.3 * control.progress) + } + } + + contentItem: Text { + text: control.text + font: control.font + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + opacity: enabled ? 1.0 : 0.2 + color: control.Universal.foreground + } + + background: Rectangle { + implicitWidth: 32 + implicitHeight: 32 + + color: control.down ? control.Universal.baseMediumLowColor : + control.enabled && control.checked ? control.Universal.accent : control.Universal.baseLowColor + + Rectangle { + visible: !control.checked + width: parent.width * control.progress + height: parent.height + color: control.Universal.accent + } + + Rectangle { + width: parent.width + height: parent.height + color: "transparent" + visible: enabled && control.hovered + border.width: 2 // ButtonBorderThemeThickness + border.color: control.Universal.baseMediumLowColor + } + } +} diff --git a/src/quickcontrols2/universal/Dial.qml b/src/quickcontrols2/universal/Dial.qml new file mode 100644 index 00000000000..cd9e615edb7 --- /dev/null +++ b/src/quickcontrols2/universal/Dial.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.Dial { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 100 + + x: control.width / 2 - width / 2 + y: control.height / 2 - height / 2 + width: Math.max(64, Math.min(control.width, control.height)) + height: width + radius: width / 2 + color: "transparent" + border.color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseMediumColor + border.width: 2 + } + + handle: Rectangle { + implicitWidth: 14 + implicitHeight: 14 + + x: control.background.x + control.background.width / 2 - width / 2 + y: control.background.y + control.background.height / 2 - height / 2 + + radius: width / 2 + color: !control.enabled ? control.Universal.baseLowColor : + control.pressed ? control.Universal.baseMediumColor : + control.hovered ? control.Universal.baseHighColor : control.Universal.baseMediumHighColor + + transform: [ + Translate { + y: -control.background.height * 0.4 + control.handle.height / 2 + }, + Rotation { + angle: control.angle + origin.x: control.handle.width / 2 + origin.y: control.handle.height / 2 + } + ] + } +} diff --git a/src/quickcontrols2/universal/Dialog.qml b/src/quickcontrols2/universal/Dialog.qml new file mode 100644 index 00000000000..3cebf7f07be --- /dev/null +++ b/src/quickcontrols2/universal/Dialog.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.Dialog { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + padding: 24 + verticalPadding: 18 + + background: Rectangle { + color: control.Universal.chromeMediumLowColor + border.color: control.Universal.chromeHighColor + border.width: 1 // FlyoutBorderThemeThickness + } + + header: Label { + text: control.title + visible: control.title + elide: Label.ElideRight + topPadding: 18 + leftPadding: 24 + rightPadding: 24 + // TODO: QPlatformTheme::TitleBarFont + font.pixelSize: 20 + background: Rectangle { + x: 1; y: 1 // // FlyoutBorderThemeThickness + color: control.Universal.chromeMediumLowColor + width: parent.width - 2 + height: parent.height - 1 + } + } + + footer: DialogButtonBox { + visible: count > 0 + } + + T.Overlay.modal: Rectangle { + color: control.Universal.baseLowColor + } + + T.Overlay.modeless: Rectangle { + color: control.Universal.baseLowColor + } +} diff --git a/src/quickcontrols2/universal/DialogButtonBox.qml b/src/quickcontrols2/universal/DialogButtonBox.qml new file mode 100644 index 00000000000..bf3f5af0a44 --- /dev/null +++ b/src/quickcontrols2/universal/DialogButtonBox.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.DialogButtonBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + (control.count === 1 ? implicitContentWidth * 2 : implicitContentWidth) + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + contentWidth: contentItem.contentWidth + + spacing: 4 + padding: 24 + topPadding: position === T.DialogButtonBox.Footer ? 6 : 24 + bottomPadding: position === T.DialogButtonBox.Header ? 6 : 24 + alignment: count === 1 ? Qt.AlignRight : undefined + + delegate: Button { + width: control.count === 1 ? control.availableWidth / 2 : undefined + } + + contentItem: ListView { + implicitWidth: contentWidth + model: control.contentModel + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + } + + background: Rectangle { + implicitHeight: 32 + color: control.Universal.chromeMediumLowColor + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + } +} diff --git a/src/quickcontrols2/universal/Drawer.qml b/src/quickcontrols2/universal/Drawer.qml new file mode 100644 index 00000000000..19f78f1e4b2 --- /dev/null +++ b/src/quickcontrols2/universal/Drawer.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.Drawer { + id: control + + parent: T.Overlay.overlay + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: control.edge === Qt.BottomEdge + leftPadding: control.edge === Qt.RightEdge + rightPadding: control.edge === Qt.LeftEdge + bottomPadding: control.edge === Qt.TopEdge + + enter: Transition { SmoothedAnimation { velocity: 5 } } + exit: Transition { SmoothedAnimation { velocity: 5 } } + + background: Rectangle { + color: control.Universal.chromeMediumLowColor + Rectangle { + readonly property bool horizontal: control.edge === Qt.LeftEdge || control.edge === Qt.RightEdge + width: horizontal ? 1 : parent.width + height: horizontal ? parent.height : 1 + color: control.Universal.chromeHighColor + x: control.edge === Qt.LeftEdge ? parent.width - 1 : 0 + y: control.edge === Qt.TopEdge ? parent.height - 1 : 0 + } + } + + T.Overlay.modal: Rectangle { + color: control.Universal.baseLowColor + } + + T.Overlay.modeless: Rectangle { + color: control.Universal.baseLowColor + } +} diff --git a/src/quickcontrols2/universal/Frame.qml b/src/quickcontrols2/universal/Frame.qml new file mode 100644 index 00000000000..780ba7348b9 --- /dev/null +++ b/src/quickcontrols2/universal/Frame.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.Frame { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 12 + + background: Rectangle { + color: "transparent" + border.color: control.Universal.chromeDisabledLowColor + } +} diff --git a/src/quickcontrols2/universal/GroupBox.qml b/src/quickcontrols2/universal/GroupBox.qml new file mode 100644 index 00000000000..5104b710ca5 --- /dev/null +++ b/src/quickcontrols2/universal/GroupBox.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.GroupBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitLabelWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: 12 + padding: 12 + topPadding: padding + (implicitLabelWidth > 0 ? implicitLabelHeight + spacing : 0) + + label: Text { + x: control.leftPadding + width: control.availableWidth + + text: control.title + font: control.font + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + + opacity: enabled ? 1.0 : 0.2 + color: control.Universal.foreground + } + + background: Rectangle { + y: control.topPadding - control.bottomPadding + width: parent.width + height: parent.height - control.topPadding + control.bottomPadding + + color: "transparent" + border.color: control.Universal.chromeDisabledLowColor + } +} diff --git a/src/quickcontrols2/universal/HorizontalHeaderView.qml b/src/quickcontrols2/universal/HorizontalHeaderView.qml new file mode 100644 index 00000000000..0bf88ebcc8e --- /dev/null +++ b/src/quickcontrols2/universal/HorizontalHeaderView.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T +import QtQuick.Controls.Universal +import QtQuick.Controls.Universal.impl + +T.HorizontalHeaderView { + id: control + + implicitWidth: syncView ? syncView.width : 0 + implicitHeight: contentHeight + + delegate: Rectangle { + // Qt6: add cellPadding (and font etc) as public API in headerview + readonly property real cellPadding: 8 + + implicitWidth: text.implicitWidth + (cellPadding * 2) + implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2)) + color: control.Universal.background + + Text { + id: text + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] + : model[control.textRole]) + : modelData + width: parent.width + height: parent.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) + } + } +} diff --git a/src/quickcontrols2/universal/ItemDelegate.qml b/src/quickcontrols2/universal/ItemDelegate.qml new file mode 100644 index 00000000000..561a6b6997d --- /dev/null +++ b/src/quickcontrols2/universal/ItemDelegate.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.ItemDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 + + padding: 12 + topPadding: padding - 1 + bottomPadding: padding + 1 + + icon.width: 20 + icon.height: 20 + icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) + } + + background: Rectangle { + visible: enabled && (control.down || control.highlighted || control.visualFocus || control.hovered) + color: control.down ? control.Universal.listMediumColor : + control.hovered ? control.Universal.listLowColor : control.Universal.altMediumLowColor + Rectangle { + width: parent.width + height: parent.height + visible: control.visualFocus || control.highlighted + color: control.Universal.accent + opacity: control.Universal.theme === Universal.Light ? 0.4 : 0.6 + } + + } +} diff --git a/src/quickcontrols2/universal/Label.qml b/src/quickcontrols2/universal/Label.qml new file mode 100644 index 00000000000..9460c997ebb --- /dev/null +++ b/src/quickcontrols2/universal/Label.qml @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.Label { + id: control + + opacity: enabled ? 1.0 : 0.2 + color: control.Universal.foreground + linkColor: Universal.accent +} diff --git a/src/quickcontrols2/universal/Menu.qml b/src/quickcontrols2/universal/Menu.qml new file mode 100644 index 00000000000..5d5a1a5650d --- /dev/null +++ b/src/quickcontrols2/universal/Menu.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal +import QtQuick.Window + +T.Menu { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + margins: 0 + overlap: 1 + + delegate: MenuItem { } + + contentItem: ListView { + implicitHeight: contentHeight + model: control.contentModel + interactive: contentHeight + control.topPadding + control.bottomPadding > control.height + clip: true + currentIndex: control.currentIndex + + ScrollIndicator.vertical: ScrollIndicator {} + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 40 + color: control.Universal.chromeMediumLowColor + border.color: control.Universal.chromeHighColor + border.width: 1 // FlyoutBorderThemeThickness + } + + T.Overlay.modal: Rectangle { + color: control.Universal.baseLowColor + } + + T.Overlay.modeless: Rectangle { + color: control.Universal.baseLowColor + } +} diff --git a/src/quickcontrols2/universal/MenuBar.qml b/src/quickcontrols2/universal/MenuBar.qml new file mode 100644 index 00000000000..2ab5891960a --- /dev/null +++ b/src/quickcontrols2/universal/MenuBar.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.MenuBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + delegate: MenuBarItem { } + + contentItem: Row { + spacing: control.spacing + Repeater { + model: control.contentModel + } + } + + background: Rectangle { + implicitHeight: 40 + color: control.Universal.chromeMediumColor + } +} diff --git a/src/quickcontrols2/universal/MenuBarItem.qml b/src/quickcontrols2/universal/MenuBarItem.qml new file mode 100644 index 00000000000..786be1325c5 --- /dev/null +++ b/src/quickcontrols2/universal/MenuBarItem.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.MenuBarItem { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 12 + topPadding: padding - 1 + bottomPadding: padding + 1 + spacing: 12 + + icon.width: 20 + icon.height: 20 + icon.color: !enabled ? Universal.baseLowColor : Universal.baseHighColor + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseHighColor + } + + background: Rectangle { + implicitWidth: 40 + implicitHeight: 40 + + color: !control.enabled ? control.Universal.baseLowColor : + control.down ? control.Universal.listMediumColor : + control.highlighted ? control.Universal.listLowColor : "transparent" + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + + visible: control.visualFocus + color: control.Universal.accent + opacity: control.Universal.theme === Universal.Light ? 0.4 : 0.6 + } + } +} diff --git a/src/quickcontrols2/universal/MenuItem.qml b/src/quickcontrols2/universal/MenuItem.qml new file mode 100644 index 00000000000..8287b0a828b --- /dev/null +++ b/src/quickcontrols2/universal/MenuItem.qml @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.MenuItem { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 12 + topPadding: padding - 1 + bottomPadding: padding + 1 + spacing: 12 + + icon.width: 20 + icon.height: 20 + icon.color: !enabled ? Universal.baseLowColor : Universal.baseHighColor + + contentItem: IconLabel { + readonly property real arrowPadding: control.subMenu && control.arrow ? control.arrow.width + control.spacing : 0 + readonly property real indicatorPadding: control.checkable && control.indicator ? control.indicator.width + control.spacing : 0 + leftPadding: !control.mirrored ? indicatorPadding : arrowPadding + rightPadding: control.mirrored ? indicatorPadding : arrowPadding + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseHighColor + } + + arrow: ColorImage { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + visible: control.subMenu + mirror: control.mirrored + color: !enabled ? control.Universal.baseLowColor : control.Universal.baseHighColor + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Universal/images/rightarrow.png" + } + + indicator: ColorImage { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + visible: control.checked + color: !control.enabled ? control.Universal.baseLowColor : control.down ? control.Universal.baseHighColor : control.Universal.baseMediumHighColor + source: !control.checkable ? "" : "qrc:/qt-project.org/imports/QtQuick/Controls/Universal/images/checkmark.png" + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 40 + + color: !control.enabled ? control.Universal.baseLowColor : + control.down ? control.Universal.listMediumColor : + control.highlighted ? control.Universal.listLowColor : control.Universal.altMediumLowColor + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + + visible: control.visualFocus + color: control.Universal.accent + opacity: control.Universal.theme === Universal.Light ? 0.4 : 0.6 + } + } +} diff --git a/src/quickcontrols2/universal/MenuSeparator.qml b/src/quickcontrols2/universal/MenuSeparator.qml new file mode 100644 index 00000000000..be6fad4580b --- /dev/null +++ b/src/quickcontrols2/universal/MenuSeparator.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.MenuSeparator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 12 + topPadding: 9 + bottomPadding: 10 + + contentItem: Rectangle { + implicitWidth: 188 + implicitHeight: 1 + color: control.Universal.baseMediumLowColor + } + + background: Rectangle { + color: control.Universal.altMediumLowColor + } +} diff --git a/src/quickcontrols2/universal/Page.qml b/src/quickcontrols2/universal/Page.qml new file mode 100644 index 00000000000..8946e7adbf5 --- /dev/null +++ b/src/quickcontrols2/universal/Page.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.Page { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + background: Rectangle { + color: control.Universal.background + } +} diff --git a/src/quickcontrols2/universal/PageIndicator.qml b/src/quickcontrols2/universal/PageIndicator.qml new file mode 100644 index 00000000000..1225bdab337 --- /dev/null +++ b/src/quickcontrols2/universal/PageIndicator.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.PageIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 7 + + delegate: Rectangle { + implicitWidth: 5 + implicitHeight: 5 + + radius: width / 2 + color: index === control.currentIndex ? control.Universal.baseMediumHighColor : + pressed ? control.Universal.baseMediumLowColor : control.Universal.baseLowColor + + required property int index + } + + contentItem: Row { + spacing: control.spacing + + Repeater { + model: control.count + delegate: control.delegate + } + } +} diff --git a/src/quickcontrols2/universal/Pane.qml b/src/quickcontrols2/universal/Pane.qml new file mode 100644 index 00000000000..257f9cafd0a --- /dev/null +++ b/src/quickcontrols2/universal/Pane.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.Pane { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 12 + + background: Rectangle { + color: control.Universal.background + } +} diff --git a/src/quickcontrols2/universal/Popup.qml b/src/quickcontrols2/universal/Popup.qml new file mode 100644 index 00000000000..5e972ea9939 --- /dev/null +++ b/src/quickcontrols2/universal/Popup.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.Popup { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 12 + + background: Rectangle { + color: control.Universal.chromeMediumLowColor + border.color: control.Universal.chromeHighColor + border.width: 1 // FlyoutBorderThemeThickness + } + + T.Overlay.modal: Rectangle { + color: control.Universal.baseLowColor + } + + T.Overlay.modeless: Rectangle { + color: control.Universal.baseLowColor + } +} diff --git a/src/quickcontrols2/universal/ProgressBar.qml b/src/quickcontrols2/universal/ProgressBar.qml new file mode 100644 index 00000000000..4f8cc874280 --- /dev/null +++ b/src/quickcontrols2/universal/ProgressBar.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal +import QtQuick.Controls.Universal.impl + +T.ProgressBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + contentItem: ProgressBarImpl { + implicitHeight: 10 + + scale: control.mirrored ? -1 : 1 + color: control.Universal.accent + progress: control.position + indeterminate: control.visible && control.indeterminate + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 10 + y: (control.height - height) / 2 + height: 10 + + visible: !control.indeterminate + color: control.Universal.baseLowColor + } +} diff --git a/src/quickcontrols2/universal/README.md b/src/quickcontrols2/universal/README.md new file mode 100644 index 00000000000..8d02d18ba39 --- /dev/null +++ b/src/quickcontrols2/universal/README.md @@ -0,0 +1,9 @@ +# Universal Style + +This style is based on the [Microsoft Universal Design Guidelines](https://dev.windows.com/design). + +The colors and metrics used all around the QML and C++ files originate from the Windows 10 SDK. The files are called **generic.xaml** and **themeresources.xml**, and they are located in the following folder: + + \(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\<SDK version>\Generic + +See also [XAML theme resources](https://msdn.microsoft.com/en-us/library/windows/apps/mt187274.aspx). diff --git a/src/quickcontrols2/universal/RadioButton.qml b/src/quickcontrols2/universal/RadioButton.qml new file mode 100644 index 00000000000..abd386ce9d0 --- /dev/null +++ b/src/quickcontrols2/universal/RadioButton.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal +import QtQuick.Controls.Universal.impl + +T.RadioButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 8 + + property bool useSystemFocusVisuals: true + + indicator: RadioIndicator { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + + opacity: enabled ? 1.0 : 0.2 + color: control.Universal.foreground + } +} diff --git a/src/quickcontrols2/universal/RadioDelegate.qml b/src/quickcontrols2/universal/RadioDelegate.qml new file mode 100644 index 00000000000..5f7a129546e --- /dev/null +++ b/src/quickcontrols2/universal/RadioDelegate.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal +import QtQuick.Controls.Universal.impl + +T.RadioDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 + + padding: 12 + topPadding: padding - 1 + bottomPadding: padding + 1 + + icon.width: 20 + icon.height: 20 + icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) + + indicator: RadioIndicator { + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: IconLabel { + leftPadding: !control.mirrored ? 0 : control.indicator.width + control.spacing + rightPadding: control.mirrored ? 0 : control.indicator.width + control.spacing + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) + } + + background: Rectangle { + visible: enabled && (control.down || control.highlighted || control.visualFocus || control.hovered) + color: control.down ? control.Universal.listMediumColor : + control.hovered ? control.Universal.listLowColor : control.Universal.altMediumLowColor + Rectangle { + width: parent.width + height: parent.height + visible: control.visualFocus || control.highlighted + color: control.Universal.accent + opacity: control.Universal.theme === Universal.Light ? 0.4 : 0.6 + } + + } +} diff --git a/src/quickcontrols2/universal/RangeSlider.qml b/src/quickcontrols2/universal/RangeSlider.qml new file mode 100644 index 00000000000..1156f5789e9 --- /dev/null +++ b/src/quickcontrols2/universal/RangeSlider.qml @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.RangeSlider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + first.implicitHandleWidth + leftPadding + rightPadding, + second.implicitHandleWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + first.implicitHandleHeight + topPadding + bottomPadding, + second.implicitHandleHeight + topPadding + bottomPadding) + + padding: 6 + + first.handle: Rectangle { + implicitWidth: control.horizontal ? 8 : 24 + implicitHeight: control.horizontal ? 24 : 8 + + x: control.leftPadding + (control.horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height)) + + radius: 4 + color: control.first.pressed ? control.Universal.chromeHighColor : + control.first.hovered ? control.Universal.chromeAltLowColor : + control.enabled ? control.Universal.accent : control.Universal.chromeDisabledHighColor + } + + second.handle: Rectangle { + implicitWidth: control.horizontal ? 8 : 24 + implicitHeight: control.horizontal ? 24 : 8 + + x: control.leftPadding + (control.horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height)) + + radius: 4 + color: control.second.pressed ? control.Universal.chromeHighColor : + control.second.hovered ? control.Universal.chromeAltLowColor : + control.enabled ? control.Universal.accent : control.Universal.chromeDisabledHighColor + } + + background: Item { + implicitWidth: control.horizontal ? 200 : 18 + implicitHeight: control.horizontal ? 18 : 200 + + x: control.leftPadding + (control.horizontal ? 0 : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : 0) + width: control.horizontal ? control.availableWidth : implicitWidth + height: control.horizontal ? implicitHeight : control.availableHeight + + scale: control.horizontal && control.mirrored ? -1 : 1 + + Rectangle { + x: control.horizontal ? 0 : (parent.width - width) / 2 + y: control.horizontal ? (parent.height - height) / 2 : 0 + width: control.horizontal ? parent.width : 2 // SliderBackgroundThemeHeight + height: control.vertical ? parent.height : 2 // SliderBackgroundThemeHeight + + color: enabled && control.hovered && !control.pressed ? control.Universal.baseMediumColor : + control.enabled ? control.Universal.baseMediumLowColor : control.Universal.chromeDisabledHighColor + } + + Rectangle { + x: control.horizontal ? control.first.position * parent.width : (parent.width - width) / 2 + y: control.horizontal ? (parent.height - height) / 2 : control.second.visualPosition * parent.height + width: control.horizontal ? control.second.position * parent.width - control.first.position * parent.width : 2 // SliderBackgroundThemeHeight + height: control.vertical ? control.second.position * parent.height - control.first.position * parent.height : 2 // SliderBackgroundThemeHeight + + color: control.enabled ? control.Universal.accent : control.Universal.chromeDisabledHighColor + } + } +} diff --git a/src/quickcontrols2/universal/RoundButton.qml b/src/quickcontrols2/universal/RoundButton.qml new file mode 100644 index 00000000000..0592596b769 --- /dev/null +++ b/src/quickcontrols2/universal/RoundButton.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.RoundButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 8 + spacing: 8 + + icon.width: 20 + icon.height: 20 + icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) + + property bool useSystemFocusVisuals: true + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) + } + + background: Rectangle { + implicitWidth: 32 + implicitHeight: 32 + + radius: control.radius + visible: !control.flat || control.down || control.checked || control.highlighted + color: control.down ? control.Universal.baseMediumLowColor : + control.enabled && (control.highlighted || control.checked) ? control.Universal.accent : + control.Universal.baseLowColor + + Rectangle { + width: parent.width + height: parent.height + radius: control.radius + color: "transparent" + visible: enabled && control.hovered + border.width: 2 // ButtonBorderThemeThickness + border.color: control.Universal.baseMediumLowColor + } + } +} diff --git a/src/quickcontrols2/universal/ScrollBar.qml b/src/quickcontrols2/universal/ScrollBar.qml new file mode 100644 index 00000000000..c0cfd081f60 --- /dev/null +++ b/src/quickcontrols2/universal/ScrollBar.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.ScrollBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + visible: control.policy !== T.ScrollBar.AlwaysOff + minimumSize: orientation === Qt.Horizontal ? height / width : width / height + + // TODO: arrows + + contentItem: Rectangle { + implicitWidth: control.interactive ? 12 : 6 + implicitHeight: control.interactive ? 12: 6 + + color: control.pressed ? control.Universal.baseMediumColor : + enabled && control.interactive && control.hovered ? control.Universal.baseMediumLowColor : + control.Universal.chromeHighColor + opacity: 0.0 + } + + background: Rectangle { + implicitWidth: control.interactive ? 12 : 6 + implicitHeight: control.interactive ? 12: 6 + + color: control.Universal.chromeLowColor + visible: control.size < 1.0 + opacity: 0.0 + } + + states: [ + State { + name: "active" + when: control.policy === T.ScrollBar.AlwaysOn || (control.active && control.size < 1.0) + } + ] + + transitions: [ + Transition { + to: "active" + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 1.0 } + }, + Transition { + from: "active" + SequentialAnimation { + PropertyAction{ targets: [control.contentItem, control.background]; property: "opacity"; value: 1.0 } + PauseAnimation { duration: 3000 } + NumberAnimation { targets: [control.contentItem, control.background]; property: "opacity"; to: 0.0 } + } + } + ] +} diff --git a/src/quickcontrols2/universal/ScrollIndicator.qml b/src/quickcontrols2/universal/ScrollIndicator.qml new file mode 100644 index 00000000000..f66a96587ca --- /dev/null +++ b/src/quickcontrols2/universal/ScrollIndicator.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.ScrollIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + contentItem: Rectangle { + implicitWidth: 6 + implicitHeight: 6 + + color: control.Universal.baseMediumLowColor + visible: control.size < 1.0 + opacity: 0.0 + + states: [ + State { + name: "active" + when: control.active + } + ] + + transitions: [ + Transition { + to: "active" + NumberAnimation { target: control.contentItem; property: "opacity"; to: 1.0 } + }, + Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 5000 } + NumberAnimation { target: control.contentItem; property: "opacity"; to: 0.0 } + } + } + ] + } +} diff --git a/src/quickcontrols2/universal/ScrollView.qml b/src/quickcontrols2/universal/ScrollView.qml new file mode 100644 index 00000000000..a6bba9de05a --- /dev/null +++ b/src/quickcontrols2/universal/ScrollView.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ScrollView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + ScrollBar.vertical: ScrollBar { + parent: control + x: control.mirrored ? 0 : control.width - width + y: control.topPadding + height: control.availableHeight + active: control.ScrollBar.horizontal.active + } + + ScrollBar.horizontal: ScrollBar { + parent: control + x: control.leftPadding + y: control.height - height + width: control.availableWidth + active: control.ScrollBar.vertical.active + } +} diff --git a/src/quickcontrols2/universal/SelectionRectangle.qml b/src/quickcontrols2/universal/SelectionRectangle.qml new file mode 100644 index 00000000000..708e701c9c3 --- /dev/null +++ b/src/quickcontrols2/universal/SelectionRectangle.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.SelectionRectangle { + id: control + + topLeftHandle: handle + bottomRightHandle: handle + + Component { + id: handle + Rectangle { + implicitWidth: 8 + implicitHeight: 24 + radius: 4 + color: tapHandler.pressed || SelectionRectangle.dragging ? control.Universal.chromeHighColor : + hoverHandler.hovered ? control.Universal.chromeAltLowColor : + control.Universal.accent + visible: control.active + + property Item control: SelectionRectangle.control + + HoverHandler { + id: hoverHandler + } + + TapHandler { + id: tapHandler + } + } + } +} diff --git a/src/quickcontrols2/universal/Slider.qml b/src/quickcontrols2/universal/Slider.qml new file mode 100644 index 00000000000..47ea58773ce --- /dev/null +++ b/src/quickcontrols2/universal/Slider.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.Slider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitHandleWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitHandleHeight + topPadding + bottomPadding) + + padding: 6 + + property bool useSystemFocusVisuals: true + + handle: Rectangle { + implicitWidth: control.horizontal ? 8 : 24 + implicitHeight: control.horizontal ? 24 : 8 + + x: control.leftPadding + (control.horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) + + radius: 4 + color: control.pressed ? control.Universal.chromeHighColor : + control.enabled ? control.hovered ? control.Universal.chromeAltLowColor : + control.Universal.accent : control.Universal.chromeDisabledHighColor + } + + background: Item { + implicitWidth: control.horizontal ? 200 : 18 + implicitHeight: control.horizontal ? 18 : 200 + + x: control.leftPadding + (control.horizontal ? 0 : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : 0) + width: control.horizontal ? control.availableWidth : implicitWidth + height: control.horizontal ? implicitHeight : control.availableHeight + + scale: control.horizontal && control.mirrored ? -1 : 1 + + Rectangle { + x: control.horizontal ? 0 : (parent.width - width) / 2 + y: control.horizontal ? (parent.height - height) / 2 : 0 + width: control.horizontal ? parent.width : 2 // SliderTrackThemeHeight + height: !control.horizontal ? parent.height : 2 // SliderTrackThemeHeight + + color: enabled && control.hovered && !control.pressed ? control.Universal.baseMediumColor : + control.enabled ? control.Universal.baseMediumLowColor : control.Universal.chromeDisabledHighColor + } + + Rectangle { + x: control.horizontal ? 0 : (parent.width - width) / 2 + y: control.horizontal ? (parent.height - height) / 2 : control.visualPosition * parent.height + width: control.horizontal ? control.position * parent.width : 2 // SliderTrackThemeHeight + height: !control.horizontal ? control.position * parent.height : 2 // SliderTrackThemeHeight + + color: control.enabled ? control.Universal.accent : control.Universal.chromeDisabledHighColor + } + } +} diff --git a/src/quickcontrols2/universal/SpinBox.qml b/src/quickcontrols2/universal/SpinBox.qml new file mode 100644 index 00000000000..0bb5e4b19b8 --- /dev/null +++ b/src/quickcontrols2/universal/SpinBox.qml @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.SpinBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentItem.implicitWidth + 16 + + up.implicitIndicatorWidth + + down.implicitIndicatorWidth) + implicitHeight: Math.max(implicitContentHeight + topPadding + bottomPadding, + implicitBackgroundHeight, + up.implicitIndicatorHeight, + down.implicitIndicatorHeight) + + // TextControlThemePadding + 2 (border) + padding: 12 + topPadding: padding - 7 + leftPadding: padding + (control.mirrored ? (up.indicator ? up.indicator.width : 0) : (down.indicator ? down.indicator.width : 0)) + rightPadding: padding - 4 + (control.mirrored ? (down.indicator ? down.indicator.width : 0) : (up.indicator ? up.indicator.width : 0)) + bottomPadding: padding - 5 + + Universal.theme: activeFocus ? Universal.Light : undefined + + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + + contentItem: TextInput { + text: control.displayText + + font: control.font + color: !enabled ? control.Universal.chromeDisabledLowColor : + activeFocus ? control.Universal.chromeBlackHighColor : control.Universal.foreground + selectionColor: control.Universal.accent + selectedTextColor: control.Universal.chromeWhiteColor + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: TextInput.AlignVCenter + + readOnly: !control.editable + validator: control.validator + inputMethodHints: control.inputMethodHints + } + + up.indicator: Item { + implicitWidth: 28 + height: control.height + 4 + y: -2 + x: control.mirrored ? 0 : control.width - width + + Rectangle { + x: 2; y: 4 + width: parent.width - 4 + height: parent.height - 8 + color: control.activeFocus ? control.Universal.accent : + control.up.pressed ? control.Universal.baseMediumLowColor : + control.up.hovered ? control.Universal.baseLowColor : "transparent" + visible: control.up.pressed || control.up.hovered + opacity: control.activeFocus && !control.up.pressed ? 0.4 : 1.0 + } + + ColorImage { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + color: !enabled ? control.Universal.chromeDisabledLowColor : + control.activeFocus ? control.Universal.chromeBlackHighColor : control.Universal.baseHighColor + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Universal/images/" + (control.mirrored ? "left" : "right") + "arrow.png" + } + } + + down.indicator: Item { + implicitWidth: 28 + height: control.height + 4 + y: -2 + x: control.mirrored ? control.width - width : 0 + + Rectangle { + x: 2; y: 4 + width: parent.width - 4 + height: parent.height - 8 + color: control.activeFocus ? control.Universal.accent : + control.down.pressed ? control.Universal.baseMediumLowColor : + control.down.hovered ? control.Universal.baseLowColor : "transparent" + visible: control.down.pressed || control.down.hovered + opacity: control.activeFocus && !control.down.pressed ? 0.4 : 1.0 + } + + ColorImage { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + color: !enabled ? control.Universal.chromeDisabledLowColor : + control.activeFocus ? control.Universal.chromeBlackHighColor : control.Universal.baseHighColor + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Universal/images/" + (control.mirrored ? "right" : "left") + "arrow.png" + } + } + + background: Rectangle { + implicitWidth: 60 + 28 // TextControlThemeMinWidth - 4 (border) + implicitHeight: 28 // TextControlThemeMinHeight - 4 (border) + + border.width: 2 // TextControlBorderThemeThickness + border.color: !control.enabled ? control.Universal.baseLowColor : + control.activeFocus ? control.Universal.accent : + control.hovered ? control.Universal.baseMediumColor : control.Universal.chromeDisabledLowColor + color: control.enabled ? control.Universal.background : control.Universal.baseLowColor + } +} diff --git a/src/quickcontrols2/universal/SplitView.qml b/src/quickcontrols2/universal/SplitView.qml new file mode 100644 index 00000000000..ff753708f1b --- /dev/null +++ b/src/quickcontrols2/universal/SplitView.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.SplitView { + id: control + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + handle: Rectangle { + implicitWidth: control.orientation === Qt.Horizontal ? 6 : control.width + implicitHeight: control.orientation === Qt.Horizontal ? control.height : 6 + color: T.SplitHandle.pressed ? control.Universal.baseMediumColor + : (enabled && T.SplitHandle.hovered ? control.Universal.baseMediumLowColor : control.Universal.chromeHighColor) + } +} diff --git a/src/quickcontrols2/universal/StackView.qml b/src/quickcontrols2/universal/StackView.qml new file mode 100644 index 00000000000..41611dd36b9 --- /dev/null +++ b/src/quickcontrols2/universal/StackView.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.StackView { + id: control + + popEnter: Transition { + ParallelAnimation { + NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200; easing.type: Easing.InQuint } + NumberAnimation { property: "x"; from: (control.mirrored ? -0.3 : 0.3) * -control.width; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + } + + popExit: Transition { + NumberAnimation { property: "opacity"; from: 1; to: 0; duration: 200; easing.type: Easing.OutQuint } + } + + pushEnter: Transition { + ParallelAnimation { + NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200; easing.type: Easing.InQuint } + NumberAnimation { property: "x"; from: (control.mirrored ? -0.3 : 0.3) * control.width; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + } + + pushExit: Transition { + NumberAnimation { property: "opacity"; from: 1; to: 0; duration: 200; easing.type: Easing.OutQuint } + } + + replaceEnter: Transition { + ParallelAnimation { + NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200; easing.type: Easing.InQuint } + NumberAnimation { property: "x"; from: (control.mirrored ? -0.3 : 0.3) * control.width; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + } + + replaceExit: Transition { + NumberAnimation { property: "opacity"; from: 1; to: 0; duration: 200; easing.type: Easing.OutQuint } + } +} diff --git a/src/quickcontrols2/universal/SwipeDelegate.qml b/src/quickcontrols2/universal/SwipeDelegate.qml new file mode 100644 index 00000000000..507c77023e9 --- /dev/null +++ b/src/quickcontrols2/universal/SwipeDelegate.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.SwipeDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 + + padding: 12 + topPadding: padding - 1 + bottomPadding: padding + 1 + + icon.width: 20 + icon.height: 20 + icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) + + swipe.transition: Transition { SmoothedAnimation { velocity: 3; easing.type: Easing.InOutCubic } } + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) + } + + background: Rectangle { + color: control.Universal.background + + Rectangle { + width: parent.width + height: parent.height + color: control.down ? control.Universal.listMediumColor : + enabled && control.hovered ? control.Universal.listLowColor : control.Universal.altMediumLowColor + Rectangle { + width: parent.width + height: parent.height + visible: control.visualFocus || control.highlighted + color: control.Universal.accent + opacity: control.Universal.theme === Universal.Light ? 0.4 : 0.6 + } + } + } +} diff --git a/src/quickcontrols2/universal/Switch.qml b/src/quickcontrols2/universal/Switch.qml new file mode 100644 index 00000000000..33ee4abb960 --- /dev/null +++ b/src/quickcontrols2/universal/Switch.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal +import QtQuick.Controls.Universal.impl + +T.Switch { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 5 + spacing: 8 + + property bool useSystemFocusVisuals: true + + indicator: SwitchIndicator { + x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + + opacity: enabled ? 1.0 : 0.2 + color: control.Universal.foreground + } +} diff --git a/src/quickcontrols2/universal/SwitchDelegate.qml b/src/quickcontrols2/universal/SwitchDelegate.qml new file mode 100644 index 00000000000..d3b6cf2da8d --- /dev/null +++ b/src/quickcontrols2/universal/SwitchDelegate.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal +import QtQuick.Controls.Universal.impl + +T.SwitchDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 + + padding: 12 + topPadding: padding - 1 + bottomPadding: padding + 1 + + icon.width: 20 + icon.height: 20 + icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) + + indicator: SwitchIndicator { + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: IconLabel { + leftPadding: !control.mirrored ? 0 : control.indicator.width + control.spacing + rightPadding: control.mirrored ? 0 : control.indicator.width + control.spacing + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) + } + + background: Rectangle { + visible: enabled && (control.down || control.highlighted || control.visualFocus || control.hovered) + color: control.down ? control.Universal.listMediumColor : + control.hovered ? control.Universal.listLowColor : control.Universal.altMediumLowColor + Rectangle { + width: parent.width + height: parent.height + visible: control.visualFocus || control.highlighted + color: control.Universal.accent + opacity: control.Universal.theme === Universal.Light ? 0.4 : 0.6 + } + + } +} diff --git a/src/quickcontrols2/universal/TabBar.qml b/src/quickcontrols2/universal/TabBar.qml new file mode 100644 index 00000000000..9b98c10e784 --- /dev/null +++ b/src/quickcontrols2/universal/TabBar.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.TabBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + contentItem: ListView { + model: control.contentModel + currentIndex: control.currentIndex + + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + flickableDirection: Flickable.AutoFlickIfNeeded + snapMode: ListView.SnapToItem + + highlightMoveDuration: 100 + highlightRangeMode: ListView.ApplyRange + preferredHighlightBegin: 48 + preferredHighlightEnd: width - 48 + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 48 + color: control.Universal.background + } +} diff --git a/src/quickcontrols2/universal/TabButton.qml b/src/quickcontrols2/universal/TabButton.qml new file mode 100644 index 00000000000..a9e8aad47ab --- /dev/null +++ b/src/quickcontrols2/universal/TabButton.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.TabButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 12 // PivotItemMargin + spacing: 8 + + icon.width: 20 + icon.height: 20 + icon.color: Color.transparent(control.hovered ? control.Universal.baseMediumHighColor : control.Universal.foreground, + control.checked || control.down || control.hovered ? 1.0 : 0.2) + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: Color.transparent(enabled && control.hovered ? control.Universal.baseMediumHighColor : control.Universal.foreground, + control.checked || control.down || (enabled && control.hovered) ? 1.0 : 0.2) + } +} diff --git a/src/quickcontrols2/universal/TextArea.qml b/src/quickcontrols2/universal/TextArea.qml new file mode 100644 index 00000000000..6fa0066b758 --- /dev/null +++ b/src/quickcontrols2/universal/TextArea.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.TextArea { + id: control + + implicitWidth: Math.max(contentWidth + leftPadding + rightPadding, + implicitBackgroundWidth + leftInset + rightInset, + placeholder.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(contentHeight + topPadding + bottomPadding, + implicitBackgroundHeight + topInset + bottomInset, + placeholder.implicitHeight + topPadding + bottomPadding) + + // TextControlThemePadding + 2 (border) + padding: 12 + topPadding: padding - 7 + rightPadding: padding - 4 + bottomPadding: padding - 5 + + Universal.theme: activeFocus ? Universal.Light : undefined + + color: !enabled ? Universal.chromeDisabledLowColor : Universal.foreground + selectionColor: Universal.accent + selectedTextColor: Universal.chromeWhiteColor + placeholderTextColor: !enabled ? Universal.chromeDisabledLowColor : + activeFocus ? Universal.chromeBlackMediumLowColor : + Universal.baseMediumColor + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + verticalAlignment: control.verticalAlignment + elide: Text.ElideRight + renderType: control.renderType + } + + background: Rectangle { + implicitWidth: 60 // TextControlThemeMinWidth - 4 (border) + implicitHeight: 28 // TextControlThemeMinHeight - 4 (border) + + border.width: 2 // TextControlBorderThemeThickness + border.color: !control.enabled ? control.Universal.baseLowColor : + control.activeFocus ? control.Universal.accent : + control.hovered ? control.Universal.baseMediumColor : control.Universal.chromeDisabledLowColor + color: control.enabled ? control.Universal.background : control.Universal.baseLowColor + } +} diff --git a/src/quickcontrols2/universal/TextField.qml b/src/quickcontrols2/universal/TextField.qml new file mode 100644 index 00000000000..903f6728307 --- /dev/null +++ b/src/quickcontrols2/universal/TextField.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.TextField { + id: control + + implicitWidth: implicitBackgroundWidth + leftInset + rightInset + || Math.max(contentWidth, placeholder.implicitWidth) + leftPadding + rightPadding + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding, + placeholder.implicitHeight + topPadding + bottomPadding) + + // TextControlThemePadding + 2 (border) + padding: 12 + topPadding: padding - 7 + rightPadding: padding - 4 + bottomPadding: padding - 5 + + Universal.theme: activeFocus ? Universal.Light : undefined + + color: !enabled ? Universal.chromeDisabledLowColor : Universal.foreground + selectionColor: Universal.accent + selectedTextColor: Universal.chromeWhiteColor + placeholderTextColor: !enabled ? Universal.chromeDisabledLowColor : + activeFocus ? Universal.chromeBlackMediumLowColor : + Universal.baseMediumColor + verticalAlignment: TextInput.AlignVCenter + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + verticalAlignment: control.verticalAlignment + elide: Text.ElideRight + renderType: control.renderType + } + + background: Rectangle { + implicitWidth: 60 // TextControlThemeMinWidth - 4 (border) + implicitHeight: 28 // TextControlThemeMinHeight - 4 (border) + + border.width: 2 // TextControlBorderThemeThickness + border.color: !control.enabled ? control.Universal.baseLowColor : + control.activeFocus ? control.Universal.accent : + control.hovered ? control.Universal.baseMediumColor : control.Universal.chromeDisabledLowColor + color: control.enabled ? control.Universal.background : control.Universal.baseLowColor + } +} diff --git a/src/quickcontrols2/universal/ToolBar.qml b/src/quickcontrols2/universal/ToolBar.qml new file mode 100644 index 00000000000..0266056f131 --- /dev/null +++ b/src/quickcontrols2/universal/ToolBar.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.ToolBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + background: Rectangle { + implicitHeight: 48 // AppBarThemeCompactHeight + color: control.Universal.chromeMediumColor + } +} diff --git a/src/quickcontrols2/universal/ToolButton.qml b/src/quickcontrols2/universal/ToolButton.qml new file mode 100644 index 00000000000..5450ac3cdce --- /dev/null +++ b/src/quickcontrols2/universal/ToolButton.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +T.ToolButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 8 + + icon.width: 20 + icon.height: 20 + icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) + + property bool useSystemFocusVisuals: true + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) + } + + background: Rectangle { + implicitWidth: 68 + implicitHeight: 48 // AppBarThemeCompactHeight + + color: control.enabled && (control.highlighted || control.checked) ? control.Universal.accent : "transparent" + + Rectangle { + width: parent.width + height: parent.height + visible: enabled && (control.down || control.hovered) + color: control.down ? control.Universal.listMediumColor : control.Universal.listLowColor + } + } +} diff --git a/src/quickcontrols2/universal/ToolSeparator.qml b/src/quickcontrols2/universal/ToolSeparator.qml new file mode 100644 index 00000000000..c0be4df4448 --- /dev/null +++ b/src/quickcontrols2/universal/ToolSeparator.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.ToolSeparator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + leftPadding: vertical ? 16 : 12 + rightPadding: vertical ? 15 : 12 + topPadding: vertical ? 12 : 16 + bottomPadding: vertical ? 12 : 15 + + contentItem: Rectangle { + implicitWidth: control.vertical ? 1 : 20 + implicitHeight: control.vertical ? 20 : 1 + color: control.Universal.baseMediumLowColor + } +} diff --git a/src/quickcontrols2/universal/ToolTip.qml b/src/quickcontrols2/universal/ToolTip.qml new file mode 100644 index 00000000000..bf931a4c84b --- /dev/null +++ b/src/quickcontrols2/universal/ToolTip.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +T.ToolTip { + id: control + + x: parent ? (parent.width - implicitWidth) / 2 : 0 + y: -implicitHeight - 16 + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + margins: 8 + padding: 8 + topPadding: padding - 3 + bottomPadding: padding - 1 + + closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnReleaseOutsideParent + + contentItem: Text { + text: control.text + font: control.font + wrapMode: Text.Wrap + opacity: enabled ? 1.0 : 0.2 + color: control.Universal.foreground + } + + background: Rectangle { + color: control.Universal.chromeMediumLowColor + border.color: control.Universal.chromeHighColor + border.width: 1 // ToolTipBorderThemeThickness + } +} diff --git a/src/quickcontrols2/universal/Tumbler.qml b/src/quickcontrols2/universal/Tumbler.qml new file mode 100644 index 00000000000..1d1faa6c551 --- /dev/null +++ b/src/quickcontrols2/universal/Tumbler.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal +import QtQuick.Controls.impl + +T.Tumbler { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + delegate: Text { + text: modelData + font: control.font + color: control.Universal.foreground + opacity: (1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2)) * (control.enabled ? 1 : 0.6) + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + required property var modelData + required property int index + } + + contentItem: TumblerView { + implicitWidth: 60 + implicitHeight: 200 + model: control.model + delegate: control.delegate + path: Path { + startX: control.contentItem.width / 2 + startY: -control.contentItem.delegateHeight / 2 + PathLine { + x: control.contentItem.width / 2 + y: (control.visibleItemCount + 1) * control.contentItem.delegateHeight - control.contentItem.delegateHeight / 2 + } + } + + property real delegateHeight: control.availableHeight / control.visibleItemCount + } +} diff --git a/src/quickcontrols2/universal/VerticalHeaderView.qml b/src/quickcontrols2/universal/VerticalHeaderView.qml new file mode 100644 index 00000000000..7dc1efd3596 --- /dev/null +++ b/src/quickcontrols2/universal/VerticalHeaderView.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T +import QtQuick.Controls.Universal +import QtQuick.Controls.Universal.impl + +T.VerticalHeaderView { + id: control + + implicitWidth: contentWidth + implicitHeight: syncView ? syncView.height : 0 + + delegate: Rectangle { + // Qt6: add cellPadding (and font etc) as public API in headerview + readonly property real cellPadding: 8 + + implicitWidth: Math.max(control.width, text.implicitWidth + (cellPadding * 2)) + implicitHeight: text.implicitHeight + (cellPadding * 2) + color: control.Universal.background + + Text { + id: text + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] + : model[control.textRole]) + : modelData + width: parent.width + height: parent.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) + } + } +} diff --git a/src/quickcontrols2/universal/images/checkmark.png b/src/quickcontrols2/universal/images/checkmark.png new file mode 100644 index 00000000000..e2aae6fe0f3 Binary files /dev/null and b/src/quickcontrols2/universal/images/checkmark.png differ diff --git a/src/quickcontrols2/universal/images/checkmark@2x.png b/src/quickcontrols2/universal/images/checkmark@2x.png new file mode 100644 index 00000000000..0df4159a7ca Binary files /dev/null and b/src/quickcontrols2/universal/images/checkmark@2x.png differ diff --git a/src/quickcontrols2/universal/images/checkmark@3x.png b/src/quickcontrols2/universal/images/checkmark@3x.png new file mode 100644 index 00000000000..43466cbcb64 Binary files /dev/null and b/src/quickcontrols2/universal/images/checkmark@3x.png differ diff --git a/src/quickcontrols2/universal/images/checkmark@4x.png b/src/quickcontrols2/universal/images/checkmark@4x.png new file mode 100644 index 00000000000..7a47bd2159a Binary files /dev/null and b/src/quickcontrols2/universal/images/checkmark@4x.png differ diff --git a/src/quickcontrols2/universal/images/downarrow.png b/src/quickcontrols2/universal/images/downarrow.png new file mode 100644 index 00000000000..b66e2efc22f Binary files /dev/null and b/src/quickcontrols2/universal/images/downarrow.png differ diff --git a/src/quickcontrols2/universal/images/downarrow@2x.png b/src/quickcontrols2/universal/images/downarrow@2x.png new file mode 100644 index 00000000000..a704376c8fa Binary files /dev/null and b/src/quickcontrols2/universal/images/downarrow@2x.png differ diff --git a/src/quickcontrols2/universal/images/downarrow@3x.png b/src/quickcontrols2/universal/images/downarrow@3x.png new file mode 100644 index 00000000000..3b6d55ab4c1 Binary files /dev/null and b/src/quickcontrols2/universal/images/downarrow@3x.png differ diff --git a/src/quickcontrols2/universal/images/downarrow@4x.png b/src/quickcontrols2/universal/images/downarrow@4x.png new file mode 100644 index 00000000000..818c6b24ff4 Binary files /dev/null and b/src/quickcontrols2/universal/images/downarrow@4x.png differ diff --git a/src/quickcontrols2/universal/images/leftarrow.png b/src/quickcontrols2/universal/images/leftarrow.png new file mode 100644 index 00000000000..0153ccd421a Binary files /dev/null and b/src/quickcontrols2/universal/images/leftarrow.png differ diff --git a/src/quickcontrols2/universal/images/leftarrow@2x.png b/src/quickcontrols2/universal/images/leftarrow@2x.png new file mode 100644 index 00000000000..fa692d5b0f9 Binary files /dev/null and b/src/quickcontrols2/universal/images/leftarrow@2x.png differ diff --git a/src/quickcontrols2/universal/images/leftarrow@3x.png b/src/quickcontrols2/universal/images/leftarrow@3x.png new file mode 100644 index 00000000000..06b0207a601 Binary files /dev/null and b/src/quickcontrols2/universal/images/leftarrow@3x.png differ diff --git a/src/quickcontrols2/universal/images/leftarrow@4x.png b/src/quickcontrols2/universal/images/leftarrow@4x.png new file mode 100644 index 00000000000..1049f616e44 Binary files /dev/null and b/src/quickcontrols2/universal/images/leftarrow@4x.png differ diff --git a/src/quickcontrols2/universal/images/rightarrow.png b/src/quickcontrols2/universal/images/rightarrow.png new file mode 100644 index 00000000000..b24d117d79f Binary files /dev/null and b/src/quickcontrols2/universal/images/rightarrow.png differ diff --git a/src/quickcontrols2/universal/images/rightarrow@2x.png b/src/quickcontrols2/universal/images/rightarrow@2x.png new file mode 100644 index 00000000000..80aca7c18f9 Binary files /dev/null and b/src/quickcontrols2/universal/images/rightarrow@2x.png differ diff --git a/src/quickcontrols2/universal/images/rightarrow@3x.png b/src/quickcontrols2/universal/images/rightarrow@3x.png new file mode 100644 index 00000000000..ba017240657 Binary files /dev/null and b/src/quickcontrols2/universal/images/rightarrow@3x.png differ diff --git a/src/quickcontrols2/universal/images/rightarrow@4x.png b/src/quickcontrols2/universal/images/rightarrow@4x.png new file mode 100644 index 00000000000..21f7ed4d155 Binary files /dev/null and b/src/quickcontrols2/universal/images/rightarrow@4x.png differ diff --git a/src/quickcontrols2/universal/impl/CMakeLists.txt b/src/quickcontrols2/universal/impl/CMakeLists.txt new file mode 100644 index 00000000000..8a60cab8177 --- /dev/null +++ b/src/quickcontrols2/universal/impl/CMakeLists.txt @@ -0,0 +1,36 @@ +##################################################################### +## qtquickcontrols2universalstyleimplplugin Plugin: +##################################################################### + +set(qml_files + "CheckIndicator.qml" + "RadioIndicator.qml" + "SwitchIndicator.qml" +) + +qt_internal_add_qml_module(qtquickcontrols2universalstyleimplplugin + URI "QtQuick.Controls.Universal.impl" + VERSION "${PROJECT_VERSION}" + PAST_MAJOR_VERSIONS 2 + CLASS_NAME QtQuickControls2UniversalStyleImplPlugin + DEPENDENCIES + QtQuick/auto + PLUGIN_TARGET qtquickcontrols2universalstyleimplplugin + NO_PLUGIN_OPTIONAL + SOURCES + qquickuniversalbusyindicator.cpp qquickuniversalbusyindicator_p.h + qquickuniversalfocusrectangle.cpp qquickuniversalfocusrectangle_p.h + qquickuniversalprogressbar.cpp qquickuniversalprogressbar_p.h + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::QmlPrivate + Qt::QuickControls2ImplPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private +) diff --git a/src/quickcontrols2/universal/impl/CheckIndicator.qml b/src/quickcontrols2/universal/impl/CheckIndicator.qml new file mode 100644 index 00000000000..90c0c466df1 --- /dev/null +++ b/src/quickcontrols2/universal/impl/CheckIndicator.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Universal + +Rectangle { + id: indicator + implicitWidth: 20 + implicitHeight: 20 + + color: !control.enabled ? "transparent" : + control.down && !partiallyChecked ? control.Universal.baseMediumColor : + control.checkState === Qt.Checked ? control.Universal.accent : "transparent" + border.color: !control.enabled ? control.Universal.baseLowColor : + control.down ? control.Universal.baseMediumColor : + control.checked ? control.Universal.accent : control.Universal.baseMediumHighColor + border.width: 2 // CheckBoxBorderThemeThickness + + property Item control + readonly property bool partiallyChecked: control.checkState === Qt.PartiallyChecked + + ColorImage { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + visible: indicator.control.checkState === Qt.Checked + color: !indicator.control.enabled ? indicator.control.Universal.baseLowColor : indicator.control.Universal.chromeWhiteColor + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Universal/images/checkmark.png" + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: indicator.partiallyChecked ? parent.width / 2 : parent.width + height: indicator.partiallyChecked ? parent.height / 2 : parent.height + + visible: !indicator.control.pressed && enabled && indicator.control.hovered || indicator.partiallyChecked + color: !indicator.partiallyChecked ? "transparent" : + !indicator.control.enabled ? indicator.control.Universal.baseLowColor : + indicator.control.down ? indicator.control.Universal.baseMediumColor : + indicator.control.hovered ? indicator.control.Universal.baseHighColor : indicator.control.Universal.baseMediumHighColor + border.width: indicator.partiallyChecked ? 0 : 2 // CheckBoxBorderThemeThickness + border.color: indicator.control.Universal.baseMediumLowColor + } +} diff --git a/src/quickcontrols2/universal/impl/RadioIndicator.qml b/src/quickcontrols2/universal/impl/RadioIndicator.qml new file mode 100644 index 00000000000..3cf1bf37288 --- /dev/null +++ b/src/quickcontrols2/universal/impl/RadioIndicator.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.Universal + +Rectangle { + id: indicator + implicitWidth: 20 + implicitHeight: 20 + radius: width / 2 + color: "transparent" + border.width: 2 // RadioButtonBorderThemeThickness + border.color: control.checked ? "transparent" : + !control.enabled ? control.Universal.baseLowColor : + control.down ? control.Universal.baseMediumColor : + control.hovered ? control.Universal.baseHighColor : control.Universal.baseMediumHighColor + + property var control + + Rectangle { + id: checkOuterEllipse + width: parent.width + height: parent.height + + radius: width / 2 + opacity: indicator.control.checked ? 1 : 0 + color: "transparent" + border.width: 2 // RadioButtonBorderThemeThickness + border.color: !indicator.control.enabled ? indicator.control.Universal.baseLowColor : + indicator.control.down ? indicator.control.Universal.baseMediumColor : indicator.control.Universal.accent + } + + Rectangle { + id: checkGlyph + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: parent.width / 2 + height: parent.height / 2 + + radius: width / 2 + opacity: indicator.control.checked ? 1 : 0 + color: !indicator.control.enabled ? indicator.control.Universal.baseLowColor : + indicator.control.down ? indicator.control.Universal.baseMediumColor : + indicator.control.hovered ? indicator.control.Universal.baseHighColor : indicator.control.Universal.baseMediumHighColor + } +} diff --git a/src/quickcontrols2/universal/impl/SwitchIndicator.qml b/src/quickcontrols2/universal/impl/SwitchIndicator.qml new file mode 100644 index 00000000000..7a758386747 --- /dev/null +++ b/src/quickcontrols2/universal/impl/SwitchIndicator.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Universal + +Item { + id: indicator + implicitWidth: 44 + implicitHeight: 20 + + property T.AbstractButton control + + Rectangle { + width: parent.width + height: parent.height + + radius: 10 + color: !indicator.control.enabled ? "transparent" : + indicator.control.pressed ? indicator.control.Universal.baseMediumColor : + indicator.control.checked ? indicator.control.Universal.accent : "transparent" + border.color: !indicator.control.enabled ? indicator.control.Universal.baseLowColor : + indicator.control.checked && !indicator.control.pressed ? indicator.control.Universal.accent : + indicator.control.hovered && !indicator.control.checked && !indicator.control.pressed ? indicator.control.Universal.baseHighColor : indicator.control.Universal.baseMediumColor + opacity: enabled && indicator.control.hovered && indicator.control.checked && !indicator.control.pressed ? (indicator.control.Universal.theme === Universal.Light ? 0.7 : 0.9) : 1.0 + border.width: 2 + } + + Rectangle { + width: 10 + height: 10 + radius: 5 + + color: !indicator.control.enabled ? indicator.control.Universal.baseLowColor : + indicator.control.pressed || indicator.control.checked ? indicator.control.Universal.chromeWhiteColor : + indicator.control.hovered && !indicator.control.checked ? indicator.control.Universal.baseHighColor : indicator.control.Universal.baseMediumHighColor + + x: Math.max(5, Math.min(parent.width - width - 5, + indicator.control.visualPosition * parent.width - (width / 2))) + y: (parent.height - height) / 2 + + Behavior on x { + enabled: !indicator.control.pressed + SmoothedAnimation { velocity: 200 } + } + } +} diff --git a/src/quickcontrols2/universal/impl/qquickuniversalbusyindicator.cpp b/src/quickcontrols2/universal/impl/qquickuniversalbusyindicator.cpp new file mode 100644 index 00000000000..b624d41e616 --- /dev/null +++ b/src/quickcontrols2/universal/impl/qquickuniversalbusyindicator.cpp @@ -0,0 +1,253 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickuniversalbusyindicator_p.h" + +#include <QtCore/qmath.h> +#include <QtCore/qeasingcurve.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> +#include <QtQuickControls2Impl/private/qquickanimatednode_p.h> + +QT_BEGIN_NAMESPACE + +static const int PhaseCount = 6; +static const int Interval = 167; +static const int TotalDuration = 4052; + +class QQuickUniversalBusyIndicatorNode : public QQuickAnimatedNode +{ +public: + QQuickUniversalBusyIndicatorNode(QQuickUniversalBusyIndicator *item); + + void updateCurrentTime(int time) override; + void sync(QQuickItem *item) override; + +private: + struct Phase { + Phase() = default; + Phase(int d, qreal f, qreal t, QEasingCurve::Type c) : duration(d), from(f), to(t), curve(c) { } + int duration = 0; + qreal from = 0; + qreal to = 0; + QEasingCurve curve = QEasingCurve::Linear; + }; + + Phase m_phases[PhaseCount]; +}; + +QQuickUniversalBusyIndicatorNode::QQuickUniversalBusyIndicatorNode(QQuickUniversalBusyIndicator *item) + : QQuickAnimatedNode(item) +{ + setLoopCount(Infinite); + setDuration(TotalDuration); + setCurrentTime(item->elapsed()); + + m_phases[0] = Phase(433, -110, 10, QEasingCurve::BezierSpline); + m_phases[1] = Phase(767, 10, 93, QEasingCurve::Linear ); + m_phases[2] = Phase(417, 93, 205, QEasingCurve::BezierSpline); + m_phases[3] = Phase(400, 205, 357, QEasingCurve::BezierSpline); + m_phases[4] = Phase(766, 357, 439, QEasingCurve::Linear ); + m_phases[5] = Phase(434, 439, 585, QEasingCurve::BezierSpline); + + m_phases[0].curve.addCubicBezierSegment(QPointF(0.02, 0.33), QPointF(0.38, 0.77), QPointF(1.00, 1.00)); + m_phases[2].curve.addCubicBezierSegment(QPointF(0.57, 0.17), QPointF(0.95, 0.75), QPointF(1.00, 1.00)); + m_phases[3].curve.addCubicBezierSegment(QPointF(0.00, 0.19), QPointF(0.07, 0.72), QPointF(1.00, 1.00)); + m_phases[5].curve.addCubicBezierSegment(QPointF(0.00, 0.00), QPointF(0.95, 0.37), QPointF(1.00, 1.00)); +} + +void QQuickUniversalBusyIndicatorNode::updateCurrentTime(int time) +{ + int nodeIndex = 0; + int count = childCount(); + QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(firstChild()); + while (transformNode) { + Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType); + + QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(transformNode->firstChild()); + Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType); + + int begin = nodeIndex * Interval; + int end = TotalDuration - (PhaseCount - nodeIndex - 1) * Interval; + + bool visible = time >= begin && time <= end; + opacityNode->setOpacity(visible ? 1.0 : 0.0); + + if (visible) { + int phaseIndex, remain = time, elapsed = 0; + for (phaseIndex = 0; phaseIndex < PhaseCount - 1; ++phaseIndex) { + if (remain <= m_phases[phaseIndex].duration + begin) + break; + remain -= m_phases[phaseIndex].duration; + elapsed += m_phases[phaseIndex].duration; + } + + const Phase &phase = m_phases[phaseIndex]; + + qreal from = phase.from - nodeIndex * count; + qreal to = phase.to - nodeIndex * count; + qreal pos = time - elapsed - begin; + + qreal value = phase.curve.valueForProgress(pos / phase.duration); + qreal rotation = from + (to - from) * value; + + QMatrix4x4 matrix; + matrix.rotate(rotation, 0, 0, 1); + transformNode->setMatrix(matrix); + } + + transformNode = static_cast<QSGTransformNode *>(transformNode->nextSibling()); + ++nodeIndex; + } +} + +void QQuickUniversalBusyIndicatorNode::sync(QQuickItem *item) +{ + QQuickUniversalBusyIndicator *indicator = static_cast<QQuickUniversalBusyIndicator *>(item); + QQuickItemPrivate *d = QQuickItemPrivate::get(item); + + QMatrix4x4 matrix; + matrix.translate(item->width() / 2, item->height() / 2); + setMatrix(matrix); + + qreal size = qMin(item->width(), item->height()); + qreal diameter = size / 10.0; + qreal radius = diameter / 2; + qreal offset = (size - diameter * 2) / M_PI; + const QRectF rect(offset, offset, diameter, diameter); + + int count = indicator->count(); + QSGNode *transformNode = firstChild(); + for (int i = 0; i < count; ++i) { + if (!transformNode) { + transformNode = new QSGTransformNode; + appendChildNode(transformNode); + + QSGOpacityNode *opacityNode = new QSGOpacityNode; + transformNode->appendChildNode(opacityNode); + + QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode(); + rectNode->setAntialiasing(true); + opacityNode->appendChildNode(rectNode); + } + + QSGNode *opacityNode = transformNode->firstChild(); + Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType); + + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild()); + Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); + + rectNode->setRect(rect); + rectNode->setColor(indicator->color()); + rectNode->setRadius(radius); + rectNode->update(); + + transformNode = transformNode->nextSibling(); + } + + while (transformNode) { + QSGNode *nextSibling = transformNode->nextSibling(); + delete transformNode; + transformNode = nextSibling; + } +} + +QQuickUniversalBusyIndicator::QQuickUniversalBusyIndicator(QQuickItem *parent) + : QQuickItem(parent) +{ + setFlag(ItemHasContents); +} + +int QQuickUniversalBusyIndicator::count() const +{ + return m_count; +} + +void QQuickUniversalBusyIndicator::setCount(int count) +{ + if (m_count == count) + return; + + m_count = count; + update(); +} + +QColor QQuickUniversalBusyIndicator::color() const +{ + return m_color; +} + +void QQuickUniversalBusyIndicator::setColor(const QColor &color) +{ + if (m_color == color) + return; + + m_color = color; + update(); +} + +int QQuickUniversalBusyIndicator::elapsed() const +{ + return m_elapsed; +} + +void QQuickUniversalBusyIndicator::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + if (change == ItemVisibleHasChanged) + update(); +} + +QSGNode *QQuickUniversalBusyIndicator::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + QQuickUniversalBusyIndicatorNode *node = static_cast<QQuickUniversalBusyIndicatorNode *>(oldNode); + if (isVisible() && width() > 0 && height() > 0) { + if (!node) { + node = new QQuickUniversalBusyIndicatorNode(this); + node->start(); + } + node->sync(this); + } else { + m_elapsed = node ? node->currentTime() : 0; + delete node; + node = nullptr; + } + return node; +} + +QT_END_NAMESPACE + +#include "moc_qquickuniversalbusyindicator_p.cpp" diff --git a/src/quickcontrols2/universal/impl/qquickuniversalbusyindicator_p.h b/src/quickcontrols2/universal/impl/qquickuniversalbusyindicator_p.h new file mode 100644 index 00000000000..6d3ebb8493f --- /dev/null +++ b/src/quickcontrols2/universal/impl/qquickuniversalbusyindicator_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKUNIVERSALBUSYINDICATOR_P_H +#define QQUICKUNIVERSALBUSYINDICATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qcolor.h> +#include <QtQuick/qquickitem.h> + +QT_BEGIN_NAMESPACE + +class QQuickUniversalBusyIndicator : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(int count READ count WRITE setCount FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + QML_NAMED_ELEMENT(BusyIndicatorImpl) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickUniversalBusyIndicator(QQuickItem *parent = nullptr); + + int count() const; + void setCount(int count); + + QColor color() const; + void setColor(const QColor &color); + + int elapsed() const; + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override; + +private: + int m_count = 5; + int m_elapsed = 0; + QColor m_color = Qt::black; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickUniversalBusyIndicator) + +#endif // QQUICKUNIVERSALBUSYINDICATOR_P_H diff --git a/src/quickcontrols2/universal/impl/qquickuniversalfocusrectangle.cpp b/src/quickcontrols2/universal/impl/qquickuniversalfocusrectangle.cpp new file mode 100644 index 00000000000..3f4d8251ab1 --- /dev/null +++ b/src/quickcontrols2/universal/impl/qquickuniversalfocusrectangle.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickuniversalfocusrectangle_p.h" + +#include <QtGui/qpixmap.h> +#include <QtGui/qpainter.h> +#include <QtGui/qpixmapcache.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +QQuickUniversalFocusRectangle::QQuickUniversalFocusRectangle(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ + QQuickItemPrivate::get(this)->setTransparentForPositioner(true); +} + +void QQuickUniversalFocusRectangle::paint(QPainter *painter) +{ + if (!isVisible() || width() <= 0 || height() <= 0) + return; + + QRect bounds = boundingRect().toAlignedRect(); + const int boundsWidth = bounds.width(); + const int boundsHeight = bounds.width(); + const QString key = QStringLiteral("qquickuniversalfocusrectangle_%1_%2").arg(QString::number(boundsWidth), QString::number(boundsHeight)); + + QPixmap pixmap(boundsWidth, boundsHeight); + if (!QPixmapCache::find(key, &pixmap)) { + bounds.adjust(0, 0, -1, -1); + pixmap.fill(Qt::transparent); + QPainter p(&pixmap); + + QPen pen; + pen.setWidth(1); + pen.setColor(Qt::white); + p.setPen(pen); + p.drawRect(bounds); + + pen.setColor(Qt::black); + pen.setDashPattern(QList<qreal>(2, 1)); + p.setPen(pen); + p.drawRect(bounds); + + QPixmapCache::insert(key, pixmap); + } + painter->drawPixmap(0, 0, pixmap); +} + +QT_END_NAMESPACE + +#include "moc_qquickuniversalfocusrectangle_p.cpp" diff --git a/src/quickcontrols2/universal/impl/qquickuniversalfocusrectangle_p.h b/src/quickcontrols2/universal/impl/qquickuniversalfocusrectangle_p.h new file mode 100644 index 00000000000..f309b512273 --- /dev/null +++ b/src/quickcontrols2/universal/impl/qquickuniversalfocusrectangle_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKUNIVERSALFOCUSRECTANGLE_P_H +#define QQUICKUNIVERSALFOCUSRECTANGLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickpainteditem.h> + +QT_BEGIN_NAMESPACE + +class QQuickUniversalFocusRectangle : public QQuickPaintedItem +{ + Q_OBJECT + QML_NAMED_ELEMENT(FocusRectangle) + QML_ADDED_IN_VERSION(2, 0) + +public: + QQuickUniversalFocusRectangle(QQuickItem *parent = nullptr); + + void paint(QPainter *painter) override; +}; + +QT_END_NAMESPACE + +#endif // QQUICKUNIVERSALFOCUSRECTANGLE_P_H diff --git a/src/quickcontrols2/universal/impl/qquickuniversalprogressbar.cpp b/src/quickcontrols2/universal/impl/qquickuniversalprogressbar.cpp new file mode 100644 index 00000000000..ab7e6c129b7 --- /dev/null +++ b/src/quickcontrols2/universal/impl/qquickuniversalprogressbar.cpp @@ -0,0 +1,340 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickuniversalprogressbar_p.h" + +#include <QtCore/qmath.h> +#include <QtCore/qeasingcurve.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> +#include <QtQuick/qsgrectanglenode.h> +#include <QtQuickControls2Impl/private/qquickanimatednode_p.h> + +QT_BEGIN_NAMESPACE + +static const int PhaseCount = 4; +static const int EllipseCount = 5; +static const int Interval = 167; +static const int TotalDuration = 3917; +static const int VisibleDuration = 3000; +static const qreal EllipseDiameter = 4; +static const qreal EllipseOffset = 4; +static const qreal ContainerAnimationStartPosition = -34; // absolute +static const qreal ContainerAnimationEndPosition = 0.435222; // relative +static const qreal EllipseAnimationWellPosition = 0.333333333333333; // relative +static const qreal EllipseAnimationEndPosition = 0.666666666666667; // relative + +class QQuickUniversalProgressBarNode : public QQuickAnimatedNode +{ +public: + QQuickUniversalProgressBarNode(QQuickUniversalProgressBar *item); + + void updateCurrentTime(int time) override; + void sync(QQuickItem *item) override; + +private: + struct Phase { + Phase() = default; + Phase(int d, qreal f, qreal t) : duration(d), from(f), to(t) { } + int duration = 0; + qreal from = 0; + qreal to = 0; + }; + + bool m_indeterminate = false; + Phase m_borderPhases[PhaseCount]; + Phase m_ellipsePhases[PhaseCount]; +}; + +QQuickUniversalProgressBarNode::QQuickUniversalProgressBarNode(QQuickUniversalProgressBar *item) + : QQuickAnimatedNode(item) +{ + setLoopCount(Infinite); + setDuration(TotalDuration); + + m_borderPhases[0] = Phase( 500, -50, 0); + m_borderPhases[1] = Phase(1500, 0, 0); + m_borderPhases[2] = Phase(1000, 0, 100); + m_borderPhases[3] = Phase( 917, 100, 100); + + m_ellipsePhases[0] = Phase(1000, 0, EllipseAnimationWellPosition); + m_ellipsePhases[1] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationWellPosition); + m_ellipsePhases[2] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationEndPosition); + m_ellipsePhases[3] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationEndPosition); +} + +void QQuickUniversalProgressBarNode::updateCurrentTime(int time) +{ + QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild()); + Q_ASSERT(!geometryNode || geometryNode->type() == QSGNode::GeometryNodeType); + if (!geometryNode) + return; + + QSGTransformNode *gridNode = static_cast<QSGTransformNode *>(geometryNode->firstChild()); + Q_ASSERT(!gridNode || gridNode->type() == QSGNode::TransformNodeType); + if (!gridNode) + return; + + qreal width = geometryNode->rect().width(); + { + qreal from = ContainerAnimationStartPosition; + qreal to = from + ContainerAnimationEndPosition * width; + qreal progress = static_cast<qreal>(time) / TotalDuration; + qreal dx = from + (to - from) * progress; + + QMatrix4x4 matrix; + matrix.translate(dx, 0); + gridNode->setMatrix(matrix); + } + + int nodeIndex = 0; + QSGTransformNode *borderNode = static_cast<QSGTransformNode *>(gridNode->firstChild()); + while (borderNode) { + Q_ASSERT(borderNode->type() == QSGNode::TransformNodeType); + + QSGTransformNode *ellipseNode = static_cast<QSGTransformNode *>(borderNode->firstChild()); + Q_ASSERT(ellipseNode->type() == QSGNode::TransformNodeType); + + QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(ellipseNode->firstChild()); + Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType); + + int begin = nodeIndex * Interval; + int end = VisibleDuration + nodeIndex * Interval; + + bool visible = time >= begin && time <= end; + opacityNode->setOpacity(visible ? 1.0 : 0.0); + + if (visible) { + { + int phaseIndex, remain = time, elapsed = 0; + for (phaseIndex = 0; phaseIndex < PhaseCount - 1; ++phaseIndex) { + if (remain <= m_borderPhases[phaseIndex].duration + begin) + break; + remain -= m_borderPhases[phaseIndex].duration; + elapsed += m_borderPhases[phaseIndex].duration; + } + + const Phase &phase = m_borderPhases[phaseIndex]; + + qreal pos = time - elapsed - begin; + qreal progress = pos / phase.duration; + qreal dx = phase.from + (phase.to - phase.from) * progress; + + QMatrix4x4 matrix; + matrix.translate(dx, 0); + borderNode->setMatrix(matrix); + } + + { + QEasingCurve curve(QEasingCurve::BezierSpline); + curve.addCubicBezierSegment(QPointF(0.4, 0.0), QPointF(0.6, 1.0), QPointF(1.0, 1.0)); + + int phaseIndex, remain = time, elapsed = 0; + for (phaseIndex = 0; phaseIndex < PhaseCount - 1; ++phaseIndex) { + if (remain <= m_ellipsePhases[phaseIndex].duration + begin) + break; + remain -= m_ellipsePhases[phaseIndex].duration; + elapsed += m_ellipsePhases[phaseIndex].duration; + } + + const Phase &phase = m_ellipsePhases[phaseIndex]; + + qreal from = phase.from * width; + qreal to = phase.to * width; + qreal pos = time - elapsed - begin; + qreal progress = curve.valueForProgress(pos / phase.duration); + qreal dx = from + (to - from) * progress; + + QMatrix4x4 matrix; + matrix.translate(dx, 0); + ellipseNode->setMatrix(matrix); + } + } + + borderNode = static_cast<QSGTransformNode *>(borderNode->nextSibling()); + ++nodeIndex; + } +} + +void QQuickUniversalProgressBarNode::sync(QQuickItem *item) +{ + QQuickUniversalProgressBar *bar = static_cast<QQuickUniversalProgressBar *>(item); + if (m_indeterminate != bar->isIndeterminate()) { + m_indeterminate = bar->isIndeterminate(); + if (m_indeterminate) + start(); + else + stop(); + } + + QQuickItemPrivate *d = QQuickItemPrivate::get(item); + + QRectF bounds = item->boundingRect(); + bounds.setHeight(item->implicitHeight()); + bounds.moveTop((item->height() - bounds.height()) / 2.0); + if (!m_indeterminate) + bounds.setWidth(bar->progress() * bounds.width()); + + QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild()); + if (!geometryNode) { + geometryNode = item->window()->createRectangleNode(); + appendChildNode(geometryNode); + } + geometryNode->setRect(bounds); + geometryNode->setColor(m_indeterminate ? Qt::transparent : bar->color()); + + if (!m_indeterminate) { + while (QSGNode *node = geometryNode->firstChild()) + delete node; + return; + } + + QSGTransformNode *gridNode = static_cast<QSGTransformNode *>(geometryNode->firstChild()); + if (!gridNode) { + gridNode = new QSGTransformNode; + geometryNode->appendChildNode(gridNode); + } + Q_ASSERT(gridNode->type() == QSGNode::TransformNodeType); + + QSGNode *borderNode = gridNode->firstChild(); + for (int i = 0; i < EllipseCount; ++i) { + if (!borderNode) { + borderNode = new QSGTransformNode; + gridNode->appendChildNode(borderNode); + + QSGTransformNode *ellipseNode = new QSGTransformNode; + borderNode->appendChildNode(ellipseNode); + + QSGOpacityNode *opacityNode = new QSGOpacityNode; + ellipseNode->appendChildNode(opacityNode); + + QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode(); + rectNode->setAntialiasing(true); + rectNode->setRadius(EllipseDiameter / 2); + opacityNode->appendChildNode(rectNode); + } + Q_ASSERT(borderNode->type() == QSGNode::TransformNodeType); + + QSGNode *ellipseNode = borderNode->firstChild(); + Q_ASSERT(ellipseNode->type() == QSGNode::TransformNodeType); + + QSGNode *opacityNode = ellipseNode->firstChild(); + Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType); + + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild()); + Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); + + rectNode->setRect(QRectF((EllipseCount - i - 1) * (EllipseDiameter + EllipseOffset), (item->height() - EllipseDiameter) / 2, EllipseDiameter, EllipseDiameter)); + rectNode->setColor(bar->color()); + rectNode->update(); + + borderNode = borderNode->nextSibling(); + } +} + +QQuickUniversalProgressBar::QQuickUniversalProgressBar(QQuickItem *parent) + : QQuickItem(parent) +{ + setFlag(ItemHasContents); +} + +QColor QQuickUniversalProgressBar::color() const +{ + return m_color; +} + +void QQuickUniversalProgressBar::setColor(const QColor &color) +{ + if (m_color == color) + return; + + m_color = color; + update(); +} + +qreal QQuickUniversalProgressBar::progress() const +{ + return m_progress; +} + +void QQuickUniversalProgressBar::setProgress(qreal progress) +{ + if (progress == m_progress) + return; + + m_progress = progress; + update(); +} + +bool QQuickUniversalProgressBar::isIndeterminate() const +{ + return m_indeterminate; +} + +void QQuickUniversalProgressBar::setIndeterminate(bool indeterminate) +{ + if (indeterminate == m_indeterminate) + return; + + m_indeterminate = indeterminate; + setClip(m_indeterminate); + update(); +} + +void QQuickUniversalProgressBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + if (change == ItemVisibleHasChanged) + update(); +} + +QSGNode *QQuickUniversalProgressBar::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) +{ + QQuickUniversalProgressBarNode *node = static_cast<QQuickUniversalProgressBarNode *>(oldNode); + if (isVisible() && width() > 0 && height() > 0) { + if (!node) + node = new QQuickUniversalProgressBarNode(this); + node->sync(this); + } else { + delete node; + node = nullptr; + } + return node; +} + +QT_END_NAMESPACE + +#include "moc_qquickuniversalprogressbar_p.cpp" diff --git a/src/quickcontrols2/universal/impl/qquickuniversalprogressbar_p.h b/src/quickcontrols2/universal/impl/qquickuniversalprogressbar_p.h new file mode 100644 index 00000000000..31cb4a322e2 --- /dev/null +++ b/src/quickcontrols2/universal/impl/qquickuniversalprogressbar_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKUNIVERSALPROGRESSBAR_P_H +#define QQUICKUNIVERSALPROGRESSBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qcolor.h> +#include <QtQuick/qquickitem.h> + +QT_BEGIN_NAMESPACE + +class QQuickUniversalProgressBar : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + Q_PROPERTY(qreal progress READ progress WRITE setProgress FINAL) + Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate FINAL) + QML_NAMED_ELEMENT(ProgressBarImpl) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickUniversalProgressBar(QQuickItem *parent = nullptr); + + QColor color() const; + void setColor(const QColor &color); + + qreal progress() const; + void setProgress(qreal progress); + + bool isIndeterminate() const; + void setIndeterminate(bool indeterminate); + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override; + +private: + QColor m_color = Qt::black; + qreal m_progress = 0.0; + bool m_indeterminate = false; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickUniversalProgressBar) + +#endif // QQUICKUNIVERSALPROGRESSBAR_P_H diff --git a/src/quickcontrols2/universal/qquickuniversalstyle.cpp b/src/quickcontrols2/universal/qquickuniversalstyle.cpp new file mode 100644 index 00000000000..3965b4618e5 --- /dev/null +++ b/src/quickcontrols2/universal/qquickuniversalstyle.cpp @@ -0,0 +1,620 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickuniversalstyle_p.h" + +#include <QtCore/qdebug.h> +#include <QtCore/qsettings.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuickControls2/private/qquickstyle_p.h> + +QT_BEGIN_NAMESPACE + +static QRgb qquickuniversal_light_color(QQuickUniversalStyle::SystemColor role) +{ + static const QRgb colors[] = { + 0xFFFFFFFF, // SystemAltHighColor + 0x33FFFFFF, // SystemAltLowColor + 0x99FFFFFF, // SystemAltMediumColor + 0xCCFFFFFF, // SystemAltMediumHighColor + 0x66FFFFFF, // SystemAltMediumLowColor + 0xFF000000, // SystemBaseHighColor + 0x33000000, // SystemBaseLowColor + 0x99000000, // SystemBaseMediumColor + 0xCC000000, // SystemBaseMediumHighColor + 0x66000000, // SystemBaseMediumLowColor + 0xFF171717, // SystemChromeAltLowColor + 0xFF000000, // SystemChromeBlackHighColor + 0x33000000, // SystemChromeBlackLowColor + 0x66000000, // SystemChromeBlackMediumLowColor + 0xCC000000, // SystemChromeBlackMediumColor + 0xFFCCCCCC, // SystemChromeDisabledHighColor + 0xFF7A7A7A, // SystemChromeDisabledLowColor + 0xFFCCCCCC, // SystemChromeHighColor + 0xFFF2F2F2, // SystemChromeLowColor + 0xFFE6E6E6, // SystemChromeMediumColor + 0xFFF2F2F2, // SystemChromeMediumLowColor + 0xFFFFFFFF, // SystemChromeWhiteColor + 0x19000000, // SystemListLowColor + 0x33000000 // SystemListMediumColor + }; + return colors[role]; +} + +static QRgb qquickuniversal_dark_color(QQuickUniversalStyle::SystemColor role) +{ + static const QRgb colors[] = { + 0xFF000000, // SystemAltHighColor + 0x33000000, // SystemAltLowColor + 0x99000000, // SystemAltMediumColor + 0xCC000000, // SystemAltMediumHighColor + 0x66000000, // SystemAltMediumLowColor + 0xFFFFFFFF, // SystemBaseHighColor + 0x33FFFFFF, // SystemBaseLowColor + 0x99FFFFFF, // SystemBaseMediumColor + 0xCCFFFFFF, // SystemBaseMediumHighColor + 0x66FFFFFF, // SystemBaseMediumLowColor + 0xFFF2F2F2, // SystemChromeAltLowColor + 0xFF000000, // SystemChromeBlackHighColor + 0x33000000, // SystemChromeBlackLowColor + 0x66000000, // SystemChromeBlackMediumLowColor + 0xCC000000, // SystemChromeBlackMediumColor + 0xFF333333, // SystemChromeDisabledHighColor + 0xFF858585, // SystemChromeDisabledLowColor + 0xFF767676, // SystemChromeHighColor + 0xFF171717, // SystemChromeLowColor + 0xFF1F1F1F, // SystemChromeMediumColor + 0xFF2B2B2B, // SystemChromeMediumLowColor + 0xFFFFFFFF, // SystemChromeWhiteColor + 0x19FFFFFF, // SystemListLowColor + 0x33FFFFFF // SystemListMediumColor + }; + return colors[role]; +} + +static QRgb qquickuniversal_accent_color(QQuickUniversalStyle::Color accent) +{ + static const QRgb colors[] = { + 0xFFA4C400, // Lime + 0xFF60A917, // Green + 0xFF008A00, // Emerald + 0xFF00ABA9, // Teal + 0xFF1BA1E2, // Cyan + 0xFF3E65FF, // Cobalt + 0xFF6A00FF, // Indigo + 0xFFAA00FF, // Violet + 0xFFF472D0, // Pink + 0xFFD80073, // Magenta + 0xFFA20025, // Crimson + 0xFFE51400, // Red + 0xFFFA6800, // Orange + 0xFFF0A30A, // Amber + 0xFFE3C800, // Yellow + 0xFF825A2C, // Brown + 0xFF6D8764, // Olive + 0xFF647687, // Steel + 0xFF76608A, // Mauve + 0xFF87794E // Taupe + }; + return colors[accent]; +} + +static QQuickUniversalStyle::Theme qquickuniversal_effective_theme(QQuickUniversalStyle::Theme theme) +{ + if (theme == QQuickUniversalStyle::System) + theme = QQuickStylePrivate::isDarkSystemTheme() ? QQuickUniversalStyle::Dark : QQuickUniversalStyle::Light; + return theme; +} + +// If no value was inherited from a parent or explicitly set, the "global" values are used. +// The initial, default values of the globals are hard-coded here, but the environment +// variables and .conf file override them if specified. +static QQuickUniversalStyle::Theme GlobalTheme = QQuickUniversalStyle::Light; +static QRgb GlobalAccent = qquickuniversal_accent_color(QQuickUniversalStyle::Cobalt); +static QRgb GlobalForeground = qquickuniversal_light_color(QQuickUniversalStyle::BaseHigh); +static QRgb GlobalBackground = qquickuniversal_light_color(QQuickUniversalStyle::AltHigh); +// These represent whether a global foreground/background was set. +// Each style's m_hasForeground/m_hasBackground are initialized to these values. +static bool HasGlobalForeground = false; +static bool HasGlobalBackground = false; + +QQuickUniversalStyle::QQuickUniversalStyle(QObject *parent) : QQuickAttachedObject(parent), + m_hasForeground(HasGlobalForeground), m_hasBackground(HasGlobalBackground), m_theme(GlobalTheme), + m_accent(GlobalAccent), m_foreground(GlobalForeground), m_background(GlobalBackground) +{ + init(); +} + +QQuickUniversalStyle *QQuickUniversalStyle::qmlAttachedProperties(QObject *object) +{ + return new QQuickUniversalStyle(object); +} + +QQuickUniversalStyle::Theme QQuickUniversalStyle::theme() const +{ + return m_theme; +} + +void QQuickUniversalStyle::setTheme(Theme theme) +{ + theme = qquickuniversal_effective_theme(theme); + m_explicitTheme = true; + if (m_theme == theme) + return; + + m_theme = theme; + propagateTheme(); + emit themeChanged(); + emit paletteChanged(); + emit foregroundChanged(); + emit backgroundChanged(); +} + +void QQuickUniversalStyle::inheritTheme(Theme theme) +{ + if (m_explicitTheme || m_theme == theme) + return; + + m_theme = theme; + propagateTheme(); + emit themeChanged(); + emit paletteChanged(); + emit foregroundChanged(); + emit backgroundChanged(); +} + +void QQuickUniversalStyle::propagateTheme() +{ + const auto styles = attachedChildren(); + for (QQuickAttachedObject *child : styles) { + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(child); + if (universal) + universal->inheritTheme(m_theme); + } +} + +void QQuickUniversalStyle::resetTheme() +{ + if (!m_explicitTheme) + return; + + m_explicitTheme = false; + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(attachedParent()); + inheritTheme(universal ? universal->theme() : GlobalTheme); +} + +QVariant QQuickUniversalStyle::accent() const +{ + return QColor::fromRgba(m_accent); +} + +void QQuickUniversalStyle::setAccent(const QVariant &var) +{ + QRgb accent = 0; + if (!variantToRgba(var, "accent", &accent)) + return; + + m_explicitAccent = true; + if (m_accent == accent) + return; + + m_accent = accent; + propagateAccent(); + emit accentChanged(); +} + +void QQuickUniversalStyle::inheritAccent(QRgb accent) +{ + if (m_explicitAccent || m_accent == accent) + return; + + m_accent = accent; + propagateAccent(); + emit accentChanged(); +} + +void QQuickUniversalStyle::propagateAccent() +{ + const auto styles = attachedChildren(); + for (QQuickAttachedObject *child : styles) { + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(child); + if (universal) + universal->inheritAccent(m_accent); + } +} + +void QQuickUniversalStyle::resetAccent() +{ + if (!m_explicitAccent) + return; + + m_explicitAccent = false; + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(attachedParent()); + inheritAccent(universal ? universal->m_accent : GlobalAccent); +} + +QVariant QQuickUniversalStyle::foreground() const +{ + if (m_hasForeground) + return QColor::fromRgba(m_foreground); + return baseHighColor(); +} + +void QQuickUniversalStyle::setForeground(const QVariant &var) +{ + QRgb foreground = 0; + if (!variantToRgba(var, "foreground", &foreground)) + return; + + m_hasForeground = true; + m_explicitForeground = true; + if (m_foreground == foreground) + return; + + m_foreground = foreground; + propagateForeground(); + emit foregroundChanged(); +} + +void QQuickUniversalStyle::inheritForeground(QRgb foreground, bool has) +{ + if (m_explicitForeground || m_foreground == foreground) + return; + + m_hasForeground = has; + m_foreground = foreground; + propagateForeground(); + emit foregroundChanged(); +} + +void QQuickUniversalStyle::propagateForeground() +{ + const auto styles = attachedChildren(); + for (QQuickAttachedObject *child : styles) { + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(child); + if (universal) + universal->inheritForeground(m_foreground, m_hasForeground); + } +} + +void QQuickUniversalStyle::resetForeground() +{ + if (!m_explicitForeground) + return; + + m_hasForeground = false; + m_explicitForeground = false; + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(attachedParent()); + inheritForeground(universal ? universal->m_foreground : GlobalForeground, universal ? universal->m_hasForeground : false); +} + +QVariant QQuickUniversalStyle::background() const +{ + if (m_hasBackground) + return QColor::fromRgba(m_background); + return altHighColor(); +} + +void QQuickUniversalStyle::setBackground(const QVariant &var) +{ + QRgb background = 0; + if (!variantToRgba(var, "background", &background)) + return; + + m_hasBackground = true; + m_explicitBackground = true; + if (m_background == background) + return; + + m_background = background; + propagateBackground(); + emit backgroundChanged(); +} + +void QQuickUniversalStyle::inheritBackground(QRgb background, bool has) +{ + if (m_explicitBackground || m_background == background) + return; + + m_hasBackground = has; + m_background = background; + propagateBackground(); + emit backgroundChanged(); +} + +void QQuickUniversalStyle::propagateBackground() +{ + const auto styles = attachedChildren(); + for (QQuickAttachedObject *child : styles) { + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(child); + if (universal) + universal->inheritBackground(m_background, m_hasBackground); + } +} + +void QQuickUniversalStyle::resetBackground() +{ + if (!m_explicitBackground) + return; + + m_hasBackground = false; + m_explicitBackground = false; + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(attachedParent()); + inheritBackground(universal ? universal->m_background : GlobalBackground, universal ? universal->m_hasBackground : false); +} + +QColor QQuickUniversalStyle::color(Color color) const +{ + return qquickuniversal_accent_color(color); +} + +QColor QQuickUniversalStyle::altHighColor() const +{ + return systemColor(AltHigh); +} + +QColor QQuickUniversalStyle::altLowColor() const +{ + return systemColor(AltLow); +} + +QColor QQuickUniversalStyle::altMediumColor() const +{ + return systemColor(AltMedium); +} + +QColor QQuickUniversalStyle::altMediumHighColor() const +{ + return systemColor(AltMediumHigh); +} + +QColor QQuickUniversalStyle::altMediumLowColor() const +{ + return systemColor(AltMediumLow); +} + +QColor QQuickUniversalStyle::baseHighColor() const +{ + return systemColor(BaseHigh); +} + +QColor QQuickUniversalStyle::baseLowColor() const +{ + return systemColor(BaseLow); +} + +QColor QQuickUniversalStyle::baseMediumColor() const +{ + return systemColor(BaseMedium); +} + +QColor QQuickUniversalStyle::baseMediumHighColor() const +{ + return systemColor(BaseMediumHigh); +} + +QColor QQuickUniversalStyle::baseMediumLowColor() const +{ + return systemColor(BaseMediumLow); +} + +QColor QQuickUniversalStyle::chromeAltLowColor() const +{ + return systemColor(ChromeAltLow); +} + +QColor QQuickUniversalStyle::chromeBlackHighColor() const +{ + return systemColor(ChromeBlackHigh); +} + +QColor QQuickUniversalStyle::chromeBlackLowColor() const +{ + return systemColor(ChromeBlackLow); +} + +QColor QQuickUniversalStyle::chromeBlackMediumLowColor() const +{ + return systemColor(ChromeBlackMediumLow); +} + +QColor QQuickUniversalStyle::chromeBlackMediumColor() const +{ + return systemColor(ChromeBlackMedium); +} + +QColor QQuickUniversalStyle::chromeDisabledHighColor() const +{ + return systemColor(ChromeDisabledHigh); +} + +QColor QQuickUniversalStyle::chromeDisabledLowColor() const +{ + return systemColor(ChromeDisabledLow); +} + +QColor QQuickUniversalStyle::chromeHighColor() const +{ + return systemColor(ChromeHigh); +} + +QColor QQuickUniversalStyle::chromeLowColor() const +{ + return systemColor(ChromeLow); +} + +QColor QQuickUniversalStyle::chromeMediumColor() const +{ + return systemColor(ChromeMedium); +} + +QColor QQuickUniversalStyle::chromeMediumLowColor() const +{ + return systemColor(ChromeMediumLow); +} + +QColor QQuickUniversalStyle::chromeWhiteColor() const +{ + return systemColor(ChromeWhite); +} + +QColor QQuickUniversalStyle::listLowColor() const +{ + return systemColor(ListLow); +} + +QColor QQuickUniversalStyle::listMediumColor() const +{ + return systemColor(ListMedium); +} + +QColor QQuickUniversalStyle::systemColor(SystemColor role) const +{ + return QColor::fromRgba(m_theme == QQuickUniversalStyle::Dark ? qquickuniversal_dark_color(role) : qquickuniversal_light_color(role)); +} + +void QQuickUniversalStyle::attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent) +{ + Q_UNUSED(oldParent); + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(newParent); + if (universal) { + inheritTheme(universal->theme()); + inheritAccent(universal->m_accent); + inheritForeground(universal->m_foreground, universal->m_hasForeground); + inheritBackground(universal->m_background, universal->m_hasBackground); + } +} + +template <typename Enum> +static Enum toEnumValue(const QByteArray &value, bool *ok) +{ + QMetaEnum enumeration = QMetaEnum::fromType<Enum>(); + return static_cast<Enum>(enumeration.keyToValue(value, ok)); +} + +static QByteArray resolveSetting(const QByteArray &env, const QSharedPointer<QSettings> &settings, const QString &name) +{ + QByteArray value = qgetenv(env); +#if QT_CONFIG(settings) + if (value.isNull() && !settings.isNull()) + value = settings->value(name).toByteArray(); +#endif + return value; +} + +void QQuickUniversalStyle::initGlobals() +{ + QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(QStringLiteral("Universal")); + + bool ok = false; + QByteArray themeValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_THEME", settings, QStringLiteral("Theme")); + Theme themeEnum = toEnumValue<Theme>(themeValue, &ok); + if (ok) + GlobalTheme = qquickuniversal_effective_theme(themeEnum); + else if (!themeValue.isEmpty()) + qWarning().nospace().noquote() << "Universal: unknown theme value: " << themeValue; + + QByteArray accentValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_ACCENT", settings, QStringLiteral("Accent")); + Color accentEnum = toEnumValue<Color>(accentValue, &ok); + if (ok) { + GlobalAccent = qquickuniversal_accent_color(accentEnum); + } else if (!accentValue.isEmpty()) { + QColor color(accentValue.constData()); + if (color.isValid()) + GlobalAccent = color.rgba(); + else + qWarning().nospace().noquote() << "Universal: unknown accent value: " << accentValue; + } + + QByteArray foregroundValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_FOREGROUND", settings, QStringLiteral("Foreground")); + Color foregroundEnum = toEnumValue<Color>(foregroundValue, &ok); + if (ok) { + GlobalForeground = qquickuniversal_accent_color(foregroundEnum); + HasGlobalForeground = true; + } else if (!foregroundValue.isEmpty()) { + QColor color(foregroundValue.constData()); + if (color.isValid()) { + GlobalForeground = color.rgba(); + HasGlobalForeground = true; + } else { + qWarning().nospace().noquote() << "Universal: unknown foreground value: " << foregroundValue; + } + } + + QByteArray backgroundValue = resolveSetting("QT_QUICK_CONTROLS_UNIVERSAL_BACKGROUND", settings, QStringLiteral("Background")); + Color backgroundEnum = toEnumValue<Color>(backgroundValue, &ok); + if (ok) { + GlobalBackground = qquickuniversal_accent_color(backgroundEnum); + HasGlobalBackground = true; + } else if (!backgroundValue.isEmpty()) { + QColor color(backgroundValue.constData()); + if (color.isValid()) { + GlobalBackground = color.rgba(); + HasGlobalBackground = true; + } else { + qWarning().nospace().noquote() << "Universal: unknown background value: " << backgroundValue; + } + } +} + +bool QQuickUniversalStyle::variantToRgba(const QVariant &var, const char *name, QRgb *rgba) const +{ + if (var.metaType().id() == QMetaType::Int) { + int val = var.toInt(); + if (val < Lime || val > Taupe) { + qmlWarning(parent()) << "unknown Universal." << name << " value: " << val; + return false; + } + *rgba = qquickuniversal_accent_color(static_cast<Color>(val)); + } else { + int val = QMetaEnum::fromType<Color>().keyToValue(var.toByteArray()); + if (val != -1) { + *rgba = qquickuniversal_accent_color(static_cast<Color>(val)); + } else { + QColor color(var.toString()); + if (!color.isValid()) { + qmlWarning(parent()) << "unknown Universal." << name << " value: " << var.toString(); + return false; + } + *rgba = color.rgba(); + } + } + return true; +} + +QT_END_NAMESPACE + +#include "moc_qquickuniversalstyle_p.cpp" diff --git a/src/quickcontrols2/universal/qquickuniversalstyle_p.h b/src/quickcontrols2/universal/qquickuniversalstyle_p.h new file mode 100644 index 00000000000..50b07071fc5 --- /dev/null +++ b/src/quickcontrols2/universal/qquickuniversalstyle_p.h @@ -0,0 +1,246 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKUNIVERSALSTYLE_P_H +#define QQUICKUNIVERSALSTYLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qcolor.h> +#include <QtQuickControls2Impl/private/qquickattachedobject_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickUniversalStylePrivate; + +class QQuickUniversalStyle : public QQuickAttachedObject +{ + Q_OBJECT + Q_PROPERTY(Theme theme READ theme WRITE setTheme RESET resetTheme NOTIFY themeChanged FINAL) + Q_PROPERTY(QVariant accent READ accent WRITE setAccent RESET resetAccent NOTIFY accentChanged FINAL) + Q_PROPERTY(QVariant foreground READ foreground WRITE setForeground RESET resetForeground NOTIFY foregroundChanged FINAL) + Q_PROPERTY(QVariant background READ background WRITE setBackground RESET resetBackground NOTIFY backgroundChanged FINAL) + + Q_PROPERTY(QColor altHighColor READ altHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor altLowColor READ altLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor altMediumColor READ altMediumColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor altMediumHighColor READ altMediumHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor altMediumLowColor READ altMediumLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor baseHighColor READ baseHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor baseLowColor READ baseLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor baseMediumColor READ baseMediumColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor baseMediumHighColor READ baseMediumHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor baseMediumLowColor READ baseMediumLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeAltLowColor READ chromeAltLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeBlackHighColor READ chromeBlackHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeBlackLowColor READ chromeBlackLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeBlackMediumLowColor READ chromeBlackMediumLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeBlackMediumColor READ chromeBlackMediumColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeDisabledHighColor READ chromeDisabledHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeDisabledLowColor READ chromeDisabledLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeHighColor READ chromeHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeLowColor READ chromeLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeMediumColor READ chromeMediumColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeMediumLowColor READ chromeMediumLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeWhiteColor READ chromeWhiteColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor listLowColor READ listLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor listMediumColor READ listMediumColor NOTIFY paletteChanged FINAL) + + QML_NAMED_ELEMENT(Universal) + QML_ATTACHED(QQuickUniversalStyle) + QML_UNCREATABLE("") + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickUniversalStyle(QObject *parent = nullptr); + + static QQuickUniversalStyle *qmlAttachedProperties(QObject *object); + + enum Theme { Light, Dark, System }; + Q_ENUM(Theme) + + Theme theme() const; + void setTheme(Theme theme); + void inheritTheme(Theme theme); + void propagateTheme(); + void resetTheme(); + + enum Color { + Lime, + Green, + Emerald, + Teal, + Cyan, + Cobalt, + Indigo, + Violet, + Pink, + Magenta, + Crimson, + Red, + Orange, + Amber, + Yellow, + Brown, + Olive, + Steel, + Mauve, + Taupe + }; + Q_ENUM(Color) + + QVariant accent() const; + void setAccent(const QVariant &accent); + void inheritAccent(QRgb accent); + void propagateAccent(); + void resetAccent(); + + QVariant foreground() const; + void setForeground(const QVariant &foreground); + void inheritForeground(QRgb foreground, bool has); + void propagateForeground(); + void resetForeground(); + + QVariant background() const; + void setBackground(const QVariant &background); + void inheritBackground(QRgb background, bool has); + void propagateBackground(); + void resetBackground(); + + Q_INVOKABLE QColor color(Color color) const; + + QColor altHighColor() const; + QColor altLowColor() const; + QColor altMediumColor() const; + QColor altMediumHighColor() const; + QColor altMediumLowColor() const; + QColor baseHighColor() const; + QColor baseLowColor() const; + QColor baseMediumColor() const; + QColor baseMediumHighColor() const; + QColor baseMediumLowColor() const; + QColor chromeAltLowColor() const; + QColor chromeBlackHighColor() const; + QColor chromeBlackLowColor() const; + QColor chromeBlackMediumLowColor() const; + QColor chromeBlackMediumColor() const; + QColor chromeDisabledHighColor() const; + QColor chromeDisabledLowColor() const; + QColor chromeHighColor() const; + QColor chromeLowColor() const; + QColor chromeMediumColor() const; + QColor chromeMediumLowColor() const; + QColor chromeWhiteColor() const; + QColor listLowColor() const; + QColor listMediumColor() const; + + enum SystemColor { + AltHigh, + AltLow, + AltMedium, + AltMediumHigh, + AltMediumLow, + BaseHigh, + BaseLow, + BaseMedium, + BaseMediumHigh, + BaseMediumLow, + ChromeAltLow, + ChromeBlackHigh, + ChromeBlackLow, + ChromeBlackMediumLow, + ChromeBlackMedium, + ChromeDisabledHigh, + ChromeDisabledLow, + ChromeHigh, + ChromeLow, + ChromeMedium, + ChromeMediumLow, + ChromeWhite, + ListLow, + ListMedium + }; + + QColor systemColor(SystemColor role) const; + + static void initGlobals(); + +Q_SIGNALS: + void themeChanged(); + void accentChanged(); + void foregroundChanged(); + void backgroundChanged(); + void paletteChanged(); + +protected: + void attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent) override; + +private: + bool variantToRgba(const QVariant &var, const char *name, QRgb *rgba) const; + + // These reflect whether a color value was explicitly set on the specific + // item that this attached style object represents. + bool m_explicitTheme = false; + bool m_explicitAccent = false; + bool m_explicitForeground = false; + bool m_explicitBackground = false; + // These will be true when this item has an explicit or inherited foreground/background + // color, or these colors were declared globally via settings (e.g. conf or env vars). + // Some color properties of the style will return different values depending on whether + // or not these are set. + bool m_hasForeground = false; + bool m_hasBackground = false; + // The actual values for this item, whether explicit, inherited or globally set. + Theme m_theme = Light; + QRgb m_accent = Qt::blue; + QRgb m_foreground = Qt::black; + QRgb m_background = Qt::white; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPEINFO(QQuickUniversalStyle, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKUNIVERSALSTYLE_P_H diff --git a/src/quickcontrols2/universal/qquickuniversaltheme.cpp b/src/quickcontrols2/universal/qquickuniversaltheme.cpp new file mode 100644 index 00000000000..46f7c52e0a6 --- /dev/null +++ b/src/quickcontrols2/universal/qquickuniversaltheme.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickuniversaltheme_p.h" + +#include <QtGui/qfontinfo.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +QT_BEGIN_NAMESPACE + +void QQuickUniversalTheme::initialize(QQuickTheme *theme) +{ + QFont systemFont; + QFont groupBoxTitleFont; + QFont tabButtonFont; + + const QFont font(QLatin1String("Segoe UI")); + if (QFontInfo(font).family() == QLatin1String("Segoe UI")) { + const QStringList families{font.family()}; + systemFont.setFamilies(families); + groupBoxTitleFont.setFamilies(families); + tabButtonFont.setFamilies(families); + } + + systemFont.setPixelSize(15); + theme->setFont(QQuickTheme::System, systemFont); + + groupBoxTitleFont.setPixelSize(15); + groupBoxTitleFont.setWeight(QFont::DemiBold); + theme->setFont(QQuickTheme::GroupBox, groupBoxTitleFont); + + tabButtonFont.setPixelSize(24); + tabButtonFont.setWeight(QFont::Light); + theme->setFont(QQuickTheme::TabBar, tabButtonFont); +} + +QT_END_NAMESPACE diff --git a/src/quickcontrols2/universal/qquickuniversaltheme_p.h b/src/quickcontrols2/universal/qquickuniversaltheme_p.h new file mode 100644 index 00000000000..f762d0e3399 --- /dev/null +++ b/src/quickcontrols2/universal/qquickuniversaltheme_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKUNIVERSALTHEME_P_H +#define QQUICKUNIVERSALTHEME_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +class QQuickTheme; + +class QQuickUniversalTheme +{ +public: + static void initialize(QQuickTheme *theme); +}; + +QT_END_NAMESPACE + +#endif // QQUICKUNIVERSALTHEME_P_H diff --git a/src/quickcontrols2/universal/qtquickcontrols2universalstyleplugin.cpp b/src/quickcontrols2/universal/qtquickcontrols2universalstyleplugin.cpp new file mode 100644 index 00000000000..46e36bea3e2 --- /dev/null +++ b/src/quickcontrols2/universal/qtquickcontrols2universalstyleplugin.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickuniversalstyle_p.h" +#include "qquickuniversaltheme_p.h" + +#include <QtQuickControls2/private/qquickstyleplugin_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +extern void qml_register_types_QtQuick_Controls_Universal(); +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Controls_Universal); + +QT_BEGIN_NAMESPACE + +class QtQuickControls2UniversalStylePlugin : public QQuickStylePlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtQuickControls2UniversalStylePlugin(QObject *parent = nullptr); + + QString name() const override; + void initializeTheme(QQuickTheme *theme) override; + + QQuickUniversalTheme theme; +}; + +QtQuickControls2UniversalStylePlugin::QtQuickControls2UniversalStylePlugin(QObject *parent) : QQuickStylePlugin(parent) +{ + volatile auto registration = &qml_register_types_QtQuick_Controls_Universal; + Q_UNUSED(registration); +} + +QString QtQuickControls2UniversalStylePlugin::name() const +{ + return QStringLiteral("Universal"); +} + +void QtQuickControls2UniversalStylePlugin::initializeTheme(QQuickTheme *theme) +{ + QQuickUniversalStyle::initGlobals(); + this->theme.initialize(theme); +} + +QT_END_NAMESPACE + +#include "qtquickcontrols2universalstyleplugin.moc" diff --git a/src/quickcontrols2/universal/qtquickcontrols2universalstyleplugin.qrc b/src/quickcontrols2/universal/qtquickcontrols2universalstyleplugin.qrc new file mode 100644 index 00000000000..bfcb0974ce4 --- /dev/null +++ b/src/quickcontrols2/universal/qtquickcontrols2universalstyleplugin.qrc @@ -0,0 +1,20 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="qt-project.org/imports/QtQuick/Controls/Universal"> + <file>images/checkmark.png</file> + <file>images/checkmark@2x.png</file> + <file>images/checkmark@3x.png</file> + <file>images/checkmark@4x.png</file> + <file>images/downarrow.png</file> + <file>images/downarrow@2x.png</file> + <file>images/downarrow@3x.png</file> + <file>images/downarrow@4x.png</file> + <file>images/leftarrow.png</file> + <file>images/leftarrow@2x.png</file> + <file>images/leftarrow@3x.png</file> + <file>images/leftarrow@4x.png</file> + <file>images/rightarrow.png</file> + <file>images/rightarrow@2x.png</file> + <file>images/rightarrow@3x.png</file> + <file>images/rightarrow@4x.png</file> +</qresource> +</RCC> diff --git a/src/quickcontrols2/universal/universal.pri b/src/quickcontrols2/universal/universal.pri new file mode 100644 index 00000000000..44fb584af97 --- /dev/null +++ b/src/quickcontrols2/universal/universal.pri @@ -0,0 +1,60 @@ +HEADERS += \ + $$PWD/qquickuniversalstyle_p.h \ + $$PWD/qquickuniversaltheme_p.h + +SOURCES += \ + $$PWD/qquickuniversalstyle.cpp \ + $$PWD/qquickuniversaltheme.cpp + +QML_FILES += \ + $$PWD/ApplicationWindow.qml \ + $$PWD/BusyIndicator.qml \ + $$PWD/Button.qml \ + $$PWD/CheckBox.qml \ + $$PWD/CheckDelegate.qml \ + $$PWD/ComboBox.qml \ + $$PWD/DelayButton.qml \ + $$PWD/Dial.qml \ + $$PWD/Dialog.qml \ + $$PWD/DialogButtonBox.qml \ + $$PWD/Drawer.qml \ + $$PWD/Frame.qml \ + $$PWD/GroupBox.qml \ + $$PWD/HorizontalHeaderView.qml \ + $$PWD/ItemDelegate.qml \ + $$PWD/Label.qml \ + $$PWD/Menu.qml \ + $$PWD/MenuBar.qml \ + $$PWD/MenuBarItem.qml \ + $$PWD/MenuItem.qml \ + $$PWD/MenuSeparator.qml \ + $$PWD/Page.qml \ + $$PWD/PageIndicator.qml \ + $$PWD/Pane.qml \ + $$PWD/Popup.qml \ + $$PWD/ProgressBar.qml \ + $$PWD/RadioButton.qml \ + $$PWD/RadioDelegate.qml \ + $$PWD/RangeSlider.qml \ + $$PWD/RoundButton.qml \ + $$PWD/ScrollView.qml \ + $$PWD/ScrollBar.qml \ + $$PWD/ScrollIndicator.qml \ + $$PWD/SelectionRectangle.qml \ + $$PWD/Slider.qml \ + $$PWD/SpinBox.qml \ + $$PWD/SplitView.qml \ + $$PWD/StackView.qml \ + $$PWD/SwipeDelegate.qml \ + $$PWD/SwitchDelegate.qml \ + $$PWD/Switch.qml \ + $$PWD/TabBar.qml \ + $$PWD/TabButton.qml \ + $$PWD/TextArea.qml \ + $$PWD/TextField.qml \ + $$PWD/ToolBar.qml \ + $$PWD/ToolButton.qml \ + $$PWD/ToolSeparator.qml \ + $$PWD/ToolTip.qml \ + $$PWD/Tumbler.qml \ + $$PWD/VerticalHeaderView.qml diff --git a/src/quickcontrols2/windows/Button.qml b/src/quickcontrols2/windows/Button.qml new file mode 100644 index 00000000000..6b28f8e7c53 --- /dev/null +++ b/src/quickcontrols2/windows/Button.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultButton { + id: control + + background: NativeStyle.Button { + control: control + contentWidth: contentItem.implicitWidth + contentHeight: contentItem.implicitHeight + useNinePatchImage: false + overrideState: NativeStyle.StyleItem.NeverHovered + } + + NativeStyle.Button { + id: hoverButton + control: control + x: background.x + y: background.y + width: background.width + height: background.height + useNinePatchImage: false + overrideState: NativeStyle.StyleItem.AlwaysHovered + opacity: control.hovered ? 1 : 0 + visible: opacity !== 0 + Behavior on opacity { NumberAnimation { duration: hoverButton.transitionDuration } } + } + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.flat && !control.down ? (control.visualFocus ? control.palette.highlight : control.palette.windowText) : control.palette.buttonText + } +} diff --git a/src/quickcontrols2/windows/CMakeLists.txt b/src/quickcontrols2/windows/CMakeLists.txt new file mode 100644 index 00000000000..3ac58054a23 --- /dev/null +++ b/src/quickcontrols2/windows/CMakeLists.txt @@ -0,0 +1,53 @@ +##################################################################### +## qtquickcontrols2windowsstyleplugin Plugin: +##################################################################### + +set(qml_files + "Button.qml" + "CheckBox.qml" + "ComboBox.qml" + "Frame.qml" + "GroupBox.qml" + "ProgressBar.qml" + "RadioButton.qml" + "SelectionRectangle.qml" + "Slider.qml" + "SpinBox.qml" + "TextArea.qml" + "TextField.qml" + "ScrollBar.qml" + "ScrollView.qml" +) + +qt_internal_add_qml_module(qtquickcontrols2windowsstyleplugin + URI "QtQuick.Controls.Windows" + VERSION "${PROJECT_VERSION}" + CLASS_NAME QtQuickControls2WindowsStylePlugin + IMPORTS + QtQuick.Controls.Fusion/auto + PAST_MAJOR_VERSIONS 2 + PLUGIN_TARGET qtquickcontrols2windowsstyleplugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + SOURCES + qtquickcontrols2windowsstyleplugin.cpp + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2Private + Qt::QuickPrivate + Qt::QuickTemplates2Private +) + +# Native style is a dependency of the Windows style. +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2windowsstyleplugin + qtquickcontrols2nativestyleplugin) +# Fusion style is the required fallback style. +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2windowsstyleplugin + qtquickcontrols2fusionstyleplugin) diff --git a/src/quickcontrols2/windows/CheckBox.qml b/src/quickcontrols2/windows/CheckBox.qml new file mode 100644 index 00000000000..eaf70a3f35e --- /dev/null +++ b/src/quickcontrols2/windows/CheckBox.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.NativeStyle as NativeStyle + +T.CheckBox { + id: control + + readonly property bool nativeIndicator: indicator instanceof NativeStyle.StyleItem + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: nativeIndicator ? 0 : 6 + padding: nativeIndicator ? 0 : 6 + + indicator: NativeStyle.CheckBox { + control: control + y: control.topPadding + (control.availableHeight - height) >> 1 + contentWidth: contentItem.implicitWidth + contentHeight: contentItem.implicitHeight + useNinePatchImage: false + overrideState: NativeStyle.StyleItem.NeverHovered + } + + NativeStyle.CheckBox { + id: hoverCheckBox + control: control + x: indicator.x + y: indicator.y + z: 99 // Needs to be above the "unhovered" indicator + width: indicator.width + height: indicator.height + useNinePatchImage: false + overrideState: NativeStyle.StyleItem.AlwaysHovered + opacity: control.hovered ? 1 : 0 + visible: opacity !== 0 + Behavior on opacity { NumberAnimation { duration: hoverCheckBox.transitionDuration } } + } + + contentItem: CheckLabel { + text: control.text + font: control.font + color: control.palette.windowText + + // For some reason, the other styles set padding here (in the delegate), instead of in + // the control above. And they also adjust the indicator position by setting x and y + // explicitly (instead of using insets). So we follow the same pattern to ensure that + // setting a custom contentItem delegate from the app will end up looking the same for + // all styles. But this should probably be fixed for all styles (to make them work the + // same way as e.g Buttons). + leftPadding: { + if (nativeIndicator) + indicator.contentPadding.left + else + indicator && !mirrored ? indicator.width + spacing : 0 + } + + topPadding: nativeIndicator ? indicator.contentPadding.top : 0 + rightPadding: { + if (nativeIndicator) + indicator.contentPadding.right + else + indicator && mirrored ? indicator.width + spacing : 0 + } + } +} diff --git a/src/quickcontrols2/windows/ComboBox.qml b/src/quickcontrols2/windows/ComboBox.qml new file mode 100644 index 00000000000..13fa844daed --- /dev/null +++ b/src/quickcontrols2/windows/ComboBox.qml @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.ComboBox { + id: control + + readonly property bool __nativeBackground: background instanceof NativeStyle.StyleItem + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding, + 90 /* minimum */ ) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + leftPadding: __nativeBackground ? background.contentPadding.left : 5 + rightPadding: __nativeBackground ? background.contentPadding.right : 5 + topPadding: __nativeBackground ? background.contentPadding.top : 5 + bottomPadding: __nativeBackground ? background.contentPadding.bottom : 5 + + contentItem: T.TextField { + implicitWidth: contentWidth + implicitHeight: contentHeight + text: control.editable ? control.editText : control.displayText + + enabled: control.editable + autoScroll: control.editable + readOnly: control.down + inputMethodHints: control.inputMethodHints + validator: control.validator + selectByMouse: control.selectTextByMouse + + font: control.font + color: control.editable ? control.palette.text : control.palette.buttonText + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + verticalAlignment: Text.AlignVCenter + } + + background: NativeStyle.ComboBox { + control: control + contentWidth: contentItem.implicitWidth + contentHeight: contentItem.implicitHeight + useNinePatchImage: false + } + + delegate: ItemDelegate { + width: ListView.view.width + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData + palette.text: control.palette.text + palette.highlightedText: control.palette.highlightedText + font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal + highlighted: control.highlightedIndex === index + hoverEnabled: control.hoverEnabled + } + + popup: T.Popup { + readonly property var layoutMargins: control.__nativeBackground ? control.background.layoutMargins : null + x: layoutMargins ? layoutMargins.left : 0 + y: control.height - (layoutMargins ? layoutMargins.bottom : 0) + width: control.width - (layoutMargins ? layoutMargins.left + layoutMargins.right : 0) + height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin) + topMargin: 6 + bottomMargin: 6 + + contentItem: ListView { + clip: true + implicitHeight: contentHeight + model: control.delegateModel + currentIndex: control.highlightedIndex + highlightMoveDuration: 0 + + Rectangle { + z: 10 + width: parent.width + height: parent.height + color: "transparent" + border.color: control.palette.mid + } + + T.ScrollIndicator.vertical: ScrollIndicator { } + } + + background: Rectangle { + color: control.palette.window + } + } +} diff --git a/src/quickcontrols2/windows/Frame.qml b/src/quickcontrols2/windows/Frame.qml new file mode 100644 index 00000000000..f16a0835171 --- /dev/null +++ b/src/quickcontrols2/windows/Frame.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultFrame { +} diff --git a/src/quickcontrols2/windows/GroupBox.qml b/src/quickcontrols2/windows/GroupBox.qml new file mode 100644 index 00000000000..4ffbaae6d30 --- /dev/null +++ b/src/quickcontrols2/windows/GroupBox.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultGroupBox { +} diff --git a/src/quickcontrols2/windows/ProgressBar.qml b/src/quickcontrols2/windows/ProgressBar.qml new file mode 100644 index 00000000000..59a1689dba9 --- /dev/null +++ b/src/quickcontrols2/windows/ProgressBar.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultProgressBar { +} diff --git a/src/quickcontrols2/windows/RadioButton.qml b/src/quickcontrols2/windows/RadioButton.qml new file mode 100644 index 00000000000..82b85698d29 --- /dev/null +++ b/src/quickcontrols2/windows/RadioButton.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultRadioButton { +} diff --git a/src/quickcontrols2/windows/ScrollBar.qml b/src/quickcontrols2/windows/ScrollBar.qml new file mode 100644 index 00000000000..8972cfc53c8 --- /dev/null +++ b/src/quickcontrols2/windows/ScrollBar.qml @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultScrollBar { + id: controlRoot + + topPadding: orientation === Qt.Vertical ? controlRoot.__decreaseVisual.indicator.height : 0 + bottomPadding: orientation === Qt.Vertical ? controlRoot.__increaseVisual.indicator.height : 0 + leftPadding: orientation === Qt.Horizontal ? controlRoot.__decreaseVisual.indicator.width : 0 + rightPadding: orientation === Qt.Horizontal ? controlRoot.__increaseVisual.indicator.width : 0 + + contentItem: NativeStyle.ScrollBar { + control: controlRoot + subControl: NativeStyle.ScrollBar.Handle + } + + NativeStyle.ScrollBar { + // Fade a hovered-looking version of the handle + // on top of the default handle when hovering it + x: contentItem.x + y: contentItem.y + z: 1 + width: contentItem.width + height: contentItem.height + control: controlRoot + subControl: NativeStyle.ScrollBar.Handle + overrideState: NativeStyle.StyleItem.AlwaysHovered + opacity: controlRoot.hovered || control.pressed ? 1 : 0 + visible: contentItem instanceof NativeStyle.StyleItem + Behavior on opacity { NumberAnimation { duration: contentItem.transitionDuration } } + } + + // The groove background should have window color + Rectangle { + x: background.x + y: background.y + z: -1 + width: background.width + height: background.height + color: controlRoot.palette.window + } + + background: NativeStyle.ScrollBar { + control: controlRoot + subControl: NativeStyle.ScrollBar.Groove + overrideState: NativeStyle.ScrollBar.NeverHovered + } + + __decreaseVisual.indicator: NativeStyle.ScrollBar { + control: controlRoot + subControl: NativeStyle.ScrollBar.SubLine + overrideState: NativeStyle.ScrollBar.AlwaysHovered + opacity: controlRoot.__decreaseVisual.hovered ? 1 : 0 + visible: contentItem instanceof NativeStyle.StyleItem + Behavior on opacity { NumberAnimation { duration: contentItem.transitionDuration } } + useNinePatchImage: false + } + + NativeStyle.ScrollBar { + control: controlRoot + subControl: NativeStyle.ScrollBar.SubLine + overrideState: NativeStyle.ScrollBar.AlwaysSunken + opacity: controlRoot.__decreaseVisual.pressed ? 1 : 0 + visible: contentItem instanceof NativeStyle.StyleItem + useNinePatchImage: false + z: 1 + } + + __increaseVisual.indicator: NativeStyle.ScrollBar { + control: controlRoot + subControl: NativeStyle.ScrollBar.AddLine + x: orientation === Qt.Horizontal ? controlRoot.width - width : 0 + y: orientation === Qt.Vertical ? controlRoot.height - height : 0 + overrideState: NativeStyle.ScrollBar.AlwaysHovered + opacity: controlRoot.__increaseVisual.hovered ? 1 : 0 + visible: contentItem instanceof NativeStyle.StyleItem + Behavior on opacity { NumberAnimation { duration: contentItem.transitionDuration } } + useNinePatchImage: false + } + + NativeStyle.ScrollBar { + control: controlRoot + subControl: NativeStyle.ScrollBar.AddLine + x: __increaseVisual.indicator.x + y: __increaseVisual.indicator.y + z: 1 + overrideState: NativeStyle.ScrollBar.AlwaysSunken + opacity: controlRoot.__increaseVisual.pressed ? 1 : 0 + visible: contentItem instanceof NativeStyle.StyleItem + useNinePatchImage: false + } +} diff --git a/src/quickcontrols2/windows/ScrollView.qml b/src/quickcontrols2/windows/ScrollView.qml new file mode 100644 index 00000000000..0e5ffff4b68 --- /dev/null +++ b/src/quickcontrols2/windows/ScrollView.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Templates as T + +T.ScrollView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + rightPadding: ScrollBar.vertical.visible ? ScrollBar.vertical.width : 0 + bottomPadding: ScrollBar.horizontal.visible ? ScrollBar.horizontal.height : 0 + + ScrollBar.vertical: ScrollBar { + parent: control + x: control.mirrored ? 0 : control.width - width + y: 0 + height: control.height - (control.ScrollBar.horizontal.visible ? control.ScrollBar.horizontal.height : 0) + active: control.ScrollBar.horizontal.active + } + + ScrollBar.horizontal: ScrollBar { + parent: control + x: 0 + y: control.height - height + width: control.width - (control.ScrollBar.vertical.visible ? control.ScrollBar.vertical.width : 0) + active: control.ScrollBar.vertical.active + } +} diff --git a/src/quickcontrols2/windows/SelectionRectangle.qml b/src/quickcontrols2/windows/SelectionRectangle.qml new file mode 100644 index 00000000000..d54b6e9b429 --- /dev/null +++ b/src/quickcontrols2/windows/SelectionRectangle.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Shapes + +T.SelectionRectangle { + id: control + + topLeftHandle: Item { + width: 20 + height: 20 + visible: SelectionRectangle.control.active + // This item is deliberately empty. Selection handles don't feel at home + // for this style. But we provide an invisible handle that the user can + // drag on. + } + + bottomRightHandle: Item { + width: 20 + height: 20 + visible: SelectionRectangle.control.active + // This item is deliberately empty. Selection handles don't feel at home + // for this style. But we provide an invisible handle that the user can + // drag on. + } + +} diff --git a/src/quickcontrols2/windows/Slider.qml b/src/quickcontrols2/windows/Slider.qml new file mode 100644 index 00000000000..ab72fcaabdb --- /dev/null +++ b/src/quickcontrols2/windows/Slider.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultSlider { +} diff --git a/src/quickcontrols2/windows/SpinBox.qml b/src/quickcontrols2/windows/SpinBox.qml new file mode 100644 index 00000000000..2f50f0d5e50 --- /dev/null +++ b/src/quickcontrols2/windows/SpinBox.qml @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.SpinBox { + id: control + + property bool nativeIndicators: up.indicator.hasOwnProperty("_qt_default") + && down.indicator.hasOwnProperty("_qt_default") + + implicitWidth: Math.max(contentItem.implicitWidth + leftInset + rightInset, + 90 /* minimum */ ) + implicitHeight: Math.max(contentItem.implicitHeight, up.implicitIndicatorHeight + down.implicitIndicatorHeight) + + topInset + bottomInset + + spacing: 2 + + leftPadding: 0 + topPadding: 0 + rightPadding: rightInset + bottomPadding: 0 + + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + + contentItem: TextField { + text: control.displayText + font: control.font + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + horizontalAlignment: Qt.AlignLeft + verticalAlignment: Qt.AlignVCenter + + topPadding: 0 + bottomPadding: 0 + leftPadding: 10 + rightPadding: 10 + + readOnly: !control.editable + validator: control.validator + inputMethodHints: control.inputMethodHints + + // Since the indicators are embedded inside the TextField we need to avoid that + // the TextField consumes mouse events for that area. + // We achieve that by setting a containmentMask + containmentMask: Item { height: contentItem.height; width: contentItem.width - upAndDown.width } + } + + NativeStyle.SpinBox { + id: upAndDown + control: control + subControl: NativeStyle.SpinBox.Up + visible: nativeIndicators + x: up.indicator.x + y: up.indicator.y + //implicitHeight: contentItem.implicitHeight-2 + height: parent.height-2 + useNinePatchImage: false + z:99 + } + + up.indicator: Item { + x: parent.width - width - 2 + y: 1 + height: upAndDown.height >> 1 + implicitWidth: upAndDown.implicitWidth + implicitHeight: (upAndDown.implicitHeight >> 1) + property bool _qt_default + } + + down.indicator: Item { + x: parent.width - width - 2 + y: up.indicator.y + (upAndDown.height >> 1) + height: upAndDown.height - up.indicator.height + implicitWidth: upAndDown.implicitWidth + implicitHeight: upAndDown.implicitHeight >> 1 + property bool _qt_default + } + + background: Item {} // No background, the TextField will cover the whole control +} diff --git a/src/quickcontrols2/windows/TextArea.qml b/src/quickcontrols2/windows/TextArea.qml new file mode 100644 index 00000000000..f6b883038b2 --- /dev/null +++ b/src/quickcontrols2/windows/TextArea.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultTextArea { +} diff --git a/src/quickcontrols2/windows/TextField.qml b/src/quickcontrols2/windows/TextField.qml new file mode 100644 index 00000000000..bc0e2cb77ac --- /dev/null +++ b/src/quickcontrols2/windows/TextField.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.NativeStyle as NativeStyle + +NativeStyle.DefaultTextField { +} diff --git a/src/quickcontrols2/windows/qtquickcontrols2windowsstyleplugin.cpp b/src/quickcontrols2/windows/qtquickcontrols2windowsstyleplugin.cpp new file mode 100644 index 00000000000..90ff1fe4175 --- /dev/null +++ b/src/quickcontrols2/windows/qtquickcontrols2windowsstyleplugin.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQml/qqml.h> +#include <QtQuickControls2/private/qquickstyleplugin_p.h> +#include <QtQuickControls2/qquickstyle.h> + +extern void qml_register_types_QtQuick_Controls_Windows(); +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Controls_Windows); + +QT_BEGIN_NAMESPACE + +class QtQuickControls2WindowsStylePlugin : public QQuickStylePlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtQuickControls2WindowsStylePlugin(QObject *parent = nullptr); + QString name() const override; + void initializeTheme(QQuickTheme *theme) override; +}; + +QtQuickControls2WindowsStylePlugin::QtQuickControls2WindowsStylePlugin(QObject *parent): + QQuickStylePlugin(parent) +{ + volatile auto registration = &qml_register_types_QtQuick_Controls_Windows; + Q_UNUSED(registration); +} + +QString QtQuickControls2WindowsStylePlugin::name() const +{ + return QStringLiteral("Windows"); +} + +void QtQuickControls2WindowsStylePlugin::initializeTheme(QQuickTheme * /*theme*/) +{ +} + +QT_END_NAMESPACE + +#include "qtquickcontrols2windowsstyleplugin.moc" diff --git a/src/quickcontrols2/windows/windows.pri b/src/quickcontrols2/windows/windows.pri new file mode 100644 index 00000000000..155730e0489 --- /dev/null +++ b/src/quickcontrols2/windows/windows.pri @@ -0,0 +1,15 @@ +QML_FILES += \ + $$PWD/Button.qml \ + $$PWD/CheckBox.qml \ + $$PWD/ComboBox.qml \ + $$PWD/Frame.qml \ + $$PWD/GroupBox.qml \ + $$PWD/ProgressBar.qml \ + $$PWD/RadioButton.qml \ + $$PWD/SelectionRectangle.qml \ + $$PWD/Slider.qml \ + $$PWD/SpinBox.qml \ + $$PWD/TextArea.qml \ + $$PWD/TextField.qml \ + $$PWD/ScrollBar.qml \ + $$PWD/ScrollView.qml \ diff --git a/src/quickcontrols2impl/CMakeLists.txt b/src/quickcontrols2impl/CMakeLists.txt new file mode 100644 index 00000000000..048938a8ced --- /dev/null +++ b/src/quickcontrols2impl/CMakeLists.txt @@ -0,0 +1,47 @@ +##################################################################### +## QuickControls2Impl Module: +##################################################################### + +qt_internal_add_qml_module(QuickControls2Impl + URI "QtQuick.Controls.impl" + VERSION "${PROJECT_VERSION}" + CLASS_NAME QtQuickControls2ImplPlugin + DEPENDENCIES + QtQuick/auto + PLUGIN_TARGET qtquickcontrols2implplugin + SOURCES + qquickanimatednode.cpp qquickanimatednode_p.h + qquickattachedobject.cpp qquickattachedobject_p.h + qquickchecklabel.cpp qquickchecklabel_p.h + qquickclippedtext.cpp qquickclippedtext_p.h + qquickcolor.cpp qquickcolor_p.h + qquickcolorimage.cpp qquickcolorimage_p.h + qquickiconimage.cpp qquickiconimage_p.h + qquickiconimage_p_p.h + qquickiconlabel.cpp qquickiconlabel_p.h + qquickiconlabel_p_p.h + qquickitemgroup.cpp qquickitemgroup_p.h + qquickmnemoniclabel.cpp qquickmnemoniclabel_p.h + qquickpaddedrectangle.cpp qquickpaddedrectangle_p.h + qquickplaceholdertext.cpp qquickplaceholdertext_p.h + qtquickcontrols2foreign_p.h + qtquickcontrols2implglobal_p.h + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + PUBLIC_LIBRARIES + Qt::Core + Qt::Gui + Qt::Quick +) + +qt_internal_extend_target(QuickControls2Impl CONDITION QT_FEATURE_quick_listview AND QT_FEATURE_quick_pathview + SOURCES + qquicktumblerview.cpp qquicktumblerview_p.h +) diff --git a/src/quickcontrols2impl/qquickanimatednode.cpp b/src/quickcontrols2impl/qquickanimatednode.cpp new file mode 100644 index 00000000000..510f643cb26 --- /dev/null +++ b/src/quickcontrols2impl/qquickanimatednode.cpp @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickanimatednode_p.h" + +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickwindow.h> + +// based on qtdeclarative/examples/quick/scenegraph/threadedanimation + +QT_BEGIN_NAMESPACE + +QQuickAnimatedNode::QQuickAnimatedNode(QQuickItem *target) + : m_window(target->window()) +{ +} + +bool QQuickAnimatedNode::isRunning() const +{ + return m_running; +} + +int QQuickAnimatedNode::currentTime() const +{ + int time = m_currentTime; + if (m_running) + time += m_timer.elapsed(); + return time; +} + +void QQuickAnimatedNode::setCurrentTime(int time) +{ + m_currentTime = time; + m_timer.restart(); +} + +int QQuickAnimatedNode::duration() const +{ + return m_duration; +} + +void QQuickAnimatedNode::setDuration(int duration) +{ + m_duration = duration; +} + +int QQuickAnimatedNode::loopCount() const +{ + return m_loopCount; +} + +void QQuickAnimatedNode::setLoopCount(int count) +{ + m_loopCount = count; +} + +void QQuickAnimatedNode::sync(QQuickItem *target) +{ + Q_UNUSED(target); +} + +QQuickWindow *QQuickAnimatedNode::window() const +{ + return m_window; +} + +void QQuickAnimatedNode::start(int duration) +{ + if (m_running) + return; + + m_running = true; + m_currentLoop = 0; + m_timer.restart(); + if (duration > 0) + m_duration = duration; + + connect(m_window, &QQuickWindow::beforeRendering, this, &QQuickAnimatedNode::advance, Qt::DirectConnection); + connect(m_window, &QQuickWindow::frameSwapped, this, &QQuickAnimatedNode::update, Qt::DirectConnection); + + // If we're inside a QQuickWidget, this call is necessary to ensure the widget + // gets updated for the first time. + m_window->update(); + + emit started(); +} + +void QQuickAnimatedNode::restart() +{ + stop(); + start(); +} + +void QQuickAnimatedNode::stop() +{ + if (!m_running) + return; + + m_running = false; + disconnect(m_window, &QQuickWindow::beforeRendering, this, &QQuickAnimatedNode::advance); + disconnect(m_window, &QQuickWindow::frameSwapped, this, &QQuickAnimatedNode::update); + emit stopped(); +} + +void QQuickAnimatedNode::updateCurrentTime(int time) +{ + Q_UNUSED(time); +} + +void QQuickAnimatedNode::advance() +{ + int time = currentTime(); + if (time > m_duration) { + time = 0; + setCurrentTime(0); + + if (m_loopCount > 0 && ++m_currentLoop >= m_loopCount) { + time = m_duration; // complete + stop(); + } + } + updateCurrentTime(time); + + // If we're inside a QQuickWidget, this call is necessary to ensure the widget gets updated. + m_window->update(); +} + +void QQuickAnimatedNode::update() +{ + if (m_running) + m_window->update(); +} + +QT_END_NAMESPACE + +#include "moc_qquickanimatednode_p.cpp" diff --git a/src/quickcontrols2impl/qquickanimatednode_p.h b/src/quickcontrols2impl/qquickanimatednode_p.h new file mode 100644 index 00000000000..e403f0bf475 --- /dev/null +++ b/src/quickcontrols2impl/qquickanimatednode_p.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKANIMATEDNODE_P_H +#define QQUICKANIMATEDNODE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qsgnode.h> +#include <QtCore/qelapsedtimer.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickItem; +class QQuickWindow; + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickAnimatedNode : public QObject, public QSGTransformNode +{ + Q_OBJECT + +public: + explicit QQuickAnimatedNode(QQuickItem *target); + + bool isRunning() const; + + int currentTime() const; + void setCurrentTime(int time); + + int duration() const; + void setDuration(int duration); + + enum LoopCount { Infinite = -1 }; + + int loopCount() const; + void setLoopCount(int count); + + virtual void sync(QQuickItem *target); + + QQuickWindow *window() const; + + // must be called from sync() or updatePaintNode() + void start(int duration = 0); + void restart(); + void stop(); + +Q_SIGNALS: + void started(); + void stopped(); + +protected: + virtual void updateCurrentTime(int time); + +private Q_SLOTS: + void advance(); + void update(); + +private: + bool m_running = false; + int m_duration = 0; + int m_loopCount = 1; + int m_currentTime = 0; + int m_currentLoop = 0; + QElapsedTimer m_timer; + QQuickWindow *m_window = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKANIMATEDNODE_P_H diff --git a/src/quickcontrols2impl/qquickattachedobject.cpp b/src/quickcontrols2impl/qquickattachedobject.cpp new file mode 100644 index 00000000000..244ff3125a8 --- /dev/null +++ b/src/quickcontrols2impl/qquickattachedobject.cpp @@ -0,0 +1,276 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickattachedobject_p.h" + +#include <QtCore/qpointer.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p.h> + +QT_BEGIN_NAMESPACE + +static QQuickAttachedObject *attachedObject(const QMetaObject *type, QObject *object, bool create = false) +{ + if (!object) + return nullptr; + auto func = qmlAttachedPropertiesFunction(object, type); + return qobject_cast<QQuickAttachedObject *>(qmlAttachedPropertiesObject(object, func, create)); +} + +static QQuickAttachedObject *findAttachedParent(const QMetaObject *type, QObject *object) +{ + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (item) { + // lookup parent items and popups + QQuickItem *parent = item->parentItem(); + while (parent) { + QQuickAttachedObject *attached = attachedObject(type, parent); + if (attached) + return attached; + + QQuickPopup *popup = qobject_cast<QQuickPopup *>(parent->parent()); + if (popup) + return attachedObject(type, popup); + + parent = parent->parentItem(); + } + + // fallback to item's window + QQuickAttachedObject *attached = attachedObject(type, item->window()); + if (attached) + return attached; + } else { + // lookup popup's window + QQuickPopup *popup = qobject_cast<QQuickPopup *>(object); + if (popup) + return attachedObject(type, popup->popupItem()->window()); + } + + // lookup parent window + QQuickWindow *window = qobject_cast<QQuickWindow *>(object); + if (window) { + QQuickWindow *parentWindow = qobject_cast<QQuickWindow *>(window->parent()); + if (parentWindow) { + QQuickAttachedObject *attached = attachedObject(type, window); + if (attached) + return attached; + } + } + + // fallback to engine (global) + if (object) { + QQmlEngine *engine = qmlEngine(object); + if (engine) { + QByteArray name = QByteArray("_q_") + type->className(); + QQuickAttachedObject *attached = engine->property(name).value<QQuickAttachedObject *>(); + if (!attached) { + attached = attachedObject(type, engine, true); + engine->setProperty(name, QVariant::fromValue(attached)); + } + return attached; + } + } + + return nullptr; +} + +static QList<QQuickAttachedObject *> findAttachedChildren(const QMetaObject *type, QObject *object) +{ + QList<QQuickAttachedObject *> children; + + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (!item) { + QQuickWindow *window = qobject_cast<QQuickWindow *>(object); + if (window) { + item = window->contentItem(); + + const auto &windowChildren = window->children(); + for (QObject *child : windowChildren) { + QQuickWindow *childWindow = qobject_cast<QQuickWindow *>(child); + if (childWindow) { + QQuickAttachedObject *attached = attachedObject(type, childWindow); + if (attached) + children += attached; + } + } + } + } + + if (item) { + const auto childItems = item->childItems(); + for (QQuickItem *child : childItems) { + QQuickAttachedObject *attached = attachedObject(type, child); + if (attached) + children += attached; + else + children += findAttachedChildren(type, child); + } + } + + return children; +} + +static QQuickItem *findAttachedItem(QObject *parent) +{ + QQuickItem *item = qobject_cast<QQuickItem *>(parent); + if (!item) { + QQuickPopup *popup = qobject_cast<QQuickPopup *>(parent); + if (popup) + item = popup->popupItem(); + } + return item; +} + +class QQuickAttachedObjectPrivate : public QObjectPrivate, public QQuickItemChangeListener +{ + Q_DECLARE_PUBLIC(QQuickAttachedObject) + +public: + static QQuickAttachedObjectPrivate *get(QQuickAttachedObject *attachedObject) + { + return attachedObject->d_func(); + } + + void attachTo(QObject *object); + void detachFrom(QObject *object); + + void itemWindowChanged(QQuickWindow *window); + void itemParentChanged(QQuickItem *item, QQuickItem *parent) override; + + QList<QQuickAttachedObject *> attachedChildren; + QPointer<QQuickAttachedObject> attachedParent; +}; + +void QQuickAttachedObjectPrivate::attachTo(QObject *object) +{ + QQuickItem *item = findAttachedItem(object); + if (item) { + connect(item, &QQuickItem::windowChanged, this, &QQuickAttachedObjectPrivate::itemWindowChanged); + QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Parent); + } +} + +void QQuickAttachedObjectPrivate::detachFrom(QObject *object) +{ + QQuickItem *item = findAttachedItem(object); + if (item) { + disconnect(item, &QQuickItem::windowChanged, this, &QQuickAttachedObjectPrivate::itemWindowChanged); + QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Parent); + } +} + +void QQuickAttachedObjectPrivate::itemWindowChanged(QQuickWindow *window) +{ + Q_Q(QQuickAttachedObject); + QQuickAttachedObject *attachedParent = nullptr; + QQuickItem *item = qobject_cast<QQuickItem *>(q->sender()); + if (item) + attachedParent = findAttachedParent(q->metaObject(), item); + if (!attachedParent) + attachedParent = attachedObject(q->metaObject(), window); + q->setAttachedParent(attachedParent); +} + +void QQuickAttachedObjectPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent) +{ + Q_Q(QQuickAttachedObject); + Q_UNUSED(parent); + q->setAttachedParent(findAttachedParent(q->metaObject(), item)); +} + +QQuickAttachedObject::QQuickAttachedObject(QObject *parent) + : QObject(*(new QQuickAttachedObjectPrivate), parent) +{ + Q_D(QQuickAttachedObject); + d->attachTo(parent); +} + +QQuickAttachedObject::~QQuickAttachedObject() +{ + Q_D(QQuickAttachedObject); + d->detachFrom(parent()); + setAttachedParent(nullptr); +} + +QList<QQuickAttachedObject *> QQuickAttachedObject::attachedChildren() const +{ + Q_D(const QQuickAttachedObject); + return d->attachedChildren; +} + +QQuickAttachedObject *QQuickAttachedObject::attachedParent() const +{ + Q_D(const QQuickAttachedObject); + return d->attachedParent; +} + +void QQuickAttachedObject::setAttachedParent(QQuickAttachedObject *parent) +{ + Q_D(QQuickAttachedObject); + if (d->attachedParent == parent) + return; + + QQuickAttachedObject *oldParent = d->attachedParent; + if (d->attachedParent) + QQuickAttachedObjectPrivate::get(d->attachedParent)->attachedChildren.removeOne(this); + d->attachedParent = parent; + if (parent) + QQuickAttachedObjectPrivate::get(parent)->attachedChildren.append(this); + attachedParentChange(parent, oldParent); +} + +void QQuickAttachedObject::init() +{ + QQuickAttachedObject *attachedParent = findAttachedParent(metaObject(), parent()); + if (attachedParent) + setAttachedParent(attachedParent); + + const QList<QQuickAttachedObject *> attachedChildren = findAttachedChildren(metaObject(), parent()); + for (QQuickAttachedObject *child : attachedChildren) + child->setAttachedParent(this); +} + +void QQuickAttachedObject::attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent) +{ + Q_UNUSED(newParent); + Q_UNUSED(oldParent); +} + +QT_END_NAMESPACE + +#include "moc_qquickattachedobject_p.cpp" diff --git a/src/quickcontrols2impl/qquickattachedobject_p.h b/src/quickcontrols2impl/qquickattachedobject_p.h new file mode 100644 index 00000000000..cd2404c2e8b --- /dev/null +++ b/src/quickcontrols2impl/qquickattachedobject_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKATTACHEDOBJECT_P_H +#define QQUICKATTACHEDOBJECT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/qqml.h> +#include <QtCore/qobject.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickAttachedObjectPrivate; + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickAttachedObject : public QObject +{ + Q_OBJECT + +public: + explicit QQuickAttachedObject(QObject *parent = nullptr); + ~QQuickAttachedObject(); + + QList<QQuickAttachedObject *> attachedChildren() const; + + QQuickAttachedObject *attachedParent() const; + void setAttachedParent(QQuickAttachedObject *parent); + +protected: + void init(); + + virtual void attachedParentChange(QQuickAttachedObject *newParent, QQuickAttachedObject *oldParent); + +private: + Q_DISABLE_COPY(QQuickAttachedObject) + Q_DECLARE_PRIVATE(QQuickAttachedObject) +}; + +QT_END_NAMESPACE + +#endif // QQUICKATTACHEDOBJECT_P_H diff --git a/src/quickcontrols2impl/qquickchecklabel.cpp b/src/quickcontrols2impl/qquickchecklabel.cpp new file mode 100644 index 00000000000..5f8075823bf --- /dev/null +++ b/src/quickcontrols2impl/qquickchecklabel.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickchecklabel_p.h" + +QT_BEGIN_NAMESPACE + +QQuickCheckLabel::QQuickCheckLabel(QQuickItem *parent) : + QQuickText(parent) +{ + setHAlign(AlignLeft); + setVAlign(AlignVCenter); + setElideMode(ElideRight); +} + +QT_END_NAMESPACE + +#include "moc_qquickchecklabel_p.cpp" diff --git a/src/quickcontrols2impl/qquickchecklabel_p.h b/src/quickcontrols2impl/qquickchecklabel_p.h new file mode 100644 index 00000000000..823ce9df497 --- /dev/null +++ b/src/quickcontrols2impl/qquickchecklabel_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCHECKLABEL_P_H +#define QQUICKCHECKLABEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquicktext_p.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickCheckLabel : public QQuickText +{ + Q_OBJECT + QML_NAMED_ELEMENT(CheckLabel) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickCheckLabel(QQuickItem *parent = nullptr); +}; + +struct QQuickTextForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickText) + QML_ADDED_IN_VERSION(2, 3) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickCheckLabel) + +#endif // QQUICKCHECKLABEL_P_H diff --git a/src/quickcontrols2impl/qquickclippedtext.cpp b/src/quickcontrols2impl/qquickclippedtext.cpp new file mode 100644 index 00000000000..b7fb34102a7 --- /dev/null +++ b/src/quickcontrols2impl/qquickclippedtext.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickclippedtext_p.h" + +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +QQuickClippedText::QQuickClippedText(QQuickItem *parent) + : QQuickText(parent) +{ +} + +qreal QQuickClippedText::clipX() const +{ + return m_clipX; +} + +void QQuickClippedText::setClipX(qreal x) +{ + if (qFuzzyCompare(x, m_clipX)) + return; + + m_clipX = x; + markClipDirty(); +} + +qreal QQuickClippedText::clipY() const +{ + return m_clipY; +} + +void QQuickClippedText::setClipY(qreal y) +{ + if (qFuzzyCompare(y, m_clipY)) + return; + + m_clipY = y; + markClipDirty(); +} + +qreal QQuickClippedText::clipWidth() const +{ + return m_clipWidth ? m_clipWidth : width(); +} + +void QQuickClippedText::setClipWidth(qreal width) +{ + m_hasClipWidth = true; + if (qFuzzyCompare(width, m_clipWidth)) + return; + + m_clipWidth = width; + markClipDirty(); +} + +qreal QQuickClippedText::clipHeight() const +{ + return m_clipHeight ? m_clipHeight : height(); +} + +void QQuickClippedText::setClipHeight(qreal height) +{ + m_hasClipHeight = true; + if (qFuzzyCompare(height, m_clipHeight)) + return; + + m_clipHeight = height; + markClipDirty(); +} + +QRectF QQuickClippedText::clipRect() const +{ + return QRectF(clipX(), clipY(), clipWidth(), clipHeight()); +} + +void QQuickClippedText::markClipDirty() +{ + QQuickItemPrivate::get(this)->dirty(QQuickItemPrivate::Size); +} + +QT_END_NAMESPACE + +#include "moc_qquickclippedtext_p.cpp" diff --git a/src/quickcontrols2impl/qquickclippedtext_p.h b/src/quickcontrols2impl/qquickclippedtext_p.h new file mode 100644 index 00000000000..f3b011fd9d8 --- /dev/null +++ b/src/quickcontrols2impl/qquickclippedtext_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCLIPPEDTEXT_P_H +#define QQUICKCLIPPEDTEXT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquicktext_p.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickClippedText : public QQuickText +{ + Q_OBJECT + Q_PROPERTY(qreal clipX READ clipX WRITE setClipX FINAL) + Q_PROPERTY(qreal clipY READ clipY WRITE setClipY FINAL) + Q_PROPERTY(qreal clipWidth READ clipWidth WRITE setClipWidth FINAL) + Q_PROPERTY(qreal clipHeight READ clipHeight WRITE setClipHeight FINAL) + QML_NAMED_ELEMENT(ClippedText) + QML_ADDED_IN_VERSION(2, 2) + +public: + explicit QQuickClippedText(QQuickItem *parent = nullptr); + + qreal clipX() const; + void setClipX(qreal x); + + qreal clipY() const; + void setClipY(qreal y); + + qreal clipWidth() const; + void setClipWidth(qreal width); + + qreal clipHeight() const; + void setClipHeight(qreal height); + + QRectF clipRect() const override; + +private: + void markClipDirty(); + + bool m_hasClipWidth = false; + bool m_hasClipHeight = false; + qreal m_clipX = 0; + qreal m_clipY = 0; + qreal m_clipWidth = 0; + qreal m_clipHeight = 0; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickClippedText) + +#endif // QQUICKCLIPPEDTEXT_P_H diff --git a/src/quickcontrols2impl/qquickcolor.cpp b/src/quickcontrols2impl/qquickcolor.cpp new file mode 100644 index 00000000000..cbd4233ccc4 --- /dev/null +++ b/src/quickcontrols2impl/qquickcolor.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcolor_p.h" + +QT_BEGIN_NAMESPACE + +QQuickColor::QQuickColor(QObject *parent) : + QObject(parent) +{ +} + +QColor QQuickColor::transparent(const QColor &color, qreal opacity) const +{ + return QColor(color.red(), color.green(), color.blue(), + int(qreal(255) * qBound(qreal(0), opacity, qreal(1)))); +} + +QColor QQuickColor::blend(const QColor &a, const QColor &b, qreal factor) const +{ + if (factor <= 0.0) + return a; + if (factor >= 1.0) + return b; + + QColor color; + color.setRedF(a.redF() * (1.0 - factor) + b.redF() * factor); + color.setGreenF(a.greenF() * (1.0 - factor) + b.greenF() * factor); + color.setBlueF(a.blueF() * (1.0 - factor) + b.blueF() * factor); + return color; +} + +QT_END_NAMESPACE + +#include "moc_qquickcolor_p.cpp" diff --git a/src/quickcontrols2impl/qquickcolor_p.h b/src/quickcontrols2impl/qquickcolor_p.h new file mode 100644 index 00000000000..cd69d0d8e74 --- /dev/null +++ b/src/quickcontrols2impl/qquickcolor_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCOLOR_P_H +#define QQUICKCOLOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtGui/qcolor.h> +#include <QtQml/qqml.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickColor : public QObject +{ + Q_OBJECT + QML_NAMED_ELEMENT(Color) + QML_SINGLETON + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickColor(QObject *parent = nullptr); + + Q_INVOKABLE QColor transparent(const QColor &color, qreal opacity) const; + Q_INVOKABLE QColor blend(const QColor &a, const QColor &b, qreal factor) const; +}; + +QT_END_NAMESPACE + +#endif // QQUICKCOLOR_P_H diff --git a/src/quickcontrols2impl/qquickcolorimage.cpp b/src/quickcontrols2impl/qquickcolorimage.cpp new file mode 100644 index 00000000000..8b9ad0e04fe --- /dev/null +++ b/src/quickcontrols2impl/qquickcolorimage.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcolorimage_p.h" + +#include <QtQuick/private/qquickimagebase_p_p.h> + +QT_BEGIN_NAMESPACE + +QQuickColorImage::QQuickColorImage(QQuickItem *parent) + : QQuickImage(parent) +{ +} + +QColor QQuickColorImage::color() const +{ + return m_color; +} + +void QQuickColorImage::setColor(const QColor &color) +{ + if (m_color == color) + return; + + m_color = color; + if (isComponentComplete()) + load(); + emit colorChanged(); +} + +void QQuickColorImage::resetColor() +{ + setColor(Qt::transparent); +} + +QColor QQuickColorImage::defaultColor() const +{ + return m_defaultColor; +} + +void QQuickColorImage::setDefaultColor(const QColor &color) +{ + if (m_defaultColor == color) + return; + + m_defaultColor = color; + emit defaultColorChanged(); +} + +void QQuickColorImage::resetDefaultColor() +{ + setDefaultColor(Qt::transparent); +} + +void QQuickColorImage::pixmapChange() +{ + QQuickImage::pixmapChange(); + if (m_color.alpha() > 0 && m_color != m_defaultColor) { + QQuickImageBasePrivate *d = static_cast<QQuickImageBasePrivate *>(QQuickItemPrivate::get(this)); + QImage image = d->pix.image(); + if (!image.isNull()) { + QPainter painter(&image); + painter.setCompositionMode(QPainter::CompositionMode_SourceIn); + painter.fillRect(image.rect(), m_color); + d->pix.setImage(image); + } + } +} + +QT_END_NAMESPACE + +#include "moc_qquickcolorimage_p.cpp" diff --git a/src/quickcontrols2impl/qquickcolorimage_p.h b/src/quickcontrols2impl/qquickcolorimage_p.h new file mode 100644 index 00000000000..faa2e42ccfb --- /dev/null +++ b/src/quickcontrols2impl/qquickcolorimage_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCOLORIMAGE_P_H +#define QQUICKCOLORIMAGE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qcolor.h> +#include <QtQuick/private/qquickimage_p.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickColorImage : public QQuickImage +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor RESET resetColor NOTIFY colorChanged FINAL) + Q_PROPERTY(QColor defaultColor READ defaultColor WRITE setDefaultColor RESET resetDefaultColor NOTIFY defaultColorChanged FINAL) + QML_NAMED_ELEMENT(ColorImage) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickColorImage(QQuickItem *parent = nullptr); + + QColor color() const; + void setColor(const QColor &color); + void resetColor(); + + QColor defaultColor() const; + void setDefaultColor(const QColor &color); + void resetDefaultColor(); + +Q_SIGNALS: + void colorChanged(); + void defaultColorChanged(); + +protected: + void pixmapChange() override; + +private: + QColor m_color = Qt::transparent; + QColor m_defaultColor = Qt::transparent; +}; + +QT_END_NAMESPACE + +#endif // QQUICKCOLORIMAGE_P_H diff --git a/src/quickcontrols2impl/qquickiconimage.cpp b/src/quickcontrols2impl/qquickiconimage.cpp new file mode 100644 index 00000000000..c7c7fa628e4 --- /dev/null +++ b/src/quickcontrols2impl/qquickiconimage.cpp @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickiconimage_p.h" +#include "qquickiconimage_p_p.h" + +#include <QtCore/qmath.h> +#include <QtQuick/private/qquickimagebase_p_p.h> + +QT_BEGIN_NAMESPACE + +QQuickIconImagePrivate::~QQuickIconImagePrivate() +{ + qDeleteAll(icon.entries); + icon.entries.clear(); +} + +bool QQuickIconImagePrivate::updateDevicePixelRatio(qreal targetDevicePixelRatio) +{ + if (isThemeIcon) { + devicePixelRatio = calculateDevicePixelRatio(); + return true; + } + + return QQuickImagePrivate::updateDevicePixelRatio(targetDevicePixelRatio); +} + +void QQuickIconImagePrivate::updateIcon() +{ + Q_Q(QQuickIconImage); + // Both geometryChange() and QQuickImageBase::sourceSizeChanged() + // (which we connect to updateIcon() in the constructor) can be called as a result + // of updateIcon() changing the various sizes, so we must check that we're not recursing. + if (updatingIcon) + return; + + updatingIcon = true; + + QSize size = sourcesize; + // If no size is specified for theme icons, it will use the smallest available size. + if (size.width() <= 0) + size.setWidth(q->width()); + if (size.height() <= 0) + size.setHeight(q->height()); + + const qreal dpr = calculateDevicePixelRatio(); + const QIconLoaderEngineEntry *entry = QIconLoaderEngine::entryForSize(icon, size * dpr, qCeil(dpr)); + + if (entry) { + QQmlContext *context = qmlContext(q); + const QUrl entryUrl = QUrl::fromLocalFile(entry->filename); + url = context ? context->resolvedUrl(entryUrl) : entryUrl; + isThemeIcon = true; + } else { + url = source; + isThemeIcon = false; + } + q->load(); + + updatingIcon = false; +} + +void QQuickIconImagePrivate::updateFillMode() +{ + Q_Q(QQuickIconImage); + // If we start with a sourceSize of 28x28 and then set sourceSize.width to 24, the fillMode + // will change to PreserveAspectFit (because pixmapSize.width() > width()), which causes the + // pixmap to be reloaded at its original size of 28x28, which causes the fillMode to change + // to Pad (because pixmapSize.width() <= width()), and so on. + if (updatingFillMode) + return; + + updatingFillMode = true; + + const QSize pixmapSize = QSize(pix.width(), pix.height()) / calculateDevicePixelRatio(); + if (pixmapSize.width() > q->width() || pixmapSize.height() > q->height()) + q->setFillMode(QQuickImage::PreserveAspectFit); + else + q->setFillMode(QQuickImage::Pad); + + updatingFillMode = false; +} + +qreal QQuickIconImagePrivate::calculateDevicePixelRatio() const +{ + Q_Q(const QQuickIconImage); + return q->window() ? q->window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio(); +} + +QQuickIconImage::QQuickIconImage(QQuickItem *parent) + : QQuickImage(*(new QQuickIconImagePrivate), parent) +{ + setFillMode(Pad); +} + +QString QQuickIconImage::name() const +{ + Q_D(const QQuickIconImage); + return d->icon.iconName; +} + +void QQuickIconImage::setName(const QString &name) +{ + Q_D(QQuickIconImage); + if (d->icon.iconName == name) + return; + + qDeleteAll(d->icon.entries); + d->icon = QIconLoader::instance()->loadIcon(name); + if (isComponentComplete()) + d->updateIcon(); + emit nameChanged(); +} + +QColor QQuickIconImage::color() const +{ + Q_D(const QQuickIconImage); + return d->color; +} + +void QQuickIconImage::setColor(const QColor &color) +{ + Q_D(QQuickIconImage); + if (d->color == color) + return; + + d->color = color; + if (isComponentComplete()) + d->updateIcon(); + emit colorChanged(); +} + +void QQuickIconImage::setSource(const QUrl &source) +{ + Q_D(QQuickIconImage); + if (d->source == source) + return; + + d->source = source; + if (isComponentComplete()) + d->updateIcon(); + emit sourceChanged(source); +} + +void QQuickIconImage::componentComplete() +{ + Q_D(QQuickIconImage); + QQuickImage::componentComplete(); + d->updateIcon(); + QObjectPrivate::connect(this, &QQuickImageBase::sourceSizeChanged, d, &QQuickIconImagePrivate::updateIcon); +} + +void QQuickIconImage::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickIconImage); + QQuickImage::geometryChange(newGeometry, oldGeometry); + if (isComponentComplete() && newGeometry.size() != oldGeometry.size()) + d->updateIcon(); +} + +void QQuickIconImage::itemChange(ItemChange change, const ItemChangeData &value) +{ + Q_D(QQuickIconImage); + if (change == ItemDevicePixelRatioHasChanged) + d->updateIcon(); + QQuickImage::itemChange(change, value); +} + +void QQuickIconImage::pixmapChange() +{ + Q_D(QQuickIconImage); + QQuickImage::pixmapChange(); + d->updateFillMode(); + + // Don't apply the color if we're recursing (updateFillMode() can cause us to recurse). + if (!d->updatingFillMode && d->color.alpha() > 0) { + QImage image = d->pix.image(); + if (!image.isNull()) { + QPainter painter(&image); + painter.setCompositionMode(QPainter::CompositionMode_SourceIn); + painter.fillRect(image.rect(), d->color); + d->pix.setImage(image); + } + } +} + +QT_END_NAMESPACE + +#include "moc_qquickiconimage_p.cpp" diff --git a/src/quickcontrols2impl/qquickiconimage_p.h b/src/quickcontrols2impl/qquickiconimage_p.h new file mode 100644 index 00000000000..37891476d5c --- /dev/null +++ b/src/quickcontrols2impl/qquickiconimage_p.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKICONIMAGE_P_H +#define QQUICKICONIMAGE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquickimage_p.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickIconImagePrivate; + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickIconImage : public QQuickImage +{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL) + QML_NAMED_ELEMENT(IconImage) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickIconImage(QQuickItem *parent = nullptr); + + QString name() const; + void setName(const QString &name); + + QColor color() const; + void setColor(const QColor &color); + + void setSource(const QUrl &url) override; + +Q_SIGNALS: + void nameChanged(); + void colorChanged(); + +protected: + void componentComplete() override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + void itemChange(ItemChange change, const ItemChangeData &value) override; + void pixmapChange() override; + +private: + Q_DISABLE_COPY(QQuickIconImage) + Q_DECLARE_PRIVATE(QQuickIconImage) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickIconImage) + +#endif // QQUICKICONIMAGE_P_H diff --git a/src/quickcontrols2impl/qquickiconimage_p_p.h b/src/quickcontrols2impl/qquickiconimage_p_p.h new file mode 100644 index 00000000000..22c51c070f6 --- /dev/null +++ b/src/quickcontrols2impl/qquickiconimage_p_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKICONIMAGE_P_P_H +#define QQUICKICONIMAGE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquickimage_p_p.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> +#include <QtGui/private/qiconloader_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickIconImagePrivate : public QQuickImagePrivate +{ + Q_DECLARE_PUBLIC(QQuickIconImage) + +public: + ~QQuickIconImagePrivate() override; + void updateIcon(); + void updateFillMode(); + qreal calculateDevicePixelRatio() const; + bool updateDevicePixelRatio(qreal targetDevicePixelRatio) override; + + QUrl source; + QColor color = Qt::transparent; + QThemeIconInfo icon; + bool updatingIcon = false; + bool isThemeIcon = false; + bool updatingFillMode = false; +}; + +QT_END_NAMESPACE + +#endif // QQUICKICONIMAGE_P_P_H diff --git a/src/quickcontrols2impl/qquickiconlabel.cpp b/src/quickcontrols2impl/qquickiconlabel.cpp new file mode 100644 index 00000000000..7e57a4e68eb --- /dev/null +++ b/src/quickcontrols2impl/qquickiconlabel.cpp @@ -0,0 +1,645 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickiconlabel_p.h" +#include "qquickiconlabel_p_p.h" +#include "qquickiconimage_p.h" +#include "qquickmnemoniclabel_p.h" + +#include <QtGui/private/qguiapplication_p.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquicktext_p.h> + +QT_BEGIN_NAMESPACE + +static void beginClass(QQuickItem *item) +{ + if (QQmlParserStatus *parserStatus = qobject_cast<QQmlParserStatus *>(item)) + parserStatus->classBegin(); +} + +static void completeComponent(QQuickItem *item) +{ + if (QQmlParserStatus *parserStatus = qobject_cast<QQmlParserStatus *>(item)) + parserStatus->componentComplete(); +} + +bool QQuickIconLabelPrivate::hasIcon() const +{ + return display != QQuickIconLabel::TextOnly && !icon.isEmpty(); +} + +bool QQuickIconLabelPrivate::hasText() const +{ + return display != QQuickIconLabel::IconOnly && !text.isEmpty(); +} + +bool QQuickIconLabelPrivate::createImage() +{ + Q_Q(QQuickIconLabel); + if (image) + return false; + + image = new QQuickIconImage(q); + watchChanges(image); + beginClass(image); + image->setObjectName(QStringLiteral("image")); + image->setName(icon.name()); + image->setSource(icon.resolvedSource()); + image->setSourceSize(QSize(icon.width(), icon.height())); + image->setColor(icon.color()); + image->setCache(icon.cache()); + QQmlEngine::setContextForObject(image, qmlContext(q)); + if (componentComplete) + completeComponent(image); + return true; +} + +bool QQuickIconLabelPrivate::destroyImage() +{ + if (!image) + return false; + + unwatchChanges(image); + delete image; + image = nullptr; + return true; +} + +bool QQuickIconLabelPrivate::updateImage() +{ + if (!hasIcon()) + return destroyImage(); + return createImage(); +} + +void QQuickIconLabelPrivate::syncImage() +{ + if (!image || icon.isEmpty()) + return; + + image->setName(icon.name()); + image->setSource(icon.resolvedSource()); + image->setSourceSize(QSize(icon.width(), icon.height())); + image->setColor(icon.color()); + image->setCache(icon.cache()); + const int valign = alignment & Qt::AlignVertical_Mask; + image->setVerticalAlignment(static_cast<QQuickImage::VAlignment>(valign)); + const int halign = alignment & Qt::AlignHorizontal_Mask; + image->setHorizontalAlignment(static_cast<QQuickImage::HAlignment>(halign)); +} + +void QQuickIconLabelPrivate::updateOrSyncImage() +{ + if (updateImage()) { + if (componentComplete) { + updateImplicitSize(); + layout(); + } + } else { + syncImage(); + } +} + +bool QQuickIconLabelPrivate::createLabel() +{ + Q_Q(QQuickIconLabel); + if (label) + return false; + + label = new QQuickMnemonicLabel(q); + watchChanges(label); + beginClass(label); + label->setObjectName(QStringLiteral("label")); + label->setFont(font); + label->setColor(color); + label->setElideMode(QQuickText::ElideRight); + const int valign = alignment & Qt::AlignVertical_Mask; + label->setVAlign(static_cast<QQuickText::VAlignment>(valign)); + const int halign = alignment & Qt::AlignHorizontal_Mask; + label->setHAlign(static_cast<QQuickText::HAlignment>(halign)); + label->setText(text); + if (componentComplete) + completeComponent(label); + return true; +} + +bool QQuickIconLabelPrivate::destroyLabel() +{ + if (!label) + return false; + + unwatchChanges(label); + delete label; + label = nullptr; + return true; +} + +bool QQuickIconLabelPrivate::updateLabel() +{ + if (!hasText()) + return destroyLabel(); + return createLabel(); +} + +void QQuickIconLabelPrivate::syncLabel() +{ + if (!label) + return; + + label->setText(text); +} + +void QQuickIconLabelPrivate::updateOrSyncLabel() +{ + if (updateLabel()) { + if (componentComplete) { + updateImplicitSize(); + layout(); + } + } else { + syncLabel(); + } +} + +void QQuickIconLabelPrivate::updateImplicitSize() +{ + Q_Q(QQuickIconLabel); + const bool showIcon = image && hasIcon(); + const bool showText = label && hasText(); + const qreal horizontalPadding = leftPadding + rightPadding; + const qreal verticalPadding = topPadding + bottomPadding; + const qreal iconImplicitWidth = showIcon ? image->implicitWidth() : 0; + const qreal iconImplicitHeight = showIcon ? image->implicitHeight() : 0; + const qreal textImplicitWidth = showText ? label->implicitWidth() : 0; + const qreal textImplicitHeight = showText ? label->implicitHeight() : 0; + const qreal effectiveSpacing = showText && showIcon && image->implicitWidth() > 0 ? spacing : 0; + const qreal implicitWidth = display == QQuickIconLabel::TextBesideIcon ? iconImplicitWidth + textImplicitWidth + effectiveSpacing + : qMax(iconImplicitWidth, textImplicitWidth); + const qreal implicitHeight = display == QQuickIconLabel::TextUnderIcon ? iconImplicitHeight + textImplicitHeight + effectiveSpacing + : qMax(iconImplicitHeight, textImplicitHeight); + q->setImplicitSize(implicitWidth + horizontalPadding, implicitHeight + verticalPadding); +} + +// adapted from QStyle::alignedRect() +static QRectF alignedRect(bool mirrored, Qt::Alignment alignment, const QSizeF &size, const QRectF &rectangle) +{ + alignment = QGuiApplicationPrivate::visualAlignment(mirrored ? Qt::RightToLeft : Qt::LeftToRight, alignment); + qreal x = rectangle.x(); + qreal y = rectangle.y(); + const qreal w = size.width(); + const qreal h = size.height(); + if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter) + y += rectangle.height() / 2 - h / 2; + else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom) + y += rectangle.height() - h; + if ((alignment & Qt::AlignRight) == Qt::AlignRight) + x += rectangle.width() - w; + else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter) + x += rectangle.width() / 2 - w / 2; + return QRectF(x, y, w, h); +} + +void QQuickIconLabelPrivate::layout() +{ + Q_Q(QQuickIconLabel); + if (!componentComplete) + return; + + const qreal availableWidth = width - leftPadding - rightPadding; + const qreal availableHeight = height - topPadding - bottomPadding; + + switch (display) { + case QQuickIconLabel::IconOnly: + if (image) { + const QRectF iconRect = alignedRect(mirrored, alignment, + QSizeF(qMin(image->implicitWidth(), availableWidth), + qMin(image->implicitHeight(), availableHeight)), + QRectF(leftPadding, topPadding, availableWidth, availableHeight)); + image->setSize(iconRect.size()); + image->setPosition(iconRect.topLeft()); + } + break; + case QQuickIconLabel::TextOnly: + if (label) { + const QRectF textRect = alignedRect(mirrored, alignment, + QSizeF(qMin(label->implicitWidth(), availableWidth), + qMin(label->implicitHeight(), availableHeight)), + QRectF(leftPadding, topPadding, availableWidth, availableHeight)); + label->setSize(textRect.size()); + label->setPosition(textRect.topLeft()); + } + break; + + case QQuickIconLabel::TextUnderIcon: { + // Work out the sizes first, as the positions depend on them. + QSizeF iconSize; + QSizeF textSize; + if (image) { + iconSize.setWidth(qMin(image->implicitWidth(), availableWidth)); + iconSize.setHeight(qMin(image->implicitHeight(), availableHeight)); + } + qreal effectiveSpacing = 0; + if (label) { + if (!iconSize.isEmpty()) + effectiveSpacing = spacing; + textSize.setWidth(qMin(label->implicitWidth(), availableWidth)); + textSize.setHeight(qMin(label->implicitHeight(), availableHeight - iconSize.height() - effectiveSpacing)); + } + + QRectF combinedRect = alignedRect(mirrored, alignment, + QSizeF(qMax(iconSize.width(), textSize.width()), + iconSize.height() + effectiveSpacing + textSize.height()), + QRectF(leftPadding, topPadding, availableWidth, availableHeight)); + if (image) { + QRectF iconRect = alignedRect(mirrored, Qt::AlignHCenter | Qt::AlignTop, iconSize, combinedRect); + image->setSize(iconRect.size()); + image->setPosition(iconRect.topLeft()); + } + if (label) { + QRectF textRect = alignedRect(mirrored, Qt::AlignHCenter | Qt::AlignBottom, textSize, combinedRect); + label->setSize(textRect.size()); + label->setPosition(textRect.topLeft()); + } + break; + } + + case QQuickIconLabel::TextBesideIcon: + default: + // Work out the sizes first, as the positions depend on them. + QSizeF iconSize(0, 0); + QSizeF textSize(0, 0); + if (image) { + iconSize.setWidth(qMin(image->implicitWidth(), availableWidth)); + iconSize.setHeight(qMin(image->implicitHeight(), availableHeight)); + } + qreal effectiveSpacing = 0; + if (label) { + if (!iconSize.isEmpty()) + effectiveSpacing = spacing; + textSize.setWidth(qMin(label->implicitWidth(), availableWidth - iconSize.width() - effectiveSpacing)); + textSize.setHeight(qMin(label->implicitHeight(), availableHeight)); + } + + const QRectF combinedRect = alignedRect(mirrored, alignment, + QSizeF(iconSize.width() + effectiveSpacing + textSize.width(), + qMax(iconSize.height(), textSize.height())), + QRectF(leftPadding, topPadding, availableWidth, availableHeight)); + if (image) { + const QRectF iconRect = alignedRect(mirrored, Qt::AlignLeft | Qt::AlignVCenter, iconSize, combinedRect); + image->setSize(iconRect.size()); + image->setPosition(iconRect.topLeft()); + } + if (label) { + const QRectF textRect = alignedRect(mirrored, Qt::AlignRight | Qt::AlignVCenter, textSize, combinedRect); + label->setSize(textRect.size()); + label->setPosition(textRect.topLeft()); + } + break; + } + + q->setBaselineOffset(label ? label->y() + label->baselineOffset() : 0); +} + +static const QQuickItemPrivate::ChangeTypes itemChangeTypes = + QQuickItemPrivate::ImplicitWidth + | QQuickItemPrivate::ImplicitHeight + | QQuickItemPrivate::Destroyed; + +void QQuickIconLabelPrivate::watchChanges(QQuickItem *item) +{ + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + itemPrivate->addItemChangeListener(this, itemChangeTypes); +} + +void QQuickIconLabelPrivate::unwatchChanges(QQuickItem* item) +{ + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + itemPrivate->removeItemChangeListener(this, itemChangeTypes); +} + +void QQuickIconLabelPrivate::itemImplicitWidthChanged(QQuickItem *) +{ + updateImplicitSize(); + layout(); +} + +void QQuickIconLabelPrivate::itemImplicitHeightChanged(QQuickItem *) +{ + updateImplicitSize(); + layout(); +} + +void QQuickIconLabelPrivate::itemDestroyed(QQuickItem *item) +{ + unwatchChanges(item); + if (item == image) + image = nullptr; + else if (item == label) + label = nullptr; +} + +QQuickIconLabel::QQuickIconLabel(QQuickItem *parent) + : QQuickItem(*(new QQuickIconLabelPrivate), parent) +{ +} + +QQuickIconLabel::~QQuickIconLabel() +{ + Q_D(QQuickIconLabel); + if (d->image) + d->unwatchChanges(d->image); + if (d->label) + d->unwatchChanges(d->label); +} + +QQuickIcon QQuickIconLabel::icon() const +{ + Q_D(const QQuickIconLabel); + return d->icon; +} + +void QQuickIconLabel::setIcon(const QQuickIcon &icon) +{ + Q_D(QQuickIconLabel); + if (d->icon == icon) + return; + + d->icon = icon; + d->icon.ensureRelativeSourceResolved(this); + d->updateOrSyncImage(); +} + +QString QQuickIconLabel::text() const +{ + Q_D(const QQuickIconLabel); + return d->text; +} + +void QQuickIconLabel::setText(const QString &text) +{ + Q_D(QQuickIconLabel); + if (d->text == text) + return; + + d->text = text; + d->updateOrSyncLabel(); +} + +QFont QQuickIconLabel::font() const +{ + Q_D(const QQuickIconLabel); + return d->font; +} + +void QQuickIconLabel::setFont(const QFont &font) +{ + Q_D(QQuickIconLabel); + if (d->font == font) + return; + + d->font = font; + if (d->label) + d->label->setFont(font); +} + +QColor QQuickIconLabel::color() const +{ + Q_D(const QQuickIconLabel); + return d->color; +} + +void QQuickIconLabel::setColor(const QColor &color) +{ + Q_D(QQuickIconLabel); + if (d->color == color) + return; + + d->color = color; + if (d->label) + d->label->setColor(color); +} + +QQuickIconLabel::Display QQuickIconLabel::display() const +{ + Q_D(const QQuickIconLabel); + return d->display; +} + +void QQuickIconLabel::setDisplay(Display display) +{ + Q_D(QQuickIconLabel); + if (d->display == display) + return; + + d->display = display; + d->updateImage(); + d->updateLabel(); + d->updateImplicitSize(); + d->layout(); +} + +qreal QQuickIconLabel::spacing() const +{ + Q_D(const QQuickIconLabel); + return d->spacing; +} + +void QQuickIconLabel::setSpacing(qreal spacing) +{ + Q_D(QQuickIconLabel); + if (qFuzzyCompare(d->spacing, spacing)) + return; + + d->spacing = spacing; + if (d->image && d->label) { + d->updateImplicitSize(); + d->layout(); + } +} + +bool QQuickIconLabel::isMirrored() const +{ + Q_D(const QQuickIconLabel); + return d->mirrored; +} + +void QQuickIconLabel::setMirrored(bool mirrored) +{ + Q_D(QQuickIconLabel); + if (d->mirrored == mirrored) + return; + + d->mirrored = mirrored; + d->layout(); +} + +Qt::Alignment QQuickIconLabel::alignment() const +{ + Q_D(const QQuickIconLabel); + return d->alignment; +} + +void QQuickIconLabel::setAlignment(Qt::Alignment alignment) +{ + Q_D(QQuickIconLabel); + const int valign = alignment & Qt::AlignVertical_Mask; + const int halign = alignment & Qt::AlignHorizontal_Mask; + const uint align = (valign ? valign : Qt::AlignVCenter) | (halign ? halign : Qt::AlignHCenter); + if (d->alignment == align) + return; + + d->alignment = static_cast<Qt::Alignment>(align); + if (d->label) { + d->label->setVAlign(static_cast<QQuickText::VAlignment>(valign)); + d->label->setHAlign(static_cast<QQuickText::HAlignment>(halign)); + } + if (d->image) { + d->image->setVerticalAlignment(static_cast<QQuickImage::VAlignment>(valign)); + d->image->setHorizontalAlignment(static_cast<QQuickImage::HAlignment>(halign)); + } + d->layout(); +} + +qreal QQuickIconLabel::topPadding() const +{ + Q_D(const QQuickIconLabel); + return d->topPadding; +} + +void QQuickIconLabel::setTopPadding(qreal padding) +{ + Q_D(QQuickIconLabel); + if (qFuzzyCompare(d->topPadding, padding)) + return; + + d->topPadding = padding; + d->updateImplicitSize(); + d->layout(); +} + +void QQuickIconLabel::resetTopPadding() +{ + setTopPadding(0); +} + +qreal QQuickIconLabel::leftPadding() const +{ + Q_D(const QQuickIconLabel); + return d->leftPadding; +} + +void QQuickIconLabel::setLeftPadding(qreal padding) +{ + Q_D(QQuickIconLabel); + if (qFuzzyCompare(d->leftPadding, padding)) + return; + + d->leftPadding = padding; + d->updateImplicitSize(); + d->layout(); +} + +void QQuickIconLabel::resetLeftPadding() +{ + setLeftPadding(0); +} + +qreal QQuickIconLabel::rightPadding() const +{ + Q_D(const QQuickIconLabel); + return d->rightPadding; +} + +void QQuickIconLabel::setRightPadding(qreal padding) +{ + Q_D(QQuickIconLabel); + if (qFuzzyCompare(d->rightPadding, padding)) + return; + + d->rightPadding = padding; + d->updateImplicitSize(); + d->layout(); +} + +void QQuickIconLabel::resetRightPadding() +{ + setRightPadding(0); +} + +qreal QQuickIconLabel::bottomPadding() const +{ + Q_D(const QQuickIconLabel); + return d->bottomPadding; +} + +void QQuickIconLabel::setBottomPadding(qreal padding) +{ + Q_D(QQuickIconLabel); + if (qFuzzyCompare(d->bottomPadding, padding)) + return; + + d->bottomPadding = padding; + d->updateImplicitSize(); + d->layout(); +} + +void QQuickIconLabel::resetBottomPadding() +{ + setBottomPadding(0); +} + +void QQuickIconLabel::componentComplete() +{ + Q_D(QQuickIconLabel); + if (d->image) + completeComponent(d->image); + if (d->label) + completeComponent(d->label); + QQuickItem::componentComplete(); + d->layout(); +} + +void QQuickIconLabel::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickIconLabel); + QQuickItem::geometryChange(newGeometry, oldGeometry); + d->layout(); +} + +QT_END_NAMESPACE + +#include "moc_qquickiconlabel_p.cpp" diff --git a/src/quickcontrols2impl/qquickiconlabel_p.h b/src/quickcontrols2impl/qquickiconlabel_p.h new file mode 100644 index 00000000000..1ea0affb42e --- /dev/null +++ b/src/quickcontrols2impl/qquickiconlabel_p.h @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKICONLABEL_P_H +#define QQUICKICONLABEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> +#include <QtQuickTemplates2/private/qquickicon_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickIconLabelPrivate; + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickIconLabel : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QQuickIcon icon READ icon WRITE setIcon FINAL) + Q_PROPERTY(QString text READ text WRITE setText FINAL) + Q_PROPERTY(QFont font READ font WRITE setFont FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + Q_PROPERTY(Display display READ display WRITE setDisplay FINAL) + Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing FINAL) + Q_PROPERTY(bool mirrored READ isMirrored WRITE setMirrored FINAL) + Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment FINAL) + Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding FINAL) + Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding FINAL) + Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding FINAL) + Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding FINAL) + QML_NAMED_ELEMENT(IconLabel) + QML_ADDED_IN_VERSION(2, 3) + +public: + enum Display { + IconOnly, + TextOnly, + TextBesideIcon, + TextUnderIcon + }; + Q_ENUM(Display) + + explicit QQuickIconLabel(QQuickItem *parent = nullptr); + ~QQuickIconLabel(); + + QQuickIcon icon() const; + void setIcon(const QQuickIcon &icon); + + QString text() const; + void setText(const QString &text); + + QFont font() const; + void setFont(const QFont &font); + + QColor color() const; + void setColor(const QColor &color); + + Display display() const; + void setDisplay(Display display); + + qreal spacing() const; + void setSpacing(qreal spacing); + + bool isMirrored() const; + void setMirrored(bool mirrored); + + Qt::Alignment alignment() const; + void setAlignment(Qt::Alignment alignment); + + qreal topPadding() const; + void setTopPadding(qreal padding); + void resetTopPadding(); + + qreal leftPadding() const; + void setLeftPadding(qreal padding); + void resetLeftPadding(); + + qreal rightPadding() const; + void setRightPadding(qreal padding); + void resetRightPadding(); + + qreal bottomPadding() const; + void setBottomPadding(qreal padding); + void resetBottomPadding(); + +protected: + void componentComplete() override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + +private: + Q_DISABLE_COPY(QQuickIconLabel) + Q_DECLARE_PRIVATE(QQuickIconLabel) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickIconLabel) + +#endif // QQUICKICONLABEL_P_H diff --git a/src/quickcontrols2impl/qquickiconlabel_p_p.h b/src/quickcontrols2impl/qquickiconlabel_p_p.h new file mode 100644 index 00000000000..d57d49f177f --- /dev/null +++ b/src/quickcontrols2impl/qquickiconlabel_p_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKICONLABEL_P_P_H +#define QQUICKICONLABEL_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> +#include <QtQuickControls2Impl/private/qquickiconlabel_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickIconImage; +class QQuickMnemonicLabel; + +class Q_AUTOTEST_EXPORT QQuickIconLabelPrivate : public QQuickItemPrivate, public QQuickItemChangeListener +{ + Q_DECLARE_PUBLIC(QQuickIconLabel) + +public: + bool hasIcon() const; + bool hasText() const; + + bool createImage(); + bool destroyImage(); + bool updateImage(); + void syncImage(); + void updateOrSyncImage(); + + bool createLabel(); + bool destroyLabel(); + bool updateLabel(); + void syncLabel(); + void updateOrSyncLabel(); + + void updateImplicitSize(); + void layout(); + + void watchChanges(QQuickItem *item); + void unwatchChanges(QQuickItem *item); + void setPositioningDirty(); + + bool isLeftToRight() const; + + void itemImplicitWidthChanged(QQuickItem *) override; + void itemImplicitHeightChanged(QQuickItem *) override; + void itemDestroyed(QQuickItem *item) override; + + bool mirrored = false; + QQuickIconLabel::Display display = QQuickIconLabel::TextBesideIcon; + Qt::Alignment alignment = Qt::AlignCenter; + qreal spacing = 0; + qreal topPadding = 0; + qreal leftPadding = 0; + qreal rightPadding = 0; + qreal bottomPadding = 0; + QFont font; + QColor color; + QString text; + QQuickIcon icon; + QQuickIconImage *image = nullptr; + QQuickMnemonicLabel *label = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKICONLABEL_P_P_H diff --git a/src/quickcontrols2impl/qquickitemgroup.cpp b/src/quickcontrols2impl/qquickitemgroup.cpp new file mode 100644 index 00000000000..1f3be28c7d3 --- /dev/null +++ b/src/quickcontrols2impl/qquickitemgroup.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickitemgroup_p.h" + +#include <QtQuick/private/qquickimplicitsizeitem_p_p.h> + +QT_BEGIN_NAMESPACE + +QQuickItemGroup::QQuickItemGroup(QQuickItem *parent) + : QQuickImplicitSizeItem(*(new QQuickImplicitSizeItemPrivate), parent) +{ +} + +QQuickItemGroup::~QQuickItemGroup() +{ + const auto children = childItems(); + for (QQuickItem *child : children) + unwatch(child); +} + +void QQuickItemGroup::watch(QQuickItem *item) +{ + QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight); +} + +void QQuickItemGroup::unwatch(QQuickItem *item) +{ + QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight); +} + +QSizeF QQuickItemGroup::calculateImplicitSize() const +{ + qreal width = 0; + qreal height = 0; + const auto children = childItems(); + for (QQuickItem *child : children) { + width = qMax(width, child->implicitWidth()); + height = qMax(height, child->implicitHeight()); + } + return QSizeF(width, height); +} + +void QQuickItemGroup::updateImplicitSize() +{ + QSizeF size = calculateImplicitSize(); + setImplicitSize(size.width(), size.height()); +} + +void QQuickItemGroup::itemChange(ItemChange change, const ItemChangeData &data) +{ + QQuickImplicitSizeItem::itemChange(change, data); + switch (change) { + case ItemChildAddedChange: + watch(data.item); + data.item->setSize(QSizeF(width(), height())); + updateImplicitSize(); + break; + case ItemChildRemovedChange: + unwatch(data.item); + updateImplicitSize(); + break; + default: + break; + } +} + +void QQuickItemGroup::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + QQuickImplicitSizeItem::geometryChange(newGeometry, oldGeometry); + + if (newGeometry.size() != oldGeometry.size()) { + const auto children = childItems(); + for (QQuickItem *child : children) + child->setSize(newGeometry.size()); + } +} + +void QQuickItemGroup::itemImplicitWidthChanged(QQuickItem *) +{ + setImplicitWidth(calculateImplicitSize().width()); +} + +void QQuickItemGroup::itemImplicitHeightChanged(QQuickItem *) +{ + setImplicitHeight(calculateImplicitSize().height()); +} + +QT_END_NAMESPACE + +#include "moc_qquickitemgroup_p.cpp" diff --git a/src/quickcontrols2impl/qquickitemgroup_p.h b/src/quickcontrols2impl/qquickitemgroup_p.h new file mode 100644 index 00000000000..9c04a990747 --- /dev/null +++ b/src/quickcontrols2impl/qquickitemgroup_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKITEMGROUP_P_H +#define QQUICKITEMGROUP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquickimplicitsizeitem_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickItemGroup : public QQuickImplicitSizeItem, protected QQuickItemChangeListener +{ + Q_OBJECT + QML_NAMED_ELEMENT(ItemGroup) + QML_ADDED_IN_VERSION(2, 2) + +public: + explicit QQuickItemGroup(QQuickItem *parent = nullptr); + ~QQuickItemGroup(); + +protected: + void watch(QQuickItem *item); + void unwatch(QQuickItem *item); + + QSizeF calculateImplicitSize() const; + void updateImplicitSize(); + + void itemChange(ItemChange change, const ItemChangeData &data) override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickItemGroup) + +#endif // QQUICKITEMGROUP_P_H diff --git a/src/quickcontrols2impl/qquickmnemoniclabel.cpp b/src/quickcontrols2impl/qquickmnemoniclabel.cpp new file mode 100644 index 00000000000..798eeae2058 --- /dev/null +++ b/src/quickcontrols2impl/qquickmnemoniclabel.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmnemoniclabel_p.h" + +#include <QtQuick/private/qquicktext_p_p.h> + +QT_BEGIN_NAMESPACE + +QQuickMnemonicLabel::QQuickMnemonicLabel(QQuickItem *parent) + : QQuickText(parent) +{ +} + +QString QQuickMnemonicLabel::text() const +{ + return m_fullText; +} + +void QQuickMnemonicLabel::setText(const QString &text) +{ + if (m_fullText == text) + return; + + m_fullText = text; + updateMnemonic(); +} + +bool QQuickMnemonicLabel::isMnemonicVisible() const +{ + return m_mnemonicVisible; +} + +void QQuickMnemonicLabel::setMnemonicVisible(bool visible) +{ + if (m_mnemonicVisible == visible) + return; + + m_mnemonicVisible = visible; + updateMnemonic(); + + if (isComponentComplete()) + forceLayout(); +} + +static QTextLayout::FormatRange underlineRange(int start, int length = 1) +{ + QTextLayout::FormatRange range; + range.start = start; + range.length = length; + range.format.setFontUnderline(true); + return range; +} + +// based on QPlatformTheme::removeMnemonics() +void QQuickMnemonicLabel::updateMnemonic() +{ + QString text(m_fullText.size(), QChar::Null); + int idx = 0; + int pos = 0; + int len = m_fullText.length(); + QList<QTextLayout::FormatRange> formats; + while (len) { + if (m_fullText.at(pos) == QLatin1Char('&') && (len == 1 || m_fullText.at(pos + 1) != QLatin1Char('&'))) { + if (m_mnemonicVisible && (pos == 0 || m_fullText.at(pos - 1) != QLatin1Char('&'))) + formats += underlineRange(pos); + ++pos; + --len; + if (len == 0) + break; + } else if (m_fullText.at(pos) == QLatin1Char('(') && len >= 4 && + m_fullText.at(pos + 1) == QLatin1Char('&') && + m_fullText.at(pos + 2) != QLatin1Char('&') && + m_fullText.at(pos + 3) == QLatin1Char(')')) { + // a mnemonic with format "\s*(&X)" + if (m_mnemonicVisible) { + formats += underlineRange(pos + 1); + } else { + int n = 0; + while (idx > n && text.at(idx - n - 1).isSpace()) + ++n; + idx -= n; + pos += 4; + len -= 4; + continue; + } + } + text[idx] = m_fullText.at(pos); + ++pos; + ++idx; + --len; + } + text.truncate(idx); + + QQuickTextPrivate::get(this)->layout.setFormats(formats); + QQuickText::setText(text); +} + +QT_END_NAMESPACE + +#include "moc_qquickmnemoniclabel_p.cpp" diff --git a/src/quickcontrols2impl/qquickmnemoniclabel_p.h b/src/quickcontrols2impl/qquickmnemoniclabel_p.h new file mode 100644 index 00000000000..69ddbfb1f79 --- /dev/null +++ b/src/quickcontrols2impl/qquickmnemoniclabel_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMNEMONICLABEL_P_H +#define QQUICKMNEMONICLABEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquicktext_p.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickMnemonicLabel : public QQuickText +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText FINAL) + Q_PROPERTY(bool mnemonicVisible READ isMnemonicVisible WRITE setMnemonicVisible FINAL) + QML_NAMED_ELEMENT(MnemonicLabel) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickMnemonicLabel(QQuickItem *parent = nullptr); + + QString text() const; + void setText(const QString &text); + + bool isMnemonicVisible() const; + void setMnemonicVisible(bool visible); + +private: + void updateMnemonic(); + + bool m_mnemonicVisible = true; + QString m_fullText; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickMnemonicLabel) + +#endif // QQUICKMNEMONICLABEL_P_H diff --git a/src/quickcontrols2impl/qquickpaddedrectangle.cpp b/src/quickcontrols2impl/qquickpaddedrectangle.cpp new file mode 100644 index 00000000000..fa3e2ca1863 --- /dev/null +++ b/src/quickcontrols2impl/qquickpaddedrectangle.cpp @@ -0,0 +1,213 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpaddedrectangle_p.h" + +#include <QtQuick/private/qsgadaptationlayer_p.h> + +QT_BEGIN_NAMESPACE + +QQuickPaddedRectangle::QQuickPaddedRectangle(QQuickItem *parent) : + QQuickRectangle(parent) +{ +} + +qreal QQuickPaddedRectangle::padding() const +{ + return m_padding; +} + +void QQuickPaddedRectangle::setPadding(qreal padding) +{ + if (!qFuzzyCompare(m_padding, padding)) { + m_padding = padding; + update(); + emit paddingChanged(); + if (!m_hasTopPadding) + emit topPaddingChanged(); + if (!m_hasLeftPadding) + emit leftPaddingChanged(); + if (!m_hasRightPadding) + emit rightPaddingChanged(); + if (!m_hasBottomPadding) + emit bottomPaddingChanged(); + } +} + +void QQuickPaddedRectangle::resetPadding() +{ + setPadding(0); +} + +qreal QQuickPaddedRectangle::topPadding() const +{ + return m_hasTopPadding ? m_topPadding : m_padding; +} + +void QQuickPaddedRectangle::setTopPadding(qreal padding) +{ + setTopPadding(padding, true); +} + +void QQuickPaddedRectangle::resetTopPadding() +{ + setTopPadding(0, false); +} + +qreal QQuickPaddedRectangle::leftPadding() const +{ + return m_hasLeftPadding ? m_leftPadding : m_padding; +} + +void QQuickPaddedRectangle::setLeftPadding(qreal padding) +{ + setLeftPadding(padding, true); +} + +void QQuickPaddedRectangle::resetLeftPadding() +{ + setLeftPadding(0, false); +} + +qreal QQuickPaddedRectangle::rightPadding() const +{ + return m_hasRightPadding ? m_rightPadding : m_padding; +} + +void QQuickPaddedRectangle::setRightPadding(qreal padding) +{ + setRightPadding(padding, true); +} + +void QQuickPaddedRectangle::resetRightPadding() +{ + setRightPadding(0, false); +} + +qreal QQuickPaddedRectangle::bottomPadding() const +{ + return m_hasBottomPadding ? m_bottomPadding : m_padding; +} + +void QQuickPaddedRectangle::setBottomPadding(qreal padding) +{ + setBottomPadding(padding, true); +} + +void QQuickPaddedRectangle::resetBottomPadding() +{ + setBottomPadding(0, false); +} + +void QQuickPaddedRectangle::setTopPadding(qreal padding, bool has) +{ + qreal oldPadding = topPadding(); + m_hasTopPadding = has; + m_topPadding = padding; + if (!qFuzzyCompare(oldPadding, padding)) { + update(); + emit topPaddingChanged(); + } +} + +void QQuickPaddedRectangle::setLeftPadding(qreal padding, bool has) +{ + qreal oldPadding = leftPadding(); + m_hasLeftPadding = has; + m_leftPadding = padding; + if (!qFuzzyCompare(oldPadding, padding)) { + update(); + emit leftPaddingChanged(); + } +} + +void QQuickPaddedRectangle::setRightPadding(qreal padding, bool has) +{ + qreal oldPadding = rightPadding(); + m_hasRightPadding = has; + m_rightPadding = padding; + if (!qFuzzyCompare(oldPadding, padding)) { + update(); + emit rightPaddingChanged(); + } +} + +void QQuickPaddedRectangle::setBottomPadding(qreal padding, bool has) +{ + qreal oldPadding = bottomPadding(); + m_hasBottomPadding = has; + m_bottomPadding = padding; + if (!qFuzzyCompare(oldPadding, padding)) { + update(); + emit bottomPaddingChanged(); + } +} + +QSGNode *QQuickPaddedRectangle::updatePaintNode(QSGNode *node, UpdatePaintNodeData *data) +{ + QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(node); + if (!transformNode) + transformNode = new QSGTransformNode; + + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(QQuickRectangle::updatePaintNode(transformNode->firstChild(), data)); + + if (rectNode) { + if (!transformNode->firstChild()) + transformNode->appendChildNode(rectNode); + + qreal top = topPadding(); + qreal left = leftPadding(); + qreal right = rightPadding(); + qreal bottom = bottomPadding(); + + if (!qFuzzyIsNull(top) || !qFuzzyIsNull(left) || !qFuzzyIsNull(right) || !qFuzzyIsNull(bottom)) { + QMatrix4x4 m; + m.translate(left, top); + transformNode->setMatrix(m); + + qreal w = qMax<qreal>(0.0, width() -left-right); + qreal h = qMax<qreal>(0.0, height() -top-bottom); + + rectNode->setRect(QRectF(0, 0, w, h)); + rectNode->update(); + } + } + return transformNode; +} + +QT_END_NAMESPACE + +#include "moc_qquickpaddedrectangle_p.cpp" diff --git a/src/quickcontrols2impl/qquickpaddedrectangle_p.h b/src/quickcontrols2impl/qquickpaddedrectangle_p.h new file mode 100644 index 00000000000..277432705e5 --- /dev/null +++ b/src/quickcontrols2impl/qquickpaddedrectangle_p.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPADDEDRECTANGLE_P_H +#define QQUICKPADDEDRECTANGLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquickrectangle_p.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickPaddedRectangle : public QQuickRectangle +{ + Q_OBJECT + Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged FINAL) + Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged FINAL) + Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged FINAL) + Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged FINAL) + Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged FINAL) + QML_NAMED_ELEMENT(PaddedRectangle) + QML_ADDED_IN_VERSION(2, 0) + +public: + QQuickPaddedRectangle(QQuickItem *parent = nullptr); + + qreal padding() const; + void setPadding(qreal padding); + void resetPadding(); + + qreal topPadding() const; + void setTopPadding(qreal padding); + void resetTopPadding(); + + qreal leftPadding() const; + void setLeftPadding(qreal padding); + void resetLeftPadding(); + + qreal rightPadding() const; + void setRightPadding(qreal padding); + void resetRightPadding(); + + qreal bottomPadding() const; + void setBottomPadding(qreal padding); + void resetBottomPadding(); + +Q_SIGNALS: + void paddingChanged(); + void topPaddingChanged(); + void leftPaddingChanged(); + void rightPaddingChanged(); + void bottomPaddingChanged(); + +protected: + QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override; + +private: + void setTopPadding(qreal padding, bool has); + void setLeftPadding(qreal padding, bool has); + void setRightPadding(qreal padding, bool has); + void setBottomPadding(qreal padding, bool has); + + qreal m_padding = 0; + qreal m_topPadding = 0; + qreal m_leftPadding = 0; + qreal m_rightPadding = 0; + qreal m_bottomPadding = 0; + bool m_hasTopPadding = false; + bool m_hasLeftPadding = false; + bool m_hasRightPadding = false; + bool m_hasBottomPadding = false; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickPaddedRectangle) + +#endif // QQUICKPADDEDRECTANGLE_P_H diff --git a/src/quickcontrols2impl/qquickplaceholdertext.cpp b/src/quickcontrols2impl/qquickplaceholdertext.cpp new file mode 100644 index 00000000000..a71fb99eec2 --- /dev/null +++ b/src/quickcontrols2impl/qquickplaceholdertext.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickplaceholdertext_p.h" + +#include <QtQuick/private/qquicktext_p_p.h> +#include <QtQuick/private/qquicktextinput_p_p.h> +#include <QtQuick/private/qquicktextedit_p_p.h> + +QT_BEGIN_NAMESPACE + +QQuickPlaceholderText::QQuickPlaceholderText(QQuickItem *parent) : QQuickText(parent) +{ +} + +void QQuickPlaceholderText::componentComplete() +{ + QQuickText::componentComplete(); + connect(parentItem(), SIGNAL(effectiveHorizontalAlignmentChanged()), this, SLOT(updateAlignment())); + updateAlignment(); +} + +void QQuickPlaceholderText::updateAlignment() +{ + if (QQuickTextInput *input = qobject_cast<QQuickTextInput *>(parentItem())) { + if (QQuickTextInputPrivate::get(input)->hAlignImplicit) + resetHAlign(); + else + setHAlign(static_cast<HAlignment>(input->hAlign())); + } else if (QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(parentItem())) { + if (QQuickTextEditPrivate::get(edit)->hAlignImplicit) + resetHAlign(); + else + setHAlign(static_cast<HAlignment>(edit->hAlign())); + } else { + resetHAlign(); + } +} + +QT_END_NAMESPACE + +#include "moc_qquickplaceholdertext_p.cpp" diff --git a/src/quickcontrols2impl/qquickplaceholdertext_p.h b/src/quickcontrols2impl/qquickplaceholdertext_p.h new file mode 100644 index 00000000000..0beccd725ce --- /dev/null +++ b/src/quickcontrols2impl/qquickplaceholdertext_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPLACEHOLDERTEXT_P_H +#define QQUICKPLACEHOLDERTEXT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquicktext_p.h> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickPlaceholderText : public QQuickText +{ + Q_OBJECT + QML_NAMED_ELEMENT(PlaceholderText) + QML_ADDED_IN_VERSION(2, 2) + +public: + explicit QQuickPlaceholderText(QQuickItem *parent = nullptr); + +protected: + void componentComplete() override; + +private Q_SLOTS: + void updateAlignment(); +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickPlaceholderText) + +#endif // QQUICKPLACEHOLDERTEXT_P_H diff --git a/src/quickcontrols2impl/qquicktumblerview.cpp b/src/quickcontrols2impl/qquicktumblerview.cpp new file mode 100644 index 00000000000..911e2ae8cfc --- /dev/null +++ b/src/quickcontrols2impl/qquicktumblerview.cpp @@ -0,0 +1,320 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktumblerview_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquicklistview_p.h> +#include <QtQuick/private/qquickpathview_p.h> + +#include <QtQuickTemplates2/private/qquicktumbler_p.h> +#include <QtQuickTemplates2/private/qquicktumbler_p_p.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcTumblerView, "qt.quick.controls.tumblerview") + +QQuickTumblerView::QQuickTumblerView(QQuickItem *parent) : + QQuickItem(parent) +{ + // We don't call createView() here because we don't know what the wrap flag is set to + // yet, and we don't want to create a view that might never get used. +} + +QVariant QQuickTumblerView::model() const +{ + return m_model; +} + +void QQuickTumblerView::setModel(const QVariant &model) +{ + qCDebug(lcTumblerView) << "setting model to:" << model << "on" + << (m_pathView ? static_cast<QObject*>(m_pathView) : static_cast<QObject*>(m_listView)); + if (model == m_model) + return; + + m_model = model; + + if (m_pathView) { + m_pathView->setModel(m_model); + } else if (m_listView) { + // QQuickItemView::setModel() resets the current index, + // but if we're still creating the Tumbler, it should be maintained. + const int oldCurrentIndex = m_listView->currentIndex(); + m_listView->setModel(m_model); + if (!isComponentComplete()) + m_listView->setCurrentIndex(oldCurrentIndex); + } + + emit modelChanged(); +} + +QQmlComponent *QQuickTumblerView::delegate() const +{ + return m_delegate; +} + +void QQuickTumblerView::setDelegate(QQmlComponent *delegate) +{ + qCDebug(lcTumblerView) << "setting delegate to:" << delegate << "on" + << (m_pathView ? static_cast<QObject*>(m_pathView) : static_cast<QObject*>(m_listView)); + if (delegate == m_delegate) + return; + + m_delegate = delegate; + + if (m_pathView) + m_pathView->setDelegate(m_delegate); + else if (m_listView) + m_listView->setDelegate(m_delegate); + + emit delegateChanged(); +} + +QQuickPath *QQuickTumblerView::path() const +{ + return m_path; +} + +void QQuickTumblerView::setPath(QQuickPath *path) +{ + if (path == m_path) + return; + + m_path = path; + emit pathChanged(); +} + +void QQuickTumblerView::createView() +{ + Q_ASSERT(m_tumbler); + + // We create a view regardless of whether or not we know + // the count yet, because we rely on the view to tell us the count. + if (m_tumbler->wrap()) { + if (m_listView) { + // It's necessary to call deleteLater() rather than delete, + // as this code is most likely being run in rensponse to a signal + // emission somewhere in the list view's internals, so we need to + // wait until that has finished. + m_listView->deleteLater(); + QQml_setParent_noEvent(m_listView, nullptr); + // The auto tests pass with unparenting the list view alone, but + // just to be sure, we unset some other things as well. + m_listView->setParentItem(nullptr); + m_listView->setVisible(false); + m_listView->setModel(QVariant()); + m_listView = nullptr; + } + + if (!m_pathView) { + qCDebug(lcTumblerView) << "creating PathView"; + + m_pathView = new QQuickPathView; + QQmlEngine::setContextForObject(m_pathView, qmlContext(this)); + QQml_setParent_noEvent(m_pathView, this); + m_pathView->setParentItem(this); + m_pathView->setPath(m_path); + m_pathView->setDelegate(m_delegate); + m_pathView->setPreferredHighlightBegin(0.5); + m_pathView->setPreferredHighlightEnd(0.5); + m_pathView->setHighlightMoveDuration(1000); + m_pathView->setClip(true); + + // Give the view a size. + updateView(); + // Set the model. + updateModel(); + + qCDebug(lcTumblerView) << "finished creating PathView"; + } + } else { + if (m_pathView) { + m_pathView->deleteLater(); + QQml_setParent_noEvent(m_pathView, nullptr); + m_pathView->setParentItem(nullptr); + m_pathView->setVisible(false); + m_pathView->setModel(QVariant()); + m_pathView = nullptr; + } + + if (!m_listView) { + qCDebug(lcTumblerView) << "creating ListView"; + + m_listView = new QQuickListView; + QQmlEngine::setContextForObject(m_listView, qmlContext(this)); + QQml_setParent_noEvent(m_listView, this); + m_listView->setParentItem(this); + m_listView->setSnapMode(QQuickListView::SnapToItem); + m_listView->setClip(true); + + // Give the view a size. + updateView(); + // Set the model. + updateModel(); + + // Set these after the model is set so that the currentItem animation + // happens instantly on startup/after switching models. If we set them too early, + // the view animates any potential currentIndex change over one second, + // which we don't want when the contentItem has just been created. + m_listView->setDelegate(m_delegate); + // Set this after setting the delegate to avoid unexpected currentIndex changes: QTBUG-79150 + m_listView->setHighlightRangeMode(QQuickListView::StrictlyEnforceRange); + m_listView->setHighlightMoveDuration(1000); + + qCDebug(lcTumblerView) << "finished creating ListView"; + } + } +} + +// Called whenever the size or visibleItemCount changes. +void QQuickTumblerView::updateView() +{ + QQuickItem *theView = view(); + if (!theView) + return; + + theView->setSize(QSizeF(width(), height())); + + // Can be called in geometryChange when it might not have a parent item yet. + if (!m_tumbler) + return; + + // Set view-specific properties that have a dependency on the size, etc. + if (m_pathView) { + m_pathView->setPathItemCount(m_tumbler->visibleItemCount() + 1); + m_pathView->setDragMargin(width() / 2); + } else { + m_listView->setPreferredHighlightBegin(height() / 2 - (height() / m_tumbler->visibleItemCount() / 2)); + m_listView->setPreferredHighlightEnd(height() / 2 + (height() / m_tumbler->visibleItemCount() / 2)); + } +} + +void QQuickTumblerView::updateModel() +{ + if (m_pathView && !m_pathView->model().isValid() && m_model.isValid()) { + // QQuickPathView::setPathItemCount() resets the offset animation, + // so we just skip the animation while constructing the view. + const int oldHighlightMoveDuration = m_pathView->highlightMoveDuration(); + m_pathView->setHighlightMoveDuration(0); + + // Setting model can change the count, which can affect the wrap, which can cause + // the current view to be deleted before setModel() is finished, which causes a crash. + // Since QQuickTumbler can't know about QQuickTumblerView, we use its private API to + // inform it that it should delay setting wrap. + QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(m_tumbler); + tumblerPrivate->beginSetModel(); + m_pathView->setModel(m_model); + tumblerPrivate->endSetModel(); + + // The count-depends-on-wrap behavior could cause wrap to change after + // the call above, so we must check that we're still using a PathView. + if (m_pathView) + m_pathView->setHighlightMoveDuration(oldHighlightMoveDuration); + } else if (m_listView && !m_listView->model().isValid() && m_model.isValid()) { + const int currentIndex = m_tumbler->currentIndex(); + QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(m_tumbler); + + // setModel() causes QQuickTumblerPrivate::_q_onViewCountChanged() to + // be called, which calls QQuickTumbler::setCurrentIndex(), + // which results in QQuickItemViewPrivate::createHighlightItem() being + // called. When the highlight item is created, + // QQuickTumblerPrivate::itemChildAdded() is notified and + // QQuickTumblerPrivate::_q_updateItemHeights() is called, which causes + // a geometry change in the item and createHighlight() is called again. + // However, since the highlight item hadn't been assigned yet in the + // previous call frame, the "if (highlight) { delete highlight; }" + // check doesn't succeed, so the item is never deleted. + // + // To avoid this, we tell QQuickTumblerPrivate to ignore signals while + // setting the model, and manually call _q_onViewCountChanged() to + // ensure the correct sequence of calls happens (_q_onViewCountChanged() + // has to be within the ignoreSignals scope, because it also generates + // recursion otherwise). + tumblerPrivate->ignoreSignals = true; + m_listView->setModel(m_model); + m_listView->setCurrentIndex(currentIndex); + + tumblerPrivate->_q_onViewCountChanged(); + tumblerPrivate->ignoreSignals = false; + } +} + +void QQuickTumblerView::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + QQuickItem::geometryChange(newGeometry, oldGeometry); + updateView(); +} + +void QQuickTumblerView::componentComplete() +{ + QQuickItem::componentComplete(); + updateView(); +} + +void QQuickTumblerView::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + + if (change == QQuickItem::ItemParentHasChanged && data.item) { + if (m_tumbler) + m_tumbler->disconnect(this); + + m_tumbler = qobject_cast<QQuickTumbler*>(parentItem()); + + if (m_tumbler) { + // We assume that the parentChanged() signal of the tumbler will be emitted before its wrap property is set... + connect(m_tumbler, &QQuickTumbler::wrapChanged, this, &QQuickTumblerView::createView); + connect(m_tumbler, &QQuickTumbler::visibleItemCountChanged, this, &QQuickTumblerView::updateView); + } + } +} + +QQuickItem *QQuickTumblerView::view() +{ + if (!m_tumbler) + return nullptr; + + if (m_tumbler->wrap()) + return m_pathView; + + return m_listView; +} + +QT_END_NAMESPACE + +#include "moc_qquicktumblerview_p.cpp" diff --git a/src/quickcontrols2impl/qquicktumblerview_p.h b/src/quickcontrols2impl/qquicktumblerview_p.h new file mode 100644 index 00000000000..44ce5fa626c --- /dev/null +++ b/src/quickcontrols2impl/qquicktumblerview_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTUMBLERVIEW_P_H +#define QQUICKTUMBLERVIEW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QQuickItem> +#include <QtQuickControls2Impl/private/qtquickcontrols2implglobal_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickListView; +class QQuickPath; +class QQuickPathView; + +class QQuickTumbler; + +class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickTumblerView : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged) + Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) + Q_PROPERTY(QQuickPath *path READ path WRITE setPath NOTIFY pathChanged) + QML_NAMED_ELEMENT(TumblerView) + QML_ADDED_IN_VERSION(2, 1) + +public: + QQuickTumblerView(QQuickItem *parent = nullptr); + + QVariant model() const; + void setModel(const QVariant &model); + + QQmlComponent *delegate() const; + void setDelegate(QQmlComponent *delegate); + + QQuickPath *path() const; + void setPath(QQuickPath *path); + +Q_SIGNALS: + void modelChanged(); + void delegateChanged(); + void pathChanged(); + +protected: + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + void componentComplete() override; + void itemChange(ItemChange change, const ItemChangeData &data) override; + +private: + QQuickItem *view(); + void createView(); + void updateView(); + void updateModel(); + + void wrapChange(); + + QQuickTumbler *m_tumbler = nullptr; + QVariant m_model; + QQmlComponent *m_delegate = nullptr; + QQuickPathView *m_pathView = nullptr; + QQuickListView *m_listView = nullptr; + QQuickPath *m_path = nullptr; +}; + +QT_END_NAMESPACE + +#endif // TUMBLERVIEW_H diff --git a/src/quickcontrols2impl/qtquickcontrols2foreign_p.h b/src/quickcontrols2impl/qtquickcontrols2foreign_p.h new file mode 100644 index 00000000000..d999fc13be1 --- /dev/null +++ b/src/quickcontrols2impl/qtquickcontrols2foreign_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +** +** +** +** +** +** +** +** +** +** +** +** +** +** +** +******************************************************************************/ +#ifndef QTQUICKCONTROLS2FOREIGN_P_H + +#include <QtQml/qqml.h> +#include <QtQuickTemplates2/private/qquickoverlay_p.h> +#include <QtQuickTemplates2/private/qquicksplitview_p.h> + +QT_BEGIN_NAMESPACE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +// These are necessary in order to use C++ types in a file where only QtQuick.Controls has been imported. +// Control types like Button don't need this done for them, as each style module provides a Button type, +// and QtQuick.Controls is a sort of alias for the active style import. + +struct QQuickOverlayAttachedForeign +{ + Q_GADGET + QML_NAMED_ELEMENT(Overlay) + QML_FOREIGN(QQuickOverlay) + QML_UNCREATABLE("") + QML_ADDED_IN_VERSION(2, 3) +}; + +struct QQuickSplitHandleAttachedForeign +{ + Q_GADGET + QML_NAMED_ELEMENT(SplitHandle) + QML_FOREIGN(QQuickSplitHandleAttached) + QML_UNCREATABLE("") + QML_ADDED_IN_VERSION(2, 13) +}; + +QT_END_NAMESPACE + +#endif // QTQUICKCONTROLS2FOREIGN_P_H diff --git a/src/quickcontrols2impl/qtquickcontrols2implglobal_p.h b/src/quickcontrols2impl/qtquickcontrols2implglobal_p.h new file mode 100644 index 00000000000..1065aa7876a --- /dev/null +++ b/src/quickcontrols2impl/qtquickcontrols2implglobal_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTQUICKCONTROLS2IMPLGLOBAL_H +#define QTQUICKCONTROLS2IMPLGLOBAL_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> + +#ifndef QT_STATIC +# if defined(QT_BUILD_QUICKCONTROLS2IMPL_LIB) +# define Q_QUICKCONTROLS2IMPL_EXPORT Q_DECL_EXPORT +# else +# define Q_QUICKCONTROLS2IMPL_EXPORT Q_DECL_IMPORT +# endif +#else +# define Q_QUICKCONTROLS2IMPL_EXPORT +#endif + +#define Q_QUICKCONTROLS2_PRIVATE_EXPORT Q_QUICKCONTROLS2IMPL_EXPORT + +#endif // QTQUICKCONTROLS2IMPLGLOBAL_H diff --git a/src/quickcontrolstestutils/CMakeLists.txt b/src/quickcontrolstestutils/CMakeLists.txt new file mode 100644 index 00000000000..69d41df2f97 --- /dev/null +++ b/src/quickcontrolstestutils/CMakeLists.txt @@ -0,0 +1,25 @@ +qt_internal_add_module(QuickControlsTestUtilsPrivate + CONFIG_MODULE_NAME quickcontrolstestutilsprivate + STATIC + INTERNAL_MODULE + SOURCES + controlstestutils.cpp + controlstestutils_p.h + dialogstestutils_p.h + dialogstestutils.cpp + qtest_quickcontrols_p.h + DEFINES + QT_BUILD_SHARED_QUICK_CONTROLS_TEST_UTILS_LIB + PUBLIC_LIBRARIES + Qt::Core + Qt::Test + Qt::Qml + Qt::QmlPrivate + Qt::Quick + Qt::QuickControls2 + Qt::QuickDialogs2QuickImplPrivate + Qt::QuickPrivate + Qt::QuickTemplates2 + Qt::QuickTemplates2Private + Qt::QuickTestUtilsPrivate +) diff --git a/src/quickcontrolstestutils/controlstestutils.cpp b/src/quickcontrolstestutils/controlstestutils.cpp new file mode 100644 index 00000000000..ec3748fed44 --- /dev/null +++ b/src/quickcontrolstestutils/controlstestutils.cpp @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 "controlstestutils_p.h" + +#include <QtTest/qsignalspy.h> +#include <QtQuickControls2/qquickstyle.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> + +QQuickControlsTestUtils::QQuickControlsApplicationHelper::QQuickControlsApplicationHelper(QQmlDataTest *testCase, + const QString &testFilePath, const QVariantMap &initialProperties, const QStringList &qmlImportPaths) + : QQuickApplicationHelper(testCase, testFilePath, initialProperties, qmlImportPaths) +{ + if (ready) + appWindow = qobject_cast<QQuickApplicationWindow*>(cleanup.data()); +} + +bool QQuickControlsTestUtils::QQuickStyleHelper::updateStyle(const QString &style) +{ + // If it's not the first time a style has been set and the new style is not different, do nothing. + if (!currentStyle.isEmpty() && style == currentStyle) + return false; + + engine.reset(); + currentStyle = style; + qmlClearTypeRegistrations(); + engine.reset(new QQmlEngine); + QQuickStyle::setStyle(style); + + QQmlComponent component(engine.data()); + component.setData(QString::fromUtf8("import QtQuick\nimport QtQuick.Controls\n Control { }").toUtf8(), QUrl()); + + return true; +} + +void QQuickControlsTestUtils::forEachControl(QQmlEngine *engine, const QString &qqc2ImportPath, + const QString &sourcePath, const QString &targetPath, const QStringList &skipList, + QQuickControlsTestUtils::ForEachCallback callback) +{ + // We cannot use QQmlComponent to load QML files directly from the source tree. + // For styles that use internal QML types (eg. material/Ripple.qml), the source + // dir would be added as an "implicit" import path overriding the actual import + // path (qtbase/qml/QtQuick/Controls.2/Material). => The QML engine fails to load + // the style C++ plugin from the implicit import path (the source dir). + // + // Therefore we only use the source tree for finding out the set of QML files that + // a particular style implements, and then we locate the respective QML files in + // the engine's import path. This way we can use QQmlComponent to load each QML file + // for benchmarking. + + const QFileInfoList entries = QDir(qqc2ImportPath + QLatin1Char('/') + sourcePath).entryInfoList( + QStringList(QStringLiteral("*.qml")), QDir::Files); + for (const QFileInfo &entry : entries) { + QString name = entry.baseName(); + if (!skipList.contains(name)) { + const auto importPathList = engine->importPathList(); + for (const QString &importPath : importPathList) { + QString name = entry.dir().dirName() + QLatin1Char('/') + entry.fileName(); + QString filePath = importPath + QLatin1Char('/') + targetPath + QLatin1Char('/') + entry.fileName(); + if (filePath.startsWith(QLatin1Char(':'))) + filePath.prepend(QStringLiteral("qrc")); + if (QFile::exists(filePath)) { + callback(name, QUrl::fromLocalFile(filePath)); + break; + } else { + QUrl url(filePath); + filePath = QQmlFile::urlToLocalFileOrQrc(filePath); + if (!filePath.isEmpty() && QFile::exists(filePath)) { + callback(name, url); + break; + } + } + } + } + } +} + +void QQuickControlsTestUtils::addTestRowForEachControl(QQmlEngine *engine, const QString &qqc2ImportPath, + const QString &sourcePath, const QString &targetPath, const QStringList &skipList) +{ + forEachControl(engine, qqc2ImportPath, sourcePath, targetPath, skipList, [&](const QString &relativePath, const QUrl &absoluteUrl) { + QTest::newRow(qPrintable(relativePath)) << absoluteUrl; + }); +} + +bool QQuickControlsTestUtils::verifyButtonClickable(QQuickAbstractButton *button) +{ + if (!button->window()) { + qWarning() << "button" << button << "doesn't have an associated window"; + return false; + } + + if (!button->isEnabled()) { + qWarning() << "button" << button << "is not enabled"; + return false; + } + + if (!button->isVisible()) { + qWarning() << "button" << button << "is not visible"; + return false; + } + + if (button->width() <= 0.0) { + qWarning() << "button" << button << "must have a width greater than 0"; + return false; + } + + if (button->height() <= 0.0) { + qWarning() << "button" << button << "must have a height greater than 0"; + return false; + } + + return true; +} + +bool QQuickControlsTestUtils::clickButton(QQuickAbstractButton *button) +{ + if (!verifyButtonClickable(button)) + return false; + + QSignalSpy spy(button, &QQuickAbstractButton::clicked); + if (!spy.isValid()) { + qWarning() << "button" << button << "must have a valid clicked signal"; + return false; + } + + const QPoint buttonCenter = button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint(); + QTest::mouseClick(button->window(), Qt::LeftButton, Qt::NoModifier, buttonCenter); + if (spy.count() != 1) { + qWarning() << "clicked signal of button" << button << "was not emitted after clicking"; + return false; + } + + return true; +} + +bool QQuickControlsTestUtils::doubleClickButton(QQuickAbstractButton *button) +{ + if (!verifyButtonClickable(button)) + return false; + + QSignalSpy spy(button, &QQuickAbstractButton::clicked); + if (!spy.isValid()) { + qWarning() << "button" << button << "must have a valid doubleClicked signal"; + return false; + } + + const QPoint buttonCenter = button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint(); + QTest::mouseDClick(button->window(), Qt::LeftButton, Qt::NoModifier, buttonCenter); + if (spy.count() != 1) { + qWarning() << "doubleClicked signal of button" << button << "was not emitted after double-clicking"; + return false; + } + + return true; +} diff --git a/src/quickcontrolstestutils/controlstestutils_p.h b/src/quickcontrolstestutils/controlstestutils_p.h new file mode 100644 index 00000000000..4d4f0432b04 --- /dev/null +++ b/src/quickcontrolstestutils/controlstestutils_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 CONTROLSTESTUTILS_P_H +#define CONTROLSTESTUTILS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTestUtils/private/visualtestutils_p.h> + +QT_BEGIN_NAMESPACE + +class QQmlEngine; +class QQuickApplicationWindow; +class QQuickAbstractButton; + +namespace QQuickControlsTestUtils +{ + class QQuickControlsApplicationHelper : public QQuickVisualTestUtils::QQuickApplicationHelper + { + public: + QQuickControlsApplicationHelper(QQmlDataTest *testCase, const QString &testFilePath, + const QVariantMap &initialProperties = {}, + const QStringList &qmlImportPaths = {}); + + QQuickApplicationWindow *appWindow = nullptr; + }; + + struct QQuickStyleHelper + { + [[nodiscard]] bool updateStyle(const QString &style); + + QString currentStyle; + QScopedPointer<QQmlEngine> engine; + }; + + typedef std::function<void(const QString &/*relativePath*/, const QUrl &/*absoluteUrl*/)> ForEachCallback; + + void forEachControl(QQmlEngine *engine, const QString &qqc2ImportPath, const QString &sourcePath, + const QString &targetPath, const QStringList &skipList, ForEachCallback callback); + void addTestRowForEachControl(QQmlEngine *engine, const QString &qqc2ImportPath, const QString &sourcePath, + const QString &targetPath, const QStringList &skipList = QStringList()); + + [[nodiscard]] bool verifyButtonClickable(QQuickAbstractButton *button); + [[nodiscard]] bool clickButton(QQuickAbstractButton *button); + [[nodiscard]] bool doubleClickButton(QQuickAbstractButton *button); +} + +QT_END_NAMESPACE + +#endif // CONTROLSTESTUTILS_P_H diff --git a/src/quickcontrolstestutils/dialogstestutils.cpp b/src/quickcontrolstestutils/dialogstestutils.cpp new file mode 100644 index 00000000000..044926e7c8e --- /dev/null +++ b/src/quickcontrolstestutils/dialogstestutils.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 "dialogstestutils_p.h" + +#include <QtTest/qsignalspy.h> +#include <QtQuick/private/qquicklistview_p.h> +#include <QtQuickTest/quicktest.h> +#include <QtQuickControls2/qquickstyle.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h> +#include <QtQuickDialogs2QuickImpl/private/qquickfiledialogdelegate_p.h> +#include <QtQuickDialogs2QuickImpl/private/qquickfolderbreadcrumbbar_p.h> +#include <QtQuickDialogs2QuickImpl/private/qquickfolderbreadcrumbbar_p_p.h> + +QT_BEGIN_NAMESPACE + +bool QQuickDialogTestUtils::verifyFileDialogDelegates(QQuickListView *fileDialogListView, + const QStringList &expectedFiles, QString &failureMessage) +{ + if (QQuickTest::qIsPolishScheduled(fileDialogListView)) { + if (!QQuickTest::qWaitForItemPolished(fileDialogListView)) { + failureMessage = QLatin1String("Failed to polish fileDialogListView"); + return false; + } + } + + QStringList actualFiles; + for (int i = 0; i < fileDialogListView->count(); ++i) { + auto delegate = qobject_cast<QQuickFileDialogDelegate*>( + QQuickVisualTestUtils::findViewDelegateItem(fileDialogListView, i)); + if (!delegate) { + failureMessage = QString::fromLatin1("Delegate at index %1 is null").arg(i); + return false; + } + + // Need to call absoluteFilePath on Windows; see comment in dialogtestutil.h. + actualFiles.append(QFileInfo(delegate->file().toLocalFile()).absoluteFilePath()); + } + + if (actualFiles != expectedFiles) { + failureMessage = QString::fromLatin1("Mismatch in actual vs expected " + "delegates in fileDialogListView:\n expected: %1\n actual: %2") + .arg(QDebug::toString(expectedFiles), QDebug::toString(actualFiles)); + return false; + } + + return true; +} + +bool QQuickDialogTestUtils::verifyBreadcrumbDelegates(QQuickFolderBreadcrumbBar *breadcrumbBar, + const QUrl &expectedFolder, QString &failureMessage) +{ + if (!breadcrumbBar) { + failureMessage = QLatin1String("breadcrumbBar is null"); + return false; + } + + auto breadcrumbBarListView = qobject_cast<QQuickListView*>(breadcrumbBar->contentItem()); + if (!breadcrumbBarListView) { + failureMessage = QLatin1String("breadcrumbBar's ListView is null"); + return false; + } + + if (QQuickTest::qIsPolishScheduled(breadcrumbBarListView)) { + if (!QQuickTest::qWaitForItemPolished(breadcrumbBarListView)) { + failureMessage = QLatin1String("Failed to polish breadcrumbBarListView"); + return false; + } + } + + QStringList actualCrumbs; + for (int i = 0; i < breadcrumbBarListView->count(); ++i) { + auto delegate = qobject_cast<QQuickAbstractButton*>( + QQuickVisualTestUtils::findViewDelegateItem(breadcrumbBarListView, i)); + if (!delegate) { + // It's a separator or some other non-crumb item. + continue; + } + + actualCrumbs.append(delegate->text()); + } + + QStringList expectedCrumbs = QQuickFolderBreadcrumbBarPrivate::crumbPathsForFolder(expectedFolder); + for (int i = 0; i < expectedCrumbs.size(); ++i) { + QString &crumbPath = expectedCrumbs[i]; + crumbPath = QQuickFolderBreadcrumbBarPrivate::folderBaseName(crumbPath); + } + + if (actualCrumbs != expectedCrumbs) { + failureMessage = QString::fromLatin1("Mismatch in actual vs expected " + "delegates in breadcrumbBarListView:\n expected: %1\n actual: %2") + .arg(QDebug::toString(expectedCrumbs), QDebug::toString(actualCrumbs)); + return false; + } + + return true; +} + +QQuickAbstractButton *QQuickDialogTestUtils::findDialogButton(QQuickDialogButtonBox *box, const QString &buttonText) +{ + for (int i = 0; i < box->count(); ++i) { + auto button = qobject_cast<QQuickAbstractButton*>(box->itemAt(i)); + if (button && button->text().toUpper() == buttonText.toUpper()) + return button; + } + return nullptr; +} + +void QQuickDialogTestUtils::enterText(QWindow *window, const QString &textToEnter) +{ + for (int i = 0; i < textToEnter.size(); ++i) { + const QChar key = textToEnter.at(i); + QTest::keyClick(window, key.toLatin1()); + } +} + +QT_END_NAMESPACE diff --git a/src/quickcontrolstestutils/dialogstestutils_p.h b/src/quickcontrolstestutils/dialogstestutils_p.h new file mode 100644 index 00000000000..2d5ff0c5739 --- /dev/null +++ b/src/quickcontrolstestutils/dialogstestutils_p.h @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIALOGSTESTUTILS_H +#define DIALOGSTESTUTILS_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> + +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> + +// We need these for Windows, because FolderListModel returns a lowercase drive letter; e.g.: +// "file:///c:/blah.txt", whereas other API returns "file:///C:/blah.txt". +#define COMPARE_URL(url1, url2) \ + QCOMPARE(QFileInfo(url1.toLocalFile()).absoluteFilePath(), QFileInfo(url2.toLocalFile()).absoluteFilePath()); + +// Store a copy of the arguments in case { ... } list initializer syntax is used as an argument, +// which could result in two different lists being created and passed to std::transform() +// (and would also require it to be enclosed in parentheses everywhere it's used). +#define COMPARE_URLS(actualUrls, expectedUrls) \ +{ \ + const QList<QUrl> actualUrlsCopy = actualUrls; \ + QList<QString> actualPaths; \ + std::transform(actualUrlsCopy.begin(), actualUrlsCopy.end(), std::back_insert_iterator(actualPaths), \ + [](const QUrl &url) { return QFileInfo(url.toLocalFile()).absoluteFilePath(); }); \ + const QList<QUrl> expectedUrlsCopy = expectedUrls; \ + QList<QString> expectedPaths; \ + std::transform(expectedUrlsCopy.begin(), expectedUrlsCopy.end(), std::back_insert_iterator(expectedPaths), \ + [](const QUrl &url) { return QFileInfo(url.toLocalFile()).absoluteFilePath(); }); \ + QCOMPARE(actualPaths, expectedPaths); \ +} + +#define OPEN_QUICK_DIALOG() \ +QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); \ +QVERIFY(dialogHelper.waitForWindowActive()); \ +QVERIFY(dialogHelper.openDialog()); \ +QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + +#define CLOSE_QUICK_DIALOG() \ + do { \ + dialogHelper.dialog->close(); \ + QVERIFY(!dialogHelper.dialog->isVisible()); \ + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); \ + } while (false) + +QT_BEGIN_NAMESPACE +class QWindow; + +class QQuickListView; + +class QQuickAbstractButton; + +class QQuickDialogButtonBox; +class QQuickFolderBreadcrumbBar; + +namespace QQuickDialogTestUtils +{ + +// Saves duplicating a bunch of code in every test. +template<typename DialogType, typename QuickDialogType> +class DialogTestHelper +{ +public: + DialogTestHelper(QQmlDataTest *testCase, const QString &testFilePath, + const QStringList &qmlImportPaths = {}, const QVariantMap &initialProperties = {}) : + appHelper(testCase, testFilePath, initialProperties, qmlImportPaths) + { + if (!appHelper.ready) + return; + + dialog = appHelper.window->property("dialog").value<DialogType*>(); + if (!dialog) { + appHelper.errorMessage = "\"dialog\" property is not valid"; + return; + } + + appHelper.window->show(); + appHelper.window->requestActivate(); + } + + Q_REQUIRED_RESULT bool isWindowInitialized() const + { + return appHelper.ready; + } + + Q_REQUIRED_RESULT bool waitForWindowActive() + { + return QTest::qWaitForWindowActive(appHelper.window); + } + + bool openDialog() + { + dialog->open(); + if (!dialog->isVisible()) { + appHelper.errorMessage = "Dialog is not visible"; + return false; + } + + // We might want to call this function more than once, + // and we only need to get these members the first time. + if (!quickDialog) { + quickDialog = appHelper.window->findChild<QuickDialogType*>(); + if (!quickDialog) { + appHelper.errorMessage = "Can't find Qt Quick-based dialog"; + return false; + } + } + + return true; + } + + bool isQuickDialogOpen() const + { + return quickDialog->isOpened(); + } + + QQuickWindow *window() const + { + return appHelper.window; + } + + const char *failureMessage() const + { + return appHelper.errorMessage.constData(); + } + + QQuickVisualTestUtils::QQuickApplicationHelper appHelper; + DialogType *dialog = nullptr; + QuickDialogType *quickDialog = nullptr; +}; + +bool verifyFileDialogDelegates(QQuickListView *fileDialogListView, const QStringList &expectedFiles, QString &failureMessage); + +bool verifyBreadcrumbDelegates(QQuickFolderBreadcrumbBar *breadcrumbBar, const QUrl &expectedFolder, QString &failureMessage); + +QQuickAbstractButton *findDialogButton(QQuickDialogButtonBox *box, const QString &buttonText); + +void enterText(QWindow *window, const QString &textToEnter); +} + +QT_END_NAMESPACE + +#endif // DIALOGSTESTUTILS_H diff --git a/src/quickcontrolstestutils/qtest_quickcontrols_p.h b/src/quickcontrolstestutils/qtest_quickcontrols_p.h new file mode 100644 index 00000000000..1c1ae278089 --- /dev/null +++ b/src/quickcontrolstestutils/qtest_quickcontrols_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTEST_QUICKCONTROLS_P_H +#define QTEST_QUICKCONTROLS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtTest/qtest.h> +#include <QtTest/private/qtestresult_p.h> +#include <QtGui/qguiapplication.h> +#include <QtQml/qqml.h> +#include <QtQuickControls2/qquickstyle.h> +#include <QtQuickControls2/private/qquickstyle_p.h> + +inline QStringList testStyles() +{ + // It's not enough to check if the name is empty, because since Qt 6 + // we set an appropriate style for the platform if no style was specified. + // Also, we need the name check to come first, as isUsingDefaultStyle() does not do any resolving, + // and so its return value wouldn't be correct otherwise. + if (QQuickStyle::name().isEmpty() || QQuickStylePrivate::isUsingDefaultStyle()) + return QQuickStylePrivate::builtInStyles(); + return QStringList(QQuickStyle::name()); +} + +inline int runTests(QObject *testObject, int argc, char *argv[]) +{ + int res = 0; + QTest::qInit(testObject, argc, argv); + const QByteArray testObjectName = QTestResult::currentTestObjectName(); + // setCurrentTestObject() takes a C string, which means we must ensure + // that the string we pass in lives long enough (i.e until the next call + // to setCurrentTestObject()), so store the name outside of the loop. + QByteArray testName; + const QStringList styles = testStyles(); + for (const QString &style : styles) { + qmlClearTypeRegistrations(); + QQuickStyle::setStyle(style); + testName = testObjectName + "::" + style.toLocal8Bit(); + QTestResult::setCurrentTestObject(testName); + res += QTest::qRun(); + } + QTestResult::setCurrentTestObject(testObjectName); + QTest::qCleanup(); + return res; +} + +#define QTEST_QUICKCONTROLS_MAIN(TestCase) \ +int main(int argc, char *argv[]) \ +{ \ + qputenv("QML_NO_TOUCH_COMPRESSION", "1"); \ + QGuiApplication app(argc, argv); \ + TestCase tc; \ + QTEST_SET_MAIN_SOURCE_PATH \ + return runTests(&tc, argc, argv); \ +} + +#endif // QTEST_QUICKCONTROLS_P_H diff --git a/src/quickdialogs2/CMakeLists.txt b/src/quickdialogs2/CMakeLists.txt new file mode 100644 index 00000000000..88ae96331ce --- /dev/null +++ b/src/quickdialogs2/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(quickdialogs2utils) +add_subdirectory(quickdialogs2quickimpl) +add_subdirectory(quickdialogs2) diff --git a/src/quickdialogs2/quickdialogs2/CMakeLists.txt b/src/quickdialogs2/quickdialogs2/CMakeLists.txt new file mode 100644 index 00000000000..f05c4c83a9b --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/CMakeLists.txt @@ -0,0 +1,45 @@ +##################################################################### +## QuickDialogs2 Module: +##################################################################### + +qt_internal_add_qml_module(QuickDialogs2 + URI "QtQuick.Dialogs" + VERSION "${PROJECT_VERSION}" + CLASS_NAME QtQuickDialogsPlugin + PLUGIN_TARGET qtquickdialogsplugin + DEPENDENCIES + QtQuick/auto + QtQuick.Dialogs.quickimpl/auto + SOURCES + qquickabstractdialog.cpp + qquickabstractdialog_p.h + qquickfiledialog.cpp + qquickfiledialog_p.h + qquickfontdialog.cpp + qquickfontdialog_p.h + qtquickdialogs2foreign_p.h + qtquickdialogs2global_p.h + DEFINES + QT_BUILD_QUICKDIALOGS2_LIB + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_SOURCE_DIR} + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickPrivate + Qt::QuickDialogs2Utils + Qt::QuickDialogs2UtilsPrivate + Qt::QuickDialogs2QuickImpl + Qt::QuickDialogs2QuickImplPrivate + PUBLIC_LIBRARIES + Qt::Core + Qt::Gui + Qt::Quick +) + +qt_internal_add_docs(QuickDialogs2 + doc/qtquickdialogs.qdocconf +) diff --git a/src/quickdialogs2/quickdialogs2/doc/images/qtquickdialogs-filedialog-gtk.png b/src/quickdialogs2/quickdialogs2/doc/images/qtquickdialogs-filedialog-gtk.png new file mode 100644 index 00000000000..9360d747a2b Binary files /dev/null and b/src/quickdialogs2/quickdialogs2/doc/images/qtquickdialogs-filedialog-gtk.png differ diff --git a/src/quickdialogs2/quickdialogs2/doc/images/qtquickdialogs-fontdialog-gtk.png b/src/quickdialogs2/quickdialogs2/doc/images/qtquickdialogs-fontdialog-gtk.png new file mode 100644 index 00000000000..0c6217bdb43 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2/doc/images/qtquickdialogs-fontdialog-gtk.png differ diff --git a/src/quickdialogs2/quickdialogs2/doc/qtquickdialogs.qdocconf b/src/quickdialogs2/quickdialogs2/doc/qtquickdialogs.qdocconf new file mode 100644 index 00000000000..b41c30ca1d3 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/doc/qtquickdialogs.qdocconf @@ -0,0 +1,40 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) +include($QT_INSTALL_DOCS/config/exampleurl-qtquickcontrols2.qdocconf) + +project = QtQuickDialogs +description = Qt Quick Dialogs Reference Documentation +version = $QT_VERSION + +qhp.projects = QtQuickDialogs + +qhp.QtQuickDialogs.file = qtquickdialogs.qhp +qhp.QtQuickDialogs.namespace = org.qt-project.qtquickdialogs.$QT_VERSION_TAG +qhp.QtQuickDialogs.virtualFolder = qtquickdialogs +qhp.QtQuickDialogs.indexTitle = Qt Quick Dialogs +qhp.QtQuickDialogs.indexRoot = + +qhp.QtQuickDialogs.filterAttributes = qtquickdialogs $QT_VERSION qtrefdoc +qhp.QtQuickDialogs.customFilters.Qt.name = QtQuickDialogs $QT_VERSION +qhp.QtQuickDialogs.customFilters.Qt.filterAttributes = qtquickdialogs $QT_VERSION + +qhp.QtQuickDialogs.subprojects = qmltypes +qhp.QtQuickDialogs.subprojects.qmltypes.title = QML Types +qhp.QtQuickDialogs.subprojects.qmltypes.indexTitle = Qt Quick Dialogs QML Types +qhp.QtQuickDialogs.subprojects.qmltypes.selectors = qmlclass +qhp.QtQuickDialogs.subprojects.qmltypes.sortPages = true + +depends = qtcore qtgui qtdoc qtqml qtquick qtquickcontrols qtlabsplatform + +# This module has no documented C++ types, clear the module header +moduleheader = + +headerdirs += .. +sourcedirs += .. \ + src + +imagedirs += images + +navigation.landingpage = "Qt Quick Dialogs" +navigation.qmltypespage = "Qt Quick Dialogs QML Types" + +tagfile = qtquickdialogs.tags diff --git a/src/quickdialogs2/quickdialogs2/doc/src/includes/fallback.qdocinc b/src/quickdialogs2/quickdialogs2/doc/src/includes/fallback.qdocinc new file mode 100644 index 00000000000..f3a4a1805bd --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/doc/src/includes/fallback.qdocinc @@ -0,0 +1 @@ +Qt Quick Dialogs uses a Qt Quick implementation as a fallback on platforms that do not have a native implementation available. diff --git a/src/quickdialogs2/quickdialogs2/doc/src/qtquickdialogs-index.qdoc b/src/quickdialogs2/quickdialogs2/doc/src/qtquickdialogs-index.qdoc new file mode 100644 index 00000000000..92a25c3fd4a --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/doc/src/qtquickdialogs-index.qdoc @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquickdialogs-index.html + \title Qt Quick Dialogs + + \brief Provides QML types for creating and interacting with system dialogs. + + The Qt Quick Dialogs module allows to create and interact with system dialogs + from QML. The module was introduced in Qt 6.2. + + \section1 Using the Module + + The \l{Qt Quick Dialogs QML Types}{QML types} can be imported into your + application using the following import statement in your \c {.qml} file: + + \qml + import QtQuick.Dialogs + \endqml + + \section1 License and Attributions + + Qt Quick Dialogs 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. + + \section1 Reference + + \list + \li \l{Qt Quick Dialogs QML Types}{QML Types} + \endlist + + \section1 Related Modules + + \list + \li \l{Qt Quick} + \li \l{Qt Quick Controls} + \li \l{Qt Quick Templates 2} + \li \l{Qt Labs Platform} + \endlist +*/ diff --git a/src/quickdialogs2/quickdialogs2/doc/src/qtquickdialogs-qmltypes.qdoc b/src/quickdialogs2/quickdialogs2/doc/src/qtquickdialogs-qmltypes.qdoc new file mode 100644 index 00000000000..748df4ab85f --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/doc/src/qtquickdialogs-qmltypes.qdoc @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \qmlmodule QtQuick.Dialogs + \title Qt Quick Dialogs QML Types + \ingroup qmlmodules + \brief Provides QML types for creating and interacting with system dialogs. + + The Qt Quick Dialogs module allows to create and interact with system dialogs + from QML. The module was introduced in Qt 6.2. + + The QML types can be imported into your + application using the following import statement in your \c {.qml} file: + + \qml + import QtQuick.Dialogs + \endqml + + \section1 QML Types + +*/ diff --git a/src/quickdialogs2/quickdialogs2/qquickabstractdialog.cpp b/src/quickdialogs2/quickdialogs2/qquickabstractdialog.cpp new file mode 100644 index 00000000000..69a478290a5 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/qquickabstractdialog.cpp @@ -0,0 +1,458 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickabstractdialog_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuickDialogs2QuickImpl/private/qquickdialogimplfactory_p.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcDialogs, "qt.quick.dialogs") + +/*! + \internal + + A dialog that can be backed by different implementations. + + Each dialog has a handle to QPlatformDialogHelper, which is created in create(). + The helper acts as an intermediary between the QML-facing dialog object + and the native/widget/quick implementation: + + +------------+ +------------------------------------+ +-------------------------------------+ + | | | | | | + | FileDialog |----->| Native/Widget/Quick QPlatformFile- |----->| Native OS dialog/QQuickFileDialog/ | + | | | DialogHelper subclass | | QQuickFileDialogImpl | + | | | | | | + +------------+ +------------------------------------+ +-------------------------------------+ +*/ + +/*! + \qmltype Dialog + \inherits QtObject +//! \instantiates QQuickAbstractDialog + \inqmlmodule QtQuick.Dialogs + \since 6.2 + \brief The base class of native dialogs. + + The Dialog type provides common QML API for native platform dialogs. + For the non-native dialog, see \l [QML QtQuickControls]{Dialog}. + + To show a native dialog, construct an instance of one of the concrete + Dialog implementations, set the desired properties, and call \l open(). + Dialog emits \l accepted() or \l rejected() when the user is done with + the dialog. +*/ + +/*! + \qmlsignal void QtQuick.Dialogs::Dialog::accepted() + + This signal is emitted when the dialog has been accepted either + interactively or by calling \l accept(). + + \sa rejected() +*/ + +/*! + \qmlsignal void QtQuick.Dialogs::Dialog::rejected() + + This signal is emitted when the dialog has been rejected either + interactively or by calling \l reject(). + + This signal is also emitted when closing the dialog with \l close(). + + \sa accepted() +*/ + +Q_DECLARE_LOGGING_CATEGORY(lcDialogs) + +QQuickAbstractDialog::QQuickAbstractDialog(QPlatformTheme::DialogType type, QObject *parent) + : QObject(parent), + m_type(type) +{ +} + +QQuickAbstractDialog::~QQuickAbstractDialog() +{ + destroy(); +} + +QPlatformDialogHelper *QQuickAbstractDialog::handle() const +{ + return m_handle.get(); +} + +/*! + \qmldefault + \qmlproperty list<Object> QtQuick.Dialogs::Dialog::data + + This default property holds the list of all objects declared as children of + the dialog. +*/ +QQmlListProperty<QObject> QQuickAbstractDialog::data() +{ + return QQmlListProperty<QObject>(this, &m_data); +} + +/*! + \qmlproperty Window QtQuick.Dialogs::Dialog::parentWindow + + This property holds the parent window of the dialog. + + Unless explicitly set, the window is automatically resolved by iterating + the QML parent objects until a \l Window or an \l Item that has a window + is found. +*/ +QWindow *QQuickAbstractDialog::parentWindow() const +{ + return m_parentWindow; +} + +void QQuickAbstractDialog::setParentWindow(QWindow *window) +{ + qCDebug(lcDialogs) << "set parent window to" << window; + if (m_parentWindow == window) + return; + + m_parentWindow = window; + emit parentWindowChanged(); +} + +/*! + \qmlproperty string QtQuick.Dialogs::Dialog::title + + This property holds the title of the dialog. +*/ +QString QQuickAbstractDialog::title() const +{ + return m_title; +} + +void QQuickAbstractDialog::setTitle(const QString &title) +{ + if (m_title == title) + return; + + m_title = title; + emit titleChanged(); +} + +/*! + \qmlproperty Qt::WindowFlags QtQuick.Dialogs::Dialog::flags + + This property holds the window flags of the dialog. The default value is \c Qt.Dialog. +*/ +Qt::WindowFlags QQuickAbstractDialog::flags() const +{ + return m_flags; +} + +void QQuickAbstractDialog::setFlags(Qt::WindowFlags flags) +{ + if (m_flags == flags) + return; + + m_flags = flags; + emit flagsChanged(); +} + +/*! + \qmlproperty Qt::WindowModality QtQuick.Dialogs::Dialog::modality + + This property holds the modality of the dialog. The default value is \c Qt.WindowModal. + + Available values: + \value Qt.NonModal The dialog is not modal and does not block input to other windows. + \value Qt.WindowModal The dialog is modal to a single window hierarchy and blocks input to its parent window, all grandparent windows, and all siblings of its parent and grandparent windows. + \value Qt.ApplicationModal The dialog is modal to the application and blocks input to all windows. +*/ +Qt::WindowModality QQuickAbstractDialog::modality() const +{ + return m_modality; +} + +void QQuickAbstractDialog::setModality(Qt::WindowModality modality) +{ + if (m_modality == modality) + return; + + m_modality = modality; + emit modalityChanged(); +} + +/*! + \qmlproperty bool QtQuick.Dialogs::Dialog::visible + + This property holds the visibility of the dialog. The default value is \c false. + + \sa open(), close() +*/ +bool QQuickAbstractDialog::isVisible() const +{ + return m_handle && m_visible; +} + +void QQuickAbstractDialog::setVisible(bool visible) +{ + qCDebug(lcDialogs) << "setVisible called with" << visible; + + if (visible) { + // Don't try to open before component completion, as we won't have a window yet, + // and open() sets m_visible to false if it fails. + if (!m_complete) + m_visibleRequested = true; + else + open(); + } else { + close(); + } +} + +/*! + \qmlproperty StandardCode QtQuick.Dialogs::Dialog::result + + This property holds the result code. + + Standard result codes: + \value Dialog.Accepted + \value Dialog.Rejected + + \note MessageDialog sets the result to the value of the clicked standard + button instead of using the standard result codes. +*/ +QQuickAbstractDialog::StandardCode QQuickAbstractDialog::result() const +{ + return m_result; +} + +void QQuickAbstractDialog::setResult(StandardCode result) +{ + if (m_result == result) + return; + + m_result = result; + emit resultChanged(); +} + +/*! + \qmlmethod void QtQuick.Dialogs::Dialog::open() + + Opens the dialog. + + \sa visible, close() +*/ +void QQuickAbstractDialog::open() +{ + qCDebug(lcDialogs) << "open called"; + if (m_visible || !create()) + return; + + onShow(m_handle.get()); + m_visible = m_handle->show(m_flags, m_modality, m_parentWindow); + if (m_visible) { + m_result = Rejected; // in case an accepted dialog gets re-opened, then closed + emit visibleChanged(); + } +} + +/*! + \qmlmethod void QtQuick.Dialogs::Dialog::close() + + Closes the dialog and emits either the \l accepted() or \l rejected() + signal. + + \sa visible, open() +*/ +void QQuickAbstractDialog::close() +{ + if (!m_handle || !m_visible) + return; + + onHide(m_handle.get()); + m_handle->hide(); + m_visible = false; + emit visibleChanged(); + + if (m_result == Accepted) + emit accepted(); + else // if (m_result == Rejected) + emit rejected(); +} + +/*! + \qmlmethod void QtQuick.Dialogs::Dialog::accept() + + Closes the dialog and emits the \l accepted() signal. + + \sa reject() +*/ +void QQuickAbstractDialog::accept() +{ + done(Accepted); +} + +/*! + \qmlmethod void QtQuick.Dialogs::Dialog::reject() + + Closes the dialog and emits the \l rejected() signal. + + \sa accept() +*/ +void QQuickAbstractDialog::reject() +{ + done(Rejected); +} + +/*! + \qmlmethod void QtQuick.Dialogs::Dialog::done(StandardCode result) + + Closes the dialog and sets the \a result. + + \sa accept(), reject(), result +*/ +void QQuickAbstractDialog::done(StandardCode result) +{ + setResult(result); + close(); +} + +void QQuickAbstractDialog::classBegin() +{ +} + +void QQuickAbstractDialog::componentComplete() +{ + qCDebug(lcDialogs) << "componentComplete"; + m_complete = true; + + if (!m_parentWindow) { + qCDebug(lcDialogs) << "- no parent window; searching for one"; + setParentWindow(findParentWindow()); + } + + if (m_visibleRequested) { + qCDebug(lcDialogs) << "visible was bound to true before component completion; opening dialog"; + open(); + m_visibleRequested = false; + } +} + +static const char *qmlTypeName(const QObject *object) +{ + return object->metaObject()->className() + qstrlen("QQuickPlatform"); +} + +bool QQuickAbstractDialog::create() +{ + qCDebug(lcDialogs) << qmlTypeName(this) << "attempting to create dialog backend of type" + << m_type << "with parent window" << m_parentWindow; + if (m_handle) + return m_handle.get(); + + qCDebug(lcDialogs) << "- attempting to create a native dialog"; + if (useNativeDialog()) + m_handle.reset(QGuiApplicationPrivate::platformTheme()->createPlatformDialogHelper(m_type)); + + if (!m_handle) { + qCDebug(lcDialogs) << "- attempting to create a quick dialog"; + m_handle.reset(QQuickDialogImplFactory::createPlatformDialogHelper(m_type, this)); + } + + qCDebug(lcDialogs) << qmlTypeName(this) << "created ->" << m_handle.get(); + if (m_handle) { + onCreate(m_handle.get()); + connect(m_handle.get(), &QPlatformDialogHelper::accept, this, &QQuickAbstractDialog::accept); + connect(m_handle.get(), &QPlatformDialogHelper::reject, this, &QQuickAbstractDialog::reject); + } + return m_handle.get(); +} + +void QQuickAbstractDialog::destroy() +{ + m_handle.reset(); +} + +bool QQuickAbstractDialog::useNativeDialog() const +{ + if (QCoreApplication::testAttribute(Qt::AA_DontUseNativeDialogs)) { + qCDebug(lcDialogs) << " - Qt::AA_DontUseNativeDialogs was set; not using native dialog"; + return false; + } + + if (!QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(m_type)) { + qCDebug(lcDialogs) << " - the platform theme told us a native dialog isn't available; not using native dialog"; + return false; + } + + return true; +} + +void QQuickAbstractDialog::onCreate(QPlatformDialogHelper *dialog) +{ + Q_UNUSED(dialog); +} + +void QQuickAbstractDialog::onShow(QPlatformDialogHelper *dialog) +{ + Q_UNUSED(dialog); +} + +void QQuickAbstractDialog::onHide(QPlatformDialogHelper *dialog) +{ + Q_UNUSED(dialog); +} + +QWindow *QQuickAbstractDialog::findParentWindow() const +{ + QObject *obj = parent(); + while (obj) { + QWindow *window = qobject_cast<QWindow *>(obj); + if (window) + return window; + QQuickItem *item = qobject_cast<QQuickItem *>(obj); + if (item && item->window()) + return item->window(); + obj = obj->parent(); + } + return nullptr; +} + +QT_END_NAMESPACE + +#include "moc_qquickabstractdialog_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2/qquickabstractdialog_p.h b/src/quickdialogs2/quickdialogs2/qquickabstractdialog_p.h new file mode 100644 index 00000000000..07e9ffbf5ae --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/qquickabstractdialog_p.h @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKABSTRACTDIALOG_P_H +#define QQUICKABSTRACTDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <memory> + +#include <QtCore/qobject.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtGui/qpa/qplatformdialoghelper.h> +#include <QtQml/qqmlparserstatus.h> +#include <QtQml/qqmllist.h> +#include <QtQml/qqml.h> + +#include "qtquickdialogs2global_p.h" + +QT_BEGIN_NAMESPACE + +class QWindow; +class QPlatformDialogHelper; + +class Q_QUICKDIALOGS2_PRIVATE_EXPORT QQuickAbstractDialog : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + Q_PROPERTY(QQmlListProperty<QObject> data READ data FINAL) + Q_PROPERTY(QWindow *parentWindow READ parentWindow WRITE setParentWindow NOTIFY parentWindowChanged FINAL) + Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL) + Q_PROPERTY(Qt::WindowFlags flags READ flags WRITE setFlags NOTIFY flagsChanged FINAL) + Q_PROPERTY(Qt::WindowModality modality READ modality WRITE setModality NOTIFY modalityChanged FINAL) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL) + Q_PROPERTY(StandardCode result READ result WRITE setResult NOTIFY resultChanged FINAL) + Q_CLASSINFO("DefaultProperty", "data") + Q_MOC_INCLUDE(<QtGui/qwindow.h>) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(6, 2) + +public: + explicit QQuickAbstractDialog(QPlatformTheme::DialogType type, QObject *parent = nullptr); + ~QQuickAbstractDialog(); + + QPlatformDialogHelper *handle() const; + + QQmlListProperty<QObject> data(); + + QWindow *parentWindow() const; + void setParentWindow(QWindow *window); + + QString title() const; + void setTitle(const QString &title); + + Qt::WindowFlags flags() const; + void setFlags(Qt::WindowFlags flags); + + Qt::WindowModality modality() const; + void setModality(Qt::WindowModality modality); + + bool isVisible() const; + void setVisible(bool visible); + + enum StandardCode { Rejected, Accepted }; + Q_ENUM(StandardCode) + + StandardCode result() const; + void setResult(StandardCode result); + +public Q_SLOTS: + void open(); + void close(); + virtual void accept(); + virtual void reject(); + virtual void done(StandardCode result); + +Q_SIGNALS: + void accepted(); + void rejected(); + void parentWindowChanged(); + void titleChanged(); + void flagsChanged(); + void modalityChanged(); + void visibleChanged(); + void resultChanged(); + +protected: + void classBegin() override; + void componentComplete() override; + + bool create(); + void destroy(); + + virtual bool useNativeDialog() const; + virtual void onCreate(QPlatformDialogHelper *dialog); + virtual void onShow(QPlatformDialogHelper *dialog); + virtual void onHide(QPlatformDialogHelper *dialog); + + QWindow *findParentWindow() const; + +private: + bool m_visibleRequested = false; + bool m_visible = false; + bool m_complete = false; + StandardCode m_result = Rejected; + QWindow *m_parentWindow = nullptr; + QString m_title; + Qt::WindowFlags m_flags = Qt::Dialog; + Qt::WindowModality m_modality = Qt::WindowModal; + QPlatformTheme::DialogType m_type; + QList<QObject *> m_data; + std::unique_ptr<QPlatformDialogHelper> m_handle; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickAbstractDialog) + +#endif // QQUICKABSTRACTDIALOG_P_H diff --git a/src/quickdialogs2/quickdialogs2/qquickfiledialog.cpp b/src/quickdialogs2/quickdialogs2/qquickfiledialog.cpp new file mode 100644 index 00000000000..b14492a6ce4 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/qquickfiledialog.cpp @@ -0,0 +1,622 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfiledialog_p.h" + +#include <QtCore/qlist.h> +#include <QtCore/qloggingcategory.h> +#include <QtQml/qqmlfile.h> + +#include <QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcFileDialog, "qt.quick.dialogs.filedialog") + +/*! + \qmltype FileDialog + \inherits Dialog +//! \instantiates QQuickFileDialog + \inqmlmodule QtQuick.Dialogs + \since 6.2 + \brief A file dialog. + + The FileDialog type provides a QML API for file dialogs. + + \image qtquickdialogs-filedialog-gtk.png + + To show a file dialog, construct an instance of FileDialog, set the + desired properties, and call \l {Dialog::}{open()}. The \l currentFile + or \l currentFiles properties can be used to determine the currently + selected file(s) in the dialog. The \l selectedFile and \l selectedFiles + properties are updated only after the final selection has been made by + accepting the dialog. + + \code + MenuItem { + text: "Open..." + onTriggered: fileDialog.open() + } + + FileDialog { + id: fileDialog + currentFile: document.source + folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) + } + + MyDocument { + id: document + source: fileDialog.file + } + \endcode + + \section2 Availability + + A native platform file dialog is currently available on the following platforms: + + \list + \li iOS + \li Android + \li Linux (when running with the GTK+ platform theme) + \li macOS + \li Windows + \endlist + + \include includes/fallback.qdocinc + + //! \sa FolderDialog, StandardPaths +*/ + +Q_DECLARE_LOGGING_CATEGORY(lcDialogs) + +QQuickFileDialog::QQuickFileDialog(QObject *parent) + : QQuickAbstractDialog(QPlatformTheme::FileDialog, parent), + m_fileMode(OpenFile), + m_options(QFileDialogOptions::create()), + m_selectedNameFilter(nullptr) +{ + m_options->setFileMode(QFileDialogOptions::ExistingFile); + m_options->setAcceptMode(QFileDialogOptions::AcceptOpen); +} + +/*! + \qmlproperty enumeration QtQuick.Dialogs::FileDialog::fileMode + + This property holds the mode of the dialog. + + Available values: + \value FileDialog.OpenFile The dialog is used to select an existing file (default). + \value FileDialog.OpenFiles The dialog is used to select multiple existing files. + \value FileDialog.SaveFile The dialog is used to select any file. The file does not have to exist. +*/ +QQuickFileDialog::FileMode QQuickFileDialog::fileMode() const +{ + return m_fileMode; +} + +void QQuickFileDialog::setFileMode(FileMode mode) +{ + qCDebug(lcFileDialog) << "setFileMode called with" << mode; + if (mode == m_fileMode) + return; + + switch (mode) { + case OpenFile: + m_options->setFileMode(QFileDialogOptions::ExistingFile); + m_options->setAcceptMode(QFileDialogOptions::AcceptOpen); + break; + case OpenFiles: + m_options->setFileMode(QFileDialogOptions::ExistingFiles); + m_options->setAcceptMode(QFileDialogOptions::AcceptOpen); + break; + case SaveFile: + m_options->setFileMode(QFileDialogOptions::AnyFile); + m_options->setAcceptMode(QFileDialogOptions::AcceptSave); + break; + default: + break; + } + + m_fileMode = mode; + emit fileModeChanged(); +} + +/*! + \qmlproperty url QtQuick.Dialogs::FileDialog::selectedFile + \readonly + + This property holds the final accepted file. + + If there are multiple selected files, this property refers to the first + file. + + Unlike the \l currentFile property, the \c selectedFile property is not + updated while the user is selecting files in the dialog, but only after the + final selection has been made. That is, when the user has clicked + \uicontrol OK to accept a file. Alternatively, the + \l {Dialog::}{accepted()} signal can be handled to get the final selection. + + \sa selectedFiles, currentFile, {Dialog::}{accepted()}, currentFolder +*/ +QUrl QQuickFileDialog::selectedFile() const +{ + return addDefaultSuffix(m_selectedFiles.value(0)); +} + +/*! + \qmlproperty list<url> QtQuick.Dialogs::FileDialog::selectedFiles + + This property holds the final accepted files. + + Unlike the \l currentFiles property, the \c selectedFiles property is not + updated while the user is selecting files in the dialog, but only after the + final selection has been made. That is, when the user has clicked + \uicontrol OK to accept files. Alternatively, the \l {Dialog::}{accepted()} + signal can be handled to get the final selection. + + \sa currentFiles, {Dialog::}{accepted()}, currentFolder +*/ +QList<QUrl> QQuickFileDialog::selectedFiles() const +{ + return addDefaultSuffixes(m_selectedFiles); +} + +void QQuickFileDialog::setSelectedFiles(const QList<QUrl> &selectedFiles) +{ + if (m_selectedFiles == selectedFiles) + return; + + bool firstChanged = m_selectedFiles.value(0) != selectedFiles.value(0); + m_selectedFiles = selectedFiles; + if (firstChanged) + emit selectedFileChanged(); + emit selectedFilesChanged(); +} + +/*! + \qmlproperty url QtQuick.Dialogs::FileDialog::currentFile + + This property holds the currently selected file in the dialog. + + Unlike the \l selectedFile property, the \c currentFile property is updated + while the user is selecting files in the dialog, even before the final + selection has been made. + + \sa selectedFile, currentFiles, currentFolder +*/ +QUrl QQuickFileDialog::currentFile() const +{ + return currentFiles().value(0); +} + +void QQuickFileDialog::setCurrentFile(const QUrl &file) +{ + setCurrentFiles(QList<QUrl>() << file); +} + +/*! + \qmlproperty list<url> QtQuick.Dialogs::FileDialog::currentFiles + + This property holds the currently selected files in the dialog. + + Unlike the \l selectedFiles property, the \c currentFiles property is + updated while the user is selecting files in the dialog, even before the + final selection has been made. + + \sa selectedFiles, currentFile, currentFolder +*/ +QList<QUrl> QQuickFileDialog::currentFiles() const +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(handle())) + return fileDialog->selectedFiles(); + return m_options->initiallySelectedFiles(); +} + +void QQuickFileDialog::setCurrentFiles(const QList<QUrl> ¤tFiles) +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(handle())) { + for (const QUrl &file : currentFiles) + fileDialog->selectFile(file); + } + m_options->setInitiallySelectedFiles(currentFiles); +} + +/*! + \qmlproperty url QtQuick.Dialogs::FileDialog::currentFolder + + This property holds the folder where files are selected. It can be set to + control the initial directory that is shown when the dialog is opened. + +\omit + For selecting a folder, use FolderDialog instead. + + \sa FolderDialog +\endomit +*/ +QUrl QQuickFileDialog::currentFolder() const +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(handle())) + return fileDialog->directory(); + + // If we're not using a native file dialog and the folder is invalid, + // return the current directory. + if (!m_options->initialDirectory().isValid()) + return QUrl::fromLocalFile(QDir::currentPath()); + + return m_options->initialDirectory(); +} + +void QQuickFileDialog::setCurrentFolder(const QUrl ¤tFolder) +{ + qCDebug(lcFileDialog) << "setCurrentFolder called with" << currentFolder; + if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(handle())) + fileDialog->setDirectory(currentFolder); + m_options->setInitialDirectory(currentFolder); +} + +/*! + \qmlproperty flags QtQuick.Dialogs::FileDialog::options + + This property holds the various options that affect the look and feel of the dialog. + + By default, all options are disabled. + + Options should be set before showing the dialog. Setting them while the dialog is + visible is not guaranteed to have an immediate effect on the dialog (depending on + the option and on the platform). + + Available options: + \value FileDialog.DontResolveSymlinks Don't resolve symlinks in the file dialog. By default symlinks are resolved. + \value FileDialog.DontConfirmOverwrite Don't ask for confirmation if an existing file is selected. By default confirmation is requested. + \value FileDialog.ReadOnly Indicates that the dialog doesn't allow creating directories. + \value FileDialog.HideNameFilterDetails Indicates if the file name filter details are hidden or not. +*/ +QFileDialogOptions::FileDialogOptions QQuickFileDialog::options() const +{ + return m_options->options(); +} + +void QQuickFileDialog::setOptions(QFileDialogOptions::FileDialogOptions options) +{ + if (options == m_options->options()) + return; + + m_options->setOptions(options); + emit optionsChanged(); +} + +void QQuickFileDialog::resetOptions() +{ + setOptions({}); +} + +/*! + \qmlproperty list<string> QtQuick.Dialogs::FileDialog::nameFilters + + This property holds the filters that restrict the types of files that + can be selected. + + \code + FileDialog { + nameFilters: ["Text files (*.txt)", "HTML files (*.html *.htm)"] + } + \endcode + + Different platforms may restrict the files that can be selected in + different ways. For example, macOS will disable file entries that do not + match the filters, whereas Windows will hide them. + + \note \b{*.*} is not a portable filter, because the historical assumption + that the file extension determines the file type is not consistent on every + operating system. It is possible to have a file with no dot in its name (for + example, \c Makefile). In a native Windows file dialog, \b{*.*} will match + such files, while in other types of file dialogs it may not. So it is better + to use \b{*} if you mean to select any file. + + \sa selectedNameFilter +*/ +QStringList QQuickFileDialog::nameFilters() const +{ + return m_options->nameFilters(); +} + +void QQuickFileDialog::setNameFilters(const QStringList &filters) +{ + qCDebug(lcFileDialog).nospace() << "setNameFilters called with " << filters + << " (old filters were: " << m_options->nameFilters() << ")"; + if (filters == m_options->nameFilters()) + return; + + m_options->setNameFilters(filters); + if (m_selectedNameFilter) { + int index = m_selectedNameFilter->index(); + if (index < 0 || index >= filters.count()) + index = 0; + m_selectedNameFilter->update(filters.value(index)); + } + emit nameFiltersChanged(); +} + +void QQuickFileDialog::resetNameFilters() +{ + setNameFilters(QStringList()); +} + +/*! + \qmlproperty int QtQuick.Dialogs::FileDialog::selectedNameFilter.index + \qmlproperty string QtQuick.Dialogs::FileDialog::selectedNameFilter.name + \qmlproperty list<string> QtQuick.Dialogs::FileDialog::selectedNameFilter.extensions + \qmlproperty list<string> QtQuick.Dialogs::FileDialog::selectedNameFilter.globs + + These properties hold the currently selected name filter. + + \table + \header + \li Name + \li Description + \row + \li \b index : int + \li This property determines which \l {nameFilters}{name filter} is selected. + The specified filter is selected when the dialog is opened. The value is + updated when the user selects another filter. + \row + \li [read-only] \b name : string + \li This property holds the name of the selected filter. In the + example below, the name of the first filter is \c {"Text files"} + and the second is \c {"HTML files"}. + \row + \li [read-only] \b extensions : list<string> + \li This property holds the list of extensions of the selected filter. + In the example below, the list of extensions of the first filter is + \c {["txt"]} and the second is \c {["html", "htm"]}. + \row + \li [read-only] \b globs : list<string> + \li This property holds the list of globs of the selected filter. + In the example below, the list of globs of the first filter is + \c {["*.txt"]} and the second is \c {["*.html", "*.htm"]}. + + This property is useful in conjunction with \l {FolderListModel}'s + \l {FolderListModel::}{nameFilters} property, for example. + \endtable + + \code + FileDialog { + id: fileDialog + selectedNameFilter.index: 1 + nameFilters: ["Text files (*.txt)", "HTML files (*.html *.htm)"] + } + + MyDocument { + id: document + fileType: fileDialog.selectedNameFilter.extensions[0] + } + \endcode + + \sa nameFilters +*/ +QQuickFileNameFilter *QQuickFileDialog::selectedNameFilter() const +{ + if (!m_selectedNameFilter) { + QQuickFileDialog *that = const_cast<QQuickFileDialog *>(this); + m_selectedNameFilter = new QQuickFileNameFilter(that); + m_selectedNameFilter->setOptions(m_options); + } + return m_selectedNameFilter; +} + +/*! + \qmlproperty string QtQuick.Dialogs::FileDialog::defaultSuffix + + This property holds a suffix that is added to selected files that have + no suffix specified. The suffix is typically used to indicate the file + type (e.g. "txt" indicates a text file). + + If the first character is a dot ('.'), it is removed. +*/ +QString QQuickFileDialog::defaultSuffix() const +{ + return m_options->defaultSuffix(); +} + +void QQuickFileDialog::setDefaultSuffix(const QString &suffix) +{ + if (suffix == m_options->defaultSuffix()) + return; + + m_options->setDefaultSuffix(suffix); + emit defaultSuffixChanged(); +} + +void QQuickFileDialog::resetDefaultSuffix() +{ + setDefaultSuffix(QString()); +} + +/*! + \qmlproperty string QtQuick.Dialogs::FileDialog::acceptLabel + + This property holds the label text shown on the button that accepts the dialog. + + When set to an empty string, the default label of the underlying platform is used. + The default label is typically \uicontrol Open or \uicontrol Save depending on which + \l fileMode the dialog is used in. + + The default value is an empty string. + + \sa rejectLabel +*/ +QString QQuickFileDialog::acceptLabel() const +{ + return m_options->labelText(QFileDialogOptions::Accept); +} + +void QQuickFileDialog::setAcceptLabel(const QString &label) +{ + if (label == m_options->labelText(QFileDialogOptions::Accept)) + return; + + m_options->setLabelText(QFileDialogOptions::Accept, label); + emit acceptLabelChanged(); +} + +void QQuickFileDialog::resetAcceptLabel() +{ + setAcceptLabel(QString()); +} + +/*! + \qmlproperty string QtQuick.Dialogs::FileDialog::rejectLabel + + This property holds the label text shown on the button that rejects the dialog. + + When set to an empty string, the default label of the underlying platform is used. + The default label is typically \uicontrol Cancel. + + The default value is an empty string. + + \sa acceptLabel +*/ +QString QQuickFileDialog::rejectLabel() const +{ + return m_options->labelText(QFileDialogOptions::Reject); +} + +void QQuickFileDialog::setRejectLabel(const QString &label) +{ + if (label == m_options->labelText(QFileDialogOptions::Reject)) + return; + + m_options->setLabelText(QFileDialogOptions::Reject, label); + emit rejectLabelChanged(); +} + +void QQuickFileDialog::resetRejectLabel() +{ + setRejectLabel(QString()); +} + +bool QQuickFileDialog::useNativeDialog() const +{ + if (!QQuickAbstractDialog::useNativeDialog()) + return false; + + if (m_options->testOption(QFileDialogOptions::DontUseNativeDialog)) { + qCDebug(lcDialogs) << " - the FileDialog was told not to use a native dialog; not using native dialog"; + return false; + } + + return true; +} + +void QQuickFileDialog::onCreate(QPlatformDialogHelper *dialog) +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(dialog)) { + connect(fileDialog, &QPlatformFileDialogHelper::currentChanged, this, &QQuickFileDialog::currentFileChanged); + connect(fileDialog, &QPlatformFileDialogHelper::currentChanged, this, &QQuickFileDialog::currentFilesChanged); + connect(fileDialog, &QPlatformFileDialogHelper::directoryEntered, this, &QQuickFileDialog::currentFolderChanged); + fileDialog->setOptions(m_options); + } +} + +void QQuickFileDialog::onShow(QPlatformDialogHelper *dialog) +{ + m_options->setWindowTitle(title()); + if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(dialog)) { + // Ensure that a name filter is always selected. + int index = selectedNameFilter()->index(); + if (index == -1) + index = 0; + const QString filter = m_options->nameFilters().value(index); + m_options->setInitiallySelectedNameFilter(filter); + + fileDialog->setOptions(m_options); // setOptions only assigns a member and isn't virtual + + connect(fileDialog, &QPlatformFileDialogHelper::filterSelected, m_selectedNameFilter, &QQuickFileNameFilter::update); + fileDialog->selectNameFilter(filter); + + const QUrl initialDir = m_options->initialDirectory(); + // If it's not valid, or it's a file and not a directory, we shouldn't set it. + if (m_firstShow && initialDir.isValid() && QDir(QQmlFile::urlToLocalFileOrQrc(initialDir)).exists()) + fileDialog->setDirectory(m_options->initialDirectory()); + } + if (m_firstShow) + m_firstShow = false; +} + +void QQuickFileDialog::onHide(QPlatformDialogHelper *dialog) +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(dialog)) { + if (m_selectedNameFilter) + disconnect(fileDialog, &QPlatformFileDialogHelper::filterSelected, m_selectedNameFilter, &QQuickFileNameFilter::update); + } +} + +void QQuickFileDialog::accept() +{ + if (QPlatformFileDialogHelper *fileDialog = qobject_cast<QPlatformFileDialogHelper *>(handle())) { + // Take the currently selected files and make them the final set of files. + setSelectedFiles(fileDialog->selectedFiles()); + } + QQuickAbstractDialog::accept(); +} + +QUrl QQuickFileDialog::addDefaultSuffix(const QUrl &file) const +{ + QUrl url = file; + const QString path = url.path(); + const QString suffix = m_options->defaultSuffix(); + // Urls with "content" scheme do not require suffixes. Such schemes are + // used on Android. + const bool isContentScheme = url.scheme() == u"content"_qs; + if (!isContentScheme && !suffix.isEmpty() && !path.endsWith(QLatin1Char('/')) + && path.lastIndexOf(QLatin1Char('.')) == -1) { + url.setPath(path + QLatin1Char('.') + suffix); + } + return url; +} + +QList<QUrl> QQuickFileDialog::addDefaultSuffixes(const QList<QUrl> &files) const +{ + QList<QUrl> urls; + urls.reserve(files.size()); + for (const QUrl &file : files) + urls += addDefaultSuffix(file); + return urls; +} + +QT_END_NAMESPACE + +#include "moc_qquickfiledialog_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2/qquickfiledialog_p.h b/src/quickdialogs2/quickdialogs2/qquickfiledialog_p.h new file mode 100644 index 00000000000..0dccbe727cc --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/qquickfiledialog_p.h @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFILEDIALOG_P_H +#define QQUICKFILEDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qurl.h> +#include <QtQml/qqml.h> + +#include "qquickabstractdialog_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFileNameFilter; + +class Q_QUICKDIALOGS2_PRIVATE_EXPORT QQuickFileDialog : public QQuickAbstractDialog +{ + Q_OBJECT + Q_PROPERTY(FileMode fileMode READ fileMode WRITE setFileMode NOTIFY fileModeChanged FINAL) + Q_PROPERTY(QUrl selectedFile READ selectedFile NOTIFY selectedFileChanged FINAL) + Q_PROPERTY(QList<QUrl> selectedFiles READ selectedFiles NOTIFY selectedFilesChanged FINAL) + Q_PROPERTY(QUrl currentFile READ currentFile WRITE setCurrentFile NOTIFY currentFileChanged FINAL) + Q_PROPERTY(QList<QUrl> currentFiles READ currentFiles WRITE setCurrentFiles NOTIFY currentFilesChanged FINAL) + Q_PROPERTY(QUrl currentFolder READ currentFolder WRITE setCurrentFolder NOTIFY currentFolderChanged FINAL) + Q_PROPERTY(QFileDialogOptions::FileDialogOptions options READ options WRITE setOptions RESET resetOptions NOTIFY optionsChanged FINAL) + Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters RESET resetNameFilters NOTIFY nameFiltersChanged FINAL) + Q_PROPERTY(QQuickFileNameFilter *selectedNameFilter READ selectedNameFilter CONSTANT) + Q_PROPERTY(QString defaultSuffix READ defaultSuffix WRITE setDefaultSuffix RESET resetDefaultSuffix NOTIFY defaultSuffixChanged FINAL) + Q_PROPERTY(QString acceptLabel READ acceptLabel WRITE setAcceptLabel RESET resetAcceptLabel NOTIFY acceptLabelChanged FINAL) + Q_PROPERTY(QString rejectLabel READ rejectLabel WRITE setRejectLabel RESET resetRejectLabel NOTIFY rejectLabelChanged FINAL) + Q_FLAGS(QFileDialogOptions::FileDialogOptions) + QML_NAMED_ELEMENT(FileDialog) + QML_ADDED_IN_VERSION(6, 2) + Q_MOC_INCLUDE(<QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h>) + +public: + explicit QQuickFileDialog(QObject *parent = nullptr); + + enum FileMode { + OpenFile, + OpenFiles, + SaveFile + }; + Q_ENUM(FileMode) + + FileMode fileMode() const; + void setFileMode(FileMode fileMode); + + QUrl selectedFile() const; + + QList<QUrl> selectedFiles() const; + + QUrl currentFile() const; + void setCurrentFile(const QUrl &file); + + QList<QUrl> currentFiles() const; + void setCurrentFiles(const QList<QUrl> ¤tFiles); + + QUrl currentFolder() const; + void setCurrentFolder(const QUrl ¤tFolder); + + QFileDialogOptions::FileDialogOptions options() const; + void setOptions(QFileDialogOptions::FileDialogOptions options); + void resetOptions(); + + QStringList nameFilters() const; + void setNameFilters(const QStringList &filters); + void resetNameFilters(); + + QQuickFileNameFilter *selectedNameFilter() const; + + QString defaultSuffix() const; + void setDefaultSuffix(const QString &suffix); + void resetDefaultSuffix(); + + QString acceptLabel() const; + void setAcceptLabel(const QString &label); + void resetAcceptLabel(); + + QString rejectLabel() const; + void setRejectLabel(const QString &label); + void resetRejectLabel(); + +Q_SIGNALS: + void fileModeChanged(); + void selectedFileChanged(); + void selectedFilesChanged(); + void currentFileChanged(); + void currentFilesChanged(); + void currentFolderChanged(); + void optionsChanged(); + void nameFiltersChanged(); + void defaultSuffixChanged(); + void acceptLabelChanged(); + void rejectLabelChanged(); + +protected: + bool useNativeDialog() const override; + void onCreate(QPlatformDialogHelper *dialog) override; + void onShow(QPlatformDialogHelper *dialog) override; + void onHide(QPlatformDialogHelper *dialog) override; + void accept() override; + +private: + QUrl addDefaultSuffix(const QUrl &file) const; + QList<QUrl> addDefaultSuffixes(const QList<QUrl> &files) const; + + void setSelectedFiles(const QList<QUrl> &selectedFiles); + + FileMode m_fileMode; + QList<QUrl> m_selectedFiles; + bool m_firstShow = true; + QSharedPointer<QFileDialogOptions> m_options; + mutable QQuickFileNameFilter *m_selectedNameFilter; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFileDialog) + +#endif // QQUICKFILEDIALOG_P_H diff --git a/src/quickdialogs2/quickdialogs2/qquickfontdialog.cpp b/src/quickdialogs2/quickdialogs2/qquickfontdialog.cpp new file mode 100644 index 00000000000..9472259dae3 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/qquickfontdialog.cpp @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFONTDIALOG_CPP +#define QQUICKFONTDIALOG_CPP + +#include "qquickfontdialog_p.h" + +#include <QtCore/qloggingcategory.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype FontDialog + \inherits Dialog +//! \instantiates QQuickFontDialog + \inqmlmodule QtQuick.Dialogs + \since 6.2 + \brief A font dialog. + + The FontDialog type provides a QML API for font dialogs. + + \image qtquickdialogs-fontdialog-gtk.png + + To show a font dialog, construct an instance of FontDialog, set the + desired properties, and call \l {Dialog::}{open()}. The \l currentFont + property can be used to determine the currently selected font in the + dialog. The \l selectedFont property is updated only after the final selection + has been made by accepting the dialog. + + \code + MenuItem { + text: "Font" + onTriggered: fontDialog.open() + } + + FontDialog { + id: fontDialog + currentFont.family: document.font + } + + MyDocument { + id: document + font: fontDialog.selectedFont + } + \endcode + + \section2 Availability + + A native platform font dialog is currently available on the following platforms: + + \list + \li macOS + \li Linux (when running with the GTK+ platform theme) + \endlist + + \include includes/fallback.qdocinc +*/ + +Q_LOGGING_CATEGORY(lcFontDialog, "qt.quick.dialogs.fontdialog") + +QQuickFontDialog::QQuickFontDialog(QObject *parent) + : QQuickAbstractDialog(QPlatformTheme::FontDialog, parent), + m_options(QFontDialogOptions::create()) +{ +} + +/*! + \qmlproperty font QtQuick.Dialogs::FontDialog::currentFont + + This property holds the currently selected font in the dialog. + + Unlike the \l selectedFont property, the \c currentFont property is updated + while the user is selecting fonts in the dialog, even before the final + selection has been made. + + \sa selectedFont +*/ + +QFont QQuickFontDialog::currentFont() const +{ + if (QPlatformFontDialogHelper *fontDialog = qobject_cast<QPlatformFontDialogHelper *>(handle())) + return fontDialog->currentFont(); + return QFont(); +} + +void QQuickFontDialog::setCurrentFont(const QFont &font) +{ + if (QPlatformFontDialogHelper *fontDialog = + qobject_cast<QPlatformFontDialogHelper *>(handle())) + fontDialog->setCurrentFont(font); +} + +/*! + \qmlproperty font QtQuick.Dialogs::FontDialog::selectedFont + + This property holds the final accepted font. + + Unlike the \l currentFont property, the \c selectedFont property is not updated + while the user is selecting fonts in the dialog, but only after the final + selection has been made. That is, when the user has clicked \uicontrol Open + to accept a font. Alternatively, the \l {Dialog::}{accepted()} signal + can be handled to get the final selection. + + \sa currentFont, {Dialog::}{accepted()} +*/ + +QFont QQuickFontDialog::selectedFont() const +{ + return m_selectedFont; +} + +void QQuickFontDialog::setSelectedFont(const QFont &font) +{ + if (m_selectedFont == font) + return; + + m_selectedFont = font; + emit selectedFontChanged(); +} + +/*! + \qmlproperty flags QtQuick.Dialogs::FontDialog::options + + This property holds the various options that affect the look and feel of the dialog. + + By default, all options are disabled. + + Options should be set before showing the dialog. Setting them while the dialog is + visible is not guaranteed to have an immediate effect on the dialog (depending on + the option and on the platform). + + Available options: + \value FontDialog.ScalableFonts Show scalable fonts. + \value FontDialog.NonScalableFonts Show non-scalable fonts. + \value FontDialog.MonospacedFonts Show monospaced fonts. + \value FontDialog.ProportionalFonts Show proportional fonts. + \value FontDialog.NoButtons Don't display \uicontrol Open and \uicontrol Cancel buttons (useful + for "live dialogs"). +*/ + +QFontDialogOptions::FontDialogOptions QQuickFontDialog::options() const +{ + return m_options->options(); +} + +void QQuickFontDialog::setOptions(QFontDialogOptions::FontDialogOptions options) +{ + if (options == m_options->options()) + return; + + m_options->setOptions(options); + emit optionsChanged(); +} + +void QQuickFontDialog::resetOptions() +{ + setOptions({}); +} + +bool QQuickFontDialog::useNativeDialog() const +{ + return QQuickAbstractDialog::useNativeDialog() + && !(m_options->testOption(QFontDialogOptions::DontUseNativeDialog)); +} + +void QQuickFontDialog::onCreate(QPlatformDialogHelper *dialog) +{ + if (QPlatformFontDialogHelper *fontDialog = qobject_cast<QPlatformFontDialogHelper *>(dialog)) { + connect(fontDialog, &QPlatformFontDialogHelper::currentFontChanged, this, + &QQuickFontDialog::currentFontChanged); + connect(fontDialog, &QPlatformFontDialogHelper::fontSelected, this, + &QQuickFontDialog::setSelectedFont); + fontDialog->setOptions(m_options); + } +} + +void QQuickFontDialog::onShow(QPlatformDialogHelper *dialog) +{ + m_options->setWindowTitle(title()); + if (QPlatformFontDialogHelper *fontDialog = qobject_cast<QPlatformFontDialogHelper *>(dialog)) + fontDialog->setOptions(m_options); // setOptions only assigns a member and isn't virtual +} + +void QQuickFontDialog::accept() +{ + if (auto fontDialog = qobject_cast<QPlatformFontDialogHelper *>(handle())) + setSelectedFont(fontDialog->currentFont()); + QQuickAbstractDialog::accept(); +} + +QT_END_NAMESPACE + +#include "moc_qquickfontdialog_p.cpp" + +#endif // QQUICKFONTDIALOG_CPP diff --git a/src/quickdialogs2/quickdialogs2/qquickfontdialog_p.h b/src/quickdialogs2/quickdialogs2/qquickfontdialog_p.h new file mode 100644 index 00000000000..c12cbd62988 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/qquickfontdialog_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFONTDIALOG_P_H +#define QQUICKFONTDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquickabstractdialog_p.h" + +#include <QtGui/qfont.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKDIALOGS2_PRIVATE_EXPORT QQuickFontDialog : public QQuickAbstractDialog +{ + Q_OBJECT + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont NOTIFY selectedFontChanged) + Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged FINAL) + Q_PROPERTY(QFontDialogOptions::FontDialogOptions options READ options WRITE setOptions + RESET resetOptions NOTIFY optionsChanged) + Q_FLAGS(QFontDialogOptions::FontDialogOptions) + QML_NAMED_ELEMENT(FontDialog) + QML_ADDED_IN_VERSION(6, 2) + +public: + explicit QQuickFontDialog(QObject *parent = nullptr); + + void setCurrentFont(const QFont &font); + QFont currentFont() const; + + void setSelectedFont(const QFont &font); + QFont selectedFont() const; + + QFontDialogOptions::FontDialogOptions options() const; + void setOptions(QFontDialogOptions::FontDialogOptions options); + void resetOptions(); + +Q_SIGNALS: + void selectedFontChanged(); + void currentFontChanged(); + void optionsChanged(); + +protected: + bool useNativeDialog() const override; + void onCreate(QPlatformDialogHelper *dialog) override; + void onShow(QPlatformDialogHelper *dialog) override; + void accept() override; + +private: + QFont m_selectedFont; + QSharedPointer<QFontDialogOptions> m_options; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFontDialog) + +#endif // QQUICKFONTDIALOG_P_H diff --git a/src/quickdialogs2/quickdialogs2/qtquickdialogs2foreign_p.h b/src/quickdialogs2/quickdialogs2/qtquickdialogs2foreign_p.h new file mode 100644 index 00000000000..8af454a6f83 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/qtquickdialogs2foreign_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTQUICKDIALOGS2FOREIGN_P_H +#define QTQUICKDIALOGS2FOREIGN_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qpa/qplatformdialoghelper.h> +#include <QtQml/qqml.h> +#include <QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h> + +QT_BEGIN_NAMESPACE + +struct QPlatformDialogHelperForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QPlatformDialogHelper) + QML_ADDED_IN_VERSION(6, 2) +}; + +struct QQuickFileNameFilterQuickDialogs2Foreign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickFileNameFilter) + QML_ADDED_IN_VERSION(6, 2) +}; + +QT_END_NAMESPACE + +#endif // QTQUICKDIALOGS2FOREIGN_P_H diff --git a/src/quickdialogs2/quickdialogs2/qtquickdialogs2global_p.h b/src/quickdialogs2/quickdialogs2/qtquickdialogs2global_p.h new file mode 100644 index 00000000000..cae55a95a3c --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/qtquickdialogs2global_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTQUICKDIALOGS2GLOBAL_P_H +#define QTQUICKDIALOGS2GLOBAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> +#include <QtQml/private/qqmlglobal_p.h> + +QT_BEGIN_NAMESPACE + +#ifndef QT_STATIC +# if defined(QT_BUILD_QUICKDIALOGS2_LIB) +# define Q_QUICKDIALOGS2_PRIVATE_EXPORT Q_DECL_EXPORT +# else +# define Q_QUICKDIALOGS2_PRIVATE_EXPORT Q_DECL_IMPORT +# endif +#else +# define Q_QUICKDIALOGS2_PRIVATE_EXPORT +#endif + +QT_END_NAMESPACE + +#endif // QTQUICKDIALOGS2GLOBAL_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt b/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt new file mode 100644 index 00000000000..caec15b0971 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt @@ -0,0 +1,146 @@ +##################################################################### +## QuickDialogs2QuickImpl Module: +##################################################################### + +set(qml_files + "qml/FileDialog.qml" + "qml/FileDialogDelegate.qml" + "qml/FileDialogDelegateLabel.qml" + "qml/FolderBreadcrumbBar.qml" + "qml/FontDialog.qml" + "qml/FontDialogContent.qml" + "qml/+Fusion/FileDialog.qml" + "qml/+Fusion/FileDialogDelegate.qml" + "qml/+Fusion/FolderBreadcrumbBar.qml" + "qml/+Fusion/FontDialog.qml" + "qml/+Imagine/FileDialog.qml" + "qml/+Imagine/FileDialogDelegate.qml" + "qml/+Imagine/FolderBreadcrumbBar.qml" + "qml/+Imagine/FontDialog.qml" + "qml/+Material/FileDialog.qml" + "qml/+Material/FileDialogDelegate.qml" + "qml/+Material/FolderBreadcrumbBar.qml" + "qml/+Material/FontDialog.qml" + "qml/+Universal/FileDialog.qml" + "qml/+Universal/FileDialogDelegate.qml" + "qml/+Universal/FolderBreadcrumbBar.qml" + "qml/+Universal/FontDialog.qml" +) + +qt_internal_add_qml_module(QuickDialogs2QuickImpl + URI "QtQuick.Dialogs.quickimpl" + VERSION "${PROJECT_VERSION}" + CLASS_NAME QtQuickDialogs2QuickImplPlugin + PLUGIN_TARGET qtquickdialogs2quickimplplugin + DEPENDENCIES + QtQuick/auto + QtQuick.Templates/auto + SOURCES + qquickdialogimplfactory.cpp + qquickdialogimplfactory_p.h + qquickfiledialogdelegate.cpp + qquickfiledialogdelegate_p.h + qquickfiledialogimpl.cpp + qquickfiledialogimpl_p.h + qquickfiledialogimpl_p_p.h + qquickfolderbreadcrumbbar.cpp + qquickfolderbreadcrumbbar_p.h + qquickfolderbreadcrumbbar_p_p.h + qquickplatformfiledialog.cpp + qquickplatformfiledialog_p.h + qquickplatformfontdialog_p.h + qquickplatformfontdialog.cpp + qtquickdialogs2quickimplforeign_p.h + qtquickdialogs2quickimplglobal_p.h + qquickfontdialogimpl_p.h + qquickfontdialogimpl_p_p.h + qquickfontdialogimpl.cpp + QML_FILES + ${qml_files} + DEFINES + QT_BUILD_QUICKDIALOGS2QUICKIMPL_LIB + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_SOURCE_DIR} + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickPrivate + Qt::QuickTemplates2 + Qt::QuickTemplates2Private + Qt::QuickDialogs2Utils + Qt::QuickDialogs2UtilsPrivate + PUBLIC_LIBRARIES + Qt::Core + Qt::Gui + Qt::Quick +) + +# Resources: +set(qtquickdialogs2quickimpl_resource_files + "images/crumb-separator-icon-round.png" + "images/crumb-separator-icon-round@2x.png" + "images/crumb-separator-icon-round@3x.png" + "images/crumb-separator-icon-round@4x.png" + "images/crumb-separator-icon-square.png" + "images/crumb-separator-icon-square@2x.png" + "images/crumb-separator-icon-square@3x.png" + "images/crumb-separator-icon-square@4x.png" + "images/file-icon-round.png" + "images/file-icon-round@2x.png" + "images/file-icon-round@3x.png" + "images/file-icon-round@4x.png" + "images/file-icon-square.png" + "images/file-icon-square@2x.png" + "images/file-icon-square@3x.png" + "images/file-icon-square@4x.png" + "images/folder-icon-round.png" + "images/folder-icon-round@2x.png" + "images/folder-icon-round@3x.png" + "images/folder-icon-round@4x.png" + "images/folder-icon-square.png" + "images/folder-icon-square@2x.png" + "images/folder-icon-square@3x.png" + "images/folder-icon-square@4x.png" + "images/imagine/filedialogdelegate-background@2x.9.png" + "images/imagine/filedialogdelegate-background@3x.9.png" + "images/imagine/filedialogdelegate-background@4x.9.png" + "images/imagine/filedialogdelegate-background.9.png" + "images/imagine/filedialogdelegate-background-disabled@2x.9.png" + "images/imagine/filedialogdelegate-background-disabled@3x.9.png" + "images/imagine/filedialogdelegate-background-disabled@4x.9.png" + "images/imagine/filedialogdelegate-background-disabled.9.png" + "images/imagine/filedialogdelegate-background-pressed@2x.9.png" + "images/imagine/filedialogdelegate-background-pressed@3x.9.png" + "images/imagine/filedialogdelegate-background-pressed@4x.9.png" + "images/imagine/filedialogdelegate-background-pressed.9.png" + "images/imagine/filedialogdelegate-background-focused@2x.9.png" + "images/imagine/filedialogdelegate-background-focused@3x.9.png" + "images/imagine/filedialogdelegate-background-focused@4x.9.png" + "images/imagine/filedialogdelegate-background-focused.9.png" + "images/imagine/filedialogdelegate-background-highlighted@2x.9.png" + "images/imagine/filedialogdelegate-background-highlighted@3x.9.png" + "images/imagine/filedialogdelegate-background-highlighted@4x.9.png" + "images/imagine/filedialogdelegate-background-highlighted.9.png" + "images/up-icon-round.png" + "images/up-icon-round@2x.png" + "images/up-icon-round@3x.png" + "images/up-icon-round@4x.png" + "images/up-icon-square.png" + "images/up-icon-square@2x.png" + "images/up-icon-square@3x.png" + "images/up-icon-square@4x.png" + "images/up-icon-thick-square.png" + "images/up-icon-thick-square@2x.png" + "images/up-icon-thick-square@3x.png" + "images/up-icon-thick-square@4x.png" +) + +qt_internal_add_resource(QuickDialogs2QuickImpl "QuickDialogs2QuickImpl" + PREFIX + "/qt-project.org/imports/QtQuick/Dialogs/quickimpl" + FILES + ${qtquickdialogs2quickimpl_resource_files} +) diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round.png new file mode 100644 index 00000000000..aaa5a3e4311 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round.svg new file mode 100644 index 00000000000..013cedefa38 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round.svg @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="8" + height="8" + viewBox="0 0 8 8" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="crumb-separator-icon-round.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect3421" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1367" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1365" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + </defs> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="16.000001" + inkscape:cx="6.7812496" + inkscape:cy="15.031249" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0" + height="14px"> + <inkscape:grid + type="xygrid" + id="grid856" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="crumb-separator-icon-round" + transform="translate(2.046,3.0914383)"> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect2017" + width="8" + height="8" + x="-2.046" + y="-3.0914383" /> + </g> + <path + id="rect858" + style="fill:#757575;stroke-width:2.43737;stroke-linejoin:round" + d="M 3.0219754,1.01117 6.416287,3.5317721 a 0.74259596,0.74259596 90 0 1 0,1.1923778 L 3.0219754,7.2447519 A 0.5029757,0.5029757 26.701285 0 1 2.2191312,6.8409408 l 0,-5.4259596 A 0.5029757,0.5029757 153.29872 0 1 3.0219754,1.01117 Z" + sodipodi:nodetypes="cccc" + inkscape:path-effect="#path-effect3421" + inkscape:original-d="m 2.2191312,0.41498117 5,3.71297983 -5,3.7129798 z" /> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect1449" + width="8" + height="8" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@2x.png new file mode 100644 index 00000000000..3f66fe172bc Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@2x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@3x.png new file mode 100644 index 00000000000..24d9f6a64e1 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@3x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@4x.png new file mode 100644 index 00000000000..1dc83ef09f4 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@4x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square.png new file mode 100644 index 00000000000..1f7ac63e7f0 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square.svg new file mode 100644 index 00000000000..9663673470b --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square.svg @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="8" + height="8" + viewBox="0 0 8 8" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="crumb-separator-icon-square.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect3421" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1367" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1365" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + </defs> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="90.509672" + inkscape:cx="4.43599" + inkscape:cy="3.3311357" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0" + height="14px"> + <inkscape:grid + type="xygrid" + id="grid856" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="crumb-separator-icon-square" + transform="translate(2.046,3.0914383)"> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect2017" + width="8" + height="8" + x="-2.046" + y="-3.0914383" /> + <path + style="fill:#757575;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -0.046,-2.0914383 4,3 -4,3 z" + id="path1065" + sodipodi:nodetypes="cccc" /> + </g> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect1449" + width="8" + height="8" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@2x.png new file mode 100644 index 00000000000..524872c1e98 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@2x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@3x.png new file mode 100644 index 00000000000..33bce847c88 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@3x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@4x.png new file mode 100644 index 00000000000..185c3eb7ae2 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@4x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round.png new file mode 100644 index 00000000000..c2a4928daf0 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round.svg new file mode 100644 index 00000000000..7ac6a23b5c1 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round.svg @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="14" + height="18" + viewBox="0 0 14 18" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="file-icon-round.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <path + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 1.5003822,2.5063148 1.5000273,15.5 A 0.99997269,0.99997269 45.000782 0 0 2.5,16.5 h 9 a 1,1 135 0 0 1,-1 V 6.3440001 A 2.3479106,2.3479106 66.930332 0 0 11.778973,4.6510931 L 9.221027,2.192907 A 2.4805476,2.4805476 21.904486 0 0 7.5000004,1.5009022 l -4.9995913,0.00451 A 1.0009299,1.0009299 134.97494 0 0 1.5003822,2.5063148 Z" + id="path917" + sodipodi:nodetypes="cccccc" + inkscape:path-effect="#path-effect1367" + inkscape:original-d="M 1.5004095,1.5063148 1.5,16.5 h 11 V 5.3440001 L 8.5,1.5 Z" /> + <path + id="path921" + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 12.35,6.5 H 8.5 a 1,1 45 0 1 -1,-1 V 1.55" + inkscape:path-effect="#path-effect1365" + inkscape:original-d="M 12.35,6.5 H 7.5 V 1.55" + sodipodi:nodetypes="ccc" /> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1367" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1365" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + </defs> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="32.000001" + inkscape:cx="7.8906248" + inkscape:cy="9.7343747" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid856" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="file-icon-round" + transform="translate(2.046,3.0914383)" /> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect2270" + width="14" + height="18" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@2x.png new file mode 100644 index 00000000000..86af70d1cf6 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@2x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@3x.png new file mode 100644 index 00000000000..06fea29ed04 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@3x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@4x.png new file mode 100644 index 00000000000..09f87873145 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@4x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square.png new file mode 100644 index 00000000000..9e8f3ddd8fd Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square.svg new file mode 100644 index 00000000000..107afa385e7 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square.svg @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="14" + height="18" + viewBox="0 0 14 18" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="file-icon-square.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <path + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 1.5004095,1.5063148 1.5,16.5 h 11 V 5.3440001 L 8.5,1.5 Z" + id="path917" + sodipodi:nodetypes="cccccc" /> + <path + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 8.5,1.55 V 5.5" + id="path919" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 12.45,5.5 H 8.5" + id="path921" + sodipodi:nodetypes="cc" /> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="22.627417" + inkscape:cx="0.022097087" + inkscape:cy="8.1538251" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid856" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="file-icon-square" + transform="translate(2.046,3.0914383)" /> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect1895" + width="14" + height="18" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@2x.png new file mode 100644 index 00000000000..8d330677445 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@2x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@3x.png new file mode 100644 index 00000000000..2987d2caed6 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@3x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@4x.png new file mode 100644 index 00000000000..69d76176e98 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@4x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round.png new file mode 100644 index 00000000000..60bc6c72c16 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round.svg new file mode 100644 index 00000000000..ba6b627644a --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round.svg @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="18" + height="14" + viewBox="0 0 18 14" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="folder-icon-round.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <path + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 1.5003723,2.5063148 1.5000372,11.5 A 0.99996275,0.99996275 45.001067 0 0 2.5,12.5 h 13 a 1,1 135 0 0 1,-1 v -7 a 1,1 45 0 0 -1,-1 h -5 A 2.4142136,2.4142136 22.5 0 1 8.7928932,2.7928932 L 8.2071068,2.2071068 A 2.4106245,2.4106245 22.469847 0 0 6.5000006,1.5010525 l -3.9995917,0.00421 A 1.0010904,1.0010904 134.97091 0 0 1.5003723,2.5063148 Z" + id="path917" + sodipodi:nodetypes="ccccccc" + inkscape:path-effect="#path-effect1132" + inkscape:original-d="M 1.5004095,1.5063148 1.5,12.5 h 15 v -9 h -7 l -2,-2 z" /> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1132" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + </defs> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="16" + inkscape:cx="-11.28125" + inkscape:cy="7.40625" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid856" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="folder-icon-round" + transform="translate(2.046,3.0914383)" /> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect2548" + width="18" + height="14" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@2x.png new file mode 100644 index 00000000000..e28734374fb Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@2x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@3x.png new file mode 100644 index 00000000000..5ee70a955e1 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@3x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@4x.png new file mode 100644 index 00000000000..47d28a4b750 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@4x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square.png new file mode 100644 index 00000000000..b84a90aecb0 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square.svg new file mode 100644 index 00000000000..0002b5ac8e2 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square.svg @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="18" + height="14" + viewBox="0 0 18 14" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="folder-icon-square.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <path + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 1.5004095,1.5063148 1.5,12.5 h 15 v -9 h -7 l -2,-2 z" + id="path917" + sodipodi:nodetypes="ccccccc" /> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="16" + inkscape:cx="-1.59375" + inkscape:cy="12.65625" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid856" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="folder-icon-square" + transform="translate(2.046,3.0914383)"> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect1423" + width="18" + height="14" + x="-2.046" + y="-3.0914383" /> + </g> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@2x.png new file mode 100644 index 00000000000..9bf320bbf07 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@2x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@3x.png new file mode 100644 index 00000000000..9f12edb6eef Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@3x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@4x.png new file mode 100644 index 00000000000..9ec5b389bdf Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@4x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled.9.png new file mode 100644 index 00000000000..ce48ee74226 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@2x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@2x.9.png new file mode 100644 index 00000000000..c7abb65c3f9 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@2x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@3x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@3x.9.png new file mode 100644 index 00000000000..46b84d7da48 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@3x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@4x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@4x.9.png new file mode 100644 index 00000000000..f4dfd338f9c Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@4x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused.9.png new file mode 100644 index 00000000000..39fa8664428 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@2x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@2x.9.png new file mode 100644 index 00000000000..6b61562c14d Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@2x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@3x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@3x.9.png new file mode 100644 index 00000000000..e46c0bf1d9a Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@3x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@4x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@4x.9.png new file mode 100644 index 00000000000..010444e8e1d Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@4x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted.9.png new file mode 100644 index 00000000000..6f565e8be20 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@2x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@2x.9.png new file mode 100644 index 00000000000..9fd0a434bb1 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@2x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@3x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@3x.9.png new file mode 100644 index 00000000000..62b7435b84a Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@3x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@4x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@4x.9.png new file mode 100644 index 00000000000..96444b89057 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@4x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed.9.png new file mode 100644 index 00000000000..39fa8664428 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@2x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@2x.9.png new file mode 100644 index 00000000000..6b61562c14d Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@2x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@3x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@3x.9.png new file mode 100644 index 00000000000..e46c0bf1d9a Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@3x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@4x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@4x.9.png new file mode 100644 index 00000000000..010444e8e1d Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@4x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background.9.png new file mode 100644 index 00000000000..cef1bafab3a Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background.svg new file mode 100644 index 00000000000..acecfcc9ac9 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background.svg @@ -0,0 +1,358 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="210mm" + height="297mm" + viewBox="0 0 210 297" + version="1.1" + id="svg5" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="filedialogdelegate-background.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata + id="metadata122"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + id="namedview7" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + objecttolerance="10.0" + gridtolerance="10.0" + guidetolerance="10.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:document-units="px" + showgrid="false" + inkscape:zoom="3.2715084" + inkscape:cx="24.912056" + inkscape:cy="54.867657" + inkscape:window-width="1848" + inkscape:window-height="1016" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="g1413" + showguides="true" + inkscape:guide-bbox="true" + inkscape:document-rotation="0"> + <sodipodi:guide + position="6.0854167,296.96676" + orientation="-1,0" + id="guide2310" + inkscape:label="" + inkscape:locked="true" + inkscape:color="rgb(0,0,255)" /> + <sodipodi:guide + position="3.363578,293.03125" + orientation="0,1" + id="guide2322" + inkscape:label="" + inkscape:locked="true" + inkscape:color="rgb(0,0,255)" /> + <sodipodi:guide + position="12.170833,297.68429" + orientation="-1,0" + id="guide2760" + inkscape:label="" + inkscape:locked="true" + inkscape:color="rgb(0,0,255)" /> + <sodipodi:guide + position="18.25625,297.91758" + orientation="-1,0" + id="guide949" + inkscape:label="" + inkscape:locked="true" + inkscape:color="rgb(0,0,255)" /> + <sodipodi:guide + position="24.341667,299.40187" + orientation="-1,0" + id="guide941" + inkscape:label="" + inkscape:locked="true" + inkscape:color="rgb(0,0,255)" /> + <sodipodi:guide + position="30.427083,299.08734" + orientation="-1,0" + id="guide1165" + inkscape:label="" + inkscape:locked="false" + inkscape:color="rgb(0,0,255)" /> + </sodipodi:namedview> + <defs + id="defs2" /> + <g + inkscape:label="[9] filedialogdelegate-background-highlighted" + inkscape:groupmode="layer" + id="g1413" + style="display:inline" + sodipodi:insensitive="true"> + <rect + style="fill:none;stroke-width:0.946642;stroke-linejoin:round" + id="rect1401" + width="6.0854168" + height="3.96875" + x="30.427084" + y="-6.9388939e-18" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:7.98967;stroke-linejoin:round" + id="rect1403" + width="0.26458332" + height="3.4395833" + x="30.427084" + y="0.26458332" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:10.1547;stroke-linejoin:round" + id="rect1405" + width="0.26458332" + height="5.5562401" + x="-0.26415125" + y="30.691679" + transform="matrix(3.6708238e-5,-1,1,1.4067378e-5,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect1407" + width="0.26458332" + height="0.26458287" + x="-3.9588995" + y="33.337505" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect1409" + width="0.26458332" + height="0.26458287" + x="-2.1059568" + y="36.247913" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#4fc1e9;fill-opacity:1;fill-rule:evenodd;stroke-width:0.263352" + id="rect1411" + width="5.5562501" + height="3.4395833" + x="30.691668" + y="0.26458332" /> + </g> + <g + inkscape:label="[9] filedialogdelegate-background-focused" + inkscape:groupmode="layer" + id="g939" + style="display:inline" + sodipodi:insensitive="true"> + <rect + style="fill:none;stroke-width:0.946642;stroke-linejoin:round" + id="rect927" + width="6.0854168" + height="3.96875" + x="18.25625" + y="-6.9388939e-18" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:7.98967;stroke-linejoin:round" + id="rect929" + width="0.26458332" + height="3.4395833" + x="18.25625" + y="0.26458332" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:10.1547;stroke-linejoin:round" + id="rect931" + width="0.26458332" + height="5.5562401" + x="-0.26432261" + y="18.520845" + transform="matrix(3.6708238e-5,-1,1,1.4067378e-5,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect933" + width="0.26458332" + height="0.26458287" + x="-3.9624968" + y="21.166674" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect935" + width="0.26458332" + height="0.26458287" + x="-2.1095541" + y="24.077082" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#e6e9ed;fill-opacity:1;fill-rule:evenodd;stroke-width:0.263352" + id="rect937" + width="5.5562501" + height="3.4395833" + x="18.520834" + y="0.26458332" /> + </g> + <g + inkscape:label="[9] filedialogdelegate-background-pressed" + inkscape:groupmode="layer" + id="g867" + style="display:inline" + sodipodi:insensitive="true"> + <rect + style="fill:none;stroke-width:0.946642;stroke-linejoin:round" + id="rect855" + width="6.0854168" + height="3.96875" + x="12.170834" + y="-6.9388939e-18" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:7.98967;stroke-linejoin:round" + id="rect857" + width="0.26458332" + height="3.4395833" + x="12.170834" + y="0.26458332" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:10.1547;stroke-linejoin:round" + id="rect859" + width="0.26458332" + height="5.5562401" + x="-0.26440823" + y="12.435429" + transform="matrix(3.6708238e-5,-1,1,1.4067378e-5,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect861" + width="0.26458332" + height="0.26458287" + x="-3.9642947" + y="15.081257" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect863" + width="0.26458332" + height="0.26458287" + x="-2.111352" + y="17.991665" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#e6e9ed;fill-opacity:1;fill-rule:evenodd;stroke-width:0.263352" + id="rect865" + width="5.5562501" + height="3.4395833" + x="12.435416" + y="0.26458332" /> + </g> + <g + inkscape:label="[9] filedialogdelegate-background-disabled" + inkscape:groupmode="layer" + id="g2435" + style="display:inline" + sodipodi:insensitive="true"> + <rect + style="fill:none;stroke-width:0.946642;stroke-linejoin:round" + id="rect2425" + width="6.0854168" + height="3.96875" + x="6.0854168" + y="-6.9388939e-18" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:7.98967;stroke-linejoin:round" + id="rect2427" + width="0.26458332" + height="3.4395833" + x="6.0854168" + y="0.26458332" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:10.1547;stroke-linejoin:round" + id="rect2429" + width="0.26458332" + height="5.5562401" + x="-0.264494" + y="6.3500099" + transform="matrix(3.6708238e-5,-1,1,1.4067378e-5,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect2431" + width="0.26458332" + height="0.26458287" + x="-3.9660921" + y="8.995841" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect2433" + width="0.26458332" + height="0.26458287" + x="-2.1131494" + y="11.906255" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#f5f7fa;fill-opacity:1;fill-rule:evenodd;stroke-width:0.263352" + id="rect124" + width="5.5562501" + height="3.4395833" + x="6.3499999" + y="0.26458332" /> + </g> + <g + inkscape:label="[9] filedialogdelegate-background" + inkscape:groupmode="layer" + id="layer1" + style="display:inline" + sodipodi:insensitive="true"> + <rect + style="fill:none;stroke-width:0.946642;stroke-linejoin:round" + id="rect846" + width="6.0854168" + height="3.96875" + x="0" + y="-6.9388939e-18" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:7.98967;stroke-linejoin:round" + id="rect1054" + width="0.26458332" + height="3.4395833" + x="0" + y="0.26458332" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:10.1547;stroke-linejoin:round" + id="rect1212" + width="0.26458332" + height="5.5562401" + x="-0.26457959" + y="0.26459303" + transform="matrix(3.6708238e-5,-1,1,1.4067378e-5,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect1505" + width="0.26458332" + height="0.26458287" + x="-3.9678898" + y="2.9104238" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect1587" + width="0.26458332" + height="0.26458287" + x="-2.1149471" + y="5.8208375" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.0578;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3108" + width="5.5562501" + height="3.4395833" + x="0.26458332" + y="0.26458332" /> + </g> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@2x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@2x.9.png new file mode 100644 index 00000000000..5a136a0ca9b Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@2x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@3x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@3x.9.png new file mode 100644 index 00000000000..f47a366b7bb Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@3x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@4x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@4x.9.png new file mode 100644 index 00000000000..9ecb680f20c Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@4x.9.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round.png new file mode 100644 index 00000000000..a4b7bc03836 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round.svg new file mode 100644 index 00000000000..fd05395798c --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round.svg @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16" + height="16" + viewBox="0 0 16 16" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="up-icon-round.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="16" + inkscape:cx="-1.96875" + inkscape:cy="10.65625" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid1497" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="up-icon-round" /> + <g + id="g1413" + transform="translate(0.3592822,-0.0034197)"> + <path + style="fill:none;fill-opacity:1;stroke:#757575;stroke-width:2.23721;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 7.6407178,2.1165354 3e-7,11.7737686" + id="path20" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;fill-opacity:1;stroke:#757575;stroke-width:2.23721;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 7.6407178,2.1165354 2.6616436,7.0956099" + id="path950" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;fill-opacity:1;stroke:#757575;stroke-width:2.23721;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 7.6407178,2.1165354 12.619792,7.0956096" + id="path952" + sodipodi:nodetypes="cc" /> + </g> + <rect + style="fill:none;stroke-width:5.33333;stroke-linejoin:round" + id="rect2897" + width="16" + height="16" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@2x.png new file mode 100644 index 00000000000..25ee970a175 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@2x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@3x.png new file mode 100644 index 00000000000..486f2f46a95 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@3x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@4x.png new file mode 100644 index 00000000000..585402531ca Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@4x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square.png new file mode 100644 index 00000000000..f7d4151a5ae Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square.svg new file mode 100644 index 00000000000..93fc45bae42 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square.svg @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16" + height="16" + viewBox="0 0 16 16" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="up-icon-square.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="11.313709" + inkscape:cx="-6.3197669" + inkscape:cy="28.416854" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid1497" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="up-icon-square" /> + <path + style="fill:#757575;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 8.000315,1 -6,6 L 3,8 8,3 13,8 14,7 Z" + id="path928" + sodipodi:nodetypes="ccccccc" /> + <rect + style="fill:none;stroke-width:5.33333;stroke-linejoin:round" + id="rect2897" + width="16" + height="16" + x="0" + y="0" /> + <rect + style="fill:#757575;fill-opacity:1;stroke:none;stroke-width:5.23075;stroke-linejoin:round" + id="rect4947" + width="1.5" + height="11" + x="7.2501574" + y="3" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@2x.png new file mode 100644 index 00000000000..2e2a3d94eb8 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@2x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@3x.png new file mode 100644 index 00000000000..8965148c90b Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@3x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@4x.png new file mode 100644 index 00000000000..0a56bbcc0aa Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@4x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square.png new file mode 100644 index 00000000000..3f9f87624a8 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square.svg new file mode 100644 index 00000000000..dd20777be73 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square.svg @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16" + height="16" + viewBox="0 0 16 16" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="up-icon-thick-square.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="22.627417" + inkscape:cx="2.3201941" + inkscape:cy="10.00998" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid1497" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="up-icon-thick-square" /> + <path + style="fill:#757575;fill-opacity:1;stroke:none;stroke-width:1.34164px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 2,8 6,-6 6,6 h -3 v 7 H 5 V 8 Z" + id="path1103" + sodipodi:nodetypes="cccccccc" /> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect1748" + width="16" + height="16" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@2x.png new file mode 100644 index 00000000000..b4efe132284 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@2x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@3x.png new file mode 100644 index 00000000000..2e8302b1f0f Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@3x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@4x.png new file mode 100644 index 00000000000..5cf05ab3056 Binary files /dev/null and b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@4x.png differ diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialog.qml new file mode 100644 index 00000000000..cf2a0a32c58 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialog.qml @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt.labs.folderlistmodel +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +import "." as DialogsImpl + +FileDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + padding: 6 + horizontalPadding: 12 + + standardButtons: T.Dialog.Open | T.Dialog.Cancel + + /* + We use attached properties because we want to handle logic in C++, and: + - We can't assume the footer only contains a DialogButtonBox (which would allow us + to connect up to it in QQuickFileDialogImpl); it also needs to hold a ComboBox + and therefore the root footer item will be e.g. a layout item instead. + - We don't want to create our own "FileDialogButtonBox" (in order to be able to handle the logic + in C++) because we'd need to copy (and hence duplicate code in) DialogButtonBox.qml. + */ + FileDialogImpl.buttonBox: buttonBox + FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox + FileDialogImpl.fileDialogListView: fileDialogListView + FileDialogImpl.breadcrumbBar: breadcrumbBar + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.palette.window + border.color: control.palette.mid + radius: 2 + + Rectangle { + z: -1 + x: 1 + y: 1 + width: parent.width + height: parent.height + color: control.palette.shadow + opacity: 0.2 + radius: 2 + } + } + + header: ColumnLayout { + spacing: 0 + + Label { + objectName: "dialogTitleBarLabel" + text: control.title + horizontalAlignment: Label.AlignHCenter + elide: Label.ElideRight + font.bold: true + padding: 6 + + Layout.fillWidth: true + Layout.leftMargin: 12 + Layout.rightMargin: 12 + Layout.topMargin: control.title.length > 0 ? 0 : 12 + Layout.preferredHeight: control.title.length > 0 ? implicitHeight : 0 + } + + DialogsImpl.FolderBreadcrumbBar { + id: breadcrumbBar + fileDialog: control + + Layout.fillWidth: true + Layout.leftMargin: 12 + Layout.rightMargin: 12 + + KeyNavigation.tab: fileDialogListView + } + } + + contentItem: Frame { + padding: 0 + verticalPadding: 1 + + ListView { + id: fileDialogListView + objectName: "fileDialogListView" + anchors.fill: parent + clip: true + focus: true + boundsBehavior: Flickable.StopAtBounds + + ScrollBar.vertical: ScrollBar {} + + model: FolderListModel { + folder: control.currentFolder + nameFilters: control.selectedNameFilter.globs + showDirsFirst: true + sortCaseSensitive: false + } + delegate: DialogsImpl.FileDialogDelegate { + objectName: "fileDialogDelegate" + index + x: 1 + width: ListView.view.width - 2 + highlighted: ListView.isCurrentItem + fileDialog: control + fileDetailRowWidth: nameFiltersComboBox.width + + KeyNavigation.backtab: breadcrumbBar + KeyNavigation.tab: nameFiltersComboBox + } + } + } + + footer: RowLayout { + id: rowLayout + spacing: 12 + + ComboBox { + // OK to use IDs here, since users shouldn't be overriding this stuff. + id: nameFiltersComboBox + model: control.nameFilters + + Layout.leftMargin: 12 + Layout.fillWidth: true + Layout.bottomMargin: 12 + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 6 + horizontalPadding: 0 + verticalPadding: 0 + background: null + + Layout.rightMargin: 12 + Layout.bottomMargin: 12 + } + } + + T.Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + T.Overlay.modeless: Rectangle { + color: Fusion.topShadow + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialogDelegate.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialogDelegate.qml new file mode 100644 index 00000000000..3c2b7b9c3c4 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialogDelegate.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl as ControlsImpl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FileDialogDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + file: fileUrl + + icon.width: 16 + icon.height: 16 + icon.color: highlighted ? palette.highlightedText : palette.text + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/" + + (fileIsDir ? "folder" : "file") + "-icon-round.png" + + // We don't use index here, but in C++. Since we're using required + // properties, the index context property will not be injected, so we can't + // use its QQmlContext to access it. + required property int index + required property string fileName + required property url fileUrl + required property int fileSize + required property date fileModified + required property bool fileIsDir + + required property int fileDetailRowWidth + + contentItem: FileDialogDelegateLabel { + delegate: control + fileDetailRowTextColor: control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + fileDetailRowWidth: control.fileDetailRowWidth + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 20 + color: control.down ? Fusion.buttonColor(control.palette, false, true, true) + : control.highlighted ? Fusion.highlight(control.palette) : control.palette.base + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FolderBreadcrumbBar.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FolderBreadcrumbBar.qml new file mode 100644 index 00000000000..df8a466881b --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FolderBreadcrumbBar.qml @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FolderBreadcrumbBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + (upButton ? upButton.implicitWidth + upButtonSpacing : 0) + + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + upButtonSpacing: 6 + + contentItem: ListView { + currentIndex: control.currentIndex + model: control.contentModel + orientation: ListView.Horizontal + snapMode: ListView.SnapToItem + highlightMoveDuration: 0 + interactive: false + clip: true + + Rectangle { + anchors.fill: parent + color: control.palette.light + border.color: control.palette.mid + radius: 2 + z: -1 + } + } + buttonDelegate: Button { + id: buttonDelegateRoot + text: folderName + flat: true + + // The default of 100 is a bit too wide for short directory names. + Binding { + target: buttonDelegateRoot.background + property: "implicitWidth" + value: 24 + } + + required property int index + required property string folderName + } + separatorDelegate: IconImage { + id: iconImage + source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/crumb-separator-icon-round.png" + sourceSize: Qt.size(8, 8) + width: 8 + 6 + height: control.contentItem.height + color: control.palette.dark + y: (control.height - height) / 2 + } + upButton: Button { + x: control.leftPadding + y: control.topPadding + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/up-icon-round.png" + icon.width: 16 + icon.height: 16 + width: height + height: Math.max(implicitHeight, control.contentItem.height) + focusPolicy: Qt.TabFocus + } + textField: TextField { + text: control.fileDialog.selectedFile + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FontDialog.qml new file mode 100644 index 00000000000..dd75338f212 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FontDialog.qml @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + implicitWidth: Math.max(control.implicitBackgroundWidth + control.leftInset + control.rightInset, + control.contentWidth + control.leftPadding + control.rightPadding, + control.implicitHeaderWidth, + control.implicitFooterWidth) + implicitHeight: Math.max(control.implicitBackgroundHeight + control.topInset + control.bottomInset, + control.contentHeight + control.topPadding + control.bottomPadding + + (control.implicitHeaderHeight > 0 ? control.implicitHeaderHeight + control.spacing : 0) + + (control.implicitFooterHeight > 0 ? control.implicitFooterHeight + control.spacing : 0)) + + leftPadding: 20 + rightPadding: 20 + // Ensure that the background's border is visible. + leftInset: -1 + rightInset: -1 + topInset: -1 + bottomInset: -1 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.palette.window + border.color: control.palette.mid + radius: 2 + + Rectangle { + z: -1 + x: 1 + y: 1 + width: parent.width + height: parent.height + color: control.palette.shadow + opacity: 0.2 + radius: 2 + } + } + + Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + Overlay.modeless: Rectangle { + color: Fusion.topShadow + } + + header: Label { + text: control.title + horizontalAlignment: Label.AlignHCenter + elide: Label.ElideRight + font.bold: true + padding: 6 + } + + contentItem: FontDialogContent { + id: content + } + + footer: RowLayout { + id: rowLayout + spacing: 12 + + Label { + text: qsTr("Writing System") + + Layout.leftMargin: 12 + Layout.topMargin: 6 + Layout.bottomMargin: 6 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + Layout.topMargin: 6 + Layout.bottomMargin: 6 + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 6 + horizontalPadding: 0 + verticalPadding: 0 + background: null + + Layout.rightMargin: 12 + Layout.topMargin: 6 + Layout.bottomMargin: 6 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialog.qml new file mode 100644 index 00000000000..9509664df6d --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialog.qml @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt.labs.folderlistmodel +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts + +import "." as DialogsImpl + +FileDialogImpl { + id: control + + // Can't set implicitWidth of the NinePatchImage background, so we do it here. + implicitWidth: Math.max(600, + implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(400, + implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + standardButtons: T.Dialog.Open | T.Dialog.Cancel + + FileDialogImpl.buttonBox: buttonBox + FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox + FileDialogImpl.fileDialogListView: fileDialogListView + FileDialogImpl.breadcrumbBar: breadcrumbBar + + background: NinePatchImage { + source: Imagine.url + "dialog-background" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + + header: ColumnLayout { + spacing: 12 + + Label { + text: control.title + elide: Label.ElideRight + font.bold: true + + Layout.leftMargin: 16 + Layout.rightMargin: 16 + Layout.topMargin: 12 + Layout.fillWidth: true + Layout.preferredHeight: control.title.length > 0 ? implicitHeight : 0 + + background: NinePatchImage { + width: parent.width + height: parent.height + + source: Imagine.url + "dialog-title" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + } + + DialogsImpl.FolderBreadcrumbBar { + id: breadcrumbBar + fileDialog: control + + Layout.leftMargin: 16 + Layout.rightMargin: 16 + Layout.fillWidth: true + Layout.maximumWidth: parent.width - 28 + } + } + + contentItem: ListView { + id: fileDialogListView + objectName: "fileDialogListView" + clip: true + boundsBehavior: Flickable.StopAtBounds + + ScrollBar.vertical: ScrollBar {} + + model: FolderListModel { + folder: control.currentFolder + nameFilters: control.selectedNameFilter.globs + showDirsFirst: true + sortCaseSensitive: false + } + delegate: DialogsImpl.FileDialogDelegate { + objectName: "fileDialogDelegate" + index + width: ListView.view.width + highlighted: ListView.isCurrentItem + fileDialog: control + fileDetailRowWidth: nameFiltersComboBox.width + } + } + + footer: RowLayout { + id: rowLayout + spacing: 20 + + ComboBox { + id: nameFiltersComboBox + model: control.nameFilters + + Layout.leftMargin: 16 + Layout.bottomMargin: 16 + Layout.fillWidth: true + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + + Layout.bottomMargin: 16 + Layout.rightMargin: 16 + } + } + + T.Overlay.modal: NinePatchImage { + source: Imagine.url + "dialog-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": true} + ] + } + } + + T.Overlay.modeless: NinePatchImage { + source: Imagine.url + "dialog-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": false} + ] + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialogDelegate.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialogDelegate.qml new file mode 100644 index 00000000000..832f851ccaf --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialogDelegate.qml @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl +import QtQuick.Controls.impl as ControlsImpl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FileDialogDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + file: fileUrl + + icon.width: 16 + icon.height: 16 + icon.color: highlighted ? palette.highlightedText : palette.text + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/" + + (fileIsDir ? "folder" : "file") + "-icon-round.png" + + required property int index + required property string fileName + required property url fileUrl + required property int fileSize + required property date fileModified + required property bool fileIsDir + + required property int fileDetailRowWidth + + contentItem: FileDialogDelegateLabel { + delegate: control + fileDetailRowTextColor: control.icon.color + fileDetailRowWidth: control.fileDetailRowWidth + } + + background: NinePatchImage { + source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/imagine/filedialogdelegate-background" + NinePatchImageSelector on source { + states: [ + { "disabled": !control.enabled }, + { "pressed": control.down }, + { "focused": control.visualFocus }, + { "highlighted": control.highlighted }, + { "mirrored": control.mirrored }, + { "hovered": control.enabled && control.hovered } + ] + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FolderBreadcrumbBar.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FolderBreadcrumbBar.qml new file mode 100644 index 00000000000..30e0586740f --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FolderBreadcrumbBar.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FolderBreadcrumbBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + (upButton ? upButton.implicitWidth + upButtonSpacing : 0) + + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + upButtonSpacing: 20 + padding: 1 + + background: Rectangle {} + contentItem: ListView { + currentIndex: control.currentIndex + model: control.contentModel + orientation: ListView.Horizontal + snapMode: ListView.SnapToItem + highlightMoveDuration: 0 + interactive: false + clip: true + } + buttonDelegate: Button { + id: buttonDelegateRoot + text: folderName + flat: true + + required property int index + required property string folderName + } + separatorDelegate: IconImage { + id: iconImage + source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/crumb-separator-icon-round.png" + sourceSize: Qt.size(8, 8) + width: 8 + height: control.contentItem.height + y: (control.height - height) / 2 + } + upButton: ToolButton { + x: control.leftPadding + y: control.topPadding + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/up-icon-thick-square.png" + icon.width: 16 + icon.height: 16 + focusPolicy: Qt.TabFocus + } + textField: TextField { + text: control.fileDialog.selectedFile + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FontDialog.qml new file mode 100644 index 00000000000..47bd53dafcc --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FontDialog.qml @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + // Can't set implicitWidth of the NinePatchImage background, so we do it here. + implicitWidth: Math.max(600, + implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(400, + implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: NinePatchImage { + source: Imagine.url + "dialog-background" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + + Overlay.modal: NinePatchImage { + source: Imagine.url + "dialog-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": true} + ] + } + } + + Overlay.modeless: NinePatchImage { + source: Imagine.url + "dialog-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": false} + ] + } + } + + header: Label { + text: control.title + elide: Label.ElideRight + font.bold: true + + leftPadding: 16 + rightPadding: 16 + topPadding: 12 + height: control.title.length > 0 ? implicitHeight : 0 + + background: NinePatchImage { + width: parent.width + height: parent.height + + source: Imagine.url + "dialog-title" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + } + + contentItem: FontDialogContent { + id: content + rowSpacing: 16 + } + + footer: RowLayout { + id: rowLayout + spacing: 20 + + Label { + text: qsTr("Writing System") + Layout.leftMargin: 20 + Layout.bottomMargin: 16 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + Layout.bottomMargin: 16 + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + Layout.rightMargin: 20 + Layout.bottomMargin: 16 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialog.qml new file mode 100644 index 00000000000..de4a9d6f443 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialog.qml @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt.labs.folderlistmodel +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +import "." as DialogsImpl + +FileDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + leftPadding: 24 + rightPadding: 24 + + standardButtons: T.Dialog.Open | T.Dialog.Cancel + + Material.elevation: 24 + + FileDialogImpl.buttonBox: buttonBox + FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox + FileDialogImpl.fileDialogListView: fileDialogListView + FileDialogImpl.breadcrumbBar: breadcrumbBar + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + radius: 2 + color: control.Material.dialogColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } + + header: ColumnLayout { + spacing: 12 + + Label { + text: control.title + visible: control.title.length > 0 + elide: Label.ElideRight + font.bold: true + font.pixelSize: 16 + + Layout.leftMargin: 24 + Layout.rightMargin: 24 + Layout.topMargin: 24 + Layout.fillWidth: true + } + + DialogsImpl.FolderBreadcrumbBar { + id: breadcrumbBar + fileDialog: control + + Layout.leftMargin: 24 + Layout.rightMargin: 24 + Layout.fillWidth: true + Layout.maximumWidth: parent.width - 48 + } + } + + contentItem: ListView { + id: fileDialogListView + objectName: "fileDialogListView" + clip: true + + ScrollBar.vertical: ScrollBar {} + + model: FolderListModel { + folder: control.currentFolder + nameFilters: control.selectedNameFilter.globs + showDirsFirst: true + sortCaseSensitive: false + } + delegate: DialogsImpl.FileDialogDelegate { + objectName: "fileDialogDelegate" + index + width: ListView.view.width + highlighted: ListView.isCurrentItem + fileDialog: control + fileDetailRowWidth: nameFiltersComboBox.width + } + } + + footer: RowLayout { + id: rowLayout + spacing: 20 + + ComboBox { + id: nameFiltersComboBox + model: control.nameFilters + + Layout.leftMargin: 20 + Layout.fillWidth: true + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + horizontalPadding: 0 + verticalPadding: 20 + + Layout.rightMargin: 20 + } + } + + Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialogDelegate.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialogDelegate.qml new file mode 100644 index 00000000000..eb4bae9bfca --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialogDelegate.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FileDialogDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 16 + verticalPadding: 8 + spacing: 16 + + icon.width: 16 + icon.height: 16 + icon.color: enabled ? Material.foreground : Material.hintTextColor + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/" + + (fileIsDir ? "folder" : "file") + "-icon-square.png" + + file: fileUrl + + required property int index + required property string fileName + required property url fileUrl + required property int fileSize + required property date fileModified + required property bool fileIsDir + + required property int fileDetailRowWidth + + contentItem: FileDialogDelegateLabel { + delegate: control + fileDetailRowTextColor: control.Material.hintTextColor + fileDetailRowWidth: control.fileDetailRowWidth + } + + background: Rectangle { + implicitHeight: control.Material.delegateHeight + + color: control.highlighted ? Color.transparent(control.Material.accentColor, 0.08) : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + pressed: control.pressed + anchor: control + active: control.down || control.visualFocus || control.hovered + color: control.highlighted ? control.Material.highlightedRippleColor : control.Material.rippleColor + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FolderBreadcrumbBar.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FolderBreadcrumbBar.qml new file mode 100644 index 00000000000..5ac638a07da --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FolderBreadcrumbBar.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FolderBreadcrumbBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + (upButton ? upButton.implicitWidth + upButtonSpacing : 0) + + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + upButtonSpacing: 20 + padding: 1 + + background: Rectangle {} + contentItem: ListView { + currentIndex: control.currentIndex + model: control.contentModel + orientation: ListView.Horizontal + snapMode: ListView.SnapToItem + highlightMoveDuration: 0 + interactive: false + clip: true + } + buttonDelegate: Button { + id: buttonDelegateRoot + text: folderName + flat: true + font.capitalization: Font.MixedCase + + // The default of 100 is a bit too wide for short directory names. + Binding { + target: buttonDelegateRoot.background + property: "implicitWidth" + value: control.Material.buttonHeight + } + + required property int index + required property string folderName + } + separatorDelegate: IconImage { + id: iconImage + source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/crumb-separator-icon-square.png" + sourceSize: Qt.size(8, 8) + // The image is 8x8, and add 2 px padding on each side. + width: 8 + 4 + height: control.contentItem.height + color: control.Material.hintTextColor + y: (control.height - height) / 2 + } + upButton: ToolButton { + x: control.leftPadding + y: control.topPadding + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/up-icon-thick-square.png" + icon.width: 16 + icon.height: 16 + width: height + focusPolicy: Qt.TabFocus + } + textField: TextField { + text: control.fileDialog.selectedFile + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FontDialog.qml new file mode 100644 index 00000000000..51134680124 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FontDialog.qml @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + leftPadding: 24 + rightPadding: 24 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + Material.elevation: 24 + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + radius: 2 + color: control.Material.dialogColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } + + Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } + + header: Label { + text: control.title + visible: control.title.length > 0 + elide: Label.ElideRight + font.bold: true + font.pixelSize: 16 + + leftPadding: 24 + rightPadding: 24 + topPadding: 24 + bottomPadding: 24 + } + + contentItem: FontDialogContent { + id: content + familyEdit.bottomPadding: 8 + styleEdit.bottomPadding: 8 + sizeEdit.bottomPadding: 8 + } + + footer: RowLayout { + id: rowLayout + spacing: 20 + + Label { + text: qsTr("Writing System") + + Layout.leftMargin: 20 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + horizontalPadding: 0 + verticalPadding: 20 + + Layout.rightMargin: 20 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialog.qml new file mode 100644 index 00000000000..7bcb4629d04 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialog.qml @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt.labs.folderlistmodel +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Universal +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +import "." as DialogsImpl + +FileDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + padding: 24 + verticalPadding: 18 + + standardButtons: T.Dialog.Open | T.Dialog.Cancel + + FileDialogImpl.buttonBox: buttonBox + FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox + FileDialogImpl.fileDialogListView: fileDialogListView + FileDialogImpl.breadcrumbBar: breadcrumbBar + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.Universal.chromeMediumLowColor + border.color: control.Universal.chromeHighColor + border.width: 1 // FlyoutBorderThemeThickness + } + + header: ColumnLayout { + spacing: 12 + + Label { + text: control.title + elide: Label.ElideRight + // TODO: QPlatformTheme::TitleBarFont + font.pixelSize: 20 + + Layout.leftMargin: 24 + Layout.rightMargin: 24 + Layout.topMargin: 18 + Layout.fillWidth: true + Layout.preferredHeight: control.title.length > 0 ? implicitHeight : 0 + + background: Rectangle { + x: 1; y: 1 // // FlyoutBorderThemeThickness + color: control.Universal.chromeMediumLowColor + width: parent.width - 2 + height: parent.height - 1 + } + } + + DialogsImpl.FolderBreadcrumbBar { + id: breadcrumbBar + fileDialog: control + + Layout.leftMargin: 24 + Layout.rightMargin: 24 + Layout.fillWidth: true + Layout.maximumWidth: parent.width - 48 + } + } + + contentItem: ListView { + id: fileDialogListView + objectName: "fileDialogListView" + clip: true + boundsBehavior: Flickable.StopAtBounds + + ScrollBar.vertical: ScrollBar {} + + model: FolderListModel { + folder: control.currentFolder + nameFilters: control.selectedNameFilter.globs + showDirsFirst: true + sortCaseSensitive: false + } + delegate: DialogsImpl.FileDialogDelegate { + objectName: "fileDialogDelegate" + index + width: ListView.view.width + highlighted: ListView.isCurrentItem + fileDialog: control + fileDetailRowWidth: nameFiltersComboBox.width + } + } + + footer: RowLayout { + id: rowLayout + spacing: 24 + + ComboBox { + id: nameFiltersComboBox + model: control.nameFilters + + Layout.leftMargin: 24 + Layout.fillWidth: true + Layout.topMargin: 6 + Layout.bottomMargin: 24 + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + horizontalPadding: 0 + + Layout.rightMargin: 24 + } + } + + T.Overlay.modal: Rectangle { + color: control.Universal.baseLowColor + } + + T.Overlay.modeless: Rectangle { + color: control.Universal.baseLowColor + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialogDelegate.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialogDelegate.qml new file mode 100644 index 00000000000..d4322dc5fa9 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialogDelegate.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Controls.Universal +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FileDialogDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 + + padding: 12 + topPadding: padding - 1 + bottomPadding: padding + 1 + + icon.width: 20 + icon.height: 20 + icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/" + + (fileIsDir ? "folder" : "file") + "-icon-square.png" + + file: fileUrl + + required property int index + required property string fileName + required property url fileUrl + required property int fileSize + required property date fileModified + required property bool fileIsDir + + required property int fileDetailRowWidth + + contentItem: FileDialogDelegateLabel { + delegate: control + fileDetailRowTextColor: control.icon.color + fileDetailRowWidth: control.fileDetailRowWidth + } + + background: Rectangle { + visible: control.down || control.highlighted || control.visualFocus || control.hovered + color: control.down ? control.Universal.listMediumColor : + control.hovered ? control.Universal.listLowColor : control.Universal.altMediumLowColor + + Rectangle { + width: parent.width + height: parent.height + visible: control.visualFocus || control.highlighted + color: control.Universal.accent + opacity: control.Universal.theme === Universal.Light ? 0.4 : 0.6 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FolderBreadcrumbBar.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FolderBreadcrumbBar.qml new file mode 100644 index 00000000000..1554b40a6f1 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FolderBreadcrumbBar.qml @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Universal +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FolderBreadcrumbBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + (upButton ? upButton.implicitWidth + upButtonSpacing : 0) + + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + upButtonSpacing: 20 + padding: 1 + + background: Rectangle {} + contentItem: ListView { + currentIndex: control.currentIndex + model: control.contentModel + orientation: ListView.Horizontal + snapMode: ListView.SnapToItem + highlightMoveDuration: 0 + interactive: false + clip: true + } + buttonDelegate: ToolButton { + id: buttonDelegateRoot + text: folderName + + // The default is a bit too wide for short directory names. + Binding { + target: buttonDelegateRoot.background + property: "implicitWidth" + value: 48 + } + + required property int index + required property string folderName + } + separatorDelegate: IconImage { + id: iconImage + source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/crumb-separator-icon-square.png" + sourceSize: Qt.size(8, 8) + // The image is 8x8, and add 2 px padding on each side. + width: 8 + 4 + height: control.contentItem.height + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) + y: (control.height - height) / 2 + } + upButton: ToolButton { + x: control.leftPadding + y: control.topPadding + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/up-icon-square.png" + icon.width: 16 + icon.height: 16 + width: height + focusPolicy: Qt.TabFocus + } + textField: TextField { + text: control.fileDialog.selectedFile + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FontDialog.qml new file mode 100644 index 00000000000..1bd3092e6bb --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FontDialog.qml @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Universal +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + padding: 24 + verticalPadding: 18 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.Universal.chromeMediumLowColor + border.color: control.Universal.chromeHighColor + border.width: 1 // FlyoutBorderThemeThickness + } + + Overlay.modal: Rectangle { + color: control.Universal.baseLowColor + } + + Overlay.modeless: Rectangle { + color: control.Universal.baseLowColor + } + + header: Label { + text: control.title + elide: Label.ElideRight + // TODO: QPlatformTheme::TitleBarFont + font.pixelSize: 20 + + leftPadding: 24 + rightPadding: 24 + topPadding: 18 + height: control.title.length > 0 ? implicitHeight : 0 + + background: Rectangle { + x: 1; y: 1 // // FlyoutBorderThemeThickness + color: control.Universal.chromeMediumLowColor + width: parent.width - 2 + height: parent.height - 1 + } + } + + contentItem: FontDialogContent { + id: content + rowSpacing: 12 + } + + footer: RowLayout { + id: rowLayout + spacing: 24 + + Label { + text: qsTr("Writing System") + + Layout.leftMargin: 24 + Layout.topMargin: 6 + Layout.bottomMargin: 24 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + Layout.topMargin: 6 + Layout.bottomMargin: 24 + + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + horizontalPadding: 0 + + Layout.rightMargin: 24 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialog.qml new file mode 100644 index 00000000000..56591904773 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialog.qml @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt.labs.folderlistmodel +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +import "." as DialogsImpl + +FileDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + leftPadding: 20 + rightPadding: 20 + // Ensure that the background's border is visible. + leftInset: -1 + rightInset: -1 + topInset: -1 + bottomInset: -1 + + standardButtons: T.Dialog.Open | T.Dialog.Cancel + + /* + We use attached properties because we want to handle logic in C++, and: + - We can't assume the footer only contains a DialogButtonBox (which would allow us + to connect up to it in QQuickFileDialogImpl); it also needs to hold a ComboBox + and therefore the root footer item will be e.g. a layout item instead. + - We don't want to create our own "FileDialogButtonBox" (in order to be able to handle the logic + in C++) because we'd need to copy (and hence duplicate code in) DialogButtonBox.qml. + */ + FileDialogImpl.buttonBox: buttonBox + FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox + FileDialogImpl.fileDialogListView: fileDialogListView + FileDialogImpl.breadcrumbBar: breadcrumbBar + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.palette.window + border.color: control.palette.dark + } + + header: Pane { + palette.window: control.palette.light + padding: 20 + + contentItem: Column { + spacing: 12 + + Label { + objectName: "dialogTitleBarLabel" + width: parent.width + text: control.title + visible: control.title.length > 0 + horizontalAlignment: Label.AlignHCenter + elide: Label.ElideRight + font.bold: true + } + + DialogsImpl.FolderBreadcrumbBar { + id: breadcrumbBar + width: parent.width + fileDialog: control + + KeyNavigation.tab: fileDialogListView + } + } + } + + contentItem: ListView { + id: fileDialogListView + objectName: "fileDialogListView" + clip: true + focus: true + boundsBehavior: Flickable.StopAtBounds + + ScrollBar.vertical: ScrollBar {} + + model: FolderListModel { + folder: control.currentFolder + nameFilters: control.selectedNameFilter.globs + showDirsFirst: true + sortCaseSensitive: false + } + delegate: DialogsImpl.FileDialogDelegate { + objectName: "fileDialogDelegate" + index + width: ListView.view.width + highlighted: ListView.isCurrentItem + fileDialog: control + fileDetailRowWidth: nameFiltersComboBox.width + + KeyNavigation.backtab: breadcrumbBar + KeyNavigation.tab: nameFiltersComboBox + } + } + + footer: Rectangle { + color: control.palette.light + implicitWidth: rowLayout.implicitWidth + implicitHeight: rowLayout.implicitHeight + + RowLayout { + id: rowLayout + width: parent.width + height: parent.height + spacing: 20 + + ComboBox { + // OK to use IDs here, since users shouldn't be overriding this stuff. + id: nameFiltersComboBox + model: control.nameFilters + + Layout.leftMargin: 20 + Layout.fillWidth: true + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + palette.window: control.palette.light + spacing: 12 + horizontalPadding: 0 + verticalPadding: 20 + + Layout.rightMargin: 20 + } + } + } + + Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialogDelegate.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialogDelegate.qml new file mode 100644 index 00000000000..03250faa7e1 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialogDelegate.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl as ControlsImpl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FileDialogDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 12 + spacing: 8 + topPadding: 0 + bottomPadding: 0 + + file: fileUrl + + icon.width: 16 + icon.height: 16 + icon.color: highlighted ? palette.highlightedText : palette.text + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/" + + (fileIsDir ? "folder" : "file") + "-icon-round.png" + + // We don't use index here, but in C++. Since we're using required + // properties, the index context property will not be injected, so we can't + // use its QQmlContext to access it. + required property int index + required property string fileName + required property url fileUrl + required property int fileSize + required property date fileModified + required property bool fileIsDir + + required property int fileDetailRowWidth + + contentItem: FileDialogDelegateLabel { + delegate: control + fileDetailRowTextColor: control.icon.color + fileDetailRowWidth: control.fileDetailRowWidth + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + visible: control.down || control.highlighted || control.visualFocus + color: Color.blend(control.down ? control.palette.midlight : control.palette.light, + control.palette.highlight, control.highlighted ? 0.15 : 0.0) + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialogDelegateLabel.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialogDelegateLabel.qml new file mode 100644 index 00000000000..9768cd51f00 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialogDelegateLabel.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +/* + Most of the elements in here are the same between styles, so we + have a reusable component for it and provide some properties to enable style-specific tweaks. +*/ +Item { + id: root + implicitWidth: column.implicitWidth + implicitHeight: column.implicitHeight + + required property DialogsQuickImpl.FileDialogDelegate delegate + required property int fileDetailRowWidth + + property color fileDetailRowTextColor + + Column { + id: column + y: (parent.height - height) / 2 + + Row { + spacing: root.delegate.spacing + + IconImage { + id: iconImage + source: root.delegate.icon.source + sourceSize: Qt.size(root.delegate.icon.width, root.delegate.icon.height) + width: root.delegate.icon.width + height: root.delegate.icon.height + color: root.delegate.icon.color + y: (parent.height - height) / 2 + } + Label { + text: root.delegate.fileName + color: root.delegate.icon.color + y: (parent.height - height) / 2 + } + } + + Item { + id: fileDetailRow + x: iconImage.width + root.delegate.spacing + width: fileDetailRowWidth - x - root.delegate.leftPadding + implicitHeight: childrenRect.height + + Label { + text: locale.formattedDataSize(root.delegate.fileSize) + font.pixelSize: root.delegate.font.pixelSize * 0.75 + color: root.fileDetailRowTextColor + } + Label { + text: Qt.formatDateTime(root.delegate.fileModified) + font.pixelSize: root.delegate.font.pixelSize * 0.75 + color: root.fileDetailRowTextColor + x: parent.width - width + } + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FolderBreadcrumbBar.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FolderBreadcrumbBar.qml new file mode 100644 index 00000000000..a1697c8fe26 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FolderBreadcrumbBar.qml @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FolderBreadcrumbBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + (upButton ? upButton.implicitWidth + upButtonSpacing : 0) + + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + upButtonSpacing: 20 + padding: 1 + + background: Rectangle { + border.color: control.palette.button + } + contentItem: ListView { + currentIndex: control.currentIndex + model: control.contentModel + orientation: ListView.Horizontal + snapMode: ListView.SnapToItem + highlightMoveDuration: 0 + interactive: false + clip: true + } + buttonDelegate: Button { + id: buttonDelegateRoot + text: folderName + flat: true + + // The default of 100 is a bit too wide for short directory names. + Binding { + target: buttonDelegateRoot.background + property: "implicitWidth" + value: 40 + } + + required property int index + required property string folderName + } + separatorDelegate: IconImage { + id: iconImage + source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/crumb-separator-icon-round.png" + sourceSize: Qt.size(8, 8) + width: 8 + height: control.contentItem.height + color: control.palette.button + y: (control.height - height) / 2 + } + upButton: ToolButton { + x: control.leftPadding + y: control.topPadding + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/up-icon-round.png" + icon.width: 16 + icon.height: 16 + width: height + focusPolicy: Qt.TabFocus + } + textField: TextField { + text: control.fileDialog.selectedFile + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialog.qml new file mode 100644 index 00000000000..e2caea40438 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialog.qml @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + implicitWidth: Math.max(control.implicitBackgroundWidth + control.leftInset + control.rightInset, + control.contentWidth + control.leftPadding + control.rightPadding, + control.implicitHeaderWidth, + control.implicitFooterWidth) + implicitHeight: Math.max(control.implicitBackgroundHeight + control.topInset + control.bottomInset, + control.contentHeight + control.topPadding + control.bottomPadding + + (control.implicitHeaderHeight > 0 ? control.implicitHeaderHeight + control.spacing : 0) + + (control.implicitFooterHeight > 0 ? control.implicitFooterHeight + control.spacing : 0)) + + leftPadding: 20 + rightPadding: 20 + // Ensure that the background's border is visible. + leftInset: -1 + rightInset: -1 + topInset: -1 + bottomInset: -1 + + spacing: 12 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.palette.window + border.color: control.palette.dark + } + + Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } + + header: Pane { + palette.window: control.palette.light + padding: 20 + + contentItem: Label { + width: parent.width + text: control.title + visible: control.title.length > 0 + horizontalAlignment: Label.AlignHCenter + elide: Label.ElideRight + font.bold: true + } + } + + contentItem: FontDialogContent { + id: content + } + + footer: Rectangle { + color: control.palette.light + implicitWidth: rowLayout.implicitWidth + implicitHeight: rowLayout.implicitHeight + + RowLayout { + id: rowLayout + width: parent.width + height: parent.height + spacing: 20 + + Label { + text: qsTr("Writing System") + + Layout.leftMargin: 20 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + palette.window: control.palette.light + spacing: 12 + horizontalPadding: 0 + verticalPadding: 20 + + Layout.rightMargin: 20 + } + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialogContent.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialogContent.qml new file mode 100644 index 00000000000..f0d5020adf0 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialogContent.qml @@ -0,0 +1,267 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts + +GridLayout { + property alias familyListView: fontFamilyListView + property alias styleListView: fontStyleListView + property alias sizeListView: fontSizeListView + property alias sampleEdit: fontSample + property alias underline: fontUnderline + property alias strikeout: fontStrikeout + property alias familyEdit: fontFamilyEdit + property alias styleEdit: fontStyleEdit + property alias sizeEdit: fontSizeEdit + + columns: 3 + + ColumnLayout { + spacing: 0 + + Layout.preferredWidth: 50 + + Label { + text: qsTr("Family") + Layout.alignment: Qt.AlignLeft + } + TextField { + id: fontFamilyEdit + objectName: "familyEdit" + readOnly: true + Layout.fillWidth: true + focus: true + } + Frame { + Layout.fillWidth: true + Layout.fillHeight: true + background: Rectangle { + color: "white" + } + ListView { + id: fontFamilyListView + objectName: "familyListView" + implicitHeight: 200 + anchors.fill: parent + clip: true + + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AlwaysOn + } + + boundsBehavior: Flickable.StopAtBounds + + highlightMoveVelocity: -1 + highlightMoveDuration: 1 + highlightFollowsCurrentItem: true + keyNavigationEnabled: true + + delegate: ItemDelegate { + width: ListView.view.width + highlighted: ListView.isCurrentItem + onClicked: () => fontFamilyListView.currentIndex = index + text: modelData + } + } + } + } + + ColumnLayout { + spacing: 0 + + Layout.preferredWidth: 30 + + Label { + text: qsTr("Style") + Layout.alignment: Qt.AlignLeft + } + TextField { + id: fontStyleEdit + objectName: "styleEdit" + readOnly: true + Layout.fillWidth: true + } + Frame { + Layout.fillWidth: true + Layout.fillHeight: true + background: Rectangle { + color: "white" + } + ListView { + id: fontStyleListView + objectName: "styleListView" + implicitHeight: 200 + anchors.fill: parent + clip: true + + ScrollBar.vertical: ScrollBar {} + boundsBehavior: Flickable.StopAtBounds + + highlightMoveVelocity: -1 + highlightMoveDuration: 1 + highlightFollowsCurrentItem: true + keyNavigationEnabled: true + + delegate: ItemDelegate { + width: ListView.view.width + highlighted: ListView.isCurrentItem + onClicked: () => fontStyleListView.currentIndex = index + text: modelData + } + } + } + } + + ColumnLayout { + spacing: 0 + + Layout.preferredWidth: 20 + + Label { + text: qsTr("Size") + Layout.alignment: Qt.AlignLeft + } + TextField { + id: fontSizeEdit + objectName: "sizeEdit" + Layout.fillWidth: true + validator: IntValidator { + bottom: 1 + top: 512 + } + } + Frame { + Layout.fillWidth: true + Layout.fillHeight: true + + background: Rectangle { + color: "white" + } + ListView { + id: fontSizeListView + objectName: "sizeListView" + implicitHeight: 200 + anchors.fill: parent + clip: true + + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AlwaysOn + } + + boundsBehavior: Flickable.StopAtBounds + + highlightMoveVelocity: -1 + highlightMoveDuration: 1 + highlightFollowsCurrentItem: true + keyNavigationEnabled: true + + delegate: ItemDelegate { + width: ListView.view.width + highlighted: ListView.isCurrentItem + onClicked: () => fontSizeListView.currentIndex = index + text: modelData + } + } + } + } + + ColumnLayout { + Layout.preferredWidth: 80 + + GroupBox { + id: effectsGroupBox + title: qsTr("Effects") + + Layout.fillWidth: true + Layout.fillHeight: true + + label: Label { + anchors.left: effectsGroupBox.left + text: parent.title + } + + RowLayout { + anchors.fill: parent + CheckBox { + id: fontUnderline + objectName: "underlineEffect" + text: qsTr("Underline") + } + CheckBox{ + id: fontStrikeout + objectName: "strikeoutEffect" + text: qsTr("Strikeout") + } + } + } + } + + GroupBox { + id: sample + padding: label.implicitHeight + title: qsTr("Sample") + + Layout.fillWidth: true + Layout.preferredWidth: 80 + Layout.fillHeight: true + Layout.columnSpan: 2 + clip: true + + background: Rectangle { + y: sample.topPadding - sample.bottomPadding + width: sample.width - sample.leftPadding + sample.rightPadding + height: sample.height - sample.topPadding + sample.bottomPadding + radius: 3 + } + + label: Label { + anchors.left: sample.left + text: sample.title + } + + TextEdit { + id: fontSample + objectName: "sampleEdit" + anchors.centerIn: parent + readOnly: true + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory.cpp new file mode 100644 index 00000000000..da298432b40 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickdialogimplfactory_p.h" + +#include <QtCore/qloggingcategory.h> + +#include "qquickplatformfiledialog_p.h" +#include "qquickplatformfontdialog_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \internal + + Creates concrete QML-based dialogs. +*/ + +Q_LOGGING_CATEGORY(lcQuickDialogImplFactory, "qt.quick.dialogs.quickdialogimplfactory") + +QPlatformDialogHelper *QQuickDialogImplFactory::createPlatformDialogHelper( + QPlatformTheme::DialogType type, QObject *parent) +{ + switch (type) { + case QPlatformTheme::FileDialog: { + auto dialog = new QQuickPlatformFileDialog(parent); + // If the QML file failed to load, we need to handle it gracefully. + if (!dialog->isValid()) { + delete dialog; + return nullptr; + } + + return dialog; + } + case QPlatformTheme::FontDialog: { + auto dialog = new QQuickPlatformFontDialog(parent); + + if (!dialog->isValid()) { + delete dialog; + return nullptr; + } + return dialog; + } + default: + break; + } + + return nullptr; +} + +QT_END_NAMESPACE diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory_p.h new file mode 100644 index 00000000000..54aa921f30e --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory_p.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKQMLDIALOGFACTORY_P_H +#define QQUICKQMLDIALOGFACTORY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtGui/qpa/qplatformtheme.h> + +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickDialogImplFactory +{ +public: + static QPlatformDialogHelper *createPlatformDialogHelper(QPlatformTheme::DialogType type, + QObject *parent); +}; + +QT_END_NAMESPACE + +#endif // QQUICKQMLDIALOGFACTORY_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogdelegate.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogdelegate.cpp new file mode 100644 index 00000000000..b1d4477305d --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogdelegate.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfiledialogdelegate_p.h" + +#include <QtCore/qfileinfo.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtQml/QQmlFile> +#include <QtQml/qqmlexpression.h> +#include <QtQuick/private/qquicklistview_p.h> +#include <QtQuickTemplates2/private/qquickitemdelegate_p_p.h> + +#include "qquickfiledialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFileDialogDelegatePrivate : public QQuickItemDelegatePrivate +{ + Q_DECLARE_PUBLIC(QQuickFileDialogDelegate) + +public: + void highlightFile(); + void chooseFile(); + + bool acceptKeyClick(Qt::Key key) const override; + + QQuickFileDialogImpl *fileDialog = nullptr; + QUrl file; +}; + +void QQuickFileDialogDelegatePrivate::highlightFile() +{ + Q_Q(QQuickFileDialogDelegate); + QQuickListViewAttached *attached = static_cast<QQuickListViewAttached*>( + qmlAttachedPropertiesObject<QQuickListView>(q)); + if (!attached) + return; + + QQmlContext *delegateContext = qmlContext(q); + if (!delegateContext) + return; + + bool converted = false; + const int index = q->property("index").toInt(&converted); + if (converted) { + attached->view()->setCurrentIndex(index); + fileDialog->setCurrentFile(file); + } +} + +void QQuickFileDialogDelegatePrivate::chooseFile() +{ + const QFileInfo fileInfo(QQmlFile::urlToLocalFileOrQrc(file)); + if (fileInfo.isDir()) { + // If it's a directory, navigate to it. + fileDialog->setCurrentFolder(file); + } else { + // Otherwise it's a file, so select it and close the dialog. + fileDialog->setSelectedFile(file); + fileDialog->accept(); + } +} + +bool QQuickFileDialogDelegatePrivate::acceptKeyClick(Qt::Key key) const +{ + return key == Qt::Key_Return || key == Qt::Key_Enter; +} + +QQuickFileDialogDelegate::QQuickFileDialogDelegate(QQuickItem *parent) + : QQuickItemDelegate(*(new QQuickFileDialogDelegatePrivate), parent) +{ + Q_D(QQuickFileDialogDelegate); + // Clicking and tabbing should result in it getting focus, + // as e.g. Ubuntu and Windows both allow tabbing through file dialogs. + setFocusPolicy(Qt::StrongFocus); + setCheckable(true); + QObjectPrivate::connect(this, &QQuickFileDialogDelegate::clicked, + d, &QQuickFileDialogDelegatePrivate::highlightFile); + QObjectPrivate::connect(this, &QQuickFileDialogDelegate::doubleClicked, + d, &QQuickFileDialogDelegatePrivate::chooseFile); +} + +QQuickFileDialogImpl *QQuickFileDialogDelegate::fileDialog() const +{ + Q_D(const QQuickFileDialogDelegate); + return d->fileDialog; +} + +void QQuickFileDialogDelegate::setFileDialog(QQuickFileDialogImpl *fileDialog) +{ + Q_D(QQuickFileDialogDelegate); + if (fileDialog == d->fileDialog) + return; + + d->fileDialog = fileDialog; + emit fileDialogChanged(); +} + +QUrl QQuickFileDialogDelegate::file() const +{ + Q_D(const QQuickFileDialogDelegate); + return d->file; +} + +void QQuickFileDialogDelegate::setFile(const QUrl &file) +{ + Q_D(QQuickFileDialogDelegate); + if (file == d->file) + return; + + d->file = file; + emit fileChanged(); +} + +void QQuickFileDialogDelegate::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QQuickFileDialogDelegate); + // We need to respond to being triggered by enter being pressed, + // but we can't use event->isAccepted() to check, because events are pre-accepted. + auto connection = QObjectPrivate::connect(this, &QQuickFileDialogDelegate::clicked, + d, &QQuickFileDialogDelegatePrivate::chooseFile); + + QQuickItemDelegate::keyReleaseEvent(event); + + disconnect(connection); +} + +QT_END_NAMESPACE + +#include "moc_qquickfiledialogdelegate_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogdelegate_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogdelegate_p.h new file mode 100644 index 00000000000..093e27bdbdd --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogdelegate_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFILEDIALOGDELEGATE_P_H +#define QQUICKFILEDIALOGDELEGATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickitemdelegate_p.h> + +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFileDialogImpl; +class QQuickFileDialogDelegatePrivate; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFileDialogDelegate : public QQuickItemDelegate +{ + Q_OBJECT + Q_PROPERTY(QQuickFileDialogImpl *fileDialog READ fileDialog WRITE setFileDialog NOTIFY fileDialogChanged) + Q_PROPERTY(QUrl file READ file WRITE setFile NOTIFY fileChanged) + QML_NAMED_ELEMENT(FileDialogDelegate) + QML_ADDED_IN_VERSION(6, 2) + +public: + explicit QQuickFileDialogDelegate(QQuickItem *parent = nullptr); + + QQuickFileDialogImpl *fileDialog() const; + void setFileDialog(QQuickFileDialogImpl *fileDialog); + + QUrl file() const; + void setFile(const QUrl &file); + +Q_SIGNALS: + void fileDialogChanged(); + void fileChanged(); + +protected: + void keyReleaseEvent(QKeyEvent *event) override; + +private: + Q_DISABLE_COPY(QQuickFileDialogDelegate) + Q_DECLARE_PRIVATE(QQuickFileDialogDelegate) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFileDialogDelegate) + +#endif // QQUICKFILEDIALOGDELEGATE_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl.cpp new file mode 100644 index 00000000000..fd1ad440684 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl.cpp @@ -0,0 +1,574 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfiledialogimpl_p.h" +#include "qquickfiledialogimpl_p_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtQml/qqmlinfo.h> +#include <QtQml/qqmlfile.h> +#include <QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p_p.h> +#include <QtQuickTemplates2/private/qquickpopupitem_p_p.h> +#include "qquickfiledialogdelegate_p.h" +#include "qquickfolderbreadcrumbbar_p.h" + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcCurrentFolder, "qt.quick.dialogs.quickfiledialogimpl.currentFolder") +Q_LOGGING_CATEGORY(lcOptions, "qt.quick.dialogs.quickfiledialogimpl.options") +Q_LOGGING_CATEGORY(lcNameFilters, "qt.quick.dialogs.quickfiledialogimpl.namefilters") +Q_LOGGING_CATEGORY(lcAttachedNameFilters, "qt.quick.dialogs.quickfiledialogimplattached.namefilters") + +QQuickFileDialogImplPrivate::QQuickFileDialogImplPrivate() +{ +} + +void QQuickFileDialogImplPrivate::setNameFilters(const QStringList &filters) +{ + Q_Q(QQuickFileDialogImpl); + if (filters == nameFilters) + return; + + nameFilters = filters; + emit q->nameFiltersChanged(); +} + +void QQuickFileDialogImplPrivate::updateEnabled() +{ + Q_Q(QQuickFileDialogImpl); + QQuickFileDialogImplAttached *attached = attachedOrWarn(); + if (!attached) + return; + + auto openButton = attached->buttonBox()->standardButton(QPlatformDialogHelper::Open); + if (!openButton) { + qmlWarning(q).nospace() << "Can't update Open button's enabled state because it wasn't found"; + return; + } + + openButton->setEnabled(!currentFile.isEmpty() && attached->breadcrumbBar() + && !attached->breadcrumbBar()->textField()->isVisible()); +} + +/*! + \internal + + Ensures that a file is always selected after a change in \c folder. + + \a oldFolderPath is the previous value of \c folder. +*/ +void QQuickFileDialogImplPrivate::updateCurrentFile(const QString &oldFolderPath) +{ + Q_Q(QQuickFileDialogImpl); + QQuickFileDialogImplAttached *attached = attachedOrWarn(); + if (!attached || !attached->fileDialogListView()) + return; + + QString newCurrentFilePath; + int newCurrentFileIndex = 0; + const QString newFolderPath = QQmlFile::urlToLocalFileOrQrc(currentFolder); + if (!oldFolderPath.isEmpty() && !newFolderPath.isEmpty()) { + // If the user went up a directory (or several), we should set + // currentFile to be the directory that we were in (or + // its closest ancestor that is a child of the new directory). + // E.g. if oldFolderPath is /foo/bar/baz/abc/xyz, and newFolderPath is /foo/bar, + // then we want to set currentFile to be /foo/bar/baz. + const int indexOfFolder = oldFolderPath.indexOf(newFolderPath); + if (indexOfFolder != -1) { + // [folder] + // [ oldFolderPath ] + // /foo/bar/baz/abc/xyz + // [rel...Paths] + QStringList relativePaths = oldFolderPath.mid(indexOfFolder + newFolderPath.size()).split(QLatin1Char('/'), Qt::SkipEmptyParts); + newCurrentFilePath = newFolderPath + QLatin1Char('/') + relativePaths.first(); + + // Now find the index of that directory so that we can set the ListView's currentIndex to it. + const QDir newFolderDir(newFolderPath); + // Just to be safe... + if (!newFolderDir.exists()) { + qmlWarning(q) << "Directory" << newCurrentFilePath << "doesn't exist; can't get a file entry list for it"; + return; + } + + const QFileInfoList dirs = newFolderDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::DirsFirst); + const QFileInfo newCurrentFileInfo(newCurrentFilePath); + // The directory can contain files, but since we put dirs first, that should never affect the indices. + newCurrentFileIndex = dirs.indexOf(newCurrentFileInfo); + } + } + + if (newCurrentFilePath.isEmpty()) { + // When entering into a directory that isn't a parent of the old one, the first + // file delegate should be selected. + // TODO: is there a cheaper way to do this? QDirIterator doesn't support sorting, + // so we can't use that. QQuickFolderListModel uses threads to fetch its data, + // so should be considered asynchronous. We might be able to use it, but it would + // complicate the code even more... + QDir newFolderDir(newFolderPath); + if (newFolderDir.exists()) { + const QFileInfoList files = newFolderDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::DirsFirst); + if (!files.isEmpty()) + newCurrentFilePath = files.first().absoluteFilePath(); + } + } + + if (!newCurrentFilePath.isEmpty()) { + q->setCurrentFile(QUrl::fromLocalFile(newCurrentFilePath)); + { + // Set the appropriate currentIndex for the selected file. We block signals from ListView + // because we don't want fileDialogListViewCurrentIndexChanged to be called, as the file + // it gets from the delegate will not be up-to-date (but most importantly because we already + // just set the selected file). + QSignalBlocker blocker(attached->fileDialogListView()); + attached->fileDialogListView()->setCurrentIndex(newCurrentFileIndex); + attached->fileDialogListView()->positionViewAtIndex(newCurrentFileIndex, QQuickListView::Center); + } + if (QQuickItem *currentItem = attached->fileDialogListView()->currentItem()) + currentItem->forceActiveFocus(); + } +} + +void QQuickFileDialogImplPrivate::handleAccept() +{ + // Let handleClick take care of calling accept(). +} + +void QQuickFileDialogImplPrivate::handleClick(QQuickAbstractButton *button) +{ + Q_Q(QQuickFileDialogImpl); + if (buttonRole(button) == QPlatformDialogHelper::AcceptRole && currentFile.isValid()) { + // The "Open" button was clicked, so we need to set the file to the current file, if any. + const QFileInfo fileInfo(currentFile.toLocalFile()); + if (fileInfo.isDir()) { + // If it's a directory, navigate to it. + q->setCurrentFolder(currentFile); + // Don't call accept(), because selecting a folder != accepting the dialog. + } else { + // Otherwise it's a file, so select it and close the dialog. + q->setSelectedFile(currentFile); + q->accept(); + QQuickDialogPrivate::handleClick(button); + emit q->fileSelected(currentFile); + } + } +} + +QQuickFileDialogImpl::QQuickFileDialogImpl(QObject *parent) + : QQuickDialog(*(new QQuickFileDialogImplPrivate), parent) +{ +} + +QQuickFileDialogImplAttached *QQuickFileDialogImpl::qmlAttachedProperties(QObject *object) +{ + return new QQuickFileDialogImplAttached(object); +} + +QUrl QQuickFileDialogImpl::currentFolder() const +{ + Q_D(const QQuickFileDialogImpl); + return d->currentFolder; +} + +void QQuickFileDialogImpl::setCurrentFolder(const QUrl ¤tFolder) +{ + qCDebug(lcCurrentFolder) << "setCurrentFolder called with" << currentFolder; + Q_D(QQuickFileDialogImpl); + if (currentFolder == d->currentFolder) + return; + + const QString oldFolderPath = QQmlFile::urlToLocalFileOrQrc(d->currentFolder); + + d->currentFolder = currentFolder; + // Since the directory changed, the old file can no longer be selected. + setCurrentFile(QUrl()); + d->updateCurrentFile(oldFolderPath); + emit currentFolderChanged(d->currentFolder); +} + +QUrl QQuickFileDialogImpl::selectedFile() const +{ + Q_D(const QQuickFileDialogImpl); + return d->selectedFile; +} + +void QQuickFileDialogImpl::setSelectedFile(const QUrl &selectedFile) +{ + Q_D(QQuickFileDialogImpl); + if (selectedFile == d->selectedFile) + return; + + d->selectedFile = selectedFile; + emit selectedFileChanged(); +} + +QUrl QQuickFileDialogImpl::currentFile() const +{ + Q_D(const QQuickFileDialogImpl); + return d->currentFile; +} + +void QQuickFileDialogImpl::setCurrentFile(const QUrl ¤tFile) +{ + Q_D(QQuickFileDialogImpl); + if (currentFile == d->currentFile) + return; + + d->currentFile = currentFile; + d->updateEnabled(); + emit currentFileChanged(d->currentFile); +} + +QSharedPointer<QFileDialogOptions> QQuickFileDialogImpl::options() const +{ + Q_D(const QQuickFileDialogImpl); + return d->options; +} + +void QQuickFileDialogImpl::setOptions(const QSharedPointer<QFileDialogOptions> &options) +{ + qCDebug(lcOptions).nospace() << "setOptions called with:" + << " acceptMode=" << options->acceptMode() + << " fileMode=" << options->fileMode() + << " initialDirectory=" << options->initialDirectory() + << " nameFilters=" << options->nameFilters() + << " initiallySelectedNameFilter=" << options->initiallySelectedNameFilter(); + + Q_D(QQuickFileDialogImpl); + d->options = options; + + if (d->options) { + d->selectedNameFilter->setOptions(options); + d->setNameFilters(options->nameFilters()); + } +} + +/*! + \internal + + The list of user-facing strings describing the available file filters. +*/ +QStringList QQuickFileDialogImpl::nameFilters() const +{ + Q_D(const QQuickFileDialogImpl); + return d->options ? d->options->nameFilters() : QStringList(); +} + +void QQuickFileDialogImpl::resetNameFilters() +{ + Q_D(QQuickFileDialogImpl); + d->setNameFilters(QStringList()); +} + +QQuickFileNameFilter *QQuickFileDialogImpl::selectedNameFilter() const +{ + Q_D(const QQuickFileDialogImpl); + if (!d->selectedNameFilter) { + QQuickFileDialogImpl *that = const_cast<QQuickFileDialogImpl *>(this); + d->selectedNameFilter = new QQuickFileNameFilter(that); + if (d->options) + d->selectedNameFilter->setOptions(d->options); + } + return d->selectedNameFilter; +} + +/*! + \internal + + These allow QQuickPlatformFileDialog::show() to set custom labels on the + dialog buttons without having to know about/go through QQuickFileDialogImplAttached + and QQuickDialogButtonBox. +*/ +void QQuickFileDialogImpl::setAcceptLabel(const QString &label) +{ + Q_D(QQuickFileDialogImpl); + d->acceptLabel = label; + QQuickFileDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + auto acceptButton = attached->buttonBox()->standardButton(QPlatformDialogHelper::Open); + if (!acceptButton) { + qmlWarning(this).nospace() << "Can't set accept label to " << label + << "; failed to find Open button in DialogButtonBox of " << this; + return; + } + + acceptButton->setText(!label.isEmpty() + ? label : QQuickDialogButtonBoxPrivate::buttonText(QPlatformDialogHelper::Open)); +} + +void QQuickFileDialogImpl::setRejectLabel(const QString &label) +{ + Q_D(QQuickFileDialogImpl); + d->rejectLabel = label; + QQuickFileDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + auto rejectButton = attached->buttonBox()->standardButton(QPlatformDialogHelper::Cancel); + if (!rejectButton) { + qmlWarning(this).nospace() << "Can't set reject label to " << label + << "; failed to find Open button in DialogButtonBox of " << this; + return; + } + + rejectButton->setText(!label.isEmpty() + ? label : QQuickDialogButtonBoxPrivate::buttonText(QPlatformDialogHelper::Cancel)); +} + +void QQuickFileDialogImpl::selectNameFilter(const QString &filter) +{ + qCDebug(lcNameFilters) << "selectNameFilter called with" << filter; + Q_D(QQuickFileDialogImpl); + d->selectedNameFilter->update(filter); + emit filterSelected(filter); +} + +void QQuickFileDialogImpl::componentComplete() +{ + Q_D(QQuickFileDialogImpl); + QQuickDialog::componentComplete(); + + // Find the right-most button and set its key navigation so that + // tab moves focus to the breadcrumb bar's up button. I tried + // doing this via KeyNavigation on the DialogButtonBox in QML, + // but it didn't work (probably because it's not the right item). + QQuickFileDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + const int buttonCount = attached->buttonBox()->count(); + if (buttonCount == 0) + return; + + QQuickAbstractButton *rightMostButton = qobject_cast<QQuickAbstractButton *>( + attached->buttonBox()->itemAt(buttonCount - 1)); + if (!rightMostButton) { + qmlWarning(this) << "Can't find right-most button in DialogButtonBox"; + return; + } + + auto keyNavigationAttached = QQuickKeyNavigationAttached::qmlAttachedProperties(rightMostButton); + if (!keyNavigationAttached) { + qmlWarning(this) << "Can't create attached KeyNavigation object on" << QDebug::toString(rightMostButton); + return; + } + + keyNavigationAttached->setTab(attached->breadcrumbBar()->upButton()); +} + +void QQuickFileDialogImpl::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + Q_D(QQuickFileDialogImpl); + QQuickDialog::itemChange(change, data); + + if (change != QQuickItem::ItemVisibleHasChanged || !isComponentComplete() || !data.boolValue) + return; + + QQuickFileDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + attached->fileDialogListView()->forceActiveFocus(); + d->updateEnabled(); +} + +QQuickFileDialogImplAttached *QQuickFileDialogImplPrivate::attachedOrWarn() +{ + Q_Q(QQuickFileDialogImpl); + QQuickFileDialogImplAttached *attached = static_cast<QQuickFileDialogImplAttached*>( + qmlAttachedPropertiesObject<QQuickFileDialogImpl>(q)); + if (!attached) + qmlWarning(q) << "Expected FileDialogImpl attached object to be present on" << this; + return attached; +} + +void QQuickFileDialogImplAttachedPrivate::nameFiltersComboBoxItemActivated(int index) +{ + qCDebug(lcAttachedNameFilters) << "nameFiltersComboBoxItemActivated called with" << index; + auto fileDialogImpl = qobject_cast<QQuickFileDialogImpl*>(parent); + if (!fileDialogImpl) + return; + + fileDialogImpl->selectNameFilter(nameFiltersComboBox->textAt(index)); +} + +void QQuickFileDialogImplAttachedPrivate::fileDialogListViewCurrentIndexChanged() +{ + auto fileDialogImpl = qobject_cast<QQuickFileDialogImpl*>(parent); + if (!fileDialogImpl) + return; + + auto fileDialogDelegate = qobject_cast<QQuickFileDialogDelegate*>(fileDialogListView->currentItem()); + if (!fileDialogDelegate) + return; + + fileDialogImpl->setCurrentFile(fileDialogDelegate->file()); +} + +QQuickFileDialogImplAttached::QQuickFileDialogImplAttached(QObject *parent) + : QObject(*(new QQuickFileDialogImplAttachedPrivate), parent) +{ + if (!qobject_cast<QQuickFileDialogImpl*>(parent)) { + qmlWarning(this) << "FileDialogImpl attached properties should only be " + << "accessed through the root FileDialogImpl instance"; + } +} + +QQuickDialogButtonBox *QQuickFileDialogImplAttached::buttonBox() const +{ + Q_D(const QQuickFileDialogImplAttached); + return d->buttonBox; +} + +void QQuickFileDialogImplAttached::setButtonBox(QQuickDialogButtonBox *buttonBox) +{ + Q_D(QQuickFileDialogImplAttached); + if (buttonBox == d->buttonBox) + return; + + if (d->buttonBox) { + QQuickFileDialogImpl *fileDialogImpl = qobject_cast<QQuickFileDialogImpl*>(parent()); + if (fileDialogImpl) { + auto dialogPrivate = QQuickDialogPrivate::get(fileDialogImpl); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::accepted, + dialogPrivate, &QQuickDialogPrivate::handleAccept); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::rejected, + dialogPrivate, &QQuickDialogPrivate::handleReject); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::clicked, + dialogPrivate, &QQuickDialogPrivate::handleClick); + } + } + + d->buttonBox = buttonBox; + + if (buttonBox) { + QQuickFileDialogImpl *fileDialogImpl = qobject_cast<QQuickFileDialogImpl*>(parent()); + if (fileDialogImpl) { + auto dialogPrivate = QQuickDialogPrivate::get(fileDialogImpl); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::accepted, + dialogPrivate, &QQuickDialogPrivate::handleAccept); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::rejected, + dialogPrivate, &QQuickDialogPrivate::handleReject); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::clicked, + dialogPrivate, &QQuickDialogPrivate::handleClick); + } + } + + emit buttonBoxChanged(); +} + +QQuickComboBox *QQuickFileDialogImplAttached::nameFiltersComboBox() const +{ + Q_D(const QQuickFileDialogImplAttached); + return d->nameFiltersComboBox; +} + +void QQuickFileDialogImplAttached::setNameFiltersComboBox(QQuickComboBox *nameFiltersComboBox) +{ + Q_D(QQuickFileDialogImplAttached); + if (nameFiltersComboBox == d->nameFiltersComboBox) + return; + + d->nameFiltersComboBox = nameFiltersComboBox; + + QObjectPrivate::connect(d->nameFiltersComboBox, &QQuickComboBox::activated, + d, &QQuickFileDialogImplAttachedPrivate::nameFiltersComboBoxItemActivated); + + emit nameFiltersComboBoxChanged(); +} + +QString QQuickFileDialogImplAttached::selectedNameFilter() const +{ + Q_D(const QQuickFileDialogImplAttached); + return d->nameFiltersComboBox ? d->nameFiltersComboBox->currentText() : QString(); +} + +void QQuickFileDialogImplAttached::selectNameFilter(const QString &filter) +{ + Q_D(QQuickFileDialogImplAttached); + qCDebug(lcAttachedNameFilters) << "selectNameFilter called with" << filter; + if (!d->nameFiltersComboBox) + return; + + const int indexInComboBox = d->nameFiltersComboBox->find(filter); + if (indexInComboBox == -1) + return; + + qCDebug(lcAttachedNameFilters) << "setting ComboBox's currentIndex to" << indexInComboBox; + d->nameFiltersComboBox->setCurrentIndex(indexInComboBox); +} + +QQuickListView *QQuickFileDialogImplAttached::fileDialogListView() const +{ + Q_D(const QQuickFileDialogImplAttached); + return d->fileDialogListView; +} + +void QQuickFileDialogImplAttached::setFileDialogListView(QQuickListView *fileDialogListView) +{ + Q_D(QQuickFileDialogImplAttached); + if (fileDialogListView == d->fileDialogListView) + return; + + d->fileDialogListView = fileDialogListView; + + QObjectPrivate::connect(d->fileDialogListView, &QQuickListView::currentIndexChanged, + d, &QQuickFileDialogImplAttachedPrivate::fileDialogListViewCurrentIndexChanged); + + emit fileDialogListViewChanged(); +} + +QQuickFolderBreadcrumbBar *QQuickFileDialogImplAttached::breadcrumbBar() const +{ + Q_D(const QQuickFileDialogImplAttached); + return d->breadcrumbBar; +} + +void QQuickFileDialogImplAttached::setBreadcrumbBar(QQuickFolderBreadcrumbBar *breadcrumbBar) +{ + Q_D(QQuickFileDialogImplAttached); + if (breadcrumbBar == d->breadcrumbBar) + return; + + d->breadcrumbBar = breadcrumbBar; + emit breadcrumbBarChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qquickfiledialogimpl_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p.h new file mode 100644 index 00000000000..23f8cf14a4a --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p.h @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFILEDIALOGIMPL_P_H +#define QQUICKFILEDIALOGIMPL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquicklistview_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> + +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickComboBox; +class QQuickDialogButtonBox; + +class QQuickFileDialogImplAttached; +class QQuickFileDialogImplAttachedPrivate; +class QQuickFileDialogImplPrivate; +class QQuickFileNameFilter; +class QQuickFolderBreadcrumbBar; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFileDialogImpl : public QQuickDialog +{ + Q_OBJECT + Q_PROPERTY(QUrl currentFolder READ currentFolder WRITE setCurrentFolder NOTIFY currentFolderChanged FINAL) + Q_PROPERTY(QUrl selectedFile READ selectedFile WRITE setSelectedFile NOTIFY selectedFileChanged FINAL) + Q_PROPERTY(QUrl currentFile READ currentFile WRITE setCurrentFile NOTIFY currentFileChanged FINAL) + Q_PROPERTY(QStringList nameFilters READ nameFilters NOTIFY nameFiltersChanged FINAL) + Q_PROPERTY(QQuickFileNameFilter *selectedNameFilter READ selectedNameFilter CONSTANT) + QML_NAMED_ELEMENT(FileDialogImpl) + QML_ATTACHED(QQuickFileDialogImplAttached) + QML_ADDED_IN_VERSION(6, 2) + Q_MOC_INCLUDE(<QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h>) + Q_MOC_INCLUDE(<QtQuickDialogs2QuickImpl/private/qquickfolderbreadcrumbbar_p.h>) + +public: + explicit QQuickFileDialogImpl(QObject *parent = nullptr); + + static QQuickFileDialogImplAttached *qmlAttachedProperties(QObject *object); + + QUrl currentFolder() const; + void setCurrentFolder(const QUrl ¤tFolder); + + QUrl selectedFile() const; + void setSelectedFile(const QUrl &file); + + QUrl currentFile() const; + void setCurrentFile(const QUrl ¤tFile); + + QSharedPointer<QFileDialogOptions> options() const; + void setOptions(const QSharedPointer<QFileDialogOptions> &options); + + QStringList nameFilters() const; + void resetNameFilters(); + + QQuickFileNameFilter *selectedNameFilter() const; + + void setAcceptLabel(const QString &label); + void setRejectLabel(const QString &label); + +public Q_SLOTS: + void selectNameFilter(const QString &filter); + +Q_SIGNALS: + void currentFolderChanged(const QUrl &folderUrl); + void selectedFileChanged(); + void currentFileChanged(const QUrl ¤tFileUrl); + void nameFiltersChanged(); + void fileSelected(const QUrl &fileUrl); + void filterSelected(const QString &filter); + +private: + void componentComplete() override; + void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) override; + + Q_DISABLE_COPY(QQuickFileDialogImpl) + Q_DECLARE_PRIVATE(QQuickFileDialogImpl) +}; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFileDialogImplAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickDialogButtonBox *buttonBox READ buttonBox WRITE setButtonBox NOTIFY buttonBoxChanged FINAL) + Q_PROPERTY(QQuickComboBox *nameFiltersComboBox READ nameFiltersComboBox WRITE setNameFiltersComboBox NOTIFY nameFiltersComboBoxChanged) + Q_PROPERTY(QQuickListView *fileDialogListView READ fileDialogListView WRITE setFileDialogListView NOTIFY fileDialogListViewChanged) + Q_PROPERTY(QQuickFolderBreadcrumbBar *breadcrumbBar READ breadcrumbBar WRITE setBreadcrumbBar NOTIFY breadcrumbBarChanged) + Q_MOC_INCLUDE(<QtQuickTemplates2/private/qquickdialogbuttonbox_p.h>) + Q_MOC_INCLUDE(<QtQuickTemplates2/private/qquickcombobox_p.h>) + +public: + explicit QQuickFileDialogImplAttached(QObject *parent = nullptr); + + QQuickDialogButtonBox *buttonBox() const; + void setButtonBox(QQuickDialogButtonBox *buttonBox); + + QQuickComboBox *nameFiltersComboBox() const; + void setNameFiltersComboBox(QQuickComboBox *nameFiltersComboBox); + + QString selectedNameFilter() const; + void selectNameFilter(const QString &filter); + + QQuickListView *fileDialogListView() const; + void setFileDialogListView(QQuickListView *fileDialogListView); + + QQuickFolderBreadcrumbBar *breadcrumbBar() const; + void setBreadcrumbBar(QQuickFolderBreadcrumbBar *breadcrumbBar); + +Q_SIGNALS: + void buttonBoxChanged(); + void nameFiltersComboBoxChanged(); + void fileDialogListViewChanged(); + void breadcrumbBarChanged(); + +private: + Q_DISABLE_COPY(QQuickFileDialogImplAttached) + Q_DECLARE_PRIVATE(QQuickFileDialogImplAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFileDialogImpl) + +#endif // QQUICKFILEDIALOGIMPL_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p_p.h new file mode 100644 index 00000000000..1831a7dc58a --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFILEDIALOG_P_P_H +#define QQUICKFILEDIALOG_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h> + +#include "qquickfiledialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFileNameFilter; + +class QQuickFileDialogImplPrivate : public QQuickDialogPrivate +{ + Q_DECLARE_PUBLIC(QQuickFileDialogImpl) + +public: + QQuickFileDialogImplPrivate(); + + static QQuickFileDialogImplPrivate *get(QQuickFileDialogImpl *dialog) + { + return dialog->d_func(); + } + + QQuickFileDialogImplAttached *attachedOrWarn(); + + void setNameFilters(const QStringList &filters); + + void updateEnabled(); + void updateCurrentFile(const QString &oldFolderPath); + + void handleAccept() override; + void handleClick(QQuickAbstractButton *button) override; + + QSharedPointer<QFileDialogOptions> options; + QUrl currentFolder; + QUrl selectedFile; + QUrl currentFile; + QStringList nameFilters; + mutable QQuickFileNameFilter *selectedNameFilter = nullptr; + QString acceptLabel; + QString rejectLabel; +}; + +class QQuickFileDialogImplAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickFileDialogImplAttached) + + void nameFiltersComboBoxItemActivated(int index); + void fileDialogListViewCurrentIndexChanged(); + +public: + QPointer<QQuickDialogButtonBox> buttonBox; + QPointer<QQuickComboBox> nameFiltersComboBox; + QPointer<QQuickListView> fileDialogListView; + QPointer<QQuickFolderBreadcrumbBar> breadcrumbBar; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFILEDIALOG_P_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar.cpp new file mode 100644 index 00000000000..a4742825388 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar.cpp @@ -0,0 +1,794 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfolderbreadcrumbbar_p.h" +#include "qquickfolderbreadcrumbbar_p_p.h" + +#include <QtCore/qdir.h> +#include <QtCore/qloggingcategory.h> +#if QT_CONFIG(shortcut) +#include <QtGui/private/qshortcutmap_p.h> +#endif +#include <QtGui/private/qguiapplication_p.h> +#include <QtQml/QQmlFile> +#include <QtQuick/private/qquicktextinput_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickpopupitem_p_p.h> +#include <QtQuickTemplates2/private/qquickshortcutcontext_p_p.h> + +#include "qquickfiledialogimpl_p.h" +#include "qquickfiledialogimpl_p_p.h" + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcFolderBreadcrumbBar, "qt.quick.dialogs.folderbreadcrumbbar") +Q_LOGGING_CATEGORY(lcContentSize, "qt.quick.dialogs.folderbreadcrumbbar.contentsize") +Q_LOGGING_CATEGORY(lcDelegates, "qt.quick.dialogs.folderbreadcrumbbar.delegates") +Q_LOGGING_CATEGORY(lcShortcuts, "qt.quick.dialogs.folderbreadcrumbbar.shortcuts") +Q_LOGGING_CATEGORY(lcTextInput, "qt.quick.dialogs.folderbreadcrumbbar.textinput") +Q_LOGGING_CATEGORY(lcCurrentItem, "qt.quick.dialogs.folderbreadcrumbbar.currentitem") + +QQuickItem *QQuickFolderBreadcrumbBarPrivate::createDelegateItem(QQmlComponent *component, const QVariantMap &initialProperties) +{ + Q_Q(QQuickFolderBreadcrumbBar); + // If we don't use the correct context, it won't be possible to refer to + // the control's id from within the delegates. + QQmlContext *creationContext = component->creationContext(); + // The component might not have been created in QML, in which case + // the creation context will be null and we have to create it ourselves. + if (!creationContext) + creationContext = qmlContext(q); + QQmlContext *context = new QQmlContext(creationContext, q); + context->setContextObject(q); + QQuickItem *item = qobject_cast<QQuickItem*>(component->createWithInitialProperties(initialProperties, context)); + if (item) + QQml_setParent_noEvent(item, q); + qCDebug(lcDelegates) << "- created delegate item" << item << "with initialProperties" << initialProperties; + return item; +} + +QString QQuickFolderBreadcrumbBarPrivate::folderBaseName(const QString &folderPath) +{ + if (folderPath == QLatin1String("/")) { + // Unix root. + return folderPath; + } else if (folderPath.endsWith(QLatin1String(":/"))) { + // Windows drive. + return folderPath.mid(0, folderPath.size() - 1); + } + const QString baseName = folderPath.mid(folderPath.lastIndexOf(QLatin1Char('/')) + 1); + return baseName; +} + +/*! + \internal + + Returns \c { "/foo", "/foo/bar", "/foo/bar/baz" } if \a folder is \c "/foo/bar/baz". +*/ +QStringList QQuickFolderBreadcrumbBarPrivate::crumbPathsForFolder(const QUrl &folder) +{ + const QString folderPath = QDir::fromNativeSeparators(QQmlFile::urlToLocalFileOrQrc(folder)); + QDir dir(folderPath); + // In order to collect the paths for each breadcrumb, we need to work backwards, so we prepend. + QStringList paths; + do { + paths.prepend(dir.absolutePath()); + } while (dir.cdUp()); + return paths; +} + +void QQuickFolderBreadcrumbBarPrivate::repopulate() +{ + Q_Q(QQuickFolderBreadcrumbBar); + qCDebug(lcDelegates) << "attemping to repopulate breadcrumb bar using folder..."; + + if (repopulating) + return; + + if (!buttonDelegate || !separatorDelegate || !q->contentItem()) { + qCWarning(lcDelegates) << "Both delegates and contentItem must be set before repopulating"; + return; + } + + QBoolBlocker repopulateGuard(repopulating); + + auto failureCleanup = [=](){ + folderPaths.clear(); + while (q->count() > 0) + q->removeItem(q->itemAt(0)); + }; + + qCDebug(lcDelegates) << "- getting paths for directory" << fileDialog->currentFolder(); + folderPaths = crumbPathsForFolder(fileDialog->currentFolder()); + + while (q->count() > 0) + q->removeItem(q->itemAt(0)); + + for (int i = 0; i < folderPaths.size(); ++i) { + const QString &folderPath = folderPaths.at(i); + + QVariantMap initialProperties = { + { QStringLiteral("index"), QVariant::fromValue(i) }, + { QStringLiteral("folderName"), QVariant::fromValue(folderBaseName(folderPath)) } + }; + QQuickItem *buttonItem = createDelegateItem(buttonDelegate, initialProperties); + if (!buttonItem) { + qCWarning(lcDelegates) << "Failed creating breadcrumb buttonDelegate item:\n" << buttonDelegate->errorString(); + failureCleanup(); + break; + } + if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(buttonItem)) { + QObjectPrivate::connect(button, &QQuickAbstractButton::clicked, + this, &QQuickFolderBreadcrumbBarPrivate::crumbClicked); + } + insertItem(q->count(), buttonItem); + + // Don't add a separator for the last button. + if (i < folderPaths.size() - 1) { + initialProperties = {}; + QQuickItem *separatorItem = createDelegateItem(separatorDelegate, initialProperties); + if (!separatorItem) { + qCWarning(lcDelegates) << "Failed creating breadcrumb separatorDelegate item:\n" << buttonDelegate->errorString(); + failureCleanup(); + break; + } + insertItem(q->count(), separatorItem); + } + } + + const int finalCount = q->count(); + // We would do - 2, since separators are included in the count, + // but as we don't add a separator for the last button, we only need to subtract 1. + const int newCurrentIndex = finalCount > 2 ? finalCount - 1 : -1; + qCDebug(lcDelegates) << "- setting currentIndex to" << newCurrentIndex; + q->setCurrentIndex(newCurrentIndex); + + updateImplicitContentSize(); + + qCDebug(lcDelegates) << "... bar now contains" << q->count() + << "buttons and separators in total, for the following paths:" << folderPaths; +} + +void QQuickFolderBreadcrumbBarPrivate::crumbClicked() +{ + Q_Q(QQuickFolderBreadcrumbBar); + qCDebug(lcCurrentItem) << "updateCurrentIndex called by sender" << q->sender(); + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(q->sender()); + if (button) { + const int buttonIndex = contentModel->indexOf(button, nullptr); + q->setCurrentIndex(buttonIndex); + const QUrl folderUrl = QUrl::fromLocalFile(folderPaths.at(buttonIndex / 2)); + // TODO: don't repopulate the whole model when clicking on crumbs + qCDebug(lcCurrentItem) << "setting file dialog's folder to" << folderUrl; + fileDialog->setCurrentFolder(folderUrl); + } +} + +void QQuickFolderBreadcrumbBarPrivate::folderChanged() +{ + if (componentComplete) + repopulate(); +} + +static inline QString upButtonName() +{ + return QStringLiteral("upButton"); +} + +void QQuickFolderBreadcrumbBarPrivate::cancelUpButton() +{ + Q_Q(QQuickFolderBreadcrumbBar); + quickCancelDeferred(q, upButtonName()); +} + +void QQuickFolderBreadcrumbBarPrivate::executeUpButton(bool complete) +{ + Q_Q(QQuickFolderBreadcrumbBar); + if (upButton.wasExecuted()) + return; + + if (!upButton || complete) + quickBeginDeferred(q, upButtonName(), upButton); + if (complete) + quickCompleteDeferred(q, upButtonName(), upButton); +} + +void QQuickFolderBreadcrumbBarPrivate::goUp() +{ + QDir dir(QQmlFile::urlToLocalFileOrQrc(fileDialog->currentFolder())); + dir.cdUp(); + fileDialog->setCurrentFolder(QUrl::fromLocalFile(dir.absolutePath())); +} + +static inline QString textFieldName() +{ + return QStringLiteral("textField"); +} + +void QQuickFolderBreadcrumbBarPrivate::cancelTextField() +{ + Q_Q(QQuickFolderBreadcrumbBar); + quickCancelDeferred(q, textFieldName()); +} + +void QQuickFolderBreadcrumbBarPrivate::executeTextField(bool complete) +{ + Q_Q(QQuickFolderBreadcrumbBar); + if (textField.wasExecuted()) + return; + + if (!textField || complete) + quickBeginDeferred(q, textFieldName(), textField); + if (complete) + quickCompleteDeferred(q, textFieldName(), textField); +} + +void QQuickFolderBreadcrumbBarPrivate::toggleTextFieldVisibility() +{ + textField->setText(QQmlFile::urlToLocalFileOrQrc(fileDialog->currentFolder())); + + qCDebug(lcTextInput).nospace() << "text field visibility was " << textField->isVisible() + << "; setting it to " << !textField->isVisible(); + textField->setVisible(!textField->isVisible()); + + if (textField->isVisible()) { + // The text field is now visible, so give it focus, + // select the text, and let it handle escape/back. + textField->forceActiveFocus(Qt::ShortcutFocusReason); + textField->selectAll(); + } + + // We connect to the TextField's visibleChanged signal, so textFieldVisibleChanged() + // will get called automatically and we don't need to call it here. + + contentItem->setVisible(!textField->isVisible()); + + // When the TextField is visible, certain items in the dialog need to be disabled. + auto fileDialogPrivate = QQuickFileDialogImplPrivate::get(fileDialog); + fileDialogPrivate->updateEnabled(); +} + +void QQuickFolderBreadcrumbBarPrivate::textFieldAccepted() +{ + const QUrl fileUrl = QUrl::fromLocalFile(textField->text()); + const bool mustExist = fileDialog->options()->acceptMode() != QFileDialogOptions::AcceptSave; + const bool enteredPathIsValidUrl = fileUrl.isValid(); + bool enteredPathExists = false; + bool enteredPathIsDir = false; + if (enteredPathIsValidUrl) { + const QFileInfo fileInfo(textField->text()); + enteredPathExists = fileInfo.exists(); + if (enteredPathExists) + enteredPathIsDir = fileInfo.isDir(); + } + + qCDebug(lcTextInput).nospace() << "text field accepted -" + << " text=" << textField->text() + << " fileUrl=" << fileUrl + << " mustExist=" << mustExist + << " enteredPathIsValidUrl=" << enteredPathIsValidUrl + << " enteredPathExists=" << enteredPathExists + << " enteredPathIsDir=" << enteredPathIsDir; + + if (enteredPathIsDir && (enteredPathExists || !mustExist)) { + qCDebug(lcTextInput) << "path entered is a folder; setting folder"; + fileDialog->setCurrentFolder(fileUrl); + } else if (!enteredPathIsDir && (enteredPathExists || !mustExist)) { + qCDebug(lcTextInput) << "path entered is a file; setting file and calling accept()"; + // It's important that we set the currentFile here, as that's what + // QQuickPlatformFileDialog::selectedFiles() needs to return, and + // QQuickFileDialog::accept() sets its file property based on + // selectedFiles(). + fileDialog->setCurrentFile(fileUrl); + fileDialog->setSelectedFile(fileUrl); + fileDialog->accept(); + } else { + qCDebug(lcTextInput) << "path entered is not valid; not setting file/folder"; + } + + // If the enter key was pressed and the dialog closed, the text input will lose + // active focus, and textFieldActiveFocusChanged() will toggle its visibility. + // We should only toggle visibility if the dialog is actually closed, otherwise + // we'll end up toggling twice, and the text input will be visible the next time + // the dialog is opened. + if (fileDialog->isVisible()) + toggleTextFieldVisibility(); +} + +void QQuickFolderBreadcrumbBarPrivate::textFieldVisibleChanged() +{ + qCDebug(lcShortcuts) << "text field was either hidden or shown"; + + if (textField && textField->isVisible()) + handleTextFieldShown(); + else + handleTextFieldHidden(); +} + +void QQuickFolderBreadcrumbBarPrivate::textFieldActiveFocusChanged() +{ + qCDebug(lcTextInput) << "text field activeFocus changed to" << textField->hasActiveFocus(); + + // When the text field loses focus, it should be hidden. + if (!textField->hasActiveFocus() && textField->isVisible()) + toggleTextFieldVisibility(); +} + +/* + When the text field is visible: + + - Ctrl+L should do nothing (matches e.g. Ubuntu and Windows) + - Escape/back should hide it +*/ +void QQuickFolderBreadcrumbBarPrivate::handleTextFieldShown() +{ +#if QT_CONFIG(shortcut) + Q_Q(QQuickFolderBreadcrumbBar); + if (editPathToggleShortcutId == 0) + return; + + QGuiApplicationPrivate *appPrivate = QGuiApplicationPrivate::instance(); + qCDebug(lcShortcuts) << "text field was shown; grabbing/ungrabbing relevant shortcuts..."; + + // Disable the back/escape shortcuts for QQuickPopup so that the TextField can get them. + auto popupItem = qobject_cast<QQuickPopupItem*>(fileDialog->popupItem()); + popupItem->ungrabShortcut(); + + appPrivate->shortcutMap.removeShortcut(editPathToggleShortcutId, q); + editPathToggleShortcutId = 0; + + editPathBackShortcutId = appPrivate->shortcutMap.addShortcut( + q, Qt::Key_Back, Qt::WindowShortcut, QQuickShortcutContext::matcher); + editPathEscapeShortcutId = appPrivate->shortcutMap.addShortcut( + q, Qt::Key_Escape, Qt::WindowShortcut, QQuickShortcutContext::matcher); + + qCDebug(lcShortcuts).nospace() << "... shortcut IDs:" + << " editPathToggleShortcutId=" << editPathToggleShortcutId + << " editPathBackShortcutId=" << editPathBackShortcutId + << " editPathEscapeShortcutId=" << editPathEscapeShortcutId; +#endif +} + +/* + When the text field is not visible: + + - Ctrl+L should make it visible + - Escape/back should close the dialog +*/ +void QQuickFolderBreadcrumbBarPrivate::handleTextFieldHidden() +{ +#if QT_CONFIG(shortcut) + Q_Q(QQuickFolderBreadcrumbBar); + + QGuiApplicationPrivate *appPrivate = QGuiApplicationPrivate::instance(); + qCDebug(lcShortcuts) << "text field was hidden; grabbing/ungrabbing relevant shortcuts..."; + + if (editPathToggleShortcutId == 0) { + editPathToggleShortcutId = appPrivate->shortcutMap.addShortcut( + q, Qt::CTRL | Qt::Key_L, Qt::WindowShortcut, QQuickShortcutContext::matcher); + } + + // When the bar is first completed, this function is called, since the text field starts off hidden. + // If removeShortcut is called with a zero id, all shortcuts for the given object will be removed, + // and we don't want that. + if (editPathBackShortcutId != 0) { + appPrivate->shortcutMap.removeShortcut(editPathBackShortcutId, q); + editPathBackShortcutId = 0; + } + if (editPathEscapeShortcutId != 0) { + appPrivate->shortcutMap.removeShortcut(editPathEscapeShortcutId, q); + editPathEscapeShortcutId = 0; + } + + // Re-enable the back/escape shortcuts for QQuickPopup now that TextField no longer needs them. + auto popupItem = qobject_cast<QQuickPopupItem*>(fileDialog->popupItem()); + if (popupItem) + popupItem->grabShortcut(); + + qCDebug(lcShortcuts).nospace() << "... shortcut IDs: " + << " editPathToggleShortcutId=" << editPathToggleShortcutId + << " editPathBackShortcutId=" << editPathBackShortcutId + << " editPathEscapeShortcutId=" << editPathEscapeShortcutId; +#endif +} + +void QQuickFolderBreadcrumbBarPrivate::ungrabEditPathShortcuts() +{ +#if QT_CONFIG(shortcut) + Q_Q(QQuickFolderBreadcrumbBar); + QGuiApplicationPrivate *appPrivate = QGuiApplicationPrivate::instance(); + qCDebug(lcShortcuts) << "ungrabbing all edit path shortcuts"; + + if (editPathToggleShortcutId != 0) { + appPrivate->shortcutMap.removeShortcut(editPathToggleShortcutId, q); + editPathToggleShortcutId = 0; + } + if (editPathBackShortcutId != 0) { + appPrivate->shortcutMap.removeShortcut(editPathBackShortcutId, q); + editPathBackShortcutId = 0; + } + if (editPathEscapeShortcutId != 0) { + appPrivate->shortcutMap.removeShortcut(editPathEscapeShortcutId, q); + editPathEscapeShortcutId = 0; + } +#endif +} + +qreal QQuickFolderBreadcrumbBarPrivate::getContentWidth() const +{ + Q_Q(const QQuickFolderBreadcrumbBar); + const int count = contentModel->count(); + qreal totalWidth = qMax(0, count - 1) * spacing; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) { + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + if (!p->widthValid()) + totalWidth += item->implicitWidth(); + else + totalWidth += item->width(); + } + } + qCDebug(lcContentSize) << "content width:" << totalWidth; + return totalWidth; +} + +qreal QQuickFolderBreadcrumbBarPrivate::getContentHeight() const +{ + Q_Q(const QQuickFolderBreadcrumbBar); + const int count = contentModel->count(); + qreal maxHeight = 0; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) + maxHeight = qMax(maxHeight, item->implicitHeight()); + } + qCDebug(lcContentSize) << "content height:" << maxHeight; + return maxHeight; +} + +void QQuickFolderBreadcrumbBarPrivate::resizeContent() +{ + Q_Q(QQuickFolderBreadcrumbBar); + if (contentItem) { + const int upButtonSpace = q->upButton() ? q->upButton()->width() + upButtonSpacing : 0; + contentItem->setPosition(QPointF(q->leftPadding() + upButtonSpace, q->topPadding())); + contentItem->setSize(QSizeF(q->availableWidth() - upButtonSpace, q->availableHeight())); + + if (textField) { + textField->setPosition(contentItem->position()); + textField->setSize(contentItem->size()); + } + } +} + +void QQuickFolderBreadcrumbBarPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) +{ + QQuickContainerPrivate::itemGeometryChanged(item, change, diff); + if (change.sizeChange()) + updateImplicitContentSize(); +} + +void QQuickFolderBreadcrumbBarPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + QQuickContainerPrivate::itemImplicitWidthChanged(item); + if (item != contentItem) + updateImplicitContentWidth(); +} + +void QQuickFolderBreadcrumbBarPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + QQuickContainerPrivate::itemImplicitHeightChanged(item); + if (item != contentItem) + updateImplicitContentHeight(); +} + +/*! + \internal + + Private class for breadcrumb navigation of a directory. + + Given a FileDialog, FolderBreadCrumbbar creates breadcrumb buttons and + separators from the specified delegate components. +*/ + +QQuickFolderBreadcrumbBar::QQuickFolderBreadcrumbBar(QQuickItem *parent) + : QQuickContainer(*(new QQuickFolderBreadcrumbBarPrivate), parent) +{ + Q_D(QQuickFolderBreadcrumbBar); + d->changeTypes |= QQuickItemPrivate::Geometry | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; +} + +QQuickFileDialogImpl *QQuickFolderBreadcrumbBar::fileDialog() const +{ + Q_D(const QQuickFolderBreadcrumbBar); + return d->fileDialog; +} + +void QQuickFolderBreadcrumbBar::setFileDialog(QQuickFileDialogImpl *fileDialog) +{ + Q_D(QQuickFolderBreadcrumbBar); + if (fileDialog == d->fileDialog) + return; + + if (d->fileDialog) + QObjectPrivate::disconnect(d->fileDialog, &QQuickFileDialogImpl::currentFolderChanged, + d, &QQuickFolderBreadcrumbBarPrivate::folderChanged); + + d->fileDialog = fileDialog; + + if (d->fileDialog) + QObjectPrivate::connect(d->fileDialog, &QQuickFileDialogImpl::currentFolderChanged, + d, &QQuickFolderBreadcrumbBarPrivate::folderChanged); + + emit fileDialogChanged(); +} + +QQmlComponent *QQuickFolderBreadcrumbBar::buttonDelegate() +{ + Q_D(QQuickFolderBreadcrumbBar); + return d->buttonDelegate; +} + +void QQuickFolderBreadcrumbBar::setButtonDelegate(QQmlComponent *delegate) +{ + Q_D(QQuickFolderBreadcrumbBar); + qCDebug(lcFolderBreadcrumbBar) << "setButtonDelegate called with" << delegate; + if (d->componentComplete) { + // Simplify the code by disallowing this. + qCWarning(lcFolderBreadcrumbBar) << "BreadcrumbBar does not support setting delegates after component completion"; + return; + } + + if (delegate == d->buttonDelegate) + return; + + d->buttonDelegate = delegate; + emit buttonDelegateChanged(); +} + +QQmlComponent *QQuickFolderBreadcrumbBar::separatorDelegate() +{ + Q_D(QQuickFolderBreadcrumbBar); + return d->separatorDelegate; +} + +void QQuickFolderBreadcrumbBar::setSeparatorDelegate(QQmlComponent *delegate) +{ + Q_D(QQuickFolderBreadcrumbBar); + qCDebug(lcFolderBreadcrumbBar) << "setSeparatorDelegate called with" << delegate; + if (d->componentComplete) { + qCWarning(lcFolderBreadcrumbBar) << "BreadcrumbBar does not support setting delegates after component completion"; + return; + } + + if (delegate == d->separatorDelegate) + return; + + d->separatorDelegate = delegate; + emit separatorDelegateChanged(); +} + +QQuickAbstractButton *QQuickFolderBreadcrumbBar::upButton() +{ + Q_D(QQuickFolderBreadcrumbBar); + if (!d->upButton) + d->executeUpButton(); + return d->upButton; +} + +void QQuickFolderBreadcrumbBar::setUpButton(QQuickAbstractButton *upButton) +{ + Q_D(QQuickFolderBreadcrumbBar); + if (upButton == d->upButton) + return; + + if (!d->upButton.isExecuting()) + d->cancelUpButton(); + + if (d->upButton) { + QObjectPrivate::disconnect(d->upButton.data(), &QQuickAbstractButton::clicked, + d, &QQuickFolderBreadcrumbBarPrivate::goUp); + } + + QQuickControlPrivate::hideOldItem(d->upButton); + d->upButton = upButton; + if (d->upButton) { + if (!d->upButton->parentItem()) + d->upButton->setParentItem(this); + + QObjectPrivate::connect(d->upButton.data(), &QQuickAbstractButton::clicked, + d, &QQuickFolderBreadcrumbBarPrivate::goUp); + } + if (!d->upButton.isExecuting()) + emit upButtonChanged(); +} + +int QQuickFolderBreadcrumbBar::upButtonSpacing() const +{ + Q_D(const QQuickFolderBreadcrumbBar); + return d->upButtonSpacing; +} + +void QQuickFolderBreadcrumbBar::setUpButtonSpacing(int upButtonSpacing) +{ + Q_D(QQuickFolderBreadcrumbBar); + if (upButtonSpacing == d->upButtonSpacing) + return; + + d->upButtonSpacing = upButtonSpacing; + emit upButtonSpacingChanged(); +} + +QQuickTextField *QQuickFolderBreadcrumbBar::textField() +{ + Q_D(QQuickFolderBreadcrumbBar); + return d->textField; +} + +void QQuickFolderBreadcrumbBar::setTextField(QQuickTextField *textField) +{ + Q_D(QQuickFolderBreadcrumbBar); + if (textField == d->textField) + return; + + if (!d->textField.isExecuting()) + d->cancelUpButton(); + + if (d->textField) + d->handleTextFieldHidden(); + + if (d->textField) { + QObjectPrivate::disconnect(d->textField.data(), &QQuickTextInput::visibleChanged, + d, &QQuickFolderBreadcrumbBarPrivate::textFieldVisibleChanged); + QObjectPrivate::disconnect(d->textField.data(), &QQuickTextInput::activeFocusChanged, + d, &QQuickFolderBreadcrumbBarPrivate::textFieldActiveFocusChanged); + QObjectPrivate::disconnect(d->textField.data(), &QQuickTextInput::accepted, + d, &QQuickFolderBreadcrumbBarPrivate::textFieldAccepted); + } + + QQuickControlPrivate::hideOldItem(d->textField); + d->textField = textField; + if (d->textField) { + if (!d->textField->parentItem()) + d->textField->setParentItem(this); + + d->textField->setVisible(false); + + QObjectPrivate::connect(d->textField.data(), &QQuickTextInput::visibleChanged, + d, &QQuickFolderBreadcrumbBarPrivate::textFieldVisibleChanged); + QObjectPrivate::connect(d->textField.data(), &QQuickTextInput::activeFocusChanged, + d, &QQuickFolderBreadcrumbBarPrivate::textFieldActiveFocusChanged); + QObjectPrivate::connect(d->textField.data(), &QQuickTextInput::accepted, + d, &QQuickFolderBreadcrumbBarPrivate::textFieldAccepted); + } + if (!d->textField.isExecuting()) + emit textFieldChanged(); +} + +bool QQuickFolderBreadcrumbBar::event(QEvent *event) +{ +#if QT_CONFIG(shortcut) + Q_D(QQuickFolderBreadcrumbBar); + if (event->type() == QEvent::Shortcut) { + QShortcutEvent *shortcutEvent = static_cast<QShortcutEvent *>(event); + if (shortcutEvent->shortcutId() == d->editPathToggleShortcutId + || shortcutEvent->shortcutId() == d->editPathBackShortcutId + || shortcutEvent->shortcutId() == d->editPathEscapeShortcutId) { + d->toggleTextFieldVisibility(); + return true; + } else if (shortcutEvent->shortcutId() == d->goUpShortcutId) { + d->goUp(); + } + } +#endif + return QQuickItem::event(event); +} + +void QQuickFolderBreadcrumbBar::componentComplete() +{ + Q_D(QQuickFolderBreadcrumbBar); + qCDebug(lcFolderBreadcrumbBar) << "componentComplete"; + QQuickContainer::componentComplete(); + d->repopulate(); + + if (d->textField) { + // Force it to be updated as setTextField() is too early to do it. + d->textFieldVisibleChanged(); + } +} + +void QQuickFolderBreadcrumbBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + Q_D(QQuickFolderBreadcrumbBar); + QQuickContainer::itemChange(change, data); + + if (change == QQuickItem::ItemVisibleHasChanged && isComponentComplete()) { + if (data.boolValue && d->fileDialog->isVisible()) { + // It's visible. + d->handleTextFieldHidden(); + + d->goUpShortcutId = QGuiApplicationPrivate::instance()->shortcutMap.addShortcut( + this, QKeySequence(Qt::ALT | Qt::Key_Up), Qt::WindowShortcut, QQuickShortcutContext::matcher); + } else { + // It's hidden. + // Hide the text field so that when the dialog gets opened again, it's not still visible. + if (d->textField) + d->textField->setVisible(false); + + // Make the ListView visible again. + if (d->contentItem) + d->contentItem->setVisible(true); + + // We also need to ungrab all shortcuts when we're not visible. + d->ungrabEditPathShortcuts(); + + if (d->goUpShortcutId != 0) { + QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(d->goUpShortcutId, this); + d->goUpShortcutId = 0; + } + } + } +} + +bool QQuickFolderBreadcrumbBar::isContent(QQuickItem *item) const +{ + if (!qmlContext(item)) + return false; + + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return false; + + return true; +} + +QFont QQuickFolderBreadcrumbBar::defaultFont() const +{ + // TODO + return QQuickTheme::font(QQuickTheme::TabBar); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickFolderBreadcrumbBar::accessibleRole() const +{ + // TODO + return QAccessible::PageTabList; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickfolderbreadcrumbbar_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar_p.h new file mode 100644 index 00000000000..5e14f5b04ff --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFOLDERBREADCRUMBBAR_P_H +#define QQUICKFOLDERBREADCRUMBBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/qqmlcomponent.h> +#include <QtQuickTemplates2/private/qquickcontainer_p.h> +#include <QtQuickTemplates2/private/qquicktextfield_p.h> + +#include "qquickfiledialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFolderBreadcrumbBarPrivate; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFolderBreadcrumbBar : public QQuickContainer +{ + Q_OBJECT + Q_PROPERTY(QQuickFileDialogImpl *fileDialog READ fileDialog WRITE setFileDialog NOTIFY fileDialogChanged) + Q_PROPERTY(QQmlComponent *buttonDelegate READ buttonDelegate WRITE setButtonDelegate NOTIFY buttonDelegateChanged) + Q_PROPERTY(QQmlComponent *separatorDelegate READ separatorDelegate WRITE setSeparatorDelegate NOTIFY separatorDelegateChanged) + Q_PROPERTY(QQuickAbstractButton *upButton READ upButton WRITE setUpButton NOTIFY upButtonChanged) + Q_PROPERTY(QQuickTextField *textField READ textField WRITE setTextField NOTIFY textFieldChanged) + Q_PROPERTY(int upButtonSpacing READ upButtonSpacing WRITE setUpButtonSpacing NOTIFY upButtonSpacingChanged) + QML_NAMED_ELEMENT(FolderBreadcrumbBar) + QML_ADDED_IN_VERSION(6, 2) + +public: + explicit QQuickFolderBreadcrumbBar(QQuickItem *parent = nullptr); + + QQuickFileDialogImpl *fileDialog() const; + void setFileDialog(QQuickFileDialogImpl *fileDialog); + + QQmlComponent *buttonDelegate(); + void setButtonDelegate(QQmlComponent *delegate); + + QQmlComponent *separatorDelegate(); + void setSeparatorDelegate(QQmlComponent *delegate); + + QQuickAbstractButton *upButton(); + void setUpButton(QQuickAbstractButton *upButton); + + int upButtonSpacing() const; + void setUpButtonSpacing(int upButtonSpacing); + + QQuickTextField *textField(); + void setTextField(QQuickTextField *textField); + +Q_SIGNALS: + void fileDialogChanged(); + void buttonDelegateChanged(); + void separatorDelegateChanged(); + void upButtonChanged(); + void upButtonSpacingChanged(); + void textFieldChanged(); + +protected: + bool event(QEvent *event) override; + + void componentComplete() override; + + void itemChange(ItemChange change, const ItemChangeData &data) override; + + bool isContent(QQuickItem *item) const override; + + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickFolderBreadcrumbBar) + Q_DECLARE_PRIVATE(QQuickFolderBreadcrumbBar) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFolderBreadcrumbBar) + +#endif // QQUICKFOLDERBREADCRUMBBAR_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar_p_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar_p_p.h new file mode 100644 index 00000000000..4616b6a9c54 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar_p_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFOLDERBREADCRUMBBAR_P_P_H +#define QQUICKFOLDERBREADCRUMBBAR_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontainer_p_p.h> +#include <QtQuickTemplates2/private/qquickdeferredexecute_p_p.h> + +#include "qquickfiledialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickAbstractButton; +class QQuickTextField; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFolderBreadcrumbBarPrivate : public QQuickContainerPrivate +{ + Q_DECLARE_PUBLIC(QQuickFolderBreadcrumbBar) + +public: + QQuickItem *createDelegateItem(QQmlComponent *component, const QVariantMap &initialProperties); + static QString folderBaseName(const QString &folderPath); + static QStringList crumbPathsForFolder(const QUrl &folder); + void repopulate(); + void crumbClicked(); + void folderChanged(); + + void cancelUpButton(); + void executeUpButton(bool complete = false); + void goUp(); + + void cancelTextField(); + void executeTextField(bool complete = false); + void toggleTextFieldVisibility(); + void textFieldAccepted(); + + void textFieldVisibleChanged(); + void textFieldActiveFocusChanged(); + void handleTextFieldShown(); + void handleTextFieldHidden(); + void ungrabEditPathShortcuts(); + + qreal getContentWidth() const override; + qreal getContentHeight() const override; + void resizeContent() override; + + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + +private: + QQuickFileDialogImpl *fileDialog = nullptr; + QList<QString> folderPaths; + QQmlComponent *buttonDelegate = nullptr; + QQmlComponent *separatorDelegate = nullptr; + QQuickDeferredPointer<QQuickAbstractButton> upButton; + QQuickDeferredPointer<QQuickTextField> textField; + int editPathToggleShortcutId = 0; + int editPathBackShortcutId = 0; + int editPathEscapeShortcutId = 0; + int goUpShortcutId = 0; + int upButtonSpacing = 0; + bool repopulating = false; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFOLDERBREADCRUMBBAR_P_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp new file mode 100644 index 00000000000..ba0b69ef267 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp @@ -0,0 +1,865 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfontdialogimpl_p.h" +#include "qquickfontdialogimpl_p_p.h" + +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p_p.h> +#include <private/qfontdatabase_p.h> + +#include <QRegularExpression> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcAttachedProperty, "qt.quick.dialogs.quickfontdialogimpl.attachedOrWarn") + +QQuickFontDialogImplPrivate::QQuickFontDialogImplPrivate() +{ +} + +QQuickFontDialogImplAttached *QQuickFontDialogImplPrivate::attachedOrWarn() +{ + Q_Q(QQuickFontDialogImpl); + QQuickFontDialogImplAttached *attached = static_cast<QQuickFontDialogImplAttached *>( + qmlAttachedPropertiesObject<QQuickFontDialogImpl>(q)); + if (!attached) { + qCWarning(lcAttachedProperty) + << "Expected FontDialogImpl attached object to be present on" << this; + } + return attached; +} + +void QQuickFontDialogImplPrivate::handleAccept() { } + +void QQuickFontDialogImplPrivate::handleClick(QQuickAbstractButton *button) +{ + Q_Q(QQuickFontDialogImpl); + if (buttonRole(button) == QPlatformDialogHelper::AcceptRole) { + q->accept(); + QQuickDialogPrivate::handleClick(button); + } +} + +QQuickFontDialogImpl::QQuickFontDialogImpl(QObject *parent) + : QQuickDialog(*(new QQuickFontDialogImplPrivate), parent) +{ +} + +QQuickFontDialogImplAttached *QQuickFontDialogImpl::qmlAttachedProperties(QObject *object) +{ + return new QQuickFontDialogImplAttached(object); +} + +QSharedPointer<QFontDialogOptions> QQuickFontDialogImpl::options() const +{ + Q_D(const QQuickFontDialogImpl); + + return d->options; +} + +void QQuickFontDialogImpl::setOptions(const QSharedPointer<QFontDialogOptions> &options) +{ + Q_D(QQuickFontDialogImpl); + + if (options == d->options) + return; + + d->options = options; + + emit optionsChanged(); +} + +QFont QQuickFontDialogImpl::currentFont() const +{ + Q_D(const QQuickFontDialogImpl); + return d->currentFont; +} + +void QQuickFontDialogImpl::setCurrentFont(const QFont &font, bool selectInListViews) +{ + Q_D(QQuickFontDialogImpl); + + if (font == d->currentFont) + return; + + d->currentFont = font; + + emit currentFontChanged(font); + + if (!selectInListViews) + return; + + QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + attached->selectFontInListViews(font); +} + +void QQuickFontDialogImpl::init() +{ + Q_D(QQuickFontDialogImpl); + QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + if (!attached->familyListView()->model().isValid()) + attached->updateFamilies(); + + attached->buttonBox()->setVisible(!(options()->options() & QFontDialogOptions::NoButtons)); +} + +void QQuickFontDialogImpl::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QQuickFontDialogImpl); + + QQuickDialog::keyReleaseEvent(event); + + QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + // The family and style text edits are read-only so that they + // can show the current selection but also allow key input to "search". + // This is why we handle just the release event, and don't accept it. + if (window()->activeFocusItem() == attached->familyEdit()) + attached->searchFamily(event->text()); + else if (window()->activeFocusItem() == attached->styleEdit()) + attached->searchStyle(event->text()); +} + +void QQuickFontDialogImpl::focusOutEvent(QFocusEvent *event) +{ + Q_D(QQuickFontDialogImpl); + + QQuickDialog::focusOutEvent(event); + + QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + attached->clearSearch(); +} + +QQuickFontDialogImplAttached::QQuickFontDialogImplAttached(QObject *parent) + : QObject(*(new QQuickFontDialogImplAttachedPrivate), parent), + m_writingSystem(QFontDatabase::Any), + m_selectedSize(-1), + m_smoothlyScalable(false), + m_ignoreFamilyUpdate(false), + m_ignoreStyleUpdate(false) +{ + if (!qobject_cast<QQuickFontDialogImpl *>(parent)) { + qmlWarning(this) << "FontDialogImpl attached properties should only be " + << "accessed through the root FileDialogImpl instance"; + } +} + +QQuickListView *QQuickFontDialogImplAttached::familyListView() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->familyListView; +} + +void QQuickFontDialogImplAttached::setFamilyListView(QQuickListView *familyListView) +{ + Q_D(QQuickFontDialogImplAttached); + if (d->familyListView == familyListView) + return; + + if (d->familyListView) { + disconnect(d->familyListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_familyChanged); + } + + d->familyListView = familyListView; + + if (familyListView) { + connect(d->familyListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_familyChanged); + } + + emit familyListViewChanged(); +} + +QQuickListView *QQuickFontDialogImplAttached::styleListView() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->styleListView; +} + +void QQuickFontDialogImplAttached::setStyleListView(QQuickListView *styleListView) +{ + Q_D(QQuickFontDialogImplAttached); + if (d->styleListView == styleListView) + return; + + if (d->styleListView) { + disconnect(d->styleListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_styleChanged); + } + + d->styleListView = styleListView; + + if (styleListView) { + connect(d->styleListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_styleChanged); + } + + emit styleListViewChanged(); +} + +QQuickListView *QQuickFontDialogImplAttached::sizeListView() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->sizeListView; +} + +void QQuickFontDialogImplAttached::setSizeListView(QQuickListView *sizeListView) +{ + Q_D(QQuickFontDialogImplAttached); + if (d->sizeListView == sizeListView) + return; + + if (d->sizeListView) { + disconnect(d->sizeListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_sizeChanged); + } + + d->sizeListView = sizeListView; + + if (d->sizeListView) { + connect(d->sizeListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_sizeChanged); + } + + emit sizeListViewChanged(); +} + +QQuickTextEdit *QQuickFontDialogImplAttached::sampleEdit() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->sampleEdit; +} + +void QQuickFontDialogImplAttached::setSampleEdit(QQuickTextEdit *sampleEdit) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->sampleEdit == sampleEdit) + return; + + if (d->sampleEdit) { + QObjectPrivate::disconnect(d->sampleEdit, &QQuickTextEdit::fontChanged, + d, &QQuickFontDialogImplAttachedPrivate::currentFontChanged); + } + + d->sampleEdit = sampleEdit; + + if (d->sampleEdit) { + QObjectPrivate::connect(d->sampleEdit, &QQuickTextEdit::fontChanged, + d, &QQuickFontDialogImplAttachedPrivate::currentFontChanged); + + d->sampleEdit->setText(QFontDatabase::writingSystemSample(m_writingSystem)); + } + + emit sampleEditChanged(); +} + +QQuickDialogButtonBox *QQuickFontDialogImplAttached::buttonBox() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->buttonBox; +} + +void QQuickFontDialogImplAttached::setButtonBox(QQuickDialogButtonBox *buttonBox) +{ + Q_D(QQuickFontDialogImplAttached); + if (buttonBox == d->buttonBox) + return; + + if (d->buttonBox) { + QQuickFontDialogImpl *fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent()); + if (fontDialogImpl) { + auto dialogPrivate = QQuickDialogPrivate::get(fontDialogImpl); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::accepted, + dialogPrivate, &QQuickDialogPrivate::handleAccept); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::rejected, + dialogPrivate, &QQuickDialogPrivate::handleReject); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::clicked, dialogPrivate, + &QQuickDialogPrivate::handleClick); + } + } + + d->buttonBox = buttonBox; + + if (buttonBox) { + QQuickFontDialogImpl *fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent()); + if (fontDialogImpl) { + auto dialogPrivate = QQuickDialogPrivate::get(fontDialogImpl); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::accepted, dialogPrivate, + &QQuickDialogPrivate::handleAccept); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::rejected, dialogPrivate, + &QQuickDialogPrivate::handleReject); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::clicked, dialogPrivate, + &QQuickDialogPrivate::handleClick); + } + } + + emit buttonBoxChanged(); +} + +QQuickComboBox *QQuickFontDialogImplAttached::writingSystemComboBox() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->writingSystemComboBox; +} + +void QQuickFontDialogImplAttached::setWritingSystemComboBox(QQuickComboBox *writingSystemComboBox) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->writingSystemComboBox == writingSystemComboBox) + return; + + if (d->writingSystemComboBox) { + disconnect(d->writingSystemComboBox, &QQuickComboBox::activated, + this, &QQuickFontDialogImplAttached::_q_writingSystemChanged); + } + + d->writingSystemComboBox = writingSystemComboBox; + + if (d->writingSystemComboBox) { + QStringList writingSystemModel; + for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) { + QFontDatabase::WritingSystem ws = QFontDatabase::WritingSystem(i); + QString wsName = QFontDatabase::writingSystemName(ws); + if (wsName.isEmpty()) + break; + writingSystemModel.append(wsName); + } + + d->writingSystemComboBox->setModel(writingSystemModel); + + connect(d->writingSystemComboBox, &QQuickComboBox::activated, + this, &QQuickFontDialogImplAttached::_q_writingSystemChanged); + } + + emit writingSystemComboBoxChanged(); +} + +QQuickCheckBox *QQuickFontDialogImplAttached::underlineCheckBox() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->underlineCheckBox; +} + +void QQuickFontDialogImplAttached::setUnderlineCheckBox(QQuickCheckBox *underlineCheckBox) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->underlineCheckBox == underlineCheckBox) + return; + + if (d->underlineCheckBox) { + disconnect(d->underlineCheckBox, &QQuickCheckBox::checkStateChanged, + this, &QQuickFontDialogImplAttached::_q_updateSample); + } + + d->underlineCheckBox = underlineCheckBox; + + if (d->underlineCheckBox) { + connect(d->underlineCheckBox, &QQuickCheckBox::checkStateChanged, + this, &QQuickFontDialogImplAttached::_q_updateSample); + } + + emit underlineCheckBoxChanged(); +} + +QQuickCheckBox *QQuickFontDialogImplAttached::strikeoutCheckBox() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->strikeoutCheckBox; +} + +void QQuickFontDialogImplAttached::setStrikeoutCheckBox(QQuickCheckBox *strikeoutCheckBox) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->strikeoutCheckBox == strikeoutCheckBox) + return; + + if (d->strikeoutCheckBox) { + disconnect(d->strikeoutCheckBox, &QQuickCheckBox::checkStateChanged, + this, &QQuickFontDialogImplAttached::_q_updateSample); + } + + d->strikeoutCheckBox = strikeoutCheckBox; + + if (d->strikeoutCheckBox) { + connect(d->strikeoutCheckBox, &QQuickCheckBox::checkStateChanged, + this, &QQuickFontDialogImplAttached::_q_updateSample); + } + + emit strikeoutCheckBoxChanged(); +} + +QQuickTextField *QQuickFontDialogImplAttached::familyEdit() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->familyEdit; +} + +void QQuickFontDialogImplAttached::setFamilyEdit(QQuickTextField *familyEdit) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->familyEdit == familyEdit) + return; + + d->familyEdit = familyEdit; + + emit familyEditChanged(); +} + +QQuickTextField *QQuickFontDialogImplAttached::styleEdit() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->styleEdit; +} + +void QQuickFontDialogImplAttached::setStyleEdit(QQuickTextField *styleEdit) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->styleEdit == styleEdit) + return; + + d->styleEdit = styleEdit; + + emit styleEditChanged(); +} + +QQuickTextField *QQuickFontDialogImplAttached::sizeEdit() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->sizeEdit; +} + +void QQuickFontDialogImplAttached::setSizeEdit(QQuickTextField *sizeEdit) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->sizeEdit == sizeEdit) + return; + + if (d->sizeEdit) { + disconnect(d->sizeEdit, &QQuickTextField::textChanged, + this, &QQuickFontDialogImplAttached::_q_sizeEdited); + } + + d->sizeEdit = sizeEdit; + + if (d->sizeEdit) { + connect(d->sizeEdit, &QQuickTextField::textChanged, + this, &QQuickFontDialogImplAttached::_q_sizeEdited); + } + + emit sizeEditChanged(); +} + +static int findFamilyInModel(const QString &selectedFamily, const QStringList &model) +{ + enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 }; + QString foundryName1, familyName1, foundryName2, familyName2; + int bestFamilyMatch = -1; + match_t bestFamilyType = MATCH_NONE; + const QFont f; + + QFontDatabasePrivate::parseFontName(selectedFamily, foundryName1, familyName1); + + int i = 0; + for (auto it = model.constBegin(); it != model.constEnd(); ++it, ++i) { + QFontDatabasePrivate::parseFontName(*it, foundryName2, familyName2); + + if (familyName1 == familyName2) { + bestFamilyType = MATCH_FAMILY; + if (foundryName1 == foundryName2) + return i; + else + bestFamilyMatch = i; + } + + // fallbacks + match_t type = MATCH_NONE; + if (bestFamilyType <= MATCH_NONE && familyName2 == QStringLiteral("helvetica")) + type = MATCH_LAST_RESORT; + if (bestFamilyType <= MATCH_LAST_RESORT && familyName2 == f.families().constFirst()) + type = MATCH_APP; + if (type != MATCH_NONE) { + bestFamilyType = type; + bestFamilyMatch = i; + } + } + + return bestFamilyMatch; +} + +static int findStyleInModel(const QString &selectedStyle, const QStringList &model) +{ + if (model.isEmpty()) + return -1; + + if (!selectedStyle.isEmpty()) { + const int idx = model.indexOf(QRegularExpression(QRegularExpression::escape(selectedStyle), QRegularExpression::CaseInsensitiveOption)); + if (idx >= 0) + return idx; + + enum class StyleClass {Unknown, Normal, Italic}; + auto classifyStyleFallback = [](const QString & style) { + if (style.toLower() == QLatin1String("italic") || style.toLower() == QLatin1String("oblique")) + return StyleClass::Italic; + if (style.toLower() == QLatin1String("normal") || style.toLower() == QLatin1String("regular")) + return StyleClass::Normal; + return StyleClass::Unknown; + }; + + auto styleClass = classifyStyleFallback(selectedStyle); + + if (styleClass != StyleClass::Unknown) + for (int i = 0; i < model.count(); ++i) + if (classifyStyleFallback(model.at(i)) == styleClass) + return i; + } + return 0; +} + +/*! + \internal + + Updates the model for the family list view, and attempt + to reselect the previously selected font family. + */ +void QQuickFontDialogImplAttached::updateFamilies() +{ + const QFontDialogOptions::FontDialogOptions scalableMask( + QFontDialogOptions::ScalableFonts | QFontDialogOptions::NonScalableFonts); + + const QFontDialogOptions::FontDialogOptions spacingMask(QFontDialogOptions::ProportionalFonts + | QFontDialogOptions::MonospacedFonts); + + const auto p = qobject_cast<QQuickFontDialogImpl *>(parent()); + + const auto options = p->options()->options(); + + QStringList familyNames; + const auto families = QFontDatabase::families(m_writingSystem); + for (const auto &family : families) { + if (QFontDatabase::isPrivateFamily(family)) + continue; + + if ((options & scalableMask) && (options & scalableMask) != scalableMask) { + if (bool(options & QFontDialogOptions::ScalableFonts) + != QFontDatabase::isSmoothlyScalable(family)) + continue; + } + + if ((options & spacingMask) && (options & scalableMask) != spacingMask) { + if (bool(options & QFontDialogOptions::MonospacedFonts) + != QFontDatabase::isFixedPitch(family)) + continue; + } + + familyNames << family; + } + + auto listView = familyListView(); + + // Index will be set to -1 on empty model, and 0 for non empty models. + m_ignoreFamilyUpdate = !m_selectedFamily.isEmpty(); + listView->setModel(familyNames); + m_ignoreFamilyUpdate = false; + + // Will overwrite selectedFamily and selectedStyle + listView->setCurrentIndex(findFamilyInModel(m_selectedFamily, familyNames)); + + if (familyNames.isEmpty()) + _q_familyChanged(); +} + +/*! + \internal + + Updates the model for the style list view, and + attempt to reselect the style that was previously selected. + + Calls updateSizes() + */ +void QQuickFontDialogImplAttached::updateStyles() +{ + const QString family = familyListView()->currentIndex() >= 0 ? m_selectedFamily : QString(); + const QStringList styles = QFontDatabase::styles(family); + + auto listView = styleListView(); + + m_ignoreStyleUpdate = !m_selectedStyle.isEmpty(); + listView->setModel(styles); + + if (styles.isEmpty()) { + styleEdit()->clear(); + m_smoothlyScalable = false; + } else { + int newIndex = findStyleInModel(m_selectedStyle, styles); + + listView->setCurrentIndex(newIndex); + + m_selectedStyle = styles.at(newIndex); + styleEdit()->setText(m_selectedStyle); + + m_smoothlyScalable = QFontDatabase::isSmoothlyScalable(m_selectedFamily, m_selectedStyle); + } + + m_ignoreStyleUpdate = false; + + updateSizes(); +} + +/*! + \internal + + Updates the model for the size list view, + and attempts to reselect the size that was previously selected + */ +void QQuickFontDialogImplAttached::updateSizes() +{ + if (!m_selectedFamily.isEmpty()) { + const QList<int> sizes = QFontDatabase::pointSizes(m_selectedFamily, m_selectedStyle); + + QStringList str_sizes; + + str_sizes.reserve(sizes.size()); + + int idx = 0, current = -1; + for (QList<int>::const_iterator it = sizes.constBegin(); it != sizes.constEnd(); it++) { + str_sizes.append(QString::number(*it)); + if (current == -1 && m_selectedSize == *it) { + current = idx; + } + ++idx; + } + + auto listView = sizeListView(); + + // only select the first element in the model when this function is first called and the new model isn't empty + listView->setModel(str_sizes); + + if (current != -1) + listView->setCurrentIndex(current); + + sizeEdit()->setText(!m_smoothlyScalable && listView->currentIndex() > 0 + ? str_sizes.at(listView->currentIndex()) + : QString::number(m_selectedSize)); + } else { + qCWarning(lcAttachedProperty) << "Warning! selectedFamily is empty"; + sizeEdit()->clear(); + } + + _q_updateSample(); +} + +void QQuickFontDialogImplAttached::_q_updateSample() +{ + if (m_selectedFamily.isEmpty()) + return; + + const int pSize = sizeEdit()->text().toInt(); + + QFont newFont = QFontDatabase::font(m_selectedFamily, m_selectedStyle, pSize); + + newFont.setUnderline(underlineCheckBox()->isChecked()); + newFont.setStrikeOut(strikeoutCheckBox()->isChecked()); + + sampleEdit()->setFont(newFont); +} + +void QQuickFontDialogImplAttached::_q_writingSystemChanged(int index) +{ + m_writingSystem = QFontDatabase::WritingSystem(index); + sampleEdit()->setText(QFontDatabase::writingSystemSample(m_writingSystem)); + + updateFamilies(); +} + +void QQuickFontDialogImplAttached::searchListView(const QString &s, QQuickListView *listView) +{ + const QStringList model = listView->model().toStringList(); + + bool redo = false; + + do { + m_search.append(s); + + for (int i = 0; i < model.count(); ++i) { + if (model.at(i).startsWith(m_search, Qt::CaseInsensitive)) { + listView->setCurrentIndex(i); + return; + } + } + + clearSearch(); + + redo = !redo; + } while (redo); +} + +void QQuickFontDialogImplAttached::clearSearch() +{ + m_search.clear(); +} + +void QQuickFontDialogImplAttached::_q_familyChanged() +{ + if (m_ignoreFamilyUpdate) + return; + + const int index = familyListView()->currentIndex(); + + if (index < 0) { + familyEdit()->clear(); + } else { + m_selectedFamily = familyListView()->model().toStringList().at(index); + familyEdit()->setText(m_selectedFamily); + } + + updateStyles(); +} + +void QQuickFontDialogImplAttached::_q_styleChanged() +{ + if (m_ignoreStyleUpdate) + return; + + const int index = styleListView()->currentIndex(); + + if (index < 0) { + qCWarning(lcAttachedProperty) << "currentIndex changed to -1"; + return; + } + + m_selectedStyle = styleListView()->model().toStringList().at(index); + styleEdit()->setText(m_selectedStyle); + m_smoothlyScalable = QFontDatabase::isSmoothlyScalable(m_selectedFamily, m_selectedStyle); + + updateSizes(); +} + +void QQuickFontDialogImplAttached::_q_sizeEdited() +{ + const int size = qAbs(sizeEdit()->text().toInt()); + + if (size == m_selectedSize) + return; + + m_selectedSize = size; + + if (sizeListView()->count()) { + auto model = sizeListView()->model().toStringList(); + + int i; + for (i = 0; i < model.count() - 1; ++i) { + if (model.at(i).toInt() >= size) + break; + } + + QSignalBlocker blocker(sizeListView()); + if (model.at(i).toInt() == size) + sizeListView()->setCurrentIndex(i); + else + sizeListView()->setCurrentIndex(-1); + } + + _q_updateSample(); +} + +void QQuickFontDialogImplAttached::_q_sizeChanged() +{ + const int index = sizeListView()->currentIndex(); + + if (index < 0) { + qCWarning(lcAttachedProperty) << "currentIndex changed to -1"; + return; + } + + const QString s = sizeListView()->model().toStringList().at(index); + m_selectedSize = s.toInt(); + + sizeEdit()->setText(s); + + _q_updateSample(); +} + +void QQuickFontDialogImplAttachedPrivate::currentFontChanged(const QFont &font) +{ + auto fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent); + + if (!fontDialogImpl) { + return; + } + + fontDialogImpl->setCurrentFont(font); + + if (fontDialogImpl->options()->testOption(QFontDialogOptions::NoButtons)) + emit fontDialogImpl->fontSelected(font); +} + +void QQuickFontDialogImplAttached::selectFontInListViews(const QFont &font) +{ + { + QSignalBlocker blocker(sampleEdit()); + familyListView()->setCurrentIndex(findFamilyInModel(font.families().constFirst(), familyListView()->model().toStringList())); + styleListView()->setCurrentIndex(findStyleInModel(QFontDatabase::styleString(font), styleListView()->model().toStringList())); + sizeEdit()->setText(QString::number(font.pointSize())); + + underlineCheckBox()->setChecked(font.underline()); + strikeoutCheckBox()->setChecked(font.strikeOut()); + } + + _q_updateSample(); +} + +QT_END_NAMESPACE + +#include "moc_qquickfontdialogimpl_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p.h new file mode 100644 index 00000000000..899f1d4b04a --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p.h @@ -0,0 +1,217 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFONTDIALOGIMPL_P_H +#define QQUICKFONTDIALOGIMPL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qfontdatabase.h> +#include <QtQuick/private/qquicklistview_p.h> +#include <QtQuick/private/qquicktextedit_p.h> +#include <QtQuickTemplates2/private/qquicktextfield_p.h> +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquickcheckbox_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickDialogButtonBox; + +class QQuickFontDialogImplAttached; +class QQuickFontDialogImplAttachedPrivate; +class QQuickFontDialogImplPrivate; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFontDialogImpl : public QQuickDialog +{ + Q_OBJECT + Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged FINAL) + QML_NAMED_ELEMENT(FontDialogImpl) + QML_ATTACHED(QQuickFontDialogImplAttached) + QML_ADDED_IN_VERSION(6, 2) + +public: + explicit QQuickFontDialogImpl(QObject *parent = nullptr); + + static QQuickFontDialogImplAttached *qmlAttachedProperties(QObject *object); + + QSharedPointer<QFontDialogOptions> options() const; + void setOptions(const QSharedPointer<QFontDialogOptions> &options); + + QFont currentFont() const; + void setCurrentFont(const QFont &font, bool selectInListViews = false); + + void init(); + +Q_SIGNALS: + void optionsChanged(); + void currentFontChanged(const QFont &font); + void fontSelected(const QFont &font); + +private: + void keyReleaseEvent(QKeyEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + + Q_DISABLE_COPY(QQuickFontDialogImpl) + Q_DECLARE_PRIVATE(QQuickFontDialogImpl) +}; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFontDialogImplAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickListView *familyListView READ familyListView WRITE setFamilyListView + NOTIFY familyListViewChanged) + Q_PROPERTY(QQuickListView *styleListView READ styleListView WRITE setStyleListView + NOTIFY styleListViewChanged) + Q_PROPERTY(QQuickListView *sizeListView READ sizeListView WRITE setSizeListView + NOTIFY sizeListViewChanged) + Q_PROPERTY(QQuickTextEdit *sampleEdit READ sampleEdit WRITE setSampleEdit + NOTIFY sampleEditChanged) + Q_PROPERTY(QQuickDialogButtonBox *buttonBox READ buttonBox WRITE setButtonBox + NOTIFY buttonBoxChanged) + Q_PROPERTY(QQuickComboBox *writingSystemComboBox READ writingSystemComboBox + WRITE setWritingSystemComboBox NOTIFY writingSystemComboBoxChanged) + Q_PROPERTY(QQuickCheckBox *underlineCheckBox READ underlineCheckBox WRITE setUnderlineCheckBox + NOTIFY underlineCheckBoxChanged) + Q_PROPERTY(QQuickCheckBox *strikeoutCheckBox READ strikeoutCheckBox WRITE setStrikeoutCheckBox + NOTIFY strikeoutCheckBoxChanged) + + Q_PROPERTY(QQuickTextField *familyEdit READ familyEdit WRITE setFamilyEdit + NOTIFY familyEditChanged) + Q_PROPERTY(QQuickTextField *styleEdit READ styleEdit WRITE setStyleEdit NOTIFY styleEditChanged) + Q_PROPERTY(QQuickTextField *sizeEdit READ sizeEdit WRITE setSizeEdit NOTIFY sizeEditChanged) + + Q_MOC_INCLUDE(<QtQuickTemplates2 / private / qquickdialogbuttonbox_p.h>) + +public: + explicit QQuickFontDialogImplAttached(QObject *parent = nullptr); + + QQuickListView *familyListView() const; + void setFamilyListView(QQuickListView *familyListView); + + QQuickListView *styleListView() const; + void setStyleListView(QQuickListView *styleListView); + + QQuickListView *sizeListView() const; + void setSizeListView(QQuickListView *sizeListView); + + QQuickTextEdit *sampleEdit() const; + void setSampleEdit(QQuickTextEdit *sampleEdit); + + QQuickDialogButtonBox *buttonBox() const; + void setButtonBox(QQuickDialogButtonBox *buttonBox); + + QQuickComboBox *writingSystemComboBox() const; + void setWritingSystemComboBox(QQuickComboBox *writingSystemComboBox); + + QQuickCheckBox *underlineCheckBox() const; + void setUnderlineCheckBox(QQuickCheckBox *underlineCheckBox); + + QQuickCheckBox *strikeoutCheckBox() const; + void setStrikeoutCheckBox(QQuickCheckBox *strikethroughCheckBox); + + QQuickTextField *familyEdit() const; + void setFamilyEdit(QQuickTextField *familyEdit); + + QQuickTextField *styleEdit() const; + void setStyleEdit(QQuickTextField *styleEdit); + + QQuickTextField *sizeEdit() const; + void setSizeEdit(QQuickTextField *sizeEdit); + +Q_SIGNALS: + void buttonBoxChanged(); + void familyListViewChanged(); + void styleListViewChanged(); + void sizeListViewChanged(); + void sampleEditChanged(); + void writingSystemComboBoxChanged(); + void underlineCheckBoxChanged(); + void strikeoutCheckBoxChanged(); + void familyEditChanged(); + void styleEditChanged(); + void sizeEditChanged(); + +public: + void searchFamily(const QString &s) { searchListView(s, familyListView()); } + void searchStyle(const QString &s) { searchListView(s, styleListView()); } + void clearSearch(); + + void updateFamilies(); + void selectFontInListViews(const QFont &font); + +private: + void updateStyles(); + void updateSizes(); + + void _q_familyChanged(); + void _q_styleChanged(); + void _q_sizeEdited(); + void _q_sizeChanged(); + void _q_updateSample(); + + void _q_writingSystemChanged(int index); + + void searchListView(const QString &s, QQuickListView *listView); + + QFontDatabase::WritingSystem m_writingSystem; + QString m_selectedFamily; + QString m_selectedStyle; + QString m_search; + int m_selectedSize; + bool m_smoothlyScalable; + bool m_ignoreFamilyUpdate; + bool m_ignoreStyleUpdate; + + Q_DISABLE_COPY(QQuickFontDialogImplAttached) + Q_DECLARE_PRIVATE(QQuickFontDialogImplAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFontDialogImpl) + +#endif // QQUICKFONTDIALOGIMPL_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p_p.h new file mode 100644 index 00000000000..8de3480dd90 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFONTDIALOGIMPL_P_P_H +#define QQUICKFONTDIALOGIMPL_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h> + +#include "qquickfontdialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFontDialogImplPrivate : public QQuickDialogPrivate +{ + Q_DECLARE_PUBLIC(QQuickFontDialogImpl) +public: + QQuickFontDialogImplPrivate(); + + static QQuickFontDialogImplPrivate *get(QQuickFontDialogImpl *dialog) + { + return dialog->d_func(); + } + + QQuickFontDialogImplAttached *attachedOrWarn(); + + void updateEnabled(); + + void handleAccept() override; + void handleClick(QQuickAbstractButton *button) override; + + QSharedPointer<QFontDialogOptions> options; + + QFont currentFont; +}; + +class QQuickFontDialogImplAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickFontDialogImplAttached) + + void currentFontChanged(const QFont &font); + +public: + QPointer<QQuickDialogButtonBox> buttonBox; + QPointer<QQuickListView> familyListView; + QPointer<QQuickListView> styleListView; + QPointer<QQuickListView> sizeListView; + QPointer<QQuickTextEdit> sampleEdit; + QPointer<QQuickComboBox> writingSystemComboBox; + QPointer<QQuickCheckBox> underlineCheckBox; + QPointer<QQuickCheckBox> strikeoutCheckBox; + QPointer<QQuickTextField> familyEdit; + QPointer<QQuickTextField> styleEdit; + QPointer<QQuickTextField> sizeEdit; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFONTDIALOGIMPL_P_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfiledialog.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfiledialog.cpp new file mode 100644 index 00000000000..a2d0f8f41c5 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfiledialog.cpp @@ -0,0 +1,228 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickplatformfiledialog_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtGui/qwindow.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p_p.h> +#include <QtQuickTemplates2/private/qquickpopupanchors_p.h> + +#include "qquickfiledialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcQuickPlatformFileDialog, "qt.quick.dialogs.quickplatformfiledialog") + +/*! + \class QQuickPlatformFileDialog + \internal + + An interface that QQuickFileDialog can use to access the non-native Qt Quick FileDialog. + + Both this and the native implementations are created in QQuickAbstractDialog::create(). +*/ +QQuickPlatformFileDialog::QQuickPlatformFileDialog(QObject *parent) +{ + qCDebug(lcQuickPlatformFileDialog) << "creating non-native Qt Quick FileDialog with parent" << parent; + + // Set a parent so that we get deleted if we can't be shown for whatever reason. + // Our eventual parent should be the window, though. + setParent(parent); + + auto qmlContext = ::qmlContext(parent); + if (!qmlContext) { + qmlWarning(parent) << "No QQmlContext for QQuickPlatformFileDialog; can't create non-native FileDialog implementation"; + return; + } + + const auto dialogQmlUrl = QUrl(QStringLiteral("qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/qml/FileDialog.qml")); + QQmlComponent fileDialogComponent(qmlContext->engine(), dialogQmlUrl, parent); + if (!fileDialogComponent.isReady()) { + qmlWarning(parent) << "Failed to load non-native FileDialog implementation:\n" << fileDialogComponent.errorString(); + return; + } + m_dialog = qobject_cast<QQuickFileDialogImpl*>(fileDialogComponent.create()); + if (!m_dialog) { + qmlWarning(parent) << "Failed to create an instance of the non-native FileDialog:\n" << fileDialogComponent.errorString(); + return; + } + // Give it a parent until it's parented to the window in show(). + m_dialog->setParent(this); + + connect(m_dialog, &QQuickDialog::accepted, this, &QPlatformDialogHelper::accept); + connect(m_dialog, &QQuickDialog::rejected, this, &QPlatformDialogHelper::reject); + + connect(m_dialog, &QQuickFileDialogImpl::fileSelected, this, &QQuickPlatformFileDialog::fileSelected); + // TODO: add support for multiple file selection (QTBUG-92585) +// connect(m_dialog, &QQuickFileDialogImpl::filesSelected, [this](const QList<QString> &files) { +// QList<QUrl> urls; +// urls.reserve(files.count()); +// for (const QString &file : files) +// urls += QUrl::fromLocalFile(file); +// emit filesSelected(urls); +// }); + connect(m_dialog, &QQuickFileDialogImpl::currentFileChanged, this, &QQuickPlatformFileDialog::currentChanged); + connect(m_dialog, &QQuickFileDialogImpl::currentFolderChanged, this, &QQuickPlatformFileDialog::directoryEntered); + connect(m_dialog, &QQuickFileDialogImpl::filterSelected, this, &QQuickPlatformFileDialog::filterSelected); + + // We would do this in QQuickFileDialogImpl, but we need to ensure that folderChanged() + // is connected to directoryEntered() before setting it to ensure that the QQuickFileDialog is notified. + if (m_dialog->currentFolder().isEmpty()) + m_dialog->setCurrentFolder(QUrl::fromLocalFile(QDir().absolutePath())); +} + +bool QQuickPlatformFileDialog::isValid() const +{ + return m_dialog; +} + +bool QQuickPlatformFileDialog::defaultNameFilterDisables() const +{ + return false; +} + +void QQuickPlatformFileDialog::setDirectory(const QUrl &directory) +{ + if (!m_dialog) + return; + + m_dialog->setCurrentFolder(directory); +} + +QUrl QQuickPlatformFileDialog::directory() const +{ + if (!m_dialog) + return {}; + + return m_dialog->currentFolder(); +} + +void QQuickPlatformFileDialog::selectFile(const QUrl &file) +{ + if (!m_dialog) + return; + + m_dialog->setSelectedFile(file); +} + +QList<QUrl> QQuickPlatformFileDialog::selectedFiles() const +{ + // TODO: support for multiple selected files + return { m_dialog->currentFile() }; +} + +void QQuickPlatformFileDialog::setFilter() +{ +} + +void QQuickPlatformFileDialog::selectNameFilter(const QString &filter) +{ + // There is a bit of a problem with order here - QQuickFileDialog::onShow() + // is called before our show(), but it needs to set the selected filter + // (which we can't do in our show() because we don't know about QQuickFileDialog). + // So, delay setting the filter until we're shown. This shouldn't be an issue + // in practice, since it doesn't make sense for the filter to programmatically + // change while the dialog is visible. + m_pendingNameFilter = filter; +} + +QString QQuickPlatformFileDialog::selectedNameFilter() const +{ + return m_dialog->selectedNameFilter()->name(); +} + +void QQuickPlatformFileDialog::exec() +{ + qCWarning(lcQuickPlatformFileDialog) << "exec() is not supported for the Qt Quick FileDialog fallback"; +} + +bool QQuickPlatformFileDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) +{ + qCDebug(lcQuickPlatformFileDialog) << "show called with flags" << flags << + "modality" << modality << "parent" << parent; + if (!m_dialog) + return false; + + if (!parent) + return false; + + auto quickWindow = qobject_cast<QQuickWindow*>(parent); + if (!quickWindow) { + qmlInfo(this->parent()) << "Parent window (" << parent << ") of non-native dialog is not a QQuickWindow"; + return false; + } + m_dialog->setParent(parent); + m_dialog->resetParentItem(); + + auto popupPrivate = QQuickPopupPrivate::get(m_dialog); + popupPrivate->getAnchors()->setCenterIn(m_dialog->parentItem()); + + QSharedPointer<QFileDialogOptions> options = QPlatformFileDialogHelper::options(); + m_dialog->setTitle(options->windowTitle()); + m_dialog->setOptions(options); + m_dialog->selectNameFilter(m_pendingNameFilter); + m_pendingNameFilter.clear(); + m_dialog->setAcceptLabel(options->isLabelExplicitlySet(QFileDialogOptions::Accept) + ? options->labelText(QFileDialogOptions::Accept) : QString()); + m_dialog->setRejectLabel(options->isLabelExplicitlySet(QFileDialogOptions::Reject) + ? options->labelText(QFileDialogOptions::Reject) : QString()); + + m_dialog->open(); + return true; +} + +void QQuickPlatformFileDialog::hide() +{ + if (!m_dialog) + return; + + m_dialog->close(); +} + +QQuickFileDialogImpl *QQuickPlatformFileDialog::dialog() const +{ + return m_dialog; +} + +QT_END_NAMESPACE + +#include "moc_qquickplatformfiledialog_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfiledialog_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfiledialog_p.h new file mode 100644 index 00000000000..883b7ed9b7b --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfiledialog_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPLATFORMFILEDIALOG_P_H +#define QQUICKPLATFORMFILEDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qpa/qplatformdialoghelper.h> + +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFileDialogImpl; +class QWindow; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickPlatformFileDialog : public QPlatformFileDialogHelper +{ + Q_OBJECT + +public: + explicit QQuickPlatformFileDialog(QObject *parent); + ~QQuickPlatformFileDialog() = default; + + bool isValid() const; + bool defaultNameFilterDisables() const override; + void setDirectory(const QUrl &directory) override; + QUrl directory() const override; + void selectFile(const QUrl &file) override; + QList<QUrl> selectedFiles() const override; + void setFilter() override; + void selectNameFilter(const QString &filter) override; + QString selectedNameFilter() const override; + + void exec() override; + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) override; + void hide() override; + + QQuickFileDialogImpl *dialog() const; + +private: + QQuickFileDialogImpl *m_dialog = nullptr; + QString m_pendingNameFilter; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPLATFORMFILEDIALOG_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog.cpp new file mode 100644 index 00000000000..0512ac15817 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog.cpp @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickplatformfontdialog_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtGui/qwindow.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p_p.h> +#include <QtQuickTemplates2/private/qquickpopupanchors_p.h> + +#include "qquickfontdialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcQuickPlatformFontDialog, "qt.quick.dialogs.quickplatformfontdialog") + +/*! + \class QQuickPlatformFontDialog + \internal + + An interface that QQuickFontDialog can use to access the non-native Qt Quick FontDialog. + + Both this and the native implementations are created in QQuickAbstractDialog::create(). + +*/ +QQuickPlatformFontDialog::QQuickPlatformFontDialog(QObject *parent) +{ + qCDebug(lcQuickPlatformFontDialog) + << "creating non-native Qt Quick FontDialog with parent" << parent; + + // Set a parent so that we get deleted if we can't be shown for whatever reason. + // Our eventual parent should be the window, though. + setParent(parent); + + auto qmlContext = ::qmlContext(parent); + if (!qmlContext) { + qmlWarning(parent) << "No QQmlContext for QQuickPlatformFontDialog; can't create " + "non-native FontDialog implementation"; + return; + } + + const auto dialogQmlUrl = QUrl(QStringLiteral( + "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/qml/FontDialog.qml")); + + QQmlComponent fontDialogComponent(qmlContext->engine(), dialogQmlUrl, parent); + if (!fontDialogComponent.isReady()) { + qmlWarning(parent) << "Failed to load non-native FontDialog implementation:\n" + << fontDialogComponent.errorString(); + return; + } + + m_dialog = qobject_cast<QQuickFontDialogImpl *>(fontDialogComponent.create()); + + if (!m_dialog) { + qmlWarning(parent) << "Failed to create an instance of the non-native FontDialog:\n" + << fontDialogComponent.errorString(); + return; + } + + m_dialog->setParent(this); + + connect(m_dialog, &QQuickDialog::accepted, this, &QPlatformDialogHelper::accept); + connect(m_dialog, &QQuickDialog::rejected, this, &QPlatformDialogHelper::reject); + + connect(m_dialog, &QQuickFontDialogImpl::currentFontChanged, + this, &QQuickPlatformFontDialog::currentFontChanged); + connect(m_dialog, &QQuickFontDialogImpl::fontSelected, this, &QQuickPlatformFontDialog::fontSelected); +} + +bool QQuickPlatformFontDialog::isValid() const +{ + return m_dialog; +} + +void QQuickPlatformFontDialog::setCurrentFont(const QFont &font) +{ + if (m_dialog) + m_dialog->setCurrentFont(font, true); +} + +QFont QQuickPlatformFontDialog::currentFont() const +{ + return m_dialog ? m_dialog->currentFont() : QFont(); +} + +void QQuickPlatformFontDialog::exec() +{ + qCWarning(lcQuickPlatformFontDialog) + << "exec() is not supported for the Qt Quick FontDialog fallback"; +} + +bool QQuickPlatformFontDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, + QWindow *parent) +{ + qCDebug(lcQuickPlatformFontDialog) + << "show called with flags" << flags << "modality" << modality << "parent" << parent; + + if (!isValid()) + return false; + + if (!parent) + return false; + + auto quickWindow = qobject_cast<QQuickWindow *>(parent); + if (!quickWindow) { + qmlInfo(this->parent()) << "Parent window (" << parent + << ") of non-native dialog is not a QQuickWindow"; + return false; + } + m_dialog->setParent(parent); + m_dialog->resetParentItem(); + + auto popupPrivate = QQuickPopupPrivate::get(m_dialog); + popupPrivate->getAnchors()->setCenterIn(m_dialog->parentItem()); + + QSharedPointer<QFontDialogOptions> options = QPlatformFontDialogHelper::options(); + m_dialog->setTitle(options->windowTitle()); + m_dialog->setOptions(options); + + m_dialog->init(); + + m_dialog->open(); + return true; +} + +void QQuickPlatformFontDialog::hide() +{ + if (isValid()) + m_dialog->close(); +} + +QQuickFontDialogImpl *QQuickPlatformFontDialog::dialog() const +{ + return m_dialog; +} + +QT_END_NAMESPACE + +#include "moc_qquickplatformfontdialog_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog_p.h new file mode 100644 index 00000000000..a5009facabc --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPLATFORMFONTDIALOG_P_H +#define QQUICKPLATFORMFONTDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qpa/qplatformdialoghelper.h> + +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFontDialogImpl; +class QWindow; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickPlatformFontDialog + : public QPlatformFontDialogHelper +{ + Q_OBJECT + +public: + explicit QQuickPlatformFontDialog(QObject *parent); + ~QQuickPlatformFontDialog() = default; + + bool isValid() const; + + virtual void setCurrentFont(const QFont &font) override; + virtual QFont currentFont() const override; + + void exec() override; + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) override; + void hide() override; + + QQuickFontDialogImpl *dialog() const; + +private: + QQuickFontDialogImpl *m_dialog = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPLATFORMFONTDIALOG_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qtquickdialogs2quickimplforeign_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qtquickdialogs2quickimplforeign_p.h new file mode 100644 index 00000000000..b1740606e3d --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qtquickdialogs2quickimplforeign_p.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTQUICKDIALOGS2QUICKIMPLFOREIGN_P_H +#define QTQUICKDIALOGS2QUICKIMPLFOREIGN_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/qqml.h> +#include <QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include <QtQuickTemplates2/private/qquickicon_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p.h> + +QT_BEGIN_NAMESPACE + +struct QQuickFileNameFilterQuickDialogs2QuickImplForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickFileNameFilter) + QML_ADDED_IN_VERSION(6, 2) +}; + +// TODO: remove these ones when not needed (QTBUG-88179) + +// verticalPadding, etc. +struct QQuickControlForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickControl) + QML_ADDED_IN_VERSION(2, 0) +}; + +struct QQuickAbstractButtonForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickAbstractButton) + QML_ADDED_IN_VERSION(2, 0) +}; + +struct QQuickIconForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickIcon) + QML_ADDED_IN_VERSION(6, 2) +}; + +// For leftInset, etc. +struct QQuickPopupForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickPopup) + QML_ADDED_IN_VERSION(2, 0) +}; + +struct QQuickDialogForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickDialog) + QML_ADDED_IN_VERSION(2, 1) +}; + +QT_END_NAMESPACE + +#endif // QTQUICKDIALOGS2QUICKIMPLFOREIGN_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qtquickdialogs2quickimplglobal_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qtquickdialogs2quickimplglobal_p.h new file mode 100644 index 00000000000..38b5a01beab --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qtquickdialogs2quickimplglobal_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTQUICKDIALOGS2QUICKIMPLGLOBAL_P_H +#define QTQUICKDIALOGS2QUICKIMPLGLOBAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> +#include <QtQml/private/qqmlglobal_p.h> + +QT_BEGIN_NAMESPACE + +#ifndef QT_STATIC +# if defined(QT_BUILD_QUICKDIALOGS2QUICKIMPL_LIB) +# define Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT Q_DECL_EXPORT +# else +# define Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT Q_DECL_IMPORT +# endif +#else +# define Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT +#endif + +QT_END_NAMESPACE + +#endif // QTQUICKDIALOGS2QUICKIMPLGLOBAL_P_H diff --git a/src/quickdialogs2/quickdialogs2utils/CMakeLists.txt b/src/quickdialogs2/quickdialogs2utils/CMakeLists.txt new file mode 100644 index 00000000000..0242ffcf6c4 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2utils/CMakeLists.txt @@ -0,0 +1,23 @@ +# This library exists because QuickDialogs2 and QuickDialogs2QuickImpl +# both need QQuickNameFilter. QQuickNameFilter was originally in +# QuickDialogs2. Since QuickDialogs2 already links to +# QuickDialogs2QuickImpl, making the latter link to the former (to get +# access to QQuickNameFilter) would result in a circular dependency, +# so we have this library as a result. + +qt_internal_add_module(QuickDialogs2Utils + SOURCES + qquickfilenamefilter.cpp + qquickfilenamefilter_p.h + qtquickdialogs2utilsglobal_p.h + DEFINES + QT_BUILD_QUICKDIALOGS2UTILS_LIB + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_SOURCE_DIR} + LIBRARIES + Qt::GuiPrivate + PUBLIC_LIBRARIES + Qt::Core +) diff --git a/src/quickdialogs2/quickdialogs2utils/qquickfilenamefilter.cpp b/src/quickdialogs2/quickdialogs2utils/qquickfilenamefilter.cpp new file mode 100644 index 00000000000..0d99d337898 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2utils/qquickfilenamefilter.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfilenamefilter_p.h" + +#include <QtCore/qloggingcategory.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcFileNameFilter, "qt.quick.dialogs.qquickfilenamefilter") + +QQuickFileNameFilter::QQuickFileNameFilter(QObject *parent) + : QObject(parent), m_index(-1) +{ +} + +int QQuickFileNameFilter::index() const +{ + return m_index; +} + +void QQuickFileNameFilter::setIndex(int index) +{ + if (m_index == index) + return; + + m_index = index; + emit indexChanged(index); +} + +QString QQuickFileNameFilter::name() const +{ + return m_name; +} + +QStringList QQuickFileNameFilter::extensions() const +{ + return m_extensions; +} + +QStringList QQuickFileNameFilter::globs() const +{ + return m_globs; +} + +QSharedPointer<QFileDialogOptions> QQuickFileNameFilter::options() const +{ + return m_options; +} + +void QQuickFileNameFilter::setOptions(const QSharedPointer<QFileDialogOptions> &options) +{ + m_options = options; +} + +static QString extractName(const QString &filter) +{ + return filter.left(filter.indexOf(QLatin1Char('(')) - 1); +} + +static QString extractExtension(QStringView filter) +{ + return filter.mid(filter.indexOf(QLatin1Char('.')) + 1).toString(); +} + +static void extractExtensionsAndGlobs(QStringView filter, QStringList &extensions, QStringList &globs) +{ + extensions.clear(); + globs.clear(); + + const int from = filter.indexOf(QLatin1Char('(')); + const int to = filter.lastIndexOf(QLatin1Char(')')) - 1; + if (from >= 0 && from < to) { + const QStringView ref = filter.mid(from + 1, to - from); + const QList<QStringView> exts = ref.split(QLatin1Char(' '), Qt::SkipEmptyParts); + // For example, given the filter "HTML files (*.html *.htm)", + // "ref" would be "*.html" and "*.htm". + for (const QStringView &ref : exts) { + extensions += extractExtension(ref); + globs += ref.toString(); + } + } +} + +void QQuickFileNameFilter::update(const QString &filter) +{ + const QStringList filters = nameFilters(); + + const int oldIndex = m_index; + const QString oldName = m_name; + const QStringList oldExtensions = m_extensions; + const QStringList oldGlobs = m_globs; + + m_index = filters.indexOf(filter); + m_name = extractName(filter); + extractExtensionsAndGlobs(filter, m_extensions, m_globs); + + if (oldIndex != m_index) + emit indexChanged(m_index); + if (oldName != m_name) + emit nameChanged(m_name); + if (oldExtensions != m_extensions) + emit extensionsChanged(m_extensions); + if (oldGlobs != m_globs) + emit globsChanged(m_globs); + + qCDebug(lcFileNameFilter).nospace() << "update called on " << this << " of " << parent() + << " with filter " << filter << " (current filters are " << filters << "):" + << "\n old index=" << oldIndex << "new index=" << m_index + << "\n old name=" << oldName << "new name=" << m_name + << "\n old extensions=" << oldExtensions << "new extensions=" << m_extensions + << "\n old glob=s" << oldGlobs << "new globs=" << m_globs; +} + +QStringList QQuickFileNameFilter::nameFilters() const +{ + return m_options ? m_options->nameFilters() : QStringList(); +} + +QString QQuickFileNameFilter::nameFilter(int index) const +{ + return m_options ? m_options->nameFilters().value(index) : QString(); +} + +QT_END_NAMESPACE + +#include "moc_qquickfilenamefilter_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2utils/qquickfilenamefilter_p.h b/src/quickdialogs2/quickdialogs2utils/qquickfilenamefilter_p.h new file mode 100644 index 00000000000..586da8698a9 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2utils/qquickfilenamefilter_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFILENAMEFILTER_P_H +#define QQUICKFILENAMEFILTER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtCore/qsharedpointer.h> +#include <QtCore/qstringlist.h> +#include <QtGui/qpa/qplatformdialoghelper.h> + +#include "qtquickdialogs2utilsglobal_p.h" + +QT_BEGIN_NAMESPACE + +class Q_QUICKDIALOGS2UTILS_PRIVATE_EXPORT QQuickFileNameFilter : public QObject +{ + Q_OBJECT + Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged FINAL) + Q_PROPERTY(QString name READ name NOTIFY nameChanged FINAL) + Q_PROPERTY(QStringList extensions READ extensions NOTIFY extensionsChanged FINAL) + Q_PROPERTY(QStringList globs READ globs NOTIFY globsChanged FINAL) + +public: + explicit QQuickFileNameFilter(QObject *parent = nullptr); + + int index() const; + void setIndex(int index); + + QString name() const; + QStringList extensions() const; + QStringList globs() const; + + QSharedPointer<QFileDialogOptions> options() const; + void setOptions(const QSharedPointer<QFileDialogOptions> &options); + + void update(const QString &filter); + +Q_SIGNALS: + void indexChanged(int index); + void nameChanged(const QString &name); + void extensionsChanged(const QStringList &extensions); + void globsChanged(const QStringList &globs); + +private: + QStringList nameFilters() const; + QString nameFilter(int index) const; + + int m_index; + QString m_name; + QStringList m_extensions; + QStringList m_globs; + QSharedPointer<QFileDialogOptions> m_options; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFILENAMEFILTER_P_H diff --git a/src/quickdialogs2/quickdialogs2utils/qtquickdialogs2utilsglobal_p.h b/src/quickdialogs2/quickdialogs2utils/qtquickdialogs2utilsglobal_p.h new file mode 100644 index 00000000000..52f7a397843 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2utils/qtquickdialogs2utilsglobal_p.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTQUICKDIALOGS2UTILSGLOBAL_P_H +#define QTQUICKDIALOGS2UTILSGLOBAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +#ifndef QT_STATIC +# if defined(QT_BUILD_QUICKDIALOGS2UTILS_LIB) +# define Q_QUICKDIALOGS2UTILS_PRIVATE_EXPORT Q_DECL_EXPORT +# else +# define Q_QUICKDIALOGS2UTILS_PRIVATE_EXPORT Q_DECL_IMPORT +# endif +#else +# define Q_QUICKDIALOGS2UTILS_PRIVATE_EXPORT +#endif + +QT_END_NAMESPACE + +#endif // QTQUICKDIALOGS2UTILSUTILSGLOBAL_P_H diff --git a/src/quicklayouts/qquickgridlayoutengine.cpp b/src/quicklayouts/qquickgridlayoutengine.cpp index 5275d70c393..234c3a0d9b2 100644 --- a/src/quicklayouts/qquickgridlayoutengine.cpp +++ b/src/quicklayouts/qquickgridlayoutengine.cpp @@ -51,11 +51,4 @@ void QQuickGridLayoutEngine::setAlignment(QQuickItem *quickItem, Qt::Alignment a } } -Qt::Alignment QQuickGridLayoutEngine::alignment(QQuickItem *quickItem) const -{ - if (QGridLayoutItem *item = findLayoutItem(quickItem)) - return item->alignment(); - return {}; -} - QT_END_NAMESPACE diff --git a/src/quicklayouts/qquickgridlayoutengine_p.h b/src/quicklayouts/qquickgridlayoutengine_p.h index ff42fa4d432..8b1a000e420 100644 --- a/src/quicklayouts/qquickgridlayoutengine_p.h +++ b/src/quicklayouts/qquickgridlayoutengine_p.h @@ -154,7 +154,6 @@ class QQuickGridLayoutEngine : public QGridLayoutEngine { } void setAlignment(QQuickItem *quickItem, Qt::Alignment alignment); - Qt::Alignment alignment(QQuickItem *quickItem) const; }; diff --git a/src/quicklayouts/qquicklayout.cpp b/src/quicklayouts/qquicklayout.cpp index d4841e770f6..80fea6923a2 100644 --- a/src/quicklayouts/qquicklayout.cpp +++ b/src/quicklayouts/qquicklayout.cpp @@ -73,7 +73,11 @@ The \l fillWidth and \l fillHeight properties can either be \c true or \c false. If they are \c false, the item's size will be fixed to its preferred size. Otherwise, it will grow or shrink - between its minimum and maximum size as the layout is resized. + between its minimum and maximum size as the layout is resized. If there are multiple items + with \l fillWidth (or \l fillHeight) set to \c true, the layout will grow or shrink the items + relative to the ratio of their preferred size. + + For more details on the layout algorithm, see also the \l {Qt Quick Layouts Overview}. \note Do not bind to the x, y, width, or height properties of items in a layout, as this would conflict with the goals of Layout, and can also cause binding loops. @@ -786,6 +790,18 @@ void QQuickLayout::componentComplete() d->m_isReady = true; } +void QQuickLayout::maybeSubscribeToBaseLineOffsetChanges(QQuickItem *item) +{ + QQuickLayoutAttached *info = attachedLayoutObject(item, false); + if (info) { + if (info->alignment() == Qt::AlignBaseline && static_cast<QQuickLayout*>(item->parentItem()) == this) { + qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem())); + } else { + qmlobject_disconnect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem())); + } + } +} + void QQuickLayout::invalidate(QQuickItem * /*childItem*/) { Q_D(QQuickLayout); @@ -809,7 +825,7 @@ void QQuickLayout::invalidate(QQuickItem * /*childItem*/) qCDebug(lcQuickLayouts) << "QQuickLayout::invalidate(), polish()"; polish(); } else { - qWarning() << "Qt Quick Layouts: Polish loop detected. Aborting after two iterations."; + qmlWarning(this) << "Qt Quick Layouts: Polish loop detected. Aborting after two iterations."; } } } @@ -860,7 +876,7 @@ void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value) if (change == ItemChildAddedChange) { Q_D(QQuickLayout); QQuickItem *item = value.item; - qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem())); + maybeSubscribeToBaseLineOffsetChanges(item); QQuickItemPrivate::get(item)->addItemChangeListener(this, changeTypes); d->m_hasItemChangeListeners = true; qCDebug(lcQuickLayouts) << "ChildAdded" << item; @@ -868,7 +884,7 @@ void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value) invalidate(); } else if (change == ItemChildRemovedChange) { QQuickItem *item = value.item; - qmlobject_disconnect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem())); + maybeSubscribeToBaseLineOffsetChanges(item); QQuickItemPrivate::get(item)->removeItemChangeListener(this, changeTypes); qCDebug(lcQuickLayouts) << "ChildRemoved" << item; if (isReady()) @@ -1306,3 +1322,5 @@ void QQuickLayout::dumpLayoutTreeRecursive(int level, QString &buf) const } QT_END_NAMESPACE + +#include "moc_qquicklayout_p.cpp" diff --git a/src/quicklayouts/qquicklayout_p.h b/src/quicklayouts/qquicklayout_p.h index 0d577a113e8..141fb3c8dae 100644 --- a/src/quicklayouts/qquicklayout_p.h +++ b/src/quicklayouts/qquicklayout_p.h @@ -121,6 +121,8 @@ class Q_QUICKLAYOUT_PRIVATE_EXPORT QQuickLayout : public QQuickItem, public QQui void itemDestroyed(QQuickItem *item) override; void itemVisibilityChanged(QQuickItem *item) override; + void maybeSubscribeToBaseLineOffsetChanges(QQuickItem *item); + Q_INVOKABLE void _q_dumpLayoutTree() const; void dumpLayoutTreeRecursive(int level, QString &buf) const; @@ -173,7 +175,6 @@ class QQuickLayoutPrivate : public QQuickItemPrivate unsigned m_isReady : 1; unsigned m_disableRearrange : 1; unsigned m_hasItemChangeListeners : 1; // if false, we don't need to remove its item change listeners... - mutable QSet<QQuickItem *> m_ignoredItems; }; diff --git a/src/quicklayouts/qquicklayoutglobal_p.h b/src/quicklayouts/qquicklayoutglobal_p.h index c63169bd93d..7163d5a0d4b 100644 --- a/src/quicklayouts/qquicklayoutglobal_p.h +++ b/src/quicklayouts/qquicklayoutglobal_p.h @@ -70,6 +70,4 @@ QT_BEGIN_NAMESPACE QT_END_NAMESPACE -void Q_QUICKLAYOUT_PRIVATE_EXPORT qml_register_types_QtQuick_Layouts(); - #endif // QQUICKLAYOUTGLOBAL_P_H diff --git a/src/quicklayouts/qquicklinearlayout.cpp b/src/quicklayouts/qquicklinearlayout.cpp index 2f97708b529..dc55196c11b 100644 --- a/src/quicklayouts/qquicklinearlayout.cpp +++ b/src/quicklayouts/qquicklinearlayout.cpp @@ -53,6 +53,10 @@ \ingroup layouts \brief Identical to \l GridLayout, but having only one row. + To be able to use this type more efficiently, it is recommended that you + understand the general mechanism of the Qt Quick Layouts module. Refer to + \l{Qt Quick Layouts Overview} for more information. + It is available as a convenience for developers, as it offers a cleaner API. Items in a RowLayout support these attached properties: @@ -96,7 +100,9 @@ Read more about attached properties \l{QML Object Attributes}{here}. \sa ColumnLayout \sa GridLayout + \sa StackLayout \sa Row + \sa {Qt Quick Layouts Overview} */ /*! @@ -107,6 +113,10 @@ \ingroup layouts \brief Identical to \l GridLayout, but having only one column. + To be able to use this type more efficiently, it is recommended that you + understand the general mechanism of the Qt Quick Layouts module. Refer to + \l{Qt Quick Layouts Overview} for more information. + It is available as a convenience for developers, as it offers a cleaner API. Items in a ColumnLayout support these attached properties: @@ -148,7 +158,9 @@ \sa RowLayout \sa GridLayout + \sa StackLayout \sa Column + \sa {Qt Quick Layouts Overview} */ @@ -160,7 +172,9 @@ \ingroup layouts \brief Provides a way of dynamically arranging items in a grid. - + To be able to use this type more efficiently, it is recommended that you + understand the general mechanism of the Qt Quick Layouts module. Refer to + \l{Qt Quick Layouts Overview} for more information. If the GridLayout is resized, all items in the layout will be rearranged. It is similar to the widget-based QGridLayout. All visible children of the GridLayout element will belong to @@ -212,7 +226,9 @@ \sa RowLayout \sa ColumnLayout + \sa StackLayout \sa Grid + \sa {Qt Quick Layouts Overview} */ @@ -268,10 +284,8 @@ QSizeF QQuickGridLayoutBase::sizeHint(Qt::SizeHint whichSizeHint) const Possible values: - \list - \li Qt.LeftToRight (default) - Items are laid out from left to right. - \li Qt.RightToLeft - Items are laid out from right to left. - \endlist + \value Qt.LeftToRight (default) Items are laid out from left to right. + \value Qt.RightToLeft Items are laid out from right to left. \sa RowLayout::layoutDirection, ColumnLayout::layoutDirection */ @@ -302,6 +316,7 @@ void QQuickGridLayoutBase::setAlignment(QQuickItem *item, Qt::Alignment alignmen { Q_D(QQuickGridLayoutBase); d->engine.setAlignment(item, alignment); + maybeSubscribeToBaseLineOffsetChanges(item); } QQuickGridLayoutBase::~QQuickGridLayoutBase() @@ -624,12 +639,10 @@ void QQuickGridLayout::setRows(int rows) Possible values are: - \list - \li GridLayout.LeftToRight (default) - Items are positioned next to - each other, then wrapped to the next line. - \li GridLayout.TopToBottom - Items are positioned next to each - other from top to bottom, then wrapped to the next column. - \endlist + \value GridLayout.LeftToRight + (default) Items are positioned next to each other, then wrapped to the next line. + \value GridLayout.TopToBottom + Items are positioned next to each other from top to bottom, then wrapped to the next column. \sa rows \sa columns @@ -796,10 +809,8 @@ QQuickLinearLayout::QQuickLinearLayout(Qt::Orientation orientation, Possible values: - \list - \li Qt.LeftToRight (default) - Items are laid out from left to right. - \li Qt.RightToLeft - Items are laid out from right to left - \endlist + \value Qt.LeftToRight (default) Items are laid out from left to right. + \value Qt.RightToLeft Items are laid out from right to left \sa GridLayout::layoutDirection, ColumnLayout::layoutDirection */ @@ -813,10 +824,8 @@ QQuickLinearLayout::QQuickLinearLayout(Qt::Orientation orientation, Possible values: - \list - \li Qt.LeftToRight (default) - Items are laid out from left to right. - \li Qt.RightToLeft - Items are laid out from right to left - \endlist + \value Qt.LeftToRight (default) Items are laid out from left to right. + \value Qt.RightToLeft Items are laid out from right to left \sa GridLayout::layoutDirection, RowLayout::layoutDirection */ diff --git a/src/quicklayouts/qquickstacklayout.cpp b/src/quicklayouts/qquickstacklayout.cpp index 19d0033e8b9..e49b18e5f26 100644 --- a/src/quicklayouts/qquickstacklayout.cpp +++ b/src/quicklayouts/qquickstacklayout.cpp @@ -52,6 +52,10 @@ \brief The StackLayout class provides a stack of items where only one item is visible at a time. + To be able to use this type more efficiently, it is recommended that you + understand the general mechanism of the Qt Quick Layouts module. Refer to + \l{Qt Quick Layouts Overview} for more information. + The current visible item can be modified by setting the \l currentIndex property. The index corresponds to the order of the StackLayout's children. @@ -98,6 +102,7 @@ \sa GridLayout \sa RowLayout \sa {QtQuick.Controls::StackView}{StackView} + \sa {Qt Quick Layouts Overview} */ QT_BEGIN_NAMESPACE @@ -200,6 +205,7 @@ void QQuickStackLayout::itemChange(QQuickItem::ItemChange change, const QQuickIt stackLayoutAttached->setIndex(-1); stackLayoutAttached->setIsCurrentItem(false); } + m_cachedItemSizeHints.remove(item); invalidate(); } else if (change == ItemChildAddedChange) { invalidate(); @@ -221,10 +227,8 @@ QSizeF QQuickStackLayout::sizeHint(Qt::SizeHint whichSizeHint) const maxS = QSizeF(std::numeric_limits<qreal>::infinity(), std::numeric_limits<qreal>::infinity()); const int count = itemCount(); - m_cachedItemSizeHints.resize(count); for (int i = 0; i < count; ++i) { - SizeHints &hints = m_cachedItemSizeHints[i]; - QQuickStackLayout::collectItemSizeHints(itemAt(i), hints.array); + SizeHints &hints = cachedItemSizeHints(i); minS = minS.expandedTo(hints.min()); prefS = prefS.expandedTo(hints.pref()); //maxS = maxS.boundedTo(hints.max()); // Can be resized to be larger than any of its items. @@ -290,11 +294,12 @@ void QQuickStackLayout::setAlignment(QQuickItem * /*item*/, Qt::Alignment /*alig void QQuickStackLayout::invalidate(QQuickItem *childItem) { - const int indexOfChild = indexOf(childItem); - if (indexOfChild >= 0 && indexOfChild < m_cachedItemSizeHints.count()) { - m_cachedItemSizeHints[indexOfChild].min() = QSizeF(); - m_cachedItemSizeHints[indexOfChild].pref() = QSizeF(); - m_cachedItemSizeHints[indexOfChild].max() = QSizeF(); + ensureLayoutItemsUpdated(); + if (childItem) { + SizeHints &hints = m_cachedItemSizeHints[childItem]; + hints.min() = QSizeF(); + hints.pref() = QSizeF(); + hints.max() = QSizeF(); } for (int i = 0; i < Qt::NSizeHints; ++i) @@ -308,7 +313,6 @@ void QQuickStackLayout::invalidate(QQuickItem *childItem) void QQuickStackLayout::updateLayoutItems() { Q_D(QQuickStackLayout); - d->m_ignoredItems.clear(); const int count = itemCount(); int oldIndex = d->currentIndex; if (!d->explicitCurrentIndex) @@ -335,6 +339,17 @@ void QQuickStackLayout::updateLayoutItems() } } +QQuickStackLayout::SizeHints &QQuickStackLayout::cachedItemSizeHints(int index) const +{ + QQuickItem *item = itemAt(index); + Q_ASSERT(item); + SizeHints &hints = m_cachedItemSizeHints[item]; // will create an entry if it doesn't exist + if (!hints.min().isValid()) + QQuickStackLayout::collectItemSizeHints(item, hints.array); + return hints; +} + + void QQuickStackLayout::rearrange(const QSizeF &newSize) { Q_D(QQuickStackLayout); @@ -346,7 +361,7 @@ void QQuickStackLayout::rearrange(const QSizeF &newSize) if (d->currentIndex == -1 || d->currentIndex >= m_cachedItemSizeHints.count()) return; - QQuickStackLayout::SizeHints &hints = m_cachedItemSizeHints[d->currentIndex]; + QQuickStackLayout::SizeHints &hints = cachedItemSizeHints(d->currentIndex); QQuickItem *item = itemAt(d->currentIndex); Q_ASSERT(item); item->setPosition(QPointF(0,0)); // ### respect alignment? @@ -379,10 +394,7 @@ void QQuickStackLayout::collectItemSizeHints(QQuickItem *item, QSizeF *sizeHints bool QQuickStackLayout::shouldIgnoreItem(QQuickItem *item) const { - const bool ignored = QQuickItemPrivate::get(item)->isTransparentForPositioner(); - if (ignored) - d_func()->m_ignoredItems << item; - return ignored; + return QQuickItemPrivate::get(item)->isTransparentForPositioner(); } QQuickStackLayoutAttached::QQuickStackLayoutAttached(QObject *object) diff --git a/src/quicklayouts/qquickstacklayout_p.h b/src/quicklayouts/qquickstacklayout_p.h index 07c2fc3727d..a6ba38c20da 100644 --- a/src/quicklayouts/qquickstacklayout_p.h +++ b/src/quicklayouts/qquickstacklayout_p.h @@ -111,8 +111,9 @@ public slots: QSizeF array[Qt::NSizeHints]; }; - mutable QVector<SizeHints> m_cachedItemSizeHints; + mutable QHash<QQuickItem*, SizeHints> m_cachedItemSizeHints; mutable QSizeF m_cachedSizeHints[Qt::NSizeHints]; + SizeHints &cachedItemSizeHints(int index) const; }; class QQuickStackLayoutPrivate : public QQuickLayoutPrivate diff --git a/src/quicknativestyle/CMakeLists.txt b/src/quicknativestyle/CMakeLists.txt new file mode 100644 index 00000000000..befd7fed0b6 --- /dev/null +++ b/src/quicknativestyle/CMakeLists.txt @@ -0,0 +1,100 @@ +##################################################################### +## qtquickcontrols2nativestyleplugin Plugin: +##################################################################### + +set(qml_files + "controls/DefaultButton.qml" + "controls/DefaultSlider.qml" + "controls/DefaultGroupBox.qml" + "controls/DefaultCheckBox.qml" + "controls/DefaultRadioButton.qml" + "controls/DefaultSpinBox.qml" + "controls/DefaultTextField.qml" + "controls/DefaultFrame.qml" + "controls/DefaultTextArea.qml" + "controls/DefaultComboBox.qml" + "controls/DefaultScrollBar.qml" + "controls/DefaultProgressBar.qml" + "controls/DefaultDial.qml" +) + +if(MACOS) + list(APPEND qml_files "util/FocusFrame.qml") +endif() + +qt_internal_add_qml_module(qtquickcontrols2nativestyleplugin + URI "QtQuick.NativeStyle" + VERSION "${PROJECT_VERSION}" + CLASSNAME QtQuickControls2NativeStylePlugin + DEPENDENCIES + QtQuick.Controls/auto + QtQuick.Layouts/auto + QtQuick/auto + PAST_MAJOR_VERSIONS 2 + PLUGIN_TARGET qtquickcontrols2nativestyleplugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + SOURCES + items/qquickstyleitem.cpp items/qquickstyleitem.h + items/qquickstyleitembutton.cpp items/qquickstyleitembutton.h + items/qquickstyleitemcheckbox.cpp items/qquickstyleitemcheckbox.h + items/qquickstyleitemcombobox.cpp items/qquickstyleitemcombobox.h + items/qquickstyleitemdial.cpp items/qquickstyleitemdial.h + items/qquickstyleitemframe.cpp items/qquickstyleitemframe.h + items/qquickstyleitemgroupbox.cpp items/qquickstyleitemgroupbox.h + items/qquickstyleitemprogressbar.cpp items/qquickstyleitemprogressbar.h + items/qquickstyleitemradiobutton.cpp items/qquickstyleitemradiobutton.h + items/qquickstyleitemscrollbar.cpp items/qquickstyleitemscrollbar.h + items/qquickstyleitemslider.cpp items/qquickstyleitemslider.h + items/qquickstyleitemspinbox.cpp items/qquickstyleitemspinbox.h + items/qquickstyleitemtextfield.cpp items/qquickstyleitemtextfield.h + qstyle/qquickcommonstyle.cpp qstyle/qquickcommonstyle.h qstyle/qquickcommonstyle_p.h + qstyle/qquickcommonstylepixmaps_p.h + qstyle/qquickdrawutil.cpp qstyle/qquickdrawutil.h + qstyle/qquicknativestyle.cpp qstyle/qquicknativestyle.h + qstyle/qquickstyle.cpp qstyle/qquickstyle.h qstyle/qquickstyle_p.h + qstyle/qquickstylehelper.cpp qstyle/qquickstylehelper_p.h + qstyle/qquickstyleoption.cpp qstyle/qquickstyleoption.h + qtquickcontrols2nativestyleplugin.cpp + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + INCLUDE_DIRECTORIES + items + qstyle + util + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2Private + Qt::QuickPrivate + Qt::QuickTemplates2Private +) + +qt_internal_extend_target(qtquickcontrols2nativestyleplugin CONDITION MACOS + SOURCES + items/qquickstyleitemscrollviewcorner.cpp items/qquickstyleitemscrollviewcorner.h + qstyle/mac/qquickmacstyle_mac.mm qstyle/mac/qquickmacstyle_mac_p.h + qstyle/mac/qquickmacstyle_mac_p_p.h + util/qquickmacfocusframe.h util/qquickmacfocusframe.mm + INCLUDE_DIRECTORIES + qstyle/mac + LIBRARIES + ${FWAppKit} +) + +qt_internal_extend_target(qtquickcontrols2nativestyleplugin CONDITION WIN32 + SOURCES + qstyle/windows/qquickwindowsstyle.cpp qstyle/windows/qquickwindowsstyle_p.h + qstyle/windows/qquickwindowsstyle_p_p.h + qstyle/windows/qquickwindowsxpstyle.cpp + INCLUDE_DIRECTORIES + qstyle/windows + LIBRARIES + gdi32 + user32 + uxtheme +) diff --git a/src/quicknativestyle/controls/DefaultButton.qml b/src/quicknativestyle/controls/DefaultButton.qml new file mode 100644 index 00000000000..b6d8e427894 --- /dev/null +++ b/src/quicknativestyle/controls/DefaultButton.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.Button { + id: control + + readonly property bool __nativeBackground: background instanceof NativeStyle.StyleItem + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + leftPadding: __nativeBackground ? background.contentPadding.left : 5 + rightPadding: __nativeBackground ? background.contentPadding.right : 5 + topPadding: __nativeBackground ? background.contentPadding.top : 5 + bottomPadding: __nativeBackground ? background.contentPadding.bottom : 5 + + background: NativeStyle.Button { + control: control + contentWidth: contentItem.implicitWidth + contentHeight: contentItem.implicitHeight + } + + icon.width: 24 + icon.height: 24 + icon.color: control.palette.buttonText + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.palette.buttonText + } +} diff --git a/src/quicknativestyle/controls/DefaultCheckBox.qml b/src/quicknativestyle/controls/DefaultCheckBox.qml new file mode 100644 index 00000000000..45e49889585 --- /dev/null +++ b/src/quicknativestyle/controls/DefaultCheckBox.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.NativeStyle as NativeStyle + +T.CheckBox { + id: control + + readonly property bool nativeIndicator: indicator instanceof NativeStyle.StyleItem + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: nativeIndicator ? 0 : 6 + padding: nativeIndicator ? 0 : 6 + + indicator: NativeStyle.CheckBox { + control: control + y: control.topPadding + (control.availableHeight - height) >> 1 + contentWidth: contentItem.implicitWidth + contentHeight: contentItem.implicitHeight + useNinePatchImage: false + } + + contentItem: CheckLabel { + text: control.text + font: control.font + color: control.palette.windowText + + // For some reason, the other styles set padding here (in the delegate), instead of in + // the control above. And they also adjust the indicator position by setting x and y + // explicitly (instead of using insets). So we follow the same pattern to ensure that + // setting a custom contentItem delegate from the app will end up looking the same for + // all styles. But this should probably be fixed for all styles (to make them work the + // same way as e.g Buttons). + leftPadding: { + if (nativeIndicator) + indicator.contentPadding.left + else + indicator && !mirrored ? indicator.width + spacing : 0 + } + + topPadding: nativeIndicator ? indicator.contentPadding.top : 0 + rightPadding: { + if (nativeIndicator) + indicator.contentPadding.right + else + indicator && mirrored ? indicator.width + spacing : 0 + } + } +} diff --git a/src/quicknativestyle/controls/DefaultComboBox.qml b/src/quicknativestyle/controls/DefaultComboBox.qml new file mode 100644 index 00000000000..d3f168d567c --- /dev/null +++ b/src/quicknativestyle/controls/DefaultComboBox.qml @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.ComboBox { + id: control + + readonly property bool __nativeBackground: background instanceof NativeStyle.StyleItem + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding, + 90 /* minimum */ ) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + leftPadding: __nativeBackground ? background.contentPadding.left : 5 + rightPadding: __nativeBackground ? background.contentPadding.right : 5 + topPadding: __nativeBackground ? background.contentPadding.top : 5 + bottomPadding: __nativeBackground ? background.contentPadding.bottom : 5 + + contentItem: T.TextField { + implicitWidth: contentWidth + implicitHeight: contentHeight + text: control.editable ? control.editText : control.displayText + + enabled: control.editable + autoScroll: control.editable + readOnly: control.down + inputMethodHints: control.inputMethodHints + validator: control.validator + selectByMouse: control.selectTextByMouse + + font: control.font + color: control.editable ? control.palette.text : control.palette.buttonText + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + verticalAlignment: Text.AlignVCenter + } + + background: NativeStyle.ComboBox { + control: control + contentWidth: contentItem.implicitWidth + contentHeight: contentItem.implicitHeight + } + + delegate: ItemDelegate { + width: ListView.view.width + text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData + palette.text: control.palette.text + palette.highlightedText: control.palette.highlightedText + font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal + highlighted: control.highlightedIndex === index + hoverEnabled: control.hoverEnabled + } + + popup: T.Popup { + readonly property var layoutMargins: control.__nativeBackground ? control.background.layoutMargins : null + x: layoutMargins ? layoutMargins.left : 0 + y: control.height - (layoutMargins ? layoutMargins.bottom : 0) + width: control.width - (layoutMargins ? layoutMargins.left + layoutMargins.right : 0) + height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin) + topMargin: 6 + bottomMargin: 6 + + contentItem: ListView { + clip: true + implicitHeight: contentHeight + model: control.delegateModel + currentIndex: control.highlightedIndex + highlightMoveDuration: 0 + + Rectangle { + z: 10 + width: parent.width + height: parent.height + color: "transparent" + border.color: control.palette.mid + } + + T.ScrollIndicator.vertical: ScrollIndicator { } + } + + background: Rectangle { + color: control.palette.window + } + } +} diff --git a/src/quicknativestyle/controls/DefaultDial.qml b/src/quicknativestyle/controls/DefaultDial.qml new file mode 100644 index 00000000000..9ede7076629 --- /dev/null +++ b/src/quicknativestyle/controls/DefaultDial.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.Dial { + id: control + + readonly property bool __nativeBackground: background instanceof NativeStyle.StyleItem + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding, + 80 /* minimum */ ) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + 80 /* minimum */ ) + + background: NativeStyle.Dial { + control: control + useNinePatchImage: false + } +} diff --git a/src/quicknativestyle/controls/DefaultFrame.qml b/src/quicknativestyle/controls/DefaultFrame.qml new file mode 100644 index 00000000000..77ca6125010 --- /dev/null +++ b/src/quicknativestyle/controls/DefaultFrame.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.Frame { + id: control + + readonly property bool __nativeBackground: background instanceof NativeStyle.StyleItem + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + leftPadding: __nativeBackground ? background.contentPadding.left : 12 + rightPadding: __nativeBackground ? background.contentPadding.right : 12 + topPadding: __nativeBackground ? background.contentPadding.top : 12 + bottomPadding: __nativeBackground ? background.contentPadding.bottom : 12 + + background: NativeStyle.Frame { + control: control + contentWidth: control.contentWidth + contentHeight: control.contentHeight + } +} diff --git a/src/quicknativestyle/controls/DefaultGroupBox.qml b/src/quicknativestyle/controls/DefaultGroupBox.qml new file mode 100644 index 00000000000..dcaeaaf8a9b --- /dev/null +++ b/src/quicknativestyle/controls/DefaultGroupBox.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.GroupBox { + id: control + + readonly property bool __nativeBackground: background instanceof NativeStyle.StyleItem + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitLabelWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + label: Rectangle { + color: control.palette.window + property point labelPos : control.__nativeBackground + ? background.labelPos + : Qt.point(0,0) + x: labelPos.x + background.x + y: labelPos.y + background.y - (__nativeBackground ? background.groupBoxPadding.top : 0) + width: children[0].implicitWidth + height: children[0].implicitHeight + Text { + width: parent.width + height: parent.height + text: control.title + font: control.font + color: control.palette.windowText + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + } + + leftPadding: __nativeBackground ? background.contentPadding.left : 0 + rightPadding: __nativeBackground ? background.contentPadding.right : 0 + topPadding: __nativeBackground ? background.contentPadding.top : 0 + bottomPadding: __nativeBackground ? background.contentPadding.bottom : 0 + + leftInset: __nativeBackground ? background.groupBoxPadding.left : 0 + topInset: __nativeBackground ? background.groupBoxPadding.top : 0 + + background: NativeStyle.GroupBox { + control: control + contentWidth: contentItem.implicitWidth + contentHeight: contentItem.implicitHeight + } +} diff --git a/src/quicknativestyle/controls/DefaultProgressBar.qml b/src/quicknativestyle/controls/DefaultProgressBar.qml new file mode 100644 index 00000000000..77934b31c46 --- /dev/null +++ b/src/quicknativestyle/controls/DefaultProgressBar.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls +import QtQuick.NativeStyle as NativeStyle + +T.ProgressBar { + id: control + + readonly property bool __nativeBackground: background instanceof NativeStyle.StyleItem + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding, + control.horizontal ? 90 : 0 /* minimum */ ) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + control.vertical ? 90 : 0 /* minimum */ ) + + background: NativeStyle.ProgressBar { + control: control + useNinePatchImage: false + } +} diff --git a/src/quicknativestyle/controls/DefaultRadioButton.qml b/src/quicknativestyle/controls/DefaultRadioButton.qml new file mode 100644 index 00000000000..91f340b716c --- /dev/null +++ b/src/quicknativestyle/controls/DefaultRadioButton.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.NativeStyle as NativeStyle + +T.RadioButton { + id: control + + readonly property bool nativeIndicator: indicator instanceof NativeStyle.StyleItem + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: nativeIndicator ? 0 : 6 + padding: nativeIndicator ? 0 : 6 + + indicator: NativeStyle.RadioButton { + control: control + contentWidth: contentItem.implicitWidth + contentHeight: contentItem.implicitHeight + useNinePatchImage: false +// Component.onCompleted: { +// var f = indicator.font(control) +// control.font.pixelSize = f.pixelSize +// print(f) +// } + } + + contentItem: CheckLabel { + text: control.text + font: control.font + color: control.palette.windowText + + // For some reason, the other styles set padding here (in the delegate), instead of in + // the control above. And they also adjust the indicator position by setting x and y + // explicitly (instead of using insets). So we follow the same pattern to ensure that + // setting a custom contentItem delegate from the app will end up looking the same for + // all styles. But this should probably be fixed for all styles (to make them work the + // same way as e.g Buttons). + leftPadding: { + if (nativeIndicator) + indicator.contentPadding.left + else + indicator && !mirrored ? indicator.width + spacing : 0 + } + + rightPadding: { + if (nativeIndicator) + indicator.contentPadding.right + else + indicator && mirrored ? indicator.width + spacing : 0 + } + } +} diff --git a/src/quicknativestyle/controls/DefaultScrollBar.qml b/src/quicknativestyle/controls/DefaultScrollBar.qml new file mode 100644 index 00000000000..ef20f7016c5 --- /dev/null +++ b/src/quicknativestyle/controls/DefaultScrollBar.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.ScrollBar { + id: control + + readonly property bool __nativeContentItem: contentItem instanceof NativeStyle.StyleItem + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + visible: policy === T.ScrollBar.AlwaysOn || (policy === T.ScrollBar.AsNeeded && size < 1.0) + minimumSize: !__nativeContentItem ? 10 : orientation === Qt.Vertical ? + contentItem.minimumSize.height / height : contentItem.minimumSize.width / width + + background: NativeStyle.ScrollBar { + control: control + subControl: NativeStyle.ScrollBar.Groove + } + + contentItem: NativeStyle.ScrollBar { + control: control + subControl: NativeStyle.ScrollBar.Handle + } +} diff --git a/src/quicknativestyle/controls/DefaultSlider.qml b/src/quicknativestyle/controls/DefaultSlider.qml new file mode 100644 index 00000000000..6d4521720c3 --- /dev/null +++ b/src/quicknativestyle/controls/DefaultSlider.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.Slider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitHandleWidth + leftPadding + rightPadding, + control.horizontal ? 90 : 0 /* minimum */ ) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitHandleHeight + topPadding + bottomPadding, + control.vertical ? 90 : 0 /* minimum */ ) + + background: NativeStyle.Slider { + control: control + subControl: NativeStyle.Slider.Groove + // We normally cannot use a nine patch image for the + // groove if we draw tickmarks (since then the scaling + // would scale the tickmarks too). The groove might + // also use a different background color before, and + // after, the handle. + useNinePatchImage: false + } + + handle: NativeStyle.Slider { + control: control + subControl: NativeStyle.Slider.Handle + x: control.leftPadding + (control.horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) + useNinePatchImage: false + } +} diff --git a/src/quicknativestyle/controls/DefaultSpinBox.qml b/src/quicknativestyle/controls/DefaultSpinBox.qml new file mode 100644 index 00000000000..640aab00200 --- /dev/null +++ b/src/quicknativestyle/controls/DefaultSpinBox.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.SpinBox { + id: control + + readonly property bool __nativeBackground: background instanceof NativeStyle.StyleItem + + implicitWidth: Math.max(implicitBackgroundWidth + spacing + up.implicitIndicatorWidth + + leftInset + rightInset, + 90 /* minimum */ ) + implicitHeight: Math.max(implicitBackgroundHeight, up.implicitIndicatorHeight + down.implicitIndicatorHeight + + (spacing * 3)) + topInset + bottomInset + + spacing: 2 + + leftPadding: (__nativeBackground ? background.contentPadding.left: 0) + topPadding: (__nativeBackground ? background.contentPadding.top: 0) + rightPadding: (__nativeBackground ? background.contentPadding.right : 0) + up.implicitIndicatorWidth + spacing + bottomPadding: (__nativeBackground ? background.contentPadding.bottom: 0) + spacing + + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + + contentItem: TextInput { + text: control.displayText + font: font.font + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + horizontalAlignment: Qt.AlignLeft + verticalAlignment: Qt.AlignVCenter + + topPadding: 2 + bottomPadding: 2 + leftPadding: 10 + rightPadding: 10 + + readOnly: !control.editable + validator: control.validator + inputMethodHints: control.inputMethodHints + } + + up.indicator: NativeStyle.SpinBox { + control: control + subControl: NativeStyle.SpinBox.Up + x: parent.width - width - spacing + y: (parent.height / 2) - height + useNinePatchImage: false + } + + down.indicator: NativeStyle.SpinBox { + control: control + subControl: NativeStyle.SpinBox.Down + x: up.indicator.x + y: up.indicator.y + up.indicator.height + useNinePatchImage: false + } + + background: NativeStyle.SpinBox { + control: control + subControl: NativeStyle.SpinBox.Frame + contentWidth: contentItem.implicitWidth + contentHeight: contentItem.implicitHeight + } +} diff --git a/src/quicknativestyle/controls/DefaultTextArea.qml b/src/quicknativestyle/controls/DefaultTextArea.qml new file mode 100644 index 00000000000..c598baf1c5a --- /dev/null +++ b/src/quicknativestyle/controls/DefaultTextArea.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.TextArea { + id: control + + implicitWidth: Math.max(contentWidth + leftPadding + rightPadding, + implicitBackgroundWidth + leftInset + rightInset, + placeholder.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(contentHeight + topPadding + bottomPadding, + implicitBackgroundHeight + topInset + bottomInset, + placeholder.implicitHeight + topPadding + bottomPadding) + + leftPadding: 7 + rightPadding: 7 + topPadding: 3 + bottomPadding: 3 + + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + placeholderTextColor: control.palette.placeholderText + verticalAlignment: TextInput.AlignTop + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.availableWidth + height: control.availableHeight + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + verticalAlignment: control.verticalAlignment + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + elide: Text.ElideRight + renderType: control.renderType + } + + background: Rectangle { + color: control.palette.light + } +} diff --git a/src/quicknativestyle/controls/DefaultTextField.qml b/src/quicknativestyle/controls/DefaultTextField.qml new file mode 100644 index 00000000000..6b366fedeb9 --- /dev/null +++ b/src/quicknativestyle/controls/DefaultTextField.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Templates as T +import QtQuick.NativeStyle as NativeStyle + +T.TextField { + id: control + + readonly property bool __nativeBackground: background instanceof NativeStyle.StyleItem + + implicitWidth: implicitBackgroundWidth + leftInset + rightInset + || Math.max(contentWidth, placeholder.implicitWidth) + leftPadding + rightPadding + + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding, + placeholder.implicitHeight + topPadding + bottomPadding) + + leftPadding: __nativeBackground ? background.contentPadding.left: 7 + rightPadding: __nativeBackground ? background.contentPadding.right: 7 + topPadding: __nativeBackground ? background.contentPadding.top: 3 + bottomPadding: __nativeBackground ? background.contentPadding.bottom: 3 + + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + placeholderTextColor: control.palette.placeholderText + verticalAlignment: TextInput.AlignTop + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + verticalAlignment: control.verticalAlignment + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + elide: Text.ElideRight + renderType: control.renderType + } + + background: NativeStyle.TextField { + control: control + contentWidth: Math.max(control.contentWidth, placeholder.implicitWidth) + contentHeight: control.contentHeight + } +} diff --git a/src/quicknativestyle/controls/controls.pri b/src/quicknativestyle/controls/controls.pri new file mode 100644 index 00000000000..8675989e29f --- /dev/null +++ b/src/quicknativestyle/controls/controls.pri @@ -0,0 +1,14 @@ +QML_FILES += \ + $$PWD/DefaultButton.qml \ + $$PWD/DefaultSlider.qml \ + $$PWD/DefaultGroupBox.qml \ + $$PWD/DefaultCheckBox.qml \ + $$PWD/DefaultRadioButton.qml \ + $$PWD/DefaultSpinBox.qml \ + $$PWD/DefaultTextField.qml \ + $$PWD/DefaultFrame.qml \ + $$PWD/DefaultTextArea.qml \ + $$PWD/DefaultComboBox.qml \ + $$PWD/DefaultScrollBar.qml \ + $$PWD/DefaultProgressBar.qml \ + $$PWD/DefaultDial.qml \ diff --git a/src/quicknativestyle/items/items.pri b/src/quicknativestyle/items/items.pri new file mode 100644 index 00000000000..5b6d9251a28 --- /dev/null +++ b/src/quicknativestyle/items/items.pri @@ -0,0 +1,36 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qquickstyleitem.h \ + $$PWD/qquickstyleitembutton.h \ + $$PWD/qquickstyleitemgroupbox.h \ + $$PWD/qquickstyleitemcheckbox.h \ + $$PWD/qquickstyleitemradiobutton.h \ + $$PWD/qquickstyleitemslider.h \ + $$PWD/qquickstyleitemspinbox.h \ + $$PWD/qquickstyleitemtextfield.h \ + $$PWD/qquickstyleitemframe.h \ + $$PWD/qquickstyleitemcombobox.h \ + $$PWD/qquickstyleitemscrollbar.h \ + $$PWD/qquickstyleitemprogressbar.h \ + $$PWD/qquickstyleitemdial.h \ + +SOURCES += \ + $$PWD/qquickstyleitem.cpp \ + $$PWD/qquickstyleitembutton.cpp \ + $$PWD/qquickstyleitemgroupbox.cpp \ + $$PWD/qquickstyleitemcheckbox.cpp \ + $$PWD/qquickstyleitemradiobutton.cpp \ + $$PWD/qquickstyleitemslider.cpp \ + $$PWD/qquickstyleitemspinbox.cpp \ + $$PWD/qquickstyleitemtextfield.cpp \ + $$PWD/qquickstyleitemframe.cpp \ + $$PWD/qquickstyleitemcombobox.cpp \ + $$PWD/qquickstyleitemscrollbar.cpp \ + $$PWD/qquickstyleitemprogressbar.cpp \ + $$PWD/qquickstyleitemdial.cpp \ + +macos { + HEADERS += $$PWD/qquickstyleitemscrollviewcorner.h + SOURCES += $$PWD/qquickstyleitemscrollviewcorner.cpp +} diff --git a/src/quicknativestyle/items/qquickstyleitem.cpp b/src/quicknativestyle/items/qquickstyleitem.cpp new file mode 100644 index 00000000000..7e8403ad305 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitem.cpp @@ -0,0 +1,578 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitem.h" + +#include <QtCore/qscopedvaluerollback.h> +#include <QtCore/qdir.h> + +#include <QtQuick/qsgninepatchnode.h> +#include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuick/qquickrendercontrol.h> + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickbutton_p.h> + +#include <QtQml/qqml.h> + +#include "qquickstyleitembutton.h" +#include "qquickstylehelper_p.h" + +QT_BEGIN_NAMESPACE + +QDebug operator<<(QDebug debug, const QQuickStyleMargins &padding) +{ + QDebugStateSaver saver(debug); + debug.nospace(); + debug << "StyleMargins("; + debug << padding.left() << ", "; + debug << padding.top() << ", "; + debug << padding.right() << ", "; + debug << padding.bottom(); + debug << ')'; + return debug; +} + +QDebug operator<<(QDebug debug, const StyleItemGeometry &cg) +{ + QDebugStateSaver saver(debug); + debug.nospace(); + debug << "StyleItemGeometry("; + debug << "implicitSize:" << cg.implicitSize << ", "; + debug << "contentRect:" << cg.contentRect << ", "; + debug << "layoutRect:" << cg.layoutRect << ", "; + debug << "minimumSize:" << cg.minimumSize << ", "; + debug << "9patchMargins:" << cg.ninePatchMargins; + debug << ')'; + return debug; +} + +int QQuickStyleItem::dprAlignedSize(const int size) const +{ + // Return the first value equal to or bigger than size + // that is a whole number when multiplied with the dpr. + static int multiplier = [&]() { + const qreal dpr = window()->effectiveDevicePixelRatio(); + for (int m = 1; m <= 10; ++m) { + const qreal v = m * dpr; + if (v == int(v)) + return m; + } + + qWarning() << "The current dpr (" << dpr << ") is not supported" + << "by the style and might result in drawing artifacts"; + return 1; + }(); + + return int(qCeil(qreal(size) / qreal(multiplier)) * multiplier); +} + +QQuickStyleItem::QQuickStyleItem(QQuickItem *parent) + : QQuickItem(parent) +{ + setFlag(QQuickItem::ItemHasContents); +} + +QQuickStyleItem::~QQuickStyleItem() +{ +} + +void QQuickStyleItem::connectToControl() const +{ + connect(m_control, &QQuickStyleItem::enabledChanged, this, &QQuickStyleItem::markImageDirty); + connect(m_control, &QQuickItem::activeFocusChanged, this, &QQuickStyleItem::markImageDirty); + + if (QQuickWindow *win = window()) { + connect(win, &QQuickWindow::activeChanged, this, &QQuickStyleItem::markImageDirty); + m_connectedWindow = win; + } +} + +void QQuickStyleItem::markImageDirty() +{ + m_dirty.setFlag(DirtyFlag::Image); + if (isComponentComplete()) + polish(); +} + +void QQuickStyleItem::markGeometryDirty() +{ + m_dirty.setFlag(DirtyFlag::Geometry); + if (isComponentComplete()) + polish(); +} + +QSGNode *QQuickStyleItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) +{ + QSGNinePatchNode *node = static_cast<QSGNinePatchNode *>(oldNode); + if (!node) + node = window()->createNinePatchNode(); + + if (m_paintedImage.isNull()) { + // If we cannot create a texture, the node should not exist either + // because its material requires a texture. + delete node; + return nullptr; + } + + const auto texture = window()->createTextureFromImage(m_paintedImage, QQuickWindow::TextureCanUseAtlas); + + QRectF bounds = boundingRect(); + const qreal dpr = window()->effectiveDevicePixelRatio(); + const QSizeF unscaledImageSize = QSizeF(m_paintedImage.size()) / dpr; + + // We can scale the image up with a nine patch node, but should + // avoid to scale it down. Otherwise the nine patch image will look + // wrapped (or look truncated, in case of no padding). So if the + // item is smaller that the image, don't scale. + if (bounds.width() < unscaledImageSize.width()) + bounds.setWidth(unscaledImageSize.width()); + if (bounds.height() < unscaledImageSize.height()) + bounds.setHeight(unscaledImageSize.height()); + +#ifdef QT_DEBUG + if (m_debugFlags.testFlag(Unscaled)) { + bounds.setSize(unscaledImageSize); + qqc2Info() << "Setting qsg node size to the unscaled size of m_paintedImage:" << bounds; + } +#endif + + if (m_useNinePatchImage) { + QMargins padding = m_styleItemGeometry.ninePatchMargins; + if (padding.right() == -1) { + // Special case: a padding of -1 means that + // the image shouldn't scale in the given direction. + padding.setLeft(0); + padding.setRight(0); + } + if (padding.bottom() == -1) { + padding.setTop(0); + padding.setBottom(0); + } + node->setPadding(padding.left(), padding.top(), padding.right(), padding.bottom()); + } + + node->setBounds(bounds); + node->setTexture(texture); + node->setDevicePixelRatio(dpr); + node->update(); + + return node; +} + +QStyle::State QQuickStyleItem::controlSize(QQuickItem *item) +{ + // TODO: add proper API for small and mini + if (item->metaObject()->indexOfProperty("qqc2_style_small") != -1) + return QStyle::State_Small; + if (item->metaObject()->indexOfProperty("qqc2_style_mini") != -1) + return QStyle::State_Mini; + return QStyle::State_None; +} + +static QWindow *effectiveWindow(QQuickWindow *window) +{ + QWindow *renderWindow = QQuickRenderControl::renderWindowFor(window); + return renderWindow ? renderWindow : window; +} + +void QQuickStyleItem::initStyleOptionBase(QStyleOption &styleOption) const +{ + Q_ASSERT(m_control); + + styleOption.control = const_cast<QQuickItem *>(control<QQuickItem>()); + styleOption.window = effectiveWindow(window()); + styleOption.palette = QQuickItemPrivate::get(m_control)->palette()->toQPalette(); + styleOption.rect = QRect(QPoint(0, 0), imageSize()); + + styleOption.state = QStyle::State_None; + styleOption.state |= controlSize(styleOption.control); + + // Note: not all controls inherit from QQuickControl (e.g QQuickTextField) + if (const auto quickControl = dynamic_cast<QQuickControl *>(m_control.data())) + styleOption.direction = quickControl->isMirrored() ? Qt::RightToLeft : Qt::LeftToRight; + + if (styleOption.window) { + if (styleOption.window->isActive()) + styleOption.state |= QStyle::State_Active; + if (m_control->isEnabled()) + styleOption.state |= QStyle::State_Enabled; + if (m_control->hasActiveFocus()) + styleOption.state |= QStyle::State_HasFocus; + if (m_control->isUnderMouse()) + styleOption.state |= QStyle::State_MouseOver; + // Should this depend on the focusReason (e.g. only TabFocus) ? + styleOption.state |= QStyle::State_KeyboardFocusChange; + } + + if (m_overrideState != None) { + // In Button.qml we fade between two versions of + // the handle, depending on if it's hovered or not + if (m_overrideState & AlwaysHovered) + styleOption.state |= QStyle::State_MouseOver; + else if (m_overrideState & NeverHovered) + styleOption.state &= ~QStyle::State_MouseOver; + } + + qqc2Info() << styleOption; +} + +void QQuickStyleItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + QQuickItem::geometryChange(newGeometry, oldGeometry); + + // Ensure that we only schedule a new geometry update + // and polish if this geometry change was caused by + // something else than us already updating geometry. + if (!m_polishing) + markGeometryDirty(); +} + +void QQuickStyleItem::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + + switch (change) { + case QQuickItem::ItemVisibleHasChanged: + if (data.boolValue) + markImageDirty(); + break; + case QQuickItem::ItemSceneChange: { + markImageDirty(); + QQuickWindow *win = data.window; + if (m_connectedWindow) + disconnect(m_connectedWindow, &QQuickWindow::activeChanged, this, &QQuickStyleItem::markImageDirty); + if (win) + connect(win, &QQuickWindow::activeChanged, this, &QQuickStyleItem::markImageDirty); + m_connectedWindow = win; + break;} + default: + break; + } +} + +void QQuickStyleItem::updateGeometry() +{ + qqc2InfoHeading("GEOMETRY"); + m_dirty.setFlag(DirtyFlag::Geometry, false); + + const QQuickStyleMargins oldContentPadding = contentPadding(); + const QQuickStyleMargins oldLayoutMargins = layoutMargins(); + const QSize oldMinimumSize = minimumSize(); + + m_styleItemGeometry = calculateGeometry(); + +#ifdef QT_DEBUG + if (m_styleItemGeometry.minimumSize.isEmpty()) + qmlWarning(this) << "minimumSize is empty!"; +#endif + + if (m_styleItemGeometry.implicitSize.isEmpty()) { + // If the item has no contents (or its size is + // empty), we just use the minimum size as implicit size. + m_styleItemGeometry.implicitSize = m_styleItemGeometry.minimumSize; + qqc2Info() << "implicitSize is empty, using minimumSize instead"; + } + + if (contentPadding() != oldContentPadding) + emit contentPaddingChanged(); + if (layoutMargins() != oldLayoutMargins) + emit layoutMarginsChanged(); + if (minimumSize() != oldMinimumSize) + emit minimumSizeChanged(); + + setImplicitSize(m_styleItemGeometry.implicitSize.width(), m_styleItemGeometry.implicitSize.height()); + + qqc2Info() << m_styleItemGeometry + << "bounding rect:" << boundingRect() + << "layout margins:" << layoutMargins() + << "content padding:" << contentPadding() + << "input content size:" << m_contentSize; +} + +void QQuickStyleItem::paintControlToImage() +{ + qqc2InfoHeading("PAINT"); + const QSize imgSize = imageSize(); + if (imgSize.isEmpty()) + return; + + m_dirty.setFlag(DirtyFlag::Image, false); + + // The size of m_paintedImage should normally be imgSize * dpr. The problem is + // that the dpr can be e.g 1.25, which means that the size can end up having a + // fraction. But an image cannot have a size with a fraction, so it would need + // to be rounded. But on the flip side, rounding the size means that the size + // of the scene graph node (which is, when the texture is not scaled, + // m_paintedImage.size() / dpr), will end up with a fraction instead. And this + // causes rendering artifacts in the scene graph when the texture is mapped + // to physical screen coordinates. So for that reason we calculate an image size + // that might be slightly larger than imgSize, so that imgSize * dpr lands on a + // whole number. The result is that neither the image size, nor the scene graph + // node, ends up with a size that has a fraction. + const qreal dpr = window()->effectiveDevicePixelRatio(); + const int alignedW = int(dprAlignedSize(imgSize.width()) * dpr); + const int alignedH = int(dprAlignedSize(imgSize.height()) * dpr); + const QSize alignedSize = QSize(alignedW, alignedH); + + if (m_paintedImage.size() != alignedSize) { + m_paintedImage = QImage(alignedSize, QImage::Format_ARGB32_Premultiplied); + m_paintedImage.setDevicePixelRatio(dpr); + qqc2Info() << "created image with dpr aligned size:" << alignedSize; + } + + m_paintedImage.fill(Qt::transparent); + + QPainter painter(&m_paintedImage); + paintEvent(&painter); + +#ifdef QT_DEBUG + if (m_debugFlags != NoDebug) { + painter.setPen(QColor(255, 0, 0, 255)); + if (m_debugFlags.testFlag(ImageRect)) + painter.drawRect(QRect(QPoint(0, 0), alignedSize / dpr)); + if (m_debugFlags.testFlag(LayoutRect)) { + const auto m = layoutMargins(); + QRect rect = QRect(QPoint(0, 0), imgSize); + rect.adjust(m.left(), m.top(), -m.right(), -m.bottom()); + painter.drawRect(rect); + } + if (m_debugFlags.testFlag(ContentRect)) { + const auto p = contentPadding(); + QRect rect = QRect(QPoint(0, 0), imgSize); + rect.adjust(p.left(), p.top(), -p.right(), -p.bottom()); + painter.drawRect(rect); + } + if (m_debugFlags.testFlag(InputContentSize)) { + const int offset = 2; + const QPoint p = m_styleItemGeometry.contentRect.topLeft(); + painter.drawLine(p.x() - offset, p.y() - offset, p.x() + m_contentSize.width(), p.y() - offset); + painter.drawLine(p.x() - offset, p.y() - offset, p.x() - offset, p.y() + m_contentSize.height()); + } + if (m_debugFlags.testFlag(NinePatchMargins)) { + const QMargins m = m_styleItemGeometry.ninePatchMargins; + if (m.right() != -1) { + painter.drawLine(m.left(), 0, m.left(), imgSize.height()); + painter.drawLine(imgSize.width() - m.right(), 0, imgSize.width() - m.right(), imgSize.height()); + } + if (m.bottom() != -1) { + painter.drawLine(0, m.top(), imgSize.width(), m.top()); + painter.drawLine(0, imgSize.height() - m.bottom(), imgSize.width(), imgSize.height() - m.bottom()); + } + } + if (m_debugFlags.testFlag(SaveImage)) { + static int nr = -1; + ++nr; + static QString filename = QStringLiteral("styleitem_saveimage_"); + const QString path = QDir::current().absoluteFilePath(filename); + const QString name = path + QString::number(nr) + QStringLiteral(".png"); + m_paintedImage.save(name); + qDebug() << "image saved to:" << name; + } + } +#endif + + update(); +} + +void QQuickStyleItem::updatePolish() +{ + QScopedValueRollback<bool> guard(m_polishing, true); + + const bool dirtyGeometry = m_dirty & DirtyFlag::Geometry; + const bool dirtyImage = isVisible() && ((m_dirty & DirtyFlag::Image) || (!m_useNinePatchImage && dirtyGeometry)); + + if (dirtyGeometry) + updateGeometry(); + if (dirtyImage) + paintControlToImage(); +} + +#ifdef QT_DEBUG +void QQuickStyleItem::addDebugInfo() +{ + // Example debug strings: + // "QQC2_NATIVESTYLE_DEBUG="myButton output contentRect" + // "QQC2_NATIVESTYLE_DEBUG="ComboBox ninepatchmargins" + // "QQC2_NATIVESTYLE_DEBUG="All layoutrect" + + static const auto debugString = qEnvironmentVariable("QQC2_NATIVESTYLE_DEBUG"); + static const auto matchAll = debugString.startsWith(QLatin1String("All ")); + static const auto prefix = QStringLiteral("QQuickStyleItem"); + if (debugString.isEmpty()) + return; + + const auto objectName = m_control->objectName(); + const auto typeName = QString::fromUtf8(metaObject()->className()).remove(prefix); + const bool matchName = !objectName.isEmpty() && debugString.startsWith(objectName); + const bool matchType = debugString.startsWith(typeName); + + if (!(matchAll || matchName || matchType)) + return; + +#define QQC2_DEBUG_FLAG(FLAG) \ + if (debugString.contains(QLatin1String(#FLAG), Qt::CaseInsensitive)) m_debugFlags |= FLAG + + QQC2_DEBUG_FLAG(Info); + QQC2_DEBUG_FLAG(ImageRect); + QQC2_DEBUG_FLAG(ContentRect); + QQC2_DEBUG_FLAG(LayoutRect); + QQC2_DEBUG_FLAG(InputContentSize); + QQC2_DEBUG_FLAG(DontUseNinePatchImage); + QQC2_DEBUG_FLAG(NinePatchMargins); + QQC2_DEBUG_FLAG(Unscaled); + QQC2_DEBUG_FLAG(Debug); + QQC2_DEBUG_FLAG(SaveImage); + + if (m_debugFlags & (DontUseNinePatchImage + | InputContentSize + | ContentRect + | LayoutRect + | NinePatchMargins)) { + // Some rects will not fit inside the drawn image unless + // we switch off (nine patch) image scaling. + m_debugFlags |= DontUseNinePatchImage; + m_useNinePatchImage = false; + } + + if (m_debugFlags != NoDebug) + qDebug() << "debug options set for" << typeName << "(" << objectName << "):" << m_debugFlags; + else + qDebug() << "available debug options:" << DebugFlags(0xFFFF); +} +#endif + +void QQuickStyleItem::componentComplete() +{ + Q_ASSERT_X(m_control, Q_FUNC_INFO, "You need to assign a value to property 'control'"); +#ifdef QT_DEBUG + addDebugInfo(); +#endif + QQuickItem::componentComplete(); + updateGeometry(); + connectToControl(); + polish(); +} + +qreal QQuickStyleItem::contentWidth() +{ + return m_contentSize.width(); +} + +void QQuickStyleItem::setContentWidth(qreal contentWidth) +{ + if (qFuzzyCompare(m_contentSize.width(), contentWidth)) + return; + + m_contentSize.setWidth(contentWidth); + markGeometryDirty(); +} + +qreal QQuickStyleItem::contentHeight() +{ + return m_contentSize.height(); +} + +void QQuickStyleItem::setContentHeight(qreal contentHeight) +{ + if (qFuzzyCompare(m_contentSize.height(), contentHeight)) + return; + + m_contentSize.setHeight(contentHeight); + markGeometryDirty(); +} + +QQuickStyleMargins QQuickStyleItem::contentPadding() const +{ + const QRect outerRect(QPoint(0, 0), m_styleItemGeometry.implicitSize); + return QQuickStyleMargins(outerRect, m_styleItemGeometry.contentRect); +} + +QQuickStyleMargins QQuickStyleItem::layoutMargins() const +{ + // ### TODO: layoutRect is currently not being used for anything. But + // eventually this information will be needed by layouts to align the controls + // correctly. This because the images drawn by QStyle are usually a bit bigger + // than the control(frame) itself, to e.g make room for shadow effects + // or focus rects/glow. And this will differ from control to control. The + // layoutRect will then inform where the frame of the control is. + QQuickStyleMargins margins; + if (m_styleItemGeometry.layoutRect.isValid()) { + const QRect outerRect(QPoint(0, 0), m_styleItemGeometry.implicitSize); + margins = QQuickStyleMargins(outerRect, m_styleItemGeometry.layoutRect); + } + return margins; +} + +QSize QQuickStyleItem::minimumSize() const +{ + // The style item should not be scaled below this size. + // Otherwise the image will be truncated. + return m_styleItemGeometry.minimumSize; +} + +QSize QQuickStyleItem::imageSize() const +{ + // Returns the size of the QImage (unscaled) that + // is used to draw the control from QStyle. + return m_useNinePatchImage ? m_styleItemGeometry.minimumSize : size().toSize(); +} + +qreal QQuickStyleItem::focusFrameRadius() const +{ + return m_styleItemGeometry.focusFrameRadius; +} + +QFont QQuickStyleItem::styleFont(QQuickItem *control) const +{ + Q_ASSERT(control); + // Note: This function should be treated as if it was static + // (meaning, don't assume anything in this object to be initialized). + // Resolving the font/font size should be done early on from QML, before we get + // around to calculate geometry and paint. Otherwise we typically need to do it + // all over again when/if the font changes. In practice this means that other + // items in QML that uses a style font, and at the same time, affects our input + // contentSize, cannot wait for this item to be fully constructed before it + // gets the font. So we need to resolve it here and now, even if this + // object might be in a half initialized state (hence also the control + // argument, instead of relying on m_control to be set). + return QGuiApplication::font(); +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitem.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitem.h b/src/quicknativestyle/items/qquickstyleitem.h new file mode 100644 index 00000000000..503260aaeee --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitem.h @@ -0,0 +1,311 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEM_H +#define QQUICKSTYLEITEM_H + +#include <QtCore/qdebug.h> +#include <QtQml/qqml.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +#include "qquicknativestyle.h" +#include "qquickstyle.h" +#include "qquickstyleoption.h" + +// Work-around for now, to avoid creator getting confused +// about missing macros. Should eventually be defined +// in qt declarative somewhere I assume. +#ifndef QML_NAMED_ELEMENT +#define QML_NAMED_ELEMENT(NAME) +#define QML_UNCREATABLE(NAME) +#endif + +#ifdef QT_DEBUG +#define qqc2Debug() if (m_debugFlags.testFlag(Debug)) qDebug() << __FUNCTION__ << ":" +#define qqc2Info() if (m_debugFlags.testFlag(Info)) qDebug() << __FUNCTION__ << ":" +#define qqc2InfoHeading(HEADING) if (m_debugFlags.testFlag(Info)) qDebug() << "--------" << HEADING << "--------" +#else +#define qqc2Debug() if (false) qDebug() +#define qqc2Info() if (false) qDebug() +#define qqc2InfoHeading(HEADING) if (false) qDebug() +#endif + +QT_BEGIN_NAMESPACE + +using namespace QQC2; + +class QQuickStyleMargins +{ + Q_GADGET + + Q_PROPERTY(int left READ left()) + Q_PROPERTY(int top READ top()) + Q_PROPERTY(int right READ right()) + Q_PROPERTY(int bottom READ bottom()) + + QML_NAMED_ELEMENT(stylemargins) + QML_UNCREATABLE("") + +public: + QQuickStyleMargins() {} + QQuickStyleMargins(const QQuickStyleMargins &other) : m_margins(other.m_margins) {} + QQuickStyleMargins(const QMargins &margins) : m_margins(margins) {} + QQuickStyleMargins(const QRect &outer, const QRect &inner) + { + const int left = inner.left() - outer.left(); + const int top = inner.top() - outer.top(); + const int right = outer.right() - inner.right(); + const int bottom = outer.bottom() - inner.bottom(); + m_margins = QMargins(left, top, right, bottom); + } + + inline void operator=(const QQuickStyleMargins &other) { m_margins = other.m_margins; } + inline bool operator==(const QQuickStyleMargins &other) const { return other.m_margins == m_margins; } + inline bool operator!=(const QQuickStyleMargins &other) const { return other.m_margins != m_margins; } + + inline int left() const { return m_margins.left(); } + inline int right() const { return m_margins.right(); } + inline int top() const { return m_margins.top(); } + inline int bottom() const { return m_margins.bottom(); } + + QMargins m_margins; +}; + +QDebug operator<<(QDebug debug, const QQuickStyleMargins &padding); + +struct StyleItemGeometry +{ + /* + A QQuickStyleItem is responsible for drawing a control, or a part of it. + + 'minimumSize' should be the minimum possible size that the item can + have _without_ taking content size into consideration (and still render + correctly). This will also be the size of the image that the item is drawn + to, unless QQuickStyleItem::useNinePatchImage is set to false. In that + case, the size of the image will be set to the size of the item instead + (which is set from QML, and will typically be the same as the size of the control). + The default way to calculate minimumSize is to call style()->sizeFromContents() + with an empty content size. This is not always well supported by the legacy QStyle + implementation, which means that you might e.g get an empty size in return. + For those cases, the correct solution is to go into the specific platform style + and change it so that it returns a valid size also for this special case. + + 'implicitSize' should reflect the preferred size of the item, taking the + given content size (as set from QML) into account. But not all controls + have contents (slider), and for many controls, the content/label is instead + placed outside the item/background image (radiobutton). In both cases, the + size of the item will not include the content size, and implicitSize can + usually be set equal to minimumSize instead. + + 'contentRect' should be the free space where the contents can be placed. Note that + this rect doesn't need to have the same size as the contentSize provided as input + to the style item. Instead, QStyle can typically calculate a rect that is bigger, to + e.g center the contents inside the control. + + 'layoutRect' can be set to shift the position of the whole control so + that aligns correctly with the other controls. This is important for + controls that draws e.g shadows or focus rings. Such adornments should + be painted, but not be included when aligning the controls. + */ + + QSize minimumSize; + QSize implicitSize; + QRect contentRect; + QRect layoutRect; // If invalid, there are no layout margins! + QMargins ninePatchMargins; + qreal focusFrameRadius; +}; + +QDebug operator<<(QDebug debug, const StyleItemGeometry &cg); + +class QQuickStyleItem : public QQuickItem +{ + Q_OBJECT + + // Input + Q_PROPERTY(QQuickItem *control MEMBER m_control NOTIFY controlChanged) + Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth) + Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight) + Q_PROPERTY(bool useNinePatchImage MEMBER m_useNinePatchImage) + Q_PROPERTY(OverrideState overrideState MEMBER m_overrideState) + + // Output + Q_PROPERTY(QQuickStyleMargins contentPadding READ contentPadding() NOTIFY contentPaddingChanged) + Q_PROPERTY(QQuickStyleMargins layoutMargins READ layoutMargins() NOTIFY layoutMarginsChanged) + Q_PROPERTY(QSize minimumSize READ minimumSize() NOTIFY minimumSizeChanged) + Q_PROPERTY(int transitionDuration MEMBER m_transitionDuration CONSTANT) + + QML_NAMED_ELEMENT(StyleItem) + QML_UNCREATABLE("StyleItem is an abstract base class.") + +public: + enum DirtyFlag { + Nothing = 0, + Geometry, + Image, + Everything = 255 + }; + Q_DECLARE_FLAGS(DirtyFlags, DirtyFlag) + + enum OverrideState { + None = 0, + AlwaysHovered, + NeverHovered, + AlwaysSunken + }; + Q_ENUM(OverrideState) + + +#ifdef QT_DEBUG + enum DebugFlag { + NoDebug = 0x000, + Debug = 0x001, + Info = 0x002, + ImageRect = 0x004, + ContentRect = 0x008, + LayoutRect = 0x010, + Unscaled = 0x020, + InputContentSize = 0x040, + DontUseNinePatchImage = 0x080, + NinePatchMargins = 0x100, + SaveImage = 0x200, + }; + Q_DECLARE_FLAGS(DebugFlags, DebugFlag) + Q_FLAG(DebugFlags) +#endif + + explicit QQuickStyleItem(QQuickItem *parent = nullptr); + ~QQuickStyleItem() override; + + qreal contentWidth(); + void setContentWidth(qreal contentWidth); + qreal contentHeight(); + void setContentHeight(qreal contentHeight); + + QQuickStyleMargins contentPadding() const; + QQuickStyleMargins layoutMargins() const; + QSize minimumSize() const; + QSize imageSize() const; + qreal focusFrameRadius() const; + + Q_INVOKABLE virtual QFont styleFont(QQuickItem *control) const; + + void markGeometryDirty(); + void markImageDirty(); + +signals: + void controlChanged(); + void contentPaddingChanged(); + void layoutMarginsChanged(); + void fontChanged(); + void minimumSizeChanged(); + +protected: + void componentComplete() override; + QSGNode *updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + void itemChange(ItemChange change, const ItemChangeData &data) override; + void updatePolish() override; + + virtual void connectToControl() const; + virtual void paintEvent(QPainter *painter) const = 0; + virtual StyleItemGeometry calculateGeometry() = 0; + + static QStyle::State controlSize(QQuickItem *item); + void initStyleOptionBase(QStyleOption &styleOption) const; + + inline QSize contentSize() const { return QSize(qCeil(m_contentSize.width()), qCeil(m_contentSize.height())); } + inline static QStyle *style() { return QQuickNativeStyle::style(); } + + template <class T> inline const T* control() const { +#ifdef QT_DEBUG + if (!dynamic_cast<T *>(m_control.data())) { + qmlWarning(this) << "control property is not of correct type"; + Q_UNREACHABLE(); + } +#endif + return static_cast<T *>(m_control.data()); + } + +#ifdef QT_DEBUG + DebugFlags m_debugFlags = NoDebug; +#endif + OverrideState m_overrideState = None; + +private: + inline void updateGeometry(); + inline void paintControlToImage(); + + int dprAlignedSize(const int size) const; + +#ifdef QT_DEBUG + void addDebugInfo(); +#endif + +private: + QPointer<QQuickItem> m_control; + QImage m_paintedImage; + StyleItemGeometry m_styleItemGeometry; + QSizeF m_contentSize; + + DirtyFlags m_dirty = Everything; + bool m_useNinePatchImage = true; + bool m_polishing = false; + mutable QQuickWindow *m_connectedWindow = nullptr; + +#ifdef Q_OS_MACOS + int m_transitionDuration = 150; +#else + int m_transitionDuration = 400; +#endif + +private: + friend class QtQuickControls2MacOSStylePlugin; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickStyleItem::DirtyFlags) + +#ifdef QT_DEBUG +Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickStyleItem::DebugFlags) +#endif + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickStyleItem) + +#endif // QQUICKSTYLEITEM_H diff --git a/src/quicknativestyle/items/qquickstyleitembutton.cpp b/src/quicknativestyle/items/qquickstyleitembutton.cpp new file mode 100644 index 00000000000..0c2c72b9208 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitembutton.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitembutton.h" + +QT_BEGIN_NAMESPACE + +QFont QQuickStyleItemButton::styleFont(QQuickItem *control) const +{ + return style()->font(QStyle::CE_PushButtonLabel, controlSize(control)); +} + +void QQuickStyleItemButton::connectToControl() const +{ + QQuickStyleItem::connectToControl(); + auto button = control<QQuickButton>(); + connect(button, &QQuickButton::downChanged, this, &QQuickStyleItem::markImageDirty); + connect(button, &QQuickButton::checkedChanged, this, &QQuickStyleItem::markImageDirty); +} + +StyleItemGeometry QQuickStyleItemButton::calculateGeometry() +{ + QStyleOptionButton styleOption; + initStyleOption(styleOption); + StyleItemGeometry geometry; + + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_PushButton, &styleOption, QSize(0, 0)); + geometry.implicitSize = style()->sizeFromContents(QStyle::CT_PushButton, &styleOption, contentSize()); + styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); + geometry.contentRect = style()->subElementRect(QStyle::SE_PushButtonContents, &styleOption); + geometry.layoutRect = style()->subElementRect(QStyle::SE_PushButtonLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_PushButtonBevel, &styleOption, geometry.minimumSize); + geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_PushButtonFocusFrameRadius, &styleOption); + + return geometry; +} + +void QQuickStyleItemButton::paintEvent(QPainter *painter) const +{ + QStyleOptionButton styleOption; + initStyleOption(styleOption); + style()->drawControl(QStyle::CE_PushButtonBevel, &styleOption, painter); +} + +void QQuickStyleItemButton::initStyleOption(QStyleOptionButton &styleOption) const +{ + initStyleOptionBase(styleOption); + auto button = control<QQuickButton>(); + + if (button->isDown()) + styleOption.state |= QStyle::State_Sunken; + if (!button->isFlat() && !button->isDown()) + styleOption.state |= QStyle::State_Raised; + if (button->isHighlighted() || button->isChecked()) + styleOption.state |= QStyle::State_On; + if (button->isFlat()) + styleOption.features |= QStyleOptionButton::Flat; +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitembutton.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitembutton.h b/src/quicknativestyle/items/qquickstyleitembutton.h new file mode 100644 index 00000000000..517716702ba --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitembutton.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMBUTTON_H +#define QQUICKSTYLEITEMBUTTON_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquickbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyleItemButton : public QQuickStyleItem +{ + Q_OBJECT + QML_NAMED_ELEMENT(Button) + +public: + QFont styleFont(QQuickItem *control) const override; + +protected: + void connectToControl() const override; + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + void initStyleOption(QStyleOptionButton &styleOption) const; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEITEMBUTTON_H diff --git a/src/quicknativestyle/items/qquickstyleitemcheckbox.cpp b/src/quicknativestyle/items/qquickstyleitemcheckbox.cpp new file mode 100644 index 00000000000..db07338cfe6 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemcheckbox.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitemcheckbox.h" + +QT_BEGIN_NAMESPACE + +QFont QQuickStyleItemCheckBox::styleFont(QQuickItem *control) const +{ + return style()->font(QStyle::CE_RadioButtonLabel, controlSize(control)); +} + +void QQuickStyleItemCheckBox::connectToControl() const +{ + QQuickStyleItem::connectToControl(); + auto checkbox = control<QQuickCheckBox>(); + connect(checkbox, &QQuickCheckBox::downChanged, this, &QQuickStyleItem::markImageDirty); + connect(checkbox, &QQuickCheckBox::checkStateChanged, this, &QQuickStyleItem::markImageDirty); +} + +StyleItemGeometry QQuickStyleItemCheckBox::calculateGeometry() +{ + QStyleOptionButton styleOption; + initStyleOption(styleOption); + StyleItemGeometry geometry; + + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_CheckBox, &styleOption, QSize(0, 0)); + geometry.implicitSize = geometry.minimumSize; + styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); + geometry.contentRect = style()->subElementRect(QStyle::SE_CheckBoxContents, &styleOption); + geometry.layoutRect = style()->subElementRect(QStyle::SE_CheckBoxLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_CheckBox, &styleOption, geometry.minimumSize); + geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_CheckBoxFocusFrameRadius, &styleOption); + + // Spacing seems to already be baked into SE_CheckBoxContents, so ignore until needed + //const int space = style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, &styleOption); + + return geometry; +} + +void QQuickStyleItemCheckBox::paintEvent(QPainter *painter) const +{ + QStyleOptionButton styleOption; + initStyleOption(styleOption); + style()->drawControl(QStyle::CE_CheckBox, &styleOption, painter); +} + +void QQuickStyleItemCheckBox::initStyleOption(QStyleOptionButton &styleOption) const +{ + initStyleOptionBase(styleOption); + auto checkbox = control<QQuickCheckBox>(); + + styleOption.state |= checkbox->isDown() ? QStyle::State_Sunken : QStyle::State_Raised; + if (checkbox->isTristate() && checkbox->checkState() == Qt::PartiallyChecked) + styleOption.state |= QStyle::State_NoChange; + else + styleOption.state |= checkbox->isChecked() ? QStyle::State_On : QStyle::State_Off; +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitemcheckbox.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitemcheckbox.h b/src/quicknativestyle/items/qquickstyleitemcheckbox.h new file mode 100644 index 00000000000..74b1a4bc50a --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemcheckbox.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMCHECKBOX_H +#define QQUICKSTYLEITEMCHECKBOX_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquickcheckbox_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyleItemCheckBox : public QQuickStyleItem +{ + Q_OBJECT + QML_NAMED_ELEMENT(CheckBox) + +public: + QFont styleFont(QQuickItem *control) const override; + +protected: + void connectToControl() const override; + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + void initStyleOption(QStyleOptionButton &styleOption) const; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEITEMCHECKBOX_H diff --git a/src/quicknativestyle/items/qquickstyleitemcombobox.cpp b/src/quicknativestyle/items/qquickstyleitemcombobox.cpp new file mode 100644 index 00000000000..747576b5139 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemcombobox.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitemcombobox.h" + +QT_BEGIN_NAMESPACE + +QFont QQuickStyleItemComboBox::styleFont(QQuickItem *control) const +{ + return style()->font(QStyle::CE_PushButtonLabel, controlSize(control)); +} + +void QQuickStyleItemComboBox::connectToControl() const +{ + QQuickStyleItem::connectToControl(); + auto comboBox = control<QQuickComboBox>(); + connect(comboBox, &QQuickComboBox::downChanged, this, &QQuickStyleItem::markImageDirty); +} + +StyleItemGeometry QQuickStyleItemComboBox::calculateGeometry() +{ + QStyleOptionComboBox styleOption; + initStyleOption(styleOption); + StyleItemGeometry geometry; + + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_ComboBox, &styleOption, QSize(0, 0)); + geometry.implicitSize = style()->sizeFromContents(QStyle::CT_ComboBox, &styleOption, contentSize()); + styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); + geometry.contentRect = style()->subControlRect(QStyle::CC_ComboBox, &styleOption, QStyle::SC_ComboBoxEditField); + geometry.layoutRect = style()->subElementRect(QStyle::SE_ComboBoxLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_ComboBox, &styleOption, geometry.minimumSize); + geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_ComboBoxFocusFrameRadius, &styleOption); + + return geometry; +} + +void QQuickStyleItemComboBox::paintEvent(QPainter *painter) const +{ + QStyleOptionComboBox styleOption; + initStyleOption(styleOption); + style()->drawComplexControl(QStyle::CC_ComboBox, &styleOption, painter); +} + +void QQuickStyleItemComboBox::initStyleOption(QStyleOptionComboBox &styleOption) const +{ + initStyleOptionBase(styleOption); + auto comboBox = control<QQuickComboBox>(); + + styleOption.subControls = QStyle::SC_ComboBoxArrow | QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField; + styleOption.frame = true; + styleOption.state |= QStyle::State_Selected; + styleOption.editable = comboBox->isEditable(); + + if (comboBox->isDown()) + styleOption.state |= QStyle::State_Sunken; + if (!comboBox->isFlat() && !comboBox->isDown()) + styleOption.state |= QStyle::State_Raised; +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitemcombobox.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitemcombobox.h b/src/quicknativestyle/items/qquickstyleitemcombobox.h new file mode 100644 index 00000000000..c417fae6e73 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemcombobox.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMCOMBOBOX_H +#define QQUICKSTYLEITEMCOMBOBOX_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquickcombobox_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyleItemComboBox : public QQuickStyleItem +{ + Q_OBJECT + QML_NAMED_ELEMENT(ComboBox) + +public: + QFont styleFont(QQuickItem *control) const override; + +protected: + void connectToControl() const override; + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + void initStyleOption(QStyleOptionComboBox &styleOption) const; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEITEMCOMBOBOX_H diff --git a/src/quicknativestyle/items/qquickstyleitemdial.cpp b/src/quicknativestyle/items/qquickstyleitemdial.cpp new file mode 100644 index 00000000000..a94ae68d765 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemdial.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitemdial.h" + +QT_BEGIN_NAMESPACE + +QFont QQuickStyleItemDial::styleFont(QQuickItem *control) const +{ + return style()->font(QStyle::CE_ProgressBarLabel, controlSize(control)); +} + +void QQuickStyleItemDial::connectToControl() const +{ + QQuickStyleItem::connectToControl(); + auto dial = control<QQuickDial>(); + connect(dial, &QQuickDial::fromChanged, this, &QQuickStyleItem::markImageDirty); + connect(dial, &QQuickDial::toChanged, this, &QQuickStyleItem::markImageDirty); + connect(dial, &QQuickDial::positionChanged, this, &QQuickStyleItem::markImageDirty); + connect(dial, &QQuickDial::valueChanged, this, &QQuickStyleItem::markImageDirty); + connect(dial, &QQuickDial::stepSizeChanged, this, &QQuickStyleItem::markImageDirty); + connect(dial, &QQuickDial::pressedChanged, this, &QQuickStyleItem::markImageDirty); +} + +StyleItemGeometry QQuickStyleItemDial::calculateGeometry() +{ + QStyleOptionSlider styleOption; + initStyleOption(styleOption); + + StyleItemGeometry geometry; + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_Dial, &styleOption, QSize(0, 0)); + geometry.implicitSize = geometry.minimumSize; + geometry.layoutRect = style()->subElementRect(QStyle::SE_SliderLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_Dial, &styleOption, geometry.minimumSize); + geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_DialFocusFrameRadius, &styleOption); + + return geometry; +} + +void QQuickStyleItemDial::paintEvent(QPainter *painter) const +{ + QStyleOptionSlider styleOption; + initStyleOption(styleOption); + style()->drawComplexControl(QStyle::CC_Dial, &styleOption, painter); +} + +void QQuickStyleItemDial::initStyleOption(QStyleOptionSlider &styleOption) const +{ + initStyleOptionBase(styleOption); + auto dial = control<QQuickDial>(); + + styleOption.subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderHandle; + styleOption.activeSubControls = QStyle::SC_None; + styleOption.tickInterval = dial->stepSize(); + styleOption.dialWrapping = dial->wrap(); + styleOption.upsideDown = true; + + if (dial->isPressed()) + styleOption.state |= QStyle::State_Sunken; + + if (dial->stepSize() == 0) { + styleOption.minimum = 0; + styleOption.maximum = 10000; + styleOption.sliderPosition = dial->position() * styleOption.maximum; + } else { + styleOption.minimum = dial->from(); + styleOption.maximum = dial->to(); + styleOption.sliderPosition = dial->value(); + } + + // TODO: add proper API for tickmarks + const int index = dial->metaObject()->indexOfProperty("qqc2_style_tickPosition"); + if (index != -1) { + const int tickPosition = dial->metaObject()->property(index).read(dial).toInt(); + styleOption.tickPosition = QStyleOptionSlider::TickPosition(tickPosition); + if (styleOption.tickPosition != QStyleOptionSlider::NoTicks) + styleOption.subControls |= QStyle::SC_DialTickmarks; + } + +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitemdial.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitemdial.h b/src/quicknativestyle/items/qquickstyleitemdial.h new file mode 100644 index 00000000000..5727919f27d --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemdial.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMDIAL_H +#define QQUICKSTYLEITEMDIAL_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquickdial_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyleItemDial : public QQuickStyleItem +{ + Q_OBJECT + QML_NAMED_ELEMENT(Dial) + +public: + QFont styleFont(QQuickItem *control) const override; + +protected: + void connectToControl() const override; + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + void initStyleOption(QStyleOptionSlider &styleOption) const; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEITEMDIAL_H diff --git a/src/quicknativestyle/items/qquickstyleitemframe.cpp b/src/quicknativestyle/items/qquickstyleitemframe.cpp new file mode 100644 index 00000000000..429b6a1dc0b --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemframe.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitemframe.h" + +QT_BEGIN_NAMESPACE + +StyleItemGeometry QQuickStyleItemFrame::calculateGeometry() +{ + QStyleOptionFrame styleOption; + initStyleOption(styleOption); + StyleItemGeometry geometry; + + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_Frame, &styleOption, QSize(0, 0)); + geometry.implicitSize = contentSize(); + styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); + geometry.contentRect = style()->subElementRect(QStyle::SE_FrameContents, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_ShapedFrame, &styleOption, geometry.minimumSize); + + return geometry; +} + +void QQuickStyleItemFrame::paintEvent(QPainter *painter) const +{ + QStyleOptionFrame styleOption; + initStyleOption(styleOption); + style()->drawControl(QStyle::CE_ShapedFrame, &styleOption, painter); +} + +void QQuickStyleItemFrame::initStyleOption(QStyleOptionFrame &styleOption) const +{ + initStyleOptionBase(styleOption); + styleOption.lineWidth = 1; + styleOption.frameShape = QStyleOptionFrame::StyledPanel; + styleOption.features = QStyleOptionFrame::Flat; +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitemframe.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitemframe.h b/src/quicknativestyle/items/qquickstyleitemframe.h new file mode 100644 index 00000000000..f44f070881a --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemframe.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMFRAME_H +#define QQUICKSTYLEITEMFRAME_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquickframe_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyleItemFrame : public QQuickStyleItem +{ + Q_OBJECT + QML_NAMED_ELEMENT(Frame) + +protected: + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + void initStyleOption(QStyleOptionFrame &styleOption) const; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEITEMFRAME_H diff --git a/src/quicknativestyle/items/qquickstyleitemgroupbox.cpp b/src/quicknativestyle/items/qquickstyleitemgroupbox.cpp new file mode 100644 index 00000000000..46cbfda4591 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemgroupbox.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitemgroupbox.h" + +QT_BEGIN_NAMESPACE + +QFont QQuickStyleItemGroupBox::styleFont(QQuickItem *control) const +{ + return style()->font(QStyle::CE_HeaderLabel, controlSize(control)); +} + +StyleItemGeometry QQuickStyleItemGroupBox::calculateGeometry() +{ + QStyleOptionGroupBox styleOption; + initStyleOption(styleOption); + + StyleItemGeometry geometry; + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_GroupBox, &styleOption, QSize(0, 0)); + + if (!control<QQuickGroupBox>()->title().isEmpty()) { + // We don't draw the title, but we need to take + // it into calculation for the control size + styleOption.text = QStringLiteral(" "); + styleOption.subControls |= QStyle::SC_GroupBoxLabel; + } + + geometry.implicitSize = style()->sizeFromContents(QStyle::CT_GroupBox, &styleOption, contentSize()); + styleOption.rect.setSize(geometry.implicitSize); + geometry.contentRect = style()->subControlRect(QStyle::CC_GroupBox, &styleOption, QStyle::SC_GroupBoxContents); + geometry.layoutRect = style()->subElementRect(QStyle::SE_GroupBoxLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_GroupBox, &styleOption, geometry.minimumSize); + + const QQuickStyleMargins oldGroupBoxPadding = m_groupBoxPadding; + const QRect frame = style()->subControlRect(QStyle::CC_GroupBox, &styleOption, QStyle::SC_GroupBoxFrame); + m_groupBoxPadding = QQuickStyleMargins(QRect(QPoint(), geometry.implicitSize), frame); + if (m_groupBoxPadding != oldGroupBoxPadding) + emit groupBoxPaddingChanged(); + + const QPointF oldLabelPos = m_labelPos; + m_labelPos = style()->subControlRect(QStyle::CC_GroupBox, &styleOption, QStyle::SC_GroupBoxLabel).topLeft(); + if (m_labelPos != oldLabelPos) + emit labelPosChanged(); + return geometry; +} + +void QQuickStyleItemGroupBox::paintEvent(QPainter *painter) const +{ + QStyleOptionGroupBox styleOption; + initStyleOption(styleOption); + style()->drawComplexControl(QStyle::CC_GroupBox, &styleOption, painter); +} + +void QQuickStyleItemGroupBox::initStyleOption(QStyleOptionGroupBox &styleOption) const +{ + initStyleOptionBase(styleOption); + styleOption.subControls = QStyle::SC_GroupBoxFrame; + styleOption.lineWidth = 1; +} + +QQuickStyleMargins QQuickStyleItemGroupBox::groupBoxPadding() const +{ + return m_groupBoxPadding; +} + +QPointF QQuickStyleItemGroupBox::labelPos() const +{ + return m_labelPos; +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitemgroupbox.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitemgroupbox.h b/src/quicknativestyle/items/qquickstyleitemgroupbox.h new file mode 100644 index 00000000000..61ecf69d992 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemgroupbox.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMGROUPBOX_H +#define QQUICKSTYLEITEMGROUPBOX_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquickgroupbox_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyleItemGroupBox : public QQuickStyleItem +{ + Q_OBJECT + Q_PROPERTY(QQuickStyleMargins groupBoxPadding READ groupBoxPadding NOTIFY groupBoxPaddingChanged) + Q_PROPERTY(QPointF labelPos READ labelPos NOTIFY labelPosChanged) + QML_NAMED_ELEMENT(GroupBox) + +public: + QQuickStyleMargins groupBoxPadding() const; + QPointF labelPos() const; + QFont styleFont(QQuickItem *control) const override; + +signals: + void groupBoxPaddingChanged(); + void labelPosChanged(); + +protected: + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + QQuickStyleMargins m_groupBoxPadding; + QPointF m_labelPos; + + void initStyleOption(QStyleOptionGroupBox &styleOption) const; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEITEMGROUPBOX_H diff --git a/src/quicknativestyle/items/qquickstyleitemprogressbar.cpp b/src/quicknativestyle/items/qquickstyleitemprogressbar.cpp new file mode 100644 index 00000000000..144b5723d5f --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemprogressbar.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitemprogressbar.h" + +QT_BEGIN_NAMESPACE + +QFont QQuickStyleItemProgressBar::styleFont(QQuickItem *control) const +{ + return style()->font(QStyle::CE_ProgressBarLabel, controlSize(control)); +} + +void QQuickStyleItemProgressBar::connectToControl() const +{ + QQuickStyleItem::connectToControl(); + auto progressBar = control<QQuickProgressBar>(); + connect(progressBar, &QQuickProgressBar::fromChanged, this, &QQuickStyleItem::markImageDirty); + connect(progressBar, &QQuickProgressBar::toChanged, this, &QQuickStyleItem::markImageDirty); + connect(progressBar, &QQuickProgressBar::positionChanged, this, &QQuickStyleItem::markImageDirty); +} + +StyleItemGeometry QQuickStyleItemProgressBar::calculateGeometry() +{ + QStyleOptionProgressBar styleOption; + initStyleOption(styleOption); + + StyleItemGeometry geometry; + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_ProgressBar, &styleOption, QSize(0, 0)); + + // From qprogressbar.cpp in qtbase: + const int cw = style()->pixelMetric(QStyle::PM_ProgressBarChunkWidth, &styleOption); + QFontMetrics fm(control<QQuickProgressBar>()->font()); + QSize size = QSize(qMax(9, cw) * 7 + fm.horizontalAdvance(QLatin1Char('0')) * 4, fm.height() + 8); + if (!(styleOption.state & QStyle::State_Horizontal)) + size = size.transposed(); + + geometry.implicitSize = style()->sizeFromContents(QStyle::CT_ProgressBar, &styleOption, size); + styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); + geometry.contentRect = style()->subElementRect(QStyle::SE_ProgressBarContents, &styleOption); + geometry.layoutRect = style()->subElementRect(QStyle::SE_ProgressBarLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_ProgressBar, &styleOption, geometry.minimumSize); + + return geometry; +} + +void QQuickStyleItemProgressBar::paintEvent(QPainter *painter) const +{ + QStyleOptionProgressBar styleOption; + initStyleOption(styleOption); +#ifndef Q_OS_MACOS + const QRect r = styleOption.rect; +#endif + // Note: on macOS, the groove will paint both the background and the contents + styleOption.rect = style()->subElementRect(QStyle::SE_ProgressBarGroove, &styleOption); + style()->drawControl(QStyle::CE_ProgressBarGroove, &styleOption, painter); +#ifndef Q_OS_MACOS + styleOption.rect = r; + styleOption.rect = style()->subElementRect(QStyle::SE_ProgressBarContents, &styleOption); + style()->drawControl(QStyle::CE_ProgressBarContents, &styleOption, painter); +#endif +} + +void QQuickStyleItemProgressBar::initStyleOption(QStyleOptionProgressBar &styleOption) const +{ + initStyleOptionBase(styleOption); + auto progressBar = control<QQuickProgressBar>(); + + styleOption.state = QStyle::State_Horizontal; + + if (progressBar->isIndeterminate()) { + styleOption.minimum = 0; + styleOption.maximum = 0; + } else if (progressBar->to() - progressBar->from() < 100) { + // Add some range to support float numbers + styleOption.minimum = 0; + styleOption.maximum = (progressBar->to() - progressBar->from()) * 100; + styleOption.progress = (progressBar->value() - progressBar->from()) * 100; + } else { + styleOption.minimum = progressBar->from(); + styleOption.maximum = progressBar->to(); + styleOption.progress = progressBar->value(); + } +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitemprogressbar.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitemprogressbar.h b/src/quicknativestyle/items/qquickstyleitemprogressbar.h new file mode 100644 index 00000000000..572c41ed3f1 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemprogressbar.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMPROGRESSBAR_H +#define QQUICKSTYLEITEMPROGRESSBAR_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquickprogressbar_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyleItemProgressBar : public QQuickStyleItem +{ + Q_OBJECT + + QML_NAMED_ELEMENT(ProgressBar) + +public: + QFont styleFont(QQuickItem *control) const override; + +protected: + void connectToControl() const override; + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + void initStyleOption(QStyleOptionProgressBar &styleOption) const; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEITEMPROGRESSBAR_H diff --git a/src/quicknativestyle/items/qquickstyleitemradiobutton.cpp b/src/quicknativestyle/items/qquickstyleitemradiobutton.cpp new file mode 100644 index 00000000000..35704273af1 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemradiobutton.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitemradiobutton.h" + +QT_BEGIN_NAMESPACE + +QFont QQuickStyleItemRadioButton::styleFont(QQuickItem *control) const +{ + return style()->font(QStyle::CE_RadioButtonLabel, controlSize(control)); +} + +void QQuickStyleItemRadioButton::connectToControl() const +{ + QQuickStyleItem::connectToControl(); + auto checkbox = control<QQuickRadioButton>(); + connect(checkbox, &QQuickRadioButton::downChanged, this, &QQuickStyleItem::markImageDirty); + connect(checkbox, &QQuickRadioButton::checkedChanged, this, &QQuickStyleItem::markImageDirty); +} + +StyleItemGeometry QQuickStyleItemRadioButton::calculateGeometry() +{ + QStyleOptionButton styleOption; + initStyleOption(styleOption); + StyleItemGeometry geometry; + + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_RadioButton, &styleOption, QSize(0, 0)); + geometry.implicitSize = geometry.minimumSize; + styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); + geometry.contentRect = style()->subElementRect(QStyle::SE_RadioButtonContents, &styleOption); + geometry.layoutRect = style()->subElementRect(QStyle::SE_RadioButtonLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_RadioButton, &styleOption, geometry.minimumSize); + geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_RadioButtonFocusFrameRadius, &styleOption); + + return geometry; +} + +void QQuickStyleItemRadioButton::paintEvent(QPainter *painter) const +{ + QStyleOptionButton styleOption; + initStyleOption(styleOption); + style()->drawControl(QStyle::CE_RadioButton, &styleOption, painter); +} + +void QQuickStyleItemRadioButton::initStyleOption(QStyleOptionButton &styleOption) const +{ + initStyleOptionBase(styleOption); + auto checkbox = control<QQuickRadioButton>(); + + styleOption.state |= checkbox->isDown() ? QStyle::State_Sunken : QStyle::State_Raised; + styleOption.state |= checkbox->isChecked() ? QStyle::State_On : QStyle::State_Off; +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitemradiobutton.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitemradiobutton.h b/src/quicknativestyle/items/qquickstyleitemradiobutton.h new file mode 100644 index 00000000000..73aad8419c8 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemradiobutton.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMRADIOBUTTON_H +#define QQUICKSTYLEITEMRADIOBUTTON_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquickradiobutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyleItemRadioButton : public QQuickStyleItem +{ + Q_OBJECT + QML_NAMED_ELEMENT(RadioButton) + +public: + QFont styleFont(QQuickItem *control) const override; + +protected: + void connectToControl() const override; + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + void initStyleOption(QStyleOptionButton &styleOption) const; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEITEMRADIOBUTTON_H diff --git a/src/quicknativestyle/items/qquickstyleitemscrollbar.cpp b/src/quicknativestyle/items/qquickstyleitemscrollbar.cpp new file mode 100644 index 00000000000..1ff90b2f19b --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemscrollbar.cpp @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitemscrollbar.h" + +QT_BEGIN_NAMESPACE + +QFont QQuickStyleItemScrollBar::styleFont(QQuickItem *control) const +{ + return style()->font(QStyle::CE_ProgressBarLabel, controlSize(control)); +} + +void QQuickStyleItemScrollBar::connectToControl() const +{ + QQuickStyleItem::connectToControl(); + auto scrollBar = control<QQuickScrollBar>(); + connect(scrollBar, &QQuickScrollBar::orientationChanged, this, &QQuickStyleItem::markImageDirty); + connect(scrollBar, &QQuickScrollBar::pressedChanged, this, &QQuickStyleItem::markImageDirty); +} + +StyleItemGeometry QQuickStyleItemScrollBar::calculateGeometry() +{ + QStyleOptionSlider styleOption; + initStyleOption(styleOption); + + StyleItemGeometry geometry; + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_ScrollBar, &styleOption, QSize(0, 0)); + if (m_subControl == SubLine || m_subControl == AddLine) { + // So far, we know that only the windows style uses these subcontrols, + // so we can use hardcoded sizes... + QSize sz(16, 17); + if (styleOption.orientation == Qt::Vertical) + sz.transpose(); + geometry.minimumSize = sz; + } + geometry.implicitSize = geometry.minimumSize; + styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); + geometry.layoutRect = style()->subElementRect(QStyle::SE_ScrollBarLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_ScrollBar, &styleOption, geometry.minimumSize); + + return geometry; +} + +void QQuickStyleItemScrollBar::paintEvent(QPainter *painter) const +{ + QStyleOptionSlider styleOption; + initStyleOption(styleOption); + if (m_subControl == SubLine || m_subControl == AddLine) { + QStyle::SubControl sc = m_subControl == SubLine ? QStyle::SC_ScrollBarSubLine : QStyle::SC_ScrollBarAddLine; + QStyleOptionSlider opt = styleOption; + opt.subControls = QStyle::SC_ScrollBarAddLine + | QStyle::SC_ScrollBarSubLine + | QStyle::SC_ScrollBarGroove; + + const qreal scale = window()->effectiveDevicePixelRatio(); + const QSize scrollBarMinSize = style()->sizeFromContents(QStyle::CT_ScrollBar, &opt, QSize(0, 0)); + const QSize sz = scrollBarMinSize * scale; + QImage scrollBarImage(sz, QImage::Format_ARGB32_Premultiplied); + scrollBarImage.setDevicePixelRatio(scale); + QPainter p(&scrollBarImage); + opt.rect = QRect(QPoint(0, 0), scrollBarMinSize); + style()->drawComplexControl(QStyle::CC_ScrollBar, &opt, &p); + QRect sourceImageRect = style()->subControlRect(QStyle::CC_ScrollBar, &opt, sc); + sourceImageRect = QRect(sourceImageRect.topLeft() * scale, sourceImageRect.size() * scale); + painter->drawImage(QPoint(0, 0), scrollBarImage, sourceImageRect); + } else { + style()->drawComplexControl(QStyle::CC_ScrollBar, &styleOption, painter); + } +} + +void QQuickStyleItemScrollBar::initStyleOption(QStyleOptionSlider &styleOption) const +{ + initStyleOptionBase(styleOption); + auto scrollBar = control<QQuickScrollBar>(); + + switch (m_subControl) { + case Groove: + styleOption.subControls = QStyle::SC_ScrollBarGroove | QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine; + break; + case Handle: + styleOption.subControls = QStyle::SC_ScrollBarSlider; + break; + case AddLine: + styleOption.subControls = QStyle::SC_ScrollBarAddLine; + break; + case SubLine: + styleOption.subControls = QStyle::SC_ScrollBarSubLine; + break; + } + + styleOption.activeSubControls = QStyle::SC_None; + styleOption.orientation = scrollBar->orientation(); + if (styleOption.orientation == Qt::Horizontal) + styleOption.state |= QStyle::State_Horizontal; + + if (scrollBar->isPressed()) + styleOption.state |= QStyle::State_Sunken; + + if (m_overrideState != None) { + // In ScrollBar.qml we fade between two versions of + // the handle, depending on if it's hovered or not + + if (m_overrideState == AlwaysHovered) { + styleOption.activeSubControls = (styleOption.subControls & (QStyle::SC_ScrollBarSlider | QStyle::SC_ScrollBarGroove | QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine)); + } else if (m_overrideState == NeverHovered) { + styleOption.activeSubControls &= ~(styleOption.subControls & (QStyle::SC_ScrollBarSlider | QStyle::SC_ScrollBarGroove | QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine)); + } else if (m_overrideState == AlwaysSunken) { + styleOption.state |= QStyle::State_Sunken; + styleOption.activeSubControls = (styleOption.subControls & (QStyle::SC_ScrollBarSlider | QStyle::SC_ScrollBarGroove | QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine)); + } + } + + // The following values will let the handle fill 100% of the + // groove / imageSize. But when the handle is resized by + // QQuickScrollBar, it will end up with the correct size visually. + styleOption.pageStep = 1000; + styleOption.minimum = 0; + styleOption.maximum = 1; + styleOption.sliderValue = 0; +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitemscrollbar.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitemscrollbar.h b/src/quicknativestyle/items/qquickstyleitemscrollbar.h new file mode 100644 index 00000000000..31dc410044c --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemscrollbar.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMSCROLLBAR_H +#define QQUICKSTYLEITEMSCROLLBAR_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquickscrollbar_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyleItemScrollBar : public QQuickStyleItem +{ + Q_OBJECT + + Q_PROPERTY(SubControl subControl MEMBER m_subControl) + + QML_NAMED_ELEMENT(ScrollBar) + +public: + enum SubControl { + Groove = 1, + Handle, + AddLine, + SubLine + }; + Q_ENUM(SubControl) + + QFont styleFont(QQuickItem *control) const override; + +protected: + void connectToControl() const override; + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + void initStyleOption(QStyleOptionSlider &styleOption) const; + +private: + SubControl m_subControl = Groove; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEITEMSCROLLBAR_H diff --git a/src/quicknativestyle/items/qquickstyleitemscrollviewcorner.cpp b/src/quicknativestyle/items/qquickstyleitemscrollviewcorner.cpp new file mode 100644 index 00000000000..ef12703b2db --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemscrollviewcorner.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitemscrollviewcorner.h" + +StyleItemGeometry QQuickStyleItemScrollViewCorner::calculateGeometry() +{ + QStyleOptionSlider styleOption; + initStyleOption(styleOption); + + StyleItemGeometry geometry; + + // The size of the corner should be the width of the vertical + // scrollbar and the height of the horizontal scrollbar. + styleOption.orientation = Qt::Vertical; + const auto vScrollBarWidth = style()->sizeFromContents(QStyle::CT_ScrollBar, &styleOption, QSize(0, 0)).width(); + styleOption.orientation = Qt::Horizontal; + const auto hScrollBarHeight = style()->sizeFromContents(QStyle::CT_ScrollBar, &styleOption, QSize(0, 0)).height(); + + geometry.minimumSize = QSize(vScrollBarWidth, hScrollBarHeight); + geometry.implicitSize = geometry.minimumSize; + + return geometry; +} + +void QQuickStyleItemScrollViewCorner::paintEvent(QPainter *painter) const +{ + QStyleOptionSlider styleOption; + initStyleOption(styleOption); + + // Grab a center piece of a vertical scrollbar groove onto a QImage, and use this + // image to draw a corner. We draw the corner by first drawing the piece as it is, and + // then rotate it 90 degrees, clip it into a triangle, and draw it once more on top. + // The result is that we end up with one vertical and one horizontal triangle that + // together form a filled corner rectangle. + + styleOption.orientation = Qt::Vertical; + + const qreal scale = window()->effectiveDevicePixelRatio(); + const int grooveWidth = minimumSize().width(); + const int grooveHeight = minimumSize().height(); + const QSize scrollBarMinSize = style()->sizeFromContents(QStyle::CT_ScrollBar, &styleOption, QSize(0, 0)); + const QSize scrollBarSize = scrollBarMinSize + QSize(0, grooveHeight); + const int hStart = scrollBarMinSize.height() / 2; + const QRect targetImageRect(0, hStart * scale, grooveWidth * scale, grooveHeight * scale); + + QImage scrollBarImage(scrollBarSize * scale, QImage::Format_ARGB32_Premultiplied); + scrollBarImage.setDevicePixelRatio(scale); + scrollBarImage.fill(Qt::transparent); + QPainter scrollBarPainter(&scrollBarImage); + styleOption.rect = QRect(QPoint(0, 0), scrollBarSize); + style()->drawComplexControl(QStyle::CC_ScrollBar, &styleOption, &scrollBarPainter); + + // Draw vertical groove + painter->drawImage(QPoint(0, 0), scrollBarImage, targetImageRect); + + QPainterPath path; + path.moveTo(0, 0); + path.lineTo(0, grooveHeight); + path.lineTo(grooveWidth, grooveHeight); + path.closeSubpath(); + + QTransform transform; + transform.translate(grooveWidth, 0); + transform.rotate(90); + + painter->save(); + painter->setCompositionMode(QPainter::CompositionMode_Source); + painter->setClipPath(path); + painter->setTransform(transform); + // Draw horizontal groove, clipped to a triangle + painter->drawImage(QPoint(0, 0), scrollBarImage, targetImageRect); + painter->restore(); +} + +void QQuickStyleItemScrollViewCorner::initStyleOption(QStyleOptionSlider &styleOption) const +{ + initStyleOptionBase(styleOption); + + styleOption.subControls = QStyle::SC_ScrollBarGroove; + styleOption.activeSubControls = QStyle::SC_None; + styleOption.pageStep = 1000; + styleOption.minimum = 0; + styleOption.maximum = 1; + styleOption.sliderValue = 0; +} diff --git a/src/quicknativestyle/items/qquickstyleitemscrollviewcorner.h b/src/quicknativestyle/items/qquickstyleitemscrollviewcorner.h new file mode 100644 index 00000000000..637a8ea821e --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemscrollviewcorner.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMSCROLLVIEWCORNER_H +#define QQUICKSTYLEITEMSCROLLVIEWCORNER_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquickscrollbar_p.h> + +class QQuickStyleItemScrollViewCorner : public QQuickStyleItem +{ + Q_OBJECT + QML_NAMED_ELEMENT(ScrollViewCorner) + +protected: + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + void initStyleOption(QStyleOptionSlider &styleOption) const; +}; + +#endif // QQUICKSTYLEITEMSCROLLVIEWCORNER_H diff --git a/src/quicknativestyle/items/qquickstyleitemslider.cpp b/src/quicknativestyle/items/qquickstyleitemslider.cpp new file mode 100644 index 00000000000..03f567d6fc5 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemslider.cpp @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitemslider.h" + +QT_BEGIN_NAMESPACE + +QFont QQuickStyleItemSlider::styleFont(QQuickItem *control) const +{ + return style()->font(QStyle::CE_ProgressBarLabel, controlSize(control)); +} + +void QQuickStyleItemSlider::connectToControl() const +{ + QQuickStyleItem::connectToControl(); + auto slider = control<QQuickSlider>(); + connect(slider, &QQuickSlider::fromChanged, this, &QQuickStyleItem::markImageDirty); + connect(slider, &QQuickSlider::toChanged, this, &QQuickStyleItem::markImageDirty); + connect(slider, &QQuickSlider::positionChanged, this, &QQuickStyleItem::markImageDirty); + connect(slider, &QQuickSlider::valueChanged, this, &QQuickStyleItem::markImageDirty); + connect(slider, &QQuickSlider::stepSizeChanged, this, &QQuickStyleItem::markImageDirty); + connect(slider, &QQuickSlider::pressedChanged, this, &QQuickStyleItem::markImageDirty); + connect(slider, &QQuickSlider::orientationChanged, this, &QQuickStyleItem::markImageDirty); +} + +StyleItemGeometry QQuickStyleItemSlider::calculateGeometry() +{ + QStyleOptionSlider styleOption; + initStyleOption(styleOption); + + StyleItemGeometry geometry; + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_Slider, &styleOption, QSize(0, 0)); + geometry.implicitSize = geometry.minimumSize; + styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); + geometry.layoutRect = style()->subElementRect(QStyle::SE_SliderLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_Slider, &styleOption, geometry.minimumSize); + geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_SliderFocusFrameRadius, &styleOption); + + return geometry; +} + +void QQuickStyleItemSlider::paintEvent(QPainter *painter) const +{ + QStyleOptionSlider styleOption; + initStyleOption(styleOption); + style()->drawComplexControl(QStyle::CC_Slider, &styleOption, painter); +} + +void QQuickStyleItemSlider::initStyleOption(QStyleOptionSlider &styleOption) const +{ + initStyleOptionBase(styleOption); + auto slider = control<QQuickSlider>(); + + styleOption.subControls = QStyle::SC_None; + if (m_subControl & Groove) + styleOption.subControls |= QStyle::SC_SliderGroove; + if (m_subControl & Handle) + styleOption.subControls |= QStyle::SC_SliderHandle; + styleOption.activeSubControls = QStyle::SC_None; + styleOption.orientation = slider->orientation(); + + if (slider->isPressed()) + styleOption.state |= QStyle::State_Sunken; + + qreal min = 0; + qreal max = 1; + if (!qFuzzyIsNull(slider->stepSize())) { + min = slider->from(); + max = slider->to(); + + // TODO: add proper API for tickmarks + const int index = slider->metaObject()->indexOfProperty("qqc2_style_tickPosition"); + if (index != -1) { + const int tickPosition = slider->metaObject()->property(index).read(slider).toInt(); + styleOption.tickPosition = QStyleOptionSlider::TickPosition(tickPosition); + if (styleOption.tickPosition != QStyleOptionSlider::NoTicks) + styleOption.subControls |= QStyle::SC_SliderTickmarks; + } + } + + // Since the [from, to] interval in QQuickSlider is floating point, users can + // specify very small ranges and step sizes, (e.g. [0.., 0.25], step size 0.05). + // Since the style operates on ints, we cannot pass these values directly to the style, + // so we normalize all values to the range [0, 10000] + static const qreal Scale = 10000; + const qreal normalizeMultiplier = Scale/(max - min); + styleOption.tickInterval = int(slider->stepSize() * normalizeMultiplier); + styleOption.minimum = 0; + styleOption.maximum = int(Scale); + styleOption.sliderValue = int((slider->value() - min) * normalizeMultiplier); + styleOption.sliderPosition = int(slider->position() * styleOption.maximum); +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitemslider.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitemslider.h b/src/quicknativestyle/items/qquickstyleitemslider.h new file mode 100644 index 00000000000..0d86a65b874 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemslider.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMSLIDER_H +#define QQUICKSTYLEITEMSLIDER_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquickslider_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyleItemSlider : public QQuickStyleItem +{ + Q_OBJECT + + Q_PROPERTY(SubControl subControl MEMBER m_subControl) + + QML_NAMED_ELEMENT(Slider) + +public: + enum SubControl { + Groove = 1, + Handle, + }; + Q_ENUM(SubControl) + + QFont styleFont(QQuickItem *control) const override; + +protected: + void connectToControl() const override; + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + void initStyleOption(QStyleOptionSlider &styleOption) const; + +private: + SubControl m_subControl = Groove; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEITEMSLIDER_H diff --git a/src/quicknativestyle/items/qquickstyleitemspinbox.cpp b/src/quicknativestyle/items/qquickstyleitemspinbox.cpp new file mode 100644 index 00000000000..2f73da7db72 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemspinbox.cpp @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitemspinbox.h" +#include <QtQuickTemplates2/private/qquickindicatorbutton_p.h> + +QT_BEGIN_NAMESPACE + +QFont QQuickStyleItemSpinBox::styleFont(QQuickItem *control) const +{ + return style()->font(QStyle::CE_ComboBoxLabel, controlSize(control)); +} + +void QQuickStyleItemSpinBox::connectToControl() const +{ + QQuickStyleItem::connectToControl(); + auto spinbox = control<QQuickSpinBox>(); + connect(spinbox->up(), &QQuickIndicatorButton::pressedChanged, this, &QQuickStyleItem::markImageDirty); + connect(spinbox->down(), &QQuickIndicatorButton::pressedChanged, this, &QQuickStyleItem::markImageDirty); +} + +StyleItemGeometry QQuickStyleItemSpinBox::calculateGeometry() +{ + QStyleOptionSpinBox styleOption; + initStyleOption(styleOption); + StyleItemGeometry geometry; + + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_SpinBox, &styleOption, QSize(0, 0)); + + if (styleOption.subControls == QStyle::SC_SpinBoxFrame) { + geometry.implicitSize = style()->sizeFromContents(QStyle::CT_SpinBox, &styleOption, contentSize()); + styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); + geometry.contentRect = style()->subControlRect(QStyle::CC_SpinBox, &styleOption, QStyle::SC_SpinBoxEditField); + geometry.layoutRect = style()->subElementRect(QStyle::SE_SpinBoxLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_SpinBox, &styleOption, geometry.minimumSize); + geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_SpinBoxFocusFrameRadius, &styleOption); + } else { + geometry.implicitSize = geometry.minimumSize; + } + + return geometry; +} + +void QQuickStyleItemSpinBox::paintEvent(QPainter *painter) const +{ + QStyleOptionSpinBox styleOption; + initStyleOption(styleOption); + style()->drawComplexControl(QStyle::CC_SpinBox, &styleOption, painter); +} + +void QQuickStyleItemSpinBox::initStyleOption(QStyleOptionSpinBox &styleOption) const +{ + initStyleOptionBase(styleOption); + auto spinbox = control<QQuickSpinBox>(); + + switch (m_subControl) { + case Frame: + styleOption.subControls = QStyle::SC_SpinBoxFrame; + styleOption.frame = true; + break; + case Up: + styleOption.subControls = (QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown); + break; + case Down: + styleOption.subControls = QStyle::SC_SpinBoxDown; + break; + } + + if (spinbox->up()->isPressed()) { + styleOption.activeSubControls = QStyle::SC_SpinBoxUp; + styleOption.state |= QStyle::State_Sunken; + } else if (spinbox->down()->isPressed()) { + styleOption.activeSubControls = QStyle::SC_SpinBoxDown; + styleOption.state |= QStyle::State_Sunken; + } + + styleOption.buttonSymbols = QStyleOptionSpinBox::UpDownArrows; + styleOption.stepEnabled = QStyleOptionSpinBox::StepEnabled; +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitemspinbox.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitemspinbox.h b/src/quicknativestyle/items/qquickstyleitemspinbox.h new file mode 100644 index 00000000000..9667d0ffed7 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemspinbox.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMSPINBOX_H +#define QQUICKSTYLEITEMSPINBOX_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquickspinbox_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyleItemSpinBox : public QQuickStyleItem +{ + Q_OBJECT + + Q_PROPERTY(SubControl subControl MEMBER m_subControl) + + QML_NAMED_ELEMENT(SpinBox) + +public: + enum SubControl { + Frame = 1, + Up, + Down, + }; + Q_ENUM(SubControl) + + QFont styleFont(QQuickItem *control) const override; + +protected: + void connectToControl() const override; + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + void initStyleOption(QStyleOptionSpinBox &styleOption) const; + +private: + SubControl m_subControl = Frame; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEITEMSPINBOX_H diff --git a/src/quicknativestyle/items/qquickstyleitemtextfield.cpp b/src/quicknativestyle/items/qquickstyleitemtextfield.cpp new file mode 100644 index 00000000000..0b8ab379427 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemtextfield.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleitemtextfield.h" + +QT_BEGIN_NAMESPACE + +QFont QQuickStyleItemTextField::styleFont(QQuickItem *control) const +{ + return style()->font(QStyle::CE_ComboBoxLabel, controlSize(control)); +} + +void QQuickStyleItemTextField::connectToControl() const +{ + QQuickStyleItem::connectToControl(); + auto textField = control<QQuickTextField>(); + connect(textField, &QQuickTextField::readOnlyChanged, this, &QQuickStyleItem::markImageDirty); + connect(textField, &QQuickTextField::focusChanged, this, &QQuickStyleItem::markImageDirty); +} + +StyleItemGeometry QQuickStyleItemTextField::calculateGeometry() +{ + QStyleOptionFrame styleOption; + initStyleOption(styleOption); + StyleItemGeometry geometry; + + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_LineEdit, &styleOption, QSize(0, 0)); + + // Inspired by QLineEdit::sizeHint() + QFontMetricsF fm(styleFont(const_cast<QQuickItem*>(control<QQuickItem>()))); + const QSize sz(qCeil(fm.horizontalAdvance(QLatin1Char('x')) * 17), + contentSize().height()); + geometry.implicitSize = style()->sizeFromContents(QStyle::CT_LineEdit, &styleOption, sz); + + styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); + geometry.layoutRect = styleOption.rect; + geometry.contentRect = style()->subElementRect(QStyle::SE_LineEditContents, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_ShapedFrame, &styleOption, geometry.minimumSize); + geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_TextFieldFocusFrameRadius, &styleOption); + + return geometry; +} + +void QQuickStyleItemTextField::paintEvent(QPainter *painter) const +{ + QStyleOptionFrame styleOption; + initStyleOption(styleOption); + style()->drawPrimitive(QStyle::PE_PanelLineEdit, &styleOption, painter); +} + +void QQuickStyleItemTextField::initStyleOption(QStyleOptionFrame &styleOption) const +{ + initStyleOptionBase(styleOption); + auto textField = control<QQuickTextField>(); + + styleOption.lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &styleOption); + styleOption.midLineWidth = 0; + styleOption.state |= QStyle::State_Sunken; + if (textField->isReadOnly()) + styleOption.state |= QStyle::State_ReadOnly; +} + +QT_END_NAMESPACE + +#include "moc_qquickstyleitemtextfield.cpp" diff --git a/src/quicknativestyle/items/qquickstyleitemtextfield.h b/src/quicknativestyle/items/qquickstyleitemtextfield.h new file mode 100644 index 00000000000..9f6b66b7299 --- /dev/null +++ b/src/quicknativestyle/items/qquickstyleitemtextfield.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTYLEITEMTEXTFIELD_H +#define QQUICKSTYLEITEMTEXTFIELD_H + +#include "qquickstyleitem.h" +#include <QtQuickTemplates2/private/qquicktextfield_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyleItemTextField : public QQuickStyleItem +{ + Q_OBJECT + QML_NAMED_ELEMENT(TextField) + +public: + QFont styleFont(QQuickItem *control) const override; + +protected: + void connectToControl() const override; + void paintEvent(QPainter *painter) const override; + StyleItemGeometry calculateGeometry() override; + +private: + void initStyleOption(QStyleOptionFrame &styleOption) const; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLEITEMTEXTFIELD_H diff --git a/src/quicknativestyle/qstyle/mac/mac.pri b/src/quicknativestyle/qstyle/mac/mac.pri new file mode 100644 index 00000000000..2f7ee7d436c --- /dev/null +++ b/src/quicknativestyle/qstyle/mac/mac.pri @@ -0,0 +1,12 @@ +LIBS_PRIVATE += -framework AppKit + +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qquickmacstyle_mac_p.h \ + $$PWD/qquickmacstyle_mac_p_p.h + +SOURCES += + +OBJECTIVE_SOURCES += \ + $$PWD/qquickmacstyle_mac.mm diff --git a/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm b/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm new file mode 100644 index 00000000000..0e2f96183f6 --- /dev/null +++ b/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm @@ -0,0 +1,6063 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + Note: The qdoc comments for QMacStyle are contained in + .../doc/src/qstyles.qdoc. +*/ + +#include <AppKit/AppKit.h> + +#include "qquickmacstyle_mac_p.h" +#include "qquickmacstyle_mac_p_p.h" +#include "qquickstylehelper_p.h" + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +#define QMAC_QAQUASTYLE_SIZE_CONSTRAIN +//#define DEBUG_SIZE_CONSTRAINT + +#include <QtCore/qoperatingsystemversion.h> +#include <QtCore/qvariant.h> +#include <QtCore/qvarlengtharray.h> + +#include <QtGui/qpainterpath.h> +#include <QtGui/qpa/qplatformnativeinterface.h> +#include <QtGui/qpa/qplatformfontdatabase.h> +#include <QtGui/qpa/qplatformtheme.h> + +#include <QtCore/private/qcore_mac_p.h> +#include <QtGui/private/qcoregraphics_p.h> +#include <QtGui/private/qguiapplication_p.h> + +#include <cmath> + +QT_USE_NAMESPACE + +// OBS! Changing QT_MANGLE_NAMESPACE and QT_NAMESPACE_ALIAS_OBJC_CLASS to take +// both QT_NAMESPACE and QQC2_NAMESPACE into account (and not only QT_NAMESPACE, which +// would otherwise be the case). This will make it possible to link in both widgets and +// controls in the same application when building statically. +#undef QT_MANGLE_NAMESPACE +#undef QT_NAMESPACE_ALIAS_OBJC_CLASS + +#define QQC2_MANGLE1(a, b) a##_##b +#define QQC2_MANGLE2(a, b) QQC2_MANGLE1(a, b) + +#if defined(QT_NAMESPACE) + #define QT_MANGLE_NAMESPACE(name) QQC2_MANGLE2(QQC2_MANGLE1(name, QQC2_NAMESPACE), QT_NAMESPACE) + #define QT_NAMESPACE_ALIAS_OBJC_CLASS(name) @compatibility_alias name QT_MANGLE_NAMESPACE(name) +#else + #define QT_MANGLE_NAMESPACE(name) QQC2_MANGLE2(name, QQC2_NAMESPACE) + #define QT_NAMESPACE_ALIAS_OBJC_CLASS(name) @compatibility_alias name QT_MANGLE_NAMESPACE(name) +#endif + +@interface QT_MANGLE_NAMESPACE(QIndeterminateProgressIndicator) : NSProgressIndicator + +@property (readonly, nonatomic) NSInteger animators; + +- (instancetype)init; + +- (void)startAnimation; +- (void)stopAnimation; + +- (void)drawWithFrame:(CGRect)rect inView:(NSView *)view; + +@end + +QT_NAMESPACE_ALIAS_OBJC_CLASS(QIndeterminateProgressIndicator); + +@implementation QIndeterminateProgressIndicator + +- (instancetype)init +{ + if ((self = [super init])) { + _animators = 0; + self.indeterminate = YES; + self.usesThreadedAnimation = NO; + self.alphaValue = 0.0; + } + + return self; +} + +- (void)startAnimation +{ + if (_animators == 0) { + self.hidden = NO; + [super startAnimation:self]; + } + ++_animators; +} + +- (void)stopAnimation +{ + --_animators; + if (_animators == 0) { + [super stopAnimation:self]; + self.hidden = YES; + [self removeFromSuperviewWithoutNeedingDisplay]; + } +} + +- (void)drawWithFrame:(CGRect)rect inView:(NSView *)view +{ + // The alphaValue change is not strictly necessary, but feels safer. + self.alphaValue = 1.0; + if (self.superview != view) + [view addSubview:self]; + if (!CGRectEqualToRect(self.frame, rect)) + self.frame = rect; + [self drawRect:rect]; + self.alphaValue = 0.0; +} + +@end + +@interface QT_MANGLE_NAMESPACE(QVerticalSplitView) : NSSplitView +- (BOOL)isVertical; +@end + +QT_NAMESPACE_ALIAS_OBJC_CLASS(QVerticalSplitView); + +@implementation QVerticalSplitView +- (BOOL)isVertical +{ + return YES; +} +@end + +// See render code in drawPrimitive(PE_FrameTabWidget) +@interface QT_MANGLE_NAMESPACE(QDarkNSBox) : NSBox +@end + +QT_NAMESPACE_ALIAS_OBJC_CLASS(QDarkNSBox); + +@implementation QDarkNSBox +- (instancetype)init +{ + if ((self = [super init])) { + self.title = @""; + self.titlePosition = NSNoTitle; + self.boxType = NSBoxCustom; + self.cornerRadius = 3; + self.borderColor = [NSColor.controlColor colorWithAlphaComponent:0.1]; + self.fillColor = [NSColor.darkGrayColor colorWithAlphaComponent:0.2]; + } + + return self; +} + +- (void)drawRect:(NSRect)rect +{ + [super drawRect:rect]; +} +@end + +QT_BEGIN_NAMESPACE + +namespace QQC2_NAMESPACE { + +// The following constants are used for adjusting the size +// of push buttons so that they are drawn inside their bounds. +const int QMacStylePrivate::PushButtonLeftOffset = 6; +const int QMacStylePrivate::PushButtonRightOffset = 12; +const int QMacStylePrivate::PushButtonContentPadding = 6; + +QVector<QPointer<QObject> > QMacStylePrivate::scrollBars; + +// Title bar gradient colors for Lion were determined by inspecting PSDs exported +// using CoreUI's CoreThemeDocument; there is no public API to retrieve them + +static QLinearGradient titlebarGradientActive() +{ + static QLinearGradient darkGradient = [](){ + QLinearGradient gradient; + // FIXME: colors are chosen somewhat arbitrarily and could be fine-tuned, + // or ideally determined by calling a native API. + gradient.setColorAt(0, QColor(47, 47, 47)); + return gradient; + }(); + static QLinearGradient lightGradient = [](){ + QLinearGradient gradient; + gradient.setColorAt(0, QColor(235, 235, 235)); + gradient.setColorAt(0.5, QColor(210, 210, 210)); + gradient.setColorAt(0.75, QColor(195, 195, 195)); + gradient.setColorAt(1, QColor(180, 180, 180)); + return gradient; + }(); + return qt_mac_applicationIsInDarkMode() ? darkGradient : lightGradient; +} + +static QLinearGradient titlebarGradientInactive() +{ + static QLinearGradient darkGradient = [](){ + QLinearGradient gradient; + gradient.setColorAt(1, QColor(42, 42, 42)); + return gradient; + }(); + static QLinearGradient lightGradient = [](){ + QLinearGradient gradient; + gradient.setColorAt(0, QColor(250, 250, 250)); + gradient.setColorAt(1, QColor(225, 225, 225)); + return gradient; + }(); + return qt_mac_applicationIsInDarkMode() ? darkGradient : lightGradient; +} + +/* + Since macOS 10.14 AppKit is using transparency more extensively, especially for the + dark theme. Inactive buttons, for example, are semi-transparent. And we use them to + draw tab widget's tab bar. The combination of NSBox (also a part of tab widget) + and these transparent buttons gives us an undesired side-effect: an outline of + NSBox is visible through transparent buttons. To avoid this, we have this hack below: + we clip the area where the line would be visible through the buttons. The area we + want to clip away can be described as an intersection of the option's rect and + the tab widget's tab bar rect. But some adjustments are required, since those rects + are anyway adjusted during the rendering and they are not exactly what you'll see on + the screen. Thus this switch-statement inside. +*/ +static void clipTabBarFrame(const QStyleOption *option, const QMacStyle *style, CGContextRef ctx) +{ + Q_ASSERT(option); + Q_ASSERT(style); + Q_ASSERT(ctx); + + if (qt_mac_applicationIsInDarkMode()) { +// QTabWidget *tabWidget = qobject_cast<QTabWidget *>(option->styleObject); +// Q_ASSERT(tabWidget); + +// QRect tabBarRect = style->subElementRect(QStyle::SE_TabWidgetTabBar, option, tabWidget).adjusted(2, 0, -3, 0); +// switch (tabWidget->tabPosition()) { +// case QTabWidget::South: +// tabBarRect.setY(tabBarRect.y() + tabBarRect.height() / 2); +// break; +// case QTabWidget::North: +// case QTabWidget::West: +// tabBarRect = tabBarRect.adjusted(0, 2, 0, -2); +// break; +// case QTabWidget::East: +// tabBarRect = tabBarRect.adjusted(tabBarRect.width() / 2, 2, tabBarRect.width() / 2, -2); +// } + +// const QRegion clipPath = QRegion(option->rect) - tabBarRect; +// QVarLengthArray<CGRect, 3> cgRects; +// for (const QRect &qtRect : clipPath) +// cgRects.push_back(qtRect.toCGRect()); +// if (cgRects.size()) +// CGContextClipToRects(ctx, &cgRects[0], size_t(cgRects.size())); + } +} + +static const QColor titlebarSeparatorLineActive(111, 111, 111); +static const QColor titlebarSeparatorLineInactive(131, 131, 131); +static const QColor darkModeSeparatorLine(88, 88, 88); + +// Gradient colors used for the dock widget title bar and +// non-unifed tool bar background. +static const QColor lightMainWindowGradientBegin(240, 240, 240); +static const QColor lightMainWindowGradientEnd(200, 200, 200); +static const QColor darkMainWindowGradientBegin(47, 47, 47); +static const QColor darkMainWindowGradientEnd(47, 47, 47); + +static const int DisclosureOffset = 4; + +static const qreal titleBarIconTitleSpacing = 5; +static const qreal titleBarTitleRightMargin = 12; +static const qreal titleBarButtonSpacing = 8; + +// Tab bar colors +// active: window is active +// selected: tab is selected +// hovered: tab is hovered +bool isDarkMode() { return qt_mac_applicationIsInDarkMode(); } + +static const QColor lightTabBarTabBackgroundActive(190, 190, 190); +static const QColor darkTabBarTabBackgroundActive(38, 38, 38); +static const QColor tabBarTabBackgroundActive() { return isDarkMode() ? darkTabBarTabBackgroundActive : lightTabBarTabBackgroundActive; } + +static const QColor lightTabBarTabBackgroundActiveHovered(178, 178, 178); +static const QColor darkTabBarTabBackgroundActiveHovered(32, 32, 32); +static const QColor tabBarTabBackgroundActiveHovered() { return isDarkMode() ? darkTabBarTabBackgroundActiveHovered : lightTabBarTabBackgroundActiveHovered; } + +static const QColor lightTabBarTabBackgroundActiveSelected(211, 211, 211); +static const QColor darkTabBarTabBackgroundActiveSelected(52, 52, 52); +static const QColor tabBarTabBackgroundActiveSelected() { return isDarkMode() ? darkTabBarTabBackgroundActiveSelected : lightTabBarTabBackgroundActiveSelected; } + +static const QColor lightTabBarTabBackground(227, 227, 227); +static const QColor darkTabBarTabBackground(38, 38, 38); +static const QColor tabBarTabBackground() { return isDarkMode() ? darkTabBarTabBackground : lightTabBarTabBackground; } + +static const QColor lightTabBarTabBackgroundSelected(246, 246, 246); +static const QColor darkTabBarTabBackgroundSelected(52, 52, 52); +static const QColor tabBarTabBackgroundSelected() { return isDarkMode() ? darkTabBarTabBackgroundSelected : lightTabBarTabBackgroundSelected; } + +static const QColor lightTabBarTabLineActive(160, 160, 160); +static const QColor darkTabBarTabLineActive(90, 90, 90); +static const QColor tabBarTabLineActive() { return isDarkMode() ? darkTabBarTabLineActive : lightTabBarTabLineActive; } + +static const QColor lightTabBarTabLineActiveHovered(150, 150, 150); +static const QColor darkTabBarTabLineActiveHovered(90, 90, 90); +static const QColor tabBarTabLineActiveHovered() { return isDarkMode() ? darkTabBarTabLineActiveHovered : lightTabBarTabLineActiveHovered; } + +static const QColor lightTabBarTabLine(210, 210, 210); +static const QColor darkTabBarTabLine(90, 90, 90); +static const QColor tabBarTabLine() { return isDarkMode() ? darkTabBarTabLine : lightTabBarTabLine; } + +static const QColor lightTabBarTabLineSelected(189, 189, 189); +static const QColor darkTabBarTabLineSelected(90, 90, 90); +static const QColor tabBarTabLineSelected() { return isDarkMode() ? darkTabBarTabLineSelected : lightTabBarTabLineSelected; } + +static const QColor tabBarCloseButtonBackgroundHovered(162, 162, 162); +static const QColor tabBarCloseButtonBackgroundPressed(153, 153, 153); +static const QColor tabBarCloseButtonBackgroundSelectedHovered(192, 192, 192); +static const QColor tabBarCloseButtonBackgroundSelectedPressed(181, 181, 181); +static const QColor tabBarCloseButtonCross(100, 100, 100); +static const QColor tabBarCloseButtonCrossSelected(115, 115, 115); + +static const int closeButtonSize = 14; +static const qreal closeButtonCornerRadius = 2.0; + +#ifndef QT_NO_ACCESSIBILITY // This ifdef to avoid "unused function" warning. +QBrush brushForToolButton(bool isOnKeyWindow) +{ + // When a toolbutton in a toolbar is in the 'ON' state, we draw a + // partially transparent background. The colors must be different + // for 'Aqua' and 'DarkAqua' appearances though. + if (isDarkMode()) + return isOnKeyWindow ? QColor(73, 73, 73, 100) : QColor(56, 56, 56, 100); + + return isOnKeyWindow ? QColor(0, 0, 0, 28) : QColor(0, 0, 0, 21); +} +#endif // QT_NO_ACCESSIBILITY + +static const int headerSectionArrowHeight = 6; +static const int headerSectionSeparatorInset = 2; + +// One for each of QStyleHelper::WidgetSizePolicy +static const QMarginsF comboBoxFocusRingMargins[3] = { + { 0.5, 2, 3.5, 4 }, + { 0.5, 1, 2.5, 4 }, + { 0.5, 1.5, 2.5, 3.5 } +}; + +static const QMarginsF pullDownButtonShadowMargins[3] = { + { 0.5, -1, 0.5, 2 }, + { 0.5, -1.5, 0.5, 2.5 }, + { 0.5, 0, 0.5, 1 } +}; + +static const QMarginsF pushButtonShadowMargins[3] = { + { 1.5, -1.5, 1.5, 4.5 }, + { 1.5, -1, 1.5, 4 }, + { 1.5, 0.5, 1.5, 2.5 } +}; + +// These are frame heights as reported by Xcode 9's Interface Builder. +// Alignemnet rectangle's heights match for push and popup buttons +// with respective values 21, 18 and 15. + +static const qreal comboBoxDefaultHeight[3] = { + 26, 22, 19 +}; + +static const qreal pushButtonDefaultHeight[3] = { + 32, 28, 16 +}; + +static const qreal popupButtonDefaultHeight[3] = { + 26, 22, 15 +}; + +static const int toolButtonArrowSize = 7; +static const int toolButtonArrowMargin = 2; + +static const qreal focusRingWidth = 3.5; + +// An application can force 'Aqua' theme while the system theme is one of +// the 'Dark' variants. Since in Qt we sometimes use NSControls and even +// NSCells directly without attaching them to any view hierarchy, we have +// to set NSAppearance.currentAppearance to 'Aqua' manually, to make sure +// the correct rendering path is triggered. Apple recommends us to un-set +// the current appearance back after we finished with drawing. This is what +// AppearanceSync is for. + +class AppearanceSync { +public: + AppearanceSync() + { +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave + && !qt_mac_applicationIsInDarkMode()) { + auto requiredAppearanceName = NSApplication.sharedApplication.effectiveAppearance.name; + if (![NSAppearance.currentAppearance.name isEqualToString:requiredAppearanceName]) { + previous = NSAppearance.currentAppearance; + NSAppearance.currentAppearance = [NSAppearance appearanceNamed:requiredAppearanceName]; + } + } +#endif // QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) + } + + ~AppearanceSync() + { + if (previous) + NSAppearance.currentAppearance = previous; + } + +private: + NSAppearance *previous = nil; + + Q_DISABLE_COPY(AppearanceSync) +}; + +static bool setupScroller(NSScroller *scroller, const QStyleOptionSlider *sb) +{ + const qreal length = sb->maximum - sb->minimum + sb->pageStep; + if (qFuzzyIsNull(length)) + return false; + const qreal proportion = sb->pageStep / length; + const qreal range = qreal(sb->maximum - sb->minimum); + qreal value = range ? qreal(sb->sliderValue - sb->minimum) / range : 0; + if (sb->orientation == Qt::Horizontal && sb->direction == Qt::RightToLeft) + value = 1.0 - value; + + scroller.frame = sb->rect.toCGRect(); + scroller.floatValue = value; + scroller.knobProportion = proportion; + return true; +} + +static bool setupSlider(NSSlider *slider, const QStyleOptionSlider *sl) +{ + if (sl->minimum >= sl->maximum) + return false; + + // NSSlider seems to cache values based on tracking and the last layout of the + // NSView, resulting in incorrect knob rects that break the interaction with + // multiple sliders. So completely reinitialize the slider. + [slider initWithFrame:sl->rect.toCGRect()]; + + slider.minValue = sl->minimum; + slider.maxValue = sl->maximum; + slider.intValue = sl->sliderPosition; + slider.enabled = sl->state & QStyle::State_Enabled; + if (sl->tickPosition != QStyleOptionSlider::NoTicks) { + // Set numberOfTickMarks, but TicksBothSides will be treated differently + int interval = sl->tickInterval; + if (interval == 0) { + interval = sl->pageStep; + if (interval == 0) + interval = sl->singleStep; + if (interval == 0) + interval = 1; // return false? + } + slider.numberOfTickMarks = 1 + ((sl->maximum - sl->minimum) / interval); + + const bool ticksAbove = sl->tickPosition == QStyleOptionSlider::TicksAbove; + if (sl->orientation == Qt::Horizontal) + slider.tickMarkPosition = ticksAbove ? NSTickMarkPositionAbove : NSTickMarkPositionBelow; + else + slider.tickMarkPosition = ticksAbove ? NSTickMarkPositionLeading : NSTickMarkPositionTrailing; + } else { + slider.numberOfTickMarks = 0; + } + + // Ensure the values set above are reflected when asking + // the cell for its metrics and to draw itself. + [slider layoutSubtreeIfNeeded]; + + if (sl->state & QStyle::State_Sunken) { + const CGRect knobRect = [slider.cell knobRectFlipped:slider.isFlipped]; + CGPoint pressPoint; + pressPoint.x = CGRectGetMidX(knobRect); + pressPoint.y = CGRectGetMidY(knobRect); + [slider.cell startTrackingAt:pressPoint inView:slider]; + } + + return true; +} + +static bool isInMacUnifiedToolbarArea(QWindow *window, int windowY) +{ + QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); + QPlatformNativeInterface::NativeResourceForIntegrationFunction function = + nativeInterface->nativeResourceFunctionForIntegration("testContentBorderPosition"); + if (!function) + return false; // Not Cocoa platform plugin. + + typedef bool (*TestContentBorderPositionFunction)(QWindow *, int); + return (reinterpret_cast<TestContentBorderPositionFunction>(function))(window, windowY); +} + + +static void drawTabCloseButton(QPainter *p, bool hover, bool selected, bool pressed, bool documentMode) +{ + p->setRenderHints(QPainter::Antialiasing); + QRect rect(0, 0, closeButtonSize, closeButtonSize); + const int width = rect.width(); + const int height = rect.height(); + + if (hover) { + // draw background circle + QColor background; + if (selected) { + if (documentMode) + background = pressed ? tabBarCloseButtonBackgroundSelectedPressed : tabBarCloseButtonBackgroundSelectedHovered; + else + background = QColor(255, 255, 255, pressed ? 150 : 100); // Translucent white + } else { + background = pressed ? tabBarCloseButtonBackgroundPressed : tabBarCloseButtonBackgroundHovered; + if (!documentMode) + background = background.lighter(pressed ? 135 : 140); // Lighter tab background, lighter color + } + + p->setPen(Qt::transparent); + p->setBrush(background); + p->drawRoundedRect(rect, closeButtonCornerRadius, closeButtonCornerRadius); + } + + // draw cross + const int margin = 3; + QPen crossPen; + crossPen.setColor(selected ? (documentMode ? tabBarCloseButtonCrossSelected : Qt::white) : tabBarCloseButtonCross); + crossPen.setWidthF(1.1); + crossPen.setCapStyle(Qt::FlatCap); + p->setPen(crossPen); + p->drawLine(margin, margin, width - margin, height - margin); + p->drawLine(margin, height - margin, width - margin, margin); +} + +QRect rotateTabPainter(QPainter *p, QStyleOptionTab::Shape shape, QRect tabRect) +{ + const auto tabDirection = QMacStylePrivate::tabDirection(shape); + if (QMacStylePrivate::verticalTabs(tabDirection)) { + int newX, newY, newRot; + if (tabDirection == QMacStylePrivate::East) { + newX = tabRect.width(); + newY = tabRect.y(); + newRot = 90; + } else { + newX = 0; + newY = tabRect.y() + tabRect.height(); + newRot = -90; + } + tabRect.setRect(0, 0, tabRect.height(), tabRect.width()); + QTransform transform; + transform.translate(newX, newY); + transform.rotate(newRot); + p->setTransform(transform, true); + } + return tabRect; +} + +void drawTabShape(QPainter *p, const QStyleOptionTab *tabOpt, bool isUnified, int tabOverlap) +{ + QRect rect = tabOpt->rect; + if (QMacStylePrivate::verticalTabs(QMacStylePrivate::tabDirection(tabOpt->shape))) + rect = rect.adjusted(-tabOverlap, 0, 0, 0); + else + rect = rect.adjusted(0, -tabOverlap, 0, 0); + + p->translate(rect.x(), rect.y()); + rect.moveLeft(0); + rect.moveTop(0); + const QRect tabRect = rotateTabPainter(p, tabOpt->shape, rect); + + const int width = tabRect.width(); + const int height = tabRect.height(); + const bool active = (tabOpt->state & QStyle::State_Active); + const bool selected = (tabOpt->state & QStyle::State_Selected); + + const QRect bodyRect(1, 2, width - 2, height - 3); + const QRect topLineRect(1, 0, width - 2, 1); + const QRect bottomLineRect(1, height - 1, width - 2, 1); + if (selected) { + // fill body + if (tabOpt->documentMode && isUnified) { + p->save(); + p->setCompositionMode(QPainter::CompositionMode_Source); + p->fillRect(tabRect, QColor(Qt::transparent)); + p->restore(); + } else if (active) { + p->fillRect(bodyRect, tabBarTabBackgroundActiveSelected()); + // top line + p->fillRect(topLineRect, tabBarTabLineSelected()); + } else { + p->fillRect(bodyRect, tabBarTabBackgroundSelected()); + } + } else { + // when the mouse is over non selected tabs they get a new color + const bool hover = (tabOpt->state & QStyle::State_MouseOver); + if (hover) { + // fill body + p->fillRect(bodyRect, tabBarTabBackgroundActiveHovered()); + // bottom line + p->fillRect(bottomLineRect, isDarkMode() ? QColor(Qt::black) : tabBarTabLineActiveHovered()); + } + } + + // separator lines between tabs + const QRect leftLineRect(0, 1, 1, height - 2); + const QRect rightLineRect(width - 1, 1, 1, height - 2); + const QColor separatorLineColor = active ? tabBarTabLineActive() : tabBarTabLine(); + p->fillRect(leftLineRect, separatorLineColor); + p->fillRect(rightLineRect, separatorLineColor); +} + +void drawTabBase(QPainter *p, const QStyleOptionTabBarBase *tbb) +{ + QRect r = tbb->rect; +// if (QMacStylePrivate::verticalTabs(QMacStylePrivate::tabDirection(tbb->shape))) +// r.setWidth(w->width()); +// else +// r.setHeight(w->height()); + + const QRect tabRect = rotateTabPainter(p, tbb->shape, r); + const int width = tabRect.width(); + const int height = tabRect.height(); + const bool active = (tbb->state & QStyle::State_Active); + + // fill body + const QRect bodyRect(0, 1, width, height - 1); + const QColor bodyColor = active ? tabBarTabBackgroundActive() : tabBarTabBackground(); + p->fillRect(bodyRect, bodyColor); + + // top line + const QRect topLineRect(0, 0, width, 1); + const QColor topLineColor = active ? tabBarTabLineActive() : tabBarTabLine(); + p->fillRect(topLineRect, topLineColor); + + // bottom line + const QRect bottomLineRect(0, height - 1, width, 1); + bool isDocument = false; +// if (const QTabBar *tabBar = qobject_cast<const QTabBar*>(w)) +// isDocument = tabBar->documentMode(); + const QColor bottomLineColor = isDocument && isDarkMode() ? QColor(Qt::black) : active ? tabBarTabLineActive() : tabBarTabLine(); + p->fillRect(bottomLineRect, bottomLineColor); +} + +static QStyleHelper::WidgetSizePolicy getControlSize(const QStyleOption *option) +{ + const auto wsp = QStyleHelper::widgetSizePolicy(option); + if (wsp == QStyleHelper::SizeDefault) + return QStyleHelper::SizeLarge; + + return wsp; +} + +static QString qt_mac_removeMnemonics(const QString &original) +{ + QString returnText(original.size(), QChar()); + int finalDest = 0; + int currPos = 0; + int l = original.length(); + while (l) { + if (original.at(currPos) == QLatin1Char('&')) { + ++currPos; + --l; + if (l == 0) + break; + } else if (original.at(currPos) == QLatin1Char('(') && l >= 4 && + original.at(currPos + 1) == QLatin1Char('&') && + original.at(currPos + 2) != QLatin1Char('&') && + original.at(currPos + 3) == QLatin1Char(')')) { + /* remove mnemonics its format is "\s*(&X)" */ + int n = 0; + while (finalDest > n && returnText.at(finalDest - n - 1).isSpace()) + ++n; + finalDest -= n; + currPos += 4; + l -= 4; + continue; + } + returnText[finalDest] = original.at(currPos); + ++currPos; + ++finalDest; + --l; + } + returnText.truncate(finalDest); + return returnText; +} + +static bool qt_macWindowMainWindow(const QWindow *window) +{ + if (window->handle()) { + if (NSWindow *nswindow = static_cast<NSWindow*>( + QGuiApplication::platformNativeInterface()-> + nativeResourceForWindow(QByteArrayLiteral("nswindow"), + const_cast<QWindow *>(window)))) { + return [nswindow isMainWindow]; + } + } + return false; +} + +#define LargeSmallMini(option, large, small, mini) \ + (option->state & QStyle::State_Small) ? small : ((option->state & QStyle::State_Mini) ? mini : large) + +/***************************************************************************** + QMacCGStyle globals + *****************************************************************************/ +const int macItemFrame = 2; // menu item frame width +const int macItemHMargin = 3; // menu item hor text margin +const int macRightBorder = 12; // right border on mac + +/***************************************************************************** + QMacCGStyle utility functions + *****************************************************************************/ + +enum QAquaMetric { + // Prepend kThemeMetric to get the HIToolBox constant. + // Represents the values already used in QMacStyle. + CheckBoxHeight = 0, + CheckBoxWidth, + EditTextFrameOutset, + FocusRectOutset, + HSliderHeight, + HSliderTickHeight, + LargeProgressBarThickness, + ListHeaderHeight, + MenuSeparatorHeight, // GetThemeMenuSeparatorHeight + MiniCheckBoxHeight, + MiniCheckBoxWidth, + MiniHSliderHeight, + MiniHSliderTickHeight, + MiniPopupButtonHeight, + MiniPushButtonHeight, + MiniRadioButtonHeight, + MiniRadioButtonWidth, + MiniVSliderTickWidth, + MiniVSliderWidth, + NormalProgressBarThickness, + PopupButtonHeight, + ProgressBarShadowOutset, + PushButtonHeight, + RadioButtonHeight, + RadioButtonWidth, + SeparatorSize, + SmallCheckBoxHeight, + SmallCheckBoxWidth, + SmallHSliderHeight, + SmallHSliderTickHeight, + SmallPopupButtonHeight, + SmallProgressBarShadowOutset, + SmallPushButtonHeight, + SmallRadioButtonHeight, + SmallRadioButtonWidth, + SmallVSliderTickWidth, + SmallVSliderWidth, + VSliderTickWidth, + VSliderWidth +}; + +static const int qt_mac_aqua_metrics[] = { + // Values as of macOS 10.12.4 and Xcode 8.3.1 + 18 /* CheckBoxHeight */, + 18 /* CheckBoxWidth */, + 1 /* EditTextFrameOutset */, + 4 /* FocusRectOutset */, + 22 /* HSliderHeight */, + 5 /* HSliderTickHeight */, + 16 /* LargeProgressBarThickness */, + 17 /* ListHeaderHeight */, + 12 /* MenuSeparatorHeight, aka GetThemeMenuSeparatorHeight */, + 11 /* MiniCheckBoxHeight */, + 11 /* MiniCheckBoxWidth */, + 12 /* MiniHSliderHeight */, + 4 /* MiniHSliderTickHeight */, + 15 /* MiniPopupButtonHeight */, + 16 /* MiniPushButtonHeight */, + 11 /* MiniRadioButtonHeight */, + 11 /* MiniRadioButtonWidth */, + 4 /* MiniVSliderTickWidth */, + 12 /* MiniVSliderWidth */, + 12 /* NormalProgressBarThickness */, + 20 /* PopupButtonHeight */, + 4 /* ProgressBarShadowOutset */, + 20 /* PushButtonHeight */, + 18 /* RadioButtonHeight */, + 18 /* RadioButtonWidth */, + 1 /* SeparatorSize */, + 16 /* SmallCheckBoxHeight */, + 14 /* SmallCheckBoxWidth */, + 15 /* SmallHSliderHeight */, + 4 /* SmallHSliderTickHeight */, + 17 /* SmallPopupButtonHeight */, + 2 /* SmallProgressBarShadowOutset */, + 17 /* SmallPushButtonHeight */, + 15 /* SmallRadioButtonHeight */, + 15 /* SmallRadioButtonWidth */, + 4 /* SmallVSliderTickWidth */, + 15 /* SmallVSliderWidth */, + 5 /* VSliderTickWidth */, + 22 /* VSliderWidth */ +}; + +static inline int qt_mac_aqua_get_metric(QAquaMetric m) +{ + return qt_mac_aqua_metrics[m]; +} + +static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QStyleOption *opt, + QSize szHint, QStyleHelper::WidgetSizePolicy sz) +{ + QSize ret(-1, -1); + if (sz != QStyleHelper::SizeSmall && sz != QStyleHelper::SizeLarge && sz != QStyleHelper::SizeMini) { + qDebug("Not sure how to return this..."); + return ret; + } +// if ((widget && widget->testAttribute(Qt::WA_SetFont)) || !QApplication::desktopSettingsAware()) { +// // If you're using a custom font and it's bigger than the default font, +// // then no constraints for you. If you are smaller, we can try to help you out +// QFont font = qt_app_fonts_hash()->value(widget->metaObject()->className(), QFont()); +// if (widget->font().pointSize() > font.pointSize()) +// return ret; +// } + + // TODO: investigate how this function is used. 'ct' can/should be + // filled out correctly in the styleoption already from the styleitem? + Q_ASSERT(ct != QStyle::CT_CustomBase); +// if (ct == QStyle::CT_CustomBase && widget) { +//#if QT_CONFIG(pushbutton) +// if (qobject_cast<const QPushButton *>(widg)) +// ct = QStyle::CT_PushButton; +//#endif +// else if (qobject_cast<const QRadioButton *>(widget)) +// ct = QStyle::CT_RadioButton; +//#if QT_CONFIG(checkbox) +// else if (qobject_cast<const QCheckBox *>(widg)) +// ct = QStyle::CT_CheckBox; +//#endif +//#if QT_CONFIG(combobox) +// else if (qobject_cast<const QComboBox *>(widg)) +// ct = QStyle::CT_ComboBox; +//#endif +//#if QT_CONFIG(toolbutton) +// else if (qobject_cast<const QToolButton *>(widg)) +// ct = QStyle::CT_ToolButton; +//#endif +// else if (qobject_cast<const QSlider *>(widget)) +// ct = QStyle::CT_Slider; +//#if QT_CONFIG(progressbar) +// else if (qobject_cast<const QProgressBar *>(widg)) +// ct = QStyle::CT_ProgressBar; +//#endif +//#if QT_CONFIG(lineedit) +// else if (qobject_cast<const QLineEdit *>(widg)) +// ct = QStyle::CT_LineEdit; +//#endif +//#if QT_CONFIG(itemviews) +// else if (qobject_cast<const QHeaderView *>(widg)) +// ct = QStyle::CT_HeaderSection; +//#endif +//#if QT_CONFIG(menubar) +// else if (qobject_cast<const QMenuBar *>(widg)) +// ct = QStyle::CT_MenuBar; +//#endif +//#if QT_CONFIG(sizegrip) +// else if (qobject_cast<const QSizeGrip *>(widg)) +// ct = QStyle::CT_SizeGrip; +//#endif +// else +// return ret; +// } + + switch (ct) { + case QStyle::CT_PushButton: { + const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt); + if (btn) { + QString buttonText = qt_mac_removeMnemonics(btn->text); + if (buttonText.contains(QLatin1Char('\n'))) + ret = QSize(-1, -1); + else if (sz == QStyleHelper::SizeLarge) + ret = QSize(-1, qt_mac_aqua_get_metric(PushButtonHeight)); + else if (sz == QStyleHelper::SizeSmall) + ret = QSize(-1, qt_mac_aqua_get_metric(SmallPushButtonHeight)); + else if (sz == QStyleHelper::SizeMini) + ret = QSize(-1, qt_mac_aqua_get_metric(MiniPushButtonHeight)); + + if (!btn->icon.isNull()){ + // If the button got an icon, and the icon is larger than the + // button, we can't decide on a default size + ret.setWidth(-1); + if (ret.height() < btn->iconSize.height()) + ret.setHeight(-1); + } + else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){ + // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels. + // However, this doesn't work for German, therefore only do it for English, + // I suppose it would be better to do some sort of lookups for languages + // that like to have really long words. + // FIXME This is not exactly true. Out of context, OK buttons have their + // implicit size calculated the same way as any other button. Inside a + // QDialogButtonBox, their size should be calculated such that the action + // or accept button (i.e., rightmost) and cancel button have the same width. + ret.setWidth(69); + } + } else { + // The only sensible thing to do is to return whatever the style suggests... + if (sz == QStyleHelper::SizeLarge) + ret = QSize(-1, qt_mac_aqua_get_metric(PushButtonHeight)); + else if (sz == QStyleHelper::SizeSmall) + ret = QSize(-1, qt_mac_aqua_get_metric(SmallPushButtonHeight)); + else if (sz == QStyleHelper::SizeMini) + ret = QSize(-1, qt_mac_aqua_get_metric(MiniPushButtonHeight)); + else + // Since there's no default size we return the large size... + ret = QSize(-1, qt_mac_aqua_get_metric(PushButtonHeight)); + } + break; } + case QStyle::CT_SizeGrip: + // Not HIG kosher: mimic what we were doing earlier until we support 4-edge resizing in MDI subwindows + if (sz == QStyleHelper::SizeLarge || sz == QStyleHelper::SizeSmall) { + int s = sz == QStyleHelper::SizeSmall ? 16 : 22; // large: pixel measured from HITheme, small: from my hat + int width = 0; +//#if QT_CONFIG(mdiarea) +// if (widg && qobject_cast<QMdiSubWindow *>(widg->parentWidget())) +// width = s; +//#endif + ret = QSize(width, s); + } + break; + case QStyle::CT_ComboBox: + switch (sz) { + case QStyleHelper::SizeLarge: + ret = QSize(-1, qt_mac_aqua_get_metric(PopupButtonHeight)); + break; + case QStyleHelper::SizeSmall: + ret = QSize(-1, qt_mac_aqua_get_metric(SmallPopupButtonHeight)); + break; + case QStyleHelper::SizeMini: + ret = QSize(-1, qt_mac_aqua_get_metric(MiniPopupButtonHeight)); + break; + default: + break; + } + break; + case QStyle::CT_ToolButton: + if (sz == QStyleHelper::SizeSmall) { + int width = 0, height = 0; + if (szHint == QSize(-1, -1)) { //just 'guess'.. +//#if QT_CONFIG(toolbutton) +// const QStyleOptionToolButton *bt = qstyleoption_cast<const QStyleOptionToolButton *>(opt); +// // If this conversion fails then the widget was not what it claimed to be. +// if(bt) { +// if (!bt->icon.isNull()) { +// QSize iconSize = bt->iconSize; +// QSize pmSize = bt->icon.actualSize(QSize(32, 32), QIcon::Normal); +// width = qMax(width, qMax(iconSize.width(), pmSize.width())); +// height = qMax(height, qMax(iconSize.height(), pmSize.height())); +// } +// if (!bt->text.isNull() && bt->toolButtonStyle != Qt::ToolButtonIconOnly) { +// int text_width = bt->fontMetrics.horizontalAdvance(bt->text), +// text_height = bt->fontMetrics.height(); +// if (bt->toolButtonStyle == Qt::ToolButtonTextUnderIcon) { +// width = qMax(width, text_width); +// height += text_height; +// } else { +// width += text_width; +// width = qMax(height, text_height); +// } +// } +// } else +//#endif + { + // Let's return the size hint... + width = szHint.width(); + height = szHint.height(); + } + } else { + width = szHint.width(); + height = szHint.height(); + } + width = qMax(20, width + 5); //border + height = qMax(20, height + 5); //border + ret = QSize(width, height); + } + break; + case QStyle::CT_Slider: { + int w = -1; + const QStyleOptionSlider *sld = qstyleoption_cast<const QStyleOptionSlider *>(opt); + // If this conversion fails then the widget was not what it claimed to be. + if(sld) { + if (sz == QStyleHelper::SizeLarge) { + if (sld->orientation == Qt::Horizontal) { + w = qt_mac_aqua_get_metric(HSliderHeight); + if (sld->tickPosition != QStyleOptionSlider::NoTicks) + w += qt_mac_aqua_get_metric(HSliderTickHeight); + } else { + w = qt_mac_aqua_get_metric(VSliderWidth); + if (sld->tickPosition != QStyleOptionSlider::NoTicks) + w += qt_mac_aqua_get_metric(VSliderTickWidth); + } + } else if (sz == QStyleHelper::SizeSmall) { + if (sld->orientation == Qt::Horizontal) { + w = qt_mac_aqua_get_metric(SmallHSliderHeight); + if (sld->tickPosition != QStyleOptionSlider::NoTicks) + w += qt_mac_aqua_get_metric(SmallHSliderTickHeight); + } else { + w = qt_mac_aqua_get_metric(SmallVSliderWidth); + if (sld->tickPosition != QStyleOptionSlider::NoTicks) + w += qt_mac_aqua_get_metric(SmallVSliderTickWidth); + } + } else if (sz == QStyleHelper::SizeMini) { + if (sld->orientation == Qt::Horizontal) { + w = qt_mac_aqua_get_metric(MiniHSliderHeight); + if (sld->tickPosition != QStyleOptionSlider::NoTicks) + w += qt_mac_aqua_get_metric(MiniHSliderTickHeight); + } else { + w = qt_mac_aqua_get_metric(MiniVSliderWidth); + if (sld->tickPosition != QStyleOptionSlider::NoTicks) + w += qt_mac_aqua_get_metric(MiniVSliderTickWidth); + } + } + } else { + // This is tricky, we were requested to find a size for a slider which is not + // a slider. We don't know if this is vertical or horizontal or if we need to + // have tick marks or not. + // For this case we will return an horizontal slider without tick marks. + w = qt_mac_aqua_get_metric(HSliderHeight); + w += qt_mac_aqua_get_metric(HSliderTickHeight); + } + if (sld->orientation == Qt::Horizontal) + ret.setHeight(w); + else + ret.setWidth(w); + break; + } +//#if QT_CONFIG(progressbar) +// case QStyle::CT_ProgressBar: { +// int finalValue = -1; +// Qt::Orientation orient = Qt::Horizontal; +// if (const QProgressBar *pb = qobject_cast<const QProgressBar *>(widg)) +// orient = pb->orientation(); + +// if (sz == QStyleHelper::SizeLarge) +// finalValue = qt_mac_aqua_get_metric(LargeProgressBarThickness) +// + qt_mac_aqua_get_metric(ProgressBarShadowOutset); +// else +// finalValue = qt_mac_aqua_get_metric(NormalProgressBarThickness) +// + qt_mac_aqua_get_metric(SmallProgressBarShadowOutset); +// if (orient == Qt::Horizontal) +// ret.setHeight(finalValue); +// else +// ret.setWidth(finalValue); +// break; +// } +//#endif +//#if QT_CONFIG(combobox) +// case QStyle::CT_LineEdit: +// if (!widg || !qobject_cast<QComboBox *>(widg->parentWidget())) { +// //should I take into account the font dimentions of the lineedit? -Sam +// if (sz == QStyleHelper::SizeLarge) +// ret = QSize(-1, 21); +// else +// ret = QSize(-1, 19); +// } +// break; +//#endif + case QStyle::CT_HeaderSection: +//#if QT_CONFIG(treeview) +// if (isTreeView(widg)) +// ret = QSize(-1, qt_mac_aqua_get_metric(ListHeaderHeight)); +//#endif + break; + case QStyle::CT_MenuBar: + if (sz == QStyleHelper::SizeLarge) { + ret = QSize(-1, [[NSApp mainMenu] menuBarHeight]); + // In the qt_mac_set_native_menubar(false) case, + // we come it here with a zero-height main menu, + // preventing the in-window menu from displaying. + // Use 22 pixels for the height, by observation. + if (ret.height() <= 0) + ret.setHeight(22); + } + break; + default: + break; + } + return ret; +} + +#if defined(QMAC_QAQUASTYLE_SIZE_CONSTRAIN) || defined(DEBUG_SIZE_CONSTRAINT) +static QStyleHelper::WidgetSizePolicy qt_aqua_guess_size( + const QSize &large, + const QSize &small, + const QSize &mini) +{ + if (large == QSize(-1, -1)) { + if (small != QSize(-1, -1)) + return QStyleHelper::SizeSmall; + if (mini != QSize(-1, -1)) + return QStyleHelper::SizeMini; + return QStyleHelper::SizeDefault; + } else if (small == QSize(-1, -1)) { + if (mini != QSize(-1, -1)) + return QStyleHelper::SizeMini; + return QStyleHelper::SizeLarge; + } else if (mini == QSize(-1, -1)) { + return QStyleHelper::SizeLarge; + } + + if (qEnvironmentVariableIsSet("QWIDGET_ALL_SMALL")) + return QStyleHelper::SizeSmall; + else if (qEnvironmentVariableIsSet("QWIDGET_ALL_MINI")) + return QStyleHelper::SizeMini; + + return QStyleHelper::SizeLarge; +} +#endif + +QPainterPath QMacStylePrivate::windowPanelPath(const QRectF &r) const +{ + static const qreal CornerPointOffset = 5.5; + static const qreal CornerControlOffset = 2.1; + + QPainterPath path; + // Top-left corner + path.moveTo(r.left(), r.top() + CornerPointOffset); + path.cubicTo(r.left(), r.top() + CornerControlOffset, + r.left() + CornerControlOffset, r.top(), + r.left() + CornerPointOffset, r.top()); + // Top-right corner + path.lineTo(r.right() - CornerPointOffset, r.top()); + path.cubicTo(r.right() - CornerControlOffset, r.top(), + r.right(), r.top() + CornerControlOffset, + r.right(), r.top() + CornerPointOffset); + // Bottom-right corner + path.lineTo(r.right(), r.bottom() - CornerPointOffset); + path.cubicTo(r.right(), r.bottom() - CornerControlOffset, + r.right() - CornerControlOffset, r.bottom(), + r.right() - CornerPointOffset, r.bottom()); + // Bottom-right corner + path.lineTo(r.left() + CornerPointOffset, r.bottom()); + path.cubicTo(r.left() + CornerControlOffset, r.bottom(), + r.left(), r.bottom() - CornerControlOffset, + r.left(), r.bottom() - CornerPointOffset); + path.lineTo(r.left(), r.top() + CornerPointOffset); + + return path; +} + +QMacStylePrivate::CocoaControlType QMacStylePrivate::windowButtonCocoaControl(QStyle::SubControl sc) const +{ + struct WindowButtons { + QStyle::SubControl sc; + QMacStylePrivate::CocoaControlType ct; + }; + + static const WindowButtons buttons[] = { + { QStyle::SC_TitleBarCloseButton, QMacStylePrivate::Button_WindowClose }, + { QStyle::SC_TitleBarMinButton, QMacStylePrivate::Button_WindowMiniaturize }, + { QStyle::SC_TitleBarMaxButton, QMacStylePrivate::Button_WindowZoom } + }; + + for (const auto &wb : buttons) + if (wb.sc == sc) + return wb.ct; + + return NoControl; +} + + +void QMacStylePrivate::tabLayout(const QStyleOptionTab *opt, QRect *textRect, QRect *iconRect) const +{ + Q_ASSERT(textRect); + Q_ASSERT(iconRect); + QRect tr = opt->rect; + const bool verticalTabs = opt->shape == QStyleOptionTab::RoundedEast + || opt->shape == QStyleOptionTab::RoundedWest + || opt->shape == QStyleOptionTab::TriangularEast + || opt->shape == QStyleOptionTab::TriangularWest; + if (verticalTabs) + tr.setRect(0, 0, tr.height(), tr.width()); // 0, 0 as we will have a translate transform + + int verticalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftVertical, opt); + int horizontalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, opt); + const int hpadding = 4; + const int vpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabVSpace, opt) / 2; + if (opt->shape == QStyleOptionTab::RoundedSouth || opt->shape == QStyleOptionTab::TriangularSouth) + verticalShift = -verticalShift; + tr.adjust(hpadding, verticalShift - vpadding, horizontalShift - hpadding, vpadding); + + // left widget + if (!opt->leftButtonSize.isEmpty()) { + const int buttonSize = verticalTabs ? opt->leftButtonSize.height() : opt->leftButtonSize.width(); + tr.setLeft(tr.left() + 4 + buttonSize); + // make text aligned to center + if (opt->rightButtonSize.isEmpty()) + tr.setRight(tr.right() - 4 - buttonSize); + } + // right widget + if (!opt->rightButtonSize.isEmpty()) { + const int buttonSize = verticalTabs ? opt->rightButtonSize.height() : opt->rightButtonSize.width(); + tr.setRight(tr.right() - 4 - buttonSize); + // make text aligned to center + if (opt->leftButtonSize.isEmpty()) + tr.setLeft(tr.left() + 4 + buttonSize); + } + + // icon + if (!opt->icon.isNull()) { + QSize iconSize = opt->iconSize; + if (!iconSize.isValid()) { + int iconExtent = proxyStyle->pixelMetric(QStyle::PM_SmallIconSize); + iconSize = QSize(iconExtent, iconExtent); + } + QSize tabIconSize = opt->icon.actualSize(iconSize, + (opt->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled, + (opt->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off); + // High-dpi icons do not need adjustment; make sure tabIconSize is not larger than iconSize + tabIconSize = QSize(qMin(tabIconSize.width(), iconSize.width()), qMin(tabIconSize.height(), iconSize.height())); + + const int stylePadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabHSpace, opt) / 2 - hpadding; + + if (opt->documentMode) { + // documents show the icon as part of the the text + const int textWidth = + opt->fontMetrics.boundingRect(tr, Qt::AlignCenter | Qt::TextShowMnemonic, opt->text).width(); + *iconRect = QRect(tr.center().x() - textWidth / 2 - stylePadding - tabIconSize.width(), + tr.center().y() - tabIconSize.height() / 2, + tabIconSize.width(), tabIconSize.height()); + } else { + *iconRect = QRect(tr.left() + stylePadding, tr.center().y() - tabIconSize.height() / 2, + tabIconSize.width(), tabIconSize.height()); + } + if (!verticalTabs) + *iconRect = proxyStyle->visualRect(opt->direction, opt->rect, *iconRect); + + tr.setLeft(tr.left() + stylePadding + tabIconSize.width() + 4); + tr.setRight(tr.right() - stylePadding - tabIconSize.width() - 4); + } + + if (!verticalTabs) + tr = proxyStyle->visualRect(opt->direction, opt->rect, tr); + + *textRect = tr; +} + +QMacStylePrivate::Direction QMacStylePrivate::tabDirection(QStyleOptionTab::Shape shape) +{ + switch (shape) { + case QStyleOptionTab::RoundedSouth: + case QStyleOptionTab::TriangularSouth: + return South; + case QStyleOptionTab::RoundedNorth: + case QStyleOptionTab::TriangularNorth: + return North; + case QStyleOptionTab::RoundedWest: + case QStyleOptionTab::TriangularWest: + return West; + case QStyleOptionTab::RoundedEast: + case QStyleOptionTab::TriangularEast: + return East; + } +} + +bool QMacStylePrivate::verticalTabs(QMacStylePrivate::Direction direction) +{ + return (direction == QMacStylePrivate::East + || direction == QMacStylePrivate::West); +} + +QStyleHelper::WidgetSizePolicy QMacStylePrivate::effectiveAquaSizeConstrain(const QStyleOption *option, + QStyle::ContentsType ct, + QSize szHint, QSize *insz) const +{ + QStyleHelper::WidgetSizePolicy sz = aquaSizeConstrain(option, ct, szHint, insz); + if (sz == QStyleHelper::SizeDefault) + return QStyleHelper::SizeLarge; + return sz; +} + +QStyleHelper::WidgetSizePolicy QMacStylePrivate::aquaSizeConstrain(const QStyleOption *option, + QStyle::ContentsType ct, QSize szHint, QSize *insz) const +{ + if (!option) + return QStyleHelper::SizeLarge; + + if (option->state & QStyle::State_Small) + return QStyleHelper::SizeSmall; + if (option->state & QStyle::State_Mini) + return QStyleHelper::SizeMini; + + return QStyleHelper::SizeLarge; + +} + +uint qHash(const QMacStylePrivate::CocoaControl &cw, uint seed = 0) +{ + return ((cw.type << 2) | cw.size) ^ seed; +} + +QMacStylePrivate::CocoaControl::CocoaControl() + : type(NoControl), size(QStyleHelper::SizeDefault) +{ +} + +QMacStylePrivate::CocoaControl::CocoaControl(CocoaControlType t, QStyleHelper::WidgetSizePolicy s) + : type(t), size(s) +{ +} + +bool QMacStylePrivate::CocoaControl::operator==(const CocoaControl &other) const +{ + return other.type == type && other.size == size; +} + +QSizeF QMacStylePrivate::CocoaControl::defaultFrameSize() const +{ + // We need this because things like NSView.alignmentRectInsets + // or -[NSCell titleRectForBounds:] won't work unless the control + // has a reasonable frame set. IOW, it's a chicken and egg problem. + // These values are as observed in Xcode 9's Interface Builder. + + if (type == Button_PushButton) + return QSizeF(-1, pushButtonDefaultHeight[size]); + + if (type == Button_PopupButton + || type == Button_PullDown) + return QSizeF(-1, popupButtonDefaultHeight[size]); + + if (type == ComboBox) + return QSizeF(-1, comboBoxDefaultHeight[size]); + + return QSizeF(); +} + +QRectF QMacStylePrivate::CocoaControl::adjustedControlFrame(const QRectF &rect) const +{ + QRectF frameRect; + const auto frameSize = defaultFrameSize(); + if (type == QMacStylePrivate::Button_SquareButton) { + frameRect = rect.adjusted(3, 1, -3, -1) + .adjusted(focusRingWidth, focusRingWidth, -focusRingWidth, -focusRingWidth); + } else if (type == QMacStylePrivate::Button_PushButton) { + // Start from the style option's top-left corner. + frameRect = QRectF(rect.topLeft(), + QSizeF(rect.width(), frameSize.height())); + if (size == QStyleHelper::SizeSmall) + frameRect = frameRect.translated(0, 1.5); + else if (size == QStyleHelper::SizeMini) + frameRect = frameRect.adjusted(0, 0, -8, 0).translated(4, 4); + } else { + // Center in the style option's rect. + frameRect = QRectF(QPointF(0, (rect.height() - frameSize.height()) / 2.0), + QSizeF(rect.width(), frameSize.height())); + frameRect = frameRect.translated(rect.topLeft()); + if (type == QMacStylePrivate::Button_PullDown || type == QMacStylePrivate::Button_PopupButton) { + if (size == QStyleHelper::SizeLarge) + frameRect = frameRect.adjusted(0, 0, -6, 0).translated(3, 0); + else if (size == QStyleHelper::SizeSmall) + frameRect = frameRect.adjusted(0, 0, -4, 0).translated(2, 1); + else if (size == QStyleHelper::SizeMini) + frameRect = frameRect.adjusted(0, 0, -9, 0).translated(5, 0); + } else if (type == QMacStylePrivate::ComboBox) { + frameRect = frameRect.adjusted(0, 0, -6, 0).translated(4, 0); + } + } + + return frameRect; +} + +QMarginsF QMacStylePrivate::CocoaControl::titleMargins() const +{ + if (type == QMacStylePrivate::Button_PushButton) { + if (size == QStyleHelper::SizeLarge) + return QMarginsF(12, 5, 12, 9); + if (size == QStyleHelper::SizeSmall) + return QMarginsF(12, 4, 12, 9); + if (size == QStyleHelper::SizeMini) + return QMarginsF(10, 1, 10, 2); + } + + if (type == QMacStylePrivate::Button_PullDown) { + if (size == QStyleHelper::SizeLarge) + return QMarginsF(7.5, 2.5, 22.5, 5.5); + if (size == QStyleHelper::SizeSmall) + return QMarginsF(7.5, 2, 20.5, 4); + if (size == QStyleHelper::SizeMini) + return QMarginsF(4.5, 0, 16.5, 2); + } + + if (type == QMacStylePrivate::Button_SquareButton) + return QMarginsF(6, 1, 6, 2); + + return QMarginsF(); +} + +bool QMacStylePrivate::CocoaControl::getCocoaButtonTypeAndBezelStyle(NSButtonType *buttonType, NSBezelStyle *bezelStyle) const +{ + switch (type) { + case Button_CheckBox: + *buttonType = NSSwitchButton; + *bezelStyle = NSRegularSquareBezelStyle; + break; + case Button_Disclosure: + *buttonType = NSOnOffButton; + *bezelStyle = NSDisclosureBezelStyle; + break; + case Button_RadioButton: + *buttonType = NSRadioButton; + *bezelStyle = NSRegularSquareBezelStyle; + break; + case Button_SquareButton: + *buttonType = NSPushOnPushOffButton; + *bezelStyle = NSShadowlessSquareBezelStyle; + break; + case Button_PushButton: + *buttonType = NSPushOnPushOffButton; + *bezelStyle = NSRoundedBezelStyle; + break; + default: + return false; + } + + return true; +} + +QMacStylePrivate::CocoaControlType cocoaControlType(const QStyleOption *opt) +{ + if (const auto *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + const bool hasMenu = btn->features & QStyleOptionButton::HasMenu; + // When the contents won't fit in a large sized button, + // and WA_MacNormalSize is not set, make the button square. + // Threshold used to be at 34, not 32. + const auto maxNonSquareHeight = pushButtonDefaultHeight[QStyleHelper::SizeLarge]; + const bool isSquare = (btn->features & QStyleOptionButton::Flat) + || (btn->rect.height() > maxNonSquareHeight); +// && !(w && w->testAttribute(Qt::WA_MacNormalSize))); + return (isSquare? QMacStylePrivate::Button_SquareButton : + hasMenu ? QMacStylePrivate::Button_PullDown : + QMacStylePrivate::Button_PushButton); + } + + if (const auto *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + if (combo->editable) + return QMacStylePrivate::ComboBox; + // TODO Me may support square, non-editable combo boxes, but not more than that + return QMacStylePrivate::Button_PopupButton; + } + + return QMacStylePrivate::NoControl; +} + +/** + Carbon draws comboboxes (and other views) outside the rect given as argument. Use this function to obtain + the corresponding inner rect for drawing the same combobox so that it stays inside the given outerBounds. +*/ +CGRect QMacStylePrivate::comboboxInnerBounds(const CGRect &outerBounds, const CocoaControl &cocoaWidget) +{ + CGRect innerBounds = outerBounds; + // Carbon draw parts of the view outside the rect. + // So make the rect a bit smaller to compensate + // (I wish HIThemeGetButtonBackgroundBounds worked) + if (cocoaWidget.type == Button_PopupButton) { + switch (cocoaWidget.size) { + case QStyleHelper::SizeSmall: + innerBounds.origin.x += 3; + innerBounds.origin.y += 3; + innerBounds.size.width -= 6; + innerBounds.size.height -= 7; + break; + case QStyleHelper::SizeMini: + innerBounds.origin.x += 2; + innerBounds.origin.y += 2; + innerBounds.size.width -= 5; + innerBounds.size.height -= 6; + break; + case QStyleHelper::SizeLarge: + case QStyleHelper::SizeDefault: + innerBounds.origin.x += 2; + innerBounds.origin.y += 2; + innerBounds.size.width -= 5; + innerBounds.size.height -= 6; + } + } else if (cocoaWidget.type == ComboBox) { + switch (cocoaWidget.size) { + case QStyleHelper::SizeSmall: + innerBounds.origin.x += 3; + innerBounds.origin.y += 3; + innerBounds.size.width -= 7; + innerBounds.size.height -= 8; + break; + case QStyleHelper::SizeMini: + innerBounds.origin.x += 3; + innerBounds.origin.y += 3; + innerBounds.size.width -= 4; + innerBounds.size.height -= 8; + break; + case QStyleHelper::SizeLarge: + case QStyleHelper::SizeDefault: + innerBounds.origin.x += 3; + innerBounds.origin.y += 2; + innerBounds.size.width -= 6; + innerBounds.size.height -= 8; + } + } + + return innerBounds; +} + +/** + Inside a combobox Qt places a line edit widget. The size of this widget should depend on the kind + of combobox we choose to draw. This function calculates and returns this size. +*/ +QRectF QMacStylePrivate::comboboxEditBounds(const QRectF &outerBounds, const CocoaControl &cw) +{ + QRectF ret = outerBounds; + if (cw.type == ComboBox) { + switch (cw.size) { + case QStyleHelper::SizeLarge: + ret = ret.adjusted(0, 0, -25, 0).translated(2, 4.5); + ret.setHeight(16); + break; + case QStyleHelper::SizeSmall: + ret = ret.adjusted(0, 0, -22, 0).translated(2, 3); + ret.setHeight(14); + break; + case QStyleHelper::SizeMini: + ret = ret.adjusted(0, 0, -19, 0).translated(2, 2.5); + ret.setHeight(10.5); + break; + default: + break; + } + } else if (cw.type == Button_PopupButton) { + switch (cw.size) { + case QStyleHelper::SizeLarge: + ret.adjust(10, 1, -23, -4); + break; + case QStyleHelper::SizeSmall: + ret.adjust(10, 4, -20, -3); + break; + case QStyleHelper::SizeMini: + ret.adjust(9, 0, -19, 0); + ret.setHeight(13); + break; + default: + break; + } + } + return ret; +} + +QMacStylePrivate::QMacStylePrivate() + : backingStoreNSView(nil) +{ + if (auto *ssf = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::SmallFont)) + smallSystemFont = *ssf; + if (auto *msf = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::MiniFont)) + miniSystemFont = *msf; +} + +QMacStylePrivate::~QMacStylePrivate() +{ + QMacAutoReleasePool pool; + for (NSView *b : cocoaControls) + [b release]; + for (NSCell *cell : cocoaCells) + [cell release]; +} + +NSView *QMacStylePrivate::cocoaControl(CocoaControl cocoaControl) const +{ + if (cocoaControl.type == QMacStylePrivate::NoControl + || cocoaControl.size == QStyleHelper::SizeDefault) + return nil; + + if (cocoaControl.type == Box) { + if (__builtin_available(macOS 10.14, *)) { + if (qt_mac_applicationIsInDarkMode()) { + // See render code in drawPrimitive(PE_FrameTabWidget) + cocoaControl.type = Box_Dark; + } + } + } + + NSView *bv = cocoaControls.value(cocoaControl, nil); + if (!bv) { + switch (cocoaControl.type) { + case Box: { + NSBox *box = [[NSBox alloc] init]; + bv = box; + box.title = @""; + box.titlePosition = NSNoTitle; + break; + } + case Box_Dark: + bv = [[QDarkNSBox alloc] init]; + break; + case Button_CheckBox: + case Button_Disclosure: + case Button_PushButton: + case Button_RadioButton: + case Button_SquareButton: { + NSButton *bc = [[NSButton alloc] init]; + bc.title = @""; + // See below for style and bezel setting. + bv = bc; + break; + } + case Button_PopupButton: + case Button_PullDown: { + NSPopUpButton *bc = [[NSPopUpButton alloc] init]; + bc.title = @""; + if (cocoaControl.type == Button_PullDown) + bc.pullsDown = YES; + bv = bc; + break; + } + case Button_WindowClose: + case Button_WindowMiniaturize: + case Button_WindowZoom: { + const NSWindowButton button = [=] { + switch (cocoaControl.type) { + case Button_WindowClose: + return NSWindowCloseButton; + case Button_WindowMiniaturize: + return NSWindowMiniaturizeButton; + case Button_WindowZoom: + return NSWindowZoomButton; + default: + break; + } + Q_UNREACHABLE(); + } (); + const auto styleMask = NSWindowStyleMaskTitled + | NSWindowStyleMaskClosable + | NSWindowStyleMaskMiniaturizable + | NSWindowStyleMaskResizable; + bv = [NSWindow standardWindowButton:button forStyleMask:styleMask]; + [bv retain]; + break; + } + case ComboBox: + bv = [[NSComboBox alloc] init]; + break; + case ProgressIndicator_Determinate: + bv = [[NSProgressIndicator alloc] init]; + break; + case ProgressIndicator_Indeterminate: + bv = [[QIndeterminateProgressIndicator alloc] init]; + break; + case Scroller_Horizontal: + bv = [[NSScroller alloc] initWithFrame:NSMakeRect(0, 0, 200, 20)]; + break; + case Scroller_Vertical: + // Cocoa sets the orientation from the view's frame + // at construction time, and it cannot be changed later. + bv = [[NSScroller alloc] initWithFrame:NSMakeRect(0, 0, 20, 200)]; + break; + case Slider_Horizontal: + bv = [[NSSlider alloc] initWithFrame:NSMakeRect(0, 0, 200, 20)]; + break; + case Slider_Vertical: + // Cocoa sets the orientation from the view's frame + // at construction time, and it cannot be changed later. + bv = [[NSSlider alloc] initWithFrame:NSMakeRect(0, 0, 20, 200)]; + break; + case SplitView_Horizontal: + bv = [[NSSplitView alloc] init]; + break; + case SplitView_Vertical: + bv = [[QVerticalSplitView alloc] init]; + break; + case TextField: + bv = [[NSTextField alloc] init]; + break; + default: + break; + } + + if ([bv isKindOfClass:[NSControl class]]) { + auto *ctrl = static_cast<NSControl *>(bv); + switch (cocoaControl.size) { + case QStyleHelper::SizeSmall: + ctrl.controlSize = NSControlSizeSmall; + break; + case QStyleHelper::SizeMini: + ctrl.controlSize = NSControlSizeMini; + break; + default: + break; + } + } else if (cocoaControl.type == ProgressIndicator_Determinate || + cocoaControl.type == ProgressIndicator_Indeterminate) { + auto *pi = static_cast<NSProgressIndicator *>(bv); + pi.indeterminate = (cocoaControl.type == ProgressIndicator_Indeterminate); + switch (cocoaControl.size) { + case QStyleHelper::SizeSmall: + pi.controlSize = NSControlSizeSmall; + break; + case QStyleHelper::SizeMini: + pi.controlSize = NSControlSizeMini; + break; + default: + break; + } + } + + cocoaControls.insert(cocoaControl, bv); + } + + NSButtonType buttonType; + NSBezelStyle bezelStyle; + if (cocoaControl.getCocoaButtonTypeAndBezelStyle(&buttonType, &bezelStyle)) { + // FIXME We need to reset the button's type and + // bezel style properties, even when cached. + auto *button = static_cast<NSButton *>(bv); + button.buttonType = buttonType; + button.bezelStyle = bezelStyle; + if (cocoaControl.type == Button_CheckBox) + button.allowsMixedState = YES; + } + + return bv; +} + +NSCell *QMacStylePrivate::cocoaCell(CocoaControl cocoaControl) const +{ + NSCell *cell = cocoaCells[cocoaControl]; + if (!cell) { + switch (cocoaControl.type) { + case Stepper: + cell = [[NSStepperCell alloc] init]; + break; + case Button_Disclosure: { + NSButtonCell *bc = [[NSButtonCell alloc] init]; + bc.buttonType = NSOnOffButton; + bc.bezelStyle = NSDisclosureBezelStyle; + cell = bc; + break; + } + default: + break; + } + + switch (cocoaControl.size) { + case QStyleHelper::SizeSmall: + cell.controlSize = NSControlSizeSmall; + break; + case QStyleHelper::SizeMini: + cell.controlSize = NSControlSizeMini; + break; + default: + break; + } + + cocoaCells.insert(cocoaControl, cell); + } + + return cell; +} + +void QMacStylePrivate::drawNSViewInRect(NSView *view, const QRectF &rect, QPainter *p, DrawRectBlock drawRectBlock) const +{ + QMacAutoReleasePool pool; + QMacCGContext ctx(p); + setupNSGraphicsContext(ctx, YES); + + // FIXME: The rect that we get in is relative to the widget that we're drawing + // style on behalf of, and doesn't take into account the offset of that widget + // to the widget that owns the backingstore, which we are placing the native + // view into below. This means most of the views are placed in the upper left + // corner of backingStoreNSView, which does not map to where the actual widget + // is, and which may cause problems such as triggering a setNeedsDisplay of the + // backingStoreNSView for the wrong rect. We work around this by making the view + // layer-backed, which prevents triggering display of the backingStoreNSView, but + // but there may be other issues lurking here due to the wrong position. QTBUG-68023 + view.wantsLayer = YES; + + // FIXME: We are also setting the frame of the incoming view a lot at the call + // sites of this function, making it unclear who's actually responsible for + // maintaining the size and position of the view. In theory the call sites + // should ensure the _size_ of the view is correct, and then let this code + // take care of _positioning_ the view at the right place inside backingStoreNSView. + // For now we pass on the rect as is, to prevent any regressions until this + // can be investigated properly. + view.frame = rect.toCGRect(); + + [backingStoreNSView addSubview:view]; + + // FIXME: Based on the code below, this method isn't drawing an NSView into + // a rect, it's drawing _part of the NSView_, defined by the incoming clip + // or dirty rect, into the current graphics context. We're doing some manual + // translations at the call sites that would indicate that this relationship + // is a bit fuzzy. + const CGRect dirtyRect = rect.toCGRect(); + + if (drawRectBlock) + drawRectBlock(ctx, dirtyRect); + else + [view drawRect:dirtyRect]; + + [view removeFromSuperviewWithoutNeedingDisplay]; + + restoreNSGraphicsContext(ctx); +} + +void QMacStylePrivate::resolveCurrentNSView(QWindow *window) const +{ + backingStoreNSView = window ? (NSView *)window->winId() : nil; +} + +QMacStyle::QMacStyle() + : QCommonStyle(*new QMacStylePrivate) +{ + QMacAutoReleasePool pool; + + static QMacNotificationObserver scrollbarStyleObserver(nil, + NSPreferredScrollerStyleDidChangeNotification, []() { + // Purge destroyed scroll bars + QMacStylePrivate::scrollBars.removeAll(QPointer<QObject>()); + + QEvent event(QEvent::StyleChange); + for (const auto &o : QMacStylePrivate::scrollBars) + QCoreApplication::sendEvent(o, &event); + }); + +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) + Q_D(QMacStyle); + // FIXME: Tie this logic into theme change, or even polish/unpolish + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) { + d->appearanceObserver = QMacKeyValueObserver(NSApp, @"effectiveAppearance", [this] { + Q_D(QMacStyle); + for (NSView *b : d->cocoaControls) + [b release]; + d->cocoaControls.clear(); + }); + } +#endif +} + +QMacStyle::~QMacStyle() +{ +} + +int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt) const +{ + Q_D(const QMacStyle); + const int controlSize = getControlSize(opt); + int ret = 0; + + switch (metric) { + case PM_TabCloseIndicatorWidth: + case PM_TabCloseIndicatorHeight: + ret = closeButtonSize; + break; + case PM_ToolBarIconSize: + ret = proxy()->pixelMetric(PM_LargeIconSize); + break; + case PM_FocusFrameVMargin: + case PM_FocusFrameHMargin: + ret = qt_mac_aqua_get_metric(FocusRectOutset); + break; + case PM_DialogButtonsSeparator: + ret = -5; + break; + case PM_DialogButtonsButtonHeight: { + QSize sz; + ret = d->aquaSizeConstrain(opt, QStyle::CT_PushButton, QSize(-1, -1), &sz); + if (sz == QSize(-1, -1)) + ret = 32; + else + ret = sz.height(); + break; } + case PM_DialogButtonsButtonWidth: { + QSize sz; + ret = d->aquaSizeConstrain(opt, QStyle::CT_PushButton, QSize(-1, -1), &sz); + if (sz == QSize(-1, -1)) + ret = 70; + else + ret = sz.width(); + break; } + + case PM_MenuBarHMargin: + ret = 8; + break; + + case PM_MenuBarVMargin: + ret = 0; + break; + + case PM_MenuBarPanelWidth: + ret = 0; + break; + + case PM_MenuButtonIndicator: + ret = toolButtonArrowSize; + break; + + case QStyle::PM_MenuDesktopFrameWidth: + ret = 5; + break; + + case PM_CheckBoxLabelSpacing: + case PM_RadioButtonLabelSpacing: + ret = [=] { + if (opt) { + if (opt->state & State_Mini) + return 4; + if (opt->state & State_Small) + return 3; + } + return 2; + } (); + break; + case PM_MenuScrollerHeight: + ret = 15; // I hate having magic numbers in here... + break; + case PM_DefaultFrameWidth: +//#if QT_CONFIG(mainwindow) +// if (widget && (widget->isWindow() || !widget->parentWidget() +// || (qobject_cast<const QMainWindow*>(widget->parentWidget()) +// && static_cast<QMainWindow *>(widget->parentWidget())->centralWidget() == widget)) +// && qobject_cast<const QAbstractScrollArea *>(widget)) +// ret = 0; +// else +//#endif + // The combo box popup has no frame. + if (qstyleoption_cast<const QStyleOptionComboBox *>(opt) != 0) + ret = 0; + else + ret = 1; + break; + case PM_MaximumDragDistance: + ret = -1; + break; + case PM_ScrollBarSliderMin: + ret = 24; + break; + case PM_SpinBoxFrameWidth: + ret = qt_mac_aqua_get_metric(EditTextFrameOutset); + break; + case PM_ButtonShiftHorizontal: + case PM_ButtonShiftVertical: + ret = 0; + break; + case PM_SliderLength: + ret = 17; + break; + // Returns the number of pixels to use for the business part of the + // slider (i.e., the non-tickmark portion). The remaining space is shared + // equally between the tickmark regions. + case PM_SliderControlThickness: + if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width(); + int ticks = sl->tickPosition; + int n = 0; + if (ticks & QStyleOptionSlider::TicksAbove) + ++n; + if (ticks & QStyleOptionSlider::TicksBelow) + ++n; + if (!n) { + ret = space; + break; + } + + int thick = 6; // Magic constant to get 5 + 16 + 5 + if (ticks != QStyleOptionSlider::TicksBothSides && ticks != QStyleOptionSlider::NoTicks) + thick += proxy()->pixelMetric(PM_SliderLength, sl) / 4; + + space -= thick; + if (space > 0) + thick += (space * 2) / (n + 2); + ret = thick; + } else { + ret = 0; + } + break; + case PM_SmallIconSize: + ret = int(QStyleHelper::dpiScaled(16., opt)); + break; + + case PM_LargeIconSize: + ret = int(QStyleHelper::dpiScaled(32., opt)); + break; + + case PM_IconViewIconSize: + ret = proxy()->pixelMetric(PM_LargeIconSize, opt); + break; + + case PM_ButtonDefaultIndicator: + ret = 0; + break; + case PM_TitleBarHeight: { + NSUInteger style = NSWindowStyleMaskTitled; +// if (widget && ((widget->windowFlags() & Qt::Tool) == Qt::Tool)) +// style |= NSWindowStyleMaskUtilityWindow; + ret = int([NSWindow frameRectForContentRect:NSZeroRect + styleMask:style].size.height); + break; } + case QStyle::PM_TabBarTabHSpace: + switch (d->aquaSizeConstrain(opt)) { + case QStyleHelper::SizeLarge: + ret = QCommonStyle::pixelMetric(metric, opt); + break; + case QStyleHelper::SizeSmall: + ret = 20; + break; + case QStyleHelper::SizeMini: + ret = 16; + break; + case QStyleHelper::SizeDefault: + const QStyleOptionTab *tb = qstyleoption_cast<const QStyleOptionTab *>(opt); + if (tb && tb->documentMode) + ret = 30; + else + ret = QCommonStyle::pixelMetric(metric, opt); + break; + } + break; + case PM_TabBarTabVSpace: + ret = 4; + break; + case PM_TabBarTabShiftHorizontal: + case PM_TabBarTabShiftVertical: + ret = 0; + break; + case PM_TabBarBaseHeight: + ret = 0; + break; + case PM_TabBarTabOverlap: + ret = 1; + break; + case PM_TabBarBaseOverlap: + switch (d->aquaSizeConstrain(opt)) { + case QStyleHelper::SizeDefault: + case QStyleHelper::SizeLarge: + ret = 11; + break; + case QStyleHelper::SizeSmall: + ret = 8; + break; + case QStyleHelper::SizeMini: + ret = 7; + break; + } + break; + case PM_ScrollBarExtent: { + const QStyleHelper::WidgetSizePolicy size = d->effectiveAquaSizeConstrain(opt); + ret = static_cast<int>([NSScroller + scrollerWidthForControlSize:static_cast<NSControlSize>(size) + scrollerStyle:[NSScroller preferredScrollerStyle]]); + break; } + case PM_IndicatorHeight: { + switch (d->aquaSizeConstrain(opt)) { + case QStyleHelper::SizeDefault: + case QStyleHelper::SizeLarge: + ret = qt_mac_aqua_get_metric(CheckBoxHeight); + break; + case QStyleHelper::SizeMini: + ret = qt_mac_aqua_get_metric(MiniCheckBoxHeight); + break; + case QStyleHelper::SizeSmall: + ret = qt_mac_aqua_get_metric(SmallCheckBoxHeight); + break; + } + break; } + case PM_IndicatorWidth: { + switch (d->aquaSizeConstrain(opt)) { + case QStyleHelper::SizeDefault: + case QStyleHelper::SizeLarge: + ret = qt_mac_aqua_get_metric(CheckBoxWidth); + break; + case QStyleHelper::SizeMini: + ret = qt_mac_aqua_get_metric(MiniCheckBoxWidth); + break; + case QStyleHelper::SizeSmall: + ret = qt_mac_aqua_get_metric(SmallCheckBoxWidth); + break; + } + ++ret; + break; } + case PM_ExclusiveIndicatorHeight: { + switch (d->aquaSizeConstrain(opt)) { + case QStyleHelper::SizeDefault: + case QStyleHelper::SizeLarge: + ret = qt_mac_aqua_get_metric(RadioButtonHeight); + break; + case QStyleHelper::SizeMini: + ret = qt_mac_aqua_get_metric(MiniRadioButtonHeight); + break; + case QStyleHelper::SizeSmall: + ret = qt_mac_aqua_get_metric(SmallRadioButtonHeight); + break; + } + break; } + case PM_ExclusiveIndicatorWidth: { + switch (d->aquaSizeConstrain(opt)) { + case QStyleHelper::SizeDefault: + case QStyleHelper::SizeLarge: + ret = qt_mac_aqua_get_metric(RadioButtonWidth); + break; + case QStyleHelper::SizeMini: + ret = qt_mac_aqua_get_metric(MiniRadioButtonWidth); + break; + case QStyleHelper::SizeSmall: + ret = qt_mac_aqua_get_metric(SmallRadioButtonWidth); + break; + } + ++ret; + break; } + case PM_MenuVMargin: + ret = 4; + break; + case PM_MenuPanelWidth: + ret = 0; + break; + case PM_ToolTipLabelFrameWidth: + ret = 0; + break; + case PM_SizeGripSize: { + QStyleHelper::WidgetSizePolicy aSize; +// if (widget && widget->window()->windowType() == Qt::Tool) +// aSize = QStyleHelper::SizeSmall; +// else + aSize = QStyleHelper::SizeLarge; + const QSize size = qt_aqua_get_known_size(CT_SizeGrip, opt, QSize(), aSize); + ret = size.width(); + break; } + case PM_MdiSubWindowFrameWidth: + ret = 1; + break; + case PM_DockWidgetFrameWidth: + ret = 0; + break; + case PM_DockWidgetTitleMargin: + ret = 0; + break; + case PM_DockWidgetSeparatorExtent: + ret = 1; + break; + case PM_ToolBarHandleExtent: + ret = 11; + break; + case PM_ToolBarItemMargin: + ret = 0; + break; + case PM_ToolBarItemSpacing: + ret = 4; + break; + case PM_SplitterWidth: + ret = 7; + break; + case PM_LayoutLeftMargin: + case PM_LayoutTopMargin: + case PM_LayoutRightMargin: + case PM_LayoutBottomMargin: + { + if (opt->state & State_Window) { + /* + AHIG would have (20, 8, 10) here but that makes + no sense. It would also have 14 for the top margin + but this contradicts both Builder and most + applications. + */ + return_SIZE(20, 10, 10); // AHIG + } else { + // hack to detect QTabWidget +// if (widget && widget->parentWidget() +// && widget->parentWidget()->sizePolicy().controlType() == QSizePolicy::TabWidget) { +// if (metric == PM_LayoutTopMargin) { +// /* +// Builder would have 14 (= 20 - 6) instead of 12, +// but that makes the tab look disproportionate. +// */ +// return_SIZE(12, 6, 6); // guess +// } else { +// return_SIZE(20 /* Builder */, 8 /* guess */, 8 /* guess */); +// } +// } else { + /* + Child margins are highly inconsistent in AHIG and Builder. + */ + return_SIZE(12, 8, 6); // guess +// } + } + } + case PM_LayoutHorizontalSpacing: + case PM_LayoutVerticalSpacing: + return -1; + case PM_MenuHMargin: + ret = 0; + break; + case PM_ToolBarExtensionExtent: + ret = 21; + break; + case PM_ToolBarFrameWidth: + ret = 1; + break; + case PM_ScrollView_ScrollBarOverlap: + ret = [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay ? + pixelMetric(PM_ScrollBarExtent, opt) : 0; + break; + case PM_PushButtonFocusFrameRadius: + ret = LargeSmallMini(opt, 8, 7, 5); + break; + case PM_CheckBoxFocusFrameRadius: + ret = LargeSmallMini(opt, 6, 5, 4); + break; + case PM_ComboBoxFocusFrameRadius: + ret = LargeSmallMini(opt, 8, 7, 4); + break; + case PM_RadioButtonFocusFrameRadius: + ret = 10; + break; + case PM_SliderFocusFrameRadius: + // QTBUG-93423: We currently need to skip drawing a focus ring around the handle, since + // the handle drawn by the UIKit is not centered inside the rect we get from calling + // [cell knobRectFlipped:slider.isFlipped]. So we choose to draw the focus as + // a rect instead until we have a better solution available. + ret = 0; + break; + case PM_DialFocusFrameRadius: + case PM_SpinBoxFocusFrameRadius: + case PM_TextAreaFocusFrameRadius: + case PM_TextFieldFocusFrameRadius: + ret = 3; + break; + default: + ret = QCommonStyle::pixelMetric(metric, opt); + break; + } + return ret; +} + +//QPalette QMacStyle::standardPalette() const +//{ +// auto platformTheme = QGuiApplicationPrivate::platformTheme(); +// auto styleNames = platformTheme->themeHint(QPlatformTheme::StyleNames); +// if (styleNames.toStringList().contains("macintosh")) +// return QPalette(); // Inherit everything from theme +// else +// return QStyle::standardPalette(); +//} + +int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, QStyleHintReturn *hret) const +{ + QMacAutoReleasePool pool; + + int ret = 0; + switch (sh) { + case SH_Slider_SnapToValue: + case SH_PrintDialog_RightAlignButtons: + case SH_FontDialog_SelectAssociatedText: + case SH_MenuBar_MouseTracking: + case SH_Menu_MouseTracking: + case SH_ComboBox_ListMouseTracking: + case SH_MainWindow_SpaceBelowMenuBar: + case SH_ItemView_ChangeHighlightOnFocus: + ret = 1; + break; + case SH_ToolBox_SelectedPageTitleBold: + ret = 0; + break; + case SH_DialogButtonBox_ButtonsHaveIcons: + ret = 0; + break; + case SH_Menu_SelectionWrap: + ret = false; + break; + case SH_Menu_KeyboardSearch: + ret = true; + break; + case SH_Menu_SpaceActivatesItem: + ret = true; + break; + case SH_Slider_AbsoluteSetButtons: + ret = Qt::LeftButton|Qt::MiddleButton; + break; + case SH_Slider_PageSetButtons: + ret = 0; + break; + case SH_ScrollBar_ContextMenu: + ret = false; + break; + case SH_TitleBar_AutoRaise: + ret = true; + break; + case SH_Menu_AllowActiveAndDisabled: + ret = false; + break; + case SH_Menu_SubMenuPopupDelay: + ret = 100; + break; + case SH_Menu_SubMenuUniDirection: + ret = true; + break; + case SH_Menu_SubMenuSloppySelectOtherActions: + ret = false; + break; + case SH_Menu_SubMenuResetWhenReenteringParent: + ret = true; + break; + case SH_Menu_SubMenuDontStartSloppyOnLeave: + ret = true; + break; + + case SH_ScrollBar_LeftClickAbsolutePosition: { + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + bool result = [defaults boolForKey:@"AppleScrollerPagingBehavior"]; +// if(QApplication::keyboardModifiers() & Qt::AltModifier) +// ret = !result; +// else + ret = result; + break; } + case SH_TabBar_PreferNoArrows: + ret = true; + break; + /* + case SH_DialogButtons_DefaultButton: + ret = QDialogButtons::Reject; + break; + */ + case SH_GroupBox_TextLabelVerticalAlignment: + ret = Qt::AlignTop; + break; + case SH_ScrollView_FrameOnlyAroundContents: + ret = QCommonStyle::styleHint(sh, opt, hret); + break; + case SH_Menu_FillScreenWithScroll: + ret = false; + break; + case SH_Menu_Scrollable: + ret = true; + break; + case SH_RichText_FullWidthSelection: + ret = true; + break; + case SH_BlinkCursorWhenTextSelected: + ret = false; + break; + case SH_Slider_StopMouseOverSlider: + ret = true; + break; + case SH_ListViewExpand_SelectMouseType: + ret = QEvent::MouseButtonRelease; + break; + case SH_TabBar_SelectMouseType: + if (const QStyleOptionTabBarBase *opt2 = qstyleoption_cast<const QStyleOptionTabBarBase *>(opt)) { + ret = opt2->documentMode ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease; + } else { + ret = QEvent::MouseButtonRelease; + } + break; + case SH_ComboBox_Popup: + if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) + ret = !cmb->editable; + else + ret = 0; + break; + case SH_Workspace_FillSpaceOnMaximize: + ret = true; + break; + case SH_Widget_ShareActivation: + ret = true; + break; + case SH_Header_ArrowAlignment: + ret = Qt::AlignRight; + break; + case SH_TabBar_Alignment: { +//#if QT_CONFIG(tabwidget) +// if (const QTabWidget *tab = qobject_cast<const QTabWidget*>(w)) { +// if (tab->documentMode()) { +// ret = Qt::AlignLeft; +// break; +// } +// } +//#endif +//#if QT_CONFIG(tabbar) +// if (const QTabBar *tab = qobject_cast<const QTabBar*>(w)) { +// if (tab->documentMode()) { +// ret = Qt::AlignLeft; +// break; +// } +// } +//#endif + ret = Qt::AlignCenter; + } break; + case SH_UnderlineShortcut: + ret = false; + break; + case SH_ToolTipLabel_Opacity: + ret = 242; // About 95% + break; + case SH_Button_FocusPolicy: + ret = Qt::TabFocus; + break; + case SH_EtchDisabledText: + ret = false; + break; + case SH_FocusFrame_Mask: { + ret = true; + if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) { + const uchar fillR = 192, fillG = 191, fillB = 190; + QImage img; + + QSize pixmapSize = opt->rect.size(); + if (!pixmapSize.isEmpty()) { + QPixmap pix(pixmapSize); + pix.fill(QColor(fillR, fillG, fillB)); + QPainter pix_paint(&pix); + proxy()->drawControl(CE_FocusFrame, opt, &pix_paint); + pix_paint.end(); + img = pix.toImage(); + } + + const QRgb *sptr = (QRgb*)img.bits(), *srow; + const qsizetype sbpl = img.bytesPerLine(); + const int w = sbpl/4, h = img.height(); + + QImage img_mask(img.width(), img.height(), QImage::Format_ARGB32); + QRgb *dptr = (QRgb*)img_mask.bits(), *drow; + const qsizetype dbpl = img_mask.bytesPerLine(); + + for (int y = 0; y < h; ++y) { + srow = sptr+((y*sbpl)/4); + drow = dptr+((y*dbpl)/4); + for (int x = 0; x < w; ++x) { + const int redDiff = qRed(*srow) - fillR; + const int greenDiff = qGreen(*srow) - fillG; + const int blueDiff = qBlue(*srow) - fillB; + const int diff = (redDiff * redDiff) + (greenDiff * greenDiff) + (blueDiff * blueDiff); + (*drow++) = (diff < 10) ? 0xffffffff : 0xff000000; + ++srow; + } + } + QBitmap qmask = QBitmap::fromImage(img_mask); + mask->region = QRegion(qmask); + } + break; } + case SH_TitleBar_NoBorder: + ret = 1; + break; + case SH_RubberBand_Mask: + ret = 0; + break; + case SH_ComboBox_LayoutDirection: + ret = Qt::LeftToRight; + break; + case SH_ItemView_EllipsisLocation: + ret = Qt::AlignHCenter; + break; + case SH_ItemView_ShowDecorationSelected: + ret = true; + break; + case SH_TitleBar_ModifyNotification: + ret = false; + break; + case SH_ScrollBar_RollBetweenButtons: + ret = true; + break; + case SH_WindowFrame_Mask: + ret = false; + break; + case SH_TabBar_ElideMode: + ret = Qt::ElideRight; + break; +// case SH_DialogButtonLayout: +// ret = QDialogButtonBox::MacLayout; +// break; +// case SH_FormLayoutWrapPolicy: +// ret = QFormLayout::DontWrapRows; +// break; +// case SH_FormLayoutFieldGrowthPolicy: +// ret = QFormLayout::FieldsStayAtSizeHint; +// break; + case SH_FormLayoutFormAlignment: + ret = Qt::AlignHCenter | Qt::AlignTop; + break; + case SH_FormLayoutLabelAlignment: + ret = Qt::AlignRight; + break; +// case SH_ComboBox_PopupFrameStyle: +// ret = QFrame::NoFrame; +// break; + case SH_MessageBox_TextInteractionFlags: + ret = Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard; + break; + case SH_SpellCheckUnderlineStyle: + ret = QTextCharFormat::DashUnderline; + break; + case SH_MessageBox_CenterButtons: + ret = false; + break; + case SH_MenuBar_AltKeyNavigation: + ret = false; + break; + case SH_ItemView_MovementWithoutUpdatingSelection: + ret = false; + break; + case SH_FocusFrame_AboveWidget: + ret = true; + break; +// case SH_WizardStyle: +// ret = QWizard::MacStyle; +// break; + case SH_ItemView_ArrowKeysNavigateIntoChildren: + ret = false; + break; + case SH_Menu_FlashTriggeredItem: + ret = true; + break; + case SH_Menu_FadeOutOnHide: + ret = true; + break; + case SH_ItemView_PaintAlternatingRowColorsForEmptyArea: + ret = true; + break; + case SH_TabBar_CloseButtonPosition: + ret = QStyleOptionTabBarBase::LeftSide; + break; + case SH_DockWidget_ButtonsHaveFrame: + ret = false; + break; + case SH_ScrollBar_Transient: + // For the initial version in QQC2, we don't support transient scrollbars. When the + // time comes, consider doing all such animations from QML. + // ret = [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay; + ret = false; + break; + case SH_TitleBar_ShowToolTipsOnButtons: + // min/max/close buttons on windows don't show tool tips + ret = false; + break; + case SH_ComboBox_AllowWheelScrolling: + ret = false; + break; + case SH_SpinBox_ButtonsInsideFrame: + ret = false; + break; + case SH_Table_GridLineColor: + ret = int(qt_mac_toQColor(NSColor.gridColor).rgba()); + break; + default: + ret = QCommonStyle::styleHint(sh, opt, hret); + break; + } + return ret; +} + +QPixmap QMacStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, + const QStyleOption *opt) const +{ + switch (iconMode) { + case QIcon::Disabled: { + QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32); + int imgh = img.height(); + int imgw = img.width(); + QRgb pixel; + for (int y = 0; y < imgh; ++y) { + for (int x = 0; x < imgw; ++x) { + pixel = img.pixel(x, y); + img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), + qAlpha(pixel) / 2)); + } + } + return QPixmap::fromImage(img); + } + default: + ; + } + return QCommonStyle::generatedIconPixmap(iconMode, pixmap, opt); +} + + +QPixmap QMacStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt) const +{ + // The default implementation of QStyle::standardIconImplementation() is to call standardPixmap() + // I don't want infinite recursion so if we do get in that situation, just return the Window's + // standard pixmap instead (since there is no mac-specific icon then). This should be fine until + // someone changes how Windows standard + // pixmap works. + static bool recursionGuard = false; + + if (recursionGuard) + return QCommonStyle::standardPixmap(standardPixmap, opt); + + recursionGuard = true; + QIcon icon = proxy()->standardIcon(standardPixmap, opt); + recursionGuard = false; + int size; + switch (standardPixmap) { + default: + size = 32; + break; + case SP_MessageBoxCritical: + case SP_MessageBoxQuestion: + case SP_MessageBoxInformation: + case SP_MessageBoxWarning: + size = 64; + break; + } + return icon.pixmap(opt->window, QSize(size, size)); +} + +void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p) const +{ + Q_D(const QMacStyle); + + const AppearanceSync appSync; + QMacCGContext cg(p); + d->resolveCurrentNSView(opt->window); + + switch (pe) { + case PE_IndicatorArrowUp: + case PE_IndicatorArrowDown: + case PE_IndicatorArrowRight: + case PE_IndicatorArrowLeft: { + p->save(); + p->setRenderHint(QPainter::Antialiasing); + const int xOffset = 1; // FIXME: opt->direction == Qt::LeftToRight ? 2 : -1; + qreal halfSize = 0.5 * qMin(opt->rect.width(), opt->rect.height()); + const qreal penWidth = qMax(halfSize / 3.0, 1.25); +//#if QT_CONFIG(toolbutton) +// if (const QToolButton *tb = qobject_cast<const QToolButton *>(w)) { +// // When stroking the arrow, make sure it fits in the tool button +// if (tb->arrowType() != Qt::NoArrow +// || tb->popupMode() == QToolButton::MenuButtonPopup) +// halfSize -= penWidth; +// } +//#endif + + QTransform transform; + transform.translate(opt->rect.center().x() + xOffset, opt->rect.center().y() + 2); + QPainterPath path; + switch(pe) { + default: + case PE_IndicatorArrowDown: + break; + case PE_IndicatorArrowUp: + transform.rotate(180); + break; + case PE_IndicatorArrowLeft: + transform.rotate(90); + break; + case PE_IndicatorArrowRight: + transform.rotate(-90); + break; + } + p->setTransform(transform); + + path.moveTo(-halfSize, -halfSize * 0.5); + path.lineTo(0.0, halfSize * 0.5); + path.lineTo(halfSize, -halfSize * 0.5); + + const QPen arrowPen(opt->palette.text(), penWidth, + Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); + p->strokePath(path, arrowPen); + p->restore(); + break; } + case PE_FrameTabBarBase: + if (const QStyleOptionTabBarBase *tbb + = qstyleoption_cast<const QStyleOptionTabBarBase *>(opt)) { + if (tbb->documentMode) { + p->save(); + drawTabBase(p, tbb); + p->restore(); + return; + } + QRegion region(tbb->rect); + region -= tbb->tabBarRect; + p->save(); + p->setClipRegion(region); + QStyleOptionTabWidgetFrame twf; + twf.QStyleOption::operator=(*tbb); + twf.shape = tbb->shape; + switch (QMacStylePrivate::tabDirection(twf.shape)) { + case QMacStylePrivate::North: + twf.rect = twf.rect.adjusted(0, 0, 0, 10); + break; + case QMacStylePrivate::South: + twf.rect = twf.rect.adjusted(0, -10, 0, 0); + break; + case QMacStylePrivate::West: + twf.rect = twf.rect.adjusted(0, 0, 10, 0); + break; + case QMacStylePrivate::East: + twf.rect = twf.rect.adjusted(0, -10, 0, 0); + break; + } + proxy()->drawPrimitive(PE_FrameTabWidget, &twf, p); + p->restore(); + } + break; + case PE_PanelTipLabel: + p->fillRect(opt->rect, opt->palette.brush(QPalette::ToolTipBase)); + break; + case PE_FrameGroupBox: + if (const auto *groupBox = qstyleoption_cast<const QStyleOptionFrame *>(opt)) + if (groupBox->features & QStyleOptionFrame::Flat) { + QCommonStyle::drawPrimitive(pe, groupBox, p); + break; + } + Q_FALLTHROUGH(); + case PE_FrameTabWidget: + { + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Box, QStyleHelper::SizeLarge); + auto *box = static_cast<NSBox *>(d->cocoaControl(cw)); + // FIXME Since macOS 10.14, simply calling drawRect: won't display anything anymore. + // The AppKit team is aware of this and has proposed a couple of solutions. + // The first solution was to call displayRectIgnoringOpacity:inContext: instead. + // However, it doesn't seem to work on 10.13. More importantly, dark mode on 10.14 + // is extremely slow. Light mode works fine. + // The second solution is to subclass NSBox and reimplement a trivial drawRect: which + // would only call super. This works without any issue on 10.13, but a double border + // shows on 10.14 in both light and dark modes. + // The code below picks what works on each version and mode. On 10.13 and earlier, we + // simply call drawRect: on a regular NSBox. On 10.14, we call displayRectIgnoringOpacity: + // inContext:, but only in light mode. In dark mode, we use a custom NSBox subclass, + // QDarkNSBox, of type NSBoxCustom. Its appearance is close enough to the real thing so + // we can use this for now. + auto adjustedRect = opt->rect; + bool needTranslation = false; + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave + && !qt_mac_applicationIsInDarkMode()) { + // In Aqua theme we have to use the 'default' NSBox (as opposite + // to the 'custom' QDarkNSBox we use in dark theme). Since -drawRect: + // does nothing in default NSBox, we call -displayRectIgnoringOpaticty:. + // Unfortunately, the resulting box is smaller then the actual rect we + // wanted. This can be seen, e.g. because tabs (buttons) are misaligned + // vertically and even worse, if QTabWidget has autoFillBackground + // set, this background overpaints NSBox making it to disappear. + // We trick our NSBox to render in a larger rectangle, so that + // the actuall result (which is again smaller than requested), + // more or less is what we really want. We'll have to adjust CTM + // and translate accordingly. + adjustedRect.adjust(0, 0, 6, 6); + needTranslation = true; + } + d->drawNSViewInRect(box, adjustedRect, p, ^(CGContextRef ctx, const CGRect &rect) { +//#if QT_CONFIG(tabwidget) +// if (QTabWidget *tabWidget = qobject_cast<QTabWidget *>(opt->styleObject)) +// clipTabBarFrame(opt, this, ctx); +//#endif + QMacAutoReleasePool pool; + CGContextTranslateCTM(ctx, 0, rect.origin.y + rect.size.height); + CGContextScaleCTM(ctx, 1, -1); + if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSMojave + || [box isMemberOfClass:QDarkNSBox.class]) { + [box drawRect:rect]; + } else { + if (needTranslation) + CGContextTranslateCTM(ctx, -3.0, 5.0); + [box displayRectIgnoringOpacity:box.bounds inContext:NSGraphicsContext.currentContext]; + } + }); + break; + } + case PE_IndicatorToolBarSeparator: { + QPainterPath path; + if (opt->state & State_Horizontal) { + int xpoint = opt->rect.center().x(); + path.moveTo(xpoint + 0.5, opt->rect.top() + 1); + path.lineTo(xpoint + 0.5, opt->rect.bottom()); + } else { + int ypoint = opt->rect.center().y(); + path.moveTo(opt->rect.left() + 2 , ypoint + 0.5); + path.lineTo(opt->rect.right() + 1, ypoint + 0.5); + } + QPainterPathStroker theStroker; + theStroker.setCapStyle(Qt::FlatCap); + theStroker.setDashPattern(QVector<qreal>() << 1 << 2); + path = theStroker.createStroke(path); + const auto dark = qt_mac_applicationIsInDarkMode() ? opt->palette.dark().color().darker() + : QColor(0, 0, 0, 119); + p->fillPath(path, dark); + } + break; + case PE_FrameWindow: + if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { +// if (w && w->inherits("QMdiSubWindow")) { +// p->save(); +// p->setPen(QPen(frame->palette.dark().color(), frame->lineWidth)); +// p->setBrush(frame->palette.window()); +// p->drawRect(frame->rect); +// p->restore(); +// } + } + break; + case PE_IndicatorDockWidgetResizeHandle: { + // The docwidget resize handle is drawn as a one-pixel wide line. + p->save(); + if (opt->state & State_Horizontal) { + p->setPen(QColor(160, 160, 160)); + p->drawLine(opt->rect.topLeft(), opt->rect.topRight()); + } else { + p->setPen(QColor(145, 145, 145)); + p->drawLine(opt->rect.topRight(), opt->rect.bottomRight()); + } + p->restore(); + } break; + case PE_IndicatorToolBarHandle: { + p->save(); + QPainterPath path; + int x = opt->rect.x() + 6; + int y = opt->rect.y() + 7; + static const int RectHeight = 2; + if (opt->state & State_Horizontal) { + while (y < opt->rect.height() - RectHeight - 5) { + path.moveTo(x, y); + path.addEllipse(x, y, RectHeight, RectHeight); + y += 6; + } + } else { + while (x < opt->rect.width() - RectHeight - 5) { + path.moveTo(x, y); + path.addEllipse(x, y, RectHeight, RectHeight); + x += 6; + } + } + p->setPen(Qt::NoPen); + QColor dark = opt->palette.dark().color().darker(); + dark.setAlphaF(0.50); + p->fillPath(path, dark); + p->restore(); + + break; + } + case PE_IndicatorHeaderArrow: + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { + // In HITheme, up is down, down is up and hamburgers eat people. + if (header->sortIndicator != QStyleOptionHeader::None) + proxy()->drawPrimitive( + (header->sortIndicator == QStyleOptionHeader::SortDown) ? + PE_IndicatorArrowUp : PE_IndicatorArrowDown, header, p); + } + break; + case PE_IndicatorMenuCheckMark: { + QColor pc; + if (opt->state & State_On) + pc = opt->palette.highlightedText().color(); + else + pc = opt->palette.text().color(); + + QCFType<CGColorRef> checkmarkColor = CGColorCreateGenericRGB(static_cast<CGFloat>(pc.redF()), + static_cast<CGFloat>(pc.greenF()), + static_cast<CGFloat>(pc.blueF()), + static_cast<CGFloat>(pc.alphaF())); + // kCTFontUIFontSystem and others give the same result + // as kCTFontUIFontMenuItemMark. However, the latter is + // more reminiscent to HITheme's kThemeMenuItemMarkFont. + // See also the font for small- and mini-sized widgets, + // where we end up using the generic system font type. + const CTFontUIFontType fontType = (opt->state & State_Mini) ? kCTFontUIFontMiniSystem : + (opt->state & State_Small) ? kCTFontUIFontSmallSystem : + kCTFontUIFontMenuItemMark; + // Similarly for the font size, where there is a small difference + // between regular combobox and item view items, and and menu items. + // However, we ignore any difference for small- and mini-sized widgets. + const CGFloat fontSize = fontType == kCTFontUIFontMenuItemMark ? opt->fontMetrics.height() : 0.0; + QCFType<CTFontRef> checkmarkFont = CTFontCreateUIFontForLanguage(fontType, fontSize, NULL); + + CGContextSaveGState(cg); + CGContextSetShouldSmoothFonts(cg, NO); // Same as HITheme and Cocoa menu checkmarks + + // Baseline alignment tweaks for QComboBox and QMenu + const CGFloat vOffset = (opt->state & State_Mini) ? 0.0 : + (opt->state & State_Small) ? 1.0 : + 0.75; + + CGContextTranslateCTM(cg, 0, opt->rect.bottom()); + CGContextScaleCTM(cg, 1, -1); + // Translate back to the original position and add rect origin and offset + CGContextTranslateCTM(cg, opt->rect.x(), vOffset); + + // CTFont has severe difficulties finding the checkmark character among its + // glyphs. Fortunately, CTLine knows its ways inside the Cocoa labyrinth. + static const CFStringRef keys[] = { kCTFontAttributeName, kCTForegroundColorAttributeName }; + static const int numValues = sizeof(keys) / sizeof(keys[0]); + const CFTypeRef values[] = { (CFTypeRef)checkmarkFont, (CFTypeRef)checkmarkColor }; + Q_STATIC_ASSERT((sizeof(values) / sizeof(values[0])) == numValues); + QCFType<CFDictionaryRef> attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, + numValues, NULL, NULL); + // U+2713: CHECK MARK + QCFType<CFAttributedStringRef> checkmarkString = CFAttributedStringCreate(kCFAllocatorDefault, (CFStringRef)@"\u2713", attributes); + QCFType<CTLineRef> line = CTLineCreateWithAttributedString(checkmarkString); + + CTLineDraw((CTLineRef)line, cg); + CGContextFlush(cg); // CTLineDraw's documentation says it doesn't flush + + CGContextRestoreGState(cg); + break; } + case PE_IndicatorItemViewItemCheck: + case PE_IndicatorRadioButton: + case PE_IndicatorCheckBox: { + const bool isEnabled = opt->state & State_Enabled; + const bool isPressed = opt->state & State_Sunken; + const bool isRadioButton = (pe == PE_IndicatorRadioButton); + const auto ct = isRadioButton ? QMacStylePrivate::Button_RadioButton : QMacStylePrivate::Button_CheckBox; + const auto cs = d->effectiveAquaSizeConstrain(opt); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); + auto *tb = static_cast<NSButton *>(d->cocoaControl(cw)); + tb.enabled = isEnabled; + tb.state = (opt->state & State_NoChange) ? NSMixedState : + (opt->state & State_On) ? NSOnState : NSOffState; + [tb highlight:isPressed]; + const auto vOffset = [=] { + // As measured + if (cs == QStyleHelper::SizeMini) + return ct == QMacStylePrivate::Button_CheckBox ? -0.5 : 0.5; + + return cs == QStyleHelper::SizeSmall ? 0.5 : 0.0; + } (); + d->drawNSViewInRect(tb, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) { + QMacAutoReleasePool pool; + CGContextTranslateCTM(ctx, 0, vOffset); + [tb.cell drawInteriorWithFrame:rect inView:tb]; + }); + break; } + case PE_FrameFocusRect: + // Use the our own focus widget stuff. + break; + case PE_IndicatorBranch: { + if (!(opt->state & State_Children)) + break; + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Button_Disclosure, QStyleHelper::SizeLarge); + NSButtonCell *triangleCell = static_cast<NSButtonCell *>(d->cocoaCell(cw)); + [triangleCell setState:(opt->state & State_Open) ? NSOnState : NSOffState]; +// bool viewHasFocus = (w && w->hasFocus()) || (opt->state & State_HasFocus); + bool viewHasFocus = false; + [triangleCell setBackgroundStyle:((opt->state & State_Selected) && viewHasFocus) ? NSBackgroundStyleEmphasized : NSBackgroundStyleNormal]; + + d->setupNSGraphicsContext(cg, NO); + + QRect qtRect = opt->rect.adjusted(DisclosureOffset, 0, -DisclosureOffset, 0); + CGRect rect = CGRectMake(qtRect.x() + 1, qtRect.y(), qtRect.width(), qtRect.height()); + CGContextTranslateCTM(cg, rect.origin.x, rect.origin.y + rect.size.height); + CGContextScaleCTM(cg, 1, -1); + CGContextTranslateCTM(cg, -rect.origin.x, -rect.origin.y); + + [triangleCell drawBezelWithFrame:NSRectFromCGRect(rect) inView:[triangleCell controlView]]; + + d->restoreNSGraphicsContext(cg); + break; } + + case PE_Frame: { + const QPen oldPen = p->pen(); + QPen penCpy = p->pen(); + penCpy.setWidth(2); + penCpy.setColor(opt->palette.dark().color()); + p->setPen(penCpy); + p->drawRect(opt->rect); + p->setPen(oldPen); + break; } + case PE_PanelLineEdit: + case PE_FrameLineEdit: + if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + if (frame->state & State_Sunken) { + const bool isEnabled = opt->state & State_Enabled; + const bool isReadOnly = opt->state & State_ReadOnly; + const bool isRounded = frame->features & QStyleOptionFrame::Rounded; + const auto cs = d->effectiveAquaSizeConstrain(opt, CT_LineEdit); + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::TextField, cs); + auto *tf = static_cast<NSTextField *>(d->cocoaControl(cw)); + tf.enabled = isEnabled; + tf.editable = !isReadOnly; + tf.bezeled = YES; + static_cast<NSTextFieldCell *>(tf.cell).bezelStyle = isRounded ? NSTextFieldRoundedBezel : NSTextFieldSquareBezel; + tf.frame = opt->rect.toCGRect(); + d->drawNSViewInRect(tf, opt->rect, p, ^(CGContextRef, const CGRect &rect) { + QMacAutoReleasePool pool; + if (!qt_mac_applicationIsInDarkMode()) { + // In 'Dark' mode controls are transparent, so we do not + // over-paint the (potentially custom) color in the background. + // In 'Light' mode we have to care about the correct + // background color. See the comments below for PE_PanelLineEdit. + CGContextRef cgContext = NSGraphicsContext.currentContext.CGContext; + // See QMacCGContext, here we expect bitmap context created with + // color space 'kCGColorSpaceSRGB', if it's something else - we + // give up. + if (cgContext ? bool(CGBitmapContextGetColorSpace(cgContext)) : false) { + tf.drawsBackground = YES; + const QColor bgColor = frame->palette.brush(QPalette::Base).color(); + tf.backgroundColor = [NSColor colorWithSRGBRed:bgColor.redF() + green:bgColor.greenF() + blue:bgColor.blueF() + alpha:bgColor.alphaF()]; + if (bgColor.alpha() != 255) { + // No way we can have it bezeled and transparent ... + tf.bordered = YES; + } + } + } + + [tf.cell drawWithFrame:rect inView:tf]; + }); + } else { + QCommonStyle::drawPrimitive(pe, opt, p); + } + } + break; + case PE_PanelScrollAreaCorner: { + const QBrush brush(opt->palette.brush(QPalette::Base)); + p->fillRect(opt->rect, brush); + p->setPen(QPen(QColor(217, 217, 217))); + p->drawLine(opt->rect.topLeft(), opt->rect.topRight()); + p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft()); + } break; + case PE_FrameStatusBarItem: + break; +//#if QT_CONFIG(tabbar) +// case PE_IndicatorTabClose: { +// // Make close button visible only on the hovered tab. +// QTabBar *tabBar = qobject_cast<QTabBar*>(w->parentWidget()); +// const QWidget *closeBtn = w; +// if (!tabBar) { +// // QStyleSheetStyle instead of CloseButton (which has +// // a QTabBar as a parent widget) uses the QTabBar itself: +// tabBar = qobject_cast<QTabBar *>(const_cast<QWidget*>(w)); +// closeBtn = decltype(closeBtn)(property("_q_styleSheetRealCloseButton").value<void *>()); +// } +// if (tabBar) { +// const bool documentMode = tabBar->documentMode(); +// const QTabBarPrivate *tabBarPrivate = static_cast<QTabBarPrivate *>(QObjectPrivate::get(tabBar)); +// const int hoveredTabIndex = tabBarPrivate->hoveredTabIndex(); +// if (!documentMode || +// (hoveredTabIndex != -1 && ((closeBtn == tabBar->tabButton(hoveredTabIndex, QTabBar::LeftSide)) || +// (closeBtn == tabBar->tabButton(hoveredTabIndex, QTabBar::RightSide))))) { +// const bool hover = (opt->state & State_MouseOver); +// const bool selected = (opt->state & State_Selected); +// const bool pressed = (opt->state & State_Sunken); +// drawTabCloseButton(p, hover, selected, pressed, documentMode); +// } +// } +// } break; +//#endif // QT_CONFIG(tabbar) + case PE_PanelStatusBar: { + // Fill the status bar with the titlebar gradient. + QLinearGradient linearGrad; + const bool isMainWindow = qt_macWindowMainWindow(opt->window); + if (isMainWindow) + linearGrad = titlebarGradientActive(); + else + linearGrad = titlebarGradientInactive(); + + linearGrad.setStart(0, opt->rect.top()); + linearGrad.setFinalStop(0, opt->rect.bottom()); + p->fillRect(opt->rect, linearGrad); + + // Draw the black separator line at the top of the status bar. + if (isMainWindow) + p->setPen(titlebarSeparatorLineActive); + else + p->setPen(titlebarSeparatorLineInactive); + p->drawLine(opt->rect.left(), opt->rect.top(), opt->rect.right(), opt->rect.top()); + + break; + } + case PE_PanelMenu: { + p->save(); + p->fillRect(opt->rect, Qt::transparent); + p->setPen(Qt::transparent); + p->setBrush(opt->palette.window()); + p->setRenderHint(QPainter::Antialiasing, true); + const QPainterPath path = d->windowPanelPath(opt->rect); + p->drawPath(path); + p->restore(); + } break; + + default: + QCommonStyle::drawPrimitive(pe, opt, p); + break; + } +} + +static QPixmap darkenPixmap(const QPixmap &pixmap) +{ + QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32); + int imgh = img.height(); + int imgw = img.width(); + int h, s, v, a; + QRgb pixel; + for (int y = 0; y < imgh; ++y) { + for (int x = 0; x < imgw; ++x) { + pixel = img.pixel(x, y); + a = qAlpha(pixel); + QColor hsvColor(pixel); + hsvColor.getHsv(&h, &s, &v); + s = qMin(100, s * 2); + v = v / 2; + hsvColor.setHsv(h, s, v); + pixel = hsvColor.rgb(); + img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), a)); + } + } + return QPixmap::fromImage(img); +} + +void QMacStylePrivate::setupVerticalInvertedXform(CGContextRef cg, bool reverse, bool vertical, const CGRect &rect) const +{ + if (vertical) { + CGContextTranslateCTM(cg, rect.size.height, 0); + CGContextRotateCTM(cg, M_PI_2); + } + if (vertical != reverse) { + CGContextTranslateCTM(cg, rect.size.width, 0); + CGContextScaleCTM(cg, -1, 1); + } +} + +void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p) const +{ + Q_D(const QMacStyle); + + const AppearanceSync sync; + const QMacAutoReleasePool pool; + + QMacCGContext cg(p); + d->resolveCurrentNSView(opt->window); + + switch (ce) { + case CE_HeaderSection: + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { + State flags = header->state; + QRect ir = header->rect; + const bool pressed = (flags & State_Sunken) && !(flags & State_On); + p->fillRect(ir, pressed ? header->palette.dark() : header->palette.button()); + p->setPen(QPen(header->palette.dark(), 1.0)); + if (header->orientation == Qt::Horizontal) + p->drawLine(QLineF(ir.right() + 0.5, ir.top() + headerSectionSeparatorInset, + ir.right() + 0.5, ir.bottom() - headerSectionSeparatorInset)); + else + p->drawLine(QLineF(ir.left() + headerSectionSeparatorInset, ir.bottom(), + ir.right() - headerSectionSeparatorInset, ir.bottom())); + } + + break; + case CE_HeaderLabel: + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { + p->save(); + QRect textr = header->rect; + if (!header->icon.isNull()) { + QIcon::Mode mode = QIcon::Disabled; + if (opt->state & State_Enabled) + mode = QIcon::Normal; + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + QPixmap pixmap = header->icon.pixmap(opt->window, QSize(iconExtent, iconExtent), mode); + + QRect pixr = header->rect; + pixr.setY(header->rect.center().y() - (pixmap.height() / pixmap.devicePixelRatio() - 1) / 2); + proxy()->drawItemPixmap(p, pixr, Qt::AlignVCenter, pixmap); + textr.translate(pixmap.width() / pixmap.devicePixelRatio() + 2, 0); + } + + proxy()->drawItemText(p, textr, header->textAlignment | Qt::AlignVCenter, header->palette, + header->state & State_Enabled, header->text, QPalette::ButtonText); + p->restore(); + } + break; + case CE_ToolButtonLabel: + if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) { + QStyleOptionToolButton myTb = *tb; + myTb.state &= ~State_AutoRaise; +#ifndef QT_NO_ACCESSIBILITY + if (QStyleHelper::hasAncestor(opt->styleObject, QAccessible::ToolBar)) { + QRect cr = tb->rect; + int shiftX = 0; + int shiftY = 0; + bool needText = false; + int alignment = 0; + bool down = tb->state & (State_Sunken | State_On); + if (down) { + shiftX = proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb); + shiftY = proxy()->pixelMetric(PM_ButtonShiftVertical, tb); + } + // The down state is special for QToolButtons in a toolbar on the Mac + // The text is a bit bolder and gets a drop shadow and the icons are also darkened. + // This doesn't really fit into any particular case in QIcon, so we + // do the majority of the work ourselves. + if (!(tb->features & QStyleOptionToolButton::Arrow)) { + Qt::ToolButtonStyle tbstyle = tb->toolButtonStyle; + if (tb->icon.isNull() && !tb->text.isEmpty()) + tbstyle = Qt::ToolButtonTextOnly; + + switch (tbstyle) { + case Qt::ToolButtonTextOnly: { + needText = true; + alignment = Qt::AlignCenter; + break; } + case Qt::ToolButtonIconOnly: + case Qt::ToolButtonTextBesideIcon: + case Qt::ToolButtonTextUnderIcon: { + QRect pr = cr; + QIcon::Mode iconMode = (tb->state & State_Enabled) ? QIcon::Normal + : QIcon::Disabled; + QIcon::State iconState = (tb->state & State_On) ? QIcon::On + : QIcon::Off; + QPixmap pixmap = tb->icon.pixmap(opt->window, + tb->rect.size().boundedTo(tb->iconSize), + iconMode, iconState); + + // Draw the text if it's needed. + if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) { + needText = true; + if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) { + pr.setHeight(pixmap.size().height() / pixmap.devicePixelRatio() + 6); + cr.adjust(0, pr.bottom(), 0, -3); + alignment |= Qt::AlignCenter; + } else { + pr.setWidth(pixmap.width() / pixmap.devicePixelRatio() + 8); + cr.adjust(pr.right(), 0, 0, 0); + alignment |= Qt::AlignLeft | Qt::AlignVCenter; + } + } + if (opt->state & State_Sunken) { + pr.translate(shiftX, shiftY); + pixmap = darkenPixmap(pixmap); + } + proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pixmap); + break; } + default: + Q_ASSERT(false); + break; + } + + if (needText) { + QPalette pal = tb->palette; + QPalette::ColorRole role = QPalette::NoRole; + if (!proxy()->styleHint(SH_UnderlineShortcut, tb)) + alignment |= Qt::TextHideMnemonic; + if (down) + cr.translate(shiftX, shiftY); + if (tbstyle == Qt::ToolButtonTextOnly + || (tbstyle != Qt::ToolButtonTextOnly && !down)) { + QPen pen = p->pen(); + QColor light = down || isDarkMode() ? Qt::black : Qt::white; + light.setAlphaF(0.375f); + p->setPen(light); + p->drawText(cr.adjusted(0, 1, 0, 1), alignment, tb->text); + p->setPen(pen); + if (down && tbstyle == Qt::ToolButtonTextOnly) { +// pal = QApplication::palette("QMenu"); + pal.setCurrentColorGroup(tb->palette.currentColorGroup()); + role = QPalette::HighlightedText; + } + } + proxy()->drawItemText(p, cr, alignment, pal, + tb->state & State_Enabled, tb->text, role); + } + } else { + QCommonStyle::drawControl(ce, &myTb, p); + } + } else +#endif // QT_NO_ACCESSIBILITY + { + QCommonStyle::drawControl(ce, &myTb, p); + } + } + break; + case CE_ToolBoxTabShape: + QCommonStyle::drawControl(ce, opt, p); + break; + case CE_PushButtonBevel: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + if (!(btn->state & (State_Raised | State_Sunken | State_On))) + break; + + if (btn->features & QStyleOptionButton::CommandLinkButton) { + QCommonStyle::drawControl(ce, opt, p); + break; + } + + const bool hasFocus = btn->state & State_HasFocus; + const bool isActive = btn->state & State_Active; + + // a focused auto-default button within an active window + // takes precedence over a normal default button + if ((btn->features & QStyleOptionButton::AutoDefaultButton) + && isActive && hasFocus) + d->autoDefaultButton = btn->styleObject; + else if (d->autoDefaultButton == btn->styleObject) + d->autoDefaultButton = nullptr; + + const bool isEnabled = btn->state & State_Enabled; + const bool isPressed = btn->state & State_Sunken; + const bool isHighlighted = isActive && + ((btn->state & State_On) + || (btn->features & QStyleOptionButton::DefaultButton) + || (btn->features & QStyleOptionButton::AutoDefaultButton + && d->autoDefaultButton == btn->styleObject)); + const bool hasMenu = btn->features & QStyleOptionButton::HasMenu; + const auto ct = cocoaControlType(btn); + const auto cs = d->effectiveAquaSizeConstrain(btn); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); + auto *pb = static_cast<NSButton *>(d->cocoaControl(cw)); + // Ensure same size and location as we used to have with HITheme. + // This is more convoluted than we initialy thought. See for example + // differences between plain and menu button frames. + const QRectF frameRect = cw.adjustedControlFrame(btn->rect); + pb.frame = frameRect.toCGRect(); + + pb.enabled = isEnabled; + [pb highlight:isPressed]; + pb.state = isHighlighted && !isPressed ? NSOnState : NSOffState; + d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef, const CGRect &r) { + QMacAutoReleasePool pool; + [pb.cell drawBezelWithFrame:r inView:pb.superview]; + }); + [pb highlight:NO]; + + if (hasMenu && cw.type == QMacStylePrivate::Button_SquareButton) { + // Using -[NSPopuButtonCell drawWithFrame:inView:] above won't do + // it right because we don't set the text in the native button. + const int mbi = proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn); + const auto ir = frameRect.toRect(); + int arrowYOffset = 0; + const auto ar = visualRect(btn->direction, ir, QRect(ir.right() - mbi - 6, ir.height() / 2 - arrowYOffset, mbi, mbi)); + + QStyleOption arrowOpt = *opt; + arrowOpt.rect = ar; + proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p); + } + } + break; + case CE_PushButtonLabel: + if (const QStyleOptionButton *b = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + QStyleOptionButton btn(*b); + // We really don't want the label to be drawn the same as on + // windows style if it has an icon and text, then it should be more like a + // tab. So, cheat a little here. However, if it *is* only an icon + // the windows style works great, so just use that implementation. + const bool isEnabled = btn.state & State_Enabled; + const bool hasMenu = btn.features & QStyleOptionButton::HasMenu; + const bool hasIcon = !btn.icon.isNull(); + const bool hasText = !btn.text.isEmpty(); + const bool isActive = btn.state & State_Active; + const bool isPressed = btn.state & State_Sunken; + + const auto ct = cocoaControlType(&btn); + + if (!hasMenu && ct != QMacStylePrivate::Button_SquareButton) { + if (isPressed + || (isActive && isEnabled + && ((btn.state & State_On) + || ((btn.features & QStyleOptionButton::DefaultButton) && !d->autoDefaultButton) + || d->autoDefaultButton == btn.styleObject))) + btn.palette.setColor(QPalette::ButtonText, Qt::white); + } + + if ((!hasIcon && !hasMenu) || (hasIcon && !hasText)) { + QCommonStyle::drawControl(ce, &btn, p); + } else { + QRect freeContentRect = btn.rect; + QRect textRect = itemTextRect( + btn.fontMetrics, freeContentRect, Qt::AlignCenter, isEnabled, btn.text); + if (hasMenu) { + textRect.moveTo(11, textRect.top()); + } + // Draw the icon: + if (hasIcon) { + int contentW = textRect.width(); + if (hasMenu) + contentW += proxy()->pixelMetric(PM_MenuButtonIndicator) + 4; + QIcon::Mode mode = isEnabled ? QIcon::Normal : QIcon::Disabled; + if (mode == QIcon::Normal && btn.state & State_HasFocus) + mode = QIcon::Active; + // Decide if the icon is should be on or off: + QIcon::State state = QIcon::Off; + if (btn.state & State_On) + state = QIcon::On; + QPixmap pixmap = btn.icon.pixmap(opt->window, btn.iconSize, mode, state); + int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio(); + int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio(); + contentW += pixmapWidth + QMacStylePrivate::PushButtonContentPadding; + int iconLeftOffset = freeContentRect.x() + (freeContentRect.width() - contentW) / 2; + int iconTopOffset = freeContentRect.y() + (freeContentRect.height() - pixmapHeight) / 2; + QRect iconDestRect(iconLeftOffset, iconTopOffset, pixmapWidth, pixmapHeight); + QRect visualIconDestRect = visualRect(btn.direction, freeContentRect, iconDestRect); + proxy()->drawItemPixmap(p, visualIconDestRect, Qt::AlignLeft | Qt::AlignVCenter, pixmap); + int newOffset = iconDestRect.x() + iconDestRect.width() + + QMacStylePrivate::PushButtonContentPadding - textRect.x(); + textRect.adjust(newOffset, 0, newOffset, 0); + } + // Draw the text: + if (hasText) { + textRect = visualRect(btn.direction, freeContentRect, textRect); + proxy()->drawItemText(p, textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, btn.palette, + isEnabled, btn.text, QPalette::ButtonText); + } + } + } + break; + case CE_ComboBoxLabel: + if (const auto *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + auto comboCopy = *cb; + comboCopy.direction = Qt::LeftToRight; + // The rectangle will be adjusted to SC_ComboBoxEditField with comboboxEditBounds() + QCommonStyle::drawControl(CE_ComboBoxLabel, &comboCopy, p); + } + break; + case CE_TabBarTabShape: + if (const auto *tabOpt = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + if (tabOpt->documentMode) { + p->save(); + bool isUnified = false; +// if (w) { +// QRect tabRect = tabOpt->rect; +// QPoint windowTabStart = w->mapTo(w->window(), tabRect.topLeft()); +// isUnified = isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowTabStart.y()); +// } + + const int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, opt); + drawTabShape(p, tabOpt, isUnified, tabOverlap); + + p->restore(); + return; + } + + const bool isActive = tabOpt->state & State_Active; + const bool isEnabled = tabOpt->state & State_Enabled; + const bool isPressed = tabOpt->state & State_Sunken; + const bool isSelected = tabOpt->state & State_Selected; + const auto tabDirection = QMacStylePrivate::tabDirection(tabOpt->shape); + const bool verticalTabs = tabDirection == QMacStylePrivate::East + || tabDirection == QMacStylePrivate::West; + + QStyleOptionTab::TabPosition tp = tabOpt->position; + QStyleOptionTab::SelectedPosition sp = tabOpt->selectedPosition; + if (tabOpt->direction == Qt::RightToLeft && !verticalTabs) { + if (tp == QStyleOptionTab::Beginning) + tp = QStyleOptionTab::End; + else if (tp == QStyleOptionTab::End) + tp = QStyleOptionTab::Beginning; + + if (sp == QStyleOptionTab::NextIsSelected) + sp = QStyleOptionTab::PreviousIsSelected; + else if (sp == QStyleOptionTab::PreviousIsSelected) + sp = QStyleOptionTab::NextIsSelected; + } + + // Alas, NSSegmentedControl and NSSegmentedCell are letting us down. + // We're not able to draw it at will, either calling -[drawSegment: + // inFrame:withView:], -[drawRect:] or anything in between. Besides, + // there's no public API do draw the pressed state, AFAICS. We'll use + // a push NSButton instead and clip the CGContext. + // NOTE/TODO: this is not true. On 10.13 NSSegmentedControl works with + // some (black?) magic/magic dances, on 10.14 it simply works (was + // it fixed in AppKit?). But, indeed, we cannot make a tab 'pressed' + // with NSSegmentedControl (only selected), so we stay with buttons + // (mixing buttons and NSSegmentedControl for such a simple thing + // is too much work). + + const auto cs = d->effectiveAquaSizeConstrain(opt); + // Extra hacks to get the proper pressed appreance when not selected or selected and inactive + const bool needsInactiveHack = (!isActive && isSelected); + const auto ct = !needsInactiveHack && (isSelected || tp == QStyleOptionTab::OnlyOneTab) ? + QMacStylePrivate::Button_PushButton : + QMacStylePrivate::Button_PopupButton; + const bool isPopupButton = ct == QMacStylePrivate::Button_PopupButton; + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); + auto *pb = static_cast<NSButton *>(d->cocoaControl(cw)); + + auto vOffset = isPopupButton ? 1 : 2; + if (tabDirection == QMacStylePrivate::East) + vOffset -= 1; + const auto outerAdjust = isPopupButton ? 1 : 4; + const auto innerAdjust = isPopupButton ? 20 : 10; + QRectF frameRect = tabOpt->rect; + if (verticalTabs) + frameRect = QRectF(frameRect.y(), frameRect.x(), frameRect.height(), frameRect.width()); + // Adjust before clipping + frameRect = frameRect.translated(0, vOffset); + switch (tp) { + case QStyleOptionTab::Beginning: + // Pressed state hack: tweak adjustments in preparation for flip below + if (!isSelected && tabDirection == QMacStylePrivate::West) + frameRect = frameRect.adjusted(-innerAdjust, 0, outerAdjust, 0); + else + frameRect = frameRect.adjusted(-outerAdjust, 0, innerAdjust, 0); + break; + case QStyleOptionTab::Middle: + frameRect = frameRect.adjusted(-innerAdjust, 0, innerAdjust, 0); + break; + case QStyleOptionTab::End: + // Pressed state hack: tweak adjustments in preparation for flip below + if (isSelected || tabDirection == QMacStylePrivate::West) + frameRect = frameRect.adjusted(-innerAdjust, 0, outerAdjust, 0); + else + frameRect = frameRect.adjusted(-outerAdjust, 0, innerAdjust, 0); + break; + case QStyleOptionTab::OnlyOneTab: + frameRect = frameRect.adjusted(-outerAdjust, 0, outerAdjust, 0); + break; + } + pb.frame = frameRect.toCGRect(); + + pb.enabled = isEnabled; + [pb highlight:isPressed]; + // Set off state when inactive. See needsInactiveHack for when it's selected + pb.state = (isActive && isSelected && !isPressed) ? NSOnState : NSOffState; + + const auto drawBezelBlock = ^(CGContextRef ctx, const CGRect &r) { + QMacAutoReleasePool pool; + CGContextClipToRect(ctx, opt->rect.toCGRect()); + if (!isSelected || needsInactiveHack) { + // Final stage of the pressed state hack: flip NSPopupButton rendering + if (!verticalTabs && tp == QStyleOptionTab::End) { + CGContextTranslateCTM(ctx, opt->rect.right(), 0); + CGContextScaleCTM(ctx, -1, 1); + CGContextTranslateCTM(ctx, -frameRect.left(), 0); + } else if (tabDirection == QMacStylePrivate::West && tp == QStyleOptionTab::Beginning) { + CGContextTranslateCTM(ctx, 0, opt->rect.top()); + CGContextScaleCTM(ctx, 1, -1); + CGContextTranslateCTM(ctx, 0, -frameRect.right()); + } else if (tabDirection == QMacStylePrivate::East && tp == QStyleOptionTab::End) { + CGContextTranslateCTM(ctx, 0, opt->rect.bottom()); + CGContextScaleCTM(ctx, 1, -1); + CGContextTranslateCTM(ctx, 0, -frameRect.left()); + } + } + + // Rotate and translate CTM when vertical + // On macOS: positive angle is CW, negative is CCW + if (tabDirection == QMacStylePrivate::West) { + CGContextTranslateCTM(ctx, 0, frameRect.right()); + CGContextRotateCTM(ctx, -M_PI_2); + CGContextTranslateCTM(ctx, -frameRect.left(), 0); + } else if (tabDirection == QMacStylePrivate::East) { + CGContextTranslateCTM(ctx, opt->rect.right(), 0); + CGContextRotateCTM(ctx, M_PI_2); + } + + // Now, if it's a trick with a popup button, it has an arrow + // which makes no sense on tabs. + NSPopUpArrowPosition oldPosition = NSPopUpArrowAtCenter; + NSPopUpButtonCell *pbCell = nil; + if (isPopupButton) { + pbCell = static_cast<NSPopUpButtonCell *>(pb.cell); + oldPosition = pbCell.arrowPosition; + pbCell.arrowPosition = NSPopUpNoArrow; + } + + [pb.cell drawBezelWithFrame:r inView:pb.superview]; + + if (pbCell) // Restore, we may reuse it for a ComboBox. + pbCell.arrowPosition = oldPosition; + }; + + if (needsInactiveHack) { + // First, render tab as non-selected tab on a pixamp + const qreal pixelRatio = p->device()->devicePixelRatioF(); + QImage tabPixmap(opt->rect.size() * pixelRatio, QImage::Format_ARGB32_Premultiplied); + tabPixmap.setDevicePixelRatio(pixelRatio); + tabPixmap.fill(Qt::transparent); + QPainter tabPainter(&tabPixmap); + d->drawNSViewInRect(pb, frameRect, &tabPainter, ^(CGContextRef ctx, const CGRect &r) { + QMacAutoReleasePool pool; + CGContextTranslateCTM(ctx, -opt->rect.left(), -opt->rect.top()); + drawBezelBlock(ctx, r); + }); + tabPainter.end(); + + // Then, darken it with the proper shade of gray + const qreal inactiveGray = 0.898; // As measured + const int inactiveGray8 = qRound(inactiveGray * 255.0); + const QRgb inactiveGrayRGB = qRgb(inactiveGray8, inactiveGray8, inactiveGray8); + for (int l = 0; l < tabPixmap.height(); ++l) { + auto *line = reinterpret_cast<QRgb*>(tabPixmap.scanLine(l)); + for (int i = 0; i < tabPixmap.width(); ++i) { + if (qAlpha(line[i]) == 255) { + line[i] = inactiveGrayRGB; + } else if (qAlpha(line[i]) > 128) { + const int g = qRound(inactiveGray * qRed(line[i])); + line[i] = qRgba(g, g, g, qAlpha(line[i])); + } + } + } + + // Finally, draw the tab pixmap on the current painter + p->drawImage(opt->rect, tabPixmap); + } else { + d->drawNSViewInRect(pb, frameRect, p, drawBezelBlock); + } + + if (!isSelected && sp != QStyleOptionTab::NextIsSelected + && tp != QStyleOptionTab::End + && tp != QStyleOptionTab::OnlyOneTab) { + static const QPen separatorPen(Qt::black, 1.0); + p->save(); + p->setOpacity(isEnabled ? 0.105 : 0.06); // As measured + p->setPen(separatorPen); + if (tabDirection == QMacStylePrivate::West) { + p->drawLine(QLineF(opt->rect.left() + 1.5, opt->rect.bottom(), + opt->rect.right() - 0.5, opt->rect.bottom())); + } else if (tabDirection == QMacStylePrivate::East) { + p->drawLine(QLineF(opt->rect.left(), opt->rect.bottom(), + opt->rect.right() - 0.5, opt->rect.bottom())); + } else { + p->drawLine(QLineF(opt->rect.right(), opt->rect.top() + 1.0, + opt->rect.right(), opt->rect.bottom() - 0.5)); + } + p->restore(); + } + } + break; + case CE_TabBarTabLabel: + if (const auto *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + QStyleOptionTab myTab = *tab; + const auto tabDirection = QMacStylePrivate::tabDirection(tab->shape); + const bool verticalTabs = tabDirection == QMacStylePrivate::East + || tabDirection == QMacStylePrivate::West; + + // Check to see if we use have the same as the system font + // (QComboMenuItem is internal and should never be seen by the + // outside world, unless they read the source, in which case, it's + // their own fault). +// const bool nonDefaultFont = p->font() != qt_app_fonts_hash()->value("QComboMenuItem"); + const bool nonDefaultFont = false; + +// if (!myTab.documentMode && (myTab.state & State_Selected) && (myTab.state & State_Active)) +// if (const auto *tabBar = qobject_cast<const QTabBar *>(w)) +// if (!tabBar->tabTextColor(tabBar->currentIndex()).isValid()) +// myTab.palette.setColor(QPalette::WindowText, Qt::white); + + if (myTab.documentMode && isDarkMode()) { + bool active = (myTab.state & State_Selected) && (myTab.state & State_Active); + myTab.palette.setColor(QPalette::WindowText, active ? Qt::white : Qt::gray); + } + + int heightOffset = 0; + if (verticalTabs) { + heightOffset = -1; + } else if (nonDefaultFont) { + if (p->fontMetrics().height() == myTab.rect.height()) + heightOffset = 2; + } + myTab.rect.setHeight(myTab.rect.height() + heightOffset); + + QCommonStyle::drawControl(ce, &myTab, p); + } + break; + case CE_DockWidgetTitle: + if (const auto *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) { + const bool isVertical = dwOpt->verticalTitleBar; + const auto effectiveRect = isVertical ? opt->rect.transposed() : opt->rect; + p->save(); + if (isVertical) { + p->translate(effectiveRect.left(), effectiveRect.top() + effectiveRect.width()); + p->rotate(-90); + p->translate(-effectiveRect.left(), -effectiveRect.top()); + } + + // fill title bar background + QLinearGradient linearGrad; + linearGrad.setStart(QPointF(0, 0)); + linearGrad.setFinalStop(QPointF(0, 2 * effectiveRect.height())); + linearGrad.setColorAt(0, opt->palette.button().color()); + linearGrad.setColorAt(1, opt->palette.dark().color()); + p->fillRect(effectiveRect, linearGrad); + + // draw horizontal line at bottom + p->setPen(opt->palette.dark().color()); + p->drawLine(effectiveRect.bottomLeft(), effectiveRect.bottomRight()); + + if (!dwOpt->title.isEmpty()) { + auto titleRect = proxy()->subElementRect(SE_DockWidgetTitleBarText, opt); + if (isVertical) + titleRect = QRect(effectiveRect.left() + opt->rect.bottom() - titleRect.bottom(), + effectiveRect.top() + titleRect.left() - opt->rect.left(), + titleRect.height(), + titleRect.width()); + + const auto text = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width()); + proxy()->drawItemText(p, titleRect, Qt::AlignCenter, dwOpt->palette, + dwOpt->state & State_Enabled, text, QPalette::WindowText); + } + p->restore(); + } + break; + case CE_FocusFrame: { +// const auto *ff = qobject_cast<const QFocusFrame *>(w); +// const auto *ffw = ff ? ff->widget() : nullptr; +// const auto ct = [=] { +// if (ffw) { +// if (ffw->inherits("QCheckBox")) +// return QMacStylePrivate::Button_CheckBox; +// if (ffw->inherits("QRadioButton")) +// return QMacStylePrivate::Button_RadioButton; +// if (ffw->inherits("QLineEdit") || ffw->inherits("QTextEdit")) +// return QMacStylePrivate::TextField; +// } +// +// return QMacStylePrivate::Box; // Not really, just make it the default +// } (); +// const auto cs = ffw ? (ffw->testAttribute(Qt::WA_MacMiniSize) ? QStyleHelper::SizeMini : +// ffw->testAttribute(Qt::WA_MacSmallSize) ? QStyleHelper::SizeSmall : +// QStyleHelper::SizeLarge) : +// QStyleHelper::SizeLarge; +// const int hMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin, opt); +// const int vMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin, opt); +// d->drawFocusRing(p, opt->rect, hMargin, vMargin, QMacStylePrivate::CocoaControl(ct, cs)); + break; } + case CE_MenuEmptyArea: + // Skip: PE_PanelMenu fills in everything + break; + case CE_MenuItem: + case CE_MenuHMargin: + case CE_MenuVMargin: + case CE_MenuTearoff: + case CE_MenuScroller: + if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { + const bool active = mi->state & State_Selected; + if (active) + p->fillRect(mi->rect, mi->palette.highlight()); + + const QStyleHelper::WidgetSizePolicy widgetSize = d->aquaSizeConstrain(opt); + + if (ce == CE_MenuTearoff) { + p->setPen(QPen(mi->palette.dark().color(), 1, Qt::DashLine)); + p->drawLine(mi->rect.x() + 2, mi->rect.y() + mi->rect.height() / 2 - 1, + mi->rect.x() + mi->rect.width() - 4, + mi->rect.y() + mi->rect.height() / 2 - 1); + p->setPen(QPen(mi->palette.light().color(), 1, Qt::DashLine)); + p->drawLine(mi->rect.x() + 2, mi->rect.y() + mi->rect.height() / 2, + mi->rect.x() + mi->rect.width() - 4, + mi->rect.y() + mi->rect.height() / 2); + } else if (ce == CE_MenuScroller) { + const QSize scrollerSize = QSize(10, 8); + const int scrollerVOffset = 5; + const int left = mi->rect.x() + (mi->rect.width() - scrollerSize.width()) / 2; + const int right = left + scrollerSize.width(); + int top; + int bottom; + if (opt->state & State_DownArrow) { + bottom = mi->rect.y() + scrollerVOffset; + top = bottom + scrollerSize.height(); + } else { + bottom = mi->rect.bottom() - scrollerVOffset; + top = bottom - scrollerSize.height(); + } + p->save(); + p->setRenderHint(QPainter::Antialiasing); + QPainterPath path; + path.moveTo(left, bottom); + path.lineTo(right, bottom); + path.lineTo((left + right) / 2, top); + p->fillPath(path, opt->palette.buttonText()); + p->restore(); + } else if (ce != CE_MenuItem) { + break; + } + + if (mi->menuItemType == QStyleOptionMenuItem::Separator) { + CGColorRef separatorColor = [NSColor quaternaryLabelColor].CGColor; + const QRect separatorRect = QRect(mi->rect.left(), mi->rect.center().y(), mi->rect.width(), 2); + p->fillRect(separatorRect, qt_mac_toQColor(separatorColor)); + break; + } + + const int maxpmw = mi->maxIconWidth; + const bool enabled = mi->state & State_Enabled; + + int xpos = mi->rect.x() + 18; + int checkcol = maxpmw; + if (!enabled) + p->setPen(mi->palette.text().color()); + else if (active) + p->setPen(mi->palette.highlightedText().color()); + else + p->setPen(mi->palette.buttonText().color()); + + if (mi->checked) { + QStyleOption checkmarkOpt; +// checkmarkOpt.initFrom(w); + + const int mw = checkcol + macItemFrame; + const int mh = mi->rect.height() + macItemFrame; + const int xp = mi->rect.x() + macItemFrame; + checkmarkOpt.rect = QRect(xp, mi->rect.y() - checkmarkOpt.fontMetrics.descent(), mw, mh); + + checkmarkOpt.state.setFlag(State_On, active); + checkmarkOpt.state.setFlag(State_Enabled, enabled); + if (widgetSize == QStyleHelper::SizeMini) + checkmarkOpt.state |= State_Mini; + else if (widgetSize == QStyleHelper::SizeSmall) + checkmarkOpt.state |= State_Small; + + // We let drawPrimitive(PE_IndicatorMenuCheckMark) pick the right color + checkmarkOpt.palette.setColor(QPalette::HighlightedText, p->pen().color()); + checkmarkOpt.palette.setColor(QPalette::Text, p->pen().color()); + + proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &checkmarkOpt, p); + } + if (!mi->icon.isNull()) { + QIcon::Mode mode = (mi->state & State_Enabled) ? QIcon::Normal + : QIcon::Disabled; + // Always be normal or disabled to follow the Mac style. + int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize); + QSize iconSize(smallIconSize, smallIconSize); +//#if QT_CONFIG(combobox) +// if (const QComboBox *comboBox = qobject_cast<const QComboBox *>(w)) { +// iconSize = comboBox->iconSize(); +// } +//#endif + QPixmap pixmap = mi->icon.pixmap(opt->window, iconSize, mode); + int pixw = pixmap.width() / pixmap.devicePixelRatio(); + int pixh = pixmap.height() / pixmap.devicePixelRatio(); + QRect cr(xpos, mi->rect.y(), checkcol, mi->rect.height()); + QRect pmr(0, 0, pixw, pixh); + pmr.moveCenter(cr.center()); + p->drawPixmap(pmr.topLeft(), pixmap); + xpos += pixw + 6; + } + + QString s = mi->text; + const auto text_flags = Qt::AlignVCenter | Qt::TextHideMnemonic + | Qt::TextSingleLine | Qt::AlignAbsolute; + int yPos = mi->rect.y(); + if (widgetSize == QStyleHelper::SizeMini) + yPos += 1; + + const bool isSubMenu = mi->menuItemType == QStyleOptionMenuItem::SubMenu; + const int tabwidth = isSubMenu ? 9 : mi->tabWidth; + + QString rightMarginText; + if (isSubMenu) + rightMarginText = QStringLiteral("\u25b6\ufe0e"); // U+25B6 U+FE0E: BLACK RIGHT-POINTING TRIANGLE + + // If present, save and remove embedded shorcut from text + const int tabIndex = s.indexOf(QLatin1Char('\t')); + if (tabIndex >= 0) { + if (!isSubMenu) // ... but ignore it if it's a submenu. + rightMarginText = s.mid(tabIndex + 1); + s = s.left(tabIndex); + } + + p->save(); + if (!rightMarginText.isEmpty()) { +// p->setFont(qt_app_fonts_hash()->value("QMenuItem", p->font())); + int xp = mi->rect.right() - tabwidth - macRightBorder + 2; + if (!isSubMenu) + xp -= macItemHMargin + macItemFrame + 3; // Adjust for shortcut + p->drawText(xp, yPos, tabwidth, mi->rect.height(), text_flags | Qt::AlignRight, rightMarginText); + } + + if (!s.isEmpty()) { + const int xm = macItemFrame + maxpmw + macItemHMargin; + QFont myFont = mi->font; + // myFont may not have any "hard" flags set. We override + // the point size so that when it is resolved against the device, this font will win. + // This is mainly to handle cases where someone sets the font on the window + // and then the combo inherits it and passes it onward. At that point the resolve mask + // is very, very weak. This makes it stonger. + myFont.setPointSizeF(QFontInfo(mi->font).pointSizeF()); + + // QTBUG-65653: Our own text rendering doesn't look good enough, especially on non-retina + // displays. Worked around here while waiting for a proper fix in QCoreTextFontEngine. + // Only if we're not using QCoreTextFontEngine we do fallback to our own text rendering. + const auto *fontEngine = QFontPrivate::get(myFont)->engineForScript(QChar::Script_Common); + Q_ASSERT(fontEngine); + if (fontEngine->type() == QFontEngine::Multi) { + fontEngine = static_cast<const QFontEngineMulti *>(fontEngine)->engine(0); + Q_ASSERT(fontEngine); + } + if (fontEngine->type() == QFontEngine::Mac) { + NSFont *f = (NSFont *)(CTFontRef)fontEngine->handle(); + + // Respect the menu item palette as set in the style option. + const auto pc = p->pen().color(); + NSColor *c = [NSColor colorWithSRGBRed:pc.redF() + green:pc.greenF() + blue:pc.blueF() + alpha:pc.alphaF()]; + + s = qt_mac_removeMnemonics(s); + + QMacCGContext cgCtx(p); + d->setupNSGraphicsContext(cgCtx, YES); + + // Draw at point instead of in rect, as the rect we've computed for the menu item + // is based on the font metrics we got from HarfBuzz, so we may risk having CoreText + // line-break the string if it doesn't fit the given rect. It's better to draw outside + // the rect and possibly overlap something than to have part of the text disappear. + [s.toNSString() drawAtPoint:CGPointMake(xpos, yPos) + withAttributes:@{ NSFontAttributeName:f, NSForegroundColorAttributeName:c, + NSObliquenessAttributeName: [NSNumber numberWithDouble: myFont.italic() ? 0.3 : 0.0]}]; + + d->restoreNSGraphicsContext(cgCtx); + } else { + p->setFont(myFont); + p->drawText(xpos, yPos, mi->rect.width() - xm - tabwidth + 1, + mi->rect.height(), text_flags, s); + } + } + p->restore(); + } + break; + case CE_MenuBarItem: + case CE_MenuBarEmptyArea: + if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { + const bool selected = (opt->state & State_Selected) && (opt->state & State_Enabled) && (opt->state & State_Sunken); + const QBrush bg = selected ? mi->palette.highlight() : mi->palette.window(); + p->fillRect(mi->rect, bg); + + if (ce != CE_MenuBarItem) + break; + + if (!mi->icon.isNull()) { + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + drawItemPixmap(p, mi->rect, + Qt::AlignCenter | Qt::TextHideMnemonic | Qt::TextDontClip + | Qt::TextSingleLine, + mi->icon.pixmap(opt->window, QSize(iconExtent, iconExtent), + (mi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled)); + } else { + drawItemText(p, mi->rect, + Qt::AlignCenter | Qt::TextHideMnemonic | Qt::TextDontClip + | Qt::TextSingleLine, + mi->palette, mi->state & State_Enabled, + mi->text, selected ? QPalette::HighlightedText : QPalette::ButtonText); + } + } + break; + case CE_ProgressBarLabel: + case CE_ProgressBarContents: + break; + case CE_ProgressBarGroove: + if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) { + const bool isIndeterminate = (pb->minimum == 0 && pb->maximum == 0); + const bool inverted = pb->invertedAppearance; + bool reverse = pb->direction == Qt::RightToLeft; + if (inverted) + reverse = !reverse; + + QRect rect = pb->rect; + const CGRect cgRect = rect.toCGRect(); + + const auto aquaSize = d->aquaSizeConstrain(opt); + +// const QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(d->animation(opt->styleObject)); + QIndeterminateProgressIndicator *ipi = nil; +// if (isIndeterminate || animation) + ipi = static_cast<QIndeterminateProgressIndicator *>(d->cocoaControl({ QMacStylePrivate::ProgressIndicator_Indeterminate, aquaSize })); + if (isIndeterminate) { + // QIndeterminateProgressIndicator derives from NSProgressIndicator. We use a single + // instance that we start animating as soon as one of the progress bars is indeterminate. + // Since they will be in sync (as it's the case in Cocoa), we just need to draw it with + // the right geometry when the animation triggers an update. However, we can't hide it + // entirely between frames since that would stop the animation, so we just set its alpha + // value to 0. Same if we remove it from its superview. See QIndeterminateProgressIndicator + // implementation for details. + // + // Quick: consider implementing this animation by using Quick/QML instead. + // +// if (!animation && opt->styleObject) { +// auto *animation = new QProgressStyleAnimation(d->animateSpeed(QMacStylePrivate::AquaProgressBar), opt->styleObject); +// // NSProgressIndicator is heavier to draw than the HITheme API, so we reduce the frame rate a couple notches. +// animation->setFrameRate(QStyleAnimation::FifteenFps); +// d->startAnimation(animation); +// [ipi startAnimation]; +// } + + d->setupNSGraphicsContext(cg, NO); + d->setupVerticalInvertedXform(cg, reverse, false, cgRect); + [ipi drawWithFrame:cgRect inView:d->backingStoreNSView]; + d->restoreNSGraphicsContext(cg); + } else { +// if (animation) { +// d->stopAnimation(opt->styleObject); +// [ipi stopAnimation]; +// } + + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::ProgressIndicator_Determinate, aquaSize); + auto *pi = static_cast<NSProgressIndicator *>(d->cocoaControl(cw)); + d->drawNSViewInRect(pi, rect, p, ^(CGContextRef ctx, const CGRect &rect) { + QMacAutoReleasePool pool; + d->setupVerticalInvertedXform(ctx, reverse, false, rect); + pi.minValue = pb->minimum; + pi.maxValue = pb->maximum; + pi.doubleValue = pb->progress; + [pi drawRect:rect]; + }); + } + } + break; + case CE_SizeGrip: { + // This is not HIG kosher: Fall back to the old stuff until we decide what to do. +//#ifndef QT_NO_MDIAREA +// if (!w || !qobject_cast<QMdiSubWindow *>(w->parentWidget())) +//#endif +// break; + +// if (w->testAttribute(Qt::WA_MacOpaqueSizeGrip)) +// p->fillRect(opt->rect, opt->palette.window()); + +// QPen lineColor = QColor(82, 82, 82, 192); +// lineColor.setWidth(1); +// p->save(); +// p->setRenderHint(QPainter::Antialiasing); +// p->setPen(lineColor); +// const Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : qApp->layoutDirection(); +// const int NumLines = 3; +// for (int l = 0; l < NumLines; ++l) { +// const int offset = (l * 4 + 3); +// QPoint start, end; +// if (layoutDirection == Qt::LeftToRight) { +// start = QPoint(opt->rect.width() - offset, opt->rect.height() - 1); +// end = QPoint(opt->rect.width() - 1, opt->rect.height() - offset); +// } else { +// start = QPoint(offset, opt->rect.height() - 1); +// end = QPoint(1, opt->rect.height() - offset); +// } +// p->drawLine(start, end); +// } +// p->restore(); + break; + } + case CE_Splitter: + if (opt->rect.width() > 1 && opt->rect.height() > 1) { + const bool isVertical = !(opt->state & QStyle::State_Horizontal); + // Qt refers to the layout orientation, while Cocoa refers to the divider's. + const auto ct = isVertical ? QMacStylePrivate::SplitView_Horizontal : QMacStylePrivate::SplitView_Vertical; + const auto cw = QMacStylePrivate::CocoaControl(ct, QStyleHelper::SizeLarge); + auto *sv = static_cast<NSSplitView *>(d->cocoaControl(cw)); + sv.frame = opt->rect.toCGRect(); + d->drawNSViewInRect(sv, opt->rect, p, ^(CGContextRef, const CGRect &rect) { + QMacAutoReleasePool pool; + [sv drawDividerInRect:rect]; + }); + } else { + QPen oldPen = p->pen(); + p->setPen(opt->palette.dark().color()); + if (opt->state & QStyle::State_Horizontal) + p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft()); + else + p->drawLine(opt->rect.topLeft(), opt->rect.topRight()); + p->setPen(oldPen); + } + break; + case CE_RubberBand: + if (const QStyleOptionRubberBand *rubber = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) { + QColor fillColor(opt->palette.color(QPalette::Disabled, QPalette::Highlight)); + if (!rubber->opaque) { + QColor strokeColor; + // I retrieved these colors from the Carbon-Dev mailing list + strokeColor.setHsvF(0, 0, 0.86, 1.0); + fillColor.setHsvF(0, 0, 0.53, 0.25); + if (opt->rect.width() * opt->rect.height() <= 3) { + p->fillRect(opt->rect, strokeColor); + } else { + QPen oldPen = p->pen(); + QBrush oldBrush = p->brush(); + QPen pen(strokeColor); + p->setPen(pen); + p->setBrush(fillColor); + QRect adjusted = opt->rect.adjusted(1, 1, -1, -1); + if (adjusted.isValid()) + p->drawRect(adjusted); + p->setPen(oldPen); + p->setBrush(oldBrush); + } + } else { + p->fillRect(opt->rect, fillColor); + } + } + break; + case CE_ToolBar: { + const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(opt); + const bool isDarkMode = qt_mac_applicationIsInDarkMode(); + + // Unified title and toolbar drawing. In this mode the cocoa platform plugin will + // fill the top toolbar area part with a background gradient that "unifies" with + // the title bar. The following code fills the toolBar area with transparent pixels + // to make that gradient visible. +// if (w) { +//#if QT_CONFIG(mainwindow) +// if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(w->window())) { +// if (toolBar && toolBar->toolBarArea == Qt::TopToolBarArea && mainWindow->unifiedTitleAndToolBarOnMac()) { +// // fill with transparent pixels. +// p->save(); +// p->setCompositionMode(QPainter::CompositionMode_Source); +// p->fillRect(opt->rect, Qt::transparent); +// p->restore(); + +// // Draw a horizontal separator line at the toolBar bottom if the "unified" area ends here. +// // There might be additional toolbars or other widgets such as tab bars in document +// // mode below. Determine this by making a unified toolbar area test for the row below +// // this toolbar. +// const QPoint windowToolbarEnd = w->mapTo(w->window(), opt->rect.bottomLeft()); +// const bool isEndOfUnifiedArea = !isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowToolbarEnd.y() + 1); +// if (isEndOfUnifiedArea) { +// const int margin = qt_mac_aqua_get_metric(SeparatorSize); +// const auto separatorRect = QRect(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin); +// p->fillRect(separatorRect, isDarkMode ? darkModeSeparatorLine : opt->palette.dark().color()); +// } +// break; +// } +// } +//#endif +// } + + // draw background gradient + QLinearGradient linearGrad; + if (opt->state & State_Horizontal) + linearGrad = QLinearGradient(0, opt->rect.top(), 0, opt->rect.bottom()); + else + linearGrad = QLinearGradient(opt->rect.left(), 0, opt->rect.right(), 0); + + QColor mainWindowGradientBegin = isDarkMode ? darkMainWindowGradientBegin : lightMainWindowGradientBegin; + QColor mainWindowGradientEnd = isDarkMode ? darkMainWindowGradientEnd : lightMainWindowGradientEnd; + + linearGrad.setColorAt(0, mainWindowGradientBegin); + linearGrad.setColorAt(1, mainWindowGradientEnd); + p->fillRect(opt->rect, linearGrad); + + p->save(); + QRect toolbarRect = isDarkMode ? opt->rect.adjusted(0, 0, 0, 1) : opt->rect; + if (opt->state & State_Horizontal) { + p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientBegin.lighter(114)); + p->drawLine(toolbarRect.topLeft(), toolbarRect.topRight()); + p->setPen(isDarkMode ? darkModeSeparatorLine :mainWindowGradientEnd.darker(114)); + p->drawLine(toolbarRect.bottomLeft(), toolbarRect.bottomRight()); + } else { + p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientBegin.lighter(114)); + p->drawLine(toolbarRect.topLeft(), toolbarRect.bottomLeft()); + p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientEnd.darker(114)); + p->drawLine(toolbarRect.topRight(), toolbarRect.bottomRight()); + } + p->restore(); + + break; } + default: + QCommonStyle::drawControl(ce, opt, p); + break; + } +} + +static void setLayoutItemMargins(int left, int top, int right, int bottom, QRect *rect, Qt::LayoutDirection dir) +{ + if (dir == Qt::RightToLeft) { + rect->adjust(-right, top, -left, bottom); + } else { + rect->adjust(left, top, right, bottom); + } +} + +QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt) const +{ + Q_D(const QMacStyle); + QRect rect; + const int controlSize = getControlSize(opt); + + switch (sr) { + case SE_ItemViewItemText: + if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { + int fw = proxy()->pixelMetric(PM_FocusFrameHMargin, opt); + // We add the focusframeargin between icon and text in commonstyle + rect = QCommonStyle::subElementRect(sr, opt); + if (vopt->features & QStyleOptionViewItem::HasDecoration) + rect.adjust(-fw, 0, 0, 0); + } + break; + case SE_ToolBoxTabContents: + rect = QCommonStyle::subElementRect(sr, opt); + break; + case SE_PushButtonContents: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + // Comment from the old HITheme days: + // "Unlike Carbon, we want the button to always be drawn inside its bounds. + // Therefore, the button is a bit smaller, so that even if it got focus, + // the focus 'shadow' will be inside. Adjust the content rect likewise." + // In the future, we should consider using -[NSCell titleRectForBounds:]. + // Since it requires configuring the NSButton fully, i.e. frame, image, + // title and font, we keep things more manual until we are more familiar + // with side effects when changing NSButton state. + const auto ct = cocoaControlType(btn); + const auto cs = d->effectiveAquaSizeConstrain(btn); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); + auto frameRect = cw.adjustedControlFrame(btn->rect); + frameRect -= cw.titleMargins(); + rect = frameRect.toRect(); + } + break; + case SE_HeaderLabel: { + int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt); + rect.setRect(opt->rect.x() + margin, opt->rect.y(), + opt->rect.width() - margin * 2, opt->rect.height() - 2); + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { + // Subtract width needed for arrow, if there is one + if (header->sortIndicator != QStyleOptionHeader::None) { + if (opt->state & State_Horizontal) + rect.setWidth(rect.width() - (headerSectionArrowHeight) - (margin * 2)); + else + rect.setHeight(rect.height() - (headerSectionArrowHeight) - (margin * 2)); + } + } + rect = visualRect(opt->direction, opt->rect, rect); + break; + } + case SE_HeaderArrow: { + int h = opt->rect.height(); + int w = opt->rect.width(); + int x = opt->rect.x(); + int y = opt->rect.y(); + int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt); + + if (opt->state & State_Horizontal) { + rect.setRect(x + w - margin * 2 - headerSectionArrowHeight, y + 5, + headerSectionArrowHeight, h - margin * 2 - 5); + } else { + rect.setRect(x + 5, y + h - margin * 2 - headerSectionArrowHeight, + w - margin * 2 - 5, headerSectionArrowHeight); + } + rect = visualRect(opt->direction, opt->rect, rect); + break; + } + case SE_ProgressBarGroove: + // Wrong in the secondary dimension, but accurate enough in the main dimension. + rect = opt->rect; + break; + case SE_ProgressBarLabel: + break; + case SE_ProgressBarContents: + rect = opt->rect; + break; + case SE_TreeViewDisclosureItem: { + rect = opt->rect; + // As previously returned by HIThemeGetButtonContentBounds + rect.setLeft(rect.left() + 2 + DisclosureOffset); + break; + } + case SE_TabWidgetLeftCorner: + if (const QStyleOptionTabWidgetFrame *twf + = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { + switch (twf->shape) { + case QStyleOptionTab::RoundedNorth: + case QStyleOptionTab::TriangularNorth: + rect = QRect(QPoint(0, 0), twf->leftCornerWidgetSize); + break; + case QStyleOptionTab::RoundedSouth: + case QStyleOptionTab::TriangularSouth: + rect = QRect(QPoint(0, twf->rect.height() - twf->leftCornerWidgetSize.height()), + twf->leftCornerWidgetSize); + break; + default: + break; + } + rect = visualRect(twf->direction, twf->rect, rect); + } + break; + case SE_TabWidgetRightCorner: + if (const QStyleOptionTabWidgetFrame *twf + = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { + switch (twf->shape) { + case QStyleOptionTab::RoundedNorth: + case QStyleOptionTab::TriangularNorth: + rect = QRect(QPoint(twf->rect.width() - twf->rightCornerWidgetSize.width(), 0), + twf->rightCornerWidgetSize); + break; + case QStyleOptionTab::RoundedSouth: + case QStyleOptionTab::TriangularSouth: + rect = QRect(QPoint(twf->rect.width() - twf->rightCornerWidgetSize.width(), + twf->rect.height() - twf->rightCornerWidgetSize.height()), + twf->rightCornerWidgetSize); + break; + default: + break; + } + rect = visualRect(twf->direction, twf->rect, rect); + } + break; + case SE_TabWidgetTabContents: + rect = QCommonStyle::subElementRect(sr, opt); + if (const auto *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { + if (twf->lineWidth != 0) { + switch (QMacStylePrivate::tabDirection(twf->shape)) { + case QMacStylePrivate::North: + rect.adjust(+1, +14, -1, -1); + break; + case QMacStylePrivate::South: + rect.adjust(+1, +1, -1, -14); + break; + case QMacStylePrivate::West: + rect.adjust(+14, +1, -1, -1); + break; + case QMacStylePrivate::East: + rect.adjust(+1, +1, -14, -1); + } + } + } + break; + case SE_TabBarTabText: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + QRect dummyIconRect; + d->tabLayout(tab, &rect, &dummyIconRect); + } + break; + case SE_TabBarTabLeftButton: + case SE_TabBarTabRightButton: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + bool selected = tab->state & State_Selected; + int verticalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab); + int horizontalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab); + int hpadding = 5; + + bool verticalTabs = tab->shape == QStyleOptionTab::RoundedEast + || tab->shape == QStyleOptionTab::RoundedWest + || tab->shape == QStyleOptionTab::TriangularEast + || tab->shape == QStyleOptionTab::TriangularWest; + + QRect tr = tab->rect; + if (tab->shape == QStyleOptionTab::RoundedSouth || tab->shape == QStyleOptionTab::TriangularSouth) + verticalShift = -verticalShift; + if (verticalTabs) { + qSwap(horizontalShift, verticalShift); + horizontalShift *= -1; + verticalShift *= -1; + } + if (tab->shape == QStyleOptionTab::RoundedWest || tab->shape == QStyleOptionTab::TriangularWest) + horizontalShift = -horizontalShift; + + tr.adjust(0, 0, horizontalShift, verticalShift); + if (selected) + { + tr.setBottom(tr.bottom() - verticalShift); + tr.setRight(tr.right() - horizontalShift); + } + + QSize size = (sr == SE_TabBarTabLeftButton) ? tab->leftButtonSize : tab->rightButtonSize; + int w = size.width(); + int h = size.height(); + int midHeight = static_cast<int>(qCeil(float(tr.height() - h) / 2)); + int midWidth = ((tr.width() - w) / 2); + + bool atTheTop = true; + switch (tab->shape) { + case QStyleOptionTab::RoundedWest: + case QStyleOptionTab::TriangularWest: + atTheTop = (sr == SE_TabBarTabLeftButton); + break; + case QStyleOptionTab::RoundedEast: + case QStyleOptionTab::TriangularEast: + atTheTop = (sr == SE_TabBarTabRightButton); + break; + default: + if (sr == SE_TabBarTabLeftButton) + rect = QRect(tab->rect.x() + hpadding, midHeight, w, h); + else + rect = QRect(tab->rect.right() - w - hpadding, midHeight, w, h); + rect = visualRect(tab->direction, tab->rect, rect); + } + if (verticalTabs) { + if (atTheTop) + rect = QRect(midWidth, tr.y() + tab->rect.height() - hpadding - h, w, h); + else + rect = QRect(midWidth, tr.y() + hpadding, w, h); + } + } + break; + case SE_LineEditContents: { + // From using pixelTool with XCode/NSTextTextField + int leftPadding = 4; + int rightPadding = 4; + int topPadding = 4; + int bottomPadding = 0; + + if (opt->state & QStyle::State_Small) { + topPadding = 3; + } else if (opt->state & QStyle::State_Mini) { + topPadding = 2; + } + + rect = QRect(leftPadding, topPadding, opt->rect.width() - leftPadding - rightPadding, + opt->rect.height() - topPadding - bottomPadding); + break; } + case SE_CheckBoxLayoutItem: + rect = opt->rect; + if (controlSize == QStyleHelper::SizeLarge) { + setLayoutItemMargins(+2, +2, -3, -2, &rect, opt->direction); + } else if (controlSize == QStyleHelper::SizeSmall) { + setLayoutItemMargins(+1, +2, -2, -1, &rect, opt->direction); + } else { + setLayoutItemMargins(-0, +0, -1, -0, &rect, opt->direction); + } + break; + case SE_ComboBoxLayoutItem: + if (const auto *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + //#ifndef QT_NO_TOOLBAR + // if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) { + // // Do nothing, because QToolbar needs the entire widget rect. + // // Otherwise it will be clipped. Equivalent to + // // widget->setAttribute(Qt::WA_LayoutUsesWidgetRect), but without + // // all the hassle. + // } else + //#endif + if (combo->editable) + rect = LargeSmallMini(opt, + opt->rect.adjusted(5, 6, -6, -7), + opt->rect.adjusted(4, 4, -5, -7), + opt->rect.adjusted(5, 4, -4, -6)); + else + rect = LargeSmallMini(opt, + opt->rect.adjusted(6, 4, -7, -7), + opt->rect.adjusted(6, 7, -6, -5), + opt->rect.adjusted(9, 5, -5, -7)); + } + break; + case SE_LabelLayoutItem: + rect = opt->rect; + setLayoutItemMargins(+1, 0 /* SHOULD be -1, done for alignment */, 0, 0 /* SHOULD be -1, done for alignment */, &rect, opt->direction); + break; + case SE_ProgressBarLayoutItem: + if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) { + const bool isIndeterminate = (pb->minimum == 0 && pb->maximum == 0); + rect = opt->rect; + + if (isIndeterminate) { + rect.adjust(1, 2, -1, -2); + } else { + rect.adjust(1, 1, -1, -2); + } + } + break; + case SE_PushButtonLayoutItem: + rect = opt->rect; + if (const QStyleOptionButton *buttonOpt = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + if ((buttonOpt->features & QStyleOptionButton::Flat)) + break; + } + rect = LargeSmallMini(opt, + opt->rect.adjusted(7, 5, -7, -7), + opt->rect.adjusted(6, 6, -6, -6), + opt->rect.adjusted(6, 5, -6, -6)); + break; + case SE_SpinBoxLayoutItem: + rect = LargeSmallMini(opt, + opt->rect.adjusted(2, 3, -2, -2), + opt->rect.adjusted(2, 3, -2, -2), + opt->rect.adjusted(2, 3, -2, -2)); + break; + case SE_RadioButtonLayoutItem: + rect = LargeSmallMini(opt, + opt->rect.adjusted(2, 2, -3, -2), + opt->rect.adjusted(2, 2, -3, -2), + opt->rect.adjusted(1, 2, -3, -2)); + break; + case SE_SliderLayoutItem: + if (const QStyleOptionSlider *sliderOpt + = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + rect = opt->rect; + if (sliderOpt->subControls & QStyle::SC_SliderHandle) { + if (sliderOpt->tickPosition == QStyleOptionSlider::NoTicks) + rect.adjust(3, 3, -3, -3); + } else { + rect.adjust(3, 0, -3, 0); + } + } + break; + case SE_ScrollBarLayoutItem: + if (const QStyleOptionSlider *sliderOpt = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + rect = opt->rect; + } + case SE_FrameLayoutItem: + // hack because QStyleOptionFrame doesn't have a frameStyle member +// if (const QFrame *frame = qobject_cast<const QFrame *>(widget)) { +// rect = opt->rect; +// switch (frame->frameStyle() & QFrame::Shape_Mask) { +// case QFrame::HLine: +// rect.adjust(0, +1, 0, -1); +// break; +// case QFrame::VLine: +// rect.adjust(+1, 0, -1, 0); +// break; +// default: +// ; +// } +// } + break; + case SE_GroupBoxLayoutItem: + rect = opt->rect; + if (const QStyleOptionGroupBox *groupBoxOpt = + qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) { + /* + AHIG is very inconsistent when it comes to group boxes. + Basically, we make sure that (non-checkable) group boxes + and tab widgets look good when laid out side by side. + */ + if (groupBoxOpt->subControls & (QStyle::SC_GroupBoxCheckBox + | QStyle::SC_GroupBoxLabel)) { + int delta; + if (groupBoxOpt->subControls & QStyle::SC_GroupBoxCheckBox) { + delta = SIZE(8, 4, 4); // guess + } else { + delta = SIZE(15, 12, 12); // guess + } + rect.setTop(rect.top() + delta); + } + } + rect.setBottom(rect.bottom() - 1); + break; + case SE_TabWidgetLayoutItem: + if (const QStyleOptionTabWidgetFrame *tabWidgetOpt = + qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { + /* + AHIG specifies "12 or 14" as the distance from the window + edge. We choose 14 and since the default top margin is 20, + the overlap is 6. + */ + rect = tabWidgetOpt->rect; + if (tabWidgetOpt->shape == QStyleOptionTab::RoundedNorth) + rect.setTop(rect.top() + SIZE(6 /* AHIG */, 3 /* guess */, 2 /* AHIG */)); + } + break; + case SE_DockWidgetCloseButton: + case SE_DockWidgetFloatButton: + case SE_DockWidgetTitleBarText: + case SE_DockWidgetIcon: { + int iconSize = proxy()->pixelMetric(PM_SmallIconSize, opt); + int buttonMargin = proxy()->pixelMetric(PM_DockWidgetTitleBarButtonMargin, opt); + QRect srect = opt->rect; + + const QStyleOptionDockWidget *dwOpt + = qstyleoption_cast<const QStyleOptionDockWidget*>(opt); + bool canClose = dwOpt == 0 ? true : dwOpt->closable; + bool canFloat = dwOpt == 0 ? false : dwOpt->floatable; + + const bool verticalTitleBar = dwOpt->verticalTitleBar; + + // If this is a vertical titlebar, we transpose and work as if it was + // horizontal, then transpose again. + if (verticalTitleBar) + srect = srect.transposed(); + + do { + int right = srect.right(); + int left = srect.left(); + + QRect closeRect; + if (canClose) { + QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, + opt).actualSize(QSize(iconSize, iconSize)); + sz += QSize(buttonMargin, buttonMargin); + if (verticalTitleBar) + sz = sz.transposed(); + closeRect = QRect(left, + srect.center().y() - sz.height()/2, + sz.width(), sz.height()); + left = closeRect.right() + 1; + } + if (sr == SE_DockWidgetCloseButton) { + rect = closeRect; + break; + } + + QRect floatRect; + if (canFloat) { + QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarNormalButton, + opt).actualSize(QSize(iconSize, iconSize)); + sz += QSize(buttonMargin, buttonMargin); + if (verticalTitleBar) + sz = sz.transposed(); + floatRect = QRect(left, + srect.center().y() - sz.height()/2, + sz.width(), sz.height()); + left = floatRect.right() + 1; + } + if (sr == SE_DockWidgetFloatButton) { + rect = floatRect; + break; + } + + QRect iconRect; +// if (const QDockWidget *dw = qobject_cast<const QDockWidget*>(widget)) { +// QIcon icon; +// if (dw->isFloating()) +// icon = dw->windowIcon(); +// if (!icon.isNull() +// && icon.cacheKey() != QApplication::windowIcon().cacheKey()) { +// QSize sz = icon.actualSize(QSize(rect.height(), rect.height())); +// if (verticalTitleBar) +// sz = sz.transposed(); +// iconRect = QRect(right - sz.width(), srect.center().y() - sz.height()/2, +// sz.width(), sz.height()); +// right = iconRect.left() - 1; +// } +// } + if (sr == SE_DockWidgetIcon) { + rect = iconRect; + break; + } + + QRect textRect = QRect(left, srect.top(), + right - left, srect.height()); + if (sr == SE_DockWidgetTitleBarText) { + rect = textRect; + break; + } + } while (false); + + if (verticalTitleBar) { + rect = QRect(srect.left() + rect.top() - srect.top(), + srect.top() + srect.right() - rect.right(), + rect.height(), rect.width()); + } else { + rect = visualRect(opt->direction, srect, rect); + } + break; + } + default: + rect = QCommonStyle::subElementRect(sr, opt); + break; + } + return rect; +} + +void QMacStylePrivate::drawToolbarButtonArrow(const QStyleOption *opt, QPainter *p) const +{ + Q_Q(const QMacStyle); + QStyleOption arrowOpt = *opt; + arrowOpt.rect = QRect(opt->rect.right() - (toolButtonArrowSize + toolButtonArrowMargin), + opt->rect.bottom() - (toolButtonArrowSize + toolButtonArrowMargin), + toolButtonArrowSize, + toolButtonArrowSize); + q->proxy()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &arrowOpt, p); +} + +void QMacStylePrivate::setupNSGraphicsContext(CGContextRef cg, bool flipped) const +{ + CGContextSaveGState(cg); + [NSGraphicsContext saveGraphicsState]; + + [NSGraphicsContext setCurrentContext: + [NSGraphicsContext graphicsContextWithCGContext:cg flipped:flipped]]; +} + +void QMacStylePrivate::restoreNSGraphicsContext(CGContextRef cg) const +{ + [NSGraphicsContext restoreGraphicsState]; + CGContextRestoreGState(cg); +} + +void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p) const +{ + Q_D(const QMacStyle); + const AppearanceSync sync; + + QMacCGContext cg(p); + d->resolveCurrentNSView(opt->window); + + switch (cc) { + case CC_ScrollBar: + if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + + const bool drawTrack = sb->subControls & SC_ScrollBarGroove; + const bool drawKnob = sb->subControls & SC_ScrollBarSlider; + if (!drawTrack && !drawKnob) + break; + + const bool isHorizontal = sb->orientation == Qt::Horizontal; + + if (opt && opt->styleObject && !QMacStylePrivate::scrollBars.contains(opt->styleObject)) + QMacStylePrivate::scrollBars.append(QPointer<QObject>(opt->styleObject)); + + static const CGFloat knobWidths[] = { 7.0, 5.0, 5.0 }; + static const CGFloat expandedKnobWidths[] = { 11.0, 9.0, 9.0 }; + const auto cocoaSize = d->effectiveAquaSizeConstrain(opt); + const CGFloat maxExpandScale = expandedKnobWidths[cocoaSize] / knobWidths[cocoaSize]; + + const bool isTransient = proxy()->styleHint(SH_ScrollBar_Transient, opt); +// if (!isTransient) +// d->stopAnimation(opt->styleObject); + bool wasActive = false; + CGFloat opacity = 0.0; + CGFloat expandScale = 1.0; + CGFloat expandOffset = 0.0; + bool shouldExpand = false; + + if (QObject *styleObject = opt->styleObject) { + const int oldPos = styleObject->property("_q_stylepos").toInt(); + const int oldMin = styleObject->property("_q_stylemin").toInt(); + const int oldMax = styleObject->property("_q_stylemax").toInt(); + const QRect oldRect = styleObject->property("_q_stylerect").toRect(); + const QStyle::State oldState = static_cast<QStyle::State>(styleObject->property("_q_stylestate").value<QStyle::State::Int>()); + const uint oldActiveControls = styleObject->property("_q_stylecontrols").toUInt(); + + // a scrollbar is transient when the scrollbar itself and + // its sibling are both inactive (ie. not pressed/hovered/moved) + const bool transient = isTransient && !opt->activeSubControls && !(sb->state & State_On); + + if (!transient || + oldPos != sb->sliderPosition || + oldMin != sb->minimum || + oldMax != sb->maximum || + oldRect != sb->rect || + oldState != sb->state || + oldActiveControls != sb->activeSubControls) { + + // if the scrollbar is transient or its attributes, geometry or + // state has changed, the opacity is reset back to 100% opaque + opacity = 1.0; + + styleObject->setProperty("_q_stylepos", sb->sliderPosition); + styleObject->setProperty("_q_stylemin", sb->minimum); + styleObject->setProperty("_q_stylemax", sb->maximum); + styleObject->setProperty("_q_stylerect", sb->rect); + styleObject->setProperty("_q_stylestate", static_cast<QStyle::State::Int>(sb->state)); + styleObject->setProperty("_q_stylecontrols", static_cast<uint>(sb->activeSubControls)); + +// QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject)); +// if (transient) { +// if (!anim) { +// anim = new QScrollbarStyleAnimation(QScrollbarStyleAnimation::Deactivating, styleObject); +// d->startAnimation(anim); +// } else if (anim->mode() == QScrollbarStyleAnimation::Deactivating) { +// // the scrollbar was already fading out while the +// // state changed -> restart the fade out animation +// anim->setCurrentTime(0); +// } +// } else if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) { +// d->stopAnimation(styleObject); +// } + } + +// QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject)); +// if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) { +// // once a scrollbar was active (hovered/pressed), it retains +// // the active look even if it's no longer active while fading out +// if (oldActiveControls) +// anim->setActive(true); + +// wasActive = anim->wasActive(); +// opacity = anim->currentValue(); +// } + + shouldExpand = isTransient && (opt->activeSubControls || wasActive); + if (shouldExpand) { +// if (!anim && !oldActiveControls) { +// // Start expand animation only once and when entering +// anim = new QScrollbarStyleAnimation(QScrollbarStyleAnimation::Activating, styleObject); +// d->startAnimation(anim); +// } +// if (anim && anim->mode() == QScrollbarStyleAnimation::Activating) { +// expandScale = 1.0 + (maxExpandScale - 1.0) * anim->currentValue(); +// expandOffset = 5.5 * (1.0 - anim->currentValue()); +// } else { +// // Keep expanded state after the animation ends, and when fading out +// expandScale = maxExpandScale; +// expandOffset = 0.0; +// } + } + } + + d->setupNSGraphicsContext(cg, NO /* flipped */); + + const auto controlType = isHorizontal ? QMacStylePrivate::Scroller_Horizontal : QMacStylePrivate::Scroller_Vertical; + const auto cw = QMacStylePrivate::CocoaControl(controlType, cocoaSize); + NSScroller *scroller = static_cast<NSScroller *>(d->cocoaControl(cw)); + + const QColor bgColor = QStyleHelper::backgroundColor(opt->palette); + const bool hasDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128; + if (isTransient) { + // macOS behavior: as soon as one color channel is >= 128, + // the background is considered bright, scroller is dark. + scroller.knobStyle = hasDarkBg? NSScrollerKnobStyleLight : NSScrollerKnobStyleDark; + } else { + scroller.knobStyle = NSScrollerKnobStyleDefault; + } + + scroller.scrollerStyle = isTransient ? NSScrollerStyleOverlay : NSScrollerStyleLegacy; + + if (!setupScroller(scroller, sb)) + break; + + if (isTransient) { + CGContextBeginTransparencyLayerWithRect(cg, scroller.frame, nullptr); + CGContextSetAlpha(cg, opacity); + } + + if (drawTrack) { + // Draw the track when hovering. Expand by shifting the track rect. + if (!isTransient || opt->activeSubControls || wasActive) { + CGRect trackRect = scroller.bounds; + if (isHorizontal) + trackRect.origin.y += expandOffset; + else + trackRect.origin.x += expandOffset; + [scroller drawKnobSlotInRect:trackRect highlight:NO]; + } + } + + if (drawKnob) { + if (shouldExpand) { + // -[NSScroller drawKnob] is not useful here because any scaling applied + // will only be used to draw the hi-DPI artwork. And even if did scale, + // the stretched knob would look wrong, actually. So we need to draw the + // scroller manually when it's being hovered. + const CGFloat scrollerWidth = [NSScroller scrollerWidthForControlSize:scroller.controlSize scrollerStyle:scroller.scrollerStyle]; + const CGFloat knobWidth = knobWidths[cocoaSize] * expandScale; + // Cocoa can help get the exact knob length in the current orientation + const CGRect scrollerKnobRect = CGRectInset([scroller rectForPart:NSScrollerKnob], 1, 1); + const CGFloat knobLength = isHorizontal ? scrollerKnobRect.size.width : scrollerKnobRect.size.height; + const CGFloat knobPos = isHorizontal ? scrollerKnobRect.origin.x : scrollerKnobRect.origin.y; + const CGFloat knobOffset = qRound((scrollerWidth + expandOffset - knobWidth) / 2.0); + const CGFloat knobRadius = knobWidth / 2.0; + CGRect knobRect; + if (isHorizontal) + knobRect = CGRectMake(knobPos, knobOffset, knobLength, knobWidth); + else + knobRect = CGRectMake(knobOffset, knobPos, knobWidth, knobLength); + QCFType<CGPathRef> knobPath = CGPathCreateWithRoundedRect(knobRect, knobRadius, knobRadius, nullptr); + CGContextAddPath(cg, knobPath); + CGContextSetAlpha(cg, 0.5); + CGColorRef knobColor = hasDarkBg ? NSColor.whiteColor.CGColor : NSColor.blackColor.CGColor; + CGContextSetFillColorWithColor(cg, knobColor); + CGContextFillPath(cg); + } else { + [scroller drawKnob]; + + if (!isTransient && opt->state & State_Sunken) { + // The knob should appear darker (going from 0.76 down to 0.49). + // But no blending mode can help darken enough in a single pass, + // so we resort to drawing the knob twice with a small help from + // blending. This brings the gray level to a close enough 0.53. + CGContextSetBlendMode(cg, kCGBlendModePlusDarker); + [scroller drawKnob]; + } + } + } + + if (isTransient) + CGContextEndTransparencyLayer(cg); + + d->restoreNSGraphicsContext(cg); + } + break; + case CC_Slider: + if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + const bool isHorizontal = sl->orientation == Qt::Horizontal; + const auto ct = isHorizontal ? QMacStylePrivate::Slider_Horizontal : QMacStylePrivate::Slider_Vertical; + const auto cs = d->effectiveAquaSizeConstrain(opt); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); + auto *slider = static_cast<NSSlider *>(d->cocoaControl(cw)); + if (!setupSlider(slider, sl)) + break; + + const bool hasTicks = sl->tickPosition != QStyleOptionSlider::NoTicks; + const bool hasDoubleTicks = sl->tickPosition == QStyleOptionSlider::TicksBothSides; + const bool drawKnob = sl->subControls & SC_SliderHandle; + const bool drawBar = sl->subControls & SC_SliderGroove; + const bool drawTicks = sl->subControls & SC_SliderTickmarks; + const bool isPressed = sl->state & State_Sunken; + + CGPoint pressPoint; + if (isPressed && drawKnob) { + const CGRect knobRect = [slider.cell knobRectFlipped:slider.isFlipped]; + pressPoint.x = CGRectGetMidX(knobRect); + pressPoint.y = CGRectGetMidY(knobRect); + [slider.cell startTrackingAt:pressPoint inView:slider]; + } + + d->drawNSViewInRect(slider, opt->rect, p, ^(CGContextRef, const CGRect &) { + // Note that we don't support drawing the slider upside down. When this + // is needed, simply set scale = -1 on the QML control / style item instead. + NSSliderCell *cell = slider.cell; + + if (drawBar) { + const CGRect barRect = [cell barRectFlipped:slider.isFlipped]; + // "flipped" will only make a difference when NSSliderCell is vertical. And then + // flipped means fill the groove from bottom-to-top instead of top-to-bottom. + // Bottom-to-top is QSlider's normal mode, which means that we always need to flip + // in vertical mode. (In case NSSlider can also be flipped horizontally in the future, + // we stay on the safe side, and only flip when in vertical mode). + [cell drawBarInside:barRect flipped:!isHorizontal]; + } + + if (drawBar && hasTicks && drawTicks) { + if (!hasDoubleTicks) { + [cell drawTickMarks]; + } else { + if (sl->orientation == Qt::Horizontal) { + slider.tickMarkPosition = NSTickMarkPositionAbove; + [slider layoutSubtreeIfNeeded]; + [cell drawTickMarks]; + slider.tickMarkPosition = NSTickMarkPositionBelow; + [slider layoutSubtreeIfNeeded]; + [cell drawTickMarks]; + } else { + slider.tickMarkPosition = NSTickMarkPositionLeading; + [slider layoutSubtreeIfNeeded]; + [cell drawTickMarks]; + slider.tickMarkPosition = NSTickMarkPositionTrailing; + [slider layoutSubtreeIfNeeded]; + [cell drawTickMarks]; + } + } + } + + if (drawKnob) + [cell drawKnob]; + }); + + if (isPressed && drawKnob) + [slider.cell stopTracking:pressPoint at:pressPoint inView:slider mouseIsUp:NO]; + } + break; + case CC_SpinBox: + if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { + if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) { + const auto lineEditRect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxEditField); + QStyleOptionFrame frame; + static_cast<QStyleOption &>(frame) = *opt; + frame.rect = lineEditRect; + frame.state |= State_Sunken; + frame.lineWidth = 1; + frame.midLineWidth = 0; + frame.features = QStyleOptionFrame::None; + frame.frameShape = QStyleOptionFrame::Box; + drawPrimitive(PE_FrameLineEdit, &frame, p); + } + if (sb->subControls & (SC_SpinBoxUp | SC_SpinBoxDown)) { + const QRect updown = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp) + | proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown); + + d->setupNSGraphicsContext(cg, NO); + + const auto aquaSize = d->effectiveAquaSizeConstrain(opt); + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Stepper, aquaSize); + NSStepperCell *cell = static_cast<NSStepperCell *>(d->cocoaCell(cw)); + cell.enabled = (sb->state & State_Enabled); + + const CGRect newRect = [cell drawingRectForBounds:updown.toCGRect()]; + + const bool upPressed = sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken); + const bool downPressed = sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken); + const CGFloat x = CGRectGetMidX(newRect); + const CGFloat y = upPressed ? -3 : 3; // Weird coordinate shift going on. Verified with Hopper + const CGPoint pressPoint = CGPointMake(x, y); + // Pretend we're pressing the mouse on the right button. Unfortunately, NSStepperCell has no + // API to highlight a specific button. The highlighted property works only on the down button. + if (upPressed || downPressed) + [cell startTrackingAt:pressPoint inView:d->backingStoreNSView]; + + [cell drawWithFrame:newRect inView:d->backingStoreNSView]; + + if (upPressed || downPressed) + [cell stopTracking:pressPoint at:pressPoint inView:d->backingStoreNSView mouseIsUp:NO]; + + d->restoreNSGraphicsContext(cg); + } + } + break; + case CC_ComboBox: + if (const auto *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + const bool isEnabled = combo->state & State_Enabled; + const bool isPressed = combo->state & State_Sunken; + + const auto ct = cocoaControlType(combo); + const auto cs = d->effectiveAquaSizeConstrain(combo); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); + auto *cc = static_cast<NSControl *>(d->cocoaControl(cw)); + cc.enabled = isEnabled; + QRectF frameRect = cw.adjustedControlFrame(combo->rect);; + if (cw.type == QMacStylePrivate::Button_PopupButton) { + // Non-editable QComboBox + auto *pb = static_cast<NSPopUpButton *>(cc); + // FIXME Old offsets. Try to move to adjustedControlFrame() + if (cw.size == QStyleHelper::SizeSmall) { + frameRect = frameRect.translated(0, 1); + } else if (cw.size == QStyleHelper::SizeMini) { + // Same 0.5 pt misalignment as AppKit and fit the focus ring + frameRect = frameRect.translated(2, -0.5); + } + pb.frame = frameRect.toCGRect(); + [pb highlight:isPressed]; + d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef, const CGRect &r) { + QMacAutoReleasePool pool; + [pb.cell drawBezelWithFrame:r inView:pb.superview]; + }); + } else if (cw.type == QMacStylePrivate::ComboBox) { + // Editable QComboBox + auto *cb = static_cast<NSComboBox *>(cc); + const auto frameRect = cw.adjustedControlFrame(combo->rect); + cb.frame = frameRect.toCGRect(); + + // This API was requested to Apple in rdar #36197888. We know it's safe to use up to macOS 10.13.3 + if (NSButtonCell *cell = static_cast<NSButtonCell *>([cc.cell qt_valueForPrivateKey:@"_buttonCell"])) { + cell.highlighted = isPressed; + } else { + // TODO Render to pixmap and darken the button manually + } + + d->drawNSViewInRect(cb, frameRect, p, ^(CGContextRef, const CGRect &r) { + // FIXME This is usually drawn in the control's superview, but we wouldn't get inactive look in this case + QMacAutoReleasePool pool; + [cb.cell drawWithFrame:r inView:cb]; + }); + } + } + break; + case CC_TitleBar: + if (const auto *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) { + const bool isActive = (titlebar->state & State_Active) + && (titlebar->titleBarState & State_Active); + + p->fillRect(opt->rect, Qt::transparent); + p->setRenderHint(QPainter::Antialiasing); + p->setClipRect(opt->rect, Qt::IntersectClip); + + // FIXME A single drawPath() with 0-sized pen + // doesn't look as good as this double fillPath(). + const auto outerFrameRect = QRectF(opt->rect.adjusted(0, 0, 0, opt->rect.height())); + QPainterPath outerFramePath = d->windowPanelPath(outerFrameRect); + p->fillPath(outerFramePath, opt->palette.dark()); + + const auto frameAdjust = 1.0 / p->device()->devicePixelRatioF(); + const auto innerFrameRect = outerFrameRect.adjusted(frameAdjust, frameAdjust, -frameAdjust, 0); + QPainterPath innerFramePath = d->windowPanelPath(innerFrameRect); + if (isActive) { + QLinearGradient g; + g.setStart(QPointF(0, 0)); + g.setFinalStop(QPointF(0, 2 * opt->rect.height())); + g.setColorAt(0, opt->palette.button().color()); + g.setColorAt(1, opt->palette.dark().color()); + p->fillPath(innerFramePath, g); + } else { + p->fillPath(innerFramePath, opt->palette.button()); + } + + if (titlebar->subControls & (SC_TitleBarCloseButton + | SC_TitleBarMaxButton + | SC_TitleBarMinButton + | SC_TitleBarNormalButton)) { + const bool isHovered = (titlebar->state & State_MouseOver); + static const SubControl buttons[] = { + SC_TitleBarCloseButton, SC_TitleBarMinButton, SC_TitleBarMaxButton + }; + for (const auto sc : buttons) { + const auto ct = d->windowButtonCocoaControl(sc); + const auto cw = QMacStylePrivate::CocoaControl(ct, QStyleHelper::SizeLarge); + auto *wb = static_cast<NSButton *>(d->cocoaControl(cw)); + wb.enabled = (sc & titlebar->subControls) && isActive; + [wb highlight:(titlebar->state & State_Sunken) && (sc & titlebar->activeSubControls)]; + Q_UNUSED(isHovered); // FIXME No public API for this + + const auto buttonRect = proxy()->subControlRect(CC_TitleBar, titlebar, sc); + d->drawNSViewInRect(wb, buttonRect, p, ^(CGContextRef, const CGRect &rect) { + QMacAutoReleasePool pool; + auto *wbCell = static_cast<NSButtonCell *>(wb.cell); + [wbCell drawWithFrame:rect inView:wb]; + }); + } + } + + if (titlebar->subControls & SC_TitleBarLabel) { + const auto tr = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarLabel); + if (!titlebar->icon.isNull()) { + const auto iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + const auto iconSize = QSize(iconExtent, iconExtent); + const auto iconPos = tr.x() - titlebar->icon.actualSize(iconSize).width() - qRound(titleBarIconTitleSpacing); + // Only render the icon if it'll be fully visible + if (iconPos < tr.right() - titleBarIconTitleSpacing) + p->drawPixmap(iconPos, tr.y(), titlebar->icon.pixmap(opt->window, iconSize, QIcon::Normal)); + } + + if (!titlebar->text.isEmpty()) + drawItemText(p, tr, Qt::AlignCenter, opt->palette, isActive, titlebar->text, QPalette::Text); + } + } + break; + case CC_GroupBox: + if (const QStyleOptionGroupBox *gb + = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) { + + QStyleOptionGroupBox groupBox(*gb); + const bool flat = groupBox.features & QStyleOptionFrame::Flat; + if (!flat) + groupBox.state |= QStyle::State_Mini; // Force mini-sized checkbox to go with small-sized label + else + groupBox.subControls = groupBox.subControls & ~SC_GroupBoxFrame; // We don't like frames and ugly lines + +// const bool didSetFont = widget && widget->testAttribute(Qt::WA_SetFont); +// const bool didModifySubControls = !didSetFont && QApplication::desktopSettingsAware(); +// if (didModifySubControls) +// groupBox.subControls = groupBox.subControls & ~SC_GroupBoxLabel; + QCommonStyle::drawComplexControl(cc, &groupBox, p); +// if (didModifySubControls) { +// const QRect rect = proxy()->subControlRect(CC_GroupBox, &groupBox, SC_GroupBoxLabel); +// const bool rtl = groupBox.direction == Qt::RightToLeft; +// const int alignment = Qt::TextHideMnemonic | (rtl ? Qt::AlignRight : Qt::AlignLeft); +// const QFont savedFont = p->font(); +// if (!flat) +// p->setFont(d->smallSystemFont); +// proxy()->drawItemText(p, rect, alignment, groupBox.palette, groupBox.state & State_Enabled, groupBox.text, QPalette::WindowText); +// if (!flat) +// p->setFont(savedFont); +// } + } + break; + case CC_ToolButton: + if (const QStyleOptionToolButton *tb + = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) { +#ifndef QT_NO_ACCESSIBILITY + if (QStyleHelper::hasAncestor(opt->styleObject, QAccessible::ToolBar)) { + if (tb->subControls & SC_ToolButtonMenu) { + QStyleOption arrowOpt = *tb; + arrowOpt.rect = proxy()->subControlRect(cc, tb, SC_ToolButtonMenu); + arrowOpt.rect.setY(arrowOpt.rect.y() + arrowOpt.rect.height() / 2); + arrowOpt.rect.setHeight(arrowOpt.rect.height() / 2); + proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p); + } else if ((tb->features & QStyleOptionToolButton::HasMenu) + && (tb->toolButtonStyle != Qt::ToolButtonTextOnly && !tb->icon.isNull())) { + d->drawToolbarButtonArrow(tb, p); + } + if (tb->state & State_On) { + NSView *view = reinterpret_cast<NSView *>(opt->window->winId()); + bool isKey = false; + if (view) + isKey = [view.window isKeyWindow]; + + QBrush brush(brushForToolButton(isKey)); + QPainterPath path; + path.addRoundedRect(QRectF(tb->rect.x(), tb->rect.y(), tb->rect.width(), tb->rect.height() + 4), 4, 4); + p->setRenderHint(QPainter::Antialiasing); + p->fillPath(path, brush); + } + proxy()->drawControl(CE_ToolButtonLabel, opt, p); + } else +#endif // QT_NO_ACCESSIBILITY + { + auto bflags = tb->state; + if (tb->subControls & SC_ToolButton) + bflags |= State_Sunken; + auto mflags = tb->state; + if (tb->subControls & SC_ToolButtonMenu) + mflags |= State_Sunken; + + if (tb->subControls & SC_ToolButton) { + if (bflags & (State_Sunken | State_On | State_Raised)) { + const bool isEnabled = tb->state & State_Enabled; + const bool isPressed = tb->state & State_Sunken; + const bool isHighlighted = (tb->state & State_Active) && (tb->state & State_On); + const auto ct = QMacStylePrivate::Button_PushButton; + const auto cs = d->effectiveAquaSizeConstrain(opt); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); + auto *pb = static_cast<NSButton *>(d->cocoaControl(cw)); + pb.bezelStyle = NSShadowlessSquareBezelStyle; // TODO Use NSTexturedRoundedBezelStyle in the future. + pb.frame = opt->rect.toCGRect(); + pb.buttonType = NSPushOnPushOffButton; + pb.enabled = isEnabled; + [pb highlight:isPressed]; + pb.state = isHighlighted && !isPressed ? NSOnState : NSOffState; + const auto buttonRect = proxy()->subControlRect(cc, tb, SC_ToolButton); + d->drawNSViewInRect(pb, buttonRect, p, ^(CGContextRef, const CGRect &rect) { + QMacAutoReleasePool pool; + [pb.cell drawBezelWithFrame:rect inView:pb]; + }); + } + } + + if (tb->subControls & SC_ToolButtonMenu) { + const auto menuRect = proxy()->subControlRect(cc, tb, SC_ToolButtonMenu); + QStyleOption arrowOpt = *tb; + arrowOpt.rect = QRect(menuRect.x() + ((menuRect.width() - toolButtonArrowSize) / 2), + menuRect.height() - (toolButtonArrowSize + toolButtonArrowMargin), + toolButtonArrowSize, + toolButtonArrowSize); + proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p); + } else if (tb->features & QStyleOptionToolButton::HasMenu) { + d->drawToolbarButtonArrow(tb, p); + } + QRect buttonRect = proxy()->subControlRect(CC_ToolButton, tb, SC_ToolButton); + int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt); + QStyleOptionToolButton label = *tb; + label.rect = buttonRect.adjusted(fw, fw, -fw, -fw); + proxy()->drawControl(CE_ToolButtonLabel, &label, p); + } + } + break; + case CC_Dial: + if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(opt)) + QStyleHelper::drawDial(dial, p); + break; + default: + QCommonStyle::drawComplexControl(cc, opt, p); + break; + } +} + +QStyle::SubControl QMacStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt) const +{ + Q_D(const QMacStyle); + + SubControl sc = QStyle::SC_None; + + switch (cc) { + case CC_ComboBox: + if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + sc = QCommonStyle::hitTestComplexControl(cc, cmb, pt); + if (!cmb->editable && sc != QStyle::SC_None) + sc = SC_ComboBoxArrow; // A bit of a lie, but what we want + } + break; + case CC_Slider: + if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + if (!sl->rect.contains(pt)) + break; + + const bool hasTicks = sl->tickPosition != QStyleOptionSlider::NoTicks; + const bool isHorizontal = sl->orientation == Qt::Horizontal; + const auto ct = isHorizontal ? QMacStylePrivate::Slider_Horizontal : QMacStylePrivate::Slider_Vertical; + const auto cs = d->effectiveAquaSizeConstrain(opt); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); + auto *slider = static_cast<NSSlider *>(d->cocoaControl(cw)); + if (!setupSlider(slider, sl)) + break; + + NSSliderCell *cell = slider.cell; + const auto barRect = QRectF::fromCGRect([cell barRectFlipped:slider.isFlipped]); + const auto knobRect = QRectF::fromCGRect([cell knobRectFlipped:slider.isFlipped]); + if (knobRect.contains(pt)) { + sc = SC_SliderHandle; + } else if (barRect.contains(pt)) { + sc = SC_SliderGroove; + } else if (hasTicks) { + sc = SC_SliderTickmarks; + } + } + break; + case CC_ScrollBar: + if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + if (!sb->rect.contains(pt)) { + sc = SC_None; + break; + } + + const bool isHorizontal = sb->orientation == Qt::Horizontal; + const auto ct = isHorizontal ? QMacStylePrivate::Scroller_Horizontal : QMacStylePrivate::Scroller_Vertical; + const auto cs = d->effectiveAquaSizeConstrain(opt); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); + auto *scroller = static_cast<NSScroller *>(d->cocoaControl(cw)); + if (!setupScroller(scroller, sb)) { + sc = SC_None; + break; + } + + // Since -[NSScroller testPart:] doesn't want to cooperate, we do it the + // straightforward way. In any case, macOS doesn't return line-sized changes + // with NSScroller since 10.7, according to the aforementioned method's doc. + const auto knobRect = QRectF::fromCGRect([scroller rectForPart:NSScrollerKnob]); + if (isHorizontal) { + const bool isReverse = sb->direction == Qt::RightToLeft; + if (pt.x() < knobRect.left()) + sc = isReverse ? SC_ScrollBarAddPage : SC_ScrollBarSubPage; + else if (pt.x() > knobRect.right()) + sc = isReverse ? SC_ScrollBarSubPage : SC_ScrollBarAddPage; + else + sc = SC_ScrollBarSlider; + } else { + if (pt.y() < knobRect.top()) + sc = SC_ScrollBarSubPage; + else if (pt.y() > knobRect.bottom()) + sc = SC_ScrollBarAddPage; + else + sc = SC_ScrollBarSlider; + } + } + break; + default: + sc = QCommonStyle::hitTestComplexControl(cc, opt, pt); + break; + } + return sc; +} + +QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc) const +{ + Q_D(const QMacStyle); + + QRect ret; + + switch (cc) { + case CC_ScrollBar: + if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + const bool isHorizontal = sb->orientation == Qt::Horizontal; + const bool isReverseHorizontal = isHorizontal && (sb->direction == Qt::RightToLeft); + + NSScrollerPart part = NSScrollerNoPart; + if (sc == SC_ScrollBarSlider) { + part = NSScrollerKnob; + } else if (sc == SC_ScrollBarGroove) { + part = NSScrollerKnobSlot; + } else if (sc == SC_ScrollBarSubPage || sc == SC_ScrollBarAddPage) { + if ((!isReverseHorizontal && sc == SC_ScrollBarSubPage) + || (isReverseHorizontal && sc == SC_ScrollBarAddPage)) + part = NSScrollerDecrementPage; + else + part = NSScrollerIncrementPage; + } + // And nothing else since 10.7 + + if (part != NSScrollerNoPart) { + const auto ct = isHorizontal ? QMacStylePrivate::Scroller_Horizontal : QMacStylePrivate::Scroller_Vertical; + const auto cs = d->effectiveAquaSizeConstrain(opt); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); + auto *scroller = static_cast<NSScroller *>(d->cocoaControl(cw)); + if (setupScroller(scroller, sb)) + ret = QRectF::fromCGRect([scroller rectForPart:part]).toRect(); + } + } + break; + case CC_Slider: + if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + const bool hasTicks = sl->tickPosition != QStyleOptionSlider::NoTicks; + const bool isHorizontal = sl->orientation == Qt::Horizontal; + const auto ct = isHorizontal ? QMacStylePrivate::Slider_Horizontal : QMacStylePrivate::Slider_Vertical; + const auto cs = d->effectiveAquaSizeConstrain(opt); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); + auto *slider = static_cast<NSSlider *>(d->cocoaControl(cw)); + if (!setupSlider(slider, sl)) + break; + + NSSliderCell *cell = slider.cell; + if (sc == SC_SliderHandle) { + ret = QRectF::fromCGRect([cell knobRectFlipped:slider.isFlipped]).toRect(); + } else if (sc == SC_SliderGroove) { + ret = QRectF::fromCGRect([cell barRectFlipped:slider.isFlipped]).toRect(); + } else if (hasTicks && sc == SC_SliderTickmarks) { + const auto tickMarkRect = QRectF::fromCGRect([cell rectOfTickMarkAtIndex:0]); + if (isHorizontal) + ret = QRect(sl->rect.left(), tickMarkRect.top(), sl->rect.width(), tickMarkRect.height()); + else + ret = QRect(tickMarkRect.left(), sl->rect.top(), tickMarkRect.width(), sl->rect.height()); + } + +// if (sl->upsideDown) { +// if isHorizontal) { +// } else { +// } +// } + } + break; + case CC_TitleBar: + if (const auto *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) { + // The title bar layout is as follows: close, min, zoom, icon, title + // [ x _ + @ Window Title ] + // Center the icon and title until it starts to overlap with the buttons. + // The icon doesn't count towards SC_TitleBarLabel, but it's still rendered + // next to the title text. See drawComplexControl(). + if (sc == SC_TitleBarLabel) { + qreal labelWidth = titlebar->fontMetrics.horizontalAdvance(titlebar->text) + 1; // FIXME Rounding error? + qreal labelHeight = titlebar->fontMetrics.height(); + + const auto lastButtonRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarMaxButton); + qreal controlsSpacing = lastButtonRect.right() + titleBarButtonSpacing; + if (!titlebar->icon.isNull()) { + const auto iconSize = proxy()->pixelMetric(PM_SmallIconSize); + const auto actualIconSize = titlebar->icon.actualSize(QSize(iconSize, iconSize)).width();; + controlsSpacing += actualIconSize + titleBarIconTitleSpacing; + } + + const qreal labelPos = qMax(controlsSpacing, (opt->rect.width() - labelWidth) / 2.0); + labelWidth = qMin(labelWidth, opt->rect.width() - (labelPos + titleBarTitleRightMargin)); + ret = QRect(labelPos, (opt->rect.height() - labelHeight) / 2, + labelWidth, labelHeight); + } else { + const auto currentButton = d->windowButtonCocoaControl(sc); + if (currentButton == QMacStylePrivate::NoControl) + break; + + QPointF buttonPos = titlebar->rect.topLeft() + QPointF(titleBarButtonSpacing, 0); + QSizeF buttonSize; + for (int ct = QMacStylePrivate::Button_WindowClose; ct <= currentButton; ct++) { + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::CocoaControlType(ct), + QStyleHelper::SizeLarge); + auto *wb = static_cast<NSButton *>(d->cocoaControl(cw)); + if (ct == currentButton) + buttonSize = QSizeF::fromCGSize(wb.frame.size); + else + buttonPos.rx() += wb.frame.size.width + titleBarButtonSpacing; + } + + const auto vOffset = (opt->rect.height() - buttonSize.height()) / 2.0; + ret = QRectF(buttonPos, buttonSize).translated(0, vOffset).toRect(); + } + } + break; + case CC_ComboBox: + if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + const auto ct = cocoaControlType(combo); + const auto cs = d->effectiveAquaSizeConstrain(combo); + const auto cw = QMacStylePrivate::CocoaControl(ct, cs); + + // Old widget path. Current not understood why it's needed: + //const auto editRect = QMacStylePrivate::comboboxEditBounds(cw.adjustedControlFrame(combo->rect), cw); + + // New path: + QRectF editRect; + switch (cs) { + case QStyleHelper::SizeLarge: + editRect = combo->rect.adjusted(15, 7, -25, -9); + break; + case QStyleHelper::SizeSmall: + if (combo->editable) + editRect = combo->rect.adjusted(15, 6, -22, -9); + else + editRect = combo->rect.adjusted(15, 8, -22, -6); + break; + default: + if (combo->editable) + editRect = combo->rect.adjusted(15, 6, -20, -7); + else + editRect = combo->rect.adjusted(15, 5, -22, -6); + break; + } + + switch (sc) { + case SC_ComboBoxEditField:{ + ret = editRect.toAlignedRect(); + break; } + case SC_ComboBoxArrow:{ + ret = editRect.toAlignedRect(); + ret.setX(ret.x() + ret.width()); + ret.setWidth(combo->rect.right() - ret.right()); + break; } + case SC_ComboBoxListBoxPopup:{ + if (combo->editable) { + const CGRect inner = QMacStylePrivate::comboboxInnerBounds(combo->rect.toCGRect(), cw); + const int comboTop = combo->rect.top(); + ret = QRect(qRound(inner.origin.x), + comboTop, + qRound(inner.origin.x - combo->rect.left() + inner.size.width), + editRect.bottom() - comboTop + 2); + } else { + ret = QRect(combo->rect.x() + 4 - 11, + combo->rect.y() + 1, + editRect.width() + 10 + 11, + 1); + } + break; } + default: + break; + } + } + break; + case CC_GroupBox: + if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) { + bool checkable = groupBox->subControls & SC_GroupBoxCheckBox; + const bool flat = groupBox->features & QStyleOptionFrame::Flat; + bool hasNoText = !checkable && groupBox->text.isEmpty(); + switch (sc) { + case SC_GroupBoxLabel: + case SC_GroupBoxCheckBox: { + // Cheat and use the smaller font if we need to + const bool checkable = groupBox->subControls & SC_GroupBoxCheckBox; + const bool fontIsSet = false; +// const bool fontIsSet = (widget && widget->testAttribute(Qt::WA_SetFont)) +// || !QApplication::desktopSettingsAware(); + const int margin = flat || hasNoText ? 0 : 9; + ret = groupBox->rect.adjusted(margin, 0, -margin, 0); + + const QFontMetricsF fm = flat || fontIsSet ? QFontMetricsF(groupBox->fontMetrics) : QFontMetricsF(d->smallSystemFont); + const QSizeF s = fm.size(Qt::AlignHCenter | Qt::AlignVCenter, qt_mac_removeMnemonics(groupBox->text), 0, nullptr); + const int tw = qCeil(s.width()); + const int h = qCeil(fm.height()); + ret.setHeight(h); + + QRect labelRect = alignedRect(groupBox->direction, groupBox->textAlignment, + QSize(tw, h), ret); + if (flat && checkable) + labelRect.moveLeft(labelRect.left() + 4); + int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, opt); + bool rtl = groupBox->direction == Qt::RightToLeft; + if (sc == SC_GroupBoxLabel) { + if (checkable) { + int newSum = indicatorWidth + 1; + int newLeft = labelRect.left() + (rtl ? -newSum : newSum); + labelRect.moveLeft(newLeft); + if (flat) + labelRect.moveTop(labelRect.top() + 3); + else + labelRect.moveTop(labelRect.top() + 4); + } else if (flat) { + int newLeft = labelRect.left() - (rtl ? 3 : -3); + labelRect.moveLeft(newLeft); + labelRect.moveTop(labelRect.top() + 3); + } else { + int newLeft = labelRect.left() - (rtl ? 3 : 2); + labelRect.moveLeft(newLeft); + labelRect.moveTop(labelRect.top() + 4); + } + ret = labelRect; + } + + if (sc == SC_GroupBoxCheckBox) { + int left = rtl ? labelRect.right() - indicatorWidth : labelRect.left() - 1; + int top = flat ? ret.top() + 1 : ret.top() + 5; + ret.setRect(left, top, + indicatorWidth, proxy()->pixelMetric(PM_IndicatorHeight, opt)); + } + break; + } + case SC_GroupBoxContents: + case SC_GroupBoxFrame: { + QFontMetrics fm = groupBox->fontMetrics; + int yOffset = 3; + if (!flat) + yOffset = 5; + + if (hasNoText) + yOffset = -qCeil(QFontMetricsF(fm).height()); + ret = opt->rect.adjusted(0, qCeil(QFontMetricsF(fm).height()) + yOffset, 0, 0); + if (sc == SC_GroupBoxContents) { + if (flat) + ret.adjust(3, -5, -3, -4); // guess too + else + ret.adjust(3, 3, -3, -4); // guess + } + } + break; + default: + ret = QCommonStyle::subControlRect(cc, groupBox, sc); + break; + } + } + break; + case CC_SpinBox: + if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { + QStyleHelper::WidgetSizePolicy aquaSize = d->effectiveAquaSizeConstrain(spin); + const auto fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, spin); + int spinner_w; + int spinner_h; + int adjust_y; + int spinBoxSep; + switch (aquaSize) { + case QStyleHelper::SizeLarge: + spinner_w = 14; + spinner_h = 24; + adjust_y = -1; + spinBoxSep = 2; + break; + case QStyleHelper::SizeSmall: + spinner_w = 12; + spinner_h = 20; + adjust_y = -1; + spinBoxSep = 2; + break; + case QStyleHelper::SizeMini: + spinner_w = 10; + spinner_h = 16; + adjust_y = -1; + spinBoxSep = 1; + break; + default: + Q_UNREACHABLE(); + } + + switch (sc) { + case SC_SpinBoxUp: + case SC_SpinBoxDown: { + if (spin->buttonSymbols == QStyleOptionSpinBox::NoButtons) + break; + + const int y = fw; + const int x = spin->rect.width() - spinner_w; + ret.setRect(x + spin->rect.x(), y + spin->rect.y(), spinner_w, spinner_h); + + const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Stepper, aquaSize); + NSStepperCell *cell = static_cast<NSStepperCell *>(d->cocoaCell(cw)); + const CGRect outRect = [cell drawingRectForBounds:ret.toCGRect()]; + ret = QRectF::fromCGRect(outRect).toRect(); + + switch (sc) { + case SC_SpinBoxUp: + ret.setHeight(ret.height() / 2); + break; + case SC_SpinBoxDown: + ret.setY(ret.y() + ret.height() / 2); + break; + default: + Q_ASSERT(0); + break; + } + // The buttons are drawn with a top-margin (for some reason) into + // the rect. So undo that margin here: + ret.translate(0, adjust_y); + ret = visualRect(spin->direction, spin->rect, ret); + break; + } + case SC_SpinBoxEditField: + ret = spin->rect.adjusted(fw, fw, -fw, -fw); + if (spin->subControls & SC_SpinBoxUp || spin->subControls & SC_SpinBoxDown) { + ret.setWidth(spin->rect.width() - spinBoxSep - spinner_w); + ret = visualRect(spin->direction, spin->rect, ret); + } + break; + default: + ret = QCommonStyle::subControlRect(cc, spin, sc); + break; + } + } + break; + case CC_ToolButton: + ret = QCommonStyle::subControlRect(cc, opt, sc); + if (sc == SC_ToolButtonMenu) { +#ifndef QT_NO_ACCESSIBILITY + if (QStyleHelper::hasAncestor(opt->styleObject, QAccessible::ToolBar)) + ret.adjust(-toolButtonArrowMargin, 0, 0, 0); +#endif + ret.adjust(-1, 0, 0, 0); + } + break; + default: + ret = QCommonStyle::subControlRect(cc, opt, sc); + break; + } + return ret; +} + +QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &csz) const +{ + Q_D(const QMacStyle); + + QSize sz(csz); + bool useAquaGuideline = true; + + switch (ct) { + case CT_SpinBox: + if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { + if (vopt->subControls == SC_SpinBoxFrame) { + const QSize minimumSize(20, 24); + if (sz.width() < minimumSize.width()) + sz.setWidth(minimumSize.width()); + if (sz.height() < minimumSize.height()) + sz.setHeight(minimumSize.height()); + } else { + const QSize buttonSize = proxy()->subControlRect(CC_SpinBox, vopt, SC_SpinBoxUp).size(); + const int upAndDownTogetherHeight = buttonSize.height() * 2; + sz += QSize(buttonSize.width(), upAndDownTogetherHeight); + } + } + break; + case QStyle::CT_TabWidget: + // the size between the pane and the "contentsRect" (+4,+4) + // (the "contentsRect" is on the inside of the pane) + sz = QCommonStyle::sizeFromContents(ct, opt, csz); + /** + This is supposed to show the relationship between the tabBar and + the stack widget of a QTabWidget. + Unfortunately ascii is not a good way of representing graphics..... + PS: The '=' line is the painted frame. + + top ---+ + | + | + | + | vvv just outside the painted frame is the "pane" + - -|- - - - - - - - - - <-+ + TAB BAR +=====^============ | +2 pixels + - - -|- - -|- - - - - - - <-+ + | | ^ ^^^ just inside the painted frame is the "contentsRect" + | | | + | overlap | + | | | + bottom ------+ <-+ +14 pixels + | + v + ------------------------------ <- top of stack widget + + + To summarize: + * 2 is the distance between the pane and the contentsRect + * The 14 and the 1's are the distance from the contentsRect to the stack widget. + (same value as used in SE_TabWidgetTabContents) + * overlap is how much the pane should overlap the tab bar + */ + // then add the size between the stackwidget and the "contentsRect" + if (const QStyleOptionTabWidgetFrame *twf + = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { + QSize extra(0,0); + const int overlap = pixelMetric(PM_TabBarBaseOverlap, opt); + const int gapBetweenTabbarAndStackWidget = 2 + 14 - overlap; + + const auto tabDirection = QMacStylePrivate::tabDirection(twf->shape); + if (tabDirection == QMacStylePrivate::North + || tabDirection == QMacStylePrivate::South) { + extra = QSize(2, gapBetweenTabbarAndStackWidget + 1); + } else { + extra = QSize(gapBetweenTabbarAndStackWidget + 1, 2); + } + sz+= extra; + } + break; + case QStyle::CT_TabBarTab: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { +// const bool differentFont = (widget && widget->testAttribute(Qt::WA_SetFont)) +// || !QApplication::desktopSettingsAware(); + const bool differentFont = false; + const auto tabDirection = QMacStylePrivate::tabDirection(tab->shape); + const bool verticalTabs = tabDirection == QMacStylePrivate::East + || tabDirection == QMacStylePrivate::West; + if (verticalTabs) + sz = sz.transposed(); + + int defaultTabHeight; + const auto cs = d->effectiveAquaSizeConstrain(opt); + switch (cs) { + case QStyleHelper::SizeLarge: + if (tab->documentMode) + defaultTabHeight = 24; + else + defaultTabHeight = 21; + break; + case QStyleHelper::SizeSmall: + defaultTabHeight = 18; + break; + case QStyleHelper::SizeMini: + defaultTabHeight = 16; + break; + default: + break; + } + + const bool widthSet = !differentFont && tab->icon.isNull(); + if (widthSet) { + const auto textSize = opt->fontMetrics.size(Qt::TextShowMnemonic, tab->text); + sz.rwidth() = textSize.width(); + sz.rheight() = qMax(defaultTabHeight, textSize.height()); + } else { + sz.rheight() = qMax(defaultTabHeight, sz.height()); + } + sz.rwidth() += proxy()->pixelMetric(PM_TabBarTabHSpace, tab); + + if (verticalTabs) + sz = sz.transposed(); + + int maxWidgetHeight = qMax(tab->leftButtonSize.height(), tab->rightButtonSize.height()); + int maxWidgetWidth = qMax(tab->leftButtonSize.width(), tab->rightButtonSize.width()); + + int widgetWidth = 0; + int widgetHeight = 0; + int padding = 0; + if (tab->leftButtonSize.isValid()) { + padding += 8; + widgetWidth += tab->leftButtonSize.width(); + widgetHeight += tab->leftButtonSize.height(); + } + if (tab->rightButtonSize.isValid()) { + padding += 8; + widgetWidth += tab->rightButtonSize.width(); + widgetHeight += tab->rightButtonSize.height(); + } + + if (verticalTabs) { + sz.setWidth(qMax(sz.width(), maxWidgetWidth)); + sz.setHeight(sz.height() + widgetHeight + padding); + } else { + if (widthSet) + sz.setWidth(sz.width() + widgetWidth + padding); + sz.setHeight(qMax(sz.height(), maxWidgetHeight)); + } + } + break; + case CT_LineEdit: + if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + if (sz.isEmpty()) { + // Minimum size (with padding: 18x24) + sz.rwidth() = 10; + sz.rheight() = 20; + } + // From using pixelTool with XCode/NSTextTextField + int leftPadding = 4; + int rightPadding = 4; + int topPadding = 4; + int bottomPadding = 0; + + if (opt->state & QStyle::State_Small) { + topPadding = 3; + } else if (opt->state & QStyle::State_Mini) { + topPadding = 2; + } + + sz.rwidth() += leftPadding + rightPadding; + sz.rheight() += topPadding + bottomPadding; + } + break; + case QStyle::CT_PushButton: { + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) + if (btn->features & QStyleOptionButton::CommandLinkButton) + return QCommonStyle::sizeFromContents(ct, opt, sz); + + // By default, we fit the contents inside a normal rounded push button. + // Do this by add enough space around the contents so that rounded + // borders (including highlighting when active) will show. + // TODO Use QFocusFrame and get rid of these horrors. + QSize macsz; + const auto controlSize = d->effectiveAquaSizeConstrain(opt, CT_PushButton, sz, &macsz); + // FIXME See comment in CT_PushButton case in qt_aqua_get_known_size(). + if (macsz.width() != -1) + sz.setWidth(macsz.width()); + else + sz.rwidth() += QMacStylePrivate::PushButtonLeftOffset + QMacStylePrivate::PushButtonRightOffset + 12; + // All values as measured from HIThemeGetButtonBackgroundBounds() + if (controlSize != QStyleHelper::SizeMini) + sz.rwidth() += 12; // We like 12 over here. + if (controlSize == QStyleHelper::SizeLarge && sz.height() > 16) + sz.rheight() += pushButtonDefaultHeight[QStyleHelper::SizeLarge] - 16; + else if (controlSize == QStyleHelper::SizeMini) + sz.setHeight(24); // FIXME Our previous HITheme-based logic returned this. + else + sz.setHeight(pushButtonDefaultHeight[controlSize]); + break; + } + case QStyle::CT_MenuItem: + if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { + int maxpmw = mi->maxIconWidth; + int w = sz.width(); + int h = sz.height(); + +//#if QT_CONFIG(combobox) +// const QComboBox *comboBox = qobject_cast<const QComboBox *>(widget); +//#endif + + if (mi->menuItemType == QStyleOptionMenuItem::Separator) { + w = 10; + h = qt_mac_aqua_get_metric(MenuSeparatorHeight); + } else { + h = mi->fontMetrics.height() + 2; + if (!mi->icon.isNull()) { +//#if QT_CONFIG(combobox) +// if (comboBox) { +// const QSize &iconSize = comboBox->iconSize(); +// h = qMax(h, iconSize.height() + 4); +// maxpmw = qMax(maxpmw, iconSize.width()); +// } else +//#endif + { + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + h = qMax(h, mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + 4); + } + } + } + if (mi->text.contains(QLatin1Char('\t'))) + w += 12; + else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu) + w += 35; // Not quite exactly as it seems to depend on other factors + if (maxpmw) + w += maxpmw + 6; + // add space for a check. All items have place for a check too. + w += 20; +// if (comboBox && comboBox->isVisible()) { +// QStyleOptionComboBox cmb; +// cmb.initFrom(comboBox); +// cmb.editable = false; +// cmb.subControls = QStyle::SC_ComboBoxEditField; +// cmb.activeSubControls = QStyle::SC_None; +// w = qMax(w, subControlRect(QStyle::CC_ComboBox, &cmb, +// QStyle::SC_ComboBoxEditField, +// comboBox).width()); +// } else { +// w += 12; + sz = QSize(w, h); + } break; + case CT_MenuBarItem: + if (!sz.isEmpty()) + sz += QSize(12, 4); // Constants from QWindowsStyle + break; + case CT_ToolButton: + sz.rwidth() += 10; + sz.rheight() += 10; + if (const auto *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) + if (tb->features & QStyleOptionToolButton::Menu) + sz.rwidth() += toolButtonArrowMargin; + return sz; + case CT_ComboBox: + if (const auto *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + const int controlSize = getControlSize(opt); + + if (!cb->editable) { + if (sz.width() < 10) { + // minimumSize (to ensure a nice nine patch image) + sz.rwidth() += 10; + } + // Same as CT_PushButton, because we have to fit the focus + // ring and a non-editable combo box is a NSPopUpButton. + sz.rwidth() += QMacStylePrivate::PushButtonLeftOffset + QMacStylePrivate::PushButtonRightOffset; + + if (controlSize == QStyleHelper::SizeLarge) { + sz.rwidth() += 30; + } else if (controlSize == QStyleHelper::SizeSmall) { + sz.rwidth() += 26; + } else { + sz.rwidth() += 21; + } + } else { + sz.rwidth() += 50; // FIXME Double check this + } + + // This should be enough to fit the focus ring + if (controlSize == QStyleHelper::SizeMini) + sz.setHeight(24); // FIXME Our previous HITheme-based logic returned this for CT_PushButton. + else + sz.setHeight(pushButtonDefaultHeight[controlSize]); + + return sz; + } + break; + case CT_Menu: { + if (proxy() == this) { + sz = csz; + } else { + QStyleHintReturnMask menuMask; + QStyleOption myOption = *opt; + myOption.rect.setSize(sz); + if (proxy()->styleHint(SH_Menu_Mask, &myOption, &menuMask)) + sz = menuMask.region.boundingRect().size(); + } + break; } + case CT_HeaderSection:{ + const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt); + sz = QCommonStyle::sizeFromContents(ct, opt, csz); + if (header->text.contains(QLatin1Char('\n'))) + useAquaGuideline = false; + break; } + case CT_ScrollBar : + // Make sure that the scroll bar is large enough to display the thumb indicator. + if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + const int minimumWidth = 24; + const int absoluteHeight = 14; + if (slider->orientation == Qt::Horizontal) { + sz = sz.expandedTo(QSize(minimumWidth, sz.height())); + sz.setHeight(absoluteHeight); + } else { + sz = sz.expandedTo(QSize(sz.width(), minimumWidth)); + sz.setWidth(absoluteHeight); + } + } + break; + case CT_ItemViewItem: + if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { + sz = QCommonStyle::sizeFromContents(ct, vopt, csz); + sz.setHeight(sz.height() + 2); + } + break; + default: + sz = QCommonStyle::sizeFromContents(ct, opt, csz); + } + + if (useAquaGuideline && ct != CT_PushButton) { + // TODO Probably going away at some point + QSize macsz; + if (d->aquaSizeConstrain(opt, ct, sz, &macsz) != QStyleHelper::SizeDefault) { + if (macsz.width() != -1) + sz.setWidth(macsz.width()); + if (macsz.height() != -1) + sz.setHeight(macsz.height()); + } + } + + // The sizes that Carbon and the guidelines gives us excludes the focus frame. + // We compensate for this by adding some extra space here to make room for the frame when drawing: + if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){ + if (combo->editable) { + const auto widgetSize = d->aquaSizeConstrain(opt); + QMacStylePrivate::CocoaControl cw; + cw.type = combo->editable ? QMacStylePrivate::ComboBox : QMacStylePrivate::Button_PopupButton; + cw.size = widgetSize; + const CGRect diffRect = QMacStylePrivate::comboboxInnerBounds(CGRectZero, cw); + sz.rwidth() -= qRound(diffRect.size.width); + sz.rheight() -= qRound(diffRect.size.height); + } + } + return sz; +} + +QFont QMacStyle::font(QStyle::ControlElement element, const QStyle::State state) const +{ + QFont font = QCommonStyle::font(element, state); + + if (state & QStyle::State_Small) { + font.setPixelSize(11); + } else if (state & QStyle::State_Mini) { + font.setPixelSize(9); + } + + return font; +} + +QMargins QMacStyle::ninePatchMargins(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, const QSize &imageSize) const +{ + QMargins margins; + + switch (cc) { + case CC_ComboBox: { + const QRect arrow = subControlRect(CC_ComboBox, opt, SC_ComboBoxArrow); + margins = QMargins(10, 0, arrow.width() + 1, -1); + break; } + default: + margins = QCommonStyle::ninePatchMargins(cc, opt, imageSize); + break; + } + + return margins; +} + +void QMacStyle::drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal, + bool enabled, const QString &text, QPalette::ColorRole textRole) const +{ + if(flags & Qt::TextShowMnemonic) + flags |= Qt::TextHideMnemonic; + QCommonStyle::drawItemText(p, r, flags, pal, enabled, text, textRole); +} + +QIcon QMacStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *opt) const +{ + switch (standardIcon) { + default: + return QCommonStyle::standardIcon(standardIcon, opt); + case SP_ToolBarHorizontalExtensionButton: + case SP_ToolBarVerticalExtensionButton: { + QPixmap pixmap(QLatin1String(":/qt-project.org/styles/macstyle/images/toolbar-ext.png")); + if (standardIcon == SP_ToolBarVerticalExtensionButton) { + QPixmap pix2(pixmap.height(), pixmap.width()); + pix2.setDevicePixelRatio(pixmap.devicePixelRatio()); + pix2.fill(Qt::transparent); + QPainter p(&pix2); + p.translate(pix2.width(), 0); + p.rotate(90); + p.drawPixmap(0, 0, pixmap); + return pix2; + } + return pixmap; + } + } +} + +} // QQC2_NAMESPACE + +QT_END_NAMESPACE diff --git a/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac_p.h b/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac_p.h new file mode 100644 index 00000000000..b9e1c5f3414 --- /dev/null +++ b/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMACSTYLE_MAC_P_H +#define QMACSTYLE_MAC_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquickcommonstyle.h" + +#define QQC2_NAMESPACE QQC2 + +QT_BEGIN_NAMESPACE + +class QPalette; + +namespace QQC2_NAMESPACE { + +class QStyleOptionButton; +class QMacStylePrivate; + +class QMacStyle : public QCommonStyle +{ + Q_OBJECT +public: + QMacStyle(); + ~QMacStyle(); + + void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p) const override; + void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p) const override; + void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p) const override; + + QRect subElementRect(SubElement r, const QStyleOption *opt) const override; + QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc) const override; + SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt) const override; + + QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize) const override; + QFont font(ControlElement element, const QStyle::State state) const override; + QMargins ninePatchMargins(ComplexControl cc, const QStyleOptionComplex *opt, const QSize &imageSize) const override; + + int pixelMetric(PixelMetric pm, const QStyleOption *opt = 0) const override; + int styleHint(StyleHint sh, const QStyleOption *opt = 0, QStyleHintReturn *shret = 0) const override; + + QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt) const override; + QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const override; + + void drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal, + bool enabled, const QString &text, + QPalette::ColorRole textRole = QPalette::NoRole) const override; + + QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *opt = 0) const override; + +private: + Q_DISABLE_COPY_MOVE(QMacStyle) + Q_DECLARE_PRIVATE(QMacStyle) +}; + +} // QQC2_NAMESPACE + +QT_END_NAMESPACE + +#endif // QMACSTYLE_MAC_P_H diff --git a/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac_p_p.h b/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac_p_p.h new file mode 100644 index 00000000000..a0c67bfb6b7 --- /dev/null +++ b/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac_p_p.h @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QMACSTYLE_MAC_P_P_H +#define QMACSTYLE_MAC_P_P_H + +#include "qquickmacstyle_mac_p.h" +#include "qquickcommonstyle_p.h" +#include "qquickstylehelper_p.h" + +#include <QtCore/qdebug.h> +#include <QtCore/qhash.h> +#include <QtCore/qmap.h> +#include <QtCore/qmath.h> +#include <QtCore/qpair.h> +#include <QtCore/qpointer.h> +#include <QtCore/qtextstream.h> +#include <QtCore/qvector.h> + +#include <QtGui/qbitmap.h> +#include <QtGui/qevent.h> +#include <QtGui/qpaintdevice.h> +#include <QtGui/qpainter.h> +#include <QtGui/qpixmapcache.h> + +#include <QtQuick/qquickitem.h> + +#include <QtCore/private/qcore_mac_p.h> +#include <QtGui/private/qpainter_p.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +Q_FORWARD_DECLARE_MUTABLE_CG_TYPE(CGContext); + +Q_FORWARD_DECLARE_OBJC_CLASS(NSView); +Q_FORWARD_DECLARE_OBJC_CLASS(NSCell); + +QT_BEGIN_NAMESPACE + +namespace QQC2 { + +/* + AHIG: + macOS Human Interface Guidelines + https://developer.apple.com/macos/human-interface-guidelines/overview/themes/ + + Builder: + Interface Builder in Xcode 8 or later +*/ + +// this works as long as we have at most 16 different control types +#define CT1(c) CT2(c, c) +#define CT2(c1, c2) ((uint(c1) << 16) | uint(c2)) + +#define SIZE(large, small, mini) \ + (controlSize == QStyleHelper::SizeLarge ? (large) : controlSize == QStyleHelper::SizeSmall ? (small) : (mini)) + +// same as return SIZE(...) but optimized +#define return_SIZE(large, small, mini) \ + do { \ + static const int sizes[] = { (large), (small), (mini) }; \ + return sizes[controlSize]; \ + } while (false) + +class QMacStylePrivate : public QCommonStylePrivate +{ + Q_DECLARE_PUBLIC(QMacStyle) + +public: + enum Direction { + North, South, East, West + }; + + enum CocoaControlType { + NoControl, // For when there's no such a control in Cocoa + Box, // QGroupBox + Box_Dark, // FIXME See render code in drawPrimitive(PE_FrameTabWidget) + Button_CheckBox, + Button_Disclosure, // Disclosure triangle, like in QTreeView + Button_PopupButton, // Non-editable QComboBox + Button_PullDown, // QPushButton with menu + Button_PushButton, // Plain QPushButton and QTabBar buttons + Button_RadioButton, + Button_SquareButton, // Oversized QPushButton + Button_WindowClose, + Button_WindowMiniaturize, + Button_WindowZoom, + ComboBox, // Editable QComboBox + ProgressIndicator_Determinate, + ProgressIndicator_Indeterminate, + Scroller_Horizontal, + Scroller_Vertical, + SegmentedControl_First, // QTabBar buttons focus ring + SegmentedControl_Middle, + SegmentedControl_Last, + SegmentedControl_Single, + Slider_Horizontal, + Slider_Vertical, + SplitView_Horizontal, + SplitView_Vertical, + Stepper, // QSpinBox buttons + TextField + }; + + struct CocoaControl { + CocoaControl(); + CocoaControl(CocoaControlType t, QStyleHelper::WidgetSizePolicy s); + + CocoaControlType type; + QStyleHelper::WidgetSizePolicy size; + + bool operator==(const CocoaControl &other) const; + + QSizeF defaultFrameSize() const; + QRectF adjustedControlFrame(const QRectF &rect) const; + QMarginsF titleMargins() const; + + bool getCocoaButtonTypeAndBezelStyle(NSButtonType *buttonType, NSBezelStyle *bezelStyle) const; + }; + + typedef void (^DrawRectBlock)(CGContextRef, const CGRect &); + + QMacStylePrivate(); + ~QMacStylePrivate(); + + // Ideally these wouldn't exist, but since they already exist we need some accessors. + static const int PushButtonLeftOffset; + static const int PushButtonRightOffset; + static const int PushButtonContentPadding; + + enum Animates { AquaPushButton, AquaProgressBar, AquaListViewItemOpen, AquaScrollBar }; + QStyleHelper::WidgetSizePolicy aquaSizeConstrain(const QStyleOption *option, + QStyle::ContentsType ct = QStyle::CT_CustomBase, + QSize szHint=QSize(-1, -1), QSize *insz = 0) const; + QStyleHelper::WidgetSizePolicy effectiveAquaSizeConstrain(const QStyleOption *option, + QStyle::ContentsType ct = QStyle::CT_CustomBase, + QSize szHint=QSize(-1, -1), QSize *insz = 0) const; + inline int animateSpeed(Animates) const { return 33; } + + // Utility functions + static CGRect comboboxInnerBounds(const CGRect &outterBounds, const CocoaControl &cocoaWidget); + + static QRectF comboboxEditBounds(const QRectF &outterBounds, const CocoaControl &cw); + + void setAutoDefaultButton(QObject *button) const; + + NSView *cocoaControl(CocoaControl cocoaControl) const; + NSCell *cocoaCell(CocoaControl cocoaControl) const; + + void setupNSGraphicsContext(CGContextRef cg, bool flipped) const; + void restoreNSGraphicsContext(CGContextRef cg) const; + + void setupVerticalInvertedXform(CGContextRef cg, bool reverse, bool vertical, const CGRect &rect) const; + + void drawNSViewInRect(NSView *view, const QRectF &rect, QPainter *p, DrawRectBlock drawRectBlock = nil) const; + void resolveCurrentNSView(QWindow *window) const; + + void drawToolbarButtonArrow(const QStyleOption *opt, QPainter *p) const; + + QPainterPath windowPanelPath(const QRectF &r) const; + + CocoaControlType windowButtonCocoaControl(QStyle::SubControl sc) const; + + void tabLayout(const QStyleOptionTab *opt, QRect *textRect, QRect *iconRect) const override; + static Direction tabDirection(QStyleOptionTab::Shape shape); + static bool verticalTabs(QMacStylePrivate::Direction tabDirection); + +public: + mutable QPointer<QObject> autoDefaultButton; + static QVector<QPointer<QObject> > scrollBars; + + mutable QPointer<QQuickItem> focusWidget; // TODO: rename to focusItem + mutable NSView *backingStoreNSView; + mutable QHash<CocoaControl, NSView *> cocoaControls; + mutable QHash<CocoaControl, NSCell *> cocoaCells; + + QFont smallSystemFont; + QFont miniSystemFont; + + QMacKeyValueObserver appearanceObserver; +}; + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif // QMACSTYLE_MAC_P_P_H diff --git a/src/quicknativestyle/qstyle/qquickcommonstyle.cpp b/src/quicknativestyle/qstyle/qquickcommonstyle.cpp new file mode 100644 index 00000000000..81bd57d4aa2 --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickcommonstyle.cpp @@ -0,0 +1,6083 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcommonstyle.h" +#include "qquickcommonstyle_p.h" +#include "qquickcommonstylepixmaps_p.h" + +#include "qquickstyleoption.h" +#include "qquickdrawutil.h" +#include "qquickstylehelper_p.h" + +#include <QtGui/QWindow> +#include <qfile.h> +#include <private/qguiapplication_p.h> +#include <qpa/qplatformtheme.h> +#include <qbitmap.h> +#include <qcache.h> +#include <qmath.h> +#include <qpainter.h> +#include <qpaintengine.h> +#include <qpainterpath.h> +#include <private/qmath_p.h> +#include <qdebug.h> +#include <qtextformat.h> +#include <qfileinfo.h> +#include <qdir.h> +#include <qsettings.h> +#include <qvariant.h> +#include <qpixmapcache.h> +#include <qmatrix4x4.h> + +#include <limits.h> + +#include <private/qtextengine_p.h> +#include <QtGui/private/qhexstring_p.h> + +QT_BEGIN_NAMESPACE + +static inline qreal dpr(const QWindow *w) +{ + return w != nullptr ? w->devicePixelRatio() : qApp->devicePixelRatio(); +} + +/*! + \class QCommonStyle + \brief The QCommonStyle class encapsulates the common Look and Feel of a GUI. + + \ingroup appearance + \inmodule QtWidgets + + This abstract class implements some of the widget's look and feel + that is common to all GUI styles provided and shipped as part of + Qt. + + Since QCommonStyle inherits QStyle, all of its functions are fully documented + in the QStyle documentation. + \omit + , although the + extra functions that QCommonStyle provides, e.g. + drawComplexControl(), drawControl(), drawPrimitive(), + hitTestComplexControl(), subControlRect(), sizeFromContents(), and + subElementRect() are documented here. + \endomit + + \sa QStyle, QProxyStyle +*/ + +namespace QQC2 { + +QCommonStyle::QCommonStyle() + : QStyle(*new QCommonStylePrivate) +{ } + +QCommonStyle::QCommonStyle(QCommonStylePrivate &dd) + : QStyle(dd) +{ } + +QCommonStyle::~QCommonStyle() +{ } + +void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p) const +{ + Q_D(const QCommonStyle); + switch (pe) { + case PE_FrameButtonBevel: + case PE_FrameButtonTool: + qDrawShadeRect(p, opt->rect, opt->palette, + opt->state & (State_Sunken | State_On), 1, 0); + break; + case PE_PanelButtonCommand: + case PE_PanelButtonBevel: + case PE_PanelButtonTool: + case PE_IndicatorButtonDropDown: + qDrawShadePanel(p, opt->rect, opt->palette, + opt->state & (State_Sunken | State_On), 1, + &opt->palette.brush(QPalette::Button)); + break; + case PE_IndicatorItemViewItemCheck: + proxy()->drawPrimitive(PE_IndicatorCheckBox, opt, p); + break; + case PE_IndicatorCheckBox: + if (opt->state & State_NoChange) { + p->setPen(opt->palette.windowText().color()); + p->fillRect(opt->rect, opt->palette.brush(QPalette::Button)); + p->drawRect(opt->rect); + p->drawLine(opt->rect.topLeft(), opt->rect.bottomRight()); + } else { + qDrawShadePanel(p, opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height(), + opt->palette, opt->state & (State_Sunken | State_On), 1, + &opt->palette.brush(QPalette::Button)); + } + break; + case PE_IndicatorRadioButton: { + QRect ir = opt->rect; + p->setPen(opt->palette.dark().color()); + p->drawArc(opt->rect, 0, 5760); + if (opt->state & (State_Sunken | State_On)) { + ir.adjust(2, 2, -2, -2); + p->setBrush(opt->palette.windowText()); + p->drawEllipse(ir); + } + break; } + case PE_FrameFocusRect: + if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) { + QColor bg = fropt->backgroundColor; + QPen oldPen = p->pen(); + if (bg.isValid()) { + int h, s, v; + bg.getHsv(&h, &s, &v); + if (v >= 128) + p->setPen(Qt::black); + else + p->setPen(Qt::white); + } else { + p->setPen(opt->palette.windowText().color()); + } + QRect focusRect = opt->rect.adjusted(1, 1, -1, -1); + p->drawRect(focusRect.adjusted(0, 0, -1, -1)); //draw pen inclusive + p->setPen(oldPen); + } + break; + case PE_IndicatorMenuCheckMark: { + const int markW = opt->rect.width() > 7 ? 7 : opt->rect.width(); + const int markH = markW; + int posX = opt->rect.x() + (opt->rect.width() - markW)/2 + 1; + int posY = opt->rect.y() + (opt->rect.height() - markH)/2; + + QVector<QLineF> a; + a.reserve(markH); + + int i, xx, yy; + xx = posX; + yy = 3 + posY; + for (i = 0; i < markW/2; ++i) { + a << QLineF(xx, yy, xx, yy + 2); + ++xx; + ++yy; + } + yy -= 2; + for (; i < markH; ++i) { + a << QLineF(xx, yy, xx, yy + 2); + ++xx; + --yy; + } + if (!(opt->state & State_Enabled) && !(opt->state & State_On)) { + p->save(); + p->translate(1, 1); + p->setPen(opt->palette.light().color()); + p->drawLines(a); + p->restore(); + } + p->setPen((opt->state & State_On) ? opt->palette.highlightedText().color() : opt->palette.text().color()); + p->drawLines(a); + break; } + case PE_Frame: + case PE_FrameMenu: + if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + if (pe == PE_FrameMenu || (frame->state & State_Sunken) || (frame->state & State_Raised)) { + qDrawShadePanel(p, frame->rect, frame->palette, frame->state & State_Sunken, + frame->lineWidth); + } else { + qDrawPlainRect(p, frame->rect, frame->palette.windowText().color(), frame->lineWidth); + } + } + break; + case PE_PanelMenuBar: + if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)){ + qDrawShadePanel(p, frame->rect, frame->palette, false, frame->lineWidth, + &frame->palette.brush(QPalette::Button)); + + } + else if (const QStyleOptionToolBar *frame = qstyleoption_cast<const QStyleOptionToolBar *>(opt)){ + qDrawShadePanel(p, frame->rect, frame->palette, false, frame->lineWidth, + &frame->palette.brush(QPalette::Button)); + } + + break; + case PE_PanelMenu: + break; + case PE_PanelToolBar: + break; + case PE_IndicatorProgressChunk: + { + p->fillRect(opt->rect.x(), opt->rect.y() + 3, opt->rect.width() -2, opt->rect.height() - 6, + opt->palette.brush(QPalette::Highlight)); + } + break; + case PE_IndicatorBranch: { + static const int decoration_size = 9; + int mid_h = opt->rect.x() + opt->rect.width() / 2; + int mid_v = opt->rect.y() + opt->rect.height() / 2; + int bef_h = mid_h; + int bef_v = mid_v; + int aft_h = mid_h; + int aft_v = mid_v; + if (opt->state & State_Children) { + int delta = decoration_size / 2; + bef_h -= delta; + bef_v -= delta; + aft_h += delta; + aft_v += delta; + p->drawLine(bef_h + 2, bef_v + 4, bef_h + 6, bef_v + 4); + if (!(opt->state & State_Open)) + p->drawLine(bef_h + 4, bef_v + 2, bef_h + 4, bef_v + 6); + QPen oldPen = p->pen(); + p->setPen(opt->palette.dark().color()); + p->drawRect(bef_h, bef_v, decoration_size - 1, decoration_size - 1); + p->setPen(oldPen); + } + QBrush brush(opt->palette.dark().color(), Qt::Dense4Pattern); + if (opt->state & State_Item) { + if (opt->direction == Qt::RightToLeft) + p->fillRect(opt->rect.left(), mid_v, bef_h - opt->rect.left(), 1, brush); + else + p->fillRect(aft_h, mid_v, opt->rect.right() - aft_h + 1, 1, brush); + } + if (opt->state & State_Sibling) + p->fillRect(mid_h, aft_v, 1, opt->rect.bottom() - aft_v + 1, brush); + if (opt->state & (State_Open | State_Children | State_Item | State_Sibling)) + p->fillRect(mid_h, opt->rect.y(), 1, bef_v - opt->rect.y(), brush); + break; } + case PE_FrameStatusBarItem: + qDrawShadeRect(p, opt->rect, opt->palette, true, 1, 0, nullptr); + break; + case PE_IndicatorHeaderArrow: + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { + QPen oldPen = p->pen(); + if (header->sortIndicator & QStyleOptionHeader::SortUp) { + p->setPen(QPen(opt->palette.light(), 0)); + p->drawLine(opt->rect.x() + opt->rect.width(), opt->rect.y(), + opt->rect.x() + opt->rect.width() / 2, opt->rect.y() + opt->rect.height()); + p->setPen(QPen(opt->palette.dark(), 0)); + const QPoint points[] = { + QPoint(opt->rect.x() + opt->rect.width() / 2, opt->rect.y() + opt->rect.height()), + QPoint(opt->rect.x(), opt->rect.y()), + QPoint(opt->rect.x() + opt->rect.width(), opt->rect.y()), + }; + p->drawPolyline(points, sizeof points / sizeof *points); + } else if (header->sortIndicator & QStyleOptionHeader::SortDown) { + p->setPen(QPen(opt->palette.light(), 0)); + const QPoint points[] = { + QPoint(opt->rect.x(), opt->rect.y() + opt->rect.height()), + QPoint(opt->rect.x() + opt->rect.width(), opt->rect.y() + opt->rect.height()), + QPoint(opt->rect.x() + opt->rect.width() / 2, opt->rect.y()), + }; + p->drawPolyline(points, sizeof points / sizeof *points); + p->setPen(QPen(opt->palette.dark(), 0)); + p->drawLine(opt->rect.x(), opt->rect.y() + opt->rect.height(), + opt->rect.x() + opt->rect.width() / 2, opt->rect.y()); + } + p->setPen(oldPen); + } + break; + case PE_FrameTabBarBase: + if (const QStyleOptionTabBarBase *tbb + = qstyleoption_cast<const QStyleOptionTabBarBase *>(opt)) { + p->save(); + switch (tbb->shape) { + case QStyleOptionTab::RoundedNorth: + case QStyleOptionTab::TriangularNorth: + p->setPen(QPen(tbb->palette.light(), 0)); + p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight()); + break; + case QStyleOptionTab::RoundedWest: + case QStyleOptionTab::TriangularWest: + p->setPen(QPen(tbb->palette.light(), 0)); + p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft()); + break; + case QStyleOptionTab::RoundedSouth: + case QStyleOptionTab::TriangularSouth: + p->setPen(QPen(tbb->palette.shadow(), 0)); + p->drawLine(tbb->rect.left(), tbb->rect.bottom(), + tbb->rect.right(), tbb->rect.bottom()); + p->setPen(QPen(tbb->palette.dark(), 0)); + p->drawLine(tbb->rect.left(), tbb->rect.bottom() - 1, + tbb->rect.right() - 1, tbb->rect.bottom() - 1); + break; + case QStyleOptionTab::RoundedEast: + case QStyleOptionTab::TriangularEast: + p->setPen(QPen(tbb->palette.dark(), 0)); + p->drawLine(tbb->rect.topRight(), tbb->rect.bottomRight()); + break; + } + p->restore(); + } + break; + case PE_IndicatorTabClose: { + if (d->tabBarcloseButtonIcon.isNull()) { + d->tabBarcloseButtonIcon.addPixmap(QPixmap( + QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-closetab-16.png")), + QIcon::Normal, QIcon::Off); + d->tabBarcloseButtonIcon.addPixmap(QPixmap( + QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-closetab-down-16.png")), + QIcon::Normal, QIcon::On); + d->tabBarcloseButtonIcon.addPixmap(QPixmap( + QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-closetab-hover-16.png")), + QIcon::Active, QIcon::Off); + } + + int size = proxy()->pixelMetric(QStyle::PM_SmallIconSize); + QIcon::Mode mode = opt->state & State_Enabled ? + (opt->state & State_Raised ? QIcon::Active : QIcon::Normal) + : QIcon::Disabled; + if (!(opt->state & State_Raised) + && !(opt->state & State_Sunken) + && !(opt->state & QStyle::State_Selected)) + mode = QIcon::Disabled; + + QIcon::State state = opt->state & State_Sunken ? QIcon::On : QIcon::Off; + QPixmap pixmap = d->tabBarcloseButtonIcon.pixmap(QSize(size, size), dpr(opt->window), mode, state); + proxy()->drawItemPixmap(p, opt->rect, Qt::AlignCenter, pixmap); + break; + } + case PE_FrameTabWidget: + case PE_FrameWindow: + qDrawWinPanel(p, opt->rect, opt->palette, false, nullptr); + break; + case PE_FrameLineEdit: + proxy()->drawPrimitive(PE_Frame, opt, p); + break; + case PE_FrameGroupBox: + if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + if (frame->features & QStyleOptionFrame::Flat) { + QRect fr = frame->rect; + QPoint p1(fr.x(), fr.y() + 1); + QPoint p2(fr.x() + fr.width(), p1.y()); + qDrawShadeLine(p, p1, p2, frame->palette, true, + frame->lineWidth, frame->midLineWidth); + } else { + qDrawShadeRect(p, frame->rect.x(), frame->rect.y(), frame->rect.width(), + frame->rect.height(), frame->palette, true, + frame->lineWidth, frame->midLineWidth); + } + } + break; + case PE_FrameDockWidget: + if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + int lw = frame->lineWidth; + if (lw <= 0) + lw = proxy()->pixelMetric(PM_DockWidgetFrameWidth); + + qDrawShadePanel(p, frame->rect, frame->palette, false, lw); + } + break; + case PE_IndicatorToolBarHandle: + p->save(); + p->translate(opt->rect.x(), opt->rect.y()); + if (opt->state & State_Horizontal) { + int x = opt->rect.width() / 3; + if (opt->direction == Qt::RightToLeft) + x -= 2; + if (opt->rect.height() > 4) { + qDrawShadePanel(p, x, 2, 3, opt->rect.height() - 4, + opt->palette, false, 1, nullptr); + qDrawShadePanel(p, x+3, 2, 3, opt->rect.height() - 4, + opt->palette, false, 1, nullptr); + } + } else { + if (opt->rect.width() > 4) { + int y = opt->rect.height() / 3; + qDrawShadePanel(p, 2, y, opt->rect.width() - 4, 3, + opt->palette, false, 1, nullptr); + qDrawShadePanel(p, 2, y+3, opt->rect.width() - 4, 3, + opt->palette, false, 1, nullptr); + } + } + p->restore(); + break; + case PE_IndicatorToolBarSeparator: + { + QPoint p1, p2; + if (opt->state & State_Horizontal) { + p1 = QPoint(opt->rect.width()/2, 0); + p2 = QPoint(p1.x(), opt->rect.height()); + } else { + p1 = QPoint(0, opt->rect.height()/2); + p2 = QPoint(opt->rect.width(), p1.y()); + } + qDrawShadeLine(p, p1, p2, opt->palette, 1, 1, 0); + break; + } + case PE_IndicatorSpinPlus: + case PE_IndicatorSpinMinus: { + QRect r = opt->rect; + int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt); + QRect br = r.adjusted(fw, fw, -fw, -fw); + + int offset = (opt->state & State_Sunken) ? 1 : 0; + int step = (br.width() + 4) / 5; + p->fillRect(br.x() + offset, br.y() + offset +br.height() / 2 - step / 2, + br.width(), step, + opt->palette.buttonText()); + if (pe == PE_IndicatorSpinPlus) + p->fillRect(br.x() + br.width() / 2 - step / 2 + offset, br.y() + offset, + step, br.height(), + opt->palette.buttonText()); + + break; } + case PE_IndicatorSpinUp: + case PE_IndicatorSpinDown: { + QRect r = opt->rect; + int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt); + // QRect br = r.adjusted(fw, fw, -fw, -fw); + int x = r.x(), y = r.y(), w = r.width(), h = r.height(); + int sw = w-4; + if (sw < 3) + break; + else if (!(sw & 1)) + sw--; + sw -= (sw / 7) * 2; // Empty border + int sh = sw/2 + 2; // Must have empty row at foot of arrow + + int sx = x + w / 2 - sw / 2; + int sy = y + h / 2 - sh / 2; + + if (pe == PE_IndicatorSpinUp && fw) + --sy; + + int bsx = 0; + int bsy = 0; + if (opt->state & State_Sunken) { + bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal); + bsy = proxy()->pixelMetric(PM_ButtonShiftVertical); + } + p->save(); + p->translate(sx + bsx, sy + bsy); + p->setPen(opt->palette.buttonText().color()); + p->setBrush(opt->palette.buttonText()); + if (pe == PE_IndicatorSpinDown) { + const QPoint points[] = { QPoint(0, 1), QPoint(sw-1, 1), QPoint(sh-2, sh-1) }; + p->drawPolygon(points, sizeof points / sizeof *points); + } else { + const QPoint points[] = { QPoint(0, sh-1), QPoint(sw-1, sh-1), QPoint(sh-2, 1) }; + p->drawPolygon(points, sizeof points / sizeof *points); + } + p->restore(); + break; } + case PE_PanelTipLabel: { + const QBrush brush(opt->palette.toolTipBase()); + qDrawPlainRect(p, opt->rect, opt->palette.toolTipText().color(), 1, &brush); + break; + } + case PE_IndicatorTabTear: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + bool rtl = tab->direction == Qt::RightToLeft; + const bool horizontal = tab->rect.height() > tab->rect.width(); + const int margin = 4; + QPainterPath path; + + if (horizontal) { + QRect rect = tab->rect.adjusted(rtl ? margin : 0, 0, rtl ? 1 : -margin, 0); + rect.setTop(rect.top() + ((tab->state & State_Selected) ? 1 : 3)); + rect.setBottom(rect.bottom() - ((tab->state & State_Selected) ? 0 : 2)); + + path.moveTo(QPoint(rtl ? rect.right() : rect.left(), rect.top())); + int count = 4; + for (int jags = 1; jags <= count; ++jags, rtl = !rtl) + path.lineTo(QPoint(rtl ? rect.left() : rect.right(), rect.top() + jags * rect.height()/count)); + } else { + QRect rect = tab->rect.adjusted(0, 0, 0, -margin); + rect.setLeft(rect.left() + ((tab->state & State_Selected) ? 1 : 3)); + rect.setRight(rect.right() - ((tab->state & State_Selected) ? 0 : 2)); + + path.moveTo(QPoint(rect.left(), rect.top())); + int count = 4; + for (int jags = 1; jags <= count; ++jags, rtl = !rtl) + path.lineTo(QPoint(rect.left() + jags * rect.width()/count, rtl ? rect.top() : rect.bottom())); + } + + p->setPen(QPen(tab->palette.dark(), qreal(.8))); + p->setBrush(tab->palette.window()); + p->setRenderHint(QPainter::Antialiasing); + p->drawPath(path); + } + break; + case PE_PanelLineEdit: + if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + p->fillRect(panel->rect.adjusted(panel->lineWidth, panel->lineWidth, -panel->lineWidth, -panel->lineWidth), + panel->palette.brush(QPalette::Base)); + + if (panel->lineWidth > 0) + proxy()->drawPrimitive(PE_FrameLineEdit, panel, p); + } + break; + case PE_IndicatorColumnViewArrow: { + if (const QStyleOptionViewItem *viewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { + bool reverse = (viewOpt->direction == Qt::RightToLeft); + p->save(); + QPainterPath path; + int x = viewOpt->rect.x() + 1; + int offset = (viewOpt->rect.height() / 3); + int height = (viewOpt->rect.height()) - offset * 2; + if (height % 2 == 1) + --height; + int x2 = x + height - 1; + if (reverse) { + x = viewOpt->rect.x() + viewOpt->rect.width() - 1; + x2 = x - height + 1; + } + path.moveTo(x, viewOpt->rect.y() + offset); + path.lineTo(x, viewOpt->rect.y() + offset + height); + path.lineTo(x2, viewOpt->rect.y() + offset+height/2); + path.closeSubpath(); + if (viewOpt->state & QStyle::State_Selected ) { + if (viewOpt->showDecorationSelected) { + QColor color = viewOpt->palette.color(QPalette::Active, QPalette::HighlightedText); + p->setPen(color); + p->setBrush(color); + } else { + QColor color = viewOpt->palette.color(QPalette::Active, QPalette::WindowText); + p->setPen(color); + p->setBrush(color); + } + + } else { + QColor color = viewOpt->palette.color(QPalette::Active, QPalette::Mid); + p->setPen(color); + p->setBrush(color); + } + p->drawPath(path); + + // draw the vertical and top triangle line + if (!(viewOpt->state & QStyle::State_Selected)) { + QPainterPath lines; + lines.moveTo(x, viewOpt->rect.y() + offset); + lines.lineTo(x, viewOpt->rect.y() + offset + height); + lines.moveTo(x, viewOpt->rect.y() + offset); + lines.lineTo(x2, viewOpt->rect.y() + offset+height/2); + QColor color = viewOpt->palette.color(QPalette::Active, QPalette::Dark); + p->setPen(color); + p->drawPath(lines); + } + p->restore(); + } + break; } + case PE_IndicatorItemViewItemDrop: { + QRect rect = opt->rect; + if (opt->rect.height() == 0) + p->drawLine(rect.topLeft(), rect.topRight()); + else + p->drawRect(rect); + break; } + case PE_PanelItemViewRow: + if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { + QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; + if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active)) + cg = QPalette::Inactive; + + if ((vopt->state & QStyle::State_Selected) && proxy()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, opt)) + p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Highlight)); + else if (vopt->features & QStyleOptionViewItem::Alternate) + p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase)); + } + break; + case PE_PanelItemViewItem: + if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { + QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; + if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active)) + cg = QPalette::Inactive; + + if (vopt->showDecorationSelected && (vopt->state & QStyle::State_Selected)) { + p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Highlight)); + } else { + if (vopt->backgroundBrush.style() != Qt::NoBrush) { + QPointF oldBO = p->brushOrigin(); + p->setBrushOrigin(vopt->rect.topLeft()); + p->fillRect(vopt->rect, vopt->backgroundBrush); + p->setBrushOrigin(oldBO); + } + + if (vopt->state & QStyle::State_Selected) { + QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, opt); + p->fillRect(textRect, vopt->palette.brush(cg, QPalette::Highlight)); + } + } + } + break; + case PE_PanelScrollAreaCorner: { + const QBrush brush(opt->palette.brush(QPalette::Window)); + p->fillRect(opt->rect, brush); + } break; + case PE_IndicatorArrowUp: + case PE_IndicatorArrowDown: + case PE_IndicatorArrowRight: + case PE_IndicatorArrowLeft: + { + if (opt->rect.width() <= 1 || opt->rect.height() <= 1) + break; + QRect r = opt->rect; + int size = qMin(r.height(), r.width()); + QPixmap pixmap; + QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-") + % QLatin1String(metaObject()->className()), opt, QSize(size, size)) + % HexString<uint>(pe); + if (!QPixmapCache::find(pixmapName, &pixmap)) { + qreal pixelRatio = p->device()->devicePixelRatioF(); + int border = qRound(pixelRatio*(size/5)); + int sqsize = qRound(pixelRatio*(2*(size/2))); + QImage image(sqsize, sqsize, QImage::Format_ARGB32_Premultiplied); + image.fill(0); + QPainter imagePainter(&image); + + QPolygon a; + switch (pe) { + case PE_IndicatorArrowUp: + a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize - border, sqsize/2); + break; + case PE_IndicatorArrowDown: + a.setPoints(3, border, sqsize/2, sqsize/2, sqsize - border, sqsize - border, sqsize/2); + break; + case PE_IndicatorArrowRight: + a.setPoints(3, sqsize - border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border); + break; + case PE_IndicatorArrowLeft: + a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border); + break; + default: + break; + } + + int bsx = 0; + int bsy = 0; + + if (opt->state & State_Sunken) { + bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt); + bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt); + } + + QRect bounds = a.boundingRect(); + int sx = sqsize / 2 - bounds.center().x() - 1; + int sy = sqsize / 2 - bounds.center().y() - 1; + imagePainter.translate(sx + bsx, sy + bsy); + imagePainter.setPen(opt->palette.buttonText().color()); + imagePainter.setBrush(opt->palette.buttonText()); + + if (!(opt->state & State_Enabled)) { + imagePainter.translate(1, 1); + imagePainter.setBrush(opt->palette.light().color()); + imagePainter.setPen(opt->palette.light().color()); + imagePainter.drawPolygon(a); + imagePainter.translate(-1, -1); + imagePainter.setBrush(opt->palette.mid().color()); + imagePainter.setPen(opt->palette.mid().color()); + } + + imagePainter.drawPolygon(a); + imagePainter.end(); + pixmap = QPixmap::fromImage(image); + pixmap.setDevicePixelRatio(pixelRatio); + QPixmapCache::insert(pixmapName, pixmap); + } + int xOffset = r.x() + (r.width() - size)/2; + int yOffset = r.y() + (r.height() - size)/2; + p->drawPixmap(xOffset, yOffset, pixmap); + } + break; + default: + break; + } +} + +static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbutton, + const QRect &rect, QPainter *painter) +{ + QStyle::PrimitiveElement pe; + switch (toolbutton->arrowType) { + case Qt::LeftArrow: + pe = QStyle::PE_IndicatorArrowLeft; + break; + case Qt::RightArrow: + pe = QStyle::PE_IndicatorArrowRight; + break; + case Qt::UpArrow: + pe = QStyle::PE_IndicatorArrowUp; + break; + case Qt::DownArrow: + pe = QStyle::PE_IndicatorArrowDown; + break; + default: + return; + } + QStyleOption arrowOpt = *toolbutton; + arrowOpt.rect = rect; + style->drawPrimitive(pe, &arrowOpt, painter); +} + +static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth, int maxHeight = -1, int *lastVisibleLine = nullptr) +{ + if (lastVisibleLine) + *lastVisibleLine = -1; + qreal height = 0; + qreal widthUsed = 0; + textLayout.beginLayout(); + int i = 0; + while (true) { + QTextLine line = textLayout.createLine(); + if (!line.isValid()) + break; + line.setLineWidth(lineWidth); + line.setPosition(QPointF(0, height)); + height += line.height(); + widthUsed = qMax(widthUsed, line.naturalTextWidth()); + // we assume that the height of the next line is the same as the current one + if (maxHeight > 0 && lastVisibleLine && height + line.height() > maxHeight) { + const QTextLine nextLine = textLayout.createLine(); + *lastVisibleLine = nextLine.isValid() ? i : -1; + break; + } + ++i; + } + textLayout.endLayout(); + return QSizeF(widthUsed, height); +} + +QString QCommonStylePrivate::calculateElidedText(const QString &text, const QTextOption &textOption, + const QFont &font, const QRect &textRect, const Qt::Alignment valign, + Qt::TextElideMode textElideMode, int flags, + bool lastVisibleLineShouldBeElided, QPointF *paintStartPosition) const +{ + QTextLayout textLayout(text, font); + textLayout.setTextOption(textOption); + + // In AlignVCenter mode when more than one line is displayed and the height only allows + // some of the lines it makes no sense to display those. From a users perspective it makes + // more sense to see the start of the text instead something inbetween. + const bool vAlignmentOptimization = paintStartPosition && valign.testFlag(Qt::AlignVCenter); + + int lastVisibleLine = -1; + viewItemTextLayout(textLayout, textRect.width(), vAlignmentOptimization ? textRect.height() : -1, &lastVisibleLine); + + const QRectF boundingRect = textLayout.boundingRect(); + // don't care about LTR/RTL here, only need the height + const QRect layoutRect = QStyle::alignedRect(Qt::LayoutDirectionAuto, valign, + boundingRect.size().toSize(), textRect); + + if (paintStartPosition) + *paintStartPosition = QPointF(textRect.x(), layoutRect.top()); + + QString ret; + qreal height = 0; + const int lineCount = textLayout.lineCount(); + for (int i = 0; i < lineCount; ++i) { + const QTextLine line = textLayout.lineAt(i); + height += line.height(); + + // above visible rect + if (height + layoutRect.top() <= textRect.top()) { + if (paintStartPosition) + paintStartPosition->ry() += line.height(); + continue; + } + + const int start = line.textStart(); + const int length = line.textLength(); + const bool drawElided = line.naturalTextWidth() > textRect.width(); + bool elideLastVisibleLine = lastVisibleLine == i; + if (!drawElided && i + 1 < lineCount && lastVisibleLineShouldBeElided) { + const QTextLine nextLine = textLayout.lineAt(i + 1); + const int nextHeight = height + nextLine.height() / 2; + // elide when less than the next half line is visible + if (nextHeight + layoutRect.top() > textRect.height() + textRect.top()) + elideLastVisibleLine = true; + } + + QString text = textLayout.text().mid(start, length); + if (drawElided || elideLastVisibleLine) { + if (elideLastVisibleLine) { + if (text.endsWith(QChar::LineSeparator)) + text.chop(1); + text += QChar(0x2026); + } + const QStackTextEngine engine(text, font); + ret += engine.elidedText(textElideMode, textRect.width(), flags); + + // no newline for the last line (last visible or real) + // sometimes drawElided is true but no eliding is done so the text ends + // with QChar::LineSeparator - don't add another one. This happened with + // arabic text in the testcase for QTBUG-72805 + if (i < lineCount - 1 && + !ret.endsWith(QChar::LineSeparator)) + ret += QChar::LineSeparator; + } else { + ret += text; + } + + // below visible text, can stop + if ((height + layoutRect.top() >= textRect.bottom()) || + (lastVisibleLine >= 0 && lastVisibleLine == i)) + break; + } + return ret; +} + +QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int role) const +{ + switch (role) { + case Qt::CheckStateRole: + if (option->features & QStyleOptionViewItem::HasCheckIndicator) + return QSize(proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth, option), + proxyStyle->pixelMetric(QStyle::PM_IndicatorHeight, option)); + break; + case Qt::DisplayRole: + if (option->features & QStyleOptionViewItem::HasDisplay) { + QTextOption textOption; + textOption.setWrapMode(QTextOption::WordWrap); + QTextLayout textLayout(option->text, option->font); + textLayout.setTextOption(textOption); + const bool wrapText = option->features & QStyleOptionViewItem::WrapText; + const int textMargin = proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, option) + 1; + QRect bounds = option->rect; + switch (option->decorationPosition) { + case QStyleOptionViewItem::Left: + case QStyleOptionViewItem::Right: { + if (wrapText && bounds.isValid()) { + int width = bounds.width() - 2 * textMargin; + if (option->features & QStyleOptionViewItem::HasDecoration) + width -= option->decorationSize.width() + 2 * textMargin; + bounds.setWidth(width); + } else + bounds.setWidth(QFIXED_MAX); + break; + } + case QStyleOptionViewItem::Top: + case QStyleOptionViewItem::Bottom: + if (wrapText) + bounds.setWidth(bounds.isValid() ? bounds.width() - 2 * textMargin : option->decorationSize.width()); + else + bounds.setWidth(QFIXED_MAX); + break; + default: + break; + } + + if (wrapText && option->features & QStyleOptionViewItem::HasCheckIndicator) + bounds.setWidth(bounds.width() - proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth) - 2 * textMargin); + + const int lineWidth = bounds.width(); + const QSizeF size = viewItemTextLayout(textLayout, lineWidth); + return QSize(qCeil(size.width()) + 2 * textMargin, qCeil(size.height())); + } + break; + case Qt::DecorationRole: + if (option->features & QStyleOptionViewItem::HasDecoration) { + return option->decorationSize; + } + break; + default: + break; + } + + return QSize(0, 0); +} + +void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect) const +{ + const int textMargin = proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr) + 1; + + QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding + const bool wrapText = option->features & QStyleOptionViewItem::WrapText; + QTextOption textOption; + textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap); + textOption.setTextDirection(option->direction); + textOption.setAlignment(QStyle::visualAlignment(option->direction, option->displayAlignment)); + + QPointF paintPosition; + const QString newText = calculateElidedText(option->text, textOption, + option->font, textRect, option->displayAlignment, + option->textElideMode, 0, + true, &paintPosition); + + QTextLayout textLayout(newText, option->font); + textLayout.setTextOption(textOption); + viewItemTextLayout(textLayout, textRect.width()); + textLayout.draw(p, paintPosition); +} + +/*! \internal + compute the position for the different component of an item (pixmap, text, checkbox) + + Set sizehint to false to layout the elements inside opt->rect. Set sizehint to true to ignore + opt->rect and return rectangles in infinite space + + Code duplicated in QItemDelegate::doLayout +*/ +void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItem *opt, QRect *checkRect, + QRect *pixmapRect, QRect *textRect, bool sizehint) const +{ + Q_ASSERT(checkRect && pixmapRect && textRect); + *pixmapRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DecorationRole)); + *textRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DisplayRole)); + *checkRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::CheckStateRole)); + + const bool hasCheck = checkRect->isValid(); + const bool hasPixmap = pixmapRect->isValid(); + const bool hasText = textRect->isValid(); + const bool hasMargin = (hasText | hasPixmap | hasCheck); + const int frameHMargin = hasMargin ? + proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt) + 1 : 0; + const int textMargin = hasText ? frameHMargin : 0; + const int pixmapMargin = hasPixmap ? frameHMargin : 0; + const int checkMargin = hasCheck ? frameHMargin : 0; + const int x = opt->rect.left(); + const int y = opt->rect.top(); + int w, h; + + if (textRect->height() == 0 && (!hasPixmap || !sizehint)) { + //if there is no text, we still want to have a decent height for the item sizeHint and the editor size + textRect->setHeight(opt->fontMetrics.height()); + } + + QSize pm(0, 0); + if (hasPixmap) { + pm = pixmapRect->size(); + pm.rwidth() += 2 * pixmapMargin; + } + if (sizehint) { + h = qMax(checkRect->height(), qMax(textRect->height(), pm.height())); + if (opt->decorationPosition == QStyleOptionViewItem::Left + || opt->decorationPosition == QStyleOptionViewItem::Right) { + w = textRect->width() + pm.width(); + } else { + w = qMax(textRect->width(), pm.width()); + } + } else { + w = opt->rect.width(); + h = opt->rect.height(); + } + + int cw = 0; + QRect check; + if (hasCheck) { + cw = checkRect->width() + 2 * checkMargin; + if (sizehint) w += cw; + if (opt->direction == Qt::RightToLeft) { + check.setRect(x + w - cw, y, cw, h); + } else { + check.setRect(x, y, cw, h); + } + } + + QRect display; + QRect decoration; + switch (opt->decorationPosition) { + case QStyleOptionViewItem::Top: { + if (hasPixmap) + pm.setHeight(pm.height() + pixmapMargin); // add space + h = sizehint ? textRect->height() : h - pm.height(); + + if (opt->direction == Qt::RightToLeft) { + decoration.setRect(x, y, w - cw, pm.height()); + display.setRect(x, y + pm.height(), w - cw, h); + } else { + decoration.setRect(x + cw, y, w - cw, pm.height()); + display.setRect(x + cw, y + pm.height(), w - cw, h); + } + break; } + case QStyleOptionViewItem::Bottom: { + if (hasText) + textRect->setHeight(textRect->height() + textMargin); // add space + h = sizehint ? textRect->height() + pm.height() : h; + + if (opt->direction == Qt::RightToLeft) { + display.setRect(x, y, w - cw, textRect->height()); + decoration.setRect(x, y + textRect->height(), w - cw, h - textRect->height()); + } else { + display.setRect(x + cw, y, w - cw, textRect->height()); + decoration.setRect(x + cw, y + textRect->height(), w - cw, h - textRect->height()); + } + break; } + case QStyleOptionViewItem::Left: { + if (opt->direction == Qt::LeftToRight) { + decoration.setRect(x + cw, y, pm.width(), h); + display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h); + } else { + display.setRect(x, y, w - pm.width() - cw, h); + decoration.setRect(display.right() + 1, y, pm.width(), h); + } + break; } + case QStyleOptionViewItem::Right: { + if (opt->direction == Qt::LeftToRight) { + display.setRect(x + cw, y, w - pm.width() - cw, h); + decoration.setRect(display.right() + 1, y, pm.width(), h); + } else { + decoration.setRect(x, y, pm.width(), h); + display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h); + } + break; } + default: + qWarning("doLayout: decoration position is invalid"); + decoration = *pixmapRect; + break; + } + + if (!sizehint) { // we only need to do the internal layout if we are going to paint + *checkRect = QStyle::alignedRect(opt->direction, Qt::AlignCenter, + checkRect->size(), check); + *pixmapRect = QStyle::alignedRect(opt->direction, opt->decorationAlignment, + pixmapRect->size(), decoration); + // the text takes up all available space, unless the decoration is not shown as selected + if (opt->showDecorationSelected) + *textRect = display; + else + *textRect = QStyle::alignedRect(opt->direction, opt->displayAlignment, + textRect->size().boundedTo(display.size()), display); + } else { + *checkRect = check; + *pixmapRect = decoration; + *textRect = display; + } +} + +QString QCommonStylePrivate::toolButtonElideText(const QStyleOptionToolButton *option, + const QRect &textRect, int flags) const +{ + if (option->fontMetrics.horizontalAdvance(option->text) <= textRect.width()) + return option->text; + + QString text = option->text; + text.replace(QLatin1Char('\n'), QChar::LineSeparator); + QTextOption textOption; + textOption.setWrapMode(QTextOption::ManualWrap); + textOption.setTextDirection(option->direction); + + return calculateElidedText(text, textOption, + option->font, textRect, Qt::AlignTop, + Qt::ElideMiddle, flags, + false, nullptr); +} + +/*! \internal + Compute the textRect and the pixmapRect from the opt rect + + Uses the same computation than in QTabBar::tabSizeHint + */ +void QCommonStylePrivate::tabLayout(const QStyleOptionTab *opt, QRect *textRect, QRect *iconRect) const +{ + Q_ASSERT(textRect); + Q_ASSERT(iconRect); + QRect tr = opt->rect; + bool verticalTabs = opt->shape == QStyleOptionTab::RoundedEast + || opt->shape == QStyleOptionTab::RoundedWest + || opt->shape == QStyleOptionTab::TriangularEast + || opt->shape == QStyleOptionTab::TriangularWest; + if (verticalTabs) + tr.setRect(0, 0, tr.height(), tr.width()); // 0, 0 as we will have a translate transform + + int verticalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftVertical, opt); + int horizontalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, opt); + int hpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabHSpace, opt) / 2; + int vpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabVSpace, opt) / 2; + if (opt->shape == QStyleOptionTab::RoundedSouth || opt->shape == QStyleOptionTab::TriangularSouth) + verticalShift = -verticalShift; + tr.adjust(hpadding, verticalShift - vpadding, horizontalShift - hpadding, vpadding); + bool selected = opt->state & QStyle::State_Selected; + if (selected) { + tr.setTop(tr.top() - verticalShift); + tr.setRight(tr.right() - horizontalShift); + } + + // left widget + if (!opt->leftButtonSize.isEmpty()) { + tr.setLeft(tr.left() + 4 + + (verticalTabs ? opt->leftButtonSize.height() : opt->leftButtonSize.width())); + } + // right widget + if (!opt->rightButtonSize.isEmpty()) { + tr.setRight(tr.right() - 4 - + (verticalTabs ? opt->rightButtonSize.height() : opt->rightButtonSize.width())); + } + + // icon + if (!opt->icon.isNull()) { + QSize iconSize = opt->iconSize; + if (!iconSize.isValid()) { + int iconExtent = proxyStyle->pixelMetric(QStyle::PM_SmallIconSize); + iconSize = QSize(iconExtent, iconExtent); + } + QSize tabIconSize = opt->icon.actualSize(iconSize, + (opt->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled, + (opt->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off); + // High-dpi icons do not need adjustment; make sure tabIconSize is not larger than iconSize + tabIconSize = QSize(qMin(tabIconSize.width(), iconSize.width()), qMin(tabIconSize.height(), iconSize.height())); + + const int offsetX = (iconSize.width() - tabIconSize.width()) / 2; + *iconRect = QRect(tr.left() + offsetX, tr.center().y() - tabIconSize.height() / 2, + tabIconSize.width(), tabIconSize.height()); + if (!verticalTabs) + *iconRect = QStyle::visualRect(opt->direction, opt->rect, *iconRect); + tr.setLeft(tr.left() + tabIconSize.width() + 4); + } + + if (!verticalTabs) + tr = QStyle::visualRect(opt->direction, opt->rect, tr); + + *textRect = tr; +} + +/*! + \reimp +*/ +void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, QPainter *p) const +{ + Q_D(const QCommonStyle); + + // TODO: Set opt->window manually for now before calling any of the drawing functions. opt->window is + // pulled of the widget is QStyle. But now that we have no widget, we need some other + // solution. + Q_ASSERT(opt->window); + + switch (element) { + + case CE_PushButton: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + proxy()->drawControl(CE_PushButtonBevel, btn, p); + QStyleOptionButton subopt = *btn; + subopt.rect = subElementRect(SE_PushButtonContents, btn); + proxy()->drawControl(CE_PushButtonLabel, &subopt, p); + } + break; + case CE_PushButtonBevel: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + QRect br = btn->rect; + int dbi = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn); + if (btn->features & QStyleOptionButton::DefaultButton) + proxy()->drawPrimitive(PE_FrameDefaultButton, opt, p); + if (btn->features & QStyleOptionButton::AutoDefaultButton) + br.setCoords(br.left() + dbi, br.top() + dbi, br.right() - dbi, br.bottom() - dbi); + if (!(btn->features & (QStyleOptionButton::Flat | QStyleOptionButton::CommandLinkButton)) + || btn->state & (State_Sunken | State_On) + || (btn->features & QStyleOptionButton::CommandLinkButton && btn->state & State_MouseOver)) { + QStyleOptionButton tmpBtn = *btn; + tmpBtn.rect = br; + proxy()->drawPrimitive(PE_PanelButtonCommand, &tmpBtn, p); + } + if (btn->features & QStyleOptionButton::HasMenu) { + int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, btn); + QRect ir = btn->rect; + QStyleOptionButton newBtn = *btn; + newBtn.rect = QRect(ir.right() - mbi + 2, ir.height()/2 - mbi/2 + 3, mbi - 6, mbi - 6); + proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p); + } + if (btn->state & State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*btn); + fropt.rect = subElementRect(SE_PushButtonFocusRect, btn); + proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p); + } + } + break; + case CE_PushButtonLabel: + if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + QRect textRect = button->rect; + uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic; + if (!proxy()->styleHint(SH_UnderlineShortcut, button)) + tf |= Qt::TextHideMnemonic; + + if (!button->icon.isNull()) { + //Center both icon and text + QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; + if (mode == QIcon::Normal && button->state & State_HasFocus) + mode = QIcon::Active; + QIcon::State state = QIcon::Off; + if (button->state & State_On) + state = QIcon::On; + + QPixmap pixmap = button->icon.pixmap(button->iconSize, dpr(opt->window), mode, state); + int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio(); + int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio(); + int labelWidth = pixmapWidth; + int labelHeight = pixmapHeight; + int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint() + if (!button->text.isEmpty()) { + int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width(); + labelWidth += (textWidth + iconSpacing); + } + + QRect iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2, + textRect.y() + (textRect.height() - labelHeight) / 2, + pixmapWidth, pixmapHeight); + + iconRect = visualRect(button->direction, textRect, iconRect); + + if (button->direction == Qt::RightToLeft) { + tf |= Qt::AlignRight; + textRect.setRight(iconRect.left() - iconSpacing); + } else { + tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead + textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing); + } + + if (button->state & (State_On | State_Sunken)) + iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt), + proxy()->pixelMetric(PM_ButtonShiftVertical, opt)); + p->drawPixmap(iconRect, pixmap); + } else { + tf |= Qt::AlignHCenter; + } + if (button->state & (State_On | State_Sunken)) + textRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt), + proxy()->pixelMetric(PM_ButtonShiftVertical, opt)); + + if (button->features & QStyleOptionButton::HasMenu) { + int indicatorSize = proxy()->pixelMetric(PM_MenuButtonIndicator, button); + if (button->direction == Qt::LeftToRight) + textRect = textRect.adjusted(0, 0, -indicatorSize, 0); + else + textRect = textRect.adjusted(indicatorSize, 0, 0, 0); + } + proxy()->drawItemText(p, textRect, tf, button->palette, (button->state & State_Enabled), + button->text, QPalette::ButtonText); + } + break; + case CE_RadioButton: + case CE_CheckBox: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + bool isRadio = (element == CE_RadioButton); + QStyleOptionButton subopt = *btn; + subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator + : SE_CheckBoxIndicator, btn); + proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox, + &subopt, p); + subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents + : SE_CheckBoxContents, btn); + proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p); + if (btn->state & State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*btn); + fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect + : SE_CheckBoxFocusRect, btn); + proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p); + } + } + break; + case CE_RadioButtonLabel: + case CE_CheckBoxLabel: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter); + + if (!proxy()->styleHint(SH_UnderlineShortcut, btn)) + alignment |= Qt::TextHideMnemonic; + QPixmap pix; + QRect textRect = btn->rect; + if (!btn->icon.isNull()) { + pix = btn->icon.pixmap(btn->iconSize, dpr(opt->window), btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled); + proxy()->drawItemPixmap(p, btn->rect, alignment, pix); + if (btn->direction == Qt::RightToLeft) + textRect.setRight(textRect.right() - btn->iconSize.width() - 4); + else + textRect.setLeft(textRect.left() + btn->iconSize.width() + 4); + } + if (!btn->text.isEmpty()){ + proxy()->drawItemText(p, textRect, alignment | Qt::TextShowMnemonic, + btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText); + } + } + break; + case CE_MenuScroller: { + QStyleOption arrowOpt = *opt; + arrowOpt.state |= State_Enabled; + proxy()->drawPrimitive(((opt->state & State_DownArrow) ? PE_IndicatorArrowDown : PE_IndicatorArrowUp), &arrowOpt, p); + break; } + case CE_MenuTearoff: + if (opt->state & State_Selected) + p->fillRect(opt->rect, opt->palette.brush(QPalette::Highlight)); + else + p->fillRect(opt->rect, opt->palette.brush(QPalette::Button)); + p->setPen(QPen(opt->palette.dark().color(), 1, Qt::DashLine)); + p->drawLine(opt->rect.x() + 2, opt->rect.y() + opt->rect.height() / 2 - 1, + opt->rect.x() + opt->rect.width() - 4, + opt->rect.y() + opt->rect.height() / 2 - 1); + p->setPen(QPen(opt->palette.light().color(), 1, Qt::DashLine)); + p->drawLine(opt->rect.x() + 2, opt->rect.y() + opt->rect.height() / 2, + opt->rect.x() + opt->rect.width() - 4, opt->rect.y() + opt->rect.height() / 2); + break; + case CE_MenuBarItem: + if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { + uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip + | Qt::TextSingleLine; + if (!proxy()->styleHint(SH_UnderlineShortcut, mbi)) + alignment |= Qt::TextHideMnemonic; + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + QPixmap pix = mbi->icon.pixmap(QSize(iconExtent, iconExtent), dpr(opt->window), + mbi->state.testFlag(State_Enabled) ? QIcon::Normal : QIcon::Disabled); + if (!pix.isNull()) + proxy()->drawItemPixmap(p,mbi->rect, alignment, pix); + else + proxy()->drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, + mbi->text, QPalette::ButtonText); + } + break; + case CE_MenuBarEmptyArea: + break; + case CE_ProgressBar: + if (const QStyleOptionProgressBar *pb + = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) { + QStyleOptionProgressBar subopt = *pb; + subopt.rect = subElementRect(SE_ProgressBarGroove, pb); + proxy()->drawControl(CE_ProgressBarGroove, &subopt, p); + subopt.rect = subElementRect(SE_ProgressBarContents, pb); + proxy()->drawControl(CE_ProgressBarContents, &subopt, p); + if (pb->textVisible) { + subopt.rect = subElementRect(SE_ProgressBarLabel, pb); + proxy()->drawControl(CE_ProgressBarLabel, &subopt, p); + } + } + break; + case CE_ProgressBarGroove: + if (opt->rect.isValid()) + qDrawShadePanel(p, opt->rect, opt->palette, true, 1, + &opt->palette.brush(QPalette::Window)); + break; + case CE_ProgressBarLabel: + if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) { + QPalette::ColorRole textRole = QPalette::NoRole; + if ((pb->textAlignment & Qt::AlignCenter) && pb->textVisible + && ((qint64(pb->progress) - qint64(pb->minimum)) * 2 >= (qint64(pb->maximum) - qint64(pb->minimum)))) { + textRole = QPalette::HighlightedText; + //Draw text shadow, This will increase readability when the background of same color + QRect shadowRect(pb->rect); + shadowRect.translate(1,1); + QColor shadowColor = (pb->palette.color(textRole).value() <= 128) + ? QColor(255,255,255,160) : QColor(0,0,0,160); + QPalette shadowPalette = pb->palette; + shadowPalette.setColor(textRole, shadowColor); + proxy()->drawItemText(p, shadowRect, Qt::AlignCenter | Qt::TextSingleLine, shadowPalette, + pb->state & State_Enabled, pb->text, textRole); + } + proxy()->drawItemText(p, pb->rect, Qt::AlignCenter | Qt::TextSingleLine, pb->palette, + pb->state & State_Enabled, pb->text, textRole); + } + break; + case CE_ProgressBarContents: + if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) { + + QRect rect = pb->rect; + const bool inverted = pb->invertedAppearance; + qint64 minimum = qint64(pb->minimum); + qint64 maximum = qint64(pb->maximum); + qint64 progress = qint64(pb->progress); + + QPalette pal2 = pb->palette; + // Correct the highlight color if it is the same as the background + if (pal2.highlight() == pal2.window()) + pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active, + QPalette::Highlight)); + bool reverse = pb->direction == Qt::RightToLeft; + if (inverted) + reverse = !reverse; + int w = rect.width(); + if (pb->minimum == 0 && pb->maximum == 0) { + // draw busy indicator + int x = (progress - minimum) % (w * 2); + if (x > w) + x = 2 * w - x; + x = reverse ? rect.right() - x : x + rect.x(); + p->setPen(QPen(pal2.highlight().color(), 4)); + p->drawLine(x, rect.y(), x, rect.height()); + } else { + const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, pb); + if (!unit_width) + return; + + int u; + if (unit_width > 1) + u = ((rect.width() + unit_width) / unit_width); + else + u = w / unit_width; + qint64 p_v = progress - minimum; + qint64 t_s = (maximum - minimum) ? (maximum - minimum) : qint64(1); + + if (u > 0 && p_v >= INT_MAX / u && t_s >= u) { + // scale down to something usable. + p_v /= u; + t_s /= u; + } + + // nu < tnu, if last chunk is only a partial chunk + int tnu, nu; + tnu = nu = p_v * u / t_s; + + if (nu * unit_width > w) + --nu; + + // Draw nu units out of a possible u of unit_width + // width, each a rectangle bordered by background + // color, all in a sunken panel with a percentage text + // display at the end. + int x = 0; + int x0 = reverse ? rect.right() - ((unit_width > 1) ? unit_width : 0) + : rect.x(); + + QStyleOptionProgressBar pbBits = *pb; + pbBits.rect = rect; + pbBits.palette = pal2; + int myY = pbBits.rect.y(); + int myHeight = pbBits.rect.height(); + pbBits.state = State_Horizontal; + for (int i = 0; i < nu; ++i) { + pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight); + proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p); + x += reverse ? -unit_width : unit_width; + } + + // Draw the last partial chunk to fill up the + // progress bar entirely + if (nu < tnu) { + int pixels_left = w - (nu * unit_width); + int offset = reverse ? x0 + x + unit_width-pixels_left : x0 + x; + pbBits.rect.setRect(offset, myY, pixels_left, myHeight); + proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p); + } + } + } + break; + case CE_HeaderLabel: + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { + QRect rect = header->rect; + if (!header->icon.isNull()) { + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + QPixmap pixmap + = header->icon.pixmap(QSize(iconExtent, iconExtent), dpr(opt->window), + header->state.testFlag(State_Enabled) ? QIcon::Normal : QIcon::Disabled); + int pixw = pixmap.width() / pixmap.devicePixelRatio(); + + QRect aligned = alignedRect(header->direction, QFlag(header->iconAlignment), pixmap.size() / pixmap.devicePixelRatio(), rect); + QRect inter = aligned.intersected(rect); + p->drawPixmap(inter.x(), inter.y(), pixmap, + inter.x() - aligned.x(), inter.y() - aligned.y(), + aligned.width() * pixmap.devicePixelRatio(), + pixmap.height() * pixmap.devicePixelRatio()); + + const int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt); + if (header->direction == Qt::LeftToRight) + rect.setLeft(rect.left() + pixw + margin); + else + rect.setRight(rect.right() - pixw - margin); + } + if (header->state & QStyle::State_On) { + QFont fnt = p->font(); + fnt.setBold(true); + p->setFont(fnt); + } + proxy()->drawItemText(p, rect, header->textAlignment, header->palette, + (header->state & State_Enabled), header->text, QPalette::ButtonText); + } + break; + case CE_ToolButtonLabel: + if (const QStyleOptionToolButton *toolbutton + = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) { + QRect rect = toolbutton->rect; + int shiftX = 0; + int shiftY = 0; + if (toolbutton->state & (State_Sunken | State_On)) { + shiftX = proxy()->pixelMetric(PM_ButtonShiftHorizontal, toolbutton); + shiftY = proxy()->pixelMetric(PM_ButtonShiftVertical, toolbutton); + } + // Arrow type always overrules and is always shown + bool hasArrow = toolbutton->features & QStyleOptionToolButton::Arrow; + if (((!hasArrow && toolbutton->icon.isNull()) && !toolbutton->text.isEmpty()) + || toolbutton->toolButtonStyle == Qt::ToolButtonTextOnly) { + int alignment = Qt::AlignCenter | Qt::TextShowMnemonic; + if (!proxy()->styleHint(SH_UnderlineShortcut, opt)) + alignment |= Qt::TextHideMnemonic; + rect.translate(shiftX, shiftY); + p->setFont(toolbutton->font); + proxy()->drawItemText(p, rect, alignment, toolbutton->palette, + opt->state & State_Enabled, toolbutton->text, + QPalette::ButtonText); + } else { + QPixmap pm; + QSize pmSize = toolbutton->iconSize; + if (!toolbutton->icon.isNull()) { + QIcon::State state = toolbutton->state & State_On ? QIcon::On : QIcon::Off; + QIcon::Mode mode; + if (!(toolbutton->state & State_Enabled)) + mode = QIcon::Disabled; + else if ((opt->state & State_MouseOver) && (opt->state & State_AutoRaise)) + mode = QIcon::Active; + else + mode = QIcon::Normal; + pm = toolbutton->icon.pixmap(toolbutton->rect.size().boundedTo(toolbutton->iconSize), + dpr(opt->window), mode, state); + pmSize = pm.size() / pm.devicePixelRatio(); + } + + if (toolbutton->toolButtonStyle != Qt::ToolButtonIconOnly) { + p->setFont(toolbutton->font); + QRect pr = rect, + tr = rect; + int alignment = Qt::TextShowMnemonic; + if (!proxy()->styleHint(SH_UnderlineShortcut, opt)) + alignment |= Qt::TextHideMnemonic; + + if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) { + pr.setHeight(pmSize.height() + 4); //### 4 is currently hardcoded in QToolButton::sizeHint() + tr.adjust(0, pr.height() - 1, 0, -1); + pr.translate(shiftX, shiftY); + if (!hasArrow) { + proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pm); + } else { + drawArrow(proxy(), toolbutton, pr, p); + } + alignment |= Qt::AlignCenter; + } else { + pr.setWidth(pmSize.width() + 4); //### 4 is currently hardcoded in QToolButton::sizeHint() + tr.adjust(pr.width(), 0, 0, 0); + pr.translate(shiftX, shiftY); + if (!hasArrow) { + proxy()->drawItemPixmap(p, QStyle::visualRect(opt->direction, rect, pr), Qt::AlignCenter, pm); + } else { + drawArrow(proxy(), toolbutton, pr, p); + } + alignment |= Qt::AlignLeft | Qt::AlignVCenter; + } + tr.translate(shiftX, shiftY); + const QString text = d->toolButtonElideText(toolbutton, tr, alignment); + proxy()->drawItemText(p, QStyle::visualRect(opt->direction, rect, tr), alignment, toolbutton->palette, + toolbutton->state & State_Enabled, text, + QPalette::ButtonText); + } else { + rect.translate(shiftX, shiftY); + if (hasArrow) { + drawArrow(proxy(), toolbutton, rect, p); + } else { + proxy()->drawItemPixmap(p, rect, Qt::AlignCenter, pm); + } + } + } + } + break; + case CE_ToolBoxTab: + if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) { + proxy()->drawControl(CE_ToolBoxTabShape, tb, p); + proxy()->drawControl(CE_ToolBoxTabLabel, tb, p); + } + break; + case CE_ToolBoxTabShape: + if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) { + p->setPen(tb->palette.mid().color().darker(150)); + int d = 20 + tb->rect.height() - 3; + if (tb->direction != Qt::RightToLeft) { + const QPoint points[] = { + QPoint(-1, tb->rect.height() + 1), + QPoint(-1, 1), + QPoint(tb->rect.width() - d, 1), + QPoint(tb->rect.width() - 20, tb->rect.height() - 2), + QPoint(tb->rect.width() - 1, tb->rect.height() - 2), + QPoint(tb->rect.width() - 1, tb->rect.height() + 1), + QPoint(-1, tb->rect.height() + 1), + }; + p->drawPolygon(points, sizeof points / sizeof *points); + } else { + const QPoint points[] = { + QPoint(tb->rect.width(), tb->rect.height() + 1), + QPoint(tb->rect.width(), 1), + QPoint(d - 1, 1), + QPoint(20 - 1, tb->rect.height() - 2), + QPoint(0, tb->rect.height() - 2), + QPoint(0, tb->rect.height() + 1), + QPoint(tb->rect.width(), tb->rect.height() + 1), + }; + p->drawPolygon(points, sizeof points / sizeof *points); + } + p->setPen(tb->palette.light().color()); + if (tb->direction != Qt::RightToLeft) { + p->drawLine(0, 2, tb->rect.width() - d, 2); + p->drawLine(tb->rect.width() - d - 1, 2, tb->rect.width() - 21, tb->rect.height() - 1); + p->drawLine(tb->rect.width() - 20, tb->rect.height() - 1, + tb->rect.width(), tb->rect.height() - 1); + } else { + p->drawLine(tb->rect.width() - 1, 2, d - 1, 2); + p->drawLine(d, 2, 20, tb->rect.height() - 1); + p->drawLine(19, tb->rect.height() - 1, + -1, tb->rect.height() - 1); + } + p->setBrush(Qt::NoBrush); + } + break; + case CE_TabBarTab: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + proxy()->drawControl(CE_TabBarTabShape, tab, p); + proxy()->drawControl(CE_TabBarTabLabel, tab, p); + } + break; + case CE_TabBarTabShape: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + p->save(); + + QRect rect(tab->rect); + bool selected = tab->state & State_Selected; + bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab; + int tabOverlap = onlyOne ? 0 : proxy()->pixelMetric(PM_TabBarTabOverlap, opt); + + if (!selected) { + switch (tab->shape) { + case QStyleOptionTab::TriangularNorth: + rect.adjust(0, 0, 0, -tabOverlap); + if(!selected) + rect.adjust(1, 1, -1, 0); + break; + case QStyleOptionTab::TriangularSouth: + rect.adjust(0, tabOverlap, 0, 0); + if(!selected) + rect.adjust(1, 0, -1, -1); + break; + case QStyleOptionTab::TriangularEast: + rect.adjust(tabOverlap, 0, 0, 0); + if(!selected) + rect.adjust(0, 1, -1, -1); + break; + case QStyleOptionTab::TriangularWest: + rect.adjust(0, 0, -tabOverlap, 0); + if(!selected) + rect.adjust(1, 1, 0, -1); + break; + default: + break; + } + } + + p->setPen(QPen(tab->palette.windowText(), 0)); + if (selected) { + p->setBrush(tab->palette.base()); + } else { + p->setBrush(tab->palette.window()); + } + + int y; + int x; + QPolygon a(10); + switch (tab->shape) { + case QStyleOptionTab::TriangularNorth: + case QStyleOptionTab::TriangularSouth: { + a.setPoint(0, 0, -1); + a.setPoint(1, 0, 0); + y = rect.height() - 2; + x = y / 3; + a.setPoint(2, x++, y - 1); + ++x; + a.setPoint(3, x++, y++); + a.setPoint(4, x, y); + + int i; + int right = rect.width() - 1; + for (i = 0; i < 5; ++i) + a.setPoint(9 - i, right - a.point(i).x(), a.point(i).y()); + if (tab->shape == QStyleOptionTab::TriangularNorth) + for (i = 0; i < 10; ++i) + a.setPoint(i, a.point(i).x(), rect.height() - 1 - a.point(i).y()); + + a.translate(rect.left(), rect.top()); + p->setRenderHint(QPainter::Antialiasing); + p->translate(0, 0.5); + + QPainterPath path; + path.addPolygon(a); + p->drawPath(path); + break; } + case QStyleOptionTab::TriangularEast: + case QStyleOptionTab::TriangularWest: { + a.setPoint(0, -1, 0); + a.setPoint(1, 0, 0); + x = rect.width() - 2; + y = x / 3; + a.setPoint(2, x - 1, y++); + ++y; + a.setPoint(3, x++, y++); + a.setPoint(4, x, y); + int i; + int bottom = rect.height() - 1; + for (i = 0; i < 5; ++i) + a.setPoint(9 - i, a.point(i).x(), bottom - a.point(i).y()); + if (tab->shape == QStyleOptionTab::TriangularWest) + for (i = 0; i < 10; ++i) + a.setPoint(i, rect.width() - 1 - a.point(i).x(), a.point(i).y()); + a.translate(rect.left(), rect.top()); + p->setRenderHint(QPainter::Antialiasing); + p->translate(0.5, 0); + QPainterPath path; + path.addPolygon(a); + p->drawPath(path); + break; } + default: + break; + } + p->restore(); + } + break; + case CE_ToolBoxTabLabel: + if (const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) { + bool enabled = tb->state & State_Enabled; + bool selected = tb->state & State_Selected; + int iconExtent = proxy()->pixelMetric(QStyle::PM_SmallIconSize, tb); + QPixmap pm = tb->icon.pixmap(QSize(iconExtent, iconExtent), dpr(opt->window), + enabled ? QIcon::Normal : QIcon::Disabled); + + QRect cr = subElementRect(QStyle::SE_ToolBoxTabContents, tb); + QRect tr, ir; + int ih = 0; + if (pm.isNull()) { + tr = cr; + tr.adjust(4, 0, -8, 0); + } else { + int iw = pm.width() / pm.devicePixelRatio() + 4; + ih = pm.height()/ pm.devicePixelRatio(); + ir = QRect(cr.left() + 4, cr.top(), iw + 2, ih); + tr = QRect(ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height()); + } + + if (selected && proxy()->styleHint(QStyle::SH_ToolBox_SelectedPageTitleBold, tb)) { + QFont f(p->font()); + f.setBold(true); + p->setFont(f); + } + + QString txt = tb->fontMetrics.elidedText(tb->text, Qt::ElideRight, tr.width()); + + if (ih) + p->drawPixmap(ir.left(), (tb->rect.height() - ih) / 2, pm); + + int alignment = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic; + if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, tb)) + alignment |= Qt::TextHideMnemonic; + proxy()->drawItemText(p, tr, alignment, tb->palette, enabled, txt, QPalette::ButtonText); + + if (!txt.isEmpty() && opt->state & State_HasFocus) { + QStyleOptionFocusRect opt; + opt.rect = tr; + opt.palette = tb->palette; + opt.state = QStyle::State_None; + proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p); + } + } + break; + case CE_TabBarTabLabel: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + QRect tr = tab->rect; + bool verticalTabs = tab->shape == QStyleOptionTab::RoundedEast + || tab->shape == QStyleOptionTab::RoundedWest + || tab->shape == QStyleOptionTab::TriangularEast + || tab->shape == QStyleOptionTab::TriangularWest; + + int alignment = Qt::AlignCenter | Qt::TextShowMnemonic; + if (!proxy()->styleHint(SH_UnderlineShortcut, opt)) + alignment |= Qt::TextHideMnemonic; + + if (verticalTabs) { + p->save(); + int newX, newY, newRot; + if (tab->shape == QStyleOptionTab::RoundedEast || tab->shape == QStyleOptionTab::TriangularEast) { + newX = tr.width() + tr.x(); + newY = tr.y(); + newRot = 90; + } else { + newX = tr.x(); + newY = tr.y() + tr.height(); + newRot = -90; + } + QTransform m = QTransform::fromTranslate(newX, newY); + m.rotate(newRot); + p->setTransform(m, true); + } + QRect iconRect; + d->tabLayout(tab, &tr, &iconRect); + tr = proxy()->subElementRect(SE_TabBarTabText, opt); //we compute tr twice because the style may override subElementRect + + if (!tab->icon.isNull()) { + QPixmap tabIcon = tab->icon.pixmap(tab->iconSize, dpr(opt->window), + (tab->state & State_Enabled) ? QIcon::Normal + : QIcon::Disabled, + (tab->state & State_Selected) ? QIcon::On + : QIcon::Off); + p->drawPixmap(iconRect.x(), iconRect.y(), tabIcon); + } + + proxy()->drawItemText(p, tr, alignment, tab->palette, tab->state & State_Enabled, tab->text, QPalette::WindowText); + if (verticalTabs) + p->restore(); + + if (tab->state & State_HasFocus) { + const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth); + + int x1, x2; + x1 = tab->rect.left(); + x2 = tab->rect.right() - 1; + + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*tab); + fropt.rect.setRect(x1 + 1 + OFFSET, tab->rect.y() + OFFSET, + x2 - x1 - 2*OFFSET, tab->rect.height() - 2*OFFSET); + drawPrimitive(PE_FrameFocusRect, &fropt, p); + } + } + break; + case CE_SizeGrip: { + p->save(); + int x, y, w, h; + opt->rect.getRect(&x, &y, &w, &h); + + int sw = qMin(h, w); + if (h > w) + p->translate(0, h - w); + else + p->translate(w - h, 0); + + int sx = x; + int sy = y; + int s = sw / 3; + + Qt::Corner corner; + if (const QStyleOptionSizeGrip *sgOpt = qstyleoption_cast<const QStyleOptionSizeGrip *>(opt)) + corner = sgOpt->corner; + else if (opt->direction == Qt::RightToLeft) + corner = Qt::BottomLeftCorner; + else + corner = Qt::BottomRightCorner; + + if (corner == Qt::BottomLeftCorner) { + sx = x + sw; + for (int i = 0; i < 4; ++i) { + p->setPen(QPen(opt->palette.light().color(), 1)); + p->drawLine(x, sy - 1 , sx + 1, sw); + p->setPen(QPen(opt->palette.dark().color(), 1)); + p->drawLine(x, sy, sx, sw); + p->setPen(QPen(opt->palette.dark().color(), 1)); + p->drawLine(x, sy + 1, sx - 1, sw); + sx -= s; + sy += s; + } + } else if (corner == Qt::BottomRightCorner) { + for (int i = 0; i < 4; ++i) { + p->setPen(QPen(opt->palette.light().color(), 1)); + p->drawLine(sx - 1, sw, sw, sy - 1); + p->setPen(QPen(opt->palette.dark().color(), 1)); + p->drawLine(sx, sw, sw, sy); + p->setPen(QPen(opt->palette.dark().color(), 1)); + p->drawLine(sx + 1, sw, sw, sy + 1); + sx += s; + sy += s; + } + } else if (corner == Qt::TopRightCorner) { + sy = y + sw; + for (int i = 0; i < 4; ++i) { + p->setPen(QPen(opt->palette.light().color(), 1)); + p->drawLine(sx - 1, y, sw, sy + 1); + p->setPen(QPen(opt->palette.dark().color(), 1)); + p->drawLine(sx, y, sw, sy); + p->setPen(QPen(opt->palette.dark().color(), 1)); + p->drawLine(sx + 1, y, sw, sy - 1); + sx += s; + sy -= s; + } + } else if (corner == Qt::TopLeftCorner) { + for (int i = 0; i < 4; ++i) { + p->setPen(QPen(opt->palette.light().color(), 1)); + p->drawLine(x, sy - 1, sx - 1, y); + p->setPen(QPen(opt->palette.dark().color(), 1)); + p->drawLine(x, sy, sx, y); + p->setPen(QPen(opt->palette.dark().color(), 1)); + p->drawLine(x, sy + 1, sx + 1, y); + sx += s; + sy += s; + } + } + p->restore(); + break; } + case CE_RubberBand: { + if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) { + QPixmap tiledPixmap(16, 16); + QPainter pixmapPainter(&tiledPixmap); + pixmapPainter.setPen(Qt::NoPen); + pixmapPainter.setBrush(Qt::Dense4Pattern); + pixmapPainter.setBackground(QBrush(opt->palette.base())); + pixmapPainter.setBackgroundMode(Qt::OpaqueMode); + pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height()); + pixmapPainter.end(); + // ### workaround for borked XRENDER + tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage()); + + p->save(); + QRect r = opt->rect; + QStyleHintReturnMask mask; + if (proxy()->styleHint(QStyle::SH_RubberBand_Mask, opt, &mask)) + p->setClipRegion(mask.region); + p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap); + p->setPen(opt->palette.color(QPalette::Active, QPalette::WindowText)); + p->setBrush(Qt::NoBrush); + p->drawRect(r.adjusted(0, 0, -1, -1)); + if (rbOpt->shape == QStyleOptionRubberBand::Rectangle) + p->drawRect(r.adjusted(3, 3, -4, -4)); + p->restore(); + } + break; } + case CE_DockWidgetTitle: + if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) { + QRect r = dwOpt->rect.adjusted(0, 0, -1, -1); + if (dwOpt->movable) { + p->setPen(dwOpt->palette.color(QPalette::Dark)); + p->drawRect(r); + } + + if (!dwOpt->title.isEmpty()) { + const bool verticalTitleBar = dwOpt->verticalTitleBar; + + if (verticalTitleBar) { + r = r.transposed(); + + p->save(); + p->translate(r.left(), r.top() + r.width()); + p->rotate(-90); + p->translate(-r.left(), -r.top()); + } + + const int indent = p->fontMetrics().descent(); + proxy()->drawItemText(p, r.adjusted(indent + 1, 1, -indent - 1, -1), + Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette, + dwOpt->state & State_Enabled, dwOpt->title, + QPalette::WindowText); + + if (verticalTitleBar) + p->restore(); + } + } + break; + case CE_Header: + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { + QRegion clipRegion = p->clipRegion(); + p->setClipRect(opt->rect); + proxy()->drawControl(CE_HeaderSection, header, p); + QStyleOptionHeader subopt = *header; + subopt.rect = subElementRect(SE_HeaderLabel, header); + if (subopt.rect.isValid()) + proxy()->drawControl(CE_HeaderLabel, &subopt, p); + if (header->sortIndicator != QStyleOptionHeader::None) { + subopt.rect = subElementRect(SE_HeaderArrow, opt); + proxy()->drawPrimitive(PE_IndicatorHeaderArrow, &subopt, p); + } + p->setClipRegion(clipRegion); + } + break; + case CE_FocusFrame: + p->fillRect(opt->rect, opt->palette.windowText()); + break; + case CE_HeaderSection: + qDrawShadePanel(p, opt->rect, opt->palette, + opt->state & State_Sunken, 1, + &opt->palette.brush(QPalette::Button)); + break; + case CE_HeaderEmptyArea: + p->fillRect(opt->rect, opt->palette.window()); + break; + case CE_ComboBoxLabel: + if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField); + p->save(); + p->setClipRect(editRect); + if (!cb->currentIcon.isNull()) { + QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal + : QIcon::Disabled; + QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, dpr(opt->window), mode); + QRect iconRect(editRect); + iconRect.setWidth(cb->iconSize.width() + 4); + iconRect = alignedRect(cb->direction, + Qt::AlignLeft | Qt::AlignVCenter, + iconRect.size(), editRect); + if (cb->editable) + p->fillRect(iconRect, opt->palette.brush(QPalette::Base)); + proxy()->drawItemPixmap(p, iconRect, Qt::AlignCenter, pixmap); + + if (cb->direction == Qt::RightToLeft) + editRect.translate(-4 - cb->iconSize.width(), 0); + else + editRect.translate(cb->iconSize.width() + 4, 0); + } + if (!cb->currentText.isEmpty() && !cb->editable) { + proxy()->drawItemText(p, editRect.adjusted(1, 0, -1, 0), + visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter), + cb->palette, cb->state & State_Enabled, cb->currentText); + } + p->restore(); + } + break; + case CE_ToolBar: + if (const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) { + // Compatibility with styles that use PE_PanelToolBar + QStyleOptionFrame frame; + frame.QStyleOption::operator=(*toolBar); + frame.lineWidth = toolBar->lineWidth; + frame.midLineWidth = toolBar->midLineWidth; + proxy()->drawPrimitive(PE_PanelToolBar, opt, p); + + qDrawShadePanel(p, toolBar->rect, toolBar->palette, false, toolBar->lineWidth, + &toolBar->palette.brush(QPalette::Button)); + } + break; + case CE_ColumnViewGrip: { + // draw background gradients + QLinearGradient g(0, 0, opt->rect.width(), 0); + g.setColorAt(0, opt->palette.color(QPalette::Active, QPalette::Mid)); + g.setColorAt(0.5, Qt::white); + p->fillRect(QRect(0, 0, opt->rect.width(), opt->rect.height()), g); + + // draw the two lines + QPen pen(p->pen()); + pen.setWidth(opt->rect.width()/20); + pen.setColor(opt->palette.color(QPalette::Active, QPalette::Dark)); + p->setPen(pen); + + int line1starting = opt->rect.width()*8 / 20; + int line2starting = opt->rect.width()*13 / 20; + int top = opt->rect.height()*20/75; + int bottom = opt->rect.height() - 1 - top; + p->drawLine(line1starting, top, line1starting, bottom); + p->drawLine(line2starting, top, line2starting, bottom); + } + break; + case CE_ItemViewItem: + if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { + p->save(); + p->setClipRect(opt->rect); + + QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt); + QRect iconRect = proxy()->subElementRect(SE_ItemViewItemDecoration, vopt); + QRect textRect = proxy()->subElementRect(SE_ItemViewItemText, vopt); + + // draw the background + proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p); + + // draw the check mark + if (vopt->features & QStyleOptionViewItem::HasCheckIndicator) { + QStyleOptionViewItem option(*vopt); + option.rect = checkRect; + option.state = option.state & ~QStyle::State_HasFocus; + + switch (vopt->checkState) { + case Qt::Unchecked: + option.state |= QStyle::State_Off; + break; + case Qt::PartiallyChecked: + option.state |= QStyle::State_NoChange; + break; + case Qt::Checked: + option.state |= QStyle::State_On; + break; + } + proxy()->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, p); + } + + // draw the icon + QIcon::Mode mode = QIcon::Normal; + if (!(vopt->state & QStyle::State_Enabled)) + mode = QIcon::Disabled; + else if (vopt->state & QStyle::State_Selected) + mode = QIcon::Selected; + QIcon::State state = vopt->state & QStyle::State_Open ? QIcon::On : QIcon::Off; + vopt->icon.paint(p, iconRect, vopt->decorationAlignment, mode, state); + + // draw the text + if (!vopt->text.isEmpty()) { + QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled + ? QPalette::Normal : QPalette::Disabled; + if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active)) + cg = QPalette::Inactive; + + if (vopt->state & QStyle::State_Selected) { + p->setPen(vopt->palette.color(cg, QPalette::HighlightedText)); + } else { + p->setPen(vopt->palette.color(cg, QPalette::Text)); + } + if (vopt->state & QStyle::State_Editing) { + p->setPen(vopt->palette.color(cg, QPalette::Text)); + p->drawRect(textRect.adjusted(0, 0, -1, -1)); + } + + d->viewItemDrawText(p, vopt, textRect); + } + + // draw the focus rect + if (vopt->state & QStyle::State_HasFocus) { + QStyleOptionFocusRect o; + o.QStyleOption::operator=(*vopt); + o.rect = proxy()->subElementRect(SE_ItemViewItemFocusRect, vopt); + o.state |= QStyle::State_KeyboardFocusChange; + o.state |= QStyle::State_Item; + QPalette::ColorGroup cg = (vopt->state & QStyle::State_Enabled) + ? QPalette::Normal : QPalette::Disabled; + o.backgroundColor = vopt->palette.color(cg, (vopt->state & QStyle::State_Selected) + ? QPalette::Highlight : QPalette::Window); + proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, p); + } + + p->restore(); + } + break; + case CE_ShapedFrame: + if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + int frameShape = f->frameShape; + int frameShadow = QStyleOptionFrame::Plain; + if (f->state & QStyle::State_Sunken) { + frameShadow = QStyleOptionFrame::Sunken; + } else if (f->state & QStyle::State_Raised) { + frameShadow = QStyleOptionFrame::Raised; + } + + int lw = f->lineWidth; + int mlw = f->midLineWidth; + QPalette::ColorRole foregroundRole = QPalette::WindowText; + + switch (frameShape) { + case QStyleOptionFrame::Box: + if (frameShadow == QStyleOptionFrame::Plain) { + qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw); + } else { + qDrawShadeRect(p, f->rect, f->palette, frameShadow == QStyleOptionFrame::Sunken, lw, mlw); + } + break; + case QStyleOptionFrame::StyledPanel: + proxy()->drawPrimitive(QStyle::PE_Frame, opt, p); + break; + case QStyleOptionFrame::Panel: + if (frameShadow == QStyleOptionFrame::Plain) { + qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw); + } else { + qDrawShadePanel(p, f->rect, f->palette, frameShadow == QStyleOptionFrame::Sunken, lw); + } + break; + case QStyleOptionFrame::WinPanel: + if (frameShadow == QStyleOptionFrame::Plain) { + qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw); + } else { + qDrawWinPanel(p, f->rect, f->palette, frameShadow == QStyleOptionFrame::Sunken); + } + break; + case QStyleOptionFrame::HLine: + case QStyleOptionFrame::VLine: { + QPoint p1, p2; + if (frameShape == QStyleOptionFrame::HLine) { + p1 = QPoint(opt->rect.x(), opt->rect.y() + opt->rect.height() / 2); + p2 = QPoint(opt->rect.x() + opt->rect.width(), p1.y()); + } else { + p1 = QPoint(opt->rect.x() + opt->rect.width() / 2, opt->rect.y()); + p2 = QPoint(p1.x(), p1.y() + opt->rect.height()); + } + if (frameShadow == QStyleOptionFrame::Plain) { + QPen oldPen = p->pen(); + p->setPen(QPen(opt->palette.brush(foregroundRole), lw)); + p->drawLine(p1, p2); + p->setPen(oldPen); + } else { + qDrawShadeLine(p, p1, p2, f->palette, frameShadow == QStyleOptionFrame::Sunken, lw, mlw); + } + break; + } + } + } + break; + default: + break; + } +} + +QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt) const +{ + Q_D(const QCommonStyle); + QRect r; + switch (sr) { + case SE_PushButtonContents: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + int dx1, dx2; + dx1 = proxy()->pixelMetric(PM_DefaultFrameWidth, btn); + if (btn->features & QStyleOptionButton::AutoDefaultButton) + dx1 += proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn); + dx2 = dx1 * 2; + r.setRect(opt->rect.x() + dx1, opt->rect.y() + dx1, opt->rect.width() - dx2, + opt->rect.height() - dx2); + r = visualRect(opt->direction, opt->rect, r); + } + break; + case SE_PushButtonFocusRect: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + int dbw1 = 0, dbw2 = 0; + if (btn->features & QStyleOptionButton::AutoDefaultButton){ + dbw1 = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn); + dbw2 = dbw1 * 2; + } + + int dfw1 = proxy()->pixelMetric(PM_DefaultFrameWidth, btn) + 1, + dfw2 = dfw1 * 2; + + r.setRect(btn->rect.x() + dfw1 + dbw1, btn->rect.y() + dfw1 + dbw1, + btn->rect.width() - dfw2 - dbw2, btn->rect.height()- dfw2 - dbw2); + r = visualRect(opt->direction, opt->rect, r); + } + break; + case SE_CheckBoxIndicator: + { + int h = proxy()->pixelMetric(PM_IndicatorHeight, opt); + r.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - h) / 2), + proxy()->pixelMetric(PM_IndicatorWidth, opt), h); + r = visualRect(opt->direction, opt->rect, r); + } + break; + + case SE_CheckBoxContents: + { + // Deal with the logical first, then convert it back to screen coords. + QRect ir = visualRect(opt->direction, opt->rect, + subElementRect(SE_CheckBoxIndicator, opt)); + int spacing = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, opt); + r.setRect(ir.right() + spacing, opt->rect.y(), opt->rect.width() - ir.width() - spacing, + opt->rect.height()); + r = visualRect(opt->direction, opt->rect, r); + } + break; + + case SE_CheckBoxFocusRect: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + if (btn->icon.isNull() && btn->text.isEmpty()) { + r = subElementRect(SE_CheckBoxIndicator, opt); + r.adjust(1, 1, -1, -1); + break; + } + // As above, deal with the logical first, then convert it back to screen coords. + QRect cr = visualRect(btn->direction, btn->rect, subElementRect(SE_CheckBoxContents, btn)); + + QRect iconRect, textRect; + if (!btn->text.isEmpty()) { + textRect = itemTextRect(opt->fontMetrics, cr, Qt::AlignAbsolute | Qt::AlignLeft + | Qt::AlignVCenter | Qt::TextShowMnemonic, + btn->state & State_Enabled, btn->text); + } + if (!btn->icon.isNull()) { + iconRect = itemPixmapRect(cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter + | Qt::TextShowMnemonic, + btn->icon.pixmap(btn->iconSize, dpr(opt->window), QIcon::Normal)); + if (!textRect.isEmpty()) + textRect.translate(iconRect.right() + 4, 0); + } + r = iconRect | textRect; + r.adjust(-3, -2, 3, 2); + r = r.intersected(btn->rect); + r = visualRect(btn->direction, btn->rect, r); + } + break; + + case SE_RadioButtonIndicator: + { + int h = proxy()->pixelMetric(PM_ExclusiveIndicatorHeight, opt); + r.setRect(opt->rect.x(), opt->rect.y() + ((opt->rect.height() - h) / 2), + proxy()->pixelMetric(PM_ExclusiveIndicatorWidth, opt), h); + r = visualRect(opt->direction, opt->rect, r); + } + break; + + case SE_RadioButtonContents: + { + QRect ir = visualRect(opt->direction, opt->rect, + subElementRect(SE_RadioButtonIndicator, opt)); + int spacing = proxy()->pixelMetric(PM_RadioButtonLabelSpacing, opt); + r.setRect(ir.left() + ir.width() + spacing, opt->rect.y(), opt->rect.width() - ir.width() - spacing, + opt->rect.height()); + r = visualRect(opt->direction, opt->rect, r); + break; + } + + case SE_RadioButtonFocusRect: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + if (btn->icon.isNull() && btn->text.isEmpty()) { + r = subElementRect(SE_RadioButtonIndicator, opt); + r.adjust(1, 1, -1, -1); + break; + } + QRect cr = visualRect(btn->direction, btn->rect, subElementRect(SE_RadioButtonContents, opt)); + + QRect iconRect, textRect; + if (!btn->text.isEmpty()){ + textRect = itemTextRect(opt->fontMetrics, cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter + | Qt::TextShowMnemonic, btn->state & State_Enabled, btn->text); + } + if (!btn->icon.isNull()) { + iconRect = itemPixmapRect(cr, Qt::AlignAbsolute | Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, + btn->icon.pixmap(btn->iconSize, dpr(opt->window), QIcon::Normal)); + if (!textRect.isEmpty()) + textRect.translate(iconRect.right() + 4, 0); + } + r = iconRect | textRect; + r.adjust(-3, -2, 3, 2); + r = r.intersected(btn->rect); + r = visualRect(btn->direction, btn->rect, r); + } + break; + case SE_SliderFocusRect: + if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider); + int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider); + if (slider->orientation == Qt::Horizontal) + r.setRect(0, tickOffset - 1, slider->rect.width(), thickness + 2); + else + r.setRect(tickOffset - 1, 0, thickness + 2, slider->rect.height()); + r = r.intersected(slider->rect); + r = visualRect(opt->direction, opt->rect, r); + } + break; + case SE_ProgressBarGroove: + case SE_ProgressBarContents: + case SE_ProgressBarLabel: + if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) { + int textw = 0; + if (pb->textVisible) + textw = qMax(pb->fontMetrics.horizontalAdvance(pb->text), pb->fontMetrics.horizontalAdvance(QLatin1String("100%"))) + 6; + + if ((pb->textAlignment & Qt::AlignCenter) == 0) { + if (sr != SE_ProgressBarLabel) + r.setCoords(pb->rect.left(), pb->rect.top(), + pb->rect.right() - textw, pb->rect.bottom()); + else + r.setCoords(pb->rect.right() - textw, pb->rect.top(), + pb->rect.right(), pb->rect.bottom()); + } else { + r = pb->rect; + } + r = visualRect(pb->direction, pb->rect, r); + } + break; + case SE_ComboBoxFocusRect: + if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + int margin = cb->frame ? 3 : 0; + r.setRect(opt->rect.left() + margin, opt->rect.top() + margin, + opt->rect.width() - 2*margin - 16, opt->rect.height() - 2*margin); + r = visualRect(opt->direction, opt->rect, r); + } + break; + case SE_ToolBoxTabContents: + r = opt->rect; + r.adjust(0, 0, -30, 0); + break; + case SE_HeaderLabel: { + int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt); + r.setRect(opt->rect.x() + margin, opt->rect.y() + margin, + opt->rect.width() - margin * 2, opt->rect.height() - margin * 2); + + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { + // Subtract width needed for arrow, if there is one + if (header->sortIndicator != QStyleOptionHeader::None) { + if (opt->state & State_Horizontal) + r.setWidth(r.width() - (opt->rect.height() / 2) - (margin * 2)); + else + r.setHeight(r.height() - (opt->rect.width() / 2) - (margin * 2)); + } + } + r = visualRect(opt->direction, opt->rect, r); + break; } + case SE_HeaderArrow: { + int h = opt->rect.height(); + int w = opt->rect.width(); + int x = opt->rect.x(); + int y = opt->rect.y(); + int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt); + + if (opt->state & State_Horizontal) { + int horiz_size = h / 2; + r.setRect(x + w - margin * 2 - horiz_size, y + 5, + horiz_size, h - margin * 2 - 5); + } else { + int vert_size = w / 2; + r.setRect(x + 5, y + h - margin * 2 - vert_size, + w - margin * 2 - 5, vert_size); + } + r = visualRect(opt->direction, opt->rect, r); + break; } + + case SE_RadioButtonClickRect: + r = subElementRect(SE_RadioButtonFocusRect, opt); + r |= subElementRect(SE_RadioButtonIndicator, opt); + break; + case SE_CheckBoxClickRect: + r = subElementRect(SE_CheckBoxFocusRect, opt); + r |= subElementRect(SE_CheckBoxIndicator, opt); + break; + case SE_TabWidgetTabBar: + if (const QStyleOptionTabWidgetFrame *twf + = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { + r.setSize(twf->tabBarSize); + const uint alingMask = Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter; + switch (twf->shape) { + case QStyleOptionTab::RoundedNorth: + case QStyleOptionTab::TriangularNorth: + // Constrain the size now, otherwise, center could get off the page + // This of course repeated for all the other directions + r.setWidth(qMin(r.width(), twf->rect.width() + - twf->leftCornerWidgetSize.width() + - twf->rightCornerWidgetSize.width())); + switch (proxy()->styleHint(SH_TabBar_Alignment, twf) & alingMask) { + default: + case Qt::AlignLeft: + r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(), 0)); + break; + case Qt::AlignHCenter: + r.moveTopLeft(QPoint(twf->rect.center().x() - qRound(r.width() / 2.0f) + + (twf->leftCornerWidgetSize.width() / 2) + - (twf->rightCornerWidgetSize.width() / 2), 0)); + break; + case Qt::AlignRight: + r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width() + - twf->rightCornerWidgetSize.width(), 0)); + break; + } + r = visualRect(twf->direction, twf->rect, r); + break; + case QStyleOptionTab::RoundedSouth: + case QStyleOptionTab::TriangularSouth: + r.setWidth(qMin(r.width(), twf->rect.width() + - twf->leftCornerWidgetSize.width() + - twf->rightCornerWidgetSize.width())); + switch (proxy()->styleHint(SH_TabBar_Alignment, twf) & alingMask) { + default: + case Qt::AlignLeft: + r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(), + twf->rect.height() - twf->tabBarSize.height())); + break; + case Qt::AlignHCenter: + r.moveTopLeft(QPoint(twf->rect.center().x() - qRound(r.width() / 2.0f) + + (twf->leftCornerWidgetSize.width() / 2) + - (twf->rightCornerWidgetSize.width() / 2), + twf->rect.height() - twf->tabBarSize.height())); + break; + case Qt::AlignRight: + r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width() + - twf->rightCornerWidgetSize.width(), + twf->rect.height() - twf->tabBarSize.height())); + break; + } + r = visualRect(twf->direction, twf->rect, r); + break; + case QStyleOptionTab::RoundedEast: + case QStyleOptionTab::TriangularEast: + r.setHeight(qMin(r.height(), twf->rect.height() + - twf->leftCornerWidgetSize.height() + - twf->rightCornerWidgetSize.height())); + switch (proxy()->styleHint(SH_TabBar_Alignment, twf) & alingMask) { + default: + case Qt::AlignLeft: + r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(), + twf->leftCornerWidgetSize.height())); + break; + case Qt::AlignHCenter: + r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(), + twf->rect.center().y() - r.height() / 2)); + break; + case Qt::AlignRight: + r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(), + twf->rect.height() - twf->tabBarSize.height() + - twf->rightCornerWidgetSize.height())); + break; + } + break; + case QStyleOptionTab::RoundedWest: + case QStyleOptionTab::TriangularWest: + r.setHeight(qMin(r.height(), twf->rect.height() + - twf->leftCornerWidgetSize.height() + - twf->rightCornerWidgetSize.height())); + switch (proxy()->styleHint(SH_TabBar_Alignment, twf) & alingMask) { + default: + case Qt::AlignLeft: + r.moveTopLeft(QPoint(0, twf->leftCornerWidgetSize.height())); + break; + case Qt::AlignHCenter: + r.moveTopLeft(QPoint(0, twf->rect.center().y() - r.height() / 2)); + break; + case Qt::AlignRight: + r.moveTopLeft(QPoint(0, twf->rect.height() - twf->tabBarSize.height() + - twf->rightCornerWidgetSize.height())); + break; + } + break; + } + } + break; + case SE_TabWidgetTabPane: + case SE_TabWidgetTabContents: + if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { + QStyleOptionTab tabopt; + tabopt.shape = twf->shape; + int overlap = proxy()->pixelMetric(PM_TabBarBaseOverlap, &tabopt); + if (twf->lineWidth == 0) + overlap = 0; + switch (twf->shape) { + case QStyleOptionTab::RoundedNorth: + case QStyleOptionTab::TriangularNorth: + r = QRect(QPoint(0,qMax(twf->tabBarSize.height() - overlap, 0)), + QSize(twf->rect.width(), qMin(twf->rect.height() - twf->tabBarSize.height() + overlap, twf->rect.height()))); + break; + case QStyleOptionTab::RoundedSouth: + case QStyleOptionTab::TriangularSouth: + r = QRect(QPoint(0,0), QSize(twf->rect.width(), qMin(twf->rect.height() - twf->tabBarSize.height() + overlap, twf->rect.height()))); + break; + case QStyleOptionTab::RoundedEast: + case QStyleOptionTab::TriangularEast: + r = QRect(QPoint(0, 0), QSize(qMin(twf->rect.width() - twf->tabBarSize.width() + overlap, twf->rect.width()), twf->rect.height())); + break; + case QStyleOptionTab::RoundedWest: + case QStyleOptionTab::TriangularWest: + r = QRect(QPoint(qMax(twf->tabBarSize.width() - overlap, 0), 0), + QSize(qMin(twf->rect.width() - twf->tabBarSize.width() + overlap, twf->rect.width()), twf->rect.height())); + break; + } + if (sr == SE_TabWidgetTabContents && twf->lineWidth > 0) + r.adjust(2, 2, -2, -2); + } + break; + case SE_TabWidgetLeftCorner: + if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { + QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf); + switch (twf->shape) { + case QStyleOptionTab::RoundedNorth: + case QStyleOptionTab::TriangularNorth: + r = QRect(QPoint(paneRect.x(), paneRect.y() - twf->leftCornerWidgetSize.height()), + twf->leftCornerWidgetSize); + break; + case QStyleOptionTab::RoundedSouth: + case QStyleOptionTab::TriangularSouth: + r = QRect(QPoint(paneRect.x(), paneRect.height()), twf->leftCornerWidgetSize); + break; + default: + break; + } + r = visualRect(twf->direction, twf->rect, r); + } + break; + case SE_TabWidgetRightCorner: + if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) { + QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf); + switch (twf->shape) { + case QStyleOptionTab::RoundedNorth: + case QStyleOptionTab::TriangularNorth: + r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(), + paneRect.y() - twf->rightCornerWidgetSize.height()), + twf->rightCornerWidgetSize); + break; + case QStyleOptionTab::RoundedSouth: + case QStyleOptionTab::TriangularSouth: + r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(), + paneRect.height()), twf->rightCornerWidgetSize); + break; + default: + break; + } + r = visualRect(twf->direction, twf->rect, r); + } + break; + case SE_TabBarTabText: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + QRect dummyIconRect; + d->tabLayout(tab, &r, &dummyIconRect); + } + break; + case SE_TabBarTabLeftButton: + case SE_TabBarTabRightButton: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + bool selected = tab->state & State_Selected; + int verticalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab); + int horizontalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab); + int hpadding = proxy()->pixelMetric(QStyle::PM_TabBarTabHSpace, opt) / 2; + hpadding = qMax(hpadding, 4); //workaround KStyle returning 0 because they workaround an old bug in Qt + + bool verticalTabs = tab->shape == QStyleOptionTab::RoundedEast + || tab->shape == QStyleOptionTab::RoundedWest + || tab->shape == QStyleOptionTab::TriangularEast + || tab->shape == QStyleOptionTab::TriangularWest; + + QRect tr = tab->rect; + if (tab->shape == QStyleOptionTab::RoundedSouth || tab->shape == QStyleOptionTab::TriangularSouth) + verticalShift = -verticalShift; + if (verticalTabs) { + qSwap(horizontalShift, verticalShift); + horizontalShift *= -1; + verticalShift *= -1; + } + if (tab->shape == QStyleOptionTab::RoundedWest || tab->shape == QStyleOptionTab::TriangularWest) + horizontalShift = -horizontalShift; + + tr.adjust(0, 0, horizontalShift, verticalShift); + if (selected) + { + tr.setBottom(tr.bottom() - verticalShift); + tr.setRight(tr.right() - horizontalShift); + } + + QSize size = (sr == SE_TabBarTabLeftButton) ? tab->leftButtonSize : tab->rightButtonSize; + int w = size.width(); + int h = size.height(); + int midHeight = static_cast<int>(qCeil(float(tr.height() - h) / 2)); + int midWidth = ((tr.width() - w) / 2); + + bool atTheTop = true; + switch (tab->shape) { + case QStyleOptionTab::RoundedWest: + case QStyleOptionTab::TriangularWest: + atTheTop = (sr == SE_TabBarTabLeftButton); + break; + case QStyleOptionTab::RoundedEast: + case QStyleOptionTab::TriangularEast: + atTheTop = (sr == SE_TabBarTabRightButton); + break; + default: + if (sr == SE_TabBarTabLeftButton) + r = QRect(tab->rect.x() + hpadding, midHeight, w, h); + else + r = QRect(tab->rect.right() - w - hpadding, midHeight, w, h); + r = visualRect(tab->direction, tab->rect, r); + } + if (verticalTabs) { + if (atTheTop) + r = QRect(midWidth, tr.y() + tab->rect.height() - hpadding - h, w, h); + else + r = QRect(midWidth, tr.y() + hpadding, w, h); + } + } + + break; + case SE_TabBarTearIndicator: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + switch (tab->shape) { + case QStyleOptionTab::RoundedNorth: + case QStyleOptionTab::TriangularNorth: + case QStyleOptionTab::RoundedSouth: + case QStyleOptionTab::TriangularSouth: + r.setRect(tab->rect.left(), tab->rect.top(), 8, opt->rect.height()); + break; + case QStyleOptionTab::RoundedWest: + case QStyleOptionTab::TriangularWest: + case QStyleOptionTab::RoundedEast: + case QStyleOptionTab::TriangularEast: + r.setRect(tab->rect.left(), tab->rect.top(), opt->rect.width(), 8); + break; + default: + break; + } + r = visualRect(opt->direction, opt->rect, r); + } + break; + case SE_TabBarScrollLeftButton: { + const bool vertical = opt->rect.width() < opt->rect.height(); + const Qt::LayoutDirection ld = opt->direction; + const int buttonWidth = proxy()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, nullptr); + const int buttonOverlap = proxy()->pixelMetric(QStyle::PM_TabBar_ScrollButtonOverlap, nullptr); + + r = vertical ? QRect(0, opt->rect.height() - (buttonWidth * 2) + buttonOverlap, opt->rect.width(), buttonWidth) + : QStyle::visualRect(ld, opt->rect, QRect(opt->rect.width() - (buttonWidth * 2) + buttonOverlap, 0, buttonWidth, opt->rect.height())); + break; } + case SE_TabBarScrollRightButton: { + const bool vertical = opt->rect.width() < opt->rect.height(); + const Qt::LayoutDirection ld = opt->direction; + const int buttonWidth = proxy()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, nullptr); + + r = vertical ? QRect(0, opt->rect.height() - buttonWidth, opt->rect.width(), buttonWidth) + : QStyle::visualRect(ld, opt->rect, QRect(opt->rect.width() - buttonWidth, 0, buttonWidth, opt->rect.height())); + break; } + case SE_TreeViewDisclosureItem: + r = opt->rect; + break; + case SE_LineEditContents: + if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + r = f->rect.adjusted(f->lineWidth, f->lineWidth, -f->lineWidth, -f->lineWidth); + r = visualRect(opt->direction, opt->rect, r); + } + break; + case SE_FrameContents: + if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, f); + r = opt->rect.adjusted(fw, fw, -fw, -fw); + r = visualRect(opt->direction, opt->rect, r); + } + break; + case SE_ShapedFrameContents: + if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + int frameShape = f->frameShape; + int frameShadow = QStyleOptionFrame::Plain; + if (f->state & QStyle::State_Sunken) { + frameShadow = QStyleOptionFrame::Sunken; + } else if (f->state & QStyle::State_Raised) { + frameShadow = QStyleOptionFrame::Raised; + } + + int frameWidth = 0; + + switch (frameShape) { + case QStyleOptionFrame::NoFrame: + frameWidth = 0; + break; + + case QStyleOptionFrame::Box: + case QStyleOptionFrame::HLine: + case QStyleOptionFrame::VLine: + switch (frameShadow) { + case QStyleOptionFrame::Plain: + frameWidth = f->lineWidth; + break; + case QStyleOptionFrame::Raised: + case QStyleOptionFrame::Sunken: + frameWidth = (short)(f->lineWidth*2 + f->midLineWidth); + break; + } + break; + + case QStyleOptionFrame::StyledPanel: + //keep the compatibility with Qt 4.4 if there is a proxy style. + //be sure to call drawPrimitive(QStyle::SE_FrameContents) on the proxy style + return subElementRect(QStyle::SE_FrameContents, opt); + + case QStyleOptionFrame::WinPanel: + frameWidth = 2; + break; + + case QStyleOptionFrame::Panel: + switch (frameShadow) { + case QStyleOptionFrame::Plain: + case QStyleOptionFrame::Raised: + case QStyleOptionFrame::Sunken: + frameWidth = f->lineWidth; + break; + } + break; + } + r = f->rect.adjusted(frameWidth, frameWidth, -frameWidth, -frameWidth); + } + break; + case SE_DockWidgetCloseButton: + case SE_DockWidgetFloatButton: + case SE_DockWidgetTitleBarText: + case SE_DockWidgetIcon: { + int iconSize = proxy()->pixelMetric(PM_SmallIconSize, opt); + int buttonMargin = proxy()->pixelMetric(PM_DockWidgetTitleBarButtonMargin, opt); + QRect rect = opt->rect; + + const QStyleOptionDockWidget *dwOpt + = qstyleoption_cast<const QStyleOptionDockWidget*>(opt); + bool canClose = dwOpt == nullptr ? true : dwOpt->closable; + bool canFloat = dwOpt == nullptr ? false : dwOpt->floatable; + + const bool verticalTitleBar = dwOpt && dwOpt->verticalTitleBar; + + // If this is a vertical titlebar, we transpose and work as if it was + // horizontal, then transpose again. + + if (verticalTitleBar) + rect = rect.transposed(); + + do { + int right = rect.right(); + int left = rect.left(); + + QRect closeRect; + if (canClose) { + QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, + opt).actualSize(QSize(iconSize, iconSize)); + sz += QSize(buttonMargin, buttonMargin); + if (verticalTitleBar) + sz = sz.transposed(); + closeRect = QRect(right - sz.width(), + rect.center().y() - sz.height()/2, + sz.width(), sz.height()); + right = closeRect.left() - 1; + } + if (sr == SE_DockWidgetCloseButton) { + r = closeRect; + break; + } + + QRect floatRect; + if (canFloat) { + QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarNormalButton, + opt).actualSize(QSize(iconSize, iconSize)); + sz += QSize(buttonMargin, buttonMargin); + if (verticalTitleBar) + sz = sz.transposed(); + floatRect = QRect(right - sz.width(), + rect.center().y() - sz.height()/2, + sz.width(), sz.height()); + right = floatRect.left() - 1; + } + if (sr == SE_DockWidgetFloatButton) { + r = floatRect; + break; + } + + QRect iconRect; + if (sr == SE_DockWidgetIcon) { + r = iconRect; + break; + } + + QRect textRect = QRect(left, rect.top(), + right - left, rect.height()); + if (sr == SE_DockWidgetTitleBarText) { + r = textRect; + break; + } + + } while (false); + + if (verticalTitleBar) { + r = QRect(rect.left() + r.top() - rect.top(), + rect.top() + rect.right() - r.right(), + r.height(), r.width()); + } else { + r = visualRect(opt->direction, rect, r); + } + break; + } + case SE_ItemViewItemCheckIndicator: + if (!qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { + r = subElementRect(SE_CheckBoxIndicator, opt); + break; + } + Q_FALLTHROUGH(); + case SE_ItemViewItemDecoration: + case SE_ItemViewItemText: + case SE_ItemViewItemFocusRect: + if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { + if (!d->isViewItemCached(*vopt)) { + d->viewItemLayout(vopt, &d->checkRect, &d->decorationRect, &d->displayRect, false); + if (d->cachedOption) { + delete d->cachedOption; + d->cachedOption = nullptr; + } + d->cachedOption = new QStyleOptionViewItem(*vopt); + } + if (sr == SE_ItemViewItemCheckIndicator) + r = d->checkRect; + else if (sr == SE_ItemViewItemDecoration) + r = d->decorationRect; + else if (sr == SE_ItemViewItemText || sr == SE_ItemViewItemFocusRect) + r = d->displayRect; + } + break; + case SE_ToolBarHandle: + if (const QStyleOptionToolBar *tbopt = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) { + if (tbopt->features & QStyleOptionToolBar::Movable) { + ///we need to access the widget here because the style option doesn't + //have all the information we need (ie. the layout's margin) + const QMargins margins(2, 2, 2, 2); + const int handleExtent = proxy()->pixelMetric(QStyle::PM_ToolBarHandleExtent, opt); + if (tbopt->state & QStyle::State_Horizontal) { + r = QRect(margins.left(), margins.top(), + handleExtent, + tbopt->rect.height() - (margins.top() + margins.bottom())); + r = QStyle::visualRect(tbopt->direction, tbopt->rect, r); + } else { + r = QRect(margins.left(), margins.top(), + tbopt->rect.width() - (margins.left() + margins.right()), + handleExtent); + } + } + } + break; + default: + break; + } + return r; +} + +// in lieu of std::array, minimal API +template <int N> +struct StaticPolygonF +{ + QPointF data[N]; + + Q_DECL_CONSTEXPR int size() const { return N; } + Q_DECL_CONSTEXPR const QPointF *cbegin() const { return data; } + Q_DECL_CONSTEXPR const QPointF &operator[](int idx) const { return data[idx]; } +}; + +static StaticPolygonF<3> calcArrow(const QStyleOptionSlider *dial, qreal &a) +{ + int width = dial->rect.width(); + int height = dial->rect.height(); + int r = qMin(width, height) / 2; + int currentSliderPosition = dial->upsideDown ? dial->sliderPosition : (dial->maximum - dial->sliderPosition); + + if (dial->maximum == dial->minimum) + a = Q_PI / 2; + else if (dial->dialWrapping) + a = Q_PI * 3 / 2 - (currentSliderPosition - dial->minimum) * 2 * Q_PI + / (dial->maximum - dial->minimum); + else + a = (Q_PI * 8 - (currentSliderPosition - dial->minimum) * 10 * Q_PI + / (dial->maximum - dial->minimum)) / 6; + + int xc = width / 2; + int yc = height / 2; + + int len = r - QStyleHelper::calcBigLineSize(r) - 5; + if (len < 5) + len = 5; + int back = len / 2; + + StaticPolygonF<3> arrow = {{ + QPointF(0.5 + xc + len * qCos(a), + 0.5 + yc - len * qSin(a)), + QPointF(0.5 + xc + back * qCos(a + Q_PI * 5 / 6), + 0.5 + yc - back * qSin(a + Q_PI * 5 / 6)), + QPointF(0.5 + xc + back * qCos(a - Q_PI * 5 / 6), + 0.5 + yc - back * qSin(a - Q_PI * 5 / 6)), + }}; + return arrow; +} + +void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p) const +{ + switch (cc) { + case CC_Slider: + if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + if (slider->subControls == SC_SliderTickmarks) { + int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider); + int ticks = slider->tickPosition; + int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider); + int len = proxy()->pixelMetric(PM_SliderLength, slider); + int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider); + int interval = slider->tickInterval; + if (interval <= 0) { + interval = slider->singleStep; + if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval, + available) + - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, + 0, available) < 3) + interval = slider->pageStep; + } + if (!interval) + interval = 1; + int fudge = len / 2; + int pos; + // Since there is no subrect for tickmarks do a translation here. + p->save(); + p->translate(slider->rect.x(), slider->rect.y()); + p->setPen(slider->palette.windowText().color()); + int v = slider->minimum; + while (v <= slider->maximum + 1) { + if (v == slider->maximum + 1 && interval == 1) + break; + const int v_ = qMin(v, slider->maximum); + pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, + v_, available) + fudge; + if (slider->orientation == Qt::Horizontal) { + if (ticks & QStyleOptionSlider::TicksAbove) + p->drawLine(pos, 0, pos, tickOffset - 2); + if (ticks & QStyleOptionSlider::TicksBelow) + p->drawLine(pos, tickOffset + thickness + 1, pos, + slider->rect.height()-1); + } else { + if (ticks & QStyleOptionSlider::TicksAbove) + p->drawLine(0, pos, tickOffset - 2, pos); + if (ticks & QStyleOptionSlider::TicksBelow) + p->drawLine(tickOffset + thickness + 1, pos, + slider->rect.width()-1, pos); + } + // in the case where maximum is max int + int nextInterval = v + interval; + if (nextInterval < v) + break; + v = nextInterval; + } + p->restore(); + } + } + break; + case CC_ScrollBar: + if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + // Make a copy here and reset it for each primitive. + QStyleOptionSlider newScrollbar = *scrollbar; + State saveFlags = scrollbar->state; + + if (scrollbar->subControls & SC_ScrollBarSubLine) { + newScrollbar.state = saveFlags; + newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarSubLine); + if (newScrollbar.rect.isValid()) { + if (!(scrollbar->activeSubControls & SC_ScrollBarSubLine)) + newScrollbar.state &= ~(State_Sunken | State_MouseOver); + proxy()->drawControl(CE_ScrollBarSubLine, &newScrollbar, p); + } + } + if (scrollbar->subControls & SC_ScrollBarAddLine) { + newScrollbar.rect = scrollbar->rect; + newScrollbar.state = saveFlags; + newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarAddLine); + if (newScrollbar.rect.isValid()) { + if (!(scrollbar->activeSubControls & SC_ScrollBarAddLine)) + newScrollbar.state &= ~(State_Sunken | State_MouseOver); + proxy()->drawControl(CE_ScrollBarAddLine, &newScrollbar, p); + } + } + if (scrollbar->subControls & SC_ScrollBarSubPage) { + newScrollbar.rect = scrollbar->rect; + newScrollbar.state = saveFlags; + newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarSubPage); + if (newScrollbar.rect.isValid()) { + if (!(scrollbar->activeSubControls & SC_ScrollBarSubPage)) + newScrollbar.state &= ~(State_Sunken | State_MouseOver); + proxy()->drawControl(CE_ScrollBarSubPage, &newScrollbar, p); + } + } + if (scrollbar->subControls & SC_ScrollBarAddPage) { + newScrollbar.rect = scrollbar->rect; + newScrollbar.state = saveFlags; + newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarAddPage); + if (newScrollbar.rect.isValid()) { + if (!(scrollbar->activeSubControls & SC_ScrollBarAddPage)) + newScrollbar.state &= ~(State_Sunken | State_MouseOver); + proxy()->drawControl(CE_ScrollBarAddPage, &newScrollbar, p); + } + } + if (scrollbar->subControls & SC_ScrollBarFirst) { + newScrollbar.rect = scrollbar->rect; + newScrollbar.state = saveFlags; + newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarFirst); + if (newScrollbar.rect.isValid()) { + if (!(scrollbar->activeSubControls & SC_ScrollBarFirst)) + newScrollbar.state &= ~(State_Sunken | State_MouseOver); + proxy()->drawControl(CE_ScrollBarFirst, &newScrollbar, p); + } + } + if (scrollbar->subControls & SC_ScrollBarLast) { + newScrollbar.rect = scrollbar->rect; + newScrollbar.state = saveFlags; + newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarLast); + if (newScrollbar.rect.isValid()) { + if (!(scrollbar->activeSubControls & SC_ScrollBarLast)) + newScrollbar.state &= ~(State_Sunken | State_MouseOver); + proxy()->drawControl(CE_ScrollBarLast, &newScrollbar, p); + } + } + if (scrollbar->subControls & SC_ScrollBarSlider) { + newScrollbar.rect = scrollbar->rect; + newScrollbar.state = saveFlags; + newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarSlider); + if (newScrollbar.rect.isValid()) { + if (!(scrollbar->activeSubControls & SC_ScrollBarSlider)) + newScrollbar.state &= ~(State_Sunken | State_MouseOver); + proxy()->drawControl(CE_ScrollBarSlider, &newScrollbar, p); + + if (scrollbar->state & State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(newScrollbar); + fropt.rect.setRect(newScrollbar.rect.x() + 2, newScrollbar.rect.y() + 2, + newScrollbar.rect.width() - 5, + newScrollbar.rect.height() - 5); + proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p); + } + } + } + } + break; + case CC_SpinBox: + if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { + QStyleOptionSpinBox copy = *sb; + PrimitiveElement pe; + + if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) { + QRect r = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxFrame); + qDrawWinPanel(p, r, sb->palette, true); + } + + if (sb->subControls & SC_SpinBoxUp) { + copy.subControls = SC_SpinBoxUp; + QPalette pal2 = sb->palette; + if (!(sb->stepEnabled & QStyleOptionSpinBox::StepUpEnabled)) { + pal2.setCurrentColorGroup(QPalette::Disabled); + copy.state &= ~State_Enabled; + } + + copy.palette = pal2; + + if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) { + copy.state |= State_On; + copy.state |= State_Sunken; + } else { + copy.state |= State_Raised; + copy.state &= ~State_Sunken; + } + pe = (sb->buttonSymbols == QStyleOptionSpinBox::PlusMinus ? PE_IndicatorSpinPlus + : PE_IndicatorSpinUp); + + copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp); + proxy()->drawPrimitive(PE_PanelButtonBevel, ©, p); + copy.rect.adjust(3, 0, -4, 0); + proxy()->drawPrimitive(pe, ©, p); + } + + if (sb->subControls & SC_SpinBoxDown) { + copy.subControls = SC_SpinBoxDown; + copy.state = sb->state; + QPalette pal2 = sb->palette; + if (!(sb->stepEnabled & QStyleOptionSpinBox::StepDownEnabled)) { + pal2.setCurrentColorGroup(QPalette::Disabled); + copy.state &= ~State_Enabled; + } + copy.palette = pal2; + + if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) { + copy.state |= State_On; + copy.state |= State_Sunken; + } else { + copy.state |= State_Raised; + copy.state &= ~State_Sunken; + } + pe = (sb->buttonSymbols == QStyleOptionSpinBox::PlusMinus ? PE_IndicatorSpinMinus + : PE_IndicatorSpinDown); + + copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown); + proxy()->drawPrimitive(PE_PanelButtonBevel, ©, p); + copy.rect.adjust(3, 0, -4, 0); + proxy()->drawPrimitive(pe, ©, p); + } + } + break; + case CC_ToolButton: + if (const QStyleOptionToolButton *toolbutton + = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) { + QRect button, menuarea; + button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton); + menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu); + + State bflags = toolbutton->state & ~State_Sunken; + + if (bflags & State_AutoRaise) { + if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) { + bflags &= ~State_Raised; + } + } + State mflags = bflags; + if (toolbutton->state & State_Sunken) { + if (toolbutton->activeSubControls & SC_ToolButton) + bflags |= State_Sunken; + mflags |= State_Sunken; + } + + QStyleOption tool = *toolbutton; + if (toolbutton->subControls & SC_ToolButton) { + if (bflags & (State_Sunken | State_On | State_Raised)) { + tool.rect = button; + tool.state = bflags; + proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p); + } + } + + if (toolbutton->state & State_HasFocus) { + QStyleOptionFocusRect fr; + fr.QStyleOption::operator=(*toolbutton); + fr.rect.adjust(3, 3, -3, -3); + if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) + fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, + toolbutton), 0); + proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p); + } + QStyleOptionToolButton label = *toolbutton; + label.state = bflags; + int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt); + label.rect = button.adjusted(fw, fw, -fw, -fw); + proxy()->drawControl(CE_ToolButtonLabel, &label, p); + + if (toolbutton->subControls & SC_ToolButtonMenu) { + tool.rect = menuarea; + tool.state = mflags; + if (mflags & (State_Sunken | State_On | State_Raised)) + proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p); + proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p); + } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) { + int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton); + QRect ir = toolbutton->rect; + QStyleOptionToolButton newBtn = *toolbutton; + newBtn.rect = QRect(ir.right() + 5 - mbi, ir.y() + ir.height() - mbi + 4, mbi - 6, mbi - 6); + newBtn.rect = visualRect(toolbutton->direction, button, newBtn.rect); + proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p); + } + } + break; + case CC_TitleBar: + if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) { + QRect ir; + if (opt->subControls & SC_TitleBarLabel) { + QColor left = tb->palette.highlight().color(); + QColor right = tb->palette.base().color(); + + QBrush fillBrush(left); + if (left != right) { + QPoint p1(tb->rect.x(), tb->rect.top() + tb->rect.height()/2); + QPoint p2(tb->rect.right(), tb->rect.top() + tb->rect.height()/2); + QLinearGradient lg(p1, p2); + lg.setColorAt(0, left); + lg.setColorAt(1, right); + fillBrush = lg; + } + + p->fillRect(opt->rect, fillBrush); + + ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarLabel); + + p->setPen(tb->palette.highlightedText().color()); + p->drawText(ir.x() + 2, ir.y(), ir.width() - 2, ir.height(), + Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text); + } + + bool down = false; + QPixmap pm; + + QStyleOption tool = *tb; + if (tb->subControls & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) { + ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarCloseButton); + down = tb->activeSubControls & SC_TitleBarCloseButton && (opt->state & State_Sunken); + if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool) + pm = proxy()->standardIcon(SP_DockWidgetCloseButton, &tool).pixmap(QSize(10, 10), dpr(opt->window)); + else + pm = proxy()->standardIcon(SP_TitleBarCloseButton, &tool).pixmap(QSize(10, 10), dpr(opt->window)); + tool.rect = ir; + tool.state = down ? State_Sunken : State_Raised; + proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p); + + p->save(); + if (down) + p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb), + proxy()->pixelMetric(PM_ButtonShiftVertical, tb)); + proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); + p->restore(); + } + + if (tb->subControls & SC_TitleBarMaxButton + && tb->titleBarFlags & Qt::WindowMaximizeButtonHint + && !(tb->titleBarState & Qt::WindowMaximized)) { + ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarMaxButton); + + down = tb->activeSubControls & SC_TitleBarMaxButton && (opt->state & State_Sunken); + pm = proxy()->standardIcon(SP_TitleBarMaxButton, &tool).pixmap(QSize(10, 10), dpr(opt->window)); + tool.rect = ir; + tool.state = down ? State_Sunken : State_Raised; + proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p); + + p->save(); + if (down) + p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb), + proxy()->pixelMetric(PM_ButtonShiftVertical, tb)); + proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); + p->restore(); + } + + if (tb->subControls & SC_TitleBarMinButton + && tb->titleBarFlags & Qt::WindowMinimizeButtonHint + && !(tb->titleBarState & Qt::WindowMinimized)) { + ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarMinButton); + down = tb->activeSubControls & SC_TitleBarMinButton && (opt->state & State_Sunken); + pm = proxy()->standardIcon(SP_TitleBarMinButton, &tool).pixmap(QSize(10, 10), dpr(opt->window)); + tool.rect = ir; + tool.state = down ? State_Sunken : State_Raised; + proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p); + + p->save(); + if (down) + p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb), + proxy()->pixelMetric(PM_ButtonShiftVertical, tb)); + proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); + p->restore(); + } + + bool drawNormalButton = (tb->subControls & SC_TitleBarNormalButton) + && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint) + && (tb->titleBarState & Qt::WindowMinimized)) + || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint) + && (tb->titleBarState & Qt::WindowMaximized))); + + if (drawNormalButton) { + ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarNormalButton); + down = tb->activeSubControls & SC_TitleBarNormalButton && (opt->state & State_Sunken); + pm = proxy()->standardIcon(SP_TitleBarNormalButton, &tool).pixmap(QSize(10, 10), dpr(opt->window)); + tool.rect = ir; + tool.state = down ? State_Sunken : State_Raised; + proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p); + + p->save(); + if (down) + p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb), + proxy()->pixelMetric(PM_ButtonShiftVertical, tb)); + proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); + p->restore(); + } + + if (tb->subControls & SC_TitleBarShadeButton + && tb->titleBarFlags & Qt::WindowShadeButtonHint + && !(tb->titleBarState & Qt::WindowMinimized)) { + ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarShadeButton); + down = (tb->activeSubControls & SC_TitleBarShadeButton && (opt->state & State_Sunken)); + pm = proxy()->standardIcon(SP_TitleBarShadeButton, &tool).pixmap(QSize(10, 10), dpr(opt->window)); + tool.rect = ir; + tool.state = down ? State_Sunken : State_Raised; + proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p); + p->save(); + if (down) + p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb), + proxy()->pixelMetric(PM_ButtonShiftVertical, tb)); + proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); + p->restore(); + } + + if (tb->subControls & SC_TitleBarUnshadeButton + && tb->titleBarFlags & Qt::WindowShadeButtonHint + && tb->titleBarState & Qt::WindowMinimized) { + ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarUnshadeButton); + + down = tb->activeSubControls & SC_TitleBarUnshadeButton && (opt->state & State_Sunken); + pm = proxy()->standardIcon(SP_TitleBarUnshadeButton, &tool).pixmap(QSize(10, 10), dpr(opt->window)); + tool.rect = ir; + tool.state = down ? State_Sunken : State_Raised; + proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p); + p->save(); + if (down) + p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb), + proxy()->pixelMetric(PM_ButtonShiftVertical, tb)); + proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); + p->restore(); + } + if (tb->subControls & SC_TitleBarContextHelpButton + && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) { + ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarContextHelpButton); + + down = tb->activeSubControls & SC_TitleBarContextHelpButton && (opt->state & State_Sunken); + pm = proxy()->standardIcon(SP_TitleBarContextHelpButton, &tool).pixmap(QSize(10, 10), dpr(opt->window)); + tool.rect = ir; + tool.state = down ? State_Sunken : State_Raised; + proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p); + p->save(); + if (down) + p->translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb), + proxy()->pixelMetric(PM_ButtonShiftVertical, tb)); + proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); + p->restore(); + } + if (tb->subControls & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) { + ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarSysMenu); + if (!tb->icon.isNull()) { + tb->icon.paint(p, ir); + } else { + int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb); + pm = proxy()->standardIcon(SP_TitleBarMenuButton, &tool).pixmap(QSize(iconSize, iconSize), dpr(opt->window)); + tool.rect = ir; + p->save(); + proxy()->drawItemPixmap(p, ir, Qt::AlignCenter, pm); + p->restore(); + } + } + } + break; + case CC_Dial: + if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + // OK, this is more a port of things over + p->save(); + + // avoid dithering + if (p->paintEngine()->hasFeature(QPaintEngine::Antialiasing)) + p->setRenderHint(QPainter::Antialiasing); + + int width = dial->rect.width(); + int height = dial->rect.height(); + qreal r = qMin(width, height) / 2; + qreal d_ = r / 6; + qreal dx = dial->rect.x() + d_ + (width - 2 * r) / 2 + 1; + qreal dy = dial->rect.y() + d_ + (height - 2 * r) / 2 + 1; + QRect br = QRect(int(dx), int(dy), int(r * 2 - 2 * d_ - 2), int(r * 2 - 2 * d_ - 2)); + + QPalette pal = opt->palette; + // draw notches + if (dial->subControls & QStyle::SC_DialTickmarks) { + p->setPen(pal.windowText().color()); + p->drawLines(QStyleHelper::calcLines(dial)); + } + + if (dial->state & State_Enabled) { + p->setBrush(pal.brush(QPalette::ColorRole(proxy()->styleHint(SH_Dial_BackgroundRole, dial)))); + p->setPen(Qt::NoPen); + p->drawEllipse(br); + p->setBrush(Qt::NoBrush); + } + p->setPen(QPen(pal.dark().color())); + p->drawArc(br, 60 * 16, 180 * 16); + p->setPen(QPen(pal.light().color())); + p->drawArc(br, 240 * 16, 180 * 16); + + qreal a; + const StaticPolygonF<3> arrow = calcArrow(dial, a); + + p->setPen(Qt::NoPen); + p->setBrush(pal.button()); + p->drawPolygon(arrow.cbegin(), arrow.size()); + + a = QStyleHelper::angle(QPointF(width / 2, height / 2), arrow[0]); + p->setBrush(Qt::NoBrush); + + if (a <= 0 || a > 200) { + p->setPen(pal.light().color()); + p->drawLine(arrow[2], arrow[0]); + p->drawLine(arrow[1], arrow[2]); + p->setPen(pal.dark().color()); + p->drawLine(arrow[0], arrow[1]); + } else if (a > 0 && a < 45) { + p->setPen(pal.light().color()); + p->drawLine(arrow[2], arrow[0]); + p->setPen(pal.dark().color()); + p->drawLine(arrow[1], arrow[2]); + p->drawLine(arrow[0], arrow[1]); + } else if (a >= 45 && a < 135) { + p->setPen(pal.dark().color()); + p->drawLine(arrow[2], arrow[0]); + p->drawLine(arrow[1], arrow[2]); + p->setPen(pal.light().color()); + p->drawLine(arrow[0], arrow[1]); + } else if (a >= 135 && a < 200) { + p->setPen(pal.dark().color()); + p->drawLine(arrow[2], arrow[0]); + p->setPen(pal.light().color()); + p->drawLine(arrow[0], arrow[1]); + p->drawLine(arrow[1], arrow[2]); + } + + // draw focus rect around the dial + QStyleOptionFocusRect fropt; + fropt.rect = dial->rect; + fropt.state = dial->state; + fropt.palette = dial->palette; + if (fropt.state & QStyle::State_HasFocus) { + br.adjust(0, 0, 2, 2); + if (dial->subControls & SC_DialTickmarks) { + int r = qMin(width, height) / 2; + br.translate(-r / 6, - r / 6); + br.setWidth(br.width() + r / 3); + br.setHeight(br.height() + r / 3); + } + fropt.rect = br.adjusted(-2, -2, 2, 2); + proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &fropt, p); + } + p->restore(); + } + break; + case CC_GroupBox: + if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) { + // Draw frame + QRect textRect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel); + QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox); + if (groupBox->subControls & QStyle::SC_GroupBoxFrame) { + QStyleOptionFrame frame; + frame.QStyleOption::operator=(*groupBox); + frame.features = groupBox->features; + frame.lineWidth = groupBox->lineWidth; + frame.midLineWidth = groupBox->midLineWidth; + frame.rect = proxy()->subControlRect(CC_GroupBox, opt, SC_GroupBoxFrame); + p->save(); + QRegion region(groupBox->rect); + if (!groupBox->text.isEmpty()) { + bool ltr = groupBox->direction == Qt::LeftToRight; + QRect finalRect; + if (groupBox->subControls & QStyle::SC_GroupBoxCheckBox) { + finalRect = checkBoxRect.united(textRect); + finalRect.adjust(ltr ? -4 : 0, 0, ltr ? 0 : 4, 0); + } else { + finalRect = textRect; + } + region -= finalRect; + } + p->setClipRegion(region); + proxy()->drawPrimitive(PE_FrameGroupBox, &frame, p); + p->restore(); + } + + // Draw title + if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { + QColor textColor = groupBox->textColor; + if (textColor.isValid()) + p->setPen(textColor); + int alignment = int(groupBox->textAlignment); + if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, opt)) + alignment |= Qt::TextHideMnemonic; + + proxy()->drawItemText(p, textRect, Qt::TextShowMnemonic | Qt::AlignHCenter | alignment, + groupBox->palette, groupBox->state & State_Enabled, groupBox->text, + textColor.isValid() ? QPalette::NoRole : QPalette::WindowText); + + if (groupBox->state & State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*groupBox); + fropt.rect = textRect; + proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p); + } + } + + // Draw checkbox + if (groupBox->subControls & SC_GroupBoxCheckBox) { + QStyleOptionButton box; + box.QStyleOption::operator=(*groupBox); + box.rect = checkBoxRect; + proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, p); + } + } + break; + case CC_MdiControls: + { + QStyleOptionButton btnOpt; + btnOpt.QStyleOption::operator=(*opt); + btnOpt.state &= ~State_MouseOver; + int bsx = 0; + int bsy = 0; + const int buttonIconMetric = proxy()->pixelMetric(PM_TitleBarButtonIconSize, &btnOpt); + const QSize buttonIconSize(buttonIconMetric, buttonIconMetric); + if (opt->subControls & QStyle::SC_MdiCloseButton) { + if (opt->activeSubControls & QStyle::SC_MdiCloseButton && (opt->state & State_Sunken)) { + btnOpt.state |= State_Sunken; + btnOpt.state &= ~State_Raised; + bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal); + bsy = proxy()->pixelMetric(PM_ButtonShiftVertical); + } else { + btnOpt.state |= State_Raised; + btnOpt.state &= ~State_Sunken; + bsx = 0; + bsy = 0; + } + btnOpt.rect = proxy()->subControlRect(CC_MdiControls, opt, SC_MdiCloseButton); + proxy()->drawPrimitive(PE_PanelButtonCommand, &btnOpt, p); + QPixmap pm = proxy()->standardIcon(SP_TitleBarCloseButton).pixmap(buttonIconSize, dpr(opt->window)); + proxy()->drawItemPixmap(p, btnOpt.rect.translated(bsx, bsy), Qt::AlignCenter, pm); + } + if (opt->subControls & QStyle::SC_MdiNormalButton) { + if (opt->activeSubControls & QStyle::SC_MdiNormalButton && (opt->state & State_Sunken)) { + btnOpt.state |= State_Sunken; + btnOpt.state &= ~State_Raised; + bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal); + bsy = proxy()->pixelMetric(PM_ButtonShiftVertical); + } else { + btnOpt.state |= State_Raised; + btnOpt.state &= ~State_Sunken; + bsx = 0; + bsy = 0; + } + btnOpt.rect = proxy()->subControlRect(CC_MdiControls, opt, SC_MdiNormalButton); + proxy()->drawPrimitive(PE_PanelButtonCommand, &btnOpt, p); + QPixmap pm = proxy()->standardIcon(SP_TitleBarNormalButton).pixmap(buttonIconSize, dpr(opt->window)); + proxy()->drawItemPixmap(p, btnOpt.rect.translated(bsx, bsy), Qt::AlignCenter, pm); + } + if (opt->subControls & QStyle::SC_MdiMinButton) { + if (opt->activeSubControls & QStyle::SC_MdiMinButton && (opt->state & State_Sunken)) { + btnOpt.state |= State_Sunken; + btnOpt.state &= ~State_Raised; + bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal); + bsy = proxy()->pixelMetric(PM_ButtonShiftVertical); + } else { + btnOpt.state |= State_Raised; + btnOpt.state &= ~State_Sunken; + bsx = 0; + bsy = 0; + } + btnOpt.rect = proxy()->subControlRect(CC_MdiControls, opt, SC_MdiMinButton); + proxy()->drawPrimitive(PE_PanelButtonCommand, &btnOpt, p); + QPixmap pm = proxy()->standardIcon(SP_TitleBarMinButton).pixmap(buttonIconSize, dpr(opt->window)); + proxy()->drawItemPixmap(p, btnOpt.rect.translated(bsx, bsy), Qt::AlignCenter, pm); + } + } + break; + default: + qWarning("QCommonStyle::drawComplexControl: Control %d not handled", cc); + } +} + +/*! + \reimp +*/ +QStyle::SubControl QCommonStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt) const +{ + SubControl sc = SC_None; + switch (cc) { + case CC_Slider: + if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + QRect r = proxy()->subControlRect(cc, slider, SC_SliderHandle); + if (r.isValid() && r.contains(pt)) { + sc = SC_SliderHandle; + } else { + r = proxy()->subControlRect(cc, slider, SC_SliderGroove); + if (r.isValid() && r.contains(pt)) + sc = SC_SliderGroove; + } + } + break; + case CC_ScrollBar: + if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + QRect r; + uint ctrl = SC_ScrollBarAddLine; + while (ctrl <= SC_ScrollBarGroove) { + r = proxy()->subControlRect(cc, scrollbar, QStyle::SubControl(ctrl)); + if (r.isValid() && r.contains(pt)) { + sc = QStyle::SubControl(ctrl); + break; + } + ctrl <<= 1; + } + } + break; + case CC_ToolButton: + if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) { + QRect r; + uint ctrl = SC_ToolButton; + while (ctrl <= SC_ToolButtonMenu) { + r = proxy()->subControlRect(cc, toolbutton, QStyle::SubControl(ctrl)); + if (r.isValid() && r.contains(pt)) { + sc = QStyle::SubControl(ctrl); + break; + } + ctrl <<= 1; + } + } + break; + case CC_SpinBox: + if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { + QRect r; + uint ctrl = SC_SpinBoxUp; + while (ctrl <= SC_SpinBoxEditField) { + r = proxy()->subControlRect(cc, spinbox, QStyle::SubControl(ctrl)); + if (r.isValid() && r.contains(pt)) { + sc = QStyle::SubControl(ctrl); + break; + } + ctrl <<= 1; + } + } + break; + case CC_TitleBar: + if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) { + QRect r; + uint ctrl = SC_TitleBarSysMenu; + + while (ctrl <= SC_TitleBarLabel) { + r = proxy()->subControlRect(cc, tb, QStyle::SubControl(ctrl)); + if (r.isValid() && r.contains(pt)) { + sc = QStyle::SubControl(ctrl); + break; + } + ctrl <<= 1; + } + } + break; + case CC_ComboBox: + if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + QRect r; + uint ctrl = SC_ComboBoxArrow; // Start here and go down. + while (ctrl > 0) { + r = proxy()->subControlRect(cc, cb, QStyle::SubControl(ctrl)); + if (r.isValid() && r.contains(pt)) { + sc = QStyle::SubControl(ctrl); + break; + } + ctrl >>= 1; + } + } + break; + case CC_GroupBox: + if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) { + QRect r; + uint ctrl = SC_GroupBoxCheckBox; + while (ctrl <= SC_GroupBoxFrame) { + r = proxy()->subControlRect(cc, groupBox, QStyle::SubControl(ctrl)); + if (r.isValid() && r.contains(pt)) { + sc = QStyle::SubControl(ctrl); + break; + } + ctrl <<= 1; + } + } + break; + case CC_MdiControls: + { + QRect r; + uint ctrl = SC_MdiMinButton; + while (ctrl <= SC_MdiCloseButton) { + r = proxy()->subControlRect(CC_MdiControls, opt, QStyle::SubControl(ctrl)); + if (r.isValid() && r.contains(pt) && (opt->subControls & ctrl)) { + sc = QStyle::SubControl(ctrl); + return sc; + } + ctrl <<= 1; + } + } + break; + default: + qWarning("QCommonStyle::hitTestComplexControl: Case %d not handled", cc); + } + return sc; +} + +/*! + \reimp +*/ +QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc) const +{ + QRect ret; + switch (cc) { + case CC_Slider: + if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider); + int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider); + + switch (sc) { + case SC_SliderHandle: { + int sliderPos = 0; + int len = proxy()->pixelMetric(PM_SliderLength, slider); + bool horizontal = slider->orientation == Qt::Horizontal; + sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum, + slider->sliderPosition, + (horizontal ? slider->rect.width() + : slider->rect.height()) - len, + slider->upsideDown); + if (horizontal) + ret.setRect(slider->rect.x() + sliderPos, slider->rect.y() + tickOffset, len, thickness); + else + ret.setRect(slider->rect.x() + tickOffset, slider->rect.y() + sliderPos, thickness, len); + break; } + case SC_SliderGroove: + if (slider->orientation == Qt::Horizontal) + ret.setRect(slider->rect.x(), slider->rect.y() + tickOffset, + slider->rect.width(), thickness); + else + ret.setRect(slider->rect.x() + tickOffset, slider->rect.y(), + thickness, slider->rect.height()); + break; + default: + break; + } + ret = visualRect(slider->direction, slider->rect, ret); + } + break; + case CC_ScrollBar: + if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + const QRect scrollBarRect = scrollbar->rect; + int sbextent = 0; + if (!proxy()->styleHint(SH_ScrollBar_Transient, scrollbar)) + sbextent = proxy()->pixelMetric(PM_ScrollBarExtent, scrollbar); + int maxlen = ((scrollbar->orientation == Qt::Horizontal) ? + scrollBarRect.width() : scrollBarRect.height()) - (sbextent * 2); + int sliderlen; + + // calculate slider length + if (scrollbar->maximum != scrollbar->minimum) { + uint range = scrollbar->maximum - scrollbar->minimum; + sliderlen = (qint64(scrollbar->pageStep) * maxlen) / (range + scrollbar->pageStep); + + int slidermin = proxy()->pixelMetric(PM_ScrollBarSliderMin, scrollbar); + if (sliderlen < slidermin || range > INT_MAX / 2) + sliderlen = slidermin; + if (sliderlen > maxlen) + sliderlen = maxlen; + } else { + sliderlen = maxlen; + } + + int sliderstart = sbextent + sliderPositionFromValue(scrollbar->minimum, + scrollbar->maximum, + scrollbar->sliderPosition, + maxlen - sliderlen, + scrollbar->upsideDown); + + switch (sc) { + case SC_ScrollBarSubLine: // top/left button + if (scrollbar->orientation == Qt::Horizontal) { + int buttonWidth = qMin(scrollBarRect.width() / 2, sbextent); + ret.setRect(0, 0, buttonWidth, scrollBarRect.height()); + } else { + int buttonHeight = qMin(scrollBarRect.height() / 2, sbextent); + ret.setRect(0, 0, scrollBarRect.width(), buttonHeight); + } + break; + case SC_ScrollBarAddLine: // bottom/right button + if (scrollbar->orientation == Qt::Horizontal) { + int buttonWidth = qMin(scrollBarRect.width()/2, sbextent); + ret.setRect(scrollBarRect.width() - buttonWidth, 0, buttonWidth, scrollBarRect.height()); + } else { + int buttonHeight = qMin(scrollBarRect.height()/2, sbextent); + ret.setRect(0, scrollBarRect.height() - buttonHeight, scrollBarRect.width(), buttonHeight); + } + break; + case SC_ScrollBarSubPage: // between top/left button and slider + if (scrollbar->orientation == Qt::Horizontal) + ret.setRect(sbextent, 0, sliderstart - sbextent, scrollBarRect.height()); + else + ret.setRect(0, sbextent, scrollBarRect.width(), sliderstart - sbextent); + break; + case SC_ScrollBarAddPage: // between bottom/right button and slider + if (scrollbar->orientation == Qt::Horizontal) + ret.setRect(sliderstart + sliderlen, 0, + maxlen - sliderstart - sliderlen + sbextent, scrollBarRect.height()); + else + ret.setRect(0, sliderstart + sliderlen, scrollBarRect.width(), + maxlen - sliderstart - sliderlen + sbextent); + break; + case SC_ScrollBarGroove: + if (scrollbar->orientation == Qt::Horizontal) + ret.setRect(sbextent, 0, scrollBarRect.width() - sbextent * 2, + scrollBarRect.height()); + else + ret.setRect(0, sbextent, scrollBarRect.width(), + scrollBarRect.height() - sbextent * 2); + break; + case SC_ScrollBarSlider: + if (scrollbar->orientation == Qt::Horizontal) + ret.setRect(sliderstart, 0, sliderlen, scrollBarRect.height()); + else + ret.setRect(0, sliderstart, scrollBarRect.width(), sliderlen); + break; + default: + break; + } + ret = visualRect(scrollbar->direction, scrollBarRect, ret); + } + break; + case CC_SpinBox: + if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { + QSize bs; + int fw = spinbox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinbox) : 0; + bs.setHeight(qMax(8, spinbox->rect.height()/2 - fw)); + // 1.6 -approximate golden mean + bs.setWidth(qMax(16, qMin(bs.height() * 8 / 5, spinbox->rect.width() / 4))); + int y = fw + spinbox->rect.y(); + int x, lx, rx; + x = spinbox->rect.x() + spinbox->rect.width() - fw - bs.width(); + lx = fw; + rx = x - fw; + switch (sc) { + case SC_SpinBoxUp: + if (spinbox->buttonSymbols == QStyleOptionSpinBox::NoButtons) + return QRect(); + ret = QRect(x, y, bs.width(), bs.height()); + break; + case SC_SpinBoxDown: + if (spinbox->buttonSymbols == QStyleOptionSpinBox::NoButtons) + return QRect(); + + ret = QRect(x, y + bs.height(), bs.width(), bs.height()); + break; + case SC_SpinBoxEditField: + if (spinbox->buttonSymbols == QStyleOptionSpinBox::NoButtons) { + ret = QRect(lx, fw, spinbox->rect.width() - 2*fw, spinbox->rect.height() - 2*fw); + } else { + ret = QRect(lx, fw, rx, spinbox->rect.height() - 2*fw); + } + break; + case SC_SpinBoxFrame: + ret = spinbox->rect; + default: + break; + } + ret = visualRect(spinbox->direction, spinbox->rect, ret); + } + break; + case CC_ToolButton: + if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) { + int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, tb); + ret = tb->rect; + switch (sc) { + case SC_ToolButton: + if ((tb->features + & (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay)) + == QStyleOptionToolButton::MenuButtonPopup) + ret.adjust(0, 0, -mbi, 0); + break; + case SC_ToolButtonMenu: + if ((tb->features + & (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay)) + == QStyleOptionToolButton::MenuButtonPopup) + ret.adjust(ret.width() - mbi, 0, 0, 0); + break; + default: + break; + } + ret = visualRect(tb->direction, tb->rect, ret); + } + break; + case CC_ComboBox: + if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + const qreal dpi = QStyleHelper::dpi(opt); + const int x = cb->rect.x(), y = cb->rect.y(), wi = cb->rect.width(), he = cb->rect.height(); + const int margin = cb->frame ? qRound(QStyleHelper::dpiScaled(3, dpi)) : 0; + const int bmarg = cb->frame ? qRound(QStyleHelper::dpiScaled(2, dpi)) : 0; + const int xpos = x + wi - bmarg - qRound(QStyleHelper::dpiScaled(16, dpi)); + + + switch (sc) { + case SC_ComboBoxFrame: + ret = cb->rect; + break; + case SC_ComboBoxArrow: + ret.setRect(xpos, y + bmarg, qRound(QStyleHelper::dpiScaled(16, opt)), he - 2*bmarg); + break; + case SC_ComboBoxEditField: + ret.setRect(x + margin, y + margin, wi - 2 * margin - qRound(QStyleHelper::dpiScaled(16, dpi)), he - 2 * margin); + break; + case SC_ComboBoxListBoxPopup: + ret = cb->rect; + break; + default: + break; + } + ret = visualRect(cb->direction, cb->rect, ret); + } + break; + case CC_TitleBar: + if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) { + const int controlMargin = 2; + const int controlHeight = tb->rect.height() - controlMargin *2; + const int delta = controlHeight + controlMargin; + int offset = 0; + + bool isMinimized = tb->titleBarState & Qt::WindowMinimized; + bool isMaximized = tb->titleBarState & Qt::WindowMaximized; + + switch (sc) { + case SC_TitleBarLabel: + if (tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) { + ret = tb->rect; + if (tb->titleBarFlags & Qt::WindowSystemMenuHint) + ret.adjust(delta, 0, -delta, 0); + if (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) + ret.adjust(0, 0, -delta, 0); + if (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) + ret.adjust(0, 0, -delta, 0); + if (tb->titleBarFlags & Qt::WindowShadeButtonHint) + ret.adjust(0, 0, -delta, 0); + if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) + ret.adjust(0, 0, -delta, 0); + } + break; + case SC_TitleBarContextHelpButton: + if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) + offset += delta; + Q_FALLTHROUGH(); + case SC_TitleBarMinButton: + if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)) + offset += delta; + else if (sc == SC_TitleBarMinButton) + break; + Q_FALLTHROUGH(); + case SC_TitleBarNormalButton: + if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)) + offset += delta; + else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)) + offset += delta; + else if (sc == SC_TitleBarNormalButton) + break; + Q_FALLTHROUGH(); + case SC_TitleBarMaxButton: + if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)) + offset += delta; + else if (sc == SC_TitleBarMaxButton) + break; + Q_FALLTHROUGH(); + case SC_TitleBarShadeButton: + if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint)) + offset += delta; + else if (sc == SC_TitleBarShadeButton) + break; + Q_FALLTHROUGH(); + case SC_TitleBarUnshadeButton: + if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint)) + offset += delta; + else if (sc == SC_TitleBarUnshadeButton) + break; + Q_FALLTHROUGH(); + case SC_TitleBarCloseButton: + if (tb->titleBarFlags & Qt::WindowSystemMenuHint) + offset += delta; + else if (sc == SC_TitleBarCloseButton) + break; + ret.setRect(tb->rect.right() - offset, tb->rect.top() + controlMargin, + controlHeight, controlHeight); + break; + case SC_TitleBarSysMenu: + if (tb->titleBarFlags & Qt::WindowSystemMenuHint) { + ret.setRect(tb->rect.left() + controlMargin, tb->rect.top() + controlMargin, + controlHeight, controlHeight); + } + break; + default: + break; + } + ret = visualRect(tb->direction, tb->rect, ret); + } + break; + case CC_GroupBox: { + if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) { + switch (sc) { + case SC_GroupBoxFrame: + case SC_GroupBoxContents: { + int topMargin = 0; + int topHeight = 0; + int verticalAlignment = proxy()->styleHint(SH_GroupBox_TextLabelVerticalAlignment, groupBox); + bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox; + if (groupBox->text.size() || hasCheckBox) { + int checkBoxHeight = hasCheckBox ? proxy()->pixelMetric(PM_IndicatorHeight, groupBox) : 0; + topHeight = qMax(groupBox->fontMetrics.height(), checkBoxHeight); + if (verticalAlignment & Qt::AlignVCenter) + topMargin = topHeight / 2; + else if (verticalAlignment & Qt::AlignTop) + topMargin = topHeight; + } + + QRect frameRect = groupBox->rect; + frameRect.setTop(topMargin); + + if (sc == SC_GroupBoxFrame) { + ret = frameRect; + break; + } + + int frameWidth = 0; + if ((groupBox->features & QStyleOptionFrame::Flat) == 0) + frameWidth = proxy()->pixelMetric(PM_DefaultFrameWidth, groupBox); + ret = frameRect.adjusted(frameWidth, frameWidth + topHeight - topMargin, + -frameWidth, -frameWidth); + break; + } + case SC_GroupBoxCheckBox: + case SC_GroupBoxLabel: { + QFontMetrics fontMetrics = groupBox->fontMetrics; + int th = fontMetrics.height(); + int tw = fontMetrics.size(Qt::TextShowMnemonic, groupBox->text + QLatin1Char(' ')).width(); + int marg = (groupBox->features & QStyleOptionFrame::Flat) ? 0 : 8; + ret = groupBox->rect.adjusted(marg, 0, -marg, 0); + + int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, opt); + int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, opt); + int indicatorSpace = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, opt) - 1; + bool hasCheckBox = groupBox->subControls & QStyle::SC_GroupBoxCheckBox; + int checkBoxWidth = hasCheckBox ? (indicatorWidth + indicatorSpace) : 0; + int checkBoxHeight = hasCheckBox ? indicatorHeight : 0; + + int h = qMax(th, checkBoxHeight); + ret.setHeight(h); + + // Adjusted rect for label + indicatorWidth + indicatorSpace + QRect totalRect = alignedRect(groupBox->direction, groupBox->textAlignment, + QSize(tw + checkBoxWidth, h), ret); + + // Adjust totalRect if checkbox is set + if (hasCheckBox) { + bool ltr = groupBox->direction == Qt::LeftToRight; + int left = 0; + // Adjust for check box + if (sc == SC_GroupBoxCheckBox) { + left = ltr ? totalRect.left() : (totalRect.right() - indicatorWidth); + int top = totalRect.top() + (h - checkBoxHeight) / 2; + totalRect.setRect(left, top, indicatorWidth, indicatorHeight); + // Adjust for label + } else { + left = ltr ? (totalRect.left() + checkBoxWidth - 2) : totalRect.left(); + int top = totalRect.top() + (h - th) / 2; + totalRect.setRect(left, top, totalRect.width() - checkBoxWidth, th); + } + } + ret = totalRect; + break; + } + default: + break; + } + } + break; + } + case CC_MdiControls: + { + int numSubControls = 0; + if (opt->subControls & SC_MdiCloseButton) + ++numSubControls; + if (opt->subControls & SC_MdiMinButton) + ++numSubControls; + if (opt->subControls & SC_MdiNormalButton) + ++numSubControls; + if (numSubControls == 0) + break; + + int buttonWidth = opt->rect.width() / numSubControls - 1; + int offset = 0; + switch (sc) { + case SC_MdiCloseButton: + // Only one sub control, no offset needed. + if (numSubControls == 1) + break; + offset += buttonWidth + 2; + Q_FALLTHROUGH(); + case SC_MdiNormalButton: + // No offset needed if + // 1) There's only one sub control + // 2) We have a close button and a normal button (offset already added in SC_MdiClose) + if (numSubControls == 1 || (numSubControls == 2 && !(opt->subControls & SC_MdiMinButton))) + break; + if (opt->subControls & SC_MdiNormalButton) + offset += buttonWidth; + break; + default: + break; + } + + // Subtract one pixel if we only have one sub control. At this point + // buttonWidth is the actual width + 1 pixel margin, but we don't want the + // margin when there are no other controllers. + if (numSubControls == 1) + --buttonWidth; + ret = QRect(offset, 0, buttonWidth, opt->rect.height()); + break; } + default: + qWarning("QCommonStyle::subControlRect: Case %d not handled", cc); + } + + return ret; +} + +int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt) const +{ + int ret; + + switch (m) { + case PM_FocusFrameVMargin: + case PM_FocusFrameHMargin: + ret = 2; + break; + case PM_MenuBarVMargin: + case PM_MenuBarHMargin: + ret = 0; + break; + case PM_DialogButtonsSeparator: + ret = int(QStyleHelper::dpiScaled(5, opt)); + break; + case PM_DialogButtonsButtonWidth: + ret = int(QStyleHelper::dpiScaled(70, opt)); + break; + case PM_DialogButtonsButtonHeight: + ret = int(QStyleHelper::dpiScaled(30, opt)); + break; + case PM_TitleBarHeight: { + if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) { + if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool) { + ret = qMax(opt->fontMetrics.height(), 16); + } else { + ret = qMax(opt->fontMetrics.height(), 18); + } + } else { + ret = int(QStyleHelper::dpiScaled(18., opt)); + } + + break; } + case PM_TitleBarButtonSize: + ret = int(QStyleHelper::dpiScaled(16., opt)); + break; + case PM_TitleBarButtonIconSize: + ret = int(QStyleHelper::dpiScaled(16., opt)); + break; + + case PM_ScrollBarSliderMin: + ret = int(QStyleHelper::dpiScaled(9., opt)); + break; + + case PM_ButtonMargin: + ret = int(QStyleHelper::dpiScaled(6., opt)); + break; + + case PM_DockWidgetTitleBarButtonMargin: + ret = int(QStyleHelper::dpiScaled(2., opt)); + break; + + case PM_ButtonDefaultIndicator: + ret = 0; + break; + + case PM_MenuButtonIndicator: + ret = int(QStyleHelper::dpiScaled(12, opt)); + break; + + case PM_ButtonShiftHorizontal: + case PM_ButtonShiftVertical: + + case PM_DefaultFrameWidth: + ret = 2; + break; + + case PM_ComboBoxFrameWidth: + case PM_SpinBoxFrameWidth: + case PM_MenuPanelWidth: + case PM_TabBarBaseOverlap: + case PM_TabBarBaseHeight: + ret = proxy()->pixelMetric(PM_DefaultFrameWidth, opt); + break; + case PM_MdiSubWindowFrameWidth: + ret = int(QStyleHelper::dpiScaled(4, opt)); + break; + case PM_MdiSubWindowMinimizedWidth: + ret = int(QStyleHelper::dpiScaled(196, opt)); + break; + case PM_ScrollBarExtent: + ret = int(QStyleHelper::dpiScaled(16, opt)); + break; + case PM_MaximumDragDistance: + ret = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::MaximumScrollBarDragDistance).toInt(); + break; + case PM_SliderThickness: + ret = int(QStyleHelper::dpiScaled(16, opt)); + break; + case PM_SliderTickmarkOffset: + if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() + : sl->rect.width(); + int thickness = proxy()->pixelMetric(PM_SliderControlThickness, sl); + int ticks = sl->tickPosition; + + if (ticks == QStyleOptionSlider::TicksBothSides) + ret = (space - thickness) / 2; + else if (ticks == QStyleOptionSlider::TicksAbove) + ret = space - thickness; + else + ret = 0; + } else { + ret = 0; + } + break; + case PM_SliderSpaceAvailable: + if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + if (sl->orientation == Qt::Horizontal) + ret = sl->rect.width() - proxy()->pixelMetric(PM_SliderLength, sl); + else + ret = sl->rect.height() - proxy()->pixelMetric(PM_SliderLength, sl); + } else { + ret = 0; + } + break; + case PM_DockWidgetSeparatorExtent: + ret = int(QStyleHelper::dpiScaled(6, opt)); + break; + + case PM_DockWidgetHandleExtent: + ret = int(QStyleHelper::dpiScaled(8, opt)); + break; + case PM_DockWidgetTitleMargin: + ret = 0; + break; + case PM_DockWidgetFrameWidth: + ret = 1; + break; + case PM_SpinBoxSliderHeight: + case PM_MenuBarPanelWidth: + ret = 2; + break; + case PM_MenuBarItemSpacing: + ret = 0; + break; + case PM_ToolBarFrameWidth: + ret = 1; + break; + + case PM_ToolBarItemMargin: + ret = 0; + break; + + case PM_ToolBarItemSpacing: + ret = int(QStyleHelper::dpiScaled(4, opt)); + break; + + case PM_ToolBarHandleExtent: + ret = int(QStyleHelper::dpiScaled(8, opt)); + break; + + case PM_ToolBarSeparatorExtent: + ret = int(QStyleHelper::dpiScaled(6, opt)); + break; + + case PM_ToolBarExtensionExtent: + ret = int(QStyleHelper::dpiScaled(12, opt)); + break; + + case PM_TabBarTabOverlap: + ret = 3; + break; + + case PM_TabBarTabHSpace: + ret = int(QStyleHelper::dpiScaled(24, opt)); + break; + + case PM_TabBarTabShiftHorizontal: + ret = 0; + break; + + case PM_TabBarTabShiftVertical: + ret = 2; + break; + + case PM_TabBarTabVSpace: { + const QStyleOptionTab *tb = qstyleoption_cast<const QStyleOptionTab *>(opt); + if (tb && (tb->shape == QStyleOptionTab::RoundedNorth || tb->shape == QStyleOptionTab::RoundedSouth + || tb->shape == QStyleOptionTab::RoundedWest || tb->shape == QStyleOptionTab::RoundedEast)) + ret = 8; + else + if(tb && (tb->shape == QStyleOptionTab::TriangularWest || tb->shape == QStyleOptionTab::TriangularEast)) + ret = 3; + else + ret = 2; + break; } + + case PM_ProgressBarChunkWidth: + ret = 9; + break; + + case PM_IndicatorWidth: + ret = int(QStyleHelper::dpiScaled(13, opt)); + break; + + case PM_IndicatorHeight: + ret = int(QStyleHelper::dpiScaled(13, opt)); + break; + + case PM_ExclusiveIndicatorWidth: + ret = int(QStyleHelper::dpiScaled(12, opt)); + break; + + case PM_ExclusiveIndicatorHeight: + ret = int(QStyleHelper::dpiScaled(12, opt)); + break; + + case PM_MenuTearoffHeight: + ret = int(QStyleHelper::dpiScaled(10, opt)); + break; + + case PM_MenuScrollerHeight: + ret = int(QStyleHelper::dpiScaled(10, opt)); + break; + + case PM_MenuDesktopFrameWidth: + case PM_MenuHMargin: + case PM_MenuVMargin: + ret = 0; + break; + + case PM_HeaderMargin: + ret = int(QStyleHelper::dpiScaled(4, opt)); + break; + case PM_HeaderMarkSize: + ret = int(QStyleHelper::dpiScaled(16, opt)); + break; + case PM_HeaderGripMargin: + ret = int(QStyleHelper::dpiScaled(4, opt)); + break; + case PM_HeaderDefaultSectionSizeHorizontal: + ret = int(QStyleHelper::dpiScaled(100, opt)); + break; + case PM_HeaderDefaultSectionSizeVertical: + ret = int(QStyleHelper::dpiScaled(30, opt)); + break; + case PM_TabBarScrollButtonWidth: + ret = int(QStyleHelper::dpiScaled(16, opt)); + break; + case PM_LayoutLeftMargin: + case PM_LayoutTopMargin: + case PM_LayoutRightMargin: + case PM_LayoutBottomMargin: + { + bool isWindow = opt ? (opt->state & State_Window) : false; + ret = proxy()->pixelMetric(isWindow ? PM_DefaultTopLevelMargin : PM_DefaultChildMargin); + } + break; + case PM_LayoutHorizontalSpacing: + case PM_LayoutVerticalSpacing: + ret = proxy()->pixelMetric(PM_DefaultLayoutSpacing); + break; + + case PM_DefaultTopLevelMargin: + ret = int(QStyleHelper::dpiScaled(11, opt)); + break; + case PM_DefaultChildMargin: + ret = int(QStyleHelper::dpiScaled(9, opt)); + break; + case PM_DefaultLayoutSpacing: + ret = int(QStyleHelper::dpiScaled(6, opt)); + break; + + case PM_ToolBarIconSize: + ret = 0; + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + ret = theme->themeHint(QPlatformTheme::ToolBarIconSize).toInt(); + if (ret <= 0) + ret = int(QStyleHelper::dpiScaled(24, opt)); + break; + + case PM_TabBarIconSize: + case PM_ListViewIconSize: + ret = proxy()->pixelMetric(PM_SmallIconSize, opt); + break; + + case PM_ButtonIconSize: + case PM_SmallIconSize: + ret = int(QStyleHelper::dpiScaled(16, opt)); + break; + case PM_IconViewIconSize: + ret = proxy()->pixelMetric(PM_LargeIconSize, opt); + break; + + case PM_LargeIconSize: + ret = int(QStyleHelper::dpiScaled(32, opt)); + break; + + case PM_ToolTipLabelFrameWidth: + ret = 1; + break; + case PM_CheckBoxLabelSpacing: + case PM_RadioButtonLabelSpacing: + ret = int(QStyleHelper::dpiScaled(6, opt)); + break; + case PM_SizeGripSize: + ret = int(QStyleHelper::dpiScaled(13, opt)); + break; + case PM_MessageBoxIconSize: +#ifdef Q_OS_MAC + if (QGuiApplication::desktopSettingsAware()) { + ret = 64; // No DPI scaling, it's handled elsewhere. + } else +#endif + { + ret = int(QStyleHelper::dpiScaled(32, opt)); + } + break; + case PM_TextCursorWidth: + ret = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::TextCursorWidth).toInt(); + break; + case PM_TabBar_ScrollButtonOverlap: + ret = 1; + break; + case PM_TabCloseIndicatorWidth: + case PM_TabCloseIndicatorHeight: + ret = int(QStyleHelper::dpiScaled(16, opt)); + break; + case PM_ScrollView_ScrollBarSpacing: + ret = 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, opt); + break; + case PM_ScrollView_ScrollBarOverlap: + ret = 0; + break; + case PM_SubMenuOverlap: + ret = -proxy()->pixelMetric(QStyle::PM_MenuPanelWidth, opt); + break; + case PM_TreeViewIndentation: + ret = int(QStyleHelper::dpiScaled(20, opt)); + break; + default: + ret = 0; + break; + } + + return ret; +} + +QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &csz) const +{ + Q_D(const QCommonStyle); + QSize sz(!csz.isEmpty() ? csz : QSize(0,0)); + + switch (ct) { + case CT_PushButton: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + int w = sz.width(), + h = sz.height(), + bm = proxy()->pixelMetric(PM_ButtonMargin, btn), + fw = proxy()->pixelMetric(PM_DefaultFrameWidth, btn) * 2; + w += bm + fw; + h += bm + fw; + if (btn->features & QStyleOptionButton::AutoDefaultButton){ + int dbw = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn) * 2; + w += dbw; + h += dbw; + } + sz = QSize(w, h); + } + break; + case CT_RadioButton: + case CT_CheckBox: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + bool isRadio = (ct == CT_RadioButton); + + int w = proxy()->pixelMetric(isRadio ? PM_ExclusiveIndicatorWidth + : PM_IndicatorWidth, btn); + int h = proxy()->pixelMetric(isRadio ? PM_ExclusiveIndicatorHeight + : PM_IndicatorHeight, btn); + + int margins = 0; + // we add 4 pixels for label margins + if (!btn->icon.isNull() || !btn->text.isEmpty()) + margins = 4 + proxy()->pixelMetric(isRadio ? PM_RadioButtonLabelSpacing + : PM_CheckBoxLabelSpacing, opt); + sz += QSize(w + margins, 4); + sz.setHeight(qMax(sz.height(), h)); + } + break; + case CT_MenuItem: + if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { + bool checkable = mi->menuHasCheckableItems; + int maxpmw = mi->maxIconWidth; + int w = sz.width(), h = sz.height(); + if (mi->menuItemType == QStyleOptionMenuItem::Separator) { + w = 10; + h = 2; + } else { + h = mi->fontMetrics.height() + 8; + if (!mi->icon.isNull()) { + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); + h = qMax(h, mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + 4); + } + } + if (mi->text.contains(QLatin1Char('\t'))) + w += 12; + if (maxpmw > 0) + w += maxpmw + 6; + if (checkable && maxpmw < 20) + w += 20 - maxpmw; + if (checkable || maxpmw > 0) + w += 2; + w += 12; + sz = QSize(w, h); + } + break; + case CT_ToolButton: + sz = QSize(sz.width() + 6, sz.height() + 5); + break; + case CT_ComboBox: + if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + int fw = cmb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt) * 2 : 0; + const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1); + // QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins... + int other = qMax(23, 2*textMargins + proxy()->pixelMetric(QStyle::PM_ScrollBarExtent, opt)); + sz = QSize(sz.width() + fw + other, sz.height() + fw); + } + break; + case CT_HeaderSection: + if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { + bool nullIcon = hdr->icon.isNull(); + int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, hdr); + int iconSize = nullIcon ? 0 : proxy()->pixelMetric(QStyle::PM_SmallIconSize, hdr); + QSize txt = hdr->fontMetrics.size(0, hdr->text); + sz.setHeight(margin + qMax(iconSize, txt.height()) + margin); + sz.setWidth((nullIcon ? 0 : margin) + iconSize + + (hdr->text.isNull() ? 0 : margin) + txt.width() + margin); + if (hdr->sortIndicator != QStyleOptionHeader::None) { + int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, hdr); + if (hdr->orientation == Qt::Horizontal) + sz.rwidth() += sz.height() + margin; + else + sz.rheight() += sz.width() + margin; + } + } + break; + case CT_TabWidget: + sz += QSize(4, 4); + break; + case CT_LineEdit: + if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + const int borderSize = 2 * f->lineWidth; + sz += QSize(borderSize, borderSize); + const int minSize = 10; + if (sz.width() < minSize) + sz.rwidth() = minSize; + if (sz.height() < minSize) + sz.rheight() = minSize; + } + break; + case CT_GroupBox: + if (const QStyleOptionGroupBox *styleOpt = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) { + if (sz.isEmpty()) + sz = QSize(20, 20); + sz += QSize(styleOpt->features.testFlag(QStyleOptionFrame::Flat) ? 0 : 16, 0); + } + break; + case CT_MdiControls: + if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(opt)) { + const int buttonSize = proxy()->pixelMetric(PM_TitleBarButtonSize, styleOpt); + int width = 1; + if (styleOpt->subControls & SC_MdiMinButton) + width += buttonSize + 1; + if (styleOpt->subControls & SC_MdiNormalButton) + width += buttonSize + 1; + if (styleOpt->subControls & SC_MdiCloseButton) + width += buttonSize + 1; + sz = QSize(width, buttonSize); + } else { + const int buttonSize = proxy()->pixelMetric(PM_TitleBarButtonSize, opt); + sz = QSize(1 + 3 * (buttonSize + 1), buttonSize); + } + break; + case CT_ItemViewItem: + if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { + QRect decorationRect, displayRect, checkRect; + d->viewItemLayout(vopt, &checkRect, &decorationRect, &displayRect, true); + sz = (decorationRect|displayRect|checkRect).size(); + if (decorationRect.isValid() && sz.height() == decorationRect.height()) + sz.rheight() += 2; // Prevent icons from overlapping. + } + break; + case CT_SpinBox: + if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { + // Add button + frame widths + if (vopt->subControls == SC_SpinBoxFrame) { + const qreal dpi = QStyleHelper::dpi(opt); + const bool hasButtons = (vopt->buttonSymbols != QStyleOptionSpinBox::NoButtons); + const int buttonWidth = hasButtons ? qRound(QStyleHelper::dpiScaled(16, dpi)) : 0; + const int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt) : 0; + sz += QSize(buttonWidth + 2*fw, 1 + 2*fw); + } else { + const QSize buttonSize = proxy()->subControlRect(CC_SpinBox, vopt, SC_SpinBoxUp).size(); + const int upAndDownTogetherHeight = buttonSize.height() * 2; + sz += QSize(buttonSize.width(), upAndDownTogetherHeight); + } + } + break; + case CT_Slider: + if (const QStyleOptionSlider *option = qstyleoption_cast<const QStyleOptionSlider *>(opt)) + sz = subControlRect(QStyle::CC_Slider, option, QStyle::SC_SliderHandle).size(); + break; + case CT_Dial: + sz = QSize(20, 20); + break; + case CT_Frame: + if (const QStyleOptionFrame *option = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + const int ninePatchSplit = 1; + int w = qMax(10, (option->lineWidth * 2) + ninePatchSplit); + sz = QSize(w, w); + } + break; + case CT_ProgressBar: + if (sz.isNull()) { + // Special case: return minimum nine patch image size + sz = QSize(10, 10); + } + break; + case CT_ScrollBar: + case CT_MenuBar: + case CT_Menu: + case CT_MenuBarItem: + case CT_TabBarTab: + // just return the contentsSize for now + Q_FALLTHROUGH(); + default: + break; + } + return sz; +} + +QFont QCommonStyle::font(QStyle::ControlElement element, const QStyle::State state) const +{ + Q_UNUSED(element); + Q_UNUSED(state); + return QGuiApplication::font(); +} + +QMargins QCommonStyle::ninePatchMargins(QStyle::ControlElement /*ce*/, const QStyleOption * /*opt*/, const QSize &imageSize) const +{ + // By default, we just divide the image at the center + int w = imageSize.width() / 2; + int h = imageSize.height() / 2; + return QMargins(w, h, w, h); +} + +QMargins QCommonStyle::ninePatchMargins(QStyle::ComplexControl /*cc*/, const QStyleOptionComplex * /*opt*/, const QSize &imageSize) const +{ + // By default, we just divide the image at the center + int w = imageSize.width() / 2; + int h = imageSize.height() / 2; + return QMargins(w, h, w, h); +} + +int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, QStyleHintReturn *hret) const +{ + int ret = 0; + + switch (sh) { + case SH_Menu_KeyboardSearch: + ret = false; + break; + case SH_Slider_AbsoluteSetButtons: + ret = Qt::MiddleButton; + break; + case SH_Slider_PageSetButtons: + ret = Qt::LeftButton; + break; + case SH_ScrollBar_ContextMenu: + ret = true; + break; + case SH_GroupBox_TextLabelVerticalAlignment: + ret = Qt::AlignVCenter; + break; + case SH_GroupBox_TextLabelColor: + ret = opt ? int(opt->palette.color(QPalette::Text).rgba()) : 0; + break; + + case SH_ListViewExpand_SelectMouseType: + case SH_TabBar_SelectMouseType: + ret = QEvent::MouseButtonPress; + break; + + case SH_TabBar_Alignment: + ret = Qt::AlignLeft; + break; + + case SH_Header_ArrowAlignment: + ret = Qt::AlignRight | Qt::AlignVCenter; + break; + + case SH_TitleBar_AutoRaise: + ret = false; + break; + + case SH_Menu_SubMenuPopupDelay: + ret = 256; + break; + + case SH_Menu_SloppySubMenus: + ret = true; + break; + + case SH_Menu_SubMenuUniDirection: + ret = false; + break; + case SH_Menu_SubMenuUniDirectionFailCount: + ret = 1; + break; + case SH_Menu_SubMenuSloppySelectOtherActions: + ret = true; + break; + case SH_Menu_SubMenuSloppyCloseTimeout: + ret = 1000; + break; + case SH_Menu_SubMenuResetWhenReenteringParent: + ret = false; + break; + case SH_Menu_SubMenuDontStartSloppyOnLeave: + ret = false; + break; + + case SH_ProgressDialog_TextLabelAlignment: + ret = Qt::AlignCenter; + break; + + case SH_BlinkCursorWhenTextSelected: +#if defined(Q_OS_DARWIN) + ret = 0; +#else + ret = 1; +#endif + break; + + case SH_Table_GridLineColor: + if (opt) + ret = opt->palette.color(QPalette::Mid).rgba(); + else + ret = -1; + break; + case SH_LineEdit_PasswordCharacter: { + const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); + const QPlatformTheme::ThemeHint hintType = QPlatformTheme::PasswordMaskCharacter; + const QVariant hint = theme ? theme->themeHint(hintType) : QPlatformTheme::defaultThemeHint(hintType); + ret = hint.toChar().unicode(); + break; + } + case SH_LineEdit_PasswordMaskDelay: + ret = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::PasswordMaskDelay).toInt(); + break; + case SH_ToolBox_SelectedPageTitleBold: + ret = 1; + break; + + case SH_UnderlineShortcut: + ret = 1; + break; + + case SH_SpinBox_ClickAutoRepeatRate: + ret = 150; + break; + + case SH_SpinBox_ClickAutoRepeatThreshold: + ret = 500; + break; + + case SH_SpinBox_KeyPressAutoRepeatRate: + ret = 75; + break; + + case SH_Menu_SelectionWrap: + ret = true; + break; + + case SH_Menu_FillScreenWithScroll: + ret = true; + break; + + case SH_ToolTipLabel_Opacity: + ret = 255; + break; + + case SH_Button_FocusPolicy: + ret = Qt::StrongFocus; + break; + + case SH_MessageBox_UseBorderForButtonSpacing: + ret = 0; + break; + + case SH_ToolButton_PopupDelay: + ret = 600; + break; + + case SH_FocusFrame_Mask: + ret = 1; + break; + case SH_RubberBand_Mask: + if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) { + ret = 0; + if (rbOpt->shape == QStyleOptionRubberBand::Rectangle) { + ret = true; + if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) { + mask->region = opt->rect; + int margin = proxy()->pixelMetric(PM_DefaultFrameWidth) * 2; + mask->region -= opt->rect.adjusted(margin, margin, -margin, -margin); + } + } + } + break; + case SH_SpinControls_DisableOnBounds: + ret = 1; + break; + + case SH_Dial_BackgroundRole: + ret = QPalette::Window; + break; + + case SH_ComboBox_LayoutDirection: + ret = opt ? opt->direction : Qt::LeftToRight; + break; + + case SH_ItemView_EllipsisLocation: + ret = Qt::AlignTrailing; + break; + + case SH_ItemView_ShowDecorationSelected: + ret = false; + break; + + case SH_ItemView_ActivateItemOnSingleClick: + ret = 0; + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + ret = theme->themeHint(QPlatformTheme::ItemViewActivateItemOnSingleClick).toBool() ? 1 : 0; + break; + case SH_TitleBar_ModifyNotification: + ret = true; + break; + case SH_ScrollBar_RollBetweenButtons: + ret = false; + break; + case SH_TabBar_ElideMode: + ret = Qt::ElideNone; + break; + case SH_DialogButtonLayout: + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + ret = theme->themeHint(QPlatformTheme::DialogButtonBoxLayout).toInt(); + break; + case SH_ComboBox_PopupFrameStyle: + ret = QStyleOptionFrame::StyledPanel | QStyleOptionFrame::Plain; + break; + case SH_MessageBox_TextInteractionFlags: + ret = Qt::LinksAccessibleByMouse; + break; + case SH_DialogButtonBox_ButtonsHaveIcons: + ret = 0; + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + ret = theme->themeHint(QPlatformTheme::DialogButtonBoxButtonsHaveIcons).toBool() ? 1 : 0; + break; + case SH_SpellCheckUnderlineStyle: + ret = QTextCharFormat::WaveUnderline; + break; + case SH_MessageBox_CenterButtons: + ret = true; + break; + case SH_ItemView_MovementWithoutUpdatingSelection: + ret = true; + break; + case SH_FocusFrame_AboveWidget: + ret = false; + break; + case SH_TabWidget_DefaultTabPosition: + ret = QStyleOptionTabBarBase::North; + break; + case SH_ToolBar_Movable: + ret = true; + break; + case SH_TextControl_FocusIndicatorTextCharFormat: + ret = true; + if (QStyleHintReturnVariant *vret = qstyleoption_cast<QStyleHintReturnVariant*>(hret)) { + QPen outline(opt->palette.color(QPalette::Text), 1, Qt::DotLine); + QTextCharFormat fmt; + fmt.setProperty(QTextFormat::OutlinePen, outline); + vret->variant = fmt; + } + break; + case SH_WizardStyle: + break; + case SH_FormLayoutWrapPolicy: + break; + case SH_FormLayoutFieldGrowthPolicy: + break; + case SH_FormLayoutFormAlignment: + ret = Qt::AlignLeft | Qt::AlignTop; + break; + case SH_FormLayoutLabelAlignment: + ret = Qt::AlignLeft; + break; + case SH_ItemView_ArrowKeysNavigateIntoChildren: + ret = false; + break; + case SH_ItemView_DrawDelegateFrame: + ret = 0; + break; + case SH_TabBar_CloseButtonPosition: + ret = QStyleOptionTabBarBase::RightSide; + break; + case SH_TabBar_ChangeCurrentDelay: + ret = 500; + break; + case SH_DockWidget_ButtonsHaveFrame: + ret = true; + break; + case SH_ToolButtonStyle: + ret = 0; + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + ret = theme->themeHint(QPlatformTheme::ToolButtonStyle).toInt(); + break; + case SH_RequestSoftwareInputPanel: + ret = RSIP_OnMouseClick; + break; + case SH_ScrollBar_Transient: + ret = false; + break; + case SH_Menu_SupportsSections: + ret = false; + break; + case SH_ToolTip_WakeUpDelay: + ret = 700; + break; + case SH_ToolTip_FallAsleepDelay: + ret = 2000; + break; + case SH_Widget_Animate: + ret = true; + break; + case SH_Splitter_OpaqueResize: + ret = true; + break; + case SH_ItemView_ScrollMode: + ret = QStyleOptionViewItem::ScrollPerItem; + break; + case SH_TitleBar_ShowToolTipsOnButtons: + ret = true; + break; + case SH_Widget_Animation_Duration: + ret = styleHint(SH_Widget_Animate, opt, hret) ? 200 : 0; + break; + case SH_ComboBox_AllowWheelScrolling: + ret = true; + break; + case SH_SpinBox_ButtonsInsideFrame: + ret = true; + break; + case SH_SpinBox_StepModifier: + ret = Qt::ControlModifier; + break; + default: + ret = 0; + break; + } + + return ret; +} + +#if QT_CONFIG(imageformat_xpm) +static QPixmap cachedPixmapFromXPM(const char * const *xpm) +{ + QPixmap result; + const QString tag = QString::asprintf("xpm:0x%p", static_cast<const void*>(xpm)); + if (!QPixmapCache::find(tag, &result)) { + result = QPixmap(xpm); + QPixmapCache::insert(tag, result); + } + return result; +} + +static inline QPixmap titleBarMenuCachedPixmapFromXPM() { return cachedPixmapFromXPM(qt_menu_xpm); } +#endif + +static inline QString clearText16IconPath() +{ + return QStringLiteral(":/qt-project.org/styles/commonstyle/images/cleartext-16.png"); +} + +#if defined(Q_OS_WIN) || QT_CONFIG(imageformat_png) +static QIcon clearTextIcon(bool rtl) +{ + const QString directionalThemeName = rtl + ? QStringLiteral("edit-clear-locationbar-ltr") : QStringLiteral("edit-clear-locationbar-rtl"); + if (QIcon::hasThemeIcon(directionalThemeName)) + return QIcon::fromTheme(directionalThemeName); + const QString themeName = QStringLiteral("edit-clear"); + if (QIcon::hasThemeIcon(themeName)) + return QIcon::fromTheme(themeName); + + QIcon icon; +#ifndef QT_NO_IMAGEFORMAT_PNG + QPixmap clearText16(clearText16IconPath()); + Q_ASSERT(!clearText16.size().isEmpty()); + icon.addPixmap(clearText16); + QPixmap clearText32(QStringLiteral(":/qt-project.org/styles/commonstyle/images/cleartext-32.png")); + Q_ASSERT(!clearText32.size().isEmpty()); + icon.addPixmap(clearText32); + clearText32.setDevicePixelRatio(2); // The 32x32 pixmap can also be used for 16x16/devicePixelRatio=2 + icon.addPixmap(clearText32); +#endif // !QT_NO_IMAGEFORMAT_PNG + return icon; +} +#endif + +QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option) const +{ + const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QGuiApplication::isRightToLeft()); +#if QT_CONFIG(imageformat_png) + QPixmap pixmap; + + if (QGuiApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) { + switch (sp) { + case SP_DialogYesButton: + case SP_DialogOkButton: + pixmap = QIcon::fromTheme(QLatin1String("dialog-ok")).pixmap(16); + break; + case SP_DialogApplyButton: + pixmap = QIcon::fromTheme(QLatin1String("dialog-ok-apply")).pixmap(16); + break; + case SP_DialogDiscardButton: + pixmap = QIcon::fromTheme(QLatin1String("edit-delete")).pixmap(16); + break; + case SP_DialogCloseButton: + pixmap = QIcon::fromTheme(QLatin1String("dialog-close")).pixmap(16); + break; + case SP_DirHomeIcon: + pixmap = QIcon::fromTheme(QLatin1String("user-home")).pixmap(16); + break; + case SP_MessageBoxInformation: + pixmap = QIcon::fromTheme(QLatin1String("messagebox_info")).pixmap(16); + break; + case SP_MessageBoxWarning: + pixmap = QIcon::fromTheme(QLatin1String("messagebox_warning")).pixmap(16); + break; + case SP_MessageBoxCritical: + pixmap = QIcon::fromTheme(QLatin1String("messagebox_critical")).pixmap(16); + break; + case SP_MessageBoxQuestion: + pixmap = QIcon::fromTheme(QLatin1String("help")).pixmap(16); + break; + case SP_DialogOpenButton: + case SP_DirOpenIcon: + pixmap = QIcon::fromTheme(QLatin1String("folder-open")).pixmap(16); + break; + case SP_FileIcon: + pixmap = QIcon::fromTheme(QLatin1String("text-x-generic"), + QIcon::fromTheme(QLatin1String("empty"))).pixmap(16); + break; + case SP_DirClosedIcon: + case SP_DirIcon: + pixmap = QIcon::fromTheme(QLatin1String("folder")).pixmap(16); + break; + case SP_DriveFDIcon: + pixmap = QIcon::fromTheme(QLatin1String("media-floppy"), + QIcon::fromTheme(QLatin1String("3floppy_unmount"))).pixmap(16); + break; + case SP_ComputerIcon: + pixmap = QIcon::fromTheme(QLatin1String("computer"), + QIcon::fromTheme(QLatin1String("system"))).pixmap(16); + break; + case SP_DesktopIcon: + pixmap = QIcon::fromTheme(QLatin1String("user-desktop"), + QIcon::fromTheme(QLatin1String("desktop"))).pixmap(16); + break; + case SP_TrashIcon: + pixmap = QIcon::fromTheme(QLatin1String("user-trash"), + QIcon::fromTheme(QLatin1String("trashcan_empty"))).pixmap(16); + break; + case SP_DriveCDIcon: + case SP_DriveDVDIcon: + pixmap = QIcon::fromTheme(QLatin1String("media-optical"), + QIcon::fromTheme(QLatin1String("cdrom_unmount"))).pixmap(16); + break; + case SP_DriveHDIcon: + pixmap = QIcon::fromTheme(QLatin1String("drive-harddisk"), + QIcon::fromTheme(QLatin1String("hdd_unmount"))).pixmap(16); + break; + case SP_FileDialogToParent: + pixmap = QIcon::fromTheme(QLatin1String("go-up"), + QIcon::fromTheme(QLatin1String("up"))).pixmap(16); + break; + case SP_FileDialogNewFolder: + pixmap = QIcon::fromTheme(QLatin1String("folder_new")).pixmap(16); + break; + case SP_ArrowUp: + pixmap = QIcon::fromTheme(QLatin1String("go-up"), + QIcon::fromTheme(QLatin1String("up"))).pixmap(16); + break; + case SP_ArrowDown: + pixmap = QIcon::fromTheme(QLatin1String("go-down"), + QIcon::fromTheme(QLatin1String("down"))).pixmap(16); + break; + case SP_ArrowRight: + pixmap = QIcon::fromTheme(QLatin1String("go-next"), + QIcon::fromTheme(QLatin1String("forward"))).pixmap(16); + break; + case SP_ArrowLeft: + pixmap = QIcon::fromTheme(QLatin1String("go-previous"), + QIcon::fromTheme(QLatin1String("back"))).pixmap(16); + break; + case SP_FileDialogDetailedView: + pixmap = QIcon::fromTheme(QLatin1String("view_detailed")).pixmap(16); + break; + case SP_FileDialogListView: + pixmap = QIcon::fromTheme(QLatin1String("view_icon")).pixmap(16); + break; + case SP_BrowserReload: + pixmap = QIcon::fromTheme(QLatin1String("reload")).pixmap(16); + break; + case SP_BrowserStop: + pixmap = QIcon::fromTheme(QLatin1String("process-stop")).pixmap(16); + break; + case SP_MediaPlay: + pixmap = QIcon::fromTheme(QLatin1String("media-playback-start")).pixmap(16); + break; + case SP_MediaPause: + pixmap = QIcon::fromTheme(QLatin1String("media-playback-pause")).pixmap(16); + break; + case SP_MediaStop: + pixmap = QIcon::fromTheme(QLatin1String("media-playback-stop")).pixmap(16); + break; + case SP_MediaSeekForward: + pixmap = QIcon::fromTheme(QLatin1String("media-seek-forward")).pixmap(16); + break; + case SP_MediaSeekBackward: + pixmap = QIcon::fromTheme(QLatin1String("media-seek-backward")).pixmap(16); + break; + case SP_MediaSkipForward: + pixmap = QIcon::fromTheme(QLatin1String("media-skip-forward")).pixmap(16); + break; + case SP_MediaSkipBackward: + pixmap = QIcon::fromTheme(QLatin1String("media-skip-backward")).pixmap(16); + break; + case SP_DialogResetButton: + pixmap = QIcon::fromTheme(QLatin1String("edit-clear")).pixmap(24); + break; + case SP_DialogHelpButton: + pixmap = QIcon::fromTheme(QLatin1String("help-contents")).pixmap(24); + break; + case SP_DialogNoButton: + case SP_DialogCancelButton: + pixmap = QIcon::fromTheme(QLatin1String("dialog-cancel"), + QIcon::fromTheme(QLatin1String("process-stop"))).pixmap(24); + break; + case SP_DialogSaveButton: + pixmap = QIcon::fromTheme(QLatin1String("document-save")).pixmap(24); + break; + case SP_FileLinkIcon: + pixmap = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")).pixmap(16); + if (!pixmap.isNull()) { + QPixmap fileIcon = QIcon::fromTheme(QLatin1String("text-x-generic")).pixmap(16); + if (fileIcon.isNull()) + fileIcon = QIcon::fromTheme(QLatin1String("empty")).pixmap(16); + if (!fileIcon.isNull()) { + QPainter painter(&fileIcon); + painter.drawPixmap(0, 0, 16, 16, pixmap); + return fileIcon; + } + } + break; + case SP_DirLinkIcon: + pixmap = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")).pixmap(16); + if (!pixmap.isNull()) { + QPixmap dirIcon = QIcon::fromTheme(QLatin1String("folder")).pixmap(16); + if (!dirIcon.isNull()) { + QPainter painter(&dirIcon); + painter.drawPixmap(0, 0, 16, 16, pixmap); + return dirIcon; + } + } + break; + case SP_LineEditClearButton: + pixmap = clearTextIcon(rtl).pixmap(16); + break; + default: + break; + } + } + + if (!pixmap.isNull()) + return pixmap; +#endif // QT_CONFIG(imageformat_png) + switch (sp) { +#ifndef QT_NO_IMAGEFORMAT_XPM + case SP_ToolBarHorizontalExtensionButton: + if (rtl) { + QImage im(tb_extension_arrow_h_xpm); + im = im.convertToFormat(QImage::Format_ARGB32).mirrored(true, false); + return QPixmap::fromImage(im); + } + return cachedPixmapFromXPM(tb_extension_arrow_h_xpm); + case SP_ToolBarVerticalExtensionButton: + return cachedPixmapFromXPM(tb_extension_arrow_v_xpm); + case SP_FileDialogStart: + return cachedPixmapFromXPM(filedialog_start_xpm); + case SP_FileDialogEnd: + return cachedPixmapFromXPM(filedialog_end_xpm); +#endif +#ifndef QT_NO_IMAGEFORMAT_PNG + case SP_CommandLink: + case SP_ArrowForward: + if (rtl) + return proxy()->standardPixmap(SP_ArrowLeft, option); + return proxy()->standardPixmap(SP_ArrowRight, option); + case SP_ArrowBack: + if (rtl) + return proxy()->standardPixmap(SP_ArrowRight, option); + return proxy()->standardPixmap(SP_ArrowLeft, option); + case SP_ArrowLeft: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-16.png")); + case SP_ArrowRight: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-16.png")); + case SP_ArrowUp: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-16.png")); + case SP_ArrowDown: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-16.png")); + case SP_FileDialogToParent: + return proxy()->standardPixmap(SP_ArrowUp, option); + case SP_FileDialogNewFolder: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-16.png")); + case SP_FileDialogDetailedView: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-16.png")); + case SP_FileDialogInfoView: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-16.png")); + case SP_FileDialogContentsView: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-16.png")); + case SP_FileDialogListView: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-16.png")); + case SP_FileDialogBack: + return proxy()->standardPixmap(SP_ArrowBack, option); + case SP_DriveHDIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/harddrive-16.png")); + case SP_TrashIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-16.png")); + case SP_DriveFDIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/floppy-16.png")); + case SP_DriveNetIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/networkdrive-16.png")); + case SP_DesktopIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/desktop-16.png")); + case SP_ComputerIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/computer-16.png")); + case SP_DriveCDIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-16.png")); + case SP_DriveDVDIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-16.png")); + case SP_DirHomeIcon: + case SP_DirOpenIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-16.png")); + case SP_DirIcon: + case SP_DirClosedIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-16.png")); + case SP_DirLinkIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirlink-16.png")); + case SP_FileIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png")); + case SP_FileLinkIcon: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-16.png")); + case SP_DialogOkButton: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-16.png")); + case SP_DialogCancelButton: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-16.png")); + case SP_DialogHelpButton: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-16.png")); + case SP_DialogOpenButton: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png")); + case SP_DialogSaveButton: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-16.png")); + case SP_DialogCloseButton: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-16.png")); + case SP_DialogApplyButton: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-16.png")); + case SP_DialogResetButton: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-16.png")); + case SP_DialogDiscardButton: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-16.png")); + case SP_DialogYesButton: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-16.png")); + case SP_DialogNoButton: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-16.png")); + case SP_BrowserReload: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/refresh-24.png")); + case SP_BrowserStop: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/stop-24.png")); + case SP_MediaPlay: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-play-32.png")); + case SP_MediaPause: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-pause-32.png")); + case SP_MediaStop: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-stop-32.png")); + case SP_MediaSeekForward: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-forward-32.png")); + case SP_MediaSeekBackward: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-backward-32.png")); + case SP_MediaSkipForward: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-forward-32.png")); + case SP_MediaSkipBackward: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-backward-32.png")); + case SP_MediaVolume: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-16.png")); + case SP_MediaVolumeMuted: + return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-muted-16.png")); + case SP_LineEditClearButton: + return QPixmap(clearText16IconPath()); +#endif // QT_NO_IMAGEFORMAT_PNG + default: + break; + } + +#ifndef QT_NO_IMAGEFORMAT_XPM + switch (sp) { + case SP_TitleBarMenuButton: + return titleBarMenuCachedPixmapFromXPM(); + case SP_TitleBarShadeButton: + return cachedPixmapFromXPM(qt_shade_xpm); + case SP_TitleBarUnshadeButton: + return cachedPixmapFromXPM(qt_unshade_xpm); + case SP_TitleBarNormalButton: + return cachedPixmapFromXPM(qt_normalizeup_xpm); + case SP_TitleBarMinButton: + return cachedPixmapFromXPM(qt_minimize_xpm); + case SP_TitleBarMaxButton: + return cachedPixmapFromXPM(qt_maximize_xpm); + case SP_TitleBarCloseButton: + return cachedPixmapFromXPM(qt_close_xpm); + case SP_TitleBarContextHelpButton: + return cachedPixmapFromXPM(qt_help_xpm); + case SP_DockWidgetCloseButton: + return cachedPixmapFromXPM(dock_widget_close_xpm); + case SP_MessageBoxInformation: + return cachedPixmapFromXPM(information_xpm); + case SP_MessageBoxWarning: + return cachedPixmapFromXPM(warning_xpm); + case SP_MessageBoxCritical: + return cachedPixmapFromXPM(critical_xpm); + case SP_MessageBoxQuestion: + return cachedPixmapFromXPM(question_xpm); + default: + break; + } +#endif //QT_NO_IMAGEFORMAT_XPM + +#if !QT_CONFIG(imageformat_png) && !QT_CONFIG(imageformat_xpm) + Q_UNUSED(rtl); +#endif + + return QPixmap(); +} + +#if QT_CONFIG(imageformat_png) +static inline QString iconResourcePrefix() { return QStringLiteral(":/qt-project.org/styles/commonstyle/images/"); } +static inline QString iconPngSuffix() { return QStringLiteral(".png"); } + +static void addIconFiles(const QString &prefix, const int sizes[], size_t count, QIcon &icon) +{ + for (size_t i = 0; i < count; ++i) + icon.addFile(prefix + QString::number(sizes[i]) + iconPngSuffix()); +} + +static const int dockTitleIconSizes[] = {10, 16, 20, 32, 48, 64}; +static const int titleBarSizes[] = {16, 32, 48}; +static const int toolBarExtHSizes[] = {8, 16, 32}; +static const int toolBarExtVSizes[] = {5, 10, 20}; +#endif // imageformat_png + +/*! + \internal +*/ +QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option) const +{ + QIcon icon; + const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QGuiApplication::isRightToLeft()); + +#ifdef Q_OS_WIN + switch (standardIcon) { + case SP_DriveCDIcon: + case SP_DriveDVDIcon: + case SP_DriveNetIcon: + case SP_DriveHDIcon: + case SP_DriveFDIcon: + case SP_FileIcon: + case SP_FileLinkIcon: + case SP_DesktopIcon: + case SP_ComputerIcon: + case SP_VistaShield: + case SP_MessageBoxInformation: + case SP_MessageBoxWarning: + case SP_MessageBoxCritical: + case SP_MessageBoxQuestion: + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon); + for (int size = 16 ; size <= 32 ; size += 16) { + QPixmap pixmap = theme->standardPixmap(sp, QSizeF(size, size)); + icon.addPixmap(pixmap, QIcon::Normal); + } + } + break; + case SP_DirIcon: + case SP_DirLinkIcon: + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + QPlatformTheme::StandardPixmap spOff = static_cast<QPlatformTheme::StandardPixmap>(standardIcon); + QPlatformTheme::StandardPixmap spOn = standardIcon == SP_DirIcon ? QPlatformTheme::DirOpenIcon : + QPlatformTheme::DirLinkOpenIcon; + for (int size = 16 ; size <= 32 ; size += 16) { + QSizeF pixSize(size, size); + QPixmap pixmap = theme->standardPixmap(spOff, pixSize); + icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off); + pixmap = theme->standardPixmap(spOn, pixSize); + icon.addPixmap(pixmap, QIcon::Normal, QIcon::On); + } + } + break; + case SP_LineEditClearButton: + icon = clearTextIcon(rtl); + break; + default: + break; + } + if (!icon.isNull()) + return icon; + +#endif + + if (QGuiApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) { + switch (standardIcon) { + case SP_DirHomeIcon: + icon = QIcon::fromTheme(QLatin1String("user-home")); + break; + case SP_MessageBoxInformation: + icon = QIcon::fromTheme(QLatin1String("dialog-information")); + break; + case SP_MessageBoxWarning: + icon = QIcon::fromTheme(QLatin1String("dialog-warning")); + break; + case SP_MessageBoxCritical: + icon = QIcon::fromTheme(QLatin1String("dialog-error")); + break; + case SP_MessageBoxQuestion: + icon = QIcon::fromTheme(QLatin1String("dialog-question")); + break; + case SP_DialogOpenButton: + case SP_DirOpenIcon: + icon = QIcon::fromTheme(QLatin1String("folder-open")); + break; + case SP_DialogSaveButton: + icon = QIcon::fromTheme(QLatin1String("document-save")); + break; + case SP_DialogApplyButton: + icon = QIcon::fromTheme(QLatin1String("dialog-ok-apply")); + break; + case SP_DialogYesButton: + case SP_DialogOkButton: + icon = QIcon::fromTheme(QLatin1String("dialog-ok")); + break; + case SP_DialogDiscardButton: + icon = QIcon::fromTheme(QLatin1String("edit-delete")); + break; + case SP_DialogResetButton: + icon = QIcon::fromTheme(QLatin1String("edit-clear")); + break; + case SP_DialogHelpButton: + icon = QIcon::fromTheme(QLatin1String("help-contents")); + break; + case SP_FileIcon: + icon = QIcon::fromTheme(QLatin1String("text-x-generic")); + break; + case SP_DirClosedIcon: + case SP_DirIcon: + icon = QIcon::fromTheme(QLatin1String("folder")); + break; + case SP_DriveFDIcon: + icon = QIcon::fromTheme(QLatin1String("floppy_unmount")); + break; + case SP_ComputerIcon: + icon = QIcon::fromTheme(QLatin1String("computer"), + QIcon::fromTheme(QLatin1String("system"))); + break; + case SP_DesktopIcon: + icon = QIcon::fromTheme(QLatin1String("user-desktop")); + break; + case SP_TrashIcon: + icon = QIcon::fromTheme(QLatin1String("user-trash")); + break; + case SP_DriveCDIcon: + case SP_DriveDVDIcon: + icon = QIcon::fromTheme(QLatin1String("media-optical")); + break; + case SP_DriveHDIcon: + icon = QIcon::fromTheme(QLatin1String("drive-harddisk")); + break; + case SP_FileDialogToParent: + icon = QIcon::fromTheme(QLatin1String("go-up")); + break; + case SP_FileDialogNewFolder: + icon = QIcon::fromTheme(QLatin1String("folder-new")); + break; + case SP_ArrowUp: + icon = QIcon::fromTheme(QLatin1String("go-up")); + break; + case SP_ArrowDown: + icon = QIcon::fromTheme(QLatin1String("go-down")); + break; + case SP_ArrowRight: + icon = QIcon::fromTheme(QLatin1String("go-next")); + break; + case SP_ArrowLeft: + icon = QIcon::fromTheme(QLatin1String("go-previous")); + break; + case SP_DialogNoButton: + case SP_DialogCancelButton: + icon = QIcon::fromTheme(QLatin1String("dialog-cancel"), + QIcon::fromTheme(QLatin1String("process-stop"))); + break; + case SP_DialogCloseButton: + icon = QIcon::fromTheme(QLatin1String("window-close")); + break; + case SP_FileDialogDetailedView: + icon = QIcon::fromTheme(QLatin1String("view-list-details")); + break; + case SP_FileDialogListView: + icon = QIcon::fromTheme(QLatin1String("view-list-icons")); + break; + case SP_BrowserReload: + icon = QIcon::fromTheme(QLatin1String("view-refresh")); + break; + case SP_BrowserStop: + icon = QIcon::fromTheme(QLatin1String("process-stop")); + break; + case SP_MediaPlay: + icon = QIcon::fromTheme(QLatin1String("media-playback-start")); + break; + case SP_MediaPause: + icon = QIcon::fromTheme(QLatin1String("media-playback-pause")); + break; + case SP_MediaStop: + icon = QIcon::fromTheme(QLatin1String("media-playback-stop")); + break; + case SP_MediaSeekForward: + icon = QIcon::fromTheme(QLatin1String("media-seek-forward")); + break; + case SP_MediaSeekBackward: + icon = QIcon::fromTheme(QLatin1String("media-seek-backward")); + break; + case SP_MediaSkipForward: + icon = QIcon::fromTheme(QLatin1String("media-skip-forward")); + break; + case SP_MediaSkipBackward: + icon = QIcon::fromTheme(QLatin1String("media-skip-backward")); + break; + case SP_MediaVolume: + icon = QIcon::fromTheme(QLatin1String("audio-volume-medium")); + break; + case SP_MediaVolumeMuted: + icon = QIcon::fromTheme(QLatin1String("audio-volume-muted")); + break; + case SP_ArrowForward: + if (rtl) + return QCommonStyle::standardIcon(SP_ArrowLeft, option); + return QCommonStyle::standardIcon(SP_ArrowRight, option); + case SP_ArrowBack: + if (rtl) + return QCommonStyle::standardIcon(SP_ArrowRight, option); + return QCommonStyle::standardIcon(SP_ArrowLeft, option); + case SP_FileLinkIcon: + { + QIcon linkIcon = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")); + if (!linkIcon.isNull()) { + QIcon baseIcon = QCommonStyle::standardIcon(SP_FileIcon, option); + const QList<QSize> sizes = baseIcon.availableSizes(QIcon::Normal, QIcon::Off); + const qreal devicePixelRatio = option ? dpr(option->window) : 1.; + for (int i = 0 ; i < sizes.size() ; ++i) { + int size = sizes[i].width(); + QPixmap basePixmap = baseIcon.pixmap(QSize(size, size), devicePixelRatio); + QPixmap linkPixmap = linkIcon.pixmap(QSize(size / 2, size / 2), devicePixelRatio); + QPainter painter(&basePixmap); + painter.drawPixmap(size/2, size/2, linkPixmap); + icon.addPixmap(basePixmap); + } + } + } + break; + case SP_DirLinkIcon: + { + QIcon linkIcon = QIcon::fromTheme(QLatin1String("emblem-symbolic-link")); + if (!linkIcon.isNull()) { + QIcon baseIcon = QCommonStyle::standardIcon(SP_DirIcon, option); + const QList<QSize> sizes = baseIcon.availableSizes(QIcon::Normal, QIcon::Off); + const qreal devicePixelRatio = option ? dpr(option->window) : 1.; + for (int i = 0 ; i < sizes.size() ; ++i) { + int size = sizes[i].width(); + QPixmap basePixmap = baseIcon.pixmap(QSize(size, size), devicePixelRatio); + QPixmap linkPixmap = linkIcon.pixmap(QSize(size / 2, size / 2), devicePixelRatio); + QPainter painter(&basePixmap); + painter.drawPixmap(size/2, size/2, linkPixmap); + icon.addPixmap(basePixmap); + } + } + } + break; + default: + break; + } + } // if (QGuiApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) + + if (!icon.isNull()) + return icon; + +#if defined(Q_OS_MAC) + if (QGuiApplication::desktopSettingsAware()) { + switch (standardIcon) { + case SP_DirIcon: { + // A rather special case + QIcon closeIcon = QCommonStyle::standardIcon(SP_DirClosedIcon, option); + QIcon openIcon = QCommonStyle::standardIcon(SP_DirOpenIcon, option); + closeIcon.addPixmap(openIcon.pixmap(16, 16), QIcon::Normal, QIcon::On); + closeIcon.addPixmap(openIcon.pixmap(32, 32), QIcon::Normal, QIcon::On); + closeIcon.addPixmap(openIcon.pixmap(64, 64), QIcon::Normal, QIcon::On); + closeIcon.addPixmap(openIcon.pixmap(128, 128), QIcon::Normal, QIcon::On); + return closeIcon; + } + + case SP_TitleBarNormalButton: + case SP_TitleBarCloseButton: { + QIcon titleBarIcon; + if (standardIcon == SP_TitleBarCloseButton) { + titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/closedock-16.png")); + titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/closedock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On); + } else { + titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/dockdock-16.png")); + titleBarIcon.addFile(QLatin1String(":/qt-project.org/styles/macstyle/images/dockdock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On); + } + return titleBarIcon; + } + + case SP_MessageBoxQuestion: + case SP_MessageBoxInformation: + case SP_MessageBoxWarning: + case SP_MessageBoxCritical: + case SP_DesktopIcon: + case SP_TrashIcon: + case SP_ComputerIcon: + case SP_DriveFDIcon: + case SP_DriveHDIcon: + case SP_DriveCDIcon: + case SP_DriveDVDIcon: + case SP_DriveNetIcon: + case SP_DirOpenIcon: + case SP_DirClosedIcon: + case SP_DirLinkIcon: + case SP_FileLinkIcon: + case SP_FileIcon: + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon); + QIcon retIcon; + const QList<QSize> sizes = theme->themeHint(QPlatformTheme::IconPixmapSizes).value<QList<QSize> >(); + for (const QSize &size : sizes) { + QPixmap mainIcon; + const QString cacheKey = QLatin1String("qt_mac_constructQIconFromIconRef") + QString::number(standardIcon) + QString::number(size.width()); + if (standardIcon >= QStyle::SP_CustomBase) { + mainIcon = theme->standardPixmap(sp, QSizeF(size)); + } else if (QPixmapCache::find(cacheKey, &mainIcon) == false) { + mainIcon = theme->standardPixmap(sp, QSizeF(size)); + QPixmapCache::insert(cacheKey, mainIcon); + } + + retIcon.addPixmap(mainIcon); + } + if (!retIcon.isNull()) + return retIcon; + } + + default: + break; + } + } // if (QGuiApplication::desktopSettingsAware()) +#endif // Q_OS_MAC + + switch (standardIcon) { +#ifndef QT_NO_IMAGEFORMAT_PNG + case SP_TitleBarMinButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-min-"), + titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon); + break; + case SP_TitleBarMaxButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-max-"), + titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon); + break; + case SP_TitleBarShadeButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-shade-"), + titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon); + + break; + case SP_TitleBarUnshadeButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-unshade-"), + titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon); + break; + case SP_TitleBarContextHelpButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-contexthelp-"), + titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon); + break; + case SP_FileDialogNewFolder: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-128.png"), QSize(128, 128)); + break; + case SP_FileDialogBack: + return QCommonStyle::standardIcon(SP_ArrowBack, option); + case SP_FileDialogToParent: + return QCommonStyle::standardIcon(SP_ArrowUp, option); + case SP_FileDialogDetailedView: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewdetailed-128.png"), QSize(128, 128)); + break; + case SP_FileDialogInfoView: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/fileinfo-128.png"), QSize(128, 128)); + break; + case SP_FileDialogContentsView: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filecontents-128.png"), QSize(128, 128)); + break; + case SP_FileDialogListView: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/viewlist-128.png"), QSize(128, 128)); + break; + case SP_DialogOkButton: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-ok-128.png"), QSize(128, 128)); + break; + case SP_DialogCancelButton: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-cancel-128.png"), QSize(128, 128)); + break; + case SP_DialogHelpButton: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-help-128.png"), QSize(128, 128)); + break; + case SP_DialogOpenButton: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-open-128.png"), QSize(128, 128)); + break; + case SP_DialogSaveButton: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-save-128.png"), QSize(128, 128)); + break; + case SP_DialogCloseButton: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-close-128.png"), QSize(128, 128)); + break; + case SP_DialogApplyButton: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-apply-128.png"), QSize(128, 128)); + break; + case SP_DialogResetButton: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-clear-128.png"), QSize(128, 128)); + break; + case SP_DialogDiscardButton: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-delete-128.png"), QSize(128, 128)); + break; + case SP_DialogYesButton: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-yes-128.png"), QSize(128, 128)); + break; + case SP_DialogNoButton: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/standardbutton-no-128.png"), QSize(128, 128)); + break; + case SP_ArrowForward: + if (rtl) + return QCommonStyle::standardIcon(SP_ArrowLeft, option); + return QCommonStyle::standardIcon(SP_ArrowRight, option); + case SP_ArrowBack: + if (rtl) + return QCommonStyle::standardIcon(SP_ArrowRight, option); + return QCommonStyle::standardIcon(SP_ArrowLeft, option); + case SP_ArrowLeft: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/left-128.png"), QSize(128, 128)); + break; + case SP_ArrowRight: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/right-128.png"), QSize(128, 128)); + break; + case SP_ArrowUp: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/up-128.png"), QSize(128, 128)); + break; + case SP_ArrowDown: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/down-128.png"), QSize(128, 128)); + break; + case SP_DirHomeIcon: + case SP_DirIcon: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-16.png"), + QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-16.png"), + QSize(), QIcon::Normal, QIcon::On); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-32.png"), + QSize(32, 32), QIcon::Normal, QIcon::Off); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-32.png"), + QSize(32, 32), QIcon::Normal, QIcon::On); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dirclosed-128.png"), + QSize(128, 128), QIcon::Normal, QIcon::Off); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/diropen-128.png"), + QSize(128, 128), QIcon::Normal, QIcon::On); + break; + case SP_DriveCDIcon: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/cdr-128.png"), QSize(128, 128)); + break; + case SP_DriveDVDIcon: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/dvd-128.png"), QSize(128, 128)); + break; + case SP_FileIcon: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-128.png"), QSize(128, 128)); + break; + case SP_FileLinkIcon: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/filelink-128.png"), QSize(128, 128)); + break; + case SP_TrashIcon: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-32.png"), QSize(32, 32)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/trash-128.png"), QSize(128, 128)); + break; + case SP_BrowserReload: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/refresh-24.png"), QSize(24, 24)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/refresh-32.png"), QSize(32, 32)); + break; + case SP_BrowserStop: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/stop-24.png"), QSize(24, 24)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/stop-32.png"), QSize(32, 32)); + break; + case SP_MediaPlay: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-play-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-play-32.png"), QSize(32, 32)); + break; + case SP_MediaPause: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-pause-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-pause-32.png"), QSize(32, 32)); + break; + case SP_MediaStop: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-stop-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-stop-32.png"), QSize(32, 32)); + break; + case SP_MediaSeekForward: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-forward-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-forward-32.png"), QSize(32, 32)); + break; + case SP_MediaSeekBackward: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-backward-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-seek-backward-32.png"), QSize(32, 32)); + break; + case SP_MediaSkipForward: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-forward-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-forward-32.png"), QSize(32, 32)); + break; + case SP_MediaSkipBackward: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-backward-16.png"), QSize(16, 16)); + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-skip-backward-32.png"), QSize(32, 32)); + break; + case SP_MediaVolume: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-16.png"), QSize(16, 16)); + break; + case SP_MediaVolumeMuted: + icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/media-volume-muted-16.png"), QSize(16, 16)); + break; + case SP_TitleBarCloseButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("closedock-"), + dockTitleIconSizes, sizeof(dockTitleIconSizes)/sizeof(dockTitleIconSizes[0]), icon); + break; + case SP_TitleBarMenuButton: +# ifndef QT_NO_IMAGEFORMAT_XPM + icon.addPixmap(titleBarMenuCachedPixmapFromXPM()); +# endif + icon.addFile(QLatin1String(":/qt-project.org/qmessagebox/images/qtlogo-64.png")); + break; + case SP_TitleBarNormalButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("normalizedockup-"), + dockTitleIconSizes, sizeof(dockTitleIconSizes)/sizeof(dockTitleIconSizes[0]), icon); + break; + case SP_ToolBarHorizontalExtensionButton: { + QString prefix = iconResourcePrefix() + QStringLiteral("toolbar-ext-h-"); + if (rtl) + prefix += QStringLiteral("rtl-"); + addIconFiles(prefix, toolBarExtHSizes, sizeof(toolBarExtHSizes)/sizeof(toolBarExtHSizes[0]), icon); + } + break; + case SP_ToolBarVerticalExtensionButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("toolbar-ext-v-"), + toolBarExtVSizes, sizeof(toolBarExtVSizes)/sizeof(toolBarExtVSizes[0]), icon); + break; +#endif // QT_NO_IMAGEFORMAT_PNG + default: + icon.addPixmap(proxy()->standardPixmap(standardIcon, option)); + break; + } + return icon; +} + +static inline uint qt_intensity(uint r, uint g, uint b) +{ + // 30% red, 59% green, 11% blue + return (77 * r + 150 * g + 28 * b) / 255; +} + +/*! \reimp */ +QPixmap QCommonStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, + const QStyleOption *opt) const +{ + switch (iconMode) { + case QIcon::Disabled: { + QImage im = pixmap.toImage().convertToFormat(QImage::Format_ARGB32); + + // Create a colortable based on the background (black -> bg -> white) + QColor bg = opt->palette.color(QPalette::Disabled, QPalette::Window); + int red = bg.red(); + int green = bg.green(); + int blue = bg.blue(); + uchar reds[256], greens[256], blues[256]; + for (int i=0; i<128; ++i) { + reds[i] = uchar((red * (i<<1)) >> 8); + greens[i] = uchar((green * (i<<1)) >> 8); + blues[i] = uchar((blue * (i<<1)) >> 8); + } + for (int i=0; i<128; ++i) { + reds[i+128] = uchar(qMin(red + (i << 1), 255)); + greens[i+128] = uchar(qMin(green + (i << 1), 255)); + blues[i+128] = uchar(qMin(blue + (i << 1), 255)); + } + + int intensity = qt_intensity(red, green, blue); + const int factor = 191; + + // High intensity colors needs dark shifting in the color table, while + // low intensity colors needs light shifting. This is to increase the + // perceived contrast. + if ((red - factor > green && red - factor > blue) + || (green - factor > red && green - factor > blue) + || (blue - factor > red && blue - factor > green)) + intensity = qMin(255, intensity + 91); + else if (intensity <= 128) + intensity -= 51; + + for (int y=0; y<im.height(); ++y) { + QRgb *scanLine = (QRgb*)im.scanLine(y); + for (int x=0; x<im.width(); ++x) { + QRgb pixel = *scanLine; + // Calculate color table index, taking intensity adjustment + // and a magic offset into account. + uint ci = uint(qGray(pixel)/3 + (130 - intensity / 3)); + *scanLine = qRgba(reds[ci], greens[ci], blues[ci], qAlpha(pixel)); + ++scanLine; + } + } + + return QPixmap::fromImage(im); + } + case QIcon::Selected: { + QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied); + QColor color = opt->palette.color(QPalette::Normal, QPalette::Highlight); + color.setAlphaF(0.3f); + QPainter painter(&img); + painter.setCompositionMode(QPainter::CompositionMode_SourceAtop); + painter.fillRect(0, 0, img.width(), img.height(), color); + painter.end(); + return QPixmap::fromImage(img); } + case QIcon::Active: + return pixmap; + default: + break; + } + return pixmap; +} + +} // namespace QQC2 + +QT_END_NAMESPACE + +#include "moc_qquickcommonstyle.cpp" diff --git a/src/quicknativestyle/qstyle/qquickcommonstyle.h b/src/quicknativestyle/qstyle/qquickcommonstyle.h new file mode 100644 index 00000000000..894194a044d --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickcommonstyle.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOMMONSTYLE_H +#define QCOMMONSTYLE_H + +#include "qquickstyle.h" + +QT_BEGIN_NAMESPACE + +namespace QQC2 { + +class QCommonStylePrivate; + +class QCommonStyle: public QStyle +{ + Q_OBJECT + +public: + QCommonStyle(); + ~QCommonStyle() override; + + void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p) const override; + void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p) const override; + void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p) const override; + + QRect subElementRect(SubElement r, const QStyleOption *opt) const override; + QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc) const override; + + QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize) const override; + QFont font(ControlElement element, const QStyle::State state) const override; + QMargins ninePatchMargins(ControlElement ce, const QStyleOption *opt, const QSize &imageSize) const override; + QMargins ninePatchMargins(ComplexControl cc, const QStyleOptionComplex *opt, const QSize &imageSize) const override; + + int pixelMetric(PixelMetric m, const QStyleOption *opt = nullptr) const override; + int styleHint(StyleHint sh, const QStyleOption *opt = nullptr, QStyleHintReturn *shret = nullptr) const override; + + QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *opt = nullptr) const override; + QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt = nullptr) const override; + QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const override; + + SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt) const override; + +protected: + QCommonStyle(QCommonStylePrivate &dd); + +private: + Q_DECLARE_PRIVATE(QCommonStyle) + Q_DISABLE_COPY(QCommonStyle) +}; + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif // QCOMMONSTYLE_H diff --git a/src/quicknativestyle/qstyle/qquickcommonstyle_p.h b/src/quicknativestyle/qstyle/qquickcommonstyle_p.h new file mode 100644 index 00000000000..ba2b868928b --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickcommonstyle_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOMMONSTYLE_P_H +#define QCOMMONSTYLE_P_H + +#include "qquickcommonstyle.h" +#include "qquickstyle_p.h" +#include "qquickstyleoption.h" + +QT_BEGIN_NAMESPACE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +class QTextOption; + +namespace QQC2 { + +class QCommonStylePrivate : public QStylePrivate +{ + Q_DECLARE_PUBLIC(QCommonStyle) +public: + + ~QCommonStylePrivate() + { + delete cachedOption; + } + + QString calculateElidedText(const QString &text, const QTextOption &textOption, + const QFont &font, const QRect &textRect, const Qt::Alignment valign, + Qt::TextElideMode textElideMode, int flags, + bool lastVisibleLineShouldBeElided, QPointF *paintStartPosition) const; + void viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect) const; + void viewItemLayout(const QStyleOptionViewItem *opt, QRect *checkRect, + QRect *pixmapRect, QRect *textRect, bool sizehint) const; + QSize viewItemSize(const QStyleOptionViewItem *option, int role) const; + + mutable QRect decorationRect, displayRect, checkRect; + mutable QStyleOptionViewItem *cachedOption = nullptr; + bool isViewItemCached(const QStyleOptionViewItem &option) const { + return cachedOption + && option.index == cachedOption->index + && option.state == cachedOption->state + && option.rect == cachedOption->rect + && option.text == cachedOption->text + && option.direction == cachedOption->direction + && option.displayAlignment == cachedOption->displayAlignment + && option.decorationAlignment == cachedOption->decorationAlignment + && option.decorationPosition == cachedOption->decorationPosition + && option.decorationSize == cachedOption->decorationSize + && option.features == cachedOption->features + && option.icon.isNull() == cachedOption->icon.isNull() + && option.font == cachedOption->font + && option.viewItemPosition == cachedOption->viewItemPosition; + } + QString toolButtonElideText(const QStyleOptionToolButton *toolbutton, + const QRect &textRect, int flags) const; + + mutable QIcon tabBarcloseButtonIcon; + virtual void tabLayout(const QStyleOptionTab *opt, QRect *textRect, QRect *pixmapRect) const; +}; + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif //QCOMMONSTYLE_P_H diff --git a/src/quicknativestyle/qstyle/qquickcommonstylepixmaps_p.h b/src/quicknativestyle/qstyle/qquickcommonstylepixmaps_p.h new file mode 100644 index 00000000000..59f1afac6da --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickcommonstylepixmaps_p.h @@ -0,0 +1,532 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT_NO_IMAGEFORMAT_XPM + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +namespace QQC2 { + +static const char * const check_list_controller_xpm[] = { +"16 16 4 1", +" c None", +". c #000000000000", +"X c #FFFFFFFF0000", +"o c #C71BC30BC71B", +" ", +" ", +" .......... ", +" .XXXXXXXX. ", +" .XXXXXXXX.oo ", +" .XXXXXXXX.oo ", +" .XXXXXXXX.oo ", +" .XXXXXXXX.oo ", +" .XXXXXXXX.oo ", +" .XXXXXXXX.oo ", +" .XXXXXXXX.oo ", +" ..........oo ", +" oooooooooo ", +" oooooooooo ", +" ", +" "}; + + +static const char * const tb_extension_arrow_v_xpm[] = { + "5 8 3 1", + " c None", + ". c #000000", + "+ c none", + ".+++.", + "..+..", + "+...+", + "++.++", + ".+++.", + "..+..", + "+...+", + "++.++" +}; + +static const char * const tb_extension_arrow_h_xpm[] = { + "8 5 3 1", + " c None", + ". c #000000", + "+ c none", + "..++..++", + "+..++..+", + "++..++..", + "+..++..+", + "..++..++", +}; + +static const char * const filedialog_start_xpm[]={ + "16 15 8 1", + "a c #cec6bd", + "# c #000000", + "e c #ffff00", + "b c #999999", + "f c #cccccc", + "d c #dcdcdc", + "c c #ffffff", + ". c None", + ".....######aaaaa", + "...bb#cccc##aaaa", + "..bcc#cccc#d#aaa", + ".bcef#cccc#dd#aa", + ".bcfe#cccc#####a", + ".bcef#ccccccccc#", + "bbbbbbbbbbbbccc#", + "bccccccccccbbcc#", + "bcefefefefee#bc#", + ".bcefefefefef#c#", + ".bcfefefefefe#c#", + "..bcfefefefeeb##", + "..bbbbbbbbbbbbb#", + "...#############", + "................"}; + +static const char * const filedialog_end_xpm[]={ + "16 15 9 1", + "d c #a0a0a0", + "c c #c3c3c3", + "# c #cec6bd", + ". c #000000", + "f c #ffff00", + "e c #999999", + "g c #cccccc", + "b c #ffffff", + "a c None", + "......####aaaaaa", + ".bbbb..###aaaaaa", + ".bbbb.c.##aaaaaa", + ".bbbb....ddeeeea", + ".bbbbbbb.bbbbbe.", + ".bbbbbbb.bcfgfe.", + "eeeeeeeeeeeeefe.", + "ebbbbbbbbbbeege.", + "ebfgfgfgfgff.ee.", + "aebfgfgfgfgfg.e.", + "aebgfgfgfgfgf.e.", + "aaebgfgfgfgffe..", + "aaeeeeeeeeeeeee.", + "aaa.............", + "aaaaaaaaaaaaaaaa"}; + + +/* XPM */ +static const char * const qt_menu_xpm[] = { +"16 16 72 1", +" c None", +". c #65AF36", +"+ c #66B036", +"@ c #77B94C", +"# c #A7D28C", +"$ c #BADBA4", +"% c #A4D088", +"& c #72B646", +"* c #9ACB7A", +"= c #7FBD56", +"- c #85C05F", +"; c #F4F9F0", +"> c #FFFFFF", +", c #E5F1DC", +"' c #ECF5E7", +") c #7ABA50", +"! c #83BF5C", +"~ c #AED595", +"{ c #D7EACA", +"] c #A9D28D", +"^ c #BCDDA8", +"/ c #C4E0B1", +"( c #81BE59", +"_ c #D0E7C2", +": c #D4E9C6", +"< c #6FB542", +"[ c #6EB440", +"} c #88C162", +"| c #98CA78", +"1 c #F4F9F1", +"2 c #8FC56C", +"3 c #F1F8EC", +"4 c #E8F3E1", +"5 c #D4E9C7", +"6 c #74B748", +"7 c #80BE59", +"8 c #73B747", +"9 c #6DB43F", +"0 c #CBE4BA", +"a c #80BD58", +"b c #6DB33F", +"c c #FEFFFE", +"d c #68B138", +"e c #F9FCF7", +"f c #91C66F", +"g c #E8F3E0", +"h c #DCEDD0", +"i c #91C66E", +"j c #A3CF86", +"k c #C9E3B8", +"l c #B0D697", +"m c #E3F0DA", +"n c #95C873", +"o c #E6F2DE", +"p c #9ECD80", +"q c #BEDEAA", +"r c #C7E2B6", +"s c #79BA4F", +"t c #6EB441", +"u c #BCDCA7", +"v c #FAFCF8", +"w c #F6FAF3", +"x c #84BF5D", +"y c #EDF6E7", +"z c #FAFDF9", +"A c #88C263", +"B c #98CA77", +"C c #CDE5BE", +"D c #67B037", +"E c #D9EBCD", +"F c #6AB23C", +"G c #77B94D", +" .++++++++++++++", +".+++++++++++++++", +"+++@#$%&+++*=+++", +"++-;>,>')+!>~+++", +"++{>]+^>/(_>:~<+", +"+[>>}+|>123>456+", +"+7>>8+->>90>~+++", +"+a>>b+a>c[0>~+++", +"+de>=+f>g+0>~+++", +"++h>i+j>k+0>~+++", +"++l>mno>p+q>rst+", +"++duv>wl++xy>zA+", +"++++B>Cb++++&D++", +"+++++0zE++++++++", +"++++++FG+++++++.", +"++++++++++++++. "}; + +static const char * const qt_close_xpm[] = { +"10 10 2 1", +"# c #000000", +". c None", +"..........", +".##....##.", +"..##..##..", +"...####...", +"....##....", +"...####...", +"..##..##..", +".##....##.", +"..........", +".........."}; + +static const char * const qt_maximize_xpm[]={ +"10 10 2 1", +"# c #000000", +". c None", +"#########.", +"#########.", +"#.......#.", +"#.......#.", +"#.......#.", +"#.......#.", +"#.......#.", +"#.......#.", +"#########.", +".........."}; + +static const char * const qt_minimize_xpm[] = { +"10 10 2 1", +"# c #000000", +". c None", +"..........", +"..........", +"..........", +"..........", +"..........", +"..........", +"..........", +".#######..", +".#######..", +".........."}; + +static const char * const qt_normalizeup_xpm[] = { +"10 10 2 1", +"# c #000000", +". c None", +"...######.", +"...######.", +"...#....#.", +".######.#.", +".######.#.", +".#....###.", +".#....#...", +".#....#...", +".######...", +".........."}; + +static const char * const qt_help_xpm[] = { +"10 10 2 1", +". c None", +"# c #000000", +"..........", +"..######..", +".##....##.", +"......##..", +".....##...", +"....##....", +"....##....", +"..........", +"....##....", +".........."}; + +static const char * const qt_shade_xpm[] = { +"10 10 2 1", +"# c #000000", +". c None", +"..........", +"..........", +"..........", +"..........", +"....#.....", +"...###....", +"..#####...", +".#######..", +"..........", +".........."}; + +static const char * const qt_unshade_xpm[] = { +"10 10 2 1", +"# c #000000", +". c None", +"..........", +"..........", +"..........", +".#######..", +"..#####...", +"...###....", +"....#.....", +"..........", +"..........", +".........."}; + +static const char * const dock_widget_close_xpm[] = { +"8 8 2 1", +"# c #000000", +". c None", +"........", +".##..##.", +"..####..", +"...##...", +"..####..", +".##..##.", +"........", +"........"}; + +/* XPM */ +static const char * const information_xpm[]={ +"32 32 5 1", +". c None", +"c c #000000", +"* c #999999", +"a c #ffffff", +"b c #0000ff", +"...........********.............", +"........***aaaaaaaa***..........", +"......**aaaaaaaaaaaaaa**........", +".....*aaaaaaaaaaaaaaaaaa*.......", +"....*aaaaaaaabbbbaaaaaaaac......", +"...*aaaaaaaabbbbbbaaaaaaaac.....", +"..*aaaaaaaaabbbbbbaaaaaaaaac....", +".*aaaaaaaaaaabbbbaaaaaaaaaaac...", +".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.", +"*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +".*aaaaaaaaaaabbbbbaaaaaaaaaac***", +".*aaaaaaaaaaabbbbbaaaaaaaaaac***", +"..*aaaaaaaaaabbbbbaaaaaaaaac***.", +"...caaaaaaabbbbbbbbbaaaaaac****.", +"....caaaaaaaaaaaaaaaaaaaac****..", +".....caaaaaaaaaaaaaaaaaac****...", +"......ccaaaaaaaaaaaaaacc****....", +".......*cccaaaaaaaaccc*****.....", +"........***cccaaaac*******......", +"..........****caaac*****........", +".............*caaac**...........", +"...............caac**...........", +"................cac**...........", +".................cc**...........", +"..................***...........", +"...................**..........."}; +/* XPM */ +static const char* const warning_xpm[]={ +"32 32 4 1", +". c None", +"a c #ffff00", +"* c #000000", +"b c #999999", +".............***................", +"............*aaa*...............", +"...........*aaaaa*b.............", +"...........*aaaaa*bb............", +"..........*aaaaaaa*bb...........", +"..........*aaaaaaa*bb...........", +".........*aaaaaaaaa*bb..........", +".........*aaaaaaaaa*bb..........", +"........*aaaaaaaaaaa*bb.........", +"........*aaaa***aaaa*bb.........", +".......*aaaa*****aaaa*bb........", +".......*aaaa*****aaaa*bb........", +"......*aaaaa*****aaaaa*bb.......", +"......*aaaaa*****aaaaa*bb.......", +".....*aaaaaa*****aaaaaa*bb......", +".....*aaaaaa*****aaaaaa*bb......", +"....*aaaaaaaa***aaaaaaaa*bb.....", +"....*aaaaaaaa***aaaaaaaa*bb.....", +"...*aaaaaaaaa***aaaaaaaaa*bb....", +"...*aaaaaaaaaa*aaaaaaaaaa*bb....", +"..*aaaaaaaaaaa*aaaaaaaaaaa*bb...", +"..*aaaaaaaaaaaaaaaaaaaaaaa*bb...", +".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..", +".*aaaaaaaaaaa****aaaaaaaaaa*bb..", +"*aaaaaaaaaaaa****aaaaaaaaaaa*bb.", +"*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb", +".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb", +"..*************************bbbbb", +"....bbbbbbbbbbbbbbbbbbbbbbbbbbb.", +".....bbbbbbbbbbbbbbbbbbbbbbbbb.."}; +/* XPM */ +static const char* const critical_xpm[]={ +"32 32 4 1", +". c None", +"a c #999999", +"* c #ff0000", +"b c #ffffff", +"...........********.............", +".........************...........", +".......****************.........", +"......******************........", +".....********************a......", +"....**********************a.....", +"...************************a....", +"..*******b**********b*******a...", +"..******bbb********bbb******a...", +".******bbbbb******bbbbb******a..", +".*******bbbbb****bbbbb*******a..", +"*********bbbbb**bbbbb*********a.", +"**********bbbbbbbbbb**********a.", +"***********bbbbbbbb***********aa", +"************bbbbbb************aa", +"************bbbbbb************aa", +"***********bbbbbbbb***********aa", +"**********bbbbbbbbbb**********aa", +"*********bbbbb**bbbbb*********aa", +".*******bbbbb****bbbbb*******aa.", +".******bbbbb******bbbbb******aa.", +"..******bbb********bbb******aaa.", +"..*******b**********b*******aa..", +"...************************aaa..", +"....**********************aaa...", +"....a********************aaa....", +".....a******************aaa.....", +"......a****************aaa......", +".......aa************aaaa.......", +".........aa********aaaaa........", +"...........aaaaaaaaaaa..........", +".............aaaaaaa............"}; +/* XPM */ +static const char *const question_xpm[] = { +"32 32 5 1", +". c None", +"c c #000000", +"* c #999999", +"a c #ffffff", +"b c #0000ff", +"...........********.............", +"........***aaaaaaaa***..........", +"......**aaaaaaaaaaaaaa**........", +".....*aaaaaaaaaaaaaaaaaa*.......", +"....*aaaaaaaaaaaaaaaaaaaac......", +"...*aaaaaaaabbbbbbaaaaaaaac.....", +"..*aaaaaaaabaaabbbbaaaaaaaac....", +".*aaaaaaaabbaaaabbbbaaaaaaaac...", +".*aaaaaaaabbbbaabbbbaaaaaaaac*..", +"*aaaaaaaaabbbbaabbbbaaaaaaaaac*.", +"*aaaaaaaaaabbaabbbbaaaaaaaaaac*.", +"*aaaaaaaaaaaaabbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaaabbbaaaaaaaaaaaac**", +"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**", +"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac**", +".*aaaaaaaaaaaabbaaaaaaaaaaaac***", +".*aaaaaaaaaaabbbbaaaaaaaaaaac***", +"..*aaaaaaaaaabbbbaaaaaaaaaac***.", +"...caaaaaaaaaabbaaaaaaaaaac****.", +"....caaaaaaaaaaaaaaaaaaaac****..", +".....caaaaaaaaaaaaaaaaaac****...", +"......ccaaaaaaaaaaaaaacc****....", +".......*cccaaaaaaaaccc*****.....", +"........***cccaaaac*******......", +"..........****caaac*****........", +".............*caaac**...........", +"...............caac**...........", +"................cac**...........", +".................cc**...........", +"..................***...........", +"...................**..........."}; + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif //QT_NO_IMAGEFORMAT_XPM diff --git a/src/quicknativestyle/qstyle/qquickdrawutil.cpp b/src/quicknativestyle/qstyle/qquickdrawutil.cpp new file mode 100644 index 00000000000..d5290a7beaf --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickdrawutil.cpp @@ -0,0 +1,1145 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickdrawutil.h" + +#include "qbitmap.h" +#include "qpixmapcache.h" +#include "qpainter.h" +#include "qpalette.h" +#include <private/qpaintengineex_p.h> +#include <qvarlengtharray.h> +#include <qmath.h> +#include <private/qhexstring_p.h> + +QT_BEGIN_NAMESPACE + +namespace QQC2 { + +namespace { +class PainterStateGuard { + Q_DISABLE_COPY_MOVE(PainterStateGuard) +public: + explicit PainterStateGuard(QPainter *p) : m_painter(p) {} + ~PainterStateGuard() + { + for ( ; m_level > 0; --m_level) + m_painter->restore(); + } + + void save() + { + m_painter->save(); + ++m_level; + } + + void restore() + { + m_painter->restore(); + --m_level; + } + +private: + QPainter *m_painter; + int m_level= 0; +}; +} // namespace + +/*! + \headerfile <qdrawutil.h> + \title Drawing Utility Functions + + \sa QPainter +*/ + +/*! + \fn void qDrawShadeLine(QPainter *painter, int x1, int y1, int x2, int y2, + const QPalette &palette, bool sunken, + int lineWidth, int midLineWidth) + \relates <qdrawutil.h> + + Draws a horizontal (\a y1 == \a y2) or vertical (\a x1 == \a x2) + shaded line using the given \a painter. Note that nothing is + drawn if \a y1 != \a y2 and \a x1 != \a x2 (i.e. the line is + neither horizontal nor vertical). + + The provided \a palette specifies the shading colors (\l + {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l + {QPalette::mid()}{middle} colors). The given \a lineWidth + specifies the line width for each of the lines; it is not the + total line width. The given \a midLineWidth specifies the width of + a middle line drawn in the QPalette::mid() color. + + The line appears sunken if \a sunken is true, otherwise raised. + + \warning This function does not look at QWidget::style() or + QApplication::style(). Use the drawing functions in QStyle to + make widgets that follow the current GUI style. + + + Alternatively you can use a QFrame widget and apply the + QFrame::setFrameStyle() function to display a shaded line: + + \snippet code/src_gui_painting_qdrawutil.cpp 0 + + \sa qDrawShadeRect(), qDrawShadePanel(), QStyle +*/ + +void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2, + const QPalette &pal, bool sunken, + int lineWidth, int midLineWidth) +{ + if (Q_UNLIKELY(!p || lineWidth < 0 || midLineWidth < 0)) { + qWarning("qDrawShadeLine: Invalid parameters"); + return; + } + int tlw = lineWidth*2 + midLineWidth; // total line width + QPen oldPen = p->pen(); // save pen + if (sunken) + p->setPen(pal.color(QPalette::Dark)); + else + p->setPen(pal.light().color()); + QPolygon a; + int i; + if (y1 == y2) { // horizontal line + int y = y1 - tlw/2; + if (x1 > x2) { // swap x1 and x2 + int t = x1; + x1 = x2; + x2 = t; + } + x2--; + for (i=0; i<lineWidth; i++) { // draw top shadow + a.setPoints(3, x1+i, y+tlw-1-i, + x1+i, y+i, + x2-i, y+i); + p->drawPolyline(a); + } + if (midLineWidth > 0) { + p->setPen(pal.mid().color()); + for (i=0; i<midLineWidth; i++) // draw lines in the middle + p->drawLine(x1+lineWidth, y+lineWidth+i, + x2-lineWidth, y+lineWidth+i); + } + if (sunken) + p->setPen(pal.light().color()); + else + p->setPen(pal.dark().color()); + for (i=0; i<lineWidth; i++) { // draw bottom shadow + a.setPoints(3, x1+i, y+tlw-i-1, + x2-i, y+tlw-i-1, + x2-i, y+i+1); + p->drawPolyline(a); + } + } + else if (x1 == x2) { // vertical line + int x = x1 - tlw/2; + if (y1 > y2) { // swap y1 and y2 + int t = y1; + y1 = y2; + y2 = t; + } + y2--; + for (i=0; i<lineWidth; i++) { // draw left shadow + a.setPoints(3, x+i, y2, + x+i, y1+i, + x+tlw-1, y1+i); + p->drawPolyline(a); + } + if (midLineWidth > 0) { + p->setPen(pal.mid().color()); + for (i=0; i<midLineWidth; i++) // draw lines in the middle + p->drawLine(x+lineWidth+i, y1+lineWidth, x+lineWidth+i, y2); + } + if (sunken) + p->setPen(pal.light().color()); + else + p->setPen(pal.dark().color()); + for (i=0; i<lineWidth; i++) { // draw right shadow + a.setPoints(3, x+lineWidth, y2-i, + x+tlw-i-1, y2-i, + x+tlw-i-1, y1+lineWidth); + p->drawPolyline(a); + } + } + p->setPen(oldPen); +} + +/*! + \fn void qDrawShadeRect(QPainter *painter, int x, int y, int width, int height, + const QPalette &palette, bool sunken, + int lineWidth, int midLineWidth, + const QBrush *fill) + \relates <qdrawutil.h> + + Draws the shaded rectangle beginning at (\a x, \a y) with the + given \a width and \a height using the provided \a painter. + + The provide \a palette specifies the shading colors (\l + {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l + {QPalette::mid()}{middle} colors. The given \a lineWidth + specifies the line width for each of the lines; it is not the + total line width. The \a midLineWidth specifies the width of a + middle line drawn in the QPalette::mid() color. The rectangle's + interior is filled with the \a fill brush unless \a fill is 0. + + The rectangle appears sunken if \a sunken is true, otherwise + raised. + + \warning This function does not look at QWidget::style() or + QApplication::style(). Use the drawing functions in QStyle to make + widgets that follow the current GUI style. + + Alternatively you can use a QFrame widget and apply the + QFrame::setFrameStyle() function to display a shaded rectangle: + + \snippet code/src_gui_painting_qdrawutil.cpp 1 + + \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle +*/ + +void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, + const QPalette &pal, bool sunken, + int lineWidth, int midLineWidth, + const QBrush *fill) +{ + if (w == 0 || h == 0) + return; + if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0 || midLineWidth < 0)) { + qWarning("qDrawShadeRect: Invalid parameters"); + return; + } + + PainterStateGuard painterGuard(p); + const qreal devicePixelRatio = p->device()->devicePixelRatioF(); + if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { + painterGuard.save(); + const qreal inverseScale = qreal(1) / devicePixelRatio; + p->scale(inverseScale, inverseScale); + x = qRound(devicePixelRatio * x); + y = qRound(devicePixelRatio * y); + w = qRound(devicePixelRatio * w); + h = qRound(devicePixelRatio * h); + lineWidth = qRound(devicePixelRatio * lineWidth); + midLineWidth = qRound(devicePixelRatio * midLineWidth); + } + + QPen oldPen = p->pen(); + if (sunken) + p->setPen(pal.dark().color()); + else + p->setPen(pal.light().color()); + int x1=x, y1=y, x2=x+w-1, y2=y+h-1; + + if (lineWidth == 1 && midLineWidth == 0) {// standard shade rectangle + p->drawRect(x1, y1, w-2, h-2); + if (sunken) + p->setPen(pal.light().color()); + else + p->setPen(pal.dark().color()); + QLineF lines[4] = { QLineF(x1+1, y1+1, x2-2, y1+1), + QLineF(x1+1, y1+2, x1+1, y2-2), + QLineF(x1, y2, x2, y2), + QLineF(x2,y1, x2,y2-1) }; + p->drawLines(lines, 4); // draw bottom/right lines + } else { // more complicated + int m = lineWidth+midLineWidth; + int i, j=0, k=m; + for (i=0; i<lineWidth; i++) { // draw top shadow + QLineF lines[4] = { QLineF(x1+i, y2-i, x1+i, y1+i), + QLineF(x1+i, y1+i, x2-i, y1+i), + QLineF(x1+k, y2-k, x2-k, y2-k), + QLineF(x2-k, y2-k, x2-k, y1+k) }; + p->drawLines(lines, 4); + k++; + } + p->setPen(pal.mid().color()); + j = lineWidth*2; + for (i=0; i<midLineWidth; i++) { // draw lines in the middle + p->drawRect(x1+lineWidth+i, y1+lineWidth+i, w-j-1, h-j-1); + j += 2; + } + if (sunken) + p->setPen(pal.light().color()); + else + p->setPen(pal.dark().color()); + k = m; + for (i=0; i<lineWidth; i++) { // draw bottom shadow + QLineF lines[4] = { QLineF(x1+1+i, y2-i, x2-i, y2-i), + QLineF(x2-i, y2-i, x2-i, y1+i+1), + QLineF(x1+k, y2-k, x1+k, y1+k), + QLineF(x1+k, y1+k, x2-k, y1+k) }; + p->drawLines(lines, 4); + k++; + } + } + if (fill) { + QBrush oldBrush = p->brush(); + int tlw = lineWidth + midLineWidth; + p->setPen(Qt::NoPen); + p->setBrush(*fill); + p->drawRect(x+tlw, y+tlw, w-2*tlw, h-2*tlw); + p->setBrush(oldBrush); + } + p->setPen(oldPen); // restore pen +} + + +/*! + \fn void qDrawShadePanel(QPainter *painter, int x, int y, int width, int height, + const QPalette &palette, bool sunken, + int lineWidth, const QBrush *fill) + \relates <qdrawutil.h> + + Draws the shaded panel beginning at (\a x, \a y) with the given \a + width and \a height using the provided \a painter and the given \a + lineWidth. + + The given \a palette specifies the shading colors (\l + {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l + {QPalette::mid()}{middle} colors). The panel's interior is filled + with the \a fill brush unless \a fill is 0. + + The panel appears sunken if \a sunken is true, otherwise raised. + + \warning This function does not look at QWidget::style() or + QApplication::style(). Use the drawing functions in QStyle to make + widgets that follow the current GUI style. + + Alternatively you can use a QFrame widget and apply the + QFrame::setFrameStyle() function to display a shaded panel: + + \snippet code/src_gui_painting_qdrawutil.cpp 2 + + \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle +*/ + +void qDrawShadePanel(QPainter *p, int x, int y, int w, int h, + const QPalette &pal, bool sunken, + int lineWidth, const QBrush *fill) +{ + if (w == 0 || h == 0) + return; + if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) { + qWarning("qDrawShadePanel: Invalid parameters"); + } + + PainterStateGuard painterGuard(p); + const qreal devicePixelRatio = p->device()->devicePixelRatioF(); + if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { + painterGuard.save(); + const qreal inverseScale = qreal(1) / devicePixelRatio; + p->scale(inverseScale, inverseScale); + x = qRound(devicePixelRatio * x); + y = qRound(devicePixelRatio * y); + w = qRound(devicePixelRatio * w); + h = qRound(devicePixelRatio * h); + lineWidth = qRound(devicePixelRatio * lineWidth); + } + + QColor shade = pal.dark().color(); + QColor light = pal.light().color(); + if (fill) { + if (fill->color() == shade) + shade = pal.shadow().color(); + if (fill->color() == light) + light = pal.midlight().color(); + } + QPen oldPen = p->pen(); // save pen + QVector<QLineF> lines; + lines.reserve(2*lineWidth); + + if (sunken) + p->setPen(shade); + else + p->setPen(light); + int x1, y1, x2, y2; + int i; + x1 = x; + y1 = y2 = y; + x2 = x+w-2; + for (i=0; i<lineWidth; i++) { // top shadow + lines << QLineF(x1, y1++, x2--, y2++); + } + x2 = x1; + y1 = y+h-2; + for (i=0; i<lineWidth; i++) { // left shado + lines << QLineF(x1++, y1, x2++, y2--); + } + p->drawLines(lines); + lines.clear(); + if (sunken) + p->setPen(light); + else + p->setPen(shade); + x1 = x; + y1 = y2 = y+h-1; + x2 = x+w-1; + for (i=0; i<lineWidth; i++) { // bottom shadow + lines << QLineF(x1++, y1--, x2, y2--); + } + x1 = x2; + y1 = y; + y2 = y+h-lineWidth-1; + for (i=0; i<lineWidth; i++) { // right shadow + lines << QLineF(x1--, y1++, x2--, y2); + } + p->drawLines(lines); + if (fill) // fill with fill color + p->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill); + p->setPen(oldPen); // restore pen +} + + +/*! + \internal + This function draws a rectangle with two pixel line width. + It is called from qDrawWinButton() and qDrawWinPanel(). + + c1..c4 and fill are used: + + 1 1 1 1 1 2 + 1 3 3 3 4 2 + 1 3 F F 4 2 + 1 3 F F 4 2 + 1 4 4 4 4 2 + 2 2 2 2 2 2 +*/ + +static void qDrawWinShades(QPainter *p, + int x, int y, int w, int h, + const QColor &c1, const QColor &c2, + const QColor &c3, const QColor &c4, + const QBrush *fill) +{ + if (w < 2 || h < 2) // can't do anything with that + return; + + PainterStateGuard painterGuard(p); + const qreal devicePixelRatio = p->device()->devicePixelRatioF(); + if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { + painterGuard.save(); + const qreal inverseScale = qreal(1) / devicePixelRatio; + p->scale(inverseScale, inverseScale); + x = qRound(devicePixelRatio * x); + y = qRound(devicePixelRatio * y); + w = qRound(devicePixelRatio * w); + h = qRound(devicePixelRatio * h); + } + + QPen oldPen = p->pen(); + QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) }; + p->setPen(c1); + p->drawPolyline(a, 3); + QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) }; + p->setPen(c2); + p->drawPolyline(b, 3); + if (w > 4 && h > 4) { + QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) }; + p->setPen(c3); + p->drawPolyline(c, 3); + QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) }; + p->setPen(c4); + p->drawPolyline(d, 3); + if (fill) + p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill); + } + p->setPen(oldPen); +} + + +/*! + \fn void qDrawWinButton(QPainter *painter, int x, int y, int width, int height, + const QPalette &palette, bool sunken, + const QBrush *fill) + \relates <qdrawutil.h> + + Draws the Windows-style button specified by the given point (\a x, + \a y}, \a width and \a height using the provided \a painter with a + line width of 2 pixels. The button's interior is filled with the + \a{fill} brush unless \a fill is 0. + + The given \a palette specifies the shading colors (\l + {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l + {QPalette::mid()}{middle} colors). + + The button appears sunken if \a sunken is true, otherwise raised. + + \warning This function does not look at QWidget::style() or + QApplication::style()-> Use the drawing functions in QStyle to make + widgets that follow the current GUI style. + + \sa qDrawWinPanel(), QStyle +*/ + +void qDrawWinButton(QPainter *p, int x, int y, int w, int h, + const QPalette &pal, bool sunken, + const QBrush *fill) +{ + if (sunken) + qDrawWinShades(p, x, y, w, h, + pal.shadow().color(), pal.light().color(), pal.dark().color(), + pal.button().color(), fill); + else + qDrawWinShades(p, x, y, w, h, + pal.light().color(), pal.shadow().color(), pal.button().color(), + pal.dark().color(), fill); +} + +/*! + \fn void qDrawWinPanel(QPainter *painter, int x, int y, int width, int height, + const QPalette &palette, bool sunken, + const QBrush *fill) + \relates <qdrawutil.h> + + Draws the Windows-style panel specified by the given point(\a x, + \a y), \a width and \a height using the provided \a painter with a + line width of 2 pixels. The button's interior is filled with the + \a fill brush unless \a fill is 0. + + The given \a palette specifies the shading colors. The panel + appears sunken if \a sunken is true, otherwise raised. + + \warning This function does not look at QWidget::style() or + QApplication::style(). Use the drawing functions in QStyle to make + widgets that follow the current GUI style. + + Alternatively you can use a QFrame widget and apply the + QFrame::setFrameStyle() function to display a shaded panel: + + \snippet code/src_gui_painting_qdrawutil.cpp 3 + + \sa qDrawShadePanel(), qDrawWinButton(), QStyle +*/ + +void qDrawWinPanel(QPainter *p, int x, int y, int w, int h, + const QPalette &pal, bool sunken, + const QBrush *fill) +{ + if (sunken) + qDrawWinShades(p, x, y, w, h, + pal.dark().color(), pal.light().color(), pal.shadow().color(), + pal.midlight().color(), fill); + else + qDrawWinShades(p, x, y, w, h, + pal.light().color(), pal.shadow().color(), pal.midlight().color(), + pal.dark().color(), fill); +} + +/*! + \fn void qDrawPlainRect(QPainter *painter, int x, int y, int width, int height, const QColor &lineColor, + int lineWidth, const QBrush *fill) + \relates <qdrawutil.h> + + Draws the plain rectangle beginning at (\a x, \a y) with the given + \a width and \a height, using the specified \a painter, \a lineColor + and \a lineWidth. The rectangle's interior is filled with the \a + fill brush unless \a fill is 0. + + \warning This function does not look at QWidget::style() or + QApplication::style(). Use the drawing functions in QStyle to make + widgets that follow the current GUI style. + + Alternatively you can use a QFrame widget and apply the + QFrame::setFrameStyle() function to display a plain rectangle: + + \snippet code/src_gui_painting_qdrawutil.cpp 4 + + \sa qDrawShadeRect(), QStyle +*/ + +void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c, + int lineWidth, const QBrush *fill) +{ + if (w == 0 || h == 0) + return; + if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) { + qWarning("qDrawPlainRect: Invalid parameters"); + } + + PainterStateGuard painterGuard(p); + const qreal devicePixelRatio = p->device()->devicePixelRatioF(); + if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { + painterGuard.save(); + const qreal inverseScale = qreal(1) / devicePixelRatio; + p->scale(inverseScale, inverseScale); + x = qRound(devicePixelRatio * x); + y = qRound(devicePixelRatio * y); + w = qRound(devicePixelRatio * w); + h = qRound(devicePixelRatio * h); + lineWidth = qRound(devicePixelRatio * lineWidth); + } + + QPen oldPen = p->pen(); + QBrush oldBrush = p->brush(); + p->setPen(c); + p->setBrush(Qt::NoBrush); + for (int i=0; i<lineWidth; i++) + p->drawRect(x+i, y+i, w-i*2 - 1, h-i*2 - 1); + if (fill) { // fill with fill color + p->setPen(Qt::NoPen); + p->setBrush(*fill); + p->drawRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2); + } + p->setPen(oldPen); + p->setBrush(oldBrush); +} + +/***************************************************************************** + Overloaded functions. + *****************************************************************************/ + +/*! + \fn void qDrawShadeLine(QPainter *painter, const QPoint &p1, const QPoint &p2, + const QPalette &palette, bool sunken, int lineWidth, int midLineWidth) + \relates <qdrawutil.h> + \overload + + Draws a horizontal or vertical shaded line between \a p1 and \a p2 + using the given \a painter. Note that nothing is drawn if the line + between the points would be neither horizontal nor vertical. + + The provided \a palette specifies the shading colors (\l + {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l + {QPalette::mid()}{middle} colors). The given \a lineWidth + specifies the line width for each of the lines; it is not the + total line width. The given \a midLineWidth specifies the width of + a middle line drawn in the QPalette::mid() color. + + The line appears sunken if \a sunken is true, otherwise raised. + + \warning This function does not look at QWidget::style() or + QApplication::style(). Use the drawing functions in QStyle to + make widgets that follow the current GUI style. + + + Alternatively you can use a QFrame widget and apply the + QFrame::setFrameStyle() function to display a shaded line: + + \snippet code/src_gui_painting_qdrawutil.cpp 5 + + \sa qDrawShadeRect(), qDrawShadePanel(), QStyle +*/ + +void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2, + const QPalette &pal, bool sunken, + int lineWidth, int midLineWidth) +{ + qDrawShadeLine(p, p1.x(), p1.y(), p2.x(), p2.y(), pal, sunken, + lineWidth, midLineWidth); +} + +/*! + \fn void qDrawShadeRect(QPainter *painter, const QRect &rect, const QPalette &palette, + bool sunken, int lineWidth, int midLineWidth, const QBrush *fill) + \relates <qdrawutil.h> + \overload + + Draws the shaded rectangle specified by \a rect using the given \a painter. + + The provide \a palette specifies the shading colors (\l + {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l + {QPalette::mid()}{middle} colors. The given \a lineWidth + specifies the line width for each of the lines; it is not the + total line width. The \a midLineWidth specifies the width of a + middle line drawn in the QPalette::mid() color. The rectangle's + interior is filled with the \a fill brush unless \a fill is 0. + + The rectangle appears sunken if \a sunken is true, otherwise + raised. + + \warning This function does not look at QWidget::style() or + QApplication::style(). Use the drawing functions in QStyle to make + widgets that follow the current GUI style. + + Alternatively you can use a QFrame widget and apply the + QFrame::setFrameStyle() function to display a shaded rectangle: + + \snippet code/src_gui_painting_qdrawutil.cpp 6 + + \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle +*/ + +void qDrawShadeRect(QPainter *p, const QRect &r, + const QPalette &pal, bool sunken, + int lineWidth, int midLineWidth, + const QBrush *fill) +{ + qDrawShadeRect(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, + lineWidth, midLineWidth, fill); +} + +/*! + \fn void qDrawShadePanel(QPainter *painter, const QRect &rect, const QPalette &palette, + bool sunken, int lineWidth, const QBrush *fill) + \relates <qdrawutil.h> + \overload + + Draws the shaded panel at the rectangle specified by \a rect using the + given \a painter and the given \a lineWidth. + + The given \a palette specifies the shading colors (\l + {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l + {QPalette::mid()}{middle} colors). The panel's interior is filled + with the \a fill brush unless \a fill is 0. + + The panel appears sunken if \a sunken is true, otherwise raised. + + \warning This function does not look at QWidget::style() or + QApplication::style(). Use the drawing functions in QStyle to make + widgets that follow the current GUI style. + + Alternatively you can use a QFrame widget and apply the + QFrame::setFrameStyle() function to display a shaded panel: + + \snippet code/src_gui_painting_qdrawutil.cpp 7 + + \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle +*/ + +void qDrawShadePanel(QPainter *p, const QRect &r, + const QPalette &pal, bool sunken, + int lineWidth, const QBrush *fill) +{ + qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, + lineWidth, fill); +} + +/*! + \fn void qDrawWinButton(QPainter *painter, const QRect &rect, const QPalette &palette, + bool sunken, const QBrush *fill) + \relates <qdrawutil.h> + \overload + + Draws the Windows-style button at the rectangle specified by \a rect using + the given \a painter with a line width of 2 pixels. The button's interior + is filled with the \a{fill} brush unless \a fill is 0. + + The given \a palette specifies the shading colors (\l + {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l + {QPalette::mid()}{middle} colors). + + The button appears sunken if \a sunken is true, otherwise raised. + + \warning This function does not look at QWidget::style() or + QApplication::style()-> Use the drawing functions in QStyle to make + widgets that follow the current GUI style. + + \sa qDrawWinPanel(), QStyle +*/ + +void qDrawWinButton(QPainter *p, const QRect &r, + const QPalette &pal, bool sunken, const QBrush *fill) +{ + qDrawWinButton(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill); +} + +/*! + \fn void qDrawWinPanel(QPainter *painter, const QRect &rect, const QPalette &palette, + bool sunken, const QBrush *fill) + \overload + + Draws the Windows-style panel at the rectangle specified by \a rect using + the given \a painter with a line width of 2 pixels. The button's interior + is filled with the \a fill brush unless \a fill is 0. + + The given \a palette specifies the shading colors. The panel + appears sunken if \a sunken is true, otherwise raised. + + \warning This function does not look at QWidget::style() or + QApplication::style(). Use the drawing functions in QStyle to make + widgets that follow the current GUI style. + + Alternatively you can use a QFrame widget and apply the + QFrame::setFrameStyle() function to display a shaded panel: + + \snippet code/src_gui_painting_qdrawutil.cpp 8 + + \sa qDrawShadePanel(), qDrawWinButton(), QStyle +*/ + +void qDrawWinPanel(QPainter *p, const QRect &r, + const QPalette &pal, bool sunken, const QBrush *fill) +{ + qDrawWinPanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill); +} + +/*! + \fn void qDrawPlainRect(QPainter *painter, const QRect &rect, const QColor &lineColor, int lineWidth, const QBrush *fill) + \relates <qdrawutil.h> + \overload + + Draws the plain rectangle specified by \a rect using the given \a painter, + \a lineColor and \a lineWidth. The rectangle's interior is filled with the + \a fill brush unless \a fill is 0. + + \warning This function does not look at QWidget::style() or + QApplication::style(). Use the drawing functions in QStyle to make + widgets that follow the current GUI style. + + Alternatively you can use a QFrame widget and apply the + QFrame::setFrameStyle() function to display a plain rectangle: + + \snippet code/src_gui_painting_qdrawutil.cpp 9 + + \sa qDrawShadeRect(), QStyle +*/ + +void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &c, + int lineWidth, const QBrush *fill) +{ + qDrawPlainRect(p, r.x(), r.y(), r.width(), r.height(), c, + lineWidth, fill); +} + + +/*! + \class QTileRules + \since 4.6 + + \inmodule QtWidgets + + \brief The QTileRules class provides the rules used to draw a + pixmap or image split into nine segments. + + Spliiting is similar to \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}. + + \sa Qt::TileRule, QMargins +*/ + +/*! \fn QTileRules::QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule) + Constructs a QTileRules with the given \a horizontalRule and + \a verticalRule. + */ + +/*! \fn QTileRules::QTileRules(Qt::TileRule rule) + Constructs a QTileRules with the given \a rule used for both + the horizontal rule and the vertical rule. + */ + +/*! + \fn void qDrawBorderPixmap(QPainter *painter, const QRect &target, const QMargins &margins, const QPixmap &pixmap) + \relates <qdrawutil.h> + \since 4.6 + + \brief The qDrawBorderPixmap function is for drawing a pixmap into + the margins of a rectangle. + + Draws the given \a pixmap into the given \a target rectangle, using the + given \a painter. The pixmap will be split into nine segments and drawn + according to the \a margins structure. +*/ + +typedef QVarLengthArray<QPainter::PixmapFragment, 16> QPixmapFragmentsArray; + +/*! + \since 4.6 + + Draws the indicated \a sourceRect rectangle from the given \a pixmap into + the given \a targetRect rectangle, using the given \a painter. The pixmap + will be split into nine segments according to the given \a targetMargins + and \a sourceMargins structures. Finally, the pixmap will be drawn + according to the given \a rules. + + This function is used to draw a scaled pixmap, similar to + \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images} + + \sa Qt::TileRule, QTileRules, QMargins +*/ + +void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins, + const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins, + const QTileRules &rules +#ifndef Q_CLANG_QDOC + , QDrawBorderPixmap::DrawingHints hints +#endif + ) +{ + QPainter::PixmapFragment d; + d.opacity = 1.0; + d.rotation = 0.0; + + QPixmapFragmentsArray opaqueData; + QPixmapFragmentsArray translucentData; + + // source center + const int sourceCenterTop = sourceRect.top() + sourceMargins.top(); + const int sourceCenterLeft = sourceRect.left() + sourceMargins.left(); + const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1; + const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1; + const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft; + const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop; + // target center + const int targetCenterTop = targetRect.top() + targetMargins.top(); + const int targetCenterLeft = targetRect.left() + targetMargins.left(); + const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1; + const int targetCenterRight = targetRect.right() - targetMargins.right() + 1; + const int targetCenterWidth = targetCenterRight - targetCenterLeft; + const int targetCenterHeight = targetCenterBottom - targetCenterTop; + + QVarLengthArray<qreal, 16> xTarget; // x-coordinates of target rectangles + QVarLengthArray<qreal, 16> yTarget; // y-coordinates of target rectangles + + int columns = 3; + int rows = 3; + if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0) + columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth))); + if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0) + rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight))); + + xTarget.resize(columns + 1); + yTarget.resize(rows + 1); + + bool oldAA = painter->testRenderHint(QPainter::Antialiasing); + if (painter->paintEngine()->type() != QPaintEngine::OpenGL + && painter->paintEngine()->type() != QPaintEngine::OpenGL2 + && oldAA && painter->combinedTransform().type() != QTransform::TxNone) { + painter->setRenderHint(QPainter::Antialiasing, false); + } + + xTarget[0] = targetRect.left(); + xTarget[1] = targetCenterLeft; + xTarget[columns - 1] = targetCenterRight; + xTarget[columns] = targetRect.left() + targetRect.width(); + + yTarget[0] = targetRect.top(); + yTarget[1] = targetCenterTop; + yTarget[rows - 1] = targetCenterBottom; + yTarget[rows] = targetRect.top() + targetRect.height(); + + qreal dx = targetCenterWidth; + qreal dy = targetCenterHeight; + + switch (rules.horizontal) { + case Qt::StretchTile: + dx = targetCenterWidth; + break; + case Qt::RepeatTile: + dx = sourceCenterWidth; + break; + case Qt::RoundTile: + dx = targetCenterWidth / qreal(columns - 2); + break; + } + + for (int i = 2; i < columns - 1; ++i) + xTarget[i] = xTarget[i - 1] + dx; + + switch (rules.vertical) { + case Qt::StretchTile: + dy = targetCenterHeight; + break; + case Qt::RepeatTile: + dy = sourceCenterHeight; + break; + case Qt::RoundTile: + dy = targetCenterHeight / qreal(rows - 2); + break; + } + + for (int i = 2; i < rows - 1; ++i) + yTarget[i] = yTarget[i - 1] + dy; + + // corners + if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left + d.x = (0.5 * (xTarget[1] + xTarget[0])); + d.y = (0.5 * (yTarget[1] + yTarget[0])); + d.sourceLeft = sourceRect.left(); + d.sourceTop = sourceRect.top(); + d.width = sourceMargins.left(); + d.height = sourceMargins.top(); + d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; + d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; + if (hints & QDrawBorderPixmap::OpaqueTopLeft) + opaqueData.append(d); + else + translucentData.append(d); + } + if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right + d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); + d.y = (0.5 * (yTarget[1] + yTarget[0])); + d.sourceLeft = sourceCenterRight; + d.sourceTop = sourceRect.top(); + d.width = sourceMargins.right(); + d.height = sourceMargins.top(); + d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; + d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; + if (hints & QDrawBorderPixmap::OpaqueTopRight) + opaqueData.append(d); + else + translucentData.append(d); + } + if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left + d.x = (0.5 * (xTarget[1] + xTarget[0])); + d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1])); + d.sourceLeft = sourceRect.left(); + d.sourceTop = sourceCenterBottom; + d.width = sourceMargins.left(); + d.height = sourceMargins.bottom(); + d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; + d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; + if (hints & QDrawBorderPixmap::OpaqueBottomLeft) + opaqueData.append(d); + else + translucentData.append(d); + } + if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right + d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); + d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1])); + d.sourceLeft = sourceCenterRight; + d.sourceTop = sourceCenterBottom; + d.width = sourceMargins.right(); + d.height = sourceMargins.bottom(); + d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; + d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; + if (hints & QDrawBorderPixmap::OpaqueBottomRight) + opaqueData.append(d); + else + translucentData.append(d); + } + + // horizontal edges + if (targetCenterWidth > 0 && sourceCenterWidth > 0) { + if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top + QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData; + d.sourceLeft = sourceCenterLeft; + d.sourceTop = sourceRect.top(); + d.width = sourceCenterWidth; + d.height = sourceMargins.top(); + d.y = (0.5 * (yTarget[1] + yTarget[0])); + d.scaleX = dx / d.width; + d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; + for (int i = 1; i < columns - 1; ++i) { + d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); + data.append(d); + } + if (rules.horizontal == Qt::RepeatTile) + data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); + } + if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom + QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData; + d.sourceLeft = sourceCenterLeft; + d.sourceTop = sourceCenterBottom; + d.width = sourceCenterWidth; + d.height = sourceMargins.bottom(); + d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1])); + d.scaleX = dx / d.width; + d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; + for (int i = 1; i < columns - 1; ++i) { + d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); + data.append(d); + } + if (rules.horizontal == Qt::RepeatTile) + data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); + } + } + + // vertical edges + if (targetCenterHeight > 0 && sourceCenterHeight > 0) { + if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left + QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData; + d.sourceLeft = sourceRect.left(); + d.sourceTop = sourceCenterTop; + d.width = sourceMargins.left(); + d.height = sourceCenterHeight; + d.x = (0.5 * (xTarget[1] + xTarget[0])); + d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; + d.scaleY = dy / d.height; + for (int i = 1; i < rows - 1; ++i) { + d.y = (0.5 * (yTarget[i + 1] + yTarget[i])); + data.append(d); + } + if (rules.vertical == Qt::RepeatTile) + data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); + } + if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right + QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData; + d.sourceLeft = sourceCenterRight; + d.sourceTop = sourceCenterTop; + d.width = sourceMargins.right(); + d.height = sourceCenterHeight; + d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); + d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; + d.scaleY = dy / d.height; + for (int i = 1; i < rows - 1; ++i) { + d.y = (0.5 * (yTarget[i + 1] + yTarget[i])); + data.append(d); + } + if (rules.vertical == Qt::RepeatTile) + data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); + } + } + + // center + if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) { + QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData; + d.sourceLeft = sourceCenterLeft; + d.sourceTop = sourceCenterTop; + d.width = sourceCenterWidth; + d.height = sourceCenterHeight; + d.scaleX = dx / d.width; + d.scaleY = dy / d.height; + + qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX; + qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY; + + for (int j = 1; j < rows - 1; ++j) { + d.y = (0.5 * (yTarget[j + 1] + yTarget[j])); + for (int i = 1; i < columns - 1; ++i) { + d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); + data.append(d); + } + if (rules.horizontal == Qt::RepeatTile) + data[data.size() - 1].width = repeatWidth; + } + if (rules.vertical == Qt::RepeatTile) { + for (int i = 1; i < columns - 1; ++i) + data[data.size() - i].height = repeatHeight; + } + } + + if (opaqueData.size()) + painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint); + if (translucentData.size()) + painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap); + + if (oldAA) + painter->setRenderHint(QPainter::Antialiasing, true); +} + +} // namespace QQC2 + +QT_END_NAMESPACE diff --git a/src/quicknativestyle/qstyle/qquickdrawutil.h b/src/quicknativestyle/qstyle/qquickdrawutil.h new file mode 100644 index 00000000000..4f7a6c2ecd0 --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickdrawutil.h @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDRAWUTIL_H +#define QDRAWUTIL_H + +#include <QtCore/qnamespace.h> +#include <QtCore/qstring.h> // char*->QString conversion +#include <QtCore/qmargins.h> +#include <QtGui/qpixmap.h> + +QT_BEGIN_NAMESPACE + + +class QPainter; +class QPalette; +class QPoint; +class QColor; +class QBrush; +class QRect; + +namespace QQC2 { + +// +// Standard shade drawing +// + +void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2, + const QPalette &pal, bool sunken = true, + int lineWidth = 1, int midLineWidth = 0); + +void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2, + const QPalette &pal, bool sunken = true, + int lineWidth = 1, int midLineWidth = 0); + +void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, + const QPalette &pal, bool sunken = false, + int lineWidth = 1, int midLineWidth = 0, + const QBrush *fill = nullptr); + +void qDrawShadeRect(QPainter *p, const QRect &r, + const QPalette &pal, bool sunken = false, + int lineWidth = 1, int midLineWidth = 0, + const QBrush *fill = nullptr); + +void qDrawShadePanel(QPainter *p, int x, int y, int w, int h, + const QPalette &pal, bool sunken = false, + int lineWidth = 1, const QBrush *fill = nullptr); + +void qDrawShadePanel(QPainter *p, const QRect &r, + const QPalette &pal, bool sunken = false, + int lineWidth = 1, const QBrush *fill = nullptr); + +void qDrawWinButton(QPainter *p, int x, int y, int w, int h, + const QPalette &pal, bool sunken = false, + const QBrush *fill = nullptr); + +void qDrawWinButton(QPainter *p, const QRect &r, + const QPalette &pal, bool sunken = false, + const QBrush *fill = nullptr); + +void qDrawWinPanel(QPainter *p, int x, int y, int w, int h, + const QPalette &pal, bool sunken = false, + const QBrush *fill = nullptr); + +void qDrawWinPanel(QPainter *p, const QRect &r, + const QPalette &pal, bool sunken = false, + const QBrush *fill = nullptr); + +void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &, + int lineWidth = 1, const QBrush *fill = nullptr); + +void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &, + int lineWidth = 1, const QBrush *fill = nullptr); + + + +struct QTileRules +{ + inline QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule) + : horizontal(horizontalRule), vertical(verticalRule) {} + inline QTileRules(Qt::TileRule rule = Qt::StretchTile) + : horizontal(rule), vertical(rule) {} + Qt::TileRule horizontal; + Qt::TileRule vertical; +}; + +#ifndef Q_CLANG_QDOC +// For internal use only. +namespace QDrawBorderPixmap +{ + enum DrawingHint + { + OpaqueTopLeft = 0x0001, + OpaqueTop = 0x0002, + OpaqueTopRight = 0x0004, + OpaqueLeft = 0x0008, + OpaqueCenter = 0x0010, + OpaqueRight = 0x0020, + OpaqueBottomLeft = 0x0040, + OpaqueBottom = 0x0080, + OpaqueBottomRight = 0x0100, + OpaqueCorners = OpaqueTopLeft | OpaqueTopRight | OpaqueBottomLeft | OpaqueBottomRight, + OpaqueEdges = OpaqueTop | OpaqueLeft | OpaqueRight | OpaqueBottom, + OpaqueFrame = OpaqueCorners | OpaqueEdges, + OpaqueAll = OpaqueCenter | OpaqueFrame + }; + + Q_DECLARE_FLAGS(DrawingHints, DrawingHint) +} +#endif + +void qDrawBorderPixmap(QPainter *painter, + const QRect &targetRect, + const QMargins &targetMargins, + const QPixmap &pixmap, + const QRect &sourceRect, + const QMargins &sourceMargins, + const QTileRules &rules = QTileRules() +#ifndef Q_CLANG_QDOC + , QDrawBorderPixmap::DrawingHints hints = QDrawBorderPixmap::DrawingHints() +#endif + ); + +inline void qDrawBorderPixmap(QPainter *painter, + const QRect &target, + const QMargins &margins, + const QPixmap &pixmap) +{ + qDrawBorderPixmap(painter, target, margins, pixmap, pixmap.rect(), margins); +} + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif // QDRAWUTIL_H diff --git a/src/quicknativestyle/qstyle/qquicknativestyle.cpp b/src/quicknativestyle/qstyle/qquicknativestyle.cpp new file mode 100644 index 00000000000..7a2030e06d0 --- /dev/null +++ b/src/quicknativestyle/qstyle/qquicknativestyle.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicknativestyle.h" + +QT_BEGIN_NAMESPACE + +namespace QQC2 { + +QStyle *QQuickNativeStyle::s_style = nullptr; + +} // namespace QQC2 + +QT_END_NAMESPACE diff --git a/src/quicknativestyle/qstyle/qquicknativestyle.h b/src/quicknativestyle/qstyle/qquicknativestyle.h new file mode 100644 index 00000000000..13c313f0d89 --- /dev/null +++ b/src/quicknativestyle/qstyle/qquicknativestyle.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKNATIVESTYLE_H +#define QQUICKNATIVESTYLE_H + +#include "qquickstyle.h" + +QT_BEGIN_NAMESPACE + +namespace QQC2 { + +class QQuickNativeStyle +{ +public: + static void setStyle(QStyle *style) + { + if (s_style) + delete s_style; + s_style = style; + } + + inline static QStyle *style() + { + return s_style; + } + +private: + static QStyle *s_style; +}; + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif // QQUICKNATIVESTYLE_H diff --git a/src/quicknativestyle/qstyle/qquickstyle.cpp b/src/quicknativestyle/qstyle/qquickstyle.cpp new file mode 100644 index 00000000000..2278fb65323 --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickstyle.cpp @@ -0,0 +1,412 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyle.h" +#include "qquickstyle_p.h" +#include "qquickstyleoption.h" + +#include <QtGui/qpainter.h> +#include <QtGui/qbitmap.h> +#include <QtGui/qpixmapcache.h> +#include <QtGui/qpa/qplatformtheme.h> + +#include <QtGui/private/qguiapplication_p.h> + +#ifndef QT_NO_DEBUG +# include <QtCore/qdebug.h> +#endif + +#include <limits.h> +#include <algorithm> + +QT_BEGIN_NAMESPACE + +namespace QQC2 { + +/*! + Constructs a style object. +*/ +QStyle::QStyle() + : QObject(*new QStylePrivate) +{ + Q_D(QStyle); + d->proxyStyle = this; +} + +/*! + \internal + + Constructs a style object. +*/ +QStyle::QStyle(QStylePrivate &dd) + : QObject(dd) +{ + Q_D(QStyle); + d->proxyStyle = this; +} + +/*! + Destroys the style object. +*/ +QStyle::~QStyle() +{ +} + +/*! + \fn QRect QStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text) const + + Returns the area within the given \a rectangle in which to draw + the provided \a text according to the specified font \a metrics + and \a alignment. The \a enabled parameter indicates whether or + not the associated item is enabled. + + If the given \a rectangle is larger than the area needed to render + the \a text, the rectangle that is returned will be offset within + \a rectangle according to the specified \a alignment. For + example, if \a alignment is Qt::AlignCenter, the returned + rectangle will be centered within \a rectangle. If the given \a + rectangle is smaller than the area needed, the returned rectangle + will be the smallest rectangle large enough to render the \a text. + + \sa Qt::Alignment +*/ +QRect QStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rect, int alignment, bool enabled, + const QString &text) const +{ + QRect result; + int x, y, w, h; + rect.getRect(&x, &y, &w, &h); + if (!text.isEmpty()) { + result = metrics.boundingRect(x, y, w, h, alignment, text); + if (!enabled && proxy()->styleHint(SH_EtchDisabledText)) { + result.setWidth(result.width()+1); + result.setHeight(result.height()+1); + } + } else { + result = QRect(x, y, w, h); + } + return result; +} + +/*! + \fn QRect QStyle::itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap &pixmap) const + + Returns the area within the given \a rectangle in which to draw + the specified \a pixmap according to the defined \a alignment. +*/ +QRect QStyle::itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const +{ + QRect result; + int x, y, w, h; + rect.getRect(&x, &y, &w, &h); + + const int pixmapWidth = pixmap.width()/pixmap.devicePixelRatio(); + const int pixmapHeight = pixmap.height()/pixmap.devicePixelRatio(); + + if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter) + y += h/2 - pixmapHeight/2; + else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom) + y += h - pixmapHeight; + if ((alignment & Qt::AlignRight) == Qt::AlignRight) + x += w - pixmapWidth; + else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter) + x += w/2 - pixmapWidth/2; + else if ((alignment & Qt::AlignLeft) != Qt::AlignLeft && QGuiApplication::isRightToLeft()) + x += w - pixmapWidth; + result = QRect(x, y, pixmapWidth, pixmapHeight); + return result; +} + +/*! + \fn void QStyle::drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString& text, QPalette::ColorRole textRole) const + + Draws the given \a text in the specified \a rectangle using the + provided \a painter and \a palette. + + The text is drawn using the painter's pen, and aligned and wrapped + according to the specified \a alignment. If an explicit \a + textRole is specified, the text is drawn using the \a palette's + color for the given role. The \a enabled parameter indicates + whether or not the item is enabled; when reimplementing this + function, the \a enabled parameter should influence how the item is + drawn. + + \sa Qt::Alignment, drawItemPixmap() +*/ +void QStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal, + bool enabled, const QString& text, QPalette::ColorRole textRole) const +{ + if (text.isEmpty()) + return; + QPen savedPen; + if (textRole != QPalette::NoRole) { + savedPen = painter->pen(); + painter->setPen(QPen(pal.brush(textRole), savedPen.widthF())); + } + if (!enabled) { + if (proxy()->styleHint(SH_DitherDisabledText)) { + QRect br; + painter->drawText(rect, alignment, text, &br); + painter->fillRect(br, QBrush(painter->background().color(), Qt::Dense5Pattern)); + return; + } else if (proxy()->styleHint(SH_EtchDisabledText)) { + QPen pen = painter->pen(); + painter->setPen(pal.light().color()); + painter->drawText(rect.adjusted(1, 1, 1, 1), alignment, text); + painter->setPen(pen); + } + } + painter->drawText(rect, alignment, text); + if (textRole != QPalette::NoRole) + painter->setPen(savedPen); +} + +/*! + \fn void QStyle::drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment, + const QPixmap &pixmap) const + + Draws the given \a pixmap in the specified \a rectangle, according + to the specified \a alignment, using the provided \a painter. + + \sa drawItemText() +*/ + +void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, + const QPixmap &pixmap) const +{ + qreal scale = pixmap.devicePixelRatio(); + QRect aligned = alignedRect(QGuiApplication::layoutDirection(), QFlag(alignment), pixmap.size() / scale, rect); + QRect inter = aligned.intersected(rect); + + painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width() * scale, inter.height() *scale); +} + +/*! + \fn QRect QStyle::visualRect(Qt::LayoutDirection direction, const QRect &boundingRectangle, const QRect &logicalRectangle) + + Returns the given \a logicalRectangle converted to screen + coordinates based on the specified \a direction. The \a + boundingRectangle is used when performing the translation. + + This function is provided to support right-to-left desktops, and + is typically used in implementations of the subControlRect() + function. + + \sa QWidget::layoutDirection +*/ +QRect QStyle::visualRect(Qt::LayoutDirection direction, const QRect &boundingRect, const QRect &logicalRect) +{ + if (direction == Qt::LeftToRight) + return logicalRect; + QRect rect = logicalRect; + rect.translate(2 * (boundingRect.right() - logicalRect.right()) + + logicalRect.width() - boundingRect.width(), 0); + return rect; +} + +/*! + \fn QPoint QStyle::visualPos(Qt::LayoutDirection direction, const QRect &boundingRectangle, const QPoint &logicalPosition) + + Returns the given \a logicalPosition converted to screen + coordinates based on the specified \a direction. The \a + boundingRectangle is used when performing the translation. + + \sa QWidget::layoutDirection +*/ +QPoint QStyle::visualPos(Qt::LayoutDirection direction, const QRect &boundingRect, const QPoint &logicalPos) +{ + if (direction == Qt::LeftToRight) + return logicalPos; + return QPoint(boundingRect.right() - logicalPos.x(), logicalPos.y()); +} + +/*! + Returns a new rectangle of the specified \a size that is aligned to the given \a + rectangle according to the specified \a alignment and \a direction. + */ +QRect QStyle::alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment, const QSize &size, const QRect &rectangle) +{ + alignment = visualAlignment(direction, alignment); + int x = rectangle.x(); + int y = rectangle.y(); + int w = size.width(); + int h = size.height(); + if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter) + y += rectangle.size().height()/2 - h/2; + else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom) + y += rectangle.size().height() - h; + if ((alignment & Qt::AlignRight) == Qt::AlignRight) + x += rectangle.size().width() - w; + else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter) + x += rectangle.size().width()/2 - w/2; + return QRect(x, y, w, h); +} + +/*! + Transforms an \a alignment of Qt::AlignLeft or Qt::AlignRight + without Qt::AlignAbsolute into Qt::AlignLeft or Qt::AlignRight with + Qt::AlignAbsolute according to the layout \a direction. The other + alignment flags are left untouched. + + If no horizontal alignment was specified, the function returns the + default alignment for the given layout \a direction. + + QWidget::layoutDirection +*/ +Qt::Alignment QStyle::visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment) +{ + return QGuiApplicationPrivate::visualAlignment(direction, alignment); +} + +/*! + Converts the given \a logicalValue to a pixel position. The \a min + parameter maps to 0, \a max maps to \a span and other values are + distributed evenly in-between. + + This function can handle the entire integer range without + overflow, providing that \a span is less than 4096. + + By default, this function assumes that the maximum value is on the + right for horizontal items and on the bottom for vertical items. + Set the \a upsideDown parameter to true to reverse this behavior. + + \sa sliderValueFromPosition() +*/ + +int QStyle::sliderPositionFromValue(int min, int max, int logicalValue, int span, bool upsideDown) +{ + if (span <= 0 || logicalValue < min || max <= min) + return 0; + if (logicalValue > max) + return upsideDown ? span : min; + + uint range = max - min; + uint p = upsideDown ? max - logicalValue : logicalValue - min; + + if (range > (uint)INT_MAX/4096) { + double dpos = (double(p))/(double(range)/span); + return int(dpos); + } else if (range > (uint)span) { + return (2 * p * span + range) / (2*range); + } else { + uint div = span / range; + uint mod = span % range; + return p * div + (2 * p * mod + range) / (2 * range); + } + // equiv. to (p * span) / range + 0.5 + // no overflow because of this implicit assumption: + // span <= 4096 +} + +/*! + \fn int QStyle::sliderValueFromPosition(int min, int max, int position, int span, bool upsideDown) + + Converts the given pixel \a position to a logical value. 0 maps to + the \a min parameter, \a span maps to \a max and other values are + distributed evenly in-between. + + This function can handle the entire integer range without + overflow. + + By default, this function assumes that the maximum value is on the + right for horizontal items and on the bottom for vertical + items. Set the \a upsideDown parameter to true to reverse this + behavior. + + \sa sliderPositionFromValue() +*/ + +int QStyle::sliderValueFromPosition(int min, int max, int pos, int span, bool upsideDown) +{ + if (span <= 0 || pos <= 0) + return upsideDown ? max : min; + if (pos >= span) + return upsideDown ? min : max; + + uint range = max - min; + + if ((uint)span > range) { + int tmp = (2 * pos * range + span) / (2 * span); + return upsideDown ? max - tmp : tmp + min; + } else { + uint div = range / span; + uint mod = range % span; + int tmp = pos * div + (2 * pos * mod + span) / (2 * span); + return upsideDown ? max - tmp : tmp + min; + } + // equiv. to min + (pos*range)/span + 0.5 + // no overflow because of this implicit assumption: + // pos <= span < sqrt(INT_MAX+0.0625)+0.25 ~ sqrt(INT_MAX) +} + +/*! + Returns the style's standard palette. + + Note that on systems that support system colors, the style's + standard palette is not used. In particular, the Windows + Vista and Mac styles do not use the standard palette, but make + use of native theme engines. With these styles, you should not set + the palette with QApplication::setPalette(). + + \sa QApplication::setPalette() + */ +QPalette QStyle::standardPalette() const +{ + QColor background = QColor(0xd4, 0xd0, 0xc8); // win 2000 grey + + QColor light(background.lighter()); + QColor dark(background.darker()); + QColor mid(Qt::gray); + QPalette palette(Qt::black, background, light, dark, mid, Qt::black, Qt::white); + palette.setBrush(QPalette::Disabled, QPalette::WindowText, dark); + palette.setBrush(QPalette::Disabled, QPalette::Text, dark); + palette.setBrush(QPalette::Disabled, QPalette::ButtonText, dark); + palette.setBrush(QPalette::Disabled, QPalette::Base, background); + return palette; +} + +//Windows and KDE allow menus to cover the taskbar, while GNOME and macOS don't +bool QStylePrivate::useFullScreenForPopup() +{ + auto theme = QGuiApplicationPrivate::platformTheme(); + return theme && theme->themeHint(QPlatformTheme::UseFullScreenForPopupMenu).toBool(); +} + +} // namespace QQC2 + +QT_END_NAMESPACE + +#include "moc_qquickstyle.cpp" diff --git a/src/quicknativestyle/qstyle/qquickstyle.h b/src/quicknativestyle/qstyle/qquickstyle.h new file mode 100644 index 00000000000..38a0dcf5bd4 --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickstyle.h @@ -0,0 +1,839 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTYLE_H +#define QSTYLE_H + +#include <QtCore/qobject.h> +#include <QtCore/qrect.h> +#include <QtCore/qsize.h> +#include <QtGui/qwindow.h> +#include <QtGui/qicon.h> +#include <QtGui/qpixmap.h> +#include <QtGui/qpalette.h> + +QT_BEGIN_NAMESPACE + +class QAction; +class QDebug; +class QFontMetrics; + +namespace QQC2 { + +class QStyleHintReturn; +class QStyleOption; +class QStyleOptionComplex; +class QStylePrivate; + +class QStyle : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QStyle) + +protected: + QStyle(QStylePrivate &dd); + +public: + QStyle(); + virtual ~QStyle(); + + enum StateFlag { + State_None = 0x00000000, + State_Enabled = 0x00000001, + State_Raised = 0x00000002, + State_Sunken = 0x00000004, + State_Off = 0x00000008, + State_NoChange = 0x00000010, + State_On = 0x00000020, + State_DownArrow = 0x00000040, + State_Horizontal = 0x00000080, + State_HasFocus = 0x00000100, + State_Top = 0x00000200, + State_Bottom = 0x00000400, + State_FocusAtBorder = 0x00000800, + State_AutoRaise = 0x00001000, + State_MouseOver = 0x00002000, + State_UpArrow = 0x00004000, + State_Selected = 0x00008000, + State_Active = 0x00010000, + State_Window = 0x00020000, + State_Open = 0x00040000, + State_Children = 0x00080000, + State_Item = 0x00100000, + State_Sibling = 0x00200000, + State_Editing = 0x00400000, + State_KeyboardFocusChange = 0x00800000, +#ifdef QT_KEYPAD_NAVIGATION + State_HasEditFocus = 0x01000000, +#endif + State_ReadOnly = 0x02000000, + State_Small = 0x04000000, + State_Mini = 0x08000000 + }; + Q_ENUM(StateFlag) + Q_DECLARE_FLAGS(State, StateFlag) + + enum PrimitiveElement { + PE_Frame, + PE_FrameDefaultButton, + PE_FrameDockWidget, + PE_FrameFocusRect, + PE_FrameGroupBox, + PE_FrameLineEdit, + PE_FrameMenu, + PE_FrameStatusBarItem, + PE_FrameTabWidget, + PE_FrameWindow, + PE_FrameButtonBevel, + PE_FrameButtonTool, + PE_FrameTabBarBase, + + PE_PanelButtonCommand, + PE_PanelButtonBevel, + PE_PanelButtonTool, + PE_PanelMenuBar, + PE_PanelToolBar, + PE_PanelLineEdit, + + PE_IndicatorArrowDown, + PE_IndicatorArrowLeft, + PE_IndicatorArrowRight, + PE_IndicatorArrowUp, + PE_IndicatorBranch, + PE_IndicatorButtonDropDown, + PE_IndicatorItemViewItemCheck, + PE_IndicatorCheckBox, + PE_IndicatorDockWidgetResizeHandle, + PE_IndicatorHeaderArrow, + PE_IndicatorMenuCheckMark, + PE_IndicatorProgressChunk, + PE_IndicatorRadioButton, + PE_IndicatorSpinDown, + PE_IndicatorSpinMinus, + PE_IndicatorSpinPlus, + PE_IndicatorSpinUp, + PE_IndicatorToolBarHandle, + PE_IndicatorToolBarSeparator, + PE_PanelTipLabel, + PE_IndicatorTabTear, + PE_IndicatorTabTearLeft = PE_IndicatorTabTear, + PE_PanelScrollAreaCorner, + + PE_Widget, + + PE_IndicatorColumnViewArrow, + PE_IndicatorItemViewItemDrop, + + PE_PanelItemViewItem, + PE_PanelItemViewRow, // ### Qt 6: remove + + PE_PanelStatusBar, + + PE_IndicatorTabClose, + PE_PanelMenu, + + PE_IndicatorTabTearRight, + + // do not add any values below/greater this + PE_CustomBase = 0xf000000 + }; + Q_ENUM(PrimitiveElement) + + enum ControlElement { + CE_PushButton, + CE_PushButtonBevel, + CE_PushButtonLabel, + + CE_CheckBox, + CE_CheckBoxLabel, + + CE_RadioButton, + CE_RadioButtonLabel, + + CE_TabBarTab, + CE_TabBarTabShape, + CE_TabBarTabLabel, + + CE_ProgressBar, + CE_ProgressBarGroove, + CE_ProgressBarContents, + CE_ProgressBarLabel, + + CE_MenuItem, + CE_MenuScroller, + CE_MenuVMargin, + CE_MenuHMargin, + CE_MenuTearoff, + CE_MenuEmptyArea, + + CE_MenuBarItem, + CE_MenuBarEmptyArea, + + CE_ToolButtonLabel, + + CE_Header, + CE_HeaderSection, + CE_HeaderLabel, + + CE_ToolBoxTab, + CE_SizeGrip, + CE_Splitter, + CE_RubberBand, + CE_DockWidgetTitle, + + CE_ScrollBarAddLine, + CE_ScrollBarSubLine, + CE_ScrollBarAddPage, + CE_ScrollBarSubPage, + CE_ScrollBarSlider, + CE_ScrollBarFirst, + CE_ScrollBarLast, + + CE_FocusFrame, + CE_ComboBoxLabel, + + CE_ToolBar, + CE_ToolBoxTabShape, + CE_ToolBoxTabLabel, + CE_HeaderEmptyArea, + + CE_ColumnViewGrip, + + CE_ItemViewItem, + + CE_ShapedFrame, + + // do not add any values below/greater than this + CE_CustomBase = 0xf0000000 + }; + Q_ENUM(ControlElement) + + enum SubElement { + SE_PushButtonContents, + SE_PushButtonFocusRect, + + SE_CheckBoxIndicator, + SE_CheckBoxContents, + SE_CheckBoxFocusRect, + SE_CheckBoxClickRect, + + SE_RadioButtonIndicator, + SE_RadioButtonContents, + SE_RadioButtonFocusRect, + SE_RadioButtonClickRect, + + SE_ComboBoxFocusRect, + + SE_SliderFocusRect, + + SE_ProgressBarGroove, + SE_ProgressBarContents, + SE_ProgressBarLabel, + + SE_ToolBoxTabContents, + + SE_HeaderLabel, + SE_HeaderArrow, + + SE_TabWidgetTabBar, + SE_TabWidgetTabPane, + SE_TabWidgetTabContents, + SE_TabWidgetLeftCorner, + SE_TabWidgetRightCorner, + + SE_ItemViewItemCheckIndicator, + SE_TabBarTearIndicator, + SE_TabBarTearIndicatorLeft = SE_TabBarTearIndicator, + + SE_TreeViewDisclosureItem, + + SE_LineEditContents, + SE_FrameContents, + + SE_DockWidgetCloseButton, + SE_DockWidgetFloatButton, + SE_DockWidgetTitleBarText, + SE_DockWidgetIcon, + + SE_CheckBoxLayoutItem, + SE_ComboBoxLayoutItem, + SE_DateTimeEditLayoutItem, + SE_LabelLayoutItem, + SE_ProgressBarLayoutItem, + SE_PushButtonLayoutItem, + SE_RadioButtonLayoutItem, + SE_SliderLayoutItem, + SE_ScrollBarLayoutItem, + SE_SpinBoxLayoutItem, + SE_ToolButtonLayoutItem, + + SE_FrameLayoutItem, + SE_GroupBoxLayoutItem, + SE_TabWidgetLayoutItem, + + SE_ItemViewItemDecoration, + SE_ItemViewItemText, + SE_ItemViewItemFocusRect, + + SE_TabBarTabLeftButton, + SE_TabBarTabRightButton, + SE_TabBarTabText, + + SE_ShapedFrameContents, + + SE_ToolBarHandle, + + SE_TabBarScrollLeftButton, + SE_TabBarScrollRightButton, + SE_TabBarTearIndicatorRight, + + // do not add any values below/greater than this + SE_CustomBase = 0xf0000000 + }; + Q_ENUM(SubElement) + + enum ComplexControl { + CC_SpinBox, + CC_ComboBox, + CC_ScrollBar, + CC_Slider, + CC_ToolButton, + CC_TitleBar, + CC_Dial, + CC_GroupBox, + CC_MdiControls, + + // do not add any values below/greater than this + CC_CustomBase = 0xf0000000 + }; + Q_ENUM(ComplexControl) + + enum SubControl { + SC_None = 0x00000000, + + SC_ScrollBarAddLine = 0x00000001, + SC_ScrollBarSubLine = 0x00000002, + SC_ScrollBarAddPage = 0x00000004, + SC_ScrollBarSubPage = 0x00000008, + SC_ScrollBarFirst = 0x00000010, + SC_ScrollBarLast = 0x00000020, + SC_ScrollBarSlider = 0x00000040, + SC_ScrollBarGroove = 0x00000080, + + SC_SpinBoxUp = 0x00000001, + SC_SpinBoxDown = 0x00000002, + SC_SpinBoxFrame = 0x00000004, + SC_SpinBoxEditField = 0x00000008, + + SC_ComboBoxFrame = 0x00000001, + SC_ComboBoxEditField = 0x00000002, + SC_ComboBoxArrow = 0x00000004, + SC_ComboBoxListBoxPopup = 0x00000008, + + SC_SliderGroove = 0x00000001, + SC_SliderHandle = 0x00000002, + SC_SliderTickmarks = 0x00000004, + + SC_ToolButton = 0x00000001, + SC_ToolButtonMenu = 0x00000002, + + SC_TitleBarSysMenu = 0x00000001, + SC_TitleBarMinButton = 0x00000002, + SC_TitleBarMaxButton = 0x00000004, + SC_TitleBarCloseButton = 0x00000008, + SC_TitleBarNormalButton = 0x00000010, + SC_TitleBarShadeButton = 0x00000020, + SC_TitleBarUnshadeButton = 0x00000040, + SC_TitleBarContextHelpButton = 0x00000080, + SC_TitleBarLabel = 0x00000100, + + SC_DialGroove = 0x00000001, + SC_DialHandle = 0x00000002, + SC_DialTickmarks = 0x00000004, + + SC_GroupBoxCheckBox = 0x00000001, + SC_GroupBoxLabel = 0x00000002, + SC_GroupBoxContents = 0x00000004, + SC_GroupBoxFrame = 0x00000008, + + SC_MdiMinButton = 0x00000001, + SC_MdiNormalButton = 0x00000002, + SC_MdiCloseButton = 0x00000004, + + SC_CustomBase = 0xf0000000, + SC_All = 0xffffffff + }; + Q_ENUM(SubControl) + Q_DECLARE_FLAGS(SubControls, SubControl) + + enum PixelMetric { + PM_ButtonMargin, + PM_ButtonDefaultIndicator, + PM_MenuButtonIndicator, + PM_ButtonShiftHorizontal, + PM_ButtonShiftVertical, + + PM_DefaultFrameWidth, + PM_SpinBoxFrameWidth, + PM_ComboBoxFrameWidth, + + PM_MaximumDragDistance, + + PM_ScrollBarExtent, + PM_ScrollBarSliderMin, + + PM_SliderThickness, // total slider thickness + PM_SliderControlThickness, // thickness of the business part + PM_SliderLength, // total length of slider + PM_SliderTickmarkOffset, // + PM_SliderSpaceAvailable, // available space for slider to move + + PM_DockWidgetSeparatorExtent, + PM_DockWidgetHandleExtent, + PM_DockWidgetFrameWidth, + + PM_TabBarTabOverlap, + PM_TabBarTabHSpace, + PM_TabBarTabVSpace, + PM_TabBarBaseHeight, + PM_TabBarBaseOverlap, + + PM_ProgressBarChunkWidth, + + PM_SplitterWidth, + PM_TitleBarHeight, + + PM_MenuScrollerHeight, + PM_MenuHMargin, + PM_MenuVMargin, + PM_MenuPanelWidth, + PM_MenuTearoffHeight, + PM_MenuDesktopFrameWidth, + + PM_MenuBarPanelWidth, + PM_MenuBarItemSpacing, + PM_MenuBarVMargin, + PM_MenuBarHMargin, + + PM_IndicatorWidth, + PM_IndicatorHeight, + PM_ExclusiveIndicatorWidth, + PM_ExclusiveIndicatorHeight, + + PM_DialogButtonsSeparator, + PM_DialogButtonsButtonWidth, + PM_DialogButtonsButtonHeight, + + PM_MdiSubWindowFrameWidth, + PM_MdiSubWindowMinimizedWidth, + + PM_HeaderMargin, + PM_HeaderMarkSize, + PM_HeaderGripMargin, + PM_TabBarTabShiftHorizontal, + PM_TabBarTabShiftVertical, + PM_TabBarScrollButtonWidth, + + PM_ToolBarFrameWidth, + PM_ToolBarHandleExtent, + PM_ToolBarItemSpacing, + PM_ToolBarItemMargin, + PM_ToolBarSeparatorExtent, + PM_ToolBarExtensionExtent, + + PM_SpinBoxSliderHeight, + + PM_DefaultTopLevelMargin, + PM_DefaultChildMargin, + PM_DefaultLayoutSpacing, + + PM_ToolBarIconSize, + PM_ListViewIconSize, + PM_IconViewIconSize, + PM_SmallIconSize, + PM_LargeIconSize, + + PM_FocusFrameVMargin, + PM_FocusFrameHMargin, + + PM_ToolTipLabelFrameWidth, + PM_CheckBoxLabelSpacing, + PM_TabBarIconSize, + PM_SizeGripSize, + PM_DockWidgetTitleMargin, + PM_MessageBoxIconSize, + PM_ButtonIconSize, + + PM_DockWidgetTitleBarButtonMargin, + + PM_RadioButtonLabelSpacing, + PM_LayoutLeftMargin, + PM_LayoutTopMargin, + PM_LayoutRightMargin, + PM_LayoutBottomMargin, + PM_LayoutHorizontalSpacing, + PM_LayoutVerticalSpacing, + PM_TabBar_ScrollButtonOverlap, + + PM_TextCursorWidth, + + PM_TabCloseIndicatorWidth, + PM_TabCloseIndicatorHeight, + + PM_ScrollView_ScrollBarSpacing, + PM_ScrollView_ScrollBarOverlap, + PM_SubMenuOverlap, + PM_TreeViewIndentation, + + PM_HeaderDefaultSectionSizeHorizontal, + PM_HeaderDefaultSectionSizeVertical, + + PM_TitleBarButtonIconSize, + PM_TitleBarButtonSize, + + PM_PushButtonFocusFrameRadius, + PM_CheckBoxFocusFrameRadius, + PM_ComboBoxFocusFrameRadius, + PM_DialFocusFrameRadius, + PM_RadioButtonFocusFrameRadius, + PM_SliderFocusFrameRadius, + PM_SpinBoxFocusFrameRadius, + PM_TextAreaFocusFrameRadius, + PM_TextFieldFocusFrameRadius, + + // do not add any values below/greater than this + PM_CustomBase = 0xf0000000 + }; + Q_ENUM(PixelMetric) + + enum ContentsType { + CT_PushButton, + CT_CheckBox, + CT_RadioButton, + CT_ToolButton, + CT_ComboBox, + CT_Splitter, + CT_ProgressBar, + CT_MenuItem, + CT_MenuBarItem, + CT_MenuBar, + CT_Menu, + CT_TabBarTab, + CT_Slider, + CT_Dial, + CT_ScrollBar, + CT_LineEdit, + CT_SpinBox, + CT_SizeGrip, + CT_TabWidget, + CT_DialogButtons, + CT_HeaderSection, + CT_GroupBox, + CT_MdiControls, + CT_ItemViewItem, + CT_Frame, + // do not add any values below/greater than this + CT_CustomBase = 0xf0000000 + }; + Q_ENUM(ContentsType) + + enum RequestSoftwareInputPanel { + RSIP_OnMouseClickAndAlreadyFocused, + RSIP_OnMouseClick + }; + Q_ENUM(RequestSoftwareInputPanel) + + enum StyleHint { + SH_EtchDisabledText, + SH_DitherDisabledText, + SH_ScrollBar_MiddleClickAbsolutePosition, + SH_ScrollBar_ScrollWhenPointerLeavesControl, + SH_TabBar_SelectMouseType, + SH_TabBar_Alignment, + SH_Header_ArrowAlignment, + SH_Slider_SnapToValue, + SH_Slider_SloppyKeyEvents, + SH_ProgressDialog_CenterCancelButton, + SH_ProgressDialog_TextLabelAlignment, + SH_PrintDialog_RightAlignButtons, + SH_MainWindow_SpaceBelowMenuBar, + SH_FontDialog_SelectAssociatedText, + SH_Menu_AllowActiveAndDisabled, + SH_Menu_SpaceActivatesItem, + SH_Menu_SubMenuPopupDelay, + SH_ScrollView_FrameOnlyAroundContents, + SH_MenuBar_AltKeyNavigation, + SH_ComboBox_ListMouseTracking, + SH_Menu_MouseTracking, + SH_MenuBar_MouseTracking, + SH_ItemView_ChangeHighlightOnFocus, + SH_Widget_ShareActivation, + SH_Workspace_FillSpaceOnMaximize, + SH_ComboBox_Popup, + SH_TitleBar_NoBorder, + SH_Slider_StopMouseOverSlider, + SH_BlinkCursorWhenTextSelected, + SH_RichText_FullWidthSelection, + SH_Menu_Scrollable, + SH_GroupBox_TextLabelVerticalAlignment, + SH_GroupBox_TextLabelColor, + SH_Menu_SloppySubMenus, + SH_Table_GridLineColor, + SH_LineEdit_PasswordCharacter, + SH_DialogButtons_DefaultButton, + SH_ToolBox_SelectedPageTitleBold, + SH_TabBar_PreferNoArrows, + SH_ScrollBar_LeftClickAbsolutePosition, + SH_ListViewExpand_SelectMouseType, + SH_UnderlineShortcut, + SH_SpinBox_AnimateButton, + SH_SpinBox_KeyPressAutoRepeatRate, + SH_SpinBox_ClickAutoRepeatRate, + SH_Menu_FillScreenWithScroll, + SH_ToolTipLabel_Opacity, + SH_DrawMenuBarSeparator, + SH_TitleBar_ModifyNotification, + SH_Button_FocusPolicy, + SH_MessageBox_UseBorderForButtonSpacing, + SH_TitleBar_AutoRaise, + SH_ToolButton_PopupDelay, + SH_FocusFrame_Mask, + SH_RubberBand_Mask, + SH_WindowFrame_Mask, + SH_SpinControls_DisableOnBounds, + SH_Dial_BackgroundRole, + SH_ComboBox_LayoutDirection, + SH_ItemView_EllipsisLocation, + SH_ItemView_ShowDecorationSelected, + SH_ItemView_ActivateItemOnSingleClick, + SH_ScrollBar_ContextMenu, + SH_ScrollBar_RollBetweenButtons, + SH_Slider_AbsoluteSetButtons, + SH_Slider_PageSetButtons, + SH_Menu_KeyboardSearch, + SH_TabBar_ElideMode, + SH_DialogButtonLayout, + SH_ComboBox_PopupFrameStyle, + SH_MessageBox_TextInteractionFlags, + SH_DialogButtonBox_ButtonsHaveIcons, + SH_SpellCheckUnderlineStyle, + SH_MessageBox_CenterButtons, + SH_Menu_SelectionWrap, + SH_ItemView_MovementWithoutUpdatingSelection, + SH_ToolTip_Mask, + SH_FocusFrame_AboveWidget, + SH_TextControl_FocusIndicatorTextCharFormat, + SH_WizardStyle, + SH_ItemView_ArrowKeysNavigateIntoChildren, + SH_Menu_Mask, + SH_Menu_FlashTriggeredItem, + SH_Menu_FadeOutOnHide, + SH_SpinBox_ClickAutoRepeatThreshold, + SH_ItemView_PaintAlternatingRowColorsForEmptyArea, + SH_FormLayoutWrapPolicy, + SH_TabWidget_DefaultTabPosition, + SH_ToolBar_Movable, + SH_FormLayoutFieldGrowthPolicy, + SH_FormLayoutFormAlignment, + SH_FormLayoutLabelAlignment, + SH_ItemView_DrawDelegateFrame, + SH_TabBar_CloseButtonPosition, + SH_DockWidget_ButtonsHaveFrame, + SH_ToolButtonStyle, + SH_RequestSoftwareInputPanel, + SH_ScrollBar_Transient, + SH_Menu_SupportsSections, + SH_ToolTip_WakeUpDelay, + SH_ToolTip_FallAsleepDelay, + SH_Widget_Animate, + SH_Splitter_OpaqueResize, + // Whether we should use a native popup. + // Only supported for non-editable combo boxes on Mac OS X so far. + SH_ComboBox_UseNativePopup, + SH_LineEdit_PasswordMaskDelay, + SH_TabBar_ChangeCurrentDelay, + SH_Menu_SubMenuUniDirection, + SH_Menu_SubMenuUniDirectionFailCount, + SH_Menu_SubMenuSloppySelectOtherActions, + SH_Menu_SubMenuSloppyCloseTimeout, + SH_Menu_SubMenuResetWhenReenteringParent, + SH_Menu_SubMenuDontStartSloppyOnLeave, + SH_ItemView_ScrollMode, + SH_TitleBar_ShowToolTipsOnButtons, + SH_Widget_Animation_Duration, + SH_ComboBox_AllowWheelScrolling, + SH_SpinBox_ButtonsInsideFrame, + SH_SpinBox_StepModifier, + // Add new style hint values here + + SH_CustomBase = 0xf0000000 + }; + Q_ENUM(StyleHint) + + enum StandardPixmap { + SP_TitleBarMenuButton, + SP_TitleBarMinButton, + SP_TitleBarMaxButton, + SP_TitleBarCloseButton, + SP_TitleBarNormalButton, + SP_TitleBarShadeButton, + SP_TitleBarUnshadeButton, + SP_TitleBarContextHelpButton, + SP_DockWidgetCloseButton, + SP_MessageBoxInformation, + SP_MessageBoxWarning, + SP_MessageBoxCritical, + SP_MessageBoxQuestion, + SP_DesktopIcon, + SP_TrashIcon, + SP_ComputerIcon, + SP_DriveFDIcon, + SP_DriveHDIcon, + SP_DriveCDIcon, + SP_DriveDVDIcon, + SP_DriveNetIcon, + SP_DirOpenIcon, + SP_DirClosedIcon, + SP_DirLinkIcon, + SP_DirLinkOpenIcon, + SP_FileIcon, + SP_FileLinkIcon, + SP_ToolBarHorizontalExtensionButton, + SP_ToolBarVerticalExtensionButton, + SP_FileDialogStart, + SP_FileDialogEnd, + SP_FileDialogToParent, + SP_FileDialogNewFolder, + SP_FileDialogDetailedView, + SP_FileDialogInfoView, + SP_FileDialogContentsView, + SP_FileDialogListView, + SP_FileDialogBack, + SP_DirIcon, + SP_DialogOkButton, + SP_DialogCancelButton, + SP_DialogHelpButton, + SP_DialogOpenButton, + SP_DialogSaveButton, + SP_DialogCloseButton, + SP_DialogApplyButton, + SP_DialogResetButton, + SP_DialogDiscardButton, + SP_DialogYesButton, + SP_DialogNoButton, + SP_ArrowUp, + SP_ArrowDown, + SP_ArrowLeft, + SP_ArrowRight, + SP_ArrowBack, + SP_ArrowForward, + SP_DirHomeIcon, + SP_CommandLink, + SP_VistaShield, + SP_BrowserReload, + SP_BrowserStop, + SP_MediaPlay, + SP_MediaStop, + SP_MediaPause, + SP_MediaSkipForward, + SP_MediaSkipBackward, + SP_MediaSeekForward, + SP_MediaSeekBackward, + SP_MediaVolume, + SP_MediaVolumeMuted, + SP_LineEditClearButton, + SP_DialogYesToAllButton, + SP_DialogNoToAllButton, + SP_DialogSaveAllButton, + SP_DialogAbortButton, + SP_DialogRetryButton, + SP_DialogIgnoreButton, + SP_RestoreDefaultsButton, + // do not add any values below/greater than this + SP_CustomBase = 0xf0000000 + }; + Q_ENUM(StandardPixmap) + + virtual QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const; + virtual QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const; + virtual QRect subElementRect(SubElement subElement, const QStyleOption *option) const = 0; + virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc) const = 0; + + virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize) const = 0; + virtual QFont font(ControlElement element, const QStyle::State state) const = 0; + virtual QMargins ninePatchMargins(ControlElement ce, const QStyleOption *opt, const QSize &imageSize) const = 0; + virtual QMargins ninePatchMargins(ComplexControl cc, const QStyleOptionComplex *opt, const QSize &imageSize) const = 0; + + virtual SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt) const = 0; + + virtual int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr) const = 0; + virtual int styleHint(StyleHint stylehint, const QStyleOption *opt = nullptr, QStyleHintReturn* returnData = nullptr) const = 0; + + virtual void drawItemText(QPainter *painter, const QRect &rect, + int flags, const QPalette &pal, bool enabled, + const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const; + virtual void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const; + virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p) const = 0; + virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p) const = 0; + virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p) const = 0; + + virtual QPalette standardPalette() const; + virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt = nullptr) const = 0; + virtual QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr) const = 0; + virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const = 0; + + static QRect visualRect(Qt::LayoutDirection direction, const QRect &boundingRect, const QRect &logicalRect); + static QPoint visualPos(Qt::LayoutDirection direction, const QRect &boundingRect, const QPoint &logicalPos); + static int sliderPositionFromValue(int min, int max, int val, int space, bool upsideDown = false); + static int sliderValueFromPosition(int min, int max, int pos, int space, bool upsideDown = false); + static Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment); + static QRect alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment, const QSize &size, const QRect &rectangle); + + // TODO: Remove the concept of proxy (but keep it for now until everything builds) + const QStyle *proxy() const { return this; } + +private: + Q_DISABLE_COPY(QStyle) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::State) +Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::SubControls) + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif // QSTYLE_H diff --git a/src/quicknativestyle/qstyle/qquickstyle_p.h b/src/quicknativestyle/qstyle/qquickstyle_p.h new file mode 100644 index 00000000000..46f5374099d --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickstyle_p.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTYLE_P_H +#define QSTYLE_P_H + +#include "qquickstyle.h" + +#include <QtCore/private/qobject_p.h> +#include <QtGui/qguiapplication.h> + +QT_BEGIN_NAMESPACE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qstyle_*.cpp. This header file may change from version to version +// without notice, or even be removed. +// +// We mean it. +// + +// Private class + +namespace QQC2 { + +class QStylePrivate: public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QStyle) + +public: + static bool useFullScreenForPopup(); + mutable int layoutSpacingIndex = -1; + QStyle *proxyStyle; +}; + +inline QImage styleCacheImage(const QSize &size) +{ + const qreal pixelRatio = qApp->devicePixelRatio(); + QImage cacheImage = QImage(size * pixelRatio, QImage::Format_ARGB32_Premultiplied); + cacheImage.setDevicePixelRatio(pixelRatio); + return cacheImage; +} + +inline QPixmap styleCachePixmap(const QSize &size) +{ + const qreal pixelRatio = qApp->devicePixelRatio(); + QPixmap cachePixmap = QPixmap(size * pixelRatio); + cachePixmap.setDevicePixelRatio(pixelRatio); + return cachePixmap; +} + +#define BEGIN_STYLE_PIXMAPCACHE(a) \ + QRect rect = option->rect; \ + QPixmap internalPixmapCache; \ + QImage imageCache; \ + QPainter *p = painter; \ + QString unique = QStyleHelper::uniqueName((a), option, option->rect.size()); \ + int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \ + bool doPixmapCache = (!option->rect.isEmpty()) \ + && ((txType <= QTransform::TxTranslate) || (painter->deviceTransform().type() == QTransform::TxScale)); \ + if (doPixmapCache && QPixmapCache::find(unique, &internalPixmapCache)) { \ + painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \ + } else { \ + if (doPixmapCache) { \ + rect.setRect(0, 0, option->rect.width(), option->rect.height()); \ + imageCache = styleCacheImage(option->rect.size()); \ + imageCache.fill(0); \ + p = new QPainter(&imageCache); \ + } + +#define END_STYLE_PIXMAPCACHE \ + if (doPixmapCache) { \ + p->end(); \ + delete p; \ + internalPixmapCache = QPixmap::fromImage(imageCache); \ + painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \ + QPixmapCache::insert(unique, internalPixmapCache); \ + } \ + } + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif //QSTYLE_P_H diff --git a/src/quicknativestyle/qstyle/qquickstylehelper.cpp b/src/quicknativestyle/qstyle/qquickstylehelper.cpp new file mode 100644 index 00000000000..fdc60b64685 --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickstylehelper.cpp @@ -0,0 +1,439 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstylehelper_p.h" +#include "qquickstyleoption.h" +#include "qquickstyle_p.h" + +#include <QtCore/qmath.h> +#include <QtGui/qpainter.h> +#include <QtGui/qpixmapcache.h> +#include <QtGui/qwindow.h> +#include <QtGui/private/qhighdpiscaling_p.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/private/qmath_p.h> +#include <QtGui/private/qhexstring_p.h> + +#include <qmetaobject.h> +#include <qstringbuilder.h> + +QT_BEGIN_NAMESPACE + +Q_GUI_EXPORT int qt_defaultDpiX(); + +namespace QQC2 { + +namespace QStyleHelper { + +QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size) +{ + const QStyleOptionComplex *complexOption = qstyleoption_cast<const QStyleOptionComplex *>(option); + QString tmp = key % HexString<uint>(option->state) + % HexString<uint>(option->direction) + % HexString<uint>(complexOption ? uint(complexOption->activeSubControls) : 0u) + % HexString<quint64>(option->palette.cacheKey()) + % HexString<uint>(size.width()) + % HexString<uint>(size.height()); + + if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { + tmp = tmp % HexString<uint>(spinBox->buttonSymbols) + % HexString<uint>(spinBox->stepEnabled) + % QLatin1Char(spinBox->frame ? '1' : '0'); ; + } + + return tmp; +} + +#ifdef Q_OS_DARWIN +static const qreal qstyleBaseDpi = 72; +#else +static const qreal qstyleBaseDpi = 96; +#endif + +qreal dpi(const QStyleOption *option) +{ +#ifndef Q_OS_DARWIN + // Prioritize the application override, except for on macOS where + // we have historically not supported the AA_Use96Dpi flag. + if (QCoreApplication::testAttribute(Qt::AA_Use96Dpi)) + return 96; +#endif + + // Expect that QStyleOption::QFontMetrics::QFont has the correct DPI set + if (option) + return option->fontMetrics.fontDpi(); + + return qstyleBaseDpi; +} + +qreal dpiScaled(qreal value, qreal dpi) +{ + return value * dpi / qstyleBaseDpi; +} + +qreal dpiScaled(qreal value, const QPaintDevice *device) +{ + return dpiScaled(value, device->logicalDpiX()); +} + +qreal dpiScaled(qreal value, const QStyleOption *option) +{ + return dpiScaled(value, dpi(option)); +} + +#if QT_CONFIG(accessibility) +bool isInstanceOf(QObject *obj, QAccessible::Role role) +{ + bool match = false; + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(obj); + match = iface && iface->role() == role; + return match; +} + +// Searches for an ancestor of a particular accessible role +bool hasAncestor(QObject *obj, QAccessible::Role role) +{ + bool found = false; + QObject *parent = obj ? obj->parent() : nullptr; + while (parent && !found) { + if (isInstanceOf(parent, role)) + found = true; + parent = parent->parent(); + } + return found; +} +#endif + +int calcBigLineSize(int radius) +{ + int bigLineSize = radius / 6; + if (bigLineSize < 4) + bigLineSize = 4; + if (bigLineSize > radius / 2) + bigLineSize = radius / 2; + return bigLineSize; +} + +static QPointF calcRadialPos(const QStyleOptionSlider *dial, qreal offset) +{ + const int width = dial->rect.width(); + const int height = dial->rect.height(); + const int r = qMin(width, height) / 2; + const int currentSliderPosition = dial->upsideDown ? dial->sliderPosition : (dial->maximum - dial->sliderPosition); + qreal a = 0; + if (dial->maximum == dial->minimum) + a = Q_PI / 2; + else if (dial->dialWrapping) + a = Q_PI * 3 / 2 - (currentSliderPosition - dial->minimum) * 2 * Q_PI + / (dial->maximum - dial->minimum); + else + a = (Q_PI * 8 - (currentSliderPosition - dial->minimum) * 10 * Q_PI + / (dial->maximum - dial->minimum)) / 6; + qreal xc = width / 2.0; + qreal yc = height / 2.0; + qreal len = r - QStyleHelper::calcBigLineSize(r) - 3; + qreal back = offset * len; + QPointF pos(QPointF(xc + back * qCos(a), yc - back * qSin(a))); + return pos; +} + +qreal angle(const QPointF &p1, const QPointF &p2) +{ + static const qreal rad_factor = 180 / Q_PI; + qreal _angle = 0; + + if (p1.x() == p2.x()) { + if (p1.y() < p2.y()) + _angle = 270; + else + _angle = 90; + } else { + qreal x1, x2, y1, y2; + + if (p1.x() <= p2.x()) { + x1 = p1.x(); y1 = p1.y(); + x2 = p2.x(); y2 = p2.y(); + } else { + x2 = p1.x(); y2 = p1.y(); + x1 = p2.x(); y1 = p2.y(); + } + + qreal m = -(y2 - y1) / (x2 - x1); + _angle = qAtan(m) * rad_factor; + + if (p1.x() < p2.x()) + _angle = 180 - _angle; + else + _angle = -_angle; + } + return _angle; +} + +QPolygonF calcLines(const QStyleOptionSlider *dial) +{ + QPolygonF poly; + int width = dial->rect.width(); + int height = dial->rect.height(); + qreal r = qMin(width, height) / 2; + int bigLineSize = calcBigLineSize(int(r)); + + qreal xc = width / 2 + 0.5; + qreal yc = height / 2 + 0.5; + const int ns = dial->tickInterval; + if (!ns) // Invalid values may be set by Qt Designer. + return poly; + int notches = (dial->maximum + ns - 1 - dial->minimum) / ns; + if (notches <= 0) + return poly; + if (dial->maximum < dial->minimum || dial->maximum - dial->minimum > 1000) { + int maximum = dial->minimum + 1000; + notches = (maximum + ns - 1 - dial->minimum) / ns; + } + + poly.resize(2 + 2 * notches); + int smallLineSize = bigLineSize / 2; + for (int i = 0; i <= notches; ++i) { + qreal angle = dial->dialWrapping ? Q_PI * 3 / 2 - i * 2 * Q_PI / notches + : (Q_PI * 8 - i * 10 * Q_PI / notches) / 6; + qreal s = qSin(angle); + qreal c = qCos(angle); + if (i == 0 || (((ns * i) % (dial->pageStep ? dial->pageStep : 1)) == 0)) { + poly[2 * i] = QPointF(xc + (r - bigLineSize) * c, + yc - (r - bigLineSize) * s); + poly[2 * i + 1] = QPointF(xc + r * c, yc - r * s); + } else { + poly[2 * i] = QPointF(xc + (r - 1 - smallLineSize) * c, + yc - (r - 1 - smallLineSize) * s); + poly[2 * i + 1] = QPointF(xc + (r - 1) * c, yc -(r - 1) * s); + } + } + return poly; +} + +// This will draw a nice and shiny QDial for us. We don't want +// all the shinyness in QWindowsStyle, hence we place it here + +void drawDial(const QStyleOptionSlider *option, QPainter *painter) +{ + QPalette pal = option->palette; + QColor buttonColor = pal.button().color(); + const int width = option->rect.width(); + const int height = option->rect.height(); + const bool enabled = option->state & QStyle::State_Enabled; + qreal r = qMin(width, height) / 2; + r -= r/50; + const qreal penSize = r/20.0; + + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + + // Draw notches + if (option->subControls & QStyle::SC_DialTickmarks) { + painter->setPen(option->palette.dark().color().darker(120)); + painter->drawLines(QStyleHelper::calcLines(option)); + } + + // setting color before BEGIN_STYLE_PIXMAPCACHE since + // otherwise it is not set when the image is in the cache + buttonColor.setHsv(buttonColor .hue(), + qMin(140, buttonColor .saturation()), + qMax(180, buttonColor.value())); + + // Cache dial background + BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("qdial")) + p->setRenderHint(QPainter::Antialiasing); + + const qreal d_ = r / 6; + const qreal dx = option->rect.x() + d_ + (width - 2 * r) / 2 + 1; + const qreal dy = option->rect.y() + d_ + (height - 2 * r) / 2 + 1; + + QRectF br = QRectF(dx + 0.5, dy + 0.5, + int(r * 2 - 2 * d_ - 2), + int(r * 2 - 2 * d_ - 2)); + + if (enabled) { + // Drop shadow + qreal shadowSize = qMax(1.0, penSize/2.0); + QRectF shadowRect= br.adjusted(-2*shadowSize, -2*shadowSize, + 2*shadowSize, 2*shadowSize); + QRadialGradient shadowGradient(shadowRect.center().x(), + shadowRect.center().y(), shadowRect.width()/2.0, + shadowRect.center().x(), shadowRect.center().y()); + shadowGradient.setColorAt(qreal(0.91), QColor(0, 0, 0, 40)); + shadowGradient.setColorAt(qreal(1.0), Qt::transparent); + p->setBrush(shadowGradient); + p->setPen(Qt::NoPen); + p->translate(shadowSize, shadowSize); + p->drawEllipse(shadowRect); + p->translate(-shadowSize, -shadowSize); + + // Main gradient + QRadialGradient gradient(br.center().x() - br.width()/3, dy, + br.width()*1.3, br.center().x(), + br.center().y() - br.height()/2); + gradient.setColorAt(0, buttonColor.lighter(110)); + gradient.setColorAt(qreal(0.5), buttonColor); + gradient.setColorAt(qreal(0.501), buttonColor.darker(102)); + gradient.setColorAt(1, buttonColor.darker(115)); + p->setBrush(gradient); + } else { + p->setBrush(Qt::NoBrush); + } + + p->setPen(QPen(buttonColor.darker(280))); + p->drawEllipse(br); + p->setBrush(Qt::NoBrush); + p->setPen(buttonColor.lighter(110)); + p->drawEllipse(br.adjusted(1, 1, -1, -1)); + + if (option->state & QStyle::State_HasFocus) { + QColor highlight = pal.highlight().color(); + highlight.setHsv(highlight.hue(), + qMin(160, highlight.saturation()), + qMax(230, highlight.value())); + highlight.setAlpha(127); + p->setPen(QPen(highlight, 2.0)); + p->setBrush(Qt::NoBrush); + p->drawEllipse(br.adjusted(-1, -1, 1, 1)); + } + + END_STYLE_PIXMAPCACHE + + QPointF dp = calcRadialPos(option, qreal(0.70)); + buttonColor = buttonColor.lighter(104); + buttonColor.setAlphaF(0.8f); + const qreal ds = r/qreal(7.0); + QRectF dialRect(dp.x() - ds, dp.y() - ds, 2*ds, 2*ds); + QRadialGradient dialGradient(dialRect.center().x() + dialRect.width()/2, + dialRect.center().y() + dialRect.width(), + dialRect.width()*2, + dialRect.center().x(), dialRect.center().y()); + dialGradient.setColorAt(1, buttonColor.darker(140)); + dialGradient.setColorAt(qreal(0.4), buttonColor.darker(120)); + dialGradient.setColorAt(0, buttonColor.darker(110)); + if (penSize > 3.0) { + painter->setPen(QPen(QColor(0, 0, 0, 25), penSize)); + painter->drawLine(calcRadialPos(option, qreal(0.90)), calcRadialPos(option, qreal(0.96))); + } + + painter->setBrush(dialGradient); + painter->setPen(QColor(255, 255, 255, 150)); + painter->drawEllipse(dialRect.adjusted(-1, -1, 1, 1)); + painter->setPen(QColor(0, 0, 0, 80)); + painter->drawEllipse(dialRect); + painter->restore(); +} + +void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rect, + int left, int top, int right, + int bottom) +{ + QSize size = pixmap.size(); + //painter->setRenderHint(QPainter::SmoothPixmapTransform); + + //top + if (top > 0) { + painter->drawPixmap(QRect(rect.left() + left, rect.top(), rect.width() -right - left, top), pixmap, + QRect(left, 0, size.width() -right - left, top)); + + //top-left + if(left > 0) + painter->drawPixmap(QRect(rect.left(), rect.top(), left, top), pixmap, + QRect(0, 0, left, top)); + + //top-right + if (right > 0) + painter->drawPixmap(QRect(rect.left() + rect.width() - right, rect.top(), right, top), pixmap, + QRect(size.width() - right, 0, right, top)); + } + + //left + if (left > 0) + painter->drawPixmap(QRect(rect.left(), rect.top()+top, left, rect.height() - top - bottom), pixmap, + QRect(0, top, left, size.height() - bottom - top)); + + //center + painter->drawPixmap(QRect(rect.left() + left, rect.top()+top, rect.width() -right - left, + rect.height() - bottom - top), pixmap, + QRect(left, top, size.width() -right -left, + size.height() - bottom - top)); + //right + if (right > 0) + painter->drawPixmap(QRect(rect.left() +rect.width() - right, rect.top()+top, right, rect.height() - top - bottom), pixmap, + QRect(size.width() - right, top, right, size.height() - bottom - top)); + + //bottom + if (bottom > 0) { + painter->drawPixmap(QRect(rect.left() +left, rect.top() + rect.height() - bottom, + rect.width() - right - left, bottom), pixmap, + QRect(left, size.height() - bottom, + size.width() - right - left, bottom)); + //bottom-left + if (left > 0) + painter->drawPixmap(QRect(rect.left(), rect.top() + rect.height() - bottom, left, bottom), pixmap, + QRect(0, size.height() - bottom, left, bottom)); + + //bottom-right + if (right > 0) + painter->drawPixmap(QRect(rect.left() + rect.width() - right, rect.top() + rect.height() - bottom, right, bottom), pixmap, + QRect(size.width() - right, size.height() - bottom, right, bottom)); + + } +} + +WidgetSizePolicy widgetSizePolicy(const QStyleOption *opt) +{ + if (opt && opt->state & QStyle::State_Mini) + return SizeMini; + else if (opt && opt->state & QStyle::State_Small) + return SizeSmall; + + return SizeDefault; +} + +QColor backgroundColor(const QPalette &pal) +{ +// if (qobject_cast<const QScrollBar *>(widget) && widget->parent() && +// qobject_cast<const QAbstractScrollArea *>(widget->parent()->parent())) +// return widget->parentWidget()->parentWidget()->palette().color(QPalette::Base); + return pal.color(QPalette::Base); +} + +} + +} // namespace QQC2 + +QT_END_NAMESPACE diff --git a/src/quicknativestyle/qstyle/qquickstylehelper_p.h b/src/quicknativestyle/qstyle/qquickstylehelper_p.h new file mode 100644 index 00000000000..d2a9636be97 --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickstylehelper_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qpoint.h> +#include <QtCore/qstring.h> +#include <QtGui/qpaintdevice.h> +#include <QtGui/qpolygon.h> +#include <QtCore/qstringbuilder.h> +#if QT_CONFIG(accessibility) +#include <QtGui/qaccessible.h> +#endif + +#ifndef QSTYLEHELPER_P_H +#define QSTYLEHELPER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QObject; +class QPainter; +class QPixmap; + +namespace QQC2 { + +class QStyleOptionSlider; +class QStyleOption; + +namespace QStyleHelper +{ + QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size); + + qreal dpi(const QStyleOption *option); + qreal dpiScaled(qreal value, qreal dpi); + qreal dpiScaled(qreal value, const QPaintDevice *device); + qreal dpiScaled(qreal value, const QStyleOption *option); + + qreal angle(const QPointF &p1, const QPointF &p2); + QPolygonF calcLines(const QStyleOptionSlider *dial); + int calcBigLineSize(int radius); + void drawDial(const QStyleOptionSlider *dial, QPainter *painter); + + void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rect, + int left = 0, int top = 0, int right = 0, + int bottom = 0); + +#if QT_CONFIG(accessibility) + bool isInstanceOf(QObject *obj, QAccessible::Role role); + bool hasAncestor(QObject *obj, QAccessible::Role role); +#endif + QColor backgroundColor(const QPalette &pal); + + enum WidgetSizePolicy { SizeLarge = 0, SizeSmall = 1, SizeMini = 2, SizeDefault = -1 }; + WidgetSizePolicy widgetSizePolicy(const QStyleOption *opt); +} + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif // QSTYLEHELPER_P_H diff --git a/src/quicknativestyle/qstyle/qquickstyleoption.cpp b/src/quicknativestyle/qstyle/qquickstyleoption.cpp new file mode 100644 index 00000000000..c34dddd7e15 --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickstyleoption.cpp @@ -0,0 +1,652 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleoption.h" + +#include <QtGui/private/qguiapplication_p.h> +#include <QtCore/qdebug.h> +#include <QtCore/qmath.h> + +QT_BEGIN_NAMESPACE + +namespace QQC2 { + +QStyleOption::QStyleOption(int version, int type) + : version(version), type(type), state(QStyle::State_None), + direction(QGuiApplication::layoutDirection()), fontMetrics(QFont()), + styleObject(nullptr), control(nullptr), window(nullptr) +{ +} + +/*! + Destroys this style option object. +*/ +QStyleOption::~QStyleOption() +{ +} + +/*! + Constructs a copy of \a other. +*/ +QStyleOption::QStyleOption(const QStyleOption &other) + : version(Version), type(Type), state(other.state), + direction(other.direction), rect(other.rect), fontMetrics(other.fontMetrics), + palette(other.palette), styleObject(other.styleObject), + control(other.control), window(other.window) +{ +} + +/*! + Assign \a other to this QStyleOption. +*/ +QStyleOption &QStyleOption::operator=(const QStyleOption &other) +{ + control = other.control; + window = other.window; + state = other.state; + direction = other.direction; + rect = other.rect; + fontMetrics = other.fontMetrics; + palette = other.palette; + styleObject = other.styleObject; + return *this; +} + +/*! + Constructs a QStyleOptionFocusRect, initializing the members + variables to their default values. +*/ +QStyleOptionFocusRect::QStyleOptionFocusRect() + : QStyleOption(Version, SO_FocusRect) +{ + state |= QStyle::State_KeyboardFocusChange; // assume we had one, will be corrected in initFrom() +} + +/*! + \internal +*/ +QStyleOptionFocusRect::QStyleOptionFocusRect(int versionIn) + : QStyleOption(versionIn, SO_FocusRect) +{ + state |= QStyle::State_KeyboardFocusChange; // assume we had one, will be corrected in initFrom() +} + +/*! + Constructs a QStyleOptionFrame, initializing the members + variables to their default values. +*/ +QStyleOptionFrame::QStyleOptionFrame() + : QStyleOption(Version, SO_Frame), lineWidth(0), midLineWidth(0), + features(None), frameShape(NoFrame) +{ +} + +/*! + \internal +*/ +QStyleOptionFrame::QStyleOptionFrame(int versionIn) + : QStyleOption(versionIn, SO_Frame), lineWidth(0), midLineWidth(0), + features(None) +{ +} + +/*! + Constructs a QStyleOptionGroupBox, initializing the members + variables to their default values. +*/ +QStyleOptionGroupBox::QStyleOptionGroupBox() + : QStyleOptionComplex(Version, Type), features(QStyleOptionFrame::None), + textAlignment(Qt::AlignLeft), lineWidth(0), midLineWidth(0) +{ +} + +QStyleOptionGroupBox::QStyleOptionGroupBox(int versionIn) + : QStyleOptionComplex(versionIn, Type), features(QStyleOptionFrame::None), + textAlignment(Qt::AlignLeft), lineWidth(0), midLineWidth(0) +{ +} + +/*! + Constructs a QStyleOptionHeader, initializing the members + variables to their default values. +*/ +QStyleOptionHeader::QStyleOptionHeader() + : QStyleOption(QStyleOptionHeader::Version, SO_Header), + section(0), textAlignment(Qt::AlignLeft), iconAlignment(Qt::AlignLeft), + position(QStyleOptionHeader::Beginning), + selectedPosition(QStyleOptionHeader::NotAdjacent), sortIndicator(None), + orientation(Qt::Horizontal) +{ +} + +/*! + \internal +*/ +QStyleOptionHeader::QStyleOptionHeader(int versionIn) + : QStyleOption(versionIn, SO_Header), + section(0), textAlignment(Qt::AlignLeft), iconAlignment(Qt::AlignLeft), + position(QStyleOptionHeader::Beginning), + selectedPosition(QStyleOptionHeader::NotAdjacent), sortIndicator(None), + orientation(Qt::Horizontal) +{ +} + +/*! + Constructs a QStyleOptionButton, initializing the members + variables to their default values. +*/ +QStyleOptionButton::QStyleOptionButton() + : QStyleOption(QStyleOptionButton::Version, SO_Button), features(None) +{ +} + +/*! + \internal +*/ +QStyleOptionButton::QStyleOptionButton(int versionIn) + : QStyleOption(versionIn, SO_Button), features(None) +{ +} + +/*! + Constructs a QStyleOptionToolBar, initializing the members + variables to their default values. +*/ +QStyleOptionToolBar::QStyleOptionToolBar() + : QStyleOption(Version, SO_ToolBar), positionOfLine(OnlyOne), positionWithinLine(OnlyOne), + toolBarArea(Qt::TopToolBarArea), features(None), lineWidth(0), midLineWidth(0) +{ +} + +/*! + \fn QStyleOptionToolBar::QStyleOptionToolBar(const QStyleOptionToolBar &other) + + Constructs a copy of the \a other style option. +*/ +QStyleOptionToolBar::QStyleOptionToolBar(int versionIn) +: QStyleOption(versionIn, SO_ToolBar), positionOfLine(OnlyOne), positionWithinLine(OnlyOne), + toolBarArea(Qt::TopToolBarArea), features(None), lineWidth(0), midLineWidth(0) +{ + +} + +/*! + Constructs a QStyleOptionTab object, initializing the members + variables to their default values. +*/ +QStyleOptionTab::QStyleOptionTab() + : QStyleOption(QStyleOptionTab::Version, SO_Tab), + row(0), + position(Beginning), + selectedPosition(NotAdjacent), cornerWidgets(QStyleOptionTab::NoCornerWidgets), + documentMode(false), + features(QStyleOptionTab::None) +{ +} + +QStyleOptionTab::QStyleOptionTab(int versionIn) + : QStyleOption(versionIn, SO_Tab), + row(0), + position(Beginning), + selectedPosition(NotAdjacent), cornerWidgets(QStyleOptionTab::NoCornerWidgets), + documentMode(false), + features(QStyleOptionTab::None) +{ +} + +/*! + Constructs a QStyleOptionTabV4 object, initializing the members + variables to their default values. + */ +QStyleOptionTabV4::QStyleOptionTabV4() : QStyleOptionTab(QStyleOptionTabV4::Version) +{ +} + +/*! + Constructs a QStyleOptionProgressBar, initializing the members + variables to their default values. +*/ +QStyleOptionProgressBar::QStyleOptionProgressBar() + : QStyleOption(QStyleOptionProgressBar::Version, SO_ProgressBar), + minimum(0), maximum(0), progress(0), textAlignment(Qt::AlignLeft), textVisible(false), + invertedAppearance(false), bottomToTop(false) +{ +} + +QStyleOptionProgressBar::QStyleOptionProgressBar(int versionIn) + : QStyleOption(versionIn, SO_ProgressBar), + minimum(0), maximum(0), progress(0), textAlignment(Qt::AlignLeft), textVisible(false), + invertedAppearance(false), bottomToTop(false) +{ +} + +/*! + Constructs a QStyleOptionMenuItem, initializing the members + variables to their default values. +*/ +QStyleOptionMenuItem::QStyleOptionMenuItem() + : QStyleOption(QStyleOptionMenuItem::Version, SO_MenuItem), menuItemType(Normal), + checkType(NotCheckable), checked(false), menuHasCheckableItems(true), maxIconWidth(0), tabWidth(0) +{ +} + +/*! + \internal +*/ +QStyleOptionMenuItem::QStyleOptionMenuItem(int versionIn) + : QStyleOption(versionIn, SO_MenuItem), menuItemType(Normal), + checkType(NotCheckable), checked(false), menuHasCheckableItems(true), maxIconWidth(0), tabWidth(0) +{ +} + +/*! + Constructs a QStyleOptionComplex of the specified \a type and \a + version, initializing the member variables to their default + values. This constructor is usually called by subclasses. +*/ +QStyleOptionComplex::QStyleOptionComplex(int versionIn, int typeIn) + : QStyleOption(versionIn, typeIn), subControls(QStyle::SC_All), activeSubControls(QStyle::SC_None) +{ +} + + +/*! + Constructs a QStyleOptionSlider, initializing the members + variables to their default values. +*/ +QStyleOptionSlider::QStyleOptionSlider() + : QStyleOptionComplex(Version, SO_Slider), orientation(Qt::Horizontal), minimum(0), maximum(0), + tickPosition(NoTicks), tickInterval(0), upsideDown(false), + sliderPosition(0), sliderValue(0), singleStep(0), pageStep(0), notchTarget(0.0), + dialWrapping(false) +{ +} + +/*! + \internal +*/ +QStyleOptionSlider::QStyleOptionSlider(int versionIn) + : QStyleOptionComplex(versionIn, SO_Slider), orientation(Qt::Horizontal), minimum(0), maximum(0), + tickPosition(NoTicks), tickInterval(0), upsideDown(false), + sliderPosition(0), sliderValue(0), singleStep(0), pageStep(0), notchTarget(0.0), + dialWrapping(false) +{ +} + +/*! + Constructs a QStyleOptionSpinBox, initializing the members + variables to their default values. +*/ +QStyleOptionSpinBox::QStyleOptionSpinBox() + : QStyleOptionComplex(Version, SO_SpinBox), buttonSymbols(UpDownArrows), + stepEnabled(StepNone), frame(false) +{ +} + +/*! + \internal +*/ +QStyleOptionSpinBox::QStyleOptionSpinBox(int versionIn) + : QStyleOptionComplex(versionIn, SO_SpinBox), buttonSymbols(UpDownArrows), + stepEnabled(StepNone), frame(false) +{ +} + +/*! + Constructs a QStyleOptionDockWidget, initializing the member + variables to their default values. +*/ +QStyleOptionDockWidget::QStyleOptionDockWidget() + : QStyleOption(Version, SO_DockWidget), closable(false), + movable(false), floatable(false), verticalTitleBar(false) +{ +} + +/*! + \internal +*/ +QStyleOptionDockWidget::QStyleOptionDockWidget(int versionIn) + : QStyleOption(versionIn, SO_DockWidget), closable(false), + movable(false), floatable(false), verticalTitleBar(false) +{ +} + +/*! + Constructs a QStyleOptionToolButton, initializing the members + variables to their default values. +*/ +QStyleOptionToolButton::QStyleOptionToolButton() + : QStyleOptionComplex(Version, SO_ToolButton), features(None), arrowType(Qt::DownArrow) + , toolButtonStyle(Qt::ToolButtonIconOnly) +{ +} + +QStyleOptionToolButton::QStyleOptionToolButton(int versionIn) + : QStyleOptionComplex(versionIn, SO_ToolButton), features(None), arrowType(Qt::DownArrow) + , toolButtonStyle(Qt::ToolButtonIconOnly) + +{ +} + +/*! + Creates a QStyleOptionComboBox, initializing the members variables + to their default values. +*/ +QStyleOptionComboBox::QStyleOptionComboBox() + : QStyleOptionComplex(Version, SO_ComboBox), editable(false), frame(true) +{ +} + +QStyleOptionComboBox::QStyleOptionComboBox(int versionIn) + : QStyleOptionComplex(versionIn, SO_ComboBox), editable(false), frame(true) +{ +} + +/*! + Creates a QStyleOptionToolBox, initializing the members variables + to their default values. +*/ +QStyleOptionToolBox::QStyleOptionToolBox() + : QStyleOption(Version, SO_ToolBox), position(Beginning), selectedPosition(NotAdjacent) +{ +} + +QStyleOptionToolBox::QStyleOptionToolBox(int versionIn) + : QStyleOption(versionIn, SO_ToolBox), position(Beginning), selectedPosition(NotAdjacent) +{ +} + + +/*! + Creates a QStyleOptionRubberBand, initializing the members + variables to their default values. +*/ +QStyleOptionRubberBand::QStyleOptionRubberBand() + : QStyleOption(Version, SO_RubberBand), opaque(false), shape(Line) +{ +} + +QStyleOptionRubberBand::QStyleOptionRubberBand(int versionIn) + : QStyleOption(versionIn, SO_RubberBand), opaque(false) +{ +} + +/*! + Constructs a QStyleOptionTitleBar, initializing the members + variables to their default values. +*/ +QStyleOptionTitleBar::QStyleOptionTitleBar() + : QStyleOptionComplex(Version, SO_TitleBar), titleBarState(0) +{ +} + +QStyleOptionTitleBar::QStyleOptionTitleBar(int versionIn) + : QStyleOptionComplex(versionIn, SO_TitleBar), titleBarState(0) +{ +} + +/*! + Constructs a QStyleOptionViewItem, initializing the members + variables to their default values. +*/ +QStyleOptionViewItem::QStyleOptionViewItem() + : QStyleOption(Version, SO_ViewItem), + displayAlignment(Qt::AlignLeft), decorationAlignment(Qt::AlignLeft), + textElideMode(Qt::ElideMiddle), decorationPosition(Left), + showDecorationSelected(false), features(None), + checkState(Qt::Unchecked), viewItemPosition(QStyleOptionViewItem::Invalid) +{ +} + +QStyleOptionViewItem::QStyleOptionViewItem(int versionIn) + : QStyleOption(versionIn, SO_ViewItem), + displayAlignment(Qt::AlignLeft), decorationAlignment(Qt::AlignLeft), + textElideMode(Qt::ElideMiddle), decorationPosition(Left), + showDecorationSelected(false), features(None), + checkState(Qt::Unchecked), viewItemPosition(QStyleOptionViewItem::Invalid) +{ +} + +/*! + Constructs a QStyleOptionTabWidgetFrame, initializing the members + variables to their default values. +*/ +QStyleOptionTabWidgetFrame::QStyleOptionTabWidgetFrame() + : QStyleOption(Version, SO_TabWidgetFrame), lineWidth(0), midLineWidth(0), shape(QStyleOptionTab::RoundedNorth) +{ +} + +QStyleOptionTabWidgetFrame::QStyleOptionTabWidgetFrame(int versionIn) + : QStyleOption(versionIn, SO_TabWidgetFrame), lineWidth(0), midLineWidth(0) +{ +} + +/*! + Construct a QStyleOptionTabBarBase, initializing the members + vaiables to their default values. +*/ +QStyleOptionTabBarBase::QStyleOptionTabBarBase() + : QStyleOption(Version, SO_TabBarBase), documentMode(false), shape(QStyleOptionTab::RoundedNorth) +{ +} + +QStyleOptionTabBarBase::QStyleOptionTabBarBase(int versionIn) + : QStyleOption(versionIn, SO_TabBarBase), documentMode(false) +{ +} + +/*! + Constructs a QStyleOptionSizeGrip. +*/ +QStyleOptionSizeGrip::QStyleOptionSizeGrip() + : QStyleOptionComplex(Version, Type), corner(Qt::BottomRightCorner) +{ +} + +QStyleOptionSizeGrip::QStyleOptionSizeGrip(int versionIn) + : QStyleOptionComplex(versionIn, Type), corner(Qt::BottomRightCorner) +{ +} + +/*! + Constructs a QStyleOptionGraphicsItem. +*/ +QStyleOptionGraphicsItem::QStyleOptionGraphicsItem() + : QStyleOption(Version, Type), levelOfDetail(1) +{ +} + +QStyleOptionGraphicsItem::QStyleOptionGraphicsItem(int versionIn) + : QStyleOption(versionIn, Type), levelOfDetail(1) +{ +} + +/*! + \since 4.6 + + Returns the level of detail from the \a worldTransform. + + Its value represents the maximum value of the height and + width of a unity rectangle, mapped using the \a worldTransform + of the painter used to draw the item. By default, if no + transformations are applied, its value is 1. If zoomed out 1:2, the level + of detail will be 0.5, and if zoomed in 2:1, its value is 2. + + \sa QGraphicsScene::minimumRenderSize() +*/ +qreal QStyleOptionGraphicsItem::levelOfDetailFromTransform(const QTransform &worldTransform) +{ + if (worldTransform.type() <= QTransform::TxTranslate) + return 1; // Translation only? The LOD is 1. + + // Two unit vectors. + QLineF v1(0, 0, 1, 0); + QLineF v2(0, 0, 0, 1); + // LOD is the transformed area of a 1x1 rectangle. + return qSqrt(worldTransform.map(v1).length() * worldTransform.map(v2).length()); +} + +/*! + Constructs a QStyleHintReturn with version \a version and type \a + type. + + The version has no special meaning for QStyleHintReturn; it can be + used by subclasses to distinguish between different version of + the same hint type. + + \sa QStyleOption::version, QStyleOption::type +*/ +QStyleHintReturn::QStyleHintReturn(int versionIn, int type) + : version(versionIn), type(type) +{ +} + +/*! + \internal +*/ + +QStyleHintReturn::~QStyleHintReturn() +{ +} + +/*! + Constructs a QStyleHintReturnMask. The member variables are + initialized to default values. +*/ +QStyleHintReturnMask::QStyleHintReturnMask() : QStyleHintReturn(Version, Type) +{ +} + +QStyleHintReturnMask::~QStyleHintReturnMask() +{ +} + +/*! + Constructs a QStyleHintReturnVariant. The member variables are + initialized to default values. +*/ +QStyleHintReturnVariant::QStyleHintReturnVariant() : QStyleHintReturn(Version, Type) +{ +} + +QStyleHintReturnVariant::~QStyleHintReturnVariant() +{ +} + +#if !defined(QT_NO_DEBUG_STREAM) +QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType) +{ +#if !defined(QT_NO_DEBUG) + switch (optionType) { + case QStyleOption::SO_Default: + debug << "SO_Default"; break; + case QStyleOption::SO_FocusRect: + debug << "SO_FocusRect"; break; + case QStyleOption::SO_Button: + debug << "SO_Button"; break; + case QStyleOption::SO_Tab: + debug << "SO_Tab"; break; + case QStyleOption::SO_MenuItem: + debug << "SO_MenuItem"; break; + case QStyleOption::SO_Frame: + debug << "SO_Frame"; break; + case QStyleOption::SO_ProgressBar: + debug << "SO_ProgressBar"; break; + case QStyleOption::SO_ToolBox: + debug << "SO_ToolBox"; break; + case QStyleOption::SO_Header: + debug << "SO_Header"; break; + case QStyleOption::SO_DockWidget: + debug << "SO_DockWidget"; break; + case QStyleOption::SO_ViewItem: + debug << "SO_ViewItem"; break; + case QStyleOption::SO_TabWidgetFrame: + debug << "SO_TabWidgetFrame"; break; + case QStyleOption::SO_TabBarBase: + debug << "SO_TabBarBase"; break; + case QStyleOption::SO_RubberBand: + debug << "SO_RubberBand"; break; + case QStyleOption::SO_Complex: + debug << "SO_Complex"; break; + case QStyleOption::SO_Slider: + debug << "SO_Slider"; break; + case QStyleOption::SO_SpinBox: + debug << "SO_SpinBox"; break; + case QStyleOption::SO_ToolButton: + debug << "SO_ToolButton"; break; + case QStyleOption::SO_ComboBox: + debug << "SO_ComboBox"; break; + case QStyleOption::SO_TitleBar: + debug << "SO_TitleBar"; break; + case QStyleOption::SO_CustomBase: + debug << "SO_CustomBase"; break; + case QStyleOption::SO_GroupBox: + debug << "SO_GroupBox"; break; + case QStyleOption::SO_ToolBar: + debug << "SO_ToolBar"; break; + case QStyleOption::SO_ComplexCustomBase: + debug << "SO_ComplexCustomBase"; break; + case QStyleOption::SO_SizeGrip: + debug << "SO_SizeGrip"; break; + case QStyleOption::SO_GraphicsItem: + debug << "SO_GraphicsItem"; break; + } +#else + Q_UNUSED(optionType); +#endif + return debug; +} + +QDebug operator<<(QDebug debug, const QStyleOption &option) +{ +#if !defined(QT_NO_DEBUG) + debug << "QStyleOption("; + debug << QStyleOption::OptionType(option.type); + debug << ',' << (option.direction == Qt::RightToLeft ? "RightToLeft" : "LeftToRight"); + debug << ',' << option.state; + debug << ',' << option.rect; + debug << ',' << option.styleObject; + debug << ')'; +#else + Q_UNUSED(option); +#endif + return debug; +} +#endif + +} // namespace QQC2 + +QT_END_NAMESPACE diff --git a/src/quicknativestyle/qstyle/qquickstyleoption.h b/src/quicknativestyle/qstyle/qquickstyleoption.h new file mode 100644 index 00000000000..0aeddab8d06 --- /dev/null +++ b/src/quicknativestyle/qstyle/qquickstyleoption.h @@ -0,0 +1,796 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTYLEOPTION_H +#define QSTYLEOPTION_H + +#include "qquickstyle.h" + +#include <QtCore/qlocale.h> +#include <QtCore/qvariant.h> +#include <QtCore/qdebug.h> +#include <QtCore/qabstractitemmodel.h> + +#include <QtGui/qicon.h> +#include <QtGui/qfontmetrics.h> + +QT_BEGIN_NAMESPACE + +class QQuickItem; + +namespace QQC2 { + +class QStyleOption +{ +public: + enum OptionType { + SO_Default, SO_FocusRect, SO_Button, SO_Tab, SO_MenuItem, + SO_Frame, SO_ProgressBar, SO_ToolBox, SO_Header, + SO_DockWidget, SO_ViewItem, SO_TabWidgetFrame, + SO_TabBarBase, SO_RubberBand, SO_ToolBar, SO_GraphicsItem, + + SO_Complex = 0xf0000, SO_Slider, SO_SpinBox, SO_ToolButton, SO_ComboBox, + SO_TitleBar, SO_GroupBox, SO_SizeGrip, + + SO_CustomBase = 0xf00, + SO_ComplexCustomBase = 0xf000000 + }; + Q_ENUMS(OptionType) + + enum StyleOptionType { Type = SO_Default }; + enum StyleOptionVersion { Version = 1 }; + + int version; // TODO: Remove version information + int type; + QStyle::State state; + Qt::LayoutDirection direction; + QRect rect; + QFontMetrics fontMetrics; + QPalette palette; + QObject *styleObject; + + // QQC2 additions. Remember to also update copy + // constructor and assignment operator when adding + // new variables here. + QQuickItem *control; + QWindow *window; + + QStyleOption(int version = QStyleOption::Version, int type = SO_Default); + QStyleOption(const QStyleOption &other); + ~QStyleOption(); + + QStyleOption &operator=(const QStyleOption &other); +}; + +class QStyleOptionFocusRect : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_FocusRect }; + enum StyleOptionVersion { Version = 1 }; + + QColor backgroundColor; + + QStyleOptionFocusRect(); + QStyleOptionFocusRect(const QStyleOptionFocusRect &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionFocusRect &operator=(const QStyleOptionFocusRect &) = default; + +protected: + QStyleOptionFocusRect(int version); +}; + +class QStyleOptionFrame : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_Frame }; + enum StyleOptionVersion { Version = 3 }; + enum FrameFeature { + None = 0x00, + Flat = 0x01, + Rounded = 0x02 + }; + Q_DECLARE_FLAGS(FrameFeatures, FrameFeature) + enum Shape { + NoFrame = 0, // no frame + Box = 0x0001, // rectangular box + Panel = 0x0002, // rectangular panel + WinPanel = 0x0003, // rectangular panel (Windows) + HLine = 0x0004, // horizontal line + VLine = 0x0005, // vertical line + StyledPanel = 0x0006 // rectangular panel depending on the GUI style + }; + enum Shadow { + Plain = 0x0010, // plain line + Raised = 0x0020, // raised shadow effect + Sunken = 0x0030 // sunken shadow effect + }; + + int lineWidth; + int midLineWidth; + FrameFeatures features; + Shape frameShape; + + QStyleOptionFrame(); + QStyleOptionFrame(const QStyleOptionFrame &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionFrame &operator=(const QStyleOptionFrame &) = default; + +protected: + QStyleOptionFrame(int version); +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionFrame::FrameFeatures) +Q_DECLARE_MIXED_ENUM_OPERATORS_SYMMETRIC(int, QStyleOptionFrame::Shape, QStyleOptionFrame::Shadow) + +Q_DECL_DEPRECATED typedef QStyleOptionFrame QStyleOptionFrameV2; +Q_DECL_DEPRECATED typedef QStyleOptionFrame QStyleOptionFrameV3; + +class QStyleOptionTab : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_Tab }; + enum StyleOptionVersion { Version = 3 }; + + enum TabPosition { Beginning, Middle, End, OnlyOneTab }; + enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected }; + enum CornerWidget { NoCornerWidgets = 0x00, LeftCornerWidget = 0x01, + RightCornerWidget = 0x02 }; + enum TabFeature { None = 0x00, HasFrame = 0x01 }; + enum Shape { RoundedNorth, RoundedSouth, RoundedWest, RoundedEast, + TriangularNorth, TriangularSouth, TriangularWest, TriangularEast + }; + Q_DECLARE_FLAGS(CornerWidgets, CornerWidget) + Q_DECLARE_FLAGS(TabFeatures, TabFeature) + + QString text; + QIcon icon; + int row; + TabPosition position; + Shape shape = RoundedNorth; + SelectedPosition selectedPosition; + CornerWidgets cornerWidgets; + QSize iconSize; + bool documentMode; + QSize leftButtonSize; + QSize rightButtonSize; + TabFeatures features; + + QStyleOptionTab(); + QStyleOptionTab(const QStyleOptionTab &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionTab &operator=(const QStyleOptionTab &) = default; + +protected: + QStyleOptionTab(int version); +}; + +class QStyleOptionTabWidgetFrame : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_TabWidgetFrame }; + enum StyleOptionVersion { Version = 2 }; + + int lineWidth; + int midLineWidth; + QStyleOptionTab::Shape shape; + QSize tabBarSize; + QSize rightCornerWidgetSize; + QSize leftCornerWidgetSize; + QRect tabBarRect; + QRect selectedTabRect; + + QStyleOptionTabWidgetFrame(); + inline QStyleOptionTabWidgetFrame(const QStyleOptionTabWidgetFrame &other) + : QStyleOption(Version, Type) { *this = other; } + QStyleOptionTabWidgetFrame &operator=(const QStyleOptionTabWidgetFrame &) = default; + +protected: + QStyleOptionTabWidgetFrame(int version); +}; + +Q_DECL_DEPRECATED typedef QStyleOptionTabWidgetFrame QStyleOptionTabWidgetFrameV2; + + +class QStyleOptionTabBarBase : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_TabBarBase }; + + enum TabBarPosition { North, South, West, East }; + enum ButtonPosition { LeftSide, RightSide }; + + QRect tabBarRect; + QRect selectedTabRect; + bool documentMode; + QStyleOptionTab::Shape shape; + + QStyleOptionTabBarBase(); + QStyleOptionTabBarBase(const QStyleOptionTabBarBase &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionTabBarBase &operator=(const QStyleOptionTabBarBase &) = default; + +protected: + QStyleOptionTabBarBase(int version); +}; + +class QStyleOptionHeader : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_Header }; + enum StyleOptionVersion { Version = 1 }; + enum SectionPosition { Beginning, Middle, End, OnlyOneSection }; + enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected, + NextAndPreviousAreSelected }; + enum SortIndicator { None, SortUp, SortDown }; + + int section; + QString text; + Qt::Alignment textAlignment; + QIcon icon; + Qt::Alignment iconAlignment; + SectionPosition position; + SelectedPosition selectedPosition; + SortIndicator sortIndicator; + Qt::Orientation orientation; + + QStyleOptionHeader(); + QStyleOptionHeader(const QStyleOptionHeader &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionHeader &operator=(const QStyleOptionHeader &) = default; + +protected: + QStyleOptionHeader(int version); +}; + +class QStyleOptionButton : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_Button }; + enum StyleOptionVersion { Version = 1 }; + + enum ButtonFeature { None = 0x00, Flat = 0x01, HasMenu = 0x02, DefaultButton = 0x04, + AutoDefaultButton = 0x08, CommandLinkButton = 0x10 }; + Q_DECLARE_FLAGS(ButtonFeatures, ButtonFeature) + + ButtonFeatures features; + QString text; + QIcon icon; + QSize iconSize; + + QStyleOptionButton(); + QStyleOptionButton(const QStyleOptionButton &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionButton &operator=(const QStyleOptionButton &) = default; + +protected: + QStyleOptionButton(int version); +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionButton::ButtonFeatures) + +class QStyleOptionTabV4 : public QStyleOptionTab +{ +public: + enum StyleOptionVersion { Version = 4 }; + QStyleOptionTabV4(); + int tabIndex = -1; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionTab::CornerWidgets) + +Q_DECL_DEPRECATED typedef QStyleOptionTab QStyleOptionTabV2; +Q_DECL_DEPRECATED typedef QStyleOptionTab QStyleOptionTabV3; + + +class QStyleOptionToolBar : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_ToolBar }; + enum StyleOptionVersion { Version = 1 }; + enum ToolBarPosition { Beginning, Middle, End, OnlyOne }; + enum ToolBarFeature { None = 0x0, Movable = 0x1 }; + Q_DECLARE_FLAGS(ToolBarFeatures, ToolBarFeature) + + ToolBarPosition positionOfLine; // The toolbar line position + ToolBarPosition positionWithinLine; // The position within a toolbar + Qt::ToolBarArea toolBarArea; // The toolbar docking area + ToolBarFeatures features; + int lineWidth; + int midLineWidth; + + QStyleOptionToolBar(); + QStyleOptionToolBar(const QStyleOptionToolBar &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionToolBar &operator=(const QStyleOptionToolBar &) = default; + +protected: + QStyleOptionToolBar(int version); +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionToolBar::ToolBarFeatures) + +class QStyleOptionProgressBar : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_ProgressBar }; + enum StyleOptionVersion { Version = 2 }; + + int minimum; + int maximum; + int progress; + QString text; + Qt::Alignment textAlignment; + bool textVisible; + bool invertedAppearance; + bool bottomToTop; + + QStyleOptionProgressBar(); + QStyleOptionProgressBar(const QStyleOptionProgressBar &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionProgressBar &operator=(const QStyleOptionProgressBar &) = default; + +protected: + QStyleOptionProgressBar(int version); +}; + +class QStyleOptionMenuItem : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_MenuItem }; + enum StyleOptionVersion { Version = 1 }; + + enum MenuItemType { Normal, DefaultItem, Separator, SubMenu, Scroller, TearOff, Margin, + EmptyArea }; + enum CheckType { NotCheckable, Exclusive, NonExclusive }; + + MenuItemType menuItemType; + CheckType checkType; + bool checked; + bool menuHasCheckableItems; + QRect menuRect; + QString text; + QIcon icon; + int maxIconWidth; + int tabWidth; // ### Qt 6: rename to reservedShortcutWidth + QFont font; + + QStyleOptionMenuItem(); + QStyleOptionMenuItem(const QStyleOptionMenuItem &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionMenuItem &operator=(const QStyleOptionMenuItem &) = default; + +protected: + QStyleOptionMenuItem(int version); +}; + +class QStyleOptionDockWidget : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_DockWidget }; + enum StyleOptionVersion { Version = 2 }; + + QString title; + bool closable; + bool movable; + bool floatable; + bool verticalTitleBar; + + QStyleOptionDockWidget(); + QStyleOptionDockWidget(const QStyleOptionDockWidget &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionDockWidget &operator=(const QStyleOptionDockWidget &) = default; + +protected: + QStyleOptionDockWidget(int version); +}; + +Q_DECL_DEPRECATED typedef QStyleOptionDockWidget QStyleOptionDockWidgetV2; + +class QStyleOptionViewItem : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_ViewItem }; + enum StyleOptionVersion { Version = 4 }; + + enum Position { Left, Right, Top, Bottom }; + enum ScrollMode { ScrollPerItem, ScrollPerPixel }; // Doesn't really belong in this class. + + Qt::Alignment displayAlignment; + Qt::Alignment decorationAlignment; + Qt::TextElideMode textElideMode; + Position decorationPosition; + QSize decorationSize; + QFont font; + bool showDecorationSelected; + + enum ViewItemFeature { + None = 0x00, + WrapText = 0x01, + Alternate = 0x02, + HasCheckIndicator = 0x04, + HasDisplay = 0x08, + HasDecoration = 0x10 + }; + Q_DECLARE_FLAGS(ViewItemFeatures, ViewItemFeature) + + ViewItemFeatures features; + + QLocale locale; + + enum ViewItemPosition { Invalid, Beginning, Middle, End, OnlyOne }; + + QModelIndex index; + Qt::CheckState checkState; + QIcon icon; + QString text; + ViewItemPosition viewItemPosition; + QBrush backgroundBrush; + + QStyleOptionViewItem(); + QStyleOptionViewItem(const QStyleOptionViewItem &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionViewItem &operator=(const QStyleOptionViewItem &) = default; + +protected: + QStyleOptionViewItem(int version); +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionViewItem::ViewItemFeatures) + +Q_DECL_DEPRECATED typedef QStyleOptionViewItem QStyleOptionViewItemV2; +Q_DECL_DEPRECATED typedef QStyleOptionViewItem QStyleOptionViewItemV3; +Q_DECL_DEPRECATED typedef QStyleOptionViewItem QStyleOptionViewItemV4; + +class QStyleOptionToolBox : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_ToolBox }; + enum StyleOptionVersion { Version = 2 }; + + QString text; + QIcon icon; + + enum TabPosition { Beginning, Middle, End, OnlyOneTab }; + enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected }; + + TabPosition position; + SelectedPosition selectedPosition; + + QStyleOptionToolBox(); + QStyleOptionToolBox(const QStyleOptionToolBox &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionToolBox &operator=(const QStyleOptionToolBox &) = default; + +protected: + QStyleOptionToolBox(int version); +}; + +Q_DECL_DEPRECATED typedef QStyleOptionToolBox QStyleOptionToolBoxV2; + +class QStyleOptionRubberBand : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_RubberBand }; + enum StyleOptionVersion { Version = 1 }; + enum Shape { Line, Rectangle }; + + bool opaque; + Shape shape; + + QStyleOptionRubberBand(); + QStyleOptionRubberBand(const QStyleOptionRubberBand &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionRubberBand &operator=(const QStyleOptionRubberBand &) = default; + +protected: + QStyleOptionRubberBand(int version); +}; + +// -------------------------- Complex style options ------------------------------- +class QStyleOptionComplex : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_Complex }; + enum StyleOptionVersion { Version = 1 }; + + QStyle::SubControls subControls; + QStyle::SubControls activeSubControls; + + QStyleOptionComplex(int version = QStyleOptionComplex::Version, int type = SO_Complex); + QStyleOptionComplex(const QStyleOptionComplex &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionComplex &operator=(const QStyleOptionComplex &) = default; +}; + +class QStyleOptionSlider : public QStyleOptionComplex +{ +public: + enum StyleOptionType { Type = SO_Slider }; + enum StyleOptionVersion { Version = 1 }; + enum TickPosition { + NoTicks = 0, + TicksAbove = 1, + TicksLeft = TicksAbove, + TicksBelow = 2, + TicksRight = TicksBelow, + TicksBothSides = 3 + }; + + Qt::Orientation orientation; + int minimum; + int maximum; + TickPosition tickPosition; + int tickInterval; + bool upsideDown; + int sliderPosition; + int sliderValue; + int singleStep; + int pageStep; + qreal notchTarget; + bool dialWrapping; + + QStyleOptionSlider(); + QStyleOptionSlider(const QStyleOptionSlider &other) : QStyleOptionComplex(Version, Type) { *this = other; } + QStyleOptionSlider &operator=(const QStyleOptionSlider &) = default; + +protected: + QStyleOptionSlider(int version); +}; + +class QStyleOptionSpinBox : public QStyleOptionComplex +{ +public: + enum StyleOptionType { Type = SO_SpinBox }; + enum StyleOptionVersion { Version = 1 }; + enum StepEnabledFlag { StepNone = 0x00, StepUpEnabled = 0x01, StepDownEnabled = 0x02, StepEnabled = 0xFF }; + enum ButtonSymbols { UpDownArrows, PlusMinus, NoButtons }; + + ButtonSymbols buttonSymbols; + StepEnabledFlag stepEnabled; + bool frame; + + QStyleOptionSpinBox(); + QStyleOptionSpinBox(const QStyleOptionSpinBox &other) : QStyleOptionComplex(Version, Type) { *this = other; } + QStyleOptionSpinBox &operator=(const QStyleOptionSpinBox &) = default; + +protected: + QStyleOptionSpinBox(int version); +}; + +class QStyleOptionToolButton : public QStyleOptionComplex +{ +public: + enum StyleOptionType { Type = SO_ToolButton }; + enum StyleOptionVersion { Version = 1 }; + + enum ToolButtonFeature { None = 0x00, Arrow = 0x01, Menu = 0x04, MenuButtonPopup = Menu, PopupDelay = 0x08, + HasMenu = 0x10 }; + Q_DECLARE_FLAGS(ToolButtonFeatures, ToolButtonFeature) + + ToolButtonFeatures features; + QIcon icon; + QSize iconSize; + QString text; + Qt::ArrowType arrowType; + Qt::ToolButtonStyle toolButtonStyle; + QPoint pos; + QFont font; + + QStyleOptionToolButton(); + QStyleOptionToolButton(const QStyleOptionToolButton &other) : QStyleOptionComplex(Version, Type) { *this = other; } + QStyleOptionToolButton &operator=(const QStyleOptionToolButton &) = default; + +protected: + QStyleOptionToolButton(int version); +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionToolButton::ToolButtonFeatures) + +class QStyleOptionComboBox : public QStyleOptionComplex +{ +public: + enum StyleOptionType { Type = SO_ComboBox }; + enum StyleOptionVersion { Version = 1 }; + + bool editable; + QRect popupRect; + bool frame; + QString currentText; + QIcon currentIcon; + QSize iconSize; + + QStyleOptionComboBox(); + QStyleOptionComboBox(const QStyleOptionComboBox &other) : QStyleOptionComplex(Version, Type) { *this = other; } + QStyleOptionComboBox &operator=(const QStyleOptionComboBox &) = default; + +protected: + QStyleOptionComboBox(int version); +}; + +class QStyleOptionTitleBar : public QStyleOptionComplex +{ +public: + enum StyleOptionType { Type = SO_TitleBar }; + enum StyleOptionVersion { Version = 1 }; + + QString text; + QIcon icon; + int titleBarState; + Qt::WindowFlags titleBarFlags; + + QStyleOptionTitleBar(); + QStyleOptionTitleBar(const QStyleOptionTitleBar &other) : QStyleOptionComplex(Version, Type) { *this = other; } + QStyleOptionTitleBar &operator=(const QStyleOptionTitleBar &) = default; + +protected: + QStyleOptionTitleBar(int version); +}; + +class QStyleOptionGroupBox : public QStyleOptionComplex +{ +public: + enum StyleOptionType { Type = SO_GroupBox }; + enum StyleOptionVersion { Version = 1 }; + + QStyleOptionFrame::FrameFeatures features; + QString text; + Qt::Alignment textAlignment; + QColor textColor; + int lineWidth; + int midLineWidth; + + QStyleOptionGroupBox(); + QStyleOptionGroupBox(const QStyleOptionGroupBox &other) : QStyleOptionComplex(Version, Type) { *this = other; } + QStyleOptionGroupBox &operator=(const QStyleOptionGroupBox &) = default; +protected: + QStyleOptionGroupBox(int version); +}; + +class QStyleOptionSizeGrip : public QStyleOptionComplex +{ +public: + enum StyleOptionType { Type = SO_SizeGrip }; + enum StyleOptionVersion { Version = 1 }; + + Qt::Corner corner; + + QStyleOptionSizeGrip(); + QStyleOptionSizeGrip(const QStyleOptionSizeGrip &other) : QStyleOptionComplex(Version, Type) { *this = other; } + QStyleOptionSizeGrip &operator=(const QStyleOptionSizeGrip &) = default; +protected: + QStyleOptionSizeGrip(int version); +}; + +class QStyleOptionGraphicsItem : public QStyleOption +{ +public: + enum StyleOptionType { Type = SO_GraphicsItem }; + enum StyleOptionVersion { Version = 1 }; + + QRectF exposedRect; + qreal levelOfDetail; + + QStyleOptionGraphicsItem(); + QStyleOptionGraphicsItem(const QStyleOptionGraphicsItem &other) : QStyleOption(Version, Type) { *this = other; } + QStyleOptionGraphicsItem &operator=(const QStyleOptionGraphicsItem &) = default; + static qreal levelOfDetailFromTransform(const QTransform &worldTransform); +protected: + QStyleOptionGraphicsItem(int version); +}; + +template <typename T> +T qstyleoption_cast(const QStyleOption *opt) +{ + typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type Opt; + if (opt && opt->version >= Opt::Version && (opt->type == Opt::Type + || int(Opt::Type) == QStyleOption::SO_Default + || (int(Opt::Type) == QStyleOption::SO_Complex + && opt->type > QStyleOption::SO_Complex))) + return static_cast<T>(opt); + return nullptr; +} + +template <typename T> +T qstyleoption_cast(QStyleOption *opt) +{ + typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type Opt; + if (opt && opt->version >= Opt::Version && (opt->type == Opt::Type + || int(Opt::Type) == QStyleOption::SO_Default + || (int(Opt::Type) == QStyleOption::SO_Complex + && opt->type > QStyleOption::SO_Complex))) + return static_cast<T>(opt); + return nullptr; +} + +// -------------------------- QStyleHintReturn ------------------------------- + +class QStyleHintReturn +{ +public: + enum HintReturnType { + SH_Default=0xf000, SH_Mask, SH_Variant + }; + + enum StyleOptionType { Type = SH_Default }; + enum StyleOptionVersion { Version = 1 }; + + QStyleHintReturn(int version = QStyleOption::Version, int type = SH_Default); + ~QStyleHintReturn(); + + int version; + int type; +}; + +class QStyleHintReturnMask : public QStyleHintReturn +{ +public: + enum StyleOptionType { Type = SH_Mask }; + enum StyleOptionVersion { Version = 1 }; + + QStyleHintReturnMask(); + ~QStyleHintReturnMask(); + + QRegion region; +}; + +class QStyleHintReturnVariant : public QStyleHintReturn +{ +public: + enum StyleOptionType { Type = SH_Variant }; + enum StyleOptionVersion { Version = 1 }; + + QStyleHintReturnVariant(); + ~QStyleHintReturnVariant(); + + QVariant variant; +}; + +template <typename T> +T qstyleoption_cast(const QStyleHintReturn *hint) +{ + typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type Opt; + if (hint && hint->version <= Opt::Version && + (hint->type == Opt::Type || int(Opt::Type) == QStyleHintReturn::SH_Default)) + return static_cast<T>(hint); + return nullptr; +} + +template <typename T> +T qstyleoption_cast(QStyleHintReturn *hint) +{ + typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type Opt; + if (hint && hint->version <= Opt::Version && + (hint->type == Opt::Type || int(Opt::Type) == QStyleHintReturn::SH_Default)) + return static_cast<T>(hint); + return nullptr; +} + +#if !defined(QT_NO_DEBUG_STREAM) +QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType); +QDebug operator<<(QDebug debug, const QStyleOption &option); +#endif + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif // QSTYLEOPTION_H diff --git a/src/quicknativestyle/qstyle/qstyle.pri b/src/quicknativestyle/qstyle/qstyle.pri new file mode 100644 index 00000000000..4d02549897e --- /dev/null +++ b/src/quicknativestyle/qstyle/qstyle.pri @@ -0,0 +1,23 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qquicknativestyle.h \ + $$PWD/qquickcommonstyle.h \ + $$PWD/qquickcommonstyle_p.h \ + $$PWD/qquickcommonstylepixmaps_p.h \ + $$PWD/qquickdrawutil.h \ + $$PWD/qquickstyle.h \ + $$PWD/qquickstyle_p.h \ + $$PWD/qquickstylehelper_p.h \ + $$PWD/qquickstyleoption.h + +SOURCES += \ + $$PWD/qquicknativestyle.cpp \ + $$PWD/qquickcommonstyle.cpp \ + $$PWD/qquickdrawutil.cpp \ + $$PWD/qquickstyle.cpp \ + $$PWD/qquickstylehelper.cpp \ + $$PWD/qquickstyleoption.cpp + +macos: include(mac/mac.pri) +win32: include(windows/windows.pri) diff --git a/src/quicknativestyle/qstyle/windows/qquickwindowsstyle.cpp b/src/quicknativestyle/qstyle/windows/qquickwindowsstyle.cpp new file mode 100644 index 00000000000..242b770ddca --- /dev/null +++ b/src/quicknativestyle/qstyle/windows/qquickwindowsstyle.cpp @@ -0,0 +1,2388 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module 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 "qquickwindowsstyle_p.h" +#include "qquickwindowsstyle_p_p.h" +#include "qquickstyleoption.h" +#include "qquickstylehelper_p.h" +#include "qquickdrawutil.h" + +#include <QtGui/qbitmap.h> +#include <QtGui/qevent.h> +#include <QtGui/qpaintengine.h> +#include <QtGui/qpainter.h> +#include <QtCore/qdebug.h> +#include <QtCore/qfile.h> +#include <QtCore/qtextstream.h> +#include <QtGui/qpixmapcache.h> +#include <private/qmath_p.h> +#include <qmath.h> +#include <QtGui/qpainterpath.h> +#include <QtGui/qscreen.h> +#include <QtGui/qwindow.h> +#include <qpa/qplatformtheme.h> +#include <qpa/qplatformscreen.h> +#include <private/qguiapplication_p.h> +#include <private/qhighdpiscaling_p.h> +#include <qpa/qplatformnativeinterface.h> + +#if 0 && QT_CONFIG(animation) +//#include <private/qstyleanimation_p.h> +#endif + +#include <algorithm> + +QT_BEGIN_NAMESPACE + +#if defined(Q_OS_WIN) + +QT_BEGIN_INCLUDE_NAMESPACE +#include "qt_windows.h" +QT_END_INCLUDE_NAMESPACE +# ifndef COLOR_GRADIENTACTIVECAPTION +# define COLOR_GRADIENTACTIVECAPTION 27 +# endif +# ifndef COLOR_GRADIENTINACTIVECAPTION +# define COLOR_GRADIENTINACTIVECAPTION 28 +# endif + +Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &); +#endif //Q_OS_WIN + +QT_BEGIN_INCLUDE_NAMESPACE +#include <limits.h> +QT_END_INCLUDE_NAMESPACE + +namespace QQC2 { + +enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight }; + +/* + \internal +*/ + +QWindowsStylePrivate::QWindowsStylePrivate() = default; + +qreal QWindowsStylePrivate::appDevicePixelRatio() +{ + return qApp->devicePixelRatio(); +} + +bool QWindowsStylePrivate::isDarkMode() +{ + bool result = false; +#ifdef Q_OS_WIN + // Windows only: Return whether dark mode style support is desired and + // dark mode is in effect. + if (auto ni = QGuiApplication::platformNativeInterface()) { + const QVariant darkModeStyleP = ni->property("darkModeStyle"); + result = darkModeStyleP.metaType().id() == QMetaType::Bool + && darkModeStyleP.value<bool>() + && ni->property("darkMode").value<bool>(); + } +#endif + return result; +} + +// ###TODO SH_UnderlineShortcut +#if 0 +// Returns \c true if the toplevel parent of \a widget has seen the Alt-key +bool QWindowsStylePrivate::hasSeenAlt(const QWidget *widget) const +{ + widget = widget->window(); + return seenAlt.contains(widget); +} + +/*! + \reimp +*/ +bool QWindowsStyle::eventFilter(QObject *o, QEvent *e) +{ + // Records Alt- and Focus events +// if (!o->isWidgetType()) + return QObject::eventFilter(o, e); + QWidget *widget = qobject_cast<QWidget*>(o); + Q_D(QWindowsStyle); + switch (e->type()) { + case QEvent::KeyPress: + if (static_cast<QKeyEvent *>(e)->key() == Qt::Key_Alt) { + widget = widget->window(); + + // Alt has been pressed - find all widgets that care + QList<QWidget *> l = widget->findChildren<QWidget *>(); + auto ignorable = [](QWidget *w) { + return w->isWindow() || !w->isVisible() + || w->style()->styleHint(SH_UnderlineShortcut, nullptr, w); + }; + l.erase(std::remove_if (l.begin(), l.end(), ignorable), l.end()); + // Update states before repainting + d->seenAlt.append(widget); + d->alt_down = true; + + // Repaint all relevant widgets + for (int pos = 0; pos < l.size(); ++pos) + l.at(pos)->update(); + } + break; + case QEvent::KeyRelease: + if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Alt) { + widget = widget->window(); + + // Update state and repaint the menu bars. + d->alt_down = false; +#if 0 && QT_CONFIG(menubar) + QList<QMenuBar *> l = widget->findChildren<QMenuBar *>(); + for (int i = 0; i < l.size(); ++i) + l.at(i)->update(); +#endif + } + break; + case QEvent::Close: + // Reset widget when closing + d->seenAlt.removeAll(widget); + d->seenAlt.removeAll(widget->window()); + break; + default: + break; + } + return QCommonStyle::eventFilter(o, e); +} +#endif + +/*! + \class QWindowsStyle + \brief The QWindowsStyle class provides a Microsoft Windows-like look and feel. + + \ingroup appearance + \inmodule QtWidgets + \internal + + This style is Qt's default GUI style on Windows. + + \image qwindowsstyle.png + \sa QWindowsVistaStyle, QMacStyle, QFusionStyle +*/ + +/*! + Constructs a QWindowsStyle object. +*/ +QWindowsStyle::QWindowsStyle() : QCommonStyle(*new QWindowsStylePrivate) +{ +} + +/*! + \internal + + Constructs a QWindowsStyle object. +*/ +QWindowsStyle::QWindowsStyle(QWindowsStylePrivate &dd) : QCommonStyle(dd) +{ +} + + +/*! Destroys the QWindowsStyle object. */ +QWindowsStyle::~QWindowsStyle() +{ +} + +#ifdef Q_OS_WIN +static inline QRgb colorref2qrgb(COLORREF col) +{ + return qRgb(GetRValue(col), GetGValue(col), GetBValue(col)); +} +#endif +#if 0 +/*! \reimp */ +void QWindowsStyle::polish(QApplication *app) +{ + QCommonStyle::polish(app); + QWindowsStylePrivate *d = const_cast<QWindowsStylePrivate*>(d_func()); + // We only need the overhead when shortcuts are sometimes hidden + if (!proxy()->styleHint(SH_UnderlineShortcut, nullptr) && app) + app->installEventFilter(this); + + const auto &palette = QGuiApplication::palette(); + d->activeGradientCaptionColor = palette.highlight().color(); + d->activeCaptionColor = d->activeGradientCaptionColor; + d->inactiveGradientCaptionColor = palette.dark().color(); + d->inactiveCaptionColor = d->inactiveGradientCaptionColor; + d->inactiveCaptionText = palette.window().color(); + +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) //fetch native title bar colors + if (app->desktopSettingsAware()){ + DWORD activeCaption = GetSysColor(COLOR_ACTIVECAPTION); + DWORD gradientActiveCaption = GetSysColor(COLOR_GRADIENTACTIVECAPTION); + DWORD inactiveCaption = GetSysColor(COLOR_INACTIVECAPTION); + DWORD gradientInactiveCaption = GetSysColor(COLOR_GRADIENTINACTIVECAPTION); + DWORD inactiveCaptionText = GetSysColor(COLOR_INACTIVECAPTIONTEXT); + d->activeCaptionColor = colorref2qrgb(activeCaption); + d->activeGradientCaptionColor = colorref2qrgb(gradientActiveCaption); + d->inactiveCaptionColor = colorref2qrgb(inactiveCaption); + d->inactiveGradientCaptionColor = colorref2qrgb(gradientInactiveCaption); + d->inactiveCaptionText = colorref2qrgb(inactiveCaptionText); + } +#endif +} + +/*! \reimp */ +void QWindowsStyle::unpolish(QApplication *app) +{ + QCommonStyle::unpolish(app); + app->removeEventFilter(this); +} + +/*! \reimp */ +void QWindowsStyle::polish(QWidget *widget) +{ + QCommonStyle::polish(widget); +} + +/*! \reimp */ +void QWindowsStyle::unpolish(QWidget *widget) +{ + QCommonStyle::unpolish(widget); +} + +/*! + \reimp +*/ +void QWindowsStyle::polish(QPalette &pal) +{ + QCommonStyle::polish(pal); +} +#endif + +int QWindowsStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *opt) +{ +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) + switch (pm) { + case QStyle::PM_DockWidgetFrameWidth: + return GetSystemMetrics(SM_CXFRAME); + + case QStyle::PM_TitleBarHeight: + Q_ASSERT(opt); + if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) { + if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool) { + // MS always use one less than they say + return GetSystemMetrics(SM_CYSMCAPTION) - 1; + } + } + return GetSystemMetrics(SM_CYCAPTION) - 1; + + case QStyle::PM_ScrollBarExtent: + { + NONCLIENTMETRICS ncm; + ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT); + if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0)) + return qMax(ncm.iScrollHeight, ncm.iScrollWidth); + } + break; + + case QStyle::PM_MdiSubWindowFrameWidth: + return GetSystemMetrics(SM_CYFRAME); + + default: + break; + } +#else // Q_OS_WIN && !Q_OS_WINRT + Q_UNUSED(pm); + Q_UNUSED(widget); +#endif + return QWindowsStylePrivate::InvalidMetric; +} + +int QWindowsStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm) +{ + switch (pm) { + case QStyle::PM_ToolBarItemSpacing: + return 0; + case QStyle::PM_ButtonDefaultIndicator: + case QStyle::PM_ButtonShiftHorizontal: + case QStyle::PM_ButtonShiftVertical: + case QStyle::PM_MenuHMargin: + case QStyle::PM_MenuVMargin: + case QStyle::PM_ToolBarItemMargin: + return 1; + case QStyle::PM_DockWidgetSeparatorExtent: + return 4; +#if 0 && QT_CONFIG(tabbar) + case QStyle::PM_TabBarTabShiftHorizontal: + return 0; + case QStyle::PM_TabBarTabShiftVertical: + return 2; +#endif + + case QStyle::PM_SliderLength: + return 11; + +#if 0 && QT_CONFIG(menu) + case QStyle::PM_MenuBarHMargin: + case QStyle::PM_MenuBarVMargin: + case QStyle::PM_MenuBarPanelWidth: + return 0; + case QStyle::PM_SmallIconSize: + return 16; + case QStyle::PM_LargeIconSize: + return 32; + case QStyle::PM_DockWidgetTitleMargin: + return 2; + case QStyle::PM_DockWidgetTitleBarButtonMargin: + case QStyle::PM_DockWidgetFrameWidth: + return 4; + +#endif // QT_CONFIG(menu) + case QStyle::PM_ToolBarHandleExtent: + return 10; + default: + break; + } + return QWindowsStylePrivate::InvalidMetric; +} + +static QScreen *screenOf(const QWindow *w) +{ + if (w) { + if (auto screen = w->screen()) + return screen; + } + return QGuiApplication::primaryScreen(); +} + +// Calculate the overall scale factor to obtain Qt Device Independent +// Pixels from a native Windows size. Divide by devicePixelRatio +// and account for secondary screens with differing logical DPI. +qreal QWindowsStylePrivate::nativeMetricScaleFactor(const QStyleOption *opt) +{ + Q_ASSERT(opt); + const QWindow *win = opt->window; + return nativeMetricScaleFactor(win); +} + +qreal QWindowsStylePrivate::nativeMetricScaleFactor(const QWindow *win) +{ + qreal result = qreal(1) / QWindowsStylePrivate::devicePixelRatio(win); + if (QGuiApplicationPrivate::screen_list.size() > 1) { + const QScreen *primaryScreen = QGuiApplication::primaryScreen(); + const QScreen *screen = screenOf(win); + if (screen != primaryScreen) { + const qreal primaryLogicalDpi = primaryScreen->handle()->logicalDpi().first; + const qreal logicalDpi = screen->handle()->logicalDpi().first; + if (!qFuzzyCompare(primaryLogicalDpi, logicalDpi)) + result *= logicalDpi / primaryLogicalDpi; + } + } + return result; +} + +/*! + \reimp +*/ +int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt) const +{ + int ret = QWindowsStylePrivate::pixelMetricFromSystemDp(pm, opt); + if (ret != QWindowsStylePrivate::InvalidMetric) + return qRound(qreal(ret) * QWindowsStylePrivate::nativeMetricScaleFactor(opt)); + + ret = QWindowsStylePrivate::fixedPixelMetric(pm); + if (ret != QWindowsStylePrivate::InvalidMetric) + return int(QStyleHelper::dpiScaled(ret, opt)); + + ret = 0; + + switch (pm) { + case PM_MaximumDragDistance: + ret = QCommonStyle::pixelMetric(PM_MaximumDragDistance); + if (ret == -1) + ret = 60; + break; + + // Returns the number of pixels to use for the business part of the + // slider (i.e., the non-tickmark portion). The remaining space is shared + // equally between the tickmark regions. + case PM_SliderControlThickness: + if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width(); + int ticks = sl->tickPosition; + int n = 0; + if (ticks & QStyleOptionSlider::TicksAbove) + ++n; + if (ticks & QStyleOptionSlider::TicksBelow) + ++n; + if (!n) { + ret = space; + break; + } + + int thick = 6; // Magic constant to get 5 + 16 + 5 + if (ticks != QStyleOptionSlider::TicksBothSides && ticks != QStyleOptionSlider::NoTicks) + thick += proxy()->pixelMetric(PM_SliderLength, sl) / 4; + + space -= thick; + if (space > 0) + thick += (space * 2) / (n + 2); + ret = thick; + } + break; + + case PM_IconViewIconSize: + ret = proxy()->pixelMetric(PM_LargeIconSize, opt); + break; + + case PM_SplitterWidth: + ret = int(QStyleHelper::dpiScaled(4, opt)); + break; + + default: + ret = QCommonStyle::pixelMetric(pm, opt); + break; + } + + return ret; +} + +/*! + \reimp + */ +QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt) const +{ +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) + QPixmap desktopIcon; + switch (standardPixmap) { + case SP_DriveCDIcon: + case SP_DriveDVDIcon: + case SP_DriveNetIcon: + case SP_DriveHDIcon: + case SP_DriveFDIcon: + case SP_FileIcon: + case SP_FileLinkIcon: + case SP_DirLinkIcon: + case SP_DirClosedIcon: + case SP_DesktopIcon: + case SP_ComputerIcon: + case SP_DirOpenIcon: + case SP_FileDialogNewFolder: + case SP_DirHomeIcon: + case SP_TrashIcon: + case SP_VistaShield: + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardPixmap); + desktopIcon = theme->standardPixmap(sp, QSizeF(16, 16)); + } + break; + case SP_MessageBoxInformation: + case SP_MessageBoxWarning: + case SP_MessageBoxCritical: + case SP_MessageBoxQuestion: + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardPixmap); + desktopIcon = theme->standardPixmap(sp, QSizeF()); + } + break; + default: + break; + } + if (!desktopIcon.isNull()) { + return desktopIcon; + } +#endif // Q_OS_WIN && !Q_OS_WINRT + return QCommonStyle::standardPixmap(standardPixmap, opt); +} + +/*! \reimp */ +int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, + QStyleHintReturn *returnData) const +{ + int ret = 0; + + switch (hint) { + case SH_EtchDisabledText: + ret = d_func()->isDarkMode() ? 0 : 1; + break; + case SH_Slider_SnapToValue: + case SH_PrintDialog_RightAlignButtons: + case SH_FontDialog_SelectAssociatedText: + case SH_Menu_AllowActiveAndDisabled: + case SH_MenuBar_AltKeyNavigation: + case SH_MenuBar_MouseTracking: + case SH_Menu_MouseTracking: + case SH_ComboBox_ListMouseTracking: + case SH_Slider_StopMouseOverSlider: + case SH_MainWindow_SpaceBelowMenuBar: + ret = 1; + + break; + case SH_ItemView_ShowDecorationSelected: +#if 0 && QT_CONFIG(listview) + if (qobject_cast<const QListView*>(widget)) + ret = 1; +#endif + break; + case SH_ItemView_ChangeHighlightOnFocus: + ret = 1; + break; + case SH_ToolBox_SelectedPageTitleBold: + ret = 0; + break; + +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) // Option not used on WinRT -> common style + case SH_UnderlineShortcut: + { + ret = 1; + BOOL cues = false; + SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &cues, 0); + ret = int(cues); + // Do nothing if we always paint underlines + Q_D(const QWindowsStyle); + if (!ret && d) { +#if 0 && QT_CONFIG(menubar) + const QMenuBar *menuBar = qobject_cast<const QMenuBar *>(widget); + if (!menuBar && qobject_cast<const QMenu *>(widget)) { + QWidget *w = QApplication::activeWindow(); + if (w && w != widget) + menuBar = w->findChild<QMenuBar *>(); + } + // If we paint a menu bar draw underlines if is in the keyboardState + if (menuBar) { + if (menuBar->d_func()->keyboardState || d->altDown()) + ret = 1; + // Otherwise draw underlines if the toplevel widget has seen an alt-press + } else +#endif // QT_CONFIG(menubar) +// if (d->hasSeenAlt(widget)) { +// ret = 1; +// } + } +#ifndef QT_NO_ACCESSIBILITY + if (!ret && opt && opt->type == QStyleOption::SO_MenuItem + && QStyleHelper::isInstanceOf(opt->styleObject, QAccessible::MenuItem) + && opt->styleObject->property("_q_showUnderlined").toBool()) + ret = 1; +#endif // QT_NO_ACCESSIBILITY + break; + } +#endif // Q_OS_WIN && !Q_OS_WINRT + case SH_Menu_SubMenuSloppyCloseTimeout: + case SH_Menu_SubMenuPopupDelay: { +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) + DWORD delay; + if (SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &delay, 0)) + ret = delay; + else +#endif // Q_OS_WIN && !Q_OS_WINRT + ret = 400; + break; + } +#if 0 && QT_CONFIG(rubberband) + case SH_RubberBand_Mask: + if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) { + ret = 0; + if (rbOpt->shape == QRubberBand::Rectangle) { + ret = true; + if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) { + mask->region = opt->rect; + int size = 1; + if (widget && widget->isWindow()) + size = 4; + mask->region -= opt->rect.adjusted(size, size, -size, -size); + } + } + } + break; +#endif // QT_CONFIG(rubberband) +#if 0 && QT_CONFIG(wizard) + case SH_WizardStyle: + ret = QWizard::ModernStyle; + break; +#endif + case SH_ItemView_ArrowKeysNavigateIntoChildren: + ret = true; + break; + case SH_DialogButtonBox_ButtonsHaveIcons: + ret = 0; + break; + default: + ret = QCommonStyle::styleHint(hint, opt, returnData); + break; + } + return ret; +} + +/*! \reimp */ +void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p) const +{ + // Used to restore across fallthrough cases. Currently only used in PE_IndicatorCheckBox + bool doRestore = false; + + switch (pe) { +#if 0 && QT_CONFIG(toolbar) + case PE_IndicatorToolBarSeparator: + { + QRect rect = opt->rect; + const int margin = 2; + QPen oldPen = p->pen(); + if (opt->state & State_Horizontal){ + const int offset = rect.width()/2; + p->setPen(QPen(opt->palette.dark().color())); + p->drawLine(rect.bottomLeft().x() + offset, + rect.bottomLeft().y() - margin, + rect.topLeft().x() + offset, + rect.topLeft().y() + margin); + p->setPen(QPen(opt->palette.light().color())); + p->drawLine(rect.bottomLeft().x() + offset + 1, + rect.bottomLeft().y() - margin, + rect.topLeft().x() + offset + 1, + rect.topLeft().y() + margin); + } + else{ //Draw vertical separator + const int offset = rect.height()/2; + p->setPen(QPen(opt->palette.dark().color())); + p->drawLine(rect.topLeft().x() + margin , + rect.topLeft().y() + offset, + rect.topRight().x() - margin, + rect.topRight().y() + offset); + p->setPen(QPen(opt->palette.light().color())); + p->drawLine(rect.topLeft().x() + margin , + rect.topLeft().y() + offset + 1, + rect.topRight().x() - margin, + rect.topRight().y() + offset + 1); + } + p->setPen(oldPen); + } + break; + case PE_IndicatorToolBarHandle: + p->save(); + p->translate(opt->rect.x(), opt->rect.y()); + if (opt->state & State_Horizontal) { + int x = opt->rect.width() / 2 - 4; + if (opt->direction == Qt::RightToLeft) + x -= 2; + if (opt->rect.height() > 4) { + qDrawShadePanel(p, x, 2, 3, opt->rect.height() - 4, + opt->palette, false, 1, nullptr); + qDrawShadePanel(p, x + 3, 2, 3, opt->rect.height() - 4, + opt->palette, false, 1, nullptr); + } + } else { + if (opt->rect.width() > 4) { + int y = opt->rect.height() / 2 - 4; + qDrawShadePanel(p, 2, y, opt->rect.width() - 4, 3, + opt->palette, false, 1, nullptr); + qDrawShadePanel(p, 2, y + 3, opt->rect.width() - 4, 3, + opt->palette, false, 1, nullptr); + } + } + p->restore(); + break; + +#endif // QT_CONFIG(toolbar) + case PE_FrameButtonTool: + case PE_PanelButtonTool: { + QPen oldPen = p->pen(); +#if 0 && QT_CONFIG(dockwidget) + if (w && w->inherits("QDockWidgetTitleButton")) { + if (const QWidget *dw = w->parentWidget()) + if (dw->isWindow()){ + qDrawWinButton(p, opt->rect.adjusted(1, 1, 0, 0), opt->palette, opt->state & (State_Sunken | State_On), + &opt->palette.button()); + + return; + } + } +#endif // QT_CONFIG(dockwidget) + QBrush fill; + bool stippled; + bool panel = (pe == PE_PanelButtonTool); + if ((!(opt->state & State_Sunken )) + && (!(opt->state & State_Enabled) + || !(opt->state & State_MouseOver && opt->state & State_AutoRaise)) + && (opt->state & State_On)) { + fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern); + stippled = true; + } else { + fill = opt->palette.brush(QPalette::Button); + stippled = false; + } + + if (opt->state & (State_Raised | State_Sunken | State_On)) { + if (opt->state & State_AutoRaise) { + if (opt->state & (State_Enabled | State_Sunken | State_On)){ + if (panel) + qDrawShadePanel(p, opt->rect, opt->palette, + opt->state & (State_Sunken | State_On), 1, &fill); + else + qDrawShadeRect(p, opt->rect, opt->palette, + opt->state & (State_Sunken | State_On), 1); + } + if (stippled) { + p->setPen(opt->palette.button().color()); + p->drawRect(opt->rect.adjusted(1,1,-2,-2)); + } + } else { + qDrawWinButton(p, opt->rect, opt->palette, + opt->state & (State_Sunken | State_On), panel ? &fill : nullptr); + } + } else { + p->fillRect(opt->rect, fill); + } + p->setPen(oldPen); + break; } + case PE_PanelButtonCommand: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + QBrush fill; + State flags = opt->state; + QPalette pal = opt->palette; + QRect r = opt->rect; + if (! (flags & State_Sunken) && (flags & State_On)) + fill = QBrush(pal.light().color(), Qt::Dense4Pattern); + else + fill = pal.brush(QPalette::Button); + + if (btn->features & QStyleOptionButton::DefaultButton && flags & State_Sunken) { + p->setPen(pal.dark().color()); + p->setBrush(fill); + p->drawRect(r.adjusted(0, 0, -1, -1)); + } else if (flags & (State_Raised | State_On | State_Sunken)) { + qDrawWinButton(p, r, pal, flags & (State_Sunken | State_On), + &fill); + } else { + p->fillRect(r, fill); + } + } + break; + case PE_FrameDefaultButton: { + QPen oldPen = p->pen(); + p->setPen(QPen(opt->palette.shadow().color(), 0)); + QRectF rect = opt->rect; + const qreal dpi = QStyleHelper::dpi(opt); + const qreal topLevelAdjustment = QStyleHelper::dpiScaled(0.5, dpi); + const qreal bottomRightAdjustment = QStyleHelper::dpiScaled(-1.5, dpi); + rect.adjust(topLevelAdjustment, topLevelAdjustment, + bottomRightAdjustment, bottomRightAdjustment); + p->drawRect(rect); + p->setPen(oldPen); + break; + } + case PE_IndicatorCheckBox: { + QBrush fill; + if (opt->state & State_NoChange) + fill = QBrush(opt->palette.base().color(), Qt::Dense4Pattern); + else if (opt->state & State_Sunken) + fill = opt->palette.button(); + else if (opt->state & State_Enabled) + fill = opt->palette.base(); + else + fill = opt->palette.window(); + p->save(); + doRestore = true; + qDrawWinPanel(p, opt->rect, opt->palette, true, &fill); + if (opt->state & State_NoChange) + p->setPen(opt->palette.dark().color()); + else + p->setPen(opt->palette.text().color()); + } + Q_FALLTHROUGH(); + case PE_IndicatorItemViewItemCheck: + if (!doRestore) { + p->save(); + doRestore = true; + } +#if 0 && QT_CONFIG(itemviews) + if (pe == PE_IndicatorItemViewItemCheck) { + const QStyleOptionViewItem *itemViewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt); + p->setPen(itemViewOpt + && itemViewOpt->showDecorationSelected + && opt->state & State_Selected + ? opt->palette.highlightedText().color() + : opt->palette.text().color()); + if (opt->state & State_NoChange) + p->setBrush(opt->palette.brush(QPalette::Button)); + p->drawRect(opt->rect.x() + 1, opt->rect.y() + 1, opt->rect.width() - 2, opt->rect.height() - 2); + } +#endif // QT_CONFIG(itemviews) + if (!(opt->state & State_Off)) { + QPointF points[6]; + qreal scaleh = opt->rect.width() / 12.0; + qreal scalev = opt->rect.height() / 12.0; + points[0] = { opt->rect.x() + 3.5 * scaleh, opt->rect.y() + 5.5 * scalev }; + points[1] = { points[0].x(), points[0].y() + 2 * scalev }; + points[2] = { points[1].x() + 2 * scaleh, points[1].y() + 2 * scalev }; + points[3] = { points[2].x() + 4 * scaleh, points[2].y() - 4 * scalev }; + points[4] = { points[3].x(), points[3].y() - 2 * scalev }; + points[5] = { points[4].x() - 4 * scaleh, points[4].y() + 4 * scalev }; + p->setPen(QPen(opt->palette.text().color(), 0)); + p->setBrush(opt->palette.text().color()); + p->drawPolygon(points, 6); + } + if (doRestore) + p->restore(); + break; + case PE_FrameFocusRect: + if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) { + //### check for d->alt_down + if (!(fropt->state & State_KeyboardFocusChange) && !proxy()->styleHint(SH_UnderlineShortcut, opt)) + return; + QRect r = opt->rect; + p->save(); + p->setBackgroundMode(Qt::TransparentMode); + QColor bg_col = fropt->backgroundColor; + if (!bg_col.isValid()) + bg_col = p->background().color(); + // Create an "XOR" color. + QColor patternCol((bg_col.red() ^ 0xff) & 0xff, + (bg_col.green() ^ 0xff) & 0xff, + (bg_col.blue() ^ 0xff) & 0xff); + p->setBrush(QBrush(patternCol, Qt::Dense4Pattern)); + p->setBrushOrigin(r.topLeft()); + p->setPen(Qt::NoPen); + p->drawRect(r.left(), r.top(), r.width(), 1); // Top + p->drawRect(r.left(), r.bottom(), r.width(), 1); // Bottom + p->drawRect(r.left(), r.top(), 1, r.height()); // Left + p->drawRect(r.right(), r.top(), 1, r.height()); // Right + p->restore(); + } + break; + case PE_IndicatorRadioButton: + { + QRect r = opt->rect; + p->save(); + p->setRenderHint(QPainter::Antialiasing, true); + + QPointF circleCenter = r.center() + QPoint(1, 1); + qreal radius = (r.width() + (r.width() + 1) % 2) / 2.0 - 1; + + QPainterPath path1; + path1.addEllipse(circleCenter, radius, radius); + radius *= 0.85; + QPainterPath path2; + path2.addEllipse(circleCenter, radius, radius); + radius *= 0.85; + QPainterPath path3; + path3.addEllipse(circleCenter, radius, radius); + radius *= 0.5; + QPainterPath path4; + path4.addEllipse(circleCenter, radius, radius); + + QPolygon topLeftPol, bottomRightPol; + topLeftPol.setPoints(3, r.x(), r.y(), r.x(), r.y() + r.height(), r.x() + r.width(), r.y()); + bottomRightPol.setPoints(3, r.x(), r.y() + r.height(), r.x() + r.width(), r.y() + r.height(), r.x() + r.width(), r.y()); + + p->setClipRegion(QRegion(topLeftPol)); + p->setPen(opt->palette.dark().color()); + p->setBrush(opt->palette.dark().color()); + p->drawPath(path1); + p->setPen(opt->palette.shadow().color()); + p->setBrush(opt->palette.shadow().color()); + p->drawPath(path2); + + p->setClipRegion(QRegion(bottomRightPol)); + p->setPen(opt->palette.light().color()); + p->setBrush(opt->palette.light().color()); + p->drawPath(path1); + p->setPen(opt->palette.midlight().color()); + p->setBrush(opt->palette.midlight().color()); + p->drawPath(path2); + + QColor fillColor = ((opt->state & State_Sunken) || !(opt->state & State_Enabled)) ? + opt->palette.button().color() : opt->palette.base().color(); + + p->setClipping(false); + p->setPen(fillColor); + p->setBrush(fillColor); + p->drawPath(path3); + + if (opt->state & State_On) { + p->setPen(opt->palette.text().color()); + p->setBrush(opt->palette.text()); + p->drawPath(path4); + } + p->restore(); + break; + } +#ifndef QT_NO_FRAME + case PE_Frame: + case PE_FrameMenu: + if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + if (frame->lineWidth == 2 || pe == PE_Frame) { + QPalette popupPal = frame->palette; + if (pe == PE_FrameMenu) { + popupPal.setColor(QPalette::Light, frame->palette.window().color()); + popupPal.setColor(QPalette::Midlight, frame->palette.light().color()); + } + if (pe == PE_Frame && (frame->state & State_Raised)) + qDrawWinButton(p, frame->rect, popupPal, frame->state & State_Sunken); + else if (pe == PE_Frame && (frame->state & State_Sunken)) + { + popupPal.setColor(QPalette::Midlight, frame->palette.window().color()); + qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken); + } + else + qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken); + } else { + QCommonStyle::drawPrimitive(pe, opt, p); + } + } else { + QPalette popupPal = opt->palette; + popupPal.setColor(QPalette::Light, opt->palette.window().color()); + popupPal.setColor(QPalette::Midlight, opt->palette.light().color()); + qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken); + } + break; +#endif // QT_NO_FRAME + case PE_FrameButtonBevel: + case PE_PanelButtonBevel: { + QBrush fill; + bool panel = pe != PE_FrameButtonBevel; + p->setBrushOrigin(opt->rect.topLeft()); + if (!(opt->state & State_Sunken) && (opt->state & State_On)) + fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern); + else + fill = opt->palette.brush(QPalette::Button); + + if (opt->state & (State_Raised | State_On | State_Sunken)) { + qDrawWinButton(p, opt->rect, opt->palette, opt->state & (State_Sunken | State_On), + panel ? &fill : nullptr); + } else { + if (panel) + p->fillRect(opt->rect, fill); + else + p->drawRect(opt->rect); + } + break; } + case PE_FrameWindow: { + QPalette popupPal = opt->palette; + popupPal.setColor(QPalette::Light, opt->palette.window().color()); + popupPal.setColor(QPalette::Midlight, opt->palette.light().color()); + qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken); + break; } +#if 0 && QT_CONFIG(dockwidget) + case PE_IndicatorDockWidgetResizeHandle: + break; + case PE_FrameDockWidget: + if (qstyleoption_cast<const QStyleOptionFrame *>(opt)) { + proxy()->drawPrimitive(QStyle::PE_FrameWindow, opt, p, w); + } + break; +#endif // QT_CONFIG(dockwidget) + + case PE_FrameStatusBarItem: + qDrawShadePanel(p, opt->rect, opt->palette, true, 1, nullptr); + break; + + case PE_IndicatorProgressChunk: + { + bool vertical = false, inverted = false; + if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) { + vertical = !(pb->state & QStyle::State_Horizontal); + inverted = pb->invertedAppearance; + } + + int space = 2; + int chunksize = proxy()->pixelMetric(PM_ProgressBarChunkWidth, opt) - space; + if (!vertical) { + if (opt->rect.width() <= chunksize) + space = 0; + + if (inverted) + p->fillRect(opt->rect.x() + space, opt->rect.y(), opt->rect.width() - space, opt->rect.height(), + opt->palette.brush(QPalette::Highlight)); + else + p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width() - space, opt->rect.height(), + opt->palette.brush(QPalette::Highlight)); + } else { + if (opt->rect.height() <= chunksize) + space = 0; + + if (inverted) + p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height() - space, + opt->palette.brush(QPalette::Highlight)); + else + p->fillRect(opt->rect.x(), opt->rect.y() + space, opt->rect.width(), opt->rect.height() - space, + opt->palette.brush(QPalette::Highlight)); + } + } + break; + + case PE_FrameTabWidget: { + qDrawWinButton(p, opt->rect, opt->palette, false, nullptr); + break; + } + default: + QCommonStyle::drawPrimitive(pe, opt, p); + } +} + +/*! \reimp */ +void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p) const +{ + switch (ce) { +#if 0 && QT_CONFIG(rubberband) + case CE_RubberBand: + if (qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) { + // ### workaround for slow general painter path + QPixmap tiledPixmap(16, 16); + QPainter pixmapPainter(&tiledPixmap); + pixmapPainter.setPen(Qt::NoPen); + pixmapPainter.setBrush(Qt::Dense4Pattern); + pixmapPainter.setBackground(Qt::white); + pixmapPainter.setBackgroundMode(Qt::OpaqueMode); + pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height()); + pixmapPainter.end(); + tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage()); + p->save(); + QRect r = opt->rect; + QStyleHintReturnMask mask; + if (proxy()->styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask)) + p->setClipRegion(mask.region); + p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap); + p->restore(); + return; + } + break; +#endif // QT_CONFIG(rubberband) + +#if 0 && QT_CONFIG(menu) && QT_CONFIG(mainwindow) + case CE_MenuBarEmptyArea: + if (widget && qobject_cast<const QMainWindow *>(widget->parentWidget())) { + p->fillRect(opt->rect, opt->palette.button()); + QPen oldPen = p->pen(); + p->setPen(QPen(opt->palette.dark().color())); + p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight()); + p->setPen(oldPen); + } + break; +#endif +#if 0 && QT_CONFIG(menu) + case CE_MenuItem: + if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { + int x, y, w, h; + menuitem->rect.getRect(&x, &y, &w, &h); + int tab = menuitem->tabWidth; + bool dis = !(menuitem->state & State_Enabled); + bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable + ? menuitem->checked : false; + bool act = menuitem->state & State_Selected; + + // windows always has a check column, regardless whether we have an icon or not + int checkcol = qMax<int>(menuitem->maxIconWidth, QWindowsStylePrivate::windowsCheckMarkWidth); + + QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button); + p->fillRect(menuitem->rect.adjusted(0, 0, -1, 0), fill); + + if (menuitem->menuItemType == QStyleOptionMenuItem::Separator){ + int yoff = y-1 + h / 2; + p->setPen(menuitem->palette.dark().color()); + p->drawLine(x + 2, yoff, x + w - 4, yoff); + p->setPen(menuitem->palette.light().color()); + p->drawLine(x + 2, yoff + 1, x + w - 4, yoff + 1); + return; + } + + QRect vCheckRect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height())); + if (!menuitem->icon.isNull() && checked) { + if (act) { + qDrawShadePanel(p, vCheckRect, + menuitem->palette, true, 1, + &menuitem->palette.brush(QPalette::Button)); + } else { + QBrush fill(menuitem->palette.light().color(), Qt::Dense4Pattern); + qDrawShadePanel(p, vCheckRect, menuitem->palette, true, 1, &fill); + } + } else if (!act) { + p->fillRect(vCheckRect, menuitem->palette.brush(QPalette::Button)); + } + + // On Windows Style, if we have a checkable item and an icon we + // draw the icon recessed to indicate an item is checked. If we + // have no icon, we draw a checkmark instead. + if (!menuitem->icon.isNull()) { + QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal; + if (act && !dis) + mode = QIcon::Active; + QPixmap pixmap; + if (checked) + pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode, QIcon::On); + else + pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode); + const int pixw = pixmap.width() / pixmap.devicePixelRatio(); + const int pixh = pixmap.height() / pixmap.devicePixelRatio(); + QRect pmr(0, 0, pixw, pixh); + pmr.moveCenter(vCheckRect.center()); + p->setPen(menuitem->palette.text().color()); + p->drawPixmap(pmr.topLeft(), pixmap); + } else if (checked) { + QStyleOptionMenuItem newMi = *menuitem; + newMi.state = State_None; + if (!dis) + newMi.state |= State_Enabled; + if (act) + newMi.state |= State_On; + newMi.rect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x() + QWindowsStylePrivate::windowsItemFrame, + menuitem->rect.y() + QWindowsStylePrivate::windowsItemFrame, + checkcol - 2 * QWindowsStylePrivate::windowsItemFrame, + menuitem->rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame)); + proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget); + } + p->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color()); + + QColor discol; + if (dis) { + discol = menuitem->palette.text().color(); + p->setPen(discol); + } + + int xm = int(QWindowsStylePrivate::windowsItemFrame) + checkcol + int(QWindowsStylePrivate::windowsItemHMargin); + int xpos = menuitem->rect.x() + xm; + QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin, + w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin); + QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect); + QStringRef s(&menuitem->text); + if (!s.isEmpty()) { // draw text + p->save(); + int t = s.indexOf(QLatin1Char('\t')); + int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; + if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget)) + text_flags |= Qt::TextHideMnemonic; + text_flags |= Qt::AlignLeft; + if (t >= 0) { + QRect vShortcutRect = visualRect(opt->direction, menuitem->rect, + QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom()))); + const QString textToDraw = s.mid(t + 1).toString(); + if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) { + p->setPen(menuitem->palette.light().color()); + p->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, textToDraw); + p->setPen(discol); + } + p->drawText(vShortcutRect, text_flags, textToDraw); + s = s.left(t); + } + QFont font = menuitem->font; + if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem) + font.setBold(true); + p->setFont(font); + const QString textToDraw = s.left(t).toString(); + if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) { + p->setPen(menuitem->palette.light().color()); + p->drawText(vTextRect.adjusted(1, 1, 1, 1), text_flags, textToDraw); + p->setPen(discol); + } + p->drawText(vTextRect, text_flags, textToDraw); + p->restore(); + } + if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow + int dim = (h - 2 * QWindowsStylePrivate::windowsItemFrame) / 2; + PrimitiveElement arrow; + arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight; + xpos = x + w - QWindowsStylePrivate::windowsArrowHMargin - QWindowsStylePrivate::windowsItemFrame - dim; + QRect vSubMenuRect = visualRect(opt->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim)); + QStyleOptionMenuItem newMI = *menuitem; + newMI.rect = vSubMenuRect; + newMI.state = dis ? State_None : State_Enabled; + if (act) + newMI.palette.setColor(QPalette::ButtonText, + newMI.palette.highlightedText().color()); + proxy()->drawPrimitive(arrow, &newMI, p, widget); + } + + } + break; +#endif // QT_CONFIG(menu) +#if 0 && QT_CONFIG(menubar) + case CE_MenuBarItem: + if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { + bool active = mbi->state & State_Selected; + bool hasFocus = mbi->state & State_HasFocus; + bool down = mbi->state & State_Sunken; + QStyleOptionMenuItem newMbi = *mbi; + p->fillRect(mbi->rect, mbi->palette.brush(QPalette::Button)); + if (active || hasFocus) { + QBrush b = mbi->palette.brush(QPalette::Button); + if (active && down) + p->setBrushOrigin(p->brushOrigin() + QPoint(1, 1)); + if (active && hasFocus) + qDrawShadeRect(p, mbi->rect.x(), mbi->rect.y(), mbi->rect.width(), + mbi->rect.height(), mbi->palette, active && down, 1, 0, &b); + if (active && down) { + newMbi.rect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, mbi, widget), + proxy()->pixelMetric(PM_ButtonShiftVertical, mbi, widget)); + p->setBrushOrigin(p->brushOrigin() - QPoint(1, 1)); + } + } + QCommonStyle::drawControl(ce, &newMbi, p, widget); + } + break; +#endif // QT_CONFIG(menubar) +#if 0 && QT_CONFIG(tabbar) + case CE_TabBarTabShape: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) { + bool rtlHorTabs = (tab->direction == Qt::RightToLeft + && (tab->shape == QTabBar::RoundedNorth + || tab->shape == QTabBar::RoundedSouth)); + bool selected = tab->state & State_Selected; + bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End) + || (rtlHorTabs + && tab->position == QStyleOptionTab::Beginning)); + bool firstTab = ((!rtlHorTabs + && tab->position == QStyleOptionTab::Beginning) + || (rtlHorTabs + && tab->position == QStyleOptionTab::End)); + bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab; + bool previousSelected = + ((!rtlHorTabs + && tab->selectedPosition == QStyleOptionTab::PreviousIsSelected) + || (rtlHorTabs + && tab->selectedPosition == QStyleOptionTab::NextIsSelected)); + bool nextSelected = + ((!rtlHorTabs + && tab->selectedPosition == QStyleOptionTab::NextIsSelected) + || (rtlHorTabs + && tab->selectedPosition + == QStyleOptionTab::PreviousIsSelected)); + int tabBarAlignment = proxy()->styleHint(SH_TabBar_Alignment, tab, widget); + bool leftAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignLeft) + || (rtlHorTabs + && tabBarAlignment == Qt::AlignRight); + + bool rightAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignRight) + || (rtlHorTabs + && tabBarAlignment == Qt::AlignLeft); + + QColor light = tab->palette.light().color(); + QColor dark = tab->palette.dark().color(); + QColor shadow = tab->palette.shadow().color(); + int borderThinkness = proxy()->pixelMetric(PM_TabBarBaseOverlap, tab, widget); + if (selected) + borderThinkness /= 2; + QRect r2(opt->rect); + int x1 = r2.left(); + int x2 = r2.right(); + int y1 = r2.top(); + int y2 = r2.bottom(); + switch (tab->shape) { + default: + QCommonStyle::drawControl(ce, tab, p, widget); + break; + case QTabBar::RoundedNorth: { + if (!selected) { + y1 += 2; + x1 += onlyOne || firstTab ? borderThinkness : 0; + x2 -= onlyOne || lastTab ? borderThinkness : 0; + } + + p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.window()); + + // Delete border + if (selected) { + p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.window()); + p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.window()); + } + // Left + if (firstTab || selected || onlyOne || !previousSelected) { + p->setPen(light); + p->drawLine(x1, y1 + 2, x1, y2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness)); + p->drawPoint(x1 + 1, y1 + 1); + } + // Top + { + int beg = x1 + (previousSelected ? 0 : 2); + int end = x2 - (nextSelected ? 0 : 2); + p->setPen(light); + p->drawLine(beg, y1, end, y1); + } + // Right + if (lastTab || selected || onlyOne || !nextSelected) { + p->setPen(shadow); + p->drawLine(x2, y1 + 2, x2, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness)); + p->drawPoint(x2 - 1, y1 + 1); + p->setPen(dark); + p->drawLine(x2 - 1, y1 + 2, x2 - 1, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness)); + } + break; } + case QTabBar::RoundedSouth: { + if (!selected) { + y2 -= 2; + x1 += firstTab ? borderThinkness : 0; + x2 -= lastTab ? borderThinkness : 0; + } + + p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window()); + + // Delete border + if (selected) { + p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.window()); + p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->palette.window()); + } + // Left + if (firstTab || selected || onlyOne || !previousSelected) { + p->setPen(light); + p->drawLine(x1, y2 - 2, x1, y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness)); + p->drawPoint(x1 + 1, y2 - 1); + } + // Bottom + { + int beg = x1 + (previousSelected ? 0 : 2); + int end = x2 - (nextSelected ? 0 : 2); + p->setPen(shadow); + p->drawLine(beg, y2, end, y2); + p->setPen(dark); + p->drawLine(beg, y2 - 1, end, y2 - 1); + } + // Right + if (lastTab || selected || onlyOne || !nextSelected) { + p->setPen(shadow); + p->drawLine(x2, y2 - 2, x2, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness)); + p->drawPoint(x2 - 1, y2 - 1); + p->setPen(dark); + p->drawLine(x2 - 1, y2 - 2, x2 - 1, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness)); + } + break; } + case QTabBar::RoundedWest: { + if (!selected) { + x1 += 2; + y1 += firstTab ? borderThinkness : 0; + y2 -= lastTab ? borderThinkness : 0; + } + + p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.window()); + + // Delete border + if (selected) { + p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.window()); + p->fillRect(QRect(x2, y1, 1, y2-y1), tab->palette.window()); + } + // Top + if (firstTab || selected || onlyOne || !previousSelected) { + p->setPen(light); + p->drawLine(x1 + 2, y1, x2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1); + p->drawPoint(x1 + 1, y1 + 1); + } + // Left + { + int beg = y1 + (previousSelected ? 0 : 2); + int end = y2 - (nextSelected ? 0 : 2); + p->setPen(light); + p->drawLine(x1, beg, x1, end); + } + // Bottom + if (lastTab || selected || onlyOne || !nextSelected) { + p->setPen(shadow); + p->drawLine(x1 + 3, y2, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2); + p->drawPoint(x1 + 2, y2 - 1); + p->setPen(dark); + p->drawLine(x1 + 3, y2 - 1, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1); + p->drawPoint(x1 + 1, y2 - 1); + p->drawPoint(x1 + 2, y2); + } + break; } + case QTabBar::RoundedEast: { + if (!selected) { + x2 -= 2; + y1 += firstTab ? borderThinkness : 0; + y2 -= lastTab ? borderThinkness : 0; + } + + p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window()); + + // Delete border + if (selected) { + p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.window()); + p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.window()); + } + // Top + if (firstTab || selected || onlyOne || !previousSelected) { + p->setPen(light); + p->drawLine(x2 - 2, y1, x1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1); + p->drawPoint(x2 - 1, y1 + 1); + } + // Right + { + int beg = y1 + (previousSelected ? 0 : 2); + int end = y2 - (nextSelected ? 0 : 2); + p->setPen(shadow); + p->drawLine(x2, beg, x2, end); + p->setPen(dark); + p->drawLine(x2 - 1, beg, x2 - 1, end); + } + // Bottom + if (lastTab || selected || onlyOne || !nextSelected) { + p->setPen(shadow); + p->drawLine(x2 - 2, y2, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2); + p->drawPoint(x2 - 1, y2 - 1); + p->setPen(dark); + p->drawLine(x2 - 2, y2 - 1, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1); + } + break; } + } + } + break; +#endif // QT_CONFIG(tabbar) + case CE_ToolBoxTabShape: + qDrawShadePanel(p, opt->rect, opt->palette, + opt->state & (State_Sunken | State_On), 1, + &opt->palette.brush(QPalette::Button)); + break; +#if 0 && QT_CONFIG(splitter) + case CE_Splitter: + p->eraseRect(opt->rect); + break; +#endif // QT_CONFIG(splitter) +#if 0 && QT_CONFIG(scrollbar) + case CE_ScrollBarSubLine: + case CE_ScrollBarAddLine: { + if ((opt->state & State_Sunken)) { + p->setPen(opt->palette.dark().color()); + p->setBrush(opt->palette.brush(QPalette::Button)); + p->drawRect(opt->rect.adjusted(0, 0, -1, -1)); + } else { + QStyleOption buttonOpt = *opt; + if (!(buttonOpt.state & State_Sunken)) + buttonOpt.state |= State_Raised; + QPalette pal(opt->palette); + pal.setColor(QPalette::Button, opt->palette.light().color()); + pal.setColor(QPalette::Light, opt->palette.button().color()); + qDrawWinButton(p, opt->rect, pal, opt->state & (State_Sunken | State_On), + &opt->palette.brush(QPalette::Button)); + } + PrimitiveElement arrow; + if (opt->state & State_Horizontal) { + if (ce == CE_ScrollBarAddLine) + arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft; + else + arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight; + } else { + if (ce == CE_ScrollBarAddLine) + arrow = PE_IndicatorArrowDown; + else + arrow = PE_IndicatorArrowUp; + } + QStyleOption arrowOpt = *opt; + arrowOpt.rect = opt->rect.adjusted(4, 4, -4, -4); + proxy()->drawPrimitive(arrow, &arrowOpt, p, widget); + break; } + case CE_ScrollBarAddPage: + case CE_ScrollBarSubPage: { + QBrush br; + QBrush bg = p->background(); + Qt::BGMode bg_mode = p->backgroundMode(); + p->setPen(Qt::NoPen); + p->setBackgroundMode(Qt::OpaqueMode); + + if (opt->state & State_Sunken) { + br = QBrush(opt->palette.shadow().color(), Qt::Dense4Pattern); + p->setBackground(opt->palette.dark().color()); + p->setBrush(br); + } else { + const QBrush paletteBrush = opt->palette.brush(QPalette::Light); + if (paletteBrush.style() == Qt::TexturePattern) { + if (qHasPixmapTexture(paletteBrush)) + br = QBrush(paletteBrush.texture()); + else + br = QBrush(paletteBrush.textureImage()); + } else + br = QBrush(opt->palette.light().color(), Qt::Dense4Pattern); + p->setBackground(opt->palette.window().color()); + p->setBrush(br); + } + p->drawRect(opt->rect); + p->setBackground(bg); + p->setBackgroundMode(bg_mode); + break; } + case CE_ScrollBarSlider: + if (!(opt->state & State_Enabled)) { + QBrush br; + const QBrush paletteBrush = opt->palette.brush(QPalette::Light); + if (paletteBrush.style() == Qt::TexturePattern) { + if (qHasPixmapTexture(paletteBrush)) + br = QBrush(paletteBrush.texture()); + else + br = QBrush(paletteBrush.textureImage()); + } else + br = QBrush(opt->palette.light().color(), Qt::Dense4Pattern); + p->setPen(Qt::NoPen); + p->setBrush(br); + p->setBackgroundMode(Qt::OpaqueMode); + p->drawRect(opt->rect); + } else { + QStyleOptionButton buttonOpt; + buttonOpt.QStyleOption::operator=(*opt); + buttonOpt.state = State_Enabled | State_Raised; + + QPalette pal(opt->palette); + pal.setColor(QPalette::Button, opt->palette.light().color()); + pal.setColor(QPalette::Light, opt->palette.button().color()); + qDrawWinButton(p, opt->rect, pal, false, &opt->palette.brush(QPalette::Button)); + } + break; +#endif // QT_CONFIG(scrollbar) + case CE_HeaderSection: { + QBrush fill; + if (opt->state & State_On) + fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern); + else + fill = opt->palette.brush(QPalette::Button); + + if (opt->state & (State_Raised | State_Sunken)) { + qDrawWinButton(p, opt->rect, opt->palette, opt->state & State_Sunken, &fill); + } else { + p->fillRect(opt->rect, fill); + } + break; } +#if 0 && QT_CONFIG(toolbar) + case CE_ToolBar: + if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) { + // Reserve the beveled appearance only for mainwindow toolbars + if (!(widget && qobject_cast<const QMainWindow*> (widget->parentWidget()))) + break; + + QRect rect = opt->rect; + bool paintLeftBorder = true; + bool paintRightBorder = true; + bool paintBottomBorder = true; + + switch (toolbar->toolBarArea){ + case Qt::BottomToolBarArea : + switch (toolbar->positionOfLine){ + case QStyleOptionToolBar::Beginning: + case QStyleOptionToolBar::OnlyOne: + paintBottomBorder = false; + break; + default: + break; + } + Q_FALLTHROUGH(); // It continues in the end of the next case + case Qt::TopToolBarArea : + switch (toolbar->positionWithinLine){ + case QStyleOptionToolBar::Beginning: + paintLeftBorder = false; + break; + case QStyleOptionToolBar::End: + paintRightBorder = false; + break; + case QStyleOptionToolBar::OnlyOne: + paintRightBorder = false; + paintLeftBorder = false; + break; + default: + break; + } + if (opt->direction == Qt::RightToLeft){ //reverse layout changes the order of Beginning/end + bool tmp = paintLeftBorder; + paintRightBorder=paintLeftBorder; + paintLeftBorder=tmp; + } + break; + case Qt::RightToolBarArea : + switch (toolbar->positionOfLine){ + case QStyleOptionToolBar::Beginning: + case QStyleOptionToolBar::OnlyOne: + paintRightBorder = false; + break; + default: + break; + } + break; + case Qt::LeftToolBarArea : + switch (toolbar->positionOfLine){ + case QStyleOptionToolBar::Beginning: + case QStyleOptionToolBar::OnlyOne: + paintLeftBorder = false; + break; + default: + break; + } + break; + default: + break; + } + + + //draw top border + p->setPen(QPen(opt->palette.light().color())); + p->drawLine(rect.topLeft().x(), + rect.topLeft().y(), + rect.topRight().x(), + rect.topRight().y()); + + if (paintLeftBorder){ + p->setPen(QPen(opt->palette.light().color())); + p->drawLine(rect.topLeft().x(), + rect.topLeft().y(), + rect.bottomLeft().x(), + rect.bottomLeft().y()); + } + + if (paintRightBorder){ + p->setPen(QPen(opt->palette.dark().color())); + p->drawLine(rect.topRight().x(), + rect.topRight().y(), + rect.bottomRight().x(), + rect.bottomRight().y()); + } + + if (paintBottomBorder){ + p->setPen(QPen(opt->palette.dark().color())); + p->drawLine(rect.bottomLeft().x(), + rect.bottomLeft().y(), + rect.bottomRight().x(), + rect.bottomRight().y()); + } + } + break; + + +#endif // QT_CONFIG(toolbar) + + case CE_ProgressBarContents: + if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) { + QRect rect = pb->rect; + if (!rect.isValid()) + return; + + const bool vertical = !(pb->state & QStyle::State_Horizontal); + const bool inverted = pb->invertedAppearance; + + QTransform m; + if (vertical) { + rect = QRect(rect.y(), rect.x(), rect.height(), rect.width()); // flip width and height + m.rotate(90); + m.translate(0, -(rect.height() + rect.y()*2)); + } + QPalette pal2 = pb->palette; + // Correct the highlight color if it is the same as the background + if (pal2.highlight() == pal2.window()) + pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active, + QPalette::Highlight)); + bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical); + if (inverted) + reverse = !reverse; + int w = rect.width(); + Q_D(const QWindowsStyle); + if (pb->minimum == 0 && pb->maximum == 0) { + const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, pb); + QStyleOptionProgressBar pbBits = *pb; + Q_ASSERT(unit_width >0); + + pbBits.rect = rect; + pbBits.palette = pal2; + + int step = 0; + int chunkCount = w / unit_width + 1; +#if 0 && QT_CONFIG(animation) + if (QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(d->animation(opt->styleObject))) + step = (animation->animationStep() / 3) % chunkCount; + else + d->startAnimation(new QProgressStyleAnimation(d->animationFps, opt->styleObject)); +#else + Q_UNUSED(d); +#endif + int chunksInRow = 5; + int myY = pbBits.rect.y(); + int myHeight = pbBits.rect.height(); + int chunksToDraw = chunksInRow; + + if (step > chunkCount - 5)chunksToDraw = (chunkCount - step); + p->save(); + p->setClipRect(m.mapRect(QRectF(rect)).toRect()); + + int x0 = reverse ? rect.left() + rect.width() - unit_width*(step) - unit_width : rect.left() + unit_width * step; + int x = 0; + + for (int i = 0; i < chunksToDraw ; ++i) { + pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight); + pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect(); + proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p); + x += reverse ? -unit_width : unit_width; + } + //Draw wrap-around chunks + if ( step > chunkCount-5){ + x0 = reverse ? rect.left() + rect.width() - unit_width : rect.left() ; + x = 0; + int chunksToDraw = step - (chunkCount - chunksInRow); + for (int i = 0; i < chunksToDraw ; ++i) { + pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight); + pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect(); + proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p); + x += reverse ? -unit_width : unit_width; + } + } + p->restore(); //restore state + } + else { +#if 0 && QT_CONFIG(animation) + d->stopAnimation(opt->styleObject); +#endif + QCommonStyle::drawControl(ce, opt, p); + } + } + break; + +#if 0 && QT_CONFIG(dockwidget) + case CE_DockWidgetTitle: + + if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) { + Q_D(const QWindowsStyle); + + const bool verticalTitleBar = dwOpt->verticalTitleBar; + + QRect rect = dwOpt->rect; + QRect r = rect; + + if (verticalTitleBar) { + r = r.transposed(); + + p->save(); + p->translate(r.left(), r.top() + r.width()); + p->rotate(-90); + p->translate(-r.left(), -r.top()); + } + + bool floating = false; + bool active = dwOpt->state & State_Active; + QColor inactiveCaptionTextColor = d->inactiveCaptionText; + if (dwOpt->movable) { + QColor left, right; + + //Titlebar gradient + if (opt->state & QStyle::State_Window) { + floating = true; + if (active) { + left = d->activeCaptionColor; + right = d->activeGradientCaptionColor; + } else { + left = d->inactiveCaptionColor; + right = d->inactiveGradientCaptionColor; + } + QBrush fillBrush(left); + if (left != right) { + QPoint p1(r.x(), r.top() + r.height()/2); + QPoint p2(rect.right(), r.top() + r.height()/2); + QLinearGradient lg(p1, p2); + lg.setColorAt(0, left); + lg.setColorAt(1, right); + fillBrush = lg; + } + p->fillRect(r.adjusted(0, 0, 0, -3), fillBrush); + } + } + if (!dwOpt->title.isEmpty()) { + QFont oldFont = p->font(); + if (floating) { + QFont font = oldFont; + font.setBold(true); + p->setFont(font); + } + QPalette palette = dwOpt->palette; + palette.setColor(QPalette::Window, inactiveCaptionTextColor); + QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, opt, widget); + if (verticalTitleBar) { + titleRect = QRect(r.left() + rect.bottom() + - titleRect.bottom(), + r.top() + titleRect.left() - rect.left(), + titleRect.height(), titleRect.width()); + } + proxy()->drawItemText(p, titleRect, + Qt::AlignLeft | Qt::AlignVCenter, palette, + dwOpt->state & State_Enabled, dwOpt->title, + floating ? (active ? QPalette::BrightText : QPalette::Window) : QPalette::WindowText); + p->setFont(oldFont); + } + if (verticalTitleBar) + p->restore(); + } + return; +#endif // QT_CONFIG(dockwidget) +#if 0 && QT_CONFIG(combobox) + case CE_ComboBoxLabel: + if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + if (cb->state & State_HasFocus) { + p->setPen(cb->palette.highlightedText().color()); + p->setBackground(cb->palette.highlight()); + } else { + p->setPen(cb->palette.text().color()); + p->setBackground(cb->palette.window()); + } + } + QCommonStyle::drawControl(ce, opt, p, widget); + break; +#endif // QT_CONFIG(combobox) + default: + QCommonStyle::drawControl(ce, opt, p); + } +} + +/*! \reimp */ +QRect QWindowsStyle::subElementRect(SubElement sr, const QStyleOption *opt) const +{ + QRect r; + switch (sr) { + case SE_SliderFocusRect: + case SE_ToolBoxTabContents: + r = visualRect(opt->direction, opt->rect, opt->rect); + break; + case SE_DockWidgetTitleBarText: { + r = QCommonStyle::subElementRect(sr, opt); + const QStyleOptionDockWidget *dwOpt + = qstyleoption_cast<const QStyleOptionDockWidget*>(opt); + const bool verticalTitleBar = dwOpt && dwOpt->verticalTitleBar; + int m = proxy()->pixelMetric(PM_DockWidgetTitleMargin, opt); + if (verticalTitleBar) { + r.adjust(0, 0, 0, -m); + } else { + if (opt->direction == Qt::LeftToRight) + r.adjust(m, 0, 0, 0); + else + r.adjust(0, 0, -m, 0); + } + break; + } + case SE_ProgressBarContents: + r = QCommonStyle::subElementRect(SE_ProgressBarGroove, opt); + r.adjust(3, 3, -3, -3); + break; + default: + r = QCommonStyle::subElementRect(sr, opt); + } + return r; +} + + +/*! \reimp */ +void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, + QPainter *p) const +{ +#if 0 + switch (cc) { +#if QT_CONFIG(slider) + case CC_Slider: + if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider); + int len = proxy()->pixelMetric(PM_SliderLength, slider); + int ticks = slider->tickPosition; + QRect groove = proxy()->subControlRect(CC_Slider, slider, SC_SliderGroove); + QRect handle = proxy()->subControlRect(CC_Slider, slider, SC_SliderHandle); + + if ((slider->subControls & SC_SliderGroove) && groove.isValid()) { + int mid = thickness / 2; + + if (ticks & QStyleOptionSlider::TicksAbove) + mid += len / 8; + if (ticks & QStyleOptionSlider::TicksBelow) + mid -= len / 8; + + p->setPen(slider->palette.shadow().color()); + if (slider->orientation == Qt::Horizontal) { + qDrawWinPanel(p, groove.x(), groove.y() + mid - 2, + groove.width(), 4, slider->palette, true); + p->drawLine(groove.x() + 1, groove.y() + mid - 1, + groove.x() + groove.width() - 3, groove.y() + mid - 1); + } else { + qDrawWinPanel(p, groove.x() + mid - 2, groove.y(), + 4, groove.height(), slider->palette, true); + p->drawLine(groove.x() + mid - 1, groove.y() + 1, + groove.x() + mid - 1, groove.y() + groove.height() - 3); + } + } + + if (slider->subControls & SC_SliderTickmarks) { + QStyleOptionSlider tmpSlider = *slider; + tmpSlider.subControls = SC_SliderTickmarks; + QCommonStyle::drawComplexControl(cc, &tmpSlider, p); + } + + if (slider->subControls & SC_SliderHandle) { + // 4444440 + // 4333310 + // 4322210 + // 4322210 + // 4322210 + // 4322210 + // *43210* + // **410** + // ***0*** + const QColor c0 = slider->palette.shadow().color(); + const QColor c1 = slider->palette.dark().color(); + // const QColor c2 = g.button(); + const QColor c3 = slider->palette.midlight().color(); + const QColor c4 = slider->palette.light().color(); + QBrush handleBrush; + + if (slider->state & State_Enabled) { + handleBrush = slider->palette.color(QPalette::Button); + } else { + handleBrush = QBrush(slider->palette.color(QPalette::Button), + Qt::Dense4Pattern); + } + + + int x = handle.x(), y = handle.y(), + wi = handle.width(), he = handle.height(); + + int x1 = x; + int x2 = x+wi-1; + int y1 = y; + int y2 = y+he-1; + + Qt::Orientation orient = slider->orientation; + bool tickAbove = slider->tickPosition == QStyleOptionSlider::TicksAbove; + bool tickBelow = slider->tickPosition == QStyleOptionSlider::TicksBelow; + + if (slider->state & State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*slider); + fropt.rect = subElementRect(SE_SliderFocusRect, slider); + proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p); + } + + if ((tickAbove && tickBelow) || (!tickAbove && !tickBelow)) { + Qt::BGMode oldMode = p->backgroundMode(); + p->setBackgroundMode(Qt::OpaqueMode); + qDrawWinButton(p, QRect(x, y, wi, he), slider->palette, false, + &handleBrush); + p->setBackgroundMode(oldMode); + return; + } + + QSliderDirection dir; + + if (orient == Qt::Horizontal) + if (tickAbove) + dir = SlUp; + else + dir = SlDown; + else + if (tickAbove) + dir = SlLeft; + else + dir = SlRight; + + QPolygon a; + + int d = 0; + switch (dir) { + case SlUp: + y1 = y1 + wi/2; + d = (wi + 1) / 2 - 1; + a.setPoints(5, x1,y1, x1,y2, x2,y2, x2,y1, x1+d,y1-d); + break; + case SlDown: + y2 = y2 - wi/2; + d = (wi + 1) / 2 - 1; + a.setPoints(5, x1,y1, x1,y2, x1+d,y2+d, x2,y2, x2,y1); + break; + case SlLeft: + d = (he + 1) / 2 - 1; + x1 = x1 + he/2; + a.setPoints(5, x1,y1, x1-d,y1+d, x1,y2, x2,y2, x2,y1); + break; + case SlRight: + d = (he + 1) / 2 - 1; + x2 = x2 - he/2; + a.setPoints(5, x1,y1, x1,y2, x2,y2, x2+d,y1+d, x2,y1); + break; + } + + QBrush oldBrush = p->brush(); + p->setPen(Qt::NoPen); + p->setBrush(handleBrush); + Qt::BGMode oldMode = p->backgroundMode(); + p->setBackgroundMode(Qt::OpaqueMode); + p->drawRect(x1, y1, x2-x1+1, y2-y1+1); + p->drawPolygon(a); + p->setBrush(oldBrush); + p->setBackgroundMode(oldMode); + + if (dir != SlUp) { + p->setPen(c4); + p->drawLine(x1, y1, x2, y1); + p->setPen(c3); + p->drawLine(x1, y1+1, x2, y1+1); + } + if (dir != SlLeft) { + p->setPen(c3); + p->drawLine(x1+1, y1+1, x1+1, y2); + p->setPen(c4); + p->drawLine(x1, y1, x1, y2); + } + if (dir != SlRight) { + p->setPen(c0); + p->drawLine(x2, y1, x2, y2); + p->setPen(c1); + p->drawLine(x2-1, y1+1, x2-1, y2-1); + } + if (dir != SlDown) { + p->setPen(c0); + p->drawLine(x1, y2, x2, y2); + p->setPen(c1); + p->drawLine(x1+1, y2-1, x2-1, y2-1); + } + + switch (dir) { + case SlUp: + p->setPen(c4); + p->drawLine(x1, y1, x1+d, y1-d); + p->setPen(c0); + d = wi - d - 1; + p->drawLine(x2, y1, x2-d, y1-d); + d--; + p->setPen(c3); + p->drawLine(x1+1, y1, x1+1+d, y1-d); + p->setPen(c1); + p->drawLine(x2-1, y1, x2-1-d, y1-d); + break; + case SlDown: + p->setPen(c4); + p->drawLine(x1, y2, x1+d, y2+d); + p->setPen(c0); + d = wi - d - 1; + p->drawLine(x2, y2, x2-d, y2+d); + d--; + p->setPen(c3); + p->drawLine(x1+1, y2, x1+1+d, y2+d); + p->setPen(c1); + p->drawLine(x2-1, y2, x2-1-d, y2+d); + break; + case SlLeft: + p->setPen(c4); + p->drawLine(x1, y1, x1-d, y1+d); + p->setPen(c0); + d = he - d - 1; + p->drawLine(x1, y2, x1-d, y2-d); + d--; + p->setPen(c3); + p->drawLine(x1, y1+1, x1-d, y1+1+d); + p->setPen(c1); + p->drawLine(x1, y2-1, x1-d, y2-1-d); + break; + case SlRight: + p->setPen(c4); + p->drawLine(x2, y1, x2+d, y1+d); + p->setPen(c0); + d = he - d - 1; + p->drawLine(x2, y2, x2+d, y2-d); + d--; + p->setPen(c3); + p->drawLine(x2, y1+1, x2+d, y1+1+d); + p->setPen(c1); + p->drawLine(x2, y2-1, x2+d, y2-1-d); + break; + } + } + } + break; +#endif // QT_CONFIG(slider) +#if QT_CONFIG(scrollbar) + case CC_ScrollBar: + if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + QStyleOptionSlider newScrollbar = *scrollbar; + if (scrollbar->minimum == scrollbar->maximum) + newScrollbar.state &= ~State_Enabled; //do not draw the slider. + QCommonStyle::drawComplexControl(cc, &newScrollbar, p, widget); + } + break; +#endif // QT_CONFIG(scrollbar) +#if QT_CONFIG(combobox) + case CC_ComboBox: + if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { + QBrush editBrush = cmb->palette.brush(QPalette::Button); + if ((cmb->subControls & SC_ComboBoxFrame)) { + if (cmb->frame) { + QPalette shadePal = opt->palette; + shadePal.setColor(QPalette::Midlight, shadePal.button().color()); + qDrawWinPanel(p, opt->rect, shadePal, true, &editBrush); + } + else { + p->fillRect(opt->rect, editBrush); + } + } + if (cmb->subControls & SC_ComboBoxArrow) { + State flags = State_None; + + QRect ar = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget); + bool sunkenArrow = cmb->activeSubControls == SC_ComboBoxArrow + && cmb->state & State_Sunken; + if (sunkenArrow) { + p->setPen(cmb->palette.dark().color()); + p->setBrush(cmb->palette.brush(QPalette::Button)); + p->drawRect(ar.adjusted(0,0,-1,-1)); + } else { + // Make qDrawWinButton use the right colors for drawing the shade of the button + QPalette pal(cmb->palette); + pal.setColor(QPalette::Button, cmb->palette.light().color()); + pal.setColor(QPalette::Light, cmb->palette.button().color()); + qDrawWinButton(p, ar, pal, false, + &cmb->palette.brush(QPalette::Button)); + } + + ar.adjust(2, 2, -2, -2); + if (opt->state & State_Enabled) + flags |= State_Enabled; + if (opt->state & State_HasFocus) + flags |= State_HasFocus; + + if (sunkenArrow) + flags |= State_Sunken; + QStyleOption arrowOpt = *cmb; + arrowOpt.rect = ar.adjusted(1, 1, -1, -1); + arrowOpt.state = flags; + proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget); + } + + if (cmb->subControls & SC_ComboBoxEditField) { + QRect re = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget); + if (cmb->state & State_HasFocus && !cmb->editable) + p->fillRect(re.x(), re.y(), re.width(), re.height(), + cmb->palette.brush(QPalette::Highlight)); + + if (cmb->state & State_HasFocus) { + p->setPen(cmb->palette.highlightedText().color()); + p->setBackground(cmb->palette.highlight()); + + } else { + p->setPen(cmb->palette.text().color()); + p->setBackground(cmb->palette.window()); + } + + if (cmb->state & State_HasFocus && !cmb->editable) { + QStyleOptionFocusRect focus; + focus.QStyleOption::operator=(*cmb); + focus.rect = subElementRect(SE_ComboBoxFocusRect, cmb, widget); + focus.state |= State_FocusAtBorder; + focus.backgroundColor = cmb->palette.highlight().color(); + proxy()->drawPrimitive(PE_FrameFocusRect, &focus, p, widget); + } + } + } + break; +#endif // QT_CONFIG(combobox) +#if QT_CONFIG(spinbox) + case CC_SpinBox: + if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { + QStyleOptionSpinBox copy = *sb; + PrimitiveElement pe; + bool enabled = opt->state & State_Enabled; + if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) { + QBrush editBrush = sb->palette.brush(QPalette::Base); + QRect r = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxFrame, widget); + QPalette shadePal = sb->palette; + shadePal.setColor(QPalette::Midlight, shadePal.button().color()); + qDrawWinPanel(p, r, shadePal, true, &editBrush); + } + + QPalette shadePal(opt->palette); + shadePal.setColor(QPalette::Button, opt->palette.light().color()); + shadePal.setColor(QPalette::Light, opt->palette.button().color()); + + if (sb->subControls & SC_SpinBoxUp) { + copy.subControls = SC_SpinBoxUp; + QPalette pal2 = sb->palette; + if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled)) { + pal2.setCurrentColorGroup(QPalette::Disabled); + copy.state &= ~State_Enabled; + } + + copy.palette = pal2; + + if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) { + copy.state |= State_On; + copy.state |= State_Sunken; + } else { + copy.state |= State_Raised; + copy.state &= ~State_Sunken; + } + pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus + : PE_IndicatorSpinUp); + + copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget); + qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On), + ©.palette.brush(QPalette::Button)); + copy.rect.adjust(4, 1, -5, -1); + if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled)) + && proxy()->styleHint(SH_EtchDisabledText, opt, widget) ) + { + QStyleOptionSpinBox lightCopy = copy; + lightCopy.rect.adjust(1, 1, 1, 1); + lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light()); + proxy()->drawPrimitive(pe, &lightCopy, p, widget); + } + proxy()->drawPrimitive(pe, ©, p, widget); + } + + if (sb->subControls & SC_SpinBoxDown) { + copy.subControls = SC_SpinBoxDown; + copy.state = sb->state; + QPalette pal2 = sb->palette; + if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled)) { + pal2.setCurrentColorGroup(QPalette::Disabled); + copy.state &= ~State_Enabled; + } + copy.palette = pal2; + + if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) { + copy.state |= State_On; + copy.state |= State_Sunken; + } else { + copy.state |= State_Raised; + copy.state &= ~State_Sunken; + } + pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus + : PE_IndicatorSpinDown); + + copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget); + qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On), + ©.palette.brush(QPalette::Button)); + copy.rect.adjust(4, 0, -5, -1); + if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled)) + && proxy()->styleHint(SH_EtchDisabledText, opt, widget) ) + { + QStyleOptionSpinBox lightCopy = copy; + lightCopy.rect.adjust(1, 1, 1, 1); + lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light()); + proxy()->drawPrimitive(pe, &lightCopy, p, widget); + } + proxy()->drawPrimitive(pe, ©, p, widget); + } + } + break; +#endif // QT_CONFIG(spinbox) + default: + QCommonStyle::drawComplexControl(cc, opt, p); + } +#else // 0 + QCommonStyle::drawComplexControl(cc, opt, p); +#endif +} + +/*! \reimp */ +QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &csz) const +{ + QSize sz(csz); + switch (ct) { + case CT_PushButton: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + sz = QCommonStyle::sizeFromContents(ct, opt, csz); + int w = sz.width(), + h = sz.height(); + int defwidth = 0; + if (btn->features & QStyleOptionButton::AutoDefaultButton) + defwidth = 2 * proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn); + const qreal dpi = QStyleHelper::dpi(opt); + int minwidth = int(QStyleHelper::dpiScaled(75, dpi)); + int minheight = int(QStyleHelper::dpiScaled(23, dpi)); + +#ifndef QT_QWS_SMALL_PUSHBUTTON + if (w < minwidth + defwidth && !btn->text.isEmpty()) + w = minwidth + defwidth; + if (h < minheight + defwidth) + h = minheight + defwidth; +#endif + sz = QSize(w, h); + } + break; +#if 0 && QT_CONFIG(menu) + case CT_MenuItem: + if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { + int w = sz.width(); + sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget); + + if (mi->menuItemType == QStyleOptionMenuItem::Separator) { + sz = QSize(10, QWindowsStylePrivate::windowsSepHeight); + } + else if (mi->icon.isNull()) { + sz.setHeight(sz.height() - 2); + w -= 6; + } + + if (mi->menuItemType != QStyleOptionMenuItem::Separator && !mi->icon.isNull()) { + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt, widget); + sz.setHeight(qMax(sz.height(), + mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + + 2 * QWindowsStylePrivate::windowsItemFrame)); + } + int maxpmw = mi->maxIconWidth; + int tabSpacing = 20; + if (mi->text.contains(QLatin1Char('\t'))) + w += tabSpacing; + else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu) + w += 2 * QWindowsStylePrivate::windowsArrowHMargin; + else if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem) { + // adjust the font and add the difference in size. + // it would be better if the font could be adjusted in the initStyleOption qmenu func!! + QFontMetrics fm(mi->font); + QFont fontBold = mi->font; + fontBold.setBold(true); + QFontMetrics fmBold(fontBold); + w += fmBold.horizontalAdvance(mi->text) - fm.horizontalAdvance(mi->text); + } + + int checkcol = qMax<int>(maxpmw, QWindowsStylePrivate::windowsCheckMarkWidth); // Windows always shows a check column + w += checkcol; + w += int(QWindowsStylePrivate::windowsRightBorder) + 10; + sz.setWidth(w); + } + break; +#endif // QT_CONFIG(menu) +#if 0 && QT_CONFIG(menubar) + case CT_MenuBarItem: + if (!sz.isEmpty()) + sz += QSize(QWindowsStylePrivate::windowsItemHMargin * 4, QWindowsStylePrivate::windowsItemVMargin * 2); + break; +#endif + case CT_ToolButton: + if (qstyleoption_cast<const QStyleOptionToolButton *>(opt)) + return sz += QSize(7, 6); + Q_FALLTHROUGH(); + + default: + sz = QCommonStyle::sizeFromContents(ct, opt, csz); + } + return sz; +} + +/*! + \reimp +*/ +QIcon QWindowsStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option) const +{ + return QCommonStyle::standardIcon(standardIcon, option); +} + +} // namespace QQC2 + +QT_END_NAMESPACE + +#include "moc_qquickwindowsstyle_p.cpp" diff --git a/src/quicknativestyle/qstyle/windows/qquickwindowsstyle_p.h b/src/quicknativestyle/qstyle/windows/qquickwindowsstyle_p.h new file mode 100644 index 00000000000..92926b71294 --- /dev/null +++ b/src/quicknativestyle/qstyle/windows/qquickwindowsstyle_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module 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 QQUICKWINDOWSSTYLE_P_H +#define QQUICKWINDOWSSTYLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquickcommonstyle.h" + +QT_BEGIN_NAMESPACE + +class QPalette; + +namespace QQC2 { + +class QStyleOptionButton; +class QWindowsStylePrivate; + +class QWindowsStylePrivate; + +class QWindowsStyle : public QCommonStyle +{ + Q_OBJECT +public: + QWindowsStyle(); + ~QWindowsStyle() override; +/* + void polish(QApplication*) override; + void unpolish(QApplication*) override; + + void polish(QWidget*) override; + void unpolish(QWidget*) override; + + void polish(QPalette &) override; +*/ + void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p) const override; + void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p) const override; + void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p) const override; + + QRect subElementRect(SubElement r, const QStyleOption *opt) const override; + QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize) const override; + + int pixelMetric(PixelMetric pm, const QStyleOption *option = nullptr) const override; + + int styleHint(StyleHint hint, const QStyleOption *opt = nullptr, + QStyleHintReturn *returnData = nullptr) const override; + + QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt) const override; + + QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr) const override; + +protected: +// bool eventFilter(QObject *o, QEvent *e) override; + QWindowsStyle(QWindowsStylePrivate &dd); + +private: + Q_DISABLE_COPY_MOVE(QWindowsStyle) + Q_DECLARE_PRIVATE(QWindowsStyle) +}; + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif // QQUICKWINDOWSSTYLE_P_H diff --git a/src/quicknativestyle/qstyle/windows/qquickwindowsstyle_p_p.h b/src/quicknativestyle/qstyle/windows/qquickwindowsstyle_p_p.h new file mode 100644 index 00000000000..64b95a4016d --- /dev/null +++ b/src/quicknativestyle/qstyle/windows/qquickwindowsstyle_p_p.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module 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 QQUICKWINDOWSSTYLE_P_P_H +#define QQUICKWINDOWSSTYLE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of XX. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include "qquickwindowsstyle_p.h" +#include "qquickcommonstyle_p.h" +#include "qquickstylehelper_p.h" + +QT_BEGIN_NAMESPACE + +namespace QQC2 { + +class QStyleOptionButton; +class QWindowsStylePrivate; + +#include <qlist.h> + +class QTime; + +class QWindowsStylePrivate : public QCommonStylePrivate +{ + Q_DECLARE_PUBLIC(QWindowsStyle) +public: + enum { InvalidMetric = -23576 }; + + QWindowsStylePrivate(); + static int pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option = nullptr); + static int fixedPixelMetric(QStyle::PixelMetric pm); + static qreal devicePixelRatio(const QStyleOption *option = nullptr) + { + return devicePixelRatio(option ? option->window : nullptr); + } + + static qreal devicePixelRatio(const QWindow *win) + { return win ? win->devicePixelRatio() : QWindowsStylePrivate::appDevicePixelRatio(); } + static qreal nativeMetricScaleFactor(const QStyleOption *option = nullptr); + static qreal nativeMetricScaleFactor(const QWindow *win); + static bool isDarkMode(); + +#if 0 + bool hasSeenAlt(const QWidget *widget) const; + bool altDown() const { return alt_down; } + bool alt_down = false; +#endif + QList<const QWidget *> seenAlt; + int menuBarTimer = 0; + + QColor inactiveCaptionText; + QColor activeCaptionColor; + QColor activeGradientCaptionColor; + QColor inactiveCaptionColor; + QColor inactiveGradientCaptionColor; + + enum { + windowsItemFrame = 2, // menu item frame width + windowsSepHeight = 9, // separator item height + windowsItemHMargin = 3, // menu item hor text margin + windowsItemVMargin = 2, // menu item ver text margin + windowsArrowHMargin = 6, // arrow horizontal margin + windowsRightBorder = 15, // right border on windows + windowsCheckMarkWidth = 12 // checkmarks width on windows + }; + +private: + static qreal appDevicePixelRatio(); +}; + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif //QQUICKWINDOWSSTYLE_P_P_H + diff --git a/src/quicknativestyle/qstyle/windows/qquickwindowsvistastyle.cpp b/src/quicknativestyle/qstyle/windows/qquickwindowsvistastyle.cpp new file mode 100644 index 00000000000..c815b23f041 --- /dev/null +++ b/src/quicknativestyle/qstyle/windows/qquickwindowsvistastyle.cpp @@ -0,0 +1,2494 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module 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 "qquickwindowsvistastyle_p.h" +#include "qquickwindowsvistastyle_p_p.h" +#include <qoperatingsystemversion.h> +#include <qscreen.h> +#include <qwindow.h> +#include <private/qstyleanimation_p.h> +#include <private/qstylehelper_p.h> +#include <qpa/qplatformnativeinterface.h> + +QT_BEGIN_NAMESPACE + +static const int windowsItemFrame = 2; // menu item frame width +static const int windowsItemHMargin = 3; // menu item hor text margin +static const int windowsItemVMargin = 4; // menu item ver text margin +static const int windowsArrowHMargin = 6; // arrow horizontal margin +static const int windowsRightBorder = 15; // right border on windows + +#ifndef TMT_CONTENTMARGINS +# define TMT_CONTENTMARGINS 3602 +#endif +#ifndef TMT_SIZINGMARGINS +# define TMT_SIZINGMARGINS 3601 +#endif +#ifndef LISS_NORMAL +# define LISS_NORMAL 1 +# define LISS_HOT 2 +# define LISS_SELECTED 3 +# define LISS_DISABLED 4 +# define LISS_SELECTEDNOTFOCUS 5 +# define LISS_HOTSELECTED 6 +#endif +#ifndef BP_COMMANDLINK +# define BP_COMMANDLINK 6 +# define BP_COMMANDLINKGLYPH 7 +# define CMDLGS_NORMAL 1 +# define CMDLGS_HOT 2 +# define CMDLGS_PRESSED 3 +# define CMDLGS_DISABLED 4 +#endif + +/* \internal + Checks if we should use Vista style , or if we should + fall back to Windows style. +*/ +bool QWindowsVistaStylePrivate::useVista() +{ + return QWindowsVistaStylePrivate::useXP(); +} + +/* \internal + Checks and returns the style object +*/ +inline QObject *styleObject(const QStyleOption *option) { + return option ? option->styleObject : nullptr; +} + +/* \internal + Checks if we can animate on a style option +*/ +bool canAnimate(const QStyleOption *option) { + return option + && option->styleObject + && !option->styleObject->property("_q_no_animation").toBool(); +} + +static inline QImage createAnimationBuffer(const QStyleOption *option, const QWidget *widget) +{ + const int devicePixelRatio = widget ? widget->devicePixelRatio() : 1; + QImage result(option->rect.size() * devicePixelRatio, QImage::Format_ARGB32_Premultiplied); + result.setDevicePixelRatio(devicePixelRatio); + result.fill(0); + return result; +} + +/* \internal + Used by animations to clone a styleoption and shift its offset +*/ +QStyleOption *clonedAnimationStyleOption(const QStyleOption*option) { + QStyleOption *styleOption = nullptr; + if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) + styleOption = new QStyleOptionSlider(*slider); + else if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox*>(option)) + styleOption = new QStyleOptionSpinBox(*spinbox); + else if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox*>(option)) + styleOption = new QStyleOptionGroupBox(*groupBox); + else if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option)) + styleOption = new QStyleOptionComboBox(*combo); + else if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option)) + styleOption = new QStyleOptionButton(*button); + else + styleOption = new QStyleOption(*option); + styleOption->rect = QRect(QPoint(0,0), option->rect.size()); + return styleOption; +} + +/* \internal + Used by animations to delete cloned styleoption +*/ +void deleteClonedAnimationStyleOption(const QStyleOption *option) +{ + if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) + delete slider; + else if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox*>(option)) + delete spinbox; + else if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox*>(option)) + delete groupBox; + else if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option)) + delete combo; + else if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option)) + delete button; + else + delete option; +} + +/*! + \class QWindowsVistaStyle + \brief The QWindowsVistaStyle class provides a look and feel suitable for applications on Microsoft Windows Vista. + \since 4.3 + \ingroup appearance + \inmodule QtWidgets + \internal + + \warning This style is only available on the Windows Vista platform + because it makes use of Windows Vista's style engine. + + \sa QMacStyle, QWindowsXPStyle, QFusionStyle +*/ + +/*! + Constructs a QWindowsVistaStyle object. +*/ +QWindowsVistaStyle::QWindowsVistaStyle() + : QWindowsXPStyle(*new QWindowsVistaStylePrivate) +{ +} + +/*! + Destructor. +*/ +QWindowsVistaStyle::~QWindowsVistaStyle() = default; + +//convert Qt state flags to uxtheme button states +static int buttonStateId(int flags, int partId) +{ + int stateId = 0; + if (partId == BP_RADIOBUTTON || partId == BP_CHECKBOX) { + if (!(flags & QStyle::State_Enabled)) + stateId = RBS_UNCHECKEDDISABLED; + else if (flags & QStyle::State_Sunken) + stateId = RBS_UNCHECKEDPRESSED; + else if (flags & QStyle::State_MouseOver) + stateId = RBS_UNCHECKEDHOT; + else + stateId = RBS_UNCHECKEDNORMAL; + + if (flags & QStyle::State_On) + stateId += RBS_CHECKEDNORMAL-1; + + } else if (partId == BP_PUSHBUTTON) { + if (!(flags & QStyle::State_Enabled)) + stateId = PBS_DISABLED; + else if (flags & (QStyle::State_Sunken | QStyle::State_On)) + stateId = PBS_PRESSED; + else if (flags & QStyle::State_MouseOver) + stateId = PBS_HOT; + else + stateId = PBS_NORMAL; + } else { + Q_ASSERT(1); + } + return stateId; +} + +bool QWindowsVistaAnimation::isUpdateNeeded() const +{ + return QWindowsVistaStylePrivate::useVista(); +} + +void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option) +{ + painter->drawImage(option->rect, currentImage()); +} + +static inline bool supportsStateTransition(QStyle::PrimitiveElement element, + const QStyleOption *option, + const QWidget *widget) +{ + bool result = false; + switch (element) { + case QStyle::PE_IndicatorRadioButton: + case QStyle::PE_IndicatorCheckBox: + result = true; + break; + // QTBUG-40634, do not animate when color is set in palette for PE_PanelLineEdit. + case QStyle::PE_FrameLineEdit: + result = !QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget); + break; + default: + break; + } + return result; +} + +/*! + \internal + + Animations are used for some state transitions on specific widgets. + + Only one running animation can exist for a widget at any specific + time. Animations can be added through + QWindowsVistaStylePrivate::startAnimation(Animation *) and any + existing animation on a widget can be retrieved with + QWindowsVistaStylePrivate::widgetAnimation(Widget *). + + Once an animation has been started, + QWindowsVistaStylePrivate::timerEvent(QTimerEvent *) will + continuously call update() on the widget until it is stopped, + meaning that drawPrimitive will be called many times until the + transition has completed. During this time, the result will be + retrieved by the Animation::paint(...) function and not by the style + itself. + + To determine if a transition should occur, the style needs to know + the previous state of the widget as well as the current one. This is + solved by updating dynamic properties on the widget every time the + function is called. + + Transitions interrupting existing transitions should always be + smooth, so whenever a hover-transition is started on a pulsating + button, it uses the current frame of the pulse-animation as the + starting image for the hover transition. + + */ + +void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget) const +{ + QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func()); + + int state = option->state; + if (!QWindowsVistaStylePrivate::useVista()) { + QWindowsStyle::drawPrimitive(element, option, painter, widget); + return; + } + + if ((option->state & State_Enabled) && d->transitionsEnabled() && canAnimate(option)) { + { + QRect oldRect; + QRect newRect; + + if (supportsStateTransition(element, option, widget)) { + // Retrieve and update the dynamic properties tracking + // the previous state of the widget: + QObject *styleObject = option->styleObject; + styleObject->setProperty("_q_no_animation", true); + + int oldState = styleObject->property("_q_stylestate").toInt(); + oldRect = styleObject->property("_q_stylerect").toRect(); + newRect = option->rect; + styleObject->setProperty("_q_stylestate", int(option->state)); + styleObject->setProperty("_q_stylerect", option->rect); + + bool doTransition = oldState && + ((state & State_Sunken) != (oldState & State_Sunken) || + (state & State_On) != (oldState & State_On) || + (state & State_MouseOver) != (oldState & State_MouseOver)); + + if (oldRect != newRect || + (state & State_Enabled) != (oldState & State_Enabled) || + (state & State_Active) != (oldState & State_Active)) + d->stopAnimation(styleObject); + + if (option->state & State_ReadOnly && element == PE_FrameLineEdit) // Do not animate read only line edits + doTransition = false; + + if (doTransition) { + QStyleOption *styleOption = clonedAnimationStyleOption(option); + styleOption->state = QStyle::State(oldState); + + QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject)); + QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject); + + // We create separate images for the initial and final transition states and store them in the + // Transition object. + QImage startImage = createAnimationBuffer(option, widget); + QPainter startPainter(&startImage); + + QImage endImage = createAnimationBuffer(option, widget); + QPainter endPainter(&endImage); + + // If we have a running animation on the widget already, we will use that to paint the initial + // state of the new transition, this ensures a smooth transition from a current animation such as a + // pulsating default button into the intended target state. + if (!anim) + proxy()->drawPrimitive(element, styleOption, &startPainter, widget); + else + anim->paint(&startPainter, styleOption); + + t->setStartImage(startImage); + + // The end state of the transition is simply the result we would have painted + // if the style was not animated. + styleOption->styleObject = nullptr; + styleOption->state = option->state; + proxy()->drawPrimitive(element, styleOption, &endPainter, widget); + + + t->setEndImage(endImage); + + HTHEME theme; + int partId; + DWORD duration; + int fromState = 0; + int toState = 0; + + //translate state flags to UXTHEME states : + if (element == PE_FrameLineEdit) { + theme = OpenThemeData(nullptr, L"Edit"); + partId = EP_EDITBORDER_NOSCROLL; + + if (oldState & State_MouseOver) + fromState = ETS_HOT; + else if (oldState & State_HasFocus) + fromState = ETS_FOCUSED; + else + fromState = ETS_NORMAL; + + if (state & State_MouseOver) + toState = ETS_HOT; + else if (state & State_HasFocus) + toState = ETS_FOCUSED; + else + toState = ETS_NORMAL; + + } else { + theme = OpenThemeData(nullptr, L"Button"); + if (element == PE_IndicatorRadioButton) + partId = BP_RADIOBUTTON; + else if (element == PE_IndicatorCheckBox) + partId = BP_CHECKBOX; + else + partId = BP_PUSHBUTTON; + + fromState = buttonStateId(oldState, partId); + toState = buttonStateId(option->state, partId); + } + + // Retrieve the transition time between the states from the system. + if (theme + && SUCCEEDED(GetThemeTransitionDuration(theme, partId, fromState, toState, + TMT_TRANSITIONDURATIONS, &duration))) { + t->setDuration(int(duration)); + } + t->setStartTime(QTime::currentTime()); + + deleteClonedAnimationStyleOption(styleOption); + d->startAnimation(t); + } + styleObject->setProperty("_q_no_animation", false); + } + + } // End of animation part + } + + QRect rect = option->rect; + + switch (element) { + case PE_IndicatorHeaderArrow: + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { + int stateId = HSAS_SORTEDDOWN; + if (header->sortIndicator & QStyleOptionHeader::SortDown) + stateId = HSAS_SORTEDUP; //note that the uxtheme sort down indicator is the inverse of ours + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::HeaderTheme, + HP_HEADERSORTARROW, stateId, option->rect); + d->drawBackground(theme); + } + break; + + case PE_IndicatorBranch: + { + XPThemeData theme(widget, painter, QWindowsXPStylePrivate::VistaTreeViewTheme); + static int decoration_size = 0; + if (!decoration_size && theme.isValid()) { + XPThemeData themeSize = theme; + themeSize.partId = TVP_HOTGLYPH; + themeSize.stateId = GLPS_OPENED; + const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + decoration_size = qRound(qMax(size.width(), size.height())); + } + int mid_h = option->rect.x() + option->rect.width() / 2; + int mid_v = option->rect.y() + option->rect.height() / 2; + int bef_h = mid_h; + int bef_v = mid_v; + int aft_h = mid_h; + int aft_v = mid_v; + if (option->state & State_Children) { + int delta = decoration_size / 2; + theme.rect = QRect(bef_h - delta, bef_v - delta, decoration_size, decoration_size); + theme.partId = option->state & State_MouseOver ? TVP_HOTGLYPH : TVP_GLYPH; + theme.stateId = option->state & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED; + if (option->direction == Qt::RightToLeft) + theme.mirrorHorizontally = true; + d->drawBackground(theme); + bef_h -= delta + 2; + bef_v -= delta + 2; + aft_h += delta - 2; + aft_v += delta - 2; + } +#if 0 + QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern); + if (option->state & State_Item) { + if (option->direction == Qt::RightToLeft) + painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush); + else + painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush); + } + if (option->state & State_Sibling && option->rect.bottom() > aft_v) + painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush); + if (option->state & (State_Open | State_Children | State_Item | State_Sibling) && (bef_v > option->rect.y())) + painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush); +#endif + } + break; + + case PE_PanelButtonBevel: + case PE_IndicatorCheckBox: + case PE_IndicatorRadioButton: + { + if (QWindowsVistaAnimation *a = + qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option)))){ + a->paint(painter, option); + } else { + QWindowsXPStyle::drawPrimitive(element, option, painter, widget); + } + } + break; + + case PE_FrameMenu: + { + int stateId = option->state & State_Active ? MB_ACTIVE : MB_INACTIVE; + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPBORDERS, stateId, option->rect); + d->drawBackground(theme); + } + break; + case PE_Frame: { +#ifndef QT_NO_ACCESSIBILITY + if (QStyleHelper::isInstanceOf(option->styleObject, QAccessible::EditableText) + || QStyleHelper::isInstanceOf(option->styleObject, QAccessible::StaticText) || +#else + if ( +#endif + (widget && widget->inherits("QTextEdit"))) { + painter->save(); + int stateId = ETS_NORMAL; + if (!(state & State_Enabled)) + stateId = ETS_DISABLED; + else if (state & State_ReadOnly) + stateId = ETS_READONLY; + else if (state & State_HasFocus) + stateId = ETS_SELECTED; + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::EditTheme, + EP_EDITBORDER_HVSCROLL, stateId, option->rect); + // Since EP_EDITBORDER_HVSCROLL does not us borderfill, theme.noContent cannot be used for clipping + int borderSize = 1; + GetThemeInt(theme.handle(), theme.partId, theme.stateId, TMT_BORDERSIZE, &borderSize); + QRegion clipRegion = option->rect; + QRegion content = option->rect.adjusted(borderSize, borderSize, -borderSize, -borderSize); + clipRegion ^= content; + painter->setClipRegion(clipRegion); + d->drawBackground(theme); + painter->restore(); + } else { + QWindowsXPStyle::drawPrimitive(element, option, painter, widget); + } + } + break; + + case PE_PanelLineEdit: + if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) { + bool isEnabled = option->state & State_Enabled; + if (QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget)) { + painter->fillRect(panel->rect, panel->palette.brush(QPalette::Base)); + } else { + int partId = EP_BACKGROUND; + int stateId = EBS_NORMAL; + if (!isEnabled) + stateId = EBS_DISABLED; + else if (state & State_ReadOnly) + stateId = EBS_READONLY; + else if (state & State_MouseOver) + stateId = EBS_HOT; + + XPThemeData theme(nullptr, painter, QWindowsXPStylePrivate::EditTheme, + partId, stateId, rect); + if (!theme.isValid()) { + QWindowsStyle::drawPrimitive(element, option, painter, widget); + return; + } + int bgType; + GetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &bgType); + if ( bgType == BT_IMAGEFILE ) { + d->drawBackground(theme); + } else { + QBrush fillColor = option->palette.brush(QPalette::Base); + if (!isEnabled) { + PROPERTYORIGIN origin = PO_NOTFOUND; + GetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin); + // Use only if the fill property comes from our part + if ((origin == PO_PART || origin == PO_STATE)) { + COLORREF bgRef; + GetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef); + fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef))); + } + } + painter->fillRect(option->rect, fillColor); + } + } + if (panel->lineWidth > 0) + proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget); + return; + } + break; + + case PE_FrameLineEdit: + if (QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option)))) { + anim->paint(painter, option); + } else { + QPainter *p = painter; + if (QWindowsXPStylePrivate::isItemViewDelegateLineEdit(widget)) { + // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class. + QPen oldPen = p->pen(); + // Inner white border + p->setPen(QPen(option->palette.base().color(), 1)); + p->drawRect(option->rect.adjusted(1, 1, -2, -2)); + // Outer dark border + p->setPen(QPen(option->palette.shadow().color(), 1)); + p->drawRect(option->rect.adjusted(0, 0, -1, -1)); + p->setPen(oldPen); + return; + } + int stateId = ETS_NORMAL; + if (!(state & State_Enabled)) + stateId = ETS_DISABLED; + else if (state & State_ReadOnly) + stateId = ETS_READONLY; + else if (state & State_MouseOver) + stateId = ETS_HOT; + else if (state & State_HasFocus) + stateId = ETS_SELECTED; + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::EditTheme, + EP_EDITBORDER_NOSCROLL, stateId, option->rect); + theme.noContent = true; + painter->save(); + QRegion clipRegion = option->rect; + clipRegion -= option->rect.adjusted(2, 2, -2, -2); + painter->setClipRegion(clipRegion); + d->drawBackground(theme); + painter->restore(); + } + break; + + case PE_IndicatorToolBarHandle: + { + XPThemeData theme; + QRect rect; + if (option->state & State_Horizontal) { + theme = XPThemeData(widget, painter, + QWindowsXPStylePrivate::RebarTheme, + RP_GRIPPER, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2)); + rect = option->rect.adjusted(0, 1, 0, -2); + rect.setWidth(4); + } else { + theme = XPThemeData(widget, painter, QWindowsXPStylePrivate::RebarTheme, + RP_GRIPPERVERT, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2)); + rect = option->rect.adjusted(1, 0, -1, 0); + rect.setHeight(4); + } + theme.rect = rect; + d->drawBackground(theme); + } + break; + + case PE_IndicatorToolBarSeparator: + { + QPen pen = painter->pen(); + int margin = 3; + painter->setPen(option->palette.window().color().darker(114)); + if (option->state & State_Horizontal) { + int x1 = option->rect.center().x(); + painter->drawLine(QPoint(x1, option->rect.top() + margin), QPoint(x1, option->rect.bottom() - margin)); + } else { + int y1 = option->rect.center().y(); + painter->drawLine(QPoint(option->rect.left() + margin, y1), QPoint(option->rect.right() - margin, y1)); + } + painter->setPen(pen); + } + break; + + case PE_PanelTipLabel: { + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::ToolTipTheme, + TTP_STANDARD, TTSS_NORMAL, option->rect); + d->drawBackground(theme); + break; + } + + case PE_PanelItemViewItem: + { + const QStyleOptionViewItem *vopt; + bool newStyle = true; + QAbstractItemView::SelectionBehavior selectionBehavior = QAbstractItemView::SelectRows; + QAbstractItemView::SelectionMode selectionMode = QAbstractItemView::NoSelection; + if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget)) { + newStyle = !qobject_cast<const QTableView*>(view); + selectionBehavior = view->selectionBehavior(); + selectionMode = view->selectionMode(); +#ifndef QT_NO_ACCESSIBILITY + } else if (!widget) { + newStyle = !QStyleHelper::hasAncestor(option->styleObject, QAccessible::MenuItem) ; +#endif + } + + if (newStyle && (vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option))) { + bool selected = vopt->state & QStyle::State_Selected; + const bool hover = selectionMode != QAbstractItemView::NoSelection && (vopt->state & QStyle::State_MouseOver); + bool active = vopt->state & QStyle::State_Active; + + if (vopt->features & QStyleOptionViewItem::Alternate) + painter->fillRect(vopt->rect, vopt->palette.alternateBase()); + + QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled + ? QPalette::Normal : QPalette::Disabled; + if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active)) + cg = QPalette::Inactive; + + QRect itemRect = subElementRect(QStyle::SE_ItemViewItemFocusRect, option, widget).adjusted(-1, 0, 1, 0); + itemRect.setTop(vopt->rect.top()); + itemRect.setBottom(vopt->rect.bottom()); + + QSize sectionSize = itemRect.size(); + if (vopt->showDecorationSelected) + sectionSize = vopt->rect.size(); + + if (selectionBehavior == QAbstractItemView::SelectRows) + sectionSize.setWidth(vopt->rect.width()); + QPixmap pixmap; + + if (vopt->backgroundBrush.style() != Qt::NoBrush) { + const QPointF oldBrushOrigin = painter->brushOrigin(); + painter->setBrushOrigin(vopt->rect.topLeft()); + painter->fillRect(vopt->rect, vopt->backgroundBrush); + painter->setBrushOrigin(oldBrushOrigin); + } + + if (hover || selected) { + if (sectionSize.width() > 0 && sectionSize.height() > 0) { + QString key = QString::fromLatin1("qvdelegate-%1-%2-%3-%4-%5").arg(sectionSize.width()) + .arg(sectionSize.height()).arg(selected).arg(active).arg(hover); + if (!QPixmapCache::find(key, &pixmap)) { + pixmap = QPixmap(sectionSize); + pixmap.fill(Qt::transparent); + + int state; + if (selected && hover) + state = LISS_HOTSELECTED; + else if (selected && !active) + state = LISS_SELECTEDNOTFOCUS; + else if (selected) + state = LISS_SELECTED; + else + state = LISS_HOT; + + QPainter pixmapPainter(&pixmap); + XPThemeData theme(widget, &pixmapPainter, + QWindowsXPStylePrivate::VistaTreeViewTheme, + LVP_LISTITEM, state, QRect(0, 0, sectionSize.width(), sectionSize.height())); + if (theme.isValid()) { + d->drawBackground(theme); + } else { + QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget); + break; + } + QPixmapCache::insert(key, pixmap); + } + } + + if (vopt->showDecorationSelected) { + const int frame = 2; //Assumes a 2 pixel pixmap border + QRect srcRect = QRect(0, 0, sectionSize.width(), sectionSize.height()); + QRect pixmapRect = vopt->rect; + bool reverse = vopt->direction == Qt::RightToLeft; + bool leftSection = vopt->viewItemPosition == QStyleOptionViewItem::Beginning; + bool rightSection = vopt->viewItemPosition == QStyleOptionViewItem::End; + if (vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne + || vopt->viewItemPosition == QStyleOptionViewItem::Invalid) + painter->drawPixmap(pixmapRect.topLeft(), pixmap); + else if (reverse ? rightSection : leftSection){ + painter->drawPixmap(QRect(pixmapRect.topLeft(), + QSize(frame, pixmapRect.height())), pixmap, + QRect(QPoint(0, 0), QSize(frame, pixmapRect.height()))); + painter->drawPixmap(pixmapRect.adjusted(frame, 0, 0, 0), + pixmap, srcRect.adjusted(frame, 0, -frame, 0)); + } else if (reverse ? leftSection : rightSection) { + painter->drawPixmap(QRect(pixmapRect.topRight() - QPoint(frame - 1, 0), + QSize(frame, pixmapRect.height())), pixmap, + QRect(QPoint(pixmapRect.width() - frame, 0), + QSize(frame, pixmapRect.height()))); + painter->drawPixmap(pixmapRect.adjusted(0, 0, -frame, 0), + pixmap, srcRect.adjusted(frame, 0, -frame, 0)); + } else if (vopt->viewItemPosition == QStyleOptionViewItem::Middle) + painter->drawPixmap(pixmapRect, pixmap, + srcRect.adjusted(frame, 0, -frame, 0)); + } else { + if (vopt->text.isEmpty() && vopt->icon.isNull()) + break; + painter->drawPixmap(itemRect.topLeft(), pixmap); + } + } + } else { + QWindowsXPStyle::drawPrimitive(element, option, painter, widget); + } + break; + } + case PE_Widget: + { +#if QT_CONFIG(dialogbuttonbox) + const QDialogButtonBox *buttonBox = nullptr; + + if (qobject_cast<const QMessageBox *> (widget)) + buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox")); +#if QT_CONFIG(inputdialog) + else if (qobject_cast<const QInputDialog *> (widget)) + buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox")); +#endif // QT_CONFIG(inputdialog) + + if (buttonBox) { + //draw white panel part + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::TaskDialogTheme, + TDLG_PRIMARYPANEL, 0, option->rect); + QRect toprect = option->rect; + toprect.setBottom(buttonBox->geometry().top()); + theme.rect = toprect; + d->drawBackground(theme); + + //draw bottom panel part + QRect buttonRect = option->rect; + buttonRect.setTop(buttonBox->geometry().top()); + theme.rect = buttonRect; + theme.partId = TDLG_SECONDARYPANEL; + d->drawBackground(theme); + } +#endif + } + break; + default: + QWindowsXPStyle::drawPrimitive(element, option, painter, widget); + break; + } +} + + +/*! + \internal + + see drawPrimitive for comments on the animation support + */ +void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget) const +{ + QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func()); + + if (!QWindowsVistaStylePrivate::useVista()) { + QWindowsStyle::drawControl(element, option, painter, widget); + return; + } + + bool selected = option->state & State_Selected; + bool pressed = option->state & State_Sunken; + bool disabled = !(option->state & State_Enabled); + + int state = option->state; + int themeNumber = -1; + + QRect rect(option->rect); + State flags = option->state; + int partId = 0; + int stateId = 0; + + if (d->transitionsEnabled() && canAnimate(option)) + { + if (element == CE_PushButtonBevel) { + QRect oldRect; + QRect newRect; + + QObject *styleObject = option->styleObject; + + int oldState = styleObject->property("_q_stylestate").toInt(); + oldRect = styleObject->property("_q_stylerect").toRect(); + newRect = option->rect; + styleObject->setProperty("_q_stylestate", int(option->state)); + styleObject->setProperty("_q_stylerect", option->rect); + + bool wasDefault = false; + bool isDefault = false; + if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) { + wasDefault = styleObject->property("_q_isdefault").toBool(); + isDefault = button->features & QStyleOptionButton::DefaultButton; + styleObject->setProperty("_q_isdefault", isDefault); + } + + bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) || + (state & State_On) != (oldState & State_On) || + (state & State_MouseOver) != (oldState & State_MouseOver)); + + if (oldRect != newRect || (wasDefault && !isDefault)) { + doTransition = false; + d->stopAnimation(styleObject); + } + + if (doTransition) { + styleObject->setProperty("_q_no_animation", true); + + QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject); + QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject)); + QStyleOption *styleOption = clonedAnimationStyleOption(option); + styleOption->state = QStyle::State(oldState); + + QImage startImage = createAnimationBuffer(option, widget); + QPainter startPainter(&startImage); + + // Use current state of existing animation if already one is running + if (!anim) { + proxy()->drawControl(element, styleOption, &startPainter, widget); + } else { + anim->paint(&startPainter, styleOption); + d->stopAnimation(styleObject); + } + + t->setStartImage(startImage); + QImage endImage = createAnimationBuffer(option, widget); + QPainter endPainter(&endImage); + styleOption->state = option->state; + proxy()->drawControl(element, styleOption, &endPainter, widget); + t->setEndImage(endImage); + + + DWORD duration = 0; + const HTHEME theme = OpenThemeData(nullptr, L"Button"); + + int fromState = buttonStateId(oldState, BP_PUSHBUTTON); + int toState = buttonStateId(option->state, BP_PUSHBUTTON); + if (GetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK) + t->setDuration(int(duration)); + else + t->setDuration(0); + t->setStartTime(QTime::currentTime()); + styleObject->setProperty("_q_no_animation", false); + + deleteClonedAnimationStyleOption(styleOption); + d->startAnimation(t); + } + + QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject)); + if (anim) { + anim->paint(painter, option); + return; + } + + } + } + switch (element) { + case CE_PushButtonBevel: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) + { + themeNumber = QWindowsXPStylePrivate::ButtonTheme; + partId = BP_PUSHBUTTON; + if (btn->features & QStyleOptionButton::CommandLinkButton) + partId = BP_COMMANDLINK; + bool justFlat = (btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken)); + if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat)) + stateId = PBS_DISABLED; + else if (justFlat) + ; + else if (flags & (State_Sunken | State_On)) + stateId = PBS_PRESSED; + else if (flags & State_MouseOver) + stateId = PBS_HOT; + else if (btn->features & QStyleOptionButton::DefaultButton && (state & State_Active)) + stateId = PBS_DEFAULTED; + else + stateId = PBS_NORMAL; + + if (!justFlat) { + + if (d->transitionsEnabled() && (btn->features & QStyleOptionButton::DefaultButton) && + !(state & (State_Sunken | State_On)) && !(state & State_MouseOver) && + (state & State_Enabled) && (state & State_Active)) + { + QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option))); + + if (!anim) { + QImage startImage = createAnimationBuffer(option, widget); + QImage alternateImage = createAnimationBuffer(option, widget); + + QWindowsVistaPulse *pulse = new QWindowsVistaPulse(styleObject(option)); + + QPainter startPainter(&startImage); + stateId = PBS_DEFAULTED; + XPThemeData theme(widget, &startPainter, themeNumber, partId, stateId, rect); + d->drawBackground(theme); + + QPainter alternatePainter(&alternateImage); + theme.stateId = PBS_DEFAULTED_ANIMATING; + theme.painter = &alternatePainter; + d->drawBackground(theme); + pulse->setStartImage(startImage); + pulse->setEndImage(alternateImage); + pulse->setStartTime(QTime::currentTime()); + pulse->setDuration(2000); + d->startAnimation(pulse); + anim = pulse; + } + + if (anim) + anim->paint(painter, option); + else { + XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect); + d->drawBackground(theme); + } + } + else { + XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect); + d->drawBackground(theme); + } + } + + if (btn->features & QStyleOptionButton::HasMenu) { + int mbiw = 0, mbih = 0; + XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::ToolBarTheme, + TP_DROPDOWNBUTTON); + if (theme.isValid()) { + const QSizeF size = theme.size() * QStyleHelper::dpiScaled(1, option); + if (!size.isEmpty()) { + mbiw = qRound(size.width()); + mbih = qRound(size.height()); + } + } + QRect ir = subElementRect(SE_PushButtonContents, option, nullptr); + QStyleOptionButton newBtn = *btn; + newBtn.rect = QStyle::visualRect(option->direction, option->rect, + QRect(ir.right() - mbiw - 2, + option->rect.top() + (option->rect.height()/2) - (mbih/2), + mbiw + 1, mbih + 1)); + proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget); + } + return; + } + break; + + case CE_ProgressBarContents: + if (const QStyleOptionProgressBar *bar + = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { + bool isIndeterminate = (bar->minimum == 0 && bar->maximum == 0); + const bool vertical = bar->orientation == Qt::Vertical; + const bool inverted = bar->invertedAppearance; + + if (isIndeterminate || (bar->progress > 0 && (bar->progress < bar->maximum) && d->transitionsEnabled())) { + if (!d->animation(styleObject(option))) + d->startAnimation(new QProgressStyleAnimation(d->animationFps, styleObject(option))); + } else { + d->stopAnimation(styleObject(option)); + } + + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::ProgressTheme, + vertical ? PP_FILLVERT : PP_FILL); + theme.rect = option->rect; + bool reverse = (bar->direction == Qt::LeftToRight && inverted) || (bar->direction == Qt::RightToLeft && !inverted); + QTime current = QTime::currentTime(); + + if (isIndeterminate) { + if (QProgressStyleAnimation *a = qobject_cast<QProgressStyleAnimation *>(d->animation(styleObject(option)))) { + int glowSize = 120; + int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width()); + int animOffset = a->startTime().msecsTo(current) / 4; + if (animOffset > animationWidth) + a->setStartTime(QTime::currentTime()); + painter->save(); + painter->setClipRect(theme.rect); + QRect animRect; + QSize pixmapSize(14, 14); + if (vertical) { + animRect = QRect(theme.rect.left(), + inverted ? rect.top() - glowSize + animOffset : + rect.bottom() + glowSize - animOffset, + rect.width(), glowSize); + pixmapSize.setHeight(animRect.height()); + } else { + animRect = QRect(rect.left() - glowSize + animOffset, + rect.top(), glowSize, rect.height()); + animRect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, + option->rect, animRect); + pixmapSize.setWidth(animRect.width()); + } + QString name = QString::fromLatin1("qiprogress-%1-%2").arg(pixmapSize.width()).arg(pixmapSize.height()); + QPixmap pixmap; + if (!QPixmapCache::find(name, &pixmap)) { + QImage image(pixmapSize, QImage::Format_ARGB32); + image.fill(Qt::transparent); + QPainter imagePainter(&image); + theme.painter = &imagePainter; + theme.partId = vertical ? PP_FILLVERT : PP_FILL; + theme.rect = QRect(QPoint(0,0), animRect.size()); + QLinearGradient alphaGradient(0, 0, vertical ? 0 : image.width(), + vertical ? image.height() : 0); + alphaGradient.setColorAt(0, QColor(0, 0, 0, 0)); + alphaGradient.setColorAt(0.5, QColor(0, 0, 0, 220)); + alphaGradient.setColorAt(1, QColor(0, 0, 0, 0)); + imagePainter.fillRect(image.rect(), alphaGradient); + imagePainter.setCompositionMode(QPainter::CompositionMode_SourceIn); + d->drawBackground(theme); + imagePainter.end(); + pixmap = QPixmap::fromImage(image); + QPixmapCache::insert(name, pixmap); + } + painter->drawPixmap(animRect, pixmap); + painter->restore(); + } + } + else { + qint64 progress = qMax<qint64>(bar->progress, bar->minimum); // workaround for bug in QProgressBar + + if (vertical) { + int maxHeight = option->rect.height(); + int minHeight = 0; + double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxHeight); + int height = isIndeterminate ? maxHeight: qMax(int(vc6_workaround), minHeight); + theme.rect.setHeight(height); + if (!inverted) + theme.rect.moveTop(rect.height() - theme.rect.height()); + } else { + int maxWidth = option->rect.width(); + int minWidth = 0; + double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth); + int width = isIndeterminate ? maxWidth : qMax(int(vc6_workaround), minWidth); + theme.rect.setWidth(width); + theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, + option->rect, theme.rect); + } + d->drawBackground(theme); + + if (QProgressStyleAnimation *a = qobject_cast<QProgressStyleAnimation *>(d->animation(styleObject(option)))) { + int glowSize = 140; + int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width()); + int animOffset = a->startTime().msecsTo(current) / 4; + theme.partId = vertical ? PP_MOVEOVERLAYVERT : PP_MOVEOVERLAY; + if (animOffset > animationWidth) { + if (bar->progress < bar->maximum) + a->setStartTime(QTime::currentTime()); + else + d->stopAnimation(styleObject(option)); //we stop the glow motion only after it has + //moved out of view + } + painter->save(); + painter->setClipRect(theme.rect); + if (vertical) { + theme.rect = QRect(theme.rect.left(), + inverted ? rect.top() - glowSize + animOffset : + rect.bottom() + glowSize - animOffset, + rect.width(), glowSize); + } else { + theme.rect = QRect(rect.left() - glowSize + animOffset,rect.top(), glowSize, rect.height()); + theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, option->rect, theme.rect); + } + d->drawBackground(theme); + painter->restore(); + } + } + } + break; + + case CE_MenuBarItem: + { + + if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) + { + if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem) + break; + + QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText; + QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal); + + int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; + if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget)) + alignment |= Qt::TextHideMnemonic; + + if (widget && mbi->palette.color(QPalette::Window) != Qt::transparent) { // Not needed for QtQuick Controls + //The rect adjustment is a workaround for the menu not really filling its background. + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_BARBACKGROUND, 0, option->rect.adjusted(-1, 0, 2, 1)); + d->drawBackground(theme); + } + + int stateId = MBI_NORMAL; + if (disabled) + stateId = MBI_DISABLED; + else if (pressed) + stateId = MBI_PUSHED; + else if (selected) + stateId = MBI_HOT; + + XPThemeData theme2(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_BARITEM, stateId, option->rect); + d->drawBackground(theme2); + + if (!pix.isNull()) + drawItemPixmap(painter, mbi->rect, alignment, pix); + else + drawItemText(painter, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole); + } + } + break; +#if QT_CONFIG(menu) + case CE_MenuItem: + if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { + // windows always has a check column, regardless whether we have an icon or not + const qreal factor = QWindowsXPStylePrivate::nativeMetricScaleFactor(widget); + int checkcol = qRound(qreal(25) * factor); + const int gutterWidth = qRound(qreal(3) * factor); + { + XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPCHECKBACKGROUND, MBI_HOT); + XPThemeData themeSize = theme; + themeSize.partId = MENU_POPUPCHECK; + themeSize.stateId = 0; + const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + checkcol = qMax(menuitem->maxIconWidth, qRound(gutterWidth + size.width() + margins.left() + margins.right())); + } + QRect rect = option->rect; + + //draw vertical menu line + if (option->direction == Qt::LeftToRight) + checkcol += rect.x(); + QPoint p1 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.top())); + QPoint p2 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.bottom())); + QRect gutterRect(p1.x(), p1.y(), gutterWidth, p2.y() - p1.y() + 1); + XPThemeData theme2(widget, painter, QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPGUTTER, stateId, gutterRect); + d->drawBackground(theme2); + + int x, y, w, h; + menuitem->rect.getRect(&x, &y, &w, &h); + int tab = menuitem->tabWidth; + bool dis = !(menuitem->state & State_Enabled); + bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable + ? menuitem->checked : false; + bool act = menuitem->state & State_Selected; + + if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { + int yoff = y-2 + h / 2; + const int separatorSize = qRound(qreal(6) * QWindowsStylePrivate::nativeMetricScaleFactor(widget)); + QPoint p1 = QPoint(x + checkcol, yoff); + QPoint p2 = QPoint(x + w + separatorSize, yoff); + stateId = MBI_HOT; + QRect subRect(p1.x() + (gutterWidth - menuitem->rect.x()), p1.y(), + p2.x() - p1.x(), separatorSize); + subRect = QStyle::visualRect(option->direction, option->rect, subRect ); + XPThemeData theme2(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPSEPARATOR, stateId, subRect); + d->drawBackground(theme2); + return; + } + + QRect vCheckRect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x(), + menuitem->rect.y(), checkcol - (gutterWidth + menuitem->rect.x()), menuitem->rect.height())); + + if (act) { + stateId = dis ? MBI_DISABLED : MBI_HOT; + XPThemeData theme2(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPITEM, stateId, option->rect); + d->drawBackground(theme2); + } + + if (checked) { + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPCHECKBACKGROUND, + menuitem->icon.isNull() ? MBI_HOT : MBI_PUSHED, vCheckRect); + XPThemeData themeSize = theme; + themeSize.partId = MENU_POPUPCHECK; + themeSize.stateId = 0; + const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + QRect checkRect(0, 0, qRound(size.width() + margins.left() + margins.right()), + qRound(size.height() + margins.bottom() + margins.top())); + checkRect.moveCenter(vCheckRect.center()); + theme.rect = checkRect; + + d->drawBackground(theme); + + if (menuitem->icon.isNull()) { + checkRect = QRect(QPoint(0, 0), size.toSize()); + checkRect.moveCenter(theme.rect.center()); + theme.rect = checkRect; + + theme.partId = MENU_POPUPCHECK; + bool bullet = menuitem->checkType & QStyleOptionMenuItem::Exclusive; + if (dis) + theme.stateId = bullet ? MC_BULLETDISABLED: MC_CHECKMARKDISABLED; + else + theme.stateId = bullet ? MC_BULLETNORMAL: MC_CHECKMARKNORMAL; + d->drawBackground(theme); + } + } + + if (!menuitem->icon.isNull()) { + QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal; + if (act && !dis) + mode = QIcon::Active; + QPixmap pixmap; + if (checked) + pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On); + else + pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode); + const int pixw = pixmap.width() / pixmap.devicePixelRatio(); + const int pixh = pixmap.height() / pixmap.devicePixelRatio(); + QRect pmr(0, 0, pixw, pixh); + pmr.moveCenter(vCheckRect.center()); + painter->setPen(menuitem->palette.text().color()); + painter->drawPixmap(pmr.topLeft(), pixmap); + } + + painter->setPen(menuitem->palette.buttonText().color()); + + const QColor textColor = menuitem->palette.text().color(); + if (dis) + painter->setPen(textColor); + + int xm = windowsItemFrame + checkcol + windowsItemHMargin + (gutterWidth - menuitem->rect.x()) - 1; + int xpos = menuitem->rect.x() + xm; + QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin); + QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect); + QString s = menuitem->text; + if (!s.isEmpty()) { // draw text + painter->save(); + int t = s.indexOf(QLatin1Char('\t')); + int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; + if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget)) + text_flags |= Qt::TextHideMnemonic; + text_flags |= Qt::AlignLeft; + if (t >= 0) { + QRect vShortcutRect = visualRect(option->direction, menuitem->rect, + QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom()))); + painter->drawText(vShortcutRect, text_flags, s.mid(t + 1)); + s = s.left(t); + } + QFont font = menuitem->font; + if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem) + font.setBold(true); + painter->setFont(font); + painter->setPen(textColor); + painter->drawText(vTextRect, text_flags, s.left(t)); + painter->restore(); + } + if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow + int dim = (h - 2 * windowsItemFrame) / 2; + PrimitiveElement arrow; + arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight; + xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim; + QRect vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim)); + QStyleOptionMenuItem newMI = *menuitem; + newMI.rect = vSubMenuRect; + newMI.state = dis ? State_None : State_Enabled; + proxy()->drawPrimitive(arrow, &newMI, painter, widget); + } + } + break; +#endif // QT_CONFIG(menu) + case CE_HeaderSection: + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { + partId = HP_HEADERITEM; + if (flags & State_Sunken) + stateId = HIS_PRESSED; + else if (flags & State_MouseOver) + stateId = HIS_HOT; + else + stateId = HIS_NORMAL; + + if (header->sortIndicator != QStyleOptionHeader::None) + stateId += 3; + + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::HeaderTheme, + partId, stateId, option->rect); + d->drawBackground(theme); + } + break; + case CE_MenuBarEmptyArea: + { + stateId = MBI_NORMAL; + if (!(state & State_Enabled)) + stateId = MBI_DISABLED; + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::MenuTheme, + MENU_BARBACKGROUND, stateId, option->rect); + d->drawBackground(theme); + } + break; + case CE_ToolBar: + if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) { + QPalette pal = option->palette; + pal.setColor(QPalette::Dark, option->palette.window().color().darker(130)); + QStyleOptionToolBar copyOpt = *toolbar; + copyOpt.palette = pal; + QWindowsStyle::drawControl(element, ©Opt, painter, widget); + } + break; +#if QT_CONFIG(dockwidget) + case CE_DockWidgetTitle: + if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) { + const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget); + QRect rect = option->rect; + if (dockWidget && dockWidget->isFloating()) { + QWindowsXPStyle::drawControl(element, option, painter, widget); + break; //otherwise fall through + } + + const bool verticalTitleBar = dwOpt->verticalTitleBar; + + if (verticalTitleBar) { + rect = rect.transposed(); + + painter->translate(rect.left() - 1, rect.top() + rect.width()); + painter->rotate(-90); + painter->translate(-rect.left() + 1, -rect.top()); + } + + painter->setBrush(option->palette.window().color().darker(110)); + painter->setPen(option->palette.window().color().darker(130)); + painter->drawRect(rect.adjusted(0, 1, -1, -3)); + + int buttonMargin = 4; + int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget); + int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget); + const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget); + bool isFloating = dw && dw->isFloating(); + + QRect r = option->rect.adjusted(0, 2, -1, -3); + QRect titleRect = r; + + if (dwOpt->closable) { + QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10)); + titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0); + } + + if (dwOpt->floatable) { + QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10)); + titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0); + } + + if (isFloating) { + titleRect.adjust(0, -fw, 0, 0); + if (widget && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey()) + titleRect.adjust(titleRect.height() + mw, 0, 0, 0); + } else { + titleRect.adjust(mw, 0, 0, 0); + if (!dwOpt->floatable && !dwOpt->closable) + titleRect.adjust(0, 0, -mw, 0); + } + if (!verticalTitleBar) + titleRect = visualRect(dwOpt->direction, r, titleRect); + + if (!dwOpt->title.isEmpty()) { + QString titleText = painter->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, + verticalTitleBar ? titleRect.height() : titleRect.width()); + const int indent = 4; + drawItemText(painter, rect.adjusted(indent + 1, 1, -indent - 1, -1), + Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, + dwOpt->palette, + dwOpt->state & State_Enabled, titleText, + QPalette::WindowText); + } + } + break; +#endif // QT_CONFIG(dockwidget) +#if QT_CONFIG(itemviews) + case CE_ItemViewItem: + { + const QStyleOptionViewItem *vopt; + + const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget); + bool newStyle = true; + + if (qobject_cast<const QTableView*>(widget)) + newStyle = false; + + if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option))) { + /* + // We cannot currently get the correct selection color for "explorer style" views + COLORREF cref = 0; + XPThemeData theme(d->treeViewHelper(), 0, QLatin1String("LISTVIEW"), 0, 0); + unsigned int res = GetThemeColor(theme.handle(), LVP_LISTITEM, LISS_SELECTED, TMT_TEXTCOLOR, &cref); + QColor textColor(GetRValue(cref), GetGValue(cref), GetBValue(cref)); + */ + QPalette palette = vopt->palette; + palette.setColor(QPalette::All, QPalette::HighlightedText, palette.color(QPalette::Active, QPalette::Text)); + // Note that setting a saturated color here results in ugly XOR colors in the focus rect + palette.setColor(QPalette::All, QPalette::Highlight, palette.base().color().darker(108)); + QStyleOptionViewItem adjustedOption = *vopt; + adjustedOption.palette = palette; + // We hide the focusrect in singleselection as it is not required + if ((view->selectionMode() == QAbstractItemView::SingleSelection) + && !(vopt->state & State_KeyboardFocusChange)) + adjustedOption.state &= ~State_HasFocus; + QWindowsXPStyle::drawControl(element, &adjustedOption, painter, widget); + } else { + QWindowsXPStyle::drawControl(element, option, painter, widget); + } + break; + } +#endif // QT_CONFIG(itemviews) +#if QT_CONFIG(combobox) + case CE_ComboBoxLabel: + QCommonStyle::drawControl(element, option, painter, widget); + break; +#endif // QT_CONFIG(combobox) + default: + QWindowsXPStyle::drawControl(element, option, painter, widget); + break; + } +} + +/*! + \internal + + see drawPrimitive for comments on the animation support + + */ +void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget) const +{ + QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func()); + if (!QWindowsVistaStylePrivate::useVista()) { + QWindowsStyle::drawComplexControl(control, option, painter, widget); + return; + } + + State state = option->state; + SubControls sub = option->subControls; + QRect r = option->rect; + + int partId = 0; + int stateId = 0; + + State flags = option->state; + if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow()) + flags |= State_MouseOver; + + if (d->transitionsEnabled() && canAnimate(option)) + { + + if (control == CC_ScrollBar || control == CC_SpinBox || control == CC_ComboBox) { + + QObject *styleObject = option->styleObject; // Can be widget or qquickitem + + int oldState = styleObject->property("_q_stylestate").toInt(); + int oldActiveControls = styleObject->property("_q_stylecontrols").toInt(); + + QRect oldRect = styleObject->property("_q_stylerect").toRect(); + styleObject->setProperty("_q_stylestate", int(option->state)); + styleObject->setProperty("_q_stylecontrols", int(option->activeSubControls)); + styleObject->setProperty("_q_stylerect", option->rect); + + bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) || + (state & State_On) != (oldState & State_On) || + (state & State_MouseOver) != (oldState & State_MouseOver) || + oldActiveControls != int(option->activeSubControls)); + + if (qstyleoption_cast<const QStyleOptionSlider *>(option)) { + QRect oldSliderPos = styleObject->property("_q_stylesliderpos").toRect(); + QRect currentPos = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget); + styleObject->setProperty("_q_stylesliderpos", currentPos); + if (oldSliderPos != currentPos) { + doTransition = false; + d->stopAnimation(styleObject); + } + } else if (control == CC_SpinBox) { + //spinboxes have a transition when focus changes + if (!doTransition) + doTransition = (state & State_HasFocus) != (oldState & State_HasFocus); + } + + if (oldRect != option->rect) { + doTransition = false; + d->stopAnimation(styleObject); + } + + if (doTransition) { + QImage startImage = createAnimationBuffer(option, widget); + QPainter startPainter(&startImage); + + QImage endImage = createAnimationBuffer(option, widget); + QPainter endPainter(&endImage); + + QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject)); + QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject); + + // Draw the image that ends the animation by using the current styleoption + QStyleOptionComplex *styleOption = qstyleoption_cast<QStyleOptionComplex*>(clonedAnimationStyleOption(option)); + + styleObject->setProperty("_q_no_animation", true); + + // Draw transition source + if (!anim) { + styleOption->state = QStyle::State(oldState); + styleOption->activeSubControls = QStyle::SubControl(oldActiveControls); + proxy()->drawComplexControl(control, styleOption, &startPainter, widget); + } else { + anim->paint(&startPainter, option); + } + t->setStartImage(startImage); + + // Draw transition target + styleOption->state = option->state; + styleOption->activeSubControls = option->activeSubControls; + proxy()->drawComplexControl(control, styleOption, &endPainter, widget); + + styleObject->setProperty("_q_no_animation", false); + + t->setEndImage(endImage); + t->setStartTime(QTime::currentTime()); + + if (option->state & State_MouseOver || option->state & State_Sunken) + t->setDuration(150); + else + t->setDuration(500); + + deleteClonedAnimationStyleOption(styleOption); + d->startAnimation(t); + } + if (QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject))) { + anim->paint(painter, option); + return; + } + } + } + + switch (control) { + case CC_ComboBox: + if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) + { + if (cmb->editable) { + if (sub & SC_ComboBoxEditField) { + partId = EP_EDITBORDER_NOSCROLL; + if (!(flags & State_Enabled)) + stateId = ETS_DISABLED; + else if (flags & State_MouseOver) + stateId = ETS_HOT; + else if (flags & State_HasFocus) + stateId = ETS_FOCUSED; + else + stateId = ETS_NORMAL; + + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::EditTheme, + partId, stateId, r); + + d->drawBackground(theme); + } + if (sub & SC_ComboBoxArrow) { + QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget); + XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme); + theme.rect = subRect; + partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT; + + if (!(cmb->state & State_Enabled)) + stateId = CBXS_DISABLED; + else if (cmb->state & State_Sunken || cmb->state & State_On) + stateId = CBXS_PRESSED; + else if (cmb->state & State_MouseOver && option->activeSubControls & SC_ComboBoxArrow) + stateId = CBXS_HOT; + else + stateId = CBXS_NORMAL; + + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + + } else { + if (sub & SC_ComboBoxFrame) { + XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme); + theme.rect = option->rect; + theme.partId = CP_READONLY; + if (!(cmb->state & State_Enabled)) + theme.stateId = CBXS_DISABLED; + else if (cmb->state & State_Sunken || cmb->state & State_On) + theme.stateId = CBXS_PRESSED; + else if (cmb->state & State_MouseOver) + theme.stateId = CBXS_HOT; + else + theme.stateId = CBXS_NORMAL; + d->drawBackground(theme); + } + if (sub & SC_ComboBoxArrow) { + XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme); + theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget); + theme.partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT; + if (!(cmb->state & State_Enabled)) + theme.stateId = CBXS_DISABLED; + else + theme.stateId = CBXS_NORMAL; + d->drawBackground(theme); + } + if ((sub & SC_ComboBoxEditField) && (flags & State_HasFocus)) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*cmb); + fropt.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget); + proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } + } + } + break; + case CC_ScrollBar: + if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) + { + XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ScrollBarTheme); + bool maxedOut = (scrollbar->maximum == scrollbar->minimum); + if (maxedOut) + flags &= ~State_Enabled; + + bool isHorz = flags & State_Horizontal; + bool isRTL = option->direction == Qt::RightToLeft; + if (sub & SC_ScrollBarAddLine) { + theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget); + partId = SBP_ARROWBTN; + if (!(flags & State_Enabled)) + stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED); + else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken)) + stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED); + else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver)) + stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT); + else if (scrollbar->state & State_MouseOver) + stateId = (isHorz ? (isRTL ? ABS_LEFTHOVER : ABS_RIGHTHOVER) : ABS_DOWNHOVER); + else + stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL); + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + if (sub & SC_ScrollBarSubLine) { + theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget); + partId = SBP_ARROWBTN; + if (!(flags & State_Enabled)) + stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED); + else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken)) + stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED); + else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver)) + stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT); + else if (scrollbar->state & State_MouseOver) + stateId = (isHorz ? (isRTL ? ABS_RIGHTHOVER : ABS_LEFTHOVER) : ABS_UPHOVER); + else + stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL); + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + if (maxedOut) { + theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget); + theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget)); + theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget)); + partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT; + stateId = SCRBS_DISABLED; + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } else { + if (sub & SC_ScrollBarSubPage) { + theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget); + partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT; + if (!(flags & State_Enabled)) + stateId = SCRBS_DISABLED; + else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken)) + stateId = SCRBS_PRESSED; + else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver)) + stateId = SCRBS_HOT; + else + stateId = SCRBS_NORMAL; + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + if (sub & SC_ScrollBarAddPage) { + theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget); + partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT; + if (!(flags & State_Enabled)) + stateId = SCRBS_DISABLED; + else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken)) + stateId = SCRBS_PRESSED; + else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver)) + stateId = SCRBS_HOT; + else + stateId = SCRBS_NORMAL; + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + if (sub & SC_ScrollBarSlider) { + theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget); + if (!(flags & State_Enabled)) + stateId = SCRBS_DISABLED; + else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken)) + stateId = SCRBS_PRESSED; + else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver)) + stateId = SCRBS_HOT; + else if (option->state & State_MouseOver) + stateId = SCRBS_HOVER; + else + stateId = SCRBS_NORMAL; + + // Draw handle + theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT; + theme.stateId = stateId; + d->drawBackground(theme); + } + } + } + break; +#if QT_CONFIG(spinbox) + case CC_SpinBox: + if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) + { + XPThemeData theme(widget, painter, QWindowsXPStylePrivate::SpinTheme); + if (sb->frame && (sub & SC_SpinBoxFrame)) { + partId = EP_EDITBORDER_NOSCROLL; + if (!(flags & State_Enabled)) + stateId = ETS_DISABLED; + else if (flags & State_MouseOver) + stateId = ETS_HOT; + else if (flags & State_HasFocus) + stateId = ETS_SELECTED; + else + stateId = ETS_NORMAL; + + XPThemeData ftheme(widget, painter, + QWindowsXPStylePrivate::EditTheme, + partId, stateId, r); + // The spinbox in Windows QStyle is drawn with frameless QLineEdit inside it + // That however breaks with QtQuickControls where this results in transparent + // spinbox background, so if there's no "widget" passed (QtQuickControls case), + // let ftheme.noContent be false, which fixes the spinbox rendering in QQC + ftheme.noContent = (widget != nullptr); + d->drawBackground(ftheme); + } + if (sub & SC_SpinBoxUp) { + theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget).adjusted(0, 0, 0, 1); + partId = SPNP_UP; + if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled)) + stateId = UPS_DISABLED; + else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) + stateId = UPS_PRESSED; + else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver)) + stateId = UPS_HOT; + else + stateId = UPS_NORMAL; + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + if (sub & SC_SpinBoxDown) { + theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget); + partId = SPNP_DOWN; + if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled)) + stateId = DNS_DISABLED; + else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) + stateId = DNS_PRESSED; + else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver)) + stateId = DNS_HOT; + else + stateId = DNS_NORMAL; + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + } + break; +#endif // QT_CONFIG(spinbox) + default: + QWindowsXPStyle::drawComplexControl(control, option, painter, widget); + break; + } +} + +/*! + \internal + */ +QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption *option, + const QSize &size, const QWidget *widget) const +{ + if (!QWindowsVistaStylePrivate::useVista()) + return QWindowsStyle::sizeFromContents(type, option, size, widget); + + QSize sz(size); + switch (type) { + case CT_MenuItem: + sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget); + int minimumHeight; + { + XPThemeData theme(widget, nullptr, + QWindowsXPStylePrivate::MenuTheme, + MENU_POPUPCHECKBACKGROUND, MBI_HOT); + XPThemeData themeSize = theme; + themeSize.partId = MENU_POPUPCHECK; + themeSize.stateId = 0; + const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + minimumHeight = qMax(qRound(size.height() + margins.bottom() + margins.top()), sz.height()); + sz.rwidth() += qRound(size.width() + margins.left() + margins.right()); + } + + if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { + if (menuitem->menuItemType != QStyleOptionMenuItem::Separator) + sz.setHeight(minimumHeight); + } + return sz; +#if QT_CONFIG(menubar) + case CT_MenuBarItem: + if (!sz.isEmpty()) + sz += QSize(windowsItemHMargin * 5 + 1, 5); + return sz; +#endif + case CT_ItemViewItem: + sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget); + sz.rheight() += 2; + return sz; + case CT_SpinBox: + { + //Spinbox adds frame twice + sz = QWindowsStyle::sizeFromContents(type, option, size, widget); + int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget); + sz -= QSize(2*border, 2*border); + } + return sz; + case CT_HeaderSection: + { + // When there is a sort indicator it adds to the width but it is shown + // above the text natively and not on the side + if (QStyleOptionHeader *hdr = qstyleoption_cast<QStyleOptionHeader *>(const_cast<QStyleOption *>(option))) { + QStyleOptionHeader::SortIndicator sortInd = hdr->sortIndicator; + hdr->sortIndicator = QStyleOptionHeader::None; + sz = QWindowsXPStyle::sizeFromContents(type, hdr, size, widget); + hdr->sortIndicator = sortInd; + return sz; + } + break; + } + default: + break; + } + return QWindowsXPStyle::sizeFromContents(type, option, size, widget); +} + +/*! + \internal + */ +QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const +{ + if (!QWindowsVistaStylePrivate::useVista()) + return QWindowsStyle::subElementRect(element, option, widget); + + QRect rect = QWindowsXPStyle::subElementRect(element, option, widget); + switch (element) { + + case SE_PushButtonContents: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { + MARGINS borderSize; + const HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : nullptr, L"Button"); + if (theme) { + int stateId = PBS_NORMAL; + if (!(option->state & State_Enabled)) + stateId = PBS_DISABLED; + else if (option->state & State_Sunken) + stateId = PBS_PRESSED; + else if (option->state & State_MouseOver) + stateId = PBS_HOT; + else if (btn->features & QStyleOptionButton::DefaultButton) + stateId = PBS_DEFAULTED; + + int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget); + rect = option->rect.adjusted(border, border, -border, -border); + + if (SUCCEEDED(GetThemeMargins(theme, nullptr, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, nullptr, &borderSize))) { + rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight, + -borderSize.cxRightWidth, -borderSize.cyBottomHeight); + rect = visualRect(option->direction, option->rect, rect); + } + } + } + break; + + case SE_HeaderArrow: + { + QRect r = rect; + int h = option->rect.height(); + int w = option->rect.width(); + int x = option->rect.x(); + int y = option->rect.y(); + int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget); + + XPThemeData theme(widget, nullptr, + QWindowsXPStylePrivate::HeaderTheme, + HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect); + + int arrowWidth = 13; + int arrowHeight = 5; + if (theme.isValid()) { + const QSizeF size = theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + if (!size.isEmpty()) { + arrowWidth = qRound(size.width()); + arrowHeight = qRound(size.height()); + } + } + if (option->state & State_Horizontal) { + r.setRect(x + w/2 - arrowWidth/2, y , arrowWidth, arrowHeight); + } else { + int vert_size = w / 2; + r.setRect(x + 5, y + h - margin * 2 - vert_size, + w - margin * 2 - 5, vert_size); + } + rect = visualRect(option->direction, option->rect, r); + } + break; + + case SE_HeaderLabel: + { + int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget); + QRect r = option->rect; + r.setRect(option->rect.x() + margin, option->rect.y() + margin, + option->rect.width() - margin * 2, option->rect.height() - margin * 2); + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { + // Subtract width needed for arrow, if there is one + if (header->sortIndicator != QStyleOptionHeader::None) { + if (!(option->state & State_Horizontal)) //horizontal arrows are positioned on top + r.setHeight(r.height() - (option->rect.width() / 2) - (margin * 2)); + } + } + rect = visualRect(option->direction, option->rect, r); + } + break; + case SE_ProgressBarContents: + rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget); + break; + case SE_ItemViewItemDecoration: + if (qstyleoption_cast<const QStyleOptionViewItem *>(option)) + rect.adjust(-2, 0, 2, 0); + break; + case SE_ItemViewItemFocusRect: + if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option)) { + QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget); + QRect displayRect = subElementRect(QStyle::SE_ItemViewItemDecoration, option, widget); + if (!vopt->icon.isNull()) + rect = textRect.united(displayRect); + else + rect = textRect; + rect = rect.adjusted(1, 0, -1, 0); + } + break; + default: + break; + } + return rect; +} + + +/* + This function is used by subControlRect to check if a button + should be drawn for the given subControl given a set of window flags. +*/ +static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){ + + bool isMinimized = tb->titleBarState & Qt::WindowMinimized; + bool isMaximized = tb->titleBarState & Qt::WindowMaximized; + const auto flags = tb->titleBarFlags; + bool retVal = false; + switch (sc) { + case QStyle::SC_TitleBarContextHelpButton: + if (flags & Qt::WindowContextHelpButtonHint) + retVal = true; + break; + case QStyle::SC_TitleBarMinButton: + if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint)) + retVal = true; + break; + case QStyle::SC_TitleBarNormalButton: + if (isMinimized && (flags & Qt::WindowMinimizeButtonHint)) + retVal = true; + else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint)) + retVal = true; + break; + case QStyle::SC_TitleBarMaxButton: + if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint)) + retVal = true; + break; + case QStyle::SC_TitleBarShadeButton: + if (!isMinimized && flags & Qt::WindowShadeButtonHint) + retVal = true; + break; + case QStyle::SC_TitleBarUnshadeButton: + if (isMinimized && flags & Qt::WindowShadeButtonHint) + retVal = true; + break; + case QStyle::SC_TitleBarCloseButton: + if (flags & Qt::WindowSystemMenuHint) + retVal = true; + break; + case QStyle::SC_TitleBarSysMenu: + if (flags & Qt::WindowSystemMenuHint) + retVal = true; + break; + default : + retVal = true; + } + return retVal; +} + + +/*! \internal */ +int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, + QStyleHintReturn *returnData) const +{ + QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func()); + int ret = 0; + switch (hint) { + case SH_MessageBox_CenterButtons: + ret = false; + break; + case SH_ToolTip_Mask: + if (option) { + if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) { + ret = true; + XPThemeData themeData(widget, nullptr, + QWindowsXPStylePrivate::ToolTipTheme, + TTP_STANDARD, TTSS_NORMAL, option->rect); + mask->region = d->region(themeData); + } + } + break; + case SH_Table_GridLineColor: + if (option) + ret = int(option->palette.color(QPalette::Base).darker(118).rgba()); + else + ret = -1; + break; + case SH_Header_ArrowAlignment: + ret = Qt::AlignTop | Qt::AlignHCenter; + break; + default: + ret = QWindowsXPStyle::styleHint(hint, option, widget, returnData); + break; + } + return ret; +} + + +/*! + \internal + */ +QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option, + SubControl subControl, const QWidget *widget) const +{ + if (!QWindowsVistaStylePrivate::useVista()) + return QWindowsStyle::subControlRect(control, option, subControl, widget); + + QRect rect = QWindowsXPStyle::subControlRect(control, option, subControl, widget); + switch (control) { +#if QT_CONFIG(combobox) + case CC_ComboBox: + if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { + const int x = cb->rect.x(), y = cb->rect.y(), wi = cb->rect.width(), he = cb->rect.height(); + const int margin = cb->frame ? 3 : 0; + const int bmarg = cb->frame ? 2 : 0; + const int arrowWidth = qRound(QStyleHelper::dpiScaled(16, option)); + const int arrowButtonWidth = bmarg + arrowWidth; + const int xpos = x + wi - arrowButtonWidth; + + switch (subControl) { + case SC_ComboBoxFrame: + rect = cb->rect; + break; + case SC_ComboBoxArrow: + rect.setRect(xpos, y , arrowButtonWidth, he); + break; + case SC_ComboBoxEditField: + rect.setRect(x + margin, y + margin, wi - 2 * margin - arrowWidth, he - 2 * margin); + break; + case SC_ComboBoxListBoxPopup: + rect = cb->rect; + break; + default: + break; + } + rect = visualRect(cb->direction, cb->rect, rect); + return rect; + } + break; +#endif // QT_CONFIG(combobox) + case CC_TitleBar: + if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) { + if (!buttonVisible(subControl, tb)) + return rect; + const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget); + const bool isToolTitle = false; + const int height = tb->rect.height(); + const int width = tb->rect.width(); + const int buttonWidth = + qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor - QStyleHelper::dpiScaled(4, option)); + + const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget); + const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0; + const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0; + const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0; + const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0; + const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0; + + switch (subControl) { + case SC_TitleBarLabel: + rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height); + if (isToolTitle) { + if (sysmenuHint) { + rect.adjust(0, 0, int(-buttonWidth - 3 * factor), 0); + } + if (minimizeHint || maximizeHint) + rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0); + } else { + if (sysmenuHint) { + const int leftOffset = int(height - 8 * factor); + rect.adjust(leftOffset, 0, 0, int(4 * factor)); + } + if (minimizeHint) + rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0); + if (maximizeHint) + rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0); + if (contextHint) + rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0); + if (shadeHint) + rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0); + } + rect.translate(0, int(2 * factor)); + rect = visualRect(option->direction, option->rect, rect); + break; + case SC_TitleBarSysMenu: + { + const int controlTop = int(6 * factor); + const int controlHeight = int(height - controlTop - 3 * factor); + int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, option); + QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent)); + if (tb->icon.isNull()) + iconSize = QSize(controlHeight, controlHeight); + int hPad = (controlHeight - iconSize.height())/2; + int vPad = (controlHeight - iconSize.width())/2; + rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height()); + rect.translate(0, int(3 * factor)); + rect = visualRect(option->direction, option->rect, rect); + } + break; + default: + break; + } + } + break; + default: + break; + } + return rect; +} + +/*! + \internal + */ +QStyle::SubControl QWindowsVistaStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, + const QPoint &pos, const QWidget *widget) const +{ + if (!QWindowsVistaStylePrivate::useVista()) { + return QWindowsStyle::hitTestComplexControl(control, option, pos, widget); + } + return QWindowsXPStyle::hitTestComplexControl(control, option, pos, widget); +} + +int QWindowsVistaStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm) +{ + switch (pm) { + case QStyle::PM_DockWidgetTitleBarButtonMargin: + return 5; + case QStyle::PM_ScrollBarSliderMin: + return 18; + case QStyle::PM_MenuHMargin: + case QStyle::PM_MenuVMargin: + return 0; + case QStyle::PM_MenuPanelWidth: + return 3; + default: + break; + } + return QWindowsVistaStylePrivate::InvalidMetric; +} + +/*! + \internal + */ +int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const +{ + if (!QWindowsVistaStylePrivate::useVista()) + return QWindowsStyle::pixelMetric(metric, option, widget); + + int ret = QWindowsVistaStylePrivate::fixedPixelMetric(metric); + if (ret != QWindowsStylePrivate::InvalidMetric) + return int(QStyleHelper::dpiScaled(ret, option)); + + return QWindowsXPStyle::pixelMetric(metric, option, widget); +} + +/*! + \internal + */ +QPalette QWindowsVistaStyle::standardPalette() const +{ + return QWindowsXPStyle::standardPalette(); +} + +/*! + \internal + */ +void QWindowsVistaStyle::polish(QApplication *app) +{ + QWindowsXPStyle::polish(app); +} + +/*! + \internal + */ +void QWindowsVistaStyle::polish(QWidget *widget) +{ + QWindowsXPStyle::polish(widget); +#if QT_CONFIG(lineedit) + if (qobject_cast<QLineEdit*>(widget)) + widget->setAttribute(Qt::WA_Hover); + else +#endif // QT_CONFIG(lineedit) + if (qobject_cast<QGroupBox*>(widget)) + widget->setAttribute(Qt::WA_Hover); +#if QT_CONFIG(commandlinkbutton) + else if (qobject_cast<QCommandLinkButton*>(widget)) { + QFont buttonFont = widget->font(); + buttonFont.setFamilies(QStringList{QLatin1String("Segoe UI")}); + widget->setFont(buttonFont); + } +#endif // QT_CONFIG(commandlinkbutton) + else if (widget->inherits("QTipLabel")){ + //note that since tooltips are not reused + //we do not have to care about unpolishing + widget->setContentsMargins(3, 0, 4, 0); + COLORREF bgRef; + HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : nullptr, L"TOOLTIP"); + if (theme && SUCCEEDED(GetThemeColor(theme, TTP_STANDARD, TTSS_NORMAL, TMT_TEXTCOLOR, &bgRef))) { + QColor textColor = QColor::fromRgb(bgRef); + QPalette pal; + pal.setColor(QPalette::All, QPalette::ToolTipText, textColor); + widget->setPalette(pal); + } + } else if (qobject_cast<QMessageBox *> (widget)) { + widget->setAttribute(Qt::WA_StyledBackground); +#if QT_CONFIG(dialogbuttonbox) + QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox")); + if (buttonBox) + buttonBox->setContentsMargins(0, 9, 0, 0); +#endif + } +#if QT_CONFIG(inputdialog) + else if (qobject_cast<QInputDialog *> (widget)) { + widget->setAttribute(Qt::WA_StyledBackground); +#if QT_CONFIG(dialogbuttonbox) + QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox")); + if (buttonBox) + buttonBox->setContentsMargins(0, 9, 0, 0); +#endif + } +#endif // QT_CONFIG(inputdialog) + else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) { + tree->viewport()->setAttribute(Qt::WA_Hover); + } + else if (QListView *list = qobject_cast<QListView *> (widget)) { + list->viewport()->setAttribute(Qt::WA_Hover); + } +} + +/*! + \internal + */ +void QWindowsVistaStyle::unpolish(QWidget *widget) +{ + QWindowsXPStyle::unpolish(widget); + + QWindowsVistaStylePrivate *d = d_func(); + + d->stopAnimation(widget); + +#if QT_CONFIG(lineedit) + if (qobject_cast<QLineEdit*>(widget)) + widget->setAttribute(Qt::WA_Hover, false); + else +#endif // QT_CONFIG(lineedit) + if (qobject_cast<QGroupBox*>(widget)) + widget->setAttribute(Qt::WA_Hover, false); + else if (qobject_cast<QMessageBox *> (widget)) { + widget->setAttribute(Qt::WA_StyledBackground, false); +#if QT_CONFIG(dialogbuttonbox) + QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox")); + if (buttonBox) + buttonBox->setContentsMargins(0, 0, 0, 0); +#endif + } +#if QT_CONFIG(inputdialog) + else if (qobject_cast<QInputDialog *> (widget)) { + widget->setAttribute(Qt::WA_StyledBackground, false); +#if QT_CONFIG(dialogbuttonbox) + QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox")); + if (buttonBox) + buttonBox->setContentsMargins(0, 0, 0, 0); +#endif + } +#endif // QT_CONFIG(inputdialog) + else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) { + tree->viewport()->setAttribute(Qt::WA_Hover, false); + } +#if QT_CONFIG(commandlinkbutton) + else if (qobject_cast<QCommandLinkButton*>(widget)) { + QFont font = QApplication::font("QCommandLinkButton"); + QFont widgetFont = widget->font(); + widgetFont.setFamilies(font.families()); //Only family set by polish + widget->setFont(widgetFont); + } +#endif // QT_CONFIG(commandlinkbutton) +} + + +/*! + \internal + */ +void QWindowsVistaStyle::unpolish(QApplication *app) +{ + QWindowsXPStyle::unpolish(app); +} + +/*! + \internal + */ +void QWindowsVistaStyle::polish(QPalette &pal) +{ + QWindowsStyle::polish(pal); + pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(104)); +} + +/*! + \internal + */ +QPixmap QWindowsVistaStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option, + const QWidget *widget) const +{ + if (!QWindowsVistaStylePrivate::useVista()) { + return QWindowsStyle::standardPixmap(standardPixmap, option, widget); + } + return QWindowsXPStyle::standardPixmap(standardPixmap, option, widget); +} + +QWindowsVistaStylePrivate::QWindowsVistaStylePrivate() : + QWindowsXPStylePrivate() +{ +} + +bool QWindowsVistaStylePrivate::transitionsEnabled() const +{ + BOOL animEnabled = false; + if (SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &animEnabled, 0)) + { + if (animEnabled) + return true; + } + return false; +} + +/*! +\reimp +*/ +QIcon QWindowsVistaStyle::standardIcon(StandardPixmap standardIcon, + const QStyleOption *option, + const QWidget *widget) const +{ + if (!QWindowsVistaStylePrivate::useVista()) { + return QWindowsStyle::standardIcon(standardIcon, option, widget); + } + + QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate *>(d_func()); + switch (standardIcon) { + case SP_CommandLink: + { + XPThemeData theme(nullptr, nullptr, + QWindowsXPStylePrivate::ButtonTheme, + BP_COMMANDLINKGLYPH, CMDLGS_NORMAL); + if (theme.isValid()) { + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); + QIcon linkGlyph; + QPixmap pm(size); + pm.fill(Qt::transparent); + QPainter p(&pm); + theme.painter = &p; + theme.rect = QRect(QPoint(0, 0), size); + d->drawBackground(theme); + linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal + pm.fill(Qt::transparent); + + theme.stateId = CMDLGS_PRESSED; + d->drawBackground(theme); + linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed + pm.fill(Qt::transparent); + + theme.stateId = CMDLGS_HOT; + d->drawBackground(theme); + linkGlyph.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover + pm.fill(Qt::transparent); + + theme.stateId = CMDLGS_DISABLED; + d->drawBackground(theme); + linkGlyph.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled + return linkGlyph; + } + } + break; + default: + break; + } + return QWindowsXPStyle::standardIcon(standardIcon, option, widget); +} + +QT_END_NAMESPACE diff --git a/src/quicknativestyle/qstyle/windows/qquickwindowsvistastyle_p.h b/src/quicknativestyle/qstyle/windows/qquickwindowsvistastyle_p.h new file mode 100644 index 00000000000..07cd2b8ae7a --- /dev/null +++ b/src/quicknativestyle/qstyle/windows/qquickwindowsvistastyle_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module 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 QWINDOWSVISTASTYLE_P_H +#define QWINDOWSVISTASTYLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWidgets/private/qtwidgetsglobal_p.h> +#include "qquickwindowsxpstyle_p.h" + +QT_BEGIN_NAMESPACE + +class QWindowsVistaStylePrivate; +class QWindowsVistaStyle : public QWindowsXPStyle +{ + Q_OBJECT +public: + QWindowsVistaStyle(); + ~QWindowsVistaStyle() override; + + void drawPrimitive(PrimitiveElement element, const QStyleOption *option, + QPainter *painter, + const QWidget *widget = nullptr) const override; + void drawControl(ControlElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget) const override; + void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget) const override; + QSize sizeFromContents(ContentsType type, const QStyleOption *option, + const QSize &size, const QWidget *widget) const override; + + QRect subElementRect(SubElement element, const QStyleOption *option, + const QWidget *widget) const override; + QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, + SubControl sc, const QWidget *widget) const override; + + SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, + const QPoint &pos, const QWidget *widget = nullptr) const override; + + QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr, + const QWidget *widget = nullptr) const override; + QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, + const QWidget *widget = nullptr) const override; + int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr, + const QWidget *widget = nullptr) const override; + int styleHint(StyleHint hint, const QStyleOption *opt = nullptr, + const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override; + + void polish(QWidget *widget) override; + void unpolish(QWidget *widget) override; + void polish(QPalette &pal) override; + void polish(QApplication *app) override; + void unpolish(QApplication *app) override; + QPalette standardPalette() const override; + +private: + Q_DISABLE_COPY_MOVE(QWindowsVistaStyle) + Q_DECLARE_PRIVATE(QWindowsVistaStyle) + friend class QStyleFactory; +}; + +QT_END_NAMESPACE + +#endif // QWINDOWSVISTASTYLE_P_H diff --git a/src/quicknativestyle/qstyle/windows/qquickwindowsvistastyle_p_p.h b/src/quicknativestyle/qstyle/windows/qquickwindowsvistastyle_p_p.h new file mode 100644 index 00000000000..a5383175a3b --- /dev/null +++ b/src/quicknativestyle/qstyle/windows/qquickwindowsvistastyle_p_p.h @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module 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 QWINDOWSVISTASTYLE_P_P_H +#define QWINDOWSVISTASTYLE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWidgets/private/qtwidgetsglobal_p.h> +#include "qquickwindowsvistastyle_p.h" +#include "qquickwindowsxpstyle_p_p.h" +#include <private/qstyleanimation_p.h> +#include <private/qpaintengine_raster_p.h> +#include <qpaintengine.h> +#include <qwidget.h> +#include <qapplication.h> +#include <qpixmapcache.h> +#include <qstyleoption.h> +#if QT_CONFIG(pushbutton) +#include <qpushbutton.h> +#endif +#include <qradiobutton.h> +#if QT_CONFIG(lineedit) +#include <qlineedit.h> +#endif +#include <qgroupbox.h> +#if QT_CONFIG(toolbutton) +#include <qtoolbutton.h> +#endif +#if QT_CONFIG(spinbox) +#include <qspinbox.h> +#endif +#if QT_CONFIG(toolbar) +#include <qtoolbar.h> +#endif +#if QT_CONFIG(combobox) +#include <qcombobox.h> +#endif +#if QT_CONFIG(scrollbar) +#include <qscrollbar.h> +#endif +#if QT_CONFIG(progressbar) +#include <qprogressbar.h> +#endif +#if QT_CONFIG(dockwidget) +#include <qdockwidget.h> +#endif +#if QT_CONFIG(listview) +#include <qlistview.h> +#endif +#if QT_CONFIG(treeview) +#include <qtreeview.h> +#endif +#include <qtextedit.h> +#include <qmessagebox.h> +#if QT_CONFIG(dialogbuttonbox) +#include <qdialogbuttonbox.h> +#endif +#include <qinputdialog.h> +#if QT_CONFIG(tableview) +#include <qtableview.h> +#endif +#include <qdatetime.h> +#if QT_CONFIG(commandlinkbutton) +#include <qcommandlinkbutton.h> +#endif + +QT_BEGIN_NAMESPACE + +#if !defined(SCHEMA_VERIFY_VSSYM32) +#define TMT_ANIMATIONDURATION 5006 +#define TMT_TRANSITIONDURATIONS 6000 +#define EP_EDITBORDER_NOSCROLL 6 +#define EP_EDITBORDER_HVSCROLL 9 +#define EP_BACKGROUND 3 +#define EBS_NORMAL 1 +#define EBS_HOT 2 +#define EBS_DISABLED 3 +#define EBS_READONLY 5 +#define PBS_DEFAULTED_ANIMATING 6 +#define MBI_NORMAL 1 +#define MBI_HOT 2 +#define MBI_PUSHED 3 +#define MBI_DISABLED 4 +#define MB_ACTIVE 1 +#define MB_INACTIVE 2 +#define PP_FILL 5 +#define PP_FILLVERT 6 +#define PP_MOVEOVERLAY 8 +#define PP_MOVEOVERLAYVERT 10 +#define MENU_BARBACKGROUND 7 +#define MENU_BARITEM 8 +#define MENU_POPUPCHECK 11 +#define MENU_POPUPCHECKBACKGROUND 12 +#define MENU_POPUPGUTTER 13 +#define MENU_POPUPITEM 14 +#define MENU_POPUPBORDERS 10 +#define MENU_POPUPSEPARATOR 15 +#define MC_CHECKMARKNORMAL 1 +#define MC_CHECKMARKDISABLED 2 +#define MC_BULLETNORMAL 3 +#define MC_BULLETDISABLED 4 +#define ABS_UPHOVER 17 +#define ABS_DOWNHOVER 18 +#define ABS_LEFTHOVER 19 +#define ABS_RIGHTHOVER 20 +#define CP_DROPDOWNBUTTONRIGHT 6 +#define CP_DROPDOWNBUTTONLEFT 7 +#define SCRBS_HOVER 5 +#define TVP_HOTGLYPH 4 +#define SPI_GETCLIENTAREAANIMATION 0x1042 +#define TDLG_PRIMARYPANEL 1 +#define TDLG_SECONDARYPANEL 8 +#endif + +class QWindowsVistaAnimation : public QBlendStyleAnimation +{ + Q_OBJECT +public: + QWindowsVistaAnimation(Type type, QObject *target) : QBlendStyleAnimation(type, target) { } + + bool isUpdateNeeded() const override; + void paint(QPainter *painter, const QStyleOption *option); +}; + + +// Handles state transition animations +class QWindowsVistaTransition : public QWindowsVistaAnimation +{ + Q_OBJECT +public: + QWindowsVistaTransition(QObject *target) : QWindowsVistaAnimation(Transition, target) {} +}; + + +// Handles pulse animations (default buttons) +class QWindowsVistaPulse: public QWindowsVistaAnimation +{ + Q_OBJECT +public: + QWindowsVistaPulse(QObject *target) : QWindowsVistaAnimation(Pulse, target) {} +}; + + +class QWindowsVistaStylePrivate : public QWindowsXPStylePrivate +{ + Q_DECLARE_PUBLIC(QWindowsVistaStyle) + +public: + QWindowsVistaStylePrivate(); + + static int fixedPixelMetric(QStyle::PixelMetric pm); + static inline bool useVista(); + bool transitionsEnabled() const; +}; + +QT_END_NAMESPACE + +#endif // QWINDOWSVISTASTYLE_P_P_H diff --git a/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle.cpp b/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle.cpp new file mode 100644 index 00000000000..39de66d55c3 --- /dev/null +++ b/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle.cpp @@ -0,0 +1,4147 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module 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 "qquickstylehelper_p.h" +#include "qquickwindowsxpstyle_p.h" +#include "qquickwindowsxpstyle_p_p.h" + +#include <private/qobject_p.h> +#include <private/qpaintengine_raster_p.h> +#include <qpa/qplatformnativeinterface.h> +#include <qpainter.h> +#include <qpaintengine.h> +#include <qbackingstore.h> +#include <qpixmapcache.h> +#include <qpa/qplatformnativeinterface.h> +#include <qvarlengtharray.h> +#include <qdebug.h> + +#include <algorithm> + +QT_BEGIN_NAMESPACE + +namespace QQC2 { + +// General const values +static const int windowsItemFrame = 2; // menu item frame width +static const int windowsItemHMargin = 3; // menu item hor text margin +static const int windowsItemVMargin = 0; // menu item ver text margin +static const int windowsArrowHMargin = 6; // arrow horizontal margin +static const int windowsRightBorder = 12; // right border on windows + +// Theme names matching the QWindowsXPStylePrivate::Theme enumeration. +static const wchar_t *themeNames[QWindowsXPStylePrivate::NThemes] = +{ + L"BUTTON", L"COMBOBOX", L"EDIT", L"HEADER", L"LISTVIEW", + L"MENU", L"PROGRESS", L"REBAR", L"SCROLLBAR", L"SPIN", + L"TAB", L"TASKDIALOG", L"TOOLBAR", L"TOOLTIP", L"TRACKBAR", + L"TREEVIEW", L"WINDOW", L"STATUS", L"TREEVIEW" +}; + +// Theme data helper ------------------------------------------------------------------------------ +/* \internal + Returns \c true if the themedata is valid for use. +*/ +bool XPThemeData::isValid() +{ + return QWindowsXPStylePrivate::useXP() && theme >= 0 && handle(); +} + + +/* \internal + Returns the theme engine handle to the specific class. + If the handle hasn't been opened before, it opens the data, and + adds it to a static map, for caching. +*/ +HTHEME XPThemeData::handle() +{ + if (!QWindowsXPStylePrivate::useXP()) + return nullptr; + + if (!htheme) + htheme = QWindowsXPStylePrivate::createTheme(theme, QWindowsXPStylePrivate::winId(window)); + return htheme; +} + +/* \internal + Converts a QRect to the native RECT structure. +*/ +RECT XPThemeData::toRECT(const QRect &qr) +{ + RECT r; + r.left = qr.x(); + r.right = qr.x() + qr.width(); + r.top = qr.y(); + r.bottom = qr.y() + qr.height(); + return r; +} + +/* \internal + Returns the native region of a part, if the part is considered + transparent. The region is scaled to the parts size (rect). +*/ + +// QWindowsXPStylePrivate ------------------------------------------------------------------------- +// Static initializations +HWND QWindowsXPStylePrivate::m_vistaTreeViewHelper = nullptr; +HTHEME QWindowsXPStylePrivate::m_themes[NThemes]; +bool QWindowsXPStylePrivate::use_xp = false; +QBasicAtomicInt QWindowsXPStylePrivate::ref = Q_BASIC_ATOMIC_INITIALIZER(-1); // -1 based refcounting + +static void qt_add_rect(HRGN &winRegion, QRect r) +{ + HRGN rgn = CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height()); + if (rgn) { + HRGN dest = CreateRectRgn(0,0,0,0); + int result = CombineRgn(dest, winRegion, rgn, RGN_OR); + if (result) { + DeleteObject(winRegion); + winRegion = dest; + } + DeleteObject(rgn); + } +} + +static HRGN qt_hrgn_from_qregion(const QRegion ®ion) +{ + HRGN hRegion = CreateRectRgn(0,0,0,0); + if (region.rectCount() == 1) { + qt_add_rect(hRegion, region.boundingRect()); + return hRegion; + } + for (const QRect &rect : region) + qt_add_rect(hRegion, rect); + return hRegion; +} + +/* \internal + Checks if the theme engine can/should be used, or if we should + fall back to Windows style. +*/ +bool QWindowsXPStylePrivate::useXP(bool update) +{ + if (update) { + use_xp = IsThemeActive() && (IsAppThemed() || !QCoreApplication::instance()) + && !QWindowsStylePrivate::isDarkMode(); + } + return use_xp; +} + +/* \internal + Handles refcounting, and queries the theme engine for usage. +*/ +void QWindowsXPStylePrivate::init(bool force) +{ + if (ref.ref() && !force) + return; + if (!force) // -1 based atomic refcounting + ref.ref(); + + useXP(true); + std::fill(m_themes, m_themes + NThemes, nullptr); +} + +/* \internal + Cleans up all static data. +*/ +void QWindowsXPStylePrivate::cleanup(bool force) +{ + if (bufferBitmap) { + if (bufferDC && nullBitmap) + SelectObject(bufferDC, nullBitmap); + DeleteObject(bufferBitmap); + bufferBitmap = nullptr; + } + + if (bufferDC) + DeleteDC(bufferDC); + bufferDC = nullptr; + + if (ref.deref() && !force) + return; + if (!force) // -1 based atomic refcounting + ref.deref(); + + use_xp = false; + cleanupHandleMap(); +} + +/* In order to obtain the correct VistaTreeViewTheme (arrows for PE_IndicatorBranch), + * we need to set the windows "explorer" theme explicitly on a native + * window and open the "TREEVIEW" theme handle passing its window handle + * in order to get Vista-style item view themes (particulary drawBackground() + * for selected items needs this). + * We invoke a service of the native Windows interface to create + * a non-visible window handle, open the theme on it and insert it into + * the cache so that it is found by XPThemeData::handle() first. + */ + +static inline HWND createTreeViewHelperWindow() +{ + if (QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface()) { + void *hwnd = nullptr; + void *wndProc = reinterpret_cast<void *>(DefWindowProc); + if (QMetaObject::invokeMethod(ni, "createMessageWindow", Qt::DirectConnection, + Q_RETURN_ARG(void*, hwnd), + Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindowClass")), + Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindow")), + Q_ARG(void*, wndProc)) && hwnd) { + return reinterpret_cast<HWND>(hwnd); + } + } + return nullptr; +} + +bool QWindowsXPStylePrivate::initVistaTreeViewTheming() +{ + if (m_vistaTreeViewHelper) + return true; + + m_vistaTreeViewHelper = createTreeViewHelperWindow(); + if (!m_vistaTreeViewHelper) { + qWarning("Unable to create the treeview helper window."); + return false; + } + if (FAILED(SetWindowTheme(m_vistaTreeViewHelper, L"explorer", nullptr))) { + qErrnoWarning("SetWindowTheme() failed."); + cleanupVistaTreeViewTheming(); + return false; + } + return true; +} + +void QWindowsXPStylePrivate::cleanupVistaTreeViewTheming() +{ + if (m_vistaTreeViewHelper) { + DestroyWindow(m_vistaTreeViewHelper); + m_vistaTreeViewHelper = nullptr; + } +} + +/* \internal + Closes all open theme data handles to ensure that we don't leak + resources, and that we don't refere to old handles when for + example the user changes the theme style. +*/ +void QWindowsXPStylePrivate::cleanupHandleMap() +{ + for (auto &theme : m_themes) { + if (theme) { + CloseThemeData(theme); + theme = nullptr; + } + } + QWindowsXPStylePrivate::cleanupVistaTreeViewTheming(); +} + +HTHEME QWindowsXPStylePrivate::createTheme(int theme, HWND hwnd) +{ + if (Q_UNLIKELY(theme < 0 || theme >= NThemes || !hwnd)) { + qWarning("Invalid parameters #%d, %p", theme, hwnd); + return nullptr; + } + if (!m_themes[theme]) { + const wchar_t *name = themeNames[theme]; + if (theme == VistaTreeViewTheme && QWindowsXPStylePrivate::initVistaTreeViewTheming()) + hwnd = QWindowsXPStylePrivate::m_vistaTreeViewHelper; + m_themes[theme] = OpenThemeData(hwnd, name); + if (Q_UNLIKELY(!m_themes[theme])) + qErrnoWarning("OpenThemeData() failed for theme %d (%s).", + theme, qPrintable(themeName(theme))); + } + return m_themes[theme]; +} + +QString QWindowsXPStylePrivate::themeName(int theme) +{ + return theme >= 0 && theme < NThemes ? + QString::fromWCharArray(themeNames[theme]) : + QString(); +} + +/* +bool QWindowsXPStylePrivate::isItemViewDelegateLineEdit(const QWidget *widget) +{ + if (!widget) + return false; + const QWidget *parent1 = widget->parentWidget(); + // Exlude dialogs or other toplevels parented on item views. + if (!parent1 || parent1->isWindow()) + return false; + const QWidget *parent2 = parent1->parentWidget(); + return parent2 && widget->inherits("QLineEdit") + && parent2->inherits("QAbstractItemView"); +} +*/ + +/* +// Returns whether base color is set for this widget +bool QWindowsXPStylePrivate::isLineEditBaseColorSet(const QStyleOption *option, const QWidget *widget) +{ + uint resolveMask = option->palette.resolve(); + if (widget) { + // Since spin box includes a line edit we need to resolve the palette mask also from + // the parent, as while the color is always correct on the palette supplied by panel, + // the mask can still be empty. If either mask specifies custom base color, use that. +#if QT_CONFIG(spinbox) + if (const QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget())) + resolveMask |= spinbox->palette().resolve(); +#endif // QT_CONFIG(spinbox) + } + return (resolveMask & (1 << QPalette::Base)) != 0; +} +*/ + +/*! \internal + This function will always return a valid window handle, and might + create a limbo widget to do so. + We often need a window handle to for example open theme data, so + this function ensures that we get one. +*/ +HWND QWindowsXPStylePrivate::winId(const QWindow *window) +{ + if (window) + if (const HWND hwnd = reinterpret_cast<HWND>(window->winId())) + return hwnd; + + // Find top level with native window (there might be dialogs that do not have one). + const auto allWindows = QGuiApplication::allWindows(); + for (const QWindow *window : allWindows) { + if (window->isTopLevel() && window->type() != Qt::Desktop && window->handle() != nullptr) + return reinterpret_cast<HWND>(window->winId()); + } + + return GetDesktopWindow(); +} + +/*! \internal + Returns a native buffer (DIB section) of at least the size of + ( \a x , \a y ). The buffer has a 32 bit depth, to not lose + the alpha values on proper alpha-pixmaps. +*/ +HBITMAP QWindowsXPStylePrivate::buffer(int w, int h) +{ + // If we already have a HBITMAP which is of adequate size, just return that + if (bufferBitmap) { + if (bufferW >= w && bufferH >= h) + return bufferBitmap; + // Not big enough, discard the old one + if (bufferDC && nullBitmap) + SelectObject(bufferDC, nullBitmap); + DeleteObject(bufferBitmap); + bufferBitmap = nullptr; + } + + w = qMax(bufferW, w); + h = qMax(bufferH, h); + + if (!bufferDC) { + HDC displayDC = GetDC(nullptr); + bufferDC = CreateCompatibleDC(displayDC); + ReleaseDC(nullptr, displayDC); + } + + // Define the header + BITMAPINFO bmi; + memset(&bmi, 0, sizeof(bmi)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = w; + bmi.bmiHeader.biHeight = -h; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + + // Create the pixmap + bufferPixels = nullptr; + bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, reinterpret_cast<void **>(&bufferPixels), nullptr, 0); + GdiFlush(); + nullBitmap = static_cast<HBITMAP>(SelectObject(bufferDC, bufferBitmap)); + + if (Q_UNLIKELY(!bufferBitmap)) { + qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() failed.", w, h); + bufferW = 0; + bufferH = 0; + return nullptr; + } + if (Q_UNLIKELY(!bufferPixels)) { + qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() did not allocate pixel data.", w, h); + bufferW = 0; + bufferH = 0; + return nullptr; + } + bufferW = w; + bufferH = h; +#ifdef DEBUG_XP_STYLE + qDebug("Creating new dib section (%d, %d)", w, h); +#endif + return bufferBitmap; +} + +/*! \internal + Returns \c true if the part contains any transparency at all. This does + not indicate what kind of transparency we're dealing with. It can be + - Alpha transparency + - Masked transparency +*/ +bool QWindowsXPStylePrivate::isTransparent(XPThemeData &themeData) +{ + return IsThemeBackgroundPartiallyTransparent(themeData.handle(), themeData.partId, + themeData.stateId); +} + + +/*! \internal + Returns a QRegion of the region of the part +*/ +QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData) +{ + HRGN hRgn = nullptr; + const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(themeData.window); + RECT rect = themeData.toRECT(QRect(themeData.rect.topLeft() / factor, themeData.rect.size() / factor)); + if (!SUCCEEDED(GetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId, + themeData.stateId, &rect, &hRgn))) { + return QRegion(); + } + + HRGN dest = CreateRectRgn(0, 0, 0, 0); + const bool success = CombineRgn(dest, hRgn, nullptr, RGN_COPY) != ERROR; + + QRegion region; + + if (success) { + const auto numBytes = GetRegionData(dest, 0, nullptr); + if (numBytes == 0) + return QRegion(); + + char *buf = new (std::nothrow) char[numBytes]; + if (!buf) + return QRegion(); + + RGNDATA *rd = reinterpret_cast<RGNDATA*>(buf); + if (GetRegionData(dest, numBytes, rd) == 0) { + delete [] buf; + return QRegion(); + } + + RECT *r = reinterpret_cast<RECT*>(rd->Buffer); + for (uint i = 0; i < rd->rdh.nCount; ++i) { + QRect rect; + rect.setCoords(int(r->left * factor), int(r->top * factor), int((r->right - 1) * factor), int((r->bottom - 1) * factor)); + ++r; + region |= rect; + } + + delete [] buf; + } + + DeleteObject(hRgn); + DeleteObject(dest); + + return region; +} + +/*! \internal + Returns \c true if the native doublebuffer contains pixels with + varying alpha value. +*/ +bool QWindowsXPStylePrivate::hasAlphaChannel(const QRect &rect) +{ + const int startX = rect.left(); + const int startY = rect.top(); + const int w = rect.width(); + const int h = rect.height(); + + int firstAlpha = -1; + for (int y = startY; y < h/2; ++y) { + auto buffer = reinterpret_cast<const DWORD *>(bufferPixels) + (y * bufferW); + for (int x = startX; x < w; ++x, ++buffer) { + int alpha = (*buffer) >> 24; + if (firstAlpha == -1) + firstAlpha = alpha; + else if (alpha != firstAlpha) + return true; + } + } + return false; +} + +/*! \internal + When the theme engine paints both a true alpha pixmap and a glyph + into our buffer, the glyph might not contain a proper alpha value. + The rule of thumb for premultiplied pixmaps is that the color + values of a pixel can never be higher than the alpha values, so + we use this to our advantage here, and fix all instances where + this occures. +*/ +bool QWindowsXPStylePrivate::fixAlphaChannel(const QRect &rect) +{ + const int startX = rect.left(); + const int startY = rect.top(); + const int w = rect.width(); + const int h = rect.height(); + bool hasFixedAlphaValue = false; + + for (int y = startY; y < h; ++y) { + auto buffer = reinterpret_cast<DWORD *>(bufferPixels) + (y * bufferW); + for (int x = startX; x < w; ++x, ++buffer) { + uint pixel = *buffer; + int alpha = qAlpha(pixel); + if (qRed(pixel) > alpha || qGreen(pixel) > alpha || qBlue(pixel) > alpha) { + *buffer |= 0xff000000; + hasFixedAlphaValue = true; + } + } + } + return hasFixedAlphaValue; +} + +/*! \internal + Swaps the alpha values on certain pixels: + 0xFF?????? -> 0x00?????? + 0x00?????? -> 0xFF?????? + Used to determin the mask of a non-alpha transparent pixmap in + the native doublebuffer, and swap the alphas so we may paint + the image as a Premultiplied QImage with drawImage(), and obtain + the mask transparency. +*/ +bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect, bool allPixels) +{ + const int startX = rect.left(); + const int startY = rect.top(); + const int w = rect.width(); + const int h = rect.height(); + bool valueChange = false; + + // Flip the alphas, so that 255-alpha pixels are 0, and 0-alpha are 255. + for (int y = startY; y < h; ++y) { + auto buffer = reinterpret_cast<DWORD *>(bufferPixels) + (y * bufferW); + for (int x = startX; x < w; ++x, ++buffer) { + if (allPixels) { + *buffer |= 0xFF000000; + continue; + } + unsigned int alphaValue = (*buffer) & 0xFF000000; + if (alphaValue == 0xFF000000) { + *buffer = 0; + valueChange = true; + } else if (alphaValue == 0) { + *buffer |= 0xFF000000; + valueChange = true; + } + } + } + return valueChange; +} + +enum TransformType { SimpleTransform, HighDpiScalingTransform, ComplexTransform }; + +static inline TransformType transformType(const QTransform &transform, qreal devicePixelRatio) +{ + if (transform.type() <= QTransform::TxTranslate) + return SimpleTransform; + if (transform.type() > QTransform::TxScale) + return ComplexTransform; + return qFuzzyCompare(transform.m11(), devicePixelRatio) + && qFuzzyCompare(transform.m22(), devicePixelRatio) + ? HighDpiScalingTransform : ComplexTransform; +} + +// QTBUG-60571: Exclude known fully opaque theme parts which produce values +// invalid in ARGB32_Premultiplied (for example, 0x00ffffff). +static inline bool isFullyOpaque(const XPThemeData &themeData) +{ + return themeData.theme == QWindowsXPStylePrivate::TaskDialogTheme && themeData.partId == TDLG_PRIMARYPANEL; +} + +/*! \internal + Main theme drawing function. + Determines the correct lowlevel drawing method depending on several + factors. + Use drawBackgroundThruNativeBuffer() if: + - Painter does not have an HDC + - Theme part is flipped (mirrored horizontally) + else use drawBackgroundDirectly(). + \note drawBackgroundThruNativeBuffer() can return false for large + sizes due to buffer()/CreateDIBSection() failing. +*/ +bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData, qreal correctionFactor) +{ + if (themeData.rect.isEmpty()) + return true; + + QPainter *painter = themeData.painter; + Q_ASSERT_X(painter != nullptr, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter"); + if (!painter || !painter->isActive()) + return false; + + painter->save(); + + // Access paintDevice via engine since the painter may + // return the clip device which can still be a widget device in case of grabWidget(). + + //bool translucentToplevel = false; + //const QPaintDevice *paintDevice = painter->device(); + const qreal additionalDevicePixelRatio = themeData.window ? themeData.window->devicePixelRatio() : qreal(1); + Q_ASSERT(painter->device()->devType() != QInternal::Widget); +/* + if (paintDevice->devType() == QInternal::Widget) { + const QWidget *window = static_cast<const QWidget *>(paintDevice)->window(); + translucentToplevel = window->testAttribute(Qt::WA_TranslucentBackground); + } + + const TransformType tt = transformType(painter->deviceTransform(), aditionalDevicePixelRatio); + + bool canDrawDirectly = false; + if (themeData.widget && painter->opacity() == 1.0 && !themeData.rotate + && !isFullyOpaque(themeData) + && tt != ComplexTransform && !themeData.mirrorVertically + && !translucentToplevel) { + // Draw on backing store DC only for real widgets or backing store images. + const QPaintDevice *enginePaintDevice = painter->paintEngine()->paintDevice(); + switch (enginePaintDevice->devType()) { + case QInternal::Widget: + canDrawDirectly = true; + break; + case QInternal::Image: + // Ensure the backing store has received as resize and is initialized. + if (QBackingStore *bs = backingStoreForWidget(themeData.widget)) + if (bs->size().isValid() && bs->paintDevice() == enginePaintDevice) + canDrawDirectly = true; + } + } + + const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : nullptr; + const bool result = dc && qFuzzyCompare(correctionFactor, qreal(1)) + ? drawBackgroundDirectly(dc, themeData, aditionalDevicePixelRatio) + : drawBackgroundThruNativeBuffer(themeData, aditionalDevicePixelRatio, correctionFactor); + */ + const bool result = drawBackgroundThruNativeBuffer(themeData, additionalDevicePixelRatio, correctionFactor); + painter->restore(); + return result; +} + +static inline QRectF scaleRect(const QRectF &r, qreal factor) +{ + return r.isValid() && factor > 1 + ? QRectF(r.topLeft() * factor, r.size() * factor) + : r; +} + +static QRegion scaleRegion(const QRegion ®ion, qreal factor) +{ + if (region.isEmpty() || qFuzzyCompare(factor, qreal(1))) + return region; + QRegion result; + for (const QRect &rect : region) + result += QRectF(QPointF(rect.topLeft()) * factor, QSizeF(rect.size() * factor)).toRect(); + return result; +} + +/*! \internal + This function draws the theme parts directly to the paintengines HDC. + Do not use this if you need to perform other transformations on the + resulting data. +*/ +bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeData, qreal additionalDevicePixelRatio) +{ + QPainter *painter = themeData.painter; + + const auto &deviceTransform = painter->deviceTransform(); + const QPointF redirectionDelta(deviceTransform.dx(), deviceTransform.dy()); + const QRect area = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio).translated(redirectionDelta).toRect(); + + QRegion sysRgn = painter->paintEngine()->systemClip(); + if (sysRgn.isEmpty()) + sysRgn = area; + else + sysRgn &= area; + if (painter->hasClipping()) + sysRgn &= scaleRegion(painter->clipRegion(), additionalDevicePixelRatio).translated(redirectionDelta.toPoint()); + HRGN hrgn = qt_hrgn_from_qregion(sysRgn); + SelectClipRgn(dc, hrgn); + +#ifdef DEBUG_XP_STYLE + printf("---[ DIRECT PAINTING ]------------------> Name(%-10s) Part(%d) State(%d)\n", + qPrintable(themeData.name), themeData.partId, themeData.stateId); + showProperties(themeData); +#endif + + RECT drawRECT = themeData.toRECT(area); + DTBGOPTS drawOptions; + memset(&drawOptions, 0, sizeof(drawOptions)); + drawOptions.dwSize = sizeof(drawOptions); + drawOptions.rcClip = themeData.toRECT(sysRgn.boundingRect()); + drawOptions.dwFlags = DTBG_CLIPRECT + | (themeData.noBorder ? DTBG_OMITBORDER : 0) + | (themeData.noContent ? DTBG_OMITCONTENT : 0) + | (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0); + + const HRESULT result = DrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions); + SelectClipRgn(dc, nullptr); + DeleteObject(hrgn); + return SUCCEEDED(result); +} + +/*! \internal + This function uses a secondary Native doublebuffer for painting parts. + It should only be used when the painteengine doesn't provide a proper + HDC for direct painting (e.g. when doing a grabWidget(), painting to + other pixmaps etc), or when special transformations are needed (e.g. + flips (horizonal mirroring only, vertical are handled by the theme + engine). + + \a correctionFactor is an additional factor used to scale up controls + that are too small on High DPI screens, as has been observed for + WP_MDICLOSEBUTTON, WP_MDIRESTOREBUTTON, WP_MDIMINBUTTON (QTBUG-75927). +*/ +bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData, + qreal additionalDevicePixelRatio, + qreal correctionFactor) +{ + QPainter *painter = themeData.painter; + QRectF rectF = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio); + + if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips. + rectF = QRectF(0, 0, rectF.height(), rectF.width()); + } + rectF.moveTo(0, 0); + + const bool hasCorrectionFactor = !qFuzzyCompare(correctionFactor, qreal(1)); + QRect rect = rectF.toRect(); + QRect drawRect = hasCorrectionFactor + ? QRectF(rectF.topLeft() / correctionFactor, rectF.size() / correctionFactor).toRect() : rect; + int partId = themeData.partId; + int stateId = themeData.stateId; + int w = rect.width(); + int h = rect.height(); + + // Values initialized later, either from cached values, or from function calls + AlphaChannelType alphaType = UnknownAlpha; + bool stateHasData = true; // We assume so; + bool hasAlpha = false; + bool partIsTransparent; + bool potentialInvalidAlpha; + + QString pixmapCacheKey = QStringLiteral("$qt_xp_"); + pixmapCacheKey.append(themeName(themeData.theme)); + pixmapCacheKey.append(QLatin1Char('p')); + pixmapCacheKey.append(QString::number(partId)); + pixmapCacheKey.append(QLatin1Char('s')); + pixmapCacheKey.append(QString::number(stateId)); + pixmapCacheKey.append(QLatin1Char('s')); + pixmapCacheKey.append(themeData.noBorder ? QLatin1Char('0') : QLatin1Char('1')); + pixmapCacheKey.append(QLatin1Char('b')); + pixmapCacheKey.append(themeData.noContent ? QLatin1Char('0') : QLatin1Char('1')); + pixmapCacheKey.append(QString::number(w)); + pixmapCacheKey.append(QLatin1Char('w')); + pixmapCacheKey.append(QString::number(h)); + pixmapCacheKey.append(QLatin1Char('h')); + pixmapCacheKey.append(QString::number(additionalDevicePixelRatio)); + pixmapCacheKey.append(QLatin1Char('d')); + if (hasCorrectionFactor) { + pixmapCacheKey.append(QLatin1Char('c')); + pixmapCacheKey.append(QString::number(correctionFactor)); + } + + QPixmap cachedPixmap; + ThemeMapKey key(themeData); + ThemeMapData data = alphaCache.value(key); + + bool haveCachedPixmap = false; + bool isCached = data.dataValid; + if (isCached) { + partIsTransparent = data.partIsTransparent; + hasAlpha = data.hasAlphaChannel; + alphaType = data.alphaType; + potentialInvalidAlpha = data.hadInvalidAlpha; + + haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, &cachedPixmap); + +#ifdef DEBUG_XP_STYLE + char buf[25]; + ::sprintf(buf, "+ Pixmap(%3d, %3d) ]", w, h); + printf("---[ CACHED %s--------> Name(%-10s) Part(%d) State(%d)\n", + haveCachedPixmap ? buf : "]-------------------", + qPrintable(themeData.name), themeData.partId, themeData.stateId); +#endif + } else { + // Not cached, so get values from Theme Engine + BOOL tmt_borderonly = false; + COLORREF tmt_transparentcolor = 0x0; + PROPERTYORIGIN proporigin = PO_NOTFOUND; + GetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERONLY, &tmt_borderonly); + GetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, TMT_TRANSPARENTCOLOR, &tmt_transparentcolor); + GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_CAPTIONMARGINS, &proporigin); + + partIsTransparent = isTransparent(themeData); + + potentialInvalidAlpha = false; + GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &proporigin); + if (proporigin == PO_PART || proporigin == PO_STATE) { + int tmt_glyphtype = GT_NONE; + GetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &tmt_glyphtype); + potentialInvalidAlpha = partIsTransparent && tmt_glyphtype == GT_IMAGEGLYPH; + } + +#ifdef DEBUG_XP_STYLE + printf("---[ NOT CACHED ]-----------------------> Name(%-10s) Part(%d) State(%d)\n", + qPrintable(themeData.name), themeData.partId, themeData.stateId); + printf("-->partIsTransparen = %d\n", partIsTransparent); + printf("-->potentialInvalidAlpha = %d\n", potentialInvalidAlpha); + showProperties(themeData); +#endif + } + bool wasAlphaSwapped = false; + bool wasAlphaFixed = false; + + // OLD PSDK Workaround ------------------------------------------------------------------------ + // See if we need extra clipping for the older PSDK, which does + // not have a DrawThemeBackgroundEx function for DTGB_OMITBORDER + // and DTGB_OMITCONTENT + bool addBorderContentClipping = false; + QRegion extraClip; + QRect area = drawRect; + if (themeData.noBorder || themeData.noContent) { + extraClip = area; + // We are running on a system where the uxtheme.dll does not have + // the DrawThemeBackgroundEx function, so we need to clip away + // borders or contents manually. + + int borderSize = 0; + PROPERTYORIGIN origin = PO_NOTFOUND; + GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin); + GetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize); + borderSize *= additionalDevicePixelRatio; + + // Clip away border region + if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) { + if (themeData.noBorder) { + extraClip &= area; + area = area.adjusted(-borderSize, -borderSize, borderSize, borderSize); + } + + // Clip away content region + if (themeData.noContent) { + QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize); + extraClip ^= content; + } + } + addBorderContentClipping = (themeData.noBorder | themeData.noContent); + } + + QImage img; + if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! ------------------------- + if (!buffer(drawRect.width(), drawRect.height())) // Ensure a buffer of at least (w, h) in size + return false; + HDC dc = bufferHDC(); + + // Clear the buffer + if (alphaType != NoAlpha) { + // Consider have separate "memset" function for small chunks for more speedup + memset(bufferPixels, 0x00, bufferW * drawRect.height() * 4); + } + + // Difference between area and rect + int dx = area.x() - drawRect.x(); + int dy = area.y() - drawRect.y(); + + // Adjust so painting rect starts from Origo + rect.moveTo(0,0); + area.moveTo(dx,dy); + DTBGOPTS drawOptions; + drawOptions.dwSize = sizeof(drawOptions); + drawOptions.rcClip = themeData.toRECT(rect); + drawOptions.dwFlags = DTBG_CLIPRECT + | (themeData.noBorder ? DTBG_OMITBORDER : 0) + | (themeData.noContent ? DTBG_OMITCONTENT : 0); + + // Drawing the part into the backing store + RECT wRect(themeData.toRECT(area)); + DrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &wRect, &drawOptions); + + // If not cached, analyze the buffer data to figure + // out alpha type, and if it contains data + if (!isCached) { + // SHORTCUT: If the part's state has no data, cache it for NOOP later + if (!stateHasData) { + memset(static_cast<void *>(&data), 0, sizeof(data)); + data.dataValid = true; + alphaCache.insert(key, data); + return true; + } + hasAlpha = hasAlphaChannel(rect); + if (!hasAlpha && partIsTransparent) + potentialInvalidAlpha = true; +#if defined(DEBUG_XP_STYLE) && 1 + dumpNativeDIB(drawRect.width(), drawRect.height()); +#endif + } + + // Fix alpha values, if needed + if (potentialInvalidAlpha) + wasAlphaFixed = fixAlphaChannel(drawRect); + + QImage::Format format; + if ((partIsTransparent && !wasAlphaSwapped) || (!partIsTransparent && hasAlpha)) { + format = QImage::Format_ARGB32_Premultiplied; + alphaType = RealAlpha; + } else if (wasAlphaSwapped) { + format = QImage::Format_ARGB32_Premultiplied; + alphaType = MaskAlpha; + } else { + format = QImage::Format_RGB32; + // The image data we got from the theme engine does not have any transparency, + // thus the alpha channel is set to 0. + // However, Format_RGB32 requires the alpha part to be set to 0xff, thus + // we must flip it from 0x00 to 0xff + swapAlphaChannel(rect, true); + alphaType = NoAlpha; + } +#if defined(DEBUG_XP_STYLE) && 1 + printf("Image format is: %s\n", alphaType == RealAlpha ? "Real Alpha" : alphaType == MaskAlpha ? "Masked Alpha" : "No Alpha"); +#endif + img = QImage(bufferPixels, bufferW, bufferH, format); + if (hasCorrectionFactor) + img = img.scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation); + img.setDevicePixelRatio(additionalDevicePixelRatio); + } + + // Blitting backing store + bool useRegion = partIsTransparent && !hasAlpha && !wasAlphaSwapped; + + QRegion newRegion; + QRegion oldRegion; + if (useRegion) { + newRegion = region(themeData); + oldRegion = painter->clipRegion(); + painter->setClipRegion(newRegion); +#if defined(DEBUG_XP_STYLE) && 0 + printf("Using region:\n"); + for (const QRect &r : newRegion) + printf(" (%d, %d, %d, %d)\n", r.x(), r.y(), r.right(), r.bottom()); +#endif + } + + if (addBorderContentClipping) + painter->setClipRegion(scaleRegion(extraClip, 1.0 / additionalDevicePixelRatio), Qt::IntersectClip); + + if (!themeData.mirrorHorizontally && !themeData.mirrorVertically && !themeData.rotate) { + if (!haveCachedPixmap) + painter->drawImage(themeData.rect, img, rect); + else + painter->drawPixmap(themeData.rect, cachedPixmap); + } else { + // This is _slow_! + // Make a copy containing only the necessary data, and mirror + // on all wanted axes. Then draw the copy. + // If cached, the normal pixmap is cached, instead of caching + // all possible orientations for each part and state. + QImage imgCopy; + if (!haveCachedPixmap) + imgCopy = img.copy(rect); + else + imgCopy = cachedPixmap.toImage(); + + if (themeData.rotate) { + QTransform rotMatrix; + rotMatrix.rotate(themeData.rotate); + imgCopy = imgCopy.transformed(rotMatrix); + } + if (themeData.mirrorHorizontally || themeData.mirrorVertically) { + imgCopy = imgCopy.mirrored(themeData.mirrorHorizontally, themeData.mirrorVertically); + } + painter->drawImage(themeData.rect, + imgCopy); + } + + if (useRegion || addBorderContentClipping) { + if (oldRegion.isEmpty()) + painter->setClipping(false); + else + painter->setClipRegion(oldRegion); + } + + // Cache the pixmap to avoid expensive swapAlphaChannel() calls + if (!haveCachedPixmap && w && h) { + QPixmap pix = QPixmap::fromImage(img).copy(rect); + QPixmapCache::insert(pixmapCacheKey, pix); +#ifdef DEBUG_XP_STYLE + printf("+++Adding pixmap to cache, size(%d, %d), wasAlphaSwapped(%d), wasAlphaFixed(%d), name(%s)\n", + w, h, wasAlphaSwapped, wasAlphaFixed, qPrintable(pixmapCacheKey)); +#endif + } + + // Add to theme part cache + if (!isCached) { + memset(static_cast<void *>(&data), 0, sizeof(data)); + data.dataValid = true; + data.partIsTransparent = partIsTransparent; + data.alphaType = alphaType; + data.hasAlphaChannel = hasAlpha; + data.wasAlphaSwapped = wasAlphaSwapped; + data.hadInvalidAlpha = wasAlphaFixed; + alphaCache.insert(key, data); + } + return true; +} + + +// ------------------------------------------------------------------------------------------------ + +/*! + \class QWindowsXPStyle + \brief The QWindowsXPStyle class provides a Microsoft Windows XP-like look and feel. + + \ingroup appearance + \inmodule QtWidgets + \internal + + \warning This style is only available on the Windows XP platform + because it makes use of Windows XP's style engine. + + Most of the functions are documented in the base classes + QWindowsStyle, QCommonStyle, and QStyle, but the + QWindowsXPStyle overloads of drawComplexControl(), drawControl(), + drawControlMask(), drawPrimitive(), proxy()->subControlRect(), and + sizeFromContents(), are documented here. + + \image qwindowsxpstyle.png + \sa QMacStyle, QWindowsStyle, QFusionStyle +*/ + +/*! + Constructs a QWindowsStyle +*/ +QWindowsXPStyle::QWindowsXPStyle() + : QWindowsStyle(*new QWindowsXPStylePrivate) +{ +} + +/*! + Destroys the style. +*/ +QWindowsXPStyle::~QWindowsXPStyle() = default; + +/*! \reimp */ +QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option) const +{ + if (!QWindowsXPStylePrivate::useXP()) { + return QWindowsStyle::subElementRect(sr, option); + } + + QRect rect(option->rect); + switch (sr) { + case SE_DockWidgetCloseButton: + case SE_DockWidgetFloatButton: + rect = QWindowsStyle::subElementRect(sr, option); + return rect.translated(0, 1); + break; +#if 0 + case SE_TabWidgetTabContents: + if (qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) + { + rect = QWindowsStyle::subElementRect(sr, option); + if (sr == SE_TabWidgetTabContents) { + if (const QTabWidget *tabWidget = qobject_cast<const QTabWidget *>(widget)) { + if (tabWidget->documentMode()) + break; + } + + rect.adjust(0, 0, -2, -2); + } + } + break; + case SE_TabWidgetTabBar: { + rect = QWindowsStyle::subElementRect(sr, option); + const QStyleOptionTabWidgetFrame *twfOption = + qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option); + if (twfOption && twfOption->direction == Qt::RightToLeft + && (twfOption->shape == QTabBar::RoundedNorth + || twfOption->shape == QTabBar::RoundedSouth)) + { + QStyleOptionTab otherOption; + otherOption.shape = (twfOption->shape == QTabBar::RoundedNorth + ? QTabBar::RoundedEast : QTabBar::RoundedSouth); + int overlap = proxy()->pixelMetric(PM_TabBarBaseOverlap, &otherOption); + int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option); + rect.adjust(-overlap + borderThickness, 0, -overlap + borderThickness, 0); + } + break;} +#endif + case SE_PushButtonContents: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { + MARGINS borderSize; + if (option->window) { + XPThemeData buttontheme(option->window, nullptr, QWindowsXPStylePrivate::ButtonTheme); + HTHEME theme = buttontheme.handle(); + if (theme) { + int stateId; + if (!(option->state & State_Enabled)) + stateId = PBS_DISABLED; + else if (option->state & State_Sunken) + stateId = PBS_PRESSED; + else if (option->state & State_MouseOver) + stateId = PBS_HOT; + else if (btn->features & QStyleOptionButton::DefaultButton) + stateId = PBS_DEFAULTED; + else + stateId = PBS_NORMAL; + + int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn); + rect = option->rect.adjusted(border, border, -border, -border); + + if (SUCCEEDED(GetThemeMargins(theme, nullptr, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, nullptr, &borderSize))) { + rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight, + -borderSize.cxRightWidth, -borderSize.cyBottomHeight); + rect = visualRect(option->direction, option->rect, rect); + } + } + } + } + break; + case SE_ProgressBarContents: + rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option); + if (option->state & QStyle::State_Horizontal) + rect.adjust(4, 3, -4, -3); + else + rect.adjust(3, 2, -3, -2); + break; + default: + rect = QWindowsStyle::subElementRect(sr, option); + } + return rect; +} + +/*! + \reimp +*/ +void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p) const +{ + QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func()); + + if (!QWindowsXPStylePrivate::useXP()) { + QWindowsStyle::drawPrimitive(pe, option, p); + return; + } + + int themeNumber = -1; + int partId = 0; + int stateId = 0; + QRect rect = option->rect; + State flags = option->state; + bool hMirrored = false; + bool vMirrored = false; + bool noBorder = false; + bool noContent = false; + int rotate = 0; + + switch (pe) { +#if 0 + case PE_FrameTabBarBase: + if (const QStyleOptionTabBarBase *tbb + = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) { + p->save(); + switch (tbb->shape) { + case QTabBar::RoundedNorth: + p->setPen(QPen(tbb->palette.dark(), 0)); + p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight()); + break; + case QTabBar::RoundedWest: + p->setPen(QPen(tbb->palette.dark(), 0)); + p->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom()); + break; + case QTabBar::RoundedSouth: + p->setPen(QPen(tbb->palette.dark(), 0)); + p->drawLine(tbb->rect.left(), tbb->rect.top(), + tbb->rect.right(), tbb->rect.top()); + break; + case QTabBar::RoundedEast: + p->setPen(QPen(tbb->palette.dark(), 0)); + p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft()); + break; + case QTabBar::TriangularNorth: + case QTabBar::TriangularEast: + case QTabBar::TriangularWest: + case QTabBar::TriangularSouth: + p->restore(); + QWindowsStyle::drawPrimitive(pe, option, p); + return; + } + p->restore(); + } + return; +#endif + case PE_PanelButtonBevel: + themeNumber = QWindowsXPStylePrivate::ButtonTheme; + partId = BP_PUSHBUTTON; + if (!(flags & State_Enabled)) + stateId = PBS_DISABLED; + else if ((flags & State_Sunken) || (flags & State_On)) + stateId = PBS_PRESSED; + else if (flags & State_MouseOver) + stateId = PBS_HOT; + //else if (flags & State_ButtonDefault) + // stateId = PBS_DEFAULTED; + else + stateId = PBS_NORMAL; + break; + + case PE_PanelButtonTool: +// if (widget && widget->inherits("QDockWidgetTitleButton")) { +// if (const QWidget *dw = widget->parentWidget()) +// if (dw->isWindow()) +// return; +// } + themeNumber = QWindowsXPStylePrivate::ToolBarTheme; + partId = TP_BUTTON; + if (!(flags & State_Enabled)) + stateId = TS_DISABLED; + else if (flags & State_Sunken) + stateId = TS_PRESSED; + else if (flags & State_MouseOver) + stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT; + else if (flags & State_On) + stateId = TS_CHECKED; + else if (!(flags & State_AutoRaise)) + stateId = TS_HOT; + else + stateId = TS_NORMAL; + break; + + case PE_IndicatorButtonDropDown: + themeNumber = QWindowsXPStylePrivate::ToolBarTheme; + partId = TP_SPLITBUTTONDROPDOWN; + if (!(flags & State_Enabled)) + stateId = TS_DISABLED; + else if (flags & State_Sunken) + stateId = TS_PRESSED; + else if (flags & State_MouseOver) + stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT; + else if (flags & State_On) + stateId = TS_CHECKED; + else if (!(flags & State_AutoRaise)) + stateId = TS_HOT; + else + stateId = TS_NORMAL; + if (option->direction == Qt::RightToLeft) + hMirrored = true; + break; + + case PE_IndicatorCheckBox: + themeNumber = QWindowsXPStylePrivate::ButtonTheme; + partId = BP_CHECKBOX; + if (!(flags & State_Enabled)) + stateId = CBS_UNCHECKEDDISABLED; + else if (flags & State_Sunken) + stateId = CBS_UNCHECKEDPRESSED; + else if (flags & State_MouseOver) + stateId = CBS_UNCHECKEDHOT; + else + stateId = CBS_UNCHECKEDNORMAL; + + if (flags & State_On) + stateId += CBS_CHECKEDNORMAL-1; + else if (flags & State_NoChange) + stateId += CBS_MIXEDNORMAL-1; + + break; + + case PE_IndicatorRadioButton: + themeNumber = QWindowsXPStylePrivate::ButtonTheme; + partId = BP_RADIOBUTTON; + if (!(flags & State_Enabled)) + stateId = RBS_UNCHECKEDDISABLED; + else if (flags & State_Sunken) + stateId = RBS_UNCHECKEDPRESSED; + else if (flags & State_MouseOver) + stateId = RBS_UNCHECKEDHOT; + else + stateId = RBS_UNCHECKEDNORMAL; + + if (flags & State_On) + stateId += RBS_CHECKEDNORMAL-1; + break; + + case PE_IndicatorDockWidgetResizeHandle: + return; + +case PE_Frame: + { + if (flags & State_Raised) + return; + themeNumber = QWindowsXPStylePrivate::ListViewTheme; + partId = LVP_LISTGROUP; + XPThemeData theme(option->window, nullptr, themeNumber, partId); + + if (!(flags & State_Enabled)) + stateId = ETS_DISABLED; + else + stateId = ETS_NORMAL; + int fillType; + if (GetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &fillType) == S_OK) { + if (fillType == BT_BORDERFILL) { + COLORREF bcRef; + GetThemeColor(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &bcRef); + QColor bordercolor(qRgb(GetRValue(bcRef), GetGValue(bcRef), GetBValue(bcRef))); + QPen oldPen = p->pen(); + // int borderSize = 1; + // GetThemeInt(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &borderSize); + + // Inner white border + p->setPen(QPen(option->palette.base().color(), 0)); + const qreal dpi = QStyleHelper::dpi(option); + const auto topLevelAdjustment = QStyleHelper::dpiScaled(0.5, dpi); + const auto bottomRightAdjustment = QStyleHelper::dpiScaled(-1, dpi); + p->drawRect(QRectF(option->rect).adjusted(topLevelAdjustment, topLevelAdjustment, + bottomRightAdjustment, bottomRightAdjustment)); + // Outer dark border + p->setPen(QPen(bordercolor, 0)); + p->drawRect(QRectF(option->rect).adjusted(0, 0, -topLevelAdjustment, -topLevelAdjustment)); + p->setPen(oldPen); + return; + } + if (fillType == BT_NONE) + return; + } + break; + } + case PE_FrameLineEdit: { + // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class. + /* + if (QWindowsXPStylePrivate::isItemViewDelegateLineEdit(widget)) { + QPen oldPen = p->pen(); + // Inner white border + p->setPen(QPen(option->palette.base().color(), 1)); + p->drawRect(option->rect.adjusted(1, 1, -2, -2)); + // Outer dark border + p->setPen(QPen(option->palette.shadow().color(), 1)); + p->drawRect(option->rect.adjusted(0, 0, -1, -1)); + p->setPen(oldPen); + return; + } + */ + if (qstyleoption_cast<const QStyleOptionFrame *>(option)) { + themeNumber = QWindowsXPStylePrivate::EditTheme; + partId = EP_EDITTEXT; + noContent = true; + if (!(flags & State_Enabled)) + stateId = ETS_DISABLED; + else + stateId = ETS_NORMAL; + } + break; + } + + case PE_PanelLineEdit: + if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) { + themeNumber = QWindowsXPStylePrivate::EditTheme; + partId = EP_EDITTEXT; + noBorder = true; + bool isEnabled = flags & State_Enabled; + + stateId = isEnabled ? ETS_NORMAL : ETS_DISABLED; + + /*if (QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget)) { + p->fillRect(panel->rect, panel->palette.brush(QPalette::Base)); + } else*/ { + XPThemeData theme(nullptr, p, themeNumber, partId, stateId, rect); + if (!theme.isValid()) { + QWindowsStyle::drawPrimitive(pe, option, p); + return; + } + int bgType; + GetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &bgType); + if ( bgType == BT_IMAGEFILE ) { + theme.mirrorHorizontally = hMirrored; + theme.mirrorVertically = vMirrored; + theme.noBorder = noBorder; + theme.noContent = noContent; + theme.rotate = rotate; + d->drawBackground(theme); + } else { + QBrush fillColor = option->palette.brush(QPalette::Base); + + if (!isEnabled) { + PROPERTYORIGIN origin = PO_NOTFOUND; + GetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin); + // Use only if the fill property comes from our part + if ((origin == PO_PART || origin == PO_STATE)) { + COLORREF bgRef; + GetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef); + fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef))); + } + } + p->fillRect(option->rect, fillColor); + } + } + + if (panel->lineWidth > 0) + proxy()->drawPrimitive(PE_FrameLineEdit, panel, p); + return; + } + break; +#if 0 + case PE_FrameTabWidget: + if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) + { + themeNumber = QWindowsXPStylePrivate::TabTheme; + partId = TABP_PANE; + + if (option->window) { + bool useGradient = true; + const int maxlength = 256; + wchar_t themeFileName[maxlength]; + wchar_t themeColor[maxlength]; + // Due to a a scaling issue with the XP Silver theme, tab gradients are not used with it + if (GetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, nullptr, 0) == S_OK) { + wchar_t *offset = nullptr; + if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != nullptr) { + offset++; + if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) { + useGradient = false; + } + } + } + // This should work, but currently there's an error in the ::drawBackgroundDirectly() + // code, when using the HDC directly.. + if (useGradient) { + QStyleOptionTabWidgetFrame frameOpt = *tab; + //frameOpt.rect = widget->rect(); + + QRect contentsRect = subElementRect(SE_TabWidgetTabContents, &frameOpt); + QRegion reg = option->rect; + reg -= contentsRect; + p->setClipRegion(reg); + XPThemeData theme(option->window, p, themeNumber, partId, stateId, rect); + theme.mirrorHorizontally = hMirrored; + theme.mirrorVertically = vMirrored; + d->drawBackground(theme); + p->setClipRect(contentsRect); + partId = TABP_BODY; + } + } + switch (tab->shape) { + case QTabBar::RoundedNorth: + case QTabBar::TriangularNorth: + break; + case QTabBar::RoundedSouth: + case QTabBar::TriangularSouth: + vMirrored = true; + break; + case QTabBar::RoundedEast: + case QTabBar::TriangularEast: + rotate = 90; + break; + case QTabBar::RoundedWest: + case QTabBar::TriangularWest: + rotate = 90; + hMirrored = true; + break; + default: + break; + } + } + break; +#endif + case PE_FrameMenu: + p->save(); + p->setPen(option->palette.dark().color()); + p->drawRect(rect.adjusted(0, 0, -1, -1)); + p->restore(); + return; + + case PE_PanelMenuBar: + break; + + case PE_FrameDockWidget: + if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option)) + { + themeNumber = QWindowsXPStylePrivate::WindowTheme; + if (flags & State_Active) + stateId = FS_ACTIVE; + else + stateId = FS_INACTIVE; + + int fwidth = proxy()->pixelMetric(PM_DockWidgetFrameWidth, frm); + + XPThemeData theme(option->window, p, themeNumber, 0, stateId); + if (!theme.isValid()) + break; + theme.rect = QRect(frm->rect.x(), frm->rect.y(), frm->rect.x()+fwidth, frm->rect.height()-fwidth); theme.partId = WP_SMALLFRAMELEFT; + d->drawBackground(theme); + theme.rect = QRect(frm->rect.width()-fwidth, frm->rect.y(), fwidth, frm->rect.height()-fwidth); + theme.partId = WP_SMALLFRAMERIGHT; + d->drawBackground(theme); + theme.rect = QRect(frm->rect.x(), frm->rect.bottom()-fwidth+1, frm->rect.width(), fwidth); + theme.partId = WP_SMALLFRAMEBOTTOM; + d->drawBackground(theme); + return; + } + break; + + case PE_IndicatorHeaderArrow: + { +#if 0 // XP theme engine doesn't know about this :( + name = QWindowsXPStylePrivate::HeaderTheme; + partId = HP_HEADERSORTARROW; + if (flags & State_Down) + stateId = HSAS_SORTEDDOWN; + else + stateId = HSAS_SORTEDUP; +#else + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { + p->save(); + p->setPen(option->palette.dark().color()); + p->translate(0, option->rect.height()/2 - 4); + if (header->sortIndicator & QStyleOptionHeader::SortUp) { // invert logic to follow Windows style guide + p->drawLine(option->rect.x(), option->rect.y(), option->rect.x()+8, option->rect.y()); + p->drawLine(option->rect.x()+1, option->rect.y()+1, option->rect.x()+7, option->rect.y()+1); + p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2); + p->drawLine(option->rect.x()+3, option->rect.y()+3, option->rect.x()+5, option->rect.y()+3); + p->drawPoint(option->rect.x()+4, option->rect.y()+4); + } else if (header->sortIndicator & QStyleOptionHeader::SortDown) { + p->drawLine(option->rect.x(), option->rect.y()+4, option->rect.x()+8, option->rect.y()+4); + p->drawLine(option->rect.x()+1, option->rect.y()+3, option->rect.x()+7, option->rect.y()+3); + p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2); + p->drawLine(option->rect.x()+3, option->rect.y()+1, option->rect.x()+5, option->rect.y()+1); + p->drawPoint(option->rect.x()+4, option->rect.y()); + } + p->restore(); + return; + } +#endif + } + break; + + case PE_FrameStatusBarItem: + themeNumber = QWindowsXPStylePrivate::StatusTheme; + partId = SP_PANE; + break; + + case PE_FrameGroupBox: + themeNumber = QWindowsXPStylePrivate::ButtonTheme; + partId = BP_GROUPBOX; + if (!(flags & State_Enabled)) + stateId = GBS_DISABLED; + else + stateId = GBS_NORMAL; + if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) { + if (frame->features & QStyleOptionFrame::Flat) { + // Windows XP does not have a theme part for a flat GroupBox, paint it with the windows style + QRect fr = frame->rect; + QPoint p1(fr.x(), fr.y() + 1); + QPoint p2(fr.x() + fr.width(), p1.y() + 1); + rect = QRect(p1, p2); + themeNumber = -1; + } + } + break; + + case PE_IndicatorProgressChunk: + { + Qt::Orientation orient = Qt::Horizontal; + bool inverted = false; + if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { + orient = pb->state & QStyle::State_Horizontal ? Qt::Horizontal : Qt::Vertical; + inverted = pb->invertedAppearance; + } + if (orient == Qt::Horizontal) { + partId = PP_CHUNK; + rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height() ); + if (inverted && option->direction == Qt::LeftToRight) + hMirrored = true; + } else { + partId = PP_CHUNKVERT; + rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height()); + } + themeNumber = QWindowsXPStylePrivate::ProgressTheme; + stateId = 1; + } + break; + + case PE_FrameWindow: + if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option)) + { + themeNumber = QWindowsXPStylePrivate::WindowTheme; + if (flags & State_Active) + stateId = FS_ACTIVE; + else + stateId = FS_INACTIVE; + + int fwidth = int((frm->lineWidth + frm->midLineWidth) / QWindowsStylePrivate::nativeMetricScaleFactor(option)); + + XPThemeData theme(option->window, p, themeNumber, 0, stateId); + if (!theme.isValid()) + break; + + // May fail due to too-large buffers for large widgets, fall back to Windows style. + theme.rect = QRect(option->rect.x(), option->rect.y()+fwidth, option->rect.x()+fwidth, option->rect.height()-fwidth); + theme.partId = WP_FRAMELEFT; + if (!d->drawBackground(theme)) { + QWindowsStyle::drawPrimitive(pe, option, p); + return; + } + theme.rect = QRect(option->rect.width()-fwidth, option->rect.y()+fwidth, fwidth, option->rect.height()-fwidth); + theme.partId = WP_FRAMERIGHT; + if (!d->drawBackground(theme)) { + QWindowsStyle::drawPrimitive(pe, option, p); + return; + } + theme.rect = QRect(option->rect.x(), option->rect.height()-fwidth, option->rect.width(), fwidth); + theme.partId = WP_FRAMEBOTTOM; + if (!d->drawBackground(theme)) { + QWindowsStyle::drawPrimitive(pe, option, p); + return; + } + theme.rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.y()+fwidth); + theme.partId = WP_CAPTION; + if (!d->drawBackground(theme)) + QWindowsStyle::drawPrimitive(pe, option, p); + return; + } + break; + + case PE_IndicatorBranch: + { + static const int decoration_size = 9; + int mid_h = option->rect.x() + option->rect.width() / 2; + int mid_v = option->rect.y() + option->rect.height() / 2; + int bef_h = mid_h; + int bef_v = mid_v; + int aft_h = mid_h; + int aft_v = mid_v; + QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern); + if (option->state & State_Item) { + if (option->direction == Qt::RightToLeft) + p->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush); + else + p->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush); + } + if (option->state & State_Sibling) + p->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush); + if (option->state & (State_Open | State_Children | State_Item | State_Sibling)) + p->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush); + if (option->state & State_Children) { + int delta = decoration_size / 2; + bef_h -= delta; + bef_v -= delta; + aft_h += delta; + aft_v += delta; + XPThemeData theme(nullptr, p, QWindowsXPStylePrivate::XpTreeViewTheme); + theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size); + theme.partId = TVP_GLYPH; + theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED; + d->drawBackground(theme); + } + } + return; + + case PE_IndicatorToolBarSeparator: + if (option->rect.height() < 3) { + // XP style requires a few pixels for the separator + // to be visible. + QWindowsStyle::drawPrimitive(pe, option, p); + return; + } + themeNumber = QWindowsXPStylePrivate::ToolBarTheme; + partId = TP_SEPARATOR; + + if (option->state & State_Horizontal) + partId = TP_SEPARATOR; + else + partId = TP_SEPARATORVERT; + + break; + + case PE_IndicatorToolBarHandle: + + themeNumber = QWindowsXPStylePrivate::RebarTheme; + partId = RP_GRIPPER; + if (option->state & State_Horizontal) { + partId = RP_GRIPPER; + rect.adjust(0, 0, -2, 0); + } + else { + partId = RP_GRIPPERVERT; + rect.adjust(0, 0, 0, -2); + } + break; + + case PE_IndicatorItemViewItemCheck: { + QStyleOptionButton button; + button.QStyleOption::operator=(*option); + button.state &= ~State_MouseOver; + proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, p); + return; + } + + default: + break; + } + + XPThemeData theme(option->window, p, themeNumber, partId, stateId, rect); + if (!theme.isValid()) { + QWindowsStyle::drawPrimitive(pe, option, p); + return; + } + theme.mirrorHorizontally = hMirrored; + theme.mirrorVertically = vMirrored; + theme.noBorder = noBorder; + theme.noContent = noContent; + theme.rotate = rotate; + d->drawBackground(theme); +} + +/*! + \reimp +*/ +void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *p) const +{ + QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func()); + if (!QWindowsXPStylePrivate::useXP()) { + QWindowsStyle::drawControl(element, option, p); + return; + } + + QRect rect(option->rect); + State flags = option->state; + + int rotate = 0; + bool hMirrored = false; + bool vMirrored = false; + + int themeNumber = -1; + int partId = 0; + int stateId = 0; + switch (element) { + case CE_SizeGrip: + { + themeNumber = QWindowsXPStylePrivate::StatusTheme; + partId = SP_GRIPPER; + XPThemeData theme(nullptr, p, themeNumber, partId); + QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize(); + size.rheight()--; + if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) { + switch (sg->corner) { + case Qt::BottomRightCorner: + rect = QRect(QPoint(rect.right() - size.width(), rect.bottom() - size.height()), size); + break; + case Qt::BottomLeftCorner: + rect = QRect(QPoint(rect.left() + 1, rect.bottom() - size.height()), size); + hMirrored = true; + break; + case Qt::TopRightCorner: + rect = QRect(QPoint(rect.right() - size.width(), rect.top() + 1), size); + vMirrored = true; + break; + case Qt::TopLeftCorner: + rect = QRect(rect.topLeft() + QPoint(1, 1), size); + hMirrored = vMirrored = true; + } + } + } + break; + + case CE_HeaderSection: + themeNumber = QWindowsXPStylePrivate::HeaderTheme; + partId = HP_HEADERITEM; + if (flags & State_Sunken) + stateId = HIS_PRESSED; + else if (flags & State_MouseOver) + stateId = HIS_HOT; + else + stateId = HIS_NORMAL; + break; + + case CE_Splitter: + p->eraseRect(option->rect); + return; + + case CE_PushButtonBevel: + if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) + { + themeNumber = QWindowsXPStylePrivate::ButtonTheme; + partId = BP_PUSHBUTTON; + bool justFlat = ((btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken))) + || ((btn->features & QStyleOptionButton::CommandLinkButton) + && !(flags & State_MouseOver) + && !(btn->features & QStyleOptionButton::DefaultButton)); + if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat)) + stateId = PBS_DISABLED; + else if (justFlat) + ; + else if (flags & (State_Sunken | State_On)) + stateId = PBS_PRESSED; + else if (flags & State_MouseOver) + stateId = PBS_HOT; + else if (btn->features & QStyleOptionButton::DefaultButton) + stateId = PBS_DEFAULTED; + else + stateId = PBS_NORMAL; + + if (!justFlat) { + XPThemeData theme(option->window, p, themeNumber, partId, stateId, rect); + d->drawBackground(theme); + } + + if (btn->features & QStyleOptionButton::HasMenu) { + int mbiw = 0, mbih = 0; + XPThemeData theme(option->window, nullptr, + QWindowsXPStylePrivate::ToolBarTheme, + TP_SPLITBUTTONDROPDOWN); + if (theme.isValid()) { + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize(); + mbiw = size.width(); + mbih = size.height(); + } + + QRect ir = btn->rect; + QStyleOptionButton newBtn = *btn; + newBtn.rect = QRect(ir.right() - mbiw - 1, 1 + (ir.height()/2) - (mbih/2), mbiw, mbih); + proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p); + } + return; + } + break; + case CE_TabBarTab: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) + { + stateId = tab->state & State_Enabled ? TIS_NORMAL : TIS_DISABLED; + } + break; +#if 0 + case CE_TabBarTabShape: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) + { + themeNumber = QWindowsXPStylePrivate::TabTheme; + bool isDisabled = !(tab->state & State_Enabled); + bool hasFocus = tab->state & State_HasFocus; + bool isHot = tab->state & State_MouseOver; + bool selected = tab->state & State_Selected; + bool lastTab = tab->position == QStyleOptionTab::End; + bool firstTab = tab->position == QStyleOptionTab::Beginning; + bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab; + bool leftAligned = proxy()->styleHint(SH_TabBar_Alignment, tab) == Qt::AlignLeft; + bool centerAligned = proxy()->styleHint(SH_TabBar_Alignment, tab) == Qt::AlignCenter; + int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option); + int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, option); + + if (isDisabled) + stateId = TIS_DISABLED; + else if (selected) + stateId = TIS_SELECTED; + else if (hasFocus) + stateId = TIS_FOCUSED; + else if (isHot) + stateId = TIS_HOT; + else + stateId = TIS_NORMAL; + + // Selecting proper part depending on position + if (firstTab || onlyOne) { + if (leftAligned) { + partId = TABP_TABITEMLEFTEDGE; + } else if (centerAligned) { + partId = TABP_TABITEM; + } else { // rightAligned + partId = TABP_TABITEMRIGHTEDGE; + } + } else { + partId = TABP_TABITEM; + } + + if (tab->direction == Qt::RightToLeft + && (tab->shape == QTabBar::RoundedNorth + || tab->shape == QTabBar::RoundedSouth)) { + bool temp = firstTab; + firstTab = lastTab; + lastTab = temp; + } + bool begin = firstTab || onlyOne; + bool end = lastTab || onlyOne; + switch (tab->shape) { + case QTabBar::RoundedNorth: + if (selected) + rect.adjust(begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap, borderThickness); + else + rect.adjust(begin? tabOverlap : 0, tabOverlap, end ? -tabOverlap : 0, 0); + break; + case QTabBar::RoundedSouth: + //vMirrored = true; + rotate = 180; // Not 100% correct, but works + if (selected) + rect.adjust(begin ? 0 : -tabOverlap , -borderThickness, end ? 0 : tabOverlap, 0); + else + rect.adjust(begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0 , -tabOverlap); + break; + case QTabBar::RoundedEast: + rotate = 90; + if (selected) { + rect.adjust(-borderThickness, begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap); + }else{ + rect.adjust(0, begin ? tabOverlap : 0, -tabOverlap, end ? -tabOverlap : 0); + } + break; + case QTabBar::RoundedWest: + hMirrored = true; + rotate = 90; + if (selected) { + rect.adjust(0, begin ? 0 : -tabOverlap, borderThickness, end ? 0 : tabOverlap); + }else{ + rect.adjust(tabOverlap, begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0); + } + break; + default: + themeNumber = -1; // Do our own painting for triangular + break; + } + + if (!selected) { + switch (tab->shape) { + case QTabBar::RoundedNorth: + rect.adjust(0,0, 0,-1); + break; + case QTabBar::RoundedSouth: + rect.adjust(0,1, 0,0); + break; + case QTabBar::RoundedEast: + rect.adjust( 1,0, 0,0); + break; + case QTabBar::RoundedWest: + rect.adjust(0,0, -1,0); + break; + default: + break; + } + } + } + break; +#endif + case CE_ProgressBarGroove: + { + Qt::Orientation orient = Qt::Horizontal; + if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) + orient = pb->state & QStyle::State_Horizontal ? Qt::Horizontal : Qt::Vertical; + partId = (orient == Qt::Horizontal) ? PP_BAR : PP_BARVERT; + themeNumber = QWindowsXPStylePrivate::ProgressTheme; + stateId = 1; + } + break; + + case CE_MenuEmptyArea: + case CE_MenuItem: + if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) + { + int tab = menuitem->tabWidth; + bool dis = !(menuitem->state & State_Enabled); + bool act = menuitem->state & State_Selected; + bool checkable = menuitem->menuHasCheckableItems; + bool checked = checkable ? menuitem->checked : false; + + // windows always has a check column, regardless whether we have an icon or not + int checkcol = qMax(menuitem->maxIconWidth, 12); + + int x, y, w, h; + rect.getRect(&x, &y, &w, &h); + + QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button); + p->fillRect(rect, fill); + + if (element == CE_MenuEmptyArea) + break; + + // draw separator ------------------------------------------------- + if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { + int yoff = y-1 + h / 2; + p->setPen(menuitem->palette.dark().color()); + p->drawLine(x, yoff, x+w, yoff); + ++yoff; + p->setPen(menuitem->palette.light().color()); + p->drawLine(x, yoff, x+w, yoff); + return; + } + + int xpos = x; + + // draw icon ------------------------------------------------------ + if (!menuitem->icon.isNull()) { + QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal; + if (act && !dis) + mode = QIcon::Active; + QPixmap pixmap = checked ? + menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option), mode, QIcon::On) : + menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option), mode); + const int pixw = pixmap.width() / pixmap.devicePixelRatio(); + const int pixh = pixmap.height() / pixmap.devicePixelRatio(); + QRect iconRect(0, 0, pixw, pixh); + iconRect.moveCenter(QRect(xpos, y, checkcol, h).center()); + QRect vIconRect = visualRect(option->direction, option->rect, iconRect); + p->setPen(menuitem->palette.text().color()); + p->setBrush(Qt::NoBrush); + if (checked) + p->drawRect(vIconRect.adjusted(-1, -1, 0, 0)); + p->drawPixmap(vIconRect.topLeft(), pixmap); + + // draw checkmark ------------------------------------------------- + } else if (checked) { + QStyleOptionMenuItem newMi = *menuitem; + newMi.state = State_None; + if (!dis) + newMi.state |= State_Enabled; + if (act) + newMi.state |= State_On; + + QRect checkMarkRect = QRect(menuitem->rect.x() + windowsItemFrame, + menuitem->rect.y() + windowsItemFrame, + checkcol - 2 * windowsItemFrame, + menuitem->rect.height() - 2*windowsItemFrame); + newMi.rect = visualRect(option->direction, option->rect, checkMarkRect); + proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p); + } + + QColor textColor = dis ? menuitem->palette.text().color() : + act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color(); + p->setPen(textColor); + + // draw text ------------------------------------------------------ + int xm = windowsItemFrame + checkcol + windowsItemHMargin; + xpos = menuitem->rect.x() + xm; + QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin); + QRect vTextRect = visualRect(option->direction, option->rect, textRect); + QString s = menuitem->text; + if (!s.isEmpty()) { + p->save(); + int t = s.indexOf(QLatin1Char('\t')); + int text_flags = Qt::AlignVCenter|Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine | Qt::AlignLeft; + if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem)) + text_flags |= Qt::TextHideMnemonic; + // draw tab text ---------------- + if (t >= 0) { + QRect vShortcutRect = visualRect(option->direction, option->rect, QRect(textRect.topRight(), menuitem->rect.bottomRight())); + if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option)) { + p->setPen(menuitem->palette.light().color()); + p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1)); + p->setPen(textColor); + } + p->drawText(vShortcutRect, text_flags, s.mid(t + 1)); + s = s.left(t); + } + QFont font = menuitem->font; + if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem) + font.setBold(true); + p->setFont(font); + if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option)) { + p->setPen(menuitem->palette.light().color()); + p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t)); + p->setPen(textColor); + } + p->drawText(vTextRect, text_flags, s); + p->restore(); + } + + // draw sub menu arrow -------------------------------------------- + if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) { + int dim = (h - 2) / 2; + PrimitiveElement arrow; + arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight; + xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim; + QRect vSubMenuRect = visualRect(option->direction, option->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim)); + QStyleOptionMenuItem newMI = *menuitem; + newMI.rect = vSubMenuRect; + newMI.state = dis ? State_None : State_Enabled; + if (act) + newMI.palette.setColor(QPalette::ButtonText, newMI.palette.highlightedText().color()); + proxy()->drawPrimitive(arrow, &newMI, p); + } + } + return; + + case CE_MenuBarItem: + if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) + { + if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem) + break; + + bool act = mbi->state & State_Selected; + bool dis = !(mbi->state & State_Enabled); + + QBrush fill = mbi->palette.brush(act ? QPalette::Highlight : QPalette::Button); + QPalette::ColorRole textRole = dis ? QPalette::Text: + act ? QPalette::HighlightedText : QPalette::ButtonText; + QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option), QIcon::Normal); + + uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; + if (!proxy()->styleHint(SH_UnderlineShortcut, mbi)) + alignment |= Qt::TextHideMnemonic; + + p->fillRect(rect, fill); + if (!pix.isNull()) + drawItemPixmap(p, mbi->rect, alignment, pix); + else + drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole); + } + return; +#if 0 && QT_CONFIG(dockwidget) + case CE_DockWidgetTitle: + if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) + { + int buttonMargin = 4; + int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt); + int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt); + bool isFloating = false; // widget && widget->isWindow(); + bool isActive = dwOpt->state & State_Active; + + const bool verticalTitleBar = dwOpt->verticalTitleBar; + + if (verticalTitleBar) { + rect = rect.transposed(); + + p->translate(rect.left() - 1, rect.top() + rect.width()); + p->rotate(-90); + p->translate(-rect.left() + 1, -rect.top()); + } + QRect r = rect.adjusted(0, 2, -1, -3); + QRect titleRect = r; + + if (dwOpt->closable) { + QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt).actualSize(QSize(10, 10)); + titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0); + } + + if (dwOpt->floatable) { + QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt).actualSize(QSize(10, 10)); + titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0); + } + + if (isFloating) { + titleRect.adjust(0, -fw, 0, 0); + if (option->window && option->window->icon().cacheKey() != QApplication::windowIcon().cacheKey()) + titleRect.adjust(titleRect.height() + mw, 0, 0, 0); + } else { + titleRect.adjust(mw, 0, 0, 0); + if (!dwOpt->floatable && !dwOpt->closable) + titleRect.adjust(0, 0, -mw, 0); + } + + if (!verticalTitleBar) + titleRect = visualRect(dwOpt->direction, r, titleRect); + + if (!isFloating) { + QPen oldPen = p->pen(); + QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width()); + p->setPen(dwOpt->palette.color(QPalette::Dark)); + p->drawRect(r); + + if (!titleText.isEmpty()) { + drawItemText(p, titleRect, + Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette, + dwOpt->state & State_Enabled, titleText, + QPalette::WindowText); + } + + p->setPen(oldPen); + } else { + themeNumber = QWindowsXPStylePrivate::WindowTheme; + if (isActive) + stateId = CS_ACTIVE; + else + stateId = CS_INACTIVE; + + int titleHeight = rect.height() - 2; + rect = rect.adjusted(-fw, -fw, fw, 0); + + XPThemeData theme(option->window, p, themeNumber, 0, stateId); + if (!theme.isValid()) + break; + + // Draw small type title bar + theme.rect = rect; + theme.partId = WP_SMALLCAPTION; + d->drawBackground(theme); + + // Figure out maximal button space on title bar + + QIcon ico = option->window->icon(); + bool hasIcon = (ico.cacheKey() != QApplication::windowIcon().cacheKey()); + if (hasIcon) { + QPixmap pxIco = ico.pixmap(titleHeight); + if (!verticalTitleBar && dwOpt->direction == Qt::RightToLeft) + p->drawPixmap(rect.width() - titleHeight - pxIco.width(), rect.bottom() - titleHeight - 2, pxIco); + else + p->drawPixmap(fw, rect.bottom() - titleHeight - 2, pxIco); + } + if (!dwOpt->title.isEmpty()) { + QPen oldPen = p->pen(); + QFont oldFont = p->font(); + QFont titleFont = oldFont; + titleFont.setBold(true); + p->setFont(titleFont); + QString titleText + = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width()); + + int result = TST_NONE; + GetThemeEnumValue(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result); + if (result != TST_NONE) { + COLORREF textShadowRef; + GetThemeColor(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef); + QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef)); + p->setPen(textShadow); + drawItemText(p, titleRect.adjusted(1, 1, 1, 1), + Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette, + dwOpt->state & State_Enabled, titleText); + } + + COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT); + QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText)); + p->setPen(textColor); + drawItemText(p, titleRect, + Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette, + dwOpt->state & State_Enabled, titleText); + p->setFont(oldFont); + p->setPen(oldPen); + } + + } + + return; + } + break; +#endif // QT_CONFIG(dockwidget) +#if 0 && QT_CONFIG(rubberband) + case CE_RubberBand: + if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) { + QColor highlight = option->palette.color(QPalette::Active, QPalette::Highlight); + p->save(); + p->setPen(highlight.darker(120)); + QColor dimHighlight(qMin(highlight.red()/2 + 110, 255), + qMin(highlight.green()/2 + 110, 255), + qMin(highlight.blue()/2 + 110, 255), + 127); + //(widget && widget->isTopLevel())? 255 : 127); + p->setBrush(dimHighlight); + p->drawRect(option->rect.adjusted(0, 0, -1, -1)); + p->restore(); + return; + } + break; +#endif // QT_CONFIG(rubberband) + case CE_HeaderEmptyArea: + if (option->state & State_Horizontal) + { + themeNumber = QWindowsXPStylePrivate::HeaderTheme; + stateId = HIS_NORMAL; + } + else { + QWindowsStyle::drawControl(CE_HeaderEmptyArea, option, p); + return; + } + break; + default: + break; + } + + XPThemeData theme(option->window, p, themeNumber, partId, stateId, rect); + if (!theme.isValid()) { + QWindowsStyle::drawControl(element, option, p); + return; + } + + theme.rotate = rotate; + theme.mirrorHorizontally = hMirrored; + theme.mirrorVertically = vMirrored; + d->drawBackground(theme); +} + +QRect QWindowsXPStylePrivate::scrollBarGripperBounds(QStyle::State flags, XPThemeData *theme) +{ + const bool horizontal = flags & QStyle::State_Horizontal; + const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(theme->window); + const QMargins contentsMargin = + (theme->margins(theme->rect, TMT_SIZINGMARGINS) * factor).toMargins(); + theme->partId = horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT; + const QSize size = (theme->size() * factor).toSize(); + + const int hSpace = theme->rect.width() - size.width(); + const int vSpace = theme->rect.height() - size.height(); + const bool sufficientSpace = (horizontal && hSpace > (contentsMargin.left() + contentsMargin.right())) + || vSpace > contentsMargin.top() + contentsMargin.bottom(); + return sufficientSpace ? QRect(theme->rect.topLeft() + QPoint(hSpace, vSpace) / 2, size) : QRect(); +} + +#if 0 && QT_CONFIG(mdiarea) +// Helper for drawing MDI buttons into the corner widget of QMenuBar in case a +// QMdiSubWindow is maximized. +static void populateMdiButtonTheme(const QStyle *proxy, + const QStyleOptionComplex *option, + QStyle::SubControl subControl, int part, + XPThemeData *theme) +{ + theme->partId = part; + theme->rect = proxy->subControlRect(QStyle::CC_MdiControls, option, subControl); + if (!option->state.testFlag(QStyle::State_Enabled)) + theme->stateId = CBS_INACTIVE; + else if (option->state.testFlag(QStyle::State_Sunken) && option->activeSubControls.testFlag(subControl)) + theme->stateId = CBS_PUSHED; + else if (option->state.testFlag(QStyle::State_MouseOver) && option->activeSubControls.testFlag(subControl)) + theme->stateId = CBS_HOT; + else + theme->stateId = CBS_NORMAL; +} + +// Calculate an small (max 2), empirical correction factor for scaling up +// WP_MDICLOSEBUTTON, WP_MDIRESTOREBUTTON, WP_MDIMINBUTTON, which are too +// small on High DPI screens (QTBUG-75927). +qreal mdiButtonCorrectionFactor(XPThemeData &theme, const QPaintDevice *pd = nullptr) +{ + const auto dpr = pd ? pd->devicePixelRatioF() : qApp->devicePixelRatio(); + const QSizeF nativeSize = QSizeF(theme.size()) / dpr; + const QSizeF requestedSize(theme.rect.size()); + const auto rawFactor = qMin(requestedSize.width() / nativeSize.width(), + requestedSize.height() / nativeSize.height()); + const auto factor = rawFactor >= qreal(2) ? qreal(2) : qreal(1); + return factor; +} +#endif // QT_CONFIG(mdiarea) + +static void populateTitleBarButtonTheme(const QStyle *proxy, + const QStyleOptionComplex *option, + QStyle::SubControl subControl, + bool isTitleBarActive, int part, + XPThemeData *theme) +{ + theme->rect = proxy->subControlRect(QStyle::CC_TitleBar, option, subControl); + theme->partId = part; + if (!(option->state & QStyle::State_Enabled)) + theme->stateId = RBS_DISABLED; + else if (option->activeSubControls == subControl && option->state.testFlag(QStyle::State_Sunken)) + theme->stateId = RBS_PUSHED; + else if (option->activeSubControls == subControl && option->state.testFlag(QStyle::State_MouseOver)) + theme->stateId = RBS_HOT; + else if (!isTitleBarActive) + theme->stateId = RBS_INACTIVE; + else + theme->stateId = RBS_NORMAL; +} + +/*! + \reimp +*/ +void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, + QPainter *p) const +{ + QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func()); + + if (!QWindowsXPStylePrivate::useXP()) { + QWindowsStyle::drawComplexControl(cc, option, p); + return; + } + + State flags = option->state; + SubControls sub = option->subControls; + QRect r = option->rect; + + int partId = 0; + int stateId = 0; + if (option->window && option->window->isActive()) + flags |= State_MouseOver; + + switch (cc) { +//#if QT_CONFIG(spinbox) + case CC_SpinBox: + if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) + { + XPThemeData theme(option->window, p, QWindowsXPStylePrivate::SpinTheme); + + if (sb->frame && (sub & SC_SpinBoxFrame)) { + partId = EP_EDITTEXT; + if (!(flags & State_Enabled)) + stateId = ETS_DISABLED; + else if (flags & State_HasFocus) + stateId = ETS_FOCUSED; + else + stateId = ETS_NORMAL; + + XPThemeData ftheme(option->window, p, QWindowsXPStylePrivate::EditTheme, + partId, stateId, r); + ftheme.noContent = true; + d->drawBackground(ftheme); + } + if (sub & SC_SpinBoxUp) { + theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp); + partId = SPNP_UP; + if (!(sb->stepEnabled & QStyleOptionSpinBox::StepUpEnabled) || !(flags & State_Enabled)) + stateId = UPS_DISABLED; + else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) + stateId = UPS_PRESSED; + else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver)) + stateId = UPS_HOT; + else + stateId = UPS_NORMAL; + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + if (sub & SC_SpinBoxDown) { + theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown); + partId = SPNP_DOWN; + if (!(sb->stepEnabled & QStyleOptionSpinBox::StepDownEnabled) || !(flags & State_Enabled)) + stateId = DNS_DISABLED; + else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) + stateId = DNS_PRESSED; + else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver)) + stateId = DNS_HOT; + else + stateId = DNS_NORMAL; + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + } + break; +//#endif // QT_CONFIG(spinbox) +//#if QT_CONFIG(combobox) + case CC_ComboBox: + if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) + { + if (cmb->editable) { + if (sub & SC_ComboBoxEditField) { + partId = EP_EDITBORDER_NOSCROLL; + if (!(flags & State_Enabled)) + stateId = ETS_DISABLED; + else if (flags & State_MouseOver) + stateId = ETS_HOT; + else if (flags & State_HasFocus) + stateId = ETS_FOCUSED; + else + stateId = ETS_NORMAL; + + XPThemeData theme(option->window, p, + QWindowsXPStylePrivate::EditTheme, + partId, stateId, r); + + d->drawBackground(theme); + } + if (sub & SC_ComboBoxArrow) { + QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow); + XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ComboboxTheme); + theme.rect = subRect; + partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT; + + if (!(cmb->state & State_Enabled)) + stateId = CBXS_DISABLED; + else if (cmb->state & State_Sunken || cmb->state & State_On) + stateId = CBXS_PRESSED; + else if (cmb->state & State_MouseOver && option->activeSubControls & SC_ComboBoxArrow) + stateId = CBXS_HOT; + else + stateId = CBXS_NORMAL; + + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + + } else { + if (sub & SC_ComboBoxFrame) { + XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ComboboxTheme); + theme.rect = option->rect; + theme.partId = CP_READONLY; + if (!(cmb->state & State_Enabled)) + theme.stateId = CBXS_DISABLED; + else if (cmb->state & State_Sunken || cmb->state & State_On) + theme.stateId = CBXS_PRESSED; + else if (cmb->state & State_MouseOver) + theme.stateId = CBXS_HOT; + else + theme.stateId = CBXS_NORMAL; + d->drawBackground(theme); + } + if (sub & SC_ComboBoxArrow) { + XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ComboboxTheme); + theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow); + theme.partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT; + if (!(cmb->state & State_Enabled)) + theme.stateId = CBXS_DISABLED; + else + theme.stateId = CBXS_NORMAL; + d->drawBackground(theme); + } + if ((sub & SC_ComboBoxEditField) && (flags & State_HasFocus)) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*cmb); + fropt.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField); + proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p); + } + } + } + break; +//#endif // QT_CONFIG(combobox) + case CC_ScrollBar: + if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) + { + XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ScrollBarTheme); + bool maxedOut = (scrollbar->maximum == scrollbar->minimum); + if (maxedOut) + flags &= ~State_Enabled; + + bool isHorz = flags & State_Horizontal; + bool isRTL = option->direction == Qt::RightToLeft; + if (sub & SC_ScrollBarAddLine) { + theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine); + partId = SBP_ARROWBTN; + if (!(flags & State_Enabled)) + stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED); + else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken)) + stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED); + else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver)) + stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT); + else + stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL); + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + if (sub & SC_ScrollBarSubLine) { + theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine); + partId = SBP_ARROWBTN; + if (!(flags & State_Enabled)) + stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED); + else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken)) + stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED); + else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver)) + stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT); + else + stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL); + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + if (maxedOut) { + if (sub & SC_ScrollBarSlider) { + theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider); + theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage)); + theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage)); + partId = scrollbar->orientation == Qt::Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT; + stateId = SCRBS_DISABLED; + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + } else { + if (sub & SC_ScrollBarSubPage) { + theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage); + partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT; + if (!(flags & State_Enabled)) + stateId = SCRBS_DISABLED; + else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken)) + stateId = SCRBS_PRESSED; + else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver)) + stateId = SCRBS_HOT; + else + stateId = SCRBS_NORMAL; + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + if (sub & SC_ScrollBarAddPage) { + theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage); + partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT; + if (!(flags & State_Enabled)) + stateId = SCRBS_DISABLED; + else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken)) + stateId = SCRBS_PRESSED; + else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver)) + stateId = SCRBS_HOT; + else + stateId = SCRBS_NORMAL; + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + if (sub & SC_ScrollBarSlider) { + // The style paint the slider handle so that it is surrounded by transparent areas + // on each side. These areas have the same size as the Left/Right (or Top/Left) buttons. + // This is probaly done in order for the handle to travel all along the geometry + // of the slider, while the handle still not occluding the buttons. + // We do not want those transparent areas, so we clip them off here. + const int extentForButton = proxy()->pixelMetric(PM_ScrollBarExtent, scrollbar); + QSize extend(extentForButton, 0); + if (scrollbar->orientation == Qt::Vertical) + extend.transpose(); + + QRect rect = r; // 'r' is the rect for the scrollbar handle + rect.setSize(rect.size() + 2 * extend); // 'rect' is the rect for the whole scrollbar + p->setClipRect(r); // clip off button areas + p->translate(-extend.width(), -extend.height()); // translate left button area away + + theme.rect = rect; + if (!(flags & State_Enabled)) + stateId = SCRBS_DISABLED; + else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken)) + stateId = SCRBS_PRESSED; + else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver)) + stateId = SCRBS_HOT; + else + stateId = SCRBS_NORMAL; + + // Draw handle + theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT; + theme.stateId = stateId; + d->drawBackground(theme); + + const QRect gripperBounds = QWindowsXPStylePrivate::scrollBarGripperBounds(flags, &theme); + // Draw gripper if there is enough space + if (!gripperBounds.isEmpty()) { + p->save(); + theme.rect = gripperBounds; + p->setClipRegion(d->region(theme));// Only change inside the region of the gripper + d->drawBackground(theme); // Transparent gripper ontop of background + p->restore(); + } + } + } + } + break; + +//#if QT_CONFIG(slider) + case CC_Slider: + if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) + { + XPThemeData theme(option->window, p, QWindowsXPStylePrivate::TrackBarTheme); + QRect slrect = slider->rect; + QRegion tickreg = slrect; + if (sub & SC_SliderGroove) { + theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove); + if (slider->orientation == Qt::Horizontal) { + partId = TKP_TRACK; + stateId = TRS_NORMAL; + theme.rect = QRect(slrect.left(), theme.rect.center().y() - 2, slrect.width(), 4); + } else { + partId = TKP_TRACKVERT; + stateId = TRVS_NORMAL; + theme.rect = QRect(theme.rect.center().x() - 2, slrect.top(), 4, slrect.height()); + } + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + tickreg -= theme.rect; + } + if (sub & SC_SliderTickmarks) { + int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider); + int ticks = slider->tickPosition; + int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider); + int len = proxy()->pixelMetric(PM_SliderLength, slider); + int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider); + int interval = slider->tickInterval; + if (interval <= 0) { + interval = slider->singleStep; + if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval, + available) + - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, + 0, available) < 3) + interval = slider->pageStep; + } + if (!interval) + interval = 1; + int fudge = len / 2; + int pos; + int bothOffset = (ticks & QStyleOptionSlider::TicksAbove && ticks & QStyleOptionSlider::TicksBelow) ? 1 : 0; + p->setPen(d->sliderTickColor); + QVarLengthArray<QLine, 32> lines; + int v = slider->minimum; + while (v <= slider->maximum + 1) { + if (v == slider->maximum + 1 && interval == 1) + break; + const int v_ = qMin(v, slider->maximum); + int tickLength = (v_ == slider->minimum || v_ >= slider->maximum) ? 4 : 3; + pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, + v_, available) + fudge; + if (slider->orientation == Qt::Horizontal) { + if (ticks & QStyleOptionSlider::TicksAbove) + lines.append(QLine(pos, tickOffset - 1 - bothOffset, + pos, tickOffset - 1 - bothOffset - tickLength)); + + if (ticks & QStyleOptionSlider::TicksBelow) + lines.append(QLine(pos, tickOffset + thickness + bothOffset, + pos, tickOffset + thickness + bothOffset + tickLength)); + } else { + if (ticks & QStyleOptionSlider::TicksAbove) + lines.append(QLine(tickOffset - 1 - bothOffset, pos, + tickOffset - 1 - bothOffset - tickLength, pos)); + + if (ticks & QStyleOptionSlider::TicksBelow) + lines.append(QLine(tickOffset + thickness + bothOffset, pos, + tickOffset + thickness + bothOffset + tickLength, pos)); + } + // in the case where maximum is max int + int nextInterval = v + interval; + if (nextInterval < v) + break; + v = nextInterval; + } + if (!lines.isEmpty()) { + p->save(); + p->translate(slrect.topLeft()); + p->drawLines(lines.constData(), lines.size()); + p->restore(); + } + } + if (sub & SC_SliderHandle) { + theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle); + if (slider->orientation == Qt::Horizontal) { + if (slider->tickPosition == QStyleOptionSlider::TicksAbove) + partId = TKP_THUMBTOP; + else if (slider->tickPosition == QStyleOptionSlider::TicksBelow) + partId = TKP_THUMBBOTTOM; + else + partId = TKP_THUMB; + + if (!(slider->state & State_Enabled)) + stateId = TUS_DISABLED; + else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken)) + stateId = TUS_PRESSED; + else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver)) + stateId = TUS_HOT; + else if (flags & State_HasFocus) + stateId = TUS_FOCUSED; + else + stateId = TUS_NORMAL; + } else { + if (slider->tickPosition == QStyleOptionSlider::TicksLeft) + partId = TKP_THUMBLEFT; + else if (slider->tickPosition == QStyleOptionSlider::TicksRight) + partId = TKP_THUMBRIGHT; + else + partId = TKP_THUMBVERT; + + if (!(slider->state & State_Enabled)) + stateId = TUVS_DISABLED; + else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken)) + stateId = TUVS_PRESSED; + else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver)) + stateId = TUVS_HOT; + else if (flags & State_HasFocus) + stateId = TUVS_FOCUSED; + else + stateId = TUVS_NORMAL; + } + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } + if (sub & SC_SliderGroove && slider->state & State_HasFocus) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*slider); + fropt.rect = subElementRect(SE_SliderFocusRect, slider); + proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p); + } + } + break; +//#endif +#if 0 && QT_CONFIG(toolbutton) + case CC_ToolButton: + if (const QStyleOptionToolButton *toolbutton + = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { + QRect button, menuarea; + button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton); + menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu); + + State bflags = toolbutton->state & ~State_Sunken; + State mflags = bflags; + bool autoRaise = flags & State_AutoRaise; + if (autoRaise) { + if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) { + bflags &= ~State_Raised; + } + } + + if (toolbutton->state & State_Sunken) { + if (toolbutton->activeSubControls & SC_ToolButton) { + bflags |= State_Sunken; + mflags |= State_MouseOver | State_Sunken; + } else if (toolbutton->activeSubControls & SC_ToolButtonMenu) { + mflags |= State_Sunken; + bflags |= State_MouseOver; + } + } + + QStyleOption tool = *toolbutton; + if (toolbutton->subControls & SC_ToolButton) { + if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) { + if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup && autoRaise) { + XPThemeData theme(option->window, p, QWindowsXPStylePrivate::ToolBarTheme); + theme.partId = TP_SPLITBUTTON; + theme.rect = button; + if (!(bflags & State_Enabled)) + stateId = TS_DISABLED; + else if (bflags & State_Sunken) + stateId = TS_PRESSED; + else if (bflags & State_MouseOver || !(flags & State_AutoRaise)) + stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT; + else if (bflags & State_On) + stateId = TS_CHECKED; + else + stateId = TS_NORMAL; + if (option->direction == Qt::RightToLeft) + theme.mirrorHorizontally = true; + theme.stateId = stateId; + d->drawBackground(theme); + } else { + tool.rect = option->rect; + tool.state = bflags; + if (autoRaise) // for tool bars + proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p); + else + proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p); + } + } + } + + if (toolbutton->state & State_HasFocus) { + QStyleOptionFocusRect fr; + fr.QStyleOption::operator=(*toolbutton); + fr.rect.adjust(3, 3, -3, -3); + if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) + fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, + toolbutton), 0); + proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p); + } + QStyleOptionToolButton label = *toolbutton; + label.state = bflags; + int fw = 2; + if (!autoRaise) + label.state &= ~State_Sunken; + label.rect = button.adjusted(fw, fw, -fw, -fw); + proxy()->drawControl(CE_ToolButtonLabel, &label, p); + + if (toolbutton->subControls & SC_ToolButtonMenu) { + tool.rect = menuarea; + tool.state = mflags; + if (autoRaise) { + proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p); + } else { + tool.state = mflags; + menuarea.adjust(-2, 0, 0, 0); + // Draw menu button + if ((bflags & State_Sunken) != (mflags & State_Sunken)){ + p->save(); + p->setClipRect(menuarea); + tool.rect = option->rect; + proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p); + p->restore(); + } + // Draw arrow + p->save(); + p->setPen(option->palette.dark().color()); + p->drawLine(menuarea.left(), menuarea.top() + 3, + menuarea.left(), menuarea.bottom() - 3); + p->setPen(option->palette.light().color()); + p->drawLine(menuarea.left() - 1, menuarea.top() + 3, + menuarea.left() - 1, menuarea.bottom() - 3); + + tool.rect = menuarea.adjusted(2, 3, -2, -1); + proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p); + p->restore(); + } + } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) { + int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton); + QRect ir = toolbutton->rect; + QStyleOptionToolButton newBtn = *toolbutton; + newBtn.rect = QRect(ir.right() + 4 - mbi, ir.height() - mbi + 4, mbi - 5, mbi - 5); + proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p); + } + } + break; +#endif // QT_CONFIG(toolbutton) + + case CC_TitleBar: + { + if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) + { + const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(option); + bool isActive = tb->titleBarState & QStyle::State_Active; + XPThemeData theme(option->window, p, QWindowsXPStylePrivate::WindowTheme); + if (sub & SC_TitleBarLabel) { + + partId = (tb->titleBarState & Qt::WindowMinimized) ? WP_MINCAPTION : WP_CAPTION; + theme.rect = option->rect; + if (!(option->state & QStyle::State_Enabled)) + stateId = CS_DISABLED; + else if (isActive) + stateId = CS_ACTIVE; + else + stateId = CS_INACTIVE; + + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + + QRect ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarLabel); + + int result = TST_NONE; + GetThemeEnumValue(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result); + if (result != TST_NONE) { + COLORREF textShadowRef; + GetThemeColor(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef); + QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef)); + p->setPen(textShadow); + p->drawText(int(ir.x() + 3 * factor), int(ir.y() + 2 * factor), + int(ir.width() - 1 * factor), ir.height(), + Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text); + } + COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT); + QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText)); + p->setPen(textColor); + p->drawText(int(ir.x() + 2 * factor), int(ir.y() + 1 * factor), + int(ir.width() - 2 * factor), ir.height(), + Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text); + } + if (sub & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) { + theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarSysMenu); + partId = WP_SYSBUTTON; + if (!(option->state & QStyle::State_Enabled) || !isActive) + stateId = SBS_DISABLED; + else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_Sunken)) + stateId = SBS_PUSHED; + else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_MouseOver)) + stateId = SBS_HOT; + else + stateId = SBS_NORMAL; + if (!tb->icon.isNull()) { + tb->icon.paint(p, theme.rect); + } else { + theme.partId = partId; + theme.stateId = stateId; + if (theme.size().isEmpty()) { + int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb); + QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, tb).pixmap(iconSize, iconSize); + p->save(); + drawItemPixmap(p, theme.rect, Qt::AlignCenter, pm); + p->restore(); + } else { + d->drawBackground(theme); + } + } + } + + if (sub & SC_TitleBarMinButton && tb->titleBarFlags & Qt::WindowMinimizeButtonHint + && !(tb->titleBarState & Qt::WindowMinimized)) { + populateTitleBarButtonTheme(proxy(), option, SC_TitleBarMinButton, isActive, WP_MINBUTTON, &theme); + d->drawBackground(theme); + } + if (sub & SC_TitleBarMaxButton && tb->titleBarFlags & Qt::WindowMaximizeButtonHint + && !(tb->titleBarState & Qt::WindowMaximized)) { + populateTitleBarButtonTheme(proxy(), option, SC_TitleBarMaxButton, isActive, WP_MAXBUTTON, &theme); + d->drawBackground(theme); + } + if (sub & SC_TitleBarContextHelpButton + && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) { + populateTitleBarButtonTheme(proxy(), option, SC_TitleBarContextHelpButton, isActive, WP_HELPBUTTON, &theme); + d->drawBackground(theme); + } + bool drawNormalButton = (sub & SC_TitleBarNormalButton) + && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint) + && (tb->titleBarState & Qt::WindowMinimized)) + || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint) + && (tb->titleBarState & Qt::WindowMaximized))); + if (drawNormalButton) { + populateTitleBarButtonTheme(proxy(), option, SC_TitleBarNormalButton, isActive, WP_RESTOREBUTTON, &theme); + d->drawBackground(theme); + } + if (sub & SC_TitleBarShadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint + && !(tb->titleBarState & Qt::WindowMinimized)) { + populateTitleBarButtonTheme(proxy(), option, SC_TitleBarShadeButton, isActive, WP_MINBUTTON, &theme); + d->drawBackground(theme); + } + if (sub & SC_TitleBarUnshadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint + && tb->titleBarState & Qt::WindowMinimized) { + populateTitleBarButtonTheme(proxy(), option, SC_TitleBarUnshadeButton, isActive, WP_RESTOREBUTTON, &theme); + d->drawBackground(theme); + } + if (sub & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) { + populateTitleBarButtonTheme(proxy(), option, SC_TitleBarCloseButton, isActive, WP_CLOSEBUTTON, &theme); + d->drawBackground(theme); + } + } + } + break; + +#if 0 && QT_CONFIG(mdiarea) + case CC_MdiControls: + { + XPThemeData theme(option->window, p, QWindowsXPStylePrivate::WindowTheme, WP_MDICLOSEBUTTON, CBS_NORMAL); + if (Q_UNLIKELY(!theme.isValid())) + return; + + if (option->subControls.testFlag(SC_MdiCloseButton)) { + populateMdiButtonTheme(proxy(), option, SC_MdiCloseButton, WP_MDICLOSEBUTTON, &theme); + d->drawBackground(theme, mdiButtonCorrectionFactor(theme)); + } + if (option->subControls.testFlag(SC_MdiNormalButton)) { + populateMdiButtonTheme(proxy(), option, SC_MdiNormalButton, WP_MDIRESTOREBUTTON, &theme); + d->drawBackground(theme, mdiButtonCorrectionFactor(theme)); + } + if (option->subControls.testFlag(QStyle::SC_MdiMinButton)) { + populateMdiButtonTheme(proxy(), option, SC_MdiMinButton, WP_MDIMINBUTTON, &theme); + d->drawBackground(theme, mdiButtonCorrectionFactor(theme)); + } + } + break; +#endif // QT_CONFIG(mdiarea) +#if 0 && QT_CONFIG(dial) + case CC_Dial: + if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(option)) + QStyleHelper::drawDial(dial, p); + break; +#endif // QT_CONFIG(dial) + default: + QWindowsStyle::drawComplexControl(cc, option, p); + break; + } +} + +static inline Qt::Orientation progressBarOrientation(const QStyleOption *option = nullptr) +{ + if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) + return pb->state & QStyle::State_Horizontal ? Qt::Horizontal : Qt::Vertical; + return Qt::Horizontal; +} + +int QWindowsXPStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option) +{ + switch (pm) { + case QStyle::PM_IndicatorWidth: + return XPThemeData::themeSize(option->window, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).width(); + case QStyle::PM_IndicatorHeight: + return XPThemeData::themeSize(option->window, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).height(); + case QStyle::PM_ExclusiveIndicatorWidth: + return XPThemeData::themeSize(option->window, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).width(); + case QStyle::PM_ExclusiveIndicatorHeight: + return XPThemeData::themeSize(option->window, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).height(); + case QStyle::PM_ProgressBarChunkWidth: + return progressBarOrientation(option) == Qt::Horizontal + ? XPThemeData::themeSize(option->window, nullptr, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNK).width() + : XPThemeData::themeSize(option->window, nullptr, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNKVERT).height(); + case QStyle::PM_SliderThickness: + return XPThemeData::themeSize(option->window, nullptr, QWindowsXPStylePrivate::TrackBarTheme, TKP_THUMB).height(); + case QStyle::PM_TitleBarHeight: + return option->window && (option->window->type() == Qt::Tool) + ? GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME) + : GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME); + case QStyle::PM_MdiSubWindowFrameWidth: + return XPThemeData::themeSize(option->window, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_FRAMELEFT, FS_ACTIVE).width(); + case QStyle::PM_DockWidgetFrameWidth: + return XPThemeData::themeSize(option->window, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_SMALLFRAMERIGHT, FS_ACTIVE).width(); + default: + break; + } + return QWindowsXPStylePrivate::InvalidMetric; +} + +/*! \reimp */ +int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option) const +{ + if (!QWindowsXPStylePrivate::useXP()) + return QWindowsStyle::pixelMetric(pm, option); + + int res = QWindowsXPStylePrivate::pixelMetricFromSystemDp(pm, option); + if (res != QWindowsStylePrivate::InvalidMetric) + return qRound(qreal(res) * QWindowsStylePrivate::nativeMetricScaleFactor(option)); + + res = 0; + switch (pm) { + case PM_MenuBarPanelWidth: + case PM_ButtonDefaultIndicator: + res = 0; + break; + + case PM_DefaultFrameWidth: + res = 1; + //res = qobject_cast<const QListView*>(widget) ? 2 : 1; + break; + case PM_MenuPanelWidth: + case PM_SpinBoxFrameWidth: + res = 1; + break; + + case PM_TabBarTabOverlap: + case PM_MenuHMargin: + case PM_MenuVMargin: + res = 2; + break; +#if 0 + case PM_TabBarBaseOverlap: + if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) { + switch (tab->shape) { + case QTabBar::RoundedNorth: + case QTabBar::TriangularNorth: + case QTabBar::RoundedWest: + case QTabBar::TriangularWest: + res = 1; + break; + case QTabBar::RoundedSouth: + case QTabBar::TriangularSouth: + res = 2; + break; + case QTabBar::RoundedEast: + case QTabBar::TriangularEast: + res = 3; + break; + } + } + break; +#endif + case PM_SplitterWidth: + res = QStyleHelper::dpiScaled(5., option); + break; + + case PM_MdiSubWindowMinimizedWidth: + res = 160; + break; + +#if 0 && QT_CONFIG(toolbar) + case PM_ToolBarHandleExtent: + res = int(QStyleHelper::dpiScaled(8., option)); + break; + +#endif // QT_CONFIG(toolbar) + case PM_DockWidgetSeparatorExtent: + case PM_DockWidgetTitleMargin: + res = int(QStyleHelper::dpiScaled(4., option)); + break; + + case PM_ButtonShiftHorizontal: + case PM_ButtonShiftVertical: + res = qstyleoption_cast<const QStyleOptionToolButton *>(option) ? 1 : 0; + break; + + default: + res = QWindowsStyle::pixelMetric(pm, option); + } + + return res; +} + +/* + This function is used by subControlRect to check if a button + should be drawn for the given subControl given a set of window flags. +*/ +static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){ + + bool isMinimized = tb->titleBarState & Qt::WindowMinimized; + bool isMaximized = tb->titleBarState & Qt::WindowMaximized; + const uint flags = tb->titleBarFlags; + bool retVal = false; + switch (sc) { + case QStyle::SC_TitleBarContextHelpButton: + if (flags & Qt::WindowContextHelpButtonHint) + retVal = true; + break; + case QStyle::SC_TitleBarMinButton: + if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint)) + retVal = true; + break; + case QStyle::SC_TitleBarNormalButton: + if (isMinimized && (flags & Qt::WindowMinimizeButtonHint)) + retVal = true; + else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint)) + retVal = true; + break; + case QStyle::SC_TitleBarMaxButton: + if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint)) + retVal = true; + break; + case QStyle::SC_TitleBarShadeButton: + if (!isMinimized && flags & Qt::WindowShadeButtonHint) + retVal = true; + break; + case QStyle::SC_TitleBarUnshadeButton: + if (isMinimized && flags & Qt::WindowShadeButtonHint) + retVal = true; + break; + case QStyle::SC_TitleBarCloseButton: + if (flags & Qt::WindowSystemMenuHint) + retVal = true; + break; + case QStyle::SC_TitleBarSysMenu: + if (flags & Qt::WindowSystemMenuHint) + retVal = true; + break; + default : + retVal = true; + } + return retVal; +} + +/*! + \reimp +*/ +QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option, + SubControl subControl) const +{ + if (!QWindowsXPStylePrivate::useXP()) + return QWindowsStyle::subControlRect(cc, option, subControl); + + QRect rect; + + switch (cc) { + case CC_GroupBox: + rect = visualRect(option->direction, option->rect, + QWindowsStyle::subControlRect(cc, option, subControl)); + if (subControl == QStyle::SC_GroupBoxContents) { + // This will add the margins that was added by QLayouts in QtWidgets + // (default to 9 for layouts inside a QGroupBox) + rect.adjust(9, 9, -9, -9); + } + break; + case CC_TitleBar: + if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) { + if (!buttonVisible(subControl, tb)) + return rect; + const bool isToolTitle = false; + const int height = tb->rect.height(); + const int width = tb->rect.width(); + const int buttonMargin = int(QStyleHelper::dpiScaled(4, option)); + const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(option); + int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) * factor) + - buttonMargin; + int buttonWidth = qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor) + - buttonMargin; + const int delta = buttonWidth + 2; + int controlTop = option->rect.bottom() - buttonHeight - 2; + const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option); + const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0; + const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0; + const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0; + const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0; + const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0; + bool isMinimized = tb->titleBarState & Qt::WindowMinimized; + bool isMaximized = tb->titleBarState & Qt::WindowMaximized; + int offset = 0; + + switch (subControl) { + case SC_TitleBarLabel: + rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height); + if (isToolTitle) { + if (sysmenuHint) { + rect.adjust(0, 0, -buttonWidth - 3, 0); + } + if (minimizeHint || maximizeHint) + rect.adjust(0, 0, -buttonWidth - 2, 0); + } else { + if (sysmenuHint) { + const int leftOffset = height - 8; + rect.adjust(leftOffset, 0, 0, 0); + } + if (minimizeHint) + rect.adjust(0, 0, -buttonWidth - 2, 0); + if (maximizeHint) + rect.adjust(0, 0, -buttonWidth - 2, 0); + if (contextHint) + rect.adjust(0, 0, -buttonWidth - 2, 0); + if (shadeHint) + rect.adjust(0, 0, -buttonWidth - 2, 0); + } + break; + + case SC_TitleBarContextHelpButton: + if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) + offset += delta; + Q_FALLTHROUGH(); + case SC_TitleBarMinButton: + if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)) + offset += delta; + else if (subControl == SC_TitleBarMinButton) + break; + Q_FALLTHROUGH(); + case SC_TitleBarNormalButton: + if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)) + offset += delta; + else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)) + offset += delta; + else if (subControl == SC_TitleBarNormalButton) + break; + Q_FALLTHROUGH(); + case SC_TitleBarMaxButton: + if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)) + offset += delta; + else if (subControl == SC_TitleBarMaxButton) + break; + Q_FALLTHROUGH(); + case SC_TitleBarShadeButton: + if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint)) + offset += delta; + else if (subControl == SC_TitleBarShadeButton) + break; + Q_FALLTHROUGH(); + case SC_TitleBarUnshadeButton: + if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint)) + offset += delta; + else if (subControl == SC_TitleBarUnshadeButton) + break; + Q_FALLTHROUGH(); + case SC_TitleBarCloseButton: + if (tb->titleBarFlags & Qt::WindowSystemMenuHint) + offset += delta; + else if (subControl == SC_TitleBarCloseButton) + break; + + rect.setRect(width - offset - controlTop + 1, controlTop, + buttonWidth, buttonHeight); + break; + + case SC_TitleBarSysMenu: + { + const int controlTop = 6; + const int controlHeight = height - controlTop - 3; + const int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, option); + QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent)); + if (tb->icon.isNull()) + iconSize = QSize(controlHeight, controlHeight); + int hPad = (controlHeight - iconSize.height())/2; + int vPad = (controlHeight - iconSize.width())/2; + rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height()); + } + break; + default: + break; + } + } + break; + + case CC_ComboBox: + if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { + const int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height(); + const int xpos = x + wi - qRound(QStyleHelper::dpiScaled(1 + 16, option)); + + switch (subControl) { + case SC_ComboBoxFrame: + rect = cmb->rect; + break; + + case SC_ComboBoxArrow: { + const qreal dpi = QStyleHelper::dpi(option); + rect = QRect(xpos, y + qRound(QStyleHelper::dpiScaled(1, dpi)), + qRound(QStyleHelper::dpiScaled(16, dpi)), + he - qRound(QStyleHelper::dpiScaled(2, dpi))); + } + break; + + case SC_ComboBoxEditField: { + const qreal dpi = QStyleHelper::dpi(option); + const int frame = qRound(QStyleHelper::dpiScaled(2, dpi)); + rect = QRect(x + frame, y + frame, + wi - qRound(QStyleHelper::dpiScaled(3 + 16, dpi)), + he - qRound(QStyleHelper::dpiScaled(4, dpi))); + } + break; + + case SC_ComboBoxListBoxPopup: + rect = cmb->rect; + break; + + default: + break; + } + } + break; +#if 0 && QT_CONFIG(mdiarea) + case CC_MdiControls: + { + int numSubControls = 0; + if (option->subControls & SC_MdiCloseButton) + ++numSubControls; + if (option->subControls & SC_MdiMinButton) + ++numSubControls; + if (option->subControls & SC_MdiNormalButton) + ++numSubControls; + if (numSubControls == 0) + break; + + int buttonWidth = option->rect.width() / numSubControls; + int offset = 0; + switch (subControl) { + case SC_MdiCloseButton: + // Only one sub control, no offset needed. + if (numSubControls == 1) + break; + offset += buttonWidth; + Q_FALLTHROUGH(); + case SC_MdiNormalButton: + // No offset needed if + // 1) There's only one sub control + // 2) We have a close button and a normal button (offset already added in SC_MdiClose) + if (numSubControls == 1 || (numSubControls == 2 && !(option->subControls & SC_MdiMinButton))) + break; + if (option->subControls & SC_MdiNormalButton) + offset += buttonWidth; + break; + default: + break; + } + rect = QRect(offset, 0, buttonWidth, option->rect.height()); + break; + } +#endif // QT_CONFIG(mdiarea) + + default: + rect = visualRect(option->direction, option->rect, + QWindowsStyle::subControlRect(cc, option, subControl)); + break; + } + return visualRect(option->direction, option->rect, rect); +} + +/*! + \reimp +*/ +QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *option, + const QSize &contentsSize) const +{ + if (!QWindowsXPStylePrivate::useXP()) + return QWindowsStyle::sizeFromContents(ct, option, contentsSize); + + QSize sz(contentsSize); + switch (ct) { + case CT_LineEdit: + case CT_ComboBox: + { + if (contentsSize.isEmpty()) { + // Minimum size + return QSize(20, 20); + } + XPThemeData buttontheme(option->window, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_PUSHBUTTON, PBS_NORMAL); + if (buttontheme.isValid()) { + const QMarginsF borderSize = buttontheme.margins(); + if (!borderSize.isNull()) { + const qreal margin = qreal(2); + sz.rwidth() += qRound(borderSize.left() + borderSize.right() - margin); + sz.rheight() += int(borderSize.bottom() + borderSize.top() - margin); + } + const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin, option) + 1); + sz += QSize(qMax(pixelMetric(QStyle::PM_ScrollBarExtent, option) + + textMargins, 23), 0); //arrow button + } + } + break; + case CT_TabWidget: + sz += QSize(6, 6); + break; + case CT_Menu: + sz += QSize(1, 0); + break; +#if 0 && QT_CONFIG(menubar) + case CT_MenuBarItem: + if (!sz.isEmpty()) + sz += QSize(windowsItemHMargin * 5 + 1, 6); + break; +#endif + case CT_MenuItem: + if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) + { + if (menuitem->menuItemType != QStyleOptionMenuItem::Separator) { + sz = QWindowsStyle::sizeFromContents(ct, option, sz); + sz.setHeight(sz.height() - 2); + return sz; + } + } + sz = QWindowsStyle::sizeFromContents(ct, option, sz); + break; + + case CT_MdiControls: { + sz.setHeight(int(QStyleHelper::dpiScaled(19, option))); + int width = 54; + if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(option)) { + width = 0; + if (styleOpt->subControls & SC_MdiMinButton) + width += 17 + 1; + if (styleOpt->subControls & SC_MdiNormalButton) + width += 17 + 1; + if (styleOpt->subControls & SC_MdiCloseButton) + width += 17 + 1; + } + sz.setWidth(int(QStyleHelper::dpiScaled(width, option))); + } + break; + + case CT_Slider: + if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) { + QStyle::SubControls sub = slider->subControls; + const int TickSpace = 5; + int thick = proxy()->pixelMetric(QStyle::PM_SliderThickness, slider); + + if (slider->tickPosition & QStyleOptionSlider::TicksAbove) + thick += TickSpace; + if (slider->tickPosition & QStyleOptionSlider::TicksBelow) + thick += TickSpace; + sz.setWidth(thick); + + if (sub & SC_SliderGroove) { + const int SliderLength = 84; + sz.setHeight(SliderLength); + } + if (slider->orientation == Qt::Horizontal) + sz.transpose(); + if (sub & SC_SliderHandle) { + const QSize s = proxy()->subControlRect(CC_Slider, slider, SC_SliderHandle).size(); + sz = sz.expandedTo(s); + } + } + break; + case CT_ScrollBar : + // Make sure that the scroll bar is large enough to display the thumb indicator. + if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) { + const int scrollBarHeight = proxy()->pixelMetric(QStyle::PM_ScrollBarExtent, slider); + const int scrollBarSliderMin = proxy()->pixelMetric(QStyle::PM_ScrollBarSliderMin, slider); + int &szw = slider->orientation == Qt::Horizontal ? sz.rwidth() : sz.rheight(); + int &szh = slider->orientation == Qt::Horizontal ? sz.rheight() : sz.rwidth(); + if (slider->subControls & SC_ScrollBarSlider) { + szw = qMax(szw, scrollBarSliderMin); + szh = scrollBarHeight; + } else if (slider->subControls & SC_ScrollBarGroove) { + szw = qMax(szw, scrollBarSliderMin + 2 * scrollBarHeight); + szh = scrollBarHeight; + } else if (slider->subControls & (SC_ScrollBarAddLine| SC_ScrollBarSubLine)) { + // Assume that the AddLine and SubLine buttons have the same size, and just query + // for the size of AddLine + const int sbextent = proxy()->pixelMetric(PM_ScrollBarExtent, slider); + szw = qMax(szw, sbextent); + szh = scrollBarHeight; + } + } + break; + default: + sz = QWindowsStyle::sizeFromContents(ct, option, sz); + break; + } + + return sz; +} + + +/*! \reimp */ +int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, + QStyleHintReturn *returnData) const +{ + QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func()); + if (!QWindowsXPStylePrivate::useXP()) + return QWindowsStyle::styleHint(hint, option, returnData); + + int res = 0; + switch (hint) { + + case SH_EtchDisabledText: + //res = (qobject_cast<const QLabel*>(widget) != 0); + res = 0; + break; + + case SH_SpinControls_DisableOnBounds: + res = 0; + break; + + case SH_TitleBar_AutoRaise: + case SH_TitleBar_NoBorder: + res = 1; + break; + + case SH_GroupBox_TextLabelColor: + if (option->state & QStyle::State_Enabled) + res = d->groupBoxTextColor; + else + res = d->groupBoxTextColorDisabled; + break; + + case SH_Table_GridLineColor: + res = 0xC0C0C0; + break; + + case SH_WindowFrame_Mask: + { + res = 1; + QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData); + const QStyleOptionTitleBar *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(option); + if (mask && titlebar) { + // Note certain themes will not return the whole window frame but only the titlebar part when + // queried This function needs to return the entire window mask, hence we will only fetch the mask for the + // titlebar itself and add the remaining part of the window rect at the bottom. + int tbHeight = proxy()->pixelMetric(PM_TitleBarHeight, option); + QRect titleBarRect = option->rect; + titleBarRect.setHeight(tbHeight); + XPThemeData themeData; + if (titlebar->titleBarState & Qt::WindowMinimized) { + themeData = XPThemeData(option->window, nullptr, + QWindowsXPStylePrivate::WindowTheme, + WP_MINCAPTION, CS_ACTIVE, titleBarRect); + } else { + themeData = XPThemeData(option->window, nullptr, + QWindowsXPStylePrivate::WindowTheme, + WP_CAPTION, CS_ACTIVE, titleBarRect); + } + mask->region = d->region(themeData) + + QRect(0, tbHeight, option->rect.width(), option->rect.height() - tbHeight); + } + } + break; +#if 0 && QT_CONFIG(rubberband) + case SH_RubberBand_Mask: + if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) + res = 0; + break; +#endif // QT_CONFIG(rubberband) + + case SH_ItemView_DrawDelegateFrame: + res = 1; + break; + + default: + res =QWindowsStyle::styleHint(hint, option, returnData); + } + + return res; +} + +QMargins QWindowsXPStyle::ninePatchMargins(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, const QSize &imageSize) const +{ + QMargins margins; + + switch (cc) { + case CC_ScrollBar: { + margins = QWindowsStyle::ninePatchMargins(cc, opt, imageSize); + if (const auto option = qstyleoption_cast<const QStyleOptionSlider *>(opt)) { + if (option->orientation == Qt::Horizontal) { + margins.setTop(-1); + margins.setBottom(-1); + } else { + margins.setLeft(-1); + margins.setRight(-1); + } + } + break; } + default: + margins = QWindowsStyle::ninePatchMargins(cc, opt, imageSize); + break; + } + + return margins; +} + + +/*! \reimp */ +QPalette QWindowsXPStyle::standardPalette() const +{ + return QWindowsXPStylePrivate::useXP() ? QPalette() : QWindowsStyle::standardPalette(); +} + +/*! + \reimp +*/ +QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option) const +{ + if (!QWindowsXPStylePrivate::useXP()) + return QWindowsStyle::standardPixmap(standardPixmap, option); + +#if 0 + switch (standardPixmap) { + case SP_TitleBarMaxButton: + case SP_TitleBarCloseButton: + if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) + { + if (widget && widget->isWindow()) { + XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL); + if (theme.isValid()) { + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize(); + return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(size); + } + } + } + break; + default: + break; + } +#endif + return QWindowsStyle::standardPixmap(standardPixmap, option); +} + +/*! + \reimp +*/ +QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon, + const QStyleOption *option) const +{ + if (!QWindowsXPStylePrivate::useXP()) { + return QWindowsStyle::standardIcon(standardIcon, option); + } +#if 0 + QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func()); + switch (standardIcon) { + case SP_TitleBarMaxButton: + if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) + { + if (d->dockFloat.isNull()) { + XPThemeData themeSize(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme, + WP_SMALLCLOSEBUTTON, CBS_NORMAL); + XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme, + WP_MAXBUTTON, MAXBS_NORMAL); + if (theme.isValid()) { + const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize(); + QPixmap pm(size); + pm.fill(Qt::transparent); + QPainter p(&pm); + theme.painter = &p; + theme.rect = QRect(QPoint(0, 0), size); + d->drawBackground(theme); + d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal + pm.fill(Qt::transparent); + theme.stateId = MAXBS_PUSHED; + d->drawBackground(theme); + d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed + pm.fill(Qt::transparent); + theme.stateId = MAXBS_HOT; + d->drawBackground(theme); + d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover + pm.fill(Qt::transparent); + theme.stateId = MAXBS_INACTIVE; + d->drawBackground(theme); + d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled + } + } + if (widget && widget->isWindow()) + return d->dockFloat; + + } + break; + case SP_TitleBarCloseButton: + if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) + { + if (d->dockClose.isNull()) { + XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme, + WP_SMALLCLOSEBUTTON, CBS_NORMAL); + if (theme.isValid()) { + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize(); + QPixmap pm(size); + pm.fill(Qt::transparent); + QPainter p(&pm); + theme.painter = &p; + theme.partId = WP_CLOSEBUTTON; // #### + theme.rect = QRect(QPoint(0, 0), size); + d->drawBackground(theme); + d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal + pm.fill(Qt::transparent); + theme.stateId = CBS_PUSHED; + d->drawBackground(theme); + d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed + pm.fill(Qt::transparent); + theme.stateId = CBS_HOT; + d->drawBackground(theme); + d->dockClose.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover + pm.fill(Qt::transparent); + theme.stateId = CBS_INACTIVE; + d->drawBackground(theme); + d->dockClose.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled + } + } + if (widget && widget->isWindow()) + return d->dockClose; + } + break; + case SP_TitleBarNormalButton: + if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) + { + if (d->dockFloat.isNull()) { + XPThemeData themeSize(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme, + WP_SMALLCLOSEBUTTON, CBS_NORMAL); + XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme, + WP_RESTOREBUTTON, RBS_NORMAL); + if (theme.isValid()) { + const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(option)).toSize(); + QPixmap pm(size); + pm.fill(Qt::transparent); + QPainter p(&pm); + theme.painter = &p; + theme.rect = QRect(QPoint(0, 0), size); + d->drawBackground(theme); + d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal + pm.fill(Qt::transparent); + theme.stateId = RBS_PUSHED; + d->drawBackground(theme); + d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed + pm.fill(Qt::transparent); + theme.stateId = RBS_HOT; + d->drawBackground(theme); + d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover + pm.fill(Qt::transparent); + theme.stateId = RBS_INACTIVE; + d->drawBackground(theme); + d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled + } + } + if (widget && widget->isWindow()) + return d->dockFloat; + + } + break; + default: + break; + } +#endif + return QWindowsStyle::standardIcon(standardIcon, option); +} + +/*! + \internal + + Constructs a QWindowsXPStyle object. +*/ +QWindowsXPStyle::QWindowsXPStyle(QWindowsXPStylePrivate &dd) : QWindowsStyle(dd) +{ +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const XPThemeData &t) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "XPThemeData(" << t.window << ", theme=#" << t.theme << ", " << t.htheme + << ", partId=" << t.partId << ", stateId=" << t.stateId << ", rect=" << t.rect + << ", mirrorHorizontally=" << t.mirrorHorizontally << ", mirrorVertically=" + << t.mirrorVertically << ", noBorder=" << t.noBorder << ", noContent=" << t.noContent + << ", rotate=" << t.rotate << ')'; + return d; +} + +QDebug operator<<(QDebug d, const ThemeMapKey &k) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "ThemeMapKey(theme=#" << k.theme + << ", partId=" << k.partId << ", stateId=" << k.stateId + << ", noBorder=" << k.noBorder << ", noContent=" << k.noContent << ')'; + return d; +} + +QDebug operator<<(QDebug d, const ThemeMapData &td) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "ThemeMapData(alphaType=" << td.alphaType + << ", dataValid=" << td.dataValid << ", partIsTransparent=" << td.partIsTransparent + << ", hasAlphaChannel=" << td.hasAlphaChannel << ", wasAlphaSwapped=" << td.wasAlphaSwapped + << ", hadInvalidAlpha=" << td.hadInvalidAlpha << ')'; + return d; +} +#endif // QT_NO_DEBUG_STREAM + +// Debugging code ---------------------------------------------------------------------[ START ]--- +// The code for this point on is not compiled by default, but only used as assisting +// debugging code when you uncomment the DEBUG_XP_STYLE define at the top of the file. + +#ifdef DEBUG_XP_STYLE +// The schema file expects these to be defined by the user. +#define TMT_ENUMDEF 8 +#define TMT_ENUMVAL TEXT('A') +#define TMT_ENUM TEXT('B') +#define SCHEMA_STRINGS // For 2nd pass on schema file +QT_BEGIN_INCLUDE_NAMESPACE +#include <tmschema.h> +QT_END_INCLUDE_NAMESPACE + +// A property's value, type and name combo +struct PropPair { + int propValue; + int propType; + LPCWSTR propName; +}; + +// Operator for sorting of PropPairs +bool operator<(PropPair a, PropPair b) { + return wcscmp(a.propName, b.propName) < 0; +} + +// Our list of all possible properties +static QList<PropPair> all_props; + + +/*! \internal + Dumps a portion of the full native DIB section double buffer. + The DIB section double buffer is only used when doing special + transformations to the theme part, or when the real double + buffer in the paintengine does not have an HDC we may use + directly. + Since we cannot rely on the pixel data we get from Microsoft + when drawing into the DIB section, we use this function to + see the actual data we got, and can determin the appropriate + action. +*/ +void QWindowsXPStylePrivate::dumpNativeDIB(int w, int h) +{ + if (w && h) { + static int pCount = 0; + DWORD *bufPix = (DWORD*)bufferPixels; + + char *bufferDump = new char[bufferH * bufferW * 16]; + char *bufferPos = bufferDump; + + memset(bufferDump, 0, sizeof(bufferDump)); + bufferPos += sprintf(bufferPos, "const int pixelBufferW%d = %d;\n", pCount, w); + bufferPos += sprintf(bufferPos, "const int pixelBufferH%d = %d;\n", pCount, h); + bufferPos += sprintf(bufferPos, "const unsigned DWORD pixelBuffer%d[] = {", pCount); + for (int iy = 0; iy < h; ++iy) { + bufferPos += sprintf(bufferPos, "\n "); + bufPix = (DWORD*)(bufferPixels + (iy * bufferW * 4)); + for (int ix = 0; ix < w; ++ix) { + bufferPos += sprintf(bufferPos, "0x%08x, ", *bufPix); + ++bufPix; + } + } + bufferPos += sprintf(bufferPos, "\n};\n\n"); + printf(bufferDump); + + delete[] bufferDump; + ++pCount; + } +} + +/*! \internal + Shows the value of a given property for a part. +*/ +static void showProperty(XPThemeData &themeData, const PropPair &prop) +{ + PROPERTYORIGIN origin = PO_NOTFOUND; + GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin); + const char *originStr; + switch (origin) { + case PO_STATE: + originStr = "State "; + break; + case PO_PART: + originStr = "Part "; + break; + case PO_CLASS: + originStr = "Class "; + break; + case PO_GLOBAL: + originStr = "Globl "; + break; + case PO_NOTFOUND: + default: + originStr = "Unkwn "; + break; + } + + switch (prop.propType) { + case TMT_STRING: + { + wchar_t buffer[512]; + GetThemeString(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512); + printf(" (%sString) %-20S: %S\n", originStr, prop.propName, buffer); + } + break; + case TMT_ENUM: + { + int result = -1; + GetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); + printf(" (%sEnum) %-20S: %d\n", originStr, prop.propName, result); + } + break; + case TMT_INT: + { + int result = -1; + GetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); + printf(" (%sint) %-20S: %d\n", originStr, prop.propName, result); + } + break; + case TMT_BOOL: + { + BOOL result = false; + GetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); + printf(" (%sbool) %-20S: %d\n", originStr, prop.propName, result); + } + break; + case TMT_COLOR: + { + COLORREF result = 0; + GetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); + printf(" (%scolor) %-20S: 0x%08X\n", originStr, prop.propName, result); + } + break; + case TMT_MARGINS: + { + MARGINS result; + memset(&result, 0, sizeof(result)); + GetThemeMargins(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, 0, &result); + printf(" (%smargins) %-20S: (%d, %d, %d, %d)\n", originStr, + prop.propName, result.cxLeftWidth, result.cyTopHeight, result.cxRightWidth, result.cyBottomHeight); + } + break; + case TMT_FILENAME: + { + wchar_t buffer[512]; + GetThemeFilename(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512); + printf(" (%sfilename)%-20S: %S\n", originStr, prop.propName, buffer); + } + break; + case TMT_SIZE: + { + SIZE result1; + SIZE result2; + SIZE result3; + memset(&result1, 0, sizeof(result1)); + memset(&result2, 0, sizeof(result2)); + memset(&result3, 0, sizeof(result3)); + GetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_MIN, &result1); + GetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_TRUE, &result2); + GetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_DRAW, &result3); + printf(" (%ssize) %-20S: Min (%d, %d), True(%d, %d), Draw(%d, %d)\n", originStr, prop.propName, + result1.cx, result1.cy, result2.cx, result2.cy, result3.cx, result3.cy); + } + break; + case TMT_POSITION: + { + POINT result; + memset(&result, 0, sizeof(result)); + GetThemePosition(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); + printf(" (%sPosition)%-20S: (%d, %d)\n", originStr, prop.propName, result.x, result.y); + } + break; + case TMT_RECT: + { + RECT result; + memset(&result, 0, sizeof(result)); + GetThemeRect(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); + printf(" (%sRect) %-20S: (%d, %d, %d, %d)\n", originStr, prop.propName, result.left, result.top, result.right, result.bottom); + } + break; + case TMT_FONT: + { + LOGFONT result; + memset(&result, 0, sizeof(result)); + GetThemeFont(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, &result); + printf(" (%sFont) %-20S: %S height(%d) width(%d) weight(%d)\n", originStr, prop.propName, + result.lfFaceName, result.lfHeight, result.lfWidth, result.lfWeight); + } + break; + case TMT_INTLIST: + { + INTLIST result; + memset(&result, 0, sizeof(result)); + GetThemeIntList(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result); + printf(" (%sInt list)%-20S: { ", originStr, prop.propName); + for (int i = 0; i < result.iValueCount; ++i) + printf("%d ", result.iValues[i]); + printf("}\n"); + } + break; + default: + printf(" %s%S : Unknown property type (%d)!\n", originStr, prop.propName, prop.propType); + } +} + +/*! \internal + Dump all valid properties for a part. + If it's the first time this function is called, then the name, + enum value and documentation of all properties are shown, as + well as all global properties. +*/ +void QWindowsXPStylePrivate::showProperties(XPThemeData &themeData) +{ + if (!all_props.count()) { + const TMSCHEMAINFO *infoTable = GetSchemaInfo(); + for (int i = 0; i < infoTable->iPropCount; ++i) { + int propType = infoTable->pPropTable[i].bPrimVal; + int propValue = infoTable->pPropTable[i].sEnumVal; + LPCWSTR propName = infoTable->pPropTable[i].pszName; + + switch (propType) { + case TMT_ENUMDEF: + case TMT_ENUMVAL: + continue; + default: + if (propType != propValue) { + PropPair prop; + prop.propValue = propValue; + prop.propName = propName; + prop.propType = propType; + all_props.append(prop); + } + } + } + std::sort(all_props.begin(), all_props.end()); + + {// List all properties + printf("part properties count = %d:\n", all_props.count()); + printf(" Enum Property Name Description\n"); + printf("-----------------------------------------------------------\n"); + wchar_t themeName[256]; + pGetCurrentThemeName(themeName, 256, 0, 0, 0, 0); + for (int j = 0; j < all_props.count(); ++j) { + PropPair prop = all_props.at(j); + wchar_t buf[500]; + GetThemeDocumentationProperty(themeName, prop.propName, buf, 500); + printf("%3d: (%4d) %-20S %S\n", j, prop.propValue, prop.propName, buf); + } + } + + {// Show Global values + printf("Global Properties:\n"); + for (int j = 0; j < all_props.count(); ++j) { + PropPair prop = all_props.at(j); + PROPERTYORIGIN origin = PO_NOTFOUND; + GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin); + if (origin == PO_GLOBAL) { + showProperty(themeData, prop); + } + } + } + } + + for (int j = 0; j < all_props.count(); ++j) { + PropPair prop = all_props.at(j); + PROPERTYORIGIN origin = PO_NOTFOUND; + GetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin); + if (origin != PO_NOTFOUND) + { + showProperty(themeData, prop); + } + } +} +#endif +// Debugging code -----------------------------------------------------------------------[ END ]--- + +} //namespace QQC2 + +QT_END_NAMESPACE diff --git a/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle_p.h b/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle_p.h new file mode 100644 index 00000000000..89a53477778 --- /dev/null +++ b/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module 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 QQUICKWINDOWSXPSTYLE_P_H +#define QQUICKWINDOWSXPSTYLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquickwindowsstyle_p.h" + +QT_BEGIN_NAMESPACE + +namespace QQC2 { + +class QWindowsXPStylePrivate; +class QWindowsXPStyle : public QWindowsStyle +{ + Q_OBJECT +public: + QWindowsXPStyle(); + QWindowsXPStyle(QWindowsXPStylePrivate &dd); + ~QWindowsXPStyle() override; + +/* + void polish(QApplication*) override; + void unpolish(QApplication*) override; + void polish(QWidget*) override; + void unpolish(QWidget*) override; + void polish(QPalette&) override; +*/ + void drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p) const override; + void drawControl(ControlElement element, const QStyleOption *option, QPainter *p) const override; + QRect subElementRect(SubElement r, const QStyleOption *option) const override; + QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc) const override; + void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, QPainter *p) const override; + QSize sizeFromContents(ContentsType ct, const QStyleOption *option, const QSize &contentsSize) const override; + int pixelMetric(PixelMetric pm, const QStyleOption *option = nullptr) const override; + int styleHint(StyleHint hint, const QStyleOption *option = nullptr, + QStyleHintReturn *returnData = nullptr) const override; + + QPalette standardPalette() const override; + QPixmap standardPixmap(StandardPixmap standardIcon, const QStyleOption *option) const override; + QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr) const override; + + QMargins ninePatchMargins(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, const QSize &imageSize) const override; + +private: + Q_DISABLE_COPY_MOVE(QWindowsXPStyle) + Q_DECLARE_PRIVATE(QWindowsXPStyle) + friend class QStyleFactory; +}; + +} // namespace QQC2 + +QT_END_NAMESPACE + +#endif // QQUICKWINDOWSXPSTYLE_P_H diff --git a/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle_p_p.h b/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle_p_p.h new file mode 100644 index 00000000000..a449ecdda7b --- /dev/null +++ b/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle_p_p.h @@ -0,0 +1,348 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module 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 QQUICKWINDOWSXPSTYLE_P_P_H +#define QQUICKWINDOWSXPSTYLE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +//#include <QtWidgets/private/qtwidgetsglobal_p.h> +#include "qquickwindowsxpstyle_p.h" +#include "qquickwindowsstyle_p_p.h" +#include <QtCore/qmap.h> +#include <qt_windows.h> + +#include <uxtheme.h> +#include <vssym32.h> + +#include <limits.h> + +QT_BEGIN_NAMESPACE + +class QDebug; + +namespace QQC2 { + +// TMT_TEXTSHADOWCOLOR is wrongly defined in mingw +#if TMT_TEXTSHADOWCOLOR != 3818 +#undef TMT_TEXTSHADOWCOLOR +#define TMT_TEXTSHADOWCOLOR 3818 +#endif +#ifndef TST_NONE +# define TST_NONE 0 +#endif + +// These defines are missing from the tmschema, but still exist as +// states for their parts +#ifndef MINBS_INACTIVE +#define MINBS_INACTIVE 5 +#endif +#ifndef MAXBS_INACTIVE +#define MAXBS_INACTIVE 5 +#endif +#ifndef RBS_INACTIVE +#define RBS_INACTIVE 5 +#endif +#ifndef HBS_INACTIVE +#define HBS_INACTIVE 5 +#endif +#ifndef CBS_INACTIVE +#define CBS_INACTIVE 5 +#endif + +// Uncomment define below to build debug assisting code, and output +// #define DEBUG_XP_STYLE + +// Declarations ----------------------------------------------------------------------------------- +class XPThemeData +{ +public: + explicit XPThemeData(const QWindow *w = nullptr, QPainter *p = nullptr, int themeIn = -1, + int part = 0, int state = 0, const QRect &r = QRect()) + : window(w), painter(p), theme(themeIn), partId(part), stateId(state), + mirrorHorizontally(false), mirrorVertically(false), noBorder(false), + noContent(false), rect(r) + {} + + HTHEME handle(); + + static RECT toRECT(const QRect &qr); + bool isValid(); + + QSizeF size(); + QMarginsF margins(const QRect &rect, int propId = TMT_CONTENTMARGINS); + QMarginsF margins(int propId = TMT_CONTENTMARGINS); + + static QSizeF themeSize(const QWindow *w = nullptr, QPainter *p = nullptr, int themeIn = -1, int part = 0, int state = 0); + static QMarginsF themeMargins(const QRect &rect, const QWindow *w = nullptr, QPainter *p = nullptr, int themeIn = -1, + int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS); + static QMarginsF themeMargins(const QWindow *w = nullptr, QPainter *p = nullptr, int themeIn = -1, + int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS); + + const QWindow *window; + QPainter *painter; + + int theme; + HTHEME htheme = nullptr; + int partId; + int stateId; + + uint mirrorHorizontally : 1; + uint mirrorVertically : 1; + uint noBorder : 1; + uint noContent : 1; + uint rotate = 0; + QRect rect; +}; + +struct ThemeMapKey { + int theme = 0; + int partId = -1; + int stateId = -1; + bool noBorder = false; + bool noContent = false; + + ThemeMapKey() = default; + ThemeMapKey(const XPThemeData &data) + : theme(data.theme), partId(data.partId), stateId(data.stateId), + noBorder(data.noBorder), noContent(data.noContent) {} + +}; + +inline size_t qHash(const ThemeMapKey &key) +{ return key.theme ^ key.partId ^ key.stateId; } + +inline bool operator==(const ThemeMapKey &k1, const ThemeMapKey &k2) +{ + return k1.theme == k2.theme + && k1.partId == k2.partId + && k1.stateId == k2.stateId; +} + +enum AlphaChannelType { + UnknownAlpha = -1, // Alpha of part & state not yet known + NoAlpha, // Totally opaque, no need to touch alpha (RGB) + MaskAlpha, // Alpha channel must be fixed (ARGB) + RealAlpha // Proper alpha values from Windows (ARGB_Premultiplied) +}; + +struct ThemeMapData { + AlphaChannelType alphaType = UnknownAlpha; // Which type of alpha on part & state + + bool dataValid : 1; // Only used to detect if hash value is ok + bool partIsTransparent : 1; + bool hasAlphaChannel : 1; // True = part & state has real Alpha + bool wasAlphaSwapped : 1; // True = alpha channel needs to be swapped + bool hadInvalidAlpha : 1; // True = alpha channel contained invalid alpha values + + ThemeMapData() : dataValid(false), partIsTransparent(false), + hasAlphaChannel(false), wasAlphaSwapped(false), hadInvalidAlpha(false) {} +}; + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const XPThemeData &t); +QDebug operator<<(QDebug d, const ThemeMapKey &k); +QDebug operator<<(QDebug d, const ThemeMapData &td); +#endif + +class QWindowsXPStylePrivate : public QWindowsStylePrivate +{ + Q_DECLARE_PUBLIC(QWindowsXPStyle) +public: + enum Theme { + ButtonTheme, + ComboboxTheme, + EditTheme, + HeaderTheme, + ListViewTheme, + MenuTheme, + ProgressTheme, + RebarTheme, + ScrollBarTheme, + SpinTheme, + TabTheme, + TaskDialogTheme, + ToolBarTheme, + ToolTipTheme, + TrackBarTheme, + XpTreeViewTheme, // '+'/'-' shape treeview indicators (XP) + WindowTheme, + StatusTheme, + VistaTreeViewTheme, // arrow shape treeview indicators (Vista) obtained from "explorer" theme. + NThemes + }; + + QWindowsXPStylePrivate() + { init(); } + + ~QWindowsXPStylePrivate() + { cleanup(); } + + static int pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option = nullptr); + static int fixedPixelMetric(QStyle::PixelMetric pm, const QStyleOption *option = nullptr, const QWidget *widget = nullptr); + + static HWND winId(const QWindow *window); + + void init(bool force = false); + void cleanup(bool force = false); + void cleanupHandleMap(); + + HBITMAP buffer(int w = 0, int h = 0); + HDC bufferHDC() + { return bufferDC;} + + static bool useXP(bool update = false); + static QRect scrollBarGripperBounds(QStyle::State flags, XPThemeData *theme); + + bool isTransparent(XPThemeData &themeData); + QRegion region(XPThemeData &themeData); + + bool drawBackground(XPThemeData &themeData, qreal correctionFactor = 1); + bool drawBackgroundThruNativeBuffer(XPThemeData &themeData, qreal aditionalDevicePixelRatio, qreal correctionFactor); + bool drawBackgroundDirectly(HDC dc, XPThemeData &themeData, qreal aditionalDevicePixelRatio); + + bool hasAlphaChannel(const QRect &rect); + bool fixAlphaChannel(const QRect &rect); + bool swapAlphaChannel(const QRect &rect, bool allPixels = false); + + QRgb groupBoxTextColor = 0; + QRgb groupBoxTextColorDisabled = 0; + QRgb sliderTickColor = 0; + bool hasInitColors = false; + + static HTHEME createTheme(int theme, HWND hwnd); + static QString themeName(int theme); + static inline bool hasTheme(int theme) { return theme >= 0 && theme < NThemes && m_themes[theme]; } + static bool isItemViewDelegateLineEdit(const QWidget *widget); + static bool isLineEditBaseColorSet(const QStyleOption *option, const QWidget *widget); + + QIcon dockFloat, dockClose; + +private: +#ifdef DEBUG_XP_STYLE + void dumpNativeDIB(int w, int h); + void showProperties(XPThemeData &themeData); +#endif + + static bool initVistaTreeViewTheming(); + static void cleanupVistaTreeViewTheming(); + + static QBasicAtomicInt ref; + static bool use_xp; + + QHash<ThemeMapKey, ThemeMapData> alphaCache; + HDC bufferDC = nullptr; + HBITMAP bufferBitmap = nullptr; + HBITMAP nullBitmap = nullptr; + uchar *bufferPixels = nullptr; + int bufferW = 0; + int bufferH = 0; + + static HWND m_vistaTreeViewHelper; + static HTHEME m_themes[NThemes]; +}; + +inline QSizeF XPThemeData::size() +{ + QSizeF result(0, 0); + if (isValid()) { + SIZE size; + if (SUCCEEDED(GetThemePartSize(handle(), nullptr, partId, stateId, nullptr, TS_TRUE, &size))) + result = QSize(size.cx, size.cy); + } + return result; +} + +inline QMarginsF XPThemeData::margins(const QRect &qRect, int propId) +{ + QMarginsF result(0, 0, 0 ,0); + if (isValid()) { + MARGINS margins; + RECT rect = XPThemeData::toRECT(qRect); + if (SUCCEEDED(GetThemeMargins(handle(), nullptr, partId, stateId, propId, &rect, &margins))) + result = QMargins(margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight); + } + return result; +} + +inline QMarginsF XPThemeData::margins(int propId) +{ + QMarginsF result(0, 0, 0 ,0); + if (isValid()) { + MARGINS margins; + if (SUCCEEDED(GetThemeMargins(handle(), nullptr, partId, stateId, propId, nullptr, &margins))) + result = QMargins(margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight); + } + return result; +} + +inline QSizeF XPThemeData::themeSize(const QWindow *w, QPainter *p, int themeIn, int part, int state) +{ + XPThemeData theme(w, p, themeIn, part, state); + return theme.size(); +} + +inline QMarginsF XPThemeData::themeMargins(const QRect &rect, const QWindow *w, QPainter *p, int themeIn, + int part, int state, int propId) +{ + XPThemeData theme(w, p, themeIn, part, state); + return theme.margins(rect, propId); +} + +inline QMarginsF XPThemeData::themeMargins(const QWindow *w, QPainter *p, int themeIn, + int part, int state, int propId) +{ + XPThemeData theme(w, p, themeIn, part, state); + return theme.margins(propId); +} + +} //namespace QQC2 + +QT_END_NAMESPACE + +#endif //QQUICKWINDOWSXPSTYLE_P_P_H diff --git a/src/quicknativestyle/qstyle/windows/windows.pri b/src/quicknativestyle/qstyle/windows/windows.pri new file mode 100644 index 00000000000..beb50a5b207 --- /dev/null +++ b/src/quicknativestyle/qstyle/windows/windows.pri @@ -0,0 +1,18 @@ + +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qquickwindowsstyle_p.h \ + $$PWD/qquickwindowsstyle_p_p.h \ +# $$PWD/qquickwindowsvistastyle_p.h \ +# $$PWD/qquickwindowsvistastyle_p_p.h \ + $$PWD/qquickwindowsxpstyle_p.h \ + $$PWD/qquickwindowsxpstyle_p_p.h + +SOURCES += \ + $$PWD/qquickwindowsstyle.cpp \ +# $$PWD/qquickwindowsvistastyle.cpp \ + $$PWD/qquickwindowsxpstyle.cpp + +QMAKE_USE_PRIVATE += user32 gdi32 +LIBS_PRIVATE *= -luxtheme diff --git a/src/quicknativestyle/qtquickcontrols2nativestyleplugin.cpp b/src/quicknativestyle/qtquickcontrols2nativestyleplugin.cpp new file mode 100644 index 00000000000..1b6945849e9 --- /dev/null +++ b/src/quicknativestyle/qtquickcontrols2nativestyleplugin.cpp @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQml/qqml.h> +#include <QtQuickControls2/private/qquickstyleplugin_p.h> +#include <QtGui/qguiapplication.h> + +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +#include "qquicknativestyle.h" +#include "qquickcommonstyle.h" + +#if defined(Q_OS_MACOS) +#include "qquickmacstyle_mac_p.h" +#include "qquickmacfocusframe.h" +#elif defined(Q_OS_WINDOWS) +# include "qquickwindowsxpstyle_p.h" +#endif + +extern void qml_register_types_QtQuick_NativeStyle(); +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick_NativeStyle); + +QT_BEGIN_NAMESPACE + +using namespace QQC2; + +class QtQuickControls2NativeStylePlugin : public QQuickStylePlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtQuickControls2NativeStylePlugin(QObject *parent = nullptr); + ~QtQuickControls2NativeStylePlugin() override; + + void initializeEngine(QQmlEngine *engine, const char *uri) override; + void initializeTheme(QQuickTheme *theme) override; + QString name() const override; + +#if defined(Q_OS_MACOS) + QScopedPointer<QQuickMacFocusFrame> m_focusFrame; +#endif +}; + +static void deleteQStyle() +{ + // When we delete QStyle, it will free up it's own internal resources. Especially + // on macOS, this means releasing a lot of NSViews and NSCells from the QMacStyle + // destructor. If we did this from ~QtQuickControls2NativeStylePlugin, it would + // happen when the plugin was unloaded from a Q_DESTRUCTOR_FUNCTION in QLibrary, + // which is very late in the tear-down process, and after qGuiApp has been set to + // nullptr, NSApplication has stopped running, and perhaps also other static platform + // variables (e.g in AppKit?) has been deleted. And to our best guess, this is also why + // we see a crash in AppKit from the destructor in QMacStyle. So for this reason, we + // delete QStyle from a post routine rather than from the destructor. + QQuickNativeStyle::setStyle(nullptr); +} + +QtQuickControls2NativeStylePlugin::QtQuickControls2NativeStylePlugin(QObject *parent): + QQuickStylePlugin(parent) +{ + volatile auto registration = &qml_register_types_QtQuick_NativeStyle; + Q_UNUSED(registration); +} + +QtQuickControls2NativeStylePlugin::~QtQuickControls2NativeStylePlugin() +{ + if (!qGuiApp) + return; + + // QGuiApplication is still running, so we need to remove the post + // routine to not be called after we have been unloaded. + qRemovePostRoutine(deleteQStyle); + QQuickNativeStyle::setStyle(nullptr); +} + +QString QtQuickControls2NativeStylePlugin::name() const +{ + return QStringLiteral("NativeStyle"); +} + +void QtQuickControls2NativeStylePlugin::initializeEngine(QQmlEngine *engine, const char *uri) +{ + Q_UNUSED(engine); + Q_UNUSED(uri); + // Enable commonstyle as a reference style while + // the native styles are under development. + QStyle *style = nullptr; + if (qEnvironmentVariable("QQC2_COMMONSTYLE") == QStringLiteral("true")) { + style = new QCommonStyle; + } else { + const QString envStyle = qEnvironmentVariable("QQC2_STYLE"); + if (!envStyle.isNull()) { + if (envStyle == QLatin1String("common")) + style = new QCommonStyle; +#if defined(Q_OS_MACOS) + else if (envStyle == QLatin1String("mac")) + style = new QMacStyle; +#endif +#if defined(Q_OS_WINDOWS) + else if (envStyle == QLatin1String("windows")) + style = new QWindowsStyle; + else if (envStyle == QLatin1String("windowsxp")) + style = new QWindowsXPStyle; +#endif + } + if (!style) { +#if defined(Q_OS_MACOS) + style = new QMacStyle; +#elif defined(Q_OS_WINDOWS) + style = new QWindowsXPStyle; +#else + style = new QCommonStyle; +#endif + } + } + +#if defined(Q_OS_MACOS) + m_focusFrame.reset(new QQuickMacFocusFrame()); +#endif + + qAddPostRoutine(deleteQStyle); + QQuickNativeStyle::setStyle(style); +} + +void QtQuickControls2NativeStylePlugin::initializeTheme(QQuickTheme * /*theme*/) +{ +} + +QT_END_NAMESPACE + +#include "qtquickcontrols2nativestyleplugin.moc" diff --git a/src/quicknativestyle/util/FocusFrame.qml b/src/quicknativestyle/util/FocusFrame.qml new file mode 100644 index 00000000000..2da96436fe6 --- /dev/null +++ b/src/quicknativestyle/util/FocusFrame.qml @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + + // It's important that this item has a zero size. Otherwise, if the parent of the + // targetItem is e.g a layout, we will change the layout if we parent this item inside it. + width: 0 + height: 0 + // Stack on top of all siblings of the targetItem + z: 100 + + function moveToItem(item, margins, radius) { + if (!item) { + targetItem = null; + parent = null; + visible = false; + return; + } + visible = true + parent = item.parent + targetItem = item + leftOffset = margins.left + rightOffset = margins.right + topOffset = margins.top + bottomOffset = margins.bottom + frameRadius = radius + animation.restart() + } + + property Item targetItem + property real leftOffset: 0 + property real rightOffset: 0 + property real topOffset: 0 + property real bottomOffset: 0 + property real frameOpacity: 0 + property real frameSize: 0 + property real frameRadius: 0 + + // systemFrameColor is set to NSColor.keyboardFocusIndicatorColor from cpp + property color systemFrameColor + + Rectangle { + id: focusFrame + z: 10 + x: targetItem ? targetItem.x + leftOffset - frameSize : 0 + y: targetItem ? targetItem.y + topOffset - frameSize : 0 + width: targetItem ? targetItem.width - leftOffset - rightOffset + (frameSize * 2) : 0 + height: targetItem ? targetItem.height - topOffset - bottomOffset + (frameSize * 2) : 0 + radius: frameRadius + visible: targetItem && targetItem.visible + color: "transparent" + + border.color: systemFrameColor + border.width: frameSize + } + + ParallelAnimation { + id: animation + NumberAnimation { + target: root + property: "frameSize" + duration: 300 + from: 15 + to: 2.5 + easing.type: Easing.OutCubic + } + NumberAnimation { + target: focusFrame + property: "opacity" + duration: 300 + from: 0 + to: 0.55 + easing.type: Easing.OutCubic + } + } +} diff --git a/src/quicknativestyle/util/qquickmacfocusframe.h b/src/quicknativestyle/util/qquickmacfocusframe.h new file mode 100644 index 00000000000..425b2a6827c --- /dev/null +++ b/src/quicknativestyle/util/qquickmacfocusframe.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMACFOCUSFRAME_H +#define QQUICKMACFOCUSFRAME_H + +#include <QtQuick/qquickitem.h> +#include <QtQuick/private/qquicktextedit_p.h> +#include "qquickstyleitem.h" + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcFocusFrame) + +struct QQuickFocusFrameDescription { + QQuickItem *target; + QQuickStyleMargins margins; + const qreal radius = 3; + bool isValid() const { return target != nullptr; } + static QQuickFocusFrameDescription Invalid; +}; + +class QQuickMacFocusFrame : public QObject +{ + Q_OBJECT + +public: + QQuickMacFocusFrame(); + +private: + static QScopedPointer<QQuickItem> m_focusFrame; + + void createFocusFrame(QQmlContext *context); + void moveToItem(QQuickItem *item); + QQuickFocusFrameDescription getDescriptionForItem(QQuickItem *focusItem) const; +}; + +QT_END_NAMESPACE + +#endif // QQUICKMACFOCUSFRAME_H diff --git a/src/quicknativestyle/util/qquickmacfocusframe.mm b/src/quicknativestyle/util/qquickmacfocusframe.mm new file mode 100644 index 00000000000..5a2052dbbcd --- /dev/null +++ b/src/quicknativestyle/util/qquickmacfocusframe.mm @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmacfocusframe.h" + +#include <AppKit/AppKit.h> + +#include <QtCore/qmetaobject.h> + +#include <QtGui/qguiapplication.h> +#include <QtGui/private/qcoregraphics_p.h> + +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlcomponent.h> + +#include <QtQuick/qquickitem.h> +#include <QtQuick/private/qquicktextinput_p.h> +#include <QtQuick/private/qquicktextedit_p.h> +#include <QtQuick/private/qquickflickable_p.h> + +#include <QtQuickTemplates2/private/qquickframe_p.h> +#include <QtQuickTemplates2/private/qquickbutton_p.h> +#include <QtQuickTemplates2/private/qquickscrollview_p.h> +#include <QtQuickTemplates2/private/qquickslider_p.h> +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquickcheckbox_p.h> +#include <QtQuickTemplates2/private/qquickradiobutton_p.h> +#include <QtQuickTemplates2/private/qquickspinbox_p.h> +#include <QtQuickTemplates2/private/qquicktextfield_p.h> +#include <QtQuickTemplates2/private/qquicktextarea_p.h> + +#include "items/qquickstyleitem.h" +#include "qquicknativestyle.h" + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcFocusFrame, "qt.quick.controls.focusframe") + +QQuickFocusFrameDescription QQuickFocusFrameDescription::Invalid = { nullptr, QQuickStyleMargins(), 0 }; +QScopedPointer<QQuickItem> QQuickMacFocusFrame::m_focusFrame; + +QQuickMacFocusFrame::QQuickMacFocusFrame() +{ + connect(qGuiApp, &QGuiApplication::focusObjectChanged, [=]{ + if (auto item = qobject_cast<QQuickItem *>(qGuiApp->focusObject())) + moveToItem(item); + }); +} + +void QQuickMacFocusFrame::moveToItem(QQuickItem *item) +{ + if (!m_focusFrame) { + const auto context = QQmlEngine::contextForObject(item); + if (!context) + return; + createFocusFrame(context); + } + + const QQuickFocusFrameDescription &config = getDescriptionForItem(item); + QMetaObject::invokeMethod(m_focusFrame.data(), "moveToItem", + Q_ARG(QVariant, QVariant::fromValue(config.target)), + Q_ARG(QVariant, QVariant::fromValue(config.margins)), + Q_ARG(QVariant, QVariant::fromValue(config.radius))); +} + +void QQuickMacFocusFrame::createFocusFrame(QQmlContext *context) +{ + QQmlComponent component( + context->engine(), + QUrl(QStringLiteral( + "qrc:/qt-project.org/imports/QtQuick/NativeStyle/util/FocusFrame.qml"))); + m_focusFrame.reset(qobject_cast<QQuickItem *>(component.create())); + + auto indicatorColor = qt_mac_toQColor(NSColor.keyboardFocusIndicatorColor.CGColor); + indicatorColor.setAlpha(255); + m_focusFrame->setProperty("systemFrameColor", indicatorColor); +} + +QQuickFocusFrameDescription QQuickMacFocusFrame::getDescriptionForItem(QQuickItem *focusItem) const +{ + qCDebug(lcFocusFrame) << "new focusobject:" << focusItem; + const auto parentItem = focusItem->parentItem(); + if (!parentItem) + return QQuickFocusFrameDescription::Invalid; + + // The item that gets active focus can be a child of the control (e.g + // editable ComboBox). In that case, resolve the actual control first. + const auto proxy = focusItem->property("__focusFrameControl").value<QQuickItem *>(); + const auto control = proxy ? proxy : focusItem; + auto target = control->property("__focusFrameTarget").value<QQuickItem *>(); + qCDebug(lcFocusFrame) << "target:" << target; + qCDebug(lcFocusFrame) << "control:" << control; + + if (!target) { + // __focusFrameTarget points to the item in the control that should + // get the focus frame. This is usually the control itself, but can + // sometimes be a child (CheckBox). We anyway require + // this property to be set if we are to show the focus frame around + // the control in the first place. So for controls that don't want + // a frame (ProgressBar), we simply skip setting it. + // Also, we should never show a focus frame around custom controls. + // None of the built-in styles do that, so to be consistent, we + // shouldn't either. Besides, drawing a focus frame around an unknown + // item without any way to turn it off can easily be unwanted. A better + // way for custom controls to get a native focus frame is for us to offer + // a FocusFrame control (QTBUG-86818). + return QQuickFocusFrameDescription::Invalid; + } + + // If the control gives us a QQuickStyleItem, we use that to configure the focus frame. + // By default we assume that the background delegate is a QQuickStyleItem, but the + // control can override this by setting __focusFrameStyleItem. + const auto styleItemProperty = control->property("__focusFrameStyleItem"); + auto item = styleItemProperty.value<QQuickItem *>(); + if (!item) { + const auto styleItemProperty = control->property("background"); + item = styleItemProperty.value<QQuickItem *>(); + } + qCDebug(lcFocusFrame) << "styleItem:" << item; + if (!item) + return QQuickFocusFrameDescription::Invalid; + if (QQuickStyleItem *styleItem = qobject_cast<QQuickStyleItem *>(item)) + return { target, QQuickStyleMargins(styleItem->layoutMargins()), styleItem->focusFrameRadius() }; + + // Some controls don't have a QQuickStyleItem. But if the __focusFrameStyleItem + // has a "__isDefaultDelegate" property set, we show a default focus frame instead. + if (item->property("__isDefaultDelegate").toBool() == true) { + qCDebug(lcFocusFrame) << "'__isDefaultDelegate' property found, showing a default focus frame"; + const QStyleOption opt; + const qreal radius = QQuickNativeStyle::style()->pixelMetric(QStyle::PM_TextFieldFocusFrameRadius, &opt); + return { target, QQuickStyleMargins(), radius }; + } + + // The application has set a custom delegate on the control. In that + // case, it's the delegates responsibility to draw a focus frame. + qCDebug(lcFocusFrame) << "custom delegates in use, skip showing focus frame"; + return QQuickFocusFrameDescription::Invalid; +} + +QT_END_NAMESPACE diff --git a/src/quicknativestyle/util/util.pri b/src/quicknativestyle/util/util.pri new file mode 100644 index 00000000000..96786eacaaf --- /dev/null +++ b/src/quicknativestyle/util/util.pri @@ -0,0 +1,11 @@ +INCLUDEPATH += $$PWD + +macos { + HEADERS += \ + $$PWD/qquickmacfocusframe.h \ + + SOURCES += \ + $$PWD/qquickmacfocusframe.mm \ + + RESOURCES += $$PWD/FocusFrame.qml +} diff --git a/src/quickshapes/CMakeLists.txt b/src/quickshapes/CMakeLists.txt index 0f842d79acd..ed219d8728b 100644 --- a/src/quickshapes/CMakeLists.txt +++ b/src/quickshapes/CMakeLists.txt @@ -1,8 +1,8 @@ ##################################################################### -## QuickShapes Module: +## QuickShapesPrivate Module: ##################################################################### -qt_internal_add_qml_module(QuickShapes +qt_internal_add_qml_module(QuickShapesPrivate URI "QtQuick.Shapes" VERSION "${PROJECT_VERSION}" PLUGIN_TARGET qmlshapesplugin @@ -42,7 +42,7 @@ set(qtquickshapes_resource_files "shaders_ng/radialgradient.vert.qsb" ) -qt_internal_add_resource(QuickShapes "qtquickshapes" +qt_internal_add_resource(QuickShapesPrivate "qtquickshapes" PREFIX "/qt-project.org/shapes" FILES diff --git a/src/quickshapes/qquickshape.cpp b/src/quickshapes/qquickshape.cpp index fce4c3d6801..ce091fab076 100644 --- a/src/quickshapes/qquickshape.cpp +++ b/src/quickshapes/qquickshape.cpp @@ -396,10 +396,8 @@ void QQuickShapePath::setCapStyle(CapStyle style) This property defines the style of stroking. The default value is ShapePath.SolidLine. - \list - \li ShapePath.SolidLine - A plain line. - \li ShapePath.DashLine - Dashes separated by a few pixels. - \endlist + \value ShapePath.SolidLine A plain line. + \value ShapePath.DashLine Dashes separated by a few pixels. */ QQuickShapePath::StrokeStyle QQuickShapePath::strokeStyle() const @@ -1476,6 +1474,7 @@ static void generateGradientColorTable(const QQuickShapeGradientCacheKey &gradie { int pos = 0; const QGradientStops &s = gradient.stops; + Q_ASSERT(!s.isEmpty()); const bool colorInterpolation = true; uint alpha = qRound(opacity * 256); @@ -1513,8 +1512,6 @@ static void generateGradientColorTable(const QQuickShapeGradientCacheKey &gradie current_color = next_color; } - Q_ASSERT(s.size() > 0); - uint last_color = ARGB2RGBA(qPremultiply(ARGB_COMBINE_ALPHA(s[sLast].second.rgba(), alpha))); for ( ; pos < size; ++pos) colorTable[pos] = last_color; @@ -1549,7 +1546,10 @@ QSGTexture *QQuickShapeGradientCache::get(const QQuickShapeGradientCacheKey &gra if (!tx) { static const int W = 1024; // texture size is 1024x1 QImage gradTab(W, 1, QImage::Format_RGBA8888_Premultiplied); - generateGradientColorTable(grad, reinterpret_cast<uint *>(gradTab.bits()), W, 1.0f); + if (!grad.stops.isEmpty()) + generateGradientColorTable(grad, reinterpret_cast<uint *>(gradTab.bits()), W, 1.0f); + else + gradTab.fill(Qt::black); tx = new QSGPlainTexture; tx->setImage(gradTab); switch (grad.spread) { diff --git a/src/quickshapes/qquickshapegenericrenderer.cpp b/src/quickshapes/qquickshapegenericrenderer.cpp index f5fcd721524..c44ef2d4e12 100644 --- a/src/quickshapes/qquickshapegenericrenderer.cpp +++ b/src/quickshapes/qquickshapegenericrenderer.cpp @@ -145,8 +145,12 @@ void QQuickShapeGenericRenderer::setPath(int index, const QQuickPath *path) void QQuickShapeGenericRenderer::setStrokeColor(int index, const QColor &color) { ShapePathData &d(m_sp[index]); + const bool wasTransparent = d.strokeColor.a == 0; d.strokeColor = colorToColor4ub(color); + const bool isTransparent = d.strokeColor.a == 0; d.syncDirty |= DirtyColor; + if (wasTransparent && !isTransparent) + d.syncDirty |= DirtyStrokeGeom; } void QQuickShapeGenericRenderer::setStrokeWidth(int index, qreal w) @@ -841,7 +845,7 @@ bool QQuickShapeRadialGradientRhiShader::updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) { Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type()); - QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial); + QQuickShapeRadialGradientMaterial *m = static_cast<QQuickShapeRadialGradientMaterial *>(newMaterial); bool changed = false; QByteArray *buf = state.uniformData(); Q_ASSERT(buf->size() >= 92); @@ -901,7 +905,7 @@ void QQuickShapeRadialGradientRhiShader::updateSampledImage(RenderState &state, if (binding != 1) return; - QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial); + QQuickShapeRadialGradientMaterial *m = static_cast<QQuickShapeRadialGradientMaterial *>(newMaterial); QQuickShapeGenericStrokeFillNode *node = m->node(); const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread); QSGTexture *t = QQuickShapeGradientCache::cacheForRhi(state.rhi())->get(cacheKey); @@ -975,7 +979,7 @@ bool QQuickShapeConicalGradientRhiShader::updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) { Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type()); - QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial); + QQuickShapeConicalGradientMaterial *m = static_cast<QQuickShapeConicalGradientMaterial *>(newMaterial); bool changed = false; QByteArray *buf = state.uniformData(); Q_ASSERT(buf->size() >= 80); @@ -1019,7 +1023,7 @@ void QQuickShapeConicalGradientRhiShader::updateSampledImage(RenderState &state, if (binding != 1) return; - QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(newMaterial); + QQuickShapeConicalGradientMaterial *m = static_cast<QQuickShapeConicalGradientMaterial *>(newMaterial); QQuickShapeGenericStrokeFillNode *node = m->node(); const QQuickShapeGradientCacheKey cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread); QSGTexture *t = QQuickShapeGradientCache::cacheForRhi(state.rhi())->get(cacheKey); @@ -1075,3 +1079,5 @@ QSGMaterialShader *QQuickShapeConicalGradientMaterial::createShader(QSGRendererI } QT_END_NAMESPACE + +#include "moc_qquickshapegenericrenderer_p.cpp" diff --git a/src/quickshapes/qquickshapesoftwarerenderer.cpp b/src/quickshapes/qquickshapesoftwarerenderer.cpp index dc9ccb340d8..d68fc22388d 100644 --- a/src/quickshapes/qquickshapesoftwarerenderer.cpp +++ b/src/quickshapes/qquickshapesoftwarerenderer.cpp @@ -180,10 +180,8 @@ void QQuickShapeSoftwareRenderer::endSync(bool) void QQuickShapeSoftwareRenderer::setNode(QQuickShapeSoftwareRenderNode *node) { - if (m_node != node) { - m_node = node; - m_accDirty |= DirtyList; - } + m_node = node; + m_accDirty |= DirtyList; } void QQuickShapeSoftwareRenderer::updateNode() diff --git a/src/quickshapes/qquickshapesplugin.cpp b/src/quickshapes/qquickshapesplugin.cpp index 587c546fcaa..513160db60a 100644 --- a/src/quickshapes/qquickshapesplugin.cpp +++ b/src/quickshapes/qquickshapesplugin.cpp @@ -41,6 +41,9 @@ #include <QtQml/qqml.h> #include <QtQuickShapes/private/qquickshape_p.h> +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Shapes); +Q_GHS_KEEP_REFERENCE(QQuickShapes_initializeModule); + QT_BEGIN_NAMESPACE class QmlShapesPlugin : public QQmlEngineExtensionPlugin diff --git a/src/quickshapes/shaders_ng/conicalgradient.frag b/src/quickshapes/shaders_ng/conicalgradient.frag index 0b1e01bae2d..99592e14e4d 100644 --- a/src/quickshapes/shaders_ng/conicalgradient.frag +++ b/src/quickshapes/shaders_ng/conicalgradient.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 coord; diff --git a/src/quickshapes/shaders_ng/lineargradient.frag b/src/quickshapes/shaders_ng/lineargradient.frag index 16894fc764b..26fa540154a 100644 --- a/src/quickshapes/shaders_ng/lineargradient.frag +++ b/src/quickshapes/shaders_ng/lineargradient.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in float gradTabIndex; diff --git a/src/quickshapes/shaders_ng/radialgradient.frag b/src/quickshapes/shaders_ng/radialgradient.frag index 411e5892956..743cc2a8cb8 100644 --- a/src/quickshapes/shaders_ng/radialgradient.frag +++ b/src/quickshapes/shaders_ng/radialgradient.frag @@ -1,3 +1,6 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + #version 440 layout(location = 0) in vec2 coord; diff --git a/src/quicktemplates2/CMakeLists.txt b/src/quicktemplates2/CMakeLists.txt new file mode 100644 index 00000000000..3ddb994cc11 --- /dev/null +++ b/src/quicktemplates2/CMakeLists.txt @@ -0,0 +1,169 @@ +##################################################################### +## QuickTemplates2 Module: +##################################################################### + +qt_internal_add_qml_module(QuickTemplates2 + URI "QtQuick.Templates" + VERSION "${PROJECT_VERSION}" + CLASSNAME QtQuickTemplates2Plugin + DEPENDENCIES + QtQuick/auto + PLUGIN_TARGET qtquicktemplates2plugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + SOURCES + qquickabstractbutton.cpp qquickabstractbutton_p.h + qquickabstractbutton_p_p.h + qquickaction.cpp qquickaction_p.h + qquickactiongroup.cpp qquickactiongroup_p.h + qquickapplicationwindow.cpp qquickapplicationwindow_p.h + qquickbusyindicator.cpp qquickbusyindicator_p.h + qquickbutton.cpp qquickbutton_p.h + qquickbutton_p_p.h + qquickbuttongroup.cpp qquickbuttongroup_p.h + qquickcheckbox.cpp qquickcheckbox_p.h + qquickcheckdelegate.cpp qquickcheckdelegate_p.h + qquickcombobox.cpp qquickcombobox_p.h + qquickcontainer.cpp qquickcontainer_p.h + qquickcontainer_p_p.h + qquickcontentitem.cpp qquickcontentitem_p.h + qquickcontrol.cpp qquickcontrol_p.h + qquickcontrol_p_p.h + qquickdeferredexecute.cpp + qquickdeferredexecute_p_p.h + qquickdeferredpointer_p_p.h + qquickdelaybutton.cpp qquickdelaybutton_p.h + qquickdial.cpp qquickdial_p.h + qquickdialog.cpp qquickdialog_p.h + qquickdialog_p_p.h + qquickdialogbuttonbox.cpp qquickdialogbuttonbox_p.h + qquickdialogbuttonbox_p_p.h + qquickdrawer.cpp qquickdrawer_p.h + qquickdrawer_p_p.h + qquickframe.cpp qquickframe_p.h + qquickframe_p_p.h + qquickgroupbox.cpp qquickgroupbox_p.h + qquickicon.cpp qquickicon_p.h + qquickindicatorbutton_p.cpp qquickindicatorbutton_p.h + qquickitemdelegate.cpp qquickitemdelegate_p.h + qquickitemdelegate_p_p.h + qquicklabel.cpp qquicklabel_p.h + qquicklabel_p_p.h + qquickmenu.cpp qquickmenu_p.h + qquickmenu_p_p.h + qquickmenubar.cpp qquickmenubar_p.h + qquickmenubar_p_p.h + qquickmenubaritem.cpp qquickmenubaritem_p.h + qquickmenubaritem_p_p.h + qquickmenuitem.cpp qquickmenuitem_p.h + qquickmenuitem_p_p.h + qquickmenuseparator.cpp qquickmenuseparator_p.h + qquickoverlay.cpp qquickoverlay_p.h + qquickoverlay_p_p.h + qquickpage.cpp qquickpage_p.h + qquickpage_p_p.h + qquickpageindicator.cpp qquickpageindicator_p.h + qquickpane.cpp qquickpane_p.h + qquickpane_p_p.h + qquickpopup.cpp qquickpopup_p.h + qquickpopup_p_p.h + qquickpopupanchors.cpp qquickpopupanchors_p.h + qquickpopupanchors_p_p.h + qquickpopupitem.cpp + qquickpopupitem_p_p.h + qquickpopuppositioner.cpp + qquickpopuppositioner_p_p.h + qquickpresshandler.cpp + qquickpresshandler_p_p.h + qquickprogressbar.cpp qquickprogressbar_p.h + qquickradiobutton.cpp qquickradiobutton_p.h + qquickradiodelegate.cpp qquickradiodelegate_p.h + qquickrangeslider.cpp qquickrangeslider_p.h + qquickroundbutton.cpp qquickroundbutton_p.h + qquickscrollbar.cpp qquickscrollbar_p.h + qquickscrollbar_p_p.h + qquickscrollindicator.cpp qquickscrollindicator_p.h + qquickscrollview.cpp qquickscrollview_p.h + qquickselectionrectangle.cpp qquickselectionrectangle_p.h + qquickselectionrectangle_p_p.h + qquickshortcutcontext.cpp + qquickshortcutcontext_p_p.h + qquickslider.cpp qquickslider_p.h + qquickspinbox.cpp qquickspinbox_p.h + qquicksplitview.cpp qquicksplitview_p.h + qquickstackelement.cpp + qquickstackelement_p_p.h + qquickstacktransition.cpp + qquickstacktransition_p_p.h + qquickstackview.cpp qquickstackview_p.cpp qquickstackview_p.h + qquickstackview_p_p.h + qquickswipe_p.h + qquickswipedelegate.cpp qquickswipedelegate_p.h + qquickswipedelegate_p_p.h + qquickswipeview.cpp qquickswipeview_p.h + qquickswitch.cpp qquickswitch_p.h + qquickswitchdelegate.cpp qquickswitchdelegate_p.h + qquicktabbar.cpp qquicktabbar_p.h + qquicktabbutton.cpp qquicktabbutton_p.h + qquicktextarea.cpp qquicktextarea_p.h + qquicktextarea_p_p.h + qquicktextfield.cpp qquicktextfield_p.h + qquicktextfield_p_p.h + qquicktheme.cpp qquicktheme_p.h + qquicktheme_p_p.h + qquicktoolbar.cpp qquicktoolbar_p.h + qquicktoolbutton.cpp qquicktoolbutton_p.h + qquicktoolseparator.cpp qquicktoolseparator_p.h + qquicktooltip.cpp qquicktooltip_p.h + qquickvelocitycalculator.cpp + qquickvelocitycalculator_p_p.h + qtquicktemplates2global.cpp qtquicktemplates2global_p.h + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_SOURCE_DIR} + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickPrivate + PUBLIC_LIBRARIES + Qt::Core + Qt::Gui + Qt::Quick +) + +qt_internal_extend_target(QuickTemplates2 CONDITION TARGET Qt::QmlModels + LIBRARIES + Qt::QmlModelsPrivate + PUBLIC_LIBRARIES + Qt::QmlModels + PRIVATE_MODULE_INTERFACE + Qt::QmlModelsPrivate +) + +qt_internal_extend_target(QuickTemplates2 CONDITION QT_FEATURE_accessibility + SOURCES + accessible/qaccessiblequickpage.cpp accessible/qaccessiblequickpage_p.h +) + +qt_internal_extend_target(QuickTemplates2 CONDITION QT_FEATURE_quick_tableview + SOURCES + qquickheaderview.cpp qquickheaderview_p.h + qquickheaderview_p_p.h +) + +qt_internal_extend_target(QuickTemplates2 CONDITION QT_FEATURE_quick_listview AND QT_FEATURE_quick_pathview + SOURCES + qquicktumbler.cpp qquicktumbler_p.h + qquicktumbler_p_p.h +) + +qt_internal_extend_Target(qtquicktemplates2plugin + SOURCES + qtquicktemplates2plugin.cpp + LIBRARIES + Qt::Quick + Qt::QuickTemplates2Private +) diff --git a/src/quicktemplates2/accessible/accessible.pri b/src/quicktemplates2/accessible/accessible.pri new file mode 100644 index 00000000000..0c855d34c6c --- /dev/null +++ b/src/quicktemplates2/accessible/accessible.pri @@ -0,0 +1,4 @@ +HEADERS += \ + $$PWD/qaccessiblequickpage_p.h \ +SOURCES += \ + $$PWD/qaccessiblequickpage.cpp \ diff --git a/src/quicktemplates2/accessible/qaccessiblequickpage.cpp b/src/quicktemplates2/accessible/qaccessiblequickpage.cpp new file mode 100644 index 00000000000..90ac49f9da4 --- /dev/null +++ b/src/quicktemplates2/accessible/qaccessiblequickpage.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qaccessiblequickpage_p.h" +#include "qquickpage_p.h" + +QT_BEGIN_NAMESPACE + +QAccessibleQuickPage::QAccessibleQuickPage(QQuickPage *page) + : QAccessibleQuickItem(page) +{ +} + +QAccessibleInterface *QAccessibleQuickPage::child(int index) const +{ + const QList<QQuickItem*> kids = orderedChildItems(); + if (QQuickItem *item = kids.value(index)) + return QAccessible::queryAccessibleInterface(item); + return nullptr; +} + +int QAccessibleQuickPage::indexOfChild(const QAccessibleInterface *iface) const +{ + const QList<QQuickItem*> kids = orderedChildItems(); + return (int)kids.indexOf(static_cast<QQuickItem*>(iface->object())); +} + +QList<QQuickItem *> QAccessibleQuickPage::orderedChildItems() const +{ + // Just ensures that the header is first, and footer is last. Other existing order is kept. + const QQuickPage *p = page(); + QList<QQuickItem*> kids = childItems(); + const qsizetype hidx = kids.indexOf(p->header()); + if (hidx != -1) + kids.move(hidx, 0); + const qsizetype fidx = kids.indexOf(p->footer()); + if (fidx != -1) + kids.move(fidx, kids.count() - 1); + return kids; +} + +QQuickPage *QAccessibleQuickPage::page() const +{ + return static_cast<QQuickPage*>(object()); +} + +QT_END_NAMESPACE + diff --git a/src/quicktemplates2/accessible/qaccessiblequickpage_p.h b/src/quicktemplates2/accessible/qaccessiblequickpage_p.h new file mode 100644 index 00000000000..9b208c14150 --- /dev/null +++ b/src/quicktemplates2/accessible/qaccessiblequickpage_p.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QACCESSIBLEQUICKPAGE_H +#define QACCESSIBLEQUICKPAGE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qaccessiblequickitem_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickPage; + +class QAccessibleQuickPage : public QAccessibleQuickItem +{ +public: + QAccessibleQuickPage(QQuickPage *page); + QAccessibleInterface *child(int index) const override; + int indexOfChild(const QAccessibleInterface *iface) const override; +private: + QQuickPage *page() const; + QList<QQuickItem *> orderedChildItems() const; +}; + +QT_END_NAMESPACE + +#endif // QACCESSIBLEQUICKPAGE_H diff --git a/src/quicktemplates2/configure.cmake b/src/quicktemplates2/configure.cmake new file mode 100644 index 00000000000..4e097569392 --- /dev/null +++ b/src/quicktemplates2/configure.cmake @@ -0,0 +1,30 @@ + + +#### Inputs + + + +#### Libraries + + + +#### Tests + + + +#### Features + +qt_feature("quicktemplates2-hover" PRIVATE + SECTION "Quick Templates 2" + LABEL "Hover support" + PURPOSE "Provides support for hover effects." +) +qt_feature("quicktemplates2-multitouch" PRIVATE + SECTION "Quick Templates 2" + LABEL "Multi-touch support" + PURPOSE "Provides support for multi-touch." +) +qt_configure_add_summary_section(NAME "Qt Quick Templates 2") +qt_configure_add_summary_entry(ARGS "quicktemplates2-hover") +qt_configure_add_summary_entry(ARGS "quicktemplates2-multitouch") +qt_configure_end_summary_section() # end of "Qt Quick Templates 2" section diff --git a/src/quicktemplates2/doc/src/qtquicktemplates2-index.qdoc b/src/quicktemplates2/doc/src/qtquicktemplates2-index.qdoc new file mode 100644 index 00000000000..c7e25548212 --- /dev/null +++ b/src/quicktemplates2/doc/src/qtquicktemplates2-index.qdoc @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtquicktemplates2-index.html + \title Qt Quick Templates 2 + \brief A set of templates to create user interface controls in Qt Quick + + Qt Quick Templates are the foundations of \l {Qt Quick Controls}. Templates + are non-visual implementations of controls' logic and behavior. They offer + an interface to visualize the controls in QML using \l {Qt Quick}. + + Even though the templates aim to be as style-agnostic as possible, in some + cases they have to make certain assumptions about the visual structure of + a control. For example, a spinbox has buttons that increment and decrement + the value of the spinbox. In order to implement the behavior of a spinbox, + the spinbox template needs to know if the user is interacting with the up + or down button. A visual implementation of the spinbox template merely needs + to position the up and down buttons and visualize them in normal, pressed, + and disabled states. Any input event handling and state processing is taken + care of by the underlying template. + + \section1 Module Evolution + \l{Changes to Qt Quick Controls} lists important changes in the + module API and functionality that were done for the Qt 6 series of Qt. + + \section1 Related Information + + \list + \li \l{Qt Quick} + \li \l{Qt Quick Controls} + \li \l{Qt Quick Templates 2 QML Types} + \endlist +*/ diff --git a/src/quicktemplates2/doc/src/qtquicktemplates2-qmltypes.qdoc b/src/quicktemplates2/doc/src/qtquicktemplates2-qmltypes.qdoc new file mode 100644 index 00000000000..feb770bb54d --- /dev/null +++ b/src/quicktemplates2/doc/src/qtquicktemplates2-qmltypes.qdoc @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \qmlmodule QtQuick.Templates + \title Qt Quick Templates 2 QML Types + \ingroup qmlmodules + \brief Provides QML types for templates (Qt Quick Templates). + + The \l {Qt Quick Templates 2} module provides a set of non-visual templates + that can be used to build user interface controls in QML using \l {Qt Quick}. + + The QML types can be imported using the following import statement in your + \c .qml file: + + \qml + import QtQuick.Templates as T + \endqml + + For the sake of clarity, there is a one-to-one mapping between the types + provided by the \c QtQuick.Templates and \c QtQuick.Controls imports. For + every type available in the \c QtQuick.Controls import, a non-visual template + type by the same name exists in the \c QtQuick.Templates import. + + \note It is recommended to use a namespace for the templates import to avoid + overlap with the types provided by the \c QtQuick.Controls import. + + \section1 QML Types + + \generatelist {qmltypesbymodule QtQuick.Controls} + + \section1 Related Information + + \list + \li \l {Qt Quick Controls QML Types} + \li \l {Using Qt Quick Controls types in property declarations} + \endlist + + \noautolist +*/ diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp new file mode 100644 index 00000000000..ffda109dfa4 --- /dev/null +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -0,0 +1,1220 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickabstractbutton_p.h" +#include "qquickabstractbutton_p_p.h" +#include "qquickbuttongroup_p.h" +#include "qquickaction_p.h" +#include "qquickaction_p_p.h" +#include "qquickshortcutcontext_p_p.h" +#include "qquickdeferredexecute_p_p.h" + +#include <QtGui/qstylehints.h> +#include <QtGui/qguiapplication.h> +#if QT_CONFIG(shortcut) +# include <QtGui/private/qshortcutmap_p.h> +#endif +#include <QtGui/private/qguiapplication_p.h> +#include <QtQuick/private/qquickevents_p_p.h> +#include <QtQml/qqmllist.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype AbstractButton + \inherits Control +//! \instantiates QQuickAbstractButton + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-buttons + \brief Abstract base type providing functionality common to buttons. + + AbstractButton provides the interface for controls with button-like + behavior; for example, push buttons and checkable controls like + radio buttons and check boxes. As an abstract control, it has no delegate + implementations, leaving them to the types that derive from it. + + \sa ButtonGroup, {Button Controls} +*/ + +/*! + \qmlsignal QtQuick.Controls::AbstractButton::pressed() + + This signal is emitted when the button is interactively pressed by the user via touch, mouse, or keyboard. +*/ + +/*! + \qmlsignal QtQuick.Controls::AbstractButton::released() + + This signal is emitted when the button is interactively released by the user via touch, mouse, or keyboard. +*/ + +/*! + \qmlsignal QtQuick.Controls::AbstractButton::canceled() + + This signal is emitted when the button loses mouse grab + while being pressed, or when it would emit the \l released + signal but the mouse cursor is not inside the button. +*/ + +/*! + \qmlsignal QtQuick.Controls::AbstractButton::clicked() + + This signal is emitted when the button is interactively clicked by the user via touch, mouse, or keyboard. +*/ + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlsignal QtQuick.Controls::AbstractButton::toggled() + + This signal is emitted when a checkable button is interactively toggled by the user via touch, mouse, or keyboard. +*/ + +/*! + \qmlsignal QtQuick.Controls::AbstractButton::pressAndHold() + + This signal is emitted when the button is interactively pressed and held down by the user via touch or mouse. + It is not emitted when \l autoRepeat is enabled. +*/ + +/*! + \qmlsignal QtQuick.Controls::AbstractButton::doubleClicked() + + This signal is emitted when the button is interactively double clicked by the user via touch or mouse. +*/ + +void QQuickAbstractButtonPrivate::setPressPoint(const QPointF &point) +{ + pressPoint = point; + setMovePoint(point); +} + +void QQuickAbstractButtonPrivate::setMovePoint(const QPointF &point) +{ + Q_Q(QQuickAbstractButton); + bool xChange = !qFuzzyCompare(point.x(), movePoint.x()); + bool yChange = !qFuzzyCompare(point.y(), movePoint.y()); + movePoint = point; + if (xChange) + emit q->pressXChanged(); + if (yChange) + emit q->pressYChanged(); +} + +void QQuickAbstractButtonPrivate::handlePress(const QPointF &point) +{ + Q_Q(QQuickAbstractButton); + QQuickControlPrivate::handlePress(point); + setPressPoint(point); + q->setPressed(true); + + emit q->pressed(); + + if (autoRepeat) + startRepeatDelay(); + else if (touchId != -1 || Qt::LeftButton == (pressButtons & Qt::LeftButton)) + startPressAndHold(); + else + stopPressAndHold(); +} + +void QQuickAbstractButtonPrivate::handleMove(const QPointF &point) +{ + Q_Q(QQuickAbstractButton); + QQuickControlPrivate::handleMove(point); + setMovePoint(point); + q->setPressed(keepPressed || q->contains(point)); + + if (!pressed && autoRepeat) + stopPressRepeat(); + else if (holdTimer > 0 && (!pressed || QLineF(pressPoint, point).length() > QGuiApplication::styleHints()->startDragDistance())) + stopPressAndHold(); +} + +void QQuickAbstractButtonPrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickAbstractButton); + QQuickControlPrivate::handleRelease(point); + bool wasPressed = pressed; + setPressPoint(point); + q->setPressed(false); + pressButtons = Qt::NoButton; + + if (!wasHeld && (keepPressed || q->contains(point))) + q->nextCheckState(); + + if (wasPressed) { + emit q->released(); + if (!wasHeld && !wasDoubleClick) + trigger(); + } else { + emit q->canceled(); + } + + if (autoRepeat) + stopPressRepeat(); + else + stopPressAndHold(); + + wasDoubleClick = false; +} + +void QQuickAbstractButtonPrivate::handleUngrab() +{ + Q_Q(QQuickAbstractButton); + QQuickControlPrivate::handleUngrab(); + pressButtons = Qt::NoButton; + if (!pressed) + return; + + q->setPressed(false); + stopPressRepeat(); + stopPressAndHold(); + wasDoubleClick = false; + emit q->canceled(); +} + +bool QQuickAbstractButtonPrivate::acceptKeyClick(Qt::Key key) const +{ + return key == Qt::Key_Space; +} + +bool QQuickAbstractButtonPrivate::isPressAndHoldConnected() +{ + Q_Q(QQuickAbstractButton); + static const QMetaMethod method = [&]() { + const auto signal = &QQuickAbstractButton::pressAndHold; + return QMetaMethod::fromSignal(signal); + }(); + return q->isSignalConnected(method); +} + +bool QQuickAbstractButtonPrivate::isDoubleClickConnected() +{ + Q_Q(QQuickAbstractButton); + static const QMetaMethod method = [&]() { + const auto signal = &QQuickAbstractButton::doubleClicked; + return QMetaMethod::fromSignal(signal); + }(); + return q->isSignalConnected(method); +} + +void QQuickAbstractButtonPrivate::startPressAndHold() +{ + Q_Q(QQuickAbstractButton); + wasHeld = false; + stopPressAndHold(); + if (isPressAndHoldConnected()) + holdTimer = q->startTimer(QGuiApplication::styleHints()->mousePressAndHoldInterval()); +} + +void QQuickAbstractButtonPrivate::stopPressAndHold() +{ + Q_Q(QQuickAbstractButton); + if (holdTimer > 0) { + q->killTimer(holdTimer); + holdTimer = 0; + } +} + +void QQuickAbstractButtonPrivate::startRepeatDelay() +{ + Q_Q(QQuickAbstractButton); + stopPressRepeat(); + delayTimer = q->startTimer(repeatDelay); +} + +void QQuickAbstractButtonPrivate::startPressRepeat() +{ + Q_Q(QQuickAbstractButton); + stopPressRepeat(); + repeatTimer = q->startTimer(repeatInterval); +} + +void QQuickAbstractButtonPrivate::stopPressRepeat() +{ + Q_Q(QQuickAbstractButton); + if (delayTimer > 0) { + q->killTimer(delayTimer); + delayTimer = 0; + } + if (repeatTimer > 0) { + q->killTimer(repeatTimer); + repeatTimer = 0; + } +} + +#if QT_CONFIG(shortcut) +void QQuickAbstractButtonPrivate::grabShortcut() +{ + Q_Q(QQuickAbstractButton); + if (shortcut.isEmpty()) + return; + + shortcutId = QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(q, shortcut, Qt::WindowShortcut, QQuickShortcutContext::matcher); + + if (!q->isEnabled()) + QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(false, shortcutId, q); +} + +void QQuickAbstractButtonPrivate::ungrabShortcut() +{ + Q_Q(QQuickAbstractButton); + if (!shortcutId) + return; + + QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(shortcutId, q); + shortcutId = 0; +} +#endif + +void QQuickAbstractButtonPrivate::actionTextChange() +{ + Q_Q(QQuickAbstractButton); + if (explicitText) + return; + + q->buttonChange(QQuickAbstractButton::ButtonTextChange); +} + +void QQuickAbstractButtonPrivate::setText(const QString &newText, bool isExplicit) +{ + Q_Q(QQuickAbstractButton); + const QString oldText = q->text(); + explicitText = isExplicit; + text = newText; + if (oldText == q->text()) + return; + + q->buttonChange(QQuickAbstractButton::ButtonTextChange); +} + +void QQuickAbstractButtonPrivate::updateEffectiveIcon() +{ + Q_Q(QQuickAbstractButton); + // We store effectiveIcon because we need to be able to tell if the icon has actually changed. + // If we only stored our icon and the action's icon, and resolved in the getter, we'd have + // no way of knowing what the old value was here. As an added benefit, we only resolve when + // something has changed, as opposed to doing it unconditionally in the icon() getter. + const QQuickIcon newEffectiveIcon = action ? icon.resolve(action->icon()) : icon; + if (newEffectiveIcon == effectiveIcon) + return; + + effectiveIcon = newEffectiveIcon; + emit q->iconChanged(); +} + +void QQuickAbstractButtonPrivate::click() +{ + Q_Q(QQuickAbstractButton); + if (effectiveEnable) + emit q->clicked(); +} + +void QQuickAbstractButtonPrivate::trigger() +{ + Q_Q(QQuickAbstractButton); + const bool wasEnabled = effectiveEnable; + if (action && action->isEnabled()) + QQuickActionPrivate::get(action)->trigger(q, false); + if (wasEnabled && (!action || !action->isEnabled())) + emit q->clicked(); +} + +void QQuickAbstractButtonPrivate::toggle(bool value) +{ + Q_Q(QQuickAbstractButton); + const bool wasChecked = checked; + q->setChecked(value); + if (wasChecked != checked) + emit q->toggled(); +} + +static inline QString indicatorName() { return QStringLiteral("indicator"); } + +void QQuickAbstractButtonPrivate::cancelIndicator() +{ + Q_Q(QQuickAbstractButton); + quickCancelDeferred(q, indicatorName()); +} + +void QQuickAbstractButtonPrivate::executeIndicator(bool complete) +{ + Q_Q(QQuickAbstractButton); + if (indicator.wasExecuted()) + return; + + if (!indicator || complete) + quickBeginDeferred(q, indicatorName(), indicator); + if (complete) + quickCompleteDeferred(q, indicatorName(), indicator); +} + +void QQuickAbstractButtonPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickAbstractButton); + QQuickControlPrivate::itemImplicitWidthChanged(item); + if (item == indicator) + emit q->implicitIndicatorWidthChanged(); +} + +void QQuickAbstractButtonPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickAbstractButton); + QQuickControlPrivate::itemImplicitHeightChanged(item); + if (item == indicator) + emit q->implicitIndicatorHeightChanged(); +} + +void QQuickAbstractButtonPrivate::itemDestroyed(QQuickItem *item) +{ + Q_Q(QQuickAbstractButton); + QQuickControlPrivate::itemDestroyed(item); + if (item == indicator) { + indicator = nullptr; + emit q->implicitIndicatorWidthChanged(); + emit q->implicitIndicatorHeightChanged(); + } +} + +QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const +{ + Q_Q(const QQuickAbstractButton); + if (group) + return qobject_cast<QQuickAbstractButton *>(group->checkedButton()); + + const QList<QQuickAbstractButton *> buttons = findExclusiveButtons(); + // TODO: A singular QRadioButton can be unchecked, which seems logical, + // because there's nothing to be exclusive with. However, a RadioButton + // from QtQuick.Controls 1.x can never be unchecked, which is the behavior + // that QQuickRadioButton adopted. Uncommenting the following count check + // gives the QRadioButton behavior. Notice that tst_radiobutton.qml needs + // to be updated. + if (!autoExclusive /*|| buttons.count() == 1*/) + return nullptr; + + for (QQuickAbstractButton *button : buttons) { + if (button->isChecked() && button != q) + return button; + } + return checked ? const_cast<QQuickAbstractButton *>(q) : nullptr; +} + +QList<QQuickAbstractButton *> QQuickAbstractButtonPrivate::findExclusiveButtons() const +{ + QList<QQuickAbstractButton *> buttons; + if (group) { + QQmlListProperty<QQuickAbstractButton> groupButtons = group->buttons(); + int count = groupButtons.count(&groupButtons); + for (int i = 0; i < count; ++i) { + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(groupButtons.at(&groupButtons, i)); + if (button) + buttons += button; + } + } else if (parentItem) { + const auto childItems = parentItem->childItems(); + for (QQuickItem *child : childItems) { + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(child); + if (button && button->autoExclusive() && !QQuickAbstractButtonPrivate::get(button)->group) + buttons += button; + } + } + return buttons; +} + +QQuickAbstractButton::QQuickAbstractButton(QQuickItem *parent) + : QQuickControl(*(new QQuickAbstractButtonPrivate), parent) +{ + setActiveFocusOnTab(true); +#ifdef Q_OS_MACOS + setFocusPolicy(Qt::TabFocus); +#else + setFocusPolicy(Qt::StrongFocus); +#endif + setAcceptedMouseButtons(Qt::LeftButton); +#if QT_CONFIG(quicktemplates2_multitouch) + setAcceptTouchEvents(true); +#endif +#if QT_CONFIG(cursor) + setCursor(Qt::ArrowCursor); +#endif +} + +QQuickAbstractButton::QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQuickItem *parent) + : QQuickControl(dd, parent) +{ + setActiveFocusOnTab(true); +#ifdef Q_OS_MACOS + setFocusPolicy(Qt::TabFocus); +#else + setFocusPolicy(Qt::StrongFocus); +#endif + setAcceptedMouseButtons(Qt::LeftButton); +#if QT_CONFIG(quicktemplates2_multitouch) + setAcceptTouchEvents(true); +#endif +#if QT_CONFIG(cursor) + setCursor(Qt::ArrowCursor); +#endif +} + +QQuickAbstractButton::~QQuickAbstractButton() +{ + Q_D(QQuickAbstractButton); + d->removeImplicitSizeListener(d->indicator); + if (d->group) + d->group->removeButton(this); +#if QT_CONFIG(shortcut) + d->ungrabShortcut(); +#endif +} + +/*! + \qmlproperty string QtQuick.Controls::AbstractButton::text + + This property holds a textual description of the button. + + \note The text is used for accessibility purposes, so it makes sense to + set a textual description even if the content item is an image. + + \sa icon, display, {Control::contentItem}{contentItem} +*/ +QString QQuickAbstractButton::text() const +{ + Q_D(const QQuickAbstractButton); + return d->explicitText || !d->action ? d->text : d->action->text(); +} + +void QQuickAbstractButton::setText(const QString &text) +{ + Q_D(QQuickAbstractButton); + d->setText(text, true); +} + +void QQuickAbstractButton::resetText() +{ + Q_D(QQuickAbstractButton); + d->setText(QString(), false); +} + +/*! + \qmlproperty bool QtQuick.Controls::AbstractButton::down + + This property holds whether the button is visually down. + + Unless explicitly set, this property follows the value of \l pressed. To + return to the default value, set this property to \c undefined. + + \sa pressed +*/ +bool QQuickAbstractButton::isDown() const +{ + Q_D(const QQuickAbstractButton); + return d->down; +} + +void QQuickAbstractButton::setDown(bool down) +{ + Q_D(QQuickAbstractButton); + d->explicitDown = true; + + if (d->down == down) + return; + + d->down = down; + emit downChanged(); +} + +void QQuickAbstractButton::resetDown() +{ + Q_D(QQuickAbstractButton); + if (!d->explicitDown) + return; + + setDown(d->pressed); + d->explicitDown = false; +} + +/*! + \qmlproperty bool QtQuick.Controls::AbstractButton::pressed + \readonly + + This property holds whether the button is physically pressed. A button can + be pressed by either touch or key events. + + \sa down +*/ +bool QQuickAbstractButton::isPressed() const +{ + Q_D(const QQuickAbstractButton); + return d->pressed; +} + +void QQuickAbstractButton::setPressed(bool isPressed) +{ + Q_D(QQuickAbstractButton); + if (d->pressed == isPressed) + return; + + d->pressed = isPressed; + setAccessibleProperty("pressed", isPressed); + emit pressedChanged(); + buttonChange(ButtonPressedChanged); + + if (!d->explicitDown) { + setDown(d->pressed); + d->explicitDown = false; + } +} + +/*! + \qmlproperty bool QtQuick.Controls::AbstractButton::checked + + This property holds whether the button is checked. + + Since Qt 6.2, setting this property no longer affects the + \l {AbstractButton::}{checkable} property. Explicitly set the + \c checkable property if needed. + + \sa checkable +*/ +bool QQuickAbstractButton::isChecked() const +{ + Q_D(const QQuickAbstractButton); + return d->checked; +} + +void QQuickAbstractButton::setChecked(bool checked) +{ + Q_D(QQuickAbstractButton); + if (d->checked == checked) + return; + + d->checked = checked; + if (d->action) + d->action->setChecked(checked); + setAccessibleProperty("checked", checked); + buttonChange(ButtonCheckedChange); + emit checkedChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::AbstractButton::checkable + + This property holds whether the button is checkable. + + A checkable button toggles between checked (on) and unchecked (off) when + the user clicks on it or presses the space bar while the button has active + focus. + + The default value is \c false. + + \sa checked +*/ +bool QQuickAbstractButton::isCheckable() const +{ + Q_D(const QQuickAbstractButton); + return d->checkable; +} + +void QQuickAbstractButton::setCheckable(bool checkable) +{ + Q_D(QQuickAbstractButton); + if (d->checkable == checkable) + return; + + d->checkable = checkable; + if (d->action) + d->action->setCheckable(checkable); + setAccessibleProperty("checkable", checkable); + buttonChange(ButtonCheckableChange); + emit checkableChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::AbstractButton::autoExclusive + + This property holds whether auto-exclusivity is enabled. + + If auto-exclusivity is enabled, checkable buttons that belong to the same + parent item behave as if they were part of the same ButtonGroup. Only + one button can be checked at any time; checking another button automatically + unchecks the previously checked one. + + \note The property has no effect on buttons that belong to a ButtonGroup. + + RadioButton and TabButton are auto-exclusive by default. +*/ +bool QQuickAbstractButton::autoExclusive() const +{ + Q_D(const QQuickAbstractButton); + return d->autoExclusive; +} + +void QQuickAbstractButton::setAutoExclusive(bool exclusive) +{ + Q_D(QQuickAbstractButton); + if (d->autoExclusive == exclusive) + return; + + d->autoExclusive = exclusive; + emit autoExclusiveChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::AbstractButton::autoRepeat + + This property holds whether the button repeats \l pressed(), \l released() + and \l clicked() signals while the button is pressed and held down. + + If this property is set to \c true, the \l pressAndHold() signal will not + be emitted. + + The default value is \c false. + + The initial delay and the repetition interval are defined in milliseconds + by \l autoRepeatDelay and \l autoRepeatInterval. +*/ +bool QQuickAbstractButton::autoRepeat() const +{ + Q_D(const QQuickAbstractButton); + return d->autoRepeat; +} + +void QQuickAbstractButton::setAutoRepeat(bool repeat) +{ + Q_D(QQuickAbstractButton); + if (d->autoRepeat == repeat) + return; + + d->stopPressRepeat(); + d->autoRepeat = repeat; + emit autoRepeatChanged(); +} + +/*! + \qmlproperty Item QtQuick.Controls::AbstractButton::indicator + + This property holds the indicator item. +*/ +QQuickItem *QQuickAbstractButton::indicator() const +{ + QQuickAbstractButtonPrivate *d = const_cast<QQuickAbstractButtonPrivate *>(d_func()); + if (!d->indicator) + d->executeIndicator(); + return d->indicator; +} + +void QQuickAbstractButton::setIndicator(QQuickItem *indicator) +{ + Q_D(QQuickAbstractButton); + if (d->indicator == indicator) + return; + + if (!d->indicator.isExecuting()) + d->cancelIndicator(); + + const qreal oldImplicitIndicatorWidth = implicitIndicatorWidth(); + const qreal oldImplicitIndicatorHeight = implicitIndicatorHeight(); + + d->removeImplicitSizeListener(d->indicator); + QQuickControlPrivate::hideOldItem(d->indicator); + d->indicator = indicator; + + if (indicator) { + if (!indicator->parentItem()) + indicator->setParentItem(this); + indicator->setAcceptedMouseButtons(Qt::LeftButton); + d->addImplicitSizeListener(indicator); + } + + if (!qFuzzyCompare(oldImplicitIndicatorWidth, implicitIndicatorWidth())) + emit implicitIndicatorWidthChanged(); + if (!qFuzzyCompare(oldImplicitIndicatorHeight, implicitIndicatorHeight())) + emit implicitIndicatorHeightChanged(); + if (!d->indicator.isExecuting()) + emit indicatorChanged(); +} + +/*! + \qmlproperty string QtQuick.Controls::AbstractButton::icon.name + \qmlproperty url QtQuick.Controls::AbstractButton::icon.source + \qmlproperty int QtQuick.Controls::AbstractButton::icon.width + \qmlproperty int QtQuick.Controls::AbstractButton::icon.height + \qmlproperty color QtQuick.Controls::AbstractButton::icon.color + \qmlproperty bool QtQuick.Controls::AbstractButton::icon.cache + + This property group was added in QtQuick.Controls 2.3. + + \include qquickicon.qdocinc grouped-properties + + \sa text, display, {Icons in Qt Quick Controls} +*/ + +QQuickIcon QQuickAbstractButton::icon() const +{ + Q_D(const QQuickAbstractButton); + return d->effectiveIcon; +} + +void QQuickAbstractButton::setIcon(const QQuickIcon &icon) +{ + Q_D(QQuickAbstractButton); + d->icon = icon; + d->icon.ensureRelativeSourceResolved(this); + d->updateEffectiveIcon(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty enumeration QtQuick.Controls::AbstractButton::display + + This property determines how the \l icon and \l text are displayed within + the button. + + \table + \header \li Display \li Result + \row \li \c AbstractButton.IconOnly \li \image qtquickcontrols2-button-icononly.png + \row \li \c AbstractButton.TextOnly \li \image qtquickcontrols2-button-textonly.png + \row \li \c AbstractButton.TextBesideIcon \li \image qtquickcontrols2-button-textbesideicon.png + \row \li \c AbstractButton.TextUnderIcon \li \image qtquickcontrols2-button-textundericon.png + \endtable + + \sa {Control::}{spacing}, {Control::}{padding} +*/ +QQuickAbstractButton::Display QQuickAbstractButton::display() const +{ + Q_D(const QQuickAbstractButton); + return d->display; +} + +void QQuickAbstractButton::setDisplay(Display display) +{ + Q_D(QQuickAbstractButton); + if (display == d->display) + return; + + d->display = display; + emit displayChanged(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty Action QtQuick.Controls::AbstractButton::action + + This property holds the button action. + + \sa Action +*/ +QQuickAction *QQuickAbstractButton::action() const +{ + Q_D(const QQuickAbstractButton); + return d->action; +} + +void QQuickAbstractButton::setAction(QQuickAction *action) +{ + Q_D(QQuickAbstractButton); + if (d->action == action) + return; + + const QString oldText = text(); + + if (QQuickAction *oldAction = d->action.data()) { + QQuickActionPrivate::get(oldAction)->unregisterItem(this); + QObjectPrivate::disconnect(oldAction, &QQuickAction::triggered, d, &QQuickAbstractButtonPrivate::click); + QObjectPrivate::disconnect(oldAction, &QQuickAction::textChanged, d, &QQuickAbstractButtonPrivate::actionTextChange); + + QObjectPrivate::disconnect(oldAction, &QQuickAction::iconChanged, d, &QQuickAbstractButtonPrivate::updateEffectiveIcon); + disconnect(oldAction, &QQuickAction::checkedChanged, this, &QQuickAbstractButton::setChecked); + disconnect(oldAction, &QQuickAction::checkableChanged, this, &QQuickAbstractButton::setCheckable); + disconnect(oldAction, &QQuickAction::enabledChanged, this, &QQuickItem::setEnabled); + } + + if (action) { + QQuickActionPrivate::get(action)->registerItem(this); + QObjectPrivate::connect(action, &QQuickAction::triggered, d, &QQuickAbstractButtonPrivate::click); + QObjectPrivate::connect(action, &QQuickAction::textChanged, d, &QQuickAbstractButtonPrivate::actionTextChange); + + QObjectPrivate::connect(action, &QQuickAction::iconChanged, d, &QQuickAbstractButtonPrivate::updateEffectiveIcon); + connect(action, &QQuickAction::checkedChanged, this, &QQuickAbstractButton::setChecked); + connect(action, &QQuickAction::checkableChanged, this, &QQuickAbstractButton::setCheckable); + connect(action, &QQuickAction::enabledChanged, this, &QQuickItem::setEnabled); + + setChecked(action->isChecked()); + setCheckable(action->isCheckable()); + setEnabled(action->isEnabled()); + } + + d->action = action; + + if (oldText != text()) + buttonChange(ButtonTextChange); + + d->updateEffectiveIcon(); + + emit actionChanged(); +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty int QtQuick.Controls::AbstractButton::autoRepeatDelay + + This property holds the initial delay of auto-repetition in milliseconds. + The default value is \c 300 ms. + + \sa autoRepeat, autoRepeatInterval +*/ +int QQuickAbstractButton::autoRepeatDelay() const +{ + Q_D(const QQuickAbstractButton); + return d->repeatDelay; +} + +void QQuickAbstractButton::setAutoRepeatDelay(int delay) +{ + Q_D(QQuickAbstractButton); + if (d->repeatDelay == delay) + return; + + d->repeatDelay = delay; + emit autoRepeatDelayChanged(); +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty int QtQuick.Controls::AbstractButton::autoRepeatInterval + + This property holds the interval of auto-repetition in milliseconds. + The default value is \c 100 ms. + + \sa autoRepeat, autoRepeatDelay +*/ +int QQuickAbstractButton::autoRepeatInterval() const +{ + Q_D(const QQuickAbstractButton); + return d->repeatInterval; +} + +void QQuickAbstractButton::setAutoRepeatInterval(int interval) +{ + Q_D(QQuickAbstractButton); + if (d->repeatInterval == interval) + return; + + d->repeatInterval = interval; + emit autoRepeatIntervalChanged(); +} + +#if QT_CONFIG(shortcut) +QKeySequence QQuickAbstractButton::shortcut() const +{ + Q_D(const QQuickAbstractButton); + return d->shortcut; +} + +void QQuickAbstractButton::setShortcut(const QKeySequence &shortcut) +{ + Q_D(QQuickAbstractButton); + if (d->shortcut == shortcut) + return; + + d->ungrabShortcut(); + d->shortcut = shortcut; + if (isVisible()) + d->grabShortcut(); +} +#endif + +/*! + \readonly + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty real QtQuick.Controls::AbstractButton::pressX + + This property holds the x-coordinate of the last press. + + \note The value is updated on touch moves, but left intact after touch release. + + \sa pressY +*/ +qreal QQuickAbstractButton::pressX() const +{ + Q_D(const QQuickAbstractButton); + return d->movePoint.x(); +} + +/*! + \readonly + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty real QtQuick.Controls::AbstractButton::pressY + + This property holds the y-coordinate of the last press. + + \note The value is updated on touch moves, but left intact after touch release. + + \sa pressX +*/ +qreal QQuickAbstractButton::pressY() const +{ + Q_D(const QQuickAbstractButton); + return d->movePoint.y(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::AbstractButton::implicitIndicatorWidth + \readonly + + This property holds the implicit indicator width. + + The value is equal to \c {indicator ? indicator.implicitWidth : 0}. + + This is typically used, together with \l {Control::}{implicitContentWidth} and + \l {Control::}{implicitBackgroundWidth}, to calculate the \l {Item::}{implicitWidth}. + + \sa implicitIndicatorHeight +*/ +qreal QQuickAbstractButton::implicitIndicatorWidth() const +{ + Q_D(const QQuickAbstractButton); + if (!d->indicator) + return 0; + return d->indicator->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::AbstractButton::implicitIndicatorHeight + \readonly + + This property holds the implicit indicator height. + + The value is equal to \c {indicator ? indicator.implicitHeight : 0}. + + This is typically used, together with \l {Control::}{implicitContentHeight} and + \l {Control::}{implicitBackgroundHeight}, to calculate the \l {Item::}{implicitHeight}. + + \sa implicitIndicatorWidth +*/ +qreal QQuickAbstractButton::implicitIndicatorHeight() const +{ + Q_D(const QQuickAbstractButton); + if (!d->indicator) + return 0; + return d->indicator->implicitHeight(); +} + +/*! + \qmlmethod void QtQuick.Controls::AbstractButton::toggle() + + Toggles the checked state of the button. +*/ +void QQuickAbstractButton::toggle() +{ + Q_D(QQuickAbstractButton); + setChecked(!d->checked); +} + +void QQuickAbstractButton::componentComplete() +{ + Q_D(QQuickAbstractButton); + d->executeIndicator(true); + QQuickControl::componentComplete(); +} + +bool QQuickAbstractButton::event(QEvent *event) +{ +#if QT_CONFIG(shortcut) + Q_D(QQuickAbstractButton); + if (event->type() == QEvent::Shortcut) { + QShortcutEvent *se = static_cast<QShortcutEvent *>(event); + if (se->shortcutId() == d->shortcutId) { + d->trigger(); + return true; + } + } +#endif + return QQuickControl::event(event); +} + +void QQuickAbstractButton::focusOutEvent(QFocusEvent *event) +{ + Q_D(QQuickAbstractButton); + QQuickControl::focusOutEvent(event); + if (d->touchId == -1) // don't ungrab on multi-touch if another control gets focused + d->handleUngrab(); +} + +void QQuickAbstractButton::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickAbstractButton); + QQuickControl::keyPressEvent(event); + if (d->acceptKeyClick(static_cast<Qt::Key>(event->key()))) { + d->setPressPoint(QPoint(qRound(width() / 2), qRound(height() / 2))); + setPressed(true); + + if (d->autoRepeat) + d->startRepeatDelay(); + + emit pressed(); + event->accept(); + } +} + +void QQuickAbstractButton::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QQuickAbstractButton); + QQuickControl::keyReleaseEvent(event); + if (d->pressed && d->acceptKeyClick(static_cast<Qt::Key>(event->key()))) { + setPressed(false); + + nextCheckState(); + emit released(); + d->trigger(); + + if (d->autoRepeat) + d->stopPressRepeat(); + event->accept(); + } +} + +void QQuickAbstractButton::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickAbstractButton); + d->pressButtons = event->buttons(); + QQuickControl::mousePressEvent(event); +} + +void QQuickAbstractButton::mouseDoubleClickEvent(QMouseEvent *event) +{ + Q_D(QQuickAbstractButton); + if (d->isDoubleClickConnected()) { + QQuickControl::mouseDoubleClickEvent(event); + emit doubleClicked(); + d->wasDoubleClick = true; + } +} + +void QQuickAbstractButton::timerEvent(QTimerEvent *event) +{ + Q_D(QQuickAbstractButton); + QQuickControl::timerEvent(event); + if (event->timerId() == d->holdTimer) { + d->stopPressAndHold(); + d->wasHeld = true; + emit pressAndHold(); + } else if (event->timerId() == d->delayTimer) { + d->startPressRepeat(); + } else if (event->timerId() == d->repeatTimer) { + emit released(); + d->trigger(); + emit pressed(); + } +} + +void QQuickAbstractButton::itemChange(ItemChange change, const ItemChangeData &value) +{ + QQuickControl::itemChange(change, value); +#if QT_CONFIG(shortcut) + Q_D(QQuickAbstractButton); + if (change == ItemVisibleHasChanged) { + if (value.boolValue) + d->grabShortcut(); + else + d->ungrabShortcut(); + } +#endif +} + +void QQuickAbstractButton::buttonChange(ButtonChange change) +{ + Q_D(QQuickAbstractButton); + switch (change) { + case ButtonCheckedChange: + if (d->checked) { + QQuickAbstractButton *button = d->findCheckedButton(); + if (button && button != this) + button->setChecked(false); + } + break; + case ButtonTextChange: { + const QString txt = text(); + maybeSetAccessibleName(txt); +#if QT_CONFIG(shortcut) + setShortcut(QKeySequence::mnemonic(txt)); +#endif + emit textChanged(); + break; + } + default: + break; + } +} + +void QQuickAbstractButton::nextCheckState() +{ + Q_D(QQuickAbstractButton); + if (d->checkable && (!d->checked || d->findCheckedButton() != this)) + d->toggle(!d->checked); +} + +#if QT_CONFIG(accessibility) +void QQuickAbstractButton::accessibilityActiveChanged(bool active) +{ + QQuickControl::accessibilityActiveChanged(active); + + Q_D(QQuickAbstractButton); + if (active) { + maybeSetAccessibleName(text()); + setAccessibleProperty("pressed", d->pressed); + setAccessibleProperty("checked", d->checked); + setAccessibleProperty("checkable", d->checkable); + } +} + +QAccessible::Role QQuickAbstractButton::accessibleRole() const +{ + Q_D(const QQuickAbstractButton); + if (d->checkable) { + return QAccessible::CheckBox; + } + return QAccessible::Button; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickabstractbutton_p.cpp" diff --git a/src/quicktemplates2/qquickabstractbutton_p.h b/src/quicktemplates2/qquickabstractbutton_p.h new file mode 100644 index 00000000000..a5dbd733d0f --- /dev/null +++ b/src/quicktemplates2/qquickabstractbutton_p.h @@ -0,0 +1,225 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKABSTRACTBUTTON_P_H +#define QQUICKABSTRACTBUTTON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickicon_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickAction; +class QQuickAbstractButtonPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickAbstractButton : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText RESET resetText NOTIFY textChanged FINAL) + Q_PROPERTY(bool down READ isDown WRITE setDown NOTIFY downChanged RESET resetDown FINAL) + Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged FINAL) + Q_PROPERTY(bool checked READ isChecked WRITE setChecked NOTIFY checkedChanged FINAL) + Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable NOTIFY checkableChanged FINAL) + Q_PROPERTY(bool autoExclusive READ autoExclusive WRITE setAutoExclusive NOTIFY autoExclusiveChanged FINAL) + Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY autoRepeatChanged FINAL) + Q_PROPERTY(QQuickItem *indicator READ indicator WRITE setIndicator NOTIFY indicatorChanged FINAL) + // 2.3 (Qt 5.10) + Q_PROPERTY(QQuickIcon icon READ icon WRITE setIcon NOTIFY iconChanged FINAL REVISION(2, 3)) + Q_PROPERTY(Display display READ display WRITE setDisplay NOTIFY displayChanged FINAL REVISION(2, 3)) + Q_PROPERTY(QQuickAction *action READ action WRITE setAction NOTIFY actionChanged FINAL REVISION(2, 3)) + // 2.4 (Qt 5.11) + Q_PROPERTY(int autoRepeatDelay READ autoRepeatDelay WRITE setAutoRepeatDelay NOTIFY autoRepeatDelayChanged FINAL REVISION(2, 4)) + Q_PROPERTY(int autoRepeatInterval READ autoRepeatInterval WRITE setAutoRepeatInterval NOTIFY autoRepeatIntervalChanged FINAL REVISION(2, 4)) + Q_PROPERTY(qreal pressX READ pressX NOTIFY pressXChanged FINAL REVISION(2, 4)) + Q_PROPERTY(qreal pressY READ pressY NOTIFY pressYChanged FINAL REVISION(2, 4)) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitIndicatorWidth READ implicitIndicatorWidth NOTIFY implicitIndicatorWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitIndicatorHeight READ implicitIndicatorHeight NOTIFY implicitIndicatorHeightChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,indicator") + QML_NAMED_ELEMENT(AbstractButton) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickAbstractButton(QQuickItem *parent = nullptr); + ~QQuickAbstractButton(); + + QString text() const; + void setText(const QString &text); + void resetText(); + + bool isDown() const; + void setDown(bool down); + void resetDown(); + + bool isPressed() const; + void setPressed(bool pressed); + + bool isChecked() const; + void setChecked(bool checked); + + bool isCheckable() const; + void setCheckable(bool checkable); + + bool autoExclusive() const; + void setAutoExclusive(bool exclusive); + + bool autoRepeat() const; + void setAutoRepeat(bool repeat); + + QQuickItem *indicator() const; + void setIndicator(QQuickItem *indicator); + + // 2.3 (Qt 5.10) + QQuickIcon icon() const; + void setIcon(const QQuickIcon &icon); + + enum Display { + IconOnly, + TextOnly, + TextBesideIcon, + TextUnderIcon + }; + Q_ENUM(Display) + + Display display() const; + void setDisplay(Display display); + + QQuickAction *action() const; + void setAction(QQuickAction *action); + +#if QT_CONFIG(shortcut) + QKeySequence shortcut() const; + void setShortcut(const QKeySequence &shortcut); +#endif + + // 2.4 (Qt 5.11) + int autoRepeatDelay() const; + void setAutoRepeatDelay(int delay); + + int autoRepeatInterval() const; + void setAutoRepeatInterval(int interval); + + qreal pressX() const; + qreal pressY() const; + + // 2.5 (Qt 5.12) + qreal implicitIndicatorWidth() const; + qreal implicitIndicatorHeight() const; + +public Q_SLOTS: + void toggle(); + +Q_SIGNALS: + void pressed(); + void released(); + void canceled(); + void clicked(); + void pressAndHold(); + void doubleClicked(); + void textChanged(); + void downChanged(); + void pressedChanged(); + void checkedChanged(); + void checkableChanged(); + void autoExclusiveChanged(); + void autoRepeatChanged(); + void indicatorChanged(); + // 2.2 (Qt 5.9) + Q_REVISION(2, 2) void toggled(); + // 2.3 (Qt 5.10) + Q_REVISION(2, 3) void iconChanged(); + Q_REVISION(2, 3) void displayChanged(); + Q_REVISION(2, 3) void actionChanged(); + // 2.4 (Qt 5.11) + Q_REVISION(2, 4) void autoRepeatDelayChanged(); + Q_REVISION(2, 4) void autoRepeatIntervalChanged(); + Q_REVISION(2, 4) void pressXChanged(); + Q_REVISION(2, 4) void pressYChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void implicitIndicatorWidthChanged(); + Q_REVISION(2, 5) void implicitIndicatorHeightChanged(); + +protected: + QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQuickItem *parent); + + void componentComplete() override; + + bool event(QEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void keyReleaseEvent(QKeyEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseDoubleClickEvent(QMouseEvent *event) override; + void timerEvent(QTimerEvent *event) override; + + void itemChange(ItemChange change, const ItemChangeData &value) override; + + enum ButtonChange { + ButtonCheckedChange, + ButtonCheckableChange, + ButtonPressedChanged, + ButtonTextChange + }; + virtual void buttonChange(ButtonChange change); + + virtual void nextCheckState(); + +#if QT_CONFIG(accessibility) + void accessibilityActiveChanged(bool active) override; + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickAbstractButton) + Q_DECLARE_PRIVATE(QQuickAbstractButton) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickAbstractButton) + +#endif // QQUICKABSTRACTBUTTON_P_H diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h new file mode 100644 index 00000000000..907790dcc80 --- /dev/null +++ b/src/quicktemplates2/qquickabstractbutton_p_p.h @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKABSTRACTBUTTON_P_P_H +#define QQUICKABSTRACTBUTTON_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p_p.h> +#if QT_CONFIG(shortcut) +# include <QtGui/qkeysequence.h> +#endif + +QT_BEGIN_NAMESPACE + +class QQuickAction; +class QQuickButtonGroup; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickAbstractButtonPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickAbstractButton) + +public: + static QQuickAbstractButtonPrivate *get(QQuickAbstractButton *button) + { + return button->d_func(); + } + + void setPressPoint(const QPointF &point); + void setMovePoint(const QPointF &point); + + void handlePress(const QPointF &point) override; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + void handleUngrab() override; + + virtual bool acceptKeyClick(Qt::Key key) const; + + bool isPressAndHoldConnected(); + bool isDoubleClickConnected(); + void startPressAndHold(); + void stopPressAndHold(); + + void startRepeatDelay(); + void startPressRepeat(); + void stopPressRepeat(); + +#if QT_CONFIG(shortcut) + void grabShortcut(); + void ungrabShortcut(); +#endif + + QQuickAbstractButton *findCheckedButton() const; + QList<QQuickAbstractButton *> findExclusiveButtons() const; + + void actionTextChange(); + void setText(const QString &text, bool isExplicit); + + void updateEffectiveIcon(); + + void click(); + void trigger(); + void toggle(bool value); + + void cancelIndicator(); + void executeIndicator(bool complete = false); + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + void itemDestroyed(QQuickItem *item) override; + + // copied from qabstractbutton.cpp + static const int AUTO_REPEAT_DELAY = 300; + static const int AUTO_REPEAT_INTERVAL = 100; + + bool explicitText = false; + bool down = false; + bool explicitDown = false; + bool pressed = false; + bool keepPressed = false; + bool checked = false; + bool checkable = false; + bool autoExclusive = false; + bool autoRepeat = false; + bool wasHeld = false; + bool wasDoubleClick = false; + int holdTimer = 0; + int delayTimer = 0; + int repeatTimer = 0; + int repeatDelay = AUTO_REPEAT_DELAY; + int repeatInterval = AUTO_REPEAT_INTERVAL; +#if QT_CONFIG(shortcut) + int shortcutId = 0; + QKeySequence shortcut; +#endif + QString text; + QQuickIcon icon; + QQuickIcon effectiveIcon; + QPointF pressPoint; + QPointF movePoint; + Qt::MouseButtons pressButtons = Qt::NoButton; + QQuickAbstractButton::Display display = QQuickAbstractButton::TextBesideIcon; + QQuickDeferredPointer<QQuickItem> indicator; + QQuickButtonGroup *group = nullptr; + QPointer<QQuickAction> action; +}; + +QT_END_NAMESPACE + +#endif // QQUICKABSTRACTBUTTON_P_P_H diff --git a/src/quicktemplates2/qquickaction.cpp b/src/quicktemplates2/qquickaction.cpp new file mode 100644 index 00000000000..193169162d4 --- /dev/null +++ b/src/quicktemplates2/qquickaction.cpp @@ -0,0 +1,587 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickaction_p.h" +#include "qquickaction_p_p.h" +#include "qquickactiongroup_p.h" +#include "qquickshortcutcontext_p_p.h" + +#include <QtGui/qevent.h> +#if QT_CONFIG(shortcut) +# include <QtGui/private/qshortcutmap_p.h> +#endif +#include <QtGui/private/qguiapplication_p.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Action + \inherits QtObject +//! \instantiates QQuickAction + \inqmlmodule QtQuick.Controls + \since 5.10 + \ingroup utilities + \brief Abstract user interface action. + + Action represents an abstract user interface action that can have shortcuts + and can be assigned to menu items and toolbar buttons. + + Actions may contain \l text, an \l icon, and a \l shortcut. Actions are normally + \l triggered by the user via menu items, toolbar buttons, or keyboard shortcuts. + A \l checkable Action toggles its \l checked state when triggered. + + \snippet qtquickcontrols2-action.qml action + + Action is commonly used to implement application commands that can be invoked + via menu items, toolbar buttons, and keyboard shortcuts. Since the user expects + the commands to be performed in the same way, regardless of the user interface + used, it is useful to represent the commands as shareable actions. + + Action can be also used to separate the logic and the visual presentation. For + example, when declaring buttons and menu items in \c .ui.qml files, actions can + be declared elsewhere and assigned from the outside. + + \snippet qtquickcontrols2-action.qml toolbutton + + When an action is paired with buttons and menu items, the \c enabled, \c checkable, + and \c checked states are synced automatically. For example, in a word processor, + if the user clicks a "Bold" toolbar button, the "Bold" menu item will automatically + be checked. Buttons and menu items get their \c text and \c icon from the action by + default. An action-specific \c text or \c icon can be overridden for a specific + control by specifying \c text or \c icon directly on the control. + + \snippet qtquickcontrols2-action.qml menuitem + + Since Action presents a user interface action, it is intended to be assigned to + a \l MenuItem, \l ToolButton, or any other control that inherits \l AbstractButton. + For keyboard shortcuts, the simpler \l Shortcut type is more appropriate. + + \sa MenuItem, ToolButton, Shortcut +*/ + +/*! + \qmlsignal QtQuick.Controls::Action::toggled(QtObject source) + + This signal is emitted when the action is toggled. The \a source argument + identifies the object that toggled the action. + + For example, if the action is assigned to a menu item and a toolbar button, the + action is toggled when the control is toggled, the shortcut is activated, or + when \l toggle() is called directly. +*/ + +/*! + \qmlsignal QtQuick.Controls::Action::triggered(QtObject source) + + This signal is emitted when the action is triggered. The \a source argument + identifies the object that triggered the action. + + For example, if the action is assigned to a menu item and a toolbar button, the + action is triggered when the control is clicked, the shortcut is activated, or + when \l trigger() is called directly. +*/ + +#if QT_CONFIG(shortcut) +static QKeySequence variantToKeySequence(const QVariant &var) +{ + if (var.metaType().id() == QMetaType::Int) + return QKeySequence(static_cast<QKeySequence::StandardKey>(var.toInt())); + return QKeySequence::fromString(var.toString()); +} + +QQuickActionPrivate::ShortcutEntry::ShortcutEntry(QObject *target) + : m_target(target) +{ +} + +QQuickActionPrivate::ShortcutEntry::~ShortcutEntry() +{ + ungrab(); +} + +QObject *QQuickActionPrivate::ShortcutEntry::target() const +{ + return m_target; +} + +int QQuickActionPrivate::ShortcutEntry::shortcutId() const +{ + return m_shortcutId; +} + +void QQuickActionPrivate::ShortcutEntry::grab(const QKeySequence &shortcut, bool enabled) +{ + if (shortcut.isEmpty() || m_shortcutId) + return; + + Qt::ShortcutContext context = Qt::WindowShortcut; // TODO + m_shortcutId = QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(m_target, shortcut, context, QQuickShortcutContext::matcher); + + if (!enabled) + QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(false, m_shortcutId, m_target); +} + +void QQuickActionPrivate::ShortcutEntry::ungrab() +{ + if (!m_shortcutId) + return; + + QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(m_shortcutId, m_target); + m_shortcutId = 0; +} + +void QQuickActionPrivate::ShortcutEntry::setEnabled(bool enabled) +{ + if (!m_shortcutId) + return; + + QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enabled, m_shortcutId, m_target); +} + +QVariant QQuickActionPrivate::shortcut() const +{ + return vshortcut; +} + +void QQuickActionPrivate::setShortcut(const QVariant &var) +{ + Q_Q(QQuickAction); + if (vshortcut == var) + return; + + defaultShortcutEntry->ungrab(); + for (QQuickActionPrivate::ShortcutEntry *entry : qAsConst(shortcutEntries)) + entry->ungrab(); + + vshortcut = var; + keySequence = variantToKeySequence(var); + + defaultShortcutEntry->grab(keySequence, enabled); + for (QQuickActionPrivate::ShortcutEntry *entry : qAsConst(shortcutEntries)) + entry->grab(keySequence, enabled); + + emit q->shortcutChanged(keySequence); +} +#endif // QT_CONFIG(shortcut) + +void QQuickActionPrivate::setEnabled(bool enable) +{ + Q_Q(QQuickAction); + if (enabled == enable) + return; + + enabled = enable; + +#if QT_CONFIG(shortcut) + defaultShortcutEntry->setEnabled(enable); + for (QQuickActionPrivate::ShortcutEntry *entry : qAsConst(shortcutEntries)) + entry->setEnabled(enable); +#endif + + emit q->enabledChanged(enable); +} + +bool QQuickActionPrivate::watchItem(QQuickItem *item) +{ + Q_Q(QQuickAction); + if (!item) + return false; + + item->installEventFilter(q); + QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Visibility | QQuickItemPrivate::Destroyed); + return true; +} + +bool QQuickActionPrivate::unwatchItem(QQuickItem *item) +{ + Q_Q(QQuickAction); + if (!item) + return false; + + item->removeEventFilter(q); + QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Visibility | QQuickItemPrivate::Destroyed); + return true; +} + +void QQuickActionPrivate::registerItem(QQuickItem *item) +{ + if (!watchItem(item)) + return; + +#if QT_CONFIG(shortcut) + QQuickActionPrivate::ShortcutEntry *entry = new QQuickActionPrivate::ShortcutEntry(item); + if (item->isVisible()) + entry->grab(keySequence, enabled); + shortcutEntries += entry; + + updateDefaultShortcutEntry(); +#endif +} + +void QQuickActionPrivate::unregisterItem(QQuickItem *item) +{ +#if QT_CONFIG(shortcut) + QQuickActionPrivate::ShortcutEntry *entry = findShortcutEntry(item); + if (!entry || !unwatchItem(item)) + return; + + shortcutEntries.removeOne(entry); + delete entry; + + updateDefaultShortcutEntry(); +#else + Q_UNUSED(item); +#endif +} + +void QQuickActionPrivate::itemVisibilityChanged(QQuickItem *item) +{ +#if QT_CONFIG(shortcut) + QQuickActionPrivate::ShortcutEntry *entry = findShortcutEntry(item); + if (!entry) + return; + + if (item->isVisible()) + entry->grab(keySequence, enabled); + else + entry->ungrab(); + + updateDefaultShortcutEntry(); +#else + Q_UNUSED(item); +#endif +} + +void QQuickActionPrivate::itemDestroyed(QQuickItem *item) +{ + unregisterItem(item); +} + +#if QT_CONFIG(shortcut) +bool QQuickActionPrivate::handleShortcutEvent(QObject *object, QShortcutEvent *event) +{ + Q_Q(QQuickAction); + if (event->key() != keySequence) + return false; + + QQuickActionPrivate::ShortcutEntry *entry = findShortcutEntry(object); + if (!entry || event->shortcutId() != entry->shortcutId()) + return false; + + q->trigger(entry->target()); + return true; +} + +QQuickActionPrivate::ShortcutEntry *QQuickActionPrivate::findShortcutEntry(QObject *target) const +{ + Q_Q(const QQuickAction); + if (target == q) + return defaultShortcutEntry; + for (QQuickActionPrivate::ShortcutEntry *entry : shortcutEntries) { + if (entry->target() == target) + return entry; + } + return nullptr; +} + +void QQuickActionPrivate::updateDefaultShortcutEntry() +{ + bool hasActiveShortcutEntries = false; + for (QQuickActionPrivate::ShortcutEntry *entry : qAsConst(shortcutEntries)) { + if (entry->shortcutId()) { + hasActiveShortcutEntries = true; + break; + } + } + + if (hasActiveShortcutEntries) + defaultShortcutEntry->ungrab(); + else if (!defaultShortcutEntry->shortcutId()) + defaultShortcutEntry->grab(keySequence, enabled); +} +#endif // QT_CONFIG(shortcut) + +QQuickAction::QQuickAction(QObject *parent) + : QObject(*(new QQuickActionPrivate), parent) +{ +#if QT_CONFIG(shortcut) + Q_D(QQuickAction); + d->defaultShortcutEntry = new QQuickActionPrivate::ShortcutEntry(this); +#endif +} + +QQuickAction::~QQuickAction() +{ + Q_D(QQuickAction); + if (d->group) + d->group->removeAction(this); + +#if QT_CONFIG(shortcut) + for (QQuickActionPrivate::ShortcutEntry *entry : qAsConst(d->shortcutEntries)) + d->unwatchItem(qobject_cast<QQuickItem *>(entry->target())); + + qDeleteAll(d->shortcutEntries); + delete d->defaultShortcutEntry; +#endif +} + +/*! + \qmlproperty string QtQuick.Controls::Action::text + + This property holds a textual description of the action. +*/ +QString QQuickAction::text() const +{ + Q_D(const QQuickAction); + return d->text; +} + +void QQuickAction::setText(const QString &text) +{ + Q_D(QQuickAction); + if (d->text == text) + return; + + d->text = text; + emit textChanged(text); +} + +/*! + \qmlproperty string QtQuick.Controls::Action::icon.name + \qmlproperty url QtQuick.Controls::Action::icon.source + \qmlproperty int QtQuick.Controls::Action::icon.width + \qmlproperty int QtQuick.Controls::Action::icon.height + \qmlproperty color QtQuick.Controls::Action::icon.color + \qmlproperty bool QtQuick.Controls::Action::icon.cache + + \include qquickicon.qdocinc grouped-properties +*/ +QQuickIcon QQuickAction::icon() const +{ + Q_D(const QQuickAction); + return d->icon; +} + +void QQuickAction::setIcon(const QQuickIcon &icon) +{ + Q_D(QQuickAction); + if (d->icon == icon) + return; + + d->icon = icon; + d->icon.ensureRelativeSourceResolved(this); + emit iconChanged(icon); +} + +/*! + \qmlproperty bool QtQuick.Controls::Action::enabled + + This property holds whether the action is enabled. The default value is \c true. +*/ +bool QQuickAction::isEnabled() const +{ + Q_D(const QQuickAction); + return d->enabled && (!d->group || d->group->isEnabled()); +} + +void QQuickAction::setEnabled(bool enabled) +{ + Q_D(QQuickAction); + d->explicitEnabled = true; + d->setEnabled(enabled); +} + +void QQuickAction::resetEnabled() +{ + Q_D(QQuickAction); + if (!d->explicitEnabled) + return; + + d->explicitEnabled = false; + d->setEnabled(true); +} + +/*! + \qmlproperty bool QtQuick.Controls::Action::checked + + This property holds whether the action is checked. + + \sa checkable +*/ +bool QQuickAction::isChecked() const +{ + Q_D(const QQuickAction); + return d->checked; +} + +void QQuickAction::setChecked(bool checked) +{ + Q_D(QQuickAction); + if (d->checked == checked) + return; + + d->checked = checked; + emit checkedChanged(checked); +} + +/*! + \qmlproperty bool QtQuick.Controls::Action::checkable + + This property holds whether the action is checkable. The default value is \c false. + + A checkable action toggles between checked (on) and unchecked (off) when triggered. + + \sa checked +*/ +bool QQuickAction::isCheckable() const +{ + Q_D(const QQuickAction); + return d->checkable; +} + +void QQuickAction::setCheckable(bool checkable) +{ + Q_D(QQuickAction); + if (d->checkable == checkable) + return; + + d->checkable = checkable; + emit checkableChanged(checkable); +} + +#if QT_CONFIG(shortcut) +/*! + \qmlproperty keysequence QtQuick.Controls::Action::shortcut + + This property holds the action's shortcut. The key sequence can be set + to one of the \l{QKeySequence::StandardKey}{standard keyboard shortcuts}, + or it can be described with a string containing a sequence of up to four + key presses that are needed to trigger the shortcut. + + \code + Action { + shortcut: "Ctrl+E,Ctrl+W" + onTriggered: edit.wrapMode = TextEdit.Wrap + } + \endcode +*/ +QKeySequence QQuickAction::shortcut() const +{ + Q_D(const QQuickAction); + return d->keySequence; +} + +void QQuickAction::setShortcut(const QKeySequence &shortcut) +{ + Q_D(QQuickAction); + d->setShortcut(shortcut.toString()); +} +#endif // QT_CONFIG(shortcut) + +/*! + \qmlmethod void QtQuick.Controls::Action::toggle(QtObject source) + + Toggles the action and emits \l toggled() if enabled, with an optional \a source object defined. +*/ +void QQuickAction::toggle(QObject *source) +{ + Q_D(QQuickAction); + if (!d->enabled) + return; + + if (d->checkable) + setChecked(!d->checked); + + emit toggled(source); +} + +/*! + \qmlmethod void QtQuick.Controls::Action::trigger(QtObject source) + + Triggers the action and emits \l triggered() if enabled, with an optional \a source object defined. +*/ +void QQuickAction::trigger(QObject *source) +{ + Q_D(QQuickAction); + d->trigger(source, true); +} + +void QQuickActionPrivate::trigger(QObject* source, bool doToggle) +{ + Q_Q(QQuickAction); + if (!enabled) + return; + + QPointer<QObject> guard = q; + // the checked action of an exclusive group cannot be unchecked + if (checkable && (!checked || !group || !group->isExclusive() || group->checkedAction() != q)) { + if (doToggle) + q->toggle(source); + else + emit q->toggled(source); + } + + if (!guard.isNull()) + emit q->triggered(source); +} + +bool QQuickAction::event(QEvent *event) +{ +#if QT_CONFIG(shortcut) + Q_D(QQuickAction); + if (event->type() == QEvent::Shortcut) + return d->handleShortcutEvent(this, static_cast<QShortcutEvent *>(event)); +#endif + return QObject::event(event); +} + +bool QQuickAction::eventFilter(QObject *object, QEvent *event) +{ +#if QT_CONFIG(shortcut) + Q_D(QQuickAction); + if (event->type() == QEvent::Shortcut) + return d->handleShortcutEvent(object, static_cast<QShortcutEvent *>(event)); +#else + Q_UNUSED(object); + Q_UNUSED(event); +#endif + return false; +} + +QT_END_NAMESPACE + +#include "moc_qquickaction_p.cpp" diff --git a/src/quicktemplates2/qquickaction_p.h b/src/quicktemplates2/qquickaction_p.h new file mode 100644 index 00000000000..f600d89ed7e --- /dev/null +++ b/src/quicktemplates2/qquickaction_p.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKACTION_P_H +#define QQUICKACTION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> +#include <QtQuickTemplates2/private/qquickicon_p.h> +#include <QtCore/qobject.h> +#include <QtQml/qqml.h> + +QT_BEGIN_NAMESPACE + +class QQuickIcon; +class QQuickActionPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickAction : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged FINAL) + Q_PROPERTY(QQuickIcon icon READ icon WRITE setIcon NOTIFY iconChanged FINAL) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged RESET resetEnabled FINAL) + Q_PROPERTY(bool checked READ isChecked WRITE setChecked NOTIFY checkedChanged FINAL) + Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable NOTIFY checkableChanged FINAL) +#if QT_CONFIG(shortcut) + Q_PRIVATE_PROPERTY(QQuickAction::d_func(), QVariant shortcut READ shortcut WRITE setShortcut NOTIFY shortcutChanged FINAL) +#endif + QML_NAMED_ELEMENT(Action) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickAction(QObject *parent = nullptr); + ~QQuickAction(); + + QString text() const; + void setText(const QString &text); + + QQuickIcon icon() const; + void setIcon(const QQuickIcon &icon); + + bool isEnabled() const; + void setEnabled(bool enabled); + void resetEnabled(); + + bool isChecked() const; + void setChecked(bool checked); + + bool isCheckable() const; + void setCheckable(bool checkable); + +#if QT_CONFIG(shortcut) + QKeySequence shortcut() const; + void setShortcut(const QKeySequence &shortcut); +#endif + +public Q_SLOTS: + void toggle(QObject *source = nullptr); + void trigger(QObject *source = nullptr); + +Q_SIGNALS: + void textChanged(const QString &text); + void iconChanged(const QQuickIcon &icon); + void enabledChanged(bool enabled); + void checkedChanged(bool checked); + void checkableChanged(bool checkable); +#if QT_CONFIG(shortcut) + void shortcutChanged(const QKeySequence &shortcut); +#endif + + void toggled(QObject *source = nullptr); + void triggered(QObject *source = nullptr); + +protected: + bool event(QEvent *event) override; + bool eventFilter(QObject *object, QEvent *event) override; + +private: + Q_DISABLE_COPY(QQuickAction) + Q_DECLARE_PRIVATE(QQuickAction) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickAction) + +#endif // QQUICKACTION_P_H diff --git a/src/quicktemplates2/qquickaction_p_p.h b/src/quicktemplates2/qquickaction_p_p.h new file mode 100644 index 00000000000..d9b83548c98 --- /dev/null +++ b/src/quicktemplates2/qquickaction_p_p.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKACTION_P_P_H +#define QQUICKACTION_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/private/qobject_p.h> +#include <QtCore/qvariant.h> +#include <QtCore/qstring.h> +#if QT_CONFIG(shortcut) +# include <QtGui/qkeysequence.h> +#endif +#include <QtQuick/private/qquickitemchangelistener_p.h> + +QT_BEGIN_NAMESPACE + +class QShortcutEvent; +class QQuickActionGroup; + +class QQuickActionPrivate : public QObjectPrivate, public QQuickItemChangeListener +{ + Q_DECLARE_PUBLIC(QQuickAction) + +public: + static QQuickActionPrivate *get(QQuickAction *action) + { + return action->d_func(); + } + +#if QT_CONFIG(shortcut) + QVariant shortcut() const; + void setShortcut(const QVariant &shortcut); +#endif + + void setEnabled(bool enable); + + bool watchItem(QQuickItem *item); + bool unwatchItem(QQuickItem *item); + + void registerItem(QQuickItem *item); + void unregisterItem(QQuickItem *item); + + void itemVisibilityChanged(QQuickItem *item) override; + void itemDestroyed(QQuickItem *item) override; + + bool handleShortcutEvent(QObject *object, QShortcutEvent *event); + + void trigger(QObject*, bool doToggle); + +#if QT_CONFIG(shortcut) + class ShortcutEntry + { + public: + explicit ShortcutEntry(QObject *target); + ~ShortcutEntry(); + + QObject *target() const; + int shortcutId() const; + + void grab(const QKeySequence &vshortcut, bool enabled); + void ungrab(); + + void setEnabled(bool enabled); + + private: + int m_shortcutId = 0; + QObject *m_target = nullptr; + }; + + ShortcutEntry *findShortcutEntry(QObject *target) const; + void updateDefaultShortcutEntry(); +#endif // QT_CONFIG(shortcut) + + bool explicitEnabled = false; + bool enabled = true; + bool checked = false; + bool checkable = false; + QString text; + QQuickIcon icon; +#if QT_CONFIG(shortcut) + QKeySequence keySequence; + QVariant vshortcut; + ShortcutEntry *defaultShortcutEntry = nullptr; + QList<ShortcutEntry *> shortcutEntries; +#endif + QQuickActionGroup *group = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKACTION_P_P_H diff --git a/src/quicktemplates2/qquickactiongroup.cpp b/src/quicktemplates2/qquickactiongroup.cpp new file mode 100644 index 00000000000..1656ecf51e5 --- /dev/null +++ b/src/quicktemplates2/qquickactiongroup.cpp @@ -0,0 +1,471 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickactiongroup_p.h" + +#include <QtCore/private/qobject_p.h> +#include <QtCore/qmetaobject.h> +#include <QtCore/qvariant.h> +#include <QtQml/qqmlinfo.h> + +#include "qquickaction_p.h" +#include "qquickaction_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ActionGroup + \inherits QtObject +//! \instantiates QQuickActionGroup + \inqmlmodule QtQuick.Controls + \since 5.10 + \ingroup utilities + \brief Groups actions together. + + ActionGroup is a non-visual group of actions. A mutually \l exclusive + action group is used with actions where only one of the options can be + selected at a time. + + The most straight-forward way to use ActionGroup is to declare actions + as children of the group. + + \code + ActionGroup { + id: alignmentGroup + + Action { + checked: true + checkable: true + text: qsTr("Left") + } + + Action { + checkable: true + text: qsTr("Center") + } + + Action { + checkable: true + text: qsTr("Right") + } + } + \endcode + + Alternatively, the \l group attached property allows declaring the actions + elsewhere and assigning them to a specific group. + + \code + ActionGroup { id: alignmentGroup } + + Action { + checked: true + checkable: true + text: qsTr("Left") + ActionGroup.group: alignmentGroup + } + + Action { + checkable: true + text: qsTr("Center") + ActionGroup.group: alignmentGroup + } + + Action { + checkable: true + text: qsTr("Right") + ActionGroup.group: alignmentGroup + } + \endcode + + More advanced use cases can be handled using the \c addAction() and + \c removeAction() methods. + + \sa Action, ButtonGroup +*/ + +/*! + \qmlsignal QtQuick.Controls::ActionGroup::triggered(Action action) + + This signal is emitted when an \a action in the group has been triggered. + + This signal is convenient for implementing a common signal handler for + all actions in the same group. + + \code + ActionGroup { + onTriggered: console.log("triggered:", action.text) + + Action { text: "First" } + Action { text: "Second" } + Action { text: "Third" } + } + \endcode + + \sa Action::triggered() +*/ + +class QQuickActionGroupPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickActionGroup) + +public: + void clear(); + void actionTriggered(); + void _q_updateCurrent(); + + static bool changeEnabled(QQuickAction *action, bool enabled); + + static void actions_append(QQmlListProperty<QQuickAction> *prop, QQuickAction *obj); + static qsizetype actions_count(QQmlListProperty<QQuickAction> *prop); + static QQuickAction *actions_at(QQmlListProperty<QQuickAction> *prop, qsizetype index); + static void actions_clear(QQmlListProperty<QQuickAction> *prop); + + bool enabled = true; + bool exclusive = true; + QPointer<QQuickAction> checkedAction; + QList<QQuickAction*> actions; +}; + +void QQuickActionGroupPrivate::clear() +{ + for (QQuickAction *action : qAsConst(actions)) { + QQuickActionPrivate::get(action)->group = nullptr; + QObjectPrivate::disconnect(action, &QQuickAction::triggered, this, &QQuickActionGroupPrivate::actionTriggered); + QObjectPrivate::disconnect(action, &QQuickAction::checkedChanged, this, &QQuickActionGroupPrivate::_q_updateCurrent); + } + actions.clear(); +} + +void QQuickActionGroupPrivate::actionTriggered() +{ + Q_Q(QQuickActionGroup); + QQuickAction *action = qobject_cast<QQuickAction*>(q->sender()); + if (action) + emit q->triggered(action); +} + +void QQuickActionGroupPrivate::_q_updateCurrent() +{ + Q_Q(QQuickActionGroup); + if (!exclusive) + return; + QQuickAction *action = qobject_cast<QQuickAction*>(q->sender()); + if (action && action->isChecked()) + q->setCheckedAction(action); + else if (!actions.contains(checkedAction)) + q->setCheckedAction(nullptr); +} + +bool QQuickActionGroupPrivate::changeEnabled(QQuickAction *action, bool enabled) +{ + return action->isEnabled() != enabled && (!enabled || !QQuickActionPrivate::get(action)->explicitEnabled); +} + +void QQuickActionGroupPrivate::actions_append(QQmlListProperty<QQuickAction> *prop, QQuickAction *obj) +{ + QQuickActionGroup *q = static_cast<QQuickActionGroup *>(prop->object); + q->addAction(obj); +} + +qsizetype QQuickActionGroupPrivate::actions_count(QQmlListProperty<QQuickAction> *prop) +{ + QQuickActionGroupPrivate *p = static_cast<QQuickActionGroupPrivate *>(prop->data); + return p->actions.count(); +} + +QQuickAction *QQuickActionGroupPrivate::actions_at(QQmlListProperty<QQuickAction> *prop, qsizetype index) +{ + QQuickActionGroupPrivate *p = static_cast<QQuickActionGroupPrivate *>(prop->data); + return p->actions.value(index); +} + +void QQuickActionGroupPrivate::actions_clear(QQmlListProperty<QQuickAction> *prop) +{ + QQuickActionGroupPrivate *p = static_cast<QQuickActionGroupPrivate *>(prop->data); + if (!p->actions.isEmpty()) { + p->clear(); + QQuickActionGroup *q = static_cast<QQuickActionGroup *>(prop->object); + // QTBUG-52358: don't clear the checked action immediately + QMetaObject::invokeMethod(q, "_q_updateCurrent", Qt::QueuedConnection); + emit q->actionsChanged(); + } +} + +QQuickActionGroup::QQuickActionGroup(QObject *parent) + : QObject(*(new QQuickActionGroupPrivate), parent) +{ +} + +QQuickActionGroup::~QQuickActionGroup() +{ + Q_D(QQuickActionGroup); + d->clear(); +} + +QQuickActionGroupAttached *QQuickActionGroup::qmlAttachedProperties(QObject *object) +{ + return new QQuickActionGroupAttached(object); +} + +/*! + \qmlproperty Action QtQuick.Controls::ActionGroup::checkedAction + + This property holds the currently selected action in an exclusive group, + or \c null if there is none or the group is non-exclusive. + + By default, it is the first checked action added to an exclusive action group. + + \sa exclusive +*/ +QQuickAction *QQuickActionGroup::checkedAction() const +{ + Q_D(const QQuickActionGroup); + return d->checkedAction; +} + +void QQuickActionGroup::setCheckedAction(QQuickAction *checkedAction) +{ + Q_D(QQuickActionGroup); + if (d->checkedAction == checkedAction) + return; + + if (d->checkedAction) + d->checkedAction->setChecked(false); + d->checkedAction = checkedAction; + if (checkedAction) + checkedAction->setChecked(true); + emit checkedActionChanged(); +} + +/*! + \qmlproperty list<Action> QtQuick.Controls::ActionGroup::actions + \qmldefault + + This property holds the list of actions in the group. + + \sa group +*/ +QQmlListProperty<QQuickAction> QQuickActionGroup::actions() +{ + Q_D(QQuickActionGroup); + return QQmlListProperty<QQuickAction>(this, d, + QQuickActionGroupPrivate::actions_append, + QQuickActionGroupPrivate::actions_count, + QQuickActionGroupPrivate::actions_at, + QQuickActionGroupPrivate::actions_clear); +} + +/*! + \qmlproperty bool QtQuick.Controls::ActionGroup::exclusive + + This property holds whether the action group is exclusive. The default value is \c true. + + If this property is \c true, then only one action in the group can be checked at any given time. + The user can trigger any action to check it, and that action will replace the existing one as + the checked action in the group. + + In an exclusive group, the user cannot uncheck the currently checked action by triggering it; + instead, another action in the group must be triggered to set the new checked action for that + group. + + In a non-exclusive group, checking and unchecking actions does not affect the other actions in + the group. Furthermore, the value of the \l checkedAction property is \c null. +*/ +bool QQuickActionGroup::isExclusive() const +{ + Q_D(const QQuickActionGroup); + return d->exclusive; +} + +void QQuickActionGroup::setExclusive(bool exclusive) +{ + Q_D(QQuickActionGroup); + if (d->exclusive == exclusive) + return; + + d->exclusive = exclusive; + emit exclusiveChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::ActionGroup::enabled + + This property holds whether the action group is enabled. The default value is \c true. + + If this property is \c false, then all actions in the group are disabled. If this property + is \c true, all actions in the group are enabled, unless explicitly disabled. +*/ +bool QQuickActionGroup::isEnabled() const +{ + Q_D(const QQuickActionGroup); + return d->enabled; +} + +void QQuickActionGroup::setEnabled(bool enabled) +{ + Q_D(QQuickActionGroup); + if (d->enabled == enabled) + return; + + for (QQuickAction *action : qAsConst(d->actions)) { + if (d->changeEnabled(action, enabled)) + emit action->enabledChanged(enabled); + } + + d->enabled = enabled; + emit enabledChanged(); +} + +/*! + \qmlmethod void QtQuick.Controls::ActionGroup::addAction(Action action) + + Adds an \a action to the action group. + + \note Manually adding objects to a action group is typically unnecessary. + The \l actions property and the \l group attached property provide a + convenient and declarative syntax. + + \sa actions, group +*/ +void QQuickActionGroup::addAction(QQuickAction *action) +{ + Q_D(QQuickActionGroup); + if (!action || d->actions.contains(action)) + return; + + const bool enabledChange = d->changeEnabled(action, d->enabled); + + QQuickActionPrivate::get(action)->group = this; + QObjectPrivate::connect(action, &QQuickAction::triggered, d, &QQuickActionGroupPrivate::actionTriggered); + QObjectPrivate::connect(action, &QQuickAction::checkedChanged, d, &QQuickActionGroupPrivate::_q_updateCurrent); + + if (d->exclusive && action->isChecked()) + setCheckedAction(action); + if (enabledChange) + emit action->enabledChanged(action->isEnabled()); + + d->actions.append(action); + emit actionsChanged(); +} + +/*! + \qmlmethod void QtQuick.Controls::ActionGroup::removeAction(Action action) + + Removes an \a action from the action group. + + \note Manually removing objects from a action group is typically unnecessary. + The \l actions property and the \l group attached property provide a + convenient and declarative syntax. + + \sa actions, group +*/ +void QQuickActionGroup::removeAction(QQuickAction *action) +{ + Q_D(QQuickActionGroup); + if (!action || !d->actions.contains(action)) + return; + + const bool enabledChange = d->changeEnabled(action, d->enabled); + + QQuickActionPrivate::get(action)->group = nullptr; + QObjectPrivate::disconnect(action, &QQuickAction::triggered, d, &QQuickActionGroupPrivate::actionTriggered); + QObjectPrivate::disconnect(action, &QQuickAction::checkedChanged, d, &QQuickActionGroupPrivate::_q_updateCurrent); + + if (d->checkedAction == action) + setCheckedAction(nullptr); + if (enabledChange) + emit action->enabledChanged(action->isEnabled()); + + d->actions.removeOne(action); + emit actionsChanged(); +} + +class QQuickActionGroupAttachedPrivate : public QObjectPrivate +{ +public: + QQuickActionGroup *group = nullptr; +}; + +QQuickActionGroupAttached::QQuickActionGroupAttached(QObject *parent) + : QObject(*(new QQuickActionGroupAttachedPrivate), parent) +{ +} + +/*! + \qmlattachedproperty ActionGroup QtQuick.Controls::ActionGroup::group + + This property attaches an action to an action group. + + \code + ActionGroup { id: group } + + Action { + checked: true + text: qsTr("Option A") + ActionGroup.group: group + } + + Action { + text: qsTr("Option B") + ActionGroup.group: group + } + \endcode + + \sa actions +*/ +QQuickActionGroup *QQuickActionGroupAttached::group() const +{ + Q_D(const QQuickActionGroupAttached); + return d->group; +} + +void QQuickActionGroupAttached::setGroup(QQuickActionGroup *group) +{ + Q_D(QQuickActionGroupAttached); + if (d->group == group) + return; + + if (d->group) + d->group->removeAction(qobject_cast<QQuickAction*>(parent())); + d->group = group; + if (group) + group->addAction(qobject_cast<QQuickAction*>(parent())); + emit groupChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qquickactiongroup_p.cpp" diff --git a/src/quicktemplates2/qquickactiongroup_p.h b/src/quicktemplates2/qquickactiongroup_p.h new file mode 100644 index 00000000000..d905f59598e --- /dev/null +++ b/src/quicktemplates2/qquickactiongroup_p.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKACTIONGROUP_P_H +#define QQUICKACTIONGROUP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> +#include <QtQml/qqml.h> + +QT_BEGIN_NAMESPACE + +class QQuickAction; +class QQuickActionGroupPrivate; +class QQuickActionGroupAttached; +class QQuickActionGroupAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickActionGroup : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickAction *checkedAction READ checkedAction WRITE setCheckedAction NOTIFY checkedActionChanged FINAL) + Q_PROPERTY(QQmlListProperty<QQuickAction> actions READ actions NOTIFY actionsChanged FINAL) + Q_PROPERTY(bool exclusive READ isExclusive WRITE setExclusive NOTIFY exclusiveChanged FINAL) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL) + Q_CLASSINFO("DefaultProperty", "actions") + QML_NAMED_ELEMENT(ActionGroup) + QML_ATTACHED(QQuickActionGroupAttached) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickActionGroup(QObject *parent = nullptr); + ~QQuickActionGroup(); + + static QQuickActionGroupAttached *qmlAttachedProperties(QObject *object); + + QQuickAction *checkedAction() const; + void setCheckedAction(QQuickAction *checkedAction); + + QQmlListProperty<QQuickAction> actions(); + + bool isExclusive() const; + void setExclusive(bool exclusive); + + bool isEnabled() const; + void setEnabled(bool enabled); + +public Q_SLOTS: + void addAction(QQuickAction *action); + void removeAction(QQuickAction *action); + +Q_SIGNALS: + void checkedActionChanged(); + void actionsChanged(); + void exclusiveChanged(); + void enabledChanged(); + void triggered(QQuickAction *action); + +private: + Q_DISABLE_COPY(QQuickActionGroup) + Q_DECLARE_PRIVATE(QQuickActionGroup) + + Q_PRIVATE_SLOT(d_func(), void _q_updateCurrent()) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickActionGroupAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickActionGroup *group READ group WRITE setGroup NOTIFY groupChanged FINAL) + +public: + explicit QQuickActionGroupAttached(QObject *parent = nullptr); + + QQuickActionGroup *group() const; + void setGroup(QQuickActionGroup *group); + +Q_SIGNALS: + void groupChanged(); + +private: + Q_DISABLE_COPY(QQuickActionGroupAttached) + Q_DECLARE_PRIVATE(QQuickActionGroupAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickActionGroup) +QML_DECLARE_TYPEINFO(QQuickActionGroup, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKACTIONGROUP_P_H diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp new file mode 100644 index 00000000000..eb1d12c930f --- /dev/null +++ b/src/quicktemplates2/qquickapplicationwindow.cpp @@ -0,0 +1,955 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickapplicationwindow_p.h" +#include "qquickcontentitem_p.h" +#include "qquickpopup_p_p.h" +#include "qquickcontrol_p_p.h" +#include "qquicktextarea_p.h" +#include "qquicktextfield_p.h" +#include "qquicktoolbar_p.h" +#include "qquicktabbar_p.h" +#include "qquickdialogbuttonbox_p.h" +#include "qquickdeferredexecute_p_p.h" +#include "qquickdeferredpointer_p_p.h" + +#include <QtCore/private/qobject_p.h> +#include <QtCore/qscopedvaluerollback.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQuick/private/qquickwindowmodule_p_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ApplicationWindow + \inherits Window +//! \instantiates QQuickApplicationWindow + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes + \brief Styled top-level window with support for a header and footer. + + ApplicationWindow is a \l Window which makes it convenient to add + a \l {menuBar}{menu bar}, \l header and \l footer item to the window. + + You can declare ApplicationWindow as the root item of your application, + and run it by using \l QQmlApplicationEngine. In this way you can control + the window's properties, appearance and layout from QML. + + \image qtquickcontrols2-applicationwindow-wireframe.png + + \qml + import QtQuick.Controls 2.12 + + ApplicationWindow { + visible: true + + menuBar: MenuBar { + // ... + } + + header: ToolBar { + // ... + } + + footer: TabBar { + // ... + } + + StackView { + anchors.fill: parent + } + } + \endqml + + \note By default, an ApplicationWindow is not visible. + + \section2 Attached ApplicationWindow Properties + + Due to how \l {Scope and Naming Resolution} works in QML, it is possible + to reference the \c id of the application root element anywhere in its + child QML objects. Even though this approach is fine for many applications + and use cases, for a generic QML component it may not be acceptable as it + creates a dependency to the surrounding environment. + + ApplicationWindow provides a set of attached properties that can be used + to access the window and its building blocks from places where no direct + access to the window is available, without creating a dependency to a + certain window \c id. A QML component that uses the ApplicationWindow + attached properties works in any window regardless of its \c id. + + \sa {Customizing ApplicationWindow}, Overlay, Page, {Container Controls}, + {Focus Management in Qt Quick Controls} +*/ + +static const QQuickItemPrivate::ChangeTypes ItemChanges = QQuickItemPrivate::Visibility + | QQuickItemPrivate::Geometry | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickApplicationWindowPrivate + : public QQuickWindowQmlImplPrivate + , public QQuickItemChangeListener +{ + Q_DECLARE_PUBLIC(QQuickApplicationWindow) + +public: + QQuickApplicationWindowPrivate() + { + complete = true; + } + + static QQuickApplicationWindowPrivate *get(QQuickApplicationWindow *window) + { + return window->d_func(); + } + + QQmlListProperty<QObject> contentData(); + + void relayout(); + + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + void itemVisibilityChanged(QQuickItem *item) override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + void updateFont(const QFont &f); + inline void setFont_helper(const QFont &f) { + if (font.resolveMask() == f.resolveMask() && font == f) + return; + updateFont(f); + } + void resolveFont(); + + void _q_updateActiveFocus(); + void setActiveFocusControl(QQuickItem *item); + + static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj); + + void cancelBackground(); + void executeBackground(bool complete = false); + + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::System); } + void updateChildrenPalettes(const QPalette &parentPalette) override + { + // Update regular children + QQuickWindowPrivate::updateChildrenPalettes(parentPalette); + + // And cover one special case + for (auto &&popup : q_func()->findChildren<QQuickPopup *>()) + QQuickPopupPrivate::get(popup)->inheritPalette(parentPalette); + } + + QQuickDeferredPointer<QQuickItem> background; + QQuickItem *appWindowContentItem = nullptr; + QQuickItem *menuBar = nullptr; + QQuickItem *header = nullptr; + QQuickItem *footer = nullptr; + QFont font; + QLocale locale; + QQuickItem *activeFocusControl = nullptr; + bool insideRelayout = false; +}; + +static void layoutItem(QQuickItem *item, qreal y, qreal width) +{ + if (!item) + return; + + item->setY(y); + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + if (!p->widthValid()) { + item->setWidth(width); + p->widthValidFlag = false; + } +} + +void QQuickApplicationWindowPrivate::relayout() +{ + Q_Q(QQuickApplicationWindow); + if (!complete || insideRelayout) + return; + + QScopedValueRollback<bool> guard(insideRelayout, true); + QQuickItem *content = q->contentItem(); + qreal hh = header && header->isVisible() ? header->height() : 0; + qreal fh = footer && footer->isVisible() ? footer->height() : 0; + qreal mbh = menuBar && menuBar->isVisible() ? menuBar->height() : 0; + + content->setY(mbh + hh); + content->setWidth(q->width()); + content->setHeight(q->height() - mbh - hh - fh); + + layoutItem(menuBar, -mbh - hh, q->width()); + layoutItem(header, -hh, q->width()); + layoutItem(footer, content->height(), q->width()); + + if (background) { + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + if (!p->widthValid() && qFuzzyIsNull(background->x())) { + background->setWidth(q->width()); + p->widthValidFlag = false; + } + if (!p->heightValid() && qFuzzyIsNull(background->y())) { + background->setHeight(q->height()); + p->heightValidFlag = false; + } + } +} + +void QQuickApplicationWindowPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) +{ + Q_UNUSED(item); + Q_UNUSED(change); + Q_UNUSED(diff); + relayout(); +} + +void QQuickApplicationWindowPrivate::itemVisibilityChanged(QQuickItem *item) +{ + Q_UNUSED(item); + relayout(); +} + +void QQuickApplicationWindowPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_UNUSED(item); + relayout(); +} + +void QQuickApplicationWindowPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_UNUSED(item); + relayout(); +} + +void QQuickApplicationWindowPrivate::updateFont(const QFont &f) +{ + Q_Q(QQuickApplicationWindow); + const bool changed = font != f; + font = f; + + QQuickControlPrivate::updateFontRecur(q->QQuickWindow::contentItem(), f); + + const QList<QQuickPopup *> popups = q->findChildren<QQuickPopup *>(); + for (QQuickPopup *popup : popups) + QQuickControlPrivate::get(static_cast<QQuickControl *>(popup->popupItem()))->inheritFont(f); + + if (changed) + emit q->fontChanged(); +} + +void QQuickApplicationWindowPrivate::resolveFont() +{ + QFont resolvedFont = font.resolve(QQuickTheme::font(QQuickTheme::System)); + setFont_helper(resolvedFont); +} + +static QQuickItem *findActiveFocusControl(QQuickWindow *window) +{ + QQuickItem *item = window->activeFocusItem(); + while (item) { + if (qobject_cast<QQuickControl *>(item) || qobject_cast<QQuickTextField *>(item) || qobject_cast<QQuickTextArea *>(item)) + return item; + item = item->parentItem(); + } + return item; +} + +void QQuickApplicationWindowPrivate::_q_updateActiveFocus() +{ + Q_Q(QQuickApplicationWindow); + setActiveFocusControl(findActiveFocusControl(q)); +} + +void QQuickApplicationWindowPrivate::setActiveFocusControl(QQuickItem *control) +{ + Q_Q(QQuickApplicationWindow); + if (activeFocusControl != control) { + activeFocusControl = control; + emit q->activeFocusControlChanged(); + } +} + +void QQuickApplicationWindowPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj) +{ + QQuickItemPrivate::data_append(prop, obj); + + // associate "top-level" popups with the window as soon as they are added to the default property + if (QQuickPopup *popup = qobject_cast<QQuickPopup *>(obj)) + QQuickPopupPrivate::get(popup)->setWindow(static_cast<QQuickApplicationWindow *>(prop->data)); +} + +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickApplicationWindowPrivate::cancelBackground() +{ + Q_Q(QQuickApplicationWindow); + quickCancelDeferred(q, backgroundName()); +} + +void QQuickApplicationWindowPrivate::executeBackground(bool complete) +{ + Q_Q(QQuickApplicationWindow); + if (background.wasExecuted()) + return; + + if (!background || complete) + quickBeginDeferred(q, backgroundName(), background); + if (complete) + quickCompleteDeferred(q, backgroundName(), background); +} + +QQuickApplicationWindow::QQuickApplicationWindow(QWindow *parent) + : QQuickWindowQmlImpl(*(new QQuickApplicationWindowPrivate), parent) +{ + connect(this, SIGNAL(activeFocusItemChanged()), this, SLOT(_q_updateActiveFocus())); +} + +QQuickApplicationWindow::~QQuickApplicationWindow() +{ + Q_D(QQuickApplicationWindow); + d->setActiveFocusControl(nullptr); + disconnect(this, SIGNAL(activeFocusItemChanged()), this, SLOT(_q_updateActiveFocus())); + if (d->menuBar) + QQuickItemPrivate::get(d->menuBar)->removeItemChangeListener(d, ItemChanges); + if (d->header) + QQuickItemPrivate::get(d->header)->removeItemChangeListener(d, ItemChanges); + if (d->footer) + QQuickItemPrivate::get(d->footer)->removeItemChangeListener(d, ItemChanges); +} + +QQuickApplicationWindowAttached *QQuickApplicationWindow::qmlAttachedProperties(QObject *object) +{ + return new QQuickApplicationWindowAttached(object); +} + +/*! + \qmlproperty Item QtQuick.Controls::ApplicationWindow::background + + This property holds the background item. + + The background item is stacked under the \l {contentItem}{content item}, + but above the \l {Window::color}{background color} of the window. + + The background item is useful for images and gradients, for example, + but the \l {Window::}{color} property is preferable for solid colors, + as it doesn't need to create an item. + + \note If the background item has no explicit size specified, it automatically + follows the control's size. In most cases, there is no need to specify + width or height for a background item. + + \sa {Customizing ApplicationWindow}, contentItem, header, footer +*/ +QQuickItem *QQuickApplicationWindow::background() const +{ + QQuickApplicationWindowPrivate *d = const_cast<QQuickApplicationWindowPrivate *>(d_func()); + if (!d->background) + d->executeBackground(); + return d->background; +} + +void QQuickApplicationWindow::setBackground(QQuickItem *background) +{ + Q_D(QQuickApplicationWindow); + if (d->background == background) + return; + + if (!d->background.isExecuting()) + d->cancelBackground(); + + QQuickControlPrivate::hideOldItem(d->background); + d->background = background; + if (background) { + background->setParentItem(QQuickWindow::contentItem()); + if (qFuzzyIsNull(background->z())) + background->setZ(-1); + if (isComponentComplete()) + d->relayout(); + } + if (!d->background.isExecuting()) + emit backgroundChanged(); +} + +/*! + \qmlproperty Item QtQuick.Controls::ApplicationWindow::header + + This property holds the window header item. The header item is positioned at the + top of the window, below the menu bar, and resized to the width of the window. + The default value is \c null. + + \code + ApplicationWindow { + header: TabBar { + // ... + } + } + \endcode + + \note Assigning a ToolBar, TabBar, or DialogButtonBox as a window header + automatically sets the respective \l ToolBar::position, \l TabBar::position, + or \l DialogButtonBox::position property to \c Header. + + \sa menuBar, footer, Page::header +*/ +QQuickItem *QQuickApplicationWindow::header() const +{ + Q_D(const QQuickApplicationWindow); + return d->header; +} + +void QQuickApplicationWindow::setHeader(QQuickItem *header) +{ + Q_D(QQuickApplicationWindow); + if (d->header == header) + return; + + if (d->header) { + QQuickItemPrivate::get(d->header)->removeItemChangeListener(d, ItemChanges); + d->header->setParentItem(nullptr); + } + d->header = header; + if (header) { + header->setParentItem(contentItem()); + QQuickItemPrivate *p = QQuickItemPrivate::get(header); + p->addItemChangeListener(d, ItemChanges); + if (qFuzzyIsNull(header->z())) + header->setZ(1); + if (QQuickToolBar *toolBar = qobject_cast<QQuickToolBar *>(header)) + toolBar->setPosition(QQuickToolBar::Header); + else if (QQuickTabBar *tabBar = qobject_cast<QQuickTabBar *>(header)) + tabBar->setPosition(QQuickTabBar::Header); + else if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(header)) + buttonBox->setPosition(QQuickDialogButtonBox::Header); + } + if (isComponentComplete()) + d->relayout(); + emit headerChanged(); +} + +/*! + \qmlproperty Item QtQuick.Controls::ApplicationWindow::footer + + This property holds the window footer item. The footer item is positioned to + the bottom, and resized to the width of the window. The default value is \c null. + + \code + ApplicationWindow { + footer: ToolBar { + // ... + } + } + \endcode + + \note Assigning a ToolBar, TabBar, or DialogButtonBox as a window footer + automatically sets the respective \l ToolBar::position, \l TabBar::position, + or \l DialogButtonBox::position property to \c Footer. + + \sa menuBar, header, Page::footer +*/ +QQuickItem *QQuickApplicationWindow::footer() const +{ + Q_D(const QQuickApplicationWindow); + return d->footer; +} + +void QQuickApplicationWindow::setFooter(QQuickItem *footer) +{ + Q_D(QQuickApplicationWindow); + if (d->footer == footer) + return; + + if (d->footer) { + QQuickItemPrivate::get(d->footer)->removeItemChangeListener(d, ItemChanges); + d->footer->setParentItem(nullptr); + } + d->footer = footer; + if (footer) { + footer->setParentItem(contentItem()); + QQuickItemPrivate *p = QQuickItemPrivate::get(footer); + p->addItemChangeListener(d, ItemChanges); + if (qFuzzyIsNull(footer->z())) + footer->setZ(1); + if (QQuickToolBar *toolBar = qobject_cast<QQuickToolBar *>(footer)) + toolBar->setPosition(QQuickToolBar::Footer); + else if (QQuickTabBar *tabBar = qobject_cast<QQuickTabBar *>(footer)) + tabBar->setPosition(QQuickTabBar::Footer); + else if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(footer)) + buttonBox->setPosition(QQuickDialogButtonBox::Footer); + } + if (isComponentComplete()) + d->relayout(); + emit footerChanged(); +} + +/*! + \qmlproperty list<Object> QtQuick.Controls::ApplicationWindow::contentData + \qmldefault + + This default property holds the list of all objects declared as children of + the window. + + The data property allows you to freely mix visual children, resources and + other windows in an ApplicationWindow. + + If you assign an Item to the contentData list, it becomes a child of the + window's contentItem, so that it appears inside the window. The item's + parent will be the window's \l contentItem. + + It should not generally be necessary to refer to the contentData property, + as it is the default property for ApplicationWindow and thus all child + items are automatically assigned to this property. + + \sa contentItem +*/ +QQmlListProperty<QObject> QQuickApplicationWindowPrivate::contentData() +{ + Q_Q(QQuickApplicationWindow); + return QQmlListProperty<QObject>(q->contentItem(), q, + QQuickApplicationWindowPrivate::contentData_append, + QQuickItemPrivate::data_count, + QQuickItemPrivate::data_at, + QQuickItemPrivate::data_clear); +} + +/*! + \qmlproperty Item QtQuick.Controls::ApplicationWindow::contentItem + \readonly + + This property holds the window content item. + + The content item is stacked above the \l background item, and under the + \l menuBar, \l header, and \l footer items. + + \sa background, menuBar, header, footer +*/ +QQuickItem *QQuickApplicationWindow::contentItem() const +{ + QQuickApplicationWindowPrivate *d = const_cast<QQuickApplicationWindowPrivate *>(d_func()); + if (!d->appWindowContentItem) { + d->appWindowContentItem = new QQuickContentItem(this, QQuickWindow::contentItem()); + d->appWindowContentItem->setFlag(QQuickItem::ItemIsFocusScope); + d->appWindowContentItem->setFocus(true); + d->relayout(); + } + return d->appWindowContentItem; +} + +/*! + \qmlproperty Control QtQuick.Controls::ApplicationWindow::activeFocusControl + \readonly + + This property holds the control that currently has active focus, or \c null if there is + no control with active focus. + + The difference between \l Window::activeFocusItem and ApplicationWindow::activeFocusControl + is that the former may point to a building block of a control, whereas the latter points + to the enclosing control. For example, when SpinBox has focus, activeFocusItem points to + the editor and activeFocusControl to the SpinBox itself. + + \sa Window::activeFocusItem +*/ +QQuickItem *QQuickApplicationWindow::activeFocusControl() const +{ + Q_D(const QQuickApplicationWindow); + return d->activeFocusControl; +} + +/*! + \qmlproperty font QtQuick.Controls::ApplicationWindow::font + + This property holds the font currently set for the window. + + The default font depends on the system environment. QGuiApplication maintains a system/theme + font which serves as a default for all application windows. You can also set the default font + for windows by passing a custom font to QGuiApplication::setFont(), before loading any QML. + Finally, the font is matched against Qt's font database to find the best match. + + ApplicationWindow propagates explicit font properties to child controls. If you change a specific + property on the window's font, that property propagates to all child controls in the window, + overriding any system defaults for that property. + + \sa Control::font +*/ +QFont QQuickApplicationWindow::font() const +{ + Q_D(const QQuickApplicationWindow); + return d->font; +} + +void QQuickApplicationWindow::setFont(const QFont &font) +{ + Q_D(QQuickApplicationWindow); + if (d->font.resolveMask() == font.resolveMask() && d->font == font) + return; + + QFont resolvedFont = font.resolve(QQuickTheme::font(QQuickTheme::System)); + d->setFont_helper(resolvedFont); +} + +void QQuickApplicationWindow::resetFont() +{ + setFont(QFont()); +} + +/*! + \qmlproperty Locale QtQuick.Controls::ApplicationWindow::locale + + This property holds the locale of the window. + + The default locale depends on the system environment. You can set the + default locale by calling QLocale::setDefault(), before loading any QML. + + ApplicationWindow propagates the locale to child controls. If you change + the window's locale, that locale propagates to all child controls in the + window, overriding the system default locale. + + \sa Control::locale +*/ +QLocale QQuickApplicationWindow::locale() const +{ + Q_D(const QQuickApplicationWindow); + return d->locale; +} + +void QQuickApplicationWindow::setLocale(const QLocale &locale) +{ + Q_D(QQuickApplicationWindow); + if (d->locale == locale) + return; + + d->locale = locale; + QQuickControlPrivate::updateLocaleRecur(QQuickWindow::contentItem(), locale); + + // TODO: internal QQuickPopupManager that provides reliable access to all QQuickPopup instances + const QList<QQuickPopup *> popups = QQuickWindow::contentItem()->findChildren<QQuickPopup *>(); + for (QQuickPopup *popup : popups) + QQuickControlPrivate::get(static_cast<QQuickControl *>(popup->popupItem()))->updateLocale(locale, false); // explicit=false + + emit localeChanged(); +} + +void QQuickApplicationWindow::resetLocale() +{ + setLocale(QLocale()); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty Item QtQuick.Controls::ApplicationWindow::menuBar + + This property holds the window menu bar. The menu bar is positioned at the + top of the window, above the header, and resized to the width of the window. + The default value is \c null. + + \code + ApplicationWindow { + menuBar: MenuBar { + // ... + } + } + \endcode + + \sa header, footer, MenuBar +*/ +QQuickItem *QQuickApplicationWindow::menuBar() const +{ + Q_D(const QQuickApplicationWindow); + return d->menuBar; +} + +void QQuickApplicationWindow::setMenuBar(QQuickItem *menuBar) +{ + Q_D(QQuickApplicationWindow); + if (d->menuBar == menuBar) + return; + + if (d->menuBar) { + QQuickItemPrivate::get(d->menuBar)->removeItemChangeListener(d, ItemChanges); + d->menuBar->setParentItem(nullptr); + } + d->menuBar = menuBar; + if (menuBar) { + menuBar->setParentItem(contentItem()); + QQuickItemPrivate *p = QQuickItemPrivate::get(menuBar); + p->addItemChangeListener(d, ItemChanges); + if (qFuzzyIsNull(menuBar->z())) + menuBar->setZ(2); + } + if (isComponentComplete()) + d->relayout(); + emit menuBarChanged(); +} + +bool QQuickApplicationWindow::isComponentComplete() const +{ + Q_D(const QQuickApplicationWindow); + return d->complete; +} + +void QQuickApplicationWindow::classBegin() +{ + Q_D(QQuickApplicationWindow); + d->complete = false; + QQuickWindowQmlImpl::classBegin(); + d->resolveFont(); +} + +void QQuickApplicationWindow::componentComplete() +{ + Q_D(QQuickApplicationWindow); + d->complete = true; + d->executeBackground(true); + QQuickWindowQmlImpl::componentComplete(); + d->relayout(); +} + +void QQuickApplicationWindow::resizeEvent(QResizeEvent *event) +{ + Q_D(QQuickApplicationWindow); + QQuickWindowQmlImpl::resizeEvent(event); + d->relayout(); +} + +class QQuickApplicationWindowAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickApplicationWindowAttached) + +public: + void windowChange(QQuickWindow *wnd); + void activeFocusChange(); + + QQuickWindow *window = nullptr; + QQuickItem *activeFocusControl = nullptr; +}; + +void QQuickApplicationWindowAttachedPrivate::windowChange(QQuickWindow *wnd) +{ + Q_Q(QQuickApplicationWindowAttached); + if (window == wnd) + return; + + QQuickApplicationWindow *oldWindow = qobject_cast<QQuickApplicationWindow *>(window); + if (oldWindow && !QQuickApplicationWindowPrivate::get(oldWindow)) + oldWindow = nullptr; // being deleted (QTBUG-52731) + + if (oldWindow) { + disconnect(oldWindow, &QQuickApplicationWindow::activeFocusControlChanged, + this, &QQuickApplicationWindowAttachedPrivate::activeFocusChange); + QObject::disconnect(oldWindow, &QQuickApplicationWindow::menuBarChanged, + q, &QQuickApplicationWindowAttached::menuBarChanged); + QObject::disconnect(oldWindow, &QQuickApplicationWindow::headerChanged, + q, &QQuickApplicationWindowAttached::headerChanged); + QObject::disconnect(oldWindow, &QQuickApplicationWindow::footerChanged, + q, &QQuickApplicationWindowAttached::footerChanged); + } else if (window) { + disconnect(window, &QQuickWindow::activeFocusItemChanged, + this, &QQuickApplicationWindowAttachedPrivate::activeFocusChange); + } + + QQuickApplicationWindow *newWindow = qobject_cast<QQuickApplicationWindow *>(wnd); + if (newWindow) { + connect(newWindow, &QQuickApplicationWindow::activeFocusControlChanged, + this, &QQuickApplicationWindowAttachedPrivate::activeFocusChange); + QObject::connect(newWindow, &QQuickApplicationWindow::menuBarChanged, + q, &QQuickApplicationWindowAttached::menuBarChanged); + QObject::connect(newWindow, &QQuickApplicationWindow::headerChanged, + q, &QQuickApplicationWindowAttached::headerChanged); + QObject::connect(newWindow, &QQuickApplicationWindow::footerChanged, + q, &QQuickApplicationWindowAttached::footerChanged); + } else if (wnd) { + connect(wnd, &QQuickWindow::activeFocusItemChanged, + this, &QQuickApplicationWindowAttachedPrivate::activeFocusChange); + } + + window = wnd; + emit q->windowChanged(); + emit q->contentItemChanged(); + + activeFocusChange(); + if ((oldWindow && oldWindow->menuBar()) || (newWindow && newWindow->menuBar())) + emit q->menuBarChanged(); + if ((oldWindow && oldWindow->header()) || (newWindow && newWindow->header())) + emit q->headerChanged(); + if ((oldWindow && oldWindow->footer()) || (newWindow && newWindow->footer())) + emit q->footerChanged(); +} + +void QQuickApplicationWindowAttachedPrivate::activeFocusChange() +{ + Q_Q(QQuickApplicationWindowAttached); + QQuickItem *control = nullptr; + if (QQuickApplicationWindow *appWindow = qobject_cast<QQuickApplicationWindow *>(window)) + control = appWindow->activeFocusControl(); + else if (window) + control = findActiveFocusControl(window); + if (activeFocusControl == control) + return; + + activeFocusControl = control; + emit q->activeFocusControlChanged(); +} + +QQuickApplicationWindowAttached::QQuickApplicationWindowAttached(QObject *parent) + : QObject(*(new QQuickApplicationWindowAttachedPrivate), parent) +{ + Q_D(QQuickApplicationWindowAttached); + if (QQuickItem *item = qobject_cast<QQuickItem *>(parent)) { + d->windowChange(item->window()); + QObjectPrivate::connect(item, &QQuickItem::windowChanged, d, &QQuickApplicationWindowAttachedPrivate::windowChange); + if (!d->window) { + QQuickItem *p = item; + while (p) { + if (QQuickPopup *popup = qobject_cast<QQuickPopup *>(p->parent())) { + d->windowChange(popup->window()); + QObjectPrivate::connect(popup, &QQuickPopup::windowChanged, d, &QQuickApplicationWindowAttachedPrivate::windowChange); + } + p = p->parentItem(); + } + } + } else if (QQuickPopup *popup = qobject_cast<QQuickPopup *>(parent)) { + d->windowChange(popup->window()); + QObjectPrivate::connect(popup, &QQuickPopup::windowChanged, d, &QQuickApplicationWindowAttachedPrivate::windowChange); + } +} + +/*! + \qmlattachedproperty ApplicationWindow QtQuick.Controls::ApplicationWindow::window + \readonly + + This attached property holds the application window. The property can be attached + to any item. The value is \c null if the item is not in an ApplicationWindow. + + \sa {Attached ApplicationWindow Properties} +*/ +QQuickApplicationWindow *QQuickApplicationWindowAttached::window() const +{ + Q_D(const QQuickApplicationWindowAttached); + return qobject_cast<QQuickApplicationWindow *>(d->window); +} + +/*! + \qmlattachedproperty Item QtQuick.Controls::ApplicationWindow::contentItem + \readonly + + This attached property holds the window content item. The property can be attached + to any item. The value is \c null if the item is not in an ApplicationWindow. + + \sa {Attached ApplicationWindow Properties} +*/ +QQuickItem *QQuickApplicationWindowAttached::contentItem() const +{ + Q_D(const QQuickApplicationWindowAttached); + if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window)) + return window->contentItem(); + return nullptr; +} + +/*! + \qmlattachedproperty Control QtQuick.Controls::ApplicationWindow::activeFocusControl + \readonly + + This attached property holds the control that currently has active focus, or \c null + if there is no control with active focus. The property can be attached to any item. + The value is \c null if the item is not in a window, or the window has no active focus. + + \sa Window::activeFocusItem, {Attached ApplicationWindow Properties} +*/ +QQuickItem *QQuickApplicationWindowAttached::activeFocusControl() const +{ + Q_D(const QQuickApplicationWindowAttached); + return d->activeFocusControl; +} + +/*! + \qmlattachedproperty Item QtQuick.Controls::ApplicationWindow::header + \readonly + + This attached property holds the window header item. The property can be attached + to any item. The value is \c null if the item is not in an ApplicationWindow, or + the window has no header item. + + \sa {Attached ApplicationWindow Properties} +*/ +QQuickItem *QQuickApplicationWindowAttached::header() const +{ + Q_D(const QQuickApplicationWindowAttached); + if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window)) + return window->header(); + return nullptr; +} + +/*! + \qmlattachedproperty Item QtQuick.Controls::ApplicationWindow::footer + \readonly + + This attached property holds the window footer item. The property can be attached + to any item. The value is \c null if the item is not in an ApplicationWindow, or + the window has no footer item. + + \sa {Attached ApplicationWindow Properties} +*/ +QQuickItem *QQuickApplicationWindowAttached::footer() const +{ + Q_D(const QQuickApplicationWindowAttached); + if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window)) + return window->footer(); + return nullptr; +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlattachedproperty Item QtQuick.Controls::ApplicationWindow::menuBar + \readonly + + This attached property holds the window menu bar. The property can be attached + to any item. The value is \c null if the item is not in an ApplicationWindow, or + the window has no menu bar. + + \sa {Attached ApplicationWindow Properties} +*/ +QQuickItem *QQuickApplicationWindowAttached::menuBar() const +{ + Q_D(const QQuickApplicationWindowAttached); + if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window)) + return window->menuBar(); + return nullptr; +} + +QT_END_NAMESPACE + +#include "moc_qquickapplicationwindow_p.cpp" diff --git a/src/quicktemplates2/qquickapplicationwindow_p.h b/src/quicktemplates2/qquickapplicationwindow_p.h new file mode 100644 index 00000000000..f5aa8b8b1ac --- /dev/null +++ b/src/quicktemplates2/qquickapplicationwindow_p.h @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKAPPLICATIONWINDOW_P_H +#define QQUICKAPPLICATIONWINDOW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquickwindowmodule_p.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> +#include <QtGui/qfont.h> +#include <QtGui/qpalette.h> +#include <QtCore/qlocale.h> + +QT_BEGIN_NAMESPACE + +class QQuickApplicationWindowPrivate; +class QQuickApplicationWindowAttached; +class QQuickApplicationWindowAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickApplicationWindow : public QQuickWindowQmlImpl +{ + Q_OBJECT + Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) + Q_PROPERTY(QQuickItem *contentItem READ contentItem CONSTANT FINAL) + Q_PRIVATE_PROPERTY(QQuickApplicationWindow::d_func(), QQmlListProperty<QObject> contentData READ contentData FINAL) + Q_PROPERTY(QQuickItem *activeFocusControl READ activeFocusControl NOTIFY activeFocusControlChanged FINAL) + Q_PROPERTY(QQuickItem *header READ header WRITE setHeader NOTIFY headerChanged FINAL) + Q_PROPERTY(QQuickItem *footer READ footer WRITE setFooter NOTIFY footerChanged FINAL) + Q_PROPERTY(QFont font READ font WRITE setFont RESET resetFont NOTIFY fontChanged FINAL) + Q_PROPERTY(QLocale locale READ locale WRITE setLocale RESET resetLocale NOTIFY localeChanged FINAL) + // 2.3 (Qt 5.10) + Q_PROPERTY(QQuickItem *menuBar READ menuBar WRITE setMenuBar NOTIFY menuBarChanged FINAL REVISION(2, 3)) + // 2.14 (Qt 6) + Q_PRIVATE_PROPERTY(QQuickApplicationWindow::d_func(), QQuickPalette *palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged REVISION(2, 3)) + Q_CLASSINFO("DeferredPropertyNames", "background") + Q_CLASSINFO("DefaultProperty", "contentData") + QML_NAMED_ELEMENT(ApplicationWindow) + QML_ADDED_IN_VERSION(2, 0) + QML_ATTACHED(QQuickApplicationWindowAttached) + +public: + explicit QQuickApplicationWindow(QWindow *parent = nullptr); + ~QQuickApplicationWindow(); + + static QQuickApplicationWindowAttached *qmlAttachedProperties(QObject *object); + + QQuickItem *background() const; + void setBackground(QQuickItem *background); + + QQuickItem *contentItem() const; + + QQuickItem *activeFocusControl() const; + + QQuickItem *header() const; + void setHeader(QQuickItem *header); + + QQuickItem *footer() const; + void setFooter(QQuickItem *footer); + + QFont font() const; + void setFont(const QFont &font); + void resetFont(); + + QLocale locale() const; + void setLocale(const QLocale &locale); + void resetLocale(); + + QQuickItem *menuBar() const; + void setMenuBar(QQuickItem *menuBar); + +Q_SIGNALS: + void backgroundChanged(); + void activeFocusControlChanged(); + void headerChanged(); + void footerChanged(); + void fontChanged(); + void localeChanged(); + Q_REVISION(2, 3) void menuBarChanged(); + +protected: + bool isComponentComplete() const; + void classBegin() override; + void componentComplete() override; + void resizeEvent(QResizeEvent *event) override; + +private: + Q_DISABLE_COPY(QQuickApplicationWindow) + Q_DECLARE_PRIVATE(QQuickApplicationWindow) + Q_PRIVATE_SLOT(d_func(), void _q_updateActiveFocus()) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickApplicationWindowAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickApplicationWindow *window READ window NOTIFY windowChanged FINAL) + Q_PROPERTY(QQuickItem *contentItem READ contentItem NOTIFY contentItemChanged FINAL) + Q_PROPERTY(QQuickItem *activeFocusControl READ activeFocusControl NOTIFY activeFocusControlChanged FINAL) + Q_PROPERTY(QQuickItem *header READ header NOTIFY headerChanged FINAL) + Q_PROPERTY(QQuickItem *footer READ footer NOTIFY footerChanged FINAL) + Q_PROPERTY(QQuickItem *menuBar READ menuBar NOTIFY menuBarChanged FINAL) // REVISION(2, 3) + +public: + explicit QQuickApplicationWindowAttached(QObject *parent = nullptr); + + QQuickApplicationWindow *window() const; + QQuickItem *contentItem() const; + QQuickItem *activeFocusControl() const; + QQuickItem *header() const; + QQuickItem *footer() const; + QQuickItem *menuBar() const; + +Q_SIGNALS: + void windowChanged(); + void contentItemChanged(); + void activeFocusControlChanged(); + void headerChanged(); + void footerChanged(); + // 2.3 (Qt 5.10) + /*Q_REVISION(2, 3)*/ void menuBarChanged(); + +private: + Q_DISABLE_COPY(QQuickApplicationWindowAttached) + Q_DECLARE_PRIVATE(QQuickApplicationWindowAttached) +}; + +struct QWindowForeign2 +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QWindow) + QML_ADDED_IN_VERSION(2, 0) +}; + +struct QQuickWindowForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickWindow) + QML_ADDED_IN_VERSION(2, 0) +}; + +struct QQuickWindowQmlImplForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickWindowQmlImpl) + QML_ADDED_IN_VERSION(2, 2) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickApplicationWindow) +QML_DECLARE_TYPEINFO(QQuickApplicationWindow, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKAPPLICATIONWINDOW_P_H diff --git a/src/quicktemplates2/qquickbusyindicator.cpp b/src/quicktemplates2/qquickbusyindicator.cpp new file mode 100644 index 00000000000..1b4f590f639 --- /dev/null +++ b/src/quicktemplates2/qquickbusyindicator.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickbusyindicator_p.h" +#include "qquickcontrol_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype BusyIndicator + \inherits Control +//! \instantiates QQuickBusyIndicator + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-indicators + \brief Indicates background activity, for example, while content is being loaded. + + \image qtquickcontrols2-busyindicator.gif + + The busy indicator should be used to indicate activity while content is + being loaded or the UI is blocked waiting for a resource to become available. + + The following snippet shows how to use the BusyIndicator: + + \qml + BusyIndicator { + running: image.status === Image.Loading + } + \endqml + + BusyIndicator is similar to an indeterminate \l ProgressBar. Both can be + used to indicate background activity. The main difference is visual, and + that ProgressBar can also present a concrete amount of progress (when it + can be determined). Due to the visual difference, busy indicators and + indeterminate progress bars fit different places in user interfaces. + Typical places for a busy indicator: + \list + \li in the corner of a \l ToolBar + \li as an overlay on top of a \l Page + \li on the side of an \l ItemDelegate + \endlist + + \sa {Customizing BusyIndicator}, {Indicator Controls}, ProgressBar +*/ + +class QQuickBusyIndicatorPrivate : public QQuickControlPrivate +{ +public: + bool running = true; +}; + +QQuickBusyIndicator::QQuickBusyIndicator(QQuickItem *parent) + : QQuickControl(*(new QQuickBusyIndicatorPrivate), parent) +{ +} + +/*! + \qmlproperty bool QtQuick.Controls::BusyIndicator::running + + This property holds whether the busy indicator is currently indicating + activity. + + \note The indicator is only visible when this property is set to \c true. + + The default value is \c true. +*/ +bool QQuickBusyIndicator::isRunning() const +{ + Q_D(const QQuickBusyIndicator); + return d->running; +} + +void QQuickBusyIndicator::setRunning(bool running) +{ + Q_D(QQuickBusyIndicator); + if (d->running == running) + return; + + d->running = running; + emit runningChanged(); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickBusyIndicator::touchEvent(QTouchEvent *event) +{ + event->ignore(); // QTBUG-61785 +} +#endif + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickBusyIndicator::accessibleRole() const +{ + return QAccessible::Indicator; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickbusyindicator_p.cpp" diff --git a/src/quicktemplates2/qquickbusyindicator_p.h b/src/quicktemplates2/qquickbusyindicator_p.h new file mode 100644 index 00000000000..bdb2eb240bf --- /dev/null +++ b/src/quicktemplates2/qquickbusyindicator_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKBUSYINDICATOR_P_H +#define QQUICKBUSYINDICATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickBusyIndicatorPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickBusyIndicator : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged FINAL) + QML_NAMED_ELEMENT(BusyIndicator) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickBusyIndicator(QQuickItem *parent = nullptr); + + bool isRunning() const; + void setRunning(bool running); + +Q_SIGNALS: + void runningChanged(); + +protected: +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickBusyIndicator) + Q_DECLARE_PRIVATE(QQuickBusyIndicator) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickBusyIndicator) + +#endif // QQUICKBUSYINDICATOR_P_H diff --git a/src/quicktemplates2/qquickbutton.cpp b/src/quicktemplates2/qquickbutton.cpp new file mode 100644 index 00000000000..beae5287a4e --- /dev/null +++ b/src/quicktemplates2/qquickbutton.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickbutton_p.h" +#include "qquickbutton_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Button + \inherits AbstractButton +//! \instantiates QQuickButton + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-buttons + \brief Push-button that can be clicked to perform a command or answer a question. + + \image qtquickcontrols2-button.gif + + Button presents a push-button control that can be pushed or clicked by + the user. Buttons are normally used to perform an action, or to answer + a question. Typical buttons are \e OK, \e Apply, \e Cancel, \e Close, + \e Yes, \e No, and \e Help. + + Button inherits its API from AbstractButton. For instance, you can set + \l {AbstractButton::text}{text}, display an \l {Icons in Qt Quick Controls}{icon}, + and react to \l {AbstractButton::clicked}{clicks} using the AbstractButton API. + + A button emits the signal \l {AbstractButton::}{clicked()} when it is activated by the user. + Connect to this signal to perform the button's action. Buttons also + provide the signals \l {AbstractButton::}{canceled()}, \l {AbstractButton::}{doubleClicked()}, \l {AbstractButton::}{pressed()}, + \l {AbstractButton::}{released()} and \l {AbstractButton::}{pressAndHold()} for long presses. + + See the snippet below on how to connect to the button's signals. + + \code + RowLayout { + Button { + text: "Ok" + onClicked: model.submit() + } + Button { + text: "Cancel" + onClicked: model.revert() + } + } + \endcode + + \sa {Customizing Button}, {Button Controls} +*/ + +QQuickButton::QQuickButton(QQuickItem *parent) + : QQuickAbstractButton(*(new QQuickButtonPrivate), parent) +{ +} + +QQuickButton::QQuickButton(QQuickButtonPrivate &dd, QQuickItem *parent) + : QQuickAbstractButton(dd, parent) +{ +} + +QFont QQuickButton::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::Button); +} + +/*! + \qmlproperty bool QtQuick.Controls::Button::highlighted + + This property holds whether the button is highlighted. + + \image qtquickcontrols2-button-highlighted.gif + + A button can be highlighted in order to draw the user's attention towards + it. It has no effect on keyboard interaction. + + The default value is \c false. +*/ +bool QQuickButton::isHighlighted() const +{ + Q_D(const QQuickButton); + return d->highlighted; +} + +void QQuickButton::setHighlighted(bool highlighted) +{ + Q_D(QQuickButton); + if (highlighted == d->highlighted) + return; + + d->highlighted = highlighted; + emit highlightedChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::Button::flat + + This property holds whether the button is flat. + + \image qtquickcontrols2-button-flat.gif + + A flat button typically does not draw a background unless it is pressed or checked. + + The default value is \c false. +*/ +bool QQuickButton::isFlat() const +{ + Q_D(const QQuickButton); + return d->flat; +} + +void QQuickButton::setFlat(bool flat) +{ + Q_D(QQuickButton); + if (flat == d->flat) + return; + + d->flat = flat; + emit flatChanged(); +} + +QPalette QQuickButtonPrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::Button); +} + +QT_END_NAMESPACE + +#include "moc_qquickbutton_p.cpp" diff --git a/src/quicktemplates2/qquickbutton_p.h b/src/quicktemplates2/qquickbutton_p.h new file mode 100644 index 00000000000..bfac5663b7b --- /dev/null +++ b/src/quicktemplates2/qquickbutton_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKBUTTON_P_H +#define QQUICKBUTTON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickButtonPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickButton : public QQuickAbstractButton +{ + Q_OBJECT + Q_PROPERTY(bool highlighted READ isHighlighted WRITE setHighlighted NOTIFY highlightedChanged FINAL) + Q_PROPERTY(bool flat READ isFlat WRITE setFlat NOTIFY flatChanged FINAL) + QML_NAMED_ELEMENT(Button) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickButton(QQuickItem *parent = nullptr); + + bool isHighlighted() const; + void setHighlighted(bool highlighted); + + bool isFlat() const; + void setFlat(bool flat); + +Q_SIGNALS: + void highlightedChanged(); + void flatChanged(); + +protected: + QQuickButton(QQuickButtonPrivate &dd, QQuickItem *parent); + + QFont defaultFont() const override; + +private: + Q_DISABLE_COPY(QQuickButton) + Q_DECLARE_PRIVATE(QQuickButton) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickButton) + +#endif // QQUICKBUTTON_P_H diff --git a/src/quicktemplates2/qquickbutton_p_p.h b/src/quicktemplates2/qquickbutton_p_p.h new file mode 100644 index 00000000000..e83e3209346 --- /dev/null +++ b/src/quicktemplates2/qquickbutton_p_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKBUTTON_P_P_H +#define QQUICKBUTTON_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickButtonPrivate : public QQuickAbstractButtonPrivate +{ + Q_DECLARE_PUBLIC(QQuickButton) + +public: + QPalette defaultPalette() const override; + + bool flat = false; + bool highlighted = false; +}; + +QT_END_NAMESPACE + +#endif // QQUICKBUTTON_P_P_H diff --git a/src/quicktemplates2/qquickbuttongroup.cpp b/src/quicktemplates2/qquickbuttongroup.cpp new file mode 100644 index 00000000000..fd8e822c5f0 --- /dev/null +++ b/src/quicktemplates2/qquickbuttongroup.cpp @@ -0,0 +1,546 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickbuttongroup_p.h" + +#include <QtCore/private/qobject_p.h> +#include <QtCore/qmetaobject.h> +#include <QtCore/qvariant.h> +#include <QtQml/qqmlinfo.h> + +#include "qquickabstractbutton_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ButtonGroup + \inherits QtObject +//! \instantiates QQuickButtonGroup + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup utilities + \brief Mutually-exclusive group of checkable buttons. + + ButtonGroup is a non-visual, mutually exclusive group of buttons. + It is used with controls such as RadioButton, where only one of the options + can be selected at a time. + + The most straight-forward way to use ButtonGroup is to assign + a list of buttons. For example, the list of children of a + \l{Item Positioners}{positioner} or a \l{Qt Quick Layouts}{layout} + that manages a group of mutually exclusive buttons. + + \code + ButtonGroup { + buttons: column.children + } + + Column { + id: column + + RadioButton { + checked: true + text: qsTr("DAB") + } + + RadioButton { + text: qsTr("FM") + } + + RadioButton { + text: qsTr("AM") + } + } + \endcode + + Mutually exclusive buttons do not always share the same parent item, + or the parent layout may sometimes contain items that should not be + included in the button group. Such cases are best handled using + the \l group attached property. + + \code + ButtonGroup { id: radioGroup } + + Column { + Label { + text: qsTr("Radio:") + } + + RadioButton { + checked: true + text: qsTr("DAB") + ButtonGroup.group: radioGroup + } + + RadioButton { + text: qsTr("FM") + ButtonGroup.group: radioGroup + } + + RadioButton { + text: qsTr("AM") + ButtonGroup.group: radioGroup + } + } + \endcode + + More advanced use cases can be handled using the \c addButton() and + \c removeButton() methods. + + \sa RadioButton, {Button Controls} +*/ + +/*! + \qmlsignal QtQuick.Controls::ButtonGroup::clicked(AbstractButton button) + \since QtQuick.Controls 2.1 (Qt 5.8) + + This signal is emitted when a \a button in the group has been clicked. + + This signal is convenient for implementing a common signal handler for + all buttons in the same group. + + \code + ButtonGroup { + buttons: column.children + onClicked: console.log("clicked:", button.text) + } + + Column { + id: column + Button { text: "First" } + Button { text: "Second" } + Button { text: "Third" } + } + \endcode + + \sa AbstractButton::clicked() +*/ + +class QQuickButtonGroupPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickButtonGroup) + +public: + void clear(); + void buttonClicked(); + void _q_updateCurrent(); + void updateCheckState(); + void setCheckState(Qt::CheckState state); + + static void buttons_append(QQmlListProperty<QQuickAbstractButton> *prop, QQuickAbstractButton *obj); + static qsizetype buttons_count(QQmlListProperty<QQuickAbstractButton> *prop); + static QQuickAbstractButton *buttons_at(QQmlListProperty<QQuickAbstractButton> *prop, qsizetype index); + static void buttons_clear(QQmlListProperty<QQuickAbstractButton> *prop); + + bool complete = true; + bool exclusive = true; + bool settingCheckState = false; + Qt::CheckState checkState = Qt::Unchecked; + QPointer<QQuickAbstractButton> checkedButton; + QList<QQuickAbstractButton*> buttons; +}; + +void QQuickButtonGroupPrivate::clear() +{ + for (QQuickAbstractButton *button : qAsConst(buttons)) { + QQuickAbstractButtonPrivate::get(button)->group = nullptr; + QObjectPrivate::disconnect(button, &QQuickAbstractButton::clicked, this, &QQuickButtonGroupPrivate::buttonClicked); + QObjectPrivate::disconnect(button, &QQuickAbstractButton::checkedChanged, this, &QQuickButtonGroupPrivate::_q_updateCurrent); + } + buttons.clear(); +} + +void QQuickButtonGroupPrivate::buttonClicked() +{ + Q_Q(QQuickButtonGroup); + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(q->sender()); + if (button) + emit q->clicked(button); +} + +void QQuickButtonGroupPrivate::_q_updateCurrent() +{ + Q_Q(QQuickButtonGroup); + if (exclusive) { + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(q->sender()); + if (button && button->isChecked()) + q->setCheckedButton(button); + else if (!buttons.contains(checkedButton)) + q->setCheckedButton(nullptr); + } + updateCheckState(); +} + +void QQuickButtonGroupPrivate::updateCheckState() +{ + if (!complete || settingCheckState) + return; + + bool anyChecked = false; + bool allChecked = !buttons.isEmpty(); + for (QQuickAbstractButton *button : qAsConst(buttons)) { + const bool isChecked = button->isChecked(); + anyChecked |= isChecked; + allChecked &= isChecked; + } + setCheckState(Qt::CheckState(anyChecked + allChecked)); +} + +void QQuickButtonGroupPrivate::setCheckState(Qt::CheckState state) +{ + Q_Q(QQuickButtonGroup); + if (checkState == state) + return; + + checkState = state; + emit q->checkStateChanged(); +} + +void QQuickButtonGroupPrivate::buttons_append(QQmlListProperty<QQuickAbstractButton> *prop, QQuickAbstractButton *obj) +{ + QQuickButtonGroup *q = static_cast<QQuickButtonGroup *>(prop->object); + q->addButton(obj); +} + +qsizetype QQuickButtonGroupPrivate::buttons_count(QQmlListProperty<QQuickAbstractButton> *prop) +{ + QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data); + return p->buttons.count(); +} + +QQuickAbstractButton *QQuickButtonGroupPrivate::buttons_at(QQmlListProperty<QQuickAbstractButton> *prop, qsizetype index) +{ + QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data); + return p->buttons.value(index); +} + +void QQuickButtonGroupPrivate::buttons_clear(QQmlListProperty<QQuickAbstractButton> *prop) +{ + QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data); + if (!p->buttons.isEmpty()) { + p->clear(); + QQuickButtonGroup *q = static_cast<QQuickButtonGroup *>(prop->object); + // QTBUG-52358: don't clear the checked button immediately + QMetaObject::invokeMethod(q, "_q_updateCurrent", Qt::QueuedConnection); + emit q->buttonsChanged(); + } +} + +QQuickButtonGroup::QQuickButtonGroup(QObject *parent) + : QObject(*(new QQuickButtonGroupPrivate), parent) +{ +} + +QQuickButtonGroup::~QQuickButtonGroup() +{ + Q_D(QQuickButtonGroup); + d->clear(); +} + +QQuickButtonGroupAttached *QQuickButtonGroup::qmlAttachedProperties(QObject *object) +{ + return new QQuickButtonGroupAttached(object); +} + +/*! + \qmlproperty AbstractButton QtQuick.Controls::ButtonGroup::checkedButton + + This property holds the currently selected button in an exclusive group, + or \c null if there is none or the group is non-exclusive. + + By default, it is the first checked button added to an exclusive button group. + + \sa exclusive +*/ +QQuickAbstractButton *QQuickButtonGroup::checkedButton() const +{ + Q_D(const QQuickButtonGroup); + return d->checkedButton; +} + +void QQuickButtonGroup::setCheckedButton(QQuickAbstractButton *checkedButton) +{ + Q_D(QQuickButtonGroup); + if (d->checkedButton == checkedButton) + return; + + if (d->checkedButton) + d->checkedButton->setChecked(false); + d->checkedButton = checkedButton; + if (checkedButton) + checkedButton->setChecked(true); + emit checkedButtonChanged(); +} + +/*! + \qmlproperty list<AbstractButton> QtQuick.Controls::ButtonGroup::buttons + + This property holds the list of buttons. + + \code + ButtonGroup { + buttons: column.children + } + + Column { + id: column + + RadioButton { + checked: true + text: qsTr("Option A") + } + + RadioButton { + text: qsTr("Option B") + } + } + \endcode + + \sa group +*/ +QQmlListProperty<QQuickAbstractButton> QQuickButtonGroup::buttons() +{ + Q_D(QQuickButtonGroup); + return QQmlListProperty<QQuickAbstractButton>(this, d, + QQuickButtonGroupPrivate::buttons_append, + QQuickButtonGroupPrivate::buttons_count, + QQuickButtonGroupPrivate::buttons_at, + QQuickButtonGroupPrivate::buttons_clear); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::ButtonGroup::exclusive + + This property holds whether the button group is exclusive. The default value is \c true. + + If this property is \c true, then only one button in the group can be checked at any given time. + The user can click on any button to check it, and that button will replace the existing one as + the checked button in the group. + + In an exclusive group, the user cannot uncheck the currently checked button by clicking on it; + instead, another button in the group must be clicked to set the new checked button for that group. + + In a non-exclusive group, checking and unchecking buttons does not affect the other buttons in + the group. Furthermore, the value of the \l checkedButton property is \c null. +*/ +bool QQuickButtonGroup::isExclusive() const +{ + Q_D(const QQuickButtonGroup); + return d->exclusive; +} + +void QQuickButtonGroup::setExclusive(bool exclusive) +{ + Q_D(QQuickButtonGroup); + if (d->exclusive == exclusive) + return; + + d->exclusive = exclusive; + emit exclusiveChanged(); +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty enumeration QtQuick.Controls::ButtonGroup::checkState + + This property holds the combined check state of the button group. + + Available states: + \value Qt.Unchecked None of the buttons are checked. + \value Qt.PartiallyChecked Some of the buttons are checked. + \value Qt.Checked All of the buttons are checked. + + Setting the check state of a non-exclusive button group to \c Qt.Unchecked + or \c Qt.Checked unchecks or checks all buttons in the group, respectively. + \c Qt.PartiallyChecked is ignored. + + Setting the check state of an exclusive button group to \c Qt.Unchecked + unchecks the \l checkedButton. \c Qt.Checked and \c Qt.PartiallyChecked + are ignored. +*/ +Qt::CheckState QQuickButtonGroup::checkState() const +{ + Q_D(const QQuickButtonGroup); + return d->checkState; +} + +void QQuickButtonGroup::setCheckState(Qt::CheckState state) +{ + Q_D(QQuickButtonGroup); + if (d->checkState == state || state == Qt::PartiallyChecked) + return; + + d->settingCheckState = true; + if (d->exclusive) { + if (d->checkedButton && state == Qt::Unchecked) + setCheckedButton(nullptr); + } else { + for (QQuickAbstractButton *button : qAsConst(d->buttons)) + button->setChecked(state == Qt::Checked); + } + d->settingCheckState = false; + d->setCheckState(state); +} + +/*! + \qmlmethod void QtQuick.Controls::ButtonGroup::addButton(AbstractButton button) + + Adds a \a button to the button group. + + \note Manually adding objects to a button group is typically unnecessary. + The \l buttons property and the \l group attached property provide a + convenient and declarative syntax. + + \sa buttons, group +*/ +void QQuickButtonGroup::addButton(QQuickAbstractButton *button) +{ + Q_D(QQuickButtonGroup); + if (!button || d->buttons.contains(button)) + return; + + QQuickAbstractButtonPrivate::get(button)->group = this; + QObjectPrivate::connect(button, &QQuickAbstractButton::clicked, d, &QQuickButtonGroupPrivate::buttonClicked); + QObjectPrivate::connect(button, &QQuickAbstractButton::checkedChanged, d, &QQuickButtonGroupPrivate::_q_updateCurrent); + + if (d->exclusive && button->isChecked()) + setCheckedButton(button); + + d->buttons.append(button); + d->updateCheckState(); + emit buttonsChanged(); +} + +/*! + \qmlmethod void QtQuick.Controls::ButtonGroup::removeButton(AbstractButton button) + + Removes a \a button from the button group. + + \note Manually removing objects from a button group is typically unnecessary. + The \l buttons property and the \l group attached property provide a + convenient and declarative syntax. + + \sa buttons, group +*/ +void QQuickButtonGroup::removeButton(QQuickAbstractButton *button) +{ + Q_D(QQuickButtonGroup); + if (!button || !d->buttons.contains(button)) + return; + + QQuickAbstractButtonPrivate::get(button)->group = nullptr; + QObjectPrivate::disconnect(button, &QQuickAbstractButton::clicked, d, &QQuickButtonGroupPrivate::buttonClicked); + QObjectPrivate::disconnect(button, &QQuickAbstractButton::checkedChanged, d, &QQuickButtonGroupPrivate::_q_updateCurrent); + + if (d->checkedButton == button) + setCheckedButton(nullptr); + + d->buttons.removeOne(button); + d->updateCheckState(); + emit buttonsChanged(); +} + +void QQuickButtonGroup::classBegin() +{ + Q_D(QQuickButtonGroup); + d->complete = false; +} + +void QQuickButtonGroup::componentComplete() +{ + Q_D(QQuickButtonGroup); + d->complete = true; + if (!d->buttons.isEmpty()) + d->updateCheckState(); +} + +class QQuickButtonGroupAttachedPrivate : public QObjectPrivate +{ +public: + QQuickButtonGroup *group = nullptr; +}; + +QQuickButtonGroupAttached::QQuickButtonGroupAttached(QObject *parent) + : QObject(*(new QQuickButtonGroupAttachedPrivate), parent) +{ +} + +/*! + \qmlattachedproperty ButtonGroup QtQuick.Controls::ButtonGroup::group + + This property attaches a button to a button group. + + \code + ButtonGroup { id: group } + + RadioButton { + checked: true + text: qsTr("Option A") + ButtonGroup.group: group + } + + RadioButton { + text: qsTr("Option B") + ButtonGroup.group: group + } + \endcode + + \sa buttons +*/ +QQuickButtonGroup *QQuickButtonGroupAttached::group() const +{ + Q_D(const QQuickButtonGroupAttached); + return d->group; +} + +void QQuickButtonGroupAttached::setGroup(QQuickButtonGroup *group) +{ + Q_D(QQuickButtonGroupAttached); + if (d->group == group) + return; + + if (d->group) + d->group->removeButton(qobject_cast<QQuickAbstractButton*>(parent())); + d->group = group; + if (group) + group->addButton(qobject_cast<QQuickAbstractButton*>(parent())); + emit groupChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qquickbuttongroup_p.cpp" diff --git a/src/quicktemplates2/qquickbuttongroup_p.h b/src/quicktemplates2/qquickbuttongroup_p.h new file mode 100644 index 00000000000..daff84f2a02 --- /dev/null +++ b/src/quicktemplates2/qquickbuttongroup_p.h @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKBUTTONGROUP_P_H +#define QQUICKBUTTONGROUP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> +#include <QtQml/qqml.h> +#include <QtQml/qqmlparserstatus.h> + +QT_BEGIN_NAMESPACE + +class QQuickAbstractButton; +class QQuickButtonGroupPrivate; +class QQuickButtonGroupAttached; +class QQuickButtonGroupAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickButtonGroup : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_PROPERTY(QQuickAbstractButton *checkedButton READ checkedButton WRITE setCheckedButton NOTIFY checkedButtonChanged FINAL) + Q_PROPERTY(QQmlListProperty<QQuickAbstractButton> buttons READ buttons NOTIFY buttonsChanged FINAL) + // 2.3 (Qt 5.10) + Q_PROPERTY(bool exclusive READ isExclusive WRITE setExclusive NOTIFY exclusiveChanged FINAL REVISION(2, 3)) + // 2.4 (Qt 5.11) + Q_PROPERTY(Qt::CheckState checkState READ checkState WRITE setCheckState NOTIFY checkStateChanged FINAL REVISION(2, 4)) + Q_INTERFACES(QQmlParserStatus) + QML_NAMED_ELEMENT(ButtonGroup) + QML_ATTACHED(QQuickButtonGroupAttached) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickButtonGroup(QObject *parent = nullptr); + ~QQuickButtonGroup(); + + static QQuickButtonGroupAttached *qmlAttachedProperties(QObject *object); + + QQuickAbstractButton *checkedButton() const; + void setCheckedButton(QQuickAbstractButton *checkedButton); + + QQmlListProperty<QQuickAbstractButton> buttons(); + + bool isExclusive() const; + void setExclusive(bool exclusive); + + // 2.4 (Qt 5.11) + Qt::CheckState checkState() const; + void setCheckState(Qt::CheckState state); + +public Q_SLOTS: + void addButton(QQuickAbstractButton *button); + void removeButton(QQuickAbstractButton *button); + +Q_SIGNALS: + void checkedButtonChanged(); + void buttonsChanged(); + // 2.1 (Qt 5.8) + Q_REVISION(2, 1) void clicked(QQuickAbstractButton *button); + // 2.3 (Qt 5.10) + Q_REVISION(2, 3) void exclusiveChanged(); + // 2.4 (Qt 5.11) + Q_REVISION(2, 4) void checkStateChanged(); + +protected: + void classBegin() override; + void componentComplete() override; + +private: + Q_DISABLE_COPY(QQuickButtonGroup) + Q_DECLARE_PRIVATE(QQuickButtonGroup) + + Q_PRIVATE_SLOT(d_func(), void _q_updateCurrent()) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickButtonGroupAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickButtonGroup *group READ group WRITE setGroup NOTIFY groupChanged FINAL) + +public: + explicit QQuickButtonGroupAttached(QObject *parent = nullptr); + + QQuickButtonGroup *group() const; + void setGroup(QQuickButtonGroup *group); + +Q_SIGNALS: + void groupChanged(); + +private: + Q_DISABLE_COPY(QQuickButtonGroupAttached) + Q_DECLARE_PRIVATE(QQuickButtonGroupAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickButtonGroup) +QML_DECLARE_TYPEINFO(QQuickButtonGroup, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKBUTTONGROUP_P_H diff --git a/src/quicktemplates2/qquickcheckbox.cpp b/src/quicktemplates2/qquickcheckbox.cpp new file mode 100644 index 00000000000..e3184ceb52f --- /dev/null +++ b/src/quicktemplates2/qquickcheckbox.cpp @@ -0,0 +1,245 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcheckbox_p.h" +#include "qquickabstractbutton_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> +#include <QtQml/qjsvalue.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype CheckBox + \inherits AbstractButton +//! \instantiates QQuickCheckBox + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-buttons + \brief Check button that can be toggled on or off. + + \image qtquickcontrols2-checkbox.gif + + CheckBox presents an option button that can be toggled on (checked) or + off (unchecked). Check boxes are typically used to select one or more + options from a set of options. For larger sets of options, such as those + in a list, consider using \l CheckDelegate instead. + + CheckBox inherits its API from \l AbstractButton. For instance, the + state of the checkbox can be set with the \l {AbstractButton::}{checked} property. + + In addition to the checked and unchecked states, there is a third state: + partially checked. The partially checked state can be enabled using the + \l tristate property. This state indicates that the regular checked/unchecked + state can not be determined; generally because of other states that affect + the checkbox. This state is useful when several child nodes are selected + in a treeview, for example. + + \code + ColumnLayout { + CheckBox { + checked: true + text: qsTr("First") + } + CheckBox { + text: qsTr("Second") + } + CheckBox { + checked: true + text: qsTr("Third") + } + } + \endcode + + Hierarchical checkbox groups can be managed with a non-exclusive + \l ButtonGroup. + + \image qtquickcontrols2-checkbox-group.png + + The following example illustrates how the combined check state of + children can be bound to the check state of the parent checkbox: + + \snippet qtquickcontrols2-checkbox-group.qml 1 + + \sa {Customizing CheckBox}, ButtonGroup, {Button Controls} +*/ + +class QQuickCheckBoxPrivate : public QQuickAbstractButtonPrivate +{ + Q_DECLARE_PUBLIC(QQuickCheckBox) + +public: + void setNextCheckState(const QJSValue &callback); + + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::CheckBox); } + + bool tristate = false; + Qt::CheckState checkState = Qt::Unchecked; + QJSValue nextCheckState; +}; + +void QQuickCheckBoxPrivate::setNextCheckState(const QJSValue &callback) +{ + Q_Q(QQuickCheckBox); + nextCheckState = callback; + emit q->nextCheckStateChanged(); +} + +QQuickCheckBox::QQuickCheckBox(QQuickItem *parent) + : QQuickAbstractButton(*(new QQuickCheckBoxPrivate), parent) +{ + setCheckable(true); +} + +/*! + \qmlproperty bool QtQuick.Controls::CheckBox::tristate + + This property holds whether the checkbox is a tri-state checkbox. + + In the animation below, the first checkbox is tri-state: + + \image qtquickcontrols2-checkbox-tristate.gif + + The default is \c false, i.e., the checkbox has only two states. +*/ +bool QQuickCheckBox::isTristate() const +{ + Q_D(const QQuickCheckBox); + return d->tristate; +} + +void QQuickCheckBox::setTristate(bool tristate) +{ + Q_D(QQuickCheckBox); + if (d->tristate == tristate) + return; + + d->tristate = tristate; + emit tristateChanged(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::CheckBox::checkState + + This property holds the check state of the checkbox. + + Available states: + \value Qt.Unchecked The checkbox is unchecked. + \value Qt.PartiallyChecked The checkbox is partially checked. This state is only used when \l tristate is enabled. + \value Qt.Checked The checkbox is checked. + + \sa tristate, {AbstractButton::checked}{checked} +*/ +Qt::CheckState QQuickCheckBox::checkState() const +{ + Q_D(const QQuickCheckBox); + return d->checkState; +} + +void QQuickCheckBox::setCheckState(Qt::CheckState state) +{ + Q_D(QQuickCheckBox); + if (d->checkState == state) + return; + + bool wasChecked = isChecked(); + d->checked = state == Qt::Checked; + d->checkState = state; + emit checkStateChanged(); + if (d->checked != wasChecked) + emit checkedChanged(); +} + +QFont QQuickCheckBox::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::CheckBox); +} + +void QQuickCheckBox::buttonChange(ButtonChange change) +{ + if (change == ButtonCheckedChange) + setCheckState(isChecked() ? Qt::Checked : Qt::Unchecked); + else + QQuickAbstractButton::buttonChange(change); +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty function QtQuick.Controls::CheckBox::nextCheckState + + This property holds a callback function that is called to determine + the next check state whenever the checkbox is interactively toggled + by the user via touch, mouse, or keyboard. + + By default, a normal checkbox cycles between \c Qt.Unchecked and + \c Qt.Checked states, and a tri-state checkbox cycles between + \c Qt.Unchecked, \c Qt.PartiallyChecked, and \c Qt.Checked states. + + The \c nextCheckState callback function can override the default behavior. + The following example implements a tri-state checkbox that can present + a partially checked state depending on external conditions, but never + cycles to the partially checked state when interactively toggled by + the user. + + \code + CheckBox { + tristate: true + checkState: allChildrenChecked ? Qt.Checked : + anyChildChecked ? Qt.PartiallyChecked : Qt.Unchecked + + nextCheckState: function() { + if (checkState === Qt.Checked) + return Qt.Unchecked + else + return Qt.Checked + } + } + \endcode +*/ +void QQuickCheckBox::nextCheckState() +{ + Q_D(QQuickCheckBox); + if (d->nextCheckState.isCallable()) + setCheckState(static_cast<Qt::CheckState>(d->nextCheckState.call().toInt())); + else if (d->tristate) + setCheckState(static_cast<Qt::CheckState>((d->checkState + 1) % 3)); + else + QQuickAbstractButton::nextCheckState(); +} + +QT_END_NAMESPACE + +#include "moc_qquickcheckbox_p.cpp" diff --git a/src/quicktemplates2/qquickcheckbox_p.h b/src/quicktemplates2/qquickcheckbox_p.h new file mode 100644 index 00000000000..8e53b41dd72 --- /dev/null +++ b/src/quicktemplates2/qquickcheckbox_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCHECKBOX_P_H +#define QQUICKCHECKBOX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickCheckBoxPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickCheckBox : public QQuickAbstractButton +{ + Q_OBJECT + Q_PROPERTY(bool tristate READ isTristate WRITE setTristate NOTIFY tristateChanged FINAL) + Q_PROPERTY(Qt::CheckState checkState READ checkState WRITE setCheckState NOTIFY checkStateChanged FINAL) + // 2.4 (Qt 5.11) + Q_PRIVATE_PROPERTY(QQuickCheckBox::d_func(), QJSValue nextCheckState MEMBER nextCheckState WRITE setNextCheckState NOTIFY nextCheckStateChanged FINAL REVISION(2, 4)) + QML_NAMED_ELEMENT(CheckBox) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickCheckBox(QQuickItem *parent = nullptr); + + bool isTristate() const; + void setTristate(bool tristate); + + Qt::CheckState checkState() const; + void setCheckState(Qt::CheckState state); + +Q_SIGNALS: + void tristateChanged(); + void checkStateChanged(); + // 2.4 (Qt 5.11) + Q_REVISION(2, 4) void nextCheckStateChanged(); + +protected: + QFont defaultFont() const override; + + void buttonChange(ButtonChange change) override; + void nextCheckState() override; + +private: + Q_DISABLE_COPY(QQuickCheckBox) + Q_DECLARE_PRIVATE(QQuickCheckBox) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickCheckBox) + +#endif // QQUICKCHECKBOX_P_H diff --git a/src/quicktemplates2/qquickcheckdelegate.cpp b/src/quicktemplates2/qquickcheckdelegate.cpp new file mode 100644 index 00000000000..7596e104b9f --- /dev/null +++ b/src/quicktemplates2/qquickcheckdelegate.cpp @@ -0,0 +1,239 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcheckdelegate_p.h" +#include "qquickitemdelegate_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> +#include <QtQml/qjsvalue.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype CheckDelegate + \inherits ItemDelegate +//! \instantiates QQuickCheckDelegate + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-delegates + \brief Item delegate with a check indicator that can be toggled on or off. + + \image qtquickcontrols2-checkdelegate.gif + + CheckDelegate presents an item delegate that can be toggled on (checked) or + off (unchecked). Check delegates are typically used to select one or more + options from a set of options in a list. For smaller sets of options, or + for options that need to be uniquely identifiable, consider using + \l CheckBox instead. + + CheckDelegate inherits its API from \l ItemDelegate, which is inherited + from AbstractButton. For instance, you can set \l {AbstractButton::text}{text}, + and react to \l {AbstractButton::clicked}{clicks} using the AbstractButton + API. The state of the check delegate can be set with the + \l {AbstractButton::}{checked} property. + + In addition to the checked and unchecked states, there is a third state: + partially checked. The partially checked state can be enabled using the + \l tristate property. This state indicates that the regular checked/unchecked + state can not be determined; generally because of other states that affect + the check delegate. This state is useful when several child nodes are selected + in a treeview, for example. + + \code + ListView { + model: ["Option 1", "Option 2", "Option 3"] + delegate: CheckDelegate { + text: modelData + } + } + \endcode + + \sa {Customizing CheckDelegate}, {Delegate Controls}, CheckBox +*/ + +class QQuickCheckDelegatePrivate : public QQuickItemDelegatePrivate +{ + Q_DECLARE_PUBLIC(QQuickCheckDelegate) + +public: + void setNextCheckState(const QJSValue &callback); + + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::ListView); } + + bool tristate = false; + Qt::CheckState checkState = Qt::Unchecked; + QJSValue nextCheckState; +}; + +void QQuickCheckDelegatePrivate::setNextCheckState(const QJSValue &callback) +{ + Q_Q(QQuickCheckDelegate); + nextCheckState = callback; + emit q->nextCheckStateChanged(); +} + +QQuickCheckDelegate::QQuickCheckDelegate(QQuickItem *parent) + : QQuickItemDelegate(*(new QQuickCheckDelegatePrivate), parent) +{ + setCheckable(true); +} + +/*! + \qmlproperty bool QtQuick.Controls::CheckDelegate::tristate + + This property determines whether the check delegate has three states. + + In the animation below, the first checkdelegate is tri-state: + + \image qtquickcontrols2-checkdelegate-tristate.gif + + The default is \c false, i.e., the delegate has only two states. +*/ +bool QQuickCheckDelegate::isTristate() const +{ + Q_D(const QQuickCheckDelegate); + return d->tristate; +} + +void QQuickCheckDelegate::setTristate(bool tristate) +{ + Q_D(QQuickCheckDelegate); + if (d->tristate == tristate) + return; + + d->tristate = tristate; + emit tristateChanged(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::CheckDelegate::checkState + + This property determines the check state of the check delegate. + + Available states: + \value Qt.Unchecked The delegate is unchecked. + \value Qt.PartiallyChecked The delegate is partially checked. This state is only used when \l tristate is enabled. + \value Qt.Checked The delegate is checked. + + \sa tristate, {AbstractButton::checked}{checked} +*/ +Qt::CheckState QQuickCheckDelegate::checkState() const +{ + Q_D(const QQuickCheckDelegate); + return d->checkState; +} + +void QQuickCheckDelegate::setCheckState(Qt::CheckState state) +{ + Q_D(QQuickCheckDelegate); + if (d->checkState == state) + return; + + bool wasChecked = isChecked(); + d->checked = state == Qt::Checked; + d->checkState = state; + emit checkStateChanged(); + if (d->checked != wasChecked) + emit checkedChanged(); +} + +QFont QQuickCheckDelegate::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::ListView); +} + +void QQuickCheckDelegate::buttonChange(ButtonChange change) +{ + if (change == ButtonCheckedChange) + setCheckState(isChecked() ? Qt::Checked : Qt::Unchecked); + else + QQuickAbstractButton::buttonChange(change); +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty function QtQuick.Controls::CheckDelegate::nextCheckState + + This property holds a callback function that is called to determine + the next check state whenever the check delegate is interactively toggled + by the user via touch, mouse, or keyboard. + + By default, a normal check delegate cycles between \c Qt.Unchecked and + \c Qt.Checked states, and a tri-state check delegate cycles between + \c Qt.Unchecked, \c Qt.PartiallyChecked, and \c Qt.Checked states. + + The \c nextCheckState callback function can override the default behavior. + The following example implements a tri-state check delegate that can present + a partially checked state depending on external conditions, but never + cycles to the partially checked state when interactively toggled by + the user. + + \code + CheckDelegate { + tristate: true + checkState: allChildrenChecked ? Qt.Checked : + anyChildChecked ? Qt.PartiallyChecked : Qt.Unchecked + + nextCheckState: function() { + if (checkState === Qt.Checked) + return Qt.Unchecked + else + return Qt.Checked + } + } + \endcode +*/ +void QQuickCheckDelegate::nextCheckState() +{ + Q_D(QQuickCheckDelegate); + if (d->nextCheckState.isCallable()) + setCheckState(static_cast<Qt::CheckState>(d->nextCheckState.call().toInt())); + else if (d->tristate) + setCheckState(static_cast<Qt::CheckState>((d->checkState + 1) % 3)); + else + QQuickItemDelegate::nextCheckState(); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickCheckDelegate::accessibleRole() const +{ + return QAccessible::CheckBox; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickcheckdelegate_p.cpp" diff --git a/src/quicktemplates2/qquickcheckdelegate_p.h b/src/quicktemplates2/qquickcheckdelegate_p.h new file mode 100644 index 00000000000..9b69943fd66 --- /dev/null +++ b/src/quicktemplates2/qquickcheckdelegate_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCHECKDELEGATE_P_H +#define QQUICKCHECKDELEGATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickitemdelegate_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickCheckDelegatePrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickCheckDelegate : public QQuickItemDelegate +{ + Q_OBJECT + Q_PROPERTY(bool tristate READ isTristate WRITE setTristate NOTIFY tristateChanged FINAL) + Q_PROPERTY(Qt::CheckState checkState READ checkState WRITE setCheckState NOTIFY checkStateChanged FINAL) + // 2.4 (Qt 5.11) + Q_PRIVATE_PROPERTY(QQuickCheckDelegate::d_func(), QJSValue nextCheckState MEMBER nextCheckState WRITE setNextCheckState NOTIFY nextCheckStateChanged FINAL REVISION(2, 4)) + QML_NAMED_ELEMENT(CheckDelegate) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickCheckDelegate(QQuickItem *parent = nullptr); + + bool isTristate() const; + void setTristate(bool tristate); + + Qt::CheckState checkState() const; + void setCheckState(Qt::CheckState state); + +Q_SIGNALS: + void tristateChanged(); + void checkStateChanged(); + // 2.4 (Qt 5.11) + Q_REVISION(2, 4) void nextCheckStateChanged(); + +protected: + QFont defaultFont() const override; + + void buttonChange(ButtonChange change) override; + void nextCheckState() override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickCheckDelegate) + Q_DECLARE_PRIVATE(QQuickCheckDelegate) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickCheckDelegate) + +#endif // QQUICKCHECKDELEGATE_P_H diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp new file mode 100644 index 00000000000..6e36c080814 --- /dev/null +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -0,0 +1,2221 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcombobox_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickabstractbutton_p.h" +#include "qquickabstractbutton_p_p.h" +#include "qquickpopup_p_p.h" +#include "qquickdeferredexecute_p_p.h" + +#include <QtCore/qregularexpression.h> +#include <QtCore/qabstractitemmodel.h> +#include <QtCore/qglobal.h> +#include <QtGui/qinputmethod.h> +#include <QtGui/qguiapplication.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtQml/qjsvalue.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/private/qlazilyallocated_p.h> +#include <private/qqmldelegatemodel_p.h> +#include <QtQuick/private/qquickaccessibleattached_p.h> +#include <QtQuick/private/qquickevents_p_p.h> +#include <QtQuick/private/qquicktextinput_p.h> +#include <QtQuick/private/qquicktextinput_p_p.h> +#include <QtQuick/private/qquickitemview_p.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcCalculateWidestTextWidth, "qt.quick.controls.combobox.calculatewidesttextwidth") + +/*! + \qmltype ComboBox + \inherits Control +//! \instantiates QQuickComboBox + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-input + \ingroup qtquickcontrols2-focusscopes + \brief Combined button and popup list for selecting options. + + \image qtquickcontrols2-combobox.gif + + ComboBox is a combined button and popup list. It provides a means of + presenting a list of options to the user in a way that takes up the + minimum amount of screen space. + + ComboBox is populated with a data model. The data model is commonly + a JavaScript array, a \l ListModel or an integer, but other types + of \l {qml-data-models}{data models} are also supported. + + \code + ComboBox { + model: ["First", "Second", "Third"] + } + \endcode + + \section1 Editable ComboBox + + ComboBox can be made \l editable. An editable combo box auto-completes + its text based on what is available in the model. + + The following example demonstrates appending content to an editable + combo box by reacting to the \l accepted signal. + + \snippet qtquickcontrols2-combobox-accepted.qml combobox + + \section1 ComboBox's Popup + + By default, clicking outside of ComboBox's popup will close it, and the + event is propagated to items lower in the stacking order. To prevent the + popup from closing, set its \l {Popup::}{closePolicy}: + + \snippet qtquickcontrols2-combobox-popup.qml closePolicy + + To prevent event propagation, set its \l {Popup::}{modal} property to + \c true: + + \snippet qtquickcontrols2-combobox-popup.qml modal + + \section1 ComboBox Model Roles + + ComboBox is able to visualize standard \l {qml-data-models}{data models} + that provide the \c modelData role: + \list + \li models that have only one role + \li models that do not have named roles (JavaScript array, integer) + \endlist + + When using models that have multiple named roles, ComboBox must be configured + to use a specific \l {textRole}{text role} for its \l {displayText}{display text} + and \l delegate instances. If you want to use a role of the model item + that corresponds to the text role, set \l valueRole. The \l currentValue + property and \l indexOfValue() method can then be used to get information + about those values. + + For example: + + \snippet qtquickcontrols2-combobox-valuerole.qml file + + \note If ComboBox is assigned a data model that has multiple named roles, but + \l textRole is not defined, ComboBox is unable to visualize it and throws a + \c {ReferenceError: modelData is not defined}. + + \sa {Customizing ComboBox}, {Input Controls}, {Focus Management in Qt Quick Controls} +*/ + +/*! + \qmlsignal void QtQuick.Controls::ComboBox::activated(int index) + + This signal is emitted when the item at \a index is activated by the user. + + An item is activated when it is selected while the popup is open, + causing the popup to close (and \l currentIndex to change), + or while the popup is closed and the combo box is navigated via + keyboard, causing the \l currentIndex to change. + The \l currentIndex property is set to \a index. + + \sa currentIndex +*/ + +/*! + \qmlsignal void QtQuick.Controls::ComboBox::highlighted(int index) + + This signal is emitted when the item at \a index in the popup list is highlighted by the user. + + The highlighted signal is only emitted when the popup is open and an item + is highlighted, but not necessarily \l activated. + + \sa highlightedIndex +*/ + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlsignal void QtQuick.Controls::ComboBox::accepted() + + This signal is emitted when the \uicontrol Return or \uicontrol Enter key is pressed + on an \l editable combo box. + + You can handle this signal in order to add the newly entered + item to the model, for example: + + \snippet qtquickcontrols2-combobox-accepted.qml combobox + + Before the signal is emitted, a check is done to see if the string + exists in the model. If it does, \l currentIndex will be set to its index, + and \l currentText to the string itself. + + After the signal has been emitted, and if the first check failed (that is, + the item did not exist), another check will be done to see if the item was + added by the signal handler. If it was, the \l currentIndex and + \l currentText are updated accordingly. Otherwise, they will be set to + \c -1 and \c "", respectively. + + \note If there is a \l validator set on the combo box, the signal will only be + emitted if the input is in an acceptable state. +*/ + +namespace { + enum Activation { NoActivate, Activate }; + enum Highlighting { NoHighlight, Highlight }; +} + +class QQuickComboBoxDelegateModel : public QQmlDelegateModel +{ +public: + explicit QQuickComboBoxDelegateModel(QQuickComboBox *combo); + QVariant variantValue(int index, const QString &role) override; + +private: + QQuickComboBox *combo = nullptr; +}; + +QQuickComboBoxDelegateModel::QQuickComboBoxDelegateModel(QQuickComboBox *combo) + : QQmlDelegateModel(qmlContext(combo), combo), + combo(combo) +{ +} + +QVariant QQuickComboBoxDelegateModel::variantValue(int index, const QString &role) +{ + const QVariant model = combo->model(); + if (model.userType() == QMetaType::QVariantList) { + QVariant object = model.toList().value(index); + if (object.userType() == QMetaType::QVariantMap) { + const QVariantMap data = object.toMap(); + if (data.count() == 1 && role == QLatin1String("modelData")) + return data.first(); + return data.value(role); + } else if (object.userType() == QMetaType::QObjectStar) { + const QObject *data = object.value<QObject *>(); + if (data && role != QLatin1String("modelData")) + return data->property(role.toUtf8()); + } + } + return QQmlDelegateModel::variantValue(index, role); +} + +class QQuickComboBoxPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickComboBox) + +public: + bool isPopupVisible() const; + void showPopup(); + void hidePopup(bool accept); + void togglePopup(bool accept); + void popupVisibleChanged(); + + void itemClicked(); + void itemHovered(); + + void createdItem(int index, QObject *object); + void modelUpdated(); + void countChanged(); + + QString effectiveTextRole() const; + void updateEditText(); + void updateCurrentText(); + void updateCurrentValue(); + void updateCurrentTextAndValue(); + void updateAcceptableInput(); + + bool isValidIndex(int index) const; + + void acceptInput(); + QString tryComplete(const QString &inputText); + + void incrementCurrentIndex(); + void decrementCurrentIndex(); + void setCurrentIndex(int index, Activation activate); + void updateHighlightedIndex(); + void setHighlightedIndex(int index, Highlighting highlight); + + void keySearch(const QString &text); + int match(int start, const QString &text, Qt::MatchFlags flags) const; + + void createDelegateModel(); + + void handlePress(const QPointF &point) override; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + void handleUngrab() override; + + void cancelIndicator(); + void executeIndicator(bool complete = false); + + void cancelPopup(); + void executePopup(bool complete = false); + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + void setInputMethodHints(Qt::InputMethodHints hints, bool force = false); + + virtual qreal getContentWidth() const override; + qreal calculateWidestTextWidth() const; + void maybeUpdateImplicitContentWidth(); + + static void hideOldPopup(QQuickPopup *popup); + + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::ComboBox); } + + bool flat = false; + bool down = false; + bool hasDown = false; + bool pressed = false; + bool ownModel = false; + bool keyNavigating = false; + bool hasDisplayText = false; + bool hasCurrentIndex = false; + bool hasCalculatedWidestText = false; + int highlightedIndex = -1; + int currentIndex = -1; + QQuickComboBox::ImplicitContentWidthPolicy implicitContentWidthPolicy = QQuickComboBox::ContentItemImplicitWidth; + QVariant model; + QString textRole; + QString currentText; + QString displayText; + QString valueRole; + QVariant currentValue; + QQuickItem *pressedItem = nullptr; + QQmlInstanceModel *delegateModel = nullptr; + QQmlComponent *delegate = nullptr; + QQuickDeferredPointer<QQuickItem> indicator; + QQuickDeferredPointer<QQuickPopup> popup; + bool m_acceptableInput = true; + + struct ExtraData { + bool editable = false; + bool accepting = false; + bool allowComplete = false; + bool selectTextByMouse = false; + Qt::InputMethodHints inputMethodHints = Qt::ImhNone; + QString editText; + QValidator *validator = nullptr; + }; + QLazilyAllocated<ExtraData> extra; +}; + +bool QQuickComboBoxPrivate::isPopupVisible() const +{ + return popup && popup->isVisible(); +} + +void QQuickComboBoxPrivate::showPopup() +{ + if (!popup) + executePopup(true); + + if (popup && !popup->isVisible()) + popup->open(); +} + +void QQuickComboBoxPrivate::hidePopup(bool accept) +{ + Q_Q(QQuickComboBox); + if (accept) { + q->setCurrentIndex(highlightedIndex); + emit q->activated(currentIndex); + } + if (popup && popup->isVisible()) + popup->close(); +} + +void QQuickComboBoxPrivate::togglePopup(bool accept) +{ + if (!popup || !popup->isVisible()) + showPopup(); + else + hidePopup(accept); +} + +void QQuickComboBoxPrivate::popupVisibleChanged() +{ + Q_Q(QQuickComboBox); + if (isPopupVisible()) + QGuiApplication::inputMethod()->reset(); + + QQuickItemView *itemView = popup->findChild<QQuickItemView *>(); + if (itemView) + itemView->setHighlightRangeMode(QQuickItemView::NoHighlightRange); + + updateHighlightedIndex(); + + if (itemView) + itemView->positionViewAtIndex(highlightedIndex, QQuickItemView::Beginning); + + if (!hasDown) { + q->setDown(pressed || isPopupVisible()); + hasDown = false; + } +} + +void QQuickComboBoxPrivate::itemClicked() +{ + Q_Q(QQuickComboBox); + int index = delegateModel->indexOf(q->sender(), nullptr); + if (index != -1) { + setHighlightedIndex(index, Highlight); + hidePopup(true); + } +} + +void QQuickComboBoxPrivate::itemHovered() +{ + Q_Q(QQuickComboBox); + if (keyNavigating) + return; + + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->sender()); + if (!button || !button->isHovered() || !button->isEnabled() || QQuickAbstractButtonPrivate::get(button)->touchId != -1) + return; + + int index = delegateModel->indexOf(button, nullptr); + if (index != -1) { + setHighlightedIndex(index, Highlight); + + if (QQuickItemView *itemView = popup->findChild<QQuickItemView *>()) + itemView->positionViewAtIndex(index, QQuickItemView::Contain); + } +} + +void QQuickComboBoxPrivate::createdItem(int index, QObject *object) +{ + Q_Q(QQuickComboBox); + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (item && !item->parentItem()) { + if (popup) + item->setParentItem(popup->contentItem()); + else + item->setParentItem(q); + QQuickItemPrivate::get(item)->setCulled(true); + } + + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(object); + if (button) { + button->setFocusPolicy(Qt::NoFocus); + connect(button, &QQuickAbstractButton::clicked, this, &QQuickComboBoxPrivate::itemClicked); + connect(button, &QQuickAbstractButton::hoveredChanged, this, &QQuickComboBoxPrivate::itemHovered); + } + + if (index == currentIndex && !q->isEditable()) + updateCurrentTextAndValue(); +} + +void QQuickComboBoxPrivate::modelUpdated() +{ + if (componentComplete && (!extra.isAllocated() || !extra->accepting)) { + updateCurrentTextAndValue(); + + if (implicitContentWidthPolicy == QQuickComboBox::WidestText) + updateImplicitContentSize(); + } +} + +void QQuickComboBoxPrivate::countChanged() +{ + Q_Q(QQuickComboBox); + if (q->count() == 0) + q->setCurrentIndex(-1); + emit q->countChanged(); +} + +QString QQuickComboBoxPrivate::effectiveTextRole() const +{ + return textRole.isEmpty() ? QStringLiteral("modelData") : textRole; +} + +void QQuickComboBoxPrivate::updateEditText() +{ + Q_Q(QQuickComboBox); + QQuickTextInput *input = qobject_cast<QQuickTextInput *>(contentItem); + if (!input) + return; + + const QString text = input->text(); + + if (extra.isAllocated() && extra->allowComplete && !text.isEmpty()) { + const QString completed = tryComplete(text); + if (completed.length() > text.length()) { + input->setText(completed); + // This will select the text backwards. + input->select(completed.length(), text.length()); + return; + } + } + q->setEditText(text); +} + +void QQuickComboBoxPrivate::updateCurrentText() +{ + Q_Q(QQuickComboBox); + const QString text = q->textAt(currentIndex); + if (currentText != text) { + currentText = text; + if (!hasDisplayText) + q->maybeSetAccessibleName(text); + emit q->currentTextChanged(); + } + if (!hasDisplayText && displayText != text) { + displayText = text; + emit q->displayTextChanged(); + } + if (!extra.isAllocated() || !extra->accepting) + q->setEditText(currentText); +} + +void QQuickComboBoxPrivate::updateCurrentValue() +{ + Q_Q(QQuickComboBox); + const QVariant value = q->valueAt(currentIndex); + if (currentValue == value) + return; + + currentValue = value; + emit q->currentValueChanged(); +} + +void QQuickComboBoxPrivate::updateCurrentTextAndValue() +{ + updateCurrentText(); + updateCurrentValue(); +} + +void QQuickComboBoxPrivate::updateAcceptableInput() +{ + Q_Q(QQuickComboBox); + + if (!contentItem) + return; + + const QQuickTextInput *textInputContentItem = qobject_cast<QQuickTextInput *>(contentItem); + + if (!textInputContentItem) + return; + + const bool newValue = textInputContentItem->hasAcceptableInput(); + + if (m_acceptableInput != newValue) { + m_acceptableInput = newValue; + emit q->acceptableInputChanged(); + } +} + +bool QQuickComboBoxPrivate::isValidIndex(int index) const +{ + return delegateModel && index >= 0 && index < delegateModel->count(); +} + +void QQuickComboBoxPrivate::acceptInput() +{ + Q_Q(QQuickComboBox); + int idx = q->find(extra.value().editText, Qt::MatchFixedString); + if (idx > -1) { + // The item that was accepted already exists, so make it the current item. + q->setCurrentIndex(idx); + // After accepting text that matches an existing entry, the selection should be cleared. + QQuickTextInput *input = qobject_cast<QQuickTextInput *>(contentItem); + if (input) { + const auto text = input->text(); + input->select(text.size(), text.size()); + } + } + + extra.value().accepting = true; + emit q->accepted(); + + // The user might have added the item since it didn't exist, so check again + // to see if we can select that new item. + if (idx == -1) + q->setCurrentIndex(q->find(extra.value().editText, Qt::MatchFixedString)); + extra.value().accepting = false; +} + +QString QQuickComboBoxPrivate::tryComplete(const QString &input) +{ + Q_Q(QQuickComboBox); + QString match; + + const int itemCount = q->count(); + for (int idx = 0; idx < itemCount; ++idx) { + const QString text = q->textAt(idx); + if (!text.startsWith(input, Qt::CaseInsensitive)) + continue; + + // either the first or the shortest match + if (match.isEmpty() || text.length() < match.length()) + match = text; + } + + if (match.isEmpty()) + return input; + + return input + match.mid(input.length()); +} + +void QQuickComboBoxPrivate::setCurrentIndex(int index, Activation activate) +{ + Q_Q(QQuickComboBox); + if (currentIndex == index) + return; + + currentIndex = index; + emit q->currentIndexChanged(); + + if (componentComplete) + updateCurrentTextAndValue(); + + if (activate) + emit q->activated(index); +} + +void QQuickComboBoxPrivate::incrementCurrentIndex() +{ + Q_Q(QQuickComboBox); + if (extra.isAllocated()) + extra->allowComplete = false; + if (isPopupVisible()) { + if (highlightedIndex < q->count() - 1) + setHighlightedIndex(highlightedIndex + 1, Highlight); + } else { + if (currentIndex < q->count() - 1) + setCurrentIndex(currentIndex + 1, Activate); + } + if (extra.isAllocated()) + extra->allowComplete = true; +} + +void QQuickComboBoxPrivate::decrementCurrentIndex() +{ + if (extra.isAllocated()) + extra->allowComplete = false; + if (isPopupVisible()) { + if (highlightedIndex > 0) + setHighlightedIndex(highlightedIndex - 1, Highlight); + } else { + if (currentIndex > 0) + setCurrentIndex(currentIndex - 1, Activate); + } + if (extra.isAllocated()) + extra->allowComplete = true; +} + +void QQuickComboBoxPrivate::updateHighlightedIndex() +{ + setHighlightedIndex(popup->isVisible() ? currentIndex : -1, NoHighlight); +} + +void QQuickComboBoxPrivate::setHighlightedIndex(int index, Highlighting highlight) +{ + Q_Q(QQuickComboBox); + if (highlightedIndex == index) + return; + + highlightedIndex = index; + emit q->highlightedIndexChanged(); + + if (highlight) + emit q->highlighted(index); +} + +void QQuickComboBoxPrivate::keySearch(const QString &text) +{ + const int startIndex = isPopupVisible() ? highlightedIndex : currentIndex; + const int index = match(startIndex + 1, text, Qt::MatchStartsWith | Qt::MatchWrap); + if (index != -1) { + if (isPopupVisible()) + setHighlightedIndex(index, Highlight); + else + setCurrentIndex(index, Activate); + } +} + +int QQuickComboBoxPrivate::match(int start, const QString &text, Qt::MatchFlags flags) const +{ + Q_Q(const QQuickComboBox); + uint matchType = flags & 0x0F; + bool wrap = flags & Qt::MatchWrap; + Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; + QRegularExpression::PatternOptions options = flags & Qt::MatchCaseSensitive ? QRegularExpression::NoPatternOption + : QRegularExpression::CaseInsensitiveOption; + int from = start; + int to = q->count(); + + // iterates twice if wrapping + for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) { + for (int idx = from; idx < to; ++idx) { + QString t = q->textAt(idx); + switch (matchType) { + case Qt::MatchExactly: + if (t == text) + return idx; + break; + case Qt::MatchRegularExpression: { + QRegularExpression rx(QRegularExpression::anchoredPattern(text), options); + if (rx.match(t).hasMatch()) + return idx; + break; + } + case Qt::MatchWildcard: { + QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(text), + options); + if (rx.match(t).hasMatch()) + return idx; + break; + } + case Qt::MatchStartsWith: + if (t.startsWith(text, cs)) + return idx; + break; + case Qt::MatchEndsWith: + if (t.endsWith(text, cs)) + return idx; + break; + case Qt::MatchFixedString: + if (t.compare(text, cs) == 0) + return idx; + break; + case Qt::MatchContains: + default: + if (t.contains(text, cs)) + return idx; + break; + } + } + // prepare for the next iteration + from = 0; + to = start; + } + return -1; +} + +void QQuickComboBoxPrivate::createDelegateModel() +{ + Q_Q(QQuickComboBox); + bool ownedOldModel = ownModel; + QQmlInstanceModel* oldModel = delegateModel; + if (oldModel) { + disconnect(delegateModel, &QQmlInstanceModel::countChanged, this, &QQuickComboBoxPrivate::countChanged); + disconnect(delegateModel, &QQmlInstanceModel::modelUpdated, this, &QQuickComboBoxPrivate::modelUpdated); + disconnect(delegateModel, &QQmlInstanceModel::createdItem, this, &QQuickComboBoxPrivate::createdItem); + } + + ownModel = false; + delegateModel = model.value<QQmlInstanceModel *>(); + + if (!delegateModel && model.isValid()) { + QQmlDelegateModel *dataModel = new QQuickComboBoxDelegateModel(q); + dataModel->setModel(model); + dataModel->setDelegate(delegate); + if (q->isComponentComplete()) + dataModel->componentComplete(); + + ownModel = true; + delegateModel = dataModel; + } + + if (delegateModel) { + connect(delegateModel, &QQmlInstanceModel::countChanged, this, &QQuickComboBoxPrivate::countChanged); + connect(delegateModel, &QQmlInstanceModel::modelUpdated, this, &QQuickComboBoxPrivate::modelUpdated); + connect(delegateModel, &QQmlInstanceModel::createdItem, this, &QQuickComboBoxPrivate::createdItem); + } + + emit q->delegateModelChanged(); + + if (ownedOldModel) + delete oldModel; +} + +void QQuickComboBoxPrivate::handlePress(const QPointF &point) +{ + Q_Q(QQuickComboBox); + QQuickControlPrivate::handlePress(point); + q->setPressed(true); +} + +void QQuickComboBoxPrivate::handleMove(const QPointF &point) +{ + Q_Q(QQuickComboBox); + QQuickControlPrivate::handleMove(point); + q->setPressed(q->contains(point)); +} + +void QQuickComboBoxPrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickComboBox); + QQuickControlPrivate::handleRelease(point); + if (pressed) { + q->setPressed(false); + togglePopup(false); + } +} + +void QQuickComboBoxPrivate::handleUngrab() +{ + Q_Q(QQuickComboBox); + QQuickControlPrivate::handleUngrab(); + q->setPressed(false); +} + +static inline QString indicatorName() { return QStringLiteral("indicator"); } + +void QQuickComboBoxPrivate::cancelIndicator() +{ + Q_Q(QQuickComboBox); + quickCancelDeferred(q, indicatorName()); +} + +void QQuickComboBoxPrivate::executeIndicator(bool complete) +{ + Q_Q(QQuickComboBox); + if (indicator.wasExecuted()) + return; + + if (!indicator || complete) + quickBeginDeferred(q, indicatorName(), indicator); + if (complete) + quickCompleteDeferred(q, indicatorName(), indicator); +} + +static inline QString popupName() { return QStringLiteral("popup"); } + +void QQuickComboBoxPrivate::cancelPopup() +{ + Q_Q(QQuickComboBox); + quickCancelDeferred(q, popupName()); +} + +void QQuickComboBoxPrivate::executePopup(bool complete) +{ + Q_Q(QQuickComboBox); + if (popup.wasExecuted()) + return; + + if (!popup || complete) + quickBeginDeferred(q, popupName(), popup); + if (complete) + quickCompleteDeferred(q, popupName(), popup); +} + +void QQuickComboBoxPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickComboBox); + QQuickControlPrivate::itemImplicitWidthChanged(item); + if (item == indicator) + emit q->implicitIndicatorWidthChanged(); +} + +void QQuickComboBoxPrivate::setInputMethodHints(Qt::InputMethodHints hints, bool force) +{ + Q_Q(QQuickComboBox); + if (!force && hints == q->inputMethodHints()) + return; + + extra.value().inputMethodHints = hints; + emit q->inputMethodHintsChanged(); +} + +void QQuickComboBoxPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickComboBox); + QQuickControlPrivate::itemImplicitHeightChanged(item); + if (item == indicator) + emit q->implicitIndicatorHeightChanged(); +} + +qreal QQuickComboBoxPrivate::getContentWidth() const +{ + if (componentComplete) { + switch (implicitContentWidthPolicy) { + case QQuickComboBox::WidestText: + return calculateWidestTextWidth(); + case QQuickComboBox::WidestTextWhenCompleted: + if (!hasCalculatedWidestText) + return calculateWidestTextWidth(); + break; + default: + break; + } + } + + return QQuickControlPrivate::getContentWidth(); +} + +qreal QQuickComboBoxPrivate::calculateWidestTextWidth() const +{ + Q_Q(const QQuickComboBox); + if (!componentComplete) + return 0; + + const int count = q->count(); + if (count == 0) + return 0; + + auto textInput = qobject_cast<QQuickTextInput*>(contentItem); + if (!textInput) + return 0; + + qCDebug(lcCalculateWidestTextWidth) << "calculating widest text from" << count << "items..."; + + // Avoid the index check and repeated calls to effectiveTextRole() + // that would result from calling textAt() in a loop. + const QString textRole = effectiveTextRole(); + auto textInputPrivate = QQuickTextInputPrivate::get(textInput); + qreal widest = 0; + for (int i = 0; i < count; ++i) { + const QString text = delegateModel->stringValue(i, textRole); + const qreal textImplicitWidth = textInputPrivate->calculateImplicitWidthForText(text); + widest = qMax(widest, textImplicitWidth); + } + + qCDebug(lcCalculateWidestTextWidth) << "... widest text is" << widest; + return widest; +} + +/*! + \internal + + If the user requested it (and we haven't already done it, depending on the policy), + update the implicit content width to the largest text in the model. +*/ +void QQuickComboBoxPrivate::maybeUpdateImplicitContentWidth() +{ + if (!componentComplete) + return; + + if (implicitContentWidthPolicy == QQuickComboBox::ContentItemImplicitWidth + || (implicitContentWidthPolicy == QQuickComboBox::WidestTextWhenCompleted && hasCalculatedWidestText)) + return; + + updateImplicitContentWidth(); + hasCalculatedWidestText = true; +} + +void QQuickComboBoxPrivate::hideOldPopup(QQuickPopup *popup) +{ + if (!popup) + return; + + qCDebug(lcItemManagement) << "hiding old popup" << popup; + + popup->setVisible(false); + popup->setParentItem(nullptr); +#if QT_CONFIG(accessibility) + // Remove the item from the accessibility tree. + QQuickAccessibleAttached *accessible = accessibleAttached(popup); + if (accessible) + accessible->setIgnored(true); +#endif +} + +QQuickComboBox::QQuickComboBox(QQuickItem *parent) + : QQuickControl(*(new QQuickComboBoxPrivate), parent) +{ + setFocusPolicy(Qt::StrongFocus); + setFlag(QQuickItem::ItemIsFocusScope); + setAcceptedMouseButtons(Qt::LeftButton); +#if QT_CONFIG(cursor) + setCursor(Qt::ArrowCursor); +#endif + Q_D(QQuickComboBox); + d->setInputMethodHints(Qt::ImhNoPredictiveText, true); +} + +QQuickComboBox::~QQuickComboBox() +{ + Q_D(QQuickComboBox); + d->removeImplicitSizeListener(d->indicator); + if (d->popup) { + // Disconnect visibleChanged() to avoid a spurious highlightedIndexChanged() signal + // emission during the destruction of the (visible) popup. (QTBUG-57650) + QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); + QQuickComboBoxPrivate::hideOldPopup(d->popup); + d->popup = nullptr; + } +} + +/*! + \readonly + \qmlproperty int QtQuick.Controls::ComboBox::count + + This property holds the number of items in the combo box. +*/ +int QQuickComboBox::count() const +{ + Q_D(const QQuickComboBox); + return d->delegateModel ? d->delegateModel->count() : 0; +} + +/*! + \qmlproperty model QtQuick.Controls::ComboBox::model + + This property holds the model providing data for the combo box. + + \code + ComboBox { + textRole: "key" + model: ListModel { + ListElement { key: "First"; value: 123 } + ListElement { key: "Second"; value: 456 } + ListElement { key: "Third"; value: 789 } + } + } + \endcode + + \sa textRole, {qml-data-models}{Data Models} +*/ +QVariant QQuickComboBox::model() const +{ + Q_D(const QQuickComboBox); + return d->model; +} + +void QQuickComboBox::setModel(const QVariant& m) +{ + Q_D(QQuickComboBox); + QVariant model = m; + if (model.userType() == qMetaTypeId<QJSValue>()) + model = model.value<QJSValue>().toVariant(); + + if (d->model == model) + return; + + if (QAbstractItemModel* aim = qvariant_cast<QAbstractItemModel *>(d->model)) { + QObjectPrivate::disconnect(aim, &QAbstractItemModel::dataChanged, + d, QOverload<>::of(&QQuickComboBoxPrivate::updateCurrentTextAndValue)); + } + if (QAbstractItemModel* aim = qvariant_cast<QAbstractItemModel *>(model)) { + QObjectPrivate::connect(aim, &QAbstractItemModel::dataChanged, + d, QOverload<>::of(&QQuickComboBoxPrivate::updateCurrentTextAndValue)); + } + + d->model = model; + d->createDelegateModel(); + emit countChanged(); + if (isComponentComplete()) { + setCurrentIndex(count() > 0 ? 0 : -1); + d->updateCurrentTextAndValue(); + } + emit modelChanged(); + + d->maybeUpdateImplicitContentWidth(); +} + +/*! + \internal + \qmlproperty model QtQuick.Controls::ComboBox::delegateModel + + This property holds the model providing delegate instances for the combo box. +*/ +QQmlInstanceModel *QQuickComboBox::delegateModel() const +{ + Q_D(const QQuickComboBox); + return d->delegateModel; +} + + +/*! + \readonly + \qmlproperty bool QtQuick.Controls::ComboBox::pressed + + This property holds whether the combo box button is physically pressed. + A button can be pressed by either touch or key events. + + \sa down +*/ +bool QQuickComboBox::isPressed() const +{ + Q_D(const QQuickComboBox); + return d->pressed; +} + +void QQuickComboBox::setPressed(bool pressed) +{ + Q_D(QQuickComboBox); + if (d->pressed == pressed) + return; + + d->pressed = pressed; + emit pressedChanged(); + + if (!d->hasDown) { + setDown(d->pressed || d->isPopupVisible()); + d->hasDown = false; + } +} + +/*! + \readonly + \qmlproperty int QtQuick.Controls::ComboBox::highlightedIndex + + This property holds the index of the highlighted item in the combo box popup list. + + When a highlighted item is activated, the popup is closed, \l currentIndex + is set to \c highlightedIndex, and the value of this property is reset to + \c -1, as there is no longer a highlighted item. + + \sa highlighted(), currentIndex +*/ +int QQuickComboBox::highlightedIndex() const +{ + Q_D(const QQuickComboBox); + return d->highlightedIndex; +} + +/*! + \qmlproperty int QtQuick.Controls::ComboBox::currentIndex + + This property holds the index of the current item in the combo box. + + The default value is \c -1 when \l count is \c 0, and \c 0 otherwise. + + \sa activated(), currentText, highlightedIndex +*/ +int QQuickComboBox::currentIndex() const +{ + Q_D(const QQuickComboBox); + return d->currentIndex; +} + +void QQuickComboBox::setCurrentIndex(int index) +{ + Q_D(QQuickComboBox); + d->hasCurrentIndex = true; + d->setCurrentIndex(index, NoActivate); +} + +/*! + \readonly + \qmlproperty string QtQuick.Controls::ComboBox::currentText + + This property holds the text of the current item in the combo box. + + \sa currentIndex, displayText, textRole, editText +*/ +QString QQuickComboBox::currentText() const +{ + Q_D(const QQuickComboBox); + return d->currentText; +} + +/*! + \qmlproperty string QtQuick.Controls::ComboBox::displayText + + This property holds the text that is displayed on the combo box button. + + By default, the display text presents the current selection. That is, + it follows the text of the current item. However, the default display + text can be overridden with a custom value. + + \code + ComboBox { + currentIndex: 1 + displayText: "Size: " + currentText + model: ["S", "M", "L"] + } + \endcode + + \sa currentText, textRole +*/ +QString QQuickComboBox::displayText() const +{ + Q_D(const QQuickComboBox); + return d->displayText; +} + +void QQuickComboBox::setDisplayText(const QString &text) +{ + Q_D(QQuickComboBox); + d->hasDisplayText = true; + if (d->displayText == text) + return; + + d->displayText = text; + maybeSetAccessibleName(text); + emit displayTextChanged(); +} + +void QQuickComboBox::resetDisplayText() +{ + Q_D(QQuickComboBox); + if (!d->hasDisplayText) + return; + + d->hasDisplayText = false; + d->updateCurrentText(); +} + + +/*! + \qmlproperty string QtQuick.Controls::ComboBox::textRole + + This property holds the model role used for populating the combo box. + + When the model has multiple roles, \c textRole can be set to determine + which role should be displayed. + + \sa model, currentText, displayText, {ComboBox Model Roles} +*/ +QString QQuickComboBox::textRole() const +{ + Q_D(const QQuickComboBox); + return d->textRole; +} + +void QQuickComboBox::setTextRole(const QString &role) +{ + Q_D(QQuickComboBox); + if (d->textRole == role) + return; + + d->textRole = role; + if (isComponentComplete()) + d->updateCurrentText(); + emit textRoleChanged(); +} + +/*! + \since QtQuick.Controls 2.14 (Qt 5.14) + \qmlproperty string QtQuick.Controls::ComboBox::valueRole + + This property holds the model role used for storing the value associated + with each item in the model. + + For an example of how to use this property, see \l {ComboBox Model Roles}. + + \sa model, currentValue +*/ +QString QQuickComboBox::valueRole() const +{ + Q_D(const QQuickComboBox); + return d->valueRole; +} + +void QQuickComboBox::setValueRole(const QString &role) +{ + Q_D(QQuickComboBox); + if (d->valueRole == role) + return; + + d->valueRole = role; + if (isComponentComplete()) + d->updateCurrentValue(); + emit valueRoleChanged(); +} + +/*! + \qmlproperty Component QtQuick.Controls::ComboBox::delegate + + This property holds a delegate that presents an item in the combo box popup. + + It is recommended to use \l ItemDelegate (or any other \l AbstractButton + derivatives) as the delegate. This ensures that the interaction works as + expected, and the popup will automatically close when appropriate. When + other types are used as the delegate, the popup must be closed manually. + For example, if \l MouseArea is used: + + \code + delegate: Rectangle { + // ... + MouseArea { + // ... + onClicked: comboBox.popup.close() + } + } + \endcode + + \sa ItemDelegate, {Customizing ComboBox} +*/ +QQmlComponent *QQuickComboBox::delegate() const +{ + Q_D(const QQuickComboBox); + return d->delegate; +} + +void QQuickComboBox::setDelegate(QQmlComponent* delegate) +{ + Q_D(QQuickComboBox); + if (d->delegate == delegate) + return; + + delete d->delegate; + d->delegate = delegate; + QQmlDelegateModel *delegateModel = qobject_cast<QQmlDelegateModel*>(d->delegateModel); + if (delegateModel) + delegateModel->setDelegate(d->delegate); + emit delegateChanged(); +} + +/*! + \qmlproperty Item QtQuick.Controls::ComboBox::indicator + + This property holds the drop indicator item. + + \sa {Customizing ComboBox} +*/ +QQuickItem *QQuickComboBox::indicator() const +{ + QQuickComboBoxPrivate *d = const_cast<QQuickComboBoxPrivate *>(d_func()); + if (!d->indicator) + d->executeIndicator(); + return d->indicator; +} + +void QQuickComboBox::setIndicator(QQuickItem *indicator) +{ + Q_D(QQuickComboBox); + if (d->indicator == indicator) + return; + + if (!d->indicator.isExecuting()) + d->cancelIndicator(); + + const qreal oldImplicitIndicatorWidth = implicitIndicatorWidth(); + const qreal oldImplicitIndicatorHeight = implicitIndicatorHeight(); + + d->removeImplicitSizeListener(d->indicator); + QQuickControlPrivate::hideOldItem(d->indicator); + d->indicator = indicator; + if (indicator) { + if (!indicator->parentItem()) + indicator->setParentItem(this); + d->addImplicitSizeListener(indicator); + } + + if (!qFuzzyCompare(oldImplicitIndicatorWidth, implicitIndicatorWidth())) + emit implicitIndicatorWidthChanged(); + if (!qFuzzyCompare(oldImplicitIndicatorHeight, implicitIndicatorHeight())) + emit implicitIndicatorHeightChanged(); + if (!d->indicator.isExecuting()) + emit indicatorChanged(); +} + +/*! + \qmlproperty Popup QtQuick.Controls::ComboBox::popup + + This property holds the popup. + + The popup can be opened or closed manually, if necessary: + + \code + onSpecialEvent: comboBox.popup.close() + \endcode + + \sa {Customizing ComboBox} +*/ +QQuickPopup *QQuickComboBox::popup() const +{ + QQuickComboBoxPrivate *d = const_cast<QQuickComboBoxPrivate *>(d_func()); + if (!d->popup) + d->executePopup(isComponentComplete()); + return d->popup; +} + +void QQuickComboBox::setPopup(QQuickPopup *popup) +{ + Q_D(QQuickComboBox); + if (d->popup == popup) + return; + + if (!d->popup.isExecuting()) + d->cancelPopup(); + + if (d->popup) { + QObjectPrivate::disconnect(d->popup.data(), &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); + QQuickComboBoxPrivate::hideOldPopup(d->popup); + } + if (popup) { + QQuickPopupPrivate::get(popup)->allowVerticalFlip = true; + popup->setClosePolicy(QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent); + QObjectPrivate::connect(popup, &QQuickPopup::visibleChanged, d, &QQuickComboBoxPrivate::popupVisibleChanged); + + if (QQuickItemView *itemView = popup->findChild<QQuickItemView *>()) + itemView->setHighlightRangeMode(QQuickItemView::NoHighlightRange); + } + d->popup = popup; + if (!d->popup.isExecuting()) + emit popupChanged(); +} + +/*! + \since QtQuick.Controls 2.1 (Qt 5.8) + \qmlproperty bool QtQuick.Controls::ComboBox::flat + + This property holds whether the combo box button is flat. + + A flat combo box button does not draw a background unless it is interacted + with. In comparison to normal combo boxes, flat combo boxes provide looks + that make them stand out less from the rest of the UI. For instance, when + placing a combo box into a tool bar, it may be desirable to make the combo + box flat so it matches better with the flat looks of tool buttons. + + The default value is \c false. +*/ +bool QQuickComboBox::isFlat() const +{ + Q_D(const QQuickComboBox); + return d->flat; +} + +void QQuickComboBox::setFlat(bool flat) +{ + Q_D(QQuickComboBox); + if (d->flat == flat) + return; + + d->flat = flat; + emit flatChanged(); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty bool QtQuick.Controls::ComboBox::down + + This property holds whether the combo box button is visually down. + + Unless explicitly set, this property is \c true when either \c pressed + or \c popup.visible is \c true. To return to the default value, set this + property to \c undefined. + + \sa pressed, popup +*/ +bool QQuickComboBox::isDown() const +{ + Q_D(const QQuickComboBox); + return d->down; +} + +void QQuickComboBox::setDown(bool down) +{ + Q_D(QQuickComboBox); + d->hasDown = true; + + if (d->down == down) + return; + + d->down = down; + emit downChanged(); +} + +void QQuickComboBox::resetDown() +{ + Q_D(QQuickComboBox); + if (!d->hasDown) + return; + + setDown(d->pressed || d->isPopupVisible()); + d->hasDown = false; +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty bool QtQuick.Controls::ComboBox::editable + + This property holds whether the combo box is editable. + + The default value is \c false. + + \sa validator +*/ +bool QQuickComboBox::isEditable() const +{ + Q_D(const QQuickComboBox); + return d->extra.isAllocated() && d->extra->editable; +} + +void QQuickComboBox::setEditable(bool editable) +{ + Q_D(QQuickComboBox); + if (editable == isEditable()) + return; + + if (d->contentItem) { + if (editable) { + d->contentItem->installEventFilter(this); + if (QQuickTextInput *input = qobject_cast<QQuickTextInput *>(d->contentItem)) { + QObjectPrivate::connect(input, &QQuickTextInput::textChanged, d, &QQuickComboBoxPrivate::updateEditText); + QObjectPrivate::connect(input, &QQuickTextInput::accepted, d, &QQuickComboBoxPrivate::acceptInput); + } +#if QT_CONFIG(cursor) + d->contentItem->setCursor(Qt::IBeamCursor); +#endif + } else { + d->contentItem->removeEventFilter(this); + if (QQuickTextInput *input = qobject_cast<QQuickTextInput *>(d->contentItem)) { + QObjectPrivate::disconnect(input, &QQuickTextInput::textChanged, d, &QQuickComboBoxPrivate::updateEditText); + QObjectPrivate::disconnect(input, &QQuickTextInput::accepted, d, &QQuickComboBoxPrivate::acceptInput); + } +#if QT_CONFIG(cursor) + d->contentItem->unsetCursor(); +#endif + } + } + + d->extra.value().editable = editable; + setAccessibleProperty("editable", editable); + emit editableChanged(); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty string QtQuick.Controls::ComboBox::editText + + This property holds the text in the text field of an editable combo box. + + \sa editable, currentText, displayText +*/ +QString QQuickComboBox::editText() const +{ + Q_D(const QQuickComboBox); + return d->extra.isAllocated() ? d->extra->editText : QString(); +} + +void QQuickComboBox::setEditText(const QString &text) +{ + Q_D(QQuickComboBox); + if (text == editText()) + return; + + d->extra.value().editText = text; + emit editTextChanged(); +} + +void QQuickComboBox::resetEditText() +{ + setEditText(QString()); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty Validator QtQuick.Controls::ComboBox::validator + + This property holds an input text validator for an editable combo box. + + When a validator is set, the text field will only accept input which + leaves the text property in an intermediate state. The \l accepted signal + will only be emitted if the text is in an acceptable state when the + \uicontrol Return or \uicontrol Enter key is pressed. + + The currently supported validators are \l[QtQuick]{IntValidator}, + \l[QtQuick]{DoubleValidator}, and \l[QtQuick]{RegularExpressionValidator}. An + example of using validators is shown below, which allows input of + integers between \c 0 and \c 10 into the text field: + + \code + ComboBox { + model: 10 + editable: true + validator: IntValidator { + top: 9 + bottom: 0 + } + } + \endcode + + \sa acceptableInput, accepted, editable +*/ +QValidator *QQuickComboBox::validator() const +{ + Q_D(const QQuickComboBox); + return d->extra.isAllocated() ? d->extra->validator : nullptr; +} + +void QQuickComboBox::setValidator(QValidator *validator) +{ + Q_D(QQuickComboBox); + if (validator == QQuickComboBox::validator()) + return; + + d->extra.value().validator = validator; +#if QT_CONFIG(validator) + if (validator) + validator->setLocale(d->locale); +#endif + emit validatorChanged(); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty flags QtQuick.Controls::ComboBox::inputMethodHints + + Provides hints to the input method about the expected content of the combo box and how it + should operate. + + The default value is \c Qt.ImhNoPredictiveText. + + \include inputmethodhints.qdocinc +*/ +Qt::InputMethodHints QQuickComboBox::inputMethodHints() const +{ + Q_D(const QQuickComboBox); + return d->extra.isAllocated() ? d->extra->inputMethodHints : Qt::ImhNoPredictiveText; +} + +void QQuickComboBox::setInputMethodHints(Qt::InputMethodHints hints) +{ + Q_D(QQuickComboBox); + d->setInputMethodHints(hints); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty bool QtQuick.Controls::ComboBox::inputMethodComposing + \readonly + + This property holds whether an editable combo box has partial text input from an input method. + + While it is composing, an input method may rely on mouse or key events from the combo box to + edit or commit the partial text. This property can be used to determine when to disable event + handlers that may interfere with the correct operation of an input method. +*/ +bool QQuickComboBox::isInputMethodComposing() const +{ + Q_D(const QQuickComboBox); + return d->contentItem && d->contentItem->property("inputMethodComposing").toBool(); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty bool QtQuick.Controls::ComboBox::acceptableInput + \readonly + + This property holds whether the combo box contains acceptable text in the editable text field. + + If a validator has been set, the value is \c true only if the current text is acceptable + to the validator as a final string (not as an intermediate string). + + \sa validator, accepted +*/ +bool QQuickComboBox::hasAcceptableInput() const +{ + Q_D(const QQuickComboBox); + return d->m_acceptableInput; +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::ComboBox::implicitIndicatorWidth + \readonly + + This property holds the implicit indicator width. + + The value is equal to \c {indicator ? indicator.implicitWidth : 0}. + + This is typically used, together with \l {Control::}{implicitContentWidth} and + \l {Control::}{implicitBackgroundWidth}, to calculate the \l {Item::}{implicitWidth}. + + \sa implicitIndicatorHeight +*/ +qreal QQuickComboBox::implicitIndicatorWidth() const +{ + Q_D(const QQuickComboBox); + if (!d->indicator) + return 0; + return d->indicator->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::ComboBox::implicitIndicatorHeight + \readonly + + This property holds the implicit indicator height. + + The value is equal to \c {indicator ? indicator.implicitHeight : 0}. + + This is typically used, together with \l {Control::}{implicitContentHeight} and + \l {Control::}{implicitBackgroundHeight}, to calculate the \l {Item::}{implicitHeight}. + + \sa implicitIndicatorWidth +*/ +qreal QQuickComboBox::implicitIndicatorHeight() const +{ + Q_D(const QQuickComboBox); + if (!d->indicator) + return 0; + return d->indicator->implicitHeight(); +} + +/*! + \readonly + \since QtQuick.Controls 2.14 (Qt 5.14) + \qmlproperty var QtQuick.Controls::ComboBox::currentValue + + This property holds the value of the current item in the combo box. + + For an example of how to use this property, see \l {ComboBox Model Roles}. + + \sa currentIndex, currentText, valueRole +*/ +QVariant QQuickComboBox::currentValue() const +{ + Q_D(const QQuickComboBox); + return d->currentValue; +} + +/*! + \readonly + \since QtQuick.Controls 2.14 (Qt 5.14) + \qmlmethod var QtQuick.Controls::ComboBox::valueAt(int index) + + Returns the value at position \a index in the combo box. + + \sa indexOfValue +*/ +QVariant QQuickComboBox::valueAt(int index) const +{ + Q_D(const QQuickComboBox); + if (!d->isValidIndex(index)) + return QVariant(); + + const QString effectiveValueRole = d->valueRole.isEmpty() ? QStringLiteral("modelData") : d->valueRole; + return d->delegateModel->variantValue(index, effectiveValueRole); +} + +/*! + \since QtQuick.Controls 2.14 (Qt 5.14) + \qmlmethod int QtQuick.Controls::ComboBox::indexOfValue(object value) + + Returns the index of the specified \a value, or \c -1 if no match is found. + + For an example of how to use this method, see \l {ComboBox Model Roles}. + + \include qquickcombobox.qdocinc functions-after-component-completion + + \sa find(), currentValue, currentIndex, valueRole, valueAt +*/ +int QQuickComboBox::indexOfValue(const QVariant &value) const +{ + for (int i = 0; i < count(); ++i) { + const QVariant ourValue = valueAt(i); + if (value == ourValue) + return i; + } + return -1; +} + +/*! + \since QtQuick.Controls 2.15 (Qt 5.15) + \qmlproperty bool QtQuick.Controls::ComboBox::selectTextByMouse + + This property holds whether the text field for an editable ComboBox + can be selected with the mouse. + + The default value is \c false. +*/ +bool QQuickComboBox::selectTextByMouse() const +{ + Q_D(const QQuickComboBox); + return d->extra.isAllocated() ? d->extra->selectTextByMouse : false; +} + +void QQuickComboBox::setSelectTextByMouse(bool canSelect) +{ + Q_D(QQuickComboBox); + if (canSelect == selectTextByMouse()) + return; + + d->extra.value().selectTextByMouse = canSelect; + emit selectTextByMouseChanged(); +} + +/*! + \since QtQuick.Controls 6.0 (Qt 6.0) + \qmlproperty enumeration QtQuick.Controls::ComboBox::implicitContentWidthPolicy + + This property controls how the \l{Control::}{implicitContentWidth} of the ComboBox is + calculated. + + When the width of a ComboBox is not large enough to display text, that text + is elided. Depending on which parts of the text are elided, this can make + selecting an item difficult for the end user. An efficient way of ensuring + that a ComboBox is wide enough to avoid text being elided is to set a width + that is known to be large enough: + + \code + width: 300 + implicitContentWidthPolicy: ComboBox.ContentItemImplicitWidth + \endcode + + However, it is often not possible to know whether or not a hard-coded value + will be large enough, as the size of text depends on many factors, such as + font family, font size, translations, and so on. + + implicitContentWidthPolicy provides an easy way to control how the + implicitContentWidth is calculated, which in turn affects the + \l{Item::}{implicitWidth} of the ComboBox and ensures that text will not be elided. + + The available values are: + + \value ContentItemImplicitWidth + The implicitContentWidth will default to that of the \l{Control::}{contentItem}. + This is the most efficient option, as no extra text layout is done. + \value WidestText + The implicitContentWidth will be set to the implicit width of the + the largest text for the given \l textRole every time the model + changes. + This option should be used with smaller models, as it can be expensive. + \value WidestTextWhenCompleted + The implicitContentWidth will be set to the implicit width of the + the largest text for the given \l textRole once after + \l {QQmlParserStatus::componentComplete()}{component completion}. + This option should be used with smaller models, as it can be expensive. + + The default value is \c ContentItemImplicitWidth. + + As this property only affects the \c implicitWidth of the ComboBox, setting + an explicit \l{Item::}{width} can still result in eliding. + + \note This feature requires the contentItem to be a type derived from + \l TextInput. + + \note This feature requires text to be laid out, and can therefore be + expensive for large models or models whose contents are updated + frequently. +*/ +QQuickComboBox::ImplicitContentWidthPolicy QQuickComboBox::implicitContentWidthPolicy() const +{ + Q_D(const QQuickComboBox); + return d->implicitContentWidthPolicy; +} + +void QQuickComboBox::setImplicitContentWidthPolicy(QQuickComboBox::ImplicitContentWidthPolicy policy) +{ + Q_D(QQuickComboBox); + if (policy == d->implicitContentWidthPolicy) + return; + + d->implicitContentWidthPolicy = policy; + d->maybeUpdateImplicitContentWidth(); + emit implicitContentWidthPolicyChanged(); +} +/*! + \qmlmethod string QtQuick.Controls::ComboBox::textAt(int index) + + Returns the text for the specified \a index, or an empty string + if the index is out of bounds. + + \include qquickcombobox.qdocinc functions-after-component-completion + For example: + \snippet qtquickcontrols2-combobox-textat.qml textat + + \sa textRole +*/ +QString QQuickComboBox::textAt(int index) const +{ + Q_D(const QQuickComboBox); + if (!d->isValidIndex(index)) + return QString(); + + return d->delegateModel->stringValue(index, d->effectiveTextRole()); +} + +/*! + \qmlmethod int QtQuick.Controls::ComboBox::find(string text, enumeration flags) + + Returns the index of the specified \a text, or \c -1 if no match is found. + + The way the search is performed is defined by the specified match \a flags. By default, + combo box performs case sensitive exact matching (\c Qt.MatchExactly). All other match + types are case-insensitive unless the \c Qt.MatchCaseSensitive flag is also specified. + + \value Qt.MatchExactly The search term matches exactly (default). + \value Qt.MatchRegularExpression The search term matches as a regular expression. + \value Qt.MatchWildcard The search term matches using wildcards. + \value Qt.MatchFixedString The search term matches as a fixed string. + \value Qt.MatchStartsWith The search term matches the start of the item. + \value Qt.MatchEndsWidth The search term matches the end of the item. + \value Qt.MatchContains The search term is contained in the item. + \value Qt.MatchCaseSensitive The search is case sensitive. + + \include qquickcombobox.qdocinc functions-after-component-completion + For example: + \snippet qtquickcontrols2-combobox-find.qml find + + \sa textRole +*/ +int QQuickComboBox::find(const QString &text, Qt::MatchFlags flags) const +{ + Q_D(const QQuickComboBox); + return d->match(0, text, flags); +} + +/*! + \qmlmethod void QtQuick.Controls::ComboBox::incrementCurrentIndex() + + Increments the current index of the combo box, or the highlighted + index if the popup list is visible. + + \sa currentIndex, highlightedIndex +*/ +void QQuickComboBox::incrementCurrentIndex() +{ + Q_D(QQuickComboBox); + d->incrementCurrentIndex(); +} + +/*! + \qmlmethod void QtQuick.Controls::ComboBox::decrementCurrentIndex() + + Decrements the current index of the combo box, or the highlighted + index if the popup list is visible. + + \sa currentIndex, highlightedIndex +*/ +void QQuickComboBox::decrementCurrentIndex() +{ + Q_D(QQuickComboBox); + d->decrementCurrentIndex(); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlmethod void QtQuick.Controls::ComboBox::selectAll() + + Selects all the text in the editable text field of the combo box. + + \sa editText +*/ +void QQuickComboBox::selectAll() +{ + Q_D(QQuickComboBox); + QQuickTextInput *input = qobject_cast<QQuickTextInput *>(d->contentItem); + if (!input) + return; + input->selectAll(); +} + +bool QQuickComboBox::eventFilter(QObject *object, QEvent *event) +{ + Q_D(QQuickComboBox); + switch (event->type()) { + case QEvent::MouseButtonRelease: + if (d->isPopupVisible()) + d->hidePopup(false); + break; + case QEvent::KeyPress: { + QKeyEvent *ke = static_cast<QKeyEvent *>(event); + if (d->filterKeyEvent(ke, false)) + return true; + event->accept(); + if (d->extra.isAllocated()) + d->extra->allowComplete = ke->key() != Qt::Key_Backspace && ke->key() != Qt::Key_Delete; + break; + } + case QEvent::FocusOut: + if (qGuiApp->focusObject() != this && (!d->popup || !d->popup->hasActiveFocus())) { + // Only close the popup if focus was transferred somewhere else + // than to the popup or the popup button (which normally means that + // the user clicked on the popup button to open it, not close it). + d->hidePopup(false); + setPressed(false); + + // The focus left the text field, so if the edit text matches an item in the model, + // change our currentIndex to that. This matches widgets' behavior. + const int indexForEditText = find(d->extra.value().editText, Qt::MatchFixedString); + if (indexForEditText > -1) + setCurrentIndex(indexForEditText); + } + break; +#if QT_CONFIG(im) + case QEvent::InputMethod: + if (d->extra.isAllocated()) + d->extra->allowComplete = !static_cast<QInputMethodEvent*>(event)->commitString().isEmpty(); + break; +#endif + default: + break; + } + return QQuickControl::eventFilter(object, event); +} + +void QQuickComboBox::focusInEvent(QFocusEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::focusInEvent(event); + // Setting focus on TextField should not be done when drop down indicator was clicked + // That is why, if focus is not set with key reason, it should not be passed to textEdit by default. + // Focus on Edit Text should be set only intentionally by user. + if ((event->reason() == Qt::TabFocusReason || event->reason() == Qt::BacktabFocusReason || + event->reason() == Qt::ShortcutFocusReason) && d->contentItem && isEditable()) + d->contentItem->forceActiveFocus(event->reason()); +} + +void QQuickComboBox::focusOutEvent(QFocusEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::focusOutEvent(event); + + if (qGuiApp->focusObject() != d->contentItem && (!d->popup || !d->popup->hasActiveFocus())) { + // Only close the popup if focus was transferred + // somewhere else than to the popup or the inner line edit (which is + // normally done from QQuickComboBox::focusInEvent). + d->hidePopup(false); + setPressed(false); + } +} + +#if QT_CONFIG(im) +void QQuickComboBox::inputMethodEvent(QInputMethodEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::inputMethodEvent(event); + if (!isEditable() && !event->commitString().isEmpty()) + d->keySearch(event->commitString()); + else + event->ignore(); +} +#endif + +void QQuickComboBox::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::keyPressEvent(event); + + switch (event->key()) { + case Qt::Key_Escape: + case Qt::Key_Back: + if (d->isPopupVisible()) + event->accept(); + break; + case Qt::Key_Space: + if (!event->isAutoRepeat()) + setPressed(true); + event->accept(); + break; + case Qt::Key_Enter: + case Qt::Key_Return: + if (d->isPopupVisible()) + setPressed(true); + event->accept(); + break; + case Qt::Key_Up: + d->keyNavigating = true; + d->decrementCurrentIndex(); + event->accept(); + break; + case Qt::Key_Down: + d->keyNavigating = true; + d->incrementCurrentIndex(); + event->accept(); + break; + case Qt::Key_Home: + d->keyNavigating = true; + if (d->isPopupVisible()) + d->setHighlightedIndex(0, Highlight); + else + d->setCurrentIndex(0, Activate); + event->accept(); + break; + case Qt::Key_End: + d->keyNavigating = true; + if (d->isPopupVisible()) + d->setHighlightedIndex(count() - 1, Highlight); + else + d->setCurrentIndex(count() - 1, Activate); + event->accept(); + break; + default: + if (!isEditable() && !event->text().isEmpty()) + d->keySearch(event->text()); + else + event->ignore(); + break; + } +} + +void QQuickComboBox::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::keyReleaseEvent(event); + d->keyNavigating = false; + if (event->isAutoRepeat()) + return; + + switch (event->key()) { + case Qt::Key_Space: + if (!isEditable() && isPressed()) + d->togglePopup(true); + setPressed(false); + event->accept(); + break; + case Qt::Key_Enter: + case Qt::Key_Return: + if (!isEditable() || d->isPopupVisible()) + d->hidePopup(d->isPopupVisible()); + setPressed(false); + event->accept(); + break; + case Qt::Key_Escape: + case Qt::Key_Back: + if (d->isPopupVisible()) { + d->hidePopup(false); + setPressed(false); + event->accept(); + } + break; + default: + break; + } +} + +#if QT_CONFIG(wheelevent) +void QQuickComboBox::wheelEvent(QWheelEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::wheelEvent(event); + if (d->wheelEnabled && !d->isPopupVisible()) { + if (event->angleDelta().y() > 0) + d->decrementCurrentIndex(); + else + d->incrementCurrentIndex(); + } +} +#endif + +bool QQuickComboBox::event(QEvent *e) +{ + Q_D(QQuickComboBox); + if (e->type() == QEvent::LanguageChange) + d->updateCurrentTextAndValue(); + return QQuickControl::event(e); +} + +void QQuickComboBox::componentComplete() +{ + Q_D(QQuickComboBox); + d->executeIndicator(true); + QQuickControl::componentComplete(); + if (d->popup) + d->executePopup(true); + + if (d->delegateModel && d->ownModel) + static_cast<QQmlDelegateModel *>(d->delegateModel)->componentComplete(); + + if (count() > 0) { + if (!d->hasCurrentIndex && d->currentIndex == -1) + setCurrentIndex(0); + else + d->updateCurrentTextAndValue(); + + // If the widest text was already calculated in the call to + // QQmlDelegateModel::componentComplete() above, then we shouldn't do it here too. + if (!d->hasCalculatedWidestText) + d->maybeUpdateImplicitContentWidth(); + } +} + +void QQuickComboBox::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) +{ + Q_D(QQuickComboBox); + QQuickControl::itemChange(change, value); + if (change == ItemVisibleHasChanged && !value.boolValue) { + d->hidePopup(false); + setPressed(false); + } +} + +void QQuickComboBox::fontChange(const QFont &newFont, const QFont &oldFont) +{ + Q_D(QQuickComboBox); + QQuickControl::fontChange(newFont, oldFont); + d->maybeUpdateImplicitContentWidth(); +} + +void QQuickComboBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + Q_D(QQuickComboBox); + if (oldItem) { + oldItem->removeEventFilter(this); + if (QQuickTextInput *oldInput = qobject_cast<QQuickTextInput *>(oldItem)) { + QObjectPrivate::disconnect(oldInput, &QQuickTextInput::accepted, d, &QQuickComboBoxPrivate::acceptInput); + QObjectPrivate::disconnect(oldInput, &QQuickTextInput::textChanged, d, &QQuickComboBoxPrivate::updateEditText); + disconnect(oldInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickComboBox::inputMethodComposingChanged); + QObjectPrivate::disconnect(oldInput, &QQuickTextInput::acceptableInputChanged, d, &QQuickComboBoxPrivate::updateAcceptableInput); + } + } + if (newItem && isEditable()) { + newItem->installEventFilter(this); + if (QQuickTextInput *newInput = qobject_cast<QQuickTextInput *>(newItem)) { + QObjectPrivate::connect(newInput, &QQuickTextInput::accepted, d, &QQuickComboBoxPrivate::acceptInput); + QObjectPrivate::connect(newInput, &QQuickTextInput::textChanged, d, &QQuickComboBoxPrivate::updateEditText); + connect(newInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickComboBox::inputMethodComposingChanged); + QObjectPrivate::connect(newInput, &QQuickTextInput::acceptableInputChanged, d, &QQuickComboBoxPrivate::updateAcceptableInput); + } +#if QT_CONFIG(cursor) + newItem->setCursor(Qt::IBeamCursor); +#endif + } + + d->updateAcceptableInput(); +} + +void QQuickComboBox::localeChange(const QLocale &newLocale, const QLocale &oldLocale) +{ + QQuickControl::localeChange(newLocale, oldLocale); +#if QT_CONFIG(validator) + if (QValidator *v = validator()) + v->setLocale(newLocale); +#endif +} + +QFont QQuickComboBox::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::ComboBox); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickComboBox::accessibleRole() const +{ + return QAccessible::ComboBox; +} + +void QQuickComboBox::accessibilityActiveChanged(bool active) +{ + Q_D(QQuickComboBox); + QQuickControl::accessibilityActiveChanged(active); + + if (active) { + maybeSetAccessibleName(d->hasDisplayText ? d->displayText : d->currentText); + setAccessibleProperty("editable", isEditable()); + } +} +#endif // + +QT_END_NAMESPACE + +#include "moc_qquickcombobox_p.cpp" diff --git a/src/quicktemplates2/qquickcombobox_p.h b/src/quicktemplates2/qquickcombobox_p.h new file mode 100644 index 00000000000..71dd836603e --- /dev/null +++ b/src/quicktemplates2/qquickcombobox_p.h @@ -0,0 +1,272 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCOMBOBOX_P_H +#define QQUICKCOMBOBOX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qloggingcategory.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcItemManagement) + +class QValidator; +class QQuickPopup; +class QQmlInstanceModel; +class QQuickComboBoxPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickComboBox : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(int count READ count NOTIFY countChanged FINAL) + Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged FINAL) + Q_PROPERTY(QQmlInstanceModel *delegateModel READ delegateModel NOTIFY delegateModelChanged FINAL) + Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged FINAL) + Q_PROPERTY(int highlightedIndex READ highlightedIndex NOTIFY highlightedIndexChanged FINAL) + Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL) + Q_PROPERTY(QString currentText READ currentText NOTIFY currentTextChanged FINAL) + Q_PROPERTY(QString displayText READ displayText WRITE setDisplayText RESET resetDisplayText NOTIFY displayTextChanged FINAL) + Q_PROPERTY(QString textRole READ textRole WRITE setTextRole NOTIFY textRoleChanged FINAL) + Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL) + Q_PROPERTY(QQuickItem *indicator READ indicator WRITE setIndicator NOTIFY indicatorChanged FINAL) + Q_PROPERTY(QQuickPopup *popup READ popup WRITE setPopup NOTIFY popupChanged FINAL) + // 2.1 (Qt 5.8) + Q_PROPERTY(bool flat READ isFlat WRITE setFlat NOTIFY flatChanged FINAL REVISION(2, 1)) + // 2.2 (Qt 5.9) + Q_PROPERTY(bool down READ isDown WRITE setDown RESET resetDown NOTIFY downChanged FINAL REVISION(2, 2)) + Q_PROPERTY(bool editable READ isEditable WRITE setEditable NOTIFY editableChanged FINAL REVISION(2, 2)) + Q_PROPERTY(QString editText READ editText WRITE setEditText RESET resetEditText NOTIFY editTextChanged FINAL REVISION(2, 2)) + Q_PROPERTY(QValidator *validator READ validator WRITE setValidator NOTIFY validatorChanged FINAL REVISION(2, 2)) + Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints NOTIFY inputMethodHintsChanged FINAL REVISION(2, 2)) + Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged FINAL REVISION(2, 2)) + Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged FINAL REVISION(2, 2)) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitIndicatorWidth READ implicitIndicatorWidth NOTIFY implicitIndicatorWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitIndicatorHeight READ implicitIndicatorHeight NOTIFY implicitIndicatorHeightChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,indicator,popup") + // 2.14 (Qt 5.14) + Q_PROPERTY(QVariant currentValue READ currentValue NOTIFY currentValueChanged FINAL REVISION(2, 14)) + Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole NOTIFY valueRoleChanged FINAL REVISION(2, 14)) + // 2.15 (Qt 5.15) + Q_PROPERTY(bool selectTextByMouse READ selectTextByMouse WRITE setSelectTextByMouse NOTIFY selectTextByMouseChanged FINAL REVISION(2, 15)) + // 6.0 (Qt 6.0) + Q_PROPERTY(ImplicitContentWidthPolicy implicitContentWidthPolicy READ implicitContentWidthPolicy + WRITE setImplicitContentWidthPolicy NOTIFY implicitContentWidthPolicyChanged FINAL REVISION(6, 0)) + QML_NAMED_ELEMENT(ComboBox) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickComboBox(QQuickItem *parent = nullptr); + ~QQuickComboBox(); + + int count() const; + + QVariant model() const; + void setModel(const QVariant &model); + QQmlInstanceModel *delegateModel() const; + + bool isPressed() const; + void setPressed(bool pressed); + + int highlightedIndex() const; + + int currentIndex() const; + void setCurrentIndex(int index); + + QString currentText() const; + + QString displayText() const; + void setDisplayText(const QString &text); + void resetDisplayText(); + + QString textRole() const; + void setTextRole(const QString &role); + + QString valueRole() const; + void setValueRole(const QString &role); + + QQmlComponent *delegate() const; + void setDelegate(QQmlComponent *delegate); + + QQuickItem *indicator() const; + void setIndicator(QQuickItem *indicator); + + QQuickPopup *popup() const; + void setPopup(QQuickPopup *popup); + + Q_INVOKABLE QString textAt(int index) const; + Q_INVOKABLE int find(const QString &text, Qt::MatchFlags flags = Qt::MatchExactly) const; + + // 2.1 (Qt 5.8) + bool isFlat() const; + void setFlat(bool flat); + + // 2.2 (Qt 5.9) + bool isDown() const; + void setDown(bool down); + void resetDown(); + + bool isEditable() const; + void setEditable(bool editable); + + QString editText() const; + void setEditText(const QString &text); + void resetEditText(); + + QValidator *validator() const; + void setValidator(QValidator *validator); + + Qt::InputMethodHints inputMethodHints() const; + void setInputMethodHints(Qt::InputMethodHints hints); + + bool isInputMethodComposing() const; + bool hasAcceptableInput() const; + + // 2.5 (Qt 5.12) + qreal implicitIndicatorWidth() const; + qreal implicitIndicatorHeight() const; + + // 2.14 (Qt 5.14) + QVariant currentValue() const; + Q_REVISION(2, 14) Q_INVOKABLE QVariant valueAt(int index) const; + Q_REVISION(2, 14) Q_INVOKABLE int indexOfValue(const QVariant &value) const; + + // 2.15 (Qt 5.15) + bool selectTextByMouse() const; + void setSelectTextByMouse(bool canSelect); + + // 6.0 (Qt 6.0) + enum ImplicitContentWidthPolicy { + ContentItemImplicitWidth, + WidestText, + WidestTextWhenCompleted + }; + Q_ENUM(ImplicitContentWidthPolicy) + + ImplicitContentWidthPolicy implicitContentWidthPolicy() const; + void setImplicitContentWidthPolicy(ImplicitContentWidthPolicy policy); + +public Q_SLOTS: + void incrementCurrentIndex(); + void decrementCurrentIndex(); + Q_REVISION(2, 2) void selectAll(); + +Q_SIGNALS: + void activated(int index); + void highlighted(int index); + void countChanged(); + void modelChanged(); + void delegateModelChanged(); + void pressedChanged(); + void highlightedIndexChanged(); + void currentIndexChanged(); + void currentTextChanged(); + void displayTextChanged(); + void textRoleChanged(); + void delegateChanged(); + void indicatorChanged(); + void popupChanged(); + // 2.1 (Qt 5.8) + Q_REVISION(2, 1) void flatChanged(); + // 2.2 (Qt 5.9) + Q_REVISION(2, 2) void accepted(); + Q_REVISION(2, 2) void downChanged(); + Q_REVISION(2, 2) void editableChanged(); + Q_REVISION(2, 2) void editTextChanged(); + Q_REVISION(2, 2) void validatorChanged(); + Q_REVISION(2, 2) void inputMethodHintsChanged(); + Q_REVISION(2, 2) void inputMethodComposingChanged(); + Q_REVISION(2, 2) void acceptableInputChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void implicitIndicatorWidthChanged(); + Q_REVISION(2, 5) void implicitIndicatorHeightChanged(); + // 2.14 (Qt 5.14) + Q_REVISION(2, 14) void valueRoleChanged(); + Q_REVISION(2, 14) void currentValueChanged(); + // 2.15 (Qt 5.15) + Q_REVISION(2, 15) void selectTextByMouseChanged(); + // 6.0 (Qt 6.0) + Q_REVISION(6, 0) void implicitContentWidthPolicyChanged(); + +protected: + bool eventFilter(QObject *object, QEvent *event) override; + void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; +#if QT_CONFIG(im) + void inputMethodEvent(QInputMethodEvent *event) override; +#endif + void keyPressEvent(QKeyEvent *event) override; + void keyReleaseEvent(QKeyEvent *event) override; +#if QT_CONFIG(wheelevent) + void wheelEvent(QWheelEvent *event) override; +#endif + bool event(QEvent *e) override; + + void componentComplete() override; + void itemChange(ItemChange change, const ItemChangeData &value) override; + void fontChange(const QFont &newFont, const QFont &oldFont) override; + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + void localeChange(const QLocale &newLocale, const QLocale &oldLocale) override; + + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; + void accessibilityActiveChanged(bool active) override; +#endif + +private: + Q_DISABLE_COPY(QQuickComboBox) + Q_DECLARE_PRIVATE(QQuickComboBox) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickComboBox) + +#endif // QQUICKCOMBOBOX_P_H diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp new file mode 100644 index 00000000000..e190c49470a --- /dev/null +++ b/src/quicktemplates2/qquickcontainer.cpp @@ -0,0 +1,913 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcontainer_p.h" +#include "qquickcontainer_p_p.h" + +#include <QtQuick/private/qquickflickable_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Container + \inherits Control +//! \instantiates QQuickContainer + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-containers + \brief Abstract base type providing functionality common to containers. + + Container is the base type of container-like user interface controls that + allow dynamic insertion and removal of items. + + \section2 Using Containers + + Typically, items are statically declared as children of Container, but it + is also possible to \l {addItem}{add}, \l {insertItem}{insert}, + \l {moveItem}{move} and \l {removeItem}{remove} items dynamically. The + items in a container can be accessed using \l itemAt() or + \l contentChildren. + + Most containers have the concept of a "current" item. The current item is + specified via the \l currentIndex property, and can be accessed using the + read-only \l currentItem property. + + The following example illustrates dynamic insertion of items to a \l TabBar, + which is one of the concrete implementations of Container. + + \code + Row { + TabBar { + id: tabBar + + currentIndex: 0 + width: parent.width - addButton.width + + TabButton { text: "TabButton" } + } + + Component { + id: tabButton + TabButton { text: "TabButton" } + } + + Button { + id: addButton + text: "+" + flat: true + onClicked: { + tabBar.addItem(tabButton.createObject(tabBar)) + console.log("added:", tabBar.itemAt(tabBar.count - 1)) + } + } + } + \endcode + + \section2 Managing the Current Index + + When using multiple containers, such as \l TabBar and \l SwipeView, together, + their \l currentIndex properties can be bound to each other to keep them in + sync. When the user interacts with either container, its current index changes + automatically propagate to the other container. + + Notice, however, that assigning a \c currentIndex value in JavaScript removes + the respective binding. In order to retain the bindings, use the following + methods to alter the current index: + + \list + \li \l incrementCurrentIndex() + \li \l decrementCurrentIndex() + \li \l setCurrentIndex() + \endlist + + \code + TabBar { + id: tabBar + currentIndex: swipeView.currentIndex + } + + SwipeView { + id: swipeView + currentIndex: tabBar.currentIndex + } + + Button { + text: qsTr("Home") + onClicked: swipeView.setCurrentIndex(0) + enabled: swipeView.currentIndex != 0 + } + + Button { + text: qsTr("Previous") + onClicked: swipeView.decrementCurrentIndex() + enabled: swipeView.currentIndex > 0 + } + + Button { + text: qsTr("Next") + onClicked: swipeView.incrementCurrentIndex() + enabled: swipeView.currentIndex < swipeView.count - 1 + } + \endcode + + + \section2 Implementing Containers + + Container does not provide any default visualization. It is used to implement + such containers as \l SwipeView and \l TabBar. When implementing a custom + container, the most important part of the API is \l contentModel, which provides + the contained items in a way that it can be used as a delegate model for item + views and repeaters. + + \code + Container { + id: container + + contentItem: ListView { + model: container.contentModel + snapMode: ListView.SnapOneItem + orientation: ListView.Horizontal + } + + Text { + text: "Page 1" + width: container.width + height: container.height + } + + Text { + text: "Page 2" + width: container.width + height: container.height + } + } + \endcode + + Notice how the sizes of the page items are set by hand. This is because the + example uses a plain Container, which does not make any assumptions on the + visual layout. It is typically not necessary to specify sizes for items in + concrete Container implementations, such as \l SwipeView and \l TabBar. + + \sa {Container Controls} +*/ + +static QQuickItem *effectiveContentItem(QQuickItem *item) +{ + QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(item); + if (flickable) + return flickable->contentItem(); + return item; +} + +void QQuickContainerPrivate::init() +{ + Q_Q(QQuickContainer); + contentModel = new QQmlObjectModel(q); + QObject::connect(contentModel, &QQmlObjectModel::countChanged, q, &QQuickContainer::countChanged); + QObject::connect(contentModel, &QQmlObjectModel::childrenChanged, q, &QQuickContainer::contentChildrenChanged); + connect(q, &QQuickControl::implicitContentWidthChanged, this, &QQuickContainerPrivate::updateContentWidth); + connect(q, &QQuickControl::implicitContentHeightChanged, this, &QQuickContainerPrivate::updateContentHeight); +} + +void QQuickContainerPrivate::cleanup() +{ + Q_Q(QQuickContainer); + // ensure correct destruction order (QTBUG-46798) + const int count = contentModel->count(); + for (int i = 0; i < count; ++i) { + QQuickItem *item = itemAt(i); + if (item) + QQuickItemPrivate::get(item)->removeItemChangeListener(this, changeTypes); + } + + if (contentItem) { + QQuickItem *focusItem = QQuickItemPrivate::get(contentItem)->subFocusItem; + if (focusItem && window) + QQuickWindowPrivate::get(window)->clearFocusInScope(contentItem, focusItem, Qt::OtherFocusReason); + + q->contentItemChange(nullptr, contentItem); + QQuickControlPrivate::hideOldItem(contentItem); + } + + QObject::disconnect(contentModel, &QQmlObjectModel::countChanged, q, &QQuickContainer::countChanged); + QObject::disconnect(contentModel, &QQmlObjectModel::childrenChanged, q, &QQuickContainer::contentChildrenChanged); + delete contentModel; + contentModel = nullptr; +} + +QQuickItem *QQuickContainerPrivate::itemAt(int index) const +{ + return qobject_cast<QQuickItem *>(contentModel->get(index)); +} + +void QQuickContainerPrivate::insertItem(int index, QQuickItem *item) +{ + Q_Q(QQuickContainer); + if (!q->isContent(item)) + return; + contentData.append(item); + + updatingCurrent = true; + + item->setParentItem(effectiveContentItem(q->contentItem())); + QQuickItemPrivate::get(item)->addItemChangeListener(this, changeTypes); + contentModel->insert(index, item); + + q->itemAdded(index, item); + + int count = contentModel->count(); + for (int i = index + 1; i < count; ++i) + q->itemMoved(i, itemAt(i)); + + if (count == 1 && currentIndex == -1) + q->setCurrentIndex(index); + + updatingCurrent = false; +} + +void QQuickContainerPrivate::moveItem(int from, int to, QQuickItem *item) +{ + Q_Q(QQuickContainer); + int oldCurrent = currentIndex; + contentModel->move(from, to); + + updatingCurrent = true; + + q->itemMoved(to, item); + + if (from < to) { + for (int i = from; i < to; ++i) + q->itemMoved(i, itemAt(i)); + } else { + for (int i = from; i > to; --i) + q->itemMoved(i, itemAt(i)); + } + + if (from == oldCurrent) + q->setCurrentIndex(to); + else if (from < oldCurrent && to >= oldCurrent) + q->setCurrentIndex(oldCurrent - 1); + else if (from > oldCurrent && to <= oldCurrent) + q->setCurrentIndex(oldCurrent + 1); + + updatingCurrent = false; +} + +void QQuickContainerPrivate::removeItem(int index, QQuickItem *item) +{ + Q_Q(QQuickContainer); + if (!q->isContent(item)) + return; + contentData.removeOne(item); + + updatingCurrent = true; + + int count = contentModel->count(); + bool currentChanged = false; + if (index == currentIndex && (index != 0 || count == 1)) { + q->setCurrentIndex(currentIndex - 1); + } else if (index < currentIndex) { + --currentIndex; + currentChanged = true; + } + + QQuickItemPrivate::get(item)->removeItemChangeListener(this, changeTypes); + item->setParentItem(nullptr); + contentModel->remove(index); + --count; + + q->itemRemoved(index, item); + + for (int i = index; i < count; ++i) + q->itemMoved(i, itemAt(i)); + + if (currentChanged) + emit q->currentIndexChanged(); + + updatingCurrent = false; +} + +void QQuickContainerPrivate::reorderItems() +{ + Q_Q(QQuickContainer); + if (!contentItem) + return; + + QList<QQuickItem *> siblings = effectiveContentItem(contentItem)->childItems(); + + int to = 0; + for (int i = 0; i < siblings.count(); ++i) { + QQuickItem* sibling = siblings.at(i); + if (QQuickItemPrivate::get(sibling)->isTransparentForPositioner()) + continue; + int index = contentModel->indexOf(sibling, nullptr); + q->moveItem(index, to++); + } +} + +void QQuickContainerPrivate::_q_currentIndexChanged() +{ + Q_Q(QQuickContainer); + if (!updatingCurrent) + q->setCurrentIndex(contentItem ? contentItem->property("currentIndex").toInt() : -1); +} + +void QQuickContainerPrivate::itemChildAdded(QQuickItem *, QQuickItem *child) +{ + // add dynamically reparented items (eg. by a Repeater) + if (!QQuickItemPrivate::get(child)->isTransparentForPositioner() && !contentData.contains(child)) + insertItem(contentModel->count(), child); +} + +void QQuickContainerPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent) +{ + // remove dynamically unparented items (eg. by a Repeater) + if (!parent) + removeItem(contentModel->indexOf(item, nullptr), item); +} + +void QQuickContainerPrivate::itemSiblingOrderChanged(QQuickItem *) +{ + if (!componentComplete) + return; + + // reorder the restacked items (eg. by a Repeater) + reorderItems(); +} + +void QQuickContainerPrivate::itemDestroyed(QQuickItem *item) +{ + int index = contentModel->indexOf(item, nullptr); + if (index != -1) + removeItem(index, item); + else + QQuickControlPrivate::itemDestroyed(item); +} + +void QQuickContainerPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj) +{ + QQuickContainer *q = static_cast<QQuickContainer *>(prop->object); + QQuickContainerPrivate *p = QQuickContainerPrivate::get(q); + QQuickItem *item = qobject_cast<QQuickItem *>(obj); + if (item) { + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + item->setParentItem(effectiveContentItem(q->contentItem())); + else if (p->contentModel->indexOf(item, nullptr) == -1) + q->addItem(item); + } else { + p->contentData.append(obj); + } +} + +qsizetype QQuickContainerPrivate::contentData_count(QQmlListProperty<QObject> *prop) +{ + QQuickContainer *q = static_cast<QQuickContainer *>(prop->object); + return QQuickContainerPrivate::get(q)->contentData.count(); +} + +QObject *QQuickContainerPrivate::contentData_at(QQmlListProperty<QObject> *prop, qsizetype index) +{ + QQuickContainer *q = static_cast<QQuickContainer *>(prop->object); + return QQuickContainerPrivate::get(q)->contentData.value(index); +} + +void QQuickContainerPrivate::contentData_clear(QQmlListProperty<QObject> *prop) +{ + QQuickContainer *q = static_cast<QQuickContainer *>(prop->object); + return QQuickContainerPrivate::get(q)->contentData.clear(); +} + +void QQuickContainerPrivate::contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *item) +{ + QQuickContainer *q = static_cast<QQuickContainer *>(prop->object); + q->addItem(item); +} + +qsizetype QQuickContainerPrivate::contentChildren_count(QQmlListProperty<QQuickItem> *prop) +{ + QQuickContainer *q = static_cast<QQuickContainer *>(prop->object); + return QQuickContainerPrivate::get(q)->contentModel->count(); +} + +QQuickItem *QQuickContainerPrivate::contentChildren_at(QQmlListProperty<QQuickItem> *prop, qsizetype index) +{ + QQuickContainer *q = static_cast<QQuickContainer *>(prop->object); + return q->itemAt(index); +} + +void QQuickContainerPrivate::contentChildren_clear(QQmlListProperty<QQuickItem> *prop) +{ + QQuickContainer *q = static_cast<QQuickContainer *>(prop->object); + return QQuickContainerPrivate::get(q)->contentModel->clear(); +} + +void QQuickContainerPrivate::updateContentWidth() +{ + Q_Q(QQuickContainer); + if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth) || !contentModel) + return; + + contentWidth = implicitContentWidth; + emit q->contentWidthChanged(); +} + +void QQuickContainerPrivate::updateContentHeight() +{ + Q_Q(QQuickContainer); + if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight) || !contentModel) + return; + + contentHeight = implicitContentHeight; + emit q->contentHeightChanged(); +} + +QQuickContainer::QQuickContainer(QQuickItem *parent) + : QQuickControl(*(new QQuickContainerPrivate), parent) +{ + Q_D(QQuickContainer); + d->init(); +} + +QQuickContainer::QQuickContainer(QQuickContainerPrivate &dd, QQuickItem *parent) + : QQuickControl(dd, parent) +{ + Q_D(QQuickContainer); + d->init(); +} + +QQuickContainer::~QQuickContainer() +{ + Q_D(QQuickContainer); + d->cleanup(); +} + +/*! + \qmlproperty int QtQuick.Controls::Container::count + \readonly + + This property holds the number of items. +*/ +int QQuickContainer::count() const +{ + Q_D(const QQuickContainer); + return d->contentModel->count(); +} + +/*! + \qmlmethod Item QtQuick.Controls::Container::itemAt(int index) + + Returns the item at \a index, or \c null if it does not exist. +*/ +QQuickItem *QQuickContainer::itemAt(int index) const +{ + Q_D(const QQuickContainer); + return d->itemAt(index); +} + +/*! + \qmlmethod void QtQuick.Controls::Container::addItem(Item item) + + Adds an \a item. +*/ +void QQuickContainer::addItem(QQuickItem *item) +{ + Q_D(QQuickContainer); + insertItem(d->contentModel->count(), item); +} + +/*! + \qmlmethod void QtQuick.Controls::Container::insertItem(int index, Item item) + + Inserts an \a item at \a index. +*/ +void QQuickContainer::insertItem(int index, QQuickItem *item) +{ + Q_D(QQuickContainer); + if (!item) + return; + const int count = d->contentModel->count(); + if (index < 0 || index > count) + index = count; + + int oldIndex = d->contentModel->indexOf(item, nullptr); + if (oldIndex != -1) { + if (oldIndex < index) + --index; + if (oldIndex != index) + d->moveItem(oldIndex, index, item); + } else { + d->insertItem(index, item); + } +} + +/*! + \qmlmethod void QtQuick.Controls::Container::moveItem(int from, int to) + + Moves an item \a from one index \a to another. +*/ +void QQuickContainer::moveItem(int from, int to) +{ + Q_D(QQuickContainer); + const int count = d->contentModel->count(); + if (from < 0 || from > count - 1) + return; + if (to < 0 || to > count - 1) + to = count - 1; + + if (from != to) + d->moveItem(from, to, d->itemAt(from)); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Container::removeItem(Item item) + + Removes and destroys the specified \a item. +*/ +void QQuickContainer::removeItem(QQuickItem *item) +{ + Q_D(QQuickContainer); + if (!item) + return; + + const int index = d->contentModel->indexOf(item, nullptr); + if (index == -1) + return; + + d->removeItem(index, item); + item->deleteLater(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod Item QtQuick.Controls::Container::takeItem(int index) + + Removes and returns the item at \a index. + + \note The ownership of the item is transferred to the caller. +*/ +QQuickItem *QQuickContainer::takeItem(int index) +{ + Q_D(QQuickContainer); + const int count = d->contentModel->count(); + if (index < 0 || index >= count) + return nullptr; + + QQuickItem *item = itemAt(index); + if (item) + d->removeItem(index, item); + return item; +} + +/*! + \qmlproperty model QtQuick.Controls::Container::contentModel + \readonly + + This property holds the content model of items. + + The content model is provided for visualization purposes. It can be assigned + as a model to a content item that presents the contents of the container. + + \code + Container { + id: container + contentItem: ListView { + model: container.contentModel + } + } + \endcode + + \sa contentData, contentChildren +*/ +QVariant QQuickContainer::contentModel() const +{ + Q_D(const QQuickContainer); + return QVariant::fromValue(d->contentModel); +} + +/*! + \qmlproperty list<Object> QtQuick.Controls::Container::contentData + \qmldefault + + This property holds the list of content data. + + The list contains all objects that have been declared in QML as children + of the container, and also items that have been dynamically added or + inserted using the \l addItem() and \l insertItem() methods, respectively. + + \note Unlike \c contentChildren, \c contentData does include non-visual QML + objects. It is not re-ordered when items are inserted or moved. + + \sa Item::data, contentChildren +*/ +QQmlListProperty<QObject> QQuickContainer::contentData() +{ + Q_D(QQuickContainer); + if (!d->contentItem) + d->executeContentItem(); + return QQmlListProperty<QObject>(this, nullptr, + QQuickContainerPrivate::contentData_append, + QQuickContainerPrivate::contentData_count, + QQuickContainerPrivate::contentData_at, + QQuickContainerPrivate::contentData_clear); +} + +/*! + \qmlproperty list<Item> QtQuick.Controls::Container::contentChildren + + This property holds the list of content children. + + The list contains all items that have been declared in QML as children + of the container, and also items that have been dynamically added or + inserted using the \l addItem() and \l insertItem() methods, respectively. + + \note Unlike \c contentData, \c contentChildren does not include non-visual + QML objects. It is re-ordered when items are inserted or moved. + + \sa Item::children, contentData +*/ +QQmlListProperty<QQuickItem> QQuickContainer::contentChildren() +{ + return QQmlListProperty<QQuickItem>(this, nullptr, + QQuickContainerPrivate::contentChildren_append, + QQuickContainerPrivate::contentChildren_count, + QQuickContainerPrivate::contentChildren_at, + QQuickContainerPrivate::contentChildren_clear); +} + +/*! + \qmlproperty int QtQuick.Controls::Container::currentIndex + + This property holds the index of the current item. + + \sa currentItem, {Managing the Current Index} +*/ +int QQuickContainer::currentIndex() const +{ + Q_D(const QQuickContainer); + return d->currentIndex; +} + +/*! + \qmlmethod void QtQuick.Controls::Container::setCurrentIndex(int index) + + Sets the current \a index of the container. + + This method can be called to set a specific current index without breaking + existing \c currentIndex bindings. + + \sa currentIndex, {Managing the Current Index} +*/ +void QQuickContainer::setCurrentIndex(int index) +{ + Q_D(QQuickContainer); + if (d->currentIndex == index) + return; + + d->currentIndex = index; + emit currentIndexChanged(); + emit currentItemChanged(); +} + +/*! + \qmlmethod void QtQuick.Controls::Container::incrementCurrentIndex() + \since QtQuick.Controls 2.1 (Qt 5.8) + + Increments the current index of the container. + + This method can be called to alter the current index without breaking + existing \c currentIndex bindings. + + \sa currentIndex, {Managing the Current Index} +*/ +void QQuickContainer::incrementCurrentIndex() +{ + Q_D(QQuickContainer); + if (d->currentIndex < count() - 1) + setCurrentIndex(d->currentIndex + 1); +} + +/*! + \qmlmethod void QtQuick.Controls::Container::decrementCurrentIndex() + \since QtQuick.Controls 2.1 (Qt 5.8) + + Decrements the current index of the container. + + This method can be called to alter the current index without breaking + existing \c currentIndex bindings. + + \sa currentIndex, {Managing the Current Index} +*/ +void QQuickContainer::decrementCurrentIndex() +{ + Q_D(QQuickContainer); + if (d->currentIndex > 0) + setCurrentIndex(d->currentIndex - 1); +} + +/*! + \qmlproperty Item QtQuick.Controls::Container::currentItem + \readonly + + This property holds the current item. + + \sa currentIndex +*/ +QQuickItem *QQuickContainer::currentItem() const +{ + Q_D(const QQuickContainer); + return itemAt(d->currentIndex); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Container::contentWidth + + This property holds the content width. It is used for calculating the total + implicit width of the container. + + Unless explicitly overridden, the content width is automatically calculated + based on the implicit width of the items in the container. + + \sa contentHeight +*/ +qreal QQuickContainer::contentWidth() const +{ + Q_D(const QQuickContainer); + return d->contentWidth; +} + +void QQuickContainer::setContentWidth(qreal width) +{ + Q_D(QQuickContainer); + d->hasContentWidth = true; + if (qFuzzyCompare(d->contentWidth, width)) + return; + + d->contentWidth = width; + d->resizeContent(); + emit contentWidthChanged(); +} + +void QQuickContainer::resetContentWidth() +{ + Q_D(QQuickContainer); + if (!d->hasContentWidth) + return; + + d->hasContentWidth = false; + d->updateContentWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Container::contentHeight + + This property holds the content height. It is used for calculating the total + implicit height of the container. + + Unless explicitly overridden, the content height is automatically calculated + based on the implicit height of the items in the container. + + \sa contentWidth +*/ +qreal QQuickContainer::contentHeight() const +{ + Q_D(const QQuickContainer); + return d->contentHeight; +} + +void QQuickContainer::setContentHeight(qreal height) +{ + Q_D(QQuickContainer); + d->hasContentHeight = true; + if (qFuzzyCompare(d->contentHeight, height)) + return; + + d->contentHeight = height; + d->resizeContent(); + emit contentHeightChanged(); +} + +void QQuickContainer::resetContentHeight() +{ + Q_D(QQuickContainer); + if (!d->hasContentHeight) + return; + + d->hasContentHeight = false; + d->updateContentHeight(); +} + +void QQuickContainer::componentComplete() +{ + Q_D(QQuickContainer); + QQuickControl::componentComplete(); + d->reorderItems(); +} + +void QQuickContainer::itemChange(ItemChange change, const ItemChangeData &data) +{ + Q_D(QQuickContainer); + QQuickControl::itemChange(change, data); + if (change == QQuickItem::ItemChildAddedChange && isComponentComplete() && data.item != d->background && data.item != d->contentItem) { + if (!QQuickItemPrivate::get(data.item)->isTransparentForPositioner() && d->contentModel->indexOf(data.item, nullptr) == -1) + addItem(data.item); + } +} + +void QQuickContainer::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + Q_D(QQuickContainer); + QQuickControl::contentItemChange(newItem, oldItem); + + static const int slotIndex = metaObject()->indexOfSlot("_q_currentIndexChanged()"); + + if (oldItem) { + QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::Children | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight); + QQuickItem *oldContentItem = effectiveContentItem(oldItem); + if (oldContentItem != oldItem) + QQuickItemPrivate::get(oldContentItem)->removeItemChangeListener(d, QQuickItemPrivate::Children); + + int signalIndex = oldItem->metaObject()->indexOfSignal("currentIndexChanged()"); + if (signalIndex != -1) + QMetaObject::disconnect(oldItem, signalIndex, this, slotIndex); + } + + if (newItem) { + QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::Children | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight); + QQuickItem *newContentItem = effectiveContentItem(newItem); + if (newContentItem != newItem) + QQuickItemPrivate::get(newContentItem)->addItemChangeListener(d, QQuickItemPrivate::Children); + + int signalIndex = newItem->metaObject()->indexOfSignal("currentIndexChanged()"); + if (signalIndex != -1) + QMetaObject::connect(newItem, signalIndex, this, slotIndex); + } +} + +bool QQuickContainer::isContent(QQuickItem *item) const +{ + // If the item has a QML context associated to it (it was created in QML), + // we add it to the content model. Otherwise, it's probably the default + // highlight item that is always created by the item views, which we need + // to exclude. + // + // TODO: Find a better way to identify/exclude the highlight item... + return qmlContext(item); +} + +void QQuickContainer::itemAdded(int index, QQuickItem *item) +{ + Q_UNUSED(index); + Q_UNUSED(item); +} + +void QQuickContainer::itemMoved(int index, QQuickItem *item) +{ + Q_UNUSED(index); + Q_UNUSED(item); +} + +void QQuickContainer::itemRemoved(int index, QQuickItem *item) +{ + Q_UNUSED(index); + Q_UNUSED(item); +} + +QT_END_NAMESPACE + +#include "moc_qquickcontainer_p.cpp" diff --git a/src/quicktemplates2/qquickcontainer_p.h b/src/quicktemplates2/qquickcontainer_p.h new file mode 100644 index 00000000000..ccfe4c56188 --- /dev/null +++ b/src/quicktemplates2/qquickcontainer_p.h @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCONTAINER_P_H +#define QQUICKCONTAINER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQml/qqmllist.h> + +QT_BEGIN_NAMESPACE + +class QQuickContainerPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickContainer : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(int count READ count NOTIFY countChanged FINAL) + Q_PROPERTY(QVariant contentModel READ contentModel CONSTANT FINAL) + Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData) + Q_PROPERTY(QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) + Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL) + Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged FINAL) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth RESET resetContentWidth NOTIFY contentWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight RESET resetContentHeight NOTIFY contentHeightChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DefaultProperty", "contentData") + QML_NAMED_ELEMENT(Container) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickContainer(QQuickItem *parent = nullptr); + ~QQuickContainer(); + + int count() const; + Q_INVOKABLE QQuickItem *itemAt(int index) const; + Q_INVOKABLE void addItem(QQuickItem *item); + Q_INVOKABLE void insertItem(int index, QQuickItem *item); + Q_INVOKABLE void moveItem(int from, int to); + Q_INVOKABLE void removeItem(QQuickItem *item); + // 2.3 (Qt 5.10) + Q_REVISION(2, 3) Q_INVOKABLE QQuickItem *takeItem(int index); + + QVariant contentModel() const; + QQmlListProperty<QObject> contentData(); + QQmlListProperty<QQuickItem> contentChildren(); + + int currentIndex() const; + QQuickItem *currentItem() const; + + // 2.5 (Qt 5.12) + qreal contentWidth() const; + void setContentWidth(qreal width); + void resetContentWidth(); + + qreal contentHeight() const; + void setContentHeight(qreal height); + void resetContentHeight(); + +public Q_SLOTS: + void setCurrentIndex(int index); + // 2.1 (Qt 5.8) + Q_REVISION(2, 1) void incrementCurrentIndex(); + Q_REVISION(2, 1) void decrementCurrentIndex(); + +Q_SIGNALS: + void countChanged(); + void contentChildrenChanged(); + void currentIndexChanged(); + void currentItemChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void contentWidthChanged(); + Q_REVISION(2, 5) void contentHeightChanged(); + +protected: + QQuickContainer(QQuickContainerPrivate &dd, QQuickItem *parent); + + void componentComplete() override; + + void itemChange(ItemChange change, const ItemChangeData &data) override; + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + + virtual bool isContent(QQuickItem *item) const; + virtual void itemAdded(int index, QQuickItem *item); + virtual void itemMoved(int index, QQuickItem *item); + virtual void itemRemoved(int index, QQuickItem *item); + +private: + Q_DISABLE_COPY(QQuickContainer) + Q_DECLARE_PRIVATE(QQuickContainer) + Q_PRIVATE_SLOT(d_func(), void _q_currentIndexChanged()) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickContainer) + +#endif // QQUICKCONTAINER_P_H diff --git a/src/quicktemplates2/qquickcontainer_p_p.h b/src/quicktemplates2/qquickcontainer_p_p.h new file mode 100644 index 00000000000..b9f8eb0f011 --- /dev/null +++ b/src/quicktemplates2/qquickcontainer_p_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCONTAINER_P_P_H +#define QQUICKCONTAINER_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontainer_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p_p.h> +#include <private/qqmlobjectmodel_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickContainerPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickContainer) + +public: + static QQuickContainerPrivate *get(QQuickContainer *container) + { + return container->d_func(); + } + + void init(); + void cleanup(); + + QQuickItem *itemAt(int index) const; + void insertItem(int index, QQuickItem *item); + void moveItem(int from, int to, QQuickItem *item); + void removeItem(int index, QQuickItem *item); + void reorderItems(); + + void _q_currentIndexChanged(); + + void itemChildAdded(QQuickItem *item, QQuickItem *child) override; + void itemSiblingOrderChanged(QQuickItem *item) override; + void itemParentChanged(QQuickItem *item, QQuickItem *parent) override; + void itemDestroyed(QQuickItem *item) override; + + static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj); + static qsizetype contentData_count(QQmlListProperty<QObject> *prop); + static QObject *contentData_at(QQmlListProperty<QObject> *prop, qsizetype index); + static void contentData_clear(QQmlListProperty<QObject> *prop); + + static void contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *obj); + static qsizetype contentChildren_count(QQmlListProperty<QQuickItem> *prop); + static QQuickItem *contentChildren_at(QQmlListProperty<QQuickItem> *prop, qsizetype index); + static void contentChildren_clear(QQmlListProperty<QQuickItem> *prop); + + void updateContentWidth(); + void updateContentHeight(); + + bool hasContentWidth = false; + bool hasContentHeight = false; + qreal contentWidth = 0; + qreal contentHeight = 0; + QObjectList contentData; + QQmlObjectModel *contentModel = nullptr; + qsizetype currentIndex = -1; + bool updatingCurrent = false; + QQuickItemPrivate::ChangeTypes changeTypes = Destroyed | Parent | SiblingOrder; +}; + +QT_END_NAMESPACE + +#endif // QQUICKCONTAINER_P_P_H diff --git a/src/quicktemplates2/qquickcontentitem.cpp b/src/quicktemplates2/qquickcontentitem.cpp new file mode 100644 index 00000000000..325eb1fb45d --- /dev/null +++ b/src/quicktemplates2/qquickcontentitem.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcontentitem_p.h" + +#include <QtQml/private/qqmlmetatype_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \internal + + Helper class that aids debugging by producing more useful debugging output. +*/ + +QQuickContentItem::QQuickContentItem(QQuickItem *parent) + : QQuickItem(parent) +{ + setObjectName(QQmlMetaType::prettyTypeName(parent)); +} + +QQuickContentItem::QQuickContentItem(const QObject *scope, QQuickItem *parent) + : QQuickItem(parent) +{ + setObjectName(QQmlMetaType::prettyTypeName(scope)); +} + +QT_END_NAMESPACE + +#include "moc_qquickcontentitem_p.cpp" diff --git a/src/quicktemplates2/qquickcontentitem_p.h b/src/quicktemplates2/qquickcontentitem_p.h new file mode 100644 index 00000000000..df0f0b243ab --- /dev/null +++ b/src/quicktemplates2/qquickcontentitem_p.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCONTENTITEM_P_H +#define QQUICKCONTENTITEM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickContentItem : public QQuickItem +{ + Q_OBJECT + +public: + explicit QQuickContentItem(QQuickItem *parent = nullptr); + explicit QQuickContentItem(const QObject *scope, QQuickItem *parent); + +private: + Q_DISABLE_COPY(QQuickContentItem) +}; + +QT_END_NAMESPACE + +#endif // QQUICKCONTENTITEM_P_H diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp new file mode 100644 index 00000000000..8a46d040f2a --- /dev/null +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -0,0 +1,2244 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcontrol_p.h" +#include "qquickcontrol_p_p.h" + +#include <QtGui/qstylehints.h> +#include <QtGui/qguiapplication.h> +#include "qquicklabel_p.h" +#include "qquicklabel_p_p.h" +#include "qquicktextarea_p.h" +#include "qquicktextarea_p_p.h" +#include "qquicktextfield_p.h" +#include "qquicktextfield_p_p.h" +#include "qquickpopup_p.h" +#include "qquickpopupitem_p_p.h" +#include "qquickapplicationwindow_p.h" +#include "qquickdeferredexecute_p_p.h" +#include "qquickcontentitem_p.h" + +#if QT_CONFIG(accessibility) +#include <QtQuick/private/qquickaccessibleattached_p.h> +#endif + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcItemManagement, "qt.quick.controls.control.itemmanagement") + +/*! + \qmltype Control + \inherits Item +//! \instantiates QQuickControl + \inqmlmodule QtQuick.Controls + \since 5.7 + \brief Abstract base type providing functionality common to all controls. + + Control is the base type of user interface controls. It receives input + events from the window system, and paints a representation of itself on + the screen. + + \section1 Control Layout + + The following diagram illustrates the layout of a typical control: + + \image qtquickcontrols2-control.png + + The \l {Item::}{implicitWidth} and \l {Item::}{implicitHeight} of a control + are typically based on the implicit sizes of the background and the content + item plus any insets and paddings. These properties determine how large + the control will be when no explicit \l {Item::}{width} or + \l {Item::}{height} is specified. + + The geometry of the \l {Control::}{contentItem} is determined by the padding. + The following example reserves 10px padding between the boundaries of the + control and its content: + + \code + Control { + padding: 10 + + contentItem: Text { + text: "Content" + } + } + \endcode + + The \l {Control::}{background} item fills the entire width and height of the + control, unless insets or an explicit size have been given for it. Background + insets are useful for extending the touchable/interactive area of a control + without affecting its visual size. This is often used on touch devices to + ensure that a control is not too small to be interacted with by the user. + Insets affect the size of the control, and hence will affect how much space + they take up in a layout, for example. + + Negative insets can be used to make the background larger than the control. + The following example uses negative insets to place a shadow outside the + control's boundaries: + + \code + Control { + topInset: -2 + leftInset: -2 + rightInset: -6 + bottomInset: -6 + + background: BorderImage { + source: ":/images/shadowed-background.png" + } + } + \endcode + + \section1 Event Handling + + All controls, except non-interactive indicators, do not let clicks and + touches through to items below them. For example, the \c console.log() + call in the example below will never be executed when clicking on the + Pane, because the \l MouseArea is below it in the scene: + + \code + MouseArea { + anchors.fill: parent + onClicked: console.log("MouseArea was clicked") + + Pane { + anchors.fill: parent + } + } + \endcode + + \sa ApplicationWindow, Container, {Using Qt Quick Controls types in + property declarations} +*/ + +const QQuickItemPrivate::ChangeTypes QQuickControlPrivate::ImplicitSizeChanges = QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed; + +static bool isKeyFocusReason(Qt::FocusReason reason) +{ + return reason == Qt::TabFocusReason || reason == Qt::BacktabFocusReason || reason == Qt::ShortcutFocusReason; +} + +QQuickControlPrivate::QQuickControlPrivate() +{ +#if QT_CONFIG(accessibility) + QAccessible::installActivationObserver(this); +#endif +} + +QQuickControlPrivate::~QQuickControlPrivate() +{ +} + +void QQuickControlPrivate::init() +{ + Q_Q(QQuickControl); + QObject::connect(q, &QQuickItem::baselineOffsetChanged, q, &QQuickControl::baselineOffsetChanged); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +bool QQuickControlPrivate::acceptTouch(const QTouchEvent::TouchPoint &point) +{ + if (point.id() == touchId) + return true; + + if (touchId == -1 && point.state() == QEventPoint::Pressed) { + touchId = point.id(); + return true; + } + + // If the control is on a Flickable that has a pressDelay, then the press is never + // sent as a touch event, therefore we need to check for this case. + if (touchId == -1 && pressWasTouch && point.state() == QEventPoint::Released && + point.position() == previousPressPos) { + return true; + } + return false; +} +#endif + +static void setActiveFocus(QQuickControl *control, Qt::FocusReason reason) +{ + QQuickControlPrivate *d = QQuickControlPrivate::get(control); + if (d->subFocusItem && d->window && d->flags & QQuickItem::ItemIsFocusScope) + QQuickWindowPrivate::get(d->window)->clearFocusInScope(control, d->subFocusItem, reason); + control->forceActiveFocus(reason); +} + +void QQuickControlPrivate::handlePress(const QPointF &) +{ + Q_Q(QQuickControl); + if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && !QGuiApplication::styleHints()->setFocusOnTouchRelease()) + setActiveFocus(q, Qt::MouseFocusReason); +} + +void QQuickControlPrivate::handleMove(const QPointF &point) +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_Q(QQuickControl); + q->setHovered(hoverEnabled && q->contains(point)); +#else + Q_UNUSED(point); +#endif +} + +void QQuickControlPrivate::handleRelease(const QPointF &) +{ + Q_Q(QQuickControl); + if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease()) + setActiveFocus(q, Qt::MouseFocusReason); + touchId = -1; + pressWasTouch = false; + previousPressPos = QPointF(); +} + +void QQuickControlPrivate::handleUngrab() +{ + touchId = -1; +} + +void QQuickControlPrivate::mirrorChange() +{ + Q_Q(QQuickControl); + q->mirrorChange(); +} + +void QQuickControlPrivate::setTopPadding(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldPadding = getPadding(); + extra.value().topPadding = value; + extra.value().hasTopPadding = !reset; + if ((!reset && !qFuzzyCompare(oldPadding.top(), value)) || (reset && !qFuzzyCompare(oldPadding.top(), getVerticalPadding()))) { + emit q->topPaddingChanged(); + emit q->availableHeightChanged(); + q->paddingChange(getPadding(), oldPadding); + } +} + +void QQuickControlPrivate::setLeftPadding(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldPadding = getPadding(); + extra.value().leftPadding = value; + extra.value().hasLeftPadding = !reset; + if ((!reset && !qFuzzyCompare(oldPadding.left(), value)) || (reset && !qFuzzyCompare(oldPadding.left(), getHorizontalPadding()))) { + emit q->leftPaddingChanged(); + emit q->availableWidthChanged(); + q->paddingChange(getPadding(), oldPadding); + } +} + +void QQuickControlPrivate::setRightPadding(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldPadding = getPadding(); + extra.value().rightPadding = value; + extra.value().hasRightPadding = !reset; + if ((!reset && !qFuzzyCompare(oldPadding.right(), value)) || (reset && !qFuzzyCompare(oldPadding.right(), getHorizontalPadding()))) { + emit q->rightPaddingChanged(); + emit q->availableWidthChanged(); + q->paddingChange(getPadding(), oldPadding); + } +} + +void QQuickControlPrivate::setBottomPadding(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldPadding = getPadding(); + extra.value().bottomPadding = value; + extra.value().hasBottomPadding = !reset; + if ((!reset && !qFuzzyCompare(oldPadding.bottom(), value)) || (reset && !qFuzzyCompare(oldPadding.bottom(), getVerticalPadding()))) { + emit q->bottomPaddingChanged(); + emit q->availableHeightChanged(); + q->paddingChange(getPadding(), oldPadding); + } +} + +void QQuickControlPrivate::setHorizontalPadding(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldPadding = getPadding(); + const qreal oldHorizontalPadding = getHorizontalPadding(); + horizontalPadding = value; + hasHorizontalPadding = !reset; + if ((!reset && !qFuzzyCompare(oldHorizontalPadding, value)) || (reset && !qFuzzyCompare(oldHorizontalPadding, padding))) { + const QMarginsF newPadding = getPadding(); + if (!qFuzzyCompare(newPadding.left(), oldPadding.left())) + emit q->leftPaddingChanged(); + if (!qFuzzyCompare(newPadding.right(), oldPadding.right())) + emit q->rightPaddingChanged(); + emit q->horizontalPaddingChanged(); + emit q->availableWidthChanged(); + q->paddingChange(newPadding, oldPadding); + } +} + +void QQuickControlPrivate::setVerticalPadding(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldPadding = getPadding(); + const qreal oldVerticalPadding = getVerticalPadding(); + verticalPadding = value; + hasVerticalPadding = !reset; + if ((!reset && !qFuzzyCompare(oldVerticalPadding, value)) || (reset && !qFuzzyCompare(oldVerticalPadding, padding))) { + const QMarginsF newPadding = getPadding(); + if (!qFuzzyCompare(newPadding.top(), oldPadding.top())) + emit q->topPaddingChanged(); + if (!qFuzzyCompare(newPadding.bottom(), oldPadding.bottom())) + emit q->bottomPaddingChanged(); + emit q->verticalPaddingChanged(); + emit q->availableHeightChanged(); + q->paddingChange(newPadding, oldPadding); + } +} + +void QQuickControlPrivate::setTopInset(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldInset = getInset(); + extra.value().topInset = value; + extra.value().hasTopInset = !reset; + if (!qFuzzyCompare(oldInset.top(), value)) { + emit q->topInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickControlPrivate::setLeftInset(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldInset = getInset(); + extra.value().leftInset = value; + extra.value().hasLeftInset = !reset; + if (!qFuzzyCompare(oldInset.left(), value)) { + emit q->leftInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickControlPrivate::setRightInset(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldInset = getInset(); + extra.value().rightInset = value; + extra.value().hasRightInset = !reset; + if (!qFuzzyCompare(oldInset.right(), value)) { + emit q->rightInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickControlPrivate::setBottomInset(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldInset = getInset(); + extra.value().bottomInset = value; + extra.value().hasBottomInset = !reset; + if (!qFuzzyCompare(oldInset.bottom(), value)) { + emit q->bottomInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickControlPrivate::resizeBackground() +{ + if (!background) + return; + + resizingBackground = true; + + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + bool changeWidth = false; + bool changeHeight = false; + if (((!p->widthValid() || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(background->x())) + || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) { + background->setX(getLeftInset()); + changeWidth = !p->width.hasBinding(); + } + if (((!p->heightValid() || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(background->y())) + || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) { + background->setY(getTopInset()); + changeHeight = !p->height.hasBinding(); + } + if (changeHeight || changeWidth) { + auto newWidth = changeWidth ? + width.valueBypassingBindings() - getLeftInset() - getRightInset() : + p->width.valueBypassingBindings(); + auto newHeight = changeHeight ? + height.valueBypassingBindings() - getTopInset() - getBottomInset() : + p->height.valueBypassingBindings(); + background->setSize({newWidth, newHeight}); + } + + resizingBackground = false; +} + +void QQuickControlPrivate::resizeContent() +{ + Q_Q(QQuickControl); + if (contentItem) { + contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding())); + contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight())); + } +} + +QQuickItem *QQuickControlPrivate::getContentItem() +{ + if (!contentItem) + executeContentItem(); + return contentItem; +} + +void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify) +{ + Q_Q(QQuickControl); + if (contentItem == item) + return; + + if (!contentItem.isExecuting()) + cancelContentItem(); + + QQuickItem *oldContentItem = contentItem; + if (oldContentItem) { + disconnect(oldContentItem, &QQuickItem::baselineOffsetChanged, this, &QQuickControlPrivate::updateBaselineOffset); + if (oldContentItem) + QQuickItemPrivate::get(oldContentItem)->removeItemChangeListener(this, QQuickControlPrivate::Focus); + removeImplicitSizeListener(oldContentItem); + } + + contentItem = item; + q->contentItemChange(item, oldContentItem); + QQuickControlPrivate::hideOldItem(oldContentItem); + + if (item) { + connect(contentItem.data(), &QQuickItem::baselineOffsetChanged, this, &QQuickControlPrivate::updateBaselineOffset); + // We need to update the control's focusReason when the contentItem receives or loses focus. Since focusPolicy + // (or other properties impacting focus handling, like QQuickItem::activeFocusOnTab) might change later, and + // since the content item might also change focus programmatically, we always have to listen for those events. + QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickControlPrivate::Focus); + if (!item->parentItem()) + item->setParentItem(q); + if (componentComplete) + resizeContent(); + addImplicitSizeListener(contentItem); + } + + updateImplicitContentSize(); + updateBaselineOffset(); + + if (notify && !contentItem.isExecuting()) + emit q->contentItemChanged(); +} + +qreal QQuickControlPrivate::getContentWidth() const +{ + return contentItem ? contentItem->implicitWidth() : 0; +} + +qreal QQuickControlPrivate::getContentHeight() const +{ + return contentItem ? contentItem->implicitHeight() : 0; +} + +void QQuickControlPrivate::updateImplicitContentWidth() +{ + Q_Q(QQuickControl); + const qreal oldWidth = implicitContentWidth; + implicitContentWidth = getContentWidth(); + if (!qFuzzyCompare(implicitContentWidth, oldWidth)) + emit q->implicitContentWidthChanged(); +} + +void QQuickControlPrivate::updateImplicitContentHeight() +{ + Q_Q(QQuickControl); + const qreal oldHeight = implicitContentHeight; + implicitContentHeight = getContentHeight(); + if (!qFuzzyCompare(implicitContentHeight, oldHeight)) + emit q->implicitContentHeightChanged(); +} + +void QQuickControlPrivate::updateImplicitContentSize() +{ + Q_Q(QQuickControl); + const qreal oldWidth = implicitContentWidth; + const qreal oldHeight = implicitContentHeight; + implicitContentWidth = getContentWidth(); + implicitContentHeight = getContentHeight(); + if (!qFuzzyCompare(implicitContentWidth, oldWidth)) + emit q->implicitContentWidthChanged(); + if (!qFuzzyCompare(implicitContentHeight, oldHeight)) + emit q->implicitContentHeightChanged(); +} + +QPalette QQuickControlPrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::System); +} + +#if QT_CONFIG(accessibility) +void QQuickControlPrivate::accessibilityActiveChanged(bool active) +{ + Q_Q(QQuickControl); + return q->accessibilityActiveChanged(active); +} + +QAccessible::Role QQuickControlPrivate::accessibleRole() const +{ + Q_Q(const QQuickControl); + return q->accessibleRole(); +} + +QQuickAccessibleAttached *QQuickControlPrivate::accessibleAttached(const QObject *object) +{ + if (!QAccessible::isActive()) + return nullptr; + return QQuickAccessibleAttached::attachedProperties(object); +} +#endif + +/*! + \internal + + Returns the font that the control w inherits from its ancestors and + QGuiApplication::font. +*/ +QFont QQuickControlPrivate::parentFont(const QQuickItem *item) +{ + QQuickItem *p = item->parentItem(); + while (p) { + if (QQuickControl *control = qobject_cast<QQuickControl *>(p)) + return control->font(); + else if (QQuickLabel *label = qobject_cast<QQuickLabel *>(p)) + return label->font(); + else if (QQuickTextField *textField = qobject_cast<QQuickTextField *>(p)) + return textField->font(); + else if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea *>(p)) + return textArea->font(); + + p = p->parentItem(); + } + + if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(item->window())) + return window->font(); + + return QQuickTheme::font(QQuickTheme::System); +} + +/*! + \internal + + Determine which font is implicitly imposed on this control by its ancestors + and QGuiApplication::font, resolve this against its own font (attributes from + the implicit font are copied over). Then propagate this font to this + control's children. +*/ +void QQuickControlPrivate::resolveFont() +{ + Q_Q(QQuickControl); + inheritFont(parentFont(q)); +} + +void QQuickControlPrivate::inheritFont(const QFont &font) +{ + Q_Q(QQuickControl); + QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font; + parentFont.setResolveMask(extra.isAllocated() ? extra->requestedFont.resolveMask() | font.resolveMask() : font.resolveMask()); + + const QFont defaultFont = q->defaultFont(); + QFont resolvedFont = parentFont.resolve(defaultFont); + + setFont_helper(resolvedFont); +} + +/*! + \internal + + Assign \a font to this control, and propagate it to all children. +*/ +void QQuickControlPrivate::updateFont(const QFont &font) +{ + Q_Q(QQuickControl); + QFont oldFont = resolvedFont; + resolvedFont = font; + + if (oldFont != font) + q->fontChange(font, oldFont); + + QQuickControlPrivate::updateFontRecur(q, font); + + if (oldFont != font) + emit q->fontChanged(); +} + +void QQuickControlPrivate::updateFontRecur(QQuickItem *item, const QFont &font) +{ + const auto childItems = item->childItems(); + for (QQuickItem *child : childItems) { + if (QQuickControl *control = qobject_cast<QQuickControl *>(child)) + QQuickControlPrivate::get(control)->inheritFont(font); + else if (QQuickLabel *label = qobject_cast<QQuickLabel *>(child)) + QQuickLabelPrivate::get(label)->inheritFont(font); + else if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea *>(child)) + QQuickTextAreaPrivate::get(textArea)->inheritFont(font); + else if (QQuickTextField *textField = qobject_cast<QQuickTextField *>(child)) + QQuickTextFieldPrivate::get(textField)->inheritFont(font); + else + QQuickControlPrivate::updateFontRecur(child, font); + } +} + +QLocale QQuickControlPrivate::calcLocale(const QQuickItem *item) +{ + const QQuickItem *p = item; + while (p) { + if (const QQuickControl *control = qobject_cast<const QQuickControl *>(p)) + return control->locale(); + + QVariant v = p->property("locale"); + if (v.isValid() && v.userType() == QMetaType::QLocale) + return v.toLocale(); + + p = p->parentItem(); + } + + if (item) { + if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(item->window())) + return window->locale(); + } + + return QLocale(); +} + +void QQuickControlPrivate::updateLocale(const QLocale &l, bool e) +{ + Q_Q(QQuickControl); + if (!e && hasLocale) + return; + + QLocale old = q->locale(); + hasLocale = e; + if (old != l) { + locale = l; + q->localeChange(l, old); + QQuickControlPrivate::updateLocaleRecur(q, l); + emit q->localeChanged(); + } +} + +void QQuickControlPrivate::updateLocaleRecur(QQuickItem *item, const QLocale &l) +{ + const auto childItems = item->childItems(); + for (QQuickItem *child : childItems) { + if (QQuickControl *control = qobject_cast<QQuickControl *>(child)) + QQuickControlPrivate::get(control)->updateLocale(l, false); + else + updateLocaleRecur(child, l); + } +} + +#if QT_CONFIG(quicktemplates2_hover) +void QQuickControlPrivate::updateHoverEnabled(bool enabled, bool xplicit) +{ + Q_Q(QQuickControl); + if (!xplicit && explicitHoverEnabled) + return; + + bool wasEnabled = q->isHoverEnabled(); + explicitHoverEnabled = xplicit; + if (wasEnabled != enabled) { + q->setAcceptHoverEvents(enabled); + QQuickControlPrivate::updateHoverEnabledRecur(q, enabled); + emit q->hoverEnabledChanged(); + } +} + +void QQuickControlPrivate::updateHoverEnabledRecur(QQuickItem *item, bool enabled) +{ + const auto childItems = item->childItems(); + for (QQuickItem *child : childItems) { + if (QQuickControl *control = qobject_cast<QQuickControl *>(child)) + QQuickControlPrivate::get(control)->updateHoverEnabled(enabled, false); + else + updateHoverEnabledRecur(child, enabled); + } +} + +bool QQuickControlPrivate::calcHoverEnabled(const QQuickItem *item) +{ + const QQuickItem *p = item; + while (p) { + // QQuickPopupItem accepts hover events to avoid leaking them through. + // Don't inherit that to the children of the popup, but fallback to the + // environment variable or style hint. + if (qobject_cast<const QQuickPopupItem *>(p)) + break; + + if (const QQuickControl *control = qobject_cast<const QQuickControl *>(p)) + return control->isHoverEnabled(); + + QVariant v = p->property("hoverEnabled"); + if (v.isValid() && v.userType() == QMetaType::Bool) + return v.toBool(); + + p = p->parentItem(); + } + + bool ok = false; + int env = qEnvironmentVariableIntValue("QT_QUICK_CONTROLS_HOVER_ENABLED", &ok); + if (ok) + return env != 0; + + // TODO: QQuickApplicationWindow::isHoverEnabled() + + return QGuiApplication::styleHints()->useHoverEffects(); +} +#endif + +static inline QString contentItemName() { return QStringLiteral("contentItem"); } + +void QQuickControlPrivate::cancelContentItem() +{ + Q_Q(QQuickControl); + quickCancelDeferred(q, contentItemName()); +} + +void QQuickControlPrivate::executeContentItem(bool complete) +{ + Q_Q(QQuickControl); + if (contentItem.wasExecuted()) + return; + + if (!contentItem || complete) + quickBeginDeferred(q, contentItemName(), contentItem); + if (complete) + quickCompleteDeferred(q, contentItemName(), contentItem); +} + +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickControlPrivate::cancelBackground() +{ + Q_Q(QQuickControl); + quickCancelDeferred(q, backgroundName()); +} + +void QQuickControlPrivate::executeBackground(bool complete) +{ + Q_Q(QQuickControl); + if (background.wasExecuted()) + return; + + if (!background || complete) + quickBeginDeferred(q, backgroundName(), background); + if (complete) + quickCompleteDeferred(q, backgroundName(), background); +} + +/* + \internal + + Hides an item that was replaced by a newer one, rather than + deleting it, as the item is typically created in QML and hence + we don't own it. +*/ +void QQuickControlPrivate::hideOldItem(QQuickItem *item) +{ + if (!item) + return; + + qCDebug(lcItemManagement) << "hiding old item" << item; + + item->setVisible(false); + item->setParentItem(nullptr); + +#if QT_CONFIG(accessibility) + // Remove the item from the accessibility tree. + QQuickAccessibleAttached *accessible = accessibleAttached(item); + if (accessible) + accessible->setIgnored(true); +#endif +} + +/* + \internal + + Named "unhide" because it's used for cases where an item + that was previously hidden by \l hideOldItem() wants to be + shown by a control again, such as a ScrollBar in ScrollView. + + \a visibility controls the visibility of \a item, as there + may have been bindings that controlled visibility, such as + with a typical ScrollBar.qml implementation: + + \code + visible: control.policy !== T.ScrollBar.AlwaysOff + \endcode + + In the future we could try to save the binding for the visible + property (using e.g. QQmlAnyBinding::takeFrom), but for now we + keep it simple and just allow restoring an equivalent literal value. +*/ +void QQuickControlPrivate::unhideOldItem(QQuickControl *control, QQuickItem *item, UnhideVisibility visibility) +{ + Q_ASSERT(item); + qCDebug(lcItemManagement) << "unhiding old item" << item; + + item->setVisible(visibility == UnhideVisibility::Show); + item->setParentItem(control); + +#if QT_CONFIG(accessibility) + // Add the item back in to the accessibility tree. + QQuickAccessibleAttached *accessible = accessibleAttached(item); + if (accessible) + accessible->setIgnored(false); +#endif +} + +void QQuickControlPrivate::updateBaselineOffset() +{ + Q_Q(QQuickControl); + if (extra.isAllocated() && extra.value().hasBaselineOffset) + return; + + if (!contentItem) + q->QQuickItem::setBaselineOffset(0); + else + q->QQuickItem::setBaselineOffset(getTopPadding() + contentItem->baselineOffset()); +} + +void QQuickControlPrivate::addImplicitSizeListener(QQuickItem *item, ChangeTypes changes) +{ + addImplicitSizeListener(item, this, changes); +} + +void QQuickControlPrivate::removeImplicitSizeListener(QQuickItem *item, ChangeTypes changes) +{ + removeImplicitSizeListener(item, this, changes); +} + +void QQuickControlPrivate::addImplicitSizeListener(QQuickItem *item, QQuickItemChangeListener *listener, ChangeTypes changes) +{ + if (!item || !listener) + return; + QQuickItemPrivate::get(item)->addItemChangeListener(listener, changes); +} + +void QQuickControlPrivate::removeImplicitSizeListener(QQuickItem *item, QQuickItemChangeListener *listener, ChangeTypes changes) +{ + if (!item || !listener) + return; + QQuickItemPrivate::get(item)->removeItemChangeListener(listener, changes); +} + +void QQuickControlPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickControl); + if (item == background) + emit q->implicitBackgroundWidthChanged(); + else if (item == contentItem) + updateImplicitContentWidth(); +} + +void QQuickControlPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickControl); + if (item == background) + emit q->implicitBackgroundHeightChanged(); + else if (item == contentItem) + updateImplicitContentHeight(); +} + +void QQuickControlPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) +{ + Q_UNUSED(diff); + if (resizingBackground || item != background || !change.sizeChange()) + return; + + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + // Only set hasBackgroundWidth/Height if it was a width/height change, + // otherwise we're prevented from setting a width/height in the future. + if (change.widthChange()) + extra.value().hasBackgroundWidth = p->widthValid(); + if (change.heightChange()) + extra.value().hasBackgroundHeight = p->heightValid(); + resizeBackground(); +} + +void QQuickControlPrivate::itemDestroyed(QQuickItem *item) +{ + Q_Q(QQuickControl); + if (item == background) { + background = nullptr; + emit q->implicitBackgroundWidthChanged(); + emit q->implicitBackgroundHeightChanged(); + } else if (item == contentItem) { + contentItem = nullptr; + updateImplicitContentSize(); + } +} + +void QQuickControlPrivate::itemFocusChanged(QQuickItem *item, Qt::FocusReason reason) +{ + Q_Q(QQuickControl); + if (item == contentItem || item == q) + q->setFocusReason(reason); +} + +QQuickControl::QQuickControl(QQuickItem *parent) + : QQuickItem(*(new QQuickControlPrivate), parent) +{ + Q_D(QQuickControl); + d->init(); +} + +QQuickControl::QQuickControl(QQuickControlPrivate &dd, QQuickItem *parent) + : QQuickItem(dd, parent) +{ + Q_D(QQuickControl); + d->init(); +} + +QQuickControl::~QQuickControl() +{ + Q_D(QQuickControl); + d->removeImplicitSizeListener(d->background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); + d->removeImplicitSizeListener(d->contentItem); + if (d->contentItem) + QQuickItemPrivate::get(d->contentItem)->removeItemChangeListener(d, QQuickItemPrivate::Focus); +#if QT_CONFIG(accessibility) + QAccessible::removeActivationObserver(d); +#endif +} + +void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) +{ + Q_D(QQuickControl); + QQuickItem::itemChange(change, value); + switch (change) { + case ItemEnabledHasChanged: + enabledChange(); + break; + case ItemVisibleHasChanged: +#if QT_CONFIG(quicktemplates2_hover) + if (!value.boolValue) + setHovered(false); +#endif + break; + case ItemSceneChange: + case ItemParentHasChanged: + if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) { + d->resolveFont(); + if (!d->hasLocale) + d->updateLocale(QQuickControlPrivate::calcLocale(d->parentItem), false); // explicit=false +#if QT_CONFIG(quicktemplates2_hover) + if (!d->explicitHoverEnabled) + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false +#endif + } + break; + case ItemActiveFocusHasChanged: + if (isKeyFocusReason(d->focusReason)) + emit visualFocusChanged(); + break; + default: + break; + } +} + +/*! + \qmlproperty font QtQuick.Controls::Control::font + + This property holds the font currently set for the control. + + This property describes the control's requested font. The font is used by the control's + style when rendering standard components, and is available as a means to ensure that custom + controls can maintain consistency with the native platform's native look and feel. It's common + that different platforms, or different styles, define different fonts for an application. + + The default font depends on the system environment. ApplicationWindow maintains a system/theme + font which serves as a default for all controls. There may also be special font defaults for + certain types of controls. You can also set the default font for controls by either: + + \list + \li passing a custom font to QGuiApplication::setFont(), before loading the QML; or + \li specifying the fonts in the \l {Qt Quick Controls 2 Configuration File}{qtquickcontrols2.conf file}. + \endlist + + Finally, the font is matched against Qt's font database to find the best match. + + Control propagates explicit font properties from parent to children. If you change a specific + property on a control's font, that property propagates to all of the control's children, + overriding any system defaults for that property. + + \code + Page { + font.family: "Courier" + + Column { + Label { + text: qsTr("This will use Courier...") + } + + Switch { + text: qsTr("... and so will this") + } + } + } + \endcode + + For the full list of available font properties, see the + \l [QtQuick]{font}{font QML Basic Type} documentation. +*/ +QFont QQuickControl::font() const +{ + Q_D(const QQuickControl); + return d->resolvedFont; +} + +void QQuickControl::setFont(const QFont &font) +{ + Q_D(QQuickControl); + if (d->extra.value().requestedFont.resolveMask() == font.resolveMask() && d->extra.value().requestedFont == font) + return; + + d->extra.value().requestedFont = font; + d->resolveFont(); +} + +void QQuickControl::resetFont() +{ + setFont(QFont()); +} + +/*! + \qmlproperty real QtQuick.Controls::Control::availableWidth + \readonly + + This property holds the width available to the \l contentItem after + deducting horizontal padding from the \l {Item::}{width} of the control. + + \sa {Control Layout}, padding, leftPadding, rightPadding +*/ +qreal QQuickControl::availableWidth() const +{ + return qMax<qreal>(0.0, width() - leftPadding() - rightPadding()); +} + +/*! + \qmlproperty real QtQuick.Controls::Control::availableHeight + \readonly + + This property holds the height available to the \l contentItem after + deducting vertical padding from the \l {Item::}{height} of the control. + + \sa {Control Layout}, padding, topPadding, bottomPadding +*/ +qreal QQuickControl::availableHeight() const +{ + return qMax<qreal>(0.0, height() - topPadding() - bottomPadding()); +} + +/*! + \qmlproperty real QtQuick.Controls::Control::padding + + This property holds the default padding. + + Padding adds a space between each edge of the content item and the + background item, effectively controlling the size of the content item. To + specify a padding value for a specific edge of the control, set its + relevant property: + + \list + \li \l {Control::}{leftPadding} + \li \l {Control::}{rightPadding} + \li \l {Control::}{topPadding} + \li \l {Control::}{bottomPadding} + \endlist + + \note Different styles may specify the default padding for certain controls + in different ways, and these ways may change over time as the design + guidelines that the style is based on evolve. To ensure that these changes + don't affect the padding values you have specified, it is best to use the + most specific properties available. For example, rather than setting + the \l padding property: + + \code + padding: 0 + \endcode + + set each specific property instead: + + \code + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + \endcode + + \sa {Control Layout}, availableWidth, availableHeight, topPadding, leftPadding, rightPadding, bottomPadding +*/ +qreal QQuickControl::padding() const +{ + Q_D(const QQuickControl); + return d->padding; +} + +void QQuickControl::setPadding(qreal padding) +{ + Q_D(QQuickControl); + if (qFuzzyCompare(d->padding, padding)) + return; + + const QMarginsF oldPadding = d->getPadding(); + const qreal oldVerticalPadding = d->getVerticalPadding(); + const qreal oldHorizontalPadding = d->getHorizontalPadding(); + + d->padding = padding; + emit paddingChanged(); + + const QMarginsF newPadding = d->getPadding(); + const qreal newVerticalPadding = d->getVerticalPadding(); + const qreal newHorizontalPadding = d->getHorizontalPadding(); + + if (!qFuzzyCompare(newPadding.top(), oldPadding.top())) + emit topPaddingChanged(); + if (!qFuzzyCompare(newPadding.left(), oldPadding.left())) + emit leftPaddingChanged(); + if (!qFuzzyCompare(newPadding.right(), oldPadding.right())) + emit rightPaddingChanged(); + if (!qFuzzyCompare(newPadding.bottom(), oldPadding.bottom())) + emit bottomPaddingChanged(); + if (!qFuzzyCompare(newVerticalPadding, oldVerticalPadding)) + emit verticalPaddingChanged(); + if (!qFuzzyCompare(newHorizontalPadding, oldHorizontalPadding)) + emit horizontalPaddingChanged(); + if (!qFuzzyCompare(newPadding.top(), oldPadding.top()) || !qFuzzyCompare(newPadding.bottom(), oldPadding.bottom())) + emit availableHeightChanged(); + if (!qFuzzyCompare(newPadding.left(), oldPadding.left()) || !qFuzzyCompare(newPadding.right(), oldPadding.right())) + emit availableWidthChanged(); + + paddingChange(newPadding, oldPadding); +} + +void QQuickControl::resetPadding() +{ + setPadding(0); +} + +/*! + \qmlproperty real QtQuick.Controls::Control::topPadding + + This property holds the top padding. Unless explicitly set, the value + is equal to \c verticalPadding. + + \sa {Control Layout}, padding, bottomPadding, verticalPadding, availableHeight +*/ +qreal QQuickControl::topPadding() const +{ + Q_D(const QQuickControl); + return d->getTopPadding(); +} + +void QQuickControl::setTopPadding(qreal padding) +{ + Q_D(QQuickControl); + d->setTopPadding(padding); +} + +void QQuickControl::resetTopPadding() +{ + Q_D(QQuickControl); + d->setTopPadding(0, true); +} + +/*! + \qmlproperty real QtQuick.Controls::Control::leftPadding + + This property holds the left padding. Unless explicitly set, the value + is equal to \c horizontalPadding. + + \sa {Control Layout}, padding, rightPadding, horizontalPadding, availableWidth +*/ +qreal QQuickControl::leftPadding() const +{ + Q_D(const QQuickControl); + return d->getLeftPadding(); +} + +void QQuickControl::setLeftPadding(qreal padding) +{ + Q_D(QQuickControl); + d->setLeftPadding(padding); +} + +void QQuickControl::resetLeftPadding() +{ + Q_D(QQuickControl); + d->setLeftPadding(0, true); +} + +/*! + \qmlproperty real QtQuick.Controls::Control::rightPadding + + This property holds the right padding. Unless explicitly set, the value + is equal to \c horizontalPadding. + + \sa {Control Layout}, padding, leftPadding, horizontalPadding, availableWidth +*/ +qreal QQuickControl::rightPadding() const +{ + Q_D(const QQuickControl); + return d->getRightPadding(); +} + +void QQuickControl::setRightPadding(qreal padding) +{ + Q_D(QQuickControl); + d->setRightPadding(padding); +} + +void QQuickControl::resetRightPadding() +{ + Q_D(QQuickControl); + d->setRightPadding(0, true); +} + +/*! + \qmlproperty real QtQuick.Controls::Control::bottomPadding + + This property holds the bottom padding. Unless explicitly set, the value + is equal to \c verticalPadding. + + \sa {Control Layout}, padding, topPadding, verticalPadding, availableHeight +*/ +qreal QQuickControl::bottomPadding() const +{ + Q_D(const QQuickControl); + return d->getBottomPadding(); +} + +void QQuickControl::setBottomPadding(qreal padding) +{ + Q_D(QQuickControl); + d->setBottomPadding(padding); +} + +void QQuickControl::resetBottomPadding() +{ + Q_D(QQuickControl); + d->setBottomPadding(0, true); +} + +/*! + \qmlproperty real QtQuick.Controls::Control::spacing + + This property holds the spacing. + + Spacing is useful for controls that have multiple or repetitive building + blocks. For example, some styles use spacing to determine the distance + between the text and indicator of \l CheckBox. Spacing is not enforced by + Control, so each style may interpret it differently, and some may ignore it + altogether. +*/ +qreal QQuickControl::spacing() const +{ + Q_D(const QQuickControl); + return d->spacing; +} + +void QQuickControl::setSpacing(qreal spacing) +{ + Q_D(QQuickControl); + if (qFuzzyCompare(d->spacing, spacing)) + return; + + qreal oldSpacing = d->spacing; + d->spacing = spacing; + emit spacingChanged(); + spacingChange(spacing, oldSpacing); +} + +void QQuickControl::resetSpacing() +{ + setSpacing(0); +} + +/*! + \qmlproperty Locale QtQuick.Controls::Control::locale + + This property holds the locale of the control. + + It contains locale specific properties for formatting data and numbers. + Unless a special locale has been set, this is either the parent's locale + or the default locale. + + Control propagates the locale from parent to children. If you change the + control's locale, that locale propagates to all of the control's children, + overriding the system default locale. + + \sa mirrored +*/ +QLocale QQuickControl::locale() const +{ + Q_D(const QQuickControl); + return d->locale; +} + +void QQuickControl::setLocale(const QLocale &locale) +{ + Q_D(QQuickControl); + if (d->hasLocale && d->locale == locale) + return; + + d->updateLocale(locale, true); // explicit=true +} + +void QQuickControl::resetLocale() +{ + Q_D(QQuickControl); + if (!d->hasLocale) + return; + + d->hasLocale = false; + d->updateLocale(QQuickControlPrivate::calcLocale(d->parentItem), false); // explicit=false +} + +/*! + \qmlproperty bool QtQuick.Controls::Control::mirrored + \readonly + + This property holds whether the control is mirrored. + + This property is provided for convenience. A control is considered mirrored + when its visual layout direction is right-to-left; that is, when + \l {LayoutMirroring::enabled}{LayoutMirroring.enabled} is \c true. + + As of Qt 6.2, the \l locale property no longer affects this property. + + \sa {LayoutMirroring}{LayoutMirroring}, {Right-to-left User Interfaces} +*/ +bool QQuickControl::isMirrored() const +{ + Q_D(const QQuickControl); + return d->isMirrored(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::Control::focusPolicy + + This property determines the way the control accepts focus. + + \value Qt.TabFocus The control accepts focus by tabbing. + \value Qt.ClickFocus The control accepts focus by clicking. + \value Qt.StrongFocus The control accepts focus by both tabbing and clicking. + \value Qt.WheelFocus The control accepts focus by tabbing, clicking, and using the mouse wheel. + \value Qt.NoFocus The control does not accept focus. +*/ +Qt::FocusPolicy QQuickControl::focusPolicy() const +{ + Q_D(const QQuickControl); + uint policy = d->focusPolicy; + if (activeFocusOnTab()) + policy |= Qt::TabFocus; + return static_cast<Qt::FocusPolicy>(policy); +} + +void QQuickControl::setFocusPolicy(Qt::FocusPolicy policy) +{ + Q_D(QQuickControl); + if (d->focusPolicy == policy) + return; + + d->focusPolicy = policy; + setActiveFocusOnTab(policy & Qt::TabFocus); + emit focusPolicyChanged(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::Control::focusReason + \readonly + + \include qquickcontrol-focusreason.qdocinc + + \sa visualFocus +*/ +Qt::FocusReason QQuickControl::focusReason() const +{ + Q_D(const QQuickControl); + return d->focusReason; +} + +void QQuickControl::setFocusReason(Qt::FocusReason reason) +{ + Q_D(QQuickControl); + if (d->focusReason == reason) + return; + + Qt::FocusReason oldReason = d->focusReason; + d->focusReason = reason; + emit focusReasonChanged(); + if (isKeyFocusReason(oldReason) != isKeyFocusReason(reason)) + emit visualFocusChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::Control::visualFocus + \readonly + + This property holds whether the control has visual focus. This property + is \c true when the control has active focus and the focus reason is either + \c Qt.TabFocusReason, \c Qt.BacktabFocusReason, or \c Qt.ShortcutFocusReason. + + In general, for visualizing key focus, this property is preferred over + \l Item::activeFocus. This ensures that key focus is only visualized when + interacting with keys - not when interacting via touch or mouse. + + \sa focusReason, Item::activeFocus +*/ +bool QQuickControl::hasVisualFocus() const +{ + Q_D(const QQuickControl); + return d->activeFocus && isKeyFocusReason(d->focusReason); +} + +/*! + \qmlproperty bool QtQuick.Controls::Control::hovered + \readonly + + This property holds whether the control is hovered. + + \sa hoverEnabled +*/ +bool QQuickControl::isHovered() const +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(const QQuickControl); + return d->hovered; +#else + return false; +#endif +} + +void QQuickControl::setHovered(bool hovered) +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(QQuickControl); + if (hovered == d->hovered) + return; + + d->hovered = hovered; + emit hoveredChanged(); + hoverChange(); +#else + Q_UNUSED(hovered); +#endif +} + +/*! + \qmlproperty bool QtQuick.Controls::Control::hoverEnabled + + This property determines whether the control accepts hover events. The default value + is \c Qt.styleHints.useHoverEffects. + + Setting this property propagates the value to all child controls that do not have + \c hoverEnabled explicitly set. + + You can also enable or disable hover effects for all Qt Quick Controls applications + by setting the \c QT_QUICK_CONTROLS_HOVER_ENABLED \l {Supported Environment Variables + in Qt Quick Controls}{environment variable}. + + \sa hovered +*/ +bool QQuickControl::isHoverEnabled() const +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(const QQuickControl); + return d->hoverEnabled; +#else + return false; +#endif +} + +void QQuickControl::setHoverEnabled(bool enabled) +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(QQuickControl); + if (d->explicitHoverEnabled && enabled == d->hoverEnabled) + return; + + d->updateHoverEnabled(enabled, true); // explicit=true +#else + Q_UNUSED(enabled); +#endif +} + +void QQuickControl::resetHoverEnabled() +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(QQuickControl); + if (!d->explicitHoverEnabled) + return; + + d->explicitHoverEnabled = false; + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false +#endif +} + +/*! + \qmlproperty bool QtQuick.Controls::Control::wheelEnabled + + This property determines whether the control handles wheel events. The default value is \c false. + + \note Care must be taken when enabling wheel events for controls within scrollable items such + as \l Flickable, as the control will consume the events and hence interrupt scrolling of the + Flickable. +*/ +bool QQuickControl::isWheelEnabled() const +{ + Q_D(const QQuickControl); + return d->wheelEnabled; +} + +void QQuickControl::setWheelEnabled(bool enabled) +{ + Q_D(QQuickControl); + if (d->wheelEnabled == enabled) + return; + + d->wheelEnabled = enabled; + emit wheelEnabledChanged(); +} + +/*! + \qmlproperty Item QtQuick.Controls::Control::background + + This property holds the background item. + + \code + Button { + id: control + text: qsTr("Button") + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + opacity: enabled ? 1 : 0.3 + color: control.down ? "#d0d0d0" : "#e0e0e0" + } + } + \endcode + + \input qquickcontrol-background.qdocinc notes + + \sa {Control Layout} +*/ +QQuickItem *QQuickControl::background() const +{ + QQuickControlPrivate *d = const_cast<QQuickControlPrivate *>(d_func()); + if (!d->background) + d->executeBackground(); + return d->background; +} + +void QQuickControl::setBackground(QQuickItem *background) +{ + Q_D(QQuickControl); + if (d->background == background) + return; + + if (!d->background.isExecuting()) + d->cancelBackground(); + + const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth(); + const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight(); + + if (d->extra.isAllocated()) { + d->extra.value().hasBackgroundWidth = false; + d->extra.value().hasBackgroundHeight = false; + } + + d->removeImplicitSizeListener(d->background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); + QQuickControlPrivate::hideOldItem(d->background); + d->background = background; + + if (background) { + background->setParentItem(this); + if (qFuzzyIsNull(background->z())) + background->setZ(-1); + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + if (p->widthValid() || p->heightValid()) { + d->extra.value().hasBackgroundWidth = p->widthValid(); + d->extra.value().hasBackgroundHeight = p->heightValid(); + } + if (isComponentComplete()) + d->resizeBackground(); + d->addImplicitSizeListener(background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); + } + + if (!qFuzzyCompare(oldImplicitBackgroundWidth, implicitBackgroundWidth())) + emit implicitBackgroundWidthChanged(); + if (!qFuzzyCompare(oldImplicitBackgroundHeight, implicitBackgroundHeight())) + emit implicitBackgroundHeightChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); +} + +/*! + \qmlproperty Item QtQuick.Controls::Control::contentItem + + This property holds the visual content item. + + \code + Button { + id: control + text: qsTr("Button") + contentItem: Label { + text: control.text + font: control.font + verticalAlignment: Text.AlignVCenter + } + } + \endcode + + \note The content item is automatically positioned and resized to fit + within the \l padding of the control. Bindings to the + \l[QtQuick]{Item::}{x}, \l[QtQuick]{Item::}{y}, + \l[QtQuick]{Item::}{width}, and \l[QtQuick]{Item::}{height} + properties of the contentItem are not respected. + + \note Most controls use the implicit size of the content item to calculate + the implicit size of the control itself. If you replace the content item + with a custom one, you should also consider providing a sensible implicit + size for it (unless it is an item like \l Text which has its own implicit + size). + + \sa {Control Layout}, padding +*/ +QQuickItem *QQuickControl::contentItem() const +{ + QQuickControlPrivate *d = const_cast<QQuickControlPrivate *>(d_func()); + if (!d->contentItem) + d->setContentItem_helper(d->getContentItem(), false); + return d->contentItem; +} + +void QQuickControl::setContentItem(QQuickItem *item) +{ + Q_D(QQuickControl); + d->setContentItem_helper(item, true); +} + +qreal QQuickControl::baselineOffset() const +{ + Q_D(const QQuickControl); + return d->baselineOffset; +} + +void QQuickControl::setBaselineOffset(qreal offset) +{ + Q_D(QQuickControl); + d->extra.value().hasBaselineOffset = true; + QQuickItem::setBaselineOffset(offset); +} + +void QQuickControl::resetBaselineOffset() +{ + Q_D(QQuickControl); + if (!d->extra.isAllocated() || !d->extra.value().hasBaselineOffset) + return; + + if (d->extra.isAllocated()) + d->extra.value().hasBaselineOffset = false; + d->updateBaselineOffset(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::horizontalPadding + + This property holds the horizontal padding. Unless explicitly set, the value + is equal to \c padding. + + \sa {Control Layout}, padding, leftPadding, rightPadding, verticalPadding +*/ +qreal QQuickControl::horizontalPadding() const +{ + Q_D(const QQuickControl); + return d->getHorizontalPadding(); +} + +void QQuickControl::setHorizontalPadding(qreal padding) +{ + Q_D(QQuickControl); + d->setHorizontalPadding(padding); +} + +void QQuickControl::resetHorizontalPadding() +{ + Q_D(QQuickControl); + d->setHorizontalPadding(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::verticalPadding + + This property holds the vertical padding. Unless explicitly set, the value + is equal to \c padding. + + \sa {Control Layout}, padding, topPadding, bottomPadding, horizontalPadding +*/ +qreal QQuickControl::verticalPadding() const +{ + Q_D(const QQuickControl); + return d->getVerticalPadding(); +} + +void QQuickControl::setVerticalPadding(qreal padding) +{ + Q_D(QQuickControl); + d->setVerticalPadding(padding); +} + +void QQuickControl::resetVerticalPadding() +{ + Q_D(QQuickControl); + d->setVerticalPadding(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::implicitContentWidth + \readonly + + This property holds the implicit content width. + + For basic controls, the value is equal to \c {contentItem ? contentItem.implicitWidth : 0}. + For types that inherit Container or Pane, the value is calculated based on the content children. + + This is typically used, together with \l implicitBackgroundWidth, to calculate + the \l {Item::}{implicitWidth}: + + \code + Control { + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + } + \endcode + + \sa implicitContentHeight, implicitBackgroundWidth +*/ +qreal QQuickControl::implicitContentWidth() const +{ + Q_D(const QQuickControl); + return d->implicitContentWidth; +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::implicitContentHeight + \readonly + + This property holds the implicit content height. + + For basic controls, the value is equal to \c {contentItem ? contentItem.implicitHeight : 0}. + For types that inherit Container or Pane, the value is calculated based on the content children. + + This is typically used, together with \l implicitBackgroundHeight, to calculate + the \l {Item::}{implicitHeight}: + + \code + Control { + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + } + \endcode + + \sa implicitContentWidth, implicitBackgroundHeight +*/ +qreal QQuickControl::implicitContentHeight() const +{ + Q_D(const QQuickControl); + return d->implicitContentHeight; +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::implicitBackgroundWidth + \readonly + + This property holds the implicit background width. + + The value is equal to \c {background ? background.implicitWidth : 0}. + + This is typically used, together with \l implicitContentWidth, to calculate + the \l {Item::}{implicitWidth}: + + \code + Control { + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + } + \endcode + + \sa implicitBackgroundHeight, implicitContentWidth +*/ +qreal QQuickControl::implicitBackgroundWidth() const +{ + Q_D(const QQuickControl); + if (!d->background) + return 0; + return d->background->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::implicitBackgroundHeight + \readonly + + This property holds the implicit background height. + + The value is equal to \c {background ? background.implicitHeight : 0}. + + This is typically used, together with \l implicitContentHeight, to calculate + the \l {Item::}{implicitHeight}: + + \code + Control { + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + } + \endcode + + \sa implicitBackgroundWidth, implicitContentHeight +*/ +qreal QQuickControl::implicitBackgroundHeight() const +{ + Q_D(const QQuickControl); + if (!d->background) + return 0; + return d->background->implicitHeight(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::topInset + + This property holds the top inset for the background. + + \sa {Control Layout}, bottomInset +*/ +qreal QQuickControl::topInset() const +{ + Q_D(const QQuickControl); + return d->getTopInset(); +} + +void QQuickControl::setTopInset(qreal inset) +{ + Q_D(QQuickControl); + d->setTopInset(inset); +} + +void QQuickControl::resetTopInset() +{ + Q_D(QQuickControl); + d->setTopInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::leftInset + + This property holds the left inset for the background. + + \sa {Control Layout}, rightInset +*/ +qreal QQuickControl::leftInset() const +{ + Q_D(const QQuickControl); + return d->getLeftInset(); +} + +void QQuickControl::setLeftInset(qreal inset) +{ + Q_D(QQuickControl); + d->setLeftInset(inset); +} + +void QQuickControl::resetLeftInset() +{ + Q_D(QQuickControl); + d->setLeftInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::rightInset + + This property holds the right inset for the background. + + \sa {Control Layout}, leftInset +*/ +qreal QQuickControl::rightInset() const +{ + Q_D(const QQuickControl); + return d->getRightInset(); +} + +void QQuickControl::setRightInset(qreal inset) +{ + Q_D(QQuickControl); + d->setRightInset(inset); +} + +void QQuickControl::resetRightInset() +{ + Q_D(QQuickControl); + d->setRightInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::bottomInset + + This property holds the bottom inset for the background. + + \sa {Control Layout}, topInset +*/ +qreal QQuickControl::bottomInset() const +{ + Q_D(const QQuickControl); + return d->getBottomInset(); +} + +void QQuickControl::setBottomInset(qreal inset) +{ + Q_D(QQuickControl); + d->setBottomInset(inset); +} + +void QQuickControl::resetBottomInset() +{ + Q_D(QQuickControl); + d->setBottomInset(0, true); +} + +void QQuickControl::classBegin() +{ + Q_D(QQuickControl); + QQuickItem::classBegin(); + d->resolveFont(); +} + +void QQuickControl::componentComplete() +{ + Q_D(QQuickControl); + d->executeBackground(true); + d->executeContentItem(true); + QQuickItem::componentComplete(); + d->resizeBackground(); + d->resizeContent(); + d->updateBaselineOffset(); + if (!d->hasLocale) + d->locale = QQuickControlPrivate::calcLocale(d->parentItem); +#if QT_CONFIG(quicktemplates2_hover) + if (!d->explicitHoverEnabled) + setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(d->parentItem)); +#endif +#if QT_CONFIG(accessibility) + if (QAccessible::isActive()) + accessibilityActiveChanged(true); +#endif +} + +QFont QQuickControl::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::System); +} + +void QQuickControl::focusInEvent(QFocusEvent *event) +{ + QQuickItem::focusInEvent(event); + setFocusReason(event->reason()); +} + +void QQuickControl::focusOutEvent(QFocusEvent *event) +{ + QQuickItem::focusOutEvent(event); + setFocusReason(event->reason()); +} + +#if QT_CONFIG(quicktemplates2_hover) +void QQuickControl::hoverEnterEvent(QHoverEvent *event) +{ + Q_D(QQuickControl); + setHovered(d->hoverEnabled); + event->ignore(); +} + +void QQuickControl::hoverMoveEvent(QHoverEvent *event) +{ + Q_D(QQuickControl); + setHovered(d->hoverEnabled && contains(event->position())); + event->ignore(); +} + +void QQuickControl::hoverLeaveEvent(QHoverEvent *event) +{ + setHovered(false); + event->ignore(); +} +#endif + +void QQuickControl::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickControl); + d->handlePress(event->position()); + if (event->source() == Qt::MouseEventSynthesizedByQt) { + d->pressWasTouch = true; + d->previousPressPos = event->position(); + } + event->accept(); +} + +void QQuickControl::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QQuickControl); + d->handleMove(event->position()); + event->accept(); +} + +void QQuickControl::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QQuickControl); + d->handleRelease(event->position()); + event->accept(); +} + +void QQuickControl::mouseUngrabEvent() +{ + Q_D(QQuickControl); + d->handleUngrab(); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickControl::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickControl); + switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + for (const QTouchEvent::TouchPoint &point : event->points()) { + if (!d->acceptTouch(point)) + continue; + + switch (point.state()) { + case QEventPoint::Pressed: + d->handlePress(point.position()); + break; + case QEventPoint::Updated: + d->handleMove(point.position()); + break; + case QEventPoint::Released: + d->handleRelease(point.position()); + break; + default: + break; + } + } + break; + + case QEvent::TouchCancel: + d->handleUngrab(); + break; + + default: + QQuickItem::touchEvent(event); + break; + } +} + +void QQuickControl::touchUngrabEvent() +{ + Q_D(QQuickControl); + d->handleUngrab(); +} +#endif + +#if QT_CONFIG(wheelevent) +void QQuickControl::wheelEvent(QWheelEvent *event) +{ + Q_D(QQuickControl); + if ((d->focusPolicy & Qt::WheelFocus) == Qt::WheelFocus) + setActiveFocus(this, Qt::MouseFocusReason); + + event->setAccepted(d->wheelEnabled); +} +#endif + +void QQuickControl::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickControl); + QQuickItem::geometryChange(newGeometry, oldGeometry); + d->resizeBackground(); + d->resizeContent(); + if (!qFuzzyCompare(newGeometry.width(), oldGeometry.width())) + emit availableWidthChanged(); + if (!qFuzzyCompare(newGeometry.height(), oldGeometry.height())) + emit availableHeightChanged(); +} + +void QQuickControl::enabledChange() +{ +} + +void QQuickControl::fontChange(const QFont &newFont, const QFont &oldFont) +{ + Q_UNUSED(newFont); + Q_UNUSED(oldFont); +} + +#if QT_CONFIG(quicktemplates2_hover) +void QQuickControl::hoverChange() +{ +} +#endif + +void QQuickControl::mirrorChange() +{ + emit mirroredChanged(); +} + +void QQuickControl::spacingChange(qreal newSpacing, qreal oldSpacing) +{ + Q_UNUSED(newSpacing); + Q_UNUSED(oldSpacing); +} + +void QQuickControl::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) +{ + Q_D(QQuickControl); + Q_UNUSED(newPadding); + Q_UNUSED(oldPadding); + d->resizeContent(); + d->updateBaselineOffset(); +} + +void QQuickControl::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + Q_UNUSED(newItem); + Q_UNUSED(oldItem); +} + +void QQuickControl::localeChange(const QLocale &newLocale, const QLocale &oldLocale) +{ + Q_UNUSED(newLocale); + Q_UNUSED(oldLocale); +} + +void QQuickControl::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset) +{ + Q_D(QQuickControl); + Q_UNUSED(newInset); + Q_UNUSED(oldInset); + d->resizeBackground(); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickControl::accessibleRole() const +{ + return QAccessible::NoRole; +} + +void QQuickControl::accessibilityActiveChanged(bool active) +{ + Q_D(QQuickControl); + if (!active) + return; + + QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(this, true)); + Q_ASSERT(accessibleAttached); + accessibleAttached->setRole(d->effectiveAccessibleRole()); +} +#endif + +QString QQuickControl::accessibleName() const +{ +#if QT_CONFIG(accessibility) + if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this)) + return accessibleAttached->name(); +#endif + return QString(); +} + +void QQuickControl::maybeSetAccessibleName(const QString &name) +{ +#if QT_CONFIG(accessibility) + if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this)) { + if (!accessibleAttached->wasNameExplicitlySet()) + accessibleAttached->setNameImplicitly(name); + } +#else + Q_UNUSED(name); +#endif +} + +QVariant QQuickControl::accessibleProperty(const char *propertyName) +{ +#if QT_CONFIG(accessibility) + if (QAccessible::isActive()) + return QQuickAccessibleAttached::property(this, propertyName); +#endif + Q_UNUSED(propertyName); + return QVariant(); +} + +bool QQuickControl::setAccessibleProperty(const char *propertyName, const QVariant &value) +{ +#if QT_CONFIG(accessibility) + if (QAccessible::isActive()) + return QQuickAccessibleAttached::setProperty(this, propertyName, value); +#endif + Q_UNUSED(propertyName); + Q_UNUSED(value); + return false; +} + +QT_END_NAMESPACE + +#include "moc_qquickcontrol_p.cpp" diff --git a/src/quicktemplates2/qquickcontrol_p.h b/src/quicktemplates2/qquickcontrol_p.h new file mode 100644 index 00000000000..79fb3915b0b --- /dev/null +++ b/src/quicktemplates2/qquickcontrol_p.h @@ -0,0 +1,320 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCONTROL_P_H +#define QQUICKCONTROL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qlocale.h> +#include <QtGui/qpalette.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/private/qquickpalette_p.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickControlPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControl : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QFont font READ font WRITE setFont RESET resetFont NOTIFY fontChanged FINAL) + Q_PROPERTY(qreal availableWidth READ availableWidth NOTIFY availableWidthChanged FINAL) + Q_PROPERTY(qreal availableHeight READ availableHeight NOTIFY availableHeightChanged FINAL) + Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged FINAL) + Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged FINAL) + Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged FINAL) + Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged FINAL) + Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged FINAL) + Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing RESET resetSpacing NOTIFY spacingChanged FINAL) + Q_PROPERTY(QLocale locale READ locale WRITE setLocale RESET resetLocale NOTIFY localeChanged FINAL) + Q_PROPERTY(bool mirrored READ isMirrored NOTIFY mirroredChanged FINAL) + Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy NOTIFY focusPolicyChanged FINAL) + Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) + Q_PROPERTY(bool visualFocus READ hasVisualFocus NOTIFY visualFocusChanged FINAL) + Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged FINAL) + Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL) + Q_PROPERTY(bool wheelEnabled READ isWheelEnabled WRITE setWheelEnabled NOTIFY wheelEnabledChanged FINAL) + Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) + Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) + Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset RESET resetBaselineOffset NOTIFY baselineOffsetChanged FINAL) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal horizontalPadding READ horizontalPadding WRITE setHorizontalPadding RESET resetHorizontalPadding NOTIFY horizontalPaddingChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal verticalPadding READ verticalPadding WRITE setVerticalPadding RESET resetVerticalPadding NOTIFY verticalPaddingChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitContentWidth READ implicitContentWidth NOTIFY implicitContentWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitContentHeight READ implicitContentHeight NOTIFY implicitContentHeightChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitBackgroundWidth READ implicitBackgroundWidth NOTIFY implicitBackgroundWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitBackgroundHeight READ implicitBackgroundHeight NOTIFY implicitBackgroundHeightChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal topInset READ topInset WRITE setTopInset RESET resetTopInset NOTIFY topInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal leftInset READ leftInset WRITE setLeftInset RESET resetLeftInset NOTIFY leftInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal rightInset READ rightInset WRITE setRightInset RESET resetRightInset NOTIFY rightInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal bottomInset READ bottomInset WRITE setBottomInset RESET resetBottomInset NOTIFY bottomInsetChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem") + QML_NAMED_ELEMENT(Control) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickControl(QQuickItem *parent = nullptr); + ~QQuickControl(); + + QFont font() const; + void setFont(const QFont &font); + void resetFont(); + + qreal availableWidth() const; + qreal availableHeight() const; + + qreal padding() const; + void setPadding(qreal padding); + void resetPadding(); + + qreal topPadding() const; + void setTopPadding(qreal padding); + void resetTopPadding(); + + qreal leftPadding() const; + void setLeftPadding(qreal padding); + void resetLeftPadding(); + + qreal rightPadding() const; + void setRightPadding(qreal padding); + void resetRightPadding(); + + qreal bottomPadding() const; + void setBottomPadding(qreal padding); + void resetBottomPadding(); + + qreal spacing() const; + void setSpacing(qreal spacing); + void resetSpacing(); + + QLocale locale() const; + void setLocale(const QLocale &locale); + void resetLocale(); + + bool isMirrored() const; + + Qt::FocusPolicy focusPolicy() const; + void setFocusPolicy(Qt::FocusPolicy policy); + + Qt::FocusReason focusReason() const; + void setFocusReason(Qt::FocusReason reason); + + bool hasVisualFocus() const; + + bool isHovered() const; + void setHovered(bool hovered); + + bool isHoverEnabled() const; + void setHoverEnabled(bool enabled); + void resetHoverEnabled(); + + bool isWheelEnabled() const; + void setWheelEnabled(bool enabled); + + QQuickItem *background() const; + void setBackground(QQuickItem *background); + + QQuickItem *contentItem() const; + void setContentItem(QQuickItem *item); + + qreal baselineOffset() const; + void setBaselineOffset(qreal offset); + void resetBaselineOffset(); + + // 2.5 (Qt 5.12) + qreal horizontalPadding() const; + void setHorizontalPadding(qreal padding); + void resetHorizontalPadding(); + + qreal verticalPadding() const; + void setVerticalPadding(qreal padding); + void resetVerticalPadding(); + + qreal implicitContentWidth() const; + qreal implicitContentHeight() const; + + qreal implicitBackgroundWidth() const; + qreal implicitBackgroundHeight() const; + + qreal topInset() const; + void setTopInset(qreal inset); + void resetTopInset(); + + qreal leftInset() const; + void setLeftInset(qreal inset); + void resetLeftInset(); + + qreal rightInset() const; + void setRightInset(qreal inset); + void resetRightInset(); + + qreal bottomInset() const; + void setBottomInset(qreal inset); + void resetBottomInset(); + +Q_SIGNALS: + void fontChanged(); + void availableWidthChanged(); + void availableHeightChanged(); + void paddingChanged(); + void topPaddingChanged(); + void leftPaddingChanged(); + void rightPaddingChanged(); + void bottomPaddingChanged(); + void spacingChanged(); + void localeChanged(); + void mirroredChanged(); + void focusPolicyChanged(); + void focusReasonChanged(); + void visualFocusChanged(); + void hoveredChanged(); + void hoverEnabledChanged(); + void wheelEnabledChanged(); + void backgroundChanged(); + void contentItemChanged(); + void baselineOffsetChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void horizontalPaddingChanged(); + Q_REVISION(2, 5) void verticalPaddingChanged(); + Q_REVISION(2, 5) void implicitContentWidthChanged(); + Q_REVISION(2, 5) void implicitContentHeightChanged(); + Q_REVISION(2, 5) void implicitBackgroundWidthChanged(); + Q_REVISION(2, 5) void implicitBackgroundHeightChanged(); + Q_REVISION(2, 5) void topInsetChanged(); + Q_REVISION(2, 5) void leftInsetChanged(); + Q_REVISION(2, 5) void rightInsetChanged(); + Q_REVISION(2, 5) void bottomInsetChanged(); + +protected: + virtual QFont defaultFont() const; + + QQuickControl(QQuickControlPrivate &dd, QQuickItem *parent); + + void classBegin() override; + void componentComplete() override; + + void itemChange(ItemChange change, const ItemChangeData &value) override; + + void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; +#if QT_CONFIG(quicktemplates2_hover) + void hoverEnterEvent(QHoverEvent *event) override; + void hoverMoveEvent(QHoverEvent *event) override; + void hoverLeaveEvent(QHoverEvent *event) override; +#endif + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void mouseUngrabEvent() override; +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; + void touchUngrabEvent() override; +#endif +#if QT_CONFIG(wheelevent) + void wheelEvent(QWheelEvent *event) override; +#endif + + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + + virtual void fontChange(const QFont &newFont, const QFont &oldFont); +#if QT_CONFIG(quicktemplates2_hover) + virtual void hoverChange(); +#endif + virtual void mirrorChange(); + virtual void spacingChange(qreal newSpacing, qreal oldSpacing); + virtual void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding); + virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem); + virtual void localeChange(const QLocale &newLocale, const QLocale &oldLocale); + virtual void insetChange(const QMarginsF &newInset, const QMarginsF &oldInset); + virtual void enabledChange(); + +#if QT_CONFIG(accessibility) + virtual QAccessible::Role accessibleRole() const; + virtual void accessibilityActiveChanged(bool active); +#endif + + // helper functions which avoid to check QT_CONFIG(accessibility) + QString accessibleName() const; + void maybeSetAccessibleName(const QString &name); + + QVariant accessibleProperty(const char *propertyName); + bool setAccessibleProperty(const char *propertyName, const QVariant &value); + +private: + Q_DISABLE_COPY(QQuickControl) + Q_DECLARE_PRIVATE(QQuickControl) +}; + +struct QQuickItemForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickItem) + QML_ADDED_IN_VERSION(2, 3) +}; + +struct QQuickColorGroupForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickColorGroup) + QML_ADDED_IN_VERSION(6, 0) +}; + +struct QQuickPaletteForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickPalette) + QML_ADDED_IN_VERSION(6, 0) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickControl) + +#endif // QQUICKCONTROL_P_H diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h new file mode 100644 index 00000000000..32840e6aafc --- /dev/null +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -0,0 +1,250 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCONTROL_P_P_H +#define QQUICKCONTROL_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQml/private/qlazilyallocated_p.h> + +#if QT_CONFIG(accessibility) +#include <QtGui/qaccessible.h> +#endif + +#include <QtCore/qloggingcategory.h> + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcItemManagement) + +class QQuickAccessibleAttached; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControlPrivate : public QQuickItemPrivate, public QQuickItemChangeListener +#if QT_CONFIG(accessibility) + , public QAccessible::ActivationObserver +#endif +{ + Q_DECLARE_PUBLIC(QQuickControl) + +public: + QQuickControlPrivate(); + ~QQuickControlPrivate(); + + static QQuickControlPrivate *get(QQuickControl *control) + { + return control->d_func(); + } + + void init(); + +#if QT_CONFIG(quicktemplates2_multitouch) + virtual bool acceptTouch(const QTouchEvent::TouchPoint &point); +#endif + virtual void handlePress(const QPointF &point); + virtual void handleMove(const QPointF &point); + virtual void handleRelease(const QPointF &point); + virtual void handleUngrab(); + + void mirrorChange() override; + + inline QMarginsF getPadding() const { return QMarginsF(getLeftPadding(), getTopPadding(), getRightPadding(), getBottomPadding()); } + inline qreal getTopPadding() const { return extra.isAllocated() && extra->hasTopPadding ? extra->topPadding : getVerticalPadding(); } + inline qreal getLeftPadding() const { return extra.isAllocated() && extra->hasLeftPadding ? extra->leftPadding : getHorizontalPadding(); } + inline qreal getRightPadding() const { return extra.isAllocated() && extra->hasRightPadding ? extra->rightPadding : getHorizontalPadding(); } + inline qreal getBottomPadding() const { return extra.isAllocated() && extra->hasBottomPadding ? extra->bottomPadding : getVerticalPadding(); } + inline qreal getHorizontalPadding() const { return hasHorizontalPadding ? horizontalPadding : padding; } + inline qreal getVerticalPadding() const { return hasVerticalPadding ? verticalPadding : padding; } + + void setTopPadding(qreal value, bool reset = false); + void setLeftPadding(qreal value, bool reset = false); + void setRightPadding(qreal value, bool reset = false); + void setBottomPadding(qreal value, bool reset = false); + void setHorizontalPadding(qreal value, bool reset = false); + void setVerticalPadding(qreal value, bool reset = false); + + inline QMarginsF getInset() const { return QMarginsF(getLeftInset(), getTopInset(), getRightInset(), getBottomInset()); } + inline qreal getTopInset() const { return extra.isAllocated() ? extra->topInset : 0; } + inline qreal getLeftInset() const { return extra.isAllocated() ? extra->leftInset : 0; } + inline qreal getRightInset() const { return extra.isAllocated() ? extra->rightInset : 0; } + inline qreal getBottomInset() const { return extra.isAllocated() ? extra->bottomInset : 0; } + + void setTopInset(qreal value, bool reset = false); + void setLeftInset(qreal value, bool reset = false); + void setRightInset(qreal value, bool reset = false); + void setBottomInset(qreal value, bool reset = false); + + virtual void resizeBackground(); + virtual void resizeContent(); + + virtual QQuickItem *getContentItem(); + void setContentItem_helper(QQuickItem *item, bool notify = true); + +#if QT_CONFIG(accessibility) + void accessibilityActiveChanged(bool active) override; + QAccessible::Role accessibleRole() const override; + static QQuickAccessibleAttached *accessibleAttached(const QObject *object); +#endif + + virtual void resolveFont(); + void inheritFont(const QFont &font); + void updateFont(const QFont &font); + static void updateFontRecur(QQuickItem *item, const QFont &font); + inline void setFont_helper(const QFont &font) { + if (resolvedFont.resolveMask() == font.resolveMask() && resolvedFont == font) + return; + updateFont(font); + } + static QFont parentFont(const QQuickItem *item); + + void updateLocale(const QLocale &l, bool e); + static void updateLocaleRecur(QQuickItem *item, const QLocale &l); + static QLocale calcLocale(const QQuickItem *item); + +#if QT_CONFIG(quicktemplates2_hover) + void updateHoverEnabled(bool enabled, bool xplicit); + static void updateHoverEnabledRecur(QQuickItem *item, bool enabled); + static bool calcHoverEnabled(const QQuickItem *item); +#endif + + virtual void cancelContentItem(); + virtual void executeContentItem(bool complete = false); + + virtual void cancelBackground(); + virtual void executeBackground(bool complete = false); + + enum class UnhideVisibility { + Show, + Hide + }; + + static void hideOldItem(QQuickItem *item); + static void unhideOldItem(QQuickControl *control, QQuickItem *item, + UnhideVisibility visibility = UnhideVisibility::Show); + + void updateBaselineOffset(); + + static const ChangeTypes ImplicitSizeChanges; + + void addImplicitSizeListener(QQuickItem *item, ChangeTypes changes = ImplicitSizeChanges); + void removeImplicitSizeListener(QQuickItem *item, ChangeTypes changes = ImplicitSizeChanges); + + static void addImplicitSizeListener(QQuickItem *item, QQuickItemChangeListener *listener, ChangeTypes changes = ImplicitSizeChanges); + static void removeImplicitSizeListener(QQuickItem *item, QQuickItemChangeListener *listener, ChangeTypes changes = ImplicitSizeChanges); + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + void itemDestroyed(QQuickItem *item) override; + void itemFocusChanged(QQuickItem *item, Qt::FocusReason reason) override; + + virtual qreal getContentWidth() const; + virtual qreal getContentHeight() const; + + void updateImplicitContentWidth(); + void updateImplicitContentHeight(); + void updateImplicitContentSize(); + + QPalette defaultPalette() const override; + + struct ExtraData { + bool hasTopPadding = false; + bool hasLeftPadding = false; + bool hasRightPadding = false; + bool hasBottomPadding = false; + bool hasBaselineOffset = false; + bool hasTopInset = false; + bool hasLeftInset = false; + bool hasRightInset = false; + bool hasBottomInset = false; + bool hasBackgroundWidth = false; + bool hasBackgroundHeight = false; + qreal topPadding = 0; + qreal leftPadding = 0; + qreal rightPadding = 0; + qreal bottomPadding = 0; + qreal topInset = 0; + qreal leftInset = 0; + qreal rightInset = 0; + qreal bottomInset = 0; + QFont requestedFont; + }; + QLazilyAllocated<ExtraData> extra; + + bool hasHorizontalPadding = false; + bool hasVerticalPadding = false; + bool hasLocale = false; + bool wheelEnabled = false; +#if QT_CONFIG(quicktemplates2_hover) + bool hovered = false; + bool explicitHoverEnabled = false; +#endif + bool resizingBackground = false; + bool pressWasTouch = false; + int touchId = -1; + QPointF previousPressPos; + qreal padding = 0; + qreal horizontalPadding = 0; + qreal verticalPadding = 0; + qreal implicitContentWidth = 0; + qreal implicitContentHeight = 0; + qreal spacing = 0; + QLocale locale; + QFont resolvedFont; + Qt::FocusPolicy focusPolicy = Qt::NoFocus; + Qt::FocusReason focusReason = Qt::OtherFocusReason; + QQuickDeferredPointer<QQuickItem> background; + QQuickDeferredPointer<QQuickItem> contentItem; +}; + +QT_END_NAMESPACE + +#endif // QQUICKCONTROL_P_P_H diff --git a/src/quicktemplates2/qquickdeferredexecute.cpp b/src/quicktemplates2/qquickdeferredexecute.cpp new file mode 100644 index 00000000000..635b7c142a5 --- /dev/null +++ b/src/quicktemplates2/qquickdeferredexecute.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickdeferredexecute_p_p.h" + +#include <QtCore/qhash.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/private/qqmldata_p.h> +#include <QtQml/private/qqmlcomponent_p.h> +#include <QtQml/private/qqmlobjectcreator_p.h> + +#include <deque> + +QT_BEGIN_NAMESPACE + +namespace QtQuickPrivate { + +typedef QHash<size_t, QQmlComponentPrivate::DeferredState *> DeferredStates; + +static inline size_t qHash(QObject *object, const QString &propertyName) +{ + return ::qHash(object) + ::qHash(propertyName); +} + +Q_GLOBAL_STATIC(DeferredStates, deferredStates) + +static void cancelDeferred(QQmlData *ddata, int propertyIndex) +{ + auto dit = ddata->deferredData.rbegin(); + while (dit != ddata->deferredData.rend()) { + (*dit)->bindings.remove(propertyIndex); + ++dit; + } +} + +static bool beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &property, QQmlComponentPrivate::DeferredState *deferredState) +{ + QObject *object = property.object(); + QQmlData *ddata = QQmlData::get(object); + Q_ASSERT(!ddata->deferredData.isEmpty()); + + int propertyIndex = property.index(); + int wasInProgress = enginePriv->inProgressCreations; + + /* we don't want deferred properties to suddenly depend on arbitrary + other properties which might have trigerred the construction of + objects as a consequence of a read. + */ + auto bindingStatus = QtPrivate::suspendCurrentBindingStatus(); + auto cleanup = qScopeGuard([&](){ + QtPrivate::restoreBindingStatus(bindingStatus); + }); + + for (auto dit = ddata->deferredData.rbegin(); dit != ddata->deferredData.rend(); ++dit) { + QQmlData::DeferredData *deferData = *dit; + + auto bindings = deferData->bindings; + auto range = bindings.equal_range(propertyIndex); + if (range.first == bindings.end()) + continue; + + QQmlComponentPrivate::ConstructionState *state = new QQmlComponentPrivate::ConstructionState; + state->completePending = true; + + QQmlContextData *creationContext = nullptr; + state->creator.reset(new QQmlObjectCreator(deferData->context->parent(), deferData->compilationUnit, creationContext)); + + enginePriv->inProgressCreations++; + + std::deque<const QV4::CompiledData::Binding *> reversedBindings; + std::copy(range.first, range.second, std::front_inserter(reversedBindings)); + state->creator->beginPopulateDeferred(deferData->context); + for (const QV4::CompiledData::Binding *binding : reversedBindings) + state->creator->populateDeferredBinding(property, deferData->deferredIdx, binding); + state->creator->finalizePopulateDeferred(); + state->errors << state->creator->errors; + + deferredState->constructionStates += state; + + // Cleanup any remaining deferred bindings for this property, also in inner contexts, + // to avoid executing them later and overriding the property that was just populated. + cancelDeferred(ddata, propertyIndex); + break; + } + + return enginePriv->inProgressCreations > wasInProgress; +} + +void beginDeferred(QObject *object, const QString &property) +{ + QQmlData *data = QQmlData::get(object); + if (data && !data->deferredData.isEmpty() && !data->wasDeleted(object) && data->context) { + QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine()); + + QQmlComponentPrivate::DeferredState *state = new QQmlComponentPrivate::DeferredState; + if (beginDeferred(ep, QQmlProperty(object, property), state)) + deferredStates()->insert(qHash(object, property), state); + else + delete state; + + // Release deferred data for those compilation units that no longer have deferred bindings + data->releaseDeferredData(); + } +} + +void cancelDeferred(QObject *object, const QString &property) +{ + QQmlData *data = QQmlData::get(object); + if (data) + cancelDeferred(data, QQmlProperty(object, property).index()); +} + +void completeDeferred(QObject *object, const QString &property) +{ + QQmlData *data = QQmlData::get(object); + QQmlComponentPrivate::DeferredState *state = deferredStates()->take(qHash(object, property)); + if (data && state && !data->wasDeleted(object)) { + /* we don't want deferred properties to suddenly depend on arbitrary + other properties which might have trigerred the construction of + objects as a consequence of a read. + */ + auto bindingStatus = QtPrivate::suspendCurrentBindingStatus(); + auto cleanup = qScopeGuard([&](){ + QtPrivate::restoreBindingStatus(bindingStatus); + }); + + QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine()); + QQmlComponentPrivate::completeDeferred(ep, state); + } + delete state; +} + +} // QtQuickPrivate + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickdeferredexecute_p_p.h b/src/quicktemplates2/qquickdeferredexecute_p_p.h new file mode 100644 index 00000000000..55750a6a060 --- /dev/null +++ b/src/quicktemplates2/qquickdeferredexecute_p_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDEFERREDEXECUTE_P_P_H +#define QQUICKDEFERREDEXECUTE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> +#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +#include <QtQml/private/qqmlvme_p.h> + +QT_BEGIN_NAMESPACE + +class QString; +class QObject; + +namespace QtQuickPrivate { + Q_QUICKTEMPLATES2_PRIVATE_EXPORT void beginDeferred(QObject *object, const QString &property); + Q_QUICKTEMPLATES2_PRIVATE_EXPORT void cancelDeferred(QObject *object, const QString &property); + Q_QUICKTEMPLATES2_PRIVATE_EXPORT void completeDeferred(QObject *object, const QString &property); +} + +template<typename T> +void quickBeginDeferred(QObject *object, const QString &property, QQuickDeferredPointer<T> &delegate) +{ + if (!QQmlVME::componentCompleteEnabled()) + return; + + delegate.setExecuting(true); + QtQuickPrivate::beginDeferred(object, property); + delegate.setExecuting(false); +} + +inline void quickCancelDeferred(QObject *object, const QString &property) +{ + QtQuickPrivate::cancelDeferred(object, property); +} + +template<typename T> +void quickCompleteDeferred(QObject *object, const QString &property, QQuickDeferredPointer<T> &delegate) +{ + Q_ASSERT(!delegate.wasExecuted()); + QtQuickPrivate::completeDeferred(object, property); + delegate.setExecuted(); +} + +QT_END_NAMESPACE + +#endif // QQUICKDEFERREDEXECUTE_P_P_H diff --git a/src/quicktemplates2/qquickdeferredpointer_p_p.h b/src/quicktemplates2/qquickdeferredpointer_p_p.h new file mode 100644 index 00000000000..f70b5dc6478 --- /dev/null +++ b/src/quicktemplates2/qquickdeferredpointer_p_p.h @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDEFERREDPOINTER_P_P_H +#define QQUICKDEFERREDPOINTER_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +template<typename T> +class QQuickDeferredPointer +{ +public: + inline QQuickDeferredPointer(); + inline QQuickDeferredPointer(T *); + inline QQuickDeferredPointer(const QQuickDeferredPointer<T> &o); + + inline bool isNull() const; + + inline bool wasExecuted() const; + inline void setExecuted(); + + inline bool isExecuting() const; + inline void setExecuting(bool); + + inline operator T*() const; + inline operator bool() const; + + inline T *data() const; + inline T *operator*() const; + inline T *operator->() const; + + inline QQuickDeferredPointer<T> &operator=(T *); + inline QQuickDeferredPointer<T> &operator=(const QQuickDeferredPointer &o); + +private: + quintptr ptr_value = 0; + + static const quintptr WasExecutedBit = 0x1; + static const quintptr IsExecutingBit = 0x2; + static const quintptr FlagsMask = WasExecutedBit | IsExecutingBit; +}; + +template<typename T> +QQuickDeferredPointer<T>::QQuickDeferredPointer() +{ +} + +template<typename T> +QQuickDeferredPointer<T>::QQuickDeferredPointer(T *v) +: ptr_value(quintptr(v)) +{ + Q_ASSERT((ptr_value & FlagsMask) == 0); +} + +template<typename T> +QQuickDeferredPointer<T>::QQuickDeferredPointer(const QQuickDeferredPointer<T> &o) +: ptr_value(o.ptr_value) +{ +} + +template<typename T> +bool QQuickDeferredPointer<T>::isNull() const +{ + return 0 == (ptr_value & (~FlagsMask)); +} + +template<typename T> +bool QQuickDeferredPointer<T>::wasExecuted() const +{ + return ptr_value & WasExecutedBit; +} + +template<typename T> +void QQuickDeferredPointer<T>::setExecuted() +{ + ptr_value |= WasExecutedBit; +} + +template<typename T> +bool QQuickDeferredPointer<T>::isExecuting() const +{ + return ptr_value & IsExecutingBit; +} + +template<typename T> +void QQuickDeferredPointer<T>::setExecuting(bool b) +{ + if (b) + ptr_value |= IsExecutingBit; + else + ptr_value &= ~IsExecutingBit; +} + +template<typename T> +QQuickDeferredPointer<T>::operator T*() const +{ + return data(); +} + +template<typename T> +QQuickDeferredPointer<T>::operator bool() const +{ + return !isNull(); +} + +template<typename T> +T *QQuickDeferredPointer<T>::data() const +{ + return (T *)(ptr_value & ~FlagsMask); +} + +template<typename T> +T *QQuickDeferredPointer<T>::operator*() const +{ + return (T *)(ptr_value & ~FlagsMask); +} + +template<typename T> +T *QQuickDeferredPointer<T>::operator->() const +{ + return (T *)(ptr_value & ~FlagsMask); +} + +template<typename T> +QQuickDeferredPointer<T> &QQuickDeferredPointer<T>::operator=(T *o) +{ + Q_ASSERT((quintptr(o) & FlagsMask) == 0); + + ptr_value = quintptr(o) | (ptr_value & FlagsMask); + return *this; +} + +template<typename T> +QQuickDeferredPointer<T> &QQuickDeferredPointer<T>::operator=(const QQuickDeferredPointer &o) +{ + ptr_value = o.ptr_value; + return *this; +} + +QT_END_NAMESPACE + +#endif // QQUICKDEFERREDPOINTER_P_P_H diff --git a/src/quicktemplates2/qquickdelaybutton.cpp b/src/quicktemplates2/qquickdelaybutton.cpp new file mode 100644 index 00000000000..25e12263f40 --- /dev/null +++ b/src/quicktemplates2/qquickdelaybutton.cpp @@ -0,0 +1,266 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickdelaybutton_p.h" +#include "qquickabstractbutton_p_p.h" + +#include <QtQuick/private/qquickanimation_p.h> +#include <QtQuick/private/qquicktransition_p.h> +#include <QtQuick/private/qquicktransitionmanager_p_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype DelayButton + \inherits AbstractButton +//! \instantiates QQuickDelayButton + \inqmlmodule QtQuick.Controls + \since 5.9 + \ingroup qtquickcontrols2-buttons + \brief Check button that triggers when held down long enough. + + \image qtquickcontrols2-delaybutton.gif + + DelayButton is a checkable button that incorporates a delay before the + button becomes \l {AbstractButton::}{checked} and the \l activated() + signal is emitted. This delay prevents accidental presses. + + The current progress is expressed as a decimal value between \c 0.0 + and \c 1.0. The time it takes for \l activated() to be emitted is + measured in milliseconds, and can be set with the \l delay property. + + The progress is indicated by a progress indicator on the button. + + \sa {Customizing DelayButton}, {Button Controls} +*/ + +/*! + \qmlsignal QtQuick.Controls::DelayButton::activated() + + This signal is emitted when \l progress reaches \c 1.0. +*/ + +class QQuickDelayTransitionManager; + +class QQuickDelayButtonPrivate : public QQuickAbstractButtonPrivate +{ + Q_DECLARE_PUBLIC(QQuickDelayButton) + +public: + void beginTransition(qreal to); + void finishTransition(); + void cancelTransition(); + + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::Button); } + + int delay = 300; + qreal progress = 0.0; + QQuickTransition *transition = nullptr; + QScopedPointer<QQuickDelayTransitionManager> transitionManager; +}; + +class QQuickDelayTransitionManager : public QQuickTransitionManager +{ +public: + QQuickDelayTransitionManager(QQuickDelayButton *button) : m_button(button) { } + + void transition(QQuickTransition *transition, qreal progress); + +protected: + void finished() override; + +private: + QQuickDelayButton *m_button = nullptr; +}; + +void QQuickDelayTransitionManager::transition(QQuickTransition *transition, qreal progress) +{ + qmlExecuteDeferred(transition); + + QQmlProperty defaultTarget(m_button, QLatin1String("progress")); + QQmlListProperty<QQuickAbstractAnimation> animations = transition->animations(); + const int count = animations.count(&animations); + for (int i = 0; i < count; ++i) { + QQuickAbstractAnimation *anim = animations.at(&animations, i); + anim->setDefaultTarget(defaultTarget); + } + + QList<QQuickStateAction> actions; + actions << QQuickStateAction(m_button, QLatin1String("progress"), progress); + QQuickTransitionManager::transition(actions, transition, m_button); +} + +void QQuickDelayTransitionManager::finished() +{ + if (qFuzzyCompare(m_button->progress(), qreal(1.0))) + emit m_button->activated(); +} + +void QQuickDelayButtonPrivate::beginTransition(qreal to) +{ + Q_Q(QQuickDelayButton); + if (!transition) { + q->setProgress(to); + finishTransition(); + return; + } + + if (!transitionManager) + transitionManager.reset(new QQuickDelayTransitionManager(q)); + + transitionManager->transition(transition, to); +} + +void QQuickDelayButtonPrivate::finishTransition() +{ + Q_Q(QQuickDelayButton); + if (qFuzzyCompare(progress, qreal(1.0))) + emit q->activated(); +} + +void QQuickDelayButtonPrivate::cancelTransition() +{ + if (transitionManager) + transitionManager->cancel(); +} + +QQuickDelayButton::QQuickDelayButton(QQuickItem *parent) + : QQuickAbstractButton(*(new QQuickDelayButtonPrivate), parent) +{ + setCheckable(true); +} + +/*! + \qmlproperty int QtQuick.Controls::DelayButton::delay + + This property holds the time it takes (in milliseconds) for \l progress + to reach \c 1.0 and emit \l activated(). + + The default value is \c 3000 ms. +*/ +int QQuickDelayButton::delay() const +{ + Q_D(const QQuickDelayButton); + return d->delay; +} + +void QQuickDelayButton::setDelay(int delay) +{ + Q_D(QQuickDelayButton); + if (d->delay == delay) + return; + + d->delay = delay; + emit delayChanged(); +} + +/*! + \qmlproperty real QtQuick.Controls::DelayButton::progress + \readonly + + This property holds the current progress as displayed by the progress + indicator, in the range \c 0.0 - \c 1.0. +*/ +qreal QQuickDelayButton::progress() const +{ + Q_D(const QQuickDelayButton); + return d->progress; +} + +void QQuickDelayButton::setProgress(qreal progress) +{ + Q_D(QQuickDelayButton); + if (qFuzzyCompare(d->progress, progress)) + return; + + d->progress = progress; + emit progressChanged(); +} + +/*! + \qmlproperty Transition QtQuick.Controls::DelayButton::transition + + This property holds the transition that is applied on the \l progress + property when the button is pressed or released. +*/ +QQuickTransition *QQuickDelayButton::transition() const +{ + Q_D(const QQuickDelayButton); + return d->transition; +} + +void QQuickDelayButton::setTransition(QQuickTransition *transition) +{ + Q_D(QQuickDelayButton); + if (d->transition == transition) + return; + + d->transition = transition; + emit transitionChanged(); +} + +void QQuickDelayButton::buttonChange(ButtonChange change) +{ + Q_D(QQuickDelayButton); + switch (change) { + case ButtonCheckedChange: + d->cancelTransition(); + setProgress(d->checked ? 1.0 : 0.0); + break; + case ButtonPressedChanged: + if (!d->checked) + d->beginTransition(d->pressed ? 1.0 : 0.0); + break; + default: + QQuickAbstractButton::buttonChange(change); + break; + } +} + +void QQuickDelayButton::nextCheckState() +{ + Q_D(QQuickDelayButton); + setChecked(!d->checked && qFuzzyCompare(d->progress, qreal(1.0))); +} + +QFont QQuickDelayButton::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::Button); +} + +QT_END_NAMESPACE + +#include "moc_qquickdelaybutton_p.cpp" diff --git a/src/quicktemplates2/qquickdelaybutton_p.h b/src/quicktemplates2/qquickdelaybutton_p.h new file mode 100644 index 00000000000..a697bca8070 --- /dev/null +++ b/src/quicktemplates2/qquickdelaybutton_p.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDELAYBUTTON_P_H +#define QQUICKDELAYBUTTON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickTransition; +class QQuickDelayButtonPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDelayButton : public QQuickAbstractButton +{ + Q_OBJECT + Q_PROPERTY(int delay READ delay WRITE setDelay NOTIFY delayChanged FINAL) + Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged FINAL) + Q_PROPERTY(QQuickTransition *transition READ transition WRITE setTransition NOTIFY transitionChanged FINAL) + QML_NAMED_ELEMENT(DelayButton) + QML_ADDED_IN_VERSION(2, 2) + +public: + explicit QQuickDelayButton(QQuickItem *parent = nullptr); + + int delay() const; + void setDelay(int delay); + + qreal progress() const; + void setProgress(qreal progress); + + QQuickTransition *transition() const; + void setTransition(QQuickTransition *transition); + +Q_SIGNALS: + void activated(); + void delayChanged(); + void progressChanged(); + void transitionChanged(); + +protected: + void buttonChange(ButtonChange change) override; + void nextCheckState() override; + + QFont defaultFont() const override; + +private: + Q_DISABLE_COPY(QQuickDelayButton) + Q_DECLARE_PRIVATE(QQuickDelayButton) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickDelayButton) + +#endif // QQUICKDELAYBUTTON_P_H diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp new file mode 100644 index 00000000000..2c38ff75586 --- /dev/null +++ b/src/quicktemplates2/qquickdial.cpp @@ -0,0 +1,861 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickdial_p.h" +#include "qquickdeferredexecute_p_p.h" + +#include <QtCore/qmath.h> +#include <QtQuick/private/qquickflickable_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p_p.h> + +#include <cmath> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Dial + \inherits Control +//! \instantiates QQuickDial + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-input + \brief Circular dial that is rotated to set a value. + + The Dial is similar to a traditional dial knob that is found on devices + such as stereos or industrial equipment. It allows the user to specify a + value within a range. + + \image qtquickcontrols2-dial-no-wrap.gif + + The value of the dial is set with the \l value property. The range is + set with the \l from and \l to properties. To enable or disable wrapping, + use the \l wrap property. + + The dial can be manipulated with a keyboard. It supports the following + actions: + + \table + \header \li \b {Action} \li \b {Key} + \row \li Decrease \l value by \l stepSize \li \c Qt.Key_Left + \row \li Decrease \l value by \l stepSize \li \c Qt.Key_Down + \row \li Set \l value to \l from \li \c Qt.Key_Home + \row \li Increase \l value by \l stepSize \li \c Qt.Key_Right + \row \li Increase \l value by \l stepSize \li \c Qt.Key_Up + \row \li Set \l value to \l to \li \c Qt.Key_End + \endtable + + \include qquickdial.qdocinc inputMode + + \sa {Customizing Dial}, {Input Controls} +*/ + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlsignal QtQuick.Controls::Dial::moved() + + This signal is emitted when the dial has been interactively moved + by the user by either touch, mouse, or keys. +*/ + +static const qreal startAngleRadians = (M_PI * 2.0) * (4.0 / 6.0); +static const qreal startAngle = -140; +static const qreal endAngleRadians = (M_PI * 2.0) * (5.0 / 6.0); +static const qreal endAngle = 140; + +class QQuickDialPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickDial) + +public: + qreal valueAt(qreal position) const; + qreal snapPosition(qreal position) const; + qreal positionAt(const QPointF &point) const; + qreal circularPositionAt(const QPointF &point) const; + qreal linearPositionAt(const QPointF &point) const; + void setPosition(qreal position); + void updatePosition(); + bool isLargeChange(const QPointF &eventPos, qreal proposedPosition) const; + bool isHorizontalOrVertical() const; + + void handlePress(const QPointF &point) override; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + void handleUngrab() override; + + void cancelHandle(); + void executeHandle(bool complete = false); + + void updateAllValuesAreInteger(); + + qreal from = 0; + qreal to = 1; + qreal value = 0; + qreal position = 0; + qreal angle = startAngle; + qreal stepSize = 0; + QPointF pressPoint; + qreal positionBeforePress = 0; + QQuickDial::SnapMode snapMode = QQuickDial::NoSnap; + QQuickDial::InputMode inputMode = QQuickDial::Circular; + QQuickDeferredPointer<QQuickItem> handle; + bool wrap = false; + bool live = true; + bool pressed = false; + bool allValuesAreInteger = false; +}; + +qreal QQuickDialPrivate::valueAt(qreal position) const +{ + qreal value = from + (to - from) * position; + + /* play nice with users expecting that integer from, to and stepSize leads to + integer values - given that we are using floating point internally (and in + the API of value), this does not hold, but it is easy enough to handle + */ + if (allValuesAreInteger) + value = qRound(value); + + return value; +} + +qreal QQuickDialPrivate::snapPosition(qreal position) const +{ + const qreal range = to - from; + if (qFuzzyIsNull(range)) + return position; + + const qreal effectiveStep = stepSize / range; + if (qFuzzyIsNull(effectiveStep)) + return position; + + return qRound(position / effectiveStep) * effectiveStep; +} + +qreal QQuickDialPrivate::positionAt(const QPointF &point) const +{ + return inputMode == QQuickDial::Circular ? circularPositionAt(point) : linearPositionAt(point); +} + +qreal QQuickDialPrivate::circularPositionAt(const QPointF &point) const +{ + qreal yy = height / 2.0 - point.y(); + qreal xx = point.x() - width / 2.0; + qreal angle = (xx || yy) ? std::atan2(yy, xx) : 0; + + if (angle < M_PI / -2) + angle = angle + M_PI * 2; + + qreal normalizedAngle = (startAngleRadians - angle) / endAngleRadians; + return normalizedAngle; +} + +qreal QQuickDialPrivate::linearPositionAt(const QPointF &point) const +{ + // This value determines the range (either horizontal or vertical) + // within which the dial can be dragged. + // The larger this value is, the further the drag distance + // must be to go from a position of e.g. 0.0 to 1.0. + qreal dragArea = 0; + + // The linear input mode uses a "relative" input system, + // where the distance from the press point is used to calculate + // the change in position. Moving the mouse above the press + // point increases the position (when inputMode is Vertical), + // and vice versa. This prevents the dial from jumping when clicked. + qreal dragDistance = 0; + + if (inputMode == QQuickDial::Horizontal) { + dragArea = width * 2; + dragDistance = pressPoint.x() - point.x(); + } else { + dragArea = height * 2; + dragDistance = point.y() - pressPoint.y(); + } + const qreal normalisedDifference = dragDistance / dragArea; + return qBound(qreal(0), positionBeforePress - normalisedDifference, qreal(1)); +} + +void QQuickDialPrivate::setPosition(qreal pos) +{ + Q_Q(QQuickDial); + pos = qBound<qreal>(qreal(0), pos, qreal(1)); + if (qFuzzyCompare(position, pos)) + return; + + position = pos; + + angle = startAngle + position * qAbs(endAngle - startAngle); + + emit q->positionChanged(); + emit q->angleChanged(); +} + +void QQuickDialPrivate::updatePosition() +{ + qreal pos = 0; + if (!qFuzzyCompare(from, to)) + pos = (value - from) / (to - from); + setPosition(pos); +} + +bool QQuickDialPrivate::isLargeChange(const QPointF &eventPos, qreal proposedPosition) const +{ + return qAbs(proposedPosition - position) >= qreal(0.5) && eventPos.y() >= height / 2; +} + +bool QQuickDialPrivate::isHorizontalOrVertical() const +{ + return inputMode == QQuickDial::Horizontal || inputMode == QQuickDial::Vertical; +} + +void QQuickDialPrivate::handlePress(const QPointF &point) +{ + Q_Q(QQuickDial); + QQuickControlPrivate::handlePress(point); + pressPoint = point; + positionBeforePress = position; + q->setPressed(true); +} + +void QQuickDialPrivate::handleMove(const QPointF &point) +{ + Q_Q(QQuickDial); + QQuickControlPrivate::handleMove(point); + const qreal oldPos = position; + qreal pos = positionAt(point); + if (snapMode == QQuickDial::SnapAlways) + pos = snapPosition(pos); + + if (wrap || isHorizontalOrVertical() || !isLargeChange(point, pos)) { + if (live) + q->setValue(valueAt(pos)); + else + setPosition(pos); + if (!qFuzzyCompare(pos, oldPos)) + emit q->moved(); + } +} + +void QQuickDialPrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickDial); + QQuickControlPrivate::handleRelease(point); + if (q->keepMouseGrab() || q->keepTouchGrab()) { + const qreal oldPos = position; + qreal pos = positionAt(point); + if (snapMode != QQuickDial::NoSnap) + pos = snapPosition(pos); + + if (wrap || isHorizontalOrVertical() || !isLargeChange(point, pos)) + q->setValue(valueAt(pos)); + if (!qFuzzyCompare(pos, oldPos)) + emit q->moved(); + + q->setKeepMouseGrab(false); + q->setKeepTouchGrab(false); + } + + q->setPressed(false); + pressPoint = QPointF(); + positionBeforePress = 0; +} + +void QQuickDialPrivate::handleUngrab() +{ + Q_Q(QQuickDial); + QQuickControlPrivate::handleUngrab(); + pressPoint = QPointF(); + positionBeforePress = 0; + q->setPressed(false); +} + +static inline QString handleName() { return QStringLiteral("handle"); } + +void QQuickDialPrivate::cancelHandle() +{ + Q_Q(QQuickDial); + quickCancelDeferred(q, handleName()); +} + +void QQuickDialPrivate::executeHandle(bool complete) +{ + Q_Q(QQuickDial); + if (handle.wasExecuted()) + return; + + if (!handle || complete) + quickBeginDeferred(q, handleName(), handle); + if (complete) + quickCompleteDeferred(q, handleName(), handle); +} + +template<typename ...Real> +static bool areRepresentableAsInteger(Real... numbers) { + auto check = [](qreal number) -> bool { return std::nearbyint(number) == number; }; + return (... && check(numbers)); +} + +void QQuickDialPrivate::updateAllValuesAreInteger() +{ + allValuesAreInteger = areRepresentableAsInteger(to, from, stepSize) && stepSize != 0.0; +} + +QQuickDial::QQuickDial(QQuickItem *parent) + : QQuickControl(*(new QQuickDialPrivate), parent) +{ + setActiveFocusOnTab(true); + setAcceptedMouseButtons(Qt::LeftButton); +#if QT_CONFIG(quicktemplates2_multitouch) + setAcceptTouchEvents(true); +#endif +#if QT_CONFIG(cursor) + setCursor(Qt::ArrowCursor); +#endif +} + +/*! + \qmlproperty real QtQuick.Controls::Dial::from + + This property holds the starting value for the range. The default value is \c 0.0. + + \sa to, value +*/ +qreal QQuickDial::from() const +{ + Q_D(const QQuickDial); + return d->from; +} + +void QQuickDial::setFrom(qreal from) +{ + Q_D(QQuickDial); + if (qFuzzyCompare(d->from, from)) + return; + + d->from = from; + emit fromChanged(); + d->updateAllValuesAreInteger(); + if (isComponentComplete()) { + setValue(d->value); + d->updatePosition(); + } +} + +/*! + \qmlproperty real QtQuick.Controls::Dial::to + + This property holds the end value for the range. The default value is + \c 1.0. + + \sa from, value +*/ +qreal QQuickDial::to() const +{ + Q_D(const QQuickDial); + return d->to; +} + +void QQuickDial::setTo(qreal to) +{ + Q_D(QQuickDial); + if (qFuzzyCompare(d->to, to)) + return; + + d->to = to; + d->updateAllValuesAreInteger(); + emit toChanged(); + if (isComponentComplete()) { + setValue(d->value); + d->updatePosition(); + } +} + +/*! + \qmlproperty real QtQuick.Controls::Dial::value + + This property holds the value in the range \c from - \c to. The default + value is \c 0.0. + + \sa position, live +*/ +qreal QQuickDial::value() const +{ + Q_D(const QQuickDial); + return d->value; +} + +void QQuickDial::setValue(qreal value) +{ + Q_D(QQuickDial); + if (isComponentComplete()) + value = d->from > d->to ? qBound(d->to, value, d->from) : qBound(d->from, value, d->to); + + if (qFuzzyCompare(d->value, value)) + return; + + d->value = value; + d->updatePosition(); + emit valueChanged(); +} + +/*! + \qmlproperty real QtQuick.Controls::Dial::position + \readonly + + This property holds the logical position of the handle. + + The position is expressed as a fraction of the control's angle range (the + range within which the handle can be moved) in the range \c {0.0 - 1.0}. + + \sa value, angle +*/ +qreal QQuickDial::position() const +{ + Q_D(const QQuickDial); + return d->position; +} + +/*! + \qmlproperty real QtQuick.Controls::Dial::angle + \readonly + + This property holds the angle of the handle. + + The range is from \c -140 degrees to \c 140 degrees. + + \sa position +*/ +qreal QQuickDial::angle() const +{ + Q_D(const QQuickDial); + return d->angle; +} + +/*! + \qmlproperty real QtQuick.Controls::Dial::stepSize + + This property holds the step size. + + The step size determines the amount by which the dial's value + is increased and decreased when interacted with via the keyboard. + For example, a step size of \c 0.2, will result in the dial's + value increasing and decreasing in increments of \c 0.2. + + The step size is only respected for touch and mouse interaction + when \l snapMode is set to a value other than \c Dial.NoSnap. + + The default value is \c 0.0, which results in an effective step + size of \c 0.1 for keyboard interaction. + + \sa snapMode, increase(), decrease() +*/ +qreal QQuickDial::stepSize() const +{ + Q_D(const QQuickDial); + return d->stepSize; +} + +void QQuickDial::setStepSize(qreal step) +{ + Q_D(QQuickDial); + if (qFuzzyCompare(d->stepSize, step)) + return; + + d->stepSize = step; + d->updateAllValuesAreInteger(); + emit stepSizeChanged(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::Dial::snapMode + + This property holds the snap mode. + + The snap mode works with the \l stepSize to allow the handle to snap to + certain points along the dial. + + Possible values: + \value Dial.NoSnap The dial does not snap (default). + \value Dial.SnapAlways The dial snaps while the handle is dragged. + \value Dial.SnapOnRelease The dial does not snap while being dragged, but only after the handle is released. + + \sa stepSize +*/ +QQuickDial::SnapMode QQuickDial::snapMode() const +{ + Q_D(const QQuickDial); + return d->snapMode; +} + +void QQuickDial::setSnapMode(SnapMode mode) +{ + Q_D(QQuickDial); + if (d->snapMode == mode) + return; + + d->snapMode = mode; + emit snapModeChanged(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty enumeration QtQuick.Controls::Dial::inputMode + + This property holds the input mode. + + \include qquickdial.qdocinc inputMode + + The default value is \c Dial.Circular. +*/ +QQuickDial::InputMode QQuickDial::inputMode() const +{ + Q_D(const QQuickDial); + return d->inputMode; +} + +void QQuickDial::setInputMode(QQuickDial::InputMode mode) +{ + Q_D(QQuickDial); + if (d->inputMode == mode) + return; + + d->inputMode = mode; + emit inputModeChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::Dial::wrap + + This property holds whether the dial wraps when dragged. + + For example, when this property is set to \c true, dragging the dial past + the \l to position will result in the handle being positioned at the + \l from position, and vice versa: + + \image qtquickcontrols2-dial-wrap.gif + + When this property is \c false, it's not possible to drag the dial across + the from and to values. + + \image qtquickcontrols2-dial-no-wrap.gif + + The default value is \c false. +*/ +bool QQuickDial::wrap() const +{ + Q_D(const QQuickDial); + return d->wrap; +} + +void QQuickDial::setWrap(bool wrap) +{ + Q_D(QQuickDial); + if (d->wrap == wrap) + return; + + d->wrap = wrap; + emit wrapChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::Dial::pressed + + This property holds whether the dial is pressed. + + The dial will be pressed when either the mouse is pressed over it, or a key + such as \c Qt.Key_Left is held down. If you'd prefer not to have the dial + be pressed upon key presses (due to styling reasons, for example), you can + use the \l {Keys}{Keys attached property}: + + \code + Dial { + Keys.onLeftPressed: {} + } + \endcode + + This will result in pressed only being \c true upon mouse presses. +*/ +bool QQuickDial::isPressed() const +{ + Q_D(const QQuickDial); + return d->pressed; +} + +void QQuickDial::setPressed(bool pressed) +{ + Q_D(QQuickDial); + if (d->pressed == pressed) + return; + + d->pressed = pressed; + setAccessibleProperty("pressed", pressed); + emit pressedChanged(); +} + +/*! + \qmlproperty Item QtQuick.Controls::Dial::handle + + This property holds the handle of the dial. + + The handle acts as a visual indicator of the position of the dial. + + \sa {Customizing Dial} +*/ +QQuickItem *QQuickDial::handle() const +{ + QQuickDialPrivate *d = const_cast<QQuickDialPrivate *>(d_func()); + if (!d->handle) + d->executeHandle(); + return d->handle; +} + +void QQuickDial::setHandle(QQuickItem *handle) +{ + Q_D(QQuickDial); + if (handle == d->handle) + return; + + if (!d->handle.isExecuting()) + d->cancelHandle(); + + QQuickControlPrivate::hideOldItem(d->handle); + d->handle = handle; + if (d->handle && !d->handle->parentItem()) + d->handle->setParentItem(this); + if (!d->handle.isExecuting()) + emit handleChanged(); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty bool QtQuick.Controls::Dial::live + + This property holds whether the dial provides live updates for the \l value + property while the handle is dragged. + + The default value is \c true. + + \sa value +*/ +bool QQuickDial::live() const +{ + Q_D(const QQuickDial); + return d->live; +} + +void QQuickDial::setLive(bool live) +{ + Q_D(QQuickDial); + if (d->live == live) + return; + + d->live = live; + emit liveChanged(); +} + +/*! + \qmlmethod void QtQuick.Controls::Dial::increase() + + Increases the value by \l stepSize, or \c 0.1 if stepSize is not defined. + + \sa stepSize +*/ +void QQuickDial::increase() +{ + Q_D(QQuickDial); + qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; + setValue(d->value + step); +} + +/*! + \qmlmethod void QtQuick.Controls::Dial::decrease() + + Decreases the value by \l stepSize, or \c 0.1 if stepSize is not defined. + + \sa stepSize +*/ +void QQuickDial::decrease() +{ + Q_D(QQuickDial); + qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; + setValue(d->value - step); +} + +void QQuickDial::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickDial); + const qreal oldValue = d->value; + switch (event->key()) { + case Qt::Key_Left: + case Qt::Key_Down: + setPressed(true); + if (isMirrored()) + increase(); + else + decrease(); + break; + + case Qt::Key_Right: + case Qt::Key_Up: + setPressed(true); + if (isMirrored()) + decrease(); + else + increase(); + break; + + case Qt::Key_Home: + setPressed(true); + setValue(isMirrored() ? d->to : d->from); + break; + + case Qt::Key_End: + setPressed(true); + setValue(isMirrored() ? d->from : d->to); + break; + + default: + event->ignore(); + QQuickControl::keyPressEvent(event); + break; + } + if (!qFuzzyCompare(d->value, oldValue)) + emit moved(); +} + +void QQuickDial::keyReleaseEvent(QKeyEvent *event) +{ + QQuickControl::keyReleaseEvent(event); + setPressed(false); +} + +void QQuickDial::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickDial); + QQuickControl::mousePressEvent(event); + d->handleMove(event->position()); + setKeepMouseGrab(true); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickDial::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickDial); + switch (event->type()) { + case QEvent::TouchUpdate: + for (const QTouchEvent::TouchPoint &point : event->points()) { + if (!d->acceptTouch(point)) + continue; + + switch (point.state()) { + case QEventPoint::Updated: + if (!keepTouchGrab()) { + bool overXDragThreshold = QQuickWindowPrivate::dragOverThreshold(point.position().x() - d->pressPoint.x(), Qt::XAxis, &point); + setKeepTouchGrab(overXDragThreshold); + + if (!overXDragThreshold) { + bool overYDragThreshold = QQuickWindowPrivate::dragOverThreshold(point.position().y() - d->pressPoint.y(), Qt::YAxis, &point); + setKeepTouchGrab(overYDragThreshold); + } + } + if (keepTouchGrab()) + d->handleMove(point.position()); + break; + + default: + QQuickControl::touchEvent(event); + break; + } + } + break; + + default: + QQuickControl::touchEvent(event); + break; + } +} +#endif + +#if QT_CONFIG(wheelevent) +void QQuickDial::wheelEvent(QWheelEvent *event) +{ + Q_D(QQuickDial); + QQuickControl::wheelEvent(event); + if (d->wheelEnabled) { + const qreal oldValue = d->value; + const QPointF angle = event->angleDelta(); + const qreal delta = (qFuzzyIsNull(angle.y()) ? angle.x() : (event->inverted() ? -angle.y() : angle.y())) / int(QWheelEvent::DefaultDeltasPerStep); + const qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; + setValue(oldValue + step * delta); + event->setAccepted(!qFuzzyCompare(d->value, oldValue)); + } +} +#endif + +void QQuickDial::mirrorChange() +{ + QQuickControl::mirrorChange(); + emit angleChanged(); +} + +void QQuickDial::componentComplete() +{ + Q_D(QQuickDial); + d->executeHandle(true); + QQuickControl::componentComplete(); + setValue(d->value); + d->updatePosition(); +} + +#if QT_CONFIG(accessibility) +void QQuickDial::accessibilityActiveChanged(bool active) +{ + QQuickControl::accessibilityActiveChanged(active); + + Q_D(QQuickDial); + if (active) + setAccessibleProperty("pressed", d->pressed); +} + +QAccessible::Role QQuickDial::accessibleRole() const +{ + return QAccessible::Dial; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickdial_p.cpp" diff --git a/src/quicktemplates2/qquickdial_p.h b/src/quicktemplates2/qquickdial_p.h new file mode 100644 index 00000000000..67bbc18390b --- /dev/null +++ b/src/quicktemplates2/qquickdial_p.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDIAL_P_H +#define QQUICKDIAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qvariant.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickDialAttached; +class QQuickDialPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDial : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged FINAL) + Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged FINAL) + Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged FINAL) + Q_PROPERTY(qreal position READ position NOTIFY positionChanged FINAL) + Q_PROPERTY(qreal angle READ angle NOTIFY angleChanged FINAL) + Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged FINAL) + Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged FINAL) + Q_PROPERTY(bool wrap READ wrap WRITE setWrap NOTIFY wrapChanged FINAL) + Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged FINAL) + Q_PROPERTY(QQuickItem *handle READ handle WRITE setHandle NOTIFY handleChanged FINAL) + // 2.2 (Qt 5.9) + Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION(2, 2)) + // 2.5 (Qt 5.12) + Q_PROPERTY(InputMode inputMode READ inputMode WRITE setInputMode NOTIFY inputModeChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DeferredPropertyNames", "background,handle") + QML_NAMED_ELEMENT(Dial) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickDial(QQuickItem *parent = nullptr); + + qreal from() const; + void setFrom(qreal from); + + qreal to() const; + void setTo(qreal to); + + qreal value() const; + void setValue(qreal value); + + qreal position() const; + + qreal angle() const; + + qreal stepSize() const; + void setStepSize(qreal step); + + enum SnapMode { + NoSnap, + SnapAlways, + SnapOnRelease + }; + Q_ENUM(SnapMode) + + SnapMode snapMode() const; + void setSnapMode(SnapMode mode); + + enum InputMode { + Circular, + Horizontal, + Vertical, + }; + Q_ENUM(InputMode) + + bool wrap() const; + void setWrap(bool wrap); + + bool isPressed() const; + void setPressed(bool pressed); + + QQuickItem *handle() const; + void setHandle(QQuickItem *handle); + + // 2.2 (Qt 5.9) + bool live() const; + void setLive(bool live); + + // 2.5 (Qt 5.12) + InputMode inputMode() const; + void setInputMode(InputMode mode); + +public Q_SLOTS: + void increase(); + void decrease(); + +Q_SIGNALS: + void fromChanged(); + void toChanged(); + void valueChanged(); + void positionChanged(); + void angleChanged(); + void stepSizeChanged(); + void snapModeChanged(); + void wrapChanged(); + void pressedChanged(); + void handleChanged(); + // 2.2 (Qt 5.9) + Q_REVISION(2, 2) void moved(); + Q_REVISION(2, 2) void liveChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void inputModeChanged(); + +protected: + void keyPressEvent(QKeyEvent *event) override; + void keyReleaseEvent(QKeyEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif +#if QT_CONFIG(wheelevent) + void wheelEvent(QWheelEvent *event) override; +#endif + + void mirrorChange() override; + void componentComplete() override; + +#if QT_CONFIG(accessibility) + void accessibilityActiveChanged(bool active) override; + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickDial) + Q_DECLARE_PRIVATE(QQuickDial) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickDial) + +#endif // QQUICKDIAL_P_H diff --git a/src/quicktemplates2/qquickdialog.cpp b/src/quicktemplates2/qquickdialog.cpp new file mode 100644 index 00000000000..812d1c1ac2c --- /dev/null +++ b/src/quicktemplates2/qquickdialog.cpp @@ -0,0 +1,578 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickdialog_p.h" +#include "qquickdialog_p_p.h" +#include "qquickdialogbuttonbox_p.h" +#include "qquickabstractbutton_p.h" +#include "qquickpopupitem_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Dialog + \inherits Popup +//! \instantiates QQuickDialog + \inqmlmodule QtQuick.Controls + \ingroup qtquickcontrols2-dialogs + \ingroup qtquickcontrols2-popups + \brief Popup dialog with standard buttons and a title, used for short-term interaction with the user. + \since 5.8 + + A dialog is a popup mostly used for short-term tasks and brief communications + with the user. Similarly to \l ApplicationWindow and \l Page, Dialog is organized + into three sections: \l header, \l {Popup::}{contentItem}, and \l footer. + + \image qtquickcontrols2-page-wireframe.png + + \section1 Dialog Title and Buttons + + Dialog's \l title is displayed by a style-specific title bar that is assigned + as a dialog \l header by default. + + Dialog's standard buttons are managed by a \l DialogButtonBox that is assigned + as a dialog \l footer by default. The dialog's \l standardButtons property is + forwarded to the respective property of the button box. Furthermore, the + \l {DialogButtonBox::}{accepted()} and \l {DialogButtonBox::}{rejected()} + signals of the button box are connected to the respective signals in Dialog. + + \snippet qtquickcontrols2-dialog.qml 1 + + \section1 Modal Dialogs + + A \l {Popup::}{modal} dialog blocks input to other content beneath + the dialog. When a modal dialog is opened, the user must finish + interacting with the dialog and close it before they can access any + other content in the same window. + + \snippet qtquickcontrols2-dialog-modal.qml 1 + + \section1 Modeless Dialogs + + A modeless dialog is a dialog that operates independently of other + content around the dialog. When a modeless dialog is opened, the user + is allowed to interact with both the dialog and the other content in + the same window. + + \snippet qtquickcontrols2-dialog-modeless.qml 1 + + \sa DialogButtonBox, {Popup Controls} +*/ + +/*! + \qmlsignal QtQuick.Controls::Dialog::accepted() + + This signal is emitted when the dialog has been accepted either + interactively or by calling \l accept(). + + \note This signal is \e not emitted when closing the dialog with + \l {Popup::}{close()} or setting \l {Popup::}{visible} to \c false. + + \sa rejected() +*/ + +/*! + \qmlsignal QtQuick.Controls::Dialog::rejected() + + This signal is emitted when the dialog has been rejected either + interactively or by calling \l reject(). + + \note This signal is \e not emitted when closing the dialog with + \l {Popup::}{close()} or setting \l {Popup::}{visible} to \c false. + + \sa accepted() +*/ + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlsignal QtQuick.Controls::Dialog::applied() + + This signal is emitted when the \c Dialog.Apply standard button is clicked. + + \sa discarded(), reset() +*/ + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlsignal QtQuick.Controls::Dialog::reset() + + This signal is emitted when the \c Dialog.Reset standard button is clicked. + + \sa discarded(), applied() +*/ + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlsignal QtQuick.Controls::Dialog::discarded() + + This signal is emitted when the \c Dialog.Discard standard button is clicked. + + \sa reset(), applied() +*/ + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlsignal QtQuick.Controls::Dialog::helpRequested() + + This signal is emitted when the \c Dialog.Help standard button is clicked. + + \sa accepted(), rejected() +*/ + +QPlatformDialogHelper::ButtonRole QQuickDialogPrivate::buttonRole(QQuickAbstractButton *button) +{ + const QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button, false)); + return attached ? attached->buttonRole() : QPlatformDialogHelper::InvalidRole; +} + +void QQuickDialogPrivate::handleAccept() +{ + Q_Q(QQuickDialog); + q->accept(); +} + +void QQuickDialogPrivate::handleReject() +{ + Q_Q(QQuickDialog); + q->reject(); +} + +void QQuickDialogPrivate::handleClick(QQuickAbstractButton *button) +{ + Q_Q(QQuickDialog); + switch (buttonRole(button)) { + case QPlatformDialogHelper::ApplyRole: + emit q->applied(); + break; + case QPlatformDialogHelper::ResetRole: + emit q->reset(); + break; + case QPlatformDialogHelper::DestructiveRole: + emit q->discarded(); + break; + case QPlatformDialogHelper::HelpRole: + emit q->helpRequested(); + break; + default: + break; + } +} + +QQuickDialog::QQuickDialog(QObject *parent) + : QQuickDialog(*(new QQuickDialogPrivate), parent) +{ +} + +QQuickDialog::QQuickDialog(QQuickDialogPrivate &dd, QObject *parent) + : QQuickPopup(dd, parent) +{ + Q_D(QQuickDialog); + QObject::connect(d->popupItem, &QQuickPopupItem::titleChanged, this, &QQuickDialog::titleChanged); + QObject::connect(d->popupItem, &QQuickPopupItem::headerChanged, this, &QQuickDialog::headerChanged); + QObject::connect(d->popupItem, &QQuickPopupItem::footerChanged, this, &QQuickDialog::footerChanged); + QObject::connect(d->popupItem, &QQuickPopupItem::implicitHeaderWidthChanged, this, &QQuickDialog::implicitHeaderWidthChanged); + QObject::connect(d->popupItem, &QQuickPopupItem::implicitHeaderHeightChanged, this, &QQuickDialog::implicitHeaderHeightChanged); + QObject::connect(d->popupItem, &QQuickPopupItem::implicitFooterWidthChanged, this, &QQuickDialog::implicitFooterWidthChanged); + QObject::connect(d->popupItem, &QQuickPopupItem::implicitFooterHeightChanged, this, &QQuickDialog::implicitFooterHeightChanged); +} + +QQuickDialog::~QQuickDialog() +{ + Q_D(QQuickDialog); + QObject::disconnect(d->popupItem, &QQuickPopupItem::titleChanged, this, &QQuickDialog::titleChanged); + QObject::disconnect(d->popupItem, &QQuickPopupItem::headerChanged, this, &QQuickDialog::headerChanged); + QObject::disconnect(d->popupItem, &QQuickPopupItem::footerChanged, this, &QQuickDialog::footerChanged); + QObject::disconnect(d->popupItem, &QQuickPopupItem::implicitHeaderWidthChanged, this, &QQuickDialog::implicitHeaderWidthChanged); + QObject::disconnect(d->popupItem, &QQuickPopupItem::implicitHeaderHeightChanged, this, &QQuickDialog::implicitHeaderHeightChanged); + QObject::disconnect(d->popupItem, &QQuickPopupItem::implicitFooterWidthChanged, this, &QQuickDialog::implicitFooterWidthChanged); + QObject::disconnect(d->popupItem, &QQuickPopupItem::implicitFooterHeightChanged, this, &QQuickDialog::implicitFooterHeightChanged); +} + +/*! + \qmlproperty string QtQuick.Controls::Dialog::title + + This property holds the dialog title. + + The title is displayed in the dialog header. + + \code + Dialog { + title: qsTr("About") + + Label { + text: "Lorem ipsum..." + } + } + \endcode +*/ +QString QQuickDialog::title() const +{ + Q_D(const QQuickDialog); + return d->popupItem->title(); +} + +void QQuickDialog::setTitle(const QString &title) +{ + Q_D(QQuickDialog); + d->popupItem->setTitle(title); +} + +/*! + \qmlproperty Item QtQuick.Controls::Dialog::header + + This property holds the dialog header item. The header item is positioned to + the top, and resized to the width of the dialog. The default value is \c null. + + \note Assigning a \l DialogButtonBox as a dialog header automatically connects + its \l {DialogButtonBox::}{accepted()} and \l {DialogButtonBox::}{rejected()} + signals to the respective signals in Dialog. + + \note Assigning a \l DialogButtonBox, \l ToolBar, or \l TabBar as a dialog + header automatically sets the respective \l DialogButtonBox::position, + \l ToolBar::position, or \l TabBar::position property to \c Header. + + \sa footer +*/ +QQuickItem *QQuickDialog::header() const +{ + Q_D(const QQuickDialog); + return d->popupItem->header(); +} + +void QQuickDialog::setHeader(QQuickItem *header) +{ + Q_D(QQuickDialog); + QQuickItem *oldHeader = d->popupItem->header(); + if (oldHeader == header) + return; + + if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(oldHeader)) { + QObjectPrivate::disconnect(buttonBox, &QQuickDialogButtonBox::accepted, d, &QQuickDialogPrivate::handleAccept); + QObjectPrivate::disconnect(buttonBox, &QQuickDialogButtonBox::rejected, d, &QQuickDialogPrivate::handleReject); + QObjectPrivate::disconnect(buttonBox, &QQuickDialogButtonBox::clicked, d, &QQuickDialogPrivate::handleClick); + if (d->buttonBox == buttonBox) + d->buttonBox = nullptr; + } + + if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(header)) { + QObjectPrivate::connect(buttonBox, &QQuickDialogButtonBox::accepted, d, &QQuickDialogPrivate::handleAccept); + QObjectPrivate::connect(buttonBox, &QQuickDialogButtonBox::rejected, d, &QQuickDialogPrivate::handleReject); + QObjectPrivate::connect(buttonBox, &QQuickDialogButtonBox::clicked, d, &QQuickDialogPrivate::handleClick); + d->buttonBox = buttonBox; + buttonBox->setStandardButtons(d->standardButtons); + } + + d->popupItem->setHeader(header); +} + +/*! + \qmlproperty Item QtQuick.Controls::Dialog::footer + + This property holds the dialog footer item. The footer item is positioned to + the bottom, and resized to the width of the dialog. The default value is \c null. + + \note Assigning a \l DialogButtonBox as a dialog footer automatically connects + its \l {DialogButtonBox::}{accepted()} and \l {DialogButtonBox::}{rejected()} + signals to the respective signals in Dialog. + + \note Assigning a \l DialogButtonBox, \l ToolBar, or \l TabBar as a dialog + footer automatically sets the respective \l DialogButtonBox::position, + \l ToolBar::position, or \l TabBar::position property to \c Footer. + + \sa header +*/ +QQuickItem *QQuickDialog::footer() const +{ + Q_D(const QQuickDialog); + return d->popupItem->footer(); +} + +void QQuickDialog::setFooter(QQuickItem *footer) +{ + Q_D(QQuickDialog); + QQuickItem *oldFooter = d->popupItem->footer(); + if (oldFooter == footer) + return; + + if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(oldFooter)) { + QObjectPrivate::disconnect(buttonBox, &QQuickDialogButtonBox::accepted, d, &QQuickDialogPrivate::handleAccept); + QObjectPrivate::disconnect(buttonBox, &QQuickDialogButtonBox::rejected, d, &QQuickDialogPrivate::handleReject); + QObjectPrivate::disconnect(buttonBox, &QQuickDialogButtonBox::clicked, d, &QQuickDialogPrivate::handleClick); + if (d->buttonBox == buttonBox) + d->buttonBox = nullptr; + } + if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(footer)) { + QObjectPrivate::connect(buttonBox, &QQuickDialogButtonBox::accepted, d, &QQuickDialogPrivate::handleAccept); + QObjectPrivate::connect(buttonBox, &QQuickDialogButtonBox::rejected, d, &QQuickDialogPrivate::handleReject); + QObjectPrivate::connect(buttonBox, &QQuickDialogButtonBox::clicked, d, &QQuickDialogPrivate::handleClick); + d->buttonBox = buttonBox; + buttonBox->setStandardButtons(d->standardButtons); + } + + d->popupItem->setFooter(footer); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::Dialog::standardButtons + + This property holds a combination of standard buttons that are used by the dialog. + + \snippet qtquickcontrols2-dialog.qml 1 + + The buttons will be positioned in the appropriate order for the user's platform. + + Possible flags: + \value Dialog.Ok An "OK" button defined with the \c AcceptRole. + \value Dialog.Open An "Open" button defined with the \c AcceptRole. + \value Dialog.Save A "Save" button defined with the \c AcceptRole. + \value Dialog.Cancel A "Cancel" button defined with the \c RejectRole. + \value Dialog.Close A "Close" button defined with the \c RejectRole. + \value Dialog.Discard A "Discard" or "Don't Save" button, depending on the platform, defined with the \c DestructiveRole. + \value Dialog.Apply An "Apply" button defined with the \c ApplyRole. + \value Dialog.Reset A "Reset" button defined with the \c ResetRole. + \value Dialog.RestoreDefaults A "Restore Defaults" button defined with the \c ResetRole. + \value Dialog.Help A "Help" button defined with the \c HelpRole. + \value Dialog.SaveAll A "Save All" button defined with the \c AcceptRole. + \value Dialog.Yes A "Yes" button defined with the \c YesRole. + \value Dialog.YesToAll A "Yes to All" button defined with the \c YesRole. + \value Dialog.No A "No" button defined with the \c NoRole. + \value Dialog.NoToAll A "No to All" button defined with the \c NoRole. + \value Dialog.Abort An "Abort" button defined with the \c RejectRole. + \value Dialog.Retry A "Retry" button defined with the \c AcceptRole. + \value Dialog.Ignore An "Ignore" button defined with the \c AcceptRole. + \value Dialog.NoButton An invalid button. + + \sa DialogButtonBox +*/ +QPlatformDialogHelper::StandardButtons QQuickDialog::standardButtons() const +{ + Q_D(const QQuickDialog); + return d->standardButtons; +} + +void QQuickDialog::setStandardButtons(QPlatformDialogHelper::StandardButtons buttons) +{ + Q_D(QQuickDialog); + if (d->standardButtons == buttons) + return; + + d->standardButtons = buttons; + if (d->buttonBox) + d->buttonBox->setStandardButtons(buttons); + emit standardButtonsChanged(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod AbstractButton QtQuick.Controls::Dialog::standardButton(StandardButton button) + + Returns the specified standard \a button, or \c null if it does not exist. + + \sa standardButtons +*/ +QQuickAbstractButton *QQuickDialog::standardButton(QPlatformDialogHelper::StandardButton button) const +{ + Q_D(const QQuickDialog); + if (!d->buttonBox) + return nullptr; + return d->buttonBox->standardButton(button); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty int QtQuick.Controls::Dialog::result + + This property holds the result code. + + Standard result codes: + \value Dialog.Accepted The dialog was accepted. + \value Dialog.Rejected The dialog was rejected. + + \sa accept(), reject(), done() +*/ +int QQuickDialog::result() const +{ + Q_D(const QQuickDialog); + return d->result; +} + +void QQuickDialog::setResult(int result) +{ + Q_D(QQuickDialog); + if (d->result == result) + return; + + d->result = result; + emit resultChanged(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Dialog::implicitHeaderWidth + \readonly + + This property holds the implicit header width. + + The value is equal to \c {header && header.visible ? header.implicitWidth : 0}. + + \sa implicitHeaderHeight, implicitFooterWidth +*/ +qreal QQuickDialog::implicitHeaderWidth() const +{ + Q_D(const QQuickDialog); + return d->popupItem->implicitHeaderWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Dialog::implicitHeaderHeight + \readonly + + This property holds the implicit header height. + + The value is equal to \c {header && header.visible ? header.implicitHeight : 0}. + + \sa implicitHeaderWidth, implicitFooterHeight +*/ +qreal QQuickDialog::implicitHeaderHeight() const +{ + Q_D(const QQuickDialog); + return d->popupItem->implicitHeaderHeight(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Dialog::implicitFooterWidth + \readonly + + This property holds the implicit footer width. + + The value is equal to \c {footer && footer.visible ? footer.implicitWidth : 0}. + + \sa implicitFooterHeight, implicitHeaderWidth +*/ +qreal QQuickDialog::implicitFooterWidth() const +{ + Q_D(const QQuickDialog); + return d->popupItem->implicitFooterWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Dialog::implicitFooterHeight + \readonly + + This property holds the implicit footer height. + + The value is equal to \c {footer && footer.visible ? footer.implicitHeight : 0}. + + \sa implicitFooterWidth, implicitHeaderHeight +*/ +qreal QQuickDialog::implicitFooterHeight() const +{ + Q_D(const QQuickDialog); + return d->popupItem->implicitFooterHeight(); +} + +/*! + \qmlmethod void QtQuick.Controls::Dialog::accept() + + Emits the \l accepted() signal and closes the dialog. + + \sa reject(), done() +*/ +void QQuickDialog::accept() +{ + done(Accepted); +} + +/*! + \qmlmethod void QtQuick.Controls::Dialog::reject() + + Emits the \l rejected() signal and closes the dialog. + + \sa accept(), done() +*/ +void QQuickDialog::reject() +{ + done(Rejected); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Dialog::done(int result) + + \list 1 + \li Sets the \a result. + \li Emits \l accepted() or \l rejected() depending on + whether the result is \c Dialog.Accepted or \c Dialog.Rejected, + respectively. + \li Emits \l{Popup::}{closed()}. + \endlist + + \sa accept(), reject(), result +*/ +void QQuickDialog::done(int result) +{ + setResult(result); + + if (result == Accepted) + emit accepted(); + else if (result == Rejected) + emit rejected(); + + close(); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickDialog::accessibleRole() const +{ + return QAccessible::Dialog; +} + +void QQuickDialog::accessibilityActiveChanged(bool active) +{ + Q_D(QQuickDialog); + QQuickPopup::accessibilityActiveChanged(active); + + if (active) + maybeSetAccessibleName(d->popupItem->title()); +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickdialog_p.cpp" diff --git a/src/quicktemplates2/qquickdialog_p.h b/src/quicktemplates2/qquickdialog_p.h new file mode 100644 index 00000000000..9b42fa15190 --- /dev/null +++ b/src/quicktemplates2/qquickdialog_p.h @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDIALOG_P_H +#define QQUICKDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p.h> +#include <QtGui/qpa/qplatformdialoghelper.h> + +QT_BEGIN_NAMESPACE + +class QQuickDialogPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDialog : public QQuickPopup +{ + Q_OBJECT + Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL) + Q_PROPERTY(QQuickItem *header READ header WRITE setHeader NOTIFY headerChanged FINAL) + Q_PROPERTY(QQuickItem *footer READ footer WRITE setFooter NOTIFY footerChanged FINAL) + Q_PROPERTY(QPlatformDialogHelper::StandardButtons standardButtons READ standardButtons WRITE setStandardButtons NOTIFY standardButtonsChanged FINAL) + // 2.3 (Qt 5.10) + Q_PROPERTY(int result READ result WRITE setResult NOTIFY resultChanged FINAL REVISION(2, 3)) + QML_EXTENDED_NAMESPACE(QPlatformDialogHelper) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitHeaderWidth READ implicitHeaderWidth NOTIFY implicitHeaderWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitHeaderHeight READ implicitHeaderHeight NOTIFY implicitHeaderHeightChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitFooterWidth READ implicitFooterWidth NOTIFY implicitFooterWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitFooterHeight READ implicitFooterHeight NOTIFY implicitFooterHeightChanged FINAL REVISION(2, 5)) + QML_NAMED_ELEMENT(Dialog) + QML_ADDED_IN_VERSION(2, 1) + +public: + explicit QQuickDialog(QObject *parent = nullptr); + ~QQuickDialog(); + + QString title() const; + void setTitle(const QString &title); + + QQuickItem *header() const; + void setHeader(QQuickItem *header); + + QQuickItem *footer() const; + void setFooter(QQuickItem *footer); + + QPlatformDialogHelper::StandardButtons standardButtons() const; + void setStandardButtons(QPlatformDialogHelper::StandardButtons buttons); + Q_REVISION(2, 3) Q_INVOKABLE QQuickAbstractButton *standardButton(QPlatformDialogHelper::StandardButton button) const; + + // 2.3 (Qt 5.10) + enum StandardCode { Rejected, Accepted }; + Q_ENUM(StandardCode) + + int result() const; + void setResult(int result); + + // 2.5 (Qt 5.12) + qreal implicitHeaderWidth() const; + qreal implicitHeaderHeight() const; + + qreal implicitFooterWidth() const; + qreal implicitFooterHeight() const; + +public Q_SLOTS: + virtual void accept(); + virtual void reject(); + virtual void done(int result); + +Q_SIGNALS: + void accepted(); + void rejected(); + void titleChanged(); + void headerChanged(); + void footerChanged(); + void standardButtonsChanged(); + // 2.3 (Qt 5.10) + Q_REVISION(2, 3) void applied(); + Q_REVISION(2, 3) void reset(); + Q_REVISION(2, 3) void discarded(); + Q_REVISION(2, 3) void helpRequested(); + Q_REVISION(2, 3) void resultChanged(); + // 2.5 (Qt 5.12) + void implicitHeaderWidthChanged(); + void implicitHeaderHeightChanged(); + void implicitFooterWidthChanged(); + void implicitFooterHeightChanged(); + +protected: + QQuickDialog(QQuickDialogPrivate &dd, QObject *parent); + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; + void accessibilityActiveChanged(bool active) override; +#endif + +private: + Q_DISABLE_COPY(QQuickDialog) + Q_DECLARE_PRIVATE(QQuickDialog) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickDialog) + +#endif // QQUICKDIALOG_P_H diff --git a/src/quicktemplates2/qquickdialog_p_p.h b/src/quicktemplates2/qquickdialog_p_p.h new file mode 100644 index 00000000000..eb40c918a4c --- /dev/null +++ b/src/quicktemplates2/qquickdialog_p_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDIALOG_P_P_H +#define QQUICKDIALOG_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p_p.h> +#include <QtGui/qpa/qplatformdialoghelper.h> + +QT_BEGIN_NAMESPACE + +class QQuickAbstractButton; +class QQuickDialogButtonBox; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDialogPrivate : public QQuickPopupPrivate +{ + Q_DECLARE_PUBLIC(QQuickDialog) + +public: + static QQuickDialogPrivate *get(QQuickDialog *dialog) + { + return dialog->d_func(); + } + + static QPlatformDialogHelper::ButtonRole buttonRole(QQuickAbstractButton *button); + + virtual void handleAccept(); + virtual void handleReject(); + virtual void handleClick(QQuickAbstractButton *button); + + int result = 0; + QString title; + QQuickDialogButtonBox *buttonBox = nullptr; + QPlatformDialogHelper::StandardButtons standardButtons = QPlatformDialogHelper::NoButton; +}; + +QT_END_NAMESPACE + +#endif // QQUICKDIALOG_P_P_H diff --git a/src/quicktemplates2/qquickdialogbuttonbox.cpp b/src/quicktemplates2/qquickdialogbuttonbox.cpp new file mode 100644 index 00000000000..8c62e4ed68a --- /dev/null +++ b/src/quicktemplates2/qquickdialogbuttonbox.cpp @@ -0,0 +1,868 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickdialogbuttonbox_p.h" +#include "qquickdialogbuttonbox_p_p.h" +#include "qquickabstractbutton_p.h" +#include "qquickbutton_p.h" +#include "qquickdialog_p_p.h" + +#include <QtCore/qpointer.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlcomponent.h> + +#include <algorithm> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype DialogButtonBox + \inherits Container +//! \instantiates QQuickDialogButtonBox + \inqmlmodule QtQuick.Controls + \ingroup qtquickcontrols2-dialogs + \brief A button box used in dialogs. + \since 5.8 + + Dialogs and message boxes typically present buttons in an order that + conforms to the interface guidelines for that platform. Invariably, + different platforms have their dialog buttons in different orders. + DialogButtonBox allows a developer to add buttons to it and will + automatically use the appropriate order for the user's platform. + + Most buttons for a dialog follow certain roles. Such roles include: + + \list + \li Accepting or rejecting the dialog. + \li Asking for help. + \li Performing actions on the dialog itself (such as resetting fields or + applying changes). + \endlist + + There can also be alternate ways of dismissing the dialog which may cause + destructive results. + + Most dialogs have buttons that can almost be considered standard (e.g. + \uicontrol OK and \uicontrol Cancel buttons). It is sometimes convenient + to create these buttons in a standard way. + + There are a couple ways of using DialogButtonBox. One way is to specify + the standard buttons (e.g. \uicontrol OK, \uicontrol Cancel, \uicontrol Save) + and let the button box setup the buttons. + + \image qtquickcontrols2-dialogbuttonbox.png + + \snippet qtquickcontrols2-dialogbuttonbox.qml 1 + + Alternatively, buttons and their roles can be specified by hand: + + \snippet qtquickcontrols2-dialogbuttonbox-attached.qml 1 + + You can also mix and match normal buttons and standard buttons. + + When a button is clicked in the button box, the \l clicked() signal is + emitted for the actual button that is pressed. In addition, the + following signals are automatically emitted when a button with the + respective role(s) is pressed: + + \table + \header + \li Role + \li Signal + \row + \li \c AcceptRole, \c YesRole + \li \l accepted() + \row + \li \c ApplyRole + \li \l applied() + \row + \li \c DiscardRole + \li \l discarded() + \row + \li \c HelpRole + \li \l helpRequested() + \row + \li \c RejectRole, \c NoRole + \li \l rejected() + \row + \li \c ResetRole + \li \l reset() + \endtable + + \sa Dialog +*/ + +/*! + \qmlsignal QtQuick.Controls::DialogButtonBox::accepted() + + This signal is emitted when a button defined with the \c AcceptRole or + \c YesRole is clicked. + + \sa rejected(), clicked(), helpRequested() +*/ + +/*! + \qmlsignal QtQuick.Controls::DialogButtonBox::rejected() + + This signal is emitted when a button defined with the \c RejectRole or + \c NoRole is clicked. + + \sa accepted(), helpRequested(), clicked() +*/ + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlsignal QtQuick.Controls::DialogButtonBox::applied() + + This signal is emitted when a button defined with the \c ApplyRole is + clicked. + + \sa discarded(), reset() +*/ + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlsignal QtQuick.Controls::DialogButtonBox::reset() + + This signal is emitted when a button defined with the \c ResetRole is + clicked. + + \sa discarded(), applied() +*/ + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlsignal QtQuick.Controls::DialogButtonBox::discarded() + + This signal is emitted when a button defined with the \c DiscardRole is + clicked. + + \sa reset(), applied() +*/ + +/*! + \qmlsignal QtQuick.Controls::DialogButtonBox::helpRequested() + + This signal is emitted when a button defined with the \c HelpRole is clicked. + + \sa accepted(), rejected(), clicked() +*/ + +/*! + \qmlsignal QtQuick.Controls::DialogButtonBox::clicked(AbstractButton button) + + This signal is emitted when a \a button inside the button box is clicked. + + \sa accepted(), rejected(), helpRequested() +*/ + +static QPlatformDialogHelper::ButtonLayout platformButtonLayout() +{ + return QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::DialogButtonBoxLayout).value<QPlatformDialogHelper::ButtonLayout>(); +} + +void QQuickDialogButtonBoxPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + QQuickContainerPrivate::itemImplicitWidthChanged(item); + if (item == contentItem) + resizeContent(); + else + updateImplicitContentWidth(); +} + +void QQuickDialogButtonBoxPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + QQuickContainerPrivate::itemImplicitHeightChanged(item); + if (item == contentItem) + resizeContent(); + else + updateImplicitContentHeight(); +} + +// adapted from QStyle::alignedRect() +static QRectF alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment, const QSizeF &size, const QRectF &rectangle) +{ + alignment = QGuiApplicationPrivate::visualAlignment(direction, alignment); + qreal x = rectangle.x(); + qreal y = rectangle.y(); + qreal w = size.width(); + qreal h = size.height(); + if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter || (alignment & Qt::AlignVertical_Mask) == 0) + y += (rectangle.size().height() - h) / 2; + else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom) + y += rectangle.size().height() - h; + if ((alignment & Qt::AlignRight) == Qt::AlignRight) + x += rectangle.size().width() - w; + else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter) + x += (rectangle.size().width() - w) / 2; + return QRectF(x, y, w, h); +} + +void QQuickDialogButtonBoxPrivate::resizeContent() +{ + Q_Q(QQuickDialogButtonBox); + if (!contentItem || !contentModel) + return; + + QRectF geometry = q->boundingRect().adjusted(q->leftPadding(), q->topPadding(), -q->rightPadding(), -q->bottomPadding()); + if (alignment != 0) + geometry = alignedRect(q->isMirrored() ? Qt::RightToLeft : Qt::LeftToRight, alignment, QSizeF(contentWidth, contentHeight), geometry); + + contentItem->setPosition(geometry.topLeft()); + contentItem->setSize(geometry.size()); +} + +void QQuickDialogButtonBoxPrivate::updateLayout() +{ + Q_Q(QQuickDialogButtonBox); + const int count = contentModel->count(); + if (count <= 0) + return; + + const int halign = alignment & Qt::AlignHorizontal_Mask; + const int valign = alignment & Qt::AlignVertical_Mask; + + QList<QQuickAbstractButton *> buttons; + const qreal cw = (alignment & Qt::AlignHorizontal_Mask) == 0 ? q->availableWidth() : contentWidth; + const qreal itemWidth = (cw - qMax(0, count - 1) * spacing) / count; + + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) { + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + if (!p->widthValid()) { + if (!halign) + item->setWidth(itemWidth); + else + item->resetWidth(); + if (!valign) + item->setHeight(contentHeight); + else + item->resetHeight(); + p->widthValidFlag = false; + } + } + buttons += static_cast<QQuickAbstractButton *>(item); + } + + struct ButtonLayout { + ButtonLayout(QPlatformDialogHelper::ButtonLayout layout) + : m_layout(QPlatformDialogHelper::buttonLayout(Qt::Horizontal, layout)) + { + } + + bool operator()(QQuickAbstractButton *first, QQuickAbstractButton *second) + { + const QPlatformDialogHelper::ButtonRole firstRole = QQuickDialogPrivate::buttonRole(first); + const QPlatformDialogHelper::ButtonRole secondRole = QQuickDialogPrivate::buttonRole(second); + + if (firstRole != secondRole && firstRole != QPlatformDialogHelper::InvalidRole && secondRole != QPlatformDialogHelper::InvalidRole) { + const int *l = m_layout; + while (*l != QPlatformDialogHelper::EOL) { + // Unset the Reverse flag. + const int role = (*l & ~QPlatformDialogHelper::Reverse); + if (role == firstRole) + return true; + if (role == secondRole) + return false; + ++l; + } + } + + if (firstRole == secondRole) + return false; + + return firstRole != QPlatformDialogHelper::InvalidRole; + } + const int *m_layout; + }; + + std::stable_sort(buttons.begin(), buttons.end(), ButtonLayout(static_cast<QPlatformDialogHelper::ButtonLayout>(buttonLayout))); + + for (int i = 0; i < buttons.count() - 1; ++i) + q->insertItem(i, buttons.at(i)); +} + +qreal QQuickDialogButtonBoxPrivate::getContentWidth() const +{ + Q_Q(const QQuickDialogButtonBox); + if (!contentModel) + return 0; + + const int count = contentModel->count(); + const qreal totalSpacing = qMax(0, count - 1) * spacing; + qreal totalWidth = totalSpacing; + qreal maxWidth = 0; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) { + totalWidth += item->implicitWidth(); + maxWidth = qMax(maxWidth, item->implicitWidth()); + } + } + if ((alignment & Qt::AlignHorizontal_Mask) == 0) + totalWidth = qMax(totalWidth, count * maxWidth + totalSpacing); + return totalWidth; +} + +qreal QQuickDialogButtonBoxPrivate::getContentHeight() const +{ + Q_Q(const QQuickDialogButtonBox); + if (!contentModel) + return 0; + + const int count = contentModel->count(); + qreal maxHeight = 0; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) + maxHeight = qMax(maxHeight, item->implicitHeight()); + } + return maxHeight; +} + +void QQuickDialogButtonBoxPrivate::handleClick() +{ + Q_Q(QQuickDialogButtonBox); + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->sender()); + if (!button) + return; + + // Can't fetch this *after* emitting clicked, as clicked may destroy the button + // or change its role. Now changing the role is not possible yet, but arguably + // both clicked and accepted/rejected/etc. should be emitted "atomically" + // depending on whatever role the button had at the time of the click. + const QPlatformDialogHelper::ButtonRole role = QQuickDialogPrivate::buttonRole(button); + QPointer<QQuickDialogButtonBox> guard(q); + + emit q->clicked(button); + + if (!guard) + return; + + switch (role) { + case QPlatformDialogHelper::AcceptRole: + case QPlatformDialogHelper::YesRole: + emit q->accepted(); + break; + case QPlatformDialogHelper::RejectRole: + case QPlatformDialogHelper::NoRole: + emit q->rejected(); + break; + case QPlatformDialogHelper::ApplyRole: + emit q->applied(); + break; + case QPlatformDialogHelper::ResetRole: + emit q->reset(); + break; + case QPlatformDialogHelper::DestructiveRole: + emit q->discarded(); + break; + case QPlatformDialogHelper::HelpRole: + emit q->helpRequested(); + break; + default: + break; + } +} + +QString QQuickDialogButtonBoxPrivate::buttonText(QPlatformDialogHelper::StandardButton standardButton) +{ + return QPlatformTheme::removeMnemonics(QGuiApplicationPrivate::platformTheme()->standardButtonText(standardButton)); +} + +QQuickAbstractButton *QQuickDialogButtonBoxPrivate::createStandardButton(QPlatformDialogHelper::StandardButton standardButton) +{ + Q_Q(QQuickDialogButtonBox); + if (!delegate) + return nullptr; + + QQmlContext *creationContext = delegate->creationContext(); + if (!creationContext) + creationContext = qmlContext(q); + QQmlContext *context = new QQmlContext(creationContext, q); + context->setContextObject(q); + + QObject *object = delegate->beginCreate(context); + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(object); + if (button) { + QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button, true)); + QQuickDialogButtonBoxAttachedPrivate::get(attached)->standardButton = standardButton; + attached->setButtonRole(QPlatformDialogHelper::buttonRole(standardButton)); + button->setText(buttonText(standardButton)); + delegate->completeCreate(); + button->setParent(q); + return button; + } + + delete object; + return nullptr; +} + +void QQuickDialogButtonBoxPrivate::removeStandardButtons() +{ + Q_Q(QQuickDialogButtonBox); + int i = q->count() - 1; + while (i >= 0) { + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->itemAt(i)); + if (button) { + QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>( + qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button, false)); + if (attached) { + QQuickDialogButtonBoxAttachedPrivate *p = QQuickDialogButtonBoxAttachedPrivate::get(attached); + if (p->standardButton != QPlatformDialogHelper::NoButton) { + q->removeItem(button); + button->deleteLater(); + } + } + } + --i; + } +} + +void QQuickDialogButtonBoxPrivate::updateLanguage() +{ + Q_Q(QQuickDialogButtonBox); + int i = q->count() - 1; + while (i >= 0) { + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(itemAt(i)); + if (button) { + QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>( + qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button, true)); + const auto boxAttachedPrivate = QQuickDialogButtonBoxAttachedPrivate::get(attached); + const QPlatformDialogHelper::StandardButton standardButton = boxAttachedPrivate->standardButton; + // The button might be a custom one with explicitly specified text, so we shouldn't change it in that case. + if (standardButton != QPlatformDialogHelper::NoButton) { + button->setText(buttonText(standardButton)); + } + } + --i; + } +} + +QQuickDialogButtonBox::QQuickDialogButtonBox(QQuickItem *parent) + : QQuickContainer(*(new QQuickDialogButtonBoxPrivate), parent) +{ + Q_D(QQuickDialogButtonBox); + d->changeTypes |= QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; + d->buttonLayout = platformButtonLayout(); +} + +QQuickDialogButtonBox::~QQuickDialogButtonBox() +{ + Q_D(QQuickDialogButtonBox); + // QQuickContainerPrivate does call this, but as our type information has already been + // destroyed by that point (since this destructor has already run), it won't call our + // implementation. So, we need to make sure our implementation is called. If we don't do this, + // the listener we installed on the contentItem won't get removed, possibly resulting in + // heap-use-after-frees. + contentItemChange(nullptr, d->contentItem); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::DialogButtonBox::position + + This property holds the position of the button box. + + \note If the button box is assigned as a header or footer of ApplicationWindow + or Page, the appropriate position is set automatically. + + Possible values: + \value DialogButtonBox.Header The button box is at the top, as a window or page header. + \value DialogButtonBox.Footer The button box is at the bottom, as a window or page header. + + The default value is \c Footer. + + \sa Dialog::header, Dialog::footer +*/ +QQuickDialogButtonBox::Position QQuickDialogButtonBox::position() const +{ + Q_D(const QQuickDialogButtonBox); + return d->position; +} + +void QQuickDialogButtonBox::setPosition(Position position) +{ + Q_D(QQuickDialogButtonBox); + if (d->position == position) + return; + + d->position = position; + emit positionChanged(); +} + +/*! + \qmlproperty flags QtQuick.Controls::DialogButtonBox::alignment + + This property holds the alignment of the buttons. + + Possible values: + \value undefined The buttons are resized to fill the available space. + \value Qt.AlignLeft The buttons are aligned to the left. + \value Qt.AlignHCenter The buttons are horizontally centered. + \value Qt.AlignRight The buttons are aligned to the right. + \value Qt.AlignTop The buttons are aligned to the top. + \value Qt.AlignVCenter The buttons are vertically centered. + \value Qt.AlignBottom The buttons are aligned to the bottom. +*/ +Qt::Alignment QQuickDialogButtonBox::alignment() const +{ + Q_D(const QQuickDialogButtonBox); + return d->alignment; +} + +void QQuickDialogButtonBox::setAlignment(Qt::Alignment alignment) +{ + Q_D(QQuickDialogButtonBox); + if (d->alignment == alignment) + return; + + d->alignment = alignment; + if (isComponentComplete()) { + d->resizeContent(); + polish(); + } + emit alignmentChanged(); +} + +void QQuickDialogButtonBox::resetAlignment() +{ + setAlignment({}); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::DialogButtonBox::standardButtons + + This property holds a combination of standard buttons that are used by the button box. + + \snippet qtquickcontrols2-dialogbuttonbox.qml 1 + + The buttons will be positioned in the appropriate order for the user's platform. + + Possible flags: + \value DialogButtonBox.Ok An "OK" button defined with the \c AcceptRole. + \value DialogButtonBox.Open An "Open" button defined with the \c AcceptRole. + \value DialogButtonBox.Save A "Save" button defined with the \c AcceptRole. + \value DialogButtonBox.Cancel A "Cancel" button defined with the \c RejectRole. + \value DialogButtonBox.Close A "Close" button defined with the \c RejectRole. + \value DialogButtonBox.Discard A "Discard" or "Don't Save" button, depending on the platform, defined with the \c DestructiveRole. + \value DialogButtonBox.Apply An "Apply" button defined with the \c ApplyRole. + \value DialogButtonBox.Reset A "Reset" button defined with the \c ResetRole. + \value DialogButtonBox.RestoreDefaults A "Restore Defaults" button defined with the \c ResetRole. + \value DialogButtonBox.Help A "Help" button defined with the \c HelpRole. + \value DialogButtonBox.SaveAll A "Save All" button defined with the \c AcceptRole. + \value DialogButtonBox.Yes A "Yes" button defined with the \c YesRole. + \value DialogButtonBox.YesToAll A "Yes to All" button defined with the \c YesRole. + \value DialogButtonBox.No A "No" button defined with the \c NoRole. + \value DialogButtonBox.NoToAll A "No to All" button defined with the \c NoRole. + \value DialogButtonBox.Abort An "Abort" button defined with the \c RejectRole. + \value DialogButtonBox.Retry A "Retry" button defined with the \c AcceptRole. + \value DialogButtonBox.Ignore An "Ignore" button defined with the \c AcceptRole. + \value DialogButtonBox.NoButton An invalid button. + + \sa standardButton() +*/ +QPlatformDialogHelper::StandardButtons QQuickDialogButtonBox::standardButtons() const +{ + Q_D(const QQuickDialogButtonBox); + return d->standardButtons; +} + +void QQuickDialogButtonBox::setStandardButtons(QPlatformDialogHelper::StandardButtons buttons) +{ + Q_D(QQuickDialogButtonBox); + if (d->standardButtons == buttons) + return; + + d->removeStandardButtons(); + + for (int i = QPlatformDialogHelper::FirstButton; i <= QPlatformDialogHelper::LastButton; i<<=1) { + QPlatformDialogHelper::StandardButton standardButton = static_cast<QPlatformDialogHelper::StandardButton>(i); + if (standardButton & buttons) { + QQuickAbstractButton *button = d->createStandardButton(standardButton); + if (button) + addItem(button); + } + } + + if (isComponentComplete()) + polish(); + + d->standardButtons = buttons; + emit standardButtonsChanged(); +} + +/*! + \qmlmethod AbstractButton QtQuick.Controls::DialogButtonBox::standardButton(StandardButton button) + + Returns the specified standard \a button, or \c null if it does not exist. + + \sa standardButtons +*/ +QQuickAbstractButton *QQuickDialogButtonBox::standardButton(QPlatformDialogHelper::StandardButton button) const +{ + Q_D(const QQuickDialogButtonBox); + if (Q_UNLIKELY(!(d->standardButtons & button))) + return nullptr; + for (int i = 0, n = count(); i < n; ++i) { + QQuickAbstractButton *btn = qobject_cast<QQuickAbstractButton *>(d->itemAt(i)); + if (Q_LIKELY(btn)) { + QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(btn, false)); + if (attached && QQuickDialogButtonBoxAttachedPrivate::get(attached)->standardButton == button) + return btn; + } + } + return nullptr; +} + +/*! + \qmlproperty Component QtQuick.Controls::DialogButtonBox::delegate + + This property holds a delegate for creating standard buttons. + + \sa standardButtons +*/ +QQmlComponent *QQuickDialogButtonBox::delegate() const +{ + Q_D(const QQuickDialogButtonBox); + return d->delegate; +} + +void QQuickDialogButtonBox::setDelegate(QQmlComponent* delegate) +{ + Q_D(QQuickDialogButtonBox); + if (d->delegate == delegate) + return; + + delete d->delegate; + d->delegate = delegate; + emit delegateChanged(); +} + +QQuickDialogButtonBoxAttached *QQuickDialogButtonBox::qmlAttachedProperties(QObject *object) +{ + return new QQuickDialogButtonBoxAttached(object); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty enumeration QtQuick.Controls::DialogButtonBox::buttonLayout + + This property holds the button layout policy to be used when arranging the buttons contained in the button box. + The default value is platform-specific. + + Available values: + \value DialogButtonBox.WinLayout Use a policy appropriate for applications on Windows. + \value DialogButtonBox.MacLayout Use a policy appropriate for applications on macOS. + \value DialogButtonBox.KdeLayout Use a policy appropriate for applications on KDE. + \value DialogButtonBox.GnomeLayout Use a policy appropriate for applications on GNOME. + \value DialogButtonBox.AndroidLayout Use a policy appropriate for applications on Android. +*/ +QPlatformDialogHelper::ButtonLayout QQuickDialogButtonBox::buttonLayout() const +{ + Q_D(const QQuickDialogButtonBox); + return d->buttonLayout; +} + +void QQuickDialogButtonBox::setButtonLayout(QPlatformDialogHelper::ButtonLayout layout) +{ + Q_D(QQuickDialogButtonBox); + if (d->buttonLayout == layout) + return; + + d->buttonLayout = layout; + if (isComponentComplete()) + d->updateLayout(); + emit buttonLayoutChanged(); +} + +void QQuickDialogButtonBox::resetButtonLayout() +{ + setButtonLayout(platformButtonLayout()); +} + +void QQuickDialogButtonBox::updatePolish() +{ + Q_D(QQuickDialogButtonBox); + QQuickContainer::updatePolish(); + d->updateLayout(); +} + +bool QQuickDialogButtonBox::event(QEvent *e) +{ + Q_D(QQuickDialogButtonBox); + if (e->type() == QEvent::LanguageChange) + d->updateLanguage(); + return QQuickContainer::event(e); +} + +void QQuickDialogButtonBox::componentComplete() +{ + Q_D(QQuickDialogButtonBox); + QQuickContainer::componentComplete(); + d->updateLayout(); +} + +void QQuickDialogButtonBox::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickDialogButtonBox); + QQuickContainer::geometryChange(newGeometry, oldGeometry); + d->updateLayout(); +} + +void QQuickDialogButtonBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + Q_D(QQuickDialogButtonBox); + QQuickContainer::contentItemChange(newItem, oldItem); + if (oldItem) + QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight); + if (newItem) + QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight); +} + +bool QQuickDialogButtonBox::isContent(QQuickItem *item) const +{ + return qobject_cast<QQuickAbstractButton *>(item); +} + +void QQuickDialogButtonBox::itemAdded(int index, QQuickItem *item) +{ + Q_D(QQuickDialogButtonBox); + Q_UNUSED(index); + if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(item)) + QObjectPrivate::connect(button, &QQuickAbstractButton::clicked, d, &QQuickDialogButtonBoxPrivate::handleClick); + if (QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(item, false))) + QQuickDialogButtonBoxAttachedPrivate::get(attached)->setButtonBox(this); + d->updateImplicitContentSize(); + if (isComponentComplete()) + polish(); +} + +void QQuickDialogButtonBox::itemRemoved(int index, QQuickItem *item) +{ + Q_D(QQuickDialogButtonBox); + Q_UNUSED(index); + if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(item)) + QObjectPrivate::disconnect(button, &QQuickAbstractButton::clicked, d, &QQuickDialogButtonBoxPrivate::handleClick); + if (QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(item, false))) + QQuickDialogButtonBoxAttachedPrivate::get(attached)->setButtonBox(nullptr); + d->updateImplicitContentSize(); + if (isComponentComplete()) + polish(); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickDialogButtonBox::accessibleRole() const +{ + return QAccessible::PageTabList; +} +#endif + +void QQuickDialogButtonBoxAttachedPrivate::setButtonBox(QQuickDialogButtonBox *box) +{ + Q_Q(QQuickDialogButtonBoxAttached); + if (buttonBox == box) + return; + + buttonBox = box; + emit q->buttonBoxChanged(); +} + +QQuickDialogButtonBoxAttached::QQuickDialogButtonBoxAttached(QObject *parent) + : QObject(*(new QQuickDialogButtonBoxAttachedPrivate), parent) +{ + Q_D(QQuickDialogButtonBoxAttached); + QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent); + while (parentItem && !d->buttonBox) { + d->buttonBox = qobject_cast<QQuickDialogButtonBox *>(parentItem); + parentItem = parentItem->parentItem(); + } +} + +/*! + \qmlattachedproperty DialogButtonBox QtQuick.Controls::DialogButtonBox::buttonBox + \readonly + + This attached property holds the button box that manages this button, or + \c null if the button is not in a button box. +*/ +QQuickDialogButtonBox *QQuickDialogButtonBoxAttached::buttonBox() const +{ + Q_D(const QQuickDialogButtonBoxAttached); + return d->buttonBox; +} + +/*! + \qmlattachedproperty enumeration QtQuick.Controls::DialogButtonBox::buttonRole + + This attached property holds the role of each button in a button box. + + \snippet qtquickcontrols2-dialogbuttonbox-attached.qml 1 + + Available values: + \value DialogButtonBox.InvalidRole The button is invalid. + \value DialogButtonBox.AcceptRole Clicking the button causes the dialog to be accepted (e.g. \uicontrol OK). + \value DialogButtonBox.RejectRole Clicking the button causes the dialog to be rejected (e.g. \uicontrol Cancel). + \value DialogButtonBox.DestructiveRole Clicking the button causes a destructive change (e.g. for discarding changes) and closes the dialog. + \value DialogButtonBox.ActionRole Clicking the button causes changes to the elements within the dialog. + \value DialogButtonBox.HelpRole The button can be clicked to request help. + \value DialogButtonBox.YesRole The button is a "Yes"-like button. + \value DialogButtonBox.NoRole The button is a "No"-like button. + \value DialogButtonBox.ResetRole The button resets the dialog's fields to default values. + \value DialogButtonBox.ApplyRole The button applies current changes. +*/ +QPlatformDialogHelper::ButtonRole QQuickDialogButtonBoxAttached::buttonRole() const +{ + Q_D(const QQuickDialogButtonBoxAttached); + return d->buttonRole; +} + +void QQuickDialogButtonBoxAttached::setButtonRole(QPlatformDialogHelper::ButtonRole role) +{ + Q_D(QQuickDialogButtonBoxAttached); + if (d->buttonRole == role) + return; + + d->buttonRole = role; + emit buttonRoleChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qquickdialogbuttonbox_p.cpp" diff --git a/src/quicktemplates2/qquickdialogbuttonbox_p.h b/src/quicktemplates2/qquickdialogbuttonbox_p.h new file mode 100644 index 00000000000..48e721e5cda --- /dev/null +++ b/src/quicktemplates2/qquickdialogbuttonbox_p.h @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDIALOGBUTTONBOX_P_H +#define QQUICKDIALOGBUTTONBOX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickcontainer_p.h> +#include <QtGui/qpa/qplatformdialoghelper.h> + +QT_BEGIN_NAMESPACE + +class QQmlComponent; +class QQuickDialogButtonBoxPrivate; +class QQuickDialogButtonBoxAttached; +class QQuickDialogButtonBoxAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDialogButtonBox : public QQuickContainer +{ + Q_OBJECT + Q_PROPERTY(Position position READ position WRITE setPosition NOTIFY positionChanged FINAL) + Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment RESET resetAlignment NOTIFY alignmentChanged FINAL) + Q_PROPERTY(QPlatformDialogHelper::StandardButtons standardButtons READ standardButtons WRITE setStandardButtons NOTIFY standardButtonsChanged FINAL) + Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL) + // 2.5 (Qt 5.12) + Q_PROPERTY(QPlatformDialogHelper::ButtonLayout buttonLayout READ buttonLayout WRITE setButtonLayout RESET resetButtonLayout NOTIFY buttonLayoutChanged FINAL REVISION(2, 5)) + Q_FLAGS(QPlatformDialogHelper::StandardButtons) + QML_NAMED_ELEMENT(DialogButtonBox) + QML_ATTACHED(QQuickDialogButtonBoxAttached) + QML_ADDED_IN_VERSION(2, 1) + +public: + explicit QQuickDialogButtonBox(QQuickItem *parent = nullptr); + ~QQuickDialogButtonBox(); + + enum Position { + Header, + Footer + }; + Q_ENUM(Position) + + Position position() const; + void setPosition(Position position); + + Qt::Alignment alignment() const; + void setAlignment(Qt::Alignment alignment); + void resetAlignment(); + + QPlatformDialogHelper::StandardButtons standardButtons() const; + void setStandardButtons(QPlatformDialogHelper::StandardButtons buttons); + Q_INVOKABLE QQuickAbstractButton *standardButton(QPlatformDialogHelper::StandardButton button) const; + + QQmlComponent *delegate() const; + void setDelegate(QQmlComponent *delegate); + + static QQuickDialogButtonBoxAttached *qmlAttachedProperties(QObject *object); + + // 2.5 (Qt 5.12) + Q_ENUMS(QPlatformDialogHelper::ButtonLayout) + + QPlatformDialogHelper::ButtonLayout buttonLayout() const; + void setButtonLayout(QPlatformDialogHelper::ButtonLayout layout); + void resetButtonLayout(); + +Q_SIGNALS: + void accepted(); + void rejected(); + void helpRequested(); + void clicked(QQuickAbstractButton *button); + void positionChanged(); + void alignmentChanged(); + void standardButtonsChanged(); + void delegateChanged(); + // 2.3 (Qt 5.10) + Q_REVISION(2, 3) void applied(); + Q_REVISION(2, 3) void reset(); + Q_REVISION(2, 3) void discarded(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void buttonLayoutChanged(); + +protected: + void updatePolish() override; + void componentComplete() override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + bool isContent(QQuickItem *item) const override; + void itemAdded(int index, QQuickItem *item) override; + void itemRemoved(int index, QQuickItem *item) override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + bool event(QEvent *e) override; + +private: + Q_DISABLE_COPY(QQuickDialogButtonBox) + Q_DECLARE_PRIVATE(QQuickDialogButtonBox) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDialogButtonBoxAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickDialogButtonBox *buttonBox READ buttonBox NOTIFY buttonBoxChanged FINAL) + Q_PROPERTY(QPlatformDialogHelper::ButtonRole buttonRole READ buttonRole WRITE setButtonRole NOTIFY buttonRoleChanged FINAL) + Q_ENUMS(QPlatformDialogHelper::ButtonRole) + +public: + explicit QQuickDialogButtonBoxAttached(QObject *parent = nullptr); + + QQuickDialogButtonBox *buttonBox() const; + + QPlatformDialogHelper::ButtonRole buttonRole() const; + void setButtonRole(QPlatformDialogHelper::ButtonRole role); + +Q_SIGNALS: + void buttonBoxChanged(); + void buttonRoleChanged(); + +private: + Q_DISABLE_COPY(QQuickDialogButtonBoxAttached) + Q_DECLARE_PRIVATE(QQuickDialogButtonBoxAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickDialogButtonBox) +QML_DECLARE_TYPEINFO(QQuickDialogButtonBox, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKDIALOGBUTTONBOX_P_H diff --git a/src/quicktemplates2/qquickdialogbuttonbox_p_p.h b/src/quicktemplates2/qquickdialogbuttonbox_p_p.h new file mode 100644 index 00000000000..5e08b2adf18 --- /dev/null +++ b/src/quicktemplates2/qquickdialogbuttonbox_p_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDIALOGBUTTONBOX_P_P_H +#define QQUICKDIALOGBUTTONBOX_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontainer_p_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDialogButtonBoxPrivate : public QQuickContainerPrivate +{ + Q_DECLARE_PUBLIC(QQuickDialogButtonBox) + +public: + static QQuickDialogButtonBoxPrivate *get(QQuickDialogButtonBox *box) + { + return box->d_func(); + } + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + void resizeContent() override; + + void updateLayout(); + + qreal getContentWidth() const override; + qreal getContentHeight() const override; + + void handleClick(); + + static QString buttonText(QPlatformDialogHelper::StandardButton standardButton); + + QQuickAbstractButton *createStandardButton(QPlatformDialogHelper::StandardButton button); + void removeStandardButtons(); + + void updateLanguage(); + + Qt::Alignment alignment; + QQuickDialogButtonBox::Position position = QQuickDialogButtonBox::Footer; + QPlatformDialogHelper::StandardButtons standardButtons = QPlatformDialogHelper::NoButton; + QPlatformDialogHelper::ButtonLayout buttonLayout = QPlatformDialogHelper::UnknownLayout; + QQmlComponent *delegate = nullptr; +}; + +class QQuickDialogButtonBoxAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickDialogButtonBoxAttached) + +public: + static QQuickDialogButtonBoxAttachedPrivate *get(QQuickDialogButtonBoxAttached *q) + { + return q->d_func(); + } + + void setButtonBox(QQuickDialogButtonBox *box); + + QQuickDialogButtonBox *buttonBox = nullptr; + QPlatformDialogHelper::ButtonRole buttonRole = QPlatformDialogHelper::InvalidRole; + QPlatformDialogHelper::StandardButton standardButton = QPlatformDialogHelper::NoButton; +}; + +QT_END_NAMESPACE + +#endif // QQUICKDIALOGBUTTONBOX_P_P_H diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp new file mode 100644 index 00000000000..1d89948b4d7 --- /dev/null +++ b/src/quicktemplates2/qquickdrawer.cpp @@ -0,0 +1,822 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickdrawer_p.h" +#include "qquickdrawer_p_p.h" +#include "qquickpopupitem_p_p.h" +#include "qquickpopuppositioner_p_p.h" + +#include <QtGui/qstylehints.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qquickanimation_p.h> +#include <QtQuick/private/qquicktransition_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Drawer + \inherits Popup +//! \instantiates QQuickDrawer + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-navigation + \ingroup qtquickcontrols2-popups + \brief Side panel that can be opened and closed using a swipe gesture. + + Drawer provides a swipe-based side panel, similar to those often used in + touch interfaces to provide a central location for navigation. + + \image qtquickcontrols2-drawer.gif + + Drawer can be positioned at any of the four edges of the content item. + The drawer above is positioned against the left edge of the window. The + drawer is then opened by \e "dragging" it out from the left edge of the + window. + + \code + import QtQuick + import QtQuick.Controls + + ApplicationWindow { + id: window + visible: true + + Drawer { + id: drawer + width: 0.66 * window.width + height: window.height + + Label { + text: "Content goes here!" + anchors.centerIn: parent + } + } + } + \endcode + + Drawer is a special type of popup that resides at one of the window \l {edge}{edges}. + By default, Drawer re-parents itself to the window \c overlay, and therefore operates + on window coordinates. It is also possible to manually set the \l{Popup::}{parent} to + something else to make the drawer operate in a specific coordinate space. + + Drawer can be configured to cover only part of its window edge. The following example + illustrates how Drawer can be positioned to appear below a window header: + + \code + import QtQuick + import QtQuick.Controls + + ApplicationWindow { + id: window + visible: true + + header: ToolBar { } + + Drawer { + y: header.height + width: window.width * 0.6 + height: window.height - header.height + } + } + \endcode + + The \l position property determines how much of the drawer is visible, as + a value between \c 0.0 and \c 1.0. It is not possible to set the x-coordinate + (or horizontal margins) of a drawer at the left or right window edge, or the + y-coordinate (or vertical margins) of a drawer at the top or bottom window edge. + + In the image above, the application's contents are \e "pushed" across the + screen. This is achieved by applying a translation to the contents: + + \code + import QtQuick + import QtQuick.Controls + + ApplicationWindow { + id: window + width: 200 + height: 228 + visible: true + + Drawer { + id: drawer + width: 0.66 * window.width + height: window.height + } + + Label { + id: content + + text: "Aa" + font.pixelSize: 96 + anchors.fill: parent + verticalAlignment: Label.AlignVCenter + horizontalAlignment: Label.AlignHCenter + + transform: Translate { + x: drawer.position * content.width * 0.33 + } + } + } + \endcode + + If you would like the application's contents to stay where they are when + the drawer is opened, don't apply a translation. + + Drawer can be configured as a non-closable persistent side panel by + making the Drawer \l {Popup::modal}{non-modal} and \l {interactive} + {non-interactive}. See the \l {Qt Quick Controls 2 - Side Panel}{Side Panel} + example for more details. + + \note On some platforms, certain edges may be reserved for system + gestures and therefore cannot be used with Drawer. For example, the + top and bottom edges may be reserved for system notifications and + control centers on Android and iOS. + + \sa SwipeView, {Customizing Drawer}, {Navigation Controls}, {Popup Controls} +*/ + +class QQuickDrawerPositioner : public QQuickPopupPositioner +{ +public: + QQuickDrawerPositioner(QQuickDrawer *drawer) : QQuickPopupPositioner(drawer) { } + + void reposition() override; +}; + +qreal QQuickDrawerPrivate::offsetAt(const QPointF &point) const +{ + qreal offset = positionAt(point) - position; + + // don't jump when dragged open + if (offset > 0 && position > 0 && !contains(point)) + offset = 0; + + return offset; +} + +qreal QQuickDrawerPrivate::positionAt(const QPointF &point) const +{ + Q_Q(const QQuickDrawer); + QQuickWindow *window = q->window(); + if (!window) + return 0; + + switch (edge) { + case Qt::TopEdge: + return point.y() / q->height(); + case Qt::LeftEdge: + return point.x() / q->width(); + case Qt::RightEdge: + return (window->width() - point.x()) / q->width(); + case Qt::BottomEdge: + return (window->height() - point.y()) / q->height(); + default: + return 0; + } +} + +QQuickPopupPositioner *QQuickDrawerPrivate::getPositioner() +{ + Q_Q(QQuickDrawer); + if (!positioner) + positioner = new QQuickDrawerPositioner(q); + return positioner; +} + +void QQuickDrawerPositioner::reposition() +{ + if (m_positioning) + return; + + QQuickDrawer *drawer = static_cast<QQuickDrawer*>(popup()); + QQuickWindow *window = drawer->window(); + if (!window) + return; + + const qreal position = drawer->position(); + QQuickItem *popupItem = drawer->popupItem(); + switch (drawer->edge()) { + case Qt::LeftEdge: + popupItem->setX((position - 1.0) * popupItem->width()); + break; + case Qt::RightEdge: + popupItem->setX(window->width() - position * popupItem->width()); + break; + case Qt::TopEdge: + popupItem->setY((position - 1.0) * popupItem->height()); + break; + case Qt::BottomEdge: + popupItem->setY(window->height() - position * popupItem->height()); + break; + } + + QQuickPopupPositioner::reposition(); +} + +void QQuickDrawerPrivate::showOverlay() +{ + // managed in setPosition() +} + +void QQuickDrawerPrivate::hideOverlay() +{ + // managed in setPosition() +} + +void QQuickDrawerPrivate::resizeOverlay() +{ + if (!dimmer || !window) + return; + + QRectF geometry(0, 0, window->width(), window->height()); + + if (edge == Qt::LeftEdge || edge == Qt::RightEdge) { + geometry.setY(popupItem->y()); + geometry.setHeight(popupItem->height()); + } else { + geometry.setX(popupItem->x()); + geometry.setWidth(popupItem->width()); + } + + dimmer->setPosition(geometry.topLeft()); + dimmer->setSize(geometry.size()); +} + +static bool isWithinDragMargin(const QQuickDrawer *drawer, const QPointF &pos) +{ + switch (drawer->edge()) { + case Qt::LeftEdge: + return pos.x() <= drawer->dragMargin(); + case Qt::RightEdge: + return pos.x() >= drawer->window()->width() - drawer->dragMargin(); + case Qt::TopEdge: + return pos.y() <= drawer->dragMargin(); + case Qt::BottomEdge: + return pos.y() >= drawer->window()->height() - drawer->dragMargin(); + default: + Q_UNREACHABLE(); + break; + } + return false; +} + +bool QQuickDrawerPrivate::startDrag(QEvent *event) +{ + Q_Q(QQuickDrawer); + if (!window || !interactive || dragMargin < 0.0 || qFuzzyIsNull(dragMargin)) + return false; + + switch (event->type()) { + case QEvent::MouseButtonPress: + if (isWithinDragMargin(q, static_cast<QMouseEvent *>(event)->scenePosition())) { + prepareEnterTransition(); + reposition(); + return handleMouseEvent(window->contentItem(), static_cast<QMouseEvent *>(event)); + } + break; + +#if QT_CONFIG(quicktemplates2_multitouch) + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + for (const QTouchEvent::TouchPoint &point : static_cast<QTouchEvent *>(event)->points()) { + if (point.state() == QEventPoint::Pressed && isWithinDragMargin(q, point.scenePosition())) { + prepareEnterTransition(); + reposition(); + return handleTouchEvent(window->contentItem(), static_cast<QTouchEvent *>(event)); + } + } + break; +#endif + + default: + break; + } + + return false; +} + +static inline bool keepGrab(QQuickItem *item) +{ + return item->keepMouseGrab() || item->keepTouchGrab(); +} + +bool QQuickDrawerPrivate::grabMouse(QQuickItem *item, QMouseEvent *event) +{ + Q_Q(QQuickDrawer); + handleMouseEvent(item, event); + + if (!window || !interactive || keepGrab(popupItem) || keepGrab(item)) + return false; + + const QPointF movePoint = event->scenePosition(); + + // Flickable uses a hard-coded threshold of 15 for flicking, and + // QStyleHints::startDragDistance for dragging. Drawer uses a bit + // larger threshold to avoid being too eager to steal touch (QTBUG-50045) + const int threshold = qMax(20, QGuiApplication::styleHints()->startDragDistance() + 5); + bool overThreshold = false; + if (position > 0 || dragMargin > 0) { + const bool xOverThreshold = QQuickWindowPrivate::dragOverThreshold(movePoint.x() - pressPoint.x(), Qt::XAxis, event, threshold); + const bool yOverThreshold = QQuickWindowPrivate::dragOverThreshold(movePoint.y() - pressPoint.y(), Qt::YAxis, event, threshold); + if (edge == Qt::LeftEdge || edge == Qt::RightEdge) + overThreshold = xOverThreshold && !yOverThreshold; + else + overThreshold = yOverThreshold && !xOverThreshold; + } + + // Don't be too eager to steal presses outside the drawer (QTBUG-53929) + if (overThreshold && qFuzzyCompare(position, qreal(1.0)) && !contains(movePoint)) { + if (edge == Qt::LeftEdge || edge == Qt::RightEdge) + overThreshold = qAbs(movePoint.x() - q->width()) < dragMargin; + else + overThreshold = qAbs(movePoint.y() - q->height()) < dragMargin; + } + + if (overThreshold) { + popupItem->grabMouse(); + popupItem->setKeepMouseGrab(true); + offset = offsetAt(movePoint); + } + + return overThreshold; +} + +#if QT_CONFIG(quicktemplates2_multitouch) +bool QQuickDrawerPrivate::grabTouch(QQuickItem *item, QTouchEvent *event) +{ + Q_Q(QQuickDrawer); + bool handled = handleTouchEvent(item, event); + + if (!window || !interactive || keepGrab(popupItem) || keepGrab(item) || !event->touchPointStates().testFlag(QEventPoint::Updated)) + return handled; + + bool overThreshold = false; + for (const QTouchEvent::TouchPoint &point : event->points()) { + if (!acceptTouch(point) || point.state() != QEventPoint::Updated) + continue; + + const QPointF movePoint = point.scenePosition(); + + // Flickable uses a hard-coded threshold of 15 for flicking, and + // QStyleHints::startDragDistance for dragging. Drawer uses a bit + // larger threshold to avoid being too eager to steal touch (QTBUG-50045) + const int threshold = qMax(20, QGuiApplication::styleHints()->startDragDistance() + 5); + if (position > 0 || dragMargin > 0) { + const bool xOverThreshold = QQuickWindowPrivate::dragOverThreshold(movePoint.x() - pressPoint.x(), Qt::XAxis, &point, threshold); + const bool yOverThreshold = QQuickWindowPrivate::dragOverThreshold(movePoint.y() - pressPoint.y(), Qt::YAxis, &point, threshold); + if (edge == Qt::LeftEdge || edge == Qt::RightEdge) + overThreshold = xOverThreshold && !yOverThreshold; + else + overThreshold = yOverThreshold && !xOverThreshold; + } + + // Don't be too eager to steal presses outside the drawer (QTBUG-53929) + if (overThreshold && qFuzzyCompare(position, qreal(1.0)) && !contains(movePoint)) { + if (edge == Qt::LeftEdge || edge == Qt::RightEdge) + overThreshold = qAbs(movePoint.x() - q->width()) < dragMargin; + else + overThreshold = qAbs(movePoint.y() - q->height()) < dragMargin; + } + + if (overThreshold) { + popupItem->grabTouchPoints(QList<int>() << touchId); + popupItem->setKeepTouchGrab(true); + offset = offsetAt(movePoint); + } + } + + return overThreshold; +} +#endif + +static const qreal openCloseVelocityThreshold = 300; + +// Overrides QQuickPopupPrivate::blockInput, which is called by +// QQuickPopupPrivate::handlePress/Move/Release, which we call in our own +// handlePress/Move/Release overrides. +// This implementation conflates two things: should the event going to the item get +// modally blocked by us? Or should we accept the event and become the grabber? +// Those are two fundamentally different questions for the drawer as a (usually) +// interactive control. +bool QQuickDrawerPrivate::blockInput(QQuickItem *item, const QPointF &point) const +{ + Q_Q(const QQuickDrawer); + + // We want all events, if mouse/touch is already grabbed. + if (popupItem->keepMouseGrab() || popupItem->keepTouchGrab()) + return true; + + // Don't block input to drawer's children/content. + if (popupItem->isAncestorOf(item)) + return false; + + // Don't block outside a drawer's background dimming + if (dimmer && !dimmer->contains(dimmer->mapFromScene(point))) + return false; + + // Accept all events within drag area. + if (isWithinDragMargin(q, point)) + return true; + + // Accept all other events if drawer is modal. + return modal; +} + +bool QQuickDrawerPrivate::handlePress(QQuickItem *item, const QPointF &point, ulong timestamp) +{ + offset = 0; + velocityCalculator.startMeasuring(point, timestamp); + + if (!QQuickPopupPrivate::handlePress(item, point, timestamp)) + return interactive && popupItem == item; + + return true; +} + +bool QQuickDrawerPrivate::handleMove(QQuickItem *item, const QPointF &point, ulong timestamp) +{ + Q_Q(QQuickDrawer); + if (!QQuickPopupPrivate::handleMove(item, point, timestamp)) + return false; + + // limit/reset the offset to the edge of the drawer when pushed from the outside + if (qFuzzyCompare(position, qreal(1.0)) && !contains(point)) + offset = 0; + + bool isGrabbed = popupItem->keepMouseGrab() || popupItem->keepTouchGrab(); + if (isGrabbed) + q->setPosition(positionAt(point) - offset); + + return isGrabbed; +} + +bool QQuickDrawerPrivate::handleRelease(QQuickItem *item, const QPointF &point, ulong timestamp) +{ + auto cleanup = qScopeGuard([this] { + popupItem->setKeepMouseGrab(false); + popupItem->setKeepTouchGrab(false); + pressPoint = QPointF(); + touchId = -1; + }); + if (pressPoint.isNull()) + return false; + if (!popupItem->keepMouseGrab() && !popupItem->keepTouchGrab()) { + velocityCalculator.reset(); + return QQuickPopupPrivate::handleRelease(item, point, timestamp); + } + + velocityCalculator.stopMeasuring(point, timestamp); + + qreal velocity = 0; + if (edge == Qt::LeftEdge || edge == Qt::RightEdge) + velocity = velocityCalculator.velocity().x(); + else + velocity = velocityCalculator.velocity().y(); + + // the velocity is calculated so that swipes from left to right + // and top to bottom have positive velocity, and swipes from right + // to left and bottom to top have negative velocity. + // + // - top/left edge: positive velocity opens, negative velocity closes + // - bottom/right edge: negative velocity opens, positive velocity closes + // + // => invert the velocity for bottom and right edges, for the threshold comparison below + if (edge == Qt::RightEdge || edge == Qt::BottomEdge) + velocity = -velocity; + + if (position > 0.7 || velocity > openCloseVelocityThreshold) { + transitionManager.transitionEnter(); + } else if (position < 0.3 || velocity < -openCloseVelocityThreshold) { + transitionManager.transitionExit(); + } else { + switch (edge) { + case Qt::LeftEdge: + if (point.x() - pressPoint.x() > 0) + transitionManager.transitionEnter(); + else + transitionManager.transitionExit(); + break; + case Qt::RightEdge: + if (point.x() - pressPoint.x() < 0) + transitionManager.transitionEnter(); + else + transitionManager.transitionExit(); + break; + case Qt::TopEdge: + if (point.y() - pressPoint.y() > 0) + transitionManager.transitionEnter(); + else + transitionManager.transitionExit(); + break; + case Qt::BottomEdge: + if (point.y() - pressPoint.y() < 0) + transitionManager.transitionEnter(); + else + transitionManager.transitionExit(); + break; + } + } + + // the cleanup() lambda will run before return + return popupItem->keepMouseGrab() || popupItem->keepTouchGrab(); +} + +void QQuickDrawerPrivate::handleUngrab() +{ + QQuickPopupPrivate::handleUngrab(); + + velocityCalculator.reset(); +} + +static QList<QQuickStateAction> prepareTransition(QQuickDrawer *drawer, QQuickTransition *transition, qreal to) +{ + QList<QQuickStateAction> actions; + if (!transition || !QQuickPopupPrivate::get(drawer)->window || !transition->enabled()) + return actions; + + qmlExecuteDeferred(transition); + + QQmlProperty defaultTarget(drawer, QLatin1String("position")); + QQmlListProperty<QQuickAbstractAnimation> animations = transition->animations(); + int count = animations.count(&animations); + for (int i = 0; i < count; ++i) { + QQuickAbstractAnimation *anim = animations.at(&animations, i); + anim->setDefaultTarget(defaultTarget); + } + + actions << QQuickStateAction(drawer, QLatin1String("position"), to); + return actions; +} + +bool QQuickDrawerPrivate::prepareEnterTransition() +{ + Q_Q(QQuickDrawer); + enterActions = prepareTransition(q, enter, 1.0); + return QQuickPopupPrivate::prepareEnterTransition(); +} + +bool QQuickDrawerPrivate::prepareExitTransition() +{ + Q_Q(QQuickDrawer); + exitActions = prepareTransition(q, exit, 0.0); + return QQuickPopupPrivate::prepareExitTransition(); +} + +bool QQuickDrawerPrivate::setEdge(Qt::Edge e) +{ + Q_Q(QQuickDrawer); + switch (e) { + case Qt::LeftEdge: + case Qt::RightEdge: + allowVerticalMove = true; + allowVerticalResize = true; + allowHorizontalMove = false; + allowHorizontalResize = false; + break; + case Qt::TopEdge: + case Qt::BottomEdge: + allowVerticalMove = false; + allowVerticalResize = false; + allowHorizontalMove = true; + allowHorizontalResize = true; + break; + default: + qmlWarning(q) << "invalid edge value - valid values are: " + << "Qt.TopEdge, Qt.LeftEdge, Qt.RightEdge, Qt.BottomEdge"; + return false; + } + + edge = e; + return true; +} + +QQuickDrawer::QQuickDrawer(QObject *parent) + : QQuickPopup(*(new QQuickDrawerPrivate), parent) +{ + Q_D(QQuickDrawer); + d->dragMargin = QGuiApplication::styleHints()->startDragDistance(); + d->setEdge(Qt::LeftEdge); + + setFocus(true); + setModal(true); + setFiltersChildMouseEvents(true); + setClosePolicy(CloseOnEscape | CloseOnReleaseOutside); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::Drawer::edge + + This property holds the edge of the window at which the drawer will + open from. The acceptable values are: + + \value Qt.TopEdge The top edge of the window. + \value Qt.LeftEdge The left edge of the window (default). + \value Qt.RightEdge The right edge of the window. + \value Qt.BottomEdge The bottom edge of the window. +*/ +Qt::Edge QQuickDrawer::edge() const +{ + Q_D(const QQuickDrawer); + return d->edge; +} + +void QQuickDrawer::setEdge(Qt::Edge edge) +{ + Q_D(QQuickDrawer); + if (d->edge == edge) + return; + + if (!d->setEdge(edge)) + return; + + if (isComponentComplete()) + d->reposition(); + emit edgeChanged(); +} + +/*! + \qmlproperty real QtQuick.Controls::Drawer::position + + This property holds the position of the drawer relative to its final + destination. That is, the position will be \c 0.0 when the drawer + is fully closed, and \c 1.0 when fully open. +*/ +qreal QQuickDrawer::position() const +{ + Q_D(const QQuickDrawer); + return d->position; +} + +void QQuickDrawer::setPosition(qreal position) +{ + Q_D(QQuickDrawer); + position = qBound<qreal>(0.0, position, 1.0); + if (qFuzzyCompare(d->position, position)) + return; + + d->position = position; + if (isComponentComplete()) + d->reposition(); + if (d->dimmer) + d->dimmer->setOpacity(position); + emit positionChanged(); +} + +/*! + \qmlproperty real QtQuick.Controls::Drawer::dragMargin + + This property holds the distance from the screen edge within which + drag actions will open the drawer. Setting the value to \c 0 or less + prevents opening the drawer by dragging. + + The default value is \c Qt.styleHints.startDragDistance. + + \sa interactive +*/ +qreal QQuickDrawer::dragMargin() const +{ + Q_D(const QQuickDrawer); + return d->dragMargin; +} + +void QQuickDrawer::setDragMargin(qreal margin) +{ + Q_D(QQuickDrawer); + if (qFuzzyCompare(d->dragMargin, margin)) + return; + + d->dragMargin = margin; + emit dragMarginChanged(); +} + +void QQuickDrawer::resetDragMargin() +{ + setDragMargin(QGuiApplication::styleHints()->startDragDistance()); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty bool QtQuick.Controls::Drawer::interactive + + This property holds whether the drawer is interactive. A non-interactive + drawer does not react to swipes. + + The default value is \c true. + + \sa dragMargin +*/ +bool QQuickDrawer::isInteractive() const +{ + Q_D(const QQuickDrawer); + return d->interactive; +} + +void QQuickDrawer::setInteractive(bool interactive) +{ + Q_D(QQuickDrawer); + if (d->interactive == interactive) + return; + + setFiltersChildMouseEvents(interactive); + d->interactive = interactive; + emit interactiveChanged(); +} + +bool QQuickDrawer::childMouseEventFilter(QQuickItem *child, QEvent *event) +{ + Q_D(QQuickDrawer); + switch (event->type()) { +#if QT_CONFIG(quicktemplates2_multitouch) + case QEvent::TouchUpdate: + return d->grabTouch(child, static_cast<QTouchEvent *>(event)); + case QEvent::TouchBegin: + case QEvent::TouchEnd: + return d->handleTouchEvent(child, static_cast<QTouchEvent *>(event)); +#endif + case QEvent::MouseMove: + return d->grabMouse(child, static_cast<QMouseEvent *>(event)); + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + return d->handleMouseEvent(child, static_cast<QMouseEvent *>(event)); + default: + break; + } + return false; +} + +void QQuickDrawer::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QQuickDrawer); + d->grabMouse(d->popupItem, event); +} + +bool QQuickDrawer::overlayEvent(QQuickItem *item, QEvent *event) +{ + Q_D(QQuickDrawer); + switch (event->type()) { +#if QT_CONFIG(quicktemplates2_multitouch) + case QEvent::TouchUpdate: + return d->grabTouch(item, static_cast<QTouchEvent *>(event)); +#endif + case QEvent::MouseMove: + return d->grabMouse(item, static_cast<QMouseEvent *>(event)); + default: + break; + } + return QQuickPopup::overlayEvent(item, event); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickDrawer::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickDrawer); + d->grabTouch(d->popupItem, event); +} +#endif + +void QQuickDrawer::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickDrawer); + QQuickPopup::geometryChange(newGeometry, oldGeometry); + d->resizeOverlay(); +} + +QT_END_NAMESPACE + +#include "moc_qquickdrawer_p.cpp" diff --git a/src/quicktemplates2/qquickdrawer_p.h b/src/quicktemplates2/qquickdrawer_p.h new file mode 100644 index 00000000000..f16ae771bb1 --- /dev/null +++ b/src/quicktemplates2/qquickdrawer_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDRAWER_P_H +#define QQUICKDRAWER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickpopup_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickDrawerPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDrawer : public QQuickPopup +{ + Q_OBJECT + Q_PROPERTY(Qt::Edge edge READ edge WRITE setEdge NOTIFY edgeChanged FINAL) + Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged FINAL) + Q_PROPERTY(qreal dragMargin READ dragMargin WRITE setDragMargin RESET resetDragMargin NOTIFY dragMarginChanged FINAL) + // 2.2 (Qt 5.9) + Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive NOTIFY interactiveChanged FINAL REVISION(2, 2)) + QML_NAMED_ELEMENT(Drawer) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickDrawer(QObject *parent = nullptr); + + Qt::Edge edge() const; + void setEdge(Qt::Edge edge); + + qreal position() const; + void setPosition(qreal position); + + qreal dragMargin() const; + void setDragMargin(qreal margin); + void resetDragMargin(); + + // 2.2 (Qt 5.9) + bool isInteractive() const; + void setInteractive(bool interactive); + +Q_SIGNALS: + void edgeChanged(); + void positionChanged(); + void dragMarginChanged(); + // 2.2 (Qt 5.9) + Q_REVISION(2, 2) void interactiveChanged(); + +protected: + bool childMouseEventFilter(QQuickItem *child, QEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + bool overlayEvent(QQuickItem *item, QEvent *event) override; +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif + + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + +private: + Q_DISABLE_COPY(QQuickDrawer) + Q_DECLARE_PRIVATE(QQuickDrawer) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickDrawer) + +#endif // QQUICKDRAWER_P_H diff --git a/src/quicktemplates2/qquickdrawer_p_p.h b/src/quicktemplates2/qquickdrawer_p_p.h new file mode 100644 index 00000000000..5f1086de975 --- /dev/null +++ b/src/quicktemplates2/qquickdrawer_p_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKDRAWER_P_P_H +#define QQUICKDRAWER_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickdrawer_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p_p.h> +#include <QtQuickTemplates2/private/qquickvelocitycalculator_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickDrawerPrivate : public QQuickPopupPrivate +{ + Q_DECLARE_PUBLIC(QQuickDrawer) + +public: + static QQuickDrawerPrivate *get(QQuickDrawer *drawer) + { + return drawer->d_func(); + } + + qreal offsetAt(const QPointF &point) const; + qreal positionAt(const QPointF &point) const; + + QQuickPopupPositioner *getPositioner() override; + void showOverlay() override; + void hideOverlay() override; + void resizeOverlay() override; + + bool startDrag(QEvent *event); + bool grabMouse(QQuickItem *item, QMouseEvent *event); +#if QT_CONFIG(quicktemplates2_multitouch) + bool grabTouch(QQuickItem *item, QTouchEvent *event); +#endif + bool blockInput(QQuickItem *item, const QPointF &point) const override; + + bool handlePress(QQuickItem* item, const QPointF &point, ulong timestamp) override; + bool handleMove(QQuickItem* item, const QPointF &point, ulong timestamp) override; + bool handleRelease(QQuickItem* item, const QPointF &point, ulong timestamp) override; + void handleUngrab() override; + + bool prepareEnterTransition() override; + bool prepareExitTransition() override; + + bool setEdge(Qt::Edge edge); + + Qt::Edge edge = Qt::LeftEdge; + qreal offset = 0; + qreal position = 0; + qreal dragMargin = 0; + QQuickVelocityCalculator velocityCalculator; +}; + +QT_END_NAMESPACE + +#endif // QQUICKDRAWER_P_P_H diff --git a/src/quicktemplates2/qquickframe.cpp b/src/quicktemplates2/qquickframe.cpp new file mode 100644 index 00000000000..8110e048e46 --- /dev/null +++ b/src/quicktemplates2/qquickframe.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickframe_p.h" +#include "qquickframe_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Frame + \inherits Pane +//! \instantiates QQuickFrame + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-containers + \brief Visual frame for a logical group of controls. + + Frame is used to layout a logical group of controls together within a + visual frame. Frame does not provide a layout of its own, but requires + you to position its contents, for instance by creating a \l RowLayout + or a \l ColumnLayout. + + Items declared as children of a Frame are automatically parented to the + Frame's \l {Control::}{contentItem}. Items created dynamically need to be + explicitly parented to the contentItem. + + If only a single item is used within a Frame, it will resize to fit the + implicit size of its contained item. This makes it particularly suitable + for use together with layouts. + + \image qtquickcontrols2-frame.png + + \snippet qtquickcontrols2-frame.qml 1 + + \sa {Customizing Frame}, {Container Controls} +*/ + +QQuickFrame::QQuickFrame(QQuickItem *parent) + : QQuickPane(*(new QQuickFramePrivate), parent) +{ +} + +QQuickFrame::QQuickFrame(QQuickFramePrivate &dd, QQuickItem *parent) + : QQuickPane(dd, parent) +{ +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickFrame::accessibleRole() const +{ + return QAccessible::Border; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickframe_p.cpp" diff --git a/src/quicktemplates2/qquickframe_p.h b/src/quicktemplates2/qquickframe_p.h new file mode 100644 index 00000000000..f65e2814060 --- /dev/null +++ b/src/quicktemplates2/qquickframe_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFRAME_P_H +#define QQUICKFRAME_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickpane_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickFramePrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickFrame : public QQuickPane +{ + Q_OBJECT + QML_NAMED_ELEMENT(Frame) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickFrame(QQuickItem *parent = nullptr); + +protected: + QQuickFrame(QQuickFramePrivate &dd, QQuickItem *parent); + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickFrame) + Q_DECLARE_PRIVATE(QQuickFrame) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFrame) + +#endif // QQUICKFRAME_P_H diff --git a/src/quicktemplates2/qquickframe_p_p.h b/src/quicktemplates2/qquickframe_p_p.h new file mode 100644 index 00000000000..ad392dc3a76 --- /dev/null +++ b/src/quicktemplates2/qquickframe_p_p.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFRAME_P_P_H +#define QQUICKFRAME_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickpane_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickFrame; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickFramePrivate : public QQuickPanePrivate +{ +}; + +QT_END_NAMESPACE + +#endif // QQUICKFRAME_P_P_H diff --git a/src/quicktemplates2/qquickgroupbox.cpp b/src/quicktemplates2/qquickgroupbox.cpp new file mode 100644 index 00000000000..3962e2e700b --- /dev/null +++ b/src/quicktemplates2/qquickgroupbox.cpp @@ -0,0 +1,289 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickgroupbox_p.h" +#include "qquickframe_p_p.h" +#include "qquickdeferredexecute_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype GroupBox + \inherits Frame +//! \instantiates QQuickGroupBox + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-containers + \brief Visual frame and title for a logical group of controls. + + GroupBox is used to layout a logical group of controls together, within + a \l {title}{titled} visual frame. GroupBox does not provide a layout of its own, but + requires you to position its contents, for instance by creating a \l RowLayout + or a \l ColumnLayout. + + Items declared as children of a GroupBox are automatically parented to the + GroupBox's \l {Control::}{contentItem}. Items created dynamically need to be + explicitly parented to the contentItem. + + If only a single item is used within a GroupBox, it will resize to fit the + implicit size of its contained item. This makes it particularly suitable + for use together with layouts. + + \image qtquickcontrols2-groupbox.png + + \snippet qtquickcontrols2-groupbox.qml 1 + + \section2 Checkable GroupBox + + Even though GroupBox has no built-in check box, it is straightforward + to create a checkable GroupBox by pairing it with a CheckBox. + + \image qtquickcontrols2-groupbox-checkable.png + + It is a common pattern to enable or disable the groupbox's children when + its checkbox is toggled on or off, but it is up to the application to decide + on the behavior of the checkbox. + + \snippet qtquickcontrols2-groupbox-checkable.qml 1 + + \sa CheckBox, {Customizing GroupBox}, {Container Controls} +*/ + +class QQuickGroupBoxPrivate : public QQuickFramePrivate +{ + Q_DECLARE_PUBLIC(QQuickGroupBox) + +public: + void cancelLabel(); + void executeLabel(bool complete = false); + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::GroupBox); } + + QString title; + QQuickDeferredPointer<QQuickItem> label; +}; + +static inline QString labelName() { return QStringLiteral("label"); } + +void QQuickGroupBoxPrivate::cancelLabel() +{ + Q_Q(QQuickGroupBox); + quickCancelDeferred(q, labelName()); +} + +void QQuickGroupBoxPrivate::executeLabel(bool complete) +{ + Q_Q(QQuickGroupBox); + if (label.wasExecuted()) + return; + + if (!label || complete) + quickBeginDeferred(q, labelName(), label); + if (complete) + quickCompleteDeferred(q, labelName(), label); +} + +void QQuickGroupBoxPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickGroupBox); + QQuickFramePrivate::itemImplicitWidthChanged(item); + if (item == label) + emit q->implicitLabelWidthChanged(); +} + +void QQuickGroupBoxPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickGroupBox); + QQuickFramePrivate::itemImplicitHeightChanged(item); + if (item == label) + emit q->implicitLabelHeightChanged(); +} + +QQuickGroupBox::QQuickGroupBox(QQuickItem *parent) + : QQuickFrame(*(new QQuickGroupBoxPrivate), parent) +{ +} + +QQuickGroupBox::~QQuickGroupBox() +{ + Q_D(QQuickGroupBox); + d->removeImplicitSizeListener(d->label); +} + +/*! + \qmlproperty string QtQuick.Controls::GroupBox::title + + This property holds the title. + + The title is typically displayed above the groupbox to + summarize its contents. +*/ +QString QQuickGroupBox::title() const +{ + Q_D(const QQuickGroupBox); + return d->title; +} + +void QQuickGroupBox::setTitle(const QString &title) +{ + Q_D(QQuickGroupBox); + if (d->title == title) + return; + + d->title = title; + maybeSetAccessibleName(title); + emit titleChanged(); +} + +/*! + \qmlproperty Item QtQuick.Controls::GroupBox::label + + This property holds the label item that visualizes \l title. + + \sa {Customizing GroupBox} +*/ +QQuickItem *QQuickGroupBox::label() const +{ + QQuickGroupBoxPrivate *d = const_cast<QQuickGroupBoxPrivate *>(d_func()); + if (!d->label) + d->executeLabel(); + return d->label; +} + +void QQuickGroupBox::setLabel(QQuickItem *label) +{ + Q_D(QQuickGroupBox); + if (d->label == label) + return; + + if (!d->label.isExecuting()) + d->cancelLabel(); + + const qreal oldImplicitLabelWidth = implicitLabelWidth(); + const qreal oldImplicitLabelHeight = implicitLabelHeight(); + + d->removeImplicitSizeListener(d->label); + QQuickControlPrivate::hideOldItem(d->label); + d->label = label; + + if (label) { + if (!label->parentItem()) + label->setParentItem(this); + d->addImplicitSizeListener(label); + } + + if (!qFuzzyCompare(oldImplicitLabelWidth, implicitLabelWidth())) + emit implicitLabelWidthChanged(); + if (!qFuzzyCompare(oldImplicitLabelHeight, implicitLabelHeight())) + emit implicitLabelHeightChanged(); + if (!d->label.isExecuting()) + emit labelChanged(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::GroupBox::implicitLabelWidth + \readonly + + This property holds the implicit label width. + + The value is equal to \c {label ? label.implicitWidth : 0}. + + \sa implicitLabelHeight +*/ +qreal QQuickGroupBox::implicitLabelWidth() const +{ + Q_D(const QQuickGroupBox); + if (!d->label) + return 0; + return d->label->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::GroupBox::implicitLabelHeight + \readonly + + This property holds the implicit label height. + + The value is equal to \c {label ? label.implicitHeight : 0}. + + \sa implicitLabelWidth +*/ +qreal QQuickGroupBox::implicitLabelHeight() const +{ + Q_D(const QQuickGroupBox); + if (!d->label) + return 0; + return d->label->implicitHeight(); +} + +void QQuickGroupBox::componentComplete() +{ + Q_D(QQuickGroupBox); + d->executeLabel(true); + QQuickFrame::componentComplete(); +} + +QFont QQuickGroupBox::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::GroupBox); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickGroupBox::accessibleRole() const +{ + return QAccessible::Grouping; +} + +void QQuickGroupBox::accessibilityActiveChanged(bool active) +{ + Q_D(QQuickGroupBox); + QQuickFrame::accessibilityActiveChanged(active); + + if (active) + maybeSetAccessibleName(d->title); +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickgroupbox_p.cpp" diff --git a/src/quicktemplates2/qquickgroupbox_p.h b/src/quicktemplates2/qquickgroupbox_p.h new file mode 100644 index 00000000000..39e20494e9b --- /dev/null +++ b/src/quicktemplates2/qquickgroupbox_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKGROUPBOX_P_H +#define QQUICKGROUPBOX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickframe_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickGroupBoxPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickGroupBox : public QQuickFrame +{ + Q_OBJECT + Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL) + Q_PROPERTY(QQuickItem *label READ label WRITE setLabel NOTIFY labelChanged FINAL) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitLabelWidth READ implicitLabelWidth NOTIFY implicitLabelWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitLabelHeight READ implicitLabelHeight NOTIFY implicitLabelHeightChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,label") + QML_NAMED_ELEMENT(GroupBox) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickGroupBox(QQuickItem *parent = nullptr); + ~QQuickGroupBox(); + + QString title() const; + void setTitle(const QString &title); + + QQuickItem *label() const; + void setLabel(QQuickItem *label); + + // 2.5 (Qt 5.12) + qreal implicitLabelWidth() const; + qreal implicitLabelHeight() const; + +Q_SIGNALS: + void titleChanged(); + void labelChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void implicitLabelWidthChanged(); + Q_REVISION(2, 5) void implicitLabelHeightChanged(); + +protected: + void componentComplete() override; + + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; + void accessibilityActiveChanged(bool active) override; +#endif + +private: + Q_DISABLE_COPY(QQuickGroupBox) + Q_DECLARE_PRIVATE(QQuickGroupBox) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickGroupBox) + +#endif // QQUICKGROUPBOX_P_H diff --git a/src/quicktemplates2/qquickheaderview.cpp b/src/quicktemplates2/qquickheaderview.cpp new file mode 100644 index 00000000000..298dbfbc05d --- /dev/null +++ b/src/quicktemplates2/qquickheaderview.cpp @@ -0,0 +1,450 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module 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 <QtQuickTemplates2/private/qquickheaderview_p_p.h> +#include <algorithm> + +/*! + \qmltype HorizontalHeaderView + \inqmlmodule QtQuick.Controls + \ingroup qtquickcontrols2-containers + \inherits TableView + \brief Provides a horizontal header view to accompany a \l TableView. + + \include qquickheaderview.qdocinc {detailed-description} {HorizontalHeaderView} + + \sa VerticalHeaderView +*/ + +/*! + \qmltype VerticalHeaderView + \inqmlmodule QtQuick.Controls + \ingroup qtquickcontrols2-containers + \inherits TableView + \brief Provides a vertical header view to accompany a \l TableView. + + \include qquickheaderview.qdocinc {detailed-description} {VerticalHeaderView} + + \sa HorizontalHeaderView +*/ + +/*! + \qmlproperty TableView QtQuick::HorizontalHeaderView::syncView + + \include qquickheaderview.qdocinc {syncView} {horizontally} +*/ + +/*! + \qmlproperty TableView QtQuick::VerticalHeaderView::syncView + + \include qquickheaderview.qdocinc {syncView} {vertically} +*/ + +/*! + \qmlproperty QVariant QtQuick::HorizontalHeaderView::model + + \include qquickheaderview.qdocinc {model} {horizontal} +*/ + +/*! + \qmlproperty QVariant QtQuick::VerticalHeaderView::model + + \include qquickheaderview.qdocinc {model} {vertical} +*/ + +/*! + \qmlproperty QString QtQuick::HorizontalHeaderView::textRole + + \include qquickheaderview.qdocinc {textRole} +*/ + +/*! + \qmlproperty QString QtQuick::VerticalHeaderView::textRole + + \include qquickheaderview.qdocinc {textRole} +*/ + +QT_BEGIN_NAMESPACE + +QQuickHeaderViewBasePrivate::QQuickHeaderViewBasePrivate() + : QQuickTableViewPrivate() +{ +} + +QQuickHeaderViewBasePrivate::~QQuickHeaderViewBasePrivate() +{ +} + +const QPointer<QQuickItem> QQuickHeaderViewBasePrivate::delegateItemAt(int row, int col) const +{ + return loadedTableItem(QPoint(col, row))->item; +} + +QVariant QQuickHeaderViewBasePrivate::modelImpl() const +{ + if (auto model = m_headerDataProxyModel.sourceModel()) + return QVariant::fromValue(model.data()); + if (auto model = m_transposeProxyModel.sourceModel()) + return QVariant::fromValue(model); + return QQuickTableViewPrivate::modelImpl(); +} + +template <typename P, typename M> +inline bool proxyModelSetter(QQuickHeaderViewBase *const q, P &proxyModel, M *model) +{ + if (model) { + if (model == proxyModel.sourceModel()) + return true; + proxyModel.setSourceModel(model); + const auto &modelVariant = QVariant::fromValue(std::addressof(proxyModel)); + bool isProxyModelChanged = (modelVariant != QQuickTableViewPrivate::get(q)->QQuickTableViewPrivate::modelImpl()); + QQuickTableViewPrivate::get(q)->QQuickTableViewPrivate::setModelImpl(modelVariant); + //Necessary, since TableView's assigned model not changed, but proxy's source changed + if (!isProxyModelChanged) + emit q->modelChanged(); + return true; + } + proxyModel.setSourceModel(nullptr); + return false; +} + +void QQuickHeaderViewBasePrivate::setModelImpl(const QVariant &newModel) +{ + Q_Q(QQuickHeaderViewBase); + m_modelExplicitlySetByUser = true; + // Case 1: newModel is QAbstractTableModel + if (proxyModelSetter(q, m_headerDataProxyModel, newModel.value<QAbstractTableModel *>())) + return; + // Case 2: newModel is QAbstractItemModel but not QAbstractTableModel + if (orientation() == Qt::Horizontal + && proxyModelSetter(q, m_transposeProxyModel, newModel.value<QAbstractItemModel *>())) + return; + + QQuickTableViewPrivate::setModelImpl(newModel); +} + +void QQuickHeaderViewBasePrivate::syncModel() +{ + Q_Q(QQuickHeaderViewBase); + + if (assignedSyncView && !m_modelExplicitlySetByUser) { + auto newModel = assignedSyncView->model(); + if (auto m = newModel.value<QAbstractItemModel *>()) + proxyModelSetter(q, m_headerDataProxyModel, m); + } + + QQuickTableViewPrivate::syncModel(); + + isTransposed = false; + const auto aim = model->abstractItemModel(); + if (orientation() == Qt::Horizontal) { + // For models that are just a list or a number, and especially not a + // table, we transpose the view when the orientation is horizontal. + // The model (list) will then be laid out horizontally rather than + // vertically, which is the otherwise the default. + isTransposed = !aim || aim->columnCount() == 1; + } + if (m_textRole.isEmpty() && aim) + m_textRole = QLatin1String("display"); +} + +void QQuickHeaderViewBasePrivate::syncSyncView() +{ + Q_Q(QQuickHeaderViewBase); + if (assignedSyncDirection != orientation()) { + qmlWarning(q_func()) << "Setting syncDirection other than Qt::" + << QVariant::fromValue(orientation()).toString() + << " is invalid."; + assignedSyncDirection = orientation(); + } + if (assignedSyncView) { + QBoolBlocker fixupGuard(inUpdateContentSize, true); + if (orientation() == Qt::Horizontal) { + q->setLeftMargin(assignedSyncView->leftMargin()); + q->setRightMargin(assignedSyncView->rightMargin()); + } else { + q->setTopMargin(assignedSyncView->topMargin()); + q->setBottomMargin(assignedSyncView->bottomMargin()); + } + } + QQuickTableViewPrivate::syncSyncView(); +} + +QQuickHeaderViewBase::QQuickHeaderViewBase(Qt::Orientation orient, QQuickItem *parent) + : QQuickTableView(*(new QQuickHeaderViewBasePrivate), parent) +{ + d_func()->setOrientation(orient); + setSyncDirection(orient); +} + +QQuickHeaderViewBase::QQuickHeaderViewBase(QQuickHeaderViewBasePrivate &dd, QQuickItem *parent) + : QQuickTableView(dd, parent) +{ +} + +QQuickHeaderViewBase::~QQuickHeaderViewBase() +{ +} + +QString QQuickHeaderViewBase::textRole() const +{ + Q_D(const QQuickHeaderViewBase); + return d->m_textRole; +} + +void QQuickHeaderViewBase::setTextRole(const QString &role) +{ + Q_D(QQuickHeaderViewBase); + if (d->m_textRole == role) + return; + + d->m_textRole = role; + emit textRoleChanged(); +} + +Qt::Orientation QQuickHeaderViewBasePrivate::orientation() const +{ + return m_headerDataProxyModel.orientation(); +} + +void QQuickHeaderViewBasePrivate::setOrientation(Qt::Orientation orientation) +{ + if (QQuickHeaderViewBasePrivate::orientation() == orientation) + return; + m_headerDataProxyModel.setOrientation(orientation); +} + +QQuickVerticalHeaderView::QQuickVerticalHeaderView(QQuickVerticalHeaderViewPrivate &dd, QQuickItem *parent) + : QQuickHeaderViewBase(dd, parent) +{ +} + +/*! \internal + \class QHeaderDataProxyModel + \brief + QHeaderDataProxyModel is a proxy AbstractItemModel type that maps + source model's headerData() to correspondent data() + */ +QHeaderDataProxyModel::QHeaderDataProxyModel(QObject *parent) + : QAbstractItemModel(parent) +{ +} + +QHeaderDataProxyModel::~QHeaderDataProxyModel() = default; + +void QHeaderDataProxyModel::setSourceModel(QAbstractItemModel *newSourceModel) +{ + if (m_model == newSourceModel) + return; + beginResetModel(); + disconnectFromModel(); + m_model = newSourceModel; + connectToModel(); + endResetModel(); +} + +QModelIndex QHeaderDataProxyModel::index(int row, int column, const QModelIndex &parent) const +{ + return hasIndex(row, column, parent) ? createIndex(row, column) : QModelIndex(); +} + +QModelIndex QHeaderDataProxyModel::parent(const QModelIndex &child) const +{ + Q_UNUSED(child); + return QModelIndex(); +} + +QModelIndex QHeaderDataProxyModel::sibling(int row, int column, const QModelIndex &) const +{ + return index(row, column); +} + +int QHeaderDataProxyModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + return m_model.isNull() ? -1 : (m_orientation == Qt::Horizontal ? 1 : m_model->rowCount(parent)); +} + +int QHeaderDataProxyModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + return m_model.isNull() ? -1 : (m_orientation == Qt::Vertical ? 1 : m_model->columnCount(parent)); +} + +QVariant QHeaderDataProxyModel::data(const QModelIndex &index, int role) const +{ + if (m_model.isNull()) + return QVariant(); + if (!hasIndex(index.row(), index.column())) + return QModelIndex(); + auto section = m_orientation == Qt::Vertical ? index.row() : index.column(); + return m_model->headerData(section, m_orientation, role); +} + +bool QHeaderDataProxyModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!hasIndex(index.row(), index.column())) + return false; + auto section = m_orientation == Qt::Vertical ? index.row() : index.column(); + auto ret = m_model->setHeaderData(section, m_orientation, value, role); + emit dataChanged(index, index, { role }); + return ret; +} + +bool QHeaderDataProxyModel::hasChildren(const QModelIndex &parent) const +{ + if (!parent.isValid()) + return rowCount(parent) > 0 && columnCount(parent) > 0; + return false; +} + +QVariant QHeaderDataProxyModel::variantValue() const +{ + return QVariant::fromValue(static_cast<QObject *>(const_cast<QHeaderDataProxyModel *>(this))); +} + +void QHeaderDataProxyModel::setOrientation(Qt::Orientation o) +{ + if (o == m_orientation) + return; + beginResetModel(); + m_orientation = o; + endResetModel(); +} + +Qt::Orientation QHeaderDataProxyModel::orientation() const +{ + return m_orientation; +} + +QPointer<QAbstractItemModel> QHeaderDataProxyModel::sourceModel() const +{ + return m_model; +} + +void QHeaderDataProxyModel::connectToModel() +{ + if (m_model.isNull()) + return; + connect(m_model, &QAbstractItemModel::headerDataChanged, + this, [this](Qt::Orientation orient, int first, int last) { + if (orient != orientation()) + return; + if (orient == Qt::Horizontal) { + emit dataChanged(createIndex(0, first), createIndex(0, last)); + } else { + emit dataChanged(createIndex(first, 0), createIndex(last, 0)); + } + }); + connect(m_model, &QAbstractItemModel::modelAboutToBeReset, + this, &QHeaderDataProxyModel::modelAboutToBeReset, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::modelReset, + this, &QHeaderDataProxyModel::modelReset, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::rowsAboutToBeMoved, + this, &QHeaderDataProxyModel::rowsAboutToBeMoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::rowsMoved, + this, &QHeaderDataProxyModel::rowsMoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, + this, &QHeaderDataProxyModel::rowsAboutToBeInserted, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::rowsInserted, + this, &QHeaderDataProxyModel::rowsInserted, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::rowsAboutToBeRemoved, + this, &QHeaderDataProxyModel::rowsAboutToBeRemoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::rowsRemoved, + this, &QHeaderDataProxyModel::rowsRemoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::columnsAboutToBeMoved, + this, &QHeaderDataProxyModel::columnsAboutToBeMoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::columnsMoved, + this, &QHeaderDataProxyModel::columnsMoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::columnsAboutToBeInserted, + this, &QHeaderDataProxyModel::columnsAboutToBeInserted, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::columnsInserted, + this, &QHeaderDataProxyModel::columnsInserted, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::columnsAboutToBeRemoved, + this, &QHeaderDataProxyModel::columnsAboutToBeRemoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::columnsRemoved, + this, &QHeaderDataProxyModel::columnsRemoved, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::layoutAboutToBeChanged, + this, &QHeaderDataProxyModel::layoutAboutToBeChanged, Qt::UniqueConnection); + connect(m_model, &QAbstractItemModel::layoutChanged, + this, &QHeaderDataProxyModel::layoutChanged, Qt::UniqueConnection); +} + +void QHeaderDataProxyModel::disconnectFromModel() +{ + if (m_model.isNull()) + return; + m_model->disconnect(this); +} + +QQuickHorizontalHeaderView::QQuickHorizontalHeaderView(QQuickItem *parent) + : QQuickHeaderViewBase(Qt::Horizontal, parent) +{ + setFlickableDirection(FlickableDirection::HorizontalFlick); +} + +QQuickHorizontalHeaderView::~QQuickHorizontalHeaderView() +{ +} + +QQuickVerticalHeaderView::QQuickVerticalHeaderView(QQuickItem *parent) + : QQuickHeaderViewBase(Qt::Vertical, parent) +{ + setFlickableDirection(FlickableDirection::VerticalFlick); +} + +QQuickVerticalHeaderView::~QQuickVerticalHeaderView() +{ +} + +QQuickHorizontalHeaderViewPrivate::QQuickHorizontalHeaderViewPrivate() = default; + +QQuickHorizontalHeaderViewPrivate::~QQuickHorizontalHeaderViewPrivate() = default; + +QQuickVerticalHeaderViewPrivate::QQuickVerticalHeaderViewPrivate() = default; + +QQuickVerticalHeaderViewPrivate::~QQuickVerticalHeaderViewPrivate() = default; + +QT_END_NAMESPACE + +#include "moc_qquickheaderview_p_p.cpp" + +#include "moc_qquickheaderview_p.cpp" diff --git a/src/quicktemplates2/qquickheaderview_p.h b/src/quicktemplates2/qquickheaderview_p.h new file mode 100644 index 00000000000..b8e8b77aa7f --- /dev/null +++ b/src/quicktemplates2/qquickheaderview_p.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module 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 QQUICKHEADERVIEW_P_H +#define QQUICKHEADERVIEW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qquicktableview_p.h> +#include <private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickHeaderViewBase; +class QQuickHeaderViewBasePrivate; +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickHeaderViewBase : public QQuickTableView +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QQuickHeaderViewBase) + Q_PROPERTY(QString textRole READ textRole WRITE setTextRole NOTIFY textRoleChanged FINAL) + +public: + explicit QQuickHeaderViewBase(Qt::Orientation orient, QQuickItem *parent = nullptr); + ~QQuickHeaderViewBase(); + + QString textRole() const; + void setTextRole(const QString &role); + +protected: + QQuickHeaderViewBase(QQuickHeaderViewBasePrivate &dd, QQuickItem *parent); + +Q_SIGNALS: + void textRoleChanged(); + +private: + Q_DISABLE_COPY(QQuickHeaderViewBase) + friend class QQuickHorizontalHeaderView; + friend class QQuickVerticalHeaderView; +}; + +class QQuickHorizontalHeaderViewPrivate; +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickHorizontalHeaderView : public QQuickHeaderViewBase +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QQuickHorizontalHeaderView) + QML_NAMED_ELEMENT(HorizontalHeaderView) + QML_ADDED_IN_VERSION(2, 15) + +public: + QQuickHorizontalHeaderView(QQuickItem *parent = nullptr); + ~QQuickHorizontalHeaderView() override; + +protected: + QQuickHorizontalHeaderView(QQuickHorizontalHeaderViewPrivate &dd, QQuickItem *parent); + +private: + Q_DISABLE_COPY(QQuickHorizontalHeaderView) +}; + +class QQuickVerticalHeaderViewPrivate; +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickVerticalHeaderView : public QQuickHeaderViewBase +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QQuickVerticalHeaderView) + QML_NAMED_ELEMENT(VerticalHeaderView) + QML_ADDED_IN_VERSION(2, 15) + +public: + QQuickVerticalHeaderView(QQuickItem *parent = nullptr); + ~QQuickVerticalHeaderView() override; + +protected: + QQuickVerticalHeaderView(QQuickVerticalHeaderViewPrivate &dd, QQuickItem *parent); + +private: + Q_DISABLE_COPY(QQuickVerticalHeaderView) +}; + +struct QQuickTableViewForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickTableView) + QML_ADDED_IN_VERSION(2, 14) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickHorizontalHeaderView) +QML_DECLARE_TYPE(QQuickVerticalHeaderView) + +#endif // QQUICKHEADERVIEW_P_H diff --git a/src/quicktemplates2/qquickheaderview_p_p.h b/src/quicktemplates2/qquickheaderview_p_p.h new file mode 100644 index 00000000000..655c2a58e6b --- /dev/null +++ b/src/quicktemplates2/qquickheaderview_p_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKHEADERVIEW_P_P_H +#define QQUICKHEADERVIEW_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QAbstractItemModel> +#include <QtCore/QPointer> +#include <QtCore/QTransposeProxyModel> +#include <QtQuick/private/qquicktableview_p_p.h> +#include <private/qquickheaderview_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QHeaderDataProxyModel : public QAbstractItemModel +{ + Q_OBJECT + Q_DISABLE_COPY(QHeaderDataProxyModel) + Q_PROPERTY(QAbstractItemModel *sourceModel READ sourceModel) +public: + explicit QHeaderDataProxyModel(QObject *parent = nullptr); + ~QHeaderDataProxyModel(); + + void setSourceModel(QAbstractItemModel *newSourceModel); + QPointer<QAbstractItemModel> sourceModel() const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &child) const override; + QModelIndex sibling(int row, int column, const QModelIndex &idx) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; + + inline QVariant variantValue() const; + inline Qt::Orientation orientation() const; + inline void setOrientation(Qt::Orientation o); + +private: + inline void connectToModel(); + inline void disconnectFromModel(); + QPointer<QAbstractItemModel> m_model = nullptr; + Qt::Orientation m_orientation = Qt::Horizontal; +}; + +class QQuickHeaderViewBasePrivate : public QQuickTableViewPrivate +{ + Q_DECLARE_PUBLIC(QQuickHeaderViewBase) +public: + QQuickHeaderViewBasePrivate(); + ~QQuickHeaderViewBasePrivate(); + + Qt::Orientation orientation() const; + void setOrientation(Qt::Orientation orientation); + const QPointer<QQuickItem> delegateItemAt(int row, int col) const; + QVariant modelImpl() const override; + void setModelImpl(const QVariant &newModel) override; + void syncModel() override; + void syncSyncView() override; + +protected: + QHeaderDataProxyModel m_headerDataProxyModel; + QTransposeProxyModel m_transposeProxyModel; + struct SectionSize + { + int section; + qreal previousSize; + }; + QStack<SectionSize> m_hiddenSectionSizes; + bool m_modelExplicitlySetByUser = false; + QString m_textRole; +}; + +class QQuickHorizontalHeaderViewPrivate : public QQuickHeaderViewBasePrivate +{ + Q_DECLARE_PUBLIC(QQuickHorizontalHeaderView) +public: + QQuickHorizontalHeaderViewPrivate(); + ~QQuickHorizontalHeaderViewPrivate(); +}; + +class QQuickVerticalHeaderViewPrivate : public QQuickHeaderViewBasePrivate +{ + Q_DECLARE_PUBLIC(QQuickVerticalHeaderView) +public: + QQuickVerticalHeaderViewPrivate(); + ~QQuickVerticalHeaderViewPrivate(); +}; + +QT_END_NAMESPACE + +#endif // QQUICKHEADERVIEW_P_P_H diff --git a/src/quicktemplates2/qquickicon.cpp b/src/quicktemplates2/qquickicon.cpp new file mode 100644 index 00000000000..88d957f40da --- /dev/null +++ b/src/quicktemplates2/qquickicon.cpp @@ -0,0 +1,311 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickicon_p.h" +#include "qtaggedpointer.h" + +#include <private/qqmlcontextdata_p.h> +#include <private/qqmldata_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickIconPrivate : public QSharedData +{ +public: + // This is based on QFont's resolve_mask. + enum ResolveProperties { + NameResolved = 0x0001, + SourceResolved = 0x0002, + WidthResolved = 0x0004, + HeightResolved = 0x0008, + ColorResolved = 0x0010, + CacheResolved = 0x0020, + AllPropertiesResolved = 0x1ffff + }; + int resolveMask = 0; + + QString name; + QUrl source; + QUrl resolvedSource; + int width = 0; + int height = 0; + QColor color = Qt::transparent; + + // we want DoCache as the default, and thus as the zero value + // so that the tagged pointer can be zero initialized + enum CacheStatus : bool { DoCache, SkipCaching }; + static_assert (DoCache == 0); + /* We use a QTaggedPointer here to save space: + - Without it, we would need an additional boolean, which due to + alignment would increase the class size by sizeof(void *) + - The pointer part stores the "owner" of the QQuickIcon, i.e. + an object which has an icon property. We need the owner to + access its context to resolve relative url's in the way users + expect. + - The tag bits are used to track whether caching is enabled. + */ + QTaggedPointer<QObject, CacheStatus> ownerAndCache = nullptr; + +}; + +QQuickIcon::QQuickIcon() + : d(new QQuickIconPrivate) +{ +} + +QQuickIcon::QQuickIcon(const QQuickIcon &other) + : d(other.d) +{ +} + +QQuickIcon::~QQuickIcon() +{ +} + +QQuickIcon &QQuickIcon::operator=(const QQuickIcon &other) +{ + d = other.d; + return *this; +} + +bool QQuickIcon::operator==(const QQuickIcon &other) const +{ + return d == other.d || (d->name == other.d->name + && d->source == other.d->source + && d->resolvedSource == other.d->resolvedSource + && d->width == other.d->width + && d->height == other.d->height + && d->color == other.d->color + && d->ownerAndCache == other.d->ownerAndCache); +} + +bool QQuickIcon::operator!=(const QQuickIcon &other) const +{ + return !(*this == other); +} + +bool QQuickIcon::isEmpty() const +{ + return d->name.isEmpty() && d->source.isEmpty(); +} + +QString QQuickIcon::name() const +{ + return d->name; +} + +void QQuickIcon::setName(const QString &name) +{ + if ((d->resolveMask & QQuickIconPrivate::NameResolved) && d->name == name) + return; + + d.detach(); + d->name = name; + d->resolveMask |= QQuickIconPrivate::NameResolved; +} + +void QQuickIcon::resetName() +{ + d.detach(); + d->name = QString(); + d->resolveMask &= ~QQuickIconPrivate::NameResolved; +} + +QUrl QQuickIcon::source() const +{ + return d->source; +} + +void QQuickIcon::setSource(const QUrl &source) +{ + if ((d->resolveMask & QQuickIconPrivate::SourceResolved) && d->source == source) + return; + + d.detach(); + d->source = source; + d->resolvedSource.clear(); + d->resolveMask |= QQuickIconPrivate::SourceResolved; +} + +void QQuickIcon::resetSource() +{ + d.detach(); + d->source = QString(); + d->resolvedSource.clear(); + d->resolveMask &= ~QQuickIconPrivate::SourceResolved; +} + +QUrl QQuickIcon::resolvedSource() const +{ + return d->resolvedSource.isEmpty() ? d->source : d->resolvedSource; +} + +// must be called by the property owner (e.g. Button) prior to emitting changed signal. +void QQuickIcon::ensureRelativeSourceResolved(const QObject *owner) +{ + if (d->source.isEmpty()) + return; + if (!d->resolvedSource.isEmpty()) + return; // already resolved relative to (possibly) different owner + const QQmlData *data = QQmlData::get(owner); + if (!data || !data->outerContext) + return; + d.detach(); + d->resolvedSource = data->outerContext->resolvedUrl(d->source); +} + +int QQuickIcon::width() const +{ + return d->width; +} + +void QQuickIcon::setWidth(int width) +{ + if ((d->resolveMask & QQuickIconPrivate::WidthResolved) && d->width == width) + return; + + d.detach(); + d->width = width; + d->resolveMask |= QQuickIconPrivate::WidthResolved; +} + +void QQuickIcon::resetWidth() +{ + d.detach(); + d->width = 0; + d->resolveMask &= ~QQuickIconPrivate::WidthResolved; +} + +int QQuickIcon::height() const +{ + return d->height; +} + +void QQuickIcon::setHeight(int height) +{ + if ((d->resolveMask & QQuickIconPrivate::HeightResolved) && d->height == height) + return; + + d.detach(); + d->height = height; + d->resolveMask |= QQuickIconPrivate::HeightResolved; +} + +void QQuickIcon::resetHeight() +{ + d.detach(); + d->height = 0; + d->resolveMask &= ~QQuickIconPrivate::HeightResolved; +} + +QColor QQuickIcon::color() const +{ + return d->color; +} + +void QQuickIcon::setColor(const QColor &color) +{ + if ((d->resolveMask & QQuickIconPrivate::ColorResolved) && d->color == color) + return; + + d.detach(); + d->color = color; + d->resolveMask |= QQuickIconPrivate::ColorResolved; +} + +void QQuickIcon::resetColor() +{ + d.detach(); + d->color = Qt::transparent; + d->resolveMask &= ~QQuickIconPrivate::ColorResolved; +} + +bool QQuickIcon::cache() const +{ + return d->ownerAndCache.tag() == QQuickIconPrivate::DoCache; +} + +void QQuickIcon::setCache(bool cache) +{ + const auto cacheState = cache ? QQuickIconPrivate::DoCache : QQuickIconPrivate::SkipCaching; + if ((d->resolveMask & QQuickIconPrivate::CacheResolved) && d->ownerAndCache.tag() == cacheState) + return; + + d.detach(); + d->ownerAndCache.setTag(cacheState); + d->resolveMask |= QQuickIconPrivate::CacheResolved; +} + +void QQuickIcon::resetCache() +{ + d.detach(); + d->ownerAndCache.setTag(QQuickIconPrivate::DoCache); + d->resolveMask &= ~QQuickIconPrivate::CacheResolved; +} + +QQuickIcon QQuickIcon::resolve(const QQuickIcon &other) const +{ + QQuickIcon resolved = *this; + resolved.d.detach(); + + if (!(d->resolveMask & QQuickIconPrivate::NameResolved)) + resolved.d->name = other.d->name; + + if (!(d->resolveMask & QQuickIconPrivate::SourceResolved)) { + resolved.d->source = other.d->source; + resolved.d->resolvedSource = other.d->resolvedSource; + } + + if (!(d->resolveMask & QQuickIconPrivate::WidthResolved)) + resolved.d->width = other.d->width; + + if (!(d->resolveMask & QQuickIconPrivate::HeightResolved)) + resolved.d->height = other.d->height; + + if (!(d->resolveMask & QQuickIconPrivate::ColorResolved)) + resolved.d->color = other.d->color; + + if (!(d->resolveMask & QQuickIconPrivate::CacheResolved)) + resolved.d->ownerAndCache.setTag(other.d->ownerAndCache.tag()); + + // owner does not change when resolving an icon + + return resolved; +} + +QT_END_NAMESPACE + +#include "moc_qquickicon_p.cpp" diff --git a/src/quicktemplates2/qquickicon_p.h b/src/quicktemplates2/qquickicon_p.h new file mode 100644 index 00000000000..03128124298 --- /dev/null +++ b/src/quicktemplates2/qquickicon_p.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKICON_P_H +#define QQUICKICON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qurl.h> +#include <QtCore/qstring.h> +#include <QtCore/qobjectdefs.h> +#include <QtCore/qshareddata.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> +#include <QtGui/qcolor.h> +#include <QtQml/qqml.h> + +QT_BEGIN_NAMESPACE + +class QQuickIconPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickIcon +{ + Q_GADGET + Q_PROPERTY(QString name READ name WRITE setName RESET resetName FINAL) + Q_PROPERTY(QUrl source READ source WRITE setSource RESET resetSource FINAL) + Q_PROPERTY(int width READ width WRITE setWidth RESET resetWidth FINAL) + Q_PROPERTY(int height READ height WRITE setHeight RESET resetHeight FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor RESET resetColor FINAL) + Q_PROPERTY(bool cache READ cache WRITE setCache RESET resetCache FINAL) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 3) + +public: + QQuickIcon(); + QQuickIcon(const QQuickIcon &other); + ~QQuickIcon(); + + QQuickIcon& operator=(const QQuickIcon &other); + bool operator==(const QQuickIcon &other) const; + bool operator!=(const QQuickIcon &other) const; + + bool isEmpty() const; + + QString name() const; + void setName(const QString &name); + void resetName(); + + QUrl source() const; + void setSource(const QUrl &source); + void resetSource(); + QUrl resolvedSource() const; + void ensureRelativeSourceResolved(const QObject *owner); + + int width() const; + void setWidth(int width); + void resetWidth(); + + int height() const; + void setHeight(int height); + void resetHeight(); + + QColor color() const; + void setColor(const QColor &color); + void resetColor(); + + bool cache() const; + void setCache(bool cache); + void resetCache(); + + QQuickIcon resolve(const QQuickIcon &other) const; + +private: + QExplicitlySharedDataPointer<QQuickIconPrivate> d; +}; + +QT_END_NAMESPACE + +#endif // QQUICKICON_P_H diff --git a/src/quicktemplates2/qquickindicatorbutton_p.cpp b/src/quicktemplates2/qquickindicatorbutton_p.cpp new file mode 100644 index 00000000000..016d89a4c61 --- /dev/null +++ b/src/quicktemplates2/qquickindicatorbutton_p.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qquickindicatorbutton_p.h" +#include "qquickdeferredexecute_p_p.h" +#include "qquickcontrol_p_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickIndicatorButton; + +static inline QString indicatorName() { return QStringLiteral("indicator"); } + +void QQuickIndicatorButtonPrivate::cancelIndicator() +{ + Q_Q(QQuickIndicatorButton); + quickCancelDeferred(q, indicatorName()); +} + +void QQuickIndicatorButtonPrivate::executeIndicator(bool complete) +{ + Q_Q(QQuickIndicatorButton); + if (indicator.wasExecuted()) + return; + + if (!indicator || complete) + quickBeginDeferred(q, indicatorName(), indicator); + if (complete) + quickCompleteDeferred(q, indicatorName(), indicator); +} + +QQuickIndicatorButton::QQuickIndicatorButton(QObject *parent) + : QObject(*(new QQuickIndicatorButtonPrivate), parent) +{ +} + +bool QQuickIndicatorButton::isPressed() const +{ + Q_D(const QQuickIndicatorButton); + return d->pressed; +} + +void QQuickIndicatorButton::setPressed(bool pressed) +{ + Q_D(QQuickIndicatorButton); + if (d->pressed == pressed) + return; + + d->pressed = pressed; + emit pressedChanged(); +} + +QQuickItem *QQuickIndicatorButton::indicator() const +{ + QQuickIndicatorButtonPrivate *d = const_cast<QQuickIndicatorButtonPrivate *>(d_func()); + if (!d->indicator) + d->executeIndicator(); + return d->indicator; +} + +void QQuickIndicatorButton::setIndicator(QQuickItem *indicator) +{ + Q_D(QQuickIndicatorButton); + if (d->indicator == indicator) + return; + + if (!d->indicator.isExecuting()) + d->cancelIndicator(); + + const qreal oldImplicitIndicatorWidth = implicitIndicatorWidth(); + const qreal oldImplicitIndicatorHeight = implicitIndicatorHeight(); + + QQuickControl *par = static_cast<QQuickControl *>(parent()); + + QQuickControlPrivate::get(par)->removeImplicitSizeListener(d->indicator); + QQuickControlPrivate::hideOldItem(d->indicator); + d->indicator = indicator; + + if (indicator) { + if (!indicator->parentItem()) + indicator->setParentItem(par); + QQuickControlPrivate::get(par)->addImplicitSizeListener(indicator); + } + + if (!qFuzzyCompare(oldImplicitIndicatorWidth, implicitIndicatorWidth())) + emit implicitIndicatorWidthChanged(); + if (!qFuzzyCompare(oldImplicitIndicatorHeight, implicitIndicatorHeight())) + emit implicitIndicatorHeightChanged(); + if (!d->indicator.isExecuting()) + emit indicatorChanged(); +} + +bool QQuickIndicatorButton::isHovered() const +{ + Q_D(const QQuickIndicatorButton); + return d->hovered; +} + +void QQuickIndicatorButton::setHovered(bool hovered) +{ + Q_D(QQuickIndicatorButton); + if (d->hovered == hovered) + return; + + d->hovered = hovered; + emit hoveredChanged(); +} + +qreal QQuickIndicatorButton::implicitIndicatorWidth() const +{ + Q_D(const QQuickIndicatorButton); + if (!d->indicator) + return 0; + return d->indicator->implicitWidth(); +} + +qreal QQuickIndicatorButton::implicitIndicatorHeight() const +{ + Q_D(const QQuickIndicatorButton); + if (!d->indicator) + return 0; + return d->indicator->implicitHeight(); +} + +QT_END_NAMESPACE + +#include "moc_qquickindicatorbutton_p.cpp" diff --git a/src/quicktemplates2/qquickindicatorbutton_p.h b/src/quicktemplates2/qquickindicatorbutton_p.h new file mode 100644 index 00000000000..44c5b0cfefd --- /dev/null +++ b/src/quicktemplates2/qquickindicatorbutton_p.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QQUICKINDICATORBUTTON_H +#define QQUICKINDICATORBUTTON_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQml/qjsvalue.h> +#include "qquickdeferredpointer_p_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickIndicatorButtonPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickIndicatorButton : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL) + Q_PROPERTY(QQuickItem *indicator READ indicator WRITE setIndicator NOTIFY indicatorChanged FINAL) + // 2.1 (Qt 5.8) + Q_PROPERTY(bool hovered READ isHovered WRITE setHovered NOTIFY hoveredChanged FINAL REVISION(2, 1)) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitIndicatorWidth READ implicitIndicatorWidth NOTIFY implicitIndicatorWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitIndicatorHeight READ implicitIndicatorHeight NOTIFY implicitIndicatorHeightChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DeferredPropertyNames", "indicator") + QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickIndicatorButton(QObject *parent); + + bool isPressed() const; + void setPressed(bool pressed); + + QQuickItem *indicator() const; + void setIndicator(QQuickItem *indicator); + + bool isHovered() const; + void setHovered(bool hovered); + + qreal implicitIndicatorWidth() const; + qreal implicitIndicatorHeight() const; + +Q_SIGNALS: + void pressedChanged(); + void indicatorChanged(); + // 2.1 (Qt 5.8) + Q_REVISION(2, 1) void hoveredChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void implicitIndicatorWidthChanged(); + Q_REVISION(2, 5) void implicitIndicatorHeightChanged(); + +private: + Q_DISABLE_COPY(QQuickIndicatorButton) + Q_DECLARE_PRIVATE(QQuickIndicatorButton) +}; + +class QQuickIndicatorButtonPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickIndicatorButton) + +public: + static QQuickIndicatorButtonPrivate *get(QQuickIndicatorButton *button) + { + return button->d_func(); + } + + void cancelIndicator(); + void executeIndicator(bool complete = false); + + bool pressed = false; + bool hovered = false; + QQuickDeferredPointer<QQuickItem> indicator; +}; + +QT_END_NAMESPACE + +#endif // QQUICKINDICATORBUTTON_H diff --git a/src/quicktemplates2/qquickitemdelegate.cpp b/src/quicktemplates2/qquickitemdelegate.cpp new file mode 100644 index 00000000000..466bd0c25e3 --- /dev/null +++ b/src/quicktemplates2/qquickitemdelegate.cpp @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickitemdelegate_p.h" +#include "qquickitemdelegate_p_p.h" +#include "qquickcontrol_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ItemDelegate + \inherits AbstractButton +//! \instantiates QQuickItemDelegate + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-delegates + \brief Basic item delegate that can be used in various views and controls. + + \image qtquickcontrols2-itemdelegate.gif + + ItemDelegate presents a standard view item. It can be used as a delegate + in various views and controls, such as \l ListView and \l ComboBox. + + ItemDelegate inherits its API from AbstractButton. For instance, you can set + \l {AbstractButton::text}{text}, display an \l {Icons in Qt Quick Controls}{icon}, + and react to \l {AbstractButton::clicked}{clicks} using the AbstractButton API. + + \snippet qtquickcontrols2-itemdelegate.qml 1 + + \sa {Customizing ItemDelegate}, {Delegate Controls} +*/ + +QQuickItemDelegate::QQuickItemDelegate(QQuickItem *parent) + : QQuickAbstractButton(*(new QQuickItemDelegatePrivate), parent) +{ + setFocusPolicy(Qt::NoFocus); +} + +QQuickItemDelegate::QQuickItemDelegate(QQuickItemDelegatePrivate &dd, QQuickItem *parent) + : QQuickAbstractButton(dd, parent) +{ + setFocusPolicy(Qt::NoFocus); +} + +/*! + \qmlproperty bool QtQuick.Controls::ItemDelegate::highlighted + + This property holds whether the delegate is highlighted. + + A delegate can be highlighted in order to draw the user's attention towards + it. It has no effect on keyboard interaction. For example, you can + highlight the current item in a ListView using the following code: + + \code + ListView { + id: listView + model: 10 + delegate: ItemDelegate { + text: modelData + highlighted: ListView.isCurrentItem + onClicked: listView.currentIndex = index + } + } + \endcode + + The default value is \c false. +*/ +bool QQuickItemDelegate::isHighlighted() const +{ + Q_D(const QQuickItemDelegate); + return d->highlighted; +} + +void QQuickItemDelegate::setHighlighted(bool highlighted) +{ + Q_D(QQuickItemDelegate); + if (highlighted == d->highlighted) + return; + + d->highlighted = highlighted; + emit highlightedChanged(); +} + +QFont QQuickItemDelegate::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::ItemView); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickItemDelegate::accessibleRole() const +{ + return QAccessible::ListItem; +} +#endif + +QPalette QQuickItemDelegatePrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::ItemView); +} + +QT_END_NAMESPACE + +#include "moc_qquickitemdelegate_p.cpp" diff --git a/src/quicktemplates2/qquickitemdelegate_p.h b/src/quicktemplates2/qquickitemdelegate_p.h new file mode 100644 index 00000000000..2568a0bf913 --- /dev/null +++ b/src/quicktemplates2/qquickitemdelegate_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKITEMDELEGATE_P_H +#define QQUICKITEMDELEGATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickItemDelegatePrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickItemDelegate : public QQuickAbstractButton +{ + Q_OBJECT + Q_PROPERTY(bool highlighted READ isHighlighted WRITE setHighlighted NOTIFY highlightedChanged FINAL) + QML_NAMED_ELEMENT(ItemDelegate) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickItemDelegate(QQuickItem *parent = nullptr); + + bool isHighlighted() const; + void setHighlighted(bool highlighted); + +Q_SIGNALS: + void highlightedChanged(); + +protected: + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +protected: + QQuickItemDelegate(QQuickItemDelegatePrivate &dd, QQuickItem *parent); + +private: + Q_DISABLE_COPY(QQuickItemDelegate) + Q_DECLARE_PRIVATE(QQuickItemDelegate) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickItemDelegate) + +#endif // QQUICKITEMDELEGATE_P_H diff --git a/src/quicktemplates2/qquickitemdelegate_p_p.h b/src/quicktemplates2/qquickitemdelegate_p_p.h new file mode 100644 index 00000000000..d7604fbe5d0 --- /dev/null +++ b/src/quicktemplates2/qquickitemdelegate_p_p.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKITEMDELEGATE_P_P_H +#define QQUICKITEMDELEGATE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickItemDelegatePrivate : public QQuickAbstractButtonPrivate +{ + Q_DECLARE_PUBLIC(QQuickItemDelegate) + +public: + QPalette defaultPalette() const override; + + bool highlighted = false; +}; + +QT_END_NAMESPACE + +#endif // QQUICKITEMDELEGATE_P_P_H diff --git a/src/quicktemplates2/qquicklabel.cpp b/src/quicktemplates2/qquicklabel.cpp new file mode 100644 index 00000000000..cb3bb489847 --- /dev/null +++ b/src/quicktemplates2/qquicklabel.cpp @@ -0,0 +1,594 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicklabel_p.h" +#include "qquicklabel_p_p.h" +#include "qquickcontrol_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickdeferredexecute_p_p.h" + +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquicktext_p.h> + +#if QT_CONFIG(accessibility) +#include <QtQuick/private/qquickaccessibleattached_p.h> +#endif + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Label + \inherits Text +//! \instantiates QQuickLabel + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup text + \brief Styled text label with inherited font. + + Label extends \l Text with styling and \l {Control::font}{font} + inheritance. The default colors and font are style specific. Label + can also have a visual \l background item. + + \image qtquickcontrols2-label.png + + \snippet qtquickcontrols2-label.qml 1 + + You can use the properties of \l Text to change the appearance of the text as desired: + + \qml + Label { + text: "Hello world" + font.pixelSize: 22 + font.italic: true + } + \endqml + + \sa {Customizing Label} +*/ + +QQuickLabelPrivate::QQuickLabelPrivate() +{ +#if QT_CONFIG(accessibility) + QAccessible::installActivationObserver(this); +#endif +} + +QQuickLabelPrivate::~QQuickLabelPrivate() +{ +#if QT_CONFIG(accessibility) + QAccessible::removeActivationObserver(this); +#endif +} + +void QQuickLabelPrivate::setTopInset(qreal value, bool reset) +{ + Q_Q(QQuickLabel); + const QMarginsF oldInset = getInset(); + extra.value().topInset = value; + extra.value().hasTopInset = !reset; + if (!qFuzzyCompare(oldInset.top(), value)) { + emit q->topInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickLabelPrivate::setLeftInset(qreal value, bool reset) +{ + Q_Q(QQuickLabel); + const QMarginsF oldInset = getInset(); + extra.value().leftInset = value; + extra.value().hasLeftInset = !reset; + if (!qFuzzyCompare(oldInset.left(), value)) { + emit q->leftInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickLabelPrivate::setRightInset(qreal value, bool reset) +{ + Q_Q(QQuickLabel); + const QMarginsF oldInset = getInset(); + extra.value().rightInset = value; + extra.value().hasRightInset = !reset; + if (!qFuzzyCompare(oldInset.right(), value)) { + emit q->rightInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickLabelPrivate::setBottomInset(qreal value, bool reset) +{ + Q_Q(QQuickLabel); + const QMarginsF oldInset = getInset(); + extra.value().bottomInset = value; + extra.value().hasBottomInset = !reset; + if (!qFuzzyCompare(oldInset.bottom(), value)) { + emit q->bottomInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickLabelPrivate::resizeBackground() +{ + if (!background) + return; + + resizingBackground = true; + + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + if (((!p->widthValid() || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(background->x())) + || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) { + background->setX(getLeftInset()); + background->setWidth(width - getLeftInset() - getRightInset()); + } + if (((!p->heightValid() || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(background->y())) + || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) { + background->setY(getTopInset()); + background->setHeight(height - getTopInset() - getBottomInset()); + } + + resizingBackground = false; +} + +/*! + \internal + + Determine which font is implicitly imposed on this control by its ancestors + and QGuiApplication::font, resolve this against its own font (attributes from + the implicit font are copied over). Then propagate this font to this + control's children. +*/ +void QQuickLabelPrivate::resolveFont() +{ + Q_Q(QQuickLabel); + inheritFont(QQuickControlPrivate::parentFont(q)); +} + +void QQuickLabelPrivate::inheritFont(const QFont &font) +{ + QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font; + parentFont.setResolveMask(extra.isAllocated() ? extra->requestedFont.resolveMask() | font.resolveMask() : font.resolveMask()); + + const QFont defaultFont = QQuickTheme::font(QQuickTheme::Label); + QFont resolvedFont = parentFont.resolve(defaultFont); + + setFont_helper(resolvedFont); +} + +/*! + \internal + + Assign \a font to this control, and propagate it to all children. +*/ +void QQuickLabelPrivate::updateFont(const QFont &font) +{ + Q_Q(QQuickLabel); + QFont oldFont = sourceFont; + q->QQuickText::setFont(font); + + QQuickControlPrivate::updateFontRecur(q, font); + + if (oldFont != font) + emit q->fontChanged(); +} + +void QQuickLabelPrivate::textChanged(const QString &text) +{ +#if QT_CONFIG(accessibility) + maybeSetAccessibleName(text); +#else + Q_UNUSED(text); +#endif +} + +#if QT_CONFIG(accessibility) +void QQuickLabelPrivate::accessibilityActiveChanged(bool active) +{ + if (!active) + return; + + Q_Q(QQuickLabel); + QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, true)); + Q_ASSERT(accessibleAttached); + accessibleAttached->setRole(effectiveAccessibleRole()); + maybeSetAccessibleName(text); +} + +QAccessible::Role QQuickLabelPrivate::accessibleRole() const +{ + return QAccessible::StaticText; +} + +void QQuickLabelPrivate::maybeSetAccessibleName(const QString &name) +{ + Q_Q(QQuickLabel); + auto accessibleAttached = qobject_cast<QQuickAccessibleAttached *>( + qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, true)); + if (accessibleAttached) { + if (!accessibleAttached->wasNameExplicitlySet()) + accessibleAttached->setNameImplicitly(name); + } +} +#endif + +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickLabelPrivate::cancelBackground() +{ + Q_Q(QQuickLabel); + quickCancelDeferred(q, backgroundName()); +} + +void QQuickLabelPrivate::executeBackground(bool complete) +{ + Q_Q(QQuickLabel); + if (background.wasExecuted()) + return; + + if (!background || complete) + quickBeginDeferred(q, backgroundName(), background); + if (complete) + quickCompleteDeferred(q, backgroundName(), background); +} + +void QQuickLabelPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) +{ + Q_UNUSED(diff); + if (resizingBackground || item != background || !change.sizeChange()) + return; + + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + extra.value().hasBackgroundWidth = p->widthValid(); + extra.value().hasBackgroundHeight = p->heightValid(); + resizeBackground(); +} + +void QQuickLabelPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickLabel); + if (item == background) + emit q->implicitBackgroundWidthChanged(); +} + +void QQuickLabelPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickLabel); + if (item == background) + emit q->implicitBackgroundHeightChanged(); +} + +void QQuickLabelPrivate::itemDestroyed(QQuickItem *item) +{ + Q_Q(QQuickLabel); + if (item == background) { + background = nullptr; + emit q->implicitBackgroundWidthChanged(); + emit q->implicitBackgroundHeightChanged(); + } +} + +QPalette QQuickLabelPrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::Label); +} + +QQuickLabel::QQuickLabel(QQuickItem *parent) + : QQuickText(*(new QQuickLabelPrivate), parent) +{ + Q_D(QQuickLabel); + QObjectPrivate::connect(this, &QQuickText::textChanged, d, &QQuickLabelPrivate::textChanged); +} + +QQuickLabel::~QQuickLabel() +{ + Q_D(QQuickLabel); + QQuickControlPrivate::removeImplicitSizeListener(d->background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); +} + +QFont QQuickLabel::font() const +{ + return QQuickText::font(); +} + +void QQuickLabel::setFont(const QFont &font) +{ + Q_D(QQuickLabel); + if (d->extra.value().requestedFont.resolveMask() == font.resolveMask() && d->extra.value().requestedFont == font) + return; + + d->extra.value().requestedFont = font; + d->resolveFont(); +} + +/*! + \qmlproperty Item QtQuick.Controls::Label::background + + This property holds the background item. + + \note If the background item has no explicit size specified, it automatically + follows the control's size. In most cases, there is no need to specify + width or height for a background item. + + \sa {Customizing Label} +*/ +QQuickItem *QQuickLabel::background() const +{ + QQuickLabelPrivate *d = const_cast<QQuickLabelPrivate *>(d_func()); + if (!d->background) + d->executeBackground(); + return d->background; +} + +void QQuickLabel::setBackground(QQuickItem *background) +{ + Q_D(QQuickLabel); + if (d->background == background) + return; + + if (!d->background.isExecuting()) + d->cancelBackground(); + + const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth(); + const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight(); + + if (d->extra.isAllocated()) { + d->extra.value().hasBackgroundWidth = false; + d->extra.value().hasBackgroundHeight = false; + } + + QQuickControlPrivate::removeImplicitSizeListener(d->background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); + QQuickControlPrivate::hideOldItem(d->background); + d->background = background; + + if (background) { + background->setParentItem(this); + if (qFuzzyIsNull(background->z())) + background->setZ(-1); + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + if (p->widthValid() || p->heightValid()) { + d->extra.value().hasBackgroundWidth = p->widthValid(); + d->extra.value().hasBackgroundHeight = p->heightValid(); + } + if (isComponentComplete()) + d->resizeBackground(); + QQuickControlPrivate::addImplicitSizeListener(background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); + } + + if (!qFuzzyCompare(oldImplicitBackgroundWidth, implicitBackgroundWidth())) + emit implicitBackgroundWidthChanged(); + if (!qFuzzyCompare(oldImplicitBackgroundHeight, implicitBackgroundHeight())) + emit implicitBackgroundHeightChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Label::implicitBackgroundWidth + \readonly + + This property holds the implicit background width. + + The value is equal to \c {background ? background.implicitWidth : 0}. + + \sa implicitBackgroundHeight +*/ +qreal QQuickLabel::implicitBackgroundWidth() const +{ + Q_D(const QQuickLabel); + if (!d->background) + return 0; + return d->background->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Label::implicitBackgroundHeight + \readonly + + This property holds the implicit background height. + + The value is equal to \c {background ? background.implicitHeight : 0}. + + \sa implicitBackgroundWidth +*/ +qreal QQuickLabel::implicitBackgroundHeight() const +{ + Q_D(const QQuickLabel); + if (!d->background) + return 0; + return d->background->implicitHeight(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Label::topInset + + This property holds the top inset for the background. + + \sa {Control Layout}, bottomInset +*/ +qreal QQuickLabel::topInset() const +{ + Q_D(const QQuickLabel); + return d->getTopInset(); +} + +void QQuickLabel::setTopInset(qreal inset) +{ + Q_D(QQuickLabel); + d->setTopInset(inset); +} + +void QQuickLabel::resetTopInset() +{ + Q_D(QQuickLabel); + d->setTopInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Label::leftInset + + This property holds the left inset for the background. + + \sa {Control Layout}, rightInset +*/ +qreal QQuickLabel::leftInset() const +{ + Q_D(const QQuickLabel); + return d->getLeftInset(); +} + +void QQuickLabel::setLeftInset(qreal inset) +{ + Q_D(QQuickLabel); + d->setLeftInset(inset); +} + +void QQuickLabel::resetLeftInset() +{ + Q_D(QQuickLabel); + d->setLeftInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Label::rightInset + + This property holds the right inset for the background. + + \sa {Control Layout}, leftInset +*/ +qreal QQuickLabel::rightInset() const +{ + Q_D(const QQuickLabel); + return d->getRightInset(); +} + +void QQuickLabel::setRightInset(qreal inset) +{ + Q_D(QQuickLabel); + d->setRightInset(inset); +} + +void QQuickLabel::resetRightInset() +{ + Q_D(QQuickLabel); + d->setRightInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Label::bottomInset + + This property holds the bottom inset for the background. + + \sa {Control Layout}, topInset +*/ +qreal QQuickLabel::bottomInset() const +{ + Q_D(const QQuickLabel); + return d->getBottomInset(); +} + +void QQuickLabel::setBottomInset(qreal inset) +{ + Q_D(QQuickLabel); + d->setBottomInset(inset); +} + +void QQuickLabel::resetBottomInset() +{ + Q_D(QQuickLabel); + d->setBottomInset(0, true); +} + +void QQuickLabel::classBegin() +{ + Q_D(QQuickLabel); + QQuickText::classBegin(); + d->resolveFont(); +} + +void QQuickLabel::componentComplete() +{ + Q_D(QQuickLabel); + d->executeBackground(true); + QQuickText::componentComplete(); + d->resizeBackground(); +#if QT_CONFIG(accessibility) + if (QAccessible::isActive()) + d->accessibilityActiveChanged(true); +#endif +} + +void QQuickLabel::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) +{ + Q_D(QQuickLabel); + QQuickText::itemChange(change, value); + switch (change) { + case ItemEnabledHasChanged: + break; + case ItemSceneChange: + case ItemParentHasChanged: + if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) { + d->resolveFont(); + } + break; + default: + break; + } +} + +void QQuickLabel::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickLabel); + QQuickText::geometryChange(newGeometry, oldGeometry); + d->resizeBackground(); +} + +void QQuickLabel::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset) +{ + Q_D(QQuickLabel); + Q_UNUSED(newInset); + Q_UNUSED(oldInset); + d->resizeBackground(); +} + +QT_END_NAMESPACE + +#include "moc_qquicklabel_p.cpp" diff --git a/src/quicktemplates2/qquicklabel_p.h b/src/quicktemplates2/qquicklabel_p.h new file mode 100644 index 00000000000..6ef60be96e9 --- /dev/null +++ b/src/quicktemplates2/qquicklabel_p.h @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABEL_P_H +#define QQUICKLABEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qpalette.h> +#include <QtQuick/private/qquicktext_p.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickLabelPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickLabel : public QQuickText +{ + Q_OBJECT + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) // override + Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitBackgroundWidth READ implicitBackgroundWidth NOTIFY implicitBackgroundWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitBackgroundHeight READ implicitBackgroundHeight NOTIFY implicitBackgroundHeightChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal topInset READ topInset WRITE setTopInset RESET resetTopInset NOTIFY topInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal leftInset READ leftInset WRITE setLeftInset RESET resetLeftInset NOTIFY leftInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal rightInset READ rightInset WRITE setRightInset RESET resetRightInset NOTIFY rightInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal bottomInset READ bottomInset WRITE setBottomInset RESET resetBottomInset NOTIFY bottomInsetChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DeferredPropertyNames", "background") + QML_NAMED_ELEMENT(Label) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickLabel(QQuickItem *parent = nullptr); + ~QQuickLabel(); + + QFont font() const; + void setFont(const QFont &font); + + QQuickItem *background() const; + void setBackground(QQuickItem *background); + + // 2.5 (Qt 5.12) + qreal implicitBackgroundWidth() const; + qreal implicitBackgroundHeight() const; + + qreal topInset() const; + void setTopInset(qreal inset); + void resetTopInset(); + + qreal leftInset() const; + void setLeftInset(qreal inset); + void resetLeftInset(); + + qreal rightInset() const; + void setRightInset(qreal inset); + void resetRightInset(); + + qreal bottomInset() const; + void setBottomInset(qreal inset); + void resetBottomInset(); + +Q_SIGNALS: + void fontChanged(); + void backgroundChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void implicitBackgroundWidthChanged(); + Q_REVISION(2, 5) void implicitBackgroundHeightChanged(); + Q_REVISION(2, 5) void topInsetChanged(); + Q_REVISION(2, 5) void leftInsetChanged(); + Q_REVISION(2, 5) void rightInsetChanged(); + Q_REVISION(2, 5) void bottomInsetChanged(); + +protected: + void classBegin() override; + void componentComplete() override; + + void itemChange(ItemChange change, const ItemChangeData &value) override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + virtual void insetChange(const QMarginsF &newInset, const QMarginsF &oldInset); + +private: + Q_DISABLE_COPY(QQuickLabel) + Q_DECLARE_PRIVATE(QQuickLabel) +}; + +struct QQuickTemplatesTextForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickText) + QML_ADDED_IN_VERSION(2, 3) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickLabel) + +#endif // QQUICKLABEL_P_H diff --git a/src/quicktemplates2/qquicklabel_p_p.h b/src/quicktemplates2/qquicklabel_p_p.h new file mode 100644 index 00000000000..3171e2f7e48 --- /dev/null +++ b/src/quicktemplates2/qquicklabel_p_p.h @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKLABEL_P_P_H +#define QQUICKLABEL_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/private/qlazilyallocated_p.h> +#include <QtQuick/private/qquicktext_p_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +#if QT_CONFIG(accessibility) +#include <QtGui/qaccessible.h> +#endif + +QT_BEGIN_NAMESPACE + +class Q_AUTOTEST_EXPORT QQuickLabelPrivate : public QQuickTextPrivate, public QQuickItemChangeListener +#if QT_CONFIG(accessibility) + , public QAccessible::ActivationObserver +#endif +{ + Q_DECLARE_PUBLIC(QQuickLabel) + +public: + QQuickLabelPrivate(); + ~QQuickLabelPrivate(); + + static QQuickLabelPrivate *get(QQuickLabel *item) + { + return static_cast<QQuickLabelPrivate *>(QObjectPrivate::get(item)); + } + + inline QMarginsF getInset() const { return QMarginsF(getLeftInset(), getTopInset(), getRightInset(), getBottomInset()); } + inline qreal getTopInset() const { return extra.isAllocated() ? extra->topInset : 0; } + inline qreal getLeftInset() const { return extra.isAllocated() ? extra->leftInset : 0; } + inline qreal getRightInset() const { return extra.isAllocated() ? extra->rightInset : 0; } + inline qreal getBottomInset() const { return extra.isAllocated() ? extra->bottomInset : 0; } + + void setTopInset(qreal value, bool reset = false); + void setLeftInset(qreal value, bool reset = false); + void setRightInset(qreal value, bool reset = false); + void setBottomInset(qreal value, bool reset = false); + + void resizeBackground(); + + void resolveFont(); + void inheritFont(const QFont &font); + void updateFont(const QFont &font); + inline void setFont_helper(const QFont &font) { + if (sourceFont.resolveMask() == font.resolveMask() && sourceFont == font) + return; + updateFont(font); + } + + void textChanged(const QString &text); + +#if QT_CONFIG(accessibility) + void accessibilityActiveChanged(bool active) override; + QAccessible::Role accessibleRole() const override; + void maybeSetAccessibleName(const QString &name); +#endif + + void cancelBackground(); + void executeBackground(bool complete = false); + + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + void itemDestroyed(QQuickItem *item) override; + + QPalette defaultPalette() const override; + + struct ExtraData { + bool hasTopInset = false; + bool hasLeftInset = false; + bool hasRightInset = false; + bool hasBottomInset = false; + bool hasBackgroundWidth = false; + bool hasBackgroundHeight = false; + qreal topInset = 0; + qreal leftInset = 0; + qreal rightInset = 0; + qreal bottomInset = 0; + QFont requestedFont; + }; + QLazilyAllocated<ExtraData> extra; + + bool resizingBackground = false; + QPalette resolvedPalette; + QQuickDeferredPointer<QQuickItem> background; +}; + +QT_END_NAMESPACE + +#endif // QQUICKLABEL_P_P_H diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp new file mode 100644 index 00000000000..373e78f71c6 --- /dev/null +++ b/src/quicktemplates2/qquickmenu.cpp @@ -0,0 +1,1539 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmenu_p.h" +#include "qquickmenu_p_p.h" +#include "qquickmenuitem_p_p.h" +#include "qquickmenubaritem_p.h" +#include "qquickmenubar_p.h" +#include "qquickpopupitem_p_p.h" +#include "qquickpopuppositioner_p_p.h" +#include "qquickaction_p.h" + +#include <QtGui/qevent.h> +#include <QtGui/qcursor.h> +#if QT_CONFIG(shortcut) +#include <QtGui/qkeysequence.h> +#endif +#include <QtGui/qpa/qplatformintegration.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/private/qqmlengine_p.h> +#include <QtQml/private/qv4scopedvalue_p.h> +#include <QtQml/private/qv4variantobject_p.h> +#include <QtQml/private/qv4qobjectwrapper_p.h> +#include <private/qqmlobjectmodel_p.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQuick/private/qquickitemview_p.h> +#include <QtQuick/private/qquickevents_p_p.h> +#include <QtQuick/private/qquickwindow_p.h> + +QT_BEGIN_NAMESPACE + +// copied from qfusionstyle.cpp +static const int SUBMENU_DELAY = 225; + +/*! + \qmltype Menu + \inherits Popup +//! \instantiates QQuickMenu + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-menus + \ingroup qtquickcontrols2-popups + \brief Menu popup that can be used as a context menu or popup menu. + + \image qtquickcontrols2-menu.png + + Menu has two main use cases: + \list + \li Context menus; for example, a menu that is shown after right clicking + \li Popup menus; for example, a menu that is shown after clicking a button + \endlist + + When used as a context menu, the recommended way of opening the menu is to call + \l popup(). Unless a position is explicitly specified, the menu is positioned at + the mouse cursor on desktop platforms that have a mouse cursor available, and + otherwise centered over its parent item. + + \code + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: { + if (mouse.button === Qt.RightButton) + contextMenu.popup() + } + onPressAndHold: { + if (mouse.source === Qt.MouseEventNotSynthesized) + contextMenu.popup() + } + + Menu { + id: contextMenu + MenuItem { text: "Cut" } + MenuItem { text: "Copy" } + MenuItem { text: "Paste" } + } + } + \endcode + + When used as a popup menu, it is easiest to specify the position by specifying + the desired \l {Popup::}{x} and \l {Popup::}{y} coordinates using the respective + properties, and call \l {Popup::}{open()} to open the menu. + + \code + Button { + id: fileButton + text: "File" + onClicked: menu.open() + + Menu { + id: menu + y: fileButton.height + + MenuItem { + text: "New..." + } + MenuItem { + text: "Open..." + } + MenuItem { + text: "Save" + } + } + } + \endcode + + Since QtQuick.Controls 2.3 (Qt 5.10), it is also possible to create sub-menus + and declare Action objects inside Menu: + + \code + Menu { + Action { text: "Cut" } + Action { text: "Copy" } + Action { text: "Paste" } + + MenuSeparator { } + + Menu { + title: "Find/Replace" + Action { text: "Find Next" } + Action { text: "Find Previous" } + Action { text: "Replace" } + } + } + \endcode + + Sub-menus are \l {cascade}{cascading} by default on desktop platforms + that have a mouse cursor available. Non-cascading menus are shown one + menu at a time, and centered over the parent menu. + + Typically, menu items are statically declared as children of the menu, but + Menu also provides API to \l {addItem}{add}, \l {insertItem}{insert}, + \l {moveItem}{move} and \l {removeItem}{remove} items dynamically. The + items in a menu can be accessed using \l itemAt() or + \l {Popup::}{contentChildren}. + + Although \l {MenuItem}{MenuItems} are most commonly used with Menu, it can + contain any type of item. + + \section1 Margins + + As it is inherited from Popup, Menu supports \l {Popup::}{margins}. By + default, all of the built-in styles specify \c 0 for Menu's margins to + ensure that the menu is kept within the bounds of the window. To allow a + menu to go outside of the window (to animate it moving into view, for + example), set the margins property to \c -1. + + \sa {Customizing Menu}, MenuItem, {Menu Controls}, {Popup Controls} +*/ + +/*! + \qmlproperty bool QtQuick.Controls::Menu::focus + + This property holds whether the popup wants focus. + + When the popup actually receives focus, \l{Popup::}{activeFocus} + will be \c true. For more information, see + \l {Keyboard Focus in Qt Quick}. + + The default value is \c false. + + \sa {Popup::}{activeFocus} +*/ + +static const QQuickPopup::ClosePolicy cascadingSubMenuClosePolicy = QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent; + +static bool shouldCascade() +{ +#if QT_CONFIG(cursor) + return QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows); +#else + return false; +#endif +} + +class QQuickMenuPositioner : public QQuickPopupPositioner +{ +public: + QQuickMenuPositioner(QQuickMenu *menu) : QQuickPopupPositioner(menu) { } + + void reposition() override; +}; + +QQuickMenuPrivate::QQuickMenuPrivate() +{ + cascade = shouldCascade(); +} + +void QQuickMenuPrivate::init() +{ + Q_Q(QQuickMenu); + contentModel = new QQmlObjectModel(q); +} + +QQuickItem *QQuickMenuPrivate::itemAt(int index) const +{ + return qobject_cast<QQuickItem *>(contentModel->get(index)); +} + +void QQuickMenuPrivate::insertItem(int index, QQuickItem *item) +{ + contentData.append(item); + item->setParentItem(contentItem); + if (qobject_cast<QQuickItemView *>(contentItem)) + QQuickItemPrivate::get(item)->setCulled(true); // QTBUG-53262 + if (complete) + resizeItem(item); + QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent); + QQuickItemPrivate::get(item)->updateOrAddGeometryChangeListener(this, QQuickGeometryChange::Width); + contentModel->insert(index, item); + + QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(item); + if (menuItem) { + Q_Q(QQuickMenu); + QQuickMenuItemPrivate::get(menuItem)->setMenu(q); + if (QQuickMenu *subMenu = menuItem->subMenu()) + QQuickMenuPrivate::get(subMenu)->setParentMenu(q); + QObjectPrivate::connect(menuItem, &QQuickMenuItem::triggered, this, &QQuickMenuPrivate::onItemTriggered); + QObjectPrivate::connect(menuItem, &QQuickItem::activeFocusChanged, this, &QQuickMenuPrivate::onItemActiveFocusChanged); + QObjectPrivate::connect(menuItem, &QQuickControl::hoveredChanged, this, &QQuickMenuPrivate::onItemHovered); + } +} + +void QQuickMenuPrivate::moveItem(int from, int to) +{ + contentModel->move(from, to); +} + +void QQuickMenuPrivate::removeItem(int index, QQuickItem *item) +{ + contentData.removeOne(item); + + QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent); + QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry); + item->setParentItem(nullptr); + contentModel->remove(index); + + QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(item); + if (menuItem) { + QQuickMenuItemPrivate::get(menuItem)->setMenu(nullptr); + if (QQuickMenu *subMenu = menuItem->subMenu()) + QQuickMenuPrivate::get(subMenu)->setParentMenu(nullptr); + QObjectPrivate::disconnect(menuItem, &QQuickMenuItem::triggered, this, &QQuickMenuPrivate::onItemTriggered); + QObjectPrivate::disconnect(menuItem, &QQuickItem::activeFocusChanged, this, &QQuickMenuPrivate::onItemActiveFocusChanged); + QObjectPrivate::disconnect(menuItem, &QQuickControl::hoveredChanged, this, &QQuickMenuPrivate::onItemHovered); + } +} + +QQuickItem *QQuickMenuPrivate::beginCreateItem() +{ + Q_Q(QQuickMenu); + if (!delegate) + return nullptr; + + QQmlContext *creationContext = delegate->creationContext(); + if (!creationContext) + creationContext = qmlContext(q); + QQmlContext *context = new QQmlContext(creationContext, q); + context->setContextObject(q); + + QObject *object = delegate->beginCreate(context); + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (!item) + delete object; + else + QQml_setParent_noEvent(item, q); + + return item; +} + +void QQuickMenuPrivate::completeCreateItem() +{ + if (!delegate) + return; + + delegate->completeCreate(); +} + +QQuickItem *QQuickMenuPrivate::createItem(QQuickMenu *menu) +{ + QQuickItem *item = beginCreateItem(); + if (QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(item)) + QQuickMenuItemPrivate::get(menuItem)->setSubMenu(menu); + completeCreateItem(); + return item; +} + +QQuickItem *QQuickMenuPrivate::createItem(QQuickAction *action) +{ + QQuickItem *item = beginCreateItem(); + if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(item)) + button->setAction(action); + completeCreateItem(); + return item; +} + +void QQuickMenuPrivate::resizeItem(QQuickItem *item) +{ + if (!item || !contentItem) + return; + + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + if (!p->widthValid()) { + item->setWidth(contentItem->width()); + p->widthValidFlag = false; + } +} + +void QQuickMenuPrivate::resizeItems() +{ + if (!contentModel) + return; + + for (int i = 0; i < contentModel->count(); ++i) + resizeItem(itemAt(i)); +} + +void QQuickMenuPrivate::itemChildAdded(QQuickItem *, QQuickItem *child) +{ + // add dynamically reparented items (eg. by a Repeater) + if (!QQuickItemPrivate::get(child)->isTransparentForPositioner() && !contentData.contains(child)) + insertItem(contentModel->count(), child); +} + +void QQuickMenuPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent) +{ + // remove dynamically unparented items (eg. by a Repeater) + if (!parent) + removeItem(contentModel->indexOf(item, nullptr), item); +} + +void QQuickMenuPrivate::itemSiblingOrderChanged(QQuickItem *) +{ + // reorder the restacked items (eg. by a Repeater) + Q_Q(QQuickMenu); + QList<QQuickItem *> siblings = contentItem->childItems(); + + int to = 0; + for (int i = 0; i < siblings.count(); ++i) { + QQuickItem* sibling = siblings.at(i); + if (QQuickItemPrivate::get(sibling)->isTransparentForPositioner()) + continue; + int index = contentModel->indexOf(sibling, nullptr); + q->moveItem(index, to++); + } +} + +void QQuickMenuPrivate::itemDestroyed(QQuickItem *item) +{ + QQuickPopupPrivate::itemDestroyed(item); + int index = contentModel->indexOf(item, nullptr); + if (index != -1) + removeItem(index, item); +} + +void QQuickMenuPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange, const QRectF &) +{ + if (!complete) + return; + + if (item == contentItem) { + // The contentItem's geometry changed, so resize any items + // that don't have explicit widths set so that they fill the width of the menu. + resizeItems(); + } else { + // The geometry of an item in the menu changed. If the item + // doesn't have an explicit width set, make it fill the width of the menu. + resizeItem(item); + } +} + +QQuickPopupPositioner *QQuickMenuPrivate::getPositioner() +{ + Q_Q(QQuickMenu); + if (!positioner) + positioner = new QQuickMenuPositioner(q); + return positioner; +} + +void QQuickMenuPositioner::reposition() +{ + QQuickMenu *menu = static_cast<QQuickMenu *>(popup()); + QQuickMenuPrivate *p = QQuickMenuPrivate::get(menu); + if (p->parentMenu) { + if (p->cascade) { + if (p->popupItem->isMirrored()) + menu->setPosition(QPointF(-menu->width() - p->parentMenu->leftPadding() + menu->overlap(), -menu->topPadding())); + else if (p->parentItem) + menu->setPosition(QPointF(p->parentItem->width() + p->parentMenu->rightPadding() - menu->overlap(), -menu->topPadding())); + } else { + menu->setPosition(QPointF(p->parentMenu->x() + (p->parentMenu->width() - menu->width()) / 2, + p->parentMenu->y() + (p->parentMenu->height() - menu->height()) / 2)); + } + } + QQuickPopupPositioner::reposition(); +} + +bool QQuickMenuPrivate::prepareEnterTransition() +{ + Q_Q(QQuickMenu); + if (parentMenu && !cascade) + parentMenu->close(); + + // If a cascading sub-menu doesn't have enough space to open on + // the right, it flips on the other side of the parent menu. + allowHorizontalFlip = cascade && parentMenu; + + if (!QQuickPopupPrivate::prepareEnterTransition()) + return false; + + if (!hasClosePolicy) { + if (cascade && parentMenu) + closePolicy = cascadingSubMenuClosePolicy; + else + q->resetClosePolicy(); + } + return true; +} + +bool QQuickMenuPrivate::prepareExitTransition() +{ + if (!QQuickPopupPrivate::prepareExitTransition()) + return false; + + stopHoverTimer(); + + QQuickMenu *subMenu = currentSubMenu(); + while (subMenu) { + QPointer<QQuickMenuItem> currentSubMenuItem = QQuickMenuPrivate::get(subMenu)->currentItem; + subMenu->close(); + subMenu = currentSubMenuItem ? currentSubMenuItem->subMenu() : nullptr; + } + return true; +} + +bool QQuickMenuPrivate::blockInput(QQuickItem *item, const QPointF &point) const +{ + // keep the parent menu open when a cascading sub-menu (this menu) is interacted with + return (cascade && parentMenu && contains(point)) || QQuickPopupPrivate::blockInput(item, point); +} + +void QQuickMenuPrivate::onItemHovered() +{ + Q_Q(QQuickMenu); + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(q->sender()); + if (!button || !button->isHovered() || !button->isEnabled() || QQuickAbstractButtonPrivate::get(button)->touchId != -1) + return; + + QQuickMenuItem *oldCurrentItem = currentItem; + + int index = contentModel->indexOf(button, nullptr); + if (index != -1) { + setCurrentIndex(index, Qt::OtherFocusReason); + if (oldCurrentItem != currentItem) { + if (oldCurrentItem) { + QQuickMenu *subMenu = oldCurrentItem->subMenu(); + if (subMenu) + subMenu->close(); + } + if (currentItem) { + QQuickMenu *subMenu = currentItem->menu(); + if (subMenu && subMenu->cascade()) + startHoverTimer(); + } + } + } +} + +void QQuickMenuPrivate::onItemTriggered() +{ + Q_Q(QQuickMenu); + QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(q->sender()); + if (!item) + return; + + if (QQuickMenu *subMenu = item->subMenu()) { + auto subMenuPrivate = QQuickMenuPrivate::get(subMenu); + subMenu->popup(subMenuPrivate->firstEnabledMenuItem()); + } else { + q->dismiss(); + } +} + +void QQuickMenuPrivate::onItemActiveFocusChanged() +{ + Q_Q(QQuickMenu); + QQuickItem *item = qobject_cast<QQuickItem*>(q->sender()); + if (!item->hasActiveFocus()) + return; + + int indexOfItem = contentModel->indexOf(item, nullptr); + QQuickControl *control = qobject_cast<QQuickControl *>(item); + setCurrentIndex(indexOfItem, control ? control->focusReason() : Qt::OtherFocusReason); +} + +QQuickMenu *QQuickMenuPrivate::currentSubMenu() const +{ + if (!currentItem) + return nullptr; + + return currentItem->subMenu(); +} + +void QQuickMenuPrivate::setParentMenu(QQuickMenu *parent) +{ + Q_Q(QQuickMenu); + if (parentMenu == parent) + return; + + if (parentMenu) { + QObject::disconnect(parentMenu.data(), &QQuickMenu::cascadeChanged, q, &QQuickMenu::setCascade); + disconnect(parentMenu.data(), &QQuickMenu::parentChanged, this, &QQuickMenuPrivate::resolveParentItem); + } + if (parent) { + QObject::connect(parent, &QQuickMenu::cascadeChanged, q, &QQuickMenu::setCascade); + connect(parent, &QQuickMenu::parentChanged, this, &QQuickMenuPrivate::resolveParentItem); + } + + parentMenu = parent; + q->resetCascade(); + resolveParentItem(); +} + +static QQuickItem *findParentMenuItem(QQuickMenu *subMenu) +{ + QQuickMenu *menu = QQuickMenuPrivate::get(subMenu)->parentMenu; + for (int i = 0; i < QQuickMenuPrivate::get(menu)->contentModel->count(); ++i) { + QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(menu->itemAt(i)); + if (item && item->subMenu() == subMenu) + return item; + } + return nullptr; +} + +void QQuickMenuPrivate::resolveParentItem() +{ + Q_Q(QQuickMenu); + if (!parentMenu) + q->resetParentItem(); + else if (!cascade) + q->setParentItem(parentMenu->parentItem()); + else + q->setParentItem(findParentMenuItem(q)); +} + +void QQuickMenuPrivate::propagateKeyEvent(QKeyEvent *event) +{ + if (QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(parentItem)) { + if (QQuickMenu *menu = menuItem->menu()) + QQuickMenuPrivate::get(menu)->propagateKeyEvent(event); + } else if (QQuickMenuBarItem *menuBarItem = qobject_cast<QQuickMenuBarItem *>(parentItem)) { + if (QQuickMenuBar *menuBar = menuBarItem->menuBar()) { + event->accept(); + QCoreApplication::sendEvent(menuBar, event); + } + } +} + +void QQuickMenuPrivate::startHoverTimer() +{ + Q_Q(QQuickMenu); + stopHoverTimer(); + hoverTimer = q->startTimer(SUBMENU_DELAY); +} + +void QQuickMenuPrivate::stopHoverTimer() +{ + Q_Q(QQuickMenu); + if (!hoverTimer) + return; + + q->killTimer(hoverTimer); + hoverTimer = 0; +} + +void QQuickMenuPrivate::setCurrentIndex(int index, Qt::FocusReason reason) +{ + Q_Q(QQuickMenu); + if (currentIndex == index) + return; + + QQuickMenuItem *newCurrentItem = qobject_cast<QQuickMenuItem *>(itemAt(index)); + if (currentItem != newCurrentItem) { + stopHoverTimer(); + if (currentItem) { + currentItem->setHighlighted(false); + if (!newCurrentItem && window) { + QQuickItem *focusItem = QQuickItemPrivate::get(contentItem)->subFocusItem; + if (focusItem) + QQuickWindowPrivate::get(window)->clearFocusInScope(contentItem, focusItem, Qt::OtherFocusReason); + } + } + if (newCurrentItem) { + newCurrentItem->setHighlighted(true); + newCurrentItem->forceActiveFocus(reason); + } + currentItem = newCurrentItem; + } + + currentIndex = index; + emit q->currentIndexChanged(); +} + +bool QQuickMenuPrivate::activateNextItem() +{ + int index = currentIndex; + int count = contentModel->count(); + while (++index < count) { + QQuickItem *item = itemAt(index); + if (!item || !item->activeFocusOnTab() || !item->isEnabled()) + continue; + setCurrentIndex(index, Qt::TabFocusReason); + return true; + } + return false; +} + +bool QQuickMenuPrivate::activatePreviousItem() +{ + int index = currentIndex; + while (--index >= 0) { + QQuickItem *item = itemAt(index); + if (!item || !item->activeFocusOnTab() || !item->isEnabled()) + continue; + setCurrentIndex(index, Qt::BacktabFocusReason); + return true; + } + return false; +} + +QQuickMenuItem *QQuickMenuPrivate::firstEnabledMenuItem() const +{ + for (int i = 0; i < contentModel->count(); ++i) { + QQuickItem *item = itemAt(i); + if (!item || !item->isEnabled()) + continue; + + QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(item); + if (!menuItem) + continue; + + return menuItem; + } + return nullptr; +} + +void QQuickMenuPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj) +{ + QQuickMenu *q = qobject_cast<QQuickMenu *>(prop->object); + QQuickMenuPrivate *p = QQuickMenuPrivate::get(q); + + QQuickItem *item = qobject_cast<QQuickItem *>(obj); + if (!item) { + if (QQuickAction *action = qobject_cast<QQuickAction *>(obj)) + item = p->createItem(action); + else if (QQuickMenu *menu = qobject_cast<QQuickMenu *>(obj)) + item = p->createItem(menu); + } + + if (item) { + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) { + QQuickItemPrivate::get(item)->addItemChangeListener(p, QQuickItemPrivate::SiblingOrder); + item->setParentItem(p->contentItem); + } else if (p->contentModel->indexOf(item, nullptr) == -1) { + q->addItem(item); + } + } else { + p->contentData.append(obj); + } +} + +qsizetype QQuickMenuPrivate::contentData_count(QQmlListProperty<QObject> *prop) +{ + QQuickMenu *q = static_cast<QQuickMenu *>(prop->object); + return QQuickMenuPrivate::get(q)->contentData.count(); +} + +QObject *QQuickMenuPrivate::contentData_at(QQmlListProperty<QObject> *prop, qsizetype index) +{ + QQuickMenu *q = static_cast<QQuickMenu *>(prop->object); + return QQuickMenuPrivate::get(q)->contentData.value(index); +} + +QPalette QQuickMenuPrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::Menu); +} + +void QQuickMenuPrivate::contentData_clear(QQmlListProperty<QObject> *prop) +{ + QQuickMenu *q = static_cast<QQuickMenu *>(prop->object); + QQuickMenuPrivate::get(q)->contentData.clear(); +} + +QQuickMenu::QQuickMenu(QObject *parent) + : QQuickPopup(*(new QQuickMenuPrivate), parent) +{ + Q_D(QQuickMenu); + setFocus(true); + d->init(); + connect(d->contentModel, &QQmlObjectModel::countChanged, this, &QQuickMenu::countChanged); +} + +QQuickMenu::~QQuickMenu() +{ + Q_D(QQuickMenu); + // We have to do this to ensure that the change listeners are removed. + // It's too late to do this in ~QQuickMenuPrivate, as contentModel has already + // been destroyed before that is called. + while (d->contentModel->count() > 0) + d->removeItem(0, d->itemAt(0)); + + if (d->contentItem) { + const auto children = d->contentItem->childItems(); + for (QQuickItem *child : std::as_const(children)) + QQuickItemPrivate::get(child)->removeItemChangeListener(d, QQuickItemPrivate::SiblingOrder); + } +} + +/*! + \qmlmethod Item QtQuick.Controls::Menu::itemAt(int index) + + Returns the item at \a index, or \c null if it does not exist. +*/ +QQuickItem *QQuickMenu::itemAt(int index) const +{ + Q_D(const QQuickMenu); + return d->itemAt(index); +} + +/*! + \qmlmethod void QtQuick.Controls::Menu::addItem(Item item) + + Adds \a item to the end of the list of items. +*/ +void QQuickMenu::addItem(QQuickItem *item) +{ + Q_D(QQuickMenu); + insertItem(d->contentModel->count(), item); +} + +/*! + \qmlmethod void QtQuick.Controls::Menu::insertItem(int index, Item item) + + Inserts \a item at \a index. +*/ +void QQuickMenu::insertItem(int index, QQuickItem *item) +{ + Q_D(QQuickMenu); + if (!item) + return; + const int count = d->contentModel->count(); + if (index < 0 || index > count) + index = count; + + int oldIndex = d->contentModel->indexOf(item, nullptr); + if (oldIndex != -1) { + if (oldIndex < index) + --index; + if (oldIndex != index) + d->moveItem(oldIndex, index); + } else { + d->insertItem(index, item); + } +} + +/*! + \qmlmethod void QtQuick.Controls::Menu::moveItem(int from, int to) + + Moves an item \a from one index \a to another. +*/ +void QQuickMenu::moveItem(int from, int to) +{ + Q_D(QQuickMenu); + const int count = d->contentModel->count(); + if (from < 0 || from > count - 1) + return; + if (to < 0 || to > count - 1) + to = count - 1; + + if (from != to) + d->moveItem(from, to); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::removeItem(Item item) + + Removes and destroys the specified \a item. +*/ +void QQuickMenu::removeItem(QQuickItem *item) +{ + Q_D(QQuickMenu); + if (!item) + return; + + const int index = d->contentModel->indexOf(item, nullptr); + if (index == -1) + return; + + d->removeItem(index, item); + item->deleteLater(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod MenuItem QtQuick.Controls::Menu::takeItem(int index) + + Removes and returns the item at \a index. + + \note The ownership of the item is transferred to the caller. +*/ +QQuickItem *QQuickMenu::takeItem(int index) +{ + Q_D(QQuickMenu); + const int count = d->contentModel->count(); + if (index < 0 || index >= count) + return nullptr; + + QQuickItem *item = itemAt(index); + if (item) + d->removeItem(index, item); + return item; +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod Menu QtQuick.Controls::Menu::menuAt(int index) + + Returns the sub-menu at \a index, or \c null if the index is not valid or + there is no sub-menu at the specified index. +*/ +QQuickMenu *QQuickMenu::menuAt(int index) const +{ + Q_D(const QQuickMenu); + QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(d->itemAt(index)); + if (!item) + return nullptr; + + return item->subMenu(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::addMenu(Menu menu) + + Adds \a menu as a sub-menu to the end of this menu. +*/ +void QQuickMenu::addMenu(QQuickMenu *menu) +{ + Q_D(QQuickMenu); + insertMenu(d->contentModel->count(), menu); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::insertMenu(int index, Menu menu) + + Inserts \a menu as a sub-menu at \a index. The index is within all items in the menu. +*/ +void QQuickMenu::insertMenu(int index, QQuickMenu *menu) +{ + Q_D(QQuickMenu); + if (!menu) + return; + + insertItem(index, d->createItem(menu)); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::removeMenu(Menu menu) + + Removes and destroys the specified \a menu. +*/ +void QQuickMenu::removeMenu(QQuickMenu *menu) +{ + Q_D(QQuickMenu); + if (!menu) + return; + + const int count = d->contentModel->count(); + for (int i = 0; i < count; ++i) { + QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(d->itemAt(i)); + if (!item || item->subMenu() != menu) + continue; + + removeItem(item); + break; + } + + menu->deleteLater(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod Menu QtQuick.Controls::Menu::takeMenu(int index) + + Removes and returns the menu at \a index. The index is within all items in the menu. + + \note The ownership of the menu is transferred to the caller. +*/ +QQuickMenu *QQuickMenu::takeMenu(int index) +{ + Q_D(QQuickMenu); + QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(d->itemAt(index)); + if (!item) + return nullptr; + + QQuickMenu *subMenu = item->subMenu(); + if (!subMenu) + return nullptr; + + d->removeItem(index, item); + item->deleteLater(); + return subMenu; +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod Action QtQuick.Controls::Menu::actionAt(int index) + + Returns the action at \a index, or \c null if the index is not valid or + there is no action at the specified index. +*/ +QQuickAction *QQuickMenu::actionAt(int index) const +{ + Q_D(const QQuickMenu); + QQuickAbstractButton *item = qobject_cast<QQuickAbstractButton *>(d->itemAt(index)); + if (!item) + return nullptr; + + return item->action(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::addAction(Action action) + + Adds \a action to the end of this menu. +*/ +void QQuickMenu::addAction(QQuickAction *action) +{ + Q_D(QQuickMenu); + insertAction(d->contentModel->count(), action); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::insertAction(int index, Action action) + + Inserts \a action at \a index. The index is within all items in the menu. +*/ +void QQuickMenu::insertAction(int index, QQuickAction *action) +{ + Q_D(QQuickMenu); + if (!action) + return; + + insertItem(index, d->createItem(action)); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::removeAction(Action action) + + Removes and destroys the specified \a action. +*/ +void QQuickMenu::removeAction(QQuickAction *action) +{ + Q_D(QQuickMenu); + if (!action) + return; + + const int count = d->contentModel->count(); + for (int i = 0; i < count; ++i) { + QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(d->itemAt(i)); + if (!item || item->action() != action) + continue; + + removeItem(item); + break; + } + + action->deleteLater(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod Action QtQuick.Controls::Menu::takeAction(int index) + + Removes and returns the action at \a index. The index is within all items in the menu. + + \note The ownership of the action is transferred to the caller. +*/ +QQuickAction *QQuickMenu::takeAction(int index) +{ + Q_D(QQuickMenu); + QQuickMenuItem *item = qobject_cast<QQuickMenuItem *>(d->itemAt(index)); + if (!item) + return nullptr; + + QQuickAction *action = item->action(); + if (!action) + return nullptr; + + d->removeItem(index, item); + item->deleteLater(); + return action; +} + +/*! + \qmlproperty model QtQuick.Controls::Menu::contentModel + \readonly + + This property holds the model used to display menu items. + + The content model is provided for visualization purposes. It can be assigned + as a model to a content item that presents the contents of the menu. + + \code + Menu { + id: menu + contentItem: ListView { + model: menu.contentModel + } + } + \endcode + + The model allows menu items to be statically declared as children of the + menu. +*/ +QVariant QQuickMenu::contentModel() const +{ + Q_D(const QQuickMenu); + return QVariant::fromValue(d->contentModel); +} + +/*! + \qmlproperty list<Object> QtQuick.Controls::Menu::contentData + \qmldefault + + This property holds the list of content data. + + The list contains all objects that have been declared in QML as children + of the menu, and also items that have been dynamically added or + inserted using the \l addItem() and \l insertItem() methods, respectively. + + \note Unlike \c contentChildren, \c contentData does include non-visual QML + objects. It is not re-ordered when items are inserted or moved. + + \sa Item::data, {Popup::}{contentChildren} +*/ +QQmlListProperty<QObject> QQuickMenu::contentData() +{ + Q_D(QQuickMenu); + if (!d->contentItem) + QQuickControlPrivate::get(d->popupItem)->executeContentItem(); + return QQmlListProperty<QObject>(this, nullptr, + QQuickMenuPrivate::contentData_append, + QQuickMenuPrivate::contentData_count, + QQuickMenuPrivate::contentData_at, + QQuickMenuPrivate::contentData_clear); +} + +/*! + \qmlproperty string QtQuick.Controls::Menu::title + + This property holds the title for the menu. + + The title of a menu is often displayed in the text of a menu item when the + menu is a submenu, and in the text of a tool button when it is in a + menubar. +*/ +QString QQuickMenu::title() const +{ + Q_D(const QQuickMenu); + return d->title; +} + +void QQuickMenu::setTitle(QString &title) +{ + Q_D(QQuickMenu); + if (title == d->title) + return; + d->title = title; + emit titleChanged(title); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::Menu::cascade + + This property holds whether the menu cascades its sub-menus. + + The default value is platform-specific. Menus are cascading by default on + desktop platforms that have a mouse cursor available. Non-cascading menus + are shown one menu at a time, and centered over the parent menu. + + \note Changing the value of the property has no effect while the menu is open. + + \sa overlap +*/ +bool QQuickMenu::cascade() const +{ + Q_D(const QQuickMenu); + return d->cascade; +} + +void QQuickMenu::setCascade(bool cascade) +{ + Q_D(QQuickMenu); + if (d->cascade == cascade) + return; + d->cascade = cascade; + if (d->parentMenu) + d->resolveParentItem(); + emit cascadeChanged(cascade); +} + +void QQuickMenu::resetCascade() +{ + Q_D(QQuickMenu); + if (d->parentMenu) + setCascade(d->parentMenu->cascade()); + else + setCascade(shouldCascade()); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty real QtQuick.Controls::Menu::overlap + + This property holds the amount of pixels by which the menu horizontally overlaps its parent menu. + + The property only has effect when the menu is used as a cascading sub-menu. + + The default value is style-specific. + + \note Changing the value of the property has no effect while the menu is open. + + \sa cascade +*/ +qreal QQuickMenu::overlap() const +{ + Q_D(const QQuickMenu); + return d->overlap; +} + +void QQuickMenu::setOverlap(qreal overlap) +{ + Q_D(QQuickMenu); + if (d->overlap == overlap) + return; + d->overlap = overlap; + emit overlapChanged(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty Component QtQuick.Controls::Menu::delegate + + This property holds the component that is used to create items + to present actions. + + \code + Menu { + Action { text: "Cut" } + Action { text: "Copy" } + Action { text: "Paste" } + } + \endcode + + \sa Action +*/ +QQmlComponent *QQuickMenu::delegate() const +{ + Q_D(const QQuickMenu); + return d->delegate; +} + +void QQuickMenu::setDelegate(QQmlComponent *delegate) +{ + Q_D(QQuickMenu); + if (d->delegate == delegate) + return; + + d->delegate = delegate; + emit delegateChanged(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty int QtQuick.Controls::Menu::currentIndex + + This property holds the index of the currently highlighted item. + + Menu items can be highlighted by mouse hover or keyboard navigation. + + \sa MenuItem::highlighted +*/ +int QQuickMenu::currentIndex() const +{ + Q_D(const QQuickMenu); + return d->currentIndex; +} + +void QQuickMenu::setCurrentIndex(int index) +{ + Q_D(QQuickMenu); + d->setCurrentIndex(index, Qt::OtherFocusReason); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty int QtQuick.Controls::Menu::count + \readonly + + This property holds the number of items. +*/ +int QQuickMenu::count() const +{ + Q_D(const QQuickMenu); + return d->contentModel->count(); +} + +void QQuickMenu::popup(QQuickItem *menuItem) +{ + Q_D(QQuickMenu); + // No position has been explicitly specified, so position the menu at the mouse cursor + // on desktop platforms that have a mouse cursor available and support multiple windows. + QQmlNullableValue<QPointF> pos; +#if QT_CONFIG(cursor) + if (d->parentItem && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows)) + pos = d->parentItem->mapFromGlobal(QCursor::pos()); +#endif + + // As a fallback, center the menu over its parent item. + if (pos.isNull && d->parentItem) + pos = QPointF((d->parentItem->width() - width()) / 2, (d->parentItem->height() - height()) / 2); + + popup(pos.isNull ? QPointF() : pos.value, menuItem); +} + +void QQuickMenu::popup(const QPointF &pos, QQuickItem *menuItem) +{ + Q_D(QQuickMenu); + qreal offset = 0; +#if QT_CONFIG(cursor) + if (menuItem) + offset = d->popupItem->mapFromItem(menuItem, QPointF(0, 0)).y(); +#endif + setPosition(pos - QPointF(0, offset)); + + if (menuItem) + d->setCurrentIndex(d->contentModel->indexOf(menuItem, nullptr), Qt::PopupFocusReason); + open(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::popup(MenuItem item = null) + \qmlmethod void QtQuick.Controls::Menu::popup(Item parent, MenuItem item = null) + + Opens the menu at the mouse cursor on desktop platforms that have a mouse cursor + available, and otherwise centers the menu over its \a parent item. + + The menu can be optionally aligned to a specific menu \a item. + + \sa Popup::open() +*/ + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::popup(point pos, MenuItem item = null) + \qmlmethod void QtQuick.Controls::Menu::popup(Item parent, point pos, MenuItem item = null) + + Opens the menu at the specified position \a pos in the popups coordinate system, + that is, a coordinate relative to its \a parent item. + + The menu can be optionally aligned to a specific menu \a item. + + \sa Popup::open() +*/ + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::popup(real x, real y, MenuItem item = null) + \qmlmethod void QtQuick.Controls::Menu::popup(Item parent, real x, real y, MenuItem item = null) + + Opens the menu at the specified position \a x, \a y in the popups coordinate system, + that is, a coordinate relative to its \a parent item. + + The menu can be optionally aligned to a specific menu \a item. + + \sa dismiss(), Popup::open() +*/ +void QQuickMenu::popup(QQmlV4Function *args) +{ + Q_D(QQuickMenu); + const int len = args->length(); + if (len > 4) { + args->v4engine()->throwTypeError(); + return; + } + + QV4::ExecutionEngine *v4 = args->v4engine(); + QV4::Scope scope(v4); + + QQmlNullableValue<QPointF> pos; + QQuickItem *menuItem = nullptr; + QQuickItem *parentItem = nullptr; + + if (len > 0) { + // Item parent + QV4::ScopedValue firstArg(scope, (*args)[0]); + if (const QV4::QObjectWrapper *obj = firstArg->as<QV4::QObjectWrapper>()) { + QQuickItem *item = qobject_cast<QQuickItem *>(obj->object()); + if (item && !d->popupItem->isAncestorOf(item)) + parentItem = item; + } else if (firstArg->isUndefined()) { + resetParentItem(); + parentItem = d->parentItem; + } + + // MenuItem item + QV4::ScopedValue lastArg(scope, (*args)[len - 1]); + if (const QV4::QObjectWrapper *obj = lastArg->as<QV4::QObjectWrapper>()) { + QQuickItem *item = qobject_cast<QQuickItem *>(obj->object()); + if (item && d->popupItem->isAncestorOf(item)) + menuItem = item; + } + } + + if (len >= 3 || (!parentItem && len >= 2)) { + // real x, real y + QV4::ScopedValue xArg(scope, (*args)[parentItem ? 1 : 0]); + QV4::ScopedValue yArg(scope, (*args)[parentItem ? 2 : 1]); + if (xArg->isNumber() && yArg->isNumber()) + pos = QPointF(xArg->asDouble(), yArg->asDouble()); + } + + if (pos.isNull && (len >= 2 || (!parentItem && len >= 1))) { + // point pos + QV4::ScopedValue posArg(scope, (*args)[parentItem ? 1 : 0]); + const QVariant var = v4->toVariant(posArg, QMetaType {}); + if (var.userType() == QMetaType::QPointF) + pos = var.toPointF(); + } + + if (parentItem) + setParentItem(parentItem); + + if (pos.isNull) + popup(menuItem); + else + popup(pos, menuItem); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlmethod void QtQuick.Controls::Menu::dismiss() + + Closes all menus in the hierarchy that this menu belongs to. + + \note Unlike \l {Popup::}{close()} that only closes a menu and its sub-menus, + \c dismiss() closes the whole hierarchy of menus, including the parent menus. + In practice, \c close() is suitable e.g. for implementing navigation in a + hierarchy of menus, and \c dismiss() is the appropriate method for closing + the whole hierarchy of menus. + + \sa popup(), Popup::close() +*/ +void QQuickMenu::dismiss() +{ + QQuickMenu *menu = this; + while (menu) { + menu->close(); + menu = QQuickMenuPrivate::get(menu)->parentMenu; + } +} + +void QQuickMenu::componentComplete() +{ + Q_D(QQuickMenu); + QQuickPopup::componentComplete(); + d->resizeItems(); +} + +void QQuickMenu::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + Q_D(QQuickMenu); + QQuickPopup::contentItemChange(newItem, oldItem); + + if (oldItem) { + QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::Children); + QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::Geometry); + } + if (newItem) { + QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::Children); + QQuickItemPrivate::get(newItem)->updateOrAddGeometryChangeListener(d, QQuickGeometryChange::Width); + } + + d->contentItem = newItem; +} + +void QQuickMenu::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + Q_D(QQuickMenu); + QQuickPopup::itemChange(change, data); + + if (change == QQuickItem::ItemVisibleHasChanged) { + if (!data.boolValue && d->cascade) { + // Ensure that when the menu isn't visible, there's no current item + // the next time it's opened. + d->setCurrentIndex(-1, Qt::OtherFocusReason); + } + } +} + +void QQuickMenu::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickMenu); + QQuickPopup::keyPressEvent(event); + + // QTBUG-17051 + // Work around the fact that ListView has no way of distinguishing between + // mouse and keyboard interaction, thanks to the "interactive" bool in Flickable. + // What we actually want is to have a way to always allow keyboard interaction but + // only allow flicking with the mouse when there are too many menu items to be + // shown at once. + switch (event->key()) { + case Qt::Key_Up: + if (!d->activatePreviousItem()) + d->propagateKeyEvent(event); + break; + + case Qt::Key_Down: + d->activateNextItem(); + break; + + case Qt::Key_Left: + case Qt::Key_Right: + event->ignore(); + if (d->popupItem->isMirrored() == (event->key() == Qt::Key_Right)) { + if (d->parentMenu && d->currentItem) { + if (!d->cascade) + d->parentMenu->open(); + close(); + event->accept(); + } + } else { + if (QQuickMenu *subMenu = d->currentSubMenu()) { + auto subMenuPrivate = QQuickMenuPrivate::get(subMenu); + subMenu->popup(subMenuPrivate->firstEnabledMenuItem()); + event->accept(); + } + } + if (!event->isAccepted()) + d->propagateKeyEvent(event); + break; + +#if QT_CONFIG(shortcut) + case Qt::Key_Alt: + // If &mnemonic shortcut is enabled, go back to (possibly) the parent + // menu bar so the shortcut key will be processed by the menu bar. + if (!QKeySequence::mnemonic(QStringLiteral("&A")).isEmpty()) + close(); + break; +#endif + + default: + break; + } +} + +void QQuickMenu::timerEvent(QTimerEvent *event) +{ + Q_D(QQuickMenu); + if (event->timerId() == d->hoverTimer) { + if (QQuickMenu *subMenu = d->currentSubMenu()) + subMenu->open(); + d->stopHoverTimer(); + return; + } + QQuickPopup::timerEvent(event); +} + +QFont QQuickMenu::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::Menu); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickMenu::accessibleRole() const +{ + return QAccessible::PopupMenu; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickmenu_p.cpp" diff --git a/src/quicktemplates2/qquickmenu_p.h b/src/quicktemplates2/qquickmenu_p.h new file mode 100644 index 00000000000..4a690f9c8c9 --- /dev/null +++ b/src/quicktemplates2/qquickmenu_p.h @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMENU_P_H +#define QQUICKMENU_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/qqmllist.h> +#include <QtQml/qqml.h> + +#include "qquickpopup_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickAction; +class QQmlComponent; +class QQuickMenuItem; +class QQuickMenuPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenu : public QQuickPopup +{ + Q_OBJECT + Q_PROPERTY(QVariant contentModel READ contentModel CONSTANT FINAL) + Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL) + Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL) + // 2.3 (Qt 5.10) + Q_PROPERTY(int count READ count NOTIFY countChanged FINAL REVISION(2, 3)) + Q_PROPERTY(bool cascade READ cascade WRITE setCascade RESET resetCascade NOTIFY cascadeChanged FINAL REVISION(2, 3)) + Q_PROPERTY(qreal overlap READ overlap WRITE setOverlap NOTIFY overlapChanged FINAL REVISION(2, 3)) + Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL REVISION(2, 3)) + Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL REVISION(2, 3)) + Q_CLASSINFO("DefaultProperty", "contentData") + QML_NAMED_ELEMENT(Menu) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickMenu(QObject *parent = nullptr); + ~QQuickMenu(); + + Q_INVOKABLE QQuickItem *itemAt(int index) const; + Q_INVOKABLE void addItem(QQuickItem *item); + Q_INVOKABLE void insertItem(int index, QQuickItem *item); + Q_INVOKABLE void moveItem(int from, int to); + Q_INVOKABLE void removeItem(QQuickItem *item); + + QVariant contentModel() const; + QQmlListProperty<QObject> contentData(); + + QString title() const; + void setTitle(QString &title); + + bool cascade() const; + void setCascade(bool cascade); + void resetCascade(); + + qreal overlap() const; + void setOverlap(qreal overlap); + + QQmlComponent *delegate() const; + void setDelegate(QQmlComponent *delegate); + + int currentIndex() const; + void setCurrentIndex(int index); + + // 2.3 (Qt 5.10) + int count() const; + Q_REVISION(2, 3) Q_INVOKABLE QQuickItem *takeItem(int index); + + Q_REVISION(2, 3) Q_INVOKABLE QQuickMenu *menuAt(int index) const; + Q_REVISION(2, 3) Q_INVOKABLE void addMenu(QQuickMenu *menu); + Q_REVISION(2, 3) Q_INVOKABLE void insertMenu(int index, QQuickMenu *menu); + Q_REVISION(2, 3) Q_INVOKABLE void removeMenu(QQuickMenu *menu); + Q_REVISION(2, 3) Q_INVOKABLE QQuickMenu *takeMenu(int index); + + Q_REVISION(2, 3) Q_INVOKABLE QQuickAction *actionAt(int index) const; + Q_REVISION(2, 3) Q_INVOKABLE void addAction(QQuickAction *action); + Q_REVISION(2, 3) Q_INVOKABLE void insertAction(int index, QQuickAction *action); + Q_REVISION(2, 3) Q_INVOKABLE void removeAction(QQuickAction *action); + Q_REVISION(2, 3) Q_INVOKABLE QQuickAction *takeAction(int index); + + void popup(QQuickItem *menuItem = nullptr); + void popup(const QPointF &pos, QQuickItem *menuItem = nullptr); + + Q_REVISION(2, 3) Q_INVOKABLE void popup(QQmlV4Function *args); + Q_REVISION(2, 3) Q_INVOKABLE void dismiss(); + +protected: + void componentComplete() override; + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) override; + void keyPressEvent(QKeyEvent *event) override; + +Q_SIGNALS: + void titleChanged(const QString &title); + // 2.3 (Qt 5.10) + Q_REVISION(2, 3) void countChanged(); + Q_REVISION(2, 3) void cascadeChanged(bool cascade); + Q_REVISION(2, 3) void overlapChanged(); + Q_REVISION(2, 3) void delegateChanged(); + Q_REVISION(2, 3) void currentIndexChanged(); + +protected: + void timerEvent(QTimerEvent *event) override; + + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickMenu) + Q_DECLARE_PRIVATE(QQuickMenu) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickMenu) + +#endif // QQUICKMENU_P_H diff --git a/src/quicktemplates2/qquickmenu_p_p.h b/src/quicktemplates2/qquickmenu_p_p.h new file mode 100644 index 00000000000..86701d9bef8 --- /dev/null +++ b/src/quicktemplates2/qquickmenu_p_p.h @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMENU_P_P_H +#define QQUICKMENU_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qlist.h> +#include <QtCore/qpointer.h> + +#include <QtQuickTemplates2/private/qquickmenu_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickAction; +class QQmlComponent; +class QQmlObjectModel; +class QQuickMenuItem; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuPrivate : public QQuickPopupPrivate +{ + Q_DECLARE_PUBLIC(QQuickMenu) + +public: + QQuickMenuPrivate(); + + static QQuickMenuPrivate *get(QQuickMenu *menu) + { + return menu->d_func(); + } + + void init(); + + QQuickItem *itemAt(int index) const; + void insertItem(int index, QQuickItem *item); + void moveItem(int from, int to); + void removeItem(int index, QQuickItem *item); + + QQuickItem *beginCreateItem(); + void completeCreateItem(); + + QQuickItem *createItem(QQuickMenu *menu); + QQuickItem *createItem(QQuickAction *action); + + void resizeItem(QQuickItem *item); + void resizeItems(); + + void itemChildAdded(QQuickItem *item, QQuickItem *child) override; + void itemSiblingOrderChanged(QQuickItem *item) override; + void itemParentChanged(QQuickItem *item, QQuickItem *parent) override; + void itemDestroyed(QQuickItem *item) override; + void itemGeometryChanged(QQuickItem *, QQuickGeometryChange change, const QRectF &diff) override; + + QQuickPopupPositioner *getPositioner() override; + bool prepareEnterTransition() override; + bool prepareExitTransition() override; + bool blockInput(QQuickItem *item, const QPointF &point) const override; + + void onItemHovered(); + void onItemTriggered(); + void onItemActiveFocusChanged(); + + QQuickMenu *currentSubMenu() const; + void setParentMenu(QQuickMenu *parent); + void resolveParentItem(); + + void propagateKeyEvent(QKeyEvent *event); + + void startHoverTimer(); + void stopHoverTimer(); + + void setCurrentIndex(int index, Qt::FocusReason reason); + bool activateNextItem(); + bool activatePreviousItem(); + + QQuickMenuItem *firstEnabledMenuItem() const; + + static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj); + static qsizetype contentData_count(QQmlListProperty<QObject> *prop); + static QObject *contentData_at(QQmlListProperty<QObject> *prop, qsizetype index); + static void contentData_clear(QQmlListProperty<QObject> *prop); + + QPalette defaultPalette() const override; + + bool cascade = false; + int hoverTimer = 0; + int currentIndex = -1; + qreal overlap = 0; + QPointer<QQuickMenu> parentMenu; + QPointer<QQuickMenuItem> currentItem; + QQuickItem *contentItem = nullptr; // TODO: cleanup + QList<QObject *> contentData; + QQmlObjectModel *contentModel; + QQmlComponent *delegate = nullptr; + QString title; +}; + +QT_END_NAMESPACE + +#endif // QQUICKMENU_P_P_H diff --git a/src/quicktemplates2/qquickmenubar.cpp b/src/quicktemplates2/qquickmenubar.cpp new file mode 100644 index 00000000000..a732d889316 --- /dev/null +++ b/src/quicktemplates2/qquickmenubar.cpp @@ -0,0 +1,581 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmenubar_p.h" +#include "qquickmenubar_p_p.h" +#include "qquickmenubaritem_p_p.h" +#include "qquickmenu_p.h" +#include "qquickmenu_p_p.h" + +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlengine.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype MenuBar + \inherits Container +//! \instantiates QQuickMenuBar + \inqmlmodule QtQuick.Controls + \since 5.10 + \ingroup qtquickcontrols2-menus + \ingroup qtquickcontrols2-focusscopes + \brief Provides a window menu bar. + + \image qtquickcontrols2-menubar.png + + MenuBar consists of drop-down menus, and is normally located at the top + edge of the window. + + \quotefromfile qtquickcontrols2-menubar.qml + \skipuntil begin + \printto skipfrom + \skipuntil skipto + \printto end + + Typically, menus are statically declared as children of the menu bar, but + MenuBar also provides API to \l {addMenu}{add}, \l {insertMenu}{insert}, + \l {removeMenu}{remove}, and \l {takeMenu}{take} menus dynamically. The + menus in a menu bar can be accessed using \l menuAt(). + + \sa {Customizing MenuBar}, Menu, MenuBarItem, {Menu Controls}, + {Focus Management in Qt Quick Controls} +*/ + +QQuickItem *QQuickMenuBarPrivate::beginCreateItem(QQuickMenu *menu) +{ + Q_Q(QQuickMenuBar); + if (!delegate) + return nullptr; + + QQmlContext *creationContext = delegate->creationContext(); + if (!creationContext) + creationContext = qmlContext(q); + QQmlContext *context = new QQmlContext(creationContext, q); + context->setContextObject(q); + + QObject *object = delegate->beginCreate(context); + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (!item) { + delete object; + delete context; + return nullptr; + } + + if (QQuickMenuBarItem *menuBarItem = qobject_cast<QQuickMenuBarItem *>(item)) + menuBarItem->setMenu(menu); + item->setParentItem(q); + QQml_setParent_noEvent(item, q); + + return item; +} + +void QQuickMenuBarPrivate::completeCreateItem() +{ + if (!delegate) + return; + + delegate->completeCreate(); +} + +QQuickItem *QQuickMenuBarPrivate::createItem(QQuickMenu *menu) +{ + QQuickItem *item = beginCreateItem(menu); + completeCreateItem(); + return item; +} + +void QQuickMenuBarPrivate::toggleCurrentMenu(bool visible, bool activate) +{ + if (!currentItem || visible == popupMode) + return; + + QQuickMenu *menu = currentItem->menu(); + + triggering = true; + popupMode = visible; + if (menu) + menu->setVisible(visible); + if (!visible) + currentItem->forceActiveFocus(); + else if (menu && activate) + menu->setCurrentIndex(0); + triggering = false; +} + +void QQuickMenuBarPrivate::activateItem(QQuickMenuBarItem *item) +{ + if (currentItem == item) + return; + + if (currentItem) { + currentItem->setHighlighted(false); + if (popupMode) { + if (QQuickMenu *menu = currentItem->menu()) + menu->dismiss(); + } + } + + if (item) { + item->setHighlighted(true); + if (popupMode) { + if (QQuickMenu *menu = item->menu()) + menu->open(); + } + } + + currentItem = item; +} + +void QQuickMenuBarPrivate::activateNextItem() +{ + int index = currentItem ? contentModel->indexOf(currentItem, nullptr) : -1; + if (index >= contentModel->count() - 1) + index = -1; + activateItem(qobject_cast<QQuickMenuBarItem *>(itemAt(++index))); +} + +void QQuickMenuBarPrivate::activatePreviousItem() +{ + int index = currentItem ? contentModel->indexOf(currentItem, nullptr) : contentModel->count(); + if (index <= 0) + index = contentModel->count(); + activateItem(qobject_cast<QQuickMenuBarItem *>(itemAt(--index))); +} + +void QQuickMenuBarPrivate::onItemHovered() +{ + Q_Q(QQuickMenuBar); + QQuickMenuBarItem *item = qobject_cast<QQuickMenuBarItem *>(q->sender()); + if (!item || item == currentItem || !item->isHovered() || !item->isEnabled() || QQuickMenuBarItemPrivate::get(item)->touchId != -1) + return; + + activateItem(item); +} + +void QQuickMenuBarPrivate::onItemTriggered() +{ + Q_Q(QQuickMenuBar); + QQuickMenuBarItem *item = qobject_cast<QQuickMenuBarItem *>(q->sender()); + if (!item) + return; + + if (item == currentItem) { + toggleCurrentMenu(!popupMode, false); + } else { + popupMode = true; + activateItem(item); + } +} + +void QQuickMenuBarPrivate::onMenuAboutToHide() +{ + if (triggering || !currentItem || (currentItem->isHovered() && currentItem->isEnabled()) || !currentItem->isHighlighted()) + return; + + popupMode = false; + activateItem(nullptr); +} + +qreal QQuickMenuBarPrivate::getContentWidth() const +{ + Q_Q(const QQuickMenuBar); + const int count = contentModel->count(); + qreal totalWidth = qMax(0, count - 1) * spacing; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) + totalWidth += item->implicitWidth(); + } + return totalWidth; +} + +qreal QQuickMenuBarPrivate::getContentHeight() const +{ + Q_Q(const QQuickMenuBar); + const int count = contentModel->count(); + qreal maxHeight = 0; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) + maxHeight = qMax(maxHeight, item->implicitHeight()); + } + return maxHeight; +} + +void QQuickMenuBarPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + QQuickContainerPrivate::itemImplicitWidthChanged(item); + if (item != contentItem) + updateImplicitContentWidth(); +} + +void QQuickMenuBarPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + QQuickContainerPrivate::itemImplicitHeightChanged(item); + if (item != contentItem) + updateImplicitContentHeight(); +} + +void QQuickMenuBarPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj) +{ + QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object); + if (QQuickMenu *menu = qobject_cast<QQuickMenu *>(obj)) + obj = QQuickMenuBarPrivate::get(menuBar)->createItem(menu); + QQuickContainerPrivate::contentData_append(prop, obj); +} + +void QQuickMenuBarPrivate::menus_append(QQmlListProperty<QQuickMenu> *prop, QQuickMenu *obj) +{ + QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object); + menuBar->addMenu(obj); +} + +qsizetype QQuickMenuBarPrivate::menus_count(QQmlListProperty<QQuickMenu> *prop) +{ + QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object); + return menuBar->count(); +} + +QQuickMenu *QQuickMenuBarPrivate::menus_at(QQmlListProperty<QQuickMenu> *prop, qsizetype index) +{ + QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object); + return menuBar->menuAt(index); +} + +void QQuickMenuBarPrivate::menus_clear(QQmlListProperty<QQuickMenu> *prop) +{ + QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object); + QQuickMenuBarPrivate::get(menuBar)->contentModel->clear(); +} + +QPalette QQuickMenuBarPrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::MenuBar); +} + +QQuickMenuBar::QQuickMenuBar(QQuickItem *parent) + : QQuickContainer(*(new QQuickMenuBarPrivate), parent) +{ + Q_D(QQuickMenuBar); + d->changeTypes |= QQuickItemPrivate::Geometry; + setFlag(ItemIsFocusScope); + setFocusPolicy(Qt::ClickFocus); +} + +/*! + \qmlproperty Component QtQuick.Controls::MenuBar::delegate + + This property holds the component that is used to create menu bar + items to present menus in the menu bar. + + \sa MenuBarItem +*/ +QQmlComponent *QQuickMenuBar::delegate() const +{ + Q_D(const QQuickMenuBar); + return d->delegate; +} + +void QQuickMenuBar::setDelegate(QQmlComponent *delegate) +{ + Q_D(QQuickMenuBar); + if (d->delegate == delegate) + return; + + d->delegate = delegate; + emit delegateChanged(); +} + +/*! + \qmlmethod Menu QtQuick.Controls::MenuBar::menuAt(int index) + + Returns the menu at \a index, or \c null if it does not exist. +*/ +QQuickMenu *QQuickMenuBar::menuAt(int index) const +{ + Q_D(const QQuickMenuBar); + QQuickMenuBarItem *item = qobject_cast<QQuickMenuBarItem *>(d->itemAt(index)); + if (!item) + return nullptr; + return item->menu(); +} + +/*! + \qmlmethod void QtQuick.Controls::MenuBar::addMenu(Menu menu) + + Adds \a menu to the end of the list of menus. +*/ +void QQuickMenuBar::addMenu(QQuickMenu *menu) +{ + Q_D(QQuickMenuBar); + addItem(d->createItem(menu)); +} + +/*! + \qmlmethod void QtQuick.Controls::MenuBar::insertMenu(int index, Menu menu) + + Inserts \a menu at \a index. +*/ +void QQuickMenuBar::insertMenu(int index, QQuickMenu *menu) +{ + Q_D(QQuickMenuBar); + insertItem(index, d->createItem(menu)); +} + +/*! + \qmlmethod void QtQuick.Controls::MenuBar::removeMenu(Menu menu) + + Removes and destroys the specified \a menu. +*/ +void QQuickMenuBar::removeMenu(QQuickMenu *menu) +{ + Q_D(QQuickMenuBar); + if (!menu) + return; + + const int count = d->contentModel->count(); + for (int i = 0; i < count; ++i) { + QQuickMenuBarItem *item = qobject_cast<QQuickMenuBarItem *>(itemAt(i)); + if (!item || item->menu() != menu) + continue; + + removeItem(item); + break; + } + + menu->deleteLater(); +} + +/*! + \qmlmethod Menu QtQuick.Controls::MenuBar::takeMenu(int index) + + Removes and returns the menu at \a index. + + \note The ownership of the item is transferred to the caller. +*/ +QQuickMenu *QQuickMenuBar::takeMenu(int index) +{ + Q_D(QQuickMenuBar); + QQuickMenuBarItem *item = qobject_cast<QQuickMenuBarItem *>(itemAt(index)); + if (!item) + return nullptr; + + QQuickMenu *menu = item->menu(); + if (!menu) + return nullptr; + + d->removeItem(index, item); + item->deleteLater(); + return menu; +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty real QtQuick.Controls::MenuBar::contentWidth + + This property holds the content width. It is used for calculating the total + implicit width of the menu bar. + + \note This property is available in MenuBar since QtQuick.Controls 2.3 (Qt 5.10), + but it was promoted to the Container base type in QtQuick.Controls 2.5 (Qt 5.12). + + \sa Container::contentWidth +*/ + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty real QtQuick.Controls::MenuBar::contentHeight + + This property holds the content height. It is used for calculating the total + implicit height of the menu bar. + + \note This property is available in MenuBar since QtQuick.Controls 2.3 (Qt 5.10), + but it was promoted to the Container base type in QtQuick.Controls 2.5 (Qt 5.12). + + \sa Container::contentHeight +*/ + +/*! + \qmlproperty list<Menu> QtQuick.Controls::MenuBar::menus + + This property holds the list of menus. + + The list contains all menus that have been declared in QML as children + of the menu bar, and also menus that have been dynamically added or + inserted using the \l addMenu() and \l insertMenu() methods, respectively. +*/ +QQmlListProperty<QQuickMenu> QQuickMenuBarPrivate::menus() +{ + Q_Q(QQuickMenuBar); + return QQmlListProperty<QQuickMenu>(q, nullptr, + QQuickMenuBarPrivate::menus_append, + QQuickMenuBarPrivate::menus_count, + QQuickMenuBarPrivate::menus_at, + QQuickMenuBarPrivate::menus_clear); +} + +QQmlListProperty<QObject> QQuickMenuBarPrivate::contentData() +{ + Q_Q(QQuickMenuBar); + return QQmlListProperty<QObject>(q, nullptr, + QQuickMenuBarPrivate::contentData_append, + QQuickContainerPrivate::contentData_count, + QQuickContainerPrivate::contentData_at, + QQuickContainerPrivate::contentData_clear); +} + +bool QQuickMenuBar::eventFilter(QObject *object, QEvent *event) +{ + return QObject::eventFilter(object, event); +} + +void QQuickMenuBar::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickMenuBar); + QQuickContainer::keyReleaseEvent(event); + + switch (event->key()) { + case Qt::Key_Up: + d->toggleCurrentMenu(false, false); + break; + + case Qt::Key_Down: + d->toggleCurrentMenu(true, true); + break; + + case Qt::Key_Left: + case Qt::Key_Right: + if (isMirrored() == (event->key() == Qt::Key_Left)) + d->activateNextItem(); + else + d->activatePreviousItem(); + break; + case Qt::Key_Escape: + if (d->currentItem) { + d->activateItem(nullptr); + setFocus(false); + } + break; + default: + break; + } +} + +void QQuickMenuBar::keyReleaseEvent(QKeyEvent *event) +{ + QQuickContainer::keyReleaseEvent(event); + + switch (event->key()) { + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Escape: + event->accept(); + break; + + default: + event->ignore(); + break; + } +} + +void QQuickMenuBar::hoverLeaveEvent(QHoverEvent *event) +{ + Q_D(QQuickMenuBar); + QQuickContainer::hoverLeaveEvent(event); + if (!d->popupMode && d->currentItem) + d->activateItem(nullptr); +} + +bool QQuickMenuBar::isContent(QQuickItem *item) const +{ + return qobject_cast<QQuickMenuBarItem *>(item); +} + +void QQuickMenuBar::itemAdded(int index, QQuickItem *item) +{ + Q_D(QQuickMenuBar); + QQuickContainer::itemAdded(index, item); + if (QQuickMenuBarItem *menuBarItem = qobject_cast<QQuickMenuBarItem *>(item)) { + QQuickMenuBarItemPrivate::get(menuBarItem)->setMenuBar(this); + QObjectPrivate::connect(menuBarItem, &QQuickControl::hoveredChanged, d, &QQuickMenuBarPrivate::onItemHovered); + QObjectPrivate::connect(menuBarItem, &QQuickMenuBarItem::triggered, d, &QQuickMenuBarPrivate::onItemTriggered); + if (QQuickMenu *menu = menuBarItem->menu()) + QObjectPrivate::connect(menu, &QQuickPopup::aboutToHide, d, &QQuickMenuBarPrivate::onMenuAboutToHide); + } + d->updateImplicitContentSize(); + emit menusChanged(); +} + +void QQuickMenuBar::itemMoved(int index, QQuickItem *item) +{ + QQuickContainer::itemMoved(index, item); + emit menusChanged(); +} + +void QQuickMenuBar::itemRemoved(int index, QQuickItem *item) +{ + Q_D(QQuickMenuBar); + QQuickContainer::itemRemoved(index, item); + if (QQuickMenuBarItem *menuBarItem = qobject_cast<QQuickMenuBarItem *>(item)) { + QQuickMenuBarItemPrivate::get(menuBarItem)->setMenuBar(nullptr); + QObjectPrivate::disconnect(menuBarItem, &QQuickControl::hoveredChanged, d, &QQuickMenuBarPrivate::onItemHovered); + QObjectPrivate::disconnect(menuBarItem, &QQuickMenuBarItem::triggered, d, &QQuickMenuBarPrivate::onItemTriggered); + if (QQuickMenu *menu = menuBarItem->menu()) + QObjectPrivate::disconnect(menu, &QQuickPopup::aboutToHide, d, &QQuickMenuBarPrivate::onMenuAboutToHide); + } + d->updateImplicitContentSize(); + emit menusChanged(); +} + +QFont QQuickMenuBar::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::MenuBar); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickMenuBar::accessibleRole() const +{ + return QAccessible::MenuBar; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickmenubar_p.cpp" diff --git a/src/quicktemplates2/qquickmenubar_p.h b/src/quicktemplates2/qquickmenubar_p.h new file mode 100644 index 00000000000..5eb5dabfdd0 --- /dev/null +++ b/src/quicktemplates2/qquickmenubar_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMENUBAR_P_H +#define QQUICKMENUBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontainer_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickMenu; +class QQuickMenuBarPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuBar : public QQuickContainer +{ + Q_OBJECT + Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL) + Q_PRIVATE_PROPERTY(QQuickMenuBar::d_func(), QQmlListProperty<QQuickMenu> menus READ menus NOTIFY menusChanged FINAL) + Q_PRIVATE_PROPERTY(QQuickMenuBar::d_func(), QQmlListProperty<QObject> contentData READ contentData FINAL) + QML_NAMED_ELEMENT(MenuBar) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickMenuBar(QQuickItem *parent = nullptr); + + QQmlComponent *delegate() const; + void setDelegate(QQmlComponent *delegate); + + Q_INVOKABLE QQuickMenu *menuAt(int index) const; + Q_INVOKABLE void addMenu(QQuickMenu *menu); + Q_INVOKABLE void insertMenu(int index, QQuickMenu *menu); + Q_INVOKABLE void removeMenu(QQuickMenu *menu); + Q_INVOKABLE QQuickMenu *takeMenu(int index); + +Q_SIGNALS: + void delegateChanged(); + void menusChanged(); + +protected: + bool eventFilter(QObject *object, QEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void keyReleaseEvent(QKeyEvent *event) override; + void hoverLeaveEvent(QHoverEvent *event) override; + + bool isContent(QQuickItem *item) const override; + void itemAdded(int index, QQuickItem *item) override; + void itemMoved(int index, QQuickItem *item) override; + void itemRemoved(int index, QQuickItem *item) override; + + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickMenuBar) + Q_DECLARE_PRIVATE(QQuickMenuBar) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickMenuBar) + +#endif // QQUICKMENUBAR_P_H diff --git a/src/quicktemplates2/qquickmenubar_p_p.h b/src/quicktemplates2/qquickmenubar_p_p.h new file mode 100644 index 00000000000..0562d7e5dc1 --- /dev/null +++ b/src/quicktemplates2/qquickmenubar_p_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMENUBAR_P_P_H +#define QQUICKMENUBAR_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickmenubar_p.h> +#include <QtQuickTemplates2/private/qquickcontainer_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQmlComponent; +class QQuickMenuBarItem; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuBarPrivate : public QQuickContainerPrivate +{ + Q_DECLARE_PUBLIC(QQuickMenuBar) + +public: + static QQuickMenuBarPrivate *get(QQuickMenuBar *menuBar) + { + return menuBar->d_func(); + } + + QQmlListProperty<QQuickMenu> menus(); + QQmlListProperty<QObject> contentData(); + + QQuickItem *beginCreateItem(QQuickMenu *menu); + void completeCreateItem(); + + QQuickItem *createItem(QQuickMenu *menu); + + void toggleCurrentMenu(bool visible, bool activate); + void activateItem(QQuickMenuBarItem *item); + void activateNextItem(); + void activatePreviousItem(); + + void onItemHovered(); + void onItemTriggered(); + void onMenuAboutToHide(); + + qreal getContentWidth() const override; + qreal getContentHeight() const override; + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj); + + static void menus_append(QQmlListProperty<QQuickMenu> *prop, QQuickMenu *obj); + static qsizetype menus_count(QQmlListProperty<QQuickMenu> *prop); + static QQuickMenu *menus_at(QQmlListProperty<QQuickMenu> *prop, qsizetype index); + static void menus_clear(QQmlListProperty<QQuickMenu> *prop); + + QPalette defaultPalette() const override; + + bool popupMode = false; + bool triggering = false; + QQmlComponent *delegate = nullptr; + QPointer<QQuickMenuBarItem> currentItem; +}; + +QT_END_NAMESPACE + +#endif // QQUICKMENUBAR_P_P_H diff --git a/src/quicktemplates2/qquickmenubaritem.cpp b/src/quicktemplates2/qquickmenubaritem.cpp new file mode 100644 index 00000000000..de43adb6a3f --- /dev/null +++ b/src/quicktemplates2/qquickmenubaritem.cpp @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmenubaritem_p.h" +#include "qquickmenubaritem_p_p.h" +#include "qquickmenubar_p.h" +#include "qquickmenu_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype MenuBarItem + \inherits AbstractButton +//! \instantiates QQuickMenuBarItem + \inqmlmodule QtQuick.Controls + \since 5.10 + \ingroup qtquickcontrols2-menus + \brief Presents a drop-down menu within a MenuBar. + + MenuBarItem presents a Menu within a MenuBar. The respective drop-down menu + is shown when a MenuBarItem is \l triggered via keyboard, mouse, or touch. + + \image qtquickcontrols2-menubar.png + + MenuBarItem is used as a default \l {MenuBar::}{delegate} type for MenuBar. + Notice that it is not necessary to declare MenuBarItem instances by hand when + using MenuBar. It is sufficient to declare Menu instances as children of the + MenuBar and the respective items are created automatically. + + \sa {Customizing MenuBar}, MenuBar, {Menu Controls} +*/ + +/*! + \qmlsignal void QtQuick.Controls::MenuBarItem::triggered() + + This signal is emitted when the menu bar item is triggered by the user. +*/ + +void QQuickMenuBarItemPrivate::setMenuBar(QQuickMenuBar *newMenuBar) +{ + Q_Q(QQuickMenuBarItem); + if (menuBar == newMenuBar) + return; + + menuBar = newMenuBar; + emit q->menuBarChanged(); +} + +QPalette QQuickMenuBarItemPrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::MenuBar); +} + +QQuickMenuBarItem::QQuickMenuBarItem(QQuickItem *parent) + : QQuickAbstractButton(*(new QQuickMenuBarItemPrivate), parent) +{ + setFocusPolicy(Qt::NoFocus); + connect(this, &QQuickAbstractButton::clicked, this, &QQuickMenuBarItem::triggered); +} + +/*! + \qmlproperty Menu QtQuick.Controls::MenuBarItem::menuBar + \readonly + + This property holds the menu bar that contains this item, + or \c null if the item is not in a menu bar. +*/ +QQuickMenuBar *QQuickMenuBarItem::menuBar() const +{ + Q_D(const QQuickMenuBarItem); + return d->menuBar; +} + +/*! + \qmlproperty Menu QtQuick.Controls::MenuBarItem::menu + + This property holds the menu that this item presents in a + menu bar, or \c null if this item does not have a menu. +*/ +QQuickMenu *QQuickMenuBarItem::menu() const +{ + Q_D(const QQuickMenuBarItem); + return d->menu; +} + +void QQuickMenuBarItem::setMenu(QQuickMenu *menu) +{ + Q_D(QQuickMenuBarItem); + if (d->menu == menu) + return; + + if (d->menu) + disconnect(d->menu, &QQuickMenu::titleChanged, this, &QQuickAbstractButton::setText); + + if (menu) { + setText(menu->title()); + menu->setY(height()); + menu->setParentItem(this); + menu->setClosePolicy(QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutsideParent | QQuickPopup::CloseOnReleaseOutsideParent); + connect(menu, &QQuickMenu::titleChanged, this, &QQuickAbstractButton::setText); + } + + d->menu = menu; + emit menuChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::MenuBarItem::highlighted + + This property holds whether the menu bar item is highlighted by the user. + + A menu bar item can be highlighted by mouse hover or keyboard navigation. + + The default value is \c false. +*/ +bool QQuickMenuBarItem::isHighlighted() const +{ + Q_D(const QQuickMenuBarItem); + return d->highlighted; +} + +void QQuickMenuBarItem::setHighlighted(bool highlighted) +{ + Q_D(QQuickMenuBarItem); + if (highlighted == d->highlighted) + return; + + d->highlighted = highlighted; + emit highlightedChanged(); +} + +void QQuickMenuBarItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickMenuBarItem); + QQuickAbstractButton::geometryChange(newGeometry, oldGeometry); + if (d->menu) + d->menu->setY(newGeometry.height()); +} + +QFont QQuickMenuBarItem::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::MenuBar); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickMenuBarItem::accessibleRole() const +{ + return QAccessible::MenuBar; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickmenubaritem_p.cpp" diff --git a/src/quicktemplates2/qquickmenubaritem_p.h b/src/quicktemplates2/qquickmenubaritem_p.h new file mode 100644 index 00000000000..a913f242bba --- /dev/null +++ b/src/quicktemplates2/qquickmenubaritem_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMENUBARITEM_P_H +#define QQUICKMENUBARITEM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickMenu; +class QQuickMenuBar; +class QQuickMenuBarItemPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuBarItem : public QQuickAbstractButton +{ + Q_OBJECT + Q_PROPERTY(QQuickMenuBar *menuBar READ menuBar NOTIFY menuBarChanged FINAL) + Q_PROPERTY(QQuickMenu *menu READ menu WRITE setMenu NOTIFY menuChanged FINAL) + Q_PROPERTY(bool highlighted READ isHighlighted WRITE setHighlighted NOTIFY highlightedChanged FINAL) + QML_NAMED_ELEMENT(MenuBarItem) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickMenuBarItem(QQuickItem *parent = nullptr); + + QQuickMenuBar *menuBar() const; + + QQuickMenu *menu() const; + void setMenu(QQuickMenu *menu); + + bool isHighlighted() const; + void setHighlighted(bool highlighted); + +Q_SIGNALS: + void triggered(); + void menuBarChanged(); + void menuChanged(); + void highlightedChanged(); + +protected: + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickMenuBarItem) + Q_DECLARE_PRIVATE(QQuickMenuBarItem) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickMenuBarItem) + +#endif // QQUICKMENUBARITEM_P_H diff --git a/src/quicktemplates2/qquickmenubaritem_p_p.h b/src/quicktemplates2/qquickmenubaritem_p_p.h new file mode 100644 index 00000000000..22c509dcfb1 --- /dev/null +++ b/src/quicktemplates2/qquickmenubaritem_p_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMENUBARITEM_P_P_H +#define QQUICKMENUBARITEM_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickmenubaritem_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickMenu; +class QQuickMenuBar; + +class QQuickMenuBarItemPrivate : public QQuickAbstractButtonPrivate +{ + Q_DECLARE_PUBLIC(QQuickMenuBarItem) + +public: + static QQuickMenuBarItemPrivate *get(QQuickMenuBarItem *item) + { + return item->d_func(); + } + + void setMenuBar(QQuickMenuBar *menuBar); + + QPalette defaultPalette() const override; + + bool highlighted = false; + QQuickMenu *menu = nullptr; + QQuickMenuBar *menuBar = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKMENUBARITEM_P_P_H diff --git a/src/quicktemplates2/qquickmenuitem.cpp b/src/quicktemplates2/qquickmenuitem.cpp new file mode 100644 index 00000000000..559024416ba --- /dev/null +++ b/src/quicktemplates2/qquickmenuitem.cpp @@ -0,0 +1,281 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmenuitem_p.h" +#include "qquickmenuitem_p_p.h" +#include "qquickmenu_p.h" +#include "qquickdeferredexecute_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> +#include <QtQuick/private/qquickevents_p_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype MenuItem + \inherits AbstractButton +//! \instantiates QQuickMenuItem + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-menus + \brief Presents an item within a Menu. + + MenuItem is a convenience type that implements the AbstractButton API, + providing a familiar way to respond to menu items being \l triggered, for + example. + + MenuItem inherits its API from AbstractButton. For instance, you can set + \l {AbstractButton::text}{text} and \l {Icons in Qt Quick Controls}{icon} + using the AbstractButton API. + + \code + Button { + id: fileButton + text: "File" + onClicked: menu.open() + + Menu { + id: menu + + MenuItem { + text: "New..." + onTriggered: document.reset() + } + MenuItem { + text: "Open..." + onTriggered: openDialog.open() + } + MenuItem { + text: "Save" + onTriggered: saveDialog.open() + } + } + } + \endcode + + \sa {Customizing Menu}, Menu, {Menu Controls} +*/ + +void QQuickMenuItemPrivate::setMenu(QQuickMenu *newMenu) +{ + Q_Q(QQuickMenuItem); + if (menu == newMenu) + return; + + menu = newMenu; + emit q->menuChanged(); +} + +void QQuickMenuItemPrivate::setSubMenu(QQuickMenu *newSubMenu) +{ + Q_Q(QQuickMenuItem); + if (subMenu == newSubMenu) + return; + + if (subMenu) { + QObject::disconnect(subMenu, &QQuickMenu::titleChanged, q, &QQuickAbstractButton::setText); + QObjectPrivate::disconnect(subMenu, &QQuickPopup::enabledChanged, this, &QQuickMenuItemPrivate::updateEnabled); + } + + if (newSubMenu) { + QObject::connect(newSubMenu, &QQuickMenu::titleChanged, q, &QQuickAbstractButton::setText); + QObjectPrivate::connect(newSubMenu, &QQuickPopup::enabledChanged, this, &QQuickMenuItemPrivate::updateEnabled); + q->setText(newSubMenu->title()); + } + + subMenu = newSubMenu; + updateEnabled(); + emit q->subMenuChanged(); +} + +void QQuickMenuItemPrivate::updateEnabled() +{ + Q_Q(QQuickMenuItem); + q->setEnabled(subMenu && subMenu->isEnabled()); +} + +static inline QString arrowName() { return QStringLiteral("arrow"); } + +void QQuickMenuItemPrivate::cancelArrow() +{ + Q_Q(QQuickAbstractButton); + quickCancelDeferred(q, arrowName()); +} + +void QQuickMenuItemPrivate::executeArrow(bool complete) +{ + Q_Q(QQuickMenuItem); + if (arrow.wasExecuted()) + return; + + if (!arrow || complete) + quickBeginDeferred(q, arrowName(), arrow); + if (complete) + quickCompleteDeferred(q, arrowName(), arrow); +} + +bool QQuickMenuItemPrivate::acceptKeyClick(Qt::Key key) const +{ + return key == Qt::Key_Space || key == Qt::Key_Return || key == Qt::Key_Enter; +} + +QPalette QQuickMenuItemPrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::Menu); +} + +/*! + \qmlsignal void QtQuick.Controls::MenuItem::triggered() + + This signal is emitted when the menu item is triggered by the user. +*/ + +QQuickMenuItem::QQuickMenuItem(QQuickItem *parent) + : QQuickAbstractButton(*(new QQuickMenuItemPrivate), parent) +{ + connect(this, &QQuickAbstractButton::clicked, this, &QQuickMenuItem::triggered); +} + +/*! + \qmlproperty bool QtQuick.Controls::MenuItem::highlighted + + This property holds whether the menu item is highlighted by the user. + + A menu item can be highlighted by mouse hover or keyboard navigation. + + The default value is \c false. + + \sa Menu::currentIndex +*/ +bool QQuickMenuItem::isHighlighted() const +{ + Q_D(const QQuickMenuItem); + return d->highlighted; +} + +void QQuickMenuItem::setHighlighted(bool highlighted) +{ + Q_D(QQuickMenuItem); + if (highlighted == d->highlighted) + return; + + d->highlighted = highlighted; + emit highlightedChanged(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty Item QtQuick.Controls::MenuItem::arrow + + This property holds the sub-menu arrow item. + + \sa {Customizing Menu} +*/ +QQuickItem *QQuickMenuItem::arrow() const +{ + QQuickMenuItemPrivate *d = const_cast<QQuickMenuItemPrivate *>(d_func()); + if (!d->arrow) + d->executeArrow(); + return d->arrow; +} + +void QQuickMenuItem::setArrow(QQuickItem *arrow) +{ + Q_D(QQuickMenuItem); + if (d->arrow == arrow) + return; + + if (!d->arrow.isExecuting()) + d->cancelArrow(); + + QQuickControlPrivate::hideOldItem(d->arrow); + d->arrow = arrow; + if (arrow && !arrow->parentItem()) + arrow->setParentItem(this); + if (!d->arrow.isExecuting()) + emit arrowChanged(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty Menu QtQuick.Controls::MenuItem::menu + \readonly + + This property holds the menu that contains this menu item, + or \c null if the item is not in a menu. +*/ +QQuickMenu *QQuickMenuItem::menu() const +{ + Q_D(const QQuickMenuItem); + return d->menu; +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty Menu QtQuick.Controls::MenuItem::subMenu + \readonly + + This property holds the sub-menu that this item presents in + the parent menu, or \c null if this item is not a sub-menu item. +*/ +QQuickMenu *QQuickMenuItem::subMenu() const +{ + Q_D(const QQuickMenuItem); + return d->subMenu; +} + +void QQuickMenuItem::componentComplete() +{ + Q_D(QQuickMenuItem); + d->executeArrow(true); + QQuickAbstractButton::componentComplete(); +} + +QFont QQuickMenuItem::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::Menu); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickMenuItem::accessibleRole() const +{ + return QAccessible::MenuItem; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickmenuitem_p.cpp" diff --git a/src/quicktemplates2/qquickmenuitem_p.h b/src/quicktemplates2/qquickmenuitem_p.h new file mode 100644 index 00000000000..817da76bba4 --- /dev/null +++ b/src/quicktemplates2/qquickmenuitem_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMENUITEM_P_H +#define QQUICKMENUITEM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickMenu; +class QQuickMenuItemPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuItem : public QQuickAbstractButton +{ + Q_OBJECT + Q_PROPERTY(bool highlighted READ isHighlighted WRITE setHighlighted NOTIFY highlightedChanged FINAL) + // 2.3 (Qt 5.10) + Q_PROPERTY(QQuickItem *arrow READ arrow WRITE setArrow NOTIFY arrowChanged FINAL REVISION(2, 3)) + Q_PROPERTY(QQuickMenu *menu READ menu NOTIFY menuChanged FINAL REVISION(2, 3)) + Q_PROPERTY(QQuickMenu *subMenu READ subMenu NOTIFY subMenuChanged FINAL REVISION(2, 3)) + Q_CLASSINFO("DeferredPropertyNames", "arrow,background,contentItem,indicator") + QML_NAMED_ELEMENT(MenuItem) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickMenuItem(QQuickItem *parent = nullptr); + + bool isHighlighted() const; + void setHighlighted(bool highlighted); + + // 2.3 (Qt 5.10) + QQuickItem *arrow() const; + void setArrow(QQuickItem *arrow); + + QQuickMenu *menu() const; + QQuickMenu *subMenu() const; + +Q_SIGNALS: + void triggered(); + void highlightedChanged(); + // 2.3 (Qt 5.10) + Q_REVISION(2, 3) void arrowChanged(); + Q_REVISION(2, 3) void menuChanged(); + Q_REVISION(2, 3) void subMenuChanged(); + +protected: + void componentComplete() override; + + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickMenuItem) + Q_DECLARE_PRIVATE(QQuickMenuItem) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickMenuItem) + +#endif // QQUICKMENUITEM_P_H diff --git a/src/quicktemplates2/qquickmenuitem_p_p.h b/src/quicktemplates2/qquickmenuitem_p_p.h new file mode 100644 index 00000000000..966e14e7e9e --- /dev/null +++ b/src/quicktemplates2/qquickmenuitem_p_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMENUITEM_P_P_H +#define QQUICKMENUITEM_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickmenuitem_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickMenu; + +class QQuickMenuItemPrivate : public QQuickAbstractButtonPrivate +{ + Q_DECLARE_PUBLIC(QQuickMenuItem) + +public: + static QQuickMenuItemPrivate *get(QQuickMenuItem *item) + { + return item->d_func(); + } + + void setMenu(QQuickMenu *menu); + void setSubMenu(QQuickMenu *subMenu); + + void updateEnabled(); + + void cancelArrow(); + void executeArrow(bool complete = false); + + bool acceptKeyClick(Qt::Key key) const override; + + QPalette defaultPalette() const override; + + bool highlighted = false; + QQuickDeferredPointer<QQuickItem> arrow; + QQuickMenu *menu = nullptr; + QQuickMenu *subMenu = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKMENUITEM_P_P_H diff --git a/src/quicktemplates2/qquickmenuseparator.cpp b/src/quicktemplates2/qquickmenuseparator.cpp new file mode 100644 index 00000000000..d646ed437d6 --- /dev/null +++ b/src/quicktemplates2/qquickmenuseparator.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickmenuseparator_p.h" +#include "qquickcontrol_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype MenuSeparator + \inherits Control +//! \instantiates QQuickMenuSeparator + \inqmlmodule QtQuick.Controls + \since 5.8 + \ingroup qtquickcontrols2-separators + \brief Separates a group of items in a menu from adjacent items. + + MenuSeparator is used to visually distinguish between groups of items in a + menu by separating them with a line. + + \image qtquickcontrols2-menuseparator.png + + \quotefromfile qtquickcontrols2-menuseparator-custom.qml + \skipto import QtQuick + \printuntil import QtQuick.Controls + \skipto Menu + \printto contentItem.parent: window + \skipline contentItem.parent: window + \printuntil text: qsTr("Exit") + \printuntil } + \printuntil } + + \sa {Customizing Menu}, Menu, {Separator Controls} +*/ + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuSeparatorPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickMenuSeparator) + +public: + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::Menu); } +}; + +QQuickMenuSeparator::QQuickMenuSeparator(QQuickItem *parent) + : QQuickControl(*(new QQuickMenuSeparatorPrivate), parent) +{ +} + +QFont QQuickMenuSeparator::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::Menu); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickMenuSeparator::accessibleRole() const +{ + return QAccessible::Separator; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickmenuseparator_p.cpp" diff --git a/src/quicktemplates2/qquickmenuseparator_p.h b/src/quicktemplates2/qquickmenuseparator_p.h new file mode 100644 index 00000000000..330aaac40bb --- /dev/null +++ b/src/quicktemplates2/qquickmenuseparator_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKMENUSEPARATOR_P_H +#define QQUICKMENUSEPARATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickMenuSeparator; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuSeparator : public QQuickControl +{ + Q_OBJECT + QML_NAMED_ELEMENT(MenuSeparator) + QML_ADDED_IN_VERSION(2, 1) + +public: + explicit QQuickMenuSeparator(QQuickItem *parent = nullptr); + +protected: + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickMenuSeparator) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickMenuSeparator) + +#endif // QQUICKMENUSEPARATOR_P_H diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp new file mode 100644 index 00000000000..1829f9a30e7 --- /dev/null +++ b/src/quicktemplates2/qquickoverlay.cpp @@ -0,0 +1,763 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcontrol_p_p.h" +#include "qquickoverlay_p.h" +#include "qquickoverlay_p_p.h" +#include "qquickpopupitem_p_p.h" +#include "qquickpopup_p_p.h" +#include "qquickdrawer_p.h" +#include "qquickdrawer_p_p.h" +#include "qquickapplicationwindow_p.h" +#include <QtQml/qqmlinfo.h> +#include <QtQml/qqmlproperty.h> +#include <QtQml/qqmlcomponent.h> +#include <algorithm> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Overlay + \inherits Item +//! \instantiates QQuickOverlay + \inqmlmodule QtQuick.Controls + \since 5.10 + \brief A window overlay for popups. + + Overlay provides a layer for popups, ensuring that popups are displayed above + other content and that the background is dimmed when a \l {Popup::}{modal} or + \l {Popup::dim}{dimmed} popup is visible. + + The overlay is an ordinary Item that covers the entire window. It can be used + as a visual parent to position a popup in scene coordinates. + + \include qquickoverlay-popup-parent.qdocinc + + \sa ApplicationWindow +*/ + +QList<QQuickPopup *> QQuickOverlayPrivate::stackingOrderPopups() const +{ + const QList<QQuickItem *> children = paintOrderChildItems(); + + QList<QQuickPopup *> popups; + popups.reserve(children.count()); + + for (auto it = children.crbegin(), end = children.crend(); it != end; ++it) { + QQuickPopup *popup = qobject_cast<QQuickPopup *>((*it)->parent()); + if (popup) + popups += popup; + } + + return popups; +} + +QList<QQuickDrawer *> QQuickOverlayPrivate::stackingOrderDrawers() const +{ + QList<QQuickDrawer *> sorted(allDrawers); + std::sort(sorted.begin(), sorted.end(), [](const QQuickDrawer *one, const QQuickDrawer *another) { + return one->z() > another->z(); + }); + return sorted; +} + +void QQuickOverlayPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) +{ + updateGeometry(); +} + +bool QQuickOverlayPrivate::startDrag(QEvent *event, const QPointF &pos) +{ + Q_Q(QQuickOverlay); + if (allDrawers.isEmpty()) + return false; + + // don't start dragging a drawer if a modal popup overlay is blocking (QTBUG-60602) + QQuickItem *item = q->childAt(pos.x(), pos.y()); + if (item) { + const auto popups = stackingOrderPopups(); + for (QQuickPopup *popup : popups) { + QQuickPopupPrivate *p = QQuickPopupPrivate::get(popup); + if (p->dimmer == item && popup->isVisible() && popup->isModal()) + return false; + } + } + + const QList<QQuickDrawer *> drawers = stackingOrderDrawers(); + for (QQuickDrawer *drawer : drawers) { + QQuickDrawerPrivate *p = QQuickDrawerPrivate::get(drawer); + if (p->startDrag(event)) { + setMouseGrabberPopup(drawer); + return true; + } + } + + return false; +} + +bool QQuickOverlayPrivate::handlePress(QQuickItem *source, QEvent *event, QQuickPopup *target) +{ + if (target) { + if (target->overlayEvent(source, event)) { + setMouseGrabberPopup(target); + return true; + } + return false; + } + + switch (event->type()) { + default: { + if (mouseGrabberPopup) + break; +#if QT_CONFIG(quicktemplates2_multitouch) + Q_FALLTHROUGH(); + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: +#endif + // allow non-modal popups to close themselves, + // and non-dimming modal popups to block the event + const auto popups = stackingOrderPopups(); + for (QQuickPopup *popup : popups) { + if (popup->overlayEvent(source, event)) { + setMouseGrabberPopup(popup); + return true; + } + } + break; + } + } + + event->ignore(); + return false; +} + +bool QQuickOverlayPrivate::handleMove(QQuickItem *source, QEvent *event, QQuickPopup *target) +{ + if (target) + return target->overlayEvent(source, event); + return false; +} + +bool QQuickOverlayPrivate::handleRelease(QQuickItem *source, QEvent *event, QQuickPopup *target) +{ + if (target) { + setMouseGrabberPopup(nullptr); + if (target->overlayEvent(source, event)) { + setMouseGrabberPopup(nullptr); + return true; + } + } else { + const auto popups = stackingOrderPopups(); + for (QQuickPopup *popup : popups) { + if (popup->overlayEvent(source, event)) + return true; + } + } + return false; +} + +bool QQuickOverlayPrivate::handleMouseEvent(QQuickItem *source, QMouseEvent *event, QQuickPopup *target) +{ + switch (event->type()) { + case QEvent::MouseButtonPress: + if (!target && startDrag(event, event->scenePosition())) + return true; + return handlePress(source, event, target); + case QEvent::MouseMove: + return handleMove(source, event, target ? target : mouseGrabberPopup.data()); + case QEvent::MouseButtonRelease: + return handleRelease(source, event, target ? target : mouseGrabberPopup.data()); + default: + break; + } + return false; +} + +bool QQuickOverlayPrivate::handleHoverEvent(QQuickItem *source, QHoverEvent *event, QQuickPopup *target) +{ + switch (event->type()) { + case QEvent::HoverEnter: + case QEvent::HoverMove: + case QEvent::HoverLeave: + if (target) + return target->overlayEvent(source, event); + return false; + default: + Q_UNREACHABLE(); // function must only be called on hover events + break; + } + return false; +} + +#if QT_CONFIG(quicktemplates2_multitouch) +bool QQuickOverlayPrivate::handleTouchEvent(QQuickItem *source, QTouchEvent *event, QQuickPopup *target) +{ + bool handled = false; + switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + for (const QTouchEvent::TouchPoint &point : event->points()) { + switch (point.state()) { + case QEventPoint::Pressed: + if (!target && startDrag(event, point.scenePosition())) + handled = true; + else + handled |= handlePress(source, event, target); + break; + case QEventPoint::Updated: + handled |= handleMove(source, event, target ? target : mouseGrabberPopup.data()); + break; + case QEventPoint::Released: + handled |= handleRelease(source, event, target ? target : mouseGrabberPopup.data()); + break; + default: + break; + } + } + break; + + default: + break; + } + + return handled; +} +#endif + +void QQuickOverlayPrivate::addPopup(QQuickPopup *popup) +{ + Q_Q(QQuickOverlay); + allPopups += popup; + if (QQuickDrawer *drawer = qobject_cast<QQuickDrawer *>(popup)) { + allDrawers += drawer; + q->setVisible(!allDrawers.isEmpty() || !q->childItems().isEmpty()); + } +} + +void QQuickOverlayPrivate::removePopup(QQuickPopup *popup) +{ + Q_Q(QQuickOverlay); + allPopups.removeOne(popup); + if (allDrawers.removeOne(qobject_cast<QQuickDrawer *>(popup))) + q->setVisible(!allDrawers.isEmpty() || !q->childItems().isEmpty()); +} + +void QQuickOverlayPrivate::setMouseGrabberPopup(QQuickPopup *popup) +{ + if (popup && !popup->isVisible()) + popup = nullptr; + mouseGrabberPopup = popup; +} + +void QQuickOverlayPrivate::updateGeometry() +{ + Q_Q(QQuickOverlay); + if (!window) + return; + + QPointF pos; + QSizeF size = window->size(); + qreal rotation = 0; + + switch (window->contentOrientation()) { + case Qt::PrimaryOrientation: + case Qt::PortraitOrientation: + size = window->size(); + break; + case Qt::LandscapeOrientation: + rotation = 90; + pos = QPointF((size.width() - size.height()) / 2, -(size.width() - size.height()) / 2); + size.transpose(); + break; + case Qt::InvertedPortraitOrientation: + rotation = 180; + break; + case Qt::InvertedLandscapeOrientation: + rotation = 270; + pos = QPointF((size.width() - size.height()) / 2, -(size.width() - size.height()) / 2); + size.transpose(); + break; + default: + break; + } + + q->setSize(size); + q->setPosition(pos); + q->setRotation(rotation); +} + +QQuickOverlay::QQuickOverlay(QQuickItem *parent) + : QQuickItem(*(new QQuickOverlayPrivate), parent) +{ + Q_D(QQuickOverlay); + setZ(1000001); // DefaultWindowDecoration+1 + setAcceptedMouseButtons(Qt::AllButtons); +#if QT_CONFIG(quicktemplates2_multitouch) + setAcceptTouchEvents(true); +#endif + setFiltersChildMouseEvents(true); + setVisible(false); + + if (parent) { + d->updateGeometry(); + QQuickItemPrivate::get(parent)->addItemChangeListener(d, QQuickItemPrivate::Geometry); + if (QQuickWindow *window = parent->window()) { + window->installEventFilter(this); + QObjectPrivate::connect(window, &QWindow::contentOrientationChanged, d, &QQuickOverlayPrivate::updateGeometry); + } + } +} + +QQuickOverlay::~QQuickOverlay() +{ + Q_D(QQuickOverlay); + if (QQuickItem *parent = parentItem()) + QQuickItemPrivate::get(parent)->removeItemChangeListener(d, QQuickItemPrivate::Geometry); +} + +QQmlComponent *QQuickOverlay::modal() const +{ + Q_D(const QQuickOverlay); + return d->modal; +} + +void QQuickOverlay::setModal(QQmlComponent *modal) +{ + Q_D(QQuickOverlay); + if (d->modal == modal) + return; + + d->modal = modal; + emit modalChanged(); +} + +QQmlComponent *QQuickOverlay::modeless() const +{ + Q_D(const QQuickOverlay); + return d->modeless; +} + +void QQuickOverlay::setModeless(QQmlComponent *modeless) +{ + Q_D(QQuickOverlay); + if (d->modeless == modeless) + return; + + d->modeless = modeless; + emit modelessChanged(); +} + +QQuickOverlay *QQuickOverlay::overlay(QQuickWindow *window) +{ + if (!window) + return nullptr; + + const char *name = "_q_QQuickOverlay"; + QQuickOverlay *overlay = window->property(name).value<QQuickOverlay *>(); + if (!overlay) { + QQuickItem *content = window->contentItem(); + // Do not re-create the overlay if the window is being destroyed + // and thus, its content item no longer has a window associated. + if (content && content->window()) { + overlay = new QQuickOverlay(window->contentItem()); + window->setProperty(name, QVariant::fromValue(overlay)); + } + } + return overlay; +} + +QQuickOverlayAttached *QQuickOverlay::qmlAttachedProperties(QObject *object) +{ + return new QQuickOverlayAttached(object); +} + +void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data) +{ + Q_D(QQuickOverlay); + QQuickItem::itemChange(change, data); + + if (change == ItemChildAddedChange || change == ItemChildRemovedChange) { + setVisible(!d->allDrawers.isEmpty() || !childItems().isEmpty()); + if (data.item->parent() == d->mouseGrabberPopup) + d->setMouseGrabberPopup(nullptr); + } +} + +void QQuickOverlay::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickOverlay); + QQuickItem::geometryChange(newGeometry, oldGeometry); + for (QQuickPopup *popup : qAsConst(d->allPopups)) + QQuickPopupPrivate::get(popup)->resizeOverlay(); +} + +void QQuickOverlay::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickOverlay); + d->handleMouseEvent(this, event); +} + +void QQuickOverlay::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QQuickOverlay); + d->handleMouseEvent(this, event); +} + +void QQuickOverlay::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QQuickOverlay); + d->handleMouseEvent(this, event); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickOverlay::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickOverlay); + d->handleTouchEvent(this, event); +} +#endif + +#if QT_CONFIG(wheelevent) +void QQuickOverlay::wheelEvent(QWheelEvent *event) +{ + Q_D(QQuickOverlay); + if (d->mouseGrabberPopup) { + d->mouseGrabberPopup->overlayEvent(this, event); + return; + } else { + const auto popups = d->stackingOrderPopups(); + for (QQuickPopup *popup : popups) { + if (popup->overlayEvent(this, event)) + return; + } + } + event->ignore(); +} +#endif + +bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event) +{ + Q_D(QQuickOverlay); + const auto popups = d->stackingOrderPopups(); + for (QQuickPopup *popup : popups) { + QQuickPopupPrivate *p = QQuickPopupPrivate::get(popup); + + // Stop filtering overlay events when reaching a popup item or an item + // that is inside the popup. Let the popup content handle its events. + if (item == p->popupItem || p->popupItem->isAncestorOf(item)) + break; + + // Let the popup try closing itself when pressing or releasing over its + // background dimming OR over another popup underneath, in case the popup + // does not have background dimming. + if (item == p->dimmer || !p->popupItem->isAncestorOf(item)) { + bool handled = false; + switch (event->type()) { +#if QT_CONFIG(quicktemplates2_multitouch) + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + handled = d->handleTouchEvent(item, static_cast<QTouchEvent *>(event), popup); + break; +#endif + case QEvent::HoverEnter: + case QEvent::HoverMove: + case QEvent::HoverLeave: + handled = d->handleHoverEvent(item, static_cast<QHoverEvent *>(event), popup); + break; + + case QEvent::MouseButtonPress: + case QEvent::MouseMove: + case QEvent::MouseButtonRelease: + handled = d->handleMouseEvent(item, static_cast<QMouseEvent *>(event), popup); + break; + + default: + break; + } + if (handled) + return true; + } + } + return false; +} + +bool QQuickOverlay::eventFilter(QObject *object, QEvent *event) +{ + Q_D(QQuickOverlay); + if (!isVisible() || object != d->window) + return false; + + switch (event->type()) { +#if QT_CONFIG(quicktemplates2_multitouch) + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + if (static_cast<QTouchEvent *>(event)->touchPointStates() & QEventPoint::Pressed) + emit pressed(); + if (static_cast<QTouchEvent *>(event)->touchPointStates() & QEventPoint::Released) + emit released(); + + // allow non-modal popups to close on touch release outside + if (!d->mouseGrabberPopup) { + for (const QTouchEvent::TouchPoint &point : static_cast<QTouchEvent *>(event)->points()) { + if (point.state() == QEventPoint::Released) { + if (d->handleRelease(d->window->contentItem(), event, nullptr)) + break; + } + } + } + + QQuickWindowPrivate::get(d->window)->handleTouchEvent(static_cast<QTouchEvent *>(event)); + + // If a touch event hasn't been accepted after being delivered, there + // were no items interested in touch events at any of the touch points. + // Make sure to accept the touch event in order to receive the consequent + // touch events, to be able to close non-modal popups on release outside. + event->accept(); + return true; +#endif + + case QEvent::MouseButtonPress: +#if QT_CONFIG(quicktemplates2_multitouch) + // do not emit pressed() twice when mouse events have been synthesized from touch events + if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized) +#endif + emit pressed(); + + QQuickWindowPrivate::get(d->window)->handleMouseEvent(static_cast<QMouseEvent *>(event)); + + // If a mouse event hasn't been accepted after being delivered, there + // was no item interested in mouse events at the mouse point. Make sure + // to accept the mouse event in order to receive the consequent mouse + // events, to be able to close non-modal popups on release outside. + event->accept(); + return true; + + case QEvent::MouseButtonRelease: +#if QT_CONFIG(quicktemplates2_multitouch) + // do not emit released() twice when mouse events have been synthesized from touch events + if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized) +#endif + emit released(); + + // allow non-modal popups to close on mouse release outside + if (!d->mouseGrabberPopup) + d->handleRelease(d->window->contentItem(), event, nullptr); + break; + + case QEvent::Wheel: { + // If the top item in the drawing-order is blocked by a modal popup, then + // eat the event. There is no scenario where the top most item is blocked + // by a popup, but an item further down in the drawing order is not. + QWheelEvent *we = static_cast<QWheelEvent *>(event); + const QVector<QQuickItem *> targetItems = d->deliveryAgentPrivate()->pointerTargets( + d->window->contentItem(), we, we->point(0), false, false); + if (targetItems.isEmpty()) + break; + + QQuickItem * const topItem = targetItems.first(); + const auto popups = d->stackingOrderPopups(); + for (const auto &popup : popups) { + if (!popup->overlayEvent(topItem, we)) + continue; + const QQuickItem *popupItem = popup->popupItem(); + if (!popupItem) + continue; + if (!popupItem->isAncestorOf(topItem)) + return true; + } + break; + } + + default: + break; + } + + return false; +} + +class QQuickOverlayAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickOverlayAttached) + +public: + void setWindow(QQuickWindow *newWindow); + + QQuickWindow *window = nullptr; + QQmlComponent *modal = nullptr; + QQmlComponent *modeless = nullptr; +}; + +void QQuickOverlayAttachedPrivate::setWindow(QQuickWindow *newWindow) +{ + Q_Q(QQuickOverlayAttached); + if (window == newWindow) + return; + + if (QQuickOverlay *oldOverlay = QQuickOverlay::overlay(window)) { + QObject::disconnect(oldOverlay, &QQuickOverlay::pressed, q, &QQuickOverlayAttached::pressed); + QObject::disconnect(oldOverlay, &QQuickOverlay::released, q, &QQuickOverlayAttached::released); + } + + if (QQuickOverlay *newOverlay = QQuickOverlay::overlay(newWindow)) { + QObject::connect(newOverlay, &QQuickOverlay::pressed, q, &QQuickOverlayAttached::pressed); + QObject::connect(newOverlay, &QQuickOverlay::released, q, &QQuickOverlayAttached::released); + } + + window = newWindow; + emit q->overlayChanged(); +} + +/*! + \qmlattachedsignal QtQuick.Controls::Overlay::pressed() + + This attached signal is emitted when the overlay is pressed by the user while + a popup is visible. + + The signal can be attached to any item, popup, or window. When attached to an + item or a popup, the signal is only emitted if the item or popup is in a window. +*/ + +/*! + \qmlattachedsignal QtQuick.Controls::Overlay::released() + + This attached signal is emitted when the overlay is released by the user while + a popup is visible. + + The signal can be attached to any item, popup, or window. When attached to an + item or a popup, the signal is only emitted if the item or popup is in a window. +*/ + +QQuickOverlayAttached::QQuickOverlayAttached(QObject *parent) + : QObject(*(new QQuickOverlayAttachedPrivate), parent) +{ + Q_D(QQuickOverlayAttached); + if (QQuickItem *item = qobject_cast<QQuickItem *>(parent)) { + d->setWindow(item->window()); + QObjectPrivate::connect(item, &QQuickItem::windowChanged, d, &QQuickOverlayAttachedPrivate::setWindow); + } else if (QQuickPopup *popup = qobject_cast<QQuickPopup *>(parent)) { + d->setWindow(popup->window()); + QObjectPrivate::connect(popup, &QQuickPopup::windowChanged, d, &QQuickOverlayAttachedPrivate::setWindow); + } else { + d->setWindow(qobject_cast<QQuickWindow *>(parent)); + } +} + +/*! + \qmlattachedproperty Overlay QtQuick.Controls::Overlay::overlay + \readonly + + This attached property holds the window overlay item. + + The property can be attached to any item, popup, or window. When attached to an + item or a popup, the value is \c null if the item or popup is not in a window. +*/ +QQuickOverlay *QQuickOverlayAttached::overlay() const +{ + Q_D(const QQuickOverlayAttached); + return QQuickOverlay::overlay(d->window); +} + +/*! + \qmlattachedproperty Component QtQuick.Controls::Overlay::modal + + This attached property holds a component to use as a visual item that implements + background dimming for modal popups. It is created for and stacked below visible + modal popups. + + The property can be attached to any popup. + + For example, to change the color of the background dimming for a modal + popup, the following code can be used: + + \snippet qtquickcontrols2-overlay-modal.qml 1 + + \sa Popup::modal +*/ +QQmlComponent *QQuickOverlayAttached::modal() const +{ + Q_D(const QQuickOverlayAttached); + return d->modal; +} + +void QQuickOverlayAttached::setModal(QQmlComponent *modal) +{ + Q_D(QQuickOverlayAttached); + if (d->modal == modal) + return; + + d->modal = modal; + emit modalChanged(); +} + +/*! + \qmlattachedproperty Component QtQuick.Controls::Overlay::modeless + + This attached property holds a component to use as a visual item that implements + background dimming for modeless popups. It is created for and stacked below visible + dimming popups. + + The property can be attached to any popup. + + For example, to change the color of the background dimming for a modeless + popup, the following code can be used: + + \snippet qtquickcontrols2-overlay-modeless.qml 1 + + \sa Popup::dim +*/ +QQmlComponent *QQuickOverlayAttached::modeless() const +{ + Q_D(const QQuickOverlayAttached); + return d->modeless; +} + +void QQuickOverlayAttached::setModeless(QQmlComponent *modeless) +{ + Q_D(QQuickOverlayAttached); + if (d->modeless == modeless) + return; + + d->modeless = modeless; + emit modelessChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qquickoverlay_p.cpp" diff --git a/src/quicktemplates2/qquickoverlay_p.h b/src/quicktemplates2/qquickoverlay_p.h new file mode 100644 index 00000000000..c6e530e2807 --- /dev/null +++ b/src/quicktemplates2/qquickoverlay_p.h @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKOVERLAY_P_H +#define QQUICKOVERLAY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQmlComponent; +class QQuickOverlayPrivate; +class QQuickOverlayAttached; +class QQuickOverlayAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickOverlay : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QQmlComponent *modal READ modal WRITE setModal NOTIFY modalChanged FINAL) + Q_PROPERTY(QQmlComponent *modeless READ modeless WRITE setModeless NOTIFY modelessChanged FINAL) + QML_NAMED_ELEMENT(Overlay) + QML_ATTACHED(QQuickOverlayAttached) + QML_UNCREATABLE("") + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickOverlay(QQuickItem *parent = nullptr); + ~QQuickOverlay(); + + QQmlComponent *modal() const; + void setModal(QQmlComponent *modal); + + QQmlComponent *modeless() const; + void setModeless(QQmlComponent *modeless); + + static QQuickOverlay *overlay(QQuickWindow *window); + + static QQuickOverlayAttached *qmlAttachedProperties(QObject *object); + +Q_SIGNALS: + void modalChanged(); + void modelessChanged(); + void pressed(); + void released(); + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif +#if QT_CONFIG(wheelevent) + void wheelEvent(QWheelEvent *event) override; +#endif + bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; + bool eventFilter(QObject *object, QEvent *event) override; + +private: + Q_DISABLE_COPY(QQuickOverlay) + Q_DECLARE_PRIVATE(QQuickOverlay) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickOverlayAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickOverlay *overlay READ overlay NOTIFY overlayChanged FINAL) + Q_PROPERTY(QQmlComponent *modal READ modal WRITE setModal NOTIFY modalChanged FINAL) + Q_PROPERTY(QQmlComponent *modeless READ modeless WRITE setModeless NOTIFY modelessChanged FINAL) + +public: + explicit QQuickOverlayAttached(QObject *parent = nullptr); + + QQuickOverlay *overlay() const; + + QQmlComponent *modal() const; + void setModal(QQmlComponent *modal); + + QQmlComponent *modeless() const; + void setModeless(QQmlComponent *modeless); + +Q_SIGNALS: + void overlayChanged(); + void modalChanged(); + void modelessChanged(); + void pressed(); + void released(); + +private: + Q_DISABLE_COPY(QQuickOverlayAttached) + Q_DECLARE_PRIVATE(QQuickOverlayAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickOverlay) +QML_DECLARE_TYPEINFO(QQuickOverlay, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKOVERLAY_P_H diff --git a/src/quicktemplates2/qquickoverlay_p_p.h b/src/quicktemplates2/qquickoverlay_p_p.h new file mode 100644 index 00000000000..fbb2f86c73a --- /dev/null +++ b/src/quicktemplates2/qquickoverlay_p_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKOVERLAY_P_P_H +#define QQUICKOVERLAY_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickoverlay_p.h> + +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickPopup; +class QQuickDrawer; + +class QQuickOverlayPrivate : public QQuickItemPrivate, public QQuickItemChangeListener +{ + Q_DECLARE_PUBLIC(QQuickOverlay) + +public: + static QQuickOverlayPrivate *get(QQuickOverlay *overlay) + { + return overlay->d_func(); + } + + bool startDrag(QEvent *event, const QPointF &pos); + bool handlePress(QQuickItem *source, QEvent *event, QQuickPopup *target); + bool handleMove(QQuickItem *source, QEvent *event, QQuickPopup *target); + bool handleRelease(QQuickItem *source, QEvent *event, QQuickPopup *target); + + bool handleMouseEvent(QQuickItem *source, QMouseEvent *event, QQuickPopup *target = nullptr); + bool handleHoverEvent(QQuickItem *source, QHoverEvent *event, QQuickPopup *target = nullptr); +#if QT_CONFIG(quicktemplates2_multitouch) + bool handleTouchEvent(QQuickItem *source, QTouchEvent *event, QQuickPopup *target = nullptr); +#endif + + void addPopup(QQuickPopup *popup); + void removePopup(QQuickPopup *popup); + void setMouseGrabberPopup(QQuickPopup *popup); + + QList<QQuickPopup *> stackingOrderPopups() const; + QList<QQuickDrawer *> stackingOrderDrawers() const; + + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + + void updateGeometry(); + + QQmlComponent *modal = nullptr; + QQmlComponent *modeless = nullptr; + QList<QQuickPopup *> allPopups; + QList<QQuickDrawer *> allDrawers; + QPointer<QQuickPopup> mouseGrabberPopup; +}; + +QT_END_NAMESPACE + +#endif // QQUICKOVERLAY_P_P_H diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp new file mode 100644 index 00000000000..a65e53fe82e --- /dev/null +++ b/src/quicktemplates2/qquickpage.cpp @@ -0,0 +1,498 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpage_p.h" +#include "qquickpage_p_p.h" +#include "qquicktabbar_p.h" +#include "qquicktoolbar_p.h" +#include "qquickdialogbuttonbox_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Page + \inherits Pane +//! \instantiates QQuickPage + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes + \brief Styled page control with support for a header and footer. + + Page is a container control which makes it convenient to add + a \l header and \l footer item to a page. + + \image qtquickcontrols2-page-wireframe.png + + Items declared as children of a Page are: + \list + \li automatically parented to the Page's contentItem. Items created + dynamically need to be explicitly parented to the contentItem. + \li not automatically positioned or resized. + \endlist + + The following example snippet illustrates how to use a page-specific + toolbar header and an application-wide tabbar footer. + + \qml + import QtQuick.Controls + import QtQuick.Layouts + + ApplicationWindow { + visible: true + + StackView { + anchors.fill: parent + + initialItem: Page { + header: ToolBar { + // ... + } + + ColumnLayout { + anchors.fill: parent + // ... + } + } + } + + footer: TabBar { + // ... + } + } + \endqml + + \sa ApplicationWindow, {Container Controls}, + {Focus Management in Qt Quick Controls} +*/ + +static const QQuickItemPrivate::ChangeTypes LayoutChanges = QQuickItemPrivate::Geometry | QQuickItemPrivate::Visibility | QQuickItemPrivate::Destroyed + | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; + +namespace { + enum Position { + Header, + Footer + }; + + Q_STATIC_ASSERT(int(Header) == int(QQuickTabBar::Header)); + Q_STATIC_ASSERT(int(Footer) == int(QQuickTabBar::Footer)); + + Q_STATIC_ASSERT(int(Header) == int(QQuickToolBar::Header)); + Q_STATIC_ASSERT(int(Footer) == int(QQuickToolBar::Footer)); + + Q_STATIC_ASSERT(int(Header) == int(QQuickDialogButtonBox::Header)); + Q_STATIC_ASSERT(int(Footer) == int(QQuickDialogButtonBox::Footer)); + + static void setPos(QQuickItem *item, Position position) + { + if (QQuickToolBar *toolBar = qobject_cast<QQuickToolBar *>(item)) + toolBar->setPosition(static_cast<QQuickToolBar::Position>(position)); + else if (QQuickTabBar *tabBar = qobject_cast<QQuickTabBar *>(item)) + tabBar->setPosition(static_cast<QQuickTabBar::Position>(position)); + else if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(item)) + buttonBox->setPosition(static_cast<QQuickDialogButtonBox::Position>(position)); + } +} + +void QQuickPagePrivate::relayout() +{ + Q_Q(QQuickPage); + const qreal hh = header && header->isVisible() ? header->height() : 0; + const qreal fh = footer && footer->isVisible() ? footer->height() : 0; + const qreal hsp = hh > 0 ? spacing : 0; + const qreal fsp = fh > 0 ? spacing : 0; + + if (contentItem) { + contentItem->setY(q->topPadding() + hh + hsp); + contentItem->setX(q->leftPadding()); + contentItem->setWidth(q->availableWidth()); + contentItem->setHeight(q->availableHeight() - hh - fh - hsp - fsp); + } + + if (header) + header->setWidth(q->width()); + + if (footer) { + footer->setY(q->height() - footer->height()); + footer->setWidth(q->width()); + } +} + +void QQuickPagePrivate::resizeContent() +{ + relayout(); +} + +void QQuickPagePrivate::itemVisibilityChanged(QQuickItem *item) +{ + Q_Q(QQuickPage); + QQuickPanePrivate::itemVisibilityChanged(item); + if (item == header) { + QBoolBlocker signalGuard(emittingImplicitSizeChangedSignals); + emit q->implicitHeaderWidthChanged(); + emit q->implicitHeaderHeightChanged(); + relayout(); + } else if (item == footer) { + QBoolBlocker signalGuard(emittingImplicitSizeChangedSignals); + emit q->implicitFooterWidthChanged(); + emit q->implicitFooterHeightChanged(); + relayout(); + } +} + +void QQuickPagePrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickPage); + QQuickPanePrivate::itemImplicitWidthChanged(item); + + // Avoid binding loops by skipping signal emission if we're already doing it. + if (emittingImplicitSizeChangedSignals) + return; + + if (item == header) + emit q->implicitHeaderWidthChanged(); + else if (item == footer) + emit q->implicitFooterWidthChanged(); +} + +void QQuickPagePrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickPage); + QQuickPanePrivate::itemImplicitHeightChanged(item); + + // Avoid binding loops by skipping signal emission if we're already doing it. + if (emittingImplicitSizeChangedSignals) + return; + + if (item == header) + emit q->implicitHeaderHeightChanged(); + else if (item == footer) + emit q->implicitFooterHeightChanged(); +} + +void QQuickPagePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF & diff) +{ + QQuickPanePrivate::itemGeometryChanged(item, change, diff); + if (item == header || item == footer) + relayout(); +} + +void QQuickPagePrivate::itemDestroyed(QQuickItem *item) +{ + Q_Q(QQuickPage); + QQuickPanePrivate::itemDestroyed(item); + if (item == header) { + header = nullptr; + relayout(); + emit q->implicitHeaderWidthChanged(); + emit q->implicitHeaderHeightChanged(); + emit q->headerChanged(); + } else if (item == footer) { + footer = nullptr; + relayout(); + emit q->implicitFooterWidthChanged(); + emit q->implicitFooterHeightChanged(); + emit q->footerChanged(); + } +} + +QQuickPage::QQuickPage(QQuickItem *parent) + : QQuickPane(*(new QQuickPagePrivate), parent) +{ +} + +QQuickPage::QQuickPage(QQuickPagePrivate &dd, QQuickItem *parent) + : QQuickPane(dd, parent) +{ +} + +QQuickPage::~QQuickPage() +{ + Q_D(QQuickPage); + if (d->header) + QQuickItemPrivate::get(d->header)->removeItemChangeListener(d, LayoutChanges); + if (d->footer) + QQuickItemPrivate::get(d->footer)->removeItemChangeListener(d, LayoutChanges); +} + +/*! + \qmlproperty string QtQuick.Controls::Page::title + + This property holds the page title. + + The title is often displayed at the top of a page to give + the user context about the page they are viewing. + + Page does not render the title itself, but instead relies + on the application to do so. For example: + + \code + ApplicationWindow { + visible: true + width: 400 + height: 400 + + header: Label { + text: view.currentItem.title + horizontalAlignment: Text.AlignHCenter + } + + SwipeView { + id: view + anchors.fill: parent + + Page { + title: qsTr("Home") + } + Page { + title: qsTr("Discover") + } + Page { + title: qsTr("Activity") + } + } + } + \endcode +*/ + +QString QQuickPage::title() const +{ + return d_func()->title; +} + +void QQuickPage::setTitle(const QString &title) +{ + Q_D(QQuickPage); + if (d->title == title) + return; + + d->title = title; + maybeSetAccessibleName(title); + emit titleChanged(); +} + +/*! + \qmlproperty Item QtQuick.Controls::Page::header + + This property holds the page header item. The header item is positioned to + the top, and resized to the width of the page. The default value is \c null. + + \note Assigning a ToolBar, TabBar, or DialogButtonBox as a page header + automatically sets the respective \l ToolBar::position, \l TabBar::position, + or \l DialogButtonBox::position property to \c Header. + + \sa footer, ApplicationWindow::header +*/ +QQuickItem *QQuickPage::header() const +{ + Q_D(const QQuickPage); + return d->header; +} + +void QQuickPage::setHeader(QQuickItem *header) +{ + Q_D(QQuickPage); + if (d->header == header) + return; + + if (d->header) { + QQuickItemPrivate::get(d->header)->removeItemChangeListener(d, LayoutChanges); + d->header->setParentItem(nullptr); + } + d->header = header; + if (header) { + header->setParentItem(this); + QQuickItemPrivate::get(header)->addItemChangeListener(d, LayoutChanges); + if (qFuzzyIsNull(header->z())) + header->setZ(1); + setPos(header, Header); + } + if (isComponentComplete()) + d->relayout(); + emit headerChanged(); +} + +/*! + \qmlproperty Item QtQuick.Controls::Page::footer + + This property holds the page footer item. The footer item is positioned to + the bottom, and resized to the width of the page. The default value is \c null. + + \note Assigning a ToolBar, TabBar, or DialogButtonBox as a page footer + automatically sets the respective \l ToolBar::position, \l TabBar::position, + or \l DialogButtonBox::position property to \c Footer. + + \sa header, ApplicationWindow::footer +*/ +QQuickItem *QQuickPage::footer() const +{ + Q_D(const QQuickPage); + return d->footer; +} + +void QQuickPage::setFooter(QQuickItem *footer) +{ + Q_D(QQuickPage); + if (d->footer == footer) + return; + + if (d->footer) { + QQuickItemPrivate::get(d->footer)->removeItemChangeListener(d, LayoutChanges); + d->footer->setParentItem(nullptr); + } + d->footer = footer; + if (footer) { + footer->setParentItem(this); + QQuickItemPrivate::get(footer)->addItemChangeListener(d, LayoutChanges); + if (qFuzzyIsNull(footer->z())) + footer->setZ(1); + setPos(footer, Footer); + } + if (isComponentComplete()) + d->relayout(); + emit footerChanged(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Page::implicitHeaderWidth + \readonly + + This property holds the implicit header width. + + The value is equal to \c {header && header.visible ? header.implicitWidth : 0}. + + \sa implicitHeaderHeight, implicitFooterWidth +*/ +qreal QQuickPage::implicitHeaderWidth() const +{ + Q_D(const QQuickPage); + if (!d->header || !d->header->isVisible()) + return 0; + return d->header->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Page::implicitHeaderHeight + \readonly + + This property holds the implicit header height. + + The value is equal to \c {header && header.visible ? header.implicitHeight : 0}. + + \sa implicitHeaderWidth, implicitFooterHeight +*/ +qreal QQuickPage::implicitHeaderHeight() const +{ + Q_D(const QQuickPage); + if (!d->header || !d->header->isVisible()) + return 0; + return d->header->implicitHeight(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Page::implicitFooterWidth + \readonly + + This property holds the implicit footer width. + + The value is equal to \c {footer && footer.visible ? footer.implicitWidth : 0}. + + \sa implicitFooterHeight, implicitHeaderWidth +*/ +qreal QQuickPage::implicitFooterWidth() const +{ + Q_D(const QQuickPage); + if (!d->footer || !d->footer->isVisible()) + return 0; + return d->footer->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Page::implicitFooterHeight + \readonly + + This property holds the implicit footer height. + + The value is equal to \c {footer && footer.visible ? footer.implicitHeight : 0}. + + \sa implicitFooterWidth, implicitHeaderHeight +*/ +qreal QQuickPage::implicitFooterHeight() const +{ + Q_D(const QQuickPage); + if (!d->footer || !d->footer->isVisible()) + return 0; + return d->footer->implicitHeight(); +} + +void QQuickPage::componentComplete() +{ + Q_D(QQuickPage); + QQuickPane::componentComplete(); + d->relayout(); +} + +void QQuickPage::spacingChange(qreal newSpacing, qreal oldSpacing) +{ + Q_D(QQuickPage); + QQuickPane::spacingChange(newSpacing, oldSpacing); + d->relayout(); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickPage::accessibleRole() const +{ + return QAccessible::PageTab; +} + +void QQuickPage::accessibilityActiveChanged(bool active) +{ + Q_D(QQuickPage); + QQuickPane::accessibilityActiveChanged(active); + + if (active) + maybeSetAccessibleName(d->title); +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickpage_p.cpp" diff --git a/src/quicktemplates2/qquickpage_p.h b/src/quicktemplates2/qquickpage_p.h new file mode 100644 index 00000000000..0a65f67f28c --- /dev/null +++ b/src/quicktemplates2/qquickpage_p.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPAGE_P_H +#define QQUICKPAGE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickpane_p.h> +#include <QtQml/qqmllist.h> + +QT_BEGIN_NAMESPACE + +class QQuickPagePrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPage : public QQuickPane +{ + Q_OBJECT + Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL) + Q_PROPERTY(QQuickItem *header READ header WRITE setHeader NOTIFY headerChanged FINAL) + Q_PROPERTY(QQuickItem *footer READ footer WRITE setFooter NOTIFY footerChanged FINAL) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitHeaderWidth READ implicitHeaderWidth NOTIFY implicitHeaderWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitHeaderHeight READ implicitHeaderHeight NOTIFY implicitHeaderHeightChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitFooterWidth READ implicitFooterWidth NOTIFY implicitFooterWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitFooterHeight READ implicitFooterHeight NOTIFY implicitFooterHeightChanged FINAL REVISION(2, 5)) + QML_NAMED_ELEMENT(Page) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickPage(QQuickItem *parent = nullptr); + ~QQuickPage(); + + QString title() const; + void setTitle(const QString &title); + + QQuickItem *header() const; + void setHeader(QQuickItem *header); + + QQuickItem *footer() const; + void setFooter(QQuickItem *footer); + + // 2.5 (Qt 5.12) + qreal implicitHeaderWidth() const; + qreal implicitHeaderHeight() const; + + qreal implicitFooterWidth() const; + qreal implicitFooterHeight() const; + +Q_SIGNALS: + void titleChanged(); + void headerChanged(); + void footerChanged(); + // 2.5 (Qt 5.12) + void implicitHeaderWidthChanged(); + void implicitHeaderHeightChanged(); + void implicitFooterWidthChanged(); + void implicitFooterHeightChanged(); + +protected: + QQuickPage(QQuickPagePrivate &dd, QQuickItem *parent); + + void componentComplete() override; + + void spacingChange(qreal newSpacing, qreal oldSpacing) override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; + void accessibilityActiveChanged(bool active) override; +#endif + +private: + Q_DISABLE_COPY(QQuickPage) + Q_DECLARE_PRIVATE(QQuickPage) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickPage) + +#endif // QQUICKPAGE_P_H diff --git a/src/quicktemplates2/qquickpage_p_p.h b/src/quicktemplates2/qquickpage_p_p.h new file mode 100644 index 00000000000..6c8b037102d --- /dev/null +++ b/src/quicktemplates2/qquickpage_p_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPAGE_P_P_H +#define QQUICKPAGE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickpane_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickPane; + +class QQuickPagePrivate : public QQuickPanePrivate +{ + Q_DECLARE_PUBLIC(QQuickPage) + +public: + void relayout(); + void resizeContent() override; + + void itemVisibilityChanged(QQuickItem *item) override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF & diff) override; + void itemDestroyed(QQuickItem *item) override; + + QString title; + QQuickItem *header = nullptr; + QQuickItem *footer = nullptr; + bool emittingImplicitSizeChangedSignals = false; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPAGE_P_P_H diff --git a/src/quicktemplates2/qquickpageindicator.cpp b/src/quicktemplates2/qquickpageindicator.cpp new file mode 100644 index 00000000000..42834962e1b --- /dev/null +++ b/src/quicktemplates2/qquickpageindicator.cpp @@ -0,0 +1,354 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpageindicator_p.h" +#include "qquickcontrol_p_p.h" + +#include <QtCore/qmath.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype PageIndicator + \inherits Control +//! \instantiates QQuickPageIndicator + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-indicators + \brief Indicates the currently active page. + + PageIndicator is used to indicate the currently active page + in a container of multiple pages. PageIndicator consists of + delegate items that present pages. + + \image qtquickcontrols2-pageindicator.png + + \code + Column { + StackLayout { + id: stackLayout + + Page { + // ... + } + Page { + // ... + } + Page { + // ... + } + } + + PageIndicator { + currentIndex: stackLayout.currentIndex + count: stackLayout.count + } + } + \endcode + + \sa SwipeView, {Customizing PageIndicator}, {Indicator Controls} +*/ + +class QQuickPageIndicatorPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickPageIndicator) + +public: + void handlePress(const QPointF &point) override; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + void handleUngrab() override; + + QQuickItem *itemAt(const QPointF &pos) const; + void updatePressed(bool pressed, const QPointF &pos = QPointF()); + void setContextProperty(QQuickItem *item, const QString &name, const QVariant &value); + + void itemChildAdded(QQuickItem *, QQuickItem *child) override; + + int count = 0; + int currentIndex = 0; + bool interactive = false; + QQmlComponent *delegate = nullptr; + QQuickItem *pressedItem = nullptr; +}; + +void QQuickPageIndicatorPrivate::handlePress(const QPointF &point) +{ + QQuickControlPrivate::handlePress(point); + if (interactive) + updatePressed(true, point); +} + +void QQuickPageIndicatorPrivate::handleMove(const QPointF &point) +{ + QQuickControlPrivate::handleMove(point); + if (interactive) + updatePressed(true, point); +} + +void QQuickPageIndicatorPrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickPageIndicator); + QQuickControlPrivate::handleRelease(point); + if (interactive) { + if (pressedItem && contentItem) + q->setCurrentIndex(contentItem->childItems().indexOf(pressedItem)); + updatePressed(false); + } +} + +void QQuickPageIndicatorPrivate::handleUngrab() +{ + QQuickControlPrivate::handleUngrab(); + if (interactive) + updatePressed(false); +} + +QQuickItem *QQuickPageIndicatorPrivate::itemAt(const QPointF &pos) const +{ + Q_Q(const QQuickPageIndicator); + if (!contentItem || !q->contains(pos)) + return nullptr; + + QPointF contentPos = q->mapToItem(contentItem, pos); + QQuickItem *item = contentItem->childAt(contentPos.x(), contentPos.y()); + while (item && item->parentItem() != contentItem) + item = item->parentItem(); + if (item && !QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return item; + + // find the nearest + qreal distance = qInf(); + QQuickItem *nearest = nullptr; + const auto childItems = contentItem->childItems(); + for (QQuickItem *child : childItems) { + if (QQuickItemPrivate::get(child)->isTransparentForPositioner()) + continue; + + QPointF center = child->boundingRect().center(); + QPointF pt = contentItem->mapToItem(child, contentPos); + + qreal len = QLineF(center, pt).length(); + if (len < distance) { + distance = len; + nearest = child; + } + } + return nearest; +} + +void QQuickPageIndicatorPrivate::updatePressed(bool pressed, const QPointF &pos) +{ + QQuickItem *prevItem = pressedItem; + pressedItem = pressed ? itemAt(pos) : nullptr; + if (prevItem != pressedItem) { + setContextProperty(prevItem, QStringLiteral("pressed"), false); + setContextProperty(pressedItem, QStringLiteral("pressed"), pressed); + } +} + +void QQuickPageIndicatorPrivate::setContextProperty(QQuickItem *item, const QString &name, const QVariant &value) +{ + QQmlContext *context = qmlContext(item); + if (context && context->isValid()) { + context = context->parentContext(); + if (context && context->isValid()) + context->setContextProperty(name, value); + } +} + +void QQuickPageIndicatorPrivate::itemChildAdded(QQuickItem *, QQuickItem *child) +{ + if (!QQuickItemPrivate::get(child)->isTransparentForPositioner()) + setContextProperty(child, QStringLiteral("pressed"), false); +} + +QQuickPageIndicator::QQuickPageIndicator(QQuickItem *parent) + : QQuickControl(*(new QQuickPageIndicatorPrivate), parent) +{ +} + +/*! + \qmlproperty int QtQuick.Controls::PageIndicator::count + + This property holds the number of pages. +*/ +int QQuickPageIndicator::count() const +{ + Q_D(const QQuickPageIndicator); + return d->count; +} + +void QQuickPageIndicator::setCount(int count) +{ + Q_D(QQuickPageIndicator); + if (d->count == count) + return; + + d->count = count; + emit countChanged(); +} + +/*! + \qmlproperty int QtQuick.Controls::PageIndicator::currentIndex + + This property holds the index of the current page. +*/ +int QQuickPageIndicator::currentIndex() const +{ + Q_D(const QQuickPageIndicator); + return d->currentIndex; +} + +void QQuickPageIndicator::setCurrentIndex(int index) +{ + Q_D(QQuickPageIndicator); + if (d->currentIndex == index) + return; + + d->currentIndex = index; + emit currentIndexChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::PageIndicator::interactive + + This property holds whether the control is interactive. An interactive page indicator + reacts to presses and automatically changes the \l {currentIndex}{current index} + appropriately. + + \snippet qtquickcontrols2-pageindicator-interactive.qml 1 + + \note Page indicators are typically quite small (in order to avoid + distracting the user from the actual content of the user interface). They + can be hard to click, and might not be easily recognized as interactive by + the user. For these reasons, they are best used to complement primary + methods of navigation (such as \l SwipeView), not replace them. + + The default value is \c false. +*/ +bool QQuickPageIndicator::isInteractive() const +{ + Q_D(const QQuickPageIndicator); + return d->interactive; +} + +void QQuickPageIndicator::setInteractive(bool interactive) +{ + Q_D(QQuickPageIndicator); + if (d->interactive == interactive) + return; + + d->interactive = interactive; + if (interactive) { + setAcceptedMouseButtons(Qt::LeftButton); +#if QT_CONFIG(quicktemplates2_multitouch) + setAcceptTouchEvents(true); +#endif +#if QT_CONFIG(cursor) + setCursor(Qt::ArrowCursor); +#endif + } else { + setAcceptedMouseButtons(Qt::NoButton); +#if QT_CONFIG(quicktemplates2_multitouch) + setAcceptTouchEvents(true); +#endif +#if QT_CONFIG(cursor) + unsetCursor(); +#endif + } + emit interactiveChanged(); +} + +/*! + \qmlproperty Component QtQuick.Controls::PageIndicator::delegate + + This property holds a delegate that presents a page. + + The following properties are available in the context of each delegate: + \table + \row \li \b index : int \li The index of the item + \row \li \b pressed : bool \li Whether the item is pressed + \endtable +*/ +QQmlComponent *QQuickPageIndicator::delegate() const +{ + Q_D(const QQuickPageIndicator); + return d->delegate; +} + +void QQuickPageIndicator::setDelegate(QQmlComponent *delegate) +{ + Q_D(QQuickPageIndicator); + if (d->delegate == delegate) + return; + + d->delegate = delegate; + emit delegateChanged(); +} + +void QQuickPageIndicator::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + Q_D(QQuickPageIndicator); + QQuickControl::contentItemChange(newItem, oldItem); + if (oldItem) + QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::Children); + if (newItem) + QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::Children); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickPageIndicator::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickPageIndicator); + if (d->interactive) + QQuickControl::touchEvent(event); + else + event->ignore(); // QTBUG-61785 +} +#endif + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickPageIndicator::accessibleRole() const +{ + return QAccessible::Indicator; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickpageindicator_p.cpp" diff --git a/src/quicktemplates2/qquickpageindicator_p.h b/src/quicktemplates2/qquickpageindicator_p.h new file mode 100644 index 00000000000..a21e88fe490 --- /dev/null +++ b/src/quicktemplates2/qquickpageindicator_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPAGEINDICATOR_P_H +#define QQUICKPAGEINDICATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQmlComponent; +class QQuickPageIndicatorPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPageIndicator : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged FINAL) + Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL) + Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive NOTIFY interactiveChanged FINAL) + Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL) + QML_NAMED_ELEMENT(PageIndicator) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickPageIndicator(QQuickItem *parent = nullptr); + + int count() const; + void setCount(int count); + + int currentIndex() const; + void setCurrentIndex(int index); + + bool isInteractive() const; + void setInteractive(bool interactive); + + QQmlComponent *delegate() const; + void setDelegate(QQmlComponent *delegate); + +Q_SIGNALS: + void countChanged(); + void currentIndexChanged(); + void interactiveChanged(); + void delegateChanged(); + +protected: + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickPageIndicator) + Q_DECLARE_PRIVATE(QQuickPageIndicator) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickPageIndicator) + +#endif // QQUICKPAGEINDICATOR_P_H diff --git a/src/quicktemplates2/qquickpane.cpp b/src/quicktemplates2/qquickpane.cpp new file mode 100644 index 00000000000..3cdc450fd10 --- /dev/null +++ b/src/quicktemplates2/qquickpane.cpp @@ -0,0 +1,432 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpane_p.h" +#include "qquickpane_p_p.h" +#include "qquickcontentitem_p.h" + +#include <QtCore/qloggingcategory.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcPane, "qt.quick.controls.pane") + +/*! + \qmltype Pane + \inherits Control +//! \instantiates QQuickPane + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes + \brief Provides a background matching with the application style and theme. + + Pane provides a background color that matches with the application style + and theme. Pane does not provide a layout of its own, but requires you to + position its contents, for instance by creating a \l RowLayout or a + \l ColumnLayout. + + Items declared as children of a Pane are automatically parented to the + Pane's \l[QtQuickControls2]{Control::}{contentItem}. Items created + dynamically need to be explicitly parented to the \c contentItem. + + \section1 Content Sizing + + If only a single item is used within a Pane, it will resize to fit the + implicit size of its contained item. This makes it particularly suitable + for use together with layouts. + + \image qtquickcontrols2-pane.png + + \snippet qtquickcontrols2-pane.qml 1 + + Sometimes there might be two items within the pane: + + \code + Pane { + SwipeView { + // ... + } + PageIndicator { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + } + } + \endcode + + In this case, Pane cannot calculate a sensible implicit size. Since we're + anchoring the \l PageIndicator over the \l SwipeView, we can simply set the + content size to the view's implicit size: + + \code + Pane { + contentWidth: view.implicitWidth + contentHeight: view.implicitHeight + + SwipeView { + id: view + // ... + } + PageIndicator { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + } + } + \endcode + + If the \l[QtQuickControls2]{Control::}{contentItem} has no implicit size + and only one child, Pane will use the implicit size of that child. For + example, in the following code, the Pane assumes the size of the Rectangle: + + \code + Pane { + Item { + Rectangle { + implicitWidth: 200 + implicitHeight: 200 + color: "salmon" + } + } + } + \endcode + + \sa {Customizing Pane}, {Container Controls}, + {Focus Management in Qt Quick Controls}, {Event Handling} +*/ + +void QQuickPanePrivate::init() +{ + Q_Q(QQuickPane); + q->setFlag(QQuickItem::ItemIsFocusScope); + q->setAcceptedMouseButtons(Qt::AllButtons); +#if QT_CONFIG(cursor) + q->setCursor(Qt::ArrowCursor); +#endif + connect(q, &QQuickControl::implicitContentWidthChanged, this, &QQuickPanePrivate::updateContentWidth); + connect(q, &QQuickControl::implicitContentHeightChanged, this, &QQuickPanePrivate::updateContentHeight); +} + +QList<QQuickItem *> QQuickPanePrivate::contentChildItems() const +{ + if (!contentItem) + return QList<QQuickItem *>(); + + return contentItem->childItems(); +} + +QQuickItem *QQuickPanePrivate::getContentItem() +{ + Q_Q(QQuickPane); + if (QQuickItem *item = QQuickControlPrivate::getContentItem()) + return item; + + return new QQuickContentItem(q); +} + +void QQuickPanePrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + QQuickControlPrivate::itemImplicitWidthChanged(item); + + if (item == firstChild) + updateImplicitContentWidth(); +} + +void QQuickPanePrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + QQuickControlPrivate::itemImplicitHeightChanged(item); + + if (item == firstChild) + updateImplicitContentHeight(); +} + +void QQuickPanePrivate::contentChildrenChange() +{ + Q_Q(QQuickPane); + QQuickItem *newFirstChild = contentChildItems().value(0); + if (newFirstChild != firstChild) { + if (firstChild) + removeImplicitSizeListener(firstChild); + if (newFirstChild) + addImplicitSizeListener(newFirstChild); + firstChild = newFirstChild; + } + + updateImplicitContentSize(); + emit q->contentChildrenChanged(); +} + +qreal QQuickPanePrivate::getContentWidth() const +{ + if (!contentItem) + return 0; + + const qreal cw = contentItem->implicitWidth(); + if (!qFuzzyIsNull(cw)) + return cw; + + const auto contentChildren = contentChildItems(); + if (contentChildren.count() == 1) + return contentChildren.first()->implicitWidth(); + + return 0; +} + +qreal QQuickPanePrivate::getContentHeight() const +{ + if (!contentItem) + return 0; + + const qreal ch = contentItem->implicitHeight(); + if (!qFuzzyIsNull(ch)) + return ch; + + const auto contentChildren = contentChildItems(); + if (contentChildren.count() == 1) + return contentChildren.first()->implicitHeight(); + + return 0; +} + +void QQuickPanePrivate::updateContentWidth() +{ + Q_Q(QQuickPane); + if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth)) + return; + + const qreal oldContentWidth = contentWidth; + contentWidth = implicitContentWidth; + qCDebug(lcPane) << "contentWidth of" << q << "changed to" << contentWidth; + q->contentSizeChange(QSizeF(contentWidth, contentHeight), QSizeF(oldContentWidth, contentHeight)); + emit q->contentWidthChanged(); +} + +void QQuickPanePrivate::updateContentHeight() +{ + Q_Q(QQuickPane); + if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight)) + return; + + const qreal oldContentHeight = contentHeight; + contentHeight = implicitContentHeight; + qCDebug(lcPane) << "contentHeight of" << q << "changed to" << contentHeight; + q->contentSizeChange(QSizeF(contentWidth, contentHeight), QSizeF(contentWidth, oldContentHeight)); + emit q->contentHeightChanged(); +} + +QQuickPane::QQuickPane(QQuickItem *parent) + : QQuickControl(*(new QQuickPanePrivate), parent) +{ + Q_D(QQuickPane); + d->init(); +} + +QQuickPane::~QQuickPane() +{ + Q_D(QQuickPane); + d->removeImplicitSizeListener(d->contentItem); + d->removeImplicitSizeListener(d->firstChild); +} + +QQuickPane::QQuickPane(QQuickPanePrivate &dd, QQuickItem *parent) + : QQuickControl(dd, parent) +{ + Q_D(QQuickPane); + d->init(); +} + +/*! + \qmlproperty real QtQuick.Controls::Pane::contentWidth + + This property holds the content width. It is used for calculating the total + implicit width of the pane. + + For more information, see \l {Content Sizing}. + + \sa contentHeight +*/ +qreal QQuickPane::contentWidth() const +{ + Q_D(const QQuickPane); + return d->contentWidth; +} + +void QQuickPane::setContentWidth(qreal width) +{ + Q_D(QQuickPane); + d->hasContentWidth = true; + if (qFuzzyCompare(d->contentWidth, width)) + return; + + const qreal oldWidth = d->contentWidth; + d->contentWidth = width; + contentSizeChange(QSizeF(width, d->contentHeight), QSizeF(oldWidth, d->contentHeight)); + emit contentWidthChanged(); +} + +void QQuickPane::resetContentWidth() +{ + Q_D(QQuickPane); + if (!d->hasContentWidth) + return; + + d->hasContentHeight = false; + d->updateContentWidth(); +} + +/*! + \qmlproperty real QtQuick.Controls::Pane::contentHeight + + This property holds the content height. It is used for calculating the total + implicit height of the pane. + + For more information, see \l {Content Sizing}. + + \sa contentWidth +*/ +qreal QQuickPane::contentHeight() const +{ + Q_D(const QQuickPane); + return d->contentHeight; +} + +void QQuickPane::setContentHeight(qreal height) +{ + Q_D(QQuickPane); + d->hasContentHeight = true; + if (qFuzzyCompare(d->contentHeight, height)) + return; + + const qreal oldHeight = d->contentHeight; + d->contentHeight = height; + contentSizeChange(QSizeF(d->contentWidth, height), QSizeF(d->contentWidth, oldHeight)); + emit contentHeightChanged(); +} + +void QQuickPane::resetContentHeight() +{ + Q_D(QQuickPane); + if (!d->hasContentHeight) + return; + + d->hasContentHeight = false; + d->updateContentHeight(); +} + +/*! + \qmlproperty list<Object> QtQuick.Controls::Pane::contentData + \qmldefault + + This property holds the list of content data. + + The list contains all objects that have been declared in QML as children + of the pane. + + \note Unlike \c contentChildren, \c contentData does include non-visual QML + objects. + + \sa Item::data, contentChildren +*/ +QQmlListProperty<QObject> QQuickPanePrivate::contentData() +{ + Q_Q(QQuickPane); + return QQmlListProperty<QObject>(q->contentItem(), nullptr, + QQuickItemPrivate::data_append, + QQuickItemPrivate::data_count, + QQuickItemPrivate::data_at, + QQuickItemPrivate::data_clear); +} + +/*! + \qmlproperty list<Item> QtQuick.Controls::Pane::contentChildren + + This property holds the list of content children. + + The list contains all items that have been declared in QML as children + of the pane. + + \note Unlike \c contentData, \c contentChildren does not include non-visual + QML objects. + + \sa Item::children, contentData +*/ +QQmlListProperty<QQuickItem> QQuickPanePrivate::contentChildren() +{ + Q_Q(QQuickPane); + return QQmlListProperty<QQuickItem>(q->contentItem(), nullptr, + QQuickItemPrivate::children_append, + QQuickItemPrivate::children_count, + QQuickItemPrivate::children_at, + QQuickItemPrivate::children_clear); +} + +void QQuickPane::componentComplete() +{ + Q_D(QQuickPane); + QQuickControl::componentComplete(); + d->updateImplicitContentSize(); +} + +void QQuickPane::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + Q_D(QQuickPane); + QQuickControl::contentItemChange(newItem, oldItem); + if (oldItem) { + d->removeImplicitSizeListener(oldItem); + QObjectPrivate::disconnect(oldItem, &QQuickItem::childrenChanged, d, &QQuickPanePrivate::contentChildrenChange); + } + if (newItem) { + d->addImplicitSizeListener(newItem); + QObjectPrivate::connect(newItem, &QQuickItem::childrenChanged, d, &QQuickPanePrivate::contentChildrenChange); + } + d->contentChildrenChange(); +} + +void QQuickPane::contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) +{ + Q_UNUSED(newSize); + Q_UNUSED(oldSize); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickPane::accessibleRole() const +{ + return QAccessible::Pane; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickpane_p.cpp" diff --git a/src/quicktemplates2/qquickpane_p.h b/src/quicktemplates2/qquickpane_p.h new file mode 100644 index 00000000000..2aeb94cd7e6 --- /dev/null +++ b/src/quicktemplates2/qquickpane_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPANE_P_H +#define QQUICKPANE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQml/qqmllist.h> + +QT_BEGIN_NAMESPACE + +class QQuickPanePrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPane : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth RESET resetContentWidth NOTIFY contentWidthChanged FINAL) + Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight RESET resetContentHeight NOTIFY contentHeightChanged FINAL) + Q_PRIVATE_PROPERTY(QQuickPane::d_func(), QQmlListProperty<QObject> contentData READ contentData FINAL) + Q_PRIVATE_PROPERTY(QQuickPane::d_func(), QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) + Q_CLASSINFO("DefaultProperty", "contentData") + QML_NAMED_ELEMENT(Pane) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickPane(QQuickItem *parent = nullptr); + ~QQuickPane(); + + qreal contentWidth() const; + void setContentWidth(qreal width); + void resetContentWidth(); + + qreal contentHeight() const; + void setContentHeight(qreal height); + void resetContentHeight(); + +Q_SIGNALS: + void contentWidthChanged(); + void contentHeightChanged(); + void contentChildrenChanged(); + +protected: + QQuickPane(QQuickPanePrivate &dd, QQuickItem *parent); + + void componentComplete() override; + + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + virtual void contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize); + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickPane) + Q_DECLARE_PRIVATE(QQuickPane) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickPane) + +#endif // QQUICKPANE_P_H diff --git a/src/quicktemplates2/qquickpane_p_p.h b/src/quicktemplates2/qquickpane_p_p.h new file mode 100644 index 00000000000..bd89aee2f89 --- /dev/null +++ b/src/quicktemplates2/qquickpane_p_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPANE_P_P_H +#define QQUICKPANE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickPane; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPanePrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickPane) + +public: + void init(); + + virtual QQmlListProperty<QObject> contentData(); + virtual QQmlListProperty<QQuickItem> contentChildren(); + virtual QList<QQuickItem *> contentChildItems() const; + + QQuickItem *getContentItem() override; + + qreal getContentWidth() const override; + qreal getContentHeight() const override; + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + void contentChildrenChange(); + + void updateContentWidth(); + void updateContentHeight(); + + bool hasContentWidth = false; + bool hasContentHeight = false; + qreal contentWidth = 0; + qreal contentHeight = 0; + QQuickItem *firstChild = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPANE_P_P_H diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp new file mode 100644 index 00000000000..de862cfc118 --- /dev/null +++ b/src/quicktemplates2/qquickpopup.cpp @@ -0,0 +1,2844 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpopup_p.h" +#include "qquickpopup_p_p.h" +#include "qquickpopupanchors_p.h" +#include "qquickpopupitem_p_p.h" +#include "qquickpopuppositioner_p_p.h" +#include "qquickapplicationwindow_p.h" +#include "qquickoverlay_p_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickdialog_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/private/qquickaccessibleattached_p.h> +#include <QtQuick/private/qquicktransition_p.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcDimmer, "qt.quick.controls.popup.dimmer") +Q_LOGGING_CATEGORY(lcPopup, "qt.quick.controls.popup") + +/*! + \qmltype Popup + \inherits QtObject +//! \instantiates QQuickPopup + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-popups + \ingroup qtquickcontrols2-focusscopes + \brief Base type of popup-like user interface controls. + + Popup is the base type of popup-like user interface controls. It can be + used with \l Window or \l ApplicationWindow. + + \qml + import QtQuick.Window 2.2 + import QtQuick.Controls 2.12 + + ApplicationWindow { + id: window + width: 400 + height: 400 + visible: true + + Button { + text: "Open" + onClicked: popup.open() + } + + Popup { + id: popup + x: 100 + y: 100 + width: 200 + height: 300 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent + } + } + \endqml + + In order to ensure that a popup is displayed above other items in the + scene, it is recommended to use ApplicationWindow. ApplicationWindow also + provides background dimming effects. + + Popup does not provide a layout of its own, but requires you to position + its contents, for instance by creating a \l RowLayout or a \l ColumnLayout. + + Items declared as children of a Popup are automatically parented to the + Popups's \l contentItem. Items created dynamically need to be explicitly + parented to the contentItem. + + \section1 Popup Layout + + The following diagram illustrates the layout of a popup within a window: + + \image qtquickcontrols2-popup.png + + The \l implicitWidth and \l implicitHeight of a popup are typically based + on the implicit sizes of the background and the content item plus any insets + and paddings. These properties determine how large the popup will be when no + explicit \l width or \l height is specified. + + The geometry of the \l contentItem is determined by the padding. The following + example reserves 10px padding between the boundaries of the popup and its content: + + \code + Popup { + padding: 10 + + contentItem: Text { + text: "Content" + } + } + \endcode + + The \l background item fills the entire width and height of the popup, + unless insets or an explicit size have been given for it. + + Negative insets can be used to make the background larger than the popup. + The following example uses negative insets to place a shadow outside the + popup's boundaries: + + \code + Popup { + topInset: -2 + leftInset: -2 + rightInset: -6 + bottomInset: -6 + + background: BorderImage { + source: ":/images/shadowed-background.png" + } + } + \endcode + + \section1 Popup Sizing + + If only a single item is used within a Popup, it will resize to fit the + implicit size of its contained item. This makes it particularly suitable + for use together with layouts. + + \code + Popup { + ColumnLayout { + anchors.fill: parent + CheckBox { text: qsTr("E-mail") } + CheckBox { text: qsTr("Calendar") } + CheckBox { text: qsTr("Contacts") } + } + } + \endcode + + Sometimes there might be two items within the popup: + + \code + Popup { + SwipeView { + // ... + } + PageIndicator { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + } + } + \endcode + + In this case, Popup cannot calculate a sensible implicit size. Since we're + anchoring the \l PageIndicator over the \l SwipeView, we can simply set the + content size to the view's implicit size: + + \code + Popup { + contentWidth: view.implicitWidth + contentHeight: view.implicitHeight + + SwipeView { + id: view + // ... + } + PageIndicator { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + } + } + \endcode + + \note The popup's \l{contentItem}{content item} gets parented to the + \l{Overlay::overlay}{overlay}, and does not live within the popup's parent. + Because of that, a \l{Item::scale}{scale} applied to the tree in which + the popup lives does not apply to the visual popup. To make the popup + of e.g. a \l{ComboBox} follow the scale of the combobox, apply the same scale + to the \l{Overlay::overlay}{overlay} as well: + + \code + Window { + property double scaleFactor: 2.0 + + Scale { + id: scale + xScale: scaleFactor + yScale: scaleFactor + } + Item { + id: scaledContent + transform: scale + + ComboBox { + id: combobox + // ... + } + } + + Overlay.overlay.transform: scale + } + \endcode + + \section1 Popup Positioning + + Similar to items in Qt Quick, Popup's \l x and \l y coordinates are + relative to its parent. This means that opening a popup that is a + child of a \l Button, for example, will cause the popup to be positioned + relative to the button. + + \include qquickoverlay-popup-parent.qdocinc + + Another way to center a popup in the window regardless of its parent item + is to use \l {anchors.centerIn}: + + \snippet qtquickcontrols2-popup.qml centerIn + + To ensure that the popup is positioned within the bounds of the enclosing + window, the \l margins property can be set to a non-negative value. + + \section1 Popup Transitions + + Since Qt 5.15.3 the following properties are restored to their original values from before + the enter transition after the exit transition is completed. + + \list + \li \l opacity + \li \l scale + \endlist + + This allows the built-in styles to animate on these properties without losing any explicitly + defined value. + + \section1 Back/Escape Event Handling + + By default, a Popup will close if the Escape or Back keys are pressed. This + can be problematic for popups which contain items that want to handle those + events themselves. There are two solutions to this: + + \list + \li Set Popup's \l closePolicy to a value that does not include + \c {Popup.CloseOnEscape}. + \li Handle \l {Keys}' \l {Keys::}{shortcutOverride} signal and accept the + event before Popup can. + \endlist + + \sa {Popup Controls}, {Customizing Popup}, ApplicationWindow +*/ + +/*! + \qmlsignal void QtQuick.Controls::Popup::opened() + + This signal is emitted when the popup is opened. + + \sa aboutToShow() +*/ + +/*! + \qmlsignal void QtQuick.Controls::Popup::closed() + + This signal is emitted when the popup is closed. + + \sa aboutToHide() +*/ + +/*! + \qmlsignal void QtQuick.Controls::Popup::aboutToShow() + + This signal is emitted when the popup is about to show. + + \sa opened() +*/ + +/*! + \qmlsignal void QtQuick.Controls::Popup::aboutToHide() + + This signal is emitted when the popup is about to hide. + + \sa closed() +*/ + +const QQuickPopup::ClosePolicy QQuickPopupPrivate::DefaultClosePolicy = QQuickPopup::CloseOnEscape | QQuickPopup::CloseOnPressOutside; + +QQuickPopupPrivate::QQuickPopupPrivate() + : transitionManager(this) +{ +} + +void QQuickPopupPrivate::init() +{ + Q_Q(QQuickPopup); + popupItem = new QQuickPopupItem(q); + popupItem->setVisible(false); + q->setParentItem(qobject_cast<QQuickItem *>(parent)); + QObject::connect(popupItem, &QQuickControl::paddingChanged, q, &QQuickPopup::paddingChanged); + QObject::connect(popupItem, &QQuickControl::backgroundChanged, q, &QQuickPopup::backgroundChanged); + QObject::connect(popupItem, &QQuickControl::contentItemChanged, q, &QQuickPopup::contentItemChanged); + QObject::connect(popupItem, &QQuickControl::implicitContentWidthChanged, q, &QQuickPopup::implicitContentWidthChanged); + QObject::connect(popupItem, &QQuickControl::implicitContentHeightChanged, q, &QQuickPopup::implicitContentHeightChanged); + QObject::connect(popupItem, &QQuickControl::implicitBackgroundWidthChanged, q, &QQuickPopup::implicitBackgroundWidthChanged); + QObject::connect(popupItem, &QQuickControl::implicitBackgroundHeightChanged, q, &QQuickPopup::implicitBackgroundHeightChanged); +} + +void QQuickPopupPrivate::closeOrReject() +{ + Q_Q(QQuickPopup); + if (QQuickDialog *dialog = qobject_cast<QQuickDialog*>(q)) + dialog->reject(); + else + q->close(); + touchId = -1; +} + +bool QQuickPopupPrivate::tryClose(const QPointF &pos, QQuickPopup::ClosePolicy flags) +{ + if (!interactive) + return false; + + static const QQuickPopup::ClosePolicy outsideFlags = QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnReleaseOutside; + static const QQuickPopup::ClosePolicy outsideParentFlags = QQuickPopup::CloseOnPressOutsideParent | QQuickPopup::CloseOnReleaseOutsideParent; + + const bool onOutside = closePolicy & (flags & outsideFlags); + const bool onOutsideParent = closePolicy & (flags & outsideParentFlags); + + if ((onOutside && outsidePressed) || (onOutsideParent && outsideParentPressed)) { + if (!contains(pos) && (!dimmer || dimmer->contains(dimmer->mapFromScene(pos)))) { + if (!onOutsideParent || !parentItem || !parentItem->contains(parentItem->mapFromScene(pos))) { + closeOrReject(); + return true; + } + } + } + return false; +} + +bool QQuickPopupPrivate::contains(const QPointF &scenePos) const +{ + return popupItem->contains(popupItem->mapFromScene(scenePos)); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +bool QQuickPopupPrivate::acceptTouch(const QTouchEvent::TouchPoint &point) +{ + if (point.id() == touchId) + return true; + + if (touchId == -1 && point.state() != QEventPoint::Released) { + touchId = point.id(); + return true; + } + + return false; +} +#endif + +bool QQuickPopupPrivate::blockInput(QQuickItem *item, const QPointF &point) const +{ + // don't propagate events within the popup beyond the overlay + if (popupItem->contains(popupItem->mapFromScene(point)) + && item == QQuickOverlay::overlay(window)) { + return true; + } + + // don't block presses and releases + // a) outside a non-modal popup, + // b) to popup children/content, or + // b) outside a modal popups's background dimming + return modal && !popupItem->isAncestorOf(item) && (!dimmer || dimmer->contains(dimmer->mapFromScene(point))); +} + +bool QQuickPopupPrivate::handlePress(QQuickItem *item, const QPointF &point, ulong timestamp) +{ + Q_UNUSED(timestamp); + pressPoint = point; + outsidePressed = !contains(point); + outsideParentPressed = outsidePressed && parentItem && !parentItem->contains(parentItem->mapFromScene(point)); + tryClose(point, QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent); + return blockInput(item, point); +} + +bool QQuickPopupPrivate::handleMove(QQuickItem *item, const QPointF &point, ulong timestamp) +{ + Q_UNUSED(timestamp); + return blockInput(item, point); +} + +bool QQuickPopupPrivate::handleRelease(QQuickItem *item, const QPointF &point, ulong timestamp) +{ + Q_UNUSED(timestamp); + if (item != popupItem && !contains(pressPoint)) + tryClose(point, QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent); + pressPoint = QPointF(); + outsidePressed = false; + outsideParentPressed = false; + touchId = -1; + return blockInput(item, point); +} + +void QQuickPopupPrivate::handleUngrab() +{ + Q_Q(QQuickPopup); + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + if (overlay) { + QQuickOverlayPrivate *p = QQuickOverlayPrivate::get(overlay); + if (p->mouseGrabberPopup == q) + p->mouseGrabberPopup = nullptr; + } + pressPoint = QPointF(); + touchId = -1; +} + +bool QQuickPopupPrivate::handleMouseEvent(QQuickItem *item, QMouseEvent *event) +{ + switch (event->type()) { + case QEvent::MouseButtonPress: + return handlePress(item, event->scenePosition(), event->timestamp()); + case QEvent::MouseMove: + return handleMove(item, event->scenePosition(), event->timestamp()); + case QEvent::MouseButtonRelease: + return handleRelease(item, event->scenePosition(), event->timestamp()); + default: + Q_UNREACHABLE(); + return false; + } +} + +bool QQuickPopupPrivate::handleHoverEvent(QQuickItem *item, QHoverEvent *event) +{ + switch (event->type()) { + case QEvent::HoverEnter: + case QEvent::HoverMove: + case QEvent::HoverLeave: + return blockInput(item, event->scenePosition()); + default: + Q_UNREACHABLE(); + return false; + } +} + +#if QT_CONFIG(quicktemplates2_multitouch) +bool QQuickPopupPrivate::handleTouchEvent(QQuickItem *item, QTouchEvent *event) +{ + switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + for (const QTouchEvent::TouchPoint &point : event->points()) { + if (event->type() != QEvent::TouchEnd && !acceptTouch(point)) + return blockInput(item, point.position()); + + switch (point.state()) { + case QEventPoint::Pressed: + return handlePress(item, item->mapToScene(point.position()), event->timestamp()); + case QEventPoint::Updated: + return handleMove(item, item->mapToScene(point.position()), event->timestamp()); + case QEventPoint::Released: + return handleRelease(item, item->mapToScene(point.position()), event->timestamp()); + default: + break; + } + } + break; + + case QEvent::TouchCancel: + handleUngrab(); + break; + + default: + break; + } + + return false; +} +#endif + +bool QQuickPopupPrivate::prepareEnterTransition() +{ + Q_Q(QQuickPopup); + if (!window) { + qmlWarning(q) << "cannot find any window to open popup in."; + return false; + } + + if (transitionState == EnterTransition && transitionManager.isRunning()) + return false; + + if (transitionState != EnterTransition) { + popupItem->setParentItem(QQuickOverlay::overlay(window)); + if (dim) + createOverlay(); + showOverlay(); + emit q->aboutToShow(); + visible = true; + transitionState = EnterTransition; + popupItem->setVisible(true); + getPositioner()->setParentItem(parentItem); + emit q->visibleChanged(); + + if (focus) + popupItem->setFocus(true, Qt::PopupFocusReason); + } + return true; +} + +bool QQuickPopupPrivate::prepareExitTransition() +{ + Q_Q(QQuickPopup); + if (transitionState == ExitTransition && transitionManager.isRunning()) + return false; + + // We need to cache the original scale and opacity values so we can reset it after + // the exit transition is done so they have the original values again + prevScale = popupItem->scale(); + prevOpacity = popupItem->opacity(); + + if (transitionState != ExitTransition) { + // The setFocus(false) call below removes any active focus before we're + // able to check it in finalizeExitTransition. + if (!hadActiveFocusBeforeExitTransition) + hadActiveFocusBeforeExitTransition = popupItem->hasActiveFocus(); + if (focus) + popupItem->setFocus(false, Qt::PopupFocusReason); + transitionState = ExitTransition; + hideOverlay(); + emit q->aboutToHide(); + emit q->openedChanged(); + } + return true; +} + +void QQuickPopupPrivate::finalizeEnterTransition() +{ + Q_Q(QQuickPopup); + transitionState = NoTransition; + getPositioner()->reposition(); + emit q->openedChanged(); + opened(); +} + +void QQuickPopupPrivate::finalizeExitTransition() +{ + Q_Q(QQuickPopup); + getPositioner()->setParentItem(nullptr); + if (popupItem) { + popupItem->setParentItem(nullptr); + popupItem->setVisible(false); + } + destroyOverlay(); + + if (hadActiveFocusBeforeExitTransition && window) { + // restore focus to the next popup in chain, or to the window content if there are no other popups open + QQuickPopup *nextFocusPopup = nullptr; + if (QQuickOverlay *overlay = QQuickOverlay::overlay(window)) { + const auto stackingOrderPopups = QQuickOverlayPrivate::get(overlay)->stackingOrderPopups(); + for (auto popup : stackingOrderPopups) { + if (QQuickPopupPrivate::get(popup)->transitionState != ExitTransition + && popup->hasFocus()) { + nextFocusPopup = popup; + break; + } + } + } + if (nextFocusPopup) { + nextFocusPopup->forceActiveFocus(Qt::PopupFocusReason); + } else { + QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow*>(window); + if (applicationWindow) + applicationWindow->contentItem()->setFocus(true, Qt::PopupFocusReason); + else + window->contentItem()->setFocus(true, Qt::PopupFocusReason); + } + } + + visible = false; + transitionState = NoTransition; + hadActiveFocusBeforeExitTransition = false; + emit q->visibleChanged(); + emit q->closed(); + if (popupItem) { + popupItem->setScale(prevScale); + popupItem->setOpacity(prevOpacity); + } +} + +void QQuickPopupPrivate::opened() +{ + Q_Q(QQuickPopup); + emit q->opened(); +} + +QMarginsF QQuickPopupPrivate::getMargins() const +{ + Q_Q(const QQuickPopup); + return QMarginsF(q->leftMargin(), q->topMargin(), q->rightMargin(), q->bottomMargin()); +} + +void QQuickPopupPrivate::setTopMargin(qreal value, bool reset) +{ + Q_Q(QQuickPopup); + qreal oldMargin = q->topMargin(); + topMargin = value; + hasTopMargin = !reset; + if ((!reset && !qFuzzyCompare(oldMargin, value)) || (reset && !qFuzzyCompare(oldMargin, margins))) { + emit q->topMarginChanged(); + q->marginsChange(QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin), + QMarginsF(leftMargin, oldMargin, rightMargin, bottomMargin)); + } +} + +void QQuickPopupPrivate::setLeftMargin(qreal value, bool reset) +{ + Q_Q(QQuickPopup); + qreal oldMargin = q->leftMargin(); + leftMargin = value; + hasLeftMargin = !reset; + if ((!reset && !qFuzzyCompare(oldMargin, value)) || (reset && !qFuzzyCompare(oldMargin, margins))) { + emit q->leftMarginChanged(); + q->marginsChange(QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin), + QMarginsF(oldMargin, topMargin, rightMargin, bottomMargin)); + } +} + +void QQuickPopupPrivate::setRightMargin(qreal value, bool reset) +{ + Q_Q(QQuickPopup); + qreal oldMargin = q->rightMargin(); + rightMargin = value; + hasRightMargin = !reset; + if ((!reset && !qFuzzyCompare(oldMargin, value)) || (reset && !qFuzzyCompare(oldMargin, margins))) { + emit q->rightMarginChanged(); + q->marginsChange(QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin), + QMarginsF(leftMargin, topMargin, oldMargin, bottomMargin)); + } +} + +void QQuickPopupPrivate::setBottomMargin(qreal value, bool reset) +{ + Q_Q(QQuickPopup); + qreal oldMargin = q->bottomMargin(); + bottomMargin = value; + hasBottomMargin = !reset; + if ((!reset && !qFuzzyCompare(oldMargin, value)) || (reset && !qFuzzyCompare(oldMargin, margins))) { + emit q->bottomMarginChanged(); + q->marginsChange(QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin), + QMarginsF(leftMargin, topMargin, rightMargin, oldMargin)); + } +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty Object QtQuick.Controls::Popup::anchors.centerIn + + Anchors provide a way to position an item by specifying its + relationship with other items. + + A common use case is to center a popup within its parent. One way to do + this is with the \l[QtQuick]{Item::}{x} and \l[QtQuick]{Item::}{y} properties. Anchors offer + a more convenient approach: + + \qml + Pane { + // ... + + Popup { + anchors.centerIn: parent + } + } + \endqml + + It is also possible to center the popup in the window by using \l Overlay: + + \snippet qtquickcontrols2-popup.qml centerIn + + This makes it easy to center a popup in the window from any component. + + \note Popups can only be centered within their immediate parent or + the window overlay; trying to center in other items will produce a warning. + + \sa {Popup Positioning}, {Item::}{anchors}, {Using Qt Quick Controls types + in property declarations} +*/ +QQuickPopupAnchors *QQuickPopupPrivate::getAnchors() +{ + Q_Q(QQuickPopup); + if (!anchors) + anchors = new QQuickPopupAnchors(q); + return anchors; +} + +QQuickPopupPositioner *QQuickPopupPrivate::getPositioner() +{ + Q_Q(QQuickPopup); + if (!positioner) + positioner = new QQuickPopupPositioner(q); + return positioner; +} + +void QQuickPopupPrivate::setWindow(QQuickWindow *newWindow) +{ + Q_Q(QQuickPopup); + if (window == newWindow) + return; + + if (window) { + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + if (overlay) + QQuickOverlayPrivate::get(overlay)->removePopup(q); + } + + window = newWindow; + + if (newWindow) { + QQuickOverlay *overlay = QQuickOverlay::overlay(newWindow); + if (overlay) + QQuickOverlayPrivate::get(overlay)->addPopup(q); + + QQuickControlPrivate *p = QQuickControlPrivate::get(popupItem); + p->resolveFont(); + if (QQuickApplicationWindow *appWindow = qobject_cast<QQuickApplicationWindow *>(newWindow)) + p->updateLocale(appWindow->locale(), false); // explicit=false + } + + emit q->windowChanged(newWindow); + + if (complete && visible && window) + transitionManager.transitionEnter(); +} + +void QQuickPopupPrivate::itemDestroyed(QQuickItem *item) +{ + Q_Q(QQuickPopup); + if (item == parentItem) + q->setParentItem(nullptr); +} + +void QQuickPopupPrivate::reposition() +{ + getPositioner()->reposition(); +} + +QPalette QQuickPopupPrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::System); +} + +static QQuickItem *createDimmer(QQmlComponent *component, QQuickPopup *popup, QQuickItem *parent) +{ + QQuickItem *item = nullptr; + if (component) { + QQmlContext *creationContext = component->creationContext(); + if (!creationContext) + creationContext = qmlContext(popup); + QQmlContext *context = new QQmlContext(creationContext, popup); + context->setContextObject(popup); + item = qobject_cast<QQuickItem*>(component->beginCreate(context)); + } + + // when there is no overlay component available (with plain QQuickWindow), + // use a plain QQuickItem as a fallback to block hover events + if (!item && popup->isModal()) + item = new QQuickItem; + + if (item) { + item->setOpacity(popup->isVisible() ? 1.0 : 0.0); + item->setParentItem(parent); + item->stackBefore(popup->popupItem()); + item->setZ(popup->z()); + // needed for the virtual keyboard to set a containment mask on the dimmer item + qCDebug(lcDimmer) << "dimmer" << item << "registered with" << parent; + parent->setProperty("_q_dimmerItem", QVariant::fromValue<QQuickItem*>(item)); + if (popup->isModal()) { + item->setAcceptedMouseButtons(Qt::AllButtons); +#if QT_CONFIG(cursor) + item->setCursor(Qt::ArrowCursor); +#endif +#if QT_CONFIG(quicktemplates2_hover) + // TODO: switch to QStyleHints::useHoverEffects in Qt 5.8 + item->setAcceptHoverEvents(true); + // item->setAcceptHoverEvents(QGuiApplication::styleHints()->useHoverEffects()); + // connect(QGuiApplication::styleHints(), &QStyleHints::useHoverEffectsChanged, item, &QQuickItem::setAcceptHoverEvents); +#endif + } + if (component) + component->completeCreate(); + } + qCDebug(lcDimmer) << "finished creating dimmer from component" << component + << "for popup" << popup << "with parent" << parent << "- item is:" << item; + return item; +} + +void QQuickPopupPrivate::createOverlay() +{ + Q_Q(QQuickPopup); + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + if (!overlay) + return; + + QQmlComponent *component = nullptr; + QQuickOverlayAttached *overlayAttached = qobject_cast<QQuickOverlayAttached *>(qmlAttachedPropertiesObject<QQuickOverlay>(q, false)); + if (overlayAttached) + component = modal ? overlayAttached->modal() : overlayAttached->modeless(); + + if (!component) + component = modal ? overlay->modal() : overlay->modeless(); + + if (!dimmer) + dimmer = createDimmer(component, q, overlay); + resizeOverlay(); +} + +void QQuickPopupPrivate::destroyOverlay() +{ + if (dimmer) { + qCDebug(lcDimmer) << "destroying dimmer" << dimmer; + if (QObject *dimmerParentItem = dimmer->parentItem()) { + if (dimmerParentItem->property("_q_dimmerItem").value<QQuickItem*>() == dimmer) + dimmerParentItem->setProperty("_q_dimmerItem", QVariant()); + } + dimmer->setParentItem(nullptr); + dimmer->deleteLater(); + dimmer = nullptr; + } +} + +void QQuickPopupPrivate::toggleOverlay() +{ + destroyOverlay(); + if (dim) + createOverlay(); +} + +void QQuickPopupPrivate::showOverlay() +{ + // use QQmlProperty instead of QQuickItem::setOpacity() to trigger QML Behaviors + if (dim && dimmer) + QQmlProperty::write(dimmer, QStringLiteral("opacity"), 1.0); +} + +void QQuickPopupPrivate::hideOverlay() +{ + // use QQmlProperty instead of QQuickItem::setOpacity() to trigger QML Behaviors + if (dim && dimmer) + QQmlProperty::write(dimmer, QStringLiteral("opacity"), 0.0); +} + +void QQuickPopupPrivate::resizeOverlay() +{ + if (!dimmer) + return; + + qreal w = window ? window->width() : 0; + qreal h = window ? window->height() : 0; + dimmer->setSize(QSizeF(w, h)); +} + +QQuickPopupTransitionManager::QQuickPopupTransitionManager(QQuickPopupPrivate *popup) + : popup(popup) +{ +} + +void QQuickPopupTransitionManager::transitionEnter() +{ + if (popup->transitionState == QQuickPopupPrivate::ExitTransition) + cancel(); + + if (!popup->prepareEnterTransition()) + return; + + if (popup->window) + transition(popup->enterActions, popup->enter, popup->q_func()); + else + finished(); +} + +void QQuickPopupTransitionManager::transitionExit() +{ + if (!popup->prepareExitTransition()) + return; + + if (popup->window) + transition(popup->exitActions, popup->exit, popup->q_func()); + else + finished(); +} + +void QQuickPopupTransitionManager::finished() +{ + if (popup->transitionState == QQuickPopupPrivate::EnterTransition) + popup->finalizeEnterTransition(); + else if (popup->transitionState == QQuickPopupPrivate::ExitTransition) + popup->finalizeExitTransition(); +} + +QQuickPopup::QQuickPopup(QObject *parent) + : QObject(*(new QQuickPopupPrivate), parent) +{ + Q_D(QQuickPopup); + d->init(); +} + +QQuickPopup::QQuickPopup(QQuickPopupPrivate &dd, QObject *parent) + : QObject(dd, parent) +{ + Q_D(QQuickPopup); + d->init(); +} + +QQuickPopup::~QQuickPopup() +{ + Q_D(QQuickPopup); + setParentItem(nullptr); + d->popupItem->ungrabShortcut(); + + // If the popup is destroyed before the exit transition finishes, + // the necessary cleanup (removing modal dimmers that block mouse events, + // emitting closed signal, etc.) won't happen. That's why we do it manually here. + if (d->transitionState == QQuickPopupPrivate::ExitTransition && d->transitionManager.isRunning()) + d->finalizeExitTransition(); + + delete d->popupItem; + d->popupItem = nullptr; + delete d->positioner; + d->positioner = nullptr; +} + +/*! + \qmlmethod void QtQuick.Controls::Popup::open() + + Opens the popup. + + \sa visible +*/ +void QQuickPopup::open() +{ + setVisible(true); +} + +/*! + \qmlmethod void QtQuick.Controls::Popup::close() + + Closes the popup. + + \sa visible +*/ +void QQuickPopup::close() +{ + setVisible(false); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::x + + This property holds the x-coordinate of the popup. + + \sa y, z +*/ +qreal QQuickPopup::x() const +{ + Q_D(const QQuickPopup); + return d->effectiveX; +} + +void QQuickPopup::setX(qreal x) +{ + Q_D(QQuickPopup); + setPosition(QPointF(x, d->y)); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::y + + This property holds the y-coordinate of the popup. + + \sa x, z +*/ +qreal QQuickPopup::y() const +{ + Q_D(const QQuickPopup); + return d->effectiveY; +} + +void QQuickPopup::setY(qreal y) +{ + Q_D(QQuickPopup); + setPosition(QPointF(d->x, y)); +} + +QPointF QQuickPopup::position() const +{ + Q_D(const QQuickPopup); + return QPointF(d->effectiveX, d->effectiveY); +} + +void QQuickPopup::setPosition(const QPointF &pos) +{ + Q_D(QQuickPopup); + const bool xChange = !qFuzzyCompare(d->x, pos.x()); + const bool yChange = !qFuzzyCompare(d->y, pos.y()); + if (!xChange && !yChange) + return; + + d->x = pos.x(); + d->y = pos.y(); + if (d->popupItem->isVisible()) { + d->reposition(); + } else { + if (xChange) + emit xChanged(); + if (yChange) + emit yChanged(); + } +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::z + + This property holds the z-value of the popup. Z-value determines + the stacking order of popups. + + If two visible popups have the same z-value, the last one that + was opened will be on top. + + The default z-value is \c 0. + + \sa x, y +*/ +qreal QQuickPopup::z() const +{ + Q_D(const QQuickPopup); + return d->popupItem->z(); +} + +void QQuickPopup::setZ(qreal z) +{ + Q_D(QQuickPopup); + if (qFuzzyCompare(z, d->popupItem->z())) + return; + d->popupItem->setZ(z); + emit zChanged(); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::width + + This property holds the width of the popup. +*/ +qreal QQuickPopup::width() const +{ + Q_D(const QQuickPopup); + return d->popupItem->width(); +} + +void QQuickPopup::setWidth(qreal width) +{ + Q_D(QQuickPopup); + d->hasWidth = true; + d->popupItem->setWidth(width); +} + +void QQuickPopup::resetWidth() +{ + Q_D(QQuickPopup); + if (!d->hasWidth) + return; + + d->hasWidth = false; + d->popupItem->resetWidth(); + if (d->popupItem->isVisible()) + d->reposition(); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::height + + This property holds the height of the popup. +*/ +qreal QQuickPopup::height() const +{ + Q_D(const QQuickPopup); + return d->popupItem->height(); +} + +void QQuickPopup::setHeight(qreal height) +{ + Q_D(QQuickPopup); + d->hasHeight = true; + d->popupItem->setHeight(height); +} + +void QQuickPopup::resetHeight() +{ + Q_D(QQuickPopup); + if (!d->hasHeight) + return; + + d->hasHeight = false; + d->popupItem->resetHeight(); + if (d->popupItem->isVisible()) + d->reposition(); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::implicitWidth + + This property holds the implicit width of the popup. +*/ +qreal QQuickPopup::implicitWidth() const +{ + Q_D(const QQuickPopup); + return d->popupItem->implicitWidth(); +} + +void QQuickPopup::setImplicitWidth(qreal width) +{ + Q_D(QQuickPopup); + d->popupItem->setImplicitWidth(width); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::implicitHeight + + This property holds the implicit height of the popup. +*/ +qreal QQuickPopup::implicitHeight() const +{ + Q_D(const QQuickPopup); + return d->popupItem->implicitHeight(); +} + +void QQuickPopup::setImplicitHeight(qreal height) +{ + Q_D(QQuickPopup); + d->popupItem->setImplicitHeight(height); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::contentWidth + + This property holds the content width. It is used for calculating the + total implicit width of the Popup. + + For more information, see \l {Popup Sizing}. + + \sa contentHeight +*/ +qreal QQuickPopup::contentWidth() const +{ + Q_D(const QQuickPopup); + return d->popupItem->contentWidth(); +} + +void QQuickPopup::setContentWidth(qreal width) +{ + Q_D(QQuickPopup); + d->popupItem->setContentWidth(width); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::contentHeight + + This property holds the content height. It is used for calculating the + total implicit height of the Popup. + + For more information, see \l {Popup Sizing}. + + \sa contentWidth +*/ +qreal QQuickPopup::contentHeight() const +{ + Q_D(const QQuickPopup); + return d->popupItem->contentHeight(); +} + +void QQuickPopup::setContentHeight(qreal height) +{ + Q_D(QQuickPopup); + d->popupItem->setContentHeight(height); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::availableWidth + \readonly + + This property holds the width available to the \l contentItem after + deducting horizontal padding from the \l {Item::}{width} of the popup. + + \sa padding, leftPadding, rightPadding +*/ +qreal QQuickPopup::availableWidth() const +{ + Q_D(const QQuickPopup); + return d->popupItem->availableWidth(); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::availableHeight + \readonly + + This property holds the height available to the \l contentItem after + deducting vertical padding from the \l {Item::}{height} of the popup. + + \sa padding, topPadding, bottomPadding +*/ +qreal QQuickPopup::availableHeight() const +{ + Q_D(const QQuickPopup); + return d->popupItem->availableHeight(); +} + +/*! + \since QtQuick.Controls 2.1 (Qt 5.8) + \qmlproperty real QtQuick.Controls::Popup::spacing + + This property holds the spacing. + + Spacing is useful for popups that have multiple or repetitive building + blocks. For example, some styles use spacing to determine the distance + between the header, content, and footer of \l Dialog. Spacing is not + enforced by Popup, so each style may interpret it differently, and some + may ignore it altogether. +*/ +qreal QQuickPopup::spacing() const +{ + Q_D(const QQuickPopup); + return d->popupItem->spacing(); +} + +void QQuickPopup::setSpacing(qreal spacing) +{ + Q_D(QQuickPopup); + d->popupItem->setSpacing(spacing); +} + +void QQuickPopup::resetSpacing() +{ + setSpacing(0); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::margins + + This property holds the distance between the edges of the popup and the + edges of its window. + + A popup with negative margins is not pushed within the bounds + of the enclosing window. The default value is \c -1. + + \sa topMargin, leftMargin, rightMargin, bottomMargin, {Popup Layout} +*/ +qreal QQuickPopup::margins() const +{ + Q_D(const QQuickPopup); + return d->margins; +} + +void QQuickPopup::setMargins(qreal margins) +{ + Q_D(QQuickPopup); + if (qFuzzyCompare(d->margins, margins)) + return; + QMarginsF oldMargins(leftMargin(), topMargin(), rightMargin(), bottomMargin()); + d->margins = margins; + emit marginsChanged(); + QMarginsF newMargins(leftMargin(), topMargin(), rightMargin(), bottomMargin()); + if (!qFuzzyCompare(newMargins.top(), oldMargins.top())) + emit topMarginChanged(); + if (!qFuzzyCompare(newMargins.left(), oldMargins.left())) + emit leftMarginChanged(); + if (!qFuzzyCompare(newMargins.right(), oldMargins.right())) + emit rightMarginChanged(); + if (!qFuzzyCompare(newMargins.bottom(), oldMargins.bottom())) + emit bottomMarginChanged(); + marginsChange(newMargins, oldMargins); +} + +void QQuickPopup::resetMargins() +{ + setMargins(-1); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::topMargin + + This property holds the distance between the top edge of the popup and + the top edge of its window. + + A popup with a negative top margin is not pushed within the top edge + of the enclosing window. The default value is \c -1. + + \sa margins, bottomMargin, {Popup Layout} +*/ +qreal QQuickPopup::topMargin() const +{ + Q_D(const QQuickPopup); + if (d->hasTopMargin) + return d->topMargin; + return d->margins; +} + +void QQuickPopup::setTopMargin(qreal margin) +{ + Q_D(QQuickPopup); + d->setTopMargin(margin); +} + +void QQuickPopup::resetTopMargin() +{ + Q_D(QQuickPopup); + d->setTopMargin(-1, true); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::leftMargin + + This property holds the distance between the left edge of the popup and + the left edge of its window. + + A popup with a negative left margin is not pushed within the left edge + of the enclosing window. The default value is \c -1. + + \sa margins, rightMargin, {Popup Layout} +*/ +qreal QQuickPopup::leftMargin() const +{ + Q_D(const QQuickPopup); + if (d->hasLeftMargin) + return d->leftMargin; + return d->margins; +} + +void QQuickPopup::setLeftMargin(qreal margin) +{ + Q_D(QQuickPopup); + d->setLeftMargin(margin); +} + +void QQuickPopup::resetLeftMargin() +{ + Q_D(QQuickPopup); + d->setLeftMargin(-1, true); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::rightMargin + + This property holds the distance between the right edge of the popup and + the right edge of its window. + + A popup with a negative right margin is not pushed within the right edge + of the enclosing window. The default value is \c -1. + + \sa margins, leftMargin, {Popup Layout} +*/ +qreal QQuickPopup::rightMargin() const +{ + Q_D(const QQuickPopup); + if (d->hasRightMargin) + return d->rightMargin; + return d->margins; +} + +void QQuickPopup::setRightMargin(qreal margin) +{ + Q_D(QQuickPopup); + d->setRightMargin(margin); +} + +void QQuickPopup::resetRightMargin() +{ + Q_D(QQuickPopup); + d->setRightMargin(-1, true); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::bottomMargin + + This property holds the distance between the bottom edge of the popup and + the bottom edge of its window. + + A popup with a negative bottom margin is not pushed within the bottom edge + of the enclosing window. The default value is \c -1. + + \sa margins, topMargin, {Popup Layout} +*/ +qreal QQuickPopup::bottomMargin() const +{ + Q_D(const QQuickPopup); + if (d->hasBottomMargin) + return d->bottomMargin; + return d->margins; +} + +void QQuickPopup::setBottomMargin(qreal margin) +{ + Q_D(QQuickPopup); + d->setBottomMargin(margin); +} + +void QQuickPopup::resetBottomMargin() +{ + Q_D(QQuickPopup); + d->setBottomMargin(-1, true); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::padding + + This property holds the default padding. + + \include qquickpopup-padding.qdocinc + + \sa availableWidth, availableHeight, topPadding, leftPadding, rightPadding, bottomPadding +*/ +qreal QQuickPopup::padding() const +{ + Q_D(const QQuickPopup); + return d->popupItem->padding(); +} + +void QQuickPopup::setPadding(qreal padding) +{ + Q_D(QQuickPopup); + d->popupItem->setPadding(padding); +} + +void QQuickPopup::resetPadding() +{ + Q_D(QQuickPopup); + d->popupItem->resetPadding(); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::topPadding + + This property holds the top padding. Unless explicitly set, the value + is equal to \c verticalPadding. + + \include qquickpopup-padding.qdocinc + + \sa padding, bottomPadding, verticalPadding, availableHeight +*/ +qreal QQuickPopup::topPadding() const +{ + Q_D(const QQuickPopup); + return d->popupItem->topPadding(); +} + +void QQuickPopup::setTopPadding(qreal padding) +{ + Q_D(QQuickPopup); + d->popupItem->setTopPadding(padding); +} + +void QQuickPopup::resetTopPadding() +{ + Q_D(QQuickPopup); + d->popupItem->resetTopPadding(); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::leftPadding + + This property holds the left padding. Unless explicitly set, the value + is equal to \c horizontalPadding. + + \include qquickpopup-padding.qdocinc + + \sa padding, rightPadding, horizontalPadding, availableWidth +*/ +qreal QQuickPopup::leftPadding() const +{ + Q_D(const QQuickPopup); + return d->popupItem->leftPadding(); +} + +void QQuickPopup::setLeftPadding(qreal padding) +{ + Q_D(QQuickPopup); + d->popupItem->setLeftPadding(padding); +} + +void QQuickPopup::resetLeftPadding() +{ + Q_D(QQuickPopup); + d->popupItem->resetLeftPadding(); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::rightPadding + + This property holds the right padding. Unless explicitly set, the value + is equal to \c horizontalPadding. + + \include qquickpopup-padding.qdocinc + + \sa padding, leftPadding, horizontalPadding, availableWidth +*/ +qreal QQuickPopup::rightPadding() const +{ + Q_D(const QQuickPopup); + return d->popupItem->rightPadding(); +} + +void QQuickPopup::setRightPadding(qreal padding) +{ + Q_D(QQuickPopup); + d->popupItem->setRightPadding(padding); +} + +void QQuickPopup::resetRightPadding() +{ + Q_D(QQuickPopup); + d->popupItem->resetRightPadding(); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::bottomPadding + + This property holds the bottom padding. Unless explicitly set, the value + is equal to \c verticalPadding. + + \include qquickpopup-padding.qdocinc + + \sa padding, topPadding, verticalPadding, availableHeight +*/ +qreal QQuickPopup::bottomPadding() const +{ + Q_D(const QQuickPopup); + return d->popupItem->bottomPadding(); +} + +void QQuickPopup::setBottomPadding(qreal padding) +{ + Q_D(QQuickPopup); + d->popupItem->setBottomPadding(padding); +} + +void QQuickPopup::resetBottomPadding() +{ + Q_D(QQuickPopup); + d->popupItem->resetBottomPadding(); +} + +/*! + \qmlproperty Locale QtQuick.Controls::Popup::locale + + This property holds the locale of the popup. + + \sa mirrored, {LayoutMirroring}{LayoutMirroring} +*/ +QLocale QQuickPopup::locale() const +{ + Q_D(const QQuickPopup); + return d->popupItem->locale(); +} + +void QQuickPopup::setLocale(const QLocale &locale) +{ + Q_D(QQuickPopup); + d->popupItem->setLocale(locale); +} + +void QQuickPopup::resetLocale() +{ + Q_D(QQuickPopup); + d->popupItem->resetLocale(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::Popup::mirrored + \readonly + + This property holds whether the popup is mirrored. + + This property is provided for convenience. A popup is considered mirrored + when its visual layout direction is right-to-left; that is, when using a + right-to-left locale. + + \sa locale, {Right-to-left User Interfaces} +*/ +bool QQuickPopup::isMirrored() const +{ + Q_D(const QQuickPopup); + return d->popupItem->isMirrored(); +} + +/*! + \qmlproperty font QtQuick.Controls::Popup::font + + This property holds the font currently set for the popup. + + Popup propagates explicit font properties to its children. If you change a specific + property on a popup's font, that property propagates to all of the popup's children, + overriding any system defaults for that property. + + \code + Popup { + font.family: "Courier" + + Column { + Label { + text: qsTr("This will use Courier...") + } + + Switch { + text: qsTr("... and so will this") + } + } + } + \endcode + + \sa Control::font, ApplicationWindow::font +*/ +QFont QQuickPopup::font() const +{ + Q_D(const QQuickPopup); + return d->popupItem->font(); +} + +void QQuickPopup::setFont(const QFont &font) +{ + Q_D(QQuickPopup); + d->popupItem->setFont(font); +} + +void QQuickPopup::resetFont() +{ + Q_D(QQuickPopup); + d->popupItem->resetFont(); +} + +QQuickWindow *QQuickPopup::window() const +{ + Q_D(const QQuickPopup); + return d->window; +} + +QQuickItem *QQuickPopup::popupItem() const +{ + Q_D(const QQuickPopup); + return d->popupItem; +} + +/*! + \qmlproperty Item QtQuick.Controls::Popup::parent + + This property holds the parent item. +*/ +QQuickItem *QQuickPopup::parentItem() const +{ + Q_D(const QQuickPopup); + return d->parentItem; +} + +void QQuickPopup::setParentItem(QQuickItem *parent) +{ + Q_D(QQuickPopup); + if (d->parentItem == parent) + return; + + if (d->parentItem) { + QObjectPrivate::disconnect(d->parentItem, &QQuickItem::windowChanged, d, &QQuickPopupPrivate::setWindow); + QQuickItemPrivate::get(d->parentItem)->removeItemChangeListener(d, QQuickItemPrivate::Destroyed); + } + d->parentItem = parent; + QQuickPopupPositioner *positioner = d->getPositioner(); + if (positioner->parentItem()) + positioner->setParentItem(parent); + if (parent) { + QObjectPrivate::connect(parent, &QQuickItem::windowChanged, d, &QQuickPopupPrivate::setWindow); + QQuickItemPrivate::get(d->parentItem)->addItemChangeListener(d, QQuickItemPrivate::Destroyed); + } else { + close(); + } + d->setWindow(parent ? parent->window() : nullptr); + emit parentChanged(); +} + +void QQuickPopup::resetParentItem() +{ + if (QQuickWindow *window = qobject_cast<QQuickWindow *>(parent())) + setParentItem(window->contentItem()); + else + setParentItem(qobject_cast<QQuickItem *>(parent())); +} + +/*! + \qmlproperty Item QtQuick.Controls::Popup::background + + This property holds the background item. + + \note If the background item has no explicit size specified, it automatically + follows the popup's size. In most cases, there is no need to specify + width or height for a background item. + + \note Most popups use the implicit size of the background item to calculate + the implicit size of the popup itself. If you replace the background item + with a custom one, you should also consider providing a sensible implicit + size for it (unless it is an item like \l Image which has its own implicit + size). + + \sa {Customizing Popup} +*/ +QQuickItem *QQuickPopup::background() const +{ + Q_D(const QQuickPopup); + return d->popupItem->background(); +} + +void QQuickPopup::setBackground(QQuickItem *background) +{ + Q_D(QQuickPopup); + d->popupItem->setBackground(background); +} + +/*! + \qmlproperty Item QtQuick.Controls::Popup::contentItem + + This property holds the content item of the popup. + + The content item is the visual implementation of the popup. When the + popup is made visible, the content item is automatically reparented to + the \l {Overlay::overlay}{overlay item}. + + \note The content item is automatically resized to fit within the + \l padding of the popup. + + \note Most popups use the implicit size of the content item to calculate + the implicit size of the popup itself. If you replace the content item + with a custom one, you should also consider providing a sensible implicit + size for it (unless it is an item like \l Text which has its own implicit + size). + + \sa {Customizing Popup} +*/ +QQuickItem *QQuickPopup::contentItem() const +{ + Q_D(const QQuickPopup); + return d->popupItem->contentItem(); +} + +void QQuickPopup::setContentItem(QQuickItem *item) +{ + Q_D(QQuickPopup); + d->popupItem->setContentItem(item); +} + +/*! + \qmlproperty list<Object> QtQuick.Controls::Popup::contentData + \qmldefault + + This property holds the list of content data. + + The list contains all objects that have been declared in QML as children + of the popup. + + \note Unlike \c contentChildren, \c contentData does include non-visual QML + objects. + + \sa Item::data, contentChildren +*/ +QQmlListProperty<QObject> QQuickPopupPrivate::contentData() +{ + QQuickControlPrivate *p = QQuickControlPrivate::get(popupItem); + if (!p->contentItem) + p->executeContentItem(); + return QQmlListProperty<QObject>(popupItem->contentItem(), nullptr, + QQuickItemPrivate::data_append, + QQuickItemPrivate::data_count, + QQuickItemPrivate::data_at, + QQuickItemPrivate::data_clear); +} + +/*! + \qmlproperty list<Item> QtQuick.Controls::Popup::contentChildren + + This property holds the list of content children. + + The list contains all items that have been declared in QML as children + of the popup. + + \note Unlike \c contentData, \c contentChildren does not include non-visual + QML objects. + + \sa Item::children, contentData +*/ +QQmlListProperty<QQuickItem> QQuickPopupPrivate::contentChildren() +{ + return QQmlListProperty<QQuickItem>(popupItem->contentItem(), nullptr, + QQuickItemPrivate::children_append, + QQuickItemPrivate::children_count, + QQuickItemPrivate::children_at, + QQuickItemPrivate::children_clear); +} + +/*! + \qmlproperty bool QtQuick.Controls::Popup::clip + + This property holds whether clipping is enabled. The default value is \c false. +*/ +bool QQuickPopup::clip() const +{ + Q_D(const QQuickPopup); + return d->popupItem->clip(); +} + +void QQuickPopup::setClip(bool clip) +{ + Q_D(QQuickPopup); + if (clip == d->popupItem->clip()) + return; + d->popupItem->setClip(clip); + emit clipChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::Popup::focus + + This property holds whether the popup wants focus. + + When the popup actually receives focus, \l activeFocus will be \c true. + For more information, see \l {Keyboard Focus in Qt Quick}. + + The default value is \c false. + + \sa activeFocus +*/ +bool QQuickPopup::hasFocus() const +{ + Q_D(const QQuickPopup); + return d->focus; +} + +void QQuickPopup::setFocus(bool focus) +{ + Q_D(QQuickPopup); + if (d->focus == focus) + return; + d->focus = focus; + emit focusChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::Popup::activeFocus + \readonly + + This property holds whether the popup has active focus. + + \sa focus, {Keyboard Focus in Qt Quick} +*/ +bool QQuickPopup::hasActiveFocus() const +{ + Q_D(const QQuickPopup); + return d->popupItem->hasActiveFocus(); +} + +/*! + \qmlproperty bool QtQuick.Controls::Popup::modal + + This property holds whether the popup is modal. + + Modal popups often have a distinctive background dimming effect defined + in \l {Overlay::modal}{Overlay.modal}, and do not allow press + or release events through to items beneath them. For example, if the user + accidentally clicks outside of a popup, any item beneath that popup at + the location of the click will not receive the event. + + On desktop platforms, it is common for modal popups to be closed only when + the escape key is pressed. To achieve this behavior, set + \l closePolicy to \c Popup.CloseOnEscape. By default, \c closePolicy + is set to \c {Popup.CloseOnEscape | Popup.CloseOnPressOutside}, which + means that clicking outside of a modal popup will close it. + + The default value is \c false. + + \sa dim +*/ +bool QQuickPopup::isModal() const +{ + Q_D(const QQuickPopup); + return d->modal; +} + +void QQuickPopup::setModal(bool modal) +{ + Q_D(QQuickPopup); + if (d->modal == modal) + return; + d->modal = modal; + if (d->complete && d->visible) + d->toggleOverlay(); + emit modalChanged(); + + QQuickItemPrivate::get(d->popupItem)->isTabFence = modal; + + if (!d->hasDim) { + setDim(modal); + d->hasDim = false; + } +} + +/*! + \qmlproperty bool QtQuick.Controls::Popup::dim + + This property holds whether the popup dims the background. + + Unless explicitly set, this property follows the value of \l modal. To + return to the default value, set this property to \c undefined. + + \sa modal, {Overlay::modeless}{Overlay.modeless} +*/ +bool QQuickPopup::dim() const +{ + Q_D(const QQuickPopup); + return d->dim; +} + +void QQuickPopup::setDim(bool dim) +{ + Q_D(QQuickPopup); + d->hasDim = true; + + if (d->dim == dim) + return; + + d->dim = dim; + if (d->complete && d->visible) + d->toggleOverlay(); + emit dimChanged(); +} + +void QQuickPopup::resetDim() +{ + Q_D(QQuickPopup); + if (!d->hasDim) + return; + + setDim(d->modal); + d->hasDim = false; +} + +/*! + \qmlproperty bool QtQuick.Controls::Popup::visible + + This property holds whether the popup is visible. The default value is \c false. + + \sa open(), close(), opened +*/ +bool QQuickPopup::isVisible() const +{ + Q_D(const QQuickPopup); + return d->visible && d->popupItem->isVisible(); +} + +void QQuickPopup::setVisible(bool visible) +{ + Q_D(QQuickPopup); + if (d->visible == visible && d->transitionState != QQuickPopupPrivate::ExitTransition) + return; + + if (d->complete) { + if (visible) + d->transitionManager.transitionEnter(); + else + d->transitionManager.transitionExit(); + } else { + d->visible = visible; + } +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::Popup::enabled + + This property holds whether the popup is enabled. The default value is \c true. + + \sa visible, Item::enabled +*/ +bool QQuickPopup::isEnabled() const +{ + Q_D(const QQuickPopup); + return d->popupItem->isEnabled(); +} + +void QQuickPopup::setEnabled(bool enabled) +{ + Q_D(QQuickPopup); + d->popupItem->setEnabled(enabled); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::Popup::opened + + This property holds whether the popup is fully open. The popup is considered opened + when it's visible and neither the \l enter nor \l exit transitions are running. + + \sa open(), close(), visible +*/ +bool QQuickPopup::isOpened() const +{ + Q_D(const QQuickPopup); + return d->transitionState == QQuickPopupPrivate::NoTransition && isVisible(); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::opacity + + This property holds the opacity of the popup. Opacity is specified as a number between + \c 0.0 (fully transparent) and \c 1.0 (fully opaque). The default value is \c 1.0. + + \sa visible +*/ +qreal QQuickPopup::opacity() const +{ + Q_D(const QQuickPopup); + return d->popupItem->opacity(); +} + +void QQuickPopup::setOpacity(qreal opacity) +{ + Q_D(QQuickPopup); + d->popupItem->setOpacity(opacity); +} + +/*! + \qmlproperty real QtQuick.Controls::Popup::scale + + This property holds the scale factor of the popup. The default value is \c 1.0. + + A scale of less than \c 1.0 causes the popup to be rendered at a smaller size, + and a scale greater than \c 1.0 renders the popup at a larger size. Negative + scales are not supported. +*/ +qreal QQuickPopup::scale() const +{ + Q_D(const QQuickPopup); + return d->popupItem->scale(); +} + +void QQuickPopup::setScale(qreal scale) +{ + Q_D(QQuickPopup); + if (qFuzzyCompare(scale, d->popupItem->scale())) + return; + d->popupItem->setScale(scale); + emit scaleChanged(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::Popup::closePolicy + + This property determines the circumstances under which the popup closes. + The flags can be combined to allow several ways of closing the popup. + + The available values are: + \value Popup.NoAutoClose The popup will only close when manually instructed to do so. + \value Popup.CloseOnPressOutside The popup will close when the mouse is pressed outside of it. + \value Popup.CloseOnPressOutsideParent The popup will close when the mouse is pressed outside of its parent. + \value Popup.CloseOnReleaseOutside The popup will close when the mouse is released outside of it. + \value Popup.CloseOnReleaseOutsideParent The popup will close when the mouse is released outside of its parent. + \value Popup.CloseOnEscape The popup will close when the escape key is pressed while the popup + has active focus. + + The \c {CloseOnPress*} and \c {CloseOnRelease*} policies only apply for events + outside of popups. That is, if there are two popups open and the first has + \c Popup.CloseOnPressOutside as its policy, clicking on the second popup will + not result in the first closing. + + The default value is \c {Popup.CloseOnEscape | Popup.CloseOnPressOutside}. + This default value may interfere with existing shortcuts in the application + that makes use of the \e Escape key. + + \note There is a known limitation that the \c Popup.CloseOnReleaseOutside + and \c Popup.CloseOnReleaseOutsideParent policies only work with + \l modal popups. +*/ +QQuickPopup::ClosePolicy QQuickPopup::closePolicy() const +{ + Q_D(const QQuickPopup); + return d->closePolicy; +} + +void QQuickPopup::setClosePolicy(ClosePolicy policy) +{ + Q_D(QQuickPopup); + d->hasClosePolicy = true; + if (d->closePolicy == policy) + return; + d->closePolicy = policy; + if (isVisible()) { + if (policy & QQuickPopup::CloseOnEscape) + d->popupItem->grabShortcut(); + else + d->popupItem->ungrabShortcut(); + } + emit closePolicyChanged(); +} + +void QQuickPopup::resetClosePolicy() +{ + Q_D(QQuickPopup); + setClosePolicy(QQuickPopupPrivate::DefaultClosePolicy); + d->hasClosePolicy = false; +} + +/*! + \qmlproperty enumeration QtQuick.Controls::Popup::transformOrigin + + This property holds the origin point for transformations in enter and exit transitions. + + Nine transform origins are available, as shown in the image below. + The default transform origin is \c Popup.Center. + + \image qtquickcontrols2-popup-transformorigin.png + + \sa enter, exit, Item::transformOrigin +*/ +QQuickPopup::TransformOrigin QQuickPopup::transformOrigin() const +{ + Q_D(const QQuickPopup); + return static_cast<TransformOrigin>(d->popupItem->transformOrigin()); +} + +void QQuickPopup::setTransformOrigin(TransformOrigin origin) +{ + Q_D(QQuickPopup); + d->popupItem->setTransformOrigin(static_cast<QQuickItem::TransformOrigin>(origin)); +} + +/*! + \qmlproperty Transition QtQuick.Controls::Popup::enter + + This property holds the transition that is applied to the popup item + when the popup is opened and enters the screen. + + The following example animates the opacity of the popup when it enters + the screen: + \code + Popup { + enter: Transition { + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0 } + } + } + \endcode + + \sa exit +*/ +QQuickTransition *QQuickPopup::enter() const +{ + Q_D(const QQuickPopup); + return d->enter; +} + +void QQuickPopup::setEnter(QQuickTransition *transition) +{ + Q_D(QQuickPopup); + if (d->enter == transition) + return; + d->enter = transition; + emit enterChanged(); +} + +/*! + \qmlproperty Transition QtQuick.Controls::Popup::exit + + This property holds the transition that is applied to the popup item + when the popup is closed and exits the screen. + + The following example animates the opacity of the popup when it exits + the screen: + \code + Popup { + exit: Transition { + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0 } + } + } + \endcode + + \sa enter +*/ +QQuickTransition *QQuickPopup::exit() const +{ + Q_D(const QQuickPopup); + return d->exit; +} + +void QQuickPopup::setExit(QQuickTransition *transition) +{ + Q_D(QQuickPopup); + if (d->exit == transition) + return; + d->exit = transition; + emit exitChanged(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::horizontalPadding + + This property holds the horizontal padding. Unless explicitly set, the value + is equal to \c padding. + + \include qquickpopup-padding.qdocinc + + \sa padding, leftPadding, rightPadding, verticalPadding +*/ +qreal QQuickPopup::horizontalPadding() const +{ + Q_D(const QQuickPopup); + return d->popupItem->horizontalPadding(); +} + +void QQuickPopup::setHorizontalPadding(qreal padding) +{ + Q_D(QQuickPopup); + d->popupItem->setHorizontalPadding(padding); +} + +void QQuickPopup::resetHorizontalPadding() +{ + Q_D(QQuickPopup); + d->popupItem->resetHorizontalPadding(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::verticalPadding + + This property holds the vertical padding. Unless explicitly set, the value + is equal to \c padding. + + \include qquickpopup-padding.qdocinc + + \sa padding, topPadding, bottomPadding, horizontalPadding +*/ +qreal QQuickPopup::verticalPadding() const +{ + Q_D(const QQuickPopup); + return d->popupItem->verticalPadding(); +} + +void QQuickPopup::setVerticalPadding(qreal padding) +{ + Q_D(QQuickPopup); + d->popupItem->setVerticalPadding(padding); +} + +void QQuickPopup::resetVerticalPadding() +{ + Q_D(QQuickPopup); + d->popupItem->resetVerticalPadding(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::implicitContentWidth + \readonly + + This property holds the implicit content width. + + The value is calculated based on the content children. + + \sa implicitContentHeight, implicitBackgroundWidth +*/ +qreal QQuickPopup::implicitContentWidth() const +{ + Q_D(const QQuickPopup); + return d->popupItem->implicitContentWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::implicitContentHeight + \readonly + + This property holds the implicit content height. + + The value is calculated based on the content children. + + \sa implicitContentWidth, implicitBackgroundHeight +*/ +qreal QQuickPopup::implicitContentHeight() const +{ + Q_D(const QQuickPopup); + return d->popupItem->implicitContentHeight(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::implicitBackgroundWidth + \readonly + + This property holds the implicit background width. + + The value is equal to \c {background ? background.implicitWidth : 0}. + + \sa implicitBackgroundHeight, implicitContentWidth +*/ +qreal QQuickPopup::implicitBackgroundWidth() const +{ + Q_D(const QQuickPopup); + return d->popupItem->implicitBackgroundWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::implicitBackgroundHeight + \readonly + + This property holds the implicit background height. + + The value is equal to \c {background ? background.implicitHeight : 0}. + + \sa implicitBackgroundWidth, implicitContentHeight +*/ +qreal QQuickPopup::implicitBackgroundHeight() const +{ + Q_D(const QQuickPopup); + return d->popupItem->implicitBackgroundHeight(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::topInset + + This property holds the top inset for the background. + + \sa {Popup Layout}, bottomInset +*/ +qreal QQuickPopup::topInset() const +{ + Q_D(const QQuickPopup); + return d->popupItem->topInset(); +} + +void QQuickPopup::setTopInset(qreal inset) +{ + Q_D(QQuickPopup); + d->popupItem->setTopInset(inset); +} + +void QQuickPopup::resetTopInset() +{ + Q_D(QQuickPopup); + d->popupItem->resetTopInset(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::leftInset + + This property holds the left inset for the background. + + \sa {Popup Layout}, rightInset +*/ +qreal QQuickPopup::leftInset() const +{ + Q_D(const QQuickPopup); + return d->popupItem->leftInset(); +} + +void QQuickPopup::setLeftInset(qreal inset) +{ + Q_D(QQuickPopup); + d->popupItem->setLeftInset(inset); +} + +void QQuickPopup::resetLeftInset() +{ + Q_D(QQuickPopup); + d->popupItem->resetLeftInset(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::rightInset + + This property holds the right inset for the background. + + \sa {Popup Layout}, leftInset +*/ +qreal QQuickPopup::rightInset() const +{ + Q_D(const QQuickPopup); + return d->popupItem->rightInset(); +} + +void QQuickPopup::setRightInset(qreal inset) +{ + Q_D(QQuickPopup); + d->popupItem->setRightInset(inset); +} + +void QQuickPopup::resetRightInset() +{ + Q_D(QQuickPopup); + d->popupItem->resetRightInset(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::bottomInset + + This property holds the bottom inset for the background. + + \sa {Popup Layout}, topInset +*/ +qreal QQuickPopup::bottomInset() const +{ + Q_D(const QQuickPopup); + return d->popupItem->bottomInset(); +} + +void QQuickPopup::setBottomInset(qreal inset) +{ + Q_D(QQuickPopup); + d->popupItem->setBottomInset(inset); +} + +void QQuickPopup::resetBottomInset() +{ + Q_D(QQuickPopup); + d->popupItem->resetBottomInset(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty palette QtQuick.Controls::Popup::palette + + This property holds the palette currently set for the popup. + + Popup propagates explicit palette properties to its children. If you change a specific + property on a popup's palette, that property propagates to all of the popup's children, + overriding any system defaults for that property. + + \code + Popup { + palette.text: "red" + + Column { + Label { + text: qsTr("This will use red color...") + } + + Switch { + text: qsTr("... and so will this") + } + } + } + \endcode + + \sa Item::palette, Window::palette, ColorGroup, Palette +*/ + +bool QQuickPopup::filtersChildMouseEvents() const +{ + Q_D(const QQuickPopup); + return d->popupItem->filtersChildMouseEvents(); +} + +void QQuickPopup::setFiltersChildMouseEvents(bool filter) +{ + Q_D(QQuickPopup); + d->popupItem->setFiltersChildMouseEvents(filter); +} + +/*! + \qmlmethod QtQuick.Controls::Popup::forceActiveFocus(enumeration reason = Qt.OtherFocusReason) + + Forces active focus on the popup with the given \a reason. + + This method sets focus on the popup and ensures that all ancestor + \l FocusScope objects in the object hierarchy are also given \l focus. + + \sa activeFocus, Qt::FocusReason +*/ +void QQuickPopup::forceActiveFocus(Qt::FocusReason reason) +{ + Q_D(QQuickPopup); + d->popupItem->forceActiveFocus(reason); +} + +void QQuickPopup::classBegin() +{ + Q_D(QQuickPopup); + d->complete = false; + QQmlContext *context = qmlContext(this); + if (context) + QQmlEngine::setContextForObject(d->popupItem, context); + d->popupItem->classBegin(); +} + +void QQuickPopup::componentComplete() +{ + Q_D(QQuickPopup); + qCDebug(lcPopup) << "componentComplete" << this; + if (!parentItem()) + resetParentItem(); + + if (d->visible && d->window) + d->transitionManager.transitionEnter(); + + d->complete = true; + d->popupItem->componentComplete(); + + if (isVisible()) { + if (d->closePolicy & QQuickPopup::CloseOnEscape) + d->popupItem->grabShortcut(); + else + d->popupItem->ungrabShortcut(); + } +} + +bool QQuickPopup::isComponentComplete() const +{ + Q_D(const QQuickPopup); + return d->complete; +} + +bool QQuickPopup::childMouseEventFilter(QQuickItem *child, QEvent *event) +{ + Q_UNUSED(child); + Q_UNUSED(event); + return false; +} + +void QQuickPopup::focusInEvent(QFocusEvent *event) +{ + event->accept(); +} + +void QQuickPopup::focusOutEvent(QFocusEvent *event) +{ + event->accept(); +} + +void QQuickPopup::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickPopup); + event->accept(); + + if (hasActiveFocus() && (event->key() == Qt::Key_Tab || event->key() == Qt::Key_Backtab)) + QQuickItemPrivate::focusNextPrev(d->popupItem, event->key() == Qt::Key_Tab); +} + +void QQuickPopup::keyReleaseEvent(QKeyEvent *event) +{ + event->accept(); +} + +void QQuickPopup::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickPopup); + event->setAccepted(d->handleMouseEvent(d->popupItem, event)); +} + +void QQuickPopup::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QQuickPopup); + event->setAccepted(d->handleMouseEvent(d->popupItem, event)); +} + +void QQuickPopup::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QQuickPopup); + event->setAccepted(d->handleMouseEvent(d->popupItem, event)); +} + +void QQuickPopup::mouseDoubleClickEvent(QMouseEvent *event) +{ + event->accept(); +} + +void QQuickPopup::mouseUngrabEvent() +{ + Q_D(QQuickPopup); + d->handleUngrab(); +} + +bool QQuickPopup::overlayEvent(QQuickItem *item, QEvent *event) +{ + Q_D(QQuickPopup); + switch (event->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: + case QEvent::MouseMove: + case QEvent::Wheel: + if (d->modal) + event->accept(); + return d->modal; + +#if QT_CONFIG(quicktemplates2_multitouch) + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + return d->handleTouchEvent(item, static_cast<QTouchEvent *>(event)); +#endif + case QEvent::HoverEnter: + case QEvent::HoverMove: + case QEvent::HoverLeave: + return d->handleHoverEvent(item, static_cast<QHoverEvent *>(event)); + + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + return d->handleMouseEvent(item, static_cast<QMouseEvent *>(event)); + + default: + return false; + } +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickPopup::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickPopup); + d->handleTouchEvent(d->popupItem, event); +} + +void QQuickPopup::touchUngrabEvent() +{ + Q_D(QQuickPopup); + d->handleUngrab(); +} +#endif + +#if QT_CONFIG(wheelevent) +void QQuickPopup::wheelEvent(QWheelEvent *event) +{ + event->accept(); +} +#endif + +void QQuickPopup::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + Q_UNUSED(newItem); + Q_UNUSED(oldItem); +} + +void QQuickPopup::contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) +{ + qCDebug(lcPopup) << "contentSizeChange called on" << this << "with newSize" << newSize << "oldSize" << oldSize; + if (!qFuzzyCompare(newSize.width(), oldSize.width())) + emit contentWidthChanged(); + if (!qFuzzyCompare(newSize.height(), oldSize.height())) + emit contentHeightChanged(); +} + +void QQuickPopup::fontChange(const QFont &newFont, const QFont &oldFont) +{ + Q_UNUSED(newFont); + Q_UNUSED(oldFont); + emit fontChanged(); +} + +void QQuickPopup::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickPopup); + qCDebug(lcPopup) << "geometryChange called on" << this << "with newGeometry" << newGeometry << "oldGeometry" << oldGeometry; + d->reposition(); + if (!qFuzzyCompare(newGeometry.width(), oldGeometry.width())) { + emit widthChanged(); + emit availableWidthChanged(); + } + if (!qFuzzyCompare(newGeometry.height(), oldGeometry.height())) { + emit heightChanged(); + emit availableHeightChanged(); + } +} + +void QQuickPopup::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + Q_D(QQuickPopup); + + switch (change) { + case QQuickItem::ItemActiveFocusHasChanged: + emit activeFocusChanged(); + break; + case QQuickItem::ItemOpacityHasChanged: + emit opacityChanged(); + break; + case QQuickItem::ItemVisibleHasChanged: + if (isComponentComplete() && d->closePolicy & CloseOnEscape) { + if (data.boolValue) + d->popupItem->grabShortcut(); + else + d->popupItem->ungrabShortcut(); + } + break; + default: + break; + } +} + +void QQuickPopup::localeChange(const QLocale &newLocale, const QLocale &oldLocale) +{ + Q_UNUSED(newLocale); + Q_UNUSED(oldLocale); + emit localeChanged(); +} + +void QQuickPopup::marginsChange(const QMarginsF &newMargins, const QMarginsF &oldMargins) +{ + Q_D(QQuickPopup); + Q_UNUSED(newMargins); + Q_UNUSED(oldMargins); + d->reposition(); +} + +void QQuickPopup::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) +{ + const bool tp = !qFuzzyCompare(newPadding.top(), oldPadding.top()); + const bool lp = !qFuzzyCompare(newPadding.left(), oldPadding.left()); + const bool rp = !qFuzzyCompare(newPadding.right(), oldPadding.right()); + const bool bp = !qFuzzyCompare(newPadding.bottom(), oldPadding.bottom()); + + if (tp) + emit topPaddingChanged(); + if (lp) + emit leftPaddingChanged(); + if (rp) + emit rightPaddingChanged(); + if (bp) + emit bottomPaddingChanged(); + + if (lp || rp) { + emit horizontalPaddingChanged(); + emit availableWidthChanged(); + } + if (tp || bp) { + emit verticalPaddingChanged(); + emit availableHeightChanged(); + } +} + +void QQuickPopup::spacingChange(qreal newSpacing, qreal oldSpacing) +{ + Q_UNUSED(newSpacing); + Q_UNUSED(oldSpacing); + emit spacingChanged(); +} + +void QQuickPopup::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset) +{ + if (!qFuzzyCompare(newInset.top(), oldInset.top())) + emit topInsetChanged(); + if (!qFuzzyCompare(newInset.left(), oldInset.left())) + emit leftInsetChanged(); + if (!qFuzzyCompare(newInset.right(), oldInset.right())) + emit rightInsetChanged(); + if (!qFuzzyCompare(newInset.bottom(), oldInset.bottom())) + emit bottomInsetChanged(); +} + +QFont QQuickPopup::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::System); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickPopup::effectiveAccessibleRole() const +{ + auto *attached = qmlAttachedPropertiesObject<QQuickAccessibleAttached>(this, false); + + auto role = QAccessible::NoRole; + if (auto *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(attached)) + role = accessibleAttached->role(); + if (role == QAccessible::NoRole) + role = accessibleRole(); + + return role; +} + +QAccessible::Role QQuickPopup::accessibleRole() const +{ + return QAccessible::Dialog; +} + +void QQuickPopup::accessibilityActiveChanged(bool active) +{ + Q_UNUSED(active); +} +#endif + +QString QQuickPopup::accessibleName() const +{ + Q_D(const QQuickPopup); + return d->popupItem->accessibleName(); +} + +void QQuickPopup::maybeSetAccessibleName(const QString &name) +{ + Q_D(QQuickPopup); + d->popupItem->maybeSetAccessibleName(name); +} + +QVariant QQuickPopup::accessibleProperty(const char *propertyName) +{ + Q_D(const QQuickPopup); + return d->popupItem->accessibleProperty(propertyName); +} + +bool QQuickPopup::setAccessibleProperty(const char *propertyName, const QVariant &value) +{ + Q_D(QQuickPopup); + return d->popupItem->setAccessibleProperty(propertyName, value); +} + +QT_END_NAMESPACE + +#include "moc_qquickpopup_p.cpp" diff --git a/src/quicktemplates2/qquickpopup_p.h b/src/quicktemplates2/qquickpopup_p.h new file mode 100644 index 00000000000..456dcad4a96 --- /dev/null +++ b/src/quicktemplates2/qquickpopup_p.h @@ -0,0 +1,481 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPOPUP_P_H +#define QQUICKPOPUP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtCore/qmargins.h> +#include <QtGui/qevent.h> +#include <QtCore/qlocale.h> +#include <QtGui/qfont.h> +#include <QtGui/qpalette.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> +#include <QtQml/qqml.h> +#include <QtQml/qqmllist.h> +#include <QtQml/qqmlparserstatus.h> +#include <QtQuick/qquickitem.h> + +#if QT_CONFIG(accessibility) +#include <QtGui/qaccessible.h> +#endif + +QT_BEGIN_NAMESPACE + +class QQuickWindow; +class QQuickPopupAnchors; +class QQuickPopupPrivate; +class QQuickTransition; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopup : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged FINAL) + Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged FINAL) + Q_PROPERTY(qreal z READ z WRITE setZ NOTIFY zChanged FINAL) + Q_PROPERTY(qreal width READ width WRITE setWidth RESET resetWidth NOTIFY widthChanged FINAL) + Q_PROPERTY(qreal height READ height WRITE setHeight RESET resetHeight NOTIFY heightChanged FINAL) + Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged FINAL) + Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged FINAL) + Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged FINAL) + Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged FINAL) + Q_PROPERTY(qreal availableWidth READ availableWidth NOTIFY availableWidthChanged FINAL) + Q_PROPERTY(qreal availableHeight READ availableHeight NOTIFY availableHeightChanged FINAL) + Q_PROPERTY(qreal margins READ margins WRITE setMargins RESET resetMargins NOTIFY marginsChanged FINAL) + Q_PROPERTY(qreal topMargin READ topMargin WRITE setTopMargin RESET resetTopMargin NOTIFY topMarginChanged FINAL) + Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin RESET resetLeftMargin NOTIFY leftMarginChanged FINAL) + Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin RESET resetRightMargin NOTIFY rightMarginChanged FINAL) + Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin RESET resetBottomMargin NOTIFY bottomMarginChanged FINAL) + Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged FINAL) + Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged FINAL) + Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged FINAL) + Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged FINAL) + Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged FINAL) + Q_PROPERTY(QLocale locale READ locale WRITE setLocale RESET resetLocale NOTIFY localeChanged FINAL) + Q_PROPERTY(QFont font READ font WRITE setFont RESET resetFont NOTIFY fontChanged FINAL) + Q_PROPERTY(QQuickItem *parent READ parentItem WRITE setParentItem RESET resetParentItem NOTIFY parentChanged FINAL) + Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) + Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) + Q_PRIVATE_PROPERTY(QQuickPopup::d_func(), QQmlListProperty<QObject> contentData READ contentData) + Q_PRIVATE_PROPERTY(QQuickPopup::d_func(), QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) + Q_PROPERTY(bool clip READ clip WRITE setClip NOTIFY clipChanged FINAL) + Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged FINAL) + Q_PROPERTY(bool activeFocus READ hasActiveFocus NOTIFY activeFocusChanged FINAL) + Q_PROPERTY(bool modal READ isModal WRITE setModal NOTIFY modalChanged FINAL) + Q_PROPERTY(bool dim READ dim WRITE setDim RESET resetDim NOTIFY dimChanged FINAL) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL) + Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL) + Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged FINAL) + Q_PROPERTY(ClosePolicy closePolicy READ closePolicy WRITE setClosePolicy RESET resetClosePolicy NOTIFY closePolicyChanged FINAL) + Q_PROPERTY(TransformOrigin transformOrigin READ transformOrigin WRITE setTransformOrigin FINAL) + Q_PROPERTY(QQuickTransition *enter READ enter WRITE setEnter NOTIFY enterChanged FINAL) + Q_PROPERTY(QQuickTransition *exit READ exit WRITE setExit NOTIFY exitChanged FINAL) + // 2.1 (Qt 5.8) + Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing RESET resetSpacing NOTIFY spacingChanged FINAL REVISION(2, 1)) + // 2.3 (Qt 5.10) + Q_PROPERTY(bool opened READ isOpened NOTIFY openedChanged FINAL REVISION(2, 3)) + Q_PROPERTY(bool mirrored READ isMirrored NOTIFY mirroredChanged FINAL REVISION(2, 3)) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL REVISION(2, 3)) + Q_PRIVATE_PROPERTY(QQuickPopup::d_func(), QQuickPalette *palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged REVISION(2, 3)) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal horizontalPadding READ horizontalPadding WRITE setHorizontalPadding RESET resetHorizontalPadding NOTIFY horizontalPaddingChanged FINAL) + Q_PROPERTY(qreal verticalPadding READ verticalPadding WRITE setVerticalPadding RESET resetVerticalPadding NOTIFY verticalPaddingChanged FINAL) + Q_PRIVATE_PROPERTY(QQuickPopup::d_func(), QQuickPopupAnchors *anchors READ getAnchors DESIGNABLE false CONSTANT FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitContentWidth READ implicitContentWidth NOTIFY implicitContentWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitContentHeight READ implicitContentHeight NOTIFY implicitContentHeightChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitBackgroundWidth READ implicitBackgroundWidth NOTIFY implicitBackgroundWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitBackgroundHeight READ implicitBackgroundHeight NOTIFY implicitBackgroundHeightChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal topInset READ topInset WRITE setTopInset RESET resetTopInset NOTIFY topInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal leftInset READ leftInset WRITE setLeftInset RESET resetLeftInset NOTIFY leftInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal rightInset READ rightInset WRITE setRightInset RESET resetRightInset NOTIFY rightInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal bottomInset READ bottomInset WRITE setBottomInset RESET resetBottomInset NOTIFY bottomInsetChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DeferredPropertyNames", "background,contentItem") + Q_CLASSINFO("DefaultProperty", "contentData") + QML_NAMED_ELEMENT(Popup) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickPopup(QObject *parent = nullptr); + ~QQuickPopup(); + + qreal x() const; + void setX(qreal x); + + qreal y() const; + void setY(qreal y); + + QPointF position() const; + void setPosition(const QPointF &pos); + + qreal z() const; + void setZ(qreal z); + + qreal width() const; + void setWidth(qreal width); + void resetWidth(); + + qreal height() const; + void setHeight(qreal height); + void resetHeight(); + + qreal implicitWidth() const; + void setImplicitWidth(qreal width); + + qreal implicitHeight() const; + void setImplicitHeight(qreal height); + + qreal contentWidth() const; + void setContentWidth(qreal width); + + qreal contentHeight() const; + void setContentHeight(qreal height); + + qreal availableWidth() const; + qreal availableHeight() const; + + qreal margins() const; + void setMargins(qreal margins); + void resetMargins(); + + qreal topMargin() const; + void setTopMargin(qreal margin); + void resetTopMargin(); + + qreal leftMargin() const; + void setLeftMargin(qreal margin); + void resetLeftMargin(); + + qreal rightMargin() const; + void setRightMargin(qreal margin); + void resetRightMargin(); + + qreal bottomMargin() const; + void setBottomMargin(qreal margin); + void resetBottomMargin(); + + qreal padding() const; + void setPadding(qreal padding); + void resetPadding(); + + qreal topPadding() const; + void setTopPadding(qreal padding); + void resetTopPadding(); + + qreal leftPadding() const; + void setLeftPadding(qreal padding); + void resetLeftPadding(); + + qreal rightPadding() const; + void setRightPadding(qreal padding); + void resetRightPadding(); + + qreal bottomPadding() const; + void setBottomPadding(qreal padding); + void resetBottomPadding(); + + QLocale locale() const; + void setLocale(const QLocale &locale); + void resetLocale(); + + QFont font() const; + void setFont(const QFont &font); + void resetFont(); + + QQuickWindow *window() const; + QQuickItem *popupItem() const; + + QQuickItem *parentItem() const; + void setParentItem(QQuickItem *parent); + void resetParentItem(); + + QQuickItem *background() const; + void setBackground(QQuickItem *background); + + QQuickItem *contentItem() const; + void setContentItem(QQuickItem *item); + + bool clip() const; + void setClip(bool clip); + + bool hasFocus() const; + void setFocus(bool focus); + + bool hasActiveFocus() const; + + bool isModal() const; + void setModal(bool modal); + + bool dim() const; + void setDim(bool dim); + void resetDim(); + + bool isVisible() const; + virtual void setVisible(bool visible); + + qreal opacity() const; + void setOpacity(qreal opacity); + + qreal scale() const; + void setScale(qreal scale); + + enum ClosePolicyFlag { + NoAutoClose = 0x00, + CloseOnPressOutside = 0x01, + CloseOnPressOutsideParent = 0x02, + CloseOnReleaseOutside = 0x04, + CloseOnReleaseOutsideParent = 0x08, + CloseOnEscape = 0x10 + }; + Q_DECLARE_FLAGS(ClosePolicy, ClosePolicyFlag) + Q_FLAG(ClosePolicy) + + ClosePolicy closePolicy() const; + void setClosePolicy(ClosePolicy policy); + void resetClosePolicy(); + + // keep in sync with Item.TransformOrigin + enum TransformOrigin { + TopLeft, Top, TopRight, + Left, Center, Right, + BottomLeft, Bottom, BottomRight + }; + Q_ENUM(TransformOrigin) + + TransformOrigin transformOrigin() const; + void setTransformOrigin(TransformOrigin); + + QQuickTransition *enter() const; + void setEnter(QQuickTransition *transition); + + QQuickTransition *exit() const; + void setExit(QQuickTransition *transition); + + bool filtersChildMouseEvents() const; + void setFiltersChildMouseEvents(bool filter); + + Q_INVOKABLE void forceActiveFocus(Qt::FocusReason reason = Qt::OtherFocusReason); + + // 2.1 (Qt 5.8) + qreal spacing() const; + void setSpacing(qreal spacing); + void resetSpacing(); + + // 2.3 (Qt 5.10) + bool isOpened() const; + bool isMirrored() const; + + bool isEnabled() const; + void setEnabled(bool enabled); + + // 2.5 (Qt 5.12) + qreal horizontalPadding() const; + void setHorizontalPadding(qreal padding); + void resetHorizontalPadding(); + + qreal verticalPadding() const; + void setVerticalPadding(qreal padding); + void resetVerticalPadding(); + + qreal implicitContentWidth() const; + qreal implicitContentHeight() const; + + qreal implicitBackgroundWidth() const; + qreal implicitBackgroundHeight() const; + + qreal topInset() const; + void setTopInset(qreal inset); + void resetTopInset(); + + qreal leftInset() const; + void setLeftInset(qreal inset); + void resetLeftInset(); + + qreal rightInset() const; + void setRightInset(qreal inset); + void resetRightInset(); + + qreal bottomInset() const; + void setBottomInset(qreal inset); + void resetBottomInset(); + +public Q_SLOTS: + void open(); + void close(); + +Q_SIGNALS: + void opened(); + void closed(); + void aboutToShow(); + void aboutToHide(); + void xChanged(); + void yChanged(); + void zChanged(); + void widthChanged(); + void heightChanged(); + void implicitWidthChanged(); + void implicitHeightChanged(); + void contentWidthChanged(); + void contentHeightChanged(); + void availableWidthChanged(); + void availableHeightChanged(); + void marginsChanged(); + void topMarginChanged(); + void leftMarginChanged(); + void rightMarginChanged(); + void bottomMarginChanged(); + void paddingChanged(); + void topPaddingChanged(); + void leftPaddingChanged(); + void rightPaddingChanged(); + void bottomPaddingChanged(); + void fontChanged(); + void localeChanged(); + void parentChanged(); + void backgroundChanged(); + void contentItemChanged(); + void contentChildrenChanged(); + void clipChanged(); + void focusChanged(); + void activeFocusChanged(); + void modalChanged(); + void dimChanged(); + void visibleChanged(); + void opacityChanged(); + void scaleChanged(); + void closePolicyChanged(); + void enterChanged(); + void exitChanged(); + void windowChanged(QQuickWindow *window); + // 2.1 (Qt 5.8) + Q_REVISION(2, 1) void spacingChanged(); + // 2.3 (Qt 5.10) + Q_REVISION(2, 3) void openedChanged(); + Q_REVISION(2, 3) void mirroredChanged(); + Q_REVISION(2, 3) void enabledChanged(); + Q_REVISION(2, 3) void paletteChanged(); + Q_REVISION(2, 3) void paletteCreated(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void horizontalPaddingChanged(); + Q_REVISION(2, 5) void verticalPaddingChanged(); + Q_REVISION(2, 5) void implicitContentWidthChanged(); + Q_REVISION(2, 5) void implicitContentHeightChanged(); + Q_REVISION(2, 5) void implicitBackgroundWidthChanged(); + Q_REVISION(2, 5) void implicitBackgroundHeightChanged(); + Q_REVISION(2, 5) void topInsetChanged(); + Q_REVISION(2, 5) void leftInsetChanged(); + Q_REVISION(2, 5) void rightInsetChanged(); + Q_REVISION(2, 5) void bottomInsetChanged(); + +protected: + QQuickPopup(QQuickPopupPrivate &dd, QObject *parent); + + void classBegin() override; + void componentComplete() override; + bool isComponentComplete() const; + + virtual bool childMouseEventFilter(QQuickItem *child, QEvent *event); + virtual void focusInEvent(QFocusEvent *event); + virtual void focusOutEvent(QFocusEvent *event); + virtual void keyPressEvent(QKeyEvent *event); + virtual void keyReleaseEvent(QKeyEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void mouseDoubleClickEvent(QMouseEvent *event); + virtual void mouseUngrabEvent(); + virtual bool overlayEvent(QQuickItem *item, QEvent *event); +#if QT_CONFIG(quicktemplates2_multitouch) + virtual void touchEvent(QTouchEvent *event); + virtual void touchUngrabEvent(); +#endif +#if QT_CONFIG(wheelevent) + virtual void wheelEvent(QWheelEvent *event); +#endif + + virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem); + virtual void contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize); + virtual void fontChange(const QFont &newFont, const QFont &oldFont); + virtual void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry); + virtual void localeChange(const QLocale &newLocale, const QLocale &oldLocale); + virtual void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data); + virtual void marginsChange(const QMarginsF &newMargins, const QMarginsF &oldMargins); + virtual void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding); + virtual void spacingChange(qreal newSpacing, qreal oldSpacing); + virtual void insetChange(const QMarginsF &newInset, const QMarginsF &oldInset); + + virtual QFont defaultFont() const; + +#if QT_CONFIG(accessibility) + QAccessible::Role effectiveAccessibleRole() const; +private: + virtual QAccessible::Role accessibleRole() const; +protected: + virtual void accessibilityActiveChanged(bool active); +#endif + + QString accessibleName() const; + void maybeSetAccessibleName(const QString &name); + + QVariant accessibleProperty(const char *propertyName); + bool setAccessibleProperty(const char *propertyName, const QVariant &value); + +private: + Q_DISABLE_COPY(QQuickPopup) + Q_DECLARE_PRIVATE(QQuickPopup) + friend class QQuickPopupItem; + friend class QQuickOverlay; + friend class QQuickOverlayPrivate; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPopup::ClosePolicy) + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickPopup) + +#endif // QQUICKPOPUP_P_H diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h new file mode 100644 index 00000000000..82aa6308eda --- /dev/null +++ b/src/quicktemplates2/qquickpopup_p_p.h @@ -0,0 +1,219 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPOPUP_P_P_H +#define QQUICKPOPUP_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickpopup_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +#include <QtCore/private/qobject_p.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQuick/private/qquicktransitionmanager_p_p.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickTransition; +class QQuickTransitionManager; +class QQuickPopup; +class QQuickPopupAnchors; +class QQuickPopupItem; +class QQuickPopupPrivate; +class QQuickPopupPositioner; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopupTransitionManager : public QQuickTransitionManager +{ +public: + QQuickPopupTransitionManager(QQuickPopupPrivate *popup); + + void transitionEnter(); + void transitionExit(); + +protected: + void finished() override; + +private: + QQuickPopupPrivate *popup = nullptr; +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopupPrivate + : public QObjectPrivate + , public QQuickItemChangeListener + , public QQuickPaletteProviderPrivateBase<QQuickPopup, QQuickPopupPrivate> +{ + Q_DECLARE_PUBLIC(QQuickPopup) + +public: + QQuickPopupPrivate(); + + static QQuickPopupPrivate *get(QQuickPopup *popup) + { + return popup->d_func(); + } + + QQmlListProperty<QObject> contentData(); + QQmlListProperty<QQuickItem> contentChildren(); + + void init(); + void closeOrReject(); + bool tryClose(const QPointF &pos, QQuickPopup::ClosePolicy flags); + + bool contains(const QPointF &scenePos) const; + +#if QT_CONFIG(quicktemplates2_multitouch) + virtual bool acceptTouch(const QTouchEvent::TouchPoint &point); +#endif + virtual bool blockInput(QQuickItem *item, const QPointF &point) const; + + virtual bool handlePress(QQuickItem* item, const QPointF &point, ulong timestamp); + virtual bool handleMove(QQuickItem* item, const QPointF &point, ulong timestamp); + virtual bool handleRelease(QQuickItem* item, const QPointF &point, ulong timestamp); + virtual void handleUngrab(); + + bool handleMouseEvent(QQuickItem *item, QMouseEvent *event); + bool handleHoverEvent(QQuickItem *item, QHoverEvent *event); +#if QT_CONFIG(quicktemplates2_multitouch) + bool handleTouchEvent(QQuickItem *item, QTouchEvent *event); +#endif + + void reposition(); + + void createOverlay(); + void destroyOverlay(); + void toggleOverlay(); + virtual void showOverlay(); + virtual void hideOverlay(); + virtual void resizeOverlay(); + + virtual bool prepareEnterTransition(); + virtual bool prepareExitTransition(); + virtual void finalizeEnterTransition(); + virtual void finalizeExitTransition(); + + virtual void opened(); + + QMarginsF getMargins() const; + + void setTopMargin(qreal value, bool reset = false); + void setLeftMargin(qreal value, bool reset = false); + void setRightMargin(qreal value, bool reset = false); + void setBottomMargin(qreal value, bool reset = false); + + QQuickPopupAnchors *getAnchors(); + virtual QQuickPopupPositioner *getPositioner(); + + void setWindow(QQuickWindow *window); + void itemDestroyed(QQuickItem *item) override; + + QPalette defaultPalette() const override; + + enum TransitionState { + NoTransition, EnterTransition, ExitTransition + }; + + static const QQuickPopup::ClosePolicy DefaultClosePolicy; + + bool focus = false; + bool modal = false; + bool dim = false; + bool hasDim = false; + bool visible = false; + bool complete = true; + bool positioning = false; + bool hasWidth = false; + bool hasHeight = false; + bool hasTopMargin = false; + bool hasLeftMargin = false; + bool hasRightMargin = false; + bool hasBottomMargin = false; + bool allowVerticalFlip = false; + bool allowHorizontalFlip = false; + bool allowVerticalMove = true; + bool allowHorizontalMove = true; + bool allowVerticalResize = true; + bool allowHorizontalResize = true; + bool hadActiveFocusBeforeExitTransition = false; + bool interactive = true; + bool hasClosePolicy = false; + bool outsidePressed = false; + bool outsideParentPressed = false; + int touchId = -1; + qreal x = 0; + qreal y = 0; + qreal effectiveX = 0; + qreal effectiveY = 0; + qreal margins = -1; + qreal topMargin = 0; + qreal leftMargin = 0; + qreal rightMargin = 0; + qreal bottomMargin = 0; + QPointF pressPoint; + TransitionState transitionState = NoTransition; + QQuickPopup::ClosePolicy closePolicy = DefaultClosePolicy; + QQuickItem *parentItem = nullptr; + QQuickItem *dimmer = nullptr; + QPointer<QQuickWindow> window; + QQuickTransition *enter = nullptr; + QQuickTransition *exit = nullptr; + QQuickPopupItem *popupItem = nullptr; + QQuickPopupPositioner *positioner = nullptr; + QList<QQuickStateAction> enterActions; + QList<QQuickStateAction> exitActions; + QQuickPopupTransitionManager transitionManager; + QQuickPopupAnchors *anchors = nullptr; + qreal prevOpacity = 0; + qreal prevScale = 0; + + friend class QQuickPopupTransitionManager; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPOPUP_P_P_H diff --git a/src/quicktemplates2/qquickpopupanchors.cpp b/src/quicktemplates2/qquickpopupanchors.cpp new file mode 100644 index 00000000000..0d286cc01ad --- /dev/null +++ b/src/quicktemplates2/qquickpopupanchors.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpopupanchors_p.h" +#include "qquickpopupanchors_p_p.h" +#include "qquickpopup_p_p.h" + +QT_BEGIN_NAMESPACE + +QQuickPopupAnchors::QQuickPopupAnchors(QQuickPopup *popup) + : QObject(*(new QQuickPopupAnchorsPrivate), popup) +{ + Q_D(QQuickPopupAnchors); + d->popup = popup; +} + +QQuickPopupAnchors::~QQuickPopupAnchors() +{ + Q_D(const QQuickPopupAnchors); + if (d->centerIn) { + auto centerInPrivate = QQuickItemPrivate::get(d->centerIn); + centerInPrivate->removeItemChangeListener(this, QQuickItemPrivate::Destroyed); + } +} + +QQuickItem *QQuickPopupAnchors::centerIn() const +{ + Q_D(const QQuickPopupAnchors); + return d->centerIn; +} + +void QQuickPopupAnchors::setCenterIn(QQuickItem *item) +{ + Q_D(QQuickPopupAnchors); + if (item == d->centerIn) + return; + + if (d->centerIn) { + auto centerInPrivate = QQuickItemPrivate::get(d->centerIn); + centerInPrivate->removeItemChangeListener(this, QQuickItemPrivate::Destroyed); + } + + d->centerIn = item; + + if (d->centerIn) { + auto centerInPrivate = QQuickItemPrivate::get(d->centerIn); + centerInPrivate->addItemChangeListener(this, QQuickItemPrivate::Destroyed); + } + + QQuickPopupPrivate::get(d->popup)->reposition(); + + emit centerInChanged(); +} + +void QQuickPopupAnchors::resetCenterIn() +{ + setCenterIn(nullptr); +} + +void QQuickPopupAnchors::itemDestroyed(QQuickItem *) +{ + resetCenterIn(); +} + +QT_END_NAMESPACE + +#include "moc_qquickpopupanchors_p.cpp" diff --git a/src/quicktemplates2/qquickpopupanchors_p.h b/src/quicktemplates2/qquickpopupanchors_p.h new file mode 100644 index 00000000000..dce1c5b26af --- /dev/null +++ b/src/quicktemplates2/qquickpopupanchors_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPOPUPANCHORS_P_H +#define QQUICKPOPUPANCHORS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtQml/qqml.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickItem; +class QQuickPopupAnchorsPrivate; +class QQuickPopup; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopupAnchors : public QObject, public QQuickItemChangeListener +{ + Q_OBJECT + Q_PROPERTY(QQuickItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 5) + +public: + explicit QQuickPopupAnchors(QQuickPopup *popup); + ~QQuickPopupAnchors(); + + QQuickItem *centerIn() const; + void setCenterIn(QQuickItem *item); + void resetCenterIn(); + +Q_SIGNALS: + void centerInChanged(); + +private: + void itemDestroyed(QQuickItem *item) override; + + Q_DISABLE_COPY(QQuickPopupAnchors) + Q_DECLARE_PRIVATE(QQuickPopupAnchors) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickPopupAnchors) + +#endif // QQUICKPOPUPANCHORS_P_H diff --git a/src/quicktemplates2/qquickpopupanchors_p_p.h b/src/quicktemplates2/qquickpopupanchors_p_p.h new file mode 100644 index 00000000000..989dc6df8f9 --- /dev/null +++ b/src/quicktemplates2/qquickpopupanchors_p_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPOPUPANCHORS_P_P_H +#define QQUICKPOPUPANCHORS_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/private/qobject_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickItem; +class QQuickPopup; + +class QQuickPopupAnchorsPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickPopupAnchors) + +public: + static QQuickPopupAnchorsPrivate *get(QQuickPopupAnchors *popupAnchors) + { + return popupAnchors->d_func(); + } + + QQuickPopup *popup = nullptr; + QQuickItem *centerIn = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPOPUPANCHORS_P_P_H diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp new file mode 100644 index 00000000000..b1214a52cc6 --- /dev/null +++ b/src/quicktemplates2/qquickpopupitem.cpp @@ -0,0 +1,433 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpopupitem_p_p.h" +#include "qquickapplicationwindow_p.h" +#include "qquickshortcutcontext_p_p.h" +#include "qquickpage_p_p.h" +#include "qquickcontentitem_p.h" +#include "qquickpopup_p_p.h" +#include "qquickdeferredexecute_p_p.h" + +#include <QtCore/qloggingcategory.h> +#if QT_CONFIG(shortcut) +# include <QtGui/private/qshortcutmap_p.h> +#endif +#include <QtGui/private/qguiapplication_p.h> + +#if QT_CONFIG(accessibility) +#include <QtQuick/private/qquickaccessibleattached_p.h> +#endif + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcPopupItem, "qt.quick.controls.popupitem") + +QQuickPopupItemPrivate::QQuickPopupItemPrivate(QQuickPopup *popup) + : popup(popup) +{ + isTabFence = true; +} + +void QQuickPopupItemPrivate::implicitWidthChanged() +{ + qCDebug(lcPopupItem).nospace() << "implicitWidthChanged called on " << q_func() << "; new implicitWidth is " << implicitWidth; + QQuickPagePrivate::implicitWidthChanged(); + emit popup->implicitWidthChanged(); +} + +void QQuickPopupItemPrivate::implicitHeightChanged() +{ + qCDebug(lcPopupItem).nospace() << "implicitHeightChanged called on " << q_func() << "; new implicitHeight is " << implicitHeight; + QQuickPagePrivate::implicitHeightChanged(); + emit popup->implicitHeightChanged(); +} + +void QQuickPopupItemPrivate::resolveFont() +{ + if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(popup->window())) + inheritFont(window->font()); + else + inheritFont(QQuickTheme::font(QQuickTheme::System)); +} + +QQuickItem *QQuickPopupItemPrivate::getContentItem() +{ + Q_Q(QQuickPopupItem); + if (QQuickItem *item = QQuickPagePrivate::getContentItem()) + return item; + + return new QQuickContentItem(popup, q); +} + +static inline QString contentItemName() { return QStringLiteral("contentItem"); } + +void QQuickPopupItemPrivate::cancelContentItem() +{ + quickCancelDeferred(popup, contentItemName()); +} + +void QQuickPopupItemPrivate::executeContentItem(bool complete) +{ + if (contentItem.wasExecuted()) + return; + + if (!contentItem || complete) + quickBeginDeferred(popup, contentItemName(), contentItem); + if (complete) + quickCompleteDeferred(popup, contentItemName(), contentItem); +} + +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickPopupItemPrivate::cancelBackground() +{ + quickCancelDeferred(popup, backgroundName()); +} + +void QQuickPopupItemPrivate::executeBackground(bool complete) +{ + if (background.wasExecuted()) + return; + + if (!background || complete) + quickBeginDeferred(popup, backgroundName(), background); + if (complete) + quickCompleteDeferred(popup, backgroundName(), background); +} + +QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup) + : QQuickPage(*(new QQuickPopupItemPrivate(popup)), nullptr) +{ + setParent(popup); + setFlag(ItemIsFocusScope); + setAcceptedMouseButtons(Qt::AllButtons); +#if QT_CONFIG(quicktemplates2_multitouch) + setAcceptTouchEvents(true); +#endif +#if QT_CONFIG(cursor) + setCursor(Qt::ArrowCursor); +#endif + + connect(popup, &QQuickPopup::paletteChanged, this, &QQuickItem::paletteChanged); + connect(popup, &QQuickPopup::paletteCreated, this, &QQuickItem::paletteCreated); + +#if QT_CONFIG(quicktemplates2_hover) + // TODO: switch to QStyleHints::useHoverEffects in Qt 5.8 + setHoverEnabled(true); + // setAcceptHoverEvents(QGuiApplication::styleHints()->useHoverEffects()); + // connect(QGuiApplication::styleHints(), &QStyleHints::useHoverEffectsChanged, this, &QQuickItem::setAcceptHoverEvents); +#endif +} + +void QQuickPopupItem::grabShortcut() +{ +#if QT_CONFIG(shortcut) + Q_D(QQuickPopupItem); + QGuiApplicationPrivate *pApp = QGuiApplicationPrivate::instance(); + if (!d->backId) + d->backId = pApp->shortcutMap.addShortcut(this, Qt::Key_Back, Qt::WindowShortcut, QQuickShortcutContext::matcher); + if (!d->escapeId) + d->escapeId = pApp->shortcutMap.addShortcut(this, Qt::Key_Escape, Qt::WindowShortcut, QQuickShortcutContext::matcher); +#endif +} + +void QQuickPopupItem::ungrabShortcut() +{ +#if QT_CONFIG(shortcut) + Q_D(QQuickPopupItem); + QGuiApplicationPrivate *pApp = QGuiApplicationPrivate::instance(); + if (d->backId) { + pApp->shortcutMap.removeShortcut(d->backId, this); + d->backId = 0; + } + if (d->escapeId) { + pApp->shortcutMap.removeShortcut(d->escapeId, this); + d->escapeId = 0; + } +#endif +} + +QQuickPalette *QQuickPopupItemPrivate::palette() const +{ + return QQuickPopupPrivate::get(popup)->palette(); +} + +void QQuickPopupItemPrivate::setPalette(QQuickPalette *p) +{ + QQuickPopupPrivate::get(popup)->setPalette(p); +} + +void QQuickPopupItemPrivate::resetPalette() +{ + QQuickPopupPrivate::get(popup)->resetPalette(); +} + +QPalette QQuickPopupItemPrivate::defaultPalette() const +{ + return QQuickPopupPrivate::get(popup)->defaultPalette(); +} + +bool QQuickPopupItemPrivate::providesPalette() const +{ + return QQuickPopupPrivate::get(popup)->providesPalette(); +} + +QPalette QQuickPopupItemPrivate::parentPalette() const +{ + return QQuickPopupPrivate::get(popup)->parentPalette(); +} + +void QQuickPopupItem::updatePolish() +{ + Q_D(QQuickPopupItem); + return QQuickPopupPrivate::get(d->popup)->reposition(); +} + +bool QQuickPopupItem::event(QEvent *event) +{ +#if QT_CONFIG(shortcut) + Q_D(QQuickPopupItem); + if (event->type() == QEvent::Shortcut) { + QShortcutEvent *se = static_cast<QShortcutEvent *>(event); + if (se->shortcutId() == d->escapeId || se->shortcutId() == d->backId) { + QQuickPopupPrivate *p = QQuickPopupPrivate::get(d->popup); + if (p->interactive) { + p->closeOrReject(); + return true; + } + } + } +#endif + return QQuickItem::event(event); +} + +bool QQuickPopupItem::childMouseEventFilter(QQuickItem *child, QEvent *event) +{ + Q_D(QQuickPopupItem); + return d->popup->childMouseEventFilter(child, event); +} + +void QQuickPopupItem::focusInEvent(QFocusEvent *event) +{ + Q_D(QQuickPopupItem); + d->popup->focusInEvent(event); +} + +void QQuickPopupItem::focusOutEvent(QFocusEvent *event) +{ + Q_D(QQuickPopupItem); + d->popup->focusOutEvent(event); +} + +void QQuickPopupItem::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickPopupItem); + d->popup->keyPressEvent(event); +} + +void QQuickPopupItem::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QQuickPopupItem); + d->popup->keyReleaseEvent(event); +} + +void QQuickPopupItem::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickPopupItem); + d->popup->mousePressEvent(event); +} + +void QQuickPopupItem::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QQuickPopupItem); + d->popup->mouseMoveEvent(event); +} + +void QQuickPopupItem::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QQuickPopupItem); + d->popup->mouseReleaseEvent(event); +} + +void QQuickPopupItem::mouseDoubleClickEvent(QMouseEvent *event) +{ + Q_D(QQuickPopupItem); + d->popup->mouseDoubleClickEvent(event); +} + +void QQuickPopupItem::mouseUngrabEvent() +{ + Q_D(QQuickPopupItem); + d->popup->mouseUngrabEvent(); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickPopupItem::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickPopupItem); + d->popup->touchEvent(event); +} + +void QQuickPopupItem::touchUngrabEvent() +{ + Q_D(QQuickPopupItem); + d->popup->touchUngrabEvent(); +} +#endif + +#if QT_CONFIG(wheelevent) +void QQuickPopupItem::wheelEvent(QWheelEvent *event) +{ + Q_D(QQuickPopupItem); + d->popup->wheelEvent(event); +} +#endif + +void QQuickPopupItem::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + Q_D(QQuickPopupItem); + QQuickPage::contentItemChange(newItem, oldItem); + d->popup->contentItemChange(newItem, oldItem); +} + +void QQuickPopupItem::contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) +{ + Q_D(QQuickPopupItem); + qCDebug(lcPopupItem) << "contentSizeChange called on" << this << "newSize" << newSize << "oldSize" << oldSize; + QQuickPage::contentSizeChange(newSize, oldSize); + d->popup->contentSizeChange(newSize, oldSize); +} + +void QQuickPopupItem::fontChange(const QFont &newFont, const QFont &oldFont) +{ + Q_D(QQuickPopupItem); + QQuickPage::fontChange(newFont, oldFont); + d->popup->fontChange(newFont, oldFont); +} + +void QQuickPopupItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickPopupItem); + qCDebug(lcPopupItem) << "geometryChange called on" << this << "newGeometry" << newGeometry << "oldGeometry" << oldGeometry; + QQuickPage::geometryChange(newGeometry, oldGeometry); + d->popup->geometryChange(newGeometry, oldGeometry); +} + +void QQuickPopupItem::localeChange(const QLocale &newLocale, const QLocale &oldLocale) +{ + Q_D(QQuickPopupItem); + QQuickPage::localeChange(newLocale, oldLocale); + d->popup->localeChange(newLocale, oldLocale); +} + +void QQuickPopupItem::mirrorChange() +{ + Q_D(QQuickPopupItem); + emit d->popup->mirroredChanged(); +} + +void QQuickPopupItem::itemChange(ItemChange change, const ItemChangeData &data) +{ + Q_D(QQuickPopupItem); + QQuickPage::itemChange(change, data); + d->popup->itemChange(change, data); +} + +void QQuickPopupItem::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) +{ + Q_D(QQuickPopupItem); + QQuickPage::paddingChange(newPadding, oldPadding); + d->popup->paddingChange(newPadding, oldPadding); +} + +void QQuickPopupItem::enabledChange() +{ + Q_D(QQuickPopupItem); + // Just having QQuickPopup connect our QQuickItem::enabledChanged() signal + // to its enabledChanged() signal is enough for the enabled property to work, + // but we must also ensure that its paletteChanged() signal is emitted + // so that bindings to palette are re-evaluated, because QQuickControl::palette() + // returns a different palette depending on whether or not the control is enabled. + // To save a connection, we also emit enabledChanged here. + emit d->popup->enabledChanged(); +} + +QFont QQuickPopupItem::defaultFont() const +{ + Q_D(const QQuickPopupItem); + return d->popup->defaultFont(); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickPopupItem::accessibleRole() const +{ + Q_D(const QQuickPopupItem); + return d->popup->effectiveAccessibleRole(); +} + +void QQuickPopupItem::accessibilityActiveChanged(bool active) +{ + Q_D(const QQuickPopupItem); + // Can't just use d->popup->accessibleName() here, because that refers to the accessible + // name of us, the popup item, which is not what we want. + const QQuickAccessibleAttached *popupAccessibleAttached = QQuickControlPrivate::accessibleAttached(d->popup); + const QString oldPopupName = popupAccessibleAttached ? popupAccessibleAttached->name() : QString(); + const bool wasNameExplicitlySetOnPopup = popupAccessibleAttached && popupAccessibleAttached->wasNameExplicitlySet(); + + QQuickPage::accessibilityActiveChanged(active); + + QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this); + const QString ourName = accessibleAttached ? accessibleAttached->name() : QString(); + if (wasNameExplicitlySetOnPopup && accessibleAttached && ourName != oldPopupName) { + // The user set Accessible.name on the Popup. Since the Popup and its popup item + // have different accessible attached properties, the popup item doesn't know that + // a name was set on the Popup by the user, and that it should use that, rather than + // whatever QQuickPage sets. That's why we need to do it here. + // To avoid it being overridden by the call to accessibilityActiveChanged() below, + // we set it explicitly. It's safe to do this as the popup item is an internal implementation detail. + accessibleAttached->setName(oldPopupName); + } + + // This allows the different popup types to set a name on their popup item accordingly. + // For example: Dialog uses its title and ToolTip uses its text. + d->popup->accessibilityActiveChanged(active); +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickpopupitem_p_p.cpp" diff --git a/src/quicktemplates2/qquickpopupitem_p_p.h b/src/quicktemplates2/qquickpopupitem_p_p.h new file mode 100644 index 00000000000..04486650a04 --- /dev/null +++ b/src/quicktemplates2/qquickpopupitem_p_p.h @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPOPUPITEM_P_P_H +#define QQUICKPOPUPITEM_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickpage_p.h> +#include <QtQuickTemplates2/private/qquickpage_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickPopup; +class QQuickPopupItemPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopupItem : public QQuickPage +{ + Q_OBJECT + +public: + explicit QQuickPopupItem(QQuickPopup *popup); + + void grabShortcut(); + void ungrabShortcut(); + +protected: + void updatePolish() override; + + bool event(QEvent *event) override; + bool childMouseEventFilter(QQuickItem *child, QEvent *event) override; + void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void keyReleaseEvent(QKeyEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void mouseDoubleClickEvent(QMouseEvent *event) override; + void mouseUngrabEvent() override; +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; + void touchUngrabEvent() override; +#endif +#if QT_CONFIG(wheelevent) + void wheelEvent(QWheelEvent *event) override; +#endif + + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + void contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) override; + void fontChange(const QFont &newFont, const QFont &oldFont) override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + void localeChange(const QLocale &newLocale, const QLocale &oldLocale) override; + void mirrorChange() override; + void itemChange(ItemChange change, const ItemChangeData &data) override; + void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) override; + void enabledChange() override; + + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; + void accessibilityActiveChanged(bool active) override; +#endif + +private: + Q_DISABLE_COPY(QQuickPopupItem) + Q_DECLARE_PRIVATE(QQuickPopupItem) + friend class QQuickPopup; +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopupItemPrivate : public QQuickPagePrivate +{ + Q_DECLARE_PUBLIC(QQuickPopupItem) + +public: + QQuickPopupItemPrivate(QQuickPopup *popup); + + void implicitWidthChanged() override; + void implicitHeightChanged() override; + + void resolveFont() override; + + QQuickItem *getContentItem() override; + + void cancelContentItem() override; + void executeContentItem(bool complete = false) override; + + void cancelBackground() override; + void executeBackground(bool complete = false) override; + + QQuickPalette *palette() const override; + void setPalette(QQuickPalette* p) override; + void resetPalette() override; + + QPalette defaultPalette() const override; + bool providesPalette() const override; + + QPalette parentPalette() const override; + + int backId = 0; + int escapeId = 0; + QQuickPopup *popup = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPOPUPITEM_P_P_H diff --git a/src/quicktemplates2/qquickpopuppositioner.cpp b/src/quicktemplates2/qquickpopuppositioner.cpp new file mode 100644 index 00000000000..bbdc3848cd4 --- /dev/null +++ b/src/quicktemplates2/qquickpopuppositioner.cpp @@ -0,0 +1,329 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickoverlay_p.h" +#include "qquickpopuppositioner_p_p.h" +#include "qquickpopupanchors_p.h" +#include "qquickpopupitem_p_p.h" +#include "qquickpopup_p_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcPopupPositioner, "qt.quick.controls.popuppositioner") + +static const QQuickItemPrivate::ChangeTypes AncestorChangeTypes = QQuickItemPrivate::Geometry + | QQuickItemPrivate::Parent + | QQuickItemPrivate::Children; + +static const QQuickItemPrivate::ChangeTypes ItemChangeTypes = QQuickItemPrivate::Geometry + | QQuickItemPrivate::Parent; + +QQuickPopupPositioner::QQuickPopupPositioner(QQuickPopup *popup) + : m_popup(popup) +{ +} + +QQuickPopupPositioner::~QQuickPopupPositioner() +{ + if (m_parentItem) { + QQuickItemPrivate::get(m_parentItem)->removeItemChangeListener(this, ItemChangeTypes); + removeAncestorListeners(m_parentItem->parentItem()); + } +} + +QQuickPopup *QQuickPopupPositioner::popup() const +{ + return m_popup; +} + +QQuickItem *QQuickPopupPositioner::parentItem() const +{ + return m_parentItem; +} + +void QQuickPopupPositioner::setParentItem(QQuickItem *parent) +{ + if (m_parentItem == parent) + return; + + if (m_parentItem) { + QQuickItemPrivate::get(m_parentItem)->removeItemChangeListener(this, ItemChangeTypes); + removeAncestorListeners(m_parentItem->parentItem()); + } + + m_parentItem = parent; + + if (!parent) + return; + + QQuickItemPrivate::get(parent)->addItemChangeListener(this, ItemChangeTypes); + addAncestorListeners(parent->parentItem()); + // Store the scale property so the end result of any transition that could effect the scale + // does not influence the top left of the final popup, so it doesn't appear to flip from one + // position to another as a result + m_popupScale = m_popup->popupItem()->scale(); + if (m_popup->popupItem()->isVisible()) + QQuickPopupPrivate::get(m_popup)->reposition(); +} + +void QQuickPopupPositioner::reposition() +{ + QQuickItem *popupItem = m_popup->popupItem(); + if (!popupItem->isVisible()) + return; + + if (m_positioning) { + popupItem->polish(); + return; + } + + qCDebug(lcPopupPositioner) << "reposition called for" << m_popup; + + const qreal w = popupItem->width() * m_popupScale; + const qreal h = popupItem->height() * m_popupScale; + const qreal iw = popupItem->implicitWidth() * m_popupScale; + const qreal ih = popupItem->implicitHeight() * m_popupScale; + + bool widthAdjusted = false; + bool heightAdjusted = false; + QQuickPopupPrivate *p = QQuickPopupPrivate::get(m_popup); + + const QQuickItem *centerInParent = p->anchors ? p->getAnchors()->centerIn() : nullptr; + const QQuickOverlay *centerInOverlay = qobject_cast<const QQuickOverlay*>(centerInParent); + QRectF rect(!centerInParent ? p->allowHorizontalMove ? p->x : popupItem->x() : 0, + !centerInParent ? p->allowVerticalMove ? p->y : popupItem->y() : 0, + !p->hasWidth && iw > 0 ? iw : w, + !p->hasHeight && ih > 0 ? ih : h); + if (m_parentItem) { + // m_parentItem is the parent that the popup should open in, + // and popupItem()->parentItem() is the overlay, so the mapToItem() calls below + // effectively map the rect to scene coordinates. + if (centerInParent) { + if (centerInParent != parentItem() && !centerInOverlay) { + qmlWarning(m_popup) << "Popup can only be centered within its immediate parent or Overlay.overlay"; + return; + } + + if (centerInOverlay) { + rect.moveCenter(QPointF(qRound(centerInOverlay->width() / 2.0), qRound(centerInOverlay->height() / 2.0))); + } else { + const QPointF parentItemCenter = QPointF(qRound(m_parentItem->width() / 2), qRound(m_parentItem->height() / 2)); + rect.moveCenter(m_parentItem->mapToItem(popupItem->parentItem(), parentItemCenter)); + } + } else { + rect.moveTopLeft(m_parentItem->mapToItem(popupItem->parentItem(), rect.topLeft())); + } + + if (p->window) { + const QMarginsF margins = p->getMargins(); + QRectF bounds(qMax<qreal>(0.0, margins.left()), + qMax<qreal>(0.0, margins.top()), + p->window->width() - qMax<qreal>(0.0, margins.left()) - qMax<qreal>(0.0, margins.right()), + p->window->height() - qMax<qreal>(0.0, margins.top()) - qMax<qreal>(0.0, margins.bottom())); + if (p->window->contentOrientation() == Qt::LandscapeOrientation || p->window->contentOrientation() == Qt::InvertedLandscapeOrientation) + bounds = bounds.transposed(); + + // if the popup doesn't fit horizontally inside the window, try flipping it around (left <-> right) + if (p->allowHorizontalFlip && (rect.left() < bounds.left() || rect.right() > bounds.right())) { + const QPointF newTopLeft(m_parentItem->width() - p->x - rect.width(), p->y); + const QRectF flipped(m_parentItem->mapToItem(popupItem->parentItem(), newTopLeft), + rect.size()); + if (flipped.intersected(bounds).width() > rect.intersected(bounds).width()) + rect.moveLeft(flipped.left()); + } + + // if the popup doesn't fit vertically inside the window, try flipping it around (above <-> below) + if (p->allowVerticalFlip && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) { + const QPointF newTopLeft(p->x, m_parentItem->height() - p->y - rect.height()); + const QRectF flipped(m_parentItem->mapToItem(popupItem->parentItem(), newTopLeft), + rect.size()); + if (flipped.intersected(bounds).height() > rect.intersected(bounds).height()) + rect.moveTop(flipped.top()); + } + + // push inside the margins if specified + if (p->allowVerticalMove) { + if (margins.top() >= 0 && rect.top() < bounds.top()) + rect.moveTop(margins.top()); + if (margins.bottom() >= 0 && rect.bottom() > bounds.bottom()) + rect.moveBottom(bounds.bottom()); + } + if (p->allowHorizontalMove) { + if (margins.left() >= 0 && rect.left() < bounds.left()) + rect.moveLeft(margins.left()); + if (margins.right() >= 0 && rect.right() > bounds.right()) + rect.moveRight(bounds.right()); + } + + if (iw > 0 && (rect.left() < bounds.left() || rect.right() > bounds.right())) { + // neither the flipped or pushed geometry fits inside the window, choose + // whichever side (left vs. right) fits larger part of the popup + if (p->allowHorizontalMove && p->allowHorizontalFlip) { + if (rect.left() < bounds.left() && bounds.left() + rect.width() <= bounds.right()) + rect.moveLeft(bounds.left()); + else if (rect.right() > bounds.right() && bounds.right() - rect.width() >= bounds.left()) + rect.moveRight(bounds.right()); + } + + // as a last resort, adjust the width to fit the window + if (p->allowHorizontalResize) { + if (rect.left() < bounds.left()) { + rect.setLeft(bounds.left()); + widthAdjusted = true; + } + if (rect.right() > bounds.right()) { + rect.setRight(bounds.right()); + widthAdjusted = true; + } + } + } else if (iw > 0 && rect.left() >= bounds.left() && rect.right() <= bounds.right() + && iw != w) { + // restore original width + rect.setWidth(iw); + widthAdjusted = true; + } + + if (ih > 0 && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) { + // neither the flipped or pushed geometry fits inside the window, choose + // whichever side (above vs. below) fits larger part of the popup + if (p->allowVerticalMove && p->allowVerticalFlip) { + if (rect.top() < bounds.top() && bounds.top() + rect.height() <= bounds.bottom()) + rect.moveTop(bounds.top()); + else if (rect.bottom() > bounds.bottom() && bounds.bottom() - rect.height() >= bounds.top()) + rect.moveBottom(bounds.bottom()); + } + + // as a last resort, adjust the height to fit the window + if (p->allowVerticalResize) { + if (rect.top() < bounds.top()) { + rect.setTop(bounds.top()); + heightAdjusted = true; + } + if (rect.bottom() > bounds.bottom()) { + rect.setBottom(bounds.bottom()); + heightAdjusted = true; + } + } + } else if (ih > 0 && rect.top() >= bounds.top() && rect.bottom() <= bounds.bottom() + && ih != h) { + // restore original height + rect.setHeight(ih); + heightAdjusted = true; + } + } + } + + m_positioning = true; + + popupItem->setPosition(rect.topLeft()); + + // If the popup was assigned a parent, rect will be in scene coordinates, + // so we need to map its top left back to item coordinates. + // However, if centering within the overlay, the coordinates will be relative + // to the window, so we don't need to do anything. + const QPointF effectivePos = m_parentItem && !centerInOverlay ? m_parentItem->mapFromScene(rect.topLeft()) : rect.topLeft(); + if (!qFuzzyCompare(p->effectiveX, effectivePos.x())) { + p->effectiveX = effectivePos.x(); + emit m_popup->xChanged(); + } + if (!qFuzzyCompare(p->effectiveY, effectivePos.y())) { + p->effectiveY = effectivePos.y(); + emit m_popup->yChanged(); + } + + if (!p->hasWidth && widthAdjusted && rect.width() > 0) { + popupItem->setWidth(rect.width() / m_popupScale); + // The popup doesn't have an explicit width, so we should respect that by not + // making our call above an explicit assignment. If we don't, the popup won't + // resize after being repositioned in some cases. + QQuickItemPrivate::get(popupItem)->widthValidFlag = false; + } + if (!p->hasHeight && heightAdjusted && rect.height() > 0) { + popupItem->setHeight(rect.height() / m_popupScale); + QQuickItemPrivate::get(popupItem)->heightValidFlag = false; + } + m_positioning = false; + + qCDebug(lcPopupPositioner) << "- new popupItem geometry:" + << popupItem->x() << popupItem->y() << popupItem->width() << popupItem->height(); +} + +void QQuickPopupPositioner::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) +{ + if (m_parentItem && m_popup->popupItem()->isVisible()) + QQuickPopupPrivate::get(m_popup)->reposition(); +} + +void QQuickPopupPositioner::itemParentChanged(QQuickItem *, QQuickItem *parent) +{ + addAncestorListeners(parent); +} + +void QQuickPopupPositioner::itemChildRemoved(QQuickItem *item, QQuickItem *child) +{ + if (child == m_parentItem || child->isAncestorOf(m_parentItem)) + removeAncestorListeners(item); +} + +void QQuickPopupPositioner::removeAncestorListeners(QQuickItem *item) +{ + if (item == m_parentItem) + return; + + QQuickItem *p = item; + while (p) { + QQuickItemPrivate::get(p)->removeItemChangeListener(this, AncestorChangeTypes); + p = p->parentItem(); + } +} + +void QQuickPopupPositioner::addAncestorListeners(QQuickItem *item) +{ + if (item == m_parentItem) + return; + + QQuickItem *p = item; + while (p) { + QQuickItemPrivate::get(p)->updateOrAddItemChangeListener(this, AncestorChangeTypes); + p = p->parentItem(); + } +} + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickpopuppositioner_p_p.h b/src/quicktemplates2/qquickpopuppositioner_p_p.h new file mode 100644 index 00000000000..74bc467c619 --- /dev/null +++ b/src/quicktemplates2/qquickpopuppositioner_p_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPOPUPPOSITIONER_P_P_H +#define QQUICKPOPUPPOSITIONER_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickItem; +class QQuickPopup; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopupPositioner : public QQuickItemChangeListener +{ +public: + explicit QQuickPopupPositioner(QQuickPopup *popup); + ~QQuickPopupPositioner(); + + QQuickPopup *popup() const; + + QQuickItem *parentItem() const; + void setParentItem(QQuickItem *parent); + + virtual void reposition(); + +protected: + void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override; + void itemParentChanged(QQuickItem *, QQuickItem *parent) override; + void itemChildRemoved(QQuickItem *, QQuickItem *child) override; + + void removeAncestorListeners(QQuickItem *item); + void addAncestorListeners(QQuickItem *item); + + bool m_positioning = false; + QQuickItem *m_parentItem = nullptr; + QQuickPopup *m_popup = nullptr; + qreal m_popupScale = 1.0; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPOPUPPOSITIONER_P_P_H diff --git a/src/quicktemplates2/qquickpresshandler.cpp b/src/quicktemplates2/qquickpresshandler.cpp new file mode 100644 index 00000000000..d9ed484be99 --- /dev/null +++ b/src/quicktemplates2/qquickpresshandler.cpp @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpresshandler_p_p.h" + +#include <QtCore/private/qobject_p.h> +#include <QtGui/qguiapplication.h> +#include <QtGui/qstylehints.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/private/qquickevents_p_p.h> +#include <QtQuickTemplates2/private/qquicktextarea_p.h> +#include <QtQuickTemplates2/private/qquicktextfield_p.h> + +QT_BEGIN_NAMESPACE + +void QQuickPressHandler::mousePressEvent(QMouseEvent *event) +{ + longPress = false; + pressPos = event->position(); + if (Qt::LeftButton == (event->buttons() & Qt::LeftButton)) { + timer.start(QGuiApplication::styleHints()->mousePressAndHoldInterval(), control); + delayedMousePressEvent = new QMouseEvent(event->type(), event->position().toPoint(), event->button(), event->buttons(), event->modifiers()); + } else { + timer.stop(); + } + + if (isSignalConnected(control, "pressed(QQuickMouseEvent*)", pressedSignalIndex)) { + QQuickMouseEvent mev; + mev.reset(pressPos.x(), pressPos.y(), event->button(), event->buttons(), + event->modifiers(), false/*isClick*/, false/*wasHeld*/); + mev.setAccepted(true); + QQuickMouseEvent *mevPtr = &mev; + void *args[] = { nullptr, &mevPtr }; + QMetaObject::metacall(control, QMetaObject::InvokeMetaMethod, pressedSignalIndex, args); + event->setAccepted(mev.isAccepted()); + } +} + +void QQuickPressHandler::mouseMoveEvent(QMouseEvent *event) +{ + if (qAbs(int(event->position().x() - pressPos.x())) > QGuiApplication::styleHints()->startDragDistance()) + timer.stop(); +} + +void QQuickPressHandler::mouseReleaseEvent(QMouseEvent *event) +{ + if (!longPress) { + timer.stop(); + + if (isSignalConnected(control, "released(QQuickMouseEvent*)", releasedSignalIndex)) { + QQuickMouseEvent mev; + mev.reset(pressPos.x(), pressPos.y(), event->button(), event->buttons(), + event->modifiers(), false/*isClick*/, false/*wasHeld*/); + mev.setAccepted(true); + QQuickMouseEvent *mevPtr = &mev; + void *args[] = { nullptr, &mevPtr }; + QMetaObject::metacall(control, QMetaObject::InvokeMetaMethod, releasedSignalIndex, args); + event->setAccepted(mev.isAccepted()); + } + } +} + +void QQuickPressHandler::timerEvent(QTimerEvent *) +{ + timer.stop(); + clearDelayedMouseEvent(); + + longPress = isSignalConnected(control, "pressAndHold(QQuickMouseEvent*)", pressAndHoldSignalIndex); + if (longPress) { + QQuickMouseEvent mev; +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + mev.reset(pressPos.x(), pressPos.y(), Qt::LeftButton, Qt::LeftButton, + QGuiApplication::keyboardModifiers(), false/*isClick*/, true/*wasHeld*/); +QT_WARNING_POP + mev.setAccepted(true); + // Use fast signal invocation since we already got its index + QQuickMouseEvent *mevPtr = &mev; + void *args[] = { nullptr, &mevPtr }; + QMetaObject::metacall(control, QMetaObject::InvokeMetaMethod, pressAndHoldSignalIndex, args); + if (!mev.isAccepted()) + longPress = false; + } +} + +void QQuickPressHandler::clearDelayedMouseEvent() +{ + if (delayedMousePressEvent) { + delete delayedMousePressEvent; + delayedMousePressEvent = 0; + } +} + +bool QQuickPressHandler::isActive() +{ + return !(timer.isActive() || longPress); +} + +bool QQuickPressHandler::isSignalConnected(QQuickItem *item, const char *signalName, int &signalIndex) +{ + if (signalIndex == -1) + signalIndex = item->metaObject()->indexOfSignal(signalName); + Q_ASSERT(signalIndex != -1); + const auto signalMetaMethod = item->metaObject()->method(signalIndex); + if (QQuickTextArea *textArea = qobject_cast<QQuickTextArea*>(item)) { + return textArea->isSignalConnected(signalMetaMethod); + } else if (QQuickTextField *textField = qobject_cast<QQuickTextField*>(item)) { + return textField->isSignalConnected(signalMetaMethod); + } + qFatal("Unhandled control type for signal name: %s", signalName); + return false; +} + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickpresshandler_p_p.h b/src/quicktemplates2/qquickpresshandler_p_p.h new file mode 100644 index 00000000000..19312cddf4e --- /dev/null +++ b/src/quicktemplates2/qquickpresshandler_p_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPRESSHANDLER_P_P_H +#define QQUICKPRESSHANDLER_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qpoint.h> +#include <QtCore/qbasictimer.h> + +QT_BEGIN_NAMESPACE + +class QQuickItem; +class QMouseEvent; +class QTimerEvent; + +struct QQuickPressHandler +{ + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void timerEvent(QTimerEvent *event); + + void clearDelayedMouseEvent(); + bool isActive(); + + static bool isSignalConnected(QQuickItem *item, const char *signalName, int &signalIndex); + + QQuickItem *control = nullptr; + QBasicTimer timer; + QPointF pressPos; + bool longPress = false; + int pressAndHoldSignalIndex = -1; + int pressedSignalIndex = -1; + int releasedSignalIndex = -1; + QMouseEvent *delayedMousePressEvent = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPRESSHANDLER_P_P_H diff --git a/src/quicktemplates2/qquickprogressbar.cpp b/src/quicktemplates2/qquickprogressbar.cpp new file mode 100644 index 00000000000..f4bc52b9be7 --- /dev/null +++ b/src/quicktemplates2/qquickprogressbar.cpp @@ -0,0 +1,273 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickprogressbar_p.h" +#include "qquickcontrol_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ProgressBar + \inherits Control +//! \instantiates QQuickProgressBar + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-indicators + \brief Indicates the progress of an operation. + + \image qtquickcontrols2-progressbar.gif + + ProgressBar indicates the progress of an operation. The value should be updated + regularly. The range is defined by \l from and \l to, which both can contain any value. + + \code + ProgressBar { + value: 0.5 + } + \endcode + + ProgressBar also supports a special \l indeterminate mode, which is useful, + for example, when unable to determine the size of the item being downloaded, + or if the download progress gets interrupted due to a network disconnection. + + \image qtquickcontrols2-progressbar-indeterminate.gif + + \code + ProgressBar { + indeterminate: true + } + \endcode + + The indeterminate mode is similar to a \l BusyIndicator. Both can be used + to indicate background activity. The main difference is visual, and that + ProgressBar can also present a concrete amount of progress (when it can be + determined). Due to the visual difference, indeterminate progress bars and + busy indicators fit different places in user interfaces. Typical places for + an indeterminate progress bar: + \list + \li at the bottom of a \l ToolBar + \li inline within the content of a \l Page + \li in an \l ItemDelegate to show the progress of a particular item + \endlist + + \sa {Customizing ProgressBar}, BusyIndicator, {Indicator Controls} +*/ + +class QQuickProgressBarPrivate : public QQuickControlPrivate +{ +public: + qreal from = 0; + qreal to = 1; + qreal value = 0; + bool indeterminate = false; +}; + +QQuickProgressBar::QQuickProgressBar(QQuickItem *parent) + : QQuickControl(*(new QQuickProgressBarPrivate), parent) +{ +} + +/*! + \qmlproperty real QtQuick.Controls::ProgressBar::from + + This property holds the starting value for the progress. The default value is \c 0.0. + + \sa to, value +*/ +qreal QQuickProgressBar::from() const +{ + Q_D(const QQuickProgressBar); + return d->from; +} + +void QQuickProgressBar::setFrom(qreal from) +{ + Q_D(QQuickProgressBar); + if (qFuzzyCompare(d->from, from)) + return; + + d->from = from; + emit fromChanged(); + emit positionChanged(); + emit visualPositionChanged(); + if (isComponentComplete()) + setValue(d->value); +} + +/*! + \qmlproperty real QtQuick.Controls::ProgressBar::to + + This property holds the end value for the progress. The default value is \c 1.0. + + \sa from, value +*/ +qreal QQuickProgressBar::to() const +{ + Q_D(const QQuickProgressBar); + return d->to; +} + +void QQuickProgressBar::setTo(qreal to) +{ + Q_D(QQuickProgressBar); + if (qFuzzyCompare(d->to, to)) + return; + + d->to = to; + emit toChanged(); + emit positionChanged(); + emit visualPositionChanged(); + if (isComponentComplete()) + setValue(d->value); +} + +/*! + \qmlproperty real QtQuick.Controls::ProgressBar::value + + This property holds the progress value. The default value is \c 0.0. + + \sa from, to, position +*/ +qreal QQuickProgressBar::value() const +{ + Q_D(const QQuickProgressBar); + return d->value; +} + +void QQuickProgressBar::setValue(qreal value) +{ + Q_D(QQuickProgressBar); + if (isComponentComplete()) + value = d->from > d->to ? qBound(d->to, value, d->from) : qBound(d->from, value, d->to); + + if (qFuzzyCompare(d->value, value)) + return; + + d->value = value; + emit valueChanged(); + emit positionChanged(); + emit visualPositionChanged(); +} + +/*! + \qmlproperty real QtQuick.Controls::ProgressBar::position + \readonly + + This property holds the logical position of the progress. + + The position is expressed as a fraction of the value, in the range + \c {0.0 - 1.0}. For visualizing the progress, the right-to-left + aware \l visualPosition should be used instead. + + \sa value, visualPosition +*/ +qreal QQuickProgressBar::position() const +{ + Q_D(const QQuickProgressBar); + if (qFuzzyCompare(d->from, d->to)) + return 0; + return (d->value - d->from) / (d->to - d->from); +} + +/*! + \qmlproperty real QtQuick.Controls::ProgressBar::visualPosition + \readonly + + This property holds the visual position of the progress. + + The position is expressed as a fraction of the value, in the range \c {0.0 - 1.0}. + When the control is \l {Control::mirrored}{mirrored}, \c visuaPosition is equal + to \c {1.0 - position}. This makes \c visualPosition suitable for visualizing + the progress, taking right-to-left support into account. + + \sa position, value +*/ +qreal QQuickProgressBar::visualPosition() const +{ + if (isMirrored()) + return 1.0 - position(); + return position(); +} + +/*! + \qmlproperty bool QtQuick.Controls::ProgressBar::indeterminate + + This property holds whether the progress bar is in indeterminate mode. + A progress bar in indeterminate mode displays that an operation is in progress, but it + doesn't show how much progress has been made. + + \image qtquickcontrols2-progressbar-indeterminate.gif +*/ +bool QQuickProgressBar::isIndeterminate() const +{ + Q_D(const QQuickProgressBar); + return d->indeterminate; +} + +void QQuickProgressBar::setIndeterminate(bool indeterminate) +{ + Q_D(QQuickProgressBar); + if (d->indeterminate == indeterminate) + return; + + d->indeterminate = indeterminate; + emit indeterminateChanged(); +} + +void QQuickProgressBar::mirrorChange() +{ + QQuickControl::mirrorChange(); + if (!qFuzzyCompare(position(), qreal(0.5))) + emit visualPositionChanged(); +} + +void QQuickProgressBar::componentComplete() +{ + Q_D(QQuickProgressBar); + QQuickControl::componentComplete(); + setValue(d->value); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickProgressBar::accessibleRole() const +{ + return QAccessible::ProgressBar; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickprogressbar_p.cpp" diff --git a/src/quicktemplates2/qquickprogressbar_p.h b/src/quicktemplates2/qquickprogressbar_p.h new file mode 100644 index 00000000000..8322670fcdf --- /dev/null +++ b/src/quicktemplates2/qquickprogressbar_p.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPROGRESSBAR_P_H +#define QQUICKPROGRESSBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickProgressBarPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickProgressBar : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged FINAL) + Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged FINAL) + Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged FINAL) + Q_PROPERTY(qreal position READ position NOTIFY positionChanged FINAL) + Q_PROPERTY(qreal visualPosition READ visualPosition NOTIFY visualPositionChanged FINAL) + Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate NOTIFY indeterminateChanged FINAL) + QML_NAMED_ELEMENT(ProgressBar) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickProgressBar(QQuickItem *parent = nullptr); + + qreal from() const; + void setFrom(qreal from); + + qreal to() const; + void setTo(qreal to); + + qreal value() const; + void setValue(qreal value); + + qreal position() const; + qreal visualPosition() const; + + bool isIndeterminate() const; + void setIndeterminate(bool indeterminate); + +Q_SIGNALS: + void fromChanged(); + void toChanged(); + void valueChanged(); + void positionChanged(); + void visualPositionChanged(); + void indeterminateChanged(); + +protected: + void mirrorChange() override; + void componentComplete() override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickProgressBar) + Q_DECLARE_PRIVATE(QQuickProgressBar) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickProgressBar) + +#endif // QQUICKPROGRESSBAR_P_H diff --git a/src/quicktemplates2/qquickradiobutton.cpp b/src/quicktemplates2/qquickradiobutton.cpp new file mode 100644 index 00000000000..3f1262e03a5 --- /dev/null +++ b/src/quicktemplates2/qquickradiobutton.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickradiobutton_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickabstractbutton_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype RadioButton + \inherits AbstractButton +//! \instantiates QQuickRadioButton + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-buttons + \brief Exclusive radio button that can be toggled on or off. + + \image qtquickcontrols2-radiobutton.gif + + RadioButton presents an option button that can be toggled on (checked) or + off (unchecked). Radio buttons are typically used to select one option + from a set of options. + + RadioButton inherits its API from \l AbstractButton. For instance, + you can set \l {AbstractButton::text}{text} and react to + \l {AbstractButton::clicked}{clicks} using the AbstractButton API. + The state of the radio button can be set with the + \l {AbstractButton::}{checked} property. + + Radio buttons are \l {AbstractButton::autoExclusive}{auto-exclusive} + by default. Only one button can be checked at any time amongst radio + buttons that belong to the same parent item; checking another button + automatically unchecks the previously checked one. For radio buttons + that do not share a common parent, ButtonGroup can be used to manage + exclusivity. + + \l RadioDelegate is similar to RadioButton, except that it is typically + used in views. + + \code + ColumnLayout { + RadioButton { + checked: true + text: qsTr("First") + } + RadioButton { + text: qsTr("Second") + } + RadioButton { + text: qsTr("Third") + } + } + \endcode + + \sa ButtonGroup, {Customizing RadioButton}, {Button Controls}, RadioDelegate +*/ + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRadioButtonPrivate : public QQuickAbstractButtonPrivate +{ + Q_DECLARE_PUBLIC(QQuickRadioButton) + +public: + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::RadioButton); } +}; + +QQuickRadioButton::QQuickRadioButton(QQuickItem *parent) + : QQuickAbstractButton(*(new QQuickRadioButtonPrivate), parent) +{ + setCheckable(true); + setAutoExclusive(true); +} + +QFont QQuickRadioButton::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::RadioButton); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickRadioButton::accessibleRole() const +{ + return QAccessible::RadioButton; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickradiobutton_p.cpp" diff --git a/src/quicktemplates2/qquickradiobutton_p.h b/src/quicktemplates2/qquickradiobutton_p.h new file mode 100644 index 00000000000..29e1892294d --- /dev/null +++ b/src/quicktemplates2/qquickradiobutton_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKRADIOBUTTON_P_H +#define QQUICKRADIOBUTTON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickRadioButtonPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRadioButton : public QQuickAbstractButton +{ + Q_OBJECT + QML_NAMED_ELEMENT(RadioButton) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickRadioButton(QQuickItem *parent = nullptr); + +protected: + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickRadioButton) + +#endif // QQUICKRADIOBUTTON_P_H diff --git a/src/quicktemplates2/qquickradiodelegate.cpp b/src/quicktemplates2/qquickradiodelegate.cpp new file mode 100644 index 00000000000..836739389d7 --- /dev/null +++ b/src/quicktemplates2/qquickradiodelegate.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickradiodelegate_p.h" +#include "qquickabstractbutton_p_p.h" +#include "qquickitemdelegate_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype RadioDelegate + \inherits ItemDelegate +//! \instantiates QQuickRadioDelegate + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-delegates + \brief Exclusive item delegate with a radio indicator that can be toggled on or off. + + \image qtquickcontrols2-radiodelegate.gif + + RadioDelegate presents an item delegate that can be toggled on (checked) or + off (unchecked). Radio delegates are typically used to select one option + from a set of options. + + RadioDelegate inherits its API from \l ItemDelegate, which is inherited + from AbstractButton. For instance, you can set \l {AbstractButton::text}{text}, + and react to \l {AbstractButton::clicked}{clicks} using the AbstractButton + API. The state of the radio delegate can be set with the + \l {AbstractButton::}{checked} property. + + Radio delegates are \l {AbstractButton::autoExclusive}{auto-exclusive} + by default. Only one delegate can be checked at any time amongst radio + delegates that belong to the same parent item; checking another delegate + automatically unchecks the previously checked one. For radio delegates + that do not share a common parent, ButtonGroup can be used to manage + exclusivity. + + \l RadioButton is similar to RadioDelegate, except that it is typically + not used in views, but rather when there are only a few options, and often + with the requirement that each button is uniquely identifiable. + + \code + ButtonGroup { + id: buttonGroup + } + + ListView { + model: ["Option 1", "Option 2", "Option 3"] + delegate: RadioDelegate { + text: modelData + checked: index == 0 + ButtonGroup.group: buttonGroup + } + } + \endcode + + \sa {Customizing RadioDelegate}, {Delegate Controls}, RadioButton +*/ + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRadioDelegatePrivate : public QQuickItemDelegatePrivate +{ + Q_DECLARE_PUBLIC(QQuickRadioDelegate) + +public: + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::ListView); } +}; + +QQuickRadioDelegate::QQuickRadioDelegate(QQuickItem *parent) + : QQuickItemDelegate(*(new QQuickRadioDelegatePrivate), parent) +{ + setCheckable(true); + setAutoExclusive(true); +} + +QFont QQuickRadioDelegate::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::ListView); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickRadioDelegate::accessibleRole() const +{ + return QAccessible::RadioButton; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickradiodelegate_p.cpp" diff --git a/src/quicktemplates2/qquickradiodelegate_p.h b/src/quicktemplates2/qquickradiodelegate_p.h new file mode 100644 index 00000000000..0ddff985ceb --- /dev/null +++ b/src/quicktemplates2/qquickradiodelegate_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKRADIODELEGATE_P_H +#define QQUICKRADIODELEGATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickitemdelegate_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickRadioDelegatePrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRadioDelegate : public QQuickItemDelegate +{ + Q_OBJECT + QML_NAMED_ELEMENT(RadioDelegate) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickRadioDelegate(QQuickItem *parent = nullptr); + +protected: + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DECLARE_PRIVATE(QQuickRadioDelegate) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickRadioDelegate) + +#endif // QQUICKRADIODELEGATE_P_H diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp new file mode 100644 index 00000000000..41f8795bd54 --- /dev/null +++ b/src/quicktemplates2/qquickrangeslider.cpp @@ -0,0 +1,1343 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickrangeslider_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickdeferredexecute_p_p.h" + +#include <QtCore/qscopedpointer.h> +#include <QtQuick/private/qquickwindow_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype RangeSlider + \inherits Control +//! \instantiates QQuickRangeSlider + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-input + \ingroup qtquickcontrols2-focusscopes + \brief Used to select a range of values by sliding two handles along a track. + + \image qtquickcontrols2-rangeslider.gif + + RangeSlider is used to select a range specified by two values, by sliding + each handle along a track. + + In the example below, custom \l from and \l to values are set, and the + initial positions of the \l first and \l second handles are set: + + \code + RangeSlider { + from: 1 + to: 100 + first.value: 25 + second.value: 75 + } + \endcode + + In order to perform an action when the value for a particular handle changes, + use the following syntax: + + \code + first.onMoved: console.log("first.value changed to " + first.value) + \endcode + + The \l {first.position} and \l {second.position} properties are expressed as + fractions of the control's size, in the range \c {0.0 - 1.0}. + The \l {first.visualPosition} and \l {second.visualPosition} properties are + the same, except that they are reversed in a + \l {Right-to-left User Interfaces}{right-to-left} application. + The \c visualPosition is useful for positioning the handles when styling + RangeSlider. In the example above, \l {first.visualPosition} will be \c 0.24 + in a left-to-right application, and \c 0.76 in a right-to-left application. + + For a slider that allows the user to select a single value, see \l Slider. + + \sa {Customizing RangeSlider}, {Input Controls}, + {Focus Management in Qt Quick Controls} +*/ + +class QQuickRangeSliderNodePrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickRangeSliderNode) +public: + QQuickRangeSliderNodePrivate(qreal value, QQuickRangeSlider *slider) + : value(value), + slider(slider) + { + } + + bool isFirst() const; + + void setPosition(qreal position, bool ignoreOtherPosition = false); + void updatePosition(bool ignoreOtherPosition = false); + + void cancelHandle(); + void executeHandle(bool complete = false); + + static QQuickRangeSliderNodePrivate *get(QQuickRangeSliderNode *node); + + qreal value = 0; + bool isPendingValue = false; + qreal pendingValue = 0; + qreal position = 0; + QQuickDeferredPointer<QQuickItem> handle; + QQuickRangeSlider *slider = nullptr; + bool pressed = false; + bool hovered = false; + int touchId = -1; +}; + +bool QQuickRangeSliderNodePrivate::isFirst() const +{ + return this == get(slider->first()); +} + +void QQuickRangeSliderNodePrivate::setPosition(qreal position, bool ignoreOtherPosition) +{ + Q_Q(QQuickRangeSliderNode); + + const qreal min = isFirst() || ignoreOtherPosition ? 0.0 : qMax<qreal>(0.0, slider->first()->position()); + const qreal max = !isFirst() || ignoreOtherPosition ? 1.0 : qMin<qreal>(1.0, slider->second()->position()); + position = qBound(min, position, max); + if (!qFuzzyCompare(this->position, position)) { + this->position = position; + emit q->positionChanged(); + emit q->visualPositionChanged(); + } +} + +void QQuickRangeSliderNodePrivate::updatePosition(bool ignoreOtherPosition) +{ + qreal pos = 0; + if (!qFuzzyCompare(slider->from(), slider->to())) + pos = (value - slider->from()) / (slider->to() - slider->from()); + setPosition(pos, ignoreOtherPosition); +} + +static inline QString handleName() { return QStringLiteral("handle"); } + +void QQuickRangeSliderNodePrivate::cancelHandle() +{ + Q_Q(QQuickRangeSliderNode); + quickCancelDeferred(q, handleName()); +} + +void QQuickRangeSliderNodePrivate::executeHandle(bool complete) +{ + Q_Q(QQuickRangeSliderNode); + if (handle.wasExecuted()) + return; + + if (!handle || complete) + quickBeginDeferred(q, handleName(), handle); + if (complete) + quickCompleteDeferred(q, handleName(), handle); +} + +QQuickRangeSliderNodePrivate *QQuickRangeSliderNodePrivate::get(QQuickRangeSliderNode *node) +{ + return node->d_func(); +} + +QQuickRangeSliderNode::QQuickRangeSliderNode(qreal value, QQuickRangeSlider *slider) + : QObject(*(new QQuickRangeSliderNodePrivate(value, slider)), slider) +{ +} + +QQuickRangeSliderNode::~QQuickRangeSliderNode() +{ +} + +qreal QQuickRangeSliderNode::value() const +{ + Q_D(const QQuickRangeSliderNode); + return d->value; +} + +void QQuickRangeSliderNode::setValue(qreal value) +{ + Q_D(QQuickRangeSliderNode); + if (!d->slider->isComponentComplete()) { + d->pendingValue = value; + d->isPendingValue = true; + return; + } + + // First, restrict the first value to be within to and from. + const qreal smaller = qMin(d->slider->to(), d->slider->from()); + const qreal larger = qMax(d->slider->to(), d->slider->from()); + value = qBound(smaller, value, larger); + + // Then, ensure that it doesn't go past the other value, + // a check that depends on whether or not the range is inverted. + const bool invertedRange = d->slider->from() > d->slider->to(); + if (d->isFirst()) { + if (invertedRange) { + if (value < d->slider->second()->value()) + value = d->slider->second()->value(); + } else { + if (value > d->slider->second()->value()) + value = d->slider->second()->value(); + } + } else { + if (invertedRange) { + if (value > d->slider->first()->value()) + value = d->slider->first()->value(); + } else { + if (value < d->slider->first()->value()) + value = d->slider->first()->value(); + } + } + + if (!qFuzzyCompare(d->value, value)) { + d->value = value; + d->updatePosition(); + emit valueChanged(); + } +} + +qreal QQuickRangeSliderNode::position() const +{ + Q_D(const QQuickRangeSliderNode); + return d->position; +} + +qreal QQuickRangeSliderNode::visualPosition() const +{ + Q_D(const QQuickRangeSliderNode); + if (d->slider->orientation() == Qt::Vertical || d->slider->isMirrored()) + return 1.0 - d->position; + return d->position; +} + +QQuickItem *QQuickRangeSliderNode::handle() const +{ + QQuickRangeSliderNodePrivate *d = const_cast<QQuickRangeSliderNodePrivate *>(d_func()); + if (!d->handle) + d->executeHandle(); + return d->handle; +} + +void QQuickRangeSliderNode::setHandle(QQuickItem *handle) +{ + Q_D(QQuickRangeSliderNode); + if (d->handle == handle) + return; + + if (!d->handle.isExecuting()) + d->cancelHandle(); + + const qreal oldImplicitHandleWidth = implicitHandleWidth(); + const qreal oldImplicitHandleHeight = implicitHandleHeight(); + + QQuickControlPrivate::get(d->slider)->removeImplicitSizeListener(d->handle); + QQuickControlPrivate::hideOldItem(d->handle); + d->handle = handle; + + if (handle) { + if (!handle->parentItem()) + handle->setParentItem(d->slider); + + QQuickItem *firstHandle = QQuickRangeSliderNodePrivate::get(d->slider->first())->handle; + QQuickItem *secondHandle = QQuickRangeSliderNodePrivate::get(d->slider->second())->handle; + if (firstHandle && secondHandle) { + // The order of property assignments in QML is undefined, + // but we need the first handle to be before the second due + // to focus order constraints, so check for that here. + const QList<QQuickItem *> childItems = d->slider->childItems(); + const int firstIndex = childItems.indexOf(firstHandle); + const int secondIndex = childItems.indexOf(secondHandle); + if (firstIndex != -1 && secondIndex != -1 && firstIndex > secondIndex) { + firstHandle->stackBefore(secondHandle); + // Ensure we have some way of knowing which handle is above + // the other when it comes to mouse presses, and also that + // they are rendered in the correct order. + secondHandle->setZ(secondHandle->z() + 1); + } + } + + handle->setActiveFocusOnTab(true); + QQuickControlPrivate::get(d->slider)->addImplicitSizeListener(handle); + } + + if (!qFuzzyCompare(oldImplicitHandleWidth, implicitHandleWidth())) + emit implicitHandleWidthChanged(); + if (!qFuzzyCompare(oldImplicitHandleHeight, implicitHandleHeight())) + emit implicitHandleHeightChanged(); + if (!d->handle.isExecuting()) + emit handleChanged(); +} + +bool QQuickRangeSliderNode::isPressed() const +{ + Q_D(const QQuickRangeSliderNode); + return d->pressed; +} + +void QQuickRangeSliderNode::setPressed(bool pressed) +{ + Q_D(QQuickRangeSliderNode); + if (d->pressed == pressed) + return; + + d->pressed = pressed; + d->slider->setAccessibleProperty("pressed", pressed || d->slider->second()->isPressed()); + emit pressedChanged(); +} + +bool QQuickRangeSliderNode::isHovered() const +{ + Q_D(const QQuickRangeSliderNode); + return d->hovered; +} + +void QQuickRangeSliderNode::setHovered(bool hovered) +{ + Q_D(QQuickRangeSliderNode); + if (d->hovered == hovered) + return; + + d->hovered = hovered; + emit hoveredChanged(); +} + +qreal QQuickRangeSliderNode::implicitHandleWidth() const +{ + Q_D(const QQuickRangeSliderNode); + if (!d->handle) + return 0; + return d->handle->implicitWidth(); +} + +qreal QQuickRangeSliderNode::implicitHandleHeight() const +{ + Q_D(const QQuickRangeSliderNode); + if (!d->handle) + return 0; + return d->handle->implicitHeight(); +} + +void QQuickRangeSliderNode::increase() +{ + Q_D(QQuickRangeSliderNode); + qreal step = qFuzzyIsNull(d->slider->stepSize()) ? 0.1 : d->slider->stepSize(); + setValue(d->value + step); +} + +void QQuickRangeSliderNode::decrease() +{ + Q_D(QQuickRangeSliderNode); + qreal step = qFuzzyIsNull(d->slider->stepSize()) ? 0.1 : d->slider->stepSize(); + setValue(d->value - step); +} + +static const qreal defaultFrom = 0.0; +static const qreal defaultTo = 1.0; + +class QQuickRangeSliderPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickRangeSlider) + +public: + QQuickRangeSliderNode *pressedNode(int touchId = -1) const; + +#if QT_CONFIG(quicktemplates2_multitouch) + bool acceptTouch(const QTouchEvent::TouchPoint &point) override; +#endif + void handlePress(const QPointF &point) override; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + void handleUngrab() override; + + void updateHover(const QPointF &pos); + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + bool live = true; + qreal from = defaultFrom; + qreal to = defaultTo; + qreal stepSize = 0; + qreal touchDragThreshold = -1; + QQuickRangeSliderNode *first = nullptr; + QQuickRangeSliderNode *second = nullptr; + QPointF pressPoint; + Qt::Orientation orientation = Qt::Horizontal; + QQuickRangeSlider::SnapMode snapMode = QQuickRangeSlider::NoSnap; +}; + +static qreal valueAt(const QQuickRangeSlider *slider, qreal position) +{ + return slider->from() + (slider->to() - slider->from()) * position; +} + +static qreal snapPosition(const QQuickRangeSlider *slider, qreal position) +{ + const qreal range = slider->to() - slider->from(); + if (qFuzzyIsNull(range)) + return position; + + const qreal effectiveStep = slider->stepSize() / range; + if (qFuzzyIsNull(effectiveStep)) + return position; + + return qRound(position / effectiveStep) * effectiveStep; +} + +static qreal positionAt(const QQuickRangeSlider *slider, QQuickItem *handle, const QPointF &point) +{ + if (slider->orientation() == Qt::Horizontal) { + const qreal hw = handle ? handle->width() : 0; + const qreal offset = hw / 2; + const qreal extent = slider->availableWidth() - hw; + if (!qFuzzyIsNull(extent)) { + if (slider->isMirrored()) + return (slider->width() - point.x() - slider->rightPadding() - offset) / extent; + return (point.x() - slider->leftPadding() - offset) / extent; + } + } else { + const qreal hh = handle ? handle->height() : 0; + const qreal offset = hh / 2; + const qreal extent = slider->availableHeight() - hh; + if (!qFuzzyIsNull(extent)) + return (slider->height() - point.y() - slider->bottomPadding() - offset) / extent; + } + return 0; +} + +QQuickRangeSliderNode *QQuickRangeSliderPrivate::pressedNode(int touchId) const +{ + if (touchId == -1) + return first->isPressed() ? first : (second->isPressed() ? second : nullptr); + if (QQuickRangeSliderNodePrivate::get(first)->touchId == touchId) + return first; + if (QQuickRangeSliderNodePrivate::get(second)->touchId == touchId) + return second; + return nullptr; +} + +#if QT_CONFIG(quicktemplates2_multitouch) +bool QQuickRangeSliderPrivate::acceptTouch(const QTouchEvent::TouchPoint &point) +{ + int firstId = QQuickRangeSliderNodePrivate::get(first)->touchId; + int secondId = QQuickRangeSliderNodePrivate::get(second)->touchId; + + if (((firstId == -1 || secondId == -1) && point.state() == QEventPoint::Pressed) || point.id() == firstId || point.id() == secondId) { + touchId = point.id(); + return true; + } + + return false; +} +#endif + +void QQuickRangeSliderPrivate::handlePress(const QPointF &point) +{ + Q_Q(QQuickRangeSlider); + QQuickControlPrivate::handlePress(point); + pressPoint = point; + + QQuickItem *firstHandle = first->handle(); + QQuickItem *secondHandle = second->handle(); + const bool firstHit = firstHandle && !first->isPressed() && firstHandle->contains(q->mapToItem(firstHandle, point)); + const bool secondHit = secondHandle && !second->isPressed() && secondHandle->contains(q->mapToItem(secondHandle, point)); + QQuickRangeSliderNode *hitNode = nullptr; + QQuickRangeSliderNode *otherNode = nullptr; + + if (firstHit && secondHit) { + // choose highest + hitNode = firstHandle->z() > secondHandle->z() ? first : second; + otherNode = firstHandle->z() > secondHandle->z() ? second : first; + } else if (firstHit) { + hitNode = first; + otherNode = second; + } else if (secondHit) { + hitNode = second; + otherNode = first; + } else { + // find the nearest + const qreal firstPos = positionAt(q, firstHandle, point); + const qreal secondPos = positionAt(q, secondHandle, point); + const qreal firstDistance = qAbs(firstPos - first->position()); + const qreal secondDistance = qAbs(secondPos - second->position()); + + if (qFuzzyCompare(firstDistance, secondDistance)) { + // same distance => choose the one that can be moved towards the press position + const bool inverted = from > to; + if ((!inverted && firstPos < first->position()) || (inverted && firstPos > first->position())) { + hitNode = first; + otherNode = second; + } else { + hitNode = second; + otherNode = first; + } + } else if (firstDistance < secondDistance) { + hitNode = first; + otherNode = second; + } else { + hitNode = second; + otherNode = first; + } + } + + if (hitNode) { + hitNode->setPressed(true); + if (QQuickItem *handle = hitNode->handle()) + handle->setZ(1); + QQuickRangeSliderNodePrivate::get(hitNode)->touchId = touchId; + } + if (otherNode) { + if (QQuickItem *handle = otherNode->handle()) + handle->setZ(0); + } +} + +void QQuickRangeSliderPrivate::handleMove(const QPointF &point) +{ + Q_Q(QQuickRangeSlider); + QQuickControlPrivate::handleMove(point); + QQuickRangeSliderNode *pressedNode = QQuickRangeSliderPrivate::pressedNode(touchId); + if (pressedNode) { + const qreal oldPos = pressedNode->position(); + qreal pos = positionAt(q, pressedNode->handle(), point); + if (snapMode == QQuickRangeSlider::SnapAlways) + pos = snapPosition(q, pos); + if (live) + pressedNode->setValue(valueAt(q, pos)); + else + QQuickRangeSliderNodePrivate::get(pressedNode)->setPosition(pos); + + if (!qFuzzyCompare(pressedNode->position(), oldPos)) + emit pressedNode->moved(); + } +} + +void QQuickRangeSliderPrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickRangeSlider); + QQuickControlPrivate::handleRelease(point); + pressPoint = QPointF(); + + QQuickRangeSliderNode *pressedNode = QQuickRangeSliderPrivate::pressedNode(touchId); + if (!pressedNode) + return; + QQuickRangeSliderNodePrivate *pressedNodePrivate = QQuickRangeSliderNodePrivate::get(pressedNode); + + const qreal oldPos = pressedNode->position(); + qreal pos = positionAt(q, pressedNode->handle(), point); + if (snapMode != QQuickRangeSlider::NoSnap) + pos = snapPosition(q, pos); + qreal val = valueAt(q, pos); + if (!qFuzzyCompare(val, pressedNode->value())) + pressedNode->setValue(val); + else if (snapMode != QQuickRangeSlider::NoSnap) + pressedNodePrivate->setPosition(pos); + q->setKeepMouseGrab(false); + q->setKeepTouchGrab(false); + + if (!qFuzzyCompare(pressedNode->position(), oldPos)) + emit pressedNode->moved(); + + pressedNode->setPressed(false); + pressedNodePrivate->touchId = -1; +} + +void QQuickRangeSliderPrivate::handleUngrab() +{ + QQuickControlPrivate::handleUngrab(); + pressPoint = QPointF(); + first->setPressed(false); + second->setPressed(false); + QQuickRangeSliderNodePrivate::get(first)->touchId = -1; + QQuickRangeSliderNodePrivate::get(second)->touchId = -1; +} + +void QQuickRangeSliderPrivate::updateHover(const QPointF &pos) +{ + Q_Q(QQuickRangeSlider); + QQuickItem *firstHandle = first->handle(); + QQuickItem *secondHandle = second->handle(); + bool firstHandleHovered = firstHandle && firstHandle->isEnabled() + && firstHandle->contains(q->mapToItem(firstHandle, pos)); + bool secondHandleHovered = secondHandle && secondHandle->isEnabled() + && secondHandle->contains(q->mapToItem(secondHandle, pos)); + + if (firstHandleHovered && secondHandleHovered) { + // Only hover the handle with the higher Z value. + const bool firstHandleHasHigherZ = firstHandle->z() > secondHandle->z(); + firstHandleHovered = firstHandleHasHigherZ; + secondHandleHovered = !firstHandleHasHigherZ; + } + first->setHovered(firstHandleHovered); + second->setHovered(secondHandleHovered); +} + +void QQuickRangeSliderPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + QQuickControlPrivate::itemImplicitWidthChanged(item); + if (item == first->handle()) + emit first->implicitHandleWidthChanged(); + else if (item == second->handle()) + emit second->implicitHandleWidthChanged(); +} + +void QQuickRangeSliderPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + QQuickControlPrivate::itemImplicitHeightChanged(item); + if (item == first->handle()) + emit first->implicitHandleHeightChanged(); + else if (item == second->handle()) + emit second->implicitHandleHeightChanged(); +} + +QQuickRangeSlider::QQuickRangeSlider(QQuickItem *parent) + : QQuickControl(*(new QQuickRangeSliderPrivate), parent) +{ + Q_D(QQuickRangeSlider); + d->first = new QQuickRangeSliderNode(0.0, this); + d->second = new QQuickRangeSliderNode(1.0, this); + + setFlag(QQuickItem::ItemIsFocusScope); + setAcceptedMouseButtons(Qt::LeftButton); +#if QT_CONFIG(quicktemplates2_multitouch) + setAcceptTouchEvents(true); +#endif +#if QT_CONFIG(cursor) + setCursor(Qt::ArrowCursor); +#endif +} + +QQuickRangeSlider::~QQuickRangeSlider() +{ + Q_D(QQuickRangeSlider); + d->removeImplicitSizeListener(d->first->handle()); + d->removeImplicitSizeListener(d->second->handle()); +} + +/*! + \qmlproperty real QtQuick.Controls::RangeSlider::from + + This property holds the starting value for the range. The default value is \c 0.0. + + \sa to, first.value, second.value +*/ +qreal QQuickRangeSlider::from() const +{ + Q_D(const QQuickRangeSlider); + return d->from; +} + +void QQuickRangeSlider::setFrom(qreal from) +{ + Q_D(QQuickRangeSlider); + if (qFuzzyCompare(d->from, from)) + return; + + d->from = from; + emit fromChanged(); + + if (isComponentComplete()) { + d->first->setValue(d->first->value()); + d->second->setValue(d->second->value()); + auto *firstPrivate = QQuickRangeSliderNodePrivate::get(d->first); + auto *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second); + firstPrivate->updatePosition(true); + secondPrivate->updatePosition(); + } +} + +/*! + \qmlproperty real QtQuick.Controls::RangeSlider::to + + This property holds the end value for the range. The default value is \c 1.0. + + \sa from, first.value, second.value +*/ +qreal QQuickRangeSlider::to() const +{ + Q_D(const QQuickRangeSlider); + return d->to; +} + +void QQuickRangeSlider::setTo(qreal to) +{ + Q_D(QQuickRangeSlider); + if (qFuzzyCompare(d->to, to)) + return; + + d->to = to; + emit toChanged(); + + if (isComponentComplete()) { + d->first->setValue(d->first->value()); + d->second->setValue(d->second->value()); + auto *firstPrivate = QQuickRangeSliderNodePrivate::get(d->first); + auto *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second); + firstPrivate->updatePosition(true); + secondPrivate->updatePosition(); + } +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty qreal QtQuick.Controls::RangeSlider::touchDragThreshold + + This property holds the threshold (in logical pixels) at which a touch drag event will be initiated. + The mouse drag threshold won't be affected. + The default value is \c Qt.styleHints.startDragDistance. + + \sa QStyleHints + +*/ +qreal QQuickRangeSlider::touchDragThreshold() const +{ + Q_D(const QQuickRangeSlider); + return d->touchDragThreshold; +} + +void QQuickRangeSlider::setTouchDragThreshold(qreal touchDragThreshold) +{ + Q_D(QQuickRangeSlider); + if (d->touchDragThreshold == touchDragThreshold) + return; + + d->touchDragThreshold = touchDragThreshold; + emit touchDragThresholdChanged(); +} + +void QQuickRangeSlider::resetTouchDragThreshold() +{ + setTouchDragThreshold(-1); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlmethod real QtQuick.Controls::RangeSlider::valueAt(real position) + + Returns the value for the given \a position. + + \sa first.value, second.value, first.position, second.position, live +*/ +qreal QQuickRangeSlider::valueAt(qreal position) const +{ + Q_D(const QQuickRangeSlider); + const qreal value = (d->to - d->from) * position; + if (qFuzzyIsNull(d->stepSize)) + return d->from + value; + return d->from + qRound(value / d->stepSize) * d->stepSize; +} + +/*! + \qmlproperty real QtQuick.Controls::RangeSlider::first.value + \qmlproperty real QtQuick.Controls::RangeSlider::first.position + \qmlproperty real QtQuick.Controls::RangeSlider::first.visualPosition + \qmlproperty Item QtQuick.Controls::RangeSlider::first.handle + \qmlproperty bool QtQuick.Controls::RangeSlider::first.pressed + \qmlproperty bool QtQuick.Controls::RangeSlider::first.hovered + \qmlproperty real QtQuick.Controls::RangeSlider::first.implicitHandleWidth + \qmlproperty real QtQuick.Controls::RangeSlider::first.implicitHandleHeight + + \table + \header + \li Property + \li Description + \row + \li value + \li This property holds the value of the first handle in the range + \c from - \c to. + + If \l from is greater than \l to, the value of the first handle + must be greater than the second, and vice versa. + + The default value is \c 0.0. + \row + \li handle + \li This property holds the first handle item. + \row + \li visualPosition + \li This property holds the visual position of the first handle. + + The position is expressed as a fraction of the control's size, in the range + \c {0.0 - 1.0}. When the control is \l {Control::mirrored}{mirrored}, the + value is equal to \c {1.0 - position}. This makes the value suitable for + visualizing the slider, taking right-to-left support into account. + \row + \li position + \li This property holds the logical position of the first handle. + + The position is expressed as a fraction of the control's size, in the range + \c {0.0 - 1.0}. For visualizing a slider, the right-to-left aware + \l {first.visualPosition}{visualPosition} should be used instead. + \row + \li pressed + \li This property holds whether the first handle is pressed by either touch, + mouse, or keys. + \row + \li hovered + \li This property holds whether the first handle is hovered. + This property was introduced in QtQuick.Controls 2.1. + \row + \li implicitHandleWidth + \li This property holds the implicit width of the first handle. + This property was introduced in QtQuick.Controls 2.5. + \row + \li implicitHandleHeight + \li This property holds the implicit height of the first handle. + This property was introduced in QtQuick.Controls 2.5. + \endtable + + \sa first.moved(), first.increase(), first.decrease() +*/ +QQuickRangeSliderNode *QQuickRangeSlider::first() const +{ + Q_D(const QQuickRangeSlider); + return d->first; +} + +/*! + \qmlsignal void QtQuick.Controls::RangeSlider::first.moved() + \qmlsignal void QtQuick.Controls::RangeSlider::second.moved() + \since QtQuick.Controls 2.5 + + This signal is emitted when either the first or second handle has been + interactively moved by the user by either touch, mouse, or keys. + + \sa first, second +*/ + +/*! + \qmlproperty real QtQuick.Controls::RangeSlider::second.value + \qmlproperty real QtQuick.Controls::RangeSlider::second.position + \qmlproperty real QtQuick.Controls::RangeSlider::second.visualPosition + \qmlproperty Item QtQuick.Controls::RangeSlider::second.handle + \qmlproperty bool QtQuick.Controls::RangeSlider::second.pressed + \qmlproperty bool QtQuick.Controls::RangeSlider::second.hovered + \qmlproperty real QtQuick.Controls::RangeSlider::second.implicitHandleWidth + \qmlproperty real QtQuick.Controls::RangeSlider::second.implicitHandleHeight + + \table + \header + \li Property + \li Description + \row + \li value + \li This property holds the value of the second handle in the range + \c from - \c to. + + If \l from is greater than \l to, the value of the first handle + must be greater than the second, and vice versa. + + The default value is \c 0.0. + \row + \li handle + \li This property holds the second handle item. + \row + \li visualPosition + \li This property holds the visual position of the second handle. + + The position is expressed as a fraction of the control's size, in the range + \c {0.0 - 1.0}. When the control is \l {Control::mirrored}{mirrored}, the + value is equal to \c {1.0 - position}. This makes the value suitable for + visualizing the slider, taking right-to-left support into account. + \row + \li position + \li This property holds the logical position of the second handle. + + The position is expressed as a fraction of the control's size, in the range + \c {0.0 - 1.0}. For visualizing a slider, the right-to-left aware + \l {second.visualPosition}{visualPosition} should be used instead. + \row + \li pressed + \li This property holds whether the second handle is pressed by either touch, + mouse, or keys. + \row + \li hovered + \li This property holds whether the second handle is hovered. + This property was introduced in QtQuick.Controls 2.1. + \row + \li implicitHandleWidth + \li This property holds the implicit width of the second handle. + This property was introduced in QtQuick.Controls 2.5. + \row + \li implicitHandleHeight + \li This property holds the implicit height of the second handle. + This property was introduced in QtQuick.Controls 2.5. + \endtable + + \sa second.moved(), second.increase(), second.decrease() +*/ +QQuickRangeSliderNode *QQuickRangeSlider::second() const +{ + Q_D(const QQuickRangeSlider); + return d->second; +} + +/*! + \qmlproperty real QtQuick.Controls::RangeSlider::stepSize + + This property holds the step size. The default value is \c 0.0. + + \sa snapMode, first.increase(), first.decrease() +*/ +qreal QQuickRangeSlider::stepSize() const +{ + Q_D(const QQuickRangeSlider); + return d->stepSize; +} + +void QQuickRangeSlider::setStepSize(qreal step) +{ + Q_D(QQuickRangeSlider); + if (qFuzzyCompare(d->stepSize, step)) + return; + + d->stepSize = step; + emit stepSizeChanged(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::RangeSlider::snapMode + + This property holds the snap mode. + + The snap mode determines how the slider handles behave with + regards to the \l stepSize. + + Possible values: + \value RangeSlider.NoSnap The slider does not snap (default). + \value RangeSlider.SnapAlways The slider snaps while the handle is dragged. + \value RangeSlider.SnapOnRelease The slider does not snap while being dragged, but only after the handle is released. + + For visual explanations of the various modes, see the + \l {Slider::}{snapMode} documentation of \l Slider. + + \sa stepSize +*/ +QQuickRangeSlider::SnapMode QQuickRangeSlider::snapMode() const +{ + Q_D(const QQuickRangeSlider); + return d->snapMode; +} + +void QQuickRangeSlider::setSnapMode(SnapMode mode) +{ + Q_D(QQuickRangeSlider); + if (d->snapMode == mode) + return; + + d->snapMode = mode; + emit snapModeChanged(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::RangeSlider::orientation + + This property holds the orientation. + + Possible values: + \value Qt.Horizontal Horizontal (default) + \value Qt.Vertical Vertical + + \sa horizontal, vertical +*/ +Qt::Orientation QQuickRangeSlider::orientation() const +{ + Q_D(const QQuickRangeSlider); + return d->orientation; +} + +void QQuickRangeSlider::setOrientation(Qt::Orientation orientation) +{ + Q_D(QQuickRangeSlider); + if (d->orientation == orientation) + return; + + d->orientation = orientation; + emit orientationChanged(); +} + +/*! + \qmlmethod void QtQuick.Controls::RangeSlider::setValues(real firstValue, real secondValue) + + Sets \l first.value and \l second.value with the given arguments. + + If \l to is larger than \l from and \a firstValue is larger than + \a secondValue, firstValue will be clamped to secondValue. + + If \l from is larger than \l to and secondValue is larger than + firstValue, secondValue will be clamped to firstValue. + + This function may be necessary to set the first and second values + after the control has been completed, as there is a circular + dependency between firstValue and secondValue which can cause + assigned values to be clamped to each other. + + \sa stepSize +*/ +void QQuickRangeSlider::setValues(qreal firstValue, qreal secondValue) +{ + Q_D(QQuickRangeSlider); + // Restrict the values to be within to and from. + const qreal smaller = qMin(d->to, d->from); + const qreal larger = qMax(d->to, d->from); + firstValue = qBound(smaller, firstValue, larger); + secondValue = qBound(smaller, secondValue, larger); + + if (d->from > d->to) { + // If the from and to values are reversed, the secondValue + // might be less than the first value, which is not allowed. + if (secondValue > firstValue) + secondValue = firstValue; + } else { + // Otherwise, clamp first to second if it's too large. + if (firstValue > secondValue) + firstValue = secondValue; + } + + // Then set both values. If they didn't change, no change signal will be emitted. + QQuickRangeSliderNodePrivate *firstPrivate = QQuickRangeSliderNodePrivate::get(d->first); + if (firstValue != firstPrivate->value) { + firstPrivate->value = firstValue; + emit d->first->valueChanged(); + } + + QQuickRangeSliderNodePrivate *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second); + if (secondValue != secondPrivate->value) { + secondPrivate->value = secondValue; + emit d->second->valueChanged(); + } + + // After we've set both values, then we can update the positions. + // If we don't do this last, the positions may be incorrect. + firstPrivate->updatePosition(true); + secondPrivate->updatePosition(); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty bool QtQuick.Controls::RangeSlider::live + + This property holds whether the slider provides live updates for the \l first.value + and \l second.value properties while the respective handles are dragged. + + The default value is \c true. + + \sa first.value, second.value +*/ +bool QQuickRangeSlider::live() const +{ + Q_D(const QQuickRangeSlider); + return d->live; +} + +void QQuickRangeSlider::setLive(bool live) +{ + Q_D(QQuickRangeSlider); + if (d->live == live) + return; + + d->live = live; + emit liveChanged(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::RangeSlider::horizontal + \readonly + + This property holds whether the slider is horizontal. + + \sa orientation +*/ +bool QQuickRangeSlider::isHorizontal() const +{ + Q_D(const QQuickRangeSlider); + return d->orientation == Qt::Horizontal; +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::RangeSlider::vertical + \readonly + + This property holds whether the slider is vertical. + + \sa orientation +*/ +bool QQuickRangeSlider::isVertical() const +{ + Q_D(const QQuickRangeSlider); + return d->orientation == Qt::Vertical; +} + +void QQuickRangeSlider::focusInEvent(QFocusEvent *event) +{ + Q_D(QQuickRangeSlider); + QQuickControl::focusInEvent(event); + + // The active focus ends up to RangeSlider when using forceActiveFocus() + // or QML KeyNavigation. We must forward the focus to one of the handles, + // because RangeSlider handles key events for the focused handle. If + // neither handle has active focus, RangeSlider doesn't do anything. + QQuickItem *handle = nextItemInFocusChain(); + // QQuickItem::nextItemInFocusChain() only works as desired with + // Qt::TabFocusAllControls. otherwise pick the first handle + if (!handle || handle == this) + handle = d->first->handle(); + if (handle) + handle->forceActiveFocus(event->reason()); +} + +void QQuickRangeSlider::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickRangeSlider); + QQuickControl::keyPressEvent(event); + + QQuickRangeSliderNode *focusNode = d->first->handle()->hasActiveFocus() + ? d->first : (d->second->handle()->hasActiveFocus() ? d->second : nullptr); + if (!focusNode) + return; + + const qreal oldValue = focusNode->value(); + if (d->orientation == Qt::Horizontal) { + if (event->key() == Qt::Key_Left) { + focusNode->setPressed(true); + if (isMirrored()) + focusNode->increase(); + else + focusNode->decrease(); + event->accept(); + } else if (event->key() == Qt::Key_Right) { + focusNode->setPressed(true); + if (isMirrored()) + focusNode->decrease(); + else + focusNode->increase(); + event->accept(); + } + } else { + if (event->key() == Qt::Key_Up) { + focusNode->setPressed(true); + focusNode->increase(); + event->accept(); + } else if (event->key() == Qt::Key_Down) { + focusNode->setPressed(true); + focusNode->decrease(); + event->accept(); + } + } + if (!qFuzzyCompare(focusNode->value(), oldValue)) + emit focusNode->moved(); +} + +void QQuickRangeSlider::hoverEnterEvent(QHoverEvent *event) +{ + Q_D(QQuickRangeSlider); + QQuickControl::hoverEnterEvent(event); + d->updateHover(event->position()); + event->ignore(); +} + +void QQuickRangeSlider::hoverMoveEvent(QHoverEvent *event) +{ + Q_D(QQuickRangeSlider); + QQuickControl::hoverMoveEvent(event); + d->updateHover(event->position()); + event->ignore(); +} + +void QQuickRangeSlider::hoverLeaveEvent(QHoverEvent *event) +{ + Q_D(QQuickRangeSlider); + QQuickControl::hoverLeaveEvent(event); + d->first->setHovered(false); + d->second->setHovered(false); + event->ignore(); +} + +void QQuickRangeSlider::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QQuickRangeSlider); + QQuickControl::keyReleaseEvent(event); + d->first->setPressed(false); + d->second->setPressed(false); +} + +void QQuickRangeSlider::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickRangeSlider); + QQuickControl::mousePressEvent(event); + d->handleMove(event->position()); + setKeepMouseGrab(true); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickRangeSlider::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickRangeSlider); + switch (event->type()) { + case QEvent::TouchUpdate: + for (const QTouchEvent::TouchPoint &point : event->points()) { + if (!d->acceptTouch(point)) + continue; + + switch (point.state()) { + case QEventPoint::Pressed: + d->handlePress(point.position()); + break; + case QEventPoint::Updated: + if (!keepTouchGrab()) { + if (d->orientation == Qt::Horizontal) + setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().x() - point.pressPosition().x(), Qt::XAxis, &point, qRound(d->touchDragThreshold))); + else + setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().y() - point.pressPosition().y(), Qt::YAxis, &point, qRound(d->touchDragThreshold))); + } + if (keepTouchGrab()) + d->handleMove(point.position()); + break; + case QEventPoint::Released: + d->handleRelease(point.position()); + break; + default: + break; + } + } + break; + + default: + QQuickControl::touchEvent(event); + break; + } +} +#endif + +void QQuickRangeSlider::mirrorChange() +{ + Q_D(QQuickRangeSlider); + QQuickControl::mirrorChange(); + emit d->first->visualPositionChanged(); + emit d->second->visualPositionChanged(); +} + +void QQuickRangeSlider::classBegin() +{ + Q_D(QQuickRangeSlider); + QQuickControl::classBegin(); + + QQmlContext *context = qmlContext(this); + if (context) { + QQmlEngine::setContextForObject(d->first, context); + QQmlEngine::setContextForObject(d->second, context); + } +} + +void QQuickRangeSlider::componentComplete() +{ + Q_D(QQuickRangeSlider); + QQuickRangeSliderNodePrivate *firstPrivate = QQuickRangeSliderNodePrivate::get(d->first); + QQuickRangeSliderNodePrivate *secondPrivate = QQuickRangeSliderNodePrivate::get(d->second); + firstPrivate->executeHandle(true); + secondPrivate->executeHandle(true); + + QQuickControl::componentComplete(); + + if (firstPrivate->isPendingValue || secondPrivate->isPendingValue + || !qFuzzyCompare(d->from, defaultFrom) || !qFuzzyCompare(d->to, defaultTo)) { + // Properties were set while we were loading. To avoid clamping issues that occur when setting the + // values of first and second overriding values set by the user, set them all at once at the end. + // Another reason that we must set these values here is that the from and to values might have made the old range invalid. + setValues(firstPrivate->isPendingValue ? firstPrivate->pendingValue : firstPrivate->value, + secondPrivate->isPendingValue ? secondPrivate->pendingValue : secondPrivate->value); + + firstPrivate->pendingValue = 0; + firstPrivate->isPendingValue = false; + secondPrivate->pendingValue = 0; + secondPrivate->isPendingValue = false; + } else { + // If there was no pending data, we must still update the positions, + // as first.setValue()/second.setValue() won't be called as part of default construction. + // Don't need to ignore the second position when updating the first position here, + // as our default values are guaranteed to be valid. + firstPrivate->updatePosition(); + secondPrivate->updatePosition(); + } +} + +/*! + \qmlmethod void QtQuick.Controls::RangeSlider::first.increase() + + Increases the value of the handle by stepSize, or \c 0.1 if stepSize is not defined. + + \sa first +*/ + +/*! + \qmlmethod void QtQuick.Controls::RangeSlider::first.decrease() + + Decreases the value of the handle by stepSize, or \c 0.1 if stepSize is not defined. + + \sa first +*/ + +/*! + \qmlmethod void QtQuick.Controls::RangeSlider::second.increase() + + Increases the value of the handle by stepSize, or \c 0.1 if stepSize is not defined. + + \sa second +*/ + +/*! + \qmlmethod void QtQuick.Controls::RangeSlider::second.decrease() + + Decreases the value of the handle by stepSize, or \c 0.1 if stepSize is not defined. + + \sa second +*/ + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickRangeSlider::accessibleRole() const +{ + return QAccessible::Slider; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickrangeslider_p.cpp" diff --git a/src/quicktemplates2/qquickrangeslider_p.h b/src/quicktemplates2/qquickrangeslider_p.h new file mode 100644 index 00000000000..d767228e10b --- /dev/null +++ b/src/quicktemplates2/qquickrangeslider_p.h @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKRANGESLIDER_P_H +#define QQUICKRANGESLIDER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickRangeSliderPrivate; +class QQuickRangeSliderNode; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRangeSlider : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged FINAL) + Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged FINAL) + Q_PROPERTY(QQuickRangeSliderNode *first READ first CONSTANT FINAL) + Q_PROPERTY(QQuickRangeSliderNode *second READ second CONSTANT FINAL) + Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged FINAL) + Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged FINAL) + Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL) + // 2.2 (Qt 5.9) + Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION(2, 2)) + Q_PROPERTY(bool horizontal READ isHorizontal NOTIFY orientationChanged FINAL REVISION(2, 3)) + // 2.3 (Qt 5.10) + Q_PROPERTY(bool vertical READ isVertical NOTIFY orientationChanged FINAL REVISION(2, 3)) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal touchDragThreshold READ touchDragThreshold WRITE setTouchDragThreshold RESET resetTouchDragThreshold NOTIFY touchDragThresholdChanged FINAL REVISION(2, 5)) + QML_NAMED_ELEMENT(RangeSlider) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickRangeSlider(QQuickItem *parent = nullptr); + ~QQuickRangeSlider(); + + qreal from() const; + void setFrom(qreal from); + + qreal to() const; + void setTo(qreal to); + + QQuickRangeSliderNode *first() const; + QQuickRangeSliderNode *second() const; + + qreal stepSize() const; + void setStepSize(qreal step); + + enum SnapMode { + NoSnap, + SnapAlways, + SnapOnRelease + }; + Q_ENUM(SnapMode) + + SnapMode snapMode() const; + void setSnapMode(SnapMode mode); + + Qt::Orientation orientation() const; + void setOrientation(Qt::Orientation orientation); + + Q_INVOKABLE void setValues(qreal firstValue, qreal secondValue); + + // 2.2 (Qt 5.9) + bool live() const; + void setLive(bool live); + + // 2.3 (Qt 5.10) + bool isHorizontal() const; + bool isVertical() const; + + // 2.5 (Qt 5.12) + qreal touchDragThreshold() const; + void setTouchDragThreshold(qreal touchDragThreshold); + void resetTouchDragThreshold(); + Q_REVISION(2, 5) Q_INVOKABLE qreal valueAt(qreal position) const; + +Q_SIGNALS: + void fromChanged(); + void toChanged(); + void stepSizeChanged(); + void snapModeChanged(); + void orientationChanged(); + // 2.2 (Qt 5.9) + Q_REVISION(2, 2) void liveChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void touchDragThresholdChanged(); + +protected: + void focusInEvent(QFocusEvent *event) override; + void hoverEnterEvent(QHoverEvent *event) override; + void hoverMoveEvent(QHoverEvent *event) override; + void hoverLeaveEvent(QHoverEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void keyReleaseEvent(QKeyEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif + void mirrorChange() override; + void classBegin() override; + void componentComplete() override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + friend class QQuickRangeSliderNode; + + Q_DISABLE_COPY(QQuickRangeSlider) + Q_DECLARE_PRIVATE(QQuickRangeSlider) +}; + +class QQuickRangeSliderNodePrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRangeSliderNode : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged FINAL) + Q_PROPERTY(qreal position READ position NOTIFY positionChanged FINAL) + Q_PROPERTY(qreal visualPosition READ visualPosition NOTIFY visualPositionChanged FINAL) + Q_PROPERTY(QQuickItem *handle READ handle WRITE setHandle NOTIFY handleChanged FINAL) + Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL) + // 2.1 (Qt 5.8) + Q_PROPERTY(bool hovered READ isHovered WRITE setHovered NOTIFY hoveredChanged FINAL REVISION(2, 1)) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitHandleWidth READ implicitHandleWidth NOTIFY implicitHandleWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitHandleHeight READ implicitHandleHeight NOTIFY implicitHandleHeightChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DeferredPropertyNames", "handle") + QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickRangeSliderNode(qreal value, QQuickRangeSlider *slider); + ~QQuickRangeSliderNode(); + + qreal value() const; + void setValue(qreal value); + + qreal position() const; + qreal visualPosition() const; + + QQuickItem *handle() const; + void setHandle(QQuickItem *handle); + + bool isPressed() const; + void setPressed(bool pressed); + + // 2.1 (Qt 5.8) + bool isHovered() const; + void setHovered(bool hovered); + + // 2.5 (Qt 5.12) + qreal implicitHandleWidth() const; + qreal implicitHandleHeight() const; + +public Q_SLOTS: + void increase(); + void decrease(); + +Q_SIGNALS: + void valueChanged(); + void positionChanged(); + void visualPositionChanged(); + void handleChanged(); + void pressedChanged(); + // 2.1 (Qt 5.8) + Q_REVISION(2, 1) void hoveredChanged(); + // 2.5 (Qt 5.12) + /*Q_REVISION(2, 5)*/ void moved(); + /*Q_REVISION(2, 5)*/ void implicitHandleWidthChanged(); + /*Q_REVISION(2, 5)*/ void implicitHandleHeightChanged(); + +private: + Q_DISABLE_COPY(QQuickRangeSliderNode) + Q_DECLARE_PRIVATE(QQuickRangeSliderNode) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickRangeSlider) + +#endif // QQUICKRANGESLIDER_P_H diff --git a/src/quicktemplates2/qquickroundbutton.cpp b/src/quicktemplates2/qquickroundbutton.cpp new file mode 100644 index 00000000000..0f1b366cd90 --- /dev/null +++ b/src/quicktemplates2/qquickroundbutton.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickroundbutton_p.h" + +#include <QtQuickTemplates2/private/qquickbutton_p_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype RoundButton + \inherits Button +//! \instantiates QQuickRoundButton + \inqmlmodule QtQuick.Controls + \since 5.8 + \ingroup qtquickcontrols2-buttons + \brief A push-button control with rounded corners that can be clicked by the user. + + \image qtquickcontrols2-roundbutton.png + + RoundButton is identical to \l Button, except that it has a \l radius property + which allows the corners to be rounded without having to customize the + \l background. + + \snippet qtquickcontrols2-roundbutton.qml 1 + + \sa {Customizing RoundButton}, {Button Controls} +*/ + +class QQuickRoundButtonPrivate : public QQuickButtonPrivate +{ + Q_DECLARE_PUBLIC(QQuickRoundButton) + +public: + void setRadius(qreal newRadius = -1.0); + + qreal radius = 0; + bool explicitRadius = false; +}; + +void QQuickRoundButtonPrivate::setRadius(qreal newRadius) +{ + Q_Q(QQuickRoundButton); + const qreal oldRadius = radius; + if (newRadius < 0) + radius = qMax<qreal>(0, qMin<qreal>(width, height) / 2); + else + radius = newRadius; + + if (!qFuzzyCompare(radius, oldRadius)) + emit q->radiusChanged(); +} + +QQuickRoundButton::QQuickRoundButton(QQuickItem *parent) + : QQuickButton(*(new QQuickRoundButtonPrivate), parent) +{ +} + +/*! + \qmlproperty real QtQuick.Controls::RoundButton::radius + + This property holds the radius of the button. + + To create a relatively square button that has slightly rounded corners, + use a small value, such as \c 3. + + To create a completely circular button (the default), use a value that is + equal to half of the width or height of the button, and make the button's + width and height identical. + + To reset this property back to the default value, set its value to + \c undefined. +*/ +qreal QQuickRoundButton::radius() const +{ + Q_D(const QQuickRoundButton); + return d->radius; +} + +void QQuickRoundButton::setRadius(qreal radius) +{ + Q_D(QQuickRoundButton); + d->explicitRadius = true; + d->setRadius(radius); +} + +void QQuickRoundButton::resetRadius() +{ + Q_D(QQuickRoundButton); + d->explicitRadius = false; + d->setRadius(); +} + +void QQuickRoundButton::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickRoundButton); + QQuickControl::geometryChange(newGeometry, oldGeometry); + if (!d->explicitRadius) + d->setRadius(); +} + +QT_END_NAMESPACE + +#include "moc_qquickroundbutton_p.cpp" diff --git a/src/quicktemplates2/qquickroundbutton_p.h b/src/quicktemplates2/qquickroundbutton_p.h new file mode 100644 index 00000000000..fdd46cf8f64 --- /dev/null +++ b/src/quicktemplates2/qquickroundbutton_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKROUNDBUTTON_P_H +#define QQUICKROUNDBUTTON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickRoundButtonPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRoundButton : public QQuickButton +{ + Q_OBJECT + Q_PROPERTY(qreal radius READ radius WRITE setRadius RESET resetRadius NOTIFY radiusChanged FINAL) + QML_NAMED_ELEMENT(RoundButton) + QML_ADDED_IN_VERSION(2, 1) + +public: + explicit QQuickRoundButton(QQuickItem *parent = nullptr); + + qreal radius() const; + void setRadius(qreal radius); + void resetRadius(); + +Q_SIGNALS: + void radiusChanged(); + +protected: + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + +private: + Q_DISABLE_COPY(QQuickRoundButton) + Q_DECLARE_PRIVATE(QQuickRoundButton) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickRoundButton) + +#endif // QQUICKROUNDBUTTON_P_H diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp new file mode 100644 index 00000000000..41f76e2d903 --- /dev/null +++ b/src/quicktemplates2/qquickscrollbar.cpp @@ -0,0 +1,1284 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickscrollbar_p.h" +#include "qquickscrollbar_p_p.h" +#include "qquickscrollview_p.h" + +#include <QtQml/qqmlinfo.h> +#include <QtQuick/private/qquickflickable_p.h> +#if QT_CONFIG(accessibility) +#include <QtQuick/private/qquickaccessibleattached_p.h> +#endif + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ScrollBar + \inherits Control +//! \instantiates QQuickScrollBar + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-indicators + \brief Vertical or horizontal interactive scroll bar. + + \image qtquickcontrols2-scrollbar.gif + + ScrollBar is an interactive bar that can be used to scroll to a specific + position. A scroll bar can be either \l vertical or \l horizontal, and can + be attached to any \l Flickable, such as \l ListView and \l GridView. + It can also be used with \l ScrollView. + + \code + Flickable { + // ... + ScrollBar.vertical: ScrollBar { } + } + \endcode + + \section1 Attaching ScrollBar to a Flickable + + When ScrollBar is attached \l {ScrollBar::vertical}{vertically} or + \l {ScrollBar::horizontal}{horizontally} to a Flickable, its geometry and + the following properties are automatically set and updated as appropriate: + + \list + \li \l orientation + \li \l position + \li \l size + \li \l active + \endlist + + An attached ScrollBar re-parents itself to the target Flickable. A vertically + attached ScrollBar resizes itself to the height of the Flickable, and positions + itself to either side of it based on the \l {Control::mirrored}{layout direction}. + A horizontally attached ScrollBar resizes itself to the width of the Flickable, + and positions itself to the bottom. The automatic geometry management can be disabled + by specifying another parent for the attached ScrollBar. This can be useful, for + example, if the ScrollBar should be placed outside a clipping Flickable. This is + demonstrated by the following example: + + \code + Flickable { + id: flickable + clip: true + // ... + ScrollBar.vertical: ScrollBar { + parent: flickable.parent + anchors.top: flickable.top + anchors.left: flickable.right + anchors.bottom: flickable.bottom + } + } + \endcode + + Notice that ScrollBar does not filter key events of the Flickable it is + attached to. The following example illustrates how to implement scrolling + with up and down keys: + + \code + Flickable { + focus: true + + Keys.onUpPressed: scrollBar.decrease() + Keys.onDownPressed: scrollBar.increase() + + ScrollBar.vertical: ScrollBar { id: scrollBar } + } + \endcode + + \section1 Binding the Active State of Horizontal and Vertical Scroll Bars + + Horizontal and vertical scroll bars do not share the \l active state with + each other by default. In order to keep both bars visible whilst scrolling + to either direction, establish a two-way binding between the active states + as presented by the following example: + + \snippet qtquickcontrols2-scrollbar-active.qml 1 + + \section1 Non-attached Scroll Bars + + It is possible to create an instance of ScrollBar without using the + attached property API. This is useful when the behavior of the attached + scroll bar is not sufficient or a \l Flickable is not in use. In the + following example, horizontal and vertical scroll bars are used to + scroll over the text without using \l Flickable: + + \snippet qtquickcontrols2-scrollbar-non-attached.qml 1 + + \image qtquickcontrols2-scrollbar-non-attached.png + + When using a non-attached ScrollBar, the following must be done manually: + + \list + \li Layout the scroll bar (with the \l {Item::}{x} and \l {Item::}{y} or + \l {Item::}{anchors} property, for example). + \li Set the \l size and \l position properties to determine the size and position + of the scroll bar in relation to the scrolled item. + \li Set the \l active property to determine when the scroll bar will be + visible. + \endlist + + \sa ScrollIndicator, ScrollView, {Customizing ScrollBar}, {Indicator Controls} +*/ + +static const QQuickItemPrivate::ChangeTypes changeTypes = QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed; +static const QQuickItemPrivate::ChangeTypes horizontalChangeTypes = changeTypes | QQuickItemPrivate::ImplicitHeight; +static const QQuickItemPrivate::ChangeTypes verticalChangeTypes = changeTypes | QQuickItemPrivate::ImplicitWidth; + +QQuickScrollBarPrivate::VisualArea QQuickScrollBarPrivate::visualArea() const +{ + qreal visualPos = position; + + if (minimumSize > size && size != 1.0) + visualPos = position / (1.0 - size) * (1.0 - minimumSize); + + qreal visualSize = qBound<qreal>(0, qMax(size, minimumSize) + qMin<qreal>(0, visualPos), + qMax(0.0, 1.0 - visualPos)); + + visualPos = qBound<qreal>(0, visualPos, 1.0 - visualSize); + + return VisualArea(visualPos, visualSize); +} + +qreal QQuickScrollBarPrivate::logicalPosition(qreal position) const +{ + if (minimumSize > size && minimumSize != 1.0) + return position * (1.0 - size) / (1.0 - minimumSize); + return position; +} + +qreal QQuickScrollBarPrivate::snapPosition(qreal position) const +{ + const qreal effectiveStep = stepSize * (1.0 - size); + if (qFuzzyIsNull(effectiveStep)) + return position; + + return qRound(position / effectiveStep) * effectiveStep; +} + +qreal QQuickScrollBarPrivate::positionAt(const QPointF &point) const +{ + Q_Q(const QQuickScrollBar); + if (orientation == Qt::Horizontal) + return logicalPosition(point.x() - q->leftPadding()) / q->availableWidth(); + else + return logicalPosition(point.y() - q->topPadding()) / q->availableHeight(); +} + +void QQuickScrollBarPrivate::setInteractive(bool enabled) +{ + Q_Q(QQuickScrollBar); + if (interactive == enabled) + return; + + interactive = enabled; + if (interactive) { + q->setAcceptedMouseButtons(Qt::LeftButton); +#if QT_CONFIG(quicktemplates2_multitouch) + q->setAcceptTouchEvents(true); +#endif +#if QT_CONFIG(cursor) + q->setCursor(Qt::ArrowCursor); +#endif + } else { + q->setAcceptedMouseButtons(Qt::NoButton); +#if QT_CONFIG(quicktemplates2_multitouch) + q->setAcceptTouchEvents(false); +#endif +#if QT_CONFIG(cursor) + q->unsetCursor(); +#endif + q->ungrabMouse(); + } + emit q->interactiveChanged(); +} + +void QQuickScrollBarPrivate::updateActive() +{ + Q_Q(QQuickScrollBar); +#if QT_CONFIG(quicktemplates2_hover) + bool hover = hovered; +#else + bool hover = false; +#endif + q->setActive(moving || (interactive && (pressed || hover))); +} + +void QQuickScrollBarPrivate::resizeContent() +{ + Q_Q(QQuickScrollBar); + if (!contentItem) + return; + + // - negative overshoot (pos < 0): clamp the pos to 0, and deduct the overshoot from the size + // - positive overshoot (pos + size > 1): clamp the size to 1-pos + const VisualArea visual = visualArea(); + + if (orientation == Qt::Horizontal) { + contentItem->setPosition(QPointF(q->leftPadding() + visual.position * q->availableWidth(), q->topPadding())); + contentItem->setSize(QSizeF(q->availableWidth() * visual.size, q->availableHeight())); + } else { + contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding() + visual.position * q->availableHeight())); + contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight() * visual.size)); + } +} + +void QQuickScrollBarPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickScrollBar); + QQuickControlPrivate::itemImplicitWidthChanged(item); + QQuickIndicatorButton *indicatorButton = q->decreaseVisual(); + if (!indicatorButton || item != indicatorButton->indicator()) { + indicatorButton = q->increaseVisual(); + if (!indicatorButton || item != indicatorButton->indicator()) + return; + } + if (indicatorButton) + emit indicatorButton->implicitIndicatorWidthChanged(); +} + +void QQuickScrollBarPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickScrollBar); + QQuickControlPrivate::itemImplicitHeightChanged(item); + QQuickIndicatorButton *indicatorButton = q->decreaseVisual(); + if (!indicatorButton || item != indicatorButton->indicator()) { + indicatorButton = q->increaseVisual(); + if (!indicatorButton || item != indicatorButton->indicator()) + return; + } + if (indicatorButton) + emit indicatorButton->implicitIndicatorHeightChanged(); +} + +void QQuickScrollBarPrivate::handlePress(const QPointF &point) +{ + Q_Q(QQuickScrollBar); + QQuickControlPrivate::handlePress(point); + if (QQuickIndicatorButton *indicatorButton = q->decreaseVisual()) { + QQuickItem *decreaseArrow = indicatorButton->indicator(); + if (decreaseArrow && decreaseArrow->contains(q->mapToItem(decreaseArrow, point + QPointF(0.5, 0.5)))) { + indicatorButton->setPressed(true); + q->decrease(); + return; + } + } + + if (QQuickIndicatorButton *increaseObject = q->increaseVisual()) { + QQuickItem *increaseArrow = increaseObject->indicator(); + if (increaseArrow && increaseArrow->contains(q->mapToItem(increaseArrow, point + QPointF(0.5, 0.5)))) { + increaseObject->setPressed(true); + q->increase(); + return; + } + } + + offset = positionAt(point) - position; + qreal sz = qMax(size, logicalPosition(minimumSize)); + if (offset < 0 || offset > sz) + offset = sz / 2; + q->setPressed(true); +} + +void QQuickScrollBarPrivate::handleMove(const QPointF &point) +{ + Q_Q(QQuickScrollBar); + QQuickControlPrivate::handleMove(point); + + /* + * handleMove() will be called as soon as you hold the mouse button down *anywhere* on the + * ScrollBar, including the increase/decrease button indicator areas. So without the following + * early return, it would move the scrollbar handle to one of its extremeties. That would + * ruin the behavior we would like when clicking e.g. the "increase button": To step the + * scrollbar gently. + */ + if (!pressed) + return; + qreal pos = qBound<qreal>(0.0, positionAt(point) - offset, 1.0 - size); + if (snapMode == QQuickScrollBar::SnapAlways) + pos = snapPosition(pos); + q->setPosition(pos); +} + +void QQuickScrollBarPrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickScrollBar); + QQuickControlPrivate::handleRelease(point); + + if (orientation == Qt::Vertical) { + if (point.y() < q->topPadding() || point.y() >= (q->height() - q->bottomPadding())) + return; + } else /* orientation == Qt::Horizontal */{ + if (point.x() < q->leftPadding() || point.x() >= (q->width() - q->rightPadding())) + return; + } + qreal pos = qBound<qreal>(0.0, positionAt(point) - offset, 1.0 - size); + if (snapMode != QQuickScrollBar::NoSnap) + pos = snapPosition(pos); + q->setPosition(pos); + offset = 0.0; + q->setPressed(false); +} + +void QQuickScrollBarPrivate::handleUngrab() +{ + Q_Q(QQuickScrollBar); + QQuickControlPrivate::handleUngrab(); + offset = 0.0; + q->setPressed(false); +} + +void QQuickScrollBarPrivate::visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea) +{ + Q_Q(QQuickScrollBar); + if (!qFuzzyCompare(newVisualArea.size, oldVisualArea.size)) + emit q->visualSizeChanged(); + if (!qFuzzyCompare(newVisualArea.position, oldVisualArea.position)) + emit q->visualPositionChanged(); +} + +void QQuickScrollBarPrivate::updateHover(const QPointF &pos, std::optional<bool> newHoverState) +{ + Q_Q(QQuickScrollBar); + auto updateHoverOnButton = [&](QQuickIndicatorButton *sbButton) { + if (sbButton) { + bool hovered = newHoverState.value_or(false); + if (!newHoverState.has_value()) { + if (QQuickItem *indicator = sbButton->indicator()) + hovered = indicator->contains(q->mapToItem(indicator, pos)); + } + sbButton->setHovered(hovered); + } + }; + updateHoverOnButton(q->decreaseVisual()); + updateHoverOnButton(q->increaseVisual()); +} + +QQuickScrollBar::QQuickScrollBar(QQuickItem *parent) + : QQuickControl(*(new QQuickScrollBarPrivate), parent) +{ + Q_D(QQuickScrollBar); + d->decreaseVisual = new QQuickIndicatorButton(this); + d->increaseVisual = new QQuickIndicatorButton(this); + setKeepMouseGrab(true); + setAcceptedMouseButtons(Qt::LeftButton); +#if QT_CONFIG(quicktemplates2_multitouch) + setAcceptTouchEvents(true); +#endif +#if QT_CONFIG(cursor) + setCursor(Qt::ArrowCursor); +#endif +} + +QQuickScrollBarAttached *QQuickScrollBar::qmlAttachedProperties(QObject *object) +{ + return new QQuickScrollBarAttached(object); +} + +/*! + \qmlproperty real QtQuick.Controls::ScrollBar::size + + This property holds the size of the scroll bar, scaled to \c {0.0 - 1.0}. + + \sa {Flickable::visibleArea.heightRatio}{Flickable::visibleArea} + + This property is automatically set when the scroll bar is + \l {Attaching ScrollBar to a Flickable}{attached to a flickable}. + + \sa minimumSize, visualSize +*/ +qreal QQuickScrollBar::size() const +{ + Q_D(const QQuickScrollBar); + return d->size; +} + +void QQuickScrollBar::setSize(qreal size) +{ + Q_D(QQuickScrollBar); + if (!qt_is_finite(size) || qFuzzyCompare(d->size, size)) + return; + + auto oldVisualArea = d->visualArea(); + d->size = qBound(0.0, size, 1.0); + if (isComponentComplete()) + d->resizeContent(); + emit sizeChanged(); + d->visualAreaChange(d->visualArea(), oldVisualArea); +} + +/*! + \qmlproperty real QtQuick.Controls::ScrollBar::position + + This property holds the position of the scroll bar, scaled to \c {0.0 - 1.0}. + + \sa {Flickable::visibleArea.yPosition}{Flickable::visibleArea} + + This property is automatically set when the scroll bar is + \l {Attaching ScrollBar to a Flickable}{attached to a flickable}. + + \sa visualPosition +*/ +qreal QQuickScrollBar::position() const +{ + Q_D(const QQuickScrollBar); + return d->position; +} + +void QQuickScrollBar::setPosition(qreal position) +{ + Q_D(QQuickScrollBar); + if (!qt_is_finite(position) || qFuzzyCompare(d->position, position)) + return; + + auto oldVisualArea = d->visualArea(); + d->position = position; + if (isComponentComplete()) + d->resizeContent(); + emit positionChanged(); + d->visualAreaChange(d->visualArea(), oldVisualArea); +} + +/*! + \qmlproperty real QtQuick.Controls::ScrollBar::stepSize + + This property holds the step size. The default value is \c 0.0. + + \sa snapMode, increase(), decrease() +*/ +qreal QQuickScrollBar::stepSize() const +{ + Q_D(const QQuickScrollBar); + return d->stepSize; +} + +void QQuickScrollBar::setStepSize(qreal step) +{ + Q_D(QQuickScrollBar); + if (!qt_is_finite(step) || qFuzzyCompare(d->stepSize, step)) + return; + + d->stepSize = step; + emit stepSizeChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::ScrollBar::active + + This property holds whether the scroll bar is active, i.e. when it's \l pressed + or the attached Flickable is \l {Flickable::moving}{moving}. + + It is possible to keep \l {Binding the Active State of Horizontal and Vertical Scroll Bars} + {both horizontal and vertical bars visible} while scrolling in either direction. + + This property is automatically set when the scroll bar is + \l {Attaching ScrollBar to a Flickable}{attached to a flickable}. +*/ +bool QQuickScrollBar::isActive() const +{ + Q_D(const QQuickScrollBar); + return d->active; +} + +void QQuickScrollBar::setActive(bool active) +{ + Q_D(QQuickScrollBar); + if (d->active == active) + return; + + d->active = active; + emit activeChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::ScrollBar::pressed + + This property holds whether the scroll bar is pressed. +*/ +bool QQuickScrollBar::isPressed() const +{ + Q_D(const QQuickScrollBar); + return d->pressed; +} + +void QQuickScrollBar::setPressed(bool pressed) +{ + Q_D(QQuickScrollBar); + if (!pressed) { + if (QQuickIndicatorButton *button = decreaseVisual()) + button->setPressed(false); + if (QQuickIndicatorButton *button = increaseVisual()) + button->setPressed(false); + } + if (d->pressed == pressed) + return; + + d->pressed = pressed; + setAccessibleProperty("pressed", pressed); + d->updateActive(); + emit pressedChanged(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::ScrollBar::orientation + + This property holds the orientation of the scroll bar. + + Possible values: + \value Qt.Horizontal Horizontal + \value Qt.Vertical Vertical (default) + + This property is automatically set when the scroll bar is + \l {Attaching ScrollBar to a Flickable}{attached to a flickable}. + + \sa horizontal, vertical +*/ +Qt::Orientation QQuickScrollBar::orientation() const +{ + Q_D(const QQuickScrollBar); + return d->orientation; +} + +void QQuickScrollBar::setOrientation(Qt::Orientation orientation) +{ + Q_D(QQuickScrollBar); + if (d->orientation == orientation) + return; + + d->orientation = orientation; + if (isComponentComplete()) + d->resizeContent(); + emit orientationChanged(); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty enumeration QtQuick.Controls::ScrollBar::snapMode + + This property holds the snap mode. + + Possible values: + \value ScrollBar.NoSnap The scrollbar does not snap (default). + \value ScrollBar.SnapAlways The scrollbar snaps while dragged. + \value ScrollBar.SnapOnRelease The scrollbar does not snap while being dragged, but only after released. + + In the following table, the various modes are illustrated with animations. + The movement and the \l stepSize (\c 0.25) are identical in each animation. + + \table + \header + \row \li \b Value \li \b Example + \row \li \c ScrollBar.NoSnap \li \image qtquickcontrols2-scrollbar-nosnap.gif + \row \li \c ScrollBar.SnapAlways \li \image qtquickcontrols2-scrollbar-snapalways.gif + \row \li \c ScrollBar.SnapOnRelease \li \image qtquickcontrols2-scrollbar-snaponrelease.gif + \endtable + + \sa stepSize +*/ +QQuickScrollBar::SnapMode QQuickScrollBar::snapMode() const +{ + Q_D(const QQuickScrollBar); + return d->snapMode; +} + +void QQuickScrollBar::setSnapMode(SnapMode mode) +{ + Q_D(QQuickScrollBar); + if (d->snapMode == mode) + return; + + d->snapMode = mode; + emit snapModeChanged(); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty bool QtQuick.Controls::ScrollBar::interactive + + This property holds whether the scroll bar is interactive. The default value is \c true. + + A non-interactive scroll bar is visually and behaviorally similar to \l ScrollIndicator. + This property is useful for switching between typical mouse- and touch-orientated UIs + with interactive and non-interactive scroll bars, respectively. +*/ +bool QQuickScrollBar::isInteractive() const +{ + Q_D(const QQuickScrollBar); + return d->interactive; +} + +void QQuickScrollBar::setInteractive(bool interactive) +{ + Q_D(QQuickScrollBar); + d->explicitInteractive = true; + d->setInteractive(interactive); +} + +void QQuickScrollBar::resetInteractive() +{ + Q_D(QQuickScrollBar); + d->explicitInteractive = false; + d->setInteractive(true); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty enumeration QtQuick.Controls::ScrollBar::policy + + This property holds the policy of the scroll bar. The default policy is \c ScrollBar.AsNeeded. + + Possible values: + \value ScrollBar.AsNeeded The scroll bar is only shown when the content is too large to fit. + \value ScrollBar.AlwaysOff The scroll bar is never shown. + \value ScrollBar.AlwaysOn The scroll bar is always shown. + + The following example keeps the vertical scroll bar always visible: + + \snippet qtquickcontrols2-scrollbar-policy.qml 1 +*/ +QQuickScrollBar::Policy QQuickScrollBar::policy() const +{ + Q_D(const QQuickScrollBar); + return d->policy; +} + +void QQuickScrollBar::setPolicy(Policy policy) +{ + Q_D(QQuickScrollBar); + if (d->policy == policy) + return; + + d->policy = policy; + emit policyChanged(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::ScrollBar::horizontal + \readonly + + This property holds whether the scroll bar is horizontal. + + \sa orientation +*/ +bool QQuickScrollBar::isHorizontal() const +{ + Q_D(const QQuickScrollBar); + return d->orientation == Qt::Horizontal; +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::ScrollBar::vertical + \readonly + + This property holds whether the scroll bar is vertical. + + \sa orientation +*/ +bool QQuickScrollBar::isVertical() const +{ + Q_D(const QQuickScrollBar); + return d->orientation == Qt::Vertical; +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty real QtQuick.Controls::ScrollBar::minimumSize + + This property holds the minimum size of the scroll bar, scaled to \c {0.0 - 1.0}. + + \sa size, visualSize, visualPosition +*/ +qreal QQuickScrollBar::minimumSize() const +{ + Q_D(const QQuickScrollBar); + return d->minimumSize; +} + +void QQuickScrollBar::setMinimumSize(qreal minimumSize) +{ + Q_D(QQuickScrollBar); + if (!qt_is_finite(minimumSize) || qFuzzyCompare(d->minimumSize, minimumSize)) + return; + + auto oldVisualArea = d->visualArea(); + d->minimumSize = qBound(0.0, minimumSize, 1.0); + if (isComponentComplete()) + d->resizeContent(); + emit minimumSizeChanged(); + d->visualAreaChange(d->visualArea(), oldVisualArea); +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty real QtQuick.Controls::ScrollBar::visualSize + + This property holds the effective visual size of the scroll bar, + which may be limited by the \l {minimumSize}{minimum size}. + + \sa size, minimumSize +*/ +qreal QQuickScrollBar::visualSize() const +{ + Q_D(const QQuickScrollBar); + return d->visualArea().size; +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty real QtQuick.Controls::ScrollBar::visualPosition + + This property holds the effective visual position of the scroll bar, + which may be limited by the \l {minimumSize}{minimum size}. + + \sa position, minimumSize +*/ +qreal QQuickScrollBar::visualPosition() const +{ + Q_D(const QQuickScrollBar); + return d->visualArea().position; +} + +QQuickIndicatorButton *QQuickScrollBar::decreaseVisual() +{ + Q_D(QQuickScrollBar); + return d->decreaseVisual; +} + +QQuickIndicatorButton *QQuickScrollBar::increaseVisual() +{ + Q_D(QQuickScrollBar); + return d->increaseVisual; +} + +/*! + \qmlmethod void QtQuick.Controls::ScrollBar::increase() + + Increases the position by \l stepSize or \c 0.1 if stepSize is \c 0.0. + + \sa stepSize +*/ +void QQuickScrollBar::increase() +{ + Q_D(QQuickScrollBar); + qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; + bool wasActive = d->active; + setActive(true); + setPosition(qMin<qreal>(1.0 - d->size, d->position + step)); + setActive(wasActive); +} + +/*! + \qmlmethod void QtQuick.Controls::ScrollBar::decrease() + + Decreases the position by \l stepSize or \c 0.1 if stepSize is \c 0.0. + + \sa stepSize +*/ +void QQuickScrollBar::decrease() +{ + Q_D(QQuickScrollBar); + qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; + bool wasActive = d->active; + setActive(true); + setPosition(qMax<qreal>(0.0, d->position - step)); + setActive(wasActive); +} + +void QQuickScrollBar::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickScrollBar); + QQuickControl::mousePressEvent(event); + d->handleMove(event->position()); +} + +#if QT_CONFIG(quicktemplates2_hover) +void QQuickScrollBar::hoverChange() +{ + Q_D(QQuickScrollBar); + d->updateActive(); +} + +void QQuickScrollBar::hoverEnterEvent(QHoverEvent *event) +{ + Q_D(QQuickScrollBar); + QQuickControl::hoverEnterEvent(event); + d->updateHover(event->position()); + event->ignore(); +} + +void QQuickScrollBar::hoverMoveEvent(QHoverEvent *event) +{ + Q_D(QQuickScrollBar); + QQuickControl::hoverMoveEvent(event); + d->updateHover(event->position()); + event->ignore(); +} + +void QQuickScrollBar::hoverLeaveEvent(QHoverEvent *event) +{ + Q_D(QQuickScrollBar); + QQuickControl::hoverLeaveEvent(event); + + d->updateHover(QPoint(), false); //position is not needed when we force it to unhover + event->ignore(); +} +#endif + +void QQuickScrollBar::classBegin() +{ + Q_D(QQuickScrollBar); + QQuickControl::classBegin(); + + QQmlContext *context = qmlContext(this); + if (context) { + QQmlEngine::setContextForObject(d->decreaseVisual, context); + QQmlEngine::setContextForObject(d->increaseVisual, context); + } +} + +void QQuickScrollBar::componentComplete() +{ + Q_D(QQuickScrollBar); + QQuickIndicatorButtonPrivate::get(d->decreaseVisual)->executeIndicator(true); + QQuickIndicatorButtonPrivate::get(d->increaseVisual)->executeIndicator(true); + + QQuickControl::componentComplete(); +} + +#if QT_CONFIG(accessibility) +void QQuickScrollBar::accessibilityActiveChanged(bool active) +{ + QQuickControl::accessibilityActiveChanged(active); + + Q_D(QQuickScrollBar); + if (active) { + setAccessibleProperty("pressed", d->pressed); + + if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this)) { + connect(accessibleAttached, &QQuickAccessibleAttached::increaseAction, this, &QQuickScrollBar::increase); + connect(accessibleAttached, &QQuickAccessibleAttached::decreaseAction, this, &QQuickScrollBar::decrease); + } + } else { + if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this)) { + disconnect(accessibleAttached, &QQuickAccessibleAttached::increaseAction, this, &QQuickScrollBar::increase); + disconnect(accessibleAttached, &QQuickAccessibleAttached::decreaseAction, this, &QQuickScrollBar::decrease); + } + } +} + +QAccessible::Role QQuickScrollBar::accessibleRole() const +{ + return QAccessible::ScrollBar; +} +#endif + +void QQuickScrollBarAttachedPrivate::setFlickable(QQuickFlickable *item) +{ + if (flickable) { + // NOTE: Use removeItemChangeListener(Geometry) instead of updateOrRemoveGeometryChangeListener(Size). + // The latter doesn't remove the listener but only resets its types. Thus, it leaves behind a dangling + // pointer on destruction. + QQuickItemPrivate::get(flickable)->removeItemChangeListener(this, QQuickItemPrivate::Geometry); + QQuickItemPrivate::get(flickable)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed); + if (horizontal) + cleanupHorizontal(); + if (vertical) + cleanupVertical(); + } + + flickable = item; + + if (item) { + // Don't know how to combine these calls into one, and as long as they're separate calls, + // the remove* calls above need to be separate too, otherwise they will have no effect. + QQuickItemPrivate::get(item)->updateOrAddGeometryChangeListener(this, QQuickGeometryChange::Size); + QQuickItemPrivate::get(item)->updateOrAddItemChangeListener(this, QQuickItemPrivate::Destroyed); + if (horizontal) + initHorizontal(); + if (vertical) + initVertical(); + } +} + +void QQuickScrollBarAttachedPrivate::initHorizontal() +{ + Q_ASSERT(flickable && horizontal); + + connect(flickable, &QQuickFlickable::movingHorizontallyChanged, this, &QQuickScrollBarAttachedPrivate::activateHorizontal); + + // TODO: export QQuickFlickableVisibleArea + QObject *area = flickable->property("visibleArea").value<QObject *>(); + QObject::connect(area, SIGNAL(widthRatioChanged(qreal)), horizontal, SLOT(setSize(qreal))); + QObject::connect(area, SIGNAL(xPositionChanged(qreal)), horizontal, SLOT(setPosition(qreal))); + + // ensure that the ScrollBar is stacked above the Flickable in a ScrollView + QQuickItem *parent = horizontal->parentItem(); + if (parent && parent == flickable->parentItem()) + horizontal->stackAfter(flickable); + + // If a scroll bar was previously hidden (due to e.g. setting a new contentItem + // on a ScrollView), we need to make sure that we un-hide it. + if (auto control = qobject_cast<QQuickControl*>(q_func()->parent())) { + const auto visibility = horizontal->policy() != QQuickScrollBar::AlwaysOff + ? QQuickControlPrivate::UnhideVisibility::Show : QQuickControlPrivate::UnhideVisibility::Hide; + QQuickControlPrivate::unhideOldItem(control, horizontal, visibility); + } + + layoutHorizontal(); + horizontal->setSize(area->property("widthRatio").toReal()); + horizontal->setPosition(area->property("xPosition").toReal()); +} + +void QQuickScrollBarAttachedPrivate::initVertical() +{ + Q_ASSERT(flickable && vertical); + + connect(flickable, &QQuickFlickable::movingVerticallyChanged, this, &QQuickScrollBarAttachedPrivate::activateVertical); + + // TODO: export QQuickFlickableVisibleArea + QObject *area = flickable->property("visibleArea").value<QObject *>(); + QObject::connect(area, SIGNAL(heightRatioChanged(qreal)), vertical, SLOT(setSize(qreal))); + QObject::connect(area, SIGNAL(yPositionChanged(qreal)), vertical, SLOT(setPosition(qreal))); + + // ensure that the ScrollBar is stacked above the Flickable in a ScrollView + QQuickItem *parent = vertical->parentItem(); + if (parent && parent == flickable->parentItem()) + vertical->stackAfter(flickable); + + if (auto control = qobject_cast<QQuickControl*>(q_func()->parent())) { + const auto visibility = vertical->policy() != QQuickScrollBar::AlwaysOff + ? QQuickControlPrivate::UnhideVisibility::Show : QQuickControlPrivate::UnhideVisibility::Hide; + QQuickControlPrivate::unhideOldItem(control, vertical, visibility); + } + + layoutVertical(); + vertical->setSize(area->property("heightRatio").toReal()); + vertical->setPosition(area->property("yPosition").toReal()); +} + +void QQuickScrollBarAttachedPrivate::cleanupHorizontal() +{ + Q_ASSERT(flickable && horizontal); + + QQuickControlPrivate::hideOldItem(horizontal); + // ScrollBar.qml has a binding to visible and ScrollView.qml has a binding to parent. + // If we just set visible to false and parent to null, these bindings will overwrite + // them upon component completion as part of the binding evaluation. + // That's why we remove the binding completely. + const QQmlProperty visibleProperty(horizontal, QStringLiteral("visible")); + const QQmlProperty parentProperty(horizontal, QStringLiteral("parent")); + QQmlPropertyPrivate::removeBinding(visibleProperty); + QQmlPropertyPrivate::removeBinding(parentProperty); + + disconnect(flickable, &QQuickFlickable::movingHorizontallyChanged, this, &QQuickScrollBarAttachedPrivate::activateHorizontal); + + // TODO: export QQuickFlickableVisibleArea + QObject *area = flickable->property("visibleArea").value<QObject *>(); + QObject::disconnect(area, SIGNAL(widthRatioChanged(qreal)), horizontal, SLOT(setSize(qreal))); + QObject::disconnect(area, SIGNAL(xPositionChanged(qreal)), horizontal, SLOT(setPosition(qreal))); +} + +void QQuickScrollBarAttachedPrivate::cleanupVertical() +{ + Q_ASSERT(flickable && vertical); + + QQuickControlPrivate::hideOldItem(vertical); + const QQmlProperty visibleProperty(vertical, QStringLiteral("visible")); + const QQmlProperty parentProperty(vertical, QStringLiteral("parent")); + QQmlPropertyPrivate::removeBinding(visibleProperty); + QQmlPropertyPrivate::removeBinding(parentProperty); + + disconnect(flickable, &QQuickFlickable::movingVerticallyChanged, this, &QQuickScrollBarAttachedPrivate::activateVertical); + + // TODO: export QQuickFlickableVisibleArea + QObject *area = flickable->property("visibleArea").value<QObject *>(); + QObject::disconnect(area, SIGNAL(heightRatioChanged(qreal)), vertical, SLOT(setSize(qreal))); + QObject::disconnect(area, SIGNAL(yPositionChanged(qreal)), vertical, SLOT(setPosition(qreal))); +} + +void QQuickScrollBarAttachedPrivate::activateHorizontal() +{ + QQuickScrollBarPrivate *p = QQuickScrollBarPrivate::get(horizontal); + p->moving = flickable->isMovingHorizontally(); + p->updateActive(); +} + +void QQuickScrollBarAttachedPrivate::activateVertical() +{ + QQuickScrollBarPrivate *p = QQuickScrollBarPrivate::get(vertical); + p->moving = flickable->isMovingVertically(); + p->updateActive(); +} + +// TODO: QQuickFlickable::maxXYExtent() +class QQuickFriendlyFlickable : public QQuickFlickable +{ + friend class QQuickScrollBarAttachedPrivate; +}; + +void QQuickScrollBarAttachedPrivate::scrollHorizontal() +{ + if (!flickable) + return; + + QQuickFriendlyFlickable *f = reinterpret_cast<QQuickFriendlyFlickable *>(flickable); + + const qreal viewwidth = f->width(); + const qreal maxxextent = -f->maxXExtent() + f->minXExtent(); + const qreal cx = horizontal->position() * (maxxextent + viewwidth) - f->minXExtent(); + + if (!qIsNaN(cx) && !qFuzzyCompare(cx, flickable->contentX())) + flickable->setContentX(cx); +} + +void QQuickScrollBarAttachedPrivate::scrollVertical() +{ + if (!flickable) + return; + + QQuickFriendlyFlickable *f = reinterpret_cast<QQuickFriendlyFlickable *>(flickable); + + const qreal viewheight = f->height(); + const qreal maxyextent = -f->maxYExtent() + f->minYExtent(); + const qreal cy = vertical->position() * (maxyextent + viewheight) - f->minYExtent(); + + if (!qIsNaN(cy) && !qFuzzyCompare(cy, flickable->contentY())) + flickable->setContentY(cy); +} + +void QQuickScrollBarAttachedPrivate::mirrorVertical() +{ + layoutVertical(true); +} + +void QQuickScrollBarAttachedPrivate::layoutHorizontal(bool move) +{ + Q_ASSERT(horizontal && flickable); + if (horizontal->parentItem() != flickable) + return; + horizontal->setWidth(flickable->width()); + if (move) + horizontal->setY(flickable->height() - horizontal->height()); +} + +void QQuickScrollBarAttachedPrivate::layoutVertical(bool move) +{ + Q_ASSERT(vertical && flickable); + if (vertical->parentItem() != flickable) + return; + vertical->setHeight(flickable->height()); + if (move) + vertical->setX(vertical->isMirrored() ? 0 : flickable->width() - vertical->width()); +} + +void QQuickScrollBarAttachedPrivate::itemGeometryChanged(QQuickItem *item, const QQuickGeometryChange change, const QRectF &diff) +{ + Q_UNUSED(item); + Q_UNUSED(change); + if (horizontal && horizontal->height() > 0) { +#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry + bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), diff.height() - horizontal->height()); +#else + bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), item->height() - diff.height() - horizontal->height()); +#endif + if (flickable) + layoutHorizontal(move); + } + if (vertical && vertical->width() > 0) { +#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry + bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), diff.width() - vertical->width()); +#else + bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), item->width() - diff.width() - vertical->width()); +#endif + if (flickable) + layoutVertical(move); + } +} + +void QQuickScrollBarAttachedPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + if (item == vertical && flickable) + layoutVertical(true); +} + +void QQuickScrollBarAttachedPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + if (item == horizontal && flickable) + layoutHorizontal(true); +} + +void QQuickScrollBarAttachedPrivate::itemDestroyed(QQuickItem *item) +{ + if (item == flickable) + flickable = nullptr; + if (item == horizontal) + horizontal = nullptr; + if (item == vertical) + vertical = nullptr; +} + +QQuickScrollBarAttached::QQuickScrollBarAttached(QObject *parent) + : QObject(*(new QQuickScrollBarAttachedPrivate), parent) +{ + Q_D(QQuickScrollBarAttached); + d->setFlickable(qobject_cast<QQuickFlickable *>(parent)); + + if (parent && !d->flickable && !qobject_cast<QQuickScrollView *>(parent)) + qmlWarning(parent) << "ScrollBar must be attached to a Flickable or ScrollView"; +} + +QQuickScrollBarAttached::~QQuickScrollBarAttached() +{ + Q_D(QQuickScrollBarAttached); + if (d->horizontal) { + QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, horizontalChangeTypes); + d->horizontal = nullptr; + } + if (d->vertical) { + QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, verticalChangeTypes); + d->vertical = nullptr; + } + d->setFlickable(nullptr); +} + +/*! + \qmlattachedproperty ScrollBar QtQuick.Controls::ScrollBar::horizontal + + This property attaches a horizontal scroll bar to a \l Flickable. + + \code + Flickable { + contentWidth: 2000 + ScrollBar.horizontal: ScrollBar { } + } + \endcode + + \sa {Attaching ScrollBar to a Flickable} +*/ +QQuickScrollBar *QQuickScrollBarAttached::horizontal() const +{ + Q_D(const QQuickScrollBarAttached); + return d->horizontal; +} + +void QQuickScrollBarAttached::setHorizontal(QQuickScrollBar *horizontal) +{ + Q_D(QQuickScrollBarAttached); + if (d->horizontal == horizontal) + return; + + if (d->horizontal) { + QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, horizontalChangeTypes); + QObjectPrivate::disconnect(d->horizontal, &QQuickScrollBar::positionChanged, d, &QQuickScrollBarAttachedPrivate::scrollHorizontal); + + if (d->flickable) + d->cleanupHorizontal(); + } + + d->horizontal = horizontal; + + if (horizontal) { + if (!horizontal->parentItem()) + horizontal->setParentItem(qobject_cast<QQuickItem *>(parent())); + horizontal->setOrientation(Qt::Horizontal); + + QQuickItemPrivate::get(horizontal)->addItemChangeListener(d, horizontalChangeTypes); + QObjectPrivate::connect(horizontal, &QQuickScrollBar::positionChanged, d, &QQuickScrollBarAttachedPrivate::scrollHorizontal); + + if (d->flickable) + d->initHorizontal(); + } + emit horizontalChanged(); +} + +/*! + \qmlattachedproperty ScrollBar QtQuick.Controls::ScrollBar::vertical + + This property attaches a vertical scroll bar to a \l Flickable. + + \code + Flickable { + contentHeight: 2000 + ScrollBar.vertical: ScrollBar { } + } + \endcode + + \sa {Attaching ScrollBar to a Flickable} +*/ +QQuickScrollBar *QQuickScrollBarAttached::vertical() const +{ + Q_D(const QQuickScrollBarAttached); + return d->vertical; +} + +void QQuickScrollBarAttached::setVertical(QQuickScrollBar *vertical) +{ + Q_D(QQuickScrollBarAttached); + if (d->vertical == vertical) + return; + + if (d->vertical) { + QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, verticalChangeTypes); + QObjectPrivate::disconnect(d->vertical, &QQuickScrollBar::mirroredChanged, d, &QQuickScrollBarAttachedPrivate::mirrorVertical); + QObjectPrivate::disconnect(d->vertical, &QQuickScrollBar::positionChanged, d, &QQuickScrollBarAttachedPrivate::scrollVertical); + + if (d->flickable) + d->cleanupVertical(); + } + + d->vertical = vertical; + + if (vertical) { + if (!vertical->parentItem()) + vertical->setParentItem(qobject_cast<QQuickItem *>(parent())); + vertical->setOrientation(Qt::Vertical); + + QQuickItemPrivate::get(vertical)->addItemChangeListener(d, verticalChangeTypes); + QObjectPrivate::connect(vertical, &QQuickScrollBar::mirroredChanged, d, &QQuickScrollBarAttachedPrivate::mirrorVertical); + QObjectPrivate::connect(vertical, &QQuickScrollBar::positionChanged, d, &QQuickScrollBarAttachedPrivate::scrollVertical); + + if (d->flickable) + d->initVertical(); + } + emit verticalChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qquickscrollbar_p.cpp" diff --git a/src/quicktemplates2/qquickscrollbar_p.h b/src/quicktemplates2/qquickscrollbar_p.h new file mode 100644 index 00000000000..b7de290b240 --- /dev/null +++ b/src/quicktemplates2/qquickscrollbar_p.h @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSCROLLBAR_P_H +#define QQUICKSCROLLBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickindicatorbutton_p.h> +QT_BEGIN_NAMESPACE + +class QQuickScrollBarAttached; +class QQuickScrollBarPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickScrollBar : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(qreal size READ size WRITE setSize NOTIFY sizeChanged FINAL) + Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged FINAL) + Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged FINAL) + Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged FINAL) + Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL) + Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL) + // 2.2 (Qt 5.9) + Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged FINAL REVISION(2, 2)) + Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive RESET resetInteractive NOTIFY interactiveChanged FINAL REVISION(2, 2)) + Q_PROPERTY(Policy policy READ policy WRITE setPolicy NOTIFY policyChanged FINAL REVISION(2, 2)) + // 2.3 (Qt 5.10) + Q_PROPERTY(bool horizontal READ isHorizontal NOTIFY orientationChanged FINAL REVISION(2, 3)) + Q_PROPERTY(bool vertical READ isVertical NOTIFY orientationChanged FINAL REVISION(2, 3)) + // 2.4 (Qt 5.11) + Q_PROPERTY(qreal minimumSize READ minimumSize WRITE setMinimumSize NOTIFY minimumSizeChanged FINAL REVISION(2, 4)) + Q_PROPERTY(qreal visualSize READ visualSize NOTIFY visualSizeChanged FINAL REVISION(2, 4)) + Q_PROPERTY(qreal visualPosition READ visualPosition NOTIFY visualPositionChanged FINAL REVISION(2, 4)) + + Q_PROPERTY(QQuickIndicatorButton *__decreaseVisual READ decreaseVisual CONSTANT FINAL) + Q_PROPERTY(QQuickIndicatorButton *__increaseVisual READ increaseVisual CONSTANT FINAL) + + QML_NAMED_ELEMENT(ScrollBar) + QML_ATTACHED(QQuickScrollBarAttached) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickScrollBar(QQuickItem *parent = nullptr); + + static QQuickScrollBarAttached *qmlAttachedProperties(QObject *object); + + qreal size() const; + qreal position() const; + + qreal stepSize() const; + void setStepSize(qreal step); + + bool isActive() const; + void setActive(bool active); + + bool isPressed() const; + void setPressed(bool pressed); + + Qt::Orientation orientation() const; + void setOrientation(Qt::Orientation orientation); + + // 2.2 (Qt 5.9) + enum SnapMode { + NoSnap, + SnapAlways, + SnapOnRelease + }; + Q_ENUM(SnapMode) + + SnapMode snapMode() const; + void setSnapMode(SnapMode mode); + + bool isInteractive() const; + void setInteractive(bool interactive); + void resetInteractive(); + + enum Policy { + AsNeeded = Qt::ScrollBarAsNeeded, + AlwaysOff = Qt::ScrollBarAlwaysOff, + AlwaysOn = Qt::ScrollBarAlwaysOn + }; + Q_ENUM(Policy) + + Policy policy() const; + void setPolicy(Policy policy); + + // 2.3 (Qt 5.10) + bool isHorizontal() const; + bool isVertical() const; + + // 2.4 (Qt 5.11) + qreal minimumSize() const; + void setMinimumSize(qreal minimumSize); + + qreal visualSize() const; + qreal visualPosition() const; + + QQuickIndicatorButton *decreaseVisual(); + QQuickIndicatorButton *increaseVisual(); + +public Q_SLOTS: + void increase(); + void decrease(); + void setSize(qreal size); + void setPosition(qreal position); + +Q_SIGNALS: + void sizeChanged(); + void positionChanged(); + void stepSizeChanged(); + void activeChanged(); + void pressedChanged(); + void orientationChanged(); + // 2.2 (Qt 5.9) + Q_REVISION(2, 2) void snapModeChanged(); + Q_REVISION(2, 2) void interactiveChanged(); + Q_REVISION(2, 2) void policyChanged(); + // 2.4 (Qt 5.11) + Q_REVISION(2, 4) void minimumSizeChanged(); + Q_REVISION(2, 4) void visualSizeChanged(); + Q_REVISION(2, 4) void visualPositionChanged(); + +protected: + void mousePressEvent(QMouseEvent *event) override; + +#if QT_CONFIG(quicktemplates2_hover) + void hoverChange() override; + void hoverEnterEvent(QHoverEvent *event) override; + void hoverMoveEvent(QHoverEvent *event) override; + void hoverLeaveEvent(QHoverEvent *event) override; +#endif + + void classBegin() override; + void componentComplete() override; + +#if QT_CONFIG(accessibility) + void accessibilityActiveChanged(bool active) override; + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickScrollBar) + Q_DECLARE_PRIVATE(QQuickScrollBar) +}; + +class QQuickScrollBarAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickScrollBarAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickScrollBar *horizontal READ horizontal WRITE setHorizontal NOTIFY horizontalChanged FINAL) + Q_PROPERTY(QQuickScrollBar *vertical READ vertical WRITE setVertical NOTIFY verticalChanged FINAL) + +public: + explicit QQuickScrollBarAttached(QObject *parent = nullptr); + ~QQuickScrollBarAttached(); + + QQuickScrollBar *horizontal() const; + void setHorizontal(QQuickScrollBar *horizontal); + + QQuickScrollBar *vertical() const; + void setVertical(QQuickScrollBar *vertical); + +Q_SIGNALS: + void horizontalChanged(); + void verticalChanged(); + +private: + Q_DISABLE_COPY(QQuickScrollBarAttached) + Q_DECLARE_PRIVATE(QQuickScrollBarAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickScrollBar) +QML_DECLARE_TYPEINFO(QQuickScrollBar, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKSCROLLBAR_P_H diff --git a/src/quicktemplates2/qquickscrollbar_p_p.h b/src/quicktemplates2/qquickscrollbar_p_p.h new file mode 100644 index 00000000000..70da611f0e7 --- /dev/null +++ b/src/quicktemplates2/qquickscrollbar_p_p.h @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSCROLLBAR_P_P_H +#define QQUICKSCROLLBAR_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickscrollbar_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickFlickable; +class QQuickIndicatorButton; + +class QQuickScrollBarPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickScrollBar) + +public: + static QQuickScrollBarPrivate *get(QQuickScrollBar *bar) + { + return bar->d_func(); + } + + struct VisualArea + { + VisualArea(qreal pos, qreal sz) + : position(pos), size(sz) { } + qreal position = 0; + qreal size = 0; + }; + VisualArea visualArea() const; + + qreal logicalPosition(qreal position) const; + + qreal snapPosition(qreal position) const; + qreal positionAt(const QPointF &point) const; + void setInteractive(bool interactive); + void updateActive(); + void resizeContent() override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + void handlePress(const QPointF &point) override; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + void handleUngrab() override; + + void visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea); + + void updateHover(const QPointF &pos, std::optional<bool> newHoverState = {}); + + QQuickIndicatorButton *decreaseVisual = nullptr; + QQuickIndicatorButton *increaseVisual = nullptr; + qreal size = 0; + qreal position = 0; + qreal stepSize = 0; + qreal offset = 0; + qreal minimumSize = 0; + bool active = false; + bool pressed = false; + bool moving = false; + bool interactive = true; + bool explicitInteractive = false; + Qt::Orientation orientation = Qt::Vertical; + QQuickScrollBar::SnapMode snapMode = QQuickScrollBar::NoSnap; + QQuickScrollBar::Policy policy = QQuickScrollBar::AsNeeded; +}; + +class QQuickScrollBarAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener +{ + Q_DECLARE_PUBLIC(QQuickScrollBarAttached) + +public: + static QQuickScrollBarAttachedPrivate *get(QQuickScrollBarAttached *attached) + { + return attached->d_func(); + } + + void setFlickable(QQuickFlickable *flickable); + + void initHorizontal(); + void initVertical(); + void cleanupHorizontal(); + void cleanupVertical(); + void activateHorizontal(); + void activateVertical(); + void scrollHorizontal(); + void scrollVertical(); + void mirrorVertical(); + + void layoutHorizontal(bool move = true); + void layoutVertical(bool move = true); + + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + void itemDestroyed(QQuickItem *item) override; + + QQuickFlickable *flickable = nullptr; + QQuickScrollBar *horizontal = nullptr; + QQuickScrollBar *vertical = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSCROLLBAR_P_P_H diff --git a/src/quicktemplates2/qquickscrollindicator.cpp b/src/quicktemplates2/qquickscrollindicator.cpp new file mode 100644 index 00000000000..1e7efc6bded --- /dev/null +++ b/src/quicktemplates2/qquickscrollindicator.cpp @@ -0,0 +1,667 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickscrollindicator_p.h" +#include "qquickcontrol_p_p.h" + +#include <QtQml/qqmlinfo.h> +#include <QtQuick/private/qquickflickable_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ScrollIndicator + \inherits Control +//! \instantiates QQuickScrollIndicator + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-indicators + \brief Vertical or horizontal non-interactive scroll indicator. + + \image qtquickcontrols2-scrollindicator.gif + + ScrollIndicator is a non-interactive indicator that indicates the current scroll + position. A scroll indicator can be either \l vertical or \l horizontal, and can + be attached to any \l Flickable, such as \l ListView and \l GridView. + + \code + Flickable { + // ... + ScrollIndicator.vertical: ScrollIndicator { } + } + \endcode + + \section1 Attaching ScrollIndicator to a Flickable + + \note When ScrollIndicator is attached \l {ScrollIndicator::vertical}{vertically} + or \l {ScrollIndicator::horizontal}{horizontally} to a Flickable, its geometry and + the following properties are automatically set and updated as appropriate: + + \list + \li \l orientation + \li \l position + \li \l size + \li \l active + \endlist + + An attached ScrollIndicator re-parents itself to the target Flickable. A vertically + attached ScrollIndicator resizes itself to the height of the Flickable, and positions + itself to either side of it based on the \l {Control::mirrored}{layout direction}. + A horizontally attached ScrollIndicator resizes itself to the width of the Flickable, + and positions itself to the bottom. The automatic geometry management can be disabled + by specifying another parent for the attached ScrollIndicator. This can be useful, for + example, if the ScrollIndicator should be placed outside a clipping Flickable. This is + demonstrated by the following example: + + \code + Flickable { + id: flickable + clip: true + // ... + ScrollIndicator.vertical: ScrollIndicator { + parent: flickable.parent + anchors.top: flickable.top + anchors.left: flickable.right + anchors.bottom: flickable.bottom + } + } + \endcode + + \section1 Binding the Active State of Horizontal and Vertical Scroll Indicators + + Horizontal and vertical scroll indicators do not share the \l active state with + each other by default. In order to keep both indicators visible whilst scrolling + to either direction, establish a two-way binding between the active states as + presented by the following example: + + \snippet qtquickcontrols2-scrollindicator-active.qml 1 + + \section1 Non-attached Scroll Indicators + + It is possible to create an instance of ScrollIndicator without using the + attached property API. This is useful when the behavior of the attached + scoll indicator is not sufficient or a \l Flickable is not in use. In the + following example, horizontal and vertical scroll indicators are used to + indicate how far the user has scrolled over the text (using \l MouseArea + instead of \l Flickable): + + \snippet qtquickcontrols2-scrollindicator-non-attached.qml 1 + + \image qtquickcontrols2-scrollindicator-non-attached.png + + \sa ScrollBar, {Customizing ScrollIndicator}, {Indicator Controls} +*/ + +static const QQuickItemPrivate::ChangeTypes changeTypes = QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed; +static const QQuickItemPrivate::ChangeTypes horizontalChangeTypes = changeTypes | QQuickItemPrivate::ImplicitHeight; +static const QQuickItemPrivate::ChangeTypes verticalChangeTypes = changeTypes | QQuickItemPrivate::ImplicitWidth; + +class QQuickScrollIndicatorPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickScrollIndicator) + +public: + struct VisualArea + { + VisualArea(qreal pos, qreal sz) + : position(pos), size(sz) { } + qreal position = 0; + qreal size = 0; + }; + VisualArea visualArea() const; + void visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea); + + void resizeContent() override; + + qreal size = 0; + qreal minimumSize = 0; + qreal position = 0; + bool active = false; + Qt::Orientation orientation = Qt::Vertical; +}; + +QQuickScrollIndicatorPrivate::VisualArea QQuickScrollIndicatorPrivate::visualArea() const +{ + qreal visualPos = position; + if (minimumSize > size) + visualPos = position / (1.0 - size) * (1.0 - minimumSize); + + qreal visualSize = qBound<qreal>(0, qMax(size, minimumSize) + qMin<qreal>(0, visualPos), 1.0 - visualPos); + + visualPos = qBound<qreal>(0, visualPos, 1.0 - visualSize); + + return VisualArea(visualPos, visualSize); +} + +void QQuickScrollIndicatorPrivate::visualAreaChange(const VisualArea &newVisualArea, const VisualArea &oldVisualArea) +{ + Q_Q(QQuickScrollIndicator); + if (!qFuzzyCompare(newVisualArea.size, oldVisualArea.size)) + emit q->visualSizeChanged(); + if (!qFuzzyCompare(newVisualArea.position, oldVisualArea.position)) + emit q->visualPositionChanged(); +} + +void QQuickScrollIndicatorPrivate::resizeContent() +{ + Q_Q(QQuickScrollIndicator); + if (!contentItem) + return; + + // - negative overshoot (pos < 0): clamp the pos to 0, and deduct the overshoot from the size + // - positive overshoot (pos + size > 1): clamp the size to 1-pos + const VisualArea visual = visualArea(); + + if (orientation == Qt::Horizontal) { + contentItem->setPosition(QPointF(q->leftPadding() + visual.position * q->availableWidth(), q->topPadding())); + contentItem->setSize(QSizeF(q->availableWidth() * visual.size, q->availableHeight())); + } else { + contentItem->setPosition(QPointF(q->leftPadding(), q->topPadding() + visual.position * q->availableHeight())); + contentItem->setSize(QSizeF(q->availableWidth(), q->availableHeight() * visual.size)); + } +} + +QQuickScrollIndicator::QQuickScrollIndicator(QQuickItem *parent) + : QQuickControl(*(new QQuickScrollIndicatorPrivate), parent) +{ +} + +QQuickScrollIndicatorAttached *QQuickScrollIndicator::qmlAttachedProperties(QObject *object) +{ + return new QQuickScrollIndicatorAttached(object); +} + +/*! + \qmlproperty real QtQuick.Controls::ScrollIndicator::size + + This property holds the size of the indicator, scaled to \c {0.0 - 1.0}. + + \sa {Flickable::visibleArea.heightRatio}{Flickable::visibleArea} + + This property is automatically set when the scroll indicator is + \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}. + + \sa minimumSize, visualSize +*/ +qreal QQuickScrollIndicator::size() const +{ + Q_D(const QQuickScrollIndicator); + return d->size; +} + +void QQuickScrollIndicator::setSize(qreal size) +{ + Q_D(QQuickScrollIndicator); + if (qFuzzyCompare(d->size, size)) + return; + + auto oldVisualArea = d->visualArea(); + d->size = size; + if (isComponentComplete()) + d->resizeContent(); + emit sizeChanged(); + d->visualAreaChange(d->visualArea(), oldVisualArea); +} + +/*! + \qmlproperty real QtQuick.Controls::ScrollIndicator::position + + This property holds the position of the indicator, scaled to \c {0.0 - 1.0}. + + This property is automatically set when the scroll indicator is + \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}. + + \sa {Flickable::visibleArea.yPosition}{Flickable::visibleArea}, visualPosition +*/ +qreal QQuickScrollIndicator::position() const +{ + Q_D(const QQuickScrollIndicator); + return d->position; +} + +void QQuickScrollIndicator::setPosition(qreal position) +{ + Q_D(QQuickScrollIndicator); + if (qFuzzyCompare(d->position, position)) + return; + + auto oldVisualArea = d->visualArea(); + d->position = position; + if (isComponentComplete()) + d->resizeContent(); + emit positionChanged(); + d->visualAreaChange(d->visualArea(), oldVisualArea); +} + +/*! + \qmlproperty bool QtQuick.Controls::ScrollIndicator::active + + This property holds whether the indicator is active, that is, when the + attached Flickable is \l {Flickable::moving}{moving}. + + It is possible to keep \l {Binding the Active State of Horizontal and Vertical Scroll Indicators} + {both horizontal and vertical indicators visible} while scrolling in either direction. + + This property is automatically set when the scroll indicator is + \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}. +*/ +bool QQuickScrollIndicator::isActive() const +{ + Q_D(const QQuickScrollIndicator); + return d->active; +} + +void QQuickScrollIndicator::setActive(bool active) +{ + Q_D(QQuickScrollIndicator); + if (d->active == active) + return; + + d->active = active; + emit activeChanged(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::ScrollIndicator::orientation + + This property holds the orientation of the indicator. + + Possible values: + \value Qt.Horizontal Horizontal + \value Qt.Vertical Vertical (default) + + This property is automatically set when the scroll indicator is + \l {Attaching ScrollIndicator to a Flickable}{attached to a flickable}. + + \sa horizontal, vertical +*/ +Qt::Orientation QQuickScrollIndicator::orientation() const +{ + Q_D(const QQuickScrollIndicator); + return d->orientation; +} + +void QQuickScrollIndicator::setOrientation(Qt::Orientation orientation) +{ + Q_D(QQuickScrollIndicator); + if (d->orientation == orientation) + return; + + d->orientation = orientation; + if (isComponentComplete()) + d->resizeContent(); + emit orientationChanged(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::ScrollIndicator::horizontal + \readonly + + This property holds whether the scroll indicator is horizontal. + + \sa orientation +*/ +bool QQuickScrollIndicator::isHorizontal() const +{ + Q_D(const QQuickScrollIndicator); + return d->orientation == Qt::Horizontal; +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::ScrollIndicator::vertical + \readonly + + This property holds whether the scroll indicator is vertical. + + \sa orientation +*/ +bool QQuickScrollIndicator::isVertical() const +{ + Q_D(const QQuickScrollIndicator); + return d->orientation == Qt::Vertical; +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty real QtQuick.Controls::ScrollIndicator::minimumSize + + This property holds the minimum size of the indicator, scaled to \c {0.0 - 1.0}. + + \sa size, visualSize, visualPosition +*/ +qreal QQuickScrollIndicator::minimumSize() const +{ + Q_D(const QQuickScrollIndicator); + return d->minimumSize; +} + +void QQuickScrollIndicator::setMinimumSize(qreal minimumSize) +{ + Q_D(QQuickScrollIndicator); + if (qFuzzyCompare(d->minimumSize, minimumSize)) + return; + + auto oldVisualArea = d->visualArea(); + d->minimumSize = minimumSize; + if (isComponentComplete()) + d->resizeContent(); + emit minimumSizeChanged(); + d->visualAreaChange(d->visualArea(), oldVisualArea); +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty real QtQuick.Controls::ScrollIndicator::visualSize + + This property holds the effective visual size of the indicator, + which may be limited by the \l {minimumSize}{minimum size}. + + \sa size, minimumSize +*/ +qreal QQuickScrollIndicator::visualSize() const +{ + Q_D(const QQuickScrollIndicator); + return d->visualArea().size; +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty real QtQuick.Controls::ScrollIndicator::visualPosition + + This property holds the effective visual position of the indicator, + which may be limited by the \l {minimumSize}{minimum size}. + + \sa position, minimumSize +*/ +qreal QQuickScrollIndicator::visualPosition() const +{ + Q_D(const QQuickScrollIndicator); + return d->visualArea().position; +} + +class QQuickScrollIndicatorAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener +{ +public: + void activateHorizontal(); + void activateVertical(); + + void layoutHorizontal(bool move = true); + void layoutVertical(bool move = true); + + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + void itemDestroyed(QQuickItem *item) override; + + QQuickFlickable *flickable = nullptr; + QQuickScrollIndicator *horizontal = nullptr; + QQuickScrollIndicator *vertical = nullptr; +}; + +void QQuickScrollIndicatorAttachedPrivate::activateHorizontal() +{ + horizontal->setActive(flickable->isMovingHorizontally()); +} + +void QQuickScrollIndicatorAttachedPrivate::activateVertical() +{ + vertical->setActive(flickable->isMovingVertically()); +} + +void QQuickScrollIndicatorAttachedPrivate::layoutHorizontal(bool move) +{ + Q_ASSERT(horizontal && flickable); + if (horizontal->parentItem() != flickable) + return; + horizontal->setWidth(flickable->width()); + if (move) + horizontal->setY(flickable->height() - horizontal->height()); +} + +void QQuickScrollIndicatorAttachedPrivate::layoutVertical(bool move) +{ + Q_ASSERT(vertical && flickable); + if (vertical->parentItem() != flickable) + return; + vertical->setHeight(flickable->height()); + if (move && !QQuickItemPrivate::get(vertical)->isMirrored()) + vertical->setX(flickable->width() - vertical->width()); +} + +void QQuickScrollIndicatorAttachedPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) +{ + Q_UNUSED(item); + Q_UNUSED(change); + if (horizontal && horizontal->height() > 0) { +#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry + bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), diff.height() - horizontal->height()); +#else + bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), item->height() - diff.height() - horizontal->height()); +#endif + layoutHorizontal(move); + } + if (vertical && vertical->width() > 0) { +#ifdef QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING // TODO: correct/rename diff to oldGeometry + bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), diff.width() - vertical->width()); +#else + bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), item->width() - diff.width() - vertical->width()); +#endif + layoutVertical(move); + } +} + +void QQuickScrollIndicatorAttachedPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + if (item == vertical) + layoutVertical(true); +} + +void QQuickScrollIndicatorAttachedPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + if (item == horizontal) + layoutHorizontal(true); +} + +void QQuickScrollIndicatorAttachedPrivate::itemDestroyed(QQuickItem *item) +{ + if (item == horizontal) + horizontal = nullptr; + if (item == vertical) + vertical = nullptr; +} + +QQuickScrollIndicatorAttached::QQuickScrollIndicatorAttached(QObject *parent) + : QObject(*(new QQuickScrollIndicatorAttachedPrivate), parent) +{ + Q_D(QQuickScrollIndicatorAttached); + d->flickable = qobject_cast<QQuickFlickable *>(parent); + if (d->flickable) + QQuickItemPrivate::get(d->flickable)->updateOrAddGeometryChangeListener(d, QQuickGeometryChange::Size); + else if (parent) + qmlWarning(parent) << "ScrollIndicator must be attached to a Flickable"; +} + +QQuickScrollIndicatorAttached::~QQuickScrollIndicatorAttached() +{ + Q_D(QQuickScrollIndicatorAttached); + if (d->flickable) { + if (d->horizontal) + QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, horizontalChangeTypes); + if (d->vertical) + QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d,verticalChangeTypes); + // NOTE: Use removeItemChangeListener(Geometry) instead of updateOrRemoveGeometryChangeListener(Size). + // The latter doesn't remove the listener but only resets its types. Thus, it leaves behind a dangling + // pointer on destruction. + QQuickItemPrivate::get(d->flickable)->removeItemChangeListener(d, QQuickItemPrivate::Geometry); + } +} + +/*! + \qmlattachedproperty ScrollIndicator QtQuick.Controls::ScrollIndicator::horizontal + + This property attaches a horizontal scroll indicator to a \l Flickable. + + \code + Flickable { + contentWidth: 2000 + ScrollIndicator.horizontal: ScrollIndicator { } + } + \endcode + + \sa {Attaching ScrollIndicator to a Flickable} +*/ +QQuickScrollIndicator *QQuickScrollIndicatorAttached::horizontal() const +{ + Q_D(const QQuickScrollIndicatorAttached); + return d->horizontal; +} + +void QQuickScrollIndicatorAttached::setHorizontal(QQuickScrollIndicator *horizontal) +{ + Q_D(QQuickScrollIndicatorAttached); + if (d->horizontal == horizontal) + return; + + if (d->horizontal && d->flickable) { + QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, horizontalChangeTypes); + QObjectPrivate::disconnect(d->flickable, &QQuickFlickable::movingHorizontallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateHorizontal); + + // TODO: export QQuickFlickableVisibleArea + QObject *area = d->flickable->property("visibleArea").value<QObject *>(); + disconnect(area, SIGNAL(widthRatioChanged(qreal)), d->horizontal, SLOT(setSize(qreal))); + disconnect(area, SIGNAL(xPositionChanged(qreal)), d->horizontal, SLOT(setPosition(qreal))); + } + + d->horizontal = horizontal; + + if (horizontal && d->flickable) { + if (!horizontal->parentItem()) + horizontal->setParentItem(d->flickable); + horizontal->setOrientation(Qt::Horizontal); + + QQuickItemPrivate::get(horizontal)->addItemChangeListener(d, horizontalChangeTypes); + QObjectPrivate::connect(d->flickable, &QQuickFlickable::movingHorizontallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateHorizontal); + + // TODO: export QQuickFlickableVisibleArea + QObject *area = d->flickable->property("visibleArea").value<QObject *>(); + connect(area, SIGNAL(widthRatioChanged(qreal)), horizontal, SLOT(setSize(qreal))); + connect(area, SIGNAL(xPositionChanged(qreal)), horizontal, SLOT(setPosition(qreal))); + + d->layoutHorizontal(); + horizontal->setSize(area->property("widthRatio").toReal()); + horizontal->setPosition(area->property("xPosition").toReal()); + } + emit horizontalChanged(); +} + +/*! + \qmlattachedproperty ScrollIndicator QtQuick.Controls::ScrollIndicator::vertical + + This property attaches a vertical scroll indicator to a \l Flickable. + + \code + Flickable { + contentHeight: 2000 + ScrollIndicator.vertical: ScrollIndicator { } + } + \endcode + + \sa {Attaching ScrollIndicator to a Flickable} +*/ +QQuickScrollIndicator *QQuickScrollIndicatorAttached::vertical() const +{ + Q_D(const QQuickScrollIndicatorAttached); + return d->vertical; +} + +void QQuickScrollIndicatorAttached::setVertical(QQuickScrollIndicator *vertical) +{ + Q_D(QQuickScrollIndicatorAttached); + if (d->vertical == vertical) + return; + + if (d->vertical && d->flickable) { + QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, verticalChangeTypes); + QObjectPrivate::disconnect(d->flickable, &QQuickFlickable::movingVerticallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateVertical); + + // TODO: export QQuickFlickableVisibleArea + QObject *area = d->flickable->property("visibleArea").value<QObject *>(); + disconnect(area, SIGNAL(heightRatioChanged(qreal)), d->vertical, SLOT(setSize(qreal))); + disconnect(area, SIGNAL(yPositionChanged(qreal)), d->vertical, SLOT(setPosition(qreal))); + } + + d->vertical = vertical; + + if (vertical && d->flickable) { + if (!vertical->parentItem()) + vertical->setParentItem(d->flickable); + vertical->setOrientation(Qt::Vertical); + + QQuickItemPrivate::get(vertical)->addItemChangeListener(d, verticalChangeTypes); + QObjectPrivate::connect(d->flickable, &QQuickFlickable::movingVerticallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateVertical); + + // TODO: export QQuickFlickableVisibleArea + QObject *area = d->flickable->property("visibleArea").value<QObject *>(); + connect(area, SIGNAL(heightRatioChanged(qreal)), vertical, SLOT(setSize(qreal))); + connect(area, SIGNAL(yPositionChanged(qreal)), vertical, SLOT(setPosition(qreal))); + + d->layoutVertical(); + vertical->setSize(area->property("heightRatio").toReal()); + vertical->setPosition(area->property("yPosition").toReal()); + } + emit verticalChanged(); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickScrollIndicator::touchEvent(QTouchEvent *event) +{ + event->ignore(); // QTBUG-61785 +} +#endif + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickScrollIndicator::accessibleRole() const +{ + return QAccessible::Indicator; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickscrollindicator_p.cpp" diff --git a/src/quicktemplates2/qquickscrollindicator_p.h b/src/quicktemplates2/qquickscrollindicator_p.h new file mode 100644 index 00000000000..dbad6ffe43c --- /dev/null +++ b/src/quicktemplates2/qquickscrollindicator_p.h @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSCROLLINDICATOR_P_H +#define QQUICKSCROLLINDICATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickFlickable; +class QQuickScrollIndicatorAttached; +class QQuickScrollIndicatorPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickScrollIndicator : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(qreal size READ size WRITE setSize NOTIFY sizeChanged FINAL) + Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged FINAL) + Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged FINAL) + Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL) + // 2.3 (Qt 5.10) + Q_PROPERTY(bool horizontal READ isHorizontal NOTIFY orientationChanged FINAL REVISION(2, 3)) + Q_PROPERTY(bool vertical READ isVertical NOTIFY orientationChanged FINAL REVISION(2, 3)) + // 2.4 (Qt 5.11) + Q_PROPERTY(qreal minimumSize READ minimumSize WRITE setMinimumSize NOTIFY minimumSizeChanged FINAL REVISION(2, 4)) + Q_PROPERTY(qreal visualSize READ visualSize NOTIFY visualSizeChanged FINAL REVISION(2, 4)) + Q_PROPERTY(qreal visualPosition READ visualPosition NOTIFY visualPositionChanged FINAL REVISION(2, 4)) + QML_NAMED_ELEMENT(ScrollIndicator) + QML_ATTACHED(QQuickScrollIndicatorAttached) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickScrollIndicator(QQuickItem *parent = nullptr); + + static QQuickScrollIndicatorAttached *qmlAttachedProperties(QObject *object); + + qreal size() const; + qreal position() const; + + bool isActive() const; + void setActive(bool active); + + Qt::Orientation orientation() const; + void setOrientation(Qt::Orientation orientation); + + // 2.3 (Qt 5.10) + bool isHorizontal() const; + bool isVertical() const; + + // 2.4 (Qt 5.11) + qreal minimumSize() const; + void setMinimumSize(qreal minimumSize); + + qreal visualSize() const; + qreal visualPosition() const; + +public Q_SLOTS: + void setSize(qreal size); + void setPosition(qreal position); + +Q_SIGNALS: + void sizeChanged(); + void positionChanged(); + void activeChanged(); + void orientationChanged(); + // 2.4 (Qt 5.11) + Q_REVISION(2, 4) void minimumSizeChanged(); + Q_REVISION(2, 4) void visualSizeChanged(); + Q_REVISION(2, 4) void visualPositionChanged(); + +protected: +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickScrollIndicator) + Q_DECLARE_PRIVATE(QQuickScrollIndicator) +}; + +class QQuickScrollIndicatorAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickScrollIndicatorAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickScrollIndicator *horizontal READ horizontal WRITE setHorizontal NOTIFY horizontalChanged FINAL) + Q_PROPERTY(QQuickScrollIndicator *vertical READ vertical WRITE setVertical NOTIFY verticalChanged FINAL) + +public: + explicit QQuickScrollIndicatorAttached(QObject *parent = nullptr); + ~QQuickScrollIndicatorAttached(); + + QQuickScrollIndicator *horizontal() const; + void setHorizontal(QQuickScrollIndicator *horizontal); + + QQuickScrollIndicator *vertical() const; + void setVertical(QQuickScrollIndicator *vertical); + +Q_SIGNALS: + void horizontalChanged(); + void verticalChanged(); + +private: + Q_DISABLE_COPY(QQuickScrollIndicatorAttached) + Q_DECLARE_PRIVATE(QQuickScrollIndicatorAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickScrollIndicator) +QML_DECLARE_TYPEINFO(QQuickScrollIndicator, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKSCROLLINDICATOR_P_H diff --git a/src/quicktemplates2/qquickscrollview.cpp b/src/quicktemplates2/qquickscrollview.cpp new file mode 100644 index 00000000000..1a758a8dfa7 --- /dev/null +++ b/src/quicktemplates2/qquickscrollview.cpp @@ -0,0 +1,648 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickscrollview_p.h" +#include "qquickpane_p_p.h" +#include "qquickscrollbar_p_p.h" + +#include <QtQuick/private/qquickflickable_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ScrollView + \inherits Pane +//! \instantiates QQuickScrollView + \inqmlmodule QtQuick.Controls + \since 5.9 + \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes + \brief Scrollable view. + + ScrollView provides scrolling for user-defined content. It can be used to + either replace a \l Flickable, or to decorate an existing one. + + \image qtquickcontrols2-scrollview.png + + The first example demonstrates the simplest usage of ScrollView. + + \snippet qtquickcontrols2-scrollview.qml file + + The second example illustrates using an existing \l Flickable, that is, + a \l ListView. + + \snippet qtquickcontrols2-scrollview-listview.qml file + + \note As of Qt-6.0, ScrollView automatically clips its contents if you + don't use a Flickable as a child. If this is not wanted, you can + set your own Flickable as a child, and control the \l {Item::}{clip} + property on the Flickable explicitly. + + \section2 Sizing + + As with Flickable, there are several things to keep in mind when using + ScrollView: + \list + \li If only a single item is used within a ScrollView, the content size is + automatically calculated based on the implicit size of its contained item. + However, if more than one item is used (or an implicit size is not + provided), the \l {QtQuick.Controls::Pane::}{contentWidth} and + \l {QtQuick.Controls::Pane::}{contentHeight} properties must + be set to the combined size of its contained items. + \li If the content size is less than or equal to the size of the ScrollView, + it will not be scrollable. + \li If you want the ScrollView to only scroll vertically, you can bind + \l {QtQuick.Controls::Pane::}{contentWidth} to + \l {QtQuick.Controls::Control::}{availableWidth} + (and vice versa for contentHeight). This will let the contents fill + out all the available space horizontally inside the ScrollView, taking + any padding or scroll bars into account. + \endlist + + \section2 Scroll Bars + + The horizontal and vertical scroll bars can be accessed and customized using + the \l {ScrollBar::horizontal}{ScrollBar.horizontal} and \l {ScrollBar::vertical} + {ScrollBar.vertical} attached properties. The following example adjusts the scroll + bar policies so that the horizontal scroll bar is always off, and the vertical + scroll bar is always on. + + \snippet qtquickcontrols2-scrollview-policy.qml file + + \section2 Touch vs. Mouse Interaction + + On touch, ScrollView enables flicking and makes the scroll bars non-interactive. + + \image qtquickcontrols2-scrollindicator.gif + + When interacted with a mouse device, flicking is disabled and the scroll bars + are interactive. + + \image qtquickcontrols2-scrollbar.gif + + Scroll bars can be made interactive on touch, or non-interactive when interacted + with a mouse device, by setting the \l {ScrollBar::}{interactive} property explicitly + to \c true or \c false, respectively. + + \snippet qtquickcontrols2-scrollview-interactive.qml file + + \sa ScrollBar, ScrollIndicator, {Customizing ScrollView}, {Container Controls}, + {Focus Management in Qt Quick Controls} +*/ + +class QQuickScrollViewPrivate : public QQuickPanePrivate +{ + Q_DECLARE_PUBLIC(QQuickScrollView) + +public: + QQmlListProperty<QObject> contentData() override; + QQmlListProperty<QQuickItem> contentChildren() override; + QList<QQuickItem *> contentChildItems() const override; + + QQuickItem *getContentItem() override; + + QQuickFlickable *ensureFlickable(bool content); + bool setFlickable(QQuickFlickable *flickable, bool content); + + void flickableContentWidthChanged(); + void flickableContentHeightChanged(); + + qreal getContentWidth() const override; + qreal getContentHeight() const override; + + QQuickScrollBar *verticalScrollBar() const; + QQuickScrollBar *horizontalScrollBar() const; + + void setScrollBarsInteractive(bool interactive); + + static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj); + static qsizetype contentData_count(QQmlListProperty<QObject> *prop); + static QObject *contentData_at(QQmlListProperty<QObject> *prop, qsizetype index); + static void contentData_clear(QQmlListProperty<QObject> *prop); + + static void contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *obj); + static qsizetype contentChildren_count(QQmlListProperty<QQuickItem> *prop); + static QQuickItem *contentChildren_at(QQmlListProperty<QQuickItem> *prop, qsizetype index); + static void contentChildren_clear(QQmlListProperty<QQuickItem> *prop); + + void itemImplicitWidthChanged(QQuickItem *item) override; + + bool wasTouched = false; + QQuickFlickable *flickable = nullptr; + bool flickableHasExplicitContentWidth = true; + bool flickableHasExplicitContentHeight = true; +}; + +QList<QQuickItem *> QQuickScrollViewPrivate::contentChildItems() const +{ + if (!flickable) + return QList<QQuickItem *>(); + + return flickable->contentItem()->childItems(); +} + +QQuickItem *QQuickScrollViewPrivate::getContentItem() +{ + if (!contentItem) + executeContentItem(); + // This function is called by QQuickControl::contentItem() to lazily create + // a contentItem, so we don't need to try to set it again. + return ensureFlickable(false); +} + +QQuickFlickable *QQuickScrollViewPrivate::ensureFlickable(bool content) +{ + Q_Q(QQuickScrollView); + if (!flickable) { + flickableHasExplicitContentWidth = false; + flickableHasExplicitContentHeight = false; + // Pass ourselves as the Flickable's parent item. + auto flickable = new QQuickFlickable(q); + // We almost always want to clip the flickable so that flickable + // contents doesn't show up outside the scrollview. The only time + // this is not really needed, is when the scrollview covers the whole + // window and the scrollbars are transient. But for that corner case, if this + // optimization is needed, the user can simply create his own flickable + // child inside the scrollview, and control clipping on it explicit. + flickable->setClip(true); + flickable->setPixelAligned(true); + setFlickable(flickable, content); + } + return flickable; +} + +bool QQuickScrollViewPrivate::setFlickable(QQuickFlickable *item, bool content) +{ + Q_Q(QQuickScrollView); + if (item == flickable) + return false; + + QQuickScrollBarAttached *attached = qobject_cast<QQuickScrollBarAttached *>(qmlAttachedPropertiesObject<QQuickScrollBar>(q, false)); + + if (flickable) { + flickable->removeEventFilter(q); + + if (attached) + QQuickScrollBarAttachedPrivate::get(attached)->setFlickable(nullptr); + + QObjectPrivate::disconnect(flickable->contentItem(), &QQuickItem::childrenChanged, this, &QQuickPanePrivate::contentChildrenChange); + QObjectPrivate::disconnect(flickable, &QQuickFlickable::contentWidthChanged, this, &QQuickScrollViewPrivate::flickableContentWidthChanged); + QObjectPrivate::disconnect(flickable, &QQuickFlickable::contentHeightChanged, this, &QQuickScrollViewPrivate::flickableContentHeightChanged); + } + + flickable = item; + if (content) + q->setContentItem(flickable); + + if (flickable) { + flickable->installEventFilter(q); + if (hasContentWidth) + flickable->setContentWidth(contentWidth); + else + flickableContentWidthChanged(); + if (hasContentHeight) + flickable->setContentHeight(contentHeight); + else + flickableContentHeightChanged(); + + if (attached) + QQuickScrollBarAttachedPrivate::get(attached)->setFlickable(flickable); + + QObjectPrivate::connect(flickable->contentItem(), &QQuickItem::childrenChanged, this, &QQuickPanePrivate::contentChildrenChange); + QObjectPrivate::connect(flickable, &QQuickFlickable::contentWidthChanged, this, &QQuickScrollViewPrivate::flickableContentWidthChanged); + QObjectPrivate::connect(flickable, &QQuickFlickable::contentHeightChanged, this, &QQuickScrollViewPrivate::flickableContentHeightChanged); + } + + return true; +} + +void QQuickScrollViewPrivate::flickableContentWidthChanged() +{ + Q_Q(QQuickScrollView); + if (!flickable || !componentComplete) + return; + + const qreal cw = flickable->contentWidth(); + if (qFuzzyCompare(cw, implicitContentWidth)) + return; + + flickableHasExplicitContentWidth = true; + implicitContentWidth = cw; + emit q->implicitContentWidthChanged(); +} + +void QQuickScrollViewPrivate::flickableContentHeightChanged() +{ + Q_Q(QQuickScrollView); + if (!flickable || !componentComplete) + return; + + const qreal ch = flickable->contentHeight(); + if (qFuzzyCompare(ch, implicitContentHeight)) + return; + + flickableHasExplicitContentHeight = true; + implicitContentHeight = ch; + emit q->implicitContentHeightChanged(); +} + +qreal QQuickScrollViewPrivate::getContentWidth() const +{ + if (flickable && flickableHasExplicitContentWidth) + return flickable->contentWidth(); + + // The scrollview wraps a flickable created by us, and nobody searched for it and + // modified its contentWidth. In that case, since the application does not control + // this flickable, we fall back to calculate the content width based on the child + // items inside it. + return QQuickPanePrivate::getContentWidth(); +} + +qreal QQuickScrollViewPrivate::getContentHeight() const +{ + if (flickable && flickableHasExplicitContentHeight) + return flickable->contentHeight(); + + // The scrollview wraps a flickable created by us, and nobody searched for it and + // modified its contentHeight. In that case, since the application does not control + // this flickable, we fall back to calculate the content height based on the child + // items inside it. + return QQuickPanePrivate::getContentHeight(); +} + +QQuickScrollBar *QQuickScrollViewPrivate::verticalScrollBar() const +{ + Q_Q(const QQuickScrollView); + QQuickScrollBarAttached *attached = qobject_cast<QQuickScrollBarAttached *>(qmlAttachedPropertiesObject<QQuickScrollBar>(q, false)); + if (!attached) + return nullptr; + return attached->vertical(); +} + +QQuickScrollBar *QQuickScrollViewPrivate::horizontalScrollBar() const +{ + Q_Q(const QQuickScrollView); + QQuickScrollBarAttached *attached = qobject_cast<QQuickScrollBarAttached *>(qmlAttachedPropertiesObject<QQuickScrollBar>(q, false)); + if (!attached) + return nullptr; + return attached->horizontal(); +} + +void QQuickScrollViewPrivate::setScrollBarsInteractive(bool interactive) +{ + QQuickScrollBar *hbar = horizontalScrollBar(); + if (hbar) { + QQuickScrollBarPrivate *p = QQuickScrollBarPrivate::get(hbar); + if (!p->explicitInteractive) + p->setInteractive(interactive); + } + + QQuickScrollBar *vbar = verticalScrollBar(); + if (vbar) { + QQuickScrollBarPrivate *p = QQuickScrollBarPrivate::get(vbar); + if (!p->explicitInteractive) + p->setInteractive(interactive); + } +} + +void QQuickScrollViewPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj) +{ + QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); + // If we don't yet have a flickable assigned, and this object is a Flickable, + // make it our contentItem. + if (!p->flickable && p->setFlickable(qobject_cast<QQuickFlickable *>(obj), true)) + return; + + QQuickFlickable *flickable = p->ensureFlickable(true); + Q_ASSERT(flickable); + // Add the object that was declared as a child of us as a child object of the Flickable. + QQmlListProperty<QObject> data = flickable->flickableData(); + data.append(&data, obj); +} + +qsizetype QQuickScrollViewPrivate::contentData_count(QQmlListProperty<QObject> *prop) +{ + QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); + if (!p->flickable) + return 0; + + QQmlListProperty<QObject> data = p->flickable->flickableData(); + return data.count(&data); +} + +QObject *QQuickScrollViewPrivate::contentData_at(QQmlListProperty<QObject> *prop, qsizetype index) +{ + QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); + if (!p->flickable) + return nullptr; + + QQmlListProperty<QObject> data = p->flickable->flickableData(); + return data.at(&data, index); +} + +void QQuickScrollViewPrivate::contentData_clear(QQmlListProperty<QObject> *prop) +{ + QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); + if (!p->flickable) + return; + + QQmlListProperty<QObject> data = p->flickable->flickableData(); + return data.clear(&data); +} + +void QQuickScrollViewPrivate::contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *item) +{ + QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); + if (!p->flickable) + p->setFlickable(qobject_cast<QQuickFlickable *>(item), true); + + QQuickFlickable *flickable = p->ensureFlickable(true); + Q_ASSERT(flickable); + // Add the item that was declared as a child of us as a child item of the Flickable's contentItem. + QQmlListProperty<QQuickItem> children = flickable->flickableChildren(); + children.append(&children, item); +} + +qsizetype QQuickScrollViewPrivate::contentChildren_count(QQmlListProperty<QQuickItem> *prop) +{ + QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); + if (!p->flickable) + return 0; + + QQmlListProperty<QQuickItem> children = p->flickable->flickableChildren(); + return children.count(&children); +} + +QQuickItem *QQuickScrollViewPrivate::contentChildren_at(QQmlListProperty<QQuickItem> *prop, qsizetype index) +{ + QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); + if (!p->flickable) + return nullptr; + + QQmlListProperty<QQuickItem> children = p->flickable->flickableChildren(); + return children.at(&children, index); +} + +void QQuickScrollViewPrivate::contentChildren_clear(QQmlListProperty<QQuickItem> *prop) +{ + QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data); + if (!p->flickable) + return; + + QQmlListProperty<QQuickItem> children = p->flickable->flickableChildren(); + children.clear(&children); +} + +void QQuickScrollViewPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + // a special case for width<->height dependent content (wrapping text) in ScrollView + if (contentWidth < 0 && !componentComplete) + return; + + QQuickPanePrivate::itemImplicitWidthChanged(item); +} + +QQuickScrollView::QQuickScrollView(QQuickItem *parent) + : QQuickPane(*(new QQuickScrollViewPrivate), parent) +{ + Q_D(QQuickScrollView); + d->contentWidth = -1; + d->contentHeight = -1; + + setFiltersChildMouseEvents(true); + setWheelEnabled(true); +} + +/*! + \qmlproperty list<Object> QtQuick.Controls::ScrollView::contentData + \qmldefault + + This property holds the list of content data. + + The list contains all objects that have been declared in QML as children of the view. + + \note Unlike \c contentChildren, \c contentData does include non-visual QML objects. + + \sa Item::data, contentChildren +*/ +QQmlListProperty<QObject> QQuickScrollViewPrivate::contentData() +{ + Q_Q(QQuickScrollView); + return QQmlListProperty<QObject>(q, this, + QQuickScrollViewPrivate::contentData_append, + QQuickScrollViewPrivate::contentData_count, + QQuickScrollViewPrivate::contentData_at, + QQuickScrollViewPrivate::contentData_clear); +} + +/*! + \qmlproperty list<Item> QtQuick.Controls::ScrollView::contentChildren + + This property holds the list of content children. + + The list contains all items that have been declared in QML as children of the view. + + \note Unlike \c contentData, \c contentChildren does not include non-visual QML objects. + + \sa Item::children, contentData +*/ +QQmlListProperty<QQuickItem> QQuickScrollViewPrivate::contentChildren() +{ + Q_Q(QQuickScrollView); + return QQmlListProperty<QQuickItem>(q, this, + QQuickScrollViewPrivate::contentChildren_append, + QQuickScrollViewPrivate::contentChildren_count, + QQuickScrollViewPrivate::contentChildren_at, + QQuickScrollViewPrivate::contentChildren_clear); +} + +bool QQuickScrollView::childMouseEventFilter(QQuickItem *item, QEvent *event) +{ + Q_D(QQuickScrollView); + switch (event->type()) { + case QEvent::TouchBegin: + d->wasTouched = true; + d->setScrollBarsInteractive(false); + return false; + + case QEvent::TouchEnd: + d->wasTouched = false; + return false; + + case QEvent::MouseButtonPress: + // NOTE: Flickable does not handle touch events, only synthesized mouse events + if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized) { + d->wasTouched = false; + d->setScrollBarsInteractive(true); + return false; + } + return !d->wasTouched && item == d->flickable; + + case QEvent::MouseMove: + case QEvent::MouseButtonRelease: + if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized) + return item == d->flickable; + break; + + case QEvent::HoverEnter: + case QEvent::HoverMove: + if (d->wasTouched && (item == d->verticalScrollBar() || item == d->horizontalScrollBar())) + d->setScrollBarsInteractive(true); + break; + + default: + break; + } + + return false; +} + +bool QQuickScrollView::eventFilter(QObject *object, QEvent *event) +{ + Q_D(QQuickScrollView); + if (event->type() == QEvent::Wheel) { + d->setScrollBarsInteractive(true); + if (!d->wheelEnabled) + return true; + } + return QQuickPane::eventFilter(object, event); +} + +void QQuickScrollView::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickScrollView); + QQuickPane::keyPressEvent(event); + switch (event->key()) { + case Qt::Key_Up: + if (QQuickScrollBar *vbar = d->verticalScrollBar()) { + vbar->decrease(); + event->accept(); + } + break; + case Qt::Key_Down: + if (QQuickScrollBar *vbar = d->verticalScrollBar()) { + vbar->increase(); + event->accept(); + } + break; + case Qt::Key_Left: + if (QQuickScrollBar *hbar = d->horizontalScrollBar()) { + hbar->decrease(); + event->accept(); + } + break; + case Qt::Key_Right: + if (QQuickScrollBar *hbar = d->horizontalScrollBar()) { + hbar->increase(); + event->accept(); + } + break; + default: + event->ignore(); + break; + } +} + +void QQuickScrollView::componentComplete() +{ + Q_D(QQuickScrollView); + QQuickPane::componentComplete(); + if (!d->contentItem) + d->ensureFlickable(true); +} + +void QQuickScrollView::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + Q_D(QQuickScrollView); + if (newItem != d->flickable) { + // The new flickable was not created by us. In that case, we always + // assume/require that it has an explicit content size assigned. + d->flickableHasExplicitContentWidth = true; + d->flickableHasExplicitContentHeight = true; + auto newItemAsFlickable = qobject_cast<QQuickFlickable *>(newItem); + if (newItem && !newItemAsFlickable) + qmlWarning(this) << "ScrollView only supports Flickable types as its contentItem"; + // This is called by QQuickControlPrivate::setContentItem_helper, so no need to + // try to set it as the contentItem. + d->setFlickable(newItemAsFlickable, false); + // We do, however, need to set us as its parent item, as setContentItem_helper will only + // do so if the item doesn't already have a parent. If newItem wasn't declared as our + // child and was instead imperatively assigned, it may already have a parent item, + // which we'll need to override. + if (newItem) { + newItem->setParentItem(this); + + // Make sure that the scroll bars are stacked in front of the flickable, + // otherwise events won't get through to them. + QQuickScrollBar *verticalBar = d->verticalScrollBar(); + if (verticalBar) + verticalBar->stackAfter(newItem); + QQuickScrollBar *horizontalBar = d->horizontalScrollBar(); + if (horizontalBar) + horizontalBar->stackAfter(newItem); + } + } + QQuickPane::contentItemChange(newItem, oldItem); +} + +void QQuickScrollView::contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) +{ + Q_D(QQuickScrollView); + QQuickPane::contentSizeChange(newSize, oldSize); + if (d->flickable) { + // Only set the content size on the flickable if the flickable doesn't + // have an explicit assignment from before. Otherwise we can end up overwriting + // assignments done to those properties by the application. The + // exception is if the application has assigned a content size + // directly to the scrollview, which will then win even if the + // application has assigned something else to the flickable. + if (d->hasContentWidth || !d->flickableHasExplicitContentWidth) + d->flickable->setContentWidth(newSize.width()); + if (d->hasContentHeight || !d->flickableHasExplicitContentHeight) + d->flickable->setContentHeight(newSize.height()); + } +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickScrollView::accessibleRole() const +{ + return QAccessible::Pane; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickscrollview_p.cpp" diff --git a/src/quicktemplates2/qquickscrollview_p.h b/src/quicktemplates2/qquickscrollview_p.h new file mode 100644 index 00000000000..7eea46ddae1 --- /dev/null +++ b/src/quicktemplates2/qquickscrollview_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSCROLLVIEW_P_H +#define QQUICKSCROLLVIEW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickpane_p.h> +#include <QtQml/qqmllist.h> + +QT_BEGIN_NAMESPACE + +class QQuickScrollViewPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickScrollView : public QQuickPane +{ + Q_OBJECT + QML_NAMED_ELEMENT(ScrollView) + QML_ADDED_IN_VERSION(2, 2) + +public: + explicit QQuickScrollView(QQuickItem *parent = nullptr); + +protected: + bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; + bool eventFilter(QObject *object, QEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + + void componentComplete() override; + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + void contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickScrollView) + Q_DECLARE_PRIVATE(QQuickScrollView) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickScrollView) + +#endif // QQUICKSCROLLVIEW_P_H diff --git a/src/quicktemplates2/qquickselectionrectangle.cpp b/src/quicktemplates2/qquickselectionrectangle.cpp new file mode 100644 index 00000000000..10573eda7c0 --- /dev/null +++ b/src/quicktemplates2/qquickselectionrectangle.cpp @@ -0,0 +1,574 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickselectionrectangle_p.h" +#include "qquickselectionrectangle_p_p.h" + +#include <QtQml/qqmlinfo.h> +#include <QtQuick/private/qquickdraghandler_p.h> +#include <QtQuick/private/qquickhoverhandler_p.h> + +#include <QtQuick/private/qquicktableview_p_p.h> + +#include "qquickscrollview_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype SelectionRectangle + \inherits Control +//! \instantiates QQuickSelectionRectangle + \inqmlmodule QtQuick.Controls + \since 6.2 + \ingroup utilities + \brief Used to select table cells inside a TableView. + + \image qtquickcontrols2-selectionrectangle.png + + SelectionRectangle is used for selecting table cells in a TableView. It lets + the user start a selection by doing a pointer drag inside the viewport, or by + doing a long press on top of a cell. + + For a SelectionRectangle to be able to select cells, TableView must have + an ItemSelectionModel assigned. The ItemSelectionModel will store any + selections done on the model, and can be used for querying + which cells that the user has selected. + + The following example shows how you can make a SelectionRectangle target + a TableView: + + \snippet qtquickcontrols2-selectionrectangle.qml 0 + + \note A SelectionRectangle itself is not shown as part of a selection. Only the + delegates (like topLeftHandle and bottomRightHandle) are used. + You should also consider \l {Selecting items}{rendering the TableView delegate as selected}. + + \sa TableView, TableView::selectionModel, ItemSelectionModel +*/ + +/*! + \qmlproperty Item QtQuick.Controls::SelectionRectangle::target + + This property holds the TableView on which the + SelectionRectangle should act. +*/ + +/*! + \qmlproperty bool QtQuick.Controls::SelectionRectangle::active + \readonly + + This property is \c true while the user is performing a + selection. The selection will be active from the time the + the user starts to select, and until the selection is + removed again, for example from tapping inside the viewport. +*/ + +/*! + \qmlproperty bool QtQuick.Controls::SelectionRectangle::dragging + \readonly + + This property is \c true whenever the user is doing a pointer drag or + a handle drag to adjust the selection rectangle. +*/ + +/*! + \qmlproperty Component QtQuick.Controls::SelectionRectangle::topLeftHandle + + This property holds the delegate that will be shown on the center of the + top-left corner of the selection rectangle. When a handle is + provided, the user can drag it to adjust the selection. + + Set this property to \c null if you don't want a selection handle on the top-left. + + \sa bottomRightHandle +*/ + +/*! + \qmlproperty Component QtQuick.Controls::SelectionRectangle::bottomRightHandle + + This property holds the delegate that will be shown on the center of the + top-left corner of the selection rectangle. When a handle is + provided, the user can drag it to adjust the selection. + + Set this property to \c null if you don't want a selection handle on the bottom-right. + + \sa topLeftHandle +*/ + +/*! + \qmlproperty enumeration QtQuick.Controls::SelectionRectangle::selectionMode + + This property holds when a selection should start. + + \value SelectionRectangle.Drag A selection will start by doing a pointer drag inside the viewport + \value SelectionRectangle.PressAndHold A selection will start by doing a press and hold on top a cell + \value SelectionRectangle.Auto SelectionRectangle will choose which mode to use based on the target + and the platform. This normally means \c PressAndHold on touch based platforms, and \c Drag on desktop. + However, \c Drag will only be used if it doesn't conflict with flicking. This means that + TableView will need to be configured with \c interactive set to \c false, or placed + inside a ScrollView (where flicking, by default, is off for mouse events), for \c Drag to be chosen. + + The default value is \c Auto. +*/ + +/*! + \qmlattachedproperty SelectionRectangle QtQuick::SelectionRectangle::control + + This attached property holds the SelectionRectangle that manages the delegate instance. + It is attached to each handle instance. +*/ + +/*! + \qmlattachedproperty bool QtQuick::SelectionRectangle::dragging + + This attached property will be \c true if the user is dragging on the handle. + It is attached to each handle instance. +*/ + +QQuickSelectionRectanglePrivate::QQuickSelectionRectanglePrivate() + : QQuickControlPrivate() +{ + m_tapHandler = new QQuickTapHandler(); + m_dragHandler = new QQuickDragHandler(); + m_dragHandler->setTarget(nullptr); + + QObject::connect(&m_scrollTimer, &QTimer::timeout, [&]{ + if (m_topLeftHandle && m_draggedHandle == m_topLeftHandle) + m_selectable->setSelectionStartPos(m_scrollToPoint); + else + m_selectable->setSelectionEndPos(m_scrollToPoint); + updateHandles(); + const QSizeF dist = m_selectable->scrollTowardsSelectionPoint(m_scrollToPoint, m_scrollSpeed); + m_scrollToPoint.rx() += dist.width() > 0 ? m_scrollSpeed.width() : -m_scrollSpeed.width(); + m_scrollToPoint.ry() += dist.height() > 0 ? m_scrollSpeed.height() : -m_scrollSpeed.height(); + m_scrollSpeed = QSizeF(qAbs(dist.width() * 0.007), qAbs(dist.height() * 0.007)); + }); + + QObject::connect(m_tapHandler, &QQuickTapHandler::tapped, [=](QEventPoint) { + m_selectable->clearSelection(); + updateActiveState(false); + }); + + QObject::connect(m_tapHandler, &QQuickTapHandler::longPressed, [=]() { + if (handleUnderPos(m_tapHandler->point().pressPosition()) != nullptr) { + // Don't allow press'n'hold to start a new + // selection if it started on top of a handle. + return; + } + if (!m_alwaysAcceptPressAndHold) { + if (m_selectionMode == QQuickSelectionRectangle::Auto) { + // In Auto mode, we only accept press and hold from touch + if (m_tapHandler->point().device()->pointerType() != QPointingDevice::PointerType::Finger) + return; + } else if (m_selectionMode != QQuickSelectionRectangle::PressAndHold) { + return; + } + } + + const QPointF pos = m_tapHandler->point().position(); + m_selectable->clearSelection(); + m_selectable->setSelectionStartPos(pos); + m_selectable->setSelectionEndPos(pos); + updateHandles(); + updateActiveState(true); + }); + + QObject::connect(m_dragHandler, &QQuickDragHandler::activeChanged, [=]() { + const QPointF startPos = m_dragHandler->centroid().pressPosition(); + const QPointF dragPos = m_dragHandler->centroid().position(); + if (m_dragHandler->active()) { + m_selectable->clearSelection(); + m_selectable->setSelectionStartPos(startPos); + m_selectable->setSelectionEndPos(dragPos); + m_draggedHandle = nullptr; + updateHandles(); + updateActiveState(true); + updateDraggingState(true); + } else { + m_scrollTimer.stop(); + m_selectable->normalizeSelection(); + updateDraggingState(false); + } + }); + + QObject::connect(m_dragHandler, &QQuickDragHandler::centroidChanged, [=]() { + if (!m_dragging) + return; + const QPointF pos = m_dragHandler->centroid().position(); + m_selectable->setSelectionEndPos(pos); + updateHandles(); + scrollTowardsPos(pos); + }); +} + +void QQuickSelectionRectanglePrivate::scrollTowardsPos(const QPointF &pos) +{ + m_scrollToPoint = pos; + if (m_scrollTimer.isActive()) + return; + + const QSizeF dist = m_selectable->scrollTowardsSelectionPoint(m_scrollToPoint, m_scrollSpeed); + if (!dist.isNull()) + m_scrollTimer.start(1); +} + +QQuickItem *QQuickSelectionRectanglePrivate::handleUnderPos(const QPointF &pos) +{ + const auto handlerTarget = m_selectable->selectionPointerHandlerTarget(); + if (m_topLeftHandle) { + const QPointF localPos = m_topLeftHandle->mapFromItem(handlerTarget, pos); + if (m_topLeftHandle->contains(localPos)) + return m_topLeftHandle; + } + + if (m_bottomRightHandle) { + const QPointF localPos = m_bottomRightHandle->mapFromItem(handlerTarget, pos); + if (m_bottomRightHandle->contains(localPos)) + return m_bottomRightHandle; + } + + return nullptr; +} + +void QQuickSelectionRectanglePrivate::updateDraggingState(bool dragging) +{ + if (dragging != m_dragging) { + m_dragging = dragging; + emit q_func()->draggingChanged(); + } + + if (auto attached = getAttachedObject(m_draggedHandle)) + attached->setDragging(dragging); +} + +void QQuickSelectionRectanglePrivate::updateActiveState(bool active) +{ + if (active == m_active) + return; + + m_active = active; + emit q_func()->activeChanged(); +} + +QQuickItem *QQuickSelectionRectanglePrivate::createHandle(QQmlComponent *delegate, Qt::Corner corner) +{ + Q_Q(QQuickSelectionRectangle); + + // Incubate the handle + QObject *obj = delegate->beginCreate(QQmlEngine::contextForObject(q)); + QQuickItem *handleItem = qobject_cast<QQuickItem*>(obj); + const auto handlerTarget = m_selectable->selectionPointerHandlerTarget(); + handleItem->setParentItem(handlerTarget); + if (auto attached = getAttachedObject(handleItem)) + attached->setControl(q); + delegate->completeCreate(); + if (handleItem->z() == 0) + handleItem->setZ(100); + + // Add pointer handlers to it + QQuickDragHandler *dragHandler = new QQuickDragHandler(); + dragHandler->setTarget(nullptr); + dragHandler->setParent(handleItem); + QQuickItemPrivate::get(handleItem)->addPointerHandler(dragHandler); + + QQuickHoverHandler *hoverHandler = new QQuickHoverHandler(); + hoverHandler->setTarget(nullptr); + hoverHandler->setParent(handleItem); + hoverHandler->setCursorShape(Qt::SizeFDiagCursor); + QQuickItemPrivate::get(handleItem)->addPointerHandler(hoverHandler); + + QObject::connect(dragHandler, &QQuickDragHandler::activeChanged, [=]() { + if (dragHandler->active()) { + const QPointF localPos = dragHandler->centroid().position(); + const QPointF pos = handleItem->mapToItem(handleItem->parentItem(), localPos); + if (corner == Qt::TopLeftCorner) + m_selectable->setSelectionStartPos(pos); + else + m_selectable->setSelectionEndPos(pos); + + m_draggedHandle = handleItem; + updateHandles(); + updateDraggingState(true); + QGuiApplication::setOverrideCursor(Qt::SizeFDiagCursor); + } else { + m_scrollTimer.stop(); + m_selectable->normalizeSelection(); + updateDraggingState(false); + QGuiApplication::restoreOverrideCursor(); + } + }); + + QObject::connect(dragHandler, &QQuickDragHandler::centroidChanged, [=]() { + if (!m_dragging) + return; + + const QPointF localPos = dragHandler->centroid().position(); + const QPointF pos = handleItem->mapToItem(handleItem->parentItem(), localPos); + if (corner == Qt::TopLeftCorner) + m_selectable->setSelectionStartPos(pos); + else + m_selectable->setSelectionEndPos(pos); + + updateHandles(); + scrollTowardsPos(pos); + }); + + return handleItem; +} + +void QQuickSelectionRectanglePrivate::updateHandles() +{ + if (!m_selectable) + return; + + const QRectF rect = m_selectable->selectionRectangle().normalized(); + + if (!m_topLeftHandle && m_topLeftHandleDelegate) + m_topLeftHandle = createHandle(m_topLeftHandleDelegate, Qt::TopLeftCorner); + + if (!m_bottomRightHandle && m_bottomRightHandleDelegate) + m_bottomRightHandle = createHandle(m_bottomRightHandleDelegate, Qt::BottomRightCorner); + + if (m_topLeftHandle) { + m_topLeftHandle->setX(rect.x() - (m_topLeftHandle->width() / 2)); + m_topLeftHandle->setY(rect.y() - (m_topLeftHandle->height() / 2)); + } + + if (m_bottomRightHandle) { + m_bottomRightHandle->setX(rect.x() + rect.width() - (m_bottomRightHandle->width() / 2)); + m_bottomRightHandle->setY(rect.y() + rect.height() - (m_bottomRightHandle->height() / 2)); + } +} + +void QQuickSelectionRectanglePrivate::connectToTarget() +{ + // To support QuickSelectionRectangle::Auto, we need to listen for changes to the target + if (const auto flickable = qobject_cast<QQuickFlickable *>(m_target)) { + connect(flickable, &QQuickFlickable::interactiveChanged, this, &QQuickSelectionRectanglePrivate::updateSelectionMode); + } +} + +void QQuickSelectionRectanglePrivate::updateSelectionMode() +{ + Q_Q(QQuickSelectionRectangle); + + const bool enabled = q->isEnabled(); + m_tapHandler->setEnabled(enabled); + + if (m_selectionMode == QQuickSelectionRectangle::Auto) { + if (qobject_cast<QQuickScrollView *>(m_target->parentItem())) { + // ScrollView allows flicking with touch, but not with mouse. So we do + // the same here: you can drag to select with a mouse, but not with touch. + m_dragHandler->setAcceptedDevices(QInputDevice::DeviceType::Mouse); + m_dragHandler->setEnabled(enabled); + } else if (const auto flickable = qobject_cast<QQuickFlickable *>(m_target)) { + m_dragHandler->setEnabled(enabled && !flickable->isInteractive()); + } else { + m_dragHandler->setAcceptedDevices(QInputDevice::DeviceType::Mouse); + m_dragHandler->setEnabled(enabled); + } + } else if (m_selectionMode == QQuickSelectionRectangle::Drag) { + m_dragHandler->setAcceptedDevices(QInputDevice::DeviceType::AllDevices); + m_dragHandler->setEnabled(enabled); + } else { + m_dragHandler->setEnabled(false); + } + + // If you can't select using a drag, we always accept a PressAndHold + m_alwaysAcceptPressAndHold = !m_dragHandler->enabled(); +} + +QQuickSelectionRectangleAttached *QQuickSelectionRectanglePrivate::getAttachedObject(const QObject *object) const +{ + QObject *attachedObject = qmlAttachedPropertiesObject<QQuickSelectionRectangle>(object); + return static_cast<QQuickSelectionRectangleAttached *>(attachedObject); +} + +// -------------------------------------------------------- + +QQuickSelectionRectangle::QQuickSelectionRectangle(QQuickItem *parent) + : QQuickControl(*(new QQuickSelectionRectanglePrivate), parent) +{ + Q_D(QQuickSelectionRectangle); + + QObject::connect(this, &QQuickItem::enabledChanged, [=]() { + d->m_scrollTimer.stop(); + d->updateSelectionMode(); + d->updateDraggingState(false); + d->updateActiveState(false); + }); +} + +QQuickItem *QQuickSelectionRectangle::target() const +{ + return d_func()->m_target; +} + +void QQuickSelectionRectangle::setTarget(QQuickItem *target) +{ + Q_D(QQuickSelectionRectangle); + if (d->m_target == target) + return; + + if (d->m_selectable) { + d->m_scrollTimer.stop(); + d->m_tapHandler->setParent(nullptr); + d->m_dragHandler->setParent(nullptr); + d->m_target->disconnect(this); + } + + d->m_target = target; + d->m_selectable = nullptr; + + if (d->m_target) { + d->m_selectable = dynamic_cast<QQuickSelectable *>(QObjectPrivate::get(d->m_target.data())); + if (!d->m_selectable) + qmlWarning(this) << "the assigned target is not supported by the control"; + } + + if (d->m_selectable) { + const auto handlerTarget = d->m_selectable->selectionPointerHandlerTarget(); + d->m_dragHandler->setParent(handlerTarget); + d->m_tapHandler->setParent(handlerTarget); + QQuickItemPrivate::get(handlerTarget)->addPointerHandler(d->m_tapHandler); + QQuickItemPrivate::get(handlerTarget)->addPointerHandler(d->m_dragHandler); + d->connectToTarget(); + d->updateSelectionMode(); + } + + emit targetChanged(); +} + +bool QQuickSelectionRectangle::active() +{ + return d_func()->m_active; +} + +bool QQuickSelectionRectangle::dragging() +{ + return d_func()->m_dragging; +} + +QQuickSelectionRectangle::SelectionMode QQuickSelectionRectangle::selectionMode() const +{ + return d_func()->m_selectionMode; +} + +void QQuickSelectionRectangle::setSelectionMode(QQuickSelectionRectangle::SelectionMode selectionMode) +{ + Q_D(QQuickSelectionRectangle); + if (d->m_selectionMode == selectionMode) + return; + + d->m_selectionMode = selectionMode; + + if (d->m_target) + d->updateSelectionMode(); + + emit selectionModeChanged(); +} + +QQmlComponent *QQuickSelectionRectangle::topLeftHandle() const +{ + return d_func()->m_topLeftHandleDelegate; +} + +void QQuickSelectionRectangle::setTopLeftHandle(QQmlComponent *topLeftHandle) +{ + Q_D(QQuickSelectionRectangle); + if (d->m_topLeftHandleDelegate == topLeftHandle) + return; + + d->m_topLeftHandleDelegate = topLeftHandle; + emit topLeftHandleChanged(); +} + +QQmlComponent *QQuickSelectionRectangle::bottomRightHandle() const +{ + return d_func()->m_bottomRightHandleDelegate; +} + +void QQuickSelectionRectangle::setBottomRightHandle(QQmlComponent *bottomRightHandle) +{ + Q_D(QQuickSelectionRectangle); + if (d->m_bottomRightHandleDelegate == bottomRightHandle) + return; + + d->m_bottomRightHandleDelegate = bottomRightHandle; + emit bottomRightHandleChanged(); +} + +QQuickSelectionRectangleAttached *QQuickSelectionRectangle::qmlAttachedProperties(QObject *obj) +{ + return new QQuickSelectionRectangleAttached(obj); +} + +QQuickSelectionRectangleAttached::QQuickSelectionRectangleAttached(QObject *parent) + : QObject(parent) +{ +} + +QQuickSelectionRectangle *QQuickSelectionRectangleAttached::control() const +{ + return m_control; +} + +void QQuickSelectionRectangleAttached::setControl(QQuickSelectionRectangle *control) +{ + if (m_control == control) + return; + + m_control = control; + emit controlChanged(); +} + +bool QQuickSelectionRectangleAttached::dragging() const +{ + return m_dragging; +} + +void QQuickSelectionRectangleAttached::setDragging(bool dragging) +{ + if (m_dragging == dragging) + return; + + m_dragging = dragging; + emit draggingChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qquickselectionrectangle_p.cpp" diff --git a/src/quicktemplates2/qquickselectionrectangle_p.h b/src/quicktemplates2/qquickselectionrectangle_p.h new file mode 100644 index 00000000000..57d7706440b --- /dev/null +++ b/src/quicktemplates2/qquickselectionrectangle_p.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSELECTIONRECTANGLE_P_H +#define QQUICKSELECTIONRECTANGLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickSelectionRectanglePrivate; +class QQuickSelectable; +class QQuickSelectionRectangleAttached; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSelectionRectangle : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode NOTIFY selectionModeChanged FINAL) + Q_PROPERTY(QQuickItem *target READ target WRITE setTarget NOTIFY targetChanged FINAL) + Q_PROPERTY(QQmlComponent *topLeftHandle READ topLeftHandle WRITE setTopLeftHandle NOTIFY topLeftHandleChanged FINAL) + Q_PROPERTY(QQmlComponent *bottomRightHandle READ bottomRightHandle WRITE setBottomRightHandle NOTIFY bottomRightHandleChanged FINAL) + Q_PROPERTY(bool active READ active NOTIFY activeChanged FINAL) + Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged FINAL) + + QML_NAMED_ELEMENT(SelectionRectangle) + QML_ATTACHED(QQuickSelectionRectangleAttached) + QML_ADDED_IN_VERSION(6, 2) + +public: + enum SelectionMode { + Drag, + PressAndHold, + Auto + }; + Q_ENUM(SelectionMode) + + explicit QQuickSelectionRectangle(QQuickItem *parent = nullptr); + + QQuickItem *target() const; + void setTarget(QQuickItem *target); + + bool active(); + bool dragging(); + + SelectionMode selectionMode() const; + void setSelectionMode(SelectionMode selectionMode); + + QQmlComponent *topLeftHandle() const; + void setTopLeftHandle(QQmlComponent *topLeftHandle); + QQmlComponent *bottomRightHandle() const; + void setBottomRightHandle(QQmlComponent *bottomRightHandle); + + static QQuickSelectionRectangleAttached *qmlAttachedProperties(QObject *obj); + +Q_SIGNALS: + void targetChanged(); + void activeChanged(); + void draggingChanged(); + void topLeftHandleChanged(); + void bottomRightHandleChanged(); + void selectionModeChanged(); + +private: + Q_DISABLE_COPY(QQuickSelectionRectangle) + Q_DECLARE_PRIVATE(QQuickSelectionRectangle) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSelectionRectangleAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickSelectionRectangle *control READ control NOTIFY controlChanged FINAL) + Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged FINAL) + +public: + QQuickSelectionRectangleAttached(QObject *parent); + + QQuickSelectionRectangle *control() const; + void setControl(QQuickSelectionRectangle *control); + + bool dragging() const; + void setDragging(bool dragging); + +Q_SIGNALS: + void controlChanged(); + void draggingChanged(); + +private: + QPointer<QQuickSelectionRectangle> m_control; + bool m_dragging = false; + + friend class QQuickSelectionRectanglePrivate; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickSelectionRectangle) + +#endif // QQUICKSELECTIONRECTANGLE_P_H diff --git a/src/quicktemplates2/qquickselectionrectangle_p_p.h b/src/quicktemplates2/qquickselectionrectangle_p_p.h new file mode 100644 index 00000000000..a42e9e78bca --- /dev/null +++ b/src/quicktemplates2/qquickselectionrectangle_p_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSELECTIONRECTANGLE_P_P_H +#define QQUICKSELECTIONRECTANGLE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquickselectionrectangle_p.h" + +#include <QtCore/qpointer.h> +#include <QtCore/qtimer.h> + +#include <QtQuick/private/qquickselectable_p.h> +#include <QtQuick/private/qquicktaphandler_p.h> +#include <QtQuick/private/qquickdraghandler_p.h> + +#include <QtQuickTemplates2/private/qquickcontrol_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickSelectionRectanglePrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickSelectionRectangle) + +public: + QQuickSelectionRectanglePrivate(); + + void updateDraggingState(bool isDragging); + void updateActiveState(bool isActive); + void updateHandles(); + void updateSelectionMode(); + void connectToTarget(); + void scrollTowardsPos(const QPointF &pos); + QQuickItem *handleUnderPos(const QPointF &pos); + + QQuickItem *createHandle(QQmlComponent *delegate, Qt::Corner corner); + + QQuickSelectionRectangleAttached *getAttachedObject(const QObject *object) const; + +public: + QPointer<QQuickItem> m_target; + + QQmlComponent *m_topLeftHandleDelegate = nullptr; + QQmlComponent *m_bottomRightHandleDelegate = nullptr; + QPointer<QQuickItem> m_topLeftHandle; + QPointer<QQuickItem> m_bottomRightHandle; + QPointer<QQuickItem> m_draggedHandle = nullptr; + + QQuickSelectable *m_selectable = nullptr; + + QQuickTapHandler *m_tapHandler = nullptr; + QQuickDragHandler *m_dragHandler = nullptr; + + QTimer m_scrollTimer; + QPointF m_scrollToPoint; + QSizeF m_scrollSpeed = QSizeF(1, 1); + + QQuickSelectionRectangle::SelectionMode m_selectionMode = QQuickSelectionRectangle::Auto; + bool m_alwaysAcceptPressAndHold = false; + + bool m_enabled = true; + bool m_active = false; + bool m_dragging = false; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSELECTIONRECTANGLE_P_P_H diff --git a/src/quicktemplates2/qquickshortcutcontext.cpp b/src/quicktemplates2/qquickshortcutcontext.cpp new file mode 100644 index 00000000000..9237017dfa2 --- /dev/null +++ b/src/quicktemplates2/qquickshortcutcontext.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickshortcutcontext_p_p.h" +#include "qquickoverlay_p_p.h" +#include "qquicktooltip_p.h" +#include "qquickmenu_p.h" +#include "qquickmenu_p_p.h" +#include "qquickpopup_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtGui/qguiapplication.h> +#include <QtQuick/qquickrendercontrol.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcContextMatcher, "qt.quick.controls.shortcutcontext.matcher") + +static bool isBlockedByPopup(QQuickItem *item) +{ + if (!item || !item->window()) + return false; + + QQuickOverlay *overlay = QQuickOverlay::overlay(item->window()); + const auto popups = QQuickOverlayPrivate::get(overlay)->stackingOrderPopups(); + for (QQuickPopup *popup : popups) { + if (qobject_cast<QQuickToolTip *>(popup)) + continue; // ignore tooltips (QTBUG-60492) + if (popup->isModal() || popup->closePolicy() & QQuickPopup::CloseOnEscape) { + return item != popup->popupItem() && !popup->popupItem()->isAncestorOf(item); + } + } + + return false; +} + +bool QQuickShortcutContext::matcher(QObject *obj, Qt::ShortcutContext context) +{ + QQuickItem *item = nullptr; + switch (context) { + case Qt::ApplicationShortcut: + return true; + case Qt::WindowShortcut: + while (obj && !obj->isWindowType()) { + item = qobject_cast<QQuickItem *>(obj); + if (item && item->window()) { + obj = item->window(); + break; + } else if (QQuickPopup *popup = qobject_cast<QQuickPopup *>(obj)) { + obj = popup->window(); + item = popup->popupItem(); + + if (!obj) { + // The popup has no associated window (yet). However, sub-menus, + // unlike top-level menus, will not have an associated window + // until their parent menu is opened. So, check if this is a sub-menu + // so that actions within it can grab shortcuts. + if (auto *menu = qobject_cast<QQuickMenu *>(popup)) { + auto parentMenu = QQuickMenuPrivate::get(menu)->parentMenu; + while (!obj && parentMenu) + obj = parentMenu->window(); + } + } + break; + } + obj = obj->parent(); + } + if (QWindow *renderWindow = QQuickRenderControl::renderWindowFor(qobject_cast<QQuickWindow *>(obj))) + obj = renderWindow; + qCDebug(lcContextMatcher) << "obj" << obj << "focusWindow" << QGuiApplication::focusWindow() + << "!isBlockedByPopup(item)" << !isBlockedByPopup(item); + return obj && obj == QGuiApplication::focusWindow() && !isBlockedByPopup(item); + default: + return false; + } +} + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickshortcutcontext_p_p.h b/src/quicktemplates2/qquickshortcutcontext_p_p.h new file mode 100644 index 00000000000..44e63f1e0e8 --- /dev/null +++ b/src/quicktemplates2/qquickshortcutcontext_p_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSHORTCUTCONTEXT_P_P_H +#define QQUICKSHORTCUTCONTEXT_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qnamespace.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class QObject; + +struct Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickShortcutContext +{ + static bool matcher(QObject *object, Qt::ShortcutContext context); +}; + +QT_END_NAMESPACE + +#endif // QQUICKSHORTCUTCONTEXT_P_P_H diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp new file mode 100644 index 00000000000..1aa3e43ff1a --- /dev/null +++ b/src/quicktemplates2/qquickslider.cpp @@ -0,0 +1,895 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickslider_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickdeferredexecute_p_p.h" + +#include <QtQuick/private/qquickwindow_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Slider + \inherits Control +//! \instantiates QQuickSlider + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-input + \brief Used to select a value by sliding a handle along a track. + + \image qtquickcontrols2-slider.gif + + Slider is used to select a value by sliding a handle along a track. + + In the example below, custom \l from, \l value, and \l to values are set: + + \code + Slider { + from: 1 + value: 25 + to: 100 + } + \endcode + + The \l position property is expressed as a fraction of the control's size, + in the range \c {0.0 - 1.0}. The \l visualPosition property is + the same, except that it is reversed in a + \l {Right-to-left User Interfaces}{right-to-left} application. The + visualPosition is useful for positioning the handle when styling Slider. + In the example above, \l visualPosition will be \c 0.24 in a left-to-right + application, and \c 0.76 in a right-to-left application. + + For a slider that allows the user to select a range by providing two + handles, see \l RangeSlider. + + \sa {Customizing Slider}, {Input Controls} +*/ + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlsignal QtQuick.Controls::Slider::moved() + + This signal is emitted when the slider has been interactively moved + by the user by either touch, mouse, wheel, or keys. +*/ + +class QQuickSliderPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickSlider) + +public: + qreal snapPosition(qreal position) const; + qreal positionAt(const QPointF &point) const; + void setPosition(qreal position); + void updatePosition(); + + void handlePress(const QPointF &point) override; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + void handleUngrab() override; + + void cancelHandle(); + void executeHandle(bool complete = false); + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + qreal from = 0; + qreal to = 1; + qreal value = 0; + qreal position = 0; + qreal stepSize = 0; + qreal touchDragThreshold = -1; // in QQuickWindowPrivate::dragOverThreshold, '-1' implies using styleHints::startDragDistance() + bool live = true; + bool pressed = false; + QPointF pressPoint; + Qt::Orientation orientation = Qt::Horizontal; + QQuickSlider::SnapMode snapMode = QQuickSlider::NoSnap; + QQuickDeferredPointer<QQuickItem> handle; +}; + +qreal QQuickSliderPrivate::snapPosition(qreal position) const +{ + const qreal range = to - from; + if (qFuzzyIsNull(range)) + return position; + + const qreal effectiveStep = stepSize / range; + if (qFuzzyIsNull(effectiveStep)) + return position; + + return qRound(position / effectiveStep) * effectiveStep; +} + +qreal QQuickSliderPrivate::positionAt(const QPointF &point) const +{ + Q_Q(const QQuickSlider); + qreal pos = 0.0; + if (orientation == Qt::Horizontal) { + const qreal hw = handle ? handle->width() : 0; + const qreal offset = hw / 2; + const qreal extent = q->availableWidth() - hw; + if (!qFuzzyIsNull(extent)) { + if (q->isMirrored()) + pos = (q->width() - point.x() - q->rightPadding() - offset) / extent; + else + pos = (point.x() - q->leftPadding() - offset) / extent; + } + } else { + const qreal hh = handle ? handle->height() : 0; + const qreal offset = hh / 2; + const qreal extent = q->availableHeight() - hh; + if (!qFuzzyIsNull(extent)) + pos = (q->height() - point.y() - q->bottomPadding() - offset) / extent; + } + return qBound<qreal>(0.0, pos, 1.0); +} + +void QQuickSliderPrivate::setPosition(qreal pos) +{ + Q_Q(QQuickSlider); + pos = qBound<qreal>(0.0, pos, 1.0); + if (qFuzzyCompare(position, pos)) + return; + + position = pos; + emit q->positionChanged(); + emit q->visualPositionChanged(); +} + +void QQuickSliderPrivate::updatePosition() +{ + qreal pos = 0; + if (!qFuzzyCompare(from, to)) + pos = (value - from) / (to - from); + setPosition(pos); +} + +void QQuickSliderPrivate::handlePress(const QPointF &point) +{ + Q_Q(QQuickSlider); + QQuickControlPrivate::handlePress(point); + pressPoint = point; + q->setPressed(true); +} + +void QQuickSliderPrivate::handleMove(const QPointF &point) +{ + Q_Q(QQuickSlider); + QQuickControlPrivate::handleMove(point); + const qreal oldPos = position; + qreal pos = positionAt(point); + if (snapMode == QQuickSlider::SnapAlways) + pos = snapPosition(pos); + if (live) + q->setValue(q->valueAt(pos)); + if (!live || snapMode == QQuickSlider::NoSnap || snapMode == QQuickSlider::SnapOnRelease) + setPosition(pos); + if (!qFuzzyCompare(pos, oldPos)) + emit q->moved(); +} + +void QQuickSliderPrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickSlider); + QQuickControlPrivate::handleRelease(point); + pressPoint = QPointF(); + const qreal oldPos = position; + qreal pos = positionAt(point); + if (snapMode != QQuickSlider::NoSnap) + pos = snapPosition(pos); + qreal val = q->valueAt(pos); + if (!qFuzzyCompare(val, value)) + q->setValue(val); + else if (snapMode != QQuickSlider::NoSnap) + setPosition(pos); + if (!qFuzzyCompare(pos, oldPos)) + emit q->moved(); + q->setKeepMouseGrab(false); + q->setKeepTouchGrab(false); + q->setPressed(false); +} + +void QQuickSliderPrivate::handleUngrab() +{ + Q_Q(QQuickSlider); + QQuickControlPrivate::handleUngrab(); + pressPoint = QPointF(); + q->setPressed(false); +} + +static inline QString handleName() { return QStringLiteral("handle"); } + +void QQuickSliderPrivate::cancelHandle() +{ + Q_Q(QQuickSlider); + quickCancelDeferred(q, handleName()); +} + +void QQuickSliderPrivate::executeHandle(bool complete) +{ + Q_Q(QQuickSlider); + if (handle.wasExecuted()) + return; + + if (!handle || complete) + quickBeginDeferred(q, handleName(), handle); + if (complete) + quickCompleteDeferred(q, handleName(), handle); +} + +void QQuickSliderPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickSlider); + QQuickControlPrivate::itemImplicitWidthChanged(item); + if (item == handle) + emit q->implicitHandleWidthChanged(); +} + +void QQuickSliderPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickSlider); + QQuickControlPrivate::itemImplicitHeightChanged(item); + if (item == handle) + emit q->implicitHandleHeightChanged(); +} + +QQuickSlider::QQuickSlider(QQuickItem *parent) + : QQuickControl(*(new QQuickSliderPrivate), parent) +{ + setActiveFocusOnTab(true); +#ifdef Q_OS_MACOS + setFocusPolicy(Qt::TabFocus); +#else + setFocusPolicy(Qt::StrongFocus); +#endif + setAcceptedMouseButtons(Qt::LeftButton); +#if QT_CONFIG(quicktemplates2_multitouch) + setAcceptTouchEvents(true); +#endif +#if QT_CONFIG(cursor) + setCursor(Qt::ArrowCursor); +#endif +} + +QQuickSlider::~QQuickSlider() +{ + Q_D(QQuickSlider); + d->removeImplicitSizeListener(d->handle); +} + +/*! + \qmlproperty real QtQuick.Controls::Slider::from + + This property holds the starting value for the range. The default value is \c 0.0. + + \sa to, value +*/ +qreal QQuickSlider::from() const +{ + Q_D(const QQuickSlider); + return d->from; +} + +void QQuickSlider::setFrom(qreal from) +{ + Q_D(QQuickSlider); + if (qFuzzyCompare(d->from, from)) + return; + + d->from = from; + emit fromChanged(); + if (isComponentComplete()) { + setValue(d->value); + d->updatePosition(); + } +} + +/*! + \qmlproperty real QtQuick.Controls::Slider::to + + This property holds the end value for the range. The default value is \c 1.0. + + \sa from, value +*/ +qreal QQuickSlider::to() const +{ + Q_D(const QQuickSlider); + return d->to; +} + +void QQuickSlider::setTo(qreal to) +{ + Q_D(QQuickSlider); + if (qFuzzyCompare(d->to, to)) + return; + + d->to = to; + emit toChanged(); + if (isComponentComplete()) { + setValue(d->value); + d->updatePosition(); + } +} + +/*! + \qmlproperty real QtQuick.Controls::Slider::value + + This property holds the value in the range \c from - \c to. The default value is \c 0.0. + + \sa position +*/ +qreal QQuickSlider::value() const +{ + Q_D(const QQuickSlider); + return d->value; +} + +void QQuickSlider::setValue(qreal value) +{ + Q_D(QQuickSlider); + if (isComponentComplete()) + value = d->from > d->to ? qBound(d->to, value, d->from) : qBound(d->from, value, d->to); + + if (qFuzzyCompare(d->value, value)) + return; + + d->value = value; + d->updatePosition(); + emit valueChanged(); +} + +/*! + \qmlproperty real QtQuick.Controls::Slider::position + \readonly + + This property holds the logical position of the handle. + + The position is expressed as a fraction of the control's size, in the range + \c {0.0 - 1.0}. For visualizing a slider, the right-to-left aware + \l visualPosition should be used instead. + + \sa value, visualPosition, valueAt() +*/ +qreal QQuickSlider::position() const +{ + Q_D(const QQuickSlider); + return d->position; +} + +/*! + \qmlproperty real QtQuick.Controls::Slider::visualPosition + \readonly + + This property holds the visual position of the handle. + + The position is expressed as a fraction of the control's size, in the range + \c {0.0 - 1.0}. When the control is \l {Control::mirrored}{mirrored}, the + value is equal to \c {1.0 - position}. This makes the value suitable for + visualizing the slider, taking right-to-left support into account. + + \sa position +*/ +qreal QQuickSlider::visualPosition() const +{ + Q_D(const QQuickSlider); + if (d->orientation == Qt::Vertical || isMirrored()) + return 1.0 - d->position; + return d->position; +} + +/*! + \qmlproperty real QtQuick.Controls::Slider::stepSize + + This property holds the step size. The default value is \c 0.0. + + \sa snapMode, increase(), decrease() +*/ +qreal QQuickSlider::stepSize() const +{ + Q_D(const QQuickSlider); + return d->stepSize; +} + +void QQuickSlider::setStepSize(qreal step) +{ + Q_D(QQuickSlider); + if (qFuzzyCompare(d->stepSize, step)) + return; + + d->stepSize = step; + emit stepSizeChanged(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::Slider::snapMode + + This property holds the snap mode. + + The snap mode determines how the slider handle behaves with + regards to the \l stepSize. + + Possible values: + \value Slider.NoSnap The slider does not snap (default). + \value Slider.SnapAlways The slider snaps while the handle is dragged. + \value Slider.SnapOnRelease The slider does not snap while being dragged, but only after the handle is released. + + In the following table, the various modes are illustrated with animations. + The movement of the mouse cursor and the \l stepSize (\c 0.2) are identical + in each animation. + + \table + \header + \row \li \b Value \li \b Example + \row \li \c Slider.NoSnap \li \image qtquickcontrols2-slider-nosnap.gif + \row \li \c Slider.SnapAlways \li \image qtquickcontrols2-slider-snapalways.gif + \row \li \c Slider.SnapOnRelease \li \image qtquickcontrols2-slider-snaponrelease.gif + \endtable + + \sa stepSize +*/ +QQuickSlider::SnapMode QQuickSlider::snapMode() const +{ + Q_D(const QQuickSlider); + return d->snapMode; +} + +void QQuickSlider::setSnapMode(SnapMode mode) +{ + Q_D(QQuickSlider); + if (d->snapMode == mode) + return; + + d->snapMode = mode; + emit snapModeChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::Slider::pressed + + This property holds whether the slider is pressed by either touch, mouse, + or keys. +*/ +bool QQuickSlider::isPressed() const +{ + Q_D(const QQuickSlider); + return d->pressed; +} + +void QQuickSlider::setPressed(bool pressed) +{ + Q_D(QQuickSlider); + if (d->pressed == pressed) + return; + + d->pressed = pressed; + setAccessibleProperty("pressed", pressed); + emit pressedChanged(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::Slider::horizontal + \readonly + + This property holds whether the slider is horizontal. + + \sa orientation +*/ +bool QQuickSlider::isHorizontal() const +{ + Q_D(const QQuickSlider); + return d->orientation == Qt::Horizontal; +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::Slider::vertical + \readonly + + This property holds whether the slider is vertical. + + \sa orientation +*/ +bool QQuickSlider::isVertical() const +{ + Q_D(const QQuickSlider); + return d->orientation == Qt::Vertical; +} + +/*! + \qmlproperty enumeration QtQuick.Controls::Slider::orientation + + This property holds the orientation. + + Possible values: + \value Qt.Horizontal Horizontal (default) + \value Qt.Vertical Vertical + + \sa horizontal, vertical +*/ +Qt::Orientation QQuickSlider::orientation() const +{ + Q_D(const QQuickSlider); + return d->orientation; +} + +void QQuickSlider::setOrientation(Qt::Orientation orientation) +{ + Q_D(QQuickSlider); + if (d->orientation == orientation) + return; + + d->orientation = orientation; + emit orientationChanged(); +} + +/*! + \qmlproperty Item QtQuick.Controls::Slider::handle + + This property holds the handle item. + + \sa {Customizing Slider} +*/ +QQuickItem *QQuickSlider::handle() const +{ + QQuickSliderPrivate *d = const_cast<QQuickSliderPrivate *>(d_func()); + if (!d->handle) + d->executeHandle(); + return d->handle; +} + +void QQuickSlider::setHandle(QQuickItem *handle) +{ + Q_D(QQuickSlider); + if (d->handle == handle) + return; + + if (!d->handle.isExecuting()) + d->cancelHandle(); + + const qreal oldImplicitHandleWidth = implicitHandleWidth(); + const qreal oldImplicitHandleHeight = implicitHandleHeight(); + + d->removeImplicitSizeListener(d->handle); + QQuickControlPrivate::hideOldItem(d->handle); + d->handle = handle; + + if (handle) { + if (!handle->parentItem()) + handle->setParentItem(this); + d->addImplicitSizeListener(handle); + } + + if (!qFuzzyCompare(oldImplicitHandleWidth, implicitHandleWidth())) + emit implicitHandleWidthChanged(); + if (!qFuzzyCompare(oldImplicitHandleHeight, implicitHandleHeight())) + emit implicitHandleHeightChanged(); + if (!d->handle.isExecuting()) + emit handleChanged(); +} + +/*! + \since QtQuick.Controls 2.1 (Qt 5.8) + \qmlmethod real QtQuick.Controls::Slider::valueAt(real position) + + Returns the value for the given \a position. + + \sa value, position +*/ +qreal QQuickSlider::valueAt(qreal position) const +{ + Q_D(const QQuickSlider); + const qreal value = (d->to - d->from) * position; + if (qFuzzyIsNull(d->stepSize)) + return d->from + value; + return d->from + qRound(value / d->stepSize) * d->stepSize; +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty bool QtQuick.Controls::Slider::live + + This property holds whether the slider provides live updates for the \l value + property while the handle is dragged. + + The default value is \c true. + + \sa value, valueAt() +*/ +bool QQuickSlider::live() const +{ + Q_D(const QQuickSlider); + return d->live; +} + +void QQuickSlider::setLive(bool live) +{ + Q_D(QQuickSlider); + if (d->live == live) + return; + + d->live = live; + emit liveChanged(); +} + +/*! + \qmlmethod void QtQuick.Controls::Slider::increase() + + Increases the value by \l stepSize or \c 0.1 if stepSize is not defined. + + \sa stepSize +*/ +void QQuickSlider::increase() +{ + Q_D(QQuickSlider); + qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; + setValue(d->value + step); +} + +/*! + \qmlmethod void QtQuick.Controls::Slider::decrease() + + Decreases the value by \l stepSize or \c 0.1 if stepSize is not defined. + + \sa stepSize +*/ +void QQuickSlider::decrease() +{ + Q_D(QQuickSlider); + qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; + setValue(d->value - step); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty qreal QtQuick.Controls::Slider::touchDragThreshold + + This property holds the threshold (in logical pixels) at which a touch drag event will be initiated. + The mouse drag threshold won't be affected. + The default value is \c Qt.styleHints.startDragDistance. + + \sa QStyleHints +*/ +qreal QQuickSlider::touchDragThreshold() const +{ + Q_D(const QQuickSlider); + return d->touchDragThreshold; +} + +void QQuickSlider::setTouchDragThreshold(qreal touchDragThreshold) +{ + Q_D(QQuickSlider); + if (d->touchDragThreshold == touchDragThreshold) + return; + + d->touchDragThreshold = touchDragThreshold; + emit touchDragThresholdChanged(); +} + +void QQuickSlider::resetTouchDragThreshold() +{ + setTouchDragThreshold(-1); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Slider::implicitHandleWidth + \readonly + + This property holds the implicit handle width. + + The value is equal to \c {handle ? handle.implicitWidth : 0}. + + This is typically used, together with \l {Control::}{implicitContentWidth} and + \l {Control::}{implicitBackgroundWidth}, to calculate the \l {Item::}{implicitWidth}. + + \sa implicitHandleHeight +*/ +qreal QQuickSlider::implicitHandleWidth() const +{ + Q_D(const QQuickSlider); + if (!d->handle) + return 0; + return d->handle->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Slider::implicitHandleHeight + \readonly + + This property holds the implicit handle height. + + The value is equal to \c {handle ? handle.implicitHeight : 0}. + + This is typically used, together with \l {Control::}{implicitContentHeight} and + \l {Control::}{implicitBackgroundHeight}, to calculate the \l {Item::}{implicitHeight}. + + \sa implicitHandleWidth +*/ +qreal QQuickSlider::implicitHandleHeight() const +{ + Q_D(const QQuickSlider); + if (!d->handle) + return 0; + return d->handle->implicitHeight(); +} + +void QQuickSlider::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickSlider); + QQuickControl::keyPressEvent(event); + + const qreal oldValue = d->value; + if (d->orientation == Qt::Horizontal) { + if (event->key() == Qt::Key_Left) { + setPressed(true); + if (isMirrored()) + increase(); + else + decrease(); + event->accept(); + } else if (event->key() == Qt::Key_Right) { + setPressed(true); + if (isMirrored()) + decrease(); + else + increase(); + event->accept(); + } + } else { + if (event->key() == Qt::Key_Up) { + setPressed(true); + increase(); + event->accept(); + } else if (event->key() == Qt::Key_Down) { + setPressed(true); + decrease(); + event->accept(); + } + } + if (!qFuzzyCompare(d->value, oldValue)) + emit moved(); +} + +void QQuickSlider::keyReleaseEvent(QKeyEvent *event) +{ + QQuickControl::keyReleaseEvent(event); + setPressed(false); +} + +void QQuickSlider::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickSlider); + QQuickControl::mousePressEvent(event); + d->handleMove(event->position()); + setKeepMouseGrab(true); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickSlider::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickSlider); + switch (event->type()) { + case QEvent::TouchUpdate: + for (const QTouchEvent::TouchPoint &point : event->points()) { + if (!d->acceptTouch(point)) + continue; + + switch (point.state()) { + case QEventPoint::Pressed: + d->handlePress(point.position()); + break; + case QEventPoint::Updated: + if (!keepTouchGrab()) { + if (d->orientation == Qt::Horizontal) + setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().x() - d->pressPoint.x(), Qt::XAxis, &point, qRound(d->touchDragThreshold))); + else + setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().y() - d->pressPoint.y(), Qt::YAxis, &point, qRound(d->touchDragThreshold))); + } + if (keepTouchGrab()) + d->handleMove(point.position()); + break; + case QEventPoint::Released: + d->handleRelease(point.position()); + break; + default: + break; + } + } + break; + + default: + QQuickControl::touchEvent(event); + break; + } +} +#endif + +#if QT_CONFIG(wheelevent) +void QQuickSlider::wheelEvent(QWheelEvent *event) +{ + Q_D(QQuickSlider); + QQuickControl::wheelEvent(event); + if (d->wheelEnabled) { + const qreal oldValue = d->value; + const QPointF angle = event->angleDelta(); + const qreal delta = (qFuzzyIsNull(angle.y()) ? angle.x() : (event->inverted() ? -angle.y() : angle.y())) / int(QWheelEvent::DefaultDeltasPerStep); + const qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize; + setValue(oldValue + step * delta); + const bool wasMoved = !qFuzzyCompare(d->value, oldValue); + if (wasMoved) + emit moved(); + } +} +#endif + +void QQuickSlider::mirrorChange() +{ + QQuickControl::mirrorChange(); + emit visualPositionChanged(); +} + +void QQuickSlider::componentComplete() +{ + Q_D(QQuickSlider); + d->executeHandle(true); + QQuickControl::componentComplete(); + setValue(d->value); + d->updatePosition(); +} + +#if QT_CONFIG(accessibility) +void QQuickSlider::accessibilityActiveChanged(bool active) +{ + QQuickControl::accessibilityActiveChanged(active); + + Q_D(QQuickSlider); + if (active) + setAccessibleProperty("pressed", d->pressed); +} + +QAccessible::Role QQuickSlider::accessibleRole() const +{ + return QAccessible::Slider; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickslider_p.cpp" diff --git a/src/quicktemplates2/qquickslider_p.h b/src/quicktemplates2/qquickslider_p.h new file mode 100644 index 00000000000..ac03f7f9964 --- /dev/null +++ b/src/quicktemplates2/qquickslider_p.h @@ -0,0 +1,190 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSLIDER_P_H +#define QQUICKSLIDER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickSliderPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSlider : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged FINAL) + Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged FINAL) + Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged FINAL) + Q_PROPERTY(qreal position READ position NOTIFY positionChanged FINAL) + Q_PROPERTY(qreal visualPosition READ visualPosition NOTIFY visualPositionChanged FINAL) + Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged FINAL) + Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged FINAL) + Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL) + Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL) + Q_PROPERTY(QQuickItem *handle READ handle WRITE setHandle NOTIFY handleChanged FINAL) + Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION(2, 2)) + // 2.3 (Qt 5.10) + Q_PROPERTY(bool horizontal READ isHorizontal NOTIFY orientationChanged FINAL REVISION(2, 3)) + Q_PROPERTY(bool vertical READ isVertical NOTIFY orientationChanged FINAL REVISION(2, 3)) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal touchDragThreshold READ touchDragThreshold WRITE setTouchDragThreshold RESET resetTouchDragThreshold NOTIFY touchDragThresholdChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitHandleWidth READ implicitHandleWidth NOTIFY implicitHandleWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitHandleHeight READ implicitHandleHeight NOTIFY implicitHandleHeightChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DeferredPropertyNames", "background,handle") + QML_NAMED_ELEMENT(Slider) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickSlider(QQuickItem *parent = nullptr); + ~QQuickSlider(); + + qreal from() const; + void setFrom(qreal from); + + qreal to() const; + void setTo(qreal to); + + qreal value() const; + void setValue(qreal value); + + qreal position() const; + qreal visualPosition() const; + + qreal stepSize() const; + void setStepSize(qreal step); + + enum SnapMode { + NoSnap, + SnapAlways, + SnapOnRelease + }; + Q_ENUM(SnapMode) + + SnapMode snapMode() const; + void setSnapMode(SnapMode mode); + + bool isPressed() const; + void setPressed(bool pressed); + + Qt::Orientation orientation() const; + void setOrientation(Qt::Orientation orientation); + + QQuickItem *handle() const; + void setHandle(QQuickItem *handle); + + // 2.1 (Qt 5.8) + Q_REVISION(2, 1) Q_INVOKABLE qreal valueAt(qreal position) const; + + // 2.2 (Qt 5.9) + bool live() const; + void setLive(bool live); + + // 2.3 (Qt 5.10) + bool isHorizontal() const; + bool isVertical() const; + + // 2.5 (Qt 5.12) + qreal touchDragThreshold() const; + void setTouchDragThreshold(qreal touchDragThreshold); + void resetTouchDragThreshold(); + + qreal implicitHandleWidth() const; + qreal implicitHandleHeight() const; + +public Q_SLOTS: + void increase(); + void decrease(); + +Q_SIGNALS: + void fromChanged(); + void toChanged(); + void valueChanged(); + void positionChanged(); + void visualPositionChanged(); + void stepSizeChanged(); + void snapModeChanged(); + void pressedChanged(); + void orientationChanged(); + void handleChanged(); + // 2.2 (Qt 5.9) + Q_REVISION(2, 2) void moved(); + Q_REVISION(2, 2) void liveChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void touchDragThresholdChanged(); + Q_REVISION(2, 5) void implicitHandleWidthChanged(); + Q_REVISION(2, 5) void implicitHandleHeightChanged(); + +protected: + void keyPressEvent(QKeyEvent *event) override; + void keyReleaseEvent(QKeyEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif +#if QT_CONFIG(wheelevent) + void wheelEvent(QWheelEvent *event) override; +#endif + + void mirrorChange() override; + void componentComplete() override; + +#if QT_CONFIG(accessibility) + void accessibilityActiveChanged(bool active) override; + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickSlider) + Q_DECLARE_PRIVATE(QQuickSlider) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickSlider) + +#endif // QQUICKSLIDER_P_H diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp new file mode 100644 index 00000000000..f0d34c3659c --- /dev/null +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -0,0 +1,1064 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickspinbox_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickindicatorbutton_p.h" +#include "qquickdeferredexecute_p_p.h" + +#include <QtGui/qguiapplication.h> +#include <QtGui/qstylehints.h> + +#include <QtQml/qqmlinfo.h> +#include <QtQml/private/qqmllocale_p.h> +#include <QtQml/private/qqmlengine_p.h> +#include <QtQuick/private/qquicktextinput_p.h> + +QT_BEGIN_NAMESPACE + +// copied from qabstractbutton.cpp +static const int AUTO_REPEAT_DELAY = 300; +static const int AUTO_REPEAT_INTERVAL = 100; + +/*! + \qmltype SpinBox + \inherits Control +//! \instantiates QQuickSpinBox + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup input + \ingroup qtquickcontrols2-focusscopes + \brief Allows the user to select from a set of preset values. + + \image qtquickcontrols2-spinbox.png + + SpinBox allows the user to choose an integer value by clicking the up + or down indicator buttons, or by pressing up or down on the keyboard. + Optionally, SpinBox can be also made \l editable, so the user can enter + a text value in the input field. + + By default, SpinBox provides discrete values in the range of \c [0-99] + with a \l stepSize of \c 1. + + \snippet qtquickcontrols2-spinbox.qml 1 + + \section2 Custom Values + + \image qtquickcontrols2-spinbox-textual.png + + Even though SpinBox works on integer values, it can be customized to + accept arbitrary input values. The following snippet demonstrates how + \l validator, \l textFromValue and \l valueFromText can be used to + customize the default behavior. + + \snippet qtquickcontrols2-spinbox-textual.qml 1 + + In the same manner, SpinBox can be customized to accept floating point + numbers: + + \image qtquickcontrols2-spinbox-double.png + + \snippet qtquickcontrols2-spinbox-double.qml 1 + + \sa Tumbler, {Customizing SpinBox}, {Focus Management in Qt Quick Controls} +*/ + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlsignal QtQuick.Controls::SpinBox::valueModified() + + This signal is emitted when the spin box value has been interactively + modified by the user by either touch, mouse, wheel, or keys. + In the case of interaction via keyboard, the signal is only emitted + when the text has been accepted; meaning when the enter or return keys + are pressed, or the input field loses focus. +*/ + +class QQuickSpinBoxPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickSpinBox) + +public: + int boundValue(int value, bool wrap) const; + void updateValue(); + bool setValue(int value, bool wrap, bool modified); + bool stepBy(int steps, bool modified); + void increase(bool modified); + void decrease(bool modified); + + int effectiveStepSize() const; + + void updateDisplayText(bool modified = false); + void setDisplayText(const QString &displayText, bool modified = false); + + bool upEnabled() const; + void updateUpEnabled(); + bool downEnabled() const; + void updateDownEnabled(); + void updateHover(const QPointF &pos); + + void startRepeatDelay(); + void startPressRepeat(); + void stopPressRepeat(); + + void handlePress(const QPointF &point) override; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + void handleUngrab() override; + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::SpinBox); } + + bool editable = false; + bool wrap = false; + int from = 0; + int to = 99; + int value = 0; + int stepSize = 1; + int delayTimer = 0; + int repeatTimer = 0; + QString displayText; + QQuickIndicatorButton *up = nullptr; + QQuickIndicatorButton *down = nullptr; + QValidator *validator = nullptr; + mutable QJSValue textFromValue; + mutable QJSValue valueFromText; + Qt::InputMethodHints inputMethodHints = Qt::ImhDigitsOnly; +}; + +int QQuickSpinBoxPrivate::boundValue(int value, bool wrap) const +{ + bool inverted = from > to; + if (!wrap) + return inverted ? qBound(to, value, from) : qBound(from, value, to); + + int f = inverted ? to : from; + int t = inverted ? from : to; + if (value < f) + value = t; + else if (value > t) + value = f; + + return value; +} + +void QQuickSpinBoxPrivate::updateValue() +{ + Q_Q(QQuickSpinBox); + if (contentItem) { + QVariant text = contentItem->property("text"); + if (text.isValid()) { + int val = 0; + QQmlEngine *engine = qmlEngine(q); + if (engine && valueFromText.isCallable()) { + QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine); + QJSValue loc = QJSValuePrivate::fromReturnedValue(QQmlLocale::wrap(v4, locale)); + val = valueFromText.call(QJSValueList() << text.toString() << loc).toInt(); + } else { + val = locale.toInt(text.toString()); + } + setValue(val, /* allowWrap = */ false, /* modified = */ true); + } + } +} + +// modified indicates if the value was modified by the user and not programatically +// this is then passed on to updateDisplayText to indicate that the user has modified +// the value so it may need to trigger an update of the contentItem's text too + +bool QQuickSpinBoxPrivate::setValue(int newValue, bool allowWrap, bool modified) +{ + Q_Q(QQuickSpinBox); + int correctedValue = newValue; + if (q->isComponentComplete()) + correctedValue = boundValue(newValue, allowWrap); + + if (!modified && newValue == correctedValue && newValue == value) + return false; + + const bool emitSignals = (value != correctedValue); + value = correctedValue; + + updateDisplayText(modified); + updateUpEnabled(); + updateDownEnabled(); + + // Only emit the signals if the corrected value is not the same as the + // original value to avoid unnecessary updates + if (emitSignals) { + emit q->valueChanged(); + if (modified) + emit q->valueModified(); + } + return true; +} + +bool QQuickSpinBoxPrivate::stepBy(int steps, bool modified) +{ + return setValue(value + steps, wrap, modified); +} + +void QQuickSpinBoxPrivate::increase(bool modified) +{ + setValue(value + effectiveStepSize(), wrap, modified); +} + +void QQuickSpinBoxPrivate::decrease(bool modified) +{ + setValue(value - effectiveStepSize(), wrap, modified); +} + +int QQuickSpinBoxPrivate::effectiveStepSize() const +{ + return from > to ? -1 * stepSize : stepSize; +} + +void QQuickSpinBoxPrivate::updateDisplayText(bool modified) +{ + Q_Q(QQuickSpinBox); + QString text; + QQmlEngine *engine = qmlEngine(q); + if (engine && textFromValue.isCallable()) { + QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine); + QJSValue loc = QJSValuePrivate::fromReturnedValue(QQmlLocale::wrap(v4, locale)); + text = textFromValue.call(QJSValueList() << value << loc).toString(); + } else { + text = locale.toString(value); + } + setDisplayText(text, modified); +} + +void QQuickSpinBoxPrivate::setDisplayText(const QString &text, bool modified) +{ + Q_Q(QQuickSpinBox); + + if (!modified && displayText == text) + return; + + displayText = text; + emit q->displayTextChanged(); +} + +bool QQuickSpinBoxPrivate::upEnabled() const +{ + const QQuickItem *upIndicator = up->indicator(); + return upIndicator && upIndicator->isEnabled(); +} + +void QQuickSpinBoxPrivate::updateUpEnabled() +{ + QQuickItem *upIndicator = up->indicator(); + if (!upIndicator) + return; + + upIndicator->setEnabled(wrap || (from < to ? value < to : value > to)); +} + +bool QQuickSpinBoxPrivate::downEnabled() const +{ + const QQuickItem *downIndicator = down->indicator(); + return downIndicator && downIndicator->isEnabled(); +} + +void QQuickSpinBoxPrivate::updateDownEnabled() +{ + QQuickItem *downIndicator = down->indicator(); + if (!downIndicator) + return; + + downIndicator->setEnabled(wrap || (from < to ? value > from : value < from)); +} + +void QQuickSpinBoxPrivate::updateHover(const QPointF &pos) +{ + Q_Q(QQuickSpinBox); + QQuickItem *ui = up->indicator(); + QQuickItem *di = down->indicator(); + up->setHovered(ui && ui->isEnabled() && ui->contains(q->mapToItem(ui, pos))); + down->setHovered(di && di->isEnabled() && di->contains(q->mapToItem(di, pos))); +} + +void QQuickSpinBoxPrivate::startRepeatDelay() +{ + Q_Q(QQuickSpinBox); + stopPressRepeat(); + delayTimer = q->startTimer(AUTO_REPEAT_DELAY); +} + +void QQuickSpinBoxPrivate::startPressRepeat() +{ + Q_Q(QQuickSpinBox); + stopPressRepeat(); + repeatTimer = q->startTimer(AUTO_REPEAT_INTERVAL); +} + +void QQuickSpinBoxPrivate::stopPressRepeat() +{ + Q_Q(QQuickSpinBox); + if (delayTimer > 0) { + q->killTimer(delayTimer); + delayTimer = 0; + } + if (repeatTimer > 0) { + q->killTimer(repeatTimer); + repeatTimer = 0; + } +} + +void QQuickSpinBoxPrivate::handlePress(const QPointF &point) +{ + Q_Q(QQuickSpinBox); + QQuickControlPrivate::handlePress(point); + QQuickItem *ui = up->indicator(); + QQuickItem *di = down->indicator(); + up->setPressed(ui && ui->isEnabled() && ui->contains(ui->mapFromItem(q, point))); + down->setPressed(di && di->isEnabled() && di->contains(di->mapFromItem(q, point))); + + bool pressed = up->isPressed() || down->isPressed(); + q->setAccessibleProperty("pressed", pressed); + if (pressed) + startRepeatDelay(); +} + +void QQuickSpinBoxPrivate::handleMove(const QPointF &point) +{ + Q_Q(QQuickSpinBox); + QQuickControlPrivate::handleMove(point); + QQuickItem *ui = up->indicator(); + QQuickItem *di = down->indicator(); + up->setHovered(ui && ui->isEnabled() && ui->contains(ui->mapFromItem(q, point))); + up->setPressed(up->isHovered()); + down->setHovered(di && di->isEnabled() && di->contains(di->mapFromItem(q, point))); + down->setPressed(down->isHovered()); + + bool pressed = up->isPressed() || down->isPressed(); + q->setAccessibleProperty("pressed", pressed); + if (!pressed) + stopPressRepeat(); +} + +void QQuickSpinBoxPrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickSpinBox); + QQuickControlPrivate::handleRelease(point); + QQuickItem *ui = up->indicator(); + QQuickItem *di = down->indicator(); + + int oldValue = value; + if (up->isPressed()) { + up->setPressed(false); + if (repeatTimer <= 0 && ui && ui->contains(ui->mapFromItem(q, point))) + q->increase(); + } else if (down->isPressed()) { + down->setPressed(false); + if (repeatTimer <= 0 && di && di->contains(di->mapFromItem(q, point))) + q->decrease(); + } + if (value != oldValue) + emit q->valueModified(); + + q->setAccessibleProperty("pressed", false); + stopPressRepeat(); +} + +void QQuickSpinBoxPrivate::handleUngrab() +{ + Q_Q(QQuickSpinBox); + QQuickControlPrivate::handleUngrab(); + up->setPressed(false); + down->setPressed(false); + + q->setAccessibleProperty("pressed", false); + stopPressRepeat(); +} + +void QQuickSpinBoxPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + QQuickControlPrivate::itemImplicitWidthChanged(item); + if (item == up->indicator()) + emit up->implicitIndicatorWidthChanged(); + else if (item == down->indicator()) + emit down->implicitIndicatorWidthChanged(); +} + +void QQuickSpinBoxPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + QQuickControlPrivate::itemImplicitHeightChanged(item); + if (item == up->indicator()) + emit up->implicitIndicatorHeightChanged(); + else if (item == down->indicator()) + emit down->implicitIndicatorHeightChanged(); +} + +QQuickSpinBox::QQuickSpinBox(QQuickItem *parent) + : QQuickControl(*(new QQuickSpinBoxPrivate), parent) +{ + Q_D(QQuickSpinBox); + d->up = new QQuickIndicatorButton(this); + d->down = new QQuickIndicatorButton(this); + + setFlag(ItemIsFocusScope); + setFiltersChildMouseEvents(true); + setAcceptedMouseButtons(Qt::LeftButton); +#if QT_CONFIG(cursor) + setCursor(Qt::ArrowCursor); +#endif +} + +QQuickSpinBox::~QQuickSpinBox() +{ + Q_D(QQuickSpinBox); + d->removeImplicitSizeListener(d->up->indicator()); + d->removeImplicitSizeListener(d->down->indicator()); +} + +/*! + \qmlproperty int QtQuick.Controls::SpinBox::from + + This property holds the starting value for the range. The default value is \c 0. + + \sa to, value +*/ +int QQuickSpinBox::from() const +{ + Q_D(const QQuickSpinBox); + return d->from; +} + +void QQuickSpinBox::setFrom(int from) +{ + Q_D(QQuickSpinBox); + if (d->from == from) + return; + + d->from = from; + emit fromChanged(); + if (isComponentComplete()) { + if (!d->setValue(d->value, /* allowWrap = */ false, /* modified = */ false)) { + d->updateUpEnabled(); + d->updateDownEnabled(); + } + } +} + +/*! + \qmlproperty int QtQuick.Controls::SpinBox::to + + This property holds the end value for the range. The default value is \c 99. + + \sa from, value +*/ +int QQuickSpinBox::to() const +{ + Q_D(const QQuickSpinBox); + return d->to; +} + +void QQuickSpinBox::setTo(int to) +{ + Q_D(QQuickSpinBox); + if (d->to == to) + return; + + d->to = to; + emit toChanged(); + if (isComponentComplete()) { + if (!d->setValue(d->value, /* allowWrap = */false, /* modified = */ false)) { + d->updateUpEnabled(); + d->updateDownEnabled(); + } + } +} + +/*! + \qmlproperty int QtQuick.Controls::SpinBox::value + + This property holds the value in the range \c from - \c to. The default value is \c 0. +*/ +int QQuickSpinBox::value() const +{ + Q_D(const QQuickSpinBox); + return d->value; +} + +void QQuickSpinBox::setValue(int value) +{ + Q_D(QQuickSpinBox); + d->setValue(value, /* allowWrap = */ false, /* modified = */ false); +} + +/*! + \qmlproperty int QtQuick.Controls::SpinBox::stepSize + + This property holds the step size. The default value is \c 1. + + \sa increase(), decrease() +*/ +int QQuickSpinBox::stepSize() const +{ + Q_D(const QQuickSpinBox); + return d->stepSize; +} + +void QQuickSpinBox::setStepSize(int step) +{ + Q_D(QQuickSpinBox); + if (d->stepSize == step) + return; + + d->stepSize = step; + emit stepSizeChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::SpinBox::editable + + This property holds whether the spinbox is editable. The default value is \c false. + + \sa validator +*/ +bool QQuickSpinBox::isEditable() const +{ + Q_D(const QQuickSpinBox); + return d->editable; +} + +void QQuickSpinBox::setEditable(bool editable) +{ + Q_D(QQuickSpinBox); + if (d->editable == editable) + return; + +#if QT_CONFIG(cursor) + if (d->contentItem) { + if (editable) + d->contentItem->setCursor(Qt::IBeamCursor); + else + d->contentItem->unsetCursor(); + } +#endif + + d->editable = editable; + setAccessibleProperty("editable", editable); + emit editableChanged(); +} + +/*! + \qmlproperty Validator QtQuick.Controls::SpinBox::validator + + This property holds the input text validator for editable spinboxes. By + default, SpinBox uses \l IntValidator to accept input of integer numbers. + + \code + SpinBox { + id: control + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + } + \endcode + + \sa editable, textFromValue, valueFromText, {Control::locale}{locale}, + {Validating Input Text} +*/ +QValidator *QQuickSpinBox::validator() const +{ + Q_D(const QQuickSpinBox); + return d->validator; +} + +void QQuickSpinBox::setValidator(QValidator *validator) +{ + Q_D(QQuickSpinBox); + if (d->validator == validator) + return; + + d->validator = validator; + emit validatorChanged(); +} + +/*! + \qmlproperty function QtQuick.Controls::SpinBox::textFromValue + + This property holds a callback function that is called whenever + an integer value needs to be converted to display text. + + The default function can be overridden to display custom text for a given + value. This applies to both editable and non-editable spinboxes; + for example, when using the up and down buttons or a mouse wheel to + increment and decrement the value, the new value is converted to display + text using this function. + + The callback function signature is \c {string function(value, locale)}. + The function can have one or two arguments, where the first argument + is the value to be converted, and the optional second argument is the + locale that should be used for the conversion, if applicable. + + The default implementation does the conversion using + \l {QtQml::Number::toLocaleString()}{Number.toLocaleString}(): + + \code + textFromValue: function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); } + \endcode + + \note When applying a custom \c textFromValue implementation for editable + spinboxes, a matching \l valueFromText implementation must be provided + to be able to convert the custom text back to an integer value. + + \sa valueFromText, validator, {Control::locale}{locale} +*/ +QJSValue QQuickSpinBox::textFromValue() const +{ + Q_D(const QQuickSpinBox); + if (!d->textFromValue.isCallable()) { + QQmlEngine *engine = qmlEngine(this); + if (engine) + d->textFromValue = engine->evaluate(QStringLiteral("(function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); })")); + } + return d->textFromValue; +} + +void QQuickSpinBox::setTextFromValue(const QJSValue &callback) +{ + Q_D(QQuickSpinBox); + if (!callback.isCallable()) { + qmlWarning(this) << "textFromValue must be a callable function"; + return; + } + d->textFromValue = callback; + emit textFromValueChanged(); +} + +/*! + \qmlproperty function QtQuick.Controls::SpinBox::valueFromText + + This property holds a callback function that is called whenever + input text needs to be converted to an integer value. + + This function only needs to be overridden when \l textFromValue + is overridden for an editable spinbox. + + The callback function signature is \c {int function(text, locale)}. + The function can have one or two arguments, where the first argument + is the text to be converted, and the optional second argument is the + locale that should be used for the conversion, if applicable. + + The default implementation does the conversion using \l {QtQml::Locale}{Number.fromLocaleString()}: + + \code + valueFromText: function(text, locale) { return Number.fromLocaleString(locale, text); } + \endcode + + \note When applying a custom \l textFromValue implementation for editable + spinboxes, a matching \c valueFromText implementation must be provided + to be able to convert the custom text back to an integer value. + + \sa textFromValue, validator, {Control::locale}{locale} +*/ +QJSValue QQuickSpinBox::valueFromText() const +{ + Q_D(const QQuickSpinBox); + if (!d->valueFromText.isCallable()) { + QQmlEngine *engine = qmlEngine(this); + if (engine) + d->valueFromText = engine->evaluate(QStringLiteral("(function(text, locale) { return Number.fromLocaleString(locale, text); })")); + } + return d->valueFromText; +} + +void QQuickSpinBox::setValueFromText(const QJSValue &callback) +{ + Q_D(QQuickSpinBox); + if (!callback.isCallable()) { + qmlWarning(this) << "valueFromText must be a callable function"; + return; + } + d->valueFromText = callback; + emit valueFromTextChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::SpinBox::up.pressed + \qmlproperty Item QtQuick.Controls::SpinBox::up.indicator + \qmlproperty bool QtQuick.Controls::SpinBox::up.hovered + \qmlproperty real QtQuick.Controls::SpinBox::up.implicitIndicatorWidth + \qmlproperty real QtQuick.Controls::SpinBox::up.implicitIndicatorHeight + + These properties hold the up indicator item and whether it is pressed or + hovered. The \c up.hovered property was introduced in QtQuick.Controls 2.1, + and the \c up.implicitIndicatorWidth and \c up.implicitIndicatorHeight + properties were introduced in QtQuick.Controls 2.5. + + \sa increase() +*/ +QQuickIndicatorButton *QQuickSpinBox::up() const +{ + Q_D(const QQuickSpinBox); + return d->up; +} + +/*! + \qmlproperty bool QtQuick.Controls::SpinBox::down.pressed + \qmlproperty Item QtQuick.Controls::SpinBox::down.indicator + \qmlproperty bool QtQuick.Controls::SpinBox::down.hovered + \qmlproperty real QtQuick.Controls::SpinBox::down.implicitIndicatorWidth + \qmlproperty real QtQuick.Controls::SpinBox::down.implicitIndicatorHeight + + These properties hold the down indicator item and whether it is pressed or + hovered. The \c down.hovered property was introduced in QtQuick.Controls 2.1, + and the \c down.implicitIndicatorWidth and \c down.implicitIndicatorHeight + properties were introduced in QtQuick.Controls 2.5. + + \sa decrease() +*/ +QQuickIndicatorButton *QQuickSpinBox::down() const +{ + Q_D(const QQuickSpinBox); + return d->down; +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty flags QtQuick.Controls::SpinBox::inputMethodHints + + This property provides hints to the input method about the expected content + of the spin box and how it should operate. + + The default value is \c Qt.ImhDigitsOnly. + + \include inputmethodhints.qdocinc +*/ +Qt::InputMethodHints QQuickSpinBox::inputMethodHints() const +{ + Q_D(const QQuickSpinBox); + return d->inputMethodHints; +} + +void QQuickSpinBox::setInputMethodHints(Qt::InputMethodHints hints) +{ + Q_D(QQuickSpinBox); + if (d->inputMethodHints == hints) + return; + + d->inputMethodHints = hints; + emit inputMethodHintsChanged(); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty bool QtQuick.Controls::SpinBox::inputMethodComposing + \readonly + + This property holds whether an editable spin box has partial text input from an input method. + + While it is composing, an input method may rely on mouse or key events from the spin box to + edit or commit the partial text. This property can be used to determine when to disable event + handlers that may interfere with the correct operation of an input method. +*/ +bool QQuickSpinBox::isInputMethodComposing() const +{ + Q_D(const QQuickSpinBox); + return d->contentItem && d->contentItem->property("inputMethodComposing").toBool(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::SpinBox::wrap + + This property holds whether the spinbox wraps. The default value is \c false. + + If wrap is \c true, stepping past \l to changes the value to \l from and vice versa. +*/ +bool QQuickSpinBox::wrap() const +{ + Q_D(const QQuickSpinBox); + return d->wrap; +} + +void QQuickSpinBox::setWrap(bool wrap) +{ + Q_D(QQuickSpinBox); + if (d->wrap == wrap) + return; + + d->wrap = wrap; + if (d->value == d->from || d->value == d->to) { + d->updateUpEnabled(); + d->updateDownEnabled(); + } + emit wrapChanged(); +} + +/*! + \since QtQuick.Controls 2.4 (Qt 5.11) + \qmlproperty string QtQuick.Controls::SpinBox::displayText + \readonly + + This property holds the textual value of the spinbox. + + The value of the property is based on \l textFromValue and \l {Control::} + {locale}, and equal to: + \badcode + var text = spinBox.textFromValue(spinBox.value, spinBox.locale) + \endcode + + \sa textFromValue +*/ +QString QQuickSpinBox::displayText() const +{ + Q_D(const QQuickSpinBox); + return d->displayText; +} + +/*! + \qmlmethod void QtQuick.Controls::SpinBox::increase() + + Increases the value by \l stepSize, or \c 1 if stepSize is not defined. + + \sa stepSize +*/ +void QQuickSpinBox::increase() +{ + Q_D(QQuickSpinBox); + d->increase(false); +} + +/*! + \qmlmethod void QtQuick.Controls::SpinBox::decrease() + + Decreases the value by \l stepSize, or \c 1 if stepSize is not defined. + + \sa stepSize +*/ +void QQuickSpinBox::decrease() +{ + Q_D(QQuickSpinBox); + d->decrease(false); +} + +void QQuickSpinBox::focusInEvent(QFocusEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::focusInEvent(event); + + // When an editable SpinBox gets focus, it must pass on the focus to its editor. + if (d->editable && d->contentItem && !d->contentItem->hasActiveFocus()) + d->contentItem->forceActiveFocus(event->reason()); +} + +void QQuickSpinBox::hoverEnterEvent(QHoverEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::hoverEnterEvent(event); + d->updateHover(event->position()); + event->ignore(); +} + +void QQuickSpinBox::hoverMoveEvent(QHoverEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::hoverMoveEvent(event); + d->updateHover(event->position()); + event->ignore(); +} + +void QQuickSpinBox::hoverLeaveEvent(QHoverEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::hoverLeaveEvent(event); + d->down->setHovered(false); + d->up->setHovered(false); + event->ignore(); +} + +void QQuickSpinBox::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::keyPressEvent(event); + + switch (event->key()) { + case Qt::Key_Up: + if (d->upEnabled()) { + d->increase(true); + d->up->setPressed(true); + event->accept(); + } + break; + + case Qt::Key_Down: + if (d->downEnabled()) { + d->decrease(true); + d->down->setPressed(true); + event->accept(); + } + break; + + default: + break; + } + + setAccessibleProperty("pressed", d->up->isPressed() || d->down->isPressed()); +} + +void QQuickSpinBox::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::keyReleaseEvent(event); + + if (d->editable && (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)) + d->updateValue(); + + d->up->setPressed(false); + d->down->setPressed(false); + setAccessibleProperty("pressed", false); +} + +void QQuickSpinBox::timerEvent(QTimerEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::timerEvent(event); + if (event->timerId() == d->delayTimer) { + d->startPressRepeat(); + } else if (event->timerId() == d->repeatTimer) { + if (d->up->isPressed()) + d->increase(true); + else if (d->down->isPressed()) + d->decrease(true); + } +} + +#if QT_CONFIG(wheelevent) +void QQuickSpinBox::wheelEvent(QWheelEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::wheelEvent(event); + if (d->wheelEnabled) { + const QPointF angle = event->angleDelta(); + const qreal delta = (qFuzzyIsNull(angle.y()) ? angle.x() : angle.y()) / int(QWheelEvent::DefaultDeltasPerStep); + d->stepBy(qRound(d->effectiveStepSize() * delta), true); + } +} +#endif + +void QQuickSpinBox::classBegin() +{ + Q_D(QQuickSpinBox); + QQuickControl::classBegin(); + + QQmlContext *context = qmlContext(this); + if (context) { + QQmlEngine::setContextForObject(d->up, context); + QQmlEngine::setContextForObject(d->down, context); + } +} + +void QQuickSpinBox::componentComplete() +{ + Q_D(QQuickSpinBox); + QQuickIndicatorButtonPrivate::get(d->up)->executeIndicator(true); + QQuickIndicatorButtonPrivate::get(d->down)->executeIndicator(true); + + QQuickControl::componentComplete(); + if (!d->setValue(d->value, /* allowWrap = */ false, /* modified = */ false)) { + d->updateDisplayText(); + d->updateUpEnabled(); + d->updateDownEnabled(); + } +} + +void QQuickSpinBox::itemChange(ItemChange change, const ItemChangeData &value) +{ + Q_D(QQuickSpinBox); + QQuickControl::itemChange(change, value); + if (d->editable && change == ItemActiveFocusHasChanged && !value.boolValue) + d->updateValue(); +} + +void QQuickSpinBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + Q_D(QQuickSpinBox); + if (QQuickTextInput *oldInput = qobject_cast<QQuickTextInput *>(oldItem)) + disconnect(oldInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickSpinBox::inputMethodComposingChanged); + + if (newItem) { + newItem->setActiveFocusOnTab(true); + if (d->activeFocus) + newItem->forceActiveFocus(d->focusReason); +#if QT_CONFIG(cursor) + if (d->editable) + newItem->setCursor(Qt::IBeamCursor); +#endif + + if (QQuickTextInput *newInput = qobject_cast<QQuickTextInput *>(newItem)) + connect(newInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickSpinBox::inputMethodComposingChanged); + } +} + +void QQuickSpinBox::localeChange(const QLocale &newLocale, const QLocale &oldLocale) +{ + Q_D(QQuickSpinBox); + QQuickControl::localeChange(newLocale, oldLocale); + d->updateDisplayText(); +} + +QFont QQuickSpinBox::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::SpinBox); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickSpinBox::accessibleRole() const +{ + return QAccessible::SpinBox; +} + +void QQuickSpinBox::accessibilityActiveChanged(bool active) +{ + Q_D(QQuickSpinBox); + QQuickControl::accessibilityActiveChanged(active); + + if (active) + setAccessibleProperty("editable", d->editable); +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickspinbox_p.cpp" diff --git a/src/quicktemplates2/qquickspinbox_p.h b/src/quicktemplates2/qquickspinbox_p.h new file mode 100644 index 00000000000..9e64e96e327 --- /dev/null +++ b/src/quicktemplates2/qquickspinbox_p.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSPINBOX_P_H +#define QQUICKSPINBOX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQml/qjsvalue.h> + +QT_BEGIN_NAMESPACE + +class QValidator; +class QQuickSpinBoxPrivate; +class QQuickIndicatorButton; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSpinBox : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(int from READ from WRITE setFrom NOTIFY fromChanged FINAL) + Q_PROPERTY(int to READ to WRITE setTo NOTIFY toChanged FINAL) + Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged FINAL) + Q_PROPERTY(int stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged FINAL) + Q_PROPERTY(bool editable READ isEditable WRITE setEditable NOTIFY editableChanged FINAL) + Q_PROPERTY(QValidator *validator READ validator WRITE setValidator NOTIFY validatorChanged FINAL) + Q_PROPERTY(QJSValue textFromValue READ textFromValue WRITE setTextFromValue NOTIFY textFromValueChanged FINAL) + Q_PROPERTY(QJSValue valueFromText READ valueFromText WRITE setValueFromText NOTIFY valueFromTextChanged FINAL) + Q_PROPERTY(QQuickIndicatorButton *up READ up CONSTANT FINAL) + Q_PROPERTY(QQuickIndicatorButton *down READ down CONSTANT FINAL) + // 2.2 (Qt 5.9) + Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints NOTIFY inputMethodHintsChanged FINAL REVISION(2, 2)) + Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged FINAL REVISION(2, 2)) + // 2.3 (Qt 5.10) + Q_PROPERTY(bool wrap READ wrap WRITE setWrap NOTIFY wrapChanged FINAL REVISION(2, 3)) + // 2.4 (Qt 5.11) + Q_PROPERTY(QString displayText READ displayText NOTIFY displayTextChanged FINAL REVISION(2, 4)) + QML_NAMED_ELEMENT(SpinBox) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickSpinBox(QQuickItem *parent = nullptr); + ~QQuickSpinBox(); + + int from() const; + void setFrom(int from); + + int to() const; + void setTo(int to); + + int value() const; + void setValue(int value); + + int stepSize() const; + void setStepSize(int step); + + bool isEditable() const; + void setEditable(bool editable); + + QValidator *validator() const; + void setValidator(QValidator *validator); + + QJSValue textFromValue() const; + void setTextFromValue(const QJSValue &callback); + + QJSValue valueFromText() const; + void setValueFromText(const QJSValue &callback); + + QQuickIndicatorButton *up() const; + QQuickIndicatorButton *down() const; + + // 2.2 (Qt 5.9) + Qt::InputMethodHints inputMethodHints() const; + void setInputMethodHints(Qt::InputMethodHints hints); + + bool isInputMethodComposing() const; + + // 2.3 (Qt 5.10) + bool wrap() const; + void setWrap(bool wrap); + + // 2.4 (Qt 5.11) + QString displayText() const; + +public Q_SLOTS: + void increase(); + void decrease(); + +Q_SIGNALS: + void fromChanged(); + void toChanged(); + void valueChanged(); + void stepSizeChanged(); + void editableChanged(); + void validatorChanged(); + void textFromValueChanged(); + void valueFromTextChanged(); + // 2.2 (Qt 5.9) + Q_REVISION(2, 2) void valueModified(); + Q_REVISION(2, 2) void inputMethodHintsChanged(); + Q_REVISION(2, 2) void inputMethodComposingChanged(); + // 2.3 (Qt 5.10) + Q_REVISION(2, 3) void wrapChanged(); + // 2.4 (Qt 5.11) + Q_REVISION(2, 4) void displayTextChanged(); + +protected: + void focusInEvent(QFocusEvent *event) override; + void hoverEnterEvent(QHoverEvent *event) override; + void hoverMoveEvent(QHoverEvent *event) override; + void hoverLeaveEvent(QHoverEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void keyReleaseEvent(QKeyEvent *event) override; + void timerEvent(QTimerEvent *event) override; +#if QT_CONFIG(wheelevent) + void wheelEvent(QWheelEvent *event) override; +#endif + + void classBegin() override; + void componentComplete() override; + void itemChange(ItemChange change, const ItemChangeData &value) override; + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + void localeChange(const QLocale &newLocale, const QLocale &oldLocale) override; + + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; + void accessibilityActiveChanged(bool active) override; +#endif + +private: + Q_DISABLE_COPY(QQuickSpinBox) + Q_DECLARE_PRIVATE(QQuickSpinBox) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickSpinBox) + +#endif // QQUICKSPINBOX_P_H diff --git a/src/quicktemplates2/qquicksplitview.cpp b/src/quicktemplates2/qquicksplitview.cpp new file mode 100644 index 00000000000..24e42d82586 --- /dev/null +++ b/src/quicktemplates2/qquicksplitview.cpp @@ -0,0 +1,2141 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicksplitview_p.h" +#include "qquicksplitview_p_p.h" +#include "qquickcontentitem_p.h" + +#include <QtCore/qdebug.h> +#include <QtCore/qloggingcategory.h> +#include <QtCore/qcborarray.h> +#include <QtCore/qcbormap.h> +#include <QtCore/qcborvalue.h> +#include <QtQml/QQmlInfo> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype SplitView + \inherits Container +//! \instantiates QQuickSplitView + \inqmlmodule QtQuick.Controls + \since 5.13 + \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes + \brief Lays out items with a draggable splitter between each item. + + SplitView is a control that lays out items horizontally or vertically with + a draggable splitter between each item. + + SplitView supports the following attached properties on items it manages: + + \list + \li \l{minimumWidth}{SplitView.minimumWidth} + \li \l{minimumHeight}{SplitView.minimumHeight} + \li \l{preferredWidth}{SplitView.preferredWidth} + \li \l{preferredHeight}{SplitView.preferredHeight} + \li \l{maximumWidth}{SplitView.maximumWidth} + \li \l{maximumHeight}{SplitView.maximumHeight} + \li \l{fillWidth}{SplitView.fillWidth} (true for only one child) + \li \l{fillHeight}{SplitView.fillHeight} (true for only one child) + \endlist + + In addition, each handle has the following read-only attached properties: + + \list + \li \l{SplitHandle::hovered}{SplitHandle.hovered} + \li \l{SplitHandle::pressed}{SplitHandle.pressed} + \endlist + + \note Handles should be purely visual and not handle events, as it can + interfere with their hovered and pressed states. + + The preferred size of items in a SplitView can be specified via + \l{Item::}{implicitWidth} and \l{Item::}{implicitHeight} or + \c SplitView.preferredWidth and \c SplitView.preferredHeight: + + \code + SplitView { + anchors.fill: parent + + Item { + SplitView.preferredWidth: 50 + } + + // ... + } + \endcode + + For a horizontal SplitView, it's not necessary to specify the preferred + height of each item, as they will be resized to the height of the view. + This applies in reverse for vertical views. + + When a split handle is dragged, the \c SplitView.preferredWidth or + \c SplitView.preferredHeight property is overwritten, depending on the + \l orientation of the view. + + To limit the size of items in a horizontal view, use the following + properties: + + \code + SplitView { + anchors.fill: parent + + Item { + SplitView.minimumWidth: 25 + SplitView.preferredWidth: 50 + SplitView.maximumWidth: 100 + } + + // ... + } + \endcode + + To limit the size of items in a vertical view, use the following + properties: + + \code + SplitView { + anchors.fill: parent + orientation: Qt.Vertical + + Item { + SplitView.minimumHeight: 25 + SplitView.preferredHeight: 50 + SplitView.maximumHeight: 100 + } + + // ... + } + \endcode + + There will always be one item (the fill item) in the SplitView that has + \c SplitView.fillWidth set to \c true (or \c SplitView.fillHeight, if + \l orientation is \c Qt.Vertical). This means that the item will get all + leftover space when other items have been laid out. By default, the last + visible child of the SplitView will have this set, but it can be changed by + explicitly setting \c fillWidth to \c true on another item. + + A handle can belong to the item either on the left or top side, or on the + right or bottom side: + + \list + \li If the fill item is to the right: the handle belongs to the left + item. + \li If the fill item is on the left: the handle belongs to the right + item. + \endlist + + To create a SplitView with three items, and let the center item get + superfluous space, one could do the following: + + \code + SplitView { + anchors.fill: parent + orientation: Qt.Horizontal + + Rectangle { + implicitWidth: 200 + SplitView.maximumWidth: 400 + color: "lightblue" + Label { + text: "View 1" + anchors.centerIn: parent + } + } + Rectangle { + id: centerItem + SplitView.minimumWidth: 50 + SplitView.fillWidth: true + color: "lightgray" + Label { + text: "View 2" + anchors.centerIn: parent + } + } + Rectangle { + implicitWidth: 200 + color: "lightgreen" + Label { + text: "View 3" + anchors.centerIn: parent + } + } + } + \endcode + + \section1 Serializing SplitView's State + + The main purpose of SplitView is to allow users to easily configure the + size of various UI elements. In addition, the user's preferred sizes should + be remembered across sessions. To achieve this, the values of the \c + SplitView.preferredWidth and \c SplitView.preferredHeight properties can be + serialized using the \l saveState() and \l restoreState() functions: + + \qml + import QtQuick.Controls + import Qt.labs.settings + + ApplicationWindow { + // ... + + Component.onCompleted: splitView.restoreState(settings.splitView) + Component.onDestruction: settings.splitView = splitView.saveState() + + Settings { + id: settings + property var splitView + } + + SplitView { + id: splitView + // ... + } + } + \endqml + + Alternatively, the \l {Settings::}{value()} and \l {Settings::}{setValue()} + functions of \l Settings can be used: + + \qml + import QtQuick.Controls + import Qt.labs.settings + + ApplicationWindow { + // ... + + Component.onCompleted: splitView.restoreState(settings.value("ui/splitview")) + Component.onDestruction: settings.setValue("ui/splitview", splitView.saveState()) + + Settings { + id: settings + } + + SplitView { + id: splitView + // ... + } + } + \endqml + + \sa SplitHandle, {Customizing SplitView}, {Container Controls} +*/ + +Q_LOGGING_CATEGORY(qlcQQuickSplitView, "qt.quick.controls.splitview") +Q_LOGGING_CATEGORY(qlcQQuickSplitViewPointer, "qt.quick.controls.splitview.pointer") +Q_LOGGING_CATEGORY(qlcQQuickSplitViewState, "qt.quick.controls.splitview.state") + +void QQuickSplitViewPrivate::updateFillIndex() +{ + const int count = contentModel->count(); + const bool horizontal = isHorizontal(); + + qCDebug(qlcQQuickSplitView) << "looking for fillWidth/Height item amongst" << count << "items"; + + m_fillIndex = -1; + int i = 0; + int lastVisibleIndex = -1; + for (; i < count; ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->object(i)); + if (!item->isVisible()) + continue; + + lastVisibleIndex = i; + + const QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, false)); + if (!attached) + continue; + + if ((horizontal && attached->fillWidth()) || (!horizontal && attached->fillHeight())) { + m_fillIndex = i; + qCDebug(qlcQQuickSplitView) << "found fillWidth/Height item at index" << m_fillIndex; + break; + } + } + + if (m_fillIndex == -1) { + // If there was no item with fillWidth/fillHeight set, m_fillIndex will be -1, + // and we'll set it to the last visible item. + // If there was an item with fillWidth/fillHeight set, we were already done and this will be skipped. + m_fillIndex = lastVisibleIndex != -1 ? lastVisibleIndex : count - 1; + qCDebug(qlcQQuickSplitView) << "found no fillWidth/Height item; using last item at index" << m_fillIndex; + } +} + +/* + Resizes split items according to their preferred size and any constraints. + + If a split item is being resized due to a split handle being dragged, + it will be resized accordingly. + + Items that aren't visible are skipped. +*/ +void QQuickSplitViewPrivate::layoutResizeSplitItems(qreal &usedWidth, qreal &usedHeight, int &indexBeingResizedDueToDrag) +{ + const int count = contentModel->count(); + const bool horizontal = isHorizontal(); + for (int index = 0; index < count; ++index) { + QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->object(index)); + if (!item->isVisible()) { + // The item is not visible, so skip it. + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": split item " << item + << " at index " << index << " is not visible; skipping it and its handles (if any)"; + continue; + } + + const QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, false)); + const auto sizeData = effectiveSizeData(itemPrivate, attached); + + const bool resizeLeftItem = m_fillIndex > m_pressedHandleIndex; + // True if any handle is pressed. + const bool isAHandlePressed = m_pressedHandleIndex != -1; + // True if this particular item is being resized as a result of a handle being dragged. + const bool isBeingResized = isAHandlePressed && ((resizeLeftItem && index == m_pressedHandleIndex) + || (!resizeLeftItem && index == m_nextVisibleIndexAfterPressedHandle)); + if (isBeingResized) { + indexBeingResizedDueToDrag = index; + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": dragging handle for item"; + } + + const qreal size = horizontal ? width : height; + qreal requestedSize = 0; + if (isBeingResized) { + // Don't let the mouse go past either edge of the SplitView. + const qreal clampedMousePos = horizontal + ? qBound(qreal(0.0), m_mousePos.x(), qreal(width)) + : qBound(qreal(0.0), m_mousePos.y(), qreal(height)); + + // We also need to ensure that the item's edge doesn't go too far + // out and hence give the item more space than is available. + const int firstIndex = resizeLeftItem ? m_nextVisibleIndexAfterPressedHandle : 0; + const int lastIndex = resizeLeftItem ? contentModel->count() - 1 : m_pressedHandleIndex; + const qreal accumulated = accumulatedSize(firstIndex, lastIndex); + + const qreal mousePosRelativeToLeftHandleEdge = horizontal + ? m_pressPos.x() - m_handlePosBeforePress.x() + : m_pressPos.y() - m_handlePosBeforePress.y(); + + const QQuickItem *pressedHandleItem = m_handleItems.at(m_pressedHandleIndex); + const qreal pressedHandleSize = horizontal ? pressedHandleItem->width() : pressedHandleItem->height(); + + if (resizeLeftItem) { + // The handle shouldn't cross other handles, so use the right edge of + // the first handle to the left as the left edge. + qreal leftEdge = 0; + if (m_pressedHandleIndex - 1 >= 0) { + const QQuickItem *leftHandle = m_handleItems.at(m_pressedHandleIndex - 1); + leftEdge = horizontal + ? leftHandle->x() + leftHandle->width() + : leftHandle->y() + leftHandle->height(); + } + + // The mouse can be clicked anywhere in the handle, and if we don't account for + // its position within the handle, the handle will jump when dragged. + const qreal pressedHandlePos = clampedMousePos - mousePosRelativeToLeftHandleEdge; + + const qreal rightStop = size - accumulated - pressedHandleSize; + qreal leftStop = qMax(leftEdge, pressedHandlePos); + // qBound() doesn't care if min is greater than max, but we do. + if (leftStop > rightStop) + leftStop = rightStop; + const qreal newHandlePos = qBound(leftStop, pressedHandlePos, rightStop); + const qreal newItemSize = newHandlePos - leftEdge; + + // Modify the preferredWidth, otherwise the original implicitWidth/preferredWidth + // will be used on the next layout (when it's no longer being resized). + if (!attached) { + // Force the attached object to be created since we rely on it. + attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, true)); + } + + /* + Users could conceivably respond to size changes in items by setting attached + SplitView properties: + + onWidthChanged: if (width < 10) secondItem.SplitView.preferredWidth = 100 + + We handle this by doing another layout after the current layout if the + attached/implicit size properties are set during this layout. However, we also + need to set preferredWidth/Height here (for reasons mentioned in the comment above), + but we don't want this to count as a request for a delayed layout, so we guard against it. + */ + m_ignoreNextLayoutRequest = true; + + if (horizontal) + attached->setPreferredWidth(newItemSize); + else + attached->setPreferredHeight(newItemSize); + + // We still need to use requestedWidth in the setWidth() call below, + // because sizeData has already been calculated and now contains an old + // effectivePreferredWidth value. + requestedSize = newItemSize; + + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": resized (dragged) " << item + << " (clampedMousePos=" << clampedMousePos + << " pressedHandlePos=" << pressedHandlePos + << " accumulated=" << accumulated + << " leftEdge=" << leftEdge + << " leftStop=" << leftStop + << " rightStop=" << rightStop + << " newHandlePos=" << newHandlePos + << " newItemSize=" << newItemSize << ")"; + } else { // Resizing the item on the right. + // The handle shouldn't cross other handles, so use the left edge of + // the first handle to the right as the right edge. + qreal rightEdge = size; + if (m_nextVisibleIndexAfterPressedHandle < m_handleItems.size()) { + const QQuickItem *rightHandle = m_handleItems.at(m_nextVisibleIndexAfterPressedHandle); + rightEdge = horizontal ? rightHandle->x() : rightHandle->y(); + } + + // The mouse can be clicked anywhere in the handle, and if we don't account for + // its position within the handle, the handle will jump when dragged. + const qreal pressedHandlePos = clampedMousePos - mousePosRelativeToLeftHandleEdge; + + const qreal leftStop = accumulated - pressedHandleSize; + qreal rightStop = qMin(rightEdge - pressedHandleSize, pressedHandlePos); + // qBound() doesn't care if min is greater than max, but we do. + if (rightStop < leftStop) + rightStop = leftStop; + const qreal newHandlePos = qBound(leftStop, pressedHandlePos, rightStop); + const qreal newItemSize = rightEdge - (newHandlePos + pressedHandleSize); + + // Modify the preferredWidth, otherwise the original implicitWidth/preferredWidth + // will be used on the next layout (when it's no longer being resized). + if (!attached) { + // Force the attached object to be created since we rely on it. + attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, true)); + } + + m_ignoreNextLayoutRequest = true; + + if (horizontal) + attached->setPreferredWidth(newItemSize); + else + attached->setPreferredHeight(newItemSize); + + // We still need to use requestedSize in the setWidth()/setHeight() call below, + // because sizeData has already been calculated and now contains an old + // effectivePreferredWidth/Height value. + requestedSize = newItemSize; + + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": resized (dragged) " << item + << " (clampedMousePos=" << clampedMousePos + << " pressedHandlePos=" << pressedHandlePos + << " accumulated=" << accumulated + << " leftEdge=" << rightEdge + << " leftStop=" << leftStop + << " rightStop=" << rightStop + << " newHandlePos=" << newHandlePos + << " newItemSize=" << newItemSize << ")"; + } + } else if (index != m_fillIndex) { + // No handle is being dragged and we're not the fill item, + // so set our preferred size as we normally would. + requestedSize = horizontal + ? sizeData.effectivePreferredWidth : sizeData.effectivePreferredHeight; + } + + if (index != m_fillIndex) { + if (horizontal) { + item->setWidth(qBound( + sizeData.effectiveMinimumWidth, + requestedSize, + sizeData.effectiveMaximumWidth)); + item->setHeight(height); + } else { + item->setWidth(width); + item->setHeight(qBound( + sizeData.effectiveMinimumHeight, + requestedSize, + sizeData.effectiveMaximumHeight)); + } + + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": resized split item " << item + << " (effective" + << " minW=" << sizeData.effectiveMinimumWidth + << ", minH=" << sizeData.effectiveMinimumHeight + << ", prfW=" << sizeData.effectivePreferredWidth + << ", prfH=" << sizeData.effectivePreferredHeight + << ", maxW=" << sizeData.effectiveMaximumWidth + << ", maxH=" << sizeData.effectiveMaximumHeight << ")"; + + // Keep track of how much space has been used so far. + if (horizontal) + usedWidth += item->width(); + else + usedHeight += item->height(); + } else if (indexBeingResizedDueToDrag != m_fillIndex) { + // The fill item is resized afterwards, outside of the loop. + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": skipping fill item as we resize it last"; + } + + // Also account for the size of the handle for this item (if any). + // We do this for the fill item too, which is why it's outside of the check above. + if (index < count - 1 && m_handle) { + QQuickItem *handleItem = m_handleItems.at(index); + // The handle for an item that's not visible will usually already be skipped + // with the item visibility check higher up, but if the view looks like this + // [ visible ] | [ visible (fill) ] | [ hidden ] + // ^ + // hidden + // and we're iterating over the second item (which is visible but has no handle), + // we need to add an extra check for it to avoid it still taking up space. + if (handleItem->isVisible()) { + if (horizontal) { + qCDebug(qlcQQuickSplitView).nospace() << " - " << index + << ": handle takes up " << handleItem->width() << " width"; + usedWidth += handleItem->width(); + } else { + qCDebug(qlcQQuickSplitView).nospace() << " - " << index + << ": handle takes up " << handleItem->height() << " height"; + usedHeight += handleItem->height(); + } + } else { + qCDebug(qlcQQuickSplitView).nospace() << " - " << index << ": handle is not visible; skipping it"; + } + } + } +} + +/* + Resizes the fill item by giving it the remaining space + after all other items have been resized. + + Items that aren't visible are skipped. +*/ +void QQuickSplitViewPrivate::layoutResizeFillItem(QQuickItem *fillItem, + qreal &usedWidth, qreal &usedHeight, int indexBeingResizedDueToDrag) +{ + // Only bother resizing if it it's visible. Also, if it's being resized due to a drag, + // then we've already set its size in layoutResizeSplitItems(), so no need to do it here. + if (!fillItem->isVisible() || indexBeingResizedDueToDrag == m_fillIndex) { + qCDebug(qlcQQuickSplitView).nospace() << m_fillIndex << ": - fill item " << fillItem + << " is not visible or was already resized due to a drag;" + << " skipping it and its handles (if any)"; + return; + } + + const QQuickItemPrivate *fillItemPrivate = QQuickItemPrivate::get(fillItem); + const QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(fillItem, false)); + const auto fillSizeData = effectiveSizeData(fillItemPrivate, attached); + if (isHorizontal()) { + fillItem->setWidth(qBound( + fillSizeData.effectiveMinimumWidth, + width - usedWidth, + fillSizeData.effectiveMaximumWidth)); + fillItem->setHeight(height); + } else { + fillItem->setWidth(width); + fillItem->setHeight(qBound( + fillSizeData.effectiveMinimumHeight, + height - usedHeight, + fillSizeData.effectiveMaximumHeight)); + } + + qCDebug(qlcQQuickSplitView).nospace() << " - " << m_fillIndex + << ": resized split fill item " << fillItem << " (effective" + << " minW=" << fillSizeData.effectiveMinimumWidth + << ", minH=" << fillSizeData.effectiveMinimumHeight + << ", maxW=" << fillSizeData.effectiveMaximumWidth + << ", maxH=" << fillSizeData.effectiveMaximumHeight << ")"; +} + +/* + Positions items by laying them out in a row or column. + + Items that aren't visible are skipped. +*/ +void QQuickSplitViewPrivate::layoutPositionItems(const QQuickItem *fillItem) +{ + const bool horizontal = isHorizontal(); + const int count = contentModel->count(); + qreal usedWidth = 0; + qreal usedHeight = 0; + + for (int i = 0; i < count; ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->object(i)); + if (!item->isVisible()) { + qCDebug(qlcQQuickSplitView).nospace() << " - " << i << ": split item " << item + << " is not visible; skipping it and its handles (if any)"; + continue; + } + + // Position the item. + if (horizontal) { + item->setX(usedWidth); + item->setY(0); + } else { + item->setX(0); + item->setY(usedHeight); + } + + // Keep track of how much space has been used so far. + if (horizontal) + usedWidth += item->width(); + else + usedHeight += item->height(); + + if (Q_UNLIKELY(qlcQQuickSplitView().isDebugEnabled())) { + const QQuickItemPrivate *fillItemPrivate = QQuickItemPrivate::get(fillItem); + const QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(fillItem, false)); + const auto sizeData = effectiveSizeData(fillItemPrivate, attached); + qCDebug(qlcQQuickSplitView).nospace() << " - " << i << ": positioned " + << (i == m_fillIndex ? "fill item " : "item ") << item << " (effective" + << " minW=" << sizeData.effectiveMinimumWidth + << ", minH=" << sizeData.effectiveMinimumHeight + << ", prfW=" << sizeData.effectivePreferredWidth + << ", prfH=" << sizeData.effectivePreferredHeight + << ", maxW=" << sizeData.effectiveMaximumWidth + << ", maxH=" << sizeData.effectiveMaximumHeight << ")"; + } + + // Position the handle for this item (if any). + if (i < count - 1 && m_handle) { + // Position the handle. + QQuickItem *handleItem = m_handleItems.at(i); + handleItem->setX(horizontal ? usedWidth : 0); + handleItem->setY(horizontal ? 0 : usedHeight); + + if (horizontal) + usedWidth += handleItem->width(); + else + usedHeight += handleItem->height(); + + qCDebug(qlcQQuickSplitView).nospace() << " - " << i << ": positioned handle " << handleItem; + } + } +} + +void QQuickSplitViewPrivate::requestLayout() +{ + Q_Q(QQuickSplitView); + q->polish(); +} + +void QQuickSplitViewPrivate::layout() +{ + if (!componentComplete) + return; + + if (m_layingOut) + return; + + const int count = contentModel->count(); + if (count <= 0) + return; + + Q_ASSERT_X(m_fillIndex < count, Q_FUNC_INFO, qPrintable( + QString::fromLatin1("m_fillIndex is %1 but our count is %2").arg(m_fillIndex).arg(count))); + + Q_ASSERT_X(!m_handle || m_handleItems.size() == count - 1, Q_FUNC_INFO, qPrintable(QString::fromLatin1( + "Expected %1 handle items, but there are %2").arg(count - 1).arg(m_handleItems.size()))); + + // We allow mouse events to instantly trigger layouts, whereas with e.g. + // attached properties being set, we require a delayed layout. + // To prevent recursive calls during mouse events, we need this guard. + QBoolBlocker guard(m_layingOut, true); + + const bool horizontal = isHorizontal(); + qCDebug(qlcQQuickSplitView) << "laying out" << count << "split items" + << (horizontal ? "horizontally" : "vertically") << "in SplitView" << q_func(); + + qreal usedWidth = 0; + qreal usedHeight = 0; + int indexBeingResizedDueToDrag = -1; + + qCDebug(qlcQQuickSplitView) << " resizing:"; + + // First, resize the items. We need to do this first because otherwise fill + // items would take up all of the remaining space as soon as they are encountered. + layoutResizeSplitItems(usedWidth, usedHeight, indexBeingResizedDueToDrag); + + qCDebug(qlcQQuickSplitView).nospace() + << " - (remaining width=" << width - usedWidth + << " remaining height=" << height - usedHeight << ")"; + + // Give the fill item the remaining space. + QQuickItem *fillItem = qobject_cast<QQuickItem*>(contentModel->object(m_fillIndex)); + layoutResizeFillItem(fillItem, usedWidth, usedHeight, indexBeingResizedDueToDrag); + + qCDebug(qlcQQuickSplitView) << " positioning:"; + + // Position the items. + layoutPositionItems(fillItem); + + qCDebug(qlcQQuickSplitView).nospace() << "finished layouting"; +} + +void QQuickSplitViewPrivate::createHandles() +{ + Q_ASSERT(m_handle); + // A handle only makes sense if there are two items on either side. + if (contentModel->count() <= 1) + return; + + // Create new handle items if there aren't enough. + const int count = contentModel->count() - 1; + qCDebug(qlcQQuickSplitView) << "creating" << count << "handles"; + m_handleItems.reserve(count); + for (int i = 0; i < count; ++i) + createHandleItem(i); +} + +void QQuickSplitViewPrivate::createHandleItem(int index) +{ + Q_Q(QQuickSplitView); + if (contentModel->count() <= 1) + return; + + qCDebug(qlcQQuickSplitView) << "- creating handle for split item at index" << index + << "from handle component" << m_handle; + + // If we don't use the correct context, it won't be possible to refer to + // the control's id from within the delegate. + QQmlContext *creationContext = m_handle->creationContext(); + // The component might not have been created in QML, in which case + // the creation context will be null and we have to create it ourselves. + if (!creationContext) + creationContext = qmlContext(q); + QQmlContext *context = new QQmlContext(creationContext, q); + context->setContextObject(q); + QQuickItem *handleItem = qobject_cast<QQuickItem*>(m_handle->beginCreate(context)); + if (handleItem) { + qCDebug(qlcQQuickSplitView) << "- successfully created handle item" << handleItem << "for split item at index" << index; + + // Insert the item to our list of items *before* its parent is set to us, + // so that we can avoid it being added as a content item by checking + // if it is in the list in isContent(). + m_handleItems.insert(index, handleItem); + + handleItem->setParentItem(q); + // Handles must have priority for press events, so we need to set this. + handleItem->setAcceptedMouseButtons(Qt::LeftButton); + handleItem->setKeepMouseGrab(true); +#if QT_CONFIG(cursor) + updateCursorHandle(handleItem); +#endif + m_handle->completeCreate(); + resizeHandle(handleItem); + } +} + +void QQuickSplitViewPrivate::removeExcessHandles() +{ + int excess = m_handleItems.size() - qMax(0, contentModel->count() - 1); + qCDebug(qlcQQuickSplitView) << "removing" << excess << "excess handles from the end of our list"; + for (; excess > 0; --excess) { + QQuickItem *handleItem = m_handleItems.takeLast(); + delete handleItem; + } +} + +qreal QQuickSplitViewPrivate::accumulatedSize(int firstIndex, int lastIndex) const +{ + qreal size = 0.0; + const bool horizontal = isHorizontal(); + for (int i = firstIndex; i <= lastIndex; ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->object(i)); + if (item->isVisible()) { + if (i != m_fillIndex) { + size += horizontal ? item->width() : item->height(); + } else { + // If the fill item has a minimum size specified, we must respect it. + const QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, false)); + if (attached) { + const QQuickSplitViewAttachedPrivate *attachedPrivate + = QQuickSplitViewAttachedPrivate::get(attached); + if (horizontal && attachedPrivate->m_isMinimumWidthSet) + size += attachedPrivate->m_minimumWidth; + else if (!horizontal && attachedPrivate->m_isMinimumHeightSet) + size += attachedPrivate->m_minimumHeight; + } + } + } + + // Only add the handle's width if there's actually a handle for this split item index. + if (i < lastIndex || lastIndex < contentModel->count() - 1) { + const QQuickItem *handleItem = m_handleItems.at(i); + if (handleItem->isVisible()) + size += horizontal ? handleItem->width() : handleItem->height(); + } + } + return size; +} + +qreal effectiveMinimumWidth(const QQuickSplitViewAttachedPrivate *attachedPrivate) +{ + return attachedPrivate && attachedPrivate->m_isMinimumWidthSet ? attachedPrivate->m_minimumWidth : 0; +} + +qreal effectiveMinimumHeight(const QQuickSplitViewAttachedPrivate *attachedPrivate) +{ + return attachedPrivate && attachedPrivate->m_isMinimumHeightSet ? attachedPrivate->m_minimumHeight : 0; +} + +qreal effectivePreferredWidth(const QQuickSplitViewAttachedPrivate *attachedPrivate, + const QQuickItemPrivate *itemPrivate) +{ + return attachedPrivate && attachedPrivate->m_isPreferredWidthSet + ? attachedPrivate->m_preferredWidth : itemPrivate->implicitWidth; +} + +qreal effectivePreferredHeight(const QQuickSplitViewAttachedPrivate *attachedPrivate, + const QQuickItemPrivate *itemPrivate) +{ + return attachedPrivate && attachedPrivate->m_isPreferredHeightSet + ? attachedPrivate->m_preferredHeight : itemPrivate->implicitHeight; +} + +qreal effectiveMaximumWidth(const QQuickSplitViewAttachedPrivate *attachedPrivate) +{ + return attachedPrivate && attachedPrivate->m_isMaximumWidthSet + ? attachedPrivate->m_maximumWidth : std::numeric_limits<qreal>::infinity(); +} + +qreal effectiveMaximumHeight(const QQuickSplitViewAttachedPrivate *attachedPrivate) +{ + return attachedPrivate && attachedPrivate->m_isMaximumHeightSet + ? attachedPrivate->m_maximumHeight : std::numeric_limits<qreal>::infinity(); +} + +// We don't just take an index, because the item and attached properties object +// will both be used outside of this function by calling code, so save some +// time by not accessing them twice. +QQuickSplitViewPrivate::EffectiveSizeData QQuickSplitViewPrivate::effectiveSizeData( + const QQuickItemPrivate *itemPrivate, const QQuickSplitViewAttached *attached) const +{ + EffectiveSizeData data; + const QQuickSplitViewAttachedPrivate *attachedPrivate = attached ? QQuickSplitViewAttachedPrivate::get(attached) : nullptr; + data.effectiveMinimumWidth = effectiveMinimumWidth(attachedPrivate); + data.effectiveMinimumHeight = effectiveMinimumHeight(attachedPrivate); + data.effectivePreferredWidth = effectivePreferredWidth(attachedPrivate, itemPrivate); + data.effectivePreferredHeight = effectivePreferredHeight(attachedPrivate, itemPrivate); + data.effectiveMaximumWidth = effectiveMaximumWidth(attachedPrivate); + data.effectiveMaximumHeight = effectiveMaximumHeight(attachedPrivate); + return data; +} + +int QQuickSplitViewPrivate::handleIndexForSplitIndex(int splitIndex) const +{ + // If it's the first and only item in the view, it doesn't have a handle, + // so return -1: splitIndex (0) - 1. + // If it's the last item in the view, it doesn't have a handle, so use + // the handle for the previous item. + return splitIndex == contentModel->count() - 1 ? splitIndex - 1 : splitIndex; +} + +void QQuickSplitViewPrivate::destroyHandles() +{ + qCDebug(qlcQQuickSplitView) << "destroying" << m_handleItems.size() << "handles"; + qDeleteAll(m_handleItems); + m_handleItems.clear(); +} + +void QQuickSplitViewPrivate::resizeHandle(QQuickItem *handleItem) +{ + const bool horizontal = isHorizontal(); + handleItem->setWidth(horizontal ? handleItem->implicitWidth() : width); + handleItem->setHeight(horizontal ? height : handleItem->implicitHeight()); +} + +void QQuickSplitViewPrivate::resizeHandles() +{ + for (QQuickItem *handleItem : m_handleItems) + resizeHandle(handleItem); +} + +#if QT_CONFIG(cursor) +void QQuickSplitViewPrivate::updateCursorHandle(QQuickItem *handleItem) +{ + handleItem->setCursor(isHorizontal() ? Qt::SplitHCursor : Qt::SplitVCursor); +} +#endif + +void QQuickSplitViewPrivate::updateHandleVisibilities() +{ + // If this is the first item that is visible, we won't have any + // handles yet, because we don't create a handle if we only have one item. + if (m_handleItems.isEmpty()) + return; + + // If the visibility/children change makes any item the last (right/bottom-most) + // visible item, we don't want to display a handle for it either: + // [ visible (fill) ] | [ hidden ] | [ hidden ] + // ^ ^ + // hidden hidden + const int count = contentModel->count(); + int lastVisibleItemIndex = -1; + for (int i = count - 1; i >= 0; --i) { + const QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->object(i)); + if (item->isVisible()) { + lastVisibleItemIndex = i; + break; + } + } + + for (int i = 0; i < count - 1; ++i) { + const QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->object(i)); + QQuickItem *handleItem = m_handleItems.at(i); + if (i != lastVisibleItemIndex) + handleItem->setVisible(item->isVisible()); + else + handleItem->setVisible(false); + qCDebug(qlcQQuickSplitView) << "set visible property of handle" << handleItem << "at index" + << i << "to" << handleItem->isVisible(); + } +} + +void QQuickSplitViewPrivate::updateHoveredHandle(QQuickItem *hoveredItem) +{ + qCDebug(qlcQQuickSplitViewPointer) << "updating hovered handle after" << hoveredItem << "was hovered"; + + const int oldHoveredHandleIndex = m_hoveredHandleIndex; + m_hoveredHandleIndex = m_handleItems.indexOf(hoveredItem); + if (m_hoveredHandleIndex == oldHoveredHandleIndex) + return; + + // First, clear the hovered flag of any previously-hovered handle. + if (oldHoveredHandleIndex != -1) { + QQuickItem *oldHoveredHandle = m_handleItems.at(oldHoveredHandleIndex); + QQuickSplitHandleAttached *oldHoveredHandleAttached = qobject_cast<QQuickSplitHandleAttached*>( + qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(oldHoveredHandle, true)); + QQuickSplitHandleAttachedPrivate::get(oldHoveredHandleAttached)->setHovered(false); + qCDebug(qlcQQuickSplitViewPointer) << "handle item at index" << oldHoveredHandleIndex << "is no longer hovered"; + } + + if (m_hoveredHandleIndex != -1) { + QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>( + qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(hoveredItem, true)); + QQuickSplitHandleAttachedPrivate::get(handleAttached)->setHovered(true); + qCDebug(qlcQQuickSplitViewPointer) << "handle item at index" << m_hoveredHandleIndex << "is now hovered"; + } else { + qCDebug(qlcQQuickSplitViewPointer) << "either there is no hovered item or" << hoveredItem << "is not a handle"; + } +} + +void QQuickSplitViewPrivate::setResizing(bool resizing) +{ + Q_Q(QQuickSplitView); + if (resizing == m_resizing) + return; + + m_resizing = resizing; + emit q->resizingChanged(); +} + +bool QQuickSplitViewPrivate::isHorizontal() const +{ + return m_orientation == Qt::Horizontal; +} + +QQuickItem *QQuickSplitViewPrivate::getContentItem() +{ + Q_Q(QQuickSplitView); + if (QQuickItem *item = QQuickContainerPrivate::getContentItem()) + return item; + + return new QQuickContentItem(q); +} + +void QQuickSplitViewPrivate::handlePress(const QPointF &point) +{ + Q_Q(QQuickSplitView); + QQuickContainerPrivate::handlePress(point); + + QQuickItem *pressedItem = q->childAt(point.x(), point.y()); + const int pressedHandleIndex = m_handleItems.indexOf(pressedItem); + if (pressedHandleIndex != -1) { + m_pressedHandleIndex = pressedHandleIndex; + m_pressPos = point; + m_mousePos = point; + + const QQuickItem *leftOrTopItem = qobject_cast<QQuickItem*>(contentModel->object(m_pressedHandleIndex)); + // Find the first item to the right/bottom of this one that is visible. + QQuickItem *rightOrBottomItem = nullptr; + m_nextVisibleIndexAfterPressedHandle = -1; + for (int i = m_pressedHandleIndex + 1; i < contentModel->count(); ++i) { + auto nextItem = qobject_cast<QQuickItem*>(contentModel->object(i)); + if (nextItem->isVisible()) { + rightOrBottomItem = nextItem; + m_nextVisibleIndexAfterPressedHandle = i; + break; + } + } + Q_ASSERT_X(rightOrBottomItem, Q_FUNC_INFO, qPrintable(QString::fromLatin1( + "Failed to find a visible item to the right/bottom of the one that was pressed at index %1; this shouldn't happen") + .arg(m_pressedHandleIndex))); + + const bool isHorizontal = m_orientation == Qt::Horizontal; + m_leftOrTopItemSizeBeforePress = isHorizontal ? leftOrTopItem->width() : leftOrTopItem->height(); + m_rightOrBottomItemSizeBeforePress = isHorizontal ? rightOrBottomItem->width() : rightOrBottomItem->height(); + m_handlePosBeforePress = pressedItem->position(); + + + // Force the attached object to be created since we rely on it. + QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>( + qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(pressedItem, true)); + QQuickSplitHandleAttachedPrivate::get(handleAttached)->setPressed(true); + + setResizing(true); + + qCDebug(qlcQQuickSplitViewPointer).nospace() << "handled press -" + << " left/top index=" << m_pressedHandleIndex << "," + << " size before press=" << m_leftOrTopItemSizeBeforePress << "," + << " item=" << leftOrTopItem + << " right/bottom index=" << m_nextVisibleIndexAfterPressedHandle << "," + << " size before press=" << m_rightOrBottomItemSizeBeforePress + << " item=" << rightOrBottomItem; + } +} + +void QQuickSplitViewPrivate::handleMove(const QPointF &point) +{ + QQuickContainerPrivate::handleMove(point); + + if (m_pressedHandleIndex != -1) { + m_mousePos = point; + // Don't request layouts for input events because we want + // resizing to be as responsive and smooth as possible. + updatePolish(); + } +} + +void QQuickSplitViewPrivate::handleRelease(const QPointF &point) +{ + QQuickContainerPrivate::handleRelease(point); + + if (m_pressedHandleIndex != -1) { + QQuickItem *pressedHandle = m_handleItems.at(m_pressedHandleIndex); + QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>( + qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(pressedHandle, true)); + QQuickSplitHandleAttachedPrivate::get(handleAttached)->setPressed(false); + } + + setResizing(false); + + m_pressedHandleIndex = -1; + m_pressPos = QPointF(); + m_mousePos = QPointF(); + m_handlePosBeforePress = QPointF(); + m_leftOrTopItemSizeBeforePress = 0.0; + m_rightOrBottomItemSizeBeforePress = 0.0; +} + +void QQuickSplitViewPrivate::itemVisibilityChanged(QQuickItem *item) +{ + const int itemIndex = contentModel->indexOf(item, nullptr); + Q_ASSERT(itemIndex != -1); + + qCDebug(qlcQQuickSplitView) << "visible property of split item" + << item << "at index" << itemIndex << "changed to" << item->isVisible(); + + // The visibility of an item just changed, so we need to update the visibility + // of the corresponding handle (if one exists). + + const int handleIndex = handleIndexForSplitIndex(itemIndex); + if (handleIndex != -1) { + QQuickItem *handleItem = m_handleItems.at(handleIndex); + handleItem->setVisible(item->isVisible()); + + qCDebug(qlcQQuickSplitView) << "set visible property of handle item" + << handleItem << "at index" << handleIndex << "to" << item->isVisible(); + } + + updateHandleVisibilities(); + updateFillIndex(); + requestLayout(); +} + +void QQuickSplitViewPrivate::itemImplicitWidthChanged(QQuickItem *) +{ + requestLayout(); +} + +void QQuickSplitViewPrivate::itemImplicitHeightChanged(QQuickItem *) +{ + requestLayout(); +} + +void QQuickSplitViewPrivate::updatePolish() +{ + layout(); +} + +QQuickSplitViewPrivate *QQuickSplitViewPrivate::get(QQuickSplitView *splitView) +{ + return splitView->d_func(); +} + +QQuickSplitView::QQuickSplitView(QQuickItem *parent) + : QQuickContainer(*(new QQuickSplitViewPrivate), parent) +{ + Q_D(QQuickSplitView); + d->changeTypes |= QQuickItemPrivate::Visibility; + + setFiltersChildMouseEvents(true); +} + +QQuickSplitView::QQuickSplitView(QQuickSplitViewPrivate &dd, QQuickItem *parent) + : QQuickContainer(dd, parent) +{ + Q_D(QQuickSplitView); + d->changeTypes |= QQuickItemPrivate::Visibility; + + setFiltersChildMouseEvents(true); +} + +QQuickSplitView::~QQuickSplitView() +{ + Q_D(QQuickSplitView); + for (int i = 0; i < d->contentModel->count(); ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(d->contentModel->object(i)); + d->removeImplicitSizeListener(item); + } +} + +/*! + \qmlproperty enumeration QtQuick.Controls::SplitView::orientation + + This property holds the orientation of the SplitView. + + The orientation determines how the split items are laid out: + + Possible values: + \value Qt.Horizontal The items are laid out horizontally (default). + \value Qt.Vertical The items are laid out vertically. +*/ +Qt::Orientation QQuickSplitView::orientation() const +{ + Q_D(const QQuickSplitView); + return d->m_orientation; +} + +void QQuickSplitView::setOrientation(Qt::Orientation orientation) +{ + Q_D(QQuickSplitView); + if (orientation == d->m_orientation) + return; + + d->m_orientation = orientation; + d->resizeHandles(); +#if QT_CONFIG(cursor) + for (QQuickItem *handleItem : d->m_handleItems) + d->updateCursorHandle(handleItem); +#endif + d->requestLayout(); + emit orientationChanged(); +} + +/*! + \qmlproperty bool QtQuick.Controls::SplitView::resizing + \readonly + + This property is \c true when the user is resizing + split items by dragging on the splitter handles. +*/ +bool QQuickSplitView::isResizing() const +{ + Q_D(const QQuickSplitView); + return d->m_resizing; +} + +/*! + \qmlproperty Component QtQuick.Controls::SplitView::handle + + This property holds the handle component. + + An instance of this component will be instantiated \c {count - 1} + times, as long as \c count is greater than than \c {1}. + + The following table explains how each handle will be resized + depending on the orientation of the split view: + + \table + \header + \li Orientation + \li Handle Width + \li Handle Height + \row + \li \c Qt.Horizontal + \li \c implicitWidth + \li The \c height of the SplitView. + \row + \li \c Qt.Vertical + \li The \c width of the SplitView. + \li \c implicitHeight + \endtable + + To change the size of the handle for mouse and touch events without + changing its visual size, use a \l {Item::}{containmentMask}: + + \snippet qtquickcontrols2-splitview-handle-containmentmask.qml 1 + + \sa {Customizing SplitView} +*/ +QQmlComponent *QQuickSplitView::handle() +{ + Q_D(const QQuickSplitView); + return d->m_handle; +} + +void QQuickSplitView::setHandle(QQmlComponent *handle) +{ + Q_D(QQuickSplitView); + if (handle == d->m_handle) + return; + + qCDebug(qlcQQuickSplitView) << "setting handle" << handle; + + if (d->m_handle) + d->destroyHandles(); + + d->m_handle = handle; + + if (d->m_handle) { + d->createHandles(); + d->updateHandleVisibilities(); + } + + d->requestLayout(); + + emit handleChanged(); +} + +bool QQuickSplitView::isContent(QQuickItem *item) const +{ + Q_D(const QQuickSplitView); + if (!qmlContext(item)) + return false; + + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return false; + + return !d->m_handleItems.contains(item); +} + +QQuickSplitViewAttached *QQuickSplitView::qmlAttachedProperties(QObject *object) +{ + return new QQuickSplitViewAttached(object); +} + +/*! + \qmlmethod var QtQuick.Controls::SplitView::saveState() + + Saves the preferred sizes of split items into a byte array and returns it. + + \sa {Serializing SplitView's State}, restoreState() +*/ +QVariant QQuickSplitView::saveState() +{ + Q_D(QQuickSplitView); + qCDebug(qlcQQuickSplitViewState) << "saving state for split items in" << this; + + // Save the preferred sizes of each split item. + QCborArray cborArray; + for (int i = 0; i < d->contentModel->count(); ++i) { + const QQuickItem *item = qobject_cast<QQuickItem*>(d->contentModel->object(i)); + const QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, false)); + // Don't serialise stuff if we don't need to. If a split item was given a preferred + // size in QML or it was dragged, it will have an attached object and either + // m_isPreferredWidthSet or m_isPreferredHeightSet (or both) will be true, + // so items without these can be skipped. We write the index of each item + // that has data so that we know which item to set it on when restoring. + if (!attached) + continue; + + const QQuickSplitViewAttachedPrivate *attachedPrivate = QQuickSplitViewAttachedPrivate::get(attached); + if (!attachedPrivate->m_isPreferredWidthSet && !attachedPrivate->m_isPreferredHeightSet) + continue; + + QCborMap cborMap; + cborMap[QLatin1String("index")] = i; + if (attachedPrivate->m_isPreferredWidthSet) { + cborMap[QLatin1String("preferredWidth")] = static_cast<double>(attachedPrivate->m_preferredWidth); + + qCDebug(qlcQQuickSplitViewState).nospace() << "- wrote preferredWidth of " + << attachedPrivate->m_preferredWidth << " for split item " << item << " at index " << i; + } + if (attachedPrivate->m_isPreferredHeightSet) { + cborMap[QLatin1String("preferredHeight")] = static_cast<double>(attachedPrivate->m_preferredHeight); + + qCDebug(qlcQQuickSplitViewState).nospace() << "- wrote preferredHeight of " + << attachedPrivate->m_preferredHeight << " for split item " << item << " at index " << i; + } + + cborArray.append(cborMap); + } + + const QByteArray byteArray = cborArray.toCborValue().toCbor(); + qCDebug(qlcQQuickSplitViewState) << "the resulting byte array is:" << byteArray; + return QVariant(byteArray); +} + +/*! + \qmlmethod bool QtQuick.Controls::SplitView::restoreState(state) + + Reads the preferred sizes from \a state and applies them to the split items. + + Returns \c true if the state was successfully restored, otherwise \c false. + + \sa {Serializing SplitView's State}, saveState() +*/ +bool QQuickSplitView::restoreState(const QVariant &state) +{ + const QByteArray cborByteArray = state.toByteArray(); + Q_D(QQuickSplitView); + if (cborByteArray.isEmpty()) + return false; + + QCborParserError parserError; + const QCborValue cborValue(QCborValue::fromCbor(cborByteArray, &parserError)); + if (parserError.error != QCborError::NoError) { + qmlWarning(this) << "Error reading SplitView state:" << parserError.errorString(); + return false; + } + + qCDebug(qlcQQuickSplitViewState) << "restoring state for split items of" << this + << "from the following string:" << state; + + const QCborArray cborArray(cborValue.toArray()); + const int ourCount = d->contentModel->count(); + // This could conceivably happen if items were removed from the SplitView since the state was last saved. + if (cborArray.size() > ourCount) { + qmlWarning(this) << "Error reading SplitView state: expected " + << ourCount << " or less split items but got " << cborArray.size(); + return false; + } + + for (auto it = cborArray.constBegin(); it != cborArray.constEnd(); ++it) { + QCborMap cborMap(it->toMap()); + const int splitItemIndex = cborMap.value(QLatin1String("index")).toInteger(); + const bool isPreferredWidthSet = cborMap.contains(QLatin1String("preferredWidth")); + const bool isPreferredHeightSet = cborMap.contains(QLatin1String("preferredHeight")); + + QQuickItem *item = qobject_cast<QQuickItem*>(d->contentModel->object(splitItemIndex)); + // If the split item does not have a preferred size specified in QML, it could still have + // been resized via dragging before it was saved. In this case, it won't have an + // attached object upon application startup, so we create it. + QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, true)); + if (isPreferredWidthSet) { + const qreal preferredWidth = cborMap.value(QLatin1String("preferredWidth")).toDouble(); + attached->setPreferredWidth(preferredWidth); + } + if (isPreferredHeightSet) { + const qreal preferredHeight = cborMap.value(QLatin1String("preferredHeight")).toDouble(); + attached->setPreferredHeight(preferredHeight); + } + + const QQuickSplitViewAttachedPrivate *attachedPrivate = QQuickSplitViewAttachedPrivate::get(attached); + qCDebug(qlcQQuickSplitViewState).nospace() + << "- restored the following state for split item " << item << " at index " << splitItemIndex + << ": preferredWidthSet=" << attachedPrivate->m_isPreferredWidthSet + << " preferredWidth=" << attachedPrivate->m_preferredWidth + << " preferredHeightSet=" << attachedPrivate->m_isPreferredHeightSet + << " preferredHeight=" << attachedPrivate->m_preferredHeight; + } + + return true; +} + +void QQuickSplitView::componentComplete() +{ + Q_D(QQuickSplitView); + QQuickControl::componentComplete(); + d->resizeHandles(); + d->updateFillIndex(); + d->updatePolish(); +} + +void QQuickSplitView::hoverMoveEvent(QHoverEvent *event) +{ + Q_D(QQuickSplitView); + QQuickContainer::hoverMoveEvent(event); + + QQuickItem *hoveredItem = childAt(event->position().toPoint().x(), event->position().toPoint().y()); + d->updateHoveredHandle(hoveredItem); +} + +void QQuickSplitView::hoverLeaveEvent(QHoverEvent *event) +{ + Q_UNUSED(event); + Q_D(QQuickSplitView); + // If SplitView is no longer hovered (e.g. visible set to false), clear handle hovered value + d->updateHoveredHandle(nullptr); +} + +bool QQuickSplitView::childMouseEventFilter(QQuickItem *item, QEvent *event) +{ + Q_D(QQuickSplitView); + qCDebug(qlcQQuickSplitViewPointer) << "childMouseEventFilter called with" << item << event; + + if (Q_LIKELY(event->isPointerEvent())) { + auto *pointerEvent = static_cast<QPointerEvent *>(event); + const auto &eventPoint = pointerEvent->points().first(); + const QPointF point = mapFromItem(item, eventPoint.position()); + + switch (event->type()) { + case QEvent::MouseButtonPress: + d->handlePress(point); + // Keep the mouse grab if this item belongs to the handle, + // otherwise this event can be stolen e.g. Flickable if we're inside it. + if (d->m_pressedHandleIndex != -1) + item->setKeepMouseGrab(true); + break; + case QEvent::MouseButtonRelease: + d->handleRelease(point); + break; + case QEvent::MouseMove: + d->handleMove(point); + break; + case QEvent::TouchBegin: + if (pointerEvent->pointCount() == 1) { + d->handlePress(point); + // We filter the event on behalf of item, but we want the item + // to be the exclusive grabber so that we can continue to filter + // touch events for it. + if (d->m_pressedHandleIndex != -1) { + item->setKeepTouchGrab(true); + pointerEvent->setExclusiveGrabber(eventPoint, item); + } + } + break; + case QEvent::TouchEnd: + if (pointerEvent->pointCount() == 1) + d->handleRelease(point); + break; + case QEvent::TouchUpdate: + if (pointerEvent->pointCount() == 1) + d->handleMove(point); + break; + default: + break; + } + } + + // If this event belongs to the handle, filter it. (d->m_pressedHandleIndex != -1) means that + // we press or move the handle, so we don't need to propagate it further. + if (d->m_pressedHandleIndex != -1) + return true; + + return QQuickContainer::childMouseEventFilter(item, event); +} + +void QQuickSplitView::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickSplitView); + QQuickControl::geometryChange(newGeometry, oldGeometry); + d->resizeHandles(); + d->requestLayout(); +} + +void QQuickSplitView::itemAdded(int index, QQuickItem *item) +{ + Q_D(QQuickSplitView); + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return; + + const int count = d->contentModel->count(); + qCDebug(qlcQQuickSplitView).nospace() << "split item " << item << " added at index " << index + << "; there are now " << count << " items"; + + QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, false)); + if (attached) + QQuickSplitViewAttachedPrivate::get(attached)->setView(this); + + // Only need to add handles if we have more than one split item. + if (count > 1) { + // If the item was added at the end, it shouldn't get a handle; + // the handle always goes to the split item on the left. + d->createHandleItem(index < count - 1 ? index : index - 1); + } + + d->addImplicitSizeListener(item); + + d->updateHandleVisibilities(); + d->updateFillIndex(); + d->requestLayout(); +} + +void QQuickSplitView::itemMoved(int index, QQuickItem *item) +{ + Q_D(QQuickSplitView); + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return; + + qCDebug(qlcQQuickSplitView) << "split item" << item << "moved to index" << index; + + d->updateHandleVisibilities(); + d->updateFillIndex(); + d->requestLayout(); +} + +void QQuickSplitView::itemRemoved(int index, QQuickItem *item) +{ + Q_D(QQuickSplitView); + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return; + + qCDebug(qlcQQuickSplitView).nospace() << "split item " << item << " removed from index " << index + << "; there are now " << d->contentModel->count() << " items"; + + // Clear hovered/pressed handle if there are any. + if (d->m_hoveredHandleIndex != -1 || d->m_pressedHandleIndex != -1) { + const int handleIndex = d->m_hoveredHandleIndex != -1 ? d->m_hoveredHandleIndex : d->m_pressedHandleIndex; + QQuickItem *itemHandle = d->m_handleItems.at(handleIndex); + QQuickSplitHandleAttached *handleAttached = qobject_cast<QQuickSplitHandleAttached*>( + qmlAttachedPropertiesObject<QQuickSplitHandleAttached>(itemHandle, false)); + if (handleAttached) { + auto handleAttachedPrivate = QQuickSplitHandleAttachedPrivate::get(handleAttached); + handleAttachedPrivate->setHovered(false); + handleAttachedPrivate->setPressed(false); + } + + d->m_hoveredHandleIndex = -1; + d->m_pressedHandleIndex = -1; + } + + // Unset any attached properties since the item is no longer owned by us. + QQuickSplitViewAttached *attached = qobject_cast<QQuickSplitViewAttached*>( + qmlAttachedPropertiesObject<QQuickSplitView>(item, false)); + if (attached) + QQuickSplitViewAttachedPrivate::get(attached)->setView(this); + + d->removeImplicitSizeListener(item); + + d->removeExcessHandles(); + d->updateHandleVisibilities(); + d->updateFillIndex(); + d->requestLayout(); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickSplitView::accessibleRole() const +{ + return QAccessible::Pane; +} +#endif + +QQuickSplitViewAttached::QQuickSplitViewAttached(QObject *parent) + : QObject(*(new QQuickSplitViewAttachedPrivate), parent) +{ + Q_D(QQuickSplitViewAttached); + QQuickItem *item = qobject_cast<QQuickItem *>(parent); + if (!item) { + qmlWarning(parent) << "SplitView: attached properties can only be used on Items"; + return; + } + + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return; + + d->m_splitItem = item; + + // Child items get added to SplitView's contentItem, so we have to ensure + // that exists first before trying to set m_splitView. + // Apparently, in some cases it's normal for the parent item + // to not exist until shortly after this constructor has run. + if (!item->parentItem()) + return; + + // This will get hit when attached SplitView properties are imperatively set + // on an item that previously had none set, for example. + QQuickSplitView *splitView = qobject_cast<QQuickSplitView*>(item->parentItem()->parentItem()); + if (!splitView) { + qmlWarning(parent) << "SplitView: attached properties must be accessed through a direct child of SplitView"; + return; + } + + d->setView(splitView); +} + +/*! + \qmlattachedproperty SplitView QtQuick.Controls::SplitView::view + + This attached property holds the split view of the item it is + attached to, or \c null if the item is not in a split view. +*/ +QQuickSplitView *QQuickSplitViewAttached::view() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_splitView; +} + +/*! + \qmlattachedproperty real QtQuick.Controls::SplitView::minimumWidth + + This attached property controls the minimum width of the split item. + The \l preferredWidth is bound within the \l minimumWidth and + \l maximumWidth. A split item cannot be dragged to be smaller than + its \c minimumWidth. + + The default value is \c 0. To reset this property to its default value, + set it to \c undefined. + + \sa maximumWidth, preferredWidth, fillWidth, minimumHeight +*/ +qreal QQuickSplitViewAttached::minimumWidth() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_minimumWidth; +} + +void QQuickSplitViewAttached::setMinimumWidth(qreal width) +{ + Q_D(QQuickSplitViewAttached); + d->m_isMinimumWidthSet = true; + if (qFuzzyCompare(width, d->m_minimumWidth)) + return; + + d->m_minimumWidth = width; + d->requestLayoutView(); + emit minimumWidthChanged(); +} + +void QQuickSplitViewAttached::resetMinimumWidth() +{ + Q_D(QQuickSplitViewAttached); + const qreal oldEffectiveMinimumWidth = effectiveMinimumWidth(d); + + d->m_isMinimumWidthSet = false; + d->m_minimumWidth = -1; + + const qreal newEffectiveMinimumWidth = effectiveMinimumWidth(d); + if (qFuzzyCompare(newEffectiveMinimumWidth, oldEffectiveMinimumWidth)) + return; + + d->requestLayoutView(); + emit minimumWidthChanged(); +} + +/*! + \qmlattachedproperty real QtQuick.Controls::SplitView::minimumHeight + + This attached property controls the minimum height of the split item. + The \l preferredHeight is bound within the \l minimumHeight and + \l maximumHeight. A split item cannot be dragged to be smaller than + its \c minimumHeight. + + The default value is \c 0. To reset this property to its default value, + set it to \c undefined. + + \sa maximumHeight, preferredHeight, fillHeight, minimumWidth +*/ +qreal QQuickSplitViewAttached::minimumHeight() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_minimumHeight; +} + +void QQuickSplitViewAttached::setMinimumHeight(qreal height) +{ + Q_D(QQuickSplitViewAttached); + d->m_isMinimumHeightSet = true; + if (qFuzzyCompare(height, d->m_minimumHeight)) + return; + + d->m_minimumHeight = height; + d->requestLayoutView(); + emit minimumHeightChanged(); +} + +void QQuickSplitViewAttached::resetMinimumHeight() +{ + Q_D(QQuickSplitViewAttached); + const qreal oldEffectiveMinimumHeight = effectiveMinimumHeight(d); + + d->m_isMinimumHeightSet = false; + d->m_minimumHeight = -1; + + const qreal newEffectiveMinimumHeight = effectiveMinimumHeight(d); + if (qFuzzyCompare(newEffectiveMinimumHeight, oldEffectiveMinimumHeight)) + return; + + d->requestLayoutView(); + emit minimumHeightChanged(); +} + +/*! + \qmlattachedproperty real QtQuick.Controls::SplitView::preferredWidth + + This attached property controls the preferred width of the split item. The + preferred width will be used as the size of the item, and will be bound + within the \l minimumWidth and \l maximumWidth. If the preferred width + is not set, the item's \l {Item::}{implicitWidth} will be used. + + When a split item is resized, the preferredWidth will be set in order + to keep track of the new size. + + By default, this property is not set, and therefore + \l {Item::}{implicitWidth} will be used instead. To reset this property to + its default value, set it to \c undefined. + + \note Do not set the \l{Item::}{width} property of a split item, as it will be + overwritten upon each layout of the SplitView. + + \sa minimumWidth, maximumWidth, fillWidth, preferredHeight +*/ +qreal QQuickSplitViewAttached::preferredWidth() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_preferredWidth; +} + +void QQuickSplitViewAttached::setPreferredWidth(qreal width) +{ + Q_D(QQuickSplitViewAttached); + d->m_isPreferredWidthSet = true; + // Make sure that we clear this flag now, before we emit the change signals + // which could cause another setter to be called. + auto splitViewPrivate = d->m_splitView ? QQuickSplitViewPrivate::get(d->m_splitView) : nullptr; + const bool ignoreNextLayoutRequest = splitViewPrivate && splitViewPrivate->m_ignoreNextLayoutRequest; + if (splitViewPrivate) + splitViewPrivate->m_ignoreNextLayoutRequest = false; + + if (qFuzzyCompare(width, d->m_preferredWidth)) + return; + + d->m_preferredWidth = width; + + if (!ignoreNextLayoutRequest) { + // We are currently in the middle of performing a layout, and the user (not our internal code) + // changed the preferred width of one of the split items, so request another layout. + d->requestLayoutView(); + } + + emit preferredWidthChanged(); +} + +void QQuickSplitViewAttached::resetPreferredWidth() +{ + Q_D(QQuickSplitViewAttached); + const qreal oldEffectivePreferredWidth = effectivePreferredWidth( + d, QQuickItemPrivate::get(d->m_splitItem)); + + d->m_isPreferredWidthSet = false; + d->m_preferredWidth = -1; + + const qreal newEffectivePreferredWidth = effectivePreferredWidth( + d, QQuickItemPrivate::get(d->m_splitItem)); + if (qFuzzyCompare(newEffectivePreferredWidth, oldEffectivePreferredWidth)) + return; + + d->requestLayoutView(); + emit preferredWidthChanged(); +} + +/*! + \qmlattachedproperty real QtQuick.Controls::SplitView::preferredHeight + + This attached property controls the preferred height of the split item. The + preferred height will be used as the size of the item, and will be bound + within the \l minimumHeight and \l maximumHeight. If the preferred height + is not set, the item's \l{Item::}{implicitHeight} will be used. + + When a split item is resized, the preferredHeight will be set in order + to keep track of the new size. + + By default, this property is not set, and therefore + \l{Item::}{implicitHeight} will be used instead. To reset this property to + its default value, set it to \c undefined. + + \note Do not set the \l{Item::}{height} property of a split item, as it will be + overwritten upon each layout of the SplitView. + + \sa minimumHeight, maximumHeight, fillHeight, preferredWidth +*/ +qreal QQuickSplitViewAttached::preferredHeight() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_preferredHeight; +} + +void QQuickSplitViewAttached::setPreferredHeight(qreal height) +{ + Q_D(QQuickSplitViewAttached); + d->m_isPreferredHeightSet = true; + // Make sure that we clear this flag now, before we emit the change signals + // which could cause another setter to be called. + auto splitViewPrivate = d->m_splitView ? QQuickSplitViewPrivate::get(d->m_splitView) : nullptr; + const bool ignoreNextLayoutRequest = splitViewPrivate && splitViewPrivate->m_ignoreNextLayoutRequest; + if (splitViewPrivate) + splitViewPrivate->m_ignoreNextLayoutRequest = false; + + if (qFuzzyCompare(height, d->m_preferredHeight)) + return; + + d->m_preferredHeight = height; + + if (!ignoreNextLayoutRequest) { + // We are currently in the middle of performing a layout, and the user (not our internal code) + // changed the preferred height of one of the split items, so request another layout. + d->requestLayoutView(); + } + + emit preferredHeightChanged(); +} + +void QQuickSplitViewAttached::resetPreferredHeight() +{ + Q_D(QQuickSplitViewAttached); + const qreal oldEffectivePreferredHeight = effectivePreferredHeight( + d, QQuickItemPrivate::get(d->m_splitItem)); + + d->m_isPreferredHeightSet = false; + d->m_preferredHeight = -1; + + const qreal newEffectivePreferredHeight = effectivePreferredHeight( + d, QQuickItemPrivate::get(d->m_splitItem)); + if (qFuzzyCompare(newEffectivePreferredHeight, oldEffectivePreferredHeight)) + return; + + d->requestLayoutView(); + emit preferredHeightChanged(); +} + +/*! + \qmlattachedproperty real QtQuick.Controls::SplitView::maximumWidth + + This attached property controls the maximum width of the split item. + The \l preferredWidth is bound within the \l minimumWidth and + \l maximumWidth. A split item cannot be dragged to be larger than + its \c maximumWidth. + + The default value is \c Infinity. To reset this property to its default + value, set it to \c undefined. + + \sa minimumWidth, preferredWidth, fillWidth, maximumHeight +*/ +qreal QQuickSplitViewAttached::maximumWidth() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_maximumWidth; +} + +void QQuickSplitViewAttached::setMaximumWidth(qreal width) +{ + Q_D(QQuickSplitViewAttached); + d->m_isMaximumWidthSet = true; + if (qFuzzyCompare(width, d->m_maximumWidth)) + return; + + d->m_maximumWidth = width; + d->requestLayoutView(); + emit maximumWidthChanged(); +} + +void QQuickSplitViewAttached::resetMaximumWidth() +{ + Q_D(QQuickSplitViewAttached); + const qreal oldEffectiveMaximumWidth = effectiveMaximumWidth(d); + + d->m_isMaximumWidthSet = false; + d->m_maximumWidth = -1; + + const qreal newEffectiveMaximumWidth = effectiveMaximumWidth(d); + if (qFuzzyCompare(newEffectiveMaximumWidth, oldEffectiveMaximumWidth)) + return; + + d->requestLayoutView(); + emit maximumWidthChanged(); +} + +/*! + \qmlattachedproperty real QtQuick.Controls::SplitView::maximumHeight + + This attached property controls the maximum height of the split item. + The \l preferredHeight is bound within the \l minimumHeight and + \l maximumHeight. A split item cannot be dragged to be larger than + its \c maximumHeight. + + The default value is \c Infinity. To reset this property to its default + value, set it to \c undefined. + + \sa minimumHeight, preferredHeight, fillHeight, maximumWidth +*/ +qreal QQuickSplitViewAttached::maximumHeight() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_maximumHeight; +} + +void QQuickSplitViewAttached::setMaximumHeight(qreal height) +{ + Q_D(QQuickSplitViewAttached); + d->m_isMaximumHeightSet = true; + if (qFuzzyCompare(height, d->m_maximumHeight)) + return; + + d->m_maximumHeight = height; + d->requestLayoutView(); + emit maximumHeightChanged(); +} + +void QQuickSplitViewAttached::resetMaximumHeight() +{ + Q_D(QQuickSplitViewAttached); + const qreal oldEffectiveMaximumHeight = effectiveMaximumHeight(d); + + d->m_isMaximumHeightSet = false; + d->m_maximumHeight = -1; + + const qreal newEffectiveMaximumHeight = effectiveMaximumHeight(d); + if (qFuzzyCompare(newEffectiveMaximumHeight, oldEffectiveMaximumHeight)) + return; + + d->requestLayoutView(); + emit maximumHeightChanged(); +} + +/*! + \qmlattachedproperty bool QtQuick.Controls::SplitView::fillWidth + + This attached property controls whether the item takes the remaining space + in the split view after all other items have been laid out. + + By default, the last visible child of the split view will have this set, + but it can be changed by explicitly setting \c fillWidth to \c true on + another item. + + The width of a split item with \c fillWidth set to \c true is still + restricted within its \l minimumWidth and \l maximumWidth. + + \sa minimumWidth, preferredWidth, maximumWidth, fillHeight +*/ +bool QQuickSplitViewAttached::fillWidth() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_fillWidth; +} + +void QQuickSplitViewAttached::setFillWidth(bool fill) +{ + Q_D(QQuickSplitViewAttached); + d->m_isFillWidthSet = true; + if (fill == d->m_fillWidth) + return; + + d->m_fillWidth = fill; + if (d->m_splitView && d->m_splitView->orientation() == Qt::Horizontal) + QQuickSplitViewPrivate::get(d->m_splitView)->updateFillIndex(); + d->requestLayoutView(); + emit fillWidthChanged(); +} + +/*! + \qmlattachedproperty bool QtQuick.Controls::SplitView::fillHeight + + This attached property controls whether the item takes the remaining space + in the split view after all other items have been laid out. + + By default, the last visible child of the split view will have this set, + but it can be changed by explicitly setting \c fillHeight to \c true on + another item. + + The height of a split item with \c fillHeight set to \c true is still + restricted within its \l minimumHeight and \l maximumHeight. + + \sa minimumHeight, preferredHeight, maximumHeight, fillWidth +*/ +bool QQuickSplitViewAttached::fillHeight() const +{ + Q_D(const QQuickSplitViewAttached); + return d->m_fillHeight; +} + +void QQuickSplitViewAttached::setFillHeight(bool fill) +{ + Q_D(QQuickSplitViewAttached); + d->m_isFillHeightSet = true; + if (fill == d->m_fillHeight) + return; + + d->m_fillHeight = fill; + if (d->m_splitView && d->m_splitView->orientation() == Qt::Vertical) + QQuickSplitViewPrivate::get(d->m_splitView)->updateFillIndex(); + d->requestLayoutView(); + emit fillHeightChanged(); +} + +QQuickSplitViewAttachedPrivate::QQuickSplitViewAttachedPrivate() + : m_fillWidth(false) + , m_fillHeight(false) + , m_isFillWidthSet(false) + , m_isFillHeightSet(false) + , m_isMinimumWidthSet(false) + , m_isMinimumHeightSet(false) + , m_isPreferredWidthSet(false) + , m_isPreferredHeightSet(false) + , m_isMaximumWidthSet(false) + , m_isMaximumHeightSet(false) + , m_minimumWidth(0) + , m_minimumHeight(0) + , m_preferredWidth(-1) + , m_preferredHeight(-1) + , m_maximumWidth(std::numeric_limits<qreal>::infinity()) + , m_maximumHeight(std::numeric_limits<qreal>::infinity()) +{ +} + +void QQuickSplitViewAttachedPrivate::setView(QQuickSplitView *newView) +{ + Q_Q(QQuickSplitViewAttached); + if (newView == m_splitView) + return; + + m_splitView = newView; + qCDebug(qlcQQuickSplitView) << "set SplitView" << newView << "on attached object" << this; + emit q->viewChanged(); +} + +void QQuickSplitViewAttachedPrivate::requestLayoutView() +{ + if (m_splitView) + QQuickSplitViewPrivate::get(m_splitView)->requestLayout(); +} + +QQuickSplitViewAttachedPrivate *QQuickSplitViewAttachedPrivate::get(QQuickSplitViewAttached *attached) +{ + return attached->d_func(); +} + +const QQuickSplitViewAttachedPrivate *QQuickSplitViewAttachedPrivate::get(const QQuickSplitViewAttached *attached) +{ + return attached->d_func(); +} + +QQuickSplitHandleAttachedPrivate::QQuickSplitHandleAttachedPrivate() + : m_hovered(false) + , m_pressed(false) +{ +} + +void QQuickSplitHandleAttachedPrivate::setHovered(bool hovered) +{ + Q_Q(QQuickSplitHandleAttached); + if (hovered == m_hovered) + return; + + m_hovered = hovered; + emit q->hoveredChanged(); +} + +void QQuickSplitHandleAttachedPrivate::setPressed(bool pressed) +{ + Q_Q(QQuickSplitHandleAttached); + if (pressed == m_pressed) + return; + + m_pressed = pressed; + emit q->pressedChanged(); +} + +QQuickSplitHandleAttachedPrivate *QQuickSplitHandleAttachedPrivate::get(QQuickSplitHandleAttached *attached) +{ + return attached->d_func(); +} + +const QQuickSplitHandleAttachedPrivate *QQuickSplitHandleAttachedPrivate::get(const QQuickSplitHandleAttached *attached) +{ + return attached->d_func(); +} + +QQuickSplitHandleAttached::QQuickSplitHandleAttached(QObject *parent) + : QObject(*(new QQuickSplitHandleAttachedPrivate), parent) +{ +} + +/*! + \qmltype SplitHandle + \inherits QtObject +//! \instantiates QQuickSplitHandleAttached + \inqmlmodule QtQuick.Controls + \since 5.13 + \brief Provides attached properties for SplitView handles. + + SplitHandle provides attached properties for \l SplitView handles. + + For split items themselves, use the attached \l SplitView properties. + + \sa SplitView +*/ + +/*! + \qmlattachedproperty bool QtQuick.Controls::SplitHandle::hovered + + This attached property holds whether the split handle is hovered. + + \sa pressed +*/ +bool QQuickSplitHandleAttached::isHovered() const +{ + Q_D(const QQuickSplitHandleAttached); + return d->m_hovered; +} + +/*! + \qmlattachedproperty bool QtQuick.Controls::SplitHandle::pressed + + This attached property holds whether the split handle is pressed. + + \sa hovered +*/ +bool QQuickSplitHandleAttached::isPressed() const +{ + Q_D(const QQuickSplitHandleAttached); + return d->m_pressed; +} + +QQuickSplitHandleAttached *QQuickSplitHandleAttached::qmlAttachedProperties(QObject *object) +{ + return new QQuickSplitHandleAttached(object); +} + +QT_END_NAMESPACE + +#include "moc_qquicksplitview_p.cpp" diff --git a/src/quicktemplates2/qquicksplitview_p.h b/src/quicktemplates2/qquicksplitview_p.h new file mode 100644 index 00000000000..5d8f8a31758 --- /dev/null +++ b/src/quicktemplates2/qquicksplitview_p.h @@ -0,0 +1,227 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSPLITVIEW_P_H +#define QQUICKSPLITVIEW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontainer_p.h> +#include <QtQml/qqmllist.h> + +QT_BEGIN_NAMESPACE + +class QQuickSplitViewPrivate; +class QQuickSplitViewAttached; +class QQuickSplitViewAttachedPrivate; +class QQuickSplitHandleAttached; +class QQuickSplitHandleAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSplitView : public QQuickContainer +{ + Q_OBJECT + Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL) + Q_PROPERTY(bool resizing READ isResizing NOTIFY resizingChanged) + Q_PROPERTY(QQmlComponent *handle READ handle WRITE setHandle NOTIFY handleChanged FINAL) + QML_NAMED_ELEMENT(SplitView) + QML_ATTACHED(QQuickSplitViewAttached) + QML_ADDED_IN_VERSION(2, 13) + +public: + explicit QQuickSplitView(QQuickItem *parent = nullptr); + ~QQuickSplitView() override; + + Qt::Orientation orientation() const; + void setOrientation(Qt::Orientation orientation); + + bool isResizing() const; + + QQmlComponent *handle(); + void setHandle(QQmlComponent *handle); + + bool isContent(QQuickItem *item) const override; + + static QQuickSplitViewAttached *qmlAttachedProperties(QObject *object); + + // Based on the same code in QMainWindow. + enum VersionMarkers { + VersionMarker = 0xff + }; + Q_INVOKABLE QVariant saveState(); + Q_INVOKABLE bool restoreState(const QVariant &state); + +Q_SIGNALS: + void orientationChanged(); + void resizingChanged(); + void handleChanged(); + +protected: + QQuickSplitView(QQuickSplitViewPrivate &dd, QQuickItem *parent); + + void componentComplete() override; + void hoverMoveEvent(QHoverEvent *event) override; + void hoverLeaveEvent(QHoverEvent *event) override; + bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + + void itemAdded(int index, QQuickItem *item) override; + void itemMoved(int index, QQuickItem *item) override; + void itemRemoved(int index, QQuickItem *item) override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickSplitView) + Q_DECLARE_PRIVATE(QQuickSplitView) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSplitViewAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickSplitView *view READ view NOTIFY viewChanged FINAL) + Q_PROPERTY(qreal minimumWidth READ minimumWidth WRITE setMinimumWidth + RESET resetMinimumWidth NOTIFY minimumWidthChanged FINAL) + Q_PROPERTY(qreal minimumHeight READ minimumHeight WRITE setMinimumHeight + RESET resetMinimumHeight NOTIFY minimumHeightChanged FINAL) + Q_PROPERTY(qreal preferredWidth READ preferredWidth WRITE setPreferredWidth + RESET resetPreferredWidth NOTIFY preferredWidthChanged FINAL) + Q_PROPERTY(qreal preferredHeight READ preferredHeight WRITE setPreferredHeight + RESET resetPreferredHeight NOTIFY preferredHeightChanged FINAL) + Q_PROPERTY(qreal maximumWidth READ maximumWidth WRITE setMaximumWidth + RESET resetMaximumWidth NOTIFY maximumWidthChanged FINAL) + Q_PROPERTY(qreal maximumHeight READ maximumHeight WRITE setMaximumHeight + RESET resetMaximumHeight NOTIFY maximumHeightChanged FINAL) + Q_PROPERTY(bool fillHeight READ fillHeight WRITE setFillHeight NOTIFY fillHeightChanged FINAL) + Q_PROPERTY(bool fillWidth READ fillWidth WRITE setFillWidth NOTIFY fillWidthChanged FINAL) + +public: + explicit QQuickSplitViewAttached(QObject *parent = nullptr); + + QQuickSplitView *view() const; + + qreal minimumWidth() const; + void setMinimumWidth(qreal width); + void resetMinimumWidth(); + + qreal minimumHeight() const; + void setMinimumHeight(qreal height); + void resetMinimumHeight(); + + qreal preferredWidth() const; + void setPreferredWidth(qreal width); + void resetPreferredWidth(); + + qreal preferredHeight() const; + void setPreferredHeight(qreal height); + void resetPreferredHeight(); + + qreal maximumWidth() const; + void setMaximumWidth(qreal width); + void resetMaximumWidth(); + + qreal maximumHeight() const; + void setMaximumHeight(qreal height); + void resetMaximumHeight(); + + bool fillWidth() const; + void setFillWidth(bool fill); + + bool fillHeight() const; + void setFillHeight(bool fill); + +Q_SIGNALS: + void viewChanged(); + void minimumWidthChanged(); + void minimumHeightChanged(); + void preferredWidthChanged(); + void preferredHeightChanged(); + void maximumWidthChanged(); + void maximumHeightChanged(); + void fillWidthChanged(); + void fillHeightChanged(); + +private: + Q_DISABLE_COPY(QQuickSplitViewAttached) + Q_DECLARE_PRIVATE(QQuickSplitViewAttached) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSplitHandleAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged FINAL) + Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged FINAL) + QML_NAMED_ELEMENT(SplitHandle) + QML_ATTACHED(QQuickSplitHandleAttached) + QML_UNCREATABLE("") + QML_ADDED_IN_VERSION(2, 13) + +public: + explicit QQuickSplitHandleAttached(QObject *parent = nullptr); + + bool isHovered() const; + bool isPressed() const; + + static QQuickSplitHandleAttached *qmlAttachedProperties(QObject *object); + +Q_SIGNALS: + void hoveredChanged(); + void pressedChanged(); + +private: + Q_DISABLE_COPY(QQuickSplitHandleAttached) + Q_DECLARE_PRIVATE(QQuickSplitHandleAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickSplitView) +QML_DECLARE_TYPEINFO(QQuickSplitView, QML_HAS_ATTACHED_PROPERTIES) + +QML_DECLARE_TYPE(QQuickSplitHandleAttached) +QML_DECLARE_TYPEINFO(QQuickSplitHandleAttached, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKSPLITVIEW_P_H diff --git a/src/quicktemplates2/qquicksplitview_p_p.h b/src/quicktemplates2/qquicksplitview_p_p.h new file mode 100644 index 00000000000..fdf27f5002e --- /dev/null +++ b/src/quicktemplates2/qquicksplitview_p_p.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSPLITVIEW_P_P_H +#define QQUICKSPLITVIEW_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontainer_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickSplitView; +class QQuickSplitViewAttached; +class QQuickSplitHandleAttached; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSplitViewPrivate : public QQuickContainerPrivate +{ + Q_DECLARE_PUBLIC(QQuickSplitView) + +public: + void updateFillIndex(); + void layoutResizeSplitItems(qreal &usedWidth, qreal &usedHeight, int &indexBeingResizedDueToDrag); + void layoutResizeFillItem(QQuickItem *fillItem, qreal &usedWidth, qreal &usedHeight, int indexBeingResizedDueToDrag); + void layoutPositionItems(const QQuickItem *fillItem); + void requestLayout(); + void layout(); + void createHandles(); + void createHandleItem(int index); + void removeExcessHandles(); + void destroyHandles(); + void resizeHandle(QQuickItem *handleItem); + void resizeHandles(); +#if QT_CONFIG(cursor) + void updateCursorHandle(QQuickItem *handleItem); +#endif + void updateHandleVisibilities(); + void updateHoveredHandle(QQuickItem *hoveredItem); + void setResizing(bool resizing); + + bool isHorizontal() const; + qreal accumulatedSize(int firstIndex, int lastIndex) const; + + struct EffectiveSizeData { + qreal effectiveMinimumWidth; + qreal effectiveMinimumHeight; + qreal effectivePreferredWidth; + qreal effectivePreferredHeight; + qreal effectiveMaximumWidth; + qreal effectiveMaximumHeight; + }; + + EffectiveSizeData effectiveSizeData(const QQuickItemPrivate *itemPrivate, + const QQuickSplitViewAttached *attached) const; + + int handleIndexForSplitIndex(int splitIndex) const; + + QQuickItem *getContentItem() override; + void handlePress(const QPointF &point) override; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + + void itemVisibilityChanged(QQuickItem *item) override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + void updatePolish() override; + + static QQuickSplitViewPrivate *get(QQuickSplitView *splitView); + + Qt::Orientation m_orientation = Qt::Horizontal; + QQmlComponent *m_handle = nullptr; + QList<QQuickItem*> m_handleItems; + int m_hoveredHandleIndex = -1; + int m_pressedHandleIndex = -1; + int m_nextVisibleIndexAfterPressedHandle = -1; + QPointF m_pressPos; + QPointF m_mousePos; + QPointF m_handlePosBeforePress; + qreal m_leftOrTopItemSizeBeforePress = 0.0; + qreal m_rightOrBottomItemSizeBeforePress = 0.0; + int m_fillIndex = -1; + bool m_layingOut = false; + bool m_ignoreNextLayoutRequest = false; + bool m_resizing = false; +}; + +class QQuickSplitViewAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickSplitViewAttached) + +public: + QQuickSplitViewAttachedPrivate(); + + void setView(QQuickSplitView *newView); + void requestLayoutView(); + + static QQuickSplitViewAttachedPrivate *get(QQuickSplitViewAttached *attached); + static const QQuickSplitViewAttachedPrivate *get(const QQuickSplitViewAttached *attached); + + QQuickItem *m_splitItem = nullptr; + QQuickSplitView *m_splitView = nullptr; + + unsigned m_fillWidth : 1; + unsigned m_fillHeight : 1; + unsigned m_isFillWidthSet : 1; + unsigned m_isFillHeightSet : 1; + unsigned m_isMinimumWidthSet : 1; + unsigned m_isMinimumHeightSet : 1; + unsigned m_isPreferredWidthSet : 1; + unsigned m_isPreferredHeightSet : 1; + unsigned m_isMaximumWidthSet : 1; + unsigned m_isMaximumHeightSet : 1; + qreal m_minimumWidth; + qreal m_minimumHeight; + qreal m_preferredWidth; + qreal m_preferredHeight; + qreal m_maximumWidth; + qreal m_maximumHeight; +}; + +class QQuickSplitHandleAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickSplitHandleAttached) + +public: + QQuickSplitHandleAttachedPrivate(); + + void setHovered(bool hovered); + void setPressed(bool pressed); + + static QQuickSplitHandleAttachedPrivate *get(QQuickSplitHandleAttached *attached); + static const QQuickSplitHandleAttachedPrivate *get(const QQuickSplitHandleAttached *attached); + + unsigned m_hovered : 1; + unsigned m_pressed : 1; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSPLITVIEW_P_P_H diff --git a/src/quicktemplates2/qquickstackelement.cpp b/src/quicktemplates2/qquickstackelement.cpp new file mode 100644 index 00000000000..c2291e8cae5 --- /dev/null +++ b/src/quicktemplates2/qquickstackelement.cpp @@ -0,0 +1,343 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstackelement_p_p.h" +#include "qquickstackview_p_p.h" + +#include <QtQml/qqmlinfo.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlincubator.h> +#include <QtQml/private/qv4qobjectwrapper_p.h> +#include <QtQml/private/qqmlcomponent_p.h> +#include <QtQml/private/qqmlengine_p.h> +#include <QtQml/private/qqmlincubator_p.h> + +QT_BEGIN_NAMESPACE + +static QQuickStackViewAttached *attachedStackObject(QQuickStackElement *element) +{ + QQuickStackViewAttached *attached = qobject_cast<QQuickStackViewAttached *>(qmlAttachedPropertiesObject<QQuickStackView>(element->item, false)); + if (attached) + QQuickStackViewAttachedPrivate::get(attached)->element = element; + return attached; +} + +class QQuickStackIncubator : public QQmlIncubator +{ +public: + QQuickStackIncubator(QQuickStackElement *element) + : QQmlIncubator(Synchronous), + element(element) + { + } + +protected: + void setInitialState(QObject *object) override + { + auto privIncubator = QQmlIncubatorPrivate::get(this); + element->incubate(object, privIncubator->requiredProperties()); + } + +private: + QQuickStackElement *element; +}; + +QQuickStackElement::QQuickStackElement() + : QQuickItemViewTransitionableItem(nullptr) +{ +} + +QQuickStackElement::~QQuickStackElement() +{ + if (item) + QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed); + + if (ownComponent) + delete component; + + QQuickStackViewAttached *attached = attachedStackObject(this); + if (item) { + if (ownItem) { + item->setParentItem(nullptr); + item->deleteLater(); + item = nullptr; + } else { + setVisible(false); + if (!widthValid) + item->resetWidth(); + if (!heightValid) + item->resetHeight(); + if (item->parentItem() != originalParent) { + item->setParentItem(originalParent); + } else { + if (attached) + QQuickStackViewAttachedPrivate::get(attached)->itemParentChanged(item, nullptr); + } + } + } + + if (attached) + emit attached->removed(); + + delete context; +} + +QQuickStackElement *QQuickStackElement::fromString(const QString &str, QQuickStackView *view, QString *error) +{ + QUrl url(str); + if (!url.isValid()) { + *error = QStringLiteral("invalid url: ") + str; + return nullptr; + } + + if (url.isRelative()) + url = qmlContext(view)->resolvedUrl(url); + + QQuickStackElement *element = new QQuickStackElement; + element->component = new QQmlComponent(qmlEngine(view), url, view); + element->ownComponent = true; + return element; +} + +QQuickStackElement *QQuickStackElement::fromObject(QObject *object, QQuickStackView *view, QString *error) +{ + Q_UNUSED(view); + QQmlComponent *component = qobject_cast<QQmlComponent *>(object); + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (!component && !item) { + *error = QQmlMetaType::prettyTypeName(object) + QStringLiteral(" is not supported. Must be Item or Component."); + return nullptr; + } + + QQuickStackElement *element = new QQuickStackElement; + element->component = qobject_cast<QQmlComponent *>(object); + element->item = qobject_cast<QQuickItem *>(object); + if (element->item) + element->originalParent = element->item->parentItem(); + return element; +} + +bool QQuickStackElement::load(QQuickStackView *parent) +{ + setView(parent); + if (!item) { + ownItem = true; + + if (component->isLoading()) { + QObject::connect(component, &QQmlComponent::statusChanged, [this](QQmlComponent::Status status) { + if (status == QQmlComponent::Ready) + load(view); + else if (status == QQmlComponent::Error) + QQuickStackViewPrivate::get(view)->warn(component->errorString().trimmed()); + }); + return true; + } + + QQmlContext *creationContext = component->creationContext(); + if (!creationContext) + creationContext = qmlContext(parent); + context = new QQmlContext(creationContext, parent); + context->setContextObject(parent); + + QQuickStackIncubator incubator(this); + component->create(incubator, context); + if (component->isError()) + QQuickStackViewPrivate::get(parent)->warn(component->errorString().trimmed()); + } else { + RequiredProperties noRequiredProperties {}; + initialize(noRequiredProperties); + } + return item; +} + +void QQuickStackElement::incubate(QObject *object, RequiredProperties &requiredProperties) +{ + item = qmlobject_cast<QQuickItem *>(object); + if (item) { + QQmlEngine::setObjectOwnership(item, QQmlEngine::CppOwnership); + item->setParent(view); + initialize(requiredProperties); + } +} + +void QQuickStackElement::initialize(RequiredProperties &requiredProperties) +{ + if (!item || init) + return; + + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + if (!(widthValid = p->widthValid())) + item->setWidth(view->width()); + if (!(heightValid = p->heightValid())) + item->setHeight(view->height()); + item->setParentItem(view); + + if (!properties.isUndefined()) { + QQmlEngine *engine = qmlEngine(view); + Q_ASSERT(engine); + QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine); + Q_ASSERT(v4); + QV4::Scope scope(v4); + QV4::ScopedValue ipv(scope, properties.value()); + QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value()); + QV4::ScopedValue qmlObject(scope, QV4::QObjectWrapper::wrap(v4, item)); + QQmlComponentPrivate::setInitialProperties( + v4, qmlContext, qmlObject, ipv, requiredProperties, item, + component ? QQmlComponentPrivate::get(component)->state.creator.data() : nullptr); + properties.clear(); + } + + if (!requiredProperties.empty()) { + QString error; + for (const auto &property: requiredProperties) { + error += QLatin1String("Property %1 was marked as required but not set.\n") + .arg(property.propertyName); + } + QQuickStackViewPrivate::get(view)->warn(error); + item = nullptr; + } else { + p->addItemChangeListener(this, QQuickItemPrivate::Destroyed); + } + + init = true; +} + +void QQuickStackElement::setIndex(int value) +{ + if (index == value) + return; + + index = value; + QQuickStackViewAttached *attached = attachedStackObject(this); + if (attached) + emit attached->indexChanged(); +} + +void QQuickStackElement::setView(QQuickStackView *value) +{ + if (view == value) + return; + + view = value; + QQuickStackViewAttached *attached = attachedStackObject(this); + if (attached) + emit attached->viewChanged(); +} + +void QQuickStackElement::setStatus(QQuickStackView::Status value) +{ + if (status == value) + return; + + status = value; + QQuickStackViewAttached *attached = attachedStackObject(this); + if (!attached) + return; + + switch (value) { + case QQuickStackView::Inactive: + emit attached->deactivated(); + break; + case QQuickStackView::Deactivating: + emit attached->deactivating(); + break; + case QQuickStackView::Activating: + emit attached->activating(); + break; + case QQuickStackView::Active: + emit attached->activated(); + break; + default: + Q_UNREACHABLE(); + break; + } + + emit attached->statusChanged(); +} + +void QQuickStackElement::setVisible(bool visible) +{ + QQuickStackViewAttached *attached = attachedStackObject(this); + if (!item || (attached && QQuickStackViewAttachedPrivate::get(attached)->explicitVisible)) + return; + + item->setVisible(visible); +} + +void QQuickStackElement::transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget) +{ + if (transitioner) + transitioner->transitionNextReposition(this, type, asTarget); +} + +bool QQuickStackElement::prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds) +{ + if (transitioner) { + if (item) { + QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors; + // TODO: expose QQuickAnchorLine so we can test for other conflicting anchors + if (anchors && (anchors->fill() || anchors->centerIn())) + qmlWarning(item) << "StackView has detected conflicting anchors. Transitions may not execute properly."; + } + + // TODO: add force argument to QQuickItemViewTransitionableItem::prepareTransition()? + nextTransitionToSet = true; + nextTransitionFromSet = true; + nextTransitionFrom += QPointF(1, 1); + return QQuickItemViewTransitionableItem::prepareTransition(transitioner, index, viewBounds); + } + return false; +} + +void QQuickStackElement::startTransition(QQuickItemViewTransitioner *transitioner, QQuickStackView::Status status) +{ + setStatus(status); + if (transitioner) + QQuickItemViewTransitionableItem::startTransition(transitioner, index); +} + +void QQuickStackElement::completeTransition(QQuickTransition *quickTransition) +{ + QQuickItemViewTransitionableItem::completeTransition(quickTransition); +} + +void QQuickStackElement::itemDestroyed(QQuickItem *) +{ + item = nullptr; +} + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickstackelement_p_p.h b/src/quicktemplates2/qquickstackelement_p_p.h new file mode 100644 index 00000000000..1c7cd5632b8 --- /dev/null +++ b/src/quicktemplates2/qquickstackelement_p_p.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTACKELEMENT_P_P_H +#define QQUICKSTACKELEMENT_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickstackview_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p_p.h> +#include <QtQuick/private/qquickitemviewtransition_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQml/private/qv4persistent_p.h> + +QT_BEGIN_NAMESPACE + +class QQmlContext; +class QQmlComponent; +struct QQuickStackTransition; +class RequiredProperties; + +class QQuickStackElement : public QQuickItemViewTransitionableItem, public QQuickItemChangeListener +{ + QQuickStackElement(); + +public: + ~QQuickStackElement(); + + static QQuickStackElement *fromString(const QString &str, QQuickStackView *view, QString *error); + static QQuickStackElement *fromObject(QObject *object, QQuickStackView *view, QString *error); + + bool load(QQuickStackView *parent); + void incubate(QObject *object, RequiredProperties &requiredProperties); + void initialize(RequiredProperties &requiredProperties); + + void setIndex(int index); + void setView(QQuickStackView *view); + void setStatus(QQuickStackView::Status status); + void setVisible(bool visible); + + void transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget); + bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds); + void startTransition(QQuickItemViewTransitioner *transitioner, QQuickStackView::Status status); + void completeTransition(QQuickTransition *quickTransition); + + void itemDestroyed(QQuickItem *item) override; + + int index = -1; + bool init = false; + bool removal = false; + bool ownItem = false; + bool ownComponent = false; + bool widthValid = false; + bool heightValid = false; + QQmlContext *context = nullptr; + QQmlComponent *component = nullptr; + QQuickStackView *view = nullptr; + QPointer<QQuickItem> originalParent; + QQuickStackView::Status status = QQuickStackView::Inactive; + QV4::PersistentValue properties; + QV4::PersistentValue qmlCallingContext; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTACKELEMENT_P_P_H diff --git a/src/quicktemplates2/qquickstacktransition.cpp b/src/quicktemplates2/qquickstacktransition.cpp new file mode 100644 index 00000000000..a0192d1be1b --- /dev/null +++ b/src/quicktemplates2/qquickstacktransition.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstacktransition_p_p.h" +#include "qquickstackelement_p_p.h" +#include "qquickstackview_p_p.h" + +QT_BEGIN_NAMESPACE + +static QQuickStackTransition exitTransition(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) +{ + QQuickStackTransition st; + st.status = QQuickStackView::Deactivating; + st.element = element; + + const QQuickItemViewTransitioner *transitioner = QQuickStackViewPrivate::get(view)->transitioner; + + switch (operation) { + case QQuickStackView::PushTransition: + st.type = QQuickItemViewTransitioner::AddTransition; + if (transitioner) + st.transition = transitioner->addDisplacedTransition; + break; + case QQuickStackView::ReplaceTransition: + st.type = QQuickItemViewTransitioner::MoveTransition; + if (transitioner) + st.transition = transitioner->moveDisplacedTransition; + break; + case QQuickStackView::PopTransition: + st.target = true; + st.type = QQuickItemViewTransitioner::RemoveTransition; + st.viewBounds = view->boundingRect(); + if (transitioner) + st.transition = transitioner->removeTransition; + break; + default: + Q_UNREACHABLE(); + break; + } + + return st; +} + +static QQuickStackTransition enterTransition(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) +{ + QQuickStackTransition st; + st.status = QQuickStackView::Activating; + st.element = element; + + const QQuickItemViewTransitioner *transitioner = QQuickStackViewPrivate::get(view)->transitioner; + + switch (operation) { + case QQuickStackView::PushTransition: + st.target = true; + st.type = QQuickItemViewTransitioner::AddTransition; + st.viewBounds = view->boundingRect(); + if (transitioner) + st.transition = transitioner->addTransition; + break; + case QQuickStackView::ReplaceTransition: + st.target = true; + st.type = QQuickItemViewTransitioner::MoveTransition; + st.viewBounds = view->boundingRect(); + if (transitioner) + st.transition = transitioner->moveTransition; + break; + case QQuickStackView::PopTransition: + st.type = QQuickItemViewTransitioner::RemoveTransition; + if (transitioner) + st.transition = transitioner->removeDisplacedTransition; + break; + default: + Q_UNREACHABLE(); + break; + } + + return st; +} + +static QQuickStackView::Operation operationTransition(QQuickStackView::Operation operation, QQuickStackView::Operation transition) +{ + if (operation == QQuickStackView::Immediate || operation == QQuickStackView::Transition) + return transition; + return operation; +} + +QQuickStackTransition QQuickStackTransition::popExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) +{ + return exitTransition(operationTransition(operation, QQuickStackView::PopTransition), element, view); +} + +QQuickStackTransition QQuickStackTransition::popEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) +{ + return enterTransition(operationTransition(operation, QQuickStackView::PopTransition), element, view); +} + +QQuickStackTransition QQuickStackTransition::pushExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) +{ + return exitTransition(operationTransition(operation, QQuickStackView::PushTransition), element, view); +} + +QQuickStackTransition QQuickStackTransition::pushEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) +{ + return enterTransition(operationTransition(operation, QQuickStackView::PushTransition), element, view); +} + +QQuickStackTransition QQuickStackTransition::replaceExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) +{ + return exitTransition(operationTransition(operation, QQuickStackView::ReplaceTransition), element, view); +} + +QQuickStackTransition QQuickStackTransition::replaceEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) +{ + return enterTransition(operationTransition(operation, QQuickStackView::ReplaceTransition), element, view); +} + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickstacktransition_p_p.h b/src/quicktemplates2/qquickstacktransition_p_p.h new file mode 100644 index 00000000000..3a08fb4a681 --- /dev/null +++ b/src/quicktemplates2/qquickstacktransition_p_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTACKTRANSITION_P_P_H +#define QQUICKSTACKTRANSITION_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickstackview_p.h> +#include <QtQuick/private/qquickitemviewtransition_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStackElement; + +struct QQuickStackTransition +{ + static QQuickStackTransition popExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view); + static QQuickStackTransition popEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view); + + static QQuickStackTransition pushExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view); + static QQuickStackTransition pushEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view); + + static QQuickStackTransition replaceExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view); + static QQuickStackTransition replaceEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view); + + bool target = false; + QQuickStackView::Status status = QQuickStackView::Inactive; + QQuickItemViewTransitioner::TransitionType type = QQuickItemViewTransitioner::NoTransition; + QRectF viewBounds; + QQuickStackElement *element = nullptr; + QQuickTransition *transition = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTACKTRANSITION_P_P_H diff --git a/src/quicktemplates2/qquickstackview.cpp b/src/quicktemplates2/qquickstackview.cpp new file mode 100644 index 00000000000..77b674a22ac --- /dev/null +++ b/src/quicktemplates2/qquickstackview.cpp @@ -0,0 +1,1407 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstackview_p.h" +#include "qquickstackview_p_p.h" +#include "qquickstackelement_p_p.h" +#include "qquickstacktransition_p_p.h" + +#include <QtCore/qscopedvaluerollback.h> +#include <QtQml/qjsvalue.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlinfo.h> + +#include <private/qv4qobjectwrapper_p.h> +#include <private/qqmlengine_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype StackView + \inherits Control +//! \instantiates QQuickStackView + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-navigation + \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes + \brief Provides a stack-based navigation model. + + \image qtquickcontrols2-stackview-wireframe.png + + StackView can be used with a set of inter-linked information pages. For + example, an email application with separate views to list the latest emails, + view a specific email, and list/view the attachments. The email list view + is pushed onto the stack as users open an email, and popped out as they + choose to go back. + + The following snippet demonstrates a simple use case, where the \c mainView + is pushed onto and popped out of the stack on relevant button click: + + \qml + ApplicationWindow { + title: qsTr("Hello World") + width: 640 + height: 480 + visible: true + + StackView { + id: stack + initialItem: mainView + anchors.fill: parent + } + + Component { + id: mainView + + Row { + spacing: 10 + + Button { + text: "Push" + onClicked: stack.push(mainView) + } + Button { + text: "Pop" + enabled: stack.depth > 1 + onClicked: stack.pop() + + } + Text { + text: stack.depth + } + } + } + } + \endqml + + \section1 Using StackView in an Application + + Using StackView in an application is as simple as adding it as a child to + a Window. The stack is usually anchored to the edges of the window, except + at the top or bottom where it might be anchored to a status bar, or some + other similar UI component. The stack can then be used by invoking its + navigation methods. The first item to show in the StackView is the one + that was assigned to \l initialItem, or the topmost item if \l initialItem + is not set. + + \section1 Basic Navigation + + StackView supports three primary navigation operations: push(), pop(), and + replace(). These correspond to classic stack operations where "push" adds + an item to the top of a stack, "pop" removes the top item from the + stack, and "replace" is like a pop followed by a push, which replaces the + topmost item with the new item. The topmost item in the stack + corresponds to the one that is \l{StackView::currentItem}{currently} + visible on screen. Logically, "push" navigates forward or deeper into the + application UI, "pop" navigates backward, and "replace" replaces the + \l currentItem. + + \section2 Pushing Items + + In the following animation, three \l Label controls are pushed onto a + stack view with the \l push() function: + + \image qtquickcontrols2-stackview-push.gif + + The stack now contains the following items: \c [A, B, C]. + + \note When the stack is empty, a push() operation will not have a + transition animation because there is nothing to transition from (typically + on application start-up). + + \section2 Popping Items + + Continuing on from the example above, the topmost item on the stack is + removed with a call to \l pop(): + + \image qtquickcontrols2-stackview-pop.gif + + The stack now contains the following items: \c [A, B]. + + \note A pop() operation on a stack with depth 1 or 0 does nothing. In such + cases, the stack can be emptied using the \l clear() method. + + \section3 Unwinding Items via Pop + + Sometimes, it is necessary to go back more than a single step in the stack. + For example, to return to a "main" item or some kind of section item in the + application. In such cases, it is possible to specify an item as a + parameter for pop(). This is called an "unwind" operation, where the stack + unwinds till the specified item. If the item is not found, stack unwinds + until it is left with one item, which becomes the \l currentItem. To + explicitly unwind to the bottom of the stack, it is recommended to use + \l{pop()}{pop(null)}, although any non-existent item will do. + + In the following animation, we unwind the stack to the first item by + calling \c pop(null): + + \image qtquickcontrols2-stackview-unwind.gif + + The stack now contains a single item: \c [A]. + + \section2 Replacing Items + + In the following animation, we \l replace the topmost item with \c D: + + \image qtquickcontrols2-stackview-replace.gif + + The stack now contains the following items: \c [A, B, D]. + + \section1 Deep Linking + + \e{Deep linking} means launching an application into a particular state. For + example, a newspaper application could be launched into showing a + particular article, bypassing the topmost item. In terms of StackView, deep linking means the ability to modify + the state of the stack, so much so that it is possible to push a set of + items to the top of the stack, or to completely reset the stack to a given + state. + + The API for deep linking in StackView is the same as for basic navigation. + Pushing an array instead of a single item adds all the items in that array + to the stack. The transition animation, however, is applied only for the + last item in the array. The normal semantics of push() apply for deep + linking, that is, it adds whatever is pushed onto the stack. + + \note Only the last item of the array is loaded. The rest of the items are + loaded only when needed, either on subsequent calls to pop or on request to + get an item using get(). + + This gives us the following result, given the stack [A, B, C]: + + \list + \li \l{push()}{push([D, E, F])} => [A, B, C, D, E, F] - "push" transition + animation between C and F + \li \l{replace()}{replace([D, E, F])} => [A, B, D, E, F] - "replace" + transition animation between C and F + \li \l{clear()} followed by \l{push()}{push([D, E, F])} => [D, E, F] - no + transition animation for pushing items as the stack was empty. + \endlist + + \section1 Finding Items + + An Item for which the application does not have a reference can be found + by calling find(). The method needs a callback function, which is invoked + for each item in the stack (starting at the top) until a match is found. + If the callback returns \c true, find() stops and returns the matching + item, otherwise \c null is returned. + + The code below searches the stack for an item named "order_id" and unwinds + to that item. + + \badcode + stackView.pop(stackView.find(function(item) { + return item.name == "order_id"; + })); + \endcode + + You can also get to an item in the stack using \l {get()}{get(index)}. + + \badcode + previousItem = stackView.get(myItem.StackView.index - 1)); + \endcode + + \section1 Transitions + + For each push or pop operation, different transition animations are applied + to entering and exiting items. These animations define how the entering item + should animate in, and the exiting item should animate out. The animations + can be customized by assigning different \l{Transition}s for the + \l pushEnter, \l pushExit, \l popEnter, \l popExit, \l replaceEnter, and + \l replaceExit properties of StackView. + + \note The transition animations affect each others' transitional behavior. + Customizing the animation for one and leaving the other may give unexpected + results. + + The following snippet defines a simple fade transition for push and pop + operations: + + \qml + StackView { + id: stackview + anchors.fill: parent + + pushEnter: Transition { + PropertyAnimation { + property: "opacity" + from: 0 + to:1 + duration: 200 + } + } + pushExit: Transition { + PropertyAnimation { + property: "opacity" + from: 1 + to:0 + duration: 200 + } + } + popEnter: Transition { + PropertyAnimation { + property: "opacity" + from: 0 + to:1 + duration: 200 + } + } + popExit: Transition { + PropertyAnimation { + property: "opacity" + from: 1 + to:0 + duration: 200 + } + } + } + \endqml + + \note Using anchors on the items added to a StackView is not supported. + Typically push, pop, and replace transitions animate the position, + which is not possible when anchors are applied. Notice that this + only applies to the root of the item. Using anchors for its children + works as expected. + + \section1 Item Ownership + + StackView only takes ownership of items that it creates itself. This means + that any item pushed onto a StackView will never be destroyed by the + StackView; only items that StackView creates from \l {Component}{Components} + or \l [QML] {url}{URLs} are destroyed by the StackView. To illustrate this, + the messages in the example below will only be printed when the StackView + is destroyed, not when the items are popped off the stack: + + \qml + Component { + id: itemComponent + + Item { + Component.onDestruction: print("Destroying second item") + } + } + + StackView { + initialItem: Item { + Component.onDestruction: print("Destroying initial item") + } + + Component.onCompleted: push(itemComponent.createObject(window)) + } + \endqml + + However, both of the items created from the URL and Component in the + following example will be destroyed by the StackView when they are popped + off of it: + + \qml + Component { + id: itemComponent + + Item { + Component.onDestruction: print("Destroying second item") + } + } + + StackView { + initialItem: "Item1.qml" + + Component.onCompleted: push(itemComponent) + } + \endqml + + \section1 Size + + StackView does not inherit an implicit size from items that are pushed onto + it. This means that using it as the \l {Popup::}{contentItem} of a + \l Dialog, for example, will not work as expected: + + \code + Dialog { + StackView { + initialItem: Rectangle { + width: 200 + height: 200 + color: "salmon" + } + } + } + \endcode + + There are several ways to ensure that StackView has a size in this + situation: + + \list + \li Set \l[QtQuick]{Item::}{implicitWidth} and + \l[QtQuick]{Item::}{implicitHeight} on the StackView itself. + \li Set \l[QtQuick]{Item::}{implicitWidth} and + \l[QtQuick]{Item::}{implicitHeight} on the \l Rectangle. + \li Set \l {Popup::}{contentWidth} and \l {Popup::}{contentHeight} on + the Dialog. + \li Give the Dialog a size. + \endlist + + \sa {Customizing StackView}, {Navigating with StackView}, {Navigation Controls}, + {Container Controls}, {Focus Management in Qt Quick Controls} +*/ + +QQuickStackView::QQuickStackView(QQuickItem *parent) + : QQuickControl(*(new QQuickStackViewPrivate), parent) +{ + setFlag(ItemIsFocusScope); +} + +QQuickStackView::~QQuickStackView() +{ + Q_D(QQuickStackView); + if (d->transitioner) { + d->transitioner->setChangeListener(nullptr); + delete d->transitioner; + } + qDeleteAll(d->removing); + qDeleteAll(d->removed); + qDeleteAll(d->elements); +} + +QQuickStackViewAttached *QQuickStackView::qmlAttachedProperties(QObject *object) +{ + return new QQuickStackViewAttached(object); +} + +/*! + \qmlproperty bool QtQuick.Controls::StackView::busy + \readonly + This property holds whether a transition is running. +*/ +bool QQuickStackView::isBusy() const +{ + Q_D(const QQuickStackView); + return d->busy; +} + +/*! + \qmlproperty int QtQuick.Controls::StackView::depth + \readonly + This property holds the number of items currently pushed onto the stack. +*/ +int QQuickStackView::depth() const +{ + Q_D(const QQuickStackView); + return d->elements.count(); +} + +/*! + \qmlproperty Item QtQuick.Controls::StackView::currentItem + \readonly + This property holds the current top-most item in the stack. +*/ +QQuickItem *QQuickStackView::currentItem() const +{ + Q_D(const QQuickStackView); + return d->currentItem; +} + +/*! + \qmlmethod Item QtQuick.Controls::StackView::get(index, behavior) + + Returns the item at position \a index in the stack, or \c null if the index + is out of bounds. + + Supported \a behavior values: + \value StackView.DontLoad The item is not forced to load (and \c null is returned if not yet loaded). + \value StackView.ForceLoad The item is forced to load. +*/ +QQuickItem *QQuickStackView::get(int index, LoadBehavior behavior) +{ + Q_D(QQuickStackView); + QQuickStackElement *element = d->elements.value(index); + if (element) { + if (behavior == ForceLoad) + element->load(this); + return element->item; + } + return nullptr; +} + +/*! + \qmlmethod Item QtQuick.Controls::StackView::find(callback, behavior) + + Search for a specific item inside the stack. The \a callback function is called + for each item in the stack (with the item and index as arguments) until the callback + function returns \c true. The return value is the item found. For example: + + \code + stackView.find(function(item, index) { + return item.isTheOne + }) + \endcode + + Supported \a behavior values: + \value StackView.DontLoad Unloaded items are skipped (the callback function is not called for them). + \value StackView.ForceLoad Unloaded items are forced to load. +*/ +QQuickItem *QQuickStackView::find(const QJSValue &callback, LoadBehavior behavior) +{ + Q_D(QQuickStackView); + QJSValue func(callback); + QQmlEngine *engine = qmlEngine(this); + if (!engine || !func.isCallable()) // TODO: warning? + return nullptr; + + for (int i = d->elements.count() - 1; i >= 0; --i) { + QQuickStackElement *element = d->elements.at(i); + if (behavior == ForceLoad) + element->load(this); + if (element->item) { + QJSValue rv = func.call(QJSValueList() << engine->newQObject(element->item) << i); + if (rv.toBool()) + return element->item; + } + } + + return nullptr; +} + +/*! + \qmlmethod Item QtQuick.Controls::StackView::push(item, properties, operation) + + Pushes an \a item onto the stack using an optional \a operation, and + optionally applies a set of \a properties on the item. The item can be + an \l Item, \l Component, or a \l [QML] url. Returns the item that became + current. + + StackView creates an instance automatically if the pushed item is a \l Component, + or a \l [QML] url, and the instance will be destroyed when it is popped + off the stack. See \l {Item Ownership} for more information. + + The optional \a properties argument specifies a map of initial + property values for the pushed item. For dynamically created items, these values + are applied before the creation is finalized. This is more efficient than setting + property values after creation, particularly where large sets of property values + are defined, and also allows property bindings to be set up (using \l{Qt::binding} + {Qt.binding()}) before the item is created. + + Pushing a single item: + \code + stackView.push(rect) + + // or with properties: + stackView.push(rect, {"color": "red"}) + \endcode + + Multiple items can be pushed at the same time either by passing them as + additional arguments, or as an array. The last item becomes the current + item. Each item can be followed by a set of properties to apply. + + Passing a variable amount of arguments: + \code + stackView.push(rect1, rect2, rect3) + + // or with properties: + stackView.push(rect1, {"color": "red"}, rect2, {"color": "green"}, rect3, {"color": "blue"}) + \endcode + + Pushing an array of items: + \code + stackView.push([rect1, rect2, rect3]) + + // or with properties: + stackView.push([rect1, {"color": "red"}, rect2, {"color": "green"}, rect3, {"color": "blue"}]) + \endcode + + An \a operation can be optionally specified as the last argument. Supported + operations: + + \value StackView.Immediate An immediate operation without transitions. + \value StackView.PushTransition An operation with push transitions (since QtQuick.Controls 2.1). + \value StackView.ReplaceTransition An operation with replace transitions (since QtQuick.Controls 2.1). + \value StackView.PopTransition An operation with pop transitions (since QtQuick.Controls 2.1). + + If no operation is provided, \c Immediate will be used if the stack is + empty, and \c PushTransition otherwise. + + \note Items that already exist in the stack are not pushed. + + \sa initialItem, {Pushing Items} +*/ +void QQuickStackView::push(QQmlV4Function *args) +{ + Q_D(QQuickStackView); + const QString operationName = QStringLiteral("push"); + if (d->modifyingElements) { + d->warnOfInterruption(operationName); + return; + } + + QScopedValueRollback<bool> modifyingElements(d->modifyingElements, true); + QScopedValueRollback<QString> operationNameRollback(d->operation, operationName); + if (args->length() <= 0) { + d->warn(QStringLiteral("missing arguments")); + args->setReturnValue(QV4::Encode::null()); + return; + } + + QV4::ExecutionEngine *v4 = args->v4engine(); + QV4::Scope scope(v4); + + Operation operation = d->elements.isEmpty() ? Immediate : PushTransition; + QV4::ScopedValue lastArg(scope, (*args)[args->length() - 1]); + if (lastArg->isInt32()) + operation = static_cast<Operation>(lastArg->toInt32()); + + QStringList errors; + QList<QQuickStackElement *> elements = d->parseElements(0, args, &errors); + // Remove any items that are already in the stack, as they can't be in two places at once. + for (int i = 0; i < elements.size(); ) { + QQuickStackElement *element = elements.at(i); + if (element->item && d->findElement(element->item)) + elements.removeAt(i); + else + ++i; + } + + if (!errors.isEmpty() || elements.isEmpty()) { + if (!errors.isEmpty()) { + for (const QString &error : qAsConst(errors)) + d->warn(error); + } else { + d->warn(QStringLiteral("nothing to push")); + } + args->setReturnValue(QV4::Encode::null()); + return; + } + + QQuickStackElement *exit = nullptr; + if (!d->elements.isEmpty()) + exit = d->elements.top(); + + int oldDepth = d->elements.count(); + if (d->pushElements(elements)) { + d->depthChange(d->elements.count(), oldDepth); + QQuickStackElement *enter = d->elements.top(); + d->startTransition(QQuickStackTransition::pushEnter(operation, enter, this), + QQuickStackTransition::pushExit(operation, exit, this), + operation == Immediate); + d->setCurrentItem(enter); + } + + if (d->currentItem) { + QV4::ScopedValue rv(scope, QV4::QObjectWrapper::wrap(v4, d->currentItem)); + args->setReturnValue(rv->asReturnedValue()); + } else { + args->setReturnValue(QV4::Encode::null()); + } +} + +/*! + \qmlmethod Item QtQuick.Controls::StackView::pop(item, operation) + + Pops one or more items off the stack. Returns the last item removed from the stack. + + If the \a item argument is specified, all items down to (but not + including) \a item will be popped. If \a item is \c null, all + items down to (but not including) the first item is popped. + If not specified, only the current item is popped. + + \note A pop() operation on a stack with depth 1 or 0 does nothing. In such + cases, the stack can be emptied using the \l clear() method. + + \include qquickstackview.qdocinc pop-ownership + + An \a operation can be optionally specified as the last argument. Supported + operations: + + \value StackView.Immediate An immediate operation without transitions. + \value StackView.PushTransition An operation with push transitions (since QtQuick.Controls 2.1). + \value StackView.ReplaceTransition An operation with replace transitions (since QtQuick.Controls 2.1). + \value StackView.PopTransition An operation with pop transitions (since QtQuick.Controls 2.1). + + If no operation is provided, \c PopTransition will be used. + + Examples: + \code + stackView.pop() + stackView.pop(someItem, StackView.Immediate) + stackView.pop(StackView.Immediate) + stackView.pop(null) + \endcode + + \sa clear(), {Popping Items}, {Unwinding Items via Pop} +*/ +void QQuickStackView::pop(QQmlV4Function *args) +{ + Q_D(QQuickStackView); + const QString operationName = QStringLiteral("pop"); + if (d->modifyingElements) { + d->warnOfInterruption(operationName); + args->setReturnValue(QV4::Encode::null()); + return; + } + + QScopedValueRollback<bool> modifyingElements(d->modifyingElements, true); + QScopedValueRollback<QString> operationNameRollback(d->operation, operationName); + int argc = args->length(); + if (d->elements.count() <= 1 || argc > 2) { + if (argc > 2) + d->warn(QStringLiteral("too many arguments")); + args->setReturnValue(QV4::Encode::null()); + return; + } + + int oldDepth = d->elements.count(); + QQuickStackElement *exit = d->elements.pop(); + QQuickStackElement *enter = d->elements.top(); + + QV4::ExecutionEngine *v4 = args->v4engine(); + QV4::Scope scope(v4); + + if (argc > 0) { + QV4::ScopedValue value(scope, (*args)[0]); + if (value->isNull()) { + enter = d->elements.value(0); + } else if (const QV4::QObjectWrapper *o = value->as<QV4::QObjectWrapper>()) { + QQuickItem *item = qobject_cast<QQuickItem *>(o->object()); + enter = d->findElement(item); + if (!enter) { + if (item != d->currentItem) + d->warn(QStringLiteral("unknown argument: ") + value->toQString()); // TODO: safe? + args->setReturnValue(QV4::Encode::null()); + d->elements.push(exit); // restore + return; + } + } + } + + Operation operation = PopTransition; + if (argc > 0) { + QV4::ScopedValue lastArg(scope, (*args)[argc - 1]); + if (lastArg->isInt32()) + operation = static_cast<Operation>(lastArg->toInt32()); + } + + QQuickItem *previousItem = nullptr; + + if (d->popElements(enter)) { + if (exit) { + exit->removal = true; + d->removing.insert(exit); + previousItem = exit->item; + } + d->depthChange(d->elements.count(), oldDepth); + d->startTransition(QQuickStackTransition::popExit(operation, exit, this), + QQuickStackTransition::popEnter(operation, enter, this), + operation == Immediate); + d->setCurrentItem(enter); + } + + if (previousItem) { + QV4::ScopedValue rv(scope, QV4::QObjectWrapper::wrap(v4, previousItem)); + args->setReturnValue(rv->asReturnedValue()); + } else { + args->setReturnValue(QV4::Encode::null()); + } +} + +/*! + \qmlmethod Item QtQuick.Controls::StackView::replace(target, item, properties, operation) + + Replaces one or more items on the stack with the specified \a item and + optional \a operation, and optionally applies a set of \a properties on the + item. The item can be an \l Item, \l Component, or a \l [QML] url. + Returns the item that became current. + + \include qquickstackview.qdocinc pop-ownership + + If the \a target argument is specified, all items down to the \a target + item will be replaced. If \a target is \c null, all items in the stack + will be replaced. If not specified, only the top item will be replaced. + + StackView creates an instance automatically if the replacing item is a \l Component, + or a \l [QML] url. The optional \a properties argument specifies a map of initial + property values for the replacing item. For dynamically created items, these values + are applied before the creation is finalized. This is more efficient than setting + property values after creation, particularly where large sets of property values + are defined, and also allows property bindings to be set up (using \l{Qt::binding} + {Qt.binding()}) before the item is created. + + Replace the top item: + \code + stackView.replace(rect) + + // or with properties: + stackView.replace(rect, {"color": "red"}) + \endcode + + Multiple items can be replaced at the same time either by passing them as + additional arguments, or as an array. Each item can be followed by a set + of properties to apply. + + Passing a variable amount of arguments: + \code + stackView.replace(rect1, rect2, rect3) + + // or with properties: + stackView.replace(rect1, {"color": "red"}, rect2, {"color": "green"}, rect3, {"color": "blue"}) + \endcode + + Replacing an array of items: + \code + stackView.replace([rect1, rect2, rect3]) + + // or with properties: + stackView.replace([rect1, {"color": "red"}, rect2, {"color": "green"}, rect3, {"color": "blue"}]) + \endcode + + An \a operation can be optionally specified as the last argument. Supported + operations: + + \value StackView.Immediate An immediate operation without transitions. + \value StackView.PushTransition An operation with push transitions (since QtQuick.Controls 2.1). + \value StackView.ReplaceTransition An operation with replace transitions (since QtQuick.Controls 2.1). + \value StackView.PopTransition An operation with pop transitions (since QtQuick.Controls 2.1). + + If no operation is provided, \c Immediate will be used if the stack is + empty, and \c ReplaceTransition otherwise. + + The following example illustrates the use of push and pop transitions with replace(). + + \code + StackView { + id: stackView + + initialItem: Component { + id: page + + Page { + Row { + spacing: 20 + anchors.centerIn: parent + + Button { + text: "<" + onClicked: stackView.replace(page, StackView.PopTransition) + } + Button { + text: ">" + onClicked: stackView.replace(page, StackView.PushTransition) + } + } + } + } + } + \endcode + + \sa push(), {Replacing Items} +*/ +void QQuickStackView::replace(QQmlV4Function *args) +{ + Q_D(QQuickStackView); + const QString operationName = QStringLiteral("replace"); + if (d->modifyingElements) { + d->warnOfInterruption(operationName); + args->setReturnValue(QV4::Encode::null()); + return; + } + + QScopedValueRollback<bool> modifyingElements(d->modifyingElements, true); + QScopedValueRollback<QString> operationNameRollback(d->operation, operationName); + if (args->length() <= 0) { + d->warn(QStringLiteral("missing arguments")); + args->setReturnValue(QV4::Encode::null()); + return; + } + + QV4::ExecutionEngine *v4 = args->v4engine(); + QV4::Scope scope(v4); + + Operation operation = d->elements.isEmpty() ? Immediate : ReplaceTransition; + QV4::ScopedValue lastArg(scope, (*args)[args->length() - 1]); + if (lastArg->isInt32()) + operation = static_cast<Operation>(lastArg->toInt32()); + + QQuickStackElement *target = nullptr; + QV4::ScopedValue firstArg(scope, (*args)[0]); + if (firstArg->isNull()) + target = d->elements.value(0); + else if (!firstArg->isInt32()) + target = d->findElement(firstArg); + + QStringList errors; + QList<QQuickStackElement *> elements = d->parseElements(target ? 1 : 0, args, &errors); + if (!errors.isEmpty() || elements.isEmpty()) { + if (!errors.isEmpty()) { + for (const QString &error : qAsConst(errors)) + d->warn(error); + } else { + d->warn(QStringLiteral("nothing to push")); + } + args->setReturnValue(QV4::Encode::null()); + return; + } + + int oldDepth = d->elements.count(); + QQuickStackElement* exit = nullptr; + if (!d->elements.isEmpty()) + exit = d->elements.pop(); + + if (exit != target ? d->replaceElements(target, elements) : d->pushElements(elements)) { + d->depthChange(d->elements.count(), oldDepth); + if (exit) { + exit->removal = true; + d->removing.insert(exit); + } + QQuickStackElement *enter = d->elements.top(); + d->startTransition(QQuickStackTransition::replaceExit(operation, exit, this), + QQuickStackTransition::replaceEnter(operation, enter, this), + operation == Immediate); + d->setCurrentItem(enter); + } + + if (d->currentItem) { + QV4::ScopedValue rv(scope, QV4::QObjectWrapper::wrap(v4, d->currentItem)); + args->setReturnValue(rv->asReturnedValue()); + } else { + args->setReturnValue(QV4::Encode::null()); + } +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::StackView::empty + \readonly + + This property holds whether the stack is empty. + + \sa depth +*/ +bool QQuickStackView::isEmpty() const +{ + Q_D(const QQuickStackView); + return d->elements.isEmpty(); +} + +/*! + \qmlmethod void QtQuick.Controls::StackView::clear(transition) + + Removes all items from the stack. + + \include qquickstackview.qdocinc pop-ownership + + Since QtQuick.Controls 2.3, a \a transition can be optionally specified. Supported transitions: + + \value StackView.Immediate Clear the stack immediately without any transition (default). + \value StackView.PushTransition Clear the stack with a push transition. + \value StackView.ReplaceTransition Clear the stack with a replace transition. + \value StackView.PopTransition Clear the stack with a pop transition. +*/ +void QQuickStackView::clear(Operation operation) +{ + Q_D(QQuickStackView); + if (d->elements.isEmpty()) + return; + + const QString operationName = QStringLiteral("clear"); + if (d->modifyingElements) { + d->warnOfInterruption(operationName); + return; + } + + const int oldDepth = d->elements.size(); + + QScopedValueRollback<bool> modifyingElements(d->modifyingElements, true); + QScopedValueRollback<QString> operationNameRollback(d->operation, operationName); + if (operation != Immediate) { + QQuickStackElement *exit = d->elements.pop(); + exit->removal = true; + d->removing.insert(exit); + d->startTransition(QQuickStackTransition::popExit(operation, exit, this), + QQuickStackTransition::popEnter(operation, nullptr, this), false); + } + + d->setCurrentItem(nullptr); + qDeleteAll(d->elements); + d->elements.clear(); + d->depthChange(0, oldDepth); +} + +/*! + \qmlproperty var QtQuick.Controls::StackView::initialItem + + This property holds the initial item that should be shown when the StackView + is created. The initial item can be an \l Item, \l Component, or a \l [QML] url. + Specifying an initial item is equivalent to: + \code + Component.onCompleted: stackView.push(myInitialItem) + \endcode + + \sa push() +*/ +QJSValue QQuickStackView::initialItem() const +{ + Q_D(const QQuickStackView); + return d->initialItem; +} + +void QQuickStackView::setInitialItem(const QJSValue &item) +{ + Q_D(QQuickStackView); + d->initialItem = item; +} + +/*! + \qmlproperty Transition QtQuick.Controls::StackView::popEnter + + This property holds the transition that is applied to the item that + enters the stack when another item is popped off of it. + + \sa {Customizing StackView} +*/ +QQuickTransition *QQuickStackView::popEnter() const +{ + Q_D(const QQuickStackView); + if (d->transitioner) + return d->transitioner->removeDisplacedTransition; + return nullptr; +} + +void QQuickStackView::setPopEnter(QQuickTransition *enter) +{ + Q_D(QQuickStackView); + d->ensureTransitioner(); + if (d->transitioner->removeDisplacedTransition == enter) + return; + + d->transitioner->removeDisplacedTransition = enter; + emit popEnterChanged(); +} + +/*! + \qmlproperty Transition QtQuick.Controls::StackView::popExit + + This property holds the transition that is applied to the item that + exits the stack when the item is popped off of it. + + \sa {Customizing StackView} +*/ +QQuickTransition *QQuickStackView::popExit() const +{ + Q_D(const QQuickStackView); + if (d->transitioner) + return d->transitioner->removeTransition; + return nullptr; +} + +void QQuickStackView::setPopExit(QQuickTransition *exit) +{ + Q_D(QQuickStackView); + d->ensureTransitioner(); + if (d->transitioner->removeTransition == exit) + return; + + d->transitioner->removeTransition = exit; + emit popExitChanged(); +} + +/*! + \qmlproperty Transition QtQuick.Controls::StackView::pushEnter + + This property holds the transition that is applied to the item that + enters the stack when the item is pushed onto it. + + \sa {Customizing StackView} +*/ +QQuickTransition *QQuickStackView::pushEnter() const +{ + Q_D(const QQuickStackView); + if (d->transitioner) + return d->transitioner->addTransition; + return nullptr; +} + +void QQuickStackView::setPushEnter(QQuickTransition *enter) +{ + Q_D(QQuickStackView); + d->ensureTransitioner(); + if (d->transitioner->addTransition == enter) + return; + + d->transitioner->addTransition = enter; + emit pushEnterChanged(); +} + +/*! + \qmlproperty Transition QtQuick.Controls::StackView::pushExit + + This property holds the transition that is applied to the item that + exits the stack when another item is pushed onto it. + + \sa {Customizing StackView} +*/ +QQuickTransition *QQuickStackView::pushExit() const +{ + Q_D(const QQuickStackView); + if (d->transitioner) + return d->transitioner->addDisplacedTransition; + return nullptr; +} + +void QQuickStackView::setPushExit(QQuickTransition *exit) +{ + Q_D(QQuickStackView); + d->ensureTransitioner(); + if (d->transitioner->addDisplacedTransition == exit) + return; + + d->transitioner->addDisplacedTransition = exit; + emit pushExitChanged(); +} + +/*! + \qmlproperty Transition QtQuick.Controls::StackView::replaceEnter + + This property holds the transition that is applied to the item that + enters the stack when another item is replaced by it. + + \sa {Customizing StackView} +*/ +QQuickTransition *QQuickStackView::replaceEnter() const +{ + Q_D(const QQuickStackView); + if (d->transitioner) + return d->transitioner->moveTransition; + return nullptr; +} + +void QQuickStackView::setReplaceEnter(QQuickTransition *enter) +{ + Q_D(QQuickStackView); + d->ensureTransitioner(); + if (d->transitioner->moveTransition == enter) + return; + + d->transitioner->moveTransition = enter; + emit replaceEnterChanged(); +} + +/*! + \qmlproperty Transition QtQuick.Controls::StackView::replaceExit + + This property holds the transition that is applied to the item that + exits the stack when it is replaced by another item. + + \sa {Customizing StackView} +*/ +QQuickTransition *QQuickStackView::replaceExit() const +{ + Q_D(const QQuickStackView); + if (d->transitioner) + return d->transitioner->moveDisplacedTransition; + return nullptr; +} + +void QQuickStackView::setReplaceExit(QQuickTransition *exit) +{ + Q_D(QQuickStackView); + d->ensureTransitioner(); + if (d->transitioner->moveDisplacedTransition == exit) + return; + + d->transitioner->moveDisplacedTransition = exit; + emit replaceExitChanged(); +} + +void QQuickStackView::componentComplete() +{ + QQuickControl::componentComplete(); + + Q_D(QQuickStackView); + QScopedValueRollback<QString> operationNameRollback(d->operation, QStringLiteral("initialItem")); + QQuickStackElement *element = nullptr; + QString error; + int oldDepth = d->elements.count(); + if (QObject *o = d->initialItem.toQObject()) + element = QQuickStackElement::fromObject(o, this, &error); + else if (d->initialItem.isString()) + element = QQuickStackElement::fromString(d->initialItem.toString(), this, &error); + if (!error.isEmpty()) { + d->warn(error); + delete element; + } else if (d->pushElement(element)) { + d->depthChange(d->elements.count(), oldDepth); + d->setCurrentItem(element); + element->setStatus(QQuickStackView::Active); + } +} + +void QQuickStackView::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + QQuickControl::geometryChange(newGeometry, oldGeometry); + + Q_D(QQuickStackView); + for (QQuickStackElement *element : qAsConst(d->elements)) { + if (element->item) { + if (!element->widthValid) + element->item->setWidth(newGeometry.width()); + if (!element->heightValid) + element->item->setHeight(newGeometry.height()); + } + } +} + +bool QQuickStackView::childMouseEventFilter(QQuickItem *item, QEvent *event) +{ + // in order to block accidental user interaction while busy/transitioning, + // StackView filters out childrens' mouse events. therefore we block all + // press events. however, since push() may be called from signal handlers + // such as onPressed or onDoubleClicked, we must let the current mouse + // grabber item receive the respective mouse release event to avoid + // breaking its state (QTBUG-50305). + if (event->type() == QEvent::MouseButtonPress) + return true; + if (event->type() == QEvent::UngrabMouse) + return false; + QQuickWindow *window = item->window(); + return window && !window->mouseGrabberItem(); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickStackView::touchEvent(QTouchEvent *event) +{ + event->ignore(); // QTBUG-65084 +} +#endif + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickStackView::accessibleRole() const +{ + return QAccessible::LayeredPane; +} +#endif + +void QQuickStackViewAttachedPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent) +{ + Q_Q(QQuickStackViewAttached); + int oldIndex = element ? element->index : -1; + QQuickStackView *oldView = element ? element->view : nullptr; + QQuickStackView::Status oldStatus = element ? element->status : QQuickStackView::Inactive; + + QQuickStackView *newView = qobject_cast<QQuickStackView *>(parent); + element = newView ? QQuickStackViewPrivate::get(newView)->findElement(item) : nullptr; + + int newIndex = element ? element->index : -1; + QQuickStackView::Status newStatus = element ? element->status : QQuickStackView::Inactive; + + if (oldIndex != newIndex) + emit q->indexChanged(); + if (oldView != newView) + emit q->viewChanged(); + if (oldStatus != newStatus) + emit q->statusChanged(); +} + +QQuickStackViewAttached::QQuickStackViewAttached(QObject *parent) + : QObject(*(new QQuickStackViewAttachedPrivate), parent) +{ + Q_D(QQuickStackViewAttached); + QQuickItem *item = qobject_cast<QQuickItem *>(parent); + if (item) { + connect(item, &QQuickItem::visibleChanged, this, &QQuickStackViewAttached::visibleChanged); + QQuickItemPrivate::get(item)->addItemChangeListener(d, QQuickItemPrivate::Parent); + d->itemParentChanged(item, item->parentItem()); + } else if (parent) { + qmlWarning(parent) << "StackView must be attached to an Item"; + } +} + +QQuickStackViewAttached::~QQuickStackViewAttached() +{ + Q_D(QQuickStackViewAttached); + QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); + if (parentItem) + QQuickItemPrivate::get(parentItem)->removeItemChangeListener(d, QQuickItemPrivate::Parent); +} + +/*! + \qmlattachedproperty int QtQuick.Controls::StackView::index + \readonly + + This attached property holds the stack index of the item it's + attached to, or \c -1 if the item is not in a stack. +*/ +int QQuickStackViewAttached::index() const +{ + Q_D(const QQuickStackViewAttached); + return d->element ? d->element->index : -1; +} + +/*! + \qmlattachedproperty StackView QtQuick.Controls::StackView::view + \readonly + + This attached property holds the stack view of the item it's + attached to, or \c null if the item is not in a stack. +*/ +QQuickStackView *QQuickStackViewAttached::view() const +{ + Q_D(const QQuickStackViewAttached); + return d->element ? d->element->view : nullptr; +} + +/*! + \qmlattachedproperty enumeration QtQuick.Controls::StackView::status + \readonly + + This attached property holds the stack status of the item it's + attached to, or \c StackView.Inactive if the item is not in a stack. + + Available values: + \value StackView.Inactive The item is inactive (or not in a stack). + \value StackView.Deactivating The item is being deactivated (popped off). + \value StackView.Activating The item is being activated (becoming the current item). + \value StackView.Active The item is active, that is, the current item. +*/ +QQuickStackView::Status QQuickStackViewAttached::status() const +{ + Q_D(const QQuickStackViewAttached); + return d->element ? d->element->status : QQuickStackView::Inactive; +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlattachedproperty bool QtQuick.Controls::StackView::visible + + This attached property holds the visibility of the item it's attached to. + The value follows the value of \l Item::visible. + + By default, StackView shows incoming items when the enter transition begins, + and hides outgoing items when the exit transition ends. Setting this property + explicitly allows the default behavior to be overridden, making it possible + to keep items that are below the top-most item visible. + + \note The default transitions of most styles slide outgoing items outside the + view, and may also animate their opacity. In order to keep a full stack + of items visible, consider customizing the \l transitions so that the + items underneath can be seen. + + \image qtquickcontrols2-stackview-visible.png + + \snippet qtquickcontrols2-stackview-visible.qml 1 +*/ +bool QQuickStackViewAttached::isVisible() const +{ + const QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); + return parentItem && parentItem->isVisible(); +} + +void QQuickStackViewAttached::setVisible(bool visible) +{ + Q_D(QQuickStackViewAttached); + d->explicitVisible = true; + QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); + if (parentItem) + parentItem->setVisible(visible); +} + +void QQuickStackViewAttached::resetVisible() +{ + Q_D(QQuickStackViewAttached); + d->explicitVisible = false; + if (!d->element || !d->element->view) + return; + + QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); + if (parentItem) + parentItem->setVisible(parentItem == d->element->view->currentItem()); +} + +/*! + \qmlattachedsignal QtQuick.Controls::StackView::activated() + \since QtQuick.Controls 2.1 (Qt 5.8) + + This attached signal is emitted when the item it's attached to is activated in the stack. + + \sa status +*/ + +/*! + \qmlattachedsignal QtQuick.Controls::StackView::deactivated() + \since QtQuick.Controls 2.1 (Qt 5.8) + + This attached signal is emitted when the item it's attached to is deactivated in the stack. + + \sa status +*/ + +/*! + \qmlattachedsignal QtQuick.Controls::StackView::activating() + \since QtQuick.Controls 2.1 (Qt 5.8) + + This attached signal is emitted when the item it's attached to is in the process of being + activated in the stack. + + \sa status +*/ + +/*! + \qmlattachedsignal QtQuick.Controls::StackView::deactivating() + \since QtQuick.Controls 2.1 (Qt 5.8) + + This attached signal is emitted when the item it's attached to is in the process of being + dectivated in the stack. + + \sa status +*/ + +/*! + \qmlattachedsignal QtQuick.Controls::StackView::removed() + \since QtQuick.Controls 2.1 (Qt 5.8) + + This attached signal is emitted when the item it's attached to has been + removed from the stack. It can be used to safely destroy an Item that was + pushed onto the stack, for example: + + \code + Item { + StackView.onRemoved: destroy() // Will be destroyed sometime after this call. + } + \endcode + + \sa status +*/ + +QT_END_NAMESPACE + +#include "moc_qquickstackview_p.cpp" diff --git a/src/quicktemplates2/qquickstackview_p.cpp b/src/quicktemplates2/qquickstackview_p.cpp new file mode 100644 index 00000000000..402efa75d1f --- /dev/null +++ b/src/quicktemplates2/qquickstackview_p.cpp @@ -0,0 +1,360 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstackview_p_p.h" +#include "qquickstackelement_p_p.h" +#include "qquickstacktransition_p_p.h" + +#include <QtQml/qqmlinfo.h> +#include <QtQml/qqmllist.h> +#include <QtQml/private/qv4qmlcontext_p.h> +#include <QtQml/private/qv4qobjectwrapper_p.h> +#include <QtQml/private/qv4variantobject_p.h> +#include <QtQml/private/qv4urlobject_p.h> +#include <QtQuick/private/qquickanimation_p.h> +#include <QtQuick/private/qquicktransition_p.h> + +QT_BEGIN_NAMESPACE + +void QQuickStackViewPrivate::warn(const QString &error) +{ + Q_Q(QQuickStackView); + if (operation.isEmpty()) + qmlWarning(q) << error; + else + qmlWarning(q) << operation << ": " << error; +} + +void QQuickStackViewPrivate::warnOfInterruption(const QString &attemptedOperation) +{ + Q_Q(QQuickStackView); + qmlWarning(q) << "cannot " << attemptedOperation << " while already in the process of completing a " << operation; +} + +void QQuickStackViewPrivate::setCurrentItem(QQuickStackElement *element) +{ + Q_Q(QQuickStackView); + QQuickItem *item = element ? element->item : nullptr; + if (currentItem == item) + return; + + currentItem = item; + if (element) + element->setVisible(true); + if (item) + item->setFocus(true); + emit q->currentItemChanged(); +} + +static bool initProperties(QQuickStackElement *element, const QV4::Value &props, QQmlV4Function *args) +{ + if (props.isObject()) { + const QV4::QObjectWrapper *wrapper = props.as<QV4::QObjectWrapper>(); + if (!wrapper) { + QV4::ExecutionEngine *v4 = args->v4engine(); + element->properties.set(v4, props); + element->qmlCallingContext.set(v4, v4->qmlContext()); + return true; + } + } + return false; +} + +QList<QQuickStackElement *> QQuickStackViewPrivate::parseElements(int from, QQmlV4Function *args, QStringList *errors) +{ + QV4::ExecutionEngine *v4 = args->v4engine(); + auto context = v4->callingQmlContext(); + QV4::Scope scope(v4); + + QList<QQuickStackElement *> elements; + + int argc = args->length(); + for (int i = from; i < argc; ++i) { + QV4::ScopedValue arg(scope, (*args)[i]); + if (QV4::ArrayObject *array = arg->as<QV4::ArrayObject>()) { + const uint len = uint(array->getLength()); + for (uint j = 0; j < len; ++j) { + QString error; + QV4::ScopedValue value(scope, array->get(j)); + QQuickStackElement *element = createElement(value, context, &error); + if (element) { + if (j < len - 1) { + QV4::ScopedValue props(scope, array->get(j + 1)); + if (initProperties(element, props, args)) + ++j; + } + elements += element; + } else if (!error.isEmpty()) { + *errors += error; + } + } + } else { + QString error; + QQuickStackElement *element = createElement(arg, context, &error); + if (element) { + if (i < argc - 1) { + QV4::ScopedValue props(scope, (*args)[i + 1]); + if (initProperties(element, props, args)) + ++i; + } + elements += element; + } else if (!error.isEmpty()) { + *errors += error; + } + } + } + return elements; +} + +QQuickStackElement *QQuickStackViewPrivate::findElement(QQuickItem *item) const +{ + if (item) { + for (QQuickStackElement *e : qAsConst(elements)) { + if (e->item == item) + return e; + } + } + return nullptr; +} + +QQuickStackElement *QQuickStackViewPrivate::findElement(const QV4::Value &value) const +{ + if (const QV4::QObjectWrapper *o = value.as<QV4::QObjectWrapper>()) + return findElement(qobject_cast<QQuickItem *>(o->object())); + return nullptr; +} + +static QUrl resolvedUrl(const QUrl &url, const QQmlRefPointer<QQmlContextData> &context) +{ + if (url.isRelative()) + return context->resolvedUrl(url).toString(); + return url; +} + +static QString resolvedUrl(const QString &str, const QQmlRefPointer<QQmlContextData> &context) +{ + QUrl url(str); + if (url.isRelative()) + return context->resolvedUrl(url).toString(); + return str; +} + +QQuickStackElement *QQuickStackViewPrivate::createElement(const QV4::Value &value, const QQmlRefPointer<QQmlContextData> &context, QString *error) +{ + Q_Q(QQuickStackView); + if (const QV4::String *s = value.as<QV4::String>()) + return QQuickStackElement::fromString(resolvedUrl(s->toQString(), context), q, error); + if (const QV4::QObjectWrapper *o = value.as<QV4::QObjectWrapper>()) + return QQuickStackElement::fromObject(o->object(), q, error); + if (const QV4::UrlObject *u = value.as<QV4::UrlObject>()) + return QQuickStackElement::fromString(resolvedUrl(u->href(), context), q, error); + + if (const QV4::Object *v = value.as<QV4::Object>()) { + const QVariant data = v->engine()->toVariant(value, QMetaType::fromType<QUrl>()); + if (data.typeId() == QMetaType::QUrl) { + return QQuickStackElement::fromString(resolvedUrl(data.toUrl(), context).toString(), q, + error); + } + } + + return nullptr; +} + +bool QQuickStackViewPrivate::pushElements(const QList<QQuickStackElement *> &elems) +{ + Q_Q(QQuickStackView); + if (!elems.isEmpty()) { + for (QQuickStackElement *e : elems) { + e->setIndex(elements.count()); + elements += e; + } + return elements.top()->load(q); + } + return false; +} + +bool QQuickStackViewPrivate::pushElement(QQuickStackElement *element) +{ + if (element) + return pushElements(QList<QQuickStackElement *>() << element); + return false; +} + +bool QQuickStackViewPrivate::popElements(QQuickStackElement *element) +{ + Q_Q(QQuickStackView); + while (elements.count() > 1 && elements.top() != element) { + delete elements.pop(); + if (!element) + break; + } + return elements.top()->load(q); +} + +bool QQuickStackViewPrivate::replaceElements(QQuickStackElement *target, const QList<QQuickStackElement *> &elems) +{ + if (target) { + while (!elements.isEmpty()) { + QQuickStackElement* top = elements.pop(); + delete top; + if (top == target) + break; + } + } + return pushElements(elems); +} + +void QQuickStackViewPrivate::ensureTransitioner() +{ + if (!transitioner) { + transitioner = new QQuickItemViewTransitioner; + transitioner->setChangeListener(this); + } +} + +void QQuickStackViewPrivate::startTransition(const QQuickStackTransition &first, const QQuickStackTransition &second, bool immediate) +{ + if (first.element) + first.element->transitionNextReposition(transitioner, first.type, first.target); + if (second.element) + second.element->transitionNextReposition(transitioner, second.type, second.target); + + if (first.element) { + // Let the check for immediate happen after prepareTransition() is + // called, because we need the prepared transition in both branches. + // Same for the second element. + if (!first.element->item || !first.element->prepareTransition(transitioner, first.viewBounds) || immediate) + completeTransition(first.element, first.transition, first.status); + else + first.element->startTransition(transitioner, first.status); + } + if (second.element) { + if (!second.element->item || !second.element->prepareTransition(transitioner, second.viewBounds) || immediate) + completeTransition(second.element, second.transition, second.status); + else + second.element->startTransition(transitioner, second.status); + } + + if (transitioner) { + setBusy(!transitioner->runningJobs.isEmpty()); + transitioner->resetTargetLists(); + } +} + +void QQuickStackViewPrivate::completeTransition(QQuickStackElement *element, QQuickTransition *transition, QQuickStackView::Status status) +{ + element->setStatus(status); + if (transition) { + if (element->prepared) { + // Here we force reading all the animations, even if the desired + // transition type is StackView.Immediate. After that we force + // all the animations to complete immediately, without waiting for + // the animation timer. + // This allows us to correctly restore all the properties affected + // by the push/pop animations. + ACTION_IF_DELETED(element, element->completeTransition(transition), return); + } else if (element->item) { + // At least try to move the item to its desired place. This, + // however, is only a partly correct solution, because a lot more + // properties can be affected by the transition + element->item->setPosition(element->nextTransitionTo); + } + } + viewItemTransitionFinished(element); +} + +void QQuickStackViewPrivate::viewItemTransitionFinished(QQuickItemViewTransitionableItem *transitionable) +{ + QQuickStackElement *element = static_cast<QQuickStackElement *>(transitionable); + if (element->status == QQuickStackView::Activating) { + element->setStatus(QQuickStackView::Active); + } else if (element->status == QQuickStackView::Deactivating) { + element->setStatus(QQuickStackView::Inactive); + QQuickStackElement *existingElement = element->item ? findElement(element->item) : nullptr; + // If a different element with the same item is found, + // do not call setVisible(false) since it needs to be visible. + if (!existingElement || element == existingElement) + element->setVisible(false); + if (element->removal || element->isPendingRemoval()) + removed += element; + } + + if (transitioner && transitioner->runningJobs.isEmpty()) { + // ~QQuickStackElement() emits QQuickStackViewAttached::removed(), which may be used + // to modify the stack. Set the status first and make a copy of the destroyable stack + // elements to exclude any modifications that may happen during qDeleteAll(). (QTBUG-62153) + setBusy(false); + QList<QQuickStackElement*> removedElements = removed; + removed.clear(); + + for (QQuickStackElement *removedElement : qAsConst(removedElements)) { + // If an element with the same item is found in the active stack list, + // forget about the item so that we don't hide it. + if (removedElement->item && findElement(removedElement->item)) { + QQuickItemPrivate::get(removedElement->item)->removeItemChangeListener(removedElement, QQuickItemPrivate::Destroyed); + removedElement->item = nullptr; + } + } + + qDeleteAll(removedElements); + } + + removing.remove(element); +} + +void QQuickStackViewPrivate::setBusy(bool b) +{ + Q_Q(QQuickStackView); + if (busy == b) + return; + + busy = b; + q->setFiltersChildMouseEvents(busy); + emit q->busyChanged(); +} + +void QQuickStackViewPrivate::depthChange(int newDepth, int oldDepth) +{ + Q_Q(QQuickStackView); + if (newDepth == oldDepth) + return; + + emit q->depthChanged(); + if (newDepth == 0 || oldDepth == 0) + emit q->emptyChanged(); +} + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickstackview_p.h b/src/quicktemplates2/qquickstackview_p.h new file mode 100644 index 00000000000..f4cb5458330 --- /dev/null +++ b/src/quicktemplates2/qquickstackview_p.h @@ -0,0 +1,224 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTACKVIEW_P_H +#define QQUICKSTACKVIEW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQmlV4Function; +class QQuickTransition; +class QQuickStackElement; +class QQuickStackViewPrivate; +class QQuickStackViewAttached; +class QQuickStackViewAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickStackView : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(bool busy READ isBusy NOTIFY busyChanged FINAL) + Q_PROPERTY(int depth READ depth NOTIFY depthChanged FINAL) + Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged FINAL) + Q_PROPERTY(QJSValue initialItem READ initialItem WRITE setInitialItem FINAL) + Q_PROPERTY(QQuickTransition *popEnter READ popEnter WRITE setPopEnter NOTIFY popEnterChanged FINAL) + Q_PROPERTY(QQuickTransition *popExit READ popExit WRITE setPopExit NOTIFY popExitChanged FINAL) + Q_PROPERTY(QQuickTransition *pushEnter READ pushEnter WRITE setPushEnter NOTIFY pushEnterChanged FINAL) + Q_PROPERTY(QQuickTransition *pushExit READ pushExit WRITE setPushExit NOTIFY pushExitChanged FINAL) + Q_PROPERTY(QQuickTransition *replaceEnter READ replaceEnter WRITE setReplaceEnter NOTIFY replaceEnterChanged FINAL) + Q_PROPERTY(QQuickTransition *replaceExit READ replaceExit WRITE setReplaceExit NOTIFY replaceExitChanged FINAL) + // 2.3 (Qt 5.10) + Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged FINAL REVISION(2, 3)) + QML_NAMED_ELEMENT(StackView) + QML_ATTACHED(QQuickStackViewAttached) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickStackView(QQuickItem *parent = nullptr); + ~QQuickStackView(); + + static QQuickStackViewAttached *qmlAttachedProperties(QObject *object); + + bool isBusy() const; + int depth() const; + QQuickItem *currentItem() const; + + enum Status { + Inactive = 0, + Deactivating = 1, + Activating = 2, + Active = 3 + }; + Q_ENUM(Status) + + QJSValue initialItem() const; + void setInitialItem(const QJSValue &item); + + QQuickTransition *popEnter() const; + void setPopEnter(QQuickTransition *enter); + + QQuickTransition *popExit() const; + void setPopExit(QQuickTransition *exit); + + QQuickTransition *pushEnter() const; + void setPushEnter(QQuickTransition *enter); + + QQuickTransition *pushExit() const; + void setPushExit(QQuickTransition *exit); + + QQuickTransition *replaceEnter() const; + void setReplaceEnter(QQuickTransition *enter); + + QQuickTransition *replaceExit() const; + void setReplaceExit(QQuickTransition *exit); + + enum LoadBehavior { + DontLoad, + ForceLoad + }; + Q_ENUM(LoadBehavior) + + Q_INVOKABLE QQuickItem *get(int index, LoadBehavior behavior = DontLoad); + Q_INVOKABLE QQuickItem *find(const QJSValue &callback, LoadBehavior behavior = DontLoad); + + enum Operation { + Transition = -1, // ### Deprecated in Qt 6; remove in Qt 7. + Immediate = 0, + PushTransition = 1, + ReplaceTransition = 2, + PopTransition = 3, + }; + Q_ENUM(Operation) + + Q_INVOKABLE void push(QQmlV4Function *args); + Q_INVOKABLE void pop(QQmlV4Function *args); + Q_INVOKABLE void replace(QQmlV4Function *args); + + // 2.3 (Qt 5.10) + bool isEmpty() const; + +public Q_SLOTS: + void clear(Operation operation = Immediate); + +Q_SIGNALS: + void busyChanged(); + void depthChanged(); + void currentItemChanged(); + void popEnterChanged(); + void popExitChanged(); + void pushEnterChanged(); + void pushExitChanged(); + void replaceEnterChanged(); + void replaceExitChanged(); + // 2.3 (Qt 5.10) + Q_REVISION(2, 3) void emptyChanged(); + +protected: + void componentComplete() override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + bool childMouseEventFilter(QQuickItem *, QEvent *) override; + +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickStackView) + Q_DECLARE_PRIVATE(QQuickStackView) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickStackViewAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(int index READ index NOTIFY indexChanged FINAL) + Q_PROPERTY(QQuickStackView *view READ view NOTIFY viewChanged FINAL) + Q_PROPERTY(QQuickStackView::Status status READ status NOTIFY statusChanged FINAL) + // 2.2 (Qt 5.9) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible RESET resetVisible NOTIFY visibleChanged FINAL) // REVISION(2, 2) + +public: + explicit QQuickStackViewAttached(QObject *parent = nullptr); + ~QQuickStackViewAttached(); + + int index() const; + QQuickStackView *view() const; + QQuickStackView::Status status() const; + + // 2.2 (Qt 5.9) + bool isVisible() const; + void setVisible(bool visible); + void resetVisible(); + +Q_SIGNALS: + void indexChanged(); + void viewChanged(); + void statusChanged(); + // 2.1 (Qt 5.8) + /*Q_REVISION(2, 1)*/ void activated(); + /*Q_REVISION(2, 1)*/ void activating(); + /*Q_REVISION(2, 1)*/ void deactivated(); + /*Q_REVISION(2, 1)*/ void deactivating(); + /*Q_REVISION(2, 1)*/ void removed(); + // 2.2 (Qt 5.9) + /*Q_REVISION(2, 2)*/ void visibleChanged(); + +private: + Q_DISABLE_COPY(QQuickStackViewAttached) + Q_DECLARE_PRIVATE(QQuickStackViewAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickStackView) +QML_DECLARE_TYPEINFO(QQuickStackView, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKSTACKVIEW_P_H diff --git a/src/quicktemplates2/qquickstackview_p_p.h b/src/quicktemplates2/qquickstackview_p_p.h new file mode 100644 index 00000000000..0c64019db81 --- /dev/null +++ b/src/quicktemplates2/qquickstackview_p_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSTACKVIEW_P_P_H +#define QQUICKSTACKVIEW_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickstackview_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p_p.h> +#include <QtQuick/private/qquickitemviewtransition_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQml/private/qv4value_p.h> +#include <QtQml/private/qqmlcontextdata_p.h> +#include <QtCore/qset.h> +#include <QtCore/qstack.h> + +QT_BEGIN_NAMESPACE + +class QQuickStackElement; +struct QQuickStackTransition; + +class QQuickStackViewPrivate : public QQuickControlPrivate, public QQuickItemViewTransitionChangeListener +{ + Q_DECLARE_PUBLIC(QQuickStackView) + +public: + static QQuickStackViewPrivate *get(QQuickStackView *view) + { + return view->d_func(); + } + + void warn(const QString &error); + void warnOfInterruption(const QString &attemptedOperation); + + void setCurrentItem(QQuickStackElement *element); + + QList<QQuickStackElement *> parseElements(int from, QQmlV4Function *args, QStringList *errors); + QQuickStackElement *findElement(QQuickItem *item) const; + QQuickStackElement *findElement(const QV4::Value &value) const; + QQuickStackElement *createElement(const QV4::Value &value, const QQmlRefPointer<QQmlContextData> &context, QString *error); + bool pushElements(const QList<QQuickStackElement *> &elements); + bool pushElement(QQuickStackElement *element); + bool popElements(QQuickStackElement *element); + bool replaceElements(QQuickStackElement *element, const QList<QQuickStackElement *> &elements); + + void ensureTransitioner(); + void startTransition(const QQuickStackTransition &first, const QQuickStackTransition &second, bool immediate); + void completeTransition(QQuickStackElement *element, QQuickTransition *transition, QQuickStackView::Status status); + + void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item) override; + void setBusy(bool busy); + void depthChange(int newDepth, int oldDepth); + + bool busy = false; + bool modifyingElements = false; + QString operation; + QJSValue initialItem; + QQuickItem *currentItem = nullptr; + QSet<QQuickStackElement*> removing; + QList<QQuickStackElement*> removed; + QStack<QQuickStackElement *> elements; + QQuickItemViewTransitioner *transitioner = nullptr; +}; + +class QQuickStackViewAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener +{ + Q_DECLARE_PUBLIC(QQuickStackViewAttached) + +public: + static QQuickStackViewAttachedPrivate *get(QQuickStackViewAttached *attached) + { + return attached->d_func(); + } + + void itemParentChanged(QQuickItem *item, QQuickItem *parent) override; + + bool explicitVisible = false; + QQuickStackElement *element = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTACKVIEW_P_P_H diff --git a/src/quicktemplates2/qquickswipe_p.h b/src/quicktemplates2/qquickswipe_p.h new file mode 100644 index 00000000000..768d5638fd8 --- /dev/null +++ b/src/quicktemplates2/qquickswipe_p.h @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSWIPE_P_H +#define QQUICKSWIPE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> +#include <QtQuickTemplates2/private/qquickswipedelegate_p.h> + +QT_BEGIN_NAMESPACE + +class QQmlComponent; +class QQuickItem; +class QQuickTransition; +class QQuickSwipePrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSwipe : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged FINAL) + Q_PROPERTY(bool complete READ isComplete NOTIFY completeChanged FINAL) + Q_PROPERTY(QQmlComponent *left READ left WRITE setLeft NOTIFY leftChanged FINAL) + Q_PROPERTY(QQmlComponent *behind READ behind WRITE setBehind NOTIFY behindChanged FINAL) + Q_PROPERTY(QQmlComponent *right READ right WRITE setRight NOTIFY rightChanged FINAL) + Q_PROPERTY(QQuickItem *leftItem READ leftItem NOTIFY leftItemChanged FINAL) + Q_PROPERTY(QQuickItem *behindItem READ behindItem NOTIFY behindItemChanged FINAL) + Q_PROPERTY(QQuickItem *rightItem READ rightItem NOTIFY rightItemChanged FINAL) + // 2.2 (Qt 5.9) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL) // REVISION(2, 2) + Q_PROPERTY(QQuickTransition *transition READ transition WRITE setTransition NOTIFY transitionChanged FINAL) // REVISION(2, 2) + QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickSwipe(QQuickSwipeDelegate *control); + + qreal position() const; + void setPosition(qreal position); + + bool isComplete() const; + void setComplete(bool complete); + + QQmlComponent *left() const; + void setLeft(QQmlComponent *left); + + QQmlComponent *behind() const; + void setBehind(QQmlComponent *behind); + + QQmlComponent *right() const; + void setRight(QQmlComponent *right); + + QQuickItem *leftItem() const; + void setLeftItem(QQuickItem *item); + + QQuickItem *behindItem() const; + void setBehindItem(QQuickItem *item); + + QQuickItem *rightItem() const; + void setRightItem(QQuickItem *item); + + // 2.1 (Qt 5.8) + Q_REVISION(2, 1) Q_INVOKABLE void close(); + + // 2.2 (Qt 5.9) + bool isEnabled() const; + void setEnabled(bool enabled); + + QQuickTransition *transition() const; + void setTransition(QQuickTransition *transition); + + Q_REVISION(2, 2) Q_INVOKABLE void open(QQuickSwipeDelegate::Side side); + +Q_SIGNALS: + void positionChanged(); + void completeChanged(); + void leftChanged(); + void behindChanged(); + void rightChanged(); + void leftItemChanged(); + void behindItemChanged(); + void rightItemChanged(); + // 2.1 (Qt 5.8) + /*Q_REVISION(2, 1)*/ void completed(); + // 2.2 (Qt 5.9) + /*Q_REVISION(2, 2)*/ void opened(); + /*Q_REVISION(2, 2)*/ void closed(); + /*Q_REVISION(2, 2)*/ void enabledChanged(); + /*Q_REVISION(2, 2)*/ void transitionChanged(); + +private: + Q_DISABLE_COPY(QQuickSwipe) + Q_DECLARE_PRIVATE(QQuickSwipe) +}; + +QT_END_NAMESPACE + +#endif // QQUICKSWIPE_P_H diff --git a/src/quicktemplates2/qquickswipedelegate.cpp b/src/quicktemplates2/qquickswipedelegate.cpp new file mode 100644 index 00000000000..242dbc66540 --- /dev/null +++ b/src/quicktemplates2/qquickswipedelegate.cpp @@ -0,0 +1,1527 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickswipedelegate_p.h" +#include "qquickswipedelegate_p_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickitemdelegate_p_p.h" +#include "qquickvelocitycalculator_p_p.h" + +#include <QtGui/qstylehints.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/private/qeventpoint_p.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuick/private/qquickanimation_p.h> +#include <QtQuick/private/qquicktransition_p.h> +#include <QtQuick/private/qquicktransitionmanager_p_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype SwipeDelegate + \inherits ItemDelegate +//! \instantiates QQuickSwipeDelegate + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-delegates + \brief Swipable item delegate. + + SwipeDelegate presents a view item that can be swiped left or right to + expose more options or information. It is used as a delegate in views such + as \l ListView. + + In the following example, SwipeDelegate is used in a \l ListView to allow + items to be removed from it by swiping to the left: + + \snippet qtquickcontrols2-swipedelegate.qml 1 + + SwipeDelegate inherits its API from \l ItemDelegate, which is inherited + from AbstractButton. For instance, you can set \l {AbstractButton::text}{text}, + and react to \l {AbstractButton::clicked}{clicks} using the AbstractButton + API. + + Information regarding the progress of a swipe, as well as the components + that should be shown upon swiping, are both available through the + \l {SwipeDelegate::}{swipe} grouped property object. For example, + \c swipe.position holds the position of the + swipe within the range \c -1.0 to \c 1.0. The \c swipe.left + property determines which item will be displayed when the control is swiped + to the right, and vice versa for \c swipe.right. The positioning of these + components is left to applications to decide. For example, without specifying + any position for \c swipe.left or \c swipe.right, the following will + occur: + + \image qtquickcontrols2-swipedelegate.gif + + If \c swipe.left and \c swipe.right are anchored to the left and + right of the \l {Control::}{background} item (respectively), they'll behave like this: + + \image qtquickcontrols2-swipedelegate-leading-trailing.gif + + When using \c swipe.left and \c swipe.right, the control cannot be + swiped past the left and right edges. To achieve this type of "wrapping" + behavior, set \c swipe.behind instead. This will result in the same + item being shown regardless of which direction the control is swiped. For + example, in the image below, we set \c swipe.behind and then swipe the + control repeatedly in both directions: + + \image qtquickcontrols2-swipedelegate-behind.gif + + \sa {Customizing SwipeDelegate}, {Delegate Controls}, {Qt Quick Controls 2 - Swipe to Remove}{Swipe to Remove Example} +*/ + +namespace { + typedef QQuickSwipeDelegateAttached Attached; + + Attached *attachedObject(QQuickItem *item) { + return qobject_cast<Attached*>(qmlAttachedPropertiesObject<QQuickSwipeDelegate>(item, false)); + } + + enum PositionAnimation { + DontAnimatePosition, + AnimatePosition + }; +} + +class QQuickSwipeTransitionManager : public QQuickTransitionManager +{ +public: + QQuickSwipeTransitionManager(QQuickSwipe *swipe); + + void transition(QQuickTransition *transition, qreal position); + +protected: + void finished() override; + +private: + QQuickSwipe *m_swipe = nullptr; +}; + +class QQuickSwipePrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickSwipe) + +public: + QQuickSwipePrivate(QQuickSwipeDelegate *control) : control(control) { } + + static QQuickSwipePrivate *get(QQuickSwipe *swipe); + + QQuickItem *createDelegateItem(QQmlComponent *component); + QQuickItem *showRelevantItemForPosition(qreal position); + QQuickItem *createRelevantItemForDistance(qreal distance); + void reposition(PositionAnimation animationPolicy); + void createLeftItem(); + void createBehindItem(); + void createRightItem(); + void createAndShowLeftItem(); + void createAndShowBehindItem(); + void createAndShowRightItem(); + + void warnAboutMixingDelegates(); + void warnAboutSettingDelegatesWhileVisible(); + + bool hasDelegates() const; + + bool isTransitioning() const; + void beginTransition(qreal position); + void finishTransition(); + + QQuickSwipeDelegate *control = nullptr; + // Same range as position, but is set before press events so that we can + // keep track of which direction the user must swipe when using left and right delegates. + qreal positionBeforePress = 0; + qreal position = 0; + // A "less strict" version of complete that is true if complete was true + // before the last press event. + bool wasComplete = false; + bool complete = false; + bool enabled = true; + bool waitForTransition = false; + QQuickVelocityCalculator velocityCalculator; + QQmlComponent *left = nullptr; + QQmlComponent *behind = nullptr; + QQmlComponent *right = nullptr; + QQuickItem *leftItem = nullptr; + QQuickItem *behindItem = nullptr; + QQuickItem *rightItem = nullptr; + QQuickTransition *transition = nullptr; + QScopedPointer<QQuickSwipeTransitionManager> transitionManager; +}; + +QQuickSwipeTransitionManager::QQuickSwipeTransitionManager(QQuickSwipe *swipe) + : m_swipe(swipe) +{ +} + +void QQuickSwipeTransitionManager::transition(QQuickTransition *transition, qreal position) +{ + qmlExecuteDeferred(transition); + + QQmlProperty defaultTarget(m_swipe, QLatin1String("position")); + QQmlListProperty<QQuickAbstractAnimation> animations = transition->animations(); + const int count = animations.count(&animations); + for (int i = 0; i < count; ++i) { + QQuickAbstractAnimation *anim = animations.at(&animations, i); + anim->setDefaultTarget(defaultTarget); + } + + QList<QQuickStateAction> actions; + actions << QQuickStateAction(m_swipe, QLatin1String("position"), position); + QQuickTransitionManager::transition(actions, transition, m_swipe); +} + +void QQuickSwipeTransitionManager::finished() +{ + QQuickSwipePrivate::get(m_swipe)->finishTransition(); +} + +QQuickSwipePrivate *QQuickSwipePrivate::get(QQuickSwipe *swipe) +{ + return swipe->d_func(); +} + +QQuickItem *QQuickSwipePrivate::createDelegateItem(QQmlComponent *component) +{ + // If we don't use the correct context, it won't be possible to refer to + // the control's id from within the delegates. + QQmlContext *creationContext = component->creationContext(); + // The component might not have been created in QML, in which case + // the creation context will be null and we have to create it ourselves. + if (!creationContext) + creationContext = qmlContext(control); + QQmlContext *context = new QQmlContext(creationContext, control); + context->setContextObject(control); + QQuickItem *item = qobject_cast<QQuickItem*>(component->beginCreate(context)); + if (item) { + item->setParentItem(control); + component->completeCreate(); + } + return item; +} + +QQuickItem *QQuickSwipePrivate::showRelevantItemForPosition(qreal position) +{ + if (qFuzzyIsNull(position)) + return nullptr; + + if (behind) { + createAndShowBehindItem(); + return behindItem; + } + + if (right && position < 0.0) { + createAndShowRightItem(); + return rightItem; + } + + if (left && position > 0.0) { + createAndShowLeftItem(); + return leftItem; + } + + return nullptr; +} + +QQuickItem *QQuickSwipePrivate::createRelevantItemForDistance(qreal distance) +{ + if (qFuzzyIsNull(distance)) + return nullptr; + + if (behind) { + createBehindItem(); + return behindItem; + } + + // a) If the position before the press was 0.0, we know that *any* movement + // whose distance is negative will result in the right item being shown and + // vice versa. + // b) Once the control has been exposed (that is, swiped to the left or right, + // and hence the position is either -1.0 or 1.0), we must use the width of the + // relevant item to determine if the distance is larger than that item, + // in order to know whether or not to display it. + // c) If the control has been exposed, and the swipe is larger than the width + // of the relevant item from which the swipe started from, we must show the + // item on the other side (if any). + + if (right) { + if ((distance < 0.0 && positionBeforePress == 0.0) /* a) */ + || (rightItem && positionBeforePress == -1.0 && distance < rightItem->width()) /* b) */ + || (leftItem && positionBeforePress == 1.0 && qAbs(distance) > leftItem->width())) /* c) */ { + createRightItem(); + return rightItem; + } + } + + if (left) { + if ((distance > 0.0 && positionBeforePress == 0.0) /* a) */ + || (leftItem && positionBeforePress == 1.0 && qAbs(distance) < leftItem->width()) /* b) */ + || (rightItem && positionBeforePress == -1.0 && qAbs(distance) > rightItem->width())) /* c) */ { + createLeftItem(); + return leftItem; + } + } + + return nullptr; +} + +void QQuickSwipePrivate::reposition(PositionAnimation animationPolicy) +{ + QQuickItem *relevantItem = showRelevantItemForPosition(position); + const qreal relevantWidth = relevantItem ? relevantItem->width() : 0.0; + const qreal contentItemX = position * relevantWidth + control->leftPadding(); + + // "Behavior on x" relies on the property system to know when it should update, + // so we can prevent it from animating by setting the x position directly. + if (animationPolicy == AnimatePosition) { + if (QQuickItem *contentItem = control->contentItem()) + contentItem->setProperty("x", contentItemX); + if (QQuickItem *background = control->background()) + background->setProperty("x", position * relevantWidth); + } else { + if (QQuickItem *contentItem = control->contentItem()) + contentItem->setX(contentItemX); + if (QQuickItem *background = control->background()) + background->setX(position * relevantWidth); + } +} + +void QQuickSwipePrivate::createLeftItem() +{ + if (!leftItem) { + Q_Q(QQuickSwipe); + q->setLeftItem(createDelegateItem(left)); + if (!leftItem) + qmlWarning(control) << "Failed to create left item:" << left->errors(); + } +} + +void QQuickSwipePrivate::createBehindItem() +{ + if (!behindItem) { + Q_Q(QQuickSwipe); + q->setBehindItem(createDelegateItem(behind)); + if (!behindItem) + qmlWarning(control) << "Failed to create behind item:" << behind->errors(); + } +} + +void QQuickSwipePrivate::createRightItem() +{ + if (!rightItem) { + Q_Q(QQuickSwipe); + q->setRightItem(createDelegateItem(right)); + if (!rightItem) + qmlWarning(control) << "Failed to create right item:" << right->errors(); + } +} + +void QQuickSwipePrivate::createAndShowLeftItem() +{ + createLeftItem(); + + if (leftItem) + leftItem->setVisible(true); + + if (rightItem) + rightItem->setVisible(false); +} + +void QQuickSwipePrivate::createAndShowBehindItem() +{ + createBehindItem(); + + if (behindItem) + behindItem->setVisible(true); +} + +void QQuickSwipePrivate::createAndShowRightItem() +{ + createRightItem(); + + // This item may have already existed but was hidden. + if (rightItem) + rightItem->setVisible(true); + + // The left item isn't visible when the right item is visible, so save rendering effort by hiding it. + if (leftItem) + leftItem->setVisible(false); +} + +void QQuickSwipePrivate::warnAboutMixingDelegates() +{ + qmlWarning(control) << "cannot set both behind and left/right properties"; +} + +void QQuickSwipePrivate::warnAboutSettingDelegatesWhileVisible() +{ + qmlWarning(control) << "left/right/behind properties may only be set when swipe.position is 0"; +} + +bool QQuickSwipePrivate::hasDelegates() const +{ + return left || right || behind; +} + +bool QQuickSwipePrivate::isTransitioning() const +{ + return transitionManager && transitionManager->isRunning(); +} + +void QQuickSwipePrivate::beginTransition(qreal newPosition) +{ + if (waitForTransition) + return; + Q_Q(QQuickSwipe); + if (!transition) { + q->setPosition(newPosition); + finishTransition(); + return; + } + + if (!transitionManager) + transitionManager.reset(new QQuickSwipeTransitionManager(q)); + + transitionManager->transition(transition, newPosition); +} + +void QQuickSwipePrivate::finishTransition() +{ + Q_Q(QQuickSwipe); + waitForTransition = false; + q->setComplete(qFuzzyCompare(qAbs(position), qreal(1.0))); + if (complete) { + emit q->opened(); + } else { + if (qFuzzyIsNull(position)) + wasComplete = false; + emit q->closed(); + } +} + +QQuickSwipe::QQuickSwipe(QQuickSwipeDelegate *control) + : QObject(*(new QQuickSwipePrivate(control))) +{ +} + +QQmlComponent *QQuickSwipe::left() const +{ + Q_D(const QQuickSwipe); + return d->left; +} + +void QQuickSwipe::setLeft(QQmlComponent *left) +{ + Q_D(QQuickSwipe); + if (left == d->left) + return; + + if (d->behind) { + d->warnAboutMixingDelegates(); + return; + } + + if (!qFuzzyIsNull(d->position)) { + d->warnAboutSettingDelegatesWhileVisible(); + return; + } + + d->left = left; + + if (!d->left) { + delete d->leftItem; + d->leftItem = nullptr; + } + + d->control->setFiltersChildMouseEvents(d->hasDelegates()); + + emit leftChanged(); +} + +QQmlComponent *QQuickSwipe::behind() const +{ + Q_D(const QQuickSwipe); + return d->behind; +} + +void QQuickSwipe::setBehind(QQmlComponent *behind) +{ + Q_D(QQuickSwipe); + if (behind == d->behind) + return; + + if (d->left || d->right) { + d->warnAboutMixingDelegates(); + return; + } + + if (!qFuzzyIsNull(d->position)) { + d->warnAboutSettingDelegatesWhileVisible(); + return; + } + + d->behind = behind; + + if (!d->behind) { + delete d->behindItem; + d->behindItem = nullptr; + } + + d->control->setFiltersChildMouseEvents(d->hasDelegates()); + + emit behindChanged(); +} + +QQmlComponent *QQuickSwipe::right() const +{ + Q_D(const QQuickSwipe); + return d->right; +} + +void QQuickSwipe::setRight(QQmlComponent *right) +{ + Q_D(QQuickSwipe); + if (right == d->right) + return; + + if (d->behind) { + d->warnAboutMixingDelegates(); + return; + } + + if (!qFuzzyIsNull(d->position)) { + d->warnAboutSettingDelegatesWhileVisible(); + return; + } + + d->right = right; + + if (!d->right) { + delete d->rightItem; + d->rightItem = nullptr; + } + + d->control->setFiltersChildMouseEvents(d->hasDelegates()); + + emit rightChanged(); +} + +QQuickItem *QQuickSwipe::leftItem() const +{ + Q_D(const QQuickSwipe); + return d->leftItem; +} + +void QQuickSwipe::setLeftItem(QQuickItem *item) +{ + Q_D(QQuickSwipe); + if (item == d->leftItem) + return; + + delete d->leftItem; + d->leftItem = item; + + if (d->leftItem) { + d->leftItem->setParentItem(d->control); + + if (qFuzzyIsNull(d->leftItem->z())) + d->leftItem->setZ(-2); + } + + emit leftItemChanged(); +} + +QQuickItem *QQuickSwipe::behindItem() const +{ + Q_D(const QQuickSwipe); + return d->behindItem; +} + +void QQuickSwipe::setBehindItem(QQuickItem *item) +{ + Q_D(QQuickSwipe); + if (item == d->behindItem) + return; + + delete d->behindItem; + d->behindItem = item; + + if (d->behindItem) { + d->behindItem->setParentItem(d->control); + + if (qFuzzyIsNull(d->behindItem->z())) + d->behindItem->setZ(-2); + } + + emit behindItemChanged(); +} + +QQuickItem *QQuickSwipe::rightItem() const +{ + Q_D(const QQuickSwipe); + return d->rightItem; +} + +void QQuickSwipe::setRightItem(QQuickItem *item) +{ + Q_D(QQuickSwipe); + if (item == d->rightItem) + return; + + delete d->rightItem; + d->rightItem = item; + + if (d->rightItem) { + d->rightItem->setParentItem(d->control); + + if (qFuzzyIsNull(d->rightItem->z())) + d->rightItem->setZ(-2); + } + + emit rightItemChanged(); +} + +qreal QQuickSwipe::position() const +{ + Q_D(const QQuickSwipe); + return d->position; +} + +void QQuickSwipe::setPosition(qreal position) +{ + Q_D(QQuickSwipe); + const qreal adjustedPosition = qBound<qreal>(-1.0, position, 1.0); + if (adjustedPosition == d->position) + return; + + d->position = adjustedPosition; + d->reposition(AnimatePosition); + emit positionChanged(); +} + +bool QQuickSwipe::isComplete() const +{ + Q_D(const QQuickSwipe); + return d->complete; +} + +void QQuickSwipe::setComplete(bool complete) +{ + Q_D(QQuickSwipe); + if (complete == d->complete) + return; + + d->complete = complete; + emit completeChanged(); + if (d->complete) + emit completed(); +} + +bool QQuickSwipe::isEnabled() const +{ + Q_D(const QQuickSwipe); + return d->enabled; +} + +void QQuickSwipe::setEnabled(bool enabled) +{ + Q_D(QQuickSwipe); + if (enabled == d->enabled) + return; + + d->enabled = enabled; + emit enabledChanged(); +} + +QQuickTransition *QQuickSwipe::transition() const +{ + Q_D(const QQuickSwipe); + return d->transition; +} + +void QQuickSwipe::setTransition(QQuickTransition *transition) +{ + Q_D(QQuickSwipe); + if (transition == d->transition) + return; + + d->transition = transition; + emit transitionChanged(); +} + +void QQuickSwipe::open(QQuickSwipeDelegate::Side side) +{ + Q_D(QQuickSwipe); + if (qFuzzyCompare(qAbs(d->position), qreal(1.0))) + return; + + if ((side != QQuickSwipeDelegate::Left && side != QQuickSwipeDelegate::Right) + || (!d->left && !d->behind && side == QQuickSwipeDelegate::Left) + || (!d->right && !d->behind && side == QQuickSwipeDelegate::Right)) + return; + + d->beginTransition(side); + d->wasComplete = true; + d->velocityCalculator.reset(); + d->positionBeforePress = d->position; +} + +void QQuickSwipe::close() +{ + Q_D(QQuickSwipe); + if (qFuzzyIsNull(d->position)) + return; + + if (d->control->isPressed()) { + // We don't support closing when we're pressed; release() or clicked() should be used instead. + return; + } + + d->beginTransition(0.0); + d->waitForTransition = true; + d->wasComplete = false; + d->positionBeforePress = 0.0; + d->velocityCalculator.reset(); +} + +QQuickSwipeDelegatePrivate::QQuickSwipeDelegatePrivate(QQuickSwipeDelegate *control) + : swipe(control) +{ +} + +void QQuickSwipeDelegatePrivate::resizeBackground() +{ + if (!background) + return; + + resizingBackground = true; + + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + const bool extraAllocated = extra.isAllocated(); + // Don't check for or set the x here since it will just be overwritten by reposition(). + if (((!p->widthValid() || !extraAllocated || !extra->hasBackgroundWidth)) + || (extraAllocated && (extra->hasLeftInset || extra->hasRightInset))) { + background->setWidth(width - getLeftInset() - getRightInset()); + } + if (((!p->heightValid() || !extraAllocated || !extra->hasBackgroundHeight) && qFuzzyIsNull(background->y())) + || (extraAllocated && (extra->hasTopInset || extra->hasBottomInset))) { + background->setY(getTopInset()); + background->setHeight(height - getTopInset() - getBottomInset()); + } + + resizingBackground = false; +} + +bool QQuickSwipeDelegatePrivate::handleMousePressEvent(QQuickItem *item, QMouseEvent *event) +{ + Q_Q(QQuickSwipeDelegate); + const auto posInItem = item->mapToItem(q, event->position().toPoint()); + QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&swipe); + // If the position is 0, we want to handle events ourselves - we don't want child items to steal them. + // This code will only get called when a child item has been created; + // events will go through the regular channels (mousePressEvent()) until then. + if (qFuzzyIsNull(swipePrivate->position)) { + q->mousePressEvent(event); + // The press point could be incorrect if the press happened over a child item, + // so we correct it after calling the base class' mousePressEvent(), rather + // than having to duplicate its code just so we can set the pressPoint. + setPressPoint(posInItem); + return true; + } + + // If the delegate is swiped open, send the event to the exposed item, + // in case it's an interactive child (like a Button). + if (swipePrivate->complete) + forwardMouseEvent(event, item, posInItem); + + // The position is non-zero, this press could be either for a delegate or the control itself + // (the control can be clicked to e.g. close the swipe). Either way, we must begin measuring + // mouse movement in case it turns into a swipe, in which case we grab the mouse. + swipePrivate->positionBeforePress = swipePrivate->position; + swipePrivate->velocityCalculator.startMeasuring(event->position().toPoint(), event->timestamp()); + setPressPoint(item->mapToItem(q, event->position().toPoint())); + + // When a delegate or any of its children uses the attached properties and signals, + // it declares that it wants mouse events. + const bool delivered = attachedObjectsSetPressed(item, event->scenePosition(), true); + if (delivered) + event->accept(); + return delivered; +} + +bool QQuickSwipeDelegatePrivate::handleMouseMoveEvent(QQuickItem *item, QMouseEvent *event) +{ + Q_Q(QQuickSwipeDelegate); + + if (holdTimer > 0) { + if (QLineF(pressPoint, event->position()).length() > QGuiApplication::styleHints()->startDragDistance()) + stopPressAndHold(); + } + + // The delegate can still be pressed when swipe.enabled is false, + // but the mouse moving shouldn't have any effect on swipe.position. + QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&swipe); + if (!swipePrivate->enabled) + return false; + + // Protect against division by zero. + if (width == 0) + return false; + + // Don't bother reacting to events if we don't have any delegates. + if (!swipePrivate->left && !swipePrivate->right && !swipePrivate->behind) + return false; + + // Don't handle move events for the control if it wasn't pressed. + if (item == q && !pressed) + return false; + + const QPointF mappedEventPos = item->mapToItem(q, event->position().toPoint()); + const qreal distance = (mappedEventPos - pressPoint).x(); + if (!q->keepMouseGrab()) { + // Taken from QQuickDrawerPrivate::grabMouse; see comments there. + int threshold = qMax(20, QGuiApplication::styleHints()->startDragDistance() + 5); + const bool overThreshold = QQuickWindowPrivate::dragOverThreshold(distance, Qt::XAxis, event, threshold); + if (window && overThreshold) { + QQuickItem *grabber = q->window()->mouseGrabberItem(); + if (!grabber || !grabber->keepMouseGrab()) { + q->grabMouse(); + q->setKeepMouseGrab(true); + q->setPressed(true); + swipe.setComplete(false); + + attachedObjectsSetPressed(item, event->scenePosition(), false, true); + } + } + } + + if (q->keepMouseGrab()) { + // Ensure we don't try to calculate a position when the user tried to drag + // to the left when the left item is already exposed, and vice versa. + // The code below assumes that the drag is valid, so if we don't have this check, + // the wrong items are visible and the swiping wraps. + if (swipePrivate->behind + || ((swipePrivate->left || swipePrivate->right) + && (qFuzzyIsNull(swipePrivate->positionBeforePress) + || (swipePrivate->positionBeforePress == -1.0 && distance >= 0.0) + || (swipePrivate->positionBeforePress == 1.0 && distance <= 0.0)))) { + + // We must instantiate the items here so that we can calculate the + // position against the width of the relevant item. + QQuickItem *relevantItem = swipePrivate->createRelevantItemForDistance(distance); + // If there isn't any relevant item, the user may have swiped back to the 0 position, + // or they swiped back to a position that is equal to positionBeforePress. + const qreal normalizedDistance = relevantItem ? distance / relevantItem->width() : 0.0; + qreal position = 0; + + // If the control was exposed before the drag begun, the distance should be inverted. + // For example, if the control had been swiped to the right, the position would be 1.0. + // If the control was then swiped to the left by a distance of -20 pixels, the normalized + // distance might be -0.2, for example, which cannot be used as the position; the swipe + // started from the right, so we account for that by adding the position. + if (qFuzzyIsNull(normalizedDistance)) { + // There are two cases when the normalizedDistance can be 0, + // and we must distinguish between them: + // + // a) The swipe returns to the position that it was at before the press event. + // In this case, the distance will be 0. + // There would have been many position changes in the meantime, so we can't just + // ignore the move event; we have to set position to what it was before the press. + // + // b) If the position was at, 1.0, for example, and the control was then swiped + // to the left by the exact width of the left item, there won't be any relevant item + // (because the swipe's position would be at 0.0). In turn, the normalizedDistance + // would be 0 (because of the lack of a relevant item), but the distance will be non-zero. + position = qFuzzyIsNull(distance) ? swipePrivate->positionBeforePress : 0; + } else if (!swipePrivate->wasComplete) { + position = normalizedDistance; + } else { + position = distance > 0 ? normalizedDistance - 1.0 : normalizedDistance + 1.0; + } + + if (swipePrivate->isTransitioning()) + swipePrivate->transitionManager->cancel(); + swipe.setPosition(position); + } + } else { + // The swipe wasn't initiated. + if (event->position().toPoint().y() < 0 || event->position().toPoint().y() > height) { + // The mouse went outside the vertical bounds of the control, so + // we should no longer consider it pressed. + q->setPressed(false); + } + } + + event->accept(); + + return q->keepMouseGrab(); +} + +static const qreal exposeVelocityThreshold = 300.0; + +bool QQuickSwipeDelegatePrivate::handleMouseReleaseEvent(QQuickItem *item, QMouseEvent *event) +{ + Q_Q(QQuickSwipeDelegate); + QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&swipe); + swipePrivate->velocityCalculator.stopMeasuring(event->position().toPoint(), event->timestamp()); + + const bool hadGrabbedMouse = q->keepMouseGrab(); + q->setKeepMouseGrab(false); + + // QQuickSwipe::close() doesn't allow closing while pressed, but now we're releasing. + // So set the pressed state false if this release _could_ result in closing, so that check can be bypassed. + if (!qIsNull(swipePrivate->position)) + q->setPressed(false); + + // Animations for the background and contentItem delegates are typically + // only enabled when !control.down, so that the animations aren't running + // when the user is swiping. To ensure that the animations are enabled + // *before* the positions of these delegates change (via the swipe.setPosition() calls below), + // we must cancel the press. QQuickAbstractButton::mouseUngrabEvent() does this + // for us, but by then it's too late. + if (hadGrabbedMouse) { + // TODO: this is copied from QQuickAbstractButton::mouseUngrabEvent(). + // Eventually it should be moved into a private helper so that we don't have to duplicate it. + q->setPressed(false); + stopPressRepeat(); + stopPressAndHold(); + emit q->canceled(); + } + + // Inform the given item that the mouse is released, in case it's an interactive child. + if (item != q && (swipePrivate->complete || swipePrivate->wasComplete)) + forwardMouseEvent(event, item, item->mapFromScene(event->scenePosition())); + + // The control can be exposed by either swiping past the halfway mark, or swiping fast enough. + const qreal swipeVelocity = swipePrivate->velocityCalculator.velocity().x(); + if (swipePrivate->position > 0.5 || + (swipePrivate->position > 0.0 && swipeVelocity > exposeVelocityThreshold)) { + swipePrivate->beginTransition(1.0); + swipePrivate->wasComplete = true; + } else if (swipePrivate->position < -0.5 || + (swipePrivate->position < 0.0 && swipeVelocity < -exposeVelocityThreshold)) { + swipePrivate->beginTransition(-1.0); + swipePrivate->wasComplete = true; + } else if (!swipePrivate->isTransitioning()) { + // The position is either <= 0.5 or >= -0.5, so the position should go to 0. + // However, if the position was already 0 or close to it, we were just clicked, + // and we don't need to start a transition. + if (!qFuzzyIsNull(swipePrivate->position)) + swipePrivate->beginTransition(0.0); + swipePrivate->wasComplete = false; + } + + // Inform any QQuickSwipeDelegateAttached objects that the mouse is released. + attachedObjectsSetPressed(item, event->scenePosition(), false); + + // Only consume child events if we had grabbed the mouse. + return hadGrabbedMouse; +} + +/*! \internal + Send a localized copy of \a event with \a localPos to the \a destination item. +*/ +void QQuickSwipeDelegatePrivate::forwardMouseEvent(QMouseEvent *event, QQuickItem *destination, QPointF localPos) +{ + Q_Q(QQuickSwipeDelegate); + QMutableSinglePointEvent localizedEvent(*event); + localizedEvent.mutablePoint().setPosition(localPos); + QGuiApplication::sendEvent(destination, &localizedEvent); + q->setPressed(!localizedEvent.isAccepted()); +} + +/*! \internal + For each QQuickSwipeDelegateAttached object on children of \a item: + if \a scenePos is in the attachee (the item to which it's attached), then + set its \a pressed state. Unless \a cancel is \c true, when the state + transitions from pressed to released, also emit \l QQuickSwipeDelegateAttached::clicked(). + Returns \c true if at least one relevant attached object was found. +*/ +bool QQuickSwipeDelegatePrivate::attachedObjectsSetPressed(QQuickItem *item, QPointF scenePos, bool pressed, bool cancel) +{ + bool found = false; + QVarLengthArray<QQuickItem *, 16> itemAndChildren; + itemAndChildren.append(item); + for (int i = 0; i < itemAndChildren.count(); ++i) { + auto item = itemAndChildren.at(i); + auto posInItem = item->mapFromScene(scenePos); + if (item->contains(posInItem)) { + if (Attached *attached = attachedObject(item)) { + const bool wasPressed = attached->isPressed(); + attached->setPressed(pressed); + if (wasPressed && !pressed && !cancel) + emit attached->clicked(); + found = true; + } + } + for (auto child : item->childItems()) + itemAndChildren.append(child); + } + return found; +} + +static void warnIfHorizontallyAnchored(QQuickItem *item, const QString &itemName) +{ + if (!item) + return; + + QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors; + if (anchors && (anchors->fill() || anchors->centerIn() || anchors->left().item || anchors->right().item) + && !item->property("_q_QQuickSwipeDelegate_warned").toBool()) { + qmlWarning(item) << QString::fromLatin1("SwipeDelegate: cannot use horizontal anchors with %1; unable to layout the item.").arg(itemName); + item->setProperty("_q_QQuickSwipeDelegate_warned", true); + } +} + +void QQuickSwipeDelegatePrivate::resizeContent() +{ + warnIfHorizontallyAnchored(background, QStringLiteral("background")); + warnIfHorizontallyAnchored(contentItem, QStringLiteral("contentItem")); + + // If the background and contentItem are repositioned due to a swipe, + // we don't want to call QQuickControlPrivate's implementation of this function, + // as it repositions the contentItem to be visible. + // However, we still want to position the contentItem vertically + // and resize it (in case the control was resized while open). + QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&swipe); + if (!swipePrivate->complete) { + QQuickItemDelegatePrivate::resizeContent(); + } else if (contentItem) { + Q_Q(QQuickSwipeDelegate); + contentItem->setY(q->topPadding()); + contentItem->setWidth(q->availableWidth()); + contentItem->setHeight(q->availableHeight()); + } +} + +QPalette QQuickSwipeDelegatePrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::ListView); +} + +QQuickSwipeDelegate::QQuickSwipeDelegate(QQuickItem *parent) + : QQuickItemDelegate(*(new QQuickSwipeDelegatePrivate(this)), parent) +{ + // QQuickSwipeDelegate still depends on synthesized mouse events + setAcceptTouchEvents(false); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlmethod void QtQuick.Controls::SwipeDelegate::swipe.open(enumeration side) + + This method sets the \c position of the swipe so that it opens + from the specified \a side. + + Available values: + \value SwipeDelegate.Left The \c position is set to \c 1, which makes the swipe open + from the left. Either \c swipe.left or \c swipe.behind must + have been specified; otherwise the call is ignored. + \value SwipeDelegate.Right The \c position is set to \c -1, which makes the swipe open + from the right. Either \c swipe.right or \c swipe.behind must + have been specified; otherwise the call is ignored. + + Any animations defined for the \l {Item::}{x} position of \l {Control::}{contentItem} + and \l {Control::}{background} will be triggered. + + \sa swipe, swipe.close() +*/ + +/*! + \since QtQuick.Controls 2.1 (Qt 5.8) + \qmlmethod void QtQuick.Controls::SwipeDelegate::swipe.close() + + This method sets the \c position of the swipe to \c 0. Any animations + defined for the \l {Item::}{x} position of \l {Control::}{contentItem} + and \l {Control::}{background} will be triggered. + + \sa swipe, swipe.open() +*/ + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlsignal void QtQuick.Controls::SwipeDelegate::swipe.opened() + + This signal is emitted when the delegate has been swiped open + and the transition has finished. + + It is useful for performing some action upon completion of a swipe. + For example, it can be used to remove the delegate from the list + that it is in. + + \sa swipe, swipe.closed() +*/ + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlsignal void QtQuick.Controls::SwipeDelegate::swipe.closed() + + This signal is emitted when the delegate has been swiped to closed + and the transition has finished. + + It is useful for performing some action upon cancellation of a swipe. + For example, it can be used to cancel the removal of the delegate from + the list that it is in. + + \sa swipe, swipe.opened() +*/ + +/*! + \since QtQuick.Controls 2.1 (Qt 5.8) + \qmlsignal void QtQuick.Controls::SwipeDelegate::swipe.completed() + + This signal is emitted when \c swipe.complete becomes \c true. + + It is useful for performing some action upon completion of a swipe. + For example, it can be used to remove the delegate from the list + that it is in. + + \sa swipe +*/ + +/*! + \qmlproperty real QtQuick.Controls::SwipeDelegate::swipe.position + \qmlproperty bool QtQuick.Controls::SwipeDelegate::swipe.complete + \qmlproperty bool QtQuick.Controls::SwipeDelegate::swipe.enabled + \qmlproperty Component QtQuick.Controls::SwipeDelegate::swipe.left + \qmlproperty Component QtQuick.Controls::SwipeDelegate::swipe.behind + \qmlproperty Component QtQuick.Controls::SwipeDelegate::swipe.right + \qmlproperty Item QtQuick.Controls::SwipeDelegate::swipe.leftItem + \qmlproperty Item QtQuick.Controls::SwipeDelegate::swipe.behindItem + \qmlproperty Item QtQuick.Controls::SwipeDelegate::swipe.rightItem + \qmlproperty Transition QtQuick.Controls::SwipeDelegate::swipe.transition + + \table + \header + \li Name + \li Description + \row + \li position + \li This read-only property holds the position of the swipe relative to either + side of the control. When this value reaches either + \c -1.0 (left side) or \c 1.0 (right side) and the mouse button is + released, \c complete will be \c true. + \row + \li complete + \li This read-only property holds whether the control is fully exposed after + having been swiped to the left or right. + + When complete is \c true, any interactive items declared in \c left, + \c right, or \c behind will receive mouse events. + \row + \li enabled + \li This property determines whether or not the control can be swiped. + + This property was added in QtQuick.Controls 2.2. + \row + \li left + \li This property holds the left delegate. + + The left delegate sits behind both \l {Control::}{contentItem} and + \l {Control::}{background}. When the SwipeDelegate is swiped to the right, + this item will be gradually revealed. + + \include qquickswipedelegate-interaction.qdocinc + \row + \li behind + \li This property holds the delegate that is shown when the + SwipeDelegate is swiped to both the left and right. + + As with the \c left and \c right delegates, it sits behind both + \l {Control::}{contentItem} and \l {Control::}{background}. However, a + SwipeDelegate whose \c behind has been set can be continuously swiped + from either side, and will always show the same item. + + \include qquickswipedelegate-interaction.qdocinc + \row + \li right + \li This property holds the right delegate. + + The right delegate sits behind both \l {Control::}{contentItem} and + \l {Control::}{background}. When the SwipeDelegate is swiped to the left, + this item will be gradually revealed. + + \include qquickswipedelegate-interaction.qdocinc + \row + \li leftItem + \li This read-only property holds the item instantiated from the \c left component. + + If \c left has not been set, or the position hasn't changed since + creation of the SwipeDelegate, this property will be \c null. + \row + \li behindItem + \li This read-only property holds the item instantiated from the \c behind component. + + If \c behind has not been set, or the position hasn't changed since + creation of the SwipeDelegate, this property will be \c null. + \row + \li rightItem + \li This read-only property holds the item instantiated from the \c right component. + + If \c right has not been set, or the position hasn't changed since + creation of the SwipeDelegate, this property will be \c null. + \row + \li transition + \li This property holds the transition that is applied when a swipe is released, + or \l swipe.open() or \l swipe.close() is called. + + \snippet qtquickcontrols2-swipedelegate-transition.qml 1 + + This property was added in Qt Quick Controls 2.2. + \endtable + + \sa {Control::}{contentItem}, {Control::}{background}, swipe.open(), swipe.close() +*/ +QQuickSwipe *QQuickSwipeDelegate::swipe() const +{ + Q_D(const QQuickSwipeDelegate); + return const_cast<QQuickSwipe*>(&d->swipe); +} + +QQuickSwipeDelegateAttached *QQuickSwipeDelegate::qmlAttachedProperties(QObject *object) +{ + return new QQuickSwipeDelegateAttached(object); +} + +static bool isChildOrGrandchildOf(QQuickItem *child, QQuickItem *item) +{ + return item && (child == item || item->isAncestorOf(child)); +} + +bool QQuickSwipeDelegate::childMouseEventFilter(QQuickItem *child, QEvent *event) +{ + Q_D(QQuickSwipeDelegate); + // The contentItem is, by default, usually a non-interactive item like Text, and + // the same applies to the background. This means that simply stacking the left/right/behind + // items before these items won't allow us to get mouse events when the control is not currently exposed + // but has been previously. Therefore, we instead call setFiltersChildMouseEvents(true) in the constructor + // and filter out child events only when the child is the left/right/behind item. + const QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&d->swipe); + if (!isChildOrGrandchildOf(child, swipePrivate->leftItem) && !isChildOrGrandchildOf(child, swipePrivate->behindItem) + && !isChildOrGrandchildOf(child, swipePrivate->rightItem)) { + return false; + } + + switch (event->type()) { + case QEvent::MouseButtonPress: { + return d->handleMousePressEvent(child, static_cast<QMouseEvent *>(event)); + } case QEvent::MouseMove: { + return d->handleMouseMoveEvent(child, static_cast<QMouseEvent *>(event)); + } case QEvent::MouseButtonRelease: { + // Make sure that the control gets release events if it has created child + // items that are stealing events from it. + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + QQuickItemDelegate::mouseReleaseEvent(mouseEvent); + return d->handleMouseReleaseEvent(child, mouseEvent); + } case QEvent::UngrabMouse: { + // If the mouse was pressed over e.g. rightItem and then dragged down, + // the ListView would eventually grab the mouse, at which point we must + // clear the pressed flag so that it doesn't stay pressed after the release. + Attached *attached = attachedObject(child); + if (attached) + attached->setPressed(false); + return false; + } default: + return false; + } +} + +// We only override this to set positionBeforePress; +// otherwise, it's the same as the base class implementation. +void QQuickSwipeDelegate::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickSwipeDelegate); + QQuickItemDelegate::mousePressEvent(event); + + QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&d->swipe); + if (!swipePrivate->enabled) + return; + + swipePrivate->positionBeforePress = swipePrivate->position; + swipePrivate->velocityCalculator.startMeasuring(event->position().toPoint(), event->timestamp()); + + if (swipePrivate->complete) { + auto item = d->swipe.rightItem(); + if (item && item->contains(item->mapFromScene(event->scenePosition()))) { + d->pressedItem = item; + d->handleMousePressEvent(item, event); + } else { + item = d->swipe.leftItem(); + if (item && item->contains(item->mapFromScene(event->scenePosition()))) { + d->pressedItem = item; + d->handleMousePressEvent(item, event); + } + } + } +} + +void QQuickSwipeDelegate::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QQuickSwipeDelegate); + if (filtersChildMouseEvents()) + d->handleMouseMoveEvent(this, event); + else + QQuickItemDelegate::mouseMoveEvent(event); + if (d->pressedItem) + d->handleMouseMoveEvent(d->pressedItem, event); +} + +void QQuickSwipeDelegate::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QQuickSwipeDelegate); + if (!filtersChildMouseEvents() || !d->handleMouseReleaseEvent(this, event)) + QQuickItemDelegate::mouseReleaseEvent(event); + + if (d->pressedItem) { + if (d->pressedItem->acceptedMouseButtons()) + d->handleMouseReleaseEvent(d->pressedItem, event); + d->pressedItem = nullptr; + } +} + +void QQuickSwipeDelegate::mouseUngrabEvent() +{ + Q_D(QQuickSwipeDelegate); + setPressed(false); + + auto item = d->swipe.rightItem(); + if (item) { + if (auto control = qmlobject_cast<QQuickControl *>(item)) + QQuickControlPrivate::get(control)->handleUngrab(); + Attached *attached = attachedObject(item); + if (attached) + attached->setPressed(false); + } else { + item = d->swipe.leftItem(); + if (item) { + if (auto control = qmlobject_cast<QQuickControl *>(item)) + QQuickControlPrivate::get(control)->handleUngrab(); + Attached *attached = attachedObject(item); + if (attached) + attached->setPressed(false); + } + } + + d->pressedItem = nullptr; +} + +void QQuickSwipeDelegate::touchEvent(QTouchEvent *event) +{ + // Don't allow QQuickControl accept the touch event, because QQuickSwipeDelegate + // is still based on synthesized mouse events + event->ignore(); +} + +void QQuickSwipeDelegate::componentComplete() +{ + Q_D(QQuickSwipeDelegate); + QQuickItemDelegate::componentComplete(); + QQuickSwipePrivate::get(&d->swipe)->reposition(DontAnimatePosition); +} + +void QQuickSwipeDelegate::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickSwipeDelegate); + QQuickControl::geometryChange(newGeometry, oldGeometry); + + if (isComponentComplete() && !qFuzzyCompare(newGeometry.width(), oldGeometry.width())) { + QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&d->swipe); + swipePrivate->reposition(DontAnimatePosition); + } +} + +QFont QQuickSwipeDelegate::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::ListView); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickSwipeDelegate::accessibleRole() const +{ + return QAccessible::ListItem; +} +#endif + +class QQuickSwipeDelegateAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickSwipeDelegateAttached) + +public: + // True when left/right/behind is non-interactive and is pressed. + bool pressed = false; +}; + +/*! + \since QtQuick.Controls 2.1 (Qt 5.8) + \qmlattachedsignal QtQuick.Controls::SwipeDelegate::clicked() + + This signal can be attached to a non-interactive item declared in + \c swipe.left, \c swipe.right, or \c swipe.behind, in order to react to + clicks. Items can only be clicked when \c swipe.complete is \c true. + + For interactive controls (such as \l Button) declared in these + items, use their respective \c clicked() signal instead. + + To respond to clicks on the SwipeDelegate itself, use its + \l {AbstractButton::}{clicked()} signal. + + \note See the documentation for \l pressed for information on + how to use the event-related properties correctly. + + \sa pressed +*/ + +QQuickSwipeDelegateAttached::QQuickSwipeDelegateAttached(QObject *object) + : QObject(*(new QQuickSwipeDelegateAttachedPrivate), object) +{ + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (item) { + // This allows us to be notified when an otherwise non-interactive item + // is pressed and clicked. The alternative is much more more complex: + // iterating through children that contain the event pos and finding + // the first one with an attached object. + item->setAcceptedMouseButtons(Qt::AllButtons); + } else { + qWarning() << "Attached properties of SwipeDelegate must be accessed through an Item"; + } +} + +/*! + \since QtQuick.Controls 2.1 (Qt 5.8) + \qmlattachedproperty bool QtQuick.Controls::SwipeDelegate::pressed + \readonly + + This property can be attached to a non-interactive item declared in + \c swipe.left, \c swipe.right, or \c swipe.behind, in order to detect if it + is pressed. Items can only be pressed when \c swipe.complete is \c true. + + For example: + + \code + swipe.right: Label { + anchors.right: parent.right + height: parent.height + text: "Action" + color: "white" + padding: 12 + background: Rectangle { + color: SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato" + } + } + \endcode + + It is possible to have multiple items which individually receive mouse and + touch events. For example, to have two actions in the \c swipe.right item, + use the following code: + + \code + swipe.right: Row { + anchors.right: parent.right + height: parent.height + + Label { + id: moveLabel + text: qsTr("Move") + color: "white" + verticalAlignment: Label.AlignVCenter + padding: 12 + height: parent.height + + SwipeDelegate.onClicked: console.log("Moving...") + + background: Rectangle { + color: moveLabel.SwipeDelegate.pressed ? Qt.darker("#ffbf47", 1.1) : "#ffbf47" + } + } + Label { + id: deleteLabel + text: qsTr("Delete") + color: "white" + verticalAlignment: Label.AlignVCenter + padding: 12 + height: parent.height + + SwipeDelegate.onClicked: console.log("Deleting...") + + background: Rectangle { + color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato" + } + } + } + \endcode + + Note how the \c color assignment in each \l {Control::}{background} item + qualifies the attached property with the \c id of the label. This + is important; using the attached properties on an item causes that item + to accept events. Suppose we had left out the \c id in the previous example: + + \code + color: SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato" + \endcode + + The \l Rectangle background item is a child of the label, so it naturally + receives events before it. In practice, this means that the background + color will change, but the \c onClicked handler in the label will never + get called. + + For interactive controls (such as \l Button) declared in these + items, use their respective \c pressed property instead. + + For presses on the SwipeDelegate itself, use its + \l {AbstractButton::}{pressed} property. + + \sa clicked() +*/ +bool QQuickSwipeDelegateAttached::isPressed() const +{ + Q_D(const QQuickSwipeDelegateAttached); + return d->pressed; +} + +void QQuickSwipeDelegateAttached::setPressed(bool pressed) +{ + Q_D(QQuickSwipeDelegateAttached); + if (pressed == d->pressed) + return; + + d->pressed = pressed; + emit pressedChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qquickswipe_p.cpp" +#include "moc_qquickswipedelegate_p.cpp" diff --git a/src/quicktemplates2/qquickswipedelegate_p.h b/src/quicktemplates2/qquickswipedelegate_p.h new file mode 100644 index 00000000000..cbf5f4b4839 --- /dev/null +++ b/src/quicktemplates2/qquickswipedelegate_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSWIPEDELEGATE_P_H +#define QQUICKSWIPEDELEGATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickitemdelegate_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickSwipe; +class QQuickSwipeDelegatePrivate; +class QQuickSwipeDelegateAttached; +class QQuickSwipeDelegateAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSwipeDelegate : public QQuickItemDelegate +{ + Q_OBJECT + Q_PROPERTY(QQuickSwipe *swipe READ swipe CONSTANT FINAL) + QML_NAMED_ELEMENT(SwipeDelegate) + QML_ATTACHED(QQuickSwipeDelegateAttached) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickSwipeDelegate(QQuickItem *parent = nullptr); + + QQuickSwipe *swipe() const; + + enum Side { Left = 1, Right = -1 }; + Q_ENUM(Side) + + static QQuickSwipeDelegateAttached *qmlAttachedProperties(QObject *object); + +protected: + bool childMouseEventFilter(QQuickItem *child, QEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void mouseUngrabEvent() override; + void touchEvent(QTouchEvent *event) override; + + void componentComplete() override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickSwipeDelegate) + Q_DECLARE_PRIVATE(QQuickSwipeDelegate) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSwipeDelegateAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged FINAL) + +public: + explicit QQuickSwipeDelegateAttached(QObject *object = nullptr); + + bool isPressed() const; + void setPressed(bool pressed); + +Q_SIGNALS: + void pressedChanged(); + void clicked(); + +private: + Q_DISABLE_COPY(QQuickSwipeDelegateAttached) + Q_DECLARE_PRIVATE(QQuickSwipeDelegateAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickSwipeDelegate) +QML_DECLARE_TYPEINFO(QQuickSwipeDelegate, QML_HAS_ATTACHED_PROPERTIES) +Q_DECLARE_METATYPE(QQuickSwipeDelegate::Side) + +#endif // QQUICKSWIPEDELEGATE_P_H diff --git a/src/quicktemplates2/qquickswipedelegate_p_p.h b/src/quicktemplates2/qquickswipedelegate_p_p.h new file mode 100644 index 00000000000..46e47eb677e --- /dev/null +++ b/src/quicktemplates2/qquickswipedelegate_p_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSWIPEDELEGATE_P_P_H +#define QQUICKSWIPEDELEGATE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickitemdelegate_p_p.h> +#include <QtQuickTemplates2/private/qquickswipe_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickSwipeDelegate; + +class QQuickSwipeDelegatePrivate : public QQuickItemDelegatePrivate +{ + Q_DECLARE_PUBLIC(QQuickSwipeDelegate) + +public: + QQuickSwipeDelegatePrivate(QQuickSwipeDelegate *control); + + bool handleMousePressEvent(QQuickItem *item, QMouseEvent *event); + bool handleMouseMoveEvent(QQuickItem *item, QMouseEvent *event); + bool handleMouseReleaseEvent(QQuickItem *item, QMouseEvent *event); + void forwardMouseEvent(QMouseEvent *event, QQuickItem *destination, QPointF localPos); + bool attachedObjectsSetPressed(QQuickItem *item, QPointF scenePos, bool pressed, bool cancel = false); + + void resizeContent() override; + void resizeBackground() override; + + QPalette defaultPalette() const override; + + QQuickSwipe swipe; + QQuickItem *pressedItem = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSWIPEDELEGATE_P_P_H diff --git a/src/quicktemplates2/qquickswipeview.cpp b/src/quicktemplates2/qquickswipeview.cpp new file mode 100644 index 00000000000..8a18d6266d2 --- /dev/null +++ b/src/quicktemplates2/qquickswipeview.cpp @@ -0,0 +1,489 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickswipeview_p.h" + +#include <QtQml/qqmlinfo.h> +#include <QtQuickTemplates2/private/qquickcontainer_p_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype SwipeView + \inherits Container +//! \instantiates QQuickSwipeView + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-navigation + \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes + \brief Enables the user to navigate pages by swiping sideways. + + SwipeView provides a swipe-based navigation model. + + \image qtquickcontrols2-swipeview.gif + + SwipeView is populated with a set of pages. One page is visible at a time. + The user can navigate between the pages by swiping sideways. Notice that + SwipeView itself is entirely non-visual. It is recommended to combine it + with PageIndicator, to give the user a visual clue that there are multiple + pages. + + \snippet qtquickcontrols2-swipeview-indicator.qml 1 + + As shown above, SwipeView is typically populated with a static set of + pages that are defined inline as children of the view. It is also possible + to \l {Container::addItem()}{add}, \l {Container::insertItem()}{insert}, + \l {Container::moveItem()}{move}, and \l {Container::removeItem()}{remove} + pages dynamically at run time. + + \include container-currentindex.qdocinc {file} {SwipeView} {TabBar} + + It is generally not advisable to add excessive amounts of pages to a + SwipeView. However, when the amount of pages grows larger, or individual + pages are relatively complex, it may be desirable to free up resources by + unloading pages that are outside the immediate reach of the user. + The following example presents how to use \l Loader to keep a maximum of + three pages simultaneously instantiated. + + \code + SwipeView { + Repeater { + model: 6 + Loader { + active: SwipeView.isCurrentItem || SwipeView.isNextItem || SwipeView.isPreviousItem + sourceComponent: Text { + text: index + Component.onCompleted: console.log("created:", index) + Component.onDestruction: console.log("destroyed:", index) + } + } + } + } + \endcode + + \note SwipeView takes over the geometry management of items added to the + view. Using anchors on the items is not supported, and any \c width + or \c height assignment will be overridden by the view. Notice that + this only applies to the root of the item. Specifying width and height, + or using anchors for its children works as expected. + + \sa TabBar, PageIndicator, {Customizing SwipeView}, {Navigation Controls}, {Container Controls}, + {Focus Management in Qt Quick Controls} +*/ + +class QQuickSwipeViewPrivate : public QQuickContainerPrivate +{ + Q_DECLARE_PUBLIC(QQuickSwipeView) + +public: + void resizeItem(int index, QQuickItem *item); + void resizeItems(); + + static QQuickSwipeViewPrivate *get(QQuickSwipeView *view); + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + qreal getContentWidth() const override; + qreal getContentHeight() const override; + + bool interactive = true; + Qt::Orientation orientation = Qt::Horizontal; +}; + +class QQuickSwipeViewAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickSwipeViewAttached) + +public: + static QQuickSwipeViewAttachedPrivate *get(QQuickSwipeViewAttached *attached) + { + return attached->d_func(); + } + + void update(QQuickSwipeView *newView, int newIndex); + void updateCurrentIndex(); + void setCurrentIndex(int i); + + QQuickSwipeView *swipeView = nullptr; + int index = -1; + int currentIndex = -1; +}; + +void QQuickSwipeViewPrivate::resizeItem(int index, QQuickItem *item) +{ + QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors; + // TODO: expose QQuickAnchorLine so we can test for other conflicting anchors + if (anchors && (anchors->fill() || anchors->centerIn()) && !item->property("_q_QQuickSwipeView_warned").toBool()) { + qmlWarning(item) << "SwipeView has detected conflicting anchors. Unable to layout the item."; + item->setProperty("_q_QQuickSwipeView_warned", true); + } + if (orientation == Qt::Horizontal) + item->setPosition({index * (contentItem->width() + spacing), 0}); + else + item->setPosition({0, index * (contentItem->height() + spacing)}); + item->setSize(QSizeF(contentItem->width(), contentItem->height())); +} + +void QQuickSwipeViewPrivate::resizeItems() +{ + Q_Q(QQuickSwipeView); + const int count = q->count(); + for (int i = 0; i < count; ++i) { + QQuickItem *item = itemAt(i); + if (item) + resizeItem(i, item); + } +} + +QQuickSwipeViewPrivate *QQuickSwipeViewPrivate::get(QQuickSwipeView *view) +{ + return view->d_func(); +} + +void QQuickSwipeViewPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickSwipeView); + QQuickContainerPrivate::itemImplicitWidthChanged(item); + if (item == q->currentItem()) + updateImplicitContentWidth(); +} + +void QQuickSwipeViewPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickSwipeView); + QQuickContainerPrivate::itemImplicitHeightChanged(item); + if (item == q->currentItem()) + updateImplicitContentHeight(); +} + +qreal QQuickSwipeViewPrivate::getContentWidth() const +{ + Q_Q(const QQuickSwipeView); + QQuickItem *currentItem = q->currentItem(); + return currentItem ? currentItem->implicitWidth() : 0; +} + +qreal QQuickSwipeViewPrivate::getContentHeight() const +{ + Q_Q(const QQuickSwipeView); + QQuickItem *currentItem = q->currentItem(); + return currentItem ? currentItem->implicitHeight() : 0; +} + +QQuickSwipeView::QQuickSwipeView(QQuickItem *parent) + : QQuickContainer(*(new QQuickSwipeViewPrivate), parent) +{ + Q_D(QQuickSwipeView); + d->changeTypes |= QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; + setFlag(ItemIsFocusScope); + setActiveFocusOnTab(true); + QObjectPrivate::connect(this, &QQuickContainer::currentItemChanged, d, &QQuickControlPrivate::updateImplicitContentSize); +} + +/*! + \since QtQuick.Controls 2.1 (Qt 5.8) + \qmlproperty bool QtQuick.Controls::SwipeView::interactive + + This property describes whether the user can interact with the SwipeView. + The user cannot swipe a view that is not interactive. + + The default value is \c true. +*/ +bool QQuickSwipeView::isInteractive() const +{ + Q_D(const QQuickSwipeView); + return d->interactive; +} + +void QQuickSwipeView::setInteractive(bool interactive) +{ + Q_D(QQuickSwipeView); + if (d->interactive == interactive) + return; + + d->interactive = interactive; + emit interactiveChanged(); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty enumeration QtQuick.Controls::SwipeView::orientation + + This property holds the orientation. + + Possible values: + \value Qt.Horizontal Horizontal (default) + \value Qt.Vertical Vertical + + \sa horizontal, vertical +*/ +Qt::Orientation QQuickSwipeView::orientation() const +{ + Q_D(const QQuickSwipeView); + return d->orientation; +} + +void QQuickSwipeView::setOrientation(Qt::Orientation orientation) +{ + Q_D(QQuickSwipeView); + if (d->orientation == orientation) + return; + + d->orientation = orientation; + if (isComponentComplete()) + d->resizeItems(); + emit orientationChanged(); +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::SwipeView::horizontal + \readonly + + This property holds whether the swipe view is horizontal. + + \sa orientation +*/ +bool QQuickSwipeView::isHorizontal() const +{ + Q_D(const QQuickSwipeView); + return d->orientation == Qt::Horizontal; +} + +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty bool QtQuick.Controls::SwipeView::vertical + \readonly + + This property holds whether the swipe view is vertical. + + \sa orientation +*/ +bool QQuickSwipeView::isVertical() const +{ + Q_D(const QQuickSwipeView); + return d->orientation == Qt::Vertical; +} + +QQuickSwipeViewAttached *QQuickSwipeView::qmlAttachedProperties(QObject *object) +{ + return new QQuickSwipeViewAttached(object); +} + +void QQuickSwipeView::componentComplete() +{ + Q_D(QQuickSwipeView); + QQuickContainer::componentComplete(); + d->resizeItems(); +} + +void QQuickSwipeView::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickSwipeView); + QQuickContainer::geometryChange(newGeometry, oldGeometry); + d->resizeItems(); +} + +void QQuickSwipeView::itemAdded(int index, QQuickItem *item) +{ + Q_D(QQuickSwipeView); + if (isComponentComplete()) + d->resizeItem(index, item); + QQuickSwipeViewAttached *attached = qobject_cast<QQuickSwipeViewAttached *>(qmlAttachedPropertiesObject<QQuickSwipeView>(item)); + if (attached) + QQuickSwipeViewAttachedPrivate::get(attached)->update(this, index); +} + +void QQuickSwipeView::itemMoved(int index, QQuickItem *item) +{ + QQuickSwipeViewAttached *attached = qobject_cast<QQuickSwipeViewAttached *>(qmlAttachedPropertiesObject<QQuickSwipeView>(item)); + if (attached) + QQuickSwipeViewAttachedPrivate::get(attached)->update(this, index); +} + +void QQuickSwipeView::itemRemoved(int, QQuickItem *item) +{ + QQuickSwipeViewAttached *attached = qobject_cast<QQuickSwipeViewAttached *>(qmlAttachedPropertiesObject<QQuickSwipeView>(item)); + if (attached) + QQuickSwipeViewAttachedPrivate::get(attached)->update(nullptr, -1); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickSwipeView::accessibleRole() const +{ + return QAccessible::PageTabList; +} +#endif + +/*! + \qmlattachedproperty int QtQuick.Controls::SwipeView::index + \readonly + + This attached property holds the index of each child item in the SwipeView. + + It is attached to each child item of the SwipeView. +*/ + +/*! + \qmlattachedproperty bool QtQuick.Controls::SwipeView::isCurrentItem + \readonly + + This attached property is \c true if this child is the current item. + + It is attached to each child item of the SwipeView. +*/ + +/*! + \qmlattachedproperty bool QtQuick.Controls::SwipeView::isNextItem + \since QtQuick.Controls 2.1 (Qt 5.8) + \readonly + + This attached property is \c true if this child is the next item. + + It is attached to each child item of the SwipeView. +*/ + +/*! + \qmlattachedproperty bool QtQuick.Controls::SwipeView::isPreviousItem + \since QtQuick.Controls 2.1 (Qt 5.8) + \readonly + + This attached property is \c true if this child is the previous item. + + It is attached to each child item of the SwipeView. +*/ + +/*! + \qmlattachedproperty SwipeView QtQuick.Controls::SwipeView::view + \readonly + + This attached property holds the view that manages this child item. + + It is attached to each child item of the SwipeView. +*/ + +void QQuickSwipeViewAttachedPrivate::updateCurrentIndex() +{ + setCurrentIndex(swipeView ? swipeView->currentIndex() : -1); +} + +void QQuickSwipeViewAttachedPrivate::setCurrentIndex(int i) +{ + if (i == currentIndex) + return; + + Q_Q(QQuickSwipeViewAttached); + const bool wasCurrent = q->isCurrentItem(); + const bool wasNext = q->isNextItem(); + const bool wasPrevious = q->isPreviousItem(); + + currentIndex = i; + if (wasCurrent != q->isCurrentItem()) + emit q->isCurrentItemChanged(); + if (wasNext != q->isNextItem()) + emit q->isNextItemChanged(); + if (wasPrevious != q->isPreviousItem()) + emit q->isPreviousItemChanged(); +} + +void QQuickSwipeViewAttachedPrivate::update(QQuickSwipeView *newView, int newIndex) +{ + Q_Q(QQuickSwipeViewAttached); + int oldIndex = index; + QQuickSwipeView *oldView = swipeView; + + index = newIndex; + swipeView = newView; + + if (oldView != newView) { + if (oldView) { + disconnect(oldView, &QQuickSwipeView::currentIndexChanged, + this, &QQuickSwipeViewAttachedPrivate::updateCurrentIndex); + } + if (newView) { + connect(newView, &QQuickSwipeView::currentIndexChanged, + this, &QQuickSwipeViewAttachedPrivate::updateCurrentIndex); + } + emit q->viewChanged(); + } + if (oldIndex != newIndex) + emit q->indexChanged(); + + updateCurrentIndex(); +} + +QQuickSwipeViewAttached::QQuickSwipeViewAttached(QObject *parent) + : QObject(*(new QQuickSwipeViewAttachedPrivate), parent) +{ + if (!qobject_cast<QQuickItem *>(parent)) + qmlWarning(parent) << "SwipeView: attached properties must be accessed from within a child item"; +} + +int QQuickSwipeViewAttached::index() const +{ + Q_D(const QQuickSwipeViewAttached); + return d->index; +} + +bool QQuickSwipeViewAttached::isCurrentItem() const +{ + Q_D(const QQuickSwipeViewAttached); + return d->index != -1 && d->currentIndex != -1 && d->index == d->currentIndex; +} + +QQuickSwipeView *QQuickSwipeViewAttached::view() const +{ + Q_D(const QQuickSwipeViewAttached); + return d->swipeView; +} + +bool QQuickSwipeViewAttached::isNextItem() const +{ + Q_D(const QQuickSwipeViewAttached); + return d->index != -1 && d->currentIndex != -1 && d->index == d->currentIndex + 1; +} + +bool QQuickSwipeViewAttached::isPreviousItem() const +{ + Q_D(const QQuickSwipeViewAttached); + return d->index != -1 && d->currentIndex != -1 && d->index == d->currentIndex - 1; +} + +QT_END_NAMESPACE + +#include "moc_qquickswipeview_p.cpp" diff --git a/src/quicktemplates2/qquickswipeview_p.h b/src/quicktemplates2/qquickswipeview_p.h new file mode 100644 index 00000000000..7723a58374b --- /dev/null +++ b/src/quicktemplates2/qquickswipeview_p.h @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSWIPEVIEW_P_H +#define QQUICKSWIPEVIEW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontainer_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickSwipeViewAttached; +class QQuickSwipeViewPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSwipeView : public QQuickContainer +{ + Q_OBJECT + // 2.1 (Qt 5.8) + Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive NOTIFY interactiveChanged FINAL REVISION(2, 1)) + // 2.2 (Qt 5.9) + Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL REVISION(2, 2)) + // 2.3 (Qt 5.10) + Q_PROPERTY(bool horizontal READ isHorizontal NOTIFY orientationChanged FINAL REVISION(2, 3)) + Q_PROPERTY(bool vertical READ isVertical NOTIFY orientationChanged FINAL REVISION(2, 3)) + QML_NAMED_ELEMENT(SwipeView) + QML_ATTACHED(QQuickSwipeViewAttached) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickSwipeView(QQuickItem *parent = nullptr); + + static QQuickSwipeViewAttached *qmlAttachedProperties(QObject *object); + + // 2.1 (Qt 5.8) + bool isInteractive() const; + void setInteractive(bool interactive); + + // 2.2 (Qt 5.9) + Qt::Orientation orientation() const; + void setOrientation(Qt::Orientation orientation); + + // 2.3 (Qt 5.10) + bool isHorizontal() const; + bool isVertical() const; + +Q_SIGNALS: + // 2.1 (Qt 5.8) + Q_REVISION(2, 1) void interactiveChanged(); + // 2.2 (Qt 5.9) + Q_REVISION(2, 2) void orientationChanged(); + +protected: + void componentComplete() override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + void itemAdded(int index, QQuickItem *item) override; + void itemMoved(int index, QQuickItem *item) override; + void itemRemoved(int index, QQuickItem *item) override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickSwipeView) + Q_DECLARE_PRIVATE(QQuickSwipeView) +}; + +class QQuickSwipeViewAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSwipeViewAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(int index READ index NOTIFY indexChanged FINAL) + Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY isCurrentItemChanged FINAL) + Q_PROPERTY(QQuickSwipeView *view READ view NOTIFY viewChanged FINAL) + // 2.1 (Qt 5.8) + Q_PROPERTY(bool isNextItem READ isNextItem NOTIFY isNextItemChanged FINAL REVISION(2, 1)) + Q_PROPERTY(bool isPreviousItem READ isPreviousItem NOTIFY isPreviousItemChanged FINAL REVISION(2, 1)) + +public: + explicit QQuickSwipeViewAttached(QObject *parent = nullptr); + + int index() const; + bool isCurrentItem() const; + QQuickSwipeView *view() const; + + // 2.1 (Qt 5.8) + bool isNextItem() const; + bool isPreviousItem() const; + +Q_SIGNALS: + void indexChanged(); + void isCurrentItemChanged(); + void viewChanged(); + // 2.1 (Qt 5.8) + /*Q_REVISION(2, 1)*/ void isNextItemChanged(); + /*Q_REVISION(2, 1)*/ void isPreviousItemChanged(); + +private: + Q_DISABLE_COPY(QQuickSwipeViewAttached) + Q_DECLARE_PRIVATE(QQuickSwipeViewAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickSwipeView) +QML_DECLARE_TYPEINFO(QQuickSwipeView, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKSWIPEVIEW_P_H diff --git a/src/quicktemplates2/qquickswitch.cpp b/src/quicktemplates2/qquickswitch.cpp new file mode 100644 index 00000000000..9d4ac4530b4 --- /dev/null +++ b/src/quicktemplates2/qquickswitch.cpp @@ -0,0 +1,241 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickswitch_p.h" +#include "qquickabstractbutton_p_p.h" + +#include <QtGui/qstylehints.h> +#include <QtGui/qguiapplication.h> +#include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qquickevents_p_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Switch + \inherits AbstractButton +//! \instantiates QQuickSwitch + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-buttons + \brief Switch button that can be toggled on or off. + + \image qtquickcontrols2-switch.gif + + Switch is an option button that can be dragged or toggled on (checked) or + off (unchecked). Switches are typically used to select between two states. + For larger sets of options, such as those in a list, consider using + \l SwitchDelegate instead. + + Switch inherits its API from \l AbstractButton. For instance, the state + of the switch can be set with the \l {AbstractButton::}{checked} property. + + \code + ColumnLayout { + Switch { + text: qsTr("Wi-Fi") + } + Switch { + text: qsTr("Bluetooth") + } + } + \endcode + + \sa {Customizing Switch}, {Button Controls} +*/ + +class QQuickSwitchPrivate : public QQuickAbstractButtonPrivate +{ + Q_DECLARE_PUBLIC(QQuickSwitch) + +public: + qreal positionAt(const QPointF &point) const; + + bool canDrag(const QPointF &movePoint) const; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::Switch); } + + qreal position = 0; +}; + +qreal QQuickSwitchPrivate::positionAt(const QPointF &point) const +{ + Q_Q(const QQuickSwitch); + qreal pos = 0.0; + if (indicator) + pos = indicator->mapFromItem(q, point).x() / indicator->width(); + if (q->isMirrored()) + return 1.0 - pos; + return pos; +} + +bool QQuickSwitchPrivate::canDrag(const QPointF &movePoint) const +{ + // don't start dragging the handle unless the initial press was at the indicator, + // or the drag has reached the indicator area. this prevents unnatural jumps when + // dragging far outside the indicator. + const qreal pressPos = positionAt(pressPoint); + const qreal movePos = positionAt(movePoint); + return (pressPos >= 0.0 && pressPos <= 1.0) || (movePos >= 0.0 && movePos <= 1.0); +} + +void QQuickSwitchPrivate::handleMove(const QPointF &point) +{ + Q_Q(QQuickSwitch); + QQuickAbstractButtonPrivate::handleMove(point); + if (q->keepMouseGrab() || q->keepTouchGrab()) + q->setPosition(positionAt(point)); +} + +void QQuickSwitchPrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickSwitch); + QQuickAbstractButtonPrivate::handleRelease(point); + q->setKeepMouseGrab(false); + q->setKeepTouchGrab(false); +} + +QQuickSwitch::QQuickSwitch(QQuickItem *parent) + : QQuickAbstractButton(*(new QQuickSwitchPrivate), parent) +{ + Q_D(QQuickSwitch); + d->keepPressed = true; + setCheckable(true); +} + +/*! + \qmlproperty real QtQuick.Controls::Switch::position + \readonly + + \input includes/qquickswitch.qdocinc position +*/ +qreal QQuickSwitch::position() const +{ + Q_D(const QQuickSwitch); + return d->position; +} + +void QQuickSwitch::setPosition(qreal position) +{ + Q_D(QQuickSwitch); + position = qBound<qreal>(0.0, position, 1.0); + if (qFuzzyCompare(d->position, position)) + return; + + d->position = position; + emit positionChanged(); + emit visualPositionChanged(); +} + +/*! + \qmlproperty real QtQuick.Controls::Switch::visualPosition + \readonly + + \input includes/qquickswitch.qdocinc visualPosition +*/ +qreal QQuickSwitch::visualPosition() const +{ + Q_D(const QQuickSwitch); + if (isMirrored()) + return 1.0 - d->position; + return d->position; +} + +void QQuickSwitch::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QQuickSwitch); + if (!keepMouseGrab()) { + const QPointF movePoint = event->position(); + if (d->canDrag(movePoint)) + setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(movePoint.x() - d->pressPoint.x(), Qt::XAxis, event)); + } + QQuickAbstractButton::mouseMoveEvent(event); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickSwitch::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickSwitch); + if (!keepTouchGrab() && event->type() == QEvent::TouchUpdate) { + for (const QTouchEvent::TouchPoint &point : event->points()) { + if (point.id() != d->touchId || point.state() != QEventPoint::Updated) + continue; + if (d->canDrag(point.position())) + setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().x() - d->pressPoint.x(), Qt::XAxis, &point)); + } + } + QQuickAbstractButton::touchEvent(event); +} +#endif + +void QQuickSwitch::mirrorChange() +{ + QQuickAbstractButton::mirrorChange(); + emit visualPositionChanged(); +} + +void QQuickSwitch::nextCheckState() +{ + Q_D(QQuickSwitch); + if (keepMouseGrab() || keepTouchGrab()) { + d->toggle(d->position > 0.5); + // the checked state might not change => force a position update to + // avoid that the handle is left somewhere in the middle (QTBUG-57944) + setPosition(d->checked ? 1.0 : 0.0); + } else { + QQuickAbstractButton::nextCheckState(); + } +} + +void QQuickSwitch::buttonChange(ButtonChange change) +{ + Q_D(QQuickSwitch); + if (change == ButtonCheckedChange) + setPosition(d->checked ? 1.0 : 0.0); + else + QQuickAbstractButton::buttonChange(change); +} + +QFont QQuickSwitch::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::Switch); +} + +QT_END_NAMESPACE + +#include "moc_qquickswitch_p.cpp" diff --git a/src/quicktemplates2/qquickswitch_p.h b/src/quicktemplates2/qquickswitch_p.h new file mode 100644 index 00000000000..b3df029923a --- /dev/null +++ b/src/quicktemplates2/qquickswitch_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSWITCH_P_H +#define QQUICKSWITCH_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickSwitchPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSwitch : public QQuickAbstractButton +{ + Q_OBJECT + Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged FINAL) + Q_PROPERTY(qreal visualPosition READ visualPosition NOTIFY visualPositionChanged FINAL) + QML_NAMED_ELEMENT(Switch) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickSwitch(QQuickItem *parent = nullptr); + + qreal position() const; + void setPosition(qreal position); + + qreal visualPosition() const; + +Q_SIGNALS: + void positionChanged(); + void visualPositionChanged(); + +protected: + void mouseMoveEvent(QMouseEvent *event) override; +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif + + void mirrorChange() override; + + void nextCheckState() override; + void buttonChange(ButtonChange change) override; + + QFont defaultFont() const override; + +private: + Q_DISABLE_COPY(QQuickSwitch) + Q_DECLARE_PRIVATE(QQuickSwitch) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickSwitch) + +#endif // QQUICKSWITCH_P_H diff --git a/src/quicktemplates2/qquickswitchdelegate.cpp b/src/quicktemplates2/qquickswitchdelegate.cpp new file mode 100644 index 00000000000..4b9e3e79f45 --- /dev/null +++ b/src/quicktemplates2/qquickswitchdelegate.cpp @@ -0,0 +1,238 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickswitchdelegate_p.h" + +#include "qquickitemdelegate_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype SwitchDelegate + \inherits ItemDelegate +//! \instantiates QQuickSwitchDelegate + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-delegates + \brief Item delegate with a switch indicator that can be toggled on or off. + + \image qtquickcontrols2-switchdelegate.gif + + SwitchDelegate presents an item delegate that can be toggled on (checked) or + off (unchecked). Switch delegates are typically used to select one or more + options from a set of options. For smaller sets of options, or for options + that need to be uniquely identifiable, consider using \l Switch instead. + + SwitchDelegate inherits its API from \l ItemDelegate, which is inherited + from \l AbstractButton. For instance, you can set \l {AbstractButton::text}{text}, + and react to \l {AbstractButton::clicked}{clicks} using the \l AbstractButton + API. The state of the switch delegate can be set with the + \l {AbstractButton::}{checked} property. + + \code + ListView { + model: ["Option 1", "Option 2", "Option 3"] + delegate: SwitchDelegate { + text: modelData + } + } + \endcode + + \sa {Customizing SwitchDelegate}, {Delegate Controls} +*/ + +class QQuickSwitchDelegatePrivate : public QQuickItemDelegatePrivate +{ + Q_DECLARE_PUBLIC(QQuickSwitchDelegate) + +public: + qreal positionAt(const QPointF &point) const; + + bool canDrag(const QPointF &movePoint) const; + void handleMove(const QPointF &point) override; + void handleRelease(const QPointF &point) override; + + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::ListView); } + + qreal position = 0; +}; + +qreal QQuickSwitchDelegatePrivate::positionAt(const QPointF &point) const +{ + Q_Q(const QQuickSwitchDelegate); + qreal pos = 0.0; + if (indicator) + pos = indicator->mapFromItem(q, point).x() / indicator->width(); + if (q->isMirrored()) + return 1.0 - pos; + return pos; +} + +bool QQuickSwitchDelegatePrivate::canDrag(const QPointF &movePoint) const +{ + // don't start dragging the handle unless the initial press was at the indicator, + // or the drag has reached the indicator area. this prevents unnatural jumps when + // dragging far outside the indicator. + const qreal pressPos = positionAt(pressPoint); + const qreal movePos = positionAt(movePoint); + return (pressPos >= 0.0 && pressPos <= 1.0) || (movePos >= 0.0 && movePos <= 1.0); +} + +void QQuickSwitchDelegatePrivate::handleMove(const QPointF &point) +{ + Q_Q(QQuickSwitchDelegate); + QQuickItemDelegatePrivate::handleMove(point); + if (q->keepMouseGrab() || q->keepTouchGrab()) + q->setPosition(positionAt(point)); +} + +void QQuickSwitchDelegatePrivate::handleRelease(const QPointF &point) +{ + Q_Q(QQuickSwitchDelegate); + QQuickItemDelegatePrivate::handleRelease(point); + q->setKeepMouseGrab(false); + q->setKeepTouchGrab(false); +} + +QQuickSwitchDelegate::QQuickSwitchDelegate(QQuickItem *parent) + : QQuickItemDelegate(*(new QQuickSwitchDelegatePrivate), parent) +{ + Q_D(QQuickSwitchDelegate); + d->keepPressed = true; + setCheckable(true); +} + +/*! + \qmlproperty real QtQuick.Controls::SwitchDelegate::position + \readonly + + \input includes/qquickswitch.qdocinc position +*/ +qreal QQuickSwitchDelegate::position() const +{ + Q_D(const QQuickSwitchDelegate); + return d->position; +} + +void QQuickSwitchDelegate::setPosition(qreal position) +{ + Q_D(QQuickSwitchDelegate); + position = qBound<qreal>(0.0, position, 1.0); + if (qFuzzyCompare(d->position, position)) + return; + + d->position = position; + emit positionChanged(); + emit visualPositionChanged(); +} + +/*! + \qmlproperty real QtQuick.Controls::SwitchDelegate::visualPosition + \readonly + + \input includes/qquickswitch.qdocinc visualPosition +*/ +qreal QQuickSwitchDelegate::visualPosition() const +{ + Q_D(const QQuickSwitchDelegate); + if (isMirrored()) + return 1.0 - d->position; + return d->position; +} + +void QQuickSwitchDelegate::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QQuickSwitchDelegate); + if (!keepMouseGrab()) { + const QPointF movePoint = event->position(); + if (d->canDrag(movePoint)) + setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(movePoint.x() - d->pressPoint.x(), Qt::XAxis, event)); + } + QQuickItemDelegate::mouseMoveEvent(event); +} + +#if QT_CONFIG(quicktemplates2_multitouch) +void QQuickSwitchDelegate::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickSwitchDelegate); + if (!keepTouchGrab() && event->type() == QEvent::TouchUpdate) { + for (const QTouchEvent::TouchPoint &point : event->points()) { + if (point.id() != d->touchId || point.state() != QEventPoint::Updated) + continue; + if (d->canDrag(point.position())) + setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.position().x() - d->pressPoint.x(), Qt::XAxis, &point)); + } + } + QQuickItemDelegate::touchEvent(event); +} +#endif + +QFont QQuickSwitchDelegate::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::ListView); +} + +void QQuickSwitchDelegate::mirrorChange() +{ + QQuickItemDelegate::mirrorChange(); + emit visualPositionChanged(); +} + +void QQuickSwitchDelegate::nextCheckState() +{ + Q_D(QQuickSwitchDelegate); + if (keepMouseGrab() || keepTouchGrab()) { + d->toggle(d->position > 0.5); + // the checked state might not change => force a position update to + // avoid that the handle is left somewhere in the middle (QTBUG-57944) + setPosition(d->checked ? 1.0 : 0.0); + } else { + QQuickItemDelegate::nextCheckState(); + } +} + +void QQuickSwitchDelegate::buttonChange(ButtonChange change) +{ + Q_D(QQuickSwitchDelegate); + if (change == ButtonCheckedChange) + setPosition(d->checked ? 1.0 : 0.0); + else + QQuickAbstractButton::buttonChange(change); +} + +QT_END_NAMESPACE + +#include "moc_qquickswitchdelegate_p.cpp" diff --git a/src/quicktemplates2/qquickswitchdelegate_p.h b/src/quicktemplates2/qquickswitchdelegate_p.h new file mode 100644 index 00000000000..a2eb6f62ae3 --- /dev/null +++ b/src/quicktemplates2/qquickswitchdelegate_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKSWITCHDELEGATE_P_H +#define QQUICKSWITCHDELEGATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickitemdelegate_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickSwitchDelegatePrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSwitchDelegate : public QQuickItemDelegate +{ + Q_OBJECT + Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged FINAL) + Q_PROPERTY(qreal visualPosition READ visualPosition NOTIFY visualPositionChanged FINAL) + QML_NAMED_ELEMENT(SwitchDelegate) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickSwitchDelegate(QQuickItem *parent = nullptr); + + qreal position() const; + void setPosition(qreal position); + + qreal visualPosition() const; + +Q_SIGNALS: + void positionChanged(); + void visualPositionChanged(); + +protected: + void mouseMoveEvent(QMouseEvent *event) override; +#if QT_CONFIG(quicktemplates2_multitouch) + void touchEvent(QTouchEvent *event) override; +#endif + + QFont defaultFont() const override; + + void mirrorChange() override; + + void nextCheckState() override; + void buttonChange(ButtonChange change) override; + +private: + Q_DISABLE_COPY(QQuickSwitchDelegate) + Q_DECLARE_PRIVATE(QQuickSwitchDelegate) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickSwitchDelegate) + +#endif // QQUICKSWITCHDELEGATE_P_H diff --git a/src/quicktemplates2/qquicktabbar.cpp b/src/quicktemplates2/qquicktabbar.cpp new file mode 100644 index 00000000000..0297324e01d --- /dev/null +++ b/src/quicktemplates2/qquicktabbar.cpp @@ -0,0 +1,508 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktabbar_p.h" +#include "qquicktabbutton_p.h" +#include "qquickcontainer_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype TabBar + \inherits Container +//! \instantiates QQuickTabBar + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-navigation + \ingroup qtquickcontrols2-containers + \ingroup qtquickcontrols2-focusscopes + \brief Allows the user to switch between different views or subtasks. + + TabBar provides a tab-based navigation model. + + \image qtquickcontrols2-tabbar-wireframe.png + + TabBar is populated with TabButton controls, and can be used together with + any layout or container control that provides \c currentIndex -property, + such as \l StackLayout or \l SwipeView + + \snippet qtquickcontrols2-tabbar.qml 1 + + As shown above, TabBar is typically populated with a static set of tab buttons + that are defined inline as children of the tab bar. It is also possible to + \l {Container::addItem()}{add}, \l {Container::insertItem()}{insert}, + \l {Container::moveItem()}{move}, and \l {Container::removeItem()}{remove} + items dynamically at run time. The items can be accessed using + \l {Container::}{itemAt()} or \l {Container::}{contentChildren}. + + \include container-currentindex.qdocinc {file} {TabBar} {SwipeView} + + \section2 Resizing Tabs + + By default, TabBar resizes its buttons to fit the width of the control. + The available space is distributed equally to each button. The default + resizing behavior can be overridden by setting an explicit width for the + buttons. + + The following example illustrates how to keep each tab button at their + implicit size instead of being resized to fit the tabbar: + + \borderedimage qtquickcontrols2-tabbar-explicit.png + + \snippet qtquickcontrols2-tabbar-explicit.qml 1 + + \section2 Flickable Tabs + + If the total width of the buttons exceeds the available width of the tab bar, + it automatically becomes flickable. + + \image qtquickcontrols2-tabbar-flickable.png + + \snippet qtquickcontrols2-tabbar-flickable.qml 1 + + \sa TabButton, {Customizing TabBar}, {Navigation Controls}, {Container Controls}, + {Focus Management in Qt Quick Controls} +*/ + +class QQuickTabBarPrivate : public QQuickContainerPrivate +{ + Q_DECLARE_PUBLIC(QQuickTabBar) + +public: + void updateCurrentItem(); + void updateCurrentIndex(); + void updateLayout(); + + qreal getContentWidth() const override; + qreal getContentHeight() const override; + + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::TabBar); } + + bool updatingLayout = false; + QQuickTabBar::Position position = QQuickTabBar::Header; +#if QT_CONFIG(wheelevent) + QPoint accumulatedAngleDelta; +#endif +}; + +class QQuickTabBarAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickTabBarAttached) + +public: + static QQuickTabBarAttachedPrivate *get(QQuickTabBarAttached *attached) + { + return attached->d_func(); + } + + void update(QQuickTabBar *tabBar, int index); + + int index = -1; + QQuickTabBar *tabBar = nullptr; +}; + +void QQuickTabBarPrivate::updateCurrentItem() +{ + QQuickTabButton *button = qobject_cast<QQuickTabButton *>(contentModel->get(currentIndex)); + if (button) + button->setChecked(true); +} + +void QQuickTabBarPrivate::updateCurrentIndex() +{ + Q_Q(QQuickTabBar); + QQuickTabButton *button = qobject_cast<QQuickTabButton *>(q->sender()); + if (button && button->isChecked()) + q->setCurrentIndex(contentModel->indexOf(button, nullptr)); +} + +void QQuickTabBarPrivate::updateLayout() +{ + Q_Q(QQuickTabBar); + const int count = contentModel->count(); + if (count <= 0 || !contentItem) + return; + + qreal reservedWidth = 0; + int resizableCount = 0; + + QList<QQuickItem *> allItems; + allItems.reserve(count); + + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) { + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + if (!p->widthValid()) + ++resizableCount; + else + reservedWidth += item->width(); + allItems += item; + } + } + + const qreal totalSpacing = qMax(0, count - 1) * spacing; + const qreal itemWidth = (contentItem->width() - reservedWidth - totalSpacing) / qMax(1, resizableCount); + + updatingLayout = true; + for (QQuickItem *item : qAsConst(allItems)) { + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + if (!p->widthValid()) { + item->setWidth(itemWidth); + p->widthValidFlag = false; + } + if (!p->heightValid()) { + item->setHeight(contentHeight); + p->heightValidFlag = false; + } else { + item->setY((contentHeight - item->height()) / 2); + } + } + updatingLayout = false; +} + +qreal QQuickTabBarPrivate::getContentWidth() const +{ + Q_Q(const QQuickTabBar); + const int count = contentModel->count(); + qreal totalWidth = qMax(0, count - 1) * spacing; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) { + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + if (!p->widthValid()) + totalWidth += item->implicitWidth(); + else + totalWidth += item->width(); + } + } + return totalWidth; +} + +qreal QQuickTabBarPrivate::getContentHeight() const +{ + Q_Q(const QQuickTabBar); + const int count = contentModel->count(); + qreal maxHeight = 0; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) + maxHeight = qMax(maxHeight, item->implicitHeight()); + } + return maxHeight; +} + +void QQuickTabBarPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) +{ + QQuickContainerPrivate::itemGeometryChanged(item, change, diff); + if (!updatingLayout) { + if (change.sizeChange()) + updateImplicitContentSize(); + updateLayout(); + } +} + +void QQuickTabBarPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + QQuickContainerPrivate::itemImplicitWidthChanged(item); + if (item != contentItem) + updateImplicitContentWidth(); +} + +void QQuickTabBarPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + QQuickContainerPrivate::itemImplicitHeightChanged(item); + if (item != contentItem) + updateImplicitContentHeight(); +} + +QQuickTabBar::QQuickTabBar(QQuickItem *parent) + : QQuickContainer(*(new QQuickTabBarPrivate), parent) +{ + Q_D(QQuickTabBar); + d->changeTypes |= QQuickItemPrivate::Geometry | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; + setFlag(ItemIsFocusScope); + QObjectPrivate::connect(this, &QQuickTabBar::currentIndexChanged, d, &QQuickTabBarPrivate::updateCurrentItem); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::TabBar::position + + This property holds the position of the tab bar. + + \note If the tab bar is assigned as a header or footer of \l ApplicationWindow + or \l Page, the appropriate position is set automatically. + + Possible values: + \value TabBar.Header The tab bar is at the top, as a window or page header. + \value TabBar.Footer The tab bar is at the bottom, as a window or page footer. + + The default value is style-specific. + + \sa ApplicationWindow::header, ApplicationWindow::footer, Page::header, Page::footer +*/ +QQuickTabBar::Position QQuickTabBar::position() const +{ + Q_D(const QQuickTabBar); + return d->position; +} + +void QQuickTabBar::setPosition(Position position) +{ + Q_D(QQuickTabBar); + if (d->position == position) + return; + + d->position = position; + emit positionChanged(); +} + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty real QtQuick.Controls::TabBar::contentWidth + + This property holds the content width. It is used for calculating the total + implicit width of the tab bar. + + \note This property is available in TabBar since QtQuick.Controls 2.2 (Qt 5.9), + but it was promoted to the Container base type in QtQuick.Controls 2.5 (Qt 5.12). + + \sa Container::contentWidth +*/ + +/*! + \since QtQuick.Controls 2.2 (Qt 5.9) + \qmlproperty real QtQuick.Controls::TabBar::contentHeight + + This property holds the content height. It is used for calculating the total + implicit height of the tab bar. + + \note This property is available in TabBar since QtQuick.Controls 2.2 (Qt 5.9), + but it was promoted to the Container base type in QtQuick.Controls 2.5 (Qt 5.12). + + \sa Container::contentHeight +*/ + +QQuickTabBarAttached *QQuickTabBar::qmlAttachedProperties(QObject *object) +{ + return new QQuickTabBarAttached(object); +} + +void QQuickTabBar::updatePolish() +{ + Q_D(QQuickTabBar); + QQuickContainer::updatePolish(); + d->updateLayout(); +} + +void QQuickTabBar::componentComplete() +{ + Q_D(QQuickTabBar); + QQuickContainer::componentComplete(); + d->updateCurrentItem(); + d->updateLayout(); +} + +void QQuickTabBar::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickTabBar); + QQuickContainer::geometryChange(newGeometry, oldGeometry); + d->updateLayout(); +} + +bool QQuickTabBar::isContent(QQuickItem *item) const +{ + return qobject_cast<QQuickTabButton *>(item); +} + +void QQuickTabBar::itemAdded(int index, QQuickItem *item) +{ + Q_D(QQuickTabBar); + Q_UNUSED(index); + QQuickItemPrivate::get(item)->setCulled(true); // QTBUG-55129 + if (QQuickTabButton *button = qobject_cast<QQuickTabButton *>(item)) + QObjectPrivate::connect(button, &QQuickTabButton::checkedChanged, d, &QQuickTabBarPrivate::updateCurrentIndex); + QQuickTabBarAttached *attached = qobject_cast<QQuickTabBarAttached *>(qmlAttachedPropertiesObject<QQuickTabBar>(item)); + if (attached) + QQuickTabBarAttachedPrivate::get(attached)->update(this, index); + d->updateImplicitContentSize(); + if (isComponentComplete()) + polish(); +} + +void QQuickTabBar::itemMoved(int index, QQuickItem *item) +{ + QQuickTabBarAttached *attached = qobject_cast<QQuickTabBarAttached *>(qmlAttachedPropertiesObject<QQuickTabBar>(item)); + if (attached) + QQuickTabBarAttachedPrivate::get(attached)->update(this, index); +} + +void QQuickTabBar::itemRemoved(int index, QQuickItem *item) +{ + Q_D(QQuickTabBar); + Q_UNUSED(index); + if (QQuickTabButton *button = qobject_cast<QQuickTabButton *>(item)) + QObjectPrivate::disconnect(button, &QQuickTabButton::checkedChanged, d, &QQuickTabBarPrivate::updateCurrentIndex); + QQuickTabBarAttached *attached = qobject_cast<QQuickTabBarAttached *>(qmlAttachedPropertiesObject<QQuickTabBar>(item)); + if (attached) + QQuickTabBarAttachedPrivate::get(attached)->update(nullptr, -1); + d->updateImplicitContentSize(); + if (isComponentComplete()) + polish(); +} + +#if QT_CONFIG(wheelevent) +void QQuickTabBar::wheelEvent(QWheelEvent *event) +{ + Q_D(QQuickTabBar); + QQuickContainer::wheelEvent(event); + if (d->wheelEnabled) { + d->accumulatedAngleDelta += event->angleDelta(); + int xSteps = d->accumulatedAngleDelta.x() / QWheelEvent::DefaultDeltasPerStep; + int ySteps = d->accumulatedAngleDelta.y() / QWheelEvent::DefaultDeltasPerStep; + if (xSteps > 0 || ySteps > 0) { + decrementCurrentIndex(); + d->accumulatedAngleDelta = QPoint(); + } else if (xSteps < 0 || ySteps < 0) { + incrementCurrentIndex(); + d->accumulatedAngleDelta = QPoint(); + } + } +} +#endif + +QFont QQuickTabBar::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::TabBar); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickTabBar::accessibleRole() const +{ + return QAccessible::PageTabList; +} +#endif + +/*! + \qmlattachedproperty int QtQuick.Controls::TabBar::index + \since QtQuick.Controls 2.3 (Qt 5.10) + \readonly + + This attached property holds the index of each tab button in the TabBar. + + It is attached to each tab button of the TabBar. +*/ + +/*! + \qmlattachedproperty TabBar QtQuick.Controls::TabBar::tabBar + \since QtQuick.Controls 2.3 (Qt 5.10) + \readonly + + This attached property holds the tab bar that manages this tab button. + + It is attached to each tab button of the TabBar. +*/ + +/*! + \qmlattachedproperty enumeration QtQuick.Controls::TabBar::position + \since QtQuick.Controls 2.3 (Qt 5.10) + \readonly + + This attached property holds the position of the tab bar. + + It is attached to each tab button of the TabBar. + + Possible values: + \value TabBar.Header The tab bar is at the top, as a window or page header. + \value TabBar.Footer The tab bar is at the bottom, as a window or page footer. +*/ + +void QQuickTabBarAttachedPrivate::update(QQuickTabBar *newTabBar, int newIndex) +{ + Q_Q(QQuickTabBarAttached); + const int oldIndex = index; + const QQuickTabBar *oldTabBar = tabBar; + const QQuickTabBar::Position oldPos = q->position(); + + index = newIndex; + tabBar = newTabBar; + + if (oldTabBar != newTabBar) { + if (oldTabBar) + QObject::disconnect(oldTabBar, &QQuickTabBar::positionChanged, q, &QQuickTabBarAttached::positionChanged); + if (newTabBar) + QObject::connect(newTabBar, &QQuickTabBar::positionChanged, q, &QQuickTabBarAttached::positionChanged); + emit q->tabBarChanged(); + } + + if (oldIndex != newIndex) + emit q->indexChanged(); + if (oldPos != q->position()) + emit q->positionChanged(); +} + +QQuickTabBarAttached::QQuickTabBarAttached(QObject *parent) + : QObject(*(new QQuickTabBarAttachedPrivate), parent) +{ +} + +int QQuickTabBarAttached::index() const +{ + Q_D(const QQuickTabBarAttached); + return d->index; +} + +QQuickTabBar *QQuickTabBarAttached::tabBar() const +{ + Q_D(const QQuickTabBarAttached); + return d->tabBar; +} + +QQuickTabBar::Position QQuickTabBarAttached::position() const +{ + Q_D(const QQuickTabBarAttached); + if (!d->tabBar) + return QQuickTabBar::Header; + return d->tabBar->position(); +} + +QT_END_NAMESPACE + +#include "moc_qquicktabbar_p.cpp" diff --git a/src/quicktemplates2/qquicktabbar_p.h b/src/quicktemplates2/qquicktabbar_p.h new file mode 100644 index 00000000000..2da6d4a77b3 --- /dev/null +++ b/src/quicktemplates2/qquicktabbar_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTABBAR_P_H +#define QQUICKTABBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontainer_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickTabBarPrivate; +class QQuickTabBarAttached; +class QQuickTabBarAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTabBar : public QQuickContainer +{ + Q_OBJECT + Q_PROPERTY(Position position READ position WRITE setPosition NOTIFY positionChanged FINAL) + QML_NAMED_ELEMENT(TabBar) + QML_ATTACHED(QQuickTabBarAttached) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickTabBar(QQuickItem *parent = nullptr); + + enum Position { + Header, + Footer + }; + Q_ENUM(Position) + + Position position() const; + void setPosition(Position position); + + static QQuickTabBarAttached *qmlAttachedProperties(QObject *object); + +Q_SIGNALS: + void positionChanged(); + +protected: + void updatePolish() override; + void componentComplete() override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + bool isContent(QQuickItem *item) const override; + void itemAdded(int index, QQuickItem *item) override; + void itemMoved(int index, QQuickItem *item) override; + void itemRemoved(int index, QQuickItem *item) override; +#if QT_CONFIG(wheelevent) + void wheelEvent(QWheelEvent *event) override; +#endif + + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickTabBar) + Q_DECLARE_PRIVATE(QQuickTabBar) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTabBarAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(int index READ index NOTIFY indexChanged FINAL) + Q_PROPERTY(QQuickTabBar *tabBar READ tabBar NOTIFY tabBarChanged FINAL) + Q_PROPERTY(QQuickTabBar::Position position READ position NOTIFY positionChanged FINAL) + +public: + explicit QQuickTabBarAttached(QObject *parent = nullptr); + + int index() const; + QQuickTabBar *tabBar() const; + QQuickTabBar::Position position() const; + +Q_SIGNALS: + void indexChanged(); + void tabBarChanged(); + void positionChanged(); + +private: + Q_DISABLE_COPY(QQuickTabBarAttached) + Q_DECLARE_PRIVATE(QQuickTabBarAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickTabBar) +QML_DECLARE_TYPEINFO(QQuickTabBar, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKTABBAR_P_H diff --git a/src/quicktemplates2/qquicktabbutton.cpp b/src/quicktemplates2/qquicktabbutton.cpp new file mode 100644 index 00000000000..0faa2150ea0 --- /dev/null +++ b/src/quicktemplates2/qquicktabbutton.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktabbutton_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickabstractbutton_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype TabButton + \inherits AbstractButton +//! \instantiates QQuickTabButton + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-navigation + \brief Button with a look suitable for a TabBar. + + \image qtquickcontrols2-tabbutton.png + + TabButton is used in conjunction with a \l TabBar. + + \snippet qtquickcontrols2-tabbutton.qml 1 + + TabButton inherits its API from AbstractButton. For instance, you can set + \l {AbstractButton::text}{text}, and react to \l {AbstractButton::clicked}{clicks} + using the AbstractButton API. + + \sa TabBar, {Customizing TabButton}, {Button Controls}, {Navigation Controls} +*/ + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTabButtonPrivate : public QQuickAbstractButtonPrivate +{ + Q_DECLARE_PUBLIC(QQuickTabButton) + +public: + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::TabBar); } +}; + +QQuickTabButton::QQuickTabButton(QQuickItem *parent) + : QQuickAbstractButton(*(new QQuickTabButtonPrivate), parent) +{ + setCheckable(true); + setAutoExclusive(true); +} + +QFont QQuickTabButton::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::TabBar); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickTabButton::accessibleRole() const +{ + return QAccessible::PageTab; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquicktabbutton_p.cpp" diff --git a/src/quicktemplates2/qquicktabbutton_p.h b/src/quicktemplates2/qquicktabbutton_p.h new file mode 100644 index 00000000000..302180c47db --- /dev/null +++ b/src/quicktemplates2/qquicktabbutton_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTABBUTTON_P_H +#define QQUICKTABBUTTON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickTabButtonPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTabButton : public QQuickAbstractButton +{ + Q_OBJECT + QML_NAMED_ELEMENT(TabButton) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickTabButton(QQuickItem *parent = nullptr); + +protected: + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DECLARE_PRIVATE(QQuickTabButton) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickTabButton) + +#endif // QQUICKTABBUTTON_P_H diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp new file mode 100644 index 00000000000..1628f649259 --- /dev/null +++ b/src/quicktemplates2/qquicktextarea.cpp @@ -0,0 +1,1181 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktextarea_p.h" +#include "qquicktextarea_p_p.h" +#include "qquickcontrol_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickscrollview_p.h" +#include "qquickdeferredexecute_p_p.h" + +#include <QtQml/qqmlinfo.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquickclipnode_p.h> +#include <QtQuick/private/qquickflickable_p.h> + +#if QT_CONFIG(accessibility) +#include <QtQuick/private/qquickaccessibleattached_p.h> +#endif + +QT_BEGIN_NAMESPACE + +/*! + \qmltype TextArea + \inherits TextEdit +//! \instantiates QQuickTextArea + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-input + \brief Multi-line text input area. + + TextArea is a multi-line text editor. TextArea extends TextEdit with + a \l {placeholderText}{placeholder text} functionality, and adds decoration. + + \image qtquickcontrols2-textarea.png + + \code + TextArea { + placeholderText: qsTr("Enter description") + } + \endcode + + TextArea is not scrollable by itself. Especially on screen-size constrained + platforms, it is often preferable to make entire application pages scrollable. + On such a scrollable page, a non-scrollable TextArea might behave better than + nested scrollable controls. Notice, however, that in such a scenario, the background + decoration of the TextArea scrolls together with the rest of the scrollable + content. + + \section2 Scrollable TextArea + + If you want to make a TextArea scrollable, for example, when it covers + an entire application page, it can be placed inside a \l ScrollView. + + \image qtquickcontrols2-textarea-scrollable.png + + \snippet qtquickcontrols2-textarea-scrollable.qml 1 + + A TextArea that is placed inside a \l ScrollView does the following: + + \list + \li Sets the content size automatically + \li Ensures that the background decoration stays in place + \li Clips the content + \endlist + + \section2 Tab Focus + + By default, pressing the tab key while TextArea has + \l {Item::activeFocus}{active focus} results in a tab character being input + into the control itself. To make tab pass active focus onto another item, + use the attached \l KeyNavigation properties: + + \code + TextField { + id: textField + } + + TextArea { + KeyNavigation.priority: KeyNavigation.BeforeItem + KeyNavigation.tab: textField + } + \endcode + + \sa TextField, {Customizing TextArea}, {Input Controls} +*/ + +/*! + \qmlsignal QtQuick.Controls::TextArea::pressAndHold(MouseEvent event) + + This signal is emitted when there is a long press (the delay depends on the platform plugin). + The \a event parameter provides information about the press, including the x and y + coordinates of the press, and which button is pressed. + + \sa pressed, released +*/ + +/*! + \qmlsignal QtQuick.Controls::TextArea::pressed(MouseEvent event) + \since QtQuick.Controls 2.1 (Qt 5.8) + + This signal is emitted when the text area is pressed by the user. + The \a event parameter provides information about the press, + including the x and y coordinates of the press, and which button is pressed. + + \sa released, pressAndHold +*/ + +/*! + \qmlsignal QtQuick.Controls::TextArea::released(MouseEvent event) + \since QtQuick.Controls 2.1 (Qt 5.8) + + This signal is emitted when the text area is released by the user. + The \a event parameter provides information about the release, + including the x and y coordinates of the press, and which button + is pressed. + + \sa pressed, pressAndHold +*/ + +QQuickTextAreaPrivate::QQuickTextAreaPrivate() +{ +#if QT_CONFIG(accessibility) + QAccessible::installActivationObserver(this); +#endif +} + +QQuickTextAreaPrivate::~QQuickTextAreaPrivate() +{ +#if QT_CONFIG(accessibility) + QAccessible::removeActivationObserver(this); +#endif +} + +void QQuickTextAreaPrivate::setTopInset(qreal value, bool reset) +{ + Q_Q(QQuickTextArea); + const QMarginsF oldInset = getInset(); + extra.value().topInset = value; + extra.value().hasTopInset = !reset; + if (!qFuzzyCompare(oldInset.top(), value)) { + emit q->topInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickTextAreaPrivate::setLeftInset(qreal value, bool reset) +{ + Q_Q(QQuickTextArea); + const QMarginsF oldInset = getInset(); + extra.value().leftInset = value; + extra.value().hasLeftInset = !reset; + if (!qFuzzyCompare(oldInset.left(), value)) { + emit q->leftInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickTextAreaPrivate::setRightInset(qreal value, bool reset) +{ + Q_Q(QQuickTextArea); + const QMarginsF oldInset = getInset(); + extra.value().rightInset = value; + extra.value().hasRightInset = !reset; + if (!qFuzzyCompare(oldInset.right(), value)) { + emit q->rightInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickTextAreaPrivate::setBottomInset(qreal value, bool reset) +{ + Q_Q(QQuickTextArea); + const QMarginsF oldInset = getInset(); + extra.value().bottomInset = value; + extra.value().hasBottomInset = !reset; + if (!qFuzzyCompare(oldInset.bottom(), value)) { + emit q->bottomInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickTextAreaPrivate::resizeBackground() +{ + if (!background) + return; + + resizingBackground = true; + + // When using the attached property TextArea.flickable, we reparent the background out + // of TextArea and into the Flickable since we don't want the background to move while + // flicking. This means that the size of the background should also follow the size of + // the Flickable rather than the size of the TextArea. + const auto flickable = qobject_cast<QQuickFlickable *>(background->parentItem()); + + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + if (((!p->widthValid() || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(background->x())) + || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) { + const qreal bgWidth = flickable ? flickable->width() : width; + background->setX(getLeftInset()); + background->setWidth(bgWidth - getLeftInset() - getRightInset()); + } + + if (((!p->heightValid() || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(background->y())) + || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) { + const qreal bgHeight = flickable ? flickable->height() : height; + background->setY(getTopInset()); + background->setHeight(bgHeight - getTopInset() - getBottomInset()); + } + + resizingBackground = false; +} + +/*! + \internal + + Determine which font is implicitly imposed on this control by its ancestors + and QGuiApplication::font, resolve this against its own font (attributes from + the implicit font are copied over). Then propagate this font to this + control's children. +*/ +void QQuickTextAreaPrivate::resolveFont() +{ + Q_Q(QQuickTextArea); + inheritFont(QQuickControlPrivate::parentFont(q)); +} + +void QQuickTextAreaPrivate::inheritFont(const QFont &font) +{ + QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font; + parentFont.setResolveMask(extra.isAllocated() ? extra->requestedFont.resolveMask() | font.resolveMask() : font.resolveMask()); + + const QFont defaultFont = QQuickTheme::font(QQuickTheme::TextArea); + QFont resolvedFont = parentFont.resolve(defaultFont); + + setFont_helper(resolvedFont); +} + +/*! + \internal + + Assign \a font to this control, and propagate it to all children. +*/ +void QQuickTextAreaPrivate::updateFont(const QFont &font) +{ + Q_Q(QQuickTextArea); + QFont oldFont = sourceFont; + q->QQuickTextEdit::setFont(font); + + QQuickControlPrivate::updateFontRecur(q, font); + + if (oldFont != font) + emit q->fontChanged(); +} + +#if QT_CONFIG(quicktemplates2_hover) +void QQuickTextAreaPrivate::updateHoverEnabled(bool enabled, bool xplicit) +{ + Q_Q(QQuickTextArea); + if (!xplicit && explicitHoverEnabled) + return; + + bool wasEnabled = q->isHoverEnabled(); + explicitHoverEnabled = xplicit; + if (wasEnabled != enabled) { + q->setAcceptHoverEvents(enabled); + QQuickControlPrivate::updateHoverEnabledRecur(q, enabled); + emit q->hoverEnabledChanged(); + } +} +#endif + +void QQuickTextAreaPrivate::attachFlickable(QQuickFlickable *item) +{ + Q_Q(QQuickTextArea); + flickable = item; + q->setParentItem(flickable->contentItem()); + + if (background) + background->setParentItem(flickable); + + QObjectPrivate::connect(q, &QQuickTextArea::contentSizeChanged, this, &QQuickTextAreaPrivate::resizeFlickableContent); + QObjectPrivate::connect(q, &QQuickTextEdit::cursorRectangleChanged, this, &QQuickTextAreaPrivate::ensureCursorVisible); + + QObject::connect(flickable, &QQuickFlickable::contentXChanged, q, &QQuickItem::update); + QObject::connect(flickable, &QQuickFlickable::contentYChanged, q, &QQuickItem::update); + + QQuickItemPrivate::get(flickable)->updateOrAddGeometryChangeListener(this, QQuickGeometryChange::Size); + QQuickItemPrivate::get(flickable)->addItemChangeListener(this, QQuickItemPrivate::Destroyed); + QObjectPrivate::connect(flickable, &QQuickFlickable::contentWidthChanged, this, &QQuickTextAreaPrivate::resizeFlickableControl); + QObjectPrivate::connect(flickable, &QQuickFlickable::contentHeightChanged, this, &QQuickTextAreaPrivate::resizeFlickableControl); + + resizeFlickableControl(); +} + +void QQuickTextAreaPrivate::detachFlickable() +{ + Q_Q(QQuickTextArea); + q->setParentItem(nullptr); + if (background && background->parentItem() == flickable) + background->setParentItem(q); + + QObjectPrivate::disconnect(q, &QQuickTextArea::contentSizeChanged, this, &QQuickTextAreaPrivate::resizeFlickableContent); + QObjectPrivate::disconnect(q, &QQuickTextEdit::cursorRectangleChanged, this, &QQuickTextAreaPrivate::ensureCursorVisible); + + QObject::disconnect(flickable, &QQuickFlickable::contentXChanged, q, &QQuickItem::update); + QObject::disconnect(flickable, &QQuickFlickable::contentYChanged, q, &QQuickItem::update); + + QQuickItemPrivate::get(flickable)->updateOrRemoveGeometryChangeListener(this, QQuickGeometryChange::Nothing); + QQuickItemPrivate::get(flickable)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed); + QObjectPrivate::disconnect(flickable, &QQuickFlickable::contentWidthChanged, this, &QQuickTextAreaPrivate::resizeFlickableControl); + QObjectPrivate::disconnect(flickable, &QQuickFlickable::contentHeightChanged, this, &QQuickTextAreaPrivate::resizeFlickableControl); + + flickable = nullptr; + + resizeBackground(); +} + +void QQuickTextAreaPrivate::ensureCursorVisible() +{ + Q_Q(QQuickTextArea); + if (!flickable) + return; + + const qreal cx = flickable->contentX(); + const qreal cy = flickable->contentY(); + const qreal w = flickable->width(); + const qreal h = flickable->height(); + + const qreal tp = q->topPadding(); + const qreal lp = q->leftPadding(); + const QRectF cr = q->cursorRectangle(); + + if (cr.left() <= cx + lp) { + flickable->setContentX(cr.left() - lp); + } else { + // calculate the rectangle of the next character and ensure that + // it's visible if it's on the same line with the cursor + const qreal rp = q->rightPadding(); + const QRectF nr = q->cursorPosition() < q->length() ? q->positionToRectangle(q->cursorPosition() + 1) : QRectF(); + if (qFuzzyCompare(nr.y(), cr.y()) && nr.right() >= cx + lp + w - rp) + flickable->setContentX(nr.right() - w + rp); + else if (cr.right() >= cx + lp + w - rp) + flickable->setContentX(cr.right() - w + rp); + } + + if (cr.top() <= cy + tp) { + flickable->setContentY(cr.top() - tp); + } else { + const qreal bp = q->bottomPadding(); + if (cr.bottom() >= cy + tp + h - bp) + flickable->setContentY(cr.bottom() - h + bp); + } +} + +void QQuickTextAreaPrivate::resizeFlickableControl() +{ + Q_Q(QQuickTextArea); + if (!flickable) + return; + + const qreal w = wrapMode == QQuickTextArea::NoWrap ? qMax(flickable->width(), flickable->contentWidth()) : flickable->width(); + const qreal h = qMax(flickable->height(), flickable->contentHeight()); + q->setSize(QSizeF(w, h)); + + resizeBackground(); +} + +void QQuickTextAreaPrivate::resizeFlickableContent() +{ + Q_Q(QQuickTextArea); + if (!flickable) + return; + + flickable->setContentWidth(q->contentWidth() + q->leftPadding() + q->rightPadding()); + flickable->setContentHeight(q->contentHeight() + q->topPadding() + q->bottomPadding()); +} + +void QQuickTextAreaPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) +{ + Q_UNUSED(diff); + if (!resizingBackground && item == background) { + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + // Only set hasBackgroundWidth/Height if it was a width/height change, + // otherwise we're prevented from setting a width/height in the future. + if (change.widthChange()) + extra.value().hasBackgroundWidth = p->widthValid(); + if (change.heightChange()) + extra.value().hasBackgroundHeight = p->heightValid(); + } + + if (flickable) + resizeFlickableControl(); + else + resizeBackground(); +} + +qreal QQuickTextAreaPrivate::getImplicitWidth() const +{ + return QQuickItemPrivate::getImplicitWidth(); +} + +qreal QQuickTextAreaPrivate::getImplicitHeight() const +{ + return QQuickItemPrivate::getImplicitHeight(); +} + +void QQuickTextAreaPrivate::implicitWidthChanged() +{ + Q_Q(QQuickTextArea); + QQuickItemPrivate::implicitWidthChanged(); + emit q->implicitWidthChanged3(); +} + +void QQuickTextAreaPrivate::implicitHeightChanged() +{ + Q_Q(QQuickTextArea); + QQuickItemPrivate::implicitHeightChanged(); + emit q->implicitHeightChanged3(); +} + +void QQuickTextAreaPrivate::readOnlyChanged(bool isReadOnly) +{ + Q_UNUSED(isReadOnly); +#if QT_CONFIG(accessibility) + if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(q_func())) + accessibleAttached->set_readOnly(isReadOnly); +#endif +#if QT_CONFIG(cursor) + q_func()->setCursor(isReadOnly && !selectByMouse ? Qt::ArrowCursor : Qt::IBeamCursor); +#endif +} + +#if QT_CONFIG(accessibility) +void QQuickTextAreaPrivate::accessibilityActiveChanged(bool active) +{ + if (!active) + return; + + Q_Q(QQuickTextArea); + QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, true)); + Q_ASSERT(accessibleAttached); + accessibleAttached->setRole(effectiveAccessibleRole()); + accessibleAttached->set_readOnly(q->isReadOnly()); + accessibleAttached->setDescription(placeholder); +} + +QAccessible::Role QQuickTextAreaPrivate::accessibleRole() const +{ + return QAccessible::EditableText; +} +#endif + +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickTextAreaPrivate::cancelBackground() +{ + Q_Q(QQuickTextArea); + quickCancelDeferred(q, backgroundName()); +} + +void QQuickTextAreaPrivate::executeBackground(bool complete) +{ + Q_Q(QQuickTextArea); + if (background.wasExecuted()) + return; + + if (!background || complete) + quickBeginDeferred(q, backgroundName(), background); + if (complete) + quickCompleteDeferred(q, backgroundName(), background); +} + +void QQuickTextAreaPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickTextArea); + if (item == background) + emit q->implicitBackgroundWidthChanged(); +} + +void QQuickTextAreaPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickTextArea); + if (item == background) + emit q->implicitBackgroundHeightChanged(); +} + +void QQuickTextAreaPrivate::itemDestroyed(QQuickItem *item) +{ + Q_Q(QQuickTextArea); + if (item == background) { + background = nullptr; + emit q->implicitBackgroundWidthChanged(); + emit q->implicitBackgroundHeightChanged(); + } else if (item == flickable) { + detachFlickable(); + } +} + +QPalette QQuickTextAreaPrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::TextArea); +} + +QQuickTextArea::QQuickTextArea(QQuickItem *parent) + : QQuickTextEdit(*(new QQuickTextAreaPrivate), parent) +{ + Q_D(QQuickTextArea); + setActiveFocusOnTab(true); + setAcceptedMouseButtons(Qt::AllButtons); + d->setImplicitResizeEnabled(false); + d->pressHandler.control = this; +#if QT_CONFIG(cursor) + setCursor(Qt::IBeamCursor); +#endif + QObjectPrivate::connect(this, &QQuickTextEdit::readOnlyChanged, + d, &QQuickTextAreaPrivate::readOnlyChanged); +} + +QQuickTextArea::~QQuickTextArea() +{ + Q_D(QQuickTextArea); + if (d->flickable) + d->detachFlickable(); + QQuickControlPrivate::removeImplicitSizeListener(d->background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); +} + +QQuickTextAreaAttached *QQuickTextArea::qmlAttachedProperties(QObject *object) +{ + return new QQuickTextAreaAttached(object); +} + +QFont QQuickTextArea::font() const +{ + return QQuickTextEdit::font(); +} + +void QQuickTextArea::setFont(const QFont &font) +{ + Q_D(QQuickTextArea); + if (d->extra.value().requestedFont.resolveMask() == font.resolveMask() && d->extra.value().requestedFont == font) + return; + + d->extra.value().requestedFont = font; + d->resolveFont(); +} + +/*! + \qmlproperty Item QtQuick.Controls::TextArea::background + + This property holds the background item. + + \input qquickcontrol-background.qdocinc notes + + \sa {Customizing TextArea} +*/ +QQuickItem *QQuickTextArea::background() const +{ + QQuickTextAreaPrivate *d = const_cast<QQuickTextAreaPrivate *>(d_func()); + if (!d->background) + d->executeBackground(); + return d->background; +} + +void QQuickTextArea::setBackground(QQuickItem *background) +{ + Q_D(QQuickTextArea); + if (d->background == background) + return; + + if (!d->background.isExecuting()) + d->cancelBackground(); + + const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth(); + const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight(); + + if (d->extra.isAllocated()) { + d->extra.value().hasBackgroundWidth = false; + d->extra.value().hasBackgroundHeight = false; + } + + QQuickControlPrivate::removeImplicitSizeListener(d->background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); + QQuickControlPrivate::hideOldItem(d->background); + d->background = background; + + if (background) { + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + if (p->widthValid() || p->heightValid()) { + d->extra.value().hasBackgroundWidth = p->widthValid(); + d->extra.value().hasBackgroundHeight = p->heightValid(); + } + if (d->flickable) + background->setParentItem(d->flickable); + else + background->setParentItem(this); + if (qFuzzyIsNull(background->z())) + background->setZ(-1); + if (isComponentComplete()) + d->resizeBackground(); + QQuickControlPrivate::addImplicitSizeListener(background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); + } + + if (!qFuzzyCompare(oldImplicitBackgroundWidth, implicitBackgroundWidth())) + emit implicitBackgroundWidthChanged(); + if (!qFuzzyCompare(oldImplicitBackgroundHeight, implicitBackgroundHeight())) + emit implicitBackgroundHeightChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); +} + +/*! + \qmlproperty string QtQuick.Controls::TextArea::placeholderText + + This property holds the short hint that is displayed in the text area before + the user enters a value. +*/ +QString QQuickTextArea::placeholderText() const +{ + Q_D(const QQuickTextArea); + return d->placeholder; +} + +void QQuickTextArea::setPlaceholderText(const QString &text) +{ + Q_D(QQuickTextArea); + if (d->placeholder == text) + return; + + d->placeholder = text; +#if QT_CONFIG(accessibility) + if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this)) + accessibleAttached->setDescription(text); +#endif + emit placeholderTextChanged(); +} + +/*! + \qmlproperty color QtQuick.Controls::TextArea::placeholderTextColor + \since QtQuick.Controls 2.5 (Qt 5.12) + + This property holds the color of placeholderText. + + \sa placeholderText +*/ +QColor QQuickTextArea::placeholderTextColor() const +{ + Q_D(const QQuickTextArea); + return d->placeholderColor; +} + +void QQuickTextArea::setPlaceholderTextColor(const QColor &color) +{ + Q_D(QQuickTextArea); + if (d->placeholderColor == color) + return; + + d->placeholderColor = color; + emit placeholderTextColorChanged(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::TextArea::focusReason + + \include qquickcontrol-focusreason.qdocinc +*/ +Qt::FocusReason QQuickTextArea::focusReason() const +{ + Q_D(const QQuickTextArea); + return d->focusReason; +} + +void QQuickTextArea::setFocusReason(Qt::FocusReason reason) +{ + Q_D(QQuickTextArea); + if (d->focusReason == reason) + return; + + d->focusReason = reason; + emit focusReasonChanged(); +} + +bool QQuickTextArea::contains(const QPointF &point) const +{ + Q_D(const QQuickTextArea); + if (d->flickable && !d->flickable->contains(d->flickable->mapFromItem(this, point))) + return false; + return QQuickTextEdit::contains(point); +} + +/*! + \since QtQuick.Controls 2.1 (Qt 5.8) + \qmlproperty bool QtQuick.Controls::TextArea::hovered + \readonly + + This property holds whether the text area is hovered. + + \sa hoverEnabled +*/ +bool QQuickTextArea::isHovered() const +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(const QQuickTextArea); + return d->hovered; +#else + return false; +#endif +} + +void QQuickTextArea::setHovered(bool hovered) +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(QQuickTextArea); + if (hovered == d->hovered) + return; + + d->hovered = hovered; + emit hoveredChanged(); +#else + Q_UNUSED(hovered); +#endif +} + +/*! + \since QtQuick.Controls 2.1 (Qt 5.8) + \qmlproperty bool QtQuick.Controls::TextArea::hoverEnabled + + This property determines whether the text area accepts hover events. The default value is \c true. + + \sa hovered +*/ +bool QQuickTextArea::isHoverEnabled() const +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(const QQuickTextArea); + return d->hoverEnabled; +#else + return false; +#endif +} + +void QQuickTextArea::setHoverEnabled(bool enabled) +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(QQuickTextArea); + if (d->explicitHoverEnabled && enabled == d->hoverEnabled) + return; + + d->updateHoverEnabled(enabled, true); // explicit=true +#else + Q_UNUSED(enabled); +#endif +} + +void QQuickTextArea::resetHoverEnabled() +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(QQuickTextArea); + if (!d->explicitHoverEnabled) + return; + + d->explicitHoverEnabled = false; + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false +#endif +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::TextArea::implicitBackgroundWidth + \readonly + + This property holds the implicit background width. + + The value is equal to \c {background ? background.implicitWidth : 0}. + + \sa implicitBackgroundHeight +*/ +qreal QQuickTextArea::implicitBackgroundWidth() const +{ + Q_D(const QQuickTextArea); + if (!d->background) + return 0; + return d->background->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::TextArea::implicitBackgroundHeight + \readonly + + This property holds the implicit background height. + + The value is equal to \c {background ? background.implicitHeight : 0}. + + \sa implicitBackgroundWidth +*/ +qreal QQuickTextArea::implicitBackgroundHeight() const +{ + Q_D(const QQuickTextArea); + if (!d->background) + return 0; + return d->background->implicitHeight(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::TextArea::topInset + + This property holds the top inset for the background. + + \sa {Control Layout}, bottomInset +*/ +qreal QQuickTextArea::topInset() const +{ + Q_D(const QQuickTextArea); + return d->getTopInset(); +} + +void QQuickTextArea::setTopInset(qreal inset) +{ + Q_D(QQuickTextArea); + d->setTopInset(inset); +} + +void QQuickTextArea::resetTopInset() +{ + Q_D(QQuickTextArea); + d->setTopInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::TextArea::leftInset + + This property holds the left inset for the background. + + \sa {Control Layout}, rightInset +*/ +qreal QQuickTextArea::leftInset() const +{ + Q_D(const QQuickTextArea); + return d->getLeftInset(); +} + +void QQuickTextArea::setLeftInset(qreal inset) +{ + Q_D(QQuickTextArea); + d->setLeftInset(inset); +} + +void QQuickTextArea::resetLeftInset() +{ + Q_D(QQuickTextArea); + d->setLeftInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::TextArea::rightInset + + This property holds the right inset for the background. + + \sa {Control Layout}, leftInset +*/ +qreal QQuickTextArea::rightInset() const +{ + Q_D(const QQuickTextArea); + return d->getRightInset(); +} + +void QQuickTextArea::setRightInset(qreal inset) +{ + Q_D(QQuickTextArea); + d->setRightInset(inset); +} + +void QQuickTextArea::resetRightInset() +{ + Q_D(QQuickTextArea); + d->setRightInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::TextArea::bottomInset + + This property holds the bottom inset for the background. + + \sa {Control Layout}, topInset +*/ +qreal QQuickTextArea::bottomInset() const +{ + Q_D(const QQuickTextArea); + return d->getBottomInset(); +} + +void QQuickTextArea::setBottomInset(qreal inset) +{ + Q_D(QQuickTextArea); + d->setBottomInset(inset); +} + +void QQuickTextArea::resetBottomInset() +{ + Q_D(QQuickTextArea); + d->setBottomInset(0, true); +} + +void QQuickTextArea::classBegin() +{ + Q_D(QQuickTextArea); + QQuickTextEdit::classBegin(); + d->resolveFont(); +} + +void QQuickTextArea::componentComplete() +{ + Q_D(QQuickTextArea); + d->executeBackground(true); + QQuickTextEdit::componentComplete(); + d->resizeBackground(); +#if QT_CONFIG(quicktemplates2_hover) + if (!d->explicitHoverEnabled) + setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(d->parentItem)); +#endif +#if QT_CONFIG(accessibility) + if (QAccessible::isActive()) + d->accessibilityActiveChanged(true); +#endif +} + +void QQuickTextArea::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) +{ + Q_D(QQuickTextArea); + QQuickTextEdit::itemChange(change, value); + switch (change) { + case ItemEnabledHasChanged: + break; + case ItemSceneChange: + case ItemParentHasChanged: + if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) { + d->resolveFont(); +#if QT_CONFIG(quicktemplates2_hover) + if (!d->explicitHoverEnabled) + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false +#endif + if (change == ItemParentHasChanged) { + QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(value.item->parentItem()); + if (flickable) { + QQuickScrollView *scrollView = qobject_cast<QQuickScrollView *>(flickable->parentItem()); + if (scrollView) + d->attachFlickable(flickable); + } + } + } + break; + default: + break; + } +} + +void QQuickTextArea::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickTextArea); + QQuickTextEdit::geometryChange(newGeometry, oldGeometry); + d->resizeBackground(); +} + +void QQuickTextArea::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset) +{ + Q_D(QQuickTextArea); + Q_UNUSED(newInset); + Q_UNUSED(oldInset); + d->resizeBackground(); +} + +QSGNode *QQuickTextArea::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) +{ + Q_D(QQuickTextArea); + QQuickDefaultClipNode *clipNode = static_cast<QQuickDefaultClipNode *>(oldNode); + if (!clipNode) + clipNode = new QQuickDefaultClipNode(QRectF()); + + QQuickItem *clipper = this; + if (d->flickable) + clipper = d->flickable; + + const QRectF cr = clipper->clipRect().adjusted( + leftPadding(), topPadding(), + (!d->cursorItem && effectiveHAlign() == HAlignment::AlignRight ? 1 : 0) - rightPadding(), + -bottomPadding()); + + clipNode->setRect(!d->flickable ? cr : cr.translated(d->flickable->contentX(), d->flickable->contentY())); + clipNode->update(); + + QSGNode *textNode = QQuickTextEdit::updatePaintNode(clipNode->firstChild(), data); + if (!textNode->parent()) + clipNode->appendChildNode(textNode); + + if (d->cursorItem) { + QQuickDefaultClipNode *cursorNode = QQuickItemPrivate::get(d->cursorItem)->clipNode(); + if (cursorNode) + cursorNode->setClipRect(d->cursorItem->mapRectFromItem(clipper, cr)); + } + + return clipNode; +} + +void QQuickTextArea::focusInEvent(QFocusEvent *event) +{ + QQuickTextEdit::focusInEvent(event); + setFocusReason(event->reason()); +} + +void QQuickTextArea::focusOutEvent(QFocusEvent *event) +{ + QQuickTextEdit::focusOutEvent(event); + setFocusReason(event->reason()); +} + +#if QT_CONFIG(quicktemplates2_hover) +void QQuickTextArea::hoverEnterEvent(QHoverEvent *event) +{ + Q_D(QQuickTextArea); + QQuickTextEdit::hoverEnterEvent(event); + setHovered(d->hoverEnabled); + event->ignore(); +} + +void QQuickTextArea::hoverLeaveEvent(QHoverEvent *event) +{ + QQuickTextEdit::hoverLeaveEvent(event); + setHovered(false); + event->ignore(); +} +#endif + +void QQuickTextArea::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickTextArea); + d->pressHandler.mousePressEvent(event); + if (d->pressHandler.isActive()) { + if (d->pressHandler.delayedMousePressEvent) { + QQuickTextEdit::mousePressEvent(d->pressHandler.delayedMousePressEvent); + d->pressHandler.clearDelayedMouseEvent(); + } + // Calling the base class implementation will result in QQuickTextControl's + // press handler being called, which ignores events that aren't Qt::LeftButton. + const bool wasAccepted = event->isAccepted(); + QQuickTextEdit::mousePressEvent(event); + if (wasAccepted) + event->accept(); + } +} + +void QQuickTextArea::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QQuickTextArea); + d->pressHandler.mouseMoveEvent(event); + if (d->pressHandler.isActive()) { + if (d->pressHandler.delayedMousePressEvent) { + QQuickTextEdit::mousePressEvent(d->pressHandler.delayedMousePressEvent); + d->pressHandler.clearDelayedMouseEvent(); + } + QQuickTextEdit::mouseMoveEvent(event); + } +} + +void QQuickTextArea::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QQuickTextArea); + d->pressHandler.mouseReleaseEvent(event); + if (d->pressHandler.isActive()) { + if (d->pressHandler.delayedMousePressEvent) { + QQuickTextEdit::mousePressEvent(d->pressHandler.delayedMousePressEvent); + d->pressHandler.clearDelayedMouseEvent(); + } + QQuickTextEdit::mouseReleaseEvent(event); + } +} + +void QQuickTextArea::mouseDoubleClickEvent(QMouseEvent *event) +{ + Q_D(QQuickTextArea); + if (d->pressHandler.delayedMousePressEvent) { + QQuickTextEdit::mousePressEvent(d->pressHandler.delayedMousePressEvent); + d->pressHandler.clearDelayedMouseEvent(); + } + QQuickTextEdit::mouseDoubleClickEvent(event); +} + +void QQuickTextArea::timerEvent(QTimerEvent *event) +{ + Q_D(QQuickTextArea); + if (event->timerId() == d->pressHandler.timer.timerId()) + d->pressHandler.timerEvent(event); + else + QQuickTextEdit::timerEvent(event); +} + +class QQuickTextAreaAttachedPrivate : public QObjectPrivate +{ +public: + QQuickTextArea *control = nullptr; +}; + +QQuickTextAreaAttached::QQuickTextAreaAttached(QObject *parent) + : QObject(*(new QQuickTextAreaAttachedPrivate), parent) +{ +} + +/*! + \qmlattachedproperty TextArea QtQuick.Controls::TextArea::flickable + + This property attaches a text area to a \l Flickable. + + \sa ScrollBar, ScrollIndicator, {Scrollable TextArea} +*/ +QQuickTextArea *QQuickTextAreaAttached::flickable() const +{ + Q_D(const QQuickTextAreaAttached); + return d->control; +} + +void QQuickTextAreaAttached::setFlickable(QQuickTextArea *control) +{ + Q_D(QQuickTextAreaAttached); + QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(parent()); + if (!flickable) { + qmlWarning(parent()) << "TextArea must be attached to a Flickable"; + return; + } + + if (d->control == control) + return; + + if (d->control) + QQuickTextAreaPrivate::get(d->control)->detachFlickable(); + + d->control = control; + + if (control) + QQuickTextAreaPrivate::get(control)->attachFlickable(flickable); + + emit flickableChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qquicktextarea_p.cpp" diff --git a/src/quicktemplates2/qquicktextarea_p.h b/src/quicktemplates2/qquicktextarea_p.h new file mode 100644 index 00000000000..8ab62d4d781 --- /dev/null +++ b/src/quicktemplates2/qquicktextarea_p.h @@ -0,0 +1,223 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTEXTAREA_P_H +#define QQUICKTEXTAREA_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qpalette.h> +#include <QtQuick/private/qquicktextedit_p.h> +#include <QtQuick/private/qquickevents_p_p.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickText; +class QQuickTextAreaPrivate; +class QQuickTextAreaAttached; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextArea : public QQuickTextEdit +{ + Q_OBJECT + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) // override + Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged3 FINAL) + Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged3 FINAL) + Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) + Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText NOTIFY placeholderTextChanged FINAL) + Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) + // 2.1 (Qt 5.8) + Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged FINAL REVISION(2, 1)) + Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION(2, 1)) + // 2.5 (Qt 5.12) + Q_PROPERTY(QColor placeholderTextColor READ placeholderTextColor WRITE setPlaceholderTextColor NOTIFY placeholderTextColorChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitBackgroundWidth READ implicitBackgroundWidth NOTIFY implicitBackgroundWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitBackgroundHeight READ implicitBackgroundHeight NOTIFY implicitBackgroundHeightChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal topInset READ topInset WRITE setTopInset RESET resetTopInset NOTIFY topInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal leftInset READ leftInset WRITE setLeftInset RESET resetLeftInset NOTIFY leftInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal rightInset READ rightInset WRITE setRightInset RESET resetRightInset NOTIFY rightInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal bottomInset READ bottomInset WRITE setBottomInset RESET resetBottomInset NOTIFY bottomInsetChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DeferredPropertyNames", "background") + QML_NAMED_ELEMENT(TextArea) + QML_ATTACHED(QQuickTextAreaAttached) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickTextArea(QQuickItem *parent = nullptr); + ~QQuickTextArea(); + + static QQuickTextAreaAttached *qmlAttachedProperties(QObject *object); + + QFont font() const; + void setFont(const QFont &font); + + QQuickItem *background() const; + void setBackground(QQuickItem *background); + + QString placeholderText() const; + void setPlaceholderText(const QString &text); + + Qt::FocusReason focusReason() const; + void setFocusReason(Qt::FocusReason reason); + + bool contains(const QPointF &point) const override; + + // 2.1 (Qt 5.8) + bool isHovered() const; + void setHovered(bool hovered); + + bool isHoverEnabled() const; + void setHoverEnabled(bool enabled); + void resetHoverEnabled(); + + // 2.5 (Qt 5.12) + QColor placeholderTextColor() const; + void setPlaceholderTextColor(const QColor &color); + + qreal implicitBackgroundWidth() const; + qreal implicitBackgroundHeight() const; + + qreal topInset() const; + void setTopInset(qreal inset); + void resetTopInset(); + + qreal leftInset() const; + void setLeftInset(qreal inset); + void resetLeftInset(); + + qreal rightInset() const; + void setRightInset(qreal inset); + void resetRightInset(); + + qreal bottomInset() const; + void setBottomInset(qreal inset); + void resetBottomInset(); + +Q_SIGNALS: + void fontChanged(); + void implicitWidthChanged3(); + void implicitHeightChanged3(); + void backgroundChanged(); + void placeholderTextChanged(); + void focusReasonChanged(); + void pressAndHold(QQuickMouseEvent *event); + // 2.1 (Qt 5.8) + Q_REVISION(2, 1) void pressed(QQuickMouseEvent *event); + Q_REVISION(2, 1) void released(QQuickMouseEvent *event); + Q_REVISION(2, 1) void hoveredChanged(); + Q_REVISION(2, 1) void hoverEnabledChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void placeholderTextColorChanged(); + Q_REVISION(2, 5) void implicitBackgroundWidthChanged(); + Q_REVISION(2, 5) void implicitBackgroundHeightChanged(); + Q_REVISION(2, 5) void topInsetChanged(); + Q_REVISION(2, 5) void leftInsetChanged(); + Q_REVISION(2, 5) void rightInsetChanged(); + Q_REVISION(2, 5) void bottomInsetChanged(); + +protected: + friend struct QQuickPressHandler; + + void classBegin() override; + void componentComplete() override; + + void itemChange(ItemChange change, const ItemChangeData &value) override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + virtual void insetChange(const QMarginsF &newInset, const QMarginsF &oldInset); + + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) override; + + void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; +#if QT_CONFIG(quicktemplates2_hover) + void hoverEnterEvent(QHoverEvent *event) override; + void hoverLeaveEvent(QHoverEvent *event) override; +#endif + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void mouseDoubleClickEvent(QMouseEvent *event) override; + void timerEvent(QTimerEvent *event) override; + +private: + Q_DISABLE_COPY(QQuickTextArea) + Q_DECLARE_PRIVATE(QQuickTextArea) +}; + +class QQuickTextAreaAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextAreaAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickTextArea *flickable READ flickable WRITE setFlickable NOTIFY flickableChanged FINAL) + +public: + explicit QQuickTextAreaAttached(QObject *parent); + + QQuickTextArea *flickable() const; + void setFlickable(QQuickTextArea *control); + +Q_SIGNALS: + void flickableChanged(); + +private: + Q_DISABLE_COPY(QQuickTextAreaAttached) + Q_DECLARE_PRIVATE(QQuickTextAreaAttached) +}; + +struct QQuickTextEditForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickTextEdit) + QML_ADDED_IN_VERSION(2, 3) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickTextArea) +QML_DECLARE_TYPEINFO(QQuickTextArea, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKTEXTAREA_P_H diff --git a/src/quicktemplates2/qquicktextarea_p_p.h b/src/quicktemplates2/qquicktextarea_p_p.h new file mode 100644 index 00000000000..2ed2b44f319 --- /dev/null +++ b/src/quicktemplates2/qquicktextarea_p_p.h @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTEXTAREA_P_P_H +#define QQUICKTEXTAREA_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/private/qlazilyallocated_p.h> +#include <QtQuick/private/qquicktextedit_p_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQuickTemplates2/private/qquickpresshandler_p_p.h> +#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +#include <QtQuickTemplates2/private/qquicktextarea_p.h> + +#if QT_CONFIG(accessibility) +#include <QtGui/qaccessible.h> +#endif + +QT_BEGIN_NAMESPACE + +class QQuickFlickable; + +class QQuickTextAreaPrivate : public QQuickTextEditPrivate, public QQuickItemChangeListener +#if QT_CONFIG(accessibility) + , public QAccessible::ActivationObserver +#endif +{ + Q_DECLARE_PUBLIC(QQuickTextArea) + +public: + QQuickTextAreaPrivate(); + ~QQuickTextAreaPrivate(); + + static QQuickTextAreaPrivate *get(QQuickTextArea *item) + { + return static_cast<QQuickTextAreaPrivate *>(QObjectPrivate::get(item)); + } + + inline QMarginsF getInset() const { return QMarginsF(getLeftInset(), getTopInset(), getRightInset(), getBottomInset()); } + inline qreal getTopInset() const { return extra.isAllocated() ? extra->topInset : 0; } + inline qreal getLeftInset() const { return extra.isAllocated() ? extra->leftInset : 0; } + inline qreal getRightInset() const { return extra.isAllocated() ? extra->rightInset : 0; } + inline qreal getBottomInset() const { return extra.isAllocated() ? extra->bottomInset : 0; } + + void setTopInset(qreal value, bool reset = false); + void setLeftInset(qreal value, bool reset = false); + void setRightInset(qreal value, bool reset = false); + void setBottomInset(qreal value, bool reset = false); + + void resizeBackground(); + + void resolveFont(); + void inheritFont(const QFont &font); + void updateFont(const QFont &font); + inline void setFont_helper(const QFont &font) { + if (sourceFont.resolveMask() == font.resolveMask() && sourceFont == font) + return; + updateFont(font); + } + +#if QT_CONFIG(quicktemplates2_hover) + void updateHoverEnabled(bool h, bool e); +#endif + + void attachFlickable(QQuickFlickable *flickable); + void detachFlickable(); + void ensureCursorVisible(); + void resizeFlickableControl(); + void resizeFlickableContent(); + + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + + qreal getImplicitWidth() const override; + qreal getImplicitHeight() const override; + + void implicitWidthChanged() override; + void implicitHeightChanged() override; + + void readOnlyChanged(bool isReadOnly); + +#if QT_CONFIG(accessibility) + void accessibilityActiveChanged(bool active) override; + QAccessible::Role accessibleRole() const override; +#endif + + void cancelBackground(); + void executeBackground(bool complete = false); + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + void itemDestroyed(QQuickItem *item) override; + + QPalette defaultPalette() const override; + +#if QT_CONFIG(quicktemplates2_hover) + bool hovered = false; + bool explicitHoverEnabled = false; +#endif + + struct ExtraData { + bool hasTopInset = false; + bool hasLeftInset = false; + bool hasRightInset = false; + bool hasBottomInset = false; + bool hasBackgroundWidth = false; + bool hasBackgroundHeight = false; + qreal topInset = 0; + qreal leftInset = 0; + qreal rightInset = 0; + qreal bottomInset = 0; + QFont requestedFont; + QPalette requestedPalette; + }; + QLazilyAllocated<ExtraData> extra; + + bool resizingBackground = false; + QPalette resolvedPalette; + QQuickDeferredPointer<QQuickItem> background; + QString placeholder; + QColor placeholderColor; + Qt::FocusReason focusReason = Qt::OtherFocusReason; + QQuickPressHandler pressHandler; + QQuickFlickable *flickable = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKTEXTAREA_P_P_H diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp new file mode 100644 index 00000000000..034c06dec8d --- /dev/null +++ b/src/quicktemplates2/qquicktextfield.cpp @@ -0,0 +1,953 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktextfield_p.h" +#include "qquicktextfield_p_p.h" +#include "qquickcontrol_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickdeferredexecute_p_p.h" + +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquicktextinput_p.h> +#include <QtQuick/private/qquickclipnode_p.h> + +#if QT_CONFIG(accessibility) +#include <QtQuick/private/qquickaccessibleattached_p.h> +#endif + +QT_BEGIN_NAMESPACE + +/*! + \qmltype TextField + \inherits TextInput +//! \instantiates QQuickTextField + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-input + \brief Single-line text input field. + + TextField is a single line text editor. TextField extends TextInput with + a \l {placeholderText}{placeholder text} functionality, and adds decoration. + + \table + \row \li \image qtquickcontrols2-textfield-normal.png + \li A text field in its normal state. + \row \li \image qtquickcontrols2-textfield-focused.png + \li A text field that has active focus. + \row \li \image qtquickcontrols2-textfield-disabled.png + \li A text field that is disabled. + \endtable + + \code + TextField { + placeholderText: qsTr("Enter name") + } + \endcode + + \sa TextArea, {Customizing TextField}, {Input Controls} +*/ + +/*! + \qmlsignal QtQuick.Controls::TextField::pressAndHold(MouseEvent event) + + This signal is emitted when there is a long press (the delay depends on the platform plugin). + The \a event parameter provides information about the press, including the x and y + coordinates of the press, and which button is pressed. + + \sa pressed, released +*/ + +/*! + \qmlsignal QtQuick.Controls::TextField::pressed(MouseEvent event) + \since QtQuick.Controls 2.1 (Qt 5.8) + + This signal is emitted when the text field is pressed by the user. + The \a event parameter provides information about the press, + including the x and y coordinates of the press, and which button + is pressed. + + \sa released, pressAndHold +*/ + +/*! + \qmlsignal QtQuick.Controls::TextField::released(MouseEvent event) + \since QtQuick.Controls 2.1 (Qt 5.8) + + This signal is emitted when the text field is released by the user. + The \a event parameter provides information about the release, + including the x and y coordinates of the press, and which button + is pressed. + + \sa pressed, pressAndHold +*/ + +QQuickTextFieldPrivate::QQuickTextFieldPrivate() +{ +#if QT_CONFIG(accessibility) + QAccessible::installActivationObserver(this); +#endif +} + +QQuickTextFieldPrivate::~QQuickTextFieldPrivate() +{ +#if QT_CONFIG(accessibility) + QAccessible::removeActivationObserver(this); +#endif +} + +void QQuickTextFieldPrivate::setTopInset(qreal value, bool reset) +{ + Q_Q(QQuickTextField); + const QMarginsF oldInset = getInset(); + extra.value().topInset = value; + extra.value().hasTopInset = !reset; + if (!qFuzzyCompare(oldInset.top(), value)) { + emit q->topInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickTextFieldPrivate::setLeftInset(qreal value, bool reset) +{ + Q_Q(QQuickTextField); + const QMarginsF oldInset = getInset(); + extra.value().leftInset = value; + extra.value().hasLeftInset = !reset; + if (!qFuzzyCompare(oldInset.left(), value)) { + emit q->leftInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickTextFieldPrivate::setRightInset(qreal value, bool reset) +{ + Q_Q(QQuickTextField); + const QMarginsF oldInset = getInset(); + extra.value().rightInset = value; + extra.value().hasRightInset = !reset; + if (!qFuzzyCompare(oldInset.right(), value)) { + emit q->rightInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickTextFieldPrivate::setBottomInset(qreal value, bool reset) +{ + Q_Q(QQuickTextField); + const QMarginsF oldInset = getInset(); + extra.value().bottomInset = value; + extra.value().hasBottomInset = !reset; + if (!qFuzzyCompare(oldInset.bottom(), value)) { + emit q->bottomInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickTextFieldPrivate::resizeBackground() +{ + if (!background) + return; + + resizingBackground = true; + + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + if (((!p->widthValid() || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(background->x())) + || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) { + const bool wasWidthValid = p->widthValid(); + background->setX(getLeftInset()); + background->setWidth(width - getLeftInset() - getRightInset()); + // If the user hadn't previously set the width, that shouldn't change when we set it for them. + if (!wasWidthValid) + p->widthValidFlag = false; + } + if (((!p->heightValid() || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(background->y())) + || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) { + const bool wasHeightValid = p->heightValid(); + background->setY(getTopInset()); + background->setHeight(height - getTopInset() - getBottomInset()); + if (!wasHeightValid) + p->heightValidFlag = false; + } + + resizingBackground = false; +} + +/*! + \internal + + Determine which font is implicitly imposed on this control by its ancestors + and QGuiApplication::font, resolve this against its own font (attributes from + the implicit font are copied over). Then propagate this font to this + control's children. +*/ +void QQuickTextFieldPrivate::resolveFont() +{ + Q_Q(QQuickTextField); + inheritFont(QQuickControlPrivate::parentFont(q)); +} + +void QQuickTextFieldPrivate::inheritFont(const QFont &font) +{ + QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font; + parentFont.setResolveMask(extra.isAllocated() ? extra->requestedFont.resolveMask() | font.resolveMask() : font.resolveMask()); + + const QFont defaultFont = QQuickTheme::font(QQuickTheme::TextField); + QFont resolvedFont = parentFont.resolve(defaultFont); + + setFont_helper(resolvedFont); +} + +/*! + \internal + + Assign \a font to this control, and propagate it to all children. +*/ +void QQuickTextFieldPrivate::updateFont(const QFont &font) +{ + Q_Q(QQuickTextField); + QFont oldFont = sourceFont; + q->QQuickTextInput::setFont(font); + + QQuickControlPrivate::updateFontRecur(q, font); + + if (oldFont != font) + emit q->fontChanged(); +} + +#if QT_CONFIG(quicktemplates2_hover) +void QQuickTextFieldPrivate::updateHoverEnabled(bool enabled, bool xplicit) +{ + Q_Q(QQuickTextField); + if (!xplicit && explicitHoverEnabled) + return; + + bool wasEnabled = q->isHoverEnabled(); + explicitHoverEnabled = xplicit; + if (wasEnabled != enabled) { + q->setAcceptHoverEvents(enabled); + QQuickControlPrivate::updateHoverEnabledRecur(q, enabled); + emit q->hoverEnabledChanged(); + } +} +#endif + +qreal QQuickTextFieldPrivate::getImplicitWidth() const +{ + return QQuickItemPrivate::getImplicitWidth(); +} + +qreal QQuickTextFieldPrivate::getImplicitHeight() const +{ + return QQuickItemPrivate::getImplicitHeight(); +} + +void QQuickTextFieldPrivate::implicitWidthChanged() +{ + Q_Q(QQuickTextField); + QQuickItemPrivate::implicitWidthChanged(); + emit q->implicitWidthChanged3(); +} + +void QQuickTextFieldPrivate::implicitHeightChanged() +{ + Q_Q(QQuickTextField); + QQuickItemPrivate::implicitHeightChanged(); + emit q->implicitHeightChanged3(); +} + +void QQuickTextFieldPrivate::readOnlyChanged(bool isReadOnly) +{ + Q_UNUSED(isReadOnly); +#if QT_CONFIG(accessibility) + if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(q_func())) + accessibleAttached->set_readOnly(isReadOnly); +#endif +#if QT_CONFIG(cursor) + q_func()->setCursor(isReadOnly && !selectByMouse ? Qt::ArrowCursor : Qt::IBeamCursor); +#endif +} + +void QQuickTextFieldPrivate::echoModeChanged(QQuickTextField::EchoMode echoMode) +{ +#if QT_CONFIG(accessibility) + if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(q_func())) + accessibleAttached->set_passwordEdit((echoMode == QQuickTextField::Password || echoMode == QQuickTextField::PasswordEchoOnEdit) ? true : false); +#else + Q_UNUSED(echoMode); +#endif +} + +#if QT_CONFIG(accessibility) +void QQuickTextFieldPrivate::accessibilityActiveChanged(bool active) +{ + if (!active) + return; + + Q_Q(QQuickTextField); + QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, true)); + Q_ASSERT(accessibleAttached); + accessibleAttached->setRole(effectiveAccessibleRole()); + accessibleAttached->set_readOnly(m_readOnly); + accessibleAttached->set_passwordEdit((m_echoMode == QQuickTextField::Password || m_echoMode == QQuickTextField::PasswordEchoOnEdit) ? true : false); + accessibleAttached->setDescription(placeholder); +} + +QAccessible::Role QQuickTextFieldPrivate::accessibleRole() const +{ + return QAccessible::EditableText; +} +#endif + +static inline QString backgroundName() { return QStringLiteral("background"); } + +void QQuickTextFieldPrivate::cancelBackground() +{ + Q_Q(QQuickTextField); + quickCancelDeferred(q, backgroundName()); +} + +void QQuickTextFieldPrivate::executeBackground(bool complete) +{ + Q_Q(QQuickTextField); + if (background.wasExecuted()) + return; + + if (!background || complete) + quickBeginDeferred(q, backgroundName(), background); + if (complete) + quickCompleteDeferred(q, backgroundName(), background); +} + +void QQuickTextFieldPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) +{ + Q_UNUSED(diff); + if (resizingBackground || item != background || !change.sizeChange()) + return; + + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + // QTBUG-71875: only allocate the extra data if we have to. + // resizeBackground() relies on the value of extra.isAllocated() + // as part of its checks to see whether it should resize the background or not. + if (p->widthValid() || extra.isAllocated()) + extra.value().hasBackgroundWidth = p->widthValid(); + if (p->heightValid() || extra.isAllocated()) + extra.value().hasBackgroundHeight = p->heightValid(); + resizeBackground(); +} + +void QQuickTextFieldPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickTextField); + if (item == background) + emit q->implicitBackgroundWidthChanged(); +} + +void QQuickTextFieldPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickTextField); + if (item == background) + emit q->implicitBackgroundHeightChanged(); +} + +void QQuickTextFieldPrivate::itemDestroyed(QQuickItem *item) +{ + Q_Q(QQuickTextField); + if (item == background) { + background = nullptr; + emit q->implicitBackgroundWidthChanged(); + emit q->implicitBackgroundHeightChanged(); + } +} + +QPalette QQuickTextFieldPrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::TextField); +} + +QQuickTextField::QQuickTextField(QQuickItem *parent) + : QQuickTextInput(*(new QQuickTextFieldPrivate), parent) +{ + Q_D(QQuickTextField); + d->pressHandler.control = this; + d->setImplicitResizeEnabled(false); + setAcceptedMouseButtons(Qt::AllButtons); + setActiveFocusOnTab(true); +#if QT_CONFIG(cursor) + setCursor(Qt::IBeamCursor); +#endif + QObjectPrivate::connect(this, &QQuickTextInput::readOnlyChanged, d, &QQuickTextFieldPrivate::readOnlyChanged); + QObjectPrivate::connect(this, &QQuickTextInput::echoModeChanged, d, &QQuickTextFieldPrivate::echoModeChanged); +} + +QQuickTextField::~QQuickTextField() +{ + Q_D(QQuickTextField); + QQuickControlPrivate::removeImplicitSizeListener(d->background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); +} + +QFont QQuickTextField::font() const +{ + return QQuickTextInput::font(); +} + +void QQuickTextField::setFont(const QFont &font) +{ + Q_D(QQuickTextField); + if (d->extra.value().requestedFont.resolveMask() == font.resolveMask() && d->extra.value().requestedFont == font) + return; + + d->extra.value().requestedFont = font; + d->resolveFont(); +} + +/*! + \qmlproperty Item QtQuick.Controls::TextField::background + + This property holds the background item. + + \input qquickcontrol-background.qdocinc notes + + \sa {Customizing TextField} +*/ +QQuickItem *QQuickTextField::background() const +{ + QQuickTextFieldPrivate *d = const_cast<QQuickTextFieldPrivate *>(d_func()); + if (!d->background) + d->executeBackground(); + return d->background; +} + +void QQuickTextField::setBackground(QQuickItem *background) +{ + Q_D(QQuickTextField); + if (d->background == background) + return; + + if (!d->background.isExecuting()) + d->cancelBackground(); + + const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth(); + const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight(); + + if (d->extra.isAllocated()) { + d->extra.value().hasBackgroundWidth = false; + d->extra.value().hasBackgroundHeight = false; + } + + QQuickControlPrivate::removeImplicitSizeListener(d->background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); + QQuickControlPrivate::hideOldItem(d->background); + d->background = background; + + if (background) { + background->setParentItem(this); + if (qFuzzyIsNull(background->z())) + background->setZ(-1); + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + if (p->widthValid() || p->heightValid()) { + d->extra.value().hasBackgroundWidth = p->widthValid(); + d->extra.value().hasBackgroundHeight = p->heightValid(); + } + if (isComponentComplete()) + d->resizeBackground(); + QQuickControlPrivate::addImplicitSizeListener(background, d, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); + } + + if (!qFuzzyCompare(oldImplicitBackgroundWidth, implicitBackgroundWidth())) + emit implicitBackgroundWidthChanged(); + if (!qFuzzyCompare(oldImplicitBackgroundHeight, implicitBackgroundHeight())) + emit implicitBackgroundHeightChanged(); + if (!d->background.isExecuting()) + emit backgroundChanged(); +} + +/*! + \qmlproperty string QtQuick.Controls::TextField::placeholderText + + This property holds the hint that is displayed in the TextField before the user + enters text. +*/ +QString QQuickTextField::placeholderText() const +{ + Q_D(const QQuickTextField); + return d->placeholder; +} + +void QQuickTextField::setPlaceholderText(const QString &text) +{ + Q_D(QQuickTextField); + if (d->placeholder == text) + return; + + d->placeholder = text; +#if QT_CONFIG(accessibility) + if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(this)) + accessibleAttached->setDescription(text); +#endif + emit placeholderTextChanged(); +} + +/*! + \qmlproperty color QtQuick.Controls::TextField::placeholderTextColor + \since QtQuick.Controls 2.5 (Qt 5.12) + + This property holds the color of placeholderText. + + \sa placeholderText +*/ +QColor QQuickTextField::placeholderTextColor() const +{ + Q_D(const QQuickTextField); + return d->placeholderColor; +} + +void QQuickTextField::setPlaceholderTextColor(const QColor &color) +{ + Q_D(QQuickTextField); + if (d->placeholderColor == color) + return; + + d->placeholderColor = color; + emit placeholderTextColorChanged(); +} + +/*! + \qmlproperty enumeration QtQuick.Controls::TextField::focusReason + + \include qquickcontrol-focusreason.qdocinc +*/ +Qt::FocusReason QQuickTextField::focusReason() const +{ + Q_D(const QQuickTextField); + return d->focusReason; +} + +void QQuickTextField::setFocusReason(Qt::FocusReason reason) +{ + Q_D(QQuickTextField); + if (d->focusReason == reason) + return; + + d->focusReason = reason; + emit focusReasonChanged(); +} + +/*! + \since QtQuick.Controls 2.1 (Qt 5.8) + \qmlproperty bool QtQuick.Controls::TextField::hovered + \readonly + + This property holds whether the text field is hovered. + + \sa hoverEnabled +*/ +bool QQuickTextField::isHovered() const +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(const QQuickTextField); + return d->hovered; +#else + return false; +#endif +} + +void QQuickTextField::setHovered(bool hovered) +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(QQuickTextField); + if (hovered == d->hovered) + return; + + d->hovered = hovered; + emit hoveredChanged(); +#else + Q_UNUSED(hovered); +#endif +} + +/*! + \since QtQuick.Controls 2.1 (Qt 5.8) + \qmlproperty bool QtQuick.Controls::TextField::hoverEnabled + + This property determines whether the text field accepts hover events. The default value is \c false. + + \sa hovered +*/ +bool QQuickTextField::isHoverEnabled() const +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(const QQuickTextField); + return d->hoverEnabled; +#else + return false; +#endif +} + +void QQuickTextField::setHoverEnabled(bool enabled) +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(QQuickTextField); + if (d->explicitHoverEnabled && enabled == d->hoverEnabled) + return; + + d->updateHoverEnabled(enabled, true); // explicit=true +#else + Q_UNUSED(enabled); +#endif +} + +void QQuickTextField::resetHoverEnabled() +{ +#if QT_CONFIG(quicktemplates2_hover) + Q_D(QQuickTextField); + if (!d->explicitHoverEnabled) + return; + + d->explicitHoverEnabled = false; + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false +#endif +} + +void QQuickTextField::classBegin() +{ + Q_D(QQuickTextField); + QQuickTextInput::classBegin(); + d->resolveFont(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::TextField::implicitBackgroundWidth + \readonly + + This property holds the implicit background width. + + The value is equal to \c {background ? background.implicitWidth : 0}. + + \sa implicitBackgroundHeight +*/ +qreal QQuickTextField::implicitBackgroundWidth() const +{ + Q_D(const QQuickTextField); + if (!d->background) + return 0; + return d->background->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::TextField::implicitBackgroundHeight + \readonly + + This property holds the implicit background height. + + The value is equal to \c {background ? background.implicitHeight : 0}. + + \sa implicitBackgroundWidth +*/ +qreal QQuickTextField::implicitBackgroundHeight() const +{ + Q_D(const QQuickTextField); + if (!d->background) + return 0; + return d->background->implicitHeight(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::TextField::topInset + + This property holds the top inset for the background. + + \sa {Control Layout}, bottomInset +*/ +qreal QQuickTextField::topInset() const +{ + Q_D(const QQuickTextField); + return d->getTopInset(); +} + +void QQuickTextField::setTopInset(qreal inset) +{ + Q_D(QQuickTextField); + d->setTopInset(inset); +} + +void QQuickTextField::resetTopInset() +{ + Q_D(QQuickTextField); + d->setTopInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::TextField::leftInset + + This property holds the left inset for the background. + + \sa {Control Layout}, rightInset +*/ +qreal QQuickTextField::leftInset() const +{ + Q_D(const QQuickTextField); + return d->getLeftInset(); +} + +void QQuickTextField::setLeftInset(qreal inset) +{ + Q_D(QQuickTextField); + d->setLeftInset(inset); +} + +void QQuickTextField::resetLeftInset() +{ + Q_D(QQuickTextField); + d->setLeftInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::TextField::rightInset + + This property holds the right inset for the background. + + \sa {Control Layout}, leftInset +*/ +qreal QQuickTextField::rightInset() const +{ + Q_D(const QQuickTextField); + return d->getRightInset(); +} + +void QQuickTextField::setRightInset(qreal inset) +{ + Q_D(QQuickTextField); + d->setRightInset(inset); +} + +void QQuickTextField::resetRightInset() +{ + Q_D(QQuickTextField); + d->setRightInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::TextField::bottomInset + + This property holds the bottom inset for the background. + + \sa {Control Layout}, topInset +*/ +qreal QQuickTextField::bottomInset() const +{ + Q_D(const QQuickTextField); + return d->getBottomInset(); +} + +void QQuickTextField::setBottomInset(qreal inset) +{ + Q_D(QQuickTextField); + d->setBottomInset(inset); +} + +void QQuickTextField::resetBottomInset() +{ + Q_D(QQuickTextField); + d->setBottomInset(0, true); +} + +void QQuickTextField::componentComplete() +{ + Q_D(QQuickTextField); + d->executeBackground(true); + QQuickTextInput::componentComplete(); + d->resizeBackground(); +#if QT_CONFIG(quicktemplates2_hover) + if (!d->explicitHoverEnabled) + setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(d->parentItem)); +#endif +#if QT_CONFIG(accessibility) + if (QAccessible::isActive()) + d->accessibilityActiveChanged(true); +#endif +} + +void QQuickTextField::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) +{ + Q_D(QQuickTextField); + QQuickTextInput::itemChange(change, value); + switch (change) { + case ItemEnabledHasChanged: + break; + case ItemSceneChange: + case ItemParentHasChanged: + if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) { + d->resolveFont(); +#if QT_CONFIG(quicktemplates2_hover) + if (!d->explicitHoverEnabled) + d->updateHoverEnabled(QQuickControlPrivate::calcHoverEnabled(d->parentItem), false); // explicit=false +#endif + } + break; + default: + break; + } +} + +void QQuickTextField::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickTextField); + QQuickTextInput::geometryChange(newGeometry, oldGeometry); + d->resizeBackground(); +} + +void QQuickTextField::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset) +{ + Q_D(QQuickTextField); + Q_UNUSED(newInset); + Q_UNUSED(oldInset); + d->resizeBackground(); +} +QSGNode *QQuickTextField::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) +{ + QQuickDefaultClipNode *clipNode = static_cast<QQuickDefaultClipNode *>(oldNode); + if (!clipNode) + clipNode = new QQuickDefaultClipNode(QRectF()); + + clipNode->setRect(clipRect().adjusted(leftPadding(), topPadding(), -rightPadding(), -bottomPadding())); + clipNode->update(); + + QSGNode *textNode = QQuickTextInput::updatePaintNode(clipNode->firstChild(), data); + if (!textNode->parent()) + clipNode->appendChildNode(textNode); + + return clipNode; +} + +void QQuickTextField::focusInEvent(QFocusEvent *event) +{ + QQuickTextInput::focusInEvent(event); + setFocusReason(event->reason()); +} + +void QQuickTextField::focusOutEvent(QFocusEvent *event) +{ + QQuickTextInput::focusOutEvent(event); + setFocusReason(event->reason()); +} + +#if QT_CONFIG(quicktemplates2_hover) +void QQuickTextField::hoverEnterEvent(QHoverEvent *event) +{ + Q_D(QQuickTextField); + QQuickTextInput::hoverEnterEvent(event); + setHovered(d->hoverEnabled); + event->ignore(); +} + +void QQuickTextField::hoverLeaveEvent(QHoverEvent *event) +{ + QQuickTextInput::hoverLeaveEvent(event); + setHovered(false); + event->ignore(); +} +#endif + +void QQuickTextField::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickTextField); + d->pressHandler.mousePressEvent(event); + if (d->pressHandler.isActive()) { + if (d->pressHandler.delayedMousePressEvent) { + QQuickTextInput::mousePressEvent(d->pressHandler.delayedMousePressEvent); + d->pressHandler.clearDelayedMouseEvent(); + } + if (event->buttons() != Qt::RightButton) + QQuickTextInput::mousePressEvent(event); + } +} + +void QQuickTextField::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QQuickTextField); + d->pressHandler.mouseMoveEvent(event); + if (d->pressHandler.isActive()) { + if (d->pressHandler.delayedMousePressEvent) { + QQuickTextInput::mousePressEvent(d->pressHandler.delayedMousePressEvent); + d->pressHandler.clearDelayedMouseEvent(); + } + if (event->buttons() != Qt::RightButton) + QQuickTextInput::mouseMoveEvent(event); + } +} + +void QQuickTextField::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QQuickTextField); + d->pressHandler.mouseReleaseEvent(event); + if (d->pressHandler.isActive()) { + if (d->pressHandler.delayedMousePressEvent) { + QQuickTextInput::mousePressEvent(d->pressHandler.delayedMousePressEvent); + d->pressHandler.clearDelayedMouseEvent(); + } + if (event->buttons() != Qt::RightButton) + QQuickTextInput::mouseReleaseEvent(event); + } +} + +void QQuickTextField::mouseDoubleClickEvent(QMouseEvent *event) +{ + Q_D(QQuickTextField); + if (d->pressHandler.delayedMousePressEvent) { + QQuickTextInput::mousePressEvent(d->pressHandler.delayedMousePressEvent); + d->pressHandler.clearDelayedMouseEvent(); + } + if (event->buttons() != Qt::RightButton) + QQuickTextInput::mouseDoubleClickEvent(event); +} + +void QQuickTextField::timerEvent(QTimerEvent *event) +{ + Q_D(QQuickTextField); + if (event->timerId() == d->pressHandler.timer.timerId()) + d->pressHandler.timerEvent(event); + else + QQuickTextInput::timerEvent(event); +} + +QT_END_NAMESPACE + +#include "moc_qquicktextfield_p.cpp" diff --git a/src/quicktemplates2/qquicktextfield_p.h b/src/quicktemplates2/qquicktextfield_p.h new file mode 100644 index 00000000000..a1d433c0b2c --- /dev/null +++ b/src/quicktemplates2/qquicktextfield_p.h @@ -0,0 +1,194 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTEXTFIELD_P_H +#define QQUICKTEXTFIELD_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qpalette.h> +#include <QtQuick/private/qquicktextinput_p.h> +#include <QtQuick/private/qquickevents_p_p.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickTextFieldPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextField : public QQuickTextInput +{ + Q_OBJECT + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) // override + Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged3 FINAL) + Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged3 FINAL) + Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) + Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText NOTIFY placeholderTextChanged FINAL) + Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) + // 2.1 (Qt 5.8) + Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged FINAL REVISION(2, 1)) + Q_PROPERTY(bool hoverEnabled READ isHoverEnabled WRITE setHoverEnabled RESET resetHoverEnabled NOTIFY hoverEnabledChanged FINAL REVISION(2, 1)) + // 2.5 (Qt 5.12) + Q_PROPERTY(QColor placeholderTextColor READ placeholderTextColor WRITE setPlaceholderTextColor NOTIFY placeholderTextColorChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitBackgroundWidth READ implicitBackgroundWidth NOTIFY implicitBackgroundWidthChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal implicitBackgroundHeight READ implicitBackgroundHeight NOTIFY implicitBackgroundHeightChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal topInset READ topInset WRITE setTopInset RESET resetTopInset NOTIFY topInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal leftInset READ leftInset WRITE setLeftInset RESET resetLeftInset NOTIFY leftInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal rightInset READ rightInset WRITE setRightInset RESET resetRightInset NOTIFY rightInsetChanged FINAL REVISION(2, 5)) + Q_PROPERTY(qreal bottomInset READ bottomInset WRITE setBottomInset RESET resetBottomInset NOTIFY bottomInsetChanged FINAL REVISION(2, 5)) + Q_CLASSINFO("DeferredPropertyNames", "background") + QML_NAMED_ELEMENT(TextField) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickTextField(QQuickItem *parent = nullptr); + ~QQuickTextField(); + + QFont font() const; + void setFont(const QFont &font); + + QQuickItem *background() const; + void setBackground(QQuickItem *background); + + QString placeholderText() const; + void setPlaceholderText(const QString &text); + + Qt::FocusReason focusReason() const; + void setFocusReason(Qt::FocusReason reason); + + // 2.1 (Qt 5.8) + bool isHovered() const; + void setHovered(bool hovered); + + bool isHoverEnabled() const; + void setHoverEnabled(bool enabled); + void resetHoverEnabled(); + + // 2.5 (Qt 5.12) + QColor placeholderTextColor() const; + void setPlaceholderTextColor(const QColor &color); + + qreal implicitBackgroundWidth() const; + qreal implicitBackgroundHeight() const; + + qreal topInset() const; + void setTopInset(qreal inset); + void resetTopInset(); + + qreal leftInset() const; + void setLeftInset(qreal inset); + void resetLeftInset(); + + qreal rightInset() const; + void setRightInset(qreal inset); + void resetRightInset(); + + qreal bottomInset() const; + void setBottomInset(qreal inset); + void resetBottomInset(); + +Q_SIGNALS: + void fontChanged(); + void implicitWidthChanged3(); + void implicitHeightChanged3(); + void backgroundChanged(); + void placeholderTextChanged(); + void focusReasonChanged(); + void pressAndHold(QQuickMouseEvent *event); + // 2.1 (Qt 5.8) + Q_REVISION(2, 1) void pressed(QQuickMouseEvent *event); + Q_REVISION(2, 1) void released(QQuickMouseEvent *event); + Q_REVISION(2, 1) void hoveredChanged(); + Q_REVISION(2, 1) void hoverEnabledChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) void placeholderTextColorChanged(); + Q_REVISION(2, 5) void implicitBackgroundWidthChanged(); + Q_REVISION(2, 5) void implicitBackgroundHeightChanged(); + Q_REVISION(2, 5) void topInsetChanged(); + Q_REVISION(2, 5) void leftInsetChanged(); + Q_REVISION(2, 5) void rightInsetChanged(); + Q_REVISION(2, 5) void bottomInsetChanged(); + +protected: + friend struct QQuickPressHandler; + + void classBegin() override; + void componentComplete() override; + + void itemChange(ItemChange change, const ItemChangeData &value) override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + virtual void insetChange(const QMarginsF &newInset, const QMarginsF &oldInset); + + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) override; + + void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; +#if QT_CONFIG(quicktemplates2_hover) + void hoverEnterEvent(QHoverEvent *event) override; + void hoverLeaveEvent(QHoverEvent *event) override; +#endif + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void mouseDoubleClickEvent(QMouseEvent *event) override; + void timerEvent(QTimerEvent *event) override; + +private: + Q_DISABLE_COPY(QQuickTextField) + Q_DECLARE_PRIVATE(QQuickTextField) +}; + +struct QQuickTextFieldForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickTextInput) + QML_ADDED_IN_VERSION(2, 2) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickTextField) + +#endif // QQUICKTEXTFIELD_P_H diff --git a/src/quicktemplates2/qquicktextfield_p_p.h b/src/quicktemplates2/qquicktextfield_p_p.h new file mode 100644 index 00000000000..d81289726b5 --- /dev/null +++ b/src/quicktemplates2/qquicktextfield_p_p.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTEXTFIELD_P_P_H +#define QQUICKTEXTFIELD_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/private/qlazilyallocated_p.h> +#include <QtQuick/private/qquicktextinput_p_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQuickTemplates2/private/qquickpresshandler_p_p.h> +#include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +#include <QtQuickTemplates2/private/qquicktextfield_p.h> + +#if QT_CONFIG(accessibility) +#include <QtGui/qaccessible.h> +#endif + +QT_BEGIN_NAMESPACE + +class QQuickTextFieldPrivate : public QQuickTextInputPrivate, public QQuickItemChangeListener +#if QT_CONFIG(accessibility) + , public QAccessible::ActivationObserver +#endif +{ + Q_DECLARE_PUBLIC(QQuickTextField) + +public: + QQuickTextFieldPrivate(); + ~QQuickTextFieldPrivate(); + + static QQuickTextFieldPrivate *get(QQuickTextField *item) { + return static_cast<QQuickTextFieldPrivate *>(QObjectPrivate::get(item)); } + + inline QMarginsF getInset() const { return QMarginsF(getLeftInset(), getTopInset(), getRightInset(), getBottomInset()); } + inline qreal getTopInset() const { return extra.isAllocated() ? extra->topInset : 0; } + inline qreal getLeftInset() const { return extra.isAllocated() ? extra->leftInset : 0; } + inline qreal getRightInset() const { return extra.isAllocated() ? extra->rightInset : 0; } + inline qreal getBottomInset() const { return extra.isAllocated() ? extra->bottomInset : 0; } + + void setTopInset(qreal value, bool reset = false); + void setLeftInset(qreal value, bool reset = false); + void setRightInset(qreal value, bool reset = false); + void setBottomInset(qreal value, bool reset = false); + + void resizeBackground(); + + void resolveFont(); + void inheritFont(const QFont &font); + void updateFont(const QFont &font); + inline void setFont_helper(const QFont &font) { + if (sourceFont.resolveMask() == font.resolveMask() && sourceFont == font) + return; + updateFont(font); + } + +#if QT_CONFIG(quicktemplates2_hover) + void updateHoverEnabled(bool h, bool e); +#endif + + qreal getImplicitWidth() const override; + qreal getImplicitHeight() const override; + + void implicitWidthChanged() override; + void implicitHeightChanged() override; + + void readOnlyChanged(bool isReadOnly); + void echoModeChanged(QQuickTextField::EchoMode echoMode); + +#if QT_CONFIG(accessibility) + void accessibilityActiveChanged(bool active) override; + QAccessible::Role accessibleRole() const override; +#endif + + void cancelBackground(); + void executeBackground(bool complete = false); + + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + void itemDestroyed(QQuickItem *item) override; + + QPalette defaultPalette() const override; + +#if QT_CONFIG(quicktemplates2_hover) + bool hovered = false; + bool explicitHoverEnabled = false; +#endif + + struct ExtraData { + bool hasTopInset = false; + bool hasLeftInset = false; + bool hasRightInset = false; + bool hasBottomInset = false; + bool hasBackgroundWidth = false; + bool hasBackgroundHeight = false; + qreal topInset = 0; + qreal leftInset = 0; + qreal rightInset = 0; + qreal bottomInset = 0; + QFont requestedFont; + }; + QLazilyAllocated<ExtraData> extra; + + bool resizingBackground = false; + QQuickDeferredPointer<QQuickItem> background; + QString placeholder; + QColor placeholderColor; + Qt::FocusReason focusReason = Qt::OtherFocusReason; + QQuickPressHandler pressHandler; +}; + +QT_END_NAMESPACE + +#endif // QQUICKTEXTFIELD_P_P_H diff --git a/src/quicktemplates2/qquicktheme.cpp b/src/quicktemplates2/qquicktheme.cpp new file mode 100644 index 00000000000..b94b419845b --- /dev/null +++ b/src/quicktemplates2/qquicktheme.cpp @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktheme_p.h" +#include "qquicktheme_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> +#include <QtGui/private/qguiapplication_p.h> + +QT_BEGIN_NAMESPACE + +std::unique_ptr<QQuickTheme> QQuickThemePrivate::instance; + +static void cleanup_instance() +{ + QQuickThemePrivate::instance.reset(); +} + +static void install_instance_cleanuper() +{ + qAddPostRoutine(cleanup_instance); +} + +Q_COREAPP_STARTUP_FUNCTION(install_instance_cleanuper) + +static QPlatformTheme::Font platformFont(QQuickTheme::Scope scope) +{ + switch (scope) { + case QQuickTheme::Button: return QPlatformTheme::PushButtonFont; + case QQuickTheme::CheckBox: return QPlatformTheme::CheckBoxFont; + case QQuickTheme::ComboBox: return QPlatformTheme::ComboMenuItemFont; + case QQuickTheme::GroupBox: return QPlatformTheme::GroupBoxTitleFont; + case QQuickTheme::ItemView: return QPlatformTheme::ItemViewFont; + case QQuickTheme::Label: return QPlatformTheme::LabelFont; + case QQuickTheme::ListView: return QPlatformTheme::ListViewFont; + case QQuickTheme::Menu: return QPlatformTheme::MenuFont; + case QQuickTheme::MenuBar: return QPlatformTheme::MenuBarFont; + case QQuickTheme::RadioButton: return QPlatformTheme::RadioButtonFont; + case QQuickTheme::SpinBox: return QPlatformTheme::EditorFont; + case QQuickTheme::Switch: return QPlatformTheme::CheckBoxFont; + case QQuickTheme::TabBar: return QPlatformTheme::TabButtonFont; + case QQuickTheme::TextArea: return QPlatformTheme::EditorFont; + case QQuickTheme::TextField: return QPlatformTheme::EditorFont; + case QQuickTheme::ToolBar: return QPlatformTheme::ToolButtonFont; + case QQuickTheme::ToolTip: return QPlatformTheme::TipLabelFont; + case QQuickTheme::Tumbler: return QPlatformTheme::ItemViewFont; + default: return QPlatformTheme::SystemFont; + } +} + +static QPlatformTheme::Palette platformPalette(QQuickTheme::Scope scope) +{ + switch (scope) { + case QQuickTheme::Button: return QPlatformTheme::ButtonPalette; + case QQuickTheme::CheckBox: return QPlatformTheme::CheckBoxPalette; + case QQuickTheme::ComboBox: return QPlatformTheme::ComboBoxPalette; + case QQuickTheme::GroupBox: return QPlatformTheme::GroupBoxPalette; + case QQuickTheme::ItemView: return QPlatformTheme::ItemViewPalette; + case QQuickTheme::Label: return QPlatformTheme::LabelPalette; + case QQuickTheme::ListView: return QPlatformTheme::ItemViewPalette; + case QQuickTheme::Menu: return QPlatformTheme::MenuPalette; + case QQuickTheme::MenuBar: return QPlatformTheme::MenuBarPalette; + case QQuickTheme::RadioButton: return QPlatformTheme::RadioButtonPalette; + case QQuickTheme::SpinBox: return QPlatformTheme::TextLineEditPalette; + case QQuickTheme::Switch: return QPlatformTheme::CheckBoxPalette; + case QQuickTheme::TabBar: return QPlatformTheme::TabBarPalette; + case QQuickTheme::TextArea: return QPlatformTheme::TextEditPalette; + case QQuickTheme::TextField: return QPlatformTheme::TextLineEditPalette; + case QQuickTheme::ToolBar: return QPlatformTheme::ToolButtonPalette; + case QQuickTheme::ToolTip: return QPlatformTheme::ToolTipPalette; + case QQuickTheme::Tumbler: return QPlatformTheme::ItemViewPalette; + default: return QPlatformTheme::SystemPalette; + } +} + +QQuickTheme::QQuickTheme() + : d_ptr(new QQuickThemePrivate) +{ +} + +QQuickTheme::~QQuickTheme() +{ +} + +QQuickTheme *QQuickTheme::instance() +{ + return QQuickThemePrivate::instance.get(); +} + +QFont QQuickTheme::font(Scope scope) +{ + const QFont *font = nullptr; + if (QQuickTheme *theme = instance()) + font = QQuickThemePrivate::get(theme)->fonts[scope].data(); + else if (QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + font = theme->font(platformFont(scope)); + + if (font) { + QFont f = *font; + if (scope == System) + f.setResolveMask(0); + return f; + } + + if (scope != System) + return QQuickTheme::font(System); + + return QFont(); +} + +QPalette QQuickTheme::palette(Scope scope) +{ + const QPalette *palette = nullptr; + if (QQuickTheme *theme = instance()) + palette = QQuickThemePrivate::get(theme)->palettes[scope].data(); + else if (QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + palette = theme->palette(platformPalette(scope)); + + if (palette) { + QPalette f = *palette; + if (scope == System) + f.setResolveMask(0); + return f; + } + + if (scope != System) + return QQuickTheme::palette(System); + + return QPalette(); +} + +void QQuickTheme::setFont(Scope scope, const QFont &font) +{ + Q_D(QQuickTheme); + d->fonts[scope] = QSharedPointer<QFont>::create(d->defaultFont ? d->defaultFont->resolve(font) : font); +} + +void QQuickTheme::setPalette(Scope scope, const QPalette &palette) +{ + Q_D(QQuickTheme); + d->palettes[scope] = QSharedPointer<QPalette>::create(d->defaultPalette ? d->defaultPalette->resolve(palette) : palette); +} + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquicktheme_p.h b/src/quicktemplates2/qquicktheme_p.h new file mode 100644 index 00000000000..d51cc5b6582 --- /dev/null +++ b/src/quicktemplates2/qquicktheme_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTHEME_P_H +#define QQUICKTHEME_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> +#include <QtCore/qscopedpointer.h> +#include <QtGui/qfont.h> +#include <QtGui/qpalette.h> + +QT_BEGIN_NAMESPACE + +class QQuickThemePrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTheme +{ +public: + QQuickTheme(); + ~QQuickTheme(); + + static QQuickTheme *instance(); + + enum Scope { + System, + Button, + CheckBox, + ComboBox, + GroupBox, + ItemView, + Label, + ListView, + Menu, + MenuBar, + RadioButton, + SpinBox, + Switch, + TabBar, + TextArea, + TextField, + ToolBar, + ToolTip, + Tumbler + }; + + static QFont font(Scope scope); + static QPalette palette(Scope scope); + + void setFont(Scope scope, const QFont &font); + void setPalette(Scope scope, const QPalette &palette); + +private: + Q_DISABLE_COPY(QQuickTheme) + Q_DECLARE_PRIVATE(QQuickTheme) + QScopedPointer<QQuickThemePrivate> d_ptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKTHEME_P_H diff --git a/src/quicktemplates2/qquicktheme_p_p.h b/src/quicktemplates2/qquicktheme_p_p.h new file mode 100644 index 00000000000..b2c40eeb412 --- /dev/null +++ b/src/quicktemplates2/qquicktheme_p_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTHEME_P_P_H +#define QQUICKTHEME_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickThemePrivate +{ +public: + static QQuickThemePrivate *get(QQuickTheme *theme) + { + return theme->d_func(); + } + + static std::unique_ptr<QQuickTheme> instance; + + static const int NScopes = QQuickTheme::Tumbler + 1; + + QScopedPointer<const QFont> defaultFont; + QScopedPointer<const QPalette> defaultPalette; + QSharedPointer<QFont> fonts[NScopes]; + QSharedPointer<QPalette> palettes[NScopes]; +}; + +QT_END_NAMESPACE + +#endif // QQUICKTHEME_P_P_H diff --git a/src/quicktemplates2/qquicktoolbar.cpp b/src/quicktemplates2/qquicktoolbar.cpp new file mode 100644 index 00000000000..ea08d849301 --- /dev/null +++ b/src/quicktemplates2/qquicktoolbar.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktoolbar_p.h" +#include "qquickpane_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ToolBar + \inherits Pane +//! \instantiates QQuickToolBar + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-containers + \brief Container for context-sensitive controls. + + ToolBar is a container of application-wide and context sensitive + actions and controls, such as navigation buttons and search fields. + ToolBar is commonly used as a \l {ApplicationWindow::header}{header} + or a \l {ApplicationWindow::footer}{footer} of an \l ApplicationWindow. + + ToolBar does not provide a layout of its own, but requires you to + position its contents, for instance by creating a \l RowLayout. If only + a single item is used within the ToolBar, it will resize to fit the + implicit size of its contained item. This makes it particularly suitable + for use together with layouts. + + \image qtquickcontrols2-toolbar.png + + \code + ApplicationWindow { + visible:true + + header: ToolBar { + RowLayout { + anchors.fill: parent + ToolButton { + text: qsTr("‹") + onClicked: stack.pop() + } + Label { + text: "Title" + elide: Label.ElideRight + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + Layout.fillWidth: true + } + ToolButton { + text: qsTr("⋮") + onClicked: menu.open() + } + } + } + + StackView { + id: stack + anchors.fill: parent + } + } + \endcode + + \sa ApplicationWindow, ToolButton, {Customizing ToolBar}, {Container Controls} +*/ + +class QQuickToolBarPrivate : public QQuickPanePrivate +{ +public: + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::ToolBar); } + + QQuickToolBar::Position position = QQuickToolBar::Header; +}; + +QQuickToolBar::QQuickToolBar(QQuickItem *parent) + : QQuickPane(*(new QQuickToolBarPrivate), parent) +{ +} + +/*! + \qmlproperty enumeration QtQuick.Controls::ToolBar::position + + This property holds the position of the toolbar. + + \note If the toolbar is assigned as a header or footer of \l ApplicationWindow + or \l Page, the appropriate position is set automatically. + + Possible values: + \value ToolBar.Header The toolbar is at the top, as a window or page header. + \value ToolBar.Footer The toolbar is at the bottom, as a window or page footer. + + The default value is style-specific. + + \sa ApplicationWindow::header, ApplicationWindow::footer, Page::header, Page::footer +*/ +QQuickToolBar::Position QQuickToolBar::position() const +{ + Q_D(const QQuickToolBar); + return d->position; +} + +void QQuickToolBar::setPosition(Position position) +{ + Q_D(QQuickToolBar); + if (d->position == position) + return; + + d->position = position; + emit positionChanged(); +} + +QFont QQuickToolBar::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::ToolBar); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickToolBar::accessibleRole() const +{ + return QAccessible::ToolBar; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquicktoolbar_p.cpp" diff --git a/src/quicktemplates2/qquicktoolbar_p.h b/src/quicktemplates2/qquicktoolbar_p.h new file mode 100644 index 00000000000..cefdeaa14ad --- /dev/null +++ b/src/quicktemplates2/qquicktoolbar_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTOOLBAR_P_H +#define QQUICKTOOLBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickpane_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickToolBarPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickToolBar : public QQuickPane +{ + Q_OBJECT + Q_PROPERTY(Position position READ position WRITE setPosition NOTIFY positionChanged FINAL) + QML_NAMED_ELEMENT(ToolBar) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickToolBar(QQuickItem *parent = nullptr); + + enum Position { + Header, + Footer + }; + Q_ENUM(Position) + + Position position() const; + void setPosition(Position position); + +Q_SIGNALS: + void positionChanged(); + +protected: + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickToolBar) + Q_DECLARE_PRIVATE(QQuickToolBar) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickToolBar) + +#endif // QQUICKTOOLBAR_P_H diff --git a/src/quicktemplates2/qquicktoolbutton.cpp b/src/quicktemplates2/qquicktoolbutton.cpp new file mode 100644 index 00000000000..100cf06a097 --- /dev/null +++ b/src/quicktemplates2/qquicktoolbutton.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktoolbutton_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickbutton_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ToolButton + \inherits Button +//! \instantiates QQuickToolButton + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-buttons + \brief Button with a look suitable for a ToolBar. + + ToolButton is functionally similar to \l Button, but provides a look that + is more suitable within a \l ToolBar. + + \image qtquickcontrols2-toolbar.png + + \snippet qtquickcontrols2-toolbar.qml 1 + + ToolButton inherits its API from AbstractButton. For instance, you can set + \l {AbstractButton::text}{text}, display an \l {Icons in Qt Quick Controls}{icon}, + and react to \l {AbstractButton::clicked}{clicks} using the AbstractButton API. + + \sa ToolBar, {Customizing ToolButton}, {Button Controls} +*/ + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickToolPrivate : public QQuickButtonPrivate +{ + Q_DECLARE_PUBLIC(QQuickToolButton) + +public: + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::ToolBar); } +}; + +QQuickToolButton::QQuickToolButton(QQuickItem *parent) + : QQuickButton(*(new QQuickToolPrivate), parent) +{ +} + +QFont QQuickToolButton::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::ToolBar); +} + +QT_END_NAMESPACE + +#include "moc_qquicktoolbutton_p.cpp" diff --git a/src/quicktemplates2/qquicktoolbutton_p.h b/src/quicktemplates2/qquicktoolbutton_p.h new file mode 100644 index 00000000000..2db052f6405 --- /dev/null +++ b/src/quicktemplates2/qquicktoolbutton_p.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTOOLBUTTON_P_H +#define QQUICKTOOLBUTTON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickToolButtonPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickToolButton : public QQuickButton +{ + Q_OBJECT + QML_NAMED_ELEMENT(ToolButton) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickToolButton(QQuickItem *parent = nullptr); + +protected: + QFont defaultFont() const override; + +private: + Q_DECLARE_PRIVATE(QQuickToolButton) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickToolButton) + +#endif // QQUICKTOOLBUTTON_P_H diff --git a/src/quicktemplates2/qquicktoolseparator.cpp b/src/quicktemplates2/qquicktoolseparator.cpp new file mode 100644 index 00000000000..21d496434a6 --- /dev/null +++ b/src/quicktemplates2/qquicktoolseparator.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktoolseparator_p.h" + +#include "qquickcontrol_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ToolSeparator + \inherits Control +//! \instantiates QQuickToolSeparator + \inqmlmodule QtQuick.Controls + \since 5.8 + \ingroup qtquickcontrols2-separators + \brief Separates a group of items in a toolbar from adjacent items. + + ToolSeparator is used to visually distinguish between groups of items in a + toolbar by separating them with a line. It can be used in horizontal or + vertical toolbars by setting the \l orientation property to \c Qt.Vertical + or \c Qt.Horizontal, respectively. + + \image qtquickcontrols2-toolseparator.png + + \snippet qtquickcontrols2-toolseparator.qml 1 + + \sa {Customizing ToolSeparator}, {Separator Controls} +*/ + +class QQuickToolSeparatorPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickToolSeparator) + +public: + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::ToolBar); } + + Qt::Orientation orientation = Qt::Vertical; +}; + +QQuickToolSeparator::QQuickToolSeparator(QQuickItem *parent) + : QQuickControl(*(new QQuickToolSeparatorPrivate), parent) +{ +} + +/*! + \qmlproperty enumeration QtQuick.Controls::ToolSeparator::orientation + + This property holds the orientation of the tool separator. + + Possible values: + \value Qt.Horizontal A horizontal separator is used in a vertical toolbar. + \value Qt.Vertical A vertical separator is used in a horizontal toolbar. (default) +*/ +Qt::Orientation QQuickToolSeparator::orientation() const +{ + Q_D(const QQuickToolSeparator); + return d->orientation; +} + +void QQuickToolSeparator::setOrientation(Qt::Orientation orientation) +{ + Q_D(QQuickToolSeparator); + if (d->orientation == orientation) + return; + + d->orientation = orientation; + emit orientationChanged(); +} + +/*! + \readonly + \qmlproperty bool QtQuick.Controls::ToolSeparator::horizontal + + This property holds whether \l orientation is equal to \c Qt.Horizontal. + + It is useful for \l {Customizing ToolSeparator}{customizing ToolSeparator}. + + \sa orientation, vertical +*/ +bool QQuickToolSeparator::isHorizontal() const +{ + Q_D(const QQuickToolSeparator); + return d->orientation == Qt::Horizontal; +} + +/*! + \readonly + \qmlproperty bool QtQuick.Controls::ToolSeparator::vertical + + This property holds whether \l orientation is equal to \c Qt.Vertical. + + It is useful for \l {Customizing ToolSeparator}{customizing ToolSeparator}. + + \sa orientation, horizontal +*/ +bool QQuickToolSeparator::isVertical() const +{ + Q_D(const QQuickToolSeparator); + return d->orientation == Qt::Vertical; +} + +QFont QQuickToolSeparator::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::ToolBar); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickToolSeparator::accessibleRole() const +{ + return QAccessible::Separator; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquicktoolseparator_p.cpp" diff --git a/src/quicktemplates2/qquicktoolseparator_p.h b/src/quicktemplates2/qquicktoolseparator_p.h new file mode 100644 index 00000000000..e4692154d26 --- /dev/null +++ b/src/quicktemplates2/qquicktoolseparator_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTOOLSEPARATOR_P_H +#define QQUICKTOOLSEPARATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickToolSeparatorPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickToolSeparator : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL) + Q_PROPERTY(bool horizontal READ isHorizontal NOTIFY orientationChanged FINAL) + Q_PROPERTY(bool vertical READ isVertical NOTIFY orientationChanged FINAL) + QML_NAMED_ELEMENT(ToolSeparator) + QML_ADDED_IN_VERSION(2, 1) + +public: + explicit QQuickToolSeparator(QQuickItem *parent = nullptr); + + Qt::Orientation orientation() const; + void setOrientation(Qt::Orientation orientation); + + bool isHorizontal() const; + bool isVertical() const; + +Q_SIGNALS: + void orientationChanged(); + +protected: + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickToolSeparator) + Q_DECLARE_PRIVATE(QQuickToolSeparator) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickToolSeparator) + +#endif // QQUICKTOOLSEPARATOR_P_H diff --git a/src/quicktemplates2/qquicktooltip.cpp b/src/quicktemplates2/qquicktooltip.cpp new file mode 100644 index 00000000000..9d64360fd9e --- /dev/null +++ b/src/quicktemplates2/qquicktooltip.cpp @@ -0,0 +1,576 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktooltip_p.h" +#include "qquickpopup_p_p.h" +#include "qquickpopupitem_p_p.h" +#include "qquickcontrol_p_p.h" + +#include <QtCore/qbasictimer.h> +#include <QtQml/qqmlinfo.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQuick/qquickwindow.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ToolTip + \inherits Popup +//! \instantiates QQuickToolTip + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-popups + \brief Provides tool tips for any control. + + A tool tip is a short piece of text that informs the user of a control's + function. It is typically placed above or below the parent control. The + tip text can be any \l{Rich Text Processing}{rich text} formatted string. + + \image qtquickcontrols2-tooltip.png + + \section2 Attached Tool Tips + + The most straight-forward way to setup tool tips for controls is to + specify \l text and \l {visible}{visibility} via attached properties. + The following example illustrates this approach: + + \snippet qtquickcontrols2-tooltip.qml 1 + + Under normal circumstances, there is only one tool tip visible at a time. + In order to save resources, all items that use the ToolTip attached property + share the same visual tool tip label instance. Even though the visuals are + shared, \c text, \c timeout and \c delay are stored individually for each item + that uses the respective attached property. However, multiple items cannot + make the shared tool tip visible at the same time. The shared tool tip is only + shown for the last item that made it visible. The position of the shared tool + tip is determined by the framework. + + \include qquicktooltip.qdocinc customize-note + + \section2 Delay and Timeout + + Tool tips are typically transient in a sense that they are shown as a + result of a certain external event or user interaction, and they usually + hide after a certain timeout. It is possible to control the delay when + a tool tip is shown, and the timeout when it is hidden. This makes it + possible to implement varying strategies for showing and hiding tool tips. + + For example, on touch screens, it is a common pattern to show a tool tip + as a result of pressing and holding down a button. The following example + demonstrates how to delay showing a tool tip until the press-and-hold + interval is reached. In this example, the tool tip hides as soon as the + button is released. + + \snippet qtquickcontrols2-tooltip-pressandhold.qml 1 + + With pointer devices, however, it might be desired to show a tool tip as + a result of hovering a button for a while. The following example presents + how to show a tool tip after hovering a button for a second, and hide it + after a timeout of five seconds. + + \snippet qtquickcontrols2-tooltip-hover.qml 1 + + \section2 Custom Tool Tips + + Should one need more fine-grained control over the tool tip position, or + multiple simultaneous tool tip instances are needed, it is also possible + to create local tool tip instances. This way, it is possible to + \l {Customizing ToolTip}{customize} the tool tip, and the whole \l Popup + API is available. The following example presents a tool tip that presents + the value of a slider when the handle is dragged. + + \image qtquickcontrols2-tooltip-slider.png + + \snippet qtquickcontrols2-tooltip-slider.qml 1 + + \sa {Customizing ToolTip}, {Popup Controls}, + {QtQuick.Controls::Popup::closePolicy}{closePolicy} +*/ + +class QQuickToolTipPrivate : public QQuickPopupPrivate +{ + Q_DECLARE_PUBLIC(QQuickToolTip) + +public: + void startDelay(); + void stopDelay(); + + void startTimeout(); + void stopTimeout(); + + void opened() override; + + QPalette defaultPalette() const override { return QQuickTheme::palette(QQuickTheme::ToolTip); } + + int delay = 0; + int timeout = -1; + QString text; + QBasicTimer delayTimer; + QBasicTimer timeoutTimer; +}; + +void QQuickToolTipPrivate::startDelay() +{ + Q_Q(QQuickToolTip); + if (delay > 0) + delayTimer.start(delay, q); +} + +void QQuickToolTipPrivate::stopDelay() +{ + delayTimer.stop(); +} + +void QQuickToolTipPrivate::startTimeout() +{ + Q_Q(QQuickToolTip); + if (timeout > 0) + timeoutTimer.start(timeout, q); +} + +void QQuickToolTipPrivate::stopTimeout() +{ + timeoutTimer.stop(); +} + +void QQuickToolTipPrivate::opened() +{ + QQuickPopupPrivate::opened(); + startTimeout(); +} + +QQuickToolTip::QQuickToolTip(QQuickItem *parent) + : QQuickPopup(*(new QQuickToolTipPrivate), parent) +{ + Q_D(QQuickToolTip); + d->allowVerticalFlip = true; + d->allowHorizontalFlip = true; + d->popupItem->setHoverEnabled(false); // QTBUG-63644 +} + +/*! + \qmlproperty string QtQuick.Controls::ToolTip::text + + This property holds the text shown on the tool tip. +*/ +QString QQuickToolTip::text() const +{ + Q_D(const QQuickToolTip); + return d->text; +} + +void QQuickToolTip::setText(const QString &text) +{ + Q_D(QQuickToolTip); + if (d->text == text) + return; + + d->text = text; + maybeSetAccessibleName(text); + emit textChanged(); +} + +/*! + \qmlproperty int QtQuick.Controls::ToolTip::delay + + This property holds the delay (milliseconds) after which the tool tip is + shown. A tooltip with a negative delay is shown immediately. The default + value is \c 0. + + \sa {Delay and Timeout} +*/ +int QQuickToolTip::delay() const +{ + Q_D(const QQuickToolTip); + return d->delay; +} + +void QQuickToolTip::setDelay(int delay) +{ + Q_D(QQuickToolTip); + if (d->delay == delay) + return; + + d->delay = delay; + emit delayChanged(); +} + +/*! + \qmlproperty int QtQuick.Controls::ToolTip::timeout + + This property holds the timeout (milliseconds) after which the tool tip is + hidden. A tooltip with a negative timeout does not hide automatically. The + default value is \c -1. + + \sa {Delay and Timeout} +*/ +int QQuickToolTip::timeout() const +{ + Q_D(const QQuickToolTip); + return d->timeout; +} + +void QQuickToolTip::setTimeout(int timeout) +{ + Q_D(QQuickToolTip); + if (d->timeout == timeout) + return; + + d->timeout = timeout; + + if (timeout <= 0) + d->stopTimeout(); + else if (isOpened()) + d->startTimeout(); + + emit timeoutChanged(); +} + +void QQuickToolTip::setVisible(bool visible) +{ + Q_D(QQuickToolTip); + if (visible) { + if (!d->visible) { + // We are being made visible, and we weren't before. + if (d->delay > 0) { + d->startDelay(); + return; + } + } + } else { + d->stopDelay(); + } + QQuickPopup::setVisible(visible); +} + +QQuickToolTipAttached *QQuickToolTip::qmlAttachedProperties(QObject *object) +{ + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (!item) + qmlWarning(object) << "ToolTip must be attached to an Item"; + + return new QQuickToolTipAttached(object); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlmethod void QtQuick.Controls::ToolTip::show(string text, int timeout) + + This method shows the \a text as a tooltip, which times out in + \a timeout (milliseconds). +*/ +void QQuickToolTip::show(const QString &text, int ms) +{ + if (ms >= 0) + setTimeout(ms); + setText(text); + open(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlmethod void QtQuick.Controls::ToolTip::hide() + + This method hides the tooltip. +*/ +void QQuickToolTip::hide() +{ + close(); +} + +QFont QQuickToolTip::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::ToolTip); +} + +void QQuickToolTip::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + Q_D(QQuickToolTip); + QQuickPopup::itemChange(change, data); + if (change == QQuickItem::ItemVisibleHasChanged) { + if (!data.boolValue) + d->stopTimeout(); + + QQuickToolTipAttached *attached = qobject_cast<QQuickToolTipAttached *>(qmlAttachedPropertiesObject<QQuickToolTip>(d->parentItem, false)); + if (attached) + emit attached->visibleChanged(); + } +} + +void QQuickToolTip::timerEvent(QTimerEvent *event) +{ + Q_D(QQuickToolTip); + if (event->timerId() == d->timeoutTimer.timerId()) { + d->stopTimeout(); + QQuickPopup::setVisible(false); + return; + } + if (event->timerId() == d->delayTimer.timerId()) { + d->stopDelay(); + QQuickPopup::setVisible(true); + return; + } + QQuickPopup::timerEvent(event); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickToolTip::accessibleRole() const +{ + return QAccessible::ToolTip; +} + +void QQuickToolTip::accessibilityActiveChanged(bool active) +{ + Q_D(QQuickToolTip); + QQuickPopup::accessibilityActiveChanged(active); + + if (active) + maybeSetAccessibleName(d->text); +} +#endif + +class QQuickToolTipAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickToolTipAttached) + +public: + QQuickToolTip *instance(bool create) const; + + int delay = 0; + int timeout = -1; + QString text; +}; + +QQuickToolTip *QQuickToolTipAttachedPrivate::instance(bool create) const +{ + QQmlEngine *engine = qmlEngine(parent); + if (!engine) + return nullptr; + + static const char *name = "_q_QQuickToolTip"; + + QQuickToolTip *tip = engine->property(name).value<QQuickToolTip *>(); + if (!tip && create) { + // TODO: a cleaner way to create the instance? QQml(Meta)Type? + QQmlComponent component(engine); + component.setData("import QtQuick.Controls; ToolTip { }", QUrl()); + + QObject *object = component.create(); + if (object) + object->setParent(engine); + + tip = qobject_cast<QQuickToolTip *>(object); + if (!tip) + delete object; + else + engine->setProperty(name, QVariant::fromValue(object)); + } + return tip; +} + +QQuickToolTipAttached::QQuickToolTipAttached(QObject *parent) + : QObject(*(new QQuickToolTipAttachedPrivate), parent) +{ +} + +/*! + \qmlattachedproperty string QtQuick.Controls::ToolTip::text + + This attached property holds the text of the shared tool tip. + The property can be attached to any item. + + \sa {Attached Tool Tips} +*/ +QString QQuickToolTipAttached::text() const +{ + Q_D(const QQuickToolTipAttached); + return d->text; +} + +void QQuickToolTipAttached::setText(const QString &text) +{ + Q_D(QQuickToolTipAttached); + if (d->text == text) + return; + + d->text = text; + emit textChanged(); + + if (isVisible()) + d->instance(true)->setText(text); +} + +/*! + \qmlattachedproperty int QtQuick.Controls::ToolTip::delay + + This attached property holds the delay (milliseconds) of the shared tool tip. + The property can be attached to any item. + + \sa {Attached Tool Tips}, {Delay and Timeout} +*/ +int QQuickToolTipAttached::delay() const +{ + Q_D(const QQuickToolTipAttached); + return d->delay; +} + +void QQuickToolTipAttached::setDelay(int delay) +{ + Q_D(QQuickToolTipAttached); + if (d->delay == delay) + return; + + d->delay = delay; + emit delayChanged(); + + if (isVisible()) + d->instance(true)->setDelay(delay); +} + +/*! + \qmlattachedproperty int QtQuick.Controls::ToolTip::timeout + + This attached property holds the timeout (milliseconds) of the shared tool tip. + The property can be attached to any item. + + \sa {Attached Tool Tips}, {Delay and Timeout} +*/ +int QQuickToolTipAttached::timeout() const +{ + Q_D(const QQuickToolTipAttached); + return d->timeout; +} + +void QQuickToolTipAttached::setTimeout(int timeout) +{ + Q_D(QQuickToolTipAttached); + if (d->timeout == timeout) + return; + + d->timeout = timeout; + emit timeoutChanged(); + + if (isVisible()) + d->instance(true)->setTimeout(timeout); +} + +/*! + \qmlattachedproperty bool QtQuick.Controls::ToolTip::visible + + This attached property holds whether the shared tool tip is visible. + The property can be attached to any item. + + \sa {Attached Tool Tips} +*/ +bool QQuickToolTipAttached::isVisible() const +{ + Q_D(const QQuickToolTipAttached); + QQuickToolTip *tip = d->instance(false); + if (!tip) + return false; + + return tip->isVisible() && tip->parentItem() == parent(); +} + +void QQuickToolTipAttached::setVisible(bool visible) +{ + Q_D(QQuickToolTipAttached); + if (visible) + show(d->text); + else + hide(); +} + +/*! + \qmlattachedproperty ToolTip QtQuick.Controls::ToolTip::toolTip + + This attached property holds the shared tool tip instance. The property + can be attached to any item. + + \sa {Attached Tool Tips} +*/ +QQuickToolTip *QQuickToolTipAttached::toolTip() const +{ + Q_D(const QQuickToolTipAttached); + return d->instance(true); +} + +/*! + \qmlattachedmethod void QtQuick.Controls::ToolTip::show(string text, int timeout = -1) + + This attached method shows the shared tooltip with \a text and \a timeout (milliseconds). + The method can be attached to any item. + + \sa {Attached Tool Tips} +*/ +void QQuickToolTipAttached::show(const QString &text, int ms) +{ + Q_D(QQuickToolTipAttached); + QQuickToolTip *tip = d->instance(true); + if (!tip) + return; + + tip->resetWidth(); + tip->resetHeight(); + tip->setParentItem(qobject_cast<QQuickItem *>(parent())); + tip->setDelay(d->delay); + tip->setTimeout(ms >= 0 ? ms : d->timeout); + tip->show(text); +} + +/*! + \qmlattachedmethod void QtQuick.Controls::ToolTip::hide() + + This attached method hides the shared tooltip. The method can be attached to any item. + + \sa {Attached Tool Tips} +*/ +void QQuickToolTipAttached::hide() +{ + Q_D(QQuickToolTipAttached); + QQuickToolTip *tip = d->instance(false); + if (!tip) + return; + // check the parent item to prevent unexpectedly closing tooltip by new created invisible tooltip + if (parent() == tip->parentItem()) + tip->close(); +} + +QT_END_NAMESPACE + +#include "moc_qquicktooltip_p.cpp" diff --git a/src/quicktemplates2/qquicktooltip_p.h b/src/quicktemplates2/qquicktooltip_p.h new file mode 100644 index 00000000000..5be22fd8c21 --- /dev/null +++ b/src/quicktemplates2/qquicktooltip_p.h @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTOOLTIP_P_H +#define QQUICKTOOLTIP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickpopup_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickToolTipPrivate; +class QQuickToolTipAttached; +class QQuickToolTipAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickToolTip : public QQuickPopup +{ + Q_OBJECT + Q_PROPERTY(int delay READ delay WRITE setDelay NOTIFY delayChanged FINAL) + Q_PROPERTY(int timeout READ timeout WRITE setTimeout NOTIFY timeoutChanged FINAL) + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged FINAL) + QML_NAMED_ELEMENT(ToolTip) + QML_ATTACHED(QQuickToolTipAttached) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickToolTip(QQuickItem *parent = nullptr); + + QString text() const; + void setText(const QString &text); + + int delay() const; + void setDelay(int delay); + + int timeout() const; + void setTimeout(int timeout); + + void setVisible(bool visible) override; + + static QQuickToolTipAttached *qmlAttachedProperties(QObject *object); + +Q_SIGNALS: + void textChanged(); + void delayChanged(); + void timeoutChanged(); + +public Q_SLOTS: + Q_REVISION(2, 5) void show(const QString &text, int ms = -1); + Q_REVISION(2, 5) void hide(); + +protected: + QFont defaultFont() const override; + + void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) override; + void timerEvent(QTimerEvent *event) override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; + void accessibilityActiveChanged(bool active) override; +#endif + +private: + Q_DISABLE_COPY(QQuickToolTip) + Q_DECLARE_PRIVATE(QQuickToolTip) +}; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickToolTipAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged FINAL) + Q_PROPERTY(int delay READ delay WRITE setDelay NOTIFY delayChanged FINAL) + Q_PROPERTY(int timeout READ timeout WRITE setTimeout NOTIFY timeoutChanged FINAL) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL) + Q_PROPERTY(QQuickToolTip *toolTip READ toolTip CONSTANT FINAL) + +public: + explicit QQuickToolTipAttached(QObject *parent = nullptr); + + QString text() const; + void setText(const QString &text); + + int delay() const; + void setDelay(int delay); + + int timeout() const; + void setTimeout(int timeout); + + bool isVisible() const; + void setVisible(bool visible); + + QQuickToolTip *toolTip() const; + +Q_SIGNALS: + void textChanged(); + void delayChanged(); + void timeoutChanged(); + void visibleChanged(); + +public Q_SLOTS: + void show(const QString &text, int ms = -1); + void hide(); + +private: + Q_DISABLE_COPY(QQuickToolTipAttached) + Q_DECLARE_PRIVATE(QQuickToolTipAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickToolTip) +QML_DECLARE_TYPEINFO(QQuickToolTip, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKTOOLTIP_P_H diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp new file mode 100644 index 00000000000..f66428b83e9 --- /dev/null +++ b/src/quicktemplates2/qquicktumbler.cpp @@ -0,0 +1,1047 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktumbler_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuick/private/qquickflickable_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p_p.h> +#include <QtQuickTemplates2/private/qquicktumbler_p_p.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcTumbler, "qt.quick.controls.tumbler") + +/*! + \qmltype Tumbler + \inherits Control +//! \instantiates QQuickTumbler + \inqmlmodule QtQuick.Controls + \since 5.7 + \ingroup qtquickcontrols2-input + \brief Spinnable wheel of items that can be selected. + + \image qtquickcontrols2-tumbler-wrap.gif + + \code + Tumbler { + model: 5 + // ... + } + \endcode + + Tumbler allows the user to select an option from a spinnable \e "wheel" of + items. It is useful for when there are too many options to use, for + example, a RadioButton, and too few options to require the use of an + editable SpinBox. It is convenient in that it requires no keyboard usage + and wraps around at each end when there are a large number of items. + + The API is similar to that of views like \l ListView and \l PathView; a + \l model and \l delegate can be set, and the \l count and \l currentItem + properties provide read-only access to information about the view. To + position the view at a certain index, use \l positionViewAtIndex(). + + Unlike views like \l PathView and \l ListView, however, there is always a + current item (when the model isn't empty). This means that when \l count is + equal to \c 0, \l currentIndex will be \c -1. In all other cases, it will + be greater than or equal to \c 0. + + By default, Tumbler \l {wrap}{wraps} when it reaches the top and bottom, as + long as there are more items in the model than there are visible items; + that is, when \l count is greater than \l visibleItemCount: + + \snippet qtquickcontrols2-tumbler-timePicker.qml tumbler + + \sa {Customizing Tumbler}, {Input Controls} +*/ + +namespace { + static inline qreal delegateHeight(const QQuickTumbler *tumbler) + { + return tumbler->availableHeight() / tumbler->visibleItemCount(); + } +} + +/* + Finds the contentItem of the view that is a child of the control's \a contentItem. + The type is stored in \a type. +*/ +QQuickItem *QQuickTumblerPrivate::determineViewType(QQuickItem *contentItem) +{ + if (!contentItem) { + resetViewData(); + return nullptr; + } + + if (contentItem->inherits("QQuickPathView")) { + view = contentItem; + viewContentItem = contentItem; + viewContentItemType = PathViewContentItem; + viewOffset = 0; + + return contentItem; + } else if (contentItem->inherits("QQuickListView")) { + view = contentItem; + viewContentItem = qobject_cast<QQuickFlickable*>(contentItem)->contentItem(); + viewContentItemType = ListViewContentItem; + viewContentY = 0; + + return contentItem; + } else { + const auto childItems = contentItem->childItems(); + for (QQuickItem *childItem : childItems) { + QQuickItem *item = determineViewType(childItem); + if (item) + return item; + } + } + + resetViewData(); + viewContentItemType = UnsupportedContentItemType; + return nullptr; +} + +void QQuickTumblerPrivate::resetViewData() +{ + view = nullptr; + viewContentItem = nullptr; + if (viewContentItemType == PathViewContentItem) + viewOffset = 0; + else if (viewContentItemType == ListViewContentItem) + viewContentY = 0; + viewContentItemType = NoContentItem; +} + +QList<QQuickItem *> QQuickTumblerPrivate::viewContentItemChildItems() const +{ + if (!viewContentItem) + return QList<QQuickItem *>(); + + return viewContentItem->childItems(); +} + +QQuickTumblerPrivate *QQuickTumblerPrivate::get(QQuickTumbler *tumbler) +{ + return tumbler->d_func(); +} + +void QQuickTumblerPrivate::_q_updateItemHeights() +{ + if (ignoreSignals) + return; + + // Can't use our own private padding members here, as the padding property might be set, + // which doesn't affect them, only their getters. + Q_Q(const QQuickTumbler); + const qreal itemHeight = delegateHeight(q); + const auto items = viewContentItemChildItems(); + for (QQuickItem *childItem : items) + childItem->setHeight(itemHeight); +} + +void QQuickTumblerPrivate::_q_updateItemWidths() +{ + if (ignoreSignals) + return; + + Q_Q(const QQuickTumbler); + const qreal availableWidth = q->availableWidth(); + const auto items = viewContentItemChildItems(); + for (QQuickItem *childItem : items) + childItem->setWidth(availableWidth); +} + +void QQuickTumblerPrivate::_q_onViewCurrentIndexChanged() +{ + Q_Q(QQuickTumbler); + if (!view || ignoreCurrentIndexChanges || currentIndexSetDuringModelChange) { + // If the user set currentIndex in the onModelChanged handler, + // we have to respect that currentIndex by ignoring changes in the view + // until the model has finished being set. + qCDebug(lcTumbler).nospace() << "view currentIndex changed to " + << (view ? view->property("currentIndex").toString() : QStringLiteral("unknown index (no view)")) + << ", but we're ignoring it because one or more of the following conditions are true:" + << "\n- !view: " << !view + << "\n- ignoreCurrentIndexChanges: " << ignoreCurrentIndexChanges + << "\n- currentIndexSetDuringModelChange: " << currentIndexSetDuringModelChange; + return; + } + + const int oldCurrentIndex = currentIndex; + currentIndex = view->property("currentIndex").toInt(); + + qCDebug(lcTumbler).nospace() << "view currentIndex changed to " + << (view ? view->property("currentIndex").toString() : QStringLiteral("unknown index (no view)")) + << ", our old currentIndex was " << oldCurrentIndex; + + if (oldCurrentIndex != currentIndex) + emit q->currentIndexChanged(); +} + +void QQuickTumblerPrivate::_q_onViewCountChanged() +{ + Q_Q(QQuickTumbler); + qCDebug(lcTumbler) << "view count changed - ignoring signals?" << ignoreSignals; + if (ignoreSignals) + return; + + setCount(view->property("count").toInt()); + + if (count > 0) { + if (pendingCurrentIndex != -1) { + // If there was an attempt to set currentIndex at creation, try to finish that attempt now. + // componentComplete() is too early, because the count might only be known sometime after completion. + setCurrentIndex(pendingCurrentIndex); + // If we could successfully set the currentIndex, consider it done. + // Otherwise, we'll try again later in updatePolish(). + if (currentIndex == pendingCurrentIndex) + setPendingCurrentIndex(-1); + else + q->polish(); + } else if (currentIndex == -1) { + // If new items were added and our currentIndex was -1, we must + // enforce our rule of a non-negative currentIndex when count > 0. + setCurrentIndex(0); + } + } else { + setCurrentIndex(-1); + } +} + +void QQuickTumblerPrivate::_q_onViewOffsetChanged() +{ + viewOffset = view->property("offset").toReal(); + calculateDisplacements(); +} + +void QQuickTumblerPrivate::_q_onViewContentYChanged() +{ + viewContentY = view->property("contentY").toReal(); + calculateDisplacements(); +} + +void QQuickTumblerPrivate::calculateDisplacements() +{ + const auto items = viewContentItemChildItems(); + for (QQuickItem *childItem : items) { + QQuickTumblerAttached *attached = qobject_cast<QQuickTumblerAttached *>(qmlAttachedPropertiesObject<QQuickTumbler>(childItem, false)); + if (attached) + QQuickTumblerAttachedPrivate::get(attached)->calculateDisplacement(); + } +} + +void QQuickTumblerPrivate::itemChildAdded(QQuickItem *, QQuickItem *) +{ + _q_updateItemWidths(); + _q_updateItemHeights(); +} + +void QQuickTumblerPrivate::itemChildRemoved(QQuickItem *, QQuickItem *) +{ + _q_updateItemWidths(); + _q_updateItemHeights(); +} + +void QQuickTumblerPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) +{ + QQuickControlPrivate::itemGeometryChanged(item, change, diff); + if (change.sizeChange()) + calculateDisplacements(); +} + +QPalette QQuickTumblerPrivate::defaultPalette() const +{ + return QQuickTheme::palette(QQuickTheme::Tumbler); +} + +QQuickTumbler::QQuickTumbler(QQuickItem *parent) + : QQuickControl(*(new QQuickTumblerPrivate), parent) +{ + setActiveFocusOnTab(true); + + connect(this, SIGNAL(leftPaddingChanged()), this, SLOT(_q_updateItemWidths())); + connect(this, SIGNAL(rightPaddingChanged()), this, SLOT(_q_updateItemWidths())); + connect(this, SIGNAL(topPaddingChanged()), this, SLOT(_q_updateItemHeights())); + connect(this, SIGNAL(bottomPaddingChanged()), this, SLOT(_q_updateItemHeights())); +} + +QQuickTumbler::~QQuickTumbler() +{ + Q_D(QQuickTumbler); + // Ensure that the item change listener is removed. + d->disconnectFromView(); +} + +/*! + \qmlproperty variant QtQuick.Controls::Tumbler::model + + This property holds the model that provides data for this tumbler. +*/ +QVariant QQuickTumbler::model() const +{ + Q_D(const QQuickTumbler); + return d->model; +} + +void QQuickTumbler::setModel(const QVariant &model) +{ + Q_D(QQuickTumbler); + if (model == d->model) + return; + + d->beginSetModel(); + + d->model = model; + emit modelChanged(); + + d->endSetModel(); + + d->currentIndexSetDuringModelChange = false; + + // Don't try to correct the currentIndex if count() isn't known yet. + // We can check in setupViewData() instead. + if (isComponentComplete() && d->view && count() == 0) + d->setCurrentIndex(-1); +} + +/*! + \qmlproperty int QtQuick.Controls::Tumbler::count + \readonly + + This property holds the number of items in the model. +*/ +int QQuickTumbler::count() const +{ + Q_D(const QQuickTumbler); + return d->count; +} + +/*! + \qmlproperty int QtQuick.Controls::Tumbler::currentIndex + + This property holds the index of the current item. + + The value of this property is \c -1 when \l count is equal to \c 0. In all + other cases, it will be greater than or equal to \c 0. + + \sa currentItem, positionViewAtIndex() +*/ +int QQuickTumbler::currentIndex() const +{ + Q_D(const QQuickTumbler); + return d->currentIndex; +} + +void QQuickTumbler::setCurrentIndex(int currentIndex) +{ + Q_D(QQuickTumbler); + if (d->modelBeingSet) + d->currentIndexSetDuringModelChange = true; + d->setCurrentIndex(currentIndex, QQuickTumblerPrivate::UserChange); +} + +/*! + \qmlproperty Item QtQuick.Controls::Tumbler::currentItem + \readonly + + This property holds the item at the current index. + + \sa currentIndex, positionViewAtIndex() +*/ +QQuickItem *QQuickTumbler::currentItem() const +{ + Q_D(const QQuickTumbler); + return d->view ? d->view->property("currentItem").value<QQuickItem*>() : nullptr; +} + +/*! + \qmlproperty Component QtQuick.Controls::Tumbler::delegate + + This property holds the delegate used to display each item. +*/ +QQmlComponent *QQuickTumbler::delegate() const +{ + Q_D(const QQuickTumbler); + return d->delegate; +} + +void QQuickTumbler::setDelegate(QQmlComponent *delegate) +{ + Q_D(QQuickTumbler); + if (delegate == d->delegate) + return; + + d->delegate = delegate; + emit delegateChanged(); +} + +/*! + \qmlproperty int QtQuick.Controls::Tumbler::visibleItemCount + + This property holds the number of items visible in the tumbler. It must be + an odd number, as the current item is always vertically centered. +*/ +int QQuickTumbler::visibleItemCount() const +{ + Q_D(const QQuickTumbler); + return d->visibleItemCount; +} + +void QQuickTumbler::setVisibleItemCount(int visibleItemCount) +{ + Q_D(QQuickTumbler); + if (visibleItemCount == d->visibleItemCount) + return; + + d->visibleItemCount = visibleItemCount; + d->_q_updateItemHeights(); + emit visibleItemCountChanged(); +} + +QQuickTumblerAttached *QQuickTumbler::qmlAttachedProperties(QObject *object) +{ + return new QQuickTumblerAttached(object); +} + +/*! + \qmlproperty bool QtQuick.Controls::Tumbler::wrap + \since QtQuick.Controls 2.1 (Qt 5.8) + + This property determines whether or not the tumbler wraps around when it + reaches the top or bottom. + + The default value is \c false when \l count is less than + \l visibleItemCount, as it is simpler to interact with a non-wrapping Tumbler + when there are only a few items. To override this behavior, explicitly set + the value of this property. To return to the default behavior, set this + property to \c undefined. +*/ +bool QQuickTumbler::wrap() const +{ + Q_D(const QQuickTumbler); + return d->wrap; +} + +void QQuickTumbler::setWrap(bool wrap) +{ + Q_D(QQuickTumbler); + d->setWrap(wrap, true); +} + +void QQuickTumbler::resetWrap() +{ + Q_D(QQuickTumbler); + d->explicitWrap = false; + d->setWrapBasedOnCount(); +} + +/*! + \qmlproperty bool QtQuick.Controls::Tumbler::moving + \since QtQuick.Controls 2.2 (Qt 5.9) + + This property describes whether the tumbler is currently moving, due to + the user either dragging or flicking it. +*/ +bool QQuickTumbler::isMoving() const +{ + Q_D(const QQuickTumbler); + return d->view && d->view->property("moving").toBool(); +} + +/*! + \qmlmethod void QtQuick.Controls::Tumbler::positionViewAtIndex(int index, PositionMode mode) + \since QtQuick.Controls 2.5 (Qt 5.12) + + Positions the view so that the \a index is at the position specified by \a mode. + + For example: + + \code + positionViewAtIndex(10, Tumbler.Center) + \endcode + + If \l wrap is true (the default), the modes available to \l {PathView}'s + \l {PathView::}{positionViewAtIndex()} function + are available, otherwise the modes available to \l {ListView}'s + \l {ListView::}{positionViewAtIndex()} function + are available. + + \note There is a known limitation that using \c Tumbler.Beginning when \l + wrap is \c true will result in the wrong item being positioned at the top + of view. As a workaround, pass \c {index - 1}. + + \sa currentIndex +*/ +void QQuickTumbler::positionViewAtIndex(int index, QQuickTumbler::PositionMode mode) +{ + Q_D(QQuickTumbler); + if (!d->view) { + d->warnAboutIncorrectContentItem(); + return; + } + + QMetaObject::invokeMethod(d->view, "positionViewAtIndex", Q_ARG(int, index), Q_ARG(int, mode)); +} + +void QQuickTumbler::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickTumbler); + + QQuickControl::geometryChange(newGeometry, oldGeometry); + + d->_q_updateItemHeights(); + + if (newGeometry.width() != oldGeometry.width()) + d->_q_updateItemWidths(); +} + +void QQuickTumbler::componentComplete() +{ + Q_D(QQuickTumbler); + qCDebug(lcTumbler) << "componentComplete()"; + QQuickControl::componentComplete(); + + if (!d->view) { + // Force the view to be created. + qCDebug(lcTumbler) << "emitting wrapChanged() to force view to be created"; + emit wrapChanged(); + // Determine the type of view for attached properties, etc. + d->setupViewData(d->contentItem); + } + + // If there was no contentItem or it was of an unsupported type, + // we don't have anything else to do. + if (!d->view) + return; + + // Update item heights after we've populated the model, + // otherwise ignoreSignals will cause these functions to return early. + d->_q_updateItemHeights(); + d->_q_updateItemWidths(); + d->_q_onViewCountChanged(); + + qCDebug(lcTumbler) << "componentComplete() is done"; +} + +void QQuickTumbler::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + Q_D(QQuickTumbler); + + QQuickControl::contentItemChange(newItem, oldItem); + + if (oldItem) + d->disconnectFromView(); + + if (newItem) { + // We wait until wrap is set to that we know which type of view to create. + // If we try to set up the view too early, we'll issue warnings about it not existing. + if (isComponentComplete()) { + // Make sure we use the new content item and not the current one, as that won't + // be changed until after contentItemChange() has finished. + d->setupViewData(newItem); + + d->_q_updateItemHeights(); + d->_q_updateItemWidths(); + } + } +} + +void QQuickTumblerPrivate::disconnectFromView() +{ + Q_Q(QQuickTumbler); + if (!view) { + // If a custom content item is declared, it can happen that + // the original contentItem exists without the view etc. having been + // determined yet, and then this is called when the custom content item + // is eventually set. + return; + } + + QObject::disconnect(view, SIGNAL(currentIndexChanged()), q, SLOT(_q_onViewCurrentIndexChanged())); + QObject::disconnect(view, SIGNAL(currentItemChanged()), q, SIGNAL(currentItemChanged())); + QObject::disconnect(view, SIGNAL(countChanged()), q, SLOT(_q_onViewCountChanged())); + QObject::disconnect(view, SIGNAL(movingChanged()), q, SIGNAL(movingChanged())); + + if (viewContentItemType == PathViewContentItem) + QObject::disconnect(view, SIGNAL(offsetChanged()), q, SLOT(_q_onViewOffsetChanged())); + else + QObject::disconnect(view, SIGNAL(contentYChanged()), q, SLOT(_q_onViewContentYChanged())); + + QQuickItemPrivate *oldViewContentItemPrivate = QQuickItemPrivate::get(viewContentItem); + oldViewContentItemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Children | QQuickItemPrivate::Geometry); + + resetViewData(); +} + +void QQuickTumblerPrivate::setupViewData(QQuickItem *newControlContentItem) +{ + // Don't do anything if we've already set up. + if (view) + return; + + determineViewType(newControlContentItem); + + if (viewContentItemType == QQuickTumblerPrivate::NoContentItem) + return; + + if (viewContentItemType == QQuickTumblerPrivate::UnsupportedContentItemType) { + warnAboutIncorrectContentItem(); + return; + } + + Q_Q(QQuickTumbler); + QObject::connect(view, SIGNAL(currentIndexChanged()), q, SLOT(_q_onViewCurrentIndexChanged())); + QObject::connect(view, SIGNAL(currentItemChanged()), q, SIGNAL(currentItemChanged())); + QObject::connect(view, SIGNAL(countChanged()), q, SLOT(_q_onViewCountChanged())); + QObject::connect(view, SIGNAL(movingChanged()), q, SIGNAL(movingChanged())); + + if (viewContentItemType == PathViewContentItem) { + QObject::connect(view, SIGNAL(offsetChanged()), q, SLOT(_q_onViewOffsetChanged())); + _q_onViewOffsetChanged(); + } else { + QObject::connect(view, SIGNAL(contentYChanged()), q, SLOT(_q_onViewContentYChanged())); + _q_onViewContentYChanged(); + } + + QQuickItemPrivate *viewContentItemPrivate = QQuickItemPrivate::get(viewContentItem); + viewContentItemPrivate->addItemChangeListener(this, QQuickItemPrivate::Children | QQuickItemPrivate::Geometry); + + // Sync the view's currentIndex with ours. + syncCurrentIndex(); + + calculateDisplacements(); +} + +void QQuickTumblerPrivate::warnAboutIncorrectContentItem() +{ + Q_Q(QQuickTumbler); + qmlWarning(q) << "Tumbler: contentItem must contain either a PathView or a ListView"; +} + +void QQuickTumblerPrivate::syncCurrentIndex() +{ + const int actualViewIndex = view->property("currentIndex").toInt(); + Q_Q(QQuickTumbler); + + const bool isPendingCurrentIndex = pendingCurrentIndex != -1; + const int indexToSet = isPendingCurrentIndex ? pendingCurrentIndex : currentIndex; + + // Nothing to do. + if (actualViewIndex == indexToSet) { + setPendingCurrentIndex(-1); + return; + } + + // actualViewIndex might be 0 or -1 for PathView and ListView respectively, + // but we always use -1 for that. + if (q->count() == 0 && actualViewIndex <= 0) + return; + + ignoreCurrentIndexChanges = true; + view->setProperty("currentIndex", QVariant(indexToSet)); + ignoreCurrentIndexChanges = false; + + if (view->property("currentIndex").toInt() == indexToSet) + setPendingCurrentIndex(-1); + else if (isPendingCurrentIndex) + q->polish(); +} + +void QQuickTumblerPrivate::setPendingCurrentIndex(int index) +{ + qCDebug(lcTumbler) << "setting pendingCurrentIndex to" << index; + pendingCurrentIndex = index; +} + +QString QQuickTumblerPrivate::propertyChangeReasonToString( + QQuickTumblerPrivate::PropertyChangeReason changeReason) +{ + return changeReason == UserChange ? QStringLiteral("UserChange") : QStringLiteral("InternalChange"); +} + +void QQuickTumblerPrivate::setCurrentIndex(int newCurrentIndex, + QQuickTumblerPrivate::PropertyChangeReason changeReason) +{ + Q_Q(QQuickTumbler); + qCDebug(lcTumbler).nospace() << "setting currentIndex to " << newCurrentIndex + << ", old currentIndex was " << currentIndex + << ", changeReason is " << propertyChangeReasonToString(changeReason); + if (newCurrentIndex == currentIndex || newCurrentIndex < -1) + return; + + if (!q->isComponentComplete()) { + // Views can't set currentIndex until they're ready. + qCDebug(lcTumbler) << "we're not complete; setting pendingCurrentIndex instead"; + setPendingCurrentIndex(newCurrentIndex); + return; + } + + if (modelBeingSet && changeReason == UserChange) { + // If modelBeingSet is true and the user set the currentIndex, + // the model is in the process of being set and the user has set + // the currentIndex in onModelChanged. We have to queue the currentIndex + // change until we're ready. + qCDebug(lcTumbler) << "a model is being set; setting pendingCurrentIndex instead"; + setPendingCurrentIndex(newCurrentIndex); + return; + } + + // -1 doesn't make sense for a non-empty Tumbler, because unlike + // e.g. ListView, there's always one item selected. + // Wait until the component has finished before enforcing this rule, though, + // because the count might not be known yet. + if ((count > 0 && newCurrentIndex == -1) || (newCurrentIndex >= count)) { + return; + } + + // The view might not have been created yet, as is the case + // if you create a Tumbler component and pass e.g. { currentIndex: 2 } + // to createObject(). + if (view) { + // Only actually set our currentIndex if the view was able to set theirs. + bool couldSet = false; + if (count == 0 && newCurrentIndex == -1) { + // PathView insists on using 0 as the currentIndex when there are no items. + couldSet = true; + } else { + ignoreCurrentIndexChanges = true; + ignoreSignals = true; + view->setProperty("currentIndex", newCurrentIndex); + ignoreSignals = false; + ignoreCurrentIndexChanges = false; + + couldSet = view->property("currentIndex").toInt() == newCurrentIndex; + } + + if (couldSet) { + // The view's currentIndex might not have actually changed, but ours has, + // and that's what user code sees. + currentIndex = newCurrentIndex; + emit q->currentIndexChanged(); + } + + qCDebug(lcTumbler) << "view's currentIndex is now" << view->property("currentIndex").toInt() + << "and ours is" << currentIndex; + } +} + +void QQuickTumblerPrivate::setCount(int newCount) +{ + qCDebug(lcTumbler).nospace() << "setting count to " << newCount + << ", old count was " << count; + if (newCount == count) + return; + + count = newCount; + + Q_Q(QQuickTumbler); + setWrapBasedOnCount(); + + emit q->countChanged(); +} + +void QQuickTumblerPrivate::setWrapBasedOnCount() +{ + if (count == 0 || explicitWrap || modelBeingSet) + return; + + setWrap(count >= visibleItemCount, false); +} + +void QQuickTumblerPrivate::setWrap(bool shouldWrap, bool isExplicit) +{ + qCDebug(lcTumbler) << "setting wrap to" << shouldWrap << "- exlicit?" << isExplicit; + if (isExplicit) + explicitWrap = true; + + Q_Q(QQuickTumbler); + if (q->isComponentComplete() && shouldWrap == wrap) + return; + + // Since we use the currentIndex of the contentItem directly, we must + // ensure that we keep track of the currentIndex so it doesn't get lost + // between view changes. + const int oldCurrentIndex = currentIndex; + + disconnectFromView(); + + wrap = shouldWrap; + + // New views will set their currentIndex upon creation, which we'd otherwise + // take as the correct one, so we must ignore them. + ignoreCurrentIndexChanges = true; + + // This will cause the view to be created if our contentItem is a TumblerView. + emit q->wrapChanged(); + + ignoreCurrentIndexChanges = false; + + // If isComponentComplete() is true, we require a contentItem. If it's not + // true, it might not have been created yet, so we wait until + // componentComplete() is called. + // + // When the contentItem (usually QQuickTumblerView) has been created, we + // can start determining its type, etc. If the delegates use attached + // properties, this will have already been called, in which case it will + // return early. If the delegate doesn't use attached properties, we need + // to call it here. + if (q->isComponentComplete() || contentItem) + setupViewData(contentItem); + + setCurrentIndex(oldCurrentIndex); +} + +void QQuickTumblerPrivate::beginSetModel() +{ + modelBeingSet = true; +} + +void QQuickTumblerPrivate::endSetModel() +{ + modelBeingSet = false; + setWrapBasedOnCount(); +} + +void QQuickTumbler::keyPressEvent(QKeyEvent *event) +{ + QQuickControl::keyPressEvent(event); + + Q_D(QQuickTumbler); + if (event->isAutoRepeat() || !d->view) + return; + + if (event->key() == Qt::Key_Up) { + QMetaObject::invokeMethod(d->view, "decrementCurrentIndex"); + } else if (event->key() == Qt::Key_Down) { + QMetaObject::invokeMethod(d->view, "incrementCurrentIndex"); + } +} + +void QQuickTumbler::updatePolish() +{ + Q_D(QQuickTumbler); + if (d->pendingCurrentIndex != -1) { + // Update our count, as ignoreSignals might have been true + // when _q_onViewCountChanged() was last called. + d->setCount(d->view->property("count").toInt()); + + // If the count is still 0, it's not going to happen. + if (d->count == 0) { + d->setPendingCurrentIndex(-1); + return; + } + + // If there is a pending currentIndex at this stage, it means that + // the view wouldn't set our currentIndex in _q_onViewCountChanged + // because it wasn't ready. Try one last time here. + d->setCurrentIndex(d->pendingCurrentIndex); + + if (d->currentIndex != d->pendingCurrentIndex && d->currentIndex == -1) { + // If we *still* couldn't set it, it's probably invalid. + // See if we can at least enforce our rule of "non-negative currentIndex when count > 0" instead. + d->setCurrentIndex(0); + } + + d->setPendingCurrentIndex(-1); + } +} + +QFont QQuickTumbler::defaultFont() const +{ + return QQuickTheme::font(QQuickTheme::Tumbler); +} + +void QQuickTumblerAttachedPrivate::init(QQuickItem *delegateItem) +{ + Q_Q(QQuickTumblerAttached); + if (!delegateItem->parentItem()) { + qmlWarning(q) << "Tumbler: attached properties must be accessed through a delegate item that has a parent"; + return; + } + + QVariant indexContextProperty = qmlContext(delegateItem)->contextProperty(QStringLiteral("index")); + if (!indexContextProperty.isValid()) { + qmlWarning(q) << "Tumbler: attempting to access attached property on item without an \"index\" property"; + return; + } + + index = indexContextProperty.toInt(); + + QQuickItem *parentItem = delegateItem; + while ((parentItem = parentItem->parentItem())) { + if ((tumbler = qobject_cast<QQuickTumbler*>(parentItem))) + break; + } +} + +void QQuickTumblerAttachedPrivate::calculateDisplacement() +{ + const qreal previousDisplacement = displacement; + displacement = 0; + + if (!tumbler) { + // Can happen if the attached properties are accessed on the wrong type of item or the tumbler was destroyed. + // We don't want to emit the change signal though, as this could cause warnings about Tumbler.tumbler being null. + return; + } + + // Can happen if there is no ListView or PathView within the contentItem. + QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(tumbler); + if (!tumblerPrivate->viewContentItem) { + emitIfDisplacementChanged(previousDisplacement, displacement); + return; + } + + // The attached property gets created before our count is updated, so just cheat here + // to avoid having to listen to count changes. + const int count = tumblerPrivate->view->property("count").toInt(); + // This can happen in tests, so it may happen in normal usage too. + if (count == 0) { + emitIfDisplacementChanged(previousDisplacement, displacement); + return; + } + + if (tumblerPrivate->viewContentItemType == QQuickTumblerPrivate::PathViewContentItem) { + const qreal offset = tumblerPrivate->viewOffset; + + displacement = count > 1 ? count - index - offset : 0; + // Don't add 1 if count <= visibleItemCount + const int visibleItems = tumbler->visibleItemCount(); + const int halfVisibleItems = visibleItems / 2 + (visibleItems < count ? 1 : 0); + if (displacement > halfVisibleItems) + displacement -= count; + else if (displacement < -halfVisibleItems) + displacement += count; + } else { + const qreal contentY = tumblerPrivate->viewContentY; + const qreal delegateH = delegateHeight(tumbler); + const qreal preferredHighlightBegin = tumblerPrivate->view->property("preferredHighlightBegin").toReal(); + const qreal itemY = qobject_cast<QQuickItem*>(parent)->y(); + qreal currentItemY = 0; + auto currentItem = tumblerPrivate->view->property("currentItem").value<QQuickItem*>(); + if (currentItem) + currentItemY = currentItem->y(); + // Start from the y position of the current item. + const qreal topOfCurrentItemInViewport = currentItemY - contentY; + // Then, calculate the distance between it and the preferredHighlightBegin. + const qreal relativePositionToPreferredHighlightBegin = topOfCurrentItemInViewport - preferredHighlightBegin; + // Next, calculate the distance between us and the current item. + const qreal distanceFromCurrentItem = currentItemY - itemY; + const qreal displacementInPixels = distanceFromCurrentItem - relativePositionToPreferredHighlightBegin; + // Convert it from pixels to a floating point index. + displacement = displacementInPixels / delegateH; + } + + emitIfDisplacementChanged(previousDisplacement, displacement); +} + +void QQuickTumblerAttachedPrivate::emitIfDisplacementChanged(qreal oldDisplacement, qreal newDisplacement) +{ + Q_Q(QQuickTumblerAttached); + if (newDisplacement != oldDisplacement) + emit q->displacementChanged(); +} + +QQuickTumblerAttached::QQuickTumblerAttached(QObject *parent) + : QObject(*(new QQuickTumblerAttachedPrivate), parent) +{ + Q_D(QQuickTumblerAttached); + QQuickItem *delegateItem = qobject_cast<QQuickItem *>(parent); + if (delegateItem) + d->init(delegateItem); + else if (parent) + qmlWarning(parent) << "Tumbler: attached properties of Tumbler must be accessed through a delegate item"; + + if (d->tumbler) { + // When the Tumbler is completed, wrapChanged() is emitted to let QQuickTumblerView + // know that it can create the view. The view itself might instantiate delegates + // that use attached properties. At this point, setupViewData() hasn't been called yet + // (it's called on the next line in componentComplete()), so we call it here so that + // we have access to the view. + QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(d->tumbler); + tumblerPrivate->setupViewData(tumblerPrivate->contentItem); + + if (delegateItem && delegateItem->parentItem() == tumblerPrivate->viewContentItem) { + // This item belongs to the "new" view, meaning that the tumbler's contentItem + // was probably assigned declaratively. If they're not equal, calling + // calculateDisplacement() would use the old contentItem data, which is bad. + d->calculateDisplacement(); + } + } +} + +/*! + \qmlattachedproperty Tumbler QtQuick.Controls::Tumbler::tumbler + \readonly + + This attached property holds the tumbler. The property can be attached to + a tumbler delegate. The value is \c null if the item is not a tumbler delegate. +*/ +QQuickTumbler *QQuickTumblerAttached::tumbler() const +{ + Q_D(const QQuickTumblerAttached); + return d->tumbler; +} + +/*! + \qmlattachedproperty real QtQuick.Controls::Tumbler::displacement + \readonly + + This attached property holds a value from \c {-visibleItemCount / 2} to + \c {visibleItemCount / 2}, which represents how far away this item is from + being the current item, with \c 0 being completely current. + + For example, the item below will be 40% opaque when it is not the current item, + and transition to 100% opacity when it becomes the current item: + + \code + delegate: Text { + text: modelData + opacity: 0.4 + Math.max(0, 1 - Math.abs(Tumbler.displacement)) * 0.6 + } + \endcode +*/ +qreal QQuickTumblerAttached::displacement() const +{ + Q_D(const QQuickTumblerAttached); + return d->displacement; +} + +QT_END_NAMESPACE + +#include "moc_qquicktumbler_p.cpp" diff --git a/src/quicktemplates2/qquicktumbler_p.h b/src/quicktemplates2/qquicktumbler_p.h new file mode 100644 index 00000000000..f9d5a13bef1 --- /dev/null +++ b/src/quicktemplates2/qquicktumbler_p.h @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTUMBLER_P_H +#define QQUICKTUMBLER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qvariant.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickTumblerAttached; +class QQuickTumblerPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTumbler : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged FINAL) + Q_PROPERTY(int count READ count NOTIFY countChanged FINAL) + Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL) + Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged FINAL) + Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL) + Q_PROPERTY(int visibleItemCount READ visibleItemCount WRITE setVisibleItemCount NOTIFY visibleItemCountChanged FINAL) + // 2.1 (Qt 5.8) + Q_PROPERTY(bool wrap READ wrap WRITE setWrap RESET resetWrap NOTIFY wrapChanged FINAL REVISION(2, 1)) + // 2.2 (Qt 5.9) + Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged FINAL REVISION(2, 2)) + QML_NAMED_ELEMENT(Tumbler) + QML_ATTACHED(QQuickTumblerAttached) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickTumbler(QQuickItem *parent = nullptr); + ~QQuickTumbler(); + + QVariant model() const; + void setModel(const QVariant &model); + + int count() const; + + int currentIndex() const; + void setCurrentIndex(int currentIndex); + QQuickItem *currentItem() const; + + QQmlComponent *delegate() const; + void setDelegate(QQmlComponent *delegate); + + int visibleItemCount() const; + void setVisibleItemCount(int visibleItemCount); + + static QQuickTumblerAttached *qmlAttachedProperties(QObject *object); + + // 2.1 (Qt 5.8) + bool wrap() const; + void setWrap(bool wrap); + void resetWrap(); + + // 2.2 (Qt 5.9) + bool isMoving() const; + + enum PositionMode { + Beginning, + Center, + End, + Visible, // ListView-only + Contain, + SnapPosition + }; + Q_ENUM(PositionMode) + + // 2.5 (Qt 5.12) + Q_REVISION(2, 5) Q_INVOKABLE void positionViewAtIndex(int index, PositionMode mode); + +Q_SIGNALS: + void modelChanged(); + void countChanged(); + void currentIndexChanged(); + void currentItemChanged(); + void delegateChanged(); + void visibleItemCountChanged(); + // 2.1 (Qt 5.8) + Q_REVISION(2, 1) void wrapChanged(); + // 2.2 (Qt 5.9) + Q_REVISION(2, 2) void movingChanged(); + +protected: + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + void componentComplete() override; + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + void keyPressEvent(QKeyEvent *event) override; + void updatePolish() override; + + QFont defaultFont() const override; + +private: + Q_DISABLE_COPY(QQuickTumbler) + Q_DECLARE_PRIVATE(QQuickTumbler) + + Q_PRIVATE_SLOT(d_func(), void _q_updateItemWidths()) + Q_PRIVATE_SLOT(d_func(), void _q_updateItemHeights()) + Q_PRIVATE_SLOT(d_func(), void _q_onViewCurrentIndexChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_onViewCountChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_onViewOffsetChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_onViewContentYChanged()) +}; + +class QQuickTumblerAttachedPrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTumblerAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickTumbler *tumbler READ tumbler CONSTANT FINAL) + Q_PROPERTY(qreal displacement READ displacement NOTIFY displacementChanged FINAL) + +public: + explicit QQuickTumblerAttached(QObject *parent = nullptr); + + QQuickTumbler *tumbler() const; + qreal displacement() const; + +Q_SIGNALS: + void displacementChanged(); + +private: + Q_DISABLE_COPY(QQuickTumblerAttached) + Q_DECLARE_PRIVATE(QQuickTumblerAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickTumbler) +QML_DECLARE_TYPEINFO(QQuickTumbler, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKTUMBLER_P_H diff --git a/src/quicktemplates2/qquicktumbler_p_p.h b/src/quicktemplates2/qquicktumbler_p_p.h new file mode 100644 index 00000000000..aa5d58c076f --- /dev/null +++ b/src/quicktemplates2/qquicktumbler_p_p.h @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTUMBLER_P_P_H +#define QQUICKTUMBLER_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontrol_p_p.h> +#include <QtQuickTemplates2/private/qquicktumbler_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTumblerPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickTumbler) + +public: + enum ContentItemType { + NoContentItem, + UnsupportedContentItemType, + PathViewContentItem, + ListViewContentItem + }; + + QQuickItem *determineViewType(QQuickItem *contentItem); + void resetViewData(); + QList<QQuickItem *> viewContentItemChildItems() const; + + static QQuickTumblerPrivate *get(QQuickTumbler *tumbler); + + QPalette defaultPalette() const override; + + QVariant model; + QQmlComponent *delegate = nullptr; + int visibleItemCount = 5; + bool wrap = true; + bool explicitWrap = false; + bool modelBeingSet = false; + bool currentIndexSetDuringModelChange = false; + QQuickItem *view = nullptr; + QQuickItem *viewContentItem = nullptr; + ContentItemType viewContentItemType = UnsupportedContentItemType; + union { + qreal viewOffset; // PathView + qreal viewContentY; // ListView + }; + int currentIndex = -1; + int pendingCurrentIndex = -1; + bool ignoreCurrentIndexChanges = false; + int count = 0; + bool ignoreSignals = false; + + void _q_updateItemHeights(); + void _q_updateItemWidths(); + void _q_onViewCurrentIndexChanged(); + void _q_onViewCountChanged(); + void _q_onViewOffsetChanged(); + void _q_onViewContentYChanged(); + + void calculateDisplacements(); + + void disconnectFromView(); + void setupViewData(QQuickItem *newControlContentItem); + void warnAboutIncorrectContentItem(); + void syncCurrentIndex(); + void setPendingCurrentIndex(int index); + + enum PropertyChangeReason { + UserChange, + InternalChange + }; + + static QString propertyChangeReasonToString(PropertyChangeReason changeReason); + + void setCurrentIndex(int newCurrentIndex, PropertyChangeReason changeReason = InternalChange); + void setCount(int newCount); + void setWrapBasedOnCount(); + void setWrap(bool shouldWrap, bool isExplicit); + void beginSetModel(); + void endSetModel(); + + void itemChildAdded(QQuickItem *, QQuickItem *) override; + void itemChildRemoved(QQuickItem *, QQuickItem *) override; + void itemGeometryChanged(QQuickItem *, QQuickGeometryChange , const QRectF &) override; +}; + +class QQuickTumblerAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickTumblerAttached) + +public: + static QQuickTumblerAttachedPrivate *get(QQuickTumblerAttached *attached) + { + return attached->d_func(); + } + + void init(QQuickItem *delegateItem); + + void calculateDisplacement(); + void emitIfDisplacementChanged(qreal oldDisplacement, qreal newDisplacement); + + // The Tumbler that contains the delegate. Required to calculated the displacement. + QPointer<QQuickTumbler> tumbler; + // The index of the delegate. Used to calculate the displacement. + int index = -1; + // The displacement for our delegate. + qreal displacement = 0; +}; + +QT_END_NAMESPACE + +#endif // QQUICKTUMBLER_P_P_H diff --git a/src/quicktemplates2/qquickvelocitycalculator.cpp b/src/quicktemplates2/qquickvelocitycalculator.cpp new file mode 100644 index 00000000000..a0c5ec0d262 --- /dev/null +++ b/src/quicktemplates2/qquickvelocitycalculator.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickvelocitycalculator_p_p.h" + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +/* + Usage: + + QQuickVelocityCalculator velocityCalculator; + + // ... + + velocityCalcular.startMeasuring(event->pos(), event->timestamp()); + velocityCalcular.stopMeasuring(event->pos(), event->timestamp()); + + // ... + + if (velocityCalculator.velocity().x() > someAmount) + doSomething(); + else if (velocityCalculator.velocity().x() < -someAmount) + doSomethingElse(); +*/ + +void QQuickVelocityCalculator::startMeasuring(const QPointF &point1, qint64 timestamp) +{ + m_point1 = point1; + + if (timestamp != 0) + m_point1Timestamp = timestamp; + else + m_timer.start(); +} + +void QQuickVelocityCalculator::stopMeasuring(const QPointF &point2, qint64 timestamp) +{ + if (timestamp == 0 && !m_timer.isValid()) { + qWarning() << "QQuickVelocityCalculator: a call to stopMeasuring() must be preceded by a call to startMeasuring()"; + return; + } + + m_point2 = point2; + m_point2Timestamp = timestamp != 0 ? timestamp : m_timer.elapsed(); + m_timer.invalidate(); +} + +void QQuickVelocityCalculator::reset() +{ + m_point1 = QPointF(); + m_point2 = QPointF(); + m_point1Timestamp = 0; + m_point2Timestamp = 0; + m_timer.invalidate(); +} + +QPointF QQuickVelocityCalculator::velocity() const +{ + if ((m_point2Timestamp == 0 || m_point1Timestamp == m_point2Timestamp) && !m_timer.isValid()) + return QPointF(); + + const qreal secondsElapsed = (m_point2Timestamp != 0 ? m_point2Timestamp - m_point1Timestamp : m_timer.elapsed()) / 1000.0; + const QPointF distance = m_point2 - m_point1; + return distance / secondsElapsed; +} + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickvelocitycalculator_p_p.h b/src/quicktemplates2/qquickvelocitycalculator_p_p.h new file mode 100644 index 00000000000..2b13ff07e4e --- /dev/null +++ b/src/quicktemplates2/qquickvelocitycalculator_p_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKVELOCITYCALCULATOR_P_P_H +#define QQUICKVELOCITYCALCULATOR_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qpoint.h> +#include <QtCore/qelapsedtimer.h> + +QT_BEGIN_NAMESPACE + +class QQuickVelocityCalculator +{ +public: + void startMeasuring(const QPointF &point1, qint64 timestamp = 0); + void stopMeasuring(const QPointF &m_point2, qint64 timestamp = 0); + void reset(); + QPointF velocity() const; + +private: + QPointF m_point1; + QPointF m_point2; + qint64 m_point1Timestamp = 0; + qint64 m_point2Timestamp = 0; + // When a timestamp isn't available, we must use a timer. + // When stopMeasuring() has been called, we store the elapsed time in point2timestamp. + QElapsedTimer m_timer; +}; + +QT_END_NAMESPACE + +#endif // QQUICKVELOCITYCALCULATOR_P_P_H diff --git a/src/quicktemplates2/qt_cmdline.cmake b/src/quicktemplates2/qt_cmdline.cmake new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/quicktemplates2/qtquicktemplates2global.cpp b/src/quicktemplates2/qtquicktemplates2global.cpp new file mode 100644 index 00000000000..5100e610bc6 --- /dev/null +++ b/src/quicktemplates2/qtquicktemplates2global.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module 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 "qtquicktemplates2global_p.h" + +#include <QtGui/qtguiglobal.h> + +#if QT_CONFIG(accessibility) +#include "qquickpage_p.h" +#include "accessible/qaccessiblequickpage_p.h" +#endif + +QT_BEGIN_NAMESPACE + +#if QT_CONFIG(accessibility) +static QAccessibleInterface *qQuickAccessibleFactory(const QString &classname, QObject *object) +{ + if (classname == u"QQuickPage") { + return new QAccessibleQuickPage(qobject_cast<QQuickPage *>(object)); + } + return nullptr; +} +#endif + +void QQuickTemplates_initializeModule() +{ +#if QT_CONFIG(accessibility) + QAccessible::installFactory(&qQuickAccessibleFactory); +#endif +} + +Q_CONSTRUCTOR_FUNCTION(QQuickTemplates_initializeModule) + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qtquicktemplates2global_p.h b/src/quicktemplates2/qtquicktemplates2global_p.h new file mode 100644 index 00000000000..db848229d50 --- /dev/null +++ b/src/quicktemplates2/qtquicktemplates2global_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTQUICKTEMPLATES2GLOBAL_P_H +#define QTQUICKTEMPLATES2GLOBAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> +#include <QtQml/private/qqmlglobal_p.h> +#include <QtQuickTemplates2/private/qtquicktemplates2-config_p.h> + +QT_BEGIN_NAMESPACE + +#ifndef QT_STATIC +# if defined(QT_BUILD_QUICKTEMPLATES2_LIB) +# define Q_QUICKTEMPLATES2_PRIVATE_EXPORT Q_DECL_EXPORT +# else +# define Q_QUICKTEMPLATES2_PRIVATE_EXPORT Q_DECL_IMPORT +# endif +#else +# define Q_QUICKTEMPLATES2_PRIVATE_EXPORT +#endif + +Q_QUICKTEMPLATES2_PRIVATE_EXPORT void QQuickTemplates_initializeModule(); + +QT_END_NAMESPACE + +Q_QUICKTEMPLATES2_PRIVATE_EXPORT void qml_register_types_QtQuick_Templates(); + +#endif // QTQUICKTEMPLATES2GLOBAL_P_H diff --git a/src/quicktemplates2/qtquicktemplates2plugin.cpp b/src/quicktemplates2/qtquicktemplates2plugin.cpp new file mode 100644 index 00000000000..0c0683e834e --- /dev/null +++ b/src/quicktemplates2/qtquicktemplates2plugin.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQml/qqmlextensionplugin.h> +#include <QtQml/private/qqmlglobal_p.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +#if QT_CONFIG(shortcut) +#include <QtQuickTemplates2/private/qquickshortcutcontext_p_p.h> + +// qtdeclarative/src/quick/util/qquickshortcut.cpp +typedef bool (*ShortcutContextMatcher)(QObject *, Qt::ShortcutContext); +extern ShortcutContextMatcher qt_quick_shortcut_context_matcher(); +extern void qt_quick_set_shortcut_context_matcher(ShortcutContextMatcher matcher); +#endif + +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Templates); +Q_GHS_KEEP_REFERENCE(QQuickTemplates_initializeModule); + + +QT_BEGIN_NAMESPACE + +class QtQuickTemplates2Plugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtQuickTemplates2Plugin(QObject *parent = nullptr); + ~QtQuickTemplates2Plugin(); + + void registerTypes(const char *uri) override; + void unregisterTypes() override; + +private: + bool registered; +#if QT_CONFIG(shortcut) + ShortcutContextMatcher originalContextMatcher; +#endif +}; + +QtQuickTemplates2Plugin::QtQuickTemplates2Plugin(QObject *parent) + : QQmlExtensionPlugin(parent), registered(false) +{ + volatile auto registration = &qml_register_types_QtQuick_Templates; + volatile auto initialization = &QQuickTemplates_initializeModule; + + Q_UNUSED(registration) + Q_UNUSED(initialization) +} + +QtQuickTemplates2Plugin::~QtQuickTemplates2Plugin() +{ + // Intentionally empty: we use register/unregisterTypes() to do + // initialization and cleanup, as plugins are not unloaded on macOS. +} + +void QtQuickTemplates2Plugin::registerTypes(const char * /*uri*/) +{ +#if QT_CONFIG(shortcut) + originalContextMatcher = qt_quick_shortcut_context_matcher(); + qt_quick_set_shortcut_context_matcher(QQuickShortcutContext::matcher); +#endif + + registered = true; +} + +void QtQuickTemplates2Plugin::unregisterTypes() +{ +#if QT_CONFIG(shortcut) + qt_quick_set_shortcut_context_matcher(originalContextMatcher); +#endif +} + +QT_END_NAMESPACE + +#include "qtquicktemplates2plugin.moc" diff --git a/src/quicktemplates2/quicktemplates2.pri b/src/quicktemplates2/quicktemplates2.pri new file mode 100644 index 00000000000..0f19de5e9d2 --- /dev/null +++ b/src/quicktemplates2/quicktemplates2.pri @@ -0,0 +1,182 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qquickabstractbutton_p.h \ + $$PWD/qquickabstractbutton_p_p.h \ + $$PWD/qquickaction_p.h \ + $$PWD/qquickactiongroup_p.h \ + $$PWD/qquickapplicationwindow_p.h \ + $$PWD/qquickbusyindicator_p.h \ + $$PWD/qquickbutton_p.h \ + $$PWD/qquickbutton_p_p.h \ + $$PWD/qquickbuttongroup_p.h \ + $$PWD/qquickcheckbox_p.h \ + $$PWD/qquickcheckdelegate_p.h \ + $$PWD/qquickcombobox_p.h \ + $$PWD/qquickcontainer_p.h \ + $$PWD/qquickcontainer_p_p.h \ + $$PWD/qquickcontentitem_p.h \ + $$PWD/qquickcontrol_p.h \ + $$PWD/qquickcontrol_p_p.h \ + $$PWD/qquickdeferredexecute_p_p.h \ + $$PWD/qquickdeferredpointer_p_p.h \ + $$PWD/qquickdelaybutton_p.h \ + $$PWD/qquickdial_p.h \ + $$PWD/qquickdialog_p.h \ + $$PWD/qquickdialog_p_p.h \ + $$PWD/qquickdialogbuttonbox_p.h \ + $$PWD/qquickdialogbuttonbox_p_p.h \ + $$PWD/qquickdrawer_p.h \ + $$PWD/qquickdrawer_p_p.h \ + $$PWD/qquickframe_p.h \ + $$PWD/qquickframe_p_p.h \ + $$PWD/qquickgroupbox_p.h \ + $$PWD/qquickheaderview_p.h \ + $$PWD/qquickheaderview_p_p.h \ + $$PWD/qquickicon_p.h \ + $$PWD/qquickindicatorbutton_p.h \ + $$PWD/qquickitemdelegate_p.h \ + $$PWD/qquickitemdelegate_p_p.h \ + $$PWD/qquicklabel_p.h \ + $$PWD/qquicklabel_p_p.h \ + $$PWD/qquickmenu_p.h \ + $$PWD/qquickmenu_p_p.h \ + $$PWD/qquickmenubar_p.h \ + $$PWD/qquickmenubar_p_p.h \ + $$PWD/qquickmenubaritem_p.h \ + $$PWD/qquickmenubaritem_p_p.h \ + $$PWD/qquickmenuitem_p.h \ + $$PWD/qquickmenuitem_p_p.h \ + $$PWD/qquickmenuseparator_p.h \ + $$PWD/qquickoverlay_p.h \ + $$PWD/qquickoverlay_p_p.h \ + $$PWD/qquickpage_p.h \ + $$PWD/qquickpage_p_p.h \ + $$PWD/qquickpageindicator_p.h \ + $$PWD/qquickpane_p.h \ + $$PWD/qquickpane_p_p.h \ + $$PWD/qquickpopup_p.h \ + $$PWD/qquickpopup_p_p.h \ + $$PWD/qquickpopupanchors_p.h \ + $$PWD/qquickpopupanchors_p_p.h \ + $$PWD/qquickpopupitem_p_p.h \ + $$PWD/qquickpopuppositioner_p_p.h \ + $$PWD/qquickpresshandler_p_p.h \ + $$PWD/qquickprogressbar_p.h \ + $$PWD/qquickradiobutton_p.h \ + $$PWD/qquickradiodelegate_p.h \ + $$PWD/qquickrangeslider_p.h \ + $$PWD/qquickroundbutton_p.h \ + $$PWD/qquickscrollbar_p.h \ + $$PWD/qquickscrollbar_p_p.h \ + $$PWD/qquickscrollindicator_p.h \ + $$PWD/qquickscrollview_p.h \ + $$PWD/qquickselectionrectangle_p.h \ + $$PWD/qquickselectionrectangle_p_p.h \ + $$PWD/qquickshortcutcontext_p_p.h \ + $$PWD/qquickslider_p.h \ + $$PWD/qquickspinbox_p.h \ + $$PWD/qquicksplitview_p.h \ + $$PWD/qquickstackelement_p_p.h \ + $$PWD/qquickstacktransition_p_p.h \ + $$PWD/qquickstackview_p.h \ + $$PWD/qquickstackview_p_p.h \ + $$PWD/qquickswipe_p.h \ + $$PWD/qquickswipedelegate_p.h \ + $$PWD/qquickswipedelegate_p_p.h \ + $$PWD/qquickswipeview_p.h \ + $$PWD/qquickswitch_p.h \ + $$PWD/qquickswitchdelegate_p.h \ + $$PWD/qquicktabbar_p.h \ + $$PWD/qquicktabbutton_p.h \ + $$PWD/qquicktextarea_p.h \ + $$PWD/qquicktextarea_p_p.h \ + $$PWD/qquicktextfield_p.h \ + $$PWD/qquicktextfield_p_p.h \ + $$PWD/qquicktheme_p.h \ + $$PWD/qquicktheme_p_p.h \ + $$PWD/qquicktoolbar_p.h \ + $$PWD/qquicktoolbutton_p.h \ + $$PWD/qquicktoolseparator_p.h \ + $$PWD/qquicktooltip_p.h \ + $$PWD/qquickvelocitycalculator_p_p.h + +SOURCES += \ + $$PWD/qquickabstractbutton.cpp \ + $$PWD/qquickaction.cpp \ + $$PWD/qquickactiongroup.cpp \ + $$PWD/qquickapplicationwindow.cpp \ + $$PWD/qquickbusyindicator.cpp \ + $$PWD/qquickbutton.cpp \ + $$PWD/qquickbuttongroup.cpp \ + $$PWD/qquickcheckbox.cpp \ + $$PWD/qquickcheckdelegate.cpp \ + $$PWD/qquickcombobox.cpp \ + $$PWD/qquickcontainer.cpp \ + $$PWD/qquickcontentitem.cpp \ + $$PWD/qquickcontrol.cpp \ + $$PWD/qquickdeferredexecute.cpp \ + $$PWD/qquickdelaybutton.cpp \ + $$PWD/qquickdial.cpp \ + $$PWD/qquickdialog.cpp \ + $$PWD/qquickdialogbuttonbox.cpp \ + $$PWD/qquickdrawer.cpp \ + $$PWD/qquickframe.cpp \ + $$PWD/qquickgroupbox.cpp \ + $$PWD/qquickheaderview.cpp \ + $$PWD/qquickicon.cpp \ + $$PWD/qquickindicatorbutton_p.cpp \ + $$PWD/qquickitemdelegate.cpp \ + $$PWD/qquicklabel.cpp \ + $$PWD/qquickmenu.cpp \ + $$PWD/qquickmenubar.cpp \ + $$PWD/qquickmenubaritem.cpp \ + $$PWD/qquickmenuitem.cpp \ + $$PWD/qquickmenuseparator.cpp \ + $$PWD/qquickoverlay.cpp \ + $$PWD/qquickpage.cpp \ + $$PWD/qquickpageindicator.cpp \ + $$PWD/qquickpane.cpp \ + $$PWD/qquickpopup.cpp \ + $$PWD/qquickpopupanchors.cpp \ + $$PWD/qquickpopupitem.cpp \ + $$PWD/qquickpopuppositioner.cpp \ + $$PWD/qquickpresshandler.cpp \ + $$PWD/qquickprogressbar.cpp \ + $$PWD/qquickradiobutton.cpp \ + $$PWD/qquickradiodelegate.cpp \ + $$PWD/qquickrangeslider.cpp \ + $$PWD/qquickroundbutton.cpp \ + $$PWD/qquickscrollbar.cpp \ + $$PWD/qquickscrollindicator.cpp \ + $$PWD/qquickscrollview.cpp \ + $$PWD/qquickshortcutcontext.cpp \ + $$PWD/qquickslider.cpp \ + $$PWD/qquickspinbox.cpp \ + $$PWD/qquicksplitview.cpp \ + $$PWD/qquickstackelement.cpp \ + $$PWD/qquickstacktransition.cpp \ + $$PWD/qquickstackview.cpp \ + $$PWD/qquickstackview_p.cpp \ + $$PWD/qquickswipedelegate.cpp \ + $$PWD/qquickswipeview.cpp \ + $$PWD/qquickswitch.cpp \ + $$PWD/qquickswitchdelegate.cpp \ + $$PWD/qquicktabbar.cpp \ + $$PWD/qquicktabbutton.cpp \ + $$PWD/qquicktextarea.cpp \ + $$PWD/qquicktextfield.cpp \ + $$PWD/qquicktheme.cpp \ + $$PWD/qquicktoolbar.cpp \ + $$PWD/qquicktoolbutton.cpp \ + $$PWD/qquicktoolseparator.cpp \ + $$PWD/qquicktooltip.cpp \ + $$PWD/qquickvelocitycalculator.cpp + +qtConfig(quick-listview):qtConfig(quick-pathview) { + HEADERS += \ + $$PWD/qquicktumbler_p.h \ + $$PWD/qquicktumbler_p_p.h + SOURCES += \ + $$PWD/qquicktumbler.cpp +} diff --git a/src/quicktestutils/CMakeLists.txt b/src/quicktestutils/CMakeLists.txt new file mode 100644 index 00000000000..ce629037e80 --- /dev/null +++ b/src/quicktestutils/CMakeLists.txt @@ -0,0 +1,45 @@ +if(TARGET Qt::Quick) + set (quick_sources + quick/geometrytestutils.cpp + quick/geometrytestutils_p.h + quick/viewtestutils.cpp + quick/viewtestutils_p.h + quick/visualtestutils.cpp + quick/visualtestutils_p.h + ) +endif() + +qt_internal_add_module(QuickTestUtilsPrivate + CONFIG_MODULE_NAME quicktestutilsprivate + STATIC + INTERNAL_MODULE + SOURCES + qml/platforminputcontext_p.h + qml/platformquirks_p.h + qml/qmlutils.cpp + qml/qmlutils_p.h + qml/qqmljsastdumper.cpp + qml/qqmljsastdumper_p.h + qml/testhttpserver.cpp + qml/testhttpserver_p.h + ${quick_sources} + DEFINES + QT_BUILD_SHARED_QML_TEST_UTILS_LIB + INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC_LIBRARIES + Qt::Core + Qt::Test + Qt::Network + Qt::Qml + Qt::QmlPrivate +) + +if(TARGET Qt::Quick) + qt_internal_extend_target(QuickTestUtilsPrivate + LIBRARIES + Qt::Quick + Qt::QuickPrivate + Qt::QuickTest + ) +endif() diff --git a/src/quicktestutils/qml/platforminputcontext_p.h b/src/quicktestutils/qml/platforminputcontext_p.h new file mode 100644 index 00000000000..2f757674093 --- /dev/null +++ b/src/quicktestutils/qml/platforminputcontext_p.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 PLATFORMINPUTCONTEXT_P_H +#define PLATFORMINPUTCONTEXT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qpa/qplatforminputcontext.h> +#include <QtGui/QInputMethod> + +QT_BEGIN_NAMESPACE + +class PlatformInputContext : public QPlatformInputContext +{ +public: + PlatformInputContext() + : m_visible(false), m_action(QInputMethod::Click), m_cursorPosition(0), + m_invokeActionCallCount(0), m_showInputPanelCallCount(0), m_hideInputPanelCallCount(0), + m_updateCallCount(0), m_direction(Qt::LeftToRight) + { + } + + void showInputPanel() override + { + m_visible = true; + m_showInputPanelCallCount++; + } + void hideInputPanel() override + { + m_visible = false; + m_hideInputPanelCallCount++; + } + bool isInputPanelVisible() const override + { + return m_visible; + } + void invokeAction(QInputMethod::Action action, int cursorPosition) override + { + m_invokeActionCallCount++; + m_action = action; + m_cursorPosition = cursorPosition; + } + void update(Qt::InputMethodQueries) override + { + m_updateCallCount++; + } + + QLocale locale() const override + { + if (m_direction == Qt::RightToLeft) + return QLocale(QLocale::Arabic); + else + return QLocale(QLocale::English); + } + + Qt::LayoutDirection inputDirection() const override + { + return m_direction; + } + + void setInputDirection(Qt::LayoutDirection direction) { + m_direction = direction; + emitLocaleChanged(); + emitInputDirectionChanged(inputDirection()); + } + + void clear() { + m_cursorPosition = 0; + m_invokeActionCallCount = 0; + m_visible = false; + m_showInputPanelCallCount = 0; + m_hideInputPanelCallCount = 0; + m_updateCallCount = 0; + } + + bool m_visible; + QInputMethod::Action m_action; + int m_cursorPosition; + int m_invokeActionCallCount; + int m_showInputPanelCallCount; + int m_hideInputPanelCallCount; + int m_updateCallCount; + Qt::LayoutDirection m_direction; +}; + +QT_END_NAMESPACE + +#endif // PLATFORMINPUTCONTEXT_P_H diff --git a/src/quicktestutils/qml/platformquirks_p.h b/src/quicktestutils/qml/platformquirks_p.h new file mode 100644 index 00000000000..16aa160d7ce --- /dev/null +++ b/src/quicktestutils/qml/platformquirks_p.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 PLATFORMQUIRKS_P_H +#define PLATFORMQUIRKS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qglobal.h> + +#ifdef Q_OS_OSX +#include <Carbon/Carbon.h> +#endif + +QT_BEGIN_NAMESPACE + +struct PlatformQuirks +{ + static inline bool isClipboardAvailable() + { +#if !QT_CONFIG(clipboard) + return false; +#elif defined(Q_OS_OSX) + PasteboardRef pasteboard; + OSStatus status = PasteboardCreate(0, &pasteboard); + if (status == noErr) + CFRelease(pasteboard); + return status == noErr; +#else + return true; +#endif + } +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/quicktestutils/qml/qmlutils.cpp b/src/quicktestutils/qml/qmlutils.cpp new file mode 100644 index 00000000000..2398ce20a31 --- /dev/null +++ b/src/quicktestutils/qml/qmlutils.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 "qmlutils_p.h" + +#include <QtCore/QDebug> +#include <QtCore/QMutexLocker> +#include <QtQml/QQmlComponent> +#include <QtQml/QQmlEngine> + +QT_BEGIN_NAMESPACE + +QQmlDataTest *QQmlDataTest::m_instance = 0; + +QQmlDataTest::QQmlDataTest(const char *qmlTestDataDir) : + m_qmlTestDataDir(qmlTestDataDir), +#ifdef QT_TESTCASE_BUILDDIR + m_dataDirectory(QTest::qFindTestData("data", m_qmlTestDataDir, 0, QT_TESTCASE_BUILDDIR)), +#else + m_dataDirectory(QTest::qFindTestData("data", m_qmlTestDataDir, 0)), +#endif + + m_dataDirectoryUrl(m_dataDirectory.startsWith(QLatin1Char(':')) + ? QUrl(QLatin1String("qrc") + m_dataDirectory + QLatin1Char('/')) + : QUrl::fromLocalFile(m_dataDirectory + QLatin1Char('/'))) +{ + m_instance = this; +} + +QQmlDataTest::~QQmlDataTest() +{ + m_instance = 0; +} + +void QQmlDataTest::initTestCase() +{ + QVERIFY2(!m_dataDirectory.isEmpty(), qPrintable(QLatin1String( + "'data' directory not found in ") + QFileInfo(QString::fromUtf8(m_qmlTestDataDir)).absolutePath())); + m_directory = QFileInfo(m_dataDirectory).absolutePath(); + if (m_dataDirectoryUrl.scheme() != QLatin1String("qrc")) + QVERIFY2(QDir::setCurrent(m_directory), qPrintable(QLatin1String("Could not chdir to ") + m_directory)); +} + +QString QQmlDataTest::testFile(const QString &fileName) const +{ + if (m_directory.isEmpty()) + qFatal("QQmlDataTest::initTestCase() not called."); + QString result = m_dataDirectory; + result += QLatin1Char('/'); + result += fileName; + return result; +} + +bool QQmlDataTest::canImportModule(const QString &importTestQmlSource) const +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(importTestQmlSource.toLatin1(), QUrl()); + return !component.isError(); +} + +Q_GLOBAL_STATIC(QMutex, qQmlTestMessageHandlerMutex) + +QQmlTestMessageHandler *QQmlTestMessageHandler::m_instance = 0; + +void QQmlTestMessageHandler::messageHandler(QtMsgType, const QMessageLogContext &context, const QString &message) +{ + QMutexLocker locker(qQmlTestMessageHandlerMutex()); + if (QQmlTestMessageHandler::m_instance) { + if (QQmlTestMessageHandler::m_instance->m_includeCategories) { + QQmlTestMessageHandler::m_instance->m_messages.push_back( + QString::fromLatin1("%1: %2").arg(QString::fromUtf8(context.category), message)); + } else { + QQmlTestMessageHandler::m_instance->m_messages.push_back(message); + } + } +} + +QQmlTestMessageHandler::QQmlTestMessageHandler() +{ + QMutexLocker locker(qQmlTestMessageHandlerMutex()); + Q_ASSERT(!QQmlTestMessageHandler::m_instance); + QQmlTestMessageHandler::m_instance = this; + m_oldHandler = qInstallMessageHandler(messageHandler); + m_includeCategories = false; +} + +QQmlTestMessageHandler::~QQmlTestMessageHandler() +{ + QMutexLocker locker(qQmlTestMessageHandlerMutex()); + Q_ASSERT(QQmlTestMessageHandler::m_instance); + qInstallMessageHandler(m_oldHandler); + QQmlTestMessageHandler::m_instance = 0; +} + +QT_END_NAMESPACE + +#include "moc_qmlutils_p.cpp" diff --git a/src/quicktestutils/qml/qmlutils_p.h b/src/quicktestutils/qml/qmlutils_p.h new file mode 100644 index 00000000000..9df1ac2f1ba --- /dev/null +++ b/src/quicktestutils/qml/qmlutils_p.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 QQMLTESTUTILS_P_H +#define QQMLTESTUTILS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QDir> +#include <QtCore/QUrl> +#include <QtCore/QCoreApplication> +#include <QtCore/QStringList> +#include <QtTest/QTest> + +QT_BEGIN_NAMESPACE + +/* Base class for tests with data that are located in a "data" subfolder. */ + +class QQmlDataTest : public QObject +{ + Q_OBJECT +public: + QQmlDataTest(const char *qmlTestDataDir); + virtual ~QQmlDataTest(); + + QString testFile(const QString &fileName) const; + inline QString testFile(const char *fileName) const + { return testFile(QLatin1String(fileName)); } + inline QUrl testFileUrl(const QString &fileName) const + { + const QString fn = testFile(fileName); + return fn.startsWith(QLatin1Char(':')) + ? QUrl(QLatin1String("qrc") + fn) + : QUrl::fromLocalFile(fn); + } + inline QUrl testFileUrl(const char *fileName) const + { return testFileUrl(QLatin1String(fileName)); } + + inline QString dataDirectory() const { return m_dataDirectory; } + inline QUrl dataDirectoryUrl() const { return m_dataDirectoryUrl; } + inline QString directory() const { return m_directory; } + + static inline QQmlDataTest *instance() { return m_instance; } + + bool canImportModule(const QString &importTestQmlSource) const; + +public slots: + virtual void initTestCase(); + +private: + static QQmlDataTest *m_instance; + + // The directory in which to search for the "data" directory. + const char *m_qmlTestDataDir = nullptr; + // The path to the "data" directory, if found. + const QString m_dataDirectory; + const QUrl m_dataDirectoryUrl; + QString m_directory; +}; + +class QQmlTestMessageHandler +{ + Q_DISABLE_COPY(QQmlTestMessageHandler) +public: + QQmlTestMessageHandler(); + ~QQmlTestMessageHandler(); + + const QStringList &messages() const { return m_messages; } + const QString messageString() const { return m_messages.join(QLatin1Char('\n')); } + + void clear() { m_messages.clear(); } + + void setIncludeCategoriesEnabled(bool enabled) { m_includeCategories = enabled; } + +private: + static void messageHandler(QtMsgType, const QMessageLogContext &context, const QString &message); + + static QQmlTestMessageHandler *m_instance; + QStringList m_messages; + QtMessageHandler m_oldHandler; + bool m_includeCategories; +}; + +QT_END_NAMESPACE + +#endif // QQMLTESTUTILS_P_H diff --git a/tests/auto/shared/qqmljsastdumper.cpp b/src/quicktestutils/qml/qqmljsastdumper.cpp similarity index 99% rename from tests/auto/shared/qqmljsastdumper.cpp rename to src/quicktestutils/qml/qqmljsastdumper.cpp index 9d4d1866552..4882d6c1ff7 100644 --- a/tests/auto/shared/qqmljsastdumper.cpp +++ b/src/quicktestutils/qml/qqmljsastdumper.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQml module of the Qt Toolkit. @@ -35,7 +35,7 @@ ** ** $QT_END_LICENSE$ **/ -#include "qqmljsastdumper.h" +#include "qqmljsastdumper_p.h" #include <private/qqmljsast_p.h> #include <QtCore/QDebug> #include <QtCore/QString> @@ -248,14 +248,13 @@ bool AstDumper::visit(UiImport *el) } bool AstDumper::visit(UiPublicMember *el) { - auto boolToStr = [](bool b) { return b ? "true" : "false"; }; QString typeStr = ((el->type == UiPublicMember::Signal) ? QLatin1String("Signal") : (el->type == UiPublicMember::Property) ? QLatin1String("Property") : QStringLiteral("Unexpected(%1)").arg(el->type)); start(QLatin1String("UiPublicMember type=%1 typeModifier=%2 name=%3 isDefaultMember=%4 isReadonlyMember=%5 isRequired=%6 " "defaultToken=%7 readonlyToken=%8 propertyToken=%9 requiredToken=%10 typeModifierToken=%11 typeToken=%12 " "identifierToken=%13 colonToken=%14 semicolonToken=%15") .arg(qs(typeStr), qs(el->typeModifier), qs(el->name), - boolToStr(el->isDefaultMember), boolToStr(el->isReadonlyMember), boolToStr(el->isRequired), + boolStr(el->isDefaultMember), boolStr(el->isReadonlyMember), boolStr(el->isRequired), loc(el->defaultToken), loc(el->readonlyToken), loc(el->propertyToken), loc(el->requiredToken), loc(el->typeModifierToken), loc(el->typeToken), loc(el->identifierToken), loc(el->colonToken), loc(el->semicolonToken) diff --git a/src/quicktestutils/qml/qqmljsastdumper_p.h b/src/quicktestutils/qml/qqmljsastdumper_p.h new file mode 100644 index 00000000000..055303ae595 --- /dev/null +++ b/src/quicktestutils/qml/qqmljsastdumper_p.h @@ -0,0 +1,449 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module 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 ASTDUMPER_P_H +#define ASTDUMPER_P_H + + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qqmljsglobal_p.h> +#include <private/qqmljsastvisitor_p.h> +#include <QtCore/QString> +#include <functional> +#include <ostream> + +QT_BEGIN_NAMESPACE +class QDebug; + +namespace QQmlJS { + +enum class DumperOptions { + None=0, + NoLocations=0x1, + NoAnnotations=0x2, + DumpNode=0x4 +}; +bool operator & (DumperOptions lhs, DumperOptions rhs); +DumperOptions operator | (DumperOptions lhs, DumperOptions rhs); + +// no export, currently just a supporting file... +class AstDumper: public AST::BaseVisitor +{ +public: + static QString printNode2(AST::Node *); + + static QString diff(AST::Node *n1, AST::Node *n2, int nContext=3, DumperOptions opt=DumperOptions::None, int indent=0); + static QString printNode(AST::Node *n, DumperOptions opt=DumperOptions::None, int indent=1, int baseIndent=0); + + AstDumper(const std::function <void (const QString &)> &dumper, DumperOptions options=DumperOptions::None, + int indent=1, int baseIndent=0); + + void start(const QString &str); + void start(const char *str); + void stop(const QString &str); + void stop(const char *str); + + QString qs(const QString &s); + QString qs(const char *s); + QString qs(QStringView s); + + QString loc(const SourceLocation &s); + + QString boolStr(bool v); + + bool preVisit(AST::Node *el) override; + void postVisit(AST::Node *el) override; + + // Ui + bool visit(AST::UiProgram *el) override; + bool visit(AST::UiHeaderItemList *) override; + bool visit(AST::UiPragma *el) override; + bool visit(AST::UiImport *el) override; + bool visit(AST::UiPublicMember *el) override; + bool visit(AST::UiSourceElement *) override; + bool visit(AST::UiObjectDefinition *) override; + bool visit(AST::UiObjectInitializer *) override; + bool visit(AST::UiObjectBinding *) override; + bool visit(AST::UiScriptBinding *) override; + bool visit(AST::UiArrayBinding *) override; + bool visit(AST::UiParameterList *) override; + bool visit(AST::UiObjectMemberList *) override; + bool visit(AST::UiArrayMemberList *) override; + bool visit(AST::UiQualifiedId *) override; + bool visit(AST::UiEnumDeclaration *) override; + bool visit(AST::UiEnumMemberList *) override; + bool visit(AST::UiVersionSpecifier *) override; + bool visit(AST::UiInlineComponent *) override; + bool visit(AST::UiRequired *) override; + bool visit(AST::UiAnnotation *) override; + bool visit(AST::UiAnnotationList *) override; + + void endVisit(AST::UiProgram *) override; + void endVisit(AST::UiImport *) override; + void endVisit(AST::UiHeaderItemList *) override; + void endVisit(AST::UiPragma *) override; + void endVisit(AST::UiPublicMember *) override; + void endVisit(AST::UiSourceElement *) override; + void endVisit(AST::UiObjectDefinition *) override; + void endVisit(AST::UiObjectInitializer *) override; + void endVisit(AST::UiObjectBinding *) override; + void endVisit(AST::UiScriptBinding *) override; + void endVisit(AST::UiArrayBinding *) override; + void endVisit(AST::UiParameterList *) override; + void endVisit(AST::UiObjectMemberList *) override; + void endVisit(AST::UiArrayMemberList *) override; + void endVisit(AST::UiQualifiedId *) override; + void endVisit(AST::UiEnumDeclaration *) override; + void endVisit(AST::UiEnumMemberList *) override; + void endVisit(AST::UiVersionSpecifier *) override; + void endVisit(AST::UiInlineComponent *) override; + void endVisit(AST::UiRequired *) override; + void endVisit(AST::UiAnnotation *) override; + void endVisit(AST::UiAnnotationList *) override; + + // QQmlJS + bool visit(AST::TypeExpression *) override; + void endVisit(AST::TypeExpression *) override; + + bool visit(AST::ThisExpression *) override; + void endVisit(AST::ThisExpression *) override; + + bool visit(AST::IdentifierExpression *) override; + void endVisit(AST::IdentifierExpression *) override; + + bool visit(AST::NullExpression *) override; + void endVisit(AST::NullExpression *) override; + + bool visit(AST::TrueLiteral *) override; + void endVisit(AST::TrueLiteral *) override; + + bool visit(AST::FalseLiteral *) override; + void endVisit(AST::FalseLiteral *) override; + + bool visit(AST::SuperLiteral *) override; + void endVisit(AST::SuperLiteral *) override; + + bool visit(AST::StringLiteral *) override; + void endVisit(AST::StringLiteral *) override; + + bool visit(AST::TemplateLiteral *) override; + void endVisit(AST::TemplateLiteral *) override; + + bool visit(AST::NumericLiteral *) override; + void endVisit(AST::NumericLiteral *) override; + + bool visit(AST::RegExpLiteral *) override; + void endVisit(AST::RegExpLiteral *) override; + + bool visit(AST::ArrayPattern *) override; + void endVisit(AST::ArrayPattern *) override; + + bool visit(AST::ObjectPattern *) override; + void endVisit(AST::ObjectPattern *) override; + + bool visit(AST::PatternElementList *) override; + void endVisit(AST::PatternElementList *) override; + + bool visit(AST::PatternPropertyList *) override; + void endVisit(AST::PatternPropertyList *) override; + + bool visit(AST::PatternElement *) override; + void endVisit(AST::PatternElement *) override; + + bool visit(AST::PatternProperty *) override; + void endVisit(AST::PatternProperty *) override; + + bool visit(AST::Elision *) override; + void endVisit(AST::Elision *) override; + + bool visit(AST::NestedExpression *) override; + void endVisit(AST::NestedExpression *) override; + + bool visit(AST::IdentifierPropertyName *) override; + void endVisit(AST::IdentifierPropertyName *) override; + + bool visit(AST::StringLiteralPropertyName *) override; + void endVisit(AST::StringLiteralPropertyName *) override; + + bool visit(AST::NumericLiteralPropertyName *) override; + void endVisit(AST::NumericLiteralPropertyName *) override; + + bool visit(AST::ComputedPropertyName *) override; + void endVisit(AST::ComputedPropertyName *) override; + + bool visit(AST::ArrayMemberExpression *) override; + void endVisit(AST::ArrayMemberExpression *) override; + + bool visit(AST::FieldMemberExpression *) override; + void endVisit(AST::FieldMemberExpression *) override; + + bool visit(AST::TaggedTemplate *) override; + void endVisit(AST::TaggedTemplate *) override; + + bool visit(AST::NewMemberExpression *) override; + void endVisit(AST::NewMemberExpression *) override; + + bool visit(AST::NewExpression *) override; + void endVisit(AST::NewExpression *) override; + + bool visit(AST::CallExpression *) override; + void endVisit(AST::CallExpression *) override; + + bool visit(AST::ArgumentList *) override; + void endVisit(AST::ArgumentList *) override; + + bool visit(AST::PostIncrementExpression *) override; + void endVisit(AST::PostIncrementExpression *) override; + + bool visit(AST::PostDecrementExpression *) override; + void endVisit(AST::PostDecrementExpression *) override; + + bool visit(AST::DeleteExpression *) override; + void endVisit(AST::DeleteExpression *) override; + + bool visit(AST::VoidExpression *) override; + void endVisit(AST::VoidExpression *) override; + + bool visit(AST::TypeOfExpression *) override; + void endVisit(AST::TypeOfExpression *) override; + + bool visit(AST::PreIncrementExpression *) override; + void endVisit(AST::PreIncrementExpression *) override; + + bool visit(AST::PreDecrementExpression *) override; + void endVisit(AST::PreDecrementExpression *) override; + + bool visit(AST::UnaryPlusExpression *) override; + void endVisit(AST::UnaryPlusExpression *) override; + + bool visit(AST::UnaryMinusExpression *) override; + void endVisit(AST::UnaryMinusExpression *) override; + + bool visit(AST::TildeExpression *) override; + void endVisit(AST::TildeExpression *) override; + + bool visit(AST::NotExpression *) override; + void endVisit(AST::NotExpression *) override; + + bool visit(AST::BinaryExpression *) override; + void endVisit(AST::BinaryExpression *) override; + + bool visit(AST::ConditionalExpression *) override; + void endVisit(AST::ConditionalExpression *) override; + + bool visit(AST::Expression *) override; + void endVisit(AST::Expression *) override; + + bool visit(AST::Block *) override; + void endVisit(AST::Block *) override; + + bool visit(AST::StatementList *) override; + void endVisit(AST::StatementList *) override; + + bool visit(AST::VariableStatement *) override; + void endVisit(AST::VariableStatement *) override; + + bool visit(AST::VariableDeclarationList *) override; + void endVisit(AST::VariableDeclarationList *) override; + + bool visit(AST::EmptyStatement *) override; + void endVisit(AST::EmptyStatement *) override; + + bool visit(AST::ExpressionStatement *) override; + void endVisit(AST::ExpressionStatement *) override; + + bool visit(AST::IfStatement *) override; + void endVisit(AST::IfStatement *) override; + + bool visit(AST::DoWhileStatement *) override; + void endVisit(AST::DoWhileStatement *) override; + + bool visit(AST::WhileStatement *) override; + void endVisit(AST::WhileStatement *) override; + + bool visit(AST::ForStatement *) override; + void endVisit(AST::ForStatement *) override; + + bool visit(AST::ForEachStatement *) override; + void endVisit(AST::ForEachStatement *) override; + + bool visit(AST::ContinueStatement *) override; + void endVisit(AST::ContinueStatement *) override; + + bool visit(AST::BreakStatement *) override; + void endVisit(AST::BreakStatement *) override; + + bool visit(AST::ReturnStatement *) override; + void endVisit(AST::ReturnStatement *) override; + + bool visit(AST::YieldExpression *) override; + void endVisit(AST::YieldExpression *) override; + + bool visit(AST::WithStatement *) override; + void endVisit(AST::WithStatement *) override; + + bool visit(AST::SwitchStatement *) override; + void endVisit(AST::SwitchStatement *) override; + + bool visit(AST::CaseBlock *) override; + void endVisit(AST::CaseBlock *) override; + + bool visit(AST::CaseClauses *) override; + void endVisit(AST::CaseClauses *) override; + + bool visit(AST::CaseClause *) override; + void endVisit(AST::CaseClause *) override; + + bool visit(AST::DefaultClause *) override; + void endVisit(AST::DefaultClause *) override; + + bool visit(AST::LabelledStatement *) override; + void endVisit(AST::LabelledStatement *) override; + + bool visit(AST::ThrowStatement *) override; + void endVisit(AST::ThrowStatement *) override; + + bool visit(AST::TryStatement *) override; + void endVisit(AST::TryStatement *) override; + + bool visit(AST::Catch *) override; + void endVisit(AST::Catch *) override; + + bool visit(AST::Finally *) override; + void endVisit(AST::Finally *) override; + + bool visit(AST::FunctionDeclaration *) override; + void endVisit(AST::FunctionDeclaration *) override; + + bool visit(AST::FunctionExpression *) override; + void endVisit(AST::FunctionExpression *) override; + + bool visit(AST::FormalParameterList *) override; + void endVisit(AST::FormalParameterList *) override; + + bool visit(AST::ClassExpression *) override; + void endVisit(AST::ClassExpression *) override; + + bool visit(AST::ClassDeclaration *) override; + void endVisit(AST::ClassDeclaration *) override; + + bool visit(AST::ClassElementList *) override; + void endVisit(AST::ClassElementList *) override; + + bool visit(AST::Program *) override; + void endVisit(AST::Program *) override; + + bool visit(AST::NameSpaceImport *) override; + void endVisit(AST::NameSpaceImport *) override; + + bool visit(AST::ImportSpecifier *) override; + void endVisit(AST::ImportSpecifier *) override; + + bool visit(AST::ImportsList *) override; + void endVisit(AST::ImportsList *) override; + + bool visit(AST::NamedImports *) override; + void endVisit(AST::NamedImports *) override; + + bool visit(AST::FromClause *) override; + void endVisit(AST::FromClause *) override; + + bool visit(AST::ImportClause *) override; + void endVisit(AST::ImportClause *) override; + + bool visit(AST::ImportDeclaration *) override; + void endVisit(AST::ImportDeclaration *) override; + + bool visit(AST::ExportSpecifier *) override; + void endVisit(AST::ExportSpecifier *) override; + + bool visit(AST::ExportsList *) override; + void endVisit(AST::ExportsList *) override; + + bool visit(AST::ExportClause *) override; + void endVisit(AST::ExportClause *) override; + + bool visit(AST::ExportDeclaration *) override; + void endVisit(AST::ExportDeclaration *) override; + + bool visit(AST::ESModule *) override; + void endVisit(AST::ESModule *) override; + + bool visit(AST::DebuggerStatement *) override; + void endVisit(AST::DebuggerStatement *) override; + + bool visit(AST::Type *) override; + void endVisit(AST::Type *) override; + + bool visit(AST::TypeArgumentList *) override; + void endVisit(AST::TypeArgumentList *) override; + + bool visit(AST::TypeAnnotation *) override; + void endVisit(AST::TypeAnnotation *) override; + + void throwRecursionDepthError() override; + +private: + // attributes + std::function <void (const QString &)> dumper; + DumperOptions options = DumperOptions::None; + int indent = 0; + int baseIndent = 0; + bool dumpNode(); + bool noLocations(); + bool noAnnotations(); +}; + +QDebug operator<<(QDebug d, AST::Node *n); + +std::ostream &operator<<(std::ostream &stream, AST::Node *n); + +} // namespace AST + +QT_END_NAMESPACE + +#endif // ASTDUMPER_P_H diff --git a/tests/auto/shared/testhttpserver.cpp b/src/quicktestutils/qml/testhttpserver.cpp similarity index 96% rename from tests/auto/shared/testhttpserver.cpp rename to src/quicktestutils/qml/testhttpserver.cpp index f4347f183f7..8ac56d8ee96 100644 --- a/tests/auto/shared/testhttpserver.cpp +++ b/src/quicktestutils/qml/testhttpserver.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -26,7 +26,7 @@ ** ****************************************************************************/ -#include "testhttpserver.h" +#include "testhttpserver_p.h" #include <QTcpSocket> #include <QDebug> #include <QFile> @@ -34,6 +34,8 @@ #include <QTest> #include <QQmlFile> +QT_BEGIN_NAMESPACE + /*! \internal \class TestHTTPServer @@ -78,6 +80,11 @@ The following request urls will then result in the appropriate action: \endtable */ +static QList<QByteArrayView> ignoredHeaders = { + "HTTP2-Settings", // We ignore this + "Upgrade", // We ignore this as well +}; + static QUrl localHostUrl(quint16 port) { QUrl url; @@ -276,6 +283,12 @@ void TestHTTPServer::readyRead() break; } } + for (QByteArrayView ignore : ignoredHeaders) { + if (line.startsWith(ignore)) { + prefixFound = true; + break; + } + } if (!prefixFound && !m_waitData.headerExactMatches.contains(line)) { qWarning() << "TestHTTPServer: Unexpected header:" << line @@ -449,3 +462,7 @@ void ThreadedTestHTTPServer::start() QThread::start(); m_condition.wait(&m_mutex); } + +QT_END_NAMESPACE + +#include "moc_testhttpserver_p.cpp" diff --git a/src/quicktestutils/qml/testhttpserver_p.h b/src/quicktestutils/qml/testhttpserver_p.h new file mode 100644 index 00000000000..db99b348cab --- /dev/null +++ b/src/quicktestutils/qml/testhttpserver_p.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 TESTHTTPSERVER_P_H +#define TESTHTTPSERVER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QTcpServer> +#include <QUrl> +#include <QPair> +#include <QThread> +#include <QMutex> +#include <QWaitCondition> + +QT_BEGIN_NAMESPACE + +class TestHTTPServer : public QObject +{ + Q_OBJECT +public: + TestHTTPServer(); + + bool listen(); + quint16 port() const; + QUrl baseUrl() const; + QUrl url(const QString &documentPath) const; + QString urlString(const QString &documentPath) const; + QString errorString() const; + + enum Mode { Normal, Delay, Disconnect }; + bool serveDirectory(const QString &, Mode = Normal); + + bool wait(const QUrl &expect, const QUrl &reply, const QUrl &body); + bool hasFailed() const; + + void addAlias(const QString &filename, const QString &aliasName); + void addRedirect(const QString &filename, const QString &redirectName); + + void registerFileNameForContentSubstitution(const QString &fileName); + + // In Delay mode, each item needs one call to this function to be sent + void sendDelayedItem(); + +private slots: + void newConnection(); + void disconnected(); + void readyRead(); + void sendOne(); + +private: + enum State { + AwaitingHeader, + AwaitingData, + Failed + }; + + void serveGET(QTcpSocket *, const QByteArray &); + bool reply(QTcpSocket *, const QByteArray &); + + QList<QPair<QString, Mode> > m_directories; + QHash<QTcpSocket *, QByteArray> m_dataCache; + QList<QPair<QTcpSocket *, QByteArray> > m_toSend; + QSet<QString> m_contentSubstitutedFileNames; + + struct WaitData { + QList<QByteArray> headerExactMatches; + QList<QByteArray> headerPrefixes; + QByteArray body; + } m_waitData; + QByteArray m_replyData; + QByteArray m_bodyData; + QByteArray m_data; + State m_state; + + QHash<QString, QString> m_aliases; + QHash<QString, QString> m_redirects; + + QTcpServer m_server; +}; + +class ThreadedTestHTTPServer : public QThread +{ + Q_OBJECT +public: + ThreadedTestHTTPServer(const QString &dir, TestHTTPServer::Mode mode = TestHTTPServer::Normal); + ThreadedTestHTTPServer(const QHash<QString, TestHTTPServer::Mode> &dirs); + ~ThreadedTestHTTPServer(); + + QUrl baseUrl() const; + QUrl url(const QString &documentPath) const; + QString urlString(const QString &documentPath) const; + +protected: + void run() override; + +private: + void start(); + + QHash<QString, TestHTTPServer::Mode> m_dirs; + quint16 m_port; + QMutex m_mutex; + QWaitCondition m_condition; +}; + +QT_END_NAMESPACE + +#endif // TESTHTTPSERVER_P_H + diff --git a/src/quicktestutils/quick/geometrytestutils.cpp b/src/quicktestutils/quick/geometrytestutils.cpp new file mode 100644 index 00000000000..27e36c27972 --- /dev/null +++ b/src/quicktestutils/quick/geometrytestutils.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 "geometrytestutils_p.h" + +#include <QQuickItem> + +QT_BEGIN_NAMESPACE + +QSizeChangeListener::QSizeChangeListener(QQuickItem *item) : + item(item) +{ + connect(item, &QQuickItem::widthChanged, this, &QSizeChangeListener::onSizeChanged); + connect(item, &QQuickItem::heightChanged, this, &QSizeChangeListener::onSizeChanged); +} + +void QSizeChangeListener::onSizeChanged() +{ + append(QSize(item->width(), item->height())); +} + +QT_END_NAMESPACE + +#include "moc_geometrytestutils_p.cpp" diff --git a/src/quicktestutils/quick/geometrytestutils_p.h b/src/quicktestutils/quick/geometrytestutils_p.h new file mode 100644 index 00000000000..867dddeda3d --- /dev/null +++ b/src/quicktestutils/quick/geometrytestutils_p.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 QQUICKGEOMETRYTESTUTIL_P_H +#define QQUICKGEOMETRYTESTUTIL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QObject> +#include <QVector> +#include <QSize> + +QT_BEGIN_NAMESPACE + +class QQuickItem; + +class QSizeChangeListener : public QObject, public QVector<QSize> +{ + Q_OBJECT +public: + explicit QSizeChangeListener(QQuickItem *item); +private slots: + void onSizeChanged(); +private: + QQuickItem *item; +}; + +QT_END_NAMESPACE + +#endif // QQUICKGEOMETRYTESTUTIL_P_H diff --git a/src/quicktestutils/quick/viewtestutils.cpp b/src/quicktestutils/quick/viewtestutils.cpp new file mode 100644 index 00000000000..cd6196e677c --- /dev/null +++ b/src/quicktestutils/quick/viewtestutils.cpp @@ -0,0 +1,622 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 "viewtestutils_p.h" + +#include <QtCore/QRandomGenerator> +#include <QtQuick/QQuickView> +#include <QtQuick/QQuickView> +#include <QtGui/QScreen> +#include <QtGui/qpa/qwindowsysteminterface.h> + +#include <QtTest/QTest> + +#include <QtQuick/private/qquickdeliveryagent_p_p.h> +#include <QtQuick/private/qquickitemview_p_p.h> +#include <QtQuick/private/qquickwindow_p.h> + +#include <QtQuickTestUtils/private/visualtestutils_p.h> + +QT_BEGIN_NAMESPACE + +QQuickView *QQuickViewTestUtils::createView() +{ + QQuickView *window = new QQuickView(0); + const QSize size(240, 320); + window->resize(size); + QQuickViewTestUtils::centerOnScreen(window, size); + return window; +} + +void QQuickViewTestUtils::centerOnScreen(QQuickView *window, const QSize &size) +{ + const QRect screenGeometry = window->screen()->availableGeometry(); + const QPoint offset = QPoint(size.width() / 2, size.height() / 2); + window->setFramePosition(screenGeometry.center() - offset); +} + +void QQuickViewTestUtils::centerOnScreen(QQuickView *window) +{ + QQuickViewTestUtils::centerOnScreen(window, window->size()); +} + +void QQuickViewTestUtils::moveMouseAway(QQuickView *window) +{ +#if QT_CONFIG(cursor) // Get the cursor out of the way. + QCursor::setPos(window->geometry().topRight() + QPoint(100, 100)); +#else + Q_UNUSED(window); +#endif +} + +void QQuickViewTestUtils::moveAndRelease(QQuickView *window, const QPoint &position) +{ + QTest::mouseMove(window, position); + QTest::mouseRelease(window, Qt::LeftButton, {}, position); +} + +void QQuickViewTestUtils::moveAndPress(QQuickView *window, const QPoint &position) +{ + QTest::mouseMove(window, position); + QTest::mousePress(window, Qt::LeftButton, {}, position); +} + +void QQuickViewTestUtils::flick(QQuickView *window, const QPoint &from, const QPoint &to, int duration) +{ + const int pointCount = 5; + QPoint diff = to - from; + + // send press, five equally spaced moves, and release. + moveAndPress(window, from); + + for (int i = 0; i < pointCount; ++i) + QTest::mouseMove(window, from + (i+1)*diff/pointCount, duration / pointCount); + + moveAndRelease(window, to); + QTest::qWait(50); +} + +QList<int> QQuickViewTestUtils::adjustIndexesForAddDisplaced(const QList<int> &indexes, int index, int count) +{ + QList<int> result; + for (int i=0; i<indexes.count(); i++) { + int num = indexes[i]; + if (num >= index) { + num += count; + } + result << num; + } + return result; +} + +QList<int> QQuickViewTestUtils::adjustIndexesForMove(const QList<int> &indexes, int from, int to, int count) +{ + QList<int> result; + for (int i=0; i<indexes.count(); i++) { + int num = indexes[i]; + if (from < to) { + if (num >= from && num < from + count) + num += (to - from); // target + else if (num >= from && num < to + count) + num -= count; // displaced + } else if (from > to) { + if (num >= from && num < from + count) + num -= (from - to); // target + else if (num >= to && num < from + count) + num += count; // displaced + } + result << num; + } + return result; +} + +QList<int> QQuickViewTestUtils::adjustIndexesForRemoveDisplaced(const QList<int> &indexes, int index, int count) +{ + QList<int> result; + for (int i=0; i<indexes.count(); i++) { + int num = indexes[i]; + if (num >= index) + num -= count; + result << num; + } + return result; +} + +QQuickViewTestUtils::QaimModel::QaimModel(QObject *parent) + : QAbstractListModel(parent) +{ +} + +int QQuickViewTestUtils::QaimModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return list.count(); +} + +int QQuickViewTestUtils::QaimModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return columns; +} + +QHash<int,QByteArray> QQuickViewTestUtils::QaimModel::roleNames() const +{ + QHash<int,QByteArray> roles = QAbstractListModel::roleNames(); + roles.insert(Name, "name"); + roles.insert(Number, "number"); + return roles; +} + +QVariant QQuickViewTestUtils::QaimModel::data(const QModelIndex &index, int role) const +{ + QVariant rv; + if (role == Name) + rv = list.at(index.row()).first; + else if (role == Number) + rv = list.at(index.row()).second; + + return rv; +} + +int QQuickViewTestUtils::QaimModel::count() const +{ + return rowCount() * columnCount(); +} + +QString QQuickViewTestUtils::QaimModel::name(int index) const +{ + return list.at(index).first; +} + +QString QQuickViewTestUtils::QaimModel::number(int index) const +{ + return list.at(index).second; +} + +void QQuickViewTestUtils::QaimModel::addItem(const QString &name, const QString &number) +{ + emit beginInsertRows(QModelIndex(), list.count(), list.count()); + list.append(QPair<QString,QString>(name, number)); + emit endInsertRows(); +} + +void QQuickViewTestUtils::QaimModel::addItems(const QList<QPair<QString, QString> > &items) +{ + emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1); + for (int i=0; i<items.count(); i++) + list.append(QPair<QString,QString>(items[i].first, items[i].second)); + emit endInsertRows(); +} + +void QQuickViewTestUtils::QaimModel::insertItem(int index, const QString &name, const QString &number) +{ + emit beginInsertRows(QModelIndex(), index, index); + list.insert(index, QPair<QString,QString>(name, number)); + emit endInsertRows(); +} + +void QQuickViewTestUtils::QaimModel::insertItems(int index, const QList<QPair<QString, QString> > &items) +{ + emit beginInsertRows(QModelIndex(), index, index+items.count()-1); + for (int i=0; i<items.count(); i++) + list.insert(index + i, QPair<QString,QString>(items[i].first, items[i].second)); + emit endInsertRows(); +} + +void QQuickViewTestUtils::QaimModel::removeItem(int index) +{ + emit beginRemoveRows(QModelIndex(), index, index); + list.removeAt(index); + emit endRemoveRows(); +} + +void QQuickViewTestUtils::QaimModel::removeItems(int index, int count) +{ + emit beginRemoveRows(QModelIndex(), index, index+count-1); + while (count--) + list.removeAt(index); + emit endRemoveRows(); +} + +void QQuickViewTestUtils::QaimModel::moveItem(int from, int to) +{ + emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); + list.move(from, to); + emit endMoveRows(); +} + +void QQuickViewTestUtils::QaimModel::moveItems(int from, int to, int count) +{ + emit beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to); + qquickmodelviewstestutil_move(from, to, count, &list); + emit endMoveRows(); +} + +void QQuickViewTestUtils::QaimModel::modifyItem(int idx, const QString &name, const QString &number) +{ + list[idx] = QPair<QString,QString>(name, number); + emit dataChanged(index(idx,0), index(idx,0)); +} + +void QQuickViewTestUtils::QaimModel::clear() +{ + int count = list.count(); + if (count > 0) { + beginRemoveRows(QModelIndex(), 0, count-1); + list.clear(); + endRemoveRows(); + } +} + +void QQuickViewTestUtils::QaimModel::reset() +{ + emit beginResetModel(); + emit endResetModel(); +} + +void QQuickViewTestUtils::QaimModel::resetItems(const QList<QPair<QString, QString> > &items) +{ + beginResetModel(); + list = items; + endResetModel(); +} + +class ScopedPrintable +{ + Q_DISABLE_COPY_MOVE(ScopedPrintable) + +public: + ScopedPrintable(const QString &string) : data(QTest::toString(string)) {} + ~ScopedPrintable() { delete[] data; } + + operator const char*() const { return data; } + +private: + const char *data; +}; + +void QQuickViewTestUtils::QaimModel::matchAgainst(const QList<QPair<QString, QString> > &other, const QString &error1, const QString &error2) { + for (int i=0; i<other.count(); i++) { + QVERIFY2(list.contains(other[i]), + ScopedPrintable(other[i].first + QLatin1Char(' ') + other[i].second + QLatin1Char(' ') + error1)); + } + for (int i=0; i<list.count(); i++) { + QVERIFY2(other.contains(list[i]), + ScopedPrintable(list[i].first + QLatin1Char(' ') + list[i].second + QLatin1Char(' ') + error2)); + } +} + + + +QQuickViewTestUtils::ListRange::ListRange() + : valid(false) +{ +} + +QQuickViewTestUtils::ListRange::ListRange(const ListRange &other) + : valid(other.valid) +{ + indexes = other.indexes; +} + +QQuickViewTestUtils::ListRange::ListRange(int start, int end) + : valid(true) +{ + for (int i=start; i<=end; i++) + indexes << i; +} + +QQuickViewTestUtils::ListRange::~ListRange() +{ +} + +QQuickViewTestUtils::ListRange QQuickViewTestUtils::ListRange::operator+(const ListRange &other) const +{ + if (other == *this) + return *this; + ListRange a(*this); + a.indexes.append(other.indexes); + return a; +} + +bool QQuickViewTestUtils::ListRange::operator==(const ListRange &other) const +{ + return QSet<int>(indexes.cbegin(), indexes.cend()) + == QSet<int>(other.indexes.cbegin(), other.indexes.cend()); +} + +bool QQuickViewTestUtils::ListRange::operator!=(const ListRange &other) const +{ + return !(*this == other); +} + +bool QQuickViewTestUtils::ListRange::isValid() const +{ + return valid; +} + +int QQuickViewTestUtils::ListRange::count() const +{ + return indexes.count(); +} + +QList<QPair<QString,QString> > QQuickViewTestUtils::ListRange::getModelDataValues(const QaimModel &model) +{ + QList<QPair<QString,QString> > data; + if (!valid) + return data; + for (int i=0; i<indexes.count(); i++) + data.append(qMakePair(model.name(indexes[i]), model.number(indexes[i]))); + return data; +} + +QQuickViewTestUtils::StressTestModel::StressTestModel() + : QAbstractListModel() + , m_rowCount(20) +{ + QTimer *t = new QTimer(this); + t->setInterval(500); + t->start(); + + connect(t, &QTimer::timeout, this, &StressTestModel::updateModel); +} + +int QQuickViewTestUtils::StressTestModel::rowCount(const QModelIndex &) const +{ + return m_rowCount; +} + +QVariant QQuickViewTestUtils::StressTestModel::data(const QModelIndex &, int) const +{ + return QVariant(); +} + +void QQuickViewTestUtils::StressTestModel::updateModel() +{ + if (m_rowCount > 10) { + for (int i = 0; i < 10; ++i) { + int rnum = QRandomGenerator::global()->bounded(m_rowCount); + beginRemoveRows(QModelIndex(), rnum, rnum); + m_rowCount--; + endRemoveRows(); + } + } + if (m_rowCount < 20) { + for (int i = 0; i < 10; ++i) { + int rnum = QRandomGenerator::global()->bounded(m_rowCount); + beginInsertRows(QModelIndex(), rnum, rnum); + m_rowCount++; + endInsertRows(); + } + } +} + +bool QQuickViewTestUtils::testVisibleItems(const QQuickItemViewPrivate *priv, bool *nonUnique, FxViewItem **failItem, int *expectedIdx) +{ + QHash<QQuickItem*, int> uniqueItems; + + int skip = 0; + for (int i = 0; i < priv->visibleItems.count(); ++i) { + FxViewItem *item = priv->visibleItems.at(i); + if (!item) { + *failItem = nullptr; + return false; + } +#if 0 + qDebug() << "\t" << item->index + << item->item + << item->position() + << (!item->item || QQuickItemPrivate::get(item->item)->culled ? "hidden" : "visible"); +#endif + if (item->index == -1) { + ++skip; + } else if (item->index != priv->visibleIndex + i - skip) { + *nonUnique = false; + *failItem = item; + *expectedIdx = priv->visibleIndex + i - skip; + return false; + } else if (uniqueItems.contains(item->item)) { + *nonUnique = true; + *failItem = item; + *expectedIdx = uniqueItems.find(item->item).value(); + return false; + } + + uniqueItems.insert(item->item, item->index); + } + + return true; +} + +namespace QQuickTouchUtils { + + /* QQuickWindow does event compression and only delivers events just + * before it is about to render the next frame. Since some tests + * rely on events being delivered immediately AND that no other + * event processing has occurred in the meanwhile, we flush the + * event manually and immediately. + */ + void flush(QQuickWindow *window) { + if (!window) + return; + QQuickDeliveryAgentPrivate *da = QQuickWindowPrivate::get(window)->deliveryAgentPrivate(); + if (!da || !da->delayedTouch) + return; + da->deliverDelayedTouchEvent(); + } + +} + +namespace QTest { + int Q_TESTLIB_EXPORT defaultMouseDelay(); +} + +namespace QQuickTest { + + /*! \internal + Initialize \a view, set \a url, center in available geometry, move mouse away if desired. + If \a errorMessage is given, QQuickView::errors() will be concatenated into it; + otherwise, the QWARN messages are generally enough to debug the test. + + Returns \c false if the view fails to load the QML. That should be fatal in most tests, + so normally the return value should be checked with QVERIFY. + */ + bool initView(QQuickView &view, const QUrl &url, bool moveMouseOut, QByteArray *errorMessage) + { + view.setSource(url); + while (view.status() == QQuickView::Loading) + QTest::qWait(10); + if (view.status() != QQuickView::Ready) { + if (errorMessage) { + for (const QQmlError &e : view.errors()) + errorMessage->append(e.toString().toLocal8Bit() + '\n'); + } + return false; + } + const QRect screenGeometry = view.screen()->availableGeometry(); + const QSize size = view.size(); + const QPoint offset = QPoint(size.width() / 2, size.height() / 2); + view.setFramePosition(screenGeometry.center() - offset); + #if QT_CONFIG(cursor) // Get the cursor out of the way. + if (moveMouseOut) + QCursor::setPos(view.geometry().topRight() + QPoint(100, 100)); + #else + Q_UNUSED(moveMouseOut); + #endif + return true; + } + + /*! \internal + Initialize \a view, set \a url, center in available geometry, move mouse away, + show the \a view, wait for it to be exposed, and verify that its rootObject is not null. + + Returns \c false if anything fails, which should be fatal in most tests. + The usual way to call this function is + \code + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("myitems.qml"))); + \endcode + */ + bool showView(QQuickView &view, const QUrl &url) + { + if (!initView(view, url)) + return false; + view.show(); + if (!QTest::qWaitForWindowExposed(&view)) + return false; + if (!view.rootObject()) + return false; + return true; + } + + // TODO maybe move the generic pointerPress/Move/Release functions to QTestLib later on + + static Qt::MouseButton pressedTabletButton = Qt::NoButton; + static Qt::KeyboardModifiers pressedTabletModifiers = Qt::NoModifier; + + void pointerPress(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &p, + Qt::MouseButton button, Qt::KeyboardModifiers modifiers) + { + switch (dev->type()) { + case QPointingDevice::DeviceType::Mouse: + case QPointingDevice::DeviceType::TouchPad: + QTest::mousePress(window, button, modifiers, p); + break; + case QPointingDevice::DeviceType::TouchScreen: + QTest::touchEvent(window, const_cast<QPointingDevice *>(dev)).press(pointId, p, window); + QQuickTouchUtils::flush(window); + break; + case QPointingDevice::DeviceType::Puck: + case QPointingDevice::DeviceType::Stylus: + case QPointingDevice::DeviceType::Airbrush: + QTest::lastMouseTimestamp += QTest::defaultMouseDelay(); + pressedTabletButton = button; + pressedTabletModifiers = modifiers; + QWindowSystemInterface::handleTabletEvent(window, QTest::lastMouseTimestamp, dev, p, window->mapToGlobal(p), + button, 0.8, 0, 0, 0, 0, 0, modifiers); + break; + default: + qWarning() << "can't send a press event from" << dev; + break; + } + } + + void pointerMove(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &p) + { + switch (dev->type()) { + case QPointingDevice::DeviceType::Mouse: + case QPointingDevice::DeviceType::TouchPad: + QTest::mouseMove(window, p); + break; + case QPointingDevice::DeviceType::TouchScreen: + QTest::touchEvent(window, const_cast<QPointingDevice *>(dev)).move(pointId, p, window); + QQuickTouchUtils::flush(window); + break; + case QPointingDevice::DeviceType::Puck: + case QPointingDevice::DeviceType::Stylus: + case QPointingDevice::DeviceType::Airbrush: + QTest::lastMouseTimestamp += QTest::defaultMouseDelay(); + QWindowSystemInterface::handleTabletEvent(window, QTest::lastMouseTimestamp, dev, p, window->mapToGlobal(p), + pressedTabletButton, 0, 0, 0, 0, 0, 0, pressedTabletModifiers); + break; + default: + qWarning() << "can't send a move event from" << dev; + break; + } + } + + void pointerRelease(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &p, + Qt::MouseButton button, Qt::KeyboardModifiers modifiers) + { + switch (dev->type()) { + case QPointingDevice::DeviceType::Mouse: + case QPointingDevice::DeviceType::TouchPad: + QTest::mouseRelease(window, button, modifiers, p); + break; + case QPointingDevice::DeviceType::TouchScreen: + QTest::touchEvent(window, const_cast<QPointingDevice *>(dev)).release(pointId, p, window); + QQuickTouchUtils::flush(window); + break; + case QPointingDevice::DeviceType::Puck: + case QPointingDevice::DeviceType::Stylus: + case QPointingDevice::DeviceType::Airbrush: + QTest::lastMouseTimestamp += QTest::defaultMouseDelay(); + QWindowSystemInterface::handleTabletEvent(window, QTest::lastMouseTimestamp, dev, p, window->mapToGlobal(p), + Qt::NoButton, 0, 0, 0, 0, 0, 0, modifiers); + break; + default: + qWarning() << "can't send a press event from" << dev; + break; + } + } + +} + +QT_END_NAMESPACE + +#include "moc_viewtestutils_p.cpp" diff --git a/src/quicktestutils/quick/viewtestutils_p.h b/src/quicktestutils/quick/viewtestutils_p.h new file mode 100644 index 00000000000..feedaef76fe --- /dev/null +++ b/src/quicktestutils/quick/viewtestutils_p.h @@ -0,0 +1,227 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 QQUICKVIEWTESTUTILS_P_H +#define QQUICKVIEWTESTUTILS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QAbstractListModel> +#include <QtQml/QQmlExpression> +#include <QtQuick/QQuickItem> + +QT_FORWARD_DECLARE_CLASS(QQuickView) +QT_FORWARD_DECLARE_CLASS(QQuickItemViewPrivate) +QT_FORWARD_DECLARE_CLASS(FxViewItem) + +QT_BEGIN_NAMESPACE + +namespace QQuickViewTestUtils +{ + QQuickView *createView(); + + void flick(QQuickView *window, const QPoint &from, const QPoint &to, int duration); + void centerOnScreen(QQuickView *window, const QSize &size); + void centerOnScreen(QQuickView *window); + void moveMouseAway(QQuickView *window); + void moveAndPress(QQuickView *window, const QPoint &position); + void moveAndRelease(QQuickView *window, const QPoint &position); + + QList<int> adjustIndexesForAddDisplaced(const QList<int> &indexes, int index, int count); + QList<int> adjustIndexesForMove(const QList<int> &indexes, int from, int to, int count); + QList<int> adjustIndexesForRemoveDisplaced(const QList<int> &indexes, int index, int count); + + struct ListChange { + enum { Inserted, Removed, Moved, SetCurrent, SetContentY, Polish } type; + int index; + int count; + int to; // Move + qreal pos; // setContentY + + static ListChange insert(int index, int count = 1) { ListChange c = { Inserted, index, count, -1, 0.0 }; return c; } + static ListChange remove(int index, int count = 1) { ListChange c = { Removed, index, count, -1, 0.0 }; return c; } + static ListChange move(int index, int to, int count) { ListChange c = { Moved, index, count, to, 0.0 }; return c; } + static ListChange setCurrent(int index) { ListChange c = { SetCurrent, index, -1, -1, 0.0 }; return c; } + static ListChange setContentY(qreal pos) { ListChange c = { SetContentY, -1, -1, -1, pos }; return c; } + static ListChange polish() { ListChange c = { Polish, -1, -1, -1, 0.0 }; return c; } + }; + + class QaimModel : public QAbstractListModel + { + Q_OBJECT + public: + enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 }; + + QaimModel(QObject *parent=0); + + int rowCount(const QModelIndex &parent=QModelIndex()) const override; + int columnCount(const QModelIndex &parent=QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override; + QHash<int,QByteArray> roleNames() const override; + + int count() const; + QString name(int index) const; + QString number(int index) const; + + Q_INVOKABLE void addItem(const QString &name, const QString &number); + void addItems(const QList<QPair<QString, QString> > &items); + void insertItem(int index, const QString &name, const QString &number); + void insertItems(int index, const QList<QPair<QString, QString> > &items); + + Q_INVOKABLE void removeItem(int index); + void removeItems(int index, int count); + + void moveItem(int from, int to); + void moveItems(int from, int to, int count); + + void modifyItem(int idx, const QString &name, const QString &number); + + void clear(); + void reset(); + void resetItems(const QList<QPair<QString, QString> > &items); + + void matchAgainst(const QList<QPair<QString, QString> > &other, const QString &error1, const QString &error2); + + using QAbstractListModel::dataChanged; + + int columns = 1; + + private: + QList<QPair<QString,QString> > list; + }; + + class ListRange + { + public: + ListRange(); + ListRange(const ListRange &other); + ListRange(int start, int end); + + ~ListRange(); + + ListRange operator+(const ListRange &other) const; + bool operator==(const ListRange &other) const; + bool operator!=(const ListRange &other) const; + + bool isValid() const; + int count() const; + + QList<QPair<QString,QString> > getModelDataValues(const QaimModel &model); + + QList<int> indexes; + bool valid; + }; + + template<typename T> + static void qquickmodelviewstestutil_move(int from, int to, int n, T *items) + { + if (from > to) { + // Only move forwards - flip if backwards moving + int tfrom = from; + int tto = to; + from = tto; + to = tto+n; + n = tfrom-tto; + } + + T replaced; + int i=0; + typename T::ConstIterator it=items->begin(); it += from+n; + for (; i<to-from; ++i,++it) + replaced.append(*it); + i=0; + it=items->begin(); it += from; + for (; i<n; ++i,++it) + replaced.append(*it); + typename T::ConstIterator f=replaced.begin(); + typename T::Iterator t=items->begin(); t += from; + for (; f != replaced.end(); ++f, ++t) + *t = *f; + } + + class StressTestModel : public QAbstractListModel + { + Q_OBJECT + + public: + + StressTestModel(); + + int rowCount(const QModelIndex &) const override; + QVariant data(const QModelIndex &, int) const override; + + public Q_SLOTS: + void updateModel(); + + private: + int m_rowCount; + }; + + [[nodiscard]] bool testVisibleItems(const QQuickItemViewPrivate *priv, + bool *nonUnique, FxViewItem **failItem, int *expectedIdx); +} + +namespace QQuickTouchUtils { + void flush(QQuickWindow *window); +} + +namespace QQuickTest { + [[nodiscard]] bool initView(QQuickView &v, const QUrl &url, + bool moveMouseOut = true, QByteArray *errorMessage = nullptr); + [[nodiscard]] bool showView(QQuickView &v, const QUrl &url); + + void pointerPress(const QPointingDevice *dev, QQuickWindow *window, + int pointId, const QPoint &p, Qt::MouseButton button = Qt::LeftButton, + Qt::KeyboardModifiers modifiers = Qt::NoModifier); + + void pointerMove(const QPointingDevice *dev, QQuickWindow *window, int pointId, + const QPoint &p); + + void pointerRelease(const QPointingDevice *dev, QQuickWindow *window, int pointId, + const QPoint &p, Qt::MouseButton button = Qt::LeftButton, + Qt::KeyboardModifiers modifiers = Qt::NoModifier); +} + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QQuickViewTestUtils::QaimModel*) +Q_DECLARE_METATYPE(QQuickViewTestUtils::ListChange) +Q_DECLARE_METATYPE(QList<QQuickViewTestUtils::ListChange>) +Q_DECLARE_METATYPE(QQuickViewTestUtils::ListRange) + + +#endif // QQUICKVIEWTESTUTILS_P_H diff --git a/src/quicktestutils/quick/visualtestutils.cpp b/src/quicktestutils/quick/visualtestutils.cpp new file mode 100644 index 00000000000..272002c7ac7 --- /dev/null +++ b/src/quicktestutils/quick/visualtestutils.cpp @@ -0,0 +1,228 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 "visualtestutils_p.h" + +#include <QtCore/QCoreApplication> +#include <QtCore/QDebug> +#include <QtQuick/QQuickItem> +#include <QtQuick/private/qquickitemview_p.h> +#include <QtQuickTest/QtQuickTest> + +QT_BEGIN_NAMESPACE + +QQuickItem *QQuickVisualTestUtils::findVisibleChild(QQuickItem *parent, const QString &objectName) +{ + QQuickItem *item = 0; + QList<QQuickItem*> items = parent->findChildren<QQuickItem*>(objectName); + for (int i = 0; i < items.count(); ++i) { + if (items.at(i)->isVisible() && !QQuickItemPrivate::get(items.at(i))->culled) { + item = items.at(i); + break; + } + } + return item; +} + +void QQuickVisualTestUtils::dumpTree(QQuickItem *parent, int depth) +{ + static QString padding = QStringLiteral(" "); + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i)); + if (!item) + continue; + qDebug() << padding.left(depth*2) << item; + dumpTree(item, depth+1); + } +} + +void QQuickVisualTestUtils::moveMouseAway(QQuickWindow *window) +{ +#if QT_CONFIG(cursor) // Get the cursor out of the way. + // Using "bottomRight() + QPoint(100, 100)" was causing issues on Ubuntu, + // where the window was positioned at the bottom right corner of the window + // (even after centering the window on the screen), so we use another position. + QCursor::setPos(window->frameGeometry().bottomLeft() + QPoint(-10, 10)); +#endif + + // make sure hover events from QQuickWindowPrivate::flushFrameSynchronousEvents() + // do not interfere with the tests + QEvent leave(QEvent::Leave); + QCoreApplication::sendEvent(window, &leave); +} + +void QQuickVisualTestUtils::centerOnScreen(QQuickWindow *window) +{ + const QRect screenGeometry = window->screen()->availableGeometry(); + const QPoint offset = QPoint(window->width() / 2, window->height() / 2); + window->setFramePosition(screenGeometry.center() - offset); +} + +bool QQuickVisualTestUtils::delegateVisible(QQuickItem *item) +{ + return item->isVisible() && !QQuickItemPrivate::get(item)->culled; +} + +/*! + \internal + + Compares \a ia with \a ib, returning \c true if the images are equal. + If they are not equal, \c false is returned and \a errorMessage is set. + + A custom compare function to avoid issues such as: + When running on native Nvidia graphics cards on linux, the + distance field glyph pixels have a measurable, but not visible + pixel error. This was GT-216 with the ubuntu "nvidia-319" driver package. + llvmpipe does not show the same issue. +*/ +bool QQuickVisualTestUtils::compareImages(const QImage &ia, const QImage &ib, QString *errorMessage) +{ + if (ia.size() != ib.size()) { + QDebug(errorMessage) << "Images are of different size:" << ia.size() << ib.size() + << "DPR:" << ia.devicePixelRatio() << ib.devicePixelRatio(); + return false; + } + if (ia.format() != ib.format()) { + QDebug(errorMessage) << "Images are of different formats:" << ia.format() << ib.format(); + return false; + } + + int w = ia.width(); + int h = ia.height(); + const int tolerance = 5; + for (int y=0; y<h; ++y) { + const uint *as= (const uint *) ia.constScanLine(y); + const uint *bs= (const uint *) ib.constScanLine(y); + for (int x=0; x<w; ++x) { + uint a = as[x]; + uint b = bs[x]; + + // No tolerance for error in the alpha. + if ((a & 0xff000000) != (b & 0xff000000) + || qAbs(qRed(a) - qRed(b)) > tolerance + || qAbs(qRed(a) - qRed(b)) > tolerance + || qAbs(qRed(a) - qRed(b)) > tolerance) { + QDebug(errorMessage) << "Mismatch at:" << x << y << ':' + << Qt::hex << Qt::showbase << a << b; + return false; + } + } + } + return true; +} + +/*! + \internal + + Finds the delegate at \c index belonging to \c itemView, using the given \c flags. + + If the view needs to be polished, the function will wait for it to be done before continuing, + and returns \c nullptr if the polish didn't happen. +*/ +QQuickItem *QQuickVisualTestUtils::findViewDelegateItem(QQuickItemView *itemView, int index, FindViewDelegateItemFlags flags) +{ + if (QQuickTest::qIsPolishScheduled(itemView)) { + if (!QQuickTest::qWaitForItemPolished(itemView)) { + qWarning() << "failed to polish" << itemView; + return nullptr; + } + } + + // Do this after the polish, just in case the count changes after a polish... + if (index <= -1 || index >= itemView->count()) { + qWarning() << "index" << index << "is out of bounds for" << itemView; + return nullptr; + } + + if (flags.testFlag(FindViewDelegateItemFlag::PositionViewAtIndex)) + itemView->positionViewAtIndex(index, QQuickItemView::Center); + + return itemView->itemAtIndex(index); +} + +QQuickVisualTestUtils::QQuickApplicationHelper::QQuickApplicationHelper(QQmlDataTest *testCase, + const QString &testFilePath, const QVariantMap &initialProperties, const QStringList &qmlImportPaths) +{ + for (const auto &path : qmlImportPaths) + engine.addImportPath(path); + + QQmlComponent component(&engine); + + component.loadUrl(testCase->testFileUrl(testFilePath)); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QObject *rootObject = component.createWithInitialProperties(initialProperties); + cleanup.reset(rootObject); + if (component.isError() || !rootObject) { + errorMessage = QString::fromUtf8("Failed to create window: %1").arg(component.errorString()).toUtf8(); + return; + } + + window = qobject_cast<QQuickWindow*>(rootObject); + if (!window) { + errorMessage = QString::fromUtf8("Root object %1 must be a QQuickWindow subclass").arg(QDebug::toString(window)).toUtf8(); + return; + } + + if (window->isVisible()) { + errorMessage = QString::fromUtf8("Expected window not to be visible, but it is").toUtf8(); + return; + } + + ready = true; +} + +QQuickVisualTestUtils::MnemonicKeySimulator::MnemonicKeySimulator(QWindow *window) + : m_window(window), m_modifiers(Qt::NoModifier) +{ +} + +void QQuickVisualTestUtils::MnemonicKeySimulator::press(Qt::Key key) +{ + // QTest::keyPress() but not generating the press event for the modifier key. + if (key == Qt::Key_Alt) + m_modifiers |= Qt::AltModifier; + QTest::simulateEvent(m_window, true, key, m_modifiers, QString(), false); +} + +void QQuickVisualTestUtils::MnemonicKeySimulator::release(Qt::Key key) +{ + // QTest::keyRelease() but not generating the release event for the modifier key. + if (key == Qt::Key_Alt) + m_modifiers &= ~Qt::AltModifier; + QTest::simulateEvent(m_window, false, key, m_modifiers, QString(), false); +} + +void QQuickVisualTestUtils::MnemonicKeySimulator::click(Qt::Key key) +{ + press(key); + release(key); +} + +QT_END_NAMESPACE + +#include "moc_visualtestutils_p.cpp" diff --git a/src/quicktestutils/quick/visualtestutils_p.h b/src/quicktestutils/quick/visualtestutils_p.h new file mode 100644 index 00000000000..18967f670ed --- /dev/null +++ b/src/quicktestutils/quick/visualtestutils_p.h @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 QQUICKVISUALTESTUTILS_P_H +#define QQUICKVISUALTESTUTILS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/qqmlexpression.h> +#include <QtQuick/private/qquickitem_p.h> + +#include <private/qmlutils_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickItemView; +class QQuickWindow; + +namespace QQuickVisualTestUtils +{ + QQuickItem *findVisibleChild(QQuickItem *parent, const QString &objectName); + + void dumpTree(QQuickItem *parent, int depth = 0); + + void moveMouseAway(QQuickWindow *window); + void centerOnScreen(QQuickWindow *window); + + [[nodiscard]] bool delegateVisible(QQuickItem *item); + + /* + Find an item with the specified objectName. If index is supplied then the + item must also evaluate the {index} expression equal to index + */ + template<typename T> + T *findItem(QQuickItem *parent, const QString &objectName, int index = -1) + { + const QMetaObject &mo = T::staticMetaObject; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i)); + if (!item) + continue; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + if (index != -1) { + QQmlContext *context = qmlContext(item); + if (!context->isValid()) + continue; + QQmlExpression e(context, item, "index"); + if (e.evaluate().toInt() == index) + return static_cast<T*>(item); + } else { + return static_cast<T*>(item); + } + } + item = findItem<T>(item, objectName, index); + if (item) + return static_cast<T*>(item); + } + + return 0; + } + + template<typename T> + QList<T*> findItems(QQuickItem *parent, const QString &objectName, bool visibleOnly = true) + { + QList<T*> items; + const QMetaObject &mo = T::staticMetaObject; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i)); + if (!item || (visibleOnly && (!item->isVisible() || QQuickItemPrivate::get(item)->culled))) + continue; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) + items.append(static_cast<T*>(item)); + items += findItems<T>(item, objectName); + } + + return items; + } + + template<typename T> + QList<T*> findItems(QQuickItem *parent, const QString &objectName, const QList<int> &indexes) + { + QList<T*> items; + for (int i=0; i<indexes.count(); i++) + items << qobject_cast<QQuickItem*>(findItem<T>(parent, objectName, indexes[i])); + return items; + } + + bool compareImages(const QImage &ia, const QImage &ib, QString *errorMessage); + + struct SignalMultiSpy : public QObject + { + Q_OBJECT + public: + QList<QObject *> senders; + QList<QByteArray> signalNames; + + template <typename Func1> + QMetaObject::Connection connectToSignal(const typename QtPrivate::FunctionPointer<Func1>::Object *obj, Func1 signal, + Qt::ConnectionType type = Qt::AutoConnection) + { + return connect(obj, signal, this, &SignalMultiSpy::receive, type); + } + + void clear() { + senders.clear(); + signalNames.clear(); + } + + public slots: + void receive() { + QMetaMethod m = sender()->metaObject()->method(senderSignalIndex()); + senders << sender(); + signalNames << m.name(); + } + }; + + enum class FindViewDelegateItemFlag { + None = 0x0, + PositionViewAtIndex = 0x01 + }; + Q_DECLARE_FLAGS(FindViewDelegateItemFlags, FindViewDelegateItemFlag) + + QQuickItem* findViewDelegateItem(QQuickItemView *itemView, int index, + FindViewDelegateItemFlags flags = FindViewDelegateItemFlag::PositionViewAtIndex); + + /*! + \internal + + Same as above except allows use in QTRY_* functions without having to call it again + afterwards to assign the delegate. + */ + template<typename T> + [[nodiscard]] bool findViewDelegateItem(QQuickItemView *itemView, int index, T &delegateItem, + FindViewDelegateItemFlags flags = FindViewDelegateItemFlag::PositionViewAtIndex) + { + delegateItem = qobject_cast<T>(findViewDelegateItem(itemView, index, flags)); + return delegateItem != nullptr; + } + + class QQuickApplicationHelper + { + public: + QQuickApplicationHelper(QQmlDataTest *testCase, const QString &testFilePath, + const QVariantMap &initialProperties = {}, + const QStringList &qmlImportPaths = {}); + + // Return a C-style string instead of QString because that's what QTest uses for error messages, + // so it saves code at the calling site. + inline const char *failureMessage() const + { + return errorMessage.constData(); + } + + QQmlEngine engine; + QScopedPointer<QObject> cleanup; + QQuickWindow *window = nullptr; + + bool ready = false; + // Store as a byte array so that we can return its raw data safely; + // using qPrintable() in failureMessage() will construct a throwaway QByteArray + // that is destroyed before the function returns. + QByteArray errorMessage; + }; + + class MnemonicKeySimulator + { + Q_DISABLE_COPY(MnemonicKeySimulator) + public: + explicit MnemonicKeySimulator(QWindow *window); + + void press(Qt::Key key); + void release(Qt::Key key); + void click(Qt::Key key); + + private: + QPointer<QWindow> m_window; + Qt::KeyboardModifiers m_modifiers; + }; +} + +#define QQUICK_VERIFY_POLISH(item) \ + QTRY_COMPARE(QQuickItemPrivate::get(item)->polishScheduled, false) + +QT_END_NAMESPACE + +#endif // QQUICKVISUALTESTUTILS_P_H diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index d0cc6f9048b..c593ca2a815 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -83,6 +83,11 @@ #include <QtQuick/qquickgraphicsdevice.h> #include <QtQuick/qquickrendertarget.h> +#include "private/qwidget_p.h" + +#include <QtWidgets/qgraphicsscene.h> +#include <QtWidgets/qgraphicsview.h> + QT_BEGIN_NAMESPACE QQuickWidgetOffscreenWindow::QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control) @@ -104,19 +109,80 @@ class QQuickWidgetOffscreenWindowPrivate: public QQuickWindowPrivate { } }; +class QQuickWidgetRenderControlPrivate; + class QQuickWidgetRenderControl : public QQuickRenderControl { + Q_DECLARE_PRIVATE(QQuickWidgetRenderControl) public: - QQuickWidgetRenderControl(QQuickWidget *quickwidget) : m_quickWidget(quickwidget) {} - QWindow *renderWindow(QPoint *offset) override { - if (offset) - *offset = m_quickWidget->mapTo(m_quickWidget->window(), QPoint()); - return m_quickWidget->window()->windowHandle(); + QQuickWidgetRenderControl(QQuickWidget *quickwidget); + QWindow *renderWindow(QPoint *offset) override; + +}; + +class QQuickWidgetRenderControlPrivate : public QQuickRenderControlPrivate +{ +public: + Q_DECLARE_PUBLIC(QQuickWidgetRenderControl) + QQuickWidgetRenderControlPrivate(QQuickWidgetRenderControl *renderControl, QQuickWidget *qqw) + : QQuickRenderControlPrivate(renderControl) + , m_quickWidget(qqw) + { + } + + bool isRenderWindow(const QWindow *w) override { +#if QT_CONFIG(graphicsview) + QWidgetPrivate *widgetd = QWidgetPrivate::get(m_quickWidget); + auto *proxy = (widgetd && widgetd->extra) ? widgetd->extra->proxyWidget : nullptr; + auto *scene = proxy ? proxy->scene() : nullptr; + if (scene) { + for (const auto &view : scene->views()) { + if (view->window()->windowHandle() == w) + return true; + } + } + + return m_quickWidget->window()->windowHandle() == w; +#endif } -private: QQuickWidget *m_quickWidget; }; +QQuickWidgetRenderControl::QQuickWidgetRenderControl(QQuickWidget *quickWidget) + : QQuickRenderControl(*(new QQuickWidgetRenderControlPrivate(this, quickWidget)), nullptr) +{ +} + +QWindow *QQuickWidgetRenderControl::renderWindow(QPoint *offset) +{ + Q_D(QQuickWidgetRenderControl); + if (offset) + *offset = d->m_quickWidget->mapTo(d->m_quickWidget->window(), QPoint()); + + QWindow *result = nullptr; +#if QT_CONFIG(graphicsview) + QWidgetPrivate *widgetd = QWidgetPrivate::get(d->m_quickWidget); + if (widgetd->extra) { + if (auto proxy = widgetd->extra->proxyWidget) { + auto scene = proxy->scene(); + if (scene) { + const auto views = scene->views(); + if (!views.isEmpty()) { + // Get the first QGV containing the proxy. Not ideal, but the callers + // of this function aren't prepared to handle more than one render window. + auto candidateView = views.first(); + result = candidateView->window()->windowHandle(); + } + } + } + } +#endif + if (!result) + result = d->m_quickWidget->window()->windowHandle(); + + return result; +} + void QQuickWidgetPrivate::initOffscreenWindow() { Q_Q(QQuickWidget); @@ -492,19 +558,24 @@ QImage QQuickWidgetPrivate::grabFramebuffer() size of the view. Alternatively the resizeMode may be set to SizeRootObjectToView which will resize the view to the size of the root object. - \note QQuickWidget is an alternative to using QQuickView and QWidget::createWindowContainer(). + \section1 Performance Considerations + + QQuickWidget is an alternative to using QQuickView and QWidget::createWindowContainer(). The restrictions on stacking order do not apply, making QQuickWidget the more flexible alternative, behaving more like an ordinary widget. - \note However, the above mentioned advantages come at the expense of performance. - Unlike QQuickWindow and QQuickView, QQuickWidget requires rendering into OpenGL + However, the above mentioned advantages come at the expense of performance: + \list + + \li Unlike QQuickWindow and QQuickView, QQuickWidget requires rendering into OpenGL framebuffer objects, which needs to be enforced by calling - QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi) at startup. + QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL) at startup. This will naturally carry a minor performance hit. - \note Using QQuickWidget disables the threaded render loop on all platforms. This means that - some of the benefits of threaded rendering, for example \l Animator classes and vsync driven - animations, will not be available. + \li Using QQuickWidget disables the \l{threaded_render_loop}{threaded render loop} on all + platforms. This means that some of the benefits of threaded rendering, for example + \l Animator classes and vsync driven animations, will not be available. + \endlist \note Avoid calling winId() on a QQuickWidget. This function triggers the creation of a native window, resulting in reduced performance and possibly rendering glitches. The @@ -593,6 +664,7 @@ QQuickWidget::QQuickWidget(QWidget *parent) { setMouseTracking(true); setFocusPolicy(Qt::StrongFocus); + setAttribute(Qt::WA_AcceptTouchEvents); d_func()->init(); } @@ -1394,6 +1466,8 @@ void QQuickWidget::mouseMoveEvent(QMouseEvent *e) // top-level window always. QMouseEvent mappedEvent(e->type(), e->position(), e->position(), e->globalPosition(), e->button(), e->buttons(), e->modifiers(), e->source()); + // It's not just the timestamp but also the globalPressPosition, velocity etc. + mappedEvent.setTimestamp(e->timestamp()); QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent); e->setAccepted(mappedEvent.isAccepted()); } @@ -1409,10 +1483,12 @@ void QQuickWidget::mouseDoubleClickEvent(QMouseEvent *e) // See QTBUG-25831 QMouseEvent pressEvent(QEvent::MouseButtonPress, e->position(), e->position(), e->globalPosition(), e->button(), e->buttons(), e->modifiers(), e->source()); + pressEvent.setTimestamp(e->timestamp()); QCoreApplication::sendEvent(d->offscreenWindow, &pressEvent); e->setAccepted(pressEvent.isAccepted()); QMouseEvent mappedEvent(e->type(), e->position(), e->position(), e->globalPosition(), e->button(), e->buttons(), e->modifiers(), e->source()); + mappedEvent.setTimestamp(e->timestamp()); QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent); } @@ -1472,6 +1548,7 @@ void QQuickWidget::mousePressEvent(QMouseEvent *e) QMouseEvent mappedEvent(e->type(), e->position(), e->position(), e->globalPosition(), e->button(), e->buttons(), e->modifiers(), e->source()); + mappedEvent.setTimestamp(e->timestamp()); QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent); e->setAccepted(mappedEvent.isAccepted()); } @@ -1485,6 +1562,7 @@ void QQuickWidget::mouseReleaseEvent(QMouseEvent *e) QMouseEvent mappedEvent(e->type(), e->position(), e->position(), e->globalPosition(), e->button(), e->buttons(), e->modifiers(), e->source()); + mappedEvent.setTimestamp(e->timestamp()); QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent); e->setAccepted(mappedEvent.isAccepted()); } @@ -1567,9 +1645,23 @@ bool QQuickWidget::event(QEvent *e) case QEvent::TouchBegin: case QEvent::TouchEnd: case QEvent::TouchUpdate: - case QEvent::TouchCancel: + case QEvent::TouchCancel: { // Touch events only have local and global positions, no need to map. - return QCoreApplication::sendEvent(d->offscreenWindow, e); + bool res = QCoreApplication::sendEvent(d->offscreenWindow, e); + if (e->isAccepted() && e->type() == QEvent::TouchBegin) { + // If the TouchBegin got accepted, then make sure all points that have + // an exclusive grabber are also accepted so that the widget code for + // delivering touch events make this widget an implicit grabber of those + // points. + QPointerEvent *pointerEvent = static_cast<QPointerEvent *>(e); + auto deliveredPoints = pointerEvent->points(); + for (auto &point : deliveredPoints) { + if (pointerEvent->exclusiveGrabber(point)) + point.setAccepted(true); + } + } + return res; + } case QEvent::FocusAboutToChange: return QCoreApplication::sendEvent(d->offscreenWindow, e); @@ -1837,4 +1929,6 @@ Q_CONSTRUCTOR_FUNCTION(qt_registerDefaultPlatformBackingStoreOpenGLSupport); QT_END_NAMESPACE +#include "moc_qquickwidget_p.cpp" + #include "moc_qquickwidget.cpp" diff --git a/sync.profile b/sync.profile index 23b01bdd191..362332c63d8 100644 --- a/sync.profile +++ b/sync.profile @@ -6,6 +6,7 @@ "QtQuickWidgets" => "$basedir/src/quickwidgets", "QtQuickParticles" => "$basedir/src/particles", "QtQuickTest" => "$basedir/src/qmltest", + "QtQuickTestUtils" => "$basedir/src/quicktestutils", "QtPacketProtocol" => "$basedir/src/plugins/qmltooling/packetprotocol", "QtQmlDebug" => "$basedir/src/qmldebug", "QtQmlModels" => "$basedir/src/qmlmodels", @@ -20,7 +21,14 @@ "QtLabsWavefrontMesh" => "$basedir/src/labs/wavefrontmesh", "QtLabsQmlModels" => "$basedir/src/labs/models", "QtLabsSharedImage" => "$basedir/src/labs/sharedimage", - "QtQmlXmlListModel" => "$basedir/src/qmlxmllistmodel" + "QtQmlXmlListModel" => "$basedir/src/qmlxmllistmodel", + "QtQuickControls2" => "$basedir/src/quickcontrols2", + "QtQuickControls2Impl" => "$basedir/src/quickcontrols2impl", + "QtQuickControlsTestUtils" => "$basedir/src/quickcontrolstestutils", + "QtQuickDialogs2" => "$basedir/src/quickdialogs2/quickdialogs2", + "QtQuickDialogs2Utils" => "$basedir/src/quickdialogs2/quickdialogs2utils", + "QtQuickDialogs2QuickImpl" => "$basedir/src/quickdialogs2/quickdialogs2quickimpl", + "QtQuickTemplates2" => "$basedir/src/quicktemplates2" ); %inject_headers = ( "$basedir/src/qml" => [ "^qqmljsgrammar_p.h", "^qqmljsparser_p.h", "^qml_compile_hash_p.h" ], diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt index aad37dcee03..d9730fbb58e 100644 --- a/tests/auto/CMakeLists.txt +++ b/tests/auto/CMakeLists.txt @@ -1,18 +1,24 @@ -# Generated from auto.pro. +add_subdirectory(cmake) if(TARGET Qt::Quick) add_subdirectory(qml) add_subdirectory(quick) +endif() + +# Limit set of tests to run for static Qt builds. +if(QT_BUILD_MINIMAL_STATIC_TESTS) + return() +endif() + +if(TARGET Qt::Quick) add_subdirectory(quicktest) endif() -add_subdirectory(core) +if (TARGET Qt::QuickTest) + add_subdirectory(core) +endif() add_subdirectory(qmldevtools) -# special case begin -# add_subdirectory(cmake) -# add_subdirectory(installed_cmake) -# special case end add_subdirectory(toolsupport) -if(NOT UIKIT) +if(NOT UIKIT AND NOT ANDROID AND NOT QNX) # FIXME: QTBUG-92591 QTBUG-100202 add_subdirectory(qmltest) endif() if(TARGET Qt::Quick) @@ -21,6 +27,10 @@ endif() if(TARGET Qt::QuickWidgets) add_subdirectory(quickwidgets) endif() -if(TARGET Qt::QmlDom) +if(TARGET Qt::QmlDomPrivate AND NOT CMAKE_CROSSCOMPILING) add_subdirectory(qmldom) endif() +if(TARGET Qt::QuickTemplates2) + add_subdirectory(quickcontrols2) + add_subdirectory(quickdialogs) +endif() diff --git a/tests/auto/bic/data/QtQml.6.2.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQml.6.2.0.linux-gcc-amd64.txt new file mode 100644 index 00000000000..e6971a0cea1 --- /dev/null +++ b/tests/auto/bic/data/QtQml.6.2.0.linux-gcc-amd64.txt @@ -0,0 +1,6952 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f6f4598f300) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f6f459dcae0) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f6f459dcd20) 0 empty + +Class std::__do_is_implicitly_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_implicitly_default_constructible_impl (0x0x7f6f45a0be40) 0 empty + +Class std::__make_unsigned_selector_base + size=1 align=1 + base size=0 base align=1 +std::__make_unsigned_selector_base (0x0x7f6f43467660) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f6f434e2480) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f6f434e2540) 0 empty + +Class std::__invoke_memfun_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_ref (0x0x7f6f434e2a20) 0 empty + +Class std::__invoke_memfun_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_deref (0x0x7f6f434e2a80) 0 empty + +Class std::__invoke_memobj_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_ref (0x0x7f6f434e2ae0) 0 empty + +Class std::__invoke_memobj_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_deref (0x0x7f6f434e2b40) 0 empty + +Class std::__invoke_other + size=1 align=1 + base size=0 base align=1 +std::__invoke_other (0x0x7f6f434e2ba0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f6f434e2c60) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f6f434e2d20) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f6f434e2de0) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f6f434e2ea0) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f6f43519240) 0 empty + +Class std::__swappable_details::__do_is_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_swappable_impl (0x0x7f6f435195a0) 0 empty + +Class std::__swappable_details::__do_is_nothrow_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_nothrow_swappable_impl (0x0x7f6f43519600) 0 empty + +Class std::__swappable_with_details::__do_is_swappable_with_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_with_details::__do_is_swappable_with_impl (0x0x7f6f435198a0) 0 empty + +Class std::__swappable_with_details::__do_is_nothrow_swappable_with_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_with_details::__do_is_nothrow_swappable_with_impl (0x0x7f6f43519900) 0 empty + +Class std::__nonesuch + size=1 align=1 + base size=0 base align=1 +std::__nonesuch (0x0x7f6f43568180) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f6f435ae720) 0 empty + +Class std::__nonesuch_no_braces + size=1 align=1 + base size=1 base align=1 +std::__nonesuch_no_braces (0x0x7f6f43546d00) 0 empty + std::__nonesuch (0x0x7f6f435aec00) 0 empty + +Class std::in_place_t + size=1 align=1 + base size=0 base align=1 +std::in_place_t (0x0x7f6f43633960) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f6f43633c60) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f6f43633cc0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f6f4329ca20) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f6f4329ca80) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f6f43655270) 0 empty + std::input_iterator_tag (0x0x7f6f4329cae0) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f6f436552d8) 0 empty + std::forward_iterator_tag (0x0x7f6f43655340) 0 empty + std::input_iterator_tag (0x0x7f6f4329cb40) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f6f436553a8) 0 empty + std::bidirectional_iterator_tag (0x0x7f6f43655410) 0 empty + std::forward_iterator_tag (0x0x7f6f43655478) 0 empty + std::input_iterator_tag (0x0x7f6f4329cba0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f6f4334e8a0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f6f4334e9c0) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f6f4334ecc0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f6f4337d000) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f6f4337d120) 0 empty + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f6f4340c900) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f6f4340cc00) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f6f4340cc60) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f6f4340cd20) 0 + +Class __pthread_internal_slist + size=8 align=8 + base size=8 base align=8 +__pthread_internal_slist (0x0x7f6f4340cd80) 0 + +Class __pthread_mutex_s + size=40 align=8 + base size=40 base align=8 +__pthread_mutex_s (0x0x7f6f4340cde0) 0 + +Class __pthread_rwlock_arch_t + size=56 align=8 + base size=56 base align=8 +__pthread_rwlock_arch_t (0x0x7f6f4340ce40) 0 + +Class __pthread_cond_s + size=48 align=8 + base size=48 base align=8 +__pthread_cond_s (0x0x7f6f4340cea0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f6f43449180) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f6f43449420) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f6f43449480) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f6f430fe240) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f6f43655820) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16) + std::exception (0x0x7f6f430fe420) 0 nearly-empty + primary-for std::bad_exception (0x0x7f6f43655820) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f6f430fe600) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f6f43655888) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16) + std::exception (0x0x7f6f430fe9c0) 0 nearly-empty + primary-for std::bad_cast (0x0x7f6f43655888) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f6f436558f0) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16) + std::exception (0x0x7f6f430feba0) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f6f436558f0) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f6f430fed80) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f6f4313b300) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f6f43655958) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16) + std::exception (0x0x7f6f4313b9c0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f6f43655958) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f6f436559c0) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16) + std::bad_alloc (0x0x7f6f43655a28) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f6f436559c0) + std::exception (0x0x7f6f4313bba0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f6f43655a28) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f6f4313bd80) 0 empty + +Class std::__allocator_traits_base + size=1 align=1 + base size=0 base align=1 +std::__allocator_traits_base (0x0x7f6f43173000) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f6f431ee780) 0 empty + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f6f42dcbb40) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f6f42dcbc00) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f6f42e3dae0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f6f42e3dba0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f6f42e3dc00) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f6f42e3dc60) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f6f42e3dcc0) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f6f42e3dde0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f6f42e3de40) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f6f42aff4e0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f6f42aff660) 0 empty + +Class _G_fpos_t + size=16 align=8 + base size=16 base align=8 +_G_fpos_t (0x0x7f6f457204e0) 0 + +Class _G_fpos64_t + size=16 align=8 + base size=16 base align=8 +_G_fpos64_t (0x0x7f6f45720540) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f6f457205a0) 0 + +Class _IO_cookie_io_functions_t + size=32 align=8 + base size=32 base align=8 +_IO_cookie_io_functions_t (0x0x7f6f45720600) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f6f42339d80) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f6f422f29c0) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16) + std::exception (0x0x7f6f42339e40) 0 nearly-empty + primary-for std::logic_error (0x0x7f6f422f29c0) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f6f422f2a28) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16) + std::logic_error (0x0x7f6f422f2a90) 0 + primary-for std::domain_error (0x0x7f6f422f2a28) + std::exception (0x0x7f6f42339ea0) 0 nearly-empty + primary-for std::logic_error (0x0x7f6f422f2a90) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f6f422f2af8) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16) + std::logic_error (0x0x7f6f422f2b60) 0 + primary-for std::invalid_argument (0x0x7f6f422f2af8) + std::exception (0x0x7f6f42339f00) 0 nearly-empty + primary-for std::logic_error (0x0x7f6f422f2b60) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f6f422f2bc8) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16) + std::logic_error (0x0x7f6f422f2c30) 0 + primary-for std::length_error (0x0x7f6f422f2bc8) + std::exception (0x0x7f6f42339f60) 0 nearly-empty + primary-for std::logic_error (0x0x7f6f422f2c30) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f6f422f2c98) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16) + std::logic_error (0x0x7f6f422f2d00) 0 + primary-for std::out_of_range (0x0x7f6f422f2c98) + std::exception (0x0x7f6f42397000) 0 nearly-empty + primary-for std::logic_error (0x0x7f6f422f2d00) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f6f422f2d68) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16) + std::exception (0x0x7f6f42397060) 0 nearly-empty + primary-for std::runtime_error (0x0x7f6f422f2d68) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f6f422f2dd0) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16) + std::runtime_error (0x0x7f6f422f2e38) 0 + primary-for std::range_error (0x0x7f6f422f2dd0) + std::exception (0x0x7f6f423970c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f6f422f2e38) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f6f422f2ea0) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16) + std::runtime_error (0x0x7f6f422f2f08) 0 + primary-for std::overflow_error (0x0x7f6f422f2ea0) + std::exception (0x0x7f6f42397120) 0 nearly-empty + primary-for std::runtime_error (0x0x7f6f422f2f08) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f6f422f2f70) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16) + std::runtime_error (0x0x7f6f423b3000) 0 + primary-for std::underflow_error (0x0x7f6f422f2f70) + std::exception (0x0x7f6f42397180) 0 nearly-empty + primary-for std::runtime_error (0x0x7f6f423b3000) + +Class std::__erased_type + size=1 align=1 + base size=0 base align=1 +std::__erased_type (0x0x7f6f423de480) 0 empty + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f6f423de4e0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f6f423de660) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f6f423de720) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f6f423b3270) 0 + std::__uses_alloc_base (0x0x7f6f423de6c0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f6f4214cd20) 0 empty + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f6f42200680) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16) + std::exception (0x0x7f6f4221e420) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f6f42200680) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f6f4221e4e0) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f6f4221e540) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f6f4221e840) 0 + +Class std::__detail::_Identity + size=1 align=1 + base size=0 base align=1 +std::__detail::_Identity (0x0x7f6f41ef86c0) 0 empty + +Class std::__detail::_Select1st + size=1 align=1 + base size=0 base align=1 +std::__detail::_Select1st (0x0x7f6f41ef8780) 0 empty + +Class std::__detail::_Hash_node_base + size=8 align=8 + base size=8 base align=8 +std::__detail::_Hash_node_base (0x0x7f6f41ef8c60) 0 + +Class std::__detail::_Mod_range_hashing + size=1 align=1 + base size=0 base align=1 +std::__detail::_Mod_range_hashing (0x0x7f6f41f1fae0) 0 empty + +Class std::__detail::_Default_ranged_hash + size=1 align=1 + base size=0 base align=1 +std::__detail::_Default_ranged_hash (0x0x7f6f41f1fba0) 0 empty + +Class std::__detail::_Prime_rehash_policy + size=16 align=8 + base size=16 base align=8 +std::__detail::_Prime_rehash_policy (0x0x7f6f41f1fc00) 0 + +Class std::__detail::_Mask_range_hashing + size=1 align=1 + base size=0 base align=1 +std::__detail::_Mask_range_hashing (0x0x7f6f41f48000) 0 empty + +Class std::__detail::_Power2_rehash_policy + size=16 align=8 + base size=16 base align=8 +std::__detail::_Power2_rehash_policy (0x0x7f6f41f48120) 0 + +Class std::__detail::_Equality_base + size=1 align=1 + base size=0 base align=1 +std::__detail::_Equality_base (0x0x7f6f41d351e0) 0 empty + +Class std::_Enable_default_constructor_tag + size=1 align=1 + base size=0 base align=1 +std::_Enable_default_constructor_tag (0x0x7f6f41d35a80) 0 empty + +Class std::nullopt_t + size=1 align=1 + base size=0 base align=1 +std::nullopt_t (0x0x7f6f41d72480) 0 empty + +Vtable for std::bad_optional_access +std::bad_optional_access::_ZTVSt19bad_optional_access: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt19bad_optional_access) +16 (int (*)(...))std::bad_optional_access::~bad_optional_access +24 (int (*)(...))std::bad_optional_access::~bad_optional_access +32 (int (*)(...))std::bad_optional_access::what + +Class std::bad_optional_access + size=8 align=8 + base size=8 base align=8 +std::bad_optional_access (0x0x7f6f41d465b0) 0 nearly-empty + vptr=((& std::bad_optional_access::_ZTVSt19bad_optional_access) + 16) + std::exception (0x0x7f6f41d726c0) 0 nearly-empty + primary-for std::bad_optional_access (0x0x7f6f41d465b0) + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f6f41842060) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f6f417d20d0) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f6f418427e0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f6f417d21a0) 0 + std::_Bit_iterator_base (0x0x7f6f417d2208) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f6f41842d80) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f6f417d22d8) 0 + std::_Bit_iterator_base (0x0x7f6f417d2340) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f6f414775a0) 0 empty + +Class __pstl::execution::v1::sequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::sequenced_policy (0x0x7f6f41653a80) 0 empty + +Class __pstl::execution::v1::parallel_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::parallel_policy (0x0x7f6f41653c00) 0 empty + +Class __pstl::execution::v1::parallel_unsequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::parallel_unsequenced_policy (0x0x7f6f41653d80) 0 empty + +Class __pstl::execution::v1::unsequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::unsequenced_policy (0x0x7f6f41653f00) 0 empty + +Class std::__detail::__variant::__variant_cookie + size=1 align=1 + base size=0 base align=1 +std::__detail::__variant::__variant_cookie (0x0x7f6f4138ba80) 0 empty + +Class std::__detail::__variant::__variant_idx_cookie + size=1 align=1 + base size=0 base align=1 +std::__detail::__variant::__variant_idx_cookie (0x0x7f6f4138bae0) 0 empty + +Class std::monostate + size=1 align=1 + base size=0 base align=1 +std::monostate (0x0x7f6f410635a0) 0 empty + +Vtable for std::bad_variant_access +std::bad_variant_access::_ZTVSt18bad_variant_access: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt18bad_variant_access) +16 (int (*)(...))std::bad_variant_access::~bad_variant_access +24 (int (*)(...))std::bad_variant_access::~bad_variant_access +32 (int (*)(...))std::bad_variant_access::what + +Class std::bad_variant_access + size=16 align=8 + base size=16 base align=8 +std::bad_variant_access (0x0x7f6f413dc6e8) 0 + vptr=((& std::bad_variant_access::_ZTVSt18bad_variant_access) + 16) + std::exception (0x0x7f6f4108fae0) 0 nearly-empty + primary-for std::bad_variant_access (0x0x7f6f413dc6e8) + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f6f41149540) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f6f411495a0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f6f41149840) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f6f4118a060) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f6f411c6180) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f6f40e5a420) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f6f411ed9c0) 0 + std::__atomic_flag_base (0x0x7f6f40e5a480) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f6f40dc8c98) 0 + QAtomicInteger<int> (0x0x7f6f40dc8d00) 0 + QBasicAtomicInteger<int> (0x0x7f6f40de13c0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f6f40266660) 0 empty + +Class QKeyCombination + size=4 align=4 + base size=4 base align=4 +QKeyCombination (0x0x7f6f402666c0) 0 + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f6f4031c9c0) 0 + +Class QMethodRawArguments + size=8 align=8 + base size=8 base align=8 +QMethodRawArguments (0x0x7f6f4035f120) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f6f4035f180) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f6f4035e138) 0 + QGenericArgument (0x0x7f6f4035f420) 0 + +Class QMetaObject::SuperData + size=8 align=8 + base size=8 base align=8 +QMetaObject::SuperData (0x0x7f6f4035f900) 0 + +Class QMetaObject::Data + size=56 align=8 + base size=56 base align=8 +QMetaObject::Data (0x0x7f6f4035f960) 0 + +Class QMetaObject + size=56 align=8 + base size=56 base align=8 +QMetaObject (0x0x7f6f4035f8a0) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f6f403ac300) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f6f403d6d20) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f6f40400720) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f6f400d8240) 0 + +Class QArrayData + size=16 align=8 + base size=16 base align=8 +QArrayData (0x0x7f6f400d85a0) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f6f4019b060) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f6f4019b180) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f6f4019b540) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f6f4019b7e0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f6f4019b9c0) 0 + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f6f401e5ae0) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f6f401e5e40) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f6f4023e660) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f6f401f8618) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16) + std::runtime_error (0x0x7f6f401f8680) 0 + primary-for std::system_error (0x0x7f6f401f8618) + std::exception (0x0x7f6f3fe66240) 0 nearly-empty + primary-for std::runtime_error (0x0x7f6f401f8680) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f6f401f89c0) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16) + std::system_error (0x0x7f6f401f8a28) 0 + primary-for std::ios_base::failure (0x0x7f6f401f89c0) + std::runtime_error (0x0x7f6f401f8a90) 0 + primary-for std::system_error (0x0x7f6f401f8a28) + std::exception (0x0x7f6f3fe9d9c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f6f401f8a90) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f6f3fe9da20) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f6f3fe9da80) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f6f3fe9dae0) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f6f3fe9d960) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f6f3ff56720) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f6f4000fa20) 0 empty + +VTT for std::basic_ostream<char> +std::basic_ostream<char>::_ZTTSo: 2 entries +0 ((& std::basic_ostream<char>::_ZTVSo) + 24) +8 ((& std::basic_ostream<char>::_ZTVSo) + 64) + +VTT for std::basic_ostream<wchar_t> +std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64) + +VTT for std::basic_istream<char> +std::basic_istream<char>::_ZTTSi: 2 entries +0 ((& std::basic_istream<char>::_ZTVSi) + 24) +8 ((& std::basic_istream<char>::_ZTVSi) + 64) + +VTT for std::basic_istream<wchar_t> +std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64) + +Construction vtable for std::basic_istream<char> (0x0x7f6f3fb95618 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd0_Si: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream<char> (0x0x7f6f3fb956e8 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd16_So: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::basic_iostream<char> +std::basic_iostream<char>::_ZTTSd: 7 entries +0 ((& std::basic_iostream<char>::_ZTVSd) + 24) +8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24) +16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64) +24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24) +32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64) +40 ((& std::basic_iostream<char>::_ZTVSd) + 104) +48 ((& std::basic_iostream<char>::_ZTVSd) + 64) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f6f3fb95c30 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f6f3fb95d00 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7 entries +0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24) +16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64) +24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24) +32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64) +40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104) +48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64) + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f6f3fc06068) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16) + std::exception (0x0x7f6f3fc04420) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f6f3fc06068) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f6f3fc060d0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16) + std::exception (0x0x7f6f3fc04540) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f6f3fc060d0) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f6f3fc06138) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16) + std::exception (0x0x7f6f3fc04660) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f6f3fc06138) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f6f3fc06208) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16) + std::exception (0x0x7f6f3fc04780) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f6f3fc06208) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f6f3fc2c060) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f6f3fc2c3c0) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f6f3fc2c6c0) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f6f3fc2ca20) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f6f3fc06340) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16) + std::exception (0x0x7f6f3f8df1e0) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f6f3fc06340) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f6f3f91bf60) 0 empty + +Class std::__sp_array_delete + size=1 align=1 + base size=0 base align=1 +std::__sp_array_delete (0x0x7f6f3f9474e0) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f6f3f68d300) 0 + +Class QByteArrayView + size=16 align=8 + base size=16 base align=8 +QByteArrayView (0x0x7f6f3f7e8660) 0 + +Class QByteArray + size=24 align=8 + base size=24 base align=8 +QByteArray (0x0x7f6f3f4e9780) 0 + +Class QByteArray::FromBase64Result + size=32 align=8 + base size=28 base align=8 +QByteArray::FromBase64Result (0x0x7f6f3f330b40) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f6f3f3bcae0) 0 + +Class QChar::fromUcs4(char32_t)::R + size=4 align=2 + base size=4 base align=2 +QChar::fromUcs4(char32_t)::R (0x0x7f6f3f142a20) 0 + +Class QtPrivate::hide_char8_t + size=1 align=1 + base size=0 base align=1 +QtPrivate::hide_char8_t (0x0x7f6f3f142e40) 0 empty + +Class QtPrivate::wrap_char + size=1 align=1 + base size=0 base align=1 +QtPrivate::wrap_char (0x0x7f6f3f142ea0) 0 empty + +Class QAnyStringView + size=16 align=8 + base size=16 base align=8 +QAnyStringView (0x0x7f6f3f1c4c00) 0 + +Class QStringTokenizerBaseBase::tokenizer_state + size=24 align=8 + base size=24 base align=8 +QStringTokenizerBaseBase::tokenizer_state (0x0x7f6f3eeb5de0) 0 + +Class QStringTokenizerBaseBase + size=8 align=4 + base size=8 base align=4 +QStringTokenizerBaseBase (0x0x7f6f3eeb5d80) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f6f3eef8cc0) 0 + +Class QString + size=24 align=8 + base size=24 base align=8 +QString (0x0x7f6f3ec63f60) 0 + +Class QtPrivate::ArgBase + size=1 align=1 + base size=1 base align=1 +QtPrivate::ArgBase (0x0x7f6f3e8882a0) 0 + +Class QtPrivate::QStringViewArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QStringViewArg (0x0x7f6f3e876208) 0 + QtPrivate::ArgBase (0x0x7f6f3e888300) 0 + +Class QtPrivate::QLatin1StringArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QLatin1StringArg (0x0x7f6f3e8762d8) 0 + QtPrivate::ArgBase (0x0x7f6f3e888540) 0 + +Class QHashSeed + size=8 align=8 + base size=8 base align=8 +QHashSeed (0x0x7f6f3e8cbd80) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f6f3e904d20) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f6f3e904de0) 0 empty + +Class QStringMatcher + size=312 align=8 + base size=312 base align=8 +QStringMatcher (0x0x7f6f3e740300) 0 + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f6f3e7df480) 0 empty + +Class QtPrivate::CompareAgainstLiteralZero + size=1 align=1 + base size=0 base align=1 +QtPrivate::CompareAgainstLiteralZero (0x0x7f6f3e8011e0) 0 empty + +Class QPartialOrdering + size=1 align=1 + base size=1 base align=1 +QPartialOrdering (0x0x7f6f3e801420) 0 + +Class QIODeviceBase + size=1 align=1 + base size=0 base align=1 +QIODeviceBase (0x0x7f6f3e482f00) 0 empty + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f6f3e998ea0) 0 + QIODeviceBase (0x0x7f6f3e482f60) 0 empty + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f6f3e4d2120) 0 + +Class QtMetaContainerPrivate::QMetaContainerInterface + size=120 align=8 + base size=120 base align=8 +QtMetaContainerPrivate::QMetaContainerInterface (0x0x7f6f3e57d6c0) 0 + +Class QtMetaContainerPrivate::QMetaSequenceInterface + size=216 align=8 + base size=216 base align=8 +QtMetaContainerPrivate::QMetaSequenceInterface (0x0x7f6f3e579680) 0 + QtMetaContainerPrivate::QMetaContainerInterface (0x0x7f6f3e57d780) 0 + +Class QtMetaContainerPrivate::QMetaAssociationInterface + size=240 align=8 + base size=240 base align=8 +QtMetaContainerPrivate::QMetaAssociationInterface (0x0x7f6f3e579750) 0 + QtMetaContainerPrivate::QMetaContainerInterface (0x0x7f6f3e57d840) 0 + +Class QMetaContainer + size=8 align=8 + base size=8 base align=8 +QMetaContainer (0x0x7f6f3e278360) 0 + +Class QMetaSequence + size=8 align=8 + base size=8 base align=8 +QMetaSequence (0x0x7f6f3e579af8) 0 + QMetaContainer (0x0x7f6f3e278540) 0 + +Class QMetaAssociation + size=8 align=8 + base size=8 base align=8 +QMetaAssociation (0x0x7f6f3e579b60) 0 + QMetaContainer (0x0x7f6f3e278900) 0 + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f6f3e36eae0) 0 + +Class std::__detail::_List_node_header + size=24 align=8 + base size=24 base align=8 +std::__detail::_List_node_header (0x0x7f6f3e320bc8) 0 + std::__detail::_List_node_base (0x0x7f6f3e36eb40) 0 + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f6f3e060c00) 0 + +Class std::_Rb_tree_header + size=40 align=8 + base size=40 base align=8 +std::_Rb_tree_header (0x0x7f6f3e060f60) 0 + +Class QtPrivate::QMetaTypeInterface + size=112 align=8 + base size=112 base align=8 +QtPrivate::QMetaTypeInterface (0x0x7f6f3dedd420) 0 + +Class QMetaType + size=8 align=8 + base size=8 base align=8 +QMetaType (0x0x7f6f3dedd600) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f6f3df97660) 0 + +Class QtPrivate::QTypeNormalizer + size=16 align=8 + base size=16 base align=8 +QtPrivate::QTypeNormalizer (0x0x7f6f3da84f00) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f6f3d6a8240) 0 + +Class QAdoptSharedDataTag + size=1 align=1 + base size=0 base align=1 +QAdoptSharedDataTag (0x0x7f6f3d6a85a0) 0 empty + +Class QtPrivate::RefCounted + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCounted (0x0x7f6f3d707600) 0 + +Class QPropertyBindingPrivatePtr + size=8 align=8 + base size=8 base align=8 +QPropertyBindingPrivatePtr (0x0x7f6f3d707720) 0 + +Class QUntypedPropertyData::InheritsQUntypedPropertyData + size=1 align=1 + base size=0 base align=1 +QUntypedPropertyData::InheritsQUntypedPropertyData (0x0x7f6f3d754d80) 0 empty + +Class QUntypedPropertyData + size=1 align=1 + base size=0 base align=1 +QUntypedPropertyData (0x0x7f6f3d754d20) 0 empty + +Class QPropertyProxyBindingData + size=24 align=8 + base size=24 base align=8 +QPropertyProxyBindingData (0x0x7f6f3d754de0) 0 + +Class QtPrivate::BindingFunctionVTable + size=32 align=8 + base size=32 base align=8 +QtPrivate::BindingFunctionVTable (0x0x7f6f3d754e40) 0 + +Class QtPrivate::QPropertyBindingFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::QPropertyBindingFunction (0x0x7f6f3d7773c0) 0 + +Class QtPrivate::QPropertyBindingData + size=8 align=8 + base size=8 base align=8 +QtPrivate::QPropertyBindingData (0x0x7f6f3d777420) 0 + +Class std::experimental::fundamentals_v2::source_location + size=24 align=8 + base size=24 base align=8 +std::experimental::fundamentals_v2::source_location (0x0x7f6f3d777b40) 0 + +Class QPropertyBindingSourceLocation + size=24 align=8 + base size=24 base align=8 +QPropertyBindingSourceLocation (0x0x7f6f3d7a52a0) 0 + +Class QPropertyBindingError + size=8 align=8 + base size=8 base align=8 +QPropertyBindingError (0x0x7f6f3d7a55a0) 0 + +Class QUntypedPropertyBinding + size=8 align=8 + base size=8 base align=8 +QUntypedPropertyBinding (0x0x7f6f3d7a56c0) 0 + +Class QPropertyObserverBase + size=24 align=8 + base size=24 base align=8 +QPropertyObserverBase (0x0x7f6f3d7a5900) 0 + +Class QPropertyObserver + size=24 align=8 + base size=24 base align=8 +QPropertyObserver (0x0x7f6f3d768618) 0 + QPropertyObserverBase (0x0x7f6f3d7a5a80) 0 + +Class QPropertyNotifier + size=56 align=8 + base size=56 base align=8 +QPropertyNotifier (0x0x7f6f3d768958) 0 + QPropertyObserver (0x0x7f6f3d7689c0) 0 + QPropertyObserverBase (0x0x7f6f3d7a5f60) 0 + +Class QtPrivate::QBindableInterface + size=56 align=8 + base size=56 base align=8 +QtPrivate::QBindableInterface (0x0x7f6f3d80ce40) 0 + +Class QUntypedBindable + size=16 align=8 + base size=16 base align=8 +QUntypedBindable (0x0x7f6f3d46b000) 0 + +Class QBindingStatus + size=32 align=8 + base size=32 base align=8 +QBindingStatus (0x0x7f6f3d566f00) 0 + +Class QBindingStorage + size=16 align=8 + base size=16 base align=8 +QBindingStorage (0x0x7f6f3d566f60) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f6f3d25ed20) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f6f3d2fba80) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=80 align=8 + base size=80 base align=8 +QObjectData (0x0x7f6f3d3d9420) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f6f3d3d9d80) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f6f3d3d9d20) 0 + vptr=((& QObject::_ZTV7QObject) + 16) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f6f3d0b1cc0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f6f3d0f75a0) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f6f3d3b1ea0) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16) + QObject (0x0x7f6f3d0f7540) 0 + primary-for QAbstractAnimation (0x0x7f6f3d3b1ea0) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f6f3d0f7900) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f6f3d3b1f08) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16) + QObject (0x0x7f6f3d0f78a0) 0 + primary-for QAnimationDriver (0x0x7f6f3d3b1f08) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f6f3d0f7ae0) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f6f3d3b1f70) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16) + QObject (0x0x7f6f3d0f7a80) 0 + primary-for QEventLoop (0x0x7f6f3d3b1f70) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f6f3d163060) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f6f3d163120) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f6f3d163180) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))QAbstractEventDispatcher::startingUp +200 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f6f3d1370d0) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16) + QObject (0x0x7f6f3d1630c0) 0 + primary-for QAbstractEventDispatcher (0x0x7f6f3d1370d0) + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f6f3d19a900) 0 empty + +Class QStringConverterBase::State + size=48 align=8 + base size=48 base align=8 +QStringConverterBase::State (0x0x7f6f3cc89540) 0 + +Class QStringConverterBase + size=1 align=1 + base size=0 base align=1 +QStringConverterBase (0x0x7f6f3cc894e0) 0 empty + +Class QStringConverter::Interface + size=40 align=8 + base size=40 base align=8 +QStringConverter::Interface (0x0x7f6f3cccd180) 0 + +Class QStringConverter + size=56 align=8 + base size=56 base align=8 +QStringConverter (0x0x7f6f3cc9a270) 0 + QStringConverterBase (0x0x7f6f3cccd120) 0 empty + +Class QStringEncoder + size=56 align=8 + base size=56 base align=8 +QStringEncoder (0x0x7f6f3cc9a2d8) 0 + QStringConverter (0x0x7f6f3cc9a340) 0 + QStringConverterBase (0x0x7f6f3cccdb40) 0 empty + +Class QStringDecoder + size=56 align=8 + base size=56 base align=8 +QStringDecoder (0x0x7f6f3cc9a3a8) 0 + QStringConverter (0x0x7f6f3cc9a410) 0 + QStringConverterBase (0x0x7f6f3cd079c0) 0 empty + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f6f3cc9a478) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16) + QIODeviceBase (0x0x7f6f3cd2b6c0) 0 empty + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f6f3cd2be40) 0 + +Class QContiguousCacheData + size=40 align=8 + base size=40 base align=8 +QContiguousCacheData (0x0x7f6f3ce2c060) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f6f3ca5a6c0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f6f3ca5a840) 0 + +Class QtPrivate::EnableInternalData + size=1 align=1 + base size=0 base align=1 +QtPrivate::EnableInternalData (0x0x7f6f3cb18a80) 0 empty + +Class QDebug::Stream + size=88 align=8 + base size=88 base align=8 +QDebug::Stream (0x0x7f6f3cb339c0) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f6f3caf2f08) 0 + QIODeviceBase (0x0x7f6f3cb33960) 0 empty + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f6f3c85a360) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f6f3c85a420) 0 empty + +Class QVariant::PrivateShared + size=8 align=8 + base size=8 base align=8 +QVariant::PrivateShared (0x0x7f6f3ca09060) 0 + +Class QVariant::Private + size=32 align=8 + base size=32 base align=8 +QVariant::Private (0x0x7f6f3ca090c0) 0 + +Class QVariant + size=32 align=8 + base size=32 base align=8 +QVariant (0x0x7f6f3ca09000) 0 + +Class QtPrivate::QVariantTypeCoercer + size=32 align=8 + base size=32 base align=8 +QtPrivate::QVariantTypeCoercer (0x0x7f6f3c7cf7e0) 0 + +Class QVariantConstPointer + size=32 align=8 + base size=32 base align=8 +QVariantConstPointer (0x0x7f6f3c7cfa20) 0 + +Class QModelRoleData + size=40 align=8 + base size=40 base align=8 +QModelRoleData (0x0x7f6f3c7cfc00) 0 + +Class QModelRoleDataSpan + size=16 align=8 + base size=16 base align=8 +QModelRoleDataSpan (0x0x7f6f3c812b40) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f6f3c45ab40) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f6f3c4aad20) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f6f3c53b600) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractItemModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractItemModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f6f3c535d00) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16) + QObject (0x0x7f6f3c53b5a0) 0 + primary-for QAbstractItemModel (0x0x7f6f3c535d00) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f6f3c2843c0) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractTableModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractTableModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f6f3c5a05b0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16) + QAbstractItemModel (0x0x7f6f3c5a0618) 0 + primary-for QAbstractTableModel (0x0x7f6f3c5a05b0) + QObject (0x0x7f6f3c284360) 0 + primary-for QAbstractItemModel (0x0x7f6f3c5a0618) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f6f3c2844e0) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractListModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractListModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f6f3c5a0680) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16) + QAbstractItemModel (0x0x7f6f3c5a06e8) 0 + primary-for QAbstractListModel (0x0x7f6f3c5a0680) + QObject (0x0x7f6f3c284480) 0 + primary-for QAbstractItemModel (0x0x7f6f3c5a06e8) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f6f3c2ccd20) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f6f3c2ccde0) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QAbstractProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QAbstractProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QAbstractProxyModel::setSourceModel +416 (int (*)(...))__cxa_pure_virtual +424 (int (*)(...))__cxa_pure_virtual +432 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +440 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f6f3c2d8af8) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16) + QAbstractItemModel (0x0x7f6f3c2d8b60) 0 + primary-for QAbstractProxyModel (0x0x7f6f3c2d8af8) + QObject (0x0x7f6f3c2ccd80) 0 + primary-for QAbstractItemModel (0x0x7f6f3c2d8b60) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f6f3c31f000) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f6f3c2d8bc8) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16) + QAbstractAnimation (0x0x7f6f3c2d8c30) 0 + primary-for QAnimationGroup (0x0x7f6f3c2d8bc8) + QObject (0x0x7f6f3c2ccf60) 0 + primary-for QAbstractAnimation (0x0x7f6f3c2d8c30) + +Class QAssociativeIterator + size=16 align=8 + base size=16 base align=8 +QAssociativeIterator (0x0x7f6f3c2d8d68) 0 + QIterator<QMetaAssociation> (0x0x7f6f3c2d8dd0) 0 + QBaseIterator<QMetaAssociation> (0x0x7f6f3c31f420) 0 + +Class QAssociativeConstIterator + size=16 align=8 + base size=16 base align=8 +QAssociativeConstIterator (0x0x7f6f3c2d8f08) 0 + QConstIterator<QMetaAssociation> (0x0x7f6f3c2d8f70) 0 + QBaseIterator<QMetaAssociation> (0x0x7f6f3c31f9c0) 0 + +Class QAssociativeIterable + size=24 align=8 + base size=24 base align=8 +QAssociativeIterable (0x0x7f6f3c371000) 0 + QIterable<QMetaAssociation> (0x0x7f6f3c31ff00) 0 + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f6f3c4539c0) 0 + +Class QBitArray + size=24 align=8 + base size=24 base align=8 +QBitArray (0x0x7f6f3c0b4720) 0 + +Class QBitRef + size=16 align=8 + base size=16 base align=8 +QBitRef (0x0x7f6f3c0e3660) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f6f3c1291e0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f6f3c12c0e0) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16) + QObject (0x0x7f6f3c129120) 0 + primary-for QIODevice (0x0x7f6f3c12c0e0) + QIODeviceBase (0x0x7f6f3c129180) 0 empty + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f6f3c129600) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f6f3c112f70) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16) + QIODevice (0x0x7f6f3c12c150) 0 + primary-for QBuffer (0x0x7f6f3c112f70) + QObject (0x0x7f6f3c129540) 0 + primary-for QIODevice (0x0x7f6f3c12c150) + QIODeviceBase (0x0x7f6f3c1295a0) 0 empty + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f6f3c129840) 0 + +Class QByteArrayMatcher + size=1056 align=8 + base size=1056 base align=8 +QByteArrayMatcher (0x0x7f6f3c1297e0) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f6f3c1299c0) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f6f3c129960) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f6f3c1d31e0) 0 + +Class QCalendar::YearMonthDay + size=12 align=4 + base size=12 base align=4 +QCalendar::YearMonthDay (0x0x7f6f3bf20060) 0 + +Class QCalendar::SystemId + size=8 align=8 + base size=8 base align=8 +QCalendar::SystemId (0x0x7f6f3bf200c0) 0 + +Class QCalendar + size=8 align=8 + base size=8 base align=8 +QCalendar (0x0x7f6f3bf20000) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f6f3bf20ae0) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f6f3bfa2120) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f6f3bfeb360) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f6f3bfeb3c0) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f6f3bfeb300) 0 + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f6f3bc71600) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f6f3bc9f9c0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f6f3bd61c00) 0 + +Class QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel + size=1 align=1 + base size=0 base align=1 +QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel (0x0x7f6f3bdf53c0) 0 empty + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f6f3bdf5480) 0 + +Class QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator + size=24 align=8 + base size=17 base align=8 +QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator (0x0x7f6f3bdf5600) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f6f3ba86840) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f6f3bb87480) 0 + +Class QCborParserError + size=16 align=8 + base size=16 base align=8 +QCborParserError (0x0x7f6f3bbf4600) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f6f3bbf46c0) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f6f3b917f60) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f6f3b9704e0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f6f3b970540) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f6f3b970480) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f6f3b65bae0) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f6f3b65bb40) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f6f3b65ba80) 0 + +Class qfloat16::Wrap + size=2 align=2 + base size=2 base align=2 +qfloat16::Wrap (0x0x7f6f3b471ba0) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f6f3b471b40) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f6f3b556f60) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f6f3b5d4420) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f6f3b5d4e40) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f6f3b622060) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f6f3b2b0a80) 0 + +Class QEvent::InputEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::InputEventTag (0x0x7f6f3b337420) 0 empty + +Class QEvent::PointerEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::PointerEventTag (0x0x7f6f3b337480) 0 empty + +Class QEvent::SinglePointEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::SinglePointEventTag (0x0x7f6f3b3374e0) 0 empty + +Vtable for QEvent +QEvent::_ZTV6QEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QEvent + size=16 align=8 + base size=16 base align=8 +QEvent (0x0x7f6f3b3373c0) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QTimerEvent::clone + +Class QTimerEvent + size=24 align=8 + base size=20 base align=8 +QTimerEvent (0x0x7f6f3b331410) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16) + QEvent (0x0x7f6f3b337e40) 0 + primary-for QTimerEvent (0x0x7f6f3b331410) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QChildEvent::clone + +Class QChildEvent + size=24 align=8 + base size=24 base align=8 +QChildEvent (0x0x7f6f3b331478) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16) + QEvent (0x0x7f6f3b3a6360) 0 + primary-for QChildEvent (0x0x7f6f3b331478) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDynamicPropertyChangeEvent::clone + +Class QDynamicPropertyChangeEvent + size=40 align=8 + base size=40 base align=8 +QDynamicPropertyChangeEvent (0x0x7f6f3b3314e0) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16) + QEvent (0x0x7f6f3b3a6780) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f6f3b3314e0) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDeferredDeleteEvent::clone + +Class QDeferredDeleteEvent + size=24 align=8 + base size=20 base align=8 +QDeferredDeleteEvent (0x0x7f6f3b331548) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16) + QEvent (0x0x7f6f3b3a6a20) 0 + primary-for QDeferredDeleteEvent (0x0x7f6f3b331548) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f6f3b3a6de0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f6f3b331618) 0 + QBasicMutex (0x0x7f6f3b426b40) 0 + +Class QRecursiveMutex + size=24 align=8 + base size=24 base align=8 +QRecursiveMutex (0x0x7f6f3b426f60) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f6f3b4405a0) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f6f3b440ba0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f6f3b0f0840) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f6f3b215240) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16) + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f6f3ae67420) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f6f3ae67720) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f6f3afa0ae0) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f6f3afb98f0) 0 + std::__mutex_base (0x0x7f6f3afa0b40) 0 + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f6f3afa0d20) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f6f3afa0d80) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f6f3afa0de0) 0 empty + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f6f3afda840) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f6f3afb9958) 0 + std::__recursive_mutex_base (0x0x7f6f3afda8a0) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f6f3aec3e70) 0 + std::__mutex_base (0x0x7f6f3afdac60) 0 + std::__timed_mutex_impl<std::timed_mutex> (0x0x7f6f3afdacc0) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f6f3aec3ee0) 0 + std::__recursive_mutex_base (0x0x7f6f3b0170c0) 0 + std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7f6f3b017120) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f6f3b017f00) 0 + +Vtable for std::thread::_State +std::thread::_State::_ZTVNSt6thread6_StateE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread6_StateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_State + size=8 align=8 + base size=8 base align=8 +std::thread::_State (0x0x7f6f3b04d1e0) 0 nearly-empty + vptr=((& std::thread::_State::_ZTVNSt6thread6_StateE) + 16) + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f6f3b04d240) 0 + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f6f3b04d180) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f6f3ae2b480) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f6f3ae2b840) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f6f3ae2b8a0) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f6f3aadde40) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f6f3aad8750) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16) + std::logic_error (0x0x7f6f3aad87b8) 0 + primary-for std::future_error (0x0x7f6f3aad8750) + std::exception (0x0x7f6f3ab1d540) 0 nearly-empty + primary-for std::logic_error (0x0x7f6f3aad87b8) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f6f3ab1dc60) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f6f3ab1dc00) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f6f3a88c6c0) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f6f3a867410) 0 + std::__at_thread_exit_elt (0x0x7f6f3a88c780) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f6f3ab1dde0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f6f3ab1dba0) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f6f3a565340) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16) + std::__future_base::_State_baseV2 (0x0x7f6f3a58b480) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f6f3a565340) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f6f3a58bd20) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f6f3a565680) 0 + vptr=((& QThread::_ZTV7QThread) + 16) + QObject (0x0x7f6f3a58bcc0) 0 + primary-for QThread (0x0x7f6f3a565680) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class QRunnable + size=16 align=8 + base size=9 base align=8 +QRunnable (0x0x7f6f3a5cb0c0) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f6f3a5cb240) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f6f3a5656e8) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16) + QObject (0x0x7f6f3a5cb1e0) 0 + primary-for QThreadPool (0x0x7f6f3a5656e8) + +Vtable for QException +QException::_ZTV10QException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f6f3a565750) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16) + std::exception (0x0x7f6f3a5cb3c0) 0 nearly-empty + primary-for QException (0x0x7f6f3a565750) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=16 align=8 + base size=16 base align=8 +QUnhandledException (0x0x7f6f3a5657b8) 0 + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16) + QException (0x0x7f6f3a565820) 0 nearly-empty + primary-for QUnhandledException (0x0x7f6f3a5657b8) + std::exception (0x0x7f6f3a5cb420) 0 nearly-empty + primary-for QException (0x0x7f6f3a565820) + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f6f3a61f2a0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f6f3a40f960) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f6f3a40f900) 0 + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f6f3a44fba0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f6f3a05a478) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16) + QObject (0x0x7f6f3a44fb40) 0 + primary-for QCoreApplication (0x0x7f6f3a05a478) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f6f3a44fde0) 0 + +Class QConcatenateTablesProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QConcatenateTablesProxyModel::QPrivateSignal (0x0x7f6f3a44ff00) 0 empty + +Vtable for QConcatenateTablesProxyModel +QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QConcatenateTablesProxyModel) +16 (int (*)(...))QConcatenateTablesProxyModel::metaObject +24 (int (*)(...))QConcatenateTablesProxyModel::qt_metacast +32 (int (*)(...))QConcatenateTablesProxyModel::qt_metacall +40 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +48 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QConcatenateTablesProxyModel::index +120 (int (*)(...))QConcatenateTablesProxyModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QConcatenateTablesProxyModel::rowCount +144 (int (*)(...))QConcatenateTablesProxyModel::columnCount +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))QConcatenateTablesProxyModel::data +168 (int (*)(...))QConcatenateTablesProxyModel::setData +176 (int (*)(...))QConcatenateTablesProxyModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QConcatenateTablesProxyModel::itemData +200 (int (*)(...))QConcatenateTablesProxyModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QConcatenateTablesProxyModel::mimeTypes +224 (int (*)(...))QConcatenateTablesProxyModel::mimeData +232 (int (*)(...))QConcatenateTablesProxyModel::canDropMimeData +240 (int (*)(...))QConcatenateTablesProxyModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QConcatenateTablesProxyModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QConcatenateTablesProxyModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QConcatenateTablesProxyModel + size=16 align=8 + base size=16 base align=8 +QConcatenateTablesProxyModel (0x0x7f6f3a05a4e0) 0 + vptr=((& QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel) + 16) + QAbstractItemModel (0x0x7f6f3a05a548) 0 + primary-for QConcatenateTablesProxyModel (0x0x7f6f3a05a4e0) + QObject (0x0x7f6f3a44fea0) 0 + primary-for QAbstractItemModel (0x0x7f6f3a05a548) + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f6f3a0cf0c0) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f6f3a0cf2a0) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QFileDevice::fileName +256 (int (*)(...))QFileDevice::resize +264 (int (*)(...))QFileDevice::permissions +272 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f6f3a05a5b0) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16) + QIODevice (0x0x7f6f3a0aed90) 0 + primary-for QFileDevice (0x0x7f6f3a05a5b0) + QObject (0x0x7f6f3a0cf1e0) 0 + primary-for QIODevice (0x0x7f6f3a0aed90) + QIODeviceBase (0x0x7f6f3a0cf240) 0 empty + +Class std::filesystem::space_info + size=24 align=8 + base size=24 base align=8 +std::filesystem::space_info (0x0x7f6f3a0cff60) 0 + +Class std::filesystem::__file_clock + size=1 align=1 + base size=0 base align=1 +std::filesystem::__file_clock (0x0x7f6f3a1b2540) 0 empty + +Class std::time_base + size=1 align=1 + base size=0 base align=1 +std::time_base (0x0x7f6f3a1b29c0) 0 empty + +Class std::money_base::pattern + size=4 align=1 + base size=4 base align=1 +std::money_base::pattern (0x0x7f6f3a1fbcc0) 0 + +Class std::money_base + size=1 align=1 + base size=0 base align=1 +std::money_base (0x0x7f6f3a1fbc60) 0 empty + +Class std::messages_base + size=1 align=1 + base size=0 base align=1 +std::messages_base (0x0x7f6f39e8b2a0) 0 empty + +Class std::codecvt_base + size=1 align=1 + base size=0 base align=1 +std::codecvt_base (0x0x7f6f39e8bde0) 0 empty + +Construction vtable for std::basic_istream<char> (0x0x7f6f39cfe820 instance) in std::__cxx11::basic_istringstream<char> +std::__cxx11::basic_istringstream<char>::_ZTCNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE0_Si: 10 entries +0 120 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551496 +48 (int (*)(...))-120 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +VTT for std::__cxx11::basic_istringstream<char> +std::__cxx11::basic_istringstream<char>::_ZTTNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE: 4 entries +0 ((& std::__cxx11::basic_istringstream<char>::_ZTVNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE) + 24) +8 ((& std::__cxx11::basic_istringstream<char>::_ZTCNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 24) +16 ((& std::__cxx11::basic_istringstream<char>::_ZTCNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 64) +24 ((& std::__cxx11::basic_istringstream<char>::_ZTVNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE) + 64) + +Construction vtable for std::basic_ostream<char> (0x0x7f6f39cfea90 instance) in std::__cxx11::basic_ostringstream<char> +std::__cxx11::basic_ostringstream<char>::_ZTCNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE0_So: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::__cxx11::basic_ostringstream<char> +std::__cxx11::basic_ostringstream<char>::_ZTTNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE: 4 entries +0 ((& std::__cxx11::basic_ostringstream<char>::_ZTVNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE) + 24) +8 ((& std::__cxx11::basic_ostringstream<char>::_ZTCNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE0_So) + 24) +16 ((& std::__cxx11::basic_ostringstream<char>::_ZTCNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE0_So) + 64) +24 ((& std::__cxx11::basic_ostringstream<char>::_ZTVNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE) + 64) + +Construction vtable for std::basic_iostream<char> (0x0x7f6f39fe8e70 instance) in std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd: 15 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISd) +24 0 +32 0 +40 112 +48 (int (*)(...))-16 +56 (int (*)(...))(& _ZTISd) +64 0 +72 0 +80 18446744073709551488 +88 (int (*)(...))-128 +96 (int (*)(...))(& _ZTISd) +104 0 +112 0 + +Construction vtable for std::basic_istream<char> (0x0x7f6f39cfed00 instance) in std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Si: 10 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551488 +48 (int (*)(...))-128 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream<char> (0x0x7f6f39cfedd0 instance) in std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE16_So: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTTNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE: 10 entries +0 ((& std::__cxx11::basic_stringstream<char>::_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE) + 24) +8 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd) + 24) +16 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 24) +24 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 64) +32 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE16_So) + 24) +40 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE16_So) + 64) +48 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd) + 104) +56 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd) + 64) +64 ((& std::__cxx11::basic_stringstream<char>::_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE) + 104) +72 ((& std::__cxx11::basic_stringstream<char>::_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE) + 64) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f6f39cfef70 instance) in std::__cxx11::basic_istringstream<wchar_t> +std::__cxx11::basic_istringstream<wchar_t>::_ZTCNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E: 10 entries +0 120 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551496 +48 (int (*)(...))-120 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::__cxx11::basic_istringstream<wchar_t> +std::__cxx11::basic_istringstream<wchar_t>::_ZTTNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE: 4 entries +0 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTVNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE) + 24) +8 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTCNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 24) +16 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTCNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 64) +24 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTVNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE) + 64) + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f6f39da9208 instance) in std::__cxx11::basic_ostringstream<wchar_t> +std::__cxx11::basic_ostringstream<wchar_t>::_ZTCNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_ostreamIwS2_E: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::__cxx11::basic_ostringstream<wchar_t> +std::__cxx11::basic_ostringstream<wchar_t>::_ZTTNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE: 4 entries +0 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTVNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE) + 24) +8 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTCNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_ostreamIwS2_E) + 24) +16 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTCNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_ostreamIwS2_E) + 64) +24 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTVNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE) + 64) + +Construction vtable for std::basic_iostream<wchar_t> (0x0x7f6f39da3230 instance) in std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E: 15 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt14basic_iostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 112 +48 (int (*)(...))-16 +56 (int (*)(...))(& _ZTISt14basic_iostreamIwSt11char_traitsIwEE) +64 0 +72 0 +80 18446744073709551488 +88 (int (*)(...))-128 +96 (int (*)(...))(& _ZTISt14basic_iostreamIwSt11char_traitsIwEE) +104 0 +112 0 + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f6f39da9478 instance) in std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E: 10 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551488 +48 (int (*)(...))-128 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f6f39da9548 instance) in std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE16_St13basic_ostreamIwS2_E: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTTNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE: 10 entries +0 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE) + 24) +8 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E) + 24) +16 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 24) +24 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 64) +32 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE16_St13basic_ostreamIwS2_E) + 24) +40 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE16_St13basic_ostreamIwS2_E) + 64) +48 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E) + 104) +56 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E) + 64) +64 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE) + 104) +72 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE) + 64) + +Class std::_Resetiosflags + size=4 align=4 + base size=4 base align=4 +std::_Resetiosflags (0x0x7f6f39da4660) 0 + +Class std::_Setiosflags + size=4 align=4 + base size=4 base align=4 +std::_Setiosflags (0x0x7f6f39da47e0) 0 + +Class std::_Setbase + size=4 align=4 + base size=4 base align=4 +std::_Setbase (0x0x7f6f39da4960) 0 + +Class std::_Setprecision + size=4 align=4 + base size=4 base align=4 +std::_Setprecision (0x0x7f6f39da4c60) 0 + +Class std::_Setw + size=4 align=4 + base size=4 base align=4 +std::_Setw (0x0x7f6f39da4de0) 0 + +Class std::filesystem::__cxx11::path::__null_terminated + size=1 align=1 + base size=0 base align=1 +std::filesystem::__cxx11::path::__null_terminated (0x0x7f6f39a8cea0) 0 empty + +Class std::filesystem::__cxx11::path::_List::_Impl_deleter + size=1 align=1 + base size=0 base align=1 +std::filesystem::__cxx11::path::_List::_Impl_deleter (0x0x7f6f39a8cf60) 0 empty + +Class std::filesystem::__cxx11::path::_List + size=8 align=8 + base size=8 base align=8 +std::filesystem::__cxx11::path::_List (0x0x7f6f39a8cf00) 0 + +Class std::filesystem::__cxx11::path + size=40 align=8 + base size=40 base align=8 +std::filesystem::__cxx11::path (0x0x7f6f39a8cd80) 0 + +Vtable for std::filesystem::__cxx11::filesystem_error +std::filesystem::__cxx11::filesystem_error::_ZTVNSt10filesystem7__cxx1116filesystem_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt10filesystem7__cxx1116filesystem_errorE) +16 (int (*)(...))std::filesystem::__cxx11::filesystem_error::~filesystem_error +24 (int (*)(...))std::filesystem::__cxx11::filesystem_error::~filesystem_error +32 (int (*)(...))std::filesystem::__cxx11::filesystem_error::what + +Class std::filesystem::__cxx11::filesystem_error + size=48 align=8 + base size=48 base align=8 +std::filesystem::__cxx11::filesystem_error (0x0x7f6f39915340) 0 + vptr=((& std::filesystem::__cxx11::filesystem_error::_ZTVNSt10filesystem7__cxx1116filesystem_errorE) + 16) + std::system_error (0x0x7f6f399153a8) 0 + primary-for std::filesystem::__cxx11::filesystem_error (0x0x7f6f39915340) + std::runtime_error (0x0x7f6f39915410) 0 + primary-for std::system_error (0x0x7f6f399153a8) + std::exception (0x0x7f6f39903e40) 0 nearly-empty + primary-for std::runtime_error (0x0x7f6f39915410) + +Class std::filesystem::__cxx11::path::_Cmpt + size=48 align=8 + base size=48 base align=8 +std::filesystem::__cxx11::path::_Cmpt (0x0x7f6f39915d68) 0 + std::filesystem::__cxx11::path (0x0x7f6f39936960) 0 + +Class std::filesystem::__cxx11::path::iterator + size=24 align=8 + base size=17 base align=8 +std::filesystem::__cxx11::path::iterator (0x0x7f6f39990ba0) 0 + +Class std::filesystem::file_status + size=8 align=4 + base size=8 base align=4 +std::filesystem::file_status (0x0x7f6f396773c0) 0 + +Class std::filesystem::__cxx11::directory_entry + size=48 align=8 + base size=41 base align=8 +std::filesystem::__cxx11::directory_entry (0x0x7f6f396778a0) 0 + +Class std::filesystem::__cxx11::__directory_iterator_proxy + size=48 align=8 + base size=48 base align=8 +std::filesystem::__cxx11::__directory_iterator_proxy (0x0x7f6f396c7f60) 0 + +Class std::filesystem::__cxx11::directory_iterator + size=16 align=8 + base size=16 base align=8 +std::filesystem::__cxx11::directory_iterator (0x0x7f6f396ff720) 0 + +Class std::filesystem::__cxx11::recursive_directory_iterator + size=16 align=8 + base size=16 base align=8 +std::filesystem::__cxx11::recursive_directory_iterator (0x0x7f6f39778840) 0 + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f6f398469c0) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QFile::fileName +256 (int (*)(...))QFile::resize +264 (int (*)(...))QFile::permissions +272 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f6f39854820) 0 + vptr=((& QFile::_ZTV5QFile) + 16) + QFileDevice (0x0x7f6f39854888) 0 + primary-for QFile (0x0x7f6f39854820) + QIODevice (0x0x7f6f39a44540) 0 + primary-for QFileDevice (0x0x7f6f39854888) + QObject (0x0x7f6f39846900) 0 + primary-for QIODevice (0x0x7f6f39a44540) + QIODeviceBase (0x0x7f6f39846960) 0 empty + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f6f39487000) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f6f3951a960) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f6f3963b0c0) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f6f3963b540) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f6f3931ecc0) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f6f3931ef00) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f6f392f3a28) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16) + QObject (0x0x7f6f3931eea0) 0 + primary-for QFileSelector (0x0x7f6f392f3a28) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f6f3934f120) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f6f392f3a90) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16) + QObject (0x0x7f6f3934f0c0) 0 + primary-for QFileSystemWatcher (0x0x7f6f392f3a90) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f6f3934f8a0) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f6f392f3af8) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16) + QObject (0x0x7f6f3934f840) 0 + primary-for QFutureWatcherBase (0x0x7f6f392f3af8) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f6f3934fde0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QIdentityProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QIdentityProxyModel::insertRows +272 (int (*)(...))QIdentityProxyModel::insertColumns +280 (int (*)(...))QIdentityProxyModel::removeRows +288 (int (*)(...))QIdentityProxyModel::removeColumns +296 (int (*)(...))QIdentityProxyModel::moveRows +304 (int (*)(...))QIdentityProxyModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QAbstractProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QIdentityProxyModel::match +360 (int (*)(...))QAbstractProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QIdentityProxyModel::setSourceModel +416 (int (*)(...))QIdentityProxyModel::mapToSource +424 (int (*)(...))QIdentityProxyModel::mapFromSource +432 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +440 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f6f392f3d00) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16) + QAbstractProxyModel (0x0x7f6f392f3d68) 0 + primary-for QIdentityProxyModel (0x0x7f6f392f3d00) + QAbstractItemModel (0x0x7f6f392f3dd0) 0 + primary-for QAbstractProxyModel (0x0x7f6f392f3d68) + QObject (0x0x7f6f3934fd80) 0 + primary-for QAbstractItemModel (0x0x7f6f392f3dd0) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f6f3934ff60) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f6f393e5ba0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f6f393efbc8) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16) + QObject (0x0x7f6f393e5b40) 0 + primary-for QItemSelectionModel (0x0x7f6f393efbc8) + +Class QItemSelection + size=24 align=8 + base size=24 base align=8 +QItemSelection (0x0x7f6f390740d0) 0 + QList<QItemSelectionRange> (0x0x7f6f39074138) 0 + QListSpecialMethods<QItemSelectionRange> (0x0x7f6f390741a0) 0 empty + QListSpecialMethodsBase<QItemSelectionRange> (0x0x7f6f39430660) 0 empty + +Class QJsonValue + size=24 align=8 + base size=24 base align=8 +QJsonValue (0x0x7f6f39125780) 0 + +Class QJsonValueRef + size=16 align=8 + base size=16 base align=8 +QJsonValueRef (0x0x7f6f39125c60) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=16 base align=8 +QJsonArray::iterator (0x0x7f6f391bf000) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=16 base align=8 +QJsonArray::const_iterator (0x0x7f6f391bf060) 0 + +Class QJsonArray + size=8 align=8 + base size=8 base align=8 +QJsonArray (0x0x7f6f39196f60) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f6f39245a20) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f6f39245a80) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=16 base align=8 +QJsonObject::iterator (0x0x7f6f39005000) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=16 base align=8 +QJsonObject::const_iterator (0x0x7f6f39005060) 0 + +Class QJsonObject + size=8 align=8 + base size=8 base align=8 +QJsonObject (0x0x7f6f38fd9f60) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f6f38c90b40) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=24 align=8 + base size=24 base align=8 +QLibrary (0x0x7f6f38c99a28) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16) + QObject (0x0x7f6f38c90ae0) 0 + primary-for QLibrary (0x0x7f6f38c99a28) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f6f38cea240) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f6f38cea1e0) 0 + +Class QTypeRevision + size=2 align=1 + base size=2 base align=1 +QTypeRevision (0x0x7f6f38dbb9c0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f6f38a73240) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f6f38a73300) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f6f38acc9c0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f6f38b49360) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f6f38b8d960) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f6f38c10180) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f6f38c10900) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f6f388ad240) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f6f38902f60) 0 + +Class QMetaMethod::Data + size=8 align=8 + base size=8 base align=8 +QMetaMethod::Data (0x0x7f6f3893a060) 0 + +Class QMetaMethod + size=16 align=8 + base size=16 base align=8 +QMetaMethod (0x0x7f6f3893a000) 0 + +Class QMetaEnum::Data + size=8 align=8 + base size=8 base align=8 +QMetaEnum::Data (0x0x7f6f3899e2a0) 0 + +Class QMetaEnum + size=16 align=8 + base size=16 base align=8 +QMetaEnum (0x0x7f6f3899e240) 0 + +Class QMetaProperty::Data + size=8 align=8 + base size=8 base align=8 +QMetaProperty::Data (0x0x7f6f389e6000) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f6f389c4f60) 0 + +Class QMetaClassInfo::Data + size=8 align=8 + base size=8 base align=8 +QMetaClassInfo::Data (0x0x7f6f389e66c0) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=16 base align=8 +QMetaClassInfo (0x0x7f6f389e6660) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f6f38a294e0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f6f38a28548) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16) + QObject (0x0x7f6f38a29480) 0 + primary-for QMimeData (0x0x7f6f38a28548) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f6f38a29660) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f6f386bc180) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f6f386bc240) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=40 align=8 + base size=40 base align=8 +QObjectCleanupHandler (0x0x7f6f386b6410) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16) + QObject (0x0x7f6f386bc1e0) 0 + primary-for QObjectCleanupHandler (0x0x7f6f386b6410) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f6f386bc300) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f6f3871c120) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f6f38708e38) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16) + QAnimationGroup (0x0x7f6f38708ea0) 0 + primary-for QParallelAnimationGroup (0x0x7f6f38708e38) + QAbstractAnimation (0x0x7f6f38708f08) 0 + primary-for QAnimationGroup (0x0x7f6f38708ea0) + QObject (0x0x7f6f3871c0c0) 0 + primary-for QAbstractAnimation (0x0x7f6f38708f08) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f6f3871c300) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f6f38708f70) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16) + QAbstractAnimation (0x0x7f6f3872a000) 0 + primary-for QPauseAnimation (0x0x7f6f38708f70) + QObject (0x0x7f6f3871c2a0) 0 + primary-for QAbstractAnimation (0x0x7f6f3872a000) + +Class QPluginMetaData + size=16 align=8 + base size=16 base align=8 +QPluginMetaData (0x0x7f6f3871c4e0) 0 + +Class QStaticPlugin + size=24 align=8 + base size=24 base align=8 +QStaticPlugin (0x0x7f6f3871c540) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f6f3874ef60) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f6f3875fbc8) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16) + QObject (0x0x7f6f3874ef00) 0 + primary-for QPluginLoader (0x0x7f6f3875fbc8) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f6f38776060) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f6f387dd8a0) 0 empty + +Class QProcess::Use_setChildProcessModifier_Instead + size=1 align=1 + base size=0 base align=1 +QProcess::Use_setChildProcessModifier_Instead (0x0x7f6f387dd900) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 32 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QProcess::writeData +248 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f6f387dec98) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16) + QIODevice (0x0x7f6f38713bd0) 0 + primary-for QProcess (0x0x7f6f387dec98) + QObject (0x0x7f6f387dd7e0) 0 + primary-for QIODevice (0x0x7f6f38713bd0) + QIODeviceBase (0x0x7f6f387dd840) 0 empty + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f6f388266c0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f6f387ded00) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16) + QAbstractAnimation (0x0x7f6f387ded68) 0 + primary-for QVariantAnimation (0x0x7f6f387ded00) + QObject (0x0x7f6f38826660) 0 + primary-for QAbstractAnimation (0x0x7f6f387ded68) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f6f38826900) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f6f387dee38) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16) + QVariantAnimation (0x0x7f6f387deea0) 0 + primary-for QPropertyAnimation (0x0x7f6f387dee38) + QAbstractAnimation (0x0x7f6f387def08) 0 + primary-for QVariantAnimation (0x0x7f6f387deea0) + QObject (0x0x7f6f388268a0) 0 + primary-for QAbstractAnimation (0x0x7f6f387def08) + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f6f384e4060) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f6f385d04e0) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f6f385d0480) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f6f38383c60) 0 + +Class QRandomGenerator::InitialRandomData + size=16 align=8 + base size=16 base align=8 +QRandomGenerator::InitialRandomData (0x0x7f6f381a6ba0) 0 + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f6f381a6c00) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f6f381a6b40) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f6f3820bbc8) 0 + QRandomGenerator (0x0x7f6f38221ea0) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f6f38249ae0) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f6f38249d20) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f6f37eb61e0) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f6f37eb6660) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f6f37f35120) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f6f37f8dba0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f6f380589c0) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f6f37d33540) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f6f37d33840) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QSaveFile::writeData +248 (int (*)(...))QSaveFile::fileName +256 (int (*)(...))QFileDevice::resize +264 (int (*)(...))QFileDevice::permissions +272 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f6f37ccbf08) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16) + QFileDevice (0x0x7f6f37ccbf70) 0 + primary-for QSaveFile (0x0x7f6f37ccbf08) + QIODevice (0x0x7f6f381d2f50) 0 + primary-for QFileDevice (0x0x7f6f37ccbf70) + QObject (0x0x7f6f37d33780) 0 + primary-for QIODevice (0x0x7f6f381d2f50) + QIODeviceBase (0x0x7f6f37d337e0) 0 empty + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f6f37d33ba0) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f6f37dc73c0) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f6f37e30120) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f6f37e24b60) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16) + QAnimationGroup (0x0x7f6f37e24bc8) 0 + primary-for QSequentialAnimationGroup (0x0x7f6f37e24b60) + QAbstractAnimation (0x0x7f6f37e24c30) 0 + primary-for QAnimationGroup (0x0x7f6f37e24bc8) + QObject (0x0x7f6f37e300c0) 0 + primary-for QAbstractAnimation (0x0x7f6f37e24c30) + +Class QSequentialIterator + size=16 align=8 + base size=16 base align=8 +QSequentialIterator (0x0x7f6f37e24d68) 0 + QIterator<QMetaSequence> (0x0x7f6f37e24dd0) 0 + QBaseIterator<QMetaSequence> (0x0x7f6f37e30480) 0 + +Class QSequentialConstIterator + size=16 align=8 + base size=16 base align=8 +QSequentialConstIterator (0x0x7f6f37e24ea0) 0 + QConstIterator<QMetaSequence> (0x0x7f6f37e24f08) 0 + QBaseIterator<QMetaSequence> (0x0x7f6f37e30a20) 0 + +Class QSequentialIterable + size=24 align=8 + base size=24 base align=8 +QSequentialIterable (0x0x7f6f37e24f70) 0 + QIterable<QMetaSequence> (0x0x7f6f37e30f60) 0 + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f6f37b62540) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f6f37b653a8) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16) + QObject (0x0x7f6f37b624e0) 0 + primary-for QSettings (0x0x7f6f37b653a8) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f6f37b62960) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f6f37b65410) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16) + QObject (0x0x7f6f37b62900) 0 + primary-for QSharedMemory (0x0x7f6f37b65410) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f6f37b62b40) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f6f37b65478) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16) + QObject (0x0x7f6f37b62ae0) 0 + primary-for QSignalMapper (0x0x7f6f37b65478) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f6f3cbdc780) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f6f4188e340) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16) + QObject (0x0x7f6f3cbdc720) 0 + primary-for QSocketNotifier (0x0x7f6f4188e340) + +Class QSocketDescriptor + size=4 align=4 + base size=4 base align=4 +QSocketDescriptor (0x0x7f6f3cbdc900) 0 + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f6f3c0c42a0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 59 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QSortFilterProxyModel::mimeTypes +224 (int (*)(...))QSortFilterProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QSortFilterProxyModel::dropMimeData +248 (int (*)(...))QSortFilterProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QSortFilterProxyModel::insertRows +272 (int (*)(...))QSortFilterProxyModel::insertColumns +280 (int (*)(...))QSortFilterProxyModel::removeRows +288 (int (*)(...))QSortFilterProxyModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QSortFilterProxyModel::fetchMore +320 (int (*)(...))QSortFilterProxyModel::canFetchMore +328 (int (*)(...))QSortFilterProxyModel::flags +336 (int (*)(...))QSortFilterProxyModel::sort +344 (int (*)(...))QSortFilterProxyModel::buddy +352 (int (*)(...))QSortFilterProxyModel::match +360 (int (*)(...))QSortFilterProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QSortFilterProxyModel::setSourceModel +416 (int (*)(...))QSortFilterProxyModel::mapToSource +424 (int (*)(...))QSortFilterProxyModel::mapFromSource +432 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +440 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +448 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +456 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +464 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f6f41ec4410) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16) + QAbstractProxyModel (0x0x7f6f41ec4680) 0 + primary-for QSortFilterProxyModel (0x0x7f6f41ec4410) + QAbstractItemModel (0x0x7f6f41f944e0) 0 + primary-for QAbstractProxyModel (0x0x7f6f41ec4680) + QObject (0x0x7f6f3c0c4240) 0 + primary-for QAbstractItemModel (0x0x7f6f41f944e0) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f6f3c0c4660) 0 empty + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f6f3bf33060) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f6f3baf28a0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f6f3b67a120) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QStringListModel::itemData +200 (int (*)(...))QStringListModel::setItemData +208 (int (*)(...))QStringListModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractListModel::dropMimeData +248 (int (*)(...))QStringListModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QStringListModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QStringListModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QStringListModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QStringListModel::flags +336 (int (*)(...))QStringListModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QStringListModel + size=40 align=8 + base size=40 base align=8 +QStringListModel (0x0x7f6f41b00548) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16) + QAbstractListModel (0x0x7f6f41b005b0) 0 + primary-for QStringListModel (0x0x7f6f41b00548) + QAbstractItemModel (0x0x7f6f41b00680) 0 + primary-for QAbstractListModel (0x0x7f6f41b005b0) + QObject (0x0x7f6f3b67a0c0) 0 + primary-for QAbstractItemModel (0x0x7f6f41b00680) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f6f3b67a1e0) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f6f3b67a300) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f6f3b67a480) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QTemporaryFile::fileName +256 (int (*)(...))QFile::resize +264 (int (*)(...))QFile::permissions +272 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f6f41b006e8) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16) + QFile (0x0x7f6f41b00820) 0 + primary-for QTemporaryFile (0x0x7f6f41b006e8) + QFileDevice (0x0x7f6f41b009c0) 0 + primary-for QFile (0x0x7f6f41b00820) + QIODevice (0x0x7f6f41cb1460) 0 + primary-for QFileDevice (0x0x7f6f41b009c0) + QObject (0x0x7f6f3b67a3c0) 0 + primary-for QIODevice (0x0x7f6f41cb1460) + QIODeviceBase (0x0x7f6f3b67a420) 0 empty + +Class QTextBoundaryFinder + size=72 align=8 + base size=72 base align=8 +QTextBoundaryFinder (0x0x7f6f3b67a6c0) 0 + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f6f3b67ad20) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f6f3b5d3420) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f6f41b00c98) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16) + QObject (0x0x7f6f3b5d33c0) 0 + primary-for QTimeLine (0x0x7f6f41b00c98) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f6f3b5d3600) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=16 align=8 + base size=16 base align=8 +QTimer (0x0x7f6f41b00d00) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16) + QObject (0x0x7f6f3b5d35a0) 0 + primary-for QTimer (0x0x7f6f41b00d00) + +Class QTimeZone::OffsetData + size=48 align=8 + base size=44 base align=8 +QTimeZone::OffsetData (0x0x7f6f3b5d3f60) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f6f3b5d3f00) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f6f396bd000) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f6f41b6e820) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16) + QObject (0x0x7f6f39b1ff60) 0 + primary-for QTranslator (0x0x7f6f41b6e820) + +Class QTransposeProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTransposeProxyModel::QPrivateSignal (0x0x7f6f396bd1e0) 0 empty + +Vtable for QTransposeProxyModel +QTransposeProxyModel::_ZTV20QTransposeProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTransposeProxyModel) +16 (int (*)(...))QTransposeProxyModel::metaObject +24 (int (*)(...))QTransposeProxyModel::qt_metacast +32 (int (*)(...))QTransposeProxyModel::qt_metacall +40 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +48 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTransposeProxyModel::index +120 (int (*)(...))QTransposeProxyModel::parent +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))QTransposeProxyModel::rowCount +144 (int (*)(...))QTransposeProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QTransposeProxyModel::headerData +184 (int (*)(...))QTransposeProxyModel::setHeaderData +192 (int (*)(...))QTransposeProxyModel::itemData +200 (int (*)(...))QTransposeProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QAbstractProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QTransposeProxyModel::insertRows +272 (int (*)(...))QTransposeProxyModel::insertColumns +280 (int (*)(...))QTransposeProxyModel::removeRows +288 (int (*)(...))QTransposeProxyModel::removeColumns +296 (int (*)(...))QTransposeProxyModel::moveRows +304 (int (*)(...))QTransposeProxyModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QTransposeProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QTransposeProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QTransposeProxyModel::setSourceModel +416 (int (*)(...))QTransposeProxyModel::mapToSource +424 (int (*)(...))QTransposeProxyModel::mapFromSource +432 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +440 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QTransposeProxyModel + size=16 align=8 + base size=16 base align=8 +QTransposeProxyModel (0x0x7f6f41b6e888) 0 + vptr=((& QTransposeProxyModel::_ZTV20QTransposeProxyModel) + 16) + QAbstractProxyModel (0x0x7f6f41b6e958) 0 + primary-for QTransposeProxyModel (0x0x7f6f41b6e888) + QAbstractItemModel (0x0x7f6f41b6e9c0) 0 + primary-for QAbstractProxyModel (0x0x7f6f41b6e958) + QObject (0x0x7f6f396bd180) 0 + primary-for QAbstractItemModel (0x0x7f6f41b6e9c0) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f6f396bd360) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f6f39226ba0) 0 + +Class QtPrivate::QXmlString + size=24 align=8 + base size=24 base align=8 +QtPrivate::QXmlString (0x0x7f6f39226cc0) 0 + +Class QXmlStreamAttribute + size=104 align=8 + base size=97 base align=8 +QXmlStreamAttribute (0x0x7f6f38c68b40) 0 + +Class QXmlStreamAttributes + size=24 align=8 + base size=24 base align=8 +QXmlStreamAttributes (0x0x7f6f4194d618) 0 + QList<QXmlStreamAttribute> (0x0x7f6f4194d5b0) 0 + QListSpecialMethods<QXmlStreamAttribute> (0x0x7f6f4194d6e8) 0 empty + QListSpecialMethodsBase<QXmlStreamAttribute> (0x0x7f6f38a83c00) 0 empty + +Class QXmlStreamNamespaceDeclaration + size=48 align=8 + base size=48 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f6f38922480) 0 + +Class QXmlStreamNotationDeclaration + size=72 align=8 + base size=72 base align=8 +QXmlStreamNotationDeclaration (0x0x7f6f37eb2b40) 0 + +Class QXmlStreamEntityDeclaration + size=120 align=8 + base size=120 base align=8 +QXmlStreamEntityDeclaration (0x0x7f6f37f081e0) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f6f37f45960) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f6f37f459c0) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f6f37f45f60) 0 + +Class QNetworkRequest + size=8 align=8 + base size=8 base align=8 +QNetworkRequest (0x0x7f6f3804e180) 0 + +Class QNetworkCacheMetaData + size=8 align=8 + base size=8 base align=8 +QNetworkCacheMetaData (0x0x7f6f38448300) 0 + +Class QAbstractNetworkCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractNetworkCache::QPrivateSignal (0x0x7f6f3c9ddb40) 0 empty + +Vtable for QAbstractNetworkCache +QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractNetworkCache) +16 (int (*)(...))QAbstractNetworkCache::metaObject +24 (int (*)(...))QAbstractNetworkCache::qt_metacast +32 (int (*)(...))QAbstractNetworkCache::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNetworkCache + size=16 align=8 + base size=16 base align=8 +QAbstractNetworkCache (0x0x7f6f4197bf70) 0 + vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16) + QObject (0x0x7f6f3c9ddae0) 0 + primary-for QAbstractNetworkCache (0x0x7f6f4197bf70) + +Class QAbstractSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSocket::QPrivateSignal (0x0x7f6f3c9ddd80) 0 empty + +Vtable for QAbstractSocket +QAbstractSocket::_ZTV15QAbstractSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSocket) +16 (int (*)(...))QAbstractSocket::metaObject +24 (int (*)(...))QAbstractSocket::qt_metacast +32 (int (*)(...))QAbstractSocket::qt_metacall +40 (int (*)(...))QAbstractSocket::~QAbstractSocket +48 (int (*)(...))QAbstractSocket::~QAbstractSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::skipData +240 (int (*)(...))QAbstractSocket::writeData +248 (int (*)(...))QAbstractSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QAbstractSocket::connectToHost +272 (int (*)(...))QAbstractSocket::disconnectFromHost +280 (int (*)(...))QAbstractSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketDescriptor +304 (int (*)(...))QAbstractSocket::setSocketOption +312 (int (*)(...))QAbstractSocket::socketOption +320 (int (*)(...))QAbstractSocket::waitForConnected +328 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QAbstractSocket + size=16 align=8 + base size=16 base align=8 +QAbstractSocket (0x0x7f6f4197e000) 0 + vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16) + QIODevice (0x0x7f6f3eeae690) 0 + primary-for QAbstractSocket (0x0x7f6f4197e000) + QObject (0x0x7f6f3c9ddcc0) 0 + primary-for QIODevice (0x0x7f6f3eeae690) + QIODeviceBase (0x0x7f6f3c9ddd20) 0 empty + +Class QAuthenticator + size=8 align=8 + base size=8 base align=8 +QAuthenticator (0x0x7f6f3fb58060) 0 + +Class QDnsDomainNameRecord + size=8 align=8 + base size=8 base align=8 +QDnsDomainNameRecord (0x0x7f6f3fb58120) 0 + +Class QDnsHostAddressRecord + size=8 align=8 + base size=8 base align=8 +QDnsHostAddressRecord (0x0x7f6f3eb9e8a0) 0 + +Class QDnsMailExchangeRecord + size=8 align=8 + base size=8 base align=8 +QDnsMailExchangeRecord (0x0x7f6f3c458060) 0 + +Class QDnsServiceRecord + size=8 align=8 + base size=8 base align=8 +QDnsServiceRecord (0x0x7f6f3b51c720) 0 + +Class QDnsTextRecord + size=8 align=8 + base size=8 base align=8 +QDnsTextRecord (0x0x7f6f39ce10c0) 0 + +Class QDnsLookup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDnsLookup::QPrivateSignal (0x0x7f6f391f1b40) 0 empty + +Vtable for QDnsLookup +QDnsLookup::_ZTV10QDnsLookup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDnsLookup) +16 (int (*)(...))QDnsLookup::metaObject +24 (int (*)(...))QDnsLookup::qt_metacast +32 (int (*)(...))QDnsLookup::qt_metacall +40 (int (*)(...))QDnsLookup::~QDnsLookup +48 (int (*)(...))QDnsLookup::~QDnsLookup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDnsLookup + size=16 align=8 + base size=16 base align=8 +QDnsLookup (0x0x7f6f41684d68) 0 + vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16) + QObject (0x0x7f6f391f1ae0) 0 + primary-for QDnsLookup (0x0x7f6f41684d68) + +Class QIPv6Address + size=16 align=1 + base size=16 base align=1 +QIPv6Address (0x0x7f6f391f1e40) 0 + +Class QHostAddress + size=8 align=8 + base size=8 base align=8 +QHostAddress (0x0x7f6f391f1f60) 0 + +Class QTcpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpSocket::QPrivateSignal (0x0x7f6f3d9c1ea0) 0 empty + +Vtable for QTcpSocket +QTcpSocket::_ZTV10QTcpSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpSocket) +16 (int (*)(...))QTcpSocket::metaObject +24 (int (*)(...))QTcpSocket::qt_metacast +32 (int (*)(...))QTcpSocket::qt_metacall +40 (int (*)(...))QTcpSocket::~QTcpSocket +48 (int (*)(...))QTcpSocket::~QTcpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::skipData +240 (int (*)(...))QAbstractSocket::writeData +248 (int (*)(...))QAbstractSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QAbstractSocket::connectToHost +272 (int (*)(...))QAbstractSocket::disconnectFromHost +280 (int (*)(...))QAbstractSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketDescriptor +304 (int (*)(...))QAbstractSocket::setSocketOption +312 (int (*)(...))QAbstractSocket::socketOption +320 (int (*)(...))QAbstractSocket::waitForConnected +328 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QTcpSocket + size=16 align=8 + base size=16 base align=8 +QTcpSocket (0x0x7f6f4168e3a8) 0 + vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16) + QAbstractSocket (0x0x7f6f4168e410) 0 + primary-for QTcpSocket (0x0x7f6f4168e3a8) + QIODevice (0x0x7f6f3c7d3e70) 0 + primary-for QAbstractSocket (0x0x7f6f4168e410) + QObject (0x0x7f6f3d9c1de0) 0 + primary-for QIODevice (0x0x7f6f3c7d3e70) + QIODeviceBase (0x0x7f6f3d9c1e40) 0 empty + +Class QSslCertificate + size=8 align=8 + base size=8 base align=8 +QSslCertificate (0x0x7f6f3913e480) 0 + +Class QSslError + size=8 align=8 + base size=8 base align=8 +QSslError (0x0x7f6f3dc10780) 0 + +Class QSslSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSslSocket::QPrivateSignal (0x0x7f6f37427840) 0 empty + +Vtable for QSslSocket +QSslSocket::_ZTV10QSslSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSslSocket) +16 (int (*)(...))QSslSocket::metaObject +24 (int (*)(...))QSslSocket::qt_metacast +32 (int (*)(...))QSslSocket::qt_metacall +40 (int (*)(...))QSslSocket::~QSslSocket +48 (int (*)(...))QSslSocket::~QSslSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QSslSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QSslSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QSslSocket::bytesAvailable +184 (int (*)(...))QSslSocket::bytesToWrite +192 (int (*)(...))QSslSocket::canReadLine +200 (int (*)(...))QSslSocket::waitForReadyRead +208 (int (*)(...))QSslSocket::waitForBytesWritten +216 (int (*)(...))QSslSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QSslSocket::skipData +240 (int (*)(...))QSslSocket::writeData +248 (int (*)(...))QSslSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QSslSocket::connectToHost +272 (int (*)(...))QSslSocket::disconnectFromHost +280 (int (*)(...))QSslSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QSslSocket::setSocketDescriptor +304 (int (*)(...))QSslSocket::setSocketOption +312 (int (*)(...))QSslSocket::socketOption +320 (int (*)(...))QSslSocket::waitForConnected +328 (int (*)(...))QSslSocket::waitForDisconnected + +Class QSslSocket + size=16 align=8 + base size=16 base align=8 +QSslSocket (0x0x7f6f416b5208) 0 + vptr=((& QSslSocket::_ZTV10QSslSocket) + 16) + QTcpSocket (0x0x7f6f416b5270) 0 + primary-for QSslSocket (0x0x7f6f416b5208) + QAbstractSocket (0x0x7f6f416b52d8) 0 + primary-for QTcpSocket (0x0x7f6f416b5270) + QIODevice (0x0x7f6f39fe8b60) 0 + primary-for QAbstractSocket (0x0x7f6f416b52d8) + QObject (0x0x7f6f37427780) 0 + primary-for QIODevice (0x0x7f6f39fe8b60) + QIODeviceBase (0x0x7f6f374277e0) 0 empty + +Class QDtlsClientVerifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtlsClientVerifier::QPrivateSignal (0x0x7f6f37427a20) 0 empty + +Class QDtlsClientVerifier::GeneratorParameters + size=32 align=8 + base size=32 base align=8 +QDtlsClientVerifier::GeneratorParameters (0x0x7f6f37427a80) 0 + +Vtable for QDtlsClientVerifier +QDtlsClientVerifier::_ZTV19QDtlsClientVerifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QDtlsClientVerifier) +16 (int (*)(...))QDtlsClientVerifier::metaObject +24 (int (*)(...))QDtlsClientVerifier::qt_metacast +32 (int (*)(...))QDtlsClientVerifier::qt_metacall +40 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +48 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtlsClientVerifier + size=16 align=8 + base size=16 base align=8 +QDtlsClientVerifier (0x0x7f6f416b5340) 0 + vptr=((& QDtlsClientVerifier::_ZTV19QDtlsClientVerifier) + 16) + QObject (0x0x7f6f374279c0) 0 + primary-for QDtlsClientVerifier (0x0x7f6f416b5340) + +Class QDtls::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtls::QPrivateSignal (0x0x7f6f37427c60) 0 empty + +Vtable for QDtls +QDtls::_ZTV5QDtls: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDtls) +16 (int (*)(...))QDtls::metaObject +24 (int (*)(...))QDtls::qt_metacast +32 (int (*)(...))QDtls::qt_metacall +40 (int (*)(...))QDtls::~QDtls +48 (int (*)(...))QDtls::~QDtls +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtls + size=16 align=8 + base size=16 base align=8 +QDtls (0x0x7f6f416b53a8) 0 + vptr=((& QDtls::_ZTV5QDtls) + 16) + QObject (0x0x7f6f37427c00) 0 + primary-for QDtls (0x0x7f6f416b53a8) + +Class QHostInfo + size=8 align=8 + base size=8 base align=8 +QHostInfo (0x0x7f6f37427de0) 0 + +Class QHstsPolicy + size=8 align=8 + base size=8 base align=8 +QHstsPolicy (0x0x7f6f3da4e300) 0 + +Class QHttp2Configuration + size=8 align=8 + base size=8 base align=8 +QHttp2Configuration (0x0x7f6f3bba5e40) 0 + +Class QHttpPart + size=8 align=8 + base size=8 base align=8 +QHttpPart (0x0x7f6f3720d780) 0 + +Class QHttpMultiPart::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHttpMultiPart::QPrivateSignal (0x0x7f6f3722df00) 0 empty + +Vtable for QHttpMultiPart +QHttpMultiPart::_ZTV14QHttpMultiPart: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QHttpMultiPart) +16 (int (*)(...))QHttpMultiPart::metaObject +24 (int (*)(...))QHttpMultiPart::qt_metacast +32 (int (*)(...))QHttpMultiPart::qt_metacall +40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QHttpMultiPart + size=16 align=8 + base size=16 base align=8 +QHttpMultiPart (0x0x7f6f416d7820) 0 + vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16) + QObject (0x0x7f6f3722dea0) 0 + primary-for QHttpMultiPart (0x0x7f6f416d7820) + +Class QLocalServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalServer::QPrivateSignal (0x0x7f6f3723a120) 0 empty + +Vtable for QLocalServer +QLocalServer::_ZTV12QLocalServer: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalServer) +16 (int (*)(...))QLocalServer::metaObject +24 (int (*)(...))QLocalServer::qt_metacast +32 (int (*)(...))QLocalServer::qt_metacall +40 (int (*)(...))QLocalServer::~QLocalServer +48 (int (*)(...))QLocalServer::~QLocalServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalServer::hasPendingConnections +120 (int (*)(...))QLocalServer::nextPendingConnection +128 (int (*)(...))QLocalServer::incomingConnection + +Class QLocalServer + size=16 align=8 + base size=16 base align=8 +QLocalServer (0x0x7f6f416d7888) 0 + vptr=((& QLocalServer::_ZTV12QLocalServer) + 16) + QObject (0x0x7f6f3723a0c0) 0 + primary-for QLocalServer (0x0x7f6f416d7888) + +Class QLocalSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalSocket::QPrivateSignal (0x0x7f6f3723a8a0) 0 empty + +Vtable for QLocalSocket +QLocalSocket::_ZTV12QLocalSocket: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalSocket) +16 (int (*)(...))QLocalSocket::metaObject +24 (int (*)(...))QLocalSocket::qt_metacast +32 (int (*)(...))QLocalSocket::qt_metacall +40 (int (*)(...))QLocalSocket::~QLocalSocket +48 (int (*)(...))QLocalSocket::~QLocalSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalSocket::isSequential +120 (int (*)(...))QLocalSocket::open +128 (int (*)(...))QLocalSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QLocalSocket::bytesAvailable +184 (int (*)(...))QLocalSocket::bytesToWrite +192 (int (*)(...))QLocalSocket::canReadLine +200 (int (*)(...))QLocalSocket::waitForReadyRead +208 (int (*)(...))QLocalSocket::waitForBytesWritten +216 (int (*)(...))QLocalSocket::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QLocalSocket::skipData +240 (int (*)(...))QLocalSocket::writeData + +Class QLocalSocket + size=16 align=8 + base size=16 base align=8 +QLocalSocket (0x0x7f6f416d7a28) 0 + vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16) + QIODevice (0x0x7f6f39300e00) 0 + primary-for QLocalSocket (0x0x7f6f416d7a28) + QObject (0x0x7f6f3723a7e0) 0 + primary-for QIODevice (0x0x7f6f39300e00) + QIODeviceBase (0x0x7f6f3723a840) 0 empty + +Class QSslConfiguration + size=8 align=8 + base size=8 base align=8 +QSslConfiguration (0x0x7f6f3723aea0) 0 + +Class QSslPreSharedKeyAuthenticator + size=8 align=8 + base size=8 base align=8 +QSslPreSharedKeyAuthenticator (0x0x7f6f36daa420) 0 + +Class QNetworkAccessManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkAccessManager::QPrivateSignal (0x0x7f6f36de4d20) 0 empty + +Vtable for QNetworkAccessManager +QNetworkAccessManager::_ZTV21QNetworkAccessManager: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QNetworkAccessManager) +16 (int (*)(...))QNetworkAccessManager::metaObject +24 (int (*)(...))QNetworkAccessManager::qt_metacast +32 (int (*)(...))QNetworkAccessManager::qt_metacall +40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkAccessManager::supportedSchemes +120 (int (*)(...))QNetworkAccessManager::createRequest + +Class QNetworkAccessManager + size=16 align=8 + base size=16 base align=8 +QNetworkAccessManager (0x0x7f6f3c089138) 0 + vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16) + QObject (0x0x7f6f36de4cc0) 0 + primary-for QNetworkAccessManager (0x0x7f6f3c089138) + +Class QNetworkCookie + size=8 align=8 + base size=8 base align=8 +QNetworkCookie (0x0x7f6f36de4ea0) 0 + +Class QNetworkCookieJar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkCookieJar::QPrivateSignal (0x0x7f6f36e1af60) 0 empty + +Vtable for QNetworkCookieJar +QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkCookieJar) +16 (int (*)(...))QNetworkCookieJar::metaObject +24 (int (*)(...))QNetworkCookieJar::qt_metacast +32 (int (*)(...))QNetworkCookieJar::qt_metacall +40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkCookieJar::cookiesForUrl +120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl +128 (int (*)(...))QNetworkCookieJar::insertCookie +136 (int (*)(...))QNetworkCookieJar::updateCookie +144 (int (*)(...))QNetworkCookieJar::deleteCookie +152 (int (*)(...))QNetworkCookieJar::validateCookie + +Class QNetworkCookieJar + size=16 align=8 + base size=16 base align=8 +QNetworkCookieJar (0x0x7f6f3b288c98) 0 + vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16) + QObject (0x0x7f6f36e1af00) 0 + primary-for QNetworkCookieJar (0x0x7f6f3b288c98) + +Class QNetworkDatagram + size=8 align=8 + base size=8 base align=8 +QNetworkDatagram (0x0x7f6f36e25120) 0 + +Class QNetworkDiskCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkDiskCache::QPrivateSignal (0x0x7f6f36e47900) 0 empty + +Vtable for QNetworkDiskCache +QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkDiskCache) +16 (int (*)(...))QNetworkDiskCache::metaObject +24 (int (*)(...))QNetworkDiskCache::qt_metacast +32 (int (*)(...))QNetworkDiskCache::qt_metacall +40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkDiskCache::metaData +120 (int (*)(...))QNetworkDiskCache::updateMetaData +128 (int (*)(...))QNetworkDiskCache::data +136 (int (*)(...))QNetworkDiskCache::remove +144 (int (*)(...))QNetworkDiskCache::cacheSize +152 (int (*)(...))QNetworkDiskCache::prepare +160 (int (*)(...))QNetworkDiskCache::insert +168 (int (*)(...))QNetworkDiskCache::clear +176 (int (*)(...))QNetworkDiskCache::expire + +Class QNetworkDiskCache + size=16 align=8 + base size=16 base align=8 +QNetworkDiskCache (0x0x7f6f394c8e38) 0 + vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16) + QAbstractNetworkCache (0x0x7f6f394e7340) 0 + primary-for QNetworkDiskCache (0x0x7f6f394c8e38) + QObject (0x0x7f6f36e478a0) 0 + primary-for QAbstractNetworkCache (0x0x7f6f394e7340) + +Class QNetworkInformation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkInformation::QPrivateSignal (0x0x7f6f36e47ae0) 0 empty + +Vtable for QNetworkInformation +QNetworkInformation::_ZTV19QNetworkInformation: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNetworkInformation) +16 (int (*)(...))QNetworkInformation::metaObject +24 (int (*)(...))QNetworkInformation::qt_metacast +32 (int (*)(...))QNetworkInformation::qt_metacall +40 (int (*)(...))QNetworkInformation::~QNetworkInformation +48 (int (*)(...))QNetworkInformation::~QNetworkInformation +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QNetworkInformation + size=16 align=8 + base size=16 base align=8 +QNetworkInformation (0x0x7f6f394e73a8) 0 + vptr=((& QNetworkInformation::_ZTV19QNetworkInformation) + 16) + QObject (0x0x7f6f36e47a80) 0 + primary-for QNetworkInformation (0x0x7f6f394e73a8) + +Class QNetworkAddressEntry + size=8 align=8 + base size=8 base align=8 +QNetworkAddressEntry (0x0x7f6f36e631e0) 0 + +Class QNetworkInterface + size=8 align=8 + base size=8 base align=8 +QNetworkInterface (0x0x7f6f36f05c60) 0 + +Class QNetworkProxyQuery + size=8 align=8 + base size=8 base align=8 +QNetworkProxyQuery (0x0x7f6f36b5e1e0) 0 + +Class QNetworkProxy + size=8 align=8 + base size=8 base align=8 +QNetworkProxy (0x0x7f6f36b83960) 0 + +Vtable for QNetworkProxyFactory +QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QNetworkProxyFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNetworkProxyFactory + size=8 align=8 + base size=8 base align=8 +QNetworkProxyFactory (0x0x7f6f36bb3420) 0 nearly-empty + vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16) + +Class QNetworkReply::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkReply::QPrivateSignal (0x0x7f6f36bb3a20) 0 empty + +Vtable for QNetworkReply +QNetworkReply::_ZTV13QNetworkReply: 37 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QNetworkReply) +16 (int (*)(...))QNetworkReply::metaObject +24 (int (*)(...))QNetworkReply::qt_metacast +32 (int (*)(...))QNetworkReply::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkReply::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QNetworkReply::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QNetworkReply::writeData +248 (int (*)(...))QNetworkReply::setReadBufferSize +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))QNetworkReply::ignoreSslErrors +272 (int (*)(...))QNetworkReply::sslConfigurationImplementation +280 (int (*)(...))QNetworkReply::setSslConfigurationImplementation +288 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation + +Class QNetworkReply + size=16 align=8 + base size=16 base align=8 +QNetworkReply (0x0x7f6f36bb0340) 0 + vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16) + QIODevice (0x0x7f6f36b8be70) 0 + primary-for QNetworkReply (0x0x7f6f36bb0340) + QObject (0x0x7f6f36bb3960) 0 + primary-for QIODevice (0x0x7f6f36b8be70) + QIODeviceBase (0x0x7f6f36bb39c0) 0 empty + +Class QOcspResponse + size=8 align=8 + base size=8 base align=8 +QOcspResponse (0x0x7f6f36bdcd80) 0 + +Class QTcpServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpServer::QPrivateSignal (0x0x7f6f36bfdc60) 0 empty + +Vtable for QTcpServer +QTcpServer::_ZTV10QTcpServer: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpServer) +16 (int (*)(...))QTcpServer::metaObject +24 (int (*)(...))QTcpServer::qt_metacast +32 (int (*)(...))QTcpServer::qt_metacall +40 (int (*)(...))QTcpServer::~QTcpServer +48 (int (*)(...))QTcpServer::~QTcpServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTcpServer::hasPendingConnections +120 (int (*)(...))QTcpServer::nextPendingConnection +128 (int (*)(...))QTcpServer::incomingConnection + +Class QTcpServer + size=16 align=8 + base size=16 base align=8 +QTcpServer (0x0x7f6f36bff750) 0 + vptr=((& QTcpServer::_ZTV10QTcpServer) + 16) + QObject (0x0x7f6f36bfdc00) 0 + primary-for QTcpServer (0x0x7f6f36bff750) + +Class QSslCertificateExtension + size=8 align=8 + base size=8 base align=8 +QSslCertificateExtension (0x0x7f6f36bfdde0) 0 + +Class QSslCipher + size=8 align=8 + base size=8 base align=8 +QSslCipher (0x0x7f6f36c305a0) 0 + +Class QSslDiffieHellmanParameters + size=8 align=8 + base size=8 base align=8 +QSslDiffieHellmanParameters (0x0x7f6f36cd7f00) 0 + +Class QSslEllipticCurve + size=4 align=4 + base size=4 base align=4 +QSslEllipticCurve (0x0x7f6f36cfdc60) 0 + +Class QSslKey + size=8 align=8 + base size=8 base align=8 +QSslKey (0x0x7f6f36d16ea0) 0 + +Class QUdpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUdpSocket::QPrivateSignal (0x0x7f6f36d42720) 0 empty + +Vtable for QUdpSocket +QUdpSocket::_ZTV10QUdpSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUdpSocket) +16 (int (*)(...))QUdpSocket::metaObject +24 (int (*)(...))QUdpSocket::qt_metacast +32 (int (*)(...))QUdpSocket::qt_metacall +40 (int (*)(...))QUdpSocket::~QUdpSocket +48 (int (*)(...))QUdpSocket::~QUdpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::skipData +240 (int (*)(...))QAbstractSocket::writeData +248 (int (*)(...))QAbstractSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QAbstractSocket::connectToHost +272 (int (*)(...))QAbstractSocket::disconnectFromHost +280 (int (*)(...))QAbstractSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketDescriptor +304 (int (*)(...))QAbstractSocket::setSocketOption +312 (int (*)(...))QAbstractSocket::socketOption +320 (int (*)(...))QAbstractSocket::waitForConnected +328 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QUdpSocket + size=16 align=8 + base size=16 base align=8 +QUdpSocket (0x0x7f6f36d3ff08) 0 + vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16) + QAbstractSocket (0x0x7f6f36d3ff70) 0 + primary-for QUdpSocket (0x0x7f6f36d3ff08) + QIODevice (0x0x7f6f36d46000) 0 + primary-for QAbstractSocket (0x0x7f6f36d3ff70) + QObject (0x0x7f6f36d42660) 0 + primary-for QIODevice (0x0x7f6f36d46000) + QIODeviceBase (0x0x7f6f36d426c0) 0 empty + +Class QJSValue + size=8 align=8 + base size=8 base align=8 +QJSValue (0x0x7f6f36d42960) 0 + +Class QJSNumberCoercion + size=8 align=8 + base size=8 base align=8 +QJSNumberCoercion (0x0x7f6f36963ea0) 0 + +Class QJSPrimitiveUndefined + size=1 align=1 + base size=0 base align=1 +QJSPrimitiveUndefined (0x0x7f6f36993480) 0 empty + +Class QJSPrimitiveNull + size=1 align=1 + base size=0 base align=1 +QJSPrimitiveNull (0x0x7f6f369934e0) 0 empty + +Class QJSPrimitiveValue::AddOperators + size=1 align=1 + base size=0 base align=1 +QJSPrimitiveValue::AddOperators (0x0x7f6f36993600) 0 empty + +Class QJSPrimitiveValue::SubOperators + size=1 align=1 + base size=1 base align=1 +QJSPrimitiveValue::SubOperators (0x0x7f6f3695d820) 0 empty + QJSPrimitiveValue::StringNaNOperators<QJSPrimitiveValue::SubOperators> (0x0x7f6f369936c0) 0 empty + +Class QJSPrimitiveValue::MulOperators + size=1 align=1 + base size=1 base align=1 +QJSPrimitiveValue::MulOperators (0x0x7f6f3695d888) 0 empty + QJSPrimitiveValue::StringNaNOperators<QJSPrimitiveValue::MulOperators> (0x0x7f6f36993780) 0 empty + +Class QJSPrimitiveValue::DivOperators + size=1 align=1 + base size=1 base align=1 +QJSPrimitiveValue::DivOperators (0x0x7f6f3695d8f0) 0 empty + QJSPrimitiveValue::StringNaNOperators<QJSPrimitiveValue::DivOperators> (0x0x7f6f36993840) 0 empty + +Class QJSPrimitiveValue::QJSPrimitiveValuePrivate + size=32 align=8 + base size=25 base align=8 +QJSPrimitiveValue::QJSPrimitiveValuePrivate (0x0x7f6f369938a0) 0 + +Class QJSPrimitiveValue + size=32 align=8 + base size=32 base align=8 +QJSPrimitiveValue (0x0x7f6f36993540) 0 + +Class QJSManagedValue + size=8 align=8 + base size=8 base align=8 +QJSManagedValue (0x0x7f6f369f9ae0) 0 + +Class QQmlDebuggingEnabler + size=1 align=1 + base size=0 base align=1 +QQmlDebuggingEnabler (0x0x7f6f369f9de0) 0 empty + +Class QJSEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QJSEngine::QPrivateSignal (0x0x7f6f36a130c0) 0 empty + +Vtable for QJSEngine +QJSEngine::_ZTV9QJSEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QJSEngine) +16 (int (*)(...))QJSEngine::metaObject +24 (int (*)(...))QJSEngine::qt_metacast +32 (int (*)(...))QJSEngine::qt_metacall +40 (int (*)(...))QJSEngine::~QJSEngine +48 (int (*)(...))QJSEngine::~QJSEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QJSEngine + size=24 align=8 + base size=24 base align=8 +QJSEngine (0x0x7f6f369e2680) 0 + vptr=((& QJSEngine::_ZTV9QJSEngine) + 16) + QObject (0x0x7f6f36a13060) 0 + primary-for QJSEngine (0x0x7f6f369e2680) + +Class QJSValueIterator + size=8 align=8 + base size=8 base align=8 +QJSValueIterator (0x0x7f6f36a13a20) 0 + +Vtable for QQmlParserStatus +QQmlParserStatus::_ZTV16QQmlParserStatus: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlParserStatus) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlParserStatus + size=16 align=8 + base size=16 base align=8 +QQmlParserStatus (0x0x7f6f36a13c00) 0 + vptr=((& QQmlParserStatus::_ZTV16QQmlParserStatus) + 16) + +Class QQmlListReference + size=8 align=8 + base size=8 base align=8 +QQmlListReference (0x0x7f6f36a45720) 0 + +Vtable for QQmlPropertyValueSource +QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQmlPropertyValueSource) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlPropertyValueSource + size=8 align=8 + base size=8 base align=8 +QQmlPropertyValueSource (0x0x7f6f36a45d20) 0 nearly-empty + vptr=((& QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource) + 16) + +Class QQmlPrivate::RegisterType + size=176 align=8 + base size=170 base align=8 +QQmlPrivate::RegisterType (0x0x7f6f36a68540) 0 + +Class QQmlPrivate::RegisterTypeAndRevisions + size=152 align=8 + base size=152 base align=8 +QQmlPrivate::RegisterTypeAndRevisions (0x0x7f6f36a685a0) 0 + +Class QQmlPrivate::RegisterInterface + size=48 align=8 + base size=42 base align=8 +QQmlPrivate::RegisterInterface (0x0x7f6f36a68600) 0 + +Class QQmlPrivate::RegisterAutoParent + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterAutoParent (0x0x7f6f36a68660) 0 + +Class QQmlPrivate::RegisterSingletonType + size=136 align=8 + base size=130 base align=8 +QQmlPrivate::RegisterSingletonType (0x0x7f6f36a686c0) 0 + +Class QQmlPrivate::RegisterSingletonTypeAndRevisions + size=104 align=8 + base size=104 base align=8 +QQmlPrivate::RegisterSingletonTypeAndRevisions (0x0x7f6f36a68a20) 0 + +Class QQmlPrivate::RegisterCompositeType + size=40 align=8 + base size=40 base align=8 +QQmlPrivate::RegisterCompositeType (0x0x7f6f36a68ae0) 0 + +Class QQmlPrivate::RegisterCompositeSingletonType + size=40 align=8 + base size=40 base align=8 +QQmlPrivate::RegisterCompositeSingletonType (0x0x7f6f36a68b40) 0 + +Class QQmlPrivate::RegisterSequentialContainer + size=56 align=8 + base size=50 base align=8 +QQmlPrivate::RegisterSequentialContainer (0x0x7f6f36a68ba0) 0 + +Class QQmlPrivate::RegisterSequentialContainerAndRevisions + size=56 align=8 + base size=56 base align=8 +QQmlPrivate::RegisterSequentialContainerAndRevisions (0x0x7f6f36a68c00) 0 + +Class QQmlPrivate::AOTCompiledContext + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::AOTCompiledContext (0x0x7f6f36a68c60) 0 + +Class QQmlPrivate::AOTCompiledFunction + size=48 align=8 + base size=48 base align=8 +QQmlPrivate::AOTCompiledFunction (0x0x7f6f36a68cc0) 0 + +Class QQmlPrivate::CachedQmlUnit + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::CachedQmlUnit (0x0x7f6f36a8d6c0) 0 + +Class QQmlPrivate::RegisterQmlUnitCacheHook + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterQmlUnitCacheHook (0x0x7f6f36a8d720) 0 + +Class QQmlPrivate::SingletonFunctor + size=24 align=8 + base size=17 base align=8 +QQmlPrivate::SingletonFunctor (0x0x7f6f36a8d780) 0 + +Vtable for QQmlAbstractUrlInterceptor +QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QQmlAbstractUrlInterceptor) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlAbstractUrlInterceptor + size=8 align=8 + base size=8 base align=8 +QQmlAbstractUrlInterceptor (0x0x7f6f3677d120) 0 nearly-empty + vptr=((& QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor) + 16) + +Class QQmlError + size=8 align=8 + base size=8 base align=8 +QQmlError (0x0x7f6f3677d180) 0 + +Class QQmlImageProviderBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlImageProviderBase::QPrivateSignal (0x0x7f6f3679a9c0) 0 empty + +Vtable for QQmlImageProviderBase +QQmlImageProviderBase::_ZTV21QQmlImageProviderBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlImageProviderBase) +16 (int (*)(...))QQmlImageProviderBase::metaObject +24 (int (*)(...))QQmlImageProviderBase::qt_metacast +32 (int (*)(...))QQmlImageProviderBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QQmlImageProviderBase + size=16 align=8 + base size=16 base align=8 +QQmlImageProviderBase (0x0x7f6f3679bb60) 0 + vptr=((& QQmlImageProviderBase::_ZTV21QQmlImageProviderBase) + 16) + QObject (0x0x7f6f3679a960) 0 + primary-for QQmlImageProviderBase (0x0x7f6f3679bb60) + +Class QQmlEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngine::QPrivateSignal (0x0x7f6f3679aea0) 0 empty + +Vtable for QQmlEngine +QQmlEngine::_ZTV10QQmlEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQmlEngine) +16 (int (*)(...))QQmlEngine::metaObject +24 (int (*)(...))QQmlEngine::qt_metacast +32 (int (*)(...))QQmlEngine::qt_metacall +40 (int (*)(...))QQmlEngine::~QQmlEngine +48 (int (*)(...))QQmlEngine::~QQmlEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlEngine + size=24 align=8 + base size=24 base align=8 +QQmlEngine (0x0x7f6f3679bd00) 0 + vptr=((& QQmlEngine::_ZTV10QQmlEngine) + 16) + QJSEngine (0x0x7f6f3679bd68) 0 + primary-for QQmlEngine (0x0x7f6f3679bd00) + QObject (0x0x7f6f3679ae40) 0 + primary-for QJSEngine (0x0x7f6f3679bd68) + +Class QQmlApplicationEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlApplicationEngine::QPrivateSignal (0x0x7f6f367d01e0) 0 empty + +Vtable for QQmlApplicationEngine +QQmlApplicationEngine::_ZTV21QQmlApplicationEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlApplicationEngine) +16 (int (*)(...))QQmlApplicationEngine::metaObject +24 (int (*)(...))QQmlApplicationEngine::qt_metacast +32 (int (*)(...))QQmlApplicationEngine::qt_metacall +40 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +48 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlApplicationEngine + size=24 align=8 + base size=24 base align=8 +QQmlApplicationEngine (0x0x7f6f3679bdd0) 0 + vptr=((& QQmlApplicationEngine::_ZTV21QQmlApplicationEngine) + 16) + QQmlEngine (0x0x7f6f3679be38) 0 + primary-for QQmlApplicationEngine (0x0x7f6f3679bdd0) + QJSEngine (0x0x7f6f3679bea0) 0 + primary-for QQmlEngine (0x0x7f6f3679be38) + QObject (0x0x7f6f367d0180) 0 + primary-for QJSEngine (0x0x7f6f3679bea0) + +Class QQmlComponent::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlComponent::QPrivateSignal (0x0x7f6f367d03c0) 0 empty + +Vtable for QQmlComponent +QQmlComponent::_ZTV13QQmlComponent: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlComponent) +16 (int (*)(...))QQmlComponent::metaObject +24 (int (*)(...))QQmlComponent::qt_metacast +32 (int (*)(...))QQmlComponent::qt_metacall +40 (int (*)(...))QQmlComponent::~QQmlComponent +48 (int (*)(...))QQmlComponent::~QQmlComponent +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlComponent::create +120 (int (*)(...))QQmlComponent::beginCreate +128 (int (*)(...))QQmlComponent::completeCreate + +Class QQmlComponent + size=16 align=8 + base size=16 base align=8 +QQmlComponent (0x0x7f6f3679bf08) 0 + vptr=((& QQmlComponent::_ZTV13QQmlComponent) + 16) + QObject (0x0x7f6f367d0360) 0 + primary-for QQmlComponent (0x0x7f6f3679bf08) + +Class QQmlContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlContext::QPrivateSignal (0x0x7f6f367f9180) 0 empty + +Class QQmlContext::PropertyPair + size=56 align=8 + base size=56 base align=8 +QQmlContext::PropertyPair (0x0x7f6f367f91e0) 0 + +Vtable for QQmlContext +QQmlContext::_ZTV11QQmlContext: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QQmlContext) +16 (int (*)(...))QQmlContext::metaObject +24 (int (*)(...))QQmlContext::qt_metacast +32 (int (*)(...))QQmlContext::qt_metacall +40 (int (*)(...))QQmlContext::~QQmlContext +48 (int (*)(...))QQmlContext::~QQmlContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlContext + size=16 align=8 + base size=16 base align=8 +QQmlContext (0x0x7f6f367f7068) 0 + vptr=((& QQmlContext::_ZTV11QQmlContext) + 16) + QObject (0x0x7f6f367f9120) 0 + primary-for QQmlContext (0x0x7f6f367f7068) + +Class QQmlScriptString + size=8 align=8 + base size=8 base align=8 +QQmlScriptString (0x0x7f6f367f9840) 0 + +Class QQmlExpression::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExpression::QPrivateSignal (0x0x7f6f367f9e40) 0 empty + +Vtable for QQmlExpression +QQmlExpression::_ZTV14QQmlExpression: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QQmlExpression) +16 (int (*)(...))QQmlExpression::metaObject +24 (int (*)(...))QQmlExpression::qt_metacast +32 (int (*)(...))QQmlExpression::qt_metacall +40 (int (*)(...))QQmlExpression::~QQmlExpression +48 (int (*)(...))QQmlExpression::~QQmlExpression +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlExpression + size=16 align=8 + base size=16 base align=8 +QQmlExpression (0x0x7f6f367f71a0) 0 + vptr=((& QQmlExpression::_ZTV14QQmlExpression) + 16) + QObject (0x0x7f6f367f9de0) 0 + primary-for QQmlExpression (0x0x7f6f367f71a0) + +Vtable for QQmlTypesExtensionInterface +QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QQmlTypesExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlTypesExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlTypesExtensionInterface (0x0x7f6f36827000) 0 nearly-empty + vptr=((& QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface) + 16) + +Vtable for QQmlExtensionInterface +QQmlExtensionInterface::_ZTV22QQmlExtensionInterface: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QQmlExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlExtensionInterface (0x0x7f6f367f7208) 0 nearly-empty + vptr=((& QQmlExtensionInterface::_ZTV22QQmlExtensionInterface) + 16) + QQmlTypesExtensionInterface (0x0x7f6f36827060) 0 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f6f367f7208) + +Vtable for QQmlEngineExtensionInterface +QQmlEngineExtensionInterface::_ZTV28QQmlEngineExtensionInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QQmlEngineExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlEngineExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlEngineExtensionInterface (0x0x7f6f368270c0) 0 nearly-empty + vptr=((& QQmlEngineExtensionInterface::_ZTV28QQmlEngineExtensionInterface) + 16) + +Class QQmlExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExtensionPlugin::QPrivateSignal (0x0x7f6f36827660) 0 empty + +Vtable for QQmlExtensionPlugin +QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +16 (int (*)(...))QQmlExtensionPlugin::metaObject +24 (int (*)(...))QQmlExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlExtensionPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQmlExtensionPlugin::unregisterTypes +128 (int (*)(...))QQmlExtensionPlugin::initializeEngine +136 (int (*)(...))-16 +144 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +152 0 +160 0 +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))QQmlExtensionPlugin::_ZThn16_N19QQmlExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlExtensionPlugin (0x0x7f6f36783c40) 0 + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 16) + QObject (0x0x7f6f368275a0) 0 + primary-for QQmlExtensionPlugin (0x0x7f6f36783c40) + QQmlExtensionInterface (0x0x7f6f367f7270) 16 nearly-empty + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 152) + QQmlTypesExtensionInterface (0x0x7f6f36827600) 16 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f6f367f7270) + +Class QQmlEngineExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngineExtensionPlugin::QPrivateSignal (0x0x7f6f368278a0) 0 empty + +Vtable for QQmlEngineExtensionPlugin +QQmlEngineExtensionPlugin::_ZTV25QQmlEngineExtensionPlugin: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QQmlEngineExtensionPlugin) +16 (int (*)(...))QQmlEngineExtensionPlugin::metaObject +24 (int (*)(...))QQmlEngineExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlEngineExtensionPlugin::qt_metacall +40 (int (*)(...))QQmlEngineExtensionPlugin::~QQmlEngineExtensionPlugin +48 (int (*)(...))QQmlEngineExtensionPlugin::~QQmlEngineExtensionPlugin +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlEngineExtensionPlugin::initializeEngine +120 (int (*)(...))-16 +128 (int (*)(...))(& _ZTI25QQmlEngineExtensionPlugin) +136 (int (*)(...))QQmlEngineExtensionPlugin::_ZThn16_N25QQmlEngineExtensionPluginD1Ev +144 (int (*)(...))QQmlEngineExtensionPlugin::_ZThn16_N25QQmlEngineExtensionPluginD0Ev +152 (int (*)(...))QQmlEngineExtensionPlugin::_ZThn16_N25QQmlEngineExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlEngineExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlEngineExtensionPlugin (0x0x7f6f36783d20) 0 + vptr=((& QQmlEngineExtensionPlugin::_ZTV25QQmlEngineExtensionPlugin) + 16) + QObject (0x0x7f6f368277e0) 0 + primary-for QQmlEngineExtensionPlugin (0x0x7f6f36783d20) + QQmlEngineExtensionInterface (0x0x7f6f36827840) 16 nearly-empty + vptr=((& QQmlEngineExtensionPlugin::_ZTV25QQmlEngineExtensionPlugin) + 136) + +Class QQmlFile + size=8 align=8 + base size=8 base align=8 +QQmlFile (0x0x7f6f36827960) 0 + +Class QQmlFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlFileSelector::QPrivateSignal (0x0x7f6f36827a20) 0 empty + +Vtable for QQmlFileSelector +QQmlFileSelector::_ZTV16QQmlFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlFileSelector) +16 (int (*)(...))QQmlFileSelector::metaObject +24 (int (*)(...))QQmlFileSelector::qt_metacast +32 (int (*)(...))QQmlFileSelector::qt_metacall +40 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +48 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlFileSelector + size=16 align=8 + base size=16 base align=8 +QQmlFileSelector (0x0x7f6f367f7340) 0 + vptr=((& QQmlFileSelector::_ZTV16QQmlFileSelector) + 16) + QObject (0x0x7f6f368279c0) 0 + primary-for QQmlFileSelector (0x0x7f6f367f7340) + +Vtable for QQmlIncubator +QQmlIncubator::_ZTV13QQmlIncubator: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlIncubator) +16 (int (*)(...))QQmlIncubator::~QQmlIncubator +24 (int (*)(...))QQmlIncubator::~QQmlIncubator +32 (int (*)(...))QQmlIncubator::statusChanged +40 (int (*)(...))QQmlIncubator::setInitialState + +Class QQmlIncubator + size=16 align=8 + base size=16 base align=8 +QQmlIncubator (0x0x7f6f36827ba0) 0 + vptr=((& QQmlIncubator::_ZTV13QQmlIncubator) + 16) + +Vtable for QQmlIncubationController +QQmlIncubationController::_ZTV24QQmlIncubationController: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQmlIncubationController) +16 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +24 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +32 (int (*)(...))QQmlIncubationController::incubatingObjectCountChanged + +Class QQmlIncubationController + size=16 align=8 + base size=16 base align=8 +QQmlIncubationController (0x0x7f6f36827c00) 0 + vptr=((& QQmlIncubationController::_ZTV24QQmlIncubationController) + 16) + +Class QQmlInfo + size=16 align=8 + base size=16 base align=8 +QQmlInfo (0x0x7f6f367f73a8) 0 + QDebug (0x0x7f6f367f7410) 0 + QIODeviceBase (0x0x7f6f36827c60) 0 empty + +Class QQmlModuleRegistration + size=8 align=8 + base size=8 base align=8 +QQmlModuleRegistration (0x0x7f6f368a26c0) 0 + +Vtable for QQmlNetworkAccessManagerFactory +QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI31QQmlNetworkAccessManagerFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlNetworkAccessManagerFactory + size=8 align=8 + base size=8 base align=8 +QQmlNetworkAccessManagerFactory (0x0x7f6f368a2720) 0 nearly-empty + vptr=((& QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory) + 16) + +Class QQmlProperty + size=8 align=8 + base size=8 base align=8 +QQmlProperty (0x0x7f6f368a2780) 0 + +Class QQmlPropertyMap::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlPropertyMap::QPrivateSignal (0x0x7f6f368d99c0) 0 empty + +Vtable for QQmlPropertyMap +QQmlPropertyMap::_ZTV15QQmlPropertyMap: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQmlPropertyMap) +16 (int (*)(...))QQmlPropertyMap::metaObject +24 (int (*)(...))QQmlPropertyMap::qt_metacast +32 (int (*)(...))QQmlPropertyMap::qt_metacall +40 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +48 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlPropertyMap::updateValue + +Class QQmlPropertyMap + size=16 align=8 + base size=16 base align=8 +QQmlPropertyMap (0x0x7f6f368dcd00) 0 + vptr=((& QQmlPropertyMap::_ZTV15QQmlPropertyMap) + 16) + QObject (0x0x7f6f368d9960) 0 + primary-for QQmlPropertyMap (0x0x7f6f368dcd00) + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f368f3a80) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f368f3de0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f36907000) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f36907360) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f36907540) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f369078a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f36907a20) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f36907d80) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f36907f60) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f36927300) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f369274e0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f36927840) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f36927a20) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f36927d80) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f36927f60) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f36946300) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f3655cba0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f3655cf00) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f365730c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f36573420) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f365735a0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f36573900) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f36573a80) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f36573de0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f36573f60) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f36591300) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f36591480) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f365917e0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f36591960) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f36591cc0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f6f36591e40) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f6f365aa1e0) 0 empty + diff --git a/tests/auto/bic/data/QtQuick.6.2.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuick.6.2.0.linux-gcc-amd64.txt new file mode 100644 index 00000000000..221f5b50f56 --- /dev/null +++ b/tests/auto/bic/data/QtQuick.6.2.0.linux-gcc-amd64.txt @@ -0,0 +1,12616 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f65ce87df60) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f65cc5b4780) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f65cc5b49c0) 0 empty + +Class std::__do_is_implicitly_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_implicitly_default_constructible_impl (0x0x7f65cc5e2ae0) 0 empty + +Class std::__make_unsigned_selector_base + size=1 align=1 + base size=0 base align=1 +std::__make_unsigned_selector_base (0x0x7f65cc642300) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f65cc2bb120) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f65cc2bb1e0) 0 empty + +Class std::__invoke_memfun_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_ref (0x0x7f65cc2bb6c0) 0 empty + +Class std::__invoke_memfun_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_deref (0x0x7f65cc2bb720) 0 empty + +Class std::__invoke_memobj_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_ref (0x0x7f65cc2bb780) 0 empty + +Class std::__invoke_memobj_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_deref (0x0x7f65cc2bb7e0) 0 empty + +Class std::__invoke_other + size=1 align=1 + base size=0 base align=1 +std::__invoke_other (0x0x7f65cc2bb840) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f65cc2bb900) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f65cc2bb9c0) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f65cc2bba80) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f65cc2bbb40) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f65cc2bbea0) 0 empty + +Class std::__swappable_details::__do_is_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_swappable_impl (0x0x7f65cc2f6240) 0 empty + +Class std::__swappable_details::__do_is_nothrow_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_nothrow_swappable_impl (0x0x7f65cc2f62a0) 0 empty + +Class std::__swappable_with_details::__do_is_swappable_with_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_with_details::__do_is_swappable_with_impl (0x0x7f65cc2f6540) 0 empty + +Class std::__swappable_with_details::__do_is_nothrow_swappable_with_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_with_details::__do_is_nothrow_swappable_with_impl (0x0x7f65cc2f65a0) 0 empty + +Class std::__nonesuch + size=1 align=1 + base size=0 base align=1 +std::__nonesuch (0x0x7f65cc2f6de0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f65cc3853c0) 0 empty + +Class std::__nonesuch_no_braces + size=1 align=1 + base size=1 base align=1 +std::__nonesuch_no_braces (0x0x7f65cc314d00) 0 empty + std::__nonesuch (0x0x7f65cc3858a0) 0 empty + +Class std::in_place_t + size=1 align=1 + base size=0 base align=1 +std::in_place_t (0x0x7f65cc407600) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f65cc407900) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f65cc407960) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f65cc46e6c0) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f65cc46e720) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f65cc421270) 0 empty + std::input_iterator_tag (0x0x7f65cc46e780) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f65cc4212d8) 0 empty + std::forward_iterator_tag (0x0x7f65cc421340) 0 empty + std::input_iterator_tag (0x0x7f65cc46e7e0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f65cc4213a8) 0 empty + std::bidirectional_iterator_tag (0x0x7f65cc421410) 0 empty + std::forward_iterator_tag (0x0x7f65cc421478) 0 empty + std::input_iterator_tag (0x0x7f65cc46e840) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f65cb924540) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f65cb924660) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f65cb924960) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f65cb924c60) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f65cb924d80) 0 empty + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f65cb9e45a0) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f65cb9e48a0) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f65cb9e4900) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f65cb9e49c0) 0 + +Class __pthread_internal_slist + size=8 align=8 + base size=8 base align=8 +__pthread_internal_slist (0x0x7f65cb9e4a20) 0 + +Class __pthread_mutex_s + size=40 align=8 + base size=40 base align=8 +__pthread_mutex_s (0x0x7f65cb9e4a80) 0 + +Class __pthread_rwlock_arch_t + size=56 align=8 + base size=56 base align=8 +__pthread_rwlock_arch_t (0x0x7f65cb9e4ae0) 0 + +Class __pthread_cond_s + size=48 align=8 + base size=48 base align=8 +__pthread_cond_s (0x0x7f65cb9e4b40) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f65cb9e4de0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f65cba190c0) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f65cba19120) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f65cba19ea0) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f65cc421820) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16) + std::exception (0x0x7f65cb6d80c0) 0 nearly-empty + primary-for std::bad_exception (0x0x7f65cc421820) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f65cb6d82a0) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f65cc421888) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16) + std::exception (0x0x7f65cb6d8660) 0 nearly-empty + primary-for std::bad_cast (0x0x7f65cc421888) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f65cc4218f0) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16) + std::exception (0x0x7f65cb6d8840) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f65cc4218f0) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f65cb6d8a20) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f65cb6d8f60) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f65cc421958) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16) + std::exception (0x0x7f65cb715660) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f65cc421958) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f65cc4219c0) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16) + std::bad_alloc (0x0x7f65cc421a28) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f65cc4219c0) + std::exception (0x0x7f65cb715840) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f65cc421a28) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f65cb715a20) 0 empty + +Class std::__allocator_traits_base + size=1 align=1 + base size=0 base align=1 +std::__allocator_traits_base (0x0x7f65cb715c60) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f65cb7c4420) 0 empty + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f65cb39d7e0) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f65cb39d8a0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f65cb415780) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f65cb415840) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f65cb4158a0) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f65cb415900) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f65cb415960) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f65cb415a80) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f65cb415ae0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f65cb0d0180) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f65cb0d0300) 0 empty + +Class _G_fpos_t + size=16 align=8 + base size=16 base align=8 +_G_fpos_t (0x0x7f65caefa180) 0 + +Class _G_fpos64_t + size=16 align=8 + base size=16 base align=8 +_G_fpos64_t (0x0x7f65caefa1e0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f65caefa240) 0 + +Class _IO_cookie_io_functions_t + size=32 align=8 + base size=32 base align=8 +_IO_cookie_io_functions_t (0x0x7f65caefa2a0) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f65cab14a20) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f65caabd9c0) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16) + std::exception (0x0x7f65cab14ae0) 0 nearly-empty + primary-for std::logic_error (0x0x7f65caabd9c0) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f65caabda28) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16) + std::logic_error (0x0x7f65caabda90) 0 + primary-for std::domain_error (0x0x7f65caabda28) + std::exception (0x0x7f65cab14b40) 0 nearly-empty + primary-for std::logic_error (0x0x7f65caabda90) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f65caabdaf8) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16) + std::logic_error (0x0x7f65caabdb60) 0 + primary-for std::invalid_argument (0x0x7f65caabdaf8) + std::exception (0x0x7f65cab14ba0) 0 nearly-empty + primary-for std::logic_error (0x0x7f65caabdb60) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f65caabdbc8) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16) + std::logic_error (0x0x7f65caabdc30) 0 + primary-for std::length_error (0x0x7f65caabdbc8) + std::exception (0x0x7f65cab14c00) 0 nearly-empty + primary-for std::logic_error (0x0x7f65caabdc30) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f65caabdc98) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16) + std::logic_error (0x0x7f65caabdd00) 0 + primary-for std::out_of_range (0x0x7f65caabdc98) + std::exception (0x0x7f65cab14c60) 0 nearly-empty + primary-for std::logic_error (0x0x7f65caabdd00) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f65caabdd68) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16) + std::exception (0x0x7f65cab14cc0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f65caabdd68) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f65caabddd0) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16) + std::runtime_error (0x0x7f65caabde38) 0 + primary-for std::range_error (0x0x7f65caabddd0) + std::exception (0x0x7f65cab14d20) 0 nearly-empty + primary-for std::runtime_error (0x0x7f65caabde38) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f65caabdea0) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16) + std::runtime_error (0x0x7f65caabdf08) 0 + primary-for std::overflow_error (0x0x7f65caabdea0) + std::exception (0x0x7f65cab14d80) 0 nearly-empty + primary-for std::runtime_error (0x0x7f65caabdf08) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f65caabdf70) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16) + std::runtime_error (0x0x7f65cab7f000) 0 + primary-for std::underflow_error (0x0x7f65caabdf70) + std::exception (0x0x7f65cab14de0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f65cab7f000) + +Class std::__erased_type + size=1 align=1 + base size=0 base align=1 +std::__erased_type (0x0x7f65cabb4120) 0 empty + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f65cabb4180) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f65cabb4300) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f65cabb43c0) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f65cab7f270) 0 + std::__uses_alloc_base (0x0x7f65cabb4360) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f65ca9249c0) 0 empty + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f65ca9ce680) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16) + std::exception (0x0x7f65ca9f90c0) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f65ca9ce680) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f65ca9f9180) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f65ca9f91e0) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f65ca9f94e0) 0 + +Class std::__detail::_Identity + size=1 align=1 + base size=0 base align=1 +std::__detail::_Identity (0x0x7f65ca6cd360) 0 empty + +Class std::__detail::_Select1st + size=1 align=1 + base size=0 base align=1 +std::__detail::_Select1st (0x0x7f65ca6cd420) 0 empty + +Class std::__detail::_Hash_node_base + size=8 align=8 + base size=8 base align=8 +std::__detail::_Hash_node_base (0x0x7f65ca6cd900) 0 + +Class std::__detail::_Mod_range_hashing + size=1 align=1 + base size=0 base align=1 +std::__detail::_Mod_range_hashing (0x0x7f65ca6f2780) 0 empty + +Class std::__detail::_Default_ranged_hash + size=1 align=1 + base size=0 base align=1 +std::__detail::_Default_ranged_hash (0x0x7f65ca6f2840) 0 empty + +Class std::__detail::_Prime_rehash_policy + size=16 align=8 + base size=16 base align=8 +std::__detail::_Prime_rehash_policy (0x0x7f65ca6f28a0) 0 + +Class std::__detail::_Mask_range_hashing + size=1 align=1 + base size=0 base align=1 +std::__detail::_Mask_range_hashing (0x0x7f65ca6f2c60) 0 empty + +Class std::__detail::_Power2_rehash_policy + size=16 align=8 + base size=16 base align=8 +std::__detail::_Power2_rehash_policy (0x0x7f65ca6f2d80) 0 + +Class std::__detail::_Equality_base + size=1 align=1 + base size=0 base align=1 +std::__detail::_Equality_base (0x0x7f65ca4d1e40) 0 empty + +Class std::_Enable_default_constructor_tag + size=1 align=1 + base size=0 base align=1 +std::_Enable_default_constructor_tag (0x0x7f65ca50a720) 0 empty + +Class std::nullopt_t + size=1 align=1 + base size=0 base align=1 +std::nullopt_t (0x0x7f65ca559120) 0 empty + +Vtable for std::bad_optional_access +std::bad_optional_access::_ZTVSt19bad_optional_access: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt19bad_optional_access) +16 (int (*)(...))std::bad_optional_access::~bad_optional_access +24 (int (*)(...))std::bad_optional_access::~bad_optional_access +32 (int (*)(...))std::bad_optional_access::what + +Class std::bad_optional_access + size=8 align=8 + base size=8 base align=8 +std::bad_optional_access (0x0x7f65ca5115b0) 0 nearly-empty + vptr=((& std::bad_optional_access::_ZTVSt19bad_optional_access) + 16) + std::exception (0x0x7f65ca559360) 0 nearly-empty + primary-for std::bad_optional_access (0x0x7f65ca5115b0) + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f65c9ffacc0) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f65c9fa00d0) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f65ca01a480) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f65c9fa01a0) 0 + std::_Bit_iterator_base (0x0x7f65c9fa0208) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f65ca01aa20) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f65c9fa02d8) 0 + std::_Bit_iterator_base (0x0x7f65c9fa0340) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f65ca0501e0) 0 empty + +Class __pstl::execution::v1::sequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::sequenced_policy (0x0x7f65c9e31720) 0 empty + +Class __pstl::execution::v1::parallel_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::parallel_policy (0x0x7f65c9e318a0) 0 empty + +Class __pstl::execution::v1::parallel_unsequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::parallel_unsequenced_policy (0x0x7f65c9e31a20) 0 empty + +Class __pstl::execution::v1::unsequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::unsequenced_policy (0x0x7f65c9e31ba0) 0 empty + +Class std::__detail::__variant::__variant_cookie + size=1 align=1 + base size=0 base align=1 +std::__detail::__variant::__variant_cookie (0x0x7f65c9b63720) 0 empty + +Class std::__detail::__variant::__variant_idx_cookie + size=1 align=1 + base size=0 base align=1 +std::__detail::__variant::__variant_idx_cookie (0x0x7f65c9b63780) 0 empty + +Class std::monostate + size=1 align=1 + base size=0 base align=1 +std::monostate (0x0x7f65c9c3f240) 0 empty + +Vtable for std::bad_variant_access +std::bad_variant_access::_ZTVSt18bad_variant_access: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt18bad_variant_access) +16 (int (*)(...))std::bad_variant_access::~bad_variant_access +24 (int (*)(...))std::bad_variant_access::~bad_variant_access +32 (int (*)(...))std::bad_variant_access::what + +Class std::bad_variant_access + size=16 align=8 + base size=16 base align=8 +std::bad_variant_access (0x0x7f65c9baa6e8) 0 + vptr=((& std::bad_variant_access::_ZTVSt18bad_variant_access) + 16) + std::exception (0x0x7f65c9c63780) 0 nearly-empty + primary-for std::bad_variant_access (0x0x7f65c9baa6e8) + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f65c99231e0) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f65c9923240) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f65c99234e0) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f65c9923d20) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f65c997ede0) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f65c9a300c0) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f65c99bd9c0) 0 + std::__atomic_flag_base (0x0x7f65c9a30120) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f65c9597c98) 0 + QAtomicInteger<int> (0x0x7f65c9597d00) 0 + QBasicAtomicInteger<int> (0x0x7f65c95df060) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f65c8e39300) 0 empty + +Class QKeyCombination + size=4 align=4 + base size=4 base align=4 +QKeyCombination (0x0x7f65c8e39360) 0 + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f65c8af8660) 0 + +Class QMethodRawArguments + size=8 align=8 + base size=8 base align=8 +QMethodRawArguments (0x0x7f65c8af8d80) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f65c8af8de0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f65c8b2b138) 0 + QGenericArgument (0x0x7f65c8b350c0) 0 + +Class QMetaObject::SuperData + size=8 align=8 + base size=8 base align=8 +QMetaObject::SuperData (0x0x7f65c8b355a0) 0 + +Class QMetaObject::Data + size=56 align=8 + base size=56 base align=8 +QMetaObject::Data (0x0x7f65c8b35600) 0 + +Class QMetaObject + size=56 align=8 + base size=56 base align=8 +QMetaObject (0x0x7f65c8b35540) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f65c8b35f60) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f65c8ba99c0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f65c8bd43c0) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f65c8892ea0) 0 + +Class QArrayData + size=16 align=8 + base size=16 base align=8 +QArrayData (0x0x7f65c88b1240) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f65c8945cc0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f65c8945de0) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f65c89841e0) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f65c8984480) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f65c8984660) 0 + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f65c89d2780) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f65c89d2ae0) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f65c8a10300) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f65c89c5618) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16) + std::runtime_error (0x0x7f65c89c5680) 0 + primary-for std::system_error (0x0x7f65c89c5618) + std::exception (0x0x7f65c8a10ea0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f65c89c5680) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f65c89c59c0) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16) + std::system_error (0x0x7f65c89c5a28) 0 + primary-for std::ios_base::failure (0x0x7f65c89c59c0) + std::runtime_error (0x0x7f65c89c5a90) 0 + primary-for std::system_error (0x0x7f65c89c5a28) + std::exception (0x0x7f65c8a75660) 0 nearly-empty + primary-for std::runtime_error (0x0x7f65c89c5a90) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f65c8a756c0) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f65c8a75720) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f65c8a75780) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f65c8a75600) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f65c872e3c0) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f65c87e96c0) 0 empty + +VTT for std::basic_ostream<char> +std::basic_ostream<char>::_ZTTSo: 2 entries +0 ((& std::basic_ostream<char>::_ZTVSo) + 24) +8 ((& std::basic_ostream<char>::_ZTVSo) + 64) + +VTT for std::basic_ostream<wchar_t> +std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64) + +VTT for std::basic_istream<char> +std::basic_istream<char>::_ZTTSi: 2 entries +0 ((& std::basic_istream<char>::_ZTVSi) + 24) +8 ((& std::basic_istream<char>::_ZTVSi) + 64) + +VTT for std::basic_istream<wchar_t> +std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64) + +Construction vtable for std::basic_istream<char> (0x0x7f65c8361618 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd0_Si: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream<char> (0x0x7f65c83616e8 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd16_So: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::basic_iostream<char> +std::basic_iostream<char>::_ZTTSd: 7 entries +0 ((& std::basic_iostream<char>::_ZTVSd) + 24) +8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24) +16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64) +24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24) +32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64) +40 ((& std::basic_iostream<char>::_ZTVSd) + 104) +48 ((& std::basic_iostream<char>::_ZTVSd) + 64) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f65c8361c30 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f65c8361d00 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7 entries +0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24) +16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64) +24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24) +32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64) +40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104) +48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64) + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f65c83d1068) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16) + std::exception (0x0x7f65c83d70c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f65c83d1068) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f65c83d10d0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16) + std::exception (0x0x7f65c83d71e0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f65c83d10d0) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f65c83d1138) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16) + std::exception (0x0x7f65c83d7300) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f65c83d1138) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f65c83d1208) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16) + std::exception (0x0x7f65c83d7420) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f65c83d1208) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f65c83d7cc0) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f65c8405000) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f65c8405300) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f65c8405660) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f65c83d1340) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16) + std::exception (0x0x7f65c8084e40) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f65c83d1340) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f65c80f3c00) 0 empty + +Class std::__sp_array_delete + size=1 align=1 + base size=0 base align=1 +std::__sp_array_delete (0x0x7f65c811c180) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f65c8233f60) 0 + +Class QByteArrayView + size=16 align=8 + base size=16 base align=8 +QByteArrayView (0x0x7f65c7fc3300) 0 + +Class QByteArray + size=24 align=8 + base size=24 base align=8 +QByteArray (0x0x7f65c7cb9420) 0 + +Class QByteArray::FromBase64Result + size=32 align=8 + base size=28 base align=8 +QByteArray::FromBase64Result (0x0x7f65c7b087e0) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f65c7b97780) 0 + +Class QChar::fromUcs4(char32_t)::R + size=4 align=2 + base size=4 base align=2 +QChar::fromUcs4(char32_t)::R (0x0x7f65c79166c0) 0 + +Class QtPrivate::hide_char8_t + size=1 align=1 + base size=0 base align=1 +QtPrivate::hide_char8_t (0x0x7f65c7916ae0) 0 empty + +Class QtPrivate::wrap_char + size=1 align=1 + base size=0 base align=1 +QtPrivate::wrap_char (0x0x7f65c7916b40) 0 empty + +Class QAnyStringView + size=16 align=8 + base size=16 base align=8 +QAnyStringView (0x0x7f65c799b8a0) 0 + +Class QStringTokenizerBaseBase::tokenizer_state + size=24 align=8 + base size=24 base align=8 +QStringTokenizerBaseBase::tokenizer_state (0x0x7f65c7689a80) 0 + +Class QStringTokenizerBaseBase + size=8 align=4 + base size=8 base align=4 +QStringTokenizerBaseBase (0x0x7f65c7689a20) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f65c76d1960) 0 + +Class QString + size=24 align=8 + base size=24 base align=8 +QString (0x0x7f65c783cc00) 0 + +Class QtPrivate::ArgBase + size=1 align=1 + base size=1 base align=1 +QtPrivate::ArgBase (0x0x7f65c7435f00) 0 + +Class QtPrivate::QStringViewArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QStringViewArg (0x0x7f65c7446208) 0 + QtPrivate::ArgBase (0x0x7f65c7435f60) 0 + +Class QtPrivate::QLatin1StringArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QLatin1StringArg (0x0x7f65c74462d8) 0 + QtPrivate::ArgBase (0x0x7f65c746c1e0) 0 + +Class QHashSeed + size=8 align=8 + base size=8 base align=8 +QHashSeed (0x0x7f65c70a2a20) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f65c70db9c0) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f65c70dba80) 0 empty + +Class QStringMatcher + size=312 align=8 + base size=312 base align=8 +QStringMatcher (0x0x7f65c6eeef60) 0 + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f65c6fb4120) 0 empty + +Class QtPrivate::CompareAgainstLiteralZero + size=1 align=1 + base size=0 base align=1 +QtPrivate::CompareAgainstLiteralZero (0x0x7f65c6fb4e40) 0 empty + +Class QPartialOrdering + size=1 align=1 + base size=1 base align=1 +QPartialOrdering (0x0x7f65c6fd70c0) 0 + +Class QIODeviceBase + size=1 align=1 + base size=0 base align=1 +QIODeviceBase (0x0x7f65c7057ba0) 0 empty + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f65c7166ea0) 0 + QIODeviceBase (0x0x7f65c7057c00) 0 empty + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f65c7057d80) 0 + +Class QtMetaContainerPrivate::QMetaContainerInterface + size=120 align=8 + base size=120 base align=8 +QtMetaContainerPrivate::QMetaContainerInterface (0x0x7f65c6d76360) 0 + +Class QtMetaContainerPrivate::QMetaSequenceInterface + size=216 align=8 + base size=216 base align=8 +QtMetaContainerPrivate::QMetaSequenceInterface (0x0x7f65c6d46680) 0 + QtMetaContainerPrivate::QMetaContainerInterface (0x0x7f65c6d76420) 0 + +Class QtMetaContainerPrivate::QMetaAssociationInterface + size=240 align=8 + base size=240 base align=8 +QtMetaContainerPrivate::QMetaAssociationInterface (0x0x7f65c6d46750) 0 + QtMetaContainerPrivate::QMetaContainerInterface (0x0x7f65c6d764e0) 0 + +Class QMetaContainer + size=8 align=8 + base size=8 base align=8 +QMetaContainer (0x0x7f65c6e49000) 0 + +Class QMetaSequence + size=8 align=8 + base size=8 base align=8 +QMetaSequence (0x0x7f65c6d46af8) 0 + QMetaContainer (0x0x7f65c6e491e0) 0 + +Class QMetaAssociation + size=8 align=8 + base size=8 base align=8 +QMetaAssociation (0x0x7f65c6d46b60) 0 + QMetaContainer (0x0x7f65c6e495a0) 0 + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f65c6b41780) 0 + +Class std::__detail::_List_node_header + size=24 align=8 + base size=24 base align=8 +std::__detail::_List_node_header (0x0x7f65c6aecbc8) 0 + std::__detail::_List_node_base (0x0x7f65c6b417e0) 0 + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f65c6c328a0) 0 + +Class std::_Rb_tree_header + size=40 align=8 + base size=40 base align=8 +std::_Rb_tree_header (0x0x7f65c6c32c00) 0 + +Class QtPrivate::QMetaTypeInterface + size=112 align=8 + base size=112 base align=8 +QtPrivate::QMetaTypeInterface (0x0x7f65c66bc0c0) 0 + +Class QMetaType + size=8 align=8 + base size=8 base align=8 +QMetaType (0x0x7f65c66bc2a0) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f65c6772300) 0 + +Class QtPrivate::QTypeNormalizer + size=16 align=8 + base size=16 base align=8 +QtPrivate::QTypeNormalizer (0x0x7f65c665dba0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f65c624aea0) 0 + +Class QAdoptSharedDataTag + size=1 align=1 + base size=0 base align=1 +QAdoptSharedDataTag (0x0x7f65c627e240) 0 empty + +Class QtPrivate::RefCounted + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCounted (0x0x7f65c5ed72a0) 0 + +Class QPropertyBindingPrivatePtr + size=8 align=8 + base size=8 base align=8 +QPropertyBindingPrivatePtr (0x0x7f65c5ed73c0) 0 + +Class QUntypedPropertyData::InheritsQUntypedPropertyData + size=1 align=1 + base size=0 base align=1 +QUntypedPropertyData::InheritsQUntypedPropertyData (0x0x7f65c5f26a20) 0 empty + +Class QUntypedPropertyData + size=1 align=1 + base size=0 base align=1 +QUntypedPropertyData (0x0x7f65c5f269c0) 0 empty + +Class QPropertyProxyBindingData + size=24 align=8 + base size=24 base align=8 +QPropertyProxyBindingData (0x0x7f65c5f26a80) 0 + +Class QtPrivate::BindingFunctionVTable + size=32 align=8 + base size=32 base align=8 +QtPrivate::BindingFunctionVTable (0x0x7f65c5f26ae0) 0 + +Class QtPrivate::QPropertyBindingFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::QPropertyBindingFunction (0x0x7f65c5f4a060) 0 + +Class QtPrivate::QPropertyBindingData + size=8 align=8 + base size=8 base align=8 +QtPrivate::QPropertyBindingData (0x0x7f65c5f4a0c0) 0 + +Class std::experimental::fundamentals_v2::source_location + size=24 align=8 + base size=24 base align=8 +std::experimental::fundamentals_v2::source_location (0x0x7f65c5f4a7e0) 0 + +Class QPropertyBindingSourceLocation + size=24 align=8 + base size=24 base align=8 +QPropertyBindingSourceLocation (0x0x7f65c5f4af00) 0 + +Class QPropertyBindingError + size=8 align=8 + base size=8 base align=8 +QPropertyBindingError (0x0x7f65c5f81240) 0 + +Class QUntypedPropertyBinding + size=8 align=8 + base size=8 base align=8 +QUntypedPropertyBinding (0x0x7f65c5f81360) 0 + +Class QPropertyObserverBase + size=24 align=8 + base size=24 base align=8 +QPropertyObserverBase (0x0x7f65c5f815a0) 0 + +Class QPropertyObserver + size=24 align=8 + base size=24 base align=8 +QPropertyObserver (0x0x7f65c5f37618) 0 + QPropertyObserverBase (0x0x7f65c5f81720) 0 + +Class QPropertyNotifier + size=56 align=8 + base size=56 base align=8 +QPropertyNotifier (0x0x7f65c5f37958) 0 + QPropertyObserver (0x0x7f65c5f379c0) 0 + QPropertyObserverBase (0x0x7f65c5f81c00) 0 + +Class QtPrivate::QBindableInterface + size=56 align=8 + base size=56 base align=8 +QtPrivate::QBindableInterface (0x0x7f65c5ff3ae0) 0 + +Class QUntypedBindable + size=16 align=8 + base size=16 base align=8 +QUntypedBindable (0x0x7f65c6020c60) 0 + +Class QBindingStatus + size=32 align=8 + base size=32 base align=8 +QBindingStatus (0x0x7f65c5d37ba0) 0 + +Class QBindingStorage + size=16 align=8 + base size=16 base align=8 +QBindingStorage (0x0x7f65c5d37c00) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f65c5e3d9c0) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f65c5aee720) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=80 align=8 + base size=80 base align=8 +QObjectData (0x0x7f65c5bd80c0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f65c5bd8a20) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f65c5bd89c0) 0 + vptr=((& QObject::_ZTV7QObject) + 16) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f65c5897960) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f65c58c9240) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f65c5b81ea0) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16) + QObject (0x0x7f65c58c91e0) 0 + primary-for QAbstractAnimation (0x0x7f65c5b81ea0) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f65c58c95a0) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f65c5b81f08) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16) + QObject (0x0x7f65c58c9540) 0 + primary-for QAnimationDriver (0x0x7f65c5b81f08) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f65c58c9780) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f65c5b81f70) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16) + QObject (0x0x7f65c58c9720) 0 + primary-for QEventLoop (0x0x7f65c5b81f70) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f65c58c9cc0) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f65c58c9d80) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f65c58c9de0) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))QAbstractEventDispatcher::startingUp +200 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f65c59020d0) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16) + QObject (0x0x7f65c58c9d20) 0 + primary-for QAbstractEventDispatcher (0x0x7f65c59020d0) + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f65c596d5a0) 0 empty + +Class QStringConverterBase::State + size=48 align=8 + base size=48 base align=8 +QStringConverterBase::State (0x0x7f65c585a1e0) 0 + +Class QStringConverterBase + size=1 align=1 + base size=0 base align=1 +QStringConverterBase (0x0x7f65c585a180) 0 empty + +Class QStringConverter::Interface + size=40 align=8 + base size=40 base align=8 +QStringConverter::Interface (0x0x7f65c585ade0) 0 + +Class QStringConverter + size=56 align=8 + base size=56 base align=8 +QStringConverter (0x0x7f65c5863270) 0 + QStringConverterBase (0x0x7f65c585ad80) 0 empty + +Class QStringEncoder + size=56 align=8 + base size=56 base align=8 +QStringEncoder (0x0x7f65c58632d8) 0 + QStringConverter (0x0x7f65c5863340) 0 + QStringConverterBase (0x0x7f65c54b67e0) 0 empty + +Class QStringDecoder + size=56 align=8 + base size=56 base align=8 +QStringDecoder (0x0x7f65c58633a8) 0 + QStringConverter (0x0x7f65c5863410) 0 + QStringConverterBase (0x0x7f65c54d7660) 0 empty + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f65c5863478) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16) + QIODeviceBase (0x0x7f65c54f8360) 0 empty + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f65c54f8ae0) 0 + +Class QContiguousCacheData + size=40 align=8 + base size=40 base align=8 +QContiguousCacheData (0x0x7f65c55e0cc0) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f65c5633360) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f65c56334e0) 0 + +Class QtPrivate::EnableInternalData + size=1 align=1 + base size=0 base align=1 +QtPrivate::EnableInternalData (0x0x7f65c52e7720) 0 empty + +Class QDebug::Stream + size=88 align=8 + base size=88 base align=8 +QDebug::Stream (0x0x7f65c5308660) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f65c52bff08) 0 + QIODeviceBase (0x0x7f65c5308600) 0 empty + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f65c5430000) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f65c54300c0) 0 empty + +Class QVariant::PrivateShared + size=8 align=8 + base size=8 base align=8 +QVariant::PrivateShared (0x0x7f65c51afcc0) 0 + +Class QVariant::Private + size=32 align=8 + base size=32 base align=8 +QVariant::Private (0x0x7f65c51afd20) 0 + +Class QVariant + size=32 align=8 + base size=32 base align=8 +QVariant (0x0x7f65c51afc60) 0 + +Class QtPrivate::QVariantTypeCoercer + size=32 align=8 + base size=32 base align=8 +QtPrivate::QVariantTypeCoercer (0x0x7f65c4fa5480) 0 + +Class QVariantConstPointer + size=32 align=8 + base size=32 base align=8 +QVariantConstPointer (0x0x7f65c4fa56c0) 0 + +Class QModelRoleData + size=40 align=8 + base size=40 base align=8 +QModelRoleData (0x0x7f65c4fa58a0) 0 + +Class QModelRoleDataSpan + size=16 align=8 + base size=16 base align=8 +QModelRoleDataSpan (0x0x7f65c4fe77e0) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f65c502d7e0) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f65c50789c0) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f65c4d0f2a0) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractItemModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractItemModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f65c4d04d00) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16) + QObject (0x0x7f65c4d0f240) 0 + primary-for QAbstractItemModel (0x0x7f65c4d04d00) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f65c4e57060) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractTableModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractTableModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f65c4d6f5b0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16) + QAbstractItemModel (0x0x7f65c4d6f618) 0 + primary-for QAbstractTableModel (0x0x7f65c4d6f5b0) + QObject (0x0x7f65c4e57000) 0 + primary-for QAbstractItemModel (0x0x7f65c4d6f618) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f65c4e57180) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractListModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractListModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f65c4d6f680) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16) + QAbstractItemModel (0x0x7f65c4d6f6e8) 0 + primary-for QAbstractListModel (0x0x7f65c4d6f680) + QObject (0x0x7f65c4e57120) 0 + primary-for QAbstractItemModel (0x0x7f65c4d6f6e8) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f65c4aa09c0) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f65c4aa0a80) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QAbstractProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QAbstractProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QAbstractProxyModel::setSourceModel +416 (int (*)(...))__cxa_pure_virtual +424 (int (*)(...))__cxa_pure_virtual +432 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +440 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f65c4aa3af8) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16) + QAbstractItemModel (0x0x7f65c4aa3b60) 0 + primary-for QAbstractProxyModel (0x0x7f65c4aa3af8) + QObject (0x0x7f65c4aa0a20) 0 + primary-for QAbstractItemModel (0x0x7f65c4aa3b60) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f65c4aa0c60) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f65c4aa3bc8) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16) + QAbstractAnimation (0x0x7f65c4aa3c30) 0 + primary-for QAnimationGroup (0x0x7f65c4aa3bc8) + QObject (0x0x7f65c4aa0c00) 0 + primary-for QAbstractAnimation (0x0x7f65c4aa3c30) + +Class QAssociativeIterator + size=16 align=8 + base size=16 base align=8 +QAssociativeIterator (0x0x7f65c4aa3d68) 0 + QIterator<QMetaAssociation> (0x0x7f65c4aa3dd0) 0 + QBaseIterator<QMetaAssociation> (0x0x7f65c4b150c0) 0 + +Class QAssociativeConstIterator + size=16 align=8 + base size=16 base align=8 +QAssociativeConstIterator (0x0x7f65c4aa3f08) 0 + QConstIterator<QMetaAssociation> (0x0x7f65c4aa3f70) 0 + QBaseIterator<QMetaAssociation> (0x0x7f65c4b15660) 0 + +Class QAssociativeIterable + size=24 align=8 + base size=24 base align=8 +QAssociativeIterable (0x0x7f65c4b3f000) 0 + QIterable<QMetaAssociation> (0x0x7f65c4b15ba0) 0 + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f65c4c29660) 0 + +Class QBitArray + size=24 align=8 + base size=24 base align=8 +QBitArray (0x0x7f65c48873c0) 0 + +Class QBitRef + size=16 align=8 + base size=16 base align=8 +QBitRef (0x0x7f65c48b7300) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f65c48e3e40) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f65c48f01c0) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16) + QObject (0x0x7f65c48e3d80) 0 + primary-for QIODevice (0x0x7f65c48f01c0) + QIODeviceBase (0x0x7f65c48e3de0) 0 empty + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f65c49182a0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f65c48dcf70) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16) + QIODevice (0x0x7f65c48f0230) 0 + primary-for QBuffer (0x0x7f65c48dcf70) + QObject (0x0x7f65c49181e0) 0 + primary-for QIODevice (0x0x7f65c48f0230) + QIODeviceBase (0x0x7f65c4918240) 0 empty + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f65c49184e0) 0 + +Class QByteArrayMatcher + size=1056 align=8 + base size=1056 base align=8 +QByteArrayMatcher (0x0x7f65c4918480) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f65c4918660) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f65c4918600) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f65c4990e40) 0 + +Class QCalendar::YearMonthDay + size=12 align=4 + base size=12 base align=4 +QCalendar::YearMonthDay (0x0x7f65c46accc0) 0 + +Class QCalendar::SystemId + size=8 align=8 + base size=8 base align=8 +QCalendar::SystemId (0x0x7f65c46acd20) 0 + +Class QCalendar + size=8 align=8 + base size=8 base align=8 +QCalendar (0x0x7f65c46acc60) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f65c4705780) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f65c4759d80) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f65c47be000) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f65c47be060) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f65c47a2f60) 0 + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f65c48442a0) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f65c4880660) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f65c45328a0) 0 + +Class QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel + size=1 align=1 + base size=0 base align=1 +QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel (0x0x7f65c45cc060) 0 empty + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f65c45cc120) 0 + +Class QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator + size=24 align=8 + base size=17 base align=8 +QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator (0x0x7f65c45cc2a0) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f65c46564e0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f65c436e120) 0 + +Class QCborParserError + size=16 align=8 + base size=16 base align=8 +QCborParserError (0x0x7f65c43c62a0) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f65c43c6360) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f65c40ebc00) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f65c4143180) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f65c41431e0) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f65c4143120) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f65c422e780) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f65c422e7e0) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f65c422e720) 0 + +Class qfloat16::Wrap + size=2 align=2 + base size=2 base align=2 +qfloat16::Wrap (0x0x7f65c4045840) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f65c40457e0) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f65c3d31c00) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f65c3dae0c0) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f65c3daeae0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f65c3daecc0) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f65c3e80720) 0 + +Class QEvent::InputEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::InputEventTag (0x0x7f65c3b350c0) 0 empty + +Class QEvent::PointerEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::PointerEventTag (0x0x7f65c3b35120) 0 empty + +Class QEvent::SinglePointEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::SinglePointEventTag (0x0x7f65c3b35180) 0 empty + +Vtable for QEvent +QEvent::_ZTV6QEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QEvent + size=16 align=8 + base size=16 base align=8 +QEvent (0x0x7f65c3b35060) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QTimerEvent::clone + +Class QTimerEvent + size=24 align=8 + base size=20 base align=8 +QTimerEvent (0x0x7f65c3b00410) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16) + QEvent (0x0x7f65c3b35ae0) 0 + primary-for QTimerEvent (0x0x7f65c3b00410) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QChildEvent::clone + +Class QChildEvent + size=24 align=8 + base size=24 base align=8 +QChildEvent (0x0x7f65c3b00478) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16) + QEvent (0x0x7f65c3b7a000) 0 + primary-for QChildEvent (0x0x7f65c3b00478) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDynamicPropertyChangeEvent::clone + +Class QDynamicPropertyChangeEvent + size=40 align=8 + base size=40 base align=8 +QDynamicPropertyChangeEvent (0x0x7f65c3b004e0) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16) + QEvent (0x0x7f65c3b7a420) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f65c3b004e0) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDeferredDeleteEvent::clone + +Class QDeferredDeleteEvent + size=24 align=8 + base size=20 base align=8 +QDeferredDeleteEvent (0x0x7f65c3b00548) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16) + QEvent (0x0x7f65c3b7a6c0) 0 + primary-for QDeferredDeleteEvent (0x0x7f65c3b00548) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f65c3b7aa80) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f65c3b00618) 0 + QBasicMutex (0x0x7f65c3bf27e0) 0 + +Class QRecursiveMutex + size=24 align=8 + base size=24 base align=8 +QRecursiveMutex (0x0x7f65c3bf2c00) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f65c3c5e240) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f65c3c5e840) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f65c38e34e0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f65c39c6f00) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16) + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f65c3a3c0c0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f65c3a3c3c0) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f65c3776780) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f65c37848f0) 0 + std::__mutex_base (0x0x7f65c37767e0) 0 + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f65c37769c0) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f65c3776a20) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f65c3776a80) 0 empty + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f65c37b64e0) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f65c3784958) 0 + std::__recursive_mutex_base (0x0x7f65c37b6540) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f65c3a7cf50) 0 + std::__mutex_base (0x0x7f65c37b6900) 0 + std::__timed_mutex_impl<std::timed_mutex> (0x0x7f65c37b6960) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f65c3a7c700) 0 + std::__recursive_mutex_base (0x0x7f65c37b6d20) 0 + std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7f65c37b6d80) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f65c37f2ba0) 0 + +Vtable for std::thread::_State +std::thread::_State::_ZTVNSt6thread6_StateE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread6_StateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_State + size=8 align=8 + base size=8 base align=8 +std::thread::_State (0x0x7f65c37f2e40) 0 nearly-empty + vptr=((& std::thread::_State::_ZTVNSt6thread6_StateE) + 16) + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f65c37f2ea0) 0 + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f65c37f2de0) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f65c3605120) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f65c36054e0) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f65c3605540) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f65c32c6ae0) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f65c32a8750) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16) + std::logic_error (0x0x7f65c32a87b8) 0 + primary-for std::future_error (0x0x7f65c32a8750) + std::exception (0x0x7f65c32f31e0) 0 nearly-empty + primary-for std::logic_error (0x0x7f65c32a87b8) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f65c32f3900) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f65c32f38a0) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f65c345d360) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f65c3433410) 0 + std::__at_thread_exit_elt (0x0x7f65c345d420) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f65c32f3a80) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f65c32f3840) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f65c2d33340) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16) + std::__future_base::_State_baseV2 (0x0x7f65c2d64120) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f65c2d33340) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f65c2d649c0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f65c2d33680) 0 + vptr=((& QThread::_ZTV7QThread) + 16) + QObject (0x0x7f65c2d64960) 0 + primary-for QThread (0x0x7f65c2d33680) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class QRunnable + size=16 align=8 + base size=9 base align=8 +QRunnable (0x0x7f65c2d64d20) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f65c2d64ea0) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f65c2d336e8) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16) + QObject (0x0x7f65c2d64e40) 0 + primary-for QThreadPool (0x0x7f65c2d336e8) + +Vtable for QException +QException::_ZTV10QException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f65c2d33750) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16) + std::exception (0x0x7f65c2dab060) 0 nearly-empty + primary-for QException (0x0x7f65c2d33750) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=16 align=8 + base size=16 base align=8 +QUnhandledException (0x0x7f65c2d337b8) 0 + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16) + QException (0x0x7f65c2d33820) 0 nearly-empty + primary-for QUnhandledException (0x0x7f65c2d337b8) + std::exception (0x0x7f65c2dab0c0) 0 nearly-empty + primary-for QException (0x0x7f65c2d33820) + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f65c2dabf00) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f65c2c04600) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f65c2c045a0) 0 + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f65c2c29840) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f65c2c26478) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16) + QObject (0x0x7f65c2c297e0) 0 + primary-for QCoreApplication (0x0x7f65c2c26478) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f65c2c29a80) 0 + +Class QConcatenateTablesProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QConcatenateTablesProxyModel::QPrivateSignal (0x0x7f65c2c29ba0) 0 empty + +Vtable for QConcatenateTablesProxyModel +QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QConcatenateTablesProxyModel) +16 (int (*)(...))QConcatenateTablesProxyModel::metaObject +24 (int (*)(...))QConcatenateTablesProxyModel::qt_metacast +32 (int (*)(...))QConcatenateTablesProxyModel::qt_metacall +40 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +48 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QConcatenateTablesProxyModel::index +120 (int (*)(...))QConcatenateTablesProxyModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QConcatenateTablesProxyModel::rowCount +144 (int (*)(...))QConcatenateTablesProxyModel::columnCount +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))QConcatenateTablesProxyModel::data +168 (int (*)(...))QConcatenateTablesProxyModel::setData +176 (int (*)(...))QConcatenateTablesProxyModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QConcatenateTablesProxyModel::itemData +200 (int (*)(...))QConcatenateTablesProxyModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QConcatenateTablesProxyModel::mimeTypes +224 (int (*)(...))QConcatenateTablesProxyModel::mimeData +232 (int (*)(...))QConcatenateTablesProxyModel::canDropMimeData +240 (int (*)(...))QConcatenateTablesProxyModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QConcatenateTablesProxyModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QConcatenateTablesProxyModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QConcatenateTablesProxyModel + size=16 align=8 + base size=16 base align=8 +QConcatenateTablesProxyModel (0x0x7f65c2c264e0) 0 + vptr=((& QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel) + 16) + QAbstractItemModel (0x0x7f65c2c26548) 0 + primary-for QConcatenateTablesProxyModel (0x0x7f65c2c264e0) + QObject (0x0x7f65c2c29b40) 0 + primary-for QAbstractItemModel (0x0x7f65c2c26548) + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f65c2c29d20) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f65c2c29f00) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QFileDevice::fileName +256 (int (*)(...))QFileDevice::resize +264 (int (*)(...))QFileDevice::permissions +272 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f65c2c265b0) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16) + QIODevice (0x0x7f65c2c5fe70) 0 + primary-for QFileDevice (0x0x7f65c2c265b0) + QObject (0x0x7f65c2c29e40) 0 + primary-for QIODevice (0x0x7f65c2c5fe70) + QIODeviceBase (0x0x7f65c2c29ea0) 0 empty + +Class std::filesystem::space_info + size=24 align=8 + base size=24 base align=8 +std::filesystem::space_info (0x0x7f65c28c1c00) 0 + +Class std::filesystem::__file_clock + size=1 align=1 + base size=0 base align=1 +std::filesystem::__file_clock (0x0x7f65c29871e0) 0 empty + +Class std::time_base + size=1 align=1 + base size=0 base align=1 +std::time_base (0x0x7f65c2987660) 0 empty + +Class std::money_base::pattern + size=4 align=1 + base size=4 base align=1 +std::money_base::pattern (0x0x7f65c29e2960) 0 + +Class std::money_base + size=1 align=1 + base size=0 base align=1 +std::money_base (0x0x7f65c29e2900) 0 empty + +Class std::messages_base + size=1 align=1 + base size=0 base align=1 +std::messages_base (0x0x7f65c2a16f00) 0 empty + +Class std::codecvt_base + size=1 align=1 + base size=0 base align=1 +std::codecvt_base (0x0x7f65c2a61a80) 0 empty + +Construction vtable for std::basic_istream<char> (0x0x7f65c04cc820 instance) in std::__cxx11::basic_istringstream<char> +std::__cxx11::basic_istringstream<char>::_ZTCNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE0_Si: 10 entries +0 120 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551496 +48 (int (*)(...))-120 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +VTT for std::__cxx11::basic_istringstream<char> +std::__cxx11::basic_istringstream<char>::_ZTTNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE: 4 entries +0 ((& std::__cxx11::basic_istringstream<char>::_ZTVNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE) + 24) +8 ((& std::__cxx11::basic_istringstream<char>::_ZTCNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 24) +16 ((& std::__cxx11::basic_istringstream<char>::_ZTCNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 64) +24 ((& std::__cxx11::basic_istringstream<char>::_ZTVNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE) + 64) + +Construction vtable for std::basic_ostream<char> (0x0x7f65c04cca90 instance) in std::__cxx11::basic_ostringstream<char> +std::__cxx11::basic_ostringstream<char>::_ZTCNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE0_So: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::__cxx11::basic_ostringstream<char> +std::__cxx11::basic_ostringstream<char>::_ZTTNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE: 4 entries +0 ((& std::__cxx11::basic_ostringstream<char>::_ZTVNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE) + 24) +8 ((& std::__cxx11::basic_ostringstream<char>::_ZTCNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE0_So) + 24) +16 ((& std::__cxx11::basic_ostringstream<char>::_ZTCNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE0_So) + 64) +24 ((& std::__cxx11::basic_ostringstream<char>::_ZTVNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE) + 64) + +Construction vtable for std::basic_iostream<char> (0x0x7f65c2791f50 instance) in std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd: 15 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISd) +24 0 +32 0 +40 112 +48 (int (*)(...))-16 +56 (int (*)(...))(& _ZTISd) +64 0 +72 0 +80 18446744073709551488 +88 (int (*)(...))-128 +96 (int (*)(...))(& _ZTISd) +104 0 +112 0 + +Construction vtable for std::basic_istream<char> (0x0x7f65c04ccd00 instance) in std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Si: 10 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551488 +48 (int (*)(...))-128 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream<char> (0x0x7f65c04ccdd0 instance) in std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE16_So: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTTNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE: 10 entries +0 ((& std::__cxx11::basic_stringstream<char>::_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE) + 24) +8 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd) + 24) +16 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 24) +24 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 64) +32 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE16_So) + 24) +40 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE16_So) + 64) +48 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd) + 104) +56 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd) + 64) +64 ((& std::__cxx11::basic_stringstream<char>::_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE) + 104) +72 ((& std::__cxx11::basic_stringstream<char>::_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE) + 64) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f65c04ccf70 instance) in std::__cxx11::basic_istringstream<wchar_t> +std::__cxx11::basic_istringstream<wchar_t>::_ZTCNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E: 10 entries +0 120 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551496 +48 (int (*)(...))-120 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::__cxx11::basic_istringstream<wchar_t> +std::__cxx11::basic_istringstream<wchar_t>::_ZTTNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE: 4 entries +0 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTVNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE) + 24) +8 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTCNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 24) +16 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTCNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 64) +24 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTVNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE) + 64) + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f65c0574208 instance) in std::__cxx11::basic_ostringstream<wchar_t> +std::__cxx11::basic_ostringstream<wchar_t>::_ZTCNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_ostreamIwS2_E: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::__cxx11::basic_ostringstream<wchar_t> +std::__cxx11::basic_ostringstream<wchar_t>::_ZTTNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE: 4 entries +0 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTVNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE) + 24) +8 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTCNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_ostreamIwS2_E) + 24) +16 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTCNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_ostreamIwS2_E) + 64) +24 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTVNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE) + 64) + +Construction vtable for std::basic_iostream<wchar_t> (0x0x7f65c055e310 instance) in std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E: 15 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt14basic_iostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 112 +48 (int (*)(...))-16 +56 (int (*)(...))(& _ZTISt14basic_iostreamIwSt11char_traitsIwEE) +64 0 +72 0 +80 18446744073709551488 +88 (int (*)(...))-128 +96 (int (*)(...))(& _ZTISt14basic_iostreamIwSt11char_traitsIwEE) +104 0 +112 0 + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f65c0574478 instance) in std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E: 10 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551488 +48 (int (*)(...))-128 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f65c0574548 instance) in std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE16_St13basic_ostreamIwS2_E: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTTNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE: 10 entries +0 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE) + 24) +8 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E) + 24) +16 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 24) +24 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 64) +32 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE16_St13basic_ostreamIwS2_E) + 24) +40 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE16_St13basic_ostreamIwS2_E) + 64) +48 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E) + 104) +56 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E) + 64) +64 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE) + 104) +72 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE) + 64) + +Class std::_Resetiosflags + size=4 align=4 + base size=4 base align=4 +std::_Resetiosflags (0x0x7f65c05a2300) 0 + +Class std::_Setiosflags + size=4 align=4 + base size=4 base align=4 +std::_Setiosflags (0x0x7f65c05a2480) 0 + +Class std::_Setbase + size=4 align=4 + base size=4 base align=4 +std::_Setbase (0x0x7f65c05a2600) 0 + +Class std::_Setprecision + size=4 align=4 + base size=4 base align=4 +std::_Setprecision (0x0x7f65c05a2900) 0 + +Class std::_Setw + size=4 align=4 + base size=4 base align=4 +std::_Setw (0x0x7f65c05a2a80) 0 + +Class std::filesystem::__cxx11::path::__null_terminated + size=1 align=1 + base size=0 base align=1 +std::filesystem::__cxx11::path::__null_terminated (0x0x7f65c065cb40) 0 empty + +Class std::filesystem::__cxx11::path::_List::_Impl_deleter + size=1 align=1 + base size=0 base align=1 +std::filesystem::__cxx11::path::_List::_Impl_deleter (0x0x7f65c065cc00) 0 empty + +Class std::filesystem::__cxx11::path::_List + size=8 align=8 + base size=8 base align=8 +std::filesystem::__cxx11::path::_List (0x0x7f65c065cba0) 0 + +Class std::filesystem::__cxx11::path + size=40 align=8 + base size=40 base align=8 +std::filesystem::__cxx11::path (0x0x7f65c065ca20) 0 + +Vtable for std::filesystem::__cxx11::filesystem_error +std::filesystem::__cxx11::filesystem_error::_ZTVNSt10filesystem7__cxx1116filesystem_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt10filesystem7__cxx1116filesystem_errorE) +16 (int (*)(...))std::filesystem::__cxx11::filesystem_error::~filesystem_error +24 (int (*)(...))std::filesystem::__cxx11::filesystem_error::~filesystem_error +32 (int (*)(...))std::filesystem::__cxx11::filesystem_error::what + +Class std::filesystem::__cxx11::filesystem_error + size=48 align=8 + base size=48 base align=8 +std::filesystem::__cxx11::filesystem_error (0x0x7f65c00e3340) 0 + vptr=((& std::filesystem::__cxx11::filesystem_error::_ZTVNSt10filesystem7__cxx1116filesystem_errorE) + 16) + std::system_error (0x0x7f65c00e33a8) 0 + primary-for std::filesystem::__cxx11::filesystem_error (0x0x7f65c00e3340) + std::runtime_error (0x0x7f65c00e3410) 0 + primary-for std::system_error (0x0x7f65c00e33a8) + std::exception (0x0x7f65c00ddae0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f65c00e3410) + +Class std::filesystem::__cxx11::path::_Cmpt + size=48 align=8 + base size=48 base align=8 +std::filesystem::__cxx11::path::_Cmpt (0x0x7f65c00e3d68) 0 + std::filesystem::__cxx11::path (0x0x7f65c013c5a0) 0 + +Class std::filesystem::__cxx11::path::iterator + size=24 align=8 + base size=17 base align=8 +std::filesystem::__cxx11::path::iterator (0x0x7f65c0163840) 0 + +Class std::filesystem::file_status + size=8 align=4 + base size=8 base align=4 +std::filesystem::file_status (0x0x7f65c025d060) 0 + +Class std::filesystem::__cxx11::directory_entry + size=48 align=8 + base size=41 base align=8 +std::filesystem::__cxx11::directory_entry (0x0x7f65c025d540) 0 + +Class std::filesystem::__cxx11::__directory_iterator_proxy + size=48 align=8 + base size=48 base align=8 +std::filesystem::__cxx11::__directory_iterator_proxy (0x0x7f65bfea0c00) 0 + +Class std::filesystem::__cxx11::directory_iterator + size=16 align=8 + base size=16 base align=8 +std::filesystem::__cxx11::directory_iterator (0x0x7f65bfed43c0) 0 + +Class std::filesystem::__cxx11::recursive_directory_iterator + size=16 align=8 + base size=16 base align=8 +std::filesystem::__cxx11::recursive_directory_iterator (0x0x7f65bff4d4e0) 0 + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f65c001e660) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QFile::fileName +256 (int (*)(...))QFile::resize +264 (int (*)(...))QFile::permissions +272 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f65c0023820) 0 + vptr=((& QFile::_ZTV5QFile) + 16) + QFileDevice (0x0x7f65c0023888) 0 + primary-for QFile (0x0x7f65c0023820) + QIODevice (0x0x7f65c020f620) 0 + primary-for QFileDevice (0x0x7f65c0023888) + QObject (0x0x7f65c001e5a0) 0 + primary-for QIODevice (0x0x7f65c020f620) + QIODeviceBase (0x0x7f65c001e600) 0 empty + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f65c001ec60) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f65bfcfc600) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f65bfdcbd20) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f65bfe431e0) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f65bfaf7960) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f65bfaf7ba0) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f65bfac3a28) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16) + QObject (0x0x7f65bfaf7b40) 0 + primary-for QFileSelector (0x0x7f65bfac3a28) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f65bfaf7d80) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f65bfac3a90) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16) + QObject (0x0x7f65bfaf7d20) 0 + primary-for QFileSystemWatcher (0x0x7f65bfac3a90) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f65bfb30540) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f65bfac3af8) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16) + QObject (0x0x7f65bfb304e0) 0 + primary-for QFutureWatcherBase (0x0x7f65bfac3af8) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f65bfb30a80) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QIdentityProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QIdentityProxyModel::insertRows +272 (int (*)(...))QIdentityProxyModel::insertColumns +280 (int (*)(...))QIdentityProxyModel::removeRows +288 (int (*)(...))QIdentityProxyModel::removeColumns +296 (int (*)(...))QIdentityProxyModel::moveRows +304 (int (*)(...))QIdentityProxyModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QAbstractProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QIdentityProxyModel::match +360 (int (*)(...))QAbstractProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QIdentityProxyModel::setSourceModel +416 (int (*)(...))QIdentityProxyModel::mapToSource +424 (int (*)(...))QIdentityProxyModel::mapFromSource +432 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +440 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f65bfac3d00) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16) + QAbstractProxyModel (0x0x7f65bfac3d68) 0 + primary-for QIdentityProxyModel (0x0x7f65bfac3d00) + QAbstractItemModel (0x0x7f65bfac3dd0) 0 + primary-for QAbstractProxyModel (0x0x7f65bfac3d68) + QObject (0x0x7f65bfb30a20) 0 + primary-for QAbstractItemModel (0x0x7f65bfac3dd0) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f65bfb30c00) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f65bfbb9840) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f65bfbbcbc8) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16) + QObject (0x0x7f65bfbb97e0) 0 + primary-for QItemSelectionModel (0x0x7f65bfbbcbc8) + +Class QItemSelection + size=24 align=8 + base size=24 base align=8 +QItemSelection (0x0x7f65bfc410d0) 0 + QList<QItemSelectionRange> (0x0x7f65bfc41138) 0 + QListSpecialMethods<QItemSelectionRange> (0x0x7f65bfc411a0) 0 empty + QListSpecialMethodsBase<QItemSelectionRange> (0x0x7f65bfc20300) 0 empty + +Class QJsonValue + size=24 align=8 + base size=24 base align=8 +QJsonValue (0x0x7f65bf903420) 0 + +Class QJsonValueRef + size=16 align=8 + base size=16 base align=8 +QJsonValueRef (0x0x7f65bf903900) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=16 base align=8 +QJsonArray::iterator (0x0x7f65bf96bc60) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=16 base align=8 +QJsonArray::const_iterator (0x0x7f65bf96bcc0) 0 + +Class QJsonArray + size=8 align=8 + base size=8 base align=8 +QJsonArray (0x0x7f65bf96bc00) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f65bfa1a6c0) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f65bfa1a720) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=16 base align=8 +QJsonObject::iterator (0x0x7f65bf7afc60) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=16 base align=8 +QJsonObject::const_iterator (0x0x7f65bf7afcc0) 0 + +Class QJsonObject + size=8 align=8 + base size=8 base align=8 +QJsonObject (0x0x7f65bf7afc00) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f65bf8677e0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=24 align=8 + base size=24 base align=8 +QLibrary (0x0x7f65bf86aa28) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16) + QObject (0x0x7f65bf867780) 0 + primary-for QLibrary (0x0x7f65bf86aa28) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f65bf867ea0) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f65bf867e40) 0 + +Class QTypeRevision + size=2 align=1 + base size=2 base align=1 +QTypeRevision (0x0x7f65bf58e660) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f65bf612ea0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f65bf612f60) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f65bf2a1660) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f65bf322000) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f65bf363600) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f65bf3b9de0) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f65bf3fb5a0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f65bf449ea0) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f65bf0d4c00) 0 + +Class QMetaMethod::Data + size=8 align=8 + base size=8 base align=8 +QMetaMethod::Data (0x0x7f65bf0d4cc0) 0 + +Class QMetaMethod + size=16 align=8 + base size=16 base align=8 +QMetaMethod (0x0x7f65bf0d4c60) 0 + +Class QMetaEnum::Data + size=8 align=8 + base size=8 base align=8 +QMetaEnum::Data (0x0x7f65bf151f00) 0 + +Class QMetaEnum + size=16 align=8 + base size=16 base align=8 +QMetaEnum (0x0x7f65bf151ea0) 0 + +Class QMetaProperty::Data + size=8 align=8 + base size=8 base align=8 +QMetaProperty::Data (0x0x7f65bf198c60) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f65bf198c00) 0 + +Class QMetaClassInfo::Data + size=8 align=8 + base size=8 base align=8 +QMetaClassInfo::Data (0x0x7f65bf1c5300) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=16 base align=8 +QMetaClassInfo (0x0x7f65bf1c52a0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f65bf1fe120) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f65bf1f6548) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16) + QObject (0x0x7f65bf1fe0c0) 0 + primary-for QMimeData (0x0x7f65bf1f6548) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f65bf1fe2a0) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f65bf278de0) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f65bf278ea0) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=40 align=8 + base size=40 base align=8 +QObjectCleanupHandler (0x0x7f65bee84410) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16) + QObject (0x0x7f65bf278e40) 0 + primary-for QObjectCleanupHandler (0x0x7f65bee84410) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f65bf278f60) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f65beeced80) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f65beed6e38) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16) + QAnimationGroup (0x0x7f65beed6ea0) 0 + primary-for QParallelAnimationGroup (0x0x7f65beed6e38) + QAbstractAnimation (0x0x7f65beed6f08) 0 + primary-for QAnimationGroup (0x0x7f65beed6ea0) + QObject (0x0x7f65beeced20) 0 + primary-for QAbstractAnimation (0x0x7f65beed6f08) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f65beecef60) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f65beed6f70) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16) + QAbstractAnimation (0x0x7f65beef8000) 0 + primary-for QPauseAnimation (0x0x7f65beed6f70) + QObject (0x0x7f65beecef00) 0 + primary-for QAbstractAnimation (0x0x7f65beef8000) + +Class QPluginMetaData + size=16 align=8 + base size=16 base align=8 +QPluginMetaData (0x0x7f65bef02180) 0 + +Class QStaticPlugin + size=24 align=8 + base size=24 base align=8 +QStaticPlugin (0x0x7f65bef021e0) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f65bef20c00) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f65bef2abc8) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16) + QObject (0x0x7f65bef20ba0) 0 + primary-for QPluginLoader (0x0x7f65bef2abc8) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f65bef20cc0) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f65befaf540) 0 empty + +Class QProcess::Use_setChildProcessModifier_Instead + size=1 align=1 + base size=0 base align=1 +QProcess::Use_setChildProcessModifier_Instead (0x0x7f65befaf5a0) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 32 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QProcess::writeData +248 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f65befaac98) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16) + QIODevice (0x0x7f65beed0cb0) 0 + primary-for QProcess (0x0x7f65befaac98) + QObject (0x0x7f65befaf480) 0 + primary-for QIODevice (0x0x7f65beed0cb0) + QIODeviceBase (0x0x7f65befaf4e0) 0 empty + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f65beff8360) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f65befaad00) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16) + QAbstractAnimation (0x0x7f65befaad68) 0 + primary-for QVariantAnimation (0x0x7f65befaad00) + QObject (0x0x7f65beff8300) 0 + primary-for QAbstractAnimation (0x0x7f65befaad68) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f65beff85a0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f65befaae38) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16) + QVariantAnimation (0x0x7f65befaaea0) 0 + primary-for QPropertyAnimation (0x0x7f65befaae38) + QAbstractAnimation (0x0x7f65befaaf08) 0 + primary-for QVariantAnimation (0x0x7f65befaaea0) + QObject (0x0x7f65beff8540) 0 + primary-for QAbstractAnimation (0x0x7f65befaaf08) + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f65c302e0c0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f65c8892cc0) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f65c8892c60) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f65c4c50960) 0 + +Class QRandomGenerator::InitialRandomData + size=16 align=8 + base size=16 base align=8 +QRandomGenerator::InitialRandomData (0x0x7f65c271c1e0) 0 + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f65c271c8a0) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f65c26a6ba0) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f65caa7c618) 0 + QRandomGenerator (0x0x7f65bfdcb7e0) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f65bfc20ba0) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f65bf896720) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f65bf9fc300) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f65bf7881e0) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f65bf1c5f00) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f65c02ae300) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f65c45ee120) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f65cb347c60) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f65cb347f60) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QSaveFile::writeData +248 (int (*)(...))QSaveFile::fileName +256 (int (*)(...))QFileDevice::resize +264 (int (*)(...))QFileDevice::permissions +272 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f65ca312270) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16) + QFileDevice (0x0x7f65ca312340) 0 + primary-for QSaveFile (0x0x7f65ca312270) + QIODevice (0x0x7f65c5cd51c0) 0 + primary-for QFileDevice (0x0x7f65ca312340) + QObject (0x0x7f65cb347ea0) 0 + primary-for QIODevice (0x0x7f65c5cd51c0) + QIODeviceBase (0x0x7f65cb347f00) 0 empty + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f65ca033300) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f65c9942ae0) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f65c87fa840) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f65ca3fb7b8) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16) + QAnimationGroup (0x0x7f65ca3fb820) 0 + primary-for QSequentialAnimationGroup (0x0x7f65ca3fb7b8) + QAbstractAnimation (0x0x7f65ca3fb888) 0 + primary-for QAnimationGroup (0x0x7f65ca3fb820) + QObject (0x0x7f65c87fa7e0) 0 + primary-for QAbstractAnimation (0x0x7f65ca3fb888) + +Class QSequentialIterator + size=16 align=8 + base size=16 base align=8 +QSequentialIterator (0x0x7f65ca3fbaf8) 0 + QIterator<QMetaSequence> (0x0x7f65ca3fbb60) 0 + QBaseIterator<QMetaSequence> (0x0x7f65c87faba0) 0 + +Class QSequentialConstIterator + size=16 align=8 + base size=16 base align=8 +QSequentialConstIterator (0x0x7f65ca3fbc98) 0 + QConstIterator<QMetaSequence> (0x0x7f65ca3fbd00) 0 + QBaseIterator<QMetaSequence> (0x0x7f65c7d09120) 0 + +Class QSequentialIterable + size=24 align=8 + base size=24 base align=8 +QSequentialIterable (0x0x7f65ca3fbd68) 0 + QIterable<QMetaSequence> (0x0x7f65c7d09660) 0 + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f65c749bc60) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f65ca112478) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16) + QObject (0x0x7f65c749bc00) 0 + primary-for QSettings (0x0x7f65ca112478) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f65c74e30c0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f65ca1124e0) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16) + QObject (0x0x7f65c74e3060) 0 + primary-for QSharedMemory (0x0x7f65ca1124e0) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f65c74e32a0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f65ca112548) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16) + QObject (0x0x7f65c74e3240) 0 + primary-for QSignalMapper (0x0x7f65ca112548) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f65be6f9cc0) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f65ca11dd00) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16) + QObject (0x0x7f65be6f9c60) 0 + primary-for QSocketNotifier (0x0x7f65ca11dd00) + +Class QSocketDescriptor + size=4 align=4 + base size=4 base align=4 +QSocketDescriptor (0x0x7f65be6f9e40) 0 + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f65be7257e0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 59 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QSortFilterProxyModel::mimeTypes +224 (int (*)(...))QSortFilterProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QSortFilterProxyModel::dropMimeData +248 (int (*)(...))QSortFilterProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QSortFilterProxyModel::insertRows +272 (int (*)(...))QSortFilterProxyModel::insertColumns +280 (int (*)(...))QSortFilterProxyModel::removeRows +288 (int (*)(...))QSortFilterProxyModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QSortFilterProxyModel::fetchMore +320 (int (*)(...))QSortFilterProxyModel::canFetchMore +328 (int (*)(...))QSortFilterProxyModel::flags +336 (int (*)(...))QSortFilterProxyModel::sort +344 (int (*)(...))QSortFilterProxyModel::buddy +352 (int (*)(...))QSortFilterProxyModel::match +360 (int (*)(...))QSortFilterProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QSortFilterProxyModel::setSourceModel +416 (int (*)(...))QSortFilterProxyModel::mapToSource +424 (int (*)(...))QSortFilterProxyModel::mapFromSource +432 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +440 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +448 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +456 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +464 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f65ca122820) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16) + QAbstractProxyModel (0x0x7f65ca122888) 0 + primary-for QSortFilterProxyModel (0x0x7f65ca122820) + QAbstractItemModel (0x0x7f65ca122958) 0 + primary-for QAbstractProxyModel (0x0x7f65ca122888) + QObject (0x0x7f65be725780) 0 + primary-for QAbstractItemModel (0x0x7f65ca122958) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f65be725ba0) 0 empty + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f65be74d5a0) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f65be780de0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f65be7be660) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QStringListModel::itemData +200 (int (*)(...))QStringListModel::setItemData +208 (int (*)(...))QStringListModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractListModel::dropMimeData +248 (int (*)(...))QStringListModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QStringListModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QStringListModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QStringListModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QStringListModel::flags +336 (int (*)(...))QStringListModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QStringListModel + size=40 align=8 + base size=40 base align=8 +QStringListModel (0x0x7f65ca13f5b0) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16) + QAbstractListModel (0x0x7f65ca13f618) 0 + primary-for QStringListModel (0x0x7f65ca13f5b0) + QAbstractItemModel (0x0x7f65ca13f680) 0 + primary-for QAbstractListModel (0x0x7f65ca13f618) + QObject (0x0x7f65be7be600) 0 + primary-for QAbstractItemModel (0x0x7f65ca13f680) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f65be7be720) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f65be7be840) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f65be7be9c0) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QTemporaryFile::fileName +256 (int (*)(...))QFile::resize +264 (int (*)(...))QFile::permissions +272 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f65ca13f6e8) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16) + QFile (0x0x7f65ca13f750) 0 + primary-for QTemporaryFile (0x0x7f65ca13f6e8) + QFileDevice (0x0x7f65ca13f7b8) 0 + primary-for QFile (0x0x7f65ca13f750) + QIODevice (0x0x7f65bf06cc40) 0 + primary-for QFileDevice (0x0x7f65ca13f7b8) + QObject (0x0x7f65be7be900) 0 + primary-for QIODevice (0x0x7f65bf06cc40) + QIODeviceBase (0x0x7f65be7be960) 0 empty + +Class QTextBoundaryFinder + size=72 align=8 + base size=72 base align=8 +QTextBoundaryFinder (0x0x7f65be7bec00) 0 + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f65be7ec2a0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f65be7ec960) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f65ca13f9c0) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16) + QObject (0x0x7f65be7ec900) 0 + primary-for QTimeLine (0x0x7f65ca13f9c0) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f65be7ecb40) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=16 align=8 + base size=16 base align=8 +QTimer (0x0x7f65ca13fa28) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16) + QObject (0x0x7f65be7ecae0) 0 + primary-for QTimer (0x0x7f65ca13fa28) + +Class QTimeZone::OffsetData + size=48 align=8 + base size=44 base align=8 +QTimeZone::OffsetData (0x0x7f65be81c4e0) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f65be81c480) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f65be84b540) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f65ca1489c0) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16) + QObject (0x0x7f65be84b4e0) 0 + primary-for QTranslator (0x0x7f65ca1489c0) + +Class QTransposeProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTransposeProxyModel::QPrivateSignal (0x0x7f65be84b720) 0 empty + +Vtable for QTransposeProxyModel +QTransposeProxyModel::_ZTV20QTransposeProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTransposeProxyModel) +16 (int (*)(...))QTransposeProxyModel::metaObject +24 (int (*)(...))QTransposeProxyModel::qt_metacast +32 (int (*)(...))QTransposeProxyModel::qt_metacall +40 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +48 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTransposeProxyModel::index +120 (int (*)(...))QTransposeProxyModel::parent +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))QTransposeProxyModel::rowCount +144 (int (*)(...))QTransposeProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QTransposeProxyModel::headerData +184 (int (*)(...))QTransposeProxyModel::setHeaderData +192 (int (*)(...))QTransposeProxyModel::itemData +200 (int (*)(...))QTransposeProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QAbstractProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QTransposeProxyModel::insertRows +272 (int (*)(...))QTransposeProxyModel::insertColumns +280 (int (*)(...))QTransposeProxyModel::removeRows +288 (int (*)(...))QTransposeProxyModel::removeColumns +296 (int (*)(...))QTransposeProxyModel::moveRows +304 (int (*)(...))QTransposeProxyModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QTransposeProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QTransposeProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QTransposeProxyModel::setSourceModel +416 (int (*)(...))QTransposeProxyModel::mapToSource +424 (int (*)(...))QTransposeProxyModel::mapFromSource +432 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +440 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QTransposeProxyModel + size=16 align=8 + base size=16 base align=8 +QTransposeProxyModel (0x0x7f65ca148a28) 0 + vptr=((& QTransposeProxyModel::_ZTV20QTransposeProxyModel) + 16) + QAbstractProxyModel (0x0x7f65ca148a90) 0 + primary-for QTransposeProxyModel (0x0x7f65ca148a28) + QAbstractItemModel (0x0x7f65ca148af8) 0 + primary-for QAbstractProxyModel (0x0x7f65ca148a90) + QObject (0x0x7f65be84b6c0) 0 + primary-for QAbstractItemModel (0x0x7f65ca148af8) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f65be84b8a0) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f65be4a6120) 0 + +Class QtPrivate::QXmlString + size=24 align=8 + base size=24 base align=8 +QtPrivate::QXmlString (0x0x7f65be4a6240) 0 + +Class QXmlStreamAttribute + size=104 align=8 + base size=97 base align=8 +QXmlStreamAttribute (0x0x7f65be4c0060) 0 + +Class QXmlStreamAttributes + size=24 align=8 + base size=24 base align=8 +QXmlStreamAttributes (0x0x7f65ca166750) 0 + QList<QXmlStreamAttribute> (0x0x7f65ca1667b8) 0 + QListSpecialMethods<QXmlStreamAttribute> (0x0x7f65ca166820) 0 empty + QListSpecialMethodsBase<QXmlStreamAttribute> (0x0x7f65be4e5180) 0 empty + +Class QXmlStreamNamespaceDeclaration + size=48 align=8 + base size=48 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f65be4e5a20) 0 + +Class QXmlStreamNotationDeclaration + size=72 align=8 + base size=72 base align=8 +QXmlStreamNotationDeclaration (0x0x7f65be51a060) 0 + +Class QXmlStreamEntityDeclaration + size=120 align=8 + base size=120 base align=8 +QXmlStreamEntityDeclaration (0x0x7f65be526720) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f65be533ea0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f65be533f00) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f65be5524e0) 0 + +Vtable for QPaintDevice +QPaintDevice::_ZTV12QPaintDevice: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintDevice) +16 0 +24 0 +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDevice + size=16 align=8 + base size=10 base align=8 +QPaintDevice (0x0x7f65be5526c0) 0 + vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16) + +Class QRgba64 + size=8 align=8 + base size=8 base align=8 +QRgba64 (0x0x7f65be570180) 0 + +Class QColor::CT + size=10 align=2 + base size=10 base align=2 +QColor::CT (0x0x7f65be59ae40) 0 + +Class QColor + size=16 align=4 + base size=14 base align=4 +QColor (0x0x7f65be59ade0) 0 + +Class QPixelFormat + size=8 align=8 + base size=8 base align=8 +QPixelFormat (0x0x7f65be5dbea0) 0 + +Class QPolygon + size=24 align=8 + base size=24 base align=8 +QPolygon (0x0x7f65ca267888) 0 + QList<QPoint> (0x0x7f65ca2678f0) 0 + QListSpecialMethods<QPoint> (0x0x7f65ca267958) 0 empty + QListSpecialMethodsBase<QPoint> (0x0x7f65be60eba0) 0 empty + +Class QPolygonF + size=24 align=8 + base size=24 base align=8 +QPolygonF (0x0x7f65ca26fc30) 0 + QList<QPointF> (0x0x7f65ca26fc98) 0 + QListSpecialMethods<QPointF> (0x0x7f65ca26fd00) 0 empty + QListSpecialMethodsBase<QPointF> (0x0x7f65be6627e0) 0 empty + +Class QRegion::QRegionData + size=16 align=8 + base size=16 base align=8 +QRegion::QRegionData (0x0x7f65be2bf000) 0 + +Class QRegion + size=8 align=8 + base size=8 base align=8 +QRegion (0x0x7f65be2abf60) 0 + +Class QTransform::Affine + size=8 align=8 + base size=8 base align=8 +QTransform::Affine (0x0x7f65be2e9540) 0 + +Class QTransform + size=80 align=8 + base size=74 base align=8 +QTransform (0x0x7f65be2e94e0) 0 + +Vtable for QImage +QImage::_ZTV6QImage: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QImage) +16 (int (*)(...))QImage::~QImage +24 (int (*)(...))QImage::~QImage +32 (int (*)(...))QImage::devType +40 (int (*)(...))QImage::paintEngine +48 (int (*)(...))QImage::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QImage + size=24 align=8 + base size=24 base align=8 +QImage (0x0x7f65c9e86f08) 0 + vptr=((& QImage::_ZTV6QImage) + 16) + QPaintDevice (0x0x7f65be31c120) 0 + primary-for QImage (0x0x7f65c9e86f08) + +Vtable for QPixmap +QPixmap::_ZTV7QPixmap: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QPixmap) +16 (int (*)(...))QPixmap::~QPixmap +24 (int (*)(...))QPixmap::~QPixmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPixmap + size=24 align=8 + base size=24 base align=8 +QPixmap (0x0x7f65c9e91340) 0 + vptr=((& QPixmap::_ZTV7QPixmap) + 16) + QPaintDevice (0x0x7f65be35d900) 0 + primary-for QPixmap (0x0x7f65c9e91340) + +Class QIcon + size=8 align=8 + base size=8 base align=8 +QIcon (0x0x7f65be395540) 0 + +Vtable for QAbstractFileIconProvider +QAbstractFileIconProvider::_ZTV25QAbstractFileIconProvider: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAbstractFileIconProvider) +16 (int (*)(...))QAbstractFileIconProvider::~QAbstractFileIconProvider +24 (int (*)(...))QAbstractFileIconProvider::~QAbstractFileIconProvider +32 (int (*)(...))QAbstractFileIconProvider::icon +40 (int (*)(...))QAbstractFileIconProvider::icon +48 (int (*)(...))QAbstractFileIconProvider::type +56 (int (*)(...))QAbstractFileIconProvider::setOptions +64 (int (*)(...))QAbstractFileIconProvider::options + +Class QAbstractFileIconProvider + size=16 align=8 + base size=16 base align=8 +QAbstractFileIconProvider (0x0x7f65be3c08a0) 0 + vptr=((& QAbstractFileIconProvider::_ZTV25QAbstractFileIconProvider) + 16) + +Class QVector2D + size=8 align=4 + base size=8 base align=4 +QVector2D (0x0x7f65be3c0e40) 0 + +Class QVector3D + size=12 align=4 + base size=12 base align=4 +QVector3D (0x0x7f65be3f5c00) 0 + +Class QVector4D + size=16 align=4 + base size=16 base align=4 +QVector4D (0x0x7f65be418ba0) 0 + +Class QScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScreen::QPrivateSignal (0x0x7f65be0816c0) 0 empty + +Vtable for QScreen +QScreen::_ZTV7QScreen: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QScreen) +16 (int (*)(...))QScreen::metaObject +24 (int (*)(...))QScreen::qt_metacast +32 (int (*)(...))QScreen::qt_metacall +40 (int (*)(...))QScreen::~QScreen +48 (int (*)(...))QScreen::~QScreen +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScreen + size=16 align=8 + base size=16 base align=8 +QScreen (0x0x7f65c742c958) 0 + vptr=((& QScreen::_ZTV7QScreen) + 16) + QObject (0x0x7f65be081660) 0 + primary-for QScreen (0x0x7f65c742c958) + +Class QInputDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputDevice::QPrivateSignal (0x0x7f65be081900) 0 empty + +Vtable for QInputDevice +QInputDevice::_ZTV12QInputDevice: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputDevice) +16 (int (*)(...))QInputDevice::metaObject +24 (int (*)(...))QInputDevice::qt_metacast +32 (int (*)(...))QInputDevice::qt_metacall +40 (int (*)(...))QInputDevice::~QInputDevice +48 (int (*)(...))QInputDevice::~QInputDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputDevice + size=16 align=8 + base size=16 base align=8 +QInputDevice (0x0x7f65c742cb60) 0 + vptr=((& QInputDevice::_ZTV12QInputDevice) + 16) + QObject (0x0x7f65be0818a0) 0 + primary-for QInputDevice (0x0x7f65c742cb60) + +Class QPointingDeviceUniqueId + size=8 align=8 + base size=8 base align=8 +QPointingDeviceUniqueId (0x0x7f65be0b13c0) 0 + +Class QPointingDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPointingDevice::QPrivateSignal (0x0x7f65be0c8d20) 0 empty + +Vtable for QPointingDevice +QPointingDevice::_ZTV15QPointingDevice: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPointingDevice) +16 (int (*)(...))QPointingDevice::metaObject +24 (int (*)(...))QPointingDevice::qt_metacast +32 (int (*)(...))QPointingDevice::qt_metacall +40 (int (*)(...))QPointingDevice::~QPointingDevice +48 (int (*)(...))QPointingDevice::~QPointingDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPointingDevice + size=16 align=8 + base size=16 base align=8 +QPointingDevice (0x0x7f65c4feadd0) 0 + vptr=((& QPointingDevice::_ZTV15QPointingDevice) + 16) + QInputDevice (0x0x7f65c4feae38) 0 + primary-for QPointingDevice (0x0x7f65c4feadd0) + QObject (0x0x7f65be0c8cc0) 0 + primary-for QInputDevice (0x0x7f65c4feae38) + +Class QEventPoint + size=8 align=8 + base size=8 base align=8 +QEventPoint (0x0x7f65be0db480) 0 + +Class QKeySequence + size=8 align=8 + base size=8 base align=8 +QKeySequence (0x0x7f65be1243c0) 0 + +Vtable for QInputEvent +QInputEvent::_ZTV11QInputEvent: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QInputEvent) +16 (int (*)(...))QInputEvent::~QInputEvent +24 (int (*)(...))QInputEvent::~QInputEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QInputEvent::clone +48 (int (*)(...))QInputEvent::setTimestamp + +Class QInputEvent + size=40 align=8 + base size=40 base align=8 +QInputEvent (0x0x7f65c27c8618) 0 + vptr=((& QInputEvent::_ZTV11QInputEvent) + 16) + QEvent (0x0x7f65be1533c0) 0 + primary-for QInputEvent (0x0x7f65c27c8618) + +Vtable for QPointerEvent +QPointerEvent::_ZTV13QPointerEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPointerEvent) +16 (int (*)(...))QPointerEvent::~QPointerEvent +24 (int (*)(...))QPointerEvent::~QPointerEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QPointerEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QPointerEvent::isBeginEvent +64 (int (*)(...))QPointerEvent::isUpdateEvent +72 (int (*)(...))QPointerEvent::isEndEvent + +Class QPointerEvent + size=64 align=8 + base size=64 base align=8 +QPointerEvent (0x0x7f65c27c86e8) 0 + vptr=((& QPointerEvent::_ZTV13QPointerEvent) + 16) + QInputEvent (0x0x7f65c27c8888) 0 + primary-for QPointerEvent (0x0x7f65c27c86e8) + QEvent (0x0x7f65be1538a0) 0 + primary-for QInputEvent (0x0x7f65c27c8888) + +Vtable for QSinglePointEvent +QSinglePointEvent::_ZTV17QSinglePointEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSinglePointEvent) +16 (int (*)(...))QSinglePointEvent::~QSinglePointEvent +24 (int (*)(...))QSinglePointEvent::~QSinglePointEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QSinglePointEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QSinglePointEvent + size=80 align=8 + base size=80 base align=8 +QSinglePointEvent (0x0x7f65c0093dd0) 0 + vptr=((& QSinglePointEvent::_ZTV17QSinglePointEvent) + 16) + QPointerEvent (0x0x7f65c0093e38) 0 + primary-for QSinglePointEvent (0x0x7f65c0093dd0) + QInputEvent (0x0x7f65c00e3c30) 0 + primary-for QPointerEvent (0x0x7f65c0093e38) + QEvent (0x0x7f65be193780) 0 + primary-for QInputEvent (0x0x7f65c00e3c30) + +Vtable for QEnterEvent +QEnterEvent::_ZTV11QEnterEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QEnterEvent) +16 (int (*)(...))QEnterEvent::~QEnterEvent +24 (int (*)(...))QEnterEvent::~QEnterEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QEnterEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QEnterEvent + size=80 align=8 + base size=80 base align=8 +QEnterEvent (0x0x7f65c00e3c98) 0 + vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16) + QSinglePointEvent (0x0x7f65c00e3d00) 0 + primary-for QEnterEvent (0x0x7f65c00e3c98) + QPointerEvent (0x0x7f65c015b8f0) 0 + primary-for QSinglePointEvent (0x0x7f65c00e3d00) + QInputEvent (0x0x7f65c015b958) 0 + primary-for QPointerEvent (0x0x7f65c015b8f0) + QEvent (0x0x7f65be193c60) 0 + primary-for QInputEvent (0x0x7f65c015b958) + +Vtable for QMouseEvent +QMouseEvent::_ZTV11QMouseEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMouseEvent) +16 (int (*)(...))QMouseEvent::~QMouseEvent +24 (int (*)(...))QMouseEvent::~QMouseEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QMouseEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QMouseEvent + size=80 align=8 + base size=80 base align=8 +QMouseEvent (0x0x7f65c015bbc8) 0 + vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16) + QSinglePointEvent (0x0x7f65c015bc30) 0 + primary-for QMouseEvent (0x0x7f65c015bbc8) + QPointerEvent (0x0x7f65c015bd68) 0 + primary-for QSinglePointEvent (0x0x7f65c015bc30) + QInputEvent (0x0x7f65c015bf08) 0 + primary-for QPointerEvent (0x0x7f65c015bd68) + QEvent (0x0x7f65be1aa420) 0 + primary-for QInputEvent (0x0x7f65c015bf08) + +Vtable for QHoverEvent +QHoverEvent::_ZTV11QHoverEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHoverEvent) +16 (int (*)(...))QHoverEvent::~QHoverEvent +24 (int (*)(...))QHoverEvent::~QHoverEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QHoverEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QHoverEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QHoverEvent + size=96 align=8 + base size=96 base align=8 +QHoverEvent (0x0x7f65c0196208) 0 + vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16) + QSinglePointEvent (0x0x7f65c0196270) 0 + primary-for QHoverEvent (0x0x7f65c0196208) + QPointerEvent (0x0x7f65c0196340) 0 + primary-for QSinglePointEvent (0x0x7f65c0196270) + QInputEvent (0x0x7f65c02226e8) 0 + primary-for QPointerEvent (0x0x7f65c0196340) + QEvent (0x0x7f65be1aa9c0) 0 + primary-for QInputEvent (0x0x7f65c02226e8) + +Vtable for QWheelEvent +QWheelEvent::_ZTV11QWheelEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWheelEvent) +16 (int (*)(...))QWheelEvent::~QWheelEvent +24 (int (*)(...))QWheelEvent::~QWheelEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QWheelEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QWheelEvent::isBeginEvent +64 (int (*)(...))QWheelEvent::isUpdateEvent +72 (int (*)(...))QWheelEvent::isEndEvent + +Class QWheelEvent + size=96 align=8 + base size=96 base align=8 +QWheelEvent (0x0x7f65c0222750) 0 + vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16) + QSinglePointEvent (0x0x7f65c0222888) 0 + primary-for QWheelEvent (0x0x7f65c0222750) + QPointerEvent (0x0x7f65c0222a28) 0 + primary-for QSinglePointEvent (0x0x7f65c0222888) + QInputEvent (0x0x7f65bff18410) 0 + primary-for QPointerEvent (0x0x7f65c0222a28) + QEvent (0x0x7f65be1aade0) 0 + primary-for QInputEvent (0x0x7f65bff18410) + +Vtable for QTabletEvent +QTabletEvent::_ZTV12QTabletEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTabletEvent) +16 (int (*)(...))QTabletEvent::~QTabletEvent +24 (int (*)(...))QTabletEvent::~QTabletEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QTabletEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QTabletEvent + size=96 align=8 + base size=96 base align=8 +QTabletEvent (0x0x7f65bff18478) 0 + vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16) + QSinglePointEvent (0x0x7f65bfc98270) 0 + primary-for QTabletEvent (0x0x7f65bff18478) + QPointerEvent (0x0x7f65bfc982d8) 0 + primary-for QSinglePointEvent (0x0x7f65bfc98270) + QInputEvent (0x0x7f65bfc98410) 0 + primary-for QPointerEvent (0x0x7f65bfc982d8) + QEvent (0x0x7f65be1c8300) 0 + primary-for QInputEvent (0x0x7f65bfc98410) + +Vtable for QNativeGestureEvent +QNativeGestureEvent::_ZTV19QNativeGestureEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNativeGestureEvent) +16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QNativeGestureEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QNativeGestureEvent + size=112 align=8 + base size=112 base align=8 +QNativeGestureEvent (0x0x7f65bfc985b0) 0 + vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16) + QSinglePointEvent (0x0x7f65bfc98680) 0 + primary-for QNativeGestureEvent (0x0x7f65bfc985b0) + QPointerEvent (0x0x7f65bfc986e8) 0 + primary-for QSinglePointEvent (0x0x7f65bfc98680) + QInputEvent (0x0x7f65bfc98820) 0 + primary-for QPointerEvent (0x0x7f65bfc986e8) + QEvent (0x0x7f65be1c8ba0) 0 + primary-for QInputEvent (0x0x7f65bfc98820) + +Vtable for QKeyEvent +QKeyEvent::_ZTV9QKeyEvent: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QKeyEvent) +16 (int (*)(...))QKeyEvent::~QKeyEvent +24 (int (*)(...))QKeyEvent::~QKeyEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QKeyEvent::clone +48 (int (*)(...))QInputEvent::setTimestamp + +Class QKeyEvent + size=88 align=8 + base size=82 base align=8 +QKeyEvent (0x0x7f65bfc989c0) 0 + vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16) + QInputEvent (0x0x7f65bfc98bc8) 0 + primary-for QKeyEvent (0x0x7f65bfc989c0) + QEvent (0x0x7f65be1e7180) 0 + primary-for QInputEvent (0x0x7f65bfc98bc8) + +Vtable for QFocusEvent +QFocusEvent::_ZTV11QFocusEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusEvent) +16 (int (*)(...))QFocusEvent::~QFocusEvent +24 (int (*)(...))QFocusEvent::~QFocusEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QFocusEvent::clone + +Class QFocusEvent + size=24 align=8 + base size=20 base align=8 +QFocusEvent (0x0x7f65bfc98e38) 0 + vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16) + QEvent (0x0x7f65be1e7780) 0 + primary-for QFocusEvent (0x0x7f65bfc98e38) + +Vtable for QPaintEvent +QPaintEvent::_ZTV11QPaintEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPaintEvent) +16 (int (*)(...))QPaintEvent::~QPaintEvent +24 (int (*)(...))QPaintEvent::~QPaintEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QPaintEvent::clone + +Class QPaintEvent + size=48 align=8 + base size=41 base align=8 +QPaintEvent (0x0x7f65bfcb7340) 0 + vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16) + QEvent (0x0x7f65be1e7ae0) 0 + primary-for QPaintEvent (0x0x7f65bfcb7340) + +Vtable for QMoveEvent +QMoveEvent::_ZTV10QMoveEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QMoveEvent) +16 (int (*)(...))QMoveEvent::~QMoveEvent +24 (int (*)(...))QMoveEvent::~QMoveEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QMoveEvent::clone + +Class QMoveEvent + size=32 align=8 + base size=32 base align=8 +QMoveEvent (0x0x7f65bfcb73a8) 0 + vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16) + QEvent (0x0x7f65be1e7de0) 0 + primary-for QMoveEvent (0x0x7f65bfcb73a8) + +Vtable for QExposeEvent +QExposeEvent::_ZTV12QExposeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QExposeEvent) +16 (int (*)(...))QExposeEvent::~QExposeEvent +24 (int (*)(...))QExposeEvent::~QExposeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QExposeEvent::clone + +Class QExposeEvent + size=24 align=8 + base size=24 base align=8 +QExposeEvent (0x0x7f65bfcb76e8) 0 + vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16) + QEvent (0x0x7f65be204180) 0 + primary-for QExposeEvent (0x0x7f65bfcb76e8) + +Vtable for QPlatformSurfaceEvent +QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent) +16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QPlatformSurfaceEvent::clone + +Class QPlatformSurfaceEvent + size=24 align=8 + base size=20 base align=8 +QPlatformSurfaceEvent (0x0x7f65bfcb7750) 0 + vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16) + QEvent (0x0x7f65be204420) 0 + primary-for QPlatformSurfaceEvent (0x0x7f65bfcb7750) + +Vtable for QResizeEvent +QResizeEvent::_ZTV12QResizeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QResizeEvent) +16 (int (*)(...))QResizeEvent::~QResizeEvent +24 (int (*)(...))QResizeEvent::~QResizeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QResizeEvent::clone + +Class QResizeEvent + size=32 align=8 + base size=32 base align=8 +QResizeEvent (0x0x7f65bfa84000) 0 + vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16) + QEvent (0x0x7f65be204720) 0 + primary-for QResizeEvent (0x0x7f65bfa84000) + +Vtable for QCloseEvent +QCloseEvent::_ZTV11QCloseEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QCloseEvent) +16 (int (*)(...))QCloseEvent::~QCloseEvent +24 (int (*)(...))QCloseEvent::~QCloseEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QCloseEvent + size=16 align=8 + base size=16 base align=8 +QCloseEvent (0x0x7f65bfa84068) 0 + vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16) + QEvent (0x0x7f65be204a80) 0 + primary-for QCloseEvent (0x0x7f65bfa84068) + +Vtable for QIconDragEvent +QIconDragEvent::_ZTV14QIconDragEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QIconDragEvent) +16 (int (*)(...))QIconDragEvent::~QIconDragEvent +24 (int (*)(...))QIconDragEvent::~QIconDragEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QIconDragEvent + size=16 align=8 + base size=16 base align=8 +QIconDragEvent (0x0x7f65bfa84478) 0 + vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16) + QEvent (0x0x7f65be204ae0) 0 + primary-for QIconDragEvent (0x0x7f65bfa84478) + +Vtable for QShowEvent +QShowEvent::_ZTV10QShowEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QShowEvent) +16 (int (*)(...))QShowEvent::~QShowEvent +24 (int (*)(...))QShowEvent::~QShowEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QShowEvent + size=16 align=8 + base size=16 base align=8 +QShowEvent (0x0x7f65bfa844e0) 0 + vptr=((& QShowEvent::_ZTV10QShowEvent) + 16) + QEvent (0x0x7f65be204b40) 0 + primary-for QShowEvent (0x0x7f65bfa844e0) + +Vtable for QHideEvent +QHideEvent::_ZTV10QHideEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHideEvent) +16 (int (*)(...))QHideEvent::~QHideEvent +24 (int (*)(...))QHideEvent::~QHideEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QHideEvent + size=16 align=8 + base size=16 base align=8 +QHideEvent (0x0x7f65bfaaa068) 0 + vptr=((& QHideEvent::_ZTV10QHideEvent) + 16) + QEvent (0x0x7f65be204ba0) 0 + primary-for QHideEvent (0x0x7f65bfaaa068) + +Vtable for QContextMenuEvent +QContextMenuEvent::_ZTV17QContextMenuEvent: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QContextMenuEvent) +16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QContextMenuEvent::clone +48 (int (*)(...))QInputEvent::setTimestamp + +Class QContextMenuEvent + size=64 align=8 + base size=57 base align=8 +QContextMenuEvent (0x0x7f65bfaaa0d0) 0 + vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16) + QInputEvent (0x0x7f65bfaaa340) 0 + primary-for QContextMenuEvent (0x0x7f65bfaaa0d0) + QEvent (0x0x7f65be204c00) 0 + primary-for QInputEvent (0x0x7f65bfaaa340) + +Class QInputMethodEvent::Attribute + size=48 align=8 + base size=48 base align=8 +QInputMethodEvent::Attribute (0x0x7f65be2261e0) 0 + +Vtable for QInputMethodEvent +QInputMethodEvent::_ZTV17QInputMethodEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QInputMethodEvent) +16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QInputMethodEvent::clone + +Class QInputMethodEvent + size=96 align=8 + base size=96 base align=8 +QInputMethodEvent (0x0x7f65bfaaa3a8) 0 + vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16) + QEvent (0x0x7f65be226180) 0 + primary-for QInputMethodEvent (0x0x7f65bfaaa3a8) + +Class QInputMethodQueryEvent::QueryPair + size=40 align=8 + base size=40 base align=8 +QInputMethodQueryEvent::QueryPair (0x0x7f65be26f9c0) 0 + +Vtable for QInputMethodQueryEvent +QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent) +16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QInputMethodQueryEvent::clone + +Class QInputMethodQueryEvent + size=48 align=8 + base size=48 base align=8 +QInputMethodQueryEvent (0x0x7f65bf28e410) 0 + vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16) + QEvent (0x0x7f65be26f960) 0 + primary-for QInputMethodQueryEvent (0x0x7f65bf28e410) + +Vtable for QDropEvent +QDropEvent::_ZTV10QDropEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDropEvent) +16 (int (*)(...))QDropEvent::~QDropEvent +24 (int (*)(...))QDropEvent::~QDropEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDropEvent::clone + +Class QDropEvent + size=64 align=8 + base size=64 base align=8 +QDropEvent (0x0x7f65bec95208) 0 + vptr=((& QDropEvent::_ZTV10QDropEvent) + 16) + QEvent (0x0x7f65bdeb1ae0) 0 + primary-for QDropEvent (0x0x7f65bec95208) + +Vtable for QDragMoveEvent +QDragMoveEvent::_ZTV14QDragMoveEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDragMoveEvent) +16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDragMoveEvent::clone + +Class QDragMoveEvent + size=80 align=8 + base size=80 base align=8 +QDragMoveEvent (0x0x7f65bec95270) 0 + vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16) + QDropEvent (0x0x7f65bec952d8) 0 + primary-for QDragMoveEvent (0x0x7f65bec95270) + QEvent (0x0x7f65bdec3240) 0 + primary-for QDropEvent (0x0x7f65bec952d8) + +Vtable for QDragEnterEvent +QDragEnterEvent::_ZTV15QDragEnterEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragEnterEvent) +16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDragMoveEvent::clone + +Class QDragEnterEvent + size=80 align=8 + base size=80 base align=8 +QDragEnterEvent (0x0x7f65bec95340) 0 + vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16) + QDragMoveEvent (0x0x7f65bec953a8) 0 + primary-for QDragEnterEvent (0x0x7f65bec95340) + QDropEvent (0x0x7f65bec95410) 0 + primary-for QDragMoveEvent (0x0x7f65bec953a8) + QEvent (0x0x7f65bdec36c0) 0 + primary-for QDropEvent (0x0x7f65bec95410) + +Vtable for QDragLeaveEvent +QDragLeaveEvent::_ZTV15QDragLeaveEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragLeaveEvent) +16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QDragLeaveEvent + size=16 align=8 + base size=16 base align=8 +QDragLeaveEvent (0x0x7f65bec95478) 0 + vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16) + QEvent (0x0x7f65bdec3720) 0 + primary-for QDragLeaveEvent (0x0x7f65bec95478) + +Vtable for QHelpEvent +QHelpEvent::_ZTV10QHelpEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHelpEvent) +16 (int (*)(...))QHelpEvent::~QHelpEvent +24 (int (*)(...))QHelpEvent::~QHelpEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QHelpEvent::clone + +Class QHelpEvent + size=32 align=8 + base size=32 base align=8 +QHelpEvent (0x0x7f65bec954e0) 0 + vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16) + QEvent (0x0x7f65bdec3780) 0 + primary-for QHelpEvent (0x0x7f65bec954e0) + +Vtable for QStatusTipEvent +QStatusTipEvent::_ZTV15QStatusTipEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QStatusTipEvent) +16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QStatusTipEvent::clone + +Class QStatusTipEvent + size=40 align=8 + base size=40 base align=8 +QStatusTipEvent (0x0x7f65bec95548) 0 + vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16) + QEvent (0x0x7f65bdec3c60) 0 + primary-for QStatusTipEvent (0x0x7f65bec95548) + +Vtable for QWhatsThisClickedEvent +QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent) +16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QWhatsThisClickedEvent::clone + +Class QWhatsThisClickedEvent + size=40 align=8 + base size=40 base align=8 +QWhatsThisClickedEvent (0x0x7f65bec955b0) 0 + vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16) + QEvent (0x0x7f65bdec3f00) 0 + primary-for QWhatsThisClickedEvent (0x0x7f65bec955b0) + +Vtable for QActionEvent +QActionEvent::_ZTV12QActionEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionEvent) +16 (int (*)(...))QActionEvent::~QActionEvent +24 (int (*)(...))QActionEvent::~QActionEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QActionEvent::clone + +Class QActionEvent + size=32 align=8 + base size=32 base align=8 +QActionEvent (0x0x7f65bec95618) 0 + vptr=((& QActionEvent::_ZTV12QActionEvent) + 16) + QEvent (0x0x7f65bdee41e0) 0 + primary-for QActionEvent (0x0x7f65bec95618) + +Vtable for QFileOpenEvent +QFileOpenEvent::_ZTV14QFileOpenEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QFileOpenEvent) +16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QFileOpenEvent::clone + +Class QFileOpenEvent + size=48 align=8 + base size=48 base align=8 +QFileOpenEvent (0x0x7f65bec95680) 0 + vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16) + QEvent (0x0x7f65bdee4540) 0 + primary-for QFileOpenEvent (0x0x7f65bec95680) + +Vtable for QToolBarChangeEvent +QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QToolBarChangeEvent) +16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QToolBarChangeEvent::clone + +Class QToolBarChangeEvent + size=24 align=8 + base size=17 base align=8 +QToolBarChangeEvent (0x0x7f65bec956e8) 0 + vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16) + QEvent (0x0x7f65bdee4840) 0 + primary-for QToolBarChangeEvent (0x0x7f65bec956e8) + +Vtable for QShortcutEvent +QShortcutEvent::_ZTV14QShortcutEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QShortcutEvent) +16 (int (*)(...))QShortcutEvent::~QShortcutEvent +24 (int (*)(...))QShortcutEvent::~QShortcutEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QShortcutEvent::clone + +Class QShortcutEvent + size=32 align=8 + base size=29 base align=8 +QShortcutEvent (0x0x7f65bec95750) 0 + vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16) + QEvent (0x0x7f65bdee4b40) 0 + primary-for QShortcutEvent (0x0x7f65bec95750) + +Vtable for QWindowStateChangeEvent +QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent) +16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QWindowStateChangeEvent::clone + +Class QWindowStateChangeEvent + size=24 align=8 + base size=21 base align=8 +QWindowStateChangeEvent (0x0x7f65bec957b8) 0 + vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16) + QEvent (0x0x7f65bdee4ea0) 0 + primary-for QWindowStateChangeEvent (0x0x7f65bec957b8) + +Vtable for QTouchEvent +QTouchEvent::_ZTV11QTouchEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTouchEvent) +16 (int (*)(...))QTouchEvent::~QTouchEvent +24 (int (*)(...))QTouchEvent::~QTouchEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QTouchEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QTouchEvent::isBeginEvent +64 (int (*)(...))QTouchEvent::isUpdateEvent +72 (int (*)(...))QTouchEvent::isEndEvent + +Class QTouchEvent + size=80 align=8 + base size=79 base align=8 +QTouchEvent (0x0x7f65bec95820) 0 + vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16) + QPointerEvent (0x0x7f65bec95888) 0 + primary-for QTouchEvent (0x0x7f65bec95820) + QInputEvent (0x0x7f65bec958f0) 0 + primary-for QPointerEvent (0x0x7f65bec95888) + QEvent (0x0x7f65bdefe1e0) 0 + primary-for QInputEvent (0x0x7f65bec958f0) + +Vtable for QScrollPrepareEvent +QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollPrepareEvent) +16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QScrollPrepareEvent::clone + +Class QScrollPrepareEvent + size=96 align=8 + base size=96 base align=8 +QScrollPrepareEvent (0x0x7f65bec95958) 0 + vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16) + QEvent (0x0x7f65bdefe540) 0 + primary-for QScrollPrepareEvent (0x0x7f65bec95958) + +Vtable for QScrollEvent +QScrollEvent::_ZTV12QScrollEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QScrollEvent) +16 (int (*)(...))QScrollEvent::~QScrollEvent +24 (int (*)(...))QScrollEvent::~QScrollEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QScrollEvent::clone + +Class QScrollEvent + size=56 align=8 + base size=52 base align=8 +QScrollEvent (0x0x7f65bec959c0) 0 + vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16) + QEvent (0x0x7f65bdefe960) 0 + primary-for QScrollEvent (0x0x7f65bec959c0) + +Vtable for QScreenOrientationChangeEvent +QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent) +16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QScreenOrientationChangeEvent::clone + +Class QScreenOrientationChangeEvent + size=32 align=8 + base size=28 base align=8 +QScreenOrientationChangeEvent (0x0x7f65bec95a28) 0 + vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16) + QEvent (0x0x7f65bdefed20) 0 + primary-for QScreenOrientationChangeEvent (0x0x7f65bec95a28) + +Vtable for QApplicationStateChangeEvent +QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent) +16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QApplicationStateChangeEvent::clone + +Class QApplicationStateChangeEvent + size=24 align=8 + base size=20 base align=8 +QApplicationStateChangeEvent (0x0x7f65bec95a90) 0 + vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16) + QEvent (0x0x7f65bdf1c0c0) 0 + primary-for QApplicationStateChangeEvent (0x0x7f65bec95a90) + +Class QFont + size=16 align=8 + base size=12 base align=8 +QFont (0x0x7f65bdf1c3c0) 0 + +Class QFontDatabase + size=1 align=1 + base size=0 base align=1 +QFontDatabase (0x0x7f65bdf66540) 0 empty + +Class QRawFont + size=8 align=8 + base size=8 base align=8 +QRawFont (0x0x7f65bdf66720) 0 + +Class QGlyphRun + size=8 align=8 + base size=8 base align=8 +QGlyphRun (0x0x7f65bdfa37e0) 0 + +Class QBrushDataPointerDeleter + size=1 align=1 + base size=0 base align=1 +QBrushDataPointerDeleter (0x0x7f65bdfe3000) 0 empty + +Class QBrush + size=8 align=8 + base size=8 base align=8 +QBrush (0x0x7f65bdfe3060) 0 + +Class QBrushData + size=104 align=8 + base size=104 base align=8 +QBrushData (0x0x7f65bdccfa80) 0 + +Class QGradient::QGradientData + size=48 align=8 + base size=48 base align=8 +QGradient::QGradientData (0x0x7f65bdccfcc0) 0 + +Class QGradient + size=88 align=8 + base size=88 base align=8 +QGradient (0x0x7f65bdccfc60) 0 + +Class QLinearGradient + size=88 align=8 + base size=88 base align=8 +QLinearGradient (0x0x7f65bdcd8a90) 0 + QGradient (0x0x7f65bdcf9ba0) 0 + +Class QRadialGradient + size=88 align=8 + base size=88 base align=8 +QRadialGradient (0x0x7f65bdcd8af8) 0 + QGradient (0x0x7f65bdcf9cc0) 0 + +Class QConicalGradient + size=88 align=8 + base size=88 base align=8 +QConicalGradient (0x0x7f65bdcd8b60) 0 + QGradient (0x0x7f65bdcf9de0) 0 + +Class QPen + size=8 align=8 + base size=8 base align=8 +QPen (0x0x7f65bdcf9ea0) 0 + +Class QTextOption::Tab + size=16 align=8 + base size=14 base align=8 +QTextOption::Tab (0x0x7f65bdd7ff60) 0 + +Class QTextOption + size=24 align=8 + base size=24 base align=8 +QTextOption (0x0x7f65bdd7ff00) 0 + +Class QTextLength + size=16 align=8 + base size=16 base align=8 +QTextLength (0x0x7f65bddcb360) 0 + +Class QTextFormat + size=16 align=8 + base size=12 base align=8 +QTextFormat (0x0x7f65bddf4060) 0 + +Class QTextCharFormat + size=16 align=8 + base size=12 base align=8 +QTextCharFormat (0x0x7f65bde80618) 0 + QTextFormat (0x0x7f65bda827e0) 0 + +Class QTextBlockFormat + size=16 align=8 + base size=12 base align=8 +QTextBlockFormat (0x0x7f65bdae23a8) 0 + QTextFormat (0x0x7f65bdadccc0) 0 + +Class QTextListFormat + size=16 align=8 + base size=12 base align=8 +QTextListFormat (0x0x7f65bdb19000) 0 + QTextFormat (0x0x7f65bdb16240) 0 + +Class QTextImageFormat + size=16 align=8 + base size=12 base align=8 +QTextImageFormat (0x0x7f65bdb30bc8) 0 + QTextCharFormat (0x0x7f65bdb30c30) 0 + QTextFormat (0x0x7f65bdb3c120) 0 + +Class QTextFrameFormat + size=16 align=8 + base size=12 base align=8 +QTextFrameFormat (0x0x7f65bdb58888) 0 + QTextFormat (0x0x7f65bdb51f60) 0 + +Class QTextTableFormat + size=16 align=8 + base size=12 base align=8 +QTextTableFormat (0x0x7f65bdb844e0) 0 + QTextFrameFormat (0x0x7f65bdb84548) 0 + QTextFormat (0x0x7f65bdb8b3c0) 0 + +Class QTextTableCellFormat + size=16 align=8 + base size=12 base align=8 +QTextTableCellFormat (0x0x7f65bdbb61a0) 0 + QTextCharFormat (0x0x7f65bdbb6208) 0 + QTextFormat (0x0x7f65bdbb3660) 0 + +Class QTextCursor + size=8 align=8 + base size=8 base align=8 +QTextCursor (0x0x7f65bdbdfba0) 0 + +Class QTextInlineObject + size=16 align=8 + base size=16 base align=8 +QTextInlineObject (0x0x7f65bdc432a0) 0 + +Class QTextLayout::FormatRange + size=24 align=8 + base size=24 base align=8 +QTextLayout::FormatRange (0x0x7f65bdc436c0) 0 + +Class QTextLayout + size=8 align=8 + base size=8 base align=8 +QTextLayout (0x0x7f65bdc43660) 0 + +Class QTextLine + size=16 align=8 + base size=16 base align=8 +QTextLine (0x0x7f65bd8b2780) 0 + +Vtable for QAbstractUndoItem +QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractUndoItem) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAbstractUndoItem + size=8 align=8 + base size=8 base align=8 +QAbstractUndoItem (0x0x7f65bd8b2c00) 0 nearly-empty + vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16) + +Class QTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextDocument::QPrivateSignal (0x0x7f65bd8b2ea0) 0 empty + +Vtable for QTextDocument +QTextDocument::_ZTV13QTextDocument: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QTextDocument) +16 (int (*)(...))QTextDocument::metaObject +24 (int (*)(...))QTextDocument::qt_metacast +32 (int (*)(...))QTextDocument::qt_metacall +40 (int (*)(...))QTextDocument::~QTextDocument +48 (int (*)(...))QTextDocument::~QTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextDocument::clear +120 (int (*)(...))QTextDocument::createObject +128 (int (*)(...))QTextDocument::loadResource + +Class QTextDocument + size=16 align=8 + base size=16 base align=8 +QTextDocument (0x0x7f65bd8aee38) 0 + vptr=((& QTextDocument::_ZTV13QTextDocument) + 16) + QObject (0x0x7f65bd8b2e40) 0 + primary-for QTextDocument (0x0x7f65bd8aee38) + +Class QPalette + size=16 align=8 + base size=12 base align=8 +QPalette (0x0x7f65bd8ec780) 0 + +Class QAbstractTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTextDocumentLayout::QPrivateSignal (0x0x7f65bd983ba0) 0 empty + +Class QAbstractTextDocumentLayout::Selection + size=24 align=8 + base size=24 base align=8 +QAbstractTextDocumentLayout::Selection (0x0x7f65bd983c00) 0 + +Class QAbstractTextDocumentLayout::PaintContext + size=80 align=8 + base size=80 base align=8 +QAbstractTextDocumentLayout::PaintContext (0x0x7f65bd983c60) 0 + +Vtable for QAbstractTextDocumentLayout +QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout) +16 (int (*)(...))QAbstractTextDocumentLayout::metaObject +24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast +32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QAbstractTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QAbstractTextDocumentLayout (0x0x7f65bd98d270) 0 + vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16) + QObject (0x0x7f65bd983b40) 0 + primary-for QAbstractTextDocumentLayout (0x0x7f65bd98d270) + +Vtable for QTextObjectInterface +QTextObjectInterface::_ZTV20QTextObjectInterface: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextObjectInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QTextObjectInterface + size=8 align=8 + base size=8 base align=8 +QTextObjectInterface (0x0x7f65bda27240) 0 nearly-empty + vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16) + +Class QAccessible::State + size=8 align=8 + base size=5 base align=8 +QAccessible::State (0x0x7f65bda27480) 0 + +Vtable for QAccessible::ActivationObserver +QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAccessible::ActivationObserver + size=8 align=8 + base size=8 base align=8 +QAccessible::ActivationObserver (0x0x7f65bda274e0) 0 nearly-empty + vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16) + +Class QAccessible + size=1 align=1 + base size=0 base align=1 +QAccessible (0x0x7f65bda27420) 0 empty + +Vtable for QAccessibleInterface +QAccessibleInterface::_ZTV20QAccessibleInterface: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAccessibleInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleInterface (0x0x7f65bda27de0) 0 nearly-empty + vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16) + +Vtable for QAccessibleTextInterface +QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAccessibleTextInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset +104 (int (*)(...))QAccessibleTextInterface::textAfterOffset +112 (int (*)(...))QAccessibleTextInterface::textAtOffset +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTextInterface (0x0x7f65bda691e0) 0 nearly-empty + vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16) + +Vtable for QAccessibleEditableTextInterface +QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleEditableTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleEditableTextInterface (0x0x7f65bda69240) 0 nearly-empty + vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16) + +Vtable for QAccessibleValueInterface +QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleValueInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleValueInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleValueInterface (0x0x7f65bda692a0) 0 nearly-empty + vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16) + +Vtable for QAccessibleTableCellInterface +QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableCellInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableCellInterface (0x0x7f65bda69300) 0 nearly-empty + vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16) + +Vtable for QAccessibleTableInterface +QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleTableInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableInterface (0x0x7f65bda69360) 0 nearly-empty + vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16) + +Vtable for QAccessibleActionInterface +QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleActionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QAccessibleActionInterface::localizedActionName +48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleActionInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleActionInterface (0x0x7f65bda693c0) 0 nearly-empty + vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16) + +Vtable for QAccessibleImageInterface +QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleImageInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleImageInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleImageInterface (0x0x7f65bda69480) 0 nearly-empty + vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16) + +Vtable for QAccessibleHyperlinkInterface +QAccessibleHyperlinkInterface::_ZTV29QAccessibleHyperlinkInterface: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleHyperlinkInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleHyperlinkInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleHyperlinkInterface (0x0x7f65bda694e0) 0 nearly-empty + vptr=((& QAccessibleHyperlinkInterface::_ZTV29QAccessibleHyperlinkInterface) + 16) + +Vtable for QAccessibleEvent +QAccessibleEvent::_ZTV16QAccessibleEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAccessibleEvent) +16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleEvent + size=32 align=8 + base size=28 base align=8 +QAccessibleEvent (0x0x7f65bda69540) 0 + vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16) + +Vtable for QAccessibleStateChangeEvent +QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent) +16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleStateChangeEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleStateChangeEvent (0x0x7f65bda22750) 0 + vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16) + QAccessibleEvent (0x0x7f65bda69a80) 0 + primary-for QAccessibleStateChangeEvent (0x0x7f65bda22750) + +Vtable for QAccessibleTextCursorEvent +QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent) +16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextCursorEvent + size=32 align=8 + base size=32 base align=8 +QAccessibleTextCursorEvent (0x0x7f65bda227b8) 0 + vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16) + QAccessibleEvent (0x0x7f65bda69e40) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f65bda227b8) + +Vtable for QAccessibleTextSelectionEvent +QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent) +16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextSelectionEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleTextSelectionEvent (0x0x7f65bda22820) 0 + vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f65bda22888) 0 + primary-for QAccessibleTextSelectionEvent (0x0x7f65bda22820) + QAccessibleEvent (0x0x7f65bd6992a0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f65bda22888) + +Vtable for QAccessibleTextInsertEvent +QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent) +16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextInsertEvent + size=64 align=8 + base size=64 base align=8 +QAccessibleTextInsertEvent (0x0x7f65bda228f0) 0 + vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f65bda22958) 0 + primary-for QAccessibleTextInsertEvent (0x0x7f65bda228f0) + QAccessibleEvent (0x0x7f65bd699720) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f65bda22958) + +Vtable for QAccessibleTextRemoveEvent +QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent) +16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextRemoveEvent + size=64 align=8 + base size=64 base align=8 +QAccessibleTextRemoveEvent (0x0x7f65bda229c0) 0 + vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f65bda22a28) 0 + primary-for QAccessibleTextRemoveEvent (0x0x7f65bda229c0) + QAccessibleEvent (0x0x7f65bd699b40) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f65bda22a28) + +Vtable for QAccessibleTextUpdateEvent +QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent) +16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextUpdateEvent + size=88 align=8 + base size=88 base align=8 +QAccessibleTextUpdateEvent (0x0x7f65bda22a90) 0 + vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f65bda22af8) 0 + primary-for QAccessibleTextUpdateEvent (0x0x7f65bda22a90) + QAccessibleEvent (0x0x7f65bd699f60) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f65bda22af8) + +Vtable for QAccessibleValueChangeEvent +QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent) +16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleValueChangeEvent + size=64 align=8 + base size=64 base align=8 +QAccessibleValueChangeEvent (0x0x7f65bda22b60) 0 + vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16) + QAccessibleEvent (0x0x7f65bd6b3420) 0 + primary-for QAccessibleValueChangeEvent (0x0x7f65bda22b60) + +Vtable for QAccessibleTableModelChangeEvent +QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent) +16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTableModelChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTableModelChangeEvent (0x0x7f65bda22bc8) 0 + vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16) + QAccessibleEvent (0x0x7f65bd6b3840) 0 + primary-for QAccessibleTableModelChangeEvent (0x0x7f65bda22bc8) + +Vtable for QAccessibleBridge +QAccessibleBridge::_ZTV17QAccessibleBridge: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleBridge) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridge + size=8 align=8 + base size=8 base align=8 +QAccessibleBridge (0x0x7f65bd6c7120) 0 nearly-empty + vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16) + +Class QAccessibleBridgePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessibleBridgePlugin::QPrivateSignal (0x0x7f65bd6c73c0) 0 empty + +Vtable for QAccessibleBridgePlugin +QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin) +16 (int (*)(...))QAccessibleBridgePlugin::metaObject +24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast +32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridgePlugin + size=16 align=8 + base size=16 base align=8 +QAccessibleBridgePlugin (0x0x7f65bda22c30) 0 + vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16) + QObject (0x0x7f65bd6c7360) 0 + primary-for QAccessibleBridgePlugin (0x0x7f65bda22c30) + +Vtable for QAccessibleObject +QAccessibleObject::_ZTV17QAccessibleObject: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleObject) +16 0 +24 0 +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleObject + size=16 align=8 + base size=16 base align=8 +QAccessibleObject (0x0x7f65bda22c98) 0 + vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16) + QAccessibleInterface (0x0x7f65bd6c7480) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f65bda22c98) + +Vtable for QAccessibleApplication +QAccessibleApplication::_ZTV22QAccessibleApplication: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QAccessibleApplication) +16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleApplication::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleApplication::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleApplication::parent +88 (int (*)(...))QAccessibleApplication::child +96 (int (*)(...))QAccessibleApplication::childCount +104 (int (*)(...))QAccessibleApplication::indexOfChild +112 (int (*)(...))QAccessibleApplication::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))QAccessibleApplication::role +144 (int (*)(...))QAccessibleApplication::state +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleApplication + size=16 align=8 + base size=16 base align=8 +QAccessibleApplication (0x0x7f65bda22d00) 0 + vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16) + QAccessibleObject (0x0x7f65bda22d68) 0 + primary-for QAccessibleApplication (0x0x7f65bda22d00) + QAccessibleInterface (0x0x7f65bd6c74e0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f65bda22d68) + +Class QAccessiblePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessiblePlugin::QPrivateSignal (0x0x7f65bd6c75a0) 0 empty + +Vtable for QAccessiblePlugin +QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessiblePlugin) +16 (int (*)(...))QAccessiblePlugin::metaObject +24 (int (*)(...))QAccessiblePlugin::qt_metacast +32 (int (*)(...))QAccessiblePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessiblePlugin + size=16 align=8 + base size=16 base align=8 +QAccessiblePlugin (0x0x7f65bda22dd0) 0 + vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16) + QObject (0x0x7f65bd6c7540) 0 + primary-for QAccessiblePlugin (0x0x7f65bda22dd0) + +Class QAction::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAction::QPrivateSignal (0x0x7f65bd6c76c0) 0 empty + +Vtable for QAction +QAction::_ZTV7QAction: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QAction) +16 (int (*)(...))QAction::metaObject +24 (int (*)(...))QAction::qt_metacast +32 (int (*)(...))QAction::qt_metacall +40 (int (*)(...))QAction::~QAction +48 (int (*)(...))QAction::~QAction +56 (int (*)(...))QAction::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QAction + size=16 align=8 + base size=16 base align=8 +QAction (0x0x7f65bda22e38) 0 + vptr=((& QAction::_ZTV7QAction) + 16) + QObject (0x0x7f65bd6c7660) 0 + primary-for QAction (0x0x7f65bda22e38) + +Class QActionGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QActionGroup::QPrivateSignal (0x0x7f65bd702000) 0 empty + +Vtable for QActionGroup +QActionGroup::_ZTV12QActionGroup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionGroup) +16 (int (*)(...))QActionGroup::metaObject +24 (int (*)(...))QActionGroup::qt_metacast +32 (int (*)(...))QActionGroup::qt_metacall +40 (int (*)(...))QActionGroup::~QActionGroup +48 (int (*)(...))QActionGroup::~QActionGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QActionGroup + size=16 align=8 + base size=16 base align=8 +QActionGroup (0x0x7f65bda22ea0) 0 + vptr=((& QActionGroup::_ZTV12QActionGroup) + 16) + QObject (0x0x7f65bd6c7f60) 0 + primary-for QActionGroup (0x0x7f65bda22ea0) + +Class QSurfaceFormat + size=8 align=8 + base size=8 base align=8 +QSurfaceFormat (0x0x7f65bd7022a0) 0 + +Vtable for QSurface +QSurface::_ZTV8QSurface: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSurface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QSurface + size=24 align=8 + base size=24 base align=8 +QSurface (0x0x7f65bd702ba0) 0 + vptr=((& QSurface::_ZTV8QSurface) + 16) + +Vtable for QBitmap +QBitmap::_ZTV7QBitmap: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBitmap) +16 (int (*)(...))QBitmap::~QBitmap +24 (int (*)(...))QBitmap::~QBitmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QBitmap + size=24 align=8 + base size=24 base align=8 +QBitmap (0x0x7f65bd7260d0) 0 + vptr=((& QBitmap::_ZTV7QBitmap) + 16) + QPixmap (0x0x7f65bd726138) 0 + primary-for QBitmap (0x0x7f65bd7260d0) + QPaintDevice (0x0x7f65bd746240) 0 + primary-for QPixmap (0x0x7f65bd726138) + +Class QCursor + size=8 align=8 + base size=8 base align=8 +QCursor (0x0x7f65bd75db40) 0 + +Class QWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWindow::QPrivateSignal (0x0x7f65bd7a3d80) 0 empty + +Vtable for QWindow +QWindow::_ZTV7QWindow: 47 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWindow) +16 (int (*)(...))QWindow::metaObject +24 (int (*)(...))QWindow::qt_metacast +32 (int (*)(...))QWindow::qt_metacall +40 (int (*)(...))QWindow::~QWindow +48 (int (*)(...))QWindow::~QWindow +56 (int (*)(...))QWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QWindow::focusInEvent +192 (int (*)(...))QWindow::focusOutEvent +200 (int (*)(...))QWindow::showEvent +208 (int (*)(...))QWindow::hideEvent +216 (int (*)(...))QWindow::closeEvent +224 (int (*)(...))QWindow::keyPressEvent +232 (int (*)(...))QWindow::keyReleaseEvent +240 (int (*)(...))QWindow::mousePressEvent +248 (int (*)(...))QWindow::mouseReleaseEvent +256 (int (*)(...))QWindow::mouseDoubleClickEvent +264 (int (*)(...))QWindow::mouseMoveEvent +272 (int (*)(...))QWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))-16 +320 (int (*)(...))(& _ZTI7QWindow) +328 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev +336 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QWindow + size=40 align=8 + base size=40 base align=8 +QWindow (0x0x7f65bd710e70) 0 + vptr=((& QWindow::_ZTV7QWindow) + 16) + QObject (0x0x7f65bd7a3cc0) 0 + primary-for QWindow (0x0x7f65bd710e70) + QSurface (0x0x7f65bd7a3d20) 16 + vptr=((& QWindow::_ZTV7QWindow) + 328) + +Class QBackingStore + size=8 align=8 + base size=8 base align=8 +QBackingStore (0x0x7f65bd7dc660) 0 + +Class QClipboard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QClipboard::QPrivateSignal (0x0x7f65bd7dc780) 0 empty + +Vtable for QClipboard +QClipboard::_ZTV10QClipboard: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QClipboard) +16 (int (*)(...))QClipboard::metaObject +24 (int (*)(...))QClipboard::qt_metacast +32 (int (*)(...))QClipboard::qt_metacall +40 (int (*)(...))QClipboard::~QClipboard +48 (int (*)(...))QClipboard::~QClipboard +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QClipboard + size=16 align=8 + base size=16 base align=8 +QClipboard (0x0x7f65bd7ab820) 0 + vptr=((& QClipboard::_ZTV10QClipboard) + 16) + QObject (0x0x7f65bd7dc720) 0 + primary-for QClipboard (0x0x7f65bd7ab820) + +Class QColorTransform + size=8 align=8 + base size=8 base align=8 +QColorTransform (0x0x7f65bd7dc8a0) 0 + +Class QColorSpace + size=8 align=8 + base size=8 base align=8 +QColorSpace (0x0x7f65bd83a8a0) 0 + +Class QDesktopServices + size=1 align=1 + base size=0 base align=1 +QDesktopServices (0x0x7f65bd491660) 0 empty + +Class QDrag::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDrag::QPrivateSignal (0x0x7f65bd491720) 0 empty + +Vtable for QDrag +QDrag::_ZTV5QDrag: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDrag) +16 (int (*)(...))QDrag::metaObject +24 (int (*)(...))QDrag::qt_metacast +32 (int (*)(...))QDrag::qt_metacall +40 (int (*)(...))QDrag::~QDrag +48 (int (*)(...))QDrag::~QDrag +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDrag + size=16 align=8 + base size=16 base align=8 +QDrag (0x0x7f65bd4953a8) 0 + vptr=((& QDrag::_ZTV5QDrag) + 16) + QObject (0x0x7f65bd4916c0) 0 + primary-for QDrag (0x0x7f65bd4953a8) + +Class QFileSystemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemModel::QPrivateSignal (0x0x7f65bd491900) 0 empty + +Vtable for QFileSystemModel +QFileSystemModel::_ZTV16QFileSystemModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QFileSystemModel) +16 (int (*)(...))QFileSystemModel::metaObject +24 (int (*)(...))QFileSystemModel::qt_metacast +32 (int (*)(...))QFileSystemModel::qt_metacall +40 (int (*)(...))QFileSystemModel::~QFileSystemModel +48 (int (*)(...))QFileSystemModel::~QFileSystemModel +56 (int (*)(...))QFileSystemModel::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QFileSystemModel::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileSystemModel::index +120 (int (*)(...))QFileSystemModel::parent +128 (int (*)(...))QFileSystemModel::sibling +136 (int (*)(...))QFileSystemModel::rowCount +144 (int (*)(...))QFileSystemModel::columnCount +152 (int (*)(...))QFileSystemModel::hasChildren +160 (int (*)(...))QFileSystemModel::data +168 (int (*)(...))QFileSystemModel::setData +176 (int (*)(...))QFileSystemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QFileSystemModel::mimeTypes +224 (int (*)(...))QFileSystemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QFileSystemModel::dropMimeData +248 (int (*)(...))QFileSystemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QFileSystemModel::fetchMore +320 (int (*)(...))QFileSystemModel::canFetchMore +328 (int (*)(...))QFileSystemModel::flags +336 (int (*)(...))QFileSystemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QFileSystemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QFileSystemModel + size=16 align=8 + base size=16 base align=8 +QFileSystemModel (0x0x7f65bd495410) 0 + vptr=((& QFileSystemModel::_ZTV16QFileSystemModel) + 16) + QAbstractItemModel (0x0x7f65bd495478) 0 + primary-for QFileSystemModel (0x0x7f65bd495410) + QObject (0x0x7f65bd4918a0) 0 + primary-for QAbstractItemModel (0x0x7f65bd495478) + +Class QFontInfo + size=8 align=8 + base size=8 base align=8 +QFontInfo (0x0x7f65bd4da000) 0 + +Class QFontMetrics + size=8 align=8 + base size=8 base align=8 +QFontMetrics (0x0x7f65bd4f2900) 0 + +Class QFontMetricsF + size=8 align=8 + base size=8 base align=8 +QFontMetricsF (0x0x7f65bd520360) 0 + +Class QGenericPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGenericPlugin::QPrivateSignal (0x0x7f65bd5ad060) 0 empty + +Vtable for QGenericPlugin +QGenericPlugin::_ZTV14QGenericPlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGenericPlugin) +16 (int (*)(...))QGenericPlugin::metaObject +24 (int (*)(...))QGenericPlugin::qt_metacast +32 (int (*)(...))QGenericPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGenericPlugin + size=16 align=8 + base size=16 base align=8 +QGenericPlugin (0x0x7f65bd5915b0) 0 + vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16) + QObject (0x0x7f65bd5ad000) 0 + primary-for QGenericPlugin (0x0x7f65bd5915b0) + +Class QGenericPluginFactory + size=1 align=1 + base size=0 base align=1 +QGenericPluginFactory (0x0x7f65bd5ad120) 0 empty + +Class QInputMethod::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputMethod::QPrivateSignal (0x0x7f65bd5ad1e0) 0 empty + +Vtable for QInputMethod +QInputMethod::_ZTV12QInputMethod: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputMethod) +16 (int (*)(...))QInputMethod::metaObject +24 (int (*)(...))QInputMethod::qt_metacast +32 (int (*)(...))QInputMethod::qt_metacall +40 (int (*)(...))QInputMethod::~QInputMethod +48 (int (*)(...))QInputMethod::~QInputMethod +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputMethod + size=16 align=8 + base size=16 base align=8 +QInputMethod (0x0x7f65bd591618) 0 + vptr=((& QInputMethod::_ZTV12QInputMethod) + 16) + QObject (0x0x7f65bd5ad180) 0 + primary-for QInputMethod (0x0x7f65bd591618) + +Class QGuiApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGuiApplication::QPrivateSignal (0x0x7f65bd5ad480) 0 empty + +Vtable for QGuiApplication +QGuiApplication::_ZTV15QGuiApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGuiApplication) +16 (int (*)(...))QGuiApplication::metaObject +24 (int (*)(...))QGuiApplication::qt_metacast +32 (int (*)(...))QGuiApplication::qt_metacall +40 (int (*)(...))QGuiApplication::~QGuiApplication +48 (int (*)(...))QGuiApplication::~QGuiApplication +56 (int (*)(...))QGuiApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGuiApplication::notify +120 (int (*)(...))QGuiApplication::compressEvent + +Class QGuiApplication + size=16 align=8 + base size=16 base align=8 +QGuiApplication (0x0x7f65bd591680) 0 + vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16) + QCoreApplication (0x0x7f65bd5916e8) 0 + primary-for QGuiApplication (0x0x7f65bd591680) + QObject (0x0x7f65bd5ad420) 0 + primary-for QCoreApplication (0x0x7f65bd5916e8) + +Class QNativeInterface::QX11Application::TypeInfo + size=1 align=1 + base size=0 base align=1 +QNativeInterface::QX11Application::TypeInfo (0x0x7f65bd5ad780) 0 empty + +Vtable for QNativeInterface::QX11Application +QNativeInterface::QX11Application::_ZTVN16QNativeInterface15QX11ApplicationE: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface15QX11ApplicationE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QX11Application + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QX11Application (0x0x7f65bd5ad720) 0 nearly-empty + vptr=((& QNativeInterface::QX11Application::_ZTVN16QNativeInterface15QX11ApplicationE) + 16) + +Class QIconEngine::ScaledPixmapArgument + size=48 align=8 + base size=48 base align=8 +QIconEngine::ScaledPixmapArgument (0x0x7f65bd5ad840) 0 + +Vtable for QIconEngine +QIconEngine::_ZTV11QIconEngine: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QIconEngine) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QIconEngine::actualSize +48 (int (*)(...))QIconEngine::pixmap +56 (int (*)(...))QIconEngine::addPixmap +64 (int (*)(...))QIconEngine::addFile +72 (int (*)(...))QIconEngine::key +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QIconEngine::read +96 (int (*)(...))QIconEngine::write +104 (int (*)(...))QIconEngine::availableSizes +112 (int (*)(...))QIconEngine::iconName +120 (int (*)(...))QIconEngine::isNull +128 (int (*)(...))QIconEngine::scaledPixmap +136 (int (*)(...))QIconEngine::virtual_hook + +Class QIconEngine + size=8 align=8 + base size=8 base align=8 +QIconEngine (0x0x7f65bd5ad7e0) 0 nearly-empty + vptr=((& QIconEngine::_ZTV11QIconEngine) + 16) + +Class QIconEnginePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIconEnginePlugin::QPrivateSignal (0x0x7f65bd5ad900) 0 empty + +Vtable for QIconEnginePlugin +QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QIconEnginePlugin) +16 (int (*)(...))QIconEnginePlugin::metaObject +24 (int (*)(...))QIconEnginePlugin::qt_metacast +32 (int (*)(...))QIconEnginePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QIconEnginePlugin + size=16 align=8 + base size=16 base align=8 +QIconEnginePlugin (0x0x7f65bd591750) 0 + vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16) + QObject (0x0x7f65bd5ad8a0) 0 + primary-for QIconEnginePlugin (0x0x7f65bd591750) + +Vtable for QImageIOHandler +QImageIOHandler::_ZTV15QImageIOHandler: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QImageIOHandler) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QImageIOHandler::write +56 (int (*)(...))QImageIOHandler::option +64 (int (*)(...))QImageIOHandler::setOption +72 (int (*)(...))QImageIOHandler::supportsOption +80 (int (*)(...))QImageIOHandler::jumpToNextImage +88 (int (*)(...))QImageIOHandler::jumpToImage +96 (int (*)(...))QImageIOHandler::loopCount +104 (int (*)(...))QImageIOHandler::imageCount +112 (int (*)(...))QImageIOHandler::nextImageDelay +120 (int (*)(...))QImageIOHandler::currentImageNumber +128 (int (*)(...))QImageIOHandler::currentImageRect + +Class QImageIOHandler + size=16 align=8 + base size=16 base align=8 +QImageIOHandler (0x0x7f65bd5ad9c0) 0 + vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16) + +Class QImageIOPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QImageIOPlugin::QPrivateSignal (0x0x7f65bd5adc00) 0 empty + +Vtable for QImageIOPlugin +QImageIOPlugin::_ZTV14QImageIOPlugin: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QImageIOPlugin) +16 (int (*)(...))QImageIOPlugin::metaObject +24 (int (*)(...))QImageIOPlugin::qt_metacast +32 (int (*)(...))QImageIOPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QImageIOPlugin + size=16 align=8 + base size=16 base align=8 +QImageIOPlugin (0x0x7f65bd5917b8) 0 + vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16) + QObject (0x0x7f65bd5adba0) 0 + primary-for QImageIOPlugin (0x0x7f65bd5917b8) + +Class QImageReader + size=8 align=8 + base size=8 base align=8 +QImageReader (0x0x7f65bd60e0c0) 0 + +Class QImageWriter + size=8 align=8 + base size=8 base align=8 +QImageWriter (0x0x7f65bd60e180) 0 + +Class QQuaternion + size=16 align=4 + base size=16 base align=4 +QQuaternion (0x0x7f65bd60e240) 0 + +Class QMatrix4x4 + size=68 align=4 + base size=68 base align=4 +QMatrix4x4 (0x0x7f65bd65af60) 0 + +Class QMovie::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMovie::QPrivateSignal (0x0x7f65bd2cc4e0) 0 empty + +Vtable for QMovie +QMovie::_ZTV6QMovie: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QMovie) +16 (int (*)(...))QMovie::metaObject +24 (int (*)(...))QMovie::qt_metacast +32 (int (*)(...))QMovie::qt_metacall +40 (int (*)(...))QMovie::~QMovie +48 (int (*)(...))QMovie::~QMovie +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QMovie + size=16 align=8 + base size=16 base align=8 +QMovie (0x0x7f65bd2d5000) 0 + vptr=((& QMovie::_ZTV6QMovie) + 16) + QObject (0x0x7f65bd2cc480) 0 + primary-for QMovie (0x0x7f65bd2d5000) + +Class QOffscreenSurface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOffscreenSurface::QPrivateSignal (0x0x7f65bd2cc8a0) 0 empty + +Vtable for QOffscreenSurface +QOffscreenSurface::_ZTV17QOffscreenSurface: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOffscreenSurface) +16 (int (*)(...))QOffscreenSurface::metaObject +24 (int (*)(...))QOffscreenSurface::qt_metacast +32 (int (*)(...))QOffscreenSurface::qt_metacall +40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOffscreenSurface::surfaceType +120 (int (*)(...))QOffscreenSurface::format +128 (int (*)(...))QOffscreenSurface::size +136 (int (*)(...))QOffscreenSurface::surfaceHandle +144 (int (*)(...))-16 +152 (int (*)(...))(& _ZTI17QOffscreenSurface) +160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev +168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev +176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv +184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv +192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv +200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv + +Class QOffscreenSurface + size=40 align=8 + base size=40 base align=8 +QOffscreenSurface (0x0x7f65bd2b2700) 0 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16) + QObject (0x0x7f65bd2cc7e0) 0 + primary-for QOffscreenSurface (0x0x7f65bd2b2700) + QSurface (0x0x7f65bd2cc840) 16 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160) + +Class QOpenGLContextGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContextGroup::QPrivateSignal (0x0x7f65bd2ccb40) 0 empty + +Vtable for QOpenGLContextGroup +QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QOpenGLContextGroup) +16 (int (*)(...))QOpenGLContextGroup::metaObject +24 (int (*)(...))QOpenGLContextGroup::qt_metacast +32 (int (*)(...))QOpenGLContextGroup::qt_metacall +40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContextGroup + size=16 align=8 + base size=16 base align=8 +QOpenGLContextGroup (0x0x7f65bd2d5068) 0 + vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16) + QObject (0x0x7f65bd2ccae0) 0 + primary-for QOpenGLContextGroup (0x0x7f65bd2d5068) + +Class QOpenGLContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContext::QPrivateSignal (0x0x7f65bd2ccd20) 0 empty + +Vtable for QOpenGLContext +QOpenGLContext::_ZTV14QOpenGLContext: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QOpenGLContext) +16 (int (*)(...))QOpenGLContext::metaObject +24 (int (*)(...))QOpenGLContext::qt_metacast +32 (int (*)(...))QOpenGLContext::qt_metacall +40 (int (*)(...))QOpenGLContext::~QOpenGLContext +48 (int (*)(...))QOpenGLContext::~QOpenGLContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContext + size=16 align=8 + base size=16 base align=8 +QOpenGLContext (0x0x7f65bd2d50d0) 0 + vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16) + QObject (0x0x7f65bd2cccc0) 0 + primary-for QOpenGLContext (0x0x7f65bd2d50d0) + +Class QNativeInterface::QGLXContext::TypeInfo + size=1 align=1 + base size=0 base align=1 +QNativeInterface::QGLXContext::TypeInfo (0x0x7f65bd2ccf60) 0 empty + +Vtable for QNativeInterface::QGLXContext +QNativeInterface::QGLXContext::_ZTVN16QNativeInterface11QGLXContextE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface11QGLXContextE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QGLXContext + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QGLXContext (0x0x7f65bd2ccf00) 0 nearly-empty + vptr=((& QNativeInterface::QGLXContext::_ZTVN16QNativeInterface11QGLXContextE) + 16) + +Class QNativeInterface::QEGLContext::TypeInfo + size=1 align=1 + base size=0 base align=1 +QNativeInterface::QEGLContext::TypeInfo (0x0x7f65bd1eb060) 0 empty + +Vtable for QNativeInterface::QEGLContext +QNativeInterface::QEGLContext::_ZTVN16QNativeInterface11QEGLContextE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface11QEGLContextE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QEGLContext + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QEGLContext (0x0x7f65bd1eb000) 0 nearly-empty + vptr=((& QNativeInterface::QEGLContext::_ZTVN16QNativeInterface11QEGLContextE) + 16) + +Class QOpenGLFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLFunctions (0x0x7f65bd1eb0c0) 0 + +Class QOpenGLFunctionsPrivate::Functions + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate::Functions (0x0x7f65bd1eb720) 0 + +Class QOpenGLFunctionsPrivate + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate (0x0x7f65bd1eb6c0) 0 + +Class QOpenGLExtraFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLExtraFunctions (0x0x7f65bd2d54e0) 0 + QOpenGLFunctions (0x0x7f65bce83ea0) 0 + +Class QOpenGLExtraFunctionsPrivate::Functions + size=1728 align=8 + base size=1728 base align=8 +QOpenGLExtraFunctionsPrivate::Functions (0x0x7f65bceda240) 0 + +Class QOpenGLExtraFunctionsPrivate + size=2880 align=8 + base size=2880 base align=8 +QOpenGLExtraFunctionsPrivate (0x0x7f65bd2d5548) 0 + QOpenGLFunctionsPrivate (0x0x7f65bceda1e0) 0 + +Class QPageSize + size=8 align=8 + base size=8 base align=8 +QPageSize (0x0x7f65bcfa5f00) 0 + +Class QPageLayout + size=8 align=8 + base size=8 base align=8 +QPageLayout (0x0x7f65bd02d540) 0 + +Class QPageRanges::Range + size=8 align=4 + base size=8 base align=4 +QPageRanges::Range (0x0x7f65bcce5540) 0 + +Class QPageRanges + size=8 align=8 + base size=8 base align=8 +QPageRanges (0x0x7f65bcce54e0) 0 + +Vtable for QPagedPaintDevice +QPagedPaintDevice::_ZTV17QPagedPaintDevice: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QPagedPaintDevice) +16 0 +24 0 +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QPagedPaintDevice::setPageLayout +96 (int (*)(...))QPagedPaintDevice::setPageSize +104 (int (*)(...))QPagedPaintDevice::setPageOrientation +112 (int (*)(...))QPagedPaintDevice::setPageMargins +120 (int (*)(...))QPagedPaintDevice::setPageRanges + +Class QPagedPaintDevice + size=24 align=8 + base size=24 base align=8 +QPagedPaintDevice (0x0x7f65bcd613a8) 0 + vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16) + QPaintDevice (0x0x7f65bcd5dae0) 0 + primary-for QPagedPaintDevice (0x0x7f65bcd613a8) + +Class QPaintDeviceWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPaintDeviceWindow::QPrivateSignal (0x0x7f65bcd5dc60) 0 empty + +Vtable for QPaintDeviceWindow +QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 59 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +16 (int (*)(...))QPaintDeviceWindow::metaObject +24 (int (*)(...))QPaintDeviceWindow::qt_metacast +32 (int (*)(...))QPaintDeviceWindow::qt_metacall +40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QPaintDeviceWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QWindow::focusInEvent +192 (int (*)(...))QWindow::focusOutEvent +200 (int (*)(...))QWindow::showEvent +208 (int (*)(...))QWindow::hideEvent +216 (int (*)(...))QWindow::closeEvent +224 (int (*)(...))QWindow::keyPressEvent +232 (int (*)(...))QWindow::keyReleaseEvent +240 (int (*)(...))QWindow::mousePressEvent +248 (int (*)(...))QWindow::mouseReleaseEvent +256 (int (*)(...))QWindow::mouseDoubleClickEvent +264 (int (*)(...))QWindow::mouseMoveEvent +272 (int (*)(...))QWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))QPaintDeviceWindow::metric +320 (int (*)(...))QPaintDeviceWindow::paintEngine +328 (int (*)(...))-16 +336 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev +352 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +392 (int (*)(...))-40 +400 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev +416 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev +424 (int (*)(...))QPaintDevice::devType +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +440 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE +448 (int (*)(...))QPaintDevice::initPainter +456 (int (*)(...))QPaintDevice::redirected +464 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDeviceWindow + size=56 align=8 + base size=50 base align=8 +QPaintDeviceWindow (0x0x7f65bcca7f50) 0 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16) + QWindow (0x0x7f65bcd74000) 0 + primary-for QPaintDeviceWindow (0x0x7f65bcca7f50) + QObject (0x0x7f65bcd5db40) 0 + primary-for QWindow (0x0x7f65bcd74000) + QSurface (0x0x7f65bcd5dba0) 16 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 344) + QPaintDevice (0x0x7f65bcd5dc00) 40 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 408) + +Class QPainter::PixmapFragment + size=80 align=8 + base size=80 base align=8 +QPainter::PixmapFragment (0x0x7f65bcd5de40) 0 + +Class QPainter + size=8 align=8 + base size=8 base align=8 +QPainter (0x0x7f65bcd5dde0) 0 + +Class QTextItem + size=1 align=1 + base size=0 base align=1 +QTextItem (0x0x7f65bcb72a20) 0 empty + +Vtable for QPaintEngine +QPaintEngine::_ZTV12QPaintEngine: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintEngine) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QPaintEngine::drawRects +64 (int (*)(...))QPaintEngine::drawRects +72 (int (*)(...))QPaintEngine::drawLines +80 (int (*)(...))QPaintEngine::drawLines +88 (int (*)(...))QPaintEngine::drawEllipse +96 (int (*)(...))QPaintEngine::drawEllipse +104 (int (*)(...))QPaintEngine::drawPath +112 (int (*)(...))QPaintEngine::drawPoints +120 (int (*)(...))QPaintEngine::drawPoints +128 (int (*)(...))QPaintEngine::drawPolygon +136 (int (*)(...))QPaintEngine::drawPolygon +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QPaintEngine::drawTextItem +160 (int (*)(...))QPaintEngine::drawTiledPixmap +168 (int (*)(...))QPaintEngine::drawImage +176 (int (*)(...))QPaintEngine::coordinateOffset +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))QPaintEngine::createPixmap +200 (int (*)(...))QPaintEngine::createPixmapFromImage + +Class QPaintEngine + size=32 align=8 + base size=32 base align=8 +QPaintEngine (0x0x7f65bcbb4240) 0 + vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16) + +Class QPaintEngineState + size=4 align=4 + base size=4 base align=4 +QPaintEngineState (0x0x7f65bcbb4840) 0 + +Class QPainterPath::Element + size=24 align=8 + base size=24 base align=8 +QPainterPath::Element (0x0x7f65bcc3f540) 0 + +Class QPainterPath + size=8 align=8 + base size=8 base align=8 +QPainterPath (0x0x7f65bcc3f4e0) 0 + +Class QPainterPathStroker + size=8 align=8 + base size=8 base align=8 +QPainterPathStroker (0x0x7f65bc8f4840) 0 + +Class QPdfWriter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPdfWriter::QPrivateSignal (0x0x7f65bc921000) 0 empty + +Vtable for QPdfWriter +QPdfWriter::_ZTV10QPdfWriter: 33 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QPdfWriter) +16 (int (*)(...))QPdfWriter::metaObject +24 (int (*)(...))QPdfWriter::qt_metacast +32 (int (*)(...))QPdfWriter::qt_metacall +40 (int (*)(...))QPdfWriter::~QPdfWriter +48 (int (*)(...))QPdfWriter::~QPdfWriter +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPdfWriter::newPage +120 (int (*)(...))QPdfWriter::paintEngine +128 (int (*)(...))QPdfWriter::metric +136 (int (*)(...))-16 +144 (int (*)(...))(& _ZTI10QPdfWriter) +152 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev +160 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev +168 (int (*)(...))QPaintDevice::devType +176 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv +184 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE +192 (int (*)(...))QPaintDevice::initPainter +200 (int (*)(...))QPaintDevice::redirected +208 (int (*)(...))QPaintDevice::sharedPainter +216 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv +224 (int (*)(...))QPagedPaintDevice::setPageLayout +232 (int (*)(...))QPagedPaintDevice::setPageSize +240 (int (*)(...))QPagedPaintDevice::setPageOrientation +248 (int (*)(...))QPagedPaintDevice::setPageMargins +256 (int (*)(...))QPagedPaintDevice::setPageRanges + +Class QPdfWriter + size=40 align=8 + base size=40 base align=8 +QPdfWriter (0x0x7f65bcc7ea80) 0 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16) + QObject (0x0x7f65bc8f4f60) 0 + primary-for QPdfWriter (0x0x7f65bcc7ea80) + QPagedPaintDevice (0x0x7f65bc8ff1a0) 16 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 152) + QPaintDevice (0x0x7f65bc8f44e0) 16 + primary-for QPagedPaintDevice (0x0x7f65bc8ff1a0) + +Vtable for QPicture +QPicture::_ZTV8QPicture: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPicture) +16 (int (*)(...))QPicture::~QPicture +24 (int (*)(...))QPicture::~QPicture +32 (int (*)(...))QPicture::devType +40 (int (*)(...))QPicture::paintEngine +48 (int (*)(...))QPicture::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPicture::setData + +Class QPicture + size=24 align=8 + base size=24 base align=8 +QPicture (0x0x7f65bc8ff208) 0 + vptr=((& QPicture::_ZTV8QPicture) + 16) + QPaintDevice (0x0x7f65bc9211e0) 0 + primary-for QPicture (0x0x7f65bc8ff208) + +Class QPixmapCache::Key + size=8 align=8 + base size=8 base align=8 +QPixmapCache::Key (0x0x7f65bc960cc0) 0 + +Class QPixmapCache + size=1 align=1 + base size=0 base align=1 +QPixmapCache (0x0x7f65bc960c60) 0 empty + +Class QRasterWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRasterWindow::QPrivateSignal (0x0x7f65bc9b7f60) 0 empty + +Vtable for QRasterWindow +QRasterWindow::_ZTV13QRasterWindow: 60 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QRasterWindow) +16 (int (*)(...))QRasterWindow::metaObject +24 (int (*)(...))QRasterWindow::qt_metacast +32 (int (*)(...))QRasterWindow::qt_metacall +40 (int (*)(...))QRasterWindow::~QRasterWindow +48 (int (*)(...))QRasterWindow::~QRasterWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QPaintDeviceWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QWindow::focusInEvent +192 (int (*)(...))QWindow::focusOutEvent +200 (int (*)(...))QWindow::showEvent +208 (int (*)(...))QWindow::hideEvent +216 (int (*)(...))QWindow::closeEvent +224 (int (*)(...))QWindow::keyPressEvent +232 (int (*)(...))QWindow::keyReleaseEvent +240 (int (*)(...))QWindow::mousePressEvent +248 (int (*)(...))QWindow::mouseReleaseEvent +256 (int (*)(...))QWindow::mouseDoubleClickEvent +264 (int (*)(...))QWindow::mouseMoveEvent +272 (int (*)(...))QWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))QRasterWindow::metric +320 (int (*)(...))QPaintDeviceWindow::paintEngine +328 (int (*)(...))QRasterWindow::redirected +336 (int (*)(...))-16 +344 (int (*)(...))(& _ZTI13QRasterWindow) +352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev +360 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +392 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +400 (int (*)(...))-40 +408 (int (*)(...))(& _ZTI13QRasterWindow) +416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev +424 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev +432 (int (*)(...))QPaintDevice::devType +440 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +448 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE +456 (int (*)(...))QPaintDevice::initPainter +464 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint +472 (int (*)(...))QPaintDevice::sharedPainter + +Class QRasterWindow + size=56 align=8 + base size=50 base align=8 +QRasterWindow (0x0x7f65bc9bf820) 0 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16) + QPaintDeviceWindow (0x0x7f65bc98d690) 0 + primary-for QRasterWindow (0x0x7f65bc9bf820) + QWindow (0x0x7f65bc98d700) 0 + primary-for QPaintDeviceWindow (0x0x7f65bc98d690) + QObject (0x0x7f65bc9b7e40) 0 + primary-for QWindow (0x0x7f65bc98d700) + QSurface (0x0x7f65bc9b7ea0) 16 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 352) + QPaintDevice (0x0x7f65bc9b7f00) 40 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 416) + +Class QSessionManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSessionManager::QPrivateSignal (0x0x7f65bc9d4c60) 0 empty + +Vtable for QSessionManager +QSessionManager::_ZTV15QSessionManager: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSessionManager) +16 (int (*)(...))QSessionManager::metaObject +24 (int (*)(...))QSessionManager::qt_metacast +32 (int (*)(...))QSessionManager::qt_metacall +40 (int (*)(...))QSessionManager::~QSessionManager +48 (int (*)(...))QSessionManager::~QSessionManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSessionManager + size=16 align=8 + base size=16 base align=8 +QSessionManager (0x0x7f65bc9bf8f0) 0 + vptr=((& QSessionManager::_ZTV15QSessionManager) + 16) + QObject (0x0x7f65bc9d4c00) 0 + primary-for QSessionManager (0x0x7f65bc9bf8f0) + +Class QShortcut::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QShortcut::QPrivateSignal (0x0x7f65bc9d4e40) 0 empty + +Vtable for QShortcut +QShortcut::_ZTV9QShortcut: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QShortcut) +16 (int (*)(...))QShortcut::metaObject +24 (int (*)(...))QShortcut::qt_metacast +32 (int (*)(...))QShortcut::qt_metacall +40 (int (*)(...))QShortcut::~QShortcut +48 (int (*)(...))QShortcut::~QShortcut +56 (int (*)(...))QShortcut::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QShortcut + size=16 align=8 + base size=16 base align=8 +QShortcut (0x0x7f65bc9bf958) 0 + vptr=((& QShortcut::_ZTV9QShortcut) + 16) + QObject (0x0x7f65bc9d4de0) 0 + primary-for QShortcut (0x0x7f65bc9bf958) + +Vtable for QStandardItem +QStandardItem::_ZTV13QStandardItem: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStandardItem) +16 (int (*)(...))QStandardItem::~QStandardItem +24 (int (*)(...))QStandardItem::~QStandardItem +32 (int (*)(...))QStandardItem::data +40 (int (*)(...))QStandardItem::multiData +48 (int (*)(...))QStandardItem::setData +56 (int (*)(...))QStandardItem::clone +64 (int (*)(...))QStandardItem::type +72 (int (*)(...))QStandardItem::read +80 (int (*)(...))QStandardItem::write +88 (int (*)(...))QStandardItem::operator< + +Class QStandardItem + size=16 align=8 + base size=16 base align=8 +QStandardItem (0x0x7f65bca0d360) 0 + vptr=((& QStandardItem::_ZTV13QStandardItem) + 16) + +Class QStandardItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStandardItemModel::QPrivateSignal (0x0x7f65bc6da360) 0 empty + +Vtable for QStandardItemModel +QStandardItemModel::_ZTV18QStandardItemModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QStandardItemModel) +16 (int (*)(...))QStandardItemModel::metaObject +24 (int (*)(...))QStandardItemModel::qt_metacast +32 (int (*)(...))QStandardItemModel::qt_metacall +40 (int (*)(...))QStandardItemModel::~QStandardItemModel +48 (int (*)(...))QStandardItemModel::~QStandardItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStandardItemModel::index +120 (int (*)(...))QStandardItemModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QStandardItemModel::rowCount +144 (int (*)(...))QStandardItemModel::columnCount +152 (int (*)(...))QStandardItemModel::hasChildren +160 (int (*)(...))QStandardItemModel::data +168 (int (*)(...))QStandardItemModel::setData +176 (int (*)(...))QStandardItemModel::headerData +184 (int (*)(...))QStandardItemModel::setHeaderData +192 (int (*)(...))QStandardItemModel::itemData +200 (int (*)(...))QStandardItemModel::setItemData +208 (int (*)(...))QStandardItemModel::clearItemData +216 (int (*)(...))QStandardItemModel::mimeTypes +224 (int (*)(...))QStandardItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QStandardItemModel::dropMimeData +248 (int (*)(...))QStandardItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QStandardItemModel::insertRows +272 (int (*)(...))QStandardItemModel::insertColumns +280 (int (*)(...))QStandardItemModel::removeRows +288 (int (*)(...))QStandardItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QStandardItemModel::flags +336 (int (*)(...))QStandardItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QStandardItemModel::roleNames +376 (int (*)(...))QStandardItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QStandardItemModel + size=16 align=8 + base size=16 base align=8 +QStandardItemModel (0x0x7f65bca7b2d8) 0 + vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16) + QAbstractItemModel (0x0x7f65bca7b340) 0 + primary-for QStandardItemModel (0x0x7f65bca7b2d8) + QObject (0x0x7f65bc6da300) 0 + primary-for QAbstractItemModel (0x0x7f65bca7b340) + +Class QStaticText + size=8 align=8 + base size=8 base align=8 +QStaticText (0x0x7f65bc6da6c0) 0 + +Class QStyleHints::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyleHints::QPrivateSignal (0x0x7f65bc78b480) 0 empty + +Vtable for QStyleHints +QStyleHints::_ZTV11QStyleHints: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QStyleHints) +16 (int (*)(...))QStyleHints::metaObject +24 (int (*)(...))QStyleHints::qt_metacast +32 (int (*)(...))QStyleHints::qt_metacall +40 (int (*)(...))QStyleHints::~QStyleHints +48 (int (*)(...))QStyleHints::~QStyleHints +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QStyleHints + size=16 align=8 + base size=16 base align=8 +QStyleHints (0x0x7f65bc78d068) 0 + vptr=((& QStyleHints::_ZTV11QStyleHints) + 16) + QObject (0x0x7f65bc78b420) 0 + primary-for QStyleHints (0x0x7f65bc78d068) + +Class QTextObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextObject::QPrivateSignal (0x0x7f65bc78b660) 0 empty + +Vtable for QTextObject +QTextObject::_ZTV11QTextObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextObject) +16 (int (*)(...))QTextObject::metaObject +24 (int (*)(...))QTextObject::qt_metacast +32 (int (*)(...))QTextObject::qt_metacall +40 (int (*)(...))QTextObject::~QTextObject +48 (int (*)(...))QTextObject::~QTextObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextObject + size=16 align=8 + base size=16 base align=8 +QTextObject (0x0x7f65bc78d0d0) 0 + vptr=((& QTextObject::_ZTV11QTextObject) + 16) + QObject (0x0x7f65bc78b600) 0 + primary-for QTextObject (0x0x7f65bc78d0d0) + +Class QTextBlockGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBlockGroup::QPrivateSignal (0x0x7f65bc78b840) 0 empty + +Vtable for QTextBlockGroup +QTextBlockGroup::_ZTV15QTextBlockGroup: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTextBlockGroup) +16 (int (*)(...))QTextBlockGroup::metaObject +24 (int (*)(...))QTextBlockGroup::qt_metacast +32 (int (*)(...))QTextBlockGroup::qt_metacall +40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextBlockGroup + size=16 align=8 + base size=16 base align=8 +QTextBlockGroup (0x0x7f65bc78d138) 0 + vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16) + QTextObject (0x0x7f65bc78d1a0) 0 + primary-for QTextBlockGroup (0x0x7f65bc78d138) + QObject (0x0x7f65bc78b7e0) 0 + primary-for QTextObject (0x0x7f65bc78d1a0) + +Vtable for QTextFrameLayoutData +QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextFrameLayoutData) +16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData +24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData + +Class QTextFrameLayoutData + size=8 align=8 + base size=8 base align=8 +QTextFrameLayoutData (0x0x7f65bc78b9c0) 0 nearly-empty + vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16) + +Class QTextFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextFrame::QPrivateSignal (0x0x7f65bc78ba80) 0 empty + +Class QTextFrame::iterator + size=32 align=8 + base size=28 base align=8 +QTextFrame::iterator (0x0x7f65bc78bae0) 0 + +Vtable for QTextFrame +QTextFrame::_ZTV10QTextFrame: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextFrame) +16 (int (*)(...))QTextFrame::metaObject +24 (int (*)(...))QTextFrame::qt_metacast +32 (int (*)(...))QTextFrame::qt_metacall +40 (int (*)(...))QTextFrame::~QTextFrame +48 (int (*)(...))QTextFrame::~QTextFrame +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextFrame + size=16 align=8 + base size=16 base align=8 +QTextFrame (0x0x7f65bc78d208) 0 + vptr=((& QTextFrame::_ZTV10QTextFrame) + 16) + QTextObject (0x0x7f65bc78d270) 0 + primary-for QTextFrame (0x0x7f65bc78d208) + QObject (0x0x7f65bc78ba20) 0 + primary-for QTextObject (0x0x7f65bc78d270) + +Vtable for QTextBlockUserData +QTextBlockUserData::_ZTV18QTextBlockUserData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTextBlockUserData) +16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData +24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData + +Class QTextBlockUserData + size=8 align=8 + base size=8 base align=8 +QTextBlockUserData (0x0x7f65bc804960) 0 nearly-empty + vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16) + +Class QTextBlock::iterator + size=24 align=8 + base size=20 base align=8 +QTextBlock::iterator (0x0x7f65bc804a20) 0 + +Class QTextBlock + size=16 align=8 + base size=12 base align=8 +QTextBlock (0x0x7f65bc8049c0) 0 + +Class QTextFragment + size=16 align=8 + base size=16 base align=8 +QTextFragment (0x0x7f65bc48e2a0) 0 + +Class QSyntaxHighlighter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSyntaxHighlighter::QPrivateSignal (0x0x7f65bc4cd120) 0 empty + +Vtable for QSyntaxHighlighter +QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSyntaxHighlighter) +16 (int (*)(...))QSyntaxHighlighter::metaObject +24 (int (*)(...))QSyntaxHighlighter::qt_metacast +32 (int (*)(...))QSyntaxHighlighter::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSyntaxHighlighter + size=16 align=8 + base size=16 base align=8 +QSyntaxHighlighter (0x0x7f65bc4c4410) 0 + vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16) + QObject (0x0x7f65bc4cd0c0) 0 + primary-for QSyntaxHighlighter (0x0x7f65bc4c4410) + +Class QTextDocumentFragment + size=8 align=8 + base size=8 base align=8 +QTextDocumentFragment (0x0x7f65bc4cd2a0) 0 + +Class QTextDocumentWriter + size=8 align=8 + base size=8 base align=8 +QTextDocumentWriter (0x0x7f65bc4cd300) 0 + +Class QTextList::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextList::QPrivateSignal (0x0x7f65bc4cd3c0) 0 empty + +Vtable for QTextList +QTextList::_ZTV9QTextList: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextList) +16 (int (*)(...))QTextList::metaObject +24 (int (*)(...))QTextList::qt_metacast +32 (int (*)(...))QTextList::qt_metacall +40 (int (*)(...))QTextList::~QTextList +48 (int (*)(...))QTextList::~QTextList +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextList + size=16 align=8 + base size=16 base align=8 +QTextList (0x0x7f65bc4c4478) 0 + vptr=((& QTextList::_ZTV9QTextList) + 16) + QTextBlockGroup (0x0x7f65bc4c44e0) 0 + primary-for QTextList (0x0x7f65bc4c4478) + QTextObject (0x0x7f65bc4c4548) 0 + primary-for QTextBlockGroup (0x0x7f65bc4c44e0) + QObject (0x0x7f65bc4cd360) 0 + primary-for QTextObject (0x0x7f65bc4c4548) + +Class QTextTableCell + size=16 align=8 + base size=12 base align=8 +QTextTableCell (0x0x7f65bc4cd780) 0 + +Class QTextTable::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextTable::QPrivateSignal (0x0x7f65bc509000) 0 empty + +Vtable for QTextTable +QTextTable::_ZTV10QTextTable: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextTable) +16 (int (*)(...))QTextTable::metaObject +24 (int (*)(...))QTextTable::qt_metacast +32 (int (*)(...))QTextTable::qt_metacall +40 (int (*)(...))QTextTable::~QTextTable +48 (int (*)(...))QTextTable::~QTextTable +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextTable + size=16 align=8 + base size=16 base align=8 +QTextTable (0x0x7f65bc4c45b0) 0 + vptr=((& QTextTable::_ZTV10QTextTable) + 16) + QTextFrame (0x0x7f65bc4c4618) 0 + primary-for QTextTable (0x0x7f65bc4c45b0) + QTextObject (0x0x7f65bc4c4680) 0 + primary-for QTextFrame (0x0x7f65bc4c4618) + QObject (0x0x7f65bc4cdf60) 0 + primary-for QTextObject (0x0x7f65bc4c4680) + +Class QUndoGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoGroup::QPrivateSignal (0x0x7f65bc5093c0) 0 empty + +Vtable for QUndoGroup +QUndoGroup::_ZTV10QUndoGroup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUndoGroup) +16 (int (*)(...))QUndoGroup::metaObject +24 (int (*)(...))QUndoGroup::qt_metacast +32 (int (*)(...))QUndoGroup::qt_metacall +40 (int (*)(...))QUndoGroup::~QUndoGroup +48 (int (*)(...))QUndoGroup::~QUndoGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QUndoGroup + size=16 align=8 + base size=16 base align=8 +QUndoGroup (0x0x7f65bc4c46e8) 0 + vptr=((& QUndoGroup::_ZTV10QUndoGroup) + 16) + QObject (0x0x7f65bc509360) 0 + primary-for QUndoGroup (0x0x7f65bc4c46e8) + +Vtable for QUndoCommand +QUndoCommand::_ZTV12QUndoCommand: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QUndoCommand) +16 (int (*)(...))QUndoCommand::~QUndoCommand +24 (int (*)(...))QUndoCommand::~QUndoCommand +32 (int (*)(...))QUndoCommand::undo +40 (int (*)(...))QUndoCommand::redo +48 (int (*)(...))QUndoCommand::id +56 (int (*)(...))QUndoCommand::mergeWith + +Class QUndoCommand + size=16 align=8 + base size=16 base align=8 +QUndoCommand (0x0x7f65bc509540) 0 + vptr=((& QUndoCommand::_ZTV12QUndoCommand) + 16) + +Class QUndoStack::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoStack::QPrivateSignal (0x0x7f65bc509600) 0 empty + +Vtable for QUndoStack +QUndoStack::_ZTV10QUndoStack: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUndoStack) +16 (int (*)(...))QUndoStack::metaObject +24 (int (*)(...))QUndoStack::qt_metacast +32 (int (*)(...))QUndoStack::qt_metacall +40 (int (*)(...))QUndoStack::~QUndoStack +48 (int (*)(...))QUndoStack::~QUndoStack +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QUndoStack + size=16 align=8 + base size=16 base align=8 +QUndoStack (0x0x7f65bc4c4750) 0 + vptr=((& QUndoStack::_ZTV10QUndoStack) + 16) + QObject (0x0x7f65bc5095a0) 0 + primary-for QUndoStack (0x0x7f65bc4c4750) + +Class QValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QValidator::QPrivateSignal (0x0x7f65bc5097e0) 0 empty + +Vtable for QValidator +QValidator::_ZTV10QValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QValidator) +16 (int (*)(...))QValidator::metaObject +24 (int (*)(...))QValidator::qt_metacast +32 (int (*)(...))QValidator::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QValidator::fixup + +Class QValidator + size=16 align=8 + base size=16 base align=8 +QValidator (0x0x7f65bc4c47b8) 0 + vptr=((& QValidator::_ZTV10QValidator) + 16) + QObject (0x0x7f65bc509780) 0 + primary-for QValidator (0x0x7f65bc4c47b8) + +Class QIntValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIntValidator::QPrivateSignal (0x0x7f65bc509a80) 0 empty + +Vtable for QIntValidator +QIntValidator::_ZTV13QIntValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QIntValidator) +16 (int (*)(...))QIntValidator::metaObject +24 (int (*)(...))QIntValidator::qt_metacast +32 (int (*)(...))QIntValidator::qt_metacall +40 (int (*)(...))QIntValidator::~QIntValidator +48 (int (*)(...))QIntValidator::~QIntValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIntValidator::validate +120 (int (*)(...))QIntValidator::fixup + +Class QIntValidator + size=24 align=8 + base size=24 base align=8 +QIntValidator (0x0x7f65bc4c4820) 0 + vptr=((& QIntValidator::_ZTV13QIntValidator) + 16) + QValidator (0x0x7f65bc4c4888) 0 + primary-for QIntValidator (0x0x7f65bc4c4820) + QObject (0x0x7f65bc509a20) 0 + primary-for QValidator (0x0x7f65bc4c4888) + +Class QDoubleValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleValidator::QPrivateSignal (0x0x7f65bc509c60) 0 empty + +Vtable for QDoubleValidator +QDoubleValidator::_ZTV16QDoubleValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDoubleValidator) +16 (int (*)(...))QDoubleValidator::metaObject +24 (int (*)(...))QDoubleValidator::qt_metacast +32 (int (*)(...))QDoubleValidator::qt_metacall +40 (int (*)(...))QDoubleValidator::~QDoubleValidator +48 (int (*)(...))QDoubleValidator::~QDoubleValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDoubleValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QDoubleValidator + size=40 align=8 + base size=36 base align=8 +QDoubleValidator (0x0x7f65bc4c48f0) 0 + vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16) + QValidator (0x0x7f65bc4c4958) 0 + primary-for QDoubleValidator (0x0x7f65bc4c48f0) + QObject (0x0x7f65bc509c00) 0 + primary-for QValidator (0x0x7f65bc4c4958) + +Class QRegularExpressionValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegularExpressionValidator::QPrivateSignal (0x0x7f65bc56f060) 0 empty + +Vtable for QRegularExpressionValidator +QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QRegularExpressionValidator) +16 (int (*)(...))QRegularExpressionValidator::metaObject +24 (int (*)(...))QRegularExpressionValidator::qt_metacast +32 (int (*)(...))QRegularExpressionValidator::qt_metacall +40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegularExpressionValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegularExpressionValidator + size=16 align=8 + base size=16 base align=8 +QRegularExpressionValidator (0x0x7f65bc4c49c0) 0 + vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16) + QValidator (0x0x7f65bc4c4a28) 0 + primary-for QRegularExpressionValidator (0x0x7f65bc4c49c0) + QObject (0x0x7f65bc56f000) 0 + primary-for QValidator (0x0x7f65bc4c4a28) + +Class QNetworkRequest + size=8 align=8 + base size=8 base align=8 +QNetworkRequest (0x0x7f65bc56f1e0) 0 + +Class QNetworkCacheMetaData + size=8 align=8 + base size=8 base align=8 +QNetworkCacheMetaData (0x0x7f65bc665300) 0 + +Class QAbstractNetworkCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractNetworkCache::QPrivateSignal (0x0x7f65bc2d4b40) 0 empty + +Vtable for QAbstractNetworkCache +QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractNetworkCache) +16 (int (*)(...))QAbstractNetworkCache::metaObject +24 (int (*)(...))QAbstractNetworkCache::qt_metacast +32 (int (*)(...))QAbstractNetworkCache::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNetworkCache + size=16 align=8 + base size=16 base align=8 +QAbstractNetworkCache (0x0x7f65bc2d3e38) 0 + vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16) + QObject (0x0x7f65bc2d4ae0) 0 + primary-for QAbstractNetworkCache (0x0x7f65bc2d3e38) + +Class QAbstractSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSocket::QPrivateSignal (0x0x7f65bc2d4d80) 0 empty + +Vtable for QAbstractSocket +QAbstractSocket::_ZTV15QAbstractSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSocket) +16 (int (*)(...))QAbstractSocket::metaObject +24 (int (*)(...))QAbstractSocket::qt_metacast +32 (int (*)(...))QAbstractSocket::qt_metacall +40 (int (*)(...))QAbstractSocket::~QAbstractSocket +48 (int (*)(...))QAbstractSocket::~QAbstractSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::skipData +240 (int (*)(...))QAbstractSocket::writeData +248 (int (*)(...))QAbstractSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QAbstractSocket::connectToHost +272 (int (*)(...))QAbstractSocket::disconnectFromHost +280 (int (*)(...))QAbstractSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketDescriptor +304 (int (*)(...))QAbstractSocket::setSocketOption +312 (int (*)(...))QAbstractSocket::socketOption +320 (int (*)(...))QAbstractSocket::waitForConnected +328 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QAbstractSocket + size=16 align=8 + base size=16 base align=8 +QAbstractSocket (0x0x7f65bc2d3ea0) 0 + vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16) + QIODevice (0x0x7f65bc5ddee0) 0 + primary-for QAbstractSocket (0x0x7f65bc2d3ea0) + QObject (0x0x7f65bc2d4cc0) 0 + primary-for QIODevice (0x0x7f65bc5ddee0) + QIODeviceBase (0x0x7f65bc2d4d20) 0 empty + +Class QAuthenticator + size=8 align=8 + base size=8 base align=8 +QAuthenticator (0x0x7f65bc421060) 0 + +Class QDnsDomainNameRecord + size=8 align=8 + base size=8 base align=8 +QDnsDomainNameRecord (0x0x7f65bc421120) 0 + +Class QDnsHostAddressRecord + size=8 align=8 + base size=8 base align=8 +QDnsHostAddressRecord (0x0x7f65bc08b8a0) 0 + +Class QDnsMailExchangeRecord + size=8 align=8 + base size=8 base align=8 +QDnsMailExchangeRecord (0x0x7f65bc10d060) 0 + +Class QDnsServiceRecord + size=8 align=8 + base size=8 base align=8 +QDnsServiceRecord (0x0x7f65bc176720) 0 + +Class QDnsTextRecord + size=8 align=8 + base size=8 base align=8 +QDnsTextRecord (0x0x7f65bc1f70c0) 0 + +Class QDnsLookup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDnsLookup::QPrivateSignal (0x0x7f65bc25ab40) 0 empty + +Vtable for QDnsLookup +QDnsLookup::_ZTV10QDnsLookup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDnsLookup) +16 (int (*)(...))QDnsLookup::metaObject +24 (int (*)(...))QDnsLookup::qt_metacast +32 (int (*)(...))QDnsLookup::qt_metacall +40 (int (*)(...))QDnsLookup::~QDnsLookup +48 (int (*)(...))QDnsLookup::~QDnsLookup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDnsLookup + size=16 align=8 + base size=16 base align=8 +QDnsLookup (0x0x7f65bc257f08) 0 + vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16) + QObject (0x0x7f65bc25aae0) 0 + primary-for QDnsLookup (0x0x7f65bc257f08) + +Class QIPv6Address + size=16 align=1 + base size=16 base align=1 +QIPv6Address (0x0x7f65bc25ae40) 0 + +Class QHostAddress + size=8 align=8 + base size=8 base align=8 +QHostAddress (0x0x7f65bc25af60) 0 + +Class QTcpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpSocket::QPrivateSignal (0x0x7f65bbf0cea0) 0 empty + +Vtable for QTcpSocket +QTcpSocket::_ZTV10QTcpSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpSocket) +16 (int (*)(...))QTcpSocket::metaObject +24 (int (*)(...))QTcpSocket::qt_metacast +32 (int (*)(...))QTcpSocket::qt_metacall +40 (int (*)(...))QTcpSocket::~QTcpSocket +48 (int (*)(...))QTcpSocket::~QTcpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::skipData +240 (int (*)(...))QAbstractSocket::writeData +248 (int (*)(...))QAbstractSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QAbstractSocket::connectToHost +272 (int (*)(...))QAbstractSocket::disconnectFromHost +280 (int (*)(...))QAbstractSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketDescriptor +304 (int (*)(...))QAbstractSocket::setSocketOption +312 (int (*)(...))QAbstractSocket::socketOption +320 (int (*)(...))QAbstractSocket::waitForConnected +328 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QTcpSocket + size=16 align=8 + base size=16 base align=8 +QTcpSocket (0x0x7f65bbf1ac30) 0 + vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16) + QAbstractSocket (0x0x7f65bbf1ac98) 0 + primary-for QTcpSocket (0x0x7f65bbf1ac30) + QIODevice (0x0x7f65bc272bd0) 0 + primary-for QAbstractSocket (0x0x7f65bbf1ac98) + QObject (0x0x7f65bbf0cde0) 0 + primary-for QIODevice (0x0x7f65bc272bd0) + QIODeviceBase (0x0x7f65bbf0ce40) 0 empty + +Class QSslCertificate + size=8 align=8 + base size=8 base align=8 +QSslCertificate (0x0x7f65bbf36480) 0 + +Class QSslError + size=8 align=8 + base size=8 base align=8 +QSslError (0x0x7f65bbffc780) 0 + +Class QSslSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSslSocket::QPrivateSignal (0x0x7f65bbdfe660) 0 empty + +Vtable for QSslSocket +QSslSocket::_ZTV10QSslSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSslSocket) +16 (int (*)(...))QSslSocket::metaObject +24 (int (*)(...))QSslSocket::qt_metacast +32 (int (*)(...))QSslSocket::qt_metacall +40 (int (*)(...))QSslSocket::~QSslSocket +48 (int (*)(...))QSslSocket::~QSslSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QSslSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QSslSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QSslSocket::bytesAvailable +184 (int (*)(...))QSslSocket::bytesToWrite +192 (int (*)(...))QSslSocket::canReadLine +200 (int (*)(...))QSslSocket::waitForReadyRead +208 (int (*)(...))QSslSocket::waitForBytesWritten +216 (int (*)(...))QSslSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QSslSocket::skipData +240 (int (*)(...))QSslSocket::writeData +248 (int (*)(...))QSslSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QSslSocket::connectToHost +272 (int (*)(...))QSslSocket::disconnectFromHost +280 (int (*)(...))QSslSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QSslSocket::setSocketDescriptor +304 (int (*)(...))QSslSocket::setSocketOption +312 (int (*)(...))QSslSocket::socketOption +320 (int (*)(...))QSslSocket::waitForConnected +328 (int (*)(...))QSslSocket::waitForDisconnected + +Class QSslSocket + size=16 align=8 + base size=16 base align=8 +QSslSocket (0x0x7f65bbde9f08) 0 + vptr=((& QSslSocket::_ZTV10QSslSocket) + 16) + QTcpSocket (0x0x7f65bbde9f70) 0 + primary-for QSslSocket (0x0x7f65bbde9f08) + QAbstractSocket (0x0x7f65bbe1d000) 0 + primary-for QTcpSocket (0x0x7f65bbde9f70) + QIODevice (0x0x7f65bbd9fa80) 0 + primary-for QAbstractSocket (0x0x7f65bbe1d000) + QObject (0x0x7f65bbdfe5a0) 0 + primary-for QIODevice (0x0x7f65bbd9fa80) + QIODeviceBase (0x0x7f65bbdfe600) 0 empty + +Class QDtlsClientVerifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtlsClientVerifier::QPrivateSignal (0x0x7f65bbdfe840) 0 empty + +Class QDtlsClientVerifier::GeneratorParameters + size=32 align=8 + base size=32 base align=8 +QDtlsClientVerifier::GeneratorParameters (0x0x7f65bbdfe8a0) 0 + +Vtable for QDtlsClientVerifier +QDtlsClientVerifier::_ZTV19QDtlsClientVerifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QDtlsClientVerifier) +16 (int (*)(...))QDtlsClientVerifier::metaObject +24 (int (*)(...))QDtlsClientVerifier::qt_metacast +32 (int (*)(...))QDtlsClientVerifier::qt_metacall +40 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +48 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtlsClientVerifier + size=16 align=8 + base size=16 base align=8 +QDtlsClientVerifier (0x0x7f65bbe1d068) 0 + vptr=((& QDtlsClientVerifier::_ZTV19QDtlsClientVerifier) + 16) + QObject (0x0x7f65bbdfe7e0) 0 + primary-for QDtlsClientVerifier (0x0x7f65bbe1d068) + +Class QDtls::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtls::QPrivateSignal (0x0x7f65bbdfea80) 0 empty + +Vtable for QDtls +QDtls::_ZTV5QDtls: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDtls) +16 (int (*)(...))QDtls::metaObject +24 (int (*)(...))QDtls::qt_metacast +32 (int (*)(...))QDtls::qt_metacall +40 (int (*)(...))QDtls::~QDtls +48 (int (*)(...))QDtls::~QDtls +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtls + size=16 align=8 + base size=16 base align=8 +QDtls (0x0x7f65bbe1d0d0) 0 + vptr=((& QDtls::_ZTV5QDtls) + 16) + QObject (0x0x7f65bbdfea20) 0 + primary-for QDtls (0x0x7f65bbe1d0d0) + +Class QHostInfo + size=8 align=8 + base size=8 base align=8 +QHostInfo (0x0x7f65bbdfec00) 0 + +Class QHstsPolicy + size=8 align=8 + base size=8 base align=8 +QHstsPolicy (0x0x7f65bbaf0120) 0 + +Class QHttp2Configuration + size=8 align=8 + base size=8 base align=8 +QHttp2Configuration (0x0x7f65bbb5bc60) 0 + +Class QHttpPart + size=8 align=8 + base size=8 base align=8 +QHttpPart (0x0x7f65bbbed5a0) 0 + +Class QHttpMultiPart::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHttpMultiPart::QPrivateSignal (0x0x7f65bbc58d20) 0 empty + +Vtable for QHttpMultiPart +QHttpMultiPart::_ZTV14QHttpMultiPart: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QHttpMultiPart) +16 (int (*)(...))QHttpMultiPart::metaObject +24 (int (*)(...))QHttpMultiPart::qt_metacast +32 (int (*)(...))QHttpMultiPart::qt_metacall +40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QHttpMultiPart + size=16 align=8 + base size=16 base align=8 +QHttpMultiPart (0x0x7f65bbc6c068) 0 + vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16) + QObject (0x0x7f65bbc58cc0) 0 + primary-for QHttpMultiPart (0x0x7f65bbc6c068) + +Class QLocalServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalServer::QPrivateSignal (0x0x7f65bbc58f00) 0 empty + +Vtable for QLocalServer +QLocalServer::_ZTV12QLocalServer: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalServer) +16 (int (*)(...))QLocalServer::metaObject +24 (int (*)(...))QLocalServer::qt_metacast +32 (int (*)(...))QLocalServer::qt_metacall +40 (int (*)(...))QLocalServer::~QLocalServer +48 (int (*)(...))QLocalServer::~QLocalServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalServer::hasPendingConnections +120 (int (*)(...))QLocalServer::nextPendingConnection +128 (int (*)(...))QLocalServer::incomingConnection + +Class QLocalServer + size=16 align=8 + base size=16 base align=8 +QLocalServer (0x0x7f65bbc6c0d0) 0 + vptr=((& QLocalServer::_ZTV12QLocalServer) + 16) + QObject (0x0x7f65bbc58ea0) 0 + primary-for QLocalServer (0x0x7f65bbc6c0d0) + +Class QLocalSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalSocket::QPrivateSignal (0x0x7f65bb88b6c0) 0 empty + +Vtable for QLocalSocket +QLocalSocket::_ZTV12QLocalSocket: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalSocket) +16 (int (*)(...))QLocalSocket::metaObject +24 (int (*)(...))QLocalSocket::qt_metacast +32 (int (*)(...))QLocalSocket::qt_metacall +40 (int (*)(...))QLocalSocket::~QLocalSocket +48 (int (*)(...))QLocalSocket::~QLocalSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalSocket::isSequential +120 (int (*)(...))QLocalSocket::open +128 (int (*)(...))QLocalSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QLocalSocket::bytesAvailable +184 (int (*)(...))QLocalSocket::bytesToWrite +192 (int (*)(...))QLocalSocket::canReadLine +200 (int (*)(...))QLocalSocket::waitForReadyRead +208 (int (*)(...))QLocalSocket::waitForBytesWritten +216 (int (*)(...))QLocalSocket::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QLocalSocket::skipData +240 (int (*)(...))QLocalSocket::writeData + +Class QLocalSocket + size=16 align=8 + base size=16 base align=8 +QLocalSocket (0x0x7f65bbc6c270) 0 + vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16) + QIODevice (0x0x7f65bbbf6a10) 0 + primary-for QLocalSocket (0x0x7f65bbc6c270) + QObject (0x0x7f65bb88b600) 0 + primary-for QIODevice (0x0x7f65bbbf6a10) + QIODeviceBase (0x0x7f65bb88b660) 0 empty + +Class QSslConfiguration + size=8 align=8 + base size=8 base align=8 +QSslConfiguration (0x0x7f65bb88bcc0) 0 + +Class QSslPreSharedKeyAuthenticator + size=8 align=8 + base size=8 base align=8 +QSslPreSharedKeyAuthenticator (0x0x7f65bb9f2240) 0 + +Class QNetworkAccessManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkAccessManager::QPrivateSignal (0x0x7f65bb6ecb40) 0 empty + +Vtable for QNetworkAccessManager +QNetworkAccessManager::_ZTV21QNetworkAccessManager: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QNetworkAccessManager) +16 (int (*)(...))QNetworkAccessManager::metaObject +24 (int (*)(...))QNetworkAccessManager::qt_metacast +32 (int (*)(...))QNetworkAccessManager::qt_metacall +40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkAccessManager::supportedSchemes +120 (int (*)(...))QNetworkAccessManager::createRequest + +Class QNetworkAccessManager + size=16 align=8 + base size=16 base align=8 +QNetworkAccessManager (0x0x7f65bb703e38) 0 + vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16) + QObject (0x0x7f65bb6ecae0) 0 + primary-for QNetworkAccessManager (0x0x7f65bb703e38) + +Class QNetworkCookie + size=8 align=8 + base size=8 base align=8 +QNetworkCookie (0x0x7f65bb6eccc0) 0 + +Class QNetworkCookieJar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkCookieJar::QPrivateSignal (0x0x7f65bb794d80) 0 empty + +Vtable for QNetworkCookieJar +QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkCookieJar) +16 (int (*)(...))QNetworkCookieJar::metaObject +24 (int (*)(...))QNetworkCookieJar::qt_metacast +32 (int (*)(...))QNetworkCookieJar::qt_metacall +40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkCookieJar::cookiesForUrl +120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl +128 (int (*)(...))QNetworkCookieJar::insertCookie +136 (int (*)(...))QNetworkCookieJar::updateCookie +144 (int (*)(...))QNetworkCookieJar::deleteCookie +152 (int (*)(...))QNetworkCookieJar::validateCookie + +Class QNetworkCookieJar + size=16 align=8 + base size=16 base align=8 +QNetworkCookieJar (0x0x7f65bb792c98) 0 + vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16) + QObject (0x0x7f65bb794d20) 0 + primary-for QNetworkCookieJar (0x0x7f65bb792c98) + +Class QNetworkDatagram + size=8 align=8 + base size=8 base align=8 +QNetworkDatagram (0x0x7f65bb794f00) 0 + +Class QNetworkDiskCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkDiskCache::QPrivateSignal (0x0x7f65bb831720) 0 empty + +Vtable for QNetworkDiskCache +QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkDiskCache) +16 (int (*)(...))QNetworkDiskCache::metaObject +24 (int (*)(...))QNetworkDiskCache::qt_metacast +32 (int (*)(...))QNetworkDiskCache::qt_metacall +40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkDiskCache::metaData +120 (int (*)(...))QNetworkDiskCache::updateMetaData +128 (int (*)(...))QNetworkDiskCache::data +136 (int (*)(...))QNetworkDiskCache::remove +144 (int (*)(...))QNetworkDiskCache::cacheSize +152 (int (*)(...))QNetworkDiskCache::prepare +160 (int (*)(...))QNetworkDiskCache::insert +168 (int (*)(...))QNetworkDiskCache::clear +176 (int (*)(...))QNetworkDiskCache::expire + +Class QNetworkDiskCache + size=16 align=8 + base size=16 base align=8 +QNetworkDiskCache (0x0x7f65bb825c30) 0 + vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16) + QAbstractNetworkCache (0x0x7f65bb825c98) 0 + primary-for QNetworkDiskCache (0x0x7f65bb825c30) + QObject (0x0x7f65bb8316c0) 0 + primary-for QAbstractNetworkCache (0x0x7f65bb825c98) + +Class QNetworkInformation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkInformation::QPrivateSignal (0x0x7f65bb831900) 0 empty + +Vtable for QNetworkInformation +QNetworkInformation::_ZTV19QNetworkInformation: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNetworkInformation) +16 (int (*)(...))QNetworkInformation::metaObject +24 (int (*)(...))QNetworkInformation::qt_metacast +32 (int (*)(...))QNetworkInformation::qt_metacall +40 (int (*)(...))QNetworkInformation::~QNetworkInformation +48 (int (*)(...))QNetworkInformation::~QNetworkInformation +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QNetworkInformation + size=16 align=8 + base size=16 base align=8 +QNetworkInformation (0x0x7f65bb825d00) 0 + vptr=((& QNetworkInformation::_ZTV19QNetworkInformation) + 16) + QObject (0x0x7f65bb8318a0) 0 + primary-for QNetworkInformation (0x0x7f65bb825d00) + +Class QNetworkAddressEntry + size=8 align=8 + base size=8 base align=8 +QNetworkAddressEntry (0x0x7f65bb4ad000) 0 + +Class QNetworkInterface + size=8 align=8 + base size=8 base align=8 +QNetworkInterface (0x0x7f65bb282a80) 0 + +Class QNetworkProxyQuery + size=8 align=8 + base size=8 base align=8 +QNetworkProxyQuery (0x0x7f65bb3bc000) 0 + +Class QNetworkProxy + size=8 align=8 + base size=8 base align=8 +QNetworkProxy (0x0x7f65bb432780) 0 + +Vtable for QNetworkProxyFactory +QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QNetworkProxyFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNetworkProxyFactory + size=8 align=8 + base size=8 base align=8 +QNetworkProxyFactory (0x0x7f65bb0d1240) 0 nearly-empty + vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16) + +Class QNetworkReply::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkReply::QPrivateSignal (0x0x7f65bb0d1840) 0 empty + +Vtable for QNetworkReply +QNetworkReply::_ZTV13QNetworkReply: 37 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QNetworkReply) +16 (int (*)(...))QNetworkReply::metaObject +24 (int (*)(...))QNetworkReply::qt_metacast +32 (int (*)(...))QNetworkReply::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkReply::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QNetworkReply::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QNetworkReply::writeData +248 (int (*)(...))QNetworkReply::setReadBufferSize +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))QNetworkReply::ignoreSslErrors +272 (int (*)(...))QNetworkReply::sslConfigurationImplementation +280 (int (*)(...))QNetworkReply::setSslConfigurationImplementation +288 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation + +Class QNetworkReply + size=16 align=8 + base size=16 base align=8 +QNetworkReply (0x0x7f65bb0b7a90) 0 + vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16) + QIODevice (0x0x7f65bb08e930) 0 + primary-for QNetworkReply (0x0x7f65bb0b7a90) + QObject (0x0x7f65bb0d1780) 0 + primary-for QIODevice (0x0x7f65bb08e930) + QIODeviceBase (0x0x7f65bb0d17e0) 0 empty + +Class QOcspResponse + size=8 align=8 + base size=8 base align=8 +QOcspResponse (0x0x7f65bb16aba0) 0 + +Class QTcpServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpServer::QPrivateSignal (0x0x7f65bb1caa80) 0 empty + +Vtable for QTcpServer +QTcpServer::_ZTV10QTcpServer: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpServer) +16 (int (*)(...))QTcpServer::metaObject +24 (int (*)(...))QTcpServer::qt_metacast +32 (int (*)(...))QTcpServer::qt_metacall +40 (int (*)(...))QTcpServer::~QTcpServer +48 (int (*)(...))QTcpServer::~QTcpServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTcpServer::hasPendingConnections +120 (int (*)(...))QTcpServer::nextPendingConnection +128 (int (*)(...))QTcpServer::incomingConnection + +Class QTcpServer + size=16 align=8 + base size=16 base align=8 +QTcpServer (0x0x7f65bb1c1ea0) 0 + vptr=((& QTcpServer::_ZTV10QTcpServer) + 16) + QObject (0x0x7f65bb1caa20) 0 + primary-for QTcpServer (0x0x7f65bb1c1ea0) + +Class QSslCertificateExtension + size=8 align=8 + base size=8 base align=8 +QSslCertificateExtension (0x0x7f65bb1cac00) 0 + +Class QSslCipher + size=8 align=8 + base size=8 base align=8 +QSslCipher (0x0x7f65bb2733c0) 0 + +Class QSslDiffieHellmanParameters + size=8 align=8 + base size=8 base align=8 +QSslDiffieHellmanParameters (0x0x7f65bb04cd20) 0 + +Class QSslEllipticCurve + size=4 align=4 + base size=4 base align=4 +QSslEllipticCurve (0x0x7f65bacb2a80) 0 + +Class QSslKey + size=8 align=8 + base size=8 base align=8 +QSslKey (0x0x7f65bacf5cc0) 0 + +Class QUdpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUdpSocket::QPrivateSignal (0x0x7f65bad8d540) 0 empty + +Vtable for QUdpSocket +QUdpSocket::_ZTV10QUdpSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUdpSocket) +16 (int (*)(...))QUdpSocket::metaObject +24 (int (*)(...))QUdpSocket::qt_metacast +32 (int (*)(...))QUdpSocket::qt_metacall +40 (int (*)(...))QUdpSocket::~QUdpSocket +48 (int (*)(...))QUdpSocket::~QUdpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::skipData +240 (int (*)(...))QAbstractSocket::writeData +248 (int (*)(...))QAbstractSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QAbstractSocket::connectToHost +272 (int (*)(...))QAbstractSocket::disconnectFromHost +280 (int (*)(...))QAbstractSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketDescriptor +304 (int (*)(...))QAbstractSocket::setSocketOption +312 (int (*)(...))QAbstractSocket::socketOption +320 (int (*)(...))QAbstractSocket::waitForConnected +328 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QUdpSocket + size=16 align=8 + base size=16 base align=8 +QUdpSocket (0x0x7f65bad8b680) 0 + vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16) + QAbstractSocket (0x0x7f65bad8b6e8) 0 + primary-for QUdpSocket (0x0x7f65bad8b680) + QIODevice (0x0x7f65bacb3af0) 0 + primary-for QAbstractSocket (0x0x7f65bad8b6e8) + QObject (0x0x7f65bad8d480) 0 + primary-for QIODevice (0x0x7f65bacb3af0) + QIODeviceBase (0x0x7f65bad8d4e0) 0 empty + +Class QJSValue + size=8 align=8 + base size=8 base align=8 +QJSValue (0x0x7f65bad8d780) 0 + +Class QJSNumberCoercion + size=8 align=8 + base size=8 base align=8 +QJSNumberCoercion (0x0x7f65bae23cc0) 0 + +Class QJSPrimitiveUndefined + size=1 align=1 + base size=0 base align=1 +QJSPrimitiveUndefined (0x0x7f65bae522a0) 0 empty + +Class QJSPrimitiveNull + size=1 align=1 + base size=0 base align=1 +QJSPrimitiveNull (0x0x7f65bae52300) 0 empty + +Class QJSPrimitiveValue::AddOperators + size=1 align=1 + base size=0 base align=1 +QJSPrimitiveValue::AddOperators (0x0x7f65bae52420) 0 empty + +Class QJSPrimitiveValue::SubOperators + size=1 align=1 + base size=1 base align=1 +QJSPrimitiveValue::SubOperators (0x0x7f65bad8bf70) 0 empty + QJSPrimitiveValue::StringNaNOperators<QJSPrimitiveValue::SubOperators> (0x0x7f65bae524e0) 0 empty + +Class QJSPrimitiveValue::MulOperators + size=1 align=1 + base size=1 base align=1 +QJSPrimitiveValue::MulOperators (0x0x7f65bad8bea0) 0 empty + QJSPrimitiveValue::StringNaNOperators<QJSPrimitiveValue::MulOperators> (0x0x7f65bae525a0) 0 empty + +Class QJSPrimitiveValue::DivOperators + size=1 align=1 + base size=1 base align=1 +QJSPrimitiveValue::DivOperators (0x0x7f65bae6b000) 0 empty + QJSPrimitiveValue::StringNaNOperators<QJSPrimitiveValue::DivOperators> (0x0x7f65bae52660) 0 empty + +Class QJSPrimitiveValue::QJSPrimitiveValuePrivate + size=32 align=8 + base size=25 base align=8 +QJSPrimitiveValue::QJSPrimitiveValuePrivate (0x0x7f65bae526c0) 0 + +Class QJSPrimitiveValue + size=32 align=8 + base size=32 base align=8 +QJSPrimitiveValue (0x0x7f65bae52360) 0 + +Class QJSManagedValue + size=8 align=8 + base size=8 base align=8 +QJSManagedValue (0x0x7f65bab87900) 0 + +Class QQmlDebuggingEnabler + size=1 align=1 + base size=0 base align=1 +QQmlDebuggingEnabler (0x0x7f65bab87c00) 0 empty + +Class QJSEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QJSEngine::QPrivateSignal (0x0x7f65bab87ea0) 0 empty + +Vtable for QJSEngine +QJSEngine::_ZTV9QJSEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QJSEngine) +16 (int (*)(...))QJSEngine::metaObject +24 (int (*)(...))QJSEngine::qt_metacast +32 (int (*)(...))QJSEngine::qt_metacall +40 (int (*)(...))QJSEngine::~QJSEngine +48 (int (*)(...))QJSEngine::~QJSEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QJSEngine + size=24 align=8 + base size=24 base align=8 +QJSEngine (0x0x7f65bab1add0) 0 + vptr=((& QJSEngine::_ZTV9QJSEngine) + 16) + QObject (0x0x7f65bab87e40) 0 + primary-for QJSEngine (0x0x7f65bab1add0) + +Class QJSValueIterator + size=8 align=8 + base size=8 base align=8 +QJSValueIterator (0x0x7f65babe1840) 0 + +Vtable for QQmlParserStatus +QQmlParserStatus::_ZTV16QQmlParserStatus: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlParserStatus) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlParserStatus + size=16 align=8 + base size=16 base align=8 +QQmlParserStatus (0x0x7f65babe1a20) 0 + vptr=((& QQmlParserStatus::_ZTV16QQmlParserStatus) + 16) + +Class QQmlListReference + size=8 align=8 + base size=8 base align=8 +QQmlListReference (0x0x7f65bac4f540) 0 + +Vtable for QQmlPropertyValueSource +QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQmlPropertyValueSource) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlPropertyValueSource + size=8 align=8 + base size=8 base align=8 +QQmlPropertyValueSource (0x0x7f65bac4fb40) 0 nearly-empty + vptr=((& QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource) + 16) + +Class QQmlPrivate::RegisterType + size=176 align=8 + base size=170 base align=8 +QQmlPrivate::RegisterType (0x0x7f65ba8b6360) 0 + +Class QQmlPrivate::RegisterTypeAndRevisions + size=152 align=8 + base size=152 base align=8 +QQmlPrivate::RegisterTypeAndRevisions (0x0x7f65ba8b63c0) 0 + +Class QQmlPrivate::RegisterInterface + size=48 align=8 + base size=42 base align=8 +QQmlPrivate::RegisterInterface (0x0x7f65ba8b6420) 0 + +Class QQmlPrivate::RegisterAutoParent + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterAutoParent (0x0x7f65ba8b6480) 0 + +Class QQmlPrivate::RegisterSingletonType + size=136 align=8 + base size=130 base align=8 +QQmlPrivate::RegisterSingletonType (0x0x7f65ba8b64e0) 0 + +Class QQmlPrivate::RegisterSingletonTypeAndRevisions + size=104 align=8 + base size=104 base align=8 +QQmlPrivate::RegisterSingletonTypeAndRevisions (0x0x7f65ba8b6840) 0 + +Class QQmlPrivate::RegisterCompositeType + size=40 align=8 + base size=40 base align=8 +QQmlPrivate::RegisterCompositeType (0x0x7f65ba8b6900) 0 + +Class QQmlPrivate::RegisterCompositeSingletonType + size=40 align=8 + base size=40 base align=8 +QQmlPrivate::RegisterCompositeSingletonType (0x0x7f65ba8b6960) 0 + +Class QQmlPrivate::RegisterSequentialContainer + size=56 align=8 + base size=50 base align=8 +QQmlPrivate::RegisterSequentialContainer (0x0x7f65ba8b69c0) 0 + +Class QQmlPrivate::RegisterSequentialContainerAndRevisions + size=56 align=8 + base size=56 base align=8 +QQmlPrivate::RegisterSequentialContainerAndRevisions (0x0x7f65ba8b6a20) 0 + +Class QQmlPrivate::AOTCompiledContext + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::AOTCompiledContext (0x0x7f65ba8b6a80) 0 + +Class QQmlPrivate::AOTCompiledFunction + size=48 align=8 + base size=48 base align=8 +QQmlPrivate::AOTCompiledFunction (0x0x7f65ba8b6ae0) 0 + +Class QQmlPrivate::CachedQmlUnit + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::CachedQmlUnit (0x0x7f65ba90d4e0) 0 + +Class QQmlPrivate::RegisterQmlUnitCacheHook + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterQmlUnitCacheHook (0x0x7f65ba90d540) 0 + +Class QQmlPrivate::SingletonFunctor + size=24 align=8 + base size=17 base align=8 +QQmlPrivate::SingletonFunctor (0x0x7f65ba90d5a0) 0 + +Vtable for QQmlAbstractUrlInterceptor +QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QQmlAbstractUrlInterceptor) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlAbstractUrlInterceptor + size=8 align=8 + base size=8 base align=8 +QQmlAbstractUrlInterceptor (0x0x7f65ba6daf00) 0 nearly-empty + vptr=((& QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor) + 16) + +Class QQmlError + size=8 align=8 + base size=8 base align=8 +QQmlError (0x0x7f65ba6daf60) 0 + +Class QQmlImageProviderBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlImageProviderBase::QPrivateSignal (0x0x7f65ba73c7e0) 0 empty + +Vtable for QQmlImageProviderBase +QQmlImageProviderBase::_ZTV21QQmlImageProviderBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlImageProviderBase) +16 (int (*)(...))QQmlImageProviderBase::metaObject +24 (int (*)(...))QQmlImageProviderBase::qt_metacast +32 (int (*)(...))QQmlImageProviderBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QQmlImageProviderBase + size=16 align=8 + base size=16 base align=8 +QQmlImageProviderBase (0x0x7f65ba7432d8) 0 + vptr=((& QQmlImageProviderBase::_ZTV21QQmlImageProviderBase) + 16) + QObject (0x0x7f65ba73c780) 0 + primary-for QQmlImageProviderBase (0x0x7f65ba7432d8) + +Class QQmlEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngine::QPrivateSignal (0x0x7f65ba73ccc0) 0 empty + +Vtable for QQmlEngine +QQmlEngine::_ZTV10QQmlEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQmlEngine) +16 (int (*)(...))QQmlEngine::metaObject +24 (int (*)(...))QQmlEngine::qt_metacast +32 (int (*)(...))QQmlEngine::qt_metacall +40 (int (*)(...))QQmlEngine::~QQmlEngine +48 (int (*)(...))QQmlEngine::~QQmlEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlEngine + size=24 align=8 + base size=24 base align=8 +QQmlEngine (0x0x7f65ba743478) 0 + vptr=((& QQmlEngine::_ZTV10QQmlEngine) + 16) + QJSEngine (0x0x7f65ba7434e0) 0 + primary-for QQmlEngine (0x0x7f65ba743478) + QObject (0x0x7f65ba73cc60) 0 + primary-for QJSEngine (0x0x7f65ba7434e0) + +Class QQmlApplicationEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlApplicationEngine::QPrivateSignal (0x0x7f65ba7ae000) 0 empty + +Vtable for QQmlApplicationEngine +QQmlApplicationEngine::_ZTV21QQmlApplicationEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlApplicationEngine) +16 (int (*)(...))QQmlApplicationEngine::metaObject +24 (int (*)(...))QQmlApplicationEngine::qt_metacast +32 (int (*)(...))QQmlApplicationEngine::qt_metacall +40 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +48 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlApplicationEngine + size=24 align=8 + base size=24 base align=8 +QQmlApplicationEngine (0x0x7f65ba743548) 0 + vptr=((& QQmlApplicationEngine::_ZTV21QQmlApplicationEngine) + 16) + QQmlEngine (0x0x7f65ba7435b0) 0 + primary-for QQmlApplicationEngine (0x0x7f65ba743548) + QJSEngine (0x0x7f65ba743618) 0 + primary-for QQmlEngine (0x0x7f65ba7435b0) + QObject (0x0x7f65ba73cf60) 0 + primary-for QJSEngine (0x0x7f65ba743618) + +Class QQmlComponent::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlComponent::QPrivateSignal (0x0x7f65ba7ae1e0) 0 empty + +Vtable for QQmlComponent +QQmlComponent::_ZTV13QQmlComponent: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlComponent) +16 (int (*)(...))QQmlComponent::metaObject +24 (int (*)(...))QQmlComponent::qt_metacast +32 (int (*)(...))QQmlComponent::qt_metacall +40 (int (*)(...))QQmlComponent::~QQmlComponent +48 (int (*)(...))QQmlComponent::~QQmlComponent +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlComponent::create +120 (int (*)(...))QQmlComponent::beginCreate +128 (int (*)(...))QQmlComponent::completeCreate + +Class QQmlComponent + size=16 align=8 + base size=16 base align=8 +QQmlComponent (0x0x7f65ba743680) 0 + vptr=((& QQmlComponent::_ZTV13QQmlComponent) + 16) + QObject (0x0x7f65ba7ae180) 0 + primary-for QQmlComponent (0x0x7f65ba743680) + +Class QQmlContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlContext::QPrivateSignal (0x0x7f65ba7aef60) 0 empty + +Class QQmlContext::PropertyPair + size=56 align=8 + base size=56 base align=8 +QQmlContext::PropertyPair (0x0x7f65ba81f000) 0 + +Vtable for QQmlContext +QQmlContext::_ZTV11QQmlContext: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QQmlContext) +16 (int (*)(...))QQmlContext::metaObject +24 (int (*)(...))QQmlContext::qt_metacast +32 (int (*)(...))QQmlContext::qt_metacall +40 (int (*)(...))QQmlContext::~QQmlContext +48 (int (*)(...))QQmlContext::~QQmlContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlContext + size=16 align=8 + base size=16 base align=8 +QQmlContext (0x0x7f65ba7437b8) 0 + vptr=((& QQmlContext::_ZTV11QQmlContext) + 16) + QObject (0x0x7f65ba7aef00) 0 + primary-for QQmlContext (0x0x7f65ba7437b8) + +Class QQmlScriptString + size=8 align=8 + base size=8 base align=8 +QQmlScriptString (0x0x7f65ba81f660) 0 + +Class QQmlExpression::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExpression::QPrivateSignal (0x0x7f65ba81fc60) 0 empty + +Vtable for QQmlExpression +QQmlExpression::_ZTV14QQmlExpression: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QQmlExpression) +16 (int (*)(...))QQmlExpression::metaObject +24 (int (*)(...))QQmlExpression::qt_metacast +32 (int (*)(...))QQmlExpression::qt_metacall +40 (int (*)(...))QQmlExpression::~QQmlExpression +48 (int (*)(...))QQmlExpression::~QQmlExpression +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlExpression + size=16 align=8 + base size=16 base align=8 +QQmlExpression (0x0x7f65ba7438f0) 0 + vptr=((& QQmlExpression::_ZTV14QQmlExpression) + 16) + QObject (0x0x7f65ba81fc00) 0 + primary-for QQmlExpression (0x0x7f65ba7438f0) + +Vtable for QQmlTypesExtensionInterface +QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QQmlTypesExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlTypesExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlTypesExtensionInterface (0x0x7f65ba81fde0) 0 nearly-empty + vptr=((& QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface) + 16) + +Vtable for QQmlExtensionInterface +QQmlExtensionInterface::_ZTV22QQmlExtensionInterface: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QQmlExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlExtensionInterface (0x0x7f65ba743958) 0 nearly-empty + vptr=((& QQmlExtensionInterface::_ZTV22QQmlExtensionInterface) + 16) + QQmlTypesExtensionInterface (0x0x7f65ba81fe40) 0 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f65ba743958) + +Vtable for QQmlEngineExtensionInterface +QQmlEngineExtensionInterface::_ZTV28QQmlEngineExtensionInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QQmlEngineExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlEngineExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlEngineExtensionInterface (0x0x7f65ba81fea0) 0 nearly-empty + vptr=((& QQmlEngineExtensionInterface::_ZTV28QQmlEngineExtensionInterface) + 16) + +Class QQmlExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExtensionPlugin::QPrivateSignal (0x0x7f65ba49b480) 0 empty + +Vtable for QQmlExtensionPlugin +QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +16 (int (*)(...))QQmlExtensionPlugin::metaObject +24 (int (*)(...))QQmlExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlExtensionPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQmlExtensionPlugin::unregisterTypes +128 (int (*)(...))QQmlExtensionPlugin::initializeEngine +136 (int (*)(...))-16 +144 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +152 0 +160 0 +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))QQmlExtensionPlugin::_ZThn16_N19QQmlExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlExtensionPlugin (0x0x7f65ba74abd0) 0 + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 16) + QObject (0x0x7f65ba49b3c0) 0 + primary-for QQmlExtensionPlugin (0x0x7f65ba74abd0) + QQmlExtensionInterface (0x0x7f65ba7439c0) 16 nearly-empty + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 152) + QQmlTypesExtensionInterface (0x0x7f65ba49b420) 16 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f65ba7439c0) + +Class QQmlEngineExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngineExtensionPlugin::QPrivateSignal (0x0x7f65ba49b6c0) 0 empty + +Vtable for QQmlEngineExtensionPlugin +QQmlEngineExtensionPlugin::_ZTV25QQmlEngineExtensionPlugin: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QQmlEngineExtensionPlugin) +16 (int (*)(...))QQmlEngineExtensionPlugin::metaObject +24 (int (*)(...))QQmlEngineExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlEngineExtensionPlugin::qt_metacall +40 (int (*)(...))QQmlEngineExtensionPlugin::~QQmlEngineExtensionPlugin +48 (int (*)(...))QQmlEngineExtensionPlugin::~QQmlEngineExtensionPlugin +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlEngineExtensionPlugin::initializeEngine +120 (int (*)(...))-16 +128 (int (*)(...))(& _ZTI25QQmlEngineExtensionPlugin) +136 (int (*)(...))QQmlEngineExtensionPlugin::_ZThn16_N25QQmlEngineExtensionPluginD1Ev +144 (int (*)(...))QQmlEngineExtensionPlugin::_ZThn16_N25QQmlEngineExtensionPluginD0Ev +152 (int (*)(...))QQmlEngineExtensionPlugin::_ZThn16_N25QQmlEngineExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlEngineExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlEngineExtensionPlugin (0x0x7f65ba74ac40) 0 + vptr=((& QQmlEngineExtensionPlugin::_ZTV25QQmlEngineExtensionPlugin) + 16) + QObject (0x0x7f65ba49b600) 0 + primary-for QQmlEngineExtensionPlugin (0x0x7f65ba74ac40) + QQmlEngineExtensionInterface (0x0x7f65ba49b660) 16 nearly-empty + vptr=((& QQmlEngineExtensionPlugin::_ZTV25QQmlEngineExtensionPlugin) + 136) + +Class QQmlFile + size=8 align=8 + base size=8 base align=8 +QQmlFile (0x0x7f65ba49b780) 0 + +Class QQmlFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlFileSelector::QPrivateSignal (0x0x7f65ba49b840) 0 empty + +Vtable for QQmlFileSelector +QQmlFileSelector::_ZTV16QQmlFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlFileSelector) +16 (int (*)(...))QQmlFileSelector::metaObject +24 (int (*)(...))QQmlFileSelector::qt_metacast +32 (int (*)(...))QQmlFileSelector::qt_metacall +40 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +48 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlFileSelector + size=16 align=8 + base size=16 base align=8 +QQmlFileSelector (0x0x7f65ba743a90) 0 + vptr=((& QQmlFileSelector::_ZTV16QQmlFileSelector) + 16) + QObject (0x0x7f65ba49b7e0) 0 + primary-for QQmlFileSelector (0x0x7f65ba743a90) + +Vtable for QQmlIncubator +QQmlIncubator::_ZTV13QQmlIncubator: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlIncubator) +16 (int (*)(...))QQmlIncubator::~QQmlIncubator +24 (int (*)(...))QQmlIncubator::~QQmlIncubator +32 (int (*)(...))QQmlIncubator::statusChanged +40 (int (*)(...))QQmlIncubator::setInitialState + +Class QQmlIncubator + size=16 align=8 + base size=16 base align=8 +QQmlIncubator (0x0x7f65ba49b9c0) 0 + vptr=((& QQmlIncubator::_ZTV13QQmlIncubator) + 16) + +Vtable for QQmlIncubationController +QQmlIncubationController::_ZTV24QQmlIncubationController: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQmlIncubationController) +16 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +24 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +32 (int (*)(...))QQmlIncubationController::incubatingObjectCountChanged + +Class QQmlIncubationController + size=16 align=8 + base size=16 base align=8 +QQmlIncubationController (0x0x7f65ba49ba20) 0 + vptr=((& QQmlIncubationController::_ZTV24QQmlIncubationController) + 16) + +Class QQmlInfo + size=16 align=8 + base size=16 base align=8 +QQmlInfo (0x0x7f65ba743af8) 0 + QDebug (0x0x7f65ba743b60) 0 + QIODeviceBase (0x0x7f65ba49ba80) 0 empty + +Class QQmlModuleRegistration + size=8 align=8 + base size=8 base align=8 +QQmlModuleRegistration (0x0x7f65ba5871e0) 0 + +Vtable for QQmlNetworkAccessManagerFactory +QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI31QQmlNetworkAccessManagerFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlNetworkAccessManagerFactory + size=8 align=8 + base size=8 base align=8 +QQmlNetworkAccessManagerFactory (0x0x7f65ba587240) 0 nearly-empty + vptr=((& QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory) + 16) + +Class QQmlProperty + size=8 align=8 + base size=8 base align=8 +QQmlProperty (0x0x7f65ba5872a0) 0 + +Class QQmlPropertyMap::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlPropertyMap::QPrivateSignal (0x0x7f65ba5e54e0) 0 empty + +Vtable for QQmlPropertyMap +QQmlPropertyMap::_ZTV15QQmlPropertyMap: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQmlPropertyMap) +16 (int (*)(...))QQmlPropertyMap::metaObject +24 (int (*)(...))QQmlPropertyMap::qt_metacast +32 (int (*)(...))QQmlPropertyMap::qt_metacall +40 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +48 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlPropertyMap::updateValue + +Class QQmlPropertyMap + size=16 align=8 + base size=16 base align=8 +QQmlPropertyMap (0x0x7f65ba5ee0d0) 0 + vptr=((& QQmlPropertyMap::_ZTV15QQmlPropertyMap) + 16) + QObject (0x0x7f65ba5e5480) 0 + primary-for QQmlPropertyMap (0x0x7f65ba5ee0d0) + +Class QOpenGLBuffer + size=8 align=8 + base size=8 base align=8 +QOpenGLBuffer (0x0x7f65ba5e56c0) 0 + +Class QOpenGLDebugMessage + size=8 align=8 + base size=8 base align=8 +QOpenGLDebugMessage (0x0x7f65ba5e5c00) 0 + +Class QOpenGLDebugLogger::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLDebugLogger::QPrivateSignal (0x0x7f65ba2d3f60) 0 empty + +Vtable for QOpenGLDebugLogger +QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger) +16 (int (*)(...))QOpenGLDebugLogger::metaObject +24 (int (*)(...))QOpenGLDebugLogger::qt_metacast +32 (int (*)(...))QOpenGLDebugLogger::qt_metacall +40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLDebugLogger + size=16 align=8 + base size=16 base align=8 +QOpenGLDebugLogger (0x0x7f65ba2d8680) 0 + vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16) + QObject (0x0x7f65ba2d3f00) 0 + primary-for QOpenGLDebugLogger (0x0x7f65ba2d8680) + +Vtable for QOpenGLFramebufferObject +QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject) +16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject +24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject + +Class QOpenGLFramebufferObject + size=16 align=8 + base size=16 base align=8 +QOpenGLFramebufferObject (0x0x7f65ba3b66c0) 0 + vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16) + +Class QOpenGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QOpenGLFramebufferObjectFormat (0x0x7f65ba3b6960) 0 + +Vtable for QOpenGLPaintDevice +QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice) +16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +32 (int (*)(...))QOpenGLPaintDevice::devType +40 (int (*)(...))QOpenGLPaintDevice::paintEngine +48 (int (*)(...))QOpenGLPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget + +Class QOpenGLPaintDevice + size=24 align=8 + base size=24 base align=8 +QOpenGLPaintDevice (0x0x7f65ba2d8750) 0 + vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16) + QPaintDevice (0x0x7f65ba3b69c0) 0 + primary-for QOpenGLPaintDevice (0x0x7f65ba2d8750) + +Class QOpenGLPixelTransferOptions + size=8 align=8 + base size=8 base align=8 +QOpenGLPixelTransferOptions (0x0x7f65ba3b6c00) 0 + +Class QOpenGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShader::QPrivateSignal (0x0x7f65ba45c300) 0 empty + +Vtable for QOpenGLShader +QOpenGLShader::_ZTV13QOpenGLShader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLShader) +16 (int (*)(...))QOpenGLShader::metaObject +24 (int (*)(...))QOpenGLShader::qt_metacast +32 (int (*)(...))QOpenGLShader::qt_metacall +40 (int (*)(...))QOpenGLShader::~QOpenGLShader +48 (int (*)(...))QOpenGLShader::~QOpenGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLShader + size=16 align=8 + base size=16 base align=8 +QOpenGLShader (0x0x7f65ba462138) 0 + vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16) + QObject (0x0x7f65ba45c2a0) 0 + primary-for QOpenGLShader (0x0x7f65ba462138) + +Class QOpenGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShaderProgram::QPrivateSignal (0x0x7f65ba45c8a0) 0 empty + +Vtable for QOpenGLShaderProgram +QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram) +16 (int (*)(...))QOpenGLShaderProgram::metaObject +24 (int (*)(...))QOpenGLShaderProgram::qt_metacast +32 (int (*)(...))QOpenGLShaderProgram::qt_metacall +40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOpenGLShaderProgram::link + +Class QOpenGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QOpenGLShaderProgram (0x0x7f65ba4622d8) 0 + vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16) + QObject (0x0x7f65ba45c840) 0 + primary-for QOpenGLShaderProgram (0x0x7f65ba4622d8) + +Class QOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QOpenGLTexture (0x0x7f65ba45ca20) 0 + +Class QOpenGLTextureBlitter + size=8 align=8 + base size=8 base align=8 +QOpenGLTextureBlitter (0x0x7f65ba167c00) 0 + +Class QOpenGLTimerQuery::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimerQuery::QPrivateSignal (0x0x7f65ba167e40) 0 empty + +Vtable for QOpenGLTimerQuery +QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery) +16 (int (*)(...))QOpenGLTimerQuery::metaObject +24 (int (*)(...))QOpenGLTimerQuery::qt_metacast +32 (int (*)(...))QOpenGLTimerQuery::qt_metacall +40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimerQuery + size=16 align=8 + base size=16 base align=8 +QOpenGLTimerQuery (0x0x7f65ba462478) 0 + vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16) + QObject (0x0x7f65ba167de0) 0 + primary-for QOpenGLTimerQuery (0x0x7f65ba462478) + +Class QOpenGLTimeMonitor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimeMonitor::QPrivateSignal (0x0x7f65ba1dc060) 0 empty + +Vtable for QOpenGLTimeMonitor +QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor) +16 (int (*)(...))QOpenGLTimeMonitor::metaObject +24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast +32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall +40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimeMonitor + size=16 align=8 + base size=16 base align=8 +QOpenGLTimeMonitor (0x0x7f65ba4624e0) 0 + vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16) + QObject (0x0x7f65ba1dc000) 0 + primary-for QOpenGLTimeMonitor (0x0x7f65ba4624e0) + +Class QOpenGLVersionStatus + size=12 align=4 + base size=12 base align=4 +QOpenGLVersionStatus (0x0x7f65ba1dc1e0) 0 + +Class QOpenGLVersionFunctionsBackend + size=16 align=8 + base size=12 base align=8 +QOpenGLVersionFunctionsBackend (0x0x7f65b9ebf240) 0 + +Class QOpenGLVersionFunctionsStorage + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionFunctionsStorage (0x0x7f65b9ebf420) 0 + +Class QAbstractOpenGLFunctionsPrivate + size=16 align=8 + base size=9 base align=8 +QAbstractOpenGLFunctionsPrivate (0x0x7f65b9ebf480) 0 + +Vtable for QAbstractOpenGLFunctions +QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions) +16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions + +Class QAbstractOpenGLFunctions + size=16 align=8 + base size=16 base align=8 +QAbstractOpenGLFunctions (0x0x7f65b9ebf660) 0 + vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16) + +Class QOpenGLFunctions_1_0_CoreBackend::Functions + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7f65b9ebf840) 0 + +Class QOpenGLFunctions_1_0_CoreBackend + size=400 align=8 + base size=400 base align=8 +QOpenGLFunctions_1_0_CoreBackend (0x0x7f65b9e8dd68) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9ebf7e0) 0 + +Class QOpenGLFunctions_1_1_CoreBackend::Functions + size=128 align=8 + base size=128 base align=8 +QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7f65b9ebfba0) 0 + +Class QOpenGLFunctions_1_1_CoreBackend + size=144 align=8 + base size=144 base align=8 +QOpenGLFunctions_1_1_CoreBackend (0x0x7f65b9e8ddd0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9ebfb40) 0 + +Class QOpenGLFunctions_1_2_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7f65b9ebff00) 0 + +Class QOpenGLFunctions_1_2_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_1_2_CoreBackend (0x0x7f65b9e8de38) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9ebfea0) 0 + +Class QOpenGLFunctions_1_3_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7f65b9efc2a0) 0 + +Class QOpenGLFunctions_1_3_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_1_3_CoreBackend (0x0x7f65b9e8dea0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9efc240) 0 + +Class QOpenGLFunctions_1_4_CoreBackend::Functions + size=56 align=8 + base size=56 base align=8 +QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7f65b9efc600) 0 + +Class QOpenGLFunctions_1_4_CoreBackend + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_4_CoreBackend (0x0x7f65b9e8df08) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9efc5a0) 0 + +Class QOpenGLFunctions_1_5_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7f65b9efc960) 0 + +Class QOpenGLFunctions_1_5_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_1_5_CoreBackend (0x0x7f65b9e8df70) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9efc900) 0 + +Class QOpenGLFunctions_2_0_CoreBackend::Functions + size=744 align=8 + base size=744 base align=8 +QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7f65b9efccc0) 0 + +Class QOpenGLFunctions_2_0_CoreBackend + size=760 align=8 + base size=760 base align=8 +QOpenGLFunctions_2_0_CoreBackend (0x0x7f65b9f19000) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9efcc60) 0 + +Class QOpenGLFunctions_2_1_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7f65b9f36060) 0 + +Class QOpenGLFunctions_2_1_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_2_1_CoreBackend (0x0x7f65b9f19068) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9f36000) 0 + +Class QOpenGLFunctions_3_0_CoreBackend::Functions + size=672 align=8 + base size=672 base align=8 +QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7f65b9f363c0) 0 + +Class QOpenGLFunctions_3_0_CoreBackend + size=688 align=8 + base size=688 base align=8 +QOpenGLFunctions_3_0_CoreBackend (0x0x7f65b9f190d0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9f36360) 0 + +Class QOpenGLFunctions_3_1_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7f65b9f36720) 0 + +Class QOpenGLFunctions_3_1_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_3_1_CoreBackend (0x0x7f65b9f19138) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9f366c0) 0 + +Class QOpenGLFunctions_3_2_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7f65b9f36a80) 0 + +Class QOpenGLFunctions_3_2_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_3_2_CoreBackend (0x0x7f65b9f191a0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9f36a20) 0 + +Class QOpenGLFunctions_3_3_CoreBackend::Functions + size=464 align=8 + base size=464 base align=8 +QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7f65b9f36de0) 0 + +Class QOpenGLFunctions_3_3_CoreBackend + size=480 align=8 + base size=480 base align=8 +QOpenGLFunctions_3_3_CoreBackend (0x0x7f65b9f19208) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9f36d80) 0 + +Class QOpenGLFunctions_4_0_CoreBackend::Functions + size=368 align=8 + base size=368 base align=8 +QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7f65b9f7c180) 0 + +Class QOpenGLFunctions_4_0_CoreBackend + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_4_0_CoreBackend (0x0x7f65b9f19270) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9f7c120) 0 + +Class QOpenGLFunctions_4_1_CoreBackend::Functions + size=704 align=8 + base size=704 base align=8 +QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7f65b9f7c4e0) 0 + +Class QOpenGLFunctions_4_1_CoreBackend + size=720 align=8 + base size=720 base align=8 +QOpenGLFunctions_4_1_CoreBackend (0x0x7f65b9f192d8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9f7c480) 0 + +Class QOpenGLFunctions_4_2_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7f65b9f7c840) 0 + +Class QOpenGLFunctions_4_2_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_2_CoreBackend (0x0x7f65b9f19340) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9f7c7e0) 0 + +Class QOpenGLFunctions_4_3_CoreBackend::Functions + size=344 align=8 + base size=344 base align=8 +QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7f65b9f7cba0) 0 + +Class QOpenGLFunctions_4_3_CoreBackend + size=360 align=8 + base size=360 base align=8 +QOpenGLFunctions_4_3_CoreBackend (0x0x7f65b9f193a8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9f7cb40) 0 + +Class QOpenGLFunctions_4_4_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7f65b9f7cf00) 0 + +Class QOpenGLFunctions_4_4_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_4_4_CoreBackend (0x0x7f65b9f19410) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9f7cea0) 0 + +Class QOpenGLFunctions_4_5_CoreBackend::Functions + size=848 align=8 + base size=848 base align=8 +QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7f65b9fd12a0) 0 + +Class QOpenGLFunctions_4_5_CoreBackend + size=864 align=8 + base size=864 base align=8 +QOpenGLFunctions_4_5_CoreBackend (0x0x7f65b9f19478) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9fd1240) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions + size=2064 align=8 + base size=2064 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7f65b9fd1600) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend + size=2080 align=8 + base size=2080 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7f65b9f194e0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9fd15a0) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions + size=136 align=8 + base size=136 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7f65b9fd1960) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7f65b9f19548) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9fd1900) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7f65b9fd1cc0) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend + size=272 align=8 + base size=272 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7f65b9f195b0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9fd1c60) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions + size=296 align=8 + base size=296 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7f65ba052060) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend + size=312 align=8 + base size=312 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7f65b9f19618) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65ba052000) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7f65ba0523c0) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend + size=320 align=8 + base size=320 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7f65b9f19680) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65ba052360) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions + size=288 align=8 + base size=288 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7f65ba052720) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7f65b9f196e8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65ba0526c0) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions + size=160 align=8 + base size=160 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7f65ba052a80) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend + size=176 align=8 + base size=176 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7f65b9f19750) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65ba052a20) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions + size=240 align=8 + base size=240 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7f65ba052de0) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7f65b9f197b8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65ba052d80) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7f65b9c91180) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7f65b9f19820) 0 + QOpenGLVersionFunctionsBackend (0x0x7f65b9c91120) 0 + +Class QOpenGLVersionProfile + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionProfile (0x0x7f65b9c91480) 0 + +Class QOpenGLVersionFunctionsFactory + size=1 align=1 + base size=0 base align=1 +QOpenGLVersionFunctionsFactory (0x0x7f65b9c91600) 0 empty + +Class QOpenGLVertexArrayObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLVertexArrayObject::QPrivateSignal (0x0x7f65b9c91720) 0 empty + +Class QOpenGLVertexArrayObject::Binder + size=8 align=8 + base size=8 base align=8 +QOpenGLVertexArrayObject::Binder (0x0x7f65b9c91780) 0 + +Vtable for QOpenGLVertexArrayObject +QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject) +16 (int (*)(...))QOpenGLVertexArrayObject::metaObject +24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast +32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall +40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLVertexArrayObject + size=16 align=8 + base size=16 base align=8 +QOpenGLVertexArrayObject (0x0x7f65b9f19888) 0 + vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16) + QObject (0x0x7f65b9c916c0) 0 + primary-for QOpenGLVertexArrayObject (0x0x7f65b9f19888) + +Class QOpenGLWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWindow::QPrivateSignal (0x0x7f65b9c91de0) 0 empty + +Vtable for QOpenGLWindow +QOpenGLWindow::_ZTV13QOpenGLWindow: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWindow) +16 (int (*)(...))QOpenGLWindow::metaObject +24 (int (*)(...))QOpenGLWindow::qt_metacast +32 (int (*)(...))QOpenGLWindow::qt_metacall +40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QOpenGLWindow::resizeEvent +168 (int (*)(...))QOpenGLWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QWindow::focusInEvent +192 (int (*)(...))QWindow::focusOutEvent +200 (int (*)(...))QWindow::showEvent +208 (int (*)(...))QWindow::hideEvent +216 (int (*)(...))QWindow::closeEvent +224 (int (*)(...))QWindow::keyPressEvent +232 (int (*)(...))QWindow::keyReleaseEvent +240 (int (*)(...))QWindow::mousePressEvent +248 (int (*)(...))QWindow::mouseReleaseEvent +256 (int (*)(...))QWindow::mouseDoubleClickEvent +264 (int (*)(...))QWindow::mouseMoveEvent +272 (int (*)(...))QWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))QOpenGLWindow::metric +320 (int (*)(...))QPaintDeviceWindow::paintEngine +328 (int (*)(...))QOpenGLWindow::initializeGL +336 (int (*)(...))QOpenGLWindow::resizeGL +344 (int (*)(...))QOpenGLWindow::paintGL +352 (int (*)(...))QOpenGLWindow::paintUnderGL +360 (int (*)(...))QOpenGLWindow::paintOverGL +368 (int (*)(...))QOpenGLWindow::redirected +376 (int (*)(...))-16 +384 (int (*)(...))(& _ZTI13QOpenGLWindow) +392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev +400 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev +408 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +416 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +424 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +432 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +440 (int (*)(...))-40 +448 (int (*)(...))(& _ZTI13QOpenGLWindow) +456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev +464 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev +472 (int (*)(...))QPaintDevice::devType +480 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +488 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QPaintDevice::initPainter +504 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint +512 (int (*)(...))QPaintDevice::sharedPainter + +Class QOpenGLWindow + size=56 align=8 + base size=50 base align=8 +QOpenGLWindow (0x0x7f65b9f19958) 0 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16) + QPaintDeviceWindow (0x0x7f65ba22bee0) 0 + primary-for QOpenGLWindow (0x0x7f65b9f19958) + QWindow (0x0x7f65ba22bf50) 0 + primary-for QPaintDeviceWindow (0x0x7f65ba22bee0) + QObject (0x0x7f65b9c91cc0) 0 + primary-for QWindow (0x0x7f65ba22bf50) + QSurface (0x0x7f65b9c91d20) 16 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 392) + QPaintDevice (0x0x7f65b9c91d80) 40 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 456) + +Class QQuickTransform::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTransform::QPrivateSignal (0x0x7f65b9cd9000) 0 empty + +Vtable for QQuickTransform +QQuickTransform::_ZTV15QQuickTransform: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQuickTransform) +16 (int (*)(...))QQuickTransform::metaObject +24 (int (*)(...))QQuickTransform::qt_metacast +32 (int (*)(...))QQuickTransform::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QQuickTransform + size=16 align=8 + base size=16 base align=8 +QQuickTransform (0x0x7f65b9f19a28) 0 + vptr=((& QQuickTransform::_ZTV15QQuickTransform) + 16) + QObject (0x0x7f65b9c91f60) 0 + primary-for QQuickTransform (0x0x7f65b9f19a28) + +Class QQuickItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItem::QPrivateSignal (0x0x7f65b9cd9240) 0 empty + +Class QQuickItem::ItemChangeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::ItemChangeData (0x0x7f65b9cd92a0) 0 + +Class QQuickItem::UpdatePaintNodeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::UpdatePaintNodeData (0x0x7f65b9cd9300) 0 + +Vtable for QQuickItem +QQuickItem::_ZTV10QQuickItem: 54 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickItem) +16 (int (*)(...))QQuickItem::metaObject +24 (int (*)(...))QQuickItem::qt_metacast +32 (int (*)(...))QQuickItem::qt_metacall +40 (int (*)(...))QQuickItem::~QQuickItem +48 (int (*)(...))QQuickItem::~QQuickItem +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickItem::isTextureProvider +152 (int (*)(...))QQuickItem::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::geometryChange +176 (int (*)(...))QQuickItem::classBegin +184 (int (*)(...))QQuickItem::componentComplete +192 (int (*)(...))QQuickItem::keyPressEvent +200 (int (*)(...))QQuickItem::keyReleaseEvent +208 (int (*)(...))QQuickItem::inputMethodEvent +216 (int (*)(...))QQuickItem::focusInEvent +224 (int (*)(...))QQuickItem::focusOutEvent +232 (int (*)(...))QQuickItem::mousePressEvent +240 (int (*)(...))QQuickItem::mouseMoveEvent +248 (int (*)(...))QQuickItem::mouseReleaseEvent +256 (int (*)(...))QQuickItem::mouseDoubleClickEvent +264 (int (*)(...))QQuickItem::mouseUngrabEvent +272 (int (*)(...))QQuickItem::touchUngrabEvent +280 (int (*)(...))QQuickItem::wheelEvent +288 (int (*)(...))QQuickItem::touchEvent +296 (int (*)(...))QQuickItem::hoverEnterEvent +304 (int (*)(...))QQuickItem::hoverMoveEvent +312 (int (*)(...))QQuickItem::hoverLeaveEvent +320 (int (*)(...))QQuickItem::dragEnterEvent +328 (int (*)(...))QQuickItem::dragMoveEvent +336 (int (*)(...))QQuickItem::dragLeaveEvent +344 (int (*)(...))QQuickItem::dropEvent +352 (int (*)(...))QQuickItem::childMouseEventFilter +360 (int (*)(...))QQuickItem::updatePaintNode +368 (int (*)(...))QQuickItem::releaseResources +376 (int (*)(...))QQuickItem::updatePolish +384 (int (*)(...))-16 +392 (int (*)(...))(& _ZTI10QQuickItem) +400 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD1Ev +408 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD0Ev +416 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickItem + size=32 align=8 + base size=32 base align=8 +QQuickItem (0x0x7f65b9cc3070) 0 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 16) + QObject (0x0x7f65b9cd9180) 0 + primary-for QQuickItem (0x0x7f65b9cc3070) + QQmlParserStatus (0x0x7f65b9cd91e0) 16 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 400) + +Class QQuickFramebufferObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickFramebufferObject::QPrivateSignal (0x0x7f65b9e1f000) 0 empty + +Vtable for QQuickFramebufferObject::Renderer +QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN23QQuickFramebufferObject8RendererE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QQuickFramebufferObject::Renderer::createFramebufferObject +48 (int (*)(...))QQuickFramebufferObject::Renderer::synchronize + +Class QQuickFramebufferObject::Renderer + size=16 align=8 + base size=16 base align=8 +QQuickFramebufferObject::Renderer (0x0x7f65b9e1f060) 0 + vptr=((& QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE) + 16) + +Vtable for QQuickFramebufferObject +QQuickFramebufferObject::_ZTV23QQuickFramebufferObject: 55 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +16 (int (*)(...))QQuickFramebufferObject::metaObject +24 (int (*)(...))QQuickFramebufferObject::qt_metacast +32 (int (*)(...))QQuickFramebufferObject::qt_metacall +40 0 +48 0 +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickFramebufferObject::isTextureProvider +152 (int (*)(...))QQuickFramebufferObject::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickFramebufferObject::geometryChange +176 (int (*)(...))QQuickItem::classBegin +184 (int (*)(...))QQuickItem::componentComplete +192 (int (*)(...))QQuickItem::keyPressEvent +200 (int (*)(...))QQuickItem::keyReleaseEvent +208 (int (*)(...))QQuickItem::inputMethodEvent +216 (int (*)(...))QQuickItem::focusInEvent +224 (int (*)(...))QQuickItem::focusOutEvent +232 (int (*)(...))QQuickItem::mousePressEvent +240 (int (*)(...))QQuickItem::mouseMoveEvent +248 (int (*)(...))QQuickItem::mouseReleaseEvent +256 (int (*)(...))QQuickItem::mouseDoubleClickEvent +264 (int (*)(...))QQuickItem::mouseUngrabEvent +272 (int (*)(...))QQuickItem::touchUngrabEvent +280 (int (*)(...))QQuickItem::wheelEvent +288 (int (*)(...))QQuickItem::touchEvent +296 (int (*)(...))QQuickItem::hoverEnterEvent +304 (int (*)(...))QQuickItem::hoverMoveEvent +312 (int (*)(...))QQuickItem::hoverLeaveEvent +320 (int (*)(...))QQuickItem::dragEnterEvent +328 (int (*)(...))QQuickItem::dragMoveEvent +336 (int (*)(...))QQuickItem::dragLeaveEvent +344 (int (*)(...))QQuickItem::dropEvent +352 (int (*)(...))QQuickItem::childMouseEventFilter +360 (int (*)(...))QQuickFramebufferObject::updatePaintNode +368 (int (*)(...))QQuickFramebufferObject::releaseResources +376 (int (*)(...))QQuickItem::updatePolish +384 (int (*)(...))__cxa_pure_virtual +392 (int (*)(...))-16 +400 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +408 0 +416 0 +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickFramebufferObject + size=32 align=8 + base size=32 base align=8 +QQuickFramebufferObject (0x0x7f65b9e174e0) 0 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 16) + QQuickItem (0x0x7f65b9e141c0) 0 + primary-for QQuickFramebufferObject (0x0x7f65b9e174e0) + QObject (0x0x7f65b9de6f00) 0 + primary-for QQuickItem (0x0x7f65b9e141c0) + QQmlParserStatus (0x0x7f65b9de6f60) 16 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 408) + +Class QQuickGraphicsConfiguration + size=8 align=8 + base size=8 base align=8 +QQuickGraphicsConfiguration (0x0x7f65b9e1f1e0) 0 + +Class QQuickGraphicsDevice + size=8 align=8 + base size=8 base align=8 +QQuickGraphicsDevice (0x0x7f65b9e1f240) 0 + +Class QQuickTextureFactory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextureFactory::QPrivateSignal (0x0x7f65b9e1f300) 0 empty + +Vtable for QQuickTextureFactory +QQuickTextureFactory::_ZTV20QQuickTextureFactory: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickTextureFactory) +16 (int (*)(...))QQuickTextureFactory::metaObject +24 (int (*)(...))QQuickTextureFactory::qt_metacast +32 (int (*)(...))QQuickTextureFactory::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))QQuickTextureFactory::image + +Class QQuickTextureFactory + size=16 align=8 + base size=16 base align=8 +QQuickTextureFactory (0x0x7f65b9e17548) 0 + vptr=((& QQuickTextureFactory::_ZTV20QQuickTextureFactory) + 16) + QObject (0x0x7f65b9e1f2a0) 0 + primary-for QQuickTextureFactory (0x0x7f65b9e17548) + +Class QQuickImageResponse::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickImageResponse::QPrivateSignal (0x0x7f65b9e1f420) 0 empty + +Vtable for QQuickImageResponse +QQuickImageResponse::_ZTV19QQuickImageResponse: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageResponse) +16 (int (*)(...))QQuickImageResponse::metaObject +24 (int (*)(...))QQuickImageResponse::qt_metacast +32 (int (*)(...))QQuickImageResponse::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQuickImageResponse::errorString +128 (int (*)(...))QQuickImageResponse::cancel + +Class QQuickImageResponse + size=16 align=8 + base size=16 base align=8 +QQuickImageResponse (0x0x7f65b9e175b0) 0 + vptr=((& QQuickImageResponse::_ZTV19QQuickImageResponse) + 16) + QObject (0x0x7f65b9e1f3c0) 0 + primary-for QQuickImageResponse (0x0x7f65b9e175b0) + +Class QQuickImageProvider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickImageProvider::QPrivateSignal (0x0x7f65b9e1f600) 0 empty + +Vtable for QQuickImageProvider +QQuickImageProvider::_ZTV19QQuickImageProvider: 19 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageProvider) +16 (int (*)(...))QQuickImageProvider::metaObject +24 (int (*)(...))QQuickImageProvider::qt_metacast +32 (int (*)(...))QQuickImageProvider::qt_metacall +40 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +48 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickImageProvider::imageType +120 (int (*)(...))QQuickImageProvider::flags +128 (int (*)(...))QQuickImageProvider::requestImage +136 (int (*)(...))QQuickImageProvider::requestPixmap +144 (int (*)(...))QQuickImageProvider::requestTexture + +Class QQuickImageProvider + size=24 align=8 + base size=24 base align=8 +QQuickImageProvider (0x0x7f65b9e17618) 0 + vptr=((& QQuickImageProvider::_ZTV19QQuickImageProvider) + 16) + QQmlImageProviderBase (0x0x7f65b9e17680) 0 + primary-for QQuickImageProvider (0x0x7f65b9e17618) + QObject (0x0x7f65b9e1f5a0) 0 + primary-for QQmlImageProviderBase (0x0x7f65b9e17680) + +Vtable for QQuickAsyncImageProvider +QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQuickAsyncImageProvider) +16 (int (*)(...))QQuickImageProvider::metaObject +24 (int (*)(...))QQuickImageProvider::qt_metacast +32 (int (*)(...))QQuickImageProvider::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickImageProvider::imageType +120 (int (*)(...))QQuickImageProvider::flags +128 (int (*)(...))QQuickImageProvider::requestImage +136 (int (*)(...))QQuickImageProvider::requestPixmap +144 (int (*)(...))QQuickImageProvider::requestTexture +152 (int (*)(...))__cxa_pure_virtual + +Class QQuickAsyncImageProvider + size=32 align=8 + base size=32 base align=8 +QQuickAsyncImageProvider (0x0x7f65b9e176e8) 0 + vptr=((& QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider) + 16) + QQuickImageProvider (0x0x7f65b9e17750) 0 + primary-for QQuickAsyncImageProvider (0x0x7f65b9e176e8) + QQmlImageProviderBase (0x0x7f65b9e177b8) 0 + primary-for QQuickImageProvider (0x0x7f65b9e17750) + QObject (0x0x7f65b9e1f6c0) 0 + primary-for QQmlImageProviderBase (0x0x7f65b9e177b8) + +Class QQuickItemGrabResult::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItemGrabResult::QPrivateSignal (0x0x7f65b9e1f780) 0 empty + +Vtable for QQuickItemGrabResult +QQuickItemGrabResult::_ZTV20QQuickItemGrabResult: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickItemGrabResult) +16 (int (*)(...))QQuickItemGrabResult::metaObject +24 (int (*)(...))QQuickItemGrabResult::qt_metacast +32 (int (*)(...))QQuickItemGrabResult::qt_metacall +40 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +48 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +56 (int (*)(...))QQuickItemGrabResult::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickItemGrabResult + size=16 align=8 + base size=16 base align=8 +QQuickItemGrabResult (0x0x7f65b9e17820) 0 + vptr=((& QQuickItemGrabResult::_ZTV20QQuickItemGrabResult) + 16) + QObject (0x0x7f65b9e1f720) 0 + primary-for QQuickItemGrabResult (0x0x7f65b9e17820) + +Class QQuickPaintedItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickPaintedItem::QPrivateSignal (0x0x7f65b9e1f9c0) 0 empty + +Vtable for QQuickPaintedItem +QQuickPaintedItem::_ZTV17QQuickPaintedItem: 55 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QQuickPaintedItem) +16 (int (*)(...))QQuickPaintedItem::metaObject +24 (int (*)(...))QQuickPaintedItem::qt_metacast +32 (int (*)(...))QQuickPaintedItem::qt_metacall +40 0 +48 0 +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickPaintedItem::isTextureProvider +152 (int (*)(...))QQuickPaintedItem::textureProvider +160 (int (*)(...))QQuickPaintedItem::itemChange +168 (int (*)(...))QQuickItem::geometryChange +176 (int (*)(...))QQuickItem::classBegin +184 (int (*)(...))QQuickItem::componentComplete +192 (int (*)(...))QQuickItem::keyPressEvent +200 (int (*)(...))QQuickItem::keyReleaseEvent +208 (int (*)(...))QQuickItem::inputMethodEvent +216 (int (*)(...))QQuickItem::focusInEvent +224 (int (*)(...))QQuickItem::focusOutEvent +232 (int (*)(...))QQuickItem::mousePressEvent +240 (int (*)(...))QQuickItem::mouseMoveEvent +248 (int (*)(...))QQuickItem::mouseReleaseEvent +256 (int (*)(...))QQuickItem::mouseDoubleClickEvent +264 (int (*)(...))QQuickItem::mouseUngrabEvent +272 (int (*)(...))QQuickItem::touchUngrabEvent +280 (int (*)(...))QQuickItem::wheelEvent +288 (int (*)(...))QQuickItem::touchEvent +296 (int (*)(...))QQuickItem::hoverEnterEvent +304 (int (*)(...))QQuickItem::hoverMoveEvent +312 (int (*)(...))QQuickItem::hoverLeaveEvent +320 (int (*)(...))QQuickItem::dragEnterEvent +328 (int (*)(...))QQuickItem::dragMoveEvent +336 (int (*)(...))QQuickItem::dragLeaveEvent +344 (int (*)(...))QQuickItem::dropEvent +352 (int (*)(...))QQuickItem::childMouseEventFilter +360 (int (*)(...))QQuickPaintedItem::updatePaintNode +368 (int (*)(...))QQuickPaintedItem::releaseResources +376 (int (*)(...))QQuickItem::updatePolish +384 (int (*)(...))__cxa_pure_virtual +392 (int (*)(...))-16 +400 (int (*)(...))(& _ZTI17QQuickPaintedItem) +408 0 +416 0 +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickPaintedItem + size=32 align=8 + base size=32 base align=8 +QQuickPaintedItem (0x0x7f65b9e17888) 0 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 16) + QQuickItem (0x0x7f65b9e14230) 0 + primary-for QQuickPaintedItem (0x0x7f65b9e17888) + QObject (0x0x7f65b9e1f900) 0 + primary-for QQuickItem (0x0x7f65b9e14230) + QQmlParserStatus (0x0x7f65b9e1f960) 16 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 408) + +Class QQuickRenderControl::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickRenderControl::QPrivateSignal (0x0x7f65b9abd120) 0 empty + +Vtable for QQuickRenderControl +QQuickRenderControl::_ZTV19QQuickRenderControl: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickRenderControl) +16 (int (*)(...))QQuickRenderControl::metaObject +24 (int (*)(...))QQuickRenderControl::qt_metacast +32 (int (*)(...))QQuickRenderControl::qt_metacall +40 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +48 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickRenderControl::renderWindow + +Class QQuickRenderControl + size=16 align=8 + base size=16 base align=8 +QQuickRenderControl (0x0x7f65b9e17a28) 0 + vptr=((& QQuickRenderControl::_ZTV19QQuickRenderControl) + 16) + QObject (0x0x7f65b9abd0c0) 0 + primary-for QQuickRenderControl (0x0x7f65b9e17a28) + +Class QQuickRenderTarget + size=8 align=8 + base size=8 base align=8 +QQuickRenderTarget (0x0x7f65b9abd300) 0 + +Class QQuickTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextDocument::QPrivateSignal (0x0x7f65b9abd480) 0 empty + +Vtable for QQuickTextDocument +QQuickTextDocument::_ZTV18QQuickTextDocument: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QQuickTextDocument) +16 (int (*)(...))QQuickTextDocument::metaObject +24 (int (*)(...))QQuickTextDocument::qt_metacast +32 (int (*)(...))QQuickTextDocument::qt_metacall +40 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +48 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickTextDocument + size=16 align=8 + base size=16 base align=8 +QQuickTextDocument (0x0x7f65b9e17a90) 0 + vptr=((& QQuickTextDocument::_ZTV18QQuickTextDocument) + 16) + QObject (0x0x7f65b9abd420) 0 + primary-for QQuickTextDocument (0x0x7f65b9e17a90) + +Class QSGGeometry::Attribute + size=16 align=4 + base size=16 base align=4 +QSGGeometry::Attribute (0x0x7f65b9b28cc0) 0 + +Class QSGGeometry::AttributeSet + size=16 align=8 + base size=16 base align=8 +QSGGeometry::AttributeSet (0x0x7f65b9b28d20) 0 + +Class QSGGeometry::Point2D + size=8 align=4 + base size=8 base align=4 +QSGGeometry::Point2D (0x0x7f65b9b28d80) 0 + +Class QSGGeometry::TexturedPoint2D + size=16 align=4 + base size=16 base align=4 +QSGGeometry::TexturedPoint2D (0x0x7f65b9b28de0) 0 + +Class QSGGeometry::ColoredPoint2D + size=12 align=4 + base size=12 base align=4 +QSGGeometry::ColoredPoint2D (0x0x7f65b9b28e40) 0 + +Vtable for QSGGeometry +QSGGeometry::_ZTV11QSGGeometry: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGGeometry) +16 (int (*)(...))QSGGeometry::~QSGGeometry +24 (int (*)(...))QSGGeometry::~QSGGeometry + +Class QSGGeometry + size=128 align=8 + base size=128 base align=8 +QSGGeometry (0x0x7f65b9b28c60) 0 + vptr=((& QSGGeometry::_ZTV11QSGGeometry) + 16) + +Vtable for QSGNode +QSGNode::_ZTV7QSGNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QSGNode) +16 (int (*)(...))QSGNode::~QSGNode +24 (int (*)(...))QSGNode::~QSGNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGNode + size=72 align=8 + base size=72 base align=8 +QSGNode (0x0x7f65b9b7a840) 0 + vptr=((& QSGNode::_ZTV7QSGNode) + 16) + +Vtable for QSGBasicGeometryNode +QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGBasicGeometryNode) +16 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +24 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGBasicGeometryNode + size=104 align=8 + base size=104 base align=8 +QSGBasicGeometryNode (0x0x7f65b9b56548) 0 + vptr=((& QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode) + 16) + QSGNode (0x0x7f65b9bef0c0) 0 + primary-for QSGBasicGeometryNode (0x0x7f65b9b56548) + +Vtable for QSGGeometryNode +QSGGeometryNode::_ZTV15QSGGeometryNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSGGeometryNode) +16 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +24 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGGeometryNode + size=136 align=8 + base size=136 base align=8 +QSGGeometryNode (0x0x7f65b9b565b0) 0 + vptr=((& QSGGeometryNode::_ZTV15QSGGeometryNode) + 16) + QSGBasicGeometryNode (0x0x7f65b9b56618) 0 + primary-for QSGGeometryNode (0x0x7f65b9b565b0) + QSGNode (0x0x7f65b9bef360) 0 + primary-for QSGBasicGeometryNode (0x0x7f65b9b56618) + +Vtable for QSGClipNode +QSGClipNode::_ZTV11QSGClipNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGClipNode) +16 (int (*)(...))QSGClipNode::~QSGClipNode +24 (int (*)(...))QSGClipNode::~QSGClipNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGClipNode + size=144 align=8 + base size=144 base align=8 +QSGClipNode (0x0x7f65b9b56680) 0 + vptr=((& QSGClipNode::_ZTV11QSGClipNode) + 16) + QSGBasicGeometryNode (0x0x7f65b9b566e8) 0 + primary-for QSGClipNode (0x0x7f65b9b56680) + QSGNode (0x0x7f65b9bef540) 0 + primary-for QSGBasicGeometryNode (0x0x7f65b9b566e8) + +Vtable for QSGTransformNode +QSGTransformNode::_ZTV16QSGTransformNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGTransformNode) +16 (int (*)(...))QSGTransformNode::~QSGTransformNode +24 (int (*)(...))QSGTransformNode::~QSGTransformNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGTransformNode + size=208 align=8 + base size=208 base align=8 +QSGTransformNode (0x0x7f65b9b56750) 0 + vptr=((& QSGTransformNode::_ZTV16QSGTransformNode) + 16) + QSGNode (0x0x7f65b9bef660) 0 + primary-for QSGTransformNode (0x0x7f65b9b56750) + +Vtable for QSGRootNode +QSGRootNode::_ZTV11QSGRootNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGRootNode) +16 (int (*)(...))QSGRootNode::~QSGRootNode +24 (int (*)(...))QSGRootNode::~QSGRootNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGRootNode + size=96 align=8 + base size=96 base align=8 +QSGRootNode (0x0x7f65b9b567b8) 0 + vptr=((& QSGRootNode::_ZTV11QSGRootNode) + 16) + QSGNode (0x0x7f65b9bef780) 0 + primary-for QSGRootNode (0x0x7f65b9b567b8) + +Vtable for QSGOpacityNode +QSGOpacityNode::_ZTV14QSGOpacityNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGOpacityNode) +16 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +24 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +32 (int (*)(...))QSGOpacityNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGOpacityNode + size=88 align=8 + base size=88 base align=8 +QSGOpacityNode (0x0x7f65b9c450d0) 0 + vptr=((& QSGOpacityNode::_ZTV14QSGOpacityNode) + 16) + QSGNode (0x0x7f65b9c3d180) 0 + primary-for QSGOpacityNode (0x0x7f65b9c450d0) + +Vtable for QSGNodeVisitor +QSGNodeVisitor::_ZTV14QSGNodeVisitor: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGNodeVisitor) +16 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +24 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +32 (int (*)(...))QSGNodeVisitor::enterTransformNode +40 (int (*)(...))QSGNodeVisitor::leaveTransformNode +48 (int (*)(...))QSGNodeVisitor::enterClipNode +56 (int (*)(...))QSGNodeVisitor::leaveClipNode +64 (int (*)(...))QSGNodeVisitor::enterGeometryNode +72 (int (*)(...))QSGNodeVisitor::leaveGeometryNode +80 (int (*)(...))QSGNodeVisitor::enterOpacityNode +88 (int (*)(...))QSGNodeVisitor::leaveOpacityNode +96 (int (*)(...))QSGNodeVisitor::visitNode +104 (int (*)(...))QSGNodeVisitor::visitChildren + +Class QSGNodeVisitor + size=8 align=8 + base size=8 base align=8 +QSGNodeVisitor (0x0x7f65b9c3d2a0) 0 nearly-empty + vptr=((& QSGNodeVisitor::_ZTV14QSGNodeVisitor) + 16) + +Vtable for QSGRendererInterface +QSGRendererInterface::_ZTV20QSGRendererInterface: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGRendererInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QSGRendererInterface::getResource +48 (int (*)(...))QSGRendererInterface::getResource +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRendererInterface + size=8 align=8 + base size=8 base align=8 +QSGRendererInterface (0x0x7f65b9c3d9c0) 0 nearly-empty + vptr=((& QSGRendererInterface::_ZTV20QSGRendererInterface) + 16) + +Class QQuickWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickWindow::QPrivateSignal (0x0x7f65b995f240) 0 empty + +Class QQuickWindow::GraphicsStateInfo + size=8 align=4 + base size=8 base align=4 +QQuickWindow::GraphicsStateInfo (0x0x7f65b995f2a0) 0 + +Vtable for QQuickWindow +QQuickWindow::_ZTV12QQuickWindow: 47 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QQuickWindow) +16 (int (*)(...))QQuickWindow::metaObject +24 (int (*)(...))QQuickWindow::qt_metacast +32 (int (*)(...))QQuickWindow::qt_metacall +40 (int (*)(...))QQuickWindow::~QQuickWindow +48 (int (*)(...))QQuickWindow::~QQuickWindow +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickWindow::resizeEvent +168 (int (*)(...))QWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QQuickWindow::focusInEvent +192 (int (*)(...))QQuickWindow::focusOutEvent +200 (int (*)(...))QQuickWindow::showEvent +208 (int (*)(...))QQuickWindow::hideEvent +216 (int (*)(...))QQuickWindow::closeEvent +224 (int (*)(...))QQuickWindow::keyPressEvent +232 (int (*)(...))QQuickWindow::keyReleaseEvent +240 (int (*)(...))QQuickWindow::mousePressEvent +248 (int (*)(...))QQuickWindow::mouseReleaseEvent +256 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +264 (int (*)(...))QQuickWindow::mouseMoveEvent +272 (int (*)(...))QQuickWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QQuickWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))-16 +320 (int (*)(...))(& _ZTI12QQuickWindow) +328 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD1Ev +336 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD0Ev +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickWindow + size=40 align=8 + base size=40 base align=8 +QQuickWindow (0x0x7f65b9c453a8) 0 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 16) + QWindow (0x0x7f65b98e2310) 0 + primary-for QQuickWindow (0x0x7f65b9c453a8) + QObject (0x0x7f65b995f180) 0 + primary-for QWindow (0x0x7f65b98e2310) + QSurface (0x0x7f65b995f1e0) 16 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 328) + +Class QQuickView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickView::QPrivateSignal (0x0x7f65b99e9b40) 0 empty + +Vtable for QQuickView +QQuickView::_ZTV10QQuickView: 47 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickView) +16 (int (*)(...))QQuickView::metaObject +24 (int (*)(...))QQuickView::qt_metacast +32 (int (*)(...))QQuickView::qt_metacall +40 (int (*)(...))QQuickView::~QQuickView +48 (int (*)(...))QQuickView::~QQuickView +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QQuickView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickView::resizeEvent +168 (int (*)(...))QWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QQuickWindow::focusInEvent +192 (int (*)(...))QQuickWindow::focusOutEvent +200 (int (*)(...))QQuickWindow::showEvent +208 (int (*)(...))QQuickWindow::hideEvent +216 (int (*)(...))QQuickWindow::closeEvent +224 (int (*)(...))QQuickView::keyPressEvent +232 (int (*)(...))QQuickView::keyReleaseEvent +240 (int (*)(...))QQuickView::mousePressEvent +248 (int (*)(...))QQuickView::mouseReleaseEvent +256 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +264 (int (*)(...))QQuickView::mouseMoveEvent +272 (int (*)(...))QQuickWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QQuickWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))-16 +320 (int (*)(...))(& _ZTI10QQuickView) +328 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD1Ev +336 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD0Ev +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickView + size=40 align=8 + base size=40 base align=8 +QQuickView (0x0x7f65b99e4e38) 0 + vptr=((& QQuickView::_ZTV10QQuickView) + 16) + QQuickWindow (0x0x7f65b99e4ea0) 0 + primary-for QQuickView (0x0x7f65b99e4e38) + QWindow (0x0x7f65b98e2bd0) 0 + primary-for QQuickWindow (0x0x7f65b99e4ea0) + QObject (0x0x7f65b99e9a80) 0 + primary-for QWindow (0x0x7f65b98e2bd0) + QSurface (0x0x7f65b99e9ae0) 16 + vptr=((& QQuickView::_ZTV10QQuickView) + 328) + +Class QSGMaterialType + size=1 align=1 + base size=0 base align=1 +QSGMaterialType (0x0x7f65b99e9e40) 0 empty + +Class QSGMaterialShader::RenderState + size=16 align=8 + base size=16 base align=8 +QSGMaterialShader::RenderState (0x0x7f65b99e9f00) 0 + +Class QSGMaterialShader::GraphicsPipelineState + size=36 align=4 + base size=36 base align=4 +QSGMaterialShader::GraphicsPipelineState (0x0x7f65b9a2c180) 0 + +Vtable for QSGMaterialShader +QSGMaterialShader::_ZTV17QSGMaterialShader: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGMaterialShader) +16 (int (*)(...))QSGMaterialShader::~QSGMaterialShader +24 (int (*)(...))QSGMaterialShader::~QSGMaterialShader +32 (int (*)(...))QSGMaterialShader::updateUniformData +40 (int (*)(...))QSGMaterialShader::updateSampledImage +48 (int (*)(...))QSGMaterialShader::updateGraphicsPipelineState + +Class QSGMaterialShader + size=16 align=8 + base size=16 base align=8 +QSGMaterialShader (0x0x7f65b99e9ea0) 0 + vptr=((& QSGMaterialShader::_ZTV17QSGMaterialShader) + 16) + +Vtable for QSGMaterial +QSGMaterial::_ZTV11QSGMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGMaterial) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QSGMaterial::compare + +Class QSGMaterial + size=24 align=8 + base size=24 base align=8 +QSGMaterial (0x0x7f65b9a2cf00) 0 + vptr=((& QSGMaterial::_ZTV11QSGMaterial) + 16) + +Vtable for QSGFlatColorMaterial +QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGFlatColorMaterial) +16 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +24 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +32 (int (*)(...))QSGFlatColorMaterial::type +40 (int (*)(...))QSGFlatColorMaterial::createShader +48 (int (*)(...))QSGFlatColorMaterial::compare + +Class QSGFlatColorMaterial + size=40 align=8 + base size=40 base align=8 +QSGFlatColorMaterial (0x0x7f65b9a2e410) 0 + vptr=((& QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial) + 16) + QSGMaterial (0x0x7f65b97343c0) 0 + primary-for QSGFlatColorMaterial (0x0x7f65b9a2e410) + +Class QNativeInterface::QSGOpenGLTexture::TypeInfo + size=1 align=1 + base size=0 base align=1 +QNativeInterface::QSGOpenGLTexture::TypeInfo (0x0x7f65b97344e0) 0 empty + +Vtable for QNativeInterface::QSGOpenGLTexture +QNativeInterface::QSGOpenGLTexture::_ZTVN16QNativeInterface16QSGOpenGLTextureE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface16QSGOpenGLTextureE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QSGOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QSGOpenGLTexture (0x0x7f65b9734480) 0 nearly-empty + vptr=((& QNativeInterface::QSGOpenGLTexture::_ZTVN16QNativeInterface16QSGOpenGLTextureE) + 16) + +Class QNativeInterface::QSGVulkanTexture::TypeInfo + size=1 align=1 + base size=0 base align=1 +QNativeInterface::QSGVulkanTexture::TypeInfo (0x0x7f65b9734600) 0 empty + +Vtable for QNativeInterface::QSGVulkanTexture +QNativeInterface::QSGVulkanTexture::_ZTVN16QNativeInterface16QSGVulkanTextureE: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface16QSGVulkanTextureE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QSGVulkanTexture + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QSGVulkanTexture (0x0x7f65b97345a0) 0 nearly-empty + vptr=((& QNativeInterface::QSGVulkanTexture::_ZTVN16QNativeInterface16QSGVulkanTextureE) + 16) + +Class QSGTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTexture::QPrivateSignal (0x0x7f65b9734720) 0 empty + +Vtable for QSGTexture +QSGTexture::_ZTV10QSGTexture: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSGTexture) +16 (int (*)(...))QSGTexture::metaObject +24 (int (*)(...))QSGTexture::qt_metacast +32 (int (*)(...))QSGTexture::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QSGTexture::rhiTexture +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QSGTexture::normalizedTextureSubRect +160 (int (*)(...))QSGTexture::isAtlasTexture +168 (int (*)(...))QSGTexture::removedFromAtlas +176 (int (*)(...))QSGTexture::commitTextureOperations + +Class QSGTexture + size=16 align=8 + base size=16 base align=8 +QSGTexture (0x0x7f65b9a2e478) 0 + vptr=((& QSGTexture::_ZTV10QSGTexture) + 16) + QObject (0x0x7f65b97346c0) 0 + primary-for QSGTexture (0x0x7f65b9a2e478) + +Class QSGDynamicTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGDynamicTexture::QPrivateSignal (0x0x7f65b97349c0) 0 empty + +Vtable for QSGDynamicTexture +QSGDynamicTexture::_ZTV17QSGDynamicTexture: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGDynamicTexture) +16 (int (*)(...))QSGDynamicTexture::metaObject +24 (int (*)(...))QSGDynamicTexture::qt_metacast +32 (int (*)(...))QSGDynamicTexture::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QSGTexture::rhiTexture +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QSGTexture::normalizedTextureSubRect +160 (int (*)(...))QSGTexture::isAtlasTexture +168 (int (*)(...))QSGTexture::removedFromAtlas +176 (int (*)(...))QSGTexture::commitTextureOperations +184 (int (*)(...))__cxa_pure_virtual + +Class QSGDynamicTexture + size=16 align=8 + base size=16 base align=8 +QSGDynamicTexture (0x0x7f65b9a2e4e0) 0 + vptr=((& QSGDynamicTexture::_ZTV17QSGDynamicTexture) + 16) + QSGTexture (0x0x7f65b9a2e548) 0 + primary-for QSGDynamicTexture (0x0x7f65b9a2e4e0) + QObject (0x0x7f65b9734960) 0 + primary-for QSGTexture (0x0x7f65b9a2e548) + +Vtable for QSGImageNode +QSGImageNode::_ZTV12QSGImageNode: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QSGImageNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QSGImageNode + size=136 align=8 + base size=136 base align=8 +QSGImageNode (0x0x7f65b9a2e5b0) 0 + vptr=((& QSGImageNode::_ZTV12QSGImageNode) + 16) + QSGGeometryNode (0x0x7f65b9a2e618) 0 + primary-for QSGImageNode (0x0x7f65b9a2e5b0) + QSGBasicGeometryNode (0x0x7f65b9a2e680) 0 + primary-for QSGGeometryNode (0x0x7f65b9a2e618) + QSGNode (0x0x7f65b9734a80) 0 + primary-for QSGBasicGeometryNode (0x0x7f65b9a2e680) + +Vtable for QSGNinePatchNode +QSGNinePatchNode::_ZTV16QSGNinePatchNode: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGNinePatchNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual + +Class QSGNinePatchNode + size=136 align=8 + base size=136 base align=8 +QSGNinePatchNode (0x0x7f65b9a2e820) 0 + vptr=((& QSGNinePatchNode::_ZTV16QSGNinePatchNode) + 16) + QSGGeometryNode (0x0x7f65b9a2e888) 0 + primary-for QSGNinePatchNode (0x0x7f65b9a2e820) + QSGBasicGeometryNode (0x0x7f65b9a2e8f0) 0 + primary-for QSGGeometryNode (0x0x7f65b9a2e888) + QSGNode (0x0x7f65b9734f60) 0 + primary-for QSGBasicGeometryNode (0x0x7f65b9a2e8f0) + +Vtable for QSGRectangleNode +QSGRectangleNode::_ZTV16QSGRectangleNode: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGRectangleNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRectangleNode + size=136 align=8 + base size=136 base align=8 +QSGRectangleNode (0x0x7f65b9a2e958) 0 + vptr=((& QSGRectangleNode::_ZTV16QSGRectangleNode) + 16) + QSGGeometryNode (0x0x7f65b9a2e9c0) 0 + primary-for QSGRectangleNode (0x0x7f65b9a2e958) + QSGBasicGeometryNode (0x0x7f65b9a2ea28) 0 + primary-for QSGGeometryNode (0x0x7f65b9a2e9c0) + QSGNode (0x0x7f65b9812000) 0 + primary-for QSGBasicGeometryNode (0x0x7f65b9a2ea28) + +Vtable for QSGRenderNode::RenderState +QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QSGRenderNode11RenderStateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))QSGRenderNode::RenderState::get + +Class QSGRenderNode::RenderState + size=8 align=8 + base size=8 base align=8 +QSGRenderNode::RenderState (0x0x7f65b9812120) 0 nearly-empty + vptr=((& QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE) + 16) + +Vtable for QSGRenderNode +QSGRenderNode::_ZTV13QSGRenderNode: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSGRenderNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))QSGRenderNode::changedStates +56 (int (*)(...))QSGRenderNode::prepare +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))QSGRenderNode::releaseResources +80 (int (*)(...))QSGRenderNode::flags +88 (int (*)(...))QSGRenderNode::rect + +Class QSGRenderNode + size=80 align=8 + base size=80 base align=8 +QSGRenderNode (0x0x7f65b9a2ea90) 0 + vptr=((& QSGRenderNode::_ZTV13QSGRenderNode) + 16) + QSGNode (0x0x7f65b98120c0) 0 + primary-for QSGRenderNode (0x0x7f65b9a2ea90) + +Vtable for QSGSimpleRectNode +QSGSimpleRectNode::_ZTV17QSGSimpleRectNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGSimpleRectNode) +16 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +24 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleRectNode + size=312 align=8 + base size=312 base align=8 +QSGSimpleRectNode (0x0x7f65b9a2ed68) 0 + vptr=((& QSGSimpleRectNode::_ZTV17QSGSimpleRectNode) + 16) + QSGGeometryNode (0x0x7f65b9a2edd0) 0 + primary-for QSGSimpleRectNode (0x0x7f65b9a2ed68) + QSGBasicGeometryNode (0x0x7f65b9a2ee38) 0 + primary-for QSGGeometryNode (0x0x7f65b9a2edd0) + QSGNode (0x0x7f65b9812900) 0 + primary-for QSGBasicGeometryNode (0x0x7f65b9a2ee38) + +Vtable for QSGOpaqueTextureMaterial +QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QSGOpaqueTextureMaterial) +16 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +24 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +32 (int (*)(...))QSGOpaqueTextureMaterial::type +40 (int (*)(...))QSGOpaqueTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGOpaqueTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGOpaqueTextureMaterial (0x0x7f65b9a2eea0) 0 + vptr=((& QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial) + 16) + QSGMaterial (0x0x7f65b98129c0) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7f65b9a2eea0) + +Vtable for QSGTextureMaterial +QSGTextureMaterial::_ZTV18QSGTextureMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureMaterial) +16 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +24 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +32 (int (*)(...))QSGTextureMaterial::type +40 (int (*)(...))QSGTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGTextureMaterial (0x0x7f65b9a2ef08) 0 + vptr=((& QSGTextureMaterial::_ZTV18QSGTextureMaterial) + 16) + QSGOpaqueTextureMaterial (0x0x7f65b9a2ef70) 0 + primary-for QSGTextureMaterial (0x0x7f65b9a2ef08) + QSGMaterial (0x0x7f65b9812e40) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7f65b9a2ef70) + +Vtable for QSGSimpleTextureNode +QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGSimpleTextureNode) +16 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +24 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleTextureNode + size=376 align=8 + base size=376 base align=8 +QSGSimpleTextureNode (0x0x7f65b94cb000) 0 + vptr=((& QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode) + 16) + QSGGeometryNode (0x0x7f65b94cb068) 0 + primary-for QSGSimpleTextureNode (0x0x7f65b94cb000) + QSGBasicGeometryNode (0x0x7f65b94cb0d0) 0 + primary-for QSGGeometryNode (0x0x7f65b94cb068) + QSGNode (0x0x7f65b9812ea0) 0 + primary-for QSGBasicGeometryNode (0x0x7f65b94cb0d0) + +Class QSGTextureProvider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTextureProvider::QPrivateSignal (0x0x7f65b94d5660) 0 empty + +Vtable for QSGTextureProvider +QSGTextureProvider::_ZTV18QSGTextureProvider: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureProvider) +16 (int (*)(...))QSGTextureProvider::metaObject +24 (int (*)(...))QSGTextureProvider::qt_metacast +32 (int (*)(...))QSGTextureProvider::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSGTextureProvider + size=16 align=8 + base size=16 base align=8 +QSGTextureProvider (0x0x7f65b94cb270) 0 + vptr=((& QSGTextureProvider::_ZTV18QSGTextureProvider) + 16) + QObject (0x0x7f65b94d5600) 0 + primary-for QSGTextureProvider (0x0x7f65b94cb270) + +Vtable for QSGVertexColorMaterial +QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QSGVertexColorMaterial) +16 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +24 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +32 (int (*)(...))QSGVertexColorMaterial::type +40 (int (*)(...))QSGVertexColorMaterial::createShader +48 (int (*)(...))QSGVertexColorMaterial::compare + +Class QSGVertexColorMaterial + size=24 align=8 + base size=24 base align=8 +QSGVertexColorMaterial (0x0x7f65b94cb2d8) 0 + vptr=((& QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial) + 16) + QSGMaterial (0x0x7f65b94d5720) 0 + primary-for QSGVertexColorMaterial (0x0x7f65b94cb2d8) + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b9541660) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b95419c0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b9541ba0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b9541f00) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b956a0c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b956a420) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b956a5a0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b956a900) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b956aae0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b956ae40) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b959f060) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b959f3c0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b959f5a0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b959f900) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b959fae0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b959fe40) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b95f8720) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b95f8a80) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b95f8c00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b95f8f60) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b9621120) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b9621480) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b9621600) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b9621960) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b9621ae0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b9621e40) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b964f000) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b964f360) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b964f4e0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b964f840) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f65b964f9c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f65b964fd20) 0 empty + diff --git a/tests/auto/bic/data/QtQuickTest.6.2.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuickTest.6.2.0.linux-gcc-amd64.txt new file mode 100644 index 00000000000..8e988d63c37 --- /dev/null +++ b/tests/auto/bic/data/QtQuickTest.6.2.0.linux-gcc-amd64.txt @@ -0,0 +1,5486 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f833d266a20) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f833cdbf240) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f833cdbf480) 0 empty + +Class std::__do_is_implicitly_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_implicitly_default_constructible_impl (0x0x7f833cdf35a0) 0 empty + +Class std::__make_unsigned_selector_base + size=1 align=1 + base size=0 base align=1 +std::__make_unsigned_selector_base (0x0x7f833ce1ed80) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f833a89dba0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f833a89dc60) 0 empty + +Class std::__invoke_memfun_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_ref (0x0x7f833a8ce180) 0 empty + +Class std::__invoke_memfun_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_deref (0x0x7f833a8ce1e0) 0 empty + +Class std::__invoke_memobj_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_ref (0x0x7f833a8ce240) 0 empty + +Class std::__invoke_memobj_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_deref (0x0x7f833a8ce2a0) 0 empty + +Class std::__invoke_other + size=1 align=1 + base size=0 base align=1 +std::__invoke_other (0x0x7f833a8ce300) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f833a8ce3c0) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f833a8ce480) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f833a8ce540) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f833a8ce600) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f833a8ce960) 0 empty + +Class std::__swappable_details::__do_is_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_swappable_impl (0x0x7f833a8cecc0) 0 empty + +Class std::__swappable_details::__do_is_nothrow_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_nothrow_swappable_impl (0x0x7f833a8ced20) 0 empty + +Class std::__swappable_with_details::__do_is_swappable_with_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_with_details::__do_is_swappable_with_impl (0x0x7f833a91a000) 0 empty + +Class std::__swappable_with_details::__do_is_nothrow_swappable_with_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_with_details::__do_is_nothrow_swappable_with_impl (0x0x7f833a91a060) 0 empty + +Class std::__nonesuch + size=1 align=1 + base size=0 base align=1 +std::__nonesuch (0x0x7f833a91a8a0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f833a96de40) 0 empty + +Class std::__nonesuch_no_braces + size=1 align=1 + base size=1 base align=1 +std::__nonesuch_no_braces (0x0x7f833a914d00) 0 empty + std::__nonesuch (0x0x7f833a99b360) 0 empty + +Class std::in_place_t + size=1 align=1 + base size=0 base align=1 +std::in_place_t (0x0x7f833aa180c0) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f833aa183c0) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f833aa18420) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f833aa80180) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f833aa801e0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f833aa21270) 0 empty + std::input_iterator_tag (0x0x7f833aa80240) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f833aa212d8) 0 empty + std::forward_iterator_tag (0x0x7f833aa21340) 0 empty + std::input_iterator_tag (0x0x7f833aa802a0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f833aa213a8) 0 empty + std::bidirectional_iterator_tag (0x0x7f833aa21410) 0 empty + std::forward_iterator_tag (0x0x7f833aa21478) 0 empty + std::input_iterator_tag (0x0x7f833aa80300) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f833a737000) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f833a737120) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f833a737420) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f833a737720) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f833a737840) 0 empty + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f833a7f3060) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f833a7f3360) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f833a7f33c0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f833a7f3480) 0 + +Class __pthread_internal_slist + size=8 align=8 + base size=8 base align=8 +__pthread_internal_slist (0x0x7f833a7f34e0) 0 + +Class __pthread_mutex_s + size=40 align=8 + base size=40 base align=8 +__pthread_mutex_s (0x0x7f833a7f3540) 0 + +Class __pthread_rwlock_arch_t + size=56 align=8 + base size=56 base align=8 +__pthread_rwlock_arch_t (0x0x7f833a7f35a0) 0 + +Class __pthread_cond_s + size=48 align=8 + base size=48 base align=8 +__pthread_cond_s (0x0x7f833a7f3600) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f833a7f38a0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f833a7f3b40) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f833a7f3ba0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f833a4b5960) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f833aa21820) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16) + std::exception (0x0x7f833a4b5b40) 0 nearly-empty + primary-for std::bad_exception (0x0x7f833aa21820) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f833a4b5d20) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f833aa21888) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16) + std::exception (0x0x7f833a4f0120) 0 nearly-empty + primary-for std::bad_cast (0x0x7f833aa21888) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f833aa218f0) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16) + std::exception (0x0x7f833a4f0300) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f833aa218f0) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f833a4f04e0) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f833a4f0a20) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f833aa21958) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16) + std::exception (0x0x7f833a524120) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f833aa21958) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f833aa219c0) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16) + std::bad_alloc (0x0x7f833aa21a28) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f833aa219c0) + std::exception (0x0x7f833a524300) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f833aa21a28) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f833a5244e0) 0 empty + +Class std::__allocator_traits_base + size=1 align=1 + base size=0 base align=1 +std::__allocator_traits_base (0x0x7f833a524720) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f833a5a8ea0) 0 empty + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f833a1c82a0) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f833a1c8360) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f833a225240) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f833a225300) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f833a225360) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f833a2253c0) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f833a225420) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f833a225540) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f833a2255a0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f8339ebcc00) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f8339ebcd80) 0 empty + +Class _G_fpos_t + size=16 align=8 + base size=16 base align=8 +_G_fpos_t (0x0x7f8339cd8c00) 0 + +Class _G_fpos64_t + size=16 align=8 + base size=16 base align=8 +_G_fpos64_t (0x0x7f8339cd8c60) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f8339cd8cc0) 0 + +Class _IO_cookie_io_functions_t + size=32 align=8 + base size=32 base align=8 +_IO_cookie_io_functions_t (0x0x7f8339cd8d20) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f83399354e0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f83398bf9c0) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16) + std::exception (0x0x7f83399355a0) 0 nearly-empty + primary-for std::logic_error (0x0x7f83398bf9c0) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f83398bfa28) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16) + std::logic_error (0x0x7f83398bfa90) 0 + primary-for std::domain_error (0x0x7f83398bfa28) + std::exception (0x0x7f8339935600) 0 nearly-empty + primary-for std::logic_error (0x0x7f83398bfa90) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f83398bfaf8) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16) + std::logic_error (0x0x7f83398bfb60) 0 + primary-for std::invalid_argument (0x0x7f83398bfaf8) + std::exception (0x0x7f8339935660) 0 nearly-empty + primary-for std::logic_error (0x0x7f83398bfb60) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f83398bfbc8) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16) + std::logic_error (0x0x7f83398bfc30) 0 + primary-for std::length_error (0x0x7f83398bfbc8) + std::exception (0x0x7f83399356c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f83398bfc30) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f83398bfc98) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16) + std::logic_error (0x0x7f83398bfd00) 0 + primary-for std::out_of_range (0x0x7f83398bfc98) + std::exception (0x0x7f8339935720) 0 nearly-empty + primary-for std::logic_error (0x0x7f83398bfd00) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f83398bfd68) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16) + std::exception (0x0x7f8339935780) 0 nearly-empty + primary-for std::runtime_error (0x0x7f83398bfd68) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f83398bfdd0) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16) + std::runtime_error (0x0x7f83398bfe38) 0 + primary-for std::range_error (0x0x7f83398bfdd0) + std::exception (0x0x7f83399357e0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f83398bfe38) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f83398bfea0) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16) + std::runtime_error (0x0x7f83398bff08) 0 + primary-for std::overflow_error (0x0x7f83398bfea0) + std::exception (0x0x7f8339935840) 0 nearly-empty + primary-for std::runtime_error (0x0x7f83398bff08) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f83398bff70) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16) + std::runtime_error (0x0x7f8339981000) 0 + primary-for std::underflow_error (0x0x7f83398bff70) + std::exception (0x0x7f83399358a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f8339981000) + +Class std::__erased_type + size=1 align=1 + base size=0 base align=1 +std::__erased_type (0x0x7f833999eba0) 0 empty + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f833999ec00) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f833999ed80) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f833999ee40) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f8339981270) 0 + std::__uses_alloc_base (0x0x7f833999ede0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f833973a480) 0 empty + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f83397ce680) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16) + std::exception (0x0x7f83397dab40) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f83397ce680) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f83397dac00) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f83397dac60) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f83397daf60) 0 + +Class std::__detail::_Identity + size=1 align=1 + base size=0 base align=1 +std::__detail::_Identity (0x0x7f83394a9de0) 0 empty + +Class std::__detail::_Select1st + size=1 align=1 + base size=0 base align=1 +std::__detail::_Select1st (0x0x7f83394a9ea0) 0 empty + +Class std::__detail::_Hash_node_base + size=8 align=8 + base size=8 base align=8 +std::__detail::_Hash_node_base (0x0x7f83394dd3c0) 0 + +Class std::__detail::_Mod_range_hashing + size=1 align=1 + base size=0 base align=1 +std::__detail::_Mod_range_hashing (0x0x7f8339509240) 0 empty + +Class std::__detail::_Default_ranged_hash + size=1 align=1 + base size=0 base align=1 +std::__detail::_Default_ranged_hash (0x0x7f8339509300) 0 empty + +Class std::__detail::_Prime_rehash_policy + size=16 align=8 + base size=16 base align=8 +std::__detail::_Prime_rehash_policy (0x0x7f8339509360) 0 + +Class std::__detail::_Mask_range_hashing + size=1 align=1 + base size=0 base align=1 +std::__detail::_Mask_range_hashing (0x0x7f8339509720) 0 empty + +Class std::__detail::_Power2_rehash_policy + size=16 align=8 + base size=16 base align=8 +std::__detail::_Power2_rehash_policy (0x0x7f8339509840) 0 + +Class std::__detail::_Equality_base + size=1 align=1 + base size=0 base align=1 +std::__detail::_Equality_base (0x0x7f83392df900) 0 empty + +Class std::_Enable_default_constructor_tag + size=1 align=1 + base size=0 base align=1 +std::_Enable_default_constructor_tag (0x0x7f833932a1e0) 0 empty + +Class std::nullopt_t + size=1 align=1 + base size=0 base align=1 +std::nullopt_t (0x0x7f833932aba0) 0 empty + +Vtable for std::bad_optional_access +std::bad_optional_access::_ZTVSt19bad_optional_access: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt19bad_optional_access) +16 (int (*)(...))std::bad_optional_access::~bad_optional_access +24 (int (*)(...))std::bad_optional_access::~bad_optional_access +32 (int (*)(...))std::bad_optional_access::what + +Class std::bad_optional_access + size=8 align=8 + base size=8 base align=8 +std::bad_optional_access (0x0x7f83393125b0) 0 nearly-empty + vptr=((& std::bad_optional_access::_ZTVSt19bad_optional_access) + 16) + std::exception (0x0x7f833932ade0) 0 nearly-empty + primary-for std::bad_optional_access (0x0x7f83393125b0) + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f8338e04780) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f8338da30d0) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f8338e04f00) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f8338da31a0) 0 + std::_Bit_iterator_base (0x0x7f8338da3208) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f8338e2e4e0) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f8338da32d8) 0 + std::_Bit_iterator_base (0x0x7f8338da3340) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f8338e2ecc0) 0 empty + +Class __pstl::execution::v1::sequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::sequenced_policy (0x0x7f8338c3b1e0) 0 empty + +Class __pstl::execution::v1::parallel_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::parallel_policy (0x0x7f8338c3b360) 0 empty + +Class __pstl::execution::v1::parallel_unsequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::parallel_unsequenced_policy (0x0x7f8338c3b4e0) 0 empty + +Class __pstl::execution::v1::unsequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::unsequenced_policy (0x0x7f8338c3b660) 0 empty + +Class std::__detail::__variant::__variant_cookie + size=1 align=1 + base size=0 base align=1 +std::__detail::__variant::__variant_cookie (0x0x7f833897b1e0) 0 empty + +Class std::__detail::__variant::__variant_idx_cookie + size=1 align=1 + base size=0 base align=1 +std::__detail::__variant::__variant_idx_cookie (0x0x7f833897b240) 0 empty + +Class std::monostate + size=1 align=1 + base size=0 base align=1 +std::monostate (0x0x7f8338a06cc0) 0 empty + +Vtable for std::bad_variant_access +std::bad_variant_access::_ZTVSt18bad_variant_access: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt18bad_variant_access) +16 (int (*)(...))std::bad_variant_access::~bad_variant_access +24 (int (*)(...))std::bad_variant_access::~bad_variant_access +32 (int (*)(...))std::bad_variant_access::what + +Class std::bad_variant_access + size=16 align=8 + base size=16 base align=8 +std::bad_variant_access (0x0x7f83389a86e8) 0 + vptr=((& std::bad_variant_access::_ZTVSt18bad_variant_access) + 16) + std::exception (0x0x7f8338a70240) 0 nearly-empty + primary-for std::bad_variant_access (0x0x7f83389a86e8) + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f83386f9c60) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f83386f9cc0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f83386f9f60) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f833874f7e0) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f83387888a0) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f833881ab40) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f83387bb9c0) 0 + std::__atomic_flag_base (0x0x7f833881aba0) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f8338398c98) 0 + QAtomicInteger<int> (0x0x7f8338398d00) 0 + QBasicAtomicInteger<int> (0x0x7f833839eae0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f8337c23d80) 0 empty + +Class QKeyCombination + size=4 align=4 + base size=4 base align=4 +QKeyCombination (0x0x7f8337c23de0) 0 + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f833790d120) 0 + +Class QMethodRawArguments + size=8 align=8 + base size=8 base align=8 +QMethodRawArguments (0x0x7f833790d840) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f833790d8a0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f833792d138) 0 + QGenericArgument (0x0x7f833790db40) 0 + +Class QMetaObject::SuperData + size=8 align=8 + base size=8 base align=8 +QMetaObject::SuperData (0x0x7f8337944060) 0 + +Class QMetaObject::Data + size=56 align=8 + base size=56 base align=8 +QMetaObject::Data (0x0x7f83379440c0) 0 + +Class QMetaObject + size=56 align=8 + base size=56 base align=8 +QMetaObject (0x0x7f8337944000) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f8337944a20) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f83379ba480) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f83379bae40) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f833769b960) 0 + +Class QArrayData + size=16 align=8 + base size=16 base align=8 +QArrayData (0x0x7f833769bcc0) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f8337750780) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f83377508a0) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f8337750c60) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f8337750f00) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f8337799120) 0 + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f83377de240) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f83377de5a0) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f83377ded80) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f83377c6618) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16) + std::runtime_error (0x0x7f83377c6680) 0 + primary-for std::system_error (0x0x7f83377c6618) + std::exception (0x0x7f8337822960) 0 nearly-empty + primary-for std::runtime_error (0x0x7f83377c6680) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f83377c69c0) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16) + std::system_error (0x0x7f83377c6a28) 0 + primary-for std::ios_base::failure (0x0x7f83377c69c0) + std::runtime_error (0x0x7f83377c6a90) 0 + primary-for std::system_error (0x0x7f83377c6a28) + std::exception (0x0x7f8337880120) 0 nearly-empty + primary-for std::runtime_error (0x0x7f83377c6a90) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f8337880180) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f83378801e0) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f8337880240) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f83378800c0) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f8337514e40) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f8337612180) 0 empty + +VTT for std::basic_ostream<char> +std::basic_ostream<char>::_ZTTSo: 2 entries +0 ((& std::basic_ostream<char>::_ZTVSo) + 24) +8 ((& std::basic_ostream<char>::_ZTVSo) + 64) + +VTT for std::basic_ostream<wchar_t> +std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64) + +VTT for std::basic_istream<char> +std::basic_istream<char>::_ZTTSi: 2 entries +0 ((& std::basic_istream<char>::_ZTVSi) + 24) +8 ((& std::basic_istream<char>::_ZTVSi) + 64) + +VTT for std::basic_istream<wchar_t> +std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64) + +Construction vtable for std::basic_istream<char> (0x0x7f8336f5e618 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd0_Si: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream<char> (0x0x7f8336f5e6e8 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd16_So: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::basic_iostream<char> +std::basic_iostream<char>::_ZTTSd: 7 entries +0 ((& std::basic_iostream<char>::_ZTVSd) + 24) +8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24) +16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64) +24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24) +32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64) +40 ((& std::basic_iostream<char>::_ZTVSd) + 104) +48 ((& std::basic_iostream<char>::_ZTVSd) + 64) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f8336f5ec30 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f8336f5ed00 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7 entries +0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24) +16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64) +24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24) +32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64) +40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104) +48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64) + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f8336fd1068) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16) + std::exception (0x0x7f8336fb0b40) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f8336fd1068) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f8336fd10d0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16) + std::exception (0x0x7f8336fb0c60) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f8336fd10d0) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f8336fd1138) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16) + std::exception (0x0x7f8336fb0d80) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f8336fd1138) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f8336fd1208) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16) + std::exception (0x0x7f8336fb0ea0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f8336fd1208) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f8336fe9780) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f8336fe9ae0) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f8336fe9de0) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f8337012120) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f8336fd1340) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16) + std::exception (0x0x7f8337095900) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f8336fd1340) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f8336d036c0) 0 empty + +Class std::__sp_array_delete + size=1 align=1 + base size=0 base align=1 +std::__sp_array_delete (0x0x7f8336d03c00) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f8336e49a20) 0 + +Class QByteArrayView + size=16 align=8 + base size=16 base align=8 +QByteArrayView (0x0x7f8336baad80) 0 + +Class QByteArray + size=24 align=8 + base size=24 base align=8 +QByteArray (0x0x7f83368a8ea0) 0 + +Class QByteArray::FromBase64Result + size=32 align=8 + base size=28 base align=8 +QByteArray::FromBase64Result (0x0x7f83367102a0) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f83367d5240) 0 + +Class QChar::fromUcs4(char32_t)::R + size=4 align=2 + base size=4 base align=2 +QChar::fromUcs4(char32_t)::R (0x0x7f833651e180) 0 + +Class QtPrivate::hide_char8_t + size=1 align=1 + base size=0 base align=1 +QtPrivate::hide_char8_t (0x0x7f833651e5a0) 0 empty + +Class QtPrivate::wrap_char + size=1 align=1 + base size=0 base align=1 +QtPrivate::wrap_char (0x0x7f833651e600) 0 empty + +Class QAnyStringView + size=16 align=8 + base size=16 base align=8 +QAnyStringView (0x0x7f83365a9360) 0 + +Class QStringTokenizerBaseBase::tokenizer_state + size=24 align=8 + base size=24 base align=8 +QStringTokenizerBaseBase::tokenizer_state (0x0x7f833668f540) 0 + +Class QStringTokenizerBaseBase + size=8 align=4 + base size=8 base align=4 +QStringTokenizerBaseBase (0x0x7f833668f4e0) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f83362eb420) 0 + +Class QString + size=24 align=8 + base size=24 base align=8 +QString (0x0x7f83364506c0) 0 + +Class QtPrivate::ArgBase + size=1 align=1 + base size=1 base align=1 +QtPrivate::ArgBase (0x0x7f833603a9c0) 0 + +Class QtPrivate::QStringViewArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QStringViewArg (0x0x7f8336046208) 0 + QtPrivate::ArgBase (0x0x7f833603aa20) 0 + +Class QtPrivate::QLatin1StringArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QLatin1StringArg (0x0x7f83360462d8) 0 + QtPrivate::ArgBase (0x0x7f833603ac60) 0 + +Class QHashSeed + size=8 align=8 + base size=8 base align=8 +QHashSeed (0x0x7f8335cae4e0) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f8335ced420) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f8335ced4e0) 0 empty + +Class QStringMatcher + size=312 align=8 + base size=312 base align=8 +QStringMatcher (0x0x7f8335af7a20) 0 + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f8335b4ec00) 0 empty + +Class QtPrivate::CompareAgainstLiteralZero + size=1 align=1 + base size=0 base align=1 +QtPrivate::CompareAgainstLiteralZero (0x0x7f8335bc5900) 0 empty + +Class QPartialOrdering + size=1 align=1 + base size=1 base align=1 +QPartialOrdering (0x0x7f8335bc5b40) 0 + +Class QIODeviceBase + size=1 align=1 + base size=0 base align=1 +QIODeviceBase (0x0x7f8335c6d660) 0 empty + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f8335d65ea0) 0 + QIODeviceBase (0x0x7f8335c6d6c0) 0 empty + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f8335c6d840) 0 + +Class QtMetaContainerPrivate::QMetaContainerInterface + size=120 align=8 + base size=120 base align=8 +QtMetaContainerPrivate::QMetaContainerInterface (0x0x7f833593ede0) 0 + +Class QtMetaContainerPrivate::QMetaSequenceInterface + size=216 align=8 + base size=216 base align=8 +QtMetaContainerPrivate::QMetaSequenceInterface (0x0x7f8335946680) 0 + QtMetaContainerPrivate::QMetaContainerInterface (0x0x7f833593eea0) 0 + +Class QtMetaContainerPrivate::QMetaAssociationInterface + size=240 align=8 + base size=240 base align=8 +QtMetaContainerPrivate::QMetaAssociationInterface (0x0x7f8335946750) 0 + QtMetaContainerPrivate::QMetaContainerInterface (0x0x7f833593ef60) 0 + +Class QMetaContainer + size=8 align=8 + base size=8 base align=8 +QMetaContainer (0x0x7f8335a3da80) 0 + +Class QMetaSequence + size=8 align=8 + base size=8 base align=8 +QMetaSequence (0x0x7f8335946af8) 0 + QMetaContainer (0x0x7f8335a3dc60) 0 + +Class QMetaAssociation + size=8 align=8 + base size=8 base align=8 +QMetaAssociation (0x0x7f8335946b60) 0 + QMetaContainer (0x0x7f8335a61060) 0 + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f8335760240) 0 + +Class std::__detail::_List_node_header + size=24 align=8 + base size=24 base align=8 +std::__detail::_List_node_header (0x0x7f83356ecbc8) 0 + std::__detail::_List_node_base (0x0x7f83357602a0) 0 + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f8335835360) 0 + +Class std::_Rb_tree_header + size=40 align=8 + base size=40 base align=8 +std::_Rb_tree_header (0x0x7f83358356c0) 0 + +Class QtPrivate::QMetaTypeInterface + size=112 align=8 + base size=112 base align=8 +QtPrivate::QMetaTypeInterface (0x0x7f83352a2b40) 0 + +Class QMetaType + size=8 align=8 + base size=8 base align=8 +QMetaType (0x0x7f83352a2d20) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f833532cd80) 0 + +Class QtPrivate::QTypeNormalizer + size=16 align=8 + base size=16 base align=8 +QtPrivate::QTypeNormalizer (0x0x7f8335273660) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f8334e5f960) 0 + +Class QAdoptSharedDataTag + size=1 align=1 + base size=0 base align=1 +QAdoptSharedDataTag (0x0x7f8334e5fcc0) 0 empty + +Class QtPrivate::RefCounted + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCounted (0x0x7f8334acad20) 0 + +Class QPropertyBindingPrivatePtr + size=8 align=8 + base size=8 base align=8 +QPropertyBindingPrivatePtr (0x0x7f8334acae40) 0 + +Class QUntypedPropertyData::InheritsQUntypedPropertyData + size=1 align=1 + base size=0 base align=1 +QUntypedPropertyData::InheritsQUntypedPropertyData (0x0x7f8334b344e0) 0 empty + +Class QUntypedPropertyData + size=1 align=1 + base size=0 base align=1 +QUntypedPropertyData (0x0x7f8334b34480) 0 empty + +Class QPropertyProxyBindingData + size=24 align=8 + base size=24 base align=8 +QPropertyProxyBindingData (0x0x7f8334b34540) 0 + +Class QtPrivate::BindingFunctionVTable + size=32 align=8 + base size=32 base align=8 +QtPrivate::BindingFunctionVTable (0x0x7f8334b345a0) 0 + +Class QtPrivate::QPropertyBindingFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::QPropertyBindingFunction (0x0x7f8334b34ae0) 0 + +Class QtPrivate::QPropertyBindingData + size=8 align=8 + base size=8 base align=8 +QtPrivate::QPropertyBindingData (0x0x7f8334b34b40) 0 + +Class std::experimental::fundamentals_v2::source_location + size=24 align=8 + base size=24 base align=8 +std::experimental::fundamentals_v2::source_location (0x0x7f8334b5f2a0) 0 + +Class QPropertyBindingSourceLocation + size=24 align=8 + base size=24 base align=8 +QPropertyBindingSourceLocation (0x0x7f8334b5f9c0) 0 + +Class QPropertyBindingError + size=8 align=8 + base size=8 base align=8 +QPropertyBindingError (0x0x7f8334b5fcc0) 0 + +Class QUntypedPropertyBinding + size=8 align=8 + base size=8 base align=8 +QUntypedPropertyBinding (0x0x7f8334b5fde0) 0 + +Class QPropertyObserverBase + size=24 align=8 + base size=24 base align=8 +QPropertyObserverBase (0x0x7f8334bac060) 0 + +Class QPropertyObserver + size=24 align=8 + base size=24 base align=8 +QPropertyObserver (0x0x7f8334b32618) 0 + QPropertyObserverBase (0x0x7f8334bac1e0) 0 + +Class QPropertyNotifier + size=56 align=8 + base size=56 base align=8 +QPropertyNotifier (0x0x7f8334b32958) 0 + QPropertyObserver (0x0x7f8334b329c0) 0 + QPropertyObserverBase (0x0x7f8334bac6c0) 0 + +Class QtPrivate::QBindableInterface + size=56 align=8 + base size=56 base align=8 +QtPrivate::QBindableInterface (0x0x7f8334c085a0) 0 + +Class QUntypedBindable + size=16 align=8 + base size=16 base align=8 +QUntypedBindable (0x0x7f8334c29720) 0 + +Class QBindingStatus + size=32 align=8 + base size=32 base align=8 +QBindingStatus (0x0x7f833494b660) 0 + +Class QBindingStorage + size=16 align=8 + base size=16 base align=8 +QBindingStorage (0x0x7f833494b6c0) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f8334a4c480) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f83347031e0) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=80 align=8 + base size=80 base align=8 +QObjectData (0x0x7f8334758b40) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f83347ea4e0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f83347ea480) 0 + vptr=((& QObject::_ZTV7QObject) + 16) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f83344ac420) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f83344accc0) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f833477fea0) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16) + QObject (0x0x7f83344acc60) 0 + primary-for QAbstractAnimation (0x0x7f833477fea0) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f83344e8060) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f833477ff08) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16) + QObject (0x0x7f83344e8000) 0 + primary-for QAnimationDriver (0x0x7f833477ff08) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f83344e8240) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f833477ff70) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16) + QObject (0x0x7f83344e81e0) 0 + primary-for QEventLoop (0x0x7f833477ff70) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f83344e8780) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f83344e8840) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f83344e88a0) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))QAbstractEventDispatcher::startingUp +200 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f83345010d0) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16) + QObject (0x0x7f83344e87e0) 0 + primary-for QAbstractEventDispatcher (0x0x7f83345010d0) + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f833457a060) 0 empty + +Class QStringConverterBase::State + size=48 align=8 + base size=48 base align=8 +QStringConverterBase::State (0x0x7f8334443c60) 0 + +Class QStringConverterBase + size=1 align=1 + base size=0 base align=1 +QStringConverterBase (0x0x7f8334443c00) 0 empty + +Class QStringConverter::Interface + size=40 align=8 + base size=40 base align=8 +QStringConverter::Interface (0x0x7f83344678a0) 0 + +Class QStringConverter + size=56 align=8 + base size=56 base align=8 +QStringConverter (0x0x7f8334465270) 0 + QStringConverterBase (0x0x7f8334467840) 0 empty + +Class QStringEncoder + size=56 align=8 + base size=56 base align=8 +QStringEncoder (0x0x7f83344652d8) 0 + QStringConverter (0x0x7f8334465340) 0 + QStringConverterBase (0x0x7f83340c22a0) 0 empty + +Class QStringDecoder + size=56 align=8 + base size=56 base align=8 +QStringDecoder (0x0x7f83344653a8) 0 + QStringConverter (0x0x7f8334465410) 0 + QStringConverterBase (0x0x7f83340e2120) 0 empty + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f8334465478) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16) + QIODeviceBase (0x0x7f83340e2de0) 0 empty + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f83341375a0) 0 + +Class QContiguousCacheData + size=40 align=8 + base size=40 base align=8 +QContiguousCacheData (0x0x7f83341e9780) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f8334214de0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f8334214f60) 0 + +Class QtPrivate::EnableInternalData + size=1 align=1 + base size=0 base align=1 +QtPrivate::EnableInternalData (0x0x7f8333eef1e0) 0 empty + +Class QDebug::Stream + size=88 align=8 + base size=88 base align=8 +QDebug::Stream (0x0x7f8333f18120) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f8333ec1f08) 0 + QIODeviceBase (0x0x7f8333f180c0) 0 empty + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f8334019a80) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f8334019b40) 0 empty + +Class QVariant::PrivateShared + size=8 align=8 + base size=8 base align=8 +QVariant::PrivateShared (0x0x7f8333dc1780) 0 + +Class QVariant::Private + size=32 align=8 + base size=32 base align=8 +QVariant::Private (0x0x7f8333dc17e0) 0 + +Class QVariant + size=32 align=8 + base size=32 base align=8 +QVariant (0x0x7f8333dc1720) 0 + +Class QtPrivate::QVariantTypeCoercer + size=32 align=8 + base size=32 base align=8 +QtPrivate::QVariantTypeCoercer (0x0x7f8333b8ef00) 0 + +Class QVariantConstPointer + size=32 align=8 + base size=32 base align=8 +QVariantConstPointer (0x0x7f8333bb5180) 0 + +Class QModelRoleData + size=40 align=8 + base size=40 base align=8 +QModelRoleData (0x0x7f8333bb5360) 0 + +Class QModelRoleDataSpan + size=16 align=8 + base size=16 base align=8 +QModelRoleDataSpan (0x0x7f8333bf0240) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f8333c3b2a0) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f8333c84480) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f83338f8d20) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractItemModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractItemModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f8333901d00) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16) + QObject (0x0x7f83338f8cc0) 0 + primary-for QAbstractItemModel (0x0x7f8333901d00) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f8333a2eae0) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractTableModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractTableModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f833396c5b0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16) + QAbstractItemModel (0x0x7f833396c618) 0 + primary-for QAbstractTableModel (0x0x7f833396c5b0) + QObject (0x0x7f8333a2ea80) 0 + primary-for QAbstractItemModel (0x0x7f833396c618) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f8333a2ec00) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractListModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractListModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f833396c680) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16) + QAbstractItemModel (0x0x7f833396c6e8) 0 + primary-for QAbstractListModel (0x0x7f833396c680) + QObject (0x0x7f8333a2eba0) 0 + primary-for QAbstractItemModel (0x0x7f833396c6e8) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f83336b0480) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f83336b0540) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QAbstractProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QAbstractProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QAbstractProxyModel::setSourceModel +416 (int (*)(...))__cxa_pure_virtual +424 (int (*)(...))__cxa_pure_virtual +432 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +440 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f83336a5af8) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16) + QAbstractItemModel (0x0x7f83336a5b60) 0 + primary-for QAbstractProxyModel (0x0x7f83336a5af8) + QObject (0x0x7f83336b04e0) 0 + primary-for QAbstractItemModel (0x0x7f83336a5b60) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f83336b0720) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f83336a5bc8) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16) + QAbstractAnimation (0x0x7f83336a5c30) 0 + primary-for QAnimationGroup (0x0x7f83336a5bc8) + QObject (0x0x7f83336b06c0) 0 + primary-for QAbstractAnimation (0x0x7f83336a5c30) + +Class QAssociativeIterator + size=16 align=8 + base size=16 base align=8 +QAssociativeIterator (0x0x7f83336a5d68) 0 + QIterator<QMetaAssociation> (0x0x7f83336a5dd0) 0 + QBaseIterator<QMetaAssociation> (0x0x7f83336b0b40) 0 + +Class QAssociativeConstIterator + size=16 align=8 + base size=16 base align=8 +QAssociativeConstIterator (0x0x7f83336a5f08) 0 + QConstIterator<QMetaAssociation> (0x0x7f83336a5f70) 0 + QBaseIterator<QMetaAssociation> (0x0x7f833372e0c0) 0 + +Class QAssociativeIterable + size=24 align=8 + base size=24 base align=8 +QAssociativeIterable (0x0x7f833373f000) 0 + QIterable<QMetaAssociation> (0x0x7f833372e600) 0 + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f8333835120) 0 + +Class QBitArray + size=24 align=8 + base size=24 base align=8 +QBitArray (0x0x7f8333872e40) 0 + +Class QBitRef + size=16 align=8 + base size=16 base align=8 +QBitRef (0x0x7f833349fd80) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f83334e9900) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f83336fc2a0) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16) + QObject (0x0x7f83334e9840) 0 + primary-for QIODevice (0x0x7f83336fc2a0) + QIODeviceBase (0x0x7f83334e98a0) 0 empty + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f83334e9d20) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f83334dcf70) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16) + QIODevice (0x0x7f833352b000) 0 + primary-for QBuffer (0x0x7f83334dcf70) + QObject (0x0x7f83334e9c60) 0 + primary-for QIODevice (0x0x7f833352b000) + QIODeviceBase (0x0x7f83334e9cc0) 0 empty + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f83334e9f60) 0 + +Class QByteArrayMatcher + size=1056 align=8 + base size=1056 base align=8 +QByteArrayMatcher (0x0x7f83334e9f00) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f8333543120) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f83335430c0) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f8333598900) 0 + +Class QCalendar::YearMonthDay + size=12 align=4 + base size=12 base align=4 +QCalendar::YearMonthDay (0x0x7f83332b2780) 0 + +Class QCalendar::SystemId + size=8 align=8 + base size=8 base align=8 +QCalendar::SystemId (0x0x7f83332b27e0) 0 + +Class QCalendar + size=8 align=8 + base size=8 base align=8 +QCalendar (0x0x7f83332b2720) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f833330b240) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f8333363840) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f83333afa80) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f83333afae0) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f83333afa20) 0 + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f8333430d20) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f833348f120) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f8333149360) 0 + +Class QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel + size=1 align=1 + base size=0 base align=1 +QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel (0x0x7f83331b2ae0) 0 empty + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f83331b2ba0) 0 + +Class QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator + size=24 align=8 + base size=17 base align=8 +QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator (0x0x7f83331b2d20) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f833323ff60) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f8332f32ba0) 0 + +Class QCborParserError + size=16 align=8 + base size=16 base align=8 +QCborParserError (0x0x7f8332fb7d20) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f8332fb7de0) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f8332cf16c0) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f8332d2cc00) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f8332d2cc60) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f8332d2cba0) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f8332e3e240) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f8332e3e2a0) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f8332e3e1e0) 0 + +Class qfloat16::Wrap + size=2 align=2 + base size=2 base align=2 +qfloat16::Wrap (0x0x7f8332c4f300) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f8332c4f2a0) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f833294b6c0) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f8332992b40) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f83329c55a0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f83329c5780) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f8332a8d1e0) 0 + +Class QEvent::InputEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::InputEventTag (0x0x7f83326f5b40) 0 empty + +Class QEvent::PointerEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::PointerEventTag (0x0x7f83326f5ba0) 0 empty + +Class QEvent::SinglePointEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::SinglePointEventTag (0x0x7f83326f5c00) 0 empty + +Vtable for QEvent +QEvent::_ZTV6QEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QEvent + size=16 align=8 + base size=16 base align=8 +QEvent (0x0x7f83326f5ae0) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QTimerEvent::clone + +Class QTimerEvent + size=24 align=8 + base size=20 base align=8 +QTimerEvent (0x0x7f83326fe410) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16) + QEvent (0x0x7f83327575a0) 0 + primary-for QTimerEvent (0x0x7f83326fe410) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QChildEvent::clone + +Class QChildEvent + size=24 align=8 + base size=24 base align=8 +QChildEvent (0x0x7f83326fe478) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16) + QEvent (0x0x7f8332757a80) 0 + primary-for QChildEvent (0x0x7f83326fe478) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDynamicPropertyChangeEvent::clone + +Class QDynamicPropertyChangeEvent + size=40 align=8 + base size=40 base align=8 +QDynamicPropertyChangeEvent (0x0x7f83326fe4e0) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16) + QEvent (0x0x7f8332757ea0) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f83326fe4e0) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDeferredDeleteEvent::clone + +Class QDeferredDeleteEvent + size=24 align=8 + base size=20 base align=8 +QDeferredDeleteEvent (0x0x7f83326fe548) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16) + QEvent (0x0x7f8332791180) 0 + primary-for QDeferredDeleteEvent (0x0x7f83326fe548) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f8332791540) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f83326fe618) 0 + QBasicMutex (0x0x7f83327f92a0) 0 + +Class QRecursiveMutex + size=24 align=8 + base size=24 base align=8 +QRecursiveMutex (0x0x7f83327f96c0) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f83327f9cc0) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f8332868300) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f8332868f60) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f83325d69c0) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16) + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f8332613b40) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f8332613e40) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f8332386240) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f83323838f0) 0 + std::__mutex_base (0x0x7f83323862a0) 0 + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f8332386480) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f83323864e0) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f8332386540) 0 empty + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f8332386f60) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f8332383958) 0 + std::__recursive_mutex_base (0x0x7f83323c3000) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f83322bdd20) 0 + std::__mutex_base (0x0x7f83323c33c0) 0 + std::__timed_mutex_impl<std::timed_mutex> (0x0x7f83323c3420) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f83322bdd90) 0 + std::__recursive_mutex_base (0x0x7f83323c37e0) 0 + std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7f83323c3840) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f83323ff660) 0 + +Vtable for std::thread::_State +std::thread::_State::_ZTVNSt6thread6_StateE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread6_StateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_State + size=8 align=8 + base size=8 base align=8 +std::thread::_State (0x0x7f83323ff900) 0 nearly-empty + vptr=((& std::thread::_State::_ZTVNSt6thread6_StateE) + 16) + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f83323ff960) 0 + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f83323ff8a0) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f83321e2ba0) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f83321e2f60) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f833222b000) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f8331ed0540) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f8331ea5750) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16) + std::logic_error (0x0x7f8331ea57b8) 0 + primary-for std::future_error (0x0x7f8331ea5750) + std::exception (0x0x7f8331ed0c60) 0 nearly-empty + primary-for std::logic_error (0x0x7f8331ea57b8) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f8331f023c0) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f8331f02360) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f8332037de0) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f8332033410) 0 + std::__at_thread_exit_elt (0x0x7f8332037ea0) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f8331f02540) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f8331f02300) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f833192f340) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16) + std::__future_base::_State_baseV2 (0x0x7f833193aba0) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f833192f340) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f8331971480) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f833192f680) 0 + vptr=((& QThread::_ZTV7QThread) + 16) + QObject (0x0x7f8331971420) 0 + primary-for QThread (0x0x7f833192f680) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class QRunnable + size=16 align=8 + base size=9 base align=8 +QRunnable (0x0x7f83319717e0) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f8331971960) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f833192f6e8) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16) + QObject (0x0x7f8331971900) 0 + primary-for QThreadPool (0x0x7f833192f6e8) + +Vtable for QException +QException::_ZTV10QException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f833192f750) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16) + std::exception (0x0x7f8331971ae0) 0 nearly-empty + primary-for QException (0x0x7f833192f750) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=16 align=8 + base size=16 base align=8 +QUnhandledException (0x0x7f833192f7b8) 0 + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16) + QException (0x0x7f833192f820) 0 nearly-empty + primary-for QUnhandledException (0x0x7f833192f7b8) + std::exception (0x0x7f8331971b40) 0 nearly-empty + primary-for QException (0x0x7f833192f820) + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f83319dc9c0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f833180a0c0) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f833180a060) 0 + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f8331857300) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f8331825478) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16) + QObject (0x0x7f83318572a0) 0 + primary-for QCoreApplication (0x0x7f8331825478) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f8331857540) 0 + +Class QConcatenateTablesProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QConcatenateTablesProxyModel::QPrivateSignal (0x0x7f8331857660) 0 empty + +Vtable for QConcatenateTablesProxyModel +QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QConcatenateTablesProxyModel) +16 (int (*)(...))QConcatenateTablesProxyModel::metaObject +24 (int (*)(...))QConcatenateTablesProxyModel::qt_metacast +32 (int (*)(...))QConcatenateTablesProxyModel::qt_metacall +40 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +48 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QConcatenateTablesProxyModel::index +120 (int (*)(...))QConcatenateTablesProxyModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QConcatenateTablesProxyModel::rowCount +144 (int (*)(...))QConcatenateTablesProxyModel::columnCount +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))QConcatenateTablesProxyModel::data +168 (int (*)(...))QConcatenateTablesProxyModel::setData +176 (int (*)(...))QConcatenateTablesProxyModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QConcatenateTablesProxyModel::itemData +200 (int (*)(...))QConcatenateTablesProxyModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QConcatenateTablesProxyModel::mimeTypes +224 (int (*)(...))QConcatenateTablesProxyModel::mimeData +232 (int (*)(...))QConcatenateTablesProxyModel::canDropMimeData +240 (int (*)(...))QConcatenateTablesProxyModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QConcatenateTablesProxyModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QConcatenateTablesProxyModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QConcatenateTablesProxyModel + size=16 align=8 + base size=16 base align=8 +QConcatenateTablesProxyModel (0x0x7f83318254e0) 0 + vptr=((& QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel) + 16) + QAbstractItemModel (0x0x7f8331825548) 0 + primary-for QConcatenateTablesProxyModel (0x0x7f83318254e0) + QObject (0x0x7f8331857600) 0 + primary-for QAbstractItemModel (0x0x7f8331825548) + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f83318577e0) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f83318579c0) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QFileDevice::fileName +256 (int (*)(...))QFileDevice::resize +264 (int (*)(...))QFileDevice::permissions +272 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f83318255b0) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16) + QIODevice (0x0x7f833187bc40) 0 + primary-for QFileDevice (0x0x7f83318255b0) + QObject (0x0x7f8331857900) 0 + primary-for QIODevice (0x0x7f833187bc40) + QIODeviceBase (0x0x7f8331857960) 0 empty + +Class std::filesystem::space_info + size=24 align=8 + base size=24 base align=8 +std::filesystem::space_info (0x0x7f83314ff6c0) 0 + +Class std::filesystem::__file_clock + size=1 align=1 + base size=0 base align=1 +std::filesystem::__file_clock (0x0x7f8331573c60) 0 empty + +Class std::time_base + size=1 align=1 + base size=0 base align=1 +std::time_base (0x0x7f8331598120) 0 empty + +Class std::money_base::pattern + size=4 align=1 + base size=4 base align=1 +std::money_base::pattern (0x0x7f83315fa420) 0 + +Class std::money_base + size=1 align=1 + base size=0 base align=1 +std::money_base (0x0x7f83315fa3c0) 0 empty + +Class std::messages_base + size=1 align=1 + base size=0 base align=1 +std::messages_base (0x0x7f83316349c0) 0 empty + +Class std::codecvt_base + size=1 align=1 + base size=0 base align=1 +std::codecvt_base (0x0x7f8331686540) 0 empty + +Construction vtable for std::basic_istream<char> (0x0x7f83310cc820 instance) in std::__cxx11::basic_istringstream<char> +std::__cxx11::basic_istringstream<char>::_ZTCNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE0_Si: 10 entries +0 120 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551496 +48 (int (*)(...))-120 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +VTT for std::__cxx11::basic_istringstream<char> +std::__cxx11::basic_istringstream<char>::_ZTTNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE: 4 entries +0 ((& std::__cxx11::basic_istringstream<char>::_ZTVNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE) + 24) +8 ((& std::__cxx11::basic_istringstream<char>::_ZTCNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 24) +16 ((& std::__cxx11::basic_istringstream<char>::_ZTCNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 64) +24 ((& std::__cxx11::basic_istringstream<char>::_ZTVNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE) + 64) + +Construction vtable for std::basic_ostream<char> (0x0x7f83310cca90 instance) in std::__cxx11::basic_ostringstream<char> +std::__cxx11::basic_ostringstream<char>::_ZTCNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE0_So: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::__cxx11::basic_ostringstream<char> +std::__cxx11::basic_ostringstream<char>::_ZTTNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE: 4 entries +0 ((& std::__cxx11::basic_ostringstream<char>::_ZTVNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE) + 24) +8 ((& std::__cxx11::basic_ostringstream<char>::_ZTCNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE0_So) + 24) +16 ((& std::__cxx11::basic_ostringstream<char>::_ZTCNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE0_So) + 64) +24 ((& std::__cxx11::basic_ostringstream<char>::_ZTVNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE) + 64) + +Construction vtable for std::basic_iostream<char> (0x0x7f83313d9d20 instance) in std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd: 15 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISd) +24 0 +32 0 +40 112 +48 (int (*)(...))-16 +56 (int (*)(...))(& _ZTISd) +64 0 +72 0 +80 18446744073709551488 +88 (int (*)(...))-128 +96 (int (*)(...))(& _ZTISd) +104 0 +112 0 + +Construction vtable for std::basic_istream<char> (0x0x7f83310ccd00 instance) in std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Si: 10 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551488 +48 (int (*)(...))-128 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream<char> (0x0x7f83310ccdd0 instance) in std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE16_So: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTTNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE: 10 entries +0 ((& std::__cxx11::basic_stringstream<char>::_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE) + 24) +8 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd) + 24) +16 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 24) +24 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 64) +32 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE16_So) + 24) +40 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE16_So) + 64) +48 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd) + 104) +56 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd) + 64) +64 ((& std::__cxx11::basic_stringstream<char>::_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE) + 104) +72 ((& std::__cxx11::basic_stringstream<char>::_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE) + 64) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f83310ccf70 instance) in std::__cxx11::basic_istringstream<wchar_t> +std::__cxx11::basic_istringstream<wchar_t>::_ZTCNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E: 10 entries +0 120 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551496 +48 (int (*)(...))-120 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::__cxx11::basic_istringstream<wchar_t> +std::__cxx11::basic_istringstream<wchar_t>::_ZTTNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE: 4 entries +0 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTVNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE) + 24) +8 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTCNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 24) +16 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTCNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 64) +24 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTVNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE) + 64) + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f8331176208 instance) in std::__cxx11::basic_ostringstream<wchar_t> +std::__cxx11::basic_ostringstream<wchar_t>::_ZTCNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_ostreamIwS2_E: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::__cxx11::basic_ostringstream<wchar_t> +std::__cxx11::basic_ostringstream<wchar_t>::_ZTTNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE: 4 entries +0 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTVNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE) + 24) +8 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTCNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_ostreamIwS2_E) + 24) +16 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTCNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_ostreamIwS2_E) + 64) +24 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTVNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE) + 64) + +Construction vtable for std::basic_iostream<wchar_t> (0x0x7f833118d0e0 instance) in std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E: 15 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt14basic_iostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 112 +48 (int (*)(...))-16 +56 (int (*)(...))(& _ZTISt14basic_iostreamIwSt11char_traitsIwEE) +64 0 +72 0 +80 18446744073709551488 +88 (int (*)(...))-128 +96 (int (*)(...))(& _ZTISt14basic_iostreamIwSt11char_traitsIwEE) +104 0 +112 0 + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f8331176478 instance) in std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E: 10 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551488 +48 (int (*)(...))-128 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f8331176548 instance) in std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE16_St13basic_ostreamIwS2_E: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTTNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE: 10 entries +0 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE) + 24) +8 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E) + 24) +16 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 24) +24 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 64) +32 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE16_St13basic_ostreamIwS2_E) + 24) +40 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE16_St13basic_ostreamIwS2_E) + 64) +48 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E) + 104) +56 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E) + 64) +64 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE) + 104) +72 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE) + 64) + +Class std::_Resetiosflags + size=4 align=4 + base size=4 base align=4 +std::_Resetiosflags (0x0x7f833110dd80) 0 + +Class std::_Setiosflags + size=4 align=4 + base size=4 base align=4 +std::_Setiosflags (0x0x7f833110df00) 0 + +Class std::_Setbase + size=4 align=4 + base size=4 base align=4 +std::_Setbase (0x0x7f83311b30c0) 0 + +Class std::_Setprecision + size=4 align=4 + base size=4 base align=4 +std::_Setprecision (0x0x7f83311b33c0) 0 + +Class std::_Setw + size=4 align=4 + base size=4 base align=4 +std::_Setw (0x0x7f83311b3540) 0 + +Class std::filesystem::__cxx11::path::__null_terminated + size=1 align=1 + base size=0 base align=1 +std::filesystem::__cxx11::path::__null_terminated (0x0x7f833127b600) 0 empty + +Class std::filesystem::__cxx11::path::_List::_Impl_deleter + size=1 align=1 + base size=0 base align=1 +std::filesystem::__cxx11::path::_List::_Impl_deleter (0x0x7f833127b6c0) 0 empty + +Class std::filesystem::__cxx11::path::_List + size=8 align=8 + base size=8 base align=8 +std::filesystem::__cxx11::path::_List (0x0x7f833127b660) 0 + +Class std::filesystem::__cxx11::path + size=40 align=8 + base size=40 base align=8 +std::filesystem::__cxx11::path (0x0x7f833127b4e0) 0 + +Vtable for std::filesystem::__cxx11::filesystem_error +std::filesystem::__cxx11::filesystem_error::_ZTVNSt10filesystem7__cxx1116filesystem_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt10filesystem7__cxx1116filesystem_errorE) +16 (int (*)(...))std::filesystem::__cxx11::filesystem_error::~filesystem_error +24 (int (*)(...))std::filesystem::__cxx11::filesystem_error::~filesystem_error +32 (int (*)(...))std::filesystem::__cxx11::filesystem_error::what + +Class std::filesystem::__cxx11::filesystem_error + size=48 align=8 + base size=48 base align=8 +std::filesystem::__cxx11::filesystem_error (0x0x7f8330ce4340) 0 + vptr=((& std::filesystem::__cxx11::filesystem_error::_ZTVNSt10filesystem7__cxx1116filesystem_errorE) + 16) + std::system_error (0x0x7f8330ce43a8) 0 + primary-for std::filesystem::__cxx11::filesystem_error (0x0x7f8330ce4340) + std::runtime_error (0x0x7f8330ce4410) 0 + primary-for std::system_error (0x0x7f8330ce43a8) + std::exception (0x0x7f8330cf05a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f8330ce4410) + +Class std::filesystem::__cxx11::path::_Cmpt + size=48 align=8 + base size=48 base align=8 +std::filesystem::__cxx11::path::_Cmpt (0x0x7f8330ce4d68) 0 + std::filesystem::__cxx11::path (0x0x7f8330d4d060) 0 + +Class std::filesystem::__cxx11::path::iterator + size=24 align=8 + base size=17 base align=8 +std::filesystem::__cxx11::path::iterator (0x0x7f8330d6c300) 0 + +Class std::filesystem::file_status + size=8 align=4 + base size=8 base align=4 +std::filesystem::file_status (0x0x7f8330e21ae0) 0 + +Class std::filesystem::__cxx11::directory_entry + size=48 align=8 + base size=41 base align=8 +std::filesystem::__cxx11::directory_entry (0x0x7f8330e6b000) 0 + +Class std::filesystem::__cxx11::__directory_iterator_proxy + size=48 align=8 + base size=48 base align=8 +std::filesystem::__cxx11::__directory_iterator_proxy (0x0x7f8330ab46c0) 0 + +Class std::filesystem::__cxx11::directory_iterator + size=16 align=8 + base size=16 base align=8 +std::filesystem::__cxx11::directory_iterator (0x0x7f8330ab4e40) 0 + +Class std::filesystem::__cxx11::recursive_directory_iterator + size=16 align=8 + base size=16 base align=8 +std::filesystem::__cxx11::recursive_directory_iterator (0x0x7f8330b39f60) 0 + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f8330c2e120) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QFile::fileName +256 (int (*)(...))QFile::resize +264 (int (*)(...))QFile::permissions +272 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f8330c22820) 0 + vptr=((& QFile::_ZTV5QFile) + 16) + QFileDevice (0x0x7f8330c22888) 0 + primary-for QFile (0x0x7f8330c22820) + QIODevice (0x0x7f8330e253f0) 0 + primary-for QFileDevice (0x0x7f8330c22888) + QObject (0x0x7f8330c2e060) 0 + primary-for QIODevice (0x0x7f8330e253f0) + QIODeviceBase (0x0x7f8330c2e0c0) 0 empty + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f8330c2e720) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f833090b0c0) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f83309d07e0) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f83309d0c60) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f83306fd420) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f83306fd660) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f83306c1a28) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16) + QObject (0x0x7f83306fd600) 0 + primary-for QFileSelector (0x0x7f83306c1a28) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f83306fd840) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f83306c1a90) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16) + QObject (0x0x7f83306fd7e0) 0 + primary-for QFileSystemWatcher (0x0x7f83306c1a90) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f8330735000) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f83306c1af8) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16) + QObject (0x0x7f83306fdf60) 0 + primary-for QFutureWatcherBase (0x0x7f83306c1af8) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f8330735540) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QIdentityProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QIdentityProxyModel::insertRows +272 (int (*)(...))QIdentityProxyModel::insertColumns +280 (int (*)(...))QIdentityProxyModel::removeRows +288 (int (*)(...))QIdentityProxyModel::removeColumns +296 (int (*)(...))QIdentityProxyModel::moveRows +304 (int (*)(...))QIdentityProxyModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QAbstractProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QIdentityProxyModel::match +360 (int (*)(...))QAbstractProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QIdentityProxyModel::setSourceModel +416 (int (*)(...))QIdentityProxyModel::mapToSource +424 (int (*)(...))QIdentityProxyModel::mapFromSource +432 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +440 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f83306c1d00) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16) + QAbstractProxyModel (0x0x7f83306c1d68) 0 + primary-for QIdentityProxyModel (0x0x7f83306c1d00) + QAbstractItemModel (0x0x7f83306c1dd0) 0 + primary-for QAbstractProxyModel (0x0x7f83306c1d68) + QObject (0x0x7f83307354e0) 0 + primary-for QAbstractItemModel (0x0x7f83306c1dd0) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f83307356c0) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f83307c6300) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f83307bbbc8) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16) + QObject (0x0x7f83307c62a0) 0 + primary-for QItemSelectionModel (0x0x7f83307bbbc8) + +Class QItemSelection + size=24 align=8 + base size=24 base align=8 +QItemSelection (0x0x7f83308410d0) 0 + QList<QItemSelectionRange> (0x0x7f8330841138) 0 + QListSpecialMethods<QItemSelectionRange> (0x0x7f83308411a0) 0 empty + QListSpecialMethodsBase<QItemSelectionRange> (0x0x7f83307c6d80) 0 empty + +Class QJsonValue + size=24 align=8 + base size=24 base align=8 +QJsonValue (0x0x7f83304d8ea0) 0 + +Class QJsonValueRef + size=16 align=8 + base size=16 base align=8 +QJsonValueRef (0x0x7f833052e3c0) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=16 base align=8 +QJsonArray::iterator (0x0x7f8330573720) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=16 base align=8 +QJsonArray::const_iterator (0x0x7f8330573780) 0 + +Class QJsonArray + size=8 align=8 + base size=8 base align=8 +QJsonArray (0x0x7f83305736c0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f8330624180) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f83306241e0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=16 base align=8 +QJsonObject::iterator (0x0x7f83303b8720) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=16 base align=8 +QJsonObject::const_iterator (0x0x7f83303b8780) 0 + +Class QJsonObject + size=8 align=8 + base size=8 base align=8 +QJsonObject (0x0x7f83303b86c0) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f83304702a0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=24 align=8 + base size=24 base align=8 +QLibrary (0x0x7f8330467a28) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16) + QObject (0x0x7f8330470240) 0 + primary-for QLibrary (0x0x7f8330467a28) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f8330470960) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f8330470900) 0 + +Class QTypeRevision + size=2 align=1 + base size=2 base align=1 +QTypeRevision (0x0x7f8330195120) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f8330229960) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f8330229a20) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f832feb1120) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f832ff05a80) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f832ff740c0) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f832ffc08a0) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f833000a060) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f8330052960) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f832fcee6c0) 0 + +Class QMetaMethod::Data + size=8 align=8 + base size=8 base align=8 +QMetaMethod::Data (0x0x7f832fcee780) 0 + +Class QMetaMethod + size=16 align=8 + base size=16 base align=8 +QMetaMethod (0x0x7f832fcee720) 0 + +Class QMetaEnum::Data + size=8 align=8 + base size=8 base align=8 +QMetaEnum::Data (0x0x7f832fd5b9c0) 0 + +Class QMetaEnum + size=16 align=8 + base size=16 base align=8 +QMetaEnum (0x0x7f832fd5b960) 0 + +Class QMetaProperty::Data + size=8 align=8 + base size=8 base align=8 +QMetaProperty::Data (0x0x7f832fda1720) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f832fda16c0) 0 + +Class QMetaClassInfo::Data + size=8 align=8 + base size=8 base align=8 +QMetaClassInfo::Data (0x0x7f832fda1de0) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=16 base align=8 +QMetaClassInfo (0x0x7f832fda1d80) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f832fde9c00) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f832fdf4548) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16) + QObject (0x0x7f832fde9ba0) 0 + primary-for QMimeData (0x0x7f832fdf4548) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f832fde9d80) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f832fe7a8a0) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f832fe7a960) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=40 align=8 + base size=40 base align=8 +QObjectCleanupHandler (0x0x7f832fe80410) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16) + QObject (0x0x7f832fe7a900) 0 + primary-for QObjectCleanupHandler (0x0x7f832fe80410) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f832fe7aa20) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f832fadb840) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f832fad4e38) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16) + QAnimationGroup (0x0x7f832fad4ea0) 0 + primary-for QParallelAnimationGroup (0x0x7f832fad4e38) + QAbstractAnimation (0x0x7f832fad4f08) 0 + primary-for QAnimationGroup (0x0x7f832fad4ea0) + QObject (0x0x7f832fadb7e0) 0 + primary-for QAbstractAnimation (0x0x7f832fad4f08) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f832fadba20) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f832fad4f70) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16) + QAbstractAnimation (0x0x7f832faf9000) 0 + primary-for QPauseAnimation (0x0x7f832fad4f70) + QObject (0x0x7f832fadb9c0) 0 + primary-for QAbstractAnimation (0x0x7f832faf9000) + +Class QPluginMetaData + size=16 align=8 + base size=16 base align=8 +QPluginMetaData (0x0x7f832fadbc00) 0 + +Class QStaticPlugin + size=24 align=8 + base size=24 base align=8 +QStaticPlugin (0x0x7f832fadbc60) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f832fb2b6c0) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f832fb2ebc8) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16) + QObject (0x0x7f832fb2b660) 0 + primary-for QPluginLoader (0x0x7f832fb2ebc8) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f832fb2b780) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f832fbb9000) 0 empty + +Class QProcess::Use_setChildProcessModifier_Instead + size=1 align=1 + base size=0 base align=1 +QProcess::Use_setChildProcessModifier_Instead (0x0x7f832fbb9060) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 32 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QProcess::writeData +248 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f832fbaac98) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16) + QIODevice (0x0x7f832fae0a80) 0 + primary-for QProcess (0x0x7f832fbaac98) + QObject (0x0x7f832fb9bf00) 0 + primary-for QIODevice (0x0x7f832fae0a80) + QIODeviceBase (0x0x7f832fb9bf60) 0 empty + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f832fbb9de0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f832fbaad00) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16) + QAbstractAnimation (0x0x7f832fbaad68) 0 + primary-for QVariantAnimation (0x0x7f832fbaad00) + QObject (0x0x7f832fbb9d80) 0 + primary-for QAbstractAnimation (0x0x7f832fbaad68) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f832fc11060) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f832fbaae38) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16) + QVariantAnimation (0x0x7f832fbaaea0) 0 + primary-for QPropertyAnimation (0x0x7f832fbaae38) + QAbstractAnimation (0x0x7f832fbaaf08) 0 + primary-for QVariantAnimation (0x0x7f832fbaaea0) + QObject (0x0x7f832fc11000) 0 + primary-for QAbstractAnimation (0x0x7f832fbaaf08) + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f832fc98780) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f832f985c00) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f832f985ba0) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f832f7703c0) 0 + +Class QRandomGenerator::InitialRandomData + size=16 align=8 + base size=16 base align=8 +QRandomGenerator::InitialRandomData (0x0x7f832f58d300) 0 + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f832f58d360) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f832f58d2a0) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f832f5d7bc8) 0 + QRandomGenerator (0x0x7f832f602600) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f832f621240) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f832f621480) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f832f621900) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f832f621d80) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f832f2e7840) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f832f374300) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f832f44c120) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f832f0e2c60) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f832f0e2f60) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QSaveFile::writeData +248 (int (*)(...))QSaveFile::fileName +256 (int (*)(...))QFileDevice::resize +264 (int (*)(...))QFileDevice::permissions +272 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f832f099f08) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16) + QFileDevice (0x0x7f832f099f70) 0 + primary-for QSaveFile (0x0x7f832f099f08) + QIODevice (0x0x7f832f60eaf0) 0 + primary-for QFileDevice (0x0x7f832f099f70) + QObject (0x0x7f832f0e2ea0) 0 + primary-for QIODevice (0x0x7f832f60eaf0) + QIODeviceBase (0x0x7f832f0e2f00) 0 empty + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f832f142300) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f832f168ae0) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f832f1ea840) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f832f1f3b60) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16) + QAnimationGroup (0x0x7f832f1f3bc8) 0 + primary-for QSequentialAnimationGroup (0x0x7f832f1f3b60) + QAbstractAnimation (0x0x7f832f1f3c30) 0 + primary-for QAnimationGroup (0x0x7f832f1f3bc8) + QObject (0x0x7f832f1ea7e0) 0 + primary-for QAbstractAnimation (0x0x7f832f1f3c30) + +Class QSequentialIterator + size=16 align=8 + base size=16 base align=8 +QSequentialIterator (0x0x7f832f1f3d68) 0 + QIterator<QMetaSequence> (0x0x7f832f1f3dd0) 0 + QBaseIterator<QMetaSequence> (0x0x7f832f1eaba0) 0 + +Class QSequentialConstIterator + size=16 align=8 + base size=16 base align=8 +QSequentialConstIterator (0x0x7f832f1f3ea0) 0 + QConstIterator<QMetaSequence> (0x0x7f832f1f3f08) 0 + QBaseIterator<QMetaSequence> (0x0x7f832f23f120) 0 + +Class QSequentialIterable + size=24 align=8 + base size=24 base align=8 +QSequentialIterable (0x0x7f832f1f3f70) 0 + QIterable<QMetaSequence> (0x0x7f832f23f660) 0 + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f832ef20c60) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f832ef313a8) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16) + QObject (0x0x7f832ef20c00) 0 + primary-for QSettings (0x0x7f832ef313a8) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f832ef5e0c0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f832ef31410) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16) + QObject (0x0x7f832ef5e060) 0 + primary-for QSharedMemory (0x0x7f832ef31410) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f832ef5e2a0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f832ef31478) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16) + QObject (0x0x7f832ef5e240) 0 + primary-for QSignalMapper (0x0x7f832ef31478) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f833589cea0) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f833925e340) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16) + QObject (0x0x7f833589ce40) 0 + primary-for QSocketNotifier (0x0x7f833925e340) + +Class QSocketDescriptor + size=4 align=4 + base size=4 base align=4 +QSocketDescriptor (0x0x7f8334865060) 0 + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f83341179c0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 59 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QSortFilterProxyModel::mimeTypes +224 (int (*)(...))QSortFilterProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QSortFilterProxyModel::dropMimeData +248 (int (*)(...))QSortFilterProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QSortFilterProxyModel::insertRows +272 (int (*)(...))QSortFilterProxyModel::insertColumns +280 (int (*)(...))QSortFilterProxyModel::removeRows +288 (int (*)(...))QSortFilterProxyModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QSortFilterProxyModel::fetchMore +320 (int (*)(...))QSortFilterProxyModel::canFetchMore +328 (int (*)(...))QSortFilterProxyModel::flags +336 (int (*)(...))QSortFilterProxyModel::sort +344 (int (*)(...))QSortFilterProxyModel::buddy +352 (int (*)(...))QSortFilterProxyModel::match +360 (int (*)(...))QSortFilterProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QSortFilterProxyModel::setSourceModel +416 (int (*)(...))QSortFilterProxyModel::mapToSource +424 (int (*)(...))QSortFilterProxyModel::mapFromSource +432 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +440 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +448 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +456 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +464 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f8339892410) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16) + QAbstractProxyModel (0x0x7f8339892680) 0 + primary-for QSortFilterProxyModel (0x0x7f8339892410) + QAbstractItemModel (0x0x7f83395634e0) 0 + primary-for QAbstractProxyModel (0x0x7f8339892680) + QObject (0x0x7f8334117960) 0 + primary-for QAbstractItemModel (0x0x7f83395634e0) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f8334117d80) 0 empty + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f8333fe6780) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f83335b7000) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f83330a8840) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QStringListModel::itemData +200 (int (*)(...))QStringListModel::setItemData +208 (int (*)(...))QStringListModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractListModel::dropMimeData +248 (int (*)(...))QStringListModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QStringListModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QStringListModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QStringListModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QStringListModel::flags +336 (int (*)(...))QStringListModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QStringListModel + size=40 align=8 + base size=40 base align=8 +QStringListModel (0x0x7f83390ce548) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16) + QAbstractListModel (0x0x7f83390ce5b0) 0 + primary-for QStringListModel (0x0x7f83390ce548) + QAbstractItemModel (0x0x7f83390ce680) 0 + primary-for QAbstractListModel (0x0x7f83390ce5b0) + QObject (0x0x7f83330a87e0) 0 + primary-for QAbstractItemModel (0x0x7f83390ce680) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f83330a8900) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f83330a8a20) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f83330a8ba0) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QTemporaryFile::fileName +256 (int (*)(...))QFile::resize +264 (int (*)(...))QFile::permissions +272 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f83390ce6e8) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16) + QFile (0x0x7f83390ce820) 0 + primary-for QTemporaryFile (0x0x7f83390ce6e8) + QFileDevice (0x0x7f83390ce9c0) 0 + primary-for QFile (0x0x7f83390ce820) + QIODevice (0x0x7f8339641bd0) 0 + primary-for QFileDevice (0x0x7f83390ce9c0) + QObject (0x0x7f83330a8ae0) 0 + primary-for QIODevice (0x0x7f8339641bd0) + QIODeviceBase (0x0x7f83330a8b40) 0 empty + +Class QTextBoundaryFinder + size=72 align=8 + base size=72 base align=8 +QTextBoundaryFinder (0x0x7f83330a8de0) 0 + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f8332cbd480) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f8332cbdb40) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f83390cec98) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16) + QObject (0x0x7f8332cbdae0) 0 + primary-for QTimeLine (0x0x7f83390cec98) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f8332cbdd20) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=16 align=8 + base size=16 base align=8 +QTimer (0x0x7f83390ced00) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16) + QObject (0x0x7f8332cbdcc0) 0 + primary-for QTimer (0x0x7f83390ced00) + +Class QTimeZone::OffsetData + size=48 align=8 + base size=44 base align=8 +QTimeZone::OffsetData (0x0x7f8332e576c0) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f8332e57660) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f8332c76720) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f833913e820) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16) + QObject (0x0x7f8332c766c0) 0 + primary-for QTranslator (0x0x7f833913e820) + +Class QTransposeProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTransposeProxyModel::QPrivateSignal (0x0x7f8332c76900) 0 empty + +Vtable for QTransposeProxyModel +QTransposeProxyModel::_ZTV20QTransposeProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTransposeProxyModel) +16 (int (*)(...))QTransposeProxyModel::metaObject +24 (int (*)(...))QTransposeProxyModel::qt_metacast +32 (int (*)(...))QTransposeProxyModel::qt_metacall +40 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +48 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTransposeProxyModel::index +120 (int (*)(...))QTransposeProxyModel::parent +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))QTransposeProxyModel::rowCount +144 (int (*)(...))QTransposeProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QTransposeProxyModel::headerData +184 (int (*)(...))QTransposeProxyModel::setHeaderData +192 (int (*)(...))QTransposeProxyModel::itemData +200 (int (*)(...))QTransposeProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QAbstractProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QTransposeProxyModel::insertRows +272 (int (*)(...))QTransposeProxyModel::insertColumns +280 (int (*)(...))QTransposeProxyModel::removeRows +288 (int (*)(...))QTransposeProxyModel::removeColumns +296 (int (*)(...))QTransposeProxyModel::moveRows +304 (int (*)(...))QTransposeProxyModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QTransposeProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QTransposeProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QTransposeProxyModel::setSourceModel +416 (int (*)(...))QTransposeProxyModel::mapToSource +424 (int (*)(...))QTransposeProxyModel::mapFromSource +432 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +440 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QTransposeProxyModel + size=16 align=8 + base size=16 base align=8 +QTransposeProxyModel (0x0x7f833913e888) 0 + vptr=((& QTransposeProxyModel::_ZTV20QTransposeProxyModel) + 16) + QAbstractProxyModel (0x0x7f833913e958) 0 + primary-for QTransposeProxyModel (0x0x7f833913e888) + QAbstractItemModel (0x0x7f833913e9c0) 0 + primary-for QAbstractProxyModel (0x0x7f833913e958) + QObject (0x0x7f8332c768a0) 0 + primary-for QAbstractItemModel (0x0x7f833913e9c0) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f8332c76a80) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f8330eaf300) 0 + +Class QtPrivate::QXmlString + size=24 align=8 + base size=24 base align=8 +QtPrivate::QXmlString (0x0x7f8330eaf420) 0 + +Class QXmlStreamAttribute + size=104 align=8 + base size=97 base align=8 +QXmlStreamAttribute (0x0x7f8330e6c240) 0 + +Class QXmlStreamAttributes + size=24 align=8 + base size=24 base align=8 +QXmlStreamAttributes (0x0x7f8338f19618) 0 + QList<QXmlStreamAttribute> (0x0x7f8338f195b0) 0 + QListSpecialMethods<QXmlStreamAttribute> (0x0x7f8338f196e8) 0 empty + QListSpecialMethodsBase<QXmlStreamAttribute> (0x0x7f8330915360) 0 empty + +Class QXmlStreamNamespaceDeclaration + size=48 align=8 + base size=48 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f8330915c00) 0 + +Class QXmlStreamNotationDeclaration + size=72 align=8 + base size=72 base align=8 +QXmlStreamNotationDeclaration (0x0x7f83303f22a0) 0 + +Class QXmlStreamEntityDeclaration + size=120 align=8 + base size=120 base align=8 +QXmlStreamEntityDeclaration (0x0x7f833041c900) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f83302540c0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f8330254120) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f83302546c0) 0 + +Class QAbstractItemModelTester::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModelTester::QPrivateSignal (0x0x7f8330254900) 0 empty + +Vtable for QAbstractItemModelTester +QAbstractItemModelTester::_ZTV24QAbstractItemModelTester: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractItemModelTester) +16 (int (*)(...))QAbstractItemModelTester::metaObject +24 (int (*)(...))QAbstractItemModelTester::qt_metacast +32 (int (*)(...))QAbstractItemModelTester::qt_metacall +40 (int (*)(...))QAbstractItemModelTester::~QAbstractItemModelTester +48 (int (*)(...))QAbstractItemModelTester::~QAbstractItemModelTester +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QAbstractItemModelTester + size=16 align=8 + base size=16 base align=8 +QAbstractItemModelTester (0x0x7f8338f29d68) 0 + vptr=((& QAbstractItemModelTester::_ZTV24QAbstractItemModelTester) + 16) + QObject (0x0x7f83302548a0) 0 + primary-for QAbstractItemModelTester (0x0x7f8338f29d68) + +Class QTest::QBenchmarkIterationController + size=4 align=4 + base size=4 base align=4 +QTest::QBenchmarkIterationController (0x0x7f8330254ae0) 0 + +Class QTestEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTestEventLoop::QPrivateSignal (0x0x7f8330254ba0) 0 empty + +Vtable for QTestEventLoop +QTestEventLoop::_ZTV14QTestEventLoop: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTestEventLoop) +16 (int (*)(...))QTestEventLoop::metaObject +24 (int (*)(...))QTestEventLoop::qt_metacast +32 (int (*)(...))QTestEventLoop::qt_metacall +40 (int (*)(...))QTestEventLoop::~QTestEventLoop +48 (int (*)(...))QTestEventLoop::~QTestEventLoop +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTestEventLoop::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTestEventLoop + size=32 align=8 + base size=32 base align=8 +QTestEventLoop (0x0x7f8338f29dd0) 0 + vptr=((& QTestEventLoop::_ZTV14QTestEventLoop) + 16) + QObject (0x0x7f8330254b40) 0 + primary-for QTestEventLoop (0x0x7f8338f29dd0) + +Vtable for QSignalSpy +QSignalSpy::_ZTV10QSignalSpy: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSignalSpy) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QSignalSpy::qt_metacall +40 (int (*)(...))QSignalSpy::~QSignalSpy +48 (int (*)(...))QSignalSpy::~QSignalSpy +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalSpy + size=128 align=8 + base size=121 base align=8 +QSignalSpy (0x0x7f8336a44310) 0 + vptr=((& QSignalSpy::_ZTV10QSignalSpy) + 16) + QObject (0x0x7f832f3686c0) 0 + primary-for QSignalSpy (0x0x7f8336a44310) + QList<QList<QVariant> > (0x0x7f8338f2f208) 16 + QListSpecialMethods<QList<QVariant> > (0x0x7f8338f2f270) 16 empty + QListSpecialMethodsBase<QList<QVariant> > (0x0x7f832f368720) 16 empty + +Class QTestData + size=8 align=8 + base size=8 base align=8 +QTestData (0x0x7f8339246720) 0 + +Class QTest::Internal::QCborValueFormatter + size=1 align=1 + base size=0 base align=1 +QTest::Internal::QCborValueFormatter (0x0x7f833894d540) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f83316bda20) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f83316bdd80) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f83316bdf00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f8330dea300) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f8330dea4e0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f8330dea840) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f8330dea9c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f8330dead20) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f8330deaf00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f83303622a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f8330362480) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f83303627e0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f83303629c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f8330362d20) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f8330362f00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f832fd4d2a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f832f481b40) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f832f481ea0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f8334fdd060) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f8334fdd3c0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f8334fdd540) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f8334fdd8a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f8334fdda20) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f8334fddd80) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f8334fddf00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f8334e3e2a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f8334e3e420) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f8334e3e780) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f8334e3e900) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f8334e3ec60) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f8334e3ede0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f83380c8180) 0 empty + diff --git a/tests/auto/bic/data/QtQuickWidgets.6.2.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuickWidgets.6.2.0.linux-gcc-amd64.txt new file mode 100644 index 00000000000..a2d85a47ffe --- /dev/null +++ b/tests/auto/bic/data/QtQuickWidgets.6.2.0.linux-gcc-amd64.txt @@ -0,0 +1,23057 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7fc67a99ccc0) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7fc67a6544e0) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7fc67a654720) 0 empty + +Class std::__do_is_implicitly_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_implicitly_default_constructible_impl (0x0x7fc67a685840) 0 empty + +Class std::__make_unsigned_selector_base + size=1 align=1 + base size=0 base align=1 +std::__make_unsigned_selector_base (0x0x7fc67a6de060) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7fc67a72ee40) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7fc67a72ef00) 0 empty + +Class std::__invoke_memfun_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_ref (0x0x7fc67a75e420) 0 empty + +Class std::__invoke_memfun_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_deref (0x0x7fc67a75e480) 0 empty + +Class std::__invoke_memobj_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_ref (0x0x7fc67a75e4e0) 0 empty + +Class std::__invoke_memobj_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_deref (0x0x7fc67a75e540) 0 empty + +Class std::__invoke_other + size=1 align=1 + base size=0 base align=1 +std::__invoke_other (0x0x7fc67a75e5a0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7fc67a75e660) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7fc67a75e720) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7fc67a75e7e0) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7fc67a75e8a0) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7fc67a75ec00) 0 empty + +Class std::__swappable_details::__do_is_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_swappable_impl (0x0x7fc67a75ef60) 0 empty + +Class std::__swappable_details::__do_is_nothrow_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_nothrow_swappable_impl (0x0x7fc67a7ad000) 0 empty + +Class std::__swappable_with_details::__do_is_swappable_with_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_with_details::__do_is_swappable_with_impl (0x0x7fc67a7ad2a0) 0 empty + +Class std::__swappable_with_details::__do_is_nothrow_swappable_with_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_with_details::__do_is_nothrow_swappable_with_impl (0x0x7fc67a7ad300) 0 empty + +Class std::__nonesuch + size=1 align=1 + base size=0 base align=1 +std::__nonesuch (0x0x7fc67a7adb40) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7fc677c28120) 0 empty + +Class std::__nonesuch_no_braces + size=1 align=1 + base size=1 base align=1 +std::__nonesuch_no_braces (0x0x7fc677c1e068) 0 empty + std::__nonesuch (0x0x7fc677c28600) 0 empty + +Class std::in_place_t + size=1 align=1 + base size=0 base align=1 +std::in_place_t (0x0x7fc677ca9360) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7fc677ca9660) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7fc677ca96c0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7fc677d0a420) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7fc677d0a480) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7fc677c1e5b0) 0 empty + std::input_iterator_tag (0x0x7fc677d0a4e0) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7fc677c1e618) 0 empty + std::forward_iterator_tag (0x0x7fc677c1e680) 0 empty + std::input_iterator_tag (0x0x7fc677d0a540) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7fc677c1e6e8) 0 empty + std::bidirectional_iterator_tag (0x0x7fc677c1e750) 0 empty + std::forward_iterator_tag (0x0x7fc677c1e7b8) 0 empty + std::input_iterator_tag (0x0x7fc677d0a5a0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7fc6779c22a0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7fc6779c23c0) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7fc6779c26c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7fc6779c29c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7fc6779c2ae0) 0 empty + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7fc677a85300) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7fc677a85600) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7fc677a85660) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7fc677a85720) 0 + +Class __pthread_internal_slist + size=8 align=8 + base size=8 base align=8 +__pthread_internal_slist (0x0x7fc677a85780) 0 + +Class __pthread_mutex_s + size=40 align=8 + base size=40 base align=8 +__pthread_mutex_s (0x0x7fc677a857e0) 0 + +Class __pthread_rwlock_arch_t + size=56 align=8 + base size=56 base align=8 +__pthread_rwlock_arch_t (0x0x7fc677a85840) 0 + +Class __pthread_cond_s + size=48 align=8 + base size=48 base align=8 +__pthread_cond_s (0x0x7fc677a858a0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7fc677a85b40) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7fc677a85de0) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7fc677a85e40) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7fc677adac00) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7fc677c1eb60) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16) + std::exception (0x0x7fc677adade0) 0 nearly-empty + primary-for std::bad_exception (0x0x7fc677c1eb60) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7fc677b7d000) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7fc677c1ebc8) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16) + std::exception (0x0x7fc677b7d3c0) 0 nearly-empty + primary-for std::bad_cast (0x0x7fc677c1ebc8) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7fc677c1ec30) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16) + std::exception (0x0x7fc677b7d5a0) 0 nearly-empty + primary-for std::bad_typeid (0x0x7fc677c1ec30) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7fc677b7d780) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7fc677b7dcc0) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7fc677c1ec98) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16) + std::exception (0x0x7fc677bb13c0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fc677c1ec98) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7fc677c1ed00) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16) + std::bad_alloc (0x0x7fc677c1ed68) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7fc677c1ed00) + std::exception (0x0x7fc677bb15a0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fc677c1ed68) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7fc677bb1780) 0 empty + +Class std::__allocator_traits_base + size=1 align=1 + base size=0 base align=1 +std::__allocator_traits_base (0x0x7fc677bb19c0) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7fc677864180) 0 empty + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7fc67744e540) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7fc67744e600) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7fc6774bb4e0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7fc6774bb5a0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7fc6774bb600) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7fc6774bb660) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7fc6774bb6c0) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7fc6774bb7e0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7fc6774bb840) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7fc67754dea0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7fc677573060) 0 empty + +Class _G_fpos_t + size=16 align=8 + base size=16 base align=8 +_G_fpos_t (0x0x7fc67735fea0) 0 + +Class _G_fpos64_t + size=16 align=8 + base size=16 base align=8 +_G_fpos64_t (0x0x7fc67735ff00) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7fc67735ff60) 0 + +Class _IO_cookie_io_functions_t + size=32 align=8 + base size=32 base align=8 +_IO_cookie_io_functions_t (0x0x7fc67739e000) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7fc676fbc780) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7fc676f50d00) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16) + std::exception (0x0x7fc676fbc840) 0 nearly-empty + primary-for std::logic_error (0x0x7fc676f50d00) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7fc676f50d68) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16) + std::logic_error (0x0x7fc676f50dd0) 0 + primary-for std::domain_error (0x0x7fc676f50d68) + std::exception (0x0x7fc676fbc8a0) 0 nearly-empty + primary-for std::logic_error (0x0x7fc676f50dd0) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7fc676f50e38) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16) + std::logic_error (0x0x7fc676f50ea0) 0 + primary-for std::invalid_argument (0x0x7fc676f50e38) + std::exception (0x0x7fc676fbc900) 0 nearly-empty + primary-for std::logic_error (0x0x7fc676f50ea0) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7fc676f50f08) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16) + std::logic_error (0x0x7fc676f50f70) 0 + primary-for std::length_error (0x0x7fc676f50f08) + std::exception (0x0x7fc676fbc960) 0 nearly-empty + primary-for std::logic_error (0x0x7fc676f50f70) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7fc676bfe000) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16) + std::logic_error (0x0x7fc676bfe068) 0 + primary-for std::out_of_range (0x0x7fc676bfe000) + std::exception (0x0x7fc676fbc9c0) 0 nearly-empty + primary-for std::logic_error (0x0x7fc676bfe068) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7fc676bfe0d0) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16) + std::exception (0x0x7fc676fbca20) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc676bfe0d0) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7fc676bfe138) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16) + std::runtime_error (0x0x7fc676bfe1a0) 0 + primary-for std::range_error (0x0x7fc676bfe138) + std::exception (0x0x7fc676fbca80) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc676bfe1a0) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7fc676bfe208) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16) + std::runtime_error (0x0x7fc676bfe270) 0 + primary-for std::overflow_error (0x0x7fc676bfe208) + std::exception (0x0x7fc676fbcae0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc676bfe270) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7fc676bfe2d8) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16) + std::runtime_error (0x0x7fc676bfe340) 0 + primary-for std::underflow_error (0x0x7fc676bfe2d8) + std::exception (0x0x7fc676fbcb40) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc676bfe340) + +Class std::__erased_type + size=1 align=1 + base size=0 base align=1 +std::__erased_type (0x0x7fc676c37e40) 0 empty + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7fc676c37ea0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7fc676c5b060) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7fc676c5b120) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7fc676bfe5b0) 0 + std::__uses_alloc_base (0x0x7fc676c5b0c0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7fc6769cd720) 0 empty + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7fc676a569c0) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16) + std::exception (0x0x7fc676a6bde0) 0 nearly-empty + primary-for std::bad_function_call (0x0x7fc676a569c0) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7fc676a6bea0) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7fc676a6bf00) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7fc676a9d240) 0 + +Class std::__detail::_Identity + size=1 align=1 + base size=0 base align=1 +std::__detail::_Identity (0x0x7fc676b6f0c0) 0 empty + +Class std::__detail::_Select1st + size=1 align=1 + base size=0 base align=1 +std::__detail::_Select1st (0x0x7fc676b6f180) 0 empty + +Class std::__detail::_Hash_node_base + size=8 align=8 + base size=8 base align=8 +std::__detail::_Hash_node_base (0x0x7fc676b6f660) 0 + +Class std::__detail::_Mod_range_hashing + size=1 align=1 + base size=0 base align=1 +std::__detail::_Mod_range_hashing (0x0x7fc676b974e0) 0 empty + +Class std::__detail::_Default_ranged_hash + size=1 align=1 + base size=0 base align=1 +std::__detail::_Default_ranged_hash (0x0x7fc676b975a0) 0 empty + +Class std::__detail::_Prime_rehash_policy + size=16 align=8 + base size=16 base align=8 +std::__detail::_Prime_rehash_policy (0x0x7fc676b97600) 0 + +Class std::__detail::_Mask_range_hashing + size=1 align=1 + base size=0 base align=1 +std::__detail::_Mask_range_hashing (0x0x7fc676b979c0) 0 empty + +Class std::__detail::_Power2_rehash_policy + size=16 align=8 + base size=16 base align=8 +std::__detail::_Power2_rehash_policy (0x0x7fc676b97ae0) 0 + +Class std::__detail::_Equality_base + size=1 align=1 + base size=0 base align=1 +std::__detail::_Equality_base (0x0x7fc676977ba0) 0 empty + +Class std::_Enable_default_constructor_tag + size=1 align=1 + base size=0 base align=1 +std::_Enable_default_constructor_tag (0x0x7fc6769b1480) 0 empty + +Class std::nullopt_t + size=1 align=1 + base size=0 base align=1 +std::nullopt_t (0x0x7fc6769b1e40) 0 empty + +Vtable for std::bad_optional_access +std::bad_optional_access::_ZTVSt19bad_optional_access: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt19bad_optional_access) +16 (int (*)(...))std::bad_optional_access::~bad_optional_access +24 (int (*)(...))std::bad_optional_access::~bad_optional_access +32 (int (*)(...))std::bad_optional_access::what + +Class std::bad_optional_access + size=8 align=8 + base size=8 base align=8 +std::bad_optional_access (0x0x7fc6769a58f0) 0 nearly-empty + vptr=((& std::bad_optional_access::_ZTVSt19bad_optional_access) + 16) + std::exception (0x0x7fc6765ff0c0) 0 nearly-empty + primary-for std::bad_optional_access (0x0x7fc6769a58f0) + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7fc676095a20) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7fc67638e410) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7fc6760bc1e0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7fc67638e4e0) 0 + std::_Bit_iterator_base (0x0x7fc67638e548) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7fc6760bc780) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7fc67638e618) 0 + std::_Bit_iterator_base (0x0x7fc67638e680) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7fc6760bcf60) 0 empty + +Class __pstl::execution::v1::sequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::sequenced_policy (0x0x7fc675ed2480) 0 empty + +Class __pstl::execution::v1::parallel_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::parallel_policy (0x0x7fc675ed2600) 0 empty + +Class __pstl::execution::v1::parallel_unsequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::parallel_unsequenced_policy (0x0x7fc675ed2780) 0 empty + +Class __pstl::execution::v1::unsequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::unsequenced_policy (0x0x7fc675ed2900) 0 empty + +Class std::__detail::__variant::__variant_cookie + size=1 align=1 + base size=0 base align=1 +std::__detail::__variant::__variant_cookie (0x0x7fc675c09480) 0 empty + +Class std::__detail::__variant::__variant_idx_cookie + size=1 align=1 + base size=0 base align=1 +std::__detail::__variant::__variant_idx_cookie (0x0x7fc675c094e0) 0 empty + +Class std::monostate + size=1 align=1 + base size=0 base align=1 +std::monostate (0x0x7fc675c8ff60) 0 empty + +Vtable for std::bad_variant_access +std::bad_variant_access::_ZTVSt18bad_variant_access: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt18bad_variant_access) +16 (int (*)(...))std::bad_variant_access::~bad_variant_access +24 (int (*)(...))std::bad_variant_access::~bad_variant_access +32 (int (*)(...))std::bad_variant_access::what + +Class std::bad_variant_access + size=16 align=8 + base size=16 base align=8 +std::bad_variant_access (0x0x7fc675c06a28) 0 + vptr=((& std::bad_variant_access::_ZTVSt18bad_variant_access) + 16) + std::exception (0x0x7fc675d024e0) 0 nearly-empty + primary-for std::bad_variant_access (0x0x7fc675c06a28) + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7fc675d87f00) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7fc675d87f60) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7fc6759d6240) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7fc6759d6a80) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7fc675a1bb40) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7fc675ab2de0) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7fc675a4ed00) 0 + std::__atomic_flag_base (0x0x7fc675ab2e40) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7fc67567a000) 0 + QAtomicInteger<int> (0x0x7fc67567a068) 0 + QBasicAtomicInteger<int> (0x0x7fc67562fd80) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7fc674ed9060) 0 empty + +Class QKeyCombination + size=4 align=4 + base size=4 base align=4 +QKeyCombination (0x0x7fc674ed90c0) 0 + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7fc674f9d3c0) 0 + +Class QMethodRawArguments + size=8 align=8 + base size=8 base align=8 +QMethodRawArguments (0x0x7fc674f9dae0) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7fc674f9db40) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7fc674f91478) 0 + QGenericArgument (0x0x7fc674f9dde0) 0 + +Class QMetaObject::SuperData + size=8 align=8 + base size=8 base align=8 +QMetaObject::SuperData (0x0x7fc674bd5300) 0 + +Class QMetaObject::Data + size=56 align=8 + base size=56 base align=8 +QMetaObject::Data (0x0x7fc674bd5360) 0 + +Class QMetaObject + size=56 align=8 + base size=56 base align=8 +QMetaObject (0x0x7fc674bd52a0) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7fc674bd5cc0) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7fc674c4d720) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7fc674c76120) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7fc674d2cc00) 0 + +Class QArrayData + size=16 align=8 + base size=16 base align=8 +QArrayData (0x0x7fc674d2cf60) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7fc6749e3a20) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7fc6749e3b40) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7fc6749e3f00) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7fc674a2e1e0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7fc674a2e3c0) 0 + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7fc674a754e0) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7fc674a75840) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7fc674ab3060) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7fc6749ff958) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16) + std::runtime_error (0x0x7fc6749ff9c0) 0 + primary-for std::system_error (0x0x7fc6749ff958) + std::exception (0x0x7fc674ab3c00) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc6749ff9c0) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7fc6749ffd00) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16) + std::system_error (0x0x7fc6749ffd68) 0 + primary-for std::ios_base::failure (0x0x7fc6749ffd00) + std::runtime_error (0x0x7fc6749ffdd0) 0 + primary-for std::system_error (0x0x7fc6749ffd68) + std::exception (0x0x7fc674b153c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc6749ffdd0) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7fc674b15420) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7fc674b15480) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7fc674b154e0) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7fc674b15360) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7fc6747cd120) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7fc67489f420) 0 empty + +VTT for std::basic_ostream<char> +std::basic_ostream<char>::_ZTTSo: 2 entries +0 ((& std::basic_ostream<char>::_ZTVSo) + 24) +8 ((& std::basic_ostream<char>::_ZTVSo) + 64) + +VTT for std::basic_ostream<wchar_t> +std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64) + +VTT for std::basic_istream<char> +std::basic_istream<char>::_ZTTSi: 2 entries +0 ((& std::basic_istream<char>::_ZTVSi) + 24) +8 ((& std::basic_istream<char>::_ZTVSi) + 64) + +VTT for std::basic_istream<wchar_t> +std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64) + +Construction vtable for std::basic_istream<char> (0x0x7fc6743e3958 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd0_Si: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream<char> (0x0x7fc6743e3a28 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd16_So: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::basic_iostream<char> +std::basic_iostream<char>::_ZTTSd: 7 entries +0 ((& std::basic_iostream<char>::_ZTVSd) + 24) +8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24) +16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64) +24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24) +32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64) +40 ((& std::basic_iostream<char>::_ZTVSd) + 104) +48 ((& std::basic_iostream<char>::_ZTVSd) + 64) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7fc6743e3f70 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7fc6743e3b60 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7 entries +0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24) +16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64) +24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24) +32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64) +40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104) +48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64) + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7fc6744554e0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16) + std::exception (0x0x7fc67443ade0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7fc6744554e0) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7fc674455548) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16) + std::exception (0x0x7fc67443af00) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7fc674455548) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7fc6744555b0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16) + std::exception (0x0x7fc67447a060) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7fc6744555b0) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7fc674455680) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16) + std::exception (0x0x7fc67447a180) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7fc674455680) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7fc67447aa20) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7fc67447ad80) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7fc6744a1060) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7fc6744a13c0) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7fc6744557b8) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16) + std::exception (0x0x7fc674525ba0) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7fc6744557b8) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7fc674598960) 0 empty + +Class std::__sp_array_delete + size=1 align=1 + base size=0 base align=1 +std::__sp_array_delete (0x0x7fc674598ea0) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7fc6742d1cc0) 0 + +Class QByteArrayView + size=16 align=8 + base size=16 base align=8 +QByteArrayView (0x0x7fc674068060) 0 + +Class QByteArray + size=24 align=8 + base size=24 base align=8 +QByteArray (0x0x7fc67415b180) 0 + +Class QByteArray::FromBase64Result + size=32 align=8 + base size=28 base align=8 +QByteArray::FromBase64Result (0x0x7fc673fa3540) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7fc673c3a4e0) 0 + +Class QChar::fromUcs4(char32_t)::R + size=4 align=2 + base size=4 base align=2 +QChar::fromUcs4(char32_t)::R (0x0x7fc673db4420) 0 + +Class QtPrivate::hide_char8_t + size=1 align=1 + base size=0 base align=1 +QtPrivate::hide_char8_t (0x0x7fc673db4840) 0 empty + +Class QtPrivate::wrap_char + size=1 align=1 + base size=0 base align=1 +QtPrivate::wrap_char (0x0x7fc673db48a0) 0 empty + +Class QAnyStringView + size=16 align=8 + base size=16 base align=8 +QAnyStringView (0x0x7fc673a3d600) 0 + +Class QStringTokenizerBaseBase::tokenizer_state + size=24 align=8 + base size=24 base align=8 +QStringTokenizerBaseBase::tokenizer_state (0x0x7fc673b277e0) 0 + +Class QStringTokenizerBaseBase + size=8 align=4 + base size=8 base align=4 +QStringTokenizerBaseBase (0x0x7fc673b27780) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7fc673b706c0) 0 + +Class QString + size=24 align=8 + base size=24 base align=8 +QString (0x0x7fc6738e1960) 0 + +Class QtPrivate::ArgBase + size=1 align=1 + base size=1 base align=1 +QtPrivate::ArgBase (0x0x7fc6734d3c60) 0 + +Class QtPrivate::QStringViewArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QStringViewArg (0x0x7fc6734d9548) 0 + QtPrivate::ArgBase (0x0x7fc6734d3cc0) 0 + +Class QtPrivate::QLatin1StringArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QLatin1StringArg (0x0x7fc6734d9618) 0 + QtPrivate::ArgBase (0x0x7fc6734d3f00) 0 + +Class QHashSeed + size=8 align=8 + base size=8 base align=8 +QHashSeed (0x0x7fc673541780) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7fc67357f720) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7fc67357f7e0) 0 empty + +Class QStringMatcher + size=312 align=8 + base size=312 base align=8 +QStringMatcher (0x0x7fc67338ccc0) 0 + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7fc672fc5ea0) 0 empty + +Class QtPrivate::CompareAgainstLiteralZero + size=1 align=1 + base size=0 base align=1 +QtPrivate::CompareAgainstLiteralZero (0x0x7fc673052ba0) 0 empty + +Class QPartialOrdering + size=1 align=1 + base size=1 base align=1 +QPartialOrdering (0x0x7fc673052de0) 0 + +Class QIODeviceBase + size=1 align=1 + base size=0 base align=1 +QIODeviceBase (0x0x7fc673100900) 0 empty + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7fc672ff11a0) 0 + QIODeviceBase (0x0x7fc673100960) 0 empty + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7fc673100ae0) 0 + +Class QtMetaContainerPrivate::QMetaContainerInterface + size=120 align=8 + base size=120 base align=8 +QtMetaContainerPrivate::QMetaContainerInterface (0x0x7fc672e360c0) 0 + +Class QtMetaContainerPrivate::QMetaSequenceInterface + size=216 align=8 + base size=216 base align=8 +QtMetaContainerPrivate::QMetaSequenceInterface (0x0x7fc672ff1af8) 0 + QtMetaContainerPrivate::QMetaContainerInterface (0x0x7fc672e36180) 0 + +Class QtMetaContainerPrivate::QMetaAssociationInterface + size=240 align=8 + base size=240 base align=8 +QtMetaContainerPrivate::QMetaAssociationInterface (0x0x7fc672ff1bc8) 0 + QtMetaContainerPrivate::QMetaContainerInterface (0x0x7fc672e36240) 0 + +Class QMetaContainer + size=8 align=8 + base size=8 base align=8 +QMetaContainer (0x0x7fc672ed6d20) 0 + +Class QMetaSequence + size=8 align=8 + base size=8 base align=8 +QMetaSequence (0x0x7fc672ff1f70) 0 + QMetaContainer (0x0x7fc672ed6f00) 0 + +Class QMetaAssociation + size=8 align=8 + base size=8 base align=8 +QMetaAssociation (0x0x7fc672ff1068) 0 + QMetaContainer (0x0x7fc672ef6300) 0 + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7fc672bf74e0) 0 + +Class std::__detail::_List_node_header + size=24 align=8 + base size=24 base align=8 +std::__detail::_List_node_header (0x0x7fc672f86f08) 0 + std::__detail::_List_node_base (0x0x7fc672bf7540) 0 + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7fc672ccf600) 0 + +Class std::_Rb_tree_header + size=40 align=8 + base size=40 base align=8 +std::_Rb_tree_header (0x0x7fc672ccf960) 0 + +Class QtPrivate::QMetaTypeInterface + size=112 align=8 + base size=112 base align=8 +QtPrivate::QMetaTypeInterface (0x0x7fc672b39de0) 0 + +Class QMetaType + size=8 align=8 + base size=8 base align=8 +QMetaType (0x0x7fc672b67000) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7fc672820060) 0 + +Class QtPrivate::QTypeNormalizer + size=16 align=8 + base size=16 base align=8 +QtPrivate::QTypeNormalizer (0x0x7fc6726fb900) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7fc6722f0c00) 0 + +Class QAdoptSharedDataTag + size=1 align=1 + base size=0 base align=1 +QAdoptSharedDataTag (0x0x7fc6722f0f60) 0 empty + +Class QtPrivate::RefCounted + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCounted (0x0x7fc67237c000) 0 + +Class QPropertyBindingPrivatePtr + size=8 align=8 + base size=8 base align=8 +QPropertyBindingPrivatePtr (0x0x7fc67237c120) 0 + +Class QUntypedPropertyData::InheritsQUntypedPropertyData + size=1 align=1 + base size=0 base align=1 +QUntypedPropertyData::InheritsQUntypedPropertyData (0x0x7fc671fc9780) 0 empty + +Class QUntypedPropertyData + size=1 align=1 + base size=0 base align=1 +QUntypedPropertyData (0x0x7fc671fc9720) 0 empty + +Class QPropertyProxyBindingData + size=24 align=8 + base size=24 base align=8 +QPropertyProxyBindingData (0x0x7fc671fc97e0) 0 + +Class QtPrivate::BindingFunctionVTable + size=32 align=8 + base size=32 base align=8 +QtPrivate::BindingFunctionVTable (0x0x7fc671fc9840) 0 + +Class QtPrivate::QPropertyBindingFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::QPropertyBindingFunction (0x0x7fc671fc9d80) 0 + +Class QtPrivate::QPropertyBindingData + size=8 align=8 + base size=8 base align=8 +QtPrivate::QPropertyBindingData (0x0x7fc671fc9de0) 0 + +Class std::experimental::fundamentals_v2::source_location + size=24 align=8 + base size=24 base align=8 +std::experimental::fundamentals_v2::source_location (0x0x7fc671ff2540) 0 + +Class QPropertyBindingSourceLocation + size=24 align=8 + base size=24 base align=8 +QPropertyBindingSourceLocation (0x0x7fc671ff2c60) 0 + +Class QPropertyBindingError + size=8 align=8 + base size=8 base align=8 +QPropertyBindingError (0x0x7fc671ff2f60) 0 + +Class QUntypedPropertyBinding + size=8 align=8 + base size=8 base align=8 +QUntypedPropertyBinding (0x0x7fc6720210c0) 0 + +Class QPropertyObserverBase + size=24 align=8 + base size=24 base align=8 +QPropertyObserverBase (0x0x7fc672021300) 0 + +Class QPropertyObserver + size=24 align=8 + base size=24 base align=8 +QPropertyObserver (0x0x7fc671fd0958) 0 + QPropertyObserverBase (0x0x7fc672021480) 0 + +Class QPropertyNotifier + size=56 align=8 + base size=56 base align=8 +QPropertyNotifier (0x0x7fc671fd0c98) 0 + QPropertyObserver (0x0x7fc671fd0d00) 0 + QPropertyObserverBase (0x0x7fc672021960) 0 + +Class QtPrivate::QBindableInterface + size=56 align=8 + base size=56 base align=8 +QtPrivate::QBindableInterface (0x0x7fc67209e840) 0 + +Class QUntypedBindable + size=16 align=8 + base size=16 base align=8 +QUntypedBindable (0x0x7fc6720bf9c0) 0 + +Class QBindingStatus + size=32 align=8 + base size=32 base align=8 +QBindingStatus (0x0x7fc671dd5900) 0 + +Class QBindingStorage + size=16 align=8 + base size=16 base align=8 +QBindingStorage (0x0x7fc671dd5960) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7fc671ee1720) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7fc671f8d480) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=80 align=8 + base size=80 base align=8 +QObjectData (0x0x7fc671bd1de0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7fc671c82780) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7fc671c82720) 0 + vptr=((& QObject::_ZTV7QObject) + 16) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7fc671d446c0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7fc671d44f60) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7fc671d1d1a0) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16) + QObject (0x0x7fc671d44f00) 0 + primary-for QAbstractAnimation (0x0x7fc671d1d1a0) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7fc671d7d300) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7fc671d1d208) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16) + QObject (0x0x7fc671d7d2a0) 0 + primary-for QAnimationDriver (0x0x7fc671d1d208) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7fc671d7d4e0) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7fc671d1d270) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16) + QObject (0x0x7fc671d7d480) 0 + primary-for QEventLoop (0x0x7fc671d1d270) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7fc671d7da20) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7fc671d7dae0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7fc671d7db40) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))QAbstractEventDispatcher::startingUp +200 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7fc671d1d410) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16) + QObject (0x0x7fc671d7da80) 0 + primary-for QAbstractEventDispatcher (0x0x7fc671d1d410) + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7fc671a0d300) 0 empty + +Class QStringConverterBase::State + size=48 align=8 + base size=48 base align=8 +QStringConverterBase::State (0x0x7fc6718d8f00) 0 + +Class QStringConverterBase + size=1 align=1 + base size=0 base align=1 +QStringConverterBase (0x0x7fc6718d8ea0) 0 empty + +Class QStringConverter::Interface + size=40 align=8 + base size=40 base align=8 +QStringConverter::Interface (0x0x7fc6718fcb40) 0 + +Class QStringConverter + size=56 align=8 + base size=56 base align=8 +QStringConverter (0x0x7fc671a725b0) 0 + QStringConverterBase (0x0x7fc6718fcae0) 0 empty + +Class QStringEncoder + size=56 align=8 + base size=56 base align=8 +QStringEncoder (0x0x7fc671a72618) 0 + QStringConverter (0x0x7fc671a72680) 0 + QStringConverterBase (0x0x7fc671954540) 0 empty + +Class QStringDecoder + size=56 align=8 + base size=56 base align=8 +QStringDecoder (0x0x7fc671a726e8) 0 + QStringConverter (0x0x7fc671a72750) 0 + QStringConverterBase (0x0x7fc6719773c0) 0 empty + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7fc671a727b8) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16) + QIODeviceBase (0x0x7fc6719a00c0) 0 empty + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7fc6719a0840) 0 + +Class QContiguousCacheData + size=40 align=8 + base size=40 base align=8 +QContiguousCacheData (0x0x7fc67167ea20) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7fc6716da0c0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7fc6716da240) 0 + +Class QtPrivate::EnableInternalData + size=1 align=1 + base size=0 base align=1 +QtPrivate::EnableInternalData (0x0x7fc671786480) 0 empty + +Class QDebug::Stream + size=88 align=8 + base size=88 base align=8 +QDebug::Stream (0x0x7fc6717ab3c0) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7fc671764270) 0 + QIODeviceBase (0x0x7fc6717ab360) 0 empty + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7fc6714acd20) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7fc6714acde0) 0 empty + +Class QVariant::PrivateShared + size=8 align=8 + base size=8 base align=8 +QVariant::PrivateShared (0x0x7fc671254a20) 0 + +Class QVariant::Private + size=32 align=8 + base size=32 base align=8 +QVariant::Private (0x0x7fc671254a80) 0 + +Class QVariant + size=32 align=8 + base size=32 base align=8 +QVariant (0x0x7fc6712549c0) 0 + +Class QtPrivate::QVariantTypeCoercer + size=32 align=8 + base size=32 base align=8 +QtPrivate::QVariantTypeCoercer (0x0x7fc6710431e0) 0 + +Class QVariantConstPointer + size=32 align=8 + base size=32 base align=8 +QVariantConstPointer (0x0x7fc671043420) 0 + +Class QModelRoleData + size=40 align=8 + base size=40 base align=8 +QModelRoleData (0x0x7fc671043600) 0 + +Class QModelRoleDataSpan + size=16 align=8 + base size=16 base align=8 +QModelRoleDataSpan (0x0x7fc671081540) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7fc6710cc540) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7fc67111a720) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7fc6711b2000) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractItemModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractItemModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7fc6711a7068) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16) + QObject (0x0x7fc67118df60) 0 + primary-for QAbstractItemModel (0x0x7fc6711a7068) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7fc670ec4d80) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractTableModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractTableModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7fc6711a78f0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16) + QAbstractItemModel (0x0x7fc6711a7958) 0 + primary-for QAbstractTableModel (0x0x7fc6711a78f0) + QObject (0x0x7fc670ec4d20) 0 + primary-for QAbstractItemModel (0x0x7fc6711a7958) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7fc670ec4ea0) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractListModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractListModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7fc6711a79c0) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16) + QAbstractItemModel (0x0x7fc6711a7a28) 0 + primary-for QAbstractListModel (0x0x7fc6711a79c0) + QObject (0x0x7fc670ec4e40) 0 + primary-for QAbstractItemModel (0x0x7fc6711a7a28) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7fc670f42720) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7fc670f427e0) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QAbstractProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QAbstractProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QAbstractProxyModel::setSourceModel +416 (int (*)(...))__cxa_pure_virtual +424 (int (*)(...))__cxa_pure_virtual +432 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +440 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7fc670f31e38) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16) + QAbstractItemModel (0x0x7fc670f31ea0) 0 + primary-for QAbstractProxyModel (0x0x7fc670f31e38) + QObject (0x0x7fc670f42780) 0 + primary-for QAbstractItemModel (0x0x7fc670f31ea0) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7fc670f429c0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7fc670f31f08) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16) + QAbstractAnimation (0x0x7fc670f31f70) 0 + primary-for QAnimationGroup (0x0x7fc670f31f08) + QObject (0x0x7fc670f42960) 0 + primary-for QAbstractAnimation (0x0x7fc670f31f70) + +Class QAssociativeIterator + size=16 align=8 + base size=16 base align=8 +QAssociativeIterator (0x0x7fc670faf0d0) 0 + QIterator<QMetaAssociation> (0x0x7fc670faf138) 0 + QBaseIterator<QMetaAssociation> (0x0x7fc670f42de0) 0 + +Class QAssociativeConstIterator + size=16 align=8 + base size=16 base align=8 +QAssociativeConstIterator (0x0x7fc670faf270) 0 + QConstIterator<QMetaAssociation> (0x0x7fc670faf2d8) 0 + QBaseIterator<QMetaAssociation> (0x0x7fc670bc6360) 0 + +Class QAssociativeIterable + size=24 align=8 + base size=24 base align=8 +QAssociativeIterable (0x0x7fc670faf3a8) 0 + QIterable<QMetaAssociation> (0x0x7fc670bc68a0) 0 + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7fc670cc63c0) 0 + +Class QBitArray + size=24 align=8 + base size=24 base align=8 +QBitArray (0x0x7fc670d26120) 0 + +Class QBitRef + size=16 align=8 + base size=16 base align=8 +QBitRef (0x0x7fc670d5b060) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7fc670d7fba0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7fc670d882a0) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16) + QObject (0x0x7fc670d7fae0) 0 + primary-for QIODevice (0x0x7fc670d882a0) + QIODeviceBase (0x0x7fc670d7fb40) 0 empty + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7fc6709cb000) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7fc670d8c2d8) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16) + QIODevice (0x0x7fc670d88310) 0 + primary-for QBuffer (0x0x7fc670d8c2d8) + QObject (0x0x7fc670d7ff00) 0 + primary-for QIODevice (0x0x7fc670d88310) + QIODeviceBase (0x0x7fc670d7ff60) 0 empty + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7fc6709cb240) 0 + +Class QByteArrayMatcher + size=1056 align=8 + base size=1056 base align=8 +QByteArrayMatcher (0x0x7fc6709cb1e0) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7fc6709cb3c0) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7fc6709cb360) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7fc670a2aba0) 0 + +Class QCalendar::YearMonthDay + size=12 align=4 + base size=12 base align=4 +QCalendar::YearMonthDay (0x0x7fc670b48a20) 0 + +Class QCalendar::SystemId + size=8 align=8 + base size=8 base align=8 +QCalendar::SystemId (0x0x7fc670b48a80) 0 + +Class QCalendar + size=8 align=8 + base size=8 base align=8 +QCalendar (0x0x7fc670b489c0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7fc670ba54e0) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7fc6707f7ae0) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7fc670841d20) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7fc670841d80) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7fc670841cc0) 0 + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7fc6708ea000) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7fc6709233c0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7fc6705d3600) 0 + +Class QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel + size=1 align=1 + base size=0 base align=1 +QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel (0x0x7fc670649d80) 0 empty + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7fc670649e40) 0 + +Class QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator + size=24 align=8 + base size=17 base align=8 +QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator (0x0x7fc670686000) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7fc6706f6240) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7fc6703c8e40) 0 + +Class QCborParserError + size=16 align=8 + base size=16 base align=8 +QCborParserError (0x0x7fc670469000) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7fc6704690c0) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7fc670588960) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7fc6705bcea0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7fc6705bcf00) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7fc6705bce40) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7fc6702d04e0) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7fc6702d0540) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7fc6702d0480) 0 + +Class qfloat16::Wrap + size=2 align=2 + base size=2 base align=2 +qfloat16::Wrap (0x0x7fc6700e65a0) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7fc6700e6540) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7fc66fddb960) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7fc66fe26de0) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7fc66fe5f840) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7fc66fe5fa20) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7fc66ff20480) 0 + +Class QEvent::InputEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::InputEventTag (0x0x7fc66ff8bde0) 0 empty + +Class QEvent::PointerEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::PointerEventTag (0x0x7fc66ff8be40) 0 empty + +Class QEvent::SinglePointEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::SinglePointEventTag (0x0x7fc66ff8bea0) 0 empty + +Vtable for QEvent +QEvent::_ZTV6QEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QEvent + size=16 align=8 + base size=16 base align=8 +QEvent (0x0x7fc66ff8bd80) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QTimerEvent::clone + +Class QTimerEvent + size=24 align=8 + base size=20 base align=8 +QTimerEvent (0x0x7fc66ff92750) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16) + QEvent (0x0x7fc66fbee840) 0 + primary-for QTimerEvent (0x0x7fc66ff92750) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QChildEvent::clone + +Class QChildEvent + size=24 align=8 + base size=24 base align=8 +QChildEvent (0x0x7fc66ff927b8) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16) + QEvent (0x0x7fc66fbeed20) 0 + primary-for QChildEvent (0x0x7fc66ff927b8) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDynamicPropertyChangeEvent::clone + +Class QDynamicPropertyChangeEvent + size=40 align=8 + base size=40 base align=8 +QDynamicPropertyChangeEvent (0x0x7fc66ff92820) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16) + QEvent (0x0x7fc66fc20180) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7fc66ff92820) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDeferredDeleteEvent::clone + +Class QDeferredDeleteEvent + size=24 align=8 + base size=20 base align=8 +QDeferredDeleteEvent (0x0x7fc66ff92888) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16) + QEvent (0x0x7fc66fc20420) 0 + primary-for QDeferredDeleteEvent (0x0x7fc66ff92888) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7fc66fc207e0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7fc66ff92958) 0 + QBasicMutex (0x0x7fc66fc8f540) 0 + +Class QRecursiveMutex + size=24 align=8 + base size=24 base align=8 +QRecursiveMutex (0x0x7fc66fc8f960) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7fc66fc8ff60) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7fc66fd005a0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7fc66fa1f240) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7fc66fa67c60) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16) + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7fc66fa9bde0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7fc66fae0120) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7fc66f81a4e0) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7fc66f81fc30) 0 + std::__mutex_base (0x0x7fc66f81a540) 0 + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7fc66f81a720) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7fc66f81a780) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7fc66f81a7e0) 0 empty + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7fc66f855240) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7fc66f81fc98) 0 + std::__recursive_mutex_base (0x0x7fc66f8552a0) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7fc66fb107e0) 0 + std::__mutex_base (0x0x7fc66f855660) 0 + std::__timed_mutex_impl<std::timed_mutex> (0x0x7fc66f8556c0) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7fc66f880000) 0 + std::__recursive_mutex_base (0x0x7fc66f855a80) 0 + std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7fc66f855ae0) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7fc66f894900) 0 + +Vtable for std::thread::_State +std::thread::_State::_ZTVNSt6thread6_StateE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread6_StateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_State + size=8 align=8 + base size=8 base align=8 +std::thread::_State (0x0x7fc66f894ba0) 0 nearly-empty + vptr=((& std::thread::_State::_ZTVNSt6thread6_StateE) + 16) + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7fc66f894c00) 0 + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7fc66f894b40) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7fc66f678e40) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7fc66f6b4240) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7fc66f6b42a0) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7fc66f7667e0) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7fc66f6cda90) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16) + std::logic_error (0x0x7fc66f6cdaf8) 0 + primary-for std::future_error (0x0x7fc66f6cda90) + std::exception (0x0x7fc66f766f00) 0 nearly-empty + primary-for std::logic_error (0x0x7fc66f6cdaf8) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7fc66f791660) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7fc66f791600) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7fc66f5140c0) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7fc66f4f42d8) 0 + std::__at_thread_exit_elt (0x0x7fc66f514180) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7fc66f7917e0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7fc66f7915a0) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7fc66f1ac6e8) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16) + std::__future_base::_State_baseV2 (0x0x7fc66edc9e40) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7fc66f1ac6e8) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7fc66ee07720) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7fc66f1aca28) 0 + vptr=((& QThread::_ZTV7QThread) + 16) + QObject (0x0x7fc66ee076c0) 0 + primary-for QThread (0x0x7fc66f1aca28) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class QRunnable + size=16 align=8 + base size=9 base align=8 +QRunnable (0x0x7fc66ee07a80) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7fc66ee07c00) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7fc66f1aca90) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16) + QObject (0x0x7fc66ee07ba0) 0 + primary-for QThreadPool (0x0x7fc66f1aca90) + +Vtable for QException +QException::_ZTV10QException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7fc66f1acaf8) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16) + std::exception (0x0x7fc66ee07d80) 0 nearly-empty + primary-for QException (0x0x7fc66f1acaf8) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=16 align=8 + base size=16 base align=8 +QUnhandledException (0x0x7fc66f1acb60) 0 + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16) + QException (0x0x7fc66f1acbc8) 0 nearly-empty + primary-for QUnhandledException (0x0x7fc66f1acb60) + std::exception (0x0x7fc66ee07de0) 0 nearly-empty + primary-for QException (0x0x7fc66f1acbc8) + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7fc66ee6cc60) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7fc66eca3360) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7fc66eca3300) 0 + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7fc66ecea5a0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7fc66ecb77b8) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16) + QObject (0x0x7fc66ecea540) 0 + primary-for QCoreApplication (0x0x7fc66ecb77b8) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7fc66ecea7e0) 0 + +Class QConcatenateTablesProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QConcatenateTablesProxyModel::QPrivateSignal (0x0x7fc66ecea900) 0 empty + +Vtable for QConcatenateTablesProxyModel +QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QConcatenateTablesProxyModel) +16 (int (*)(...))QConcatenateTablesProxyModel::metaObject +24 (int (*)(...))QConcatenateTablesProxyModel::qt_metacast +32 (int (*)(...))QConcatenateTablesProxyModel::qt_metacall +40 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +48 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QConcatenateTablesProxyModel::index +120 (int (*)(...))QConcatenateTablesProxyModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QConcatenateTablesProxyModel::rowCount +144 (int (*)(...))QConcatenateTablesProxyModel::columnCount +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))QConcatenateTablesProxyModel::data +168 (int (*)(...))QConcatenateTablesProxyModel::setData +176 (int (*)(...))QConcatenateTablesProxyModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QConcatenateTablesProxyModel::itemData +200 (int (*)(...))QConcatenateTablesProxyModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QConcatenateTablesProxyModel::mimeTypes +224 (int (*)(...))QConcatenateTablesProxyModel::mimeData +232 (int (*)(...))QConcatenateTablesProxyModel::canDropMimeData +240 (int (*)(...))QConcatenateTablesProxyModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QConcatenateTablesProxyModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QConcatenateTablesProxyModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QConcatenateTablesProxyModel + size=16 align=8 + base size=16 base align=8 +QConcatenateTablesProxyModel (0x0x7fc66ecb7820) 0 + vptr=((& QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel) + 16) + QAbstractItemModel (0x0x7fc66ecb7888) 0 + primary-for QConcatenateTablesProxyModel (0x0x7fc66ecb7820) + QObject (0x0x7fc66ecea8a0) 0 + primary-for QAbstractItemModel (0x0x7fc66ecb7888) + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7fc66eceaa80) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7fc66eceac60) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QFileDevice::fileName +256 (int (*)(...))QFileDevice::resize +264 (int (*)(...))QFileDevice::permissions +272 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7fc66ecb78f0) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16) + QIODevice (0x0x7fc66ecb0f50) 0 + primary-for QFileDevice (0x0x7fc66ecb78f0) + QObject (0x0x7fc66eceaba0) 0 + primary-for QIODevice (0x0x7fc66ecb0f50) + QIODeviceBase (0x0x7fc66eceac00) 0 empty + +Class std::filesystem::space_info + size=24 align=8 + base size=24 base align=8 +std::filesystem::space_info (0x0x7fc66ed71960) 0 + +Class std::filesystem::__file_clock + size=1 align=1 + base size=0 base align=1 +std::filesystem::__file_clock (0x0x7fc66ea0af00) 0 empty + +Class std::time_base + size=1 align=1 + base size=0 base align=1 +std::time_base (0x0x7fc66ea293c0) 0 empty + +Class std::money_base::pattern + size=4 align=1 + base size=4 base align=1 +std::money_base::pattern (0x0x7fc66ea8d6c0) 0 + +Class std::money_base + size=1 align=1 + base size=0 base align=1 +std::money_base (0x0x7fc66ea8d660) 0 empty + +Class std::messages_base + size=1 align=1 + base size=0 base align=1 +std::messages_base (0x0x7fc66eab2c60) 0 empty + +Class std::codecvt_base + size=1 align=1 + base size=0 base align=1 +std::codecvt_base (0x0x7fc66eb027e0) 0 empty + +Construction vtable for std::basic_istream<char> (0x0x7fc66e965b60 instance) in std::__cxx11::basic_istringstream<char> +std::__cxx11::basic_istringstream<char>::_ZTCNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE0_Si: 10 entries +0 120 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551496 +48 (int (*)(...))-120 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +VTT for std::__cxx11::basic_istringstream<char> +std::__cxx11::basic_istringstream<char>::_ZTTNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE: 4 entries +0 ((& std::__cxx11::basic_istringstream<char>::_ZTVNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE) + 24) +8 ((& std::__cxx11::basic_istringstream<char>::_ZTCNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 24) +16 ((& std::__cxx11::basic_istringstream<char>::_ZTCNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 64) +24 ((& std::__cxx11::basic_istringstream<char>::_ZTVNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEE) + 64) + +Construction vtable for std::basic_ostream<char> (0x0x7fc66e965dd0 instance) in std::__cxx11::basic_ostringstream<char> +std::__cxx11::basic_ostringstream<char>::_ZTCNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE0_So: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::__cxx11::basic_ostringstream<char> +std::__cxx11::basic_ostringstream<char>::_ZTTNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE: 4 entries +0 ((& std::__cxx11::basic_ostringstream<char>::_ZTVNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE) + 24) +8 ((& std::__cxx11::basic_ostringstream<char>::_ZTCNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE0_So) + 24) +16 ((& std::__cxx11::basic_ostringstream<char>::_ZTCNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE0_So) + 64) +24 ((& std::__cxx11::basic_ostringstream<char>::_ZTVNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEE) + 64) + +Construction vtable for std::basic_iostream<char> (0x0x7fc66e5ea000 instance) in std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd: 15 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISd) +24 0 +32 0 +40 112 +48 (int (*)(...))-16 +56 (int (*)(...))(& _ZTISd) +64 0 +72 0 +80 18446744073709551488 +88 (int (*)(...))-128 +96 (int (*)(...))(& _ZTISd) +104 0 +112 0 + +Construction vtable for std::basic_istream<char> (0x0x7fc66e965d00 instance) in std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Si: 10 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551488 +48 (int (*)(...))-128 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream<char> (0x0x7fc66e965f70 instance) in std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE16_So: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::__cxx11::basic_stringstream<char> +std::__cxx11::basic_stringstream<char>::_ZTTNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE: 10 entries +0 ((& std::__cxx11::basic_stringstream<char>::_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE) + 24) +8 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd) + 24) +16 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 24) +24 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Si) + 64) +32 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE16_So) + 24) +40 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE16_So) + 64) +48 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd) + 104) +56 ((& std::__cxx11::basic_stringstream<char>::_ZTCNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE0_Sd) + 64) +64 ((& std::__cxx11::basic_stringstream<char>::_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE) + 104) +72 ((& std::__cxx11::basic_stringstream<char>::_ZTVNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEE) + 64) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7fc66e5ec478 instance) in std::__cxx11::basic_istringstream<wchar_t> +std::__cxx11::basic_istringstream<wchar_t>::_ZTCNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E: 10 entries +0 120 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551496 +48 (int (*)(...))-120 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::__cxx11::basic_istringstream<wchar_t> +std::__cxx11::basic_istringstream<wchar_t>::_ZTTNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE: 4 entries +0 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTVNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE) + 24) +8 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTCNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 24) +16 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTCNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 64) +24 ((& std::__cxx11::basic_istringstream<wchar_t>::_ZTVNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEE) + 64) + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7fc66e5ec6e8 instance) in std::__cxx11::basic_ostringstream<wchar_t> +std::__cxx11::basic_ostringstream<wchar_t>::_ZTCNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_ostreamIwS2_E: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::__cxx11::basic_ostringstream<wchar_t> +std::__cxx11::basic_ostringstream<wchar_t>::_ZTTNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE: 4 entries +0 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTVNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE) + 24) +8 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTCNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_ostreamIwS2_E) + 24) +16 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTCNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_ostreamIwS2_E) + 64) +24 ((& std::__cxx11::basic_ostringstream<wchar_t>::_ZTVNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEE) + 64) + +Construction vtable for std::basic_iostream<wchar_t> (0x0x7fc66e5ea3f0 instance) in std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E: 15 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt14basic_iostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 112 +48 (int (*)(...))-16 +56 (int (*)(...))(& _ZTISt14basic_iostreamIwSt11char_traitsIwEE) +64 0 +72 0 +80 18446744073709551488 +88 (int (*)(...))-128 +96 (int (*)(...))(& _ZTISt14basic_iostreamIwSt11char_traitsIwEE) +104 0 +112 0 + +Construction vtable for std::basic_istream<wchar_t> (0x0x7fc66e5ec958 instance) in std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E: 10 entries +0 128 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551488 +48 (int (*)(...))-128 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7fc66e5eca28 instance) in std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE16_St13basic_ostreamIwS2_E: 10 entries +0 112 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551504 +48 (int (*)(...))-112 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::__cxx11::basic_stringstream<wchar_t> +std::__cxx11::basic_stringstream<wchar_t>::_ZTTNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE: 10 entries +0 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE) + 24) +8 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E) + 24) +16 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 24) +24 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St13basic_istreamIwS2_E) + 64) +32 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE16_St13basic_ostreamIwS2_E) + 24) +40 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE16_St13basic_ostreamIwS2_E) + 64) +48 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E) + 104) +56 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTCNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE0_St14basic_iostreamIwS2_E) + 64) +64 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE) + 104) +72 ((& std::__cxx11::basic_stringstream<wchar_t>::_ZTVNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEE) + 64) + +Class std::_Resetiosflags + size=4 align=4 + base size=4 base align=4 +std::_Resetiosflags (0x0x7fc66e64a060) 0 + +Class std::_Setiosflags + size=4 align=4 + base size=4 base align=4 +std::_Setiosflags (0x0x7fc66e64a1e0) 0 + +Class std::_Setbase + size=4 align=4 + base size=4 base align=4 +std::_Setbase (0x0x7fc66e64a360) 0 + +Class std::_Setprecision + size=4 align=4 + base size=4 base align=4 +std::_Setprecision (0x0x7fc66e64a660) 0 + +Class std::_Setw + size=4 align=4 + base size=4 base align=4 +std::_Setw (0x0x7fc66e64a7e0) 0 + +Class std::filesystem::__cxx11::path::__null_terminated + size=1 align=1 + base size=0 base align=1 +std::filesystem::__cxx11::path::__null_terminated (0x0x7fc66e7098a0) 0 empty + +Class std::filesystem::__cxx11::path::_List::_Impl_deleter + size=1 align=1 + base size=0 base align=1 +std::filesystem::__cxx11::path::_List::_Impl_deleter (0x0x7fc66e709960) 0 empty + +Class std::filesystem::__cxx11::path::_List + size=8 align=8 + base size=8 base align=8 +std::filesystem::__cxx11::path::_List (0x0x7fc66e709900) 0 + +Class std::filesystem::__cxx11::path + size=40 align=8 + base size=40 base align=8 +std::filesystem::__cxx11::path (0x0x7fc66e709780) 0 + +Vtable for std::filesystem::__cxx11::filesystem_error +std::filesystem::__cxx11::filesystem_error::_ZTVNSt10filesystem7__cxx1116filesystem_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt10filesystem7__cxx1116filesystem_errorE) +16 (int (*)(...))std::filesystem::__cxx11::filesystem_error::~filesystem_error +24 (int (*)(...))std::filesystem::__cxx11::filesystem_error::~filesystem_error +32 (int (*)(...))std::filesystem::__cxx11::filesystem_error::what + +Class std::filesystem::__cxx11::filesystem_error + size=48 align=8 + base size=48 base align=8 +std::filesystem::__cxx11::filesystem_error (0x0x7fc66e574680) 0 + vptr=((& std::filesystem::__cxx11::filesystem_error::_ZTVNSt10filesystem7__cxx1116filesystem_errorE) + 16) + std::system_error (0x0x7fc66e5746e8) 0 + primary-for std::filesystem::__cxx11::filesystem_error (0x0x7fc66e574680) + std::runtime_error (0x0x7fc66e574750) 0 + primary-for std::system_error (0x0x7fc66e5746e8) + std::exception (0x0x7fc66e57d840) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc66e574750) + +Class std::filesystem::__cxx11::path::_Cmpt + size=48 align=8 + base size=48 base align=8 +std::filesystem::__cxx11::path::_Cmpt (0x0x7fc66e1e20d0) 0 + std::filesystem::__cxx11::path (0x0x7fc66e1d9300) 0 + +Class std::filesystem::__cxx11::path::iterator + size=24 align=8 + base size=17 base align=8 +std::filesystem::__cxx11::path::iterator (0x0x7fc66e2005a0) 0 + +Class std::filesystem::file_status + size=8 align=4 + base size=8 base align=4 +std::filesystem::file_status (0x0x7fc66e2b9d80) 0 + +Class std::filesystem::__cxx11::directory_entry + size=48 align=8 + base size=41 base align=8 +std::filesystem::__cxx11::directory_entry (0x0x7fc66e3042a0) 0 + +Class std::filesystem::__cxx11::__directory_iterator_proxy + size=48 align=8 + base size=48 base align=8 +std::filesystem::__cxx11::__directory_iterator_proxy (0x0x7fc66e349960) 0 + +Class std::filesystem::__cxx11::directory_iterator + size=16 align=8 + base size=16 base align=8 +std::filesystem::__cxx11::directory_iterator (0x0x7fc66e374120) 0 + +Class std::filesystem::__cxx11::recursive_directory_iterator + size=16 align=8 + base size=16 base align=8 +std::filesystem::__cxx11::recursive_directory_iterator (0x0x7fc66dfee240) 0 + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7fc66e0be3c0) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QFile::fileName +256 (int (*)(...))QFile::resize +264 (int (*)(...))QFile::permissions +272 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7fc66e0bab60) 0 + vptr=((& QFile::_ZTV5QFile) + 16) + QFileDevice (0x0x7fc66e0babc8) 0 + primary-for QFile (0x0x7fc66e0bab60) + QIODevice (0x0x7fc66e2a3700) 0 + primary-for QFileDevice (0x0x7fc66e0babc8) + QObject (0x0x7fc66e0be300) 0 + primary-for QIODevice (0x0x7fc66e2a3700) + QIODeviceBase (0x0x7fc66e0be360) 0 empty + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7fc66e0be9c0) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7fc66e19d360) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7fc66de6aa80) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7fc66de6af00) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7fc66df976c0) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7fc66df97900) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7fc66df58d68) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16) + QObject (0x0x7fc66df978a0) 0 + primary-for QFileSelector (0x0x7fc66df58d68) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7fc66df97ae0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7fc66df58dd0) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16) + QObject (0x0x7fc66df97a80) 0 + primary-for QFileSystemWatcher (0x0x7fc66df58dd0) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7fc66dbcc2a0) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7fc66df58e38) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16) + QObject (0x0x7fc66dbcc240) 0 + primary-for QFutureWatcherBase (0x0x7fc66df58e38) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7fc66dbcc7e0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QIdentityProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QIdentityProxyModel::insertRows +272 (int (*)(...))QIdentityProxyModel::insertColumns +280 (int (*)(...))QIdentityProxyModel::removeRows +288 (int (*)(...))QIdentityProxyModel::removeColumns +296 (int (*)(...))QIdentityProxyModel::moveRows +304 (int (*)(...))QIdentityProxyModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QAbstractProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QIdentityProxyModel::match +360 (int (*)(...))QAbstractProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QIdentityProxyModel::setSourceModel +416 (int (*)(...))QIdentityProxyModel::mapToSource +424 (int (*)(...))QIdentityProxyModel::mapFromSource +432 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +440 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7fc66dbe2068) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16) + QAbstractProxyModel (0x0x7fc66dbe20d0) 0 + primary-for QIdentityProxyModel (0x0x7fc66dbe2068) + QAbstractItemModel (0x0x7fc66dbe2138) 0 + primary-for QAbstractProxyModel (0x0x7fc66dbe20d0) + QObject (0x0x7fc66dbcc780) 0 + primary-for QAbstractItemModel (0x0x7fc66dbe2138) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7fc66dbcc960) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7fc66dc595a0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7fc66dc4ef08) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16) + QObject (0x0x7fc66dc59540) 0 + primary-for QItemSelectionModel (0x0x7fc66dc4ef08) + +Class QItemSelection + size=24 align=8 + base size=24 base align=8 +QItemSelection (0x0x7fc66dc7b410) 0 + QList<QItemSelectionRange> (0x0x7fc66dc7b478) 0 + QListSpecialMethods<QItemSelectionRange> (0x0x7fc66dc7b4e0) 0 empty + QListSpecialMethodsBase<QItemSelectionRange> (0x0x7fc66dd0c000) 0 empty + +Class QJsonValue + size=24 align=8 + base size=24 base align=8 +QJsonValue (0x0x7fc66dda3180) 0 + +Class QJsonValueRef + size=16 align=8 + base size=16 base align=8 +QJsonValueRef (0x0x7fc66dda3660) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=16 base align=8 +QJsonArray::iterator (0x0x7fc66da0c9c0) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=16 base align=8 +QJsonArray::const_iterator (0x0x7fc66da0ca20) 0 + +Class QJsonArray + size=8 align=8 + base size=8 base align=8 +QJsonArray (0x0x7fc66da0c960) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7fc66dabb420) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7fc66dabb480) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=16 base align=8 +QJsonObject::iterator (0x0x7fc66d84b9c0) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=16 base align=8 +QJsonObject::const_iterator (0x0x7fc66d84ba20) 0 + +Class QJsonObject + size=8 align=8 + base size=8 base align=8 +QJsonObject (0x0x7fc66d84b960) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7fc66d905540) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=24 align=8 + base size=24 base align=8 +QLibrary (0x0x7fc66d8f8d68) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16) + QObject (0x0x7fc66d9054e0) 0 + primary-for QLibrary (0x0x7fc66d8f8d68) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7fc66d905c00) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7fc66d905ba0) 0 + +Class QTypeRevision + size=2 align=1 + base size=2 base align=1 +QTypeRevision (0x0x7fc66d6293c0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7fc66d6c0c00) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7fc66d6c0cc0) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7fc66d7403c0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7fc66d79dd20) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7fc66d403360) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7fc66d457b40) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7fc66d49d300) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7fc66d4e8c00) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7fc66d57b960) 0 + +Class QMetaMethod::Data + size=8 align=8 + base size=8 base align=8 +QMetaMethod::Data (0x0x7fc66d57ba20) 0 + +Class QMetaMethod + size=16 align=8 + base size=16 base align=8 +QMetaMethod (0x0x7fc66d57b9c0) 0 + +Class QMetaEnum::Data + size=8 align=8 + base size=8 base align=8 +QMetaEnum::Data (0x0x7fc66d1f3c60) 0 + +Class QMetaEnum + size=16 align=8 + base size=16 base align=8 +QMetaEnum (0x0x7fc66d1f3c00) 0 + +Class QMetaProperty::Data + size=8 align=8 + base size=8 base align=8 +QMetaProperty::Data (0x0x7fc66d2389c0) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7fc66d238960) 0 + +Class QMetaClassInfo::Data + size=8 align=8 + base size=8 base align=8 +QMetaClassInfo::Data (0x0x7fc66d25f060) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=16 base align=8 +QMetaClassInfo (0x0x7fc66d25f000) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7fc66d27fea0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7fc66d28d888) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16) + QObject (0x0x7fc66d27fe40) 0 + primary-for QMimeData (0x0x7fc66d28d888) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7fc66d2a7000) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7fc66d312b40) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7fc66d312c00) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=40 align=8 + base size=40 base align=8 +QObjectCleanupHandler (0x0x7fc66d31c750) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16) + QObject (0x0x7fc66d312ba0) 0 + primary-for QObjectCleanupHandler (0x0x7fc66d31c750) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7fc66d312cc0) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7fc66d370ae0) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7fc66d3821a0) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16) + QAnimationGroup (0x0x7fc66d382208) 0 + primary-for QParallelAnimationGroup (0x0x7fc66d3821a0) + QAbstractAnimation (0x0x7fc66d382270) 0 + primary-for QAnimationGroup (0x0x7fc66d382208) + QObject (0x0x7fc66d370a80) 0 + primary-for QAbstractAnimation (0x0x7fc66d382270) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7fc66d370cc0) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7fc66d3822d8) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16) + QAbstractAnimation (0x0x7fc66d382340) 0 + primary-for QPauseAnimation (0x0x7fc66d3822d8) + QObject (0x0x7fc66d370c60) 0 + primary-for QAbstractAnimation (0x0x7fc66d382340) + +Class QPluginMetaData + size=16 align=8 + base size=16 base align=8 +QPluginMetaData (0x0x7fc66d370ea0) 0 + +Class QStaticPlugin + size=24 align=8 + base size=24 base align=8 +QStaticPlugin (0x0x7fc66d370f00) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7fc66d3bd960) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7fc66d3bcf08) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16) + QObject (0x0x7fc66d3bd900) 0 + primary-for QPluginLoader (0x0x7fc66d3bcf08) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7fc66d7f8060) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7fc676b1d360) 0 empty + +Class QProcess::Use_setChildProcessModifier_Instead + size=1 align=1 + base size=0 base align=1 +QProcess::Use_setChildProcessModifier_Instead (0x0x7fc676b1d660) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 32 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QProcess::writeData +248 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7fc676f500d0) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16) + QIODevice (0x0x7fc67311cbd0) 0 + primary-for QProcess (0x0x7fc676f500d0) + QObject (0x0x7fc676b1d060) 0 + primary-for QIODevice (0x0x7fc67311cbd0) + QIODeviceBase (0x0x7fc676b1d300) 0 empty + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7fc6768dd7e0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7fc676aeaea0) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16) + QAbstractAnimation (0x0x7fc676aeaf08) 0 + primary-for QVariantAnimation (0x0x7fc676aeaea0) + QObject (0x0x7fc6768dd720) 0 + primary-for QAbstractAnimation (0x0x7fc676aeaf08) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7fc6764e5060) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7fc676b110d0) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16) + QVariantAnimation (0x0x7fc676b11138) 0 + primary-for QPropertyAnimation (0x0x7fc676b110d0) + QAbstractAnimation (0x0x7fc676b11270) 0 + primary-for QVariantAnimation (0x0x7fc676b11138) + QObject (0x0x7fc6764e5000) 0 + primary-for QAbstractAnimation (0x0x7fc676b11270) + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7fc6749bb3c0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7fc6710212a0) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7fc671001c00) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7fc66f5758a0) 0 + +Class QRandomGenerator::InitialRandomData + size=16 align=8 + base size=16 base align=8 +QRandomGenerator::InitialRandomData (0x0x7fc66d5341e0) 0 + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7fc66d534240) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7fc66d4c9ae0) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7fc6766fa0d0) 0 + QRandomGenerator (0x0x7fc66e6ae6c0) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7fc66f92f300) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7fc66f92f540) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7fc66f92f9c0) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7fc66f92fe40) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7fc6773c4900) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7fc6758cf3c0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7fc6740871e0) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7fc673dd8d20) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7fc673baa060) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QSaveFile::writeData +248 (int (*)(...))QSaveFile::fileName +256 (int (*)(...))QFileDevice::resize +264 (int (*)(...))QFileDevice::permissions +272 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7fc6763f3ea0) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16) + QFileDevice (0x0x7fc67647fc98) 0 + primary-for QSaveFile (0x0x7fc6763f3ea0) + QIODevice (0x0x7fc670925ee0) 0 + primary-for QFileDevice (0x0x7fc67647fc98) + QObject (0x0x7fc673dd8f60) 0 + primary-for QIODevice (0x0x7fc670925ee0) + QIODeviceBase (0x0x7fc673baa000) 0 empty + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7fc673baa3c0) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7fc673900ba0) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7fc67398e900) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7fc6764fa680) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16) + QAnimationGroup (0x0x7fc6764fa6e8) 0 + primary-for QSequentialAnimationGroup (0x0x7fc6764fa680) + QAbstractAnimation (0x0x7fc6764fa750) 0 + primary-for QAnimationGroup (0x0x7fc6764fa6e8) + QObject (0x0x7fc67398e8a0) 0 + primary-for QAbstractAnimation (0x0x7fc6764fa750) + +Class QSequentialIterator + size=16 align=8 + base size=16 base align=8 +QSequentialIterator (0x0x7fc6764fa8f0) 0 + QIterator<QMetaSequence> (0x0x7fc6764fa958) 0 + QBaseIterator<QMetaSequence> (0x0x7fc67398ec60) 0 + +Class QSequentialConstIterator + size=16 align=8 + base size=16 base align=8 +QSequentialConstIterator (0x0x7fc6764faa90) 0 + QConstIterator<QMetaSequence> (0x0x7fc6764faf70) 0 + QBaseIterator<QMetaSequence> (0x0x7fc6731271e0) 0 + +Class QSequentialIterable + size=24 align=8 + base size=24 base align=8 +QSequentialIterable (0x0x7fc676541000) 0 + QIterable<QMetaSequence> (0x0x7fc673127720) 0 + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7fc6717bed20) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7fc6765bc0d0) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16) + QObject (0x0x7fc6717becc0) 0 + primary-for QSettings (0x0x7fc6765bc0d0) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7fc671279180) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7fc6765bc138) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16) + QObject (0x0x7fc671279120) 0 + primary-for QSharedMemory (0x0x7fc6765bc138) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7fc671279360) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7fc6765bc1a0) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16) + QObject (0x0x7fc671279300) 0 + primary-for QSignalMapper (0x0x7fc6765bc1a0) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7fc66caced80) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7fc6765c1340) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16) + QObject (0x0x7fc66caced20) 0 + primary-for QSocketNotifier (0x0x7fc6765c1340) + +Class QSocketDescriptor + size=4 align=4 + base size=4 base align=4 +QSocketDescriptor (0x0x7fc66cacef00) 0 + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7fc66cb028a0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 59 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QSortFilterProxyModel::mimeTypes +224 (int (*)(...))QSortFilterProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QSortFilterProxyModel::dropMimeData +248 (int (*)(...))QSortFilterProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QSortFilterProxyModel::insertRows +272 (int (*)(...))QSortFilterProxyModel::insertColumns +280 (int (*)(...))QSortFilterProxyModel::removeRows +288 (int (*)(...))QSortFilterProxyModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QSortFilterProxyModel::fetchMore +320 (int (*)(...))QSortFilterProxyModel::canFetchMore +328 (int (*)(...))QSortFilterProxyModel::flags +336 (int (*)(...))QSortFilterProxyModel::sort +344 (int (*)(...))QSortFilterProxyModel::buddy +352 (int (*)(...))QSortFilterProxyModel::match +360 (int (*)(...))QSortFilterProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QSortFilterProxyModel::setSourceModel +416 (int (*)(...))QSortFilterProxyModel::mapToSource +424 (int (*)(...))QSortFilterProxyModel::mapFromSource +432 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +440 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +448 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +456 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +464 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7fc6761c4dd0) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16) + QAbstractProxyModel (0x0x7fc6761c4e38) 0 + primary-for QSortFilterProxyModel (0x0x7fc6761c4dd0) + QAbstractItemModel (0x0x7fc6761c4ea0) 0 + primary-for QAbstractProxyModel (0x0x7fc6761c4e38) + QObject (0x0x7fc66cb02840) 0 + primary-for QAbstractItemModel (0x0x7fc6761c4ea0) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7fc66cb02c60) 0 empty + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7fc66cb28660) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7fc66cb5dea0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7fc66cb9b720) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QStringListModel::itemData +200 (int (*)(...))QStringListModel::setItemData +208 (int (*)(...))QStringListModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractListModel::dropMimeData +248 (int (*)(...))QStringListModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QStringListModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QStringListModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QStringListModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QStringListModel::flags +336 (int (*)(...))QStringListModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QStringListModel + size=40 align=8 + base size=40 base align=8 +QStringListModel (0x0x7fc6761dec98) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16) + QAbstractListModel (0x0x7fc6761ded00) 0 + primary-for QStringListModel (0x0x7fc6761dec98) + QAbstractItemModel (0x0x7fc6761ded68) 0 + primary-for QAbstractListModel (0x0x7fc6761ded00) + QObject (0x0x7fc66cb9b6c0) 0 + primary-for QAbstractItemModel (0x0x7fc6761ded68) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7fc66cb9b7e0) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7fc66cb9b900) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7fc66cb9ba80) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QTemporaryFile::fileName +256 (int (*)(...))QFile::resize +264 (int (*)(...))QFile::permissions +272 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7fc6761dedd0) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16) + QFile (0x0x7fc6761dee38) 0 + primary-for QTemporaryFile (0x0x7fc6761dedd0) + QFileDevice (0x0x7fc6761deea0) 0 + primary-for QFile (0x0x7fc6761dee38) + QIODevice (0x0x7fc66cbba000) 0 + primary-for QFileDevice (0x0x7fc6761deea0) + QObject (0x0x7fc66cb9b9c0) 0 + primary-for QIODevice (0x0x7fc66cbba000) + QIODeviceBase (0x0x7fc66cb9ba20) 0 empty + +Class QTextBoundaryFinder + size=72 align=8 + base size=72 base align=8 +QTextBoundaryFinder (0x0x7fc66cb9bcc0) 0 + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7fc66c7cb360) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7fc66c7cba20) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7fc6761e00d0) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16) + QObject (0x0x7fc66c7cb9c0) 0 + primary-for QTimeLine (0x0x7fc6761e00d0) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7fc66c7cbc00) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=16 align=8 + base size=16 base align=8 +QTimer (0x0x7fc6761e0138) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16) + QObject (0x0x7fc66c7cbba0) 0 + primary-for QTimer (0x0x7fc6761e0138) + +Class QTimeZone::OffsetData + size=48 align=8 + base size=44 base align=8 +QTimeZone::OffsetData (0x0x7fc66c7f85a0) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7fc66c7f8540) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7fc66c82a600) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7fc6761e8f70) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16) + QObject (0x0x7fc66c82a5a0) 0 + primary-for QTranslator (0x0x7fc6761e8f70) + +Class QTransposeProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTransposeProxyModel::QPrivateSignal (0x0x7fc66c82a7e0) 0 empty + +Vtable for QTransposeProxyModel +QTransposeProxyModel::_ZTV20QTransposeProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTransposeProxyModel) +16 (int (*)(...))QTransposeProxyModel::metaObject +24 (int (*)(...))QTransposeProxyModel::qt_metacast +32 (int (*)(...))QTransposeProxyModel::qt_metacall +40 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +48 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTransposeProxyModel::index +120 (int (*)(...))QTransposeProxyModel::parent +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))QTransposeProxyModel::rowCount +144 (int (*)(...))QTransposeProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QTransposeProxyModel::headerData +184 (int (*)(...))QTransposeProxyModel::setHeaderData +192 (int (*)(...))QTransposeProxyModel::itemData +200 (int (*)(...))QTransposeProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QAbstractProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QTransposeProxyModel::insertRows +272 (int (*)(...))QTransposeProxyModel::insertColumns +280 (int (*)(...))QTransposeProxyModel::removeRows +288 (int (*)(...))QTransposeProxyModel::removeColumns +296 (int (*)(...))QTransposeProxyModel::moveRows +304 (int (*)(...))QTransposeProxyModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QTransposeProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QTransposeProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QTransposeProxyModel::setSourceModel +416 (int (*)(...))QTransposeProxyModel::mapToSource +424 (int (*)(...))QTransposeProxyModel::mapFromSource +432 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +440 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QTransposeProxyModel + size=16 align=8 + base size=16 base align=8 +QTransposeProxyModel (0x0x7fc6761e9000) 0 + vptr=((& QTransposeProxyModel::_ZTV20QTransposeProxyModel) + 16) + QAbstractProxyModel (0x0x7fc6761e9068) 0 + primary-for QTransposeProxyModel (0x0x7fc6761e9000) + QAbstractItemModel (0x0x7fc6761e90d0) 0 + primary-for QAbstractProxyModel (0x0x7fc6761e9068) + QObject (0x0x7fc66c82a780) 0 + primary-for QAbstractItemModel (0x0x7fc6761e90d0) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7fc66c82a960) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7fc66c8821e0) 0 + +Class QtPrivate::QXmlString + size=24 align=8 + base size=24 base align=8 +QtPrivate::QXmlString (0x0x7fc66c882300) 0 + +Class QXmlStreamAttribute + size=104 align=8 + base size=97 base align=8 +QXmlStreamAttribute (0x0x7fc66c89f120) 0 + +Class QXmlStreamAttributes + size=24 align=8 + base size=24 base align=8 +QXmlStreamAttributes (0x0x7fc6762068f0) 0 + QList<QXmlStreamAttribute> (0x0x7fc676206958) 0 + QListSpecialMethods<QXmlStreamAttribute> (0x0x7fc6762069c0) 0 empty + QListSpecialMethodsBase<QXmlStreamAttribute> (0x0x7fc66c8c5240) 0 empty + +Class QXmlStreamNamespaceDeclaration + size=48 align=8 + base size=48 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7fc66c8c5ae0) 0 + +Class QXmlStreamNotationDeclaration + size=72 align=8 + base size=72 base align=8 +QXmlStreamNotationDeclaration (0x0x7fc66c8f6120) 0 + +Class QXmlStreamEntityDeclaration + size=120 align=8 + base size=120 base align=8 +QXmlStreamEntityDeclaration (0x0x7fc66c9037e0) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7fc66c912f60) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7fc66c91f000) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7fc66c91f5a0) 0 + +Vtable for QPaintDevice +QPaintDevice::_ZTV12QPaintDevice: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintDevice) +16 0 +24 0 +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDevice + size=16 align=8 + base size=10 base align=8 +QPaintDevice (0x0x7fc66c91f780) 0 + vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16) + +Class QRgba64 + size=8 align=8 + base size=8 base align=8 +QRgba64 (0x0x7fc66c94f240) 0 + +Class QColor::CT + size=10 align=2 + base size=10 base align=2 +QColor::CT (0x0x7fc66c978f00) 0 + +Class QColor + size=16 align=4 + base size=14 base align=4 +QColor (0x0x7fc66c978ea0) 0 + +Class QPixelFormat + size=8 align=8 + base size=8 base align=8 +QPixelFormat (0x0x7fc66c9b8f60) 0 + +Class QPolygon + size=24 align=8 + base size=24 base align=8 +QPolygon (0x0x7fc6763179c0) 0 + QList<QPoint> (0x0x7fc676317a28) 0 + QListSpecialMethods<QPoint> (0x0x7fc676317a90) 0 empty + QListSpecialMethodsBase<QPoint> (0x0x7fc66c5efc60) 0 empty + +Class QPolygonF + size=24 align=8 + base size=24 base align=8 +QPolygonF (0x0x7fc67631bd68) 0 + QList<QPointF> (0x0x7fc67631be38) 0 + QListSpecialMethods<QPointF> (0x0x7fc67631bea0) 0 empty + QListSpecialMethodsBase<QPointF> (0x0x7fc66c6478a0) 0 empty + +Class QRegion::QRegionData + size=16 align=8 + base size=16 base align=8 +QRegion::QRegionData (0x0x7fc66c6980c0) 0 + +Class QRegion + size=8 align=8 + base size=8 base align=8 +QRegion (0x0x7fc66c698060) 0 + +Class QTransform::Affine + size=8 align=8 + base size=8 base align=8 +QTransform::Affine (0x0x7fc66c6cb600) 0 + +Class QTransform + size=80 align=8 + base size=74 base align=8 +QTransform (0x0x7fc66c6cb5a0) 0 + +Vtable for QImage +QImage::_ZTV6QImage: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QImage) +16 (int (*)(...))QImage::~QImage +24 (int (*)(...))QImage::~QImage +32 (int (*)(...))QImage::devType +40 (int (*)(...))QImage::paintEngine +48 (int (*)(...))QImage::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QImage + size=24 align=8 + base size=24 base align=8 +QImage (0x0x7fc67632bf70) 0 + vptr=((& QImage::_ZTV6QImage) + 16) + QPaintDevice (0x0x7fc66c6ff1e0) 0 + primary-for QImage (0x0x7fc67632bf70) + +Vtable for QPixmap +QPixmap::_ZTV7QPixmap: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QPixmap) +16 (int (*)(...))QPixmap::~QPixmap +24 (int (*)(...))QPixmap::~QPixmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPixmap + size=24 align=8 + base size=24 base align=8 +QPixmap (0x0x7fc67633d4e0) 0 + vptr=((& QPixmap::_ZTV7QPixmap) + 16) + QPaintDevice (0x0x7fc66c73e9c0) 0 + primary-for QPixmap (0x0x7fc67633d4e0) + +Class QIcon + size=8 align=8 + base size=8 base align=8 +QIcon (0x0x7fc66c777600) 0 + +Vtable for QAbstractFileIconProvider +QAbstractFileIconProvider::_ZTV25QAbstractFileIconProvider: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAbstractFileIconProvider) +16 (int (*)(...))QAbstractFileIconProvider::~QAbstractFileIconProvider +24 (int (*)(...))QAbstractFileIconProvider::~QAbstractFileIconProvider +32 (int (*)(...))QAbstractFileIconProvider::icon +40 (int (*)(...))QAbstractFileIconProvider::icon +48 (int (*)(...))QAbstractFileIconProvider::type +56 (int (*)(...))QAbstractFileIconProvider::setOptions +64 (int (*)(...))QAbstractFileIconProvider::options + +Class QAbstractFileIconProvider + size=16 align=8 + base size=16 base align=8 +QAbstractFileIconProvider (0x0x7fc66c7a4960) 0 + vptr=((& QAbstractFileIconProvider::_ZTV25QAbstractFileIconProvider) + 16) + +Class QVector2D + size=8 align=4 + base size=8 base align=4 +QVector2D (0x0x7fc66c7a4f00) 0 + +Class QVector3D + size=12 align=4 + base size=12 base align=4 +QVector3D (0x0x7fc66c3d9cc0) 0 + +Class QVector4D + size=16 align=4 + base size=16 base align=4 +QVector4D (0x0x7fc66c3fac60) 0 + +Class QScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScreen::QPrivateSignal (0x0x7fc66c463780) 0 empty + +Vtable for QScreen +QScreen::_ZTV7QScreen: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QScreen) +16 (int (*)(...))QScreen::metaObject +24 (int (*)(...))QScreen::qt_metacast +32 (int (*)(...))QScreen::qt_metacall +40 (int (*)(...))QScreen::~QScreen +48 (int (*)(...))QScreen::~QScreen +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScreen + size=16 align=8 + base size=16 base align=8 +QScreen (0x0x7fc6709bbd68) 0 + vptr=((& QScreen::_ZTV7QScreen) + 16) + QObject (0x0x7fc66c463720) 0 + primary-for QScreen (0x0x7fc6709bbd68) + +Class QInputDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputDevice::QPrivateSignal (0x0x7fc66c4639c0) 0 empty + +Vtable for QInputDevice +QInputDevice::_ZTV12QInputDevice: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputDevice) +16 (int (*)(...))QInputDevice::metaObject +24 (int (*)(...))QInputDevice::qt_metacast +32 (int (*)(...))QInputDevice::qt_metacall +40 (int (*)(...))QInputDevice::~QInputDevice +48 (int (*)(...))QInputDevice::~QInputDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputDevice + size=16 align=8 + base size=16 base align=8 +QInputDevice (0x0x7fc6705d0068) 0 + vptr=((& QInputDevice::_ZTV12QInputDevice) + 16) + QObject (0x0x7fc66c463960) 0 + primary-for QInputDevice (0x0x7fc6705d0068) + +Class QPointingDeviceUniqueId + size=8 align=8 + base size=8 base align=8 +QPointingDeviceUniqueId (0x0x7fc66c491480) 0 + +Class QPointingDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPointingDevice::QPrivateSignal (0x0x7fc66c4acde0) 0 empty + +Vtable for QPointingDevice +QPointingDevice::_ZTV15QPointingDevice: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPointingDevice) +16 (int (*)(...))QPointingDevice::metaObject +24 (int (*)(...))QPointingDevice::qt_metacast +32 (int (*)(...))QPointingDevice::qt_metacall +40 (int (*)(...))QPointingDevice::~QPointingDevice +48 (int (*)(...))QPointingDevice::~QPointingDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPointingDevice + size=16 align=8 + base size=16 base align=8 +QPointingDevice (0x0x7fc66ff7da90) 0 + vptr=((& QPointingDevice::_ZTV15QPointingDevice) + 16) + QInputDevice (0x0x7fc66ff7daf8) 0 + primary-for QPointingDevice (0x0x7fc66ff7da90) + QObject (0x0x7fc66c4acd80) 0 + primary-for QInputDevice (0x0x7fc66ff7daf8) + +Class QEventPoint + size=8 align=8 + base size=8 base align=8 +QEventPoint (0x0x7fc66c4bf540) 0 + +Class QKeySequence + size=8 align=8 + base size=8 base align=8 +QKeySequence (0x0x7fc66c50b480) 0 + +Vtable for QInputEvent +QInputEvent::_ZTV11QInputEvent: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QInputEvent) +16 (int (*)(...))QInputEvent::~QInputEvent +24 (int (*)(...))QInputEvent::~QInputEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QInputEvent::clone +48 (int (*)(...))QInputEvent::setTimestamp + +Class QInputEvent + size=40 align=8 + base size=40 base align=8 +QInputEvent (0x0x7fc66d202750) 0 + vptr=((& QInputEvent::_ZTV11QInputEvent) + 16) + QEvent (0x0x7fc66c533480) 0 + primary-for QInputEvent (0x0x7fc66d202750) + +Vtable for QPointerEvent +QPointerEvent::_ZTV13QPointerEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPointerEvent) +16 (int (*)(...))QPointerEvent::~QPointerEvent +24 (int (*)(...))QPointerEvent::~QPointerEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QPointerEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QPointerEvent::isBeginEvent +64 (int (*)(...))QPointerEvent::isUpdateEvent +72 (int (*)(...))QPointerEvent::isEndEvent + +Class QPointerEvent + size=64 align=8 + base size=64 base align=8 +QPointerEvent (0x0x7fc66d2027b8) 0 + vptr=((& QPointerEvent::_ZTV13QPointerEvent) + 16) + QInputEvent (0x0x7fc66d202af8) 0 + primary-for QPointerEvent (0x0x7fc66d2027b8) + QEvent (0x0x7fc66c533960) 0 + primary-for QInputEvent (0x0x7fc66d202af8) + +Vtable for QSinglePointEvent +QSinglePointEvent::_ZTV17QSinglePointEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSinglePointEvent) +16 (int (*)(...))QSinglePointEvent::~QSinglePointEvent +24 (int (*)(...))QSinglePointEvent::~QSinglePointEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QSinglePointEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QSinglePointEvent + size=80 align=8 + base size=80 base align=8 +QSinglePointEvent (0x0x7fc66d367ea0) 0 + vptr=((& QSinglePointEvent::_ZTV17QSinglePointEvent) + 16) + QPointerEvent (0x0x7fc66d382618) 0 + primary-for QSinglePointEvent (0x0x7fc66d367ea0) + QInputEvent (0x0x7fc66d382680) 0 + primary-for QPointerEvent (0x0x7fc66d382618) + QEvent (0x0x7fc66c571840) 0 + primary-for QInputEvent (0x0x7fc66d382680) + +Vtable for QEnterEvent +QEnterEvent::_ZTV11QEnterEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QEnterEvent) +16 (int (*)(...))QEnterEvent::~QEnterEvent +24 (int (*)(...))QEnterEvent::~QEnterEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QEnterEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QEnterEvent + size=80 align=8 + base size=80 base align=8 +QEnterEvent (0x0x7fc66d382e38) 0 + vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16) + QSinglePointEvent (0x0x7fc66d382ea0) 0 + primary-for QEnterEvent (0x0x7fc66d382e38) + QPointerEvent (0x0x7fc66d3bcf70) 0 + primary-for QSinglePointEvent (0x0x7fc66d382ea0) + QInputEvent (0x0x7fc66d3bc340) 0 + primary-for QPointerEvent (0x0x7fc66d3bcf70) + QEvent (0x0x7fc66c571d20) 0 + primary-for QInputEvent (0x0x7fc66d3bc340) + +Vtable for QMouseEvent +QMouseEvent::_ZTV11QMouseEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMouseEvent) +16 (int (*)(...))QMouseEvent::~QMouseEvent +24 (int (*)(...))QMouseEvent::~QMouseEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QMouseEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QMouseEvent + size=80 align=8 + base size=80 base align=8 +QMouseEvent (0x0x7fc66d3bc3a8) 0 + vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16) + QSinglePointEvent (0x0x7fc66d3bcd00) 0 + primary-for QMouseEvent (0x0x7fc66d3bc3a8) + QPointerEvent (0x0x7fc66d3bcd68) 0 + primary-for QSinglePointEvent (0x0x7fc66d3bcd00) + QInputEvent (0x0x7fc66c591000) 0 + primary-for QPointerEvent (0x0x7fc66d3bcd68) + QEvent (0x0x7fc66c58e4e0) 0 + primary-for QInputEvent (0x0x7fc66c591000) + +Vtable for QHoverEvent +QHoverEvent::_ZTV11QHoverEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHoverEvent) +16 (int (*)(...))QHoverEvent::~QHoverEvent +24 (int (*)(...))QHoverEvent::~QHoverEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QHoverEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QHoverEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QHoverEvent + size=96 align=8 + base size=96 base align=8 +QHoverEvent (0x0x7fc66c591068) 0 + vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16) + QSinglePointEvent (0x0x7fc66c5910d0) 0 + primary-for QHoverEvent (0x0x7fc66c591068) + QPointerEvent (0x0x7fc66c591138) 0 + primary-for QSinglePointEvent (0x0x7fc66c5910d0) + QInputEvent (0x0x7fc66c5911a0) 0 + primary-for QPointerEvent (0x0x7fc66c591138) + QEvent (0x0x7fc66c58ea80) 0 + primary-for QInputEvent (0x0x7fc66c5911a0) + +Vtable for QWheelEvent +QWheelEvent::_ZTV11QWheelEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWheelEvent) +16 (int (*)(...))QWheelEvent::~QWheelEvent +24 (int (*)(...))QWheelEvent::~QWheelEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QWheelEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QWheelEvent::isBeginEvent +64 (int (*)(...))QWheelEvent::isUpdateEvent +72 (int (*)(...))QWheelEvent::isEndEvent + +Class QWheelEvent + size=96 align=8 + base size=96 base align=8 +QWheelEvent (0x0x7fc66c591208) 0 + vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16) + QSinglePointEvent (0x0x7fc66c591270) 0 + primary-for QWheelEvent (0x0x7fc66c591208) + QPointerEvent (0x0x7fc66c5912d8) 0 + primary-for QSinglePointEvent (0x0x7fc66c591270) + QInputEvent (0x0x7fc66c591340) 0 + primary-for QPointerEvent (0x0x7fc66c5912d8) + QEvent (0x0x7fc66c58eea0) 0 + primary-for QInputEvent (0x0x7fc66c591340) + +Vtable for QTabletEvent +QTabletEvent::_ZTV12QTabletEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTabletEvent) +16 (int (*)(...))QTabletEvent::~QTabletEvent +24 (int (*)(...))QTabletEvent::~QTabletEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QTabletEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QTabletEvent + size=96 align=8 + base size=96 base align=8 +QTabletEvent (0x0x7fc66c5913a8) 0 + vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16) + QSinglePointEvent (0x0x7fc66c591410) 0 + primary-for QTabletEvent (0x0x7fc66c5913a8) + QPointerEvent (0x0x7fc66c591478) 0 + primary-for QSinglePointEvent (0x0x7fc66c591410) + QInputEvent (0x0x7fc66c5914e0) 0 + primary-for QPointerEvent (0x0x7fc66c591478) + QEvent (0x0x7fc66c5ad3c0) 0 + primary-for QInputEvent (0x0x7fc66c5914e0) + +Vtable for QNativeGestureEvent +QNativeGestureEvent::_ZTV19QNativeGestureEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNativeGestureEvent) +16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QNativeGestureEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QNativeGestureEvent + size=112 align=8 + base size=112 base align=8 +QNativeGestureEvent (0x0x7fc66c591548) 0 + vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16) + QSinglePointEvent (0x0x7fc66c5915b0) 0 + primary-for QNativeGestureEvent (0x0x7fc66c591548) + QPointerEvent (0x0x7fc66c591618) 0 + primary-for QSinglePointEvent (0x0x7fc66c5915b0) + QInputEvent (0x0x7fc66c591680) 0 + primary-for QPointerEvent (0x0x7fc66c591618) + QEvent (0x0x7fc66c5adc60) 0 + primary-for QInputEvent (0x0x7fc66c591680) + +Vtable for QKeyEvent +QKeyEvent::_ZTV9QKeyEvent: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QKeyEvent) +16 (int (*)(...))QKeyEvent::~QKeyEvent +24 (int (*)(...))QKeyEvent::~QKeyEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QKeyEvent::clone +48 (int (*)(...))QInputEvent::setTimestamp + +Class QKeyEvent + size=88 align=8 + base size=82 base align=8 +QKeyEvent (0x0x7fc66c5916e8) 0 + vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16) + QInputEvent (0x0x7fc66c591750) 0 + primary-for QKeyEvent (0x0x7fc66c5916e8) + QEvent (0x0x7fc66c1c7240) 0 + primary-for QInputEvent (0x0x7fc66c591750) + +Vtable for QFocusEvent +QFocusEvent::_ZTV11QFocusEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusEvent) +16 (int (*)(...))QFocusEvent::~QFocusEvent +24 (int (*)(...))QFocusEvent::~QFocusEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QFocusEvent::clone + +Class QFocusEvent + size=24 align=8 + base size=20 base align=8 +QFocusEvent (0x0x7fc66c5917b8) 0 + vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16) + QEvent (0x0x7fc66c1c7840) 0 + primary-for QFocusEvent (0x0x7fc66c5917b8) + +Vtable for QPaintEvent +QPaintEvent::_ZTV11QPaintEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPaintEvent) +16 (int (*)(...))QPaintEvent::~QPaintEvent +24 (int (*)(...))QPaintEvent::~QPaintEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QPaintEvent::clone + +Class QPaintEvent + size=48 align=8 + base size=41 base align=8 +QPaintEvent (0x0x7fc66c591820) 0 + vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16) + QEvent (0x0x7fc66c1c7ba0) 0 + primary-for QPaintEvent (0x0x7fc66c591820) + +Vtable for QMoveEvent +QMoveEvent::_ZTV10QMoveEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QMoveEvent) +16 (int (*)(...))QMoveEvent::~QMoveEvent +24 (int (*)(...))QMoveEvent::~QMoveEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QMoveEvent::clone + +Class QMoveEvent + size=32 align=8 + base size=32 base align=8 +QMoveEvent (0x0x7fc66c591888) 0 + vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16) + QEvent (0x0x7fc66c1c7ea0) 0 + primary-for QMoveEvent (0x0x7fc66c591888) + +Vtable for QExposeEvent +QExposeEvent::_ZTV12QExposeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QExposeEvent) +16 (int (*)(...))QExposeEvent::~QExposeEvent +24 (int (*)(...))QExposeEvent::~QExposeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QExposeEvent::clone + +Class QExposeEvent + size=24 align=8 + base size=24 base align=8 +QExposeEvent (0x0x7fc66c5918f0) 0 + vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16) + QEvent (0x0x7fc66c1e7240) 0 + primary-for QExposeEvent (0x0x7fc66c5918f0) + +Vtable for QPlatformSurfaceEvent +QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent) +16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QPlatformSurfaceEvent::clone + +Class QPlatformSurfaceEvent + size=24 align=8 + base size=20 base align=8 +QPlatformSurfaceEvent (0x0x7fc66c591958) 0 + vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16) + QEvent (0x0x7fc66c1e74e0) 0 + primary-for QPlatformSurfaceEvent (0x0x7fc66c591958) + +Vtable for QResizeEvent +QResizeEvent::_ZTV12QResizeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QResizeEvent) +16 (int (*)(...))QResizeEvent::~QResizeEvent +24 (int (*)(...))QResizeEvent::~QResizeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QResizeEvent::clone + +Class QResizeEvent + size=32 align=8 + base size=32 base align=8 +QResizeEvent (0x0x7fc66c5919c0) 0 + vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16) + QEvent (0x0x7fc66c1e77e0) 0 + primary-for QResizeEvent (0x0x7fc66c5919c0) + +Vtable for QCloseEvent +QCloseEvent::_ZTV11QCloseEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QCloseEvent) +16 (int (*)(...))QCloseEvent::~QCloseEvent +24 (int (*)(...))QCloseEvent::~QCloseEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QCloseEvent + size=16 align=8 + base size=16 base align=8 +QCloseEvent (0x0x7fc66c591a28) 0 + vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16) + QEvent (0x0x7fc66c1e7b40) 0 + primary-for QCloseEvent (0x0x7fc66c591a28) + +Vtable for QIconDragEvent +QIconDragEvent::_ZTV14QIconDragEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QIconDragEvent) +16 (int (*)(...))QIconDragEvent::~QIconDragEvent +24 (int (*)(...))QIconDragEvent::~QIconDragEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QIconDragEvent + size=16 align=8 + base size=16 base align=8 +QIconDragEvent (0x0x7fc66c591a90) 0 + vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16) + QEvent (0x0x7fc66c1e7ba0) 0 + primary-for QIconDragEvent (0x0x7fc66c591a90) + +Vtable for QShowEvent +QShowEvent::_ZTV10QShowEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QShowEvent) +16 (int (*)(...))QShowEvent::~QShowEvent +24 (int (*)(...))QShowEvent::~QShowEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QShowEvent + size=16 align=8 + base size=16 base align=8 +QShowEvent (0x0x7fc66c591af8) 0 + vptr=((& QShowEvent::_ZTV10QShowEvent) + 16) + QEvent (0x0x7fc66c1e7c00) 0 + primary-for QShowEvent (0x0x7fc66c591af8) + +Vtable for QHideEvent +QHideEvent::_ZTV10QHideEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHideEvent) +16 (int (*)(...))QHideEvent::~QHideEvent +24 (int (*)(...))QHideEvent::~QHideEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QHideEvent + size=16 align=8 + base size=16 base align=8 +QHideEvent (0x0x7fc66c591b60) 0 + vptr=((& QHideEvent::_ZTV10QHideEvent) + 16) + QEvent (0x0x7fc66c1e7c60) 0 + primary-for QHideEvent (0x0x7fc66c591b60) + +Vtable for QContextMenuEvent +QContextMenuEvent::_ZTV17QContextMenuEvent: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QContextMenuEvent) +16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QContextMenuEvent::clone +48 (int (*)(...))QInputEvent::setTimestamp + +Class QContextMenuEvent + size=64 align=8 + base size=57 base align=8 +QContextMenuEvent (0x0x7fc66c591bc8) 0 + vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16) + QInputEvent (0x0x7fc66c591c30) 0 + primary-for QContextMenuEvent (0x0x7fc66c591bc8) + QEvent (0x0x7fc66c1e7cc0) 0 + primary-for QInputEvent (0x0x7fc66c591c30) + +Class QInputMethodEvent::Attribute + size=48 align=8 + base size=48 base align=8 +QInputMethodEvent::Attribute (0x0x7fc66c20b2a0) 0 + +Vtable for QInputMethodEvent +QInputMethodEvent::_ZTV17QInputMethodEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QInputMethodEvent) +16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QInputMethodEvent::clone + +Class QInputMethodEvent + size=96 align=8 + base size=96 base align=8 +QInputMethodEvent (0x0x7fc66c591c98) 0 + vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16) + QEvent (0x0x7fc66c20b240) 0 + primary-for QInputMethodEvent (0x0x7fc66c591c98) + +Class QInputMethodQueryEvent::QueryPair + size=40 align=8 + base size=40 base align=8 +QInputMethodQueryEvent::QueryPair (0x0x7fc66c252a80) 0 + +Vtable for QInputMethodQueryEvent +QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent) +16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QInputMethodQueryEvent::clone + +Class QInputMethodQueryEvent + size=48 align=8 + base size=48 base align=8 +QInputMethodQueryEvent (0x0x7fc66c257c30) 0 + vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16) + QEvent (0x0x7fc66c252a20) 0 + primary-for QInputMethodQueryEvent (0x0x7fc66c257c30) + +Vtable for QDropEvent +QDropEvent::_ZTV10QDropEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDropEvent) +16 (int (*)(...))QDropEvent::~QDropEvent +24 (int (*)(...))QDropEvent::~QDropEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDropEvent::clone + +Class QDropEvent + size=64 align=8 + base size=64 base align=8 +QDropEvent (0x0x7fc66c29cb60) 0 + vptr=((& QDropEvent::_ZTV10QDropEvent) + 16) + QEvent (0x0x7fc66c299ba0) 0 + primary-for QDropEvent (0x0x7fc66c29cb60) + +Vtable for QDragMoveEvent +QDragMoveEvent::_ZTV14QDragMoveEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDragMoveEvent) +16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDragMoveEvent::clone + +Class QDragMoveEvent + size=80 align=8 + base size=80 base align=8 +QDragMoveEvent (0x0x7fc66c29cbc8) 0 + vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16) + QDropEvent (0x0x7fc66c29cc30) 0 + primary-for QDragMoveEvent (0x0x7fc66c29cbc8) + QEvent (0x0x7fc66c2aa300) 0 + primary-for QDropEvent (0x0x7fc66c29cc30) + +Vtable for QDragEnterEvent +QDragEnterEvent::_ZTV15QDragEnterEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragEnterEvent) +16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDragMoveEvent::clone + +Class QDragEnterEvent + size=80 align=8 + base size=80 base align=8 +QDragEnterEvent (0x0x7fc66c29cc98) 0 + vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16) + QDragMoveEvent (0x0x7fc66c29cd00) 0 + primary-for QDragEnterEvent (0x0x7fc66c29cc98) + QDropEvent (0x0x7fc66c29cd68) 0 + primary-for QDragMoveEvent (0x0x7fc66c29cd00) + QEvent (0x0x7fc66c2aa780) 0 + primary-for QDropEvent (0x0x7fc66c29cd68) + +Vtable for QDragLeaveEvent +QDragLeaveEvent::_ZTV15QDragLeaveEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragLeaveEvent) +16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QDragLeaveEvent + size=16 align=8 + base size=16 base align=8 +QDragLeaveEvent (0x0x7fc66c29cdd0) 0 + vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16) + QEvent (0x0x7fc66c2aa7e0) 0 + primary-for QDragLeaveEvent (0x0x7fc66c29cdd0) + +Vtable for QHelpEvent +QHelpEvent::_ZTV10QHelpEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHelpEvent) +16 (int (*)(...))QHelpEvent::~QHelpEvent +24 (int (*)(...))QHelpEvent::~QHelpEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QHelpEvent::clone + +Class QHelpEvent + size=32 align=8 + base size=32 base align=8 +QHelpEvent (0x0x7fc66c29ce38) 0 + vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16) + QEvent (0x0x7fc66c2aa840) 0 + primary-for QHelpEvent (0x0x7fc66c29ce38) + +Vtable for QStatusTipEvent +QStatusTipEvent::_ZTV15QStatusTipEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QStatusTipEvent) +16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QStatusTipEvent::clone + +Class QStatusTipEvent + size=40 align=8 + base size=40 base align=8 +QStatusTipEvent (0x0x7fc66c29cea0) 0 + vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16) + QEvent (0x0x7fc66c2aad20) 0 + primary-for QStatusTipEvent (0x0x7fc66c29cea0) + +Vtable for QWhatsThisClickedEvent +QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent) +16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QWhatsThisClickedEvent::clone + +Class QWhatsThisClickedEvent + size=40 align=8 + base size=40 base align=8 +QWhatsThisClickedEvent (0x0x7fc66c29cf08) 0 + vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16) + QEvent (0x0x7fc66c2c6000) 0 + primary-for QWhatsThisClickedEvent (0x0x7fc66c29cf08) + +Vtable for QActionEvent +QActionEvent::_ZTV12QActionEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionEvent) +16 (int (*)(...))QActionEvent::~QActionEvent +24 (int (*)(...))QActionEvent::~QActionEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QActionEvent::clone + +Class QActionEvent + size=32 align=8 + base size=32 base align=8 +QActionEvent (0x0x7fc66c29cf70) 0 + vptr=((& QActionEvent::_ZTV12QActionEvent) + 16) + QEvent (0x0x7fc66c2c62a0) 0 + primary-for QActionEvent (0x0x7fc66c29cf70) + +Vtable for QFileOpenEvent +QFileOpenEvent::_ZTV14QFileOpenEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QFileOpenEvent) +16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QFileOpenEvent::clone + +Class QFileOpenEvent + size=48 align=8 + base size=48 base align=8 +QFileOpenEvent (0x0x7fc66c2d1000) 0 + vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16) + QEvent (0x0x7fc66c2c6600) 0 + primary-for QFileOpenEvent (0x0x7fc66c2d1000) + +Vtable for QToolBarChangeEvent +QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QToolBarChangeEvent) +16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QToolBarChangeEvent::clone + +Class QToolBarChangeEvent + size=24 align=8 + base size=17 base align=8 +QToolBarChangeEvent (0x0x7fc66c2d1068) 0 + vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16) + QEvent (0x0x7fc66c2c6900) 0 + primary-for QToolBarChangeEvent (0x0x7fc66c2d1068) + +Vtable for QShortcutEvent +QShortcutEvent::_ZTV14QShortcutEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QShortcutEvent) +16 (int (*)(...))QShortcutEvent::~QShortcutEvent +24 (int (*)(...))QShortcutEvent::~QShortcutEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QShortcutEvent::clone + +Class QShortcutEvent + size=32 align=8 + base size=29 base align=8 +QShortcutEvent (0x0x7fc66c2d10d0) 0 + vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16) + QEvent (0x0x7fc66c2c6c00) 0 + primary-for QShortcutEvent (0x0x7fc66c2d10d0) + +Vtable for QWindowStateChangeEvent +QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent) +16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QWindowStateChangeEvent::clone + +Class QWindowStateChangeEvent + size=24 align=8 + base size=21 base align=8 +QWindowStateChangeEvent (0x0x7fc66c2d1138) 0 + vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16) + QEvent (0x0x7fc66c2c6f60) 0 + primary-for QWindowStateChangeEvent (0x0x7fc66c2d1138) + +Vtable for QTouchEvent +QTouchEvent::_ZTV11QTouchEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTouchEvent) +16 (int (*)(...))QTouchEvent::~QTouchEvent +24 (int (*)(...))QTouchEvent::~QTouchEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QTouchEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QTouchEvent::isBeginEvent +64 (int (*)(...))QTouchEvent::isUpdateEvent +72 (int (*)(...))QTouchEvent::isEndEvent + +Class QTouchEvent + size=80 align=8 + base size=79 base align=8 +QTouchEvent (0x0x7fc66c2d11a0) 0 + vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16) + QPointerEvent (0x0x7fc66c2d1208) 0 + primary-for QTouchEvent (0x0x7fc66c2d11a0) + QInputEvent (0x0x7fc66c2d1270) 0 + primary-for QPointerEvent (0x0x7fc66c2d1208) + QEvent (0x0x7fc66c2e82a0) 0 + primary-for QInputEvent (0x0x7fc66c2d1270) + +Vtable for QScrollPrepareEvent +QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollPrepareEvent) +16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QScrollPrepareEvent::clone + +Class QScrollPrepareEvent + size=96 align=8 + base size=96 base align=8 +QScrollPrepareEvent (0x0x7fc66c2d12d8) 0 + vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16) + QEvent (0x0x7fc66c2e8600) 0 + primary-for QScrollPrepareEvent (0x0x7fc66c2d12d8) + +Vtable for QScrollEvent +QScrollEvent::_ZTV12QScrollEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QScrollEvent) +16 (int (*)(...))QScrollEvent::~QScrollEvent +24 (int (*)(...))QScrollEvent::~QScrollEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QScrollEvent::clone + +Class QScrollEvent + size=56 align=8 + base size=52 base align=8 +QScrollEvent (0x0x7fc66c2d1340) 0 + vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16) + QEvent (0x0x7fc66c2e8a20) 0 + primary-for QScrollEvent (0x0x7fc66c2d1340) + +Vtable for QScreenOrientationChangeEvent +QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent) +16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QScreenOrientationChangeEvent::clone + +Class QScreenOrientationChangeEvent + size=32 align=8 + base size=28 base align=8 +QScreenOrientationChangeEvent (0x0x7fc66c2d13a8) 0 + vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16) + QEvent (0x0x7fc66c2e8de0) 0 + primary-for QScreenOrientationChangeEvent (0x0x7fc66c2d13a8) + +Vtable for QApplicationStateChangeEvent +QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent) +16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QApplicationStateChangeEvent::clone + +Class QApplicationStateChangeEvent + size=24 align=8 + base size=20 base align=8 +QApplicationStateChangeEvent (0x0x7fc66c2d1410) 0 + vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16) + QEvent (0x0x7fc66c308180) 0 + primary-for QApplicationStateChangeEvent (0x0x7fc66c2d1410) + +Class QFont + size=16 align=8 + base size=12 base align=8 +QFont (0x0x7fc66c308480) 0 + +Class QFontDatabase + size=1 align=1 + base size=0 base align=1 +QFontDatabase (0x0x7fc66c34d600) 0 empty + +Class QRawFont + size=8 align=8 + base size=8 base align=8 +QRawFont (0x0x7fc66c34d7e0) 0 + +Class QGlyphRun + size=8 align=8 + base size=8 base align=8 +QGlyphRun (0x0x7fc66c38d8a0) 0 + +Class QBrushDataPointerDeleter + size=1 align=1 + base size=0 base align=1 +QBrushDataPointerDeleter (0x0x7fc66bfcb0c0) 0 empty + +Class QBrush + size=8 align=8 + base size=8 base align=8 +QBrush (0x0x7fc66bfcb120) 0 + +Class QBrushData + size=104 align=8 + base size=104 base align=8 +QBrushData (0x0x7fc66c108b40) 0 + +Class QGradient::QGradientData + size=48 align=8 + base size=48 base align=8 +QGradient::QGradientData (0x0x7fc66c108d80) 0 + +Class QGradient + size=88 align=8 + base size=88 base align=8 +QGradient (0x0x7fc66c108d20) 0 + +Class QLinearGradient + size=88 align=8 + base size=88 base align=8 +QLinearGradient (0x0x7fc66c132410) 0 + QGradient (0x0x7fc66c12ec60) 0 + +Class QRadialGradient + size=88 align=8 + base size=88 base align=8 +QRadialGradient (0x0x7fc66c132478) 0 + QGradient (0x0x7fc66c12ed80) 0 + +Class QConicalGradient + size=88 align=8 + base size=88 base align=8 +QConicalGradient (0x0x7fc66c1324e0) 0 + QGradient (0x0x7fc66c12eea0) 0 + +Class QPen + size=8 align=8 + base size=8 base align=8 +QPen (0x0x7fc66c12ef60) 0 + +Class QTextOption::Tab + size=16 align=8 + base size=14 base align=8 +QTextOption::Tab (0x0x7fc66bdc5060) 0 + +Class QTextOption + size=24 align=8 + base size=24 base align=8 +QTextOption (0x0x7fc66bdc5000) 0 + +Class QTextLength + size=16 align=8 + base size=16 base align=8 +QTextLength (0x0x7fc66be01420) 0 + +Class QTextFormat + size=16 align=8 + base size=12 base align=8 +QTextFormat (0x0x7fc66be29120) 0 + +Class QTextCharFormat + size=16 align=8 + base size=12 base align=8 +QTextCharFormat (0x0x7fc66beb1f70) 0 + QTextFormat (0x0x7fc66beb98a0) 0 + +Class QTextBlockFormat + size=16 align=8 + base size=12 base align=8 +QTextBlockFormat (0x0x7fc66bf15d00) 0 + QTextFormat (0x0x7fc66bf13d80) 0 + +Class QTextListFormat + size=16 align=8 + base size=12 base align=8 +QTextListFormat (0x0x7fc66bf4a958) 0 + QTextFormat (0x0x7fc66bf50300) 0 + +Class QTextImageFormat + size=16 align=8 + base size=12 base align=8 +QTextImageFormat (0x0x7fc66bf6f548) 0 + QTextCharFormat (0x0x7fc66bf6f5b0) 0 + QTextFormat (0x0x7fc66bf771e0) 0 + +Class QTextFrameFormat + size=16 align=8 + base size=12 base align=8 +QTextFrameFormat (0x0x7fc66bf98208) 0 + QTextFormat (0x0x7fc66bf9c060) 0 + +Class QTextTableFormat + size=16 align=8 + base size=12 base align=8 +QTextTableFormat (0x0x7fc66bfb6e38) 0 + QTextFrameFormat (0x0x7fc66bfb6ea0) 0 + QTextFormat (0x0x7fc66bbc3480) 0 + +Class QTextTableCellFormat + size=16 align=8 + base size=12 base align=8 +QTextTableCellFormat (0x0x7fc66bbe9af8) 0 + QTextCharFormat (0x0x7fc66bbe9b60) 0 + QTextFormat (0x0x7fc66bbeb720) 0 + +Class QTextCursor + size=8 align=8 + base size=8 base align=8 +QTextCursor (0x0x7fc66bc17c60) 0 + +Class QTextInlineObject + size=16 align=8 + base size=16 base align=8 +QTextInlineObject (0x0x7fc66bc7e360) 0 + +Class QTextLayout::FormatRange + size=24 align=8 + base size=24 base align=8 +QTextLayout::FormatRange (0x0x7fc66bc7e780) 0 + +Class QTextLayout + size=8 align=8 + base size=8 base align=8 +QTextLayout (0x0x7fc66bc7e720) 0 + +Class QTextLine + size=16 align=8 + base size=16 base align=8 +QTextLine (0x0x7fc66bce9840) 0 + +Vtable for QAbstractUndoItem +QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractUndoItem) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAbstractUndoItem + size=8 align=8 + base size=8 base align=8 +QAbstractUndoItem (0x0x7fc66bce9cc0) 0 nearly-empty + vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16) + +Class QTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextDocument::QPrivateSignal (0x0x7fc66bce9f60) 0 empty + +Vtable for QTextDocument +QTextDocument::_ZTV13QTextDocument: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QTextDocument) +16 (int (*)(...))QTextDocument::metaObject +24 (int (*)(...))QTextDocument::qt_metacast +32 (int (*)(...))QTextDocument::qt_metacall +40 (int (*)(...))QTextDocument::~QTextDocument +48 (int (*)(...))QTextDocument::~QTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextDocument::clear +120 (int (*)(...))QTextDocument::createObject +128 (int (*)(...))QTextDocument::loadResource + +Class QTextDocument + size=16 align=8 + base size=16 base align=8 +QTextDocument (0x0x7fc66bcf17b8) 0 + vptr=((& QTextDocument::_ZTV13QTextDocument) + 16) + QObject (0x0x7fc66bce9f00) 0 + primary-for QTextDocument (0x0x7fc66bcf17b8) + +Class QPalette + size=16 align=8 + base size=12 base align=8 +QPalette (0x0x7fc66bd24840) 0 + +Class QAbstractTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTextDocumentLayout::QPrivateSignal (0x0x7fc66bdbbc60) 0 empty + +Class QAbstractTextDocumentLayout::Selection + size=24 align=8 + base size=24 base align=8 +QAbstractTextDocumentLayout::Selection (0x0x7fc66bdbbcc0) 0 + +Class QAbstractTextDocumentLayout::PaintContext + size=80 align=8 + base size=80 base align=8 +QAbstractTextDocumentLayout::PaintContext (0x0x7fc66bdbbd20) 0 + +Vtable for QAbstractTextDocumentLayout +QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout) +16 (int (*)(...))QAbstractTextDocumentLayout::metaObject +24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast +32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QAbstractTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QAbstractTextDocumentLayout (0x0x7fc66bdbebc8) 0 + vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16) + QObject (0x0x7fc66bdbbc00) 0 + primary-for QAbstractTextDocumentLayout (0x0x7fc66bdbebc8) + +Vtable for QTextObjectInterface +QTextObjectInterface::_ZTV20QTextObjectInterface: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextObjectInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QTextObjectInterface + size=8 align=8 + base size=8 base align=8 +QTextObjectInterface (0x0x7fc66ba65300) 0 nearly-empty + vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16) + +Class QAccessible::State + size=8 align=8 + base size=5 base align=8 +QAccessible::State (0x0x7fc66ba65540) 0 + +Vtable for QAccessible::ActivationObserver +QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAccessible::ActivationObserver + size=8 align=8 + base size=8 base align=8 +QAccessible::ActivationObserver (0x0x7fc66ba655a0) 0 nearly-empty + vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16) + +Class QAccessible + size=1 align=1 + base size=0 base align=1 +QAccessible (0x0x7fc66ba654e0) 0 empty + +Vtable for QAccessibleInterface +QAccessibleInterface::_ZTV20QAccessibleInterface: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAccessibleInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleInterface (0x0x7fc66ba65ea0) 0 nearly-empty + vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16) + +Vtable for QAccessibleTextInterface +QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAccessibleTextInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset +104 (int (*)(...))QAccessibleTextInterface::textAfterOffset +112 (int (*)(...))QAccessibleTextInterface::textAtOffset +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTextInterface (0x0x7fc66baa92a0) 0 nearly-empty + vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16) + +Vtable for QAccessibleEditableTextInterface +QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleEditableTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleEditableTextInterface (0x0x7fc66baa9300) 0 nearly-empty + vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16) + +Vtable for QAccessibleValueInterface +QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleValueInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleValueInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleValueInterface (0x0x7fc66baa9360) 0 nearly-empty + vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16) + +Vtable for QAccessibleTableCellInterface +QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableCellInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableCellInterface (0x0x7fc66baa93c0) 0 nearly-empty + vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16) + +Vtable for QAccessibleTableInterface +QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleTableInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableInterface (0x0x7fc66baa9420) 0 nearly-empty + vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16) + +Vtable for QAccessibleActionInterface +QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleActionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QAccessibleActionInterface::localizedActionName +48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleActionInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleActionInterface (0x0x7fc66baa9480) 0 nearly-empty + vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16) + +Vtable for QAccessibleImageInterface +QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleImageInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleImageInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleImageInterface (0x0x7fc66baa9540) 0 nearly-empty + vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16) + +Vtable for QAccessibleHyperlinkInterface +QAccessibleHyperlinkInterface::_ZTV29QAccessibleHyperlinkInterface: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleHyperlinkInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleHyperlinkInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleHyperlinkInterface (0x0x7fc66baa95a0) 0 nearly-empty + vptr=((& QAccessibleHyperlinkInterface::_ZTV29QAccessibleHyperlinkInterface) + 16) + +Vtable for QAccessibleEvent +QAccessibleEvent::_ZTV16QAccessibleEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAccessibleEvent) +16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleEvent + size=32 align=8 + base size=28 base align=8 +QAccessibleEvent (0x0x7fc66baa9600) 0 + vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16) + +Vtable for QAccessibleStateChangeEvent +QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent) +16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleStateChangeEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleStateChangeEvent (0x0x7fc66ba860d0) 0 + vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16) + QAccessibleEvent (0x0x7fc66baa9b40) 0 + primary-for QAccessibleStateChangeEvent (0x0x7fc66ba860d0) + +Vtable for QAccessibleTextCursorEvent +QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent) +16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextCursorEvent + size=32 align=8 + base size=32 base align=8 +QAccessibleTextCursorEvent (0x0x7fc66ba86138) 0 + vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16) + QAccessibleEvent (0x0x7fc66baa9f00) 0 + primary-for QAccessibleTextCursorEvent (0x0x7fc66ba86138) + +Vtable for QAccessibleTextSelectionEvent +QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent) +16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextSelectionEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleTextSelectionEvent (0x0x7fc66ba861a0) 0 + vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16) + QAccessibleTextCursorEvent (0x0x7fc66ba86208) 0 + primary-for QAccessibleTextSelectionEvent (0x0x7fc66ba861a0) + QAccessibleEvent (0x0x7fc66bada360) 0 + primary-for QAccessibleTextCursorEvent (0x0x7fc66ba86208) + +Vtable for QAccessibleTextInsertEvent +QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent) +16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextInsertEvent + size=64 align=8 + base size=64 base align=8 +QAccessibleTextInsertEvent (0x0x7fc66ba86270) 0 + vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16) + QAccessibleTextCursorEvent (0x0x7fc66ba862d8) 0 + primary-for QAccessibleTextInsertEvent (0x0x7fc66ba86270) + QAccessibleEvent (0x0x7fc66bada7e0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7fc66ba862d8) + +Vtable for QAccessibleTextRemoveEvent +QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent) +16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextRemoveEvent + size=64 align=8 + base size=64 base align=8 +QAccessibleTextRemoveEvent (0x0x7fc66ba86340) 0 + vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16) + QAccessibleTextCursorEvent (0x0x7fc66ba863a8) 0 + primary-for QAccessibleTextRemoveEvent (0x0x7fc66ba86340) + QAccessibleEvent (0x0x7fc66badac00) 0 + primary-for QAccessibleTextCursorEvent (0x0x7fc66ba863a8) + +Vtable for QAccessibleTextUpdateEvent +QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent) +16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextUpdateEvent + size=88 align=8 + base size=88 base align=8 +QAccessibleTextUpdateEvent (0x0x7fc66ba86410) 0 + vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16) + QAccessibleTextCursorEvent (0x0x7fc66ba86478) 0 + primary-for QAccessibleTextUpdateEvent (0x0x7fc66ba86410) + QAccessibleEvent (0x0x7fc66baef060) 0 + primary-for QAccessibleTextCursorEvent (0x0x7fc66ba86478) + +Vtable for QAccessibleValueChangeEvent +QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent) +16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleValueChangeEvent + size=64 align=8 + base size=64 base align=8 +QAccessibleValueChangeEvent (0x0x7fc66ba864e0) 0 + vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16) + QAccessibleEvent (0x0x7fc66baef4e0) 0 + primary-for QAccessibleValueChangeEvent (0x0x7fc66ba864e0) + +Vtable for QAccessibleTableModelChangeEvent +QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent) +16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTableModelChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTableModelChangeEvent (0x0x7fc66ba86548) 0 + vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16) + QAccessibleEvent (0x0x7fc66baef900) 0 + primary-for QAccessibleTableModelChangeEvent (0x0x7fc66ba86548) + +Vtable for QAccessibleBridge +QAccessibleBridge::_ZTV17QAccessibleBridge: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleBridge) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridge + size=8 align=8 + base size=8 base align=8 +QAccessibleBridge (0x0x7fc66bb081e0) 0 nearly-empty + vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16) + +Class QAccessibleBridgePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessibleBridgePlugin::QPrivateSignal (0x0x7fc66bb08480) 0 empty + +Vtable for QAccessibleBridgePlugin +QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin) +16 (int (*)(...))QAccessibleBridgePlugin::metaObject +24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast +32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridgePlugin + size=16 align=8 + base size=16 base align=8 +QAccessibleBridgePlugin (0x0x7fc66ba865b0) 0 + vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16) + QObject (0x0x7fc66bb08420) 0 + primary-for QAccessibleBridgePlugin (0x0x7fc66ba865b0) + +Vtable for QAccessibleObject +QAccessibleObject::_ZTV17QAccessibleObject: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleObject) +16 0 +24 0 +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleObject + size=16 align=8 + base size=16 base align=8 +QAccessibleObject (0x0x7fc66ba86618) 0 + vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16) + QAccessibleInterface (0x0x7fc66bb08540) 0 nearly-empty + primary-for QAccessibleObject (0x0x7fc66ba86618) + +Vtable for QAccessibleApplication +QAccessibleApplication::_ZTV22QAccessibleApplication: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QAccessibleApplication) +16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleApplication::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleApplication::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleApplication::parent +88 (int (*)(...))QAccessibleApplication::child +96 (int (*)(...))QAccessibleApplication::childCount +104 (int (*)(...))QAccessibleApplication::indexOfChild +112 (int (*)(...))QAccessibleApplication::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))QAccessibleApplication::role +144 (int (*)(...))QAccessibleApplication::state +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleApplication + size=16 align=8 + base size=16 base align=8 +QAccessibleApplication (0x0x7fc66ba86680) 0 + vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16) + QAccessibleObject (0x0x7fc66ba866e8) 0 + primary-for QAccessibleApplication (0x0x7fc66ba86680) + QAccessibleInterface (0x0x7fc66bb085a0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7fc66ba866e8) + +Class QAccessiblePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessiblePlugin::QPrivateSignal (0x0x7fc66bb08660) 0 empty + +Vtable for QAccessiblePlugin +QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessiblePlugin) +16 (int (*)(...))QAccessiblePlugin::metaObject +24 (int (*)(...))QAccessiblePlugin::qt_metacast +32 (int (*)(...))QAccessiblePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessiblePlugin + size=16 align=8 + base size=16 base align=8 +QAccessiblePlugin (0x0x7fc66ba86750) 0 + vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16) + QObject (0x0x7fc66bb08600) 0 + primary-for QAccessiblePlugin (0x0x7fc66ba86750) + +Class QAction::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAction::QPrivateSignal (0x0x7fc66bb08780) 0 empty + +Vtable for QAction +QAction::_ZTV7QAction: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QAction) +16 (int (*)(...))QAction::metaObject +24 (int (*)(...))QAction::qt_metacast +32 (int (*)(...))QAction::qt_metacall +40 (int (*)(...))QAction::~QAction +48 (int (*)(...))QAction::~QAction +56 (int (*)(...))QAction::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QAction + size=16 align=8 + base size=16 base align=8 +QAction (0x0x7fc66ba867b8) 0 + vptr=((& QAction::_ZTV7QAction) + 16) + QObject (0x0x7fc66bb08720) 0 + primary-for QAction (0x0x7fc66ba867b8) + +Class QActionGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QActionGroup::QPrivateSignal (0x0x7fc66bb410c0) 0 empty + +Vtable for QActionGroup +QActionGroup::_ZTV12QActionGroup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionGroup) +16 (int (*)(...))QActionGroup::metaObject +24 (int (*)(...))QActionGroup::qt_metacast +32 (int (*)(...))QActionGroup::qt_metacall +40 (int (*)(...))QActionGroup::~QActionGroup +48 (int (*)(...))QActionGroup::~QActionGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QActionGroup + size=16 align=8 + base size=16 base align=8 +QActionGroup (0x0x7fc66ba86820) 0 + vptr=((& QActionGroup::_ZTV12QActionGroup) + 16) + QObject (0x0x7fc66bb41060) 0 + primary-for QActionGroup (0x0x7fc66ba86820) + +Class QSurfaceFormat + size=8 align=8 + base size=8 base align=8 +QSurfaceFormat (0x0x7fc66bb41360) 0 + +Vtable for QSurface +QSurface::_ZTV8QSurface: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSurface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QSurface + size=24 align=8 + base size=24 base align=8 +QSurface (0x0x7fc66bb41c60) 0 + vptr=((& QSurface::_ZTV8QSurface) + 16) + +Vtable for QBitmap +QBitmap::_ZTV7QBitmap: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBitmap) +16 (int (*)(...))QBitmap::~QBitmap +24 (int (*)(...))QBitmap::~QBitmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QBitmap + size=24 align=8 + base size=24 base align=8 +QBitmap (0x0x7fc66ba86a28) 0 + vptr=((& QBitmap::_ZTV7QBitmap) + 16) + QPixmap (0x0x7fc66ba86a90) 0 + primary-for QBitmap (0x0x7fc66ba86a28) + QPaintDevice (0x0x7fc66bb87300) 0 + primary-for QPixmap (0x0x7fc66ba86a90) + +Class QCursor + size=8 align=8 + base size=8 base align=8 +QCursor (0x0x7fc66bb9ec00) 0 + +Class QWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWindow::QPrivateSignal (0x0x7fc66b7e6e40) 0 empty + +Vtable for QWindow +QWindow::_ZTV7QWindow: 47 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWindow) +16 (int (*)(...))QWindow::metaObject +24 (int (*)(...))QWindow::qt_metacast +32 (int (*)(...))QWindow::qt_metacall +40 (int (*)(...))QWindow::~QWindow +48 (int (*)(...))QWindow::~QWindow +56 (int (*)(...))QWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QWindow::focusInEvent +192 (int (*)(...))QWindow::focusOutEvent +200 (int (*)(...))QWindow::showEvent +208 (int (*)(...))QWindow::hideEvent +216 (int (*)(...))QWindow::closeEvent +224 (int (*)(...))QWindow::keyPressEvent +232 (int (*)(...))QWindow::keyReleaseEvent +240 (int (*)(...))QWindow::mousePressEvent +248 (int (*)(...))QWindow::mouseReleaseEvent +256 (int (*)(...))QWindow::mouseDoubleClickEvent +264 (int (*)(...))QWindow::mouseMoveEvent +272 (int (*)(...))QWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))-16 +320 (int (*)(...))(& _ZTI7QWindow) +328 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev +336 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QWindow + size=40 align=8 + base size=40 base align=8 +QWindow (0x0x7fc66b7f5150) 0 + vptr=((& QWindow::_ZTV7QWindow) + 16) + QObject (0x0x7fc66b7e6d80) 0 + primary-for QWindow (0x0x7fc66b7f5150) + QSurface (0x0x7fc66b7e6de0) 16 + vptr=((& QWindow::_ZTV7QWindow) + 328) + +Class QBackingStore + size=8 align=8 + base size=8 base align=8 +QBackingStore (0x0x7fc66b821720) 0 + +Class QClipboard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QClipboard::QPrivateSignal (0x0x7fc66b821840) 0 empty + +Vtable for QClipboard +QClipboard::_ZTV10QClipboard: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QClipboard) +16 (int (*)(...))QClipboard::metaObject +24 (int (*)(...))QClipboard::qt_metacast +32 (int (*)(...))QClipboard::qt_metacall +40 (int (*)(...))QClipboard::~QClipboard +48 (int (*)(...))QClipboard::~QClipboard +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QClipboard + size=16 align=8 + base size=16 base align=8 +QClipboard (0x0x7fc66b7f31a0) 0 + vptr=((& QClipboard::_ZTV10QClipboard) + 16) + QObject (0x0x7fc66b8217e0) 0 + primary-for QClipboard (0x0x7fc66b7f31a0) + +Class QColorTransform + size=8 align=8 + base size=8 base align=8 +QColorTransform (0x0x7fc66b821960) 0 + +Class QColorSpace + size=8 align=8 + base size=8 base align=8 +QColorSpace (0x0x7fc66b87b960) 0 + +Class QDesktopServices + size=1 align=1 + base size=0 base align=1 +QDesktopServices (0x0x7fc66b8d5720) 0 empty + +Class QDrag::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDrag::QPrivateSignal (0x0x7fc66b8d57e0) 0 empty + +Vtable for QDrag +QDrag::_ZTV5QDrag: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDrag) +16 (int (*)(...))QDrag::metaObject +24 (int (*)(...))QDrag::qt_metacast +32 (int (*)(...))QDrag::qt_metacall +40 (int (*)(...))QDrag::~QDrag +48 (int (*)(...))QDrag::~QDrag +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDrag + size=16 align=8 + base size=16 base align=8 +QDrag (0x0x7fc66b8d1d00) 0 + vptr=((& QDrag::_ZTV5QDrag) + 16) + QObject (0x0x7fc66b8d5780) 0 + primary-for QDrag (0x0x7fc66b8d1d00) + +Class QFileSystemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemModel::QPrivateSignal (0x0x7fc66b8d59c0) 0 empty + +Vtable for QFileSystemModel +QFileSystemModel::_ZTV16QFileSystemModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QFileSystemModel) +16 (int (*)(...))QFileSystemModel::metaObject +24 (int (*)(...))QFileSystemModel::qt_metacast +32 (int (*)(...))QFileSystemModel::qt_metacall +40 (int (*)(...))QFileSystemModel::~QFileSystemModel +48 (int (*)(...))QFileSystemModel::~QFileSystemModel +56 (int (*)(...))QFileSystemModel::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QFileSystemModel::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileSystemModel::index +120 (int (*)(...))QFileSystemModel::parent +128 (int (*)(...))QFileSystemModel::sibling +136 (int (*)(...))QFileSystemModel::rowCount +144 (int (*)(...))QFileSystemModel::columnCount +152 (int (*)(...))QFileSystemModel::hasChildren +160 (int (*)(...))QFileSystemModel::data +168 (int (*)(...))QFileSystemModel::setData +176 (int (*)(...))QFileSystemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QFileSystemModel::mimeTypes +224 (int (*)(...))QFileSystemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QFileSystemModel::dropMimeData +248 (int (*)(...))QFileSystemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QFileSystemModel::fetchMore +320 (int (*)(...))QFileSystemModel::canFetchMore +328 (int (*)(...))QFileSystemModel::flags +336 (int (*)(...))QFileSystemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QFileSystemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QFileSystemModel + size=16 align=8 + base size=16 base align=8 +QFileSystemModel (0x0x7fc66b8d1d68) 0 + vptr=((& QFileSystemModel::_ZTV16QFileSystemModel) + 16) + QAbstractItemModel (0x0x7fc66b8d1dd0) 0 + primary-for QFileSystemModel (0x0x7fc66b8d1d68) + QObject (0x0x7fc66b8d5960) 0 + primary-for QAbstractItemModel (0x0x7fc66b8d1dd0) + +Class QFontInfo + size=8 align=8 + base size=8 base align=8 +QFontInfo (0x0x7fc66b91a0c0) 0 + +Class QFontMetrics + size=8 align=8 + base size=8 base align=8 +QFontMetrics (0x0x7fc66b9319c0) 0 + +Class QFontMetricsF + size=8 align=8 + base size=8 base align=8 +QFontMetricsF (0x0x7fc66b960420) 0 + +Class QGenericPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGenericPlugin::QPrivateSignal (0x0x7fc66b5ee120) 0 empty + +Vtable for QGenericPlugin +QGenericPlugin::_ZTV14QGenericPlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGenericPlugin) +16 (int (*)(...))QGenericPlugin::metaObject +24 (int (*)(...))QGenericPlugin::qt_metacast +32 (int (*)(...))QGenericPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGenericPlugin + size=16 align=8 + base size=16 base align=8 +QGenericPlugin (0x0x7fc66b98cf70) 0 + vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16) + QObject (0x0x7fc66b5ee0c0) 0 + primary-for QGenericPlugin (0x0x7fc66b98cf70) + +Class QGenericPluginFactory + size=1 align=1 + base size=0 base align=1 +QGenericPluginFactory (0x0x7fc66b5ee1e0) 0 empty + +Class QInputMethod::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputMethod::QPrivateSignal (0x0x7fc66b5ee2a0) 0 empty + +Vtable for QInputMethod +QInputMethod::_ZTV12QInputMethod: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputMethod) +16 (int (*)(...))QInputMethod::metaObject +24 (int (*)(...))QInputMethod::qt_metacast +32 (int (*)(...))QInputMethod::qt_metacall +40 (int (*)(...))QInputMethod::~QInputMethod +48 (int (*)(...))QInputMethod::~QInputMethod +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputMethod + size=16 align=8 + base size=16 base align=8 +QInputMethod (0x0x7fc66b98c138) 0 + vptr=((& QInputMethod::_ZTV12QInputMethod) + 16) + QObject (0x0x7fc66b5ee240) 0 + primary-for QInputMethod (0x0x7fc66b98c138) + +Class QGuiApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGuiApplication::QPrivateSignal (0x0x7fc66b5ee540) 0 empty + +Vtable for QGuiApplication +QGuiApplication::_ZTV15QGuiApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGuiApplication) +16 (int (*)(...))QGuiApplication::metaObject +24 (int (*)(...))QGuiApplication::qt_metacast +32 (int (*)(...))QGuiApplication::qt_metacall +40 (int (*)(...))QGuiApplication::~QGuiApplication +48 (int (*)(...))QGuiApplication::~QGuiApplication +56 (int (*)(...))QGuiApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGuiApplication::notify +120 (int (*)(...))QGuiApplication::compressEvent + +Class QGuiApplication + size=16 align=8 + base size=16 base align=8 +QGuiApplication (0x0x7fc66b5ff000) 0 + vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16) + QCoreApplication (0x0x7fc66b5ff068) 0 + primary-for QGuiApplication (0x0x7fc66b5ff000) + QObject (0x0x7fc66b5ee4e0) 0 + primary-for QCoreApplication (0x0x7fc66b5ff068) + +Class QNativeInterface::QX11Application::TypeInfo + size=1 align=1 + base size=0 base align=1 +QNativeInterface::QX11Application::TypeInfo (0x0x7fc66b5ee840) 0 empty + +Vtable for QNativeInterface::QX11Application +QNativeInterface::QX11Application::_ZTVN16QNativeInterface15QX11ApplicationE: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface15QX11ApplicationE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QX11Application + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QX11Application (0x0x7fc66b5ee7e0) 0 nearly-empty + vptr=((& QNativeInterface::QX11Application::_ZTVN16QNativeInterface15QX11ApplicationE) + 16) + +Class QIconEngine::ScaledPixmapArgument + size=48 align=8 + base size=48 base align=8 +QIconEngine::ScaledPixmapArgument (0x0x7fc66b5ee900) 0 + +Vtable for QIconEngine +QIconEngine::_ZTV11QIconEngine: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QIconEngine) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QIconEngine::actualSize +48 (int (*)(...))QIconEngine::pixmap +56 (int (*)(...))QIconEngine::addPixmap +64 (int (*)(...))QIconEngine::addFile +72 (int (*)(...))QIconEngine::key +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QIconEngine::read +96 (int (*)(...))QIconEngine::write +104 (int (*)(...))QIconEngine::availableSizes +112 (int (*)(...))QIconEngine::iconName +120 (int (*)(...))QIconEngine::isNull +128 (int (*)(...))QIconEngine::scaledPixmap +136 (int (*)(...))QIconEngine::virtual_hook + +Class QIconEngine + size=8 align=8 + base size=8 base align=8 +QIconEngine (0x0x7fc66b5ee8a0) 0 nearly-empty + vptr=((& QIconEngine::_ZTV11QIconEngine) + 16) + +Class QIconEnginePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIconEnginePlugin::QPrivateSignal (0x0x7fc66b5ee9c0) 0 empty + +Vtable for QIconEnginePlugin +QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QIconEnginePlugin) +16 (int (*)(...))QIconEnginePlugin::metaObject +24 (int (*)(...))QIconEnginePlugin::qt_metacast +32 (int (*)(...))QIconEnginePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QIconEnginePlugin + size=16 align=8 + base size=16 base align=8 +QIconEnginePlugin (0x0x7fc66b5ff0d0) 0 + vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16) + QObject (0x0x7fc66b5ee960) 0 + primary-for QIconEnginePlugin (0x0x7fc66b5ff0d0) + +Vtable for QImageIOHandler +QImageIOHandler::_ZTV15QImageIOHandler: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QImageIOHandler) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QImageIOHandler::write +56 (int (*)(...))QImageIOHandler::option +64 (int (*)(...))QImageIOHandler::setOption +72 (int (*)(...))QImageIOHandler::supportsOption +80 (int (*)(...))QImageIOHandler::jumpToNextImage +88 (int (*)(...))QImageIOHandler::jumpToImage +96 (int (*)(...))QImageIOHandler::loopCount +104 (int (*)(...))QImageIOHandler::imageCount +112 (int (*)(...))QImageIOHandler::nextImageDelay +120 (int (*)(...))QImageIOHandler::currentImageNumber +128 (int (*)(...))QImageIOHandler::currentImageRect + +Class QImageIOHandler + size=16 align=8 + base size=16 base align=8 +QImageIOHandler (0x0x7fc66b5eea80) 0 + vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16) + +Class QImageIOPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QImageIOPlugin::QPrivateSignal (0x0x7fc66b5eecc0) 0 empty + +Vtable for QImageIOPlugin +QImageIOPlugin::_ZTV14QImageIOPlugin: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QImageIOPlugin) +16 (int (*)(...))QImageIOPlugin::metaObject +24 (int (*)(...))QImageIOPlugin::qt_metacast +32 (int (*)(...))QImageIOPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QImageIOPlugin + size=16 align=8 + base size=16 base align=8 +QImageIOPlugin (0x0x7fc66b5ff138) 0 + vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16) + QObject (0x0x7fc66b5eec60) 0 + primary-for QImageIOPlugin (0x0x7fc66b5ff138) + +Class QImageReader + size=8 align=8 + base size=8 base align=8 +QImageReader (0x0x7fc66b651180) 0 + +Class QImageWriter + size=8 align=8 + base size=8 base align=8 +QImageWriter (0x0x7fc66b651240) 0 + +Class QQuaternion + size=16 align=4 + base size=16 base align=4 +QQuaternion (0x0x7fc66b651300) 0 + +Class QMatrix4x4 + size=68 align=4 + base size=68 base align=4 +QMatrix4x4 (0x0x7fc66b6ad060) 0 + +Class QMovie::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMovie::QPrivateSignal (0x0x7fc66b7125a0) 0 empty + +Vtable for QMovie +QMovie::_ZTV6QMovie: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QMovie) +16 (int (*)(...))QMovie::metaObject +24 (int (*)(...))QMovie::qt_metacast +32 (int (*)(...))QMovie::qt_metacall +40 (int (*)(...))QMovie::~QMovie +48 (int (*)(...))QMovie::~QMovie +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QMovie + size=16 align=8 + base size=16 base align=8 +QMovie (0x0x7fc66b6f3958) 0 + vptr=((& QMovie::_ZTV6QMovie) + 16) + QObject (0x0x7fc66b712540) 0 + primary-for QMovie (0x0x7fc66b6f3958) + +Class QOffscreenSurface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOffscreenSurface::QPrivateSignal (0x0x7fc66b712960) 0 empty + +Vtable for QOffscreenSurface +QOffscreenSurface::_ZTV17QOffscreenSurface: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOffscreenSurface) +16 (int (*)(...))QOffscreenSurface::metaObject +24 (int (*)(...))QOffscreenSurface::qt_metacast +32 (int (*)(...))QOffscreenSurface::qt_metacall +40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOffscreenSurface::surfaceType +120 (int (*)(...))QOffscreenSurface::format +128 (int (*)(...))QOffscreenSurface::size +136 (int (*)(...))QOffscreenSurface::surfaceHandle +144 (int (*)(...))-16 +152 (int (*)(...))(& _ZTI17QOffscreenSurface) +160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev +168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev +176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv +184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv +192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv +200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv + +Class QOffscreenSurface + size=40 align=8 + base size=40 base align=8 +QOffscreenSurface (0x0x7fc66b6c1a80) 0 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16) + QObject (0x0x7fc66b7128a0) 0 + primary-for QOffscreenSurface (0x0x7fc66b6c1a80) + QSurface (0x0x7fc66b712900) 16 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160) + +Class QOpenGLContextGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContextGroup::QPrivateSignal (0x0x7fc66b712c00) 0 empty + +Vtable for QOpenGLContextGroup +QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QOpenGLContextGroup) +16 (int (*)(...))QOpenGLContextGroup::metaObject +24 (int (*)(...))QOpenGLContextGroup::qt_metacast +32 (int (*)(...))QOpenGLContextGroup::qt_metacall +40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContextGroup + size=16 align=8 + base size=16 base align=8 +QOpenGLContextGroup (0x0x7fc66b6f39c0) 0 + vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16) + QObject (0x0x7fc66b712ba0) 0 + primary-for QOpenGLContextGroup (0x0x7fc66b6f39c0) + +Class QOpenGLContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContext::QPrivateSignal (0x0x7fc66b712de0) 0 empty + +Vtable for QOpenGLContext +QOpenGLContext::_ZTV14QOpenGLContext: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QOpenGLContext) +16 (int (*)(...))QOpenGLContext::metaObject +24 (int (*)(...))QOpenGLContext::qt_metacast +32 (int (*)(...))QOpenGLContext::qt_metacall +40 (int (*)(...))QOpenGLContext::~QOpenGLContext +48 (int (*)(...))QOpenGLContext::~QOpenGLContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContext + size=16 align=8 + base size=16 base align=8 +QOpenGLContext (0x0x7fc66b6f3a28) 0 + vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16) + QObject (0x0x7fc66b712d80) 0 + primary-for QOpenGLContext (0x0x7fc66b6f3a28) + +Class QNativeInterface::QGLXContext::TypeInfo + size=1 align=1 + base size=0 base align=1 +QNativeInterface::QGLXContext::TypeInfo (0x0x7fc66b229060) 0 empty + +Vtable for QNativeInterface::QGLXContext +QNativeInterface::QGLXContext::_ZTVN16QNativeInterface11QGLXContextE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface11QGLXContextE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QGLXContext + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QGLXContext (0x0x7fc66b229000) 0 nearly-empty + vptr=((& QNativeInterface::QGLXContext::_ZTVN16QNativeInterface11QGLXContextE) + 16) + +Class QNativeInterface::QEGLContext::TypeInfo + size=1 align=1 + base size=0 base align=1 +QNativeInterface::QEGLContext::TypeInfo (0x0x7fc66b229120) 0 empty + +Vtable for QNativeInterface::QEGLContext +QNativeInterface::QEGLContext::_ZTVN16QNativeInterface11QEGLContextE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface11QEGLContextE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QEGLContext + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QEGLContext (0x0x7fc66b2290c0) 0 nearly-empty + vptr=((& QNativeInterface::QEGLContext::_ZTVN16QNativeInterface11QEGLContextE) + 16) + +Class QOpenGLFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLFunctions (0x0x7fc66b229180) 0 + +Class QOpenGLFunctionsPrivate::Functions + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate::Functions (0x0x7fc66b2297e0) 0 + +Class QOpenGLFunctionsPrivate + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate (0x0x7fc66b229780) 0 + +Class QOpenGLExtraFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLExtraFunctions (0x0x7fc66b6f3e38) 0 + QOpenGLFunctions (0x0x7fc66b2cdf60) 0 + +Class QOpenGLExtraFunctionsPrivate::Functions + size=1728 align=8 + base size=1728 base align=8 +QOpenGLExtraFunctionsPrivate::Functions (0x0x7fc66b32f300) 0 + +Class QOpenGLExtraFunctionsPrivate + size=2880 align=8 + base size=2880 base align=8 +QOpenGLExtraFunctionsPrivate (0x0x7fc66b6f3ea0) 0 + QOpenGLFunctionsPrivate (0x0x7fc66b32f2a0) 0 + +Class QPageSize + size=8 align=8 + base size=8 base align=8 +QPageSize (0x0x7fc66b02a000) 0 + +Class QPageLayout + size=8 align=8 + base size=8 base align=8 +QPageLayout (0x0x7fc66b09c600) 0 + +Class QPageRanges::Range + size=8 align=4 + base size=8 base align=4 +QPageRanges::Range (0x0x7fc66b154600) 0 + +Class QPageRanges + size=8 align=8 + base size=8 base align=8 +QPageRanges (0x0x7fc66b1545a0) 0 + +Vtable for QPagedPaintDevice +QPagedPaintDevice::_ZTV17QPagedPaintDevice: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QPagedPaintDevice) +16 0 +24 0 +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QPagedPaintDevice::setPageLayout +96 (int (*)(...))QPagedPaintDevice::setPageSize +104 (int (*)(...))QPagedPaintDevice::setPageOrientation +112 (int (*)(...))QPagedPaintDevice::setPageMargins +120 (int (*)(...))QPagedPaintDevice::setPageRanges + +Class QPagedPaintDevice + size=24 align=8 + base size=24 base align=8 +QPagedPaintDevice (0x0x7fc66adcdd00) 0 + vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16) + QPaintDevice (0x0x7fc66adccba0) 0 + primary-for QPagedPaintDevice (0x0x7fc66adcdd00) + +Class QPaintDeviceWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPaintDeviceWindow::QPrivateSignal (0x0x7fc66adccd20) 0 empty + +Vtable for QPaintDeviceWindow +QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 59 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +16 (int (*)(...))QPaintDeviceWindow::metaObject +24 (int (*)(...))QPaintDeviceWindow::qt_metacast +32 (int (*)(...))QPaintDeviceWindow::qt_metacall +40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QPaintDeviceWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QWindow::focusInEvent +192 (int (*)(...))QWindow::focusOutEvent +200 (int (*)(...))QWindow::showEvent +208 (int (*)(...))QWindow::hideEvent +216 (int (*)(...))QWindow::closeEvent +224 (int (*)(...))QWindow::keyPressEvent +232 (int (*)(...))QWindow::keyReleaseEvent +240 (int (*)(...))QWindow::mousePressEvent +248 (int (*)(...))QWindow::mouseReleaseEvent +256 (int (*)(...))QWindow::mouseDoubleClickEvent +264 (int (*)(...))QWindow::mouseMoveEvent +272 (int (*)(...))QWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))QPaintDeviceWindow::metric +320 (int (*)(...))QPaintDeviceWindow::paintEngine +328 (int (*)(...))-16 +336 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev +352 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +392 (int (*)(...))-40 +400 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev +416 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev +424 (int (*)(...))QPaintDevice::devType +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +440 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE +448 (int (*)(...))QPaintDevice::initPainter +456 (int (*)(...))QPaintDevice::redirected +464 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDeviceWindow + size=56 align=8 + base size=50 base align=8 +QPaintDeviceWindow (0x0x7fc66add5380) 0 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16) + QWindow (0x0x7fc66add53f0) 0 + primary-for QPaintDeviceWindow (0x0x7fc66add5380) + QObject (0x0x7fc66adccc00) 0 + primary-for QWindow (0x0x7fc66add53f0) + QSurface (0x0x7fc66adccc60) 16 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 344) + QPaintDevice (0x0x7fc66adcccc0) 40 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 408) + +Class QPainter::PixmapFragment + size=80 align=8 + base size=80 base align=8 +QPainter::PixmapFragment (0x0x7fc66adccf00) 0 + +Class QPainter + size=8 align=8 + base size=8 base align=8 +QPainter (0x0x7fc66adccea0) 0 + +Class QTextItem + size=1 align=1 + base size=0 base align=1 +QTextItem (0x0x7fc66ac15ae0) 0 empty + +Vtable for QPaintEngine +QPaintEngine::_ZTV12QPaintEngine: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintEngine) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QPaintEngine::drawRects +64 (int (*)(...))QPaintEngine::drawRects +72 (int (*)(...))QPaintEngine::drawLines +80 (int (*)(...))QPaintEngine::drawLines +88 (int (*)(...))QPaintEngine::drawEllipse +96 (int (*)(...))QPaintEngine::drawEllipse +104 (int (*)(...))QPaintEngine::drawPath +112 (int (*)(...))QPaintEngine::drawPoints +120 (int (*)(...))QPaintEngine::drawPoints +128 (int (*)(...))QPaintEngine::drawPolygon +136 (int (*)(...))QPaintEngine::drawPolygon +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QPaintEngine::drawTextItem +160 (int (*)(...))QPaintEngine::drawTiledPixmap +168 (int (*)(...))QPaintEngine::drawImage +176 (int (*)(...))QPaintEngine::coordinateOffset +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))QPaintEngine::createPixmap +200 (int (*)(...))QPaintEngine::createPixmapFromImage + +Class QPaintEngine + size=32 align=8 + base size=32 base align=8 +QPaintEngine (0x0x7fc66ac54300) 0 + vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16) + +Class QPaintEngineState + size=4 align=4 + base size=4 base align=4 +QPaintEngineState (0x0x7fc66ac54900) 0 + +Class QPainterPath::Element + size=24 align=8 + base size=24 base align=8 +QPainterPath::Element (0x0x7fc66acda600) 0 + +Class QPainterPath + size=8 align=8 + base size=8 base align=8 +QPainterPath (0x0x7fc66acda5a0) 0 + +Class QPainterPathStroker + size=8 align=8 + base size=8 base align=8 +QPainterPathStroker (0x0x7fc66ad98900) 0 + +Class QPdfWriter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPdfWriter::QPrivateSignal (0x0x7fc66a9c30c0) 0 empty + +Vtable for QPdfWriter +QPdfWriter::_ZTV10QPdfWriter: 33 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QPdfWriter) +16 (int (*)(...))QPdfWriter::metaObject +24 (int (*)(...))QPdfWriter::qt_metacast +32 (int (*)(...))QPdfWriter::qt_metacall +40 (int (*)(...))QPdfWriter::~QPdfWriter +48 (int (*)(...))QPdfWriter::~QPdfWriter +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPdfWriter::newPage +120 (int (*)(...))QPdfWriter::paintEngine +128 (int (*)(...))QPdfWriter::metric +136 (int (*)(...))-16 +144 (int (*)(...))(& _ZTI10QPdfWriter) +152 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev +160 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev +168 (int (*)(...))QPaintDevice::devType +176 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv +184 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE +192 (int (*)(...))QPaintDevice::initPainter +200 (int (*)(...))QPaintDevice::redirected +208 (int (*)(...))QPaintDevice::sharedPainter +216 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv +224 (int (*)(...))QPagedPaintDevice::setPageLayout +232 (int (*)(...))QPagedPaintDevice::setPageSize +240 (int (*)(...))QPagedPaintDevice::setPageOrientation +248 (int (*)(...))QPagedPaintDevice::setPageMargins +256 (int (*)(...))QPagedPaintDevice::setPageRanges + +Class QPdfWriter + size=40 align=8 + base size=40 base align=8 +QPdfWriter (0x0x7fc66ac66e00) 0 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16) + QObject (0x0x7fc66a9c3000) 0 + primary-for QPdfWriter (0x0x7fc66ac66e00) + QPagedPaintDevice (0x0x7fc66ad9ab60) 16 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 152) + QPaintDevice (0x0x7fc66a9c3060) 16 + primary-for QPagedPaintDevice (0x0x7fc66ad9ab60) + +Vtable for QPicture +QPicture::_ZTV8QPicture: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPicture) +16 (int (*)(...))QPicture::~QPicture +24 (int (*)(...))QPicture::~QPicture +32 (int (*)(...))QPicture::devType +40 (int (*)(...))QPicture::paintEngine +48 (int (*)(...))QPicture::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPicture::setData + +Class QPicture + size=24 align=8 + base size=24 base align=8 +QPicture (0x0x7fc66ad9abc8) 0 + vptr=((& QPicture::_ZTV8QPicture) + 16) + QPaintDevice (0x0x7fc66a9c32a0) 0 + primary-for QPicture (0x0x7fc66ad9abc8) + +Class QPixmapCache::Key + size=8 align=8 + base size=8 base align=8 +QPixmapCache::Key (0x0x7fc66aa0ad80) 0 + +Class QPixmapCache + size=1 align=1 + base size=0 base align=1 +QPixmapCache (0x0x7fc66aa0ad20) 0 empty + +Class QRasterWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRasterWindow::QPrivateSignal (0x0x7fc66aa8c060) 0 empty + +Vtable for QRasterWindow +QRasterWindow::_ZTV13QRasterWindow: 60 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QRasterWindow) +16 (int (*)(...))QRasterWindow::metaObject +24 (int (*)(...))QRasterWindow::qt_metacast +32 (int (*)(...))QRasterWindow::qt_metacall +40 (int (*)(...))QRasterWindow::~QRasterWindow +48 (int (*)(...))QRasterWindow::~QRasterWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QPaintDeviceWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QWindow::focusInEvent +192 (int (*)(...))QWindow::focusOutEvent +200 (int (*)(...))QWindow::showEvent +208 (int (*)(...))QWindow::hideEvent +216 (int (*)(...))QWindow::closeEvent +224 (int (*)(...))QWindow::keyPressEvent +232 (int (*)(...))QWindow::keyReleaseEvent +240 (int (*)(...))QWindow::mousePressEvent +248 (int (*)(...))QWindow::mouseReleaseEvent +256 (int (*)(...))QWindow::mouseDoubleClickEvent +264 (int (*)(...))QWindow::mouseMoveEvent +272 (int (*)(...))QWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))QRasterWindow::metric +320 (int (*)(...))QPaintDeviceWindow::paintEngine +328 (int (*)(...))QRasterWindow::redirected +336 (int (*)(...))-16 +344 (int (*)(...))(& _ZTI13QRasterWindow) +352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev +360 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +392 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +400 (int (*)(...))-40 +408 (int (*)(...))(& _ZTI13QRasterWindow) +416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev +424 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev +432 (int (*)(...))QPaintDevice::devType +440 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +448 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE +456 (int (*)(...))QPaintDevice::initPainter +464 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint +472 (int (*)(...))QPaintDevice::sharedPainter + +Class QRasterWindow + size=56 align=8 + base size=50 base align=8 +QRasterWindow (0x0x7fc66aa841a0) 0 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16) + QPaintDeviceWindow (0x0x7fc66aa15a10) 0 + primary-for QRasterWindow (0x0x7fc66aa841a0) + QWindow (0x0x7fc66aa15a80) 0 + primary-for QPaintDeviceWindow (0x0x7fc66aa15a10) + QObject (0x0x7fc66aa73f00) 0 + primary-for QWindow (0x0x7fc66aa15a80) + QSurface (0x0x7fc66aa73f60) 16 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 352) + QPaintDevice (0x0x7fc66aa8c000) 40 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 416) + +Class QSessionManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSessionManager::QPrivateSignal (0x0x7fc66aa8cd20) 0 empty + +Vtable for QSessionManager +QSessionManager::_ZTV15QSessionManager: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSessionManager) +16 (int (*)(...))QSessionManager::metaObject +24 (int (*)(...))QSessionManager::qt_metacast +32 (int (*)(...))QSessionManager::qt_metacall +40 (int (*)(...))QSessionManager::~QSessionManager +48 (int (*)(...))QSessionManager::~QSessionManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSessionManager + size=16 align=8 + base size=16 base align=8 +QSessionManager (0x0x7fc66aa84270) 0 + vptr=((& QSessionManager::_ZTV15QSessionManager) + 16) + QObject (0x0x7fc66aa8ccc0) 0 + primary-for QSessionManager (0x0x7fc66aa84270) + +Class QShortcut::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QShortcut::QPrivateSignal (0x0x7fc66aa8cf00) 0 empty + +Vtable for QShortcut +QShortcut::_ZTV9QShortcut: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QShortcut) +16 (int (*)(...))QShortcut::metaObject +24 (int (*)(...))QShortcut::qt_metacast +32 (int (*)(...))QShortcut::qt_metacall +40 (int (*)(...))QShortcut::~QShortcut +48 (int (*)(...))QShortcut::~QShortcut +56 (int (*)(...))QShortcut::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QShortcut + size=16 align=8 + base size=16 base align=8 +QShortcut (0x0x7fc66aa842d8) 0 + vptr=((& QShortcut::_ZTV9QShortcut) + 16) + QObject (0x0x7fc66aa8cea0) 0 + primary-for QShortcut (0x0x7fc66aa842d8) + +Vtable for QStandardItem +QStandardItem::_ZTV13QStandardItem: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStandardItem) +16 (int (*)(...))QStandardItem::~QStandardItem +24 (int (*)(...))QStandardItem::~QStandardItem +32 (int (*)(...))QStandardItem::data +40 (int (*)(...))QStandardItem::multiData +48 (int (*)(...))QStandardItem::setData +56 (int (*)(...))QStandardItem::clone +64 (int (*)(...))QStandardItem::type +72 (int (*)(...))QStandardItem::read +80 (int (*)(...))QStandardItem::write +88 (int (*)(...))QStandardItem::operator< + +Class QStandardItem + size=16 align=8 + base size=16 base align=8 +QStandardItem (0x0x7fc66aada420) 0 + vptr=((& QStandardItem::_ZTV13QStandardItem) + 16) + +Class QStandardItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStandardItemModel::QPrivateSignal (0x0x7fc66a7c8420) 0 empty + +Vtable for QStandardItemModel +QStandardItemModel::_ZTV18QStandardItemModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QStandardItemModel) +16 (int (*)(...))QStandardItemModel::metaObject +24 (int (*)(...))QStandardItemModel::qt_metacast +32 (int (*)(...))QStandardItemModel::qt_metacall +40 (int (*)(...))QStandardItemModel::~QStandardItemModel +48 (int (*)(...))QStandardItemModel::~QStandardItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStandardItemModel::index +120 (int (*)(...))QStandardItemModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QStandardItemModel::rowCount +144 (int (*)(...))QStandardItemModel::columnCount +152 (int (*)(...))QStandardItemModel::hasChildren +160 (int (*)(...))QStandardItemModel::data +168 (int (*)(...))QStandardItemModel::setData +176 (int (*)(...))QStandardItemModel::headerData +184 (int (*)(...))QStandardItemModel::setHeaderData +192 (int (*)(...))QStandardItemModel::itemData +200 (int (*)(...))QStandardItemModel::setItemData +208 (int (*)(...))QStandardItemModel::clearItemData +216 (int (*)(...))QStandardItemModel::mimeTypes +224 (int (*)(...))QStandardItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QStandardItemModel::dropMimeData +248 (int (*)(...))QStandardItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QStandardItemModel::insertRows +272 (int (*)(...))QStandardItemModel::insertColumns +280 (int (*)(...))QStandardItemModel::removeRows +288 (int (*)(...))QStandardItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QStandardItemModel::flags +336 (int (*)(...))QStandardItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QStandardItemModel::roleNames +376 (int (*)(...))QStandardItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QStandardItemModel + size=16 align=8 + base size=16 base align=8 +QStandardItemModel (0x0x7fc66aa84c30) 0 + vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16) + QAbstractItemModel (0x0x7fc66aa84c98) 0 + primary-for QStandardItemModel (0x0x7fc66aa84c30) + QObject (0x0x7fc66a7c83c0) 0 + primary-for QAbstractItemModel (0x0x7fc66aa84c98) + +Class QStaticText + size=8 align=8 + base size=8 base align=8 +QStaticText (0x0x7fc66a7c8780) 0 + +Class QStyleHints::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyleHints::QPrivateSignal (0x0x7fc66a878540) 0 empty + +Vtable for QStyleHints +QStyleHints::_ZTV11QStyleHints: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QStyleHints) +16 (int (*)(...))QStyleHints::metaObject +24 (int (*)(...))QStyleHints::qt_metacast +32 (int (*)(...))QStyleHints::qt_metacall +40 (int (*)(...))QStyleHints::~QStyleHints +48 (int (*)(...))QStyleHints::~QStyleHints +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QStyleHints + size=16 align=8 + base size=16 base align=8 +QStyleHints (0x0x7fc66a86a9c0) 0 + vptr=((& QStyleHints::_ZTV11QStyleHints) + 16) + QObject (0x0x7fc66a8784e0) 0 + primary-for QStyleHints (0x0x7fc66a86a9c0) + +Class QTextObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextObject::QPrivateSignal (0x0x7fc66a878720) 0 empty + +Vtable for QTextObject +QTextObject::_ZTV11QTextObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextObject) +16 (int (*)(...))QTextObject::metaObject +24 (int (*)(...))QTextObject::qt_metacast +32 (int (*)(...))QTextObject::qt_metacall +40 (int (*)(...))QTextObject::~QTextObject +48 (int (*)(...))QTextObject::~QTextObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextObject + size=16 align=8 + base size=16 base align=8 +QTextObject (0x0x7fc66a86aa28) 0 + vptr=((& QTextObject::_ZTV11QTextObject) + 16) + QObject (0x0x7fc66a8786c0) 0 + primary-for QTextObject (0x0x7fc66a86aa28) + +Class QTextBlockGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBlockGroup::QPrivateSignal (0x0x7fc66a878900) 0 empty + +Vtable for QTextBlockGroup +QTextBlockGroup::_ZTV15QTextBlockGroup: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTextBlockGroup) +16 (int (*)(...))QTextBlockGroup::metaObject +24 (int (*)(...))QTextBlockGroup::qt_metacast +32 (int (*)(...))QTextBlockGroup::qt_metacall +40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextBlockGroup + size=16 align=8 + base size=16 base align=8 +QTextBlockGroup (0x0x7fc66a86aa90) 0 + vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16) + QTextObject (0x0x7fc66a86aaf8) 0 + primary-for QTextBlockGroup (0x0x7fc66a86aa90) + QObject (0x0x7fc66a8788a0) 0 + primary-for QTextObject (0x0x7fc66a86aaf8) + +Vtable for QTextFrameLayoutData +QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextFrameLayoutData) +16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData +24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData + +Class QTextFrameLayoutData + size=8 align=8 + base size=8 base align=8 +QTextFrameLayoutData (0x0x7fc66a878a80) 0 nearly-empty + vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16) + +Class QTextFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextFrame::QPrivateSignal (0x0x7fc66a878b40) 0 empty + +Class QTextFrame::iterator + size=32 align=8 + base size=28 base align=8 +QTextFrame::iterator (0x0x7fc66a878ba0) 0 + +Vtable for QTextFrame +QTextFrame::_ZTV10QTextFrame: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextFrame) +16 (int (*)(...))QTextFrame::metaObject +24 (int (*)(...))QTextFrame::qt_metacast +32 (int (*)(...))QTextFrame::qt_metacall +40 (int (*)(...))QTextFrame::~QTextFrame +48 (int (*)(...))QTextFrame::~QTextFrame +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextFrame + size=16 align=8 + base size=16 base align=8 +QTextFrame (0x0x7fc66a86ab60) 0 + vptr=((& QTextFrame::_ZTV10QTextFrame) + 16) + QTextObject (0x0x7fc66a86abc8) 0 + primary-for QTextFrame (0x0x7fc66a86ab60) + QObject (0x0x7fc66a878ae0) 0 + primary-for QTextObject (0x0x7fc66a86abc8) + +Vtable for QTextBlockUserData +QTextBlockUserData::_ZTV18QTextBlockUserData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTextBlockUserData) +16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData +24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData + +Class QTextBlockUserData + size=8 align=8 + base size=8 base align=8 +QTextBlockUserData (0x0x7fc66a8f3a20) 0 nearly-empty + vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16) + +Class QTextBlock::iterator + size=24 align=8 + base size=20 base align=8 +QTextBlock::iterator (0x0x7fc66a8f3ae0) 0 + +Class QTextBlock + size=16 align=8 + base size=12 base align=8 +QTextBlock (0x0x7fc66a8f3a80) 0 + +Class QTextFragment + size=16 align=8 + base size=16 base align=8 +QTextFragment (0x0x7fc66a97a360) 0 + +Class QSyntaxHighlighter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSyntaxHighlighter::QPrivateSignal (0x0x7fc66a9b81e0) 0 empty + +Vtable for QSyntaxHighlighter +QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSyntaxHighlighter) +16 (int (*)(...))QSyntaxHighlighter::metaObject +24 (int (*)(...))QSyntaxHighlighter::qt_metacast +32 (int (*)(...))QSyntaxHighlighter::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSyntaxHighlighter + size=16 align=8 + base size=16 base align=8 +QSyntaxHighlighter (0x0x7fc66a9add68) 0 + vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16) + QObject (0x0x7fc66a9b8180) 0 + primary-for QSyntaxHighlighter (0x0x7fc66a9add68) + +Class QTextDocumentFragment + size=8 align=8 + base size=8 base align=8 +QTextDocumentFragment (0x0x7fc66a9b8360) 0 + +Class QTextDocumentWriter + size=8 align=8 + base size=8 base align=8 +QTextDocumentWriter (0x0x7fc66a9b83c0) 0 + +Class QTextList::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextList::QPrivateSignal (0x0x7fc66a9b8480) 0 empty + +Vtable for QTextList +QTextList::_ZTV9QTextList: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextList) +16 (int (*)(...))QTextList::metaObject +24 (int (*)(...))QTextList::qt_metacast +32 (int (*)(...))QTextList::qt_metacall +40 (int (*)(...))QTextList::~QTextList +48 (int (*)(...))QTextList::~QTextList +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextList + size=16 align=8 + base size=16 base align=8 +QTextList (0x0x7fc66a9addd0) 0 + vptr=((& QTextList::_ZTV9QTextList) + 16) + QTextBlockGroup (0x0x7fc66a9ade38) 0 + primary-for QTextList (0x0x7fc66a9addd0) + QTextObject (0x0x7fc66a9adea0) 0 + primary-for QTextBlockGroup (0x0x7fc66a9ade38) + QObject (0x0x7fc66a9b8420) 0 + primary-for QTextObject (0x0x7fc66a9adea0) + +Class QTextTableCell + size=16 align=8 + base size=12 base align=8 +QTextTableCell (0x0x7fc66a9b8840) 0 + +Class QTextTable::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextTable::QPrivateSignal (0x0x7fc66a5f30c0) 0 empty + +Vtable for QTextTable +QTextTable::_ZTV10QTextTable: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextTable) +16 (int (*)(...))QTextTable::metaObject +24 (int (*)(...))QTextTable::qt_metacast +32 (int (*)(...))QTextTable::qt_metacall +40 (int (*)(...))QTextTable::~QTextTable +48 (int (*)(...))QTextTable::~QTextTable +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextTable + size=16 align=8 + base size=16 base align=8 +QTextTable (0x0x7fc66a9adf08) 0 + vptr=((& QTextTable::_ZTV10QTextTable) + 16) + QTextFrame (0x0x7fc66a9adf70) 0 + primary-for QTextTable (0x0x7fc66a9adf08) + QTextObject (0x0x7fc66a5f4000) 0 + primary-for QTextFrame (0x0x7fc66a9adf70) + QObject (0x0x7fc66a5f3060) 0 + primary-for QTextObject (0x0x7fc66a5f4000) + +Class QUndoGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoGroup::QPrivateSignal (0x0x7fc66a5f3480) 0 empty + +Vtable for QUndoGroup +QUndoGroup::_ZTV10QUndoGroup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUndoGroup) +16 (int (*)(...))QUndoGroup::metaObject +24 (int (*)(...))QUndoGroup::qt_metacast +32 (int (*)(...))QUndoGroup::qt_metacall +40 (int (*)(...))QUndoGroup::~QUndoGroup +48 (int (*)(...))QUndoGroup::~QUndoGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QUndoGroup + size=16 align=8 + base size=16 base align=8 +QUndoGroup (0x0x7fc66a5f4068) 0 + vptr=((& QUndoGroup::_ZTV10QUndoGroup) + 16) + QObject (0x0x7fc66a5f3420) 0 + primary-for QUndoGroup (0x0x7fc66a5f4068) + +Vtable for QUndoCommand +QUndoCommand::_ZTV12QUndoCommand: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QUndoCommand) +16 (int (*)(...))QUndoCommand::~QUndoCommand +24 (int (*)(...))QUndoCommand::~QUndoCommand +32 (int (*)(...))QUndoCommand::undo +40 (int (*)(...))QUndoCommand::redo +48 (int (*)(...))QUndoCommand::id +56 (int (*)(...))QUndoCommand::mergeWith + +Class QUndoCommand + size=16 align=8 + base size=16 base align=8 +QUndoCommand (0x0x7fc66a5f3600) 0 + vptr=((& QUndoCommand::_ZTV12QUndoCommand) + 16) + +Class QUndoStack::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoStack::QPrivateSignal (0x0x7fc66a5f36c0) 0 empty + +Vtable for QUndoStack +QUndoStack::_ZTV10QUndoStack: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUndoStack) +16 (int (*)(...))QUndoStack::metaObject +24 (int (*)(...))QUndoStack::qt_metacast +32 (int (*)(...))QUndoStack::qt_metacall +40 (int (*)(...))QUndoStack::~QUndoStack +48 (int (*)(...))QUndoStack::~QUndoStack +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QUndoStack + size=16 align=8 + base size=16 base align=8 +QUndoStack (0x0x7fc66a5f40d0) 0 + vptr=((& QUndoStack::_ZTV10QUndoStack) + 16) + QObject (0x0x7fc66a5f3660) 0 + primary-for QUndoStack (0x0x7fc66a5f40d0) + +Class QValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QValidator::QPrivateSignal (0x0x7fc66a5f38a0) 0 empty + +Vtable for QValidator +QValidator::_ZTV10QValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QValidator) +16 (int (*)(...))QValidator::metaObject +24 (int (*)(...))QValidator::qt_metacast +32 (int (*)(...))QValidator::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QValidator::fixup + +Class QValidator + size=16 align=8 + base size=16 base align=8 +QValidator (0x0x7fc66a5f4138) 0 + vptr=((& QValidator::_ZTV10QValidator) + 16) + QObject (0x0x7fc66a5f3840) 0 + primary-for QValidator (0x0x7fc66a5f4138) + +Class QIntValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIntValidator::QPrivateSignal (0x0x7fc66a5f3b40) 0 empty + +Vtable for QIntValidator +QIntValidator::_ZTV13QIntValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QIntValidator) +16 (int (*)(...))QIntValidator::metaObject +24 (int (*)(...))QIntValidator::qt_metacast +32 (int (*)(...))QIntValidator::qt_metacall +40 (int (*)(...))QIntValidator::~QIntValidator +48 (int (*)(...))QIntValidator::~QIntValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIntValidator::validate +120 (int (*)(...))QIntValidator::fixup + +Class QIntValidator + size=24 align=8 + base size=24 base align=8 +QIntValidator (0x0x7fc66a5f41a0) 0 + vptr=((& QIntValidator::_ZTV13QIntValidator) + 16) + QValidator (0x0x7fc66a5f4208) 0 + primary-for QIntValidator (0x0x7fc66a5f41a0) + QObject (0x0x7fc66a5f3ae0) 0 + primary-for QValidator (0x0x7fc66a5f4208) + +Class QDoubleValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleValidator::QPrivateSignal (0x0x7fc66a5f3d20) 0 empty + +Vtable for QDoubleValidator +QDoubleValidator::_ZTV16QDoubleValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDoubleValidator) +16 (int (*)(...))QDoubleValidator::metaObject +24 (int (*)(...))QDoubleValidator::qt_metacast +32 (int (*)(...))QDoubleValidator::qt_metacall +40 (int (*)(...))QDoubleValidator::~QDoubleValidator +48 (int (*)(...))QDoubleValidator::~QDoubleValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDoubleValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QDoubleValidator + size=40 align=8 + base size=36 base align=8 +QDoubleValidator (0x0x7fc66a5f4270) 0 + vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16) + QValidator (0x0x7fc66a5f42d8) 0 + primary-for QDoubleValidator (0x0x7fc66a5f4270) + QObject (0x0x7fc66a5f3cc0) 0 + primary-for QValidator (0x0x7fc66a5f42d8) + +Class QRegularExpressionValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegularExpressionValidator::QPrivateSignal (0x0x7fc66a65d120) 0 empty + +Vtable for QRegularExpressionValidator +QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QRegularExpressionValidator) +16 (int (*)(...))QRegularExpressionValidator::metaObject +24 (int (*)(...))QRegularExpressionValidator::qt_metacast +32 (int (*)(...))QRegularExpressionValidator::qt_metacall +40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegularExpressionValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegularExpressionValidator + size=16 align=8 + base size=16 base align=8 +QRegularExpressionValidator (0x0x7fc66a5f4340) 0 + vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16) + QValidator (0x0x7fc66a5f43a8) 0 + primary-for QRegularExpressionValidator (0x0x7fc66a5f4340) + QObject (0x0x7fc66a65d0c0) 0 + primary-for QValidator (0x0x7fc66a5f43a8) + +Class QNetworkRequest + size=8 align=8 + base size=8 base align=8 +QNetworkRequest (0x0x7fc66a65d2a0) 0 + +Class QNetworkCacheMetaData + size=8 align=8 + base size=8 base align=8 +QNetworkCacheMetaData (0x0x7fc66a7513c0) 0 + +Class QAbstractNetworkCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractNetworkCache::QPrivateSignal (0x0x7fc66a3c2c00) 0 empty + +Vtable for QAbstractNetworkCache +QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractNetworkCache) +16 (int (*)(...))QAbstractNetworkCache::metaObject +24 (int (*)(...))QAbstractNetworkCache::qt_metacast +32 (int (*)(...))QAbstractNetworkCache::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNetworkCache + size=16 align=8 + base size=16 base align=8 +QAbstractNetworkCache (0x0x7fc66a3cd7b8) 0 + vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16) + QObject (0x0x7fc66a3c2ba0) 0 + primary-for QAbstractNetworkCache (0x0x7fc66a3cd7b8) + +Class QAbstractSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSocket::QPrivateSignal (0x0x7fc66a3c2e40) 0 empty + +Vtable for QAbstractSocket +QAbstractSocket::_ZTV15QAbstractSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSocket) +16 (int (*)(...))QAbstractSocket::metaObject +24 (int (*)(...))QAbstractSocket::qt_metacast +32 (int (*)(...))QAbstractSocket::qt_metacall +40 (int (*)(...))QAbstractSocket::~QAbstractSocket +48 (int (*)(...))QAbstractSocket::~QAbstractSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::skipData +240 (int (*)(...))QAbstractSocket::writeData +248 (int (*)(...))QAbstractSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QAbstractSocket::connectToHost +272 (int (*)(...))QAbstractSocket::disconnectFromHost +280 (int (*)(...))QAbstractSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketDescriptor +304 (int (*)(...))QAbstractSocket::setSocketOption +312 (int (*)(...))QAbstractSocket::socketOption +320 (int (*)(...))QAbstractSocket::waitForConnected +328 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QAbstractSocket + size=16 align=8 + base size=16 base align=8 +QAbstractSocket (0x0x7fc66a3cd820) 0 + vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16) + QIODevice (0x0x7fc66a3d41c0) 0 + primary-for QAbstractSocket (0x0x7fc66a3cd820) + QObject (0x0x7fc66a3c2d80) 0 + primary-for QIODevice (0x0x7fc66a3d41c0) + QIODeviceBase (0x0x7fc66a3c2de0) 0 empty + +Class QAuthenticator + size=8 align=8 + base size=8 base align=8 +QAuthenticator (0x0x7fc66a50d120) 0 + +Class QDnsDomainNameRecord + size=8 align=8 + base size=8 base align=8 +QDnsDomainNameRecord (0x0x7fc66a50d1e0) 0 + +Class QDnsHostAddressRecord + size=8 align=8 + base size=8 base align=8 +QDnsHostAddressRecord (0x0x7fc66a57e960) 0 + +Class QDnsMailExchangeRecord + size=8 align=8 + base size=8 base align=8 +QDnsMailExchangeRecord (0x0x7fc66a1fd120) 0 + +Class QDnsServiceRecord + size=8 align=8 + base size=8 base align=8 +QDnsServiceRecord (0x0x7fc66a2667e0) 0 + +Class QDnsTextRecord + size=8 align=8 + base size=8 base align=8 +QDnsTextRecord (0x0x7fc66a2e6180) 0 + +Class QDnsLookup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDnsLookup::QPrivateSignal (0x0x7fc66a347c00) 0 empty + +Vtable for QDnsLookup +QDnsLookup::_ZTV10QDnsLookup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDnsLookup) +16 (int (*)(...))QDnsLookup::metaObject +24 (int (*)(...))QDnsLookup::qt_metacast +32 (int (*)(...))QDnsLookup::qt_metacall +40 (int (*)(...))QDnsLookup::~QDnsLookup +48 (int (*)(...))QDnsLookup::~QDnsLookup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDnsLookup + size=16 align=8 + base size=16 base align=8 +QDnsLookup (0x0x7fc66a350888) 0 + vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16) + QObject (0x0x7fc66a347ba0) 0 + primary-for QDnsLookup (0x0x7fc66a350888) + +Class QIPv6Address + size=16 align=1 + base size=16 base align=1 +QIPv6Address (0x0x7fc66a347f00) 0 + +Class QHostAddress + size=8 align=8 + base size=8 base align=8 +QHostAddress (0x0x7fc66a376060) 0 + +Class QTcpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpSocket::QPrivateSignal (0x0x7fc669ff7f60) 0 empty + +Vtable for QTcpSocket +QTcpSocket::_ZTV10QTcpSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpSocket) +16 (int (*)(...))QTcpSocket::metaObject +24 (int (*)(...))QTcpSocket::qt_metacast +32 (int (*)(...))QTcpSocket::qt_metacall +40 (int (*)(...))QTcpSocket::~QTcpSocket +48 (int (*)(...))QTcpSocket::~QTcpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::skipData +240 (int (*)(...))QAbstractSocket::writeData +248 (int (*)(...))QAbstractSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QAbstractSocket::connectToHost +272 (int (*)(...))QAbstractSocket::disconnectFromHost +280 (int (*)(...))QAbstractSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketDescriptor +304 (int (*)(...))QAbstractSocket::setSocketOption +312 (int (*)(...))QAbstractSocket::socketOption +320 (int (*)(...))QAbstractSocket::waitForConnected +328 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QTcpSocket + size=16 align=8 + base size=16 base align=8 +QTcpSocket (0x0x7fc66a0085b0) 0 + vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16) + QAbstractSocket (0x0x7fc66a008618) 0 + primary-for QTcpSocket (0x0x7fc66a0085b0) + QIODevice (0x0x7fc66a35cf50) 0 + primary-for QAbstractSocket (0x0x7fc66a008618) + QObject (0x0x7fc669ff7ea0) 0 + primary-for QIODevice (0x0x7fc66a35cf50) + QIODeviceBase (0x0x7fc669ff7f00) 0 empty + +Class QSslCertificate + size=8 align=8 + base size=8 base align=8 +QSslCertificate (0x0x7fc66a022540) 0 + +Class QSslError + size=8 align=8 + base size=8 base align=8 +QSslError (0x0x7fc66a0eb840) 0 + +Class QSslSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSslSocket::QPrivateSignal (0x0x7fc669eeb720) 0 empty + +Vtable for QSslSocket +QSslSocket::_ZTV10QSslSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSslSocket) +16 (int (*)(...))QSslSocket::metaObject +24 (int (*)(...))QSslSocket::qt_metacast +32 (int (*)(...))QSslSocket::qt_metacall +40 (int (*)(...))QSslSocket::~QSslSocket +48 (int (*)(...))QSslSocket::~QSslSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QSslSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QSslSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QSslSocket::bytesAvailable +184 (int (*)(...))QSslSocket::bytesToWrite +192 (int (*)(...))QSslSocket::canReadLine +200 (int (*)(...))QSslSocket::waitForReadyRead +208 (int (*)(...))QSslSocket::waitForBytesWritten +216 (int (*)(...))QSslSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QSslSocket::skipData +240 (int (*)(...))QSslSocket::writeData +248 (int (*)(...))QSslSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QSslSocket::connectToHost +272 (int (*)(...))QSslSocket::disconnectFromHost +280 (int (*)(...))QSslSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QSslSocket::setSocketDescriptor +304 (int (*)(...))QSslSocket::setSocketOption +312 (int (*)(...))QSslSocket::socketOption +320 (int (*)(...))QSslSocket::waitForConnected +328 (int (*)(...))QSslSocket::waitForDisconnected + +Class QSslSocket + size=16 align=8 + base size=16 base align=8 +QSslSocket (0x0x7fc669ee0888) 0 + vptr=((& QSslSocket::_ZTV10QSslSocket) + 16) + QTcpSocket (0x0x7fc669ee08f0) 0 + primary-for QSslSocket (0x0x7fc669ee0888) + QAbstractSocket (0x0x7fc669ee0958) 0 + primary-for QTcpSocket (0x0x7fc669ee08f0) + QIODevice (0x0x7fc669e87e00) 0 + primary-for QAbstractSocket (0x0x7fc669ee0958) + QObject (0x0x7fc669eeb660) 0 + primary-for QIODevice (0x0x7fc669e87e00) + QIODeviceBase (0x0x7fc669eeb6c0) 0 empty + +Class QDtlsClientVerifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtlsClientVerifier::QPrivateSignal (0x0x7fc669eeb900) 0 empty + +Class QDtlsClientVerifier::GeneratorParameters + size=32 align=8 + base size=32 base align=8 +QDtlsClientVerifier::GeneratorParameters (0x0x7fc669eeb960) 0 + +Vtable for QDtlsClientVerifier +QDtlsClientVerifier::_ZTV19QDtlsClientVerifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QDtlsClientVerifier) +16 (int (*)(...))QDtlsClientVerifier::metaObject +24 (int (*)(...))QDtlsClientVerifier::qt_metacast +32 (int (*)(...))QDtlsClientVerifier::qt_metacall +40 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +48 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtlsClientVerifier + size=16 align=8 + base size=16 base align=8 +QDtlsClientVerifier (0x0x7fc669ee09c0) 0 + vptr=((& QDtlsClientVerifier::_ZTV19QDtlsClientVerifier) + 16) + QObject (0x0x7fc669eeb8a0) 0 + primary-for QDtlsClientVerifier (0x0x7fc669ee09c0) + +Class QDtls::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtls::QPrivateSignal (0x0x7fc669eebb40) 0 empty + +Vtable for QDtls +QDtls::_ZTV5QDtls: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDtls) +16 (int (*)(...))QDtls::metaObject +24 (int (*)(...))QDtls::qt_metacast +32 (int (*)(...))QDtls::qt_metacall +40 (int (*)(...))QDtls::~QDtls +48 (int (*)(...))QDtls::~QDtls +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtls + size=16 align=8 + base size=16 base align=8 +QDtls (0x0x7fc669ee0a28) 0 + vptr=((& QDtls::_ZTV5QDtls) + 16) + QObject (0x0x7fc669eebae0) 0 + primary-for QDtls (0x0x7fc669ee0a28) + +Class QHostInfo + size=8 align=8 + base size=8 base align=8 +QHostInfo (0x0x7fc669eebcc0) 0 + +Class QHstsPolicy + size=8 align=8 + base size=8 base align=8 +QHstsPolicy (0x0x7fc669bd31e0) 0 + +Class QHttp2Configuration + size=8 align=8 + base size=8 base align=8 +QHttp2Configuration (0x0x7fc669c49d20) 0 + +Class QHttpPart + size=8 align=8 + base size=8 base align=8 +QHttpPart (0x0x7fc669cdb660) 0 + +Class QHttpMultiPart::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHttpMultiPart::QPrivateSignal (0x0x7fc669d47de0) 0 empty + +Vtable for QHttpMultiPart +QHttpMultiPart::_ZTV14QHttpMultiPart: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QHttpMultiPart) +16 (int (*)(...))QHttpMultiPart::metaObject +24 (int (*)(...))QHttpMultiPart::qt_metacast +32 (int (*)(...))QHttpMultiPart::qt_metacall +40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QHttpMultiPart + size=16 align=8 + base size=16 base align=8 +QHttpMultiPart (0x0x7fc669d4f9c0) 0 + vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16) + QObject (0x0x7fc669d47d80) 0 + primary-for QHttpMultiPart (0x0x7fc669d4f9c0) + +Class QLocalServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalServer::QPrivateSignal (0x0x7fc669d6e000) 0 empty + +Vtable for QLocalServer +QLocalServer::_ZTV12QLocalServer: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalServer) +16 (int (*)(...))QLocalServer::metaObject +24 (int (*)(...))QLocalServer::qt_metacast +32 (int (*)(...))QLocalServer::qt_metacall +40 (int (*)(...))QLocalServer::~QLocalServer +48 (int (*)(...))QLocalServer::~QLocalServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalServer::hasPendingConnections +120 (int (*)(...))QLocalServer::nextPendingConnection +128 (int (*)(...))QLocalServer::incomingConnection + +Class QLocalServer + size=16 align=8 + base size=16 base align=8 +QLocalServer (0x0x7fc669d4fa28) 0 + vptr=((& QLocalServer::_ZTV12QLocalServer) + 16) + QObject (0x0x7fc669d47f60) 0 + primary-for QLocalServer (0x0x7fc669d4fa28) + +Class QLocalSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalSocket::QPrivateSignal (0x0x7fc669d6e780) 0 empty + +Vtable for QLocalSocket +QLocalSocket::_ZTV12QLocalSocket: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalSocket) +16 (int (*)(...))QLocalSocket::metaObject +24 (int (*)(...))QLocalSocket::qt_metacast +32 (int (*)(...))QLocalSocket::qt_metacall +40 (int (*)(...))QLocalSocket::~QLocalSocket +48 (int (*)(...))QLocalSocket::~QLocalSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalSocket::isSequential +120 (int (*)(...))QLocalSocket::open +128 (int (*)(...))QLocalSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QLocalSocket::bytesAvailable +184 (int (*)(...))QLocalSocket::bytesToWrite +192 (int (*)(...))QLocalSocket::canReadLine +200 (int (*)(...))QLocalSocket::waitForReadyRead +208 (int (*)(...))QLocalSocket::waitForBytesWritten +216 (int (*)(...))QLocalSocket::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QLocalSocket::skipData +240 (int (*)(...))QLocalSocket::writeData + +Class QLocalSocket + size=16 align=8 + base size=16 base align=8 +QLocalSocket (0x0x7fc669d4fbc8) 0 + vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16) + QIODevice (0x0x7fc669c5ad90) 0 + primary-for QLocalSocket (0x0x7fc669d4fbc8) + QObject (0x0x7fc669d6e6c0) 0 + primary-for QIODevice (0x0x7fc669c5ad90) + QIODeviceBase (0x0x7fc669d6e720) 0 empty + +Class QSslConfiguration + size=8 align=8 + base size=8 base align=8 +QSslConfiguration (0x0x7fc669d6ed80) 0 + +Class QSslPreSharedKeyAuthenticator + size=8 align=8 + base size=8 base align=8 +QSslPreSharedKeyAuthenticator (0x0x7fc669ade300) 0 + +Class QNetworkAccessManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkAccessManager::QPrivateSignal (0x0x7fc6697dac00) 0 empty + +Vtable for QNetworkAccessManager +QNetworkAccessManager::_ZTV21QNetworkAccessManager: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QNetworkAccessManager) +16 (int (*)(...))QNetworkAccessManager::metaObject +24 (int (*)(...))QNetworkAccessManager::qt_metacast +32 (int (*)(...))QNetworkAccessManager::qt_metacall +40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkAccessManager::supportedSchemes +120 (int (*)(...))QNetworkAccessManager::createRequest + +Class QNetworkAccessManager + size=16 align=8 + base size=16 base align=8 +QNetworkAccessManager (0x0x7fc6697f07b8) 0 + vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16) + QObject (0x0x7fc6697daba0) 0 + primary-for QNetworkAccessManager (0x0x7fc6697f07b8) + +Class QNetworkCookie + size=8 align=8 + base size=8 base align=8 +QNetworkCookie (0x0x7fc6697dad80) 0 + +Class QNetworkCookieJar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkCookieJar::QPrivateSignal (0x0x7fc669885e40) 0 empty + +Vtable for QNetworkCookieJar +QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkCookieJar) +16 (int (*)(...))QNetworkCookieJar::metaObject +24 (int (*)(...))QNetworkCookieJar::qt_metacast +32 (int (*)(...))QNetworkCookieJar::qt_metacall +40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkCookieJar::cookiesForUrl +120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl +128 (int (*)(...))QNetworkCookieJar::insertCookie +136 (int (*)(...))QNetworkCookieJar::updateCookie +144 (int (*)(...))QNetworkCookieJar::deleteCookie +152 (int (*)(...))QNetworkCookieJar::validateCookie + +Class QNetworkCookieJar + size=16 align=8 + base size=16 base align=8 +QNetworkCookieJar (0x0x7fc66988b618) 0 + vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16) + QObject (0x0x7fc669885de0) 0 + primary-for QNetworkCookieJar (0x0x7fc66988b618) + +Class QNetworkDatagram + size=8 align=8 + base size=8 base align=8 +QNetworkDatagram (0x0x7fc6698b6000) 0 + +Class QNetworkDiskCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkDiskCache::QPrivateSignal (0x0x7fc66991f7e0) 0 empty + +Vtable for QNetworkDiskCache +QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkDiskCache) +16 (int (*)(...))QNetworkDiskCache::metaObject +24 (int (*)(...))QNetworkDiskCache::qt_metacast +32 (int (*)(...))QNetworkDiskCache::qt_metacall +40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkDiskCache::metaData +120 (int (*)(...))QNetworkDiskCache::updateMetaData +128 (int (*)(...))QNetworkDiskCache::data +136 (int (*)(...))QNetworkDiskCache::remove +144 (int (*)(...))QNetworkDiskCache::cacheSize +152 (int (*)(...))QNetworkDiskCache::prepare +160 (int (*)(...))QNetworkDiskCache::insert +168 (int (*)(...))QNetworkDiskCache::clear +176 (int (*)(...))QNetworkDiskCache::expire + +Class QNetworkDiskCache + size=16 align=8 + base size=16 base align=8 +QNetworkDiskCache (0x0x7fc6699175b0) 0 + vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16) + QAbstractNetworkCache (0x0x7fc669917618) 0 + primary-for QNetworkDiskCache (0x0x7fc6699175b0) + QObject (0x0x7fc66991f780) 0 + primary-for QAbstractNetworkCache (0x0x7fc669917618) + +Class QNetworkInformation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkInformation::QPrivateSignal (0x0x7fc66991f9c0) 0 empty + +Vtable for QNetworkInformation +QNetworkInformation::_ZTV19QNetworkInformation: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNetworkInformation) +16 (int (*)(...))QNetworkInformation::metaObject +24 (int (*)(...))QNetworkInformation::qt_metacast +32 (int (*)(...))QNetworkInformation::qt_metacall +40 (int (*)(...))QNetworkInformation::~QNetworkInformation +48 (int (*)(...))QNetworkInformation::~QNetworkInformation +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QNetworkInformation + size=16 align=8 + base size=16 base align=8 +QNetworkInformation (0x0x7fc669917680) 0 + vptr=((& QNetworkInformation::_ZTV19QNetworkInformation) + 16) + QObject (0x0x7fc66991f960) 0 + primary-for QNetworkInformation (0x0x7fc669917680) + +Class QNetworkAddressEntry + size=8 align=8 + base size=8 base align=8 +QNetworkAddressEntry (0x0x7fc6699900c0) 0 + +Class QNetworkInterface + size=8 align=8 + base size=8 base align=8 +QNetworkInterface (0x0x7fc66976fb40) 0 + +Class QNetworkProxyQuery + size=8 align=8 + base size=8 base align=8 +QNetworkProxyQuery (0x0x7fc6694ab0c0) 0 + +Class QNetworkProxy + size=8 align=8 + base size=8 base align=8 +QNetworkProxy (0x0x7fc66951e840) 0 + +Vtable for QNetworkProxyFactory +QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QNetworkProxyFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNetworkProxyFactory + size=8 align=8 + base size=8 base align=8 +QNetworkProxyFactory (0x0x7fc6695b1300) 0 nearly-empty + vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16) + +Class QNetworkReply::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkReply::QPrivateSignal (0x0x7fc6695b1900) 0 empty + +Vtable for QNetworkReply +QNetworkReply::_ZTV13QNetworkReply: 37 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QNetworkReply) +16 (int (*)(...))QNetworkReply::metaObject +24 (int (*)(...))QNetworkReply::qt_metacast +32 (int (*)(...))QNetworkReply::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkReply::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QNetworkReply::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QNetworkReply::writeData +248 (int (*)(...))QNetworkReply::setReadBufferSize +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))QNetworkReply::ignoreSslErrors +272 (int (*)(...))QNetworkReply::sslConfigurationImplementation +280 (int (*)(...))QNetworkReply::setSslConfigurationImplementation +288 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation + +Class QNetworkReply + size=16 align=8 + base size=16 base align=8 +QNetworkReply (0x0x7fc6695aa410) 0 + vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16) + QIODevice (0x0x7fc669530cb0) 0 + primary-for QNetworkReply (0x0x7fc6695aa410) + QObject (0x0x7fc6695b1840) 0 + primary-for QIODevice (0x0x7fc669530cb0) + QIODeviceBase (0x0x7fc6695b18a0) 0 empty + +Class QOcspResponse + size=8 align=8 + base size=8 base align=8 +QOcspResponse (0x0x7fc66924ac60) 0 + +Class QTcpServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpServer::QPrivateSignal (0x0x7fc6692b9b40) 0 empty + +Vtable for QTcpServer +QTcpServer::_ZTV10QTcpServer: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpServer) +16 (int (*)(...))QTcpServer::metaObject +24 (int (*)(...))QTcpServer::qt_metacast +32 (int (*)(...))QTcpServer::qt_metacall +40 (int (*)(...))QTcpServer::~QTcpServer +48 (int (*)(...))QTcpServer::~QTcpServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTcpServer::hasPendingConnections +120 (int (*)(...))QTcpServer::nextPendingConnection +128 (int (*)(...))QTcpServer::incomingConnection + +Class QTcpServer + size=16 align=8 + base size=16 base align=8 +QTcpServer (0x0x7fc6692bc820) 0 + vptr=((& QTcpServer::_ZTV10QTcpServer) + 16) + QObject (0x0x7fc6692b9ae0) 0 + primary-for QTcpServer (0x0x7fc6692bc820) + +Class QSslCertificateExtension + size=8 align=8 + base size=8 base align=8 +QSslCertificateExtension (0x0x7fc6692b9cc0) 0 + +Class QSslCipher + size=8 align=8 + base size=8 base align=8 +QSslCipher (0x0x7fc66935e480) 0 + +Class QSslDiffieHellmanParameters + size=8 align=8 + base size=8 base align=8 +QSslDiffieHellmanParameters (0x0x7fc669136de0) 0 + +Class QSslEllipticCurve + size=4 align=4 + base size=4 base align=4 +QSslEllipticCurve (0x0x7fc6691a1b40) 0 + +Class QSslKey + size=8 align=8 + base size=8 base align=8 +QSslKey (0x0x7fc668de2d80) 0 + +Class QUdpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUdpSocket::QPrivateSignal (0x0x7fc668e78600) 0 empty + +Vtable for QUdpSocket +QUdpSocket::_ZTV10QUdpSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUdpSocket) +16 (int (*)(...))QUdpSocket::metaObject +24 (int (*)(...))QUdpSocket::qt_metacast +32 (int (*)(...))QUdpSocket::qt_metacall +40 (int (*)(...))QUdpSocket::~QUdpSocket +48 (int (*)(...))QUdpSocket::~QUdpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::skipData +240 (int (*)(...))QAbstractSocket::writeData +248 (int (*)(...))QAbstractSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QAbstractSocket::connectToHost +272 (int (*)(...))QAbstractSocket::disconnectFromHost +280 (int (*)(...))QAbstractSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketDescriptor +304 (int (*)(...))QAbstractSocket::setSocketOption +312 (int (*)(...))QAbstractSocket::socketOption +320 (int (*)(...))QAbstractSocket::waitForConnected +328 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QUdpSocket + size=16 align=8 + base size=16 base align=8 +QUdpSocket (0x0x7fc668e84000) 0 + vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16) + QAbstractSocket (0x0x7fc668e84068) 0 + primary-for QUdpSocket (0x0x7fc668e84000) + QIODevice (0x0x7fc669188e70) 0 + primary-for QAbstractSocket (0x0x7fc668e84068) + QObject (0x0x7fc668e78540) 0 + primary-for QIODevice (0x0x7fc669188e70) + QIODeviceBase (0x0x7fc668e785a0) 0 empty + +Class QJSValue + size=8 align=8 + base size=8 base align=8 +QJSValue (0x0x7fc668e78840) 0 + +Class QJSNumberCoercion + size=8 align=8 + base size=8 base align=8 +QJSNumberCoercion (0x0x7fc668edfd80) 0 + +Class QJSPrimitiveUndefined + size=1 align=1 + base size=0 base align=1 +QJSPrimitiveUndefined (0x0x7fc668f40360) 0 empty + +Class QJSPrimitiveNull + size=1 align=1 + base size=0 base align=1 +QJSPrimitiveNull (0x0x7fc668f403c0) 0 empty + +Class QJSPrimitiveValue::AddOperators + size=1 align=1 + base size=0 base align=1 +QJSPrimitiveValue::AddOperators (0x0x7fc668f404e0) 0 empty + +Class QJSPrimitiveValue::SubOperators + size=1 align=1 + base size=1 base align=1 +QJSPrimitiveValue::SubOperators (0x0x7fc668e848f0) 0 empty + QJSPrimitiveValue::StringNaNOperators<QJSPrimitiveValue::SubOperators> (0x0x7fc668f405a0) 0 empty + +Class QJSPrimitiveValue::MulOperators + size=1 align=1 + base size=1 base align=1 +QJSPrimitiveValue::MulOperators (0x0x7fc668e84958) 0 empty + QJSPrimitiveValue::StringNaNOperators<QJSPrimitiveValue::MulOperators> (0x0x7fc668f40660) 0 empty + +Class QJSPrimitiveValue::DivOperators + size=1 align=1 + base size=1 base align=1 +QJSPrimitiveValue::DivOperators (0x0x7fc668e849c0) 0 empty + QJSPrimitiveValue::StringNaNOperators<QJSPrimitiveValue::DivOperators> (0x0x7fc668f40720) 0 empty + +Class QJSPrimitiveValue::QJSPrimitiveValuePrivate + size=32 align=8 + base size=25 base align=8 +QJSPrimitiveValue::QJSPrimitiveValuePrivate (0x0x7fc668f40780) 0 + +Class QJSPrimitiveValue + size=32 align=8 + base size=32 base align=8 +QJSPrimitiveValue (0x0x7fc668f40420) 0 + +Class QJSManagedValue + size=8 align=8 + base size=8 base align=8 +QJSManagedValue (0x0x7fc668c749c0) 0 + +Class QQmlDebuggingEnabler + size=1 align=1 + base size=0 base align=1 +QQmlDebuggingEnabler (0x0x7fc668c74cc0) 0 empty + +Class QJSEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QJSEngine::QPrivateSignal (0x0x7fc668c74f60) 0 empty + +Vtable for QJSEngine +QJSEngine::_ZTV9QJSEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QJSEngine) +16 (int (*)(...))QJSEngine::metaObject +24 (int (*)(...))QJSEngine::qt_metacast +32 (int (*)(...))QJSEngine::qt_metacall +40 (int (*)(...))QJSEngine::~QJSEngine +48 (int (*)(...))QJSEngine::~QJSEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QJSEngine + size=24 align=8 + base size=24 base align=8 +QJSEngine (0x0x7fc668c0d750) 0 + vptr=((& QJSEngine::_ZTV9QJSEngine) + 16) + QObject (0x0x7fc668c74f00) 0 + primary-for QJSEngine (0x0x7fc668c0d750) + +Class QJSValueIterator + size=8 align=8 + base size=8 base align=8 +QJSValueIterator (0x0x7fc668cd3900) 0 + +Vtable for QQmlParserStatus +QQmlParserStatus::_ZTV16QQmlParserStatus: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlParserStatus) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlParserStatus + size=16 align=8 + base size=16 base align=8 +QQmlParserStatus (0x0x7fc668cd3ae0) 0 + vptr=((& QQmlParserStatus::_ZTV16QQmlParserStatus) + 16) + +Class QQmlListReference + size=8 align=8 + base size=8 base align=8 +QQmlListReference (0x0x7fc668d48600) 0 + +Vtable for QQmlPropertyValueSource +QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQmlPropertyValueSource) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlPropertyValueSource + size=8 align=8 + base size=8 base align=8 +QQmlPropertyValueSource (0x0x7fc668d48c00) 0 nearly-empty + vptr=((& QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource) + 16) + +Class QQmlPrivate::RegisterType + size=176 align=8 + base size=170 base align=8 +QQmlPrivate::RegisterType (0x0x7fc668dad420) 0 + +Class QQmlPrivate::RegisterTypeAndRevisions + size=152 align=8 + base size=152 base align=8 +QQmlPrivate::RegisterTypeAndRevisions (0x0x7fc668dad480) 0 + +Class QQmlPrivate::RegisterInterface + size=48 align=8 + base size=42 base align=8 +QQmlPrivate::RegisterInterface (0x0x7fc668dad4e0) 0 + +Class QQmlPrivate::RegisterAutoParent + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterAutoParent (0x0x7fc668dad540) 0 + +Class QQmlPrivate::RegisterSingletonType + size=136 align=8 + base size=130 base align=8 +QQmlPrivate::RegisterSingletonType (0x0x7fc668dad5a0) 0 + +Class QQmlPrivate::RegisterSingletonTypeAndRevisions + size=104 align=8 + base size=104 base align=8 +QQmlPrivate::RegisterSingletonTypeAndRevisions (0x0x7fc668dad900) 0 + +Class QQmlPrivate::RegisterCompositeType + size=40 align=8 + base size=40 base align=8 +QQmlPrivate::RegisterCompositeType (0x0x7fc668dad9c0) 0 + +Class QQmlPrivate::RegisterCompositeSingletonType + size=40 align=8 + base size=40 base align=8 +QQmlPrivate::RegisterCompositeSingletonType (0x0x7fc668dada20) 0 + +Class QQmlPrivate::RegisterSequentialContainer + size=56 align=8 + base size=50 base align=8 +QQmlPrivate::RegisterSequentialContainer (0x0x7fc668dada80) 0 + +Class QQmlPrivate::RegisterSequentialContainerAndRevisions + size=56 align=8 + base size=56 base align=8 +QQmlPrivate::RegisterSequentialContainerAndRevisions (0x0x7fc668dadae0) 0 + +Class QQmlPrivate::AOTCompiledContext + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::AOTCompiledContext (0x0x7fc668dadb40) 0 + +Class QQmlPrivate::AOTCompiledFunction + size=48 align=8 + base size=48 base align=8 +QQmlPrivate::AOTCompiledFunction (0x0x7fc668dadba0) 0 + +Class QQmlPrivate::CachedQmlUnit + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::CachedQmlUnit (0x0x7fc668a085a0) 0 + +Class QQmlPrivate::RegisterQmlUnitCacheHook + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterQmlUnitCacheHook (0x0x7fc668a08600) 0 + +Class QQmlPrivate::SingletonFunctor + size=24 align=8 + base size=17 base align=8 +QQmlPrivate::SingletonFunctor (0x0x7fc668a08660) 0 + +Vtable for QQmlAbstractUrlInterceptor +QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QQmlAbstractUrlInterceptor) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlAbstractUrlInterceptor + size=8 align=8 + base size=8 base align=8 +QQmlAbstractUrlInterceptor (0x0x7fc66881b000) 0 nearly-empty + vptr=((& QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor) + 16) + +Class QQmlError + size=8 align=8 + base size=8 base align=8 +QQmlError (0x0x7fc66881b060) 0 + +Class QQmlImageProviderBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlImageProviderBase::QPrivateSignal (0x0x7fc6688448a0) 0 empty + +Vtable for QQmlImageProviderBase +QQmlImageProviderBase::_ZTV21QQmlImageProviderBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlImageProviderBase) +16 (int (*)(...))QQmlImageProviderBase::metaObject +24 (int (*)(...))QQmlImageProviderBase::qt_metacast +32 (int (*)(...))QQmlImageProviderBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QQmlImageProviderBase + size=16 align=8 + base size=16 base align=8 +QQmlImageProviderBase (0x0x7fc668842c30) 0 + vptr=((& QQmlImageProviderBase::_ZTV21QQmlImageProviderBase) + 16) + QObject (0x0x7fc668844840) 0 + primary-for QQmlImageProviderBase (0x0x7fc668842c30) + +Class QQmlEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngine::QPrivateSignal (0x0x7fc668844d80) 0 empty + +Vtable for QQmlEngine +QQmlEngine::_ZTV10QQmlEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQmlEngine) +16 (int (*)(...))QQmlEngine::metaObject +24 (int (*)(...))QQmlEngine::qt_metacast +32 (int (*)(...))QQmlEngine::qt_metacall +40 (int (*)(...))QQmlEngine::~QQmlEngine +48 (int (*)(...))QQmlEngine::~QQmlEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlEngine + size=24 align=8 + base size=24 base align=8 +QQmlEngine (0x0x7fc668842dd0) 0 + vptr=((& QQmlEngine::_ZTV10QQmlEngine) + 16) + QJSEngine (0x0x7fc668842e38) 0 + primary-for QQmlEngine (0x0x7fc668842dd0) + QObject (0x0x7fc668844d20) 0 + primary-for QJSEngine (0x0x7fc668842e38) + +Class QQmlApplicationEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlApplicationEngine::QPrivateSignal (0x0x7fc6688b50c0) 0 empty + +Vtable for QQmlApplicationEngine +QQmlApplicationEngine::_ZTV21QQmlApplicationEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlApplicationEngine) +16 (int (*)(...))QQmlApplicationEngine::metaObject +24 (int (*)(...))QQmlApplicationEngine::qt_metacast +32 (int (*)(...))QQmlApplicationEngine::qt_metacall +40 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +48 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlApplicationEngine + size=24 align=8 + base size=24 base align=8 +QQmlApplicationEngine (0x0x7fc668842ea0) 0 + vptr=((& QQmlApplicationEngine::_ZTV21QQmlApplicationEngine) + 16) + QQmlEngine (0x0x7fc668842f08) 0 + primary-for QQmlApplicationEngine (0x0x7fc668842ea0) + QJSEngine (0x0x7fc668842f70) 0 + primary-for QQmlEngine (0x0x7fc668842f08) + QObject (0x0x7fc6688b5060) 0 + primary-for QJSEngine (0x0x7fc668842f70) + +Class QQmlComponent::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlComponent::QPrivateSignal (0x0x7fc6688b52a0) 0 empty + +Vtable for QQmlComponent +QQmlComponent::_ZTV13QQmlComponent: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlComponent) +16 (int (*)(...))QQmlComponent::metaObject +24 (int (*)(...))QQmlComponent::qt_metacast +32 (int (*)(...))QQmlComponent::qt_metacall +40 (int (*)(...))QQmlComponent::~QQmlComponent +48 (int (*)(...))QQmlComponent::~QQmlComponent +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlComponent::create +120 (int (*)(...))QQmlComponent::beginCreate +128 (int (*)(...))QQmlComponent::completeCreate + +Class QQmlComponent + size=16 align=8 + base size=16 base align=8 +QQmlComponent (0x0x7fc6688c5000) 0 + vptr=((& QQmlComponent::_ZTV13QQmlComponent) + 16) + QObject (0x0x7fc6688b5240) 0 + primary-for QQmlComponent (0x0x7fc6688c5000) + +Class QQmlContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlContext::QPrivateSignal (0x0x7fc668922060) 0 empty + +Class QQmlContext::PropertyPair + size=56 align=8 + base size=56 base align=8 +QQmlContext::PropertyPair (0x0x7fc6689220c0) 0 + +Vtable for QQmlContext +QQmlContext::_ZTV11QQmlContext: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QQmlContext) +16 (int (*)(...))QQmlContext::metaObject +24 (int (*)(...))QQmlContext::qt_metacast +32 (int (*)(...))QQmlContext::qt_metacall +40 (int (*)(...))QQmlContext::~QQmlContext +48 (int (*)(...))QQmlContext::~QQmlContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlContext + size=16 align=8 + base size=16 base align=8 +QQmlContext (0x0x7fc6688c5138) 0 + vptr=((& QQmlContext::_ZTV11QQmlContext) + 16) + QObject (0x0x7fc668922000) 0 + primary-for QQmlContext (0x0x7fc6688c5138) + +Class QQmlScriptString + size=8 align=8 + base size=8 base align=8 +QQmlScriptString (0x0x7fc668922720) 0 + +Class QQmlExpression::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExpression::QPrivateSignal (0x0x7fc668922d20) 0 empty + +Vtable for QQmlExpression +QQmlExpression::_ZTV14QQmlExpression: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QQmlExpression) +16 (int (*)(...))QQmlExpression::metaObject +24 (int (*)(...))QQmlExpression::qt_metacast +32 (int (*)(...))QQmlExpression::qt_metacall +40 (int (*)(...))QQmlExpression::~QQmlExpression +48 (int (*)(...))QQmlExpression::~QQmlExpression +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlExpression + size=16 align=8 + base size=16 base align=8 +QQmlExpression (0x0x7fc6688c5270) 0 + vptr=((& QQmlExpression::_ZTV14QQmlExpression) + 16) + QObject (0x0x7fc668922cc0) 0 + primary-for QQmlExpression (0x0x7fc6688c5270) + +Vtable for QQmlTypesExtensionInterface +QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QQmlTypesExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlTypesExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlTypesExtensionInterface (0x0x7fc668922ea0) 0 nearly-empty + vptr=((& QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface) + 16) + +Vtable for QQmlExtensionInterface +QQmlExtensionInterface::_ZTV22QQmlExtensionInterface: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QQmlExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlExtensionInterface (0x0x7fc6688c52d8) 0 nearly-empty + vptr=((& QQmlExtensionInterface::_ZTV22QQmlExtensionInterface) + 16) + QQmlTypesExtensionInterface (0x0x7fc668922f00) 0 nearly-empty + primary-for QQmlExtensionInterface (0x0x7fc6688c52d8) + +Vtable for QQmlEngineExtensionInterface +QQmlEngineExtensionInterface::_ZTV28QQmlEngineExtensionInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QQmlEngineExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlEngineExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlEngineExtensionInterface (0x0x7fc668922f60) 0 nearly-empty + vptr=((& QQmlEngineExtensionInterface::_ZTV28QQmlEngineExtensionInterface) + 16) + +Class QQmlExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExtensionPlugin::QPrivateSignal (0x0x7fc6689a2540) 0 empty + +Vtable for QQmlExtensionPlugin +QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +16 (int (*)(...))QQmlExtensionPlugin::metaObject +24 (int (*)(...))QQmlExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlExtensionPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQmlExtensionPlugin::unregisterTypes +128 (int (*)(...))QQmlExtensionPlugin::initializeEngine +136 (int (*)(...))-16 +144 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +152 0 +160 0 +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))QQmlExtensionPlugin::_ZThn16_N19QQmlExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlExtensionPlugin (0x0x7fc668833f50) 0 + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 16) + QObject (0x0x7fc6689a2480) 0 + primary-for QQmlExtensionPlugin (0x0x7fc668833f50) + QQmlExtensionInterface (0x0x7fc6688c5340) 16 nearly-empty + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 152) + QQmlTypesExtensionInterface (0x0x7fc6689a24e0) 16 nearly-empty + primary-for QQmlExtensionInterface (0x0x7fc6688c5340) + +Class QQmlEngineExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngineExtensionPlugin::QPrivateSignal (0x0x7fc6689a2780) 0 empty + +Vtable for QQmlEngineExtensionPlugin +QQmlEngineExtensionPlugin::_ZTV25QQmlEngineExtensionPlugin: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QQmlEngineExtensionPlugin) +16 (int (*)(...))QQmlEngineExtensionPlugin::metaObject +24 (int (*)(...))QQmlEngineExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlEngineExtensionPlugin::qt_metacall +40 (int (*)(...))QQmlEngineExtensionPlugin::~QQmlEngineExtensionPlugin +48 (int (*)(...))QQmlEngineExtensionPlugin::~QQmlEngineExtensionPlugin +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlEngineExtensionPlugin::initializeEngine +120 (int (*)(...))-16 +128 (int (*)(...))(& _ZTI25QQmlEngineExtensionPlugin) +136 (int (*)(...))QQmlEngineExtensionPlugin::_ZThn16_N25QQmlEngineExtensionPluginD1Ev +144 (int (*)(...))QQmlEngineExtensionPlugin::_ZThn16_N25QQmlEngineExtensionPluginD0Ev +152 (int (*)(...))QQmlEngineExtensionPlugin::_ZThn16_N25QQmlEngineExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlEngineExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlEngineExtensionPlugin (0x0x7fc668833a10) 0 + vptr=((& QQmlEngineExtensionPlugin::_ZTV25QQmlEngineExtensionPlugin) + 16) + QObject (0x0x7fc6689a26c0) 0 + primary-for QQmlEngineExtensionPlugin (0x0x7fc668833a10) + QQmlEngineExtensionInterface (0x0x7fc6689a2720) 16 nearly-empty + vptr=((& QQmlEngineExtensionPlugin::_ZTV25QQmlEngineExtensionPlugin) + 136) + +Class QQmlFile + size=8 align=8 + base size=8 base align=8 +QQmlFile (0x0x7fc6689a2840) 0 + +Class QQmlFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlFileSelector::QPrivateSignal (0x0x7fc6689a2900) 0 empty + +Vtable for QQmlFileSelector +QQmlFileSelector::_ZTV16QQmlFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlFileSelector) +16 (int (*)(...))QQmlFileSelector::metaObject +24 (int (*)(...))QQmlFileSelector::qt_metacast +32 (int (*)(...))QQmlFileSelector::qt_metacall +40 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +48 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlFileSelector + size=16 align=8 + base size=16 base align=8 +QQmlFileSelector (0x0x7fc6688c5410) 0 + vptr=((& QQmlFileSelector::_ZTV16QQmlFileSelector) + 16) + QObject (0x0x7fc6689a28a0) 0 + primary-for QQmlFileSelector (0x0x7fc6688c5410) + +Vtable for QQmlIncubator +QQmlIncubator::_ZTV13QQmlIncubator: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlIncubator) +16 (int (*)(...))QQmlIncubator::~QQmlIncubator +24 (int (*)(...))QQmlIncubator::~QQmlIncubator +32 (int (*)(...))QQmlIncubator::statusChanged +40 (int (*)(...))QQmlIncubator::setInitialState + +Class QQmlIncubator + size=16 align=8 + base size=16 base align=8 +QQmlIncubator (0x0x7fc6689a2a80) 0 + vptr=((& QQmlIncubator::_ZTV13QQmlIncubator) + 16) + +Vtable for QQmlIncubationController +QQmlIncubationController::_ZTV24QQmlIncubationController: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQmlIncubationController) +16 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +24 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +32 (int (*)(...))QQmlIncubationController::incubatingObjectCountChanged + +Class QQmlIncubationController + size=16 align=8 + base size=16 base align=8 +QQmlIncubationController (0x0x7fc6689a2ae0) 0 + vptr=((& QQmlIncubationController::_ZTV24QQmlIncubationController) + 16) + +Class QQmlInfo + size=16 align=8 + base size=16 base align=8 +QQmlInfo (0x0x7fc6688c5478) 0 + QDebug (0x0x7fc6688c54e0) 0 + QIODeviceBase (0x0x7fc6689a2b40) 0 empty + +Class QQmlModuleRegistration + size=8 align=8 + base size=8 base align=8 +QQmlModuleRegistration (0x0x7fc66868f2a0) 0 + +Vtable for QQmlNetworkAccessManagerFactory +QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI31QQmlNetworkAccessManagerFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlNetworkAccessManagerFactory + size=8 align=8 + base size=8 base align=8 +QQmlNetworkAccessManagerFactory (0x0x7fc66868f300) 0 nearly-empty + vptr=((& QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory) + 16) + +Class QQmlProperty + size=8 align=8 + base size=8 base align=8 +QQmlProperty (0x0x7fc66868f360) 0 + +Class QQmlPropertyMap::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlPropertyMap::QPrivateSignal (0x0x7fc6686f15a0) 0 empty + +Vtable for QQmlPropertyMap +QQmlPropertyMap::_ZTV15QQmlPropertyMap: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQmlPropertyMap) +16 (int (*)(...))QQmlPropertyMap::metaObject +24 (int (*)(...))QQmlPropertyMap::qt_metacast +32 (int (*)(...))QQmlPropertyMap::qt_metacall +40 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +48 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlPropertyMap::updateValue + +Class QQmlPropertyMap + size=16 align=8 + base size=16 base align=8 +QQmlPropertyMap (0x0x7fc6686f2a28) 0 + vptr=((& QQmlPropertyMap::_ZTV15QQmlPropertyMap) + 16) + QObject (0x0x7fc6686f1540) 0 + primary-for QQmlPropertyMap (0x0x7fc6686f2a28) + +Class QOpenGLBuffer + size=8 align=8 + base size=8 base align=8 +QOpenGLBuffer (0x0x7fc6686f1780) 0 + +Class QOpenGLDebugMessage + size=8 align=8 + base size=8 base align=8 +QOpenGLDebugMessage (0x0x7fc6686f1cc0) 0 + +Class QOpenGLDebugLogger::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLDebugLogger::QPrivateSignal (0x0x7fc6684af060) 0 empty + +Vtable for QOpenGLDebugLogger +QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger) +16 (int (*)(...))QOpenGLDebugLogger::metaObject +24 (int (*)(...))QOpenGLDebugLogger::qt_metacast +32 (int (*)(...))QOpenGLDebugLogger::qt_metacall +40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLDebugLogger + size=16 align=8 + base size=16 base align=8 +QOpenGLDebugLogger (0x0x7fc6684ae000) 0 + vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16) + QObject (0x0x7fc6684af000) 0 + primary-for QOpenGLDebugLogger (0x0x7fc6684ae000) + +Vtable for QOpenGLFramebufferObject +QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject) +16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject +24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject + +Class QOpenGLFramebufferObject + size=16 align=8 + base size=16 base align=8 +QOpenGLFramebufferObject (0x0x7fc6684af780) 0 + vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16) + +Class QOpenGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QOpenGLFramebufferObjectFormat (0x0x7fc6684afa20) 0 + +Vtable for QOpenGLPaintDevice +QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice) +16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +32 (int (*)(...))QOpenGLPaintDevice::devType +40 (int (*)(...))QOpenGLPaintDevice::paintEngine +48 (int (*)(...))QOpenGLPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget + +Class QOpenGLPaintDevice + size=24 align=8 + base size=24 base align=8 +QOpenGLPaintDevice (0x0x7fc6684ae0d0) 0 + vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16) + QPaintDevice (0x0x7fc6684afa80) 0 + primary-for QOpenGLPaintDevice (0x0x7fc6684ae0d0) + +Class QOpenGLPixelTransferOptions + size=8 align=8 + base size=8 base align=8 +QOpenGLPixelTransferOptions (0x0x7fc6684afcc0) 0 + +Class QOpenGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShader::QPrivateSignal (0x0x7fc6685643c0) 0 empty + +Vtable for QOpenGLShader +QOpenGLShader::_ZTV13QOpenGLShader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLShader) +16 (int (*)(...))QOpenGLShader::metaObject +24 (int (*)(...))QOpenGLShader::qt_metacast +32 (int (*)(...))QOpenGLShader::qt_metacall +40 (int (*)(...))QOpenGLShader::~QOpenGLShader +48 (int (*)(...))QOpenGLShader::~QOpenGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLShader + size=16 align=8 + base size=16 base align=8 +QOpenGLShader (0x0x7fc66855ca90) 0 + vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16) + QObject (0x0x7fc668564360) 0 + primary-for QOpenGLShader (0x0x7fc66855ca90) + +Class QOpenGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShaderProgram::QPrivateSignal (0x0x7fc668564960) 0 empty + +Vtable for QOpenGLShaderProgram +QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram) +16 (int (*)(...))QOpenGLShaderProgram::metaObject +24 (int (*)(...))QOpenGLShaderProgram::qt_metacast +32 (int (*)(...))QOpenGLShaderProgram::qt_metacall +40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOpenGLShaderProgram::link + +Class QOpenGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QOpenGLShaderProgram (0x0x7fc66855cc30) 0 + vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16) + QObject (0x0x7fc668564900) 0 + primary-for QOpenGLShaderProgram (0x0x7fc66855cc30) + +Class QOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QOpenGLTexture (0x0x7fc668564ae0) 0 + +Class QOpenGLTextureBlitter + size=8 align=8 + base size=8 base align=8 +QOpenGLTextureBlitter (0x0x7fc66826fcc0) 0 + +Class QOpenGLTimerQuery::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimerQuery::QPrivateSignal (0x0x7fc66826ff00) 0 empty + +Vtable for QOpenGLTimerQuery +QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery) +16 (int (*)(...))QOpenGLTimerQuery::metaObject +24 (int (*)(...))QOpenGLTimerQuery::qt_metacast +32 (int (*)(...))QOpenGLTimerQuery::qt_metacall +40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimerQuery + size=16 align=8 + base size=16 base align=8 +QOpenGLTimerQuery (0x0x7fc66855cdd0) 0 + vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16) + QObject (0x0x7fc66826fea0) 0 + primary-for QOpenGLTimerQuery (0x0x7fc66855cdd0) + +Class QOpenGLTimeMonitor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimeMonitor::QPrivateSignal (0x0x7fc6682e0120) 0 empty + +Vtable for QOpenGLTimeMonitor +QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor) +16 (int (*)(...))QOpenGLTimeMonitor::metaObject +24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast +32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall +40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimeMonitor + size=16 align=8 + base size=16 base align=8 +QOpenGLTimeMonitor (0x0x7fc66855ce38) 0 + vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16) + QObject (0x0x7fc6682e00c0) 0 + primary-for QOpenGLTimeMonitor (0x0x7fc66855ce38) + +Class QOpenGLVersionStatus + size=12 align=4 + base size=12 base align=4 +QOpenGLVersionStatus (0x0x7fc6682e02a0) 0 + +Class QOpenGLVersionFunctionsBackend + size=16 align=8 + base size=12 base align=8 +QOpenGLVersionFunctionsBackend (0x0x7fc6683c0300) 0 + +Class QOpenGLVersionFunctionsStorage + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionFunctionsStorage (0x0x7fc6683c04e0) 0 + +Class QAbstractOpenGLFunctionsPrivate + size=16 align=8 + base size=9 base align=8 +QAbstractOpenGLFunctionsPrivate (0x0x7fc6683c0540) 0 + +Vtable for QAbstractOpenGLFunctions +QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions) +16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions + +Class QAbstractOpenGLFunctions + size=16 align=8 + base size=16 base align=8 +QAbstractOpenGLFunctions (0x0x7fc6683c0720) 0 + vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16) + +Class QOpenGLFunctions_1_0_CoreBackend::Functions + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7fc6683c0900) 0 + +Class QOpenGLFunctions_1_0_CoreBackend + size=400 align=8 + base size=400 base align=8 +QOpenGLFunctions_1_0_CoreBackend (0x0x7fc6683a66e8) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc6683c08a0) 0 + +Class QOpenGLFunctions_1_1_CoreBackend::Functions + size=128 align=8 + base size=128 base align=8 +QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7fc6683c0c60) 0 + +Class QOpenGLFunctions_1_1_CoreBackend + size=144 align=8 + base size=144 base align=8 +QOpenGLFunctions_1_1_CoreBackend (0x0x7fc6683a6750) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc6683c0c00) 0 + +Class QOpenGLFunctions_1_2_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7fc668003000) 0 + +Class QOpenGLFunctions_1_2_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_1_2_CoreBackend (0x0x7fc6683a67b8) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc6683c0f60) 0 + +Class QOpenGLFunctions_1_3_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7fc668003360) 0 + +Class QOpenGLFunctions_1_3_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_1_3_CoreBackend (0x0x7fc6683a6820) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc668003300) 0 + +Class QOpenGLFunctions_1_4_CoreBackend::Functions + size=56 align=8 + base size=56 base align=8 +QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7fc6680036c0) 0 + +Class QOpenGLFunctions_1_4_CoreBackend + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_4_CoreBackend (0x0x7fc6683a6888) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc668003660) 0 + +Class QOpenGLFunctions_1_5_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7fc668003a20) 0 + +Class QOpenGLFunctions_1_5_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_1_5_CoreBackend (0x0x7fc6683a68f0) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc6680039c0) 0 + +Class QOpenGLFunctions_2_0_CoreBackend::Functions + size=744 align=8 + base size=744 base align=8 +QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7fc668003d80) 0 + +Class QOpenGLFunctions_2_0_CoreBackend + size=760 align=8 + base size=760 base align=8 +QOpenGLFunctions_2_0_CoreBackend (0x0x7fc6683a6958) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc668003d20) 0 + +Class QOpenGLFunctions_2_1_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7fc66803e120) 0 + +Class QOpenGLFunctions_2_1_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_2_1_CoreBackend (0x0x7fc6683a69c0) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc66803e0c0) 0 + +Class QOpenGLFunctions_3_0_CoreBackend::Functions + size=672 align=8 + base size=672 base align=8 +QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7fc66803e480) 0 + +Class QOpenGLFunctions_3_0_CoreBackend + size=688 align=8 + base size=688 base align=8 +QOpenGLFunctions_3_0_CoreBackend (0x0x7fc6683a6a28) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc66803e420) 0 + +Class QOpenGLFunctions_3_1_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7fc66803e7e0) 0 + +Class QOpenGLFunctions_3_1_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_3_1_CoreBackend (0x0x7fc6683a6a90) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc66803e780) 0 + +Class QOpenGLFunctions_3_2_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7fc66803eb40) 0 + +Class QOpenGLFunctions_3_2_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_3_2_CoreBackend (0x0x7fc6683a6af8) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc66803eae0) 0 + +Class QOpenGLFunctions_3_3_CoreBackend::Functions + size=464 align=8 + base size=464 base align=8 +QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7fc66803eea0) 0 + +Class QOpenGLFunctions_3_3_CoreBackend + size=480 align=8 + base size=480 base align=8 +QOpenGLFunctions_3_3_CoreBackend (0x0x7fc6683a6b60) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc66803ee40) 0 + +Class QOpenGLFunctions_4_0_CoreBackend::Functions + size=368 align=8 + base size=368 base align=8 +QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7fc668085240) 0 + +Class QOpenGLFunctions_4_0_CoreBackend + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_4_0_CoreBackend (0x0x7fc6683a6bc8) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc6680851e0) 0 + +Class QOpenGLFunctions_4_1_CoreBackend::Functions + size=704 align=8 + base size=704 base align=8 +QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7fc6680855a0) 0 + +Class QOpenGLFunctions_4_1_CoreBackend + size=720 align=8 + base size=720 base align=8 +QOpenGLFunctions_4_1_CoreBackend (0x0x7fc6683a6c30) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc668085540) 0 + +Class QOpenGLFunctions_4_2_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7fc668085900) 0 + +Class QOpenGLFunctions_4_2_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_2_CoreBackend (0x0x7fc6683a6c98) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc6680858a0) 0 + +Class QOpenGLFunctions_4_3_CoreBackend::Functions + size=344 align=8 + base size=344 base align=8 +QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7fc668085c60) 0 + +Class QOpenGLFunctions_4_3_CoreBackend + size=360 align=8 + base size=360 base align=8 +QOpenGLFunctions_4_3_CoreBackend (0x0x7fc6683a6d00) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc668085c00) 0 + +Class QOpenGLFunctions_4_4_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7fc6680d9000) 0 + +Class QOpenGLFunctions_4_4_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_4_4_CoreBackend (0x0x7fc6683a6d68) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc668085f60) 0 + +Class QOpenGLFunctions_4_5_CoreBackend::Functions + size=848 align=8 + base size=848 base align=8 +QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7fc6680d9360) 0 + +Class QOpenGLFunctions_4_5_CoreBackend + size=864 align=8 + base size=864 base align=8 +QOpenGLFunctions_4_5_CoreBackend (0x0x7fc6683a6dd0) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc6680d9300) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions + size=2064 align=8 + base size=2064 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7fc6680d96c0) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend + size=2080 align=8 + base size=2080 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7fc6683a6e38) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc6680d9660) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions + size=136 align=8 + base size=136 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7fc6680d9a20) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7fc6683a6ea0) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc6680d99c0) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7fc6680d9d80) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend + size=272 align=8 + base size=272 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7fc6683a6f08) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc6680d9d20) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions + size=296 align=8 + base size=296 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7fc66815e120) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend + size=312 align=8 + base size=312 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7fc6683a6f70) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc66815e0c0) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7fc66815e480) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend + size=320 align=8 + base size=320 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7fc66816c000) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc66815e420) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions + size=288 align=8 + base size=288 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7fc66815e7e0) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7fc66816c068) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc66815e780) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions + size=160 align=8 + base size=160 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7fc66815eb40) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend + size=176 align=8 + base size=176 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7fc66816c0d0) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc66815eae0) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions + size=240 align=8 + base size=240 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7fc66815eea0) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7fc66816c138) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc66815ee40) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7fc668198240) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7fc66816c1a0) 0 + QOpenGLVersionFunctionsBackend (0x0x7fc6681981e0) 0 + +Class QOpenGLVersionProfile + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionProfile (0x0x7fc668198540) 0 + +Class QOpenGLVersionFunctionsFactory + size=1 align=1 + base size=0 base align=1 +QOpenGLVersionFunctionsFactory (0x0x7fc6681986c0) 0 empty + +Class QOpenGLVertexArrayObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLVertexArrayObject::QPrivateSignal (0x0x7fc6681987e0) 0 empty + +Class QOpenGLVertexArrayObject::Binder + size=8 align=8 + base size=8 base align=8 +QOpenGLVertexArrayObject::Binder (0x0x7fc668198840) 0 + +Vtable for QOpenGLVertexArrayObject +QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject) +16 (int (*)(...))QOpenGLVertexArrayObject::metaObject +24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast +32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall +40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLVertexArrayObject + size=16 align=8 + base size=16 base align=8 +QOpenGLVertexArrayObject (0x0x7fc66816c208) 0 + vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16) + QObject (0x0x7fc668198780) 0 + primary-for QOpenGLVertexArrayObject (0x0x7fc66816c208) + +Class QOpenGLWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWindow::QPrivateSignal (0x0x7fc668198ea0) 0 empty + +Vtable for QOpenGLWindow +QOpenGLWindow::_ZTV13QOpenGLWindow: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWindow) +16 (int (*)(...))QOpenGLWindow::metaObject +24 (int (*)(...))QOpenGLWindow::qt_metacast +32 (int (*)(...))QOpenGLWindow::qt_metacall +40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QOpenGLWindow::resizeEvent +168 (int (*)(...))QOpenGLWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QWindow::focusInEvent +192 (int (*)(...))QWindow::focusOutEvent +200 (int (*)(...))QWindow::showEvent +208 (int (*)(...))QWindow::hideEvent +216 (int (*)(...))QWindow::closeEvent +224 (int (*)(...))QWindow::keyPressEvent +232 (int (*)(...))QWindow::keyReleaseEvent +240 (int (*)(...))QWindow::mousePressEvent +248 (int (*)(...))QWindow::mouseReleaseEvent +256 (int (*)(...))QWindow::mouseDoubleClickEvent +264 (int (*)(...))QWindow::mouseMoveEvent +272 (int (*)(...))QWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))QOpenGLWindow::metric +320 (int (*)(...))QPaintDeviceWindow::paintEngine +328 (int (*)(...))QOpenGLWindow::initializeGL +336 (int (*)(...))QOpenGLWindow::resizeGL +344 (int (*)(...))QOpenGLWindow::paintGL +352 (int (*)(...))QOpenGLWindow::paintUnderGL +360 (int (*)(...))QOpenGLWindow::paintOverGL +368 (int (*)(...))QOpenGLWindow::redirected +376 (int (*)(...))-16 +384 (int (*)(...))(& _ZTI13QOpenGLWindow) +392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev +400 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev +408 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +416 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +424 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +432 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +440 (int (*)(...))-40 +448 (int (*)(...))(& _ZTI13QOpenGLWindow) +456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev +464 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev +472 (int (*)(...))QPaintDevice::devType +480 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +488 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QPaintDevice::initPainter +504 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint +512 (int (*)(...))QPaintDevice::sharedPainter + +Class QOpenGLWindow + size=56 align=8 + base size=50 base align=8 +QOpenGLWindow (0x0x7fc66816c2d8) 0 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16) + QPaintDeviceWindow (0x0x7fc667fd31c0) 0 + primary-for QOpenGLWindow (0x0x7fc66816c2d8) + QWindow (0x0x7fc667fd3230) 0 + primary-for QPaintDeviceWindow (0x0x7fc667fd31c0) + QObject (0x0x7fc668198d80) 0 + primary-for QWindow (0x0x7fc667fd3230) + QSurface (0x0x7fc668198de0) 16 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 392) + QPaintDevice (0x0x7fc668198e40) 40 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 456) + +Class QQuickTransform::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTransform::QPrivateSignal (0x0x7fc667ddb0c0) 0 empty + +Vtable for QQuickTransform +QQuickTransform::_ZTV15QQuickTransform: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQuickTransform) +16 (int (*)(...))QQuickTransform::metaObject +24 (int (*)(...))QQuickTransform::qt_metacast +32 (int (*)(...))QQuickTransform::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QQuickTransform + size=16 align=8 + base size=16 base align=8 +QQuickTransform (0x0x7fc66816c3a8) 0 + vptr=((& QQuickTransform::_ZTV15QQuickTransform) + 16) + QObject (0x0x7fc667ddb060) 0 + primary-for QQuickTransform (0x0x7fc66816c3a8) + +Class QQuickItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItem::QPrivateSignal (0x0x7fc667ddb300) 0 empty + +Class QQuickItem::ItemChangeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::ItemChangeData (0x0x7fc667ddb360) 0 + +Class QQuickItem::UpdatePaintNodeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::UpdatePaintNodeData (0x0x7fc667ddb3c0) 0 + +Vtable for QQuickItem +QQuickItem::_ZTV10QQuickItem: 54 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickItem) +16 (int (*)(...))QQuickItem::metaObject +24 (int (*)(...))QQuickItem::qt_metacast +32 (int (*)(...))QQuickItem::qt_metacall +40 (int (*)(...))QQuickItem::~QQuickItem +48 (int (*)(...))QQuickItem::~QQuickItem +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickItem::isTextureProvider +152 (int (*)(...))QQuickItem::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::geometryChange +176 (int (*)(...))QQuickItem::classBegin +184 (int (*)(...))QQuickItem::componentComplete +192 (int (*)(...))QQuickItem::keyPressEvent +200 (int (*)(...))QQuickItem::keyReleaseEvent +208 (int (*)(...))QQuickItem::inputMethodEvent +216 (int (*)(...))QQuickItem::focusInEvent +224 (int (*)(...))QQuickItem::focusOutEvent +232 (int (*)(...))QQuickItem::mousePressEvent +240 (int (*)(...))QQuickItem::mouseMoveEvent +248 (int (*)(...))QQuickItem::mouseReleaseEvent +256 (int (*)(...))QQuickItem::mouseDoubleClickEvent +264 (int (*)(...))QQuickItem::mouseUngrabEvent +272 (int (*)(...))QQuickItem::touchUngrabEvent +280 (int (*)(...))QQuickItem::wheelEvent +288 (int (*)(...))QQuickItem::touchEvent +296 (int (*)(...))QQuickItem::hoverEnterEvent +304 (int (*)(...))QQuickItem::hoverMoveEvent +312 (int (*)(...))QQuickItem::hoverLeaveEvent +320 (int (*)(...))QQuickItem::dragEnterEvent +328 (int (*)(...))QQuickItem::dragMoveEvent +336 (int (*)(...))QQuickItem::dragLeaveEvent +344 (int (*)(...))QQuickItem::dropEvent +352 (int (*)(...))QQuickItem::childMouseEventFilter +360 (int (*)(...))QQuickItem::updatePaintNode +368 (int (*)(...))QQuickItem::releaseResources +376 (int (*)(...))QQuickItem::updatePolish +384 (int (*)(...))-16 +392 (int (*)(...))(& _ZTI10QQuickItem) +400 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD1Ev +408 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD0Ev +416 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickItem + size=32 align=8 + base size=32 base align=8 +QQuickItem (0x0x7fc667fd33f0) 0 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 16) + QObject (0x0x7fc667ddb240) 0 + primary-for QQuickItem (0x0x7fc667fd33f0) + QQmlParserStatus (0x0x7fc667ddb2a0) 16 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 400) + +Class QQuickFramebufferObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickFramebufferObject::QPrivateSignal (0x0x7fc667f290c0) 0 empty + +Vtable for QQuickFramebufferObject::Renderer +QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN23QQuickFramebufferObject8RendererE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QQuickFramebufferObject::Renderer::createFramebufferObject +48 (int (*)(...))QQuickFramebufferObject::Renderer::synchronize + +Class QQuickFramebufferObject::Renderer + size=16 align=8 + base size=16 base align=8 +QQuickFramebufferObject::Renderer (0x0x7fc667f29120) 0 + vptr=((& QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE) + 16) + +Vtable for QQuickFramebufferObject +QQuickFramebufferObject::_ZTV23QQuickFramebufferObject: 55 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +16 (int (*)(...))QQuickFramebufferObject::metaObject +24 (int (*)(...))QQuickFramebufferObject::qt_metacast +32 (int (*)(...))QQuickFramebufferObject::qt_metacall +40 0 +48 0 +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickFramebufferObject::isTextureProvider +152 (int (*)(...))QQuickFramebufferObject::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickFramebufferObject::geometryChange +176 (int (*)(...))QQuickItem::classBegin +184 (int (*)(...))QQuickItem::componentComplete +192 (int (*)(...))QQuickItem::keyPressEvent +200 (int (*)(...))QQuickItem::keyReleaseEvent +208 (int (*)(...))QQuickItem::inputMethodEvent +216 (int (*)(...))QQuickItem::focusInEvent +224 (int (*)(...))QQuickItem::focusOutEvent +232 (int (*)(...))QQuickItem::mousePressEvent +240 (int (*)(...))QQuickItem::mouseMoveEvent +248 (int (*)(...))QQuickItem::mouseReleaseEvent +256 (int (*)(...))QQuickItem::mouseDoubleClickEvent +264 (int (*)(...))QQuickItem::mouseUngrabEvent +272 (int (*)(...))QQuickItem::touchUngrabEvent +280 (int (*)(...))QQuickItem::wheelEvent +288 (int (*)(...))QQuickItem::touchEvent +296 (int (*)(...))QQuickItem::hoverEnterEvent +304 (int (*)(...))QQuickItem::hoverMoveEvent +312 (int (*)(...))QQuickItem::hoverLeaveEvent +320 (int (*)(...))QQuickItem::dragEnterEvent +328 (int (*)(...))QQuickItem::dragMoveEvent +336 (int (*)(...))QQuickItem::dragLeaveEvent +344 (int (*)(...))QQuickItem::dropEvent +352 (int (*)(...))QQuickItem::childMouseEventFilter +360 (int (*)(...))QQuickFramebufferObject::updatePaintNode +368 (int (*)(...))QQuickFramebufferObject::releaseResources +376 (int (*)(...))QQuickItem::updatePolish +384 (int (*)(...))__cxa_pure_virtual +392 (int (*)(...))-16 +400 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +408 0 +416 0 +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickFramebufferObject + size=32 align=8 + base size=32 base align=8 +QQuickFramebufferObject (0x0x7fc667f1ee38) 0 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 16) + QQuickItem (0x0x7fc667e7d8c0) 0 + primary-for QQuickFramebufferObject (0x0x7fc667f1ee38) + QObject (0x0x7fc667f29000) 0 + primary-for QQuickItem (0x0x7fc667e7d8c0) + QQmlParserStatus (0x0x7fc667f29060) 16 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 408) + +Class QQuickGraphicsConfiguration + size=8 align=8 + base size=8 base align=8 +QQuickGraphicsConfiguration (0x0x7fc667f292a0) 0 + +Class QQuickGraphicsDevice + size=8 align=8 + base size=8 base align=8 +QQuickGraphicsDevice (0x0x7fc667f29300) 0 + +Class QQuickTextureFactory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextureFactory::QPrivateSignal (0x0x7fc667f293c0) 0 empty + +Vtable for QQuickTextureFactory +QQuickTextureFactory::_ZTV20QQuickTextureFactory: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickTextureFactory) +16 (int (*)(...))QQuickTextureFactory::metaObject +24 (int (*)(...))QQuickTextureFactory::qt_metacast +32 (int (*)(...))QQuickTextureFactory::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))QQuickTextureFactory::image + +Class QQuickTextureFactory + size=16 align=8 + base size=16 base align=8 +QQuickTextureFactory (0x0x7fc667f1eea0) 0 + vptr=((& QQuickTextureFactory::_ZTV20QQuickTextureFactory) + 16) + QObject (0x0x7fc667f29360) 0 + primary-for QQuickTextureFactory (0x0x7fc667f1eea0) + +Class QQuickImageResponse::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickImageResponse::QPrivateSignal (0x0x7fc667f294e0) 0 empty + +Vtable for QQuickImageResponse +QQuickImageResponse::_ZTV19QQuickImageResponse: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageResponse) +16 (int (*)(...))QQuickImageResponse::metaObject +24 (int (*)(...))QQuickImageResponse::qt_metacast +32 (int (*)(...))QQuickImageResponse::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQuickImageResponse::errorString +128 (int (*)(...))QQuickImageResponse::cancel + +Class QQuickImageResponse + size=16 align=8 + base size=16 base align=8 +QQuickImageResponse (0x0x7fc667f1ef08) 0 + vptr=((& QQuickImageResponse::_ZTV19QQuickImageResponse) + 16) + QObject (0x0x7fc667f29480) 0 + primary-for QQuickImageResponse (0x0x7fc667f1ef08) + +Class QQuickImageProvider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickImageProvider::QPrivateSignal (0x0x7fc667f296c0) 0 empty + +Vtable for QQuickImageProvider +QQuickImageProvider::_ZTV19QQuickImageProvider: 19 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageProvider) +16 (int (*)(...))QQuickImageProvider::metaObject +24 (int (*)(...))QQuickImageProvider::qt_metacast +32 (int (*)(...))QQuickImageProvider::qt_metacall +40 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +48 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickImageProvider::imageType +120 (int (*)(...))QQuickImageProvider::flags +128 (int (*)(...))QQuickImageProvider::requestImage +136 (int (*)(...))QQuickImageProvider::requestPixmap +144 (int (*)(...))QQuickImageProvider::requestTexture + +Class QQuickImageProvider + size=24 align=8 + base size=24 base align=8 +QQuickImageProvider (0x0x7fc667f1ef70) 0 + vptr=((& QQuickImageProvider::_ZTV19QQuickImageProvider) + 16) + QQmlImageProviderBase (0x0x7fc667f55000) 0 + primary-for QQuickImageProvider (0x0x7fc667f1ef70) + QObject (0x0x7fc667f29660) 0 + primary-for QQmlImageProviderBase (0x0x7fc667f55000) + +Vtable for QQuickAsyncImageProvider +QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQuickAsyncImageProvider) +16 (int (*)(...))QQuickImageProvider::metaObject +24 (int (*)(...))QQuickImageProvider::qt_metacast +32 (int (*)(...))QQuickImageProvider::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickImageProvider::imageType +120 (int (*)(...))QQuickImageProvider::flags +128 (int (*)(...))QQuickImageProvider::requestImage +136 (int (*)(...))QQuickImageProvider::requestPixmap +144 (int (*)(...))QQuickImageProvider::requestTexture +152 (int (*)(...))__cxa_pure_virtual + +Class QQuickAsyncImageProvider + size=32 align=8 + base size=32 base align=8 +QQuickAsyncImageProvider (0x0x7fc667f55068) 0 + vptr=((& QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider) + 16) + QQuickImageProvider (0x0x7fc667f550d0) 0 + primary-for QQuickAsyncImageProvider (0x0x7fc667f55068) + QQmlImageProviderBase (0x0x7fc667f55138) 0 + primary-for QQuickImageProvider (0x0x7fc667f550d0) + QObject (0x0x7fc667f29780) 0 + primary-for QQmlImageProviderBase (0x0x7fc667f55138) + +Class QQuickItemGrabResult::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItemGrabResult::QPrivateSignal (0x0x7fc667f29840) 0 empty + +Vtable for QQuickItemGrabResult +QQuickItemGrabResult::_ZTV20QQuickItemGrabResult: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickItemGrabResult) +16 (int (*)(...))QQuickItemGrabResult::metaObject +24 (int (*)(...))QQuickItemGrabResult::qt_metacast +32 (int (*)(...))QQuickItemGrabResult::qt_metacall +40 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +48 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +56 (int (*)(...))QQuickItemGrabResult::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickItemGrabResult + size=16 align=8 + base size=16 base align=8 +QQuickItemGrabResult (0x0x7fc667f551a0) 0 + vptr=((& QQuickItemGrabResult::_ZTV20QQuickItemGrabResult) + 16) + QObject (0x0x7fc667f297e0) 0 + primary-for QQuickItemGrabResult (0x0x7fc667f551a0) + +Class QQuickPaintedItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickPaintedItem::QPrivateSignal (0x0x7fc667f29a80) 0 empty + +Vtable for QQuickPaintedItem +QQuickPaintedItem::_ZTV17QQuickPaintedItem: 55 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QQuickPaintedItem) +16 (int (*)(...))QQuickPaintedItem::metaObject +24 (int (*)(...))QQuickPaintedItem::qt_metacast +32 (int (*)(...))QQuickPaintedItem::qt_metacall +40 0 +48 0 +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickPaintedItem::isTextureProvider +152 (int (*)(...))QQuickPaintedItem::textureProvider +160 (int (*)(...))QQuickPaintedItem::itemChange +168 (int (*)(...))QQuickItem::geometryChange +176 (int (*)(...))QQuickItem::classBegin +184 (int (*)(...))QQuickItem::componentComplete +192 (int (*)(...))QQuickItem::keyPressEvent +200 (int (*)(...))QQuickItem::keyReleaseEvent +208 (int (*)(...))QQuickItem::inputMethodEvent +216 (int (*)(...))QQuickItem::focusInEvent +224 (int (*)(...))QQuickItem::focusOutEvent +232 (int (*)(...))QQuickItem::mousePressEvent +240 (int (*)(...))QQuickItem::mouseMoveEvent +248 (int (*)(...))QQuickItem::mouseReleaseEvent +256 (int (*)(...))QQuickItem::mouseDoubleClickEvent +264 (int (*)(...))QQuickItem::mouseUngrabEvent +272 (int (*)(...))QQuickItem::touchUngrabEvent +280 (int (*)(...))QQuickItem::wheelEvent +288 (int (*)(...))QQuickItem::touchEvent +296 (int (*)(...))QQuickItem::hoverEnterEvent +304 (int (*)(...))QQuickItem::hoverMoveEvent +312 (int (*)(...))QQuickItem::hoverLeaveEvent +320 (int (*)(...))QQuickItem::dragEnterEvent +328 (int (*)(...))QQuickItem::dragMoveEvent +336 (int (*)(...))QQuickItem::dragLeaveEvent +344 (int (*)(...))QQuickItem::dropEvent +352 (int (*)(...))QQuickItem::childMouseEventFilter +360 (int (*)(...))QQuickPaintedItem::updatePaintNode +368 (int (*)(...))QQuickPaintedItem::releaseResources +376 (int (*)(...))QQuickItem::updatePolish +384 (int (*)(...))__cxa_pure_virtual +392 (int (*)(...))-16 +400 (int (*)(...))(& _ZTI17QQuickPaintedItem) +408 0 +416 0 +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickPaintedItem + size=32 align=8 + base size=32 base align=8 +QQuickPaintedItem (0x0x7fc667f55208) 0 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 16) + QQuickItem (0x0x7fc667e7d930) 0 + primary-for QQuickPaintedItem (0x0x7fc667f55208) + QObject (0x0x7fc667f299c0) 0 + primary-for QQuickItem (0x0x7fc667e7d930) + QQmlParserStatus (0x0x7fc667f29a20) 16 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 408) + +Class QQuickRenderControl::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickRenderControl::QPrivateSignal (0x0x7fc667fb71e0) 0 empty + +Vtable for QQuickRenderControl +QQuickRenderControl::_ZTV19QQuickRenderControl: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickRenderControl) +16 (int (*)(...))QQuickRenderControl::metaObject +24 (int (*)(...))QQuickRenderControl::qt_metacast +32 (int (*)(...))QQuickRenderControl::qt_metacall +40 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +48 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickRenderControl::renderWindow + +Class QQuickRenderControl + size=16 align=8 + base size=16 base align=8 +QQuickRenderControl (0x0x7fc667f553a8) 0 + vptr=((& QQuickRenderControl::_ZTV19QQuickRenderControl) + 16) + QObject (0x0x7fc667fb7180) 0 + primary-for QQuickRenderControl (0x0x7fc667f553a8) + +Class QQuickRenderTarget + size=8 align=8 + base size=8 base align=8 +QQuickRenderTarget (0x0x7fc667fb73c0) 0 + +Class QQuickTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextDocument::QPrivateSignal (0x0x7fc667fb7540) 0 empty + +Vtable for QQuickTextDocument +QQuickTextDocument::_ZTV18QQuickTextDocument: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QQuickTextDocument) +16 (int (*)(...))QQuickTextDocument::metaObject +24 (int (*)(...))QQuickTextDocument::qt_metacast +32 (int (*)(...))QQuickTextDocument::qt_metacall +40 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +48 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickTextDocument + size=16 align=8 + base size=16 base align=8 +QQuickTextDocument (0x0x7fc667f55410) 0 + vptr=((& QQuickTextDocument::_ZTV18QQuickTextDocument) + 16) + QObject (0x0x7fc667fb74e0) 0 + primary-for QQuickTextDocument (0x0x7fc667f55410) + +Class QSGGeometry::Attribute + size=16 align=4 + base size=16 base align=4 +QSGGeometry::Attribute (0x0x7fc667c2fd80) 0 + +Class QSGGeometry::AttributeSet + size=16 align=8 + base size=16 base align=8 +QSGGeometry::AttributeSet (0x0x7fc667c2fde0) 0 + +Class QSGGeometry::Point2D + size=8 align=4 + base size=8 base align=4 +QSGGeometry::Point2D (0x0x7fc667c2fe40) 0 + +Class QSGGeometry::TexturedPoint2D + size=16 align=4 + base size=16 base align=4 +QSGGeometry::TexturedPoint2D (0x0x7fc667c2fea0) 0 + +Class QSGGeometry::ColoredPoint2D + size=12 align=4 + base size=12 base align=4 +QSGGeometry::ColoredPoint2D (0x0x7fc667c2ff00) 0 + +Vtable for QSGGeometry +QSGGeometry::_ZTV11QSGGeometry: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGGeometry) +16 (int (*)(...))QSGGeometry::~QSGGeometry +24 (int (*)(...))QSGGeometry::~QSGGeometry + +Class QSGGeometry + size=128 align=8 + base size=128 base align=8 +QSGGeometry (0x0x7fc667c2fd20) 0 + vptr=((& QSGGeometry::_ZTV11QSGGeometry) + 16) + +Vtable for QSGNode +QSGNode::_ZTV7QSGNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QSGNode) +16 (int (*)(...))QSGNode::~QSGNode +24 (int (*)(...))QSGNode::~QSGNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGNode + size=72 align=8 + base size=72 base align=8 +QSGNode (0x0x7fc667c81900) 0 + vptr=((& QSGNode::_ZTV7QSGNode) + 16) + +Vtable for QSGBasicGeometryNode +QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGBasicGeometryNode) +16 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +24 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGBasicGeometryNode + size=104 align=8 + base size=104 base align=8 +QSGBasicGeometryNode (0x0x7fc667c5cea0) 0 + vptr=((& QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode) + 16) + QSGNode (0x0x7fc667cea180) 0 + primary-for QSGBasicGeometryNode (0x0x7fc667c5cea0) + +Vtable for QSGGeometryNode +QSGGeometryNode::_ZTV15QSGGeometryNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSGGeometryNode) +16 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +24 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGGeometryNode + size=136 align=8 + base size=136 base align=8 +QSGGeometryNode (0x0x7fc667c5cf08) 0 + vptr=((& QSGGeometryNode::_ZTV15QSGGeometryNode) + 16) + QSGBasicGeometryNode (0x0x7fc667c5cf70) 0 + primary-for QSGGeometryNode (0x0x7fc667c5cf08) + QSGNode (0x0x7fc667cea420) 0 + primary-for QSGBasicGeometryNode (0x0x7fc667c5cf70) + +Vtable for QSGClipNode +QSGClipNode::_ZTV11QSGClipNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGClipNode) +16 (int (*)(...))QSGClipNode::~QSGClipNode +24 (int (*)(...))QSGClipNode::~QSGClipNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGClipNode + size=144 align=8 + base size=144 base align=8 +QSGClipNode (0x0x7fc667d0c000) 0 + vptr=((& QSGClipNode::_ZTV11QSGClipNode) + 16) + QSGBasicGeometryNode (0x0x7fc667d0c068) 0 + primary-for QSGClipNode (0x0x7fc667d0c000) + QSGNode (0x0x7fc667cea600) 0 + primary-for QSGBasicGeometryNode (0x0x7fc667d0c068) + +Vtable for QSGTransformNode +QSGTransformNode::_ZTV16QSGTransformNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGTransformNode) +16 (int (*)(...))QSGTransformNode::~QSGTransformNode +24 (int (*)(...))QSGTransformNode::~QSGTransformNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGTransformNode + size=208 align=8 + base size=208 base align=8 +QSGTransformNode (0x0x7fc667d0c0d0) 0 + vptr=((& QSGTransformNode::_ZTV16QSGTransformNode) + 16) + QSGNode (0x0x7fc667cea720) 0 + primary-for QSGTransformNode (0x0x7fc667d0c0d0) + +Vtable for QSGRootNode +QSGRootNode::_ZTV11QSGRootNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGRootNode) +16 (int (*)(...))QSGRootNode::~QSGRootNode +24 (int (*)(...))QSGRootNode::~QSGRootNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGRootNode + size=96 align=8 + base size=96 base align=8 +QSGRootNode (0x0x7fc667d0c138) 0 + vptr=((& QSGRootNode::_ZTV11QSGRootNode) + 16) + QSGNode (0x0x7fc667cea840) 0 + primary-for QSGRootNode (0x0x7fc667d0c138) + +Vtable for QSGOpacityNode +QSGOpacityNode::_ZTV14QSGOpacityNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGOpacityNode) +16 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +24 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +32 (int (*)(...))QSGOpacityNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGOpacityNode + size=88 align=8 + base size=88 base align=8 +QSGOpacityNode (0x0x7fc667d0ca28) 0 + vptr=((& QSGOpacityNode::_ZTV14QSGOpacityNode) + 16) + QSGNode (0x0x7fc667d45240) 0 + primary-for QSGOpacityNode (0x0x7fc667d0ca28) + +Vtable for QSGNodeVisitor +QSGNodeVisitor::_ZTV14QSGNodeVisitor: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGNodeVisitor) +16 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +24 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +32 (int (*)(...))QSGNodeVisitor::enterTransformNode +40 (int (*)(...))QSGNodeVisitor::leaveTransformNode +48 (int (*)(...))QSGNodeVisitor::enterClipNode +56 (int (*)(...))QSGNodeVisitor::leaveClipNode +64 (int (*)(...))QSGNodeVisitor::enterGeometryNode +72 (int (*)(...))QSGNodeVisitor::leaveGeometryNode +80 (int (*)(...))QSGNodeVisitor::enterOpacityNode +88 (int (*)(...))QSGNodeVisitor::leaveOpacityNode +96 (int (*)(...))QSGNodeVisitor::visitNode +104 (int (*)(...))QSGNodeVisitor::visitChildren + +Class QSGNodeVisitor + size=8 align=8 + base size=8 base align=8 +QSGNodeVisitor (0x0x7fc667d45360) 0 nearly-empty + vptr=((& QSGNodeVisitor::_ZTV14QSGNodeVisitor) + 16) + +Vtable for QSGRendererInterface +QSGRendererInterface::_ZTV20QSGRendererInterface: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGRendererInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QSGRendererInterface::getResource +48 (int (*)(...))QSGRendererInterface::getResource +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRendererInterface + size=8 align=8 + base size=8 base align=8 +QSGRendererInterface (0x0x7fc667d45a80) 0 nearly-empty + vptr=((& QSGRendererInterface::_ZTV20QSGRendererInterface) + 16) + +Class QQuickWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickWindow::QPrivateSignal (0x0x7fc667a4b300) 0 empty + +Class QQuickWindow::GraphicsStateInfo + size=8 align=4 + base size=8 base align=4 +QQuickWindow::GraphicsStateInfo (0x0x7fc667a4b360) 0 + +Vtable for QQuickWindow +QQuickWindow::_ZTV12QQuickWindow: 47 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QQuickWindow) +16 (int (*)(...))QQuickWindow::metaObject +24 (int (*)(...))QQuickWindow::qt_metacast +32 (int (*)(...))QQuickWindow::qt_metacall +40 (int (*)(...))QQuickWindow::~QQuickWindow +48 (int (*)(...))QQuickWindow::~QQuickWindow +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickWindow::resizeEvent +168 (int (*)(...))QWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QQuickWindow::focusInEvent +192 (int (*)(...))QQuickWindow::focusOutEvent +200 (int (*)(...))QQuickWindow::showEvent +208 (int (*)(...))QQuickWindow::hideEvent +216 (int (*)(...))QQuickWindow::closeEvent +224 (int (*)(...))QQuickWindow::keyPressEvent +232 (int (*)(...))QQuickWindow::keyReleaseEvent +240 (int (*)(...))QQuickWindow::mousePressEvent +248 (int (*)(...))QQuickWindow::mouseReleaseEvent +256 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +264 (int (*)(...))QQuickWindow::mouseMoveEvent +272 (int (*)(...))QQuickWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QQuickWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))-16 +320 (int (*)(...))(& _ZTI12QQuickWindow) +328 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD1Ev +336 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD0Ev +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickWindow + size=40 align=8 + base size=40 base align=8 +QQuickWindow (0x0x7fc667d0cd00) 0 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 16) + QWindow (0x0x7fc6679eb690) 0 + primary-for QQuickWindow (0x0x7fc667d0cd00) + QObject (0x0x7fc667a4b240) 0 + primary-for QWindow (0x0x7fc6679eb690) + QSurface (0x0x7fc667a4b2a0) 16 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 328) + +Class QQuickView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickView::QPrivateSignal (0x0x7fc667af3c00) 0 empty + +Vtable for QQuickView +QQuickView::_ZTV10QQuickView: 47 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickView) +16 (int (*)(...))QQuickView::metaObject +24 (int (*)(...))QQuickView::qt_metacast +32 (int (*)(...))QQuickView::qt_metacall +40 (int (*)(...))QQuickView::~QQuickView +48 (int (*)(...))QQuickView::~QQuickView +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QQuickView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickView::resizeEvent +168 (int (*)(...))QWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QQuickWindow::focusInEvent +192 (int (*)(...))QQuickWindow::focusOutEvent +200 (int (*)(...))QQuickWindow::showEvent +208 (int (*)(...))QQuickWindow::hideEvent +216 (int (*)(...))QQuickWindow::closeEvent +224 (int (*)(...))QQuickView::keyPressEvent +232 (int (*)(...))QQuickView::keyReleaseEvent +240 (int (*)(...))QQuickView::mousePressEvent +248 (int (*)(...))QQuickView::mouseReleaseEvent +256 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +264 (int (*)(...))QQuickView::mouseMoveEvent +272 (int (*)(...))QQuickWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QQuickWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))-16 +320 (int (*)(...))(& _ZTI10QQuickView) +328 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD1Ev +336 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD0Ev +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickView + size=40 align=8 + base size=40 base align=8 +QQuickView (0x0x7fc667af77b8) 0 + vptr=((& QQuickView::_ZTV10QQuickView) + 16) + QQuickWindow (0x0x7fc667af7820) 0 + primary-for QQuickView (0x0x7fc667af77b8) + QWindow (0x0x7fc6679ebf50) 0 + primary-for QQuickWindow (0x0x7fc667af7820) + QObject (0x0x7fc667af3b40) 0 + primary-for QWindow (0x0x7fc6679ebf50) + QSurface (0x0x7fc667af3ba0) 16 + vptr=((& QQuickView::_ZTV10QQuickView) + 328) + +Class QSGMaterialType + size=1 align=1 + base size=0 base align=1 +QSGMaterialType (0x0x7fc667af3f00) 0 empty + +Class QSGMaterialShader::RenderState + size=16 align=8 + base size=16 base align=8 +QSGMaterialShader::RenderState (0x0x7fc667b31000) 0 + +Class QSGMaterialShader::GraphicsPipelineState + size=36 align=4 + base size=36 base align=4 +QSGMaterialShader::GraphicsPipelineState (0x0x7fc667b31240) 0 + +Vtable for QSGMaterialShader +QSGMaterialShader::_ZTV17QSGMaterialShader: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGMaterialShader) +16 (int (*)(...))QSGMaterialShader::~QSGMaterialShader +24 (int (*)(...))QSGMaterialShader::~QSGMaterialShader +32 (int (*)(...))QSGMaterialShader::updateUniformData +40 (int (*)(...))QSGMaterialShader::updateSampledImage +48 (int (*)(...))QSGMaterialShader::updateGraphicsPipelineState + +Class QSGMaterialShader + size=16 align=8 + base size=16 base align=8 +QSGMaterialShader (0x0x7fc667af3f60) 0 + vptr=((& QSGMaterialShader::_ZTV17QSGMaterialShader) + 16) + +Vtable for QSGMaterial +QSGMaterial::_ZTV11QSGMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGMaterial) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QSGMaterial::compare + +Class QSGMaterial + size=24 align=8 + base size=24 base align=8 +QSGMaterial (0x0x7fc667837000) 0 + vptr=((& QSGMaterial::_ZTV11QSGMaterial) + 16) + +Vtable for QSGFlatColorMaterial +QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGFlatColorMaterial) +16 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +24 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +32 (int (*)(...))QSGFlatColorMaterial::type +40 (int (*)(...))QSGFlatColorMaterial::createShader +48 (int (*)(...))QSGFlatColorMaterial::compare + +Class QSGFlatColorMaterial + size=40 align=8 + base size=40 base align=8 +QSGFlatColorMaterial (0x0x7fc667af7d68) 0 + vptr=((& QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial) + 16) + QSGMaterial (0x0x7fc667837480) 0 + primary-for QSGFlatColorMaterial (0x0x7fc667af7d68) + +Class QNativeInterface::QSGOpenGLTexture::TypeInfo + size=1 align=1 + base size=0 base align=1 +QNativeInterface::QSGOpenGLTexture::TypeInfo (0x0x7fc6678375a0) 0 empty + +Vtable for QNativeInterface::QSGOpenGLTexture +QNativeInterface::QSGOpenGLTexture::_ZTVN16QNativeInterface16QSGOpenGLTextureE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface16QSGOpenGLTextureE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QSGOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QSGOpenGLTexture (0x0x7fc667837540) 0 nearly-empty + vptr=((& QNativeInterface::QSGOpenGLTexture::_ZTVN16QNativeInterface16QSGOpenGLTextureE) + 16) + +Class QNativeInterface::QSGVulkanTexture::TypeInfo + size=1 align=1 + base size=0 base align=1 +QNativeInterface::QSGVulkanTexture::TypeInfo (0x0x7fc6678376c0) 0 empty + +Vtable for QNativeInterface::QSGVulkanTexture +QNativeInterface::QSGVulkanTexture::_ZTVN16QNativeInterface16QSGVulkanTextureE: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface16QSGVulkanTextureE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QSGVulkanTexture + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QSGVulkanTexture (0x0x7fc667837660) 0 nearly-empty + vptr=((& QNativeInterface::QSGVulkanTexture::_ZTVN16QNativeInterface16QSGVulkanTextureE) + 16) + +Class QSGTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTexture::QPrivateSignal (0x0x7fc6678377e0) 0 empty + +Vtable for QSGTexture +QSGTexture::_ZTV10QSGTexture: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSGTexture) +16 (int (*)(...))QSGTexture::metaObject +24 (int (*)(...))QSGTexture::qt_metacast +32 (int (*)(...))QSGTexture::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QSGTexture::rhiTexture +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QSGTexture::normalizedTextureSubRect +160 (int (*)(...))QSGTexture::isAtlasTexture +168 (int (*)(...))QSGTexture::removedFromAtlas +176 (int (*)(...))QSGTexture::commitTextureOperations + +Class QSGTexture + size=16 align=8 + base size=16 base align=8 +QSGTexture (0x0x7fc667af7dd0) 0 + vptr=((& QSGTexture::_ZTV10QSGTexture) + 16) + QObject (0x0x7fc667837780) 0 + primary-for QSGTexture (0x0x7fc667af7dd0) + +Class QSGDynamicTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGDynamicTexture::QPrivateSignal (0x0x7fc667837a80) 0 empty + +Vtable for QSGDynamicTexture +QSGDynamicTexture::_ZTV17QSGDynamicTexture: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGDynamicTexture) +16 (int (*)(...))QSGDynamicTexture::metaObject +24 (int (*)(...))QSGDynamicTexture::qt_metacast +32 (int (*)(...))QSGDynamicTexture::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QSGTexture::rhiTexture +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QSGTexture::normalizedTextureSubRect +160 (int (*)(...))QSGTexture::isAtlasTexture +168 (int (*)(...))QSGTexture::removedFromAtlas +176 (int (*)(...))QSGTexture::commitTextureOperations +184 (int (*)(...))__cxa_pure_virtual + +Class QSGDynamicTexture + size=16 align=8 + base size=16 base align=8 +QSGDynamicTexture (0x0x7fc667af7e38) 0 + vptr=((& QSGDynamicTexture::_ZTV17QSGDynamicTexture) + 16) + QSGTexture (0x0x7fc667af7ea0) 0 + primary-for QSGDynamicTexture (0x0x7fc667af7e38) + QObject (0x0x7fc667837a20) 0 + primary-for QSGTexture (0x0x7fc667af7ea0) + +Vtable for QSGImageNode +QSGImageNode::_ZTV12QSGImageNode: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QSGImageNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QSGImageNode + size=136 align=8 + base size=136 base align=8 +QSGImageNode (0x0x7fc667af7f08) 0 + vptr=((& QSGImageNode::_ZTV12QSGImageNode) + 16) + QSGGeometryNode (0x0x7fc667af7f70) 0 + primary-for QSGImageNode (0x0x7fc667af7f08) + QSGBasicGeometryNode (0x0x7fc6678c2000) 0 + primary-for QSGGeometryNode (0x0x7fc667af7f70) + QSGNode (0x0x7fc667837b40) 0 + primary-for QSGBasicGeometryNode (0x0x7fc6678c2000) + +Vtable for QSGNinePatchNode +QSGNinePatchNode::_ZTV16QSGNinePatchNode: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGNinePatchNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual + +Class QSGNinePatchNode + size=136 align=8 + base size=136 base align=8 +QSGNinePatchNode (0x0x7fc6678c21a0) 0 + vptr=((& QSGNinePatchNode::_ZTV16QSGNinePatchNode) + 16) + QSGGeometryNode (0x0x7fc6678c2208) 0 + primary-for QSGNinePatchNode (0x0x7fc6678c21a0) + QSGBasicGeometryNode (0x0x7fc6678c2270) 0 + primary-for QSGGeometryNode (0x0x7fc6678c2208) + QSGNode (0x0x7fc667910060) 0 + primary-for QSGBasicGeometryNode (0x0x7fc6678c2270) + +Vtable for QSGRectangleNode +QSGRectangleNode::_ZTV16QSGRectangleNode: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGRectangleNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRectangleNode + size=136 align=8 + base size=136 base align=8 +QSGRectangleNode (0x0x7fc6678c22d8) 0 + vptr=((& QSGRectangleNode::_ZTV16QSGRectangleNode) + 16) + QSGGeometryNode (0x0x7fc6678c2340) 0 + primary-for QSGRectangleNode (0x0x7fc6678c22d8) + QSGBasicGeometryNode (0x0x7fc6678c23a8) 0 + primary-for QSGGeometryNode (0x0x7fc6678c2340) + QSGNode (0x0x7fc6679100c0) 0 + primary-for QSGBasicGeometryNode (0x0x7fc6678c23a8) + +Vtable for QSGRenderNode::RenderState +QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QSGRenderNode11RenderStateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))QSGRenderNode::RenderState::get + +Class QSGRenderNode::RenderState + size=8 align=8 + base size=8 base align=8 +QSGRenderNode::RenderState (0x0x7fc6679101e0) 0 nearly-empty + vptr=((& QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE) + 16) + +Vtable for QSGRenderNode +QSGRenderNode::_ZTV13QSGRenderNode: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSGRenderNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))QSGRenderNode::changedStates +56 (int (*)(...))QSGRenderNode::prepare +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))QSGRenderNode::releaseResources +80 (int (*)(...))QSGRenderNode::flags +88 (int (*)(...))QSGRenderNode::rect + +Class QSGRenderNode + size=80 align=8 + base size=80 base align=8 +QSGRenderNode (0x0x7fc6678c2410) 0 + vptr=((& QSGRenderNode::_ZTV13QSGRenderNode) + 16) + QSGNode (0x0x7fc667910180) 0 + primary-for QSGRenderNode (0x0x7fc6678c2410) + +Vtable for QSGSimpleRectNode +QSGSimpleRectNode::_ZTV17QSGSimpleRectNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGSimpleRectNode) +16 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +24 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleRectNode + size=312 align=8 + base size=312 base align=8 +QSGSimpleRectNode (0x0x7fc6678c26e8) 0 + vptr=((& QSGSimpleRectNode::_ZTV17QSGSimpleRectNode) + 16) + QSGGeometryNode (0x0x7fc6678c2750) 0 + primary-for QSGSimpleRectNode (0x0x7fc6678c26e8) + QSGBasicGeometryNode (0x0x7fc6678c27b8) 0 + primary-for QSGGeometryNode (0x0x7fc6678c2750) + QSGNode (0x0x7fc6679109c0) 0 + primary-for QSGBasicGeometryNode (0x0x7fc6678c27b8) + +Vtable for QSGOpaqueTextureMaterial +QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QSGOpaqueTextureMaterial) +16 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +24 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +32 (int (*)(...))QSGOpaqueTextureMaterial::type +40 (int (*)(...))QSGOpaqueTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGOpaqueTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGOpaqueTextureMaterial (0x0x7fc6678c2820) 0 + vptr=((& QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial) + 16) + QSGMaterial (0x0x7fc667910a80) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7fc6678c2820) + +Vtable for QSGTextureMaterial +QSGTextureMaterial::_ZTV18QSGTextureMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureMaterial) +16 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +24 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +32 (int (*)(...))QSGTextureMaterial::type +40 (int (*)(...))QSGTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGTextureMaterial (0x0x7fc6678c2888) 0 + vptr=((& QSGTextureMaterial::_ZTV18QSGTextureMaterial) + 16) + QSGOpaqueTextureMaterial (0x0x7fc6678c28f0) 0 + primary-for QSGTextureMaterial (0x0x7fc6678c2888) + QSGMaterial (0x0x7fc667910f00) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7fc6678c28f0) + +Vtable for QSGSimpleTextureNode +QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGSimpleTextureNode) +16 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +24 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleTextureNode + size=376 align=8 + base size=376 base align=8 +QSGSimpleTextureNode (0x0x7fc6678c2958) 0 + vptr=((& QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode) + 16) + QSGGeometryNode (0x0x7fc6678c29c0) 0 + primary-for QSGSimpleTextureNode (0x0x7fc6678c2958) + QSGBasicGeometryNode (0x0x7fc6678c2a28) 0 + primary-for QSGGeometryNode (0x0x7fc6678c29c0) + QSGNode (0x0x7fc667910f60) 0 + primary-for QSGBasicGeometryNode (0x0x7fc6678c2a28) + +Class QSGTextureProvider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTextureProvider::QPrivateSignal (0x0x7fc6675dc720) 0 empty + +Vtable for QSGTextureProvider +QSGTextureProvider::_ZTV18QSGTextureProvider: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureProvider) +16 (int (*)(...))QSGTextureProvider::metaObject +24 (int (*)(...))QSGTextureProvider::qt_metacast +32 (int (*)(...))QSGTextureProvider::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSGTextureProvider + size=16 align=8 + base size=16 base align=8 +QSGTextureProvider (0x0x7fc6678c2bc8) 0 + vptr=((& QSGTextureProvider::_ZTV18QSGTextureProvider) + 16) + QObject (0x0x7fc6675dc6c0) 0 + primary-for QSGTextureProvider (0x0x7fc6678c2bc8) + +Vtable for QSGVertexColorMaterial +QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QSGVertexColorMaterial) +16 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +24 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +32 (int (*)(...))QSGVertexColorMaterial::type +40 (int (*)(...))QSGVertexColorMaterial::createShader +48 (int (*)(...))QSGVertexColorMaterial::compare + +Class QSGVertexColorMaterial + size=24 align=8 + base size=24 base align=8 +QSGVertexColorMaterial (0x0x7fc6678c2c30) 0 + vptr=((& QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial) + 16) + QSGMaterial (0x0x7fc6675dc7e0) 0 + primary-for QSGVertexColorMaterial (0x0x7fc6678c2c30) + +Class QSizePolicy::Bits + size=4 align=4 + base size=4 base align=4 +QSizePolicy::Bits (0x0x7fc6675dc8a0) 0 + +Class QSizePolicy + size=4 align=4 + base size=4 base align=4 +QSizePolicy (0x0x7fc6675dc840) 0 + +Class QWidgetData + size=88 align=8 + base size=88 base align=8 +QWidgetData (0x0x7fc6676c8780) 0 + +Class QWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWidget::QPrivateSignal (0x0x7fc6676c88a0) 0 empty + +Vtable for QWidget +QWidget::_ZTV7QWidget: 64 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWidget) +16 (int (*)(...))QWidget::metaObject +24 (int (*)(...))QWidget::qt_metacast +32 (int (*)(...))QWidget::qt_metacall +40 (int (*)(...))QWidget::~QWidget +48 (int (*)(...))QWidget::~QWidget +56 (int (*)(...))QWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI7QWidget) +448 (int (*)(...))QWidget::_ZThn16_N7QWidgetD1Ev +456 (int (*)(...))QWidget::_ZThn16_N7QWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QWidget + size=40 align=8 + base size=40 base align=8 +QWidget (0x0x7fc667634e00) 0 + vptr=((& QWidget::_ZTV7QWidget) + 16) + QObject (0x0x7fc6676c87e0) 0 + primary-for QWidget (0x0x7fc667634e00) + QPaintDevice (0x0x7fc6676c8840) 16 + vptr=((& QWidget::_ZTV7QWidget) + 448) + +Class QAbstractButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractButton::QPrivateSignal (0x0x7fc6673da240) 0 empty + +Vtable for QAbstractButton +QAbstractButton::_ZTV15QAbstractButton: 67 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractButton) +16 (int (*)(...))QAbstractButton::metaObject +24 (int (*)(...))QAbstractButton::qt_metacast +32 (int (*)(...))QAbstractButton::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI15QAbstractButton) +472 0 +480 0 +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractButton + size=40 align=8 + base size=40 base align=8 +QAbstractButton (0x0x7fc6676c9a28) 0 + vptr=((& QAbstractButton::_ZTV15QAbstractButton) + 16) + QWidget (0x0x7fc667634c40) 0 + primary-for QAbstractButton (0x0x7fc6676c9a28) + QObject (0x0x7fc6673da180) 0 + primary-for QWidget (0x0x7fc667634c40) + QPaintDevice (0x0x7fc6673da1e0) 16 + vptr=((& QAbstractButton::_ZTV15QAbstractButton) + 472) + +Class QAbstractSpinBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSpinBox::QPrivateSignal (0x0x7fc6673da480) 0 empty + +Vtable for QAbstractSpinBox +QAbstractSpinBox::_ZTV16QAbstractSpinBox: 70 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAbstractSpinBox) +16 (int (*)(...))QAbstractSpinBox::metaObject +24 (int (*)(...))QAbstractSpinBox::qt_metacast +32 (int (*)(...))QAbstractSpinBox::qt_metacall +40 (int (*)(...))QAbstractSpinBox::~QAbstractSpinBox +48 (int (*)(...))QAbstractSpinBox::~QAbstractSpinBox +56 (int (*)(...))QAbstractSpinBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractSpinBox::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractSpinBox::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QAbstractSpinBox::wheelEvent +208 (int (*)(...))QAbstractSpinBox::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QAbstractSpinBox::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractSpinBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractSpinBox::validate +440 (int (*)(...))QAbstractSpinBox::fixup +448 (int (*)(...))QAbstractSpinBox::stepBy +456 (int (*)(...))QAbstractSpinBox::clear +464 (int (*)(...))QAbstractSpinBox::initStyleOption +472 (int (*)(...))QAbstractSpinBox::stepEnabled +480 (int (*)(...))-16 +488 (int (*)(...))(& _ZTI16QAbstractSpinBox) +496 (int (*)(...))QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD1Ev +504 (int (*)(...))QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD0Ev +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractSpinBox + size=40 align=8 + base size=40 base align=8 +QAbstractSpinBox (0x0x7fc6676c9a90) 0 + vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 16) + QWidget (0x0x7fc6673fd000) 0 + primary-for QAbstractSpinBox (0x0x7fc6676c9a90) + QObject (0x0x7fc6673da3c0) 0 + primary-for QWidget (0x0x7fc6673fd000) + QPaintDevice (0x0x7fc6673da420) 16 + vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 496) + +Class QAbstractSlider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSlider::QPrivateSignal (0x0x7fc6673dacc0) 0 empty + +Vtable for QAbstractSlider +QAbstractSlider::_ZTV15QAbstractSlider: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSlider) +16 (int (*)(...))QAbstractSlider::metaObject +24 (int (*)(...))QAbstractSlider::qt_metacast +32 (int (*)(...))QAbstractSlider::qt_metacall +40 (int (*)(...))QAbstractSlider::~QAbstractSlider +48 (int (*)(...))QAbstractSlider::~QAbstractSlider +56 (int (*)(...))QAbstractSlider::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QAbstractSlider::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractSlider::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI15QAbstractSlider) +456 (int (*)(...))QAbstractSlider::_ZThn16_N15QAbstractSliderD1Ev +464 (int (*)(...))QAbstractSlider::_ZThn16_N15QAbstractSliderD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractSlider + size=40 align=8 + base size=40 base align=8 +QAbstractSlider (0x0x7fc6676c9c30) 0 + vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 16) + QWidget (0x0x7fc6673fd4d0) 0 + primary-for QAbstractSlider (0x0x7fc6676c9c30) + QObject (0x0x7fc6673dac00) 0 + primary-for QWidget (0x0x7fc6673fd4d0) + QPaintDevice (0x0x7fc6673dac60) 16 + vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 456) + +Class QSlider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSlider::QPrivateSignal (0x0x7fc6673daf00) 0 empty + +Vtable for QSlider +QSlider::_ZTV7QSlider: 66 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QSlider) +16 (int (*)(...))QSlider::metaObject +24 (int (*)(...))QSlider::qt_metacast +32 (int (*)(...))QSlider::qt_metacall +40 (int (*)(...))QSlider::~QSlider +48 (int (*)(...))QSlider::~QSlider +56 (int (*)(...))QSlider::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QSlider::sizeHint +136 (int (*)(...))QSlider::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSlider::mousePressEvent +176 (int (*)(...))QSlider::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QSlider::mouseMoveEvent +200 (int (*)(...))QAbstractSlider::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QSlider::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractSlider::sliderChange +440 (int (*)(...))QSlider::initStyleOption +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI7QSlider) +464 (int (*)(...))QSlider::_ZThn16_N7QSliderD1Ev +472 (int (*)(...))QSlider::_ZThn16_N7QSliderD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSlider + size=40 align=8 + base size=40 base align=8 +QSlider (0x0x7fc6676c9c98) 0 + vptr=((& QSlider::_ZTV7QSlider) + 16) + QAbstractSlider (0x0x7fc6676c9d00) 0 + primary-for QSlider (0x0x7fc6676c9c98) + QWidget (0x0x7fc6673fda80) 0 + primary-for QAbstractSlider (0x0x7fc6676c9d00) + QObject (0x0x7fc6673dae40) 0 + primary-for QWidget (0x0x7fc6673fda80) + QPaintDevice (0x0x7fc6673daea0) 16 + vptr=((& QSlider::_ZTV7QSlider) + 464) + +Class QStyle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyle::QPrivateSignal (0x0x7fc6674961e0) 0 empty + +Vtable for QStyle +QStyle::_ZTV6QStyle: 37 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QStyle) +16 (int (*)(...))QStyle::metaObject +24 (int (*)(...))QStyle::qt_metacast +32 (int (*)(...))QStyle::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStyle::polish +120 (int (*)(...))QStyle::unpolish +128 (int (*)(...))QStyle::polish +136 (int (*)(...))QStyle::unpolish +144 (int (*)(...))QStyle::polish +152 (int (*)(...))QStyle::itemTextRect +160 (int (*)(...))QStyle::itemPixmapRect +168 (int (*)(...))QStyle::drawItemText +176 (int (*)(...))QStyle::drawItemPixmap +184 (int (*)(...))QStyle::standardPalette +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))__cxa_pure_virtual +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))__cxa_pure_virtual +232 (int (*)(...))__cxa_pure_virtual +240 (int (*)(...))__cxa_pure_virtual +248 (int (*)(...))__cxa_pure_virtual +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))__cxa_pure_virtual +272 (int (*)(...))__cxa_pure_virtual +280 (int (*)(...))__cxa_pure_virtual +288 (int (*)(...))__cxa_pure_virtual + +Class QStyle + size=16 align=8 + base size=16 base align=8 +QStyle (0x0x7fc6676c9d68) 0 + vptr=((& QStyle::_ZTV6QStyle) + 16) + QObject (0x0x7fc667496180) 0 + primary-for QStyle (0x0x7fc6676c9d68) + +Class QTabBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTabBar::QPrivateSignal (0x0x7fc66753c420) 0 empty + +Vtable for QTabBar +QTabBar::_ZTV7QTabBar: 70 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QTabBar) +16 (int (*)(...))QTabBar::metaObject +24 (int (*)(...))QTabBar::qt_metacast +32 (int (*)(...))QTabBar::qt_metacall +40 (int (*)(...))QTabBar::~QTabBar +48 (int (*)(...))QTabBar::~QTabBar +56 (int (*)(...))QTabBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTabBar::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QTabBar::sizeHint +136 (int (*)(...))QTabBar::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTabBar::mousePressEvent +176 (int (*)(...))QTabBar::mouseReleaseEvent +184 (int (*)(...))QTabBar::mouseDoubleClickEvent +192 (int (*)(...))QTabBar::mouseMoveEvent +200 (int (*)(...))QTabBar::wheelEvent +208 (int (*)(...))QTabBar::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTabBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTabBar::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QTabBar::showEvent +352 (int (*)(...))QTabBar::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTabBar::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QTabBar::tabSizeHint +440 (int (*)(...))QTabBar::minimumTabSizeHint +448 (int (*)(...))QTabBar::tabInserted +456 (int (*)(...))QTabBar::tabRemoved +464 (int (*)(...))QTabBar::tabLayoutChange +472 (int (*)(...))QTabBar::initStyleOption +480 (int (*)(...))-16 +488 (int (*)(...))(& _ZTI7QTabBar) +496 (int (*)(...))QTabBar::_ZThn16_N7QTabBarD1Ev +504 (int (*)(...))QTabBar::_ZThn16_N7QTabBarD0Ev +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTabBar + size=40 align=8 + base size=40 base align=8 +QTabBar (0x0x7fc66753e068) 0 + vptr=((& QTabBar::_ZTV7QTabBar) + 16) + QWidget (0x0x7fc6674d4620) 0 + primary-for QTabBar (0x0x7fc66753e068) + QObject (0x0x7fc66753c360) 0 + primary-for QWidget (0x0x7fc6674d4620) + QPaintDevice (0x0x7fc66753c3c0) 16 + vptr=((& QTabBar::_ZTV7QTabBar) + 496) + +Class QTabWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTabWidget::QPrivateSignal (0x0x7fc66753c720) 0 empty + +Vtable for QTabWidget +QTabWidget::_ZTV10QTabWidget: 67 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTabWidget) +16 (int (*)(...))QTabWidget::metaObject +24 (int (*)(...))QTabWidget::qt_metacast +32 (int (*)(...))QTabWidget::qt_metacall +40 (int (*)(...))QTabWidget::~QTabWidget +48 (int (*)(...))QTabWidget::~QTabWidget +56 (int (*)(...))QTabWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QTabWidget::sizeHint +136 (int (*)(...))QTabWidget::minimumSizeHint +144 (int (*)(...))QTabWidget::heightForWidth +152 (int (*)(...))QTabWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QTabWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTabWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTabWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QTabWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTabWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QTabWidget::tabInserted +440 (int (*)(...))QTabWidget::tabRemoved +448 (int (*)(...))QTabWidget::initStyleOption +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI10QTabWidget) +472 (int (*)(...))QTabWidget::_ZThn16_N10QTabWidgetD1Ev +480 (int (*)(...))QTabWidget::_ZThn16_N10QTabWidgetD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTabWidget + size=40 align=8 + base size=40 base align=8 +QTabWidget (0x0x7fc66753e0d0) 0 + vptr=((& QTabWidget::_ZTV10QTabWidget) + 16) + QWidget (0x0x7fc6674d4c40) 0 + primary-for QTabWidget (0x0x7fc66753e0d0) + QObject (0x0x7fc66753c660) 0 + primary-for QWidget (0x0x7fc6674d4c40) + QPaintDevice (0x0x7fc66753c6c0) 16 + vptr=((& QTabWidget::_ZTV10QTabWidget) + 472) + +Class QRubberBand::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRubberBand::QPrivateSignal (0x0x7fc66753cae0) 0 empty + +Vtable for QRubberBand +QRubberBand::_ZTV11QRubberBand: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QRubberBand) +16 (int (*)(...))QRubberBand::metaObject +24 (int (*)(...))QRubberBand::qt_metacast +32 (int (*)(...))QRubberBand::qt_metacall +40 (int (*)(...))QRubberBand::~QRubberBand +48 (int (*)(...))QRubberBand::~QRubberBand +56 (int (*)(...))QRubberBand::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QRubberBand::paintEvent +264 (int (*)(...))QRubberBand::moveEvent +272 (int (*)(...))QRubberBand::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QRubberBand::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QRubberBand::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QRubberBand::initStyleOption +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI11QRubberBand) +456 (int (*)(...))QRubberBand::_ZThn16_N11QRubberBandD1Ev +464 (int (*)(...))QRubberBand::_ZThn16_N11QRubberBandD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QRubberBand + size=40 align=8 + base size=40 base align=8 +QRubberBand (0x0x7fc66753e138) 0 + vptr=((& QRubberBand::_ZTV11QRubberBand) + 16) + QWidget (0x0x7fc6674d4f50) 0 + primary-for QRubberBand (0x0x7fc66753e138) + QObject (0x0x7fc66753ca20) 0 + primary-for QWidget (0x0x7fc6674d4f50) + QPaintDevice (0x0x7fc66753ca80) 16 + vptr=((& QRubberBand::_ZTV11QRubberBand) + 456) + +Class QFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFrame::QPrivateSignal (0x0x7fc66753cf00) 0 empty + +Vtable for QFrame +QFrame::_ZTV6QFrame: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QFrame) +16 (int (*)(...))QFrame::metaObject +24 (int (*)(...))QFrame::qt_metacast +32 (int (*)(...))QFrame::qt_metacall +40 (int (*)(...))QFrame::~QFrame +48 (int (*)(...))QFrame::~QFrame +56 (int (*)(...))QFrame::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFrame::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI6QFrame) +456 (int (*)(...))QFrame::_ZThn16_N6QFrameD1Ev +464 (int (*)(...))QFrame::_ZThn16_N6QFrameD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFrame + size=40 align=8 + base size=40 base align=8 +QFrame (0x0x7fc66753e1a0) 0 + vptr=((& QFrame::_ZTV6QFrame) + 16) + QWidget (0x0x7fc6671d50e0) 0 + primary-for QFrame (0x0x7fc66753e1a0) + QObject (0x0x7fc66753ce40) 0 + primary-for QWidget (0x0x7fc6671d50e0) + QPaintDevice (0x0x7fc66753cea0) 16 + vptr=((& QFrame::_ZTV6QFrame) + 456) + +Class QStyleOption + size=64 align=8 + base size=64 base align=8 +QStyleOption (0x0x7fc667200240) 0 + +Class QStyleOptionFocusRect + size=80 align=8 + base size=80 base align=8 +QStyleOptionFocusRect (0x0x7fc66753e208) 0 + QStyleOption (0x0x7fc6672002a0) 0 + +Class QStyleOptionFrame + size=80 align=8 + base size=80 base align=8 +QStyleOptionFrame (0x0x7fc6762f98f0) 0 + QStyleOption (0x0x7fc6672004e0) 0 + +Class QStyleOptionTabWidgetFrame + size=136 align=8 + base size=132 base align=8 +QStyleOptionTabWidgetFrame (0x0x7fc6762f9af8) 0 + QStyleOption (0x0x7fc667200ae0) 0 + +Class QStyleOptionTabBarBase + size=104 align=8 + base size=101 base align=8 +QStyleOptionTabBarBase (0x0x7fc66753e270) 0 + QStyleOption (0x0x7fc667200d20) 0 + +Class QStyleOptionHeader + size=136 align=8 + base size=132 base align=8 +QStyleOptionHeader (0x0x7fc66753e2d8) 0 + QStyleOption (0x0x7fc667200f60) 0 + +Class QStyleOptionHeaderV2 + size=136 align=8 + base size=136 base align=8 +QStyleOptionHeaderV2 (0x0x7fc66753e340) 0 + QStyleOptionHeader (0x0x7fc66753e3a8) 0 + QStyleOption (0x0x7fc6672911e0) 0 + +Class QStyleOptionButton + size=112 align=8 + base size=112 base align=8 +QStyleOptionButton (0x0x7fc66753e478) 0 + QStyleOption (0x0x7fc6672915a0) 0 + +Class QStyleOptionTab + size=160 align=8 + base size=156 base align=8 +QStyleOptionTab (0x0x7fc66753e618) 0 + QStyleOption (0x0x7fc667291ba0) 0 + +Class QStyleOptionToolBar + size=88 align=8 + base size=88 base align=8 +QStyleOptionToolBar (0x0x7fc66753e8f0) 0 + QStyleOption (0x0x7fc6673393c0) 0 + +Class QStyleOptionProgressBar + size=112 align=8 + base size=111 base align=8 +QStyleOptionProgressBar (0x0x7fc66753ea90) 0 + QStyleOption (0x0x7fc6673399c0) 0 + +Class QStyleOptionMenuItem + size=152 align=8 + base size=152 base align=8 +QStyleOptionMenuItem (0x0x7fc66753eaf8) 0 + QStyleOption (0x0x7fc667339c00) 0 + +Class QStyleOptionDockWidget + size=96 align=8 + base size=92 base align=8 +QStyleOptionDockWidget (0x0x7fc66753eb60) 0 + QStyleOption (0x0x7fc667339e40) 0 + +Class QStyleOptionViewItem + size=208 align=8 + base size=208 base align=8 +QStyleOptionViewItem (0x0x7fc66753ebc8) 0 + QStyleOption (0x0x7fc666feb0c0) 0 + +Class QStyleOptionToolBox + size=104 align=8 + base size=104 base align=8 +QStyleOptionToolBox (0x0x7fc66753ed68) 0 + QStyleOption (0x0x7fc666feb6c0) 0 + +Class QStyleOptionRubberBand + size=72 align=8 + base size=69 base align=8 +QStyleOptionRubberBand (0x0x7fc66753edd0) 0 + QStyleOption (0x0x7fc666feb900) 0 + +Class QStyleOptionComplex + size=72 align=8 + base size=72 base align=8 +QStyleOptionComplex (0x0x7fc66753ee38) 0 + QStyleOption (0x0x7fc666febba0) 0 + +Class QStyleOptionSlider + size=128 align=8 + base size=128 base align=8 +QStyleOptionSlider (0x0x7fc66753eea0) 0 + QStyleOptionComplex (0x0x7fc66753ef08) 0 + QStyleOption (0x0x7fc666febe40) 0 + +Class QStyleOptionSpinBox + size=88 align=8 + base size=81 base align=8 +QStyleOptionSpinBox (0x0x7fc66753ef70) 0 + QStyleOptionComplex (0x0x7fc66707c000) 0 + QStyleOption (0x0x7fc6670781e0) 0 + +Class QStyleOptionToolButton + size=152 align=8 + base size=152 base align=8 +QStyleOptionToolButton (0x0x7fc66707c0d0) 0 + QStyleOptionComplex (0x0x7fc66707c138) 0 + QStyleOption (0x0x7fc667078420) 0 + +Class QStyleOptionComboBox + size=144 align=8 + base size=140 base align=8 +QStyleOptionComboBox (0x0x7fc66707c2d8) 0 + QStyleOptionComplex (0x0x7fc66707c340) 0 + QStyleOption (0x0x7fc667078a20) 0 + +Class QStyleOptionTitleBar + size=112 align=8 + base size=112 base align=8 +QStyleOptionTitleBar (0x0x7fc66707c3a8) 0 + QStyleOptionComplex (0x0x7fc66707c410) 0 + QStyleOption (0x0x7fc667078c60) 0 + +Class QStyleOptionGroupBox + size=136 align=8 + base size=132 base align=8 +QStyleOptionGroupBox (0x0x7fc66707c478) 0 + QStyleOptionComplex (0x0x7fc66707c4e0) 0 + QStyleOption (0x0x7fc667078ea0) 0 + +Class QStyleOptionSizeGrip + size=80 align=8 + base size=76 base align=8 +QStyleOptionSizeGrip (0x0x7fc66707c548) 0 + QStyleOptionComplex (0x0x7fc66707c5b0) 0 + QStyleOption (0x0x7fc667102120) 0 + +Class QStyleOptionGraphicsItem + size=96 align=8 + base size=96 base align=8 +QStyleOptionGraphicsItem (0x0x7fc66707c618) 0 + QStyleOption (0x0x7fc667102360) 0 + +Class QStyleHintReturn + size=8 align=4 + base size=8 base align=4 +QStyleHintReturn (0x0x7fc6671026c0) 0 + +Class QStyleHintReturnMask + size=16 align=8 + base size=16 base align=8 +QStyleHintReturnMask (0x0x7fc66707c680) 0 + QStyleHintReturn (0x0x7fc667102720) 0 + +Class QStyleHintReturnVariant + size=40 align=8 + base size=40 base align=8 +QStyleHintReturnVariant (0x0x7fc66707c750) 0 + QStyleHintReturn (0x0x7fc667102780) 0 + +Class QAbstractItemDelegate::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemDelegate::QPrivateSignal (0x0x7fc667102900) 0 empty + +Vtable for QAbstractItemDelegate +QAbstractItemDelegate::_ZTV21QAbstractItemDelegate: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractItemDelegate) +16 (int (*)(...))QAbstractItemDelegate::metaObject +24 (int (*)(...))QAbstractItemDelegate::qt_metacast +32 (int (*)(...))QAbstractItemDelegate::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemDelegate::createEditor +136 (int (*)(...))QAbstractItemDelegate::destroyEditor +144 (int (*)(...))QAbstractItemDelegate::setEditorData +152 (int (*)(...))QAbstractItemDelegate::setModelData +160 (int (*)(...))QAbstractItemDelegate::updateEditorGeometry +168 (int (*)(...))QAbstractItemDelegate::editorEvent +176 (int (*)(...))QAbstractItemDelegate::helpEvent +184 (int (*)(...))QAbstractItemDelegate::paintingRoles + +Class QAbstractItemDelegate + size=16 align=8 + base size=16 base align=8 +QAbstractItemDelegate (0x0x7fc66707c820) 0 + vptr=((& QAbstractItemDelegate::_ZTV21QAbstractItemDelegate) + 16) + QObject (0x0x7fc6671028a0) 0 + primary-for QAbstractItemDelegate (0x0x7fc66707c820) + +Class QAbstractScrollArea::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractScrollArea::QPrivateSignal (0x0x7fc667102b40) 0 empty + +Vtable for QAbstractScrollArea +QAbstractScrollArea::_ZTV19QAbstractScrollArea: 69 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractScrollArea) +16 (int (*)(...))QAbstractScrollArea::metaObject +24 (int (*)(...))QAbstractScrollArea::qt_metacast +32 (int (*)(...))QAbstractScrollArea::qt_metacall +40 (int (*)(...))QAbstractScrollArea::~QAbstractScrollArea +48 (int (*)(...))QAbstractScrollArea::~QAbstractScrollArea +56 (int (*)(...))QAbstractScrollArea::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractScrollArea::mousePressEvent +176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent +184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent +192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractScrollArea::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractScrollArea::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractScrollArea::dragEnterEvent +320 (int (*)(...))QAbstractScrollArea::dragMoveEvent +328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent +336 (int (*)(...))QAbstractScrollArea::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QAbstractScrollArea::viewportEvent +456 (int (*)(...))QAbstractScrollArea::scrollContentsBy +464 (int (*)(...))QAbstractScrollArea::viewportSizeHint +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI19QAbstractScrollArea) +488 (int (*)(...))QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD1Ev +496 (int (*)(...))QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractScrollArea + size=40 align=8 + base size=40 base align=8 +QAbstractScrollArea (0x0x7fc66707c888) 0 + vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 16) + QFrame (0x0x7fc66707c8f0) 0 + primary-for QAbstractScrollArea (0x0x7fc66707c888) + QWidget (0x0x7fc66711d3f0) 0 + primary-for QFrame (0x0x7fc66707c8f0) + QObject (0x0x7fc667102a80) 0 + primary-for QWidget (0x0x7fc66711d3f0) + QPaintDevice (0x0x7fc667102ae0) 16 + vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 488) + +Class QAbstractItemView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemView::QPrivateSignal (0x0x7fc667102e40) 0 empty + +Vtable for QAbstractItemView +QAbstractItemView::_ZTV17QAbstractItemView: 108 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractItemView) +16 (int (*)(...))QAbstractItemView::metaObject +24 (int (*)(...))QAbstractItemView::qt_metacast +32 (int (*)(...))QAbstractItemView::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QAbstractItemView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QAbstractItemView::viewportEvent +456 (int (*)(...))QAbstractScrollArea::scrollContentsBy +464 (int (*)(...))QAbstractItemView::viewportSizeHint +472 (int (*)(...))QAbstractItemView::setModel +480 (int (*)(...))QAbstractItemView::setSelectionModel +488 (int (*)(...))QAbstractItemView::keyboardSearch +496 (int (*)(...))__cxa_pure_virtual +504 (int (*)(...))__cxa_pure_virtual +512 (int (*)(...))__cxa_pure_virtual +520 (int (*)(...))QAbstractItemView::sizeHintForRow +528 (int (*)(...))QAbstractItemView::sizeHintForColumn +536 (int (*)(...))QAbstractItemView::itemDelegateForIndex +544 (int (*)(...))QAbstractItemView::reset +552 (int (*)(...))QAbstractItemView::setRootIndex +560 (int (*)(...))QAbstractItemView::doItemsLayout +568 (int (*)(...))QAbstractItemView::selectAll +576 (int (*)(...))QAbstractItemView::dataChanged +584 (int (*)(...))QAbstractItemView::rowsInserted +592 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +600 (int (*)(...))QAbstractItemView::selectionChanged +608 (int (*)(...))QAbstractItemView::currentChanged +616 (int (*)(...))QAbstractItemView::updateEditorData +624 (int (*)(...))QAbstractItemView::updateEditorGeometries +632 (int (*)(...))QAbstractItemView::updateGeometries +640 (int (*)(...))QAbstractItemView::verticalScrollbarAction +648 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +656 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +664 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +672 (int (*)(...))QAbstractItemView::closeEditor +680 (int (*)(...))QAbstractItemView::commitData +688 (int (*)(...))QAbstractItemView::editorDestroyed +696 (int (*)(...))__cxa_pure_virtual +704 (int (*)(...))__cxa_pure_virtual +712 (int (*)(...))__cxa_pure_virtual +720 (int (*)(...))__cxa_pure_virtual +728 (int (*)(...))__cxa_pure_virtual +736 (int (*)(...))__cxa_pure_virtual +744 (int (*)(...))QAbstractItemView::selectedIndexes +752 (int (*)(...))QAbstractItemView::edit +760 (int (*)(...))QAbstractItemView::selectionCommand +768 (int (*)(...))QAbstractItemView::startDrag +776 (int (*)(...))QAbstractItemView::initViewItemOption +784 (int (*)(...))-16 +792 (int (*)(...))(& _ZTI17QAbstractItemView) +800 0 +808 0 +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractItemView + size=40 align=8 + base size=40 base align=8 +QAbstractItemView (0x0x7fc66707c958) 0 + vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 16) + QAbstractScrollArea (0x0x7fc66707c9c0) 0 + primary-for QAbstractItemView (0x0x7fc66707c958) + QFrame (0x0x7fc66707ca28) 0 + primary-for QAbstractScrollArea (0x0x7fc66707c9c0) + QWidget (0x0x7fc66711d5b0) 0 + primary-for QFrame (0x0x7fc66707ca28) + QObject (0x0x7fc667102d80) 0 + primary-for QWidget (0x0x7fc66711d5b0) + QPaintDevice (0x0x7fc667102de0) 16 + vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 800) + +Vtable for QAccessibleWidget +QAccessibleWidget::_ZTV17QAccessibleWidget: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleWidget) +16 (int (*)(...))QAccessibleWidget::~QAccessibleWidget +24 (int (*)(...))QAccessibleWidget::~QAccessibleWidget +32 (int (*)(...))QAccessibleWidget::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleWidget::window +56 (int (*)(...))QAccessibleWidget::relations +64 (int (*)(...))QAccessibleWidget::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleWidget::parent +88 (int (*)(...))QAccessibleWidget::child +96 (int (*)(...))QAccessibleWidget::childCount +104 (int (*)(...))QAccessibleWidget::indexOfChild +112 (int (*)(...))QAccessibleWidget::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleWidget::rect +136 (int (*)(...))QAccessibleWidget::role +144 (int (*)(...))QAccessibleWidget::state +152 (int (*)(...))QAccessibleWidget::foregroundColor +160 (int (*)(...))QAccessibleWidget::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleWidget::interface_cast +184 (int (*)(...))QAccessibleWidget::actionNames +192 (int (*)(...))QAccessibleWidget::doAction +200 (int (*)(...))QAccessibleWidget::keyBindingsForAction +208 (int (*)(...))-16 +216 (int (*)(...))(& _ZTI17QAccessibleWidget) +224 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidgetD1Ev +232 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidgetD0Ev +240 (int (*)(...))QAccessibleWidget::_ZThn16_NK17QAccessibleWidget11actionNamesEv +248 (int (*)(...))QAccessibleActionInterface::localizedActionName +256 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +264 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidget8doActionERK7QString +272 (int (*)(...))QAccessibleWidget::_ZThn16_NK17QAccessibleWidget20keyBindingsForActionERK7QString + +Class QAccessibleWidget + size=32 align=8 + base size=32 base align=8 +QAccessibleWidget (0x0x7fc66716aaf0) 0 + vptr=((& QAccessibleWidget::_ZTV17QAccessibleWidget) + 16) + QAccessibleObject (0x0x7fc66707cbc8) 0 + primary-for QAccessibleWidget (0x0x7fc66716aaf0) + QAccessibleInterface (0x0x7fc6671968a0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7fc66707cbc8) + QAccessibleActionInterface (0x0x7fc667196900) 16 nearly-empty + vptr=((& QAccessibleWidget::_ZTV17QAccessibleWidget) + 224) + +Class QApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QApplication::QPrivateSignal (0x0x7fc667196a20) 0 empty + +Vtable for QApplication +QApplication::_ZTV12QApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QApplication) +16 (int (*)(...))QApplication::metaObject +24 (int (*)(...))QApplication::qt_metacast +32 (int (*)(...))QApplication::qt_metacall +40 (int (*)(...))QApplication::~QApplication +48 (int (*)(...))QApplication::~QApplication +56 (int (*)(...))QApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QApplication::notify +120 (int (*)(...))QApplication::compressEvent + +Class QApplication + size=16 align=8 + base size=16 base align=8 +QApplication (0x0x7fc66707cc30) 0 + vptr=((& QApplication::_ZTV12QApplication) + 16) + QGuiApplication (0x0x7fc66707cc98) 0 + primary-for QApplication (0x0x7fc66707cc30) + QCoreApplication (0x0x7fc66707cd00) 0 + primary-for QGuiApplication (0x0x7fc66707cc98) + QObject (0x0x7fc6671969c0) 0 + primary-for QCoreApplication (0x0x7fc66707cd00) + +Vtable for QLayoutItem +QLayoutItem::_ZTV11QLayoutItem: 19 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QLayoutItem) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QLayoutItem::hasHeightForWidth +96 (int (*)(...))QLayoutItem::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QLayoutItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QLayoutItem::spacerItem +144 (int (*)(...))QLayoutItem::controlTypes + +Class QLayoutItem + size=16 align=8 + base size=12 base align=8 +QLayoutItem (0x0x7fc667196cc0) 0 + vptr=((& QLayoutItem::_ZTV11QLayoutItem) + 16) + +Vtable for QSpacerItem +QSpacerItem::_ZTV11QSpacerItem: 19 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSpacerItem) +16 (int (*)(...))QSpacerItem::~QSpacerItem +24 (int (*)(...))QSpacerItem::~QSpacerItem +32 (int (*)(...))QSpacerItem::sizeHint +40 (int (*)(...))QSpacerItem::minimumSize +48 (int (*)(...))QSpacerItem::maximumSize +56 (int (*)(...))QSpacerItem::expandingDirections +64 (int (*)(...))QSpacerItem::setGeometry +72 (int (*)(...))QSpacerItem::geometry +80 (int (*)(...))QSpacerItem::isEmpty +88 (int (*)(...))QLayoutItem::hasHeightForWidth +96 (int (*)(...))QLayoutItem::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QLayoutItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QSpacerItem::spacerItem +144 (int (*)(...))QLayoutItem::controlTypes + +Class QSpacerItem + size=40 align=8 + base size=40 base align=8 +QSpacerItem (0x0x7fc66707cd68) 0 + vptr=((& QSpacerItem::_ZTV11QSpacerItem) + 16) + QLayoutItem (0x0x7fc667196f00) 0 + primary-for QSpacerItem (0x0x7fc66707cd68) + +Vtable for QWidgetItem +QWidgetItem::_ZTV11QWidgetItem: 19 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWidgetItem) +16 (int (*)(...))QWidgetItem::~QWidgetItem +24 (int (*)(...))QWidgetItem::~QWidgetItem +32 (int (*)(...))QWidgetItem::sizeHint +40 (int (*)(...))QWidgetItem::minimumSize +48 (int (*)(...))QWidgetItem::maximumSize +56 (int (*)(...))QWidgetItem::expandingDirections +64 (int (*)(...))QWidgetItem::setGeometry +72 (int (*)(...))QWidgetItem::geometry +80 (int (*)(...))QWidgetItem::isEmpty +88 (int (*)(...))QWidgetItem::hasHeightForWidth +96 (int (*)(...))QWidgetItem::heightForWidth +104 (int (*)(...))QWidgetItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QWidgetItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QLayoutItem::spacerItem +144 (int (*)(...))QWidgetItem::controlTypes + +Class QWidgetItem + size=24 align=8 + base size=24 base align=8 +QWidgetItem (0x0x7fc66707cdd0) 0 + vptr=((& QWidgetItem::_ZTV11QWidgetItem) + 16) + QLayoutItem (0x0x7fc666e28180) 0 + primary-for QWidgetItem (0x0x7fc66707cdd0) + +Vtable for QWidgetItemV2 +QWidgetItemV2::_ZTV13QWidgetItemV2: 19 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QWidgetItemV2) +16 (int (*)(...))QWidgetItemV2::~QWidgetItemV2 +24 (int (*)(...))QWidgetItemV2::~QWidgetItemV2 +32 (int (*)(...))QWidgetItemV2::sizeHint +40 (int (*)(...))QWidgetItemV2::minimumSize +48 (int (*)(...))QWidgetItemV2::maximumSize +56 (int (*)(...))QWidgetItem::expandingDirections +64 (int (*)(...))QWidgetItem::setGeometry +72 (int (*)(...))QWidgetItem::geometry +80 (int (*)(...))QWidgetItem::isEmpty +88 (int (*)(...))QWidgetItem::hasHeightForWidth +96 (int (*)(...))QWidgetItemV2::heightForWidth +104 (int (*)(...))QWidgetItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QWidgetItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QLayoutItem::spacerItem +144 (int (*)(...))QWidgetItem::controlTypes + +Class QWidgetItemV2 + size=88 align=8 + base size=88 base align=8 +QWidgetItemV2 (0x0x7fc66707ce38) 0 + vptr=((& QWidgetItemV2::_ZTV13QWidgetItemV2) + 16) + QWidgetItem (0x0x7fc66707cea0) 0 + primary-for QWidgetItemV2 (0x0x7fc66707ce38) + QLayoutItem (0x0x7fc666e28360) 0 + primary-for QWidgetItem (0x0x7fc66707cea0) + +Class QLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLayout::QPrivateSignal (0x0x7fc666e284e0) 0 empty + +Vtable for QLayout +QLayout::_ZTV7QLayout: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QLayout) +16 (int (*)(...))QLayout::metaObject +24 (int (*)(...))QLayout::qt_metacast +32 (int (*)(...))QLayout::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLayout::spacing +120 (int (*)(...))QLayout::setSpacing +128 (int (*)(...))QLayout::invalidate +136 (int (*)(...))QLayout::geometry +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QLayout::expandingDirections +160 (int (*)(...))QLayout::minimumSize +168 (int (*)(...))QLayout::maximumSize +176 (int (*)(...))QLayout::setGeometry +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))QLayout::indexOf +208 (int (*)(...))QLayout::indexOf +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QLayout::isEmpty +232 (int (*)(...))QLayout::controlTypes +240 (int (*)(...))QLayout::replaceWidget +248 (int (*)(...))QLayout::layout +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI7QLayout) +272 0 +280 0 +288 (int (*)(...))__cxa_pure_virtual +296 (int (*)(...))QLayout::_ZThn16_NK7QLayout11minimumSizeEv +304 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv +312 (int (*)(...))QLayout::_ZThn16_NK7QLayout19expandingDirectionsEv +320 (int (*)(...))QLayout::_ZThn16_N7QLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QLayoutItem::hasHeightForWidth +352 (int (*)(...))QLayoutItem::heightForWidth +360 (int (*)(...))QLayoutItem::minimumHeightForWidth +368 (int (*)(...))QLayout::_ZThn16_N7QLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QLayout + size=32 align=8 + base size=28 base align=8 +QLayout (0x0x7fc66716acb0) 0 + vptr=((& QLayout::_ZTV7QLayout) + 16) + QObject (0x0x7fc666e28420) 0 + primary-for QLayout (0x0x7fc66716acb0) + QLayoutItem (0x0x7fc666e28480) 16 + vptr=((& QLayout::_ZTV7QLayout) + 272) + +Class QGridLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGridLayout::QPrivateSignal (0x0x7fc666e287e0) 0 empty + +Vtable for QGridLayout +QGridLayout::_ZTV11QGridLayout: 55 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QGridLayout) +16 (int (*)(...))QGridLayout::metaObject +24 (int (*)(...))QGridLayout::qt_metacast +32 (int (*)(...))QGridLayout::qt_metacall +40 (int (*)(...))QGridLayout::~QGridLayout +48 (int (*)(...))QGridLayout::~QGridLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGridLayout::spacing +120 (int (*)(...))QGridLayout::setSpacing +128 (int (*)(...))QGridLayout::invalidate +136 (int (*)(...))QLayout::geometry +144 (int (*)(...))QGridLayout::addItem +152 (int (*)(...))QGridLayout::expandingDirections +160 (int (*)(...))QGridLayout::minimumSize +168 (int (*)(...))QGridLayout::maximumSize +176 (int (*)(...))QGridLayout::setGeometry +184 (int (*)(...))QGridLayout::itemAt +192 (int (*)(...))QGridLayout::takeAt +200 (int (*)(...))QLayout::indexOf +208 (int (*)(...))QLayout::indexOf +216 (int (*)(...))QGridLayout::count +224 (int (*)(...))QLayout::isEmpty +232 (int (*)(...))QLayout::controlTypes +240 (int (*)(...))QLayout::replaceWidget +248 (int (*)(...))QLayout::layout +256 (int (*)(...))QGridLayout::sizeHint +264 (int (*)(...))QGridLayout::hasHeightForWidth +272 (int (*)(...))QGridLayout::heightForWidth +280 (int (*)(...))QGridLayout::minimumHeightForWidth +288 (int (*)(...))-16 +296 (int (*)(...))(& _ZTI11QGridLayout) +304 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayoutD1Ev +312 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayoutD0Ev +320 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout8sizeHintEv +328 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout11minimumSizeEv +336 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout11maximumSizeEv +344 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout19expandingDirectionsEv +352 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayout11setGeometryERK5QRect +360 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +368 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +376 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout17hasHeightForWidthEv +384 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout14heightForWidthEi +392 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout21minimumHeightForWidthEi +400 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayout10invalidateEv +408 (int (*)(...))QLayoutItem::widget +416 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +424 (int (*)(...))QLayoutItem::spacerItem +432 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QGridLayout + size=32 align=8 + base size=28 base align=8 +QGridLayout (0x0x7fc66707cf08) 0 + vptr=((& QGridLayout::_ZTV11QGridLayout) + 16) + QLayout (0x0x7fc666e60000) 0 + primary-for QGridLayout (0x0x7fc66707cf08) + QObject (0x0x7fc666e28720) 0 + primary-for QLayout (0x0x7fc666e60000) + QLayoutItem (0x0x7fc666e28780) 16 + vptr=((& QGridLayout::_ZTV11QGridLayout) + 304) + +Class QBoxLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBoxLayout::QPrivateSignal (0x0x7fc666e28a80) 0 empty + +Vtable for QBoxLayout +QBoxLayout::_ZTV10QBoxLayout: 55 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QBoxLayout) +16 (int (*)(...))QBoxLayout::metaObject +24 (int (*)(...))QBoxLayout::qt_metacast +32 (int (*)(...))QBoxLayout::qt_metacall +40 (int (*)(...))QBoxLayout::~QBoxLayout +48 (int (*)(...))QBoxLayout::~QBoxLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QBoxLayout::spacing +120 (int (*)(...))QBoxLayout::setSpacing +128 (int (*)(...))QBoxLayout::invalidate +136 (int (*)(...))QLayout::geometry +144 (int (*)(...))QBoxLayout::addItem +152 (int (*)(...))QBoxLayout::expandingDirections +160 (int (*)(...))QBoxLayout::minimumSize +168 (int (*)(...))QBoxLayout::maximumSize +176 (int (*)(...))QBoxLayout::setGeometry +184 (int (*)(...))QBoxLayout::itemAt +192 (int (*)(...))QBoxLayout::takeAt +200 (int (*)(...))QLayout::indexOf +208 (int (*)(...))QLayout::indexOf +216 (int (*)(...))QBoxLayout::count +224 (int (*)(...))QLayout::isEmpty +232 (int (*)(...))QLayout::controlTypes +240 (int (*)(...))QLayout::replaceWidget +248 (int (*)(...))QLayout::layout +256 (int (*)(...))QBoxLayout::sizeHint +264 (int (*)(...))QBoxLayout::hasHeightForWidth +272 (int (*)(...))QBoxLayout::heightForWidth +280 (int (*)(...))QBoxLayout::minimumHeightForWidth +288 (int (*)(...))-16 +296 (int (*)(...))(& _ZTI10QBoxLayout) +304 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayoutD1Ev +312 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayoutD0Ev +320 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv +328 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv +336 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv +344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv +352 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect +360 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +368 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +376 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv +384 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi +392 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi +400 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv +408 (int (*)(...))QLayoutItem::widget +416 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +424 (int (*)(...))QLayoutItem::spacerItem +432 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QBoxLayout + size=32 align=8 + base size=28 base align=8 +QBoxLayout (0x0x7fc66707cf70) 0 + vptr=((& QBoxLayout::_ZTV10QBoxLayout) + 16) + QLayout (0x0x7fc666e60070) 0 + primary-for QBoxLayout (0x0x7fc66707cf70) + QObject (0x0x7fc666e289c0) 0 + primary-for QLayout (0x0x7fc666e60070) + QLayoutItem (0x0x7fc666e28a20) 16 + vptr=((& QBoxLayout::_ZTV10QBoxLayout) + 304) + +Class QHBoxLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHBoxLayout::QPrivateSignal (0x0x7fc666e28cc0) 0 empty + +Vtable for QHBoxLayout +QHBoxLayout::_ZTV11QHBoxLayout: 55 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHBoxLayout) +16 (int (*)(...))QHBoxLayout::metaObject +24 (int (*)(...))QHBoxLayout::qt_metacast +32 (int (*)(...))QHBoxLayout::qt_metacall +40 (int (*)(...))QHBoxLayout::~QHBoxLayout +48 (int (*)(...))QHBoxLayout::~QHBoxLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QBoxLayout::spacing +120 (int (*)(...))QBoxLayout::setSpacing +128 (int (*)(...))QBoxLayout::invalidate +136 (int (*)(...))QLayout::geometry +144 (int (*)(...))QBoxLayout::addItem +152 (int (*)(...))QBoxLayout::expandingDirections +160 (int (*)(...))QBoxLayout::minimumSize +168 (int (*)(...))QBoxLayout::maximumSize +176 (int (*)(...))QBoxLayout::setGeometry +184 (int (*)(...))QBoxLayout::itemAt +192 (int (*)(...))QBoxLayout::takeAt +200 (int (*)(...))QLayout::indexOf +208 (int (*)(...))QLayout::indexOf +216 (int (*)(...))QBoxLayout::count +224 (int (*)(...))QLayout::isEmpty +232 (int (*)(...))QLayout::controlTypes +240 (int (*)(...))QLayout::replaceWidget +248 (int (*)(...))QLayout::layout +256 (int (*)(...))QBoxLayout::sizeHint +264 (int (*)(...))QBoxLayout::hasHeightForWidth +272 (int (*)(...))QBoxLayout::heightForWidth +280 (int (*)(...))QBoxLayout::minimumHeightForWidth +288 (int (*)(...))-16 +296 (int (*)(...))(& _ZTI11QHBoxLayout) +304 (int (*)(...))QHBoxLayout::_ZThn16_N11QHBoxLayoutD1Ev +312 (int (*)(...))QHBoxLayout::_ZThn16_N11QHBoxLayoutD0Ev +320 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv +328 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv +336 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv +344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv +352 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect +360 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +368 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +376 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv +384 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi +392 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi +400 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv +408 (int (*)(...))QLayoutItem::widget +416 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +424 (int (*)(...))QLayoutItem::spacerItem +432 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QHBoxLayout + size=32 align=8 + base size=28 base align=8 +QHBoxLayout (0x0x7fc666e96000) 0 + vptr=((& QHBoxLayout::_ZTV11QHBoxLayout) + 16) + QBoxLayout (0x0x7fc666e96068) 0 + primary-for QHBoxLayout (0x0x7fc666e96000) + QLayout (0x0x7fc666e60380) 0 + primary-for QBoxLayout (0x0x7fc666e96068) + QObject (0x0x7fc666e28c00) 0 + primary-for QLayout (0x0x7fc666e60380) + QLayoutItem (0x0x7fc666e28c60) 16 + vptr=((& QHBoxLayout::_ZTV11QHBoxLayout) + 304) + +Class QVBoxLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVBoxLayout::QPrivateSignal (0x0x7fc666e28e40) 0 empty + +Vtable for QVBoxLayout +QVBoxLayout::_ZTV11QVBoxLayout: 55 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QVBoxLayout) +16 (int (*)(...))QVBoxLayout::metaObject +24 (int (*)(...))QVBoxLayout::qt_metacast +32 (int (*)(...))QVBoxLayout::qt_metacall +40 (int (*)(...))QVBoxLayout::~QVBoxLayout +48 (int (*)(...))QVBoxLayout::~QVBoxLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QBoxLayout::spacing +120 (int (*)(...))QBoxLayout::setSpacing +128 (int (*)(...))QBoxLayout::invalidate +136 (int (*)(...))QLayout::geometry +144 (int (*)(...))QBoxLayout::addItem +152 (int (*)(...))QBoxLayout::expandingDirections +160 (int (*)(...))QBoxLayout::minimumSize +168 (int (*)(...))QBoxLayout::maximumSize +176 (int (*)(...))QBoxLayout::setGeometry +184 (int (*)(...))QBoxLayout::itemAt +192 (int (*)(...))QBoxLayout::takeAt +200 (int (*)(...))QLayout::indexOf +208 (int (*)(...))QLayout::indexOf +216 (int (*)(...))QBoxLayout::count +224 (int (*)(...))QLayout::isEmpty +232 (int (*)(...))QLayout::controlTypes +240 (int (*)(...))QLayout::replaceWidget +248 (int (*)(...))QLayout::layout +256 (int (*)(...))QBoxLayout::sizeHint +264 (int (*)(...))QBoxLayout::hasHeightForWidth +272 (int (*)(...))QBoxLayout::heightForWidth +280 (int (*)(...))QBoxLayout::minimumHeightForWidth +288 (int (*)(...))-16 +296 (int (*)(...))(& _ZTI11QVBoxLayout) +304 (int (*)(...))QVBoxLayout::_ZThn16_N11QVBoxLayoutD1Ev +312 (int (*)(...))QVBoxLayout::_ZThn16_N11QVBoxLayoutD0Ev +320 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv +328 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv +336 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv +344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv +352 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect +360 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +368 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +376 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv +384 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi +392 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi +400 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv +408 (int (*)(...))QLayoutItem::widget +416 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +424 (int (*)(...))QLayoutItem::spacerItem +432 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QVBoxLayout + size=32 align=8 + base size=28 base align=8 +QVBoxLayout (0x0x7fc666e960d0) 0 + vptr=((& QVBoxLayout::_ZTV11QVBoxLayout) + 16) + QBoxLayout (0x0x7fc666e96138) 0 + primary-for QVBoxLayout (0x0x7fc666e960d0) + QLayout (0x0x7fc666e603f0) 0 + primary-for QBoxLayout (0x0x7fc666e96138) + QObject (0x0x7fc666e28d80) 0 + primary-for QLayout (0x0x7fc666e603f0) + QLayoutItem (0x0x7fc666e28de0) 16 + vptr=((& QVBoxLayout::_ZTV11QVBoxLayout) + 304) + +Class QButtonGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QButtonGroup::QPrivateSignal (0x0x7fc666e28f60) 0 empty + +Vtable for QButtonGroup +QButtonGroup::_ZTV12QButtonGroup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QButtonGroup) +16 (int (*)(...))QButtonGroup::metaObject +24 (int (*)(...))QButtonGroup::qt_metacast +32 (int (*)(...))QButtonGroup::qt_metacall +40 (int (*)(...))QButtonGroup::~QButtonGroup +48 (int (*)(...))QButtonGroup::~QButtonGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QButtonGroup + size=16 align=8 + base size=16 base align=8 +QButtonGroup (0x0x7fc666e961a0) 0 + vptr=((& QButtonGroup::_ZTV12QButtonGroup) + 16) + QObject (0x0x7fc666e28f00) 0 + primary-for QButtonGroup (0x0x7fc666e961a0) + +Class QCalendarWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCalendarWidget::QPrivateSignal (0x0x7fc666eb91e0) 0 empty + +Vtable for QCalendarWidget +QCalendarWidget::_ZTV15QCalendarWidget: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QCalendarWidget) +16 (int (*)(...))QCalendarWidget::metaObject +24 (int (*)(...))QCalendarWidget::qt_metacast +32 (int (*)(...))QCalendarWidget::qt_metacall +40 (int (*)(...))QCalendarWidget::~QCalendarWidget +48 (int (*)(...))QCalendarWidget::~QCalendarWidget +56 (int (*)(...))QCalendarWidget::event +64 (int (*)(...))QCalendarWidget::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QCalendarWidget::sizeHint +136 (int (*)(...))QCalendarWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QCalendarWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QCalendarWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QCalendarWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QCalendarWidget::paintCell +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI15QCalendarWidget) +456 (int (*)(...))QCalendarWidget::_ZThn16_N15QCalendarWidgetD1Ev +464 (int (*)(...))QCalendarWidget::_ZThn16_N15QCalendarWidgetD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QCalendarWidget + size=40 align=8 + base size=40 base align=8 +QCalendarWidget (0x0x7fc666e96208) 0 + vptr=((& QCalendarWidget::_ZTV15QCalendarWidget) + 16) + QWidget (0x0x7fc666e60460) 0 + primary-for QCalendarWidget (0x0x7fc666e96208) + QObject (0x0x7fc666eb9120) 0 + primary-for QWidget (0x0x7fc666e60460) + QPaintDevice (0x0x7fc666eb9180) 16 + vptr=((& QCalendarWidget::_ZTV15QCalendarWidget) + 456) + +Class QCheckBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCheckBox::QPrivateSignal (0x0x7fc666eb9660) 0 empty + +Vtable for QCheckBox +QCheckBox::_ZTV9QCheckBox: 68 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QCheckBox) +16 (int (*)(...))QCheckBox::metaObject +24 (int (*)(...))QCheckBox::qt_metacast +32 (int (*)(...))QCheckBox::qt_metacall +40 (int (*)(...))QCheckBox::~QCheckBox +48 (int (*)(...))QCheckBox::~QCheckBox +56 (int (*)(...))QCheckBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QCheckBox::sizeHint +136 (int (*)(...))QCheckBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QCheckBox::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QCheckBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QCheckBox::hitButton +440 (int (*)(...))QCheckBox::checkStateSet +448 (int (*)(...))QCheckBox::nextCheckState +456 (int (*)(...))QCheckBox::initStyleOption +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI9QCheckBox) +480 (int (*)(...))QCheckBox::_ZThn16_N9QCheckBoxD1Ev +488 (int (*)(...))QCheckBox::_ZThn16_N9QCheckBoxD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QCheckBox + size=40 align=8 + base size=40 base align=8 +QCheckBox (0x0x7fc666e96270) 0 + vptr=((& QCheckBox::_ZTV9QCheckBox) + 16) + QAbstractButton (0x0x7fc666e962d8) 0 + primary-for QCheckBox (0x0x7fc666e96270) + QWidget (0x0x7fc666e60850) 0 + primary-for QAbstractButton (0x0x7fc666e962d8) + QObject (0x0x7fc666eb95a0) 0 + primary-for QWidget (0x0x7fc666e60850) + QPaintDevice (0x0x7fc666eb9600) 16 + vptr=((& QCheckBox::_ZTV9QCheckBox) + 480) + +Class QDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDialog::QPrivateSignal (0x0x7fc666eb98a0) 0 empty + +Vtable for QDialog +QDialog::_ZTV7QDialog: 69 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QDialog) +16 (int (*)(...))QDialog::metaObject +24 (int (*)(...))QDialog::qt_metacast +32 (int (*)(...))QDialog::qt_metacall +40 (int (*)(...))QDialog::~QDialog +48 (int (*)(...))QDialog::~QDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI7QDialog) +488 (int (*)(...))QDialog::_ZThn16_N7QDialogD1Ev +496 (int (*)(...))QDialog::_ZThn16_N7QDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDialog + size=40 align=8 + base size=40 base align=8 +QDialog (0x0x7fc666e96340) 0 + vptr=((& QDialog::_ZTV7QDialog) + 16) + QWidget (0x0x7fc666e608c0) 0 + primary-for QDialog (0x0x7fc666e96340) + QObject (0x0x7fc666eb97e0) 0 + primary-for QWidget (0x0x7fc666e608c0) + QPaintDevice (0x0x7fc666eb9840) 16 + vptr=((& QDialog::_ZTV7QDialog) + 488) + +Class QColorDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QColorDialog::QPrivateSignal (0x0x7fc666eb9ae0) 0 empty + +Vtable for QColorDialog +QColorDialog::_ZTV12QColorDialog: 69 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QColorDialog) +16 (int (*)(...))QColorDialog::metaObject +24 (int (*)(...))QColorDialog::qt_metacast +32 (int (*)(...))QColorDialog::qt_metacall +40 (int (*)(...))QColorDialog::~QColorDialog +48 (int (*)(...))QColorDialog::~QColorDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QColorDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QColorDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QColorDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI12QColorDialog) +488 (int (*)(...))QColorDialog::_ZThn16_N12QColorDialogD1Ev +496 (int (*)(...))QColorDialog::_ZThn16_N12QColorDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QColorDialog + size=40 align=8 + base size=40 base align=8 +QColorDialog (0x0x7fc666e963a8) 0 + vptr=((& QColorDialog::_ZTV12QColorDialog) + 16) + QDialog (0x0x7fc666e96410) 0 + primary-for QColorDialog (0x0x7fc666e963a8) + QWidget (0x0x7fc666e60a10) 0 + primary-for QDialog (0x0x7fc666e96410) + QObject (0x0x7fc666eb9a20) 0 + primary-for QWidget (0x0x7fc666e60a10) + QPaintDevice (0x0x7fc666eb9a80) 16 + vptr=((& QColorDialog::_ZTV12QColorDialog) + 488) + +Class QColormap + size=8 align=8 + base size=8 base align=8 +QColormap (0x0x7fc666f58120) 0 + +Class QColumnView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QColumnView::QPrivateSignal (0x0x7fc666f58240) 0 empty + +Vtable for QColumnView +QColumnView::_ZTV11QColumnView: 109 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QColumnView) +16 (int (*)(...))QColumnView::metaObject +24 (int (*)(...))QColumnView::qt_metacast +32 (int (*)(...))QColumnView::qt_metacall +40 (int (*)(...))QColumnView::~QColumnView +48 (int (*)(...))QColumnView::~QColumnView +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QAbstractItemView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QColumnView::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QColumnView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QAbstractItemView::viewportEvent +456 (int (*)(...))QColumnView::scrollContentsBy +464 (int (*)(...))QAbstractItemView::viewportSizeHint +472 (int (*)(...))QColumnView::setModel +480 (int (*)(...))QColumnView::setSelectionModel +488 (int (*)(...))QAbstractItemView::keyboardSearch +496 (int (*)(...))QColumnView::visualRect +504 (int (*)(...))QColumnView::scrollTo +512 (int (*)(...))QColumnView::indexAt +520 (int (*)(...))QAbstractItemView::sizeHintForRow +528 (int (*)(...))QAbstractItemView::sizeHintForColumn +536 (int (*)(...))QAbstractItemView::itemDelegateForIndex +544 (int (*)(...))QAbstractItemView::reset +552 (int (*)(...))QColumnView::setRootIndex +560 (int (*)(...))QAbstractItemView::doItemsLayout +568 (int (*)(...))QColumnView::selectAll +576 (int (*)(...))QAbstractItemView::dataChanged +584 (int (*)(...))QColumnView::rowsInserted +592 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +600 (int (*)(...))QAbstractItemView::selectionChanged +608 (int (*)(...))QColumnView::currentChanged +616 (int (*)(...))QAbstractItemView::updateEditorData +624 (int (*)(...))QAbstractItemView::updateEditorGeometries +632 (int (*)(...))QAbstractItemView::updateGeometries +640 (int (*)(...))QAbstractItemView::verticalScrollbarAction +648 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +656 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +664 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +672 (int (*)(...))QAbstractItemView::closeEditor +680 (int (*)(...))QAbstractItemView::commitData +688 (int (*)(...))QAbstractItemView::editorDestroyed +696 (int (*)(...))QColumnView::moveCursor +704 (int (*)(...))QColumnView::horizontalOffset +712 (int (*)(...))QColumnView::verticalOffset +720 (int (*)(...))QColumnView::isIndexHidden +728 (int (*)(...))QColumnView::setSelection +736 (int (*)(...))QColumnView::visualRegionForSelection +744 (int (*)(...))QAbstractItemView::selectedIndexes +752 (int (*)(...))QAbstractItemView::edit +760 (int (*)(...))QAbstractItemView::selectionCommand +768 (int (*)(...))QAbstractItemView::startDrag +776 (int (*)(...))QAbstractItemView::initViewItemOption +784 (int (*)(...))QColumnView::createColumn +792 (int (*)(...))-16 +800 (int (*)(...))(& _ZTI11QColumnView) +808 (int (*)(...))QColumnView::_ZThn16_N11QColumnViewD1Ev +816 (int (*)(...))QColumnView::_ZThn16_N11QColumnViewD0Ev +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QColumnView + size=40 align=8 + base size=40 base align=8 +QColumnView (0x0x7fc666e965b0) 0 + vptr=((& QColumnView::_ZTV11QColumnView) + 16) + QAbstractItemView (0x0x7fc666e96618) 0 + primary-for QColumnView (0x0x7fc666e965b0) + QAbstractScrollArea (0x0x7fc666e96680) 0 + primary-for QAbstractItemView (0x0x7fc666e96618) + QFrame (0x0x7fc666e966e8) 0 + primary-for QAbstractScrollArea (0x0x7fc666e96680) + QWidget (0x0x7fc666e60d20) 0 + primary-for QFrame (0x0x7fc666e966e8) + QObject (0x0x7fc666f58180) 0 + primary-for QWidget (0x0x7fc666e60d20) + QPaintDevice (0x0x7fc666f581e0) 16 + vptr=((& QColumnView::_ZTV11QColumnView) + 808) + +Class QComboBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QComboBox::QPrivateSignal (0x0x7fc666f58480) 0 empty + +Vtable for QComboBox +QComboBox::_ZTV9QComboBox: 68 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QComboBox) +16 (int (*)(...))QComboBox::metaObject +24 (int (*)(...))QComboBox::qt_metacast +32 (int (*)(...))QComboBox::qt_metacall +40 (int (*)(...))QComboBox::~QComboBox +48 (int (*)(...))QComboBox::~QComboBox +56 (int (*)(...))QComboBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QComboBox::sizeHint +136 (int (*)(...))QComboBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QComboBox::mousePressEvent +176 (int (*)(...))QComboBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QComboBox::wheelEvent +208 (int (*)(...))QComboBox::keyPressEvent +216 (int (*)(...))QComboBox::keyReleaseEvent +224 (int (*)(...))QComboBox::focusInEvent +232 (int (*)(...))QComboBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QComboBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QComboBox::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QComboBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QComboBox::showEvent +352 (int (*)(...))QComboBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QComboBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QComboBox::inputMethodEvent +416 (int (*)(...))QComboBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QComboBox::setModel +440 (int (*)(...))QComboBox::showPopup +448 (int (*)(...))QComboBox::hidePopup +456 (int (*)(...))QComboBox::initStyleOption +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI9QComboBox) +480 (int (*)(...))QComboBox::_ZThn16_N9QComboBoxD1Ev +488 (int (*)(...))QComboBox::_ZThn16_N9QComboBoxD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QComboBox + size=40 align=8 + base size=40 base align=8 +QComboBox (0x0x7fc666e96750) 0 + vptr=((& QComboBox::_ZTV9QComboBox) + 16) + QWidget (0x0x7fc666e60d90) 0 + primary-for QComboBox (0x0x7fc666e96750) + QObject (0x0x7fc666f583c0) 0 + primary-for QWidget (0x0x7fc666e60d90) + QPaintDevice (0x0x7fc666f58420) 16 + vptr=((& QComboBox::_ZTV9QComboBox) + 480) + +Class QPushButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPushButton::QPrivateSignal (0x0x7fc666f58a20) 0 empty + +Vtable for QPushButton +QPushButton::_ZTV11QPushButton: 68 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPushButton) +16 (int (*)(...))QPushButton::metaObject +24 (int (*)(...))QPushButton::qt_metacast +32 (int (*)(...))QPushButton::qt_metacall +40 (int (*)(...))QPushButton::~QPushButton +48 (int (*)(...))QPushButton::~QPushButton +56 (int (*)(...))QPushButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QPushButton::sizeHint +136 (int (*)(...))QPushButton::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QPushButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QPushButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QPushButton::focusInEvent +232 (int (*)(...))QPushButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QPushButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QPushButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))QPushButton::initStyleOption +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI11QPushButton) +480 (int (*)(...))QPushButton::_ZThn16_N11QPushButtonD1Ev +488 (int (*)(...))QPushButton::_ZThn16_N11QPushButtonD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QPushButton + size=40 align=8 + base size=40 base align=8 +QPushButton (0x0x7fc666e967b8) 0 + vptr=((& QPushButton::_ZTV11QPushButton) + 16) + QAbstractButton (0x0x7fc666e96820) 0 + primary-for QPushButton (0x0x7fc666e967b8) + QWidget (0x0x7fc666f922a0) 0 + primary-for QAbstractButton (0x0x7fc666e96820) + QObject (0x0x7fc666f58960) 0 + primary-for QWidget (0x0x7fc666f922a0) + QPaintDevice (0x0x7fc666f589c0) 16 + vptr=((& QPushButton::_ZTV11QPushButton) + 480) + +Class QCommandLinkButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCommandLinkButton::QPrivateSignal (0x0x7fc666f58c60) 0 empty + +Vtable for QCommandLinkButton +QCommandLinkButton::_ZTV18QCommandLinkButton: 68 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QCommandLinkButton) +16 (int (*)(...))QCommandLinkButton::metaObject +24 (int (*)(...))QCommandLinkButton::qt_metacast +32 (int (*)(...))QCommandLinkButton::qt_metacall +40 (int (*)(...))QCommandLinkButton::~QCommandLinkButton +48 (int (*)(...))QCommandLinkButton::~QCommandLinkButton +56 (int (*)(...))QCommandLinkButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QCommandLinkButton::sizeHint +136 (int (*)(...))QCommandLinkButton::minimumSizeHint +144 (int (*)(...))QCommandLinkButton::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QPushButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QPushButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QPushButton::focusInEvent +232 (int (*)(...))QPushButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QCommandLinkButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QPushButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))QCommandLinkButton::initStyleOption +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI18QCommandLinkButton) +480 (int (*)(...))QCommandLinkButton::_ZThn16_N18QCommandLinkButtonD1Ev +488 (int (*)(...))QCommandLinkButton::_ZThn16_N18QCommandLinkButtonD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QCommandLinkButton + size=40 align=8 + base size=40 base align=8 +QCommandLinkButton (0x0x7fc666e96888) 0 + vptr=((& QCommandLinkButton::_ZTV18QCommandLinkButton) + 16) + QPushButton (0x0x7fc666e968f0) 0 + primary-for QCommandLinkButton (0x0x7fc666e96888) + QAbstractButton (0x0x7fc666e96958) 0 + primary-for QPushButton (0x0x7fc666e968f0) + QWidget (0x0x7fc666f92310) 0 + primary-for QAbstractButton (0x0x7fc666e96958) + QObject (0x0x7fc666f58ba0) 0 + primary-for QWidget (0x0x7fc666f92310) + QPaintDevice (0x0x7fc666f58c00) 16 + vptr=((& QCommandLinkButton::_ZTV18QCommandLinkButton) + 480) + +Class QCommonStyle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCommonStyle::QPrivateSignal (0x0x7fc666f58e40) 0 empty + +Vtable for QCommonStyle +QCommonStyle::_ZTV12QCommonStyle: 37 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QCommonStyle) +16 (int (*)(...))QCommonStyle::metaObject +24 (int (*)(...))QCommonStyle::qt_metacast +32 (int (*)(...))QCommonStyle::qt_metacall +40 (int (*)(...))QCommonStyle::~QCommonStyle +48 (int (*)(...))QCommonStyle::~QCommonStyle +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCommonStyle::polish +120 (int (*)(...))QCommonStyle::unpolish +128 (int (*)(...))QCommonStyle::polish +136 (int (*)(...))QCommonStyle::unpolish +144 (int (*)(...))QCommonStyle::polish +152 (int (*)(...))QStyle::itemTextRect +160 (int (*)(...))QStyle::itemPixmapRect +168 (int (*)(...))QStyle::drawItemText +176 (int (*)(...))QStyle::drawItemPixmap +184 (int (*)(...))QStyle::standardPalette +192 (int (*)(...))QCommonStyle::drawPrimitive +200 (int (*)(...))QCommonStyle::drawControl +208 (int (*)(...))QCommonStyle::subElementRect +216 (int (*)(...))QCommonStyle::drawComplexControl +224 (int (*)(...))QCommonStyle::hitTestComplexControl +232 (int (*)(...))QCommonStyle::subControlRect +240 (int (*)(...))QCommonStyle::pixelMetric +248 (int (*)(...))QCommonStyle::sizeFromContents +256 (int (*)(...))QCommonStyle::styleHint +264 (int (*)(...))QCommonStyle::standardPixmap +272 (int (*)(...))QCommonStyle::standardIcon +280 (int (*)(...))QCommonStyle::generatedIconPixmap +288 (int (*)(...))QCommonStyle::layoutSpacing + +Class QCommonStyle + size=16 align=8 + base size=16 base align=8 +QCommonStyle (0x0x7fc666e969c0) 0 + vptr=((& QCommonStyle::_ZTV12QCommonStyle) + 16) + QStyle (0x0x7fc666e96a28) 0 + primary-for QCommonStyle (0x0x7fc666e969c0) + QObject (0x0x7fc666f58de0) 0 + primary-for QStyle (0x0x7fc666e96a28) + +Class QCompleter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCompleter::QPrivateSignal (0x0x7fc666bfe060) 0 empty + +Vtable for QCompleter +QCompleter::_ZTV10QCompleter: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QCompleter) +16 (int (*)(...))QCompleter::metaObject +24 (int (*)(...))QCompleter::qt_metacast +32 (int (*)(...))QCompleter::qt_metacall +40 (int (*)(...))QCompleter::~QCompleter +48 (int (*)(...))QCompleter::~QCompleter +56 (int (*)(...))QCompleter::event +64 (int (*)(...))QCompleter::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCompleter::pathFromIndex +120 (int (*)(...))QCompleter::splitPath + +Class QCompleter + size=16 align=8 + base size=16 base align=8 +QCompleter (0x0x7fc666e96a90) 0 + vptr=((& QCompleter::_ZTV10QCompleter) + 16) + QObject (0x0x7fc666bfe000) 0 + primary-for QCompleter (0x0x7fc666e96a90) + +Class QDataWidgetMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDataWidgetMapper::QPrivateSignal (0x0x7fc666bfe3c0) 0 empty + +Vtable for QDataWidgetMapper +QDataWidgetMapper::_ZTV17QDataWidgetMapper: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QDataWidgetMapper) +16 (int (*)(...))QDataWidgetMapper::metaObject +24 (int (*)(...))QDataWidgetMapper::qt_metacast +32 (int (*)(...))QDataWidgetMapper::qt_metacall +40 (int (*)(...))QDataWidgetMapper::~QDataWidgetMapper +48 (int (*)(...))QDataWidgetMapper::~QDataWidgetMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDataWidgetMapper::setCurrentIndex + +Class QDataWidgetMapper + size=16 align=8 + base size=16 base align=8 +QDataWidgetMapper (0x0x7fc666e96af8) 0 + vptr=((& QDataWidgetMapper::_ZTV17QDataWidgetMapper) + 16) + QObject (0x0x7fc666bfe360) 0 + primary-for QDataWidgetMapper (0x0x7fc666e96af8) + +Class QDateTimeEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDateTimeEdit::QPrivateSignal (0x0x7fc666bfe6c0) 0 empty + +Vtable for QDateTimeEdit +QDateTimeEdit::_ZTV13QDateTimeEdit: 72 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QDateTimeEdit) +16 (int (*)(...))QDateTimeEdit::metaObject +24 (int (*)(...))QDateTimeEdit::qt_metacast +32 (int (*)(...))QDateTimeEdit::qt_metacall +40 (int (*)(...))QDateTimeEdit::~QDateTimeEdit +48 (int (*)(...))QDateTimeEdit::~QDateTimeEdit +56 (int (*)(...))QDateTimeEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDateTimeEdit::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDateTimeEdit::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QDateTimeEdit::wheelEvent +208 (int (*)(...))QDateTimeEdit::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QDateTimeEdit::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDateTimeEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QDateTimeEdit::focusNextPrevChild +432 (int (*)(...))QDateTimeEdit::validate +440 (int (*)(...))QDateTimeEdit::fixup +448 (int (*)(...))QDateTimeEdit::stepBy +456 (int (*)(...))QDateTimeEdit::clear +464 (int (*)(...))QDateTimeEdit::initStyleOption +472 (int (*)(...))QDateTimeEdit::stepEnabled +480 (int (*)(...))QDateTimeEdit::dateTimeFromText +488 (int (*)(...))QDateTimeEdit::textFromDateTime +496 (int (*)(...))-16 +504 (int (*)(...))(& _ZTI13QDateTimeEdit) +512 (int (*)(...))QDateTimeEdit::_ZThn16_N13QDateTimeEditD1Ev +520 (int (*)(...))QDateTimeEdit::_ZThn16_N13QDateTimeEditD0Ev +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDateTimeEdit + size=40 align=8 + base size=40 base align=8 +QDateTimeEdit (0x0x7fc666e96b60) 0 + vptr=((& QDateTimeEdit::_ZTV13QDateTimeEdit) + 16) + QAbstractSpinBox (0x0x7fc666e96bc8) 0 + primary-for QDateTimeEdit (0x0x7fc666e96b60) + QWidget (0x0x7fc666f92700) 0 + primary-for QAbstractSpinBox (0x0x7fc666e96bc8) + QObject (0x0x7fc666bfe600) 0 + primary-for QWidget (0x0x7fc666f92700) + QPaintDevice (0x0x7fc666bfe660) 16 + vptr=((& QDateTimeEdit::_ZTV13QDateTimeEdit) + 512) + +Class QTimeEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeEdit::QPrivateSignal (0x0x7fc666bfec60) 0 empty + +Vtable for QTimeEdit +QTimeEdit::_ZTV9QTimeEdit: 72 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeEdit) +16 (int (*)(...))QTimeEdit::metaObject +24 (int (*)(...))QTimeEdit::qt_metacast +32 (int (*)(...))QTimeEdit::qt_metacall +40 (int (*)(...))QTimeEdit::~QTimeEdit +48 (int (*)(...))QTimeEdit::~QTimeEdit +56 (int (*)(...))QDateTimeEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDateTimeEdit::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDateTimeEdit::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QDateTimeEdit::wheelEvent +208 (int (*)(...))QDateTimeEdit::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QDateTimeEdit::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDateTimeEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QDateTimeEdit::focusNextPrevChild +432 (int (*)(...))QDateTimeEdit::validate +440 (int (*)(...))QDateTimeEdit::fixup +448 (int (*)(...))QDateTimeEdit::stepBy +456 (int (*)(...))QDateTimeEdit::clear +464 (int (*)(...))QDateTimeEdit::initStyleOption +472 (int (*)(...))QDateTimeEdit::stepEnabled +480 (int (*)(...))QDateTimeEdit::dateTimeFromText +488 (int (*)(...))QDateTimeEdit::textFromDateTime +496 (int (*)(...))-16 +504 (int (*)(...))(& _ZTI9QTimeEdit) +512 (int (*)(...))QTimeEdit::_ZThn16_N9QTimeEditD1Ev +520 (int (*)(...))QTimeEdit::_ZThn16_N9QTimeEditD0Ev +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTimeEdit + size=40 align=8 + base size=40 base align=8 +QTimeEdit (0x0x7fc666e96d68) 0 + vptr=((& QTimeEdit::_ZTV9QTimeEdit) + 16) + QDateTimeEdit (0x0x7fc666e96dd0) 0 + primary-for QTimeEdit (0x0x7fc666e96d68) + QAbstractSpinBox (0x0x7fc666e96e38) 0 + primary-for QDateTimeEdit (0x0x7fc666e96dd0) + QWidget (0x0x7fc666f92c40) 0 + primary-for QAbstractSpinBox (0x0x7fc666e96e38) + QObject (0x0x7fc666bfeba0) 0 + primary-for QWidget (0x0x7fc666f92c40) + QPaintDevice (0x0x7fc666bfec00) 16 + vptr=((& QTimeEdit::_ZTV9QTimeEdit) + 512) + +Class QDateEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDateEdit::QPrivateSignal (0x0x7fc666bfede0) 0 empty + +Vtable for QDateEdit +QDateEdit::_ZTV9QDateEdit: 72 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QDateEdit) +16 (int (*)(...))QDateEdit::metaObject +24 (int (*)(...))QDateEdit::qt_metacast +32 (int (*)(...))QDateEdit::qt_metacall +40 (int (*)(...))QDateEdit::~QDateEdit +48 (int (*)(...))QDateEdit::~QDateEdit +56 (int (*)(...))QDateTimeEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDateTimeEdit::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDateTimeEdit::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QDateTimeEdit::wheelEvent +208 (int (*)(...))QDateTimeEdit::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QDateTimeEdit::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDateTimeEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QDateTimeEdit::focusNextPrevChild +432 (int (*)(...))QDateTimeEdit::validate +440 (int (*)(...))QDateTimeEdit::fixup +448 (int (*)(...))QDateTimeEdit::stepBy +456 (int (*)(...))QDateTimeEdit::clear +464 (int (*)(...))QDateTimeEdit::initStyleOption +472 (int (*)(...))QDateTimeEdit::stepEnabled +480 (int (*)(...))QDateTimeEdit::dateTimeFromText +488 (int (*)(...))QDateTimeEdit::textFromDateTime +496 (int (*)(...))-16 +504 (int (*)(...))(& _ZTI9QDateEdit) +512 (int (*)(...))QDateEdit::_ZThn16_N9QDateEditD1Ev +520 (int (*)(...))QDateEdit::_ZThn16_N9QDateEditD0Ev +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDateEdit + size=40 align=8 + base size=40 base align=8 +QDateEdit (0x0x7fc666e96ea0) 0 + vptr=((& QDateEdit::_ZTV9QDateEdit) + 16) + QDateTimeEdit (0x0x7fc666e96f08) 0 + primary-for QDateEdit (0x0x7fc666e96ea0) + QAbstractSpinBox (0x0x7fc666e96f70) 0 + primary-for QDateTimeEdit (0x0x7fc666e96f08) + QWidget (0x0x7fc666f92cb0) 0 + primary-for QAbstractSpinBox (0x0x7fc666e96f70) + QObject (0x0x7fc666bfed20) 0 + primary-for QWidget (0x0x7fc666f92cb0) + QPaintDevice (0x0x7fc666bfed80) 16 + vptr=((& QDateEdit::_ZTV9QDateEdit) + 512) + +Class QDial::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDial::QPrivateSignal (0x0x7fc666cad180) 0 empty + +Vtable for QDial +QDial::_ZTV5QDial: 66 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDial) +16 (int (*)(...))QDial::metaObject +24 (int (*)(...))QDial::qt_metacast +32 (int (*)(...))QDial::qt_metacall +40 (int (*)(...))QDial::~QDial +48 (int (*)(...))QDial::~QDial +56 (int (*)(...))QDial::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDial::sizeHint +136 (int (*)(...))QDial::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDial::mousePressEvent +176 (int (*)(...))QDial::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QDial::mouseMoveEvent +200 (int (*)(...))QAbstractSlider::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDial::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDial::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDial::sliderChange +440 (int (*)(...))QDial::initStyleOption +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI5QDial) +464 (int (*)(...))QDial::_ZThn16_N5QDialD1Ev +472 (int (*)(...))QDial::_ZThn16_N5QDialD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDial + size=40 align=8 + base size=40 base align=8 +QDial (0x0x7fc666cb7000) 0 + vptr=((& QDial::_ZTV5QDial) + 16) + QAbstractSlider (0x0x7fc666cb7068) 0 + primary-for QDial (0x0x7fc666cb7000) + QWidget (0x0x7fc666f92d20) 0 + primary-for QAbstractSlider (0x0x7fc666cb7068) + QObject (0x0x7fc666cad0c0) 0 + primary-for QWidget (0x0x7fc666f92d20) + QPaintDevice (0x0x7fc666cad120) 16 + vptr=((& QDial::_ZTV5QDial) + 464) + +Class QDialogButtonBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDialogButtonBox::QPrivateSignal (0x0x7fc666cad3c0) 0 empty + +Vtable for QDialogButtonBox +QDialogButtonBox::_ZTV16QDialogButtonBox: 64 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDialogButtonBox) +16 (int (*)(...))QDialogButtonBox::metaObject +24 (int (*)(...))QDialogButtonBox::qt_metacast +32 (int (*)(...))QDialogButtonBox::qt_metacall +40 (int (*)(...))QDialogButtonBox::~QDialogButtonBox +48 (int (*)(...))QDialogButtonBox::~QDialogButtonBox +56 (int (*)(...))QDialogButtonBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QDialogButtonBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI16QDialogButtonBox) +448 (int (*)(...))QDialogButtonBox::_ZThn16_N16QDialogButtonBoxD1Ev +456 (int (*)(...))QDialogButtonBox::_ZThn16_N16QDialogButtonBoxD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDialogButtonBox + size=40 align=8 + base size=40 base align=8 +QDialogButtonBox (0x0x7fc666cb70d0) 0 + vptr=((& QDialogButtonBox::_ZTV16QDialogButtonBox) + 16) + QWidget (0x0x7fc666f92d90) 0 + primary-for QDialogButtonBox (0x0x7fc666cb70d0) + QObject (0x0x7fc666cad300) 0 + primary-for QWidget (0x0x7fc666f92d90) + QPaintDevice (0x0x7fc666cad360) 16 + vptr=((& QDialogButtonBox::_ZTV16QDialogButtonBox) + 448) + +Class QDockWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDockWidget::QPrivateSignal (0x0x7fc666cada80) 0 empty + +Vtable for QDockWidget +QDockWidget::_ZTV11QDockWidget: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QDockWidget) +16 (int (*)(...))QDockWidget::metaObject +24 (int (*)(...))QDockWidget::qt_metacast +32 (int (*)(...))QDockWidget::qt_metacall +40 (int (*)(...))QDockWidget::~QDockWidget +48 (int (*)(...))QDockWidget::~QDockWidget +56 (int (*)(...))QDockWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDockWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QDockWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QDockWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDockWidget::initStyleOption +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI11QDockWidget) +456 (int (*)(...))QDockWidget::_ZThn16_N11QDockWidgetD1Ev +464 (int (*)(...))QDockWidget::_ZThn16_N11QDockWidgetD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDockWidget + size=40 align=8 + base size=40 base align=8 +QDockWidget (0x0x7fc666cb7270) 0 + vptr=((& QDockWidget::_ZTV11QDockWidget) + 16) + QWidget (0x0x7fc666ccde70) 0 + primary-for QDockWidget (0x0x7fc666cb7270) + QObject (0x0x7fc666cad9c0) 0 + primary-for QWidget (0x0x7fc666ccde70) + QPaintDevice (0x0x7fc666cada20) 16 + vptr=((& QDockWidget::_ZTV11QDockWidget) + 456) + +Class QTileRules + size=8 align=4 + base size=8 base align=4 +QTileRules (0x0x7fc666d8a180) 0 + +Class QErrorMessage::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QErrorMessage::QPrivateSignal (0x0x7fc666d8a7e0) 0 empty + +Vtable for QErrorMessage +QErrorMessage::_ZTV13QErrorMessage: 69 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QErrorMessage) +16 (int (*)(...))QErrorMessage::metaObject +24 (int (*)(...))QErrorMessage::qt_metacast +32 (int (*)(...))QErrorMessage::qt_metacall +40 (int (*)(...))QErrorMessage::~QErrorMessage +48 (int (*)(...))QErrorMessage::~QErrorMessage +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QErrorMessage::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QErrorMessage::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI13QErrorMessage) +488 (int (*)(...))QErrorMessage::_ZThn16_N13QErrorMessageD1Ev +496 (int (*)(...))QErrorMessage::_ZThn16_N13QErrorMessageD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QErrorMessage + size=40 align=8 + base size=40 base align=8 +QErrorMessage (0x0x7fc666cb7548) 0 + vptr=((& QErrorMessage::_ZTV13QErrorMessage) + 16) + QDialog (0x0x7fc666cb75b0) 0 + primary-for QErrorMessage (0x0x7fc666cb7548) + QWidget (0x0x7fc666d398c0) 0 + primary-for QDialog (0x0x7fc666cb75b0) + QObject (0x0x7fc666d8a720) 0 + primary-for QWidget (0x0x7fc666d398c0) + QPaintDevice (0x0x7fc666d8a780) 16 + vptr=((& QErrorMessage::_ZTV13QErrorMessage) + 488) + +Class QFileDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDialog::QPrivateSignal (0x0x7fc666d8aa20) 0 empty + +Vtable for QFileDialog +QFileDialog::_ZTV11QFileDialog: 69 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDialog) +16 (int (*)(...))QFileDialog::metaObject +24 (int (*)(...))QFileDialog::qt_metacast +32 (int (*)(...))QFileDialog::qt_metacall +40 (int (*)(...))QFileDialog::~QFileDialog +48 (int (*)(...))QFileDialog::~QFileDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QFileDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFileDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QFileDialog::done +456 (int (*)(...))QFileDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QFileDialog) +488 (int (*)(...))QFileDialog::_ZThn16_N11QFileDialogD1Ev +496 (int (*)(...))QFileDialog::_ZThn16_N11QFileDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFileDialog + size=40 align=8 + base size=40 base align=8 +QFileDialog (0x0x7fc666cb7618) 0 + vptr=((& QFileDialog::_ZTV11QFileDialog) + 16) + QDialog (0x0x7fc666cb7680) 0 + primary-for QFileDialog (0x0x7fc666cb7618) + QWidget (0x0x7fc666d39930) 0 + primary-for QDialog (0x0x7fc666cb7680) + QObject (0x0x7fc666d8a960) 0 + primary-for QWidget (0x0x7fc666d39930) + QPaintDevice (0x0x7fc666d8a9c0) 16 + vptr=((& QFileDialog::_ZTV11QFileDialog) + 488) + +Vtable for QFileIconProvider +QFileIconProvider::_ZTV17QFileIconProvider: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFileIconProvider) +16 (int (*)(...))QFileIconProvider::~QFileIconProvider +24 (int (*)(...))QFileIconProvider::~QFileIconProvider +32 (int (*)(...))QFileIconProvider::icon +40 (int (*)(...))QFileIconProvider::icon +48 (int (*)(...))QAbstractFileIconProvider::type +56 (int (*)(...))QAbstractFileIconProvider::setOptions +64 (int (*)(...))QAbstractFileIconProvider::options + +Class QFileIconProvider + size=16 align=8 + base size=16 base align=8 +QFileIconProvider (0x0x7fc666cb7820) 0 + vptr=((& QFileIconProvider::_ZTV17QFileIconProvider) + 16) + QAbstractFileIconProvider (0x0x7fc666a353c0) 0 + primary-for QFileIconProvider (0x0x7fc666cb7820) + +Class QFocusFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFocusFrame::QPrivateSignal (0x0x7fc666a355a0) 0 empty + +Vtable for QFocusFrame +QFocusFrame::_ZTV11QFocusFrame: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusFrame) +16 (int (*)(...))QFocusFrame::metaObject +24 (int (*)(...))QFocusFrame::qt_metacast +32 (int (*)(...))QFocusFrame::qt_metacall +40 (int (*)(...))QFocusFrame::~QFocusFrame +48 (int (*)(...))QFocusFrame::~QFocusFrame +56 (int (*)(...))QFocusFrame::event +64 (int (*)(...))QFocusFrame::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFocusFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QFocusFrame::initStyleOption +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI11QFocusFrame) +456 (int (*)(...))QFocusFrame::_ZThn16_N11QFocusFrameD1Ev +464 (int (*)(...))QFocusFrame::_ZThn16_N11QFocusFrameD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFocusFrame + size=40 align=8 + base size=40 base align=8 +QFocusFrame (0x0x7fc666cb7888) 0 + vptr=((& QFocusFrame::_ZTV11QFocusFrame) + 16) + QWidget (0x0x7fc6669e92a0) 0 + primary-for QFocusFrame (0x0x7fc666cb7888) + QObject (0x0x7fc666a354e0) 0 + primary-for QWidget (0x0x7fc6669e92a0) + QPaintDevice (0x0x7fc666a35540) 16 + vptr=((& QFocusFrame::_ZTV11QFocusFrame) + 456) + +Class QFontComboBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFontComboBox::QPrivateSignal (0x0x7fc666a357e0) 0 empty + +Vtable for QFontComboBox +QFontComboBox::_ZTV13QFontComboBox: 68 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFontComboBox) +16 (int (*)(...))QFontComboBox::metaObject +24 (int (*)(...))QFontComboBox::qt_metacast +32 (int (*)(...))QFontComboBox::qt_metacall +40 (int (*)(...))QFontComboBox::~QFontComboBox +48 (int (*)(...))QFontComboBox::~QFontComboBox +56 (int (*)(...))QFontComboBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFontComboBox::sizeHint +136 (int (*)(...))QComboBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QComboBox::mousePressEvent +176 (int (*)(...))QComboBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QComboBox::wheelEvent +208 (int (*)(...))QComboBox::keyPressEvent +216 (int (*)(...))QComboBox::keyReleaseEvent +224 (int (*)(...))QComboBox::focusInEvent +232 (int (*)(...))QComboBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QComboBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QComboBox::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QComboBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QComboBox::showEvent +352 (int (*)(...))QComboBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QComboBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QComboBox::inputMethodEvent +416 (int (*)(...))QComboBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QComboBox::setModel +440 (int (*)(...))QComboBox::showPopup +448 (int (*)(...))QComboBox::hidePopup +456 (int (*)(...))QComboBox::initStyleOption +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI13QFontComboBox) +480 (int (*)(...))QFontComboBox::_ZThn16_N13QFontComboBoxD1Ev +488 (int (*)(...))QFontComboBox::_ZThn16_N13QFontComboBoxD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFontComboBox + size=40 align=8 + base size=40 base align=8 +QFontComboBox (0x0x7fc666cb78f0) 0 + vptr=((& QFontComboBox::_ZTV13QFontComboBox) + 16) + QComboBox (0x0x7fc666cb7958) 0 + primary-for QFontComboBox (0x0x7fc666cb78f0) + QWidget (0x0x7fc6669e9310) 0 + primary-for QComboBox (0x0x7fc666cb7958) + QObject (0x0x7fc666a35720) 0 + primary-for QWidget (0x0x7fc6669e9310) + QPaintDevice (0x0x7fc666a35780) 16 + vptr=((& QFontComboBox::_ZTV13QFontComboBox) + 480) + +Class QFontDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFontDialog::QPrivateSignal (0x0x7fc666a35ea0) 0 empty + +Vtable for QFontDialog +QFontDialog::_ZTV11QFontDialog: 69 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFontDialog) +16 (int (*)(...))QFontDialog::metaObject +24 (int (*)(...))QFontDialog::qt_metacast +32 (int (*)(...))QFontDialog::qt_metacall +40 (int (*)(...))QFontDialog::~QFontDialog +48 (int (*)(...))QFontDialog::~QFontDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QFontDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QFontDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFontDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QFontDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QFontDialog) +488 (int (*)(...))QFontDialog::_ZThn16_N11QFontDialogD1Ev +496 (int (*)(...))QFontDialog::_ZThn16_N11QFontDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFontDialog + size=40 align=8 + base size=40 base align=8 +QFontDialog (0x0x7fc666cb7af8) 0 + vptr=((& QFontDialog::_ZTV11QFontDialog) + 16) + QDialog (0x0x7fc666cb7b60) 0 + primary-for QFontDialog (0x0x7fc666cb7af8) + QWidget (0x0x7fc6669e95b0) 0 + primary-for QDialog (0x0x7fc666cb7b60) + QObject (0x0x7fc666a35de0) 0 + primary-for QWidget (0x0x7fc6669e95b0) + QPaintDevice (0x0x7fc666a35e40) 16 + vptr=((& QFontDialog::_ZTV11QFontDialog) + 488) + +Class QFormLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFormLayout::QPrivateSignal (0x0x7fc666afc5a0) 0 empty + +Class QFormLayout::TakeRowResult + size=16 align=8 + base size=16 base align=8 +QFormLayout::TakeRowResult (0x0x7fc666afc600) 0 + +Vtable for QFormLayout +QFormLayout::_ZTV11QFormLayout: 54 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFormLayout) +16 (int (*)(...))QFormLayout::metaObject +24 (int (*)(...))QFormLayout::qt_metacast +32 (int (*)(...))QFormLayout::qt_metacall +40 (int (*)(...))QFormLayout::~QFormLayout +48 (int (*)(...))QFormLayout::~QFormLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFormLayout::spacing +120 (int (*)(...))QFormLayout::setSpacing +128 (int (*)(...))QFormLayout::invalidate +136 (int (*)(...))QLayout::geometry +144 (int (*)(...))QFormLayout::addItem +152 (int (*)(...))QFormLayout::expandingDirections +160 (int (*)(...))QFormLayout::minimumSize +168 (int (*)(...))QLayout::maximumSize +176 (int (*)(...))QFormLayout::setGeometry +184 (int (*)(...))QFormLayout::itemAt +192 (int (*)(...))QFormLayout::takeAt +200 (int (*)(...))QLayout::indexOf +208 (int (*)(...))QLayout::indexOf +216 (int (*)(...))QFormLayout::count +224 (int (*)(...))QLayout::isEmpty +232 (int (*)(...))QLayout::controlTypes +240 (int (*)(...))QLayout::replaceWidget +248 (int (*)(...))QLayout::layout +256 (int (*)(...))QFormLayout::sizeHint +264 (int (*)(...))QFormLayout::hasHeightForWidth +272 (int (*)(...))QFormLayout::heightForWidth +280 (int (*)(...))-16 +288 (int (*)(...))(& _ZTI11QFormLayout) +296 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayoutD1Ev +304 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayoutD0Ev +312 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout8sizeHintEv +320 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout11minimumSizeEv +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv +336 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout19expandingDirectionsEv +344 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayout11setGeometryERK5QRect +352 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +360 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +368 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout17hasHeightForWidthEv +376 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout14heightForWidthEi +384 (int (*)(...))QLayoutItem::minimumHeightForWidth +392 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayout10invalidateEv +400 (int (*)(...))QLayoutItem::widget +408 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +416 (int (*)(...))QLayoutItem::spacerItem +424 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QFormLayout + size=32 align=8 + base size=28 base align=8 +QFormLayout (0x0x7fc666cb7d00) 0 + vptr=((& QFormLayout::_ZTV11QFormLayout) + 16) + QLayout (0x0x7fc6669e98c0) 0 + primary-for QFormLayout (0x0x7fc666cb7d00) + QObject (0x0x7fc666afc4e0) 0 + primary-for QLayout (0x0x7fc6669e98c0) + QLayoutItem (0x0x7fc666afc540) 16 + vptr=((& QFormLayout::_ZTV11QFormLayout) + 296) + +Class QGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGesture::QPrivateSignal (0x0x7fc666bb78a0) 0 empty + +Vtable for QGesture +QGesture::_ZTV8QGesture: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QGesture) +16 (int (*)(...))QGesture::metaObject +24 (int (*)(...))QGesture::qt_metacast +32 (int (*)(...))QGesture::qt_metacall +40 (int (*)(...))QGesture::~QGesture +48 (int (*)(...))QGesture::~QGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QGesture + size=16 align=8 + base size=16 base align=8 +QGesture (0x0x7fc666b9e888) 0 + vptr=((& QGesture::_ZTV8QGesture) + 16) + QObject (0x0x7fc666bb7840) 0 + primary-for QGesture (0x0x7fc666b9e888) + +Class QPanGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPanGesture::QPrivateSignal (0x0x7fc666bb7a80) 0 empty + +Vtable for QPanGesture +QPanGesture::_ZTV11QPanGesture: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPanGesture) +16 (int (*)(...))QPanGesture::metaObject +24 (int (*)(...))QPanGesture::qt_metacast +32 (int (*)(...))QPanGesture::qt_metacall +40 (int (*)(...))QPanGesture::~QPanGesture +48 (int (*)(...))QPanGesture::~QPanGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPanGesture + size=16 align=8 + base size=16 base align=8 +QPanGesture (0x0x7fc666b9e8f0) 0 + vptr=((& QPanGesture::_ZTV11QPanGesture) + 16) + QGesture (0x0x7fc666b9e958) 0 + primary-for QPanGesture (0x0x7fc666b9e8f0) + QObject (0x0x7fc666bb7a20) 0 + primary-for QGesture (0x0x7fc666b9e958) + +Class QPinchGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPinchGesture::QPrivateSignal (0x0x7fc666bb7c60) 0 empty + +Vtable for QPinchGesture +QPinchGesture::_ZTV13QPinchGesture: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPinchGesture) +16 (int (*)(...))QPinchGesture::metaObject +24 (int (*)(...))QPinchGesture::qt_metacast +32 (int (*)(...))QPinchGesture::qt_metacall +40 (int (*)(...))QPinchGesture::~QPinchGesture +48 (int (*)(...))QPinchGesture::~QPinchGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPinchGesture + size=16 align=8 + base size=16 base align=8 +QPinchGesture (0x0x7fc666b9e9c0) 0 + vptr=((& QPinchGesture::_ZTV13QPinchGesture) + 16) + QGesture (0x0x7fc666b9ea28) 0 + primary-for QPinchGesture (0x0x7fc666b9e9c0) + QObject (0x0x7fc666bb7c00) 0 + primary-for QGesture (0x0x7fc666b9ea28) + +Class QSwipeGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSwipeGesture::QPrivateSignal (0x0x7fc6668a2300) 0 empty + +Vtable for QSwipeGesture +QSwipeGesture::_ZTV13QSwipeGesture: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSwipeGesture) +16 (int (*)(...))QSwipeGesture::metaObject +24 (int (*)(...))QSwipeGesture::qt_metacast +32 (int (*)(...))QSwipeGesture::qt_metacall +40 (int (*)(...))QSwipeGesture::~QSwipeGesture +48 (int (*)(...))QSwipeGesture::~QSwipeGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSwipeGesture + size=16 align=8 + base size=16 base align=8 +QSwipeGesture (0x0x7fc6668a52d8) 0 + vptr=((& QSwipeGesture::_ZTV13QSwipeGesture) + 16) + QGesture (0x0x7fc6668a5340) 0 + primary-for QSwipeGesture (0x0x7fc6668a52d8) + QObject (0x0x7fc6668a22a0) 0 + primary-for QGesture (0x0x7fc6668a5340) + +Class QTapGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTapGesture::QPrivateSignal (0x0x7fc6668a25a0) 0 empty + +Vtable for QTapGesture +QTapGesture::_ZTV11QTapGesture: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTapGesture) +16 (int (*)(...))QTapGesture::metaObject +24 (int (*)(...))QTapGesture::qt_metacast +32 (int (*)(...))QTapGesture::qt_metacall +40 (int (*)(...))QTapGesture::~QTapGesture +48 (int (*)(...))QTapGesture::~QTapGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTapGesture + size=16 align=8 + base size=16 base align=8 +QTapGesture (0x0x7fc6668a53a8) 0 + vptr=((& QTapGesture::_ZTV11QTapGesture) + 16) + QGesture (0x0x7fc6668a5410) 0 + primary-for QTapGesture (0x0x7fc6668a53a8) + QObject (0x0x7fc6668a2540) 0 + primary-for QGesture (0x0x7fc6668a5410) + +Class QTapAndHoldGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTapAndHoldGesture::QPrivateSignal (0x0x7fc6668a2780) 0 empty + +Vtable for QTapAndHoldGesture +QTapAndHoldGesture::_ZTV18QTapAndHoldGesture: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTapAndHoldGesture) +16 (int (*)(...))QTapAndHoldGesture::metaObject +24 (int (*)(...))QTapAndHoldGesture::qt_metacast +32 (int (*)(...))QTapAndHoldGesture::qt_metacall +40 (int (*)(...))QTapAndHoldGesture::~QTapAndHoldGesture +48 (int (*)(...))QTapAndHoldGesture::~QTapAndHoldGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTapAndHoldGesture + size=16 align=8 + base size=16 base align=8 +QTapAndHoldGesture (0x0x7fc6668a5478) 0 + vptr=((& QTapAndHoldGesture::_ZTV18QTapAndHoldGesture) + 16) + QGesture (0x0x7fc6668a54e0) 0 + primary-for QTapAndHoldGesture (0x0x7fc6668a5478) + QObject (0x0x7fc6668a2720) 0 + primary-for QGesture (0x0x7fc6668a54e0) + +Vtable for QGestureEvent +QGestureEvent::_ZTV13QGestureEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QGestureEvent) +16 (int (*)(...))QGestureEvent::~QGestureEvent +24 (int (*)(...))QGestureEvent::~QGestureEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QGestureEvent + size=64 align=8 + base size=64 base align=8 +QGestureEvent (0x0x7fc6668a5548) 0 + vptr=((& QGestureEvent::_ZTV13QGestureEvent) + 16) + QEvent (0x0x7fc6668a2900) 0 + primary-for QGestureEvent (0x0x7fc6668a5548) + +Vtable for QGestureRecognizer +QGestureRecognizer::_ZTV18QGestureRecognizer: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QGestureRecognizer) +16 0 +24 0 +32 (int (*)(...))QGestureRecognizer::create +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QGestureRecognizer::reset + +Class QGestureRecognizer + size=8 align=8 + base size=8 base align=8 +QGestureRecognizer (0x0x7fc6668e2900) 0 nearly-empty + vptr=((& QGestureRecognizer::_ZTV18QGestureRecognizer) + 16) + +Vtable for QGraphicsItem +QGraphicsItem::_ZTV13QGraphicsItem: 39 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QGraphicsItem) +16 0 +24 0 +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QGraphicsItem::shape +56 (int (*)(...))QGraphicsItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsItem::isObscuredBy +88 (int (*)(...))QGraphicsItem::opaqueArea +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))QGraphicsItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsItem::supportsExtension +296 (int (*)(...))QGraphicsItem::setExtension +304 (int (*)(...))QGraphicsItem::extension + +Class QGraphicsItem + size=16 align=8 + base size=16 base align=8 +QGraphicsItem (0x0x7fc6668e2d20) 0 + vptr=((& QGraphicsItem::_ZTV13QGraphicsItem) + 16) + +Class QGraphicsObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsObject::QPrivateSignal (0x0x7fc666665f60) 0 empty + +Vtable for QGraphicsObject +QGraphicsObject::_ZTV15QGraphicsObject: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsObject) +16 (int (*)(...))QGraphicsObject::metaObject +24 (int (*)(...))QGraphicsObject::qt_metacast +32 (int (*)(...))QGraphicsObject::qt_metacall +40 0 +48 0 +56 (int (*)(...))QGraphicsObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))-16 +120 (int (*)(...))(& _ZTI15QGraphicsObject) +128 0 +136 0 +144 (int (*)(...))QGraphicsItem::advance +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))QGraphicsItem::shape +168 (int (*)(...))QGraphicsItem::contains +176 (int (*)(...))QGraphicsItem::collidesWithItem +184 (int (*)(...))QGraphicsItem::collidesWithPath +192 (int (*)(...))QGraphicsItem::isObscuredBy +200 (int (*)(...))QGraphicsItem::opaqueArea +208 (int (*)(...))__cxa_pure_virtual +216 (int (*)(...))QGraphicsItem::type +224 (int (*)(...))QGraphicsItem::sceneEventFilter +232 (int (*)(...))QGraphicsItem::sceneEvent +240 (int (*)(...))QGraphicsItem::contextMenuEvent +248 (int (*)(...))QGraphicsItem::dragEnterEvent +256 (int (*)(...))QGraphicsItem::dragLeaveEvent +264 (int (*)(...))QGraphicsItem::dragMoveEvent +272 (int (*)(...))QGraphicsItem::dropEvent +280 (int (*)(...))QGraphicsItem::focusInEvent +288 (int (*)(...))QGraphicsItem::focusOutEvent +296 (int (*)(...))QGraphicsItem::hoverEnterEvent +304 (int (*)(...))QGraphicsItem::hoverMoveEvent +312 (int (*)(...))QGraphicsItem::hoverLeaveEvent +320 (int (*)(...))QGraphicsItem::keyPressEvent +328 (int (*)(...))QGraphicsItem::keyReleaseEvent +336 (int (*)(...))QGraphicsItem::mousePressEvent +344 (int (*)(...))QGraphicsItem::mouseMoveEvent +352 (int (*)(...))QGraphicsItem::mouseReleaseEvent +360 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +368 (int (*)(...))QGraphicsItem::wheelEvent +376 (int (*)(...))QGraphicsItem::inputMethodEvent +384 (int (*)(...))QGraphicsItem::inputMethodQuery +392 (int (*)(...))QGraphicsItem::itemChange +400 (int (*)(...))QGraphicsItem::supportsExtension +408 (int (*)(...))QGraphicsItem::setExtension +416 (int (*)(...))QGraphicsItem::extension + +Class QGraphicsObject + size=32 align=8 + base size=32 base align=8 +QGraphicsObject (0x0x7fc66660cb60) 0 + vptr=((& QGraphicsObject::_ZTV15QGraphicsObject) + 16) + QObject (0x0x7fc666665ea0) 0 + primary-for QGraphicsObject (0x0x7fc66660cb60) + QGraphicsItem (0x0x7fc666665f00) 16 + vptr=((& QGraphicsObject::_ZTV15QGraphicsObject) + 128) + +Vtable for QAbstractGraphicsShapeItem +QAbstractGraphicsShapeItem::_ZTV26QAbstractGraphicsShapeItem: 39 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractGraphicsShapeItem) +16 0 +24 0 +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QGraphicsItem::shape +56 (int (*)(...))QGraphicsItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QAbstractGraphicsShapeItem::isObscuredBy +88 (int (*)(...))QAbstractGraphicsShapeItem::opaqueArea +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))QGraphicsItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsItem::supportsExtension +296 (int (*)(...))QGraphicsItem::setExtension +304 (int (*)(...))QGraphicsItem::extension + +Class QAbstractGraphicsShapeItem + size=16 align=8 + base size=16 base align=8 +QAbstractGraphicsShapeItem (0x0x7fc6666e5000) 0 + vptr=((& QAbstractGraphicsShapeItem::_ZTV26QAbstractGraphicsShapeItem) + 16) + QGraphicsItem (0x0x7fc6666e4060) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7fc6666e5000) + +Vtable for QGraphicsPathItem +QGraphicsPathItem::_ZTV17QGraphicsPathItem: 39 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsPathItem) +16 (int (*)(...))QGraphicsPathItem::~QGraphicsPathItem +24 (int (*)(...))QGraphicsPathItem::~QGraphicsPathItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsPathItem::boundingRect +48 (int (*)(...))QGraphicsPathItem::shape +56 (int (*)(...))QGraphicsPathItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsPathItem::isObscuredBy +88 (int (*)(...))QGraphicsPathItem::opaqueArea +96 (int (*)(...))QGraphicsPathItem::paint +104 (int (*)(...))QGraphicsPathItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsPathItem::supportsExtension +296 (int (*)(...))QGraphicsPathItem::setExtension +304 (int (*)(...))QGraphicsPathItem::extension + +Class QGraphicsPathItem + size=16 align=8 + base size=16 base align=8 +QGraphicsPathItem (0x0x7fc6666e5068) 0 + vptr=((& QGraphicsPathItem::_ZTV17QGraphicsPathItem) + 16) + QAbstractGraphicsShapeItem (0x0x7fc6666e50d0) 0 + primary-for QGraphicsPathItem (0x0x7fc6666e5068) + QGraphicsItem (0x0x7fc6666e4180) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7fc6666e50d0) + +Vtable for QGraphicsRectItem +QGraphicsRectItem::_ZTV17QGraphicsRectItem: 39 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsRectItem) +16 (int (*)(...))QGraphicsRectItem::~QGraphicsRectItem +24 (int (*)(...))QGraphicsRectItem::~QGraphicsRectItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsRectItem::boundingRect +48 (int (*)(...))QGraphicsRectItem::shape +56 (int (*)(...))QGraphicsRectItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsRectItem::isObscuredBy +88 (int (*)(...))QGraphicsRectItem::opaqueArea +96 (int (*)(...))QGraphicsRectItem::paint +104 (int (*)(...))QGraphicsRectItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsRectItem::supportsExtension +296 (int (*)(...))QGraphicsRectItem::setExtension +304 (int (*)(...))QGraphicsRectItem::extension + +Class QGraphicsRectItem + size=16 align=8 + base size=16 base align=8 +QGraphicsRectItem (0x0x7fc6666e5138) 0 + vptr=((& QGraphicsRectItem::_ZTV17QGraphicsRectItem) + 16) + QAbstractGraphicsShapeItem (0x0x7fc6666e51a0) 0 + primary-for QGraphicsRectItem (0x0x7fc6666e5138) + QGraphicsItem (0x0x7fc6666e42a0) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7fc6666e51a0) + +Vtable for QGraphicsEllipseItem +QGraphicsEllipseItem::_ZTV20QGraphicsEllipseItem: 39 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGraphicsEllipseItem) +16 (int (*)(...))QGraphicsEllipseItem::~QGraphicsEllipseItem +24 (int (*)(...))QGraphicsEllipseItem::~QGraphicsEllipseItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsEllipseItem::boundingRect +48 (int (*)(...))QGraphicsEllipseItem::shape +56 (int (*)(...))QGraphicsEllipseItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsEllipseItem::isObscuredBy +88 (int (*)(...))QGraphicsEllipseItem::opaqueArea +96 (int (*)(...))QGraphicsEllipseItem::paint +104 (int (*)(...))QGraphicsEllipseItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsEllipseItem::supportsExtension +296 (int (*)(...))QGraphicsEllipseItem::setExtension +304 (int (*)(...))QGraphicsEllipseItem::extension + +Class QGraphicsEllipseItem + size=16 align=8 + base size=16 base align=8 +QGraphicsEllipseItem (0x0x7fc6666e5208) 0 + vptr=((& QGraphicsEllipseItem::_ZTV20QGraphicsEllipseItem) + 16) + QAbstractGraphicsShapeItem (0x0x7fc6666e5270) 0 + primary-for QGraphicsEllipseItem (0x0x7fc6666e5208) + QGraphicsItem (0x0x7fc6666e4420) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7fc6666e5270) + +Vtable for QGraphicsPolygonItem +QGraphicsPolygonItem::_ZTV20QGraphicsPolygonItem: 39 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGraphicsPolygonItem) +16 (int (*)(...))QGraphicsPolygonItem::~QGraphicsPolygonItem +24 (int (*)(...))QGraphicsPolygonItem::~QGraphicsPolygonItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsPolygonItem::boundingRect +48 (int (*)(...))QGraphicsPolygonItem::shape +56 (int (*)(...))QGraphicsPolygonItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsPolygonItem::isObscuredBy +88 (int (*)(...))QGraphicsPolygonItem::opaqueArea +96 (int (*)(...))QGraphicsPolygonItem::paint +104 (int (*)(...))QGraphicsPolygonItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsPolygonItem::supportsExtension +296 (int (*)(...))QGraphicsPolygonItem::setExtension +304 (int (*)(...))QGraphicsPolygonItem::extension + +Class QGraphicsPolygonItem + size=16 align=8 + base size=16 base align=8 +QGraphicsPolygonItem (0x0x7fc6666e52d8) 0 + vptr=((& QGraphicsPolygonItem::_ZTV20QGraphicsPolygonItem) + 16) + QAbstractGraphicsShapeItem (0x0x7fc6666e5340) 0 + primary-for QGraphicsPolygonItem (0x0x7fc6666e52d8) + QGraphicsItem (0x0x7fc6666e45a0) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7fc6666e5340) + +Vtable for QGraphicsLineItem +QGraphicsLineItem::_ZTV17QGraphicsLineItem: 39 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsLineItem) +16 (int (*)(...))QGraphicsLineItem::~QGraphicsLineItem +24 (int (*)(...))QGraphicsLineItem::~QGraphicsLineItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsLineItem::boundingRect +48 (int (*)(...))QGraphicsLineItem::shape +56 (int (*)(...))QGraphicsLineItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsLineItem::isObscuredBy +88 (int (*)(...))QGraphicsLineItem::opaqueArea +96 (int (*)(...))QGraphicsLineItem::paint +104 (int (*)(...))QGraphicsLineItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsLineItem::supportsExtension +296 (int (*)(...))QGraphicsLineItem::setExtension +304 (int (*)(...))QGraphicsLineItem::extension + +Class QGraphicsLineItem + size=16 align=8 + base size=16 base align=8 +QGraphicsLineItem (0x0x7fc6666e53a8) 0 + vptr=((& QGraphicsLineItem::_ZTV17QGraphicsLineItem) + 16) + QGraphicsItem (0x0x7fc6666e46c0) 0 + primary-for QGraphicsLineItem (0x0x7fc6666e53a8) + +Vtable for QGraphicsPixmapItem +QGraphicsPixmapItem::_ZTV19QGraphicsPixmapItem: 39 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsPixmapItem) +16 (int (*)(...))QGraphicsPixmapItem::~QGraphicsPixmapItem +24 (int (*)(...))QGraphicsPixmapItem::~QGraphicsPixmapItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsPixmapItem::boundingRect +48 (int (*)(...))QGraphicsPixmapItem::shape +56 (int (*)(...))QGraphicsPixmapItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsPixmapItem::isObscuredBy +88 (int (*)(...))QGraphicsPixmapItem::opaqueArea +96 (int (*)(...))QGraphicsPixmapItem::paint +104 (int (*)(...))QGraphicsPixmapItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsPixmapItem::supportsExtension +296 (int (*)(...))QGraphicsPixmapItem::setExtension +304 (int (*)(...))QGraphicsPixmapItem::extension + +Class QGraphicsPixmapItem + size=16 align=8 + base size=16 base align=8 +QGraphicsPixmapItem (0x0x7fc6666e5410) 0 + vptr=((& QGraphicsPixmapItem::_ZTV19QGraphicsPixmapItem) + 16) + QGraphicsItem (0x0x7fc6666e4840) 0 + primary-for QGraphicsPixmapItem (0x0x7fc6666e5410) + +Class QGraphicsTextItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsTextItem::QPrivateSignal (0x0x7fc6666e4a80) 0 empty + +Vtable for QGraphicsTextItem +QGraphicsTextItem::_ZTV17QGraphicsTextItem: 82 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsTextItem) +16 (int (*)(...))QGraphicsTextItem::metaObject +24 (int (*)(...))QGraphicsTextItem::qt_metacast +32 (int (*)(...))QGraphicsTextItem::qt_metacall +40 (int (*)(...))QGraphicsTextItem::~QGraphicsTextItem +48 (int (*)(...))QGraphicsTextItem::~QGraphicsTextItem +56 (int (*)(...))QGraphicsObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsTextItem::boundingRect +120 (int (*)(...))QGraphicsTextItem::shape +128 (int (*)(...))QGraphicsTextItem::contains +136 (int (*)(...))QGraphicsTextItem::paint +144 (int (*)(...))QGraphicsTextItem::isObscuredBy +152 (int (*)(...))QGraphicsTextItem::opaqueArea +160 (int (*)(...))QGraphicsTextItem::type +168 (int (*)(...))QGraphicsTextItem::sceneEvent +176 (int (*)(...))QGraphicsTextItem::mousePressEvent +184 (int (*)(...))QGraphicsTextItem::mouseMoveEvent +192 (int (*)(...))QGraphicsTextItem::mouseReleaseEvent +200 (int (*)(...))QGraphicsTextItem::mouseDoubleClickEvent +208 (int (*)(...))QGraphicsTextItem::contextMenuEvent +216 (int (*)(...))QGraphicsTextItem::keyPressEvent +224 (int (*)(...))QGraphicsTextItem::keyReleaseEvent +232 (int (*)(...))QGraphicsTextItem::focusInEvent +240 (int (*)(...))QGraphicsTextItem::focusOutEvent +248 (int (*)(...))QGraphicsTextItem::dragEnterEvent +256 (int (*)(...))QGraphicsTextItem::dragLeaveEvent +264 (int (*)(...))QGraphicsTextItem::dragMoveEvent +272 (int (*)(...))QGraphicsTextItem::dropEvent +280 (int (*)(...))QGraphicsTextItem::inputMethodEvent +288 (int (*)(...))QGraphicsTextItem::hoverEnterEvent +296 (int (*)(...))QGraphicsTextItem::hoverMoveEvent +304 (int (*)(...))QGraphicsTextItem::hoverLeaveEvent +312 (int (*)(...))QGraphicsTextItem::inputMethodQuery +320 (int (*)(...))QGraphicsTextItem::supportsExtension +328 (int (*)(...))QGraphicsTextItem::setExtension +336 (int (*)(...))QGraphicsTextItem::extension +344 (int (*)(...))-16 +352 (int (*)(...))(& _ZTI17QGraphicsTextItem) +360 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItemD1Ev +368 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItemD0Ev +376 (int (*)(...))QGraphicsItem::advance +384 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem12boundingRectEv +392 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem5shapeEv +400 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem8containsERK7QPointF +408 (int (*)(...))QGraphicsItem::collidesWithItem +416 (int (*)(...))QGraphicsItem::collidesWithPath +424 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem12isObscuredByEPK13QGraphicsItem +432 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem10opaqueAreaEv +440 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget +448 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem4typeEv +456 (int (*)(...))QGraphicsItem::sceneEventFilter +464 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem10sceneEventEP6QEvent +472 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem16contextMenuEventEP30QGraphicsSceneContextMenuEvent +480 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14dragEnterEventEP27QGraphicsSceneDragDropEvent +488 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14dragLeaveEventEP27QGraphicsSceneDragDropEvent +496 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13dragMoveEventEP27QGraphicsSceneDragDropEvent +504 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem9dropEventEP27QGraphicsSceneDragDropEvent +512 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem12focusInEventEP11QFocusEvent +520 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13focusOutEventEP11QFocusEvent +528 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15hoverEnterEventEP24QGraphicsSceneHoverEvent +536 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14hoverMoveEventEP24QGraphicsSceneHoverEvent +544 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15hoverLeaveEventEP24QGraphicsSceneHoverEvent +552 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13keyPressEventEP9QKeyEvent +560 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15keyReleaseEventEP9QKeyEvent +568 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15mousePressEventEP24QGraphicsSceneMouseEvent +576 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14mouseMoveEventEP24QGraphicsSceneMouseEvent +584 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem17mouseReleaseEventEP24QGraphicsSceneMouseEvent +592 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent +600 (int (*)(...))QGraphicsItem::wheelEvent +608 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem16inputMethodEventEP17QInputMethodEvent +616 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem16inputMethodQueryEN2Qt16InputMethodQueryE +624 (int (*)(...))QGraphicsItem::itemChange +632 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem17supportsExtensionEN13QGraphicsItem9ExtensionE +640 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem12setExtensionEN13QGraphicsItem9ExtensionERK8QVariant +648 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem9extensionERK8QVariant + +Class QGraphicsTextItem + size=40 align=8 + base size=40 base align=8 +QGraphicsTextItem (0x0x7fc6666e5478) 0 + vptr=((& QGraphicsTextItem::_ZTV17QGraphicsTextItem) + 16) + QGraphicsObject (0x0x7fc666751000) 0 + primary-for QGraphicsTextItem (0x0x7fc6666e5478) + QObject (0x0x7fc6666e49c0) 0 + primary-for QGraphicsObject (0x0x7fc666751000) + QGraphicsItem (0x0x7fc6666e4a20) 16 + vptr=((& QGraphicsTextItem::_ZTV17QGraphicsTextItem) + 360) + +Vtable for QGraphicsSimpleTextItem +QGraphicsSimpleTextItem::_ZTV23QGraphicsSimpleTextItem: 39 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsSimpleTextItem) +16 (int (*)(...))QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem +24 (int (*)(...))QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsSimpleTextItem::boundingRect +48 (int (*)(...))QGraphicsSimpleTextItem::shape +56 (int (*)(...))QGraphicsSimpleTextItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsSimpleTextItem::isObscuredBy +88 (int (*)(...))QGraphicsSimpleTextItem::opaqueArea +96 (int (*)(...))QGraphicsSimpleTextItem::paint +104 (int (*)(...))QGraphicsSimpleTextItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsSimpleTextItem::supportsExtension +296 (int (*)(...))QGraphicsSimpleTextItem::setExtension +304 (int (*)(...))QGraphicsSimpleTextItem::extension + +Class QGraphicsSimpleTextItem + size=16 align=8 + base size=16 base align=8 +QGraphicsSimpleTextItem (0x0x7fc6666e55b0) 0 + vptr=((& QGraphicsSimpleTextItem::_ZTV23QGraphicsSimpleTextItem) + 16) + QAbstractGraphicsShapeItem (0x0x7fc6666e5618) 0 + primary-for QGraphicsSimpleTextItem (0x0x7fc6666e55b0) + QGraphicsItem (0x0x7fc6666e4d20) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7fc6666e5618) + +Vtable for QGraphicsItemGroup +QGraphicsItemGroup::_ZTV18QGraphicsItemGroup: 39 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QGraphicsItemGroup) +16 (int (*)(...))QGraphicsItemGroup::~QGraphicsItemGroup +24 (int (*)(...))QGraphicsItemGroup::~QGraphicsItemGroup +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsItemGroup::boundingRect +48 (int (*)(...))QGraphicsItem::shape +56 (int (*)(...))QGraphicsItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsItemGroup::isObscuredBy +88 (int (*)(...))QGraphicsItemGroup::opaqueArea +96 (int (*)(...))QGraphicsItemGroup::paint +104 (int (*)(...))QGraphicsItemGroup::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsItem::supportsExtension +296 (int (*)(...))QGraphicsItem::setExtension +304 (int (*)(...))QGraphicsItem::extension + +Class QGraphicsItemGroup + size=16 align=8 + base size=16 base align=8 +QGraphicsItemGroup (0x0x7fc6666e5680) 0 + vptr=((& QGraphicsItemGroup::_ZTV18QGraphicsItemGroup) + 16) + QGraphicsItem (0x0x7fc6666e4e40) 0 + primary-for QGraphicsItemGroup (0x0x7fc6666e5680) + +Vtable for QGraphicsLayoutItem +QGraphicsLayoutItem::_ZTV19QGraphicsLayoutItem: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsLayoutItem) +16 0 +24 0 +32 (int (*)(...))QGraphicsLayoutItem::setGeometry +40 (int (*)(...))QGraphicsLayoutItem::getContentsMargins +48 (int (*)(...))QGraphicsLayoutItem::updateGeometry +56 (int (*)(...))QGraphicsLayoutItem::isEmpty +64 (int (*)(...))__cxa_pure_virtual + +Class QGraphicsLayoutItem + size=16 align=8 + base size=16 base align=8 +QGraphicsLayoutItem (0x0x7fc66678e540) 0 + vptr=((& QGraphicsLayoutItem::_ZTV19QGraphicsLayoutItem) + 16) + +Vtable for QGraphicsLayout +QGraphicsLayout::_ZTV15QGraphicsLayout: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsLayout) +16 0 +24 0 +32 (int (*)(...))QGraphicsLayoutItem::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsLayoutItem::isEmpty +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))QGraphicsLayout::invalidate +80 (int (*)(...))QGraphicsLayout::widgetEvent +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual + +Class QGraphicsLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsLayout (0x0x7fc6666e5750) 0 + vptr=((& QGraphicsLayout::_ZTV15QGraphicsLayout) + 16) + QGraphicsLayoutItem (0x0x7fc66678ec00) 0 + primary-for QGraphicsLayout (0x0x7fc6666e5750) + +Class QGraphicsAnchor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsAnchor::QPrivateSignal (0x0x7fc66678ef00) 0 empty + +Vtable for QGraphicsAnchor +QGraphicsAnchor::_ZTV15QGraphicsAnchor: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsAnchor) +16 (int (*)(...))QGraphicsAnchor::metaObject +24 (int (*)(...))QGraphicsAnchor::qt_metacast +32 (int (*)(...))QGraphicsAnchor::qt_metacall +40 (int (*)(...))QGraphicsAnchor::~QGraphicsAnchor +48 (int (*)(...))QGraphicsAnchor::~QGraphicsAnchor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QGraphicsAnchor + size=16 align=8 + base size=16 base align=8 +QGraphicsAnchor (0x0x7fc6666e57b8) 0 + vptr=((& QGraphicsAnchor::_ZTV15QGraphicsAnchor) + 16) + QObject (0x0x7fc66678eea0) 0 + primary-for QGraphicsAnchor (0x0x7fc6666e57b8) + +Vtable for QGraphicsAnchorLayout +QGraphicsAnchorLayout::_ZTV21QGraphicsAnchorLayout: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGraphicsAnchorLayout) +16 (int (*)(...))QGraphicsAnchorLayout::~QGraphicsAnchorLayout +24 (int (*)(...))QGraphicsAnchorLayout::~QGraphicsAnchorLayout +32 (int (*)(...))QGraphicsAnchorLayout::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsLayoutItem::isEmpty +64 (int (*)(...))QGraphicsAnchorLayout::sizeHint +72 (int (*)(...))QGraphicsAnchorLayout::invalidate +80 (int (*)(...))QGraphicsLayout::widgetEvent +88 (int (*)(...))QGraphicsAnchorLayout::count +96 (int (*)(...))QGraphicsAnchorLayout::itemAt +104 (int (*)(...))QGraphicsAnchorLayout::removeAt + +Class QGraphicsAnchorLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsAnchorLayout (0x0x7fc6666e5820) 0 + vptr=((& QGraphicsAnchorLayout::_ZTV21QGraphicsAnchorLayout) + 16) + QGraphicsLayout (0x0x7fc6666e5888) 0 + primary-for QGraphicsAnchorLayout (0x0x7fc6666e5820) + QGraphicsLayoutItem (0x0x7fc6663ea0c0) 0 + primary-for QGraphicsLayout (0x0x7fc6666e5888) + +Class QGraphicsEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsEffect::QPrivateSignal (0x0x7fc6663ea240) 0 empty + +Vtable for QGraphicsEffect +QGraphicsEffect::_ZTV15QGraphicsEffect: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsEffect) +16 (int (*)(...))QGraphicsEffect::metaObject +24 (int (*)(...))QGraphicsEffect::qt_metacast +32 (int (*)(...))QGraphicsEffect::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsEffect::boundingRectFor +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsEffect (0x0x7fc6666e58f0) 0 + vptr=((& QGraphicsEffect::_ZTV15QGraphicsEffect) + 16) + QObject (0x0x7fc6663ea1e0) 0 + primary-for QGraphicsEffect (0x0x7fc6666e58f0) + +Class QGraphicsColorizeEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsColorizeEffect::QPrivateSignal (0x0x7fc6663ea8a0) 0 empty + +Vtable for QGraphicsColorizeEffect +QGraphicsColorizeEffect::_ZTV23QGraphicsColorizeEffect: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsColorizeEffect) +16 (int (*)(...))QGraphicsColorizeEffect::metaObject +24 (int (*)(...))QGraphicsColorizeEffect::qt_metacast +32 (int (*)(...))QGraphicsColorizeEffect::qt_metacall +40 (int (*)(...))QGraphicsColorizeEffect::~QGraphicsColorizeEffect +48 (int (*)(...))QGraphicsColorizeEffect::~QGraphicsColorizeEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsEffect::boundingRectFor +120 (int (*)(...))QGraphicsColorizeEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsColorizeEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsColorizeEffect (0x0x7fc6666e5a90) 0 + vptr=((& QGraphicsColorizeEffect::_ZTV23QGraphicsColorizeEffect) + 16) + QGraphicsEffect (0x0x7fc6666e5af8) 0 + primary-for QGraphicsColorizeEffect (0x0x7fc6666e5a90) + QObject (0x0x7fc6663ea840) 0 + primary-for QGraphicsEffect (0x0x7fc6666e5af8) + +Class QGraphicsBlurEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsBlurEffect::QPrivateSignal (0x0x7fc6663eaa80) 0 empty + +Vtable for QGraphicsBlurEffect +QGraphicsBlurEffect::_ZTV19QGraphicsBlurEffect: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsBlurEffect) +16 (int (*)(...))QGraphicsBlurEffect::metaObject +24 (int (*)(...))QGraphicsBlurEffect::qt_metacast +32 (int (*)(...))QGraphicsBlurEffect::qt_metacall +40 (int (*)(...))QGraphicsBlurEffect::~QGraphicsBlurEffect +48 (int (*)(...))QGraphicsBlurEffect::~QGraphicsBlurEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsBlurEffect::boundingRectFor +120 (int (*)(...))QGraphicsBlurEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsBlurEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsBlurEffect (0x0x7fc6666e5b60) 0 + vptr=((& QGraphicsBlurEffect::_ZTV19QGraphicsBlurEffect) + 16) + QGraphicsEffect (0x0x7fc6666e5bc8) 0 + primary-for QGraphicsBlurEffect (0x0x7fc6666e5b60) + QObject (0x0x7fc6663eaa20) 0 + primary-for QGraphicsEffect (0x0x7fc6666e5bc8) + +Class QGraphicsDropShadowEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsDropShadowEffect::QPrivateSignal (0x0x7fc6664ab1e0) 0 empty + +Vtable for QGraphicsDropShadowEffect +QGraphicsDropShadowEffect::_ZTV25QGraphicsDropShadowEffect: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QGraphicsDropShadowEffect) +16 (int (*)(...))QGraphicsDropShadowEffect::metaObject +24 (int (*)(...))QGraphicsDropShadowEffect::qt_metacast +32 (int (*)(...))QGraphicsDropShadowEffect::qt_metacall +40 (int (*)(...))QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect +48 (int (*)(...))QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsDropShadowEffect::boundingRectFor +120 (int (*)(...))QGraphicsDropShadowEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsDropShadowEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsDropShadowEffect (0x0x7fc6666e5d68) 0 + vptr=((& QGraphicsDropShadowEffect::_ZTV25QGraphicsDropShadowEffect) + 16) + QGraphicsEffect (0x0x7fc6666e5dd0) 0 + primary-for QGraphicsDropShadowEffect (0x0x7fc6666e5d68) + QObject (0x0x7fc6664ab180) 0 + primary-for QGraphicsEffect (0x0x7fc6666e5dd0) + +Class QGraphicsOpacityEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsOpacityEffect::QPrivateSignal (0x0x7fc6664ab600) 0 empty + +Vtable for QGraphicsOpacityEffect +QGraphicsOpacityEffect::_ZTV22QGraphicsOpacityEffect: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGraphicsOpacityEffect) +16 (int (*)(...))QGraphicsOpacityEffect::metaObject +24 (int (*)(...))QGraphicsOpacityEffect::qt_metacast +32 (int (*)(...))QGraphicsOpacityEffect::qt_metacall +40 (int (*)(...))QGraphicsOpacityEffect::~QGraphicsOpacityEffect +48 (int (*)(...))QGraphicsOpacityEffect::~QGraphicsOpacityEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsEffect::boundingRectFor +120 (int (*)(...))QGraphicsOpacityEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsOpacityEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsOpacityEffect (0x0x7fc6666e5e38) 0 + vptr=((& QGraphicsOpacityEffect::_ZTV22QGraphicsOpacityEffect) + 16) + QGraphicsEffect (0x0x7fc6666e5ea0) 0 + primary-for QGraphicsOpacityEffect (0x0x7fc6666e5e38) + QObject (0x0x7fc6664ab5a0) 0 + primary-for QGraphicsEffect (0x0x7fc6666e5ea0) + +Vtable for QGraphicsGridLayout +QGraphicsGridLayout::_ZTV19QGraphicsGridLayout: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsGridLayout) +16 (int (*)(...))QGraphicsGridLayout::~QGraphicsGridLayout +24 (int (*)(...))QGraphicsGridLayout::~QGraphicsGridLayout +32 (int (*)(...))QGraphicsGridLayout::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsLayoutItem::isEmpty +64 (int (*)(...))QGraphicsGridLayout::sizeHint +72 (int (*)(...))QGraphicsGridLayout::invalidate +80 (int (*)(...))QGraphicsLayout::widgetEvent +88 (int (*)(...))QGraphicsGridLayout::count +96 (int (*)(...))QGraphicsGridLayout::itemAt +104 (int (*)(...))QGraphicsGridLayout::removeAt + +Class QGraphicsGridLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsGridLayout (0x0x7fc6666e5f08) 0 + vptr=((& QGraphicsGridLayout::_ZTV19QGraphicsGridLayout) + 16) + QGraphicsLayout (0x0x7fc6666e5f70) 0 + primary-for QGraphicsGridLayout (0x0x7fc6666e5f08) + QGraphicsLayoutItem (0x0x7fc6664ab780) 0 + primary-for QGraphicsLayout (0x0x7fc6666e5f70) + +Class QGraphicsItemAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsItemAnimation::QPrivateSignal (0x0x7fc6664ab960) 0 empty + +Vtable for QGraphicsItemAnimation +QGraphicsItemAnimation::_ZTV22QGraphicsItemAnimation: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGraphicsItemAnimation) +16 (int (*)(...))QGraphicsItemAnimation::metaObject +24 (int (*)(...))QGraphicsItemAnimation::qt_metacast +32 (int (*)(...))QGraphicsItemAnimation::qt_metacall +40 (int (*)(...))QGraphicsItemAnimation::~QGraphicsItemAnimation +48 (int (*)(...))QGraphicsItemAnimation::~QGraphicsItemAnimation +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsItemAnimation::beforeAnimationStep +120 (int (*)(...))QGraphicsItemAnimation::afterAnimationStep + +Class QGraphicsItemAnimation + size=24 align=8 + base size=24 base align=8 +QGraphicsItemAnimation (0x0x7fc6665000d0) 0 + vptr=((& QGraphicsItemAnimation::_ZTV22QGraphicsItemAnimation) + 16) + QObject (0x0x7fc6664ab900) 0 + primary-for QGraphicsItemAnimation (0x0x7fc6665000d0) + +Vtable for QGraphicsLinearLayout +QGraphicsLinearLayout::_ZTV21QGraphicsLinearLayout: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGraphicsLinearLayout) +16 (int (*)(...))QGraphicsLinearLayout::~QGraphicsLinearLayout +24 (int (*)(...))QGraphicsLinearLayout::~QGraphicsLinearLayout +32 (int (*)(...))QGraphicsLinearLayout::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsLayoutItem::isEmpty +64 (int (*)(...))QGraphicsLinearLayout::sizeHint +72 (int (*)(...))QGraphicsLinearLayout::invalidate +80 (int (*)(...))QGraphicsLayout::widgetEvent +88 (int (*)(...))QGraphicsLinearLayout::count +96 (int (*)(...))QGraphicsLinearLayout::itemAt +104 (int (*)(...))QGraphicsLinearLayout::removeAt + +Class QGraphicsLinearLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsLinearLayout (0x0x7fc666500138) 0 + vptr=((& QGraphicsLinearLayout::_ZTV21QGraphicsLinearLayout) + 16) + QGraphicsLayout (0x0x7fc6665001a0) 0 + primary-for QGraphicsLinearLayout (0x0x7fc666500138) + QGraphicsLayoutItem (0x0x7fc6664aba20) 0 + primary-for QGraphicsLayout (0x0x7fc6665001a0) + +Class QGraphicsWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsWidget::QPrivateSignal (0x0x7fc6664abd20) 0 empty + +Vtable for QGraphicsWidget +QGraphicsWidget::_ZTV15QGraphicsWidget: 93 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsWidget) +16 (int (*)(...))QGraphicsWidget::metaObject +24 (int (*)(...))QGraphicsWidget::qt_metacast +32 (int (*)(...))QGraphicsWidget::qt_metacall +40 (int (*)(...))QGraphicsWidget::~QGraphicsWidget +48 (int (*)(...))QGraphicsWidget::~QGraphicsWidget +56 (int (*)(...))QGraphicsWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsWidget::setGeometry +120 (int (*)(...))QGraphicsWidget::getContentsMargins +128 (int (*)(...))QGraphicsWidget::type +136 (int (*)(...))QGraphicsWidget::paint +144 (int (*)(...))QGraphicsWidget::paintWindowFrame +152 (int (*)(...))QGraphicsWidget::boundingRect +160 (int (*)(...))QGraphicsWidget::shape +168 (int (*)(...))QGraphicsWidget::initStyleOption +176 (int (*)(...))QGraphicsWidget::sizeHint +184 (int (*)(...))QGraphicsWidget::updateGeometry +192 (int (*)(...))QGraphicsWidget::itemChange +200 (int (*)(...))QGraphicsWidget::propertyChange +208 (int (*)(...))QGraphicsWidget::sceneEvent +216 (int (*)(...))QGraphicsWidget::windowFrameEvent +224 (int (*)(...))QGraphicsWidget::windowFrameSectionAt +232 (int (*)(...))QGraphicsWidget::changeEvent +240 (int (*)(...))QGraphicsWidget::closeEvent +248 (int (*)(...))QGraphicsWidget::focusInEvent +256 (int (*)(...))QGraphicsWidget::focusNextPrevChild +264 (int (*)(...))QGraphicsWidget::focusOutEvent +272 (int (*)(...))QGraphicsWidget::hideEvent +280 (int (*)(...))QGraphicsWidget::moveEvent +288 (int (*)(...))QGraphicsWidget::polishEvent +296 (int (*)(...))QGraphicsWidget::resizeEvent +304 (int (*)(...))QGraphicsWidget::showEvent +312 (int (*)(...))QGraphicsWidget::hoverMoveEvent +320 (int (*)(...))QGraphicsWidget::hoverLeaveEvent +328 (int (*)(...))QGraphicsWidget::grabMouseEvent +336 (int (*)(...))QGraphicsWidget::ungrabMouseEvent +344 (int (*)(...))QGraphicsWidget::grabKeyboardEvent +352 (int (*)(...))QGraphicsWidget::ungrabKeyboardEvent +360 (int (*)(...))-16 +368 (int (*)(...))(& _ZTI15QGraphicsWidget) +376 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidgetD1Ev +384 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidgetD0Ev +392 (int (*)(...))QGraphicsItem::advance +400 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget12boundingRectEv +408 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget5shapeEv +416 (int (*)(...))QGraphicsItem::contains +424 (int (*)(...))QGraphicsItem::collidesWithItem +432 (int (*)(...))QGraphicsItem::collidesWithPath +440 (int (*)(...))QGraphicsItem::isObscuredBy +448 (int (*)(...))QGraphicsItem::opaqueArea +456 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget +464 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget4typeEv +472 (int (*)(...))QGraphicsItem::sceneEventFilter +480 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10sceneEventEP6QEvent +488 (int (*)(...))QGraphicsItem::contextMenuEvent +496 (int (*)(...))QGraphicsItem::dragEnterEvent +504 (int (*)(...))QGraphicsItem::dragLeaveEvent +512 (int (*)(...))QGraphicsItem::dragMoveEvent +520 (int (*)(...))QGraphicsItem::dropEvent +528 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget12focusInEventEP11QFocusEvent +536 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget13focusOutEventEP11QFocusEvent +544 (int (*)(...))QGraphicsItem::hoverEnterEvent +552 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget14hoverMoveEventEP24QGraphicsSceneHoverEvent +560 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget15hoverLeaveEventEP24QGraphicsSceneHoverEvent +568 (int (*)(...))QGraphicsItem::keyPressEvent +576 (int (*)(...))QGraphicsItem::keyReleaseEvent +584 (int (*)(...))QGraphicsItem::mousePressEvent +592 (int (*)(...))QGraphicsItem::mouseMoveEvent +600 (int (*)(...))QGraphicsItem::mouseReleaseEvent +608 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +616 (int (*)(...))QGraphicsItem::wheelEvent +624 (int (*)(...))QGraphicsItem::inputMethodEvent +632 (int (*)(...))QGraphicsItem::inputMethodQuery +640 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant +648 (int (*)(...))QGraphicsItem::supportsExtension +656 (int (*)(...))QGraphicsItem::setExtension +664 (int (*)(...))QGraphicsItem::extension +672 (int (*)(...))-32 +680 (int (*)(...))(& _ZTI15QGraphicsWidget) +688 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidgetD1Ev +696 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidgetD0Ev +704 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget11setGeometryERK6QRectF +712 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget18getContentsMarginsEPdS0_S0_S0_ +720 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget14updateGeometryEv +728 (int (*)(...))QGraphicsLayoutItem::isEmpty +736 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget8sizeHintEN2Qt8SizeHintERK6QSizeF + +Class QGraphicsWidget + size=48 align=8 + base size=48 base align=8 +QGraphicsWidget (0x0x7fc666751c40) 0 + vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 16) + QGraphicsObject (0x0x7fc666751cb0) 0 + primary-for QGraphicsWidget (0x0x7fc666751c40) + QObject (0x0x7fc6664abc00) 0 + primary-for QGraphicsObject (0x0x7fc666751cb0) + QGraphicsItem (0x0x7fc6664abc60) 16 + vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 376) + QGraphicsLayoutItem (0x0x7fc6664abcc0) 32 + vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 688) + +Class QGraphicsProxyWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsProxyWidget::QPrivateSignal (0x0x7fc66654f1e0) 0 empty + +Vtable for QGraphicsProxyWidget +QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget: 108 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGraphicsProxyWidget) +16 (int (*)(...))QGraphicsProxyWidget::metaObject +24 (int (*)(...))QGraphicsProxyWidget::qt_metacast +32 (int (*)(...))QGraphicsProxyWidget::qt_metacall +40 (int (*)(...))QGraphicsProxyWidget::~QGraphicsProxyWidget +48 (int (*)(...))QGraphicsProxyWidget::~QGraphicsProxyWidget +56 (int (*)(...))QGraphicsProxyWidget::event +64 (int (*)(...))QGraphicsProxyWidget::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsProxyWidget::setGeometry +120 (int (*)(...))QGraphicsWidget::getContentsMargins +128 (int (*)(...))QGraphicsProxyWidget::type +136 (int (*)(...))QGraphicsProxyWidget::paint +144 (int (*)(...))QGraphicsWidget::paintWindowFrame +152 (int (*)(...))QGraphicsWidget::boundingRect +160 (int (*)(...))QGraphicsWidget::shape +168 (int (*)(...))QGraphicsWidget::initStyleOption +176 (int (*)(...))QGraphicsProxyWidget::sizeHint +184 (int (*)(...))QGraphicsWidget::updateGeometry +192 (int (*)(...))QGraphicsProxyWidget::itemChange +200 (int (*)(...))QGraphicsWidget::propertyChange +208 (int (*)(...))QGraphicsWidget::sceneEvent +216 (int (*)(...))QGraphicsWidget::windowFrameEvent +224 (int (*)(...))QGraphicsWidget::windowFrameSectionAt +232 (int (*)(...))QGraphicsWidget::changeEvent +240 (int (*)(...))QGraphicsWidget::closeEvent +248 (int (*)(...))QGraphicsProxyWidget::focusInEvent +256 (int (*)(...))QGraphicsProxyWidget::focusNextPrevChild +264 (int (*)(...))QGraphicsProxyWidget::focusOutEvent +272 (int (*)(...))QGraphicsProxyWidget::hideEvent +280 (int (*)(...))QGraphicsWidget::moveEvent +288 (int (*)(...))QGraphicsWidget::polishEvent +296 (int (*)(...))QGraphicsProxyWidget::resizeEvent +304 (int (*)(...))QGraphicsProxyWidget::showEvent +312 (int (*)(...))QGraphicsProxyWidget::hoverMoveEvent +320 (int (*)(...))QGraphicsProxyWidget::hoverLeaveEvent +328 (int (*)(...))QGraphicsProxyWidget::grabMouseEvent +336 (int (*)(...))QGraphicsProxyWidget::ungrabMouseEvent +344 (int (*)(...))QGraphicsWidget::grabKeyboardEvent +352 (int (*)(...))QGraphicsWidget::ungrabKeyboardEvent +360 (int (*)(...))QGraphicsProxyWidget::contextMenuEvent +368 (int (*)(...))QGraphicsProxyWidget::dragEnterEvent +376 (int (*)(...))QGraphicsProxyWidget::dragLeaveEvent +384 (int (*)(...))QGraphicsProxyWidget::dragMoveEvent +392 (int (*)(...))QGraphicsProxyWidget::dropEvent +400 (int (*)(...))QGraphicsProxyWidget::hoverEnterEvent +408 (int (*)(...))QGraphicsProxyWidget::mouseMoveEvent +416 (int (*)(...))QGraphicsProxyWidget::mousePressEvent +424 (int (*)(...))QGraphicsProxyWidget::mouseReleaseEvent +432 (int (*)(...))QGraphicsProxyWidget::mouseDoubleClickEvent +440 (int (*)(...))QGraphicsProxyWidget::wheelEvent +448 (int (*)(...))QGraphicsProxyWidget::keyPressEvent +456 (int (*)(...))QGraphicsProxyWidget::keyReleaseEvent +464 (int (*)(...))QGraphicsProxyWidget::inputMethodQuery +472 (int (*)(...))QGraphicsProxyWidget::inputMethodEvent +480 (int (*)(...))-16 +488 (int (*)(...))(& _ZTI20QGraphicsProxyWidget) +496 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidgetD1Ev +504 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidgetD0Ev +512 (int (*)(...))QGraphicsItem::advance +520 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget12boundingRectEv +528 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget5shapeEv +536 (int (*)(...))QGraphicsItem::contains +544 (int (*)(...))QGraphicsItem::collidesWithItem +552 (int (*)(...))QGraphicsItem::collidesWithPath +560 (int (*)(...))QGraphicsItem::isObscuredBy +568 (int (*)(...))QGraphicsItem::opaqueArea +576 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget +584 (int (*)(...))QGraphicsProxyWidget::_ZThn16_NK20QGraphicsProxyWidget4typeEv +592 (int (*)(...))QGraphicsItem::sceneEventFilter +600 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10sceneEventEP6QEvent +608 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget16contextMenuEventEP30QGraphicsSceneContextMenuEvent +616 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14dragEnterEventEP27QGraphicsSceneDragDropEvent +624 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14dragLeaveEventEP27QGraphicsSceneDragDropEvent +632 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13dragMoveEventEP27QGraphicsSceneDragDropEvent +640 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget9dropEventEP27QGraphicsSceneDragDropEvent +648 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget12focusInEventEP11QFocusEvent +656 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13focusOutEventEP11QFocusEvent +664 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15hoverEnterEventEP24QGraphicsSceneHoverEvent +672 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14hoverMoveEventEP24QGraphicsSceneHoverEvent +680 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15hoverLeaveEventEP24QGraphicsSceneHoverEvent +688 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13keyPressEventEP9QKeyEvent +696 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15keyReleaseEventEP9QKeyEvent +704 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15mousePressEventEP24QGraphicsSceneMouseEvent +712 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14mouseMoveEventEP24QGraphicsSceneMouseEvent +720 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget17mouseReleaseEventEP24QGraphicsSceneMouseEvent +728 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent +736 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget10wheelEventEP24QGraphicsSceneWheelEvent +744 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget16inputMethodEventEP17QInputMethodEvent +752 (int (*)(...))QGraphicsProxyWidget::_ZThn16_NK20QGraphicsProxyWidget16inputMethodQueryEN2Qt16InputMethodQueryE +760 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant +768 (int (*)(...))QGraphicsItem::supportsExtension +776 (int (*)(...))QGraphicsItem::setExtension +784 (int (*)(...))QGraphicsItem::extension +792 (int (*)(...))-32 +800 (int (*)(...))(& _ZTI20QGraphicsProxyWidget) +808 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidgetD1Ev +816 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidgetD0Ev +824 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidget11setGeometryERK6QRectF +832 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget18getContentsMarginsEPdS0_S0_S0_ +840 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget14updateGeometryEv +848 (int (*)(...))QGraphicsLayoutItem::isEmpty +856 (int (*)(...))QGraphicsProxyWidget::_ZThn32_NK20QGraphicsProxyWidget8sizeHintEN2Qt8SizeHintERK6QSizeF + +Class QGraphicsProxyWidget + size=48 align=8 + base size=48 base align=8 +QGraphicsProxyWidget (0x0x7fc6665002d8) 0 + vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 16) + QGraphicsWidget (0x0x7fc666751e00) 0 + primary-for QGraphicsProxyWidget (0x0x7fc6665002d8) + QGraphicsObject (0x0x7fc666751e70) 0 + primary-for QGraphicsWidget (0x0x7fc666751e00) + QObject (0x0x7fc66654f0c0) 0 + primary-for QGraphicsObject (0x0x7fc666751e70) + QGraphicsItem (0x0x7fc66654f120) 16 + vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 496) + QGraphicsLayoutItem (0x0x7fc66654f180) 32 + vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 808) + +Class QGraphicsScene::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsScene::QPrivateSignal (0x0x7fc66654f540) 0 empty + +Vtable for QGraphicsScene +QGraphicsScene::_ZTV14QGraphicsScene: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGraphicsScene) +16 (int (*)(...))QGraphicsScene::metaObject +24 (int (*)(...))QGraphicsScene::qt_metacast +32 (int (*)(...))QGraphicsScene::qt_metacall +40 (int (*)(...))QGraphicsScene::~QGraphicsScene +48 (int (*)(...))QGraphicsScene::~QGraphicsScene +56 (int (*)(...))QGraphicsScene::event +64 (int (*)(...))QGraphicsScene::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsScene::inputMethodQuery +120 (int (*)(...))QGraphicsScene::contextMenuEvent +128 (int (*)(...))QGraphicsScene::dragEnterEvent +136 (int (*)(...))QGraphicsScene::dragMoveEvent +144 (int (*)(...))QGraphicsScene::dragLeaveEvent +152 (int (*)(...))QGraphicsScene::dropEvent +160 (int (*)(...))QGraphicsScene::focusInEvent +168 (int (*)(...))QGraphicsScene::focusOutEvent +176 (int (*)(...))QGraphicsScene::helpEvent +184 (int (*)(...))QGraphicsScene::keyPressEvent +192 (int (*)(...))QGraphicsScene::keyReleaseEvent +200 (int (*)(...))QGraphicsScene::mousePressEvent +208 (int (*)(...))QGraphicsScene::mouseMoveEvent +216 (int (*)(...))QGraphicsScene::mouseReleaseEvent +224 (int (*)(...))QGraphicsScene::mouseDoubleClickEvent +232 (int (*)(...))QGraphicsScene::wheelEvent +240 (int (*)(...))QGraphicsScene::inputMethodEvent +248 (int (*)(...))QGraphicsScene::drawBackground +256 (int (*)(...))QGraphicsScene::drawForeground +264 (int (*)(...))QGraphicsScene::drawItems +272 (int (*)(...))QGraphicsScene::focusNextPrevChild + +Class QGraphicsScene + size=16 align=8 + base size=16 base align=8 +QGraphicsScene (0x0x7fc6665004e0) 0 + vptr=((& QGraphicsScene::_ZTV14QGraphicsScene) + 16) + QObject (0x0x7fc66654f4e0) 0 + primary-for QGraphicsScene (0x0x7fc6665004e0) + +Vtable for QGraphicsSceneEvent +QGraphicsSceneEvent::_ZTV19QGraphicsSceneEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsSceneEvent) +16 (int (*)(...))QGraphicsSceneEvent::~QGraphicsSceneEvent +24 (int (*)(...))QGraphicsSceneEvent::~QGraphicsSceneEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QGraphicsSceneEvent + size=24 align=8 + base size=24 base align=8 +QGraphicsSceneEvent (0x0x7fc666500f08) 0 + vptr=((& QGraphicsSceneEvent::_ZTV19QGraphicsSceneEvent) + 16) + QEvent (0x0x7fc6661d4960) 0 + primary-for QGraphicsSceneEvent (0x0x7fc666500f08) + +Vtable for QGraphicsSceneMouseEvent +QGraphicsSceneMouseEvent::_ZTV24QGraphicsSceneMouseEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QGraphicsSceneMouseEvent) +16 (int (*)(...))QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent +24 (int (*)(...))QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QGraphicsSceneMouseEvent + size=24 align=8 + base size=24 base align=8 +QGraphicsSceneMouseEvent (0x0x7fc666500f70) 0 + vptr=((& QGraphicsSceneMouseEvent::_ZTV24QGraphicsSceneMouseEvent) + 16) + QGraphicsSceneEvent (0x0x7fc666500ea0) 0 + primary-for QGraphicsSceneMouseEvent (0x0x7fc666500f70) + QEvent (0x0x7fc6661d4b40) 0 + primary-for QGraphicsSceneEvent (0x0x7fc666500ea0) + +Vtable for QGraphicsSceneWheelEvent +QGraphicsSceneWheelEvent::_ZTV24QGraphicsSceneWheelEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QGraphicsSceneWheelEvent) +16 (int (*)(...))QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent +24 (int (*)(...))QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QGraphicsSceneWheelEvent + size=24 align=8 + base size=24 base align=8 +QGraphicsSceneWheelEvent (0x0x7fc66628c000) 0 + vptr=((& QGraphicsSceneWheelEvent::_ZTV24QGraphicsSceneWheelEvent) + 16) + QGraphicsSceneEvent (0x0x7fc66628c068) 0 + primary-for QGraphicsSceneWheelEvent (0x0x7fc66628c000) + QEvent (0x0x7fc6661d4c60) 0 + primary-for QGraphicsSceneEvent (0x0x7fc66628c068) + +Vtable for QGraphicsSceneContextMenuEvent +QGraphicsSceneContextMenuEvent::_ZTV30QGraphicsSceneContextMenuEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI30QGraphicsSceneContextMenuEvent) +16 (int (*)(...))QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent +24 (int (*)(...))QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QGraphicsSceneContextMenuEvent + size=24 align=8 + base size=24 base align=8 +QGraphicsSceneContextMenuEvent (0x0x7fc66628c0d0) 0 + vptr=((& QGraphicsSceneContextMenuEvent::_ZTV30QGraphicsSceneContextMenuEvent) + 16) + QGraphicsSceneEvent (0x0x7fc66628c138) 0 + primary-for QGraphicsSceneContextMenuEvent (0x0x7fc66628c0d0) + QEvent (0x0x7fc6661d4d80) 0 + primary-for QGraphicsSceneEvent (0x0x7fc66628c138) + +Vtable for QGraphicsSceneHoverEvent +QGraphicsSceneHoverEvent::_ZTV24QGraphicsSceneHoverEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QGraphicsSceneHoverEvent) +16 (int (*)(...))QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent +24 (int (*)(...))QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QGraphicsSceneHoverEvent + size=24 align=8 + base size=24 base align=8 +QGraphicsSceneHoverEvent (0x0x7fc66628c1a0) 0 + vptr=((& QGraphicsSceneHoverEvent::_ZTV24QGraphicsSceneHoverEvent) + 16) + QGraphicsSceneEvent (0x0x7fc66628c208) 0 + primary-for QGraphicsSceneHoverEvent (0x0x7fc66628c1a0) + QEvent (0x0x7fc6661d4ea0) 0 + primary-for QGraphicsSceneEvent (0x0x7fc66628c208) + +Vtable for QGraphicsSceneHelpEvent +QGraphicsSceneHelpEvent::_ZTV23QGraphicsSceneHelpEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsSceneHelpEvent) +16 (int (*)(...))QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent +24 (int (*)(...))QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QGraphicsSceneHelpEvent + size=24 align=8 + base size=24 base align=8 +QGraphicsSceneHelpEvent (0x0x7fc66628c270) 0 + vptr=((& QGraphicsSceneHelpEvent::_ZTV23QGraphicsSceneHelpEvent) + 16) + QGraphicsSceneEvent (0x0x7fc66628c2d8) 0 + primary-for QGraphicsSceneHelpEvent (0x0x7fc66628c270) + QEvent (0x0x7fc6661d41e0) 0 + primary-for QGraphicsSceneEvent (0x0x7fc66628c2d8) + +Vtable for QGraphicsSceneDragDropEvent +QGraphicsSceneDragDropEvent::_ZTV27QGraphicsSceneDragDropEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QGraphicsSceneDragDropEvent) +16 (int (*)(...))QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent +24 (int (*)(...))QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QGraphicsSceneDragDropEvent + size=24 align=8 + base size=24 base align=8 +QGraphicsSceneDragDropEvent (0x0x7fc66628c340) 0 + vptr=((& QGraphicsSceneDragDropEvent::_ZTV27QGraphicsSceneDragDropEvent) + 16) + QGraphicsSceneEvent (0x0x7fc66628c3a8) 0 + primary-for QGraphicsSceneDragDropEvent (0x0x7fc66628c340) + QEvent (0x0x7fc6662b20c0) 0 + primary-for QGraphicsSceneEvent (0x0x7fc66628c3a8) + +Vtable for QGraphicsSceneResizeEvent +QGraphicsSceneResizeEvent::_ZTV25QGraphicsSceneResizeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QGraphicsSceneResizeEvent) +16 (int (*)(...))QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent +24 (int (*)(...))QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QGraphicsSceneResizeEvent + size=24 align=8 + base size=24 base align=8 +QGraphicsSceneResizeEvent (0x0x7fc66628c410) 0 + vptr=((& QGraphicsSceneResizeEvent::_ZTV25QGraphicsSceneResizeEvent) + 16) + QGraphicsSceneEvent (0x0x7fc66628c478) 0 + primary-for QGraphicsSceneResizeEvent (0x0x7fc66628c410) + QEvent (0x0x7fc6662b21e0) 0 + primary-for QGraphicsSceneEvent (0x0x7fc66628c478) + +Vtable for QGraphicsSceneMoveEvent +QGraphicsSceneMoveEvent::_ZTV23QGraphicsSceneMoveEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsSceneMoveEvent) +16 (int (*)(...))QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent +24 (int (*)(...))QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QGraphicsSceneMoveEvent + size=24 align=8 + base size=24 base align=8 +QGraphicsSceneMoveEvent (0x0x7fc66628c4e0) 0 + vptr=((& QGraphicsSceneMoveEvent::_ZTV23QGraphicsSceneMoveEvent) + 16) + QGraphicsSceneEvent (0x0x7fc66628c548) 0 + primary-for QGraphicsSceneMoveEvent (0x0x7fc66628c4e0) + QEvent (0x0x7fc6662b2300) 0 + primary-for QGraphicsSceneEvent (0x0x7fc66628c548) + +Class QGraphicsTransform::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsTransform::QPrivateSignal (0x0x7fc6662b2480) 0 empty + +Vtable for QGraphicsTransform +QGraphicsTransform::_ZTV18QGraphicsTransform: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QGraphicsTransform) +16 (int (*)(...))QGraphicsTransform::metaObject +24 (int (*)(...))QGraphicsTransform::qt_metacast +32 (int (*)(...))QGraphicsTransform::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGraphicsTransform + size=16 align=8 + base size=16 base align=8 +QGraphicsTransform (0x0x7fc66628c5b0) 0 + vptr=((& QGraphicsTransform::_ZTV18QGraphicsTransform) + 16) + QObject (0x0x7fc6662b2420) 0 + primary-for QGraphicsTransform (0x0x7fc66628c5b0) + +Class QGraphicsScale::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsScale::QPrivateSignal (0x0x7fc6662b2660) 0 empty + +Vtable for QGraphicsScale +QGraphicsScale::_ZTV14QGraphicsScale: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGraphicsScale) +16 (int (*)(...))QGraphicsScale::metaObject +24 (int (*)(...))QGraphicsScale::qt_metacast +32 (int (*)(...))QGraphicsScale::qt_metacall +40 (int (*)(...))QGraphicsScale::~QGraphicsScale +48 (int (*)(...))QGraphicsScale::~QGraphicsScale +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsScale::applyTo + +Class QGraphicsScale + size=16 align=8 + base size=16 base align=8 +QGraphicsScale (0x0x7fc66628c618) 0 + vptr=((& QGraphicsScale::_ZTV14QGraphicsScale) + 16) + QGraphicsTransform (0x0x7fc66628c680) 0 + primary-for QGraphicsScale (0x0x7fc66628c618) + QObject (0x0x7fc6662b2600) 0 + primary-for QGraphicsTransform (0x0x7fc66628c680) + +Class QGraphicsRotation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsRotation::QPrivateSignal (0x0x7fc6662b2840) 0 empty + +Vtable for QGraphicsRotation +QGraphicsRotation::_ZTV17QGraphicsRotation: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsRotation) +16 (int (*)(...))QGraphicsRotation::metaObject +24 (int (*)(...))QGraphicsRotation::qt_metacast +32 (int (*)(...))QGraphicsRotation::qt_metacall +40 (int (*)(...))QGraphicsRotation::~QGraphicsRotation +48 (int (*)(...))QGraphicsRotation::~QGraphicsRotation +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsRotation::applyTo + +Class QGraphicsRotation + size=16 align=8 + base size=16 base align=8 +QGraphicsRotation (0x0x7fc66628c6e8) 0 + vptr=((& QGraphicsRotation::_ZTV17QGraphicsRotation) + 16) + QGraphicsTransform (0x0x7fc66628c750) 0 + primary-for QGraphicsRotation (0x0x7fc66628c6e8) + QObject (0x0x7fc6662b27e0) 0 + primary-for QGraphicsTransform (0x0x7fc66628c750) + +Class QScrollArea::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScrollArea::QPrivateSignal (0x0x7fc6662b2a80) 0 empty + +Vtable for QScrollArea +QScrollArea::_ZTV11QScrollArea: 69 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QScrollArea) +16 (int (*)(...))QScrollArea::metaObject +24 (int (*)(...))QScrollArea::qt_metacast +32 (int (*)(...))QScrollArea::qt_metacall +40 (int (*)(...))QScrollArea::~QScrollArea +48 (int (*)(...))QScrollArea::~QScrollArea +56 (int (*)(...))QScrollArea::event +64 (int (*)(...))QScrollArea::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractScrollArea::mousePressEvent +176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent +184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent +192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractScrollArea::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QScrollArea::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractScrollArea::dragEnterEvent +320 (int (*)(...))QAbstractScrollArea::dragMoveEvent +328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent +336 (int (*)(...))QAbstractScrollArea::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QScrollArea::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QAbstractScrollArea::viewportEvent +456 (int (*)(...))QScrollArea::scrollContentsBy +464 (int (*)(...))QScrollArea::viewportSizeHint +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QScrollArea) +488 (int (*)(...))QScrollArea::_ZThn16_N11QScrollAreaD1Ev +496 (int (*)(...))QScrollArea::_ZThn16_N11QScrollAreaD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QScrollArea + size=40 align=8 + base size=40 base align=8 +QScrollArea (0x0x7fc66628c7b8) 0 + vptr=((& QScrollArea::_ZTV11QScrollArea) + 16) + QAbstractScrollArea (0x0x7fc66628c820) 0 + primary-for QScrollArea (0x0x7fc66628c7b8) + QFrame (0x0x7fc66628c888) 0 + primary-for QAbstractScrollArea (0x0x7fc66628c820) + QWidget (0x0x7fc66656b620) 0 + primary-for QFrame (0x0x7fc66628c888) + QObject (0x0x7fc6662b29c0) 0 + primary-for QWidget (0x0x7fc66656b620) + QPaintDevice (0x0x7fc6662b2a20) 16 + vptr=((& QScrollArea::_ZTV11QScrollArea) + 488) + +Class QGraphicsView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsView::QPrivateSignal (0x0x7fc6662b2cc0) 0 empty + +Vtable for QGraphicsView +QGraphicsView::_ZTV13QGraphicsView: 72 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QGraphicsView) +16 (int (*)(...))QGraphicsView::metaObject +24 (int (*)(...))QGraphicsView::qt_metacast +32 (int (*)(...))QGraphicsView::qt_metacall +40 (int (*)(...))QGraphicsView::~QGraphicsView +48 (int (*)(...))QGraphicsView::~QGraphicsView +56 (int (*)(...))QGraphicsView::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QGraphicsView::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QGraphicsView::mousePressEvent +176 (int (*)(...))QGraphicsView::mouseReleaseEvent +184 (int (*)(...))QGraphicsView::mouseDoubleClickEvent +192 (int (*)(...))QGraphicsView::mouseMoveEvent +200 (int (*)(...))QGraphicsView::wheelEvent +208 (int (*)(...))QGraphicsView::keyPressEvent +216 (int (*)(...))QGraphicsView::keyReleaseEvent +224 (int (*)(...))QGraphicsView::focusInEvent +232 (int (*)(...))QGraphicsView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QGraphicsView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QGraphicsView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QGraphicsView::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QGraphicsView::dragEnterEvent +320 (int (*)(...))QGraphicsView::dragMoveEvent +328 (int (*)(...))QGraphicsView::dragLeaveEvent +336 (int (*)(...))QGraphicsView::dropEvent +344 (int (*)(...))QGraphicsView::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QGraphicsView::inputMethodEvent +416 (int (*)(...))QGraphicsView::inputMethodQuery +424 (int (*)(...))QGraphicsView::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QGraphicsView::setupViewport +448 (int (*)(...))QGraphicsView::viewportEvent +456 (int (*)(...))QGraphicsView::scrollContentsBy +464 (int (*)(...))QAbstractScrollArea::viewportSizeHint +472 (int (*)(...))QGraphicsView::drawBackground +480 (int (*)(...))QGraphicsView::drawForeground +488 (int (*)(...))QGraphicsView::drawItems +496 (int (*)(...))-16 +504 (int (*)(...))(& _ZTI13QGraphicsView) +512 (int (*)(...))QGraphicsView::_ZThn16_N13QGraphicsViewD1Ev +520 (int (*)(...))QGraphicsView::_ZThn16_N13QGraphicsViewD0Ev +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QGraphicsView + size=40 align=8 + base size=40 base align=8 +QGraphicsView (0x0x7fc66628c8f0) 0 + vptr=((& QGraphicsView::_ZTV13QGraphicsView) + 16) + QAbstractScrollArea (0x0x7fc66628c958) 0 + primary-for QGraphicsView (0x0x7fc66628c8f0) + QFrame (0x0x7fc66628c9c0) 0 + primary-for QAbstractScrollArea (0x0x7fc66628c958) + QWidget (0x0x7fc66656b690) 0 + primary-for QFrame (0x0x7fc66628c9c0) + QObject (0x0x7fc6662b2c00) 0 + primary-for QWidget (0x0x7fc66656b690) + QPaintDevice (0x0x7fc6662b2c60) 16 + vptr=((& QGraphicsView::_ZTV13QGraphicsView) + 512) + +Class QGroupBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGroupBox::QPrivateSignal (0x0x7fc66633dd20) 0 empty + +Vtable for QGroupBox +QGroupBox::_ZTV9QGroupBox: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QGroupBox) +16 (int (*)(...))QGroupBox::metaObject +24 (int (*)(...))QGroupBox::qt_metacast +32 (int (*)(...))QGroupBox::qt_metacall +40 (int (*)(...))QGroupBox::~QGroupBox +48 (int (*)(...))QGroupBox::~QGroupBox +56 (int (*)(...))QGroupBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QGroupBox::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QGroupBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QGroupBox::mousePressEvent +176 (int (*)(...))QGroupBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QGroupBox::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QGroupBox::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QGroupBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QGroupBox::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QGroupBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QGroupBox::initStyleOption +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI9QGroupBox) +456 (int (*)(...))QGroupBox::_ZThn16_N9QGroupBoxD1Ev +464 (int (*)(...))QGroupBox::_ZThn16_N9QGroupBoxD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QGroupBox + size=40 align=8 + base size=40 base align=8 +QGroupBox (0x0x7fc66628cc98) 0 + vptr=((& QGroupBox::_ZTV9QGroupBox) + 16) + QWidget (0x0x7fc66656be00) 0 + primary-for QGroupBox (0x0x7fc66628cc98) + QObject (0x0x7fc66633dc60) 0 + primary-for QWidget (0x0x7fc66656be00) + QPaintDevice (0x0x7fc66633dcc0) 16 + vptr=((& QGroupBox::_ZTV9QGroupBox) + 456) + +Class QHeaderView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHeaderView::QPrivateSignal (0x0x7fc66633df60) 0 empty + +Vtable for QHeaderView +QHeaderView::_ZTV11QHeaderView: 112 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHeaderView) +16 (int (*)(...))QHeaderView::metaObject +24 (int (*)(...))QHeaderView::qt_metacast +32 (int (*)(...))QHeaderView::qt_metacall +40 (int (*)(...))QHeaderView::~QHeaderView +48 (int (*)(...))QHeaderView::~QHeaderView +56 (int (*)(...))QHeaderView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QAbstractItemView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QHeaderView::setVisible +128 (int (*)(...))QHeaderView::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QHeaderView::mousePressEvent +176 (int (*)(...))QHeaderView::mouseReleaseEvent +184 (int (*)(...))QHeaderView::mouseDoubleClickEvent +192 (int (*)(...))QHeaderView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QHeaderView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QHeaderView::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QHeaderView::viewportEvent +456 (int (*)(...))QHeaderView::scrollContentsBy +464 (int (*)(...))QAbstractItemView::viewportSizeHint +472 (int (*)(...))QHeaderView::setModel +480 (int (*)(...))QAbstractItemView::setSelectionModel +488 (int (*)(...))QAbstractItemView::keyboardSearch +496 (int (*)(...))QHeaderView::visualRect +504 (int (*)(...))QHeaderView::scrollTo +512 (int (*)(...))QHeaderView::indexAt +520 (int (*)(...))QAbstractItemView::sizeHintForRow +528 (int (*)(...))QAbstractItemView::sizeHintForColumn +536 (int (*)(...))QAbstractItemView::itemDelegateForIndex +544 (int (*)(...))QHeaderView::reset +552 (int (*)(...))QAbstractItemView::setRootIndex +560 (int (*)(...))QHeaderView::doItemsLayout +568 (int (*)(...))QAbstractItemView::selectAll +576 (int (*)(...))QHeaderView::dataChanged +584 (int (*)(...))QHeaderView::rowsInserted +592 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +600 (int (*)(...))QAbstractItemView::selectionChanged +608 (int (*)(...))QHeaderView::currentChanged +616 (int (*)(...))QAbstractItemView::updateEditorData +624 (int (*)(...))QAbstractItemView::updateEditorGeometries +632 (int (*)(...))QHeaderView::updateGeometries +640 (int (*)(...))QAbstractItemView::verticalScrollbarAction +648 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +656 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +664 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +672 (int (*)(...))QAbstractItemView::closeEditor +680 (int (*)(...))QAbstractItemView::commitData +688 (int (*)(...))QAbstractItemView::editorDestroyed +696 (int (*)(...))QHeaderView::moveCursor +704 (int (*)(...))QHeaderView::horizontalOffset +712 (int (*)(...))QHeaderView::verticalOffset +720 (int (*)(...))QHeaderView::isIndexHidden +728 (int (*)(...))QHeaderView::setSelection +736 (int (*)(...))QHeaderView::visualRegionForSelection +744 (int (*)(...))QAbstractItemView::selectedIndexes +752 (int (*)(...))QAbstractItemView::edit +760 (int (*)(...))QAbstractItemView::selectionCommand +768 (int (*)(...))QAbstractItemView::startDrag +776 (int (*)(...))QAbstractItemView::initViewItemOption +784 (int (*)(...))QHeaderView::paintSection +792 (int (*)(...))QHeaderView::sectionSizeFromContents +800 (int (*)(...))QHeaderView::initStyleOptionForIndex +808 (int (*)(...))QHeaderView::initStyleOption +816 (int (*)(...))-16 +824 (int (*)(...))(& _ZTI11QHeaderView) +832 (int (*)(...))QHeaderView::_ZThn16_N11QHeaderViewD1Ev +840 (int (*)(...))QHeaderView::_ZThn16_N11QHeaderViewD0Ev +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +880 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +888 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QHeaderView + size=40 align=8 + base size=40 base align=8 +QHeaderView (0x0x7fc66628cd00) 0 + vptr=((& QHeaderView::_ZTV11QHeaderView) + 16) + QAbstractItemView (0x0x7fc66628cd68) 0 + primary-for QHeaderView (0x0x7fc66628cd00) + QAbstractScrollArea (0x0x7fc66628cdd0) 0 + primary-for QAbstractItemView (0x0x7fc66628cd68) + QFrame (0x0x7fc66628ce38) 0 + primary-for QAbstractScrollArea (0x0x7fc66628cdd0) + QWidget (0x0x7fc66656be70) 0 + primary-for QFrame (0x0x7fc66628ce38) + QObject (0x0x7fc66633dea0) 0 + primary-for QWidget (0x0x7fc66656be70) + QPaintDevice (0x0x7fc66633df00) 16 + vptr=((& QHeaderView::_ZTV11QHeaderView) + 832) + +Class QLineEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLineEdit::QPrivateSignal (0x0x7fc66602d420) 0 empty + +Vtable for QLineEdit +QLineEdit::_ZTV9QLineEdit: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QLineEdit) +16 (int (*)(...))QLineEdit::metaObject +24 (int (*)(...))QLineEdit::qt_metacast +32 (int (*)(...))QLineEdit::qt_metacall +40 (int (*)(...))QLineEdit::~QLineEdit +48 (int (*)(...))QLineEdit::~QLineEdit +56 (int (*)(...))QLineEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QLineEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QLineEdit::sizeHint +136 (int (*)(...))QLineEdit::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QLineEdit::mousePressEvent +176 (int (*)(...))QLineEdit::mouseReleaseEvent +184 (int (*)(...))QLineEdit::mouseDoubleClickEvent +192 (int (*)(...))QLineEdit::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QLineEdit::keyPressEvent +216 (int (*)(...))QLineEdit::keyReleaseEvent +224 (int (*)(...))QLineEdit::focusInEvent +232 (int (*)(...))QLineEdit::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QLineEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QLineEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QLineEdit::dragEnterEvent +320 (int (*)(...))QLineEdit::dragMoveEvent +328 (int (*)(...))QLineEdit::dragLeaveEvent +336 (int (*)(...))QLineEdit::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QLineEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QLineEdit::inputMethodEvent +416 (int (*)(...))QLineEdit::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QLineEdit::initStyleOption +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI9QLineEdit) +456 (int (*)(...))QLineEdit::_ZThn16_N9QLineEditD1Ev +464 (int (*)(...))QLineEdit::_ZThn16_N9QLineEditD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QLineEdit + size=40 align=8 + base size=40 base align=8 +QLineEdit (0x0x7fc66628cea0) 0 + vptr=((& QLineEdit::_ZTV9QLineEdit) + 16) + QWidget (0x0x7fc666004150) 0 + primary-for QLineEdit (0x0x7fc66628cea0) + QObject (0x0x7fc66602d360) 0 + primary-for QWidget (0x0x7fc666004150) + QPaintDevice (0x0x7fc66602d3c0) 16 + vptr=((& QLineEdit::_ZTV9QLineEdit) + 456) + +Class QInputDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputDialog::QPrivateSignal (0x0x7fc66602d7e0) 0 empty + +Vtable for QInputDialog +QInputDialog::_ZTV12QInputDialog: 69 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputDialog) +16 (int (*)(...))QInputDialog::metaObject +24 (int (*)(...))QInputDialog::qt_metacast +32 (int (*)(...))QInputDialog::qt_metacall +40 (int (*)(...))QInputDialog::~QInputDialog +48 (int (*)(...))QInputDialog::~QInputDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QInputDialog::setVisible +128 (int (*)(...))QInputDialog::sizeHint +136 (int (*)(...))QInputDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QInputDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI12QInputDialog) +488 (int (*)(...))QInputDialog::_ZThn16_N12QInputDialogD1Ev +496 (int (*)(...))QInputDialog::_ZThn16_N12QInputDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QInputDialog + size=40 align=8 + base size=40 base align=8 +QInputDialog (0x0x7fc66628cf08) 0 + vptr=((& QInputDialog::_ZTV12QInputDialog) + 16) + QDialog (0x0x7fc66628cf70) 0 + primary-for QInputDialog (0x0x7fc66628cf08) + QWidget (0x0x7fc666004460) 0 + primary-for QDialog (0x0x7fc66628cf70) + QObject (0x0x7fc66602d720) 0 + primary-for QWidget (0x0x7fc666004460) + QPaintDevice (0x0x7fc66602d780) 16 + vptr=((& QInputDialog::_ZTV12QInputDialog) + 488) + +Class QItemDelegate::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemDelegate::QPrivateSignal (0x0x7fc66602dd80) 0 empty + +Vtable for QItemDelegate +QItemDelegate::_ZTV13QItemDelegate: 28 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QItemDelegate) +16 (int (*)(...))QItemDelegate::metaObject +24 (int (*)(...))QItemDelegate::qt_metacast +32 (int (*)(...))QItemDelegate::qt_metacall +40 (int (*)(...))QItemDelegate::~QItemDelegate +48 (int (*)(...))QItemDelegate::~QItemDelegate +56 (int (*)(...))QObject::event +64 (int (*)(...))QItemDelegate::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemDelegate::paint +120 (int (*)(...))QItemDelegate::sizeHint +128 (int (*)(...))QItemDelegate::createEditor +136 (int (*)(...))QAbstractItemDelegate::destroyEditor +144 (int (*)(...))QItemDelegate::setEditorData +152 (int (*)(...))QItemDelegate::setModelData +160 (int (*)(...))QItemDelegate::updateEditorGeometry +168 (int (*)(...))QItemDelegate::editorEvent +176 (int (*)(...))QAbstractItemDelegate::helpEvent +184 (int (*)(...))QAbstractItemDelegate::paintingRoles +192 (int (*)(...))QItemDelegate::drawDisplay +200 (int (*)(...))QItemDelegate::drawDecoration +208 (int (*)(...))QItemDelegate::drawFocus +216 (int (*)(...))QItemDelegate::drawCheck + +Class QItemDelegate + size=16 align=8 + base size=16 base align=8 +QItemDelegate (0x0x7fc666081138) 0 + vptr=((& QItemDelegate::_ZTV13QItemDelegate) + 16) + QAbstractItemDelegate (0x0x7fc6660811a0) 0 + primary-for QItemDelegate (0x0x7fc666081138) + QObject (0x0x7fc66602dd20) 0 + primary-for QAbstractItemDelegate (0x0x7fc6660811a0) + +Vtable for QItemEditorCreatorBase +QItemEditorCreatorBase::_ZTV22QItemEditorCreatorBase: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QItemEditorCreatorBase) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QItemEditorCreatorBase + size=8 align=8 + base size=8 base align=8 +QItemEditorCreatorBase (0x0x7fc66602df00) 0 nearly-empty + vptr=((& QItemEditorCreatorBase::_ZTV22QItemEditorCreatorBase) + 16) + +Vtable for QItemEditorFactory +QItemEditorFactory::_ZTV18QItemEditorFactory: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QItemEditorFactory) +16 (int (*)(...))QItemEditorFactory::~QItemEditorFactory +24 (int (*)(...))QItemEditorFactory::~QItemEditorFactory +32 (int (*)(...))QItemEditorFactory::createEditor +40 (int (*)(...))QItemEditorFactory::valuePropertyName + +Class QItemEditorFactory + size=16 align=8 + base size=16 base align=8 +QItemEditorFactory (0x0x7fc6660ea2a0) 0 + vptr=((& QItemEditorFactory::_ZTV18QItemEditorFactory) + 16) + +Class QKeySequenceEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QKeySequenceEdit::QPrivateSignal (0x0x7fc6660ea780) 0 empty + +Vtable for QKeySequenceEdit +QKeySequenceEdit::_ZTV16QKeySequenceEdit: 64 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QKeySequenceEdit) +16 (int (*)(...))QKeySequenceEdit::metaObject +24 (int (*)(...))QKeySequenceEdit::qt_metacast +32 (int (*)(...))QKeySequenceEdit::qt_metacall +40 (int (*)(...))QKeySequenceEdit::~QKeySequenceEdit +48 (int (*)(...))QKeySequenceEdit::~QKeySequenceEdit +56 (int (*)(...))QKeySequenceEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QKeySequenceEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QKeySequenceEdit::keyPressEvent +216 (int (*)(...))QKeySequenceEdit::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI16QKeySequenceEdit) +448 (int (*)(...))QKeySequenceEdit::_ZThn16_N16QKeySequenceEditD1Ev +456 (int (*)(...))QKeySequenceEdit::_ZThn16_N16QKeySequenceEditD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QKeySequenceEdit + size=40 align=8 + base size=40 base align=8 +QKeySequenceEdit (0x0x7fc6660812d8) 0 + vptr=((& QKeySequenceEdit::_ZTV16QKeySequenceEdit) + 16) + QWidget (0x0x7fc666004770) 0 + primary-for QKeySequenceEdit (0x0x7fc6660812d8) + QObject (0x0x7fc6660ea6c0) 0 + primary-for QWidget (0x0x7fc666004770) + QPaintDevice (0x0x7fc6660ea720) 16 + vptr=((& QKeySequenceEdit::_ZTV16QKeySequenceEdit) + 448) + +Class QLabel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLabel::QPrivateSignal (0x0x7fc6660ea9c0) 0 empty + +Vtable for QLabel +QLabel::_ZTV6QLabel: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QLabel) +16 (int (*)(...))QLabel::metaObject +24 (int (*)(...))QLabel::qt_metacast +32 (int (*)(...))QLabel::qt_metacall +40 (int (*)(...))QLabel::~QLabel +48 (int (*)(...))QLabel::~QLabel +56 (int (*)(...))QLabel::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QLabel::sizeHint +136 (int (*)(...))QLabel::minimumSizeHint +144 (int (*)(...))QLabel::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QLabel::mousePressEvent +176 (int (*)(...))QLabel::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QLabel::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QLabel::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QLabel::focusInEvent +232 (int (*)(...))QLabel::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QLabel::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QLabel::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QLabel::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QLabel::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI6QLabel) +456 (int (*)(...))QLabel::_ZThn16_N6QLabelD1Ev +464 (int (*)(...))QLabel::_ZThn16_N6QLabelD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QLabel + size=40 align=8 + base size=40 base align=8 +QLabel (0x0x7fc666081340) 0 + vptr=((& QLabel::_ZTV6QLabel) + 16) + QFrame (0x0x7fc6660813a8) 0 + primary-for QLabel (0x0x7fc666081340) + QWidget (0x0x7fc6660047e0) 0 + primary-for QFrame (0x0x7fc6660813a8) + QObject (0x0x7fc6660ea900) 0 + primary-for QWidget (0x0x7fc6660047e0) + QPaintDevice (0x0x7fc6660ea960) 16 + vptr=((& QLabel::_ZTV6QLabel) + 456) + +Class QLCDNumber::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLCDNumber::QPrivateSignal (0x0x7fc6660eacc0) 0 empty + +Vtable for QLCDNumber +QLCDNumber::_ZTV10QLCDNumber: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QLCDNumber) +16 (int (*)(...))QLCDNumber::metaObject +24 (int (*)(...))QLCDNumber::qt_metacast +32 (int (*)(...))QLCDNumber::qt_metacall +40 (int (*)(...))QLCDNumber::~QLCDNumber +48 (int (*)(...))QLCDNumber::~QLCDNumber +56 (int (*)(...))QLCDNumber::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QLCDNumber::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QLCDNumber::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI10QLCDNumber) +456 (int (*)(...))QLCDNumber::_ZThn16_N10QLCDNumberD1Ev +464 (int (*)(...))QLCDNumber::_ZThn16_N10QLCDNumberD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QLCDNumber + size=40 align=8 + base size=40 base align=8 +QLCDNumber (0x0x7fc666081410) 0 + vptr=((& QLCDNumber::_ZTV10QLCDNumber) + 16) + QFrame (0x0x7fc666081478) 0 + primary-for QLCDNumber (0x0x7fc666081410) + QWidget (0x0x7fc666004850) 0 + primary-for QFrame (0x0x7fc666081478) + QObject (0x0x7fc6660eac00) 0 + primary-for QWidget (0x0x7fc666004850) + QPaintDevice (0x0x7fc6660eac60) 16 + vptr=((& QLCDNumber::_ZTV10QLCDNumber) + 456) + +Class QListView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QListView::QPrivateSignal (0x0x7fc66615f0c0) 0 empty + +Vtable for QListView +QListView::_ZTV9QListView: 108 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QListView) +16 (int (*)(...))QListView::metaObject +24 (int (*)(...))QListView::qt_metacast +32 (int (*)(...))QListView::qt_metacall +40 (int (*)(...))QListView::~QListView +48 (int (*)(...))QListView::~QListView +56 (int (*)(...))QListView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QListView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QListView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QListView::mouseMoveEvent +200 (int (*)(...))QListView::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QListView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QListView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QListView::dragMoveEvent +328 (int (*)(...))QListView::dragLeaveEvent +336 (int (*)(...))QListView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QAbstractItemView::viewportEvent +456 (int (*)(...))QListView::scrollContentsBy +464 (int (*)(...))QListView::viewportSizeHint +472 (int (*)(...))QAbstractItemView::setModel +480 (int (*)(...))QAbstractItemView::setSelectionModel +488 (int (*)(...))QAbstractItemView::keyboardSearch +496 (int (*)(...))QListView::visualRect +504 (int (*)(...))QListView::scrollTo +512 (int (*)(...))QListView::indexAt +520 (int (*)(...))QAbstractItemView::sizeHintForRow +528 (int (*)(...))QAbstractItemView::sizeHintForColumn +536 (int (*)(...))QAbstractItemView::itemDelegateForIndex +544 (int (*)(...))QListView::reset +552 (int (*)(...))QListView::setRootIndex +560 (int (*)(...))QListView::doItemsLayout +568 (int (*)(...))QAbstractItemView::selectAll +576 (int (*)(...))QListView::dataChanged +584 (int (*)(...))QListView::rowsInserted +592 (int (*)(...))QListView::rowsAboutToBeRemoved +600 (int (*)(...))QListView::selectionChanged +608 (int (*)(...))QListView::currentChanged +616 (int (*)(...))QAbstractItemView::updateEditorData +624 (int (*)(...))QAbstractItemView::updateEditorGeometries +632 (int (*)(...))QListView::updateGeometries +640 (int (*)(...))QAbstractItemView::verticalScrollbarAction +648 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +656 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +664 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +672 (int (*)(...))QAbstractItemView::closeEditor +680 (int (*)(...))QAbstractItemView::commitData +688 (int (*)(...))QAbstractItemView::editorDestroyed +696 (int (*)(...))QListView::moveCursor +704 (int (*)(...))QListView::horizontalOffset +712 (int (*)(...))QListView::verticalOffset +720 (int (*)(...))QListView::isIndexHidden +728 (int (*)(...))QListView::setSelection +736 (int (*)(...))QListView::visualRegionForSelection +744 (int (*)(...))QListView::selectedIndexes +752 (int (*)(...))QAbstractItemView::edit +760 (int (*)(...))QAbstractItemView::selectionCommand +768 (int (*)(...))QListView::startDrag +776 (int (*)(...))QListView::initViewItemOption +784 (int (*)(...))-16 +792 (int (*)(...))(& _ZTI9QListView) +800 (int (*)(...))QListView::_ZThn16_N9QListViewD1Ev +808 (int (*)(...))QListView::_ZThn16_N9QListViewD0Ev +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QListView + size=40 align=8 + base size=40 base align=8 +QListView (0x0x7fc6660814e0) 0 + vptr=((& QListView::_ZTV9QListView) + 16) + QAbstractItemView (0x0x7fc666081548) 0 + primary-for QListView (0x0x7fc6660814e0) + QAbstractScrollArea (0x0x7fc6660815b0) 0 + primary-for QAbstractItemView (0x0x7fc666081548) + QFrame (0x0x7fc666081618) 0 + primary-for QAbstractScrollArea (0x0x7fc6660815b0) + QWidget (0x0x7fc666004bd0) 0 + primary-for QFrame (0x0x7fc666081618) + QObject (0x0x7fc66615f000) 0 + primary-for QWidget (0x0x7fc666004bd0) + QPaintDevice (0x0x7fc66615f060) 16 + vptr=((& QListView::_ZTV9QListView) + 800) + +Vtable for QListWidgetItem +QListWidgetItem::_ZTV15QListWidgetItem: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QListWidgetItem) +16 (int (*)(...))QListWidgetItem::~QListWidgetItem +24 (int (*)(...))QListWidgetItem::~QListWidgetItem +32 (int (*)(...))QListWidgetItem::clone +40 (int (*)(...))QListWidgetItem::data +48 (int (*)(...))QListWidgetItem::setData +56 (int (*)(...))QListWidgetItem::operator< +64 (int (*)(...))QListWidgetItem::read +72 (int (*)(...))QListWidgetItem::write + +Class QListWidgetItem + size=40 align=8 + base size=36 base align=8 +QListWidgetItem (0x0x7fc66615f600) 0 + vptr=((& QListWidgetItem::_ZTV15QListWidgetItem) + 16) + +Class QListWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QListWidget::QPrivateSignal (0x0x7fc665dc30c0) 0 empty + +Vtable for QListWidget +QListWidget::_ZTV11QListWidget: 112 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QListWidget) +16 (int (*)(...))QListWidget::metaObject +24 (int (*)(...))QListWidget::qt_metacast +32 (int (*)(...))QListWidget::qt_metacall +40 (int (*)(...))QListWidget::~QListWidget +48 (int (*)(...))QListWidget::~QListWidget +56 (int (*)(...))QListWidget::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QListView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QListView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QListView::mouseMoveEvent +200 (int (*)(...))QListView::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QListView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QListView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QListView::dragMoveEvent +328 (int (*)(...))QListView::dragLeaveEvent +336 (int (*)(...))QListWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QAbstractItemView::viewportEvent +456 (int (*)(...))QListView::scrollContentsBy +464 (int (*)(...))QListView::viewportSizeHint +472 (int (*)(...))QListWidget::setModel +480 (int (*)(...))QListWidget::setSelectionModel +488 (int (*)(...))QAbstractItemView::keyboardSearch +496 (int (*)(...))QListView::visualRect +504 (int (*)(...))QListView::scrollTo +512 (int (*)(...))QListView::indexAt +520 (int (*)(...))QAbstractItemView::sizeHintForRow +528 (int (*)(...))QAbstractItemView::sizeHintForColumn +536 (int (*)(...))QAbstractItemView::itemDelegateForIndex +544 (int (*)(...))QListView::reset +552 (int (*)(...))QListView::setRootIndex +560 (int (*)(...))QListView::doItemsLayout +568 (int (*)(...))QAbstractItemView::selectAll +576 (int (*)(...))QListView::dataChanged +584 (int (*)(...))QListView::rowsInserted +592 (int (*)(...))QListView::rowsAboutToBeRemoved +600 (int (*)(...))QListView::selectionChanged +608 (int (*)(...))QListView::currentChanged +616 (int (*)(...))QAbstractItemView::updateEditorData +624 (int (*)(...))QAbstractItemView::updateEditorGeometries +632 (int (*)(...))QListView::updateGeometries +640 (int (*)(...))QAbstractItemView::verticalScrollbarAction +648 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +656 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +664 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +672 (int (*)(...))QAbstractItemView::closeEditor +680 (int (*)(...))QAbstractItemView::commitData +688 (int (*)(...))QAbstractItemView::editorDestroyed +696 (int (*)(...))QListView::moveCursor +704 (int (*)(...))QListView::horizontalOffset +712 (int (*)(...))QListView::verticalOffset +720 (int (*)(...))QListView::isIndexHidden +728 (int (*)(...))QListView::setSelection +736 (int (*)(...))QListView::visualRegionForSelection +744 (int (*)(...))QListView::selectedIndexes +752 (int (*)(...))QAbstractItemView::edit +760 (int (*)(...))QAbstractItemView::selectionCommand +768 (int (*)(...))QListView::startDrag +776 (int (*)(...))QListView::initViewItemOption +784 (int (*)(...))QListWidget::mimeTypes +792 (int (*)(...))QListWidget::mimeData +800 (int (*)(...))QListWidget::dropMimeData +808 (int (*)(...))QListWidget::supportedDropActions +816 (int (*)(...))-16 +824 (int (*)(...))(& _ZTI11QListWidget) +832 (int (*)(...))QListWidget::_ZThn16_N11QListWidgetD1Ev +840 (int (*)(...))QListWidget::_ZThn16_N11QListWidgetD0Ev +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +880 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +888 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QListWidget + size=40 align=8 + base size=40 base align=8 +QListWidget (0x0x7fc666081680) 0 + vptr=((& QListWidget::_ZTV11QListWidget) + 16) + QListView (0x0x7fc6660816e8) 0 + primary-for QListWidget (0x0x7fc666081680) + QAbstractItemView (0x0x7fc666081750) 0 + primary-for QListView (0x0x7fc6660816e8) + QAbstractScrollArea (0x0x7fc6660817b8) 0 + primary-for QAbstractItemView (0x0x7fc666081750) + QFrame (0x0x7fc666081820) 0 + primary-for QAbstractScrollArea (0x0x7fc6660817b8) + QWidget (0x0x7fc666169230) 0 + primary-for QFrame (0x0x7fc666081820) + QObject (0x0x7fc665dc3000) 0 + primary-for QWidget (0x0x7fc666169230) + QPaintDevice (0x0x7fc665dc3060) 16 + vptr=((& QListWidget::_ZTV11QListWidget) + 832) + +Class QMainWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMainWindow::QPrivateSignal (0x0x7fc665dc35a0) 0 empty + +Vtable for QMainWindow +QMainWindow::_ZTV11QMainWindow: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMainWindow) +16 (int (*)(...))QMainWindow::metaObject +24 (int (*)(...))QMainWindow::qt_metacast +32 (int (*)(...))QMainWindow::qt_metacall +40 (int (*)(...))QMainWindow::~QMainWindow +48 (int (*)(...))QMainWindow::~QMainWindow +56 (int (*)(...))QMainWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QMainWindow::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QMainWindow::createPopupMenu +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI11QMainWindow) +456 (int (*)(...))QMainWindow::_ZThn16_N11QMainWindowD1Ev +464 (int (*)(...))QMainWindow::_ZThn16_N11QMainWindowD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMainWindow + size=40 align=8 + base size=40 base align=8 +QMainWindow (0x0x7fc666081888) 0 + vptr=((& QMainWindow::_ZTV11QMainWindow) + 16) + QWidget (0x0x7fc6661692a0) 0 + primary-for QMainWindow (0x0x7fc666081888) + QObject (0x0x7fc665dc34e0) 0 + primary-for QWidget (0x0x7fc6661692a0) + QPaintDevice (0x0x7fc665dc3540) 16 + vptr=((& QMainWindow::_ZTV11QMainWindow) + 456) + +Class QMdiArea::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMdiArea::QPrivateSignal (0x0x7fc665dc3d20) 0 empty + +Vtable for QMdiArea +QMdiArea::_ZTV8QMdiArea: 69 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QMdiArea) +16 (int (*)(...))QMdiArea::metaObject +24 (int (*)(...))QMdiArea::qt_metacast +32 (int (*)(...))QMdiArea::qt_metacall +40 (int (*)(...))QMdiArea::~QMdiArea +48 (int (*)(...))QMdiArea::~QMdiArea +56 (int (*)(...))QMdiArea::event +64 (int (*)(...))QMdiArea::eventFilter +72 (int (*)(...))QMdiArea::timerEvent +80 (int (*)(...))QMdiArea::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QMdiArea::sizeHint +136 (int (*)(...))QMdiArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractScrollArea::mousePressEvent +176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent +184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent +192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractScrollArea::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QMdiArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QMdiArea::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractScrollArea::dragEnterEvent +320 (int (*)(...))QAbstractScrollArea::dragMoveEvent +328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent +336 (int (*)(...))QAbstractScrollArea::dropEvent +344 (int (*)(...))QMdiArea::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QMdiArea::setupViewport +448 (int (*)(...))QMdiArea::viewportEvent +456 (int (*)(...))QMdiArea::scrollContentsBy +464 (int (*)(...))QAbstractScrollArea::viewportSizeHint +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI8QMdiArea) +488 (int (*)(...))QMdiArea::_ZThn16_N8QMdiAreaD1Ev +496 (int (*)(...))QMdiArea::_ZThn16_N8QMdiAreaD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMdiArea + size=40 align=8 + base size=40 base align=8 +QMdiArea (0x0x7fc666081a28) 0 + vptr=((& QMdiArea::_ZTV8QMdiArea) + 16) + QAbstractScrollArea (0x0x7fc666081a90) 0 + primary-for QMdiArea (0x0x7fc666081a28) + QFrame (0x0x7fc666081af8) 0 + primary-for QAbstractScrollArea (0x0x7fc666081a90) + QWidget (0x0x7fc6661695b0) 0 + primary-for QFrame (0x0x7fc666081af8) + QObject (0x0x7fc665dc3c60) 0 + primary-for QWidget (0x0x7fc6661695b0) + QPaintDevice (0x0x7fc665dc3cc0) 16 + vptr=((& QMdiArea::_ZTV8QMdiArea) + 488) + +Class QMdiSubWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMdiSubWindow::QPrivateSignal (0x0x7fc665e834e0) 0 empty + +Vtable for QMdiSubWindow +QMdiSubWindow::_ZTV13QMdiSubWindow: 64 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QMdiSubWindow) +16 (int (*)(...))QMdiSubWindow::metaObject +24 (int (*)(...))QMdiSubWindow::qt_metacast +32 (int (*)(...))QMdiSubWindow::qt_metacall +40 (int (*)(...))QMdiSubWindow::~QMdiSubWindow +48 (int (*)(...))QMdiSubWindow::~QMdiSubWindow +56 (int (*)(...))QMdiSubWindow::event +64 (int (*)(...))QMdiSubWindow::eventFilter +72 (int (*)(...))QMdiSubWindow::timerEvent +80 (int (*)(...))QMdiSubWindow::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QMdiSubWindow::sizeHint +136 (int (*)(...))QMdiSubWindow::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QMdiSubWindow::mousePressEvent +176 (int (*)(...))QMdiSubWindow::mouseReleaseEvent +184 (int (*)(...))QMdiSubWindow::mouseDoubleClickEvent +192 (int (*)(...))QMdiSubWindow::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QMdiSubWindow::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QMdiSubWindow::focusInEvent +232 (int (*)(...))QMdiSubWindow::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QMdiSubWindow::leaveEvent +256 (int (*)(...))QMdiSubWindow::paintEvent +264 (int (*)(...))QMdiSubWindow::moveEvent +272 (int (*)(...))QMdiSubWindow::resizeEvent +280 (int (*)(...))QMdiSubWindow::closeEvent +288 (int (*)(...))QMdiSubWindow::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QMdiSubWindow::showEvent +352 (int (*)(...))QMdiSubWindow::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMdiSubWindow::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI13QMdiSubWindow) +448 (int (*)(...))QMdiSubWindow::_ZThn16_N13QMdiSubWindowD1Ev +456 (int (*)(...))QMdiSubWindow::_ZThn16_N13QMdiSubWindowD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMdiSubWindow + size=40 align=8 + base size=40 base align=8 +QMdiSubWindow (0x0x7fc666081c98) 0 + vptr=((& QMdiSubWindow::_ZTV13QMdiSubWindow) + 16) + QWidget (0x0x7fc666169930) 0 + primary-for QMdiSubWindow (0x0x7fc666081c98) + QObject (0x0x7fc665e83420) 0 + primary-for QWidget (0x0x7fc666169930) + QPaintDevice (0x0x7fc665e83480) 16 + vptr=((& QMdiSubWindow::_ZTV13QMdiSubWindow) + 448) + +Class QMenu::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMenu::QPrivateSignal (0x0x7fc665e83ae0) 0 empty + +Vtable for QMenu +QMenu::_ZTV5QMenu: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QMenu) +16 (int (*)(...))QMenu::metaObject +24 (int (*)(...))QMenu::qt_metacast +32 (int (*)(...))QMenu::qt_metacall +40 (int (*)(...))QMenu::~QMenu +48 (int (*)(...))QMenu::~QMenu +56 (int (*)(...))QMenu::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QMenu::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QMenu::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QMenu::mousePressEvent +176 (int (*)(...))QMenu::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QMenu::mouseMoveEvent +200 (int (*)(...))QMenu::wheelEvent +208 (int (*)(...))QMenu::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QMenu::enterEvent +248 (int (*)(...))QMenu::leaveEvent +256 (int (*)(...))QMenu::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QMenu::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QMenu::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMenu::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QMenu::focusNextPrevChild +432 (int (*)(...))QMenu::initStyleOption +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI5QMenu) +456 (int (*)(...))QMenu::_ZThn16_N5QMenuD1Ev +464 (int (*)(...))QMenu::_ZThn16_N5QMenuD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMenu + size=40 align=8 + base size=40 base align=8 +QMenu (0x0x7fc666081e38) 0 + vptr=((& QMenu::_ZTV5QMenu) + 16) + QWidget (0x0x7fc666169b60) 0 + primary-for QMenu (0x0x7fc666081e38) + QObject (0x0x7fc665e83a20) 0 + primary-for QWidget (0x0x7fc666169b60) + QPaintDevice (0x0x7fc665e83a80) 16 + vptr=((& QMenu::_ZTV5QMenu) + 456) + +Class QMenuBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMenuBar::QPrivateSignal (0x0x7fc665e83ea0) 0 empty + +Vtable for QMenuBar +QMenuBar::_ZTV8QMenuBar: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QMenuBar) +16 (int (*)(...))QMenuBar::metaObject +24 (int (*)(...))QMenuBar::qt_metacast +32 (int (*)(...))QMenuBar::qt_metacall +40 (int (*)(...))QMenuBar::~QMenuBar +48 (int (*)(...))QMenuBar::~QMenuBar +56 (int (*)(...))QMenuBar::event +64 (int (*)(...))QMenuBar::eventFilter +72 (int (*)(...))QMenuBar::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QMenuBar::setVisible +128 (int (*)(...))QMenuBar::sizeHint +136 (int (*)(...))QMenuBar::minimumSizeHint +144 (int (*)(...))QMenuBar::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QMenuBar::mousePressEvent +176 (int (*)(...))QMenuBar::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QMenuBar::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QMenuBar::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QMenuBar::focusInEvent +232 (int (*)(...))QMenuBar::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QMenuBar::leaveEvent +256 (int (*)(...))QMenuBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QMenuBar::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QMenuBar::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMenuBar::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QMenuBar::initStyleOption +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI8QMenuBar) +456 (int (*)(...))QMenuBar::_ZThn16_N8QMenuBarD1Ev +464 (int (*)(...))QMenuBar::_ZThn16_N8QMenuBarD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMenuBar + size=40 align=8 + base size=40 base align=8 +QMenuBar (0x0x7fc666081ea0) 0 + vptr=((& QMenuBar::_ZTV8QMenuBar) + 16) + QWidget (0x0x7fc666169bd0) 0 + primary-for QMenuBar (0x0x7fc666081ea0) + QObject (0x0x7fc665e83de0) 0 + primary-for QWidget (0x0x7fc666169bd0) + QPaintDevice (0x0x7fc665e83e40) 16 + vptr=((& QMenuBar::_ZTV8QMenuBar) + 456) + +Class QMessageBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMessageBox::QPrivateSignal (0x0x7fc665f851e0) 0 empty + +Vtable for QMessageBox +QMessageBox::_ZTV11QMessageBox: 69 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMessageBox) +16 (int (*)(...))QMessageBox::metaObject +24 (int (*)(...))QMessageBox::qt_metacast +32 (int (*)(...))QMessageBox::qt_metacall +40 (int (*)(...))QMessageBox::~QMessageBox +48 (int (*)(...))QMessageBox::~QMessageBox +56 (int (*)(...))QMessageBox::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QMessageBox::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QMessageBox::resizeEvent +280 (int (*)(...))QMessageBox::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QMessageBox::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMessageBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QMessageBox) +488 (int (*)(...))QMessageBox::_ZThn16_N11QMessageBoxD1Ev +496 (int (*)(...))QMessageBox::_ZThn16_N11QMessageBoxD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMessageBox + size=40 align=8 + base size=40 base align=8 +QMessageBox (0x0x7fc666081f08) 0 + vptr=((& QMessageBox::_ZTV11QMessageBox) + 16) + QDialog (0x0x7fc666081f70) 0 + primary-for QMessageBox (0x0x7fc666081f08) + QWidget (0x0x7fc666169c40) 0 + primary-for QDialog (0x0x7fc666081f70) + QObject (0x0x7fc665f85120) 0 + primary-for QWidget (0x0x7fc666169c40) + QPaintDevice (0x0x7fc665f85180) 16 + vptr=((& QMessageBox::_ZTV11QMessageBox) + 488) + +Class QTextEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextEdit::QPrivateSignal (0x0x7fc665f85ae0) 0 empty + +Class QTextEdit::ExtraSelection + size=24 align=8 + base size=24 base align=8 +QTextEdit::ExtraSelection (0x0x7fc665f85b40) 0 + +Vtable for QTextEdit +QTextEdit::_ZTV9QTextEdit: 74 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextEdit) +16 (int (*)(...))QTextEdit::metaObject +24 (int (*)(...))QTextEdit::qt_metacast +32 (int (*)(...))QTextEdit::qt_metacall +40 (int (*)(...))QTextEdit::~QTextEdit +48 (int (*)(...))QTextEdit::~QTextEdit +56 (int (*)(...))QTextEdit::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QTextEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTextEdit::mousePressEvent +176 (int (*)(...))QTextEdit::mouseReleaseEvent +184 (int (*)(...))QTextEdit::mouseDoubleClickEvent +192 (int (*)(...))QTextEdit::mouseMoveEvent +200 (int (*)(...))QTextEdit::wheelEvent +208 (int (*)(...))QTextEdit::keyPressEvent +216 (int (*)(...))QTextEdit::keyReleaseEvent +224 (int (*)(...))QTextEdit::focusInEvent +232 (int (*)(...))QTextEdit::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTextEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTextEdit::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QTextEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QTextEdit::dragEnterEvent +320 (int (*)(...))QTextEdit::dragMoveEvent +328 (int (*)(...))QTextEdit::dragLeaveEvent +336 (int (*)(...))QTextEdit::dropEvent +344 (int (*)(...))QTextEdit::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTextEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QTextEdit::inputMethodEvent +416 (int (*)(...))QTextEdit::inputMethodQuery +424 (int (*)(...))QTextEdit::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QAbstractScrollArea::viewportEvent +456 (int (*)(...))QTextEdit::scrollContentsBy +464 (int (*)(...))QAbstractScrollArea::viewportSizeHint +472 (int (*)(...))QTextEdit::loadResource +480 (int (*)(...))QTextEdit::createMimeDataFromSelection +488 (int (*)(...))QTextEdit::canInsertFromMimeData +496 (int (*)(...))QTextEdit::insertFromMimeData +504 (int (*)(...))QTextEdit::doSetTextCursor +512 (int (*)(...))-16 +520 (int (*)(...))(& _ZTI9QTextEdit) +528 (int (*)(...))QTextEdit::_ZThn16_N9QTextEditD1Ev +536 (int (*)(...))QTextEdit::_ZThn16_N9QTextEditD0Ev +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +584 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTextEdit + size=40 align=8 + base size=40 base align=8 +QTextEdit (0x0x7fc665fba138) 0 + vptr=((& QTextEdit::_ZTV9QTextEdit) + 16) + QAbstractScrollArea (0x0x7fc665fba1a0) 0 + primary-for QTextEdit (0x0x7fc665fba138) + QFrame (0x0x7fc665fba208) 0 + primary-for QAbstractScrollArea (0x0x7fc665fba1a0) + QWidget (0x0x7fc665c1b000) 0 + primary-for QFrame (0x0x7fc665fba208) + QObject (0x0x7fc665f85a20) 0 + primary-for QWidget (0x0x7fc665c1b000) + QPaintDevice (0x0x7fc665f85a80) 16 + vptr=((& QTextEdit::_ZTV9QTextEdit) + 528) + +Class QPlainTextEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPlainTextEdit::QPrivateSignal (0x0x7fc665c68480) 0 empty + +Vtable for QPlainTextEdit +QPlainTextEdit::_ZTV14QPlainTextEdit: 74 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QPlainTextEdit) +16 (int (*)(...))QPlainTextEdit::metaObject +24 (int (*)(...))QPlainTextEdit::qt_metacast +32 (int (*)(...))QPlainTextEdit::qt_metacall +40 (int (*)(...))QPlainTextEdit::~QPlainTextEdit +48 (int (*)(...))QPlainTextEdit::~QPlainTextEdit +56 (int (*)(...))QPlainTextEdit::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QPlainTextEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QPlainTextEdit::mousePressEvent +176 (int (*)(...))QPlainTextEdit::mouseReleaseEvent +184 (int (*)(...))QPlainTextEdit::mouseDoubleClickEvent +192 (int (*)(...))QPlainTextEdit::mouseMoveEvent +200 (int (*)(...))QPlainTextEdit::wheelEvent +208 (int (*)(...))QPlainTextEdit::keyPressEvent +216 (int (*)(...))QPlainTextEdit::keyReleaseEvent +224 (int (*)(...))QPlainTextEdit::focusInEvent +232 (int (*)(...))QPlainTextEdit::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QPlainTextEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QPlainTextEdit::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QPlainTextEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QPlainTextEdit::dragEnterEvent +320 (int (*)(...))QPlainTextEdit::dragMoveEvent +328 (int (*)(...))QPlainTextEdit::dragLeaveEvent +336 (int (*)(...))QPlainTextEdit::dropEvent +344 (int (*)(...))QPlainTextEdit::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QPlainTextEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QPlainTextEdit::inputMethodEvent +416 (int (*)(...))QPlainTextEdit::inputMethodQuery +424 (int (*)(...))QPlainTextEdit::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QAbstractScrollArea::viewportEvent +456 (int (*)(...))QPlainTextEdit::scrollContentsBy +464 (int (*)(...))QAbstractScrollArea::viewportSizeHint +472 (int (*)(...))QPlainTextEdit::loadResource +480 (int (*)(...))QPlainTextEdit::createMimeDataFromSelection +488 (int (*)(...))QPlainTextEdit::canInsertFromMimeData +496 (int (*)(...))QPlainTextEdit::insertFromMimeData +504 (int (*)(...))QPlainTextEdit::doSetTextCursor +512 (int (*)(...))-16 +520 (int (*)(...))(& _ZTI14QPlainTextEdit) +528 (int (*)(...))QPlainTextEdit::_ZThn16_N14QPlainTextEditD1Ev +536 (int (*)(...))QPlainTextEdit::_ZThn16_N14QPlainTextEditD0Ev +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +584 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QPlainTextEdit + size=40 align=8 + base size=40 base align=8 +QPlainTextEdit (0x0x7fc665fba3a8) 0 + vptr=((& QPlainTextEdit::_ZTV14QPlainTextEdit) + 16) + QAbstractScrollArea (0x0x7fc665fba410) 0 + primary-for QPlainTextEdit (0x0x7fc665fba3a8) + QFrame (0x0x7fc665fba478) 0 + primary-for QAbstractScrollArea (0x0x7fc665fba410) + QWidget (0x0x7fc665c1b380) 0 + primary-for QFrame (0x0x7fc665fba478) + QObject (0x0x7fc665c683c0) 0 + primary-for QWidget (0x0x7fc665c1b380) + QPaintDevice (0x0x7fc665c68420) 16 + vptr=((& QPlainTextEdit::_ZTV14QPlainTextEdit) + 528) + +Class QPlainTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPlainTextDocumentLayout::QPrivateSignal (0x0x7fc665c689c0) 0 empty + +Vtable for QPlainTextDocumentLayout +QPlainTextDocumentLayout::_ZTV24QPlainTextDocumentLayout: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QPlainTextDocumentLayout) +16 (int (*)(...))QPlainTextDocumentLayout::metaObject +24 (int (*)(...))QPlainTextDocumentLayout::qt_metacast +32 (int (*)(...))QPlainTextDocumentLayout::qt_metacall +40 (int (*)(...))QPlainTextDocumentLayout::~QPlainTextDocumentLayout +48 (int (*)(...))QPlainTextDocumentLayout::~QPlainTextDocumentLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPlainTextDocumentLayout::draw +120 (int (*)(...))QPlainTextDocumentLayout::hitTest +128 (int (*)(...))QPlainTextDocumentLayout::pageCount +136 (int (*)(...))QPlainTextDocumentLayout::documentSize +144 (int (*)(...))QPlainTextDocumentLayout::frameBoundingRect +152 (int (*)(...))QPlainTextDocumentLayout::blockBoundingRect +160 (int (*)(...))QPlainTextDocumentLayout::documentChanged +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QPlainTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QPlainTextDocumentLayout (0x0x7fc665fba4e0) 0 + vptr=((& QPlainTextDocumentLayout::_ZTV24QPlainTextDocumentLayout) + 16) + QAbstractTextDocumentLayout (0x0x7fc665fba548) 0 + primary-for QPlainTextDocumentLayout (0x0x7fc665fba4e0) + QObject (0x0x7fc665c68960) 0 + primary-for QAbstractTextDocumentLayout (0x0x7fc665fba548) + +Class QProgressBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProgressBar::QPrivateSignal (0x0x7fc665c68c00) 0 empty + +Vtable for QProgressBar +QProgressBar::_ZTV12QProgressBar: 66 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QProgressBar) +16 (int (*)(...))QProgressBar::metaObject +24 (int (*)(...))QProgressBar::qt_metacast +32 (int (*)(...))QProgressBar::qt_metacall +40 (int (*)(...))QProgressBar::~QProgressBar +48 (int (*)(...))QProgressBar::~QProgressBar +56 (int (*)(...))QProgressBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QProgressBar::sizeHint +136 (int (*)(...))QProgressBar::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QProgressBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QProgressBar::text +440 (int (*)(...))QProgressBar::initStyleOption +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI12QProgressBar) +464 (int (*)(...))QProgressBar::_ZThn16_N12QProgressBarD1Ev +472 (int (*)(...))QProgressBar::_ZThn16_N12QProgressBarD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QProgressBar + size=40 align=8 + base size=40 base align=8 +QProgressBar (0x0x7fc665fba5b0) 0 + vptr=((& QProgressBar::_ZTV12QProgressBar) + 16) + QWidget (0x0x7fc665c1b4d0) 0 + primary-for QProgressBar (0x0x7fc665fba5b0) + QObject (0x0x7fc665c68b40) 0 + primary-for QWidget (0x0x7fc665c1b4d0) + QPaintDevice (0x0x7fc665c68ba0) 16 + vptr=((& QProgressBar::_ZTV12QProgressBar) + 464) + +Class QProgressDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProgressDialog::QPrivateSignal (0x0x7fc665c68f00) 0 empty + +Vtable for QProgressDialog +QProgressDialog::_ZTV15QProgressDialog: 69 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QProgressDialog) +16 (int (*)(...))QProgressDialog::metaObject +24 (int (*)(...))QProgressDialog::qt_metacast +32 (int (*)(...))QProgressDialog::qt_metacall +40 (int (*)(...))QProgressDialog::~QProgressDialog +48 (int (*)(...))QProgressDialog::~QProgressDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QProgressDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QProgressDialog::resizeEvent +280 (int (*)(...))QProgressDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QProgressDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QProgressDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI15QProgressDialog) +488 (int (*)(...))QProgressDialog::_ZThn16_N15QProgressDialogD1Ev +496 (int (*)(...))QProgressDialog::_ZThn16_N15QProgressDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QProgressDialog + size=40 align=8 + base size=40 base align=8 +QProgressDialog (0x0x7fc665fba618) 0 + vptr=((& QProgressDialog::_ZTV15QProgressDialog) + 16) + QDialog (0x0x7fc665fba680) 0 + primary-for QProgressDialog (0x0x7fc665fba618) + QWidget (0x0x7fc665c1b620) 0 + primary-for QDialog (0x0x7fc665fba680) + QObject (0x0x7fc665c68e40) 0 + primary-for QWidget (0x0x7fc665c1b620) + QPaintDevice (0x0x7fc665c68ea0) 16 + vptr=((& QProgressDialog::_ZTV15QProgressDialog) + 488) + +Class QProxyStyle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProxyStyle::QPrivateSignal (0x0x7fc665d12120) 0 empty + +Vtable for QProxyStyle +QProxyStyle::_ZTV11QProxyStyle: 37 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QProxyStyle) +16 (int (*)(...))QProxyStyle::metaObject +24 (int (*)(...))QProxyStyle::qt_metacast +32 (int (*)(...))QProxyStyle::qt_metacall +40 (int (*)(...))QProxyStyle::~QProxyStyle +48 (int (*)(...))QProxyStyle::~QProxyStyle +56 (int (*)(...))QProxyStyle::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProxyStyle::polish +120 (int (*)(...))QProxyStyle::unpolish +128 (int (*)(...))QProxyStyle::polish +136 (int (*)(...))QProxyStyle::unpolish +144 (int (*)(...))QProxyStyle::polish +152 (int (*)(...))QProxyStyle::itemTextRect +160 (int (*)(...))QProxyStyle::itemPixmapRect +168 (int (*)(...))QProxyStyle::drawItemText +176 (int (*)(...))QProxyStyle::drawItemPixmap +184 (int (*)(...))QProxyStyle::standardPalette +192 (int (*)(...))QProxyStyle::drawPrimitive +200 (int (*)(...))QProxyStyle::drawControl +208 (int (*)(...))QProxyStyle::subElementRect +216 (int (*)(...))QProxyStyle::drawComplexControl +224 (int (*)(...))QProxyStyle::hitTestComplexControl +232 (int (*)(...))QProxyStyle::subControlRect +240 (int (*)(...))QProxyStyle::pixelMetric +248 (int (*)(...))QProxyStyle::sizeFromContents +256 (int (*)(...))QProxyStyle::styleHint +264 (int (*)(...))QProxyStyle::standardPixmap +272 (int (*)(...))QProxyStyle::standardIcon +280 (int (*)(...))QProxyStyle::generatedIconPixmap +288 (int (*)(...))QProxyStyle::layoutSpacing + +Class QProxyStyle + size=16 align=8 + base size=16 base align=8 +QProxyStyle (0x0x7fc665fba6e8) 0 + vptr=((& QProxyStyle::_ZTV11QProxyStyle) + 16) + QCommonStyle (0x0x7fc665fba750) 0 + primary-for QProxyStyle (0x0x7fc665fba6e8) + QStyle (0x0x7fc665fba7b8) 0 + primary-for QCommonStyle (0x0x7fc665fba750) + QObject (0x0x7fc665d120c0) 0 + primary-for QStyle (0x0x7fc665fba7b8) + +Class QRadioButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRadioButton::QPrivateSignal (0x0x7fc665d12360) 0 empty + +Vtable for QRadioButton +QRadioButton::_ZTV12QRadioButton: 68 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QRadioButton) +16 (int (*)(...))QRadioButton::metaObject +24 (int (*)(...))QRadioButton::qt_metacast +32 (int (*)(...))QRadioButton::qt_metacall +40 (int (*)(...))QRadioButton::~QRadioButton +48 (int (*)(...))QRadioButton::~QRadioButton +56 (int (*)(...))QRadioButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QRadioButton::sizeHint +136 (int (*)(...))QRadioButton::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QRadioButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QRadioButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QRadioButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))QRadioButton::initStyleOption +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI12QRadioButton) +480 (int (*)(...))QRadioButton::_ZThn16_N12QRadioButtonD1Ev +488 (int (*)(...))QRadioButton::_ZThn16_N12QRadioButtonD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QRadioButton + size=40 align=8 + base size=40 base align=8 +QRadioButton (0x0x7fc665fba820) 0 + vptr=((& QRadioButton::_ZTV12QRadioButton) + 16) + QAbstractButton (0x0x7fc665fba888) 0 + primary-for QRadioButton (0x0x7fc665fba820) + QWidget (0x0x7fc665c1b690) 0 + primary-for QAbstractButton (0x0x7fc665fba888) + QObject (0x0x7fc665d122a0) 0 + primary-for QWidget (0x0x7fc665c1b690) + QPaintDevice (0x0x7fc665d12300) 16 + vptr=((& QRadioButton::_ZTV12QRadioButton) + 480) + +Class QScrollBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScrollBar::QPrivateSignal (0x0x7fc665d125a0) 0 empty + +Vtable for QScrollBar +QScrollBar::_ZTV10QScrollBar: 66 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QScrollBar) +16 (int (*)(...))QScrollBar::metaObject +24 (int (*)(...))QScrollBar::qt_metacast +32 (int (*)(...))QScrollBar::qt_metacall +40 (int (*)(...))QScrollBar::~QScrollBar +48 (int (*)(...))QScrollBar::~QScrollBar +56 (int (*)(...))QScrollBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QScrollBar::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QScrollBar::mousePressEvent +176 (int (*)(...))QScrollBar::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QScrollBar::mouseMoveEvent +200 (int (*)(...))QScrollBar::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QScrollBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QScrollBar::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QScrollBar::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QScrollBar::sliderChange +440 (int (*)(...))QScrollBar::initStyleOption +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI10QScrollBar) +464 (int (*)(...))QScrollBar::_ZThn16_N10QScrollBarD1Ev +472 (int (*)(...))QScrollBar::_ZThn16_N10QScrollBarD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QScrollBar + size=40 align=8 + base size=40 base align=8 +QScrollBar (0x0x7fc665fba8f0) 0 + vptr=((& QScrollBar::_ZTV10QScrollBar) + 16) + QAbstractSlider (0x0x7fc665fba958) 0 + primary-for QScrollBar (0x0x7fc665fba8f0) + QWidget (0x0x7fc665c1b700) 0 + primary-for QAbstractSlider (0x0x7fc665fba958) + QObject (0x0x7fc665d124e0) 0 + primary-for QWidget (0x0x7fc665c1b700) + QPaintDevice (0x0x7fc665d12540) 16 + vptr=((& QScrollBar::_ZTV10QScrollBar) + 464) + +Vtable for QScrollerProperties +QScrollerProperties::_ZTV19QScrollerProperties: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollerProperties) +16 (int (*)(...))QScrollerProperties::~QScrollerProperties +24 (int (*)(...))QScrollerProperties::~QScrollerProperties + +Class QScrollerProperties + size=16 align=8 + base size=16 base align=8 +QScrollerProperties (0x0x7fc665d12720) 0 + vptr=((& QScrollerProperties::_ZTV19QScrollerProperties) + 16) + +Class QScroller::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScroller::QPrivateSignal (0x0x7fc665da11e0) 0 empty + +Vtable for QScroller +QScroller::_ZTV9QScroller: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QScroller) +16 (int (*)(...))QScroller::metaObject +24 (int (*)(...))QScroller::qt_metacast +32 (int (*)(...))QScroller::qt_metacall +40 (int (*)(...))QScroller::~QScroller +48 (int (*)(...))QScroller::~QScroller +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScroller + size=24 align=8 + base size=24 base align=8 +QScroller (0x0x7fc665fbaa90) 0 + vptr=((& QScroller::_ZTV9QScroller) + 16) + QObject (0x0x7fc665da1180) 0 + primary-for QScroller (0x0x7fc665fbaa90) + +Class QSizeGrip::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSizeGrip::QPrivateSignal (0x0x7fc665da14e0) 0 empty + +Vtable for QSizeGrip +QSizeGrip::_ZTV9QSizeGrip: 64 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSizeGrip) +16 (int (*)(...))QSizeGrip::metaObject +24 (int (*)(...))QSizeGrip::qt_metacast +32 (int (*)(...))QSizeGrip::qt_metacall +40 (int (*)(...))QSizeGrip::~QSizeGrip +48 (int (*)(...))QSizeGrip::~QSizeGrip +56 (int (*)(...))QSizeGrip::event +64 (int (*)(...))QSizeGrip::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QSizeGrip::setVisible +128 (int (*)(...))QSizeGrip::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSizeGrip::mousePressEvent +176 (int (*)(...))QSizeGrip::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QSizeGrip::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QSizeGrip::paintEvent +264 (int (*)(...))QSizeGrip::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QSizeGrip::showEvent +352 (int (*)(...))QSizeGrip::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI9QSizeGrip) +448 (int (*)(...))QSizeGrip::_ZThn16_N9QSizeGripD1Ev +456 (int (*)(...))QSizeGrip::_ZThn16_N9QSizeGripD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSizeGrip + size=40 align=8 + base size=40 base align=8 +QSizeGrip (0x0x7fc665fbaaf8) 0 + vptr=((& QSizeGrip::_ZTV9QSizeGrip) + 16) + QWidget (0x0x7fc665d54c40) 0 + primary-for QSizeGrip (0x0x7fc665fbaaf8) + QObject (0x0x7fc665da1420) 0 + primary-for QWidget (0x0x7fc665d54c40) + QPaintDevice (0x0x7fc665da1480) 16 + vptr=((& QSizeGrip::_ZTV9QSizeGrip) + 448) + +Class QSpinBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSpinBox::QPrivateSignal (0x0x7fc665da1720) 0 empty + +Vtable for QSpinBox +QSpinBox::_ZTV8QSpinBox: 72 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSpinBox) +16 (int (*)(...))QSpinBox::metaObject +24 (int (*)(...))QSpinBox::qt_metacast +32 (int (*)(...))QSpinBox::qt_metacall +40 (int (*)(...))QSpinBox::~QSpinBox +48 (int (*)(...))QSpinBox::~QSpinBox +56 (int (*)(...))QSpinBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractSpinBox::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractSpinBox::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QAbstractSpinBox::wheelEvent +208 (int (*)(...))QAbstractSpinBox::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QAbstractSpinBox::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractSpinBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QSpinBox::validate +440 (int (*)(...))QSpinBox::fixup +448 (int (*)(...))QAbstractSpinBox::stepBy +456 (int (*)(...))QAbstractSpinBox::clear +464 (int (*)(...))QAbstractSpinBox::initStyleOption +472 (int (*)(...))QAbstractSpinBox::stepEnabled +480 (int (*)(...))QSpinBox::valueFromText +488 (int (*)(...))QSpinBox::textFromValue +496 (int (*)(...))-16 +504 (int (*)(...))(& _ZTI8QSpinBox) +512 (int (*)(...))QSpinBox::_ZThn16_N8QSpinBoxD1Ev +520 (int (*)(...))QSpinBox::_ZThn16_N8QSpinBoxD0Ev +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSpinBox + size=40 align=8 + base size=40 base align=8 +QSpinBox (0x0x7fc665fbab60) 0 + vptr=((& QSpinBox::_ZTV8QSpinBox) + 16) + QAbstractSpinBox (0x0x7fc665fbabc8) 0 + primary-for QSpinBox (0x0x7fc665fbab60) + QWidget (0x0x7fc665d54cb0) 0 + primary-for QAbstractSpinBox (0x0x7fc665fbabc8) + QObject (0x0x7fc665da1660) 0 + primary-for QWidget (0x0x7fc665d54cb0) + QPaintDevice (0x0x7fc665da16c0) 16 + vptr=((& QSpinBox::_ZTV8QSpinBox) + 512) + +Class QDoubleSpinBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleSpinBox::QPrivateSignal (0x0x7fc665da1960) 0 empty + +Vtable for QDoubleSpinBox +QDoubleSpinBox::_ZTV14QDoubleSpinBox: 72 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDoubleSpinBox) +16 (int (*)(...))QDoubleSpinBox::metaObject +24 (int (*)(...))QDoubleSpinBox::qt_metacast +32 (int (*)(...))QDoubleSpinBox::qt_metacall +40 (int (*)(...))QDoubleSpinBox::~QDoubleSpinBox +48 (int (*)(...))QDoubleSpinBox::~QDoubleSpinBox +56 (int (*)(...))QAbstractSpinBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractSpinBox::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractSpinBox::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QAbstractSpinBox::wheelEvent +208 (int (*)(...))QAbstractSpinBox::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QAbstractSpinBox::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractSpinBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDoubleSpinBox::validate +440 (int (*)(...))QDoubleSpinBox::fixup +448 (int (*)(...))QAbstractSpinBox::stepBy +456 (int (*)(...))QAbstractSpinBox::clear +464 (int (*)(...))QAbstractSpinBox::initStyleOption +472 (int (*)(...))QAbstractSpinBox::stepEnabled +480 (int (*)(...))QDoubleSpinBox::valueFromText +488 (int (*)(...))QDoubleSpinBox::textFromValue +496 (int (*)(...))-16 +504 (int (*)(...))(& _ZTI14QDoubleSpinBox) +512 (int (*)(...))QDoubleSpinBox::_ZThn16_N14QDoubleSpinBoxD1Ev +520 (int (*)(...))QDoubleSpinBox::_ZThn16_N14QDoubleSpinBoxD0Ev +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDoubleSpinBox + size=40 align=8 + base size=40 base align=8 +QDoubleSpinBox (0x0x7fc665fbac30) 0 + vptr=((& QDoubleSpinBox::_ZTV14QDoubleSpinBox) + 16) + QAbstractSpinBox (0x0x7fc665fbac98) 0 + primary-for QDoubleSpinBox (0x0x7fc665fbac30) + QWidget (0x0x7fc665d54d20) 0 + primary-for QAbstractSpinBox (0x0x7fc665fbac98) + QObject (0x0x7fc665da18a0) 0 + primary-for QWidget (0x0x7fc665d54d20) + QPaintDevice (0x0x7fc665da1900) 16 + vptr=((& QDoubleSpinBox::_ZTV14QDoubleSpinBox) + 512) + +Class QSplashScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSplashScreen::QPrivateSignal (0x0x7fc665da1ba0) 0 empty + +Vtable for QSplashScreen +QSplashScreen::_ZTV13QSplashScreen: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSplashScreen) +16 (int (*)(...))QSplashScreen::metaObject +24 (int (*)(...))QSplashScreen::qt_metacast +32 (int (*)(...))QSplashScreen::qt_metacall +40 (int (*)(...))QSplashScreen::~QSplashScreen +48 (int (*)(...))QSplashScreen::~QSplashScreen +56 (int (*)(...))QSplashScreen::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSplashScreen::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QSplashScreen::drawContents +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI13QSplashScreen) +456 (int (*)(...))QSplashScreen::_ZThn16_N13QSplashScreenD1Ev +464 (int (*)(...))QSplashScreen::_ZThn16_N13QSplashScreenD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSplashScreen + size=40 align=8 + base size=40 base align=8 +QSplashScreen (0x0x7fc665fbad00) 0 + vptr=((& QSplashScreen::_ZTV13QSplashScreen) + 16) + QWidget (0x0x7fc665d54d90) 0 + primary-for QSplashScreen (0x0x7fc665fbad00) + QObject (0x0x7fc665da1ae0) 0 + primary-for QWidget (0x0x7fc665d54d90) + QPaintDevice (0x0x7fc665da1b40) 16 + vptr=((& QSplashScreen::_ZTV13QSplashScreen) + 456) + +Class QSplitter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSplitter::QPrivateSignal (0x0x7fc665da1de0) 0 empty + +Vtable for QSplitter +QSplitter::_ZTV9QSplitter: 66 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSplitter) +16 (int (*)(...))QSplitter::metaObject +24 (int (*)(...))QSplitter::qt_metacast +32 (int (*)(...))QSplitter::qt_metacall +40 (int (*)(...))QSplitter::~QSplitter +48 (int (*)(...))QSplitter::~QSplitter +56 (int (*)(...))QSplitter::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QSplitter::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QSplitter::sizeHint +136 (int (*)(...))QSplitter::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QSplitter::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QSplitter::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QSplitter::createHandle +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI9QSplitter) +464 (int (*)(...))QSplitter::_ZThn16_N9QSplitterD1Ev +472 (int (*)(...))QSplitter::_ZThn16_N9QSplitterD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSplitter + size=40 align=8 + base size=40 base align=8 +QSplitter (0x0x7fc665fbad68) 0 + vptr=((& QSplitter::_ZTV9QSplitter) + 16) + QFrame (0x0x7fc665fbadd0) 0 + primary-for QSplitter (0x0x7fc665fbad68) + QWidget (0x0x7fc665d54e00) 0 + primary-for QFrame (0x0x7fc665fbadd0) + QObject (0x0x7fc665da1d20) 0 + primary-for QWidget (0x0x7fc665d54e00) + QPaintDevice (0x0x7fc665da1d80) 16 + vptr=((& QSplitter::_ZTV9QSplitter) + 464) + +Class QSplitterHandle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSplitterHandle::QPrivateSignal (0x0x7fc665a33060) 0 empty + +Vtable for QSplitterHandle +QSplitterHandle::_ZTV15QSplitterHandle: 64 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSplitterHandle) +16 (int (*)(...))QSplitterHandle::metaObject +24 (int (*)(...))QSplitterHandle::qt_metacast +32 (int (*)(...))QSplitterHandle::qt_metacall +40 (int (*)(...))QSplitterHandle::~QSplitterHandle +48 (int (*)(...))QSplitterHandle::~QSplitterHandle +56 (int (*)(...))QSplitterHandle::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QSplitterHandle::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSplitterHandle::mousePressEvent +176 (int (*)(...))QSplitterHandle::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QSplitterHandle::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QSplitterHandle::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QSplitterHandle::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI15QSplitterHandle) +448 (int (*)(...))QSplitterHandle::_ZThn16_N15QSplitterHandleD1Ev +456 (int (*)(...))QSplitterHandle::_ZThn16_N15QSplitterHandleD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSplitterHandle + size=40 align=8 + base size=40 base align=8 +QSplitterHandle (0x0x7fc665fbae38) 0 + vptr=((& QSplitterHandle::_ZTV15QSplitterHandle) + 16) + QWidget (0x0x7fc665d54e70) 0 + primary-for QSplitterHandle (0x0x7fc665fbae38) + QObject (0x0x7fc665da1f60) 0 + primary-for QWidget (0x0x7fc665d54e70) + QPaintDevice (0x0x7fc665a33000) 16 + vptr=((& QSplitterHandle::_ZTV15QSplitterHandle) + 448) + +Class QStackedLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStackedLayout::QPrivateSignal (0x0x7fc665a332a0) 0 empty + +Vtable for QStackedLayout +QStackedLayout::_ZTV14QStackedLayout: 54 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QStackedLayout) +16 (int (*)(...))QStackedLayout::metaObject +24 (int (*)(...))QStackedLayout::qt_metacast +32 (int (*)(...))QStackedLayout::qt_metacall +40 (int (*)(...))QStackedLayout::~QStackedLayout +48 (int (*)(...))QStackedLayout::~QStackedLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLayout::spacing +120 (int (*)(...))QLayout::setSpacing +128 (int (*)(...))QLayout::invalidate +136 (int (*)(...))QLayout::geometry +144 (int (*)(...))QStackedLayout::addItem +152 (int (*)(...))QLayout::expandingDirections +160 (int (*)(...))QStackedLayout::minimumSize +168 (int (*)(...))QLayout::maximumSize +176 (int (*)(...))QStackedLayout::setGeometry +184 (int (*)(...))QStackedLayout::itemAt +192 (int (*)(...))QStackedLayout::takeAt +200 (int (*)(...))QLayout::indexOf +208 (int (*)(...))QLayout::indexOf +216 (int (*)(...))QStackedLayout::count +224 (int (*)(...))QLayout::isEmpty +232 (int (*)(...))QLayout::controlTypes +240 (int (*)(...))QLayout::replaceWidget +248 (int (*)(...))QLayout::layout +256 (int (*)(...))QStackedLayout::sizeHint +264 (int (*)(...))QStackedLayout::hasHeightForWidth +272 (int (*)(...))QStackedLayout::heightForWidth +280 (int (*)(...))-16 +288 (int (*)(...))(& _ZTI14QStackedLayout) +296 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayoutD1Ev +304 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayoutD0Ev +312 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout8sizeHintEv +320 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout11minimumSizeEv +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout19expandingDirectionsEv +344 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayout11setGeometryERK5QRect +352 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +360 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +368 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout17hasHeightForWidthEv +376 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout14heightForWidthEi +384 (int (*)(...))QLayoutItem::minimumHeightForWidth +392 (int (*)(...))QLayout::_ZThn16_N7QLayout10invalidateEv +400 (int (*)(...))QLayoutItem::widget +408 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +416 (int (*)(...))QLayoutItem::spacerItem +424 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QStackedLayout + size=32 align=8 + base size=28 base align=8 +QStackedLayout (0x0x7fc665fbaea0) 0 + vptr=((& QStackedLayout::_ZTV14QStackedLayout) + 16) + QLayout (0x0x7fc665d54ee0) 0 + primary-for QStackedLayout (0x0x7fc665fbaea0) + QObject (0x0x7fc665a331e0) 0 + primary-for QLayout (0x0x7fc665d54ee0) + QLayoutItem (0x0x7fc665a33240) 16 + vptr=((& QStackedLayout::_ZTV14QStackedLayout) + 296) + +Class QStackedWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStackedWidget::QPrivateSignal (0x0x7fc665a335a0) 0 empty + +Vtable for QStackedWidget +QStackedWidget::_ZTV14QStackedWidget: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QStackedWidget) +16 (int (*)(...))QStackedWidget::metaObject +24 (int (*)(...))QStackedWidget::qt_metacast +32 (int (*)(...))QStackedWidget::qt_metacall +40 (int (*)(...))QStackedWidget::~QStackedWidget +48 (int (*)(...))QStackedWidget::~QStackedWidget +56 (int (*)(...))QStackedWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFrame::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI14QStackedWidget) +456 (int (*)(...))QStackedWidget::_ZThn16_N14QStackedWidgetD1Ev +464 (int (*)(...))QStackedWidget::_ZThn16_N14QStackedWidgetD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QStackedWidget + size=40 align=8 + base size=40 base align=8 +QStackedWidget (0x0x7fc665fbaf08) 0 + vptr=((& QStackedWidget::_ZTV14QStackedWidget) + 16) + QFrame (0x0x7fc665fbaf70) 0 + primary-for QStackedWidget (0x0x7fc665fbaf08) + QWidget (0x0x7fc665d54540) 0 + primary-for QFrame (0x0x7fc665fbaf70) + QObject (0x0x7fc665a334e0) 0 + primary-for QWidget (0x0x7fc665d54540) + QPaintDevice (0x0x7fc665a33540) 16 + vptr=((& QStackedWidget::_ZTV14QStackedWidget) + 456) + +Class QStatusBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStatusBar::QPrivateSignal (0x0x7fc665a337e0) 0 empty + +Vtable for QStatusBar +QStatusBar::_ZTV10QStatusBar: 64 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QStatusBar) +16 (int (*)(...))QStatusBar::metaObject +24 (int (*)(...))QStatusBar::qt_metacast +32 (int (*)(...))QStatusBar::qt_metacall +40 (int (*)(...))QStatusBar::~QStatusBar +48 (int (*)(...))QStatusBar::~QStatusBar +56 (int (*)(...))QStatusBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QStatusBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QStatusBar::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QStatusBar::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI10QStatusBar) +448 (int (*)(...))QStatusBar::_ZThn16_N10QStatusBarD1Ev +456 (int (*)(...))QStatusBar::_ZThn16_N10QStatusBarD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QStatusBar + size=40 align=8 + base size=40 base align=8 +QStatusBar (0x0x7fc665a6a000) 0 + vptr=((& QStatusBar::_ZTV10QStatusBar) + 16) + QWidget (0x0x7fc665d54620) 0 + primary-for QStatusBar (0x0x7fc665a6a000) + QObject (0x0x7fc665a33720) 0 + primary-for QWidget (0x0x7fc665d54620) + QPaintDevice (0x0x7fc665a33780) 16 + vptr=((& QStatusBar::_ZTV10QStatusBar) + 448) + +Class QStyledItemDelegate::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyledItemDelegate::QPrivateSignal (0x0x7fc665a339c0) 0 empty + +Vtable for QStyledItemDelegate +QStyledItemDelegate::_ZTV19QStyledItemDelegate: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QStyledItemDelegate) +16 (int (*)(...))QStyledItemDelegate::metaObject +24 (int (*)(...))QStyledItemDelegate::qt_metacast +32 (int (*)(...))QStyledItemDelegate::qt_metacall +40 (int (*)(...))QStyledItemDelegate::~QStyledItemDelegate +48 (int (*)(...))QStyledItemDelegate::~QStyledItemDelegate +56 (int (*)(...))QObject::event +64 (int (*)(...))QStyledItemDelegate::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStyledItemDelegate::paint +120 (int (*)(...))QStyledItemDelegate::sizeHint +128 (int (*)(...))QStyledItemDelegate::createEditor +136 (int (*)(...))QAbstractItemDelegate::destroyEditor +144 (int (*)(...))QStyledItemDelegate::setEditorData +152 (int (*)(...))QStyledItemDelegate::setModelData +160 (int (*)(...))QStyledItemDelegate::updateEditorGeometry +168 (int (*)(...))QStyledItemDelegate::editorEvent +176 (int (*)(...))QAbstractItemDelegate::helpEvent +184 (int (*)(...))QAbstractItemDelegate::paintingRoles +192 (int (*)(...))QStyledItemDelegate::displayText +200 (int (*)(...))QStyledItemDelegate::initStyleOption + +Class QStyledItemDelegate + size=16 align=8 + base size=16 base align=8 +QStyledItemDelegate (0x0x7fc665a6a068) 0 + vptr=((& QStyledItemDelegate::_ZTV19QStyledItemDelegate) + 16) + QAbstractItemDelegate (0x0x7fc665a6a0d0) 0 + primary-for QStyledItemDelegate (0x0x7fc665a6a068) + QObject (0x0x7fc665a33960) 0 + primary-for QAbstractItemDelegate (0x0x7fc665a6a0d0) + +Class QStyleFactory + size=1 align=1 + base size=0 base align=1 +QStyleFactory (0x0x7fc665a33b40) 0 empty + +Class QStylePainter + size=24 align=8 + base size=24 base align=8 +QStylePainter (0x0x7fc665a6a138) 0 + QPainter (0x0x7fc665a33ba0) 0 + +Class QStylePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStylePlugin::QPrivateSignal (0x0x7fc665a9c420) 0 empty + +Vtable for QStylePlugin +QStylePlugin::_ZTV12QStylePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QStylePlugin) +16 (int (*)(...))QStylePlugin::metaObject +24 (int (*)(...))QStylePlugin::qt_metacast +32 (int (*)(...))QStylePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QStylePlugin + size=16 align=8 + base size=16 base align=8 +QStylePlugin (0x0x7fc665a6a1a0) 0 + vptr=((& QStylePlugin::_ZTV12QStylePlugin) + 16) + QObject (0x0x7fc665a9c3c0) 0 + primary-for QStylePlugin (0x0x7fc665a6a1a0) + +Class QSystemTrayIcon::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSystemTrayIcon::QPrivateSignal (0x0x7fc665a9c540) 0 empty + +Vtable for QSystemTrayIcon +QSystemTrayIcon::_ZTV15QSystemTrayIcon: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSystemTrayIcon) +16 (int (*)(...))QSystemTrayIcon::metaObject +24 (int (*)(...))QSystemTrayIcon::qt_metacast +32 (int (*)(...))QSystemTrayIcon::qt_metacall +40 (int (*)(...))QSystemTrayIcon::~QSystemTrayIcon +48 (int (*)(...))QSystemTrayIcon::~QSystemTrayIcon +56 (int (*)(...))QSystemTrayIcon::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSystemTrayIcon + size=16 align=8 + base size=16 base align=8 +QSystemTrayIcon (0x0x7fc665a6a208) 0 + vptr=((& QSystemTrayIcon::_ZTV15QSystemTrayIcon) + 16) + QObject (0x0x7fc665a9c4e0) 0 + primary-for QSystemTrayIcon (0x0x7fc665a6a208) + +Class QTableView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTableView::QPrivateSignal (0x0x7fc665a9c840) 0 empty + +Vtable for QTableView +QTableView::_ZTV10QTableView: 108 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTableView) +16 (int (*)(...))QTableView::metaObject +24 (int (*)(...))QTableView::qt_metacast +32 (int (*)(...))QTableView::qt_metacall +40 (int (*)(...))QTableView::~QTableView +48 (int (*)(...))QTableView::~QTableView +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTableView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTableView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QAbstractItemView::viewportEvent +456 (int (*)(...))QTableView::scrollContentsBy +464 (int (*)(...))QTableView::viewportSizeHint +472 (int (*)(...))QTableView::setModel +480 (int (*)(...))QTableView::setSelectionModel +488 (int (*)(...))QAbstractItemView::keyboardSearch +496 (int (*)(...))QTableView::visualRect +504 (int (*)(...))QTableView::scrollTo +512 (int (*)(...))QTableView::indexAt +520 (int (*)(...))QTableView::sizeHintForRow +528 (int (*)(...))QTableView::sizeHintForColumn +536 (int (*)(...))QAbstractItemView::itemDelegateForIndex +544 (int (*)(...))QAbstractItemView::reset +552 (int (*)(...))QTableView::setRootIndex +560 (int (*)(...))QTableView::doItemsLayout +568 (int (*)(...))QAbstractItemView::selectAll +576 (int (*)(...))QAbstractItemView::dataChanged +584 (int (*)(...))QAbstractItemView::rowsInserted +592 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +600 (int (*)(...))QTableView::selectionChanged +608 (int (*)(...))QTableView::currentChanged +616 (int (*)(...))QAbstractItemView::updateEditorData +624 (int (*)(...))QAbstractItemView::updateEditorGeometries +632 (int (*)(...))QTableView::updateGeometries +640 (int (*)(...))QTableView::verticalScrollbarAction +648 (int (*)(...))QTableView::horizontalScrollbarAction +656 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +664 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +672 (int (*)(...))QAbstractItemView::closeEditor +680 (int (*)(...))QAbstractItemView::commitData +688 (int (*)(...))QAbstractItemView::editorDestroyed +696 (int (*)(...))QTableView::moveCursor +704 (int (*)(...))QTableView::horizontalOffset +712 (int (*)(...))QTableView::verticalOffset +720 (int (*)(...))QTableView::isIndexHidden +728 (int (*)(...))QTableView::setSelection +736 (int (*)(...))QTableView::visualRegionForSelection +744 (int (*)(...))QTableView::selectedIndexes +752 (int (*)(...))QAbstractItemView::edit +760 (int (*)(...))QAbstractItemView::selectionCommand +768 (int (*)(...))QAbstractItemView::startDrag +776 (int (*)(...))QTableView::initViewItemOption +784 (int (*)(...))-16 +792 (int (*)(...))(& _ZTI10QTableView) +800 (int (*)(...))QTableView::_ZThn16_N10QTableViewD1Ev +808 (int (*)(...))QTableView::_ZThn16_N10QTableViewD0Ev +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTableView + size=40 align=8 + base size=40 base align=8 +QTableView (0x0x7fc665a6a270) 0 + vptr=((& QTableView::_ZTV10QTableView) + 16) + QAbstractItemView (0x0x7fc665a6a2d8) 0 + primary-for QTableView (0x0x7fc665a6a270) + QAbstractScrollArea (0x0x7fc665a6a340) 0 + primary-for QAbstractItemView (0x0x7fc665a6a2d8) + QFrame (0x0x7fc665a6a3a8) 0 + primary-for QAbstractScrollArea (0x0x7fc665a6a340) + QWidget (0x0x7fc665aa7460) 0 + primary-for QFrame (0x0x7fc665a6a3a8) + QObject (0x0x7fc665a9c780) 0 + primary-for QWidget (0x0x7fc665aa7460) + QPaintDevice (0x0x7fc665a9c7e0) 16 + vptr=((& QTableView::_ZTV10QTableView) + 800) + +Class QTableWidgetSelectionRange + size=16 align=4 + base size=16 base align=4 +QTableWidgetSelectionRange (0x0x7fc665a9c9c0) 0 + +Vtable for QTableWidgetItem +QTableWidgetItem::_ZTV16QTableWidgetItem: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QTableWidgetItem) +16 (int (*)(...))QTableWidgetItem::~QTableWidgetItem +24 (int (*)(...))QTableWidgetItem::~QTableWidgetItem +32 (int (*)(...))QTableWidgetItem::clone +40 (int (*)(...))QTableWidgetItem::data +48 (int (*)(...))QTableWidgetItem::setData +56 (int (*)(...))QTableWidgetItem::operator< +64 (int (*)(...))QTableWidgetItem::read +72 (int (*)(...))QTableWidgetItem::write + +Class QTableWidgetItem + size=64 align=8 + base size=60 base align=8 +QTableWidgetItem (0x0x7fc665a9cde0) 0 + vptr=((& QTableWidgetItem::_ZTV16QTableWidgetItem) + 16) + +Class QTableWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTableWidget::QPrivateSignal (0x0x7fc665b82120) 0 empty + +Vtable for QTableWidget +QTableWidget::_ZTV12QTableWidget: 112 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTableWidget) +16 (int (*)(...))QTableWidget::metaObject +24 (int (*)(...))QTableWidget::qt_metacast +32 (int (*)(...))QTableWidget::qt_metacall +40 (int (*)(...))QTableWidget::~QTableWidget +48 (int (*)(...))QTableWidget::~QTableWidget +56 (int (*)(...))QTableWidget::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTableView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTableView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QTableWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QAbstractItemView::viewportEvent +456 (int (*)(...))QTableView::scrollContentsBy +464 (int (*)(...))QTableView::viewportSizeHint +472 (int (*)(...))QTableWidget::setModel +480 (int (*)(...))QTableView::setSelectionModel +488 (int (*)(...))QAbstractItemView::keyboardSearch +496 (int (*)(...))QTableView::visualRect +504 (int (*)(...))QTableView::scrollTo +512 (int (*)(...))QTableView::indexAt +520 (int (*)(...))QTableView::sizeHintForRow +528 (int (*)(...))QTableView::sizeHintForColumn +536 (int (*)(...))QAbstractItemView::itemDelegateForIndex +544 (int (*)(...))QAbstractItemView::reset +552 (int (*)(...))QTableView::setRootIndex +560 (int (*)(...))QTableView::doItemsLayout +568 (int (*)(...))QAbstractItemView::selectAll +576 (int (*)(...))QAbstractItemView::dataChanged +584 (int (*)(...))QAbstractItemView::rowsInserted +592 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +600 (int (*)(...))QTableView::selectionChanged +608 (int (*)(...))QTableView::currentChanged +616 (int (*)(...))QAbstractItemView::updateEditorData +624 (int (*)(...))QAbstractItemView::updateEditorGeometries +632 (int (*)(...))QTableView::updateGeometries +640 (int (*)(...))QTableView::verticalScrollbarAction +648 (int (*)(...))QTableView::horizontalScrollbarAction +656 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +664 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +672 (int (*)(...))QAbstractItemView::closeEditor +680 (int (*)(...))QAbstractItemView::commitData +688 (int (*)(...))QAbstractItemView::editorDestroyed +696 (int (*)(...))QTableView::moveCursor +704 (int (*)(...))QTableView::horizontalOffset +712 (int (*)(...))QTableView::verticalOffset +720 (int (*)(...))QTableView::isIndexHidden +728 (int (*)(...))QTableView::setSelection +736 (int (*)(...))QTableView::visualRegionForSelection +744 (int (*)(...))QTableView::selectedIndexes +752 (int (*)(...))QAbstractItemView::edit +760 (int (*)(...))QAbstractItemView::selectionCommand +768 (int (*)(...))QAbstractItemView::startDrag +776 (int (*)(...))QTableView::initViewItemOption +784 (int (*)(...))QTableWidget::mimeTypes +792 (int (*)(...))QTableWidget::mimeData +800 (int (*)(...))QTableWidget::dropMimeData +808 (int (*)(...))QTableWidget::supportedDropActions +816 (int (*)(...))-16 +824 (int (*)(...))(& _ZTI12QTableWidget) +832 (int (*)(...))QTableWidget::_ZThn16_N12QTableWidgetD1Ev +840 (int (*)(...))QTableWidget::_ZThn16_N12QTableWidgetD0Ev +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +880 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +888 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTableWidget + size=40 align=8 + base size=40 base align=8 +QTableWidget (0x0x7fc665a6ac98) 0 + vptr=((& QTableWidget::_ZTV12QTableWidget) + 16) + QTableView (0x0x7fc665a6ad00) 0 + primary-for QTableWidget (0x0x7fc665a6ac98) + QAbstractItemView (0x0x7fc665a6ad68) 0 + primary-for QTableView (0x0x7fc665a6ad00) + QAbstractScrollArea (0x0x7fc665a6add0) 0 + primary-for QAbstractItemView (0x0x7fc665a6ad68) + QFrame (0x0x7fc665a6ae38) 0 + primary-for QAbstractScrollArea (0x0x7fc665a6add0) + QWidget (0x0x7fc666169690) 0 + primary-for QFrame (0x0x7fc665a6ae38) + QObject (0x0x7fc665b82060) 0 + primary-for QWidget (0x0x7fc666169690) + QPaintDevice (0x0x7fc665b820c0) 16 + vptr=((& QTableWidget::_ZTV12QTableWidget) + 832) + +Class QTextBrowser::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBrowser::QPrivateSignal (0x0x7fc665b824e0) 0 empty + +Vtable for QTextBrowser +QTextBrowser::_ZTV12QTextBrowser: 79 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTextBrowser) +16 (int (*)(...))QTextBrowser::metaObject +24 (int (*)(...))QTextBrowser::qt_metacast +32 (int (*)(...))QTextBrowser::qt_metacall +40 (int (*)(...))QTextBrowser::~QTextBrowser +48 (int (*)(...))QTextBrowser::~QTextBrowser +56 (int (*)(...))QTextBrowser::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QTextEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTextBrowser::mousePressEvent +176 (int (*)(...))QTextBrowser::mouseReleaseEvent +184 (int (*)(...))QTextEdit::mouseDoubleClickEvent +192 (int (*)(...))QTextBrowser::mouseMoveEvent +200 (int (*)(...))QTextEdit::wheelEvent +208 (int (*)(...))QTextBrowser::keyPressEvent +216 (int (*)(...))QTextEdit::keyReleaseEvent +224 (int (*)(...))QTextEdit::focusInEvent +232 (int (*)(...))QTextBrowser::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTextBrowser::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTextEdit::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QTextEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QTextEdit::dragEnterEvent +320 (int (*)(...))QTextEdit::dragMoveEvent +328 (int (*)(...))QTextEdit::dragLeaveEvent +336 (int (*)(...))QTextEdit::dropEvent +344 (int (*)(...))QTextEdit::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTextEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QTextEdit::inputMethodEvent +416 (int (*)(...))QTextEdit::inputMethodQuery +424 (int (*)(...))QTextBrowser::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QAbstractScrollArea::viewportEvent +456 (int (*)(...))QTextEdit::scrollContentsBy +464 (int (*)(...))QAbstractScrollArea::viewportSizeHint +472 (int (*)(...))QTextBrowser::loadResource +480 (int (*)(...))QTextEdit::createMimeDataFromSelection +488 (int (*)(...))QTextEdit::canInsertFromMimeData +496 (int (*)(...))QTextEdit::insertFromMimeData +504 (int (*)(...))QTextEdit::doSetTextCursor +512 (int (*)(...))QTextBrowser::backward +520 (int (*)(...))QTextBrowser::forward +528 (int (*)(...))QTextBrowser::home +536 (int (*)(...))QTextBrowser::reload +544 (int (*)(...))QTextBrowser::doSetSource +552 (int (*)(...))-16 +560 (int (*)(...))(& _ZTI12QTextBrowser) +568 (int (*)(...))QTextBrowser::_ZThn16_N12QTextBrowserD1Ev +576 (int (*)(...))QTextBrowser::_ZThn16_N12QTextBrowserD0Ev +584 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +592 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +600 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +608 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +616 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +624 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTextBrowser + size=40 align=8 + base size=40 base align=8 +QTextBrowser (0x0x7fc665a6aea0) 0 + vptr=((& QTextBrowser::_ZTV12QTextBrowser) + 16) + QTextEdit (0x0x7fc665a6af08) 0 + primary-for QTextBrowser (0x0x7fc665a6aea0) + QAbstractScrollArea (0x0x7fc665a6af70) 0 + primary-for QTextEdit (0x0x7fc665a6af08) + QFrame (0x0x7fc665a6ac30) 0 + primary-for QAbstractScrollArea (0x0x7fc665a6af70) + QWidget (0x0x7fc665aa7690) 0 + primary-for QFrame (0x0x7fc665a6ac30) + QObject (0x0x7fc665b82420) 0 + primary-for QWidget (0x0x7fc665aa7690) + QPaintDevice (0x0x7fc665b82480) 16 + vptr=((& QTextBrowser::_ZTV12QTextBrowser) + 568) + +Class QToolBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QToolBar::QPrivateSignal (0x0x7fc665b82720) 0 empty + +Vtable for QToolBar +QToolBar::_ZTV8QToolBar: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QToolBar) +16 (int (*)(...))QToolBar::metaObject +24 (int (*)(...))QToolBar::qt_metacast +32 (int (*)(...))QToolBar::qt_metacall +40 (int (*)(...))QToolBar::~QToolBar +48 (int (*)(...))QToolBar::~QToolBar +56 (int (*)(...))QToolBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QToolBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QToolBar::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QToolBar::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QToolBar::initStyleOption +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI8QToolBar) +456 (int (*)(...))QToolBar::_ZThn16_N8QToolBarD1Ev +464 (int (*)(...))QToolBar::_ZThn16_N8QToolBarD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QToolBar + size=40 align=8 + base size=40 base align=8 +QToolBar (0x0x7fc6657c6000) 0 + vptr=((& QToolBar::_ZTV8QToolBar) + 16) + QWidget (0x0x7fc665aa7700) 0 + primary-for QToolBar (0x0x7fc6657c6000) + QObject (0x0x7fc665b82660) 0 + primary-for QWidget (0x0x7fc665aa7700) + QPaintDevice (0x0x7fc665b826c0) 16 + vptr=((& QToolBar::_ZTV8QToolBar) + 456) + +Class QToolBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QToolBox::QPrivateSignal (0x0x7fc665b82ba0) 0 empty + +Vtable for QToolBox +QToolBox::_ZTV8QToolBox: 67 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QToolBox) +16 (int (*)(...))QToolBox::metaObject +24 (int (*)(...))QToolBox::qt_metacast +32 (int (*)(...))QToolBox::qt_metacall +40 (int (*)(...))QToolBox::~QToolBox +48 (int (*)(...))QToolBox::~QToolBox +56 (int (*)(...))QToolBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFrame::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QToolBox::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QToolBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QToolBox::itemInserted +448 (int (*)(...))QToolBox::itemRemoved +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI8QToolBox) +472 (int (*)(...))QToolBox::_ZThn16_N8QToolBoxD1Ev +480 (int (*)(...))QToolBox::_ZThn16_N8QToolBoxD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QToolBox + size=40 align=8 + base size=40 base align=8 +QToolBox (0x0x7fc6657c6068) 0 + vptr=((& QToolBox::_ZTV8QToolBox) + 16) + QFrame (0x0x7fc6657c60d0) 0 + primary-for QToolBox (0x0x7fc6657c6068) + QWidget (0x0x7fc665aa7770) 0 + primary-for QFrame (0x0x7fc6657c60d0) + QObject (0x0x7fc665b82ae0) 0 + primary-for QWidget (0x0x7fc665aa7770) + QPaintDevice (0x0x7fc665b82b40) 16 + vptr=((& QToolBox::_ZTV8QToolBox) + 472) + +Class QToolButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QToolButton::QPrivateSignal (0x0x7fc665b82f00) 0 empty + +Vtable for QToolButton +QToolButton::_ZTV11QToolButton: 68 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QToolButton) +16 (int (*)(...))QToolButton::metaObject +24 (int (*)(...))QToolButton::qt_metacast +32 (int (*)(...))QToolButton::qt_metacall +40 (int (*)(...))QToolButton::~QToolButton +48 (int (*)(...))QToolButton::~QToolButton +56 (int (*)(...))QToolButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QToolButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QToolButton::sizeHint +136 (int (*)(...))QToolButton::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QToolButton::mousePressEvent +176 (int (*)(...))QToolButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QToolButton::enterEvent +248 (int (*)(...))QToolButton::leaveEvent +256 (int (*)(...))QToolButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QToolButton::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QToolButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QToolButton::hitButton +440 (int (*)(...))QToolButton::checkStateSet +448 (int (*)(...))QToolButton::nextCheckState +456 (int (*)(...))QToolButton::initStyleOption +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI11QToolButton) +480 (int (*)(...))QToolButton::_ZThn16_N11QToolButtonD1Ev +488 (int (*)(...))QToolButton::_ZThn16_N11QToolButtonD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QToolButton + size=40 align=8 + base size=40 base align=8 +QToolButton (0x0x7fc6657c6138) 0 + vptr=((& QToolButton::_ZTV11QToolButton) + 16) + QAbstractButton (0x0x7fc6657c61a0) 0 + primary-for QToolButton (0x0x7fc6657c6138) + QWidget (0x0x7fc665aa77e0) 0 + primary-for QAbstractButton (0x0x7fc6657c61a0) + QObject (0x0x7fc665b82e40) 0 + primary-for QWidget (0x0x7fc665aa77e0) + QPaintDevice (0x0x7fc665b82ea0) 16 + vptr=((& QToolButton::_ZTV11QToolButton) + 480) + +Class QToolTip + size=1 align=1 + base size=0 base align=1 +QToolTip (0x0x7fc66581e180) 0 empty + +Class QTreeView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTreeView::QPrivateSignal (0x0x7fc66581e300) 0 empty + +Vtable for QTreeView +QTreeView::_ZTV9QTreeView: 110 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTreeView) +16 (int (*)(...))QTreeView::metaObject +24 (int (*)(...))QTreeView::qt_metacast +32 (int (*)(...))QTreeView::qt_metacall +40 (int (*)(...))QTreeView::~QTreeView +48 (int (*)(...))QTreeView::~QTreeView +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTreeView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTreeView::mousePressEvent +176 (int (*)(...))QTreeView::mouseReleaseEvent +184 (int (*)(...))QTreeView::mouseDoubleClickEvent +192 (int (*)(...))QTreeView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QTreeView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTreeView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QTreeView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTreeView::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QTreeView::viewportEvent +456 (int (*)(...))QTreeView::scrollContentsBy +464 (int (*)(...))QTreeView::viewportSizeHint +472 (int (*)(...))QTreeView::setModel +480 (int (*)(...))QTreeView::setSelectionModel +488 (int (*)(...))QTreeView::keyboardSearch +496 (int (*)(...))QTreeView::visualRect +504 (int (*)(...))QTreeView::scrollTo +512 (int (*)(...))QTreeView::indexAt +520 (int (*)(...))QAbstractItemView::sizeHintForRow +528 (int (*)(...))QTreeView::sizeHintForColumn +536 (int (*)(...))QAbstractItemView::itemDelegateForIndex +544 (int (*)(...))QTreeView::reset +552 (int (*)(...))QTreeView::setRootIndex +560 (int (*)(...))QTreeView::doItemsLayout +568 (int (*)(...))QTreeView::selectAll +576 (int (*)(...))QTreeView::dataChanged +584 (int (*)(...))QTreeView::rowsInserted +592 (int (*)(...))QTreeView::rowsAboutToBeRemoved +600 (int (*)(...))QTreeView::selectionChanged +608 (int (*)(...))QTreeView::currentChanged +616 (int (*)(...))QAbstractItemView::updateEditorData +624 (int (*)(...))QAbstractItemView::updateEditorGeometries +632 (int (*)(...))QTreeView::updateGeometries +640 (int (*)(...))QAbstractItemView::verticalScrollbarAction +648 (int (*)(...))QTreeView::horizontalScrollbarAction +656 (int (*)(...))QTreeView::verticalScrollbarValueChanged +664 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +672 (int (*)(...))QAbstractItemView::closeEditor +680 (int (*)(...))QAbstractItemView::commitData +688 (int (*)(...))QAbstractItemView::editorDestroyed +696 (int (*)(...))QTreeView::moveCursor +704 (int (*)(...))QTreeView::horizontalOffset +712 (int (*)(...))QTreeView::verticalOffset +720 (int (*)(...))QTreeView::isIndexHidden +728 (int (*)(...))QTreeView::setSelection +736 (int (*)(...))QTreeView::visualRegionForSelection +744 (int (*)(...))QTreeView::selectedIndexes +752 (int (*)(...))QAbstractItemView::edit +760 (int (*)(...))QAbstractItemView::selectionCommand +768 (int (*)(...))QAbstractItemView::startDrag +776 (int (*)(...))QAbstractItemView::initViewItemOption +784 (int (*)(...))QTreeView::drawRow +792 (int (*)(...))QTreeView::drawBranches +800 (int (*)(...))-16 +808 (int (*)(...))(& _ZTI9QTreeView) +816 (int (*)(...))QTreeView::_ZThn16_N9QTreeViewD1Ev +824 (int (*)(...))QTreeView::_ZThn16_N9QTreeViewD0Ev +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTreeView + size=40 align=8 + base size=40 base align=8 +QTreeView (0x0x7fc6657c6208) 0 + vptr=((& QTreeView::_ZTV9QTreeView) + 16) + QAbstractItemView (0x0x7fc6657c6270) 0 + primary-for QTreeView (0x0x7fc6657c6208) + QAbstractScrollArea (0x0x7fc6657c62d8) 0 + primary-for QAbstractItemView (0x0x7fc6657c6270) + QFrame (0x0x7fc6657c6340) 0 + primary-for QAbstractScrollArea (0x0x7fc6657c62d8) + QWidget (0x0x7fc665aa79a0) 0 + primary-for QFrame (0x0x7fc6657c6340) + QObject (0x0x7fc66581e240) 0 + primary-for QWidget (0x0x7fc665aa79a0) + QPaintDevice (0x0x7fc66581e2a0) 16 + vptr=((& QTreeView::_ZTV9QTreeView) + 816) + +Class QTreeWidgetItemIterator + size=24 align=8 + base size=20 base align=8 +QTreeWidgetItemIterator (0x0x7fc66581e480) 0 + +Vtable for QTreeWidgetItem +QTreeWidgetItem::_ZTV15QTreeWidgetItem: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTreeWidgetItem) +16 (int (*)(...))QTreeWidgetItem::~QTreeWidgetItem +24 (int (*)(...))QTreeWidgetItem::~QTreeWidgetItem +32 (int (*)(...))QTreeWidgetItem::clone +40 (int (*)(...))QTreeWidgetItem::data +48 (int (*)(...))QTreeWidgetItem::setData +56 (int (*)(...))QTreeWidgetItem::operator< +64 (int (*)(...))QTreeWidgetItem::read +72 (int (*)(...))QTreeWidgetItem::write + +Class QTreeWidgetItem + size=96 align=8 + base size=92 base align=8 +QTreeWidgetItem (0x0x7fc66581ec00) 0 + vptr=((& QTreeWidgetItem::_ZTV15QTreeWidgetItem) + 16) + +Class QTreeWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTreeWidget::QPrivateSignal (0x0x7fc6659b2a20) 0 empty + +Vtable for QTreeWidget +QTreeWidget::_ZTV11QTreeWidget: 114 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTreeWidget) +16 (int (*)(...))QTreeWidget::metaObject +24 (int (*)(...))QTreeWidget::qt_metacast +32 (int (*)(...))QTreeWidget::qt_metacall +40 (int (*)(...))QTreeWidget::~QTreeWidget +48 (int (*)(...))QTreeWidget::~QTreeWidget +56 (int (*)(...))QTreeWidget::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTreeView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTreeView::mousePressEvent +176 (int (*)(...))QTreeView::mouseReleaseEvent +184 (int (*)(...))QTreeView::mouseDoubleClickEvent +192 (int (*)(...))QTreeView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QTreeView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTreeView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QTreeView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QTreeWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTreeView::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QTreeView::viewportEvent +456 (int (*)(...))QTreeView::scrollContentsBy +464 (int (*)(...))QTreeView::viewportSizeHint +472 (int (*)(...))QTreeWidget::setModel +480 (int (*)(...))QTreeWidget::setSelectionModel +488 (int (*)(...))QTreeView::keyboardSearch +496 (int (*)(...))QTreeView::visualRect +504 (int (*)(...))QTreeView::scrollTo +512 (int (*)(...))QTreeView::indexAt +520 (int (*)(...))QAbstractItemView::sizeHintForRow +528 (int (*)(...))QTreeView::sizeHintForColumn +536 (int (*)(...))QAbstractItemView::itemDelegateForIndex +544 (int (*)(...))QTreeView::reset +552 (int (*)(...))QTreeView::setRootIndex +560 (int (*)(...))QTreeView::doItemsLayout +568 (int (*)(...))QTreeView::selectAll +576 (int (*)(...))QTreeView::dataChanged +584 (int (*)(...))QTreeView::rowsInserted +592 (int (*)(...))QTreeView::rowsAboutToBeRemoved +600 (int (*)(...))QTreeView::selectionChanged +608 (int (*)(...))QTreeView::currentChanged +616 (int (*)(...))QAbstractItemView::updateEditorData +624 (int (*)(...))QAbstractItemView::updateEditorGeometries +632 (int (*)(...))QTreeView::updateGeometries +640 (int (*)(...))QAbstractItemView::verticalScrollbarAction +648 (int (*)(...))QTreeView::horizontalScrollbarAction +656 (int (*)(...))QTreeView::verticalScrollbarValueChanged +664 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +672 (int (*)(...))QAbstractItemView::closeEditor +680 (int (*)(...))QAbstractItemView::commitData +688 (int (*)(...))QAbstractItemView::editorDestroyed +696 (int (*)(...))QTreeView::moveCursor +704 (int (*)(...))QTreeView::horizontalOffset +712 (int (*)(...))QTreeView::verticalOffset +720 (int (*)(...))QTreeView::isIndexHidden +728 (int (*)(...))QTreeView::setSelection +736 (int (*)(...))QTreeView::visualRegionForSelection +744 (int (*)(...))QTreeView::selectedIndexes +752 (int (*)(...))QAbstractItemView::edit +760 (int (*)(...))QAbstractItemView::selectionCommand +768 (int (*)(...))QAbstractItemView::startDrag +776 (int (*)(...))QAbstractItemView::initViewItemOption +784 (int (*)(...))QTreeView::drawRow +792 (int (*)(...))QTreeView::drawBranches +800 (int (*)(...))QTreeWidget::mimeTypes +808 (int (*)(...))QTreeWidget::mimeData +816 (int (*)(...))QTreeWidget::dropMimeData +824 (int (*)(...))QTreeWidget::supportedDropActions +832 (int (*)(...))-16 +840 (int (*)(...))(& _ZTI11QTreeWidget) +848 (int (*)(...))QTreeWidget::_ZThn16_N11QTreeWidgetD1Ev +856 (int (*)(...))QTreeWidget::_ZThn16_N11QTreeWidgetD0Ev +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +880 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +888 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +896 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +904 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTreeWidget + size=40 align=8 + base size=40 base align=8 +QTreeWidget (0x0x7fc66594f680) 0 + vptr=((& QTreeWidget::_ZTV11QTreeWidget) + 16) + QTreeView (0x0x7fc66594f6e8) 0 + primary-for QTreeWidget (0x0x7fc66594f680) + QAbstractItemView (0x0x7fc66594f750) 0 + primary-for QTreeView (0x0x7fc66594f6e8) + QAbstractScrollArea (0x0x7fc66594f7b8) 0 + primary-for QAbstractItemView (0x0x7fc66594f750) + QFrame (0x0x7fc66594f820) 0 + primary-for QAbstractScrollArea (0x0x7fc66594f7b8) + QWidget (0x0x7fc66584e770) 0 + primary-for QFrame (0x0x7fc66594f820) + QObject (0x0x7fc6659b2960) 0 + primary-for QWidget (0x0x7fc66584e770) + QPaintDevice (0x0x7fc6659b29c0) 16 + vptr=((& QTreeWidget::_ZTV11QTreeWidget) + 848) + +Class QUndoView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoView::QPrivateSignal (0x0x7fc6659b2e40) 0 empty + +Vtable for QUndoView +QUndoView::_ZTV9QUndoView: 108 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QUndoView) +16 (int (*)(...))QUndoView::metaObject +24 (int (*)(...))QUndoView::qt_metacast +32 (int (*)(...))QUndoView::qt_metacall +40 (int (*)(...))QUndoView::~QUndoView +48 (int (*)(...))QUndoView::~QUndoView +56 (int (*)(...))QListView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QListView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QListView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QListView::mouseMoveEvent +200 (int (*)(...))QListView::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QListView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QListView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QListView::dragMoveEvent +328 (int (*)(...))QListView::dragLeaveEvent +336 (int (*)(...))QListView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QFrame::initStyleOption +440 (int (*)(...))QAbstractScrollArea::setupViewport +448 (int (*)(...))QAbstractItemView::viewportEvent +456 (int (*)(...))QListView::scrollContentsBy +464 (int (*)(...))QListView::viewportSizeHint +472 (int (*)(...))QAbstractItemView::setModel +480 (int (*)(...))QAbstractItemView::setSelectionModel +488 (int (*)(...))QAbstractItemView::keyboardSearch +496 (int (*)(...))QListView::visualRect +504 (int (*)(...))QListView::scrollTo +512 (int (*)(...))QListView::indexAt +520 (int (*)(...))QAbstractItemView::sizeHintForRow +528 (int (*)(...))QAbstractItemView::sizeHintForColumn +536 (int (*)(...))QAbstractItemView::itemDelegateForIndex +544 (int (*)(...))QListView::reset +552 (int (*)(...))QListView::setRootIndex +560 (int (*)(...))QListView::doItemsLayout +568 (int (*)(...))QAbstractItemView::selectAll +576 (int (*)(...))QListView::dataChanged +584 (int (*)(...))QListView::rowsInserted +592 (int (*)(...))QListView::rowsAboutToBeRemoved +600 (int (*)(...))QListView::selectionChanged +608 (int (*)(...))QListView::currentChanged +616 (int (*)(...))QAbstractItemView::updateEditorData +624 (int (*)(...))QAbstractItemView::updateEditorGeometries +632 (int (*)(...))QListView::updateGeometries +640 (int (*)(...))QAbstractItemView::verticalScrollbarAction +648 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +656 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +664 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +672 (int (*)(...))QAbstractItemView::closeEditor +680 (int (*)(...))QAbstractItemView::commitData +688 (int (*)(...))QAbstractItemView::editorDestroyed +696 (int (*)(...))QListView::moveCursor +704 (int (*)(...))QListView::horizontalOffset +712 (int (*)(...))QListView::verticalOffset +720 (int (*)(...))QListView::isIndexHidden +728 (int (*)(...))QListView::setSelection +736 (int (*)(...))QListView::visualRegionForSelection +744 (int (*)(...))QListView::selectedIndexes +752 (int (*)(...))QAbstractItemView::edit +760 (int (*)(...))QAbstractItemView::selectionCommand +768 (int (*)(...))QListView::startDrag +776 (int (*)(...))QListView::initViewItemOption +784 (int (*)(...))-16 +792 (int (*)(...))(& _ZTI9QUndoView) +800 (int (*)(...))QUndoView::_ZThn16_N9QUndoViewD1Ev +808 (int (*)(...))QUndoView::_ZThn16_N9QUndoViewD0Ev +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QUndoView + size=40 align=8 + base size=40 base align=8 +QUndoView (0x0x7fc66594f888) 0 + vptr=((& QUndoView::_ZTV9QUndoView) + 16) + QListView (0x0x7fc66594f8f0) 0 + primary-for QUndoView (0x0x7fc66594f888) + QAbstractItemView (0x0x7fc66594f958) 0 + primary-for QListView (0x0x7fc66594f8f0) + QAbstractScrollArea (0x0x7fc66594f9c0) 0 + primary-for QAbstractItemView (0x0x7fc66594f958) + QFrame (0x0x7fc66594fa28) 0 + primary-for QAbstractScrollArea (0x0x7fc66594f9c0) + QWidget (0x0x7fc66584e7e0) 0 + primary-for QFrame (0x0x7fc66594fa28) + QObject (0x0x7fc6659b2d80) 0 + primary-for QWidget (0x0x7fc66584e7e0) + QPaintDevice (0x0x7fc6659b2de0) 16 + vptr=((& QUndoView::_ZTV9QUndoView) + 800) + +Class QWhatsThis + size=1 align=1 + base size=0 base align=1 +QWhatsThis (0x0x7fc665630000) 0 empty + +Class QWidgetAction::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWidgetAction::QPrivateSignal (0x0x7fc6656300c0) 0 empty + +Vtable for QWidgetAction +QWidgetAction::_ZTV13QWidgetAction: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QWidgetAction) +16 (int (*)(...))QWidgetAction::metaObject +24 (int (*)(...))QWidgetAction::qt_metacast +32 (int (*)(...))QWidgetAction::qt_metacall +40 (int (*)(...))QWidgetAction::~QWidgetAction +48 (int (*)(...))QWidgetAction::~QWidgetAction +56 (int (*)(...))QWidgetAction::event +64 (int (*)(...))QWidgetAction::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidgetAction::createWidget +120 (int (*)(...))QWidgetAction::deleteWidget + +Class QWidgetAction + size=16 align=8 + base size=16 base align=8 +QWidgetAction (0x0x7fc66594fa90) 0 + vptr=((& QWidgetAction::_ZTV13QWidgetAction) + 16) + QAction (0x0x7fc66594faf8) 0 + primary-for QWidgetAction (0x0x7fc66594fa90) + QObject (0x0x7fc665630060) 0 + primary-for QAction (0x0x7fc66594faf8) + +Class QWizard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWizard::QPrivateSignal (0x0x7fc665630300) 0 empty + +Vtable for QWizard +QWizard::_ZTV7QWizard: 73 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWizard) +16 (int (*)(...))QWizard::metaObject +24 (int (*)(...))QWizard::qt_metacast +32 (int (*)(...))QWizard::qt_metacall +40 (int (*)(...))QWizard::~QWizard +48 (int (*)(...))QWizard::~QWizard +56 (int (*)(...))QWizard::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWizard::setVisible +128 (int (*)(...))QWizard::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWizard::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWizard::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QWizard::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))QWizard::validateCurrentPage +480 (int (*)(...))QWizard::nextId +488 (int (*)(...))QWizard::initializePage +496 (int (*)(...))QWizard::cleanupPage +504 (int (*)(...))-16 +512 (int (*)(...))(& _ZTI7QWizard) +520 (int (*)(...))QWizard::_ZThn16_N7QWizardD1Ev +528 (int (*)(...))QWizard::_ZThn16_N7QWizardD0Ev +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QWizard + size=40 align=8 + base size=40 base align=8 +QWizard (0x0x7fc66594fb60) 0 + vptr=((& QWizard::_ZTV7QWizard) + 16) + QDialog (0x0x7fc66594fbc8) 0 + primary-for QWizard (0x0x7fc66594fb60) + QWidget (0x0x7fc66584e850) 0 + primary-for QDialog (0x0x7fc66594fbc8) + QObject (0x0x7fc665630240) 0 + primary-for QWidget (0x0x7fc66584e850) + QPaintDevice (0x0x7fc6656302a0) 16 + vptr=((& QWizard::_ZTV7QWizard) + 520) + +Class QWizardPage::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWizardPage::QPrivateSignal (0x0x7fc665630b40) 0 empty + +Vtable for QWizardPage +QWizardPage::_ZTV11QWizardPage: 69 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWizardPage) +16 (int (*)(...))QWizardPage::metaObject +24 (int (*)(...))QWizardPage::qt_metacast +32 (int (*)(...))QWizardPage::qt_metacall +40 (int (*)(...))QWizardPage::~QWizardPage +48 (int (*)(...))QWizardPage::~QWizardPage +56 (int (*)(...))QWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QWizardPage::initializePage +440 (int (*)(...))QWizardPage::cleanupPage +448 (int (*)(...))QWizardPage::validatePage +456 (int (*)(...))QWizardPage::isComplete +464 (int (*)(...))QWizardPage::nextId +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QWizardPage) +488 (int (*)(...))QWizardPage::_ZThn16_N11QWizardPageD1Ev +496 (int (*)(...))QWizardPage::_ZThn16_N11QWizardPageD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QWizardPage + size=40 align=8 + base size=40 base align=8 +QWizardPage (0x0x7fc66594fd68) 0 + vptr=((& QWizardPage::_ZTV11QWizardPage) + 16) + QWidget (0x0x7fc665644a10) 0 + primary-for QWizardPage (0x0x7fc66594fd68) + QObject (0x0x7fc665630a80) 0 + primary-for QWidget (0x0x7fc665644a10) + QPaintDevice (0x0x7fc665630ae0) 16 + vptr=((& QWizardPage::_ZTV11QWizardPage) + 488) + +Class QQuickWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickWidget::QPrivateSignal (0x0x7fc665630d80) 0 empty + +Vtable for QQuickWidget +QQuickWidget::_ZTV12QQuickWidget: 64 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QQuickWidget) +16 (int (*)(...))QQuickWidget::metaObject +24 (int (*)(...))QQuickWidget::qt_metacast +32 (int (*)(...))QQuickWidget::qt_metacall +40 (int (*)(...))QQuickWidget::~QQuickWidget +48 (int (*)(...))QQuickWidget::~QQuickWidget +56 (int (*)(...))QQuickWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QQuickWidget::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QQuickWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QQuickWidget::mousePressEvent +176 (int (*)(...))QQuickWidget::mouseReleaseEvent +184 (int (*)(...))QQuickWidget::mouseDoubleClickEvent +192 (int (*)(...))QQuickWidget::mouseMoveEvent +200 (int (*)(...))QQuickWidget::wheelEvent +208 (int (*)(...))QQuickWidget::keyPressEvent +216 (int (*)(...))QQuickWidget::keyReleaseEvent +224 (int (*)(...))QQuickWidget::focusInEvent +232 (int (*)(...))QQuickWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QQuickWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QQuickWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QQuickWidget::dragEnterEvent +320 (int (*)(...))QQuickWidget::dragMoveEvent +328 (int (*)(...))QQuickWidget::dragLeaveEvent +336 (int (*)(...))QQuickWidget::dropEvent +344 (int (*)(...))QQuickWidget::showEvent +352 (int (*)(...))QQuickWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QQuickWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI12QQuickWidget) +448 (int (*)(...))QQuickWidget::_ZThn16_N12QQuickWidgetD1Ev +456 (int (*)(...))QQuickWidget::_ZThn16_N12QQuickWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QQuickWidget + size=40 align=8 + base size=40 base align=8 +QQuickWidget (0x0x7fc66594fdd0) 0 + vptr=((& QQuickWidget::_ZTV12QQuickWidget) + 16) + QWidget (0x0x7fc665644a80) 0 + primary-for QQuickWidget (0x0x7fc66594fdd0) + QObject (0x0x7fc665630cc0) 0 + primary-for QWidget (0x0x7fc665644a80) + QPaintDevice (0x0x7fc665630d20) 16 + vptr=((& QQuickWidget::_ZTV12QQuickWidget) + 448) + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc6656ecf60) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc665715300) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc6657154e0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc665715840) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc665715a20) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc665715d80) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc665715f00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc665746240) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc665746420) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc665746780) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc665746960) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc665746cc0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc665746ea0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc665776240) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc665776420) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc665776780) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc6653cb060) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc6653cb3c0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc6653cb540) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc6653cb8a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc6653cba20) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc6653cbd80) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc6653cbf00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc6653fc2a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc6653fc420) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc6653fc780) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc6653fc900) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc6653fcc60) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc6653fcde0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc66542a180) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7fc66542a300) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7fc66542a660) 0 empty + diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index de776e9dd12..c4c8d8382c6 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -1,41 +1,87 @@ -cmake_minimum_required(VERSION 2.8) - -project(qmake_cmake_files) +# This is an automatic test for the CMake configuration files. +# To run it manually, +# 1) mkdir build # Create a build directory +# 2) cd build +# 3) # Run cmake on this directory +# `$qt_prefix/bin/qt-cmake ..` or `cmake -DCMAKE_PREFIX_PATH=/path/to/qt ..` +# 4) ctest # Run ctest +cmake_minimum_required(VERSION 3.16) +project(qtdeclarative_cmake_tests) enable_testing() -find_package(Qt5Core REQUIRED) - -include("${_Qt5CTestMacros}") - -test_module_includes( - Qml QQmlEngine - Quick QQuickWindow -) - -expect_pass(test_plugins) - -add_test(qtquickcompiler ${CMAKE_CTEST_COMMAND} - --build-and-test - "${CMAKE_CURRENT_SOURCE_DIR}/qtquickcompiler/" - "${CMAKE_CURRENT_BINARY_DIR}/qtquickcompiler" - --build-config "${CMAKE_BUILD_TYPE}" - --build-generator ${CMAKE_GENERATOR} - --build-makeprogram ${CMAKE_MAKE_PROGRAM} - --build-project qqc_test - --build-options "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" ${BUILD_OPTIONS_LIST} - --test-command qqc_test - -) - -add_test(qmlimportscanner ${CMAKE_CTEST_COMMAND} - --build-and-test - "${CMAKE_CURRENT_SOURCE_DIR}/qmlimportscanner/" - "${CMAKE_CURRENT_BINARY_DIR}/qmlimportscanner" - --build-config "${CMAKE_BUILD_TYPE}" - --build-generator ${CMAKE_GENERATOR} - --build-makeprogram ${CMAKE_MAKE_PROGRAM} - --build-project qis_test - --build-options "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" ${BUILD_OPTIONS_LIST} - --test-command qis_test -) +set(required_packages Core) +set(optional_packages Qml Quick) + +# Setup the test when called as a completely standalone project. +if(TARGET Qt6::Core) + # Tests are built as part of the qtsensors build tree. + # Setup paths so that the Qt packages are found. + qt_internal_set_up_build_dir_package_paths() +endif() + +find_package(Qt6 REQUIRED COMPONENTS ${required_packages}) +find_package(Qt6 OPTIONAL_COMPONENTS ${optional_packages}) + +# Setup common test variables which were previously set by ctest_testcase_common.prf. +set(CMAKE_MODULES_UNDER_TEST "${required_packages}" "${optional_packages}") + +foreach(qt_package ${CMAKE_MODULES_UNDER_TEST}) + set(package_name "${QT_CMAKE_EXPORT_NAMESPACE}${qt_package}") + if(${package_name}_FOUND) + set(CMAKE_${qt_package}_MODULE_MAJOR_VERSION "${${package_name}_VERSION_MAJOR}") + set(CMAKE_${qt_package}_MODULE_MINOR_VERSION "${${package_name}_VERSION_MINOR}") + set(CMAKE_${qt_package}_MODULE_PATCH_VERSION "${${package_name}_VERSION_PATCH}") + endif() +endforeach() + +include("${_Qt6CTestMacros}") + +set(module_includes "") + +if(TARGET Qt::Qml) + list(APPEND module_includes + Qml QQmlEngine + ) +endif() + +if(TARGET Qt::Quick) + list(APPEND module_includes + Quick QQuickWindow + ) +endif() + +_qt_internal_test_module_includes(${module_includes}) + +if(TARGET Qt::Qml) + if(NOT CMAKE_CROSSCOMPILING) + _qt_internal_test_expect_pass(tooling_imports TESTNAME cmake_tooling_imports BINARY cmake_test) + set_tests_properties(cmake_tooling_imports PROPERTIES + FAIL_REGULAR_EXPRESSION "(Info|Warning|Error): [a-zA-Z]*\\.qml:[0-9]" + ) + endif() + # TODO: Plugin targets are not available in shared builds at the moment QTBUG-94066 + if(NOT QT6_IS_SHARED_LIBS_BUILD) + _qt_internal_test_expect_pass(test_plugins) + endif() + _qt_internal_test_expect_pass(empty_qmldir) + _qt_internal_test_expect_fail(test_internal_singleton) +endif() + +if(TARGET Qt::Quick) + if(NOT CMAKE_CROSSCOMPILING) + _qt_internal_test_expect_pass(qtquickcompiler BINARY qqc_test) + endif() + if(NOT QT6_IS_SHARED_LIBS_BUILD) + _qt_internal_test_expect_pass(test_import_static_shapes_plugin_resources + BINARY "${CMAKE_CTEST_COMMAND}" + BINARY_ARGS "-V" + ) + if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.21") + _qt_internal_test_expect_pass(qmlimportscanner + TESTNAME cmake_qmlimportscanner + BINARY qis_test + ) + endif() + endif() +endif() diff --git a/tests/auto/cmake/empty_qmldir/CMakeLists.txt b/tests/auto/cmake/empty_qmldir/CMakeLists.txt new file mode 100644 index 00000000000..259adc2610c --- /dev/null +++ b/tests/auto/cmake/empty_qmldir/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.16) +project(empty_qmldir_test) + +find_package(Qt6 ${CMAKE_Core_MODULE_MAJOR_VERSION}.${CMAKE_Core_MODULE_MINOR_VERSION} + REQUIRED COMPONENTS Qml Gui Test +) + +set(CMAKE_AUTOMOC ON) + +# Simplify finding the backing targets' DLLs on Windows +if(WIN32) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +endif() + +qt_add_executable(empty_qmldir_test main.cpp) +target_link_libraries(empty_qmldir_test PRIVATE Qt6::Test) +if(ANDROID) + # Tests link to Gui by default beacuse it's needed for Android (QTBUG-83997) when + # using qt_internal_add_test() but not here where qt_add_executable() is used. + target_link_libraries(empty_qmldir_test PRIVATE Qt6::Gui) +endif() + +qt_add_qml_module(empty_qmldir_test + URI Third + VERSION 1.0 + NO_RESOURCE_TARGET_PATH + SOURCES + enemy.cpp + enemy.h + QML_FILES + flee.qml +) + +# Ensure linting runs when building the default "all" target +set_target_properties(all_qmllint PROPERTIES EXCLUDE_FROM_ALL FALSE) diff --git a/tests/auto/cmake/empty_qmldir/enemy.cpp b/tests/auto/cmake/empty_qmldir/enemy.cpp new file mode 100644 index 00000000000..31df68de6dd --- /dev/null +++ b/tests/auto/cmake/empty_qmldir/enemy.cpp @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 "enemy.h" + +Enemy::Enemy(QObject *parent) : QObject(parent) { } + +#include "moc_enemy.cpp" diff --git a/tests/auto/cmake/empty_qmldir/enemy.h b/tests/auto/cmake/empty_qmldir/enemy.h new file mode 100644 index 00000000000..e9d37069958 --- /dev/null +++ b/tests/auto/cmake/empty_qmldir/enemy.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 ENEMY_H +#define ENEMY_H + +#include <QtQml/qqml.h> +#include <QtCore/qproperty.h> + +class Enemy : public QObject +{ + Q_OBJECT + QML_NAMED_ELEMENT(Enemy) + Q_PROPERTY(QString name MEMBER name BINDABLE bindableName) + +public: + Enemy(QObject *parent = nullptr); + + QProperty<QString> name; + QBindable<QString> bindableName() { return QBindable<QString>(&name); } +}; + +#endif // ENEMY_H diff --git a/tests/auto/cmake/empty_qmldir/flee.qml b/tests/auto/cmake/empty_qmldir/flee.qml new file mode 100644 index 00000000000..3bc2b1ebbd6 --- /dev/null +++ b/tests/auto/cmake/empty_qmldir/flee.qml @@ -0,0 +1,7 @@ +import QtQml +import Third // Self import + +QtObject { + property int success: -11 + property Enemy other: Enemy { name: "evil" } +} diff --git a/tests/auto/cmake/empty_qmldir/main.cpp b/tests/auto/cmake/empty_qmldir/main.cpp new file mode 100644 index 00000000000..2f646416550 --- /dev/null +++ b/tests/auto/cmake/empty_qmldir/main.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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/qobject.h> +#include <QtQml/qqml.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtTest/qtest.h> + +class tst_empty_qmldir : public QObject +{ + Q_OBJECT +private slots: + void canSelfImport(); +}; + +void tst_empty_qmldir::canSelfImport() +{ + QQmlEngine engine; + QQmlComponent component(&engine, QUrl("qrc:/flee.qml")); + QScopedPointer<QObject> obj(component.create()); + QVERIFY2(!obj.isNull(), qPrintable(component.errorString())); + QCOMPARE(obj->property("success").toInt(), -11); + QObject *enemy = qvariant_cast<QObject *>(obj->property("other")); + QVERIFY(enemy != nullptr); + QCOMPARE(enemy->property("name").toString(), QStringLiteral("evil")); +} + +QTEST_MAIN(tst_empty_qmldir) + +#include "main.moc" diff --git a/tests/auto/cmake/qmlimportscanner/CMakeLists.txt b/tests/auto/cmake/qmlimportscanner/CMakeLists.txt index 354b0f8dfc5..405066e3cbb 100644 --- a/tests/auto/cmake/qmlimportscanner/CMakeLists.txt +++ b/tests/auto/cmake/qmlimportscanner/CMakeLists.txt @@ -1,18 +1,20 @@ - -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.21) project(qis_test) -find_package(Qt5Qml 5.0.0 REQUIRED) -find_package(Qt5Gui 5.0.0 REQUIRED) -find_package(Qt5Test 5.0.0 REQUIRED) -find_package(Qt5QmlImportScanner REQUIRED) - -set(CMAKE_CXXFLAGS "${CMAKE_CXXFLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") +find_package(Qt6 REQUIRED COMPONENTS Core Test Qml) set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) -add_executable(qis_test "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/qis_test.qrc") -target_link_libraries(qis_test PRIVATE Qt5::Gui Qt5::Qml Qt5::Test) -qt5_import_qml_plugins(qis_test) +# We explicitly don't want to use qt_add_executable() here because we want to +# manually invoke qt6_import_qml_plugins() ourselves later +add_executable(qis_test main.cpp) +target_link_libraries(qis_test PRIVATE Qt6::Test Qt6::Qml Qt6::Core) + +qt6_add_qml_module(qis_test + URI Test + VERSION 1.0 + NO_RESOURCE_TARGET_PATH + QML_FILES main.qml +) + +qt6_import_qml_plugins(qis_test) diff --git a/tests/auto/cmake/qmlimportscanner/qis_test.qrc b/tests/auto/cmake/qmlimportscanner/qis_test.qrc deleted file mode 100644 index 1f88fc4e714..00000000000 --- a/tests/auto/cmake/qmlimportscanner/qis_test.qrc +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE RCC><RCC version="1.0"> -<qresource> -<file>./main.qml</file> -<file alias="main.cpp">./main.cpp</file> -</qresource> -</RCC> diff --git a/tests/auto/cmake/qtquickcompiler/CMakeLists.txt b/tests/auto/cmake/qtquickcompiler/CMakeLists.txt index 1eb4c4286c6..c717ed01a38 100644 --- a/tests/auto/cmake/qtquickcompiler/CMakeLists.txt +++ b/tests/auto/cmake/qtquickcompiler/CMakeLists.txt @@ -1,17 +1,29 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.16) project(qqc_test) -find_package(Qt6Qml 6.0.0 REQUIRED) -find_package(Qt6Gui 6.0.0 REQUIRED) -find_package(Qt6Test 6.0.0 REQUIRED) -find_package(Qt6QuickCompiler) +find_package(Qt6 ${CMAKE_Core_MODULE_MAJOR_VERSION}.${CMAKE_Core_MODULE_MINOR_VERSION} + REQUIRED COMPONENTS Qml Gui Test +) -set(CMAKE_CXXFLAGS "${CMAKE_CXXFLAGS} ${Qt6Core_EXECUTABLE_COMPILE_FLAGS}") +set(CMAKE_AUTOMOC ON) -qtquick_compiler_add_resources(RESOURCES "empty.qrc" "resources with space/qqc_test.qrc") +qt_add_executable(qqc_test + # Absolute path needed to avoid using the copied file in the build dir. + # That would still work, but it should use the file in the source dir. + ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp +) +target_link_libraries(qqc_test PRIVATE Qt6::Gui Qt6::Qml Qt6::Test) -set(CMAKE_AUTOMOC ON) +set_source_files_properties("resources with space/main.qml" PROPERTIES + QT_RESOURCE_ALIAS main.qml +) -add_executable(qqc_test "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" ${RESOURCES}) -target_link_libraries(qqc_test Qt6::Gui Qt6::Qml Qt6::Test) +qt_add_qml_module(qqc_test + URI Test + VERSION 1.0 + QML_FILES + "resources with space/main.qml" + RESOURCES + main.cpp +) diff --git a/tests/auto/cmake/qtquickcompiler/main.cpp b/tests/auto/cmake/qtquickcompiler/main.cpp index c357ef60e6d..3cdf4cf40bd 100644 --- a/tests/auto/cmake/qtquickcompiler/main.cpp +++ b/tests/auto/cmake/qtquickcompiler/main.cpp @@ -1,3 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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> #include <QtQml> @@ -12,14 +39,13 @@ private slots: void tst_QQC::packaging() { - QVERIFY(QFile::exists(":/main.qml")); - QCOMPARE(QFileInfo(":/main.qml").size(), 0); - QVERIFY(QFile::exists(":/main.cpp")); - QVERIFY(QFileInfo(":/main.cpp").size() > 0); - + QVERIFY(QFile::exists(":/Test/main.qml")); + QVERIFY(QFileInfo(":/Test/main.qml").size() > 0); + QVERIFY(QFile::exists(":/Test/main.cpp")); + QVERIFY(QFileInfo(":/Test/main.cpp").size() > 0); QQmlEngine engine; - QQmlComponent component(&engine, QUrl("qrc:/main.qml")); + QQmlComponent component(&engine, QUrl("qrc:/Test/main.qml")); QScopedPointer<QObject> obj(component.create()); QVERIFY(!obj.isNull()); QCOMPARE(obj->property("success").toInt(), 42); diff --git a/tests/auto/cmake/qtquickcompiler/resources with space/qqc_test.qrc b/tests/auto/cmake/qtquickcompiler/resources with space/qqc_test.qrc deleted file mode 100644 index 63d8d1f37ec..00000000000 --- a/tests/auto/cmake/qtquickcompiler/resources with space/qqc_test.qrc +++ /dev/null @@ -1,6 +0,0 @@ -<!DOCTYPE RCC><RCC version="1.0"> -<qresource> -<file>./main.qml</file> -<file alias="main.cpp">../main.cpp</file> -</qresource> -</RCC> diff --git a/tests/auto/cmake/test_import_static_shapes_plugin_resources/CMakeLists.txt b/tests/auto/cmake/test_import_static_shapes_plugin_resources/CMakeLists.txt new file mode 100644 index 00000000000..66beef0fa57 --- /dev/null +++ b/tests/auto/cmake/test_import_static_shapes_plugin_resources/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.16) + +project(test_project LANGUAGES CXX) +enable_testing() + +set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +find_package(Qt6 COMPONENTS REQUIRED Quick Test QuickTestUtilsPrivate) + +function(create_test_executable target) + qt_add_executable(${target} + MANUAL_FINALIZATION + tst_main.cpp + ) + target_link_libraries(${target} PRIVATE + Qt::Qml + Qt::Quick + Qt::QuickPrivate + Qt::QuickTestUtilsPrivate + Qt::Test + ) + + set(app_resource_files + "app.qml" + ) + + qt6_add_resources(${target} "app" + PREFIX + "/" + FILES + ${app_resource_files} + ) + + # Explicitly import qml plugins, regardless of lower CMake versions. + qt_import_qml_plugins(${target}) + + # Explicitly call finalizers, regardless of lower CMake versions. + qt_finalize_target(${target}) + + # Rune the app to ensure resources were linked and found, so there should be no qml errors. + add_test(test_${target} ${target}) +endfunction() + +create_test_executable(app) diff --git a/tests/auto/cmake/test_import_static_shapes_plugin_resources/app.qml b/tests/auto/cmake/test_import_static_shapes_plugin_resources/app.qml new file mode 100644 index 00000000000..0ca3bf250bb --- /dev/null +++ b/tests/auto/cmake/test_import_static_shapes_plugin_resources/app.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick +import QtQuick.Shapes + +Shape { + width: 200 + height: 150 + anchors.centerIn: parent + ShapePath { + strokeWidth: 4 + strokeColor: "red" + fillGradient: LinearGradient { + x1: 20; y1: 20 + x2: 180; y2: 130 + GradientStop { position: 0; color: "blue" } + GradientStop { position: 0.2; color: "green" } + GradientStop { position: 0.4; color: "red" } + GradientStop { position: 0.6; color: "yellow" } + GradientStop { position: 1; color: "cyan" } + } + strokeStyle: ShapePath.DashLine + dashPattern: [ 1, 4 ] + startX: 20; startY: 20 + PathLine { x: 180; y: 130 } + PathLine { x: 20; y: 130 } + PathLine { x: 20; y: 20 } + } +} diff --git a/tests/auto/cmake/test_import_static_shapes_plugin_resources/tst_main.cpp b/tests/auto/cmake/test_import_static_shapes_plugin_resources/tst_main.cpp new file mode 100644 index 00000000000..ab05da961f6 --- /dev/null +++ b/tests/auto/cmake/test_import_static_shapes_plugin_resources/tst_main.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtGlobal> +#include <QtCore/QScopeGuard> +#include <QtCore/QTimer> +#include <QtGui/QGuiApplication> +#include <QtQml/QQmlEngine> +#include <QtQuick/QQuickView> +#include <QtTest/QTest> + +#include <QtQuickTestUtils/private/viewtestutils_p.h> + +static bool gotShaderErrorMessage = false; +QtMessageHandler oldHandler = nullptr; + +void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + // If QuickShapesPrivate's resource object files that contain shaders are not linked to the + // the final executable, QRhiImplementation::sanityCheckGraphicsPipeline will issue a warning + // that we intercept. + if (type == QtWarningMsg && msg == QLatin1String("Empty shader passed to graphics pipeline")) { + gotShaderErrorMessage = true; + } + + if (oldHandler) + oldHandler(type, context, msg); +} + +class tstImportStaticShapesPluginResources : public QObject +{ + Q_OBJECT +private slots: + void cleanup(); + void loadApp(); +}; + +void tstImportStaticShapesPluginResources::cleanup() +{ + if (oldHandler) { + qInstallMessageHandler(oldHandler); + oldHandler = nullptr; + } +} + +void tstImportStaticShapesPluginResources::loadApp() +{ + gotShaderErrorMessage = false; + oldHandler = qInstallMessageHandler(messageHandler); + + QQuickView view; + QVERIFY(QQuickTest::showView(view, QUrl("qrc:///app.qml"))); + QCOMPARE(gotShaderErrorMessage, false); +} + +QTEST_MAIN(tstImportStaticShapesPluginResources) +#include "tst_main.moc" diff --git a/tests/auto/cmake/test_internal_singleton/CMakeLists.txt b/tests/auto/cmake/test_internal_singleton/CMakeLists.txt new file mode 100644 index 00000000000..f1db46a0f9c --- /dev/null +++ b/tests/auto/cmake/test_internal_singleton/CMakeLists.txt @@ -0,0 +1,23 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + + +cmake_minimum_required(VERSION 3.19) + +project(test_internal_singleton) + +find_package(Qt6 REQUIRED COMPONENTS Qml) + +qt_standard_project_setup() + +set_source_files_properties(Test.qml PROPERTIES + QT_QML_SINGLETON_TYPE TRUE + QT_QML_INTERNAL_TYPE TRUE +) + +qt_add_qml_module(test_internal_singleton + URI Controls + VERSION 1.0 + QML_FILES + Test.qml +) diff --git a/tests/auto/cmake/test_internal_singleton/Test.qml b/tests/auto/cmake/test_internal_singleton/Test.qml new file mode 100644 index 00000000000..a2eb03bd4e6 --- /dev/null +++ b/tests/auto/cmake/test_internal_singleton/Test.qml @@ -0,0 +1,4 @@ +pragma singleton +import QtQml + +QtObject {} diff --git a/tests/auto/cmake/test_plugins/CMakeLists.txt b/tests/auto/cmake/test_plugins/CMakeLists.txt index a23f9c332c2..7fc0dea11e4 100644 --- a/tests/auto/cmake/test_plugins/CMakeLists.txt +++ b/tests/auto/cmake/test_plugins/CMakeLists.txt @@ -1,16 +1,13 @@ -project(test_plugins) +cmake_minimum_required(VERSION 3.16) -cmake_minimum_required(VERSION 2.8) -if (POLICY CMP0056) - cmake_policy(SET CMP0056 NEW) -endif() +project(check_for_existence_of_plugin_targets) -find_package(Qt5Qml REQUIRED) +find_package(Qt6 COMPONENTS REQUIRED Qml) # See QTBUG-43438 -if (NOT TARGET Qt5::QTcpServerConnectionFactory) - message(SEND_ERROR "Qt5::QTcpServerConnectionFactory does not exist") +if(NOT TARGET Qt6::QTcpServerConnectionFactoryPlugin) + message(FATAL_ERROR "Qt6::QTcpServerConnectionFactoryPlugin does not exist") endif() -if (NOT TARGET Qt5::QLocalClientConnectionFactory) - message(SEND_ERROR "Qt5::QLocalClientConnectionFactory does not exist") +if(NOT TARGET Qt6::QLocalClientConnectionFactoryPlugin) + message(FATAL_ERROR "Qt6::QLocalClientConnectionFactoryPlugin does not exist") endif() diff --git a/tests/auto/cmake/tooling_imports/CMakeLists.txt b/tests/auto/cmake/tooling_imports/CMakeLists.txt new file mode 100644 index 00000000000..514f1ac9497 --- /dev/null +++ b/tests/auto/cmake/tooling_imports/CMakeLists.txt @@ -0,0 +1,32 @@ + +cmake_minimum_required(VERSION 3.16) +project(cmake_test) + +find_package(Qt6 ${CMAKE_Core_MODULE_MAJOR_VERSION}.${CMAKE_Core_MODULE_MINOR_VERSION} + REQUIRED COMPONENTS Qml Gui Test +) + +set(CMAKE_AUTOMOC ON) + +# Simplify finding the backing targets' DLLs on Windows +if(WIN32) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +endif() + +add_subdirectory(First) +add_subdirectory(Second) + +qt_add_executable(cmake_test main.cpp) +target_link_libraries(cmake_test PRIVATE Qt6::Test Qt6::Gui) + +qt_add_qml_module(cmake_test + URI Test + VERSION 1.0 + NO_RESOURCE_TARGET_PATH + QML_FILES + main.qml + Ttt.qml +) + +# Ensure linting runs when building the default "all" target +set_target_properties(all_qmllint PROPERTIES EXCLUDE_FROM_ALL FALSE) diff --git a/tests/auto/cmake/tooling_imports/First/CMakeLists.txt b/tests/auto/cmake/tooling_imports/First/CMakeLists.txt new file mode 100644 index 00000000000..64d32916121 --- /dev/null +++ b/tests/auto/cmake/tooling_imports/First/CMakeLists.txt @@ -0,0 +1,9 @@ +qt_add_qml_module(BackingFirst + URI First + VERSION 1.0 + SOURCES + Neighbor.cpp + Neighbor.h + QML_FILES + DoSomething.qml +) diff --git a/tests/auto/cmake/tooling_imports/First/DoSomething.qml b/tests/auto/cmake/tooling_imports/First/DoSomething.qml new file mode 100644 index 00000000000..82ee2b94f2f --- /dev/null +++ b/tests/auto/cmake/tooling_imports/First/DoSomething.qml @@ -0,0 +1,7 @@ +import QtQml 2.0 +import First // Self import + +QtObject { + property int success: 42 + property Neighbor other +} diff --git a/tests/auto/cmake/tooling_imports/First/Neighbor.cpp b/tests/auto/cmake/tooling_imports/First/Neighbor.cpp new file mode 100644 index 00000000000..38fedbaa6dd --- /dev/null +++ b/tests/auto/cmake/tooling_imports/First/Neighbor.cpp @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 "Neighbor.h" + +Neighbor::Neighbor(QObject *parent) : QObject(parent) { } + +#include "moc_Neighbor.cpp" diff --git a/tests/auto/cmake/tooling_imports/First/Neighbor.h b/tests/auto/cmake/tooling_imports/First/Neighbor.h new file mode 100644 index 00000000000..ef6cc2d58b1 --- /dev/null +++ b/tests/auto/cmake/tooling_imports/First/Neighbor.h @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 NEIGHBOR_H +#define NEIGHBOR_H + +#include <QtQml/qqml.h> + +class Neighbor : public QObject +{ + Q_OBJECT + QML_NAMED_ELEMENT(Neighbor) + +public: + Neighbor(QObject *parent = nullptr); +}; + +#endif // NEIGHBOR_H diff --git a/tests/auto/cmake/tooling_imports/Second/CMakeLists.txt b/tests/auto/cmake/tooling_imports/Second/CMakeLists.txt new file mode 100644 index 00000000000..e3513269fc9 --- /dev/null +++ b/tests/auto/cmake/tooling_imports/Second/CMakeLists.txt @@ -0,0 +1,5 @@ +qt_add_qml_module(BackingSecond + URI Second + VERSION 1.0 + QML_FILES CheckIt.qml +) diff --git a/tests/auto/cmake/tooling_imports/Second/CheckIt.qml b/tests/auto/cmake/tooling_imports/Second/CheckIt.qml new file mode 100644 index 00000000000..6bf8659bfcc --- /dev/null +++ b/tests/auto/cmake/tooling_imports/Second/CheckIt.qml @@ -0,0 +1,7 @@ +import QtQml 2.0 +import First + +QtObject { + property DoSomething otherModule: DoSomething {} + property int dummy: otherModule.success + 13 +} diff --git a/tests/auto/cmake/tooling_imports/Ttt.qml b/tests/auto/cmake/tooling_imports/Ttt.qml new file mode 100644 index 00000000000..8fc36a40daf --- /dev/null +++ b/tests/auto/cmake/tooling_imports/Ttt.qml @@ -0,0 +1,3 @@ +import QtQml + +QtObject {} diff --git a/tests/auto/cmake/tooling_imports/main.cpp b/tests/auto/cmake/tooling_imports/main.cpp new file mode 100644 index 00000000000..65663f84cc2 --- /dev/null +++ b/tests/auto/cmake/tooling_imports/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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> +#include <QtQml> +#include <QtTest> + +class tst_cmake_qmllint : public QObject +{ + Q_OBJECT +private slots: + void canImport(); +}; + +void tst_cmake_qmllint::canImport() +{ + QQmlEngine engine; + QQmlComponent component(&engine, QUrl("qrc:/main.qml")); + QScopedPointer<QObject> obj(component.create()); + QVERIFY2(!obj.isNull(), qPrintable(component.errorString())); + QCOMPARE(obj->property("result").toInt(), 97); +} + +QTEST_MAIN(tst_cmake_qmllint) + +#include "main.moc" diff --git a/tests/auto/cmake/tooling_imports/main.qml b/tests/auto/cmake/tooling_imports/main.qml new file mode 100644 index 00000000000..cc2c49ad41a --- /dev/null +++ b/tests/auto/cmake/tooling_imports/main.qml @@ -0,0 +1,11 @@ +import QtQml 2.0 +import First +import Second +import Test // Self import + +QtObject { + property DoSomething firstModule: DoSomething{} + property CheckIt secondModule: CheckIt{} + property int result: firstModule.success + secondModule.dummy + property Ttt mine: Ttt{} +} diff --git a/tests/auto/core/CMakeLists.txt b/tests/auto/core/CMakeLists.txt index 31413de9c4c..a57498db915 100644 --- a/tests/auto/core/CMakeLists.txt +++ b/tests/auto/core/CMakeLists.txt @@ -14,3 +14,7 @@ qt_internal_add_test(tst_core Qt::Qml TESTDATA ${test_data} ) + +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_core) +endif() diff --git a/tests/auto/particles/qquickage/CMakeLists.txt b/tests/auto/particles/qquickage/CMakeLists.txt index ef1cb8fe457..82e5481a283 100644 --- a/tests/auto/particles/qquickage/CMakeLists.txt +++ b/tests/auto/particles/qquickage/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickage SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickage.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickage Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickage/tst_qquickage.cpp b/tests/auto/particles/qquickage/tst_qquickage.cpp index 3a2d4e39276..2b9916d46c5 100644 --- a/tests/auto/particles/qquickage/tst_qquickage.cpp +++ b/tests/auto/particles/qquickage/tst_qquickage.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickage : public QQmlDataTest { Q_OBJECT public: - tst_qquickage() {} + tst_qquickage() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickangleddirection/CMakeLists.txt b/tests/auto/particles/qquickangleddirection/CMakeLists.txt index a60dfa8d6bb..6e6a5b42e94 100644 --- a/tests/auto/particles/qquickangleddirection/CMakeLists.txt +++ b/tests/auto/particles/qquickangleddirection/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickangleddirection SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickangleddirection.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickangleddirection Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp b/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp index 6186dc97def..66a39c13575 100644 --- a/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp +++ b/tests/auto/particles/qquickangleddirection/tst_qquickangleddirection.cpp @@ -31,14 +31,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickangleddirection : public QQmlDataTest { Q_OBJECT public: - tst_qquickangleddirection() {} + tst_qquickangleddirection() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickcumulativedirection/CMakeLists.txt b/tests/auto/particles/qquickcumulativedirection/CMakeLists.txt index 0eecede9a5c..4a81fb010cb 100644 --- a/tests/auto/particles/qquickcumulativedirection/CMakeLists.txt +++ b/tests/auto/particles/qquickcumulativedirection/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickcumulativedirection SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickcumulativedirection.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickcumulativedirection Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp b/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp index c5c4bbb897a..011ccf1ae7b 100644 --- a/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp +++ b/tests/auto/particles/qquickcumulativedirection/tst_qquickcumulativedirection.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickcumulativedirection : public QQmlDataTest { Q_OBJECT public: - tst_qquickcumulativedirection() {} + tst_qquickcumulativedirection() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickcustomaffector/CMakeLists.txt b/tests/auto/particles/qquickcustomaffector/CMakeLists.txt index 7b09402ea49..f89bce3be08 100644 --- a/tests/auto/particles/qquickcustomaffector/CMakeLists.txt +++ b/tests/auto/particles/qquickcustomaffector/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickcustomaffector SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickcustomaffector.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickcustomaffector Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp b/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp index 213768bbb6f..c912c826506 100644 --- a/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp +++ b/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickcustomaffector : public QQmlDataTest { Q_OBJECT public: - tst_qquickcustomaffector() {} + tst_qquickcustomaffector() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickellipseextruder/CMakeLists.txt b/tests/auto/particles/qquickellipseextruder/CMakeLists.txt index 4d432f78d03..33126d1541c 100644 --- a/tests/auto/particles/qquickellipseextruder/CMakeLists.txt +++ b/tests/auto/particles/qquickellipseextruder/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickellipseextruder SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickellipseextruder.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickellipseextruder Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp b/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp index ec1659d486b..56e3c457afa 100644 --- a/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp +++ b/tests/auto/particles/qquickellipseextruder/tst_qquickellipseextruder.cpp @@ -31,14 +31,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickellipseextruder : public QQmlDataTest { Q_OBJECT public: - tst_qquickellipseextruder() {} + tst_qquickellipseextruder() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickfriction/CMakeLists.txt b/tests/auto/particles/qquickfriction/CMakeLists.txt index 5e7e270d695..3883a1dba3b 100644 --- a/tests/auto/particles/qquickfriction/CMakeLists.txt +++ b/tests/auto/particles/qquickfriction/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickfriction SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickfriction.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickfriction Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp b/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp index de535118f4d..b840828fcd8 100644 --- a/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp +++ b/tests/auto/particles/qquickfriction/tst_qquickfriction.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickfriction : public QQmlDataTest { Q_OBJECT public: - tst_qquickfriction() {} + tst_qquickfriction() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickgravity/CMakeLists.txt b/tests/auto/particles/qquickgravity/CMakeLists.txt index e555dd9f804..315c2b21296 100644 --- a/tests/auto/particles/qquickgravity/CMakeLists.txt +++ b/tests/auto/particles/qquickgravity/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickgravity SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickgravity.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickgravity Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp b/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp index dcc0c017e8a..27e30e68dff 100644 --- a/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp +++ b/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickgravity : public QQmlDataTest { Q_OBJECT public: - tst_qquickgravity() {} + tst_qquickgravity() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickgroupgoal/CMakeLists.txt b/tests/auto/particles/qquickgroupgoal/CMakeLists.txt index dbacb28d29b..410189917b5 100644 --- a/tests/auto/particles/qquickgroupgoal/CMakeLists.txt +++ b/tests/auto/particles/qquickgroupgoal/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickgroupgoal SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickgroupgoal.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickgroupgoal Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp b/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp index 6ede0eb9682..86a63b1cfbd 100644 --- a/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp +++ b/tests/auto/particles/qquickgroupgoal/tst_qquickgroupgoal.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickgroupgoal : public QQmlDataTest { Q_OBJECT public: - tst_qquickgroupgoal() {} + tst_qquickgroupgoal() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickimageparticle/BLACKLIST b/tests/auto/particles/qquickimageparticle/BLACKLIST index a615dcd6e68..8a9bd8d00cd 100644 --- a/tests/auto/particles/qquickimageparticle/BLACKLIST +++ b/tests/auto/particles/qquickimageparticle/BLACKLIST @@ -1,16 +1,20 @@ # QTBUG-63055 [test_colored] b2qt +qnx # QTBUG-63055 [test_colorVariance] b2qt +qnx # QTBUG-63055 [test_deformed] b2qt +qnx # QTBUG-63055 [test_sprite] b2qt +qnx diff --git a/tests/auto/particles/qquickimageparticle/CMakeLists.txt b/tests/auto/particles/qquickimageparticle/CMakeLists.txt index 03f6ea0ef80..668d9c484dc 100644 --- a/tests/auto/particles/qquickimageparticle/CMakeLists.txt +++ b/tests/auto/particles/qquickimageparticle/CMakeLists.txt @@ -7,15 +7,12 @@ # Collect test data file(GLOB_RECURSE test_data_glob RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - data/*) + data/* ../shared/*) list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickimageparticle SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickimageparticle.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickimageparticle Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp b/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp index 32a8a9435cf..06c0e898d32 100644 --- a/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp +++ b/tests/auto/particles/qquickimageparticle/tst_qquickimageparticle.cpp @@ -30,8 +30,7 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> const double CONV_FACTOR = 0.017453292519943295;//Degrees to radians @@ -39,7 +38,7 @@ class tst_qquickimageparticle : public QQmlDataTest { Q_OBJECT public: - tst_qquickimageparticle() {} + tst_qquickimageparticle() : QQmlDataTest(QT_QMLTEST_DATADIR) {} ~tst_qquickimageparticle(); private slots: @@ -244,46 +243,50 @@ void tst_qquickimageparticle::test_deformed() void tst_qquickimageparticle::test_tabled() { - QQuickView* view = createView(testFileUrl("tabled.qml"), 600); - QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system"); - ensureAnimTime(600, system->m_animation); - - QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); - for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { - if (d->t == -1) - continue; //Particle data unused - - QCOMPARE(d->x, 0.f); - QCOMPARE(d->y, 0.f); - QCOMPARE(d->vx, 0.f); - QCOMPARE(d->vy, 0.f); - QCOMPARE(d->ax, 0.f); - QCOMPARE(d->ay, 0.f); - QCOMPARE(d->lifeSpan, 0.5f); - QCOMPARE(d->size, 32.f); - QCOMPARE(d->endSize, 32.f); - QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0))); - QCOMPARE(d->color.r, (uchar)255); - QCOMPARE(d->color.g, (uchar)255); - QCOMPARE(d->color.b, (uchar)255); - QCOMPARE(d->color.a, (uchar)255); - QCOMPARE(d->xx, 1.0f); - QCOMPARE(d->xy, 0.0f); - QCOMPARE(d->yy, 1.0f); - QCOMPARE(d->yx, 0.0f); - QCOMPARE(d->rotation, 0.0f); - QCOMPARE(d->rotationVelocity, 0.0f); - QCOMPARE(d->autoRotate, (uchar)0); - QCOMPARE(d->animX, 0.0f); - QCOMPARE(d->animY, 0.0f); - QCOMPARE(d->animWidth, 1.0f); - QCOMPARE(d->animHeight, 1.0f); - QCOMPARE(d->frameDuration, 1.0f); - QCOMPARE(d->frameCount, 1.0f); - QCOMPARE(d->animT, -1.0f); - //TODO: This performance level doesn't alter particleData, but goes straight to shaders. Find something to test - } - delete view; + #if defined(Q_OS_LINUX) + QSKIP("Crashing on Ubuntu 22.04: QTBUG-107707"); + #else + QQuickView* view = createView(testFileUrl("tabled.qml"), 600); + QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system"); + ensureAnimTime(600, system->m_animation); + + QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); + for (QQuickParticleData *d : qAsConst(system->groupData[0]->data)) { + if (d->t == -1) + continue; //Particle data unused + + QCOMPARE(d->x, 0.f); + QCOMPARE(d->y, 0.f); + QCOMPARE(d->vx, 0.f); + QCOMPARE(d->vy, 0.f); + QCOMPARE(d->ax, 0.f); + QCOMPARE(d->ay, 0.f); + QCOMPARE(d->lifeSpan, 0.5f); + QCOMPARE(d->size, 32.f); + QCOMPARE(d->endSize, 32.f); + QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0))); + QCOMPARE(d->color.r, (uchar)255); + QCOMPARE(d->color.g, (uchar)255); + QCOMPARE(d->color.b, (uchar)255); + QCOMPARE(d->color.a, (uchar)255); + QCOMPARE(d->xx, 1.0f); + QCOMPARE(d->xy, 0.0f); + QCOMPARE(d->yy, 1.0f); + QCOMPARE(d->yx, 0.0f); + QCOMPARE(d->rotation, 0.0f); + QCOMPARE(d->rotationVelocity, 0.0f); + QCOMPARE(d->autoRotate, (uchar)0); + QCOMPARE(d->animX, 0.0f); + QCOMPARE(d->animY, 0.0f); + QCOMPARE(d->animWidth, 1.0f); + QCOMPARE(d->animHeight, 1.0f); + QCOMPARE(d->frameDuration, 1.0f); + QCOMPARE(d->frameCount, 1.0f); + QCOMPARE(d->animT, -1.0f); + //TODO: This performance level doesn't alter particleData, but goes straight to shaders. Find something to test + } + delete view; + #endif } diff --git a/tests/auto/particles/qquickitemparticle/CMakeLists.txt b/tests/auto/particles/qquickitemparticle/CMakeLists.txt index ff695eb8af9..c76cc1cd670 100644 --- a/tests/auto/particles/qquickitemparticle/CMakeLists.txt +++ b/tests/auto/particles/qquickitemparticle/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickitemparticle SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickitemparticle.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickitemparticle Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp b/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp index 32fe1a63c47..57e2e324c49 100644 --- a/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp +++ b/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp @@ -32,14 +32,13 @@ #include <private/qquickparticleemitter_p.h> #include <private/qquickimage_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickitemparticle : public QQmlDataTest { Q_OBJECT public: - tst_qquickitemparticle() {} + tst_qquickitemparticle() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquicklineextruder/CMakeLists.txt b/tests/auto/particles/qquicklineextruder/CMakeLists.txt index d7791103be1..2de4abfa879 100644 --- a/tests/auto/particles/qquicklineextruder/CMakeLists.txt +++ b/tests/auto/particles/qquicklineextruder/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquicklineextruder SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquicklineextruder.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquicklineextruder Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp b/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp index cfab3f8aee9..f1e21ec98cc 100644 --- a/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp +++ b/tests/auto/particles/qquicklineextruder/tst_qquicklineextruder.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquicklineextruder : public QQmlDataTest { Q_OBJECT public: - tst_qquicklineextruder() {} + tst_qquicklineextruder() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickmaskextruder/CMakeLists.txt b/tests/auto/particles/qquickmaskextruder/CMakeLists.txt index 0ea7f18f6d8..35926389c45 100644 --- a/tests/auto/particles/qquickmaskextruder/CMakeLists.txt +++ b/tests/auto/particles/qquickmaskextruder/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickmaskextruder SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickmaskextruder.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickmaskextruder Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp b/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp index 8a80a93e3e1..ec138809cf1 100644 --- a/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp +++ b/tests/auto/particles/qquickmaskextruder/tst_qquickmaskextruder.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickmaskextruder : public QQmlDataTest { Q_OBJECT public: - tst_qquickmaskextruder() {} + tst_qquickmaskextruder() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickparticlegroup/CMakeLists.txt b/tests/auto/particles/qquickparticlegroup/CMakeLists.txt index 4d335b18d01..2f8d5e87de3 100644 --- a/tests/auto/particles/qquickparticlegroup/CMakeLists.txt +++ b/tests/auto/particles/qquickparticlegroup/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickparticlegroup SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickparticlegroup.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickparticlegroup Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp b/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp index 8dcce6a73cd..2e688fc6253 100644 --- a/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp +++ b/tests/auto/particles/qquickparticlegroup/tst_qquickparticlegroup.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickparticlegroup : public QQmlDataTest { Q_OBJECT public: - tst_qquickparticlegroup() {} + tst_qquickparticlegroup() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickparticlesystem/CMakeLists.txt b/tests/auto/particles/qquickparticlesystem/CMakeLists.txt index 984a7350f0e..1cc7dede477 100644 --- a/tests/auto/particles/qquickparticlesystem/CMakeLists.txt +++ b/tests/auto/particles/qquickparticlesystem/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickparticlesystem SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickparticlesystem.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickparticlesystem Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp b/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp index 705e47230c1..00ab7bd0445 100644 --- a/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp +++ b/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickparticlesystem : public QQmlDataTest { Q_OBJECT public: - tst_qquickparticlesystem() {} + tst_qquickparticlesystem() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickpointattractor/CMakeLists.txt b/tests/auto/particles/qquickpointattractor/CMakeLists.txt index 6dfdc085afe..e43159edb77 100644 --- a/tests/auto/particles/qquickpointattractor/CMakeLists.txt +++ b/tests/auto/particles/qquickpointattractor/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickpointattractor SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickpointattractor.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickpointattractor Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp b/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp index 8e63c1802bc..3630371de5f 100644 --- a/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp +++ b/tests/auto/particles/qquickpointattractor/tst_qquickpointattractor.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickpointattractor : public QQmlDataTest { Q_OBJECT public: - tst_qquickpointattractor() {} + tst_qquickpointattractor() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickpointdirection/CMakeLists.txt b/tests/auto/particles/qquickpointdirection/CMakeLists.txt index 73867c74bb1..ccc31b2c1d6 100644 --- a/tests/auto/particles/qquickpointdirection/CMakeLists.txt +++ b/tests/auto/particles/qquickpointdirection/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickpointdirection SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickpointdirection.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickpointdirection Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp b/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp index ae5bfe406a8..ae8860fcf7f 100644 --- a/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp +++ b/tests/auto/particles/qquickpointdirection/tst_qquickpointdirection.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickpointdirection : public QQmlDataTest { Q_OBJECT public: - tst_qquickpointdirection() {} + tst_qquickpointdirection() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickrectangleextruder/CMakeLists.txt b/tests/auto/particles/qquickrectangleextruder/CMakeLists.txt index 9e48fd6d936..52c87db86d9 100644 --- a/tests/auto/particles/qquickrectangleextruder/CMakeLists.txt +++ b/tests/auto/particles/qquickrectangleextruder/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickrectangleextruder SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickrectangleextruder.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickrectangleextruder Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp b/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp index 6447523cd17..d95c4bc4641 100644 --- a/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp +++ b/tests/auto/particles/qquickrectangleextruder/tst_qquickrectangleextruder.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickrectangleextruder : public QQmlDataTest { Q_OBJECT public: - tst_qquickrectangleextruder() {} + tst_qquickrectangleextruder() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickspritegoal/BLACKLIST b/tests/auto/particles/qquickspritegoal/BLACKLIST index bd64621f77a..f09c8912c64 100644 --- a/tests/auto/particles/qquickspritegoal/BLACKLIST +++ b/tests/auto/particles/qquickspritegoal/BLACKLIST @@ -1,3 +1,4 @@ # QTBUG-63057 [test_instantTransition] b2qt +qnx diff --git a/tests/auto/particles/qquickspritegoal/CMakeLists.txt b/tests/auto/particles/qquickspritegoal/CMakeLists.txt index 0f87615bb06..4fe39a3acd9 100644 --- a/tests/auto/particles/qquickspritegoal/CMakeLists.txt +++ b/tests/auto/particles/qquickspritegoal/CMakeLists.txt @@ -7,15 +7,12 @@ # Collect test data file(GLOB_RECURSE test_data_glob RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - data/*) + data/* ../shared/*) list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickspritegoal SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickspritegoal.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickspritegoal Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp b/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp index 4f803b9b644..43fb3bafe71 100644 --- a/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp +++ b/tests/auto/particles/qquickspritegoal/tst_qquickspritegoal.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickspritegoal : public QQmlDataTest { Q_OBJECT public: - tst_qquickspritegoal() {} + tst_qquickspritegoal() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquicktargetdirection/CMakeLists.txt b/tests/auto/particles/qquicktargetdirection/CMakeLists.txt index 1bb462af66f..bd6526c83bd 100644 --- a/tests/auto/particles/qquicktargetdirection/CMakeLists.txt +++ b/tests/auto/particles/qquicktargetdirection/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquicktargetdirection SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquicktargetdirection.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquicktargetdirection Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp b/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp index a96c6e15efb..7f9bc0815a2 100644 --- a/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp +++ b/tests/auto/particles/qquicktargetdirection/tst_qquicktargetdirection.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquicktargetdirection : public QQmlDataTest { Q_OBJECT public: - tst_qquicktargetdirection() {} + tst_qquicktargetdirection() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquicktrailemitter/CMakeLists.txt b/tests/auto/particles/qquicktrailemitter/CMakeLists.txt index e7eb6ab6073..97065a258eb 100644 --- a/tests/auto/particles/qquicktrailemitter/CMakeLists.txt +++ b/tests/auto/particles/qquicktrailemitter/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquicktrailemitter SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquicktrailemitter.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquicktrailemitter Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp b/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp index a6b73e4f1d4..9fce9a5b29c 100644 --- a/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp +++ b/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquicktrailemitter : public QQmlDataTest { Q_OBJECT public: - tst_qquicktrailemitter() {} + tst_qquicktrailemitter() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickturbulence/CMakeLists.txt b/tests/auto/particles/qquickturbulence/CMakeLists.txt index 166649214c8..f538c04829d 100644 --- a/tests/auto/particles/qquickturbulence/CMakeLists.txt +++ b/tests/auto/particles/qquickturbulence/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickturbulence SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickturbulence.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickturbulence Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp b/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp index 69d47ffa1f3..597b0dddaa6 100644 --- a/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp +++ b/tests/auto/particles/qquickturbulence/tst_qquickturbulence.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickturbulence : public QQmlDataTest { Q_OBJECT public: - tst_qquickturbulence() {} + tst_qquickturbulence() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/particles/qquickwander/CMakeLists.txt b/tests/auto/particles/qquickwander/CMakeLists.txt index 8ce66a23181..f634b8bff24 100644 --- a/tests/auto/particles/qquickwander/CMakeLists.txt +++ b/tests/auto/particles/qquickwander/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickwander SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickwander.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickwander Qt::QmlPrivate Qt::QuickParticlesPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/particles/qquickwander/tst_qquickwander.cpp b/tests/auto/particles/qquickwander/tst_qquickwander.cpp index 8df00184b41..ec454615013 100644 --- a/tests/auto/particles/qquickwander/tst_qquickwander.cpp +++ b/tests/auto/particles/qquickwander/tst_qquickwander.cpp @@ -30,14 +30,13 @@ #include "../shared/particlestestsshared.h" #include <private/qquickparticlesystem_p.h> #include <private/qabstractanimation_p.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickwander : public QQmlDataTest { Q_OBJECT public: - tst_qquickwander() {} + tst_qquickwander() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/qml/CMakeLists.txt b/tests/auto/qml/CMakeLists.txt index 685d4fba023..5fe0b0950f1 100644 --- a/tests/auto/qml/CMakeLists.txt +++ b/tests/auto/qml/CMakeLists.txt @@ -12,6 +12,12 @@ add_subdirectory(qjsvalueiterator) add_subdirectory(qjsonbinding) add_subdirectory(qqmlfile) add_subdirectory(qqmlfileselector) + +# Limit set of tests to run for static Qt builds. +if(QT_BUILD_MINIMAL_STATIC_TESTS) + return() +endif() + add_subdirectory(qqmlcomponent) add_subdirectory(qqmlconsole) add_subdirectory(qqmlengine) @@ -21,7 +27,9 @@ add_subdirectory(qqmlinfo) add_subdirectory(qqmllistreference) add_subdirectory(qqmllocale) add_subdirectory(qqmlmetaobject) -add_subdirectory(qqmlmoduleplugin) +if(NOT ANDROID) # QTBUG-100003 + add_subdirectory(qqmlmoduleplugin) +endif() add_subdirectory(qqmlnotifier) add_subdirectory(qqmlqt) add_subdirectory(qqmlxmlhttprequest) @@ -30,9 +38,23 @@ add_subdirectory(qtqmlmodules) add_subdirectory(qquickfolderlistmodel) add_subdirectory(qqmlapplicationengine) add_subdirectory(qqmlsettings) -add_subdirectory(qmldiskcache) + +if(NOT INTEGRITY) +# There's no mounted filesystem on INTEGRITY therefore skipping qmldiskcache + add_subdirectory(qmldiskcache) +endif() + add_subdirectory(qqmlmetatype) add_subdirectory(qmlcompiler_manual) +if(TARGET Qt::Quick) + # This test always creates static plugins. To avoid linker command line + # ordering issues, we need at least CMake 3.21 and we cannot include the + # test if qmlimportscanner is being built as part of the main project. + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21 AND + (QT_BUILD_STANDALONE_TESTS OR QT6_IS_SHARED_LIBS_BUILD)) + add_subdirectory(qmlbasicapp) + endif() +endif() if(TARGET Qt::Widgets) add_subdirectory(qjsengine) add_subdirectory(qjsvalue) @@ -41,19 +63,20 @@ endif() if(QT_FEATURE_process AND QT_FEATURE_qml_debug) add_subdirectory(debugger) endif() -if(QT_FEATURE_process AND NOT boot2qt) +if(QT_FEATURE_process AND NOT CMAKE_CROSSCOMPILING) add_subdirectory(qmlformat) add_subdirectory(qmlimportscanner) add_subdirectory(qmllint) add_subdirectory(qmlplugindump) endif() -if(QT_FEATURE_library) +if(QT_FEATURE_library AND NOT ANDROID) + # QTBUG-100169 add_subdirectory(qqmlextensionplugin) endif() if(QT_FEATURE_private_tests) add_subdirectory(qqmlcpputils) add_subdirectory(qqmldirparser) - if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.19") + if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.19" AND QT_FEATURE_process) # Calls qt6_target_qml_sources() directly, which needs CMake 3.19+ add_subdirectory(qmlcachegen) endif() @@ -99,7 +122,9 @@ if(QT_FEATURE_private_tests) add_subdirectory(qv4mm) add_subdirectory(qv4identifiertable) add_subdirectory(qv4regexp) - add_subdirectory(ecmascripttests) + if(QT_FEATURE_process AND NOT QNX) + add_subdirectory(ecmascripttests) + endif() add_subdirectory(bindingdependencyapi) add_subdirectory(v4misc) add_subdirectory(qqmldelegatemodel) # special case diff --git a/tests/auto/qml/bindingdependencyapi/CMakeLists.txt b/tests/auto/qml/bindingdependencyapi/CMakeLists.txt index 775160e4c53..12ca578d934 100644 --- a/tests/auto/qml/bindingdependencyapi/CMakeLists.txt +++ b/tests/auto/qml/bindingdependencyapi/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_bindingdependencyapi SOURCES - ../../shared/util.cpp ../../shared/util.h tst_bindingdependencyapi.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/bindingdependencyapi/dummy_imports.qml b/tests/auto/qml/bindingdependencyapi/dummy_imports.qml index b9a196e188d..63d33cbea64 100644 --- a/tests/auto/qml/bindingdependencyapi/dummy_imports.qml +++ b/tests/auto/qml/bindingdependencyapi/dummy_imports.qml @@ -1,8 +1,7 @@ // This file exists for the sole purpose for qmlimportscanner to find // which modules it needs to extract for deployment. -// Otherwise, it fails to find the imports that are expressed in C++ -// code in tst_parserstress.cpp +// Otherwise, it fails to find the imports that are expressed in C++. -import QtQuick 2.0 +import QtQuick -QtObject { } // This is needed in order to keep importscanner happy +QtObject { } diff --git a/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp b/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp index 82c997a5b8e..81162c2c8a3 100644 --- a/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp +++ b/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp @@ -32,7 +32,6 @@ #include <private/qqmlbinding_p.h> #include <QtQuick/private/qquicktext_p.h> #include <QtQuick/private/qquickrectangle_p.h> -#include "../../shared/util.h" #include <qqmlcontext.h> class tst_bindingdependencyapi : public QObject @@ -49,6 +48,7 @@ private slots: void testConditionalDependencies_data(); void testConditionalDependencies(); void testBindingLoop(); + void testQproperty(); private: bool findProperties(const QVector<QQmlProperty> &properties, QObject *obj, const QString &propertyName, const QVariant &value); @@ -355,6 +355,36 @@ void tst_bindingdependencyapi::testBindingLoop() delete rect; } +void tst_bindingdependencyapi::testQproperty() +{ + QQmlEngine engine; + QQmlComponent c(&engine); + c.setData(QByteArray("import QtQuick 2.0\n" + "Item {\n" + "id: root\n" + "Text {\n" + "id: label\n" + "text: root.x\n" + "}\n" + "}"), QUrl()); + QScopedPointer<QObject> root(c.create()); + QVERIFY(!root.isNull()); + QObject *text = root->findChildren<QQuickText *>().front(); + QVERIFY(text); + auto data = QQmlData::get(text); + QVERIFY(data); + auto b = data->bindings; + QVERIFY(b); + auto binding = dynamic_cast<QQmlBinding*>(b); + QVERIFY(binding); + auto dependencies = binding->dependencies(); + QCOMPARE(dependencies.size(), 1); + auto dependency = dependencies.front(); + QVERIFY(dependency.isValid()); + QCOMPARE(quintptr(dependency.object()), quintptr(root.get())); + QCOMPARE(dependency.property().name(), "x"); +} + QTEST_MAIN(tst_bindingdependencyapi) #include "tst_bindingdependencyapi.moc" diff --git a/tests/auto/qml/debugger/CMakeLists.txt b/tests/auto/qml/debugger/CMakeLists.txt index b6558ac5c14..a8bb089e15b 100644 --- a/tests/auto/qml/debugger/CMakeLists.txt +++ b/tests/auto/qml/debugger/CMakeLists.txt @@ -1,25 +1,29 @@ # Generated from debugger.pro. add_subdirectory(qqmldebugjsserver) -add_subdirectory(qdebugmessageservice) - add_subdirectory(qqmldebugtranslationservice) -add_subdirectory(qqmldebugtranslationclient) - -add_subdirectory(qqmlenginedebugservice) -add_subdirectory(qqmldebugjs) -add_subdirectory(qqmlinspector) -add_subdirectory(qqmlprofilerservice) add_subdirectory(qpacketprotocol) -add_subdirectory(qqmlenginedebuginspectorintegrationtest) -add_subdirectory(qqmlenginecontrol) -add_subdirectory(qqmldebuggingenabler) add_subdirectory(qqmlnativeconnector) -add_subdirectory(qqmldebugprocess) -add_subdirectory(qqmlpreview) + +if(NOT (CMAKE_CROSSCOMPILING OR (MACOS AND TEST_architecture_arch STREQUAL "x86_64"))) + add_subdirectory(qdebugmessageservice) + add_subdirectory(qqmldebugtranslationclient) + add_subdirectory(qqmlenginedebugservice) + add_subdirectory(qqmldebugjs) + add_subdirectory(qqmlinspector) + add_subdirectory(qqmlprofilerservice) + add_subdirectory(qqmlenginedebuginspectorintegrationtest) + add_subdirectory(qqmlenginecontrol) + add_subdirectory(qqmldebuggingenabler) + add_subdirectory(qqmldebugprocess) + add_subdirectory(qqmlpreview) +endif() + if(QT_FEATURE_private_tests) add_subdirectory(qqmldebugclient) add_subdirectory(qqmldebuglocal) - add_subdirectory(qqmldebugservice) add_subdirectory(qv4debugger) + if(NOT (CMAKE_CROSSCOMPILING OR (MACOS AND TEST_architecture_arch STREQUAL "x86_64"))) + add_subdirectory(qqmldebugservice) + endif() endif() diff --git a/tests/auto/qml/debugger/qdebugmessageservice/CMakeLists.txt b/tests/auto/qml/debugger/qdebugmessageservice/CMakeLists.txt index 3ad886b0add..f6c4af80d13 100644 --- a/tests/auto/qml/debugger/qdebugmessageservice/CMakeLists.txt +++ b/tests/auto/qml/debugger/qdebugmessageservice/CMakeLists.txt @@ -12,19 +12,16 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qdebugmessageservice SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h tst_qdebugmessageservice.cpp - INCLUDE_DIRECTORIES - ../../../shared - ../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::Network Qt::QmlDebugPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp index ecee0db4282..d0aeefdacc8 100644 --- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp +++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp @@ -27,7 +27,7 @@ ****************************************************************************/ //QQmlDebugTest -#include "debugutil_p.h" +#include "../shared/debugutil_p.h" #include <private/qqmldebugclient_p.h> #include <private/qqmldebugconnection_p.h> @@ -44,6 +44,9 @@ class tst_QDebugMessageService : public QQmlDebugTest { Q_OBJECT +public: + tst_QDebugMessageService(); + private slots: void retrieveDebugOutput(); @@ -133,6 +136,11 @@ QList<QQmlDebugClient *> tst_QDebugMessageService::createClients() return QList<QQmlDebugClient *>({m_client}); } +tst_QDebugMessageService::tst_QDebugMessageService() + : QQmlDebugTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QDebugMessageService::retrieveDebugOutput() { QCOMPARE(QQmlDebugTest::connectTo(QLibraryInfo::path(QLibraryInfo::BinariesPath) + "/qml", diff --git a/tests/auto/qml/debugger/qpacketprotocol/CMakeLists.txt b/tests/auto/qml/debugger/qpacketprotocol/CMakeLists.txt index 3ab44c2670a..28708ff48b7 100644 --- a/tests/auto/qml/debugger/qpacketprotocol/CMakeLists.txt +++ b/tests/auto/qml/debugger/qpacketprotocol/CMakeLists.txt @@ -6,12 +6,10 @@ qt_internal_add_test(tst_qpacketprotocol SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h tst_qpacketprotocol.cpp INCLUDE_DIRECTORIES - ../../../shared ../shared PUBLIC_LIBRARIES Qt::CorePrivate @@ -19,6 +17,7 @@ qt_internal_add_test(tst_qpacketprotocol Qt::GuiPrivate Qt::Network Qt::QmlDebugPrivate + Qt::QuickTestUtilsPrivate ) ## Scopes: diff --git a/tests/auto/qml/debugger/qqmldebugclient/CMakeLists.txt b/tests/auto/qml/debugger/qqmldebugclient/CMakeLists.txt index 86009707a96..50089a4d576 100644 --- a/tests/auto/qml/debugger/qqmldebugclient/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmldebugclient/CMakeLists.txt @@ -6,7 +6,6 @@ qt_internal_add_test(tst_qqmldebugclient SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h ../shared/qqmldebugtestservice.cpp ../shared/qqmldebugtestservice.h @@ -15,7 +14,6 @@ qt_internal_add_test(tst_qqmldebugclient QT_QML_DEBUG QT_QML_DEBUG_NO_WARNING INCLUDE_DIRECTORIES - ../../../shared ../shared PUBLIC_LIBRARIES Qt::CorePrivate @@ -23,6 +21,7 @@ qt_internal_add_test(tst_qqmldebugclient Qt::GuiPrivate Qt::QmlDebugPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate ) ## Scopes: diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/CMakeLists.txt b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/CMakeLists.txt index 8b3f0b6d5c7..ae0f5f5b404 100644 --- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/CMakeLists.txt @@ -6,12 +6,10 @@ qt_internal_add_test(tst_qqmldebuggingenabler SOURCES - ../../../../shared/util.cpp ../../../../shared/util.h ../../shared/debugutil.cpp ../../shared/debugutil_p.h ../../shared/qqmldebugprocess.cpp ../../shared/qqmldebugprocess_p.h tst_qqmldebuggingenabler.cpp INCLUDE_DIRECTORIES - ../../../../shared ../../shared PUBLIC_LIBRARIES Qt::CorePrivate @@ -19,6 +17,7 @@ qt_internal_add_test(tst_qqmldebuggingenabler Qt::GuiPrivate Qt::Qml Qt::QmlDebugPrivate + Qt::QuickTestUtilsPrivate ) #### Keys ignored in scope 1:.:.:qqmldebuggingenabler.pro:<TRUE>: diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp index a22ae6e7a0a..163a9e2e7eb 100644 --- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp +++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp @@ -28,7 +28,7 @@ #include "debugutil_p.h" #include "qqmldebugprocess_p.h" -#include "../../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <private/qqmldebugclient_p.h> #include <private/qqmldebugconnection_p.h> @@ -47,6 +47,9 @@ class tst_QQmlDebuggingEnabler : public QQmlDebugTest { Q_OBJECT +public: + tst_QQmlDebuggingEnabler(); + private slots: void qmlscene_data(); void qmlscene(); @@ -91,6 +94,11 @@ void tst_QQmlDebuggingEnabler::data() } } +tst_QQmlDebuggingEnabler::tst_QQmlDebuggingEnabler() + : QQmlDebugTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QQmlDebuggingEnabler::qmlscene_data() { data(); diff --git a/tests/auto/qml/debugger/qqmldebugjs/CMakeLists.txt b/tests/auto/qml/debugger/qqmldebugjs/CMakeLists.txt index 99a885589e8..8741902c8e7 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmldebugjs/CMakeLists.txt @@ -12,18 +12,17 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmldebugjs SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h tst_qqmldebugjs.cpp INCLUDE_DIRECTORIES - ../../../shared - ../shared ../shared + ../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlDebugPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp index 41c0c5ec005..82f76ca30d8 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp @@ -28,7 +28,7 @@ #include "debugutil_p.h" #include "qqmldebugprocess_p.h" -#include "../../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <private/qqmlenginedebugclient_p.h> #include <private/qv4debugclient_p.h> @@ -82,6 +82,9 @@ class tst_QQmlDebugJS : public QQmlDebugTest { Q_OBJECT +public: + tst_QQmlDebugJS(); + private slots: void initTestCase() override; @@ -175,6 +178,11 @@ private slots: }; +tst_QQmlDebugJS::tst_QQmlDebugJS() + : QQmlDebugTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QQmlDebugJS::initTestCase() { QQmlDebugTest::initTestCase(); diff --git a/tests/auto/qml/debugger/qqmldebuglocal/CMakeLists.txt b/tests/auto/qml/debugger/qqmldebuglocal/CMakeLists.txt index 80836f5f6a4..0458b076dcb 100644 --- a/tests/auto/qml/debugger/qqmldebuglocal/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmldebuglocal/CMakeLists.txt @@ -6,7 +6,6 @@ qt_internal_add_test(tst_qqmldebuglocal SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h ../shared/qqmldebugtestservice.cpp ../shared/qqmldebugtestservice.h @@ -14,7 +13,6 @@ qt_internal_add_test(tst_qqmldebuglocal DEFINES QT_QML_DEBUG_NO_WARNING INCLUDE_DIRECTORIES - ../../../shared ../shared PUBLIC_LIBRARIES Qt::CorePrivate @@ -22,6 +20,7 @@ qt_internal_add_test(tst_qqmldebuglocal Qt::GuiPrivate Qt::QmlDebugPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate ) ## Scopes: diff --git a/tests/auto/qml/debugger/qqmldebugservice/CMakeLists.txt b/tests/auto/qml/debugger/qqmldebugservice/CMakeLists.txt index 7434dc42860..1642c71d93d 100644 --- a/tests/auto/qml/debugger/qqmldebugservice/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmldebugservice/CMakeLists.txt @@ -12,7 +12,6 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmldebugservice SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h ../shared/qqmldebugtestservice.cpp ../shared/qqmldebugtestservice.h @@ -20,7 +19,6 @@ qt_internal_add_test(tst_qqmldebugservice DEFINES QT_QML_DEBUG_NO_WARNING INCLUDE_DIRECTORIES - ../../../shared ../shared PUBLIC_LIBRARIES Qt::CorePrivate @@ -28,6 +26,7 @@ qt_internal_add_test(tst_qqmldebugservice Qt::GuiPrivate Qt::QmlDebugPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp index b90844bd100..d36ae80aa59 100644 --- a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp +++ b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp @@ -30,7 +30,7 @@ #include "qqmldebugtestservice.h" #include "debugutil_p.h" #include "qqmldebugprocess_p.h" -#include "../../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <private/qqmldebugclient_p.h> #include <private/qqmldebugconnection_p.h> @@ -51,6 +51,9 @@ class tst_QQmlDebugService : public QQmlDataTest { Q_OBJECT +public: + tst_QQmlDebugService(); + private: QQmlDebugConnection *m_conn; QQmlDebugTestService *m_service; @@ -69,6 +72,11 @@ private slots: void checkSupportForOldDataStreamVersion(); }; +tst_QQmlDebugService::tst_QQmlDebugService() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QQmlDebugService::initTestCase() { QQmlDataTest::initTestCase(); diff --git a/tests/auto/qml/debugger/qqmldebugtranslationclient/CMakeLists.txt b/tests/auto/qml/debugger/qqmldebugtranslationclient/CMakeLists.txt index 8d7a9b38c29..699a6adc7e2 100644 --- a/tests/auto/qml/debugger/qqmldebugtranslationclient/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmldebugtranslationclient/CMakeLists.txt @@ -10,13 +10,11 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmldebugtranslationclient SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h tst_qqmldebugtranslationclient.cpp INCLUDE_DIRECTORIES ../../../../../src/plugins/qmltooling/qmldbg_preview - ../../../shared ../shared PUBLIC_LIBRARIES Qt::QuickPrivate @@ -25,6 +23,7 @@ qt_internal_add_test(tst_qqmldebugtranslationclient Qt::GuiPrivate Qt::Network Qt::QmlDebugPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/debugger/qqmldebugtranslationclient/tst_qqmldebugtranslationclient.cpp b/tests/auto/qml/debugger/qqmldebugtranslationclient/tst_qqmldebugtranslationclient.cpp index 7bdf4a02f1d..1c73eb8521a 100644 --- a/tests/auto/qml/debugger/qqmldebugtranslationclient/tst_qqmldebugtranslationclient.cpp +++ b/tests/auto/qml/debugger/qqmldebugtranslationclient/tst_qqmldebugtranslationclient.cpp @@ -54,6 +54,10 @@ class tst_QQmlDebugTranslationClient : public QQmlDebugTest { Q_OBJECT public: + tst_QQmlDebugTranslationClient() + : QQmlDebugTest(QT_QMLTEST_DATADIR) + { + } private slots: void init() @@ -71,7 +75,7 @@ private slots: { QVersionedPacket<QQmlDebugConnector> packet; m_debugTranslationClient->sendMessage( - QQmlDebugTranslation::createMissingTranslationsRequest(packet)); + QQmlDebugTranslation::createTranslationIssuesRequest(packet)); QTRY_VERIFY(m_debugTranslationClient->translationIssues.size() > 0); } diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/BLACKLIST b/tests/auto/qml/debugger/qqmldebugtranslationservice/BLACKLIST new file mode 100644 index 00000000000..b572260e871 --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/BLACKLIST @@ -0,0 +1,7 @@ +# QTBUG-100164 +[verifyCorrectNumberOfMissingTranslations] +android +[getElideWarnings] +android +[getElideWarningsWhenStateChanged] +android diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/CMakeLists.txt b/tests/auto/qml/debugger/qqmldebugtranslationservice/CMakeLists.txt index 6c6ddcfb625..ae112c7c941 100644 --- a/tests/auto/qml/debugger/qqmldebugtranslationservice/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/CMakeLists.txt @@ -10,7 +10,6 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmldebugtranslationservice SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h tst_qqmldebugtranslationservice.cpp @@ -18,7 +17,6 @@ qt_internal_add_test(tst_qqmldebugtranslationservice QT_QML_DEBUG INCLUDE_DIRECTORIES ../../../../../src/plugins/qmltooling/qmldbg_preview - ../../../shared ../shared PUBLIC_LIBRARIES Qt::Quick @@ -29,6 +27,7 @@ qt_internal_add_test(tst_qqmldebugtranslationservice Qt::Network Qt::Qml Qt::QmlDebugPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_es.qm b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_es.qm index 8d8064cc554..75ecfc87f32 100644 Binary files a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_es.qm and b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_es.qm differ diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_es.ts b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_es.ts index e8d675ec0da..a4e8e96c57e 100644 --- a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_es.ts +++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_es.ts @@ -2,16 +2,26 @@ <!DOCTYPE TS> <TS version="2.1" language="es_ES"> <context> - <name>test</name> - <message> - <location filename="../test.qml" line="43"/> - <source>hello</source> + <name></name> + <message id="TRID_1"> + <source>TRID_1</source> <translation>hola</translation> </message> - <message> - <location filename="../test.qml" line="49"/> - <source>short</source> - <translation type="unfinished"></translation> + <message id="TRID_2"> + <source>TRID_2</source> + <translation>long text in spanish</translation> + </message> + <message id="TRID_3"> + <source>TRID_3</source> + <translation>spanish</translation> + </message> + <message id="TRID_4"> + <source>TRID_4</source> + <translation>has it</translation> + </message> + <message id="TRID_5"> + <source>TRID_5</source> + <translation>all !</translation> </message> </context> </TS> diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_fr.qm b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_fr.qm index 273539d28a8..4bc491c34f4 100644 Binary files a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_fr.qm and b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_fr.qm differ diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_fr.ts b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_fr.ts index fd4b8f5649a..b64fee2744b 100644 --- a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_fr.ts +++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/i18n/qml_fr.ts @@ -2,15 +2,25 @@ <!DOCTYPE TS> <TS version="2.1" language="fr_FR"> <context> - <name>test</name> - <message> - <location filename="../test.qml" line="43"/> - <source>hello</source> + <name></name> + <message id="TRID_1"> + <source>TRID_1</source> <translation>bonjour</translation> </message> - <message> - <location filename="../test.qml" line="49"/> - <source>short</source> + <message id="TRID_2"> + <source>TRID_2</source> + <translation>french misses some</translation> + </message> + <message id="TRID_3"> + <source>TRID_3</source> + <translation></translation> + </message> + <message id="TRID_4"> + <source>TRID_4</source> + <translation>TRID_4</translation> + </message> + <message id="TRID_5"> + <source>TRID_5</source> <translation type="unfinished"></translation> </message> </context> diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml index 325d8cdca54..1834ed37722 100644 --- a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml +++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml @@ -26,40 +26,48 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick - -Item { +Rectangle { id: root - width: 360 - height: 360 + width: 130 + height: 200 property int widthFactor: 7 Column { + anchors.fill: parent Text { id: text1 - text: qsTr("hello") - width: root.width / widthFactor + width: parent.width; + text: qsTrId("TRID_1") } Text { id: text2 - text: qsTr("short") - width: root.width / widthFactor + width: 100; + text: qsTrId("TRID_2") } Text { id: text3 - text: "long not translated text" - width: root.width / widthFactor + width: parent.width; + text: qsTrId("TRID_3") + } + Text { + id: text4 + width: parent.width; + text: qsTrId("TRID_4") + } + Text { + id: text5 + width: parent.width; + text: qsTrId("TRID_5") + } + Text { + id: text6 + width: parent.width; + text: "way too long not translated text that should elide but not be marked" } } - // this is necessary to have the test working for different font sizes and dpi settings - Text { - id: originHelloTextToGetTheNecessaryWidth - text: "short" - opacity: 0 - anchors.bottom: root.bottom - onWidthChanged: root.width = originHelloTextToGetTheNecessaryWidth.width * widthFactor - } + states: [ State { name: "BiggerFontState" @@ -79,10 +87,6 @@ Item { font.pointSize: 20 } - PropertyChanges { - target: originHelloTextToGetTheNecessaryWidth - font.pointSize: 20 - } }, State { name: "WayBiggerFontState" @@ -101,11 +105,6 @@ Item { target: text3 font.pointSize: 30 } - - PropertyChanges { - target: originHelloTextToGetTheNecessaryWidth - font.pointSize: 30 - } } ] } diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp b/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp index b2b0ee46618..6d9be9deab5 100644 --- a/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp +++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp @@ -61,6 +61,7 @@ class tst_QQmlDebugTranslationService : public QQmlDebugTest Q_OBJECT public: tst_QQmlDebugTranslationService() + : QQmlDebugTest(QT_QMLTEST_DATADIR) { } @@ -71,8 +72,6 @@ private slots: m_view.setSource((testFileUrl(QMLFILE))); QTRY_VERIFY2(m_view.status() == QQuickView::Ready, "Failed to load QML file"); - m_view.show(); - QVERIFY(QTest::qWaitForWindowActive(&m_view)); initQtHooks(); QVERIFY(hooks->qt_qmlDebugEnableService(qPrintable(QQmlDebugTranslationServiceImpl::s_key))); } @@ -83,146 +82,80 @@ private slots: QVERIFY(currentDebugServiceMessage().isEmpty()); } - void changeLanguage(const QString &language = QLocale::system().uiLanguages().first()) + void verifyMissingAllTranslationsForMissingLanguage() { - // only necessary for visual debugging - // QTest::qWait(500); - - QVersionedPacket<QQmlDebugConnector> packet; - sendMessageToService(createChangeLanguageRequest(packet, dataDirectoryUrl(), language)); - - // check without any eventloop cycle it should be still empty - QCOMPARE(currentDebugServiceMessage(), QByteArray()); + changeLanguage("ru"); + auto translationIssues = getTranslationIssues(); - QVersionedPacket<QQmlDebugConnector> expectedReply; - expectedReply << Reply::LanguageChanged; - QCOMPARE(currentReply().at(0), expectedReply.data()); - // clear buffer explicit, because it is used in other test methods as helper method aswell - hooks->qt_qmlDebugClearBuffer(); - QVERIFY(currentDebugServiceMessage().isEmpty()); + QCOMPARE(translationIssues.length(), getTranslatableTextOccurrences().count()); + QCOMPARE(translationIssues.at(0).language, "ru ru-RU ru-Cyrl-RU"); } - void streamTranslationIssues() + void verifyCorrectNumberOfMissingTranslations() { - TranslationIssue issue; - issue.type = TranslationIssue::Type::Missing; - CodeMarker codeMarker; - codeMarker.url = "url"; - codeMarker.line = 8; - codeMarker.column = 9; - issue.codeMarker = codeMarker; - issue.language = "language"; - QVersionedPacket<QQmlDebugConnector> writePacket; - writePacket << Reply::MissingTranslations - << QVector<TranslationIssue>{issue}; - Reply replyType; - QVector<TranslationIssue> replyTranslationIssues; - QVersionedPacket<QQmlDebugConnector> readPacket(writePacket.data()); - readPacket >> replyType; + changeLanguage("fr"); - readPacket >> replyTranslationIssues; + auto translationIssues = getTranslationIssues(); - QCOMPARE(replyTranslationIssues.at(0), issue); + QCOMPARE(translationIssues.length(), 3); + QCOMPARE(translationIssues.at(0).language, "fr fr-FR fr-Latn-FR"); } - void missingAllTranslations() + void verifyCorrectNumberOfTranslatableTextOccurrences() { - changeLanguage("ru"); - - QVersionedPacket<QQmlDebugConnector> packet; - sendMessageToService(createMissingTranslationsRequest(packet)); - const QList<QByteArray> replyMessages = currentReply(); - - TranslationIssue firstMissingTranslationLine; - firstMissingTranslationLine.type = TranslationIssue::Type::Missing; - CodeMarker codeMarker; - codeMarker.url = testFileUrl(QMLFILE); - codeMarker.line = 41; - codeMarker.column = 19; - firstMissingTranslationLine.codeMarker = codeMarker; - firstMissingTranslationLine.language = "ru ru-RU ru-Cyrl-RU"; - TranslationIssue secondMissingTranslationLine; - secondMissingTranslationLine.type = TranslationIssue::Type::Missing; - codeMarker.url = testFileUrl(QMLFILE); - codeMarker.line = 46; - codeMarker.column = 19; - secondMissingTranslationLine.codeMarker = codeMarker; - secondMissingTranslationLine.language = "ru ru-RU ru-Cyrl-RU"; - QVersionedPacket<QQmlDebugConnector> expectedReply; - expectedReply << Reply::MissingTranslations - << QVector<TranslationIssue>{firstMissingTranslationLine, secondMissingTranslationLine}; - - QVERIFY2(replyMessages.at(0) == expectedReply.data(), qPrintable(debugReply(replyMessages))); + QCOMPARE(getTranslatableTextOccurrences().length(), 5); } - void missingOneTranslation() + void verifyCorrectNumberOfStates() { - changeLanguage("fr"); - - QVersionedPacket<QQmlDebugConnector> packet; - sendMessageToService(createMissingTranslationsRequest(packet)); - const QList<QByteArray> replyMessages = currentReply(); - - - TranslationIssue missingTranslationLine; - missingTranslationLine.type = TranslationIssue::Type::Missing; - CodeMarker codeMarker; - codeMarker.url = testFileUrl(QMLFILE); - codeMarker.line = 46; - codeMarker.column = 19; - missingTranslationLine.codeMarker = codeMarker; - missingTranslationLine.language = "fr fr-FR fr-Latn-FR"; - QVersionedPacket<QQmlDebugConnector> expectedReply; - expectedReply << Reply::MissingTranslations - << QVector<TranslationIssue>{missingTranslationLine}; - - QVERIFY2(replyMessages.at(0) == expectedReply.data(), qPrintable(debugReply(replyMessages))); + QCOMPARE(getStates().length(), 2); } - void getTranslatableTextOccurrences() + void getElideWarnings() { - QVersionedPacket<QQmlDebugConnector> packet; - sendMessageToService(createTranslatableTextOccurrencesRequest(packet)); - QVersionedPacket<QQmlDebugConnector> readPacket(currentReply().at(0)); + sendMessageToService(createWatchTextElidesRequest(packet)); - Reply replyType; - QVector<QmlElement> replyQmlElementList; - readPacket >> replyType; - readPacket >> replyQmlElementList; - QCOMPARE(replyQmlElementList.count(), 2); + changeLanguage("es"); + auto translationIssues = getTranslationIssues(); + + int elideWarningCount = 0; + for (auto issue : translationIssues) { + if (issue.type == TranslationIssue::Type::Elided) { + elideWarningCount++; + } + } + QCOMPARE(elideWarningCount, 1); } - void getStates() + void getElideWarningsWhenStateChanged() { - QVersionedPacket<QQmlDebugConnector> packet; - sendMessageToService(createStateListRequest(packet)); - QVersionedPacket<QQmlDebugConnector> readPacket(currentReply().at(0)); + sendMessageToService(createWatchTextElidesRequest(packet)); - Reply replyType; - QVector<QmlState> replyStateList; - readPacket >> replyType; - readPacket >> replyStateList; - QCOMPARE(replyStateList.count(), 2); + changeLanguage("es"); + + sendMessageToService(createChangeStateRequest(packet, "WayBiggerFontState")); + + auto translationIssues = getTranslationIssues(); + + int elideWarningCount = 0; + for (auto issue : translationIssues) { + if (issue.type == TranslationIssue::Type::Elided) { + elideWarningCount++; + } + } + QCOMPARE(elideWarningCount, 1); } void loopThroughAllStates() { + QVector<QmlState> stateList = getStates(); - QVersionedPacket<QQmlDebugConnector> packet; - sendMessageToService(createStateListRequest(packet)); - QVersionedPacket<QQmlDebugConnector> readPacket(currentReply().at(0)); - - Reply replyType; - QVector<QmlState> replyStateList; - readPacket >> replyType; - readPacket >> replyStateList; - QCOMPARE(replyStateList.count(), 2); + QCOMPARE(stateList.length(), 2); - for (int i = 0; i < replyStateList.count(); i++) { - auto stateName = replyStateList.at(i).name; - hooks->qt_qmlDebugClearBuffer(); + for (int i = 0; i < stateList.count(); i++) { + auto stateName = stateList.at(i).name; QVersionedPacket<QQmlDebugConnector> packet; sendMessageToService(createChangeStateRequest(packet, stateName)); @@ -238,121 +171,61 @@ private slots: } } - void getElideWarning() +private: + + QVector<QmlElement> getTranslatableTextOccurrences() { + QVersionedPacket<QQmlDebugConnector> packet; + sendMessageToService(createTranslatableTextOccurrencesRequest(packet)); + QVersionedPacket<QQmlDebugConnector> readPacket(currentReply().at(0)); - changeLanguage("fr"); + Reply replyType; + QVector<QmlElement> qmlElementList; + readPacket >> replyType; + readPacket >> qmlElementList; - QVersionedPacket<QQmlDebugConnector> packet; - sendMessageToService(createWatchTextElidesRequest(packet)); - const QList<QByteArray> replyMessages = currentReply(); - - - const QByteArray reply1 = replyMessages.at(0); - - TranslationIssue elidedeTextLine; - elidedeTextLine.type = TranslationIssue::Type::Elided; - CodeMarker codeMarker; - codeMarker.url = testFileUrl(QMLFILE); - codeMarker.line = 41; - codeMarker.column = 19; - elidedeTextLine.codeMarker = codeMarker; - elidedeTextLine.language = "fr fr-FR fr-Latn-FR"; - QVersionedPacket<QQmlDebugConnector> expectedTextElidedReply; - expectedTextElidedReply << Reply::TextElided << elidedeTextLine; - - Reply replyType1; - TranslationIssue replyTranslationIssue; - QVersionedPacket<QQmlDebugConnector> readPacket1(reply1); - readPacket1 >> replyType1; - readPacket1 >> replyTranslationIssue; - QVERIFY2(reply1 == expectedTextElidedReply.data(), qPrintable(debugReply(replyMessages))); - - { - gotMessage = false; - auto handler = qInstallMessageHandler(messageHandler); - auto guard = qScopeGuard([&]() { qInstallMessageHandler(handler); }); - - packet.clear(); - sendMessageToService(createDisableWatchTextElidesRequest(packet)); - QTRY_VERIFY(gotMessage); - } + return qmlElementList; } - void getElideWarningsWhenStateChanged() + QVector<QmlState> getStates() { - // it is only eliding in fr - changeLanguage("fr"); QVersionedPacket<QQmlDebugConnector> packet; - sendMessageToService(createWatchTextElidesRequest(packet)); - const QString stateName("BiggerFontState"); - - packet.clear(); - - sendMessageToService(createChangeStateRequest(packet, stateName)); - - QList<QByteArray> replyMessagesWithElideWarnings; - - QByteArray stateChangedReply; - while (stateChangedReply.isEmpty()) { - for (const auto &reply : currentReply()) { - QVersionedPacket<QQmlDebugConnector> packet(reply); - Reply replyType; - packet >> replyType; - - if (replyType == Reply::StateChanged) - stateChangedReply = reply; - else - replyMessagesWithElideWarnings.append(replyMessagesWithElideWarnings); - } - hooks->qt_qmlDebugClearBuffer(); - } + sendMessageToService(createStateListRequest(packet)); + auto replies = currentReply(); + QVersionedPacket<QQmlDebugConnector> readPacket(replies.at(0)); - TranslationIssue expectedTranslationIssue; - expectedTranslationIssue.type = TranslationIssue::Type::Elided; - CodeMarker codeMarker; - codeMarker.url = testFileUrl(QMLFILE); - codeMarker.line = 41; - codeMarker.column = 19; - expectedTranslationIssue.codeMarker = codeMarker; - expectedTranslationIssue.language = "fr fr-FR fr-Latn-FR"; - - // text size is calculated many times, so it could be that we get - // the same warning many times - for (const QByteArray &message : replyMessagesWithElideWarnings) { - Reply replyType; - TranslationIssue translationIssue; - QVersionedPacket<QQmlDebugConnector> readPacket1(message); - readPacket1 >> replyType; - readPacket1 >> translationIssue; - QCOMPARE(replyType, Reply::TextElided); - QVERIFY2(expectedTranslationIssue == translationIssue, - qPrintable(debugReply(replyMessagesWithElideWarnings))); + Reply replyType; + QVector<QmlState> stateList; + readPacket >> replyType; + readPacket >> stateList; - } + return stateList; + } - QVersionedPacket<QQmlDebugConnector> expectedStateChangedReply; - expectedStateChangedReply << Reply::StateChanged << stateName; + void changeLanguage(const QString &language = QLocale::system().uiLanguages().first()) + { + QVersionedPacket<QQmlDebugConnector> packet; + sendMessageToService(createChangeLanguageRequest(packet, dataDirectoryUrl(), language)); + QVersionedPacket<QQmlDebugConnector> readPacket(currentReply().at(0)); - Reply replyType2; - QString stateNameReply; - QVersionedPacket<QQmlDebugConnector> readPacket2(stateChangedReply); - readPacket2 >> replyType2 >> stateNameReply; - QCOMPARE(stateChangedReply, expectedStateChangedReply.data()); + // Use this for visual debugging + // QTest::qWait(500); + } - { - gotMessage = false; - auto handler = qInstallMessageHandler(messageHandler); - auto guard = qScopeGuard([&]() { qInstallMessageHandler(handler); }); + QVector<TranslationIssue> getTranslationIssues() + { + QVersionedPacket<QQmlDebugConnector> packet; + sendMessageToService(createTranslationIssuesRequest(packet)); + QVersionedPacket<QQmlDebugConnector> readPacket(currentReply().at(0)); - packet.clear(); - sendMessageToService(createDisableWatchTextElidesRequest(packet)); + Reply replyType; + QVector<TranslationIssue> translationIssues; + readPacket >> replyType; + readPacket >> translationIssues; - QTRY_VERIFY(gotMessage); - } + return translationIssues; } -private: QByteArray debugServiceMessage(const QByteArray &data) { QByteArray message; @@ -380,10 +253,17 @@ private slots: } void sendMessageToService(const QByteArray &message) { + clearBuffer(); hooks->qt_qmlDebugSendDataToService( qPrintable(QQmlDebugTranslationServiceImpl::s_key), message.toHex()); } + void clearBuffer() + { + hooks->qt_qmlDebugClearBuffer(); + QCoreApplication::processEvents(); + } + QByteArray currentDebugServiceMessage() { return QByteArray::fromRawData(*hooks->qt_qmlDebugMessageBuffer, *hooks->qt_qmlDebugMessageLength); @@ -424,12 +304,10 @@ private slots: return "LanguageChanged"; case Reply::StateChanged: return "StateChanged"; - case Reply::MissingTranslations: - return "MissingTranslations"; + case Reply::TranslationIssues: + return "TranslationIssues"; case Reply::TranslatableTextOccurrences: return "TranslatableTextOccurrences"; - case Reply::TextElided: - return "TextElided"; default: Q_ASSERT_X(false, "not implemented", "not implemented"); } @@ -442,7 +320,7 @@ private slots: QVersionedPacket<QQmlDebugConnector> readPacket(message); readPacket >> replyType; debugString.append(replyTypeToString(replyType)); - if (replyType == Reply::MissingTranslations) { + if (replyType == Reply::TranslationIssues) { QVector<TranslationIssue> translationIssues; readPacket >> translationIssues; QStringList translationIssueStrings; @@ -457,42 +335,10 @@ private slots: debugString.append(translationIssuesString.arg(QString::number(translationIssues.size()), translationIssueStrings.join("; "))); } - if (replyType == Reply::TextElided) { - TranslationIssue translationIssue; - readPacket >> translationIssue; - debugString.append(QString(" %1 ").arg(translationIssue.toDebugString())); - } } return debugString; } - QString missingRussionTranslationWarningLine42() const - { - const QString fileUrl(testFileUrl(QMLFILE).toString()); - return QString("%1:42:19: QQmlDebugTranslationService: In locale ru ru-RU ru-Cyrl-RU translation is missing.").arg(fileUrl); - } - QString missingFranceTranslationWarningLine47() const - { - const QString fileUrl(testFileUrl(QMLFILE).toString()); - return QString("%1:47:19: QQmlDebugTranslationService: In locale fr fr-FR fr-Latn-FR translation is missing.").arg(fileUrl); - } - QString missingSpainTranslationWarningLine47() const - { - const QString fileUrl(testFileUrl(QMLFILE).toString()); - return QString("%1:47:19: QQmlDebugTranslationService: In locale es es-ES es-Latn-ES translation is missing.").arg(fileUrl); - } - QString missingRussionTranslationWarningLine47() const - { - const QString fileUrl(testFileUrl(QMLFILE).toString()); - return QString("%1:47:19: QQmlDebugTranslationService: In locale ru ru-RU ru-Cyrl-RU translation is missing.").arg(fileUrl); - } - - QString franceElideWarningMessageLine42() const - { - return QString( - "%1:42:19: QQmlDebugTranslationService: In locale fr fr-FR fr-Latn-FR the translated text is eliding." - ).arg(testFileUrl(QMLFILE).toString()); - } QQuickView m_view; QmlState m_currentState; diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/CMakeLists.txt b/tests/auto/qml/debugger/qqmlenginecontrol/CMakeLists.txt index 63eda146ea3..faa80f16e40 100644 --- a/tests/auto/qml/debugger/qqmlenginecontrol/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmlenginecontrol/CMakeLists.txt @@ -12,18 +12,17 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlenginecontrol SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h tst_qqmlenginecontrol.cpp INCLUDE_DIRECTORIES - ../../../shared ../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlDebugPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp index 05abab737e5..b209a9e059b 100644 --- a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp +++ b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp @@ -27,7 +27,7 @@ ****************************************************************************/ #include "debugutil_p.h" -#include "../../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <private/qqmldebugclient_p.h> #include <private/qqmldebugconnection_p.h> @@ -47,7 +47,8 @@ public slots: void blockEngine(int engineId, const QString &name); }; -QQmlEngineBlocker::QQmlEngineBlocker(QQmlEngineControlClient *parent): QObject(parent) +QQmlEngineBlocker::QQmlEngineBlocker(QQmlEngineControlClient *parent) + : QObject(parent) { connect(parent, &QQmlEngineControlClient::engineAboutToBeAdded, this, &QQmlEngineBlocker::blockEngine); @@ -65,6 +66,9 @@ class tst_QQmlEngineControl : public QQmlDebugTest { Q_OBJECT +public: + tst_QQmlEngineControl(); + private: ConnectResult connectTo(const QString &testFile, bool restrictServices); QList<QQmlDebugClient *> createClients() override; @@ -79,6 +83,11 @@ private slots: void stopEngine(); }; +tst_QQmlEngineControl::tst_QQmlEngineControl() + : QQmlDebugTest(QT_QMLTEST_DATADIR) +{ +} + QQmlDebugTest::ConnectResult tst_QQmlEngineControl::connectTo(const QString &file, bool restrictServices) { diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/CMakeLists.txt b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/CMakeLists.txt index e2553e1abc4..f48c9a942bd 100644 --- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/CMakeLists.txt @@ -12,18 +12,17 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlenginedebuginspectorintegration SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h tst_qqmlenginedebuginspectorintegration.cpp INCLUDE_DIRECTORIES - ../../../shared ../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlDebugPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp index 34c6faf4aea..094d3daeb45 100644 --- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp @@ -27,7 +27,7 @@ ****************************************************************************/ #include "../shared/debugutil_p.h" -#include "../../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <private/qqmldebugconnection_p.h> #include <private/qqmlenginedebugclient_p.h> @@ -45,6 +45,9 @@ class tst_QQmlEngineDebugInspectorIntegration : public QQmlDebugTest { Q_OBJECT +public: + tst_QQmlEngineDebugInspectorIntegration(); + private: ConnectResult init(bool restrictServices); QList<QQmlDebugClient *> createClients() override; @@ -85,6 +88,11 @@ QQmlEngineDebugObjectReference tst_QQmlEngineDebugInspectorIntegration::findRoot return m_engineDebugClient->object(); } +tst_QQmlEngineDebugInspectorIntegration::tst_QQmlEngineDebugInspectorIntegration() + : QQmlDebugTest(QT_QMLTEST_DATADIR) +{ +} + QQmlDebugTest::ConnectResult tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices) { return QQmlDebugTest::connectTo( diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/CMakeLists.txt b/tests/auto/qml/debugger/qqmlenginedebugservice/CMakeLists.txt index 4c3b449cb4b..e632f91548b 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/CMakeLists.txt @@ -4,22 +4,28 @@ ## tst_qqmlenginedebugservice Test: ##################################################################### +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + qt_internal_add_test(tst_qqmlenginedebugservice SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h tst_qqmlenginedebugservice.cpp DEFINES QT_QML_DEBUG_NO_WARNING INCLUDE_DIRECTORIES - ../../../shared ../shared PUBLIC_LIBRARIES Qt::Gui Qt::QmlDebugPrivate Qt::QmlPrivate Qt::Quick + Qt::QuickTestUtilsPrivate + TESTDATA ${test_data} ) ## Scopes: diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/data/complexItem.qml b/tests/auto/qml/debugger/qqmlenginedebugservice/data/complexItem.qml new file mode 100644 index 00000000000..ae8b681013f --- /dev/null +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/data/complexItem.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Test 1.0 +Item { + id: root + width: 10; height: 20; scale: blueRect.scale; + Rectangle { id: blueRect; width: 500; height: 600; color: "blue"; } + Text { font.bold: true; color: blueRect.color; } + MouseArea { + onEntered: { console.log('hello') } + } + property variant varObj + property variant varObjList: [] + property variant varObjMap + property variant simpleVar: 10.05 + Component.onCompleted: { + varObj = blueRect; + var list = varObjList; + list[0] = blueRect; + varObjList = list; + var map = new Object; + map.rect = blueRect; + varObjMap = map; + } + NonScriptPropertyElement { + } +} diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/data/customTypes.qml b/tests/auto/qml/debugger/qqmlenginedebugservice/data/customTypes.qml new file mode 100644 index 00000000000..21c0ee84ba7 --- /dev/null +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/data/customTypes.qml @@ -0,0 +1,31 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +import Backend 1.0 +CustomTypes { +} diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/data/emptyItem.qml b/tests/auto/qml/debugger/qqmlenginedebugservice/data/emptyItem.qml new file mode 100644 index 00000000000..9bff34e1e57 --- /dev/null +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/data/emptyItem.qml @@ -0,0 +1,31 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +import QtQuick 2.0 +Item { +} diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/data/itemWithFunctions.qml b/tests/auto/qml/debugger/qqmlenginedebugservice/data/itemWithFunctions.qml new file mode 100644 index 00000000000..ba1617cb37e --- /dev/null +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/data/itemWithFunctions.qml @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +import QtQuick 2.0 +Item { + function myMethodNoArgs() { return 3; } + function myMethod(a) { return a + 9; } + function myMethodIndirect() { myMethod(3); } +} diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/data/jsonTest.qml b/tests/auto/qml/debugger/qqmlenginedebugservice/data/jsonTest.qml new file mode 100644 index 00000000000..53cae7a2717 --- /dev/null +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/data/jsonTest.qml @@ -0,0 +1,31 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +import JsonTest 1.0 +JsonTest { +} diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/data/rectangleWithTransitions.qml b/tests/auto/qml/debugger/qqmlenginedebugservice/data/rectangleWithTransitions.qml new file mode 100644 index 00000000000..5447c1577a6 --- /dev/null +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/data/rectangleWithTransitions.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +import QtQuick 2.0 +Rectangle { + id: rootRect + width: 100 + states: [ + State { + name: "state1" + PropertyChanges { + target: rootRect + width: 200 + } + } + ] + transitions: [ + Transition { + from: "*" + to: "state1" + PropertyAnimation { + target: rootRect + property: "width" + duration: 100 + } + } + ] +} diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp index a87a77180f0..9d6daa2cd11 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp @@ -27,7 +27,7 @@ ****************************************************************************/ #include "debugutil_p.h" -#include "../../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <private/qqmlbinding_p.h> #include <private/qqmlboundsignal_p.h> @@ -119,11 +119,16 @@ public slots: }; -class tst_QQmlEngineDebugService : public QObject +class tst_QQmlEngineDebugService : public QQmlDataTest { Q_OBJECT public: - tst_QQmlEngineDebugService() : m_conn(nullptr), m_dbg(nullptr), m_engine(nullptr), m_rootItem(nullptr) {} + tst_QQmlEngineDebugService() + : QQmlDataTest(QT_QMLTEST_DATADIR) + , m_conn(nullptr) + , m_dbg(nullptr) + , m_engine(nullptr) + , m_rootItem(nullptr) {} private: QQmlEngineDebugObjectReference findRootObject(int context = 0, @@ -146,7 +151,7 @@ class tst_QQmlEngineDebugService : public QObject QObjectList m_components; private slots: - void initTestCase(); + void initTestCase() override; void cleanupTestCase(); void watch_property(); @@ -327,93 +332,34 @@ void tst_QQmlEngineDebugService::getContexts() void tst_QQmlEngineDebugService::initTestCase() { + QQmlDataTest::initTestCase(); + qmlRegisterType<NonScriptProperty>("Test", 1, 0, "NonScriptPropertyElement"); QTest::ignoreMessage(QtDebugMsg, "QML Debugger: Waiting for connection on port 3768..."); m_engine = new QQmlEngine(this); - QList<QByteArray> qml; - qml << "import QtQuick 2.0\n" - "import Test 1.0\n" - "Item {" - "id: root\n" - "width: 10; height: 20; scale: blueRect.scale;" - "Rectangle { id: blueRect; width: 500; height: 600; color: \"blue\"; }" - "Text { font.bold: true; color: blueRect.color; }" - "MouseArea {" - "onEntered: { console.log('hello') }" - "}" - "property variant varObj\n" - "property variant varObjList: []\n" - "property variant varObjMap\n" - "property variant simpleVar: 10.05\n" - "Component.onCompleted: {\n" - "varObj = blueRect;\n" - "var list = varObjList;\n" - "list[0] = blueRect;\n" - "varObjList = list;\n" - "var map = new Object;\n" - "map.rect = blueRect;\n" - "varObjMap = map;\n" - "}\n" - "NonScriptPropertyElement {\n" - "}\n" - "}"; - - // add second component to test multiple root contexts - qml << "import QtQuick 2.0\n" - "Item {}"; - - // and a third to test methods - qml << "import QtQuick 2.0\n" - "Item {" - "function myMethodNoArgs() { return 3; }\n" - "function myMethod(a) { return a + 9; }\n" - "function myMethodIndirect() { myMethod(3); }\n" - "}"; - - // and a fourth to test states - qml << "import QtQuick 2.0\n" - "Rectangle {\n" - "id:rootRect\n" - "width:100\n" - "states: [\n" - "State {\n" - "name:\"state1\"\n" - "PropertyChanges {\n" - "target:rootRect\n" - "width:200\n" - "}\n" - "}\n" - "]\n" - "transitions: [\n" - "Transition {\n" - "from:\"*\"\n" - "to:\"state1\"\n" - "PropertyAnimation {\n" - "target:rootRect\n" - "property:\"width\"\n" - "duration:100\n" - "}\n" - "}\n" - "]\n" - "}\n" - ; - - // test non-streamable properties qmlRegisterType<CustomTypes>("Backend", 1, 0, "CustomTypes"); - qml << "import Backend 1.0\n" - "CustomTypes {}" - ; - qmlRegisterType<JsonTest>("JsonTest", 1, 0, "JsonTest"); - qml << "import JsonTest 1.0\n" - "JsonTest {}" - ; - for (int i=0; i<qml.count(); i++) { - QQmlComponent component(m_engine); - component.setData(qml[i], QUrl::fromLocalFile("")); + // The contents of these files was previously hardcoded as QList<QByteArray> + // directly in this test, but that fails on Android, because the required + // dependencies are not deployed. When the contents is moved to separate + // files, qmlimportscanner is capable of providing all the necessary + // dependencies. + // Note that the order of the files in this list matters! The test-cases + // expect Qml components to be created is certain order. + constexpr const char *fileNames[] = { + "complexItem.qml", + "emptyItem.qml", + "itemWithFunctions.qml", + "rectangleWithTransitions.qml", + "customTypes.qml", + "jsonTest.qml" + }; + + for (auto file : fileNames) { + QQmlComponent component(m_engine, testFileUrl(file)); QVERIFY(component.isReady()); // fails if bad syntax m_components << qobject_cast<QQuickItem*>(component.create()); } @@ -752,8 +698,8 @@ void tst_QQmlEngineDebugService::queryObject() // check source as defined in main() QQmlEngineDebugFileReference source = obj.source; - QCOMPARE(source.url, QUrl::fromLocalFile("")); - QCOMPARE(source.lineNumber, 3); + QCOMPARE(source.url, testFileUrl("complexItem.qml")); + QCOMPARE(source.lineNumber, 31); // because of license header QCOMPARE(source.columnNumber, 1); // generically test all properties, children and childrens' properties @@ -831,7 +777,7 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation() // check source as defined in main() QQmlEngineDebugFileReference source = obj.source; - QCOMPARE(source.url, QUrl(fileName)); + QCOMPARE(source.url, testFileUrl(fileName)); QCOMPARE(source.lineNumber, lineNumber); QCOMPARE(source.columnNumber, columnNumber); diff --git a/tests/auto/qml/debugger/qqmlinspector/CMakeLists.txt b/tests/auto/qml/debugger/qqmlinspector/CMakeLists.txt index 3303c7d110d..4c5ae110842 100644 --- a/tests/auto/qml/debugger/qqmlinspector/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmlinspector/CMakeLists.txt @@ -12,18 +12,17 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlinspector SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h tst_qqmlinspector.cpp INCLUDE_DIRECTORIES - ../../../shared ../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlDebugPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp index 1c72242703e..90a10f6dcd6 100644 --- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp +++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp @@ -28,7 +28,7 @@ #include "../shared/debugutil_p.h" #include "../shared/qqmldebugprocess_p.h" -#include "../../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <private/qqmldebugconnection_p.h> #include <private/qqmlinspectorclient_p.h> @@ -45,6 +45,9 @@ class tst_QQmlInspector : public QQmlDebugTest { Q_OBJECT +public: + tst_QQmlInspector(); + private: ConnectResult startQmlProcess(const QString &qmlFile, bool restrictMode = true); void checkAnimationSpeed(int targetMillisPerDegree); @@ -61,6 +64,11 @@ private slots: void showAppOnTop(); }; +tst_QQmlInspector::tst_QQmlInspector() + : QQmlDebugTest(QT_QMLTEST_DATADIR) +{ +} + QQmlDebugTest::ConnectResult tst_QQmlInspector::startQmlProcess(const QString &qmlFile, bool restrictServices) { diff --git a/tests/auto/qml/debugger/qqmlpreview/CMakeLists.txt b/tests/auto/qml/debugger/qqmlpreview/CMakeLists.txt index aef78fe28e1..2672d0d0080 100644 --- a/tests/auto/qml/debugger/qqmlpreview/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmlpreview/CMakeLists.txt @@ -15,18 +15,17 @@ list(APPEND test_data "data/zoom.qml") qt_internal_add_test(tst_qqmlpreview SOURCES ../../../../../src/plugins/qmltooling/qmldbg_preview/qqmlpreviewblacklist.cpp ../../../../../src/plugins/qmltooling/qmldbg_preview/qqmlpreviewblacklist.h - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h tst_qqmlpreview.cpp INCLUDE_DIRECTORIES ../../../../../src/plugins/qmltooling/qmldbg_preview - ../../../shared ../shared PUBLIC_LIBRARIES Qt::Gui Qt::Qml Qt::QmlDebugPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp b/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp index 8d24c9fc52f..cc48e43c08e 100644 --- a/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp +++ b/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp @@ -45,6 +45,9 @@ class tst_QQmlPreview : public QQmlDebugTest { Q_OBJECT +public: + tst_QQmlPreview(); + private: ConnectResult startQmlProcess(const QString &qmlFile); void serveRequest(const QString &path); @@ -71,6 +74,11 @@ private slots: void fps(); }; +tst_QQmlPreview::tst_QQmlPreview() + : QQmlDebugTest(QT_QMLTEST_DATADIR) +{ +} + QQmlDebugTest::ConnectResult tst_QQmlPreview::startQmlProcess(const QString &qmlFile) { return QQmlDebugTest::connectTo(QLibraryInfo::path(QLibraryInfo::BinariesPath) + "/qml", diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/CMakeLists.txt b/tests/auto/qml/debugger/qqmlprofilerservice/CMakeLists.txt index 394e4aa08d9..3d57619bbb9 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/CMakeLists.txt +++ b/tests/auto/qml/debugger/qqmlprofilerservice/CMakeLists.txt @@ -12,17 +12,16 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlprofilerservice SOURCES - ../../../shared/util.cpp ../../../shared/util.h ../shared/debugutil.cpp ../shared/debugutil_p.h ../shared/qqmldebugprocess.cpp ../shared/qqmldebugprocess_p.h tst_qqmlprofilerservice.cpp INCLUDE_DIRECTORIES - ../../../shared ../shared PUBLIC_LIBRARIES Qt::Gui Qt::GuiPrivate Qt::QmlDebugPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp index 2b564e48ad8..54ba3f2a270 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp +++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp @@ -28,7 +28,7 @@ #include "debugutil_p.h" #include "qqmldebugprocess_p.h" -#include "../../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <private/qqmlprofilerclient_p.h> #include <private/qqmldebugconnection_p.h> @@ -45,8 +45,8 @@ class QQmlProfilerTestClient : public QQmlProfilerEventReceiver Q_OBJECT public: - QQmlProfilerTestClient(QQmlDebugConnection *connection) : - client(new QQmlProfilerClient(connection, this)) + QQmlProfilerTestClient(QQmlDebugConnection *connection) + : client(new QQmlProfilerClient(connection, this)) { connect(client.data(), &QQmlProfilerClient::traceStarted, this, &QQmlProfilerTestClient::startTrace); @@ -180,6 +180,9 @@ class tst_QQmlProfilerService : public QQmlDebugTest { Q_OBJECT +public: + tst_QQmlProfilerService(); + private: enum MessageListType { MessageListQML, @@ -246,6 +249,11 @@ private slots: #define VERIFY(type, position, expected, checks, numbers) \ QVERIFY(verify(type, position, expected, checks, numbers)) +tst_QQmlProfilerService::tst_QQmlProfilerService() + : QQmlDebugTest(QT_QMLTEST_DATADIR) +{ +} + QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connectTo( bool block, const QString &file, bool recordFromStart, uint flushInterval, bool restrictServices, const QString &executable) diff --git a/tests/auto/qml/debugger/qv4debugger/CMakeLists.txt b/tests/auto/qml/debugger/qv4debugger/CMakeLists.txt index f106208737c..92565f55c13 100644 --- a/tests/auto/qml/debugger/qv4debugger/CMakeLists.txt +++ b/tests/auto/qml/debugger/qv4debugger/CMakeLists.txt @@ -4,6 +4,24 @@ ## tst_qv4debugger Test: ##################################################################### +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_add_library(testCppTypes STATIC) +qt_autogen_tools_initial_setup(testCppTypes) +target_link_libraries(testCppTypes PRIVATE Qt::Qml Qt::QmlPrivate Qt::Quick) + +qt6_add_qml_module(testCppTypes + VERSION 1.0 + URI TestTypes + SOURCES + commontypes.h +) +qt_autogen_tools_initial_setup(testCppTypesplugin) + qt_internal_add_test(tst_qv4debugger SOURCES ../../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp ../../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h @@ -18,7 +36,20 @@ qt_internal_add_test(tst_qv4debugger Qt::GuiPrivate Qt::Network Qt::QmlPrivate + Qt::QuickTestUtilsPrivate + testCppTypesplugin + TESTDATA ${test_data} ) ## Scopes: ##################################################################### + +qt_internal_extend_target(tst_qv4debugger CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" + ) + +qt_internal_extend_target(tst_qv4debugger CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" + ) diff --git a/tests/auto/qml/debugger/qv4debugger/commontypes.h b/tests/auto/qml/debugger/qv4debugger/commontypes.h new file mode 100644 index 00000000000..01b2125ae35 --- /dev/null +++ b/tests/auto/qml/debugger/qv4debugger/commontypes.h @@ -0,0 +1,20 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef COMMONTYPES_H +#define COMMONTYPES_H + +#include <QtQuick/qquickitem.h> +#include <QtQml/qqmlregistration.h> +#include <QtQml/private/qv4engine_p.h> + +class MyType : public QQuickItem +{ + Q_OBJECT + QML_ELEMENT +public: + MyType(QQuickItem *parent = nullptr) : QQuickItem(parent) {} + Q_INVOKABLE void name(QQmlV4Function*) const {} +}; + +#endif // COMMONTYPES_H diff --git a/tests/auto/qml/debugger/qv4debugger/data/breakPointInJSModule.qml b/tests/auto/qml/debugger/qv4debugger/data/breakPointInJSModule.qml new file mode 100644 index 00000000000..2582a23ec5a --- /dev/null +++ b/tests/auto/qml/debugger/qv4debugger/data/breakPointInJSModule.qml @@ -0,0 +1,4 @@ +import QtQml 2.15 +import "module1.js" as Module1 + +QtObject {} diff --git a/tests/auto/qml/debugger/qv4debugger/data/conditionalBreakPointInQml.qml b/tests/auto/qml/debugger/qv4debugger/data/conditionalBreakPointInQml.qml new file mode 100644 index 00000000000..ceb4edbe7ad --- /dev/null +++ b/tests/auto/qml/debugger/qv4debugger/data/conditionalBreakPointInQml.qml @@ -0,0 +1,9 @@ +import QtQml 2.0 +QtObject { + id: root + property int foo: 42 + property bool success: false + Component.onCompleted: { + success = true; // break here + } +} diff --git a/tests/auto/qml/debugger/qv4debugger/data/module1.js b/tests/auto/qml/debugger/qv4debugger/data/module1.js new file mode 100644 index 00000000000..9ce1f1e6b10 --- /dev/null +++ b/tests/auto/qml/debugger/qv4debugger/data/module1.js @@ -0,0 +1,5 @@ +.pragma library + +.import "module2.mjs" as Module2 + +Module2.crashMe(); diff --git a/tests/auto/qml/debugger/qv4debugger/data/module2.mjs b/tests/auto/qml/debugger/qv4debugger/data/module2.mjs new file mode 100644 index 00000000000..80f82af953b --- /dev/null +++ b/tests/auto/qml/debugger/qv4debugger/data/module2.mjs @@ -0,0 +1,7 @@ +import * as Module3 from "module3.mjs" +import * as Module4 from "module4.mjs" + +export function crashMe() +{ + console.log("Hello world!"); +} diff --git a/tests/auto/qml/debugger/qv4debugger/data/module3.mjs b/tests/auto/qml/debugger/qv4debugger/data/module3.mjs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/auto/qml/debugger/qv4debugger/data/module4.mjs b/tests/auto/qml/debugger/qv4debugger/data/module4.mjs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/auto/qml/debugger/qv4debugger/data/qtbug_107607.qml b/tests/auto/qml/debugger/qv4debugger/data/qtbug_107607.qml new file mode 100644 index 00000000000..a7758de8a85 --- /dev/null +++ b/tests/auto/qml/debugger/qv4debugger/data/qtbug_107607.qml @@ -0,0 +1,10 @@ +import QtQuick +import TestTypes +MyType { + objectName: "patron" + Item { + Component.onCompleted: { + console.log("Hallo Welt"); + } + } +} \ No newline at end of file diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp index 610665146be..331d978dd7f 100644 --- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp @@ -25,6 +25,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtTest/QtTest> #include "qv4datacollector.h" @@ -40,10 +41,13 @@ #include <private/qv4string_p.h> #include <private/qqmlbuiltinfunctions_p.h> #include <private/qqmldebugservice_p.h> +#include <QtQml/qqmlextensionplugin.h> using namespace QV4; using namespace QV4::Debugging; +Q_IMPORT_QML_PLUGIN(TestTypesPlugin); + typedef QV4::ReturnedValue (*InjectedFunction)(const FunctionObject *b, const QV4::Value *, const QV4::Value *, int); Q_DECLARE_METATYPE(InjectedFunction) @@ -200,7 +204,15 @@ public slots: ExpressionEvalJob job(debugger->engine(), request.frameNr, request.context, request.expression, &collector); debugger->runInEngine(&job); - m_expressionResults << job.returnValue(); + const QJsonObject& result = job.returnValue(); + m_expressionResults << result; + + if (request.shouldLookup) { + QJsonArray handles {result.value("handle").toInt()}; + ValueLookupJob job(handles, &collector); + debugger->runInEngine(&job); + m_lookupResults << job.returnValue(); + } } if (m_captureContextInfo) @@ -229,10 +241,14 @@ public slots: QJsonArray scopes = frameObj.value(QLatin1String("scopes")).toArray(); int nscopes = scopes.size(); int s = 0; - for (s = 0; s < nscopes; ++s) { - QJsonObject o = scopes.at(s).toObject(); - if (o.value(QLatin1String("type")).toInt(-2) == 1) // CallContext - break; + if (m_targetScope != -1) { + s = m_targetScope; + } else { + for (s = 0; s < nscopes; ++s) { + QJsonObject o = scopes.at(s).toObject(); + if (o.value(QLatin1String("type")).toInt(-2) == 1) // CallContext + break; + } } if (s == nscopes) return; @@ -262,6 +278,7 @@ public slots: bool m_wasPaused; QV4Debugger::PauseReason m_pauseReason; bool m_captureContextInfo; + int m_targetScope = -1; QList<QV4Debugger::ExecutionState> m_statesWhenPaused; QList<TestBreakPoint> m_breakPointsToAddWhenPaused; QVector<QV4::StackFrame> m_stackTrace; @@ -273,10 +290,14 @@ public slots: QString expression; int frameNr; int context; + bool shouldLookup = false; }; + + QVector<ExpressionRequest> m_expressionRequests; QV4Debugger::Speed m_resumeSpeed; QList<QJsonObject> m_expressionResults; + QList<QJsonObject> m_lookupResults; QV4Debugger *m_debugger; // Utility methods: @@ -289,10 +310,13 @@ public slots: } }; -class tst_qv4debugger : public QObject +class tst_qv4debugger : public QQmlDataTest { Q_OBJECT +public: + tst_qv4debugger(); + private slots: void init(); void cleanup(); @@ -327,6 +351,9 @@ private slots: void readThis(); void signalParameters(); + void debuggerNoCrash(); + + void breakPointInJSModule(); private: QV4Debugger *debugger() const @@ -489,7 +516,7 @@ void tst_qv4debugger::conditionalBreakPoint() QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 3); + QCOMPARE(frame0.size(), 2); QVERIFY(frame0.contains("i")); QCOMPARE(frame0.value("i").toInt(), 11); } @@ -507,24 +534,17 @@ void tst_qv4debugger::conditionalBreakPointInQml() debuggerAgent->addDebugger(v4Debugger); debuggerAgent->moveToThread(debugThread.data()); - QQmlComponent component(&engine); - component.setData("import QtQml 2.0\n" - "QtObject {\n" - " id: root\n" - " property int foo: 42\n" - " property bool success: false\n" - " Component.onCompleted: {\n" - " success = true;\n" // breakpoint here - " }\n" - "}\n", QUrl("test.qml")); + const QString qmlFileName("conditionalBreakPointInQml.qml"); + const QString qmlFilePath(testFile(qmlFileName)); + QQmlComponent component(&engine, qmlFilePath); - v4Debugger->addBreakPoint("test.qml", 7, "root.foo == 42"); + v4Debugger->addBreakPoint(qmlFileName, 7, "root.foo == 42"); QScopedPointer<QObject> obj(component.create()); QCOMPARE(obj->property("success").toBool(), true); QCOMPARE(debuggerAgent->m_statesWhenPaused.count(), 1); - QCOMPARE(debuggerAgent->m_statesWhenPaused.at(0).fileName, QStringLiteral("test.qml")); + QCOMPARE(debuggerAgent->m_statesWhenPaused.at(0).fileName, qmlFileName); QCOMPARE(debuggerAgent->m_statesWhenPaused.at(0).lineNumber, 7); debugThread->quit(); @@ -545,7 +565,7 @@ void tst_qv4debugger::readArguments() QVERIFY(m_debuggerAgent->m_wasPaused); QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 5); + QCOMPARE(frame0.size(), 4); QVERIFY(frame0.contains(QStringLiteral("a"))); QCOMPARE(frame0.type(QStringLiteral("a")), QStringLiteral("number")); QCOMPARE(frame0.value(QStringLiteral("a")).toDouble(), 1.0); @@ -568,7 +588,7 @@ void tst_qv4debugger::readComplicatedArguments() QVERIFY(m_debuggerAgent->m_wasPaused); QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 2); + QCOMPARE(frame0.size(), 1); QVERIFY(frame0.contains(QStringLiteral("a"))); QCOMPARE(frame0.type(QStringLiteral("a")), QStringLiteral("number")); QCOMPARE(frame0.value(QStringLiteral("a")).toInt(), 12); @@ -591,7 +611,7 @@ void tst_qv4debugger::readLocals() QVERIFY(m_debuggerAgent->m_wasPaused); QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 7); // locals and parameters + QCOMPARE(frame0.size(), 6); // locals and parameters QVERIFY(frame0.contains("c")); QCOMPARE(frame0.type("c"), QStringLiteral("number")); QCOMPARE(frame0.value("c").toDouble(), 3.0); @@ -619,7 +639,7 @@ void tst_qv4debugger::readObject() QVERIFY(m_debuggerAgent->m_wasPaused); QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 3); + QCOMPARE(frame0.size(), 2); QVERIFY(frame0.contains("b")); QCOMPARE(frame0.type("b"), QStringLiteral("object")); QJsonObject b = frame0.rawValue("b"); @@ -680,7 +700,7 @@ void tst_qv4debugger::readContextInAllFrames() for (int i = 0; i < 12; ++i) { const TestAgent::NamedRefs &scope = m_debuggerAgent->m_capturedScope.at(i); - QCOMPARE(scope.size(), 3); + QCOMPARE(scope.size(), 2); QVERIFY(scope.contains("n")); QCOMPARE(scope.type("n"), QStringLiteral("number")); QCOMPARE(scope.value("n").toDouble(), i + 1.0); @@ -944,6 +964,73 @@ void tst_qv4debugger::signalParameters() QCOMPARE(obj->property("resultCallbackExternal").toString(), QLatin1String("unset")); } +void tst_qv4debugger::debuggerNoCrash() +{ + QQmlEngine engine; + QV4::ExecutionEngine *v4 = engine.handle(); + QPointer<QV4Debugger> v4Debugger = new QV4Debugger(v4); + v4->setDebugger(v4Debugger.data()); + + QScopedPointer<QThread> debugThread(new QThread); + debugThread->start(); + QScopedPointer<TestAgent> debuggerAgent(new TestAgent(v4)); + debuggerAgent->addDebugger(v4Debugger); + debuggerAgent->moveToThread(debugThread.data()); + + const QString qmlFileName("qtbug_107607.qml"); + const QString qmlFilePath(testFile(qmlFileName)); + QQmlComponent component(&engine, qmlFilePath); + + TestAgent::ExpressionRequest request; + request.expression = "this.parent"; + request.frameNr = 0; + request.context = -1; + request.shouldLookup = true; + debuggerAgent->m_expressionRequests << request; + v4Debugger->addBreakPoint(qmlFileName, 7); + + QScopedPointer<QObject> obj(component.create()); + + QVERIFY(debuggerAgent->m_lookupResults.size() > 0); + const QJsonObject result = debuggerAgent->m_lookupResults[0]; + const QJsonArray properties = result["0"].toObject().value("properties").toArray(); + QCOMPARE(properties[0].toObject().value("value").toString(), QStringLiteral("patron")); + + debugThread->quit(); + debugThread->wait(); +} + +void tst_qv4debugger::breakPointInJSModule() +{ + QQmlEngine engine; + QV4::ExecutionEngine *v4 = engine.handle(); + QPointer<QV4Debugger> v4Debugger = new QV4Debugger(v4); + v4->setDebugger(v4Debugger.data()); + + QScopedPointer<QThread> debugThread(new QThread); + debugThread->start(); + QScopedPointer<TestAgent> debuggerAgent(new TestAgent(v4)); + debuggerAgent->addDebugger(v4Debugger); + debuggerAgent->moveToThread(debugThread.data()); + + QQmlComponent component(&engine, testFileUrl("breakPointInJSModule.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + + debuggerAgent->m_captureContextInfo = true; + debuggerAgent->m_targetScope = 1; + v4Debugger->addBreakPoint("module2.mjs", 6); + + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + + QVERIFY(!debuggerAgent->m_capturedScope.isEmpty()); + + debugThread->quit(); + debugThread->wait(); +} + +tst_qv4debugger::tst_qv4debugger() : QQmlDataTest(QT_QMLTEST_DATADIR) { } + QTEST_MAIN(tst_qv4debugger) #include "tst_qv4debugger.moc" diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp index 3787f34bc2b..4598e288c7b 100644 --- a/tests/auto/qml/debugger/shared/debugutil.cpp +++ b/tests/auto/qml/debugger/shared/debugutil.cpp @@ -34,6 +34,11 @@ #include <QtCore/qeventloop.h> #include <QtCore/qtimer.h> +QQmlDebugTest::QQmlDebugTest(const char *qmlTestDataDir) + : QQmlDataTest(qmlTestDataDir) +{ +} + bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int timeout) { QEventLoop loop; QTimer timer; diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h index ad24eaa7f86..e19f59d3f2d 100644 --- a/tests/auto/qml/debugger/shared/debugutil_p.h +++ b/tests/auto/qml/debugger/shared/debugutil_p.h @@ -40,13 +40,16 @@ // We mean it. // -#include <../../../shared/util.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <private/qqmldebugclient_p.h> class QQmlDebugProcess; class QQmlDebugTest : public QQmlDataTest { Q_OBJECT +public: + QQmlDebugTest(const char *qmlTestDataDir); + public: static bool waitForSignal(QObject *receiver, const char *member, int timeout = 5000); static QList<QQmlDebugClient *> createOtherClients(QQmlDebugConnection *connection); diff --git a/tests/auto/qml/ecmascripttests/CMakeLists.txt b/tests/auto/qml/ecmascripttests/CMakeLists.txt index 78e1c97e91b..078881c41a9 100644 --- a/tests/auto/qml/ecmascripttests/CMakeLists.txt +++ b/tests/auto/qml/ecmascripttests/CMakeLists.txt @@ -13,4 +13,6 @@ qt_internal_add_test(tst_ecmascripttests ) set_property(TEST tst_ecmascripttests APPEND PROPERTY ENVIRONMENT "QTEST_FUNCTION_TIMEOUT=900000") -add_subdirectory(qjstest) +if(NOT CMAKE_CROSSCOMPILING) + add_subdirectory(qjstest) +endif() diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index 6b743ba433f..82d80f7f033 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -600,7 +600,6 @@ language/statements/class/definition/methods-gen-yield-as-literal-property-name. language/statements/class/definition/methods-gen-yield-as-property-name.js fails language/statements/class/definition/methods-named-eval-arguments.js fails language/statements/class/definition/prototype-property.js fails -language/statements/class/definition/setters-prop-desc.js fails language/statements/class/definition/setters-restricted-ids.js fails language/statements/class/definition/this-access-restriction-2.js fails language/statements/class/definition/this-access-restriction.js fails diff --git a/tests/auto/qml/ecmascripttests/qjstest/test262runner.cpp b/tests/auto/qml/ecmascripttests/qjstest/test262runner.cpp index 24633d9c6d2..9037ed0c92b 100644 --- a/tests/auto/qml/ecmascripttests/qjstest/test262runner.cpp +++ b/tests/auto/qml/ecmascripttests/qjstest/test262runner.cpp @@ -393,9 +393,7 @@ void Test262Runner::loadTestExpectations() return; } - int line = 0; while (!file.atEnd()) { - ++line; QByteArray line = file.readLine().trimmed(); if (line.startsWith('#') || line.isEmpty()) continue; @@ -440,9 +438,7 @@ void Test262Runner::updateTestExpectations() QTemporaryFile updatedExpectations; updatedExpectations.open(); - int line = 0; while (!file.atEnd()) { - ++line; QByteArray originalLine = file.readLine(); QByteArray line = originalLine.trimmed(); if (line.startsWith('#') || line.isEmpty()) { diff --git a/tests/auto/qml/parserstress/CMakeLists.txt b/tests/auto/qml/parserstress/CMakeLists.txt index 2d2f3df4c3b..4505dab1da6 100644 --- a/tests/auto/qml/parserstress/CMakeLists.txt +++ b/tests/auto/qml/parserstress/CMakeLists.txt @@ -18,8 +18,12 @@ qt_internal_add_test(tst_parserstress Qt::Gui Qt::GuiPrivate Qt::QmlPrivate - TESTDATA ${test_data} + TESTDATA ${test_data} "dummy_imports.qml" ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_parserstress) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/qml/parserstress/dummy_imports.qml b/tests/auto/qml/parserstress/dummy_imports.qml index b9a196e188d..63d33cbea64 100644 --- a/tests/auto/qml/parserstress/dummy_imports.qml +++ b/tests/auto/qml/parserstress/dummy_imports.qml @@ -1,8 +1,7 @@ // This file exists for the sole purpose for qmlimportscanner to find // which modules it needs to extract for deployment. -// Otherwise, it fails to find the imports that are expressed in C++ -// code in tst_parserstress.cpp +// Otherwise, it fails to find the imports that are expressed in C++. -import QtQuick 2.0 +import QtQuick -QtObject { } // This is needed in order to keep importscanner happy +QtObject { } diff --git a/tests/auto/qml/qjsengine/CMakeLists.txt b/tests/auto/qml/qjsengine/CMakeLists.txt index 3488a73a25e..86efc2c0c25 100644 --- a/tests/auto/qml/qjsengine/CMakeLists.txt +++ b/tests/auto/qml/qjsengine/CMakeLists.txt @@ -28,7 +28,7 @@ qt_internal_add_test(tst_qjsengine Qt::Widgets LIBRARIES # special case Threads::Threads # special case - TESTDATA ${test_data} + TESTDATA ${test_data} "dummy_imports.qml" ) # Resources: @@ -62,6 +62,10 @@ qt_internal_add_resource(tst_qjsengine "qmake_immediate" ${qmake_immediate_resource_files} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qjsengine) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qjsengine/dummy_imports.qml b/tests/auto/qml/qjsengine/dummy_imports.qml index 8d86f3583b8..afe2b33adf4 100644 --- a/tests/auto/qml/qjsengine/dummy_imports.qml +++ b/tests/auto/qml/qjsengine/dummy_imports.qml @@ -1,8 +1,7 @@ // This file exists for the sole purpose for qmlimportscanner to find // which modules it needs to extract for deployment. -// Otherwise, it fails to find the imports that are expressed in C++ -// code in tst_parserstress.cpp +// Otherwise, it fails to find the imports that are expressed in C++. -import QtQml 2.0 +import QtQml -QtObject { } // This is needed in order to keep importscanner happy +QtObject { } diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 1cc48bd73b5..7883ca721dc 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -43,6 +43,7 @@ #include <QScopeGuard> #include <QUrl> #include <QModelIndex> +#include <QtQml/qqmllist.h> #ifdef Q_CC_MSVC #define NO_INLINE __declspec(noinline) @@ -105,8 +106,11 @@ private slots: void valueConversion_RegularExpression(); void castWithMultipleInheritance(); void collectGarbage(); + void collectGarbageNestedWrappersTwoEngines(); void gcWithNestedDataStructure(); void stacktrace(); + void unshiftAndSort(); + void unshiftAndPushAndSort(); void numberParsing_data(); void numberParsing(); void automaticSemicolonInsertion(); @@ -264,11 +268,13 @@ private slots: void triggerBackwardJumpWithDestructuring(); void arrayConcatOnSparseArray(); + void concatAfterUnshift(); void sortSparseArray(); void compileBrokenRegexp(); void sortNonStringArray(); void iterateInvalidProxy(); void applyOnHugeArray(); + void reflectApplyOnHugeArray(); void tostringRecursionCheck(); void arrayIncludesWithLargeArray(); @@ -278,6 +284,13 @@ private slots: void uiLanguage(); void urlObject(); + void thisInConstructor(); + void forOfAndGc(); + + void symbolToVariant(); + + void garbageCollectedObjectMethodBase(); + void spreadNoOverflow(); public: Q_INVOKABLE QJSValue throwingCppMethod1(); @@ -855,7 +868,11 @@ void tst_QJSEngine::newQObjectRace() { void run() override { - for (int i=0;i<1000;++i) + int newObjectCount = 1000; +#if defined(Q_OS_QNX) + newObjectCount = 256; +#endif + for (int i=0;i<newObjectCount;++i) { QJSEngine e; auto obj = e.newQObject(new QObject); @@ -986,6 +1003,17 @@ class TestQMetaObject : public QObject { int m_called = 1; }; +class TestQMetaObject2 : public QObject +{ + Q_OBJECT +public: + Q_INVOKABLE TestQMetaObject2(int a) : m_called(a) {} + int called() const { return m_called; } + +private: + int m_called = 1; +}; + void tst_QJSEngine::newQObjectPropertyCache() { QScopedPointer<QObject> obj(new QObject); @@ -1060,6 +1088,18 @@ void tst_QJSEngine::newQMetaObject() { QCOMPARE(metaObject.property("C").toInt(), 2); } + { + QJSEngine engine; + const QJSValue metaObject = engine.newQMetaObject(&TestQMetaObject2::staticMetaObject); + engine.globalObject().setProperty(QLatin1String("Example"), metaObject); + + const QJSValue invalid = engine.evaluate(QLatin1String("new Example()")); + QVERIFY(invalid.isError()); + QCOMPARE(invalid.toString(), QLatin1String("Error: Insufficient arguments")); + + const QJSValue valid = engine.evaluate(QLatin1String("new Example(123)")); + QCOMPARE(qjsvalue_cast<TestQMetaObject2 *>(valid)->called(), 123); + } } void tst_QJSEngine::exceptionInSlot() @@ -1619,6 +1659,13 @@ void tst_QJSEngine::valueConversion_basic() QCOMPARE(eng.fromScriptValue<QChar>(eng.toScriptValue(c)), c); } + { + QList<QObject *> list = {this}; + QQmlListProperty<QObject> prop(this, &list); + QJSValue jsVal = eng.toScriptValue(prop); + QCOMPARE(eng.fromScriptValue<QQmlListProperty<QObject>>(jsVal), prop); + } + QVERIFY(eng.toScriptValue(static_cast<void *>(nullptr)).isNull()); } @@ -1841,6 +1888,44 @@ void tst_QJSEngine::collectGarbage() QVERIFY(ptr.isNull()); } +class TestObjectContainer : public QObject +{ + Q_OBJECT + Q_PROPERTY(QObject *dummy MEMBER m_dummy CONSTANT) + +public: + TestObjectContainer() : m_dummy(new QObject(this)) {} + +private: + QObject *m_dummy; +}; + +void tst_QJSEngine::collectGarbageNestedWrappersTwoEngines() +{ + QJSEngine engine1; + QJSEngine engine2; + + TestObjectContainer container; + QQmlEngine::setObjectOwnership(&container, QQmlEngine::CppOwnership); + + engine1.globalObject().setProperty("foobar", engine1.newQObject(&container)); + engine2.globalObject().setProperty("foobar", engine2.newQObject(&container)); + + engine1.evaluate("foobar.dummy.baz = 42"); + engine2.evaluate("foobar.dummy.baz = 43"); + + QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42); + QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43); + + engine1.collectGarbage(); + engine2.collectGarbage(); + + // The GC should not collect dummy object wrappers neither in engine1 nor engine2, we + // verify that by checking whether the baz property still has its previous value. + QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42); + QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43); +} + void tst_QJSEngine::gcWithNestedDataStructure() { // The GC must be able to traverse deeply nested objects, otherwise this @@ -1971,6 +2056,81 @@ void tst_QJSEngine::stacktrace() } } +void tst_QJSEngine::unshiftAndSort() +{ + QJSEngine engine; + QJSValue func = engine.evaluate(R"""( + (function (objectArr, currIdx) { + objectArr.unshift({"sortIndex": currIdx}); + objectArr.sort(function(a, b) { + if (a.sortIndex > b.sortIndex) + return 1; + if (a.sortIndex < b.sortIndex) + return -1; + return 0; + }); + return objectArr; + }) + )"""); + QVERIFY(func.isCallable()); + QJSValue objectArr = engine.newArray(); + + for (int i = 0; i < 5; ++i) { + objectArr = func.call({objectArr, i}); + QVERIFY2(!objectArr.isError(), qPrintable(objectArr.toString())); + const int length = objectArr.property("length").toInt(); + + // It did add one element + QCOMPARE(length, i + 1); + + for (int x = 0; x < length; ++x) { + // We didn't sort cruft into the array. + QVERIFY(!objectArr.property(x).isUndefined()); + + // The array is actually sorted. + QCOMPARE(objectArr.property(x).property("sortIndex").toInt(), x); + } + } +} + +void tst_QJSEngine::unshiftAndPushAndSort() +{ + QJSEngine engine; + QJSValue func = engine.evaluate(R"""( + (function (objectArr, currIdx) { + objectArr.unshift({"sortIndex": currIdx}); + objectArr.push({"sortIndex": currIdx + 1}); + objectArr.sort(function(a, b) { + if (a.sortIndex > b.sortIndex) + return 1; + if (a.sortIndex < b.sortIndex) + return -1; + return 0; + }); + return objectArr; + }) + )"""); + QVERIFY(func.isCallable()); + QJSValue objectArr = engine.newArray(); + + for (int i = 0; i < 20; i += 2) { + objectArr = func.call({objectArr, i}); + QVERIFY2(!objectArr.isError(), qPrintable(objectArr.toString())); + const int length = objectArr.property("length").toInt(); + + // It did add 2 elements + QCOMPARE(length, i + 2); + + for (int x = 0; x < length; ++x) { + // We didn't sort cruft into the array. + QVERIFY(!objectArr.property(x).isUndefined()); + + // The array is actually sorted. + QCOMPARE(objectArr.property(x).property("sortIndex").toInt(), x); + } + } +} + void tst_QJSEngine::numberParsing_data() { QTest::addColumn<QString>("string"); @@ -5148,6 +5308,23 @@ void tst_QJSEngine::arrayConcatOnSparseArray() QVERIFY(value.property(i).isUndefined()); } +void tst_QJSEngine::concatAfterUnshift() +{ + QJSEngine engine; + const auto value = engine.evaluate(uR"( + (function() { + let test = ['val2'] + test.unshift('val1') + test = test.concat([]) + return test + })() + )"_qs); + QVERIFY2(!value.isError(), qPrintable(value.toString())); + QVERIFY(value.isArray()); + QCOMPARE(value.property(0).toString(), u"val1"_qs); + QCOMPARE(value.property(1).toString(), u"val2"_qs); +} + void tst_QJSEngine::sortSparseArray() { QJSEngine engine; @@ -5264,12 +5441,28 @@ void tst_QJSEngine::applyOnHugeArray() QCOMPARE(value.toString(), "RangeError: Array too large for apply()."); } + +void tst_QJSEngine::reflectApplyOnHugeArray() +{ + QQmlEngine engine; + const QJSValue value = engine.evaluate(R"( +(function(){ +const v1 = []; +const v3 = []; +v3.length = 3900000000; +Reflect.apply(v1.reverse,v1,v3); +})() + )"); + QVERIFY(value.isError()); + QCOMPARE(value.toString(), QLatin1String("RangeError: Invalid array length.")); +} + void tst_QJSEngine::typedArraySet() { QJSEngine engine; const auto value = engine.evaluate( "(function() {" - " var length = 0xffffffe;" + " var length = 0xfffffe0;" " var offset = 0xfffffff0;" " var e1;" " var e2;" @@ -5418,6 +5611,211 @@ void tst_QJSEngine::urlObject() QCOMPARE(result2, url); } +void tst_QJSEngine::thisInConstructor() +{ + QJSEngine engine; + const QJSValue result = engine.evaluate(R"((function() { + let a = undefined; + class Bugtest { + constructor() { + (() => { + if (true) { + a = this; + } + })(); + } + }; + new Bugtest(); + return a; + })())"); + QVERIFY(!result.isUndefined()); + QVERIFY(result.isObject()); +} + +void tst_QJSEngine::forOfAndGc() +{ + // We want to guard against the iterator of a for..of loop leaving the result unprotected from + // garbage collection. It should be possible to construct a pure JS test case, but due to the + // vaguaries of garbage collection it's hard to reliably trigger the crash. This test is the + // best I could come up with. + + QQmlEngine engine; + QQmlComponent c(&engine); + c.setData(R"( + import QtQml + + QtObject { + id: counter + property int count: 0 + + property DelegateModel model: DelegateModel { + id: filesModel + + model: ListModel { + Component.onCompleted: { + for (let idx = 0; idx < 50; idx++) + append({"i" : idx}) + } + } + + groups: [ + DelegateModelGroup { + name: "selected" + } + ] + + function getSelected() { + for (let i = 0; i < items.count; ++i) { + var item = items.get(i) + for (let el of item.groups) { + if (el === "selected") + ++counter.count + } + } + } + + property bool bSelect: true + function selectAll() { + for (let i = 0; i < items.count; ++i) { + if (bSelect && !items.get(i).inSelected) + items.addGroups(i, 1, ["selected"]) + else + items.removeGroups(i, 1, ["selected"]) + getSelected() + } + bSelect = !bSelect + } + } + + property Timer timer: Timer { + running: true + interval: 1 + repeat: true + onTriggered: filesModel.selectAll() + } + } + )", QUrl()); + + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + + QTRY_VERIFY(o->property("count").toInt() > 32768); +} + +void tst_QJSEngine::symbolToVariant() +{ + QJSEngine engine; + const QJSValue val = engine.newSymbol("asymbol"); + QCOMPARE(val.toVariant(), QStringLiteral("Symbol(asymbol)")); + + const QVariant retained = val.toVariant(QJSValue::RetainJSObjects); + QCOMPARE(retained.metaType(), QMetaType::fromType<QJSValue>()); + QVERIFY(retained.value<QJSValue>().strictlyEquals(val)); + + QCOMPARE(val.toVariant(QJSValue::ConvertJSObjects), QStringLiteral("Symbol(asymbol)")); +} + +class PACHelper : public QObject { + Q_OBJECT +public: + Q_INVOKABLE bool shExpMatch(const QString &, const QString &) { return false; } + Q_INVOKABLE QString dnsResolve(const QString &) { return QString{}; } +}; + +class ProxyAutoConf { +public: + void exposeQObjectMethodsAsGlobal(QJSEngine *engine, QObject *object) + { + QJSValue helper = engine->newQObject(object); + QJSValue g = engine->globalObject(); + QJSValueIterator it(helper); + while (it.hasNext()) { + it.next(); + if (!it.value().isCallable()) + continue; + g.setProperty(it.name(), it.value()); + } + } + + bool parse(const QString & pacBytes) + { + jsFindProxyForURL = QJSValue(); + engine = std::make_unique<QJSEngine>(); + exposeQObjectMethodsAsGlobal(engine.get(), new PACHelper); + engine->evaluate(pacBytes); + jsFindProxyForURL = engine->globalObject().property(QStringLiteral("FindProxyForURL")); + return true; + } + + QString findProxyForUrl(const QString &url, const QString &host) + { + QJSValueList args; + args << url << host; + engine->collectGarbage(); + QJSValue callResult = jsFindProxyForURL.call(args); + return callResult.toString().trimmed(); + } + +private: + std::unique_ptr<QJSEngine> engine; + QJSValue jsFindProxyForURL; +}; + +QString const pacstring = R"js( +function FindProxyForURL(host) { + list_split_all = Array( + "oneoneoneoneo.oneo.oneo.oneoneo.one", + "twotwotwotwotw.otwo.twot.wotwotw.otw", + "threethreethr.eeth.reet.hreethr.eet", + "fourfourfourfo.urfo.urfo.urfourf.our", + "fivefivefivef.ivef.ivef.ivefive.fiv", + "sixsixsixsixsi.xsix.sixs.ixsixsi.xsi", + "sevensevenseve.nsev.ense.venseve.nse", + "eight.eighteigh.tei", + "*.nin.eninen.ine" + ) + list_myip_direct = + "10.254.0.0/255.255.0.0" + for (i = 0; i < list_split_all.length; ++i) + for (j = 0; j < list_myip_direct.length; ++j) + shExpMatch(host, list_split_all) + shExpMatch() + dnsResolve()} +)js"; + +void tst_QJSEngine::garbageCollectedObjectMethodBase() +{ + ProxyAutoConf proxyConf; + bool pac_read = false; + + const auto processUrl = [&](QString const &url, QString const &host) + { + if (!pac_read) { + proxyConf.parse(pacstring); + pac_read = true; + } + return proxyConf.findProxyForUrl(url, host); + }; + + const QString url = QStringLiteral("https://servername.domain.test"); + const QString host = QStringLiteral("servername.domain.test"); + + for (size_t i = 0; i < 5; ++i) { + auto future = std::async(processUrl, url, host); + QCOMPARE(future.get(), QLatin1String("Error: Insufficient arguments")); + } +} + +void tst_QJSEngine::spreadNoOverflow() +{ + QJSEngine engine; + + const QString program = QString::fromLatin1("var a = [] ;a.length = 555840;Math.max(...a)"); + const QJSValue result = engine.evaluate(program); + QVERIFY(result.isError()); + QCOMPARE(result.errorType(), QJSValue::RangeError); +} + QTEST_MAIN(tst_QJSEngine) #include "tst_qjsengine.moc" diff --git a/tests/auto/qml/qjsmanagedvalue/CMakeLists.txt b/tests/auto/qml/qjsmanagedvalue/CMakeLists.txt index 3e466d8e2ea..2449b9a3200 100644 --- a/tests/auto/qml/qjsmanagedvalue/CMakeLists.txt +++ b/tests/auto/qml/qjsmanagedvalue/CMakeLists.txt @@ -10,7 +10,12 @@ qt_internal_add_test(tst_qjsmanagedvalue PUBLIC_LIBRARIES Qt::Qml Qt::QmlPrivate + TESTDATA "dummy_imports.qml" ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qjsmanagedvalue) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qjsmanagedvalue/dummy_imports.qml b/tests/auto/qml/qjsmanagedvalue/dummy_imports.qml new file mode 100644 index 00000000000..afe2b33adf4 --- /dev/null +++ b/tests/auto/qml/qjsmanagedvalue/dummy_imports.qml @@ -0,0 +1,7 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQml + +QtObject { } diff --git a/tests/auto/qml/qjsonbinding/CMakeLists.txt b/tests/auto/qml/qjsonbinding/CMakeLists.txt index 1704e4e7905..b85fd7b99c4 100644 --- a/tests/auto/qml/qjsonbinding/CMakeLists.txt +++ b/tests/auto/qml/qjsonbinding/CMakeLists.txt @@ -12,14 +12,12 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qjsonbinding SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qjsonbinding.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::GuiPrivate Qt::Qml + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qjsonbinding/tst_qjsonbinding.cpp b/tests/auto/qml/qjsonbinding/tst_qjsonbinding.cpp index 05e1ce8b6b5..4c12f6d44c9 100644 --- a/tests/auto/qml/qjsonbinding/tst_qjsonbinding.cpp +++ b/tests/auto/qml/qjsonbinding/tst_qjsonbinding.cpp @@ -27,7 +27,7 @@ ****************************************************************************/ #include <QtTest/QtTest> #include <QtQml/QtQml> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> Q_DECLARE_METATYPE(QJsonValue::Type) @@ -55,7 +55,7 @@ class tst_qjsonbinding : public QQmlDataTest { Q_OBJECT public: - tst_qjsonbinding() {} + tst_qjsonbinding() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void cppJsConversion_data(); @@ -77,6 +77,9 @@ private slots: void writeProperty_javascriptExpression_data(); void writeProperty_javascriptExpression(); + void cyclicStringify(); + void recursiveStringify(); + private: QByteArray readAsUtf8(const QString &fileName); static QJsonValue valueFromJson(const QByteArray &json); @@ -514,6 +517,43 @@ void tst_qjsonbinding::writeProperty_javascriptExpression() QCOMPARE(ret.toString(), expectedJson); } +void tst_qjsonbinding::cyclicStringify() +{ + QJSEngine e; + const QString program = QStringLiteral(R"( + var a = {}; + a.a = a; + JSON.stringify(a); + )"); + + QJSValue result = e.evaluate(program); + QVERIFY(result.isError()); + QCOMPARE(result.errorType(), QJSValue::TypeError); + QVERIFY(result.toString().contains(QLatin1String("Cannot convert circular structure to JSON"))); +} + +void tst_qjsonbinding::recursiveStringify() +{ + QJSEngine e; + const QString program = QStringLiteral(R"( + function create() { + var a = {} + Object.defineProperty(a, "a", { + enumerable: true, + get: function() { return create(); } + }); + return a; + } + + JSON.stringify(create()); + )"); + + QJSValue result = e.evaluate(program); + QVERIFY(result.isError()); + QCOMPARE(result.errorType(), QJSValue::RangeError); + QVERIFY(result.toString().contains(QLatin1String("Maximum call stack size exceeded"))); +} + QTEST_MAIN(tst_qjsonbinding) #include "tst_qjsonbinding.moc" diff --git a/tests/auto/qml/qjsvalue/CMakeLists.txt b/tests/auto/qml/qjsvalue/CMakeLists.txt index bb00f3221af..b8ee79713c8 100644 --- a/tests/auto/qml/qjsvalue/CMakeLists.txt +++ b/tests/auto/qml/qjsvalue/CMakeLists.txt @@ -22,7 +22,12 @@ qt_internal_add_test(tst_qjsvalue Qt::Widgets LIBRARIES # special case Threads::Threads # special case + TESTDATA "dummy_imports.qml" ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qjsvalue) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qjsvalue/dummy_imports.qml b/tests/auto/qml/qjsvalue/dummy_imports.qml new file mode 100644 index 00000000000..afe2b33adf4 --- /dev/null +++ b/tests/auto/qml/qjsvalue/dummy_imports.qml @@ -0,0 +1,7 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQml + +QtObject { } diff --git a/tests/auto/qml/qmlbasicapp/BasicExtension/CMakeLists.txt b/tests/auto/qml/qmlbasicapp/BasicExtension/CMakeLists.txt new file mode 100644 index 00000000000..a08c71a294d --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/BasicExtension/CMakeLists.txt @@ -0,0 +1,19 @@ +qt_add_library(additional_qml_module STATIC) +qt_autogen_tools_initial_setup(additional_qml_module) + +qt_add_plugin(additional_qml_module_plugin STATIC PLUGIN_TYPE qml_plugin CLASS_NAME BasicExtension) +qt_autogen_tools_initial_setup(additional_qml_module_plugin) + +qt6_add_qml_module(additional_qml_module + PLUGIN_TARGET additional_qml_module_plugin + CLASS_NAME "BasicExtension" + VERSION 1.0 + URI "BasicExtension" + QML_FILES + Extension.qml + More.ui.qml + Less.js + ESModule.mjs + lowerCase.js + lowerCaseModule.mjs +) diff --git a/tests/auto/qml/qmlbasicapp/BasicExtension/ESModule.mjs b/tests/auto/qml/qmlbasicapp/BasicExtension/ESModule.mjs new file mode 100644 index 00000000000..e1424dc5010 --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/BasicExtension/ESModule.mjs @@ -0,0 +1 @@ +export function eee() { return "eee" } diff --git a/tests/auto/qml/qmlbasicapp/BasicExtension/Extension.qml b/tests/auto/qml/qmlbasicapp/BasicExtension/Extension.qml new file mode 100644 index 00000000000..3052615aef0 --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/BasicExtension/Extension.qml @@ -0,0 +1,3 @@ +import QtQuick + +Item {} diff --git a/tests/auto/qml/qmlbasicapp/BasicExtension/Less.js b/tests/auto/qml/qmlbasicapp/BasicExtension/Less.js new file mode 100644 index 00000000000..a808d7be27c --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/BasicExtension/Less.js @@ -0,0 +1 @@ +function bar() { return "bar" } diff --git a/tests/auto/qml/qmlbasicapp/BasicExtension/More.ui.qml b/tests/auto/qml/qmlbasicapp/BasicExtension/More.ui.qml new file mode 100644 index 00000000000..014d7942291 --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/BasicExtension/More.ui.qml @@ -0,0 +1,3 @@ +import QtQml + +QtObject { objectName: "ui.qml" } diff --git a/tests/auto/qml/qmlbasicapp/BasicExtension/lowerCase.js b/tests/auto/qml/qmlbasicapp/BasicExtension/lowerCase.js new file mode 100644 index 00000000000..9d90c9c6f11 --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/BasicExtension/lowerCase.js @@ -0,0 +1 @@ +function a() { return "a" } diff --git a/tests/auto/qml/qmlbasicapp/BasicExtension/lowerCaseModule.mjs b/tests/auto/qml/qmlbasicapp/BasicExtension/lowerCaseModule.mjs new file mode 100644 index 00000000000..f35813109ce --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/BasicExtension/lowerCaseModule.mjs @@ -0,0 +1 @@ +export function fff() { return "fff" } diff --git a/tests/auto/qml/qmlbasicapp/CMakeLists.txt b/tests/auto/qml/qmlbasicapp/CMakeLists.txt new file mode 100644 index 00000000000..269cc35980f --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/CMakeLists.txt @@ -0,0 +1,30 @@ +qt_internal_add_test(tst_qmlbasicapp + SOURCES + tst_qmlbasicapp.cpp + LIBRARIES + Qt::Core + Qt::Qml +) + +qt6_add_qml_module(tst_qmlbasicapp + VERSION 1.0 + URI "BasicApp" + QML_FILES + main.qml +) + +add_subdirectory(BasicExtension) +add_subdirectory(TimeExample) + +if(QT6_IS_SHARED_LIBS_BUILD) + # Plugins are static, but qt6_import_qml_plugins() can't be used because + # it does nothing for shared builds. Import and link the plugins manually. + target_sources(tst_qmlbasicapp PRIVATE manual_imports.cpp) + target_link_libraries(tst_qmlbasicapp PRIVATE + additional_qml_module_plugin + qmlqtimeexampleplugin + ) +else() + # For fully static builds, let qmlimportscanner take care of everything + qt6_import_qml_plugins(tst_qmlbasicapp) +endif() diff --git a/tests/auto/qml/qmlbasicapp/TimeExample/CMakeLists.txt b/tests/auto/qml/qmlbasicapp/TimeExample/CMakeLists.txt new file mode 100644 index 00000000000..91bc6dc89e5 --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/TimeExample/CMakeLists.txt @@ -0,0 +1,18 @@ +qt6_add_library(qmlqtimeexample STATIC) +qt_autogen_tools_initial_setup(qmlqtimeexample) +qt6_add_qml_module(qmlqtimeexample + VERSION 1.0 + URI "TimeExample" + SOURCES + timemodel.cpp timemodel.h + QML_FILES + Clock.qml + RESOURCES + center.png + clock.png + hour.png + minute.png + DEPENDENCIES + QtQml +) +qt_autogen_tools_initial_setup(qmlqtimeexampleplugin) diff --git a/tests/auto/qml/qmlbasicapp/TimeExample/Clock.qml b/tests/auto/qml/qmlbasicapp/TimeExample/Clock.qml new file mode 100644 index 00000000000..3ee53b9c0bb --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/TimeExample/Clock.qml @@ -0,0 +1,6 @@ +import QtQml + +QtObject { + property int hours: -1 + property int minutes: -1 +} diff --git a/tests/auto/qml/qmlbasicapp/TimeExample/center.png b/tests/auto/qml/qmlbasicapp/TimeExample/center.png new file mode 100644 index 00000000000..7fbd802a44e Binary files /dev/null and b/tests/auto/qml/qmlbasicapp/TimeExample/center.png differ diff --git a/tests/auto/qml/qmlbasicapp/TimeExample/clock.png b/tests/auto/qml/qmlbasicapp/TimeExample/clock.png new file mode 100644 index 00000000000..462edacc0ea Binary files /dev/null and b/tests/auto/qml/qmlbasicapp/TimeExample/clock.png differ diff --git a/tests/auto/qml/qmlbasicapp/TimeExample/hour.png b/tests/auto/qml/qmlbasicapp/TimeExample/hour.png new file mode 100644 index 00000000000..9f33fc5d48f Binary files /dev/null and b/tests/auto/qml/qmlbasicapp/TimeExample/hour.png differ diff --git a/tests/auto/qml/qmlbasicapp/TimeExample/minute.png b/tests/auto/qml/qmlbasicapp/TimeExample/minute.png new file mode 100644 index 00000000000..e2f216c897a Binary files /dev/null and b/tests/auto/qml/qmlbasicapp/TimeExample/minute.png differ diff --git a/tests/auto/qml/qmlbasicapp/TimeExample/timemodel.cpp b/tests/auto/qml/qmlbasicapp/TimeExample/timemodel.cpp new file mode 100644 index 00000000000..e157d9ddd55 --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/TimeExample/timemodel.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "timemodel.h" + +void TimeModel::timerEvent(QTimerEvent *) +{ + const QTime now = QTime::currentTime(); + if (now.second() == 59 + && now.minute() == m_time.value().minute() + && now.hour() == m_time.value().hour()) { + // just missed time tick over, force it, wait extra 0.5 seconds + timer.start(60500, this); + } else { + timer.start(60000 - m_time.value().second() * 1000, this); + } + m_time = now; +} + +TimeModel::TimeModel(QObject *parent) + : QObject(parent) + , m_time(QTime::currentTime()) +{ + m_minute.setBinding([this]() { return m_time.value().minute(); }); + m_hour.setBinding([this]() { return m_time.value().hour(); }); + timer.start(60000 - m_time.value().second() * 1000, this); +} diff --git a/tests/auto/qml/qmlbasicapp/TimeExample/timemodel.h b/tests/auto/qml/qmlbasicapp/TimeExample/timemodel.h new file mode 100644 index 00000000000..75e7d3704cc --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/TimeExample/timemodel.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TIMEMODEL_H +#define TIMEMODEL_H + +#include <QtQml/qqml.h> +#include <QtCore/qdatetime.h> +#include <QtCore/qbasictimer.h> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qproperty.h> + +class TimeModel : public QObject +{ + Q_OBJECT + Q_PROPERTY(int hour READ hour BINDABLE hourBindable FINAL) + Q_PROPERTY(int minute READ minute BINDABLE minuteBindable FINAL) + QML_NAMED_ELEMENT(Time) + +public: + TimeModel(QObject *parent=nullptr); + + int minute() const { return m_minute.value(); } + int hour() const { return m_hour.value(); } + + QBindable<int> hourBindable() { return QBindable<int>(&m_hour); } + QBindable<int> minuteBindable() { return QBindable<int>(&m_minute); } + +private: + void timerEvent(QTimerEvent *) override; + + QProperty<int> m_minute; + QProperty<int> m_hour; + QProperty<QTime> m_time; + QBasicTimer timer; +}; + +#endif // TIMEMODEL_H diff --git a/tests/auto/qml/qmlbasicapp/main.qml b/tests/auto/qml/qmlbasicapp/main.qml new file mode 100644 index 00000000000..a01b56d35d9 --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/main.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import TimeExample // import types from the plugin +import BasicExtension + +Clock { // this class is defined in QML (Clock.qml) + property Time time: Time {} // this class is defined in C++ (plugin.cpp) + + hours: time.hour + minutes: time.minute + property Extension extension // from BasicExtension + property More more: More {} + property string fromESModule: ESModule.eee() + property string fromJSFile: Less.bar() +} diff --git a/tests/auto/qml/qmlbasicapp/manual_imports.cpp b/tests/auto/qml/qmlbasicapp/manual_imports.cpp new file mode 100644 index 00000000000..9e585105d4e --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/manual_imports.cpp @@ -0,0 +1,32 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <QtQml/qqmlextensionplugin.h> + +Q_IMPORT_QML_PLUGIN(TimeExamplePlugin) +Q_IMPORT_QML_PLUGIN(BasicExtension) diff --git a/tests/auto/qml/qmlbasicapp/tst_qmlbasicapp.cpp b/tests/auto/qml/qmlbasicapp/tst_qmlbasicapp.cpp new file mode 100644 index 00000000000..a6c6e4accdc --- /dev/null +++ b/tests/auto/qml/qmlbasicapp/tst_qmlbasicapp.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <QQmlEngine> +#include <QQmlComponent> +#include <QObject> +#include <qtest.h> + +class tst_basicapp : public QObject +{ + Q_OBJECT +private slots: + void loadComponent(); + void resourceFiles(); + void fileSystemFiles(); + void qmldirContents(); +}; + +void tst_basicapp::loadComponent() +{ + QQmlEngine engine; +#ifdef Q_OS_ANDROID + engine.addImportPath(":/"); +#endif + QQmlComponent c(&engine, QStringLiteral("qrc:/BasicApp/main.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer o(c.create()); + QVERIFY(!o.isNull()); + + const QTime time = QTime::currentTime(); + const int hour = o->property("hours").toInt(); + QVERIFY(hour >= time.hour() - 1); + QVERIFY(hour <= time.hour() + 1); + + const int minute = o->property("minutes").toInt(); + QVERIFY(minute >= time.minute() - 1); + QVERIFY(minute <= time.minute() + 1); + + QObject *more = qvariant_cast<QObject*>(o->property("more")); + QVERIFY(more); + QCOMPARE(more->objectName(), QStringLiteral("ui.qml")); + + QCOMPARE(o->property("fromESModule").toString(), QStringLiteral("eee")); + QCOMPARE(o->property("fromJSFile").toString(), QStringLiteral("bar")); +} + +void tst_basicapp::resourceFiles() +{ + QVERIFY(QFile::exists(QStringLiteral(":/BasicApp/main.qml"))); + QVERIFY(QFile::exists(QStringLiteral(":/BasicApp/qmldir"))); + QVERIFY(QFile::exists(QStringLiteral(":/TimeExample/Clock.qml"))); + QVERIFY(QFile::exists(QStringLiteral(":/TimeExample/center.png"))); + QVERIFY(QFile::exists(QStringLiteral(":/TimeExample/clock.png"))); + QVERIFY(QFile::exists(QStringLiteral(":/TimeExample/hour.png"))); + QVERIFY(QFile::exists(QStringLiteral(":/TimeExample/minute.png"))); + QVERIFY(QFile::exists(QStringLiteral(":/TimeExample/qmldir"))); + + QVERIFY(!QFile::exists(QStringLiteral(":/BasicApp/tst_qmlbasicapp.qmltypes"))); + QVERIFY(!QFile::exists(QStringLiteral(":/TimeExample/qmlqtimeexample.qmltypes"))); +} + +void tst_basicapp::fileSystemFiles() +{ +#ifdef Q_OS_ANDROID + QSKIP("This test is not valid for Android, because the files can exist only as resources."); +#endif + const QString basedir = QCoreApplication::applicationDirPath(); + QVERIFY(QFile::exists(basedir + QStringLiteral("/BasicApp/main.qml"))); + QVERIFY(QFile::exists(basedir + QStringLiteral("/BasicApp/qmldir"))); + QVERIFY(QFile::exists(basedir + QStringLiteral("/BasicApp/tst_qmlbasicapp.qmltypes"))); + QVERIFY(QFile::exists(basedir + QStringLiteral("/TimeExample/Clock.qml"))); + + QVERIFY(QFile::exists(basedir + QStringLiteral("/TimeExample/center.png"))); + QVERIFY(QFile::exists(basedir + QStringLiteral("/TimeExample/clock.png"))); + QVERIFY(QFile::exists(basedir + QStringLiteral("/TimeExample/hour.png"))); + QVERIFY(QFile::exists(basedir + QStringLiteral("/TimeExample/minute.png"))); + QVERIFY(QFile::exists(basedir + QStringLiteral("/TimeExample/qmldir"))); + QVERIFY(QFile::exists(basedir + QStringLiteral("/TimeExample/qmlqtimeexample.qmltypes"))); +} + +void tst_basicapp::qmldirContents() +{ +#ifdef Q_OS_ANDROID + const QString basedir = QStringLiteral(":"); // Use qrc resource path on Android +#else + const QString basedir = QCoreApplication::applicationDirPath(); +#endif + { + QFile qmldir(basedir + "/BasicApp/qmldir"); + QVERIFY(qmldir.open(QIODevice::ReadOnly)); + const QByteArray contents = qmldir.readAll(); + QVERIFY(contents.contains("module BasicApp")); + QVERIFY(contents.contains("typeinfo")); + QVERIFY(contents.contains("prefer :/BasicApp/")); + QVERIFY(!contents.contains("classname")); + QVERIFY(!contents.contains("plugin")); + + QFile qmldirInResources(":/BasicApp/qmldir"); + QVERIFY(qmldirInResources.open(QIODevice::ReadOnly)); + QCOMPARE(qmldirInResources.readAll(), contents); + } + + { + QFile qmldir(basedir + "/TimeExample/qmldir"); + QVERIFY(qmldir.open(QIODevice::ReadOnly)); + const QByteArray contents = qmldir.readAll(); + QVERIFY(contents.contains("module TimeExample")); + QVERIFY(contents.contains("optional plugin")); + QVERIFY(contents.contains("classname")); + QVERIFY(contents.contains("typeinfo")); + QVERIFY(contents.contains("depends QtQml")); + QVERIFY(contents.contains("prefer :/TimeExample/")); + QVERIFY(contents.contains("Clock 1.0 Clock.qml")); + + QFile qmldirInResources(":/TimeExample/qmldir"); + QVERIFY(qmldirInResources.open(QIODevice::ReadOnly)); + QCOMPARE(qmldirInResources.readAll(), contents); + } + + { + QFile qmldir(basedir + "/BasicExtension/qmldir"); + QVERIFY(qmldir.open(QIODevice::ReadOnly)); + const QByteArray contents = qmldir.readAll(); + QVERIFY(contents.contains("More 1.0 More.ui.qml")); + QVERIFY(contents.contains("Less.js")); + QVERIFY(contents.contains("ESModule.mjs")); + QVERIFY(!contents.contains("lowerCase.js")); + QVERIFY(!contents.contains("lowerCaseModule.mjs")); + } +} + +QTEST_MAIN(tst_basicapp) +#include "tst_qmlbasicapp.moc" diff --git a/tests/auto/qml/qmlcachegen/CMakeLists.txt b/tests/auto/qml/qmlcachegen/CMakeLists.txt index 4ef6aa8ce11..7f22c14f928 100644 --- a/tests/auto/qml/qmlcachegen/CMakeLists.txt +++ b/tests/auto/qml/qmlcachegen/CMakeLists.txt @@ -12,26 +12,22 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qmlcachegen SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qmlcachegen.cpp - INCLUDE_DIRECTORIES - ../../shared + scriptstringprops.h PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) qt6_add_qml_module(tst_qmlcachegen URI cachegentest VERSION 1.0 - NO_CREATE_PLUGIN_TARGET - NO_GENERATE_PLUGIN_SOURCE ) -# Resources: -set(qmake_workerscripts_test_resource_files +set(qmake_workerscripts_test_qml_files "data/worker.js" "data/worker.qml" ) @@ -39,8 +35,8 @@ set(qmake_workerscripts_test_resource_files qt6_target_qml_sources(tst_qmlcachegen PREFIX "/workerscripts" - FILES - ${qmake_workerscripts_test_resource_files} + QML_FILES + ${qmake_workerscripts_test_qml_files} ) set_source_files_properties("data/trickypaths.qml" PROPERTIES QT_RESOURCE_ALIAS "file name with spaces.qml" @@ -51,7 +47,7 @@ set_source_files_properties("data/versionStyleSuffix-1.2-core-yc.qml" set_source_files_properties("data/versionStyleSuffix-1.2-more.qml" PROPERTIES QT_RESOURCE_ALIAS "versionStyleSuffix-1.2-more.qml" ) -set(trickypaths_resource_files +set(trickypaths_qml_files "data/trickypaths.qml" "data/versionStyleSuffix-1.2-core-yc.qml" "data/versionStyleSuffix-1.2-more.qml" @@ -60,39 +56,39 @@ set(trickypaths_resource_files qt6_target_qml_sources(tst_qmlcachegen PREFIX "/directory with spaces" - FILES - ${trickypaths_resource_files} + QML_FILES + ${trickypaths_qml_files} ) set_source_files_properties("data/Retain.qml" PROPERTIES QT_RESOURCE_ALIAS "Retain.qml" ) -set(retain_resource_files +set(retain_qml_files "data/Retain.qml" ) qt6_target_qml_sources(tst_qmlcachegen PREFIX "/" - FILES - ${retain_resource_files} + QML_FILES + ${retain_qml_files} ) set_source_files_properties("data/SkipQmlCacheGen.qml" PROPERTIES QT_RESOURCE_ALIAS "Skip.qml" QT_QML_SKIP_CACHEGEN 1 ) -set(skip_resource_files +set(skip_qml_files "data/SkipQmlCacheGen.qml" ) qt6_target_qml_sources(tst_qmlcachegen PREFIX "/not/" - FILES - ${skip_resource_files} + QML_FILES + ${skip_qml_files} ) -set(qmake_immediate_resource_files +set(qmake_immediate_qml_files "data/Enums.qml" "data/componentInItem.qml" "data/jsimport.qml" @@ -104,13 +100,14 @@ set(qmake_immediate_resource_files "data/script.mjs" "data/utils.mjs" "data/versionchecks.qml" + "data/scriptstring.qml" ) qt6_target_qml_sources(tst_qmlcachegen PREFIX "/" - FILES - ${qmake_immediate_resource_files} + QML_FILES + ${qmake_immediate_qml_files} ) @@ -122,29 +119,29 @@ if(UNIX) set_source_files_properties("data/umlaut.qml" PROPERTIES QT_RESOURCE_ALIAS "Bäh.qml" ) - set(trickypaths_umlaut_resource_files + set(trickypaths_umlaut_qml_files "data/umlaut.qml" ) qt6_target_qml_sources(tst_qmlcachegen PREFIX "/" - FILES - ${trickypaths_umlaut_resource_files} + QML_FILES + ${trickypaths_umlaut_qml_files} ) endif() # Add those files to the resource system so that they get copied to the data # directory in the build directory, which is preferred by qFindTestData # over the one in the source directory where they are always placed. -set(qml_additional_resources +set(qml_additional_qml_files "data/posthocrequired.qml" "data/inlineComponentWithId.qml" ) qt6_target_qml_sources(tst_qmlcachegen PREFIX "/" - FILES ${qml_additional_resources} + QML_FILES ${qml_additional_qml_files} ) qt_internal_extend_target(tst_qmlcachegen CONDITION ANDROID OR IOS @@ -156,3 +153,8 @@ qt_internal_extend_target(tst_qmlcachegen CONDITION NOT ANDROID AND NOT IOS DEFINES QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" ) + +qt_internal_extend_target(tst_qmlcachegen CONDITION CMAKE_CROSSCOMPILING + DEFINES + QTEST_CROSS_COMPILED +) diff --git a/tests/auto/qml/qmlcachegen/data/scriptstring.qml b/tests/auto/qml/qmlcachegen/data/scriptstring.qml new file mode 100644 index 00000000000..64c73ccdbc2 --- /dev/null +++ b/tests/auto/qml/qmlcachegen/data/scriptstring.qml @@ -0,0 +1,9 @@ +import cachegentest + +ScriptStringProps { + undef: undefined + nul: null + str: "hello" + num: 42 + bol: true +} diff --git a/tests/auto/qml/qmlcachegen/data/truncateTest.qml b/tests/auto/qml/qmlcachegen/data/truncateTest.qml new file mode 100644 index 00000000000..fee768cf775 --- /dev/null +++ b/tests/auto/qml/qmlcachegen/data/truncateTest.qml @@ -0,0 +1,764 @@ +import QtQuick 2.15 +import QtQuick.Layouts 2.15 + +Item { + width: 400 + height: 400 + + component Button : Item { + property string text + property Item background + } + + ColumnLayout { + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + Button { + text: "A Special Button" + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: "red" + border.color: "#26282a" + border.width: 1 + radius: 4 + } + } + + } +} diff --git a/tests/auto/qml/qmlcachegen/scriptstringprops.h b/tests/auto/qml/qmlcachegen/scriptstringprops.h new file mode 100644 index 00000000000..e471da92b5b --- /dev/null +++ b/tests/auto/qml/qmlcachegen/scriptstringprops.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 SCRIPT_STRING_PROPS_H +#define SCRIPT_STRING_PROPS_H + +#include <QObject> +#include <QQmlScriptString> +#include <qqml.h> + +class ScriptStringProps :public QObject +{ + Q_OBJECT + QML_ELEMENT + + Q_PROPERTY(QQmlScriptString undef READ undef WRITE setUndef NOTIFY undefChanged) + Q_PROPERTY(QQmlScriptString nul READ nul WRITE setNul NOTIFY nulChanged) + Q_PROPERTY(QQmlScriptString str READ str WRITE setStr NOTIFY strChanged) + Q_PROPERTY(QQmlScriptString num READ num WRITE setNum NOTIFY numChanged) + Q_PROPERTY(QQmlScriptString bol READ bol WRITE setBol NOTIFY bolChanged) + +public: + const QQmlScriptString &undef() const; + void setUndef(const QQmlScriptString &newUndef); + + const QQmlScriptString &nul() const; + void setNul(const QQmlScriptString &newNul); + + const QQmlScriptString &str() const; + void setStr(const QQmlScriptString &newStr); + + const QQmlScriptString &num() const; + void setNum(const QQmlScriptString &newNum); + + const QQmlScriptString &bol() const; + void setBol(const QQmlScriptString &newBol); +signals: + void undefChanged(); + + void nulChanged(); + + void strChanged(); + + void numChanged(); + + void bolChanged(); + +public: + QQmlScriptString m_undef; + QQmlScriptString m_nul; + QQmlScriptString m_str; + QQmlScriptString m_num; + QQmlScriptString m_bol; +}; + +#endif diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp index 8fdfecb379e..f235bbe557f 100644 --- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp +++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp @@ -37,14 +37,21 @@ #include <QLoggingCategory> #include <private/qqmlcomponent_p.h> #include <private/qqmlscriptdata_p.h> +#include <private/qv4compileddata_p.h> #include <qtranslator.h> +#include <qqmlscriptstring.h> +#include <QString> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include "scriptstringprops.h" class tst_qmlcachegen: public QQmlDataTest { Q_OBJECT +public: + tst_qmlcachegen(); + private slots: void initTestCase() override; @@ -78,6 +85,11 @@ private slots: void parameterAdjustment(); void inlineComponent(); void posthocRequired(); + + void gracefullyHandleTruncatedCacheFile(); + + void scriptStringCachegenInteraction(); + void saveableUnitPointer(); }; // A wrapper around QQmlComponent to ensure the temporary reference counts @@ -104,6 +116,10 @@ class CleanlyLoadingComponent : public QQmlComponent static bool generateCache(const QString &qmlFileName, QByteArray *capturedStderr = nullptr) { +#if defined(QTEST_CROSS_COMPILED) + QTest::qFail("You cannot call qmlcachegen on the target.", __FILE__, __LINE__); + return false; +#endif QProcess proc; if (capturedStderr == nullptr) proc.setProcessChannelMode(QProcess::ForwardedChannels); @@ -122,6 +138,11 @@ static bool generateCache(const QString &qmlFileName, QByteArray *capturedStderr return proc.exitCode() == 0; } +tst_qmlcachegen::tst_qmlcachegen() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qmlcachegen::initTestCase() { qputenv("QML_FORCE_DISK_CACHE", "1"); @@ -137,6 +158,10 @@ void tst_qmlcachegen::initTestCase() void tst_qmlcachegen::loadGeneratedFile() { +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + QTemporaryDir tempDir; QVERIFY(tempDir.isValid()); @@ -199,6 +224,10 @@ class QTestTranslator : public QTranslator void tst_qmlcachegen::translationExpressionSupport() { +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + QTemporaryDir tempDir; QVERIFY(tempDir.isValid()); @@ -244,6 +273,10 @@ void tst_qmlcachegen::translationExpressionSupport() void tst_qmlcachegen::signalHandlerParameters() { +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + QTemporaryDir tempDir; QVERIFY(tempDir.isValid()); @@ -307,6 +340,10 @@ void tst_qmlcachegen::signalHandlerParameters() void tst_qmlcachegen::errorOnArgumentsInSignalHandler() { +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + QTemporaryDir tempDir; QVERIFY(tempDir.isValid()); @@ -332,6 +369,10 @@ void tst_qmlcachegen::errorOnArgumentsInSignalHandler() void tst_qmlcachegen::aheadOfTimeCompilation() { +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + QTemporaryDir tempDir; QVERIFY(tempDir.isValid()); @@ -372,21 +413,33 @@ void tst_qmlcachegen::versionChecksForAheadOfTimeUnits() Q_ASSERT(!temporaryModifiedCachedUnit); QQmlMetaType::CachedUnitLookupError error = QQmlMetaType::CachedUnitLookupError::NoError; + QLoggingCategory::setFilterRules("qt.qml.diskcache.debug=true"); const QQmlPrivate::CachedQmlUnit *originalUnit = QQmlMetaType::findCachedCompilationUnit( QUrl("qrc:/data/versionchecks.qml"), &error); + QLoggingCategory::setFilterRules(QString()); QVERIFY(originalUnit); QV4::CompiledData::Unit *tweakedUnit = (QV4::CompiledData::Unit *)malloc(originalUnit->qmlData->unitSize); memcpy(reinterpret_cast<void *>(tweakedUnit), reinterpret_cast<const void *>(originalUnit->qmlData), originalUnit->qmlData->unitSize); tweakedUnit->version = QV4_DATA_STRUCTURE_VERSION - 1; - temporaryModifiedCachedUnit = new QQmlPrivate::CachedQmlUnit{tweakedUnit, nullptr, nullptr}; - auto testHandler = [](const QUrl &url) -> const QQmlPrivate::CachedQmlUnit * { + const auto testHandler = [](const QUrl &url) -> const QQmlPrivate::CachedQmlUnit * { if (url == QUrl("qrc:/data/versionchecks.qml")) return temporaryModifiedCachedUnit; return nullptr; }; + + const auto dropModifiedUnit = qScopeGuard([&testHandler]() { + Q_ASSERT(temporaryModifiedCachedUnit); + free(const_cast<QV4::CompiledData::Unit *>(temporaryModifiedCachedUnit->qmlData)); + delete temporaryModifiedCachedUnit; + temporaryModifiedCachedUnit = nullptr; + + QQmlMetaType::removeCachedUnitLookupFunction(testHandler); + }); + + temporaryModifiedCachedUnit = new QQmlPrivate::CachedQmlUnit{tweakedUnit, nullptr, nullptr}; QQmlMetaType::prependCachedUnitLookupFunction(testHandler); { @@ -400,13 +453,6 @@ void tst_qmlcachegen::versionChecksForAheadOfTimeUnits() CleanlyLoadingComponent component(&engine, QUrl("qrc:/data/versionchecks.qml")); QCOMPARE(component.status(), QQmlComponent::Ready); } - - Q_ASSERT(temporaryModifiedCachedUnit); - free(const_cast<QV4::CompiledData::Unit *>(temporaryModifiedCachedUnit->qmlData)); - delete temporaryModifiedCachedUnit; - temporaryModifiedCachedUnit = nullptr; - - QQmlMetaType::removeCachedUnitLookupFunction(testHandler); } void tst_qmlcachegen::retainedResources() @@ -444,6 +490,10 @@ void tst_qmlcachegen::workerScripts() void tst_qmlcachegen::functionExpressions() { +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + QTemporaryDir tempDir; QVERIFY(tempDir.isValid()); @@ -541,6 +591,10 @@ void tst_qmlcachegen::qrcScriptImport() void tst_qmlcachegen::fsScriptImport() { +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + QTemporaryDir tempDir; QVERIFY(tempDir.isValid()); @@ -666,6 +720,10 @@ void tst_qmlcachegen::reproducibleCache_data() void tst_qmlcachegen::reproducibleCache() { +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + QFETCH(QString, filePath); QFile file(filePath); @@ -697,6 +755,10 @@ void tst_qmlcachegen::parameterAdjustment() void tst_qmlcachegen::inlineComponent() { +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + QByteArray errors; bool ok = generateCache(testFile("inlineComponentWithId.qml"), &errors); QVERIFY2(ok, errors); @@ -709,6 +771,10 @@ void tst_qmlcachegen::inlineComponent() void tst_qmlcachegen::posthocRequired() { +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + bool ok = generateCache(testFile("posthocrequired.qml")); QVERIFY(ok); QQmlEngine engine; @@ -718,6 +784,142 @@ void tst_qmlcachegen::posthocRequired() QVERIFY(component.errorString().contains(QStringLiteral("Required property x was not initialized"))); } +void tst_qmlcachegen::gracefullyHandleTruncatedCacheFile() +{ +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + + bool ok = generateCache(testFile("truncateTest.qml")); + QVERIFY(ok); + const QString qmlcFile = testFile("truncateTest.qmlc"); + QVERIFY(QFile::exists(qmlcFile)); + QFile::resize(qmlcFile, QFileInfo(qmlcFile).size() / 2); + QQmlEngine engine; + CleanlyLoadingComponent component(&engine, testFileUrl("truncateTest.qml")); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); +} + +void tst_qmlcachegen::scriptStringCachegenInteraction() +{ +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + + bool ok = generateCache(testFile("scriptstring.qml")); + QVERIFY(ok); + QQmlEngine engine; + CleanlyLoadingComponent component(&engine, testFileUrl("scriptstring.qml")); + QScopedPointer<QObject> root(component.create()); + QVERIFY2(!root.isNull(), qPrintable(component.errorString())); + auto scripty = qobject_cast<ScriptStringProps *>(root.get()); + QVERIFY(scripty); + + QVERIFY(scripty->m_undef.isUndefinedLiteral()); + QVERIFY(scripty->m_nul.isNullLiteral()); + QCOMPARE(scripty->m_str.stringLiteral(), u"hello"_qs); + QCOMPARE(scripty->m_num.numberLiteral(&ok), 42); + ok = false; + scripty->m_bol.booleanLiteral(&ok); + QVERIFY(ok); +} + +void tst_qmlcachegen::saveableUnitPointer() +{ + QV4::CompiledData::Unit unit; + unit.flags = QV4::CompiledData::Unit::StaticData | QV4::CompiledData::Unit::IsJavascript; + const auto flags = unit.flags; + + QV4::CompiledData::SaveableUnitPointer pointer(&unit); + + QVERIFY(pointer.saveToDisk<char>([](const char *, quint32) { return true; })); + QCOMPARE(unit.flags, flags); +} + +const QQmlScriptString &ScriptStringProps::undef() const +{ + return m_undef; +} + + + +void ScriptStringProps::setUndef(const QQmlScriptString &newUndef) +{ + if (m_undef == newUndef) + return; + m_undef = newUndef; + emit undefChanged(); +} + + + +const QQmlScriptString &ScriptStringProps::nul() const +{ + return m_nul; +} + + + +void ScriptStringProps::setNul(const QQmlScriptString &newNul) +{ + if (m_nul == newNul) + return; + m_nul = newNul; + emit nulChanged(); +} + + + +const QQmlScriptString &ScriptStringProps::str() const +{ + return m_str; +} + + + +void ScriptStringProps::setStr(const QQmlScriptString &newStr) +{ + if (m_str == newStr) + return; + m_str = newStr; + emit strChanged(); +} + + + +const QQmlScriptString &ScriptStringProps::num() const +{ + return m_num; +} + + + +void ScriptStringProps::setNum(const QQmlScriptString &newNum) +{ + if (m_num == newNum) + return; + m_num = newNum; + emit numChanged(); +} + + + +const QQmlScriptString &ScriptStringProps::bol() const +{ + return m_bol; +} + + + +void ScriptStringProps::setBol(const QQmlScriptString &newBol) +{ + if (m_bol == newBol) + return; + m_bol = newBol; + emit bolChanged(); +} + QTEST_GUILESS_MAIN(tst_qmlcachegen) #include "tst_qmlcachegen.moc" diff --git a/tests/auto/qml/qmlcompiler_manual/CMakeLists.txt b/tests/auto/qml/qmlcompiler_manual/CMakeLists.txt index 0afe49e7606..92ba3fc1228 100644 --- a/tests/auto/qml/qmlcompiler_manual/CMakeLists.txt +++ b/tests/auto/qml/qmlcompiler_manual/CMakeLists.txt @@ -6,24 +6,20 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qmlcompiler_manual SOURCES - ../../shared/util.cpp ../../shared/util.h + testclasses.h tst_qmlcompiler_manual.cpp - INCLUDE_DIRECTORIES - ../../shared LIBRARIES Qt::CorePrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) -## Scopes: -##################################################################### - -qt_add_resources(tst_qmlcompiler_manual "qmlcompiler" - PREFIX - "/" - FILES - "data/signalHandlers.qml" +qt6_add_qml_module(tst_qmlcompiler_manual + VERSION 1.0 + URI "QmltcManualTests" + QML_FILES + ${test_data} ) qt_internal_extend_target(tst_qmlcompiler_manual CONDITION ANDROID OR IOS diff --git a/tests/auto/qml/qmlcompiler_manual/testclasses.h b/tests/auto/qml/qmlcompiler_manual/testclasses.h new file mode 100644 index 00000000000..a56f85460d7 --- /dev/null +++ b/tests/auto/qml/qmlcompiler_manual/testclasses.h @@ -0,0 +1,318 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 TESTCLASSES_H +#define TESTCLASSES_H + +#include <QtCore/qobject.h> +#include <QtCore/qproperty.h> +#include <QtQml/qqmlregistration.h> +#include <QtQml/qqml.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQuick/qquickitem.h> + +#include <private/qqmlrefcount_p.h> +#include <private/qqmlcontextdata_p.h> + +// utility class that sets up QQmlContext for passed QObject. can be used as a +// base class to ensure that qmlEngine(object) is valid during initializer list +// evaluation +struct ContextRegistrator +{ + ContextRegistrator(QQmlEngine *engine, QObject *This); +}; + +class HelloWorld : public QObject, public ContextRegistrator +{ + Q_OBJECT + QML_NAMED_ELEMENT(HelloWorld); + Q_PROPERTY(QString hello READ getHello WRITE setHello BINDABLE bindableHello) + Q_PROPERTY(QString greeting READ getGreeting WRITE setGreeting BINDABLE bindableGreeting) + +public: + // test workaround: the url is resolved by the test base class, so use + // member variable to store the resolved url used as argument in engine + // evaluation of runtime functions + static QUrl url; + + HelloWorld(QQmlEngine *e, QObject *parent = nullptr); + virtual ~HelloWorld() { } + + QString getHello() { return hello.value(); } + QString getGreeting() { return greeting.value(); } + + void setHello(const QString &hello_) { hello.setValue(hello_); } + void setGreeting(const QString &greeting_) { greeting.setValue(greeting_); } + + QBindable<QString> bindableHello() { return QBindable<QString>(&hello); } + QBindable<QString> bindableGreeting() { return QBindable<QString>(&greeting); } + + Q_OBJECT_BINDABLE_PROPERTY(HelloWorld, QString, hello); + Q_OBJECT_BINDABLE_PROPERTY(HelloWorld, QString, greeting); +}; + +class ANON_signalHandlers : public QObject, public ContextRegistrator +{ + Q_OBJECT + QML_ANONYMOUS + Q_PROPERTY(int signal1P READ getSignal1P WRITE setSignal1P BINDABLE bindableSignal1P) + Q_PROPERTY(QString signal2P1 READ getSignal2P1 WRITE setSignal2P1 BINDABLE bindableSignal2P1) + Q_PROPERTY(int signal2P2 READ getSignal2P2 WRITE setSignal2P2 BINDABLE bindableSignal2P2) + Q_PROPERTY(QString signal2P3 READ getSignal2P3 WRITE setSignal2P3 BINDABLE bindableSignal2P3) + +public: + // test workaround: the url is resolved by the test base class, so use + // member variable to store the resolved url used as argument in engine + // evaluation of runtime functions + static QUrl url; + + ANON_signalHandlers(QQmlEngine *e, QObject *parent = nullptr); + + int getSignal1P() { return signal1P.value(); } + QString getSignal2P1() { return signal2P1.value(); } + int getSignal2P2() { return signal2P2.value(); } + QString getSignal2P3() { return signal2P3.value(); } + + void setSignal1P(const int &signal1P_) { signal1P.setValue(signal1P_); } + void setSignal2P1(const QString &signal2P1_) { signal2P1.setValue(signal2P1_); } + void setSignal2P2(const int &signal2P2_) { signal2P2.setValue(signal2P2_); } + void setSignal2P3(const QString &signal2P3_) { signal2P3.setValue(signal2P3_); } + + QBindable<int> bindableSignal1P() { return QBindable<int>(&signal1P); } + QBindable<QString> bindableSignal2P1() { return QBindable<QString>(&signal2P1); } + QBindable<int> bindableSignal2P2() { return QBindable<int>(&signal2P2); } + QBindable<QString> bindableSignal2P3() { return QBindable<QString>(&signal2P3); } + + Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, int, signal1P); + Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, QString, signal2P1); + Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, int, signal2P2); + Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, QString, signal2P3); + +Q_SIGNALS: + void signal1(); + void signal2(QString x, int y); + +public slots: + void onSignal1(); + void onSignal2(QString x, int y); + +public: + void qmlEmitSignal1(); + void qmlEmitSignal2(); + void qmlEmitSignal2WithArgs(QString x, int y); +}; + +class ANON_javaScriptFunctions : public QObject, public ContextRegistrator +{ + Q_OBJECT + QML_ANONYMOUS + Q_PROPERTY(int func1P READ getFunc1P WRITE setFunc1P) + Q_PROPERTY(QString func2P READ getFunc2P WRITE setFunc2P) + Q_PROPERTY(bool func3P READ getFunc3P WRITE setFunc3P) + +public: + // test workaround: the url is resolved by the test base class, so use + // member variable to store the resolved url used as argument in engine + // evaluation of runtime functions + static QUrl url; + + ANON_javaScriptFunctions(QQmlEngine *e, QObject *parent = nullptr); + + int getFunc1P() { return func1P.value(); } + QString getFunc2P() { return func2P.value(); } + bool getFunc3P() { return func3P.value(); } + + void setFunc1P(const int &func1P_) { func1P.setValue(func1P_); } + void setFunc2P(const QString &func2P_) { func2P.setValue(func2P_); } + void setFunc3P(const bool &func3P_) { func3P.setValue(func3P_); } + + // try if just QProperty works + QProperty<int> func1P; + QProperty<QString> func2P; + QProperty<bool> func3P; + + void func1(); + void func2(QString x); + bool func3(); +}; + +class ANON_changingBindings : public QObject, public ContextRegistrator +{ + Q_OBJECT + QML_ANONYMOUS + Q_PROPERTY(int p1 READ getP1 WRITE setP1 BINDABLE bindableP1) + Q_PROPERTY(int p2 READ getP2 WRITE setP2 BINDABLE bindableP2) + +public: + // test workaround: the url is resolved by the test base class, so use + // member variable to store the resolved url used as argument in engine + // evaluation of runtime functions + static QUrl url; + // test util to monitor binding execution + int initialBindingCallCount = 0; + // test util: allows to set C++ binding multiple times + void resetToInitialBinding(); + + ANON_changingBindings(QQmlEngine *e, QObject *parent = nullptr); + + int getP1() { return p1.value(); } + int getP2() { return p2.value(); } + + void setP1(int p1_) { p1.setValue(p1_); } + void setP2(int p2_) { p2.setValue(p2_); } + + QBindable<int> bindableP1() { return QBindable<int>(&p1); } + QBindable<int> bindableP2() { return QBindable<int>(&p2); } + + Q_OBJECT_BINDABLE_PROPERTY(ANON_changingBindings, int, p1); + Q_OBJECT_BINDABLE_PROPERTY(ANON_changingBindings, int, p2); + + void resetToConstant(); + void resetToNewBinding(); +}; + +class ANON_propertyAlias : public QObject, public ContextRegistrator +{ + Q_OBJECT + QML_ANONYMOUS + Q_PROPERTY(int dummy READ getDummy WRITE setDummy NOTIFY dummyChanged) + Q_PROPERTY(int origin READ getOrigin WRITE setOrigin BINDABLE bindableOrigin) + Q_PROPERTY(int aliasToOrigin READ getAliasToOrigin WRITE setAliasToOrigin BINDABLE + bindableAliasToOrigin) + +public: + // test workaround: the url is resolved by the test base class, so use + // member variable to store the resolved url used as argument in engine + // evaluation of runtime functions + static QUrl url; + // test util: allows to set C++ binding multiple times + void resetToInitialBinding(); + + ANON_propertyAlias(QQmlEngine *e, QObject *parent = nullptr); + + int getDummy() { return dummy.value(); } + int getOrigin() { return origin.value(); } + int getAliasToOrigin() { return getOrigin(); } + + void setDummy(int dummy_) + { + dummy.setValue(dummy_); + // emit is essential for Qt.binding() to work correctly + emit dummyChanged(); + } + void setOrigin(int origin_) { origin.setValue(origin_); } + void setAliasToOrigin(int aliasToOrigin_) { setOrigin(aliasToOrigin_); } + + QBindable<int> bindableOrigin() { return QBindable<int>(&origin); } + QBindable<int> bindableAliasToOrigin() { return bindableOrigin(); } + + QProperty<int> dummy; + QProperty<int> origin; + + void resetAliasToConstant(); + void resetOriginToConstant(); + void resetAliasToNewBinding(); + void resetOriginToNewBinding(); + int getAliasValue(); + +Q_SIGNALS: + void dummyChanged(); +}; + +class ANON_propertyChangeHandler : public QObject, public ContextRegistrator +{ + Q_OBJECT + QML_ANONYMOUS + Q_PROPERTY(int dummy READ getDummy WRITE setDummy) + Q_PROPERTY(int p READ getP WRITE setP BINDABLE bindableP) + Q_PROPERTY(int watcher READ getWatcher WRITE setWatcher) + +public: + // test workaround: the url is resolved by the test base class, so use + // member variable to store the resolved url used as argument in engine + // evaluation of runtime functions + static QUrl url; + + ANON_propertyChangeHandler(QQmlEngine *e, QObject *parent = nullptr); + + int getDummy() { return dummy.value(); } + int getP() { return p.value(); } + int getWatcher() { return watcher.value(); } + + void setDummy(int dummy_) { dummy.setValue(dummy_); } + void setP(int p_) { p.setValue(p_); } + void setWatcher(int watcher_) { watcher.setValue(watcher_); } + + QBindable<int> bindableP() { return QBindable<int>(&p); } + + QProperty<int> dummy; + QProperty<int> p; + QProperty<int> watcher; + + // property change handler: + struct ANON_propertyChangeHandler_p_changeHandler + { + ANON_propertyChangeHandler *This = nullptr; + ANON_propertyChangeHandler_p_changeHandler(ANON_propertyChangeHandler *obj); + + void operator()(); + }; + // the handler object has to be alive as long as the object + std::unique_ptr<QPropertyChangeHandler<ANON_propertyChangeHandler_p_changeHandler>> + pChangeHandler; +}; + +class ANON_propertyReturningFunction : public QObject, public ContextRegistrator +{ + Q_OBJECT + QML_ANONYMOUS + Q_PROPERTY(int counter READ getCounter WRITE setCounter) + Q_PROPERTY(QVariant f READ getF WRITE setF BINDABLE bindableF) + +public: + // test workaround: the url is resolved by the test base class, so use + // member variable to store the resolved url used as argument in engine + // evaluation of runtime functions + static QUrl url; + + ANON_propertyReturningFunction(QQmlEngine *e, QObject *parent = nullptr); + + int getCounter() { return counter.value(); } + QVariant getF() { return f.value(); } + + void setCounter(int counter_) { counter.setValue(counter_); } + void setF(QVariant f_) { f.setValue(f_); } + + QBindable<QVariant> bindableF() { return QBindable<QVariant>(&f); } + + QProperty<int> counter; + QProperty<QVariant> f; +}; + +#endif // TESTCLASSES_H diff --git a/tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp b/tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp index db1cd7132ca..a42dc525561 100644 --- a/tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp +++ b/tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp @@ -29,6 +29,8 @@ #include <qtest.h> #include <QDebug> +#include "testclasses.h" + #include <QtCore/qscopedpointer.h> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcomponent.h> @@ -36,7 +38,7 @@ #include <private/qqmlengine_p.h> #include <private/qqmltypedata_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <array> #include <memory> @@ -45,6 +47,9 @@ class tst_qmlcompiler_manual : public QQmlDataTest { Q_OBJECT +public: + tst_qmlcompiler_manual(); + private slots: void cppBinding(); void signalHandlers(); @@ -119,80 +124,53 @@ static void typeEraseArguments(std::array<void *, Size> &a, std::array<QMetaType t = { /* types */ QMetaType::fromType<std::decay_t<IOArgs>>()... }; } -// utility class that sets up QQmlContext for passed QObject. can be used as a -// base class to ensure that qmlEngine(object) is valid during initializer list -// evaluation -struct ContextRegistrator -{ - ContextRegistrator(QQmlEngine *engine, QObject *This) - { - Q_ASSERT(engine && This); - // if This object has a parent, it's not considered to be a root object, - // so it must instead have a dedicated context, but what to do when we - // reparent the root item to e.g. QQuickWindow::contentItem()? - Q_ASSERT(!This->parent() || engine->contextForObject(This->parent()) - || engine->rootContext()); - QQmlContext *context = engine->rootContext(); - if (This->parent()) { - QQmlContext *parentContext = engine->contextForObject(This->parent()); - if (parentContext) - context = new QQmlContext(parentContext, This); - } - Q_ASSERT(context); - // NB: not only sets the context, but also seeds engine into This, so - // that qmlEngine(This) works - engine->setContextForObject(This, context); - Q_ASSERT(qmlEngine(This)); - } -}; +ContextRegistrator::ContextRegistrator(QQmlEngine *engine, QObject *This) +{ + Q_ASSERT(engine && This); + if (engine->contextForObject(This)) // already set + return; + + // use simple form of the logic done in create() and set(). this code + // shouldn't actually be used in real generated classes. it just exists + // here for convenience + Q_ASSERT(!This->parent() || engine->contextForObject(This->parent()) || engine->rootContext()); + QQmlContext *parentContext = engine->contextForObject(This->parent()); + QQmlContext *context = + parentContext ? parentContext : new QQmlContext(engine->rootContext(), This); + Q_ASSERT(context); + // NB: not only sets the context, but also seeds engine into This, so + // that qmlEngine(This) works + engine->setContextForObject(This, context); + Q_ASSERT(qmlEngine(This)); +} -class HelloWorld : public QObject, public ContextRegistrator +HelloWorld::HelloWorld(QQmlEngine *e, QObject *parent) + : QObject(parent), ContextRegistrator(e, this) { - Q_OBJECT - QML_NAMED_ELEMENT(HelloWorld); - Q_PROPERTY(QString hello READ getHello WRITE setHello BINDABLE bindableHello) - Q_PROPERTY(QString greeting READ getGreeting WRITE setGreeting BINDABLE bindableGreeting) + hello = QStringLiteral("Hello, World"); + QPropertyBinding<QString> HelloWorldCpp_greeting_binding( + [&]() { + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::HELLO_WORLD_GREETING_BINDING; + constexpr int argc = 0; + QString ret {}; + std::array<void *, argc + 1> a {}; + std::array<QMetaType, argc + 1> t {}; + typeEraseArguments(a, t, ret); + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); + return ret; + }, + QT_PROPERTY_DEFAULT_BINDING_LOCATION); + bindableGreeting().setBinding(HelloWorldCpp_greeting_binding); +} -public: - // test workaround: the url is resolved by the test base class, so use - // member variable to store the resolved url used as argument in engine - // evaluation of runtime functions - static QUrl url; - - HelloWorld(QQmlEngine *e, QObject *parent = nullptr) - : QObject(parent), ContextRegistrator(e, this) - { - hello = QStringLiteral("Hello, World"); - QPropertyBinding<QString> HelloWorldCpp_greeting_binding( - [&]() { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::HELLO_WORLD_GREETING_BINDING; - constexpr int argc = 0; - QString ret {}; - std::array<void *, argc + 1> a {}; - std::array<QMetaType, argc + 1> t {}; - typeEraseArguments(a, t, ret); - e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); - return ret; - }, - QT_PROPERTY_DEFAULT_BINDING_LOCATION); - bindableGreeting().setBinding(HelloWorldCpp_greeting_binding); - } - - QString getHello() { return hello.value(); } - QString getGreeting() { return greeting.value(); } - - void setHello(const QString &hello_) { hello.setValue(hello_); } - void setGreeting(const QString &greeting_) { greeting.setValue(greeting_); } - - QBindable<QString> bindableHello() { return QBindable<QString>(&hello); } - QBindable<QString> bindableGreeting() { return QBindable<QString>(&greeting); } - - Q_OBJECT_BINDABLE_PROPERTY(HelloWorld, QString, hello); - Q_OBJECT_BINDABLE_PROPERTY(HelloWorld, QString, greeting); -}; QUrl HelloWorld::url = QUrl(); // workaround +tst_qmlcompiler_manual::tst_qmlcompiler_manual() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qmlcompiler_manual::cppBinding() { QQmlEngine e; @@ -210,106 +188,63 @@ void tst_qmlcompiler_manual::cppBinding() QCOMPARE(created.getGreeting(), QStringLiteral("Hello, Qml!")); } -class ANON_signalHandlers : public QObject, public ContextRegistrator +ANON_signalHandlers::ANON_signalHandlers(QQmlEngine *e, QObject *parent) + : QObject(parent), ContextRegistrator(e, this) { - Q_OBJECT - QML_ANONYMOUS - Q_PROPERTY(int signal1P READ getSignal1P WRITE setSignal1P BINDABLE bindableSignal1P) - Q_PROPERTY(QString signal2P1 READ getSignal2P1 WRITE setSignal2P1 BINDABLE bindableSignal2P1) - Q_PROPERTY(int signal2P2 READ getSignal2P2 WRITE setSignal2P2 BINDABLE bindableSignal2P2) - Q_PROPERTY(QString signal2P3 READ getSignal2P3 WRITE setSignal2P3 BINDABLE bindableSignal2P3) + signal1P = 0; + signal2P1 = QStringLiteral(""); + signal2P2 = 0; + signal2P3 = QStringLiteral(""); -public: - // test workaround: the url is resolved by the test base class, so use - // member variable to store the resolved url used as argument in engine - // evaluation of runtime functions - static QUrl url; - - ANON_signalHandlers(QQmlEngine *e, QObject *parent = nullptr) - : QObject(parent), ContextRegistrator(e, this) - { - signal1P = 0; - signal2P1 = QStringLiteral(""); - signal2P2 = 0; - signal2P3 = QStringLiteral(""); - - QObject::connect(this, &ANON_signalHandlers::signal1, this, - &ANON_signalHandlers::onSignal1); - QObject::connect(this, &ANON_signalHandlers::signal2, this, - &ANON_signalHandlers::onSignal2); - } - - int getSignal1P() { return signal1P.value(); } - QString getSignal2P1() { return signal2P1.value(); } - int getSignal2P2() { return signal2P2.value(); } - QString getSignal2P3() { return signal2P3.value(); } - - void setSignal1P(const int &signal1P_) { signal1P.setValue(signal1P_); } - void setSignal2P1(const QString &signal2P1_) { signal2P1.setValue(signal2P1_); } - void setSignal2P2(const int &signal2P2_) { signal2P2.setValue(signal2P2_); } - void setSignal2P3(const QString &signal2P3_) { signal2P3.setValue(signal2P3_); } - - QBindable<int> bindableSignal1P() { return QBindable<int>(&signal1P); } - QBindable<QString> bindableSignal2P1() { return QBindable<QString>(&signal2P1); } - QBindable<int> bindableSignal2P2() { return QBindable<int>(&signal2P2); } - QBindable<QString> bindableSignal2P3() { return QBindable<QString>(&signal2P3); } - - Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, int, signal1P); - Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, QString, signal2P1); - Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, int, signal2P2); - Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, QString, signal2P3); - -signals: - void signal1(); - void signal2(QString x, int y); - -public slots: - void onSignal1() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::SIGNAL_HANDLERS_ON_SIGNAL1; - e->executeRuntimeFunction(url, index, this); - } - - void onSignal2(QString x, int y) - { - constexpr int argc = 2; - std::array<void *, argc+1> a {}; - std::array<QMetaType, argc + 1> t {}; - typeEraseArguments(a, t, nullptr, x, y); - - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const qsizetype index = FunctionIndices::SIGNAL_HANDLERS_ON_SIGNAL2; - e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); - } + QObject::connect(this, &ANON_signalHandlers::signal1, this, &ANON_signalHandlers::onSignal1); + QObject::connect(this, &ANON_signalHandlers::signal2, this, &ANON_signalHandlers::onSignal2); +} + +void ANON_signalHandlers::onSignal1() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::SIGNAL_HANDLERS_ON_SIGNAL1; + e->executeRuntimeFunction(url, index, this); +} + +void ANON_signalHandlers::onSignal2(QString x, int y) +{ + constexpr int argc = 2; + std::array<void *, argc + 1> a {}; + std::array<QMetaType, argc + 1> t {}; + typeEraseArguments(a, t, nullptr, x, y); + + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const qsizetype index = FunctionIndices::SIGNAL_HANDLERS_ON_SIGNAL2; + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); +} + +void ANON_signalHandlers::qmlEmitSignal1() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL1; + e->executeRuntimeFunction(url, index, this); +} + +void ANON_signalHandlers::qmlEmitSignal2() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL2; + e->executeRuntimeFunction(url, index, this); +} + +void ANON_signalHandlers::qmlEmitSignal2WithArgs(QString x, int y) +{ + constexpr int argc = 2; + std::array<void *, argc + 1> a {}; + std::array<QMetaType, argc + 1> t {}; + typeEraseArguments(a, t, nullptr, x, y); + + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL2_WITH_ARGS; + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); +} -public: - void qmlEmitSignal1() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL1; - e->executeRuntimeFunction(url, index, this); - } - - void qmlEmitSignal2() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL2; - e->executeRuntimeFunction(url, index, this); - } - - void qmlEmitSignal2WithArgs(QString x, int y) - { - constexpr int argc = 2; - std::array<void *, argc+1> a {}; - std::array<QMetaType, argc + 1> t {}; - typeEraseArguments(a, t, nullptr, x, y); - - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL2_WITH_ARGS; - e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); - } -}; QUrl ANON_signalHandlers::url = QUrl(); // workaround void tst_qmlcompiler_manual::signalHandlers_impl(const QUrl &url) @@ -361,76 +296,49 @@ void tst_qmlcompiler_manual::signalHandlers() void tst_qmlcompiler_manual::signalHandlers_qmlcachegen() { // use qmlcachegen's compilation unit - signalHandlers_impl(QUrl("qrc:/data/signalHandlers.qml")); + signalHandlers_impl(QUrl("qrc:/QmltcManualTests/data/signalHandlers.qml")); } -class ANON_javaScriptFunctions : public QObject, public ContextRegistrator +ANON_javaScriptFunctions::ANON_javaScriptFunctions(QQmlEngine *e, QObject *parent) + : QObject(parent), ContextRegistrator(e, this) { - Q_OBJECT - QML_ANONYMOUS - Q_PROPERTY(int func1P READ getFunc1P WRITE setFunc1P) - Q_PROPERTY(QString func2P READ getFunc2P WRITE setFunc2P) - Q_PROPERTY(bool func3P READ getFunc3P WRITE setFunc3P) + func1P = 0; + func2P = QStringLiteral(""); + func3P = false; +} + +void ANON_javaScriptFunctions::func1() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::JS_FUNCTIONS_FUNC1; + e->executeRuntimeFunction(url, index, this); +} + +void ANON_javaScriptFunctions::func2(QString x) +{ + constexpr int argc = 1; + std::array<void *, argc + 1> a {}; + std::array<QMetaType, argc + 1> t {}; + typeEraseArguments(a, t, nullptr, x); + + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::JS_FUNCTIONS_FUNC2; + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); +} + +bool ANON_javaScriptFunctions::func3() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::JS_FUNCTIONS_FUNC3; + constexpr int argc = 0; + bool ret {}; + std::array<void *, argc + 1> a {}; + std::array<QMetaType, argc + 1> t {}; + typeEraseArguments(a, t, ret); + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); + return ret; +} -public: - // test workaround: the url is resolved by the test base class, so use - // member variable to store the resolved url used as argument in engine - // evaluation of runtime functions - static QUrl url; - - ANON_javaScriptFunctions(QQmlEngine *e, QObject *parent = nullptr) - : QObject(parent), ContextRegistrator(e, this) - { - func1P = 0; - func2P = QStringLiteral(""); - func3P = false; - } - - int getFunc1P() { return func1P.value(); } - QString getFunc2P() { return func2P.value(); } - bool getFunc3P() { return func3P.value(); } - - void setFunc1P(const int &func1P_) { func1P.setValue(func1P_); } - void setFunc2P(const QString &func2P_) { func2P.setValue(func2P_); } - void setFunc3P(const bool &func3P_) { func3P.setValue(func3P_); } - - // try if just QProperty works - QProperty<int> func1P; - QProperty<QString> func2P; - QProperty<bool> func3P; - - void func1() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::JS_FUNCTIONS_FUNC1; - e->executeRuntimeFunction(url, index, this); - } - - void func2(QString x) - { - constexpr int argc = 1; - std::array<void *, argc+1> a {}; - std::array<QMetaType, argc + 1> t {}; - typeEraseArguments(a, t, nullptr, x); - - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::JS_FUNCTIONS_FUNC2; - e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); - } - - bool func3() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::JS_FUNCTIONS_FUNC3; - constexpr int argc = 0; - bool ret {}; - std::array<void *, argc + 1> a {}; - std::array<QMetaType, argc + 1> t {}; - typeEraseArguments(a, t, ret); - e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); - return ret; - } -}; QUrl ANON_javaScriptFunctions::url = QUrl(); // workaround void tst_qmlcompiler_manual::jsFunctions() @@ -450,74 +358,47 @@ void tst_qmlcompiler_manual::jsFunctions() QCOMPARE(created.func3(), true); } -class ANON_changingBindings : public QObject, public ContextRegistrator +void ANON_changingBindings::resetToInitialBinding() { - Q_OBJECT - QML_ANONYMOUS - Q_PROPERTY(int p1 READ getP1 WRITE setP1 BINDABLE bindableP1) - Q_PROPERTY(int p2 READ getP2 WRITE setP2 BINDABLE bindableP2) + QPropertyBinding<int> ANON_changingBindings_p2_binding( + [&]() { + initialBindingCallCount++; + + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::CHANGING_BINDINGS_P2_BINDING; + constexpr int argc = 0; + int ret {}; + std::array<void *, argc + 1> a {}; + std::array<QMetaType, argc + 1> t {}; + typeEraseArguments(a, t, ret); + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); + return ret; + }, + QT_PROPERTY_DEFAULT_BINDING_LOCATION); + bindableP2().setBinding(ANON_changingBindings_p2_binding); +} + +ANON_changingBindings::ANON_changingBindings(QQmlEngine *e, QObject *parent) + : QObject(parent), ContextRegistrator(e, this) +{ + p1 = 1; + resetToInitialBinding(); +} + +void ANON_changingBindings::resetToConstant() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::CHANGING_BINDINGS_RESET_TO_CONSTANT; + e->executeRuntimeFunction(url, index, this); +} + +void ANON_changingBindings::resetToNewBinding() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::CHANGING_BINDINGS_RESET_TO_NEW_BINDING; + e->executeRuntimeFunction(url, index, this); +} -public: - // test workaround: the url is resolved by the test base class, so use - // member variable to store the resolved url used as argument in engine - // evaluation of runtime functions - static QUrl url; - // test util to monitor binding execution - int initialBindingCallCount = 0; - // test util: allows to set C++ binding multiple times - void resetToInitialBinding() - { - QPropertyBinding<int> ANON_changingBindings_p2_binding( - [&]() { - initialBindingCallCount++; - - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::CHANGING_BINDINGS_P2_BINDING; - constexpr int argc = 0; - int ret {}; - std::array<void *, argc + 1> a {}; - std::array<QMetaType, argc + 1> t {}; - typeEraseArguments(a, t, ret); - e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); - return ret; - }, - QT_PROPERTY_DEFAULT_BINDING_LOCATION); - bindableP2().setBinding(ANON_changingBindings_p2_binding); - } - - ANON_changingBindings(QQmlEngine *e, QObject *parent = nullptr) - : QObject(parent), ContextRegistrator(e, this) - { - p1 = 1; - resetToInitialBinding(); - } - - int getP1() { return p1.value(); } - int getP2() { return p2.value(); } - - void setP1(int p1_) { p1.setValue(p1_); } - void setP2(int p2_) { p2.setValue(p2_); } - - QBindable<int> bindableP1() { return QBindable<int>(&p1); } - QBindable<int> bindableP2() { return QBindable<int>(&p2); } - - Q_OBJECT_BINDABLE_PROPERTY(ANON_changingBindings, int, p1); - Q_OBJECT_BINDABLE_PROPERTY(ANON_changingBindings, int, p2); - - void resetToConstant() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::CHANGING_BINDINGS_RESET_TO_CONSTANT; - e->executeRuntimeFunction(url, index, this); - } - - void resetToNewBinding() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::CHANGING_BINDINGS_RESET_TO_NEW_BINDING; - e->executeRuntimeFunction(url, index, this); - } -}; QUrl ANON_changingBindings::url = QUrl(); // workaround void tst_qmlcompiler_manual::changingBindings() @@ -566,106 +447,69 @@ void tst_qmlcompiler_manual::changingBindings() QCOMPARE(created.initialBindingCallCount, 2); } -class ANON_propertyAlias : public QObject, public ContextRegistrator +void ANON_propertyAlias::resetToInitialBinding() { - Q_OBJECT - QML_ANONYMOUS - Q_PROPERTY(int dummy READ getDummy WRITE setDummy NOTIFY dummyChanged) - Q_PROPERTY(int origin READ getOrigin WRITE setOrigin BINDABLE bindableOrigin) - Q_PROPERTY(int aliasToOrigin READ getAliasToOrigin WRITE setAliasToOrigin BINDABLE - bindableAliasToOrigin) + QPropertyBinding<int> ANON_propertyAlias_origin_binding( + [&]() { + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::PROPERTY_ALIAS_ORIGIN_BINDING; + constexpr int argc = 0; + int ret {}; + std::array<void *, argc + 1> a {}; + std::array<QMetaType, argc + 1> t {}; + typeEraseArguments(a, t, ret); + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); + return ret; + }, + QT_PROPERTY_DEFAULT_BINDING_LOCATION); + bindableOrigin().setBinding(ANON_propertyAlias_origin_binding); +} + +ANON_propertyAlias::ANON_propertyAlias(QQmlEngine *e, QObject *parent) + : QObject(parent), ContextRegistrator(e, this) +{ + dummy = 12; + resetToInitialBinding(); +} + +void ANON_propertyAlias::resetAliasToConstant() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ALIAS_TO_CONSTANT; + e->executeRuntimeFunction(url, index, this); +} +void ANON_propertyAlias::resetOriginToConstant() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ORIGIN_TO_CONSTANT; + e->executeRuntimeFunction(url, index, this); +} +void ANON_propertyAlias::resetAliasToNewBinding() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ALIAS_TO_NEW_BINDING; + e->executeRuntimeFunction(url, index, this); +} +void ANON_propertyAlias::resetOriginToNewBinding() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ORIGIN_TO_NEW_BINDING; + e->executeRuntimeFunction(url, index, this); +} + +int ANON_propertyAlias::getAliasValue() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::PROPERTY_ALIAS_GET_ALIAS_VALUE; + constexpr int argc = 0; + int ret {}; + std::array<void *, argc + 1> a {}; + std::array<QMetaType, argc + 1> t {}; + typeEraseArguments(a, t, ret); + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); + return ret; +} -public: - // test workaround: the url is resolved by the test base class, so use - // member variable to store the resolved url used as argument in engine - // evaluation of runtime functions - static QUrl url; - // test util: allows to set C++ binding multiple times - void resetToInitialBinding() - { - QPropertyBinding<int> ANON_propertyAlias_origin_binding( - [&]() { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::PROPERTY_ALIAS_ORIGIN_BINDING; - constexpr int argc = 0; - int ret {}; - std::array<void *, argc + 1> a {}; - std::array<QMetaType, argc + 1> t {}; - typeEraseArguments(a, t, ret); - e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); - return ret; - }, - QT_PROPERTY_DEFAULT_BINDING_LOCATION); - bindableOrigin().setBinding(ANON_propertyAlias_origin_binding); - } - - ANON_propertyAlias(QQmlEngine *e, QObject *parent = nullptr) - : QObject(parent), ContextRegistrator(e, this) - { - dummy = 12; - resetToInitialBinding(); - } - - int getDummy() { return dummy.value(); } - int getOrigin() { return origin.value(); } - int getAliasToOrigin() { return getOrigin(); } - - void setDummy(int dummy_) - { - dummy.setValue(dummy_); - // emit is essential for Qt.binding() to work correctly - emit dummyChanged(); - } - void setOrigin(int origin_) { origin.setValue(origin_); } - void setAliasToOrigin(int aliasToOrigin_) { setOrigin(aliasToOrigin_); } - - QBindable<int> bindableOrigin() { return QBindable<int>(&origin); } - QBindable<int> bindableAliasToOrigin() { return bindableOrigin(); } - - QProperty<int> dummy; - QProperty<int> origin; - - void resetAliasToConstant() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ALIAS_TO_CONSTANT; - e->executeRuntimeFunction(url, index, this); - } - void resetOriginToConstant() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ORIGIN_TO_CONSTANT; - e->executeRuntimeFunction(url, index, this); - } - void resetAliasToNewBinding() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ALIAS_TO_NEW_BINDING; - e->executeRuntimeFunction(url, index, this); - } - void resetOriginToNewBinding() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ORIGIN_TO_NEW_BINDING; - e->executeRuntimeFunction(url, index, this); - } - - int getAliasValue() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::PROPERTY_ALIAS_GET_ALIAS_VALUE; - constexpr int argc = 0; - int ret {}; - std::array<void *, argc + 1> a {}; - std::array<QMetaType, argc + 1> t {}; - typeEraseArguments(a, t, ret); - e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); - return ret; - } - -signals: - void dummyChanged(); -}; QUrl ANON_propertyAlias::url = QUrl(); // workaround void tst_qmlcompiler_manual::propertyAlias() @@ -729,78 +573,46 @@ void tst_qmlcompiler_manual::propertyAlias() QCOMPARE(created.getAliasToOrigin(), -24); } -class ANON_propertyChangeHandler : public QObject, public ContextRegistrator +ANON_propertyChangeHandler::ANON_propertyChangeHandler(QQmlEngine *e, QObject *parent) + : QObject(parent), ContextRegistrator(e, this) { - Q_OBJECT - QML_ANONYMOUS - Q_PROPERTY(int dummy READ getDummy WRITE setDummy) - Q_PROPERTY(int p READ getP WRITE setP BINDABLE bindableP) - Q_PROPERTY(int watcher READ getWatcher WRITE setWatcher) + dummy = 42; + QPropertyBinding<int> ANON_propertyChangeHandler_p_binding( + [&]() { + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::PROPERTY_CHANGE_HANDLER_P_BINDING; + constexpr int argc = 0; + int ret {}; + std::array<void *, argc + 1> a {}; + std::array<QMetaType, argc + 1> t {}; + typeEraseArguments(a, t, ret); + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); + return ret; + }, + QT_PROPERTY_DEFAULT_BINDING_LOCATION); + bindableP().setBinding(ANON_propertyChangeHandler_p_binding); + watcher = 0; + + // NB: make sure property change handler appears after setBinding(). + // this prevents preliminary binding evaluation (which would fail as + // this object doesn't yet know about qmlEngine(this)) + pChangeHandler.reset(new QPropertyChangeHandler<ANON_propertyChangeHandler_p_changeHandler>( + bindableP().onValueChanged(ANON_propertyChangeHandler_p_changeHandler(this)))); +} + +ANON_propertyChangeHandler::ANON_propertyChangeHandler_p_changeHandler:: + ANON_propertyChangeHandler_p_changeHandler(ANON_propertyChangeHandler *obj) + : This(obj) +{ +} + +void ANON_propertyChangeHandler::ANON_propertyChangeHandler_p_changeHandler::operator()() +{ + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(This)); + const auto index = FunctionIndices::PROPERTY_CHANGE_HANDLER_ON_P_CHANGED; + e->executeRuntimeFunction(This->url, index, This); +} -public: - // test workaround: the url is resolved by the test base class, so use - // member variable to store the resolved url used as argument in engine - // evaluation of runtime functions - static QUrl url; - - ANON_propertyChangeHandler(QQmlEngine *e, QObject *parent = nullptr) - : QObject(parent), ContextRegistrator(e, this) - { - dummy = 42; - QPropertyBinding<int> ANON_propertyChangeHandler_p_binding( - [&]() { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::PROPERTY_CHANGE_HANDLER_P_BINDING; - constexpr int argc = 0; - int ret {}; - std::array<void *, argc + 1> a {}; - std::array<QMetaType, argc + 1> t {}; - typeEraseArguments(a, t, ret); - e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); - return ret; - }, - QT_PROPERTY_DEFAULT_BINDING_LOCATION); - bindableP().setBinding(ANON_propertyChangeHandler_p_binding); - watcher = 0; - - // NB: make sure property change handler appears after setBinding(). - // this prevents preliminary binding evaluation (which would fail as - // this object doesn't yet know about qmlEngine(this)) - pChangeHandler.reset(new QPropertyChangeHandler<ANON_propertyChangeHandler_p_changeHandler>( - bindableP().onValueChanged(ANON_propertyChangeHandler_p_changeHandler(this)))); - } - - int getDummy() { return dummy.value(); } - int getP() { return p.value(); } - int getWatcher() { return watcher.value(); } - - void setDummy(int dummy_) { dummy.setValue(dummy_); } - void setP(int p_) { p.setValue(p_); } - void setWatcher(int watcher_) { watcher.setValue(watcher_); } - - QBindable<int> bindableP() { return QBindable<int>(&p); } - - QProperty<int> dummy; - QProperty<int> p; - QProperty<int> watcher; - - // property change handler: - struct ANON_propertyChangeHandler_p_changeHandler - { - ANON_propertyChangeHandler *This = nullptr; - ANON_propertyChangeHandler_p_changeHandler(ANON_propertyChangeHandler *obj) : This(obj) { } - - void operator()() - { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(This)); - const auto index = FunctionIndices::PROPERTY_CHANGE_HANDLER_ON_P_CHANGED; - e->executeRuntimeFunction(This->url, index, This); - } - }; - // the handler object has to be alive as long as the object - std::unique_ptr<QPropertyChangeHandler<ANON_propertyChangeHandler_p_changeHandler>> - pChangeHandler; -}; QUrl ANON_propertyChangeHandler::url = QUrl(); // workaround void tst_qmlcompiler_manual::propertyChangeHandler() @@ -832,49 +644,25 @@ void tst_qmlcompiler_manual::propertyChangeHandler() QCOMPARE(created.property("watcher").toInt(), 96); } -class ANON_propertyReturningFunction : public QObject, public ContextRegistrator +ANON_propertyReturningFunction::ANON_propertyReturningFunction(QQmlEngine *e, QObject *parent) + : QObject(parent), ContextRegistrator(e, this) { - Q_OBJECT - QML_ANONYMOUS - Q_PROPERTY(int counter READ getCounter WRITE setCounter) - Q_PROPERTY(QVariant f READ getF WRITE setF BINDABLE bindableF) + QPropertyBinding<QVariant> ANON_propertyReturningFunction_f_binding( + [&]() { + QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); + const auto index = FunctionIndices::PROPERTY_RETURNING_FUNCTION_F_BINDING; + constexpr int argc = 0; + QVariant ret {}; + std::array<void *, argc + 1> a {}; + std::array<QMetaType, argc + 1> t {}; + typeEraseArguments(a, t, ret); + e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); + return ret; + }, + QT_PROPERTY_DEFAULT_BINDING_LOCATION); + bindableF().setBinding(ANON_propertyReturningFunction_f_binding); +} -public: - // test workaround: the url is resolved by the test base class, so use - // member variable to store the resolved url used as argument in engine - // evaluation of runtime functions - static QUrl url; - - ANON_propertyReturningFunction(QQmlEngine *e, QObject *parent = nullptr) - : QObject(parent), ContextRegistrator(e, this) - { - QPropertyBinding<QVariant> ANON_propertyReturningFunction_f_binding( - [&]() { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this)); - const auto index = FunctionIndices::PROPERTY_RETURNING_FUNCTION_F_BINDING; - constexpr int argc = 0; - QVariant ret {}; - std::array<void *, argc + 1> a {}; - std::array<QMetaType, argc + 1> t {}; - typeEraseArguments(a, t, ret); - e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data()); - return ret; - }, - QT_PROPERTY_DEFAULT_BINDING_LOCATION); - bindableF().setBinding(ANON_propertyReturningFunction_f_binding); - } - - int getCounter() { return counter.value(); } - QVariant getF() { return f.value(); } - - void setCounter(int counter_) { counter.setValue(counter_); } - void setF(QVariant f_) { f.setValue(f_); } - - QBindable<QVariant> bindableF() { return QBindable<QVariant>(&f); } - - QProperty<int> counter; - QProperty<QVariant> f; -}; QUrl ANON_propertyReturningFunction::url = QUrl(); // workaround void tst_qmlcompiler_manual::propertyReturningFunction() diff --git a/tests/auto/qml/qmldiskcache/dummy_imports.qml b/tests/auto/qml/qmldiskcache/dummy_imports.qml index b9a196e188d..63d33cbea64 100644 --- a/tests/auto/qml/qmldiskcache/dummy_imports.qml +++ b/tests/auto/qml/qmldiskcache/dummy_imports.qml @@ -1,8 +1,7 @@ // This file exists for the sole purpose for qmlimportscanner to find // which modules it needs to extract for deployment. -// Otherwise, it fails to find the imports that are expressed in C++ -// code in tst_parserstress.cpp +// Otherwise, it fails to find the imports that are expressed in C++. -import QtQuick 2.0 +import QtQuick -QtObject { } // This is needed in order to keep importscanner happy +QtObject { } diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp index 593eea3e3a5..d84aaaeba3d 100644 --- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp +++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp @@ -65,6 +65,7 @@ private slots: void cppRegisteredSingletonDependency(); void cacheModuleScripts(); void reuseStaticMappings(); + void invalidateSaveLoadCache(); private: QDir m_qmlCacheDirectory; @@ -346,7 +347,7 @@ void tst_qmldiskcache::regenerateAfterChange() const QV4::CompiledData::Object *obj = qmlUnit->objectAt(0); QCOMPARE(quint32(obj->nBindings), quint32(1)); - QCOMPARE(quint32(obj->bindingTable()->type), quint32(QV4::CompiledData::Binding::Type_Script)); + QCOMPARE(obj->bindingTable()->type(), QV4::CompiledData::Binding::Type_Script); QCOMPARE(quint32(obj->bindingTable()->value.compiledScriptIndex), quint32(0)); QCOMPARE(quint32(testUnit->functionTableSize), quint32(1)); @@ -374,7 +375,7 @@ void tst_qmldiskcache::regenerateAfterChange() const QV4::CompiledData::Object *obj = qmlUnit->objectAt(0); QCOMPARE(quint32(obj->nBindings), quint32(2)); - QCOMPARE(quint32(obj->bindingTable()->type), quint32(QV4::CompiledData::Binding::Type_Number)); + QCOMPARE(obj->bindingTable()->type(), QV4::CompiledData::Binding::Type_Number); const QV4::Value value(testUnit->constants()[obj->bindingTable()->value.constantValueIndex]); QCOMPARE(value.doubleValue(), double(42)); @@ -418,7 +419,7 @@ void tst_qmldiskcache::registerImportForImplicitComponent() const QV4::CompiledData::Object *obj = qmlUnit->objectAt(0); QCOMPARE(quint32(obj->nBindings), quint32(1)); - QCOMPARE(quint32(obj->bindingTable()->type), quint32(QV4::CompiledData::Binding::Type_Object)); + QCOMPARE(obj->bindingTable()->type(), QV4::CompiledData::Binding::Type_Object); const QV4::CompiledData::Object *implicitComponent = qmlUnit->objectAt(obj->bindingTable()->value.objectIndex); QCOMPARE(testUnit->stringAtInternal(implicitComponent->inheritedTypeNameIndex), QStringLiteral("QmlInternals.") + componentType.elementName()); @@ -550,6 +551,7 @@ void tst_qmldiskcache::recompileAfterChange() CleanlyLoadingComponent component(&engine, testCompiler.testFilePath); QScopedPointer<TypeVersion2> obj(qobject_cast<TypeVersion2*>(component.create())); QVERIFY(!obj.isNull()); + qDebug() << obj->property("x"); QVERIFY(QFileInfo(testCompiler.cacheFilePath).lastModified() > initialCacheTimeStamp); } } @@ -1030,6 +1032,112 @@ void tst_qmldiskcache::reuseStaticMappings() QCOMPARE(testCompiler.unitData(), data1); } +class AParent : public QObject +{ + Q_OBJECT + Q_PROPERTY(int x MEMBER x) +public: + AParent(QObject *parent = nullptr) : QObject(parent) {} + int x = 25; +}; + +class BParent : public QObject +{ + Q_OBJECT + + // Insert y before x, to change the property index of x + Q_PROPERTY(int y MEMBER y) + + Q_PROPERTY(int x MEMBER x) +public: + BParent(QObject *parent = nullptr) : QObject(parent) {} + int y = 13; + int x = 25; +}; + +static QString writeTempFile( + const QTemporaryDir &tempDir, const QString &fileName, const char *contents) { + QFile f(tempDir.path() + '/' + fileName); + const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate); + Q_ASSERT(ok); + f.write(contents); + return f.fileName(); +}; + +void tst_qmldiskcache::invalidateSaveLoadCache() +{ + qmlRegisterType<AParent>("Base", 1, 0, "Parent"); + QQmlEngine e; + + // If you store a CU to a .qmlc file at run time, the .qmlc file will contain + // alias entries with the encodedMetaPropertyIndex pre-resolved. That's in + // contrast to .qmlc files generated ahead of time. Exploit that to cause + // a need to recompile the file. + + QTemporaryDir tempDir; + const QString fileName = writeTempFile( + tempDir, QLatin1String("a.qml"), + "import Base\nParent { id: self; property alias z: self.x }"); + const QUrl url = QUrl::fromLocalFile(fileName); + waitForFileSystem(); + + { + QQmlComponent a(&e, url); + QVERIFY2(a.isReady(), qPrintable(a.errorString())); + QScopedPointer<QObject> ao(a.create()); + QVERIFY(!ao.isNull()); + AParent *ap = qobject_cast<AParent *>(ao.data()); + QCOMPARE(ap->property("z").toInt(), ap->x); + } + + QString errorString; + QQmlRefPointer<QV4::ExecutableCompilationUnit> oldUnit + = QV4::ExecutableCompilationUnit::create(); + QVERIFY2(oldUnit->loadFromDisk(url, QFileInfo(fileName).lastModified(), &errorString), qPrintable(errorString)); + + // Produce a checksum mismatch. + e.clearComponentCache(); + qmlClearTypeRegistrations(); + qmlRegisterType<BParent>("Base", 1, 0, "Parent"); + + { + QQmlComponent b(&e, url); + QVERIFY2(b.isReady(), qPrintable(b.errorString())); + QScopedPointer<QObject> bo(b.create()); + QVERIFY(!bo.isNull()); + BParent *bp = qobject_cast<BParent *>(bo.data()); + QCOMPARE(bp->property("z").toInt(), bp->x); + } + + // Make it recompile again. + e.clearComponentCache(); + { + QFile file(fileName); + file.open(QIODevice::WriteOnly | QIODevice::Append); + file.write(" "); + } + waitForFileSystem(); + + { + QQmlComponent b(&e, url); + QVERIFY2(b.isReady(), qPrintable(b.errorString())); + QScopedPointer<QObject> bo(b.create()); + QVERIFY(!bo.isNull()); + BParent *bp = qobject_cast<BParent *>(bo.data()); + QCOMPARE(bp->property("z").toInt(), bp->x); + } + + // Verify that the mapped unit data is actually different now. + // The cache should have been invalidated after all. + // So, now we should be able to load a freshly written CU. + + QQmlRefPointer<QV4::ExecutableCompilationUnit> unit + = QV4::ExecutableCompilationUnit::create(); + QVERIFY2(unit->loadFromDisk(url, QFileInfo(fileName).lastModified(), &errorString), qPrintable(errorString)); + + QVERIFY(unit->unitData() != oldUnit->unitData()); +} + QTEST_MAIN(tst_qmldiskcache) #include "tst_qmldiskcache.moc" diff --git a/tests/auto/qml/qmlformat/CMakeLists.txt b/tests/auto/qml/qmlformat/CMakeLists.txt index 8d5133ccf76..6716a509e12 100644 --- a/tests/auto/qml/qmlformat/CMakeLists.txt +++ b/tests/auto/qml/qmlformat/CMakeLists.txt @@ -12,15 +12,13 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qmlformat SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qmlformat.cpp DEFINES SRCDIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::TestPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qmlformat/data/Annotations.formatted.qml b/tests/auto/qml/qmlformat/data/Annotations.formatted.qml index 2fccb05e6e2..ca58c90ecfd 100644 --- a/tests/auto/qml/qmlformat/data/Annotations.formatted.qml +++ b/tests/auto/qml/qmlformat/data/Annotations.formatted.qml @@ -42,7 +42,6 @@ Item { @Annotate { } anchors.fill: parent - @AnnotateMore { property int x: 5 } @@ -57,7 +56,6 @@ Item { anchors.fill: parent legend.alignment: Qt.AlignBottom antialiasing: true - @ExtraAnnotation { signal pippo } @@ -90,7 +88,6 @@ Item { value: 6.8 } } - @SignalAnnotation { implicit: true } @@ -101,7 +98,6 @@ Item { function foo(x) { return 42; } - @BindingAnn { bType: 1 } @@ -125,7 +121,6 @@ Item { duration: 34 } } - @SuperComplete { binding: late } diff --git a/tests/auto/qml/qmlformat/data/Example1.formatted.2spaces.qml b/tests/auto/qml/qmlformat/data/Example1.formatted.2spaces.qml index 48a1acf4837..8b181f607e1 100644 --- a/tests/auto/qml/qmlformat/data/Example1.formatted.2spaces.qml +++ b/tests/auto/qml/qmlformat/data/Example1.formatted.2spaces.qml @@ -55,7 +55,6 @@ Item { // More orphans property variant some_array_literal: [30, 20, Math["PI"], [4, 3, 2], "foo", 0.3] - property bool something_computed: function (x) { const PI = 3, DAYS_PER_YEAR = 365.25; var x = 3 + 2; @@ -129,6 +128,7 @@ Item { }() default property bool some_default_bool: 500 % 5 !== 0 // some_default_bool + myFavouriteThings: [ // This is an orphan @@ -147,9 +147,7 @@ Item { Text { text: "Bla" - signal boo(int count, int times, real duration) - required property string batman } diff --git a/tests/auto/qml/qmlformat/data/Example1.formatted.qml b/tests/auto/qml/qmlformat/data/Example1.formatted.qml index a679e8a010a..cb8865d94e6 100644 --- a/tests/auto/qml/qmlformat/data/Example1.formatted.qml +++ b/tests/auto/qml/qmlformat/data/Example1.formatted.qml @@ -55,7 +55,6 @@ Item { // More orphans property variant some_array_literal: [30, 20, Math["PI"], [4, 3, 2], "foo", 0.3] - property bool something_computed: function (x) { const PI = 3, DAYS_PER_YEAR = 365.25; var x = 3 + 2; @@ -129,6 +128,7 @@ Item { }() default property bool some_default_bool: 500 % 5 !== 0 // some_default_bool + myFavouriteThings: [ // This is an orphan @@ -147,9 +147,7 @@ Item { Text { text: "Bla" - signal boo(int count, int times, real duration) - required property string batman } diff --git a/tests/auto/qml/qmlformat/data/Example1.formatted.tabs.qml b/tests/auto/qml/qmlformat/data/Example1.formatted.tabs.qml index 34b3467cb45..ef964f6f605 100644 --- a/tests/auto/qml/qmlformat/data/Example1.formatted.tabs.qml +++ b/tests/auto/qml/qmlformat/data/Example1.formatted.tabs.qml @@ -55,7 +55,6 @@ Item { // More orphans property variant some_array_literal: [30, 20, Math["PI"], [4, 3, 2], "foo", 0.3] - property bool something_computed: function (x) { const PI = 3, DAYS_PER_YEAR = 365.25; var x = 3 + 2; @@ -129,6 +128,7 @@ Item { }() default property bool some_default_bool: 500 % 5 !== 0 // some_default_bool + myFavouriteThings: [ // This is an orphan @@ -147,9 +147,7 @@ Item { Text { text: "Bla" - signal boo(int count, int times, real duration) - required property string batman } diff --git a/tests/auto/qml/qmlformat/data/arrowFunctionWithBinding.formatted.qml b/tests/auto/qml/qmlformat/data/arrowFunctionWithBinding.formatted.qml new file mode 100644 index 00000000000..2a47b2f152e --- /dev/null +++ b/tests/auto/qml/qmlformat/data/arrowFunctionWithBinding.formatted.qml @@ -0,0 +1,8 @@ +import QtQuick + +Item { Component.onCompleted: { let f = ([]) => {}; + let g = ([a]) => {}; + let h = ([a, b]) => {}; + let i = ([a, ...b]) => {}; + } +} diff --git a/tests/auto/qml/qmlformat/data/arrowFunctionWithBinding.qml b/tests/auto/qml/qmlformat/data/arrowFunctionWithBinding.qml new file mode 100644 index 00000000000..2a47b2f152e --- /dev/null +++ b/tests/auto/qml/qmlformat/data/arrowFunctionWithBinding.qml @@ -0,0 +1,8 @@ +import QtQuick + +Item { Component.onCompleted: { let f = ([]) => {}; + let g = ([a]) => {}; + let h = ([a, b]) => {}; + let i = ([a, ...b]) => {}; + } +} diff --git a/tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.formatted.qml b/tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.formatted.qml new file mode 100644 index 00000000000..edbb12c6e63 --- /dev/null +++ b/tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.formatted.qml @@ -0,0 +1,37 @@ +import QtQuick + +Item { + + function f() { + var count = 0; + class Person { + constructor(name){ + this._name = name; + } + } + class Employee extends Person { + constructor(name, age){ + super(name); + this._name = name; + this._age = age; + ++count; + } + + doWork(){} + + /* do we get the comment? */ get name(){ + return this._name.toUpperCase(); + } + + set name(newName){ + if (newName) { + this._name = newName; + } + } + + static get count(){ + return count; + } + } + } +} diff --git a/tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.qml b/tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.qml new file mode 100644 index 00000000000..268859d3cc5 --- /dev/null +++ b/tests/auto/qml/qmlformat/data/ecmaScriptClassInQml.qml @@ -0,0 +1,45 @@ +import QtQuick + +Item { + +function f() { + +var count = 0; + +class Person { + constructor(name) { + this._name = name + } +} + +class Employee extends Person{ + + + constructor(name, age) { + super(name); + this._name = name; + this._age = age; + ++count; + } + + doWork() { + + } + + get /* do we get the comment? */ name() { + return this._name.toUpperCase(); + } + + set name(newName){ + if(newName){ + this._name = newName; + } + } + + static get count() { return count;} +} + + +} + +} \ No newline at end of file diff --git a/tests/auto/qml/qmlformat/data/forWithLet.formatted.qml b/tests/auto/qml/qmlformat/data/forWithLet.formatted.qml new file mode 100644 index 00000000000..5fecc1d1804 --- /dev/null +++ b/tests/auto/qml/qmlformat/data/forWithLet.formatted.qml @@ -0,0 +1,8 @@ +import QtQml + +QtObject { + function foo() { + for (let i = 0; i < 5; ++i) + console.log(i); + } +} diff --git a/tests/auto/qml/qmlformat/data/forWithLet.qml b/tests/auto/qml/qmlformat/data/forWithLet.qml new file mode 100644 index 00000000000..afed76ebcee --- /dev/null +++ b/tests/auto/qml/qmlformat/data/forWithLet.qml @@ -0,0 +1,8 @@ +import QtQml + +QtObject { +function foo() { +for (let i = 0; i < 5; ++i) +console.log(i); +} +} diff --git a/tests/auto/qml/qmlformat/data/largeBindings.formatted.qml b/tests/auto/qml/qmlformat/data/largeBindings.formatted.qml index 70283dade66..879bf297b22 100644 --- a/tests/auto/qml/qmlformat/data/largeBindings.formatted.qml +++ b/tests/auto/qml/qmlformat/data/largeBindings.formatted.qml @@ -7,6 +7,7 @@ QtObject { var x = 300; console.log(x); } + small1: 3 small2: foo smallButNeedsBraces: if (foo) { diff --git a/tests/auto/qml/qmlformat/data/nestedFunctions.formatted.qml b/tests/auto/qml/qmlformat/data/nestedFunctions.formatted.qml index 522e844201b..5536ecf513b 100644 --- a/tests/auto/qml/qmlformat/data/nestedFunctions.formatted.qml +++ b/tests/auto/qml/qmlformat/data/nestedFunctions.formatted.qml @@ -3,6 +3,7 @@ Item { function nested() {} foo(); } + function b() { function nested() {} bar(); diff --git a/tests/auto/qml/qmlformat/data/readOnlyProps.formatted.qml b/tests/auto/qml/qmlformat/data/readOnlyProps.formatted.qml index 3084ab79513..354f2ba9794 100644 --- a/tests/auto/qml/qmlformat/data/readOnlyProps.formatted.qml +++ b/tests/auto/qml/qmlformat/data/readOnlyProps.formatted.qml @@ -6,7 +6,6 @@ QtObject { id: test signal foo } - // End comment // Testing UiArrayBinding diff --git a/tests/auto/qml/qmlformat/data/statesAndTransitions.formatted.qml b/tests/auto/qml/qmlformat/data/statesAndTransitions.formatted.qml index f72e9d81959..40cf5068da5 100644 --- a/tests/auto/qml/qmlformat/data/statesAndTransitions.formatted.qml +++ b/tests/auto/qml/qmlformat/data/statesAndTransitions.formatted.qml @@ -1,5 +1,6 @@ QtObject { id: foo + states: [ State { } diff --git a/tests/auto/qml/qmlformat/data/verbatimString.formatted.qml b/tests/auto/qml/qmlformat/data/verbatimString.formatted.qml index 65539b538af..84abe38f88e 100644 --- a/tests/auto/qml/qmlformat/data/verbatimString.formatted.qml +++ b/tests/auto/qml/qmlformat/data/verbatimString.formatted.qml @@ -1,8 +1,6 @@ Item { property string verbatim1: 'A "verbatim" string!' - property string verbatim2: "A 'verbatim' string\u2757" - property string verbatim3: `400 + 300 is ${400 + 300}. mutliline` diff --git a/tests/auto/qml/qmlformat/tst_qmlformat.cpp b/tests/auto/qml/qmlformat/tst_qmlformat.cpp index f9cf4deafba..29a14900d2d 100644 --- a/tests/auto/qml/qmlformat/tst_qmlformat.cpp +++ b/tests/auto/qml/qmlformat/tst_qmlformat.cpp @@ -33,13 +33,15 @@ #include <QString> #include <QTemporaryDir> #include <QtTest/private/qemulationdetector_p.h> - -#include <util.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> class TestQmlformat: public QQmlDataTest { Q_OBJECT +public: + TestQmlformat(); + private Q_SLOTS: void initTestCase() override; @@ -52,6 +54,8 @@ private Q_SLOTS: void testExample_data(); #endif + void testBackupFileLimit(); + private: QString readTestFile(const QString &path); QString runQmlformat(const QString &fileToFormat, QStringList args, bool shouldSucceed = true); @@ -64,6 +68,11 @@ private Q_SLOTS: bool isInvalidFile(const QFileInfo &fileName) const; }; +TestQmlformat::TestQmlformat() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void TestQmlformat::initTestCase() { QQmlDataTest::initTestCase(); @@ -245,6 +254,14 @@ void TestQmlformat::testFormat_data() << "emptyObject.formatted.qml" << QStringList {}; QTest::newRow("arrow functions") << "arrowFunctions.qml" << "arrowFunctions.formatted.qml" << QStringList {}; + QTest::newRow("ecmaScriptClassInQml") + << "ecmaScriptClassInQml.qml" + << "ecmaScriptClassInQml.formatted.qml" << QStringList {}; + QTest::newRow("arrowFunctionWithBinding") + << "arrowFunctionWithBinding.qml" + << "arrowFunctionWithBinding.formatted.qml" << QStringList{}; + QTest::newRow("forWithLet") << "forWithLet.qml" + << "forWithLet.formatted.qml" << QStringList {}; } void TestQmlformat::testFormat() @@ -287,6 +304,29 @@ void TestQmlformat::testExample() } #endif +void TestQmlformat::testBackupFileLimit() +{ + // Create a temporary directory + QTemporaryDir tempDir; + + // Unformatted file to format + const QString fileToFormat{ testFile("Annotations.qml") }; + + { + const QString tempFile = tempDir.path() + QDir::separator() + "test_0.qml"; + const QString backupFile = tempFile + QStringLiteral("~"); + QFile::copy(fileToFormat, tempFile); + + QProcess process; + process.start(m_qmlformatPath, QStringList{ "--verbose", "--inplace", tempFile }); + QVERIFY(process.waitForFinished()); + QCOMPARE(process.exitStatus(), QProcess::NormalExit); + QCOMPARE(process.exitCode(), 0); + QVERIFY(QFileInfo::exists(tempFile)); + QVERIFY(!QFileInfo::exists(backupFile)); + }; +} + QString TestQmlformat::runQmlformat(const QString &fileToFormat, QStringList args, bool shouldSucceed) { diff --git a/tests/auto/qml/qmlimportscanner/CMakeLists.txt b/tests/auto/qml/qmlimportscanner/CMakeLists.txt index ec69f00516f..74399102945 100644 --- a/tests/auto/qml/qmlimportscanner/CMakeLists.txt +++ b/tests/auto/qml/qmlimportscanner/CMakeLists.txt @@ -12,12 +12,10 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qmlimportscanner SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qmlimportscanner.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -35,8 +33,9 @@ qt_internal_extend_target(tst_qmlimportscanner CONDITION NOT ANDROID AND NOT IOS ) # special case begin +string(TOLOWER "${QT_LIBINFIX}" infix_lowercase) qt_internal_extend_target(tst_qmlimportscanner CONDITION DEFINED QT_LIBINFIX DEFINES - LIBINFIX=${QT_LIBINFIX} + LIBINFIX=${infix_lowercase} ) # special case end diff --git a/tests/auto/qml/qmlimportscanner/data/CompositeSingleton.json b/tests/auto/qml/qmlimportscanner/data/CompositeSingleton.json index f8ac3438f9a..51b1033a9c2 100644 --- a/tests/auto/qml/qmlimportscanner/data/CompositeSingleton.json +++ b/tests/auto/qml/qmlimportscanner/data/CompositeSingleton.json @@ -6,6 +6,7 @@ }, { "classname": "QtQuick2Plugin", + "linkTarget": "Qt6::qtquick2plugin", "name": "QtQuick", "plugin": "qtquick2plugin", "pluginIsOptional": true, @@ -14,6 +15,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -22,6 +24,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -30,6 +33,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/CompositeWithEnum.json b/tests/auto/qml/qmlimportscanner/data/CompositeWithEnum.json index 92d6797becd..e0c37d24c4c 100644 --- a/tests/auto/qml/qmlimportscanner/data/CompositeWithEnum.json +++ b/tests/auto/qml/qmlimportscanner/data/CompositeWithEnum.json @@ -6,6 +6,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -14,6 +15,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -22,6 +24,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/CompositeWithinSingleton.json b/tests/auto/qml/qmlimportscanner/data/CompositeWithinSingleton.json index ceed744ea49..e4135c559c8 100644 --- a/tests/auto/qml/qmlimportscanner/data/CompositeWithinSingleton.json +++ b/tests/auto/qml/qmlimportscanner/data/CompositeWithinSingleton.json @@ -6,6 +6,7 @@ }, { "classname": "QtQuick2Plugin", + "linkTarget": "Qt6::qtquick2plugin", "name": "QtQuick", "plugin": "qtquick2plugin", "pluginIsOptional": true, @@ -14,6 +15,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -22,6 +24,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -30,6 +33,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/Drawer.qml.json b/tests/auto/qml/qmlimportscanner/data/Drawer.qml.json index 4eac05306a7..424c6ca8eea 100644 --- a/tests/auto/qml/qmlimportscanner/data/Drawer.qml.json +++ b/tests/auto/qml/qmlimportscanner/data/Drawer.qml.json @@ -1,6 +1,7 @@ [ { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -9,6 +10,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -17,6 +19,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/Imports.json b/tests/auto/qml/qmlimportscanner/data/Imports.json index 1a1850163dd..16b7376713c 100644 --- a/tests/auto/qml/qmlimportscanner/data/Imports.json +++ b/tests/auto/qml/qmlimportscanner/data/Imports.json @@ -6,6 +6,7 @@ }, { "classname": "QtQuick2Plugin", + "linkTarget": "Qt6::qtquick2plugin", "name": "QtQuick", "plugin": "qtquick2plugin", "pluginIsOptional": true, @@ -14,6 +15,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -22,6 +24,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -30,6 +33,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/ListProperty.qml.json b/tests/auto/qml/qmlimportscanner/data/ListProperty.qml.json index d647f7f9aef..bd9faec18c2 100644 --- a/tests/auto/qml/qmlimportscanner/data/ListProperty.qml.json +++ b/tests/auto/qml/qmlimportscanner/data/ListProperty.qml.json @@ -2,6 +2,7 @@ { "classname": "QtQuick2Plugin", "name": "QtQuick", + "linkTarget": "Qt6::qtquick2plugin", "plugin": "qtquick2plugin", "pluginIsOptional": true, "relativePath": "QtQuick", @@ -15,6 +16,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -23,6 +25,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -31,6 +34,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/QTBUG-45916.js.json b/tests/auto/qml/qmlimportscanner/data/QTBUG-45916.js.json index f7bddd6a914..d132b676eca 100644 --- a/tests/auto/qml/qmlimportscanner/data/QTBUG-45916.js.json +++ b/tests/auto/qml/qmlimportscanner/data/QTBUG-45916.js.json @@ -1,6 +1,7 @@ [ { "classname": "QtQuick2Plugin", + "linkTarget": "Qt6::qtquick2plugin", "name": "QtQuick", "plugin": "qtquick2plugin", "pluginIsOptional": true, @@ -9,6 +10,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -17,6 +19,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -25,6 +28,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/Simple.qml.json b/tests/auto/qml/qmlimportscanner/data/Simple.qml.json index f7bddd6a914..d132b676eca 100644 --- a/tests/auto/qml/qmlimportscanner/data/Simple.qml.json +++ b/tests/auto/qml/qmlimportscanner/data/Simple.qml.json @@ -1,6 +1,7 @@ [ { "classname": "QtQuick2Plugin", + "linkTarget": "Qt6::qtquick2plugin", "name": "QtQuick", "plugin": "qtquick2plugin", "pluginIsOptional": true, @@ -9,6 +10,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -17,6 +19,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -25,6 +28,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/Singleton.json b/tests/auto/qml/qmlimportscanner/data/Singleton.json index ca1d0b2d4d8..5600cfc6a27 100644 --- a/tests/auto/qml/qmlimportscanner/data/Singleton.json +++ b/tests/auto/qml/qmlimportscanner/data/Singleton.json @@ -6,6 +6,7 @@ }, { "classname": "QtQuick2Plugin", + "linkTarget": "Qt6::qtquick2plugin", "name": "QtQuick", "plugin": "qtquick2plugin", "pluginIsOptional": true, @@ -14,6 +15,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -22,6 +24,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -30,6 +33,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/Things.json b/tests/auto/qml/qmlimportscanner/data/Things.json index e50902152e0..1245539b577 100644 --- a/tests/auto/qml/qmlimportscanner/data/Things.json +++ b/tests/auto/qml/qmlimportscanner/data/Things.json @@ -7,6 +7,7 @@ }, { "classname": "QtQuick2Plugin", + "linkTarget": "Qt6::qtquick2plugin", "name": "QtQuick", "plugin": "qtquick2plugin", "pluginIsOptional": true, @@ -15,6 +16,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -23,6 +25,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -31,6 +34,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/With/Module/A.qml b/tests/auto/qml/qmlimportscanner/data/With/Module/A.qml new file mode 100644 index 00000000000..8fc36a40daf --- /dev/null +++ b/tests/auto/qml/qmlimportscanner/data/With/Module/A.qml @@ -0,0 +1,3 @@ +import QtQml + +QtObject {} diff --git a/tests/auto/qml/qmlimportscanner/data/With/Module/qmldir b/tests/auto/qml/qmlimportscanner/data/With/Module/qmldir new file mode 100644 index 00000000000..2338864432f --- /dev/null +++ b/tests/auto/qml/qmlimportscanner/data/With/Module/qmldir @@ -0,0 +1,3 @@ +module Module + +A 1.0 A.qml diff --git a/tests/auto/qml/qmlimportscanner/data/WithOut/Module/A.qml b/tests/auto/qml/qmlimportscanner/data/WithOut/Module/A.qml new file mode 100644 index 00000000000..8fc36a40daf --- /dev/null +++ b/tests/auto/qml/qmlimportscanner/data/WithOut/Module/A.qml @@ -0,0 +1,3 @@ +import QtQml + +QtObject {} diff --git a/tests/auto/qml/qmlimportscanner/data/javascriptMethods.qml.json b/tests/auto/qml/qmlimportscanner/data/javascriptMethods.qml.json index cbd409266d2..737b90fcc6b 100644 --- a/tests/auto/qml/qmlimportscanner/data/javascriptMethods.qml.json +++ b/tests/auto/qml/qmlimportscanner/data/javascriptMethods.qml.json @@ -1,6 +1,7 @@ [ { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -13,6 +14,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -21,6 +23,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/localImport.qml.json b/tests/auto/qml/qmlimportscanner/data/localImport.qml.json index e50902152e0..1245539b577 100644 --- a/tests/auto/qml/qmlimportscanner/data/localImport.qml.json +++ b/tests/auto/qml/qmlimportscanner/data/localImport.qml.json @@ -7,6 +7,7 @@ }, { "classname": "QtQuick2Plugin", + "linkTarget": "Qt6::qtquick2plugin", "name": "QtQuick", "plugin": "qtquick2plugin", "pluginIsOptional": true, @@ -15,6 +16,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -23,6 +25,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -31,6 +34,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/parentEnum.qml.json b/tests/auto/qml/qmlimportscanner/data/parentEnum.qml.json index f7bddd6a914..d132b676eca 100644 --- a/tests/auto/qml/qmlimportscanner/data/parentEnum.qml.json +++ b/tests/auto/qml/qmlimportscanner/data/parentEnum.qml.json @@ -1,6 +1,7 @@ [ { "classname": "QtQuick2Plugin", + "linkTarget": "Qt6::qtquick2plugin", "name": "QtQuick", "plugin": "qtquick2plugin", "pluginIsOptional": true, @@ -9,6 +10,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -17,6 +19,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -25,6 +28,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/qmldirImportAndDepend.qml.json b/tests/auto/qml/qmlimportscanner/data/qmldirImportAndDepend.qml.json index e50902152e0..1245539b577 100644 --- a/tests/auto/qml/qmlimportscanner/data/qmldirImportAndDepend.qml.json +++ b/tests/auto/qml/qmlimportscanner/data/qmldirImportAndDepend.qml.json @@ -7,6 +7,7 @@ }, { "classname": "QtQuick2Plugin", + "linkTarget": "Qt6::qtquick2plugin", "name": "QtQuick", "plugin": "qtquick2plugin", "pluginIsOptional": true, @@ -15,6 +16,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -23,6 +25,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -31,6 +34,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/qmldirpref.qml b/tests/auto/qml/qmlimportscanner/data/qmldirpref.qml new file mode 100644 index 00000000000..d1b1e803290 --- /dev/null +++ b/tests/auto/qml/qmlimportscanner/data/qmldirpref.qml @@ -0,0 +1,3 @@ +import Module + +A {} diff --git a/tests/auto/qml/qmlimportscanner/data/qtQmlOnly.qml.json b/tests/auto/qml/qmlimportscanner/data/qtQmlOnly.qml.json index 4eac05306a7..424c6ca8eea 100644 --- a/tests/auto/qml/qmlimportscanner/data/qtQmlOnly.qml.json +++ b/tests/auto/qml/qmlimportscanner/data/qtQmlOnly.qml.json @@ -1,6 +1,7 @@ [ { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -9,6 +10,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -17,6 +19,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, diff --git a/tests/auto/qml/qmlimportscanner/data/rootPath.json b/tests/auto/qml/qmlimportscanner/data/rootPath.json index 21dbb126298..fe42646665e 100644 --- a/tests/auto/qml/qmlimportscanner/data/rootPath.json +++ b/tests/auto/qml/qmlimportscanner/data/rootPath.json @@ -1,6 +1,7 @@ [ { "classname": "QtQuick2Plugin", + "linkTarget": "Qt6::qtquick2plugin", "name": "QtQuick", "plugin": "qtquick2plugin", "pluginIsOptional": true, @@ -9,6 +10,7 @@ }, { "classname": "QtQmlPlugin", + "linkTarget": "Qt6::qmlplugin", "name": "QtQml", "plugin": "qmlplugin", "pluginIsOptional": true, @@ -17,6 +19,7 @@ }, { "classname": "QtQmlModelsPlugin", + "linkTarget": "Qt6::modelsplugin", "name": "QtQml.Models", "plugin": "modelsplugin", "pluginIsOptional": true, @@ -25,6 +28,7 @@ }, { "classname": "QtQmlWorkerScriptPlugin", + "linkTarget": "Qt6::workerscriptplugin", "name": "QtQml.WorkerScript", "plugin": "workerscriptplugin", "pluginIsOptional": true, @@ -53,5 +57,9 @@ "name": "Imports", "relativePath": "Imports", "type": "module" + }, + { + "name": "Module", + "type": "module" } ] diff --git a/tests/auto/qml/qmlimportscanner/tst_qmlimportscanner.cpp b/tests/auto/qml/qmlimportscanner/tst_qmlimportscanner.cpp index 5b8b92748a7..2d339cc33d1 100644 --- a/tests/auto/qml/qmlimportscanner/tst_qmlimportscanner.cpp +++ b/tests/auto/qml/qmlimportscanner/tst_qmlimportscanner.cpp @@ -29,13 +29,15 @@ #include <QtTest/QtTest> #include <QProcess> #include <QString> - -#include <util.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> class TestQmlimportscanner: public QQmlDataTest { Q_OBJECT +public: + TestQmlimportscanner(); + private Q_SLOTS: void initTestCase() override; @@ -44,6 +46,7 @@ private Q_SLOTS: void rootPath(); void modules_data(); void modules(); + void qmldirPreference(); private: void runQmlimportscanner(const QString &mode, const QString &fileToScan, @@ -52,6 +55,11 @@ private Q_SLOTS: QString m_qmlimportscannerPath; }; +TestQmlimportscanner::TestQmlimportscanner() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void TestQmlimportscanner::initTestCase() { QQmlDataTest::initTestCase(); @@ -116,6 +124,31 @@ void TestQmlimportscanner::modules() runQmlimportscanner("-qmlFiles", qmlFile.fileName(), testFile(name + ".json")); } +void TestQmlimportscanner::qmldirPreference() +{ + // ### + QStringList with {u"-importPath"_qs, testFile("With")}; + QStringList withOut {u"-importPath"_qs, testFile("WithOut")}; + QStringList genericArgs {u"-qmlFiles"_qs, testFile("qmldirpref.qml"), u"-importPath"_qs, + QLibraryInfo::path(QLibraryInfo::QmlImportsPath)}; + + + // found path should not depend on order of importPath arguments + QStringList argcombis[2] { genericArgs + with + withOut, genericArgs + withOut + with }; + for (const auto &allArgs: argcombis) { + QProcess process; + process.start(m_qmlimportscannerPath, allArgs); + QVERIFY(process.waitForFinished()); + QCOMPARE(process.exitStatus(), QProcess::NormalExit); + QCOMPARE(process.exitCode(), 0); + QVERIFY(process.readAllStandardError().isEmpty()); + auto output = process.readAllStandardOutput(); + // check that the "With" path is used, and the "WithOut" path is ignored + QVERIFY(output.contains("With/Module")); + QVERIFY(!output.contains("WithOut/Module")); + } +} + void TestQmlimportscanner::runQmlimportscanner(const QString &mode, const QString &pathToScan, const QString &resultFile) { @@ -157,9 +190,9 @@ void TestQmlimportscanner::runQmlimportscanner(const QString &mode, const QStrin #define STR(A) #A if (object.contains("plugin")) { auto plugin = object["plugin"].toString(); - const auto pos = plugin.lastIndexOf(XSTR(LIBINFIX)); + const auto pos = plugin.lastIndexOf(XSTR(LIBINFIX) "plugin"); if (pos != -1) - object["plugin"] = plugin.left(pos); + object["plugin"] = plugin.left(pos) + "plugin"; } #endif diff --git a/tests/auto/qml/qmllint/CMakeLists.txt b/tests/auto/qml/qmllint/CMakeLists.txt index c69748cc60b..15549a93b74 100644 --- a/tests/auto/qml/qmllint/CMakeLists.txt +++ b/tests/auto/qml/qmllint/CMakeLists.txt @@ -12,12 +12,10 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qmllint SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qmllint.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qmllint/data/Cycle/MenuItem.qml b/tests/auto/qml/qmllint/data/Cycle/MenuItem.qml new file mode 100644 index 00000000000..b316a5432c4 --- /dev/null +++ b/tests/auto/qml/qmllint/data/Cycle/MenuItem.qml @@ -0,0 +1,3 @@ +import QtQml + +MenuItem {} diff --git a/tests/auto/qml/qmllint/data/Cycle/qmldir b/tests/auto/qml/qmllint/data/Cycle/qmldir new file mode 100644 index 00000000000..6b0ba5519ad --- /dev/null +++ b/tests/auto/qml/qmllint/data/Cycle/qmldir @@ -0,0 +1,3 @@ +module Cycle + +MenuItem 1.0 MenuItem.qml diff --git a/tests/auto/qml/qmllint/data/LazyAndDirect/Direct.qml b/tests/auto/qml/qmllint/data/LazyAndDirect/Direct.qml new file mode 100644 index 00000000000..fcb08c1e80e --- /dev/null +++ b/tests/auto/qml/qmllint/data/LazyAndDirect/Direct.qml @@ -0,0 +1,5 @@ +import QtQml + +QtObject { + Component.onCompleted: Lazy.setDirect(this) +} diff --git a/tests/auto/qml/qmllint/data/LazyAndDirect/Lazy.qml b/tests/auto/qml/qmllint/data/LazyAndDirect/Lazy.qml new file mode 100644 index 00000000000..1f69d0f16a9 --- /dev/null +++ b/tests/auto/qml/qmllint/data/LazyAndDirect/Lazy.qml @@ -0,0 +1,8 @@ +pragma Singleton +import QtQml + +QtObject { + property Direct direct + + function setDirect(newDirect : Direct) { direct = newDirect } +} diff --git a/tests/auto/qml/qmllint/data/LazyAndDirect/qmldir b/tests/auto/qml/qmllint/data/LazyAndDirect/qmldir new file mode 100644 index 00000000000..ebc7f2a1572 --- /dev/null +++ b/tests/auto/qml/qmllint/data/LazyAndDirect/qmldir @@ -0,0 +1,4 @@ +module LazyAndDirect + +Direct 1.0 Direct.qml +singleton Lazy 1.0 Lazy.qml diff --git a/tests/auto/qml/qmllint/data/Qt5Compat/GraphicalEffects/private/qmldir b/tests/auto/qml/qmllint/data/Qt5Compat/GraphicalEffects/private/qmldir new file mode 100644 index 00000000000..b13cdc9c3ea --- /dev/null +++ b/tests/auto/qml/qmllint/data/Qt5Compat/GraphicalEffects/private/qmldir @@ -0,0 +1,2 @@ +module Qt5Compat.GraphicalEffects.private +typeinfo plugins.qmltypes diff --git a/tests/auto/qml/qmllint/data/Things/LintDirectly.qml b/tests/auto/qml/qmllint/data/Things/LintDirectly.qml new file mode 100644 index 00000000000..4384fa99f4a --- /dev/null +++ b/tests/auto/qml/qmllint/data/Things/LintDirectly.qml @@ -0,0 +1,4 @@ +Pane { + property var thing: NotPartOfThings {} + property var something: Something {} +} diff --git a/tests/auto/qml/qmllint/data/Things/NotPartOfThings.qml b/tests/auto/qml/qmllint/data/Things/NotPartOfThings.qml new file mode 100644 index 00000000000..16fd397d1df --- /dev/null +++ b/tests/auto/qml/qmllint/data/Things/NotPartOfThings.qml @@ -0,0 +1,3 @@ +import QtQuick + +Component {} diff --git a/tests/auto/qml/qmllint/data/Things/plugins.qmltypes b/tests/auto/qml/qmllint/data/Things/plugins.qmltypes index 9ad8c714680..7d0514dbdfc 100644 --- a/tests/auto/qml/qmllint/data/Things/plugins.qmltypes +++ b/tests/auto/qml/qmllint/data/Things/plugins.qmltypes @@ -64,4 +64,13 @@ Module { ] Property { name: "alignment"; type: "Qt::Alignment" } } + Component { + name: "CustomParserThing" + prototype: "QQuickItem" + exports: [ + "Things/CustomParserThing 1.0" + ] + Property { name: "foo"; type: "string" } + hasCustomParser: true + } } diff --git a/tests/auto/qml/qmllint/data/TypeWithDefaultListProperty.qml b/tests/auto/qml/qmllint/data/TypeWithDefaultListProperty.qml new file mode 100644 index 00000000000..e30314a825c --- /dev/null +++ b/tests/auto/qml/qmllint/data/TypeWithDefaultListProperty.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + default property list<QtObject> children +} diff --git a/tests/auto/qml/qmllint/data/TypeWithDefaultProperty.qml b/tests/auto/qml/qmllint/data/TypeWithDefaultProperty.qml new file mode 100644 index 00000000000..e64befb7644 --- /dev/null +++ b/tests/auto/qml/qmllint/data/TypeWithDefaultProperty.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + default property QtObject child +} diff --git a/tests/auto/qml/qmllint/data/TypeWithDefaultStringProperty.qml b/tests/auto/qml/qmllint/data/TypeWithDefaultStringProperty.qml new file mode 100644 index 00000000000..98c446870ca --- /dev/null +++ b/tests/auto/qml/qmllint/data/TypeWithDefaultStringProperty.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + default property string child +} diff --git a/tests/auto/qml/qmllint/data/TypeWithDefaultVarProperty.qml b/tests/auto/qml/qmllint/data/TypeWithDefaultVarProperty.qml new file mode 100644 index 00000000000..9fa89833d56 --- /dev/null +++ b/tests/auto/qml/qmllint/data/TypeWithDefaultVarProperty.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + default property var child +} diff --git a/tests/auto/qml/qmllint/data/accessibleId.qml b/tests/auto/qml/qmllint/data/accessibleId.qml new file mode 100644 index 00000000000..904b856320f --- /dev/null +++ b/tests/auto/qml/qmllint/data/accessibleId.qml @@ -0,0 +1,14 @@ +import QtQml + +QtObject { + id: a + property Component c: Component { + QtObject { + id: a + property QtObject o: QtObject { + property int a: 5 + objectName: a.objectName + } + } + } +} diff --git a/tests/auto/qml/qmllint/data/animationEasing.qml b/tests/auto/qml/qmllint/data/animationEasing.qml new file mode 100644 index 00000000000..1b0c9ffea42 --- /dev/null +++ b/tests/auto/qml/qmllint/data/animationEasing.qml @@ -0,0 +1,5 @@ +import QtQml +import QtQuick +NumberAnimation { + easing.type: Easing.InOutQuad +} diff --git a/tests/auto/qml/qmllint/data/badScript.attached.qml b/tests/auto/qml/qmllint/data/badScript.attached.qml new file mode 100644 index 00000000000..f3183430fc9 --- /dev/null +++ b/tests/auto/qml/qmllint/data/badScript.attached.qml @@ -0,0 +1,4 @@ +import QtQuick +Text { + font.pixelSize: 10 + pointSize * 0.1 // pointSize does not exist in the scope of the binding +} diff --git a/tests/auto/qml/qmllint/data/badScriptBinding.attached.qml b/tests/auto/qml/qmllint/data/badScriptBinding.attached.qml new file mode 100644 index 00000000000..a5ec7d9050b --- /dev/null +++ b/tests/auto/qml/qmllint/data/badScriptBinding.attached.qml @@ -0,0 +1,6 @@ +import QtQuick.Layouts +RowLayout { + function returnTrue() { return true; } + Layout.fillWidth: returnTrue() + Layout.bogusProperty: returnTrue() +} diff --git a/tests/auto/qml/qmllint/data/badScriptBinding.attachedSignalHandler.qml b/tests/auto/qml/qmllint/data/badScriptBinding.attachedSignalHandler.qml new file mode 100644 index 00000000000..56d89a81da7 --- /dev/null +++ b/tests/auto/qml/qmllint/data/badScriptBinding.attachedSignalHandler.qml @@ -0,0 +1,7 @@ +import QtQuick +Rectangle { + Keys.onBogusSignal: function(event) { + // the handler is good, but the signal doesn't exist + console.log(event); + } +} diff --git a/tests/auto/qml/qmllint/data/badScriptBinding.group.qml b/tests/auto/qml/qmllint/data/badScriptBinding.group.qml new file mode 100644 index 00000000000..d92feb81f00 --- /dev/null +++ b/tests/auto/qml/qmllint/data/badScriptBinding.group.qml @@ -0,0 +1,4 @@ +import QtQuick +Text { + font.bogusProperty: "foo" + "bar" +} diff --git a/tests/auto/qml/qmllint/data/bad_builtins/builtins.qmltypes b/tests/auto/qml/qmllint/data/bad_builtins/builtins.qmltypes new file mode 100644 index 00000000000..96f98dd14ea --- /dev/null +++ b/tests/auto/qml/qmllint/data/bad_builtins/builtins.qmltypes @@ -0,0 +1,513 @@ +import QtQuick.tooling 1.2 + +// This file describes the plugin-supplied types contained in the library. +// It is used for QML tooling purposes only. +// +// This file was auto-generated by: +// 'qmlplugindump -builtins' + +Module { + dependencies: [] + Component { + name: "Qt" + Enum { + name: "GlobalColor" + values: { + "color0": 0, + "color1": 1, + "black": 2, + "white": 3, + "darkGray": 4, + "gray": 5, + "lightGray": 6, + "red": 7, + "green": 8, + "blue": 9, + "cyan": 10, + "magenta": 11, + "yellow": 12, + "darkRed": 13, + "darkGreen": 14, + "darkBlue": 15, + "darkCyan": 16, + "darkMagenta": 17, + "darkYellow": 18, + "transparent": 19 + } + } + Enum { + name: "KeyboardModifiers" + values: { + "NoModifier": 0, + "ShiftModifier": 33554432, + "ControlModifier": 67108864, + "AltModifier": 134217728, + "MetaModifier": 268435456, + "KeypadModifier": 536870912, + "GroupSwitchModifier": 1073741824, + "KeyboardModifierMask": -33554432 + } + } + Enum { + name: "MouseButtons" + values: { + "NoButton": 0, + "LeftButton": 1, + "RightButton": 2, + "MidButton": 4, // For backwards compatibility + "MiddleButton": 4, + "BackButton": 8, + "XButton1": 8, + "ExtraButton1": 8, + "ForwardButton": 16, + "XButton2": 16, + "ExtraButton2": 16, + "TaskButton": 32, + "ExtraButton3": 32, + "ExtraButton4": 64, + "ExtraButton5": 128, + "ExtraButton6": 256, + "ExtraButton7": 512, + "ExtraButton8": 1024, + "ExtraButton9": 2048, + "ExtraButton10": 4096, + "ExtraButton11": 8192, + "ExtraButton12": 16384, + "ExtraButton13": 32768, + "ExtraButton14": 65536, + "ExtraButton15": 131072, + "ExtraButton16": 262144, + "ExtraButton17": 524288, + "ExtraButton18": 1048576, + "ExtraButton19": 2097152, + "ExtraButton20": 4194304, + "ExtraButton21": 8388608, + "ExtraButton22": 16777216, + "ExtraButton23": 33554432, + "ExtraButton24": 67108864, + "AllButtons": 134217727, + "MaxMouseButton": 67108864, + "MouseButtonMask": -1 + } + } + Enum { + name: "Orientation" + values: { + "Horizontal": 1, + "Vertical": 2 + } + } + Enum { + name: "Orientations" + values: { + "Horizontal": 1, + "Vertical": 2 + } + } + Enum { + name: "FocusPolicy" + values: { + "NoFocus": 0, + "TabFocus": 1, + "ClickFocus": 2, + "StrongFocus": 11, + "WheelFocus": 15 + } + } + Enum { + name: "TabFocusBehavior" + values: { + "NoTabFocus": 0, + "TabFocusTextControls": 1, + "TabFocusListControls": 2, + "TabFocusAllControls": 255 + } + } + Enum { + name: "SortOrder" + values: { + "AscendingOrder": 0, + "DescendingOrder": 1 + } + } + Enum { + name: "SplitBehavior" + values: { + "KeepEmptyParts": 0, + "SkipEmptyParts": 1 + } + } + Enum { + name: "Alignment" + values: { + "AlignLeft": 1, + "AlignLeading": 1, + "AlignRight": 2, + "AlignTrailing": 2, + "AlignHCenter": 4, + "AlignJustify": 8, + "AlignAbsolute": 16, + "AlignHorizontal_Mask": 31, + "AlignTop": 32, + "AlignBottom": 64, + "AlignVCenter": 128, + "AlignBaseline": 256, + "AlignVertical_Mask": 480, + "AlignCenter": 132 + } + } + Enum { + name: "TextFlag" + values: { + "TextSingleLine": 256, + "TextDontClip": 512, + "TextExpandTabs": 1024, + "TextShowMnemonic": 2048, + "TextWordWrap": 4096, + "TextWrapAnywhere": 8192, + "TextDontPrint": 16384, + "TextIncludeTrailingSpaces": 134217728, + "TextHideMnemonic": 32768, + "TextJustificationForced": 65536, + "TextForceLeftToRight": 131072, + "TextForceRightToLeft": 262144, + "TextLongestVariant": 524288, + "TextBypassShaping": 1048576 + } + } + Enum { + name: "TextElideMode" + values: { + "ElideLeft": 0, + "ElideRight": 1, + "ElideMiddle": 2, + "ElideNone": 3 + } + } + Enum { + name: "WindowType" + values: { + "Widget": 0, + "Window": 1, + "Dialog": 3, + "Sheet": 5, + "Drawer": 7, + "Popup": 9, + "Tool": 11, + "ToolTip": 13, + "SplashScreen": 15, + "Desktop": 17, + "SubWindow": 18, + "ForeignWindow": 33, + "CoverWindow": 65, + "WindowType_Mask": 255, + "MSWindowsFixedSizeDialogHint": 256, + "MSWindowsOwnDC": 512, + "BypassWindowManagerHint": 1024, + "X11BypassWindowManagerHint": 1024, + "FramelessWindowHint": 2048, + "WindowTitleHint": 4096, + "WindowSystemMenuHint": 8192, + "WindowMinimizeButtonHint": 16384, + "WindowMaximizeButtonHint": 32768, + "WindowMinMaxButtonsHint": 49152, + "WindowContextHelpButtonHint": 65536, + "WindowShadeButtonHint": 131072, + "WindowStaysOnTopHint": 262144, + "WindowTransparentForInput": 524288, + "WindowOverridesSystemGestures": 1048576, + "WindowDoesNotAcceptFocus": 2097152, + "MaximizeUsingFullscreenGeometryHint": 4194304, + "CustomizeWindowHint": 33554432, + "WindowStaysOnBottomHint": 67108864, + "WindowCloseButtonHint": 134217728, + "MacWindowToolBarButtonHint": 268435456, + "BypassGraphicsProxyWidget": 536870912, + "NoDropShadowWindowHint": 1073741824, + "WindowFullscreenButtonHint": -2147483648 + } + } + Enum { + name: "WindowFlags" + values: { + "Widget": 0, + "Window": 1, + "Dialog": 3, + "Sheet": 5, + "Drawer": 7, + "Popup": 9, + "Tool": 11, + "ToolTip": 13, + "SplashScreen": 15, + "Desktop": 17, + "SubWindow": 18, + "ForeignWindow": 33, + "CoverWindow": 65, + "WindowType_Mask": 255, + "MSWindowsFixedSizeDialogHint": 256, + "MSWindowsOwnDC": 512, + "BypassWindowManagerHint": 1024, + "X11BypassWindowManagerHint": 1024, + "FramelessWindowHint": 2048, + "WindowTitleHint": 4096, + "WindowSystemMenuHint": 8192, + "WindowMinimizeButtonHint": 16384, + "WindowMaximizeButtonHint": 32768, + "WindowMinMaxButtonsHint": 49152, + "WindowContextHelpButtonHint": 65536, + "WindowShadeButtonHint": 131072, + "WindowStaysOnTopHint": 262144, + "WindowTransparentForInput": 524288, + "WindowOverridesSystemGestures": 1048576, + "WindowDoesNotAcceptFocus": 2097152, + "MaximizeUsingFullscreenGeometryHint": 4194304, + "CustomizeWindowHint": 33554432, + "WindowStaysOnBottomHint": 67108864, + "WindowCloseButtonHint": 134217728, + "MacWindowToolBarButtonHint": 268435456, + "BypassGraphicsProxyWidget": 536870912, + "NoDropShadowWindowHint": 1073741824, + "WindowFullscreenButtonHint": -2147483648 + } + } + Enum { + name: "WindowState" + values: { + "WindowNoState": 0, + "WindowMinimized": 1, + "WindowMaximized": 2, + "WindowFullScreen": 4, + "WindowActive": 8 + } + } + Enum { + name: "WindowStates" + values: { + "WindowNoState": 0, + "WindowMinimized": 1, + "WindowMaximized": 2, + "WindowFullScreen": 4, + "WindowActive": 8 + } + } + Enum { + name: "ApplicationState" + values: { + "ApplicationSuspended": 0, + "ApplicationHidden": 1, + "ApplicationInactive": 2, + "ApplicationActive": 4 + } + } + Enum { + name: "ScreenOrientation" + values: { + "PrimaryOrientation": 0, + "PortraitOrientation": 1, + "LandscapeOrientation": 2, + "InvertedPortraitOrientation": 4, + "InvertedLandscapeOrientation": 8 + } + } + Enum { + name: "ScreenOrientations" + values: { + "PrimaryOrientation": 0, + "PortraitOrientation": 1, + "LandscapeOrientation": 2, + "InvertedPortraitOrientation": 4, + "InvertedLandscapeOrientation": 8 + } + } + Enum { + name: "WidgetAttribute" + values: { + "WA_Disabled": 0, + "WA_UnderMouse": 1, + "WA_MouseTracking": 2, + "WA_ContentsPropagated": 3, + "WA_OpaquePaintEvent": 4, + "WA_NoBackground": 4, + "WA_StaticContents": 5, + "WA_LaidOut": 7, + "WA_PaintOnScreen": 8, + "WA_NoSystemBackground": 9, + "WA_UpdatesDisabled": 10, + "WA_Mapped": 11, + "WA_MacNoClickThrough": 12, + "WA_InputMethodEnabled": 14, + "WA_WState_Visible": 15, + "WA_WState_Hidden": 16, + "WA_ForceDisabled": 32, + "WA_KeyCompression": 33, + "WA_PendingMoveEvent": 34, + "WA_PendingResizeEvent": 35, + "WA_SetPalette": 36, + "WA_SetFont": 37, + "WA_SetCursor": 38, + "WA_NoChildEventsFromChildren": 39, + "WA_WindowModified": 41, + "WA_Resized": 42, + "WA_Moved": 43, + "WA_PendingUpdate": 44, + "WA_InvalidSize": 45, + "WA_MacBrushedMetal": 46, + "WA_MacMetalStyle": 46, + "WA_CustomWhatsThis": 47, + "WA_LayoutOnEntireRect": 48, + "WA_OutsideWSRange": 49, + "WA_GrabbedShortcut": 50, + "WA_TransparentForMouseEvents": 51, + "WA_PaintUnclipped": 52, + "WA_SetWindowIcon": 53, + "WA_NoMouseReplay": 54, + "WA_DeleteOnClose": 55, + "WA_RightToLeft": 56, + "WA_SetLayoutDirection": 57, + "WA_NoChildEventsForParent": 58, + "WA_ForceUpdatesDisabled": 59, + "WA_WState_Created": 60, + "WA_WState_CompressKeys": 61, + "WA_WState_InPaintEvent": 62, + "WA_WState_Reparented": 63, + "WA_WState_ConfigPending": 64, + "WA_WState_Polished": 66, + "WA_WState_DND": 67, + "WA_WState_OwnSizePolicy": 68, + "WA_WState_ExplicitShowHide": 69, + "WA_ShowModal": 70, + "WA_MouseNoMask": 71, + "WA_GroupLeader": 72, + "WA_NoMousePropagation": 73, + "WA_Hover": 74, + "WA_InputMethodTransparent": 75, + "WA_QuitOnClose": 76, + "WA_KeyboardFocusChange": 77, + "WA_AcceptDrops": 78, + "WA_DropSiteRegistered": 79, + "WA_ForceAcceptDrops": 79, + "WA_WindowPropagation": 80, + "WA_NoX11EventCompression": 81, + "WA_TintedBackground": 82, + "WA_X11OpenGLOverlay": 83, + "WA_AlwaysShowToolTips": 84, + "WA_MacOpaqueSizeGrip": 85, + "WA_SetStyle": 86, + "WA_SetLocale": 87, + "WA_MacShowFocusRect": 88, + "WA_MacNormalSize": 89, + "WA_MacSmallSize": 90, + "WA_MacMiniSize": 91, + "WA_LayoutUsesWidgetRect": 92, + "WA_StyledBackground": 93, + "WA_MSWindowsUseDirect3D": 94, + "WA_CanHostQMdiSubWindowTitleBar": 95, + "WA_MacAlwaysShowToolWindow": 96, + "WA_StyleSheet": 97, + "WA_ShowWithoutActivating": 98, + "WA_X11BypassTransientForHint": 99, + "WA_NativeWindow": 100, + "WA_DontCreateNativeAncestors": 101, + "WA_MacVariableSize": 102, + "WA_DontShowOnScreen": 103, + "WA_X11NetWmWindowTypeDesktop": 104, + "WA_X11NetWmWindowTypeDock": 105, + "WA_X11NetWmWindowTypeToolBar": 106, + "WA_X11NetWmWindowTypeMenu": 107, + "WA_X11NetWmWindowTypeUtility": 108, + "WA_X11NetWmWindowTypeSplash": 109, + "WA_X11NetWmWindowTypeDialog": 110, + "WA_X11NetWmWindowTypeDropDownMenu": 111, + "WA_X11NetWmWindowTypePopupMenu": 112, + "WA_X11NetWmWindowTypeToolTip": 113, + "WA_X11NetWmWindowTypeNotification": 114, + "WA_X11NetWmWindowTypeCombo": 115, + "WA_X11NetWmWindowTypeDND": 116, + "WA_MacFrameworkScaled": 117, + "WA_SetWindowModality": 118, + "WA_WState_WindowOpacitySet": 119, + "WA_TranslucentBackground": 120, + "WA_AcceptTouchEvents": 121, + "WA_WState_AcceptedTouchBeginEvent": 122, + "WA_TouchPadAcceptSingleTouchEvents": 123, + "WA_X11DoNotAcceptFocus": 126, + "WA_MacNoShadow": 127, + "WA_AlwaysStackOnTop": 128, + "WA_TabletTracking": 129, + "WA_ContentsMarginsRespectsSafeArea": 130, + "WA_StyleSheetTarget": 131, + "WA_AttributeCount": 132 + } + } + Enum { + name: "ApplicationAttribute" + values: { + "AA_ImmediateWidgetCreation": 0, + "AA_MSWindowsUseDirect3DByDefault": 1, + "AA_DontShowIconsInMenus": 2, + "AA_NativeWindows": 3, + "AA_DontCreateNativeWidgetSiblings": 4, + "AA_PluginApplication": 5, + "AA_MacPluginApplication": 5, + "AA_DontUseNativeMenuBar": 6, + "AA_MacDontSwapCtrlAndMeta": 7, + "AA_Use96Dpi": 8, + "AA_X11InitThreads": 10, + "AA_SynthesizeTouchForUnhandledMouseEvents": 11, + "AA_SynthesizeMouseForUnhandledTouchEvents": 12, + "AA_UseHighDpiPixmaps": 13, + "AA_ForceRasterWidgets": 14, + "AA_UseDesktopOpenGL": 15, + "AA_UseOpenGLES": 16, + "AA_UseSoftwareOpenGL": 17, + "AA_ShareOpenGLContexts": 18, + "AA_SetPalette": 19, + "AA_EnableHighDpiScaling": 20, + "AA_DisableHighDpiScaling": 21, + "AA_UseStyleSheetPropagationInWidgetStyles": 22, + "AA_DontUseNativeDialogs": 23, + "AA_SynthesizeMouseForUnhandledTabletEvents": 24, + "AA_CompressHighFrequencyEvents": 25, + "AA_DontCheckOpenGLContextThreadAffinity": 26, + "AA_DisableShaderDiskCache": 27, + "AA_DontShowShortcutsInContextMenus": 28, + "AA_CompressTabletEvents": 29, + "AA_DisableWindowContextHelpButton": 30, + "AA_DisableSessionManager": 31, + "AA_AttributeCount": 32 + } + } + Enum { + name: "ImageConversionFlags" + values: { + "ColorMode_Mask": 3, + "AutoColor": 0, + "ColorOnly": 3, + "MonoOnly": 2, + "AlphaDither_Mask": 12, + "ThresholdAlphaDither": 0, + "OrderedAlphaDither": 4, + "DiffuseAlphaDither": 8, + "NoAlpha": 12, + "Dither_Mask": 48, + "DiffuseDither": 0, + "OrderedDither": 16, + "ThresholdDither": 32, + "DitherMode_Mask": 192, + "AutoDither": 0, + "PreferDither": 64, + "AvoidDither": 128, + "NoOpaqueDetection": 256, + "NoFormatConversion": 512 + } + } + Enum { + name: "BGMode" + values: { + "TransparentMode": 0, + "OpaqueMode": 1 + } + } + } + Component { name: "QEasingCurve"; prototype: "QQmlEasingValueType" } +} diff --git a/tests/auto/qml/qmllint/data/bindingBeforeDeclaration.qml b/tests/auto/qml/qmllint/data/bindingBeforeDeclaration.qml new file mode 100644 index 00000000000..7fc592d7f0e --- /dev/null +++ b/tests/auto/qml/qmllint/data/bindingBeforeDeclaration.qml @@ -0,0 +1,6 @@ +import QtQuick + +Item { + binding: QtObject {} + property QtObject binding +} diff --git a/tests/auto/qml/qmllint/data/cachedDependency.qml b/tests/auto/qml/qmllint/data/cachedDependency.qml new file mode 100644 index 00000000000..5a15a669979 --- /dev/null +++ b/tests/auto/qml/qmllint/data/cachedDependency.qml @@ -0,0 +1,23 @@ +import QtQuick.Controls.impl // Caches QtQuick as depedency, without QML names +import QtQuick + +Item { + QtObject { id: object } + Item { id: item } + Rectangle { id: rectangle } + + // Various ways to cast between types contained in QtQuick and QtQml + // The QML names of both have to be available for this to work + + property QtObject objectAsObject: object as QtObject + property QtObject objectAsItem: object as Item + property QtObject objectAsRectangle: object as Rectangle + + property QtObject itemAsObject: item as QtObject + property QtObject itemAsItem: item as Item + property QtObject itemAsRectangle: item as Rectangle + + property QtObject rectangleAsObject: rectangle as QtObject + property QtObject rectangleAsItem: rectangle as Item + property QtObject rectangleAsRectangle: rectangle as Rectangle +} diff --git a/tests/auto/qml/qmllint/data/connectionNoParent.qml b/tests/auto/qml/qmllint/data/connectionNoParent.qml new file mode 100644 index 00000000000..27f7e22cf3d --- /dev/null +++ b/tests/auto/qml/qmllint/data/connectionNoParent.qml @@ -0,0 +1,5 @@ +import QtQuick + +Connections { + function onClicked() {} +} diff --git a/tests/auto/qml/qmllint/data/customParserUnqualifiedAccess.qml b/tests/auto/qml/qmllint/data/customParserUnqualifiedAccess.qml new file mode 100644 index 00000000000..dc8f814c919 --- /dev/null +++ b/tests/auto/qml/qmllint/data/customParserUnqualifiedAccess.qml @@ -0,0 +1,5 @@ +import Things + +CustomParserThing { + foo: does.not.exist +} diff --git a/tests/auto/qml/qmllint/data/cycleHead.qml b/tests/auto/qml/qmllint/data/cycleHead.qml new file mode 100644 index 00000000000..080eab381f7 --- /dev/null +++ b/tests/auto/qml/qmllint/data/cycleHead.qml @@ -0,0 +1,7 @@ +import Cycle +import QtQuick + +Item { + property MenuItem item: a + MenuItem { id: a } +} diff --git a/tests/auto/qml/qmllint/data/defaultProperty.qml b/tests/auto/qml/qmllint/data/defaultProperty.qml index 6284cca15cb..be9368c7aa8 100644 --- a/tests/auto/qml/qmllint/data/defaultProperty.qml +++ b/tests/auto/qml/qmllint/data/defaultProperty.qml @@ -1,6 +1,5 @@ import QtQml 2.0 -QtObject { - default property QtObject child +TypeWithDefaultProperty { QtObject {} } diff --git a/tests/auto/qml/qmllint/data/defaultPropertyList.qml b/tests/auto/qml/qmllint/data/defaultPropertyList.qml index fd4f0f7f987..ebf6357c34f 100644 --- a/tests/auto/qml/qmllint/data/defaultPropertyList.qml +++ b/tests/auto/qml/qmllint/data/defaultPropertyList.qml @@ -1,8 +1,7 @@ import QtQml 2.0 import QtQuick 2.15 -QtObject { - default property list<QtObject> children +TypeWithDefaultListProperty { QtObject {} Rectangle {} } diff --git a/tests/auto/qml/qmllint/data/defaultPropertyVar.qml b/tests/auto/qml/qmllint/data/defaultPropertyVar.qml index 7aac1a9a75a..1202d5384d8 100644 --- a/tests/auto/qml/qmllint/data/defaultPropertyVar.qml +++ b/tests/auto/qml/qmllint/data/defaultPropertyVar.qml @@ -1,7 +1,5 @@ import QtQml 2.0 -QtObject { - default property var child - +TypeWithDefaultVarProperty { QtObject {} } diff --git a/tests/auto/qml/qmllint/data/defaultPropertyWithDoubleAssignment.qml b/tests/auto/qml/qmllint/data/defaultPropertyWithDoubleAssignment.qml index af05983f02a..8c2d09fb971 100644 --- a/tests/auto/qml/qmllint/data/defaultPropertyWithDoubleAssignment.qml +++ b/tests/auto/qml/qmllint/data/defaultPropertyWithDoubleAssignment.qml @@ -1,7 +1,6 @@ import QtQml 2.0 -QtObject { - default property QtObject child +TypeWithDefaultProperty { QtObject {} QtObject {} } diff --git a/tests/auto/qml/qmllint/data/defaultPropertyWithWrongType.qml b/tests/auto/qml/qmllint/data/defaultPropertyWithWrongType.qml index b846e247906..d04fecda492 100644 --- a/tests/auto/qml/qmllint/data/defaultPropertyWithWrongType.qml +++ b/tests/auto/qml/qmllint/data/defaultPropertyWithWrongType.qml @@ -1,6 +1,6 @@ import QtQml 2.0 -QtObject { - default property string child +TypeWithDefaultStringProperty { + // default property has type `string`, so cannot assing an object to it QtObject {} } diff --git a/tests/auto/qml/qmllint/data/defaultPropertyWithinTheSameType.qml b/tests/auto/qml/qmllint/data/defaultPropertyWithinTheSameType.qml new file mode 100644 index 00000000000..6284cca15cb --- /dev/null +++ b/tests/auto/qml/qmllint/data/defaultPropertyWithinTheSameType.qml @@ -0,0 +1,6 @@ +import QtQml 2.0 + +QtObject { + default property QtObject child + QtObject {} +} diff --git a/tests/auto/qml/qmllint/data/goodAttachedPropertyAccess.qml b/tests/auto/qml/qmllint/data/goodAttachedPropertyAccess.qml index c46370521a5..b7f64d9acbc 100644 --- a/tests/auto/qml/qmllint/data/goodAttachedPropertyAccess.qml +++ b/tests/auto/qml/qmllint/data/goodAttachedPropertyAccess.qml @@ -6,6 +6,9 @@ QtObject { } Component.onCompleted: { + // NB: this currently fails as TestType.object is recognized as QtObject + // *exactly*, ignoring the QML code above and thus there's no 'progress' + // property on TestType.object console.log(TestType.object.progress); } } diff --git a/tests/auto/qml/qmllint/data/goodBindingsOnGroupAndAttached.qml b/tests/auto/qml/qmllint/data/goodBindingsOnGroupAndAttached.qml new file mode 100644 index 00000000000..7a89b82f6ea --- /dev/null +++ b/tests/auto/qml/qmllint/data/goodBindingsOnGroupAndAttached.qml @@ -0,0 +1,11 @@ +import QtQuick +Rectangle { + Text { + font.pixelSize: 42 + } + + Keys.enabled: false + Keys.onPressed: function(event) { + console.log(event); + } +} diff --git a/tests/auto/qml/qmllint/data/importQMLModule.qml b/tests/auto/qml/qmllint/data/importQMLModule.qml new file mode 100644 index 00000000000..842183ed5bc --- /dev/null +++ b/tests/auto/qml/qmllint/data/importQMLModule.qml @@ -0,0 +1,2 @@ +import QML +QtObject {} diff --git a/tests/auto/qml/qmllint/data/inaccessibleId.qml b/tests/auto/qml/qmllint/data/inaccessibleId.qml new file mode 100644 index 00000000000..a3489f47411 --- /dev/null +++ b/tests/auto/qml/qmllint/data/inaccessibleId.qml @@ -0,0 +1,12 @@ +import QtQml + +QtObject { + id: a + + property Component c: Component { + QtObject { + property int a: 5 + objectName: a.objectName + } + } +} diff --git a/tests/auto/qml/qmllint/data/inaccessibleId2.qml b/tests/auto/qml/qmllint/data/inaccessibleId2.qml new file mode 100644 index 00000000000..b8f381b0b7f --- /dev/null +++ b/tests/auto/qml/qmllint/data/inaccessibleId2.qml @@ -0,0 +1,10 @@ +import QtQml + +QtObject { + id: a + + component Handle: QtObject { + property int a: 5 + objectName: a.objectName + } +} diff --git a/tests/auto/qml/qmllint/data/inlineComponentsChained.qml b/tests/auto/qml/qmllint/data/inlineComponentsChained.qml new file mode 100644 index 00000000000..cc063b1bc24 --- /dev/null +++ b/tests/auto/qml/qmllint/data/inlineComponentsChained.qml @@ -0,0 +1,10 @@ +import QtQuick + +Item { + component A : B { required foo } + component B : C { property QtObject foo } + component C : Item { + } + A { foo: QtObject {} } +} + diff --git a/tests/auto/qml/qmllint/data/invalidId1.qml b/tests/auto/qml/qmllint/data/invalidId1.qml new file mode 100644 index 00000000000..61c45530f1c --- /dev/null +++ b/tests/auto/qml/qmllint/data/invalidId1.qml @@ -0,0 +1,5 @@ +import QtQml + +QtObject { + id: foo.bar +} diff --git a/tests/auto/qml/qmllint/data/missingBuiltinsNoCrash.qml b/tests/auto/qml/qmllint/data/missingBuiltinsNoCrash.qml new file mode 100644 index 00000000000..a2f7d422b3e --- /dev/null +++ b/tests/auto/qml/qmllint/data/missingBuiltinsNoCrash.qml @@ -0,0 +1,3 @@ +import QtQuick // This can't be found if --bare is specified and no paths are provided + +Item {} diff --git a/tests/auto/qml/qmllint/data/missingQmltypes.qml b/tests/auto/qml/qmllint/data/missingQmltypes.qml new file mode 100644 index 00000000000..19a6dbd10b8 --- /dev/null +++ b/tests/auto/qml/qmllint/data/missingQmltypes.qml @@ -0,0 +1,4 @@ +import QtQml +import Qt5Compat.GraphicalEffects.private + +QtObject {} diff --git a/tests/auto/qml/qmllint/data/multiGrouped.qml b/tests/auto/qml/qmllint/data/multiGrouped.qml new file mode 100644 index 00000000000..ab6bd5bd025 --- /dev/null +++ b/tests/auto/qml/qmllint/data/multiGrouped.qml @@ -0,0 +1,6 @@ +import QtQuick + +Item { + anchors.verticalCenter: parent.verticalCenter + anchors { right: parent.left } +} diff --git a/tests/auto/qml/qmllint/data/onBindingInGroupedProperty.qml b/tests/auto/qml/qmllint/data/onBindingInGroupedProperty.qml new file mode 100644 index 00000000000..186b8a557fd --- /dev/null +++ b/tests/auto/qml/qmllint/data/onBindingInGroupedProperty.qml @@ -0,0 +1,10 @@ +import QtQuick + +Rectangle +{ + id: root + border + { + ColorAnimation on color { } + } +} diff --git a/tests/auto/qml/qmllint/data/prefixedAttachedProperty.qml b/tests/auto/qml/qmllint/data/prefixedAttachedProperty.qml new file mode 100644 index 00000000000..1f9634e2805 --- /dev/null +++ b/tests/auto/qml/qmllint/data/prefixedAttachedProperty.qml @@ -0,0 +1,5 @@ +import QtQuick as T + +T.Item { + T.Accessible.name: "Example" +} diff --git a/tests/auto/qml/qmllint/data/qmldirImport/QtObjectWithDefaultProperty.qml b/tests/auto/qml/qmllint/data/qmldirImport/QtObjectWithDefaultProperty.qml new file mode 100644 index 00000000000..d33d0b5c946 --- /dev/null +++ b/tests/auto/qml/qmllint/data/qmldirImport/QtObjectWithDefaultProperty.qml @@ -0,0 +1,4 @@ +import DuplicateImport // imports QtQml +QtObject { + default property QtObject child +} diff --git a/tests/auto/qml/qmllint/data/qmldirImport/duplicate.qml b/tests/auto/qml/qmllint/data/qmldirImport/duplicate.qml index 0040e67f7c4..22f454ad44c 100644 --- a/tests/auto/qml/qmllint/data/qmldirImport/duplicate.qml +++ b/tests/auto/qml/qmllint/data/qmldirImport/duplicate.qml @@ -1,8 +1,6 @@ import DuplicateImport // imports QtQml directly and indirectly via QtQuick -QtObject { - default property QtObject child - +QtObjectWithDefaultProperty { // for default property ItemDerived { // item derived has compatible QtObject type x: 4 } diff --git a/tests/auto/qml/qmllint/data/qmldirImportAndDepend/QtObjectWithDefaultProperty.qml b/tests/auto/qml/qmllint/data/qmldirImportAndDepend/QtObjectWithDefaultProperty.qml new file mode 100644 index 00000000000..fb856d0b298 --- /dev/null +++ b/tests/auto/qml/qmllint/data/qmldirImportAndDepend/QtObjectWithDefaultProperty.qml @@ -0,0 +1,4 @@ +import Things // imports QtQml +QtObject { + default property QtObject child +} diff --git a/tests/auto/qml/qmllint/data/qmldirImportAndDepend/good.qml b/tests/auto/qml/qmllint/data/qmldirImportAndDepend/good.qml index 4e97bd6a647..987301ef76b 100644 --- a/tests/auto/qml/qmllint/data/qmldirImportAndDepend/good.qml +++ b/tests/auto/qml/qmllint/data/qmldirImportAndDepend/good.qml @@ -1,7 +1,6 @@ import Things -QtObject { - default property QtObject child +QtObjectWithDefaultProperty { // for default property objectName: "QtQml was imported from Things/qmldir" ItemDerived { diff --git a/tests/auto/qml/qmllint/data/qmodelIndex.qml b/tests/auto/qml/qmllint/data/qmodelIndex.qml new file mode 100644 index 00000000000..e0df84b68b2 --- /dev/null +++ b/tests/auto/qml/qmllint/data/qmodelIndex.qml @@ -0,0 +1,6 @@ +import QtQml + +QtObject { + property ItemSelectionModel itemSelectionModel; + function row() { return itemSelectionModel.currentIndex.row; } +} diff --git a/tests/auto/qml/qmllint/data/requiredProperty.qml b/tests/auto/qml/qmllint/data/requiredProperty.qml index b10f0f67cd4..f1e82bb402f 100644 --- a/tests/auto/qml/qmllint/data/requiredProperty.qml +++ b/tests/auto/qml/qmllint/data/requiredProperty.qml @@ -1,6 +1,9 @@ -import QtQml 2.15 +import QtQuick 2.15 -QtObject { - property int x - required x +Item { + component Required : QtObject { + property int x + required x + } + Required { x: 5 } } diff --git a/tests/auto/qml/qmllint/data/requiredPropertyBindings.qml b/tests/auto/qml/qmllint/data/requiredPropertyBindings.qml new file mode 100644 index 00000000000..3bba84f4123 --- /dev/null +++ b/tests/auto/qml/qmllint/data/requiredPropertyBindings.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Item { + component Base : Item { + required property string required_now_string + property string required_later_string + + required property QtObject required_now_object + property QtObject required_later_object + } + + component Derived : Base { + required required_later_string + required required_later_object + } + + Derived { + required_now_string: "" + required_later_string: "" + + required_now_object: QtObject {} + required_later_object: QtObject {} + } +} diff --git a/tests/auto/qml/qmllint/data/requiredPropertyBindingsLater.qml b/tests/auto/qml/qmllint/data/requiredPropertyBindingsLater.qml new file mode 100644 index 00000000000..65c59d7161c --- /dev/null +++ b/tests/auto/qml/qmllint/data/requiredPropertyBindingsLater.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Item { + component Base : Item { + required property string required_now_string + property string required_later_string + property string required_even_later_string + } + + component Derived : Base { + required required_later_string + } + + Derived { + required required_even_later_string + required_now_string: "" + } +} diff --git a/tests/auto/qml/qmllint/data/requiredPropertyBindingsNow.qml b/tests/auto/qml/qmllint/data/requiredPropertyBindingsNow.qml new file mode 100644 index 00000000000..701760b4e71 --- /dev/null +++ b/tests/auto/qml/qmllint/data/requiredPropertyBindingsNow.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 + +Item { + component Base : Item { + required property string required_now_string + property string required_later_string + } + + component Derived : Base { + required required_later_string + } + + Derived { + required property string required_defined_here_string + required_later_string: "" + } +} diff --git a/tests/auto/qml/qmllint/data/requiredPropertyInComponent.qml b/tests/auto/qml/qmllint/data/requiredPropertyInComponent.qml new file mode 100644 index 00000000000..24ecf9d7067 --- /dev/null +++ b/tests/auto/qml/qmllint/data/requiredPropertyInComponent.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Row { + // explicit component + Component { + id: foo + Item { + required property int i + } + } + + // implicit component, plain property + property Component com: Item {} + + Repeater { + model: 3 + // implicit component, default property + Text { + required property int index + height: 40 + color: "black" + text: "I'm item " + index + } + } +} diff --git a/tests/auto/qml/qmllint/data/settings/bare/.qmllint.ini b/tests/auto/qml/qmllint/data/settings/bare/.qmllint.ini new file mode 100644 index 00000000000..e419c37f3ae --- /dev/null +++ b/tests/auto/qml/qmllint/data/settings/bare/.qmllint.ini @@ -0,0 +1,2 @@ +[Foo] +DisableDefaultImports=true diff --git a/tests/auto/qml/qmllint/data/settings/bare/bare.qml b/tests/auto/qml/qmllint/data/settings/bare/bare.qml new file mode 100644 index 00000000000..852b8339b97 --- /dev/null +++ b/tests/auto/qml/qmllint/data/settings/bare/bare.qml @@ -0,0 +1,3 @@ +import QtQuick // Should fail because Bare is specified with no import + +Item {} diff --git a/tests/auto/qml/qmllint/data/settings/qmltypes/.qmllint.ini b/tests/auto/qml/qmllint/data/settings/qmltypes/.qmllint.ini new file mode 100644 index 00000000000..95b02f2f379 --- /dev/null +++ b/tests/auto/qml/qmllint/data/settings/qmltypes/.qmllint.ini @@ -0,0 +1,2 @@ +[General] +OverwriteImportTypes=custom.qmltypes diff --git a/tests/auto/qml/qmllint/data/settings/qmltypes/custom.qmltypes b/tests/auto/qml/qmllint/data/settings/qmltypes/custom.qmltypes new file mode 100644 index 00000000000..b3839652dca --- /dev/null +++ b/tests/auto/qml/qmllint/data/settings/qmltypes/custom.qmltypes @@ -0,0 +1,11 @@ +import QtQuick.tooling 1.2 +Module { + dependencies: [] + Component { + name: "Thing" + prototype: "QObject" + exports: [ + "Custom/Thing 1.0", + ] + } +} diff --git a/tests/auto/qml/qmllint/data/settings/qmltypes/qmltypes.qml b/tests/auto/qml/qmllint/data/settings/qmltypes/qmltypes.qml new file mode 100644 index 00000000000..221ddff2549 --- /dev/null +++ b/tests/auto/qml/qmllint/data/settings/qmltypes/qmltypes.qml @@ -0,0 +1,3 @@ +import Custom + +Thing {} diff --git a/tests/auto/qml/qmllint/data/stringAsId.qml b/tests/auto/qml/qmllint/data/stringAsId.qml new file mode 100644 index 00000000000..58ea28cb179 --- /dev/null +++ b/tests/auto/qml/qmllint/data/stringAsId.qml @@ -0,0 +1,5 @@ +import QtQml + +QtObject { + id: "aString" +} diff --git a/tests/auto/qml/qmllint/data/stringIdUsedInWarning.qml b/tests/auto/qml/qmllint/data/stringIdUsedInWarning.qml new file mode 100644 index 00000000000..672c00f39bc --- /dev/null +++ b/tests/auto/qml/qmllint/data/stringIdUsedInWarning.qml @@ -0,0 +1,9 @@ +import QtQml + +QtObject { + id: "stringy" + property int i + property QtObject o: QtObject { + Component.onCompleted: console.log(i) + } +} diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp index ce518171e61..3cdba23872c 100644 --- a/tests/auto/qml/qmllint/tst_qmllint.cpp +++ b/tests/auto/qml/qmllint/tst_qmllint.cpp @@ -30,13 +30,15 @@ #include <QtTest/QtTest> #include <QProcess> #include <QString> - -#include <util.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> class TestQmllint: public QQmlDataTest { Q_OBJECT +public: + TestQmllint(); + private Q_SLOTS: void initTestCase() override; @@ -68,17 +70,27 @@ private Q_SLOTS: void settingsFile(); + void lazyAndDirect(); + + void missingBuiltinsNoCrash(); private: QString runQmllint(const QString &fileToLint, std::function<void(QProcess &)> handleResult, - const QStringList &extraArgs = QStringList(), bool ignoreSettings = true); + const QStringList &extraArgs = QStringList(), bool ignoreSettings = true, + bool addIncludeDirs = true); QString runQmllint(const QString &fileToLint, bool shouldSucceed, - const QStringList &extraArgs = QStringList(), bool ignoreSettings = true); + const QStringList &extraArgs = QStringList(), bool ignoreSettings = true, + bool addIncludeDirs = true); QString m_qmllintPath; QString m_qmljsrootgenPath; QString m_qmltyperegistrarPath; }; +TestQmllint::TestQmllint() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void TestQmllint::initTestCase() { QQmlDataTest::initTestCase(); @@ -158,7 +170,8 @@ void TestQmllint::testUnknownCausesFail() QStringLiteral("Warning: %1: Unknown was not found. Did you add all import paths?").arg(testFile("unknownElement.qml")))); unknownNotFound = runQmllint("TypeWithUnknownPropertyType.qml", false); QVERIFY(unknownNotFound.contains( - QStringLiteral("Warning: %1: Something was not found. Did you add all import paths?") + QStringLiteral( + "Warning: %1:4:5: Something was not found. Did you add all import paths?") .arg(testFile("TypeWithUnknownPropertyType.qml")))); } @@ -179,7 +192,7 @@ void TestQmllint::oldQmltypes() QVERIFY(errors.contains(QStringLiteral("Warning: Found deprecated dependency specifications"))); // Checking for both lines separately so that we don't have to mess with the line endings.b - QVERIFY(errors.contains(QStringLiteral("Meta object revision and export version differ, ignoring the revision."))); + QVERIFY(errors.contains(QStringLiteral("Meta object revision and export version differ."))); QVERIFY(errors.contains(QStringLiteral("Revision 0 corresponds to version 0.0; it should be 1.0."))); } @@ -404,7 +417,7 @@ void TestQmllint::dirtyQmlCode_data() << false; QTest::newRow("nanchors1") << QStringLiteral("nanchors1.qml") - << QString() + << QString("unknown grouped property scope nanchors.") << QString() << false; QTest::newRow("nanchors2") @@ -427,6 +440,9 @@ void TestQmllint::dirtyQmlCode_data() << QString("Warning: %1:5:21: Property \"stuff\" not found on type \"Empty\"") << QString() << false; + QTest::newRow("badScriptOnAttachedProperty") + << QStringLiteral("badScript.attached.qml") + << QString("Warning: %1:3:26: Unqualified access") << QString() << false; QTest::newRow("brokenNamespace") << QStringLiteral("brokenNamespace.qml") << QString("Warning: %1:4:17: Type not found in namespace") @@ -471,6 +487,21 @@ void TestQmllint::dirtyQmlCode_data() "\"doesNotExist\" exists in the current element.") << QString() << false; + QTest::newRow("BadScriptBindingOnGroup") + << QStringLiteral("badScriptBinding.group.qml") + << QStringLiteral("Warning: %1:3:10: Binding assigned to \"bogusProperty\", but no " + "property \"bogusProperty\" exists in the current element.") + << QString() << false; + QTest::newRow("BadScriptBindingOnAttachedType") + << QStringLiteral("badScriptBinding.attached.qml") + << QStringLiteral("Warning: %1:5:12: Binding assigned to \"bogusProperty\", but no " + "property \"bogusProperty\" exists in the current element.") + << QString() << false; + QTest::newRow("BadScriptBindingOnAttachedSignalHandler") + << QStringLiteral("badScriptBinding.attachedSignalHandler.qml") + << QStringLiteral( + "Warning: %1:3:10: no matching signal found for handler \"onBogusSignal\"") + << QString() << false; QTest::newRow("BadPropertyType") << QStringLiteral("badPropertyType.qml") << QStringLiteral("No type found for property \"bad\". This may be due to a missing " @@ -509,8 +540,12 @@ void TestQmllint::dirtyQmlCode_data() << false; QTest::newRow("MissingDefaultProperty") << QStringLiteral("defaultPropertyWithoutKeyword.qml") - << QStringLiteral("Cannot assign to non-existent default property") << QString() << false; - + << QStringLiteral("Cannot assign to non-existent default property") << QString() + << false; + QTest::newRow("MissingDefaultPropertyDefinedInTheSameType") + << QStringLiteral("defaultPropertyWithinTheSameType.qml") + << QStringLiteral("Cannot assign to non-existent default property") << QString() + << false; QTest::newRow("DoubleAssignToDefaultProperty") << QStringLiteral("defaultPropertyWithDoubleAssignment.qml") << QStringLiteral("Cannot assign multiple objects to a default non-list property") @@ -585,6 +620,22 @@ void TestQmllint::dirtyQmlCode_data() << QStringLiteral("Method \"deprecatedInherited(c, d)\" is deprecated (Reason: This deprecation should be visible!)") << QString() << false; + + QTest::newRow("string as id") + << QStringLiteral("stringAsId.qml") + << QStringLiteral("ids do not need quotation marks") + << QString() + << false; + QTest::newRow("stringIdUsedInWarning") + << QStringLiteral("stringIdUsedInWarning.qml") + << QStringLiteral("Component.onCompleted: console.log(stringy.i)") + << QString() + << false; + QTest::newRow("Invalid id (expression)") + << QStringLiteral("invalidId1.qml") + << QStringLiteral("Failed to parse id") + << QString() + << false; QTest::newRow("multilineString") << QStringLiteral("multilineString.qml") << QStringLiteral("String contains unescaped line terminator which is deprecated. Use " @@ -619,6 +670,27 @@ void TestQmllint::dirtyQmlCode_data() QTest::newRow("nestedInlineComponents") << QStringLiteral("nestedInlineComponents.qml") << QStringLiteral("Nested inline components are not supported") << QString() << false; + QTest::newRow("cachedDependency") + << QStringLiteral("cachedDependency.qml") + << QStringLiteral("Unused import at %1:1:1") + << QStringLiteral("Cannot assign binding of type QQuickItem to QObject") + << true; + QTest::newRow("cycle in import") + << QStringLiteral("cycleHead.qml") + << QStringLiteral("MenuItem is part of an inheritance cycle: MenuItem -> MenuItem") + << QString() << false; + QTest::newRow("missingQmltypes") + << QStringLiteral("missingQmltypes.qml") + << QStringLiteral("QML types file does not exist") + << QString() << false; + QTest::newRow("inaccessibleId") + << QStringLiteral("inaccessibleId.qml") + << QStringLiteral("Property \"objectName\" not found on type \"int\"") + << QString() << false; + QTest::newRow("inaccessibleId2") + << QStringLiteral("inaccessibleId2.qml") + << QStringLiteral("Property \"objectName\" not found on type \"int\"") + << QString() << false; } void TestQmllint::dirtyQmlCode() @@ -635,7 +707,6 @@ void TestQmllint::dirtyQmlCode() QVERIFY(process.waitForFinished()); QCOMPARE(process.exitStatus(), QProcess::NormalExit); QEXPECT_FAIL("anchors3", "We don't see that QQuickItem cannot be assigned to QQuickAnchorLine", Abort); - QEXPECT_FAIL("nanchors1", "Invalid grouped properties are not always detected", Abort); QEXPECT_FAIL("TypePropertAccess", "We cannot discern between types and instances", Abort); QEXPECT_FAIL("badAttachedPropertyTypeString", "Script bindings do not perform property type matching", Abort); @@ -754,7 +825,23 @@ void TestQmllint::cleanQmlCode_data() QTest::newRow("qjsroot") << QStringLiteral("qjsroot.qml"); QTest::newRow("InlineComponent") << QStringLiteral("inlineComponent.qml"); QTest::newRow("InlineComponentWithComponents") << QStringLiteral("inlineComponentWithComponents.qml"); + QTest::newRow("InlineComponentsChained") << QStringLiteral("inlineComponentsChained.qml"); QTest::newRow("ignoreWarnings") << QStringLiteral("ignoreWarnings.qml"); + QTest::newRow("BindingBeforeDeclaration") << QStringLiteral("bindingBeforeDeclaration.qml"); + QTest::newRow("CustomParserUnqualifiedAccess") + << QStringLiteral("customParserUnqualifiedAccess.qml"); + QTest::newRow("ImportQMLModule") << QStringLiteral("importQMLModule.qml"); + QTest::newRow("ImportDirectoryQmldir") << QStringLiteral("Things/LintDirectly.qml"); + QTest::newRow("BindingsOnGroupAndAttachedProperties") + << QStringLiteral("goodBindingsOnGroupAndAttached.qml"); + QTest::newRow("QQmlEasingEnums::Type") << QStringLiteral("animationEasing.qml"); + QTest::newRow("required property in Component") << QStringLiteral("requiredPropertyInComponent.qml"); + QTest::newRow("connectionNoParent") << QStringLiteral("connectionNoParent.qml"); // QTBUG-97600 + QTest::newRow("on binding in grouped property") << QStringLiteral("onBindingInGroupedProperty.qml"); + QTest::newRow("multipleGrouped") << QStringLiteral("multiGrouped.qml"); + QTest::newRow("ID overrides property") << QStringLiteral("accessibleId.qml"); + QTest::newRow("qmodelIndex") << QStringLiteral("qmodelIndex.qml"); + QTest::newRow("prefixedAttachedProperty") << QStringLiteral("prefixedAttachedProperty.qml"); } void TestQmllint::cleanQmlCode() @@ -766,14 +853,18 @@ void TestQmllint::cleanQmlCode() QString TestQmllint::runQmllint(const QString &fileToLint, std::function<void(QProcess &)> handleResult, - const QStringList &extraArgs, bool ignoreSettings) + const QStringList &extraArgs, bool ignoreSettings, + bool addIncludeDirs) { auto qmlImportDir = QLibraryInfo::path(QLibraryInfo::QmlImportsPath); QStringList args; - args << (QFileInfo(fileToLint).isAbsolute() ? fileToLint : testFile(fileToLint)) - << QStringLiteral("-I") << qmlImportDir - << QStringLiteral("-I") << dataDirectory(); + args << (QFileInfo(fileToLint).isAbsolute() ? fileToLint : testFile(fileToLint)); + + if (addIncludeDirs) { + args << QStringLiteral("-I") << qmlImportDir + << QStringLiteral("-I") << dataDirectory(); + } if (ignoreSettings) QStringLiteral("--ignore-settings"); @@ -805,7 +896,8 @@ QString TestQmllint::runQmllint(const QString &fileToLint, } QString TestQmllint::runQmllint(const QString &fileToLint, bool shouldSucceed, - const QStringList &extraArgs, bool ignoreSettings) + const QStringList &extraArgs, bool ignoreSettings, + bool addIncludeDirs) { return runQmllint( fileToLint, @@ -818,15 +910,38 @@ QString TestQmllint::runQmllint(const QString &fileToLint, bool shouldSucceed, else QVERIFY(process.exitCode() != 0); }, - extraArgs, ignoreSettings); + extraArgs, ignoreSettings, addIncludeDirs); } void TestQmllint::requiredProperty() { QVERIFY(runQmllint("requiredProperty.qml", true).isEmpty()); - const QString errors = runQmllint("requiredMissingProperty.qml", false); - QVERIFY(errors.contains(QStringLiteral("Property \"foo\" was marked as required but does not exist."))); + { + const QString errors = runQmllint("requiredMissingProperty.qml", false); + QVERIFY(errors.contains( + QStringLiteral("Property \"foo\" was marked as required but does not exist."))); + } + + QVERIFY(runQmllint("requiredPropertyBindings.qml", true).isEmpty()); + + { + const QString errors = runQmllint("requiredPropertyBindingsNow.qml", false); + QVERIFY(errors.contains(QStringLiteral( + "Component is missing required property required_now_string from Base"))); + QVERIFY(errors.contains(QStringLiteral( + "Component is missing required property required_defined_here_string from here"))); + } + + { + const QString errors = runQmllint("requiredPropertyBindingsLater.qml", false); + QVERIFY(errors.contains( + QStringLiteral("Component is missing required property required_later_string from " + "Base (marked as required by Derived)"))); + QVERIFY(errors.contains( + QStringLiteral("Component is missing required property required_even_later_string " + "from Base (marked as required by here)"))); + } } void TestQmllint::settingsFile() @@ -836,6 +951,22 @@ void TestQmllint::settingsFile() QVERIFY(runQmllint("settings/unusedImportWarning/unused.qml", false, QStringList(), false) .contains(QStringLiteral("Warning: %1:2:1: Unused import at %1:2:1") .arg(testFile("settings/unusedImportWarning/unused.qml")))); + QVERIFY(runQmllint("settings/bare/bare.qml", false, { "--bare" }, false, false) + .contains(QStringLiteral("Failed to find the following builtins: " + "builtins.qmltypes, jsroot.qmltypes"))); + QVERIFY(runQmllint("settings/qmltypes/qmltypes.qml", true, QStringList(), false).isEmpty()); +} + +void TestQmllint::lazyAndDirect() +{ + QVERIFY(runQmllint("LazyAndDirect/Lazy.qml", true, {}, false).isEmpty()); +} + +void TestQmllint::missingBuiltinsNoCrash() +{ + QVERIFY(runQmllint("missingBuiltinsNoCrash.qml", false, { "--bare" }, false, false) + .contains(QStringLiteral("Failed to find the following builtins: " + "builtins.qmltypes, jsroot.qmltypes"))); } QTEST_MAIN(TestQmllint) diff --git a/tests/auto/qml/qmlplugindump/CMakeLists.txt b/tests/auto/qml/qmlplugindump/CMakeLists.txt index 1bf13a2c029..96eea009382 100644 --- a/tests/auto/qml/qmlplugindump/CMakeLists.txt +++ b/tests/auto/qml/qmlplugindump/CMakeLists.txt @@ -6,15 +6,13 @@ qt_internal_add_test(tst_qmlplugindump SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qmlplugindump.cpp DEFINES QT_QMLTEST_DIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::GuiPrivate Qt::Qml + Qt::QuickTestUtilsPrivate ) ## Scopes: diff --git a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp index 17e67269f3b..542c1974c57 100644 --- a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp +++ b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp @@ -26,14 +26,13 @@ ** ****************************************************************************/ -#include "util.h" - #include <qtest.h> #include <QLibraryInfo> #include <QDir> #include <QProcess> #include <QDebug> #include <cstdlib> +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qmlplugindump : public QQmlDataTest { @@ -56,6 +55,7 @@ private slots: }; tst_qmlplugindump::tst_qmlplugindump() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } diff --git a/tests/auto/qml/qmltyperegistrar/CMakeLists.txt b/tests/auto/qml/qmltyperegistrar/CMakeLists.txt index 674dc08056c..02a0347ac29 100644 --- a/tests/auto/qml/qmltyperegistrar/CMakeLists.txt +++ b/tests/auto/qml/qmltyperegistrar/CMakeLists.txt @@ -7,6 +7,16 @@ qt_manual_moc(moc_files OUTPUT_MOC_JSON_FILES json_list noextheader INCLUDE_DIRECTORY_TARGETS Qt::Qml) +# Dummy target to pass --private-includes to qmltyperegistrar for tst_qmltyperegistrar. +# We want to test that it expects files named foo_p.h appearing in foreign metatypes +# to be in a private/ subdirectory. In particular, we have a foreign_p.h to exercise this. +# TODO: There should be more fine grained control over this. +qt_add_library(tst_qmltyperegistrarPrivate STATIC + dummy.cpp dummy_p.h +) + +target_link_libraries(tst_qmltyperegistrarPrivate PRIVATE Qt::Core) + qt_internal_add_test(tst_qmltyperegistrar SOURCES hppheader.hpp @@ -20,6 +30,7 @@ qt_internal_add_test(tst_qmltyperegistrar # Remove: Lforeign Qt::Qml foreign + tst_qmltyperegistrarPrivate ) #### Keys ignored in scope 2:.:.:tst_qmltyperegistrar.pro:<TRUE>: @@ -33,12 +44,27 @@ qt_internal_add_test(tst_qmltyperegistrar ## Scopes: ##################################################################### +# Simulate conditions that qt6_add_qml_module() would normally set up for us set_target_properties(tst_qmltyperegistrar PROPERTIES QT_QML_MODULE_VERSION 1.0 - QT_QML_PAST_MAJOR_VERSIONS 0 + QT_QML_MODULE_PAST_MAJOR_VERSIONS 0 QT_QML_MODULE_URI QmlTypeRegistrarTest - QT_QMLTYPES_FILENAME tst_qmltyperegistrar.qmltypes + QT_QML_MODULE_TYPEINFO tst_qmltyperegistrar.qmltypes + QT_QML_MODULE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) -qt6_qml_type_registration(tst_qmltyperegistrar MANUAL_MOC_JSON_FILES ${json_list}) # special case +# qt6_add_qml_module() doesn't allow us to pass through MANUAL_MOC_JSON_FILES +# yet, so we have to call it directly to test that code path for now. +_qt_internal_qml_type_registration(tst_qmltyperegistrar MANUAL_MOC_JSON_FILES ${json_list}) add_subdirectory(foreign) + +qt_add_library(tst-qmltyperegistrar-with-dashes) +target_link_libraries(tst-qmltyperegistrar-with-dashes PRIVATE Qt::Core Qt::Qml) +qt_enable_autogen_tool(tst-qmltyperegistrar-with-dashes "moc" ON) +qt_add_qml_module(tst-qmltyperegistrar-with-dashes + URI Module-With-Dashes + VERSION 1.0 + SOURCES + foo.cpp foo.h +) +qt_autogen_tools_initial_setup(tst-qmltyperegistrar-with-dashesplugin) diff --git a/tests/auto/qml/qmltyperegistrar/dummy.cpp b/tests/auto/qml/qmltyperegistrar/dummy.cpp new file mode 100644 index 00000000000..1959bc38161 --- /dev/null +++ b/tests/auto/qml/qmltyperegistrar/dummy.cpp @@ -0,0 +1,2 @@ +#include "dummy_p.h" +int foo() { return 1; } diff --git a/tests/auto/qml/qmltyperegistrar/dummy_p.h b/tests/auto/qml/qmltyperegistrar/dummy_p.h new file mode 100644 index 00000000000..e564d3b549f --- /dev/null +++ b/tests/auto/qml/qmltyperegistrar/dummy_p.h @@ -0,0 +1,2 @@ +#include <QtCore/qglobal.h> +Q_DECL_EXPORT int foo(); diff --git a/tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt b/tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt index ad967cdbf0e..81d4b00aa3a 100644 --- a/tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt +++ b/tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt @@ -7,7 +7,7 @@ qt_internal_add_cmake_library(foreign STATIC SOURCES - foreign.cpp foreign.h + foreign.cpp foreign.h foreign_p.h PUBLIC_LIBRARIES Qt::Core ) diff --git a/tests/auto/qml/qmltyperegistrar/foreign/foreign_p.h b/tests/auto/qml/qmltyperegistrar/foreign/foreign_p.h new file mode 100644 index 00000000000..8ea292c0155 --- /dev/null +++ b/tests/auto/qml/qmltyperegistrar/foreign/foreign_p.h @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 FOREIGN_P_H +#define FOREIGN_P_H + +#include <QtCore/qobject.h> + +// qmltyperegistrar will assume this file is reachable under <private/foreign_p.h> +// It's not true, but this is how it works on actual private headers in Qt. +// See the trick in tst_qmltyperegistrar's CMakeLists.txt to turn on the --private-includes option. +class ForeignPrivate : public QObject +{ + Q_OBJECT +Q_SIGNALS: + void happens(); +}; + +#endif // FOREIGN_P_H diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp index f11f5d64048..27f83ca22f4 100644 --- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp +++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp @@ -288,4 +288,23 @@ void tst_qmltyperegistrar::namespacesAndValueTypes() check(QMetaType::fromName("ValueTypeWithEnum2"), QMetaType::fromType<ValueTypeWithEnum2>()); } +void tst_qmltyperegistrar::derivedFromForeignPrivate() +{ + QVERIFY(qmltypesData.contains("file: \"private/foreign_p.h\"")); +} + +void tst_qmltyperegistrar::methodReturnType() +{ + QVERIFY(qmltypesData.contains("createAThing")); + QVERIFY(!qmltypesData.contains("QQmlComponent*")); + QVERIFY(qmltypesData.contains("type: \"QQmlComponent\"")); +} + +void tst_qmltyperegistrar::omitInvisible() +{ + // If it cannot resolve the type a QML_FOREIGN refers to, it should not generate anything. + QVERIFY(qmltypesData.contains( + R"(Component { file: "tst_qmltyperegistrar.h"; name: "Invisible"; accessSemantics: "none" })")); +} + QTEST_MAIN(tst_qmltyperegistrar) diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h index 2a8423c6829..1372c32d02e 100644 --- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h +++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h @@ -30,8 +30,10 @@ #define TST_QMLTYPEREGISTRAR_H #include "foreign.h" +#include "foreign_p.h" #include <QtQml/qqml.h> +#include <QtQml/qqmlcomponent.h> #include <QtCore/qproperty.h> #include <QtCore/qtimeline.h> #include <QtCore/qrect.h> @@ -382,6 +384,31 @@ struct BValueTypeWithEnumForeign2 QML_NAMED_ELEMENT(valueTypeWithEnum2) }; +class DerivedFromForeignPrivate : public ForeignPrivate +{ + Q_OBJECT + QML_ELEMENT +}; + +class WithMethod : public QObject +{ + Q_OBJECT + QML_ELEMENT +public: + Q_INVOKABLE QQmlComponent *createAThing(int) { return nullptr; } +}; + +class Invisible : public QObject +{ +}; + +struct InvisibleForeign +{ + Q_GADGET + QML_FOREIGN(Invisible) + QML_NAMED_ELEMENT(Invisible) +}; + class tst_qmltyperegistrar : public QObject { Q_OBJECT @@ -411,6 +438,9 @@ private slots: void finalProperty(); void parentProperty(); void namespacesAndValueTypes(); + void derivedFromForeignPrivate(); + void methodReturnType(); + void omitInvisible(); private: QByteArray qmltypesData; diff --git a/tests/auto/qml/qqmlanybinding/CMakeLists.txt b/tests/auto/qml/qqmlanybinding/CMakeLists.txt index 83c9bd79945..32efa891ea9 100644 --- a/tests/auto/qml/qqmlanybinding/CMakeLists.txt +++ b/tests/auto/qml/qqmlanybinding/CMakeLists.txt @@ -10,17 +10,15 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlanybinding SOURCES - ../../shared/util.cpp ../../shared/util.h withbindable.h tst_qqmlanybinding.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::Network Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -29,7 +27,7 @@ set_target_properties(tst_qqmlanybinding PROPERTIES QT_QML_MODULE_URI bindable ) -qt6_qml_type_registration(tst_qqmlanybinding) +_qt_internal_qml_type_registration(tst_qqmlanybinding) ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qqmlanybinding/tst_qqmlanybinding.cpp b/tests/auto/qml/qqmlanybinding/tst_qqmlanybinding.cpp index b7ea29ddd35..76f8f9e89e2 100644 --- a/tests/auto/qml/qqmlanybinding/tst_qqmlanybinding.cpp +++ b/tests/auto/qml/qqmlanybinding/tst_qqmlanybinding.cpp @@ -25,23 +25,31 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "../../shared/util.h" #include <QtQml/QQmlEngine> #include <QtQml/QQmlComponent> #include <QtCore/QScopedPointer> #include <QtQml/private/qqmlanybinding_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> #include "withbindable.h" class tst_qqmlanybinding : public QQmlDataTest { Q_OBJECT +public: + tst_qqmlanybinding(); + private slots: void basicActions_data(); void basicActions(); void unboundQQmlPropertyBindingDoesNotCrash(); }; +tst_qqmlanybinding::tst_qqmlanybinding() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qqmlanybinding::basicActions_data() { QTest::addColumn<QString>("fileName"); diff --git a/tests/auto/qml/qqmlanybinding/withbindable.h b/tests/auto/qml/qqmlanybinding/withbindable.h index 4488c0c350f..be39d42eb7c 100644 --- a/tests/auto/qml/qqmlanybinding/withbindable.h +++ b/tests/auto/qml/qqmlanybinding/withbindable.h @@ -29,6 +29,7 @@ #define WITH_BINDABLE_H #include <QObject> +#include <QtCore/qproperty.h> #include <qqml.h> class WithBinding : public QObject { diff --git a/tests/auto/qml/qqmlapplicationengine/CMakeLists.txt b/tests/auto/qml/qqmlapplicationengine/CMakeLists.txt index ea88b6c8e33..caf1e2edaa7 100644 --- a/tests/auto/qml/qqmlapplicationengine/CMakeLists.txt +++ b/tests/auto/qml/qqmlapplicationengine/CMakeLists.txt @@ -12,15 +12,13 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlapplicationengine SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlapplicationengine.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::GuiPrivate Qt::Network Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -37,6 +35,9 @@ qt_internal_add_resource(tst_qqmlapplicationengine "tst_qqmlapplicationengine" ${tst_qqmlapplicationengine_resource_files} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmlapplicationengine) +endif() #### Keys ignored in scope 2:.:.:tst_qqmlapplicationengine.pro:<TRUE>: # TRANSLATIONS = "data/i18n/qml_ja.ts" @@ -54,3 +55,4 @@ qt_internal_extend_target(tst_qqmlapplicationengine CONDITION NOT ANDROID AND NO QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" ) add_subdirectory(testapp) +add_subdirectory(androidassets) diff --git a/tests/auto/qml/qqmlapplicationengine/androidassets/CMakeLists.txt b/tests/auto/qml/qqmlapplicationengine/androidassets/CMakeLists.txt new file mode 100644 index 00000000000..1c0d3053111 --- /dev/null +++ b/tests/auto/qml/qqmlapplicationengine/androidassets/CMakeLists.txt @@ -0,0 +1,18 @@ +qt_internal_add_test(tst_androidassets + SOURCES + tst_androidassets.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Qml + Qt::Quick +) + +# add qml/*.qml files as assets instead of resources + +file( + COPY qml/main.qml + DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/android-build/assets/qml/") + +file( + COPY qml/pages/MainPage.qml + DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/android-build/assets/qml/pages/") diff --git a/tests/auto/qml/qqmlapplicationengine/androidassets/qml/main.qml b/tests/auto/qml/qqmlapplicationengine/androidassets/qml/main.qml new file mode 100644 index 00000000000..6901572b00c --- /dev/null +++ b/tests/auto/qml/qqmlapplicationengine/androidassets/qml/main.qml @@ -0,0 +1,13 @@ +import QtQuick + +// relative import: has to work when loading from android assets by path or by URL +import "pages" + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Hello World") + + MainPage { } +} diff --git a/tests/auto/qml/qqmlapplicationengine/androidassets/qml/pages/MainPage.qml b/tests/auto/qml/qqmlapplicationengine/androidassets/qml/pages/MainPage.qml new file mode 100644 index 00000000000..c9549a928a6 --- /dev/null +++ b/tests/auto/qml/qqmlapplicationengine/androidassets/qml/pages/MainPage.qml @@ -0,0 +1,11 @@ +import QtQuick + +Rectangle { + anchors.fill: parent + color: "#ddd" + + Text { + anchors.centerIn: parent + text: "Qt 6" + } +} diff --git a/tests/auto/qml/qqmlapplicationengine/androidassets/tst_androidassets.cpp b/tests/auto/qml/qqmlapplicationengine/androidassets/tst_androidassets.cpp new file mode 100644 index 00000000000..0751e23f458 --- /dev/null +++ b/tests/auto/qml/qqmlapplicationengine/androidassets/tst_androidassets.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <QtQml/qqmlapplicationengine.h> +#include <QtTest/qsignalspy.h> +#include <QtTest/qtest.h> + +class tst_AndroidAssets : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void loadsFromAssetsPath(); + void loadsFromAssetsUrl(); + +private: + + static QString pathPrefix() + { +#ifdef Q_OS_ANDROID + return QStringLiteral("assets:"); +#else + // Even when not running on android we can check that the copying to build dir worked. + return QCoreApplication::applicationDirPath() + QStringLiteral("/android-build/assets"); +#endif + } + + static QString urlPrefix() { +#ifdef Q_OS_ANDROID + return pathPrefix(); +#else + return QStringLiteral("file:") + pathPrefix(); +#endif + } +}; + + +void tst_AndroidAssets::loadsFromAssetsPath() +{ + QQmlApplicationEngine engine; + + // load QML file from assets, by path: + engine.load(pathPrefix() + QStringLiteral("/qml/main.qml")); + QTRY_VERIFY(engine.rootObjects().length() == 1); +} + +void tst_AndroidAssets::loadsFromAssetsUrl() +{ + QQmlApplicationEngine engine; + + // load QML file from assets, by URL: + engine.load(QUrl(urlPrefix() + QStringLiteral("/qml/main.qml"))); + QTRY_VERIFY(engine.rootObjects().length() == 1); +} + +QTEST_MAIN(tst_AndroidAssets) + +#include "tst_androidassets.moc" diff --git a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp index a35375d6f3c..c948ad5b9c1 100644 --- a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp +++ b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp @@ -26,7 +26,6 @@ ** ****************************************************************************/ -#include "../../shared/util.h" #include <QQmlApplicationEngine> #include <QScopedPointer> #include <QSignalSpy> @@ -35,12 +34,13 @@ #include <QProcess> #endif #include <QDebug> +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlapplicationengine : public QQmlDataTest { Q_OBJECT public: - tst_qqmlapplicationengine() {} + tst_qqmlapplicationengine() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: @@ -101,6 +101,10 @@ void tst_qqmlapplicationengine::basicLoading() // will break. void tst_qqmlapplicationengine::testNonResolvedPath() { +#if defined(Q_OS_INTEGRITY) + QSKIP("INTEGRITY stores QML files in resources, and the path to a resource cannot be relative in this case"); +#endif + #ifdef Q_OS_ANDROID QSKIP("Android stores QML files in resources, and the path to a resource cannot be relative in this case"); #endif @@ -162,6 +166,11 @@ void tst_qqmlapplicationengine::application() #if QT_CONFIG(process) QDir::setCurrent(buildDir); QProcess *testProcess = new QProcess(this); +#ifdef Q_OS_QNX + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.insert("QT_FORCE_STDERR_LOGGING", "1"); // QTBUG-76546 + testProcess->setProcessEnvironment(env); +#endif QStringList args; args << qmlFile; // QML file passed as an argument is going to be run by testapp. testProcess->start(QLatin1String("testapp/testapp"), args); diff --git a/tests/auto/qml/qqmlbinding/CMakeLists.txt b/tests/auto/qml/qqmlbinding/CMakeLists.txt index 6bf16689704..78445283e46 100644 --- a/tests/auto/qml/qqmlbinding/CMakeLists.txt +++ b/tests/auto/qml/qqmlbinding/CMakeLists.txt @@ -12,17 +12,15 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlbinding SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlbinding.cpp WithBindableProperties.h - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -31,7 +29,7 @@ set_target_properties(tst_qqmlbinding PROPERTIES QT_QML_MODULE_VERSION 1.0 ) -qt6_qml_type_registration(tst_qqmlbinding) +_qt_internal_qml_type_registration(tst_qqmlbinding) ## Scopes: diff --git a/tests/auto/qml/qqmlbinding/WithBindableProperties.h b/tests/auto/qml/qqmlbinding/WithBindableProperties.h index 562b445df7c..78665044954 100644 --- a/tests/auto/qml/qqmlbinding/WithBindableProperties.h +++ b/tests/auto/qml/qqmlbinding/WithBindableProperties.h @@ -30,6 +30,7 @@ #include <QObject> #include <qqml.h> +#include <QtCore/qproperty.h> class WithBindableProperties : public QObject diff --git a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp index c0c96ca6e56..328bc57447c 100644 --- a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp +++ b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp @@ -30,7 +30,7 @@ #include <QtQml/qqmlcomponent.h> #include <private/qqmlbind_p.h> #include <QtQuick/private/qquickrectangle_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include "WithBindableProperties.h" class tst_qqmlbinding : public QQmlDataTest @@ -66,6 +66,7 @@ private slots: }; tst_qqmlbinding::tst_qqmlbinding() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } @@ -377,6 +378,10 @@ void tst_qqmlbinding::disabledOnReadonlyProperty() void tst_qqmlbinding::delayed() { +#ifdef Q_OS_ANDROID + QSKIP("This test crashes on Android. QTBUG-103310"); +#endif + QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("delayed.qml")); QScopedPointer<QQuickItem> item {qobject_cast<QQuickItem*>(c.create())}; diff --git a/tests/auto/qml/qqmlchangeset/CMakeLists.txt b/tests/auto/qml/qqmlchangeset/CMakeLists.txt index da06b85fad9..510e3047174 100644 --- a/tests/auto/qml/qqmlchangeset/CMakeLists.txt +++ b/tests/auto/qml/qqmlchangeset/CMakeLists.txt @@ -1,10 +1,10 @@ # Generated from qqmlchangeset.pro. ##################################################################### -## tst_qqmlhangeset Test: +## tst_qqmlchangeset Test: ##################################################################### -qt_internal_add_test(tst_qqmlhangeset +qt_internal_add_test(tst_qqmlchangeset SOURCES tst_qqmlchangeset.cpp PUBLIC_LIBRARIES diff --git a/tests/auto/qml/qqmlcomponent/CMakeLists.txt b/tests/auto/qml/qqmlcomponent/CMakeLists.txt index c7dd50e8d6c..7ef68135c99 100644 --- a/tests/auto/qml/qqmlcomponent/CMakeLists.txt +++ b/tests/auto/qml/qqmlcomponent/CMakeLists.txt @@ -12,11 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlcomponent SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h tst_qqmlcomponent.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -24,6 +20,7 @@ qt_internal_add_test(tst_qqmlcomponent Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlcomponent/data/RequiredPropertiesInAttached.qml b/tests/auto/qml/qqmlcomponent/data/RequiredPropertiesInAttached.qml new file mode 100644 index 00000000000..ac496b61316 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/RequiredPropertiesInAttached.qml @@ -0,0 +1,6 @@ +import qt.test 1.0 +import QtQml +QtObject { + AttachedRequiredProperty.index: -1 + AttachedRequiredProperty.name: "minus one" +} // error: we don't support required attached properties diff --git a/tests/auto/qml/qqmlcomponent/data/RequiredPropertiesInGroup.qml b/tests/auto/qml/qqmlcomponent/data/RequiredPropertiesInGroup.qml new file mode 100644 index 00000000000..786a2936478 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/RequiredPropertiesInGroup.qml @@ -0,0 +1,5 @@ +import qt.test 1.0 +GroupedRequiredProperty { + group.index: 42 + group.name: "foobar" +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredSetInSameFile.qml b/tests/auto/qml/qqmlcomponent/data/RequiredSetInSameFile.qml similarity index 100% rename from tests/auto/qml/qqmlcomponent/data/requiredSetInSameFile.qml rename to tests/auto/qml/qqmlcomponent/data/RequiredSetInSameFile.qml diff --git a/tests/auto/qml/qqmlcomponent/data/RequiredTwoPropertiesSet.qml b/tests/auto/qml/qqmlcomponent/data/RequiredTwoPropertiesSet.qml new file mode 100644 index 00000000000..a9253034032 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/RequiredTwoPropertiesSet.qml @@ -0,0 +1,6 @@ +import qt.test 1.0 +TwoRequiredProperties { + id: test + index: 1 + name: "foobar" +} diff --git a/tests/auto/qml/qqmlcomponent/data/RerequiredNotSet.qml b/tests/auto/qml/qqmlcomponent/data/RerequiredNotSet.qml new file mode 100644 index 00000000000..2dd33e81967 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/RerequiredNotSet.qml @@ -0,0 +1,3 @@ +RequiredSetInSameFile { + required i +} // error: we explicitly want required here, but it's not set diff --git a/tests/auto/qml/qqmlcomponent/data/jsmodule/module.mjs b/tests/auto/qml/qqmlcomponent/data/jsmodule/module.mjs index 3dd3507d455..9175ba0a670 100644 --- a/tests/auto/qml/qqmlcomponent/data/jsmodule/module.mjs +++ b/tests/auto/qml/qqmlcomponent/data/jsmodule/module.mjs @@ -1,5 +1,6 @@ export function withProp(root) { - const component = Qt.createComponent("data/jsmodule/Dynamic.qml"); + const prefix = Qt.platform.os == "android" ? "qrc:" : ""; + const component = Qt.createComponent(prefix + "data/jsmodule/Dynamic.qml"); const el = component.createObject(root, { value: 42 }); return el.value; } diff --git a/tests/auto/qml/qqmlcomponent/data/removeBinding.qml b/tests/auto/qml/qqmlcomponent/data/removeBinding.qml new file mode 100644 index 00000000000..08126a1db20 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/removeBinding.qml @@ -0,0 +1,21 @@ +import QtQml 2.15 + +QtObject { + id: root + objectName: "400" + + property Component c: Component { + id: customItem + QtObject { + objectName: root.objectName + } + } + + property string result: { + const properties = { + "objectName": "42", + } + const item = customItem.createObject(root, properties) + return item.objectName; + } +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredChildOfBadBase.qml b/tests/auto/qml/qqmlcomponent/data/requiredChildOfBadBase.qml new file mode 100644 index 00000000000..b75f06d5d3f --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredChildOfBadBase.qml @@ -0,0 +1 @@ +BaseWithRequired {} // fails as required property not set diff --git a/tests/auto/qml/qqmlcomponent/data/requiredChildOfGoodBase.qml b/tests/auto/qml/qqmlcomponent/data/requiredChildOfGoodBase.qml new file mode 100644 index 00000000000..31d2d3065b8 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredChildOfGoodBase.qml @@ -0,0 +1 @@ +RequiredSetInSameFile {} // succeeds as required property is set diff --git a/tests/auto/qml/qqmlcomponent/data/requiredGroup.bad.qml b/tests/auto/qml/qqmlcomponent/data/requiredGroup.bad.qml new file mode 100644 index 00000000000..744c9131dc7 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredGroup.bad.qml @@ -0,0 +1,3 @@ +import qt.test 1.0 +RequiredGroup { +} // error: required group property is not set diff --git a/tests/auto/qml/qqmlcomponent/data/requiredGroup.good.qml b/tests/auto/qml/qqmlcomponent/data/requiredGroup.good.qml new file mode 100644 index 00000000000..836b4c69682 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredGroup.good.qml @@ -0,0 +1,4 @@ +import qt.test 1.0 +RequiredGroup { + group.disabled.buttonText: "salmon" +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInAttached.bad.qml b/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInAttached.bad.qml new file mode 100644 index 00000000000..6a55a066886 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInAttached.bad.qml @@ -0,0 +1,7 @@ +import qt.test 1.0 +import QtQml +QtObject { + AttachedRequiredProperty.onIndexChanged: { + var s = "this is just to trigger the attachment" + } +} // error: we don't support required attached properties diff --git a/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInAttached.bad2.qml b/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInAttached.bad2.qml new file mode 100644 index 00000000000..5ae49fd26a9 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInAttached.bad2.qml @@ -0,0 +1,5 @@ +import qt.test 1.0 +import QtQml +QtObject { + AttachedRequiredProperty.index: -1 +} // error: we don't support required attached properties diff --git a/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInAttachedIndirect.qml b/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInAttachedIndirect.qml new file mode 100644 index 00000000000..5993845cef2 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInAttachedIndirect.qml @@ -0,0 +1,4 @@ +import qt.test 1.0 +RequiredPropertiesInAttached { + AttachedRequiredProperty.index: -1 +} // error: we don't support required attached properties diff --git a/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInGroup.bad.qml b/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInGroup.bad.qml new file mode 100644 index 00000000000..7a3364f056f --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInGroup.bad.qml @@ -0,0 +1,2 @@ +import qt.test 1.0 +GroupedRequiredProperty {} // error (required properties not set) diff --git a/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInGroup.bad2.qml b/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInGroup.bad2.qml new file mode 100644 index 00000000000..cde4278a71f --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInGroup.bad2.qml @@ -0,0 +1,5 @@ +import qt.test 1.0 +GroupedRequiredProperty { + group.index: 42 + // error (group.name is not set) +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInGroupIndirect.qml b/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInGroupIndirect.qml new file mode 100644 index 00000000000..71e66ff3a70 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredPropertiesInGroupIndirect.qml @@ -0,0 +1,5 @@ +import qt.test 1.0 +RequiredPropertiesInGroup { + group.index: 44 + // should succeed as there's a binding on group.name in the base type +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponent.bad.qml b/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponent.bad.qml new file mode 100644 index 00000000000..9954dd58134 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponent.bad.qml @@ -0,0 +1,8 @@ +import QtQuick +Item { + component RequiredPropertyType : QtObject { + required property int i + } + + RequiredPropertyType {} // should fail +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponent.good.qml b/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponent.good.qml new file mode 100644 index 00000000000..29506b7dd44 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponent.good.qml @@ -0,0 +1,9 @@ +import QtQuick +Item { + component RequiredPropertyType : QtObject { + required property int i + i: 42 + } + + RequiredPropertyType {} // should succeed +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponentWithCppBase.bad.qml b/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponentWithCppBase.bad.qml new file mode 100644 index 00000000000..8a83d8979cf --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponentWithCppBase.bad.qml @@ -0,0 +1,9 @@ +import QtQuick +import qt.test 1.0 +Item { + component RequiredPropertyType : TwoRequiredProperties { + index: 0 + // but name is unset + } + RequiredPropertyType {} // should fail (name is not initialized) +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponentWithCppBase.good.qml b/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponentWithCppBase.good.qml new file mode 100644 index 00000000000..3e99554ffde --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponentWithCppBase.good.qml @@ -0,0 +1,9 @@ +import QtQuick +import qt.test 1.0 +Item { + component RequiredPropertyType : TwoRequiredProperties { + index: 11 + name: "foobar" + } + RequiredPropertyType {} // should succeed +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponentWithIndirectCppBase.qml b/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponentWithIndirectCppBase.qml new file mode 100644 index 00000000000..294a9f0172c --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredPropertyInlineComponentWithIndirectCppBase.qml @@ -0,0 +1,6 @@ +import QtQuick +import qt.test 1.0 +Item { + component RequiredPropertyType : RequiredTwoPropertiesSet { } + RequiredPropertyType {} // should succeed +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredSetLater.rerequired.qml b/tests/auto/qml/qqmlcomponent/data/requiredSetLater.rerequired.qml new file mode 100644 index 00000000000..975f797a202 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredSetLater.rerequired.qml @@ -0,0 +1,3 @@ +RerequiredNotSet { + i: 43 +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredTwoProperties.qml b/tests/auto/qml/qqmlcomponent/data/requiredTwoProperties.qml new file mode 100644 index 00000000000..10ce79de33a --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredTwoProperties.qml @@ -0,0 +1,5 @@ +import qt.test 1.0 +TwoRequiredProperties { + id: test + index: 1 // this property is fine +} diff --git a/tests/auto/qml/qqmlcomponent/data/requiredTwoPropertiesDummy.qml b/tests/auto/qml/qqmlcomponent/data/requiredTwoPropertiesDummy.qml new file mode 100644 index 00000000000..4e084fabd6c --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/requiredTwoPropertiesDummy.qml @@ -0,0 +1 @@ +RequiredTwoPropertiesSet {} // no error is expected diff --git a/tests/auto/qml/qqmlcomponent/data/rerequiredSet.qml b/tests/auto/qml/qqmlcomponent/data/rerequiredSet.qml new file mode 100644 index 00000000000..316d5b3f4ba --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/rerequiredSet.qml @@ -0,0 +1,4 @@ +RequiredSetInSameFile { + required i + i: 43 +} diff --git a/tests/auto/qml/qqmlcomponent/data/rerequiredSetLater.qml b/tests/auto/qml/qqmlcomponent/data/rerequiredSetLater.qml new file mode 100644 index 00000000000..4e314310956 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/rerequiredSetLater.qml @@ -0,0 +1,4 @@ +RerequiredNotSet { + required i + i: 43 +} // note: even though parent type is borked, this type is fine diff --git a/tests/auto/qml/qqmlcomponent/data/shadowingFromCpp.qml b/tests/auto/qml/qqmlcomponent/data/shadowingFromCpp.qml new file mode 100644 index 00000000000..01d9c27e035 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/shadowingFromCpp.qml @@ -0,0 +1,5 @@ +import qt.test 1.0 +ShadowedRequiredProperty { + id: test + index: 1 // this property is fine +} diff --git a/tests/auto/qml/qqmlcomponent/data/shadowingFromQmlChild.qml b/tests/auto/qml/qqmlcomponent/data/shadowingFromQmlChild.qml new file mode 100644 index 00000000000..111c5580b87 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/shadowingFromQmlChild.qml @@ -0,0 +1,6 @@ +import qt.test 1.0 +TwoRequiredProperties { + id: test + index: 1 // this property is fine + property string name: "overwritten and not required" +} diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp index a1ee52554b2..7ebe44faa86 100644 --- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp +++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp @@ -35,13 +35,14 @@ #include <QtQuick> #include <QtQuick/private/qquickrectangle_p.h> #include <QtQuick/private/qquickmousearea_p.h> +#include <QtQuick/private/qquickpalette_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/testhttpserver_p.h> #include <private/qqmlguardedcontextdata_p.h> #include <private/qv4qmlcontext_p.h> #include <private/qv4scopedvalue_p.h> #include <private/qv4qmlcontext_p.h> #include <qcolor.h> -#include "../../shared/util.h" -#include "testhttpserver.h" #include <algorithm> @@ -98,7 +99,7 @@ class tst_qqmlcomponent : public QQmlDataTest { Q_OBJECT public: - tst_qqmlcomponent() { engine.setIncubationController(&ic); } + tst_qqmlcomponent() : QQmlDataTest(QT_QMLTEST_DATADIR) { engine.setIncubationController(&ic); } private slots: void null(); @@ -129,6 +130,7 @@ private slots: void testSetInitialProperties(); void createInsideJSModule(); void qmlErrorIsReported(); + void removeBinding(); private: QQmlEngine engine; @@ -686,20 +688,117 @@ class RequiredDefaultCpp : public QObject QQuickItem *m_defaultProperty = nullptr; }; +class TwoRequiredProperties : public QObject +{ + Q_OBJECT + Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged REQUIRED) + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged REQUIRED) + + int m_index = 0; + QString m_name; + +public: + TwoRequiredProperties(QObject *parent = nullptr) : QObject(parent) { } + + int index() const { return m_index; } + QString name() const { return m_name; } + + void setIndex(int x) + { + if (m_index == x) + return; + m_index = x; + Q_EMIT indexChanged(); + } + void setName(const QString &x) + { + if (m_name == x) + return; + m_name = x; + Q_EMIT nameChanged(); + } + +Q_SIGNALS: + void indexChanged(); + void nameChanged(); +}; + +class ShadowedRequiredProperty : public TwoRequiredProperties +{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged /* REQUIRED */) + // Note: should be able to take methods from the base class +}; + +class AttachedRequiredProperties : public QObject +{ + Q_OBJECT + QML_ATTACHED(TwoRequiredProperties) +public: + AttachedRequiredProperties(QObject *parent = nullptr) : QObject(parent) { } + static TwoRequiredProperties *qmlAttachedProperties(QObject *parent) + { + return new TwoRequiredProperties(parent); + } +}; + +class GroupedRequiredProperties : public QObject +{ + Q_OBJECT + Q_PROPERTY(TwoRequiredProperties *group READ group) + TwoRequiredProperties m_group; + +public: + GroupedRequiredProperties(QObject *parent = nullptr) : QObject(parent) { } + TwoRequiredProperties *group() { return &m_group; } +}; + +class RequiredGroup : public QObject +{ + Q_OBJECT + // use QQuickPalette not to create an extra test-only + Q_PROPERTY(QQuickPalette *group READ group REQUIRED) + QQuickPalette m_group; + +public: + RequiredGroup(QObject *parent = nullptr) : QObject(parent) { } + QQuickPalette *group() { return &m_group; } +}; + void tst_qqmlcomponent::testRequiredProperties_data() { qmlRegisterType<RequiredDefaultCpp>("qt.test", 1, 0, "RequiredDefaultCpp"); + qmlRegisterType<TwoRequiredProperties>("qt.test", 1, 0, "TwoRequiredProperties"); + qmlRegisterType<ShadowedRequiredProperty>("qt.test", 1, 0, "ShadowedRequiredProperty"); + qmlRegisterUncreatableType<AttachedRequiredProperties>( + "qt.test", 1, 0, "AttachedRequiredProperty", + tr("AttachedRequiredProperties is an attached property")); + qmlRegisterType<GroupedRequiredProperties>("qt.test", 1, 0, "GroupedRequiredProperty"); + qmlRegisterType<RequiredGroup>("qt.test", 1, 0, "RequiredGroup"); + QTest::addColumn<QUrl>("testFile"); QTest::addColumn<bool>("shouldSucceed"); QTest::addColumn<QString>("errorMsg"); QTest::addRow("requiredSetViaChainedAlias") << testFileUrl("requiredSetViaChainedAlias.qml") << true << ""; QTest::addRow("requiredNotSet") << testFileUrl("requiredNotSet.qml") << false << "Required property i was not initialized"; - QTest::addRow("requiredSetInSameFile") << testFileUrl("requiredSetInSameFile.qml") << true << ""; + QTest::addRow("requiredSetInSameFile") << testFileUrl("RequiredSetInSameFile.qml") << true << ""; QTest::addRow("requiredSetViaAlias1") << testFileUrl("requiredSetViaAliasBeforeSameFile.qml") << true << ""; QTest::addRow("requiredSetViaAlias2") << testFileUrl("requiredSetViaAliasAfterSameFile.qml") << true << ""; QTest::addRow("requiredSetViaAlias3") << testFileUrl("requiredSetViaAliasParentFile.qml") << true << ""; + QTest::addRow("requiredSetInBase") << testFileUrl("requiredChildOfGoodBase.qml") << true << ""; + QTest::addRow("requiredNotSetInBase") << testFileUrl("requiredChildOfBadBase.qml") << false << "Required property i was not initialized"; + QTest::addRow("rerequiredSet") << testFileUrl("rerequiredSet.qml") << true << ""; + QTest::addRow("rerequiredNotSet") << testFileUrl("RerequiredNotSet.qml") << false + << "Required property i was not initialized"; + QTest::addRow("requiredSetLater(rerequired)") + << testFileUrl("requiredSetLater.rerequired.qml") << true << ""; + QTest::addRow("rerequiredSetLater") << testFileUrl("rerequiredSetLater.qml") << true << ""; QTest::addRow("shadowing") << testFileUrl("shadowing.qml") << false << "Required property i was not initialized"; + QTest::addRow("shadowing (C++)") << testFileUrl("shadowingFromCpp.qml") << false + << "Required property name was not initialized"; + QTest::addRow("shadowing (C++ indirect)") << testFileUrl("shadowingFromQmlChild.qml") << false + << "Required property name was not initialized"; QTest::addRow("setLater") << testFileUrl("requiredSetLater.qml") << true << ""; QTest::addRow("setViaAliasToSubcomponent") << testFileUrl("setViaAliasToSubcomponent.qml") << true << ""; QTest::addRow("aliasToSubcomponentNotSet") << testFileUrl("aliasToSubcomponentNotSet.qml") << false << "It can be set via the alias property i_alias"; @@ -707,9 +806,55 @@ void tst_qqmlcomponent::testRequiredProperties_data() QTest::addRow("required default not set") << testFileUrl("requiredDefault.2.qml") << false << "Required property requiredDefault was not initialized"; QTest::addRow("required default set (C++)") << testFileUrl("requiredDefault.3.qml") << true << ""; QTest::addRow("required default not set (C++)") << testFileUrl("requiredDefault.4.qml") << false << "Required property defaultProperty was not initialized"; + // QTBUG-96200: + QTest::addRow("required two set one (C++)") << testFileUrl("requiredTwoProperties.qml") << false + << "Required property name was not initialized"; + QTest::addRow("required two set two (C++)") + << testFileUrl("RequiredTwoPropertiesSet.qml") << true << ""; + QTest::addRow("required two set two (C++ indirect)") + << testFileUrl("requiredTwoPropertiesDummy.qml") << true << ""; + + QTest::addRow("required set (inline component)") + << testFileUrl("requiredPropertyInlineComponent.good.qml") << true << ""; + QTest::addRow("required not set (inline component)") + << testFileUrl("requiredPropertyInlineComponent.bad.qml") << false + << "Required property i was not initialized"; + QTest::addRow("required set (inline component, C++)") + << testFileUrl("requiredPropertyInlineComponentWithCppBase.good.qml") << true << ""; + QTest::addRow("required not set (inline component, C++)") + << testFileUrl("requiredPropertyInlineComponentWithCppBase.bad.qml") << false + << "Required property name was not initialized"; + QTest::addRow("required set (inline component, C++ indirect)") + << testFileUrl("requiredPropertyInlineComponentWithIndirectCppBase.qml") << true << ""; + QTest::addRow("required not set (attached)") + << testFileUrl("requiredPropertiesInAttached.bad.qml") << false + << "Attached property has required properties. This is not supported"; + QTest::addRow("required two set one (attached)") + << testFileUrl("requiredPropertiesInAttached.bad2.qml") << false + << "Attached property has required properties. This is not supported"; + QTest::addRow("required two set two (attached)") + << testFileUrl("RequiredPropertiesInAttached.qml") << false + << "Attached property has required properties. This is not supported"; + QTest::addRow("required two set two (attached indirect)") + << testFileUrl("requiredPropertiesInAttachedIndirect.qml") << false + << "Attached property has required properties. This is not supported"; + QTest::addRow("required itself not set (group)") + << testFileUrl("requiredGroup.bad.qml") << false + << "Required property group was not initialized"; + QTest::addRow("required itself set (group)") + << testFileUrl("requiredGroup.good.qml") << true << ""; + QTest::addRow("required not set (group)") + << testFileUrl("requiredPropertiesInGroup.bad.qml") << false + << "Required property index was not initialized"; + QTest::addRow("required two set one (group)") + << testFileUrl("requiredPropertiesInGroup.bad2.qml") << false + << "Required property name was not initialized"; + QTest::addRow("required two set two (group)") + << testFileUrl("RequiredPropertiesInGroup.qml") << true << ""; + QTest::addRow("required two set two (group indirect)") + << testFileUrl("requiredPropertiesInGroupIndirect.qml") << true << ""; } - void tst_qqmlcomponent::testRequiredProperties() { QQmlEngine eng; @@ -719,10 +864,18 @@ void tst_qqmlcomponent::testRequiredProperties() QQmlComponent comp(&eng); comp.loadUrl(testFile); QScopedObjPointer obj {comp.create()}; + QEXPECT_FAIL("required not set (group)", + "We fail to recognize required sub-properties inside a group property when that " + "group property is unused (QTBUG-96544)", + Abort); + QEXPECT_FAIL("required two set one (group)", + "We fail to recognized required sub-properties inside a group property, even when " + "that group property is used (QTBUG-96544)", + Abort); if (shouldSucceed) QVERIFY(obj); else { - QVERIFY(!obj); + QVERIFY2(!obj, "The object is valid when it shouldn't be"); QFETCH(QString, errorMsg); QVERIFY(comp.errorString().contains(errorMsg)); } @@ -870,6 +1023,16 @@ void tst_qqmlcomponent::qmlErrorIsReported() })); } +void tst_qqmlcomponent::removeBinding() +{ + QQmlEngine e; + QQmlComponent c(&e, testFileUrl("removeBinding.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + QCOMPARE(o->property("result"), QStringLiteral("42")); +} + QTEST_MAIN(tst_qqmlcomponent) #include "tst_qqmlcomponent.moc" diff --git a/tests/auto/qml/qqmlconnections/CMakeLists.txt b/tests/auto/qml/qqmlconnections/CMakeLists.txt index fef16f58f80..3761017b607 100644 --- a/tests/auto/qml/qqmlconnections/CMakeLists.txt +++ b/tests/auto/qml/qqmlconnections/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlconnections SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlconnections.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlconnections/data/invalidTarget.qml b/tests/auto/qml/qqmlconnections/data/invalidTarget.qml new file mode 100644 index 00000000000..23599649ec5 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/invalidTarget.qml @@ -0,0 +1,31 @@ +import QtQml + +QtObject { + id: root + objectName: button.objectName + + property QtObject b: QtObject { + objectName: "button" + id: button + signal clicked + } + + property Connections c: Connections { + id: connections + target: null + function onClicked() { button.destroy(); } + } + + property Timer t: Timer { + interval: 10 + running: true + onTriggered: { + root.objectName = connections.target.objectName + } + } + + Component.onCompleted: { + connections.target = button; + button.clicked() + } +} diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp index 31f000fab6e..a28a8dd9dd7 100644 --- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp +++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp @@ -30,8 +30,8 @@ #include <QtQml/qqmlcomponent.h> #include <private/qqmlconnections_p.h> #include <private/qquickitem_p.h> -#include "../../shared/util.h" #include <QtQml/qqmlscriptstring.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlconnections : public QQmlDataTest { @@ -78,6 +78,7 @@ private slots: void noAcceleratedGlobalLookup(); void bindToPropertyWithUnderscoreChangeHandler(); + void invalidTarget(); private: QQmlEngine engine; @@ -85,6 +86,7 @@ private slots: }; tst_qqmlconnections::tst_qqmlconnections() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } @@ -489,6 +491,25 @@ void tst_qqmlconnections::bindToPropertyWithUnderscoreChangeHandler() QVERIFY(root->property("success").toBool()); } +void tst_qqmlconnections::invalidTarget() +{ + QQmlEngine engine; + const QUrl url = testFileUrl("invalidTarget.qml"); + QQmlComponent component(&engine, url); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + + QScopedPointer<QObject> root {component.create()}; + QVERIFY(root); + QCOMPARE(root->objectName(), QStringLiteral("button")); + + QTest::ignoreMessage( + QtWarningMsg, + qPrintable( + url.toString() + + QLatin1String(":5:5: TypeError: Cannot read property 'objectName' of null"))); + QTRY_VERIFY(root->objectName().isEmpty()); +} + QTEST_MAIN(tst_qqmlconnections) #include "tst_qqmlconnections.moc" diff --git a/tests/auto/qml/qqmlconsole/CMakeLists.txt b/tests/auto/qml/qqmlconsole/CMakeLists.txt index 5e98ed2f318..5096503c157 100644 --- a/tests/auto/qml/qqmlconsole/CMakeLists.txt +++ b/tests/auto/qml/qqmlconsole/CMakeLists.txt @@ -12,17 +12,19 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlconsole SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlconsole.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::GuiPrivate Qt::Qml + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmlconsole) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qqmlconsole/data/assert.qml b/tests/auto/qml/qqmlconsole/data/assert.qml index dd580e2a72c..9687437c480 100644 --- a/tests/auto/qml/qqmlconsole/data/assert.qml +++ b/tests/auto/qml/qqmlconsole/data/assert.qml @@ -29,21 +29,22 @@ import QtQuick 2.0 QtObject { - property int q:1 + property int q: 1 + function assertFail() { - console.assert(0, "This will fail too") + console.assert(0, "This will fail too"); } Component.onCompleted: { - var x = 12; + const x = 12; console.assert(x == 12, "This will pass"); try { - console.assert(x < 12, "This will fail"); + console.assert(x < 12, "This will fail"); } catch (e) { console.log(e); } - console.assert("x < 12", "This will pass too") + console.assert("x < 12", "This will pass too"); assertFail(); - console.assert(1) + console.assert(1); } } diff --git a/tests/auto/qml/qqmlconsole/data/categorized_logging.qml b/tests/auto/qml/qqmlconsole/data/categorized_logging.qml index d593f0dfa10..6d471e7f809 100644 --- a/tests/auto/qml/qqmlconsole/data/categorized_logging.qml +++ b/tests/auto/qml/qqmlconsole/data/categorized_logging.qml @@ -40,7 +40,7 @@ import QtQuick 2.12 Item { - id:root + id: root LoggingCategory { id: testCategory @@ -69,8 +69,11 @@ Item { console.warn(testCategoryStartingFromWarning, "console.warn"); console.error(testCategoryStartingFromWarning, "console.error"); - testCategory.name = "qt.test2"; - testCategory.defaultLogLevel = LoggingCategory.Debug; + testCategory.name = "qt.test"; // should be silent + testCategoryStartingFromWarning.name = "qt.test.other"; // should issue a warning + + testCategory.defaultLogLevel = LoggingCategory.Debug; // should be silent + testCategoryStartingFromWarning.defaultLogLevel = LoggingCategory.Debug; // should issue a warning console.error(emptyCategory, "console.error"); } diff --git a/tests/auto/qml/qqmlconsole/data/exception.qml b/tests/auto/qml/qqmlconsole/data/exception.qml index 63afd188284..b9b83525e8e 100644 --- a/tests/auto/qml/qqmlconsole/data/exception.qml +++ b/tests/auto/qml/qqmlconsole/data/exception.qml @@ -30,12 +30,12 @@ import QtQuick 2.0 QtObject { function exceptionFail() { - console.exception("Exception 2") + console.exception("Exception 2"); } Component.onCompleted: { try { - console.exception("Exception 1") + console.exception("Exception 1"); } catch (e) { console.log(e); } diff --git a/tests/auto/qml/qqmlconsole/data/logging.qml b/tests/auto/qml/qqmlconsole/data/logging.qml index f5eaeb442ac..ac3884bc8e3 100644 --- a/tests/auto/qml/qqmlconsole/data/logging.qml +++ b/tests/auto/qml/qqmlconsole/data/logging.qml @@ -30,7 +30,8 @@ import QtQuick 2.0 QtObject { - id:root + id: root + required property var customObject required property var stringListProperty @@ -49,14 +50,14 @@ QtObject { consoleCount(); consoleCount(); - var a = [1, 2]; - var b = {a: "hello", d: 1 }; - b.toString = function() { return JSON.stringify(b) } - var c - var d = 12; - var e = function() { return 5;}; - var f = true; - var g = {toString: function() { throw new Error('toString'); }}; + const a = [1, 2]; + const b = { a: "hello", d: 1 }; + b.toString = function() { return JSON.stringify(b); } + let c; + const d = 12; + const e = function() { return 5; }; + const f = true; + const g = { toString: function() { throw new Error('toString'); } }; console.log(a); console.log(b); @@ -79,6 +80,6 @@ QtObject { return; } - throw ("console.log(exception) should have raised an exception"); + throw "console.log(exception) should have raised an exception"; } } diff --git a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp index 666c97a07f4..019be5f16a6 100644 --- a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp +++ b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp @@ -31,13 +31,13 @@ #include <QQmlComponent> #include <QQmlContext> #include <QLoggingCategory> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlconsole : public QQmlDataTest { Q_OBJECT public: - tst_qqmlconsole() {} + tst_qqmlconsole() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void logging(); @@ -133,18 +133,27 @@ void tst_qqmlconsole::categorized_logging() QVERIFY(messageHandler.messages().contains("qt.test.warning: console.error")); QString emptyCategory = "default: " + QString::fromLatin1("%1:%2:%3: ").arg(testUrl.toString()).arg(56).arg(5) + - "QML LoggingCategory: Declaring the name of the LoggingCategory is mandatory and cannot be changed later !"; + "QML LoggingCategory: Declaring the name of a LoggingCategory is mandatory and cannot be changed later"; QVERIFY(messageHandler.messages().contains(emptyCategory)); - QString changedCategory = "default: " + QString::fromLatin1("%1:%2:%3: ").arg(testUrl.toString()).arg(45).arg(5) + - "QML LoggingCategory: The name of a LoggingCategory cannot be changed after the Item is created"; + + QString notChangedCategory = "default: " + QString::fromLatin1("%1:%2:%3: ").arg(testUrl.toString()).arg(45).arg(5) + + "QML LoggingCategory: The name of a LoggingCategory cannot be changed after the component is completed"; + QVERIFY(!messageHandler.messages().contains(notChangedCategory)); + QString changedCategory = "default: " + QString::fromLatin1("%1:%2:%3: ").arg(testUrl.toString()).arg(50).arg(5) + + "QML LoggingCategory: The name of a LoggingCategory cannot be changed after the component is completed"; QVERIFY(messageHandler.messages().contains(changedCategory)); - QString changedDefaultLogLevel = "default: " + QString::fromLatin1("%1:%2:%3: ").arg(testUrl.toString()).arg(45).arg(5) + - "QML LoggingCategory: The defaultLogLevel of a LoggingCategory cannot be changed after the Item is created"; + + QString notChangedDefaultLogLevel = "default: " + QString::fromLatin1("%1:%2:%3: ").arg(testUrl.toString()).arg(45).arg(5) + + "QML LoggingCategory: The defaultLogLevel of a LoggingCategory cannot be changed after the component is completed"; + QVERIFY(!messageHandler.messages().contains(notChangedDefaultLogLevel)); + QString changedDefaultLogLevel = "default: " + QString::fromLatin1("%1:%2:%3: ").arg(testUrl.toString()).arg(50).arg(5) + + "QML LoggingCategory: The defaultLogLevel of a LoggingCategory cannot be changed after the component is completed"; QVERIFY(messageHandler.messages().contains(changedDefaultLogLevel)); - QString useEmptyCategory = "default: " + QString::fromLatin1("%1:%2: ").arg(testUrl.toString()).arg(75) + + + QString useEmptyCategory = "default: " + QString::fromLatin1("%1:%2: ").arg(testUrl.toString()).arg(78) + "Error: A QmlLoggingCatgory was provided without a valid name"; QVERIFY(messageHandler.messages().contains(useEmptyCategory)); @@ -190,13 +199,13 @@ void tst_qqmlconsole::testAssert() QString assert1 = "This will fail\n" + QString::fromLatin1("expression for onCompleted (%1:%2)") .arg(testUrl.toString()) - .arg(41); + .arg(42); QString assert2 = "This will fail too\n" - + QString::fromLatin1("assertFail (%1:%2)\n").arg(testUrl.toString()).arg(34) + + QString::fromLatin1("assertFail (%1:%2)\n").arg(testUrl.toString()).arg(35) + QString::fromLatin1("expression for onCompleted (%1:%2)") .arg(testUrl.toString()) - .arg(46); + .arg(47); QTest::ignoreMessage(QtCriticalMsg, qPrintable(assert1)); QTest::ignoreMessage(QtCriticalMsg, qPrintable(assert2)); diff --git a/tests/auto/qml/qqmlcontext/CMakeLists.txt b/tests/auto/qml/qqmlcontext/CMakeLists.txt index ce07e8c785c..5b2c4e7a5bd 100644 --- a/tests/auto/qml/qqmlcontext/CMakeLists.txt +++ b/tests/auto/qml/qqmlcontext/CMakeLists.txt @@ -12,15 +12,13 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlcontext SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlcontext.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlcontext/data/gcDeletesContextObject.qml b/tests/auto/qml/qqmlcontext/data/gcDeletesContextObject.qml new file mode 100644 index 00000000000..a478a587df5 --- /dev/null +++ b/tests/auto/qml/qqmlcontext/data/gcDeletesContextObject.qml @@ -0,0 +1,5 @@ +import QtQml +QtObject { + property Component c: MyItem {} + property QtObject o: c.createObject() +} diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp index 4a850541a66..75bf580947a 100644 --- a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp +++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp @@ -37,13 +37,13 @@ #include <private/qqmlguardedcontextdata_p.h> #include <private/qv4qmlcontext_p.h> #include <private/qv4object_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlcontext : public QQmlDataTest { Q_OBJECT public: - tst_qqmlcontext() {} + tst_qqmlcontext() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void baseUrl(); @@ -75,6 +75,8 @@ private slots: void contextObjectHierarchy(); void destroyContextProperty(); + void numericContextProperty(); + private: QQmlEngine engine; }; @@ -1004,6 +1006,14 @@ void tst_qqmlcontext::destroyContextProperty() // TODO: Or are we? } +void tst_qqmlcontext::numericContextProperty() +{ + QQmlEngine engine; + auto context = engine.rootContext(); + context->setContextProperty(QLatin1String("11"), 42); + QCOMPARE(context->contextProperty(QLatin1String("11")).toInt(), 42); +} + QTEST_MAIN(tst_qqmlcontext) #include "tst_qqmlcontext.moc" diff --git a/tests/auto/qml/qqmldelegatemodel/CMakeLists.txt b/tests/auto/qml/qqmldelegatemodel/CMakeLists.txt index 9020d9e8923..3cbb4540e00 100644 --- a/tests/auto/qml/qqmldelegatemodel/CMakeLists.txt +++ b/tests/auto/qml/qqmldelegatemodel/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmldelegatemodel SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmldelegatemodel.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qqmldelegatemodel Qt::QmlModelsPrivate Qt::QmlPrivate Qt::Quick + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmldelegatemodel/data/ImageToggle.qml b/tests/auto/qml/qqmldelegatemodel/data/ImageToggle.qml new file mode 100644 index 00000000000..fa154b25f3b --- /dev/null +++ b/tests/auto/qml/qqmldelegatemodel/data/ImageToggle.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Item { + property var isSelected: null + property string source + implicitWidth: 16 + implicitHeight: 16 + + onSourceChanged: { + updateImageSource() + } + + onIsSelectedChanged: { + updateImageSource() + } + + function updateImageSource() { + let result = isSelected ? source + "_selected_dark.png" : source + "_active_dark.png" + } + +} diff --git a/tests/auto/qml/qqmldelegatemodel/data/contextAccessedByHandler.qml b/tests/auto/qml/qqmldelegatemodel/data/contextAccessedByHandler.qml new file mode 100644 index 00000000000..46d75245271 --- /dev/null +++ b/tests/auto/qml/qqmldelegatemodel/data/contextAccessedByHandler.qml @@ -0,0 +1,31 @@ +import QtQuick 2.0 + +Item { + id: root + width: 640 + height: 480 + property bool works: myView.currentItem.okay + + ListView { + id: myView + model: myModel + anchors.fill: parent + delegate: Row { + property alias okay: image.isSelected + ImageToggle { + id: image + source: "glyph_16_arrow_patch" + isSelected: model.age < 6 + } + Text { + text: "age:" + model.age + " selected:" + image.isSelected + } + } + } + + ListModel { + id: myModel + ListElement { type: "Cat"; age: 3; } + ListElement { type: "Dog"; age: 2; } + } +} diff --git a/tests/auto/qml/qqmldelegatemodel/data/deleteRace.qml b/tests/auto/qml/qqmldelegatemodel/data/deleteRace.qml new file mode 100644 index 00000000000..b01b14f7b8a --- /dev/null +++ b/tests/auto/qml/qqmldelegatemodel/data/deleteRace.qml @@ -0,0 +1,50 @@ +import QtQuick +import QtQml.Models + +Item { + DelegateModel { + id: delegateModel + model: ListModel { + id: sourceModel + + ListElement { title: "foo" } + ListElement { title: "bar" } + + function clear() { + if (count > 0) + remove(0, count); + } + } + + groups: [ + DelegateModelGroup { name: "selectedItems" } + ] + + delegate: Text { + height: DelegateModel.inSelectedItems ? implicitHeight * 2 : implicitHeight + Component.onCompleted: { + if (index === 0) + DelegateModel.inSelectedItems = true; + } + } + + Component.onCompleted: { + items.create(0) + items.create(1) + } + } + + ListView { + anchors.fill: parent + model: delegateModel + } + + Timer { + running: true + interval: 10 + onTriggered: sourceModel.clear() + } + + property int count: delegateModel.items.count +} + diff --git a/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml b/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml new file mode 100644 index 00000000000..206133bb396 --- /dev/null +++ b/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml @@ -0,0 +1,11 @@ +import QtQuick 2.8 + +ListView { + id: root + width: 200 + height: 200 + + delegate: Text { + text: display + } +} diff --git a/tests/auto/qml/qqmldelegatemodel/data/resetModelData.qml b/tests/auto/qml/qqmldelegatemodel/data/resetModelData.qml new file mode 100644 index 00000000000..1fe6168c795 --- /dev/null +++ b/tests/auto/qml/qqmldelegatemodel/data/resetModelData.qml @@ -0,0 +1,16 @@ +import QtQuick + +ListView { + id: root + anchors.fill: parent + property bool success: (currentItem?.mydata ?? 0) === 42 + height: 300 + width: 200 + + delegate: Rectangle { + required property var model + implicitWidth: 100 + implicitHeight: 50 + property var mydata: model?.foo ?? model.bar + } +} diff --git a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp index 0980d8b8cae..12d1cc57cb3 100644 --- a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp +++ b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp @@ -27,12 +27,15 @@ ****************************************************************************/ #include <QtTest/qtest.h> +#include <QtCore/QConcatenateTablesProxyModel> +#include <QtGui/QStandardItemModel> #include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlapplicationengine.h> #include <QtQmlModels/private/qqmldelegatemodel_p.h> #include <QtQuick/qquickview.h> #include <QtQuick/qquickitem.h> - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtTest/QSignalSpy> class tst_QQmlDelegateModel : public QQmlDataTest { @@ -42,10 +45,14 @@ class tst_QQmlDelegateModel : public QQmlDataTest tst_QQmlDelegateModel(); private slots: + void resettingRolesRespected(); void valueWithoutCallingObjectFirst_data(); void valueWithoutCallingObjectFirst(); void qtbug_86017(); void filterOnGroup_removeWhenCompleted(); + void contextAccessedByHandler(); + void redrawUponColumnChange(); + void deleteRace(); }; class AbstractItemModel : public QAbstractItemModel @@ -100,10 +107,66 @@ class AbstractItemModel : public QAbstractItemModel }; tst_QQmlDelegateModel::tst_QQmlDelegateModel() + : QQmlDataTest(QT_QMLTEST_DATADIR) { qmlRegisterType<AbstractItemModel>("Test", 1, 0, "AbstractItemModel"); } +class TableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + int rowCount(const QModelIndex & = QModelIndex()) const override + { + return 1; + } + + int columnCount(const QModelIndex & = QModelIndex()) const override + { + return 1; + } + + QVariant data(const QModelIndex &index, int role) const override + { + switch (role) { + case 0: + return QString("foo: %1, %2").arg(index.column()).arg(index.row()); + case 1: + return 42; + default: + break; + } + + return QVariant(); + } + + Q_INVOKABLE void change() { beginResetModel(); toggle = !toggle; endResetModel(); } + + QHash<int, QByteArray> roleNames() const override + { + if (toggle) + return { {0, "foo"} }; + else + return { {1, "bar"} }; + } + + bool toggle = true; +}; + +void tst_QQmlDelegateModel::resettingRolesRespected() +{ + auto model = std::make_unique<TableModel>(); + QQmlApplicationEngine engine; + engine.setInitialProperties({ {"model", QVariant::fromValue(model.get()) }} ); + engine.load(testFileUrl("resetModelData.qml")); + QTRY_VERIFY(!engine.rootObjects().isEmpty()); + QObject *root = engine.rootObjects().constFirst(); + QVERIFY(!root->property("success").toBool()); + model->change(); + QTRY_VERIFY(root->property("success").toBool()); +} + void tst_QQmlDelegateModel::valueWithoutCallingObjectFirst_data() { QTest::addColumn<QUrl>("qmlFileUrl"); @@ -165,6 +228,51 @@ void tst_QQmlDelegateModel::filterOnGroup_removeWhenCompleted() QVERIFY(QTest::qWaitFor([=]{ return model->count() == 2; })); } +void tst_QQmlDelegateModel::contextAccessedByHandler() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("contextAccessedByHandler.qml")); + QScopedPointer<QObject> root(component.create()); + QVERIFY2(root, qPrintable(component.errorString())); + QVERIFY(root->property("works").toBool()); +} + +void tst_QQmlDelegateModel::redrawUponColumnChange() +{ + QStandardItemModel m1; + m1.appendRow({ + new QStandardItem("Banana"), + new QStandardItem("Coconut"), + }); + + QQuickView view(testFileUrl("redrawUponColumnChange.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + QQuickItem *root = view.rootObject(); + root->setProperty("model", QVariant::fromValue<QObject *>(&m1)); + + QObject *item = root->property("currentItem").value<QObject *>(); + QVERIFY(item); + QCOMPARE(item->property("text").toString(), "Banana"); + + QVERIFY(root); + m1.removeColumn(0); + + QCOMPARE(item->property("text").toString(), "Coconut"); +} + + +void tst_QQmlDelegateModel::deleteRace() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("deleteRace.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + QTRY_COMPARE(o->property("count").toInt(), 2); + QTRY_COMPARE(o->property("count").toInt(), 0); +} + QTEST_MAIN(tst_QQmlDelegateModel) #include "tst_qqmldelegatemodel.moc" diff --git a/tests/auto/qml/qqmldirparser/CMakeLists.txt b/tests/auto/qml/qqmldirparser/CMakeLists.txt index 255cc75c6af..f8e3e36ef72 100644 --- a/tests/auto/qml/qqmldirparser/CMakeLists.txt +++ b/tests/auto/qml/qqmldirparser/CMakeLists.txt @@ -12,14 +12,12 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmldirparser SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmldirparser.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Qml Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp index 8f0c58653bd..64658e8546b 100644 --- a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp +++ b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp @@ -26,8 +26,6 @@ ** ****************************************************************************/ -#include "../../shared/util.h" - #include <qtest.h> #include <QObject> #include <QQmlEngine> @@ -35,6 +33,7 @@ #include <private/qqmljsdiagnosticmessage_p.h> #include <private/qqmldirparser_p.h> #include <QDebug> +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <algorithm> @@ -52,6 +51,7 @@ private slots: }; tst_qqmldirparser::tst_qqmldirparser() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } diff --git a/tests/auto/qml/qqmlecmascript/BLACKLIST b/tests/auto/qml/qqmlecmascript/BLACKLIST deleted file mode 100644 index bd25566eefd..00000000000 --- a/tests/auto/qml/qqmlecmascript/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[gcCrashRegressionTest] -macos arm diff --git a/tests/auto/qml/qqmlecmascript/CMakeLists.txt b/tests/auto/qml/qqmlecmascript/CMakeLists.txt index 5c5bd528ed4..bb1040db165 100644 --- a/tests/auto/qml/qqmlecmascript/CMakeLists.txt +++ b/tests/auto/qml/qqmlecmascript/CMakeLists.txt @@ -12,18 +12,16 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlecmascript SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h testtypes.cpp testtypes.h tst_qqmlecmascript.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::Network Qt::QmlPrivate + Qt::QuickTestUtilsPrivate + Qt::QuickPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlecmascript/data/Lib.js b/tests/auto/qml/qqmlecmascript/data/Lib.js new file mode 100644 index 00000000000..67d4f7f56d9 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/Lib.js @@ -0,0 +1,3 @@ +.pragma library + +function f() { return 42 } diff --git a/tests/auto/qml/qqmlecmascript/data/PreNamed.qml b/tests/auto/qml/qqmlecmascript/data/PreNamed.qml new file mode 100644 index 00000000000..dc991e674ff --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/PreNamed.qml @@ -0,0 +1,11 @@ +import QtQml + +QtObject { + property QtObject other: QtObject { + objectName: "original" + } + objectName: other.objectName + function updateOriginal() { + other.objectName = "updated" + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/aliasPropertyToIC.qml b/tests/auto/qml/qqmlecmascript/data/aliasPropertyToIC.qml new file mode 100644 index 00000000000..17116bb091f --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/aliasPropertyToIC.qml @@ -0,0 +1,11 @@ +import QtQml + + +QtObject { + id: root + + component Test : QtObject {} + + property alias myalias: other + property var direct: Test { id: other } +} diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-nonstandardFormat2.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-nonstandardFormat2.qml new file mode 100644 index 00000000000..3fd3c050246 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-nonstandardFormat2.qml @@ -0,0 +1,10 @@ +import Qt.test 1.0 +import QtQml 2.15 + + +MyTypeObject { + Component.onCompleted: { + dateTimeProperty = new Date("Sun, 25 Mar 2018 11:10:49 GMT") + boolProperty = !Number.isNaN(dateTimeProperty) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/enums.1.qml b/tests/auto/qml/qqmlecmascript/data/enums.1.qml index b9295c5c89a..379a6efc8e8 100644 --- a/tests/auto/qml/qqmlecmascript/data/enums.1.qml +++ b/tests/auto/qml/qqmlecmascript/data/enums.1.qml @@ -35,4 +35,7 @@ MyQmlObject { // Enum values defined both in a type and a related type property int l: MyQmlObject.MultiplyDefined + + // Enum arithmetic + property int m: MyQmlObject.EnumValue2 | MyQmlObject.EnumValue3 } diff --git a/tests/auto/qml/qqmlecmascript/data/functionAsDefaultArgument.qml b/tests/auto/qml/qqmlecmascript/data/functionAsDefaultArgument.qml new file mode 100644 index 00000000000..9f576d1af88 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/functionAsDefaultArgument.qml @@ -0,0 +1,8 @@ +import QtQml 2.15 + +QtObject { + id: root + + function f(inner=function(){ root.objectName = "didRun" } ){ inner() } + Component.onCompleted: f() +} diff --git a/tests/auto/qml/qqmlecmascript/data/generatorCallsGC.qml b/tests/auto/qml/qqmlecmascript/data/generatorCallsGC.qml new file mode 100644 index 00000000000..7fe366cac82 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/generatorCallsGC.qml @@ -0,0 +1,13 @@ +import QtQml 2.15 + +QtObject { + function test_generator_gc() { + ((function*() { gc() })()).next(); + ((function*() { gc() })()).next(); + ((function*() { gc() })()).next(); + ((function*() { gc() })()).next(); + } + + Component.onCompleted: () => test_generator_gc() + +} diff --git a/tests/auto/qml/qqmlecmascript/data/icUsingJSLib.qml b/tests/auto/qml/qqmlecmascript/data/icUsingJSLib.qml new file mode 100644 index 00000000000..507027e1017 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/icUsingJSLib.qml @@ -0,0 +1,12 @@ +import QtQml + +import "Lib.js" as Lib + +QtObject { + component C : QtObject { + property int num: Lib.f() + } + + property var test: C { id: c } + property alias num: c.num +} diff --git a/tests/auto/qml/qqmlecmascript/data/internalClassParentGc.js b/tests/auto/qml/qqmlecmascript/data/internalClassParentGc.js new file mode 100644 index 00000000000..f51ab662ab7 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/internalClassParentGc.js @@ -0,0 +1,29 @@ +function init() { + Array.prototype.doPush = Array.prototype.push +} + +function nasty() { + var sc_Vector = Array; + var push = sc_Vector.prototype.doPush; + + // Change the memberData to hold something nasty on the current internalClass + sc_Vector.prototype.doPush = 5; + + // Trigger a re-allocation of memberData + for (var i = 0; i < 256; ++i) + sc_Vector.prototype[i + "string"] = function() { return 98; } + + // Change the (new) memberData back, to hold our doPush function again. + // This should propagate a protoId change all the way up to the lookup. + sc_Vector.prototype.doPush = push; +} + +function func() { + var b = []; + + // This becomes a lookup internally, which stores protoId and a pointer + // into the memberData. It should get invalidated when memberData is re-allocated. + b.doPush(3); + + return b; +} diff --git a/tests/auto/qml/qqmlecmascript/data/internalClassParentGc.qml b/tests/auto/qml/qqmlecmascript/data/internalClassParentGc.qml new file mode 100644 index 00000000000..e313770bf5c --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/internalClassParentGc.qml @@ -0,0 +1,13 @@ +import QtQml + +import "internalClassParentGc.js" as Foo + +QtObject { + Component.onCompleted: { + gc(); + Foo.init(); + Foo.func(); + Foo.nasty(); + objectName = Foo.func()[0]; + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/methodCallOnDerivedSingleton.qml b/tests/auto/qml/qqmlecmascript/data/methodCallOnDerivedSingleton.qml new file mode 100644 index 00000000000..9d2ee433fd9 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/methodCallOnDerivedSingleton.qml @@ -0,0 +1,6 @@ +import Qt.test +import QtQml + +QtObject { + Component.onCompleted: SingletonInheritanceTest.trackPage("test", {x: 42}) +} diff --git a/tests/auto/qml/qqmlecmascript/data/methodTypeMismatch.qml b/tests/auto/qml/qqmlecmascript/data/methodTypeMismatch.qml new file mode 100644 index 00000000000..fdf5f4ea114 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/methodTypeMismatch.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Item { + id: self + property font myFont + property int notMyFont + + property var object + + function callWithFont() { + object.method_gadget(myFont) // should be fine + } + function callWithInt() { + object.method_gadget(123) + } + function callWithInt2() { + object.method_gadget(notMyFont) + } + function callWithNull() { + object.method_gadget(null) + } + function callWithAllowedNull() { + object.method_qobject(null) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/qmlTypeWrapperArgs.qml b/tests/auto/qml/qqmlecmascript/data/qmlTypeWrapperArgs.qml new file mode 100644 index 00000000000..7f1b5b03178 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qmlTypeWrapperArgs.qml @@ -0,0 +1,8 @@ +import QtQml + +QtObject { + id: root + required property QtObject invokableObject + + Component.onCompleted: root.invokableObject.method_QObject(Component) +} diff --git a/tests/auto/qml/qqmlecmascript/data/qmlTypeWrapperArgs2.qml b/tests/auto/qml/qqmlecmascript/data/qmlTypeWrapperArgs2.qml new file mode 100644 index 00000000000..1904740b269 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qmlTypeWrapperArgs2.qml @@ -0,0 +1,9 @@ +import QtQml +import QtQml as NS + +QtObject { + id: root + required property QtObject invokableObject + + Component.onCompleted: root.invokableObject.method_QObject(NS) +} diff --git a/tests/auto/qml/qqmlecmascript/data/qpropertyBindingNoQPropertyCapture.qml b/tests/auto/qml/qqmlecmascript/data/qpropertyBindingNoQPropertyCapture.qml new file mode 100644 index 00000000000..d3a151efe3e --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qpropertyBindingNoQPropertyCapture.qml @@ -0,0 +1,19 @@ +import QtQuick + +Item { + objectName: "redRectangle" + id: redRectangle + + property bool b: false + function toggle() { b = !b } + width: b ? 600 : 500 + + Item { + id: blueRectangle + objectName: "blueRectangle" + // width: b ? (100 + redRectangle.width / 2) : 25 + width: b ? redRectangle.width : 25 + } + + property int blueRectangleWidth: blueRectangle.width +} diff --git a/tests/auto/qml/qqmlecmascript/data/qpropertyBindingReplacement.qml b/tests/auto/qml/qqmlecmascript/data/qpropertyBindingReplacement.qml new file mode 100644 index 00000000000..478a88678b0 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qpropertyBindingReplacement.qml @@ -0,0 +1,6 @@ +import QtQml + +PreNamed { + objectName: "overwritten" + Component.onCompleted: updateOriginal() +} diff --git a/tests/auto/qml/qqmlecmascript/data/qpropertyResetCorrectlyLinked.qml b/tests/auto/qml/qqmlecmascript/data/qpropertyResetCorrectlyLinked.qml new file mode 100644 index 00000000000..490fec2dc82 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qpropertyResetCorrectlyLinked.qml @@ -0,0 +1,8 @@ +import QtQuick + +Item { + property var val: undefined + property var observes: width + width: val + implicitWidth: 200 +} diff --git a/tests/auto/qml/qqmlecmascript/data/readOnlyBindable.qml b/tests/auto/qml/qqmlecmascript/data/readOnlyBindable.qml new file mode 100644 index 00000000000..116036c9ff8 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/readOnlyBindable.qml @@ -0,0 +1,7 @@ +import Qt.test +import QtQuick + +ReadOnlyBindable { + property int v: 12 + x: v +} diff --git a/tests/auto/qml/qqmlecmascript/data/restoreObserverAfterReset.qml b/tests/auto/qml/qqmlecmascript/data/restoreObserverAfterReset.qml new file mode 100644 index 00000000000..2933d9b4d5f --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/restoreObserverAfterReset.qml @@ -0,0 +1,20 @@ +import QtQuick + +Item { + height: undefined + implicitHeight: 30 + property int steps: 0 + + Behavior on height { + NumberAnimation { + duration: 500 + } + } + + onHeightChanged: ++steps + + Component.onCompleted: { + height = Qt.binding(() => implicitHeight); + implicitHeight = 60; + } +} diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp index 87d8ed0c1f4..803e09a2e96 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.cpp +++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp @@ -560,6 +560,9 @@ void registerTypes() qmlRegisterType<Receiver>("Qt.test", 1,0, "Receiver"); qmlRegisterType<Sender>("Qt.test", 1,0, "Sender"); + qmlRegisterTypesAndRevisions<ReadOnlyBindable>("Qt.test", 1); + + qmlRegisterTypesAndRevisions<SingletonRegistrationWrapper>("Qt.test", 1); } #include "testtypes.moc" diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index acc066fddd5..622d7c44c8b 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -833,12 +833,38 @@ class MyInvokableObject : public MyInvokableBaseObject Q_INVOKABLE void method_unknown(NonRegisteredType) { invoke(28); } + Q_PROPERTY(QFont someFont READ someFont WRITE setSomeFont NOTIFY someFontChanged); + QFont someFont() { return m_someFont; } + void setSomeFont(const QFont &f) + { + if (f == m_someFont) + return; + m_someFont = f; + emit someFontChanged(); + } + Q_INVOKABLE void method_gadget(QFont f) + { + invoke(40); + m_actuals << f; + } + Q_INVOKABLE void method_qobject(QObject *o) + { + invoke(41); + m_actuals << QVariant::fromValue(o); + } + private: friend class MyInvokableBaseObject; void invoke(int idx) { if (m_invoked != -1) m_invokedError = true; m_invoked = idx;} int m_invoked; bool m_invokedError; QVariantList m_actuals; + + QFont m_someFont; + +public: +Q_SIGNALS: + void someFontChanged(); }; MyInvokableBaseObject::~MyInvokableBaseObject() {} @@ -1847,6 +1873,61 @@ public slots: int slot1(int i, int j, int k) {return i+j+k;} }; +class ReadOnlyBindable : public QObject +{ + Q_OBJECT + QML_ELEMENT + Q_PROPERTY(int x READ x WRITE setX BINDABLE bindableX) + Q_OBJECT_BINDABLE_PROPERTY(ReadOnlyBindable, int, _xProp) + +public: + ReadOnlyBindable(QObject *parent = nullptr) + : QObject(parent) + { + setX(7); + } + + int x() const { return _xProp.value(); } + void setX(int x) { _xProp.setValue(x); } + QBindable<int> bindableX() const { return &_xProp; } +}; + +class SingletonBase : public QObject { + Q_OBJECT + +public: + Q_INVOKABLE virtual void trackPage(const QString&) {} + Q_INVOKABLE virtual void trackPage(const QString&, const QVariantMap&) {} + + bool m_okay = false; +}; + +class SingletonImpl : public SingletonBase { + Q_OBJECT + +public: + Q_INVOKABLE virtual void trackPage(const QString&) override {} + Q_INVOKABLE virtual void trackPage(const QString&, const QVariantMap&) override + { + m_okay = true; + } +}; + +class SingletonRegistrationWrapper { + Q_GADGET + QML_FOREIGN(SingletonBase) + QML_NAMED_ELEMENT(SingletonInheritanceTest) + QML_SINGLETON + +public: + static SingletonBase* create(QQmlEngine*, QJSEngine*) { + return new SingletonImpl(); + } + +private: + SingletonRegistrationWrapper() = default; +}; + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index d8d90b1aff9..c30c4de8253 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -39,8 +39,6 @@ #include <private/qqmlvmemetaobject_p.h> #include <private/qv4qmlcontext_p.h> #include "testtypes.h" -#include "testhttpserver.h" -#include "../../shared/util.h" #include <private/qv4functionobject_p.h> #include <private/qv4scopedvalue_p.h> #include <private/qv4jscall_p.h> @@ -54,6 +52,10 @@ #include <private/qqmlabstractbinding_p.h> #include <private/qqmlvaluetypeproxybinding_p.h> #include <QtCore/private/qproperty_p.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/testhttpserver_p.h> #ifdef Q_CC_MSVC #define NO_INLINE __declspec(noinline) @@ -72,6 +74,9 @@ class tst_qqmlecmascript : public QQmlDataTest { Q_OBJECT +public: + tst_qqmlecmascript(); + private slots: void initTestCase() override; void arrayIncludesValueType(); @@ -112,6 +117,7 @@ private slots: void outerBindingOverridesInnerBinding(); void aliasPropertyAndBinding(); void aliasPropertyReset(); + void aliasPropertyToIC(); void nonExistentAttachedObject(); void scope(); void importScope(); @@ -244,6 +250,8 @@ private slots: void function(); void topLevelGeneratorFunction(); void generatorCrashNewProperty(); + void generatorCallsGC(); + void noYieldInInnerFunction(); void qtbug_10696(); void qtbug_11606(); void qtbug_11600(); @@ -305,6 +313,8 @@ private slots: void replaceBinding(); void bindingBoundFunctions(); void qpropertyAndQtBinding(); + void qpropertyBindingReplacement(); + void qpropertyBindingNoQPropertyCapture(); void deleteRootObjectInCreation(); void onDestruction(); void onDestructionViaGC(); @@ -386,6 +396,8 @@ private slots: void qpropertyBindingHandlesUndefinedCorrectly(); void qpropertyBindingHandlesUndefinedWithoutResetCorrectly_data(); void qpropertyBindingHandlesUndefinedWithoutResetCorrectly(); + void qpropertyBindingRestoresObserverAfterReset(); + void qpropertyBindingObserverCorrectlyLinkedAfterReset(); void hugeRegexpQuantifiers(); void singletonTypeWrapperLookup(); void getThisObject(); @@ -410,11 +422,23 @@ private slots: void frozenQObject(); void constPointer(); + void icUsingJSLib(); + void optionalChainEval(); void optionalChainDelete(); void optionalChainNull(); void asCast(); + void functionNameInFunctionScope(); + void functionAsDefaultArgument(); + + void internalClassParentGc(); + void methodTypeMismatch(); + + void doNotCrashOnReadOnlyBindable(); + + + void methodCallOnDerivedSingleton(); private: // static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter); static void verifyContextLifetime(const QQmlRefPointer<QQmlContextData> &ctxt); @@ -439,6 +463,11 @@ static void gc(QQmlEngine &engine) } +tst_qqmlecmascript::tst_qqmlecmascript() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qqmlecmascript::initTestCase() { QQmlDataTest::initTestCase(); @@ -710,6 +739,9 @@ void tst_qqmlecmascript::checkDateTime_data() QTest::newRow("nonstandard-format") << testFileUrl("checkDateTime-nonstandardFormat.qml") << QDateTime::fromString("1991-08-25 20:57:08 GMT+0000", "yyyy-MM-dd hh:mm:ss t"); + QTest::newRow("nonstandard-format2") + << testFileUrl("checkDateTime-nonstandardFormat2.qml") + << QDateTime::fromString("Sun, 25 Mar 2018 11:10:49 GMT", "ddd, d MMM yyyy hh:mm:ss t"); } void tst_qqmlecmascript::checkDateTime() @@ -1375,6 +1407,7 @@ void tst_qqmlecmascript::enums() QCOMPARE(object->property("j").toInt(), 19); QCOMPARE(object->property("k").toInt(), 42); QCOMPARE(object->property("l").toInt(), 333); + QCOMPARE(object->property("m").toInt(), 3); } // Non-existent enums { @@ -1815,6 +1848,24 @@ void tst_qqmlecmascript::aliasPropertyReset() QCOMPARE(object->property("aliasedIntIsUndefined"), QVariant(false)); } +void tst_qqmlecmascript::aliasPropertyToIC() +{ + QQmlEngine engine; + std::unique_ptr<QObject> root; + + // test that a manual write (of undefined) to a resettable aliased property succeeds + QQmlComponent c(&engine, testFileUrl("aliasPropertyToIC.qml")); + root.reset(c.create()); + QVERIFY(root); + auto mo = root->metaObject(); + int aliasIndex = mo->indexOfProperty("myalias"); + auto prop = mo->property(aliasIndex); + QVERIFY(prop.isAlias()); + auto fromAlias = prop.read(root.get()).value<QObject *>(); + auto direct = root->property("direct").value<QObject *>(); + QCOMPARE(fromAlias, direct); +} + void tst_qqmlecmascript::componentCreation_data() { QTest::addColumn<QString>("method"); @@ -3027,6 +3078,26 @@ void tst_qqmlecmascript::callQtInvokables() QCOMPARE(o->actuals().count(), 1); QCOMPARE(o->actuals().at(0), QVariant::fromValue((QObject *)nullptr)); + { + o->reset(); + QQmlComponent comp(&qmlengine, testFileUrl("qmlTypeWrapperArgs.qml")); + QScopedPointer<QObject> root {comp.createWithInitialProperties({{"invokableObject", QVariant::fromValue(o)}}) }; + QVERIFY(root); + QCOMPARE(o->error(), false); + QCOMPARE(o->invoked(), 13); + QCOMPARE(o->actuals().count(), 1); + QCOMPARE(o->actuals().at(0).value<QObject *>()->metaObject()->className(), "QQmlComponentAttached"); + } + + { + o->reset(); + QQmlComponent comp(&qmlengine, testFileUrl("qmlTypeWrapperArgs2.qml")); + QScopedPointer<QObject> root {comp.createWithInitialProperties({{"invokableObject", QVariant::fromValue(o)}}) }; + QVERIFY(root); + QCOMPARE(o->error(), false); + QCOMPARE(o->invoked(), -1); // no function got called due to incompatible arguments + } + o->reset(); QVERIFY(EVALUATE_VALUE("object.method_QObject(undefined)", QV4::Primitive::undefinedValue())); QCOMPARE(o->error(), false); @@ -3290,6 +3361,19 @@ void tst_qqmlecmascript::callQtInvokables() QJSValue callback = qvariant_cast<QJSValue>(o->actuals().at(1)); QVERIFY(!callback.isNull()); QVERIFY(callback.isCallable()); + + o->reset(); + QVERIFY(EVALUATE_VALUE("object.method_gadget(object.someFont)", + QV4::Primitive::undefinedValue())); + QCOMPARE(o->error(), false); + QCOMPARE(o->invoked(), 40); + QCOMPARE(o->actuals(), QVariantList() << QVariant(o->someFont())); + + o->reset(); + QVERIFY(EVALUATE_ERROR("object.method_gadget(123)")); + QCOMPARE(o->error(), false); + QCOMPARE(o->invoked(), -1); + QCOMPARE(o->actuals(), QVariantList()); } void tst_qqmlecmascript::resolveClashingProperties() @@ -6397,6 +6481,28 @@ void tst_qqmlecmascript::generatorCrashNewProperty() QCOMPARE(o->property("c").toInt(), 42); } +void tst_qqmlecmascript::generatorCallsGC() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("generatorCallsGC.qml")); + + QScopedPointer<QObject> o(component.create()); // should not crash + QVERIFY2(o != nullptr, qPrintable(component.errorString())); +} + +void tst_qqmlecmascript::noYieldInInnerFunction() +{ + QJSEngine engine; + const QString program = R"( + function *a() { + (function() { yield 1; })(); + }; + )"; + auto result = engine.evaluate(program); + QVERIFY(result.isError()); + QCOMPARE(result.errorType(), QJSValue::SyntaxError); +} + // Test the "Qt.include" method void tst_qqmlecmascript::include() { @@ -7552,6 +7658,37 @@ void tst_qqmlecmascript::qpropertyAndQtBinding() QCOMPARE(root->complex.value(), 150); } +void tst_qqmlecmascript::qpropertyBindingReplacement() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("qpropertyBindingReplacement.qml")); + QScopedPointer<QObject> root(c.create()); + QVERIFY(root); + QCOMPARE(root->objectName(), u"overwritten"_qs); +} + +void tst_qqmlecmascript::qpropertyBindingNoQPropertyCapture() +{ + + QQmlEngine engine; + QQmlComponent comp(&engine, testFileUrl("qpropertyBindingNoQPropertyCapture.qml")); + std::unique_ptr<QObject> root(comp.create()); + QVERIFY2(root, qPrintable(comp.errorString())); + auto redRectangle = root.get(); + + QQmlProperty blueRectangleWidth(redRectangle, "blueRectangleWidth", &engine); + + auto toggle = [&](){ + QMetaObject::invokeMethod(root.get(), "toggle"); + }; + + QCOMPARE(blueRectangleWidth.read().toInt(), 25); + toggle(); + QCOMPARE(blueRectangleWidth.read().toInt(), 600); + toggle(); + QCOMPARE(blueRectangleWidth.read().toInt(), 25); +} + void tst_qqmlecmascript::deleteRootObjectInCreation() { QQmlEngine engine; @@ -9107,6 +9244,32 @@ void tst_qqmlecmascript::qpropertyBindingHandlesUndefinedWithoutResetCorrectly() QCOMPARE(root->property("value2").toInt(), 2); } +void tst_qqmlecmascript::qpropertyBindingRestoresObserverAfterReset() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("restoreObserverAfterReset.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + QTRY_COMPARE(o->property("height").toDouble(), 60.0); + QVERIFY(o->property("steps").toInt() > 3); +} + +void tst_qqmlecmascript::qpropertyBindingObserverCorrectlyLinkedAfterReset() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("qpropertyResetCorrectlyLinked.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + std::unique_ptr<QObject> o(c.create()); + QVERIFY(o); + QCOMPARE(o->property("width"), 200); + auto item = qobject_cast<QQuickItem *>(o.get()); + auto itemPriv = QQuickItemPrivate::get(item); + QBindingStorage *storage = qGetBindingStorage(itemPriv); + QPropertyBindingDataPointer ptr { storage->bindingData(&itemPriv->width) }; + QCOMPARE(ptr.observerCount(), 1); +} + void tst_qqmlecmascript::hugeRegexpQuantifiers() { QJSEngine engine; @@ -9694,6 +9857,15 @@ void tst_qqmlecmascript::constPointer() QVERIFY(root->property("propertyOk").toBool()); } +void tst_qqmlecmascript::icUsingJSLib() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("icUsingJSLib.qml")); + QScopedPointer<QObject> root(component.create()); + QVERIFY2(root, qPrintable(component.errorString())); + QCOMPARE(root->property("num").toInt(), 42); +} + void tst_qqmlecmascript::optionalChainEval() { QQmlEngine qmlengine; @@ -9804,6 +9976,192 @@ void tst_qqmlecmascript::asCast() QCOMPARE(qvariant_cast<QObject *>(root->property("rectangleAsRectangle")), rectangle); } +void tst_qqmlecmascript::functionNameInFunctionScope() +{ + QJSEngine engine; + QJSValue result = engine.evaluate(R"( + var a = {}; + var foo = function foo() { + return foo; + } + a.foo = foo(); + + function bar() { + bar = 2; + } + bar() + a.bar = bar; + + var baz = function baz() { + baz = 3; + } + baz() + a.baz = baz; + + var foo2 = function() { + return foo2; + } + a.foo2 = foo2(); + + var baz2 = function() { + baz2 = 3; + } + baz2() + a.baz2 = baz2; + a + + )"); + + QVERIFY(!result.isError()); + const QJSManagedValue m(result, &engine); + + QVERIFY(m.property("foo").isCallable()); + QCOMPARE(m.property("bar").toInt(), 2); + QVERIFY(m.property("baz").isCallable()); + QVERIFY(m.property("foo2").isCallable()); + QCOMPARE(m.property("baz2").toInt(), 3); + + const QJSValue getterInClass = engine.evaluate(R"( + class Tester { + constructor () { + this.a = 1; + this.b = 1; + } + + get sum() { + const sum = this.a + this.b; + return sum; + } + } + )"); + + QVERIFY(!getterInClass.isError()); + + const QJSValue innerName = engine.evaluate(R"( + const a = 2; + var b = function a() { return a }; + ({a: a, b: b, c: b()}) + )"); + + QVERIFY(!innerName.isError()); + const QJSManagedValue m2(innerName, &engine); + QCOMPARE(m2.property("a").toInt(), 2); + QVERIFY(m2.property("b").isCallable()); + QVERIFY(m2.property("c").isCallable()); +} + + +void tst_qqmlecmascript::functionAsDefaultArgument() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("functionAsDefaultArgument.qml")); + QScopedPointer root(component.create()); + QVERIFY(root); + QCOMPARE(root->objectName(), "didRun"); +} + +void tst_qqmlecmascript::internalClassParentGc() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("internalClassParentGc.qml")); + QScopedPointer root(component.create()); + QVERIFY(root); + QCOMPARE(root->objectName(), "3"); +} + +void tst_qqmlecmascript::methodTypeMismatch() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("methodTypeMismatch.qml")); + + QScopedPointer<MyInvokableObject> object(new MyInvokableObject()); + + QScopedPointer<QObject> o(component.create()); + QVERIFY2(o, qPrintable(component.errorString())); + o->setProperty("object", QVariant::fromValue(object.get())); + + auto mo = o->metaObject(); + QVERIFY(mo); + + auto method = mo->method(mo->indexOfMethod("callWithFont()")); + QVERIFY(method.isValid()); + QVERIFY(method.invoke(o.get())); + QCOMPARE(object->actuals(), QVariantList() << QVariant(object->someFont())); + + QRegularExpression argumentConversionErrorMatcher("Could not convert argument 0"); + QRegularExpression argumentConversionErrorMatcher2(".*/methodTypeMismatch.qml"); + QRegularExpression typeErrorMatcher( + ".*/methodTypeMismatch\\.qml:..: TypeError: Passing incompatible arguments to C\\+\\+ " + "functions from JavaScript is not allowed."); + + QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher); + QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher2); + QTest::ignoreMessage(QtWarningMsg, typeErrorMatcher); + object->reset(); + method = mo->method(mo->indexOfMethod("callWithInt()")); + QVERIFY(method.isValid()); + QVERIFY(method.invoke(o.get())); + QCOMPARE(object->actuals().size(), + 0); // actuals() should not contain reinterpret_cast<QFont>(123) !!! + + QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher); + QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher2); + QTest::ignoreMessage(QtWarningMsg, typeErrorMatcher); + object->reset(); + method = mo->method(mo->indexOfMethod("callWithInt2()")); + QVERIFY(method.isValid()); + QVERIFY(method.invoke(o.get())); + QCOMPARE(object->actuals().size(), + 0); // actuals() should not contain reinterpret_cast<QFont>(0) !!! + + QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher); + QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher2); + QTest::ignoreMessage(QtWarningMsg, typeErrorMatcher); + object->reset(); + method = mo->method(mo->indexOfMethod("callWithNull()")); + QVERIFY(method.isValid()); + QVERIFY(method.invoke(o.get())); + QCOMPARE(object->actuals().size(), + 0); // actuals() should not contain reinterpret_cast<QFont>(nullptr) !!! + + // make sure that null is still accepted by functions accepting, e.g., a QObject*! + object->reset(); + method = mo->method(mo->indexOfMethod("callWithAllowedNull()")); + QVERIFY(method.isValid()); + QVERIFY(method.invoke(o.get())); + QCOMPARE(object->actuals(), QVariantList() << QVariant::fromValue((QObject *)nullptr)); +} + +void tst_qqmlecmascript::doNotCrashOnReadOnlyBindable() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("readOnlyBindable.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); +#ifndef QT_NO_DEBUG + QTest::ignoreMessage( + QtWarningMsg, + "setBinding: Could not set binding via bindable interface. " + "The QBindable is read-only."); +#endif + QScopedPointer<QObject> o(c.create()); + QVERIFY(o); + QCOMPARE(o->property("x").toInt(), 7); +} + + +void tst_qqmlecmascript::methodCallOnDerivedSingleton() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFile("methodCallOnDerivedSingleton.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(o); + int singletonTypeId = qmlTypeId("Qt.test", 1, 0, "SingletonInheritanceTest"); + auto singleton = engine.singletonInstance<SingletonBase *>(singletonTypeId); + QVERIFY(singleton); + QVERIFY(singleton->m_okay); +} + QTEST_MAIN(tst_qqmlecmascript) #include "tst_qqmlecmascript.moc" diff --git a/tests/auto/qml/qqmlengine/CMakeLists.txt b/tests/auto/qml/qqmlengine/CMakeLists.txt index f143dddb25a..43fec7cb90c 100644 --- a/tests/auto/qml/qqmlengine/CMakeLists.txt +++ b/tests/auto/qml/qqmlengine/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlengine SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlengine.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::Network Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -38,6 +36,9 @@ qt_internal_add_resource(tst_qqmlengine "qmake_immediate" ${qmake_immediate_resource_files} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmlengine) +endif() ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qqmlengine/data/bindingInstallUseAfterFree.qml b/tests/auto/qml/qqmlengine/data/bindingInstallUseAfterFree.qml new file mode 100644 index 00000000000..596ab10ee7f --- /dev/null +++ b/tests/auto/qml/qqmlengine/data/bindingInstallUseAfterFree.qml @@ -0,0 +1,19 @@ +import QtQuick + +Item { + visible: false + + property int test: 1 + + Component { + id: comp + Item { + width: { width = test * 100 } + } + } + + Loader { + sourceComponent: comp + width: 100 + } +} diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp index e1dff63e034..953bce96033 100644 --- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp +++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp @@ -26,7 +26,6 @@ ** ****************************************************************************/ -#include "../../shared/util.h" #include <QQmlEngine> #include <QQmlContext> #include <QNetworkAccessManager> @@ -46,12 +45,13 @@ #include <private/qqmltypedata_p.h> #include <private/qqmlcomponentattached_p.h> #include <QQmlAbstractUrlInterceptor> +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlengine : public QQmlDataTest { Q_OBJECT public: - tst_qqmlengine() {} + tst_qqmlengine() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; @@ -91,6 +91,8 @@ private slots: void listWrapperAsListReference(); void attachedObjectAsObject(); void listPropertyAsQJSValue(); + void stringToColor(); + void bindingInstallUseAfterFree(); public slots: QObject *createAQObjectForOwnershipTest () @@ -1410,6 +1412,40 @@ void tst_qqmlengine::listPropertyAsQJSValue() QCOMPARE(prop.at(&prop, 0), &c); } +void tst_qqmlengine::stringToColor() +{ + QQmlEngine engine; + + // Make it import QtQuick, so that color becomes available. + QQmlComponent c(&engine); + c.setData("import QtQuick\nItem {}", QUrl()); + QVERIFY(c.isReady()); + QScopedPointer<QObject> o(c.create()); + + const QMetaType metaType(QMetaType::QColor); + QVariant color(metaType); + QVERIFY(engine.handle()->metaTypeFromJS( + engine.handle()->newString(QStringLiteral("#abcdef"))->asReturnedValue(), + metaType, color.data())); + QVERIFY(color.isValid()); + QCOMPARE(color.metaType(), metaType); + + QVariant variant(QStringLiteral("#abcdef")); + QVERIFY(variant.convert(metaType)); + QCOMPARE(variant.metaType(), metaType); + + QCOMPARE(color, variant); +} + +void tst_qqmlengine::bindingInstallUseAfterFree() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("bindingInstallUseAfterFree.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + std::unique_ptr<QObject> o{ c.create() }; + QVERIFY(o); +} + QTEST_MAIN(tst_qqmlengine) #include "tst_qqmlengine.moc" diff --git a/tests/auto/qml/qqmlenginecleanup/BLACKLIST b/tests/auto/qml/qqmlenginecleanup/BLACKLIST index 4fb1d9be4cb..f88fad8dd8b 100644 --- a/tests/auto/qml/qqmlenginecleanup/BLACKLIST +++ b/tests/auto/qml/qqmlenginecleanup/BLACKLIST @@ -1,2 +1,5 @@ [test_customModuleCleanup] windows gcc ci +# QTBUG-102833 +[test_customModuleCleanup] +android diff --git a/tests/auto/qml/qqmlenginecleanup/CMakeLists.txt b/tests/auto/qml/qqmlenginecleanup/CMakeLists.txt index f8637755b7d..fcc9358cd37 100644 --- a/tests/auto/qml/qqmlenginecleanup/CMakeLists.txt +++ b/tests/auto/qml/qqmlenginecleanup/CMakeLists.txt @@ -4,15 +4,20 @@ ## tst_qqmlenginecleanup Test: ##################################################################### +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + qt_internal_add_test(tst_qqmlenginecleanup SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlenginecleanup.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Qml Qt::QmlPrivate + Qt::QuickTestUtilsPrivate + TESTDATA ${test_data} ) ## Scopes: diff --git a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp index 31a71d5e6a0..d8bf86d91a7 100644 --- a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp +++ b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp @@ -26,20 +26,20 @@ ** ****************************************************************************/ -#include "../../shared/util.h" #include <QtCore/QObject> #include <QtQml/qqml.h> #include <QtQml/QQmlEngine> #include <QtQml/QQmlComponent> #include <private/qhashedstring_p.h> #include <private/qqmlmetatype_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> //Separate test, because if engine cleanup attempts fail they can easily break unrelated tests class tst_qqmlenginecleanup : public QQmlDataTest { Q_OBJECT public: - tst_qqmlenginecleanup() {} + tst_qqmlenginecleanup() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void test_qmlClearTypeRegistrations(); diff --git a/tests/auto/qml/qqmlerror/CMakeLists.txt b/tests/auto/qml/qqmlerror/CMakeLists.txt index 7bb8715b01b..359dd826586 100644 --- a/tests/auto/qml/qqmlerror/CMakeLists.txt +++ b/tests/auto/qml/qqmlerror/CMakeLists.txt @@ -12,15 +12,13 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlerror SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlerror.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlerror/tst_qqmlerror.cpp b/tests/auto/qml/qqmlerror/tst_qqmlerror.cpp index f282e604175..6ddf7dfe48d 100644 --- a/tests/auto/qml/qqmlerror/tst_qqmlerror.cpp +++ b/tests/auto/qml/qqmlerror/tst_qqmlerror.cpp @@ -29,11 +29,15 @@ #include <qtest.h> #include <QQmlError> #include <QDebug> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlerror : public QQmlDataTest { Q_OBJECT + +public: + tst_qqmlerror(); + private slots: void url(); void description(); @@ -45,6 +49,11 @@ private slots: void debug(); }; +tst_qqmlerror::tst_qqmlerror() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qqmlerror::url() { QQmlError error; diff --git a/tests/auto/qml/qqmlexpression/CMakeLists.txt b/tests/auto/qml/qqmlexpression/CMakeLists.txt index cc5e69d4bcd..ec90797d410 100644 --- a/tests/auto/qml/qqmlexpression/CMakeLists.txt +++ b/tests/auto/qml/qqmlexpression/CMakeLists.txt @@ -12,15 +12,13 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlexpression SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlexpression.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp b/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp index 494d5af2b8f..aec1816b82b 100644 --- a/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp +++ b/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp @@ -32,13 +32,13 @@ #include <QtQml/qqmlcomponent.h> #include <QtQml/qqmlexpression.h> #include <QtQml/qqmlscriptstring.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlexpression : public QQmlDataTest { Q_OBJECT public: - tst_qqmlexpression() {} + tst_qqmlexpression() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void scriptString(); diff --git a/tests/auto/qml/qqmlfile/tst_qqmlfile.cpp b/tests/auto/qml/qqmlfile/tst_qqmlfile.cpp index a1c8daddcff..77909d85768 100644 --- a/tests/auto/qml/qqmlfile/tst_qqmlfile.cpp +++ b/tests/auto/qml/qqmlfile/tst_qqmlfile.cpp @@ -38,19 +38,145 @@ class tst_qqmlfile : public QObject tst_qqmlfile() {} private Q_SLOTS: + void isLocalFile_data(); + void isLocalFile(); + + void urlToLocalFileOrQrcOverloads_data(); void urlToLocalFileOrQrcOverloads(); + +private: + void urlData(); }; +void tst_qqmlfile::urlData() +{ + QTest::addColumn<QString>("urlString"); + QTest::addColumn<bool>("isLocal"); + QTest::addColumn<QString>("localPath"); + + const QString invalid; + const QString relative = QStringLiteral("foo/bar"); + const QString absolute = QStringLiteral("/foo/bar"); + + QTest::addRow("plain empty") << QStringLiteral("") << false << invalid; + QTest::addRow("plain no slash") << QStringLiteral("foo/bar") << false << invalid; + QTest::addRow("plain 1 slash") << QStringLiteral("/foo/bar") << false << invalid; + QTest::addRow("plain 2 slashes") << QStringLiteral("//foo/bar") << false << invalid; + QTest::addRow("plain 3 slashes") << QStringLiteral("///foo/bar") << false << invalid; + + QTest::addRow(": empty") << QStringLiteral(":") << false << invalid; + QTest::addRow(": no slash") << QStringLiteral(":foo/bar") << false << invalid; + QTest::addRow(": 1 slash") << QStringLiteral(":/foo/bar") << false << invalid; + QTest::addRow(": 2 slashes") << QStringLiteral("://foo/bar") << false << invalid; + QTest::addRow(": 3 slashes") << QStringLiteral(":///foo/bar") << false << invalid; + + QTest::addRow("C empty") << QStringLiteral("C:") << false << invalid; + QTest::addRow("C no slash") << QStringLiteral("C:foo/bar") << false << invalid; + QTest::addRow("C 1 slash") << QStringLiteral("C:/foo/bar") << false << invalid; + QTest::addRow("C 2 slashes") << QStringLiteral("C://foo/bar") << false << invalid; + QTest::addRow("C 3 slashes") << QStringLiteral("C:///foo/bar") << false << invalid; + + QTest::addRow("file empty") << QStringLiteral("file:") << true << QString(); + QTest::addRow("file no slash") << QStringLiteral("file:foo/bar") << true << relative; + QTest::addRow("file 1 slash") << QStringLiteral("file:/foo/bar") << true << absolute; + QTest::addRow("file 2 slashes") << QStringLiteral("file://foo/bar") << true << QStringLiteral("//foo/bar"); + QTest::addRow("file 3 slashes") << QStringLiteral("file:///foo/bar") << true << absolute; + + QTest::addRow("qrc empty") << QStringLiteral("qrc:") << true << QStringLiteral(":"); + QTest::addRow("qrc no slash") << QStringLiteral("qrc:foo/bar") << true << u':' + relative; + QTest::addRow("qrc 1 slash") << QStringLiteral("qrc:/foo/bar") << true << u':' + absolute; + QTest::addRow("qrc 2 slashes") << QStringLiteral("qrc://foo/bar") << false << invalid; + QTest::addRow("qrc 3 slashes") << QStringLiteral("qrc:///foo/bar") << true << u':' + absolute; + + QTest::addRow("file+stuff empty") << QStringLiteral("file+stuff:") << false << invalid; + QTest::addRow("file+stuff no slash") << QStringLiteral("file+stuff:foo/bar") << false << invalid; + QTest::addRow("file+stuff 1 slash") << QStringLiteral("file+stuff:/foo/bar") << false << invalid; + QTest::addRow("file+stuff 2 slashes") << QStringLiteral("file+stuff://foo/bar") << false << invalid; + QTest::addRow("file+stuff 3 slashes") << QStringLiteral("file+stuff:///foo/bar") << false << invalid; + + // "assets:" and "content:" URLs are only treated as local files on android. In contrast to + // "qrc:" and "file:" we're not trying to be clever about multiple slashes. Two slashes are + // prohibited as that says part of what we would recognize as path is actually a URL authority. + // Everything else is android's problem. + +#ifdef Q_OS_ANDROID + const bool hasAssetsAndContent = true; +#else + const bool hasAssetsAndContent = false; +#endif + + const QString assetsEmpty = hasAssetsAndContent ? QStringLiteral("assets:") : invalid; + const QString assetsRelative = hasAssetsAndContent ? (QStringLiteral("assets:") + relative) : invalid; + const QString assetsAbsolute = hasAssetsAndContent ? (QStringLiteral("assets:") + absolute) : invalid; + const QString assetsThreeSlashes = hasAssetsAndContent ? (QStringLiteral("assets://") + absolute) : invalid; + + QTest::addRow("assets empty") << QStringLiteral("assets:") << hasAssetsAndContent << assetsEmpty; + QTest::addRow("assets no slash") << QStringLiteral("assets:foo/bar") << hasAssetsAndContent << assetsRelative; + QTest::addRow("assets 1 slash") << QStringLiteral("assets:/foo/bar") << hasAssetsAndContent << assetsAbsolute; + QTest::addRow("assets 2 slashes") << QStringLiteral("assets://foo/bar") << false << invalid; + QTest::addRow("assets 3 slashes") << QStringLiteral("assets:///foo/bar") << hasAssetsAndContent << assetsThreeSlashes; + + const QString contentEmpty = hasAssetsAndContent ? QStringLiteral("content:") : invalid; + const QString contentRelative = hasAssetsAndContent ? (QStringLiteral("content:") + relative) : invalid; + const QString contentAbsolute = hasAssetsAndContent ? (QStringLiteral("content:") + absolute) : invalid; + const QString contentThreeSlashes = hasAssetsAndContent ? (QStringLiteral("content://") + absolute) : invalid; + + QTest::addRow("content empty") << QStringLiteral("content:") << hasAssetsAndContent << contentEmpty; + QTest::addRow("content no slash") << QStringLiteral("content:foo/bar") << hasAssetsAndContent << contentRelative; + QTest::addRow("content 1 slash") << QStringLiteral("content:/foo/bar") << hasAssetsAndContent << contentAbsolute; + QTest::addRow("content 2 slashes") << QStringLiteral("content://foo/bar") << false << invalid; + QTest::addRow("content 3 slashes") << QStringLiteral("content:///foo/bar") << hasAssetsAndContent << contentThreeSlashes; + + + // These are local files everywhere. Their paths are only meaningful on android, though. + // The inner slashes of the path do not influence the URL parsing. + + QTest::addRow("file:assets empty") << QStringLiteral("file:assets:") << true << QStringLiteral("assets:"); + QTest::addRow("file:assets no slash") << QStringLiteral("file:assets:foo/bar") << true << QStringLiteral("assets:foo/bar"); + QTest::addRow("file:assets 1 slash") << QStringLiteral("file:assets:/foo/bar") << true << QStringLiteral("assets:/foo/bar"); + QTest::addRow("file:assets 2 slashes") << QStringLiteral("file:assets://foo/bar") << true << QStringLiteral("assets://foo/bar"); + QTest::addRow("file:assets 3 slashes") << QStringLiteral("file:assets:///foo/bar") << true << QStringLiteral("assets:///foo/bar"); + + QTest::addRow("file:content empty") << QStringLiteral("file:content:") << true << QStringLiteral("content:"); + QTest::addRow("file:content no slash") << QStringLiteral("file:content:foo/bar") << true << QStringLiteral("content:foo/bar"); + QTest::addRow("file:content 1 slash") << QStringLiteral("file:content:/foo/bar") << true << QStringLiteral("content:/foo/bar"); + QTest::addRow("file:content 2 slashes") << QStringLiteral("file:content://foo/bar") << true << QStringLiteral("content://foo/bar"); + QTest::addRow("file:content 3 slashes") << QStringLiteral("file:content:///foo/bar") << true << QStringLiteral("content:///foo/bar"); +} + +void tst_qqmlfile::isLocalFile_data() +{ + urlData(); +} + +void tst_qqmlfile::isLocalFile() +{ + QFETCH(QString, urlString); + QFETCH(bool, isLocal); + + const QUrl url(urlString); + + QCOMPARE(QQmlFile::isLocalFile(urlString), isLocal); + QCOMPARE(QQmlFile::isLocalFile(url), isLocal); +} + +void tst_qqmlfile::urlToLocalFileOrQrcOverloads_data() +{ + urlData(); +} + void tst_qqmlfile::urlToLocalFileOrQrcOverloads() { - const QString urlString = QStringLiteral("qrc:///example.qml"); + QFETCH(QString, urlString); + QFETCH(QString, localPath); + const QUrl url(urlString); const QString pathForUrlString = QQmlFile::urlToLocalFileOrQrc(urlString); const QString pathForUrl = QQmlFile::urlToLocalFileOrQrc(url); - QCOMPARE(pathForUrlString, pathForUrl); - QCOMPARE(pathForUrlString, QStringLiteral(":/example.qml")); + QCOMPARE(pathForUrlString, localPath); + QCOMPARE(pathForUrl, localPath); } QTEST_GUILESS_MAIN(tst_qqmlfile) diff --git a/tests/auto/qml/qqmlfileselector/CMakeLists.txt b/tests/auto/qml/qqmlfileselector/CMakeLists.txt index 61707f79c7c..4d7c4f840b0 100644 --- a/tests/auto/qml/qqmlfileselector/CMakeLists.txt +++ b/tests/auto/qml/qqmlfileselector/CMakeLists.txt @@ -12,18 +12,20 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlfileselector SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlfileselector.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmlfileselector) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qqmlfileselector/data/qmldirtest/main.qml b/tests/auto/qml/qqmlfileselector/data/qmldirtest/main.qml new file mode 100644 index 00000000000..d6dd2c9b90d --- /dev/null +++ b/tests/auto/qml/qqmlfileselector/data/qmldirtest/main.qml @@ -0,0 +1,13 @@ +import QtQuick +import qmldirtest + +Window { + width: 640 + height: 480 + visible: true + property color color: mybutton.color + + MyButton { + id: mybutton + } +} diff --git a/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+linux/MyButton.qml b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+linux/MyButton.qml new file mode 100644 index 00000000000..cc6eb967dae --- /dev/null +++ b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+linux/MyButton.qml @@ -0,0 +1,7 @@ +import QtQuick + +Rectangle { + width: 300 + height: 50 + color: "blue" +} diff --git a/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+macos/MyButton.qml b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+macos/MyButton.qml new file mode 100644 index 00000000000..5bf632c48d6 --- /dev/null +++ b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/+macos/MyButton.qml @@ -0,0 +1,7 @@ +import QtQuick + +Rectangle { + width: 300 + height: 50 + color: "yellow" +} diff --git a/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/MyButton.qml b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/MyButton.qml new file mode 100644 index 00000000000..32db428c4f0 --- /dev/null +++ b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qml/MyButton.qml @@ -0,0 +1,7 @@ +import QtQuick + +Rectangle { + width: 300 + height: 50 + color: "green" +} diff --git a/tests/auto/qml/qqmlfileselector/data/qmldirtest/qmldir b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qmldir new file mode 100644 index 00000000000..ac68d9097d1 --- /dev/null +++ b/tests/auto/qml/qqmlfileselector/data/qmldirtest/qmldir @@ -0,0 +1,5 @@ +module qmldirtest +MyButton 1.0 qml/MyButton.qml +MyButton 1.0 qml/+linux/MyButton.qml +MyButton 1.0 qml/+macos/MyButton.qml + diff --git a/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp b/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp index bc5cd2cdae6..fe55d8b0565 100644 --- a/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp +++ b/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp @@ -35,19 +35,19 @@ #include <QQmlContext> #include <QLoggingCategory> #include <qqmlinfo.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlfileselector : public QQmlDataTest { Q_OBJECT public: - tst_qqmlfileselector() {} + tst_qqmlfileselector() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void basicTest(); void basicTestCached(); void applicationEngineTest(); - + void qmldirCompatibility(); }; void tst_qqmlfileselector::basicTest() @@ -86,19 +86,30 @@ void tst_qqmlfileselector::basicTestCached() void tst_qqmlfileselector::applicationEngineTest() { QQmlApplicationEngine engine; -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - QQmlFileSelector* selector = QQmlFileSelector::get(&engine); -QT_WARNING_POP - QVERIFY(selector != nullptr); - selector->setExtraSelectors(QStringList() << "basic"); + engine.setExtraFileSelectors(QStringList() << "basic"); + engine.load(testFileUrl("basicTest.qml")); - QQmlComponent component(&engine, testFileUrl("basicTest.qml")); - QObject *object = component.create(); + QVERIFY(!engine.rootObjects().isEmpty()); + QObject *object = engine.rootObjects().at(0); QVERIFY(object != nullptr); QCOMPARE(object->property("value").toString(), QString("selected")); +} - delete object; +void tst_qqmlfileselector::qmldirCompatibility() +{ + QQmlApplicationEngine engine; + engine.addImportPath(dataDirectory()); + engine.load(testFileUrl("qmldirtest/main.qml")); + QVERIFY(!engine.rootObjects().isEmpty()); + QObject *object = engine.rootObjects().at(0); + auto color = object->property("color").value<QColor>(); +#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) + QCOMPARE(color, QColorConstants::Svg::blue); +#elif defined(Q_OS_DARWIN) + QCOMPARE(color, QColorConstants::Svg::yellow); +#else + QCOMPARE(color, QColorConstants::Svg::green); +#endif } QTEST_MAIN(tst_qqmlfileselector) diff --git a/tests/auto/qml/qqmlimport/CMakeLists.txt b/tests/auto/qml/qqmlimport/CMakeLists.txt index 3d4f01da2cb..6392a527a4d 100644 --- a/tests/auto/qml/qqmlimport/CMakeLists.txt +++ b/tests/auto/qml/qqmlimport/CMakeLists.txt @@ -24,15 +24,13 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlimport SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlimport.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Qml Qt::QmlPrivate Qt::Quick + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlimport/data/absoluteImport.qml b/tests/auto/qml/qqmlimport/data/absoluteImport.qml new file mode 100644 index 00000000000..d182fe5b71a --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/absoluteImport.qml @@ -0,0 +1,4 @@ +import "/foo/bar/baz" + +QtObject {} + diff --git a/tests/auto/qml/qqmlimport/data/absoluteResourceImport.qml b/tests/auto/qml/qqmlimport/data/absoluteResourceImport.qml new file mode 100644 index 00000000000..74b98664aa3 --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/absoluteResourceImport.qml @@ -0,0 +1,4 @@ +import ":/absolute/resource/path" + +QtObject {} + diff --git a/tests/auto/qml/qqmlimport/data/fileDotSlashImport.qml b/tests/auto/qml/qqmlimport/data/fileDotSlashImport.qml new file mode 100644 index 00000000000..83dbd566f3b --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/fileDotSlashImport.qml @@ -0,0 +1,6 @@ +import QtQml +import 'file://./MyModuleName' as MyModuleName + +QtObject { + objectName: MyModuleName.Font.exampleVar +} diff --git a/tests/auto/qml/qqmlimport/data/importPathOrder/MyModuleTest.qml b/tests/auto/qml/qqmlimport/data/importPathOrder/MyModuleTest.qml new file mode 100644 index 00000000000..5ac9ec4fb2f --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/importPathOrder/MyModuleTest.qml @@ -0,0 +1,7 @@ +import QtQuick +import MyModule + +Item { + MyItem { objectName: "myItem1" } + MyView {} +} diff --git a/tests/auto/qml/qqmlimport/data/importPathOrder/MyView.qml b/tests/auto/qml/qqmlimport/data/importPathOrder/MyView.qml new file mode 100644 index 00000000000..a4fdcb51a0c --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/importPathOrder/MyView.qml @@ -0,0 +1,3 @@ +import MyModule + +MyItem { objectName: "myItem2" } diff --git a/tests/auto/qml/qqmlimport/data/importPathOrder/path1/MyModule/MyItem.qml b/tests/auto/qml/qqmlimport/data/importPathOrder/path1/MyModule/MyItem.qml new file mode 100644 index 00000000000..3da82d1b770 --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/importPathOrder/path1/MyModule/MyItem.qml @@ -0,0 +1,6 @@ +import QtQuick + +Item { + width: 100 + height: 100 +} diff --git a/tests/auto/qml/qqmlimport/data/importPathOrder/path1/MyModule/qmldir b/tests/auto/qml/qqmlimport/data/importPathOrder/path1/MyModule/qmldir new file mode 100644 index 00000000000..edfd2c94624 --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/importPathOrder/path1/MyModule/qmldir @@ -0,0 +1,3 @@ +module MyModule + +MyItem MyItem.qml diff --git a/tests/auto/qml/qqmlimport/data/importPathOrder/path2/MyModule/MyItem.qml b/tests/auto/qml/qqmlimport/data/importPathOrder/path2/MyModule/MyItem.qml new file mode 100644 index 00000000000..ed02d2df7a6 --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/importPathOrder/path2/MyModule/MyItem.qml @@ -0,0 +1,6 @@ +import QtQuick + +Item { + width: 200 + height: 200 +} diff --git a/tests/auto/qml/qqmlimport/data/importPathOrder/path2/MyModule/qmldir b/tests/auto/qml/qqmlimport/data/importPathOrder/path2/MyModule/qmldir new file mode 100644 index 00000000000..edfd2c94624 --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/importPathOrder/path2/MyModule/qmldir @@ -0,0 +1,3 @@ +module MyModule + +MyItem MyItem.qml diff --git a/tests/auto/qml/qqmlimport/data/importQtQuickTooling.qml b/tests/auto/qml/qqmlimport/data/importQtQuickTooling.qml new file mode 100644 index 00000000000..5b094adfffd --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/importQtQuickTooling.qml @@ -0,0 +1,4 @@ +import QtQuick.tooling + +Property { +} diff --git a/tests/auto/qml/qqmlimport/data/relativeResourceImport.qml b/tests/auto/qml/qqmlimport/data/relativeResourceImport.qml new file mode 100644 index 00000000000..6a7e2b7ea55 --- /dev/null +++ b/tests/auto/qml/qqmlimport/data/relativeResourceImport.qml @@ -0,0 +1,4 @@ +import ":relative/resource/path" + +QtObject {} + diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp index 4f2b4f6b13f..35b035ae9cf 100644 --- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp +++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp @@ -34,12 +34,15 @@ #include <QtQuick/qquickitem.h> #include <private/qqmlimport_p.h> #include <private/qqmlengine_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_QQmlImport : public QQmlDataTest { Q_OBJECT +public: + tst_QQmlImport(); + private slots: void importPathOrder(); void testDesignerSupported(); @@ -56,6 +59,9 @@ private slots: void cleanup(); void envResourceImportPath(); void preferResourcePath(); + void invalidFileImport_data(); + void invalidFileImport(); + void invalidImportUrl(); }; void tst_QQmlImport::cleanup() @@ -101,6 +107,48 @@ void tst_QQmlImport::preferResourcePath() QCOMPARE(o->objectName(), "right"); } +void tst_QQmlImport::invalidFileImport_data() +{ + QTest::addColumn<QString>("file"); + QTest::addColumn<QString>("import"); + QTest::addRow("file absolute") + << QStringLiteral("absoluteImport.qml") + << QStringLiteral("/foo/bar/baz"); + QTest::addRow("resource absolute") + << QStringLiteral("absoluteResourceImport.qml") + << QStringLiteral(":/absolute/resource/path"); + QTest::addRow("resource relative") + << QStringLiteral("relativeResourceImport.qml") + << QStringLiteral(":relative/resource/path"); +} + +void tst_QQmlImport::invalidFileImport() +{ + QFETCH(QString, file); + QFETCH(QString, import); + + QQmlEngine engine; + + QQmlComponent component(&engine, testFileUrl(file)); + QVERIFY(component.isError()); + QVERIFY(component.errorString().contains( + QStringLiteral("\"%1\" is not a valid import URL. " + "You can pass relative paths or URLs with schema, " + "but not absolute paths or resource paths.").arg(import))); +} + +void tst_QQmlImport::invalidImportUrl() +{ + QQmlEngine engine; + const QUrl url = testFileUrl("fileDotSlashImport.qml"); + QQmlComponent component(&engine, url); + QVERIFY(component.isError()); + QCOMPARE( + component.errorString(), + url.toString() + QLatin1String( + ":2 Cannot resolve URL for import \"file://./MyModuleName\"\n")); +} + void tst_QQmlImport::testDesignerSupported() { QQuickView *window = new QQuickView(); @@ -125,7 +173,7 @@ void tst_QQmlImport::testDesignerSupported() QVERIFY(window->errors().isEmpty()); QString warningString("%1:30:1: module does not support the designer \"MyPluginUnsupported\" \n import MyPluginUnsupported 1.0\r \n ^ "); -#if !defined(Q_OS_WIN) && !defined(Q_OS_ANDROID) +#if !defined(Q_OS_WIN) warningString.remove('\r'); #endif warningString = warningString.arg(testFileUrl("testfile_unsupported.qml").toString()); @@ -175,6 +223,11 @@ void tst_QQmlImport::uiFormatLoading() delete test; } +tst_QQmlImport::tst_QQmlImport() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QQmlImport::importPathOrder() { #ifdef Q_OS_ANDROID @@ -205,6 +258,22 @@ void tst_QQmlImport::importPathOrder() engine.addImportPath(qml2Imports); expectedImportPaths.move(expectedImportPaths.indexOf(qml2Imports), 0); QCOMPARE(engine.importPathList(), expectedImportPaths); + + // Verify if the type in the module comes first in the import path list + // takes the precedence. In the case below, the width of both items + // should be the same to that of the type defined in "path2". + engine.addImportPath(testFile("importPathOrder/path1")); + engine.addImportPath(testFile("importPathOrder/path2")); + QQmlComponent component(&engine, testFile("importPathOrder/MyModuleTest.qml")); + QScopedPointer<QObject> rootItem(component.create()); + QVERIFY(component.errorString().isEmpty()); + QVERIFY(!rootItem.isNull()); + QQuickItem *item1 = rootItem->findChild<QQuickItem*>("myItem1"); + QQuickItem *item2 = rootItem->findChild<QQuickItem*>("myItem2"); + QVERIFY(item1 != nullptr); + QVERIFY(item2 != nullptr); + QCOMPARE(item1->width(), 200); + QCOMPARE(item2->width(), 200); } Q_DECLARE_METATYPE(QQmlImports::ImportVersion) @@ -286,7 +355,7 @@ void tst_QQmlImport::interceptQmldir() QQmlComponent component(&engine); component.loadUrl(testFileUrl("interceptQmldir.qml")); - QVERIFY(component.isReady()); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); QScopedPointer<QObject> obj(component.create()); QVERIFY(!obj.isNull()); } @@ -300,7 +369,7 @@ void tst_QQmlImport::singletonVersionResolution() // Singleton with higher version is simply ignored when importing lower version of plugin QQmlComponent component(&engine); component.loadUrl(testFileUrl("QTBUG-77102/main.0.9.qml")); - QVERIFY(component.isReady()); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); QScopedPointer<QObject> obj(component.create()); QVERIFY(!obj.isNull()); } @@ -309,7 +378,7 @@ void tst_QQmlImport::singletonVersionResolution() QQmlComponent component(&engine); QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression {".*ReferenceError: MySettings is not defined$"} ); component.loadUrl(testFileUrl("QTBUG-77102/main.0.9.fail.qml")); - QVERIFY(component.isReady()); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); QScopedPointer<QObject> obj(component.create()); QVERIFY(!obj.isNull()); } @@ -317,7 +386,7 @@ void tst_QQmlImport::singletonVersionResolution() // unless a version which is high enough is imported QQmlComponent component(&engine); component.loadUrl(testFileUrl("QTBUG-77102/main.1.0.qml")); - QVERIFY(component.isReady()); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); QScopedPointer<QObject> obj(component.create()); QVERIFY(!obj.isNull()); auto item = qobject_cast<QQuickItem*>(obj.get()); @@ -327,7 +396,7 @@ void tst_QQmlImport::singletonVersionResolution() // or when there is no number because we are importing from a path QQmlComponent component(&engine); component.loadUrl(testFileUrl("QTBUG-77102/main.nonumber.qml")); - QVERIFY(component.isReady()); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); QScopedPointer<QObject> obj(component.create()); QVERIFY(!obj.isNull()); auto item = qobject_cast<QQuickItem*>(obj.get()); @@ -341,9 +410,10 @@ void tst_QQmlImport::removeDynamicPlugin() QQmlEngine engine; { // Load something that adds a dynamic plugin - QQmlComponent component(&engine); - component.setData(QByteArray("import QtTest 1.0; TestResult{}"), QUrl()); - QVERIFY(component.isReady()); + QQmlComponent component(&engine, testFileUrl("importQtQuickTooling.qml")); + // Make sure to use something other than QtTest here, since the !plugins.isEmpty() + // check will fail if we do. + QVERIFY2(component.isReady(), qPrintable(component.errorString())); } QQmlImportDatabase *imports = &QQmlEnginePrivate::get(&engine)->importDatabase; const QStringList &plugins = imports->dynamicPlugins(); @@ -433,7 +503,7 @@ void tst_QQmlImport::importDependenciesPrecedence() engine.addImportPath(dataDirectory()); QQmlComponent component(&engine, testFile("dependencies.qml")); - QVERIFY(component.isReady()); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); QScopedPointer<QObject> instance(component.create()); QVERIFY(!instance.isNull()); diff --git a/tests/auto/qml/qqmlincubator/CMakeLists.txt b/tests/auto/qml/qqmlincubator/CMakeLists.txt index 34f794b7d92..b2ade30c393 100644 --- a/tests/auto/qml/qqmlincubator/CMakeLists.txt +++ b/tests/auto/qml/qqmlincubator/CMakeLists.txt @@ -12,20 +12,22 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlincubator SOURCES - ../../shared/util.cpp ../../shared/util.h testtypes.cpp testtypes.h tst_qqmlincubator.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::Network Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmlincubator) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp index 7784afd35b6..5850ddfa54e 100644 --- a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp +++ b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp @@ -38,16 +38,16 @@ #include <QQmlProperty> #include <QQmlComponent> #include <QQmlIncubator> -#include "../../shared/util.h" #include <private/qjsvalue_p.h> #include <private/qqmlincubator_p.h> #include <private/qqmlobjectcreator_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlincubator : public QQmlDataTest { Q_OBJECT public: - tst_qqmlincubator() {} + tst_qqmlincubator() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/qml/qqmlinfo/CMakeLists.txt b/tests/auto/qml/qqmlinfo/CMakeLists.txt index 4d234e8ce0b..3020b84c595 100644 --- a/tests/auto/qml/qqmlinfo/CMakeLists.txt +++ b/tests/auto/qml/qqmlinfo/CMakeLists.txt @@ -12,19 +12,21 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlinfo SOURCES - ../../shared/util.cpp ../../shared/util.h attached.cpp attached.h tst_qqmlinfo.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmlinfo) +endif() + #### Keys ignored in scope 1:.:.:qqmlinfo.pro:<TRUE>: # QML_IMPORT_MAJOR_VERSION = "1" # QML_IMPORT_NAME = "org.qtproject.Test" @@ -47,4 +49,4 @@ set_target_properties(tst_qqmlinfo PROPERTIES QT_QML_MODULE_URI org.qtproject.Test ) -qt6_qml_type_registration(tst_qqmlinfo) +_qt_internal_qml_type_registration(tst_qqmlinfo) diff --git a/tests/auto/qml/qqmlinfo/tst_qqmlinfo.cpp b/tests/auto/qml/qqmlinfo/tst_qqmlinfo.cpp index 7b7a12ee1bf..e7e7d3be767 100644 --- a/tests/auto/qml/qqmlinfo/tst_qqmlinfo.cpp +++ b/tests/auto/qml/qqmlinfo/tst_qqmlinfo.cpp @@ -33,7 +33,7 @@ #include <QTimer> #include <QQmlContext> #include <qqmlinfo.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include "attached.h" @@ -41,7 +41,7 @@ class tst_qqmlinfo : public QQmlDataTest { Q_OBJECT public: - tst_qqmlinfo() {} + tst_qqmlinfo() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void qmlObject(); diff --git a/tests/auto/qml/qqmlinstantiator/CMakeLists.txt b/tests/auto/qml/qqmlinstantiator/CMakeLists.txt index b7d967ca9ff..ffe3a10b17a 100644 --- a/tests/auto/qml/qqmlinstantiator/CMakeLists.txt +++ b/tests/auto/qml/qqmlinstantiator/CMakeLists.txt @@ -12,17 +12,15 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlinstantiator SOURCES - ../../shared/util.cpp ../../shared/util.h stringmodel.h tst_qqmlinstantiator.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlModelsPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlinstantiator/data/activeModelChangeInteraction.qml b/tests/auto/qml/qqmlinstantiator/data/activeModelChangeInteraction.qml new file mode 100644 index 00000000000..2797566ad29 --- /dev/null +++ b/tests/auto/qml/qqmlinstantiator/data/activeModelChangeInteraction.qml @@ -0,0 +1,39 @@ +import QtQuick 2.15 +import QtQml.Models 2.15 + +Item { + id: root + property int instanceCount: 0 + property alias active: instantiator.active + + ListModel { + id: listmodel + + dynamicRoles: true + } + + Component.onCompleted: { + listmodel.insert(listmodel.count, {name: "one"}) + listmodel.insert(listmodel.count, {name: "two"}) + listmodel.insert(listmodel.count, {name: "three"}) + } + + Instantiator { + id: instantiator + + active: false + + model: listmodel + + delegate: Text { + width: 100 + height: 20 + + text: name + + Component.onCompleted: ++root.instanceCount + } + + } +} + diff --git a/tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp b/tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp index 84e08c471a7..3524d5de643 100644 --- a/tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp +++ b/tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp @@ -34,19 +34,23 @@ #include <QtQmlModels/private/qqmlinstantiator_p.h> #include <QtQml/qqmlcontext.h> #include <QtQml/qqmlincubator.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include "stringmodel.h" class tst_qqmlinstantiator: public QQmlDataTest { Q_OBJECT +public: + tst_qqmlinstantiator(); + private slots: void createNone(); void createSingle(); void createMultiple(); void stringModel(); void activeProperty(); + void activeModelChangeInteraction(); void intModelChange(); void createAndRemove(); @@ -54,11 +58,17 @@ private slots: void asynchronous(); }; +tst_qqmlinstantiator::tst_qqmlinstantiator() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qqmlinstantiator::createNone() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("createNone.qml")); - QQmlInstantiator *instantiator = qobject_cast<QQmlInstantiator*>(component.create()); + QScopedPointer<QObject> o(component.create()); + QQmlInstantiator *instantiator = qobject_cast<QQmlInstantiator*>(o.data()); QVERIFY(instantiator != nullptr); QCOMPARE(instantiator->isActive(), true); QCOMPARE(instantiator->count(), 0); @@ -70,7 +80,8 @@ void tst_qqmlinstantiator::createSingle() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("createSingle.qml")); - QQmlInstantiator *instantiator = qobject_cast<QQmlInstantiator*>(component.create()); + QScopedPointer<QObject> o(component.create()); + QQmlInstantiator *instantiator = qobject_cast<QQmlInstantiator*>(o.data()); QVERIFY(instantiator != nullptr); QCOMPARE(instantiator->isActive(), true); QCOMPARE(instantiator->count(), 1); @@ -87,7 +98,8 @@ void tst_qqmlinstantiator::createMultiple() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("createMultiple.qml")); - QQmlInstantiator *instantiator = qobject_cast<QQmlInstantiator*>(component.create()); + QScopedPointer<QObject> o(component.create()); + QQmlInstantiator *instantiator = qobject_cast<QQmlInstantiator*>(o.data()); QVERIFY(instantiator != nullptr); QCOMPARE(instantiator->isActive(), true); QCOMPARE(instantiator->count(), 10); @@ -105,7 +117,8 @@ void tst_qqmlinstantiator::stringModel() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("stringModel.qml")); - QQmlInstantiator *instantiator = qobject_cast<QQmlInstantiator*>(component.create()); + QScopedPointer<QObject> o(component.create()); + QQmlInstantiator *instantiator = qobject_cast<QQmlInstantiator*>(o.data()); QVERIFY(instantiator != nullptr); QCOMPARE(instantiator->isActive(), true); QCOMPARE(instantiator->count(), 4); @@ -122,7 +135,8 @@ void tst_qqmlinstantiator::activeProperty() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("inactive.qml")); - QQmlInstantiator *instantiator = qobject_cast<QQmlInstantiator*>(component.create()); + QScopedPointer<QObject> o(component.create()); + QQmlInstantiator *instantiator = qobject_cast<QQmlInstantiator*>(o.data()); QVERIFY(instantiator != nullptr); QSignalSpy activeSpy(instantiator, SIGNAL(activeChanged())); QSignalSpy countSpy(instantiator, SIGNAL(countChanged())); @@ -153,11 +167,32 @@ void tst_qqmlinstantiator::activeProperty() QCOMPARE(object->property("idx").toInt(), 0); } +void tst_qqmlinstantiator::activeModelChangeInteraction() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("activeModelChangeInteraction.qml")); + QScopedPointer<QObject> root(component.create()); + QVERIFY(root); + + // If the instantiator is inactive, a model change does not lead to items being loaded + bool ok = false; + int count = root->property("instanceCount").toInt(&ok); + QVERIFY(ok); + QCOMPARE(count, 0); + + // When turning the instantiator active, it will however reflect the model + root->setProperty("active", true); + count = root->property("instanceCount").toInt(&ok); + QVERIFY(ok); + QCOMPARE(count, 3); +} + void tst_qqmlinstantiator::intModelChange() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("createMultiple.qml")); - QQmlInstantiator *instantiator = qobject_cast<QQmlInstantiator*>(component.create()); + QScopedPointer<QObject> o(component.create()); + QQmlInstantiator *instantiator = qobject_cast<QQmlInstantiator*>(o.data()); QVERIFY(instantiator != nullptr); QSignalSpy activeSpy(instantiator, SIGNAL(activeChanged())); QSignalSpy countSpy(instantiator, SIGNAL(countChanged())); @@ -193,7 +228,7 @@ void tst_qqmlinstantiator::createAndRemove() QScopedPointer<StringModel> model {new StringModel("model1")}; qmlRegisterSingletonInstance("Test", 1, 0, "Model1", model.get()); QQmlComponent component(&engine, testFileUrl("createAndRemove.qml")); - QObject *rootObject = component.create(); + QScopedPointer<QObject> rootObject(component.create()); QVERIFY(rootObject != nullptr); QQmlInstantiator *instantiator = diff --git a/tests/auto/qml/qqmlitemmodels/CMakeLists.txt b/tests/auto/qml/qqmlitemmodels/CMakeLists.txt index 5246638739e..7955eeba7b9 100644 --- a/tests/auto/qml/qqmlitemmodels/CMakeLists.txt +++ b/tests/auto/qml/qqmlitemmodels/CMakeLists.txt @@ -12,15 +12,13 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlitemmodels SOURCES - ../../shared/util.cpp ../../shared/util.h qtestmodel.h testtypes.h tst_qqmlitemmodels.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Qml + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlitemmodels/data/modelindex.qml b/tests/auto/qml/qqmlitemmodels/data/modelindex.qml index 0d6e3624cbe..2756f04120b 100644 --- a/tests/auto/qml/qqmlitemmodels/data/modelindex.qml +++ b/tests/auto/qml/qqmlitemmodels/data/modelindex.qml @@ -1,3 +1,4 @@ +import QtQml 2.0 import Test 1.0 ItemModelsTest { diff --git a/tests/auto/qml/qqmlitemmodels/data/persistentmodelindex.qml b/tests/auto/qml/qqmlitemmodels/data/persistentmodelindex.qml index 13037065a6f..85987bdcac4 100644 --- a/tests/auto/qml/qqmlitemmodels/data/persistentmodelindex.qml +++ b/tests/auto/qml/qqmlitemmodels/data/persistentmodelindex.qml @@ -1,3 +1,4 @@ +import QtQml 2.0 import Test 1.0 ItemModelsTest { diff --git a/tests/auto/qml/qqmlitemmodels/tst_qqmlitemmodels.cpp b/tests/auto/qml/qqmlitemmodels/tst_qqmlitemmodels.cpp index 21bde0dd144..6fb86b98d53 100644 --- a/tests/auto/qml/qqmlitemmodels/tst_qqmlitemmodels.cpp +++ b/tests/auto/qml/qqmlitemmodels/tst_qqmlitemmodels.cpp @@ -31,7 +31,7 @@ #include <QQmlComponent> #include <QDebug> #include <QStringListModel> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include "testtypes.h" #include "qtestmodel.h" @@ -45,7 +45,7 @@ class tst_qqmlitemmodels : public QQmlDataTest Q_OBJECT public: - tst_qqmlitemmodels() {} + tst_qqmlitemmodels() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/qml/qqmljsscope/BLACKLIST b/tests/auto/qml/qqmljsscope/BLACKLIST new file mode 100644 index 00000000000..1cae50360f8 --- /dev/null +++ b/tests/auto/qml/qqmljsscope/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-100020 +[orderedBindings] +android diff --git a/tests/auto/qml/qqmllanguage/CMakeLists.txt b/tests/auto/qml/qqmllanguage/CMakeLists.txt index e7fa05d23ed..08d747b8182 100644 --- a/tests/auto/qml/qqmllanguage/CMakeLists.txt +++ b/tests/auto/qml/qqmllanguage/CMakeLists.txt @@ -12,18 +12,15 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmllanguage SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h testtypes.cpp testtypes.h tst_qqmllanguage.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::Network Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -67,4 +64,4 @@ set_target_properties(tst_qqmllanguage PROPERTIES QT_QML_MODULE_URI StaticTest ) -qt6_qml_type_registration(tst_qqmllanguage) +_qt_internal_qml_type_registration(tst_qqmllanguage) diff --git a/tests/auto/qml/qqmllanguage/data/Broken.qml b/tests/auto/qml/qqmllanguage/data/Broken.qml new file mode 100644 index 00000000000..e1b61f31f4a --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/Broken.qml @@ -0,0 +1,5 @@ +import QtQml + +QtObject { + notThere: 5 +} diff --git a/tests/auto/qml/qqmllanguage/data/ComponentType.qml b/tests/auto/qml/qqmllanguage/data/ComponentType.qml new file mode 100644 index 00000000000..e8addde1c40 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/ComponentType.qml @@ -0,0 +1,8 @@ +import QtQml + +Component { + id: componentRoot + QtObject { + objectName: "enclosed" + } +} diff --git a/tests/auto/qml/qqmllanguage/data/DeepAliasOnIC.qml b/tests/auto/qml/qqmllanguage/data/DeepAliasOnIC.qml new file mode 100644 index 00000000000..bde2ad98139 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/DeepAliasOnIC.qml @@ -0,0 +1,28 @@ +import QtQml + +QtObject { + id: root + objectName: "theRoot" + + component ObjectWithColor: QtObject { + property string color + property var varvar + } + + property ObjectWithColor border: ObjectWithColor { + id: border + objectName: root.objectName + color: root.trueBorderColor + varvar: root.trueBorderVarvar + } + + readonly property rect readonlyRect: Qt.rect(12, 13, 14, 15) + + property alias borderObjectName: border.objectName + property alias borderColor: border.color + property alias borderVarvar: border.varvar + property alias readonlyRectX: root.readonlyRect.x + + property string trueBorderColor: "green" + property var trueBorderVarvar: 1234 +} diff --git a/tests/auto/qml/qqmllanguage/data/GroupFailureInner.qml b/tests/auto/qml/qqmllanguage/data/GroupFailureInner.qml new file mode 100644 index 00000000000..7972cc96834 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/GroupFailureInner.qml @@ -0,0 +1,2 @@ +import QtQml +QtObject { property url u } diff --git a/tests/auto/qml/qqmllanguage/data/GroupFailureOuter.qml b/tests/auto/qml/qqmllanguage/data/GroupFailureOuter.qml new file mode 100644 index 00000000000..2a34a29789f --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/GroupFailureOuter.qml @@ -0,0 +1,5 @@ +import QtQml + +QtObject { + property GroupFailureInner b +} diff --git a/tests/auto/qml/qqmllanguage/data/MyRectangle.qml b/tests/auto/qml/qqmllanguage/data/MyRectangle.qml new file mode 100644 index 00000000000..4d5e7c6c8dd --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/MyRectangle.qml @@ -0,0 +1,10 @@ +import QtQuick + +Item { + property alias rectangle1AnchorsleftMargin: rectangle1.anchors.leftMargin + + Rectangle { + id: rectangle1 + anchors.leftMargin: 250 + } +} diff --git a/tests/auto/qml/qqmllanguage/data/SignalInlineComponentArg.qml b/tests/auto/qml/qqmllanguage/data/SignalInlineComponentArg.qml new file mode 100644 index 00000000000..0424ac1534b --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/SignalInlineComponentArg.qml @@ -0,0 +1,21 @@ +import QtQuick + +Item { + component Abc: Item { + property string success + } + + signal canYouFeelIt(arg1: Abc) + property Abc someAbc: Abc { + success: "Signal was called" + } + property string success: "Signal not called yet" + + Component.onCompleted: { + canYouFeelIt(someAbc); + } + + onCanYouFeelIt: (arg) => { + success = arg.success + } +} diff --git a/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle1.qml b/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle1.qml new file mode 100644 index 00000000000..6186faa00b6 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle1.qml @@ -0,0 +1,15 @@ +import QtQml + +QtObject { + id: self + property QtObject b + property Component c + function a() : TypeAnnotationCycle2 { return c.createObject() as TypeAnnotationCycle2 } + + Component.onCompleted: { + c = Qt.createComponent("TypeAnnotationCycle2.qml"); + let v = a(); + v.addTypeAnnotationCycle1(self as TypeAnnotationCycle1); + b = v.b; + } +} diff --git a/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle2.qml b/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle2.qml new file mode 100644 index 00000000000..9e3ffa86d23 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/TypeAnnotationCycle2.qml @@ -0,0 +1,6 @@ +import QtQml + +QtObject { + property QtObject b + function addTypeAnnotationCycle1(c: TypeAnnotationCycle1) { b = c; } +} diff --git a/tests/auto/qml/qqmllanguage/data/alias.15.qml b/tests/auto/qml/qqmllanguage/data/alias.15.qml index 5f3de9c83e5..7e362d8823d 100644 --- a/tests/auto/qml/qqmllanguage/data/alias.15.qml +++ b/tests/auto/qml/qqmllanguage/data/alias.15.qml @@ -9,4 +9,25 @@ Item { Item { id: symbol } + + Rectangle { + id: txtElevationValue + + property Rectangle background: Rectangle { } + + state: "ValidatorInvalid" + + states: [ + State { + name: "ValidatorInvalid" + PropertyChanges { + target: txtElevationValue + background.border.color: "red" // this line caused the segfault in qtbug107795 + } + }, + State { + name: "ValidatorAcceptable" + } + ] + } } diff --git a/tests/auto/qml/qqmllanguage/data/alias.15a.qml b/tests/auto/qml/qqmllanguage/data/alias.15a.qml new file mode 100644 index 00000000000..ba8097c997f --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/alias.15a.qml @@ -0,0 +1,12 @@ +import QtQuick 2.15 + +Item { + id: root + + property alias symbol: symbol + symbol.layer.enabled: true + + Item { + id: symbol + } +} diff --git a/tests/auto/qml/qqmllanguage/data/alias.19.qml b/tests/auto/qml/qqmllanguage/data/alias.19.qml new file mode 100644 index 00000000000..a96c0c694db --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/alias.19.qml @@ -0,0 +1,11 @@ +import QtQuick + +Item { + id: myThing + width: 1920 + + MyRectangle { + rectangle1AnchorsleftMargin: myThing.width / 2 + Component.onCompleted: myThing.height = rectangle1AnchorsleftMargin + } +} diff --git a/tests/auto/qml/qqmllanguage/data/ambiguousBinding/TestCase.qml b/tests/auto/qml/qqmllanguage/data/ambiguousBinding/TestCase.qml new file mode 100644 index 00000000000..c76d2b679e2 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/ambiguousBinding/TestCase.qml @@ -0,0 +1,6 @@ +import QtQml 2.15 +import QtTest 1.0 + +QtObject { + component Comp: QtObject {} +} diff --git a/tests/auto/qml/qqmllanguage/data/ambiguousBinding/ambiguousContainingType.qml b/tests/auto/qml/qqmllanguage/data/ambiguousBinding/ambiguousContainingType.qml new file mode 100644 index 00000000000..765dc91fe1a --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/ambiguousBinding/ambiguousContainingType.qml @@ -0,0 +1,3 @@ +import QtQml 2.15 + +TestCase {} diff --git a/tests/auto/qml/qqmllanguage/data/asBroken.qml b/tests/auto/qml/qqmllanguage/data/asBroken.qml new file mode 100644 index 00000000000..381a012df6b --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/asBroken.qml @@ -0,0 +1,6 @@ +import QtQml + +QtObject { + id: self + property var selfAsBroken: self as Broken +} diff --git a/tests/auto/qml/qqmllanguage/data/badGroupedProperty.qml b/tests/auto/qml/qqmllanguage/data/badGroupedProperty.qml new file mode 100644 index 00000000000..1b8ba617252 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/badGroupedProperty.qml @@ -0,0 +1,10 @@ +import QtQml + +QtObject { + id: testItem + property rect rect + onComplete { + rect.x: 2 + rect.width: 22 + } +} diff --git a/tests/auto/qml/qqmllanguage/data/bindingAliasToComponentUrl.qml b/tests/auto/qml/qqmllanguage/data/bindingAliasToComponentUrl.qml new file mode 100644 index 00000000000..44fbd033545 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/bindingAliasToComponentUrl.qml @@ -0,0 +1,10 @@ +import QtQuick +Item { + id: root + Component { + id: accessibleNormal + Item {} + } + property alias accessibleNormalUrl: accessibleNormal.url + property url urlClone: root.accessibleNormalUrl // crashes qml utility +} diff --git a/tests/auto/qml/qqmllanguage/data/bindingAliasToComponentUrl2.qml b/tests/auto/qml/qqmllanguage/data/bindingAliasToComponentUrl2.qml new file mode 100644 index 00000000000..cfdec5e39bd --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/bindingAliasToComponentUrl2.qml @@ -0,0 +1,11 @@ +import QtQuick +Item { + id: root + Component { + id: accessibleNormal + ComponentType { + id: inaccessibleNormal + } + } + property alias accessibleNormalProgress: accessibleNormal.progress +} diff --git a/tests/auto/qml/qqmllanguage/data/componentMix.qml b/tests/auto/qml/qqmllanguage/data/componentMix.qml new file mode 100644 index 00000000000..0edc997484a --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/componentMix.qml @@ -0,0 +1,18 @@ +import QtQml + +QtObject { + component View: QtObject { + default property Component delegate + } + + component Things : QtObject { + property QtObject view: View { delegate: QtObject {} } + } + + component Delegated : View { + delegate: QtObject {} + } + + property Things things: Things {} + property Delegated delegated: Delegated {} +} diff --git a/tests/auto/qml/qqmllanguage/data/deepAliasOnICUser.qml b/tests/auto/qml/qqmllanguage/data/deepAliasOnICUser.qml new file mode 100644 index 00000000000..50eaa7c3e2a --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/deepAliasOnICUser.qml @@ -0,0 +1,9 @@ +import QtQml + +DeepAliasOnIC { + borderObjectName: "theLeaf" + borderColor: "black" + borderVarvar: "mauve" +} + + diff --git a/tests/auto/qml/qqmllanguage/data/deepAliasOnReadonly.qml b/tests/auto/qml/qqmllanguage/data/deepAliasOnReadonly.qml new file mode 100644 index 00000000000..f5ae62406b4 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/deepAliasOnReadonly.qml @@ -0,0 +1,5 @@ +import QtQml + +DeepAliasOnIC { + readonlyRectX: 55 +} diff --git a/tests/auto/qml/qqmllanguage/data/foreignExtended.qml b/tests/auto/qml/qqmllanguage/data/foreignExtended.qml index 4863e0d567e..b01af6d2296 100644 --- a/tests/auto/qml/qqmllanguage/data/foreignExtended.qml +++ b/tests/auto/qml/qqmllanguage/data/foreignExtended.qml @@ -5,12 +5,17 @@ QtObject { property Foreign foreign: Foreign { objectName: "foreign" } - property Extended extended: Extended {} + property Extended extended: Extended { + objectName: "extended" + property int changeCount: 0 + onExtensionChanged: ++changeCount + } property ForeignExtended foreignExtended: ForeignExtended { objectName: "foreignExtended" } property int extendedBase: extended.base + property int extendedChangeCount: extended.changeCount property int extendedInvokable: extended.invokable() property int extendedSlot: extended.slot() diff --git a/tests/auto/qml/qqmllanguage/data/fuzzed.1.errors.txt b/tests/auto/qml/qqmllanguage/data/fuzzed.1.errors.txt index e399799fe9b..758be7feae4 100644 --- a/tests/auto/qml/qqmllanguage/data/fuzzed.1.errors.txt +++ b/tests/auto/qml/qqmllanguage/data/fuzzed.1.errors.txt @@ -1,2 +1 @@ -2:8:Cannot assign to non-existent property "_G" - +2:11:Non-existent attached object diff --git a/tests/auto/qml/qqmllanguage/data/groupFailure.qml b/tests/auto/qml/qqmllanguage/data/groupFailure.qml new file mode 100644 index 00000000000..e8f8999482b --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/groupFailure.qml @@ -0,0 +1,5 @@ +import QtQml + +GroupFailureOuter { + b.u: null +} diff --git a/tests/auto/qml/qqmllanguage/data/jittedAsCast.qml b/tests/auto/qml/qqmllanguage/data/jittedAsCast.qml new file mode 100644 index 00000000000..e1798a5d352 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/jittedAsCast.qml @@ -0,0 +1,15 @@ +import QtQml + +QtObject { + property QtObject obj: Timer { + interval: 1 + running: true + repeat: true + onTriggered: { + if (++interval === 10) + running = false + } + } + property bool running: (obj as Timer).running + property int interval: (obj as Timer).interval +} diff --git a/tests/auto/qml/qqmllanguage/data/sameNameAliasProperty.qml b/tests/auto/qml/qqmllanguage/data/sameNameAliasProperty.qml new file mode 100644 index 00000000000..288fd618a6a --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/sameNameAliasProperty.qml @@ -0,0 +1,7 @@ +import QtQml 2.15 + +QtObject { + id: root + property int a + property alias a: root.a +} diff --git a/tests/auto/qml/qqmllanguage/data/sameNamePropertyAlias.qml b/tests/auto/qml/qqmllanguage/data/sameNamePropertyAlias.qml new file mode 100644 index 00000000000..bb26ba43965 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/sameNamePropertyAlias.qml @@ -0,0 +1,7 @@ +import QtQml 2.15 + +QtObject { + id: root + property alias a: root.a + property int a +} diff --git a/tests/auto/qml/qqmllanguage/data/signalInlineComponentArg1.qml b/tests/auto/qml/qqmllanguage/data/signalInlineComponentArg1.qml new file mode 100644 index 00000000000..e20710edd9f --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/signalInlineComponentArg1.qml @@ -0,0 +1,30 @@ +import QtQuick + +// this file performs two tests: first, using a signal with a inline component from another file +// and second, calling the signal from another file using an inline component from another file + +Item { + signal canYouFeelIt(arg1:SignalInlineComponentArg.Abc) + + property SignalInlineComponentArg.Abc someAbc: SignalInlineComponentArg.Abc { + success: "Own signal was called with component from another file" + } + + property SignalInlineComponentArg fromAnotherFile: SignalInlineComponentArg {} + + // success of own signal call with parameter from another file + property string successFromOwnSignal: "Signal not called yet" + // makes it easier to test + property string successFromSignalFromFile: fromAnotherFile.success + + Component.onCompleted: { + canYouFeelIt(someAbc); + fromAnotherFile.someAbc.success = "Signal was called from another file" + fromAnotherFile.canYouFeelIt(fromAnotherFile.someAbc) + } + + onCanYouFeelIt: (arg) => { + successFromOwnSignal = arg.success + } +} + diff --git a/tests/auto/qml/qqmllanguage/data/thisInArrow.qml b/tests/auto/qml/qqmllanguage/data/thisInArrow.qml new file mode 100644 index 00000000000..7dd19782e6e --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/thisInArrow.qml @@ -0,0 +1,39 @@ +import QtQml + +QtObject { + id: root + + property int width: 43 + Component.onCompleted: () => { console.log(this.width); } + + property var arrow: () => { return this; } + property var func: function() { return this; } + + property QtObject child: QtObject { + property var aa; + property var ff; + + Component.onCompleted: { + root.arrowResult = root.arrow(); + root.funcResult = root.func(); + + var a = root.arrow; + root.aResult = a(); + var f = root.func; + root.fResult = f(); + + aa = a; + root.aaResult = aa(); + + ff = f; + root.ffResult = ff(); + } + } + + property var arrowResult + property var funcResult + property var aResult + property var fResult + property var aaResult + property var ffResult +} diff --git a/tests/auto/qml/qqmllanguage/data/uncreatableAttached.qml b/tests/auto/qml/qqmllanguage/data/uncreatableAttached.qml new file mode 100644 index 00000000000..4a861ea0752 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/uncreatableAttached.qml @@ -0,0 +1,8 @@ +import QtQml +import ABC + +QtObject { + id: testItem + objectName: "00000000000000000000" + ItemAttached.attachedName: "111111111" +} diff --git a/tests/auto/qml/qqmllanguage/data/variantListConversion.qml b/tests/auto/qml/qqmllanguage/data/variantListConversion.qml new file mode 100644 index 00000000000..19760a64ee3 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/variantListConversion.qml @@ -0,0 +1,8 @@ +import Test +import QtQml + +Foo { + a.a: 12 + b.a: 13 + fooProperty: [a, b, Component] +} diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp index 80ec4900c76..46be3766eca 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.cpp +++ b/tests/auto/qml/qqmllanguage/testtypes.cpp @@ -122,6 +122,11 @@ void registerTypes() qmlRegisterTypesAndRevisions<Extended, Foreign, ForeignExtended>("Test", 1); qmlRegisterTypesAndRevisions<BareSingleton>("Test", 1); qmlRegisterTypesAndRevisions<UncreatableSingleton>("Test", 1); + + qmlRegisterTypesAndRevisions<Large>("Test", 1); + qmlRegisterTypesAndRevisions<Foo>("Test", 1); + + qmlRegisterTypesAndRevisions<Counter>("Test", 1); } QVariant myCustomVariantTypeConverter(const QString &data) @@ -174,7 +179,7 @@ void EnumSupportingCustomParser::verifyBindings(const QQmlRefPointer<QV4::Execut return; } - if (binding->type != QV4::CompiledData::Binding::Type_Script) { + if (binding->type() != QV4::CompiledData::Binding::Type_Script) { error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Expected script that evaluates to enum")); return; } diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 25950acb74f..f06c60f46de 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -1464,13 +1464,23 @@ class ScopedEnumsWithResolvedNameClash class Extension : public QObject { Q_OBJECT - Q_PROPERTY(int extension READ extension CONSTANT) + Q_PROPERTY(int extension READ extension WRITE setExtension NOTIFY extensionChanged FINAL) public: Extension(QObject *parent = nullptr) : QObject(parent) {} - int extension() const { return 42; } + int extension() const { return ext; } + void setExtension(int e) { + if (e != ext) { + ext = e; + emit extensionChanged(); + } + } Q_INVOKABLE int invokable() { return 123; } +Q_SIGNALS: + void extensionChanged(); public slots: int slot() { return 456; } +private: + int ext = 42; }; class Extended : public QObject @@ -1566,6 +1576,33 @@ class ExtendedByNamespace : public QObject int own() const { return 93; } }; +class ExtendedNamespaceByObject : public QObject +{ + Q_OBJECT + QML_ELEMENT + QML_EXTENDED_NAMESPACE(Extension) + + Q_PROPERTY(QString dummy READ dummy CONSTANT) + Q_PROPERTY(int extension READ extension WRITE setExtension NOTIFY extensionChanged) + + int m_ext = 0; + +public: + ExtendedNamespaceByObject(QObject *parent = nullptr) : QObject(parent) {} + QString dummy() const { return QStringLiteral("dummy"); } + int extension() const { return m_ext; } + void setExtension(int e) + { + if (e != m_ext) { + m_ext = e; + Q_EMIT extensionChanged(); + } + } + +Q_SIGNALS: + void extensionChanged(); +}; + class FactorySingleton : public QObject { Q_OBJECT @@ -1725,6 +1762,152 @@ class EnumList : public QObject Q_INVOKABLE QList<EnumList::Enum> list() const { return { Alpha, Beta, Gamma }; } }; +struct Large { + Q_GADGET + QML_VALUE_TYPE(large) + + Q_PROPERTY(uint a MEMBER a) + Q_PROPERTY(uint b MEMBER b) + Q_PROPERTY(uint c MEMBER c) + Q_PROPERTY(uint d MEMBER d) + Q_PROPERTY(uint e MEMBER e) + Q_PROPERTY(uint f MEMBER f) + +public: + quint64 a; + quint64 b; + quint64 c; + quint64 d; + quint64 e; + quint64 f; +}; + +inline bool operator==(const Large &a, const Large &b) +{ + return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d && a.e == b.e && a.f == b.f; +} + +inline bool operator!=(const Large &a, const Large &b) { return !(a == b); } + +class Foo: public QObject { + + Q_OBJECT + Q_PROPERTY(QVariantList fooProperty READ getList WRITE setList) + Q_PROPERTY(Large a MEMBER a BINDABLE aBindable) + Q_PROPERTY(Large b MEMBER b BINDABLE bBindable) + QML_ELEMENT + +public: + QVariantList getList() const { return mFooProperty;} + void setList(QVariantList list) { mFooProperty = list;} + + QBindable<Large> aBindable() { return QBindable<Large>(&a); } + QBindable<Large> bBindable() { return QBindable<Large>(&b); } + +private: + QProperty<Large> a; + QProperty<Large> b; + QVariantList mFooProperty; +}; + +class ItemAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString attachedName READ attachedName WRITE setAttachedName NOTIFY attachedNameChanged) + QML_ELEMENT + QML_ATTACHED(ItemAttached) +public: + ItemAttached(QObject *parent = nullptr) : QObject(parent) {} + + QString attachedName() const { return m_name; } + void setAttachedName(const QString &name) + { + if (name != m_name) { + m_name = name; + emit attachedNameChanged(); + } + } + + static ItemAttached *qmlAttachedProperties(QObject *object) + { + if (object->objectName() != QLatin1String("foo")) { + qWarning("Only foo can have ItemAttached!"); + return nullptr; + } + + return new ItemAttached(object); + } + +signals: + void attachedNameChanged(); + +private: + QString m_name; +}; + +class BindableOnly : public QObject +{ + Q_OBJECT + Q_PROPERTY(QByteArray data READ data WRITE setData BINDABLE dataBindable FINAL) + QML_ELEMENT +public: + BindableOnly(QObject *parent = nullptr) + : QObject(parent) + {} + + QBindable<QByteArray> dataBindable() { return QBindable<QByteArray>(&m_data); } + + QByteArray data() const { return m_data.value(); } + void setData(const QByteArray &newData) { m_data.setValue(newData); } + +private: + QProperty<QByteArray> m_data; +}; + void registerTypes(); +class CounterAttachedBaseType: public QObject +{ + Q_OBJECT + QML_ANONYMOUS + Q_PROPERTY (int value READ value NOTIFY valueChanged) + +public: + CounterAttachedBaseType(QObject *parent = nullptr) : QObject(parent) {} + + int value() { return m_value; } + Q_SIGNAL void valueChanged(); + +protected: + int m_value = 98; +}; + + +class CounterAttachedType: public CounterAttachedBaseType +{ + Q_OBJECT + QML_ANONYMOUS + +public: + CounterAttachedType(QObject *parent = nullptr) : CounterAttachedBaseType(parent) {} + + Q_INVOKABLE void increase() { + ++m_value; + Q_EMIT valueChanged(); + } +}; + +class Counter : public QObject +{ + Q_OBJECT + QML_ATTACHED(CounterAttachedBaseType) + QML_ELEMENT + +public: + static CounterAttachedBaseType *qmlAttachedProperties(QObject *o) + { + return new CounterAttachedType(o); + } +}; + #endif // TESTTYPES_H diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index f95db6136d8..41fb24a76cd 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -50,11 +50,12 @@ #include <private/qqmlvmemetaobject_p.h> #include <private/qqmlcomponent_p.h> #include <private/qqmltype_p_p.h> +#include <private/qqmlcomponentattached_p.h> +#include <private/qv4debugging_p.h> #include "testtypes.h" -#include "testhttpserver.h" - -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/testhttpserver_p.h> #include <deque> @@ -85,6 +86,9 @@ class tst_qqmllanguage : public QQmlDataTest { Q_OBJECT +public: + tst_qqmllanguage(); + private slots: void initTestCase() override; void cleanupTestCase(); @@ -242,6 +246,8 @@ private slots: void deepProperty(); + void groupAssignmentFailure(); + void compositeSingletonProperties(); void compositeSingletonSameEngine(); void compositeSingletonDifferentEngine(); @@ -345,6 +351,7 @@ private slots: void checkURLtoURLObject(); void registerValueTypes(); void extendedNamespace(); + void extendedNamespaceByObject(); void factorySingleton(); void extendedSingleton(); void qtbug_85932(); @@ -363,6 +370,29 @@ private slots: void propertyObserverOnReadonly(); + void propertyAndAliasMustHaveDistinctNames_data(); + void propertyAndAliasMustHaveDistinctNames(); + + void variantListConversion(); + void thisInArrowFunction(); + + void jittedAsCast(); + + void ambiguousContainingType(); + void objectAsBroken(); + void componentMix(); + void uncreatableAttached(); + + void bindableOnly(); + void badGroupedProperty(); + void bindingAliasToComponentUrl(); + void signalInlineComponentArg(); + + void callMethodOfAttachedDerived(); + + void typeAnnotationCycle(); + void deepAliasOnICOrReadonly(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -2139,6 +2169,22 @@ void tst_qqmllanguage::aliasProperties() QCOMPARE(subItem->property("y").toInt(), 1); } + // Nested property bindings on group properties that are actually aliases (QTBUG-94983) + { + QQmlComponent component(&engine, testFileUrl("alias.15a.qml")); + VERIFY_ERRORS(0); + + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + + QPointer<QObject> subItem = qvariant_cast<QObject*>(object->property("symbol")); + QVERIFY(!subItem.isNull()); + + QPointer<QObject> subSubItem = qvariant_cast<QObject*>(subItem->property("layer")); + + QCOMPARE(subSubItem->property("enabled").value<bool>(), true); + } + // Alias to sub-object with binding (QTBUG-57041) { // This is shold *not* crash. @@ -2216,6 +2262,16 @@ void tst_qqmllanguage::aliasProperties() QQmlComponent component(&engine, testFileUrl("alias.18.qml")); VERIFY_ERRORS("alias.18.errors.txt"); } + + // Binding on deep alias + { + QQmlComponent component(&engine, testFileUrl("alias.19.qml")); + VERIFY_ERRORS(0); + + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + QCOMPARE(object->property("height").toInt(), 960); + } } // QTBUG-13374 Test that alias properties and signals can coexist @@ -3420,11 +3476,11 @@ void tst_qqmllanguage::importJs() { DETERMINE_ERRORS(errorFile,expected,actual); - QCOMPARE(expected.size(), actual.size()); + QCOMPARE(actual.size(), expected.size()); for (int i = 0; i < expected.size(); ++i) { const int compareLen = qMin(expected.at(i).length(), actual.at(i).length()); - QCOMPARE(expected.at(i).left(compareLen), actual.at(i).left(compareLen)); + QCOMPARE(actual.at(i).left(compareLen), expected.at(i).left(compareLen)); } } @@ -3728,6 +3784,11 @@ void tst_qqmllanguage::uncreatableTypesAsProperties() QVERIFY(!object.isNull()); } +tst_qqmllanguage::tst_qqmllanguage() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qqmllanguage::initTestCase() { QQmlDataTest::initTestCase(); @@ -4353,6 +4414,17 @@ void tst_qqmllanguage::deepProperty() QCOMPARE(font.family(), QStringLiteral("test")); } +void tst_qqmllanguage::groupAssignmentFailure() +{ + auto ep = std::make_unique<QQmlEngine>(); + QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression(".*Invalid property assignment: url expected - Assigning null to incompatible properties in QML is deprecated. This will become a compile error in future versions of Qt..*")); + QQmlComponent component(ep.get(), testFileUrl("groupFailure.qml")); + QScopedPointer<QObject> o(component.create()); + QVERIFY(!o); + ep.reset(); + // ~QQmlComponent should not crash here +} + // Tests that the implicit import has lowest precedence, in the case where // there are conflicting types and types only found in the local import. // Tests that just check one (or the root) type are in ::importsOrder @@ -5500,9 +5572,20 @@ void tst_qqmllanguage::extendedForeignTypes() QScopedPointer<QObject> o(component.create()); QVERIFY(!o.isNull()); + QObject *extended = o->property("extended").value<QObject *>(); + QVERIFY(extended); + QSignalSpy extensionChangedSpy(extended, SIGNAL(extensionChanged())); + QCOMPARE(o->property("extendedBase").toInt(), 43); QCOMPARE(o->property("extendedExtension").toInt(), 42); QCOMPARE(o->property("foreignExtendedExtension").toInt(), 42); + + QCOMPARE(extensionChangedSpy.count(), 0); + extended->setProperty("extension", 44); + QCOMPARE(extensionChangedSpy.count(), 1); + QCOMPARE(o->property("extendedChangeCount").toInt(), 1); + QCOMPARE(o->property("extendedExtension").toInt(), 44); + QCOMPARE(o->property("foreignObjectName").toString(), QLatin1String("foreign")); QCOMPARE(o->property("foreignExtendedObjectName").toString(), QLatin1String("foreignExtended")); QCOMPARE(o->property("extendedInvokable").toInt(), 123); @@ -6094,6 +6177,22 @@ void tst_qqmllanguage::extendedNamespace() QCOMPARE(obj->property("fromExtension").toInt(), 9); } +void tst_qqmllanguage::extendedNamespaceByObject() +{ + QQmlEngine engine; + QQmlComponent c(&engine); + c.setData("import StaticTest\n" + "import QtQml\n" + "ExtendedNamespaceByObject {\n" + " extension: 10\n" + "}", QUrl()); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> obj(c.create()); + QVERIFY(!obj.isNull()); + + QCOMPARE(obj->property("extension").toInt(), 10); +} + void tst_qqmllanguage::factorySingleton() { QQmlEngine engine; @@ -6292,8 +6391,23 @@ void tst_qqmllanguage::bareInlineComponent() QVERIFY(tab1Found); } +struct DummyDebugger : public QV4::Debugging::Debugger +{ + bool pauseAtNextOpportunity() const final { return false; } + void maybeBreakAtInstruction() final { } + void enteringFunction() final { } + void leavingFunction(const QV4::ReturnedValue &) final { } + void aboutToThrow() final { } +}; + void tst_qqmllanguage::hangOnWarning() { + QQmlEngine engine; + + // A debugger prevents the disk cache. + // If we load the file from disk cache we don't parse it and we don't see the warning. + engine.handle()->setDebugger(new DummyDebugger); + QTest::ignoreMessage(QtWarningMsg, qPrintable(QStringLiteral("%1:3 : Ignored annotation") .arg(testFileUrl("hangOnWarning.qml").toString()))); @@ -6353,6 +6467,273 @@ void tst_qqmllanguage::propertyObserverOnReadonly() QCOMPARE(o->property("height").toDouble(), 54.2); } +void tst_qqmllanguage::propertyAndAliasMustHaveDistinctNames_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::addColumn<QString>("error"); + + QTest::addRow("sameNamePropertyAlias") << "sameNamePropertyAlias.qml" << "Property duplicates alias name"; + QTest::addRow("sameNameAliasProperty") << "sameNameAliasProperty.qml" << "Alias has same name as existing property"; +} + +void tst_qqmllanguage::propertyAndAliasMustHaveDistinctNames() +{ + QFETCH(QString, fileName); + QFETCH(QString, error); + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl(fileName)); + QVERIFY(!c.isReady()); + auto actualError = c.errorString(); + QVERIFY2(actualError.contains(error), qPrintable(actualError)); +} + +void tst_qqmllanguage::variantListConversion() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("variantListConversion.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + + Foo *foo = qobject_cast<Foo *>(o.data()); + QVERIFY(foo); + const QVariantList list = foo->getList(); + QCOMPARE(list.length(), 3); + const Large l0 = qvariant_cast<Large>(list.at(0)); + QCOMPARE(l0.a, 12ull); + const Large l1 = qvariant_cast<Large>(list.at(1)); + QCOMPARE(l1.a, 13ull); + const QObject *attached = qvariant_cast<QObject *>(list.at(2)); + QVERIFY(attached); + QCOMPARE(attached->metaObject(), &QQmlComponentAttached::staticMetaObject); +} + +void tst_qqmllanguage::thisInArrowFunction() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("thisInArrow.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + + QTest::ignoreMessage(QtDebugMsg, "43"); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + + QCOMPARE(qvariant_cast<QObject *>(o->property("arrowResult")), o.data()); + QCOMPARE(qvariant_cast<QObject *>(o->property("funcResult")), o.data()); + QCOMPARE(qvariant_cast<QObject *>(o->property("aResult")), o.data()); + QCOMPARE(qvariant_cast<QObject *>(o->property("aaResult")), o.data()); + + QCOMPARE(qvariant_cast<QObject *>(o->property("fResult")), nullptr); + QCOMPARE(o->property("fResult").metaType(), QMetaType::fromType<QJSValue>()); + QVERIFY(qvariant_cast<QJSValue>(o->property("fResult")).isObject()); + + QObject *child = qvariant_cast<QObject *>(o->property("child")); + QVERIFY(child != nullptr); + QCOMPARE(qvariant_cast<QObject *>(o->property("ffResult")), child); +} + +void tst_qqmllanguage::jittedAsCast() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("jittedAsCast.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QCOMPARE(o->property("running").toBool(), true); + QTRY_COMPARE(o->property("running").toBool(), false); + QCOMPARE(o->property("interval").toInt(), 10); +} + +void tst_qqmllanguage::ambiguousContainingType() +{ + // Need to do it twice, so that we load from disk cache the second time. + for (int i = 0; i < 2; ++i) { + QQmlEngine engine; + + // Should not crash when loading the type + QQmlComponent c(&engine, testFileUrl("ambiguousBinding/ambiguousContainingType.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + } +} + +void tst_qqmllanguage::objectAsBroken() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("asBroken.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + QVariant selfAsBroken = o->property("selfAsBroken"); + QVERIFY(selfAsBroken.isValid()); + QCOMPARE(selfAsBroken.metaType(), QMetaType::fromType<std::nullptr_t>()); + + QQmlComponent b(&engine, testFileUrl("Broken.qml")); + QVERIFY(b.isError()); +} + +void tst_qqmllanguage::componentMix() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("componentMix.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + QObject *things = qvariant_cast<QObject *>(o->property("things")); + QVERIFY(things); + QObject *delegated = qvariant_cast<QObject *>(o->property("delegated")); + QVERIFY(delegated); + QObject *view = qvariant_cast<QObject *>(things->property("view")); + QVERIFY(view); + QObject *delegate = qvariant_cast<QObject *>(view->property("delegate")); + QVERIFY(delegate); + QCOMPARE(delegate->metaObject(), &QQmlComponent::staticMetaObject); + QObject *delegate2 = qvariant_cast<QObject *>(delegated->property("delegate")); + QVERIFY(delegate2); + QCOMPARE(delegate2->metaObject(), &QQmlComponent::staticMetaObject); +} + +void tst_qqmllanguage::uncreatableAttached() +{ + qmlRegisterTypesAndRevisions<ItemAttached>("ABC", 1); + QQmlEngine engine; + const QUrl url = testFileUrl("uncreatableAttached.qml"); + QQmlComponent c(&engine, url); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QTest::ignoreMessage(QtWarningMsg, "Only foo can have ItemAttached!"); + QScopedPointer o(c.create()); + QVERIFY(o.isNull()); + QVERIFY(c.errorString().contains( + QLatin1String("Could not create attached properties object 'ItemAttached'"))); +} + +void tst_qqmllanguage::bindableOnly() +{ + qmlRegisterTypesAndRevisions<BindableOnly>("ABC", 1); + QQmlEngine engine; + + QQmlComponent c(&engine); + c.setData("import ABC\nBindableOnly {\n" + " data: \"sc\" + \"ore\"\n" + " objectName: data\n" + "}", QUrl(u"bindableOnly.qml"_qs)); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + QCOMPARE(o->property("data").value<QByteArray>(), QByteArray("score")); + QCOMPARE(o->objectName(), QStringLiteral("score")); +} + +void tst_qqmllanguage::badGroupedProperty() +{ + QQmlEngine engine; + const QUrl url = testFileUrl("badGroupedProperty.qml"); + QQmlComponent c(&engine, url); + QVERIFY(c.isError()); + QCOMPARE(c.errorString(), + QStringLiteral("%1:6 Cannot assign to non-existent property \"onComplete\"\n") + .arg(url.toString())); +} + +void tst_qqmllanguage::bindingAliasToComponentUrl() +{ + QQmlEngine engine; + { + QQmlComponent component(&engine, testFileUrl("bindingAliasToComponentUrl.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> object(component.create()); + QVERIFY(object); + QCOMPARE(object->property("accessibleNormalUrl"), object->property("urlClone")); + } + { + QQmlComponent component(&engine, testFileUrl("bindingAliasToComponentUrl2.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> object(component.create()); + QVERIFY(object); + QCOMPARE(object->property("accessibleNormalProgress"), QVariant(1.0)); + } +} + +void tst_qqmllanguage::signalInlineComponentArg() +{ + QQmlEngine engine; + { + QQmlComponent component(&engine, testFileUrl("SignalInlineComponentArg.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> object(component.create()); + + QCOMPARE(object->property("success"), QStringLiteral("Signal was called")); + } + { + QQmlComponent component(&engine, testFileUrl("signalInlineComponentArg1.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> object(component.create()); + + QCOMPARE(object->property("successFromOwnSignal"), + QStringLiteral("Own signal was called with component from another file")); + QCOMPARE(object->property("successFromSignalFromFile"), + QStringLiteral("Signal was called from another file")); + } +} + +void tst_qqmllanguage::callMethodOfAttachedDerived() +{ + QQmlEngine engine; + QQmlComponent c(&engine); + c.setData(R"( + import QtQml + import Test + + QtObject { + Component.onCompleted: Counter.increase() + property int v: Counter.value + } + )", QUrl()); + + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + + QCOMPARE(o->property("v").toInt(), 99); +} + +void tst_qqmllanguage::typeAnnotationCycle() +{ + QQmlEngine engine; + + const QUrl url = testFileUrl("TypeAnnotationCycle1.qml"); + const QUrl url2 = testFileUrl("TypeAnnotationCycle2.qml"); + + QTest::ignoreMessage( + QtWarningMsg, + qPrintable( + QLatin1String("Cyclic dependency detected between \"%1\" and \"%2\"") + .arg(url.toString(), url2.toString()))); + + QQmlComponent c(&engine, url); + QVERIFY(!c.isReady()); +} + +void tst_qqmllanguage::deepAliasOnICOrReadonly() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("deepAliasOnICUser.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + + QCOMPARE(o->property("borderColor").toString(), QLatin1String("black")); + QCOMPARE(o->property("borderObjectName").toString(), QLatin1String("theLeaf")); + + const QVariant var = o->property("borderVarvar"); + QCOMPARE(var.metaType(), QMetaType::fromType<QString>()); + QCOMPARE(var.toString(), QLatin1String("mauve")); + + QQmlComponent c2(&engine, testFileUrl("deepAliasOnReadonly.qml")); + QVERIFY(c2.isError()); + QVERIFY(c2.errorString().contains( + QLatin1String( + "Invalid property assignment: \"readonlyRectX\" is a read-only property"))); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" diff --git a/tests/auto/qml/qqmllistcompositor/tst_qqmllistcompositor.cpp b/tests/auto/qml/qqmllistcompositor/tst_qqmllistcompositor.cpp index b49832499eb..9315b2d24db 100644 --- a/tests/auto/qml/qqmllistcompositor/tst_qqmllistcompositor.cpp +++ b/tests/auto/qml/qqmllistcompositor/tst_qqmllistcompositor.cpp @@ -89,15 +89,13 @@ QT_END_NAMESPACE static const C::Group Visible = C::Group(2); static const C::Group Selection = C::Group(3); +constexpr auto VisibleFlag = C::Flag(0x04); +constexpr auto SelectionFlag = C::Flag(0x08); + class tst_qqmllistcompositor : public QObject { Q_OBJECT - enum { - VisibleFlag = 0x04, - SelectionFlag = 0x08 - }; - void populateChange( C::Change &change, int sIndex, int vIndex, int dIndex, int cIndex, int count, int flags, int moveId) { diff --git a/tests/auto/qml/qqmllistmodel/CMakeLists.txt b/tests/auto/qml/qqmllistmodel/CMakeLists.txt index d583dc3b0ee..18c247f5b9f 100644 --- a/tests/auto/qml/qqmllistmodel/CMakeLists.txt +++ b/tests/auto/qml/qqmllistmodel/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmllistmodel SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmllistmodel.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qqmllistmodel Qt::QmlModelsPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmllistmodel/data/destroyObject.qml b/tests/auto/qml/qqmllistmodel/data/destroyObject.qml new file mode 100644 index 00000000000..e6b3f33bb9a --- /dev/null +++ b/tests/auto/qml/qqmllistmodel/data/destroyObject.qml @@ -0,0 +1,23 @@ +import QtQml + +QtObject { + id: root + property ListModel projects: ListModel {} + property var object + + Component.onCompleted: { + var comp= Qt.createComponent("dummyItem.qml"); + object = comp.createObject(root, {}); + projects.append({"obj": object}); + } + + function destroy() { + try { + object.destroy(); + } catch(e) { + console.warn(e); + return false; + } + return true; + } +} diff --git a/tests/auto/qml/qqmllistmodel/data/dummyItem.qml b/tests/auto/qml/qqmllistmodel/data/dummyItem.qml new file mode 100644 index 00000000000..c9939efcdfd --- /dev/null +++ b/tests/auto/qml/qqmllistmodel/data/dummyItem.qml @@ -0,0 +1,5 @@ +import QtQml + +QtObject { + property var random: null +} diff --git a/tests/auto/qml/qqmllistmodel/data/objectOwnership.qml b/tests/auto/qml/qqmllistmodel/data/objectOwnership.qml new file mode 100644 index 00000000000..0ebb29d75b8 --- /dev/null +++ b/tests/auto/qml/qqmllistmodel/data/objectOwnership.qml @@ -0,0 +1,27 @@ +import QtQuick + +ListView { + id: root + width: 100 + height: 100 + + delegate: Component { + Item { + property Item myItem: refItem + } + } + + model: ListModel { + id: listModel + objectName: "listModel" + + function addItem() { + append({"refItem": cppOwnedItem}); + } + } + + function checkItem() { + root.currentIndex = 0; + currentItem.myItem.dummy(); + } +} diff --git a/tests/auto/qml/qqmllistmodel/data/protectQObjectFromGC.qml b/tests/auto/qml/qqmllistmodel/data/protectQObjectFromGC.qml new file mode 100644 index 00000000000..43b375b6814 --- /dev/null +++ b/tests/auto/qml/qqmllistmodel/data/protectQObjectFromGC.qml @@ -0,0 +1,21 @@ +import QtQml +import QtQml.Models + +ListModel { + id: filesModel + property Component testComponent: Component { + id: testComponent + QtObject { + required property string name + } + } + Component.onCompleted: { + filesModel.clear() + for(let i = 0; i < 10; i++) { + filesModel.append({ + path: testComponent.createObject(null, { name: "" + i }) + }) + } + gc() + } +} diff --git a/tests/auto/qml/qqmllistmodel/data/urls.qml b/tests/auto/qml/qqmllistmodel/data/urls.qml index b7fe57402eb..9e59a70cb64 100644 --- a/tests/auto/qml/qqmllistmodel/data/urls.qml +++ b/tests/auto/qml/qqmllistmodel/data/urls.qml @@ -4,16 +4,23 @@ import QtQml.Models 2 Item { id: root readonly property url url1: "http://qt-project.org" + property var result1 property var result2 + + property var alive1 + property var alive2 + ListModel {id: myModel} Component.onCompleted: { - myModel.append({"url": new URL("http://qt.io")}) - myModel.append({"url": url1}) + myModel.append({"url": new URL("http://qt.io"), "alive": "indeed"}) + myModel.append({"url": url1, "alive": "and kicking"}) const entry1 = myModel.get(0) root.result1 = entry1.url; + root.alive1 = entry1.alive; const entry2 = myModel.get(1) root.result2 = entry2.url; + root.alive2 = entry2.alive; } } diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp index bdefc857701..fbdf6d90f3d 100644 --- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp +++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp @@ -39,7 +39,7 @@ #include <QtCore/qtranslator.h> #include <QSignalSpy> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> Q_DECLARE_METATYPE(QList<int>) Q_DECLARE_METATYPE(QList<QVariantHash>) @@ -74,6 +74,7 @@ class tst_qqmllistmodel : public QQmlDataTest Q_OBJECT public: tst_qqmllistmodel() + : QQmlDataTest(QT_QMLTEST_DATADIR) { qRegisterMetaType<QVector<int> >(); } @@ -132,6 +133,13 @@ private slots: void nestedListModelIteration(); void undefinedAppendShouldCauseError(); void nullPropertyCrash(); + void objectDestroyed(); + void destroyObject(); + void emptyStringNotUndefined(); + void listElementWithTemplateString(); + void destroyComponentObject(); + void objectOwnershipFlip(); + void protectQObjectFromGC(); }; bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object) @@ -1402,6 +1410,8 @@ void tst_qqmllistmodel::url() QVERIFY(o); QCOMPARE(o->property("result1").toUrl(), QUrl("http://qt.io")); QCOMPARE(o->property("result2").toUrl(), QUrl("http://qt-project.org")); + QCOMPARE(o->property("alive1").toString(), QStringLiteral("indeed")); + QCOMPARE(o->property("alive2").toString(), QStringLiteral("and kicking")); } void tst_qqmllistmodel::datetime() @@ -1757,6 +1767,179 @@ void tst_qqmllistmodel::nullPropertyCrash() QScopedPointer<QObject>(component.create()); } +// QTBUG-91390 +void tst_qqmllistmodel::objectDestroyed() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData( + R"(import QtQuick + ListModel { + id: model + Component.onCompleted: { model.append({"a": contextObject}); } + })", + QUrl()); + + QObject *obj = new QObject; + bool destroyed = false; + connect(obj, &QObject::destroyed, [&]() { destroyed = true; }); + + engine.rootContext()->setContextProperty(u"contextObject"_qs, obj); + engine.setObjectOwnership(obj, QJSEngine::JavaScriptOwnership); + + QScopedPointer<QObject>(component.create()); + QVERIFY(!destroyed); + engine.collectGarbage(); + QTest::qSleep(250); + QVERIFY(!destroyed); + engine.evaluate(u"model.clear();"_qs); + engine.collectGarbage(); + QTRY_VERIFY(destroyed); +} + +void tst_qqmllistmodel::destroyObject() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData( + R"(import QtQuick + ListModel { + id: model + Component.onCompleted: { model.append({"a": contextObject}); } + })", + QUrl()); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> element(new QObject); + engine.rootContext()->setContextProperty(u"contextObject"_qs, element.data()); + + QScopedPointer<QObject> o(component.create()); + QVERIFY(!o.isNull()); + + QQmlListModel *model = qobject_cast<QQmlListModel *>(o.data()); + QVERIFY(model); + QCOMPARE(model->count(), 1); + QCOMPARE(model->get(0).property("a").toQObject(), element.data()); + element.reset(); + QCOMPARE(model->get(0).property("a").toQObject(), nullptr); +} + +void tst_qqmllistmodel::emptyStringNotUndefined() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData( + R"(import QtQuick + ListModel { + id: model + Component.onCompleted: { model.append({"a": ""}); } + })", + QUrl()); + QScopedPointer<QObject> root(component.create()); + QVERIFY(root); + auto lm = qobject_cast<QQmlListModel *>(root.get()); + QVERIFY(lm); + QJSValue val = lm->get(0); + QVERIFY(val.hasProperty("a")); + val = val.property("a"); + QVERIFY(!val.isUndefined()); + QVERIFY(val.isString()); + QCOMPARE(val.toString(), QString()); +} + +void tst_qqmllistmodel::listElementWithTemplateString() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(R"( + import QtQuick + ListModel { + ListElement { + prop: `test` + } + })", QUrl()); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> root(component.create()); + QVERIFY(!root.isNull()); +} + +//QTBUG-95895 +void tst_qqmllistmodel::destroyComponentObject() +{ + QQmlEngine eng; + QQmlComponent component(&eng, testFileUrl("destroyObject.qml")); + QVERIFY(!component.isError()); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + QQmlListModel *list = qvariant_cast<QQmlListModel *>(obj->property("projects")); + QVERIFY(list != nullptr); + QCOMPARE(list->count(), 1); + QPointer<QObject> created(qvariant_cast<QObject *>(obj->property("object"))); + QVERIFY(!created.isNull()); + QCOMPARE(list->get(0).property("obj").toQObject(), created.data()); + QVariant retVal; + QMetaObject::invokeMethod(obj.data(), + "destroy", + Qt::DirectConnection, + Q_RETURN_ARG(QVariant, retVal)); + QVERIFY(retVal.toBool()); + QTRY_VERIFY(created.isNull()); + QTRY_VERIFY(list->get(0).property("obj").isNull()); + QCOMPARE(list->count(), 1); +} + +// Used for objectOwnershipFlip +class TestItem : public QQuickItem +{ + Q_OBJECT +public: + // To trigger QQmlData::setImplicitDestructible through QV4::CallArgument::toValue + Q_INVOKABLE TestItem* dummy() { return this; } +}; + +void tst_qqmllistmodel::objectOwnershipFlip() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("objectOwnership.qml")); + QVERIFY(!component.isError()); + QScopedPointer<QObject> root(component.create()); + QVERIFY(!root.isNull()); + QQmlListModel *model = root->findChild<QQmlListModel*>("listModel"); + QVERIFY(model != nullptr); + + QScopedPointer<TestItem> item(new TestItem()); + item->setObjectName("cppOwnedItem"); + QJSEngine::setObjectOwnership(item.data(), QJSEngine::CppOwnership); + QCOMPARE(QJSEngine::objectOwnership(item.data()), QJSEngine::CppOwnership); + + engine.rootContext()->setContextProperty("cppOwnedItem", item.data()); + + QMetaObject::invokeMethod(model, "addItem"); + QCOMPARE(model->count(), 1); + + QMetaObject::invokeMethod(root.data(), "checkItem"); + + QCOMPARE(QJSEngine::objectOwnership(item.data()), QJSEngine::CppOwnership); +} + +void tst_qqmllistmodel::protectQObjectFromGC() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("protectQObjectFromGC.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> root(component.create()); + QVERIFY(!root.isNull()); + + QQmlListModel *listModel = qobject_cast<QQmlListModel *>(root.data()); + QVERIFY(listModel); + QCOMPARE(listModel->count(), 10); + + for (int i = 0; i < 10; ++i) { + QObject *element = qjsvalue_cast<QObject *>(listModel->get(i).property("path")); + QVERIFY(element); + QCOMPARE(element->property("name").toString(), QString::number(i)); + } +} + QTEST_MAIN(tst_qqmllistmodel) #include "tst_qqmllistmodel.moc" diff --git a/tests/auto/qml/qqmllistmodelworkerscript/CMakeLists.txt b/tests/auto/qml/qqmllistmodelworkerscript/CMakeLists.txt index 66c7c3a5573..577ba74f9ae 100644 --- a/tests/auto/qml/qqmllistmodelworkerscript/CMakeLists.txt +++ b/tests/auto/qml/qqmllistmodelworkerscript/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmllistmodelworkerscript SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmllistmodelworkerscript.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qqmllistmodelworkerscript Qt::QmlModelsPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp b/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp index 262ac25d6a5..93378ff6477 100644 --- a/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp +++ b/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp @@ -38,7 +38,7 @@ #include <QtCore/qtranslator.h> #include <QSignalSpy> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> Q_DECLARE_METATYPE(QList<int>) Q_DECLARE_METATYPE(QList<QVariantHash>) @@ -73,6 +73,7 @@ class tst_qqmllistmodelworkerscript : public QQmlDataTest Q_OBJECT public: tst_qqmllistmodelworkerscript() + : QQmlDataTest(QT_QMLTEST_DATADIR) { qRegisterMetaType<QVector<int> >(); } diff --git a/tests/auto/qml/qqmllistreference/CMakeLists.txt b/tests/auto/qml/qqmllistreference/CMakeLists.txt index 15fa87b0b7a..9d4b3cac7a4 100644 --- a/tests/auto/qml/qqmllistreference/CMakeLists.txt +++ b/tests/auto/qml/qqmllistreference/CMakeLists.txt @@ -12,19 +12,21 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmllistreference SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmllistreference.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmllistreference) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp b/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp index 61565162e59..23b3847bc13 100644 --- a/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp +++ b/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp @@ -37,13 +37,13 @@ #include <QtQml/qqmlproperty.h> #include <QDebug> #include <private/qquickstate_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmllistreference : public QQmlDataTest { Q_OBJECT public: - tst_qqmllistreference() {} + tst_qqmllistreference() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private: void modeData(); diff --git a/tests/auto/qml/qqmllocale/CMakeLists.txt b/tests/auto/qml/qqmllocale/CMakeLists.txt index 4022cb8cc45..ca7f464c379 100644 --- a/tests/auto/qml/qqmllocale/CMakeLists.txt +++ b/tests/auto/qml/qqmllocale/CMakeLists.txt @@ -12,14 +12,12 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmllocale SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmllocale.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::GuiPrivate Qt::Qml + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmllocale/data/functions.qml b/tests/auto/qml/qqmllocale/data/functions.qml index 9fee78a8362..42e26a508cb 100644 --- a/tests/auto/qml/qqmllocale/data/functions.qml +++ b/tests/auto/qml/qqmllocale/data/functions.qml @@ -3,9 +3,6 @@ import QtQuick QtObject { property var locale: Qt.locale() - // TODO: Workaround for not being able to use "Locale" in QQmlExpression (QTBUG-91747). - property var localeType: Locale - function setLocale(l) { locale = Qt.locale(l) } diff --git a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp index 3c9b1f1314d..564c66c7239 100644 --- a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp +++ b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp @@ -37,7 +37,7 @@ #include <QtCore/qscopedpointer.h> #include <QtCore/qtimezone.h> #include <qcolor.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <time.h> @@ -45,7 +45,7 @@ class tst_qqmllocale : public QQmlDataTest { Q_OBJECT public: - tst_qqmllocale() { } + tst_qqmllocale() : QQmlDataTest(QT_QMLTEST_DATADIR) { } private slots: void defaultLocale(); @@ -659,15 +659,15 @@ void tst_qqmllocale::addFormattedDataSizeDataForLocale(const QString &localeStr) expectedResult = locale.formattedDataSize(1000000, 3); QTest::newRow(qPrintable(makeTag())) << localeStr << functionCallScript << expectedResult << expectedErrorMessage; - functionCallScript = QLatin1String("locale.formattedDataSize(1000000, 3, localeType.DataSizeIecFormat)"); + functionCallScript = QLatin1String("locale.formattedDataSize(1000000, 3, Locale.DataSizeIecFormat)"); expectedResult = locale.formattedDataSize(1000000, 3, QLocale::DataSizeIecFormat); QTest::newRow(qPrintable(makeTag())) << localeStr << functionCallScript << expectedResult << expectedErrorMessage; - functionCallScript = QLatin1String("locale.formattedDataSize(1000000, 3, localeType.DataSizeTraditionalFormat)"); + functionCallScript = QLatin1String("locale.formattedDataSize(1000000, 3, Locale.DataSizeTraditionalFormat)"); expectedResult = locale.formattedDataSize(1000000, 3, QLocale::DataSizeTraditionalFormat); QTest::newRow(qPrintable(makeTag())) << localeStr << functionCallScript << expectedResult << expectedErrorMessage; - functionCallScript = QLatin1String("locale.formattedDataSize(1000000, 3, localeType.DataSizeSIFormat)"); + functionCallScript = QLatin1String("locale.formattedDataSize(1000000, 3, Locale.DataSizeSIFormat)"); expectedResult = locale.formattedDataSize(1000000, 3, QLocale::DataSizeSIFormat); QTest::newRow(qPrintable(makeTag())) << localeStr << functionCallScript << expectedResult << expectedErrorMessage; } @@ -691,7 +691,7 @@ void tst_qqmllocale::formattedDataSize_data() QString errorMessage = ".*Locale: formattedDataSize\\(\\): Expected 1-3 arguments, but received 0"; QTest::newRow("too few args") << "en_AU" << functionCallScript << QString() << errorMessage; - functionCallScript = "locale.formattedDataSize(10, 1, localeType.DataSizeIecFormat, \"foo\")"; + functionCallScript = "locale.formattedDataSize(10, 1, Locale.DataSizeIecFormat, \"foo\")"; errorMessage = ".*Locale: formattedDataSize\\(\\): Expected 1-3 arguments, but received 4"; QTest::newRow("too many args") << "en_AU" << functionCallScript << QString() << errorMessage; @@ -723,7 +723,9 @@ void tst_qqmllocale::formattedDataSize() QVERIFY(QMetaObject::invokeMethod(object.data(), "setLocale", Qt::DirectConnection, Q_ARG(QVariant, QVariant(localeStr)))); - QQmlExpression qmlExpression(engine.rootContext(), object.data(), functionCallScript); + // Make sure that we use the object's context rather than the root context, + // so that e.g. enums from the Locale type are available (QTBUG-91747). + QQmlExpression qmlExpression(qmlContext(object.data()), object.data(), functionCallScript); const QVariant evaluationResult = qmlExpression.evaluate(); if (expectedErrorMessagePattern.isEmpty()) { QVERIFY2(!qmlExpression.hasError(), qPrintable(qmlExpression.error().toString())); @@ -1437,7 +1439,7 @@ void tst_qqmllocale::timeZoneUpdated() obj.reset(c.create()); QVERIFY(obj); -#if !defined(Q_OS_LINUX) || defined(Q_OS_ANDROID) +#if (!defined(Q_OS_LINUX) && !defined(Q_OS_QNX)) || defined(Q_OS_ANDROID) QEXPECT_FAIL("", "Date.timeZoneUpdated() only works on non-Android Linux with QT_CONFIG(timezone).", Continue); @@ -1449,7 +1451,7 @@ void tst_qqmllocale::timeZoneUpdated() QMetaObject::invokeMethod(obj.data(), "check"); -#if !defined(Q_OS_LINUX) || defined(Q_OS_ANDROID) +#if (!defined(Q_OS_LINUX) && !defined(Q_OS_QNX)) || defined(Q_OS_ANDROID) QEXPECT_FAIL("", "Date.timeZoneUpdated() only works on non-Android Linux with QT_CONFIG(timezone).", Continue); diff --git a/tests/auto/qml/qqmlmetaobject/CMakeLists.txt b/tests/auto/qml/qqmlmetaobject/CMakeLists.txt index c7ec398a5db..93edb035278 100644 --- a/tests/auto/qml/qqmlmetaobject/CMakeLists.txt +++ b/tests/auto/qml/qqmlmetaobject/CMakeLists.txt @@ -12,17 +12,19 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlmetaobject SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlmetaobject.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::GuiPrivate Qt::Qml + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmlmetaobject) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp b/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp index af285fb58b8..81c6b0d2a15 100644 --- a/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp +++ b/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp @@ -29,7 +29,7 @@ #include <QtTest/QtTest> #include <QtQml/qqmlcomponent.h> #include <QtQml/qqmlengine.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> Q_DECLARE_METATYPE(QMetaMethod::MethodType) @@ -42,6 +42,10 @@ QML_DECLARE_TYPE(MyQmlObject) class tst_QQmlMetaObject : public QQmlDataTest { Q_OBJECT + +public: + tst_QQmlMetaObject(); + private slots: void initTestCase() override; @@ -54,6 +58,11 @@ private slots: MyQmlObject myQmlObject; }; +tst_QQmlMetaObject::tst_QQmlMetaObject() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QQmlMetaObject::initTestCase() { QQmlDataTest::initTestCase(); diff --git a/tests/auto/qml/qqmlmetatype/CMakeLists.txt b/tests/auto/qml/qqmlmetatype/CMakeLists.txt index 55eebaa651c..74146bb49ba 100644 --- a/tests/auto/qml/qqmlmetatype/CMakeLists.txt +++ b/tests/auto/qml/qqmlmetatype/CMakeLists.txt @@ -12,15 +12,13 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlmetatype SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlmetatype.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -48,6 +46,9 @@ qt_internal_add_resource(tst_qqmlmetatype "qmake_qmldirresource" ${qmake_qmldirresource_resource_files} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmlmetatype) +endif() ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index 4d2e8c2b5dd..f7268557274 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -37,13 +37,13 @@ #include <private/qqmlpropertyvalueinterceptor_p.h> #include <private/qqmlengine_p.h> #include <private/qqmlanybinding_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlmetatype : public QQmlDataTest { Q_OBJECT public: - tst_qqmlmetatype() {} + tst_qqmlmetatype() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; @@ -72,6 +72,8 @@ private slots: void enumsInRecursiveImport_data(); void enumsInRecursiveImport(); + + void clearPropertyCaches(); }; class TestType : public QObject @@ -734,6 +736,24 @@ void tst_qqmlmetatype::enumsInRecursiveImport() QTRY_COMPARE(obj->property("color").toString(), QString("green")); } +void tst_qqmlmetatype::clearPropertyCaches() +{ + qmlClearTypeRegistrations(); + qmlRegisterType<TestType>("ClearPropertyCaches", 1, 0, "A"); + + QQmlRefPointer<QQmlPropertyCache> oldCache( + QQmlMetaType::propertyCache(&TestType::staticMetaObject)); + QVERIFY(oldCache); + + qmlClearTypeRegistrations(); + qmlRegisterType<TestType>("ClearPropertyCaches", 1, 0, "B"); + QQmlRefPointer<QQmlPropertyCache> newCache( + QQmlMetaType::propertyCache(&TestType::staticMetaObject)); + QVERIFY(newCache); + + QVERIFY(oldCache.data() != newCache.data()); +} + QTEST_MAIN(tst_qqmlmetatype) #include "tst_qqmlmetatype.moc" diff --git a/tests/auto/qml/qqmlmoduleplugin/CMakeLists.txt b/tests/auto/qml/qqmlmoduleplugin/CMakeLists.txt index 58a52919ead..43b4c032df4 100644 --- a/tests/auto/qml/qqmlmoduleplugin/CMakeLists.txt +++ b/tests/auto/qml/qqmlmoduleplugin/CMakeLists.txt @@ -20,17 +20,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlmoduleplugin SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h tst_qqmlmoduleplugin.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::GuiPrivate Qt::Network Qt::QmlPrivate Qt::QuickShapesPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -56,6 +53,18 @@ qt_internal_add_resource(tst_qqmlmoduleplugin "qmake_staticPlugin" ${qmake_staticPlugin_resource_files} ) +set_source_files_properties("imports/ModuleFromQrc/badqmldir" + PROPERTIES QT_RESOURCE_ALIAS "imports/ModuleFromQrc/qmldir" +) + +qt_internal_add_resource(tst_qqmlmoduleplugin "moduleFromQrc" + PREFIX + "/foo/" + FILES + "imports/ModuleFromQrc/badqmldir" + "imports/ModuleFromQrc/Foo.qml" +) + #### Keys ignored in scope 2:.:.:tst_qqmlmoduleplugin.pro:<TRUE>: # CONFIG = "testcase" "-app_bundle" diff --git a/tests/auto/qml/qqmlmoduleplugin/imports/ModuleFromQrc/Foo.qml b/tests/auto/qml/qqmlmoduleplugin/imports/ModuleFromQrc/Foo.qml new file mode 100644 index 00000000000..54531c4bdc0 --- /dev/null +++ b/tests/auto/qml/qqmlmoduleplugin/imports/ModuleFromQrc/Foo.qml @@ -0,0 +1,2 @@ +import QtQml +QtObject {} diff --git a/tests/auto/qml/qqmlmoduleplugin/imports/ModuleFromQrc/badqmldir b/tests/auto/qml/qqmlmoduleplugin/imports/ModuleFromQrc/badqmldir new file mode 100644 index 00000000000..90b20ece962 --- /dev/null +++ b/tests/auto/qml/qqmlmoduleplugin/imports/ModuleFromQrc/badqmldir @@ -0,0 +1,3 @@ +module ModuleFromQrc +plugin badbad +Foo 1.0 Foo.qml diff --git a/tests/auto/qml/qqmlmoduleplugin/imports/ModuleFromQrc/qmldir b/tests/auto/qml/qqmlmoduleplugin/imports/ModuleFromQrc/qmldir new file mode 100644 index 00000000000..56587be6850 --- /dev/null +++ b/tests/auto/qml/qqmlmoduleplugin/imports/ModuleFromQrc/qmldir @@ -0,0 +1,2 @@ +module ModuleFromQrc +Foo 1.0 Foo.qml diff --git a/tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp index 4b58348962d..8321e02d792 100644 --- a/tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp +++ b/tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp @@ -47,9 +47,9 @@ class MyPlugin : public QQmlExtensionPlugin void registerTypes(const char *uri) override { - // The module is protected. The plugin can still be loaded, but it cannot register - // any types. + // Because the module is protected, this plugin should never be loaded Q_UNUSED(uri); + Q_UNREACHABLE(); } }; diff --git a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp index ea5b44f1b64..dba70ac9799 100644 --- a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp +++ b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp @@ -46,8 +46,8 @@ #include <unistd.h> #endif -#include "../../shared/testhttpserver.h" -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/testhttpserver_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> // Note: this test does not use module identifier directives in the qmldir files, because // it would result in repeated attempts to insert types into the same namespace. @@ -58,6 +58,7 @@ class tst_qqmlmoduleplugin : public QQmlDataTest { Q_OBJECT public: + tst_qqmlmoduleplugin(); private slots: void initTestCase() override; @@ -86,6 +87,7 @@ private slots: void parallelPluginImport(); void multiSingleton(); void optionalPlugin(); + void moduleFromQrc(); private: QString m_importsDirectory; @@ -174,6 +176,11 @@ void registerStaticPlugin(const char *uri) qRegisterStaticPluginFunction(plugin); }; +tst_qqmlmoduleplugin::tst_qqmlmoduleplugin() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qqmlmoduleplugin::initTestCase() { QQmlDataTest::initTestCase(); @@ -222,7 +229,7 @@ void tst_qqmlmoduleplugin::initTestCase() } \ file.close(); \ } else { \ - QCOMPARE(expected, actual); \ + QCOMPARE(actual, expected); \ } \ } @@ -829,6 +836,16 @@ void tst_qqmlmoduleplugin::optionalPlugin() QVERIFY(!object10.isNull()); } +void tst_qqmlmoduleplugin::moduleFromQrc() +{ + QQmlEngine engine; + engine.setImportPathList({ QStringLiteral(":/foo/imports/"), m_dataImportsDirectory }); + QQmlComponent component(&engine); + component.setData("import ModuleFromQrc\nFoo {}\n", QUrl()); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); +} QTEST_MAIN(tst_qqmlmoduleplugin) diff --git a/tests/auto/qml/qqmlnotifier/CMakeLists.txt b/tests/auto/qml/qqmlnotifier/CMakeLists.txt index 5cc0495393c..4056f064586 100644 --- a/tests/auto/qml/qqmlnotifier/CMakeLists.txt +++ b/tests/auto/qml/qqmlnotifier/CMakeLists.txt @@ -12,16 +12,18 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlnotifier SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlnotifier.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Qml + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmlnotifier) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp b/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp index 836b94ad45f..25eaa22b867 100644 --- a/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp +++ b/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp @@ -36,7 +36,7 @@ #include <QProcess> #endif -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class ExportedClass : public QObject { @@ -140,7 +140,7 @@ class tst_qqmlnotifier : public QQmlDataTest { Q_OBJECT public: - tst_qqmlnotifier() {} + tst_qqmlnotifier() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/qml/qqmlopenmetaobject/tst_qqmlopenmetaobject.cpp b/tests/auto/qml/qqmlopenmetaobject/tst_qqmlopenmetaobject.cpp index 6265c6ca674..27ecf24f26e 100644 --- a/tests/auto/qml/qqmlopenmetaobject/tst_qqmlopenmetaobject.cpp +++ b/tests/auto/qml/qqmlopenmetaobject/tst_qqmlopenmetaobject.cpp @@ -52,7 +52,9 @@ void tst_qqmlopenmetaobject::createProperties() { QQmlEngine engine; CustomObject object; - const QQmlRefPointer<QQmlOpenMetaObjectType> mot = new QQmlOpenMetaObjectType(object.metaObject()); + const QQmlRefPointer<QQmlOpenMetaObjectType> mot( + new QQmlOpenMetaObjectType(object.metaObject()), + QQmlRefPointer<QQmlOpenMetaObjectType>::Adopt); QQmlOpenMetaObject *const mo = new QQmlOpenMetaObject(&object, mot.data()); mo->setCached(true); mot->createProperty("customProperty"); diff --git a/tests/auto/qml/qqmlparser/CMakeLists.txt b/tests/auto/qml/qqmlparser/CMakeLists.txt index c322e29e949..004bb8ea319 100644 --- a/tests/auto/qml/qqmlparser/CMakeLists.txt +++ b/tests/auto/qml/qqmlparser/CMakeLists.txt @@ -12,16 +12,13 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlparser SOURCES - ../../shared/qqmljsastdumper.cpp ../../shared/qqmljsastdumper.h - ../../shared/util.cpp ../../shared/util.h tst_qqmlparser.cpp DEFINES SRCDIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}\\\" - INCLUDE_DIRECTORIES - ../../shared ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp index a480214219d..1268ef8900d 100644 --- a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp +++ b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp @@ -32,8 +32,8 @@ #include <private/qqmljsastvisitor_p.h> #include <private/qqmljsast_p.h> -#include "../../shared/util.h" -#include "../../shared/qqmljsastdumper.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/qqmljsastdumper_p.h> #include <qtest.h> #include <QDir> @@ -240,6 +240,7 @@ class CheckLocations : public Check } tst_qqmlparser::tst_qqmlparser() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } diff --git a/tests/auto/qml/qqmlpromise/CMakeLists.txt b/tests/auto/qml/qqmlpromise/CMakeLists.txt index e972ab08fb3..ac0ffebabeb 100644 --- a/tests/auto/qml/qqmlpromise/CMakeLists.txt +++ b/tests/auto/qml/qqmlpromise/CMakeLists.txt @@ -12,20 +12,22 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlpromise SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlpromise.cpp DEFINES QT_DISABLE_DEPRECATED_BEFORE=0 - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmlpromise) +endif() + #### Keys ignored in scope 1:.:.:qqmlpromise.pro:<TRUE>: # DISTFILES = "data/then-fulfilled-non-callable.qml" "data/then-reject-non-callable.qml" "data/then-resolve-multiple-then.qml" "data/then-resolve-chaining.qml" "data/then-reject-chaining.qml" "data/promise-resolve-with-value.qml" "data/promise-resolve-with-promise.qml" "data/promise-reject-with-value.qml" "data/promise-executor-resolve.qml" "data/promise-get-length.qml" "data/promise-executor-reject.qml" "data/promise-reject-catch.qml" "data/promise-async-resolve-with-value.qml" "data/promise-async-reject-with-value.qml" "data/promise-all-resolve.qml" "data/promise-all-empty-input.qml" "data/promise-resolve-with-array.qml" "data/promise-all-reject-reject-is-last.qml" "data/promise-all-reject-reject-is-mid.qml" "data/promise-race-resolve-1st.qml" "data/promise-race-empty-input.qml" "data/promise-race-resolve-2nd.qml" "data/promise-race-resolve-1st-in-executor-function.qml" "data/promise-resolve-is-a-function.qml" "data/promise-resolve-function-length.qml" "data/promise-all-invoke-then-method.qml" "data/promise-resolve-with-empty.qml" "data/promise-executor-throw-exception.qml" "data/promise-executor-function-extensible.qml" "data/promise-all-noniterable-input.qml" # OTHER_FILES = <EMPTY> diff --git a/tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp b/tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp index b430434526d..2049376a863 100644 --- a/tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp +++ b/tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp @@ -42,14 +42,14 @@ #include <QQmlComponent> #include <QDebug> #include <QScopedPointer> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlpromise : public QQmlDataTest { Q_OBJECT public: - tst_qqmlpromise() {} + tst_qqmlpromise() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void promise_all_empty_input(); diff --git a/tests/auto/qml/qqmlproperty/CMakeLists.txt b/tests/auto/qml/qqmlproperty/CMakeLists.txt index 2dabf0f9484..1c695251f9c 100644 --- a/tests/auto/qml/qqmlproperty/CMakeLists.txt +++ b/tests/auto/qml/qqmlproperty/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlproperty SOURCES - ../../shared/util.cpp ../../shared/util.h interfaces.h tst_qqmlproperty.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -47,4 +45,4 @@ set_target_properties(tst_qqmlproperty PROPERTIES QT_QML_MODULE_URI io.qt.bugreports ) -qt6_qml_type_registration(tst_qqmlproperty) +_qt_internal_qml_type_registration(tst_qqmlproperty) diff --git a/tests/auto/qml/qqmlproperty/data/bindToNonQObjectTarget.qml b/tests/auto/qml/qqmlproperty/data/bindToNonQObjectTarget.qml new file mode 100644 index 00000000000..d8a06aa5f95 --- /dev/null +++ b/tests/auto/qml/qqmlproperty/data/bindToNonQObjectTarget.qml @@ -0,0 +1,20 @@ +import QtQuick + +Item { + id: top; + visible:true; + width:300; + height:300 + Text { + id: text + width: 30; height: 30 + text: "1234.56" + font.bold: true + Binding { + target: text.font // which is not a QObject, so can't use it as a binding target + property: 'bold' + value: false; + when: width < 30 + } + } +} diff --git a/tests/auto/qml/qqmlproperty/data/invalidateQPropertyChangeTriggers.qml b/tests/auto/qml/qqmlproperty/data/invalidateQPropertyChangeTriggers.qml new file mode 100644 index 00000000000..bfa832c1c81 --- /dev/null +++ b/tests/auto/qml/qqmlproperty/data/invalidateQPropertyChangeTriggers.qml @@ -0,0 +1,50 @@ +import QtQml + +QtObject { + id: root + objectName: column.text + + property Component c: Component { + id: comp + QtObject { } + } + + property QtObject rectItem: null + + property bool running: false + + property Timer t: Timer { + id: column + interval: 200 + running: root.running + repeat: true + + property string text: { + let item = root.rectItem + let result = rectItem ? rectItem.objectName : "Create Object" + return result + } + + onTriggered: { + let rectItem = root.rectItem + + // If rectItem exists destory it. + if (rectItem) { + rectItem.destroy() + return + } + + // Otherwise create a new object + let newRectItem = comp.createObject(column, {}) + + + // Setting the objectName before setting root.rectItem seems to work. + // newRectItem.width = 1200 + root.rectItem = newRectItem + + // But setting the objectName after setting root.rectItem seems to + // cause the issue. + newRectItem.objectName = "1300" + } + } +} diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index a1eae50048b..896150b33ef 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -40,8 +40,11 @@ #if QT_CONFIG(regularexpression) #include <QtCore/qregularexpression.h> #endif +#if QT_CONFIG(process) +#include <QtCore/qprocess.h> +#endif #include <QtCore/private/qobject_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include "qobject.h" #include <QtQml/QQmlPropertyMap> @@ -140,7 +143,7 @@ class tst_qqmlproperty : public QQmlDataTest { Q_OBJECT public: - tst_qqmlproperty() {} + tst_qqmlproperty() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; @@ -199,6 +202,12 @@ private slots: void signalExpressionWithoutObject(); void dontRemoveQPropertyBinding(); + void compatResolveUrls(); + + void bindToNonQObjectTarget(); + + void invalidateQPropertyChangeTriggers(); + private: QQmlEngine engine; }; @@ -1995,7 +2004,8 @@ void tst_qqmlproperty::copy() { PropertyObject object; - QQmlProperty *property = new QQmlProperty(&object, QLatin1String("defaultProperty")); + QScopedPointer<QQmlProperty> property( + new QQmlProperty(&object, QLatin1String("defaultProperty"))); QCOMPARE(property->name(), QString("defaultProperty")); QCOMPARE(property->read(), QVariant(10)); QCOMPARE(property->type(), QQmlProperty::Property); @@ -2018,7 +2028,7 @@ void tst_qqmlproperty::copy() QCOMPARE(p2.propertyTypeCategory(), QQmlProperty::Normal); QCOMPARE(p2.propertyType(), QMetaType::Int); - delete property; property = nullptr; + property.reset(); QCOMPARE(p1.name(), QString("defaultProperty")); QCOMPARE(p1.read(), QVariant(10)); @@ -2031,6 +2041,16 @@ void tst_qqmlproperty::copy() QCOMPARE(p2.type(), QQmlProperty::Property); QCOMPARE(p2.propertyTypeCategory(), QQmlProperty::Normal); QCOMPARE(p2.propertyType(), QMetaType::Int); + + p1 = QQmlProperty(); + QQmlPropertyPrivate *p2d = QQmlPropertyPrivate::get(p2); + QCOMPARE(p2d->count(), 1); + + // Use a pointer to avoid compiler warning about self-assignment. + QQmlProperty *p2p = &p2; + *p2p = p2; + + QCOMPARE(p2d->count(), 1); } void tst_qqmlproperty::noContext() @@ -2300,6 +2320,91 @@ void tst_qqmlproperty::dontRemoveQPropertyBinding() QVERIFY(!object.bindableObjectName().hasBinding()); } +void tst_qqmlproperty::compatResolveUrls() +{ + QQmlEngine engine; + QQmlComponent c(&engine); + c.setData(R"( + import QtQml + QtObject { + property url a: "relative/url.png" + } + )", QUrl(QStringLiteral("qrc:/some/resource/path.qml"))); + QVERIFY(c.isReady()); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + + if (qEnvironmentVariableIsSet("QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT")) { + QCOMPARE(qvariant_cast<QUrl>(o->property("a")), + QUrl(QStringLiteral("qrc:/some/resource/relative/url.png"))); + return; + } + + QCOMPARE(qvariant_cast<QUrl>(o->property("a")), QUrl(QStringLiteral("relative/url.png"))); + +#ifdef Q_OS_ANDROID + QSKIP("Can't start QProcess to run a custom user binary on Android"); +#endif + +#if QT_CONFIG(process) + QProcess process; + process.setProgram(QCoreApplication::applicationFilePath()); + process.setEnvironment(QProcess::systemEnvironment() + + QStringList(u"QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT=1"_qs)); + process.setArguments({QStringLiteral("compatResolveUrls")}); + process.start(); + QVERIFY(process.waitForFinished()); + QCOMPARE(process.exitStatus(), QProcess::NormalExit); + QCOMPARE(process.exitCode(), 0); +#else + QSKIP("Testing the QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT " + "environment variable requires QProcess."); +#endif +} + +void tst_qqmlproperty::bindToNonQObjectTarget() +{ + QQmlEngine engine; + const QUrl url = testFileUrl("bindToNonQObjectTarget.qml"); + QQmlComponent component(&engine, url); + + // Yes, we can still create the component. The result of the script expression will only be + // known once it's executed. + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + + QTest::ignoreMessage(QtWarningMsg, + qPrintable(url.toString() + ":14:7: Unable to assign QFont to QObject*")); + QScopedPointer<QObject> o(component.create()); + QVERIFY(!o.isNull()); +} + +void tst_qqmlproperty::invalidateQPropertyChangeTriggers() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("invalidateQPropertyChangeTriggers.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> root(component.create()); + QVERIFY(!root.isNull()); + + QStringList names; + QObject::connect(root.data(), &QObject::objectNameChanged, [&](const QString &name) { + if (names.length() == 10) + root->setProperty("running", false); + else + names.append(name); + }); + + root->setProperty("running", true); + QTRY_VERIFY(!root->property("running").toBool()); + + QCOMPARE(names, (QStringList { + u""_qs, u"1300"_qs, u"Create Object"_qs, + u""_qs, u"1300"_qs, u"Create Object"_qs, + u""_qs, u"1300"_qs, u"Create Object"_qs, + u""_qs + })); +} + QTEST_MAIN(tst_qqmlproperty) #include "tst_qqmlproperty.moc" diff --git a/tests/auto/qml/qqmlpropertycache/CMakeLists.txt b/tests/auto/qml/qqmlpropertycache/CMakeLists.txt index 55f8c7b76bd..cb396998bcc 100644 --- a/tests/auto/qml/qqmlpropertycache/CMakeLists.txt +++ b/tests/auto/qml/qqmlpropertycache/CMakeLists.txt @@ -12,15 +12,13 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlpropertycache SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlpropertycache.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp index a3d84e3eb60..f8ca5e067e2 100644 --- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp +++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp @@ -34,13 +34,13 @@ #include <private/qmetaobjectbuilder_p.h> #include <private/qqmlcontextdata_p.h> #include <QCryptographicHash> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlpropertycache : public QQmlDataTest { Q_OBJECT public: - tst_qqmlpropertycache() {} + tst_qqmlpropertycache() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void properties(); @@ -200,9 +200,8 @@ void tst_qqmlpropertycache::properties() DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(metaObject), - QQmlRefPointer<QQmlPropertyCache>::Adopt); - QQmlPropertyData *data; + QQmlRefPointer<QQmlPropertyCache> cache = QQmlPropertyCache::createStandalone(metaObject); + const QQmlPropertyData *data; QVERIFY((data = cacheProperty(cache, "propertyA"))); QCOMPARE(data->coreIndex(), metaObject->indexOfProperty("propertyA")); @@ -223,12 +222,12 @@ void tst_qqmlpropertycache::propertiesDerived() DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> parentCache( - new QQmlPropertyCache(&BaseObject::staticMetaObject), + QQmlRefPointer<QQmlPropertyCache> parentCache + = QQmlPropertyCache::createStandalone(&BaseObject::staticMetaObject); + QQmlRefPointer<QQmlPropertyCache> cache( + parentCache->copyAndAppend(object.metaObject(), QTypeRevision()), QQmlRefPointer<QQmlPropertyCache>::Adopt); - QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject(), QTypeRevision()), - QQmlRefPointer<QQmlPropertyCache>::Adopt); - QQmlPropertyData *data; + const QQmlPropertyData *data; QVERIFY((data = cacheProperty(cache, "propertyA"))); QCOMPARE(data->coreIndex(), metaObject->indexOfProperty("propertyA")); @@ -251,11 +250,10 @@ void tst_qqmlpropertycache::revisionedProperties() DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cacheWithoutVersion(new QQmlPropertyCache(metaObject), - QQmlRefPointer<QQmlPropertyCache>::Adopt); - QQmlRefPointer<QQmlPropertyCache> cacheWithVersion( - new QQmlPropertyCache(metaObject, QTypeRevision::fromMinorVersion(1)), - QQmlRefPointer<QQmlPropertyCache>::Adopt); + QQmlRefPointer<QQmlPropertyCache> cacheWithoutVersion + = QQmlPropertyCache::createStandalone(metaObject); + QQmlRefPointer<QQmlPropertyCache> cacheWithVersion + = QQmlPropertyCache::createStandalone(metaObject, QTypeRevision::fromMinorVersion(1)); QQmlPropertyData *data; QVERIFY((data = cacheProperty(cacheWithoutVersion, "propertyE"))); @@ -269,9 +267,8 @@ void tst_qqmlpropertycache::methods() DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(metaObject), - QQmlRefPointer<QQmlPropertyCache>::Adopt); - QQmlPropertyData *data; + QQmlRefPointer<QQmlPropertyCache> cache(QQmlPropertyCache::createStandalone(metaObject)); + const QQmlPropertyData *data; QVERIFY((data = cacheProperty(cache, "slotA"))); QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("slotA()")); @@ -305,10 +302,10 @@ void tst_qqmlpropertycache::methodsDerived() const QMetaObject *metaObject = object.metaObject(); QQmlRefPointer<QQmlPropertyCache> parentCache( - new QQmlPropertyCache(&BaseObject::staticMetaObject), + QQmlPropertyCache::createStandalone(&BaseObject::staticMetaObject)); + QQmlRefPointer<QQmlPropertyCache> cache( + parentCache->copyAndAppend(object.metaObject(), QTypeRevision {}), QQmlRefPointer<QQmlPropertyCache>::Adopt); - QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject(), QTypeRevision {}), - QQmlRefPointer<QQmlPropertyCache>::Adopt); QQmlPropertyData *data; QVERIFY((data = cacheProperty(cache, "slotA"))); @@ -342,9 +339,8 @@ void tst_qqmlpropertycache::signalHandlers() DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(metaObject), - QQmlRefPointer<QQmlPropertyCache>::Adopt); - QQmlPropertyData *data; + QQmlRefPointer<QQmlPropertyCache> cache(QQmlPropertyCache::createStandalone(metaObject)); + const QQmlPropertyData *data; QVERIFY((data = cacheProperty(cache, "onSignalA"))); QCOMPARE(data->coreIndex(), metaObject->indexOfMethod("signalA()")); @@ -372,10 +368,10 @@ void tst_qqmlpropertycache::signalHandlersDerived() const QMetaObject *metaObject = object.metaObject(); QQmlRefPointer<QQmlPropertyCache> parentCache( - new QQmlPropertyCache(&BaseObject::staticMetaObject), + QQmlPropertyCache::createStandalone(&BaseObject::staticMetaObject)); + QQmlRefPointer<QQmlPropertyCache> cache( + parentCache->copyAndAppend(object.metaObject(), QTypeRevision{}), QQmlRefPointer<QQmlPropertyCache>::Adopt); - QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject(), QTypeRevision{}), - QQmlRefPointer<QQmlPropertyCache>::Adopt); QQmlPropertyData *data; QVERIFY((data = cacheProperty(cache, "onSignalA"))); @@ -578,10 +574,28 @@ class TestClassWithClassInfo : public QObject #define ARRAY_SIZE(arr) \ int(sizeof(arr) / sizeof(arr[0])) +template <typename T, typename = void> +struct SizeofOffsetsAndSizes_helper +{ + static constexpr size_t value = sizeof(T::offsetsAndSize); // old moc +}; + +template <typename T> +struct SizeofOffsetsAndSizes_helper<T, std::void_t<decltype(T::offsetsAndSizes)>> +{ + static constexpr size_t value = sizeof(T::offsetsAndSizes); // new moc +}; + +template <typename T> +constexpr size_t sizeofOffsetsAndSizes(const T &) +{ + return SizeofOffsetsAndSizes_helper<T>::value; +} + #define TEST_CLASS(Class) \ QTest::newRow(#Class) \ << &Class::staticMetaObject << ARRAY_SIZE(qt_meta_data_##Class) \ - << int(sizeof(qt_meta_stringdata_##Class.offsetsAndSize) / (sizeof(uint) * 2)) + << int(sizeofOffsetsAndSizes(qt_meta_stringdata_##Class) / (sizeof(uint) * 2)) Q_DECLARE_METATYPE(const QMetaObject*); diff --git a/tests/auto/qml/qqmlpropertymap/CMakeLists.txt b/tests/auto/qml/qqmlpropertymap/CMakeLists.txt index 3092aa4eb2d..291c221b23e 100644 --- a/tests/auto/qml/qqmlpropertymap/CMakeLists.txt +++ b/tests/auto/qml/qqmlpropertymap/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlpropertymap SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlpropertymap.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlpropertymap/data/cached.qml b/tests/auto/qml/qqmlpropertymap/data/cached.qml new file mode 100644 index 00000000000..3222a672c38 --- /dev/null +++ b/tests/auto/qml/qqmlpropertymap/data/cached.qml @@ -0,0 +1,5 @@ +import QtQml + +QtObject { + property string text: map ? map.c : "yada" +} diff --git a/tests/auto/qml/qqmlpropertymap/dummy_imports.qml b/tests/auto/qml/qqmlpropertymap/dummy_imports.qml index 4ae9d3f2cf2..63d33cbea64 100644 --- a/tests/auto/qml/qqmlpropertymap/dummy_imports.qml +++ b/tests/auto/qml/qqmlpropertymap/dummy_imports.qml @@ -1,8 +1,7 @@ // This file exists for the sole purpose for qmlimportscanner to find // which modules it needs to extract for deployment. -// Otherwise, it fails to find the imports that are expressed in the -// C++ code belonging to the test. +// Otherwise, it fails to find the imports that are expressed in C++. -import QtQuick 2.0 +import QtQuick -QtObject { } // This is needed in order to keep importscanner happy +QtObject { } diff --git a/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp b/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp index 07afc69a6dd..a6eca4825a6 100644 --- a/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp +++ b/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp @@ -26,7 +26,7 @@ ** ****************************************************************************/ #include <qtest.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcontext.h> #include <QtQml/qqmlpropertymap.h> @@ -39,7 +39,7 @@ class tst_QQmlPropertyMap : public QQmlDataTest { Q_OBJECT public: - tst_QQmlPropertyMap() {} + tst_QQmlPropertyMap() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; @@ -64,6 +64,7 @@ private slots: void QTBUG_48136(); void lookupsInSubTypes(); void freeze(); + void cachedSignals(); }; class LazyPropertyMap : public QQmlPropertyMap, public QQmlParserStatus @@ -595,6 +596,46 @@ void tst_QQmlPropertyMap::freeze() QCOMPARE(map.value("key1").toString(), QStringLiteral("Hello World")); } +class Map: public QQmlPropertyMap +{ + Q_OBJECT +public: + Map(QObject *parent = nullptr) + : QQmlPropertyMap(this, parent) + { + insert( "a", u"yayayaya"_qs ); + insert( "b", u"yayayayb"_qs); + insert( "c", u"yayayayc"_qs); + insert( "d", u"yayayayd"_qs); + + freeze(); + } +}; + +void tst_QQmlPropertyMap::cachedSignals() +{ + Map foo; + QQmlEngine engine; + engine.rootContext()->setContextProperty("map", &foo); + const QUrl url = testFileUrl("cached.qml"); + QQmlComponent c(&engine, url); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + QCOMPARE(o->property("text").toString(), u"yayayayc"_qs); + foo.setProperty("c", u"something"_qs); + QCOMPARE(o->property("text").toString(), u"something"_qs); + foo.insert("c", u"other"_qs); + QCOMPARE(o->property("text").toString(), u"other"_qs); + QTest::ignoreMessage( + QtWarningMsg, + qPrintable(url.toString() + u":4:5: Unable to assign [undefined] to QString"_qs)); + foo.clear("c"); + QCOMPARE(o->property("text").toString(), u"other"_qs); + foo.insert("c", u"final"_qs); + QCOMPARE(o->property("text").toString(), u"final"_qs); +} + QTEST_MAIN(tst_QQmlPropertyMap) #include "tst_qqmlpropertymap.moc" diff --git a/tests/auto/qml/qqmlqt/CMakeLists.txt b/tests/auto/qml/qqmlqt/CMakeLists.txt index 1c965d5c5ad..863057372be 100644 --- a/tests/auto/qml/qqmlqt/CMakeLists.txt +++ b/tests/auto/qml/qqmlqt/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlqt SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlqt.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlqt/data/Other/A.qml b/tests/auto/qml/qqmlqt/data/Other/A.qml new file mode 100644 index 00000000000..7f0ce43d009 --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/Other/A.qml @@ -0,0 +1,8 @@ +import QtQml + +QtObject { + property QtObject there: QtObject {} + property url here: Qt.resolvedUrl(somewhere, there) + property url somewhere +} + diff --git a/tests/auto/qml/qqmlqt/data/Other/qmldir b/tests/auto/qml/qqmlqt/data/Other/qmldir new file mode 100644 index 00000000000..bee62523315 --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/Other/qmldir @@ -0,0 +1,2 @@ +module Other +A 1.0 A.qml diff --git a/tests/auto/qml/qqmlqt/data/resolvedUrl.qml b/tests/auto/qml/qqmlqt/data/resolvedUrl.qml index aa57c73627c..77c00c8618a 100644 --- a/tests/auto/qml/qqmlqt/data/resolvedUrl.qml +++ b/tests/auto/qml/qqmlqt/data/resolvedUrl.qml @@ -1,6 +1,8 @@ import QtQuick 2.0 +import Other QtObject { + id: self property string result property bool isString: false property bool isObject: false @@ -11,5 +13,19 @@ QtObject { isString = (typeof a) == "string" isObject = (typeof a) == "object" } + + property A here: A { + there: self + somewhere: "somewhere.qml" + } + + property A there: A { + somewhere: "somewhere.qml" + } + + property url resolvedHere: here.here + property url resolvedThere: there.here + + property var unresolvedUrl: Qt.url("nowhere/else.js") } diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp index 62e42072b02..98308ddfa95 100644 --- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp +++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp @@ -44,14 +44,14 @@ #include <QQuaternion> #include <QMatrix4x4> #include <QFont> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <private/qglobal_p.h> class tst_qqmlqt : public QQmlDataTest { Q_OBJECT public: - tst_qqmlqt() {} + tst_qqmlqt() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; @@ -634,8 +634,9 @@ void tst_qqmlqt::openUrlExternally() { MyUrlHandler handler; + const QUrl htmlTestFile = testFileUrl("test.html"); QDesktopServices::setUrlHandler("test", &handler, "noteCall"); - QDesktopServices::setUrlHandler("file", &handler, "noteCall"); + QDesktopServices::setUrlHandler(htmlTestFile.scheme(), &handler, "noteCall"); QQmlComponent component(&engine, testFileUrl("openUrlExternally.qml")); QScopedPointer<QObject> object(component.create()); @@ -646,18 +647,19 @@ void tst_qqmlqt::openUrlExternally() object->setProperty("testFile", true); QCOMPARE(handler.called,2); - QCOMPARE(handler.last, testFileUrl("test.html")); + QCOMPARE(handler.last, htmlTestFile); QDesktopServices::unsetUrlHandler("test"); - QDesktopServices::unsetUrlHandler("file"); + QDesktopServices::unsetUrlHandler(htmlTestFile.scheme()); } void tst_qqmlqt::openUrlExternally_pragmaLibrary() { MyUrlHandler handler; + const QUrl htmlTestFile = testFileUrl("test.html"); QDesktopServices::setUrlHandler("test", &handler, "noteCall"); - QDesktopServices::setUrlHandler("file", &handler, "noteCall"); + QDesktopServices::setUrlHandler(htmlTestFile.scheme(), &handler, "noteCall"); QQmlComponent component(&engine, testFileUrl("openUrlExternally_lib.qml")); QScopedPointer<QObject> object(component.create()); @@ -668,10 +670,10 @@ void tst_qqmlqt::openUrlExternally_pragmaLibrary() object->setProperty("testFile", true); QCOMPARE(handler.called,2); - QCOMPARE(handler.last, testFileUrl("test.html")); + QCOMPARE(handler.last, htmlTestFile); QDesktopServices::unsetUrlHandler("test"); - QDesktopServices::unsetUrlHandler("file"); + QDesktopServices::unsetUrlHandler(htmlTestFile.scheme()); } void tst_qqmlqt::md5() @@ -1166,6 +1168,8 @@ void tst_qqmlqt::exit() void tst_qqmlqt::resolvedUrl() { + QQmlEngine engine; + engine.addImportPath(dataDirectory()); QQmlComponent component(&engine, testFileUrl("resolvedUrl.qml")); QScopedPointer<QObject> object(component.create()); @@ -1174,6 +1178,15 @@ void tst_qqmlqt::resolvedUrl() QCOMPARE(object->property("result").toString(), component.url().toString()); QCOMPARE(object->property("isString").toBool(), false); QCOMPARE(object->property("isObject").toBool(), true); + + QCOMPARE(qvariant_cast<QUrl>(object->property("resolvedHere")), + dataDirectoryUrl().resolved(QStringLiteral("somewhere.qml"))); + QCOMPARE(qvariant_cast<QUrl>(object->property("resolvedThere")), + dataDirectoryUrl().resolved(QStringLiteral("Other/somewhere.qml"))); + + QVariant unresolved = object->property("unresolvedUrl"); + QCOMPARE(unresolved.metaType(), QMetaType::fromType<QUrl>()); + QCOMPARE(qvariant_cast<QUrl>(unresolved), QUrl(QStringLiteral("nowhere/else.js"))); } void tst_qqmlqt::later_data() @@ -1354,7 +1367,7 @@ class TimeZoneSwitch { public: TimeZoneSwitch(const char *newZone) - : doChangeZone(qstrcmp(newZone, "localtime") == 0) + : doChangeZone(qstrcmp(newZone, "localtime") != 0) { if (!doChangeZone) return; @@ -1392,6 +1405,9 @@ void tst_qqmlqt::timeRoundtrip_data() // Local timezone: QTest::newRow("localtime") << QTime(0, 0, 0); +#if defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_MACOS) + qInfo("Omitting the tests that depend on setting local time's zone"); +#else // No DST: QTest::newRow("UTC") << QTime(0, 0, 0); QTest::newRow("Europe/Amsterdam") << QTime(1, 0, 0); @@ -1403,14 +1419,11 @@ void tst_qqmlqt::timeRoundtrip_data() QTest::newRow("Australia/Hobart") << QTime(10, 0, 0); QTest::newRow("Pacific/Auckland") << QTime(12, 0, 0); QTest::newRow("Pacific/Samoa") << QTime(13, 0, 0); +#endif } void tst_qqmlqt::timeRoundtrip() { -#ifdef Q_OS_WIN - QSKIP("On Windows, the DateObject doesn't handle DST transitions correctly when the timezone is not localtime."); // I.e.: for this test. -#endif - TimeZoneSwitch tzs(QTest::currentDataTag()); QFETCH(QTime, time); qmlRegisterTypesAndRevisions<TimeProvider>("Test", 1); diff --git a/tests/auto/qml/qqmlsettings/CMakeLists.txt b/tests/auto/qml/qqmlsettings/CMakeLists.txt index 01d35824da6..5b5ba1e257e 100644 --- a/tests/auto/qml/qqmlsettings/CMakeLists.txt +++ b/tests/auto/qml/qqmlsettings/CMakeLists.txt @@ -12,13 +12,11 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlsettings SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlsettings.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Qml + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlsettings/tst_qqmlsettings.cpp b/tests/auto/qml/qqmlsettings/tst_qqmlsettings.cpp index 60daeb07246..baaf126be36 100644 --- a/tests/auto/qml/qqmlsettings/tst_qqmlsettings.cpp +++ b/tests/auto/qml/qqmlsettings/tst_qqmlsettings.cpp @@ -34,12 +34,15 @@ #include <QtGui/QFont> #include <QtQml/QQmlEngine> #include <QtQml/QQmlComponent> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_QQmlSettings : public QQmlDataTest { Q_OBJECT +public: + tst_QQmlSettings(); + private slots: void initTestCase() override; @@ -144,6 +147,11 @@ class CppObject : public QObject QFont m_fontProperty; }; +tst_QQmlSettings::tst_QQmlSettings() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QQmlSettings::initTestCase() { QQmlDataTest::initTestCase(); diff --git a/tests/auto/qml/qqmlsqldatabase/CMakeLists.txt b/tests/auto/qml/qqmlsqldatabase/CMakeLists.txt index b9762b2eb69..aa40348e42e 100644 --- a/tests/auto/qml/qqmlsqldatabase/CMakeLists.txt +++ b/tests/auto/qml/qqmlsqldatabase/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlsqldatabase SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlsqldatabase.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qqmlsqldatabase Qt::QmlPrivate Qt::QuickPrivate Qt::Sql + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlsqldatabase/dummy_imports.qml b/tests/auto/qml/qqmlsqldatabase/dummy_imports.qml index 4ae9d3f2cf2..63d33cbea64 100644 --- a/tests/auto/qml/qqmlsqldatabase/dummy_imports.qml +++ b/tests/auto/qml/qqmlsqldatabase/dummy_imports.qml @@ -1,8 +1,7 @@ // This file exists for the sole purpose for qmlimportscanner to find // which modules it needs to extract for deployment. -// Otherwise, it fails to find the imports that are expressed in the -// C++ code belonging to the test. +// Otherwise, it fails to find the imports that are expressed in C++. -import QtQuick 2.0 +import QtQuick -QtObject { } // This is needed in order to keep importscanner happy +QtObject { } diff --git a/tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp b/tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp index 654877c7eac..b1516644a33 100644 --- a/tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp +++ b/tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp @@ -34,13 +34,14 @@ #include <QtSql/qsqldatabase.h> #include <QtCore/qdir.h> #include <QtCore/qfile.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmlsqldatabase : public QQmlDataTest { Q_OBJECT public: tst_qqmlsqldatabase() + : QQmlDataTest(QT_QMLTEST_DATADIR) { qApp->setApplicationName("tst_qqmlsqldatabase"); qApp->setOrganizationName("QtProject"); diff --git a/tests/auto/qml/qqmltablemodel/CMakeLists.txt b/tests/auto/qml/qqmltablemodel/CMakeLists.txt index 75da1fc93fd..02f93b5802e 100644 --- a/tests/auto/qml/qqmltablemodel/CMakeLists.txt +++ b/tests/auto/qml/qqmltablemodel/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmltablemodel SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmltablemodel.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Qml Qt::QmlPrivate Qt::Quick Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmltablemodel/data/setDataThroughDelegate.qml b/tests/auto/qml/qqmltablemodel/data/setDataThroughDelegate.qml index ebfe4ed930b..fa5d5bf8bbf 100644 --- a/tests/auto/qml/qqmltablemodel/data/setDataThroughDelegate.qml +++ b/tests/auto/qml/qqmltablemodel/data/setDataThroughDelegate.qml @@ -65,21 +65,21 @@ Item { Connections { target: root enabled: column === 1 - onShouldModify: model.display = 18 + function onShouldModify() { model.display = 18 } } Connections { target: root enabled: column === 0 // Invalid: should be "display". - onShouldModifyInvalidRole: model.age = 100 + function onShouldModifyInvalidRole() { model.age = 100 } } Connections { target: root enabled: column === 1 // Invalid: should be string. - onShouldModifyInvalidType: model.display = "Whoops" + function onShouldModifyInvalidType() { model.display = "Whoops" } } } } diff --git a/tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp b/tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp index 3923824fa26..a5db6bdd669 100644 --- a/tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp +++ b/tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp @@ -36,14 +36,14 @@ #include <QtQuick/qquickview.h> #include <QtQuick/private/qquicktableview_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_QQmlTableModel : public QQmlDataTest { Q_OBJECT public: - tst_QQmlTableModel() {} + tst_QQmlTableModel() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void appendRemoveRow(); diff --git a/tests/auto/qml/qqmltimer/dummy_imports.qml b/tests/auto/qml/qqmltimer/dummy_imports.qml index f78e04d4898..e189da66893 100644 --- a/tests/auto/qml/qqmltimer/dummy_imports.qml +++ b/tests/auto/qml/qqmltimer/dummy_imports.qml @@ -1,9 +1,8 @@ // This file exists for the sole purpose for qmlimportscanner to find // which modules it needs to extract for deployment. -// Otherwise, it fails to find the imports that are expressed in the -// C++ code belonging to the test. +// Otherwise, it fails to find the imports that are expressed in C++. -import QtQml 2.0 -import QtQuick 2.0 +import QtQml +import QtQuick -QtObject { } // This is needed in order to keep importscanner happy +QtObject { } diff --git a/tests/auto/qml/qqmltranslation/CMakeLists.txt b/tests/auto/qml/qqmltranslation/CMakeLists.txt index cb402b3e64b..67047ff604d 100644 --- a/tests/auto/qml/qqmltranslation/CMakeLists.txt +++ b/tests/auto/qml/qqmltranslation/CMakeLists.txt @@ -12,16 +12,15 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmltranslation SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmltranslation.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::QmlModelsPrivate Qt::Quick + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -39,6 +38,13 @@ set_source_files_properties( ) # special case end +# On platforms where TESTDATA is embedded into resources (Android, iOS and +# INTEGRITY), the QT_RESOURCE_ALIAS property was previously set when processing +# TESTDATA, so we need to reset it. Otherwise the wrong alias will be written +# to introspect.qrc, and the related test will fail. +set_source_files_properties(${translation_resource_files} PROPERTIES + QT_RESOURCE_ALIAS "NOTFOUND") + qt_internal_add_resource(tst_qqmltranslation "translation" PREFIX "/" diff --git a/tests/auto/qml/qqmltranslation/data/translatedElements.qml b/tests/auto/qml/qqmltranslation/data/translatedElements.qml new file mode 100644 index 00000000000..c2edfe8c787 --- /dev/null +++ b/tests/auto/qml/qqmltranslation/data/translatedElements.qml @@ -0,0 +1,15 @@ +import QtQml +import QtQml.Models + +DelegateModel { + model: ListModel { + ListElement { dish: qsTr("soup"); price: 60 } + ListElement { dish: qsTr("fish"); price: 100 } + ListElement { dish: qsTr("meat"); price: 230 } + ListElement { dish: qsTr("bread"); price: 10 } + } + + delegate: QtObject { + required property string dish + } +} diff --git a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp index 73cdba5f8cb..5e0046fb03b 100644 --- a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp +++ b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp @@ -34,13 +34,14 @@ #include <QQuickItem> #include <private/qqmlengine_p.h> #include <private/qqmltypedata_p.h> -#include "../../shared/util.h" +#include <private/qqmldelegatemodel_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qqmltranslation : public QQmlDataTest { Q_OBJECT public: - tst_qqmltranslation() {} + tst_qqmltranslation() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void translation_data(); @@ -48,6 +49,7 @@ private slots: void idTranslation(); void translationChange(); void preferJSContext(); + void listModel(); }; void tst_qqmltranslation::translation_data() @@ -97,13 +99,13 @@ void tst_qqmltranslation::translation() const bool expectCompiledTranslation = compiledTranslations.contains(propertyName); if (expectCompiledTranslation) { - if (binding->type != QV4::CompiledData::Binding::Type_Translation) + if (binding->type() != QV4::CompiledData::Binding::Type_Translation) qDebug() << "binding for property" << propertyName << "is not a compiled translation"; - QCOMPARE(quint32(binding->type), quint32(QV4::CompiledData::Binding::Type_Translation)); + QCOMPARE(binding->type(), QV4::CompiledData::Binding::Type_Translation); } else { - if (binding->type == QV4::CompiledData::Binding::Type_Translation) + if (binding->type() == QV4::CompiledData::Binding::Type_Translation) qDebug() << "binding for property" << propertyName << "is not supposed to be a compiled translation"; - QVERIFY(binding->type != QV4::CompiledData::Binding::Type_Translation); + QVERIFY(binding->type() != QV4::CompiledData::Binding::Type_Translation); } } } @@ -149,11 +151,11 @@ void tst_qqmltranslation::idTranslation() for (quint32 i = 0; i < rootObject->nBindings; ++i, ++binding) { const QString propertyName = compilationUnit->stringAt(binding->propertyNameIndex); if (propertyName == "idTranslation") { - if (binding->type != QV4::CompiledData::Binding::Type_TranslationById) + if (binding->type() != QV4::CompiledData::Binding::Type_TranslationById) qDebug() << "binding for property" << propertyName << "is not a compiled translation"; - QCOMPARE(quint32(binding->type), quint32(QV4::CompiledData::Binding::Type_TranslationById)); + QCOMPARE(binding->type(), QV4::CompiledData::Binding::Type_TranslationById); } else { - QVERIFY(binding->type != QV4::CompiledData::Binding::Type_Translation); + QVERIFY(binding->type() != QV4::CompiledData::Binding::Type_Translation); } } } @@ -193,6 +195,14 @@ class DummyTranslator : public QTranslator return QString::fromUtf8("Deutsch in mylibrary"); if (!qstrcmp(sourceText, "English in translation") && !qstrcmp(context, "nested_js_translation")) return QString::fromUtf8("Deutsch in Setzung"); + if (!qstrcmp(sourceText, "soup")) + return QString::fromUtf8("Suppe"); + if (!qstrcmp(sourceText, "fish")) + return QString::fromUtf8("Fisch"); + if (!qstrcmp(sourceText, "meat")) + return QString::fromUtf8("Fleisch"); + if (!qstrcmp(sourceText, "bread")) + return QString::fromUtf8("Brot"); return QString(); } @@ -254,6 +264,35 @@ void tst_qqmltranslation::preferJSContext() QCoreApplication::removeTranslator(&translator); } +void tst_qqmltranslation::listModel() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("translatedElements.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> o(component.create()); + QVERIFY(o); + + QQmlDelegateModel *model = qobject_cast<QQmlDelegateModel *>(o.data()); + QVERIFY(model); + + QCOMPARE(model->count(), 4); + + QCOMPARE(model->object(0)->property("dish").toString(), QStringLiteral("soup")); + QCOMPARE(model->object(1)->property("dish").toString(), QStringLiteral("fish")); + QCOMPARE(model->object(2)->property("dish").toString(), QStringLiteral("meat")); + QCOMPARE(model->object(3)->property("dish").toString(), QStringLiteral("bread")); + + DummyTranslator translator; + QCoreApplication::installTranslator(&translator); + engine.setUiLanguage(QStringLiteral("xxx")); + engine.retranslate(); + + QCOMPARE(model->object(0)->property("dish").toString(), QStringLiteral("Suppe")); + QCOMPARE(model->object(1)->property("dish").toString(), QStringLiteral("Fisch")); + QCOMPARE(model->object(2)->property("dish").toString(), QStringLiteral("Fleisch")); + QCOMPARE(model->object(3)->property("dish").toString(), QStringLiteral("Brot")); +} + QTEST_MAIN(tst_qqmltranslation) #include "tst_qqmltranslation.moc" diff --git a/tests/auto/qml/qqmltypeloader/CMakeLists.txt b/tests/auto/qml/qqmltypeloader/CMakeLists.txt index b56dbd89444..e4f99ceaf3c 100644 --- a/tests/auto/qml/qqmltypeloader/CMakeLists.txt +++ b/tests/auto/qml/qqmltypeloader/CMakeLists.txt @@ -12,16 +12,13 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmltypeloader SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h declarativetesttype.h tst_qqmltypeloader.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Qml Qt::QmlPrivate Qt::Quick + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -56,5 +53,5 @@ set_target_properties(tst_qqmltypeloader PROPERTIES QT_QML_MODULE_URI declarative.import.for.typeloader.test ) -qt6_qml_type_registration(tst_qqmltypeloader) +_qt_internal_qml_type_registration(tst_qqmltypeloader) add_subdirectory(SlowImport) diff --git a/tests/auto/qml/qqmltypeloader/dummy_imports.qml b/tests/auto/qml/qqmltypeloader/dummy_imports.qml index a4684b20073..e189da66893 100644 --- a/tests/auto/qml/qqmltypeloader/dummy_imports.qml +++ b/tests/auto/qml/qqmltypeloader/dummy_imports.qml @@ -1,9 +1,8 @@ // This file exists for the sole purpose for qmlimportscanner to find // which modules it needs to extract for deployment. -// Otherwise, it fails to find the imports that are expressed in the -// C++ code belonging to the test. +// Otherwise, it fails to find the imports that are expressed in C++. -import QtQml 2.0 -import QtQuick 2.6 +import QtQml +import QtQuick -QtObject { } // This is needed in order to keep importscanner happy +QtObject { } diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp index 4f1ca9bacec..9cbca71c28a 100644 --- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp +++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp @@ -40,13 +40,16 @@ #include <QtQml/private/qqmltypeloader_p.h> #include <QtQml/private/qqmlirbuilder_p.h> #include <QtQml/private/qqmlirloader_p.h> -#include "../../shared/testhttpserver.h" -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/testhttpserver_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_QQMLTypeLoader : public QQmlDataTest { Q_OBJECT +public: + tst_QQMLTypeLoader(); + private slots: void testLoadComplete(); void loadComponentSynchronously(); @@ -73,6 +76,11 @@ private slots: void checkSingleton(const QString & dataDirectory); }; +tst_QQMLTypeLoader::tst_QQMLTypeLoader() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QQMLTypeLoader::testLoadComplete() { #ifdef Q_OS_ANDROID @@ -329,7 +337,8 @@ class NetworkAccessManager : public QNetworkAccessManager NetworkReply *reply = new NetworkReply; QString filename = QQmlFile::urlToLocalFileOrQrc(url); - QTimer::singleShot(10, reply, [this, reply, filename]() { + QTimer::singleShot(QRandomGenerator::global()->bounded(20), reply, + [this, reply, filename]() { if (filename.isEmpty()) { reply->fail(); } else { @@ -561,6 +570,10 @@ void tst_QQMLTypeLoader::implicitComponentModule() void tst_QQMLTypeLoader::customDiskCachePath() { +#ifdef Q_OS_ANDROID + QSKIP("Android seems to have problems with QProcess"); +#endif + #if QT_CONFIG(process) const char *skipKey = "QT_TST_QQMLTYPELOADER_SKIP_MISMATCH"; if (qEnvironmentVariableIsSet(skipKey)) { @@ -724,6 +737,9 @@ void tst_QQMLTypeLoader::signalHandlersAreCompatible() // make sure that units really come from different places (the machinery // could in theory be smart enough to figure the qmlcachegen cached // version), fairly questionable check but better than nothing +#ifdef Q_OS_ANDROID + QSKIP("qrc and file system is the same thing on Android"); +#endif QVERIFY(unitFromCachegen->url() != unitFromTypeCompiler->url()); } diff --git a/tests/auto/qml/qqmlvaluetypeproviders/CMakeLists.txt b/tests/auto/qml/qqmlvaluetypeproviders/CMakeLists.txt index 697f501153b..2ee105c48d1 100644 --- a/tests/auto/qml/qqmlvaluetypeproviders/CMakeLists.txt +++ b/tests/auto/qml/qqmlvaluetypeproviders/CMakeLists.txt @@ -12,17 +12,15 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlvaluetypeproviders SOURCES - ../../shared/util.cpp ../../shared/util.h testtypes.cpp testtypes.h tst_qqmlvaluetypeproviders.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp index c0bc090bd9c..6212c2d1695 100644 --- a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp +++ b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp @@ -34,7 +34,7 @@ #include <QScopedPointer> #include <private/qqmlglobal_p.h> #include <private/qquickvaluetypes_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include "testtypes.h" QT_BEGIN_NAMESPACE @@ -50,7 +50,7 @@ class tst_qqmlvaluetypeproviders : public QQmlDataTest { Q_OBJECT public: - tst_qqmlvaluetypeproviders() {} + tst_qqmlvaluetypeproviders() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/qml/qqmlvaluetypes/CMakeLists.txt b/tests/auto/qml/qqmlvaluetypes/CMakeLists.txt index fc76a3ff12c..25bf4a4c9ec 100644 --- a/tests/auto/qml/qqmlvaluetypes/CMakeLists.txt +++ b/tests/auto/qml/qqmlvaluetypes/CMakeLists.txt @@ -12,17 +12,15 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlvaluetypes SOURCES - ../../shared/util.cpp ../../shared/util.h testtypes.cpp testtypes.h tst_qqmlvaluetypes.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlvaluetypes/data/matrix4x4_invokables.qml b/tests/auto/qml/qqmlvaluetypes/data/matrix4x4_invokables.qml index aa26956922d..09f1d472b7f 100644 --- a/tests/auto/qml/qqmlvaluetypes/data/matrix4x4_invokables.qml +++ b/tests/auto/qml/qqmlvaluetypes/data/matrix4x4_invokables.qml @@ -10,6 +10,59 @@ Item { property variant v2: Qt.vector3d(1,2,3) property real factor: 2.23 + function testTransformation() { + let m = Qt.matrix4x4(); + + m.scale(1, 2, 4); + if (m !== Qt.matrix4x4(1, 0, 0, 0, + 0, 2, 0, 0, + 0, 0, 4, 0, + 0, 0, 0, 1)) + return false; + m.scale(Qt.vector3d(-8, -4, -2)); + if (m !== Qt.matrix4x4(-8, 0, 0, 0, + 0,-8, 0, 0, + 0, 0, -8, 0, + 0, 0, 0, 1)) + return false; + m.scale(-1 / 8); + if (m !== Qt.matrix4x4()) + return false; + + m.rotate(180, Qt.vector3d(1, 0, 0)); + if (m !== Qt.matrix4x4(1, 0, 0, 0, + 0, -1, 0, 0, + 0, 0, -1, 0, + 0, 0, 0, 1)) + return false; + m.rotate(180, Qt.vector3d(0, 1, 0)); + if (m !== Qt.matrix4x4(-1, 0, 0, 0, + 0, -1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1)) + return false; + m.rotate(180, Qt.vector3d(0, 0, 1)); + if (m !== Qt.matrix4x4()) + return false; + + m.translate(Qt.vector3d(1, 2, 4)); + if (m !== Qt.matrix4x4(1, 0, 0, 1, + 0, 1, 0, 2, + 0, 0, 1, 4, + 0, 0, 0, 1)) + return false; + + m = Qt.matrix4x4(); + m.lookAt(Qt.vector3d(1, 2, 4), Qt.vector3d(1, 2, 0), Qt.vector3d(0, 1, 0)); + if (m !== Qt.matrix4x4(1, 0, 0, -1, + 0, 1, 0, -2, + 0, 0, 1, -4, + 0, 0, 0, 1)) + return false; + + return true; + } + Component.onCompleted: { success = true; if (m1.times(m2) != Qt.matrix4x4(26, 26, 26, 26, 52, 52, 52, 52, 78, 78, 78, 78, 104, 104, 104, 104)) success = false; @@ -27,5 +80,6 @@ Item { if (m1.transposed() != Qt.matrix4x4(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4)) success = false; if (m1.fuzzyEquals(m2)) success = false; if (!m1.fuzzyEquals(m2, 10)) success = false; + if (!testTransformation()) success = false; } } diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp index c062b9cd569..d4524fb4214 100644 --- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp +++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp @@ -36,7 +36,7 @@ #include <private/qqmlglobal_p.h> #include <private/qv4engine_p.h> #include <private/qv4variantobject_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include "testtypes.h" QT_BEGIN_NAMESPACE @@ -47,7 +47,7 @@ class tst_qqmlvaluetypes : public QQmlDataTest { Q_OBJECT public: - tst_qqmlvaluetypes() {} + tst_qqmlvaluetypes() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; @@ -102,6 +102,7 @@ private slots: void char16Type(); void writeBackOnFunctionCall(); void valueTypeConversions(); + void readReferenceOnGetOwnProperty(); private: QQmlEngine engine; @@ -1976,6 +1977,35 @@ void tst_qqmlvaluetypes::valueTypeConversions() QCOMPARE(resultB.b, a.a); } +class Chose : public QObject +{ + Q_OBJECT + Q_PROPERTY(QRectF f READ ff CONSTANT) +public: + Chose(QObject *parent = nullptr) : QObject(parent) {} + QRectF ff() const { return QRectF(); } + Q_INVOKABLE bool g(QJSValue v) { return v.hasProperty("x"); } +}; + +void tst_qqmlvaluetypes::readReferenceOnGetOwnProperty() +{ + Chose chose; + QQmlEngine engine; + engine.rootContext()->setContextProperty(QStringLiteral("chose"), &chose); + QQmlComponent c(&engine); + c.setData(R"fin( + import QtQml + QtObject { + property bool allo: chose.g(chose.f) + } + )fin", QUrl()); + + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + QVERIFY(o->property("allo").toBool()); +} + #undef CHECK_TYPE_IS_NOT_VALUETYPE QTEST_MAIN(tst_qqmlvaluetypes) diff --git a/tests/auto/qml/qqmlxmlhttprequest/CMakeLists.txt b/tests/auto/qml/qqmlxmlhttprequest/CMakeLists.txt index 4f428fe3a17..ea244fcbe4d 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/CMakeLists.txt +++ b/tests/auto/qml/qqmlxmlhttprequest/CMakeLists.txt @@ -12,20 +12,21 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlxmlhttprequest SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h tst_qqmlxmlhttprequest.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::Network Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qqmlxmlhttprequest) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.collection.allprop.expect b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.collection.allprop.expect index 69330e441a9..6dba52d2de0 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.collection.allprop.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.collection.allprop.expect @@ -2,7 +2,6 @@ PROPFIND /container/ HTTP/1.1 Depth: 1 Content-Length: 95 Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} Accept-Language: en-US,* diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.expect b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.expect index d752cf203af..dc7217d45c0 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/WebDAV/propfind.file.expect @@ -1,7 +1,6 @@ PROPFIND /file HTTP/1.1 Content-Length: 192 -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} Accept-Language: en-US,* diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/abort.expect b/tests/auto/qml/qqmlxmlhttprequest/data/abort.expect index d317f51b735..97c16618519 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/abort.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/abort.expect @@ -2,8 +2,7 @@ PUT /testdocument.html HTTP/1.1 Accept-Language: en-US Content-Type: text/plain;charset=UTF-8 Content-Length: 10 -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/getResponseHeader.expect b/tests/auto/qml/qqmlxmlhttprequest/data/getResponseHeader.expect index dbc37463f54..2270e7f3aa2 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/getResponseHeader.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/getResponseHeader.expect @@ -1,7 +1,6 @@ GET /testdocument.html HTTP/1.1 Accept-Language: en-US -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/open_network.expect b/tests/auto/qml/qqmlxmlhttprequest/data/open_network.expect index dbc37463f54..2270e7f3aa2 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/open_network.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/open_network.expect @@ -1,7 +1,6 @@ GET /testdocument.html HTTP/1.1 Accept-Language: en-US -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/receive_binary_data.expect b/tests/auto/qml/qqmlxmlhttprequest/data/receive_binary_data.expect index e56c2eec41d..35d28ec76d3 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/receive_binary_data.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/receive_binary_data.expect @@ -1,8 +1,7 @@ GET /gml_logo.png HTTP/1.1 Accept-Language: en-US,* Content-Type: image/png -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/receive_json_data.expect b/tests/auto/qml/qqmlxmlhttprequest/data/receive_json_data.expect index 38a9ffd705d..9784ba4a808 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/receive_json_data.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/receive_json_data.expect @@ -1,8 +1,7 @@ GET /json.data HTTP/1.1 Accept-Language: en-US,* Content-Type: application/jsonrequest -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.1.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.1.expect index e24608d7c35..64bd2b38189 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.1.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.1.expect @@ -2,8 +2,7 @@ POST /testdocument.html HTTP/1.1 Accept-Language: en-US Content-Type: text/plain;charset=UTF-8 Content-Length: 13 -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.10.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.10.expect index 29828c06d01..2bf3b5a081d 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.10.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.10.expect @@ -2,8 +2,7 @@ OPTIONS /testdocument.html HTTP/1.1 Accept-Language: en-US,* Content-Type: text/plain;charset=UTF-8 Content-Length: 13 -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.expect index e3a9aae9e29..7132819c726 100644 Binary files a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.expect and b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.expect differ diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.4.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.4.expect index 02f48d0abb2..270ee838d9e 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.4.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.4.expect @@ -2,8 +2,7 @@ POST /testdocument.html HTTP/1.1 Accept-Language: en-US Content-Type: charset=UTF-8;text/plain Content-Length: 13 -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.6.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.6.expect index 2b60a6db868..f6c8083875d 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.6.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.6.expect @@ -2,8 +2,7 @@ PUT /testdocument.html HTTP/1.1 Accept-Language: en-US Content-Type: text/plain;charset=UTF-8 Content-Length: 13 -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.8.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.8.expect index f3db27c891f..bcd7e79fc1b 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.8.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.8.expect @@ -1,7 +1,6 @@ OPTIONS / HTTP/1.1 Content-Length: 0 -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} Accept-Language: en-US,* diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.9.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.9.expect index 347181efae0..2d4f2c31464 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.9.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.9.expect @@ -1,7 +1,6 @@ OPTIONS /testdocument.html HTTP/1.1 Content-Length: 0 -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} Accept-Language: en-US,* diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_ignoreData_DELETE.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_ignoreData_DELETE.expect index 0f13fc0bf93..7d96c001018 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/send_ignoreData_DELETE.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_ignoreData_DELETE.expect @@ -1,7 +1,6 @@ DELETE /testdocument.html HTTP/1.1 Accept-Language: en-US -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_ignoreData_GET.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_ignoreData_GET.expect index dbc37463f54..2270e7f3aa2 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/send_ignoreData_GET.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_ignoreData_GET.expect @@ -1,7 +1,6 @@ GET /testdocument.html HTTP/1.1 Accept-Language: en-US -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_ignoreData_HEAD.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_ignoreData_HEAD.expect index 9d2d6bc4755..064cf1b6b70 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/send_ignoreData_HEAD.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_ignoreData_HEAD.expect @@ -1,7 +1,6 @@ HEAD /testdocument.html HTTP/1.1 Accept-Language: en-US -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.expect index 3ff8a420282..55f7f7dceb2 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_patch.expect @@ -3,8 +3,7 @@ Accept-Language: en-US If-Match: "ETagNumber" Content-Type: application/example Content-Length: 247 -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/setRequestHeader.expect b/tests/auto/qml/qqmlxmlhttprequest/data/setRequestHeader.expect index a676062ec0f..003e54f33c3 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/setRequestHeader.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/setRequestHeader.expect @@ -2,8 +2,7 @@ GET /testdocument.html HTTP/1.1 Accept-Language: en-US Test-header: value Test-header2: value,value2 -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/status.expect b/tests/auto/qml/qqmlxmlhttprequest/data/status.expect index dbc37463f54..2270e7f3aa2 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/data/status.expect +++ b/tests/auto/qml/qqmlxmlhttprequest/data/status.expect @@ -1,7 +1,6 @@ GET /testdocument.html HTTP/1.1 Accept-Language: en-US -Connection: Keep-Alive, Upgrade, HTTP2-Settings -Upgrade: h2c +Connection: Keep-Alive{{Ignore}} HTTP2-Settings: {{Ignore}} Accept-Encoding: {{Ignore}} User-Agent: Mozilla/5.0 diff --git a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp index 401152d5750..d1dcf3829aa 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp +++ b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp @@ -42,14 +42,14 @@ #include <QProcessEnvironment> #endif -#include "testhttpserver.h" -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/testhttpserver_p.h> class tst_qqmlxmlhttprequest : public QQmlDataTest { Q_OBJECT public: - tst_qqmlxmlhttprequest() {} + tst_qqmlxmlhttprequest() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; @@ -662,6 +662,8 @@ void tst_qqmlxmlhttprequest::send_options() void tst_qqmlxmlhttprequest::send_options_data() { + if (QLocale::system() != QLocale(QLocale::English, QLocale::UnitedStates)) + QSKIP("Test is locale dependent"); QTest::addColumn<QString>("url_suffix"); QTest::addColumn<QString>("file_expected"); QTest::addColumn<QString>("file_qml"); @@ -886,6 +888,8 @@ void tst_qqmlxmlhttprequest::getAllResponseHeaders_args() void tst_qqmlxmlhttprequest::getBinaryData() { + if (QLocale::system() != QLocale(QLocale::English, QLocale::UnitedStates)) + QSKIP("Test is locale dependent"); TestHTTPServer server; QVERIFY2(server.listen(), qPrintable(server.errorString())); QVERIFY(server.wait(testFileUrl("receive_binary_data.expect"), @@ -905,6 +909,8 @@ void tst_qqmlxmlhttprequest::getBinaryData() void tst_qqmlxmlhttprequest::getJsonData() { + if (QLocale::system() != QLocale(QLocale::English, QLocale::UnitedStates)) + QSKIP("Test is locale dependent"); TestHTTPServer server; QVERIFY2(server.listen(), qPrintable(server.errorString())); QVERIFY(server.wait(testFileUrl("receive_json_data.expect"), @@ -1087,6 +1093,10 @@ static const QString testString = QStringLiteral("Test-String"); void tst_qqmlxmlhttprequest::doFileRequest(std::function<void(QObject *component, QTemporaryFile &writeFile)> verifyFunction) { +#if defined(Q_OS_INTEGRITY) + QSKIP("There's no mounted filesystem on INTEGRITY."); +#endif + // Create test files QTemporaryFile writeFile; QTemporaryFile readFile; @@ -1131,6 +1141,9 @@ void tst_qqmlxmlhttprequest::sendFileRequest() #if QT_CONFIG(process) void tst_qqmlxmlhttprequest::sendFileRequestNotSet() { +#ifdef Q_OS_ANDROID + QSKIP("Trying to run the main app .so lib crashes on Android (QTBUG-99214)"); +#endif if (qEnvironmentVariableIsSet("TEST_CUSTOM_PERMISSIONS")) { // Test with no settings, neither reading nor writing should work doFileRequest([](QObject *object, QTemporaryFile &writeFile) { @@ -1185,6 +1198,10 @@ void tst_qqmlxmlhttprequest::sendFileRequestNotSet() { #if QT_CONFIG(process) void tst_qqmlxmlhttprequest::sendFileRequestNoWrite() { +#ifdef Q_OS_ANDROID + QSKIP("Trying to run the main app .so lib crashes on Android (QTBUG-99214)"); +#endif + if (qEnvironmentVariableIsSet("TEST_CUSTOM_PERMISSIONS")) { // Test with no writing enabled doFileRequest([](QObject* object, QTemporaryFile &writeFile) { @@ -1214,6 +1231,10 @@ void tst_qqmlxmlhttprequest::sendFileRequestNoWrite() { #if QT_CONFIG(process) void tst_qqmlxmlhttprequest::sendFileRequestNoRead() { +#ifdef Q_OS_ANDROID + QSKIP("Trying to run the main app .so lib crashes on Android (QTBUG-99214)"); +#endif + if (qEnvironmentVariableIsSet("TEST_CUSTOM_PERMISSIONS")) { // Test with no reading enabled doFileRequest([](QObject* object, QTemporaryFile &writeFile) { @@ -1246,6 +1267,8 @@ void tst_qqmlxmlhttprequest::sendFileRequestNoRead() { void tst_qqmlxmlhttprequest::sendPropfind() { + if (QLocale::system() != QLocale(QLocale::English, QLocale::UnitedStates)) + QSKIP("Test is locale dependent"); const QString prefix = "WebDAV//"; QFETCH(QString, qml); diff --git a/tests/auto/qml/qqmlxmllistmodel/CMakeLists.txt b/tests/auto/qml/qqmlxmllistmodel/CMakeLists.txt index 3748661ce28..b529ceed8ec 100644 --- a/tests/auto/qml/qqmlxmllistmodel/CMakeLists.txt +++ b/tests/auto/qml/qqmlxmllistmodel/CMakeLists.txt @@ -5,14 +5,12 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qqmlxmllistmodel SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qqmlxmllistmodel.cpp - INCLUDE_DIRECTORIES - ../../shared LIBRARIES Qt::Core Qt::Qml Qt::QmlXmlListModelPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qqmlxmllistmodel/tst_qqmlxmllistmodel.cpp b/tests/auto/qml/qqmlxmllistmodel/tst_qqmlxmllistmodel.cpp index ed91bba0699..66878e41d10 100644 --- a/tests/auto/qml/qqmlxmllistmodel/tst_qqmlxmllistmodel.cpp +++ b/tests/auto/qml/qqmlxmllistmodel/tst_qqmlxmllistmodel.cpp @@ -36,7 +36,7 @@ #include <QNetworkRequest> #include <QNetworkAccessManager> #include <QtQmlXmlListModel/private/qqmlxmllistmodel_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> typedef QList<QVariantList> QQmlXmlModelData; @@ -48,7 +48,7 @@ class tst_QQmlXmlListModel : public QQmlDataTest { Q_OBJECT public: - tst_QQmlXmlListModel() { } + tst_QQmlXmlListModel() : QQmlDataTest(QT_QMLTEST_DATADIR) { } private slots: void initTestCase() override @@ -132,9 +132,9 @@ private slots: class ScopedFile { public: - ScopedFile(const QUrl &url, const QByteArray &data) : m_fileUrl(url) + ScopedFile(const QString &fileName, const QByteArray &data) : m_fileName(fileName) { - m_file.setFileName(url.toLocalFile()); + m_file.setFileName(fileName); m_created = m_file.open(QIODevice::WriteOnly | QIODevice::Truncate); if (m_created) { const auto written = m_file.write(data); @@ -145,11 +145,11 @@ class ScopedFile ~ScopedFile() { QFile::remove(m_file.fileName()); } bool isCreated() const { return m_created; } - QUrl fileUrl() const { return m_fileUrl; } + QString fileName() const { return m_fileName; } private: QFile m_file; - const QUrl m_fileUrl; + const QString m_fileName; bool m_created = false; }; @@ -277,17 +277,17 @@ void tst_QQmlXmlListModel::elementErrors() QQmlComponent component(&engine, testFileUrl("elementErrors.qml")); QTest::ignoreMessage(QtWarningMsg, (testFileUrl("elementErrors.qml").toString() - + ":6:5: QML XmlListModelRole: An xml element must not start with '/'") + + ":6:5: QML XmlListModelRole: An XML element must not start with '/'") .toUtf8() .constData()); QTest::ignoreMessage(QtWarningMsg, (testFileUrl("elementErrors.qml").toString() - + ":7:5: QML XmlListModelRole: An xml element must not end with '/'") + + ":7:5: QML XmlListModelRole: An XML element must not end with '/'") .toUtf8() .constData()); QTest::ignoreMessage(QtWarningMsg, (testFileUrl("elementErrors.qml").toString() - + ":8:5: QML XmlListModelRole: An xml element must not contain \"//\"") + + ":8:5: QML XmlListModelRole: An XML element must not contain \"//\"") .toUtf8() .constData()); @@ -380,7 +380,9 @@ void tst_QQmlXmlListModel::source() if (model->property("source").toString().isEmpty()) QCOMPARE(qvariant_cast<QQmlXmlListModel::Status>(model->property("status")), QQmlXmlListModel::Null); - QCOMPARE(model->property("progress").toDouble(), qreal(source.isLocalFile() ? 1.0 : 0.0)); + qreal expectedProgress = + (source.isLocalFile() || (source.scheme() == QLatin1String("qrc"))) ? 1.0 : 0.0; + QCOMPARE(model->property("progress").toDouble(), expectedProgress); QTRY_COMPARE(spy.count(), 1); spy.clear(); QCOMPARE(qvariant_cast<QQmlXmlListModel::Status>(model->property("status")), @@ -488,6 +490,8 @@ void tst_QQmlXmlListModel::threading() QScopedPointer<QAbstractItemModel> m3(qobject_cast<QAbstractItemModel *>(component.create())); QVERIFY(m3 != nullptr); + QTemporaryDir tempDir; + for (int dataCount = 0; dataCount < xmlDataCount; ++dataCount) { QString data1, data2, data3; for (int i = 0; i < dataCount; ++i) { @@ -499,14 +503,14 @@ void tst_QQmlXmlListModel::threading() + ",sport=Curling;"; } - ScopedFile f1(testFileUrl("file1.xml"), makeItemXmlAndData(data1).toLatin1()); - ScopedFile f2(testFileUrl("file2.xml"), makeItemXmlAndData(data2).toLatin1()); - ScopedFile f3(testFileUrl("file3.xml"), makeItemXmlAndData(data3).toLatin1()); + ScopedFile f1(tempDir.filePath("file1.xml"), makeItemXmlAndData(data1).toLatin1()); + ScopedFile f2(tempDir.filePath("file2.xml"), makeItemXmlAndData(data2).toLatin1()); + ScopedFile f3(tempDir.filePath("file3.xml"), makeItemXmlAndData(data3).toLatin1()); QVERIFY(f1.isCreated() && f2.isCreated() && f3.isCreated()); - m1->setProperty("source", f1.fileUrl()); - m2->setProperty("source", f2.fileUrl()); - m3->setProperty("source", f3.fileUrl()); + m1->setProperty("source", QUrl::fromLocalFile(f1.fileName())); + m2->setProperty("source", QUrl::fromLocalFile(f2.fileName())); + m3->setProperty("source", QUrl::fromLocalFile(f3.fileName())); QCoreApplication::processEvents(); QTRY_VERIFY(m1->rowCount() == dataCount && m2->rowCount() == dataCount diff --git a/tests/auto/qml/qquickfolderlistmodel/CMakeLists.txt b/tests/auto/qml/qquickfolderlistmodel/CMakeLists.txt index 58aa6e95f1d..f6752765b45 100644 --- a/tests/auto/qml/qquickfolderlistmodel/CMakeLists.txt +++ b/tests/auto/qml/qquickfolderlistmodel/CMakeLists.txt @@ -12,15 +12,13 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickfolderlistmodel SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickfolderlistmodel.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -29,6 +27,13 @@ set(introspect_resource_files "data/txtdir/hello.txt" ) +# On platforms where TESTDATA is embedded into resources (Android, iOS and +# INTEGRITY), the QT_RESOURCE_ALIAS property was previously set when processing +# TESTDATA, so we need to reset it. Otherwise the wrong alias will be written +# to introspect.qrc, and the related test will fail. +set_source_files_properties(${introspect_resource_files} PROPERTIES + QT_RESOURCE_ALIAS "NOTFOUND") + qt_internal_add_resource(tst_qquickfolderlistmodel "introspect" PREFIX "/myprefix/subdir" diff --git a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp index d49e9b952bb..cc35510762c 100644 --- a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp +++ b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp @@ -33,7 +33,7 @@ #include <QtCore/qfile.h> #include <QtCore/qabstractitemmodel.h> #include <QDebug> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #if defined (Q_OS_WIN) #include <qt_windows.h> @@ -48,7 +48,7 @@ class tst_qquickfolderlistmodel : public QQmlDataTest { Q_OBJECT public: - tst_qquickfolderlistmodel() {} + tst_qquickfolderlistmodel() : QQmlDataTest(QT_QMLTEST_DATADIR) {} public slots: void removed(const QModelIndex &, int start, int end) { @@ -85,6 +85,10 @@ private slots: void tst_qquickfolderlistmodel::initTestCase() { +#if defined(Q_OS_MACOS) && defined(Q_PROCESSOR_ARM_64) + // ### TODO: this is only a temporary workaround for QTBUG-99665 + QSKIP("Test crashes after running to completion on macos ARM"); +#endif // The tests rely on a fixed number of files in the directory with the qml files // (the data dir), so disable the disk cache to avoid creating .qmlc files and // confusing the test. @@ -94,28 +98,27 @@ void tst_qquickfolderlistmodel::initTestCase() void tst_qquickfolderlistmodel::basicProperties() { -#ifdef Q_OS_ANDROID - QSKIP("[QTBUG-77335] Initial folder of FolderListModel on Android does not work properly," - " and from there on it is unreliable to change the folder"); -#endif QQmlComponent component(&engine, testFileUrl("basic.qml")); QTRY_VERIFY2(component.isReady(), qPrintable(component.errorString())); QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(component.create()); QVERIFY(flm != nullptr); + QSignalSpy folderChangedSpy(flm, SIGNAL(folderChanged())); QCOMPARE(flm->property("nameFilters").toStringList(), QStringList() << "*.qml"); // from basic.qml QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile(QDir::currentPath())); + folderChangedSpy.wait(); // wait for the initial folder to be processed - // wait for the initial directory listing (it will find at least the "data" dir, - // and other dirs on Windows). - QTRY_VERIFY(flm->property("count").toInt() > 0); - - QSignalSpy folderChangedSpy(flm, SIGNAL(folderChanged())); flm->setProperty("folder", dataDirectoryUrl()); QVERIFY(folderChangedSpy.wait()); QCOMPARE(flm->property("count").toInt(), 9); QCOMPARE(flm->property("folder").toUrl(), dataDirectoryUrl()); - QCOMPARE(flm->property("parentFolder").toUrl(), QUrl::fromLocalFile(QDir(directory()).canonicalPath())); +#ifndef Q_OS_ANDROID + // On Android currentDir points to some dir in qrc://, which is not + // considered to be local file, so parentFolder is always + // default-constructed QUrl. + QCOMPARE(flm->property("parentFolder").toUrl(), + QUrl::fromLocalFile(QDir(directory()).canonicalPath())); +#endif QCOMPARE(flm->property("sortField").toInt(), int(Name)); QCOMPARE(flm->property("nameFilters").toStringList(), QStringList() << "*.qml"); QCOMPARE(flm->property("sortReversed").toBool(), false); @@ -195,6 +198,14 @@ void tst_qquickfolderlistmodel::nameFilters() connect(flm, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(removed(QModelIndex,int,int))); +#ifdef Q_OS_ANDROID + // On Android the default folder is application's "files" dir, which + // requires special rights for reading. The test works when started via + // androidtestrunner, but fails when launching the APK directly. Set the + // initial folder to resources root dir, because it is always readable. + flm->setProperty("folder", testFileUrl("")); +#endif + QTRY_VERIFY(flm->rowCount() > 0); // read an invalid directory first... flm->setProperty("folder", testFileUrl("nosuchdirectory")); diff --git a/tests/auto/qml/qquickworkerscript/CMakeLists.txt b/tests/auto/qml/qquickworkerscript/CMakeLists.txt index 52a2380ff49..94473d9032f 100644 --- a/tests/auto/qml/qquickworkerscript/CMakeLists.txt +++ b/tests/auto/qml/qquickworkerscript/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickworkerscript SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickworkerscript.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QmlWorkerScriptPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp index b093dcaf07e..e410bf75a33 100644 --- a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp +++ b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp @@ -38,13 +38,13 @@ #include <private/qquickworkerscript_p.h> #include <private/qqmlengine_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_QQuickWorkerScript : public QQmlDataTest { Q_OBJECT public: - tst_QQuickWorkerScript() {} + tst_QQuickWorkerScript() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void source(); void ready(); diff --git a/tests/auto/qml/qtqmlmodules/CMakeLists.txt b/tests/auto/qml/qtqmlmodules/CMakeLists.txt index 9637588a8be..6ff0cc01aec 100644 --- a/tests/auto/qml/qtqmlmodules/CMakeLists.txt +++ b/tests/auto/qml/qtqmlmodules/CMakeLists.txt @@ -12,18 +12,20 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qtqmlmodules SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qtqmlmodules.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) +if(QT_BUILD_STANDALONE_TESTS) + qt_import_qml_plugins(tst_qtqmlmodules) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/qml/qtqmlmodules/tst_qtqmlmodules.cpp b/tests/auto/qml/qtqmlmodules/tst_qtqmlmodules.cpp index 90b6feee287..874d6fe102d 100644 --- a/tests/auto/qml/qtqmlmodules/tst_qtqmlmodules.cpp +++ b/tests/auto/qml/qtqmlmodules/tst_qtqmlmodules.cpp @@ -30,13 +30,13 @@ #include <QDebug> #include <QQmlEngine> #include <QQmlComponent> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qtqmlmodules : public QQmlDataTest { Q_OBJECT public: - tst_qtqmlmodules() {} + tst_qtqmlmodules() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void baseTypes(); diff --git a/tests/auto/qml/qv4assembler/CMakeLists.txt b/tests/auto/qml/qv4assembler/CMakeLists.txt index 1f73fd3495e..486baf7deb0 100644 --- a/tests/auto/qml/qv4assembler/CMakeLists.txt +++ b/tests/auto/qml/qv4assembler/CMakeLists.txt @@ -12,13 +12,11 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qv4assembler SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qv4assembler.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp b/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp index d6bee0c96cb..5667b7b8af3 100644 --- a/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp +++ b/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp @@ -26,13 +26,12 @@ ** ****************************************************************************/ -#include <util.h> - #include <QtTest/QtTest> #include <QtCore/qprocess.h> #include <QtCore/qtemporaryfile.h> #include <QtQml/qqml.h> #include <QtQml/qqmlapplicationengine.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <private/qv4global_p.h> @@ -44,6 +43,9 @@ class tst_QV4Assembler : public QQmlDataTest { Q_OBJECT +public: + tst_QV4Assembler(); + private slots: void initTestCase() override; void perfMapFile(); @@ -51,6 +53,11 @@ private slots: void jitEnabled(); }; +tst_QV4Assembler::tst_QV4Assembler() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QV4Assembler::initTestCase() { qputenv("QV4_JIT_CALL_THRESHOLD", "0"); @@ -145,6 +152,9 @@ void tst_QV4Assembler::jitEnabled() #if defined(Q_OS_IOS) || defined(Q_OS_TVOS) /* JIT should be disabled on iOS and tvOS. */ QVERIFY(!QT_CONFIG(qml_jit)); +#elif defined(Q_OS_ANDROID) && defined(Q_PROCESSOR_ARM) + /* JIT is disabled for Android on ARM/ARM64 before Qt 6.4, see QTBUG-102776. */ + QVERIFY(!QT_CONFIG(qml_jit)); #elif defined(Q_OS_WIN) && defined(Q_PROCESSOR_ARM) /* JIT should be disabled Windows on ARM/ARM64 for now. */ QVERIFY(!QT_CONFIG(qml_jit)); diff --git a/tests/auto/qml/qv4mm/CMakeLists.txt b/tests/auto/qml/qv4mm/CMakeLists.txt index f5667c2b5d2..93e71ac0c90 100644 --- a/tests/auto/qml/qv4mm/CMakeLists.txt +++ b/tests/auto/qml/qv4mm/CMakeLists.txt @@ -12,14 +12,12 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qv4mm SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qv4mm.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Qml Qt::QmlPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/tests/auto/qml/qv4mm/tst_qv4mm.cpp index b6a5753e56b..fe2e267cfd2 100644 --- a/tests/auto/qml/qv4mm/tst_qv4mm.cpp +++ b/tests/auto/qml/qv4mm/tst_qv4mm.cpp @@ -35,7 +35,7 @@ #include <private/qv4qobjectwrapper_p.h> #include <private/qjsvalue_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <memory> @@ -43,14 +43,22 @@ class tst_qv4mm : public QQmlDataTest { Q_OBJECT +public: + tst_qv4mm(); + private slots: void gcStats(); void multiWrappedQObjects(); void accessParentOnDestruction(); - void clearICParent(); + void cleanInternalClasses(); void createObjectsOnDestruction(); }; +tst_qv4mm::tst_qv4mm() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qv4mm::gcStats() { QLoggingCategory::setFilterRules("qt.qml.gc.*=true"); @@ -77,10 +85,10 @@ void tst_qv4mm::multiWrappedQObjects() QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1); QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0); - // Moves the additional WeakValue from m_multiplyWrappedQObjects to - // m_pendingFreedObjectWrapperValue. It's still alive after all. + // The additional WeakValue from m_multiplyWrappedQObjects hasn't been moved + // to m_pendingFreedObjectWrapperValue yet. It's still alive after all. engine1.memoryManager->runGC(); - QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 2); + QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1); // engine2 doesn't own the object as engine1 was the first to wrap it above. // Therefore, no effect here. @@ -111,16 +119,41 @@ void tst_qv4mm::accessParentOnDestruction() QCOMPARE(obj->property("destructions").toInt(), 100); } -void tst_qv4mm::clearICParent() +void tst_qv4mm::cleanInternalClasses() { QV4::ExecutionEngine engine; QV4::Scope scope(engine.rootContext()); QV4::ScopedObject object(scope, engine.newObject()); + QV4::ScopedObject prototype(scope, engine.newObject()); + + // Set a prototype so that we get a unique IC. + object->setPrototypeOf(prototype); + + QV4::Scoped<QV4::InternalClass> prevIC(scope, object->internalClass()); + QVERIFY(prevIC->d()->transitions.empty()); + + uint prevIcChainLength = 0; + for (QV4::Heap::InternalClass *ic = object->internalClass(); ic; ic = ic->parent) + ++prevIcChainLength; + + const auto checkICCHainLength = [&]() { + uint icChainLength = 0; + for (QV4::Heap::InternalClass *ic = object->internalClass(); ic; ic = ic->parent) + ++icChainLength; + + const uint redundant = object->internalClass()->numRedundantTransitions; + QVERIFY(redundant <= QV4::Heap::InternalClass::MaxRedundantTransitions); + + // A removal makes two transitions redundant. + QVERIFY(icChainLength <= prevIcChainLength + 2 * redundant); + }; + + const uint numTransitions = 16 * 1024; // Keep identifiers in a separate array so that we don't have to allocate them in the loop that // should test the GC on InternalClass allocations. QV4::ScopedArrayObject identifiers(scope, engine.newArrayObject()); - for (uint i = 0; i < 16 * 1024; ++i) { + for (uint i = 0; i < numTransitions; ++i) { QV4::Scope scope(&engine); QV4::ScopedString s(scope); s = engine.newIdentifier(QString::fromLatin1("key%1").arg(i)); @@ -131,22 +164,60 @@ void tst_qv4mm::clearICParent() object->insertMember(s, v); } - // When allocating the InternalClass objects required for deleting properties, the GC should - // eventually run and remove all but the last two. - // If we ever manage to avoid allocating the InternalClasses in the first place we will need - // to change this test. - for (uint i = 0; i < 16 * 1024; ++i) { + // There is a chain of ICs originating from the original class. + QCOMPARE(prevIC->d()->transitions.size(), 1u); + QVERIFY(prevIC->d()->transitions.front().lookup != nullptr); + + // When allocating the InternalClass objects required for deleting properties, eventually + // the IC chain gets truncated, dropping all the removed properties. + for (uint i = 0; i < numTransitions; ++i) { QV4::Scope scope(&engine); QV4::ScopedString s(scope, identifiers->get(i)); QV4::Scoped<QV4::InternalClass> ic(scope, object->internalClass()); QVERIFY(ic->d()->parent != nullptr); - object->deleteProperty(s->toPropertyKey()); + QV4::ScopedValue val(scope, object->get(s->toPropertyKey())); + QCOMPARE(val->toNumber(), double(i)); + QVERIFY(object->deleteProperty(s->toPropertyKey())); + QVERIFY(!object->hasProperty(s->toPropertyKey())); QVERIFY(object->internalClass() != ic->d()); - QCOMPARE(object->internalClass()->parent, ic->d()); - if (ic->d()->parent == nullptr) - return; } - QFAIL("Garbage collector was not triggered by large amount of InternalClasses"); + + // None of the properties we've added are left + for (uint i = 0; i < numTransitions; ++i) { + QV4::ScopedString s(scope, identifiers->get(i)); + QVERIFY(!object->hasProperty(s->toPropertyKey())); + } + + // Also no other properties have appeared + QScopedPointer<QV4::OwnPropertyKeyIterator> iterator(object->ownPropertyKeys(object)); + QVERIFY(!iterator->next(object).isValid()); + + checkICCHainLength(); + + // Add and remove properties until it clears all remaining redundant ones + uint i = 0; + while (object->internalClass()->numRedundantTransitions > 0) { + i = (i + 1) % numTransitions; + QV4::ScopedString s(scope, identifiers->get(i)); + QV4::ScopedValue v(scope); + v->setDouble(i); + object->insertMember(s, v); + QVERIFY(object->deleteProperty(s->toPropertyKey())); + } + + // Make sure that all dangling ICs are actually gone. + scope.engine->memoryManager->runGC(); + + // Now the GC has removed the ICs we originally added by adding properties. + QVERIFY(prevIC->d()->transitions.empty() || prevIC->d()->transitions.front().lookup == nullptr); + + // Same thing with redundant prototypes + for (uint i = 0; i < numTransitions; ++i) { + QV4::ScopedObject prototype(scope, engine.newObject()); + object->setPrototypeOf(prototype); // Makes previous prototype redundant + } + + checkICCHainLength(); } void tst_qv4mm::createObjectsOnDestruction() diff --git a/tests/auto/qml/registrationmacros/CMakeLists.txt b/tests/auto/qml/registrationmacros/CMakeLists.txt index 6ac5d4506cb..3e01ae34c8b 100644 --- a/tests/auto/qml/registrationmacros/CMakeLists.txt +++ b/tests/auto/qml/registrationmacros/CMakeLists.txt @@ -14,4 +14,4 @@ set_target_properties(tst_registrationmacros PROPERTIES QT_QML_MODULE_URI test ) -qt6_qml_type_registration(tst_registrationmacros) +_qt_internal_qml_type_registration(tst_registrationmacros) diff --git a/tests/auto/qml/v4misc/tst_v4misc.cpp b/tests/auto/qml/v4misc/tst_v4misc.cpp index 2412ca7f92d..c505396265f 100644 --- a/tests/auto/qml/v4misc/tst_v4misc.cpp +++ b/tests/auto/qml/v4misc/tst_v4misc.cpp @@ -177,6 +177,10 @@ void tst_v4misc::subClassing() void tst_v4misc::nestingDepth() { +#ifdef Q_OS_ANDROID + QSKIP("tst_v4misc::nestingDepth crashes on Android, see QTBUG-103743."); +#endif + { // left recursive QString s(40000, '`'); diff --git a/tests/auto/qmldom/domitem/tst_qmldomitem.h b/tests/auto/qmldom/domitem/tst_qmldomitem.h index 8346649aa0a..714b278e1f9 100644 --- a/tests/auto/qmldom/domitem/tst_qmldomitem.h +++ b/tests/auto/qmldom/domitem/tst_qmldomitem.h @@ -41,6 +41,8 @@ #include <QtQmlDom/private/qqmldomtop_p.h> #include <QtQmlDom/private/qqmldomastdumper_p.h> #include <QtQmlDom/private/qqmldommock_p.h> +#include <QtQmlDom/private/qqmldomcompare_p.h> +#include <QtQmlDom/private/qqmldomfieldfilter_p.h> #include <QtTest/QtTest> #include <QCborValue> @@ -423,6 +425,9 @@ private slots: } void testLoadDep() { +#ifdef Q_OS_ANDROID + QSKIP("Test uncompatible with Android (QTBUG-100171)"); +#endif QString baseDir = QLatin1String(QT_QMLTEST_DATADIR) + QLatin1String("/domitem"); QStringList qmltypeDirs = QStringList({ baseDir, QLibraryInfo::path(QLibraryInfo::Qml2ImportsPath) }); @@ -531,6 +536,17 @@ private slots: if (!diff.isEmpty()) qDebug().nospace().noquote() << diff; QCOMPARE(dump1, dump2); + QStringList diffs = domCompareStrList(f, copy, FieldFilter::compareFilter()); + if (!diffs.isEmpty()) + qDebug() << "testDeepCopy.diffs:" << diffs; + QVERIFY(diffs.isEmpty()); + DomItem univFile = env.universe().path(f.canonicalPath()); + MutableDomItem univFileCopy = univFile.makeCopy(); + QStringList univFileDiffs = + domCompareStrList(univFile, univFileCopy, FieldFilter::compareFilter()); + if (!univFileDiffs.isEmpty()) + qDebug() << "testDeepCopy.univFileDiffs:" << univFileDiffs; + QVERIFY(univFileDiffs.isEmpty()); } private: diff --git a/tests/auto/qmltest/events/tst_events.qml b/tests/auto/qmltest/events/tst_events.qml index 18a2e932ef5..1b35fab57a2 100644 --- a/tests/auto/qmltest/events/tst_events.qml +++ b/tests/auto/qmltest/events/tst_events.qml @@ -60,11 +60,14 @@ Rectangle { Window { id: sub visible: true + width: 200 + height: 200 property bool clicked: false MouseArea { anchors.fill: parent onClicked: sub.clicked = true } + Component.onCompleted: show() } MouseArea { @@ -101,6 +104,8 @@ Rectangle { } function test_mouse_click_subwindow() { + compare(sub.width, 200) + compare(sub.height, 200) mouseClick(sub) tryCompare(sub, "clicked", true, 10000) } diff --git a/tests/auto/qmltest/events/tst_touch.qml b/tests/auto/qmltest/events/tst_touch.qml index e6b8ac755e7..b6fdc1eb9a6 100644 --- a/tests/auto/qmltest/events/tst_touch.qml +++ b/tests/auto/qmltest/events/tst_touch.qml @@ -77,6 +77,8 @@ MultiPointTouchArea { id: subWindowTouchArea anchors.fill: parent } + + Component.onCompleted: show() } TestCase { diff --git a/tests/auto/qmltest/events/tst_wheel.qml b/tests/auto/qmltest/events/tst_wheel.qml index 96338a51ecb..fc381419711 100644 --- a/tests/auto/qmltest/events/tst_wheel.qml +++ b/tests/auto/qmltest/events/tst_wheel.qml @@ -64,7 +64,7 @@ Rectangle { verify(flick.contentX == 0); flick.contentY = 0; verify(flick.contentY == 0); - mouseWheel(flick, 200, 200, -120, 0, Qt.NoButton, Qt.NoModifier, -1); + mouseWheel(flick, 200, 200, -120, 0, Qt.NoButton, Qt.NoModifier, 100); wait(1000); verify(flick.contentX > 0); verify(flick.contentY == 0); diff --git a/tests/auto/qmltest/selftests/tst_grabImage.qml b/tests/auto/qmltest/selftests/tst_grabImage.qml index 7ce7e93a07b..714bc07f27a 100644 --- a/tests/auto/qmltest/selftests/tst_grabImage.qml +++ b/tests/auto/qmltest/selftests/tst_grabImage.qml @@ -34,6 +34,7 @@ TestCase { id: testCase name: "tst_grabImage" when: windowShown + visible: true function test_equals() { var rect = createTemporaryQmlObject("import QtQuick 2.0; Rectangle { color: 'red'; width: 10; height: 10; }", testCase); @@ -47,6 +48,8 @@ TestCase { // Don't change anything... newImage = grabImage(rect); try { + // Check that we actually grabbed something + compare(newImage.pixel(0, 0), "#ff0000") compare(newImage.size, oldImage.size); verify(newImage.equals(oldImage)); } catch (ex) { @@ -86,6 +89,8 @@ TestCase { try { verify(grabbedImage2.equals(grabbedImage)) + // Check that we actually grabbed, saved, and loaded something + compare(grabbedImage2.pixel(0, 0), "#ff0000") } catch (ex) { grabbedImage2.save("tst_grabImage_test_save2.png") throw ex; diff --git a/tests/auto/qmltest/shadersource/tst_SourcedFromOtherWindow.qml b/tests/auto/qmltest/shadersource/tst_SourcedFromOtherWindow.qml index 51ad2e02f75..8cfa3ebe058 100644 --- a/tests/auto/qmltest/shadersource/tst_SourcedFromOtherWindow.qml +++ b/tests/auto/qmltest/shadersource/tst_SourcedFromOtherWindow.qml @@ -60,7 +60,7 @@ Item { TestCase { name: "shadersource-from-other-window" - when: childWindow.isRendered + when: childWindow.rendered function test_endresult() { verify(true); // that we got here without problems... } diff --git a/tests/auto/quick/CMakeLists.txt b/tests/auto/quick/CMakeLists.txt index 8c2c9261112..360e19470a9 100644 --- a/tests/auto/quick/CMakeLists.txt +++ b/tests/auto/quick/CMakeLists.txt @@ -2,10 +2,16 @@ add_subdirectory(geometry) add_subdirectory(nodes) -add_subdirectory(drawingmodes) add_subdirectory(qquickpixmapcache) +# Limit set of tests to run for static Qt builds. +if(QT_BUILD_MINIMAL_STATIC_TESTS) + return() +endif() +add_subdirectory(drawingmodes) + if(QT_FEATURE_private_tests) + add_subdirectory(examples) add_subdirectory(nokeywords) add_subdirectory(propertyrequirements) add_subdirectory(qquickanimations) @@ -66,7 +72,9 @@ if(QT_FEATURE_private_tests) add_subdirectory(qquickvisualdatamodel) add_subdirectory(qquickview) add_subdirectory(qquickview_extra) - add_subdirectory(qquickcanvasitem) + if(NOT ANDROID) # QTBUG-103099 + add_subdirectory(qquickcanvasitem) + endif() add_subdirectory(qquickdesignersupport) add_subdirectory(qquickscreen) add_subdirectory(touchmouse) diff --git a/tests/auto/quick/drawingmodes/BLACKLIST b/tests/auto/quick/drawingmodes/BLACKLIST new file mode 100644 index 00000000000..2a7a12b9951 --- /dev/null +++ b/tests/auto/quick/drawingmodes/BLACKLIST @@ -0,0 +1,11 @@ +# QTBUG-102447 +[points] +android +[lines] +android +[lineStrip] +android +[triangles] +android +[triangleStrip] +android diff --git a/tests/auto/quick/drawingmodes/CMakeLists.txt b/tests/auto/quick/drawingmodes/CMakeLists.txt index f7bf15f49f2..b2a059f3077 100644 --- a/tests/auto/quick/drawingmodes/CMakeLists.txt +++ b/tests/auto/quick/drawingmodes/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_drawingmodes SOURCES - ../../shared/util.cpp ../../shared/util.h tst_drawingmodes.cpp DEFINES QT_DISABLE_DEPRECATED_BEFORE=0 - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Qml Qt::Quick + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp b/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp index 57c4bee1180..91bef35b1b6 100644 --- a/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp +++ b/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp @@ -35,7 +35,7 @@ #include <QtQuick/qsgflatcolormaterial.h> #include <QtGui/qscreen.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_drawingmodes : public QQmlDataTest { @@ -138,7 +138,10 @@ bool tst_drawingmodes::hasPixelAround(const QImage &fb, int centerX, int centerY return false; } -tst_drawingmodes::tst_drawingmodes() : black(qRgb(0, 0, 0)), red(qRgb(0xff, 0, 0)) +tst_drawingmodes::tst_drawingmodes() + : QQmlDataTest(QT_QMLTEST_DATADIR) + , black(qRgb(0, 0, 0)) + , red(qRgb(0xff, 0, 0)) { qmlRegisterType<DrawingModeItem>("Test", 1, 0, "DrawingModeItem"); outerWindow.showNormal(); diff --git a/tests/auto/quick/examples/BLACKLIST b/tests/auto/quick/examples/BLACKLIST new file mode 100644 index 00000000000..a4e374347ea --- /dev/null +++ b/tests/auto/quick/examples/BLACKLIST @@ -0,0 +1,15 @@ +# The following rely on qtquickcontrols2, and can be unblacklisted once QTBUG-95173 is done. +[sgexamples:examples/quick/canvas/bezierCurve/bezierCurve.qml] +* +[sgexamples:examples/quick/canvas/clip/clip.qml] +* +[sgexamples:examples/quick/canvas/quadraticCurveTo/quadraticCurveTo.qml] +* +[sgexamples:examples/quick/canvas/roundedrect/roundedrect.qml] +* +[sgexamples:examples/quick/canvas/smile/smile.qml] +* +[sgexamples:examples/quick/canvas/squircle/squircle.qml] +* +[sgexamples:examples/quick/canvas/tiger/tiger.qml] +* diff --git a/tests/auto/quick/examples/CMakeLists.txt b/tests/auto/quick/examples/CMakeLists.txt index 5bcaa3f93a8..6582c156044 100644 --- a/tests/auto/quick/examples/CMakeLists.txt +++ b/tests/auto/quick/examples/CMakeLists.txt @@ -4,7 +4,7 @@ ## tst_examples Test: ##################################################################### -qt_internal_add_test(tst_examples +qt_internal_add_test(tst_quick_examples SOURCES tst_examples.cpp DEFINES diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp index dca5c1c3fd9..21900d9eedb 100644 --- a/tests/auto/quick/examples/tst_examples.cpp +++ b/tests/auto/quick/examples/tst_examples.cpp @@ -85,6 +85,8 @@ tst_examples::tst_examples() excludedDirs << "snippets/qml/visualdatamodel_rootindex"; excludedDirs << "snippets/qml/qtbinding"; excludedDirs << "snippets/qml/imports"; + excludedDirs << "examples/quickcontrols2/imagine"; + excludedDirs << "examples/quickcontrols2/texteditor"; excludedFiles << "snippets/qml/image-ext.qml"; excludedFiles << "examples/quick/shapes/content/main.qml"; // relies on resources excludedFiles << "examples/quick/shapes/content/interactive.qml"; // relies on resources @@ -229,15 +231,24 @@ with a lower case letter. */ void tst_examples::sgexamples_data() { +#ifdef Q_OS_ANDROID + QSKIP("tst_examples::sgexamples_data needs adaptions for Android, QTBUG-102858."); +#endif QTest::addColumn<QString>("file"); - QString examples = QLatin1String(SRCDIR) + "/../../../../examples/"; + const QDir repoSourceDir(QLatin1String(SRCDIR) + "/../../../.."); + QVERIFY2(repoSourceDir.exists(), qPrintable( + QString::fromLatin1("repoSourceDir %1 doesn't exist").arg(repoSourceDir.path()))); + + const QDir examplesDir(repoSourceDir.path() + "/examples"); + QVERIFY2(examplesDir.exists(), qPrintable( + QStringLiteral("examplesDir %1 doesn't exist").arg(examplesDir.path()))); QStringList files; - files << findQmlFiles(QDir(examples)); + files << findQmlFiles(examplesDir); - foreach (const QString &file, files) - QTest::newRow(qPrintable(file)) << file; + for (const QString &file : qAsConst(files)) + QTest::newRow(qPrintable(repoSourceDir.relativeFilePath(file))) << file; } void tst_examples::sgexamples() @@ -270,19 +281,34 @@ void tst_examples::sgexamples() void tst_examples::sgsnippets_data() { +#ifdef Q_OS_ANDROID + QSKIP("tst_examples::sgsnippets_data needs adaptions for Android, QTBUG-102858."); +#endif QTest::addColumn<QString>("file"); - QString snippets = QLatin1String(SRCDIR) + "/../../../../src/qml/doc/snippets/qml"; + // Add QML snippets. + const QDir repoSourceDir(QLatin1String(SRCDIR) + "/../../../.."); + QVERIFY2(repoSourceDir.exists(), qPrintable( + QStringLiteral("repoSourceDir %1 doesn't exist").arg(repoSourceDir.path()))); + + QDir snippetsDir(repoSourceDir.path() + "/src/qml/doc/snippets/qml"); + QVERIFY2(snippetsDir.exists(), qPrintable( + QStringLiteral("qml snippetsDir %1 doesn't exist").arg(snippetsDir.path()))); + QStringList files; - files << findQmlFiles(QDir(snippets)); - foreach (const QString &file, files) - QTest::newRow(qPrintable(file)) << file; + files << findQmlFiles(snippetsDir); + for (const QString &file : qAsConst(files)) + QTest::newRow(qPrintable(repoSourceDir.relativeFilePath(file))) << file; + + // Add Quick snippets. + snippetsDir = QDir(repoSourceDir.path() + "/src/quick/doc/snippets/qml"); + QVERIFY2(snippetsDir.exists(), qPrintable( + QStringLiteral("quick snippetsDir %1 doesn't exist").arg(snippetsDir.path()))); - snippets = QLatin1String(SRCDIR) + "/../../../../src/quick/doc/snippets/qml"; files.clear(); - files << findQmlFiles(QDir(snippets)); - foreach (const QString &file, files) - QTest::newRow(qPrintable(file)) << file; + files << findQmlFiles(snippetsDir); + for (const QString &file : qAsConst(files)) + QTest::newRow(qPrintable(repoSourceDir.relativeFilePath(file))) << file; } void tst_examples::sgsnippets() diff --git a/tests/auto/quick/nodes/tst_nodestest.cpp b/tests/auto/quick/nodes/tst_nodestest.cpp index af2121f6a5a..c1998f936e9 100644 --- a/tests/auto/quick/nodes/tst_nodestest.cpp +++ b/tests/auto/quick/nodes/tst_nodestest.cpp @@ -109,8 +109,6 @@ private Q_SLOTS: private: void rhiTestData(); - QOffscreenSurface *surface = nullptr; - QOpenGLContext *context = nullptr; QSGDefaultRenderContext *renderContext = nullptr; struct { @@ -172,12 +170,12 @@ class DummyRenderer : public QSGBatchRenderer::Renderer setRootNode(root); } - void render() { + void render() override { ++renderCount; renderingOrder = ++globalRendereringOrder; } - void nodeChanged(QSGNode *node, QSGNode::DirtyState state) { + void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override { changedNode = node; changedState = state; QSGBatchRenderer::Renderer::nodeChanged(node, state); diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST b/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST index 47c11f14d81..d2a270279b6 100644 --- a/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST +++ b/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST @@ -5,7 +5,16 @@ opensuse-leap windows gcc [touchDragFlickableBehindButton] windows gcc -[touchAndDragHandlerOnFlickable] -macos # QTBUG-86729 [touchDragSliderAndFlickable] * # QTBUG-86729 + +# QTBUG-103061 +[touchDragFlickableBehindItemWithHandlers] +android +[mouseDragFlickableBehindItemWithHandlers] +android +[touchAndDragHandlerOnFlickable] +android +# QTBUG-113226 +[pinchHandlerOnFlickable] +* diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/CMakeLists.txt b/tests/auto/quick/pointerhandlers/flickableinterop/CMakeLists.txt index f67f9a0a59c..41045a64d50 100644 --- a/tests/auto/quick/pointerhandlers/flickableinterop/CMakeLists.txt +++ b/tests/auto/quick/pointerhandlers/flickableinterop/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_flickableinterop SOURCES - ../../../shared/util.cpp ../../../shared/util.h - ../../shared/geometrytestutil.cpp ../../shared/geometrytestutil.h - ../../shared/viewtestutil.cpp ../../shared/viewtestutil.h - ../../shared/visualtestutil.cpp ../../shared/visualtestutil.h tst_flickableinterop.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickable.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickable.qml new file mode 100644 index 00000000000..a4867d502c9 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickable.qml @@ -0,0 +1,49 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick + +Flickable { + id: root + width: 800 + height: 480 + contentWidth: 1000 + contentHeight: 600 + + Rectangle { + id: pinchable + objectName: "pinchable" + border.color: "black" + color: pinch.active ? "salmon" : "peachpuff" + x: 100 + y: 100 + width: 200 + height: 200 + radius: 80 + PinchHandler { + id: pinch + } + PointHandler { + id: p1 + target: Rectangle { + parent: pinchable + color: "green" + visible: p1.active + x: p1.point.position.x - width / 2 + y: p1.point.position.y - height / 2 + width: 9; height: width; radius: width / 2 + } + } + PointHandler { + id: p0 + target: Rectangle { + parent: pinchable + color: "red" + visible: p0.active + x: p0.point.position.x - width / 2 + y: p0.point.position.y - height / 2 + width: 9; height: width; radius: width / 2 + } + } + } +} diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickableWithParentTapHandler.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickableWithParentTapHandler.qml new file mode 100644 index 00000000000..2660952f164 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/pinchOnFlickableWithParentTapHandler.qml @@ -0,0 +1,24 @@ +import QtQuick + +Rectangle { + width: 320 + height: 320 + + TapHandler { + onTapped: color = "tomato" + } + + Flickable { + anchors.fill: parent + contentWidth: content.width + contentHeight: content.height + Rectangle { + id: content + objectName: "pinchable" + width: 150 + height: 150 + color: "wheat" + PinchHandler {} + } + } +} diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp index 869ba806583..b7f49834d1b 100644 --- a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp +++ b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp @@ -36,6 +36,7 @@ #include <QtQuick/private/qquickitemview_p.h> #include <QtQuick/private/qquickpointerhandler_p.h> #include <QtQuick/private/qquickdraghandler_p.h> +#include <QtQuick/private/qquickpinchhandler_p.h> #include <QtQuick/private/qquicktaphandler_p.h> #include <QtQuick/private/qquicktableview_p.h> #include <qpa/qwindowsysteminterface.h> @@ -45,8 +46,8 @@ #include <QtQml/qqmlengine.h> #include <QtQml/qqmlproperty.h> -#include "../../../shared/util.h" -#include "../../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests") @@ -55,7 +56,8 @@ class tst_FlickableInterop : public QQmlDataTest Q_OBJECT public: tst_FlickableInterop() - :touchDevice(QTest::createTouchDevice()) + : QQmlDataTest(QT_QMLTEST_DATADIR) + , touchDevice(QTest::createTouchDevice()) {} private slots: @@ -79,10 +81,15 @@ private slots: void touchDragSliderAndFlickable(); void touchAndDragHandlerOnFlickable_data(); void touchAndDragHandlerOnFlickable(); + void pinchHandlerOnFlickable(); + void nativeGesturePinchOnFlickableWithParentTapHandler_data(); + void nativeGesturePinchOnFlickableWithParentTapHandler(); private: void createView(QScopedPointer<QQuickView> &window, const char *fileName); QPointingDevice *touchDevice; + QScopedPointer<QPointingDevice> touchpad = QScopedPointer<QPointingDevice>( + QTest::createTouchDevice(QInputDevice::DeviceType::TouchPad)); }; void tst_FlickableInterop::createView(QScopedPointer<QQuickView> &window, const char *fileName) @@ -90,8 +97,8 @@ void tst_FlickableInterop::createView(QScopedPointer<QQuickView> &window, const window.reset(new QQuickView); window->setSource(testFileUrl(fileName)); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); @@ -806,6 +813,190 @@ void tst_FlickableInterop::touchAndDragHandlerOnFlickable() touchSeq.release(1, p1, window).commit(); } +void tst_FlickableInterop::pinchHandlerOnFlickable() +{ + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("pinchOnFlickable.qml"))); + QQuickFlickable *flickable = qmlobject_cast<QQuickFlickable*>(window.rootObject()); + QVERIFY(flickable); + QQuickPointerHandler *pinchHandler = flickable->findChild<QQuickPointerHandler*>(); + QVERIFY(pinchHandler); + QQuickItem *pinchable = pinchHandler->target(); + QVERIFY(pinchable); + + QSignalSpy flickMoveSpy(flickable, &QQuickFlickable::movementStarted); + QSignalSpy grabChangedSpy(touchDevice, &QPointingDevice::grabChanged); + + QObject *grabber = nullptr; + connect(touchDevice, &QPointingDevice::grabChanged, + [&grabber](QObject *g, QPointingDevice::GrabTransition transition, const QPointerEvent *, const QEventPoint &) { + if (transition == QPointingDevice::GrabTransition::GrabExclusive) + grabber = g; + }); + + QPoint p0 = pinchable->mapToScene({50, 100}).toPoint(); + QPoint p1 = pinchable->mapToScene({150, 100}).toPoint(); + QTest::QTouchEventSequence touch = QTest::touchEvent(&window, touchDevice); + + touch.press(0, p0, &window).press(1, p1, &window).commit(); + QQuickTouchUtils::flush(&window); + int activeStep = -1; + int grabTransitionCount = 0; + // drag two fingers down: PinchHandler moves the item; Flickable doesn't grab, because there are 2 points + for (int i = 0; i < 4; ++i) { + p0 += QPoint(0, dragThreshold); + p1 += QPoint(0, dragThreshold); + touch.move(0, p0, &window).move(1, p1, &window).commit(); + QQuickTouchUtils::flush(&window); + if (pinchHandler->active() && activeStep < 0) { + qCDebug(lcPointerTests) << "pinch began at step" << i; + activeStep = i; + QCOMPARE(grabber, pinchHandler); + grabTransitionCount = grabChangedSpy.count(); + } + } + QVERIFY(pinchHandler->active()); + QCOMPARE(grabChangedSpy.count(), grabTransitionCount); + QCOMPARE(grabber, pinchHandler); + qreal scale = pinchable->scale(); + QCOMPARE(scale, 1); + qreal rot = pinchable->rotation(); + QCOMPARE(rot, 0); + // start expanding and rotating + for (int i = 0; i < 4; ++i) { + p0 += QPoint(-5, 10); + p1 += QPoint(5, -10); + touch.move(0, p0, &window).move(1, p1, &window).commit(); + QQuickTouchUtils::flush(&window); + QVERIFY(pinchHandler->active()); + // PinchHandler keeps grab: no more transitions + QCOMPARE(grabChangedSpy.count(), grabTransitionCount); + QCOMPARE(grabber, pinchHandler); + QVERIFY(pinchable->scale() > scale); + scale = pinchable->scale(); + QVERIFY(pinchable->rotation() < rot); + rot = pinchable->rotation(); + } + touch.release(0, p0, &window).release(1, p1, &window).commit(); + QQuickTouchUtils::flush(&window); + QTRY_COMPARE(pinchHandler->active(), false); + QCOMPARE(flickMoveSpy.count(), 0); // Flickable never moved +} + +void tst_FlickableInterop::nativeGesturePinchOnFlickableWithParentTapHandler_data() +{ + QTest::addColumn<const QPointingDevice*>("device"); + QTest::addColumn<Qt::MouseButton>("button"); + QTest::addColumn<Qt::NativeGestureType>("gesture"); + QTest::addColumn<qreal>("value"); + QTest::addColumn<qreal>("expectedPropertyValue"); + + const QPointingDevice *constTouchPad = touchpad.data(); + + // expectedPropertyValue is 10 in newer Qt versions, but in 6.2 QQuickPinchHandler::onActiveChanged() resets the first rotation + QTest::newRow("touchpad: left and rotate") << constTouchPad << Qt::LeftButton << Qt::RotateNativeGesture << 5.0 << 5.0; + QTest::newRow("touchpad: right and rotate") << constTouchPad << Qt::RightButton << Qt::RotateNativeGesture << 5.0 << 5.0; + + // whereas zoom is cumulative as expected + QTest::newRow("touchpad: left and scale") << constTouchPad << Qt::LeftButton << Qt::ZoomNativeGesture << 0.1 << 1.21; + QTest::newRow("touchpad: right and scale") << constTouchPad << Qt::RightButton << Qt::ZoomNativeGesture << 0.1 << 1.21; + + const auto *mouse = QPointingDevice::primaryPointingDevice(); + if (mouse->type() == QInputDevice::DeviceType::Mouse) { + QTest::newRow("mouse: left and rotate") << mouse << Qt::LeftButton << Qt::RotateNativeGesture << 5.0 << 10.0; + QTest::newRow("mouse: right and rotate") << mouse << Qt::RightButton << Qt::RotateNativeGesture << 5.0 << 10.0; + QTest::newRow("mouse: left and scale") << mouse << Qt::LeftButton << Qt::ZoomNativeGesture << 0.1 << 1.21; + QTest::newRow("mouse: right and scale") << mouse << Qt::RightButton << Qt::ZoomNativeGesture << 0.1 << 1.21; + } else { + qCWarning(lcPointerTests) << "skipping mouse tests: primary device is not a mouse" << mouse; + } +} + +void tst_FlickableInterop::nativeGesturePinchOnFlickableWithParentTapHandler() +{ + QFETCH(const QPointingDevice*, device); + QFETCH(Qt::MouseButton, button); + QFETCH(Qt::NativeGestureType, gesture); + QFETCH(qreal, value); + QFETCH(qreal, expectedPropertyValue); + + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("pinchOnFlickableWithParentTapHandler.qml"))); + QQuickFlickable *flickable = window.rootObject()->findChild<QQuickFlickable*>(); + QVERIFY(flickable); + QQuickPointerHandler *pinchHandler = flickable->findChild<QQuickPinchHandler*>(); + QVERIFY(pinchHandler); + QQuickItem *pinchable = pinchHandler->target(); + QVERIFY(pinchable); + QQuickTapHandler *tapHandler = window.rootObject()->findChild<QQuickTapHandler*>(); + QVERIFY(tapHandler); + const bool expectTap = button & tapHandler->acceptedButtons(); + + QSignalSpy flickMoveSpy(flickable, &QQuickFlickable::movementStarted); + QSignalSpy grabChangedSpy(touchDevice, &QPointingDevice::grabChanged); + QSignalSpy tapActiveSpy(tapHandler, &QQuickTapHandler::activeChanged); + QSignalSpy tapSpy(tapHandler, &QQuickTapHandler::tapped); + + QObject *grabber = nullptr; + connect(device, &QPointingDevice::grabChanged, + [&grabber](QObject *g, QPointingDevice::GrabTransition transition, const QPointerEvent *, const QEventPoint &) { + if (transition == QPointingDevice::GrabTransition::GrabExclusive) + grabber = g; + }); + + const QPoint pinchPos(75, 75); + const QPoint outsidePos(200, 200); + + // move to position + QTest::mouseMove(&window, pinchPos); + + // pinch via native gesture + ulong ts = 502; // after the mouse move, which is at time 501 in practice + QWindowSystemInterface::handleGestureEvent(&window, ts++, touchpad.get(), + Qt::BeginNativeGesture, pinchPos, pinchPos); + if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); + for (int i = 0; i < 2; ++i) { + QWindowSystemInterface::handleGestureEventWithRealValue(&window, ts++, touchpad.get(), + gesture, value, pinchPos, pinchPos); + } + if (gesture == Qt::RotateNativeGesture) + QTRY_COMPARE(pinchHandler->parentItem()->rotation(), expectedPropertyValue); + else if (gesture == Qt::ZoomNativeGesture) + QTRY_COMPARE(pinchHandler->parentItem()->scale(), expectedPropertyValue); + QVERIFY(pinchHandler->active()); + QCOMPARE(grabChangedSpy.count(), 0); + QCOMPARE(grabber, nullptr); + if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); + QWindowSystemInterface::handleGestureEvent(&window, ts++, touchpad.get(), + Qt::EndNativeGesture, pinchPos, pinchPos); + + // tap in square: TapHandler detects tap iff acceptedButtons permits + // TODO delay; unfortunately this also begins at timestamp 502 because we don't have testlib + // functions to send gesture events, and QQuickTest::pointerPress() doesn't take a delay value + QQuickTest::pointerPress(device, &window, 0, pinchPos, button); + QCOMPARE(tapHandler->point().id(), expectTap ? 0 : -1); + QQuickTest::pointerRelease(device, &window, 0, pinchPos, button); + if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); + QCOMPARE(tapSpy.size(), expectTap); + QCOMPARE(tapActiveSpy.size(), 0); + QCOMPARE(tapHandler->point().id(), -1); // does not keep tracking after release + + // move outside: nothing should happen; + // but QTBUG-108896 happened because TapHandler was setting pointInfo to track this moving point + QQuickTest::pointerMove(device, &window, 0, outsidePos); + QCOMPARE(tapHandler->point().id(), -1); // does not track after mouse move + + // tap outside: nothing happens + tapSpy.clear(); + tapActiveSpy.clear(); + QQuickTest::pointerPress(device, &window, 0, outsidePos, button); + QQuickTest::pointerRelease(device, &window, 0, outsidePos, button); + if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); + QCOMPARE(tapSpy.size(), 0); + QCOMPARE(tapActiveSpy.size(), 0); +} + QTEST_MAIN(tst_FlickableInterop) #include "tst_flickableinterop.moc" diff --git a/tests/auto/quick/pointerhandlers/mousearea_interop/CMakeLists.txt b/tests/auto/quick/pointerhandlers/mousearea_interop/CMakeLists.txt index f799de97b89..a68d89ee298 100644 --- a/tests/auto/quick/pointerhandlers/mousearea_interop/CMakeLists.txt +++ b/tests/auto/quick/pointerhandlers/mousearea_interop/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_mousearea_interop SOURCES - ../../../shared/util.cpp ../../../shared/util.h - ../../shared/geometrytestutil.cpp ../../shared/geometrytestutil.h - ../../shared/viewtestutil.cpp ../../shared/viewtestutil.h - ../../shared/visualtestutil.cpp ../../shared/visualtestutil.h tst_mousearea_interop.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/pointerhandlers/mousearea_interop/data/hoverHandlerInGrandparentOfHoverableItem.qml b/tests/auto/quick/pointerhandlers/mousearea_interop/data/hoverHandlerInGrandparentOfHoverableItem.qml new file mode 100644 index 00000000000..a3b957a1f72 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/mousearea_interop/data/hoverHandlerInGrandparentOfHoverableItem.qml @@ -0,0 +1,33 @@ +import QtQuick 2.12 + +Item { + width: 320 + height: 240 + + Rectangle { + color: hh.hovered ? "orange" : "gray" + anchors.fill: container + } + + Item { + id: container + anchors.fill: parent + anchors.margins: 40 + + Rectangle { + width: parent.width + height: 40 + color: ma.pressed ? "blue" : ma.containsMouse ? "aquamarine" : "beige" + + MouseArea { + id: ma + anchors.fill: parent + hoverEnabled: true + } + } + + HoverHandler { + id: hh + } + } +} diff --git a/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp b/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp index 4709622245a..ffc0cc333d2 100644 --- a/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp +++ b/tests/auto/quick/pointerhandlers/mousearea_interop/tst_mousearea_interop.cpp @@ -31,13 +31,14 @@ #include <QtQml/qqmlengine.h> #include <QtQml/qqmlproperty.h> #include <QtQuick/private/qquickdraghandler_p.h> +#include <QtQuick/private/qquickhoverhandler_p.h> #include <QtQuick/private/qquickmousearea_p.h> #include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> #include <QtGui/private/qpointingdevice_p.h> -#include "../../../shared/util.h" -#include "../../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests") @@ -46,12 +47,14 @@ class tst_MouseAreaInterop : public QQmlDataTest Q_OBJECT public: tst_MouseAreaInterop() + : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void dragHandlerInSiblingStealingGrabFromMouseAreaViaMouse(); void dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch_data(); void dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch(); + void hoverHandlerDoesntHoverOnPress(); private: void createView(QScopedPointer<QQuickView> &window, const char *fileName); @@ -63,8 +66,8 @@ void tst_MouseAreaInterop::createView(QScopedPointer<QQuickView> &window, const window.reset(new QQuickView); window->setSource(testFileUrl(fileName)); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); @@ -175,6 +178,37 @@ void tst_MouseAreaInterop::dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch QCOMPARE(handler->active(), false); } +void tst_MouseAreaInterop::hoverHandlerDoesntHoverOnPress() // QTBUG-72843 +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("hoverHandlerInGrandparentOfHoverableItem.qml"))); + + QPointer<QQuickHoverHandler> handler = window.rootObject()->findChild<QQuickHoverHandler*>(); + QVERIFY(handler); + QQuickMouseArea *ma = window.rootObject()->findChild<QQuickMouseArea*>(); + QVERIFY(ma); + QPoint p = ma->mapToScene(ma->boundingRect().center()).toPoint(); + + // move the mouse below the "button" but within HoverHandler's region of interest + QTest::mouseMove(&window, p + QPoint(0, 50)); + QTRY_COMPARE(handler->isHovered(), true); + // move the mouse into the "button" + QTest::mouseMove(&window, p); + // both the hoverhandler and the mouse area should now be hovered! + QTRY_COMPARE(handler->isHovered(), true); + QCOMPARE(ma->hovered(), true); + + QSignalSpy hoveredChangedSpy(handler, SIGNAL(hoveredChanged())); + QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, p); + QTRY_COMPARE(ma->pressed(), true); + QCOMPARE(handler->isHovered(), true); + QCOMPARE(hoveredChangedSpy.count(), 0); + QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, p); + QTRY_COMPARE(ma->pressed(), false); + QCOMPARE(handler->isHovered(), true); + QCOMPARE(hoveredChangedSpy.count(), 0); +} + QTEST_MAIN(tst_MouseAreaInterop) #include "tst_mousearea_interop.moc" diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/CMakeLists.txt b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/CMakeLists.txt index 4aac9440f9c..03558f9bf91 100644 --- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/CMakeLists.txt +++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_multipointtoucharea_interop SOURCES - ../../../shared/util.cpp ../../../shared/util.h - ../../shared/geometrytestutil.cpp ../../shared/geometrytestutil.h - ../../shared/viewtestutil.cpp ../../shared/viewtestutil.h - ../../shared/visualtestutil.cpp ../../shared/visualtestutil.h tst_multipointtoucharea_interop.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp index 0312ed01411..243e7696583 100644 --- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp +++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp @@ -37,8 +37,8 @@ #include <QtQuick/qquickview.h> #include <QtGui/private/qpointingdevice_p.h> -#include "../../../shared/util.h" -#include "../../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests") @@ -47,6 +47,7 @@ class tst_MptaInterop : public QQmlDataTest Q_OBJECT public: tst_MptaInterop() + : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: @@ -67,8 +68,8 @@ void tst_MptaInterop::createView(QScopedPointer<QQuickView> &window, const char window.reset(new QQuickView); window->setSource(testFileUrl(fileName)); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/BLACKLIST b/tests/auto/quick/pointerhandlers/qquickdraghandler/BLACKLIST new file mode 100644 index 00000000000..e555a4bb61c --- /dev/null +++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/BLACKLIST @@ -0,0 +1,9 @@ +# QTBUG-103064 +[touchDragMulti] +android +[touchDrag] +android +[touchDragMultiSliders] +android +[touchPassiveGrabbers] +android diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquickdraghandler/CMakeLists.txt index 85c664f8ca9..9b0cd40578c 100644 --- a/tests/auto/quick/pointerhandlers/qquickdraghandler/CMakeLists.txt +++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickdraghandler SOURCES - ../../../shared/util.cpp ../../../shared/util.h - ../../shared/geometrytestutil.cpp ../../shared/geometrytestutil.h - ../../shared/viewtestutil.cpp ../../shared/viewtestutil.h - ../../shared/visualtestutil.cpp ../../shared/visualtestutil.h tst_qquickdraghandler.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp index 059f06f4698..8e191eb3980 100644 --- a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp @@ -37,8 +37,8 @@ #include <QtQuick/qquickview.h> #include <QtGui/private/qpointingdevice_p.h> -#include "../../../shared/util.h" -#include "../../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests") @@ -47,7 +47,8 @@ class tst_DragHandler : public QQmlDataTest Q_OBJECT public: tst_DragHandler() - :touchDevice(QTest::createTouchDevice()) + : QQmlDataTest(QT_QMLTEST_DATADIR) + , touchDevice(QTest::createTouchDevice()) {} private slots: @@ -84,8 +85,8 @@ void tst_DragHandler::createView(QScopedPointer<QQuickView> &window, const char window.reset(new QQuickView); window->setSource(testFileUrl(fileName)); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST b/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST index 9bb35c4770a..1c4499753af 100644 --- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST +++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/BLACKLIST @@ -1,3 +1,5 @@ [movingItemWithHoverHandler] macos # Can't move cursor (QTBUG-76312) - +# QTBUG-103065 +[movingItemWithHoverHandler] +android diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquickhoverhandler/CMakeLists.txt index 654bf1c366f..cbfadccb509 100644 --- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/CMakeLists.txt +++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickhoverhandler SOURCES - ../../../shared/util.cpp ../../../shared/util.h - ../../shared/geometrytestutil.cpp ../../shared/geometrytestutil.h - ../../shared/viewtestutil.cpp ../../shared/viewtestutil.h - ../../shared/visualtestutil.cpp ../../shared/visualtestutil.h tst_qquickhoverhandler.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/windowCursorShape.qml b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/windowCursorShape.qml new file mode 100644 index 00000000000..b5c1f3d2efb --- /dev/null +++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/windowCursorShape.qml @@ -0,0 +1,13 @@ +import QtQuick 2.15 +import QtQuick.Window 2.15 + +Window { + width: 320 + height: 240 + visible: true + color: hh.hovered ? "lightsteelblue" : "beige" + HoverHandler { + id: hh + cursorShape: Qt.OpenHandCursor + } +} diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp index f60227a7a99..5d729c04285 100644 --- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp @@ -39,8 +39,8 @@ #include <QtQml/qqmlengine.h> #include <QtQml/qqmlproperty.h> -#include "../../../shared/util.h" -#include "../../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests") @@ -54,14 +54,17 @@ class tst_HoverHandler : public QQmlDataTest Q_OBJECT public: tst_HoverHandler() + : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void hoverHandlerAndUnderlyingHoverHandler(); void mouseAreaAndUnderlyingHoverHandler(); void hoverHandlerAndUnderlyingMouseArea(); + void disabledHoverHandlerAndUnderlyingMouseArea(); void movingItemWithHoverHandler(); void margin(); + void window(); private: void createView(QScopedPointer<QQuickView> &window, const char *fileName); @@ -72,8 +75,8 @@ void tst_HoverHandler::createView(QScopedPointer<QQuickView> &window, const char window.reset(new QQuickView); window->setSource(testFileUrl(fileName)); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); @@ -283,6 +286,52 @@ void tst_HoverHandler::hoverHandlerAndUnderlyingMouseArea() #endif } +void tst_HoverHandler::disabledHoverHandlerAndUnderlyingMouseArea() +{ + // Check that if a disabled HoverHandler is installed on an item, it + // will not participate in hover event delivery, and as such, also + // not block propagation to siblings. + QScopedPointer<QQuickView> windowPtr; + createView(windowPtr, "lesHoverables.qml"); + QQuickView * window = windowPtr.data(); + QQuickItem * bottomSidebar = window->rootObject()->findChild<QQuickItem *>("bottomSidebar"); + QVERIFY(bottomSidebar); + QQuickMouseArea *bottomSidebarMA = bottomSidebar->findChild<QQuickMouseArea *>("bottomSidebarMA"); + QVERIFY(bottomSidebarMA); + QQuickItem * button = bottomSidebar->findChild<QQuickItem *>("buttonWithHH"); + QVERIFY(button); + QQuickHoverHandler *buttonHH = button->findChild<QQuickHoverHandler *>("buttonHH"); + QVERIFY(buttonHH); + + // By disabling the HoverHandler, it should no longer + // block the sibling MouseArea underneath from receiving hover events. + buttonHH->setEnabled(false); + + QPoint buttonCenter(button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint()); + QPoint rightOfButton(button->mapToScene(QPointF(button->width() + 2, button->height() / 2)).toPoint()); + QPoint outOfSidebar(bottomSidebar->mapToScene(QPointF(bottomSidebar->width() + 2, bottomSidebar->height() / 2)).toPoint()); + QSignalSpy sidebarHoveredSpy(bottomSidebarMA, SIGNAL(hoveredChanged())); + QSignalSpy buttonHoveredSpy(buttonHH, SIGNAL(hoveredChanged())); + + QTest::mouseMove(window, outOfSidebar); + QCOMPARE(bottomSidebarMA->hovered(), false); + QCOMPARE(sidebarHoveredSpy.count(), 0); + QCOMPARE(buttonHH->isHovered(), false); + QCOMPARE(buttonHoveredSpy.count(), 0); + + QTest::mouseMove(window, buttonCenter); + QCOMPARE(bottomSidebarMA->hovered(), true); + QCOMPARE(sidebarHoveredSpy.count(), 1); + QCOMPARE(buttonHH->isHovered(), false); + QCOMPARE(buttonHoveredSpy.count(), 0); + + QTest::mouseMove(window, rightOfButton); + QCOMPARE(bottomSidebarMA->hovered(), true); + QCOMPARE(sidebarHoveredSpy.count(), 1); + QCOMPARE(buttonHH->isHovered(), false); + QCOMPARE(buttonHoveredSpy.count(), 0); +} + void tst_HoverHandler::movingItemWithHoverHandler() { if (isPlatformWayland()) @@ -313,7 +362,7 @@ void tst_HoverHandler::movingItemWithHoverHandler() paddle->setX(100); QTRY_COMPARE(paddleHH->isHovered(), false); - paddle->setX(p.x()); + paddle->setX(p.x() - paddle->width() / 2); QTRY_COMPARE(paddleHH->isHovered(), true); paddle->setX(540); @@ -370,6 +419,27 @@ void tst_HoverHandler::margin() // QTBUG-85303 #endif } +void tst_HoverHandler::window() // QTBUG-98717 +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("windowCursorShape.qml")); + QScopedPointer<QQuickWindow> window(qobject_cast<QQuickWindow *>(component.create())); + QVERIFY(!window.isNull()); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); +#if QT_CONFIG(cursor) + if (isPlatformWayland()) + QSKIP("Wayland: QCursor::setPos() doesn't work."); + auto cursorPos = window->mapToGlobal(QPoint(100, 100)); + qCDebug(lcPointerTests) << "in window @" << window->position() << "setting cursor pos" << cursorPos; + QCursor::setPos(cursorPos); + if (!QTest::qWaitFor([cursorPos]{ return QCursor::pos() == cursorPos; })) + QSKIP("QCursor::setPos() doesn't work (QTBUG-76312)."); + QTRY_COMPARE(window->cursor().shape(), Qt::OpenHandCursor); +#endif +} + QTEST_MAIN(tst_HoverHandler) #include "tst_qquickhoverhandler.moc" diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/BLACKLIST b/tests/auto/quick/pointerhandlers/qquickpinchhandler/BLACKLIST new file mode 100644 index 00000000000..701cdae3446 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-103066 +[scaleNativeGesture] +android diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquickpinchhandler/CMakeLists.txt index 09550b143df..777f005f7c8 100644 --- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/CMakeLists.txt +++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickpinchhandler SOURCES - ../../../shared/util.cpp ../../../shared/util.h - ../../shared/geometrytestutil.cpp ../../shared/geometrytestutil.h - ../../shared/viewtestutil.cpp ../../shared/viewtestutil.h - ../../shared/visualtestutil.cpp ../../shared/visualtestutil.h tst_qquickpinchhandler.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/nullTarget.qml b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/nullTarget.qml new file mode 100644 index 00000000000..a348938acad --- /dev/null +++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/nullTarget.qml @@ -0,0 +1,33 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.15 + +Item { + width: 320; height: 320 + property alias pinchScale: pinch.scale + + Rectangle { + objectName: "blackrect" + width: 200; height: 200 + color: "black" + antialiasing: true + scale: pinch.scale + rotation: pinch.rotation + x: pinch.translation.x + y: pinch.translation.y + + PinchHandler { + id: pinch + target: null + minimumScale: 0.5 + maximumScale: 4 + } + + Text { + color: "cyan" + anchors.centerIn: parent + text: "scale " + pinch.scale.toFixed(2) + " activeScale " + pinch.activeScale.toFixed(2) + } + } +} diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchproperties.qml b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchproperties.qml index 3cabde5f591..1e6256cf03f 100644 --- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchproperties.qml +++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/data/pinchproperties.qml @@ -30,11 +30,38 @@ import QtQuick 2.12 Rectangle { id: whiteRect - property real scale: -1.0 + property real pinchScale: -1.0 property int activeCount : 0 property int deactiveCount : 0 width: 320; height: 320 color: "white" + + PointHandler { + id: ph1 + acceptedDevices: PointerDevice.TouchScreen + target: Rectangle { + parent: whiteRect + color: "cyan" + x: ph1.point.position.x - 3 + y: ph1.point.position.y - 3 + width: 6; height: 6; radius: 3 + } + } + + PointHandler { + id: ph2 + acceptedDevices: PointerDevice.TouchScreen + target: Rectangle { + parent: whiteRect + color: "lightgreen" + x: ph2.point.position.x - 3 + y: ph2.point.position.y - 3 + width: 6; height: 6; radius: 3 + } + } + + Text { color: "magenta"; z: 1; text: "scale: " + blackRect.scale} + Rectangle { id: blackRect objectName: "blackrect" @@ -43,8 +70,7 @@ Rectangle { x: 50 width: 100 height: 100 - opacity: (whiteRect.width-blackRect.x+whiteRect.height-blackRect.y-199)/200 - Text { color: "white"; text: "opacity: " + blackRect.opacity + "\nscale: " + blackRect.scale} + Rectangle { color: "red" width: 6; height: 6; radius: 3 @@ -56,20 +82,20 @@ Rectangle { PinchHandler { id: pincharea objectName: "pinchHandler" - minimumScale: 1.0 + minimumScale: 0.5 maximumScale: 4.0 minimumRotation: 0.0 maximumRotation: 90.0 xAxis.maximum: 140 yAxis.maximum: 170 onActiveChanged: { - whiteRect.scale = pincharea.scale + whiteRect.pinchScale = pincharea.scale if (active) ++activeCount else ++deactiveCount; } onUpdated: { - whiteRect.scale = pincharea.scale + whiteRect.pinchScale = pincharea.scale //whiteRect.pointCount = pincharea.pointCount } } diff --git a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp index 6cf62142861..7da37826b48 100644 --- a/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickpinchhandler/tst_qquickpinchhandler.cpp @@ -29,14 +29,14 @@ #include <QtTest/QtTest> #include <QtTest/QSignalSpy> #include <QtGui/QStyleHints> -#include <QtGui/private/qevent_p.h> +#include <QtGui/private/qeventpoint_p.h> #include <qpa/qwindowsysteminterface.h> #include <QtQuick/private/qquickpinchhandler_p.h> #include <QtQuick/private/qquickrectangle_p.h> #include <QtQuick/qquickview.h> #include <QtQml/qqmlcontext.h> -#include "../../../shared/util.h" -#include "../../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests") @@ -50,10 +50,11 @@ class tst_QQuickPinchHandler: public QQmlDataTest { Q_OBJECT public: - tst_QQuickPinchHandler() { } + tst_QQuickPinchHandler() : QQmlDataTest(QT_QMLTEST_DATADIR) { } private slots: void cleanupTestCase(); void pinchProperties(); + void scale_data(); void scale(); void scaleThreeFingers(); void scaleNativeGesture_data(); @@ -67,7 +68,6 @@ private slots: void transformedpinchHandler(); private: - QQuickView *createView(); QPointingDevice *touchscreen = QTest::createTouchDevice(); QPointingDevice *touchpad = QTest::createTouchDevice(QInputDevice::DeviceType::TouchPad); }; @@ -84,7 +84,7 @@ static bool withinBounds(qreal lower, qreal num, qreal upper) void tst_QQuickPinchHandler::pinchProperties() { - QScopedPointer<QQuickView> window(createView()); + QScopedPointer<QQuickView> window(QQuickViewTestUtils::createView()); window->setSource(testFileUrl("pinchproperties.qml")); window->show(); QVERIFY(window->rootObject() != nullptr); @@ -155,19 +155,19 @@ void tst_QQuickPinchHandler::pinchProperties() QSignalSpy scaleMinSpy(pinchHandler, SIGNAL(minimumScaleChanged())); QSignalSpy scaleMaxSpy(pinchHandler, SIGNAL(maximumScaleChanged())); - QCOMPARE(pinchHandler->minimumScale(), 1.0); + QCOMPARE(pinchHandler->minimumScale(), 0.5); QCOMPARE(pinchHandler->maximumScale(), 4.0); - pinchHandler->setMinimumScale(0.5); + pinchHandler->setMinimumScale(0.25); pinchHandler->setMaximumScale(1.5); - QCOMPARE(pinchHandler->minimumScale(), 0.5); + QCOMPARE(pinchHandler->minimumScale(), 0.25); QCOMPARE(pinchHandler->maximumScale(), 1.5); QCOMPARE(scaleMinSpy.count(),1); QCOMPARE(scaleMaxSpy.count(),1); - pinchHandler->setMinimumScale(0.5); + pinchHandler->setMinimumScale(0.25); pinchHandler->setMaximumScale(1.5); QCOMPARE(scaleMinSpy.count(),1); @@ -205,97 +205,126 @@ QMutableEventPoint makeTouchPoint(int id, QPoint p, QQuickView *v, QQuickItem *i return touchPoint; } -void tst_QQuickPinchHandler::scale() +void tst_QQuickPinchHandler::scale_data() { - QQuickView *window = createView(); - QScopedPointer<QQuickView> scope(window); - window->setSource(testFileUrl("pinchproperties.qml")); - window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window)); - QVERIFY(window->rootObject() != nullptr); - qApp->processEvents(); + QTest::addColumn<QUrl>("qmlfile"); + QTest::addColumn<bool>("hasTarget"); + QTest::newRow("targetModifying") << testFileUrl("pinchproperties.qml") << true; + QTest::newRow("nullTarget") << testFileUrl("nullTarget.qml") << false; +} - auto *pinchHandler = static_cast<PinchHandler *>(window->rootObject()->findChild<QQuickPinchHandler*>("pinchHandler")); - QVERIFY(pinchHandler != nullptr); - QSignalSpy grabChangedSpy(pinchHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition, QEventPoint))); +void tst_QQuickPinchHandler::scale() +{ + QFETCH(QUrl, qmlfile); + QFETCH(bool, hasTarget); - QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject()); + QQuickView window; + QVERIFY(QQuickTest::showView(window, qmlfile)); + QQuickItem *root = qobject_cast<QQuickItem*>(window.rootObject()); QVERIFY(root != nullptr); - - // target - QQuickItem *blackRect = window->rootObject()->findChild<QQuickItem*>("blackrect"); + auto *pinchHandler = static_cast<PinchHandler *>(root->findChild<QQuickPinchHandler*>()); + QVERIFY(pinchHandler != nullptr); + QQuickItem *blackRect = (hasTarget ? pinchHandler->target() : pinchHandler->parentItem()); QVERIFY(blackRect != nullptr); + QSignalSpy grabChangedSpy(pinchHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition, QEventPoint))); QPoint p0(80, 80); QPoint p1(100, 100); - { - QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen); - pinchSequence.press(0, p0, window).commit(); - QQuickTouchUtils::flush(window); - // In order for the stationary point to remember its previous position, - // we have to reuse the same pinchSequence object. Otherwise if we let it - // be destroyed and then start a new sequence, point 0 will default to being - // stationary at 0, 0, and pinchHandler will filter out that touchpoint because - // it is outside its bounds. - pinchSequence.stationary(0).press(1, p1, window).commit(); - QQuickTouchUtils::flush(window); - QTRY_COMPARE(grabChangedSpy.count(), 1); // passive grab - - QPoint pd(10, 10); - // move one point until PinchHandler activates - for (int pi = 0; pi < 10 && !pinchHandler->active(); ++pi) { - p1 += pd; - pinchSequence.stationary(0).move(1, p1, window).commit(); - QQuickTouchUtils::flush(window); - } - QCOMPARE(pinchHandler->active(), true); - // grabs occur when the handler becomes active; at that time, QQuickHandlerPoint.sceneGrabPosition should be correct - QVERIFY(pinchHandler->firstPoint().sceneGrabPosition() != QPointF()); - QVERIFY(pinchHandler->lastPoint().sceneGrabPosition() != QPointF()); - QCOMPARE(pinchHandler->firstPoint().sceneGrabPosition(), pinchHandler->firstPoint().scenePosition()); - QCOMPARE(pinchHandler->lastPoint().sceneGrabPosition(), pinchHandler->lastPoint().scenePosition()); - // first point got a passive grab; both points got exclusive grabs - QCOMPARE(grabChangedSpy.count(), 3); - QLineF line(p0, p1); - const qreal startLength = line.length(); - - p1+=pd; - pinchSequence.stationary(0).move(1, p1, window).commit(); - QQuickTouchUtils::flush(window); - line.setP2(p1); - qreal scale = line.length() / startLength; - QVERIFY(qFloatDistance(root->property("scale").toReal(), scale) < 10); - QVERIFY(qFloatDistance(blackRect->scale(), scale) < 10); - - p1+=pd; - pinchSequence.stationary(0).move(1, p1, window).commit(); - QQuickTouchUtils::flush(window); + QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(&window, touchscreen); + pinchSequence.press(0, p0, &window).commit(); + QQuickTouchUtils::flush(&window); + // In order for the stationary point to remember its previous position, + // we have to reuse the same pinchSequence object. Otherwise if we let it + // be destroyed and then start a new sequence, point 0 will default to being + // stationary at 0, 0, and pinchHandler will filter out that touchpoint because + // it is outside its bounds. + pinchSequence.stationary(0).press(1, p1, &window).commit(); + QQuickTouchUtils::flush(&window); + QCOMPARE(grabChangedSpy.size(), 1); // passive grab + + QPoint pd(10, 10); + // move one point until PinchHandler activates + for (int pi = 0; pi < 10 && !pinchHandler->active(); ++pi) { + p1 += pd; + pinchSequence.stationary(0).move(1, p1, &window).commit(); + QQuickTouchUtils::flush(&window); + } + QCOMPARE(pinchHandler->active(), true); + // grabs occur when the handler becomes active; at that time, QQuickHandlerPoint.sceneGrabPosition should be correct + QVERIFY(pinchHandler->firstPoint().sceneGrabPosition() != QPointF()); + QVERIFY(pinchHandler->lastPoint().sceneGrabPosition() != QPointF()); + QCOMPARE(pinchHandler->firstPoint().sceneGrabPosition(), pinchHandler->firstPoint().scenePosition()); + QCOMPARE(pinchHandler->lastPoint().sceneGrabPosition(), pinchHandler->lastPoint().scenePosition()); + // first point got a passive grab; both points got exclusive grabs + QCOMPARE(grabChangedSpy.size(), 3); + QLineF line(p0, p1); + const qreal startLength = line.length(); + + // move the same point even further and observe the change in scale + for (int i = 0; i < 2; ++i) { + p1 += pd; + pinchSequence.stationary(0).move(1, p1, &window).commit(); + QQuickTouchUtils::flush(&window); + if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); line.setP2(p1); - scale = line.length() / startLength; - - QVERIFY(qFloatDistance(root->property("scale").toReal(), scale) < 10); - QVERIFY(qFloatDistance(blackRect->scale(), scale) < 10); - - QPointF expectedCentroid = p0 + (p1 - p0)/2; + qreal expectedScale = line.length() / startLength; + QVERIFY(qFloatDistance(root->property("pinchScale").toReal(), expectedScale) < 10); + QVERIFY(qFloatDistance(blackRect->scale(), expectedScale) < 10); + QCOMPARE(pinchHandler->scale(), root->property("pinchScale").toReal()); + QCOMPARE(pinchHandler->scale(), pinchHandler->activeScale()); // in sync for the first gesture + QPointF expectedCentroid = p0 + (p1 - p0) / 2; QCOMPARE(pinchHandler->centroid().scenePosition(), expectedCentroid); } - // scale beyond bound - p1 += QPoint(20, 20); - { - QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, touchscreen); - pinchSequence.stationary(0).move(1, p1, window).commit(); - QQuickTouchUtils::flush(window); - QCOMPARE(blackRect->scale(), qreal(4)); // qquickpinchhandler does not manipulate scale property - pinchSequence.release(0, p0, window).release(1, p1, window).commit(); - QQuickTouchUtils::flush(window); + qreal lastScale = pinchHandler->scale(); + pinchSequence.release(0, p0, &window).release(1, p1, &window).commit(); + QQuickTouchUtils::flush(&window); + if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); + // scale property is persistent after release + QCOMPARE(pinchHandler->scale(), lastScale); + + // pinch a second time: scale picks up where we left off + p0 = QPoint(80, 80); + p1 = QPoint(100, 100); + pinchSequence.press(0, p0, &window).press(1, p1, &window).commit(); + // move one point until PinchHandler activates + for (int pi = 0; pi < 10 && !pinchHandler->active(); ++pi) { + p1 += pd; + pinchSequence.stationary(0).move(1, p1, &window).commit(); + QQuickTouchUtils::flush(&window); + } + if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); + QCOMPARE(pinchHandler->active(), true); + QCOMPARE(pinchHandler->scale(), lastScale); // just activated, not scaling further yet + for (int i = 0; i < 2; ++i) { + lastScale = pinchHandler->scale(); + p1 += pd; + pinchSequence.stationary(0).move(1, p1, &window).commit(); + QQuickTouchUtils::flush(&window); + if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); + QVERIFY(pinchHandler->scale() > lastScale); + line.setP2(p1); + qreal expectedActiveScale = line.length() / startLength; + QVERIFY(qFloatDistance(pinchHandler->activeScale(), expectedActiveScale) < 10); + QCOMPARE(pinchHandler->scale(), root->property("pinchScale").toReal()); + QVERIFY(pinchHandler->scale() != pinchHandler->activeScale()); // not in sync anymore } + + // scale beyond maximumScale + p1 = QPoint(310, 310); + pinchSequence.stationary(0).move(1, p1, &window).commit(); + QQuickTouchUtils::flush(&window); + if (lcPointerTests().isDebugEnabled()) QTest::qWait(500); + QCOMPARE(blackRect->scale(), qreal(4)); + QCOMPARE(pinchHandler->scale(), qreal(4)); // limited by maximumScale + pinchSequence.release(0, p0, &window).release(1, p1, &window).commit(); + QQuickTouchUtils::flush(&window); QCOMPARE(pinchHandler->active(), false); } void tst_QQuickPinchHandler::scaleThreeFingers() { - QQuickView *window = createView(); + QQuickView *window = QQuickViewTestUtils::createView(); QScopedPointer<QQuickView> scope(window); window->setSource(testFileUrl("threeFingers.qml")); window->show(); @@ -374,16 +403,20 @@ void tst_QQuickPinchHandler::scaleThreeFingers() void tst_QQuickPinchHandler::scaleNativeGesture_data() { QTest::addColumn<QString>("qmlfile"); + QTest::addColumn<qreal>("scale"); - QTest::newRow("just pinch") << "pinchproperties.qml"; - QTest::newRow("pinch & drag") << "pinchAndDrag.qml"; + QTest::newRow("just pinch") << "pinchproperties.qml" << 1.1; + QTest::newRow("pinch & drag") << "pinchAndDrag.qml" << 1.1; + QTest::newRow("bigger than limit") << "pinchproperties.qml" << 5.0; + QTest::newRow("smaller than limit") << "pinchproperties.qml" << 0.25; } void tst_QQuickPinchHandler::scaleNativeGesture() { QFETCH(QString, qmlfile); + QFETCH(qreal, scale); - QQuickView *window = createView(); + QQuickView *window = QQuickViewTestUtils::createView(); QScopedPointer<QQuickView> scope(window); window->setSource(testFileUrl(qmlfile)); window->show(); @@ -401,8 +434,8 @@ void tst_QQuickPinchHandler::scaleNativeGesture() QPointF targetPos = target->position(); ulong ts = 1; - // first pinch: scale it up - const qreal expectedScale = 1.1; + // first pinch: scale it + const qreal expectedScale = qBound(qreal(0.5), scale, qreal(4)); QPointF pinchPos(75, 75); QPointF pinchLocalPos = target->mapFromScene(pinchPos); // target position is adjusted in QQuickItemPrivate::adjustedPosForTransform() @@ -412,11 +445,11 @@ void tst_QQuickPinchHandler::scaleNativeGesture() QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad, Qt::BeginNativeGesture, pinchPos, pinchPos); QWindowSystemInterface::handleGestureEventWithRealValue(window, ts++, touchpad, - Qt::ZoomNativeGesture, expectedScale - 1, pinchPos, pinchPos); + Qt::ZoomNativeGesture, scale - 1, pinchPos, pinchPos); QTRY_COMPARE(target->scale(), expectedScale); QCOMPARE(pinchHandler->active(), true); - QCOMPARE(pinchHandler->centroid().position(), pinchLocalPos); - QCOMPARE(pinchHandler->centroid().scenePosition(), pinchPos); + QCOMPARE(pinchHandler->centroid().position().toPoint(), pinchLocalPos.toPoint()); + QCOMPARE(pinchHandler->centroid().scenePosition().toPoint(), pinchPos.toPoint()); QVERIFY(qAbs(target->position().x() - expectedPos.x()) < 0.001); QVERIFY(qAbs(target->position().y() - expectedPos.y()) < 0.001); QCOMPARE(pinchHandler->scale(), expectedScale); @@ -432,9 +465,12 @@ void tst_QQuickPinchHandler::scaleNativeGesture() QCOMPARE(pinchHandler->translation(), QVector2D()); QCOMPARE(pinchHandler->rotation(), 0); - // second pinch at a different position: scale it down to original size again + // second pinch at a different position: scale it back to original size again + // but remove the limits first, so that we can scale arbitrarily + pinchHandler->setMaximumScale(qInf()); + pinchHandler->setMinimumScale(-qInf()); const qreal reverseScale = (1 / expectedScale); - pinchPos = QPointF(125, 125); + pinchPos = QPointF(110, 110); pinchLocalPos = target->mapFromScene(pinchPos); QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad, Qt::BeginNativeGesture, pinchPos, pinchPos); @@ -442,8 +478,8 @@ void tst_QQuickPinchHandler::scaleNativeGesture() Qt::ZoomNativeGesture, reverseScale - 1, pinchPos, pinchPos); QTRY_COMPARE(target->scale(), 1); QCOMPARE(pinchHandler->active(), true); - QCOMPARE(pinchHandler->centroid().position(), pinchLocalPos); - QCOMPARE(pinchHandler->centroid().scenePosition(), pinchPos); + QCOMPARE(pinchHandler->centroid().position().toPoint(), pinchLocalPos.toPoint()); + QCOMPARE(pinchHandler->centroid().scenePosition().toPoint(), pinchPos.toPoint()); QCOMPARE(pinchHandler->scale(), 1); QCOMPARE(pinchHandler->activeScale(), reverseScale); QWindowSystemInterface::handleGestureEvent(window, ts++, touchpad, @@ -456,7 +492,7 @@ void tst_QQuickPinchHandler::scaleNativeGesture() void tst_QQuickPinchHandler::pan() { - QQuickView *window = createView(); + QQuickView *window = QQuickViewTestUtils::createView(); QScopedPointer<QQuickView> scope(window); window->setSource(testFileUrl("pinchproperties.qml")); window->show(); @@ -486,7 +522,7 @@ void tst_QQuickPinchHandler::pan() pinchSequence.stationary(0).press(1, p1, window).commit(); QQuickTouchUtils::flush(window); QVERIFY(!root->property("pinchActive").toBool()); - QCOMPARE(root->property("scale").toReal(), -1.0); + QCOMPARE(root->property("pinchScale").toReal(), -1.0); p0 += QPoint(dragThreshold, 0); p1 += QPoint(dragThreshold, 0); @@ -494,7 +530,7 @@ void tst_QQuickPinchHandler::pan() QQuickTouchUtils::flush(window); // movement < dragThreshold: pinchHandler not yet active QVERIFY(!root->property("pinchActive").toBool()); - QCOMPARE(root->property("scale").toReal(), -1.0); + QCOMPARE(root->property("pinchScale").toReal(), -1.0); // just above the dragThreshold: pinchHandler starts p0 += QPoint(1, 0); @@ -502,7 +538,7 @@ void tst_QQuickPinchHandler::pan() pinchSequence.move(0, p0, window).move(1, p1, window).commit(); QQuickTouchUtils::flush(window); QCOMPARE(pinchHandler->active(), true); - QCOMPARE(root->property("scale").toReal(), 1.0); + QCOMPARE(root->property("pinchScale").toReal(), 1.0); // Calculation of the center point is tricky at first: // center point of the two touch points in item coordinates: @@ -568,7 +604,7 @@ void tst_QQuickPinchHandler::dragAxesEnabled_data() void tst_QQuickPinchHandler::dragAxesEnabled() { - QQuickView *window = createView(); + QQuickView *window = QQuickViewTestUtils::createView(); QScopedPointer<QQuickView> scope(window); window->setSource(testFileUrl("pinchproperties.qml")); window->show(); @@ -635,7 +671,7 @@ void tst_QQuickPinchHandler::dragAxesEnabled() void tst_QQuickPinchHandler::retouch() { const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); - QQuickView *window = createView(); + QQuickView *window = QQuickViewTestUtils::createView(); QScopedPointer<QQuickView> scope(window); window->setSource(testFileUrl("pinchproperties.qml")); window->show(); @@ -669,7 +705,7 @@ void tst_QQuickPinchHandler::retouch() pinchSequence.move(0, p0,window).move(1, p1,window).commit(); QQuickTouchUtils::flush(window); - QCOMPARE(root->property("scale").toReal(), 1.0); + QCOMPARE(root->property("pinchScale").toReal(), 1.0); QCOMPARE(pinchHandler->active(), true); p0 -= delta; @@ -680,8 +716,8 @@ void tst_QQuickPinchHandler::retouch() QCOMPARE(pinchHandler->active(), true); // accept some slack - QVERIFY(withinBounds(1.4, root->property("scale").toReal(), 1.6)); - QCOMPARE(pinchHandler->centroid().position(), QPointF(40, 40)); // blackrect is at 50,50 + QVERIFY(withinBounds(1.4, root->property("pinchScale").toReal(), 1.6)); + QCOMPARE(pinchHandler->centroid().position().toPoint(), QPoint(40, 40)); // blackrect is at 50,50 QVERIFY(withinBounds(1.4, blackRect->scale(), 1.6)); QCOMPARE(root->property("activeCount").toInt(), 1); @@ -718,7 +754,7 @@ void tst_QQuickPinchHandler::retouch() void tst_QQuickPinchHandler::cancel() { const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); - QQuickView *window = createView(); + QQuickView *window = QQuickViewTestUtils::createView(); QScopedPointer<QQuickView> scope(window); window->setSource(testFileUrl("pinchproperties.qml")); window->show(); @@ -755,7 +791,7 @@ void tst_QQuickPinchHandler::cancel() pinchSequence.move(0, p0,window).move(1, p1,window).commit(); QQuickTouchUtils::flush(window); - QCOMPARE(root->property("scale").toReal(), 1.0); + QCOMPARE(root->property("pinchScale").toReal(), 1.0); QCOMPARE(pinchHandler->active(), true); p0 -= delta; @@ -763,8 +799,8 @@ void tst_QQuickPinchHandler::cancel() pinchSequence.move(0, p0,window).move(1, p1,window).commit(); QQuickTouchUtils::flush(window); - QVERIFY(withinBounds(1.4, root->property("scale").toReal(), 1.6)); - QCOMPARE(pinchHandler->centroid().position(), QPointF(40, 40)); // blackrect is at 50,50 + QVERIFY(withinBounds(1.4, root->property("pinchScale").toReal(), 1.6)); + QCOMPARE(pinchHandler->centroid().position().toPoint(), QPoint(40, 40)); // blackrect is at 50,50 QVERIFY(withinBounds(1.4, blackRect->scale(), 1.6)); QSKIP("cancel is not supported atm"); @@ -773,8 +809,8 @@ void tst_QQuickPinchHandler::cancel() QCoreApplication::sendEvent(window, &cancelEvent); QQuickTouchUtils::flush(window); - QCOMPARE(root->property("scale").toReal(), 1.0); - QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50 + QCOMPARE(root->property("pinchScale").toReal(), 1.0); + QCOMPARE(root->property("center").toPoint(), QPoint(40, 40)); // blackrect is at 50,50 QCOMPARE(blackRect->scale(), 1.0); QVERIFY(!root->property("pinchActive").toBool()); } @@ -811,7 +847,7 @@ void tst_QQuickPinchHandler::transformedpinchHandler() QFETCH(QPoint, p1); QFETCH(bool, shouldPinch); - QQuickView *view = createView(); + QQuickView *view = QQuickViewTestUtils::createView(); QScopedPointer<QQuickView> scope(view); view->setSource(testFileUrl("transformedPinchHandler.qml")); view->show(); @@ -850,14 +886,6 @@ void tst_QQuickPinchHandler::transformedpinchHandler() } } -QQuickView *tst_QQuickPinchHandler::createView() -{ - QQuickView *window = new QQuickView(0); - window->setGeometry(0,0,240,320); - - return window; -} - QTEST_MAIN(tst_QQuickPinchHandler) #include "tst_qquickpinchhandler.moc" diff --git a/tests/auto/quick/pointerhandlers/qquickpointerhandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquickpointerhandler/CMakeLists.txt index 9dc541a8452..dc4f6bac030 100644 --- a/tests/auto/quick/pointerhandlers/qquickpointerhandler/CMakeLists.txt +++ b/tests/auto/quick/pointerhandlers/qquickpointerhandler/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickpointerhandler SOURCES - ../../../shared/util.cpp ../../../shared/util.h - ../../shared/geometrytestutil.cpp ../../shared/geometrytestutil.h - ../../shared/viewtestutil.cpp ../../shared/viewtestutil.h - ../../shared/visualtestutil.cpp ../../shared/visualtestutil.h tst_qquickpointerhandler.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/pointerhandlers/qquickpointerhandler/data/clip.qml b/tests/auto/quick/pointerhandlers/qquickpointerhandler/data/clip.qml new file mode 100644 index 00000000000..7bc3907c8c2 --- /dev/null +++ b/tests/auto/quick/pointerhandlers/qquickpointerhandler/data/clip.qml @@ -0,0 +1,36 @@ +import QtQuick +import Qt.test 1.0 + +Item { + width: 200 + height: 200 + + Rectangle { + id: circle + y: 0 + width: 100 + height: width + radius: width/2 + color: "#3e1" + clip: true + + // Rectangle contains() is not affected by its 'radius' property + containmentMask: QtObject { + property alias radius: circle.radius + function contains(point: point) : bool { + return (Math.pow(point.x - radius, 2) + Math.pow(point.y - radius, 2)) < Math.pow(radius, 2) + } + } + EventHandler { + objectName: "circle eventHandler" + } + Rectangle { + width: circle.width/2 + height: width + color: "red" + EventHandler { + objectName: "eventHandler" + } + } + } +} diff --git a/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp index 9bbf7a38b71..51c94ea8c8b 100644 --- a/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp @@ -35,8 +35,8 @@ #include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> -#include "../../../shared/util.h" -#include "../../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests") @@ -236,7 +236,8 @@ class tst_PointerHandlers : public QQmlDataTest Q_OBJECT public: tst_PointerHandlers() - : touchDevice(QTest::createTouchDevice()) + : QQmlDataTest(QT_QMLTEST_DATADIR) + , touchDevice(QTest::createTouchDevice()) {} private slots: @@ -251,6 +252,7 @@ private slots: void handlerInWindow(); void dynamicCreationInWindow(); void cppConstruction(); + void clip(); protected: bool eventFilter(QObject *, QEvent *event) override @@ -288,8 +290,8 @@ void tst_PointerHandlers::createView(QScopedPointer<QQuickView> &window, const c // window->setGeometry(0,0,240,320); window->setSource(testFileUrl(fileName)); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); @@ -339,11 +341,11 @@ void tst_PointerHandlers::touchEventDelivery() QTest::touchEvent(window, touchDevice).move(0, p1, window); QQuickTouchUtils::flush(window); qCDebug(lcPointerTests) << "events after touch move" << eventItem1->eventList; - QCOMPARE(eventItem1->eventList.size(), 2); // no grabs -> no updates + QCOMPARE(eventItem1->eventList.size(), 3); // no grabs -> only the handler gets the update QTest::touchEvent(window, touchDevice).release(0, p1, window); QQuickTouchUtils::flush(window); qCDebug(lcPointerTests) << "events after touch release" << eventItem1->eventList; - QCOMPARE(eventItem1->eventList.size(), 3); + QCOMPARE(eventItem1->eventList.size(), 4); QCOMPARE_EVENT(eventItem1->eventList.size() - 1, Event::HandlerDestination, QEvent::Pointer, QEventPoint::State::Released, NoGrab); eventItem1->eventList.clear(); @@ -394,12 +396,12 @@ void tst_PointerHandlers::touchEventDelivery() QTest::touchEvent(window, touchDevice).move(0, p1, window); QQuickTouchUtils::flush(window); qCDebug(lcPointerTests) << "events after touch move" << eventItem1->eventList; - QCOMPARE(eventItem1->eventList.size(), 2); + QCOMPARE(eventItem1->eventList.size(), 3); QTest::touchEvent(window, touchDevice).release(0, p1, window); QQuickTouchUtils::flush(window); qCDebug(lcPointerTests) << "events after touch release" << eventItem1->eventList; - QCOMPARE(eventItem1->eventList.size(), 3); - QCOMPARE_EVENT(2, Event::HandlerDestination, QEvent::Pointer, QEventPoint::State::Released, NoGrab); + QCOMPARE(eventItem1->eventList.size(), 4); + QCOMPARE_EVENT(3, Event::HandlerDestination, QEvent::Pointer, QEventPoint::State::Released, NoGrab); eventItem1->eventList.clear(); // wait to avoid getting a double click event @@ -421,11 +423,11 @@ void tst_PointerHandlers::touchEventDelivery() QTest::touchEvent(window, touchDevice).move(0, p1, window); QQuickTouchUtils::flush(window); qCDebug(lcPointerTests) << "events after touch move" << eventItem1->eventList; - QCOMPARE(eventItem1->eventList.size(), 2); + QCOMPARE(eventItem1->eventList.size(), 3); QTest::touchEvent(window, touchDevice).release(0, p1, window); QQuickTouchUtils::flush(window); qCDebug(lcPointerTests) << "events after touch release" << eventItem1->eventList; - QCOMPARE(eventItem1->eventList.size(), 3); + QCOMPARE(eventItem1->eventList.size(), 4); eventItem1->eventList.clear(); // wait to avoid getting a double click event @@ -499,14 +501,14 @@ void tst_PointerHandlers::mouseEventDelivery() QPoint p1 = QPoint(20, 20); QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1); qCDebug(lcPointerTests) << "events after mouse press" << eventItem1->eventList; - QCOMPARE(eventItem1->eventList.size(), 2); + QCOMPARE(eventItem1->eventList.size(), 3); // handler: hover; handler: press; item: press p1 += QPoint(10, 0); QTest::mouseMove(window, p1); qCDebug(lcPointerTests) << "events after mouse move" << eventItem1->eventList; - QCOMPARE(eventItem1->eventList.size(), 2); + QCOMPARE(eventItem1->eventList.size(), 4); // handler: hover QTest::mouseRelease(window, Qt::LeftButton); qCDebug(lcPointerTests) << "events after mouse release" << eventItem1->eventList; - QCOMPARE(eventItem1->eventList.size(), 2); + QCOMPARE(eventItem1->eventList.size(), 4); eventItem1->eventList.clear(); // wait to avoid getting a double click event @@ -519,9 +521,9 @@ void tst_PointerHandlers::mouseEventDelivery() p1 = QPoint(20, 20); QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1); qCDebug(lcPointerTests) << "events after mouse press" << eventItem1->eventList; - QCOMPARE(eventItem1->eventList.size(), 2); - QCOMPARE_EVENT(0, Event::HandlerDestination, QEvent::Pointer, QEventPoint::State::Pressed, NoGrab); - QCOMPARE_EVENT(1, Event::MouseDestination, QEvent::MouseButtonPress, QEventPoint::State::Pressed, QPointingDevice::GrabExclusive); + QCOMPARE(eventItem1->eventList.size(), 3); + QCOMPARE_EVENT(1, Event::HandlerDestination, QEvent::Pointer, QEventPoint::State::Pressed, NoGrab); + QCOMPARE_EVENT(2, Event::MouseDestination, QEvent::MouseButtonPress, QEventPoint::State::Pressed, QPointingDevice::GrabExclusive); QCOMPARE(window->mouseGrabberItem(), eventItem1); QPointF localPos = eventItem1->mapFromScene(p1); @@ -534,11 +536,11 @@ void tst_PointerHandlers::mouseEventDelivery() p1 += QPoint(10, 0); QTest::mouseMove(window, p1); qCDebug(lcPointerTests) << "events after mouse move" << eventItem1->eventList; - QCOMPARE(eventItem1->eventList.size(), 4); - QCOMPARE_EVENT(3, Event::MouseDestination, QEvent::MouseMove, QEventPoint::State::Updated, QPointingDevice::GrabExclusive); + QCOMPARE(eventItem1->eventList.size(), 5); + QCOMPARE_EVENT(4, Event::MouseDestination, QEvent::MouseMove, QEventPoint::State::Updated, QPointingDevice::GrabExclusive); QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1); qCDebug(lcPointerTests) << "events after mouse release" << eventItem1->eventList; - QCOMPARE(eventItem1->eventList.size(), 7); + QCOMPARE(eventItem1->eventList.size(), 8); QCOMPARE_EVENT(eventItem1->eventList.size() - 2, Event::MouseDestination, QEvent::MouseButtonRelease, QEventPoint::State::Released, NoGrab); QCOMPARE_EVENT(eventItem1->eventList.size() - 1, Event::MouseDestination, QEvent::UngrabMouse, QEventPoint::State::Released, QPointingDevice::UngrabExclusive); eventItem1->eventList.clear(); @@ -645,9 +647,10 @@ void tst_PointerHandlers::dynamicCreation() QPoint p1(20, 20); QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1); - QTRY_COMPARE(eventItem1->eventList.size(), 2); - QCOMPARE_EVENT(0, Event::HandlerDestination, QEvent::Pointer, QEventPoint::State::Pressed, NoGrab); - QCOMPARE_EVENT(1, Event::MouseDestination, QEvent::MouseButtonPress, QEventPoint::State::Pressed, NoGrab); + QTRY_COMPARE(eventItem1->eventList.size(), 3); + QCOMPARE_EVENT(0, Event::HandlerDestination, QEvent::Pointer, QEventPoint::State::Updated, NoGrab); + QCOMPARE_EVENT(1, Event::HandlerDestination, QEvent::Pointer, QEventPoint::State::Pressed, NoGrab); + QCOMPARE_EVENT(2, Event::MouseDestination, QEvent::MouseButtonPress, QEventPoint::State::Pressed, NoGrab); QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1); } @@ -732,6 +735,63 @@ void tst_PointerHandlers::cppConstruction() QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10); } +void tst_PointerHandlers::clip() +{ + QScopedPointer<QQuickView> windowPtr; + createView(windowPtr, "clip.qml"); + QQuickView * window = windowPtr.data(); + QVERIFY(window); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + EventHandler *handler = window->contentItem()->findChild<EventHandler*>("eventHandler"); + EventHandler *circleHandler = window->contentItem()->findChild<EventHandler*>("circle eventHandler"); + + QCOMPARE(handler->pressEventCount, 0); + QCOMPARE(circleHandler->pressEventCount, 0); + QCOMPARE(handler->releaseEventCount, 0); + QCOMPARE(circleHandler->releaseEventCount, 0); + + const QPoint rectPt = QPoint(1, 1); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, rectPt); + QCOMPARE(handler->pressEventCount, 1); + QCOMPARE(circleHandler->pressEventCount, 0); + + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, rectPt); + QCOMPARE(handler->releaseEventCount, 1); + QCOMPARE(circleHandler->releaseEventCount, 0); + + + handler->pressEventCount = 0; + circleHandler->pressEventCount = 0; + handler->releaseEventCount = 0; + circleHandler->releaseEventCount = 0; + + const QPoint rectAndCirclePt = QPoint(49 ,49); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, rectAndCirclePt); + QCOMPARE(handler->pressEventCount, 1); + QCOMPARE(circleHandler->pressEventCount, 1); + + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, rectAndCirclePt); + QCOMPARE(handler->releaseEventCount, 1); + QCOMPARE(circleHandler->releaseEventCount, 1); + + + handler->pressEventCount = 0; + circleHandler->pressEventCount = 0; + handler->releaseEventCount = 0; + circleHandler->releaseEventCount = 0; + + const QPoint circlePt = QPoint(51 ,51); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, circlePt); + QCOMPARE(handler->pressEventCount, 0); + QCOMPARE(circleHandler->pressEventCount, 1); + + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, circlePt); + QCOMPARE(handler->releaseEventCount, 0); + QCOMPARE(circleHandler->releaseEventCount, 1); +} + QTEST_MAIN(tst_PointerHandlers) #include "tst_qquickpointerhandler.moc" diff --git a/tests/auto/quick/pointerhandlers/qquickpointhandler/BLACKLIST b/tests/auto/quick/pointerhandlers/qquickpointhandler/BLACKLIST index f4d271c2308..5d6a59e1ddc 100644 --- a/tests/auto/quick/pointerhandlers/qquickpointhandler/BLACKLIST +++ b/tests/auto/quick/pointerhandlers/qquickpointhandler/BLACKLIST @@ -1,2 +1,4 @@ [tabletStylus] macos ci +qnx +android # QTBUG-103068 diff --git a/tests/auto/quick/pointerhandlers/qquickpointhandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquickpointhandler/CMakeLists.txt index 507bc7549b3..e3499f46b04 100644 --- a/tests/auto/quick/pointerhandlers/qquickpointhandler/CMakeLists.txt +++ b/tests/auto/quick/pointerhandlers/qquickpointhandler/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickpointhandler SOURCES - ../../../shared/util.cpp ../../../shared/util.h - ../../shared/geometrytestutil.cpp ../../shared/geometrytestutil.h - ../../shared/viewtestutil.cpp ../../shared/viewtestutil.h - ../../shared/visualtestutil.cpp ../../shared/visualtestutil.h tst_qquickpointhandler.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp index a511c906f8e..d22b3d86aa8 100644 --- a/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp @@ -39,8 +39,9 @@ #include <QtQml/qqmlengine.h> #include <QtQml/qqmlproperty.h> -#include "../../../shared/util.h" -#include "../../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests") @@ -49,7 +50,8 @@ class tst_PointHandler : public QQmlDataTest Q_OBJECT public: tst_PointHandler() - : touchDevice(QTest::createTouchDevice()) + : QQmlDataTest(QT_QMLTEST_DATADIR) + , touchDevice(QTest::createTouchDevice()) {} private slots: @@ -71,8 +73,8 @@ void tst_PointHandler::createView(QScopedPointer<QQuickView> &window, const char window.reset(new QQuickView); window->setSource(testFileUrl(fileName)); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::centerOnScreen(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquicktaphandler/CMakeLists.txt index babe276519c..cc20b8998d5 100644 --- a/tests/auto/quick/pointerhandlers/qquicktaphandler/CMakeLists.txt +++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquicktaphandler SOURCES - ../../../shared/util.cpp ../../../shared/util.h - ../../shared/geometrytestutil.cpp ../../shared/geometrytestutil.h - ../../shared/viewtestutil.cpp ../../shared/viewtestutil.h - ../../shared/visualtestutil.cpp ../../shared/visualtestutil.h tst_qquicktaphandler.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp index 9b1101eb3a3..02d79c724c3 100644 --- a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp @@ -41,8 +41,8 @@ #include <QtQml/qqmlengine.h> #include <QtQml/qqmlproperty.h> -#include "../../../shared/util.h" -#include "../../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests") @@ -51,6 +51,7 @@ class tst_TapHandler : public QQmlDataTest Q_OBJECT public: tst_TapHandler() + : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: @@ -92,8 +93,8 @@ void tst_TapHandler::createView(QScopedPointer<QQuickView> &window, const char * window->setSource(testFileUrl(fileName)); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); @@ -739,8 +740,8 @@ void tst_TapHandler::rightLongPressIgnoreWheel() QQuickTapHandler *tap = window->rootObject()->findChild<QQuickTapHandler*>(); QVERIFY(tap); - QSignalSpy tappedSpy(tap, SIGNAL(tapped(QEventPoint *))); - QSignalSpy longPressedSpy(tap, SIGNAL(longPressed())); + QSignalSpy tappedSpy(tap, &QQuickTapHandler::tapped); + QSignalSpy longPressedSpy(tap, &QQuickTapHandler::longPressed); QPoint p1(100, 100); // Mouse wheel with ScrollBegin phase (because as soon as two fingers are touching diff --git a/tests/auto/quick/pointerhandlers/qquickwheelhandler/CMakeLists.txt b/tests/auto/quick/pointerhandlers/qquickwheelhandler/CMakeLists.txt index 588fd8f2e23..91db08f2272 100644 --- a/tests/auto/quick/pointerhandlers/qquickwheelhandler/CMakeLists.txt +++ b/tests/auto/quick/pointerhandlers/qquickwheelhandler/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickwheelhandler SOURCES - ../../../shared/util.cpp ../../../shared/util.h - ../../shared/geometrytestutil.cpp ../../shared/geometrytestutil.h - ../../shared/viewtestutil.cpp ../../shared/viewtestutil.h - ../../shared/visualtestutil.cpp ../../shared/visualtestutil.h tst_qquickwheelhandler.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/pointerhandlers/qquickwheelhandler/tst_qquickwheelhandler.cpp b/tests/auto/quick/pointerhandlers/qquickwheelhandler/tst_qquickwheelhandler.cpp index 2abf2ea8c35..84906f7848a 100644 --- a/tests/auto/quick/pointerhandlers/qquickwheelhandler/tst_qquickwheelhandler.cpp +++ b/tests/auto/quick/pointerhandlers/qquickwheelhandler/tst_qquickwheelhandler.cpp @@ -34,8 +34,8 @@ #include <QtQuick/private/qquickrectangle_p.h> #include <QtQuick/qquickview.h> #include <QtQml/qqmlcontext.h> -#include "../../../shared/util.h" -#include "../../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests") @@ -43,7 +43,7 @@ class tst_QQuickWheelHandler: public QQmlDataTest { Q_OBJECT public: - tst_QQuickWheelHandler() { } + tst_QQuickWheelHandler() : QQmlDataTest(QT_QMLTEST_DATADIR) { } private slots: void singleHandler_data(); diff --git a/tests/auto/quick/propertyrequirements/tst_propertyrequirements.cpp b/tests/auto/quick/propertyrequirements/tst_propertyrequirements.cpp index ca348eea03d..46f3c49d868 100644 --- a/tests/auto/quick/propertyrequirements/tst_propertyrequirements.cpp +++ b/tests/auto/quick/propertyrequirements/tst_propertyrequirements.cpp @@ -92,8 +92,8 @@ void tst_PropertyRequirements::constantOrNotifyableMain() } messages.sort(); - const QString message("\nThe following QML Types have properties which are neither CONSTANT nor NOTIFYable:\n"); - QWARN(qPrintable(message + messages.join("\n"))); + qWarning() << "\nThe following QML Types have properties which are neither CONSTANT nor NOTIFYable:\n" + << qPrintable(messages.join("\n")); // TODO enable once technical debt is fixes // QCOMPARE(failuresByProperty.count(), 0); @@ -127,7 +127,7 @@ void tst_PropertyRequirements::constantOrNotifyableFull() } messages.sort(); - QWARN(qPrintable(messages.join("\n"))); + qWarning() << qPrintable(messages.join("\n")); // TODO enable once technical debt is fixes // QCOMPARE(failuresByProperty.count(), 0); diff --git a/tests/auto/quick/qquickaccessible/CMakeLists.txt b/tests/auto/quick/qquickaccessible/CMakeLists.txt index 8d0fcbe4064..bc037a64ddb 100644 --- a/tests/auto/quick/qquickaccessible/CMakeLists.txt +++ b/tests/auto/quick/qquickaccessible/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickaccessible SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickaccessible.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickaccessible Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp index edaaed967a1..c220646e742 100644 --- a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp +++ b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp @@ -45,8 +45,8 @@ #include <QtQuick/private/qquicklistview_p.h> #include <QtQuick/private/qquicktext_p.h> -#include "../../shared/util.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> #define EXPECT(cond) \ do { \ @@ -77,6 +77,7 @@ private slots: void commonTests(); void quickAttachedProperties(); + void attachedWins(); void basicPropertiesTest(); void hitTest(); void checkableTest(); @@ -84,6 +85,7 @@ private slots: }; tst_QQuickAccessible::tst_QQuickAccessible() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } @@ -146,17 +148,17 @@ void tst_QQuickAccessible::commonTests() qDebug() << "testing" << accessibleRoleFileName; - QQuickView *view = new QQuickView(); + auto view = std::make_unique<QQuickView>(); // view->setFixedSize(240,320); view->setSource(testFileUrl(accessibleRoleFileName)); view->show(); // view->setFocus(); QVERIFY(view->rootObject() != nullptr); - QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(view); + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(view.get()); QVERIFY(iface); - delete view; + view.reset(); QTestAccessibility::clearEvents(); } @@ -167,12 +169,11 @@ void tst_QQuickAccessible::quickAttachedProperties() QQmlComponent component(&engine); component.setData("import QtQuick 2.0\nItem {\n" "}", QUrl()); - QObject *object = component.create(); + auto object = std::unique_ptr<QObject>(component.create()); QVERIFY(object != nullptr); - QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object); + QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object.get()); QCOMPARE(attachedObject, static_cast<QObject*>(nullptr)); - delete object; } // Attaching to non-item @@ -201,11 +202,11 @@ void tst_QQuickAccessible::quickAttachedProperties() component.setData("import QtQuick 2.0\nItem {\n" "Accessible.role: Accessible.Button\n" "}", QUrl()); - QObject *object = component.create(); + auto object = std::unique_ptr<QObject>(component.create()); QVERIFY(object != nullptr); const auto attachedObject = qobject_cast<QQuickAccessibleAttached*>( - QQuickAccessibleAttached::attachedProperties(object)); + QQuickAccessibleAttached::attachedProperties(object.get())); QVERIFY(attachedObject); if (attachedObject) { QVariant p = attachedObject->property("role"); @@ -219,7 +220,6 @@ void tst_QQuickAccessible::quickAttachedProperties() QVERIFY2(p.value<QString>().isEmpty(), QTest::toString(p)); QCOMPARE(attachedObject->wasNameExplicitlySet(), false); } - delete object; } // Attached property @@ -231,11 +231,11 @@ void tst_QQuickAccessible::quickAttachedProperties() "Accessible.name: \"Donald\"\n" "Accessible.description: \"Duck\"\n" "}", QUrl()); - QObject *object = component.create(); + auto object = std::unique_ptr<QObject>(component.create()); QVERIFY(object != nullptr); const auto attachedObject = qobject_cast<QQuickAccessibleAttached*>( - QQuickAccessibleAttached::attachedProperties(object)); + QQuickAccessibleAttached::attachedProperties(object.get())); QVERIFY(attachedObject); if (attachedObject) { QVariant p = attachedObject->property("role"); @@ -249,7 +249,6 @@ void tst_QQuickAccessible::quickAttachedProperties() QCOMPARE(p.toString(), QLatin1String("Duck")); QCOMPARE(attachedObject->wasNameExplicitlySet(), true); } - delete object; } // Check overriding of attached role for Text @@ -261,10 +260,10 @@ void tst_QQuickAccessible::quickAttachedProperties() "Accessible.name: \"TextButton\"\n" "Accessible.description: \"Text Button\"\n" "}", QUrl()); - QObject *object = component.create(); + auto object = std::unique_ptr<QObject>(component.create()); QVERIFY(object != nullptr); - QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object); + QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object.get()); QVERIFY(attachedObject); if (attachedObject) { QVariant p = attachedObject->property("role"); @@ -277,7 +276,6 @@ void tst_QQuickAccessible::quickAttachedProperties() QCOMPARE(p.isNull(), false); QCOMPARE(p.toString(), QLatin1String("Text Button")); } - delete object; } // Check overriding of attached role for Text { @@ -293,13 +291,13 @@ void tst_QQuickAccessible::quickAttachedProperties() "Accessible.description: \"Text Button\"\n" "}\n" "}", QUrl()); - QObject *object = component.create(); + auto object = std::unique_ptr<QObject>(component.create()); QVERIFY(object != nullptr); - QQuickListView *listview = qobject_cast<QQuickListView *>(object); + QQuickListView *listview = qobject_cast<QQuickListView *>(object.get()); QVERIFY(listview != nullptr); QQuickItem *contentItem = listview->contentItem(); - QQuickText *childItem = QQuickVisualTestUtil::findItem<QQuickText>(contentItem, "acc_text"); + QQuickText *childItem = QQuickVisualTestUtils::findItem<QQuickText>(contentItem, "acc_text"); QVERIFY(childItem != nullptr); QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(childItem); @@ -315,7 +313,6 @@ void tst_QQuickAccessible::quickAttachedProperties() QCOMPARE(p.isNull(), false); QCOMPARE(p.toString(), QLatin1String("Text Button")); } - delete object; } // Check that a name can be implicitly set. { @@ -327,11 +324,11 @@ void tst_QQuickAccessible::quickAttachedProperties() Accessible.role: Accessible.Button Accessible.description: "Text Button" })", QUrl()); - QScopedPointer<QObject> object(component.create()); + auto object = std::unique_ptr<QObject>(component.create()); QVERIFY(object); const auto attachedObject = qobject_cast<QQuickAccessibleAttached*>( - QQuickAccessibleAttached::attachedProperties(object.data())); + QQuickAccessibleAttached::attachedProperties(object.get())); QVERIFY(attachedObject); QVERIFY(!attachedObject->wasNameExplicitlySet()); @@ -346,18 +343,43 @@ void tst_QQuickAccessible::quickAttachedProperties() QTestAccessibility::clearEvents(); } +// Verify that a role can be explicitly set, and that the values from the +// attached object are used even if the item has a default role - QTBUG-110114 +void tst_QQuickAccessible::attachedWins() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(R"( + import QtQuick + import QtQuick.Controls + Button { + text: "Button" + objectName: "button" + Accessible.role: Accessible.RadioButton + Accessible.description: "Radio Button" + })", QUrl()); + auto button = std::unique_ptr<QObject>(component.create()); + QVERIFY(button); + + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(button.get()); + QVERIFY(iface); + + QCOMPARE(iface->role(), QAccessible::RadioButton); + QTestAccessibility::clearEvents(); +} + void tst_QQuickAccessible::basicPropertiesTest() { QAccessibleInterface *app = QAccessible::queryAccessibleInterface(qApp); QCOMPARE(app->childCount(), 0); - QQuickView *window = new QQuickView(); + auto window = std::make_unique<QQuickView>(); window->setSource(testFileUrl("text.qml")); window->show(); QCOMPARE(app->childCount(), 1); - QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(window); + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(window.get()); QVERIFY(iface); QCOMPARE(iface->childCount(), 1); @@ -391,6 +413,7 @@ void tst_QQuickAccessible::basicPropertiesTest() QCOMPARE(item->indexOfChild(text2), 1); QVERIFY(!text2->state().editable); QVERIFY(text2->state().readOnly); + QVERIFY(text2->state().focusable); QCOMPARE(iface->indexOfChild(text2), -1); QCOMPARE(text2->indexOfChild(item), -1); @@ -482,7 +505,7 @@ void tst_QQuickAccessible::basicPropertiesTest() attached->setRole(QAccessible::StaticText); QVERIFY(!text3->state().readOnly); - delete window; + window.reset(); QTestAccessibility::clearEvents(); } @@ -501,14 +524,15 @@ QAccessibleInterface *topLevelChildAt(QAccessibleInterface *iface, int x, int y) void tst_QQuickAccessible::hitTest() { - QQuickView *window = new QQuickView; + auto window = std::make_unique<QQuickView>(); window->setSource(testFileUrl("hittest.qml")); window->show(); - QAccessibleInterface *windowIface = QAccessible::queryAccessibleInterface(window); + QAccessibleInterface *windowIface = QAccessible::queryAccessibleInterface(window.get()); QVERIFY(windowIface); QAccessibleInterface *rootItem = windowIface->child(0); - QRect rootRect = rootItem->rect(); + // on Android the main window is always shown fullscreen + QRect rootRect = QRect(window->x(), window->y(), window->width(), window->height()); // check the root item from app QAccessibleInterface *appIface = QAccessible::queryAccessibleInterface(qApp); @@ -554,13 +578,13 @@ void tst_QQuickAccessible::hitTest() } } - delete window; + window.reset(); QTestAccessibility::clearEvents(); } void tst_QQuickAccessible::checkableTest() { - QScopedPointer<QQuickView> window(new QQuickView()); + auto window = std::make_unique<QQuickView>(); window->setSource(testFileUrl("checkbuttons.qml")); window->show(); @@ -573,7 +597,7 @@ void tst_QQuickAccessible::checkableTest() QAccessible::State activatedChange; activatedChange.active = true; - QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(window.data()); + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(window.get()); QVERIFY(iface); QAccessibleInterface *root = iface->child(0); @@ -637,7 +661,7 @@ void tst_QQuickAccessible::checkableTest() void tst_QQuickAccessible::ignoredTest() { - QScopedPointer<QQuickView> window(new QQuickView()); + auto window = std::make_unique<QQuickView>(); window->setSource(testFileUrl("ignored.qml")); window->show(); @@ -650,7 +674,7 @@ void tst_QQuickAccessible::ignoredTest() QAccessible::State activatedChange; activatedChange.active = true; - QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(window.data()); + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(window.get()); QVERIFY(iface); QAccessibleInterface *rectangleA = iface->child(0); diff --git a/tests/auto/quick/qquickanchors/CMakeLists.txt b/tests/auto/quick/qquickanchors/CMakeLists.txt index 08a42981452..b8a308b5d7f 100644 --- a/tests/auto/quick/qquickanchors/CMakeLists.txt +++ b/tests/auto/quick/qquickanchors/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickanchors SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickanchors.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickanchors/tst_qquickanchors.cpp b/tests/auto/quick/qquickanchors/tst_qquickanchors.cpp index 128a1544929..9c6401c60f6 100644 --- a/tests/auto/quick/qquickanchors/tst_qquickanchors.cpp +++ b/tests/auto/quick/qquickanchors/tst_qquickanchors.cpp @@ -35,18 +35,18 @@ #include <QtQuick/private/qquicktext_p.h> #include <QtQuick/private/qquickanchors_p_p.h> #include <QtQuick/private/qquickitem_p.h> -#include "../../shared/util.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> Q_DECLARE_METATYPE(QQuickAnchors::Anchor) -using namespace QQuickVisualTestUtil; +using namespace QQuickVisualTestUtils; class tst_qquickanchors : public QQmlDataTest { Q_OBJECT public: - tst_qquickanchors() {} + tst_qquickanchors() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void basicAnchors(); diff --git a/tests/auto/quick/qquickanimatedimage/BLACKLIST b/tests/auto/quick/qquickanimatedimage/BLACKLIST new file mode 100644 index 00000000000..c4778ba8e57 --- /dev/null +++ b/tests/auto/quick/qquickanimatedimage/BLACKLIST @@ -0,0 +1,5 @@ +# QTBUG-103076 +[mirror_running] +android +[mirror_notRunning] +android diff --git a/tests/auto/quick/qquickanimatedimage/CMakeLists.txt b/tests/auto/quick/qquickanimatedimage/CMakeLists.txt index e7a026a36f0..69894ccffc4 100644 --- a/tests/auto/quick/qquickanimatedimage/CMakeLists.txt +++ b/tests/auto/quick/qquickanimatedimage/CMakeLists.txt @@ -12,11 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickanimatedimage SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h tst_qquickanimatedimage.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -24,6 +20,7 @@ qt_internal_add_test(tst_qquickanimatedimage Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp index 31c3fb99460..2680647453e 100644 --- a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp +++ b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp @@ -36,8 +36,8 @@ #include <QSignalSpy> #include <QtQml/qqmlcontext.h> -#include "../../shared/testhttpserver.h" -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/testhttpserver_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> Q_DECLARE_METATYPE(QQuickImageBase::Status) @@ -62,7 +62,7 @@ class tst_qquickanimatedimage : public QQmlDataTest { Q_OBJECT public: - tst_qquickanimatedimage() {} + tst_qquickanimatedimage() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void cleanup(); diff --git a/tests/auto/quick/qquickanimatedsprite/BLACKLIST b/tests/auto/quick/qquickanimatedsprite/BLACKLIST index 7eb242876a2..720ef7a2757 100644 --- a/tests/auto/quick/qquickanimatedsprite/BLACKLIST +++ b/tests/auto/quick/qquickanimatedsprite/BLACKLIST @@ -1,3 +1,7 @@ # QTBUG-65613 [test_largeAnimation] b2qt + +# QTBUG-103260 +[test_finishBehavior] +android diff --git a/tests/auto/quick/qquickanimatedsprite/CMakeLists.txt b/tests/auto/quick/qquickanimatedsprite/CMakeLists.txt index 9e20d712e63..681c4500786 100644 --- a/tests/auto/quick/qquickanimatedsprite/CMakeLists.txt +++ b/tests/auto/quick/qquickanimatedsprite/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickanimatedsprite SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickanimatedsprite.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -24,6 +21,7 @@ qt_internal_add_test(tst_qquickanimatedsprite Qt::QmlPrivate Qt::QuickPrivate Qt::QuickTest + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp index 7a56c370d5e..81651d957d6 100644 --- a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp +++ b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp @@ -26,7 +26,7 @@ ** ****************************************************************************/ #include <QtTest/QtTest> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtQuick/qquickview.h> #include <QtQuickTest/QtQuickTest> #include <private/qabstractanimation_p.h> @@ -42,7 +42,7 @@ class tst_qquickanimatedsprite : public QQmlDataTest { Q_OBJECT public: - tst_qquickanimatedsprite(){} + tst_qquickanimatedsprite() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; @@ -329,9 +329,26 @@ class KillerThread : public QThread Q_OBJECT protected: void run() override { - sleep(3); - qFatal("Either the GUI or the render thread is stuck in an infinite loop."); + QMutexLocker lock(&abortMutex); + if (!aborted) + abortWaitCondition.wait(&abortMutex, 3000); + + if (!aborted) + qFatal("Either the GUI or the render thread is stuck in an infinite loop."); + } + +public: + void abort() + { + QMutexLocker lock(&abortMutex); + aborted = true; + abortWaitCondition.wakeAll(); } + +private: + QMutex abortMutex; + QWaitCondition abortWaitCondition; + bool aborted = false; }; // Regression test for QTBUG-53937 @@ -356,7 +373,7 @@ void tst_qquickanimatedsprite::test_changeSourceToSmallerImgKeepingBigFrameSize( // If we reach this point it's because we didn't hit QTBUG-53937 - killer->terminate(); + killer->abort(); killer->wait(); } diff --git a/tests/auto/quick/qquickanimations/CMakeLists.txt b/tests/auto/quick/qquickanimations/CMakeLists.txt index 203fa770fbe..cf53e10a1cc 100644 --- a/tests/auto/quick/qquickanimations/CMakeLists.txt +++ b/tests/auto/quick/qquickanimations/CMakeLists.txt @@ -12,12 +12,9 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickanimations SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickanimations.cpp DEFINES QT_DISABLE_DEPRECATED_BEFORE=0 - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -25,6 +22,7 @@ qt_internal_add_test(tst_qquickanimations Qt::QmlModelsPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickanimations/data/cleanupWhenRenderThreadStops.qml b/tests/auto/quick/qquickanimations/data/cleanupWhenRenderThreadStops.qml new file mode 100644 index 00000000000..4cfb59aeabc --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/cleanupWhenRenderThreadStops.qml @@ -0,0 +1,32 @@ +//main.qml + +import QtQuick 2.12 +import QtQuick.Window 2.12 + +Item { + id: root + width: 640 + height: 480 + visible: true + property bool running : false + + Rectangle { + id: rect + anchors.fill: parent + color: "red" + + Component.onCompleted: { + anim.start() + running = true + } + } + + OpacityAnimator { + id: anim + + target: rect + from: 1 + to: 0 + duration: 20000 + } +} diff --git a/tests/auto/quick/qquickanimations/data/infiniteAnimationWithoutFrom.qml b/tests/auto/quick/qquickanimations/data/infiniteAnimationWithoutFrom.qml new file mode 100644 index 00000000000..9b4bfe4faa1 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/infiniteAnimationWithoutFrom.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + width: 100 + height: 100 + + // note that 'from' property is missing + NumberAnimation { + objectName: "anim" + to: from+360 + loops: Animation.Infinite + target: rect + properties: "rotation" + duration: 100 + } + + Rectangle { + objectName: "rect" + id: rect + width: 30 + height: 10 + color: "red" + anchors.centerIn: parent + transformOrigin: Item.Center + } +} diff --git a/tests/auto/quick/qquickanimations/data/targetsDeletedWithoutRemoval.qml b/tests/auto/quick/qquickanimations/data/targetsDeletedWithoutRemoval.qml new file mode 100644 index 00000000000..e31caa19052 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/targetsDeletedWithoutRemoval.qml @@ -0,0 +1,29 @@ +import QtQuick + +Item { + id: root + + property list<Translate> targets + property alias animTargets: animation.targets + + Component { + id: trComponent + Translate {} + } + + Component.onCompleted: { + const target = trComponent.createObject(this); + targets.push(target); + target.destroy(); + // give event loop some time to actually stop the animation and destroy the target + Qt.callLater(animation.start); + } + + NumberAnimation { + id: animation + targets: root.targets + property: "x" + running: false + to: 100 + } +} diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp index 6bc8a056070..30b934eeec4 100644 --- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp +++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp @@ -46,13 +46,13 @@ #include <limits.h> #include <math.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickanimations : public QQmlDataTest { Q_OBJECT public: - tst_qquickanimations() {} + tst_qquickanimations() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override @@ -116,8 +116,10 @@ private slots: void fastFlickingBug(); void opacityAnimationFromZero(); void alwaysRunToEndInSequentialAnimationBug(); + void cleanupWhenRenderThreadStops(); + void infiniteLoopsWithoutFrom(); + void targetsDeletedNotRemoved(); }; - #define QTIMED_COMPARE(lhs, rhs) do { \ for (int ii = 0; ii < 5; ++ii) { \ if (lhs == rhs) \ @@ -1898,7 +1900,7 @@ void tst_qquickanimations::opacityAnimationFromZero() void tst_qquickanimations::alwaysRunToEndInSequentialAnimationBug() { - QQuickView view(QUrl::fromLocalFile("data/alwaysRunToEndInSequentialAnimationBug.qml")); + QQuickView view(testFileUrl("alwaysRunToEndInSequentialAnimationBug.qml")); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); @@ -1998,6 +2000,87 @@ void tst_qquickanimations::alwaysRunToEndInSequentialAnimationBug() QCOMPARE(whiteRect->property("opacity").value<qreal>(),1.0); } +void tst_qquickanimations::cleanupWhenRenderThreadStops() +{ + QQuickView view(testFileUrl("cleanupWhenRenderThreadStops.qml")); + view.show(); + view.setPersistentGraphics(false); + view.setPersistentSceneGraph(false); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + QTest::qWait(50); + view.hide(); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); +} + +void tst_qquickanimations::infiniteLoopsWithoutFrom() +{ + // This test checks QTBUG-84375 + QQuickView view(testFileUrl("infiniteAnimationWithoutFrom.qml")); + view.show(); + + QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(view.rootObject()); + + QObject *root = view.rootObject(); + QQuickAbstractAnimation *animation = root->findChild<QQuickAbstractAnimation *>("anim"); + QVERIFY(animation); + QQuickRectangle *rectangle = root->findChild<QQuickRectangle *>("rect"); + QVERIFY(rectangle); + + qreal prevRotation = rectangle->rotation(); + int numsCrossedZero = 0; + connect(rectangle, &QQuickRectangle::rotationChanged, this, [&]() { + const auto rotation = rectangle->rotation(); + // We take a large range of (180; 360] here, because the animation in + // the test runs for a short time, and so there can be huge gaps between + // rotation values. + const bool prevRotationOldLoop = prevRotation > 180.0 && prevRotation <= 360.0; + const bool currRotationNewLoop = rotation >= 0.0 && rotation <= 180.0; + if (prevRotationOldLoop && currRotationNewLoop) + numsCrossedZero++; + prevRotation = rotation; + }); + + // The logic in lamdba function above requires at least two positions in + // a rotation animation - one in [0; 180] range, and another in (180; 360] + // range + animation->start(); + animation->pause(); + QCOMPARE(numsCrossedZero, 0); + animation->setCurrentTime(40); + animation->setCurrentTime(90); + QCOMPARE(numsCrossedZero, 0); + animation->setCurrentTime(140); + animation->setCurrentTime(190); + QCOMPARE(numsCrossedZero, 1); + animation->setCurrentTime(240); + animation->setCurrentTime(290); + QCOMPARE(numsCrossedZero, 2); + + animation->stop(); +} + +void tst_qquickanimations::targetsDeletedNotRemoved() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("targetsDeletedWithoutRemoval.qml")); + QScopedPointer<QObject> obj(component.create()); + QVERIFY2(obj.get(), qPrintable(component.errorString())); + { + QQmlListReference ref(obj.get(), "targets"); + QVERIFY(ref.isValid()); + QCOMPARE(ref.size(), 1); + QTRY_COMPARE(ref.at(0), nullptr); + } + { + QQmlListReference ref(obj.get(), "animTargets"); + QVERIFY(ref.isValid()); + QCOMPARE(ref.size(), 1); + QCOMPARE(ref.at(0), nullptr); + } +} + QTEST_MAIN(tst_qquickanimations) #include "tst_qquickanimations.moc" diff --git a/tests/auto/quick/qquickanimators/CMakeLists.txt b/tests/auto/quick/qquickanimators/CMakeLists.txt index 4ad5624f85e..b8c83679981 100644 --- a/tests/auto/quick/qquickanimators/CMakeLists.txt +++ b/tests/auto/quick/qquickanimators/CMakeLists.txt @@ -12,22 +12,17 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickanimators SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickanimators.cpp DEFINES QT_DISABLE_DEPRECATED_BEFORE=0 QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp b/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp index 30a1d5a5606..f1cfa05d388 100644 --- a/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp +++ b/tests/auto/quick/qquickanimators/tst_qquickanimators.cpp @@ -37,10 +37,10 @@ #include <QtQuick/private/qquickanimation_p_p.h> #include <QtQuick/private/qquickitem_p.h> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> -using namespace QQuickViewTestUtil; +using namespace QQuickViewTestUtils; QT_BEGIN_NAMESPACE @@ -48,6 +48,9 @@ class tst_Animators: public QQmlDataTest { Q_OBJECT +public: + tst_Animators(); + private slots: void testMultiWinAnimator_data(); void testMultiWinAnimator(); @@ -55,6 +58,11 @@ private slots: void testTransitionsWithImplicitFrom(); }; +tst_Animators::tst_Animators() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_Animators::testMultiWinAnimator_data() { QTest::addColumn<int>("count"); diff --git a/tests/auto/quick/qquickapplication/CMakeLists.txt b/tests/auto/quick/qquickapplication/CMakeLists.txt index 53582b45483..431bbc85079 100644 --- a/tests/auto/quick/qquickapplication/CMakeLists.txt +++ b/tests/auto/quick/qquickapplication/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickapplication SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickapplication.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -24,6 +21,7 @@ qt_internal_add_test(tst_qquickapplication Qt::QmlPrivate Qt::Quick Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp index 785475402a4..133583e72c1 100644 --- a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp +++ b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp @@ -36,7 +36,7 @@ #include <qpa/qwindowsysteminterface.h> #include <qpa/qplatformintegration.h> #include <private/qguiapplication_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickapplication : public QQmlDataTest { @@ -60,6 +60,7 @@ private slots: }; tst_qquickapplication::tst_qquickapplication() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } diff --git a/tests/auto/quick/qquickbehaviors/BLACKLIST b/tests/auto/quick/qquickbehaviors/BLACKLIST deleted file mode 100644 index 1a9a7e9b19d..00000000000 --- a/tests/auto/quick/qquickbehaviors/BLACKLIST +++ /dev/null @@ -1,3 +0,0 @@ -# QTBUG-82404 -[currentValue] -macos ci diff --git a/tests/auto/quick/qquickbehaviors/CMakeLists.txt b/tests/auto/quick/qquickbehaviors/CMakeLists.txt index b864b0c21b9..5904ca48a1b 100644 --- a/tests/auto/quick/qquickbehaviors/CMakeLists.txt +++ b/tests/auto/quick/qquickbehaviors/CMakeLists.txt @@ -12,17 +12,15 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickbehaviors SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickbehaviors.cpp bindable.h - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) @@ -31,7 +29,7 @@ set_target_properties(tst_qquickbehaviors PROPERTIES QT_QML_MODULE_URI test ) -qt6_qml_type_registration(tst_qquickbehaviors) +_qt_internal_qml_type_registration(tst_qquickbehaviors) #### Keys ignored in scope 1:.:.:qquickbehaviors.pro:<TRUE>: diff --git a/tests/auto/quick/qquickbehaviors/data/defaultQProperty.qml b/tests/auto/quick/qquickbehaviors/data/defaultQProperty.qml new file mode 100644 index 00000000000..596efac3250 --- /dev/null +++ b/tests/auto/quick/qquickbehaviors/data/defaultQProperty.qml @@ -0,0 +1,14 @@ +import QtQuick + +Item { + property int heightChanges: 0 + property int widthChanges: 0 + implicitWidth: 50 + implicitHeight: 50 + height: { return 0 } + width: { return 10 } + Behavior on height { NumberAnimation { duration: 300 } } + Behavior on width { NumberAnimation { duration: 300 } } + onHeightChanged: ++heightChanges + onWidthChanged: ++widthChanges +} diff --git a/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp b/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp index 35423651f9d..159fb1398e6 100644 --- a/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp +++ b/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp @@ -36,14 +36,14 @@ #include <QtQuick/private/qquickanimation_p.h> #include <QtQuick/private/qquicksmoothedanimation_p.h> #include <private/qquickitem_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include "bindable.h" class tst_qquickbehaviors : public QQmlDataTest { Q_OBJECT public: - tst_qquickbehaviors() {} + tst_qquickbehaviors() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void init() { qApp->processEvents(); } //work around animation timer bug (QTBUG-22865) @@ -78,6 +78,7 @@ private slots: void safeToDelete(); void targetProperty(); void bindableProperty(); + void defaultQProperty(); }; void tst_qquickbehaviors::simpleBehavior() @@ -703,6 +704,23 @@ void tst_qquickbehaviors::bindableProperty() QTRY_COMPARE(testBindable->prop(), 300); } +void tst_qquickbehaviors::defaultQProperty() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("defaultQProperty.qml")); + QScopedPointer<QObject> root(c.create()); + QVERIFY2(root, qPrintable(c.errorString())); + + QQuickItem *item = qobject_cast<QQuickItem *>(root.data()); + QVERIFY(item); + + QCOMPARE(item->height(), 0.0); + QCOMPARE(item->width(), 10.0); + + // Both change only once: No intermediate change to 0 on width. + QCOMPARE(root->property("heightChanges").toInt(), 1); + QCOMPARE(root->property("widthChanges").toInt(), 1); +} QTEST_MAIN(tst_qquickbehaviors) diff --git a/tests/auto/quick/qquickborderimage/BLACKLIST b/tests/auto/quick/qquickborderimage/BLACKLIST new file mode 100644 index 00000000000..30b72020a42 --- /dev/null +++ b/tests/auto/quick/qquickborderimage/BLACKLIST @@ -0,0 +1,7 @@ +# QTBUG-103077 +[mirror] +android +[borderImageMesh] +android +[multiFrame] +android diff --git a/tests/auto/quick/qquickborderimage/CMakeLists.txt b/tests/auto/quick/qquickborderimage/CMakeLists.txt index 7316588123f..d3537c53212 100644 --- a/tests/auto/quick/qquickborderimage/CMakeLists.txt +++ b/tests/auto/quick/qquickborderimage/CMakeLists.txt @@ -12,16 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickborderimage SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickborderimage.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -29,6 +20,7 @@ qt_internal_add_test(tst_qquickborderimage Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp index 32b502c6dc8..e963082a1aa 100644 --- a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp +++ b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp @@ -42,9 +42,9 @@ #include <QtQuick/qquickview.h> #include <QtQml/qqmlcontext.h> -#include "../../shared/testhttpserver.h" -#include "../../shared/util.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/testhttpserver_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") @@ -96,6 +96,7 @@ void tst_qquickborderimage::cleanup() } tst_qquickborderimage::tst_qquickborderimage() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } @@ -590,18 +591,25 @@ void tst_qquickborderimage::progressAndStatusChanges() #if QT_CONFIG(opengl) void tst_qquickborderimage::borderImageMesh() { + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms"); + QQuickView *window = new QQuickView; window->setSource(testFileUrl("nonmesh.qml")); window->show(); QVERIFY(QTest::qWaitForWindowExposed(window)); + if (window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) + QSKIP("Software backend has no ShaderEffect supported, skipping test"); + QImage nonmesh = window->grabWindow(); window->setSource(testFileUrl("mesh.qml")); QImage mesh = window->grabWindow(); QString errorMessage; - QVERIFY2(QQuickVisualTestUtil::compareImages(mesh, nonmesh, &errorMessage), + QVERIFY2(QQuickVisualTestUtils::compareImages(mesh, nonmesh, &errorMessage), qPrintable(errorMessage)); } #endif diff --git a/tests/auto/quick/qquickboundaryrule/CMakeLists.txt b/tests/auto/quick/qquickboundaryrule/CMakeLists.txt index 96395c99568..456e201cadc 100644 --- a/tests/auto/quick/qquickboundaryrule/CMakeLists.txt +++ b/tests/auto/quick/qquickboundaryrule/CMakeLists.txt @@ -12,15 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickboundaryrule SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickboundaryrule.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -28,6 +20,7 @@ qt_internal_add_test(tst_qquickboundaryrule Qt::Qml Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp b/tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp index 75639dba49f..ee9321a2361 100644 --- a/tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp +++ b/tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp @@ -31,14 +31,14 @@ #include <QtQml/qqmlcomponent.h> #include <QtQuick/qquickview.h> #include <QtQuick/private/qquickdraghandler_p.h> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> class tst_qquickboundaryrule : public QQmlDataTest { Q_OBJECT public: - tst_qquickboundaryrule() {} + tst_qquickboundaryrule() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void init() { qApp->processEvents(); } //work around animation timer bug (QTBUG-22865) diff --git a/tests/auto/quick/qquickcanvasitem/BLACKLIST b/tests/auto/quick/qquickcanvasitem/BLACKLIST index f88c681630f..89654cb5e3d 100644 --- a/tests/auto/quick/qquickcanvasitem/BLACKLIST +++ b/tests/auto/quick/qquickcanvasitem/BLACKLIST @@ -19,3 +19,8 @@ opensuse-leap # QTQAINFRA-4127 [canvas::test_extraArgumentsIgnored:text] ci b2qt 32bit + +# QTBUG-100991 +[line::test_cap] +android + diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_arc.qml b/tests/auto/quick/qquickcanvasitem/data/tst_arc.qml index 33fffd4cb18..00d13f31f44 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_arc.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_arc.qml @@ -6,6 +6,7 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_angle_1(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -21,6 +22,7 @@ CanvasTestCase { } function test_angle_2(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -36,6 +38,7 @@ CanvasTestCase { } function test_angle_3(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#0f0'; @@ -53,6 +56,7 @@ CanvasTestCase { } function test_angle_4(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -71,6 +75,7 @@ CanvasTestCase { } function test_angle_5(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -90,6 +95,7 @@ CanvasTestCase { function test_angle_6(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -110,6 +116,7 @@ CanvasTestCase { function test_empty(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -125,6 +132,7 @@ CanvasTestCase { } function test_nonempty(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -141,6 +149,7 @@ CanvasTestCase { } function test_nonfinite(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -199,6 +208,7 @@ CanvasTestCase { } function test_end(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -216,6 +226,7 @@ CanvasTestCase { } function test_negative(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -234,6 +245,7 @@ CanvasTestCase { function test_scale_1(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -270,6 +282,7 @@ CanvasTestCase { function test_scale_2(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -296,6 +309,7 @@ CanvasTestCase { function test_selfintersect_1(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -316,6 +330,7 @@ CanvasTestCase { function test_selfintersect_2(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -340,6 +355,7 @@ CanvasTestCase { function test_shape_1(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -361,6 +377,7 @@ CanvasTestCase { function test_shape_2(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -381,6 +398,7 @@ CanvasTestCase { } function test_shape_3(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -401,6 +419,7 @@ CanvasTestCase { function test_shape_4(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -421,6 +440,7 @@ CanvasTestCase { function test_shape_5(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -441,6 +461,7 @@ CanvasTestCase { function test_twopie(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -488,6 +509,7 @@ CanvasTestCase { function test_zero(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_arcto.qml b/tests/auto/quick/qquickcanvasitem/data/tst_arcto.qml index ef1b7a7b2a1..81412d98c90 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_arcto.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_arcto.qml @@ -7,6 +7,7 @@ CanvasTestCase { function test_coincide(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -44,6 +45,7 @@ CanvasTestCase { } function test_collinear(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -109,6 +111,7 @@ CanvasTestCase { } function test_subpath(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -135,6 +138,7 @@ CanvasTestCase { function test_negative(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -152,6 +156,7 @@ CanvasTestCase { function test_nonfinite(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -208,6 +213,7 @@ CanvasTestCase { } function test_scale(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -237,6 +243,7 @@ CanvasTestCase { function test_shape(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -348,6 +355,7 @@ CanvasTestCase { function test_transform(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -374,6 +382,7 @@ CanvasTestCase { } function test_zero(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_composite.qml b/tests/auto/quick/qquickcanvasitem/data/tst_composite.qml index 8a5a52cf1e9..4ee24ad4376 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_composite.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_composite.qml @@ -6,6 +6,7 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_clearRect(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -17,6 +18,7 @@ CanvasTestCase { function test_clip(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); var composites = [ {compsite:"copy"}, {compsite:"destination-atop"}, @@ -47,6 +49,7 @@ CanvasTestCase { function test_globalAlpha(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); compare(ctx.globalAlpha, 1.0); @@ -83,6 +86,7 @@ CanvasTestCase { function test_operation(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.globalCompositeOperation = 'xor'; @@ -137,6 +141,7 @@ CanvasTestCase { function test_solid(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = Qt.rgba(0, 1, 1, 1.0); @@ -233,6 +238,7 @@ CanvasTestCase { } function test_transparent(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; @@ -330,6 +336,7 @@ CanvasTestCase { function test_uncovered(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_fillStyle.qml b/tests/auto/quick/qquickcanvasitem/data/tst_fillStyle.qml index 58ea6d7f591..9e8c0785c37 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_fillStyle.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_fillStyle.qml @@ -6,6 +6,7 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_default(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); verify(ctx.fillStyle, "#000000"); @@ -14,6 +15,7 @@ CanvasTestCase { } function test_get(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#fa0'; @@ -23,6 +25,7 @@ CanvasTestCase { } function test_hex(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -37,6 +40,7 @@ CanvasTestCase { } function test_invalid(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#fa0'; @@ -60,6 +64,7 @@ CanvasTestCase { } function test_saverestore(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); var old = ctx.fillStyle; ctx.save(); @@ -75,6 +80,7 @@ CanvasTestCase { } function test_namedColor(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = "red"; @@ -91,6 +97,7 @@ CanvasTestCase { } function test_rgba(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = "rgb(-100, 300, 255)"; @@ -108,6 +115,7 @@ CanvasTestCase { function test_hsla(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = "hsla(120, 100%, 50%, 0.499)"; diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_fillrect.qml b/tests/auto/quick/qquickcanvasitem/data/tst_fillrect.qml index ce1c27c6bc7..213abdd6222 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_fillrect.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_fillrect.qml @@ -6,6 +6,7 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_fillRect(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.fillStyle = "red"; ctx.fillRect(0, 0, canvas.width, canvas.height); diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_gradient.qml b/tests/auto/quick/qquickcanvasitem/data/tst_gradient.qml index 7c87d896fb1..70e77c87601 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_gradient.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_gradient.qml @@ -6,6 +6,7 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_basic(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#0f0'; @@ -18,6 +19,7 @@ CanvasTestCase { function test_interpolate(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -166,6 +168,7 @@ CanvasTestCase { } function test_radial(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#0f0'; @@ -788,6 +791,7 @@ CanvasTestCase { } function test_linear(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); try { var err = false; @@ -907,6 +911,7 @@ CanvasTestCase { } function test_object(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); var g1 = ctx.createLinearGradient(0, 0, 100, 0); @@ -978,6 +983,7 @@ CanvasTestCase { function test_conical(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); var g = ctx.createConicalGradient(10, 10, 50); diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml index 1f695d7080b..a1eb272cd02 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml @@ -11,12 +11,12 @@ CanvasTestCase { canvas.loadImage('rgrg-256x256.png'); canvas.loadImage('ggrr-256x256.png'); canvas.loadImage('broken.png'); - while (!canvas.isImageLoaded('green.png')) - wait(200); + tryVerify(function() { return canvas.isImageLoaded('green.png'); }) } function test_3args(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); ctx.reset(); @@ -35,6 +35,7 @@ CanvasTestCase { } function test_5args(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -54,6 +55,7 @@ CanvasTestCase { } function test_9args(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -118,6 +120,7 @@ CanvasTestCase { } function test_animated(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -125,6 +128,7 @@ CanvasTestCase { } function test_clip(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -139,6 +143,7 @@ CanvasTestCase { } function test_self(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -170,6 +175,7 @@ CanvasTestCase { function test_outsidesource(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -207,6 +213,7 @@ CanvasTestCase { function test_null(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -220,15 +227,18 @@ CanvasTestCase { function test_url(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); canvas.loadImage(testCase.green); + tryVerify(function() { return canvas.isImageLoaded(testCase.green); }) ctx.drawImage(testCase.green, 0, 0); comparePixel(ctx, 0,0, 0,255,0,255,2); } function test_composite(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -241,12 +251,14 @@ CanvasTestCase { } function test_path(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); } function test_transform(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -260,6 +272,7 @@ CanvasTestCase { function test_imageitem(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -268,6 +281,7 @@ CanvasTestCase { function test_imageData(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -276,6 +290,7 @@ CanvasTestCase { function test_wrongtype(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -293,6 +308,7 @@ CanvasTestCase { function test_nonfinite(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -606,6 +622,7 @@ CanvasTestCase { function test_negative(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -661,6 +678,7 @@ CanvasTestCase { function test_canvas(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -684,6 +702,7 @@ CanvasTestCase { function test_broken(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -694,6 +713,7 @@ CanvasTestCase { function test_alpha(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); @@ -706,6 +726,7 @@ CanvasTestCase { } function test_multiple_painting(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); loadImages(canvas); diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml b/tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml index 76b99a765e2..aab7a95589e 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml @@ -11,6 +11,7 @@ CanvasTestCase { skip("ctx.getImageData crashes on offscreen/minimal platforms"); var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); var size = 17 ctx.reset(); diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_line.qml b/tests/auto/quick/qquickcanvasitem/data/tst_line.qml index dc960a24d06..e5d03e5db7e 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_line.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_line.qml @@ -6,6 +6,7 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_default(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); compare(ctx.lineWidth, 1); @@ -16,6 +17,7 @@ CanvasTestCase { function test_cross(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#0f0'; @@ -43,6 +45,7 @@ CanvasTestCase { function test_join(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -306,6 +309,7 @@ CanvasTestCase { } function test_miter(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -481,6 +485,7 @@ CanvasTestCase { } function test_width(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#0f0'; @@ -621,7 +626,11 @@ CanvasTestCase { } function test_cap(row) { + if (Qt.platform.os === "android") + skip("line::test_cap crashes on Android, QTBUG-103257") + var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -838,6 +847,7 @@ CanvasTestCase { function test_lineDash(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.strokeStyle = "#fff"; @@ -894,8 +904,41 @@ CanvasTestCase { comparePixel(ctx, 39,0, 0,0,0,0); } + function test_lineDashReset(row) { + var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.strokeStyle = "#ff0000"; + ctx.lineWidth = 2; + var pattern = [2, 3, 5, 1, 6, 3] + ctx.setLineDash(pattern) + + compare(ctx.getLineDash(), pattern); + + pattern = [] + ctx.setLineDash(pattern) + compare(ctx.getLineDash(), pattern); + + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(40, 0); + ctx.stroke(); + + comparePixel(ctx, 0,0, 255,0,0,255); + comparePixel(ctx, 4,0, 255,0,0,255); + comparePixel(ctx, 5,0, 255,0,0,255); + comparePixel(ctx, 14,0, 255,0,0,255); + comparePixel(ctx, 20,0, 255,0,0,255); + comparePixel(ctx, 21,0, 255,0,0,255); + comparePixel(ctx, 22,0, 255,0,0,255); + comparePixel(ctx, 34,0, 255,0,0,255); + comparePixel(ctx, 35,0, 255,0,0,255); + } + function test_lineDashOffset(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.strokeStyle = "#fff"; diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_path.qml b/tests/auto/quick/qquickcanvasitem/data/tst_path.qml index 60c782c8fa4..ae08b585190 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_path.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_path.qml @@ -6,6 +6,7 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_basic(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#0f0'; @@ -36,6 +37,7 @@ CanvasTestCase { } function test_beginPath(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.fillStyle = '#0f0'; ctx.fillRect(0, 0, 100, 50); @@ -48,6 +50,7 @@ CanvasTestCase { } function test_closePath(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#0f0'; @@ -86,6 +89,7 @@ CanvasTestCase { function test_isPointInPath(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.arc(50, 25, 10, 0, Math.PI, false); @@ -256,6 +260,7 @@ CanvasTestCase { function test_fill(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -378,6 +383,7 @@ CanvasTestCase { } function test_stroke(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#0f0'; @@ -662,6 +668,7 @@ CanvasTestCase { } function test_clip(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -784,6 +791,7 @@ CanvasTestCase { function test_moveTo(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -839,6 +847,7 @@ CanvasTestCase { } function test_lineTo(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -904,6 +913,7 @@ CanvasTestCase { } function test_bezierCurveTo(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -1072,6 +1082,7 @@ CanvasTestCase { } function test_quadraticCurveTo(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -1173,6 +1184,7 @@ CanvasTestCase { } function test_rect(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -1371,6 +1383,7 @@ CanvasTestCase { function test_clearRect(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#0f0'; @@ -1383,6 +1396,7 @@ CanvasTestCase { } function test_fillRect(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.beginPath(); @@ -1397,6 +1411,7 @@ CanvasTestCase { function test_strokeRect(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.beginPath(); @@ -1412,6 +1427,7 @@ CanvasTestCase { } function test_transform(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_pattern.qml b/tests/auto/quick/qquickcanvasitem/data/tst_pattern.qml index 1d7fd2c12fa..e0a4d7ad235 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_pattern.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_pattern.qml @@ -6,36 +6,42 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_basic(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_animated(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_image(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_modified(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_paint(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_repeat(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_pixel.qml b/tests/auto/quick/qquickcanvasitem/data/tst_pixel.qml index 281264ba92d..ef908db92ae 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_pixel.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_pixel.qml @@ -7,6 +7,7 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_createImageData(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); var imageData = ctx.createImageData(1, 1); var imageDataValues = imageData.data; @@ -20,24 +21,28 @@ CanvasTestCase { } function test_getImageData(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_object(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_putImageData(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_filters(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_shadow.qml b/tests/auto/quick/qquickcanvasitem/data/tst_shadow.qml index 2baaa072d06..14318b3f567 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_shadow.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_shadow.qml @@ -6,12 +6,14 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_basic(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_blur(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() @@ -19,6 +21,7 @@ CanvasTestCase { function test_clip(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() @@ -26,6 +29,7 @@ CanvasTestCase { function test_composite(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() @@ -33,6 +37,7 @@ CanvasTestCase { function test_enable(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() @@ -40,36 +45,42 @@ CanvasTestCase { function test_gradient(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_image(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_offset(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_pattern(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_stroke(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_tranform(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_state.qml b/tests/auto/quick/qquickcanvasitem/data/tst_state.qml index 18464def7ce..ce02f9d7f7c 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_state.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_state.qml @@ -6,6 +6,7 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_bitmap(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -19,6 +20,7 @@ CanvasTestCase { } function test_clip(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -35,6 +37,7 @@ CanvasTestCase { } function test_fillStyle(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); // Test that restore() undoes any modifications @@ -56,6 +59,7 @@ CanvasTestCase { } function test_font(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -78,6 +82,7 @@ CanvasTestCase { } function test_globalAlpha(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -100,6 +105,7 @@ CanvasTestCase { } function test_globalCompositeOperation(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -122,6 +128,7 @@ CanvasTestCase { } function test_lineCap(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -144,6 +151,7 @@ CanvasTestCase { } function test_lineJoin(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -166,6 +174,7 @@ CanvasTestCase { } function test_lineWidth(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -188,6 +197,7 @@ CanvasTestCase { } function test_miterLimit(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -210,6 +220,7 @@ CanvasTestCase { } function test_path(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -225,6 +236,7 @@ CanvasTestCase { } function test_shadow(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -295,6 +307,7 @@ CanvasTestCase { } function test_stack(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -330,6 +343,7 @@ CanvasTestCase { } function test_strokeStyle(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -353,6 +367,7 @@ CanvasTestCase { function test_text(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -392,6 +407,7 @@ CanvasTestCase { function test_transform(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_strokeStyle.qml b/tests/auto/quick/qquickcanvasitem/data/tst_strokeStyle.qml index a3f1ab0a9bb..0dc39b8b4ce 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_strokeStyle.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_strokeStyle.qml @@ -8,6 +8,7 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_default(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); compare(ctx.strokeStyle, "#000000") @@ -17,6 +18,7 @@ CanvasTestCase { } function test_saverestore(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); var old = ctx.strokeStyle; ctx.save(); @@ -33,6 +35,7 @@ CanvasTestCase { } function test_namedColor(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.strokeStyle = "red"; @@ -50,6 +53,7 @@ CanvasTestCase { } function test_colorFromObjectToString(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -68,6 +72,7 @@ CanvasTestCase { } function test_withInvalidColor(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml b/tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml index 2b39357beda..011fbd497bc 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_svgpath.qml @@ -6,6 +6,7 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_svgpath(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); var svgs = [ // Absolute coordinates, explicit commands. diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_text.qml b/tests/auto/quick/qquickcanvasitem/data/tst_text.qml index bfc40670405..f7cd66890b5 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_text.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_text.qml @@ -6,36 +6,42 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_baseLine(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_align(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_stroke(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_fill(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_font(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() } function test_measure(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); canvas.destroy() diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_transform.qml b/tests/auto/quick/qquickcanvasitem/data/tst_transform.qml index b2f5b51fa58..bbfec6a1068 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_transform.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_transform.qml @@ -6,6 +6,7 @@ CanvasTestCase { function init_data() { return testData("2d"); } function test_order(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -20,6 +21,7 @@ CanvasTestCase { } function test_rotate(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -90,6 +92,7 @@ CanvasTestCase { } function test_scale(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); @@ -182,6 +185,7 @@ CanvasTestCase { } function test_setTransform(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -325,6 +329,7 @@ CanvasTestCase { } function test_transform(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; @@ -460,6 +465,7 @@ CanvasTestCase { } function test_translate(row) { var canvas = createCanvasObject(row); + tryVerify(function() { return canvas.available; }); var ctx = canvas.getContext('2d'); ctx.reset(); ctx.fillStyle = '#f00'; diff --git a/tests/auto/quick/qquickdeliveryagent/BLACKLIST b/tests/auto/quick/qquickdeliveryagent/BLACKLIST new file mode 100644 index 00000000000..8d1da7a79e9 --- /dev/null +++ b/tests/auto/quick/qquickdeliveryagent/BLACKLIST @@ -0,0 +1,8 @@ +# QTBUG-103080 +[passiveGrabberOrder] +android + +# QTBUG-100991 +[touchCompression] +android + diff --git a/tests/auto/quick/qquickdeliveryagent/CMakeLists.txt b/tests/auto/quick/qquickdeliveryagent/CMakeLists.txt index 1a5490effac..3426903bb14 100644 --- a/tests/auto/quick/qquickdeliveryagent/CMakeLists.txt +++ b/tests/auto/quick/qquickdeliveryagent/CMakeLists.txt @@ -10,21 +10,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickdeliveryagent SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickdeliveryagent.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickdeliveryagent/data/listViewDelegate.qml b/tests/auto/quick/qquickdeliveryagent/data/listViewDelegate.qml new file mode 100644 index 00000000000..bdb72464508 --- /dev/null +++ b/tests/auto/quick/qquickdeliveryagent/data/listViewDelegate.qml @@ -0,0 +1,21 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick + +Item { + id: root + width: 320 + height: 240 + + ListView { + id: listView + width: 320 + height: 240 + delegate: Rectangle { + width: ListView.view.width + height: ListView.view.height / ListView.view.count + color: "tomato" + } + } +} diff --git a/tests/auto/quick/qquickdeliveryagent/data/pointHandler.qml b/tests/auto/quick/qquickdeliveryagent/data/pointHandler.qml new file mode 100644 index 00000000000..a8afa8f78ae --- /dev/null +++ b/tests/auto/quick/qquickdeliveryagent/data/pointHandler.qml @@ -0,0 +1,17 @@ +import QtQuick + +Rectangle { + id: root + objectName: "root" + color: ph.active ? "coral" : "cadetblue" + border.color: "black" + width: 100; height: 100 + PointHandler { + id: ph + objectName: root.objectName + "PointHandler" + } + Text { + anchors.centerIn: parent + text: ph.point.position.x.toFixed(1) + ", " + ph.point.position.y.toFixed(1) + } +} diff --git a/tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp b/tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp index 18a0fb54aea..d0e29b3a659 100644 --- a/tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp +++ b/tests/auto/quick/qquickdeliveryagent/tst_qquickdeliveryagent.cpp @@ -35,12 +35,16 @@ #include <QtQuick/QQuickView> #include <QtQuick/QQuickWindow> #include <QtQuick/private/qquickflickable_p.h> +#include <QtQuick/private/qquicklistview_p.h> +#include <QtQuick/private/qquickpointhandler_p.h> #include <QtQuick/private/qquickshadereffectsource_p.h> #include <QtQuick/private/qquicktaphandler_p.h> #include <QtQuick/private/qquickwindow_p.h> -#include "../../shared/util.h" -#include "../shared/visualtestutil.h" -#include "../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> + +#include <QtGui/private/qeventpoint_p.h> Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") @@ -59,6 +63,26 @@ struct ViewportTransformHelper : public QQuickDeliveryAgent::Transform } }; +struct HoverItem : public QQuickItem +{ + HoverItem(QQuickItem *parent) : QQuickItem(parent){} + void hoverEnterEvent(QHoverEvent *e) override + { + hoverEnter = true; + e->setAccepted(block); + } + + void hoverLeaveEvent(QHoverEvent *e) override + { + hoverLeave = true; + e->setAccepted(block); + } + + bool hoverEnter = false; + bool hoverLeave = false; + bool block = false; +}; + // A QQuick3DViewport simulator class SubsceneRootItem : public QQuickShaderEffectSource { @@ -124,12 +148,18 @@ class tst_qquickdeliveryagent : public QQmlDataTest Q_OBJECT public: tst_qquickdeliveryagent() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } private slots: void passiveGrabberOrder(); void tapHandlerDoesntOverrideSubsceneGrabber(); + void undoDelegationWhenSubsceneFocusCleared(); + void touchCompression(); + void hoverPropagation_nested_data(); + void hoverPropagation_nested(); + void hoverPropagation_siblings(); private: QScopedPointer<QPointingDevice> touchDevice = QScopedPointer<QPointingDevice>(QTest::createTouchDevice()); @@ -158,7 +188,7 @@ void tst_qquickdeliveryagent::passiveGrabberOrder() windowAgent->setObjectName("window"); QVERIFY(subscene.deliveryAgent); QVERIFY(subscene.deliveryAgent != windowAgent); - QQuickVisualTestUtil::SignalMultiSpy spy; + QQuickVisualTestUtils::SignalMultiSpy spy; QVERIFY(spy.connectToSignal(rootTap, &QQuickTapHandler::tapped)); QVERIFY(spy.connectToSignal(subsceneTap, &QQuickTapHandler::tapped)); @@ -221,6 +251,151 @@ void tst_qquickdeliveryagent::tapHandlerDoesntOverrideSubsceneGrabber() // QTBUG QCOMPARE(clickSpy.count(), 0); // doesn't tap } +void tst_qquickdeliveryagent::undoDelegationWhenSubsceneFocusCleared() // QTBUG-105192 +{ + QQuickView window; +#ifdef DISABLE_HOVER_IN_IRRELEVANT_TESTS + QQuickWindowPrivate::get(&window)->deliveryAgentPrivate()->frameSynchronousHoverEnabled = false; +#endif + QVERIFY(QQuickTest::initView(window, testFileUrl("listViewDelegate.qml"))); + QQuickListView *listView = window.rootObject()->findChild<QQuickListView*>(); + QVERIFY(listView); + + // put the ListView into a SubsceneRootItem + SubsceneRootItem subscene(listView, listView->boundingRect(), window.rootObject()); + + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + // populate a delegate in ListView + listView->setModel(1); + QQuickItem *delegate = nullptr; + QTRY_VERIFY(QQuickVisualTestUtils::findViewDelegateItem(listView, 0, delegate)); + QCOMPARE(QQuickWindowPrivate::get(&window)->deliveryAgentPrivate()->activeFocusItem, delegate); + delete listView; + QVERIFY(QQuickWindowPrivate::get(&window)->deliveryAgentPrivate()->activeFocusItem != delegate); +} + +void tst_qquickdeliveryagent::touchCompression() +{ + QQuickView window; + // avoid interference from X11 window managers, so we can look at eventpoint globalPosition + window.setFlag(Qt::FramelessWindowHint); +#ifdef DISABLE_HOVER_IN_IRRELEVANT_TESTS + QQuickWindowPrivate::get(&window)->deliveryAgentPrivate()->frameSynchronousHoverEnabled = false; +#endif + QVERIFY(QQuickTest::showView(window, testFileUrl("pointHandler.qml"))); + QQuickDeliveryAgent *windowAgent = QQuickWindowPrivate::get(&window)->deliveryAgent; + QQuickDeliveryAgentPrivate *agentPriv = static_cast<QQuickDeliveryAgentPrivate *>(QQuickDeliveryAgentPrivate::get(windowAgent)); + QQuickItem *root = qobject_cast<QQuickItem*>(window.rootObject()); + QVERIFY(root); + QQuickPointHandler *rootHandler = root->findChild<QQuickPointHandler *>(); + QVERIFY(rootHandler); + QTest::QTouchEventSequence touch = QTest::touchEvent(&window, touchDevice.data()); + QPoint pt1(30, 50); + QPoint pt2(70, 50); + // Press and drag fast, alternating moving and stationary points + touch.press(11, pt1).press(12, pt2).commit(); + QQuickTouchUtils::flush(&window); + QTest::qWait(50); // not critical, but let it hopefully render a frame or two + QCOMPARE(agentPriv->compressedTouchCount, 0); + for (int m = 1; m < 4; ++m) { + pt1 += {0, 1}; + pt2 -= {0, 1}; + if (m % 2) + touch.move(11, pt1).stationary(12).commit(); + else + touch.stationary(11).move(12, pt2).commit(); + // don't call QQuickTouchUtils::flush() here: we want to see the compression happen + if (agentPriv->compressedTouchCount) { + if (m % 2) { + QCOMPARE(agentPriv->delayedTouch->point(0).position().toPoint(), pt1); + QCOMPARE(agentPriv->delayedTouch->point(0).globalPosition().toPoint(), root->mapToGlobal(pt1).toPoint()); + } else { + QCOMPARE(agentPriv->delayedTouch->point(1).position().toPoint(), pt2); + QCOMPARE(agentPriv->delayedTouch->point(1).globalPosition().toPoint(), root->mapToGlobal(pt2).toPoint()); + } + } + // we can't guarantee that a CI VM is fast enough, but usually compressedTouchCount == m + qCDebug(lcTests) << "compressedTouchCount" << agentPriv->compressedTouchCount << "expected" << m; + qCDebug(lcTests) << "PointHandler still sees" << rootHandler->point().position() << "while" << pt1 << "was likely not yet delivered"; + } + QTRY_COMPARE(rootHandler->point().position().toPoint(), pt1); + touch.release(11, pt1).release(12, pt2).commit(); + // should be delivered, bypassing compression; when PointHandler gets the release, it will reset its point + QTRY_COMPARE(rootHandler->active(), false); + QCOMPARE(rootHandler->point().position(), QPointF()); + QCOMPARE(agentPriv->compressedTouchCount, 0); +} + +void tst_qquickdeliveryagent::hoverPropagation_nested_data() +{ + QTest::addColumn<bool>("block"); + QTest::newRow("block=false") << false; + QTest::newRow("block=true") << true; +} + +void tst_qquickdeliveryagent::hoverPropagation_nested() +{ + QFETCH(bool, block); + + QQuickWindow window; + window.resize(200, 200); + window.show(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + + HoverItem child(window.contentItem()); + child.setAcceptHoverEvents(true); + child.setWidth(100); + child.setHeight(100); + + HoverItem grandChild(&child); + grandChild.setAcceptHoverEvents(true); + grandChild.block = block; + grandChild.setWidth(100); + grandChild.setHeight(100); + + // Start by moving the mouse to the window + QTest::mouseMove(&window, QPoint(150, 150)); + QCOMPARE(child.hoverEnter, false); + QCOMPARE(grandChild.hoverEnter, false); + + // Move the mouse inside the items. If block is true, only + // the grandchild should be hovered. Otherwise both. + QTest::mouseMove(&window, QPoint(50, 50)); + QCOMPARE(child.hoverEnter, !block); + QCOMPARE(grandChild.hoverEnter, true); +} + +void tst_qquickdeliveryagent::hoverPropagation_siblings() +{ + QQuickWindow window; + window.resize(200, 200); + window.show(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + + HoverItem sibling1(window.contentItem()); + sibling1.setAcceptHoverEvents(true); + sibling1.setWidth(100); + sibling1.setHeight(100); + + HoverItem sibling2(window.contentItem()); + sibling2.setAcceptHoverEvents(true); + sibling2.setWidth(100); + sibling2.setHeight(100); + + // Start by moving the mouse to the window + QTest::mouseMove(&window, QPoint(150, 150)); + QCOMPARE(sibling1.hoverEnter, false); + QCOMPARE(sibling2.hoverEnter, false); + + // Move the mouse inside the items. Only the + // sibling on the top should receive hover + QTest::mouseMove(&window, QPoint(50, 50)); + QCOMPARE(sibling1.hoverEnter, false); + QCOMPARE(sibling2.hoverEnter, true); +} + QTEST_MAIN(tst_qquickdeliveryagent) #include "tst_qquickdeliveryagent.moc" diff --git a/tests/auto/quick/qquickdesignersupport/CMakeLists.txt b/tests/auto/quick/qquickdesignersupport/CMakeLists.txt index 2cdb7328ce5..8c8a46ac551 100644 --- a/tests/auto/quick/qquickdesignersupport/CMakeLists.txt +++ b/tests/auto/quick/qquickdesignersupport/CMakeLists.txt @@ -12,22 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickdesignersupport SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickdesignersupport.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate - Qt::TestPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickdesignersupport/data/RecursiveProperty.qml b/tests/auto/quick/qquickdesignersupport/data/RecursiveProperty.qml new file mode 100644 index 00000000000..ec419f89355 --- /dev/null +++ b/tests/auto/quick/qquickdesignersupport/data/RecursiveProperty.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +Item { + id: myObject + readonly property int testProperty: 0 + readonly property QtObject myproperty: myObject +} + diff --git a/tests/auto/quick/qquickdesignersupport/data/propertyNameTest.qml b/tests/auto/quick/qquickdesignersupport/data/propertyNameTest.qml new file mode 100644 index 00000000000..4815709d216 --- /dev/null +++ b/tests/auto/quick/qquickdesignersupport/data/propertyNameTest.qml @@ -0,0 +1,13 @@ +import QtQuick 2.11 + +Rectangle { + objectName: "rootItem" + color: "white" + width: 800 + height: 600 + + RecursiveProperty { + objectName: "recursiveProperty" + + } +} diff --git a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp index 18d6b6b5a76..7e9bcff00ae 100644 --- a/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp +++ b/tests/auto/quick/qquickdesignersupport/tst_qquickdesignersupport.cpp @@ -40,17 +40,16 @@ #include <private/qquickstategroup_p.h> #include <private/qquickpropertychanges_p.h> #include <private/qquickrectangle_p.h> -#include "../../shared/util.h" -#include "../shared/visualtestutil.h" -#include <QtTest/private/qemulationdetector_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> -using namespace QQuickVisualTestUtil; +using namespace QQuickVisualTestUtils; class tst_qquickdesignersupport : public QQmlDataTest { Q_OBJECT public: - tst_qquickdesignersupport() {} + tst_qquickdesignersupport() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void customData(); @@ -66,6 +65,7 @@ private slots: void testSimpleBindings(); void testDotProperties(); void testItemReparenting(); + void testPropertyNames(); }; @@ -129,9 +129,6 @@ static void removeObjectFromList(const QQmlProperty &property, QObject *objectTo void tst_qquickdesignersupport::customData() { -#ifdef Q_CC_MINGW - QSKIP("QQuickDesignerSupportProperties::registerCustomData segfaults on mingw. QTBUG-90869"); -#endif QScopedPointer<QQuickView> view(new QQuickView); view->engine()->setOutputWarningsToStandardError(false); view->setSource(testFileUrl("test.qml")); @@ -188,9 +185,6 @@ void tst_qquickdesignersupport::customData() void tst_qquickdesignersupport::customDataBindings() { -#ifdef Q_CC_MINGW - QSKIP("QQuickDesignerSupportProperties::registerCustomData segfaults on mingw. QTBUG-90869"); -#endif QScopedPointer<QQuickView> view(new QQuickView); view->engine()->setOutputWarningsToStandardError(false); view->setSource(testFileUrl("test.qml")); @@ -670,12 +664,6 @@ void tst_qquickdesignersupport::testComponentOnCompleteSignal() void tst_qquickdesignersupport::testSimpleBindings() { - if (QTestPrivate::isRunningArmOnX86()) - QSKIP("Crashes in QEMU. (QTBUG-90869)"); -#ifdef Q_CC_MINGW - QSKIP("QQuickDesignerSupportProperties::registerCustomData segfaults on mingw. QTBUG-90869"); -#endif - QScopedPointer<QQuickView> view(new QQuickView); view->engine()->setOutputWarningsToStandardError(false); view->setSource(testFileUrl("bindingTest.qml")); @@ -717,12 +705,6 @@ void tst_qquickdesignersupport::testSimpleBindings() void tst_qquickdesignersupport::testDotProperties() { - if (QTestPrivate::isRunningArmOnX86()) - QSKIP("Crashes in QEMU. (QTBUG-90869)"); -#ifdef Q_CC_MINGW - QSKIP("QQuickDesignerSupportProperties::registerCustomData segfaults on mingw. QTBUG-90869"); -#endif - QScopedPointer<QQuickView> view(new QQuickView); view->engine()->setOutputWarningsToStandardError(false); view->setSource(testFileUrl("bindingTest.qml")); @@ -752,11 +734,6 @@ void tst_qquickdesignersupport::testDotProperties() void tst_qquickdesignersupport::testItemReparenting() { - if (QTestPrivate::isRunningArmOnX86()) - QSKIP("Crashes in QEMU. (QTBUG-90869)"); -#ifdef Q_CC_MINGW - QSKIP("QQuickDesignerSupportProperties::registerCustomData segfaults on mingw. QTBUG-90869"); -#endif QScopedPointer<QQuickView> view(new QQuickView); view->engine()->setOutputWarningsToStandardError(false); @@ -786,6 +763,46 @@ void tst_qquickdesignersupport::testItemReparenting() QCOMPARE(text->parentItem(), item); } +void tst_qquickdesignersupport::testPropertyNames() +{ + QScopedPointer<QQuickView> view(new QQuickView); + view->engine()->setOutputWarningsToStandardError(false); + view->setSource(testFileUrl("propertyNameTest.qml")); + + QVERIFY(view->errors().isEmpty()); + QQuickItem *rootItem = view->rootObject(); + QVERIFY(rootItem); + + QQuickDesignerSupport::PropertyNameList names = QQuickDesignerSupportProperties::allPropertyNames(rootItem); + QVERIFY(!names.isEmpty()); + QVERIFY(names.contains("width")); + QVERIFY(names.contains("height")); + QVERIFY(names.contains("clip")); + QVERIFY(names.contains("childrenRect")); + QVERIFY(names.contains("activeFocus")); + QVERIFY(names.contains("border.width")); + names = QQuickDesignerSupportProperties::propertyNameListForWritableProperties(rootItem); + QVERIFY(!names.isEmpty()); + QVERIFY(names.contains("width")); + QVERIFY(names.contains("height")); + QVERIFY(names.contains("opacity")); + QVERIFY(!names.contains("childrenRect")); + QVERIFY(!names.contains("childrenRect")); + QVERIFY(!names.contains("activeFocus")); + QVERIFY(names.contains("border.width")); + + QQuickItem *recursiveProperty = findItem<QQuickItem>(rootItem, QLatin1String("recursiveProperty")); + QVERIFY(recursiveProperty); + names = QQuickDesignerSupportProperties::allPropertyNames(recursiveProperty); + QVERIFY(!names.isEmpty()); + QVERIFY(names.contains("testProperty")); + QVERIFY(names.contains("myproperty.testProperty")); + + names = QQuickDesignerSupportProperties::propertyNameListForWritableProperties(recursiveProperty); + QVERIFY(!names.isEmpty()); + QVERIFY(!names.contains("testProperty")); +} + QTEST_MAIN(tst_qquickdesignersupport) #include "tst_qquickdesignersupport.moc" diff --git a/tests/auto/quick/qquickdrag/BLACKLIST b/tests/auto/quick/qquickdrag/BLACKLIST new file mode 100644 index 00000000000..71cc97fc7ad --- /dev/null +++ b/tests/auto/quick/qquickdrag/BLACKLIST @@ -0,0 +1,25 @@ +# QTBUG-103082 +[active] +android +[setActive] +android +[drop] +android +[move] +android +[parentChange] +android +[hotSpot] +android +[supportedActions] +android +[proposedAction] +android +[keys] +android +[source] +android +[recursion] +android +[noCrashWithImageProvider] +android diff --git a/tests/auto/quick/qquickdroparea/BLACKLIST b/tests/auto/quick/qquickdroparea/BLACKLIST new file mode 100644 index 00000000000..61650f3308c --- /dev/null +++ b/tests/auto/quick/qquickdroparea/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-103083 +[signalOrder] +android diff --git a/tests/auto/quick/qquickdroparea/CMakeLists.txt b/tests/auto/quick/qquickdroparea/CMakeLists.txt index d66bf237145..2427994b4d3 100644 --- a/tests/auto/quick/qquickdroparea/CMakeLists.txt +++ b/tests/auto/quick/qquickdroparea/CMakeLists.txt @@ -12,15 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickdroparea SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickdroparea.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -28,6 +20,7 @@ qt_internal_add_test(tst_qquickdroparea Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickdroparea/data/ignoreRetriggerEvent.qml b/tests/auto/quick/qquickdroparea/data/ignoreRetriggerEvent.qml new file mode 100644 index 00000000000..af25a04ee76 --- /dev/null +++ b/tests/auto/quick/qquickdroparea/data/ignoreRetriggerEvent.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +DropArea { + property int enterEvents: 0 + property int exitEvents: 0 + width: 100; height: 100 + objectName: "dropArea" + onEntered: function (drag) { ++enterEvents; drag.accepted = false } + onExited: {++exitEvents} + Item { + objectName: "dragItem" + x: 50; y: 50 + width: 10; height: 10 + } +} diff --git a/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp b/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp index 593f3a0efbc..9c9d059a52c 100644 --- a/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp +++ b/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp @@ -37,8 +37,8 @@ #include <qpa/qplatformdrag.h> #include <qpa/qwindowsysteminterface.h> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> template <typename T> static T evaluate(QObject *scope, const QString &expression) { @@ -60,9 +60,16 @@ template <> void evaluate<void>(QObject *scope, const QString &expression) class tst_QQuickDropArea: public QQmlDataTest { Q_OBJECT + +public: + tst_QQuickDropArea(); + private slots: void containsDrag_internal(); void containsDrag_external(); + + void ignoreRetriggerEvent(); + void keys_internal(); void keys_external(); void source_internal(); @@ -76,11 +83,17 @@ private slots: void dropStuff(); void nestedDropAreas_data(); void nestedDropAreas(); + void signalOrder(); private: QQmlEngine engine; }; +tst_QQuickDropArea::tst_QQuickDropArea() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QQuickDropArea::containsDrag_internal() { QQuickWindow window; @@ -819,6 +832,32 @@ void tst_QQuickDropArea::competingDrags() QCOMPARE(evaluate<QString>(dropArea1, "statuslol"), QStringLiteral("parent")); } +void tst_QQuickDropArea::ignoreRetriggerEvent() +{ + QQuickView window; + QByteArray errorMessage; + QVERIFY2(QQuickTest::initView(window, testFileUrl("ignoreRetriggerEvent.qml"), true, &errorMessage), errorMessage.constData()); + + QQuickItem *dropArea = window.rootObject(); + QVERIFY(dropArea); + QQuickItem *dragItem = dropArea->findChild<QQuickItem *>("dragItem"); + QVERIFY(dragItem); + + evaluate<void>(dragItem, "Drag.active = true"); + // Drag the item within the drop area + dragItem->setPosition(QPointF(25, 25)); + QCoreApplication::processEvents(); + dragItem->setPosition(QPointF(50, 50)); + QCoreApplication::processEvents(); + dragItem->setPosition(QPointF(75, 75)); + QCoreApplication::processEvents(); + + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0); +} + + void tst_QQuickDropArea::simultaneousDrags() { QQuickWindow window; @@ -949,8 +988,8 @@ void tst_QQuickDropArea::simultaneousDrags() Qt::MouseButtons(), Qt::KeyboardModifiers()); //Same as in the first case, dropArea2 already contains a drag, dropArea1 will get the event QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1); - QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1); QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); @@ -958,8 +997,8 @@ void tst_QQuickDropArea::simultaneousDrags() QWindowSystemInterface::handleDrag(&alternateWindow, &data, QPoint(50, 50), Qt::CopyAction, Qt::MouseButtons(), Qt::KeyboardModifiers()); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); - QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1); - QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 2); QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); @@ -967,16 +1006,16 @@ void tst_QQuickDropArea::simultaneousDrags() QWindowSystemInterface::handleDrag(&window, &data, QPoint(50, 50), Qt::CopyAction, Qt::MouseButtons(), Qt::KeyboardModifiers()); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2); - QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 4); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 3); QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); evaluate<void>(dragItem1, "Drag.active = false"); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2); - QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 4); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 3); QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1); @@ -1281,6 +1320,48 @@ void tst_QQuickDropArea::nestedDropAreas() QCOMPARE(window.rootObject()->property("innerExitEvents"), 2); } +void tst_QQuickDropArea::signalOrder() +{ + QQuickWindow window; + QQmlComponent component(&engine); + component.setData("import QtQuick\n" + "Item {\n" + " id: root\n" + " property var eventOrder: []\n" + " DropArea {\n" + " width: 100; height: 100\n" + " x: 0; y: 0\n" + " onEntered: eventOrder.push('entered1');\n" + " onExited: eventOrder.push('exited1');\n" + " }\n" + " DropArea {\n" + " width: 100; height: 100\n" + " x: 0; y: 100\n" + " onEntered: eventOrder.push('entered2');\n" + " onExited: eventOrder.push('exited2');\n" + " }\n" + "}", + QUrl()); + + QScopedPointer<QObject> object(component.create()); + QQuickItem *item = qobject_cast<QQuickItem *>(object.data()); + QVERIFY(item); + item->setParentItem(window.contentItem()); + + QMimeData data; + + QWindowSystemInterface::handleDrag(&window, &data, QPoint(50, 50), Qt::CopyAction, + Qt::MouseButtons(), Qt::KeyboardModifiers()); + QWindowSystemInterface::handleDrag(&window, &data, QPoint(50, 150), Qt::CopyAction, + Qt::MouseButtons(), Qt::KeyboardModifiers()); + QWindowSystemInterface::handleDrag(&window, &data, QPoint(50, 250), Qt::CopyAction, + Qt::MouseButtons(), Qt::KeyboardModifiers()); + + const QList<QVariant> eventOrder = item->property("eventOrder").toList(); + QCOMPARE(eventOrder, + QList<QVariant>({ u"entered1"_qs, u"exited1"_qs, u"entered2"_qs, u"exited2"_qs })); +} + QTEST_MAIN(tst_QQuickDropArea) #include "tst_qquickdroparea.moc" diff --git a/tests/auto/quick/qquickdynamicpropertyanimation/CMakeLists.txt b/tests/auto/quick/qquickdynamicpropertyanimation/CMakeLists.txt index 78395e4661e..75ab9332d05 100644 --- a/tests/auto/quick/qquickdynamicpropertyanimation/CMakeLists.txt +++ b/tests/auto/quick/qquickdynamicpropertyanimation/CMakeLists.txt @@ -12,14 +12,12 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickdynamicpropertyanimation SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickdynamicpropertyanimation.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Qml Qt::Quick + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickdynamicpropertyanimation/tst_qquickdynamicpropertyanimation.cpp b/tests/auto/quick/qquickdynamicpropertyanimation/tst_qquickdynamicpropertyanimation.cpp index 5251c5aff32..1b1f664841b 100644 --- a/tests/auto/quick/qquickdynamicpropertyanimation/tst_qquickdynamicpropertyanimation.cpp +++ b/tests/auto/quick/qquickdynamicpropertyanimation/tst_qquickdynamicpropertyanimation.cpp @@ -36,13 +36,13 @@ #include <QtCore/QRect> #include <QtGui/QColor> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickdynamicpropertyanimation : public QQmlDataTest { Q_OBJECT public: - tst_qquickdynamicpropertyanimation() {} + tst_qquickdynamicpropertyanimation() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private: template<class T> diff --git a/tests/auto/quick/qquickflickable/CMakeLists.txt b/tests/auto/quick/qquickflickable/CMakeLists.txt index 7c8e802daf5..737ddb2d5dd 100644 --- a/tests/auto/quick/qquickflickable/CMakeLists.txt +++ b/tests/auto/quick/qquickflickable/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickflickable SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickflickable.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickflickable/data/contentPosWhileDragging.qml b/tests/auto/quick/qquickflickable/data/contentPosWhileDragging.qml new file mode 100644 index 00000000000..b42fbc1adbe --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/contentPosWhileDragging.qml @@ -0,0 +1,24 @@ +import QtQuick +import QtQuick.Shapes +import QtQuick.Controls + +Item { + id: root + width: 500 + height: 500 + Flickable { + anchors.centerIn: parent + width: 100 + height: 100 + clip: true + contentWidth: content.width + contentHeight: content.height + Rectangle { + id: content + width: 320 + height: width + color: "#41cd52" + radius: width/2 + } + } +} diff --git a/tests/auto/quick/qquickflickable/data/dragon.qml b/tests/auto/quick/qquickflickable/data/dragon.qml new file mode 100644 index 00000000000..b82477453bf --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/dragon.qml @@ -0,0 +1,15 @@ +import QtQuick 2.12 + +Flickable { + id: flick + width: 320 + height: 320 + contentWidth: 500 + contentHeight: 500 + Text { + anchors.centerIn: parent + font.pixelSize: 50 + text: "🐉" + color: flick.dragging ? "orange" : "grey" + } +} diff --git a/tests/auto/quick/qquickflickable/data/flickableWithTapHandler.qml b/tests/auto/quick/qquickflickable/data/flickableWithTapHandler.qml new file mode 100644 index 00000000000..91b81059ab3 --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/flickableWithTapHandler.qml @@ -0,0 +1,24 @@ +import QtQuick + +Item { + width: 300 + height: 300 + + Flickable { + anchors.fill: parent + anchors.topMargin: 100 + contentWidth: 1000 + contentHeight: 1000 + + Rectangle { + objectName: "childItem" + x: 20 + y: 50 + width: 20 + height: 20 + color: "red" + TapHandler { + } + } + } +} diff --git a/tests/auto/quick/qquickflickable/data/fractionalExtent.qml b/tests/auto/quick/qquickflickable/data/fractionalExtent.qml new file mode 100644 index 00000000000..2675e8c85a4 --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/fractionalExtent.qml @@ -0,0 +1,14 @@ +import QtQuick + +Flickable { + width: 300 + height: 300 + contentWidth: content.width; contentHeight: content.height + Rectangle { + id: content + width: 350 + height: 350 + color: "darkkhaki" + } + boundsBehavior: Flickable.StopAtBounds +} diff --git a/tests/auto/quick/qquickflickable/data/nestedmouseareapce.qml b/tests/auto/quick/qquickflickable/data/nestedmouseareapce.qml new file mode 100644 index 00000000000..b36df04d457 --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/nestedmouseareapce.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +Flickable { + id: outer + objectName: "flickable" + width: 400 + height: 400 + contentX: 50 + contentY: 50 + contentWidth: 500 + contentHeight: 500 + + Rectangle { + objectName: "nested" + x: 100 + y: 100 + width: 300 + height: 300 + + color: "yellow" + MouseArea { + anchors.fill: parent + propagateComposedEvents: true + } + } +} diff --git a/tests/auto/quick/qquickflickable/data/rotatedFlickable.qml b/tests/auto/quick/qquickflickable/data/rotatedFlickable.qml new file mode 100644 index 00000000000..04816c178b0 --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/rotatedFlickable.qml @@ -0,0 +1,32 @@ +import QtQuick 2.0 + +Item { + width: 300 + height: 300 + + Flickable { + id: flickable + anchors.fill: parent + contentHeight: column.height + flickDeceleration: 5000 // speed up the test run + + Column { + id: column + width: parent.width + + Repeater { + model: 255 + + delegate: Rectangle { + width: column.width + height: 50 + color: "gray" + Text { + anchors.centerIn: parent + text: index + } + } + } + } + } +} diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 3d57cae9da6..8d4c8dfec7a 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -26,28 +26,31 @@ ** ****************************************************************************/ #include <qtest.h> +#include <QtTest/QtTest> #include <QtTest/QSignalSpy> +#include <QtQuick/qquickview.h> +#include <QtQuickTest/QtQuickTest> #include <QtGui/QStyleHints> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcomponent.h> -#include <QtQuick/qquickview.h> #include <private/qquickflickable_p.h> #include <private/qquickflickable_p_p.h> #include <private/qquickmousearea_p.h> #include <private/qquicktransition_p.h> #include <private/qqmlvaluetype_p.h> +#include <private/qquicktaphandler_p.h> #include <math.h> -#include "../../shared/util.h" -#include "../shared/geometrytestutil.h" -#include "../shared/viewtestutil.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/geometrytestutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> #include <qpa/qwindowsysteminterface.h> Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") -using namespace QQuickViewTestUtil; -using namespace QQuickVisualTestUtil; +using namespace QQuickViewTestUtils; +using namespace QQuickVisualTestUtils; // an abstract Slider which only handles touch events class TouchDragArea : public QQuickItem @@ -142,11 +145,38 @@ class TouchDragArea : public QQuickItem bool m_active; }; +class FlickableWithExtents : public QQuickFlickable +{ +public: + qreal extent = 10; + + qreal minXExtent() const override + { + return QQuickFlickable::minXExtent() + extent; + } + + qreal maxXExtent() const override + { + return QQuickFlickable::maxXExtent() + extent; + } + + qreal minYExtent() const override + { + return QQuickFlickable::minYExtent() + extent; + } + + qreal maxYExtent() const override + { + return QQuickFlickable::maxYExtent() + extent; + } +}; + class tst_qquickflickable : public QQmlDataTest { Q_OBJECT public: tst_qquickflickable() + : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: @@ -177,6 +207,7 @@ private slots: void movingAndDragging_data(); void flickOnRelease(); void pressWhileFlicking(); + void dragWhileFlicking(); void disabled(); void flickVelocity(); void margins(); @@ -189,6 +220,7 @@ private slots: void stopAtBounds(); void stopAtBounds_data(); void nestedMouseAreaUsingTouch(); + void nestedMouseAreaPropagateComposedEvents(); void nestedSliderUsingTouch(); void nestedSliderUsingTouch_data(); void pressDelayWithLoader(); @@ -205,6 +237,18 @@ private slots: void synchronousDrag(); void visibleAreaBinding(); void parallelTouch(); + void ignoreNonLeftMouseButtons(); + void ignoreNonLeftMouseButtons_data(); + void receiveTapOutsideContentItem(); + void flickWhenRotated_data(); + void flickWhenRotated(); + void flickAndReleaseOutsideBounds(); + void scrollingWithFractionalExtentSize_data(); + void scrollingWithFractionalExtentSize(); + void setContentPositionWhileDragging_data(); + void setContentPositionWhileDragging(); + void coalescedMove(); + void onlyOneMove(); private: void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to); @@ -365,8 +409,8 @@ void tst_qquickflickable::rebound() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("rebound.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); @@ -505,8 +549,8 @@ void tst_qquickflickable::pressDelay() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("pressDelay.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != nullptr); @@ -586,8 +630,8 @@ void tst_qquickflickable::nestedPressDelay() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("nestedPressDelay.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != nullptr); @@ -666,8 +710,8 @@ void tst_qquickflickable::filterReplayedPress() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("nestedPressDelay.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != nullptr); @@ -709,8 +753,8 @@ void tst_qquickflickable::nestedClickThenFlick() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("nestedClickThenFlick.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != nullptr); @@ -869,6 +913,7 @@ void tst_qquickflickable::wheel() QVERIFY(flick != nullptr); QQuickFlickablePrivate *fp = QQuickFlickablePrivate::get(flick); QSignalSpy moveEndSpy(flick, SIGNAL(movementEnded())); + quint64 timestamp = 10; // test a vertical flick { @@ -876,6 +921,7 @@ void tst_qquickflickable::wheel() QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(0,-120), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); event.setAccepted(false); + event.setTimestamp(timestamp); QGuiApplication::sendEvent(window.data(), &event); } @@ -886,6 +932,7 @@ void tst_qquickflickable::wheel() QCOMPARE(fp->velocityTimeline.isActive(), false); QCOMPARE(fp->timeline.isActive(), false); QTest::qWait(50); // make sure that onContentYChanged won't sneak in again + timestamp += 50; QCOMPARE(flick->property("movementsAfterEnd").value<int>(), 0); // QTBUG-55886 // get ready to test horizontal flick @@ -899,8 +946,8 @@ void tst_qquickflickable::wheel() QPoint pos(200, 200); QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(-120,0), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); - event.setAccepted(false); + event.setTimestamp(timestamp); QGuiApplication::sendEvent(window.data(), &event); } @@ -925,11 +972,13 @@ void tst_qquickflickable::trackpad() QVERIFY(flick != nullptr); QSignalSpy moveEndSpy(flick, SIGNAL(movementEnded())); QPoint pos(200, 200); + quint64 timestamp = 10; { QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(0,-100), QPoint(0,-120), Qt::NoButton, Qt::NoModifier, Qt::ScrollBegin, false); event.setAccepted(false); + event.setTimestamp(timestamp++); QGuiApplication::sendEvent(window.data(), &event); } @@ -943,6 +992,7 @@ void tst_qquickflickable::trackpad() QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(-100,0), QPoint(-120,0), Qt::NoButton, Qt::NoModifier, Qt::ScrollUpdate, false); event.setAccepted(false); + event.setTimestamp(timestamp++); QGuiApplication::sendEvent(window.data(), &event); } @@ -953,6 +1003,7 @@ void tst_qquickflickable::trackpad() QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(0,0), QPoint(0,0), Qt::NoButton, Qt::NoModifier, Qt::ScrollEnd, false); event.setAccepted(false); + event.setTimestamp(timestamp++); QGuiApplication::sendEvent(window.data(), &event); } @@ -1055,8 +1106,8 @@ void tst_qquickflickable::movingAndFlicking() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("flickable03.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != nullptr); @@ -1218,8 +1269,8 @@ void tst_qquickflickable::movingAndDragging() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("flickable03.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != nullptr); @@ -1421,8 +1472,8 @@ void tst_qquickflickable::pressWhileFlicking() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("flickable03.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != nullptr); @@ -1436,6 +1487,8 @@ void tst_qquickflickable::pressWhileFlicking() QSignalSpy hFlickSpy(flickable, SIGNAL(flickingHorizontallyChanged())); QSignalSpy vFlickSpy(flickable, SIGNAL(flickingVerticallyChanged())); QSignalSpy flickSpy(flickable, SIGNAL(flickingChanged())); + QSignalSpy flickStartSpy(flickable, &QQuickFlickable::flickStarted); + QSignalSpy flickEndSpy(flickable, &QQuickFlickable::flickEnded); // flick then press while it is still moving // flicking == false, moving == true; @@ -1453,6 +1506,8 @@ void tst_qquickflickable::pressWhileFlicking() QCOMPARE(vFlickSpy.count(), 1); QCOMPARE(hFlickSpy.count(), 0); QCOMPARE(flickSpy.count(), 1); + QCOMPARE(flickStartSpy.count(), 1); + QCOMPARE(flickEndSpy.count(), 0); QTest::mousePress(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(20, 50)); QTRY_VERIFY(!flickable->isFlicking()); @@ -1465,6 +1520,76 @@ void tst_qquickflickable::pressWhileFlicking() QVERIFY(!flickable->isFlickingVertically()); QTRY_VERIFY(!flickable->isMoving()); QVERIFY(!flickable->isMovingVertically()); + QCOMPARE(flickStartSpy.size(), 1); + QCOMPARE(flickEndSpy.size(), 1); + // Stop on a full pixel after user interaction + QCOMPARE(flickable->contentX(), (qreal)qRound(flickable->contentX())); +} + +void tst_qquickflickable::dragWhileFlicking() +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("flickable03.qml"))); + + QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window.rootObject()); + QVERIFY(flickable != nullptr); + + QSignalSpy vMoveSpy(flickable, &QQuickFlickable::movingVerticallyChanged); + QSignalSpy hMoveSpy(flickable, &QQuickFlickable::movingHorizontallyChanged); + QSignalSpy moveSpy(flickable, &QQuickFlickable::movingChanged); + QSignalSpy hFlickSpy(flickable, &QQuickFlickable::flickingHorizontallyChanged); + QSignalSpy vFlickSpy(flickable, &QQuickFlickable::flickingVerticallyChanged); + QSignalSpy flickSpy(flickable, &QQuickFlickable::flickingChanged); + QSignalSpy flickStartSpy(flickable, &QQuickFlickable::flickStarted); + QSignalSpy flickEndSpy(flickable, &QQuickFlickable::flickEnded); + + // flick first, let it keep moving + flick(&window, QPoint(20,190), QPoint(20, 50), 200); + QVERIFY(flickable->verticalVelocity() > 0.0); + QTRY_VERIFY(flickable->isFlicking()); + QVERIFY(flickable->isFlickingVertically()); + QCOMPARE(flickable->isFlickingHorizontally(), false); + QVERIFY(flickable->isMoving()); + QVERIFY(flickable->isMovingVertically()); + QCOMPARE(flickable->isMovingHorizontally(), false); + QCOMPARE(vMoveSpy.size(), 1); + QCOMPARE(hMoveSpy.size(), 0); + QCOMPARE(moveSpy.size(), 1); + QCOMPARE(vFlickSpy.size(), 1); + QCOMPARE(hFlickSpy.size(), 0); + QCOMPARE(flickSpy.size(), 1); + QCOMPARE(flickStartSpy.size(), 1); + QCOMPARE(flickEndSpy.size(), 0); + + // then drag slowly while it's still flicking and moving + const int dragStepDelay = 100; + QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, QPoint(20, 70)); + QTRY_COMPARE(flickable->isFlicking(), false); + QCOMPARE(flickable->isFlickingVertically(), false); + QVERIFY(flickable->isMoving()); + QVERIFY(flickable->isMovingVertically()); + + for (int y = 70; y > 50; y -= 5) { + QTest::mouseMove(&window, QPoint(20, y), dragStepDelay); + QVERIFY(flickable->isMoving()); + QVERIFY(flickable->isMovingVertically()); + // Flickable's timeline is real-time, so spoofing timestamps isn't enough + QTest::qWait(dragStepDelay); + } + + QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, QPoint(20, 50), dragStepDelay); + + QCOMPARE(flickable->isFlicking(), false); + QCOMPARE(flickable->isFlickingVertically(), false); + QTRY_COMPARE(flickable->isMoving(), false); + QCOMPARE(flickable->isMovingVertically(), false); + QCOMPARE(flickStartSpy.size(), 1); + QCOMPARE(flickEndSpy.size(), 1); + QCOMPARE(vMoveSpy.size(), 2); + QCOMPARE(hMoveSpy.size(), 0); + QCOMPARE(moveSpy.size(), 2); + QCOMPARE(vFlickSpy.size(), 2); + QCOMPARE(hFlickSpy.size(), 0); // Stop on a full pixel after user interaction QCOMPARE(flickable->contentX(), (qreal)qRound(flickable->contentX())); } @@ -1502,8 +1627,8 @@ void tst_qquickflickable::flickVelocity() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("flickable03.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != nullptr); @@ -1546,8 +1671,8 @@ void tst_qquickflickable::margins() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("margins.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->setTitle(QTest::currentTestFunction()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); @@ -1610,8 +1735,8 @@ void tst_qquickflickable::cancelOnHide() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("hide.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject()); @@ -1629,8 +1754,8 @@ void tst_qquickflickable::cancelOnMouseGrab() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("cancel.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != nullptr); @@ -1669,8 +1794,8 @@ void tst_qquickflickable::clickAndDragWhenTransformed() QScopedPointer<QQuickView> view(new QQuickView); view->setSource(testFileUrl("transformedFlickable.qml")); QTRY_COMPARE(view->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(view.data()); - QQuickViewTestUtil::moveMouseAway(view.data()); + QQuickVisualTestUtils::centerOnScreen(view.data()); + QQuickVisualTestUtils::moveMouseAway(view.data()); view->show(); QVERIFY(QTest::qWaitForWindowActive(view.data())); QVERIFY(view->rootObject() != nullptr); @@ -1723,8 +1848,8 @@ void tst_qquickflickable::flickTwiceUsingTouches() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("longList.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(window->rootObject() != nullptr); QVERIFY(QTest::qWaitForWindowActive(window.data())); @@ -1804,8 +1929,8 @@ void tst_qquickflickable::nestedStopAtBounds() QQuickView view; view.setSource(testFileUrl("nestedStopAtBounds.qml")); QTRY_COMPARE(view.status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(&view); - QQuickViewTestUtil::moveMouseAway(&view); + QQuickVisualTestUtils::centerOnScreen(&view); + QQuickVisualTestUtils::moveMouseAway(&view); view.show(); view.requestActivate(); QVERIFY(QTest::qWaitForWindowActive(&view)); @@ -1958,8 +2083,8 @@ void tst_qquickflickable::stopAtBounds() QQuickView view; view.setSource(testFileUrl("stopAtBounds.qml")); QTRY_COMPARE(view.status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(&view); - QQuickViewTestUtil::moveMouseAway(&view); + QQuickVisualTestUtils::centerOnScreen(&view); + QQuickVisualTestUtils::moveMouseAway(&view); view.show(); view.requestActivate(); QVERIFY(QTest::qWaitForWindowActive(&view)); @@ -2063,8 +2188,8 @@ void tst_qquickflickable::nestedMouseAreaUsingTouch() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("nestedmousearea.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(window->rootObject() != nullptr); QVERIFY(QTest::qWaitForWindowActive(window.data())); @@ -2083,6 +2208,27 @@ void tst_qquickflickable::nestedMouseAreaUsingTouch() QVERIFY(nested->y() < 100.0); } +void tst_qquickflickable::nestedMouseAreaPropagateComposedEvents() +{ + QScopedPointer<QQuickView> window(new QQuickView); + window->setSource(testFileUrl("nestedmouseareapce.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); + window->show(); + QVERIFY(window->rootObject() != nullptr); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); + QVERIFY(flickable != nullptr); + + QCOMPARE(flickable->contentY(), 50.0f); + flickWithTouch(window.data(), QPoint(100, 300), QPoint(100, 200)); + + // flickable should have moved + QVERIFY(!qFuzzyCompare(flickable->contentY(), 50.0)); +} + void tst_qquickflickable::nestedSliderUsingTouch_data() { QTest::addColumn<bool>("keepMouseGrab"); @@ -2109,8 +2255,8 @@ void tst_qquickflickable::nestedSliderUsingTouch() QScopedPointer<QQuickView> windowPtr(window); windowPtr->setSource(testFileUrl("nestedSlider.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window); - QQuickViewTestUtil::moveMouseAway(window); + QQuickVisualTestUtils::centerOnScreen(window); + QQuickVisualTestUtils::moveMouseAway(window); window->show(); QVERIFY(QTest::qWaitForWindowActive(window)); QVERIFY(window->rootObject() != nullptr); @@ -2148,8 +2294,8 @@ void tst_qquickflickable::pressDelayWithLoader() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("pressDelayWithLoader.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); QVERIFY(window->rootObject() != nullptr); @@ -2165,8 +2311,8 @@ void tst_qquickflickable::movementFromProgrammaticFlick() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("movementSignals.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); @@ -2218,8 +2364,8 @@ void tst_qquickflickable::ratios_smallContent() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("ratios_smallContent.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->setTitle(QTest::currentTestFunction()); window->show(); QVERIFY(QTest::qWaitForWindowExposed(window.data())); @@ -2244,8 +2390,8 @@ void tst_qquickflickable::contentXYNotTruncatedToInt() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("contentXY.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); @@ -2264,8 +2410,8 @@ void tst_qquickflickable::keepGrab() QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("keepGrab.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window.data()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickViewTestUtils::centerOnScreen(window.data()); + QQuickViewTestUtils::moveMouseAway(window.data()); window->show(); QVERIFY(QTest::qWaitForWindowActive(window.data())); @@ -2311,6 +2457,7 @@ void tst_qquickflickable::overshoot() { QFETCH(QQuickFlickable::BoundsBehavior, boundsBehavior); QFETCH(int, boundsMovement); + QFETCH(bool, pixelAligned); QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("overshoot.qml")); @@ -2320,6 +2467,7 @@ void tst_qquickflickable::overshoot() QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); QVERIFY(flickable); + flickable->setPixelAligned(pixelAligned); QCOMPARE(flickable->width(), 200.0); QCOMPARE(flickable->height(), 200.0); @@ -2366,7 +2514,7 @@ void tst_qquickflickable::overshoot() QMetaObject::invokeMethod(flickable, "reset"); // flick past the beginning - flick(window.data(), QPoint(10, 10), QPoint(50, 50), 100); + flick(window.data(), QPoint(10, 10), QPoint(50, 50), 50); QTRY_VERIFY(!flickable->property("flicking").toBool()); if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) && (boundsBehavior & QQuickFlickable::OvershootBounds)) { @@ -2435,7 +2583,7 @@ void tst_qquickflickable::overshoot() QMetaObject::invokeMethod(flickable, "reset"); // flick past the end - flick(window.data(), QPoint(50, 50), QPoint(10, 10), 100); + flick(window.data(), QPoint(50, 50), QPoint(10, 10), 50); QTRY_VERIFY(!flickable->property("flicking").toBool()); if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) && (boundsBehavior & QQuickFlickable::OvershootBounds)) { @@ -2468,29 +2616,53 @@ void tst_qquickflickable::overshoot_data() { QTest::addColumn<QQuickFlickable::BoundsBehavior>("boundsBehavior"); QTest::addColumn<int>("boundsMovement"); + QTest::addColumn<bool>("pixelAligned"); QTest::newRow("StopAtBounds,FollowBoundsBehavior") << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds) - << int(QQuickFlickable::FollowBoundsBehavior); + << int(QQuickFlickable::FollowBoundsBehavior) << false; QTest::newRow("DragOverBounds,FollowBoundsBehavior") << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds) - << int(QQuickFlickable::FollowBoundsBehavior); + << int(QQuickFlickable::FollowBoundsBehavior) << false; QTest::newRow("OvershootBounds,FollowBoundsBehavior") << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds) - << int(QQuickFlickable::FollowBoundsBehavior); + << int(QQuickFlickable::FollowBoundsBehavior) << false; QTest::newRow("DragAndOvershootBounds,FollowBoundsBehavior") << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds) - << int(QQuickFlickable::FollowBoundsBehavior); + << int(QQuickFlickable::FollowBoundsBehavior) << false; QTest::newRow("DragOverBounds,StopAtBounds") << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds) - << int(QQuickFlickable::StopAtBounds); + << int(QQuickFlickable::StopAtBounds) << false; QTest::newRow("OvershootBounds,StopAtBounds") << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds) - << int(QQuickFlickable::StopAtBounds); + << int(QQuickFlickable::StopAtBounds) << false; QTest::newRow("DragAndOvershootBounds,StopAtBounds") << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds) - << int(QQuickFlickable::StopAtBounds); + << int(QQuickFlickable::StopAtBounds) << false; + + QTest::newRow("StopAtBounds,FollowBoundsBehavior,pixelAligned") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds) + << int(QQuickFlickable::FollowBoundsBehavior) << true; + QTest::newRow("DragOverBounds,FollowBoundsBehavior,pixelAligned") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds) + << int(QQuickFlickable::FollowBoundsBehavior) << true; + QTest::newRow("OvershootBounds,FollowBoundsBehavior,pixelAligned") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds) + << int(QQuickFlickable::FollowBoundsBehavior) << true; + QTest::newRow("DragAndOvershootBounds,FollowBoundsBehavior,pixelAligned") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds) + << int(QQuickFlickable::FollowBoundsBehavior) << true; + + QTest::newRow("DragOverBounds,StopAtBounds,pixelAligned") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds) + << int(QQuickFlickable::StopAtBounds) << true; + QTest::newRow("OvershootBounds,StopAtBounds,pixelAligned") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds) + << int(QQuickFlickable::StopAtBounds) << true; + QTest::newRow("DragAndOvershootBounds,StopAtBounds,pixelAligned") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds) + << int(QQuickFlickable::StopAtBounds) << true; } void tst_qquickflickable::overshoot_reentrant() @@ -2559,8 +2731,8 @@ void tst_qquickflickable::synchronousDrag() QQuickView *window = scopedWindow.data(); window->setSource(testFileUrl("longList.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); - QQuickViewTestUtil::centerOnScreen(window); - QQuickViewTestUtil::moveMouseAway(window); + QQuickVisualTestUtils::centerOnScreen(window); + QQuickVisualTestUtils::moveMouseAway(window); window->show(); QVERIFY(window->rootObject() != nullptr); QVERIFY(QTest::qWaitForWindowActive(window)); @@ -2658,6 +2830,433 @@ void tst_qquickflickable::parallelTouch() // QTBUG-30840 QTRY_VERIFY(!flickable2->isMoving()); } +void tst_qquickflickable::ignoreNonLeftMouseButtons() // QTBUG-96909 +{ + QFETCH(Qt::MouseButton, otherButton); + const int threshold = qApp->styleHints()->startDragDistance(); + QQuickView view; + view.setSource(testFileUrl("dragon.qml")); + view.show(); + view.requestActivate(); + QQuickFlickable *flickable = static_cast<QQuickFlickable *>(view.rootObject()); + QSignalSpy dragSpy(flickable, &QQuickFlickable::draggingChanged); + + // Drag with left button + QPoint p1(100, 100); + moveAndPress(&view, p1); + for (int i = 0; i < 8; ++i) { + p1 -= QPoint(threshold, threshold); + QTest::mouseMove(&view, p1, 50); + } + QVERIFY(flickable->isDragging()); + QCOMPARE(dragSpy.count(), 1); + + // Press other button too, then release left button: dragging changes to false + QTest::mousePress(&view, otherButton); + QTest::mouseRelease(&view, Qt::LeftButton); + QTRY_COMPARE(flickable->isDragging(), false); + QCOMPARE(dragSpy.count(), 2); + + // Drag further with the other button held: Flickable ignores it + for (int i = 0; i < 8; ++i) { + p1 -= QPoint(threshold, threshold); + QTest::mouseMove(&view, p1, 50); + } + QCOMPARE(flickable->isDragging(), false); + QCOMPARE(dragSpy.count(), 2); + + // Release other button: nothing happens + QTest::mouseRelease(&view, otherButton); + QCOMPARE(dragSpy.count(), 2); +} + +void tst_qquickflickable::ignoreNonLeftMouseButtons_data() +{ + QTest::addColumn<Qt::MouseButton>("otherButton"); + + QTest::newRow("right") << Qt::RightButton; + QTest::newRow("middle") << Qt::MiddleButton; +} + +void tst_qquickflickable::receiveTapOutsideContentItem() +{ + // Check that if we add a TapHandler handler to a flickable, we + // can tap on the whole flickable area inside it, which includes + // the extents in addition to the content item. + QQuickView window; + window.resize(200, 200); + FlickableWithExtents flickable; + flickable.setParentItem(window.contentItem()); + flickable.setWidth(200); + flickable.setHeight(200); + flickable.setContentWidth(100); + flickable.setContentHeight(100); + + window.show(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + + QQuickTapHandler tapHandler(&flickable); + QSignalSpy clickedSpy(&tapHandler, SIGNAL(tapped(QEventPoint, Qt::MouseButton))); + + // Tap outside the content item in the top-left corner + QTest::mouseClick(&window, Qt::LeftButton, {}, QPoint(5, 5)); + QCOMPARE(clickedSpy.count(), 1); + + // Tap outside the content item in the bottom-right corner + const QPoint bottomRight(flickable.contentItem()->width() + 5, flickable.contentItem()->height() + 5); + QTest::mouseClick(&window, Qt::LeftButton, {}, bottomRight); + QCOMPARE(clickedSpy.count(), 2); +} + +void tst_qquickflickable::flickWhenRotated_data() +{ + QTest::addColumn<qreal>("rootRotation"); + QTest::addColumn<qreal>("flickableRotation"); + QTest::addColumn<qreal>("scale"); + + static constexpr qreal rotations[] = { 0, 30, 90, 180, 270 }; + static constexpr qreal scales[] = { 0.3, 1, 1.5 }; + + for (const auto pr : rotations) { + for (const auto fr : rotations) { + if (pr <= 90) { + for (const auto s : scales) + QTest::addRow("parent: %g, flickable: %g, scale: %g", pr, fr, s) << pr << fr << s; + } else { + // don't bother trying every scale with every set of rotations, to save time + QTest::addRow("parent: %g, flickable: %g, scale: 1", pr, fr) << pr << fr << qreal(1); + } + } + } +} + +void tst_qquickflickable::flickWhenRotated() // QTBUG-99639 +{ + QFETCH(qreal, rootRotation); + QFETCH(qreal, flickableRotation); + QFETCH(qreal, scale); + + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("rotatedFlickable.qml"))); + QQuickItem *rootItem = window.rootObject(); + QVERIFY(rootItem); + QQuickFlickable *flickable = rootItem->findChild<QQuickFlickable*>(); + QVERIFY(flickable); + + rootItem->setRotation(rootRotation); + flickable->setRotation(flickableRotation); + rootItem->setScale(scale); + QVERIFY(flickable->isAtYBeginning()); + + // Flick in Y direction in Flickable's coordinate system and check how much it moved + const QPointF startPoint = flickable->mapToGlobal(QPoint(20, 180)); + const QPointF endPoint = flickable->mapToGlobal(QPoint(20, 40)); + flick(&window, window.mapFromGlobal(startPoint).toPoint(), window.mapFromGlobal(endPoint).toPoint(), 100); + QTRY_VERIFY(flickable->isMoving()); + QTRY_VERIFY(!flickable->isMoving()); + qCDebug(lcTests) << "flicking from" << startPoint << "to" << endPoint << ": ended at contentY" << flickable->contentY(); + // usually flickable->contentY() is at 275 or very close + QVERIFY(!flickable->isAtYBeginning()); +} + +void tst_qquickflickable::flickAndReleaseOutsideBounds() // QTBUG-104987 +{ + // Check that flicking works when the mouse release happens + // outside the bounds of the flickable (and the flick started on top + // of a TapHandler that has a passive grab). + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("flickableWithTapHandler.qml"))); + QQuickItem *rootItem = window.rootObject(); + QVERIFY(rootItem); + QQuickFlickable *flickable = rootItem->findChild<QQuickFlickable*>(); + QVERIFY(flickable); + QQuickItem *childItem = flickable->findChild<QQuickItem*>("childItem"); + QVERIFY(childItem); + + QVERIFY(flickable->isAtYBeginning()); + + // Startpoint is on top of the tapHandler, while the endpoint is outside the flickable + const QPointF startPos = childItem->mapToGlobal(QPoint(10, 10)); + const QPointF endPos = flickable->mapToGlobal(QPoint(10, -10)); + const QPoint globalStartPos = window.mapFromGlobal(startPos).toPoint(); + const QPoint globalEndPos = window.mapFromGlobal(endPos).toPoint(); + const qreal dragDistance = 20; + + // Note: here we need to initiate a flick using raw events, rather than + // flickable.flick(), since we're testing if the mouse events takes the + // correct path to starts a flick (among passive and exclusive grabbers, combined + // with childMouseEventFilter()). + QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, globalStartPos); + QTest::mouseMove(&window, globalStartPos - QPoint(0, dragDistance / 2)); + QTest::mouseMove(&window, globalStartPos - QPoint(0, dragDistance)); + QTest::mouseMove(&window, globalEndPos); + QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, globalEndPos); + + // Ensure that the content item ends up being moved more than what we dragged + QTRY_VERIFY(flickable->contentY() > dragDistance * 2); +} + +void tst_qquickflickable::scrollingWithFractionalExtentSize_data() +{ + QTest::addColumn<QByteArray>("property"); + QTest::addColumn<bool>("isYAxis"); + QTest::addColumn<bool>("atBeginning"); + QTest::addColumn<QQuickFlickable::BoundsBehaviorFlag>("boundsBehaviour"); + + QTest::newRow("minyextent") << QByteArray("topMargin") << true << true << QQuickFlickable::StopAtBounds; + QTest::newRow("maxyextent") << QByteArray("bottomMargin") << true << false << QQuickFlickable::StopAtBounds; + QTest::newRow("minxextent") << QByteArray("leftMargin") << false << true << QQuickFlickable::StopAtBounds; + QTest::newRow("maxxextent") << QByteArray("rightMargin") << false << false << QQuickFlickable::StopAtBounds; + + QTest::newRow("minyextent") << QByteArray("topMargin") << true << true << QQuickFlickable::DragAndOvershootBounds; + QTest::newRow("maxyextent") << QByteArray("bottomMargin") << true << false << QQuickFlickable::DragAndOvershootBounds; + QTest::newRow("minxextent") << QByteArray("leftMargin") << false << true << QQuickFlickable::DragAndOvershootBounds; + QTest::newRow("maxxextent") << QByteArray("rightMargin") << false << false << QQuickFlickable::DragAndOvershootBounds; +} + +void tst_qquickflickable::scrollingWithFractionalExtentSize() // QTBUG-101268 +{ + QFETCH(QByteArray, property); + QFETCH(bool, isYAxis); + QFETCH(bool, atBeginning); + QFETCH(QQuickFlickable::BoundsBehaviorFlag, boundsBehaviour); + + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("fractionalExtent.qml"))); + QQuickItem *rootItem = window.rootObject(); + QVERIFY(rootItem); + QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(rootItem); + QVERIFY(flickable); + flickable->setBoundsBehavior(boundsBehaviour); + + qreal value = 100.5; + flickable->setProperty(property.constData(), 100.5); + if (isYAxis) + flickable->setContentY(atBeginning ? -value : value + qAbs(flickable->height() - flickable->contentHeight())); + else + flickable->setContentX(atBeginning ? -value : value + qAbs(flickable->width() - flickable->contentWidth())); + + if (isYAxis) { + QVERIFY(atBeginning ? flickable->isAtYBeginning() : flickable->isAtYEnd()); + QVERIFY(!flickable->isMovingVertically()); + } else { + QVERIFY(atBeginning ? flickable->isAtXBeginning() : flickable->isAtXEnd()); + QVERIFY(!flickable->isMovingHorizontally()); + } + + QPointF pos(flickable->x() + flickable->width() / 2, flickable->y() + flickable->height() / 2); + QPoint angleDelta(isYAxis ? 0 : (atBeginning ? -50 : 50), isYAxis ? (atBeginning ? -50 : 50) : 0); + + QWheelEvent wheelEvent1(pos, window.mapToGlobal(pos), QPoint(), angleDelta, + Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); + + QGuiApplication::sendEvent(&window, &wheelEvent1); + qApp->processEvents(); + if (isYAxis) { + QVERIFY(flickable->isMovingVertically()); + QTRY_VERIFY(!flickable->isMovingVertically()); + QVERIFY(!(atBeginning ? flickable->isAtYBeginning() : flickable->isAtYEnd())); + } else { + QVERIFY(flickable->isMovingHorizontally()); + QTRY_VERIFY(!flickable->isMovingHorizontally()); + QVERIFY(!(atBeginning ? flickable->isAtXBeginning() : flickable->isAtXEnd())); + } + + QWheelEvent wheelEvent2(pos, window.mapToGlobal(pos), QPoint(), -angleDelta, + Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); + wheelEvent2.setTimestamp(wheelEvent1.timestamp() + 10); + + QGuiApplication::sendEvent(&window, &wheelEvent2); + qApp->processEvents(); + + if (isYAxis) { + QVERIFY(flickable->isMovingVertically()); + QTRY_VERIFY(!flickable->isMovingVertically()); + QVERIFY(atBeginning ? flickable->isAtYBeginning() : flickable->isAtYEnd()); + } else { + QVERIFY(flickable->isMovingHorizontally()); + QTRY_VERIFY(!flickable->isMovingHorizontally()); + QVERIFY(atBeginning ? flickable->isAtXBeginning() : flickable->isAtXEnd()); + } +} + +void tst_qquickflickable::setContentPositionWhileDragging_data() +{ + QTest::addColumn<bool>("isHorizontal"); + QTest::addColumn<int>("newPos"); + QTest::addColumn<int>("newExtent"); + QTest::newRow("horizontal, setContentX") << true << 0 << -1; + QTest::newRow("vertical, setContentY") << false << 0 << -1; + QTest::newRow("horizontal, setContentWidth") << true << -1 << 200; + QTest::newRow("vertical, setContentHeight") << false << -1 << 200; +} + +void tst_qquickflickable::setContentPositionWhileDragging() // QTBUG-104966 +{ + QFETCH(bool, isHorizontal); + QFETCH(int, newPos); + QFETCH(int, newExtent); + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("contentPosWhileDragging.qml"))); + QQuickViewTestUtils::centerOnScreen(&window); + QVERIFY(window.isVisible()); + QQuickItem *rootItem = window.rootObject(); + QVERIFY(rootItem); + QQuickFlickable *flickable = rootItem->findChild<QQuickFlickable *>(); + QVERIFY(flickable); + + const auto contentPos = [flickable]() -> QPoint { + return QPoint(flickable->contentX(), flickable->contentY()); + }; + const qreal threshold = + qApp->styleHints()->startDragDistance() * flickable->parentItem()->scale(); + const QPoint thresholdPnt(qRound(threshold), qRound(threshold)); + const auto flickableCenterPos = flickable->mapToScene({flickable->width() / 2, flickable->height() / 2}).toPoint(); + + // Drag the mouse until we have surpassed the mouse drag threshold and a drag is initiated + // by checking for flickable->isDragging() + QPoint pos = flickableCenterPos; + QQuickViewTestUtils::moveAndPress(&window, pos); + int j = 1; + QVERIFY(!flickable->isDragging()); + while (!flickable->isDragging()) { + pos = flickableCenterPos - QPoint(j, j); + QTest::mouseMove(&window, pos); + j++; + } + + // Now we have entered the drag state + QVERIFY(flickable->isDragging()); + QCOMPARE(flickable->contentX(), 0); + QCOMPARE(flickable->contentY(), 0); + QVERIFY(flickable->width() > 0); + QVERIFY(flickable->height() > 0); + + + const int moveLength = 50; + const QPoint unitDelta(isHorizontal ? 1 : 0, isHorizontal ? 0 : 1); + const QPoint moveDelta = unitDelta * moveLength; + + pos -= 3*moveDelta; + QTest::mouseMove(&window, pos); + // Should be positive because we drag in the opposite direction + QCOMPARE(contentPos(), 3 * moveDelta); + QPoint expectedContentPos; + + // Set the content item position back to zero *while dragging* (!!) + if (newPos >= 0) { + if (isHorizontal) { + flickable->setContentX(newPos); + } else { + flickable->setContentY(newPos); + } + // Continue dragging + pos -= moveDelta; + expectedContentPos = moveDelta; + } else if (newExtent >= 0) { + // ...or reduce the content size be be less than current (contentX, contentY) position + // This forces the content item to move. + // contentY: 150 + // 320 - 150 = 170 pixels down to bottom + // Now reduce contentHeight to 200 + // since we are at the bottom, and the flickable is 100 pixels tall, contentY must land + // at newExtent - 100. + + if (isHorizontal) { + flickable->setContentWidth(newExtent); + } else { + flickable->setContentHeight(newExtent); + } + // Assumption is that the contentItem is aligned to the bottom of the flickable + // We therefore cannot scroll/flick it further down. Drag it up towards the top instead + // (by moving mouse down). + pos += moveDelta; + expectedContentPos = unitDelta * (newExtent - (isHorizontal ? flickable->width() : flickable->height())); + } + + QTest::mouseMove(&window, pos); + + // Make sure that the contentItem was only dragged the delta in mouse movement since the last + // setContentX/Y() call. + QCOMPARE(contentPos(), expectedContentPos); + QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, pos); + QVERIFY(!flickable->isDragging()); +} + +void tst_qquickflickable::coalescedMove() +{ + QQuickView *window = new QQuickView; + QScopedPointer<QQuickView> windowPtr(window); + windowPtr->setSource(testFileUrl("flickable03.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + QQuickVisualTestUtils::centerOnScreen(window); + QQuickVisualTestUtils::moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(window->rootObject() != nullptr); + + QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); + QVERIFY(flickable != nullptr); + + QSignalSpy movementStartedSpy(flickable, SIGNAL(movementStarted())); + QSignalSpy movementEndedSpy(flickable, SIGNAL(movementEnded())); + QSignalSpy flickStartedSpy(flickable, SIGNAL(flickStarted())); + QSignalSpy flickEndedSpy(flickable, SIGNAL(flickEnded())); + + QTest::touchEvent(window, touchDevice).press(0, {10, 10}).commit(); + + QTest::touchEvent(window, touchDevice).move(0, {10, 40}).commit(); + + QTest::touchEvent(window, touchDevice).move(0, {10, 100}).commit(); + + QTest::touchEvent(window, touchDevice).release(0, {10, 150}).commit(); + QQuickTouchUtils::flush(window); + + QTRY_VERIFY(!flickable->isMoving()); + + QCOMPARE(movementStartedSpy.size(), 1); + QCOMPARE(flickStartedSpy.size(), 1); + QCOMPARE(movementEndedSpy.size(), 1); + QCOMPARE(flickEndedSpy.size(), 1); +} + +void tst_qquickflickable::onlyOneMove() +{ + QQuickView *window = new QQuickView; + QScopedPointer<QQuickView> windowPtr(window); + windowPtr->setSource(testFileUrl("flickable03.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + QQuickVisualTestUtils::centerOnScreen(window); + QQuickVisualTestUtils::moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(window->rootObject() != nullptr); + + QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); + QVERIFY(flickable != nullptr); + + QSignalSpy movementStartedSpy(flickable, SIGNAL(movementStarted())); + QSignalSpy movementEndedSpy(flickable, SIGNAL(movementEnded())); + QSignalSpy flickStartedSpy(flickable, SIGNAL(flickStarted())); + QSignalSpy flickEndedSpy(flickable, SIGNAL(flickEnded())); + + QTest::touchEvent(window, touchDevice).press(0, {10, 10}).commit(); + QQuickTouchUtils::flush(window); + + QTest::touchEvent(window, touchDevice).move(0, {10, 100}).commit(); + QQuickTouchUtils::flush(window); + + QTest::touchEvent(window, touchDevice).release(0, {10, 200}).commit(); + QQuickTouchUtils::flush(window); + + QTRY_VERIFY(!flickable->isMoving()); + + QCOMPARE(movementStartedSpy.size(), 1); + QCOMPARE(flickStartedSpy.size(), 1); + QCOMPARE(movementEndedSpy.size(), 1); + QCOMPARE(flickEndedSpy.size(), 1); +} + QTEST_MAIN(tst_qquickflickable) #include "tst_qquickflickable.moc" diff --git a/tests/auto/quick/qquickflipable/CMakeLists.txt b/tests/auto/quick/qquickflipable/CMakeLists.txt index 95231d7ad9c..ac1d79339b4 100644 --- a/tests/auto/quick/qquickflipable/CMakeLists.txt +++ b/tests/auto/quick/qquickflipable/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickflipable SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickflipable.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickflipable/data/flip-y-axis-flipable.qml b/tests/auto/quick/qquickflipable/data/flip-y-axis-flipable.qml new file mode 100644 index 00000000000..1b6a3f50184 --- /dev/null +++ b/tests/auto/quick/qquickflipable/data/flip-y-axis-flipable.qml @@ -0,0 +1,32 @@ +// Copyright (C) 2023 UnionTech Software Technology Co., Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick + +Flipable { + id: flipable + + property real angle: 0 + width: 3840 // wider than 1024 * 2: part of it goes behind the camera while flipping + height: 2160 + + front: Rectangle { + width: parent.width + height: parent.height + color: "red" + anchors.centerIn: parent + } + back: Rectangle { + color: "yellow" + anchors.centerIn: parent + width: parent.width + height: parent.height + } + transform: Rotation { + id: rotation + origin.x: flipable.width / 2 + origin.y: flipable.height / 2 + axis.x: 0; axis.y: 1; axis.z: 0 + angle: flipable.angle + } +} diff --git a/tests/auto/quick/qquickflipable/tst_qquickflipable.cpp b/tests/auto/quick/qquickflipable/tst_qquickflipable.cpp index b4082b3d344..55747a7cdd1 100644 --- a/tests/auto/quick/qquickflipable/tst_qquickflipable.cpp +++ b/tests/auto/quick/qquickflipable/tst_qquickflipable.cpp @@ -34,12 +34,13 @@ #include <QFontMetrics> #include <QtQuick/private/qquickrectangle_p.h> #include <math.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickflipable : public QQmlDataTest { Q_OBJECT public: + tst_qquickflipable(); private slots: void create(); @@ -51,10 +52,18 @@ private slots: void QTBUG_9161_crash(); void QTBUG_8474_qgv_abort(); + void flipRotationAngle_data(); + void flipRotationAngle(); + private: QQmlEngine engine; }; +tst_qquickflipable::tst_qquickflipable() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qquickflipable::create() { QQmlEngine engine; @@ -131,6 +140,31 @@ void tst_qquickflipable::QTBUG_8474_qgv_abort() delete window; } +void tst_qquickflipable::flipRotationAngle_data() +{ + QTest::addColumn<int>("angle"); + QTest::addColumn<QQuickFlipable::Side>("side"); + + QTest::newRow("89") << 89 << QQuickFlipable::Front; + QTest::newRow("91") << 91 << QQuickFlipable::Back; + QTest::newRow("-89") << -89 << QQuickFlipable::Front; + QTest::newRow("-91") << -91 << QQuickFlipable::Back; +} + +void tst_qquickflipable::flipRotationAngle() // QTBUG-75954 +{ + QFETCH(int, angle); + QFETCH(QQuickFlipable::Side, side); + + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("flip-y-axis-flipable.qml")); + QQuickFlipable *obj = qobject_cast<QQuickFlipable*>(c.create()); + QVERIFY(obj != nullptr); + obj->setProperty("angle", angle); + QCOMPARE(obj->side(), side); + delete obj; +} + QTEST_MAIN(tst_qquickflipable) #include "tst_qquickflipable.moc" diff --git a/tests/auto/quick/qquickfocusscope/BLACKLIST b/tests/auto/quick/qquickfocusscope/BLACKLIST new file mode 100644 index 00000000000..7a1e82e98d7 --- /dev/null +++ b/tests/auto/quick/qquickfocusscope/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-103086 +[canvasFocus] +android diff --git a/tests/auto/quick/qquickfocusscope/CMakeLists.txt b/tests/auto/quick/qquickfocusscope/CMakeLists.txt index dac0f782812..539fcf8a8e1 100644 --- a/tests/auto/quick/qquickfocusscope/CMakeLists.txt +++ b/tests/auto/quick/qquickfocusscope/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickfocusscope SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickfocusscope.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickfocusscope/tst_qquickfocusscope.cpp b/tests/auto/quick/qquickfocusscope/tst_qquickfocusscope.cpp index e59bb7266c1..c38f31a318f 100644 --- a/tests/auto/quick/qquickfocusscope/tst_qquickfocusscope.cpp +++ b/tests/auto/quick/qquickfocusscope/tst_qquickfocusscope.cpp @@ -34,16 +34,16 @@ #include <private/qquicktextedit_p.h> #include <QtQuick/private/qquicktext_p.h> #include <QtQuick/private/qquickfocusscope_p.h> -#include "../../shared/util.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> -using namespace QQuickVisualTestUtil; +using namespace QQuickVisualTestUtils; class tst_qquickfocusscope : public QQmlDataTest { Q_OBJECT public: - tst_qquickfocusscope() {} + tst_qquickfocusscope() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void basic(); diff --git a/tests/auto/quick/qquickfontloader/CMakeLists.txt b/tests/auto/quick/qquickfontloader/CMakeLists.txt index bfaa048bca1..dc4a6b068dd 100644 --- a/tests/auto/quick/qquickfontloader/CMakeLists.txt +++ b/tests/auto/quick/qquickfontloader/CMakeLists.txt @@ -12,11 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickfontloader SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h tst_qquickfontloader.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -24,6 +20,7 @@ qt_internal_add_test(tst_qquickfontloader Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp b/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp index 94d603654d5..8bfeb7314a4 100644 --- a/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp +++ b/tests/auto/quick/qquickfontloader/tst_qquickfontloader.cpp @@ -31,8 +31,8 @@ #include <QtQml/qqmlcomponent.h> #include <QtQml/qqmlcontext.h> #include <QtQuick/private/qquickfontloader_p.h> -#include "../../shared/util.h" -#include "../../shared/testhttpserver.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/testhttpserver_p.h> #include <QtQuick/QQuickView> #include <QtQuick/QQuickItem> @@ -59,6 +59,7 @@ private slots: }; tst_qquickfontloader::tst_qquickfontloader() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } @@ -199,9 +200,7 @@ void tst_qquickfontloader::changeFontSourceViaState() { QQuickView window(testFileUrl("qtbug-20268.qml")); window.show(); - window.requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(&window)); - QCOMPARE(&window, qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(&window)); QQuickFontLoader *fontObject = qobject_cast<QQuickFontLoader*>(qvariant_cast<QObject *>(window.rootObject()->property("fontloader"))); QVERIFY(fontObject != nullptr); diff --git a/tests/auto/quick/qquickfontloader_static/CMakeLists.txt b/tests/auto/quick/qquickfontloader_static/CMakeLists.txt index efdf13c95da..927888ba7cc 100644 --- a/tests/auto/quick/qquickfontloader_static/CMakeLists.txt +++ b/tests/auto/quick/qquickfontloader_static/CMakeLists.txt @@ -12,12 +12,9 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickfontloader_static SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickfontloader_static.cpp DEFINES QT_DISABLE_DEPRECATED_BEFORE=0 - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -25,6 +22,7 @@ qt_internal_add_test(tst_qquickfontloader_static Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickfontloader_static/tst_qquickfontloader_static.cpp b/tests/auto/quick/qquickfontloader_static/tst_qquickfontloader_static.cpp index 7e848ef2fc0..34be2a8ca91 100644 --- a/tests/auto/quick/qquickfontloader_static/tst_qquickfontloader_static.cpp +++ b/tests/auto/quick/qquickfontloader_static/tst_qquickfontloader_static.cpp @@ -29,7 +29,7 @@ #include <QtGui/QGuiApplication> #include <QtQuick/QQuickView> #include <QtQml/QQmlComponent> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <qtest.h> QByteArray qmltemplate("import QtQuick 2.0\n" @@ -46,11 +46,11 @@ QByteArray qmltemplate("import QtQuick 2.0\n" " }\n" "}\n"); -int main(int argc, char **argv) +int actualTest(int argc, char **argv) { for (int i = 0; i < 3; i++) { QGuiApplication app(argc, argv); - QQmlDataTest dataTest; + QQmlDataTest dataTest(QT_QMLTEST_DATADIR); dataTest.initTestCase(); QQuickView window; QQmlComponent component (window.engine()); @@ -64,3 +64,25 @@ int main(int argc, char **argv) } return 0; } + +// we need the QTestLib infrastructure to create a log file +struct FontLoaderStaticTester : public QObject +{ + Q_OBJECT + +public: + int result = -1; +private slots: + void verify() { QCOMPARE(result, 0); } +}; + +int main(int argc, char **argv) +{ + int result = actualTest(argc, argv); + QCoreApplication app(argc, argv); + FontLoaderStaticTester tester; + tester.result = result; + QTest::qExec(&tester, argc, argv); +} + +#include "tst_qquickfontloader_static.moc" diff --git a/tests/auto/quick/qquickframebufferobject/BLACKLIST b/tests/auto/quick/qquickframebufferobject/BLACKLIST index 93dd7e9d1c0..1e814c5ebe8 100644 --- a/tests/auto/quick/qquickframebufferobject/BLACKLIST +++ b/tests/auto/quick/qquickframebufferobject/BLACKLIST @@ -1,4 +1,3 @@ -# QTBUG-65614 -b2qt +# QTBUG-102721 [testThatStuffWorks] -b2qt +android diff --git a/tests/auto/quick/qquickframebufferobject/CMakeLists.txt b/tests/auto/quick/qquickframebufferobject/CMakeLists.txt index 9f242842e69..7d000555339 100644 --- a/tests/auto/quick/qquickframebufferobject/CMakeLists.txt +++ b/tests/auto/quick/qquickframebufferobject/CMakeLists.txt @@ -12,13 +12,11 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickframebufferobject SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickframebufferobject.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Quick + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp index 5a772156249..2d19f299726 100644 --- a/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp +++ b/tests/auto/quick/qquickframebufferobject/tst_qquickframebufferobject.cpp @@ -28,6 +28,7 @@ #include <qtest.h> +#include <QGuiApplication> #include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> #include <qopenglcontext.h> @@ -36,7 +37,7 @@ #include <QtQuick/QQuickFramebufferObject> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #ifndef GL_MAX_SAMPLES #define GL_MAX_SAMPLES 0x8D57 @@ -143,6 +144,8 @@ class tst_QQuickFramebufferObject: public QQmlDataTest { Q_OBJECT public: + tst_QQuickFramebufferObject(); + private slots: void initTestCase() override; void testThatStuffWorks_data(); @@ -151,6 +154,11 @@ private slots: void testInvalidate(); }; +tst_QQuickFramebufferObject::tst_QQuickFramebufferObject() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QQuickFramebufferObject::initTestCase() { QQmlDataTest::initTestCase(); @@ -202,6 +210,10 @@ void tst_QQuickFramebufferObject::testThatStuffWorks() view.requestActivate(); QVERIFY(QTest::qWaitForWindowExposed(&view)); + if (QGuiApplication::platformName() == "offscreen" && + view.rendererInterface()->graphicsApi() == QSGRendererInterface::Software) + QSKIP("offscreen software rendering doesn't work with FBOs"); + QImage result = view.grabWindow(); QCOMPARE(frameInfo.renderCount, 1); @@ -242,6 +254,10 @@ void tst_QQuickFramebufferObject::testInvalidate() view.requestActivate(); QVERIFY(QTest::qWaitForWindowExposed(&view)); + if (QGuiApplication::platformName() == "offscreen" && + view.rendererInterface()->graphicsApi() == QSGRendererInterface::Software) + QSKIP("offscreen software rendering doesn't work with FBOs"); + QCOMPARE(frameInfo.fboSize, QSize(200, 200)); frameInfo.createFBOCount = 0; diff --git a/tests/auto/quick/qquickgraphicsinfo/CMakeLists.txt b/tests/auto/quick/qquickgraphicsinfo/CMakeLists.txt index 5a45d8aabd3..2e18d1fef7d 100644 --- a/tests/auto/quick/qquickgraphicsinfo/CMakeLists.txt +++ b/tests/auto/quick/qquickgraphicsinfo/CMakeLists.txt @@ -12,13 +12,11 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickgraphicsinfo SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickgraphicsinfo.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Quick + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp b/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp index 09c423890b6..b6bf9cc432f 100644 --- a/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp +++ b/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp @@ -33,20 +33,28 @@ #include <QtQuick/qquickview.h> #include <QtQuick/qsgrendererinterface.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_QQuickGraphicsInfo : public QQmlDataTest { Q_OBJECT +public: + tst_QQuickGraphicsInfo(); + private slots: void testProperties(); }; +tst_QQuickGraphicsInfo::tst_QQuickGraphicsInfo() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QQuickGraphicsInfo::testProperties() { QQuickView view; - view.setSource(QUrl("data/basic.qml")); + view.setSource(testFileUrl("basic.qml")); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); diff --git a/tests/auto/quick/qquickgridview/BLACKLIST b/tests/auto/quick/qquickgridview/BLACKLIST index 741eb2c7dce..a684b1e8bbc 100644 --- a/tests/auto/quick/qquickgridview/BLACKLIST +++ b/tests/auto/quick/qquickgridview/BLACKLIST @@ -1,5 +1,4 @@ [snapOneRow] -macos # QTBUG-86729 msvc-2019 windows-10 gcc developer-build [snapToRow] diff --git a/tests/auto/quick/qquickgridview/CMakeLists.txt b/tests/auto/quick/qquickgridview/CMakeLists.txt index 07dd48c0a89..17bee5d6931 100644 --- a/tests/auto/quick/qquickgridview/CMakeLists.txt +++ b/tests/auto/quick/qquickgridview/CMakeLists.txt @@ -12,15 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickgridview SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickgridview.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -29,6 +21,7 @@ qt_internal_add_test(tst_qquickgridview Qt::QmlPrivate Qt::QuickPrivate Qt::QuickTest + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickgridview/data/qtbug91461.qml b/tests/auto/quick/qquickgridview/data/qtbug91461.qml new file mode 100644 index 00000000000..50ab04e828b --- /dev/null +++ b/tests/auto/quick/qquickgridview/data/qtbug91461.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick + +Item { + width: 640 + height: 800 + + property real cellSize: 100 + + GridView { + id: grid + anchors.fill: parent + model: 1000 + cellWidth: cellSize + cellHeight: cellSize + cacheBuffer: 0 + currentIndex: 0 + + delegate: Rectangle { + implicitWidth: grid.cellWidth - 10 + implicitHeight: grid.cellHeight - 10 + color: GridView.isCurrentItem ? "green" : "lightgreen" + radius: 5 + border.width: GridView.isCurrentItem ? 3 : 1 + border.color: "black" + + Text { + anchors.centerIn: parent + text: model.index + } + } + } +} diff --git a/tests/auto/quick/qquickgridview/data/qtbug92998.qml b/tests/auto/quick/qquickgridview/data/qtbug92998.qml new file mode 100644 index 00000000000..d7db5fb843a --- /dev/null +++ b/tests/auto/quick/qquickgridview/data/qtbug92998.qml @@ -0,0 +1,53 @@ +import QtQuick 2.12 +import QtQuick.Window 2.12 + +Item { + width: 450 + height: 650 + GridView { + objectName: "gridview" + id: gridView + width: 450 + height: 650 + layoutDirection: Qt.RightToLeft + property int cells: calcCells(width) + cellWidth: width / cells + cellHeight: cellWidth + + delegate: Component { + Item { + width: gridView.cellWidth + height: gridView.cellHeight + Rectangle { + anchors { + fill: parent + margins: 10 + } + color: "green" + } + } + } + model: [ + { number: "1" }, + { number: "2" }, + { number: "3" }, + { number: "4" }, + { number: "5" }, + { number: "6" }, + { number: "7" }, + { number: "8" }, + { number: "9" }, + { number: "10" }, + { number: "11" }, + { number: "12" }, + { number: "13" }, + { number: "14" }, + { number: "15" }, + { number: "16" }]; + function calcCells(w) { + var rw = 120; + var c = Math.max(1, Math.round(w / rw)); + return c; + } + } +} diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp index c625f99c00d..9532aa546cd 100644 --- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp @@ -41,9 +41,9 @@ #include <QtQuick/private/qquickgridview_p.h> #include <QtQuick/private/qquicktext_p.h> #include <QtQmlModels/private/qqmllistmodel_p.h> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> #include <QtGui/qguiapplication.h> #include "qplatformdefs.h" @@ -55,8 +55,8 @@ Q_DECLARE_METATYPE(QQuickItemView::VerticalLayoutDirection) Q_DECLARE_METATYPE(QQuickItemView::PositionMode) Q_DECLARE_METATYPE(Qt::Key) -using namespace QQuickViewTestUtil; -using namespace QQuickVisualTestUtil; +using namespace QQuickViewTestUtils; +using namespace QQuickVisualTestUtils; #define SHARE_VIEWS @@ -212,8 +212,10 @@ private slots: void QTBUG_45640(); void QTBUG_49218(); + void positionViewAtBeginningAfterResizingCells(); void QTBUG_48870_fastModelUpdates(); void QTBUG_86255(); + void resizeDynamicCellWidthRtL(); void keyNavigationEnabled(); void releaseItems(); @@ -318,7 +320,9 @@ private slots: QString testForView; }; -tst_QQuickGridView::tst_QQuickGridView() : m_view(nullptr) +tst_QQuickGridView::tst_QQuickGridView() + : QQmlDataTest(QT_QMLTEST_DATADIR) + , m_view(nullptr) { } @@ -3725,7 +3729,7 @@ void tst_QQuickGridView::resizeGrid() ctxt->setContextProperty("testRightToLeft", layoutDirection == Qt::RightToLeft); ctxt->setContextProperty("testBottomToTop", verticalLayoutDirection == QQuickGridView::BottomToTop); window->setSource(testFileUrl("resizegrid.qml")); - QQuickViewTestUtil::centerOnScreen(window, window->size()); + QQuickViewTestUtils::centerOnScreen(window, window->size()); window->show(); qApp->processEvents(); @@ -4332,7 +4336,7 @@ void tst_QQuickGridView::snapToRow() QQuickView *window = getView(); - QQuickViewTestUtil::moveMouseAway(window); + QQuickViewTestUtils::moveMouseAway(window); window->setSource(testFileUrl("snapToRow.qml")); window->show(); qApp->processEvents(); @@ -4451,7 +4455,7 @@ void tst_QQuickGridView::snapOneRow() qreal flickDuration = 180 * flickSlowdown; QQuickView *window = getView(); - QQuickViewTestUtil::moveMouseAway(window); + QQuickViewTestUtils::moveMouseAway(window); window->setSource(testFileUrl("snapOneRow.qml")); window->show(); @@ -6695,6 +6699,34 @@ void tst_QQuickGridView::QTBUG_49218() delete window; } +void tst_QQuickGridView::positionViewAtBeginningAfterResizingCells() +{ + // Check that positionViewAtBeginning() ends up showing row 0, even + // if the cells are resized while the viewport is deep down in the list (QTBUG-91461). + std::unique_ptr<QQuickView> window(createView()); + window->setSource(testFileUrl("qtbug91461.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.get())); + + QQuickItem *rootItem = qobject_cast<QQuickItem*>(window->rootObject()); + QQuickGridView *gridview = qobject_cast<QQuickGridView *>(rootItem->childItems().first()); + QVERIFY(gridview != nullptr); + + gridview->positionViewAtEnd(); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); + rootItem->setProperty("cellSize", 200); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); + gridview->positionViewAtBeginning(); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); + + const QPointF topLeftCorner = window->contentItem()->mapToItem(gridview->contentItem(), QPointF(20, 20)); + const auto item0 = gridview->itemAt(topLeftCorner.x(), topLeftCorner.y()); + QVERIFY(item0); + + const int index = qmlContext(item0)->contextProperty("index").toInt(); + QCOMPARE(index, 0); +} + void tst_QQuickGridView::keyNavigationEnabled() { QScopedPointer<QQuickView> window(createView()); @@ -6808,6 +6840,25 @@ void tst_QQuickGridView::QTBUG_86255() QTRY_COMPARE(view->isFlicking(), false); } +void tst_QQuickGridView::resizeDynamicCellWidthRtL() +{ + QScopedPointer<QQuickView> window(createView()); + QTRY_VERIFY(window); + window->setSource(testFileUrl("qtbug92998.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickGridView *gridview = findItem<QQuickGridView>(window->rootObject(), "gridview"); + QTRY_VERIFY(gridview != nullptr); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); + gridview->setWidth(460); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); + QTRY_COMPARE(gridview->contentX(), 0.f); + gridview->setWidth(360); + QVERIFY(QQuickTest::qWaitForItemPolished(gridview)); + QTRY_COMPARE(gridview->contentX(), 0.f); +} + void tst_QQuickGridView::releaseItems() { QScopedPointer<QQuickView> view(createView()); diff --git a/tests/auto/quick/qquickimage/BLACKLIST b/tests/auto/quick/qquickimage/BLACKLIST new file mode 100644 index 00000000000..348ae127f34 --- /dev/null +++ b/tests/auto/quick/qquickimage/BLACKLIST @@ -0,0 +1,14 @@ +# QTBUG-98402 +[mirror] +macos-12 ci +# QTBUG-102721 +[hugeImages] +android +[multiFrame] +android +[sourceClipRect] +android +[tiling_QTBUG_6716] +android +[mirror] +android diff --git a/tests/auto/quick/qquickimage/CMakeLists.txt b/tests/auto/quick/qquickimage/CMakeLists.txt index b7e5479639e..4d4ce4f270c 100644 --- a/tests/auto/quick/qquickimage/CMakeLists.txt +++ b/tests/auto/quick/qquickimage/CMakeLists.txt @@ -12,16 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickimage SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickimage.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -29,6 +20,7 @@ qt_internal_add_test(tst_qquickimage Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp index 16f742f0aa9..36c4b607189 100644 --- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp +++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp @@ -47,13 +47,13 @@ #include <QQuickImageProvider> #include <QQmlAbstractUrlInterceptor> -#include "../../shared/util.h" -#include "../../shared/testhttpserver.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/testhttpserver_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> // #define DEBUG_WRITE_OUTPUT -using namespace QQuickVisualTestUtil; +using namespace QQuickVisualTestUtils; Q_DECLARE_METATYPE(QQuickImageBase::Status) @@ -110,6 +110,7 @@ private slots: }; tst_qquickimage::tst_qquickimage() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } diff --git a/tests/auto/quick/qquickimageprovider/BLACKLIST b/tests/auto/quick/qquickimageprovider/BLACKLIST new file mode 100644 index 00000000000..e78bcb13e92 --- /dev/null +++ b/tests/auto/quick/qquickimageprovider/BLACKLIST @@ -0,0 +1,21 @@ +# QTBUG-103047 +[requestImage_sync] +android +[requestImage_async] +android +[requestImage_async_forced] +android +[requestPixmap_sync] +android +[requestPixmap_async] +android +[removeProvider] +android +[threadTest] +android +[asyncTextureTest] +android +[instantAsyncTextureTest] +android +[asyncImageThreadSafety] +android diff --git a/tests/auto/quick/qquickimageprovider/CMakeLists.txt b/tests/auto/quick/qquickimageprovider/CMakeLists.txt index a336e280488..d66b6001cb9 100644 --- a/tests/auto/quick/qquickimageprovider/CMakeLists.txt +++ b/tests/auto/quick/qquickimageprovider/CMakeLists.txt @@ -4,6 +4,12 @@ ## tst_qquickimageprovider Test: ##################################################################### +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + qt_internal_add_test(tst_qquickimageprovider SOURCES tst_qquickimageprovider.cpp @@ -14,7 +20,19 @@ qt_internal_add_test(tst_qquickimageprovider Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate + TESTDATA ${test_data} ) ## Scopes: ##################################################################### + +qt_internal_extend_target(tst_qquickimageprovider CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" + ) + +qt_internal_extend_target(tst_qquickimageprovider CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" + ) diff --git a/tests/auto/quick/qquickimageprovider/data/forImports.qml b/tests/auto/quick/qquickimageprovider/data/forImports.qml new file mode 100644 index 00000000000..c11b37f3271 --- /dev/null +++ b/tests/auto/quick/qquickimageprovider/data/forImports.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Image { + source: "image://test/no-such-file.png"; +} diff --git a/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp b/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp index 49e94432e49..f76217d11dd 100644 --- a/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp +++ b/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp @@ -34,14 +34,15 @@ #include <QWaitCondition> #include <QThreadPool> #include <private/qqmlengine_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> Q_DECLARE_METATYPE(QQuickImageProvider*); -class tst_qquickimageprovider : public QObject +class tst_qquickimageprovider : public QQmlDataTest { Q_OBJECT public: - tst_qquickimageprovider() + tst_qquickimageprovider() : QQmlDataTest(QT_QMLTEST_DATADIR) { } @@ -72,7 +73,7 @@ private slots: private: QString newImageFileName() const; - void fillRequestTestsData(const QString &id); + void fillRequestTestsData(const char *id); void runTest(bool async, QQuickImageProvider *provider); }; @@ -161,7 +162,7 @@ QString tst_qquickimageprovider::newImageFileName() const return QString("image://test/image-%1.png").arg(count++); } -void tst_qquickimageprovider::fillRequestTestsData(const QString &id) +void tst_qquickimageprovider::fillRequestTestsData(const char *id) { QTest::addColumn<QString>("source"); QTest::addColumn<QString>("imageId"); @@ -170,39 +171,39 @@ void tst_qquickimageprovider::fillRequestTestsData(const QString &id) QTest::addColumn<QString>("error"); QString fileName = newImageFileName(); - QTest::newRow(QTest::toString(id + " simple test")) + QTest::addRow("%s simple test", id) << "image://test/" + fileName << fileName << "" << QSize(100,100) << ""; fileName = newImageFileName(); - QTest::newRow(QTest::toString(id + " simple test with capitalization"))//As it's a URL, should make no difference + QTest::addRow("%s simple test with capitalization", id)//As it's a URL, should make no difference << "image://Test/" + fileName << fileName << "" << QSize(100,100) << ""; fileName = newImageFileName(); - QTest::newRow(QTest::toString(id + " url with no id")) + QTest::addRow("%s url with no id", id) << "image://test/" + fileName << "" + fileName << "" << QSize(100,100) << ""; fileName = newImageFileName(); - QTest::newRow(QTest::toString(id + " url with path")) + QTest::addRow("%s url with path", id) << "image://test/test/path" + fileName << "test/path" + fileName << "" << QSize(100,100) << ""; fileName = newImageFileName(); - QTest::newRow(QTest::toString(id + " url with fragment")) + QTest::addRow("%s url with fragment", id) << "image://test/faq.html?#question13" + fileName << "faq.html?#question13" + fileName << "" << QSize(100,100) << ""; fileName = newImageFileName(); - QTest::newRow(QTest::toString(id + " url with query")) + QTest::addRow("%s url with query", id) << "image://test/cgi-bin/drawgraph.cgi?type=pie&color=green" + fileName << "cgi-bin/drawgraph.cgi?type=pie&color=green" + fileName << "" << QSize(100,100) << ""; fileName = newImageFileName(); - QTest::newRow(QTest::toString(id + " scaled image")) + QTest::addRow("%s scaled image", id) << "image://test/" + fileName << fileName << "sourceSize: \"80x30\"" << QSize(80,30) << ""; - QTest::newRow(QTest::toString(id + " missing")) + QTest::addRow("%s missing", id) << "image://test/no-such-file.png" << "no-such-file.png" << "" << QSize(100,100) << "<Unknown File>:2:1: QML Image: Failed to get image from provider: image://test/no-such-file.png"; - QTest::newRow(QTest::toString(id + " unknown provider")) + QTest::addRow("%s unknown provider", id) << "image://bogus/exists.png" << "" << "" << QSize() << "<Unknown File>:2:1: QML Image: Invalid image provider: image://bogus/exists.png"; } diff --git a/tests/auto/quick/qquickitem/BLACKLIST b/tests/auto/quick/qquickitem/BLACKLIST index d94a3ef1029..44b7c7efa66 100644 --- a/tests/auto/quick/qquickitem/BLACKLIST +++ b/tests/auto/quick/qquickitem/BLACKLIST @@ -1,2 +1,7 @@ [contains:hollow square: testing points inside] xcb + +# QTBUG-100991 +[mousePropagationToParent] +android + diff --git a/tests/auto/quick/qquickitem/CMakeLists.txt b/tests/auto/quick/qquickitem/CMakeLists.txt index cbc91f8f504..b4a31ab7174 100644 --- a/tests/auto/quick/qquickitem/CMakeLists.txt +++ b/tests/auto/quick/qquickitem/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickitem SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickitem.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickitem/data/containsContainmentMask.qml b/tests/auto/quick/qquickitem/data/containsContainmentMask.qml new file mode 100644 index 00000000000..cbf7f9222f2 --- /dev/null +++ b/tests/auto/quick/qquickitem/data/containsContainmentMask.qml @@ -0,0 +1,40 @@ +import QtQuick 2.11 + +Item { + width: 200 + height: 200 + + Item { + id: firstItem + + objectName: "firstItem" + x: 6 + y: 6 + width: 1000 + height: 1000 + + containmentMask: Item { + x: -5 + y: -5 + width: 10 + height: 10 + } + } + + Item { + id: secondItem + + objectName: "secondItem" + x: 6 + y: 6 + width: 0 + height: 0 + + containmentMask: Item { + parent: secondItem + anchors.centerIn: parent + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index aecaadd65d3..43b9b31d9fe 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -41,8 +41,8 @@ #include <QDebug> #include <QTimer> #include <QQmlEngine> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> #include <QSignalSpy> #include <QTranslator> #include <QtCore/qregularexpression.h> @@ -73,6 +73,7 @@ Q_OBJECT QPoint lastWheelEventPos; QPoint lastWheelEventGlobalPos; int languageChangeEventCount = 0; + int localeChangeEventCount = 0; protected: void focusInEvent(QFocusEvent *event) override { qCDebug(lcTests) << objectName() << event; @@ -110,8 +111,16 @@ Q_OBJECT bool event(QEvent *e) override { Q_ASSERT(e->isAccepted()); // every event is constructed with the accept flag initialized to true - if (e->type() == QEvent::LanguageChange) - languageChangeEventCount++; + switch (e->type()) { + case QEvent::LanguageChange: + ++languageChangeEventCount; + break; + case QEvent::LocaleChange: + ++localeChangeEventCount; + break; + default: + break; + } return QQuickItem::event(e); // default dispatch } }; @@ -172,6 +181,7 @@ class tst_qquickitem : public QQmlDataTest { Q_OBJECT public: + tst_qquickitem(); private slots: void initTestCase() override; @@ -185,6 +195,7 @@ private slots: void focusSubItemInNonFocusScope(); void parentItemWithFocus(); void reparentFocusedItem(); + void activeFocusChangedOrder(); void constructor(); void setParentItem(); @@ -220,6 +231,8 @@ private slots: void contains_data(); void contains(); + void containsContainmentMask_data(); + void containsContainmentMask(); void childAt(); @@ -233,6 +246,7 @@ private slots: void setParentCalledInOnWindowChanged(); void receivesLanguageChangeEvent(); + void receivesLocaleChangeEvent(); void polishLoopDetection_data(); void polishLoopDetection(); @@ -251,6 +265,11 @@ private slots: } }; +tst_qquickitem::tst_qquickitem() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qquickitem::initTestCase() { QQmlDataTest::initTestCase(); @@ -944,6 +963,93 @@ void tst_qquickitem::reparentFocusedItem() FVERIFY(); } +void tst_qquickitem::activeFocusChangedOrder() +{ + // This test checks that the activeFocusChanged signal first comes for an + // object that has lost focus, and only after that - for an object that + // has received focus. + + { + // Two FocusScopes inside a Window + QQuickWindow window; + QVERIFY(ensureFocus(&window)); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); + + QQuickFocusScope scope1(window.contentItem()); + QQuickItem scope1Child(&scope1); + + QQuickFocusScope scope2(window.contentItem()); + QQuickItem scope2Child(&scope2); + + scope1Child.forceActiveFocus(); + QTRY_VERIFY(scope1.hasActiveFocus()); + + int counter = 0; + connect(&scope1, &QQuickItem::activeFocusChanged, [&counter, &scope1](bool focus) { + QCOMPARE(scope1.childItems().front()->hasActiveFocus(), focus); + QCOMPARE(counter, 0); + counter++; + }); + connect(&scope2, &QQuickItem::activeFocusChanged, [&counter, &scope2](bool focus) { + QCOMPARE(scope2.childItems().front()->hasActiveFocus(), focus); + QCOMPARE(counter, 1); + counter++; + }); + + // A guard is needed so that connections are destroyed before the items. + // Otherwise the slots will be called during destruction, and test will + // crash (because childItems will be empty). + auto guard = qScopeGuard([&scope1, &scope2]() { + scope1.disconnect(); + scope2.disconnect(); + }); + Q_UNUSED(guard) + + scope2Child.forceActiveFocus(); + QTRY_VERIFY(scope2.hasActiveFocus()); + QCOMPARE(counter, 2); // make sure that both signals are received + } + + { + // Two Items inside a Window (no explicict FocusScopes) + QQuickWindow window; + QVERIFY(ensureFocus(&window)); + QTRY_COMPARE(QGuiApplication::focusWindow(), &window); + + QQuickItem item1(window.contentItem()); + + QQuickItem item2(window.contentItem()); + + item1.forceActiveFocus(); + QTRY_VERIFY(item1.hasActiveFocus()); + + int counter = 0; + connect(&item1, &QQuickItem::activeFocusChanged, [&counter](bool focus) { + QVERIFY(!focus); + QCOMPARE(counter, 0); + counter++; + }); + connect(&item2, &QQuickItem::activeFocusChanged, [&counter](bool focus) { + QVERIFY(focus); + QCOMPARE(counter, 1); + counter++; + }); + + // A guard is needed so that connections are destroyed before the items. + // Otherwise the slots will be called during destruction, and test will + // fail. + auto guard = qScopeGuard([&item1, &item2]() { + item1.disconnect(); + item2.disconnect(); + }); + Q_UNUSED(guard) + + item2.forceActiveFocus(); + QTRY_VERIFY(item2.hasActiveFocus()); + QCOMPARE(counter, 2); // make sure that both signals are received + } +} + void tst_qquickitem::constructor() { QScopedPointer<QQuickItem> root(new QQuickItem); @@ -1559,18 +1665,37 @@ Q_OBJECT int hoverEnterCount; int hoverMoveCount; int hoverLeaveCount; + QPoint hoverPosition; + QPoint hoverScenePosition; + QPoint hoverGlobalPosition; + QPoint hoverLastGlobalPosition; protected: void hoverEnterEvent(QHoverEvent *event) override { + qCDebug(lcTests) << static_cast<QSinglePointEvent *>(event) << event->position() << event->scenePosition() << event->globalPosition(); event->accept(); ++hoverEnterCount; + hoverPosition = event->position().toPoint(); + hoverScenePosition = event->scenePosition().toPoint(); + hoverGlobalPosition = event->globalPosition().toPoint(); + hoverLastGlobalPosition = event->points().first().globalLastPosition().toPoint(); } void hoverMoveEvent(QHoverEvent *event) override { + qCDebug(lcTests) << static_cast<QSinglePointEvent *>(event) << event->position() << event->scenePosition() << event->globalPosition(); event->accept(); ++hoverMoveCount; + hoverPosition = event->position().toPoint(); + hoverScenePosition = event->scenePosition().toPoint(); + hoverGlobalPosition = event->globalPosition().toPoint(); + hoverLastGlobalPosition = event->points().first().globalLastPosition().toPoint(); } void hoverLeaveEvent(QHoverEvent *event) override { + qCDebug(lcTests) << static_cast<QSinglePointEvent *>(event) << event->position() << event->scenePosition() << event->globalPosition(); event->accept(); ++hoverLeaveCount; + hoverPosition = event->position().toPoint(); + hoverScenePosition = event->scenePosition().toPoint(); + hoverGlobalPosition = event->globalPosition().toPoint(); + hoverLastGlobalPosition = event->points().first().globalLastPosition().toPoint(); } }; @@ -1627,13 +1752,28 @@ void tst_qquickitem::hoverEvent() QTest::mouseMove(window, outside); item->resetCounters(); + auto checkPositions = [=](QPoint pt) { + QCOMPARE(item->hoverPosition, pt); + QCOMPARE(item->hoverScenePosition, item->mapToScene(pt).toPoint()); + QCOMPARE(item->hoverGlobalPosition, item->mapToGlobal(pt).toPoint()); + QVERIFY(!item->hoverLastGlobalPosition.isNull()); + }; + // Enter, then move twice inside, then leave. + const bool shouldReceiveHoverEvents = visible && acceptHoverEvents; QTest::mouseMove(window, inside); + if (shouldReceiveHoverEvents) + checkPositions(inside); QTest::mouseMove(window, anotherInside); + if (shouldReceiveHoverEvents) + checkPositions(anotherInside); QTest::mouseMove(window, inside); + if (shouldReceiveHoverEvents) + checkPositions(inside); QTest::mouseMove(window, outside); + if (shouldReceiveHoverEvents) + checkPositions(outside); - const bool shouldReceiveHoverEvents = visible && acceptHoverEvents; if (shouldReceiveHoverEvents) { QCOMPARE(item->hoverEnterCount, 1); QVERIFY(item->hoverMoveCount >= 2); @@ -2049,7 +2189,8 @@ void tst_qquickitem::contains_data() QTest::newRow("(50, 0) = false") << 50 << 0 << false; QTest::newRow("(0, 50) = false") << 0 << 50 << false; QTest::newRow("(50, 50) = true") << 50 << 50 << true; - QTest::newRow("(100, 100) = true") << 100 << 100 << true; + QTest::newRow("(99, 99) = true") << 99 << 99 << true; + QTest::newRow("(100, 100) = false") << 100 << 100 << false; QTest::newRow("(150, 150) = false") << 150 << 150 << false; } @@ -2080,6 +2221,46 @@ void tst_qquickitem::contains() QCOMPARE(result.toBool(), contains); } +void tst_qquickitem::containsContainmentMask_data() +{ + QTest::addColumn<QPointF>("point"); + QTest::addColumn<bool>("contains"); + + QTest::newRow("(-6, -6) = false") << QPointF(-6, -6) << false; + QTest::newRow("(-5, -5) = true") << QPointF(-5, -5) << true; + QTest::newRow("(-4, -4) = true") << QPointF(-4, -4) << true; + QTest::newRow("(-3, -3) = true") << QPointF(-3, -3) << true; + QTest::newRow("(-2, -2) = true") << QPointF(-2, -2) << true; + QTest::newRow("(-1, -1) = true") << QPointF(-1, -1) << true; + QTest::newRow("(0, 0) = true") << QPointF(0, 0) << true; + QTest::newRow("(1, 1) = true") << QPointF(1, 1) << true; + QTest::newRow("(2, 2) = true") << QPointF(2, 2) << true; + QTest::newRow("(3, 3) = true") << QPointF(3, 3) << true; + QTest::newRow("(4, 4) = true") << QPointF(4, 4) << true; + QTest::newRow("(5, 5) = false") << QPointF(5, 5) << false; +} + +void tst_qquickitem::containsContainmentMask() +{ + QFETCH(QPointF, point); + QFETCH(bool, contains); + + QQuickView view; + view.setSource(testFileUrl("containsContainmentMask.qml")); + + QQuickItem *root = qobject_cast<QQuickItem*>(view.rootObject()); + QVERIFY(root); + + QQuickItem *firstItem = root->findChild<QQuickItem*>("firstItem"); + QVERIFY(firstItem); + + QQuickItem *secondItem = root->findChild<QQuickItem*>("secondItem"); + QVERIFY(secondItem); + + QCOMPARE(firstItem->contains(point), contains); + QCOMPARE(secondItem->contains(point), contains); +} + void tst_qquickitem::childAt() { QQuickView view; @@ -2253,6 +2434,31 @@ void tst_qquickitem::receivesLanguageChangeEvent() QCOMPARE(child2->languageChangeEventCount, 1); } +void tst_qquickitem::receivesLocaleChangeEvent() +{ + QQuickWindow window; + window.setFramePosition(QPoint(100, 100)); + window.resize(200, 200); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + QScopedPointer<TestItem> child1(new TestItem); + child1->setObjectName(QStringLiteral("child1")); + child1->setSize(QSizeF(200, 100)); + child1->setParentItem(window.contentItem()); + + QScopedPointer<TestItem> child2(new TestItem); + child2->setObjectName(QStringLiteral("child2")); + child2->setSize(QSizeF(50, 50)); + child2->setParentItem(child1.data()); + + QEvent e(QEvent::LocaleChange); + QCoreApplication::sendEvent(&window, &e); + + QTRY_COMPARE(child1->localeChangeEventCount, 1); + QCOMPARE(child2->localeChangeEventCount, 1); +} + QTEST_MAIN(tst_qquickitem) #include "tst_qquickitem.moc" diff --git a/tests/auto/quick/qquickitem2/CMakeLists.txt b/tests/auto/quick/qquickitem2/CMakeLists.txt index 6ecd1647876..6abb80dc796 100644 --- a/tests/auto/quick/qquickitem2/CMakeLists.txt +++ b/tests/auto/quick/qquickitem2/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickitem2 SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickitem.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate LIBRARIES Qt::TestPrivate TESTDATA ${test_data} diff --git a/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml b/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml new file mode 100644 index 00000000000..889e480f3b9 --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml @@ -0,0 +1,13 @@ +import QtQuick 2.6 + +Item { + visible: true + Item { + visible: false + Item { + objectName: "hiddenChild" + activeFocusOnTab: true + focus: true + } + } +} diff --git a/tests/auto/quick/qquickitem2/data/colorgroup.qml b/tests/auto/quick/qquickitem2/data/colorgroup.qml new file mode 100644 index 00000000000..25782c9a522 --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/colorgroup.qml @@ -0,0 +1,34 @@ +import QtQuick + +Item { + width: 300 + height: 300 + visible: true + + palette.active.base: "blue" + palette.inactive.base: "red" + palette.disabled.base: "gray" + + Rectangle { + id: background + objectName: "background" + + anchors.centerIn: parent + width: parent.width / 2 + height: parent.height / 2 + + color: palette.base + + Rectangle { + id: foreground + objectName: "foreground" + + anchors.centerIn: parent + width: parent.width / 2 + height: parent.height / 2 + + color: palette.base + border.color: "black" + } + } +} diff --git a/tests/auto/quick/qquickitem2/data/hollowTestItem.qml b/tests/auto/quick/qquickitem2/data/hollowTestItem.qml index d07d89c4f4c..2f77f6ae51e 100644 --- a/tests/auto/quick/qquickitem2/data/hollowTestItem.qml +++ b/tests/auto/quick/qquickitem2/data/hollowTestItem.qml @@ -31,7 +31,6 @@ Rectangle { anchors.fill: parent objectName: "hollowItem" holeRadius: 50 - circle: circleShapeTest } } } diff --git a/tests/auto/quick/qquickitem2/data/paletteAllocate.qml b/tests/auto/quick/qquickitem2/data/paletteAllocate.qml new file mode 100644 index 00000000000..6c959ddbcb3 --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/paletteAllocate.qml @@ -0,0 +1,35 @@ +import QtQuick + +Item { + id: root + width: 300 + height: 300 + visible: true + + palette.active.base: "blue" + palette.inactive.base: "red" + palette.disabled.base: "gray" + + Rectangle { + id: background + objectName: "background" + + anchors.centerIn: parent + width: parent.width / 2 + height: parent.height / 2 + + color: root.palette.base + + Rectangle { + id: foreground + objectName: "foreground" + + anchors.centerIn: parent + width: parent.width / 2 + height: parent.height / 2 + + color: root.palette.base + border.color: "black" + } + } +} diff --git a/tests/auto/quick/qquickitem2/data/undefinedInvalid.qml b/tests/auto/quick/qquickitem2/data/undefinedInvalid.qml new file mode 100644 index 00000000000..473038c5a13 --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/undefinedInvalid.qml @@ -0,0 +1,9 @@ +import QtQuick + +Item { + property var undef: undefined + width: undef + height: undef + implicitWidth: 200 + implicitHeight: 300 +} diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index b5e2f5e1413..671d42c4439 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -34,17 +34,21 @@ #include <QtQuick/qquickview.h> #include <QtGui/private/qinputmethod_p.h> #include <QtQuick/private/qquickloader_p.h> +#include <QtQuick/private/qquickpalette_p.h> #include <QtQuick/private/qquickrectangle_p.h> #include <QtQuick/private/qquicktextinput_p.h> #include <QtQuick/private/qquickitemchangelistener_p.h> #include <QtGui/qstylehints.h> #include <private/qquickitem_p.h> -#include "../../shared/util.h" -#include "../shared/visualtestutil.h" -#include "../../shared/platforminputcontext.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/platforminputcontext_p.h> #include <QtTest/private/qpropertytesthelper_p.h> -using namespace QQuickVisualTestUtil; +using namespace QQuickVisualTestUtils; + +Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") class tst_QQuickItem : public QQmlDataTest { @@ -68,6 +72,7 @@ private slots: void activeFocusOnTab10(); void activeFocusOnTab_infiniteLoop_data(); void activeFocusOnTab_infiniteLoop(); + void activeFocusOnTab_infiniteLoopControls(); void nextItemInFocusChain(); void nextItemInFocusChain2(); @@ -134,6 +139,11 @@ private slots: void grab(); + void colorGroup(); + void paletteAllocated(); + + void undefinedIsInvalidForWidthAndHeight(); + private: QQmlEngine engine; bool qt_tab_all_widgets() { @@ -247,8 +257,8 @@ QML_DECLARE_TYPE(KeyTestItem); class HollowTestItem : public QQuickItem { Q_OBJECT - Q_PROPERTY(bool circle READ isCircle WRITE setCircle) - Q_PROPERTY(qreal holeRadius READ holeRadius WRITE setHoleRadius) + Q_PROPERTY(bool circle READ isCircle WRITE setCircle NOTIFY circleChanged) + Q_PROPERTY(qreal holeRadius READ holeRadius WRITE setHoleRadius NOTIFY holeRadiusChanged) public: HollowTestItem(QQuickItem *parent = nullptr) @@ -266,10 +276,10 @@ class HollowTestItem : public QQuickItem bool isHovered() const { return m_isHovered; } bool isCircle() const { return m_isCircle; } - void setCircle(bool circle) { m_isCircle = circle; } + void setCircle(bool circle) { m_isCircle = circle; emit circleChanged(); } qreal holeRadius() const { return m_holeRadius; } - void setHoleRadius(qreal radius) { m_holeRadius = radius; } + void setHoleRadius(qreal radius) { m_holeRadius = radius; emit holeRadiusChanged(); } bool contains(const QPointF &point) const override { const qreal w = width(); @@ -292,6 +302,10 @@ class HollowTestItem : public QQuickItem return dd > (r * r) && dd <= outerRadius * outerRadius; } +signals: + void circleChanged(); + void holeRadiusChanged(); + protected: void hoverEnterEvent(QHoverEvent *) override { m_isHovered = true; } void hoverLeaveEvent(QHoverEvent *) override { m_isHovered = false; } @@ -339,6 +353,7 @@ class TabFenceItem2 : public QQuickItem QML_DECLARE_TYPE(TabFenceItem2); tst_QQuickItem::tst_QQuickItem() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } @@ -1148,6 +1163,17 @@ void tst_QQuickItem::activeFocusOnTab_infiniteLoop() QCOMPARE(item, window->rootObject()); } + +void tst_QQuickItem::activeFocusOnTab_infiniteLoopControls() +{ + auto source = testFileUrl("activeFocusOnTab_infiniteLoop3.qml"); + QScopedPointer<QQuickView>window(new QQuickView()); + window->setSource(source); + window->show(); + QVERIFY(window->errors().isEmpty()); + QTest::keyClick(window.get(), Qt::Key_Tab); // should not hang +} + void tst_QQuickItem::nextItemInFocusChain() { if (!qt_tab_all_widgets()) @@ -1289,14 +1315,13 @@ void verifyTabFocusChain(QQuickView *window, const char **focusChain, bool forwa int idx = 0; for (const char **objectName = focusChain; *objectName; ++objectName, ++idx) { const QString &descrStr = QString("idx=%1 objectName=\"%2\"").arg(idx).arg(*objectName); - const char *descr = descrStr.toLocal8Bit().data(); QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, forward ? Qt::NoModifier : Qt::ShiftModifier); QGuiApplication::sendEvent(window, &key); - QVERIFY2(key.isAccepted(), descr); + QVERIFY2(key.isAccepted(), qPrintable(descrStr)); QQuickItem *item = findItem<QQuickItem>(window->rootObject(), *objectName); - QVERIFY2(item, descr); - QVERIFY2(item->hasActiveFocus(), descr); + QVERIFY2(item, qPrintable(descrStr)); + QVERIFY2(item->hasActiveFocus(), qPrintable(descrStr)); } } @@ -3570,36 +3595,35 @@ void tst_QQuickItem::contains() QFETCH(bool, insideTarget); QFETCH(QList<QPoint>, points); - QQuickView *window = new QQuickView(nullptr); - window->rootContext()->setContextProperty("circleShapeTest", circleTest); - window->setBaseSize(QSize(400, 400)); - window->setSource(testFileUrl("hollowTestItem.qml")); - window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window)); - QCOMPARE(QGuiApplication::focusWindow(), window); - - QQuickItem *root = qobject_cast<QQuickItem *>(window->rootObject()); + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("hollowTestItem.qml"))); + QQuickItem *root = qobject_cast<QQuickItem *>(window.rootObject()); QVERIFY(root); + // Ensure that we don't get extra hover events delivered on the side. + QQuickWindowPrivate::get(&window)->deliveryAgentPrivate()->frameSynchronousHoverEnabled = false; + // Flush out any mouse events that might be queued up + qGuiApp->processEvents(); + HollowTestItem *hollowItem = root->findChild<HollowTestItem *>("hollowItem"); QVERIFY(hollowItem); + hollowItem->setCircle(circleTest); + + for (const QPoint &point : points) { + qCDebug(lcTests) << "hover and click @" << point; - foreach (const QPoint &point, points) { // check mouse hover - QTest::mouseMove(window, point); + QTest::mouseMove(&window, point); QTRY_COMPARE(hollowItem->isHovered(), insideTarget); // check mouse press - QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, point); + QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, point); QTRY_COMPARE(hollowItem->isPressed(), insideTarget); // check mouse release - QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, point); + QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, point); QTRY_COMPARE(hollowItem->isPressed(), false); } - - delete window; } void tst_QQuickItem::childAt() @@ -3716,6 +3740,114 @@ void tst_QQuickItem::isAncestorOf() QVERIFY(!sub2.isAncestorOf(&sub2)); } +/* + Verify that a nested item's palette responds to changes of the enabled state + and of the window's activation state by switching the current color group. +*/ +void tst_QQuickItem::colorGroup() +{ + QQuickView view; + + view.setSource(testFileUrl("colorgroup.qml")); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QQuickItem *root = qobject_cast<QQuickItem *>(view.rootObject()); + QQuickItem *background = root->findChild<QQuickItem *>("background"); + QVERIFY(background); + QQuickItem *foreground = root->findChild<QQuickItem *>("foreground"); + QVERIFY(foreground); + + QQuickPalette *palette = foreground->property("palette").value<QQuickPalette*>(); + QVERIFY(palette); + view.show(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QCOMPARE(palette->currentColorGroup(), QPalette::Active); + QCOMPARE(foreground->property("color").value<QColor>(), palette->active()->base()); + + background->setEnabled(false); + QCOMPARE(palette->currentColorGroup(), QPalette::Disabled); + QCOMPARE(foreground->property("color").value<QColor>(), palette->disabled()->base()); + + QWindow activationThief; + activationThief.show(); + activationThief.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&activationThief)); + QCOMPARE(palette->currentColorGroup(), QPalette::Disabled); + QCOMPARE(foreground->property("color").value<QColor>(), palette->disabled()->base()); + + background->setEnabled(true); + QCOMPARE(palette->currentColorGroup(), QPalette::Inactive); + QCOMPARE(foreground->property("color").value<QColor>(), palette->inactive()->base()); + + activationThief.hide(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + QCOMPARE(palette->currentColorGroup(), QPalette::Active); + QCOMPARE(foreground->property("color").value<QColor>(), palette->active()->base()); + + activationThief.show(); + activationThief.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&activationThief)); + QCOMPARE(palette->currentColorGroup(), QPalette::Inactive); + QCOMPARE(foreground->property("color").value<QColor>(), palette->inactive()->base()); +} + +/*! + Verify that items don't allocate their own QQuickPalette instance + unnecessarily. +*/ +void tst_QQuickItem::paletteAllocated() +{ + QQuickView view; + + view.setSource(testFileUrl("paletteAllocate.qml")); + + QQuickItem *root = qobject_cast<QQuickItem *>(view.rootObject()); + QQuickItem *background = root->findChild<QQuickItem *>("background"); + QVERIFY(background); + QQuickItem *foreground = root->findChild<QQuickItem *>("foreground"); + QVERIFY(foreground); + + bool backgroundHasPalette = false; + bool foregroundHasPalette = false; + QObject::connect(background, &QQuickItem::paletteCreated, this, [&]{ backgroundHasPalette = true; }); + QObject::connect(foreground, &QQuickItem::paletteCreated, this, [&]{ foregroundHasPalette = true; }); + + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QVERIFY(!backgroundHasPalette); + QVERIFY(!foregroundHasPalette); + + view.close(); + + QVERIFY(!backgroundHasPalette); + QVERIFY(!foregroundHasPalette); + + auto quickpalette = foreground->property("palette").value<QQuickPalette*>(); + QVERIFY(!backgroundHasPalette); + QVERIFY(quickpalette); + QVERIFY(foregroundHasPalette); +} + +void tst_QQuickItem::undefinedIsInvalidForWidthAndHeight() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("undefinedInvalid.qml")); + QScopedPointer<QObject> root(component.create()); + QVERIFY(root); + auto item = qobject_cast<QQuickItem *>(root.get()); + auto priv = QQuickItemPrivate::get(item); + QVERIFY(item); + QCOMPARE(item->height(), 300); + QCOMPARE(item->width(), 200); + QVERIFY(!priv->widthValid()); + QVERIFY(!priv->heightValid()); +} + QTEST_MAIN(tst_QQuickItem) #include "tst_qquickitem.moc" diff --git a/tests/auto/quick/qquickitemlayer/BLACKLIST b/tests/auto/quick/qquickitemlayer/BLACKLIST new file mode 100644 index 00000000000..d74ee2928ac --- /dev/null +++ b/tests/auto/quick/qquickitemlayer/BLACKLIST @@ -0,0 +1,23 @@ +# QTBUG-103088 +[layerSmooth] +android +[layerVisibility] +android +[layerZOrder] +android +[changeZOrder] +android +[itemEffect] +android +[rectangleEffect] +android +[textureMirroring] +android +[layerEffect] +android +[layerSourceRect] +android +[layerIsTextureProvider] +android +[changeSamplerName] +android diff --git a/tests/auto/quick/qquickitemlayer/CMakeLists.txt b/tests/auto/quick/qquickitemlayer/CMakeLists.txt index 37103b0c310..a17d57a72d2 100644 --- a/tests/auto/quick/qquickitemlayer/CMakeLists.txt +++ b/tests/auto/quick/qquickitemlayer/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickitemlayer SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickitemlayer.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp index 0fbd9cc24ed..ae6947f01be 100644 --- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp +++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp @@ -34,7 +34,7 @@ #include <qopenglcontext.h> #include <qopenglfunctions.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtGui/private/qguiapplication_p.h> #include <QtGui/qpa/qplatformintegration.h> @@ -97,7 +97,7 @@ bool isOffscreen() const char skipOffscreenMsg[] = "Skipping due to grabWindow not functional on offscreen/minimal platformsi (QTBUG-63185)"; -tst_QQuickItemLayer::tst_QQuickItemLayer() { } +tst_QQuickItemLayer::tst_QQuickItemLayer() : QQmlDataTest(QT_QMLTEST_DATADIR) { } void tst_QQuickItemLayer::initTestCase() { diff --git a/tests/auto/quick/qquickitemrhiintegration/BLACKLIST b/tests/auto/quick/qquickitemrhiintegration/BLACKLIST new file mode 100644 index 00000000000..03e5bc8c1d3 --- /dev/null +++ b/tests/auto/quick/qquickitemrhiintegration/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-102721 +[rhiItem] +android diff --git a/tests/auto/quick/qquicklayouts/BLACKLIST b/tests/auto/quick/qquicklayouts/BLACKLIST new file mode 100644 index 00000000000..0d299700a2d --- /dev/null +++ b/tests/auto/quick/qquicklayouts/BLACKLIST @@ -0,0 +1,11 @@ +[Tests_GridLayout::test_spacings] +qnx + +# QTBUG-103060 +[Tests_GridLayout::test_spacings] +android +[Tests_RowLayout::test_distributeToPixelGrid] +android +[Tests_RowLayout::test_rearrangeFixedSizeLayout] +android + diff --git a/tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml index 46d18a4384f..1abf2787b75 100644 --- a/tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml +++ b/tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml @@ -586,6 +586,56 @@ Item { tryCompare(layout.children[4], "y", 60); } + Component { + id: layout_alignBaseline_Component + GridLayout { + columns: 2 + columnSpacing: 0 + rowSpacing: 0 + TextInput { + property var itemRect: [x, y, width, height] + text: "red" + baselineOffset: 7 + color: "red" + verticalAlignment: TextInput.AlignVCenter + Layout.preferredWidth: 50 + Layout.preferredHeight: 10 + Layout.fillHeight: true + } + TextInput { + property var itemRect: [x, y, width, height] + text: "green" + baselineOffset: 7 + color: "green" + verticalAlignment: TextInput.AlignVCenter + Layout.preferredWidth: 50 + Layout.preferredHeight: 10 + Layout.fillHeight: true + } + + } + } + + function test_alignBaseline_dont_always_invalidate() + { + var layout = createTemporaryObject(layout_alignBaseline_Component, container); + waitForItemPolished(layout) + layout.height = 20 + // Adjusting height on an item that uses Qt.AlignBaseline might adjust the baseline + // Test if we don't get excessive number of polish() events because of baseline changes + // (In this case, we don't want to align by the baseline) + compare(isPolishScheduled(layout), false) + waitForItemPolished(layout) + var c0 = layout.children[0] + c0.Layout.alignment = Qt.AlignBaseline + var c1 = layout.children[1] + c1.Layout.alignment = Qt.AlignBaseline + + // We want to align by baseline => expect a polish event + compare(isPolishScheduled(layout), true) + waitForItemPolished(layout) + } + Component { id: layout_rightToLeft_Component diff --git a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml index 87e0a01df25..5e8f6f9bcf0 100644 --- a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml +++ b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml @@ -76,6 +76,18 @@ Item { } } + Component { + id: layout_rowLayout_Component + RowLayout { + } + } + + Component { + id: layout_columnLayout_Component + ColumnLayout { + } + } + Component { id: itemsWithAnchorsLayout_Component RowLayout { @@ -532,6 +544,102 @@ Item { layout.destroy(); } + + function buildLayout(layout, arrLayoutData) { + for (let i = 0; i < arrLayoutData.length; i++) { + let layoutItemDesc = arrLayoutData[i] + let rect = layoutItem_Component.createObject(layout) + for (let keyName in layoutItemDesc) { + rect.Layout[keyName] = layoutItemDesc[keyName] + } + } + } + + function test_dynamicAlignment_data() + { + return [ + { + tag: "simple", + + layout: { + type: "RowLayout", + items: [ + {preferredWidth: 30, preferredHeight: 20, fillHeight: true}, + {preferredWidth: 30, preferredHeight: 20}, + ] + }, + expectedGeometries: [ + [ 0, 0, 30, 60], + [30, 20, 30, 20] + ] + },{ + tag: "valign", + layout: { + type: "RowLayout", + items: [ + {preferredWidth: 12, preferredHeight: 20, fillHeight: true}, + {preferredWidth: 12, preferredHeight: 20}, + {preferredWidth: 12, preferredHeight: 20, alignment: Qt.AlignTop}, + {preferredWidth: 12, preferredHeight: 20, alignment: Qt.AlignVCenter}, + {preferredWidth: 12, preferredHeight: 20, alignment: Qt.AlignBottom} + ] + }, + expectedGeometries: [ + [ 0, 0, 12, 60], + [12, 20, 12, 20], + [24, 0, 12, 20], + [36, 20, 12, 20], + [48, 40, 12, 20] + ] + },{ + tag: "halign", + layout: { + type: "ColumnLayout", + items: [ + {preferredWidth: 20, preferredHeight: 12, fillWidth: true}, + {preferredWidth: 20, preferredHeight: 12}, + {preferredWidth: 20, preferredHeight: 12, alignment: Qt.AlignLeft}, + {preferredWidth: 20, preferredHeight: 12, alignment: Qt.AlignHCenter}, + {preferredWidth: 20, preferredHeight: 12, alignment: Qt.AlignRight} + ] + }, + expectedGeometries: [ + [ 0, 0, 60, 12], + [ 0, 12, 20, 12], + [ 0, 24, 20, 12], + [20, 36, 20, 12], + [40, 48, 20, 12] + ] + } + ] + } + + function test_dynamicAlignment(data) + { + let layout + switch (data.layout.type) { + case "RowLayout": + layout = createTemporaryObject(layout_rowLayout_Component, container) + break + case "ColumnLayout": + layout = createTemporaryObject(layout_columnLayout_Component, container) + break + default: + console.log("data.layout.type not recognized(" + data.layout.type + ")") + } + layout.spacing = 0 + buildLayout(layout, data.layout.items) + layout.width = 60 + layout.height = 60 // divides in 1/2/3/4/5/6 + waitForItemPolished(layout) + + for (let i = 0; i < layout.children.length; ++i) { + let itm = layout.children[i] + compare(itemRect(itm), data.expectedGeometries[i]) + } + } + + Component { id: layout_sizeHintNormalization_Component GridLayout { @@ -775,13 +883,6 @@ Item { layout.destroy(); } - - Component { - id: layout_rowLayout_Component - RowLayout { - } - } - function test_stretchItem_data() { return [ diff --git a/tests/auto/quick/qquicklayouts/data/tst_stacklayout.qml b/tests/auto/quick/qquicklayouts/data/tst_stacklayout.qml index c567b31db3b..303a4228a1a 100644 --- a/tests/auto/quick/qquicklayouts/data/tst_stacklayout.qml +++ b/tests/auto/quick/qquicklayouts/data/tst_stacklayout.qml @@ -272,5 +272,467 @@ Item { compare(layout.item2.isCurrentItem, false) compare(layout.item2.layout, layout) } + + Component { + id: layout_setCurrentIndex_Component + + StackLayout { + width: 200 + height: 200 + + property alias firstItem : rect + property alias secondItem: rowLayout + + Rectangle { + id: rect + color: "red" + implicitWidth: 10 + implicitHeight: 10 + } + RowLayout { + id: rowLayout + spacing: 0 + Rectangle { + color: "green" + implicitWidth: 10 + implicitHeight: 10 + Layout.fillWidth: true + Layout.fillHeight: true + } + Rectangle { + color: "blue" + implicitWidth: 10 + implicitHeight: 10 + Layout.fillWidth: true + Layout.fillHeight: true + } + } + } + } + + function test_setCurrentIndex() + { + var layout = layout_setCurrentIndex_Component.createObject(container) + compare(layout.firstItem.width, 200) + + // Invalidate the StackLayout (and its cached size hints) + layout.firstItem.implicitWidth = 42 + + layout.currentIndex = 1 + compare(layout.secondItem.width, 200) // width should not be -1 + layout.destroy() + } + + function geometry(item) { + return [item.x, item.y, item.width, item.height] + } + + Component { + id: countGeometryChanges_Component + StackLayout { + id: stack + property alias col: _col + property alias row: _row + width: 100 + ColumnLayout { + id: _col + property alias r1: _r1 + property alias r2: _r2 + property alias r3: _r3 + spacing: 0 + property int counter : 0 + onWidthChanged: { ++counter; } + Rectangle { + id: _r1 + implicitWidth: 20 + implicitHeight: 20 + Layout.fillWidth: true + property int counter : 0 + onWidthChanged: { ++counter; } + } + Rectangle { + id: _r2 + implicitWidth: 50 + implicitHeight: 50 + Layout.fillWidth: true + property int counter : 0 + onWidthChanged: { ++counter; } + } + Rectangle { + id: _r3 + implicitWidth: 40 + implicitHeight: 40 + Layout.fillWidth: true + property int counter : 0 + onWidthChanged: { ++counter; } + } + } + RowLayout { + id: _row + property alias r5: _r5 + spacing: 0 + property int counter : 0 + onWidthChanged: { ++counter; } + Rectangle { + id: _r5 + implicitWidth: 100 + implicitHeight: 100 + Layout.fillWidth: true + property int counter : 0 + onWidthChanged: { ++counter; } + } + } + } + } + + function test_countGeometryChanges() { + + var stack = countGeometryChanges_Component.createObject(container) + compare(stack.currentIndex, 0) + compare(stack.col.width, 100) + compare(stack.col.height, 110) + compare(stack.row.width, 100) + compare(stack.row.height, 100) + verify(stack.col.r1.counter <= 2) + compare(stack.col.r2.counter, 1) + verify(stack.col.r3.counter <= 2) + verify(stack.col.counter <= 2) + compare(stack.row.counter, 1) // not visible, will only receive the initial geometry change + compare(stack.row.r5.counter, 0) + stack.destroy() + } + + + Component { + id: layoutItem_Component + Rectangle { + implicitWidth: 20 + implicitHeight: 20 + } + } + + Component { + id: emtpy_StackLayout_Component + StackLayout { + property int num_onCountChanged: 0 + property int num_onCurrentIndexChanged: 0 + onCountChanged: { ++num_onCountChanged; } + onCurrentIndexChanged: { ++num_onCurrentIndexChanged; } + } + } + + function test_addAndRemoveItems() + { + var stack = emtpy_StackLayout_Component.createObject(container) + stack.currentIndex = 2 + compare(stack.implicitWidth, 0) + compare(stack.implicitHeight, 0) + + var rect0 = layoutItem_Component.createObject(stack) + verify(waitForItemPolished(stack)) + compare(stack.implicitWidth, 20) + compare(stack.implicitHeight, 20) + compare(rect0.visible, false) + + var rect1 = layoutItem_Component.createObject(stack) + rect1.Layout.preferredWidth = 30 + rect1.Layout.preferredHeight = 10 + verify(waitForItemPolished(stack)) + compare(stack.implicitWidth, 30) + compare(stack.implicitHeight, 20) + compare(rect0.visible, false) + compare(rect1.visible, false) + + var rect2 = layoutItem_Component.createObject(stack) + rect2.x = 42 // ### items in a stacklayout will have their x and y positions discarded. + rect2.y = 42 + rect2.Layout.preferredWidth = 80 + rect2.Layout.preferredHeight = 30 + rect2.Layout.fillWidth = true + verify(waitForItemPolished(stack)) + compare(stack.implicitWidth, 80) + compare(stack.implicitHeight, 30) + compare(rect0.visible, false) + compare(rect1.visible, false) + compare(rect2.visible, true) + compare(geometry(rect2), geometry(stack)) + + rect2.destroy() + wait(0) + verify(waitForItemPolished(stack)) + compare(stack.implicitWidth, 30) + compare(stack.implicitHeight, 20) + + rect0.destroy() + wait(0) + verify(waitForItemPolished(stack)) + compare(stack.implicitWidth, 30) + compare(stack.implicitHeight, 10) + + rect1.destroy() + wait(0) + verify(waitForItemPolished(stack)) + compare(stack.implicitWidth, 0) + compare(stack.implicitHeight, 0) + + stack.destroy() + } + + function test_sizeHint_data() { + return [ + { tag: "propagateNone", layoutHints: [10, 20, 30], childHints: [11, 21, 31], expected:[10, 20, Number.POSITIVE_INFINITY]}, + { tag: "propagateMinimumWidth", layoutHints: [-1, 20, 30], childHints: [10, 21, 31], expected:[10, 20, Number.POSITIVE_INFINITY]}, + { tag: "propagatePreferredWidth", layoutHints: [10, -1, 30], childHints: [11, 20, 31], expected:[10, 20, Number.POSITIVE_INFINITY]}, + { tag: "propagateMaximumWidth", layoutHints: [10, 20, -1], childHints: [11, 21, 30], expected:[10, 20, Number.POSITIVE_INFINITY]}, + { tag: "propagateAll", layoutHints: [-1, -1, -1], childHints: [10, 20, 30], expected:[10, 20, Number.POSITIVE_INFINITY]}, + { tag: "propagateCrazy", layoutHints: [-1, -1, -1], childHints: [40, 21, 30], expected:[30, 30, Number.POSITIVE_INFINITY]}, + { tag: "expandMinToExplicitPref", layoutHints: [-1, 1, -1], childHints: [11, 21, 31], expected:[ 1, 1, Number.POSITIVE_INFINITY]}, + { tag: "expandMaxToExplicitPref", layoutHints: [-1, 99, -1], childHints: [11, 21, 31], expected:[11, 99, Number.POSITIVE_INFINITY]}, + { tag: "expandAllToExplicitMin", layoutHints: [99, -1, -1], childHints: [11, 21, 31], expected:[99, 99, Number.POSITIVE_INFINITY]}, + { tag: "expandPrefToExplicitMin", layoutHints: [24, -1, -1], childHints: [11, 21, 31], expected:[24, 24, Number.POSITIVE_INFINITY]}, + { tag: "boundPrefToExplicitMax", layoutHints: [-1, -1, 19], childHints: [11, 21, 31], expected:[11, 19, Number.POSITIVE_INFINITY]}, + { tag: "boundAllToExplicitMax", layoutHints: [-1, -1, 9], childHints: [11, 21, 31], expected:[ 9, 9, Number.POSITIVE_INFINITY]}, + ]; + } + + function itemSizeHints(item) { + return [item.Layout.minimumWidth, item.implicitWidth, item.Layout.maximumWidth] + } + Component { + id: stacklayout_sizeHint_Component + StackLayout { + property int implicitWidthChangedCount : 0 + onImplicitWidthChanged: { ++implicitWidthChangedCount } + ColumnLayout { + Rectangle { + id: r1 + color: "red" + Layout.minimumWidth: 1 + Layout.preferredWidth: 2 + Layout.maximumWidth: 3 + + Layout.minimumHeight: 20 + Layout.preferredHeight: 20 + Layout.maximumHeight: 20 + Layout.fillWidth: true + } + } + } + } + + function test_sizeHint(data) { + var layout = stacklayout_sizeHint_Component.createObject(container) + + var col = layout.children[0] + col.Layout.minimumWidth = data.layoutHints[0] + col.Layout.preferredWidth = data.layoutHints[1] + col.Layout.maximumWidth = data.layoutHints[2] + + var child = col.children[0] + if (data.implicitWidth !== undefined) { + child.implicitWidth = data.implicitWidth + } + child.Layout.minimumWidth = data.childHints[0] + child.Layout.preferredWidth = data.childHints[1] + child.Layout.maximumWidth = data.childHints[2] + + verify(waitForItemPolished(layout)) + var effectiveSizeHintResult = [layout.Layout.minimumWidth, layout.implicitWidth, layout.Layout.maximumWidth] + compare(effectiveSizeHintResult, data.expected) + layout.destroy() + } + + Component { + id: stacklayout_addIgnoredItem_Component + StackLayout { + Repeater { + id: rep + model: 1 + Rectangle { + id: r + } + } + } + } + + // Items with no size information is ignored. + function test_addIgnoredItem() + { + var stack = stacklayout_addIgnoredItem_Component.createObject(container) + compare(stack.count, 1) + compare(stack.implicitWidth, 0) + compare(stack.implicitHeight, 0) + var r = stack.children[0] + r.Layout.preferredWidth = 20 + r.Layout.preferredHeight = 30 + verify(waitForItemPolished(stack)) + compare(stack.count, 1) + compare(stack.implicitWidth, 20) + compare(stack.implicitHeight, 30) + stack.destroy(); + } + + function test_dontCrashWhenAnchoredToAWindow() { + var test_layoutStr = + 'import QtQuick; \ + import QtQuick.Window; \ + import QtQuick.Layouts; \ + Window { \ + visible: true; \ + width: stack.implicitWidth; \ + height: stack.implicitHeight; \ + StackLayout { \ + id: stack; \ + currentIndex: 0; \ + anchors.fill: parent; \ + Rectangle { \ + color: "red"; \ + implicitWidth: 300; \ + implicitHeight: 200; \ + } \ + } \ + } ' + + var win = Qt.createQmlObject(test_layoutStr, container, ''); + if (win.visibility === Window.Windowed) { + // on single-window systems (such as Android), the window geometry will be + // fullscreen, and most likely it will be set to screen size. Avoid this test for + // those systems, as the size of the window will not be determined by the layout + tryCompare(win, 'width', 300); + } + win.destroy() + } + + Component { + id: test_dontCrashWhenChildIsResizedToNull_Component + StackLayout { + property alias rect : _rect + Rectangle { + id: _rect; + color: "red" + implicitWidth: 200 + implicitHeight: 200 + } + } + } + + function test_dontCrashWhenChildIsResizedToNull() { + var layout = test_dontCrashWhenChildIsResizedToNull_Component.createObject(container) + layout.rect.width = 0 + layout.width = 222 // trigger a rearrange with a valid size + layout.height = 222 + } + + Component { + id: test_currentIndex_Component + StackLayout { + currentIndex: 1 + Text { + text: "0" + } + Text { + text: "1" + } + } + } + + function test_currentIndex() { + var layout = test_currentIndex_Component.createObject(container) + var c0 = layout.children[0] + var c1 = layout.children[1] + compare(layout.currentIndex, 1) + tryCompare(layout, 'visible', true) + compare(c0.visible, false) + compare(c1.visible, true) + layout.currentIndex = 0 + compare(c0.visible, true) + compare(c1.visible, false) + var c2 = layoutItem_Component.createObject(layout) + compare(c2.visible, false) + + /* + * destroy the current item and check if visibility advances to next + */ + c0.destroy() + tryCompare(c1, 'visible', true) + compare(c2.visible, false) + c1.destroy() + tryCompare(c2, 'visible', true) + c2.destroy() + tryCompare(layout, 'currentIndex', 0) + + layout.destroy() + + /* + * Test the default/implicit value of currentIndex, either -1 (if empty) or 0: + */ + layout = emtpy_StackLayout_Component.createObject(container) + tryCompare(layout, 'visible', true) + compare(layout.currentIndex, -1) + compare(layout.num_onCurrentIndexChanged, 0) + // make it non-empty + c0 = layoutItem_Component.createObject(layout) + compare(layout.currentIndex, 0) + compare(layout.num_onCurrentIndexChanged, 1) + compare(c0.visible, true) + // make it empty again + c0.destroy() + wait(0) + compare(layout.currentIndex, -1) + //tryCompare(layout, 'currentIndex', -1) + compare(layout.num_onCurrentIndexChanged, 2) + + /* + * Check that explicit value doesn't change, + * and that no items are visible if the index is invalid/out of range + */ + layout.currentIndex = 2 + compare(layout.currentIndex, 2) + compare(layout.num_onCurrentIndexChanged, 3) + c0 = layoutItem_Component.createObject(layout) + compare(layout.currentIndex, 2) + compare(c0.visible, false) + + c1 = layoutItem_Component.createObject(layout) + compare(layout.currentIndex, 2) + compare(c0.visible, false) + compare(c1.visible, false) + + c2 = layoutItem_Component.createObject(layout) + compare(layout.currentIndex, 2) + compare(c0.visible, false) + compare(c1.visible, false) + compare(c2.visible, true) + + c2.destroy() + wait(0) + compare(layout.currentIndex, 2) + compare(c0.visible, false) + compare(c1.visible, false) + c1.destroy() + wait(0) + compare(layout.currentIndex, 2) + compare(c0.visible, false) + c0.destroy() + wait(0) + compare(layout.currentIndex, 2) + compare(layout.num_onCurrentIndexChanged, 3) + } + + function test_count() { + var layout = emtpy_StackLayout_Component.createObject(container) + tryCompare(layout, 'visible', true) + compare(layout.count, 0) + compare(layout.currentIndex, -1) + compare(layout.num_onCountChanged, 0) + compare(layout.num_onCurrentIndexChanged, 0) + var c0 = layoutItem_Component.createObject(layout) + compare(layout.count, 1) + compare(layout.currentIndex, 0) + compare(layout.num_onCurrentIndexChanged, 1) + compare(layout.num_onCountChanged, 1) + } + + } } diff --git a/tests/auto/quick/qquicklistview/BLACKLIST b/tests/auto/quick/qquicklistview/BLACKLIST index 6ef69550a40..e6b76ea247b 100644 --- a/tests/auto/quick/qquicklistview/BLACKLIST +++ b/tests/auto/quick/qquicklistview/BLACKLIST @@ -4,11 +4,9 @@ opensuse-leap #QTBUG-53863 [populateTransitions] opensuse-42.1 + +# QTBUG-103089 +[QTBUG_48044_currentItemNotVisibleAfterTransition] +android [contentHeightWithDelayRemove] -macos -#QTBUG-75960 -#QTBUG-76652 -[currentIndex] -macos -opensuse-leap -ubuntu-18.04 +android diff --git a/tests/auto/quick/qquicklistview/CMakeLists.txt b/tests/auto/quick/qquicklistview/CMakeLists.txt index 761d515eaf7..a87cc82628d 100644 --- a/tests/auto/quick/qquicklistview/CMakeLists.txt +++ b/tests/auto/quick/qquicklistview/CMakeLists.txt @@ -12,19 +12,11 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquicklistview SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h incrementalmodel.cpp incrementalmodel.h proxytestinnermodel.cpp proxytestinnermodel.h randomsortmodel.cpp randomsortmodel.h reusemodel.h tst_qquicklistview.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -33,6 +25,7 @@ qt_internal_add_test(tst_qquicklistview Qt::QmlPrivate Qt::QuickPrivate Qt::QuickTest + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquicklistview/data/appendDuringScrollDown.qml b/tests/auto/quick/qquicklistview/data/appendDuringScrollDown.qml index af35c291433..6ba64802973 100644 --- a/tests/auto/quick/qquicklistview/data/appendDuringScrollDown.qml +++ b/tests/auto/quick/qquicklistview/data/appendDuringScrollDown.qml @@ -1,10 +1,11 @@ import QtQuick 2.6 ListView { + id: listView width: 320; height: 240 focus: true delegate: Text { - height: 40; width: parent.width + height: 40; width: listView.width text: model.text verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter diff --git a/tests/auto/quick/qquicklistview/data/displayMargin.qml b/tests/auto/quick/qquicklistview/data/displayMargin.qml index aafbb4235ff..e6ea695b493 100644 --- a/tests/auto/quick/qquicklistview/data/displayMargin.qml +++ b/tests/auto/quick/qquicklistview/data/displayMargin.qml @@ -44,7 +44,7 @@ Item { model: 100 delegate: Rectangle { objectName: "delegate" - width: parent.width + width: view.width height: 25 color: index % 2 ? "steelblue" : "lightsteelblue" Text { diff --git a/tests/auto/quick/qquicklistview/data/headerCrash.qml b/tests/auto/quick/qquicklistview/data/headerCrash.qml index 124fa894f24..972ecb2906e 100644 --- a/tests/auto/quick/qquicklistview/data/headerCrash.qml +++ b/tests/auto/quick/qquicklistview/data/headerCrash.qml @@ -12,7 +12,7 @@ ListView { } delegate: Rectangle { - width: parent.width; height: 20 + width: myList.width; height: 20 color: index % 2 ? "green" : "red" } diff --git a/tests/auto/quick/qquicklistview/data/listview-itematindex.qml b/tests/auto/quick/qquicklistview/data/listview-itematindex.qml index fba8b11933d..2194f1edff4 100644 --- a/tests/auto/quick/qquicklistview/data/listview-itematindex.qml +++ b/tests/auto/quick/qquicklistview/data/listview-itematindex.qml @@ -1,13 +1,14 @@ import QtQuick 2.0 ListView { + id: listView width: 400 height: 400 focus: true model: 3 delegate: Text { - width: parent.width + width: listView.width height: 10 property int idx: index text: index diff --git a/tests/auto/quick/qquicklistview/data/outsideViewportChangeNotAffectingView.qml b/tests/auto/quick/qquicklistview/data/outsideViewportChangeNotAffectingView.qml index e0acaf49e44..ef959b10b42 100644 --- a/tests/auto/quick/qquicklistview/data/outsideViewportChangeNotAffectingView.qml +++ b/tests/auto/quick/qquicklistview/data/outsideViewportChangeNotAffectingView.qml @@ -72,7 +72,7 @@ Item { ListElement { size: 300; } } delegate: Rectangle { - width: parent.width + width: list.width color: index % 2 == 0 ? "red" : "blue" height: size Text { anchors.centerIn: parent; text: index } diff --git a/tests/auto/quick/qquicklistview/data/qtbug48044.qml b/tests/auto/quick/qquicklistview/data/qtbug48044.qml index d318643c1c5..368b6bd4bd6 100644 --- a/tests/auto/quick/qquicklistview/data/qtbug48044.qml +++ b/tests/auto/quick/qquicklistview/data/qtbug48044.qml @@ -116,7 +116,7 @@ Item { color: header ? "yellow" : "cyan" border.color: "black" height: 50 - width: parent.width + width: listView.width Text { anchors.centerIn: parent diff --git a/tests/auto/quick/qquicklistview/data/resizeAfterComponentComplete.qml b/tests/auto/quick/qquicklistview/data/resizeAfterComponentComplete.qml index 851d8f9a0ce..f5be95b7cc3 100644 --- a/tests/auto/quick/qquicklistview/data/resizeAfterComponentComplete.qml +++ b/tests/auto/quick/qquicklistview/data/resizeAfterComponentComplete.qml @@ -56,7 +56,7 @@ ListView { anchors.fill: parent model: 10 delegate: Rectangle { - width: parent.width + width: listView.width height: 40 border.color: "lightsteelblue" Text { diff --git a/tests/auto/quick/qquicklistview/data/sectionSnapping.qml b/tests/auto/quick/qquicklistview/data/sectionSnapping.qml index 2583cc03774..48a893f88c3 100644 --- a/tests/auto/quick/qquicklistview/data/sectionSnapping.qml +++ b/tests/auto/quick/qquicklistview/data/sectionSnapping.qml @@ -1,6 +1,7 @@ import QtQuick 2.0 ListView { + id: listView width: 400 height: 400 preferredHighlightBegin: 100 @@ -17,7 +18,7 @@ ListView { } delegate: Rectangle { - width: parent.width + width: listView.width height: 50 color: index % 2 ? "lightsteelblue" : "steelblue" Text { diff --git a/tests/auto/quick/qquicklistview/data/snapOneItemWrongDirection.qml b/tests/auto/quick/qquicklistview/data/snapOneItemWrongDirection.qml index f5b7b35d0cc..1dfbfe0feb1 100644 --- a/tests/auto/quick/qquicklistview/data/snapOneItemWrongDirection.qml +++ b/tests/auto/quick/qquicklistview/data/snapOneItemWrongDirection.qml @@ -1,13 +1,14 @@ import QtQuick 2.0 ListView { + id: listView width: 400 height: 400 focus: true model: 10 delegate: Rectangle { - width: parent.width + width: listView.width height: 50 color: index % 2 ? "blue" : "green" } diff --git a/tests/auto/quick/qquicklistview/data/strictlyenforcerange-resize.qml b/tests/auto/quick/qquicklistview/data/strictlyenforcerange-resize.qml index 338af384756..16b9c72b161 100644 --- a/tests/auto/quick/qquicklistview/data/strictlyenforcerange-resize.qml +++ b/tests/auto/quick/qquicklistview/data/strictlyenforcerange-resize.qml @@ -1,6 +1,7 @@ import QtQuick 2.0 ListView { + id: listView width: 400 height: 400 focus: true @@ -15,7 +16,7 @@ ListView { model: 10 delegate: Item { - width: parent.width + width: listView.width height: ListView.isCurrentItem ? 100 : 50 Text { diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 2b017aa1fc7..24196e2ba1c 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -46,9 +46,9 @@ #include <QtQmlModels/private/qqmllistmodel_p.h> #include <QtQmlModels/private/qqmldelegatemodel_p.h> #include <qpa/qwindowsysteminterface.h> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> #include "incrementalmodel.h" #include "proxytestinnermodel.h" #include "randomsortmodel.h" @@ -62,8 +62,8 @@ Q_DECLARE_METATYPE(QQuickListView::Orientation) Q_DECLARE_METATYPE(QQuickFlickable::FlickableDirection) Q_DECLARE_METATYPE(Qt::Key) -using namespace QQuickViewTestUtil; -using namespace QQuickVisualTestUtil; +using namespace QQuickViewTestUtils; +using namespace QQuickVisualTestUtils; #define SHARE_VIEWS @@ -401,7 +401,9 @@ class TestObject : public QObject int mCacheBuffer; }; -tst_QQuickListView::tst_QQuickListView() : m_view(nullptr) +tst_QQuickListView::tst_QQuickListView() + : QQmlDataTest(QT_QMLTEST_DATADIR) + , m_view(nullptr) { } @@ -431,6 +433,9 @@ void tst_QQuickListView::cleanupTestCase() template <class T> void tst_QQuickListView::items(const QUrl &source) { + // Make sure we outlive the view, or the context property will become null. + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); T model; @@ -441,7 +446,6 @@ void tst_QQuickListView::items(const QUrl &source) QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(source); @@ -512,6 +516,8 @@ void tst_QQuickListView::items(const QUrl &source) template <class T> void tst_QQuickListView::changed(const QUrl &source) { + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); T model; @@ -522,7 +528,6 @@ void tst_QQuickListView::changed(const QUrl &source) QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(source); @@ -550,6 +555,8 @@ void tst_QQuickListView::changed(const QUrl &source) template <class T> void tst_QQuickListView::inserted(const QUrl &source) { + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); window->show(); QVERIFY(QTest::qWaitForWindowExposed(window.data())); @@ -562,7 +569,6 @@ void tst_QQuickListView::inserted(const QUrl &source) QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(source); @@ -654,11 +660,12 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v for (int i = 0; i < 30; i++) model.addItem("Item" + QString::number(i), ""); + QScopedPointer<TestObject> testObject(new TestObject); + QQuickView *window = getView(); QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(testFileUrl("listviewtest.qml")); @@ -955,6 +962,8 @@ void tst_QQuickListView::insertBeforeVisible_data() template <class T> void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) { + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); T model; @@ -964,7 +973,6 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(source); @@ -1318,6 +1326,8 @@ void tst_QQuickListView::removed_more_data() template <class T> void tst_QQuickListView::clear(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection) { + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); T model; @@ -1327,7 +1337,6 @@ void tst_QQuickListView::clear(const QUrl &source, QQuickItemView::VerticalLayou QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(source); @@ -1850,6 +1859,8 @@ void tst_QQuickListView::multipleChanges_data() void tst_QQuickListView::swapWithFirstItem() { + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); QaimModel model; @@ -1859,7 +1870,6 @@ void tst_QQuickListView::swapWithFirstItem() QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(testFileUrl("listviewtest.qml")); @@ -1878,6 +1888,8 @@ void tst_QQuickListView::swapWithFirstItem() void tst_QQuickListView::checkCountForMultiColumnModels() { + QScopedPointer<TestObject> testObject(new TestObject); + // Check that a list view will only load items for the first // column, even if the model reports that it got several columns. // We test this since QQmlDelegateModel has been changed to @@ -1895,7 +1907,6 @@ void tst_QQuickListView::checkCountForMultiColumnModels() QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(testFileUrl("listviewtest.qml")); @@ -2032,6 +2043,8 @@ void tst_QQuickListView::enforceRange_withoutHighlight() void tst_QQuickListView::spacing() { + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); QaimModel model; @@ -2041,7 +2054,6 @@ void tst_QQuickListView::spacing() QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(testFileUrl("listviewtest.qml")); @@ -2309,7 +2321,7 @@ void tst_QQuickListView::sectionsDragOutsideBounds() QFETCH(int, cacheBuffer); QQuickView *window = getView(); - QQuickViewTestUtil::moveMouseAway(window); + QQuickViewTestUtils::moveMouseAway(window); QaimModel model; for (int i = 0; i < 10; i++) @@ -2962,8 +2974,8 @@ void tst_QQuickListView::keyNavigation() for (int i = 0; i < 30; i++) model.addItem("Item" + QString::number(i), ""); - QQuickView *window = getView(); QScopedPointer<TestObject> testObject(new TestObject); + QQuickView *window = getView(); window->rootContext()->setContextProperty("testModel", &model); window->rootContext()->setContextProperty("testObject", testObject.data()); window->setSource(testFileUrl("listviewtest.qml")); @@ -3167,6 +3179,8 @@ void tst_QQuickListView::itemListFlicker() void tst_QQuickListView::cacheBuffer() { + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); QaimModel model; @@ -3176,7 +3190,6 @@ void tst_QQuickListView::cacheBuffer() QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(testFileUrl("listviewtest.qml")); @@ -3269,6 +3282,8 @@ void tst_QQuickListView::cacheBuffer() void tst_QQuickListView::positionViewAtBeginningEnd() { + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); QaimModel model; @@ -3278,7 +3293,6 @@ void tst_QQuickListView::positionViewAtBeginningEnd() QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->show(); window->setSource(testFileUrl("listviewtest.qml")); @@ -3327,6 +3341,8 @@ void tst_QQuickListView::positionViewAtIndex() QFETCH(QQuickListView::PositionMode, mode); QFETCH(qreal, contentY); + QScopedPointer<TestObject> testObject(new TestObject); + QQuickView *window = getView(); QaimModel model; @@ -3336,7 +3352,6 @@ void tst_QQuickListView::positionViewAtIndex() QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->show(); window->setSource(testFileUrl("listviewtest.qml")); @@ -3676,6 +3691,8 @@ void tst_QQuickListView::manualHighlight() void tst_QQuickListView::QTBUG_11105() { + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); QaimModel model; for (int i = 0; i < 30; i++) @@ -3684,7 +3701,6 @@ void tst_QQuickListView::QTBUG_11105() QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(testFileUrl("listviewtest.qml")); @@ -4346,6 +4362,8 @@ void tst_QQuickListView::resetModel_headerFooter() void tst_QQuickListView::resizeView() { + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); QaimModel model; for (int i = 0; i < 40; i++) @@ -4354,7 +4372,6 @@ void tst_QQuickListView::resizeView() QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(testFileUrl("listviewtest.qml")); @@ -4455,6 +4472,8 @@ void tst_QQuickListView::resizeViewAndRepaint() void tst_QQuickListView::sizeLessThan1() { + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); QaimModel model; @@ -4464,7 +4483,6 @@ void tst_QQuickListView::sizeLessThan1() QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(testFileUrl("sizelessthan1.qml")); @@ -4585,6 +4603,8 @@ void tst_QQuickListView::resizeFirstDelegate() { // QTBUG-20712: Content Y jumps constantly if first delegate height == 0 // and other delegates have height > 0 + QScopedPointer<TestObject> testObject(new TestObject); + QScopedPointer<QQuickView> window(createView()); // bug only occurs when all items in the model are visible @@ -4595,7 +4615,6 @@ void tst_QQuickListView::resizeFirstDelegate() QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(testFileUrl("listviewtest.qml")); @@ -4793,6 +4812,8 @@ void tst_QQuickListView::indexAt_itemAt() QFETCH(qreal, y); QFETCH(int, index); + QScopedPointer<TestObject> testObject(new TestObject); + QQuickView *window = getView(); QaimModel model; @@ -4802,7 +4823,6 @@ void tst_QQuickListView::indexAt_itemAt() QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("testModel", &model); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(testFileUrl("listviewtest.qml")); @@ -5170,7 +5190,7 @@ void tst_QQuickListView::marginsResize() QQuickView *window = getView(); window->setSource(testFileUrl("margins2.qml")); - QQuickViewTestUtil::moveMouseAway(window); + QQuickViewTestUtils::moveMouseAway(window); window->show(); QVERIFY(QTest::qWaitForWindowExposed(window)); @@ -5306,7 +5326,7 @@ void tst_QQuickListView::snapToItem() QFETCH(qreal, startExtent); QQuickView *window = getView(); - QQuickViewTestUtil::moveMouseAway(window); + QQuickViewTestUtils::moveMouseAway(window); window->setSource(testFileUrl("snapToItem.qml")); window->show(); @@ -5990,7 +6010,7 @@ void tst_QQuickListView::snapOneItemResize_QTBUG_43555() QScopedPointer<QQuickView> window(createView()); window->resize(QSize(100, 320)); window->setResizeMode(QQuickView::SizeRootObjectToView); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("snapOneItemResize.qml")); window->show(); @@ -6304,7 +6324,7 @@ void tst_QQuickListView::snapOneItem() qreal flickDuration = 180 * flickSlowdown; QQuickView *window = getView(); - QQuickViewTestUtil::moveMouseAway(window); + QQuickViewTestUtils::moveMouseAway(window); window->setSource(testFileUrl("snapOneItem.qml")); window->show(); @@ -6670,8 +6690,8 @@ void tst_QQuickListView::populateTransitions() model.addItem("item" + QString::number(i), ""); } + QScopedPointer<TestObject> testObject(new TestObject()); QQuickView *window = getView(); - QScopedPointer<TestObject> testObject(new TestObject(window->rootContext())); window->rootContext()->setContextProperty("testModel", &model); window->rootContext()->setContextProperty("testObject", testObject.data()); window->rootContext()->setContextProperty("usePopulateTransition", usePopulateTransition); @@ -6794,12 +6814,12 @@ void tst_QQuickListView::populateTransitions_data() void tst_QQuickListView::sizeTransitions() { QFETCH(bool, topToBottom); + QScopedPointer<TestObject> testObject(new TestObject); QQuickView *window = getView(); QQmlContext *ctxt = window->rootContext(); QaimModel model; ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("topToBottom", topToBottom); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testObject", &model); window->setSource(testFileUrl("sizeTransitions.qml")); window->show(); @@ -6854,9 +6874,9 @@ void tst_QQuickListView::addTransitions() QaimModel model_targetItems_transitionFrom; QaimModel model_displacedItems_transitionVia; + QScopedPointer<TestObject> testObject(new TestObject); QQuickView *window = getView(); QQmlContext *ctxt = window->rootContext(); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("model_targetItems_transitionFrom", &model_targetItems_transitionFrom); ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia); @@ -7049,9 +7069,9 @@ void tst_QQuickListView::moveTransitions() QaimModel model_targetItems_transitionVia; QaimModel model_displacedItems_transitionVia; + QScopedPointer<TestObject> testObject(new TestObject); QQuickView *window = getView(); QQmlContext *ctxt = window->rootContext(); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("model_targetItems_transitionVia", &model_targetItems_transitionVia); ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia); @@ -7251,9 +7271,9 @@ void tst_QQuickListView::removeTransitions() QaimModel model_targetItems_transitionTo; QaimModel model_displacedItems_transitionVia; + QScopedPointer<TestObject> testObject(new TestObject); QQuickView *window = getView(); QQmlContext *ctxt = window->rootContext(); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("model_targetItems_transitionTo", &model_targetItems_transitionTo); ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia); @@ -7449,9 +7469,9 @@ void tst_QQuickListView::displacedTransitions() QPointF moveDisplaced_transitionVia(50, -100); QPointF removeDisplaced_transitionVia(150, 100); + QScopedPointer<TestObject> testObject(new TestObject()); QQuickView *window = getView(); QQmlContext *ctxt = window->rootContext(); - QScopedPointer<TestObject> testObject(new TestObject(window)); ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testObject", testObject.data()); ctxt->setContextProperty("model_displaced_transitionVia", &model_displaced_transitionVia); @@ -7675,9 +7695,9 @@ void tst_QQuickListView::multipleTransitions() for (int i = 0; i < initialCount; i++) model.addItem("Original item" + QString::number(i), ""); + QScopedPointer<TestObject> testObject(new TestObject); QQuickView *window = getView(); QQmlContext *ctxt = window->rootContext(); - QScopedPointer<TestObject> testObject(new TestObject); ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testObject", testObject.data()); ctxt->setContextProperty("addTargets_transitionFrom", addTargets_transitionFrom); @@ -7842,9 +7862,9 @@ void tst_QQuickListView::multipleDisplaced() for (int i = 0; i < 30; i++) model.addItem("Original item" + QString::number(i), ""); + QScopedPointer<TestObject> testObject(new TestObject()); QQuickView *window = getView(); QQmlContext *ctxt = window->rootContext(); - QScopedPointer<TestObject> testObject(new TestObject(window)); ctxt->setContextProperty("testModel", &model); ctxt->setContextProperty("testObject", testObject.data()); window->setSource(testFileUrl("multipleDisplaced.qml")); @@ -7939,7 +7959,7 @@ void tst_QQuickListView::matchItemLists(const QVariantList &itemLists, const QLi void tst_QQuickListView::flickBeyondBounds() { QScopedPointer<QQuickView> window(createView()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("flickBeyondBoundsBug.qml")); window->show(); @@ -7981,7 +8001,7 @@ void tst_QQuickListView::flickBothDirections() QFETCH(QPointF, targetPos); QQuickView *window = getView(); - QQuickViewTestUtil::moveMouseAway(window); + QQuickViewTestUtils::moveMouseAway(window); QQmlContext *ctxt = window->rootContext(); ctxt->setContextProperty("initialOrientation", initValues ? orientation : QQuickListView::Vertical); @@ -8154,7 +8174,7 @@ void tst_QQuickListView::delayedChanges_QTBUG_30555() void tst_QQuickListView::outsideViewportChangeNotAffectingView() { QScopedPointer<QQuickView> window(createView()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("outsideViewportChangeNotAffectingView.qml")); QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>(); @@ -8188,7 +8208,7 @@ void tst_QQuickListView::outsideViewportChangeNotAffectingView() void tst_QQuickListView::testProxyModelChangedAfterMove() { QScopedPointer<QQuickView> window(createView()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("proxytest.qml")); QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>(); @@ -9463,7 +9483,7 @@ void tst_QQuickListView::QTBUG_66163_setModelViewPortSizeChange() delegate: Rectangle { color: index % 2 ? "green" : "orange" - width: parent.width + width: view.width height: 50 } @@ -9515,8 +9535,8 @@ void tst_QQuickListView::itemFiltered() QScopedPointer<QQuickView> window(createView()); window->engine()->rootContext()->setContextProperty("_model", &proxy2); QQmlComponent component(window->engine()); - component.setData("import QtQuick 2.4; ListView { " - "anchors.fill: parent; model: _model; delegate: Text { width: parent.width;" + component.setData("import QtQuick 2.4; ListView { id: listView; " + "anchors.fill: parent; model: _model; delegate: Text { width: listView.width;" "text: model.display; } }", QUrl()); window->setContent(QUrl(), &component, component.create()); @@ -9799,12 +9819,24 @@ void tst_QQuickListView::delegateWithRequiredProperties() void tst_QQuickListView::reuse_reuseIsOffByDefault() { + QScopedPointer<TestObject> testObject(new TestObject); + // Check that delegate recycling is off by default. The reason is that // ListView needs to be backwards compatible with legacy applications. And // when using delegate recycling, there are certain differences, like that // a delegates Component.onCompleted will just be called the first time the // item is created, and not when it's reused. QScopedPointer<QQuickView> window(createView()); + + QaimModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QQmlContext *ctxt = window->rootContext(); + ctxt->setContextProperty("testModel", &model); + + ctxt->setContextProperty("testObject", testObject.data()); + window->setSource(testFileUrl("listviewtest.qml")); window->resize(640, 480); window->show(); @@ -9918,7 +9950,7 @@ void tst_QQuickListView::reuse_checkThatItemsAreReused() void tst_QQuickListView::dragOverFloatingHeaderOrFooter() // QTBUG-74046 { QQuickView *window = getView(); - QQuickViewTestUtil::moveMouseAway(window); + QQuickViewTestUtils::moveMouseAway(window); window->setSource(testFileUrl("qtbug63974.qml")); window->show(); QVERIFY(QTest::qWaitForWindowExposed(window)); diff --git a/tests/auto/quick/qquicklistview2/BLACKLIST b/tests/auto/quick/qquicklistview2/BLACKLIST new file mode 100644 index 00000000000..52b0231815f --- /dev/null +++ b/tests/auto/quick/qquicklistview2/BLACKLIST @@ -0,0 +1,9 @@ +[tapDelegateDuringFlicking] +android # QTBUG-104471 +[flickDuringFlicking] +android # QTBUG-104471 + +# QTBUG-104509 +[DragAndOvershootBounds] +android + diff --git a/tests/auto/quick/qquicklistview2/CMakeLists.txt b/tests/auto/quick/qquicklistview2/CMakeLists.txt index 8cad53c0d27..1a84ae15b15 100644 --- a/tests/auto/quick/qquicklistview2/CMakeLists.txt +++ b/tests/auto/quick/qquicklistview2/CMakeLists.txt @@ -6,15 +6,8 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquicklistview2 SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h + typerolemodel.h typerolemodel.cpp tst_qquicklistview2.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,9 +16,15 @@ qt_internal_add_test(tst_qquicklistview2 Qt::QmlPrivate Qt::QuickPrivate Qt::QuickTest + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) +qt6_add_qml_module(tst_qquicklistview2 + URI TestQQuickListViewTwo + VERSION 1.0 +) + qt_internal_extend_target(tst_qquicklistview2 CONDITION ANDROID OR IOS DEFINES QT_QMLTEST_DATADIR=\\\":/data\\\" diff --git a/tests/auto/quick/qquicklistview2/data/buttonDelegate.qml b/tests/auto/quick/qquicklistview2/data/buttonDelegate.qml new file mode 100644 index 00000000000..a40ba1cd7eb --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/buttonDelegate.qml @@ -0,0 +1,27 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +ListView { + id: root + width: 320 + height: 480 + model: 100 + + property var pressedDelegates: [] + property var releasedDelegates: [] + property var tappedDelegates: [] + property var canceledDelegates: [] + + delegate: Button { + required property int index + objectName: text + text: "button " + index + height: 100 + width: 320 + + onPressed: root.pressedDelegates.push(index) + onReleased: root.releasedDelegates.push(index) + onClicked: root.tappedDelegates.push(index) + onCanceled: root.canceledDelegates.push(index) + } +} diff --git a/tests/auto/quick/qquicklistview2/data/delegateChooserEnumRole.qml b/tests/auto/quick/qquicklistview2/data/delegateChooserEnumRole.qml new file mode 100644 index 00000000000..ec842468d25 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/delegateChooserEnumRole.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +import QtQuick +import Qt.labs.qmlmodels +import TestQQuickListViewTwo + +ListView { + width: 300; height: 300 + model: TypeRoleModel {} + delegate: DelegateChooser { + role: "type" + DelegateChoice { + roleValue: 0 + Text { + property int delegateType: 0 + text: model.text + " of type " + model.type + } + } + DelegateChoice { + roleValue: "Markdown" + Text { + property int delegateType: 1 + text: model.text + " of **type** " + model.type + textFormat: Text.MarkdownText + } + } + DelegateChoice { + roleValue: TypeRoleModel.Rect + Rectangle { + property int delegateType: 2 + width: 300; height: 20 + color: "wheat" + Text { + text: model.text + " of type " + model.type + anchors.verticalCenter: parent.verticalCenter + } + } + } + } +} diff --git a/tests/auto/quick/qquicklistview2/data/delegateModelRefresh.qml b/tests/auto/quick/qquicklistview2/data/delegateModelRefresh.qml new file mode 100644 index 00000000000..8c16ed64ce4 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/delegateModelRefresh.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQml.Models + +ApplicationWindow { + id: window + visible: true + width: 400 + height: 800 + property bool done: false + + ListView { + model: delegateModel + anchors.fill: parent + } + + DelegateModel { + id: delegateModel + model: ListModel { + ListElement { + available: true + } + ListElement { + available: true + } + ListElement { + available: true + } + } + + Component.onCompleted: { + delegateModel.refresh() + done = true; + } + function refresh() { + var rowCount = delegateModel.model.count; + const flatItemsList = [] + for (var i = 0; i < rowCount; i++) { + var entry = delegateModel.model.get(i); + flatItemsList.push(entry) + } + + for (i = 0; i < flatItemsList.length; ++i) { + var item = flatItemsList[i] + if (item !== null) + items.insert(item) + } + } + } +} diff --git a/tests/auto/quick/qquicklistview2/data/delegateWithMouseArea.qml b/tests/auto/quick/qquicklistview2/data/delegateWithMouseArea.qml new file mode 100644 index 00000000000..92a69639621 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/delegateWithMouseArea.qml @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Rectangle { + + width: 240 + height: 320 + color: "#ffffff" + + Component { + id: myDelegate + Rectangle { + id: wrapper + width: list.orientation == ListView.Vertical ? 240 : 20 + height: list.orientation == ListView.Vertical ? 20 : 240 + border.width: 1 + border.color: "black" + MouseArea { + anchors.fill: parent + } + Text { + text: index + ":" + (list.orientation == ListView.Vertical ? parent.y : parent.x).toFixed(0) + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + + ListView { + id: list + objectName: "list" + focus: true + width: 240 + height: 200 + clip: true + model: 30 + headerPositioning: ListView.OverlayHeader + delegate: myDelegate + + header: Rectangle { + width: list.orientation == Qt.Vertical ? 240 : 30 + height: list.orientation == Qt.Vertical ? 30 : 240 + color: "green" + z: 11 + Text { + anchors.centerIn: parent + text: "header " + (list.orientation == ListView.Vertical ? parent.y : parent.x).toFixed(1) + } + } + } + + // debug + Rectangle { + color: "#40ff0000" + border.width: txt.x + border.color: "black" + radius: 5 + width: txt.implicitWidth + 50 + height: txt.implicitHeight + 2 * txt.x + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.left: parent.left + + Text { + id: txt + x: 3 + y: x + text: "header position: " + (list.orientation == ListView.Vertical ? list.headerItem.y : list.headerItem.x).toFixed(1) + + "\ncontent position: " + (list.orientation == ListView.Vertical ? list.contentY : list.contentX).toFixed(1) + } + } +} diff --git a/tests/auto/quick/qquicklistview2/data/fetchMore.qml b/tests/auto/quick/qquicklistview2/data/fetchMore.qml new file mode 100644 index 00000000000..4ce53e4d28b --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/fetchMore.qml @@ -0,0 +1,21 @@ +import QtQuick +import org.qtproject.Test + +ListView { + id: listView + width: 300 + height: 150 + flickDeceleration: 10000 + + model: FetchMoreModel + delegate: Text { + height: 50 + text: model.display + } + + Text { + anchors.right: parent.right + text: "count " + listView.count + color: listView.moving ? "red" : "blue" + } +} diff --git a/tests/auto/quick/qquicklistview2/data/footerUpdate.qml b/tests/auto/quick/qquicklistview2/data/footerUpdate.qml new file mode 100644 index 00000000000..5d4dfad7fa8 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/footerUpdate.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Rectangle { + id: root + width: 800 + height: 800 + Component.onCompleted: { list.model.remove(0); } + ListView { + id: list + objectName: "list" + anchors.fill: parent + model: ListModel { + ListElement { + txt: "Foo" + } + } + delegate: Rectangle { + id: myDelegate + color: "red" + width: 800 + height: 100 + ListView.onRemove: SequentialAnimation { + PropertyAction { target: myDelegate; property: "ListView.delayRemove"; value: true } + NumberAnimation { target: myDelegate; property: "scale"; to: 0; duration: 1; } + PropertyAction { target: myDelegate; property: "ListView.delayRemove"; value: false } + } + + } + footer: Rectangle { + id: listFooter + color: "blue" + width: 800 + height: 100 + } + } +} diff --git a/tests/auto/quick/qquicklistview2/data/mouseAreaDelegate.qml b/tests/auto/quick/qquicklistview2/data/mouseAreaDelegate.qml new file mode 100644 index 00000000000..ad556913a52 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/mouseAreaDelegate.qml @@ -0,0 +1,30 @@ +import QtQuick 2.15 + +ListView { + id: root + width: 320 + height: 480 + model: 100 + + property var pressedDelegates: [] + property var releasedDelegates: [] + property var tappedDelegates: [] + property var canceledDelegates: [] + + delegate: MouseArea { + height: 100 + width: 320 + + onPressed: root.pressedDelegates.push(index) + onReleased: root.releasedDelegates.push(index) + onClicked: root.tappedDelegates.push(index) + onCanceled: root.canceledDelegates.push(index) + + Rectangle { + id: buttonArea + anchors.fill: parent + border.color: "#41cd52" + color: parent.pressed ? "lightsteelblue" : "beige" + } + } +} diff --git a/tests/auto/quick/qquicklistview2/data/noCrashOnIndexChange.qml b/tests/auto/quick/qquicklistview2/data/noCrashOnIndexChange.qml new file mode 100644 index 00000000000..6065d099817 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/noCrashOnIndexChange.qml @@ -0,0 +1,48 @@ +import QtQuick +import QtQml.Models + +Item { + ListModel { + id: myModel + ListElement { role_display: "One"; role_value: 0; } + ListElement { role_display: "One"; role_value: 2; } + ListElement { role_display: "One"; role_value: 3; } + ListElement { role_display: "One"; role_value: 4; } + ListElement { role_details: "Two"; role_value: 5; } + ListElement { role_details: "Three"; role_value: 6; } + ListElement { role_details: "Four"; role_value: 7; } + ListElement { role_details: "Five"; role_value: 8; } + ListElement { role_details: "Six"; role_value: 9; } + ListElement { role_keyID: "Seven"; role_value: 10; } + ListElement { role_keyID: "Eight"; role_value: 11; } + ListElement { role_keyID: "hello"; role_value: 12; } + } + + DelegateModel { + id: displayDelegateModel + delegate: Text { text: role_display } + model: myModel + groups: [ + DelegateModelGroup { + includeByDefault: false + name: "displayField" + } + ] + filterOnGroup: "displayField" + Component.onCompleted: { + var rowCount = myModel.count; + items.remove(0, rowCount); + for (var i = 0; i < rowCount; i++) { + var entry = myModel.get(i); + if (entry.role_display) { + items.insert(entry, "displayField"); + } + } + } + } + + ListView { + model: displayDelegateModel + } +} + diff --git a/tests/auto/quick/qquicklistview2/data/qtbug86744.qml b/tests/auto/quick/qquicklistview2/data/qtbug86744.qml new file mode 100644 index 00000000000..c69a4f7ec64 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/qtbug86744.qml @@ -0,0 +1,25 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQml.Models + +Item { + height: 200 + width: 100 + DelegateModel { + id: dm + model: 2 + delegate: Item { + width: 100 + height: 20 + property bool isCurrent: ListView.isCurrentItem + } + } + ListView { + objectName: "listView" + model: dm + currentIndex: 1 + anchors.fill: parent + } +} diff --git a/tests/auto/quick/qquicklistview2/data/qtbug98315.qml b/tests/auto/quick/qquicklistview2/data/qtbug98315.qml new file mode 100644 index 00000000000..bf2ed857b17 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/qtbug98315.qml @@ -0,0 +1,98 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQml.Models + +Item { + width: 500 + height: 200 + + property list<QtObject> myModel: [ + QtObject { + objectName: "Item 0" + property bool selected: true + }, + QtObject { + objectName: "Item 1" + property bool selected: false + }, + QtObject { + objectName: "Item 2" + property bool selected: false + }, + QtObject { + objectName: "Item 3" + property bool selected: true + }, + QtObject { + objectName: "Item 4" + property bool selected: true + }, + QtObject { + objectName: "Item 5" + property bool selected: true + }, + QtObject { + objectName: "Item 6" + property bool selected: false + } + ] + + ListView { + objectName: "listView" + id: listview + width: 500 + height: 200 + + focus: true + clip: true + spacing: 2 + orientation: ListView.Horizontal + highlightMoveDuration: 300 + highlightMoveVelocity: -1 + preferredHighlightBegin: (500 - 100) / 2 + preferredHighlightEnd: (500 + 100) / 2 + highlightRangeMode: ListView.StrictlyEnforceRange + cacheBuffer: 500 + currentIndex: 1 + + model: DelegateModel { + id: delegateModel + filterOnGroup: "visible" + model: myModel + groups: [ + DelegateModelGroup { + name: "visible" + includeByDefault: true + } + ] + delegate: Rectangle { + id: tile + objectName: model.modelData.objectName + + width: 100 + height: 100 + border.width: 0 + anchors.verticalCenter: parent.verticalCenter + + visible: model.modelData.selected + Component.onCompleted: { + DelegateModel.inPersistedItems = true + DelegateModel.inVisible = Qt.binding(function () { + return model.modelData.selected + }) + } + + property bool isCurrent: ListView.isCurrentItem + color: isCurrent ? "red" : "green" + + Text { + id: valueText + anchors.centerIn: parent + text: model.modelData.objectName + } + } + } + } +} diff --git a/tests/auto/quick/qquicklistview2/data/qtbug_92809.qml b/tests/auto/quick/qquicklistview2/data/qtbug_92809.qml new file mode 100644 index 00000000000..8a995c012d5 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/qtbug_92809.qml @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Rectangle { + id: root + width: 800 + height: 480 + + property list<QtObject> myModel: [ + QtObject { property string name: "Item 0"; property bool selected: true }, + QtObject { property string name: "Item 1"; property bool selected: true }, + QtObject { property string name: "Item 2"; property bool selected: true }, + QtObject { property string name: "Item 3"; property bool selected: true }, + QtObject { property string name: "Item 4"; property bool selected: true }, + QtObject { property string name: "Item 5"; property bool selected: true }, + QtObject { property string name: "Item 6"; property bool selected: true }, + QtObject { property string name: "Item 7"; property bool selected: true }, + QtObject { property string name: "Item 8"; property bool selected: true }, + QtObject { property string name: "Item 9"; property bool selected: true }, + QtObject { property string name: "Press Enter here"; property bool selected: true } + ] + + DelegateModel { + objectName: "model" + id: visualModel + model: myModel + filterOnGroup: "selected" + + groups: [ + DelegateModelGroup { + name: "selected" + includeByDefault: true + } + ] + + delegate: Rectangle { + width: 180 + height: 180 + visible: DelegateModel.inSelected + color: ListView.isCurrentItem ? "orange" : "yellow" + Component.onCompleted: { + DelegateModel.inPersistedItems = true + DelegateModel.inSelected = Qt.binding(function() { return model.selected }) + } + } + } + + ListView { + objectName: "list" + anchors.fill: parent + spacing: 180/15 + orientation: ListView.Horizontal + model: visualModel + focus: true + currentIndex: 0 + preferredHighlightBegin: (width-180)/2 + preferredHighlightEnd: (width+180)/2 + highlightRangeMode: ListView.StrictlyEnforceRange + highlightMoveDuration: 300 + highlightMoveVelocity: -1 + cacheBuffer: 0 + + onCurrentIndexChanged: { + if (currentIndex === 10) { + myModel[6].selected = !myModel[6].selected + } + } + } +} diff --git a/tests/auto/quick/qquicklistview2/data/singletonModelLifetime.qml b/tests/auto/quick/qquicklistview2/data/singletonModelLifetime.qml new file mode 100644 index 00000000000..f2307867238 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/singletonModelLifetime.qml @@ -0,0 +1,32 @@ +import QtQuick 2.15 +import QtQuick.Window 2.15 +import test 1.0 + +Window { + id: root + visible: true + width: 800 + height: 680 + property bool alive: false + + Component { + id: view + ListView { + model: SingletonModel + } + } + function compare(a,b) { + root.alive = (a === b) + } + + function test_singletonModelCrash() { + SingletonModel.objectName = "model" + var o = view.createObject(root) + o.destroy() + Qt.callLater(function() { + compare(SingletonModel.objectName, "model") + }) + } + + Component.onCompleted: root.test_singletonModelCrash() +} diff --git a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp index c9c77691826..a7f64caaf02 100644 --- a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp +++ b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp @@ -31,12 +31,17 @@ #include <QtQuick/private/qquickitemview_p_p.h> #include <QtQuick/private/qquicklistview_p.h> #include <QtQuickTest/QtQuickTest> -#include "../shared/viewtestutil.h" -#include "../shared/visualtestutil.h" -#include "../../shared/util.h" +#include <QStringListModel> +#include <QQmlApplicationEngine> -using namespace QQuickViewTestUtil; -using namespace QQuickVisualTestUtil; +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> + +Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") + +using namespace QQuickViewTestUtils; +using namespace QQuickVisualTestUtils; class tst_QQuickListView2 : public QQmlDataTest { @@ -46,9 +51,31 @@ class tst_QQuickListView2 : public QQmlDataTest private slots: void urlListModel(); + void dragDelegateWithMouseArea_data(); + void dragDelegateWithMouseArea(); + void delegateChooserEnumRole(); + void QTBUG_92809(); + void footerUpdate(); + void singletonModelLifetime(); + void delegateModelRefresh(); + void noCrashOnIndexChange(); + void tapDelegateDuringFlicking_data(); + void tapDelegateDuringFlicking(); + void flickDuringFlicking_data(); + void flickDuringFlicking(); + void isCurrentItem_DelegateModel(); + void isCurrentItem_NoRegressionWithDelegateModelGroups(); + + void fetchMore_data(); + void fetchMore(); + +private: + void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to); + QScopedPointer<QPointingDevice> touchDevice = QScopedPointer<QPointingDevice>(QTest::createTouchDevice()); }; tst_QQuickListView2::tst_QQuickListView2() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } @@ -71,6 +98,461 @@ void tst_QQuickListView2::urlListModel() QCOMPARE(view->count(), model.size()); } +static void dragListView(QWindow *window, QPoint *startPos, const QPoint &delta) +{ + auto drag_helper = [&](QWindow *window, QPoint *startPos, const QPoint &d) { + QPoint pos = *startPos; + const int dragDistance = d.manhattanLength(); + const QPoint unitVector(qBound(-1, d.x(), 1), qBound(-1, d.y(), 1)); + for (int i = 0; i < dragDistance; ++i) { + QTest::mouseMove(window, pos); + pos += unitVector; + } + // Move to the final position + pos = *startPos + d; + QTest::mouseMove(window, pos); + *startPos = pos; + }; + + if (delta.manhattanLength() == 0) + return; + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); + const QPoint unitVector(qBound(-1, delta.x(), 1), qBound(-1, delta.y(), 1)); + // go just beyond the drag theshold + drag_helper(window, startPos, unitVector * (dragThreshold + 1)); + drag_helper(window, startPos, unitVector); + + // next drag will actually scroll the listview + drag_helper(window, startPos, delta); +} + +void tst_QQuickListView2::dragDelegateWithMouseArea_data() +{ + QTest::addColumn<QQuickItemView::LayoutDirection>("layoutDirection"); + + for (int layDir = QQuickItemView::LeftToRight; layDir <= (int)QQuickItemView::VerticalBottomToTop; layDir++) { + const char *enumValueName = QMetaEnum::fromType<QQuickItemView::LayoutDirection>().valueToKey(layDir); + QTest::newRow(enumValueName) << static_cast<QQuickItemView::LayoutDirection>(layDir); + } +} + +void tst_QQuickListView2::dragDelegateWithMouseArea() +{ + QFETCH(QQuickItemView::LayoutDirection, layoutDirection); + + QScopedPointer<QQuickView> window(createView()); + QVERIFY(window); + window->setFlag(Qt::FramelessWindowHint); + window->setSource(testFileUrl("delegateWithMouseArea.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); + QVERIFY(listview != nullptr); + + const bool horizontal = layoutDirection < QQuickItemView::VerticalTopToBottom; + listview->setOrientation(horizontal ? QQuickListView::Horizontal : QQuickListView::Vertical); + + if (horizontal) + listview->setLayoutDirection(static_cast<Qt::LayoutDirection>(layoutDirection)); + else + listview->setVerticalLayoutDirection(static_cast<QQuickItemView::VerticalLayoutDirection>(layoutDirection)); + + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); + + auto contentPosition = [&](QQuickListView *listview) { + return (listview->orientation() == QQuickListView::Horizontal ? listview->contentX(): listview->contentY()); + }; + + qreal expectedContentPosition = contentPosition(listview); + QPoint startPos = (QPointF(listview->width(), listview->height())/2).toPoint(); + QTest::mousePress(window.data(), Qt::LeftButton, Qt::NoModifier, startPos, 200); + + QPoint dragDelta(0, -10); + + if (layoutDirection == QQuickItemView::RightToLeft || layoutDirection == QQuickItemView::VerticalBottomToTop) + dragDelta = -dragDelta; + expectedContentPosition -= dragDelta.y(); + if (horizontal) + dragDelta = dragDelta.transposed(); + + dragListView(window.data(), &startPos, dragDelta); + + QTest::mouseRelease(window.data(), Qt::LeftButton, Qt::NoModifier, startPos, 200); // Wait 200 ms before we release to avoid trigger a flick + + // wait for the "fixup" animation to finish + QVERIFY(QTest::qWaitFor([&]() + { return !listview->isMoving();} + )); + + QCOMPARE(contentPosition(listview), expectedContentPosition); +} + + +void tst_QQuickListView2::delegateChooserEnumRole() +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("delegateChooserEnumRole.qml"))); + QQuickListView *listview = qobject_cast<QQuickListView*>(window.rootObject()); + QVERIFY(listview); + QTRY_COMPARE(listview->count(), 3); + QCOMPARE(listview->itemAtIndex(0)->property("delegateType").toInt(), 0); + QCOMPARE(listview->itemAtIndex(1)->property("delegateType").toInt(), 1); + QCOMPARE(listview->itemAtIndex(2)->property("delegateType").toInt(), 2); +} + +void tst_QQuickListView2::QTBUG_92809() +{ + QScopedPointer<QQuickView> window(createView()); + QTRY_VERIFY(window); + window->setSource(testFileUrl("qtbug_92809.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); + QTRY_VERIFY(listview != nullptr); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); + listview->setCurrentIndex(1); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); + listview->setCurrentIndex(2); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); + listview->setCurrentIndex(3); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); + QTest::qWait(500); + listview->setCurrentIndex(10); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); + QTest::qWait(500); + int currentIndex = listview->currentIndex(); + QTRY_COMPARE(currentIndex, 9); +} + +void tst_QQuickListView2::footerUpdate() +{ + QScopedPointer<QQuickView> window(createView()); + QTRY_VERIFY(window); + window->setSource(testFileUrl("footerUpdate.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); + QTRY_VERIFY(listview != nullptr); + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); + QQuickItem *footer = listview->footerItem(); + QTRY_VERIFY(footer); + QVERIFY(QQuickTest::qWaitForItemPolished(footer)); + QTRY_COMPARE(footer->y(), 0); +} + +void tst_QQuickListView2::noCrashOnIndexChange() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("noCrashOnIndexChange.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> o(c.create()); + QVERIFY(!o.isNull()); + + QObject *delegateModel = qmlContext(o.data())->objectForName("displayDelegateModel"); + QVERIFY(delegateModel); + + QObject *items = qvariant_cast<QObject *>(delegateModel->property("items")); + QCOMPARE(items->property("name").toString(), QStringLiteral("items")); + QCOMPARE(items->property("count").toInt(), 4); +} + +void tst_QQuickListView2::tapDelegateDuringFlicking_data() +{ + QTest::addColumn<QByteArray>("qmlFile"); + QTest::addColumn<QQuickFlickable::BoundsBehavior>("boundsBehavior"); + QTest::addColumn<bool>("expectCanceled"); + + QTest::newRow("Button StopAtBounds") << QByteArray("buttonDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds) << false; + QTest::newRow("MouseArea StopAtBounds") << QByteArray("mouseAreaDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds) << true; + QTest::newRow("Button DragOverBounds") << QByteArray("buttonDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds) << false; + QTest::newRow("MouseArea DragOverBounds") << QByteArray("mouseAreaDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds) << true; + QTest::newRow("Button OvershootBounds") << QByteArray("buttonDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds) << false; + QTest::newRow("MouseArea OvershootBounds") << QByteArray("mouseAreaDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds) << true; + QTest::newRow("Button DragAndOvershootBounds") << QByteArray("buttonDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds) << false; + QTest::newRow("MouseArea DragAndOvershootBounds") << QByteArray("mouseAreaDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds) << true; +} + +void tst_QQuickListView2::tapDelegateDuringFlicking() // QTBUG-103832 +{ + QFETCH(QByteArray, qmlFile); + QFETCH(QQuickFlickable::BoundsBehavior, boundsBehavior); + QFETCH(bool, expectCanceled); + + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl(qmlFile.constData()))); + QQuickListView *listView = qobject_cast<QQuickListView*>(window.rootObject()); + QVERIFY(listView); + listView->setBoundsBehavior(boundsBehavior); + + flickWithTouch(&window, {100, 400}, {100, 100}); + QTRY_VERIFY(listView->contentY() > 501); // let it flick some distance + QVERIFY(listView->isFlicking()); // we want to test the case when it's still moving while we tap + // @y = 400 we pressed the 4th delegate; started flicking, and the press was canceled + QCOMPARE(listView->property("pressedDelegates").toList().first(), 4); + // At first glance one would expect MouseArea and Button would be consistent about this; + // but in fact, before ListView takes over the grab via filtering, + // Button.pressed transitions to false because QQuickAbstractButtonPrivate::handleMove + // sees that the touchpoint has strayed outside its bounds, but it does NOT emit the canceled signal + if (expectCanceled) { + const QVariantList canceledDelegates = listView->property("canceledDelegates").toList(); + QCOMPARE(canceledDelegates.size(), 1); + QCOMPARE(canceledDelegates.first(), 4); + } + QCOMPARE(listView->property("releasedDelegates").toList().size(), 0); + + // press a delegate during flicking (at y > 501 + 100, so likely delegate 6) + QTest::touchEvent(&window, touchDevice.data()).press(0, {100, 100}); + QQuickTouchUtils::flush(&window); + QTest::touchEvent(&window, touchDevice.data()).release(0, {100, 100}); + QQuickTouchUtils::flush(&window); + + const QVariantList pressedDelegates = listView->property("pressedDelegates").toList(); + const QVariantList releasedDelegates = listView->property("releasedDelegates").toList(); + const QVariantList tappedDelegates = listView->property("tappedDelegates").toList(); + const QVariantList canceledDelegates = listView->property("canceledDelegates").toList(); + + qCDebug(lcTests) << "pressed" << pressedDelegates; // usually [4, 6] + qCDebug(lcTests) << "released" << releasedDelegates; + qCDebug(lcTests) << "tapped" << tappedDelegates; + qCDebug(lcTests) << "canceled" << canceledDelegates; + + // which delegate received the second press, during flicking? + const int lastPressed = pressedDelegates.last().toInt(); + QVERIFY(lastPressed > 5); + QCOMPARE(releasedDelegates.last(), lastPressed); + QCOMPARE(tappedDelegates.last(), lastPressed); + QCOMPARE(canceledDelegates.size(), expectCanceled ? 1 : 0); // only the first press was canceled, not the second +} + +void tst_QQuickListView2::flickDuringFlicking_data() +{ + QTest::addColumn<QByteArray>("qmlFile"); + QTest::addColumn<QQuickFlickable::BoundsBehavior>("boundsBehavior"); + + QTest::newRow("Button StopAtBounds") << QByteArray("buttonDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds); + QTest::newRow("MouseArea StopAtBounds") << QByteArray("mouseAreaDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds); + QTest::newRow("Button DragOverBounds") << QByteArray("buttonDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds); + QTest::newRow("MouseArea DragOverBounds") << QByteArray("mouseAreaDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds); + QTest::newRow("Button OvershootBounds") << QByteArray("buttonDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds); + QTest::newRow("MouseArea OvershootBounds") << QByteArray("mouseAreaDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds); + QTest::newRow("Button DragAndOvershootBounds") << QByteArray("buttonDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds); + QTest::newRow("MouseArea DragAndOvershootBounds") << QByteArray("mouseAreaDelegate.qml") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds); +} + +void tst_QQuickListView2::flickDuringFlicking() // QTBUG-103832 +{ + QFETCH(QByteArray, qmlFile); + QFETCH(QQuickFlickable::BoundsBehavior, boundsBehavior); + + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl(qmlFile.constData()))); + QQuickListView *listView = qobject_cast<QQuickListView*>(window.rootObject()); + QVERIFY(listView); + listView->setBoundsBehavior(boundsBehavior); + + flickWithTouch(&window, {100, 400}, {100, 100}); + QTRY_VERIFY(listView->contentY() > 1000); // let it flick some distance + QVERIFY(listView->isFlicking()); // we want to test the case when it's moving and then we flick again + const qreal posBeforeSecondFlick = listView->contentY(); + + // flick again during flicking, and make sure that it doesn't jump back to the first delegate, + // but flicks incrementally further from the position at that time + QTest::touchEvent(&window, touchDevice.data()).press(0, {100, 400}); + QQuickTouchUtils::flush(&window); + qCDebug(lcTests) << "second press: contentY" << posBeforeSecondFlick << "->" << listView->contentY(); + qCDebug(lcTests) << "pressed delegates" << listView->property("pressedDelegates").toList(); + QVERIFY(listView->contentY() >= posBeforeSecondFlick); + + QTest::qWait(20); + QTest::touchEvent(&window, touchDevice.data()).move(0, {100, 300}); + QQuickTouchUtils::flush(&window); + qCDebug(lcTests) << "first move after second press: contentY" << posBeforeSecondFlick << "->" << listView->contentY(); + QVERIFY(listView->contentY() >= posBeforeSecondFlick); + + QTest::qWait(20); + QTest::touchEvent(&window, touchDevice.data()).move(0, {100, 200}); + QQuickTouchUtils::flush(&window); + qCDebug(lcTests) << "second move after second press: contentY" << posBeforeSecondFlick << "->" << listView->contentY(); + QVERIFY(listView->contentY() >= posBeforeSecondFlick + 100); + + QTest::touchEvent(&window, touchDevice.data()).release(0, {100, 100}); +} + +void tst_QQuickListView2::flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to) +{ + QTest::touchEvent(window, touchDevice.data()).press(0, from, window); + QQuickTouchUtils::flush(window); + + QPoint diff = to - from; + for (int i = 1; i <= 8; ++i) { + QTest::touchEvent(window, touchDevice.data()).move(0, from + i * diff / 8, window); + QQuickTouchUtils::flush(window); + } + QTest::touchEvent(window, touchDevice.data()).release(0, to, window); + QQuickTouchUtils::flush(window); +} + +class SingletonModel : public QStringListModel +{ + Q_OBJECT +public: + SingletonModel(QObject* parent = nullptr) : QStringListModel(parent) { } +}; + +void tst_QQuickListView2::singletonModelLifetime() +{ + // this does not really test any functionality of listview, but we do not have a good way + // to unit test QQmlAdaptorModel in isolation. + qmlRegisterSingletonType<SingletonModel>("test", 1, 0, "SingletonModel", + [](QQmlEngine* , QJSEngine*) -> QObject* { return new SingletonModel; }); + + QQmlApplicationEngine engine(testFile("singletonModelLifetime.qml")); + // needs event loop iteration for callLater to execute + QTRY_VERIFY(engine.rootObjects().first()->property("alive").toBool()); +} + +void tst_QQuickListView2::delegateModelRefresh() +{ + // Test case originates from QTBUG-100161 + QQmlApplicationEngine engine(testFile("delegateModelRefresh.qml")); + QVERIFY(!engine.rootObjects().isEmpty()); + // needs event loop iteration for callLater to execute + QTRY_VERIFY(engine.rootObjects().first()->property("done").toBool()); +} + +void tst_QQuickListView2::isCurrentItem_DelegateModel() +{ + QScopedPointer<QQuickView> window(createView()); + window->setSource(testFileUrl("qtbug86744.qml")); + window->resize(640, 480); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QQuickListView* listView = window->rootObject()->findChild<QQuickListView*>("listView"); + QVERIFY(listView); + QVariant value = listView->itemAtIndex(1)->property("isCurrent"); + QVERIFY(value.toBool() == true); +} + +void tst_QQuickListView2::isCurrentItem_NoRegressionWithDelegateModelGroups() +{ + QScopedPointer<QQuickView> window(createView()); + window->setSource(testFileUrl("qtbug98315.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QQuickListView* listView = window->rootObject()->findChild<QQuickListView*>("listView"); + QVERIFY(listView); + + QQuickItem *item3 = listView->itemAtIndex(1); + QVERIFY(item3); + QCOMPARE(item3->property("isCurrent").toBool(), true); + + QObject *item0 = listView->itemAtIndex(0); + QVERIFY(item0); + QCOMPARE(item0->property("isCurrent").toBool(), false); + + // Press left arrow key -> Item 1 should become current, Item 3 should not + // be current anymore. After a previous fix of QTBUG-86744 it was working + // incorrectly - see QTBUG-98315 + QTest::keyPress(window.get(), Qt::Key_Left); + + QTRY_COMPARE(item0->property("isCurrent").toBool(), true); + QCOMPARE(item3->property("isCurrent").toBool(), false); +} + +class TestFetchMoreModel : public QAbstractListModel +{ + Q_OBJECT + +public: + QVariant data(const QModelIndex& index, int role) const override + { + if (role == Qt::DisplayRole) + return QString::number(index.row()); + return {}; + } + + int columnCount(const QModelIndex&) const override { return 1; } + + int rowCount(const QModelIndex& parent) const override + { + return parent.isValid() ? 0 : m_lines; + } + + QModelIndex parent(const QModelIndex&) const override { return {}; } + + bool canFetchMore(const QModelIndex &) const override { return true; } + + void fetchMore(const QModelIndex & parent) override + { + if (Q_UNLIKELY(parent.isValid())) + return; + beginInsertRows(parent, m_lines, m_lines); + m_lines++; + endInsertRows(); + } + + int m_lines = 3; +}; + +void tst_QQuickListView2::fetchMore_data() +{ + QTest::addColumn<bool>("reuseItems"); + QTest::addColumn<int>("cacheBuffer"); + + QTest::newRow("no reuseItems, default buffer") << false << -1; + QTest::newRow("reuseItems, default buffer") << true << -1; + QTest::newRow("no reuseItems, no buffer") << false << 0; + QTest::newRow("reuseItems, no buffer") << true << 0; + QTest::newRow("no reuseItems, buffer 100 px") << false << 100; + QTest::newRow("reuseItems, buffer 100 px") << true << 100; +} + +void tst_QQuickListView2::fetchMore() // QTBUG-95107 +{ + QFETCH(bool, reuseItems); + QFETCH(int, cacheBuffer); + + TestFetchMoreModel model; + qmlRegisterSingletonInstance("org.qtproject.Test", 1, 0, "FetchMoreModel", &model); + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("fetchMore.qml"))); + auto *listView = qobject_cast<QQuickListView*>(window.rootObject()); + QVERIFY(listView); + listView->setReuseItems(reuseItems); + if (cacheBuffer >= 0) + listView->setCacheBuffer(cacheBuffer); + + for (int i = 0; i < 3; ++i) { + const int rowCount = listView->count(); + if (lcTests().isDebugEnabled()) QTest::qWait(1000); + listView->flick(0, -5000); + QTRY_VERIFY(!listView->isMoving()); + qCDebug(lcTests) << "after flick: contentY" << listView->contentY() + << "rows" << rowCount << "->" << listView->count(); + QVERIFY(listView->count() > rowCount); + QVERIFY(model.m_lines >= listView->count()); // fetchMore() was called + } +} + QTEST_MAIN(tst_QQuickListView2) #include "tst_qquicklistview2.moc" diff --git a/tests/auto/quick/qquicklistview2/typerolemodel.cpp b/tests/auto/quick/qquicklistview2/typerolemodel.cpp new file mode 100644 index 00000000000..a7604f0ba55 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/typerolemodel.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 "typerolemodel.h" + +TypeRoleModel::TypeRoleModel(QObject *parent) + : QAbstractListModel(parent) +{ + _mapRoleNames[TypeRole] = "type"; + _mapRoleNames[TextRole] = "text"; +} + +int TypeRoleModel::rowCount(const QModelIndex &) const +{ + return 3; +} + +QVariant TypeRoleModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return {}; + + constexpr Type types[] = { + Type::PlainText, + Type::Markdown, + Type::Rect + }; + switch (role) { + case TypeRole: { + const Type type = types[index.row() % std::size(types)]; + return QVariant::fromValue(type); + } + case TextRole: { + if (index.row() % std::size(types) == int(Type::Markdown)) + return "*row* " + QString::number(index.row()); + return "row " + QString::number(index.row()); + } + } + + return {}; +} diff --git a/tests/auto/quick/qquicklistview2/typerolemodel.h b/tests/auto/quick/qquicklistview2/typerolemodel.h new file mode 100644 index 00000000000..980484a0442 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/typerolemodel.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <QAbstractListModel> +#include <qqml.h> + +class TypeRoleModel : public QAbstractListModel +{ + Q_OBJECT + QML_ELEMENT + +public: + enum Role { + TypeRole = Qt::UserRole + 1, + TextRole, + }; + Q_ENUM(Role) + + enum class Type { PlainText, Markdown, Rect }; + Q_ENUM(Type) + + explicit TypeRoleModel(QObject *parent = nullptr); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QHash<int, QByteArray> roleNames() const override { return _mapRoleNames; } + +private: + QHash<int, QByteArray> _mapRoleNames; +}; diff --git a/tests/auto/quick/qquickloader/BLACKLIST b/tests/auto/quick/qquickloader/BLACKLIST index 30c02e4c132..a45a300607d 100644 --- a/tests/auto/quick/qquickloader/BLACKLIST +++ b/tests/auto/quick/qquickloader/BLACKLIST @@ -2,5 +2,3 @@ # QTBUG-63049 [asyncToSync1] b2qt -[urlToComponent] -macos diff --git a/tests/auto/quick/qquickloader/CMakeLists.txt b/tests/auto/quick/qquickloader/CMakeLists.txt index 785d5348a60..e27ff0a57be 100644 --- a/tests/auto/quick/qquickloader/CMakeLists.txt +++ b/tests/auto/quick/qquickloader/CMakeLists.txt @@ -12,16 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickloader SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickloader.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -29,6 +20,7 @@ qt_internal_add_test(tst_qquickloader Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickloader/data/loader-async-race-rect.qml b/tests/auto/quick/qquickloader/data/loader-async-race-rect.qml new file mode 100644 index 00000000000..a56dcea5ad1 --- /dev/null +++ b/tests/auto/quick/qquickloader/data/loader-async-race-rect.qml @@ -0,0 +1,10 @@ +import QtQuick 2.15 + +Rectangle { + anchors.fill: parent + color: "blue" + Item { + Item { + } + } +} diff --git a/tests/auto/quick/qquickloader/data/loader-async-race.qml b/tests/auto/quick/qquickloader/data/loader-async-race.qml new file mode 100644 index 00000000000..8ba625c5c1f --- /dev/null +++ b/tests/auto/quick/qquickloader/data/loader-async-race.qml @@ -0,0 +1,14 @@ +import QtQuick 2.15 + +Item { + id: root + Component.onCompleted: { + myloader.active = false + } + Loader { + id: myloader + anchors.fill: parent + asynchronous: true + source: "loader-async-race-rect.qml" + } +} diff --git a/tests/auto/quick/qquickloader/data/noEngine.qml b/tests/auto/quick/qquickloader/data/noEngine.qml new file mode 100644 index 00000000000..19e619f32e9 --- /dev/null +++ b/tests/auto/quick/qquickloader/data/noEngine.qml @@ -0,0 +1,32 @@ +import QtQuick 2 + +Item { + id: root + property bool a: false + property int changes: 0 + onAChanged: { + m.model = 0 + m.model = 1 + ++changes; + } + + Repeater { + id: m + model: 1 + + Item { + Timer { + onTriggered: { + root.a = true + l.source = "loaded.qml" + } + interval: 0 + running: true + } + + Loader { + id: l + } + } + } +} diff --git a/tests/auto/quick/qquickloader/data/overflow.qml b/tests/auto/quick/qquickloader/data/overflow.qml new file mode 100644 index 00000000000..e5fdfee182f --- /dev/null +++ b/tests/auto/quick/qquickloader/data/overflow.qml @@ -0,0 +1,5 @@ +import QtQuick + +Loader { + source: "overflow.qml" +} diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp index 4a2c7b0af0c..067fa759d83 100644 --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp @@ -36,9 +36,9 @@ #include <QtQuick/qquickview.h> #include <private/qquickloader_p.h> #include <private/qquickwindowmodule_p.h> -#include "testhttpserver.h" -#include "../../shared/util.h" -#include "../shared/geometrytestutil.h" +#include <QtQuickTestUtils/private/geometrytestutils_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/testhttpserver_p.h> #include <QQmlApplicationEngine> Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") @@ -133,11 +133,17 @@ private slots: void statusChangeOnlyEmittedOnce(); void setSourceAndCheckStatus(); + void loadComponentWithStates(); + void asyncLoaderRace(); + void noEngine(); + + void stackOverflow(); }; Q_DECLARE_METATYPE(QList<QQmlError>) tst_QQuickLoader::tst_QQuickLoader() + : QQmlDataTest(QT_QMLTEST_DATADIR) { qmlRegisterType<SlowComponent>("LoaderTest", 1, 0, "SlowComponent"); qRegisterMetaType<QList<QQmlError>>(); @@ -708,7 +714,7 @@ void tst_QQuickLoader::initialPropertyValues_data() << (QVariantList() << 12); QTest::newRow("initial property errors get reported") << testFileUrl("initialPropertyTriggerException.qml") - << (QStringList() << "^.*: Error: Cannot assign JavaScript function to int") + << (QStringList() << "^.*:10: Error: Cannot assign JavaScript function to int") << QStringList() << QVariantList(); } @@ -1513,6 +1519,69 @@ void tst_QQuickLoader::setSourceAndCheckStatus() QCOMPARE(loader->status(), QQuickLoader::Null); } +void tst_QQuickLoader::loadComponentWithStates() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(QByteArray("import QtQuick\n" + "Loader {\n" + "id: loader\n" + "property int createdObjCount: 0\n" + "states: [ State { when: true; PropertyChanges { target: loader; sourceComponent: myComp } } ]\n" + "Component { id: myComp; Item { Component.onCompleted: { ++createdObjCount } } }\n" + "}" ) + , dataDirectoryUrl()); + QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create())); + QTest::qWait(200); + QTRY_VERIFY(loader != nullptr); + QVERIFY(loader->item()); + QCOMPARE(static_cast<QQuickItem*>(loader.data())->childItems().size(), 1); + QCOMPARE(loader->property("createdObjCount").toInt(), 1); +} + +void tst_QQuickLoader::asyncLoaderRace() +{ + QQmlApplicationEngine engine; + auto url = testFileUrl("loader-async-race.qml"); + engine.load(url); + auto root = engine.rootObjects().at(0); + QVERIFY(root); + + QQuickLoader *loader = root->findChild<QQuickLoader *>(); + QCOMPARE(loader->active(), false); + QCOMPARE(loader->status(), QQuickLoader::Null); + QCOMPARE(loader->item(), nullptr); + + QSignalSpy spy(loader, &QQuickLoader::itemChanged); + QVERIFY(!spy.wait(100)); + QCOMPARE(loader->item(), nullptr); +} + +void tst_QQuickLoader::noEngine() +{ + QQmlEngine engine; + const QUrl url = testFileUrl("noEngine.qml"); + QQmlComponent component(&engine, url); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + QScopedPointer<QObject> o(component.create()); + + const QString message = url.toString() + + QStringLiteral(":27:13: QML Loader: createComponent: Cannot find a QML engine."); + QTest::ignoreMessage(QtWarningMsg, qPrintable(message)); + QTRY_COMPARE(o->property("changes").toInt(), 1); +} + +void tst_QQuickLoader::stackOverflow() +{ + QQmlEngine engine; + const QUrl url = testFileUrl("overflow.qml"); + QQmlComponent component(&engine, url); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + const QString message = url.toString() + QStringLiteral(": Maximum call stack size exceeded."); + QTest::ignoreMessage(QtCriticalMsg, qPrintable(message)); + QScopedPointer<QObject> o(component.create()); +} + QTEST_MAIN(tst_QQuickLoader) #include "tst_qquickloader.moc" diff --git a/tests/auto/quick/qquickmousearea/BLACKLIST b/tests/auto/quick/qquickmousearea/BLACKLIST index 61eb8043e21..f635061f7fe 100644 --- a/tests/auto/quick/qquickmousearea/BLACKLIST +++ b/tests/auto/quick/qquickmousearea/BLACKLIST @@ -1,6 +1,3 @@ -[pressAndHold] -macos ci - # QTBUG-78153 [nestedStopAtBounds] opensuse-leap @@ -9,3 +6,8 @@ opensuse-leap [pressOneAndTapAnother] opensuse-leap +# QTBUG-103092 +[pressOneAndTapAnother] +android +[containsMouseAndVisibility] +android diff --git a/tests/auto/quick/qquickmousearea/CMakeLists.txt b/tests/auto/quick/qquickmousearea/CMakeLists.txt index 7061c92384a..2f9b10fe558 100644 --- a/tests/auto/quick/qquickmousearea/CMakeLists.txt +++ b/tests/auto/quick/qquickmousearea/CMakeLists.txt @@ -12,16 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickmousearea SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickmousearea.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -29,6 +20,7 @@ qt_internal_add_test(tst_qquickmousearea Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickmousearea/data/doubleClickToHide.qml b/tests/auto/quick/qquickmousearea/data/doubleClickToHide.qml new file mode 100644 index 00000000000..01f6eaabed5 --- /dev/null +++ b/tests/auto/quick/qquickmousearea/data/doubleClickToHide.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +Item { + id: root + property int clicked: 0 + property int doubleClicked: 0 + property int released: 0 + + MouseArea { + width: 200; height: 200 + onClicked: { root.clicked++ } + onDoubleClicked: { + root.doubleClicked++ + visible = false + } + onReleased: { root.released++ } + } +} + diff --git a/tests/auto/quick/qquickmousearea/data/preventStealingListViewChild.qml b/tests/auto/quick/qquickmousearea/data/preventStealingListViewChild.qml new file mode 100644 index 00000000000..3833c5a8a9d --- /dev/null +++ b/tests/auto/quick/qquickmousearea/data/preventStealingListViewChild.qml @@ -0,0 +1,31 @@ +import QtQuick 2.15 + +ListView { + id: flick + width: 640 + height: 480 + model: 100 + + delegate: Rectangle { + border.color: "#81e889" + width: 640; height: 100 + Text { text: "Row " + index } + } + + Rectangle { + anchors.right: parent.right + anchors.margins: 2 + color: ma.pressed ? "#81e889" : "#c2f4c6" + width: 50; height: 50 + radius: 5 + MouseArea { + id: ma + anchors.fill: parent + preventStealing: true + drag { + target: parent + axis: Drag.YAxis + } + } + } +} diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp index 1e9f76c8cef..50cc5367953 100644 --- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp +++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp @@ -36,8 +36,8 @@ #include <QtQuick/qquickview.h> #include <QtQml/qqmlcontext.h> #include <QtQml/qqmlengine.h> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> #include <QtGui/qstylehints.h> #include <QtGui/QCursor> #include <QtGui/QScreen> @@ -89,6 +89,7 @@ class tst_QQuickMouseArea: public QQmlDataTest Q_OBJECT public: tst_QQuickMouseArea() + : QQmlDataTest(QT_QMLTEST_DATADIR) { qmlRegisterType<CircleMask>("Test", 1, 0, "CircleMask"); qmlRegisterType<EventSender>("Test", 1, 0, "EventSender"); @@ -122,6 +123,7 @@ private slots: void invalidClick(); void pressedOrdering(); void preventStealing(); + void preventStealingListViewChild(); void clickThrough(); void hoverPosition(); void hoverPropagation(); @@ -155,6 +157,7 @@ private slots: void settingHiddenInPressUngrabs(); void negativeZStackingOrder(); void containsMouseAndVisibility(); + void doubleClickToHide(); private: int startDragDistance() const { @@ -1090,6 +1093,36 @@ void tst_QQuickMouseArea::preventStealing() QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, p); } +// QTBUG-103522 +void tst_QQuickMouseArea::preventStealingListViewChild() +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("preventStealingListViewChild.qml"))); + QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window.rootObject()); + QVERIFY(flickable); + QQuickMouseArea *mouseArea = flickable->findChild<QQuickMouseArea*>(); + QVERIFY(mouseArea); + QPoint p = mouseArea->mapToScene(mouseArea->boundingRect().center()).toPoint(); + const int threshold = qApp->styleHints()->startDragDistance(); + + flickable->flick(0, -10000); + for (int i = 0; i < 2; ++i) { + QVERIFY(flickable->isMovingVertically()); + QTest::touchEvent(&window, device).press(0, p); + QQuickTouchUtils::flush(&window); + for (int j = 0; j < 4 && !mouseArea->drag()->active(); ++j) { + p += QPoint(0, threshold); + QTest::touchEvent(&window, device).move(0, p); + QQuickTouchUtils::flush(&window); + } + // MouseArea should be dragged because of preventStealing; ListView does not steal the grab. + QVERIFY(mouseArea->drag()->active()); + QCOMPARE(flickable->isDragging(), false); + QTest::touchEvent(&window, device).release(0, p); + QCOMPARE(mouseArea->drag()->active(), false); + } +} + void tst_QQuickMouseArea::clickThrough() { // timestamp delay to avoid generating a double click @@ -2344,6 +2377,29 @@ void tst_QQuickMouseArea::containsMouseAndVisibility() QVERIFY(!mouseArea->hovered()); } +// QTBUG-35995 and QTBUG-102158 +void tst_QQuickMouseArea::doubleClickToHide() +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("doubleClickToHide.qml"))); + + QQuickMouseArea *mouseArea = window.rootObject()->findChild<QQuickMouseArea *>(); + QVERIFY(mouseArea); + + QTest::mouseDClick(&window, Qt::LeftButton, Qt::NoModifier, {10, 10}); + + QCOMPARE(window.rootObject()->property("clicked").toInt(), 1); + QCOMPARE(window.rootObject()->property("doubleClicked").toInt(), 1); + QCOMPARE(mouseArea->isVisible(), false); + QCOMPARE(mouseArea->pressed(), false); + QCOMPARE(mouseArea->pressedButtons(), Qt::NoButton); + + mouseArea->setVisible(true); + + QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, {10, 10}); + QCOMPARE(window.rootObject()->property("clicked").toInt(), 2); +} + QTEST_MAIN(tst_QQuickMouseArea) #include "tst_qquickmousearea.moc" diff --git a/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST b/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST index abe504d20c7..2488eff2706 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST +++ b/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST @@ -1,4 +1,6 @@ [nonOverlapping] ubuntu-20.04 +ubuntu-22.04 [nested] ubuntu-20.04 +ubuntu-22.04 diff --git a/tests/auto/quick/qquickmultipointtoucharea/CMakeLists.txt b/tests/auto/quick/qquickmultipointtoucharea/CMakeLists.txt index 1902b3fefaa..30c1109c212 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/CMakeLists.txt +++ b/tests/auto/quick/qquickmultipointtoucharea/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickmultipointtoucharea SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickmultipointtoucharea.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickmultipointtoucharea/data/inFlickable.qml b/tests/auto/quick/qquickmultipointtoucharea/data/inFlickable.qml index 32733613b3d..fada2b3370d 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/data/inFlickable.qml +++ b/tests/auto/quick/qquickmultipointtoucharea/data/inFlickable.qml @@ -43,8 +43,8 @@ Rectangle { TouchPoint { id: point2; objectName: "point2" } ] - onCanceled: root.cancelCount = touchPoints.length - onTouchUpdated: root.touchCount = touchPoints.length + onCanceled: (touchPoints) => root.cancelCount = touchPoints.length + onTouchUpdated: (touchPoints) => root.touchCount = touchPoints.length Text { text: "①" diff --git a/tests/auto/quick/qquickmultipointtoucharea/data/nestedMouseArea.qml b/tests/auto/quick/qquickmultipointtoucharea/data/nestedMouseArea.qml new file mode 100644 index 00000000000..7ca3f187d69 --- /dev/null +++ b/tests/auto/quick/qquickmultipointtoucharea/data/nestedMouseArea.qml @@ -0,0 +1,26 @@ +import QtQuick 2.12 + +Item { + id: root + width: 300; height: 300 + property point mptaPoint + property point maPoint + MultiPointTouchArea { + anchors.fill : parent + onPressed: function(touchPoints) { + root.mptaPoint = Qt.point(touchPoints[0].x, touchPoints[0].y) + } + MouseArea { + id: ma + width: 100; height: 100 + anchors.centerIn: parent + onPressed: function(mouse) { + root.maPoint = Qt.point(mouse.x, mouse.y) + } + } + Rectangle { + anchors.fill: ma + border.color: "grey" + } + } +} diff --git a/tests/auto/quick/qquickmultipointtoucharea/data/nestedPinchArea.qml b/tests/auto/quick/qquickmultipointtoucharea/data/nestedPinchArea.qml new file mode 100644 index 00000000000..0e51804b305 --- /dev/null +++ b/tests/auto/quick/qquickmultipointtoucharea/data/nestedPinchArea.qml @@ -0,0 +1,44 @@ +import QtQuick 2.15 + +MultiPointTouchArea { + width: 240 + height: 320 + mouseEnabled: true + property int pressedCount: 0 + property int updatedCount: 0 + property int releasedCount: 0 + + onPressed: (points) => { pressedCount = points.length } + onUpdated: (points) => { updatedCount = points.length } + onReleased: (points) => { releasedCount = points.length } + + touchPoints: [ + TouchPoint { + id: point1 + objectName: "point1" + }, + TouchPoint { + id: point2 + objectName: "point2" + } + ] + + PinchArea { + anchors.fill: parent + } + + Rectangle { + width: 30; height: 30 + color: "green" + x: point1.x + y: point1.y + } + + Rectangle { + id: rectangle + width: 30; height: 30 + color: "yellow" + x: point2.x + y: point2.y + } +} diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp index 056028b3f07..f85fba45d60 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp +++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp @@ -37,9 +37,10 @@ #include <QtQuick/qquickview.h> #include <QtGui/QScreen> #include <QtGui/private/qevent_p.h> +#include <QtGui/private/qeventpoint_p.h> #include <QtGui/private/qpointingdevice_p.h> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") @@ -47,7 +48,7 @@ class tst_QQuickMultiPointTouchArea : public QQmlDataTest { Q_OBJECT public: - tst_QQuickMultiPointTouchArea() { } + tst_QQuickMultiPointTouchArea() : QQmlDataTest(QT_QMLTEST_DATADIR) { } private slots: void cleanupTestCase() {} @@ -72,6 +73,8 @@ private slots: void mouseGestureStarted(); void cancel(); void stationaryTouchWithChangingPressure(); + void touchFiltering(); + void nestedPinchAreaMouse(); private: QQuickView *createAndShowView(const QString &file); @@ -575,6 +578,10 @@ void tst_QQuickMultiPointTouchArea::nested() void tst_QQuickMultiPointTouchArea::inFlickable() { +#ifdef Q_OS_ANDROID + QSKIP("On Android, QPointingDevicePrivate::queryPointById() sometimes fails to find a point 'in play' (QTBUG-117079)"); +#endif + QScopedPointer<QQuickView> window(createAndShowView("inFlickable.qml")); QVERIFY(window->rootObject() != nullptr); @@ -593,7 +600,7 @@ void tst_QQuickMultiPointTouchArea::inFlickable() QPoint p1(20,100); QPoint p2(40,100); - // moving one point vertically + // moving one point vertically: flickable gets the grab QTest::touchEvent(window.data(), device).press(0, p1); QQuickTouchUtils::flush(window.data()); @@ -617,7 +624,8 @@ void tst_QQuickMultiPointTouchArea::inFlickable() QTRY_VERIFY(!flickable->isMoving()); - // moving two points vertically + // moving two points vertically: MPTAs handle them, Flickable ignores multi-touch. + // The stray mouse events simulate OS-level synth-from-touch, and should not interfere. p1 = QPoint(20,100); QTest::touchEvent(window.data(), device).press(0, p1).press(1, p2); QTest::mousePress(window.data(), Qt::LeftButton, Qt::NoModifier, p1); @@ -639,11 +647,11 @@ void tst_QQuickMultiPointTouchArea::inFlickable() i, p1.x(), p1.y(), p2.x(), p2.y(), flickable->contentY()); } - QVERIFY(flickable->contentY() < 0); - QCOMPARE(point11->pressed(), false); - QCOMPARE(point12->pressed(), false); - QCOMPARE(window->rootObject()->property("cancelCount").toInt(), 2); - QCOMPARE(window->rootObject()->property("touchCount").toInt(), 0); + QCOMPARE(flickable->contentY(), 0); + QCOMPARE(point11->pressed(), true); + QCOMPARE(point12->pressed(), true); + QCOMPARE(window->rootObject()->property("cancelCount").toInt(), 0); + QCOMPARE(window->rootObject()->property("touchCount").toInt(), 2); QTest::touchEvent(window.data(), device).release(0, p1).release(1, p2); QTest::mouseRelease(window.data(), Qt::LeftButton, Qt::NoModifier, p1); @@ -678,10 +686,8 @@ void tst_QQuickMultiPointTouchArea::inFlickable() i, p1.x(), p1.y(), p2.x(), p2.y(), flickable->contentY()); } - QEXPECT_FAIL("", "currently flickable does grab the actual mouse", Continue); QCOMPARE(flickable->contentY(), qreal(0)); QCOMPARE(point11->pressed(), true); - QEXPECT_FAIL("", "currently flickable does grab the actual mouse", Continue); QCOMPARE(point12->pressed(), true); QTest::touchEvent(window.data(), device).release(0, p1).release(1, p2); @@ -692,12 +698,16 @@ void tst_QQuickMultiPointTouchArea::inFlickable() // test that dragging out of a Flickable containing a MPTA doesn't harm Flickable's state. void tst_QQuickMultiPointTouchArea::inFlickable2() { + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); QScopedPointer<QQuickView> window(createAndShowView("inFlickable2.qml")); QVERIFY(window->rootObject() != nullptr); QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>("flickable"); QVERIFY(flickable != nullptr); + QQuickMultiPointTouchArea *mpta = window->rootObject()->findChild<QQuickMultiPointTouchArea*>(); + QVERIFY(mpta); + QQuickTouchPoint *point11 = window->rootObject()->findChild<QQuickTouchPoint*>("point1"); QVERIFY(point11); @@ -710,25 +720,12 @@ void tst_QQuickMultiPointTouchArea::inFlickable2() QQuickTouchUtils::flush(window.data()); QTest::mousePress(window.data(), Qt::LeftButton, Qt::NoModifier, p1); - p1 += QPoint(15,0); - QTest::touchEvent(window.data(), device).move(0, p1); - QQuickTouchUtils::flush(window.data()); - QTest::mouseMove(window.data(), p1); - - p1 += QPoint(15,0); - QTest::touchEvent(window.data(), device).move(0, p1); - QQuickTouchUtils::flush(window.data()); - QTest::mouseMove(window.data(), p1); - - p1 += QPoint(15,0); - QTest::touchEvent(window.data(), device).move(0, p1); - QQuickTouchUtils::flush(window.data()); - QTest::mouseMove(window.data(), p1); - - p1 += QPoint(15,0); - QTest::touchEvent(window.data(), device).move(0, p1); - QQuickTouchUtils::flush(window.data()); - QTest::mouseMove(window.data(), p1); + for (int i = 0; i < 4; ++i) { + p1 += QPoint(dragThreshold, 0); + QTest::touchEvent(window.data(), device).move(0, p1); + QQuickTouchUtils::flush(window.data()); + QTest::mouseMove(window.data(), p1); + } QVERIFY(!flickable->isMoving()); QVERIFY(point11->pressed()); @@ -741,27 +738,21 @@ void tst_QQuickMultiPointTouchArea::inFlickable2() QTRY_VERIFY(!flickable->isMoving()); // Check that we can still move the Flickable + QSignalSpy gestureStartedSpy(mpta, &QQuickMultiPointTouchArea::gestureStarted); p1 = QPoint(50,100); QTest::touchEvent(window.data(), device).press(0, p1); QQuickTouchUtils::flush(window.data()); QCOMPARE(point11->pressed(), true); - p1 += QPoint(0,15); - QTest::touchEvent(window.data(), device).move(0, p1); - QQuickTouchUtils::flush(window.data()); - - p1 += QPoint(0,15); - QTest::touchEvent(window.data(), device).move(0, p1); - QQuickTouchUtils::flush(window.data()); - - p1 += QPoint(0,15); - QTest::touchEvent(window.data(), device).move(0, p1); - QQuickTouchUtils::flush(window.data()); - - p1 += QPoint(0,15); - QTest::touchEvent(window.data(), device).move(0, p1); - QQuickTouchUtils::flush(window.data()); + for (int i = 0; i < 4; ++i) { + p1 += QPoint(0, dragThreshold); + QTest::touchEvent(window.data(), device).move(0, p1); + QQuickTouchUtils::flush(window.data()); + // QTBUG-113653: gestureStarted is emitted when touch delta exceeds drag threshold, + // regardless of the filtering Flickable parent + QCOMPARE(gestureStartedSpy.size(), i > 0 ? 1 : 0); + } QVERIFY(flickable->contentY() < 0); QVERIFY(flickable->isMoving()); @@ -1377,6 +1368,66 @@ void tst_QQuickMultiPointTouchArea::stationaryTouchWithChangingPressure() // QTB QCOMPARE(point1->pressure(), 0); } +void tst_QQuickMultiPointTouchArea::touchFiltering() // QTBUG-74028 +{ + QScopedPointer<QQuickView> window(createAndShowView("nestedMouseArea.qml")); + QVERIFY(window->rootObject() != nullptr); + QQuickMultiPointTouchArea *mpta = window->rootObject()->findChild<QQuickMultiPointTouchArea*>(); + QVERIFY(mpta); + QQuickMouseArea *ma = window->rootObject()->findChild<QQuickMouseArea*>(); + QVERIFY(ma); + + QSignalSpy mptaSpy(mpta, &QQuickMultiPointTouchArea::pressed); + const QPoint pt = window->rootObject()->boundingRect().center().toPoint(); + QTest::touchEvent(window.data(), device).press(1, pt); + QQuickTouchUtils::flush(window.data()); + QTRY_COMPARE(mpta->parentItem()->property("mptaPoint").toPoint(), pt); + QCOMPARE(mpta->parentItem()->property("maPoint").toPoint(), ma->boundingRect().center().toPoint()); + QCOMPARE(mptaSpy.count(), 1); +} + +void tst_QQuickMultiPointTouchArea::nestedPinchAreaMouse() // QTBUG-83662 +{ + QScopedPointer<QQuickView> window(createAndShowView("nestedPinchArea.qml")); + QQuickMultiPointTouchArea *mpta = qobject_cast<QQuickMultiPointTouchArea *>(window->rootObject()); + QVERIFY(mpta); + QQuickTouchPoint *point1 = mpta->findChild<QQuickTouchPoint*>("point1"); + QCOMPARE(point1->pressed(), false); + QQuickTouchPoint *point2 = mpta->findChild<QQuickTouchPoint*>("point2"); + QCOMPARE(point2->pressed(), false); + QSignalSpy pressedSpy(mpta, &QQuickMultiPointTouchArea::pressed); + QSignalSpy updatedSpy(mpta, &QQuickMultiPointTouchArea::updated); + QSignalSpy releasedSpy(mpta, &QQuickMultiPointTouchArea::released); + QPoint p1(20, 20); + QTest::mousePress(window.data(), Qt::LeftButton, Qt::NoModifier, p1); + QCOMPARE(point1->pressed(), true); + QCOMPARE(point2->pressed(), false); + QCOMPARE(pressedSpy.count(), 1); + QCOMPARE(mpta->property("pressedCount").toInt(), 1); + QCOMPARE(updatedSpy.count(), 0); + QCOMPARE(mpta->property("updatedCount").toInt(), 0); + QCOMPARE(releasedSpy.count(), 0); + QCOMPARE(mpta->property("releasedCount").toInt(), 0); + p1 += QPoint(0, 15); + QTest::mouseMove(window.data(), p1); + QCOMPARE(point1->pressed(), true); + QCOMPARE(point2->pressed(), false); + QCOMPARE(pressedSpy.count(), 1); + QCOMPARE(mpta->property("pressedCount").toInt(), 1); + QCOMPARE(updatedSpy.count(), 1); + QCOMPARE(mpta->property("updatedCount").toInt(), 1); + QCOMPARE(releasedSpy.count(), 0); + QCOMPARE(mpta->property("releasedCount").toInt(), 0); + QTest::mouseRelease(window.data(), Qt::LeftButton, Qt::NoModifier, p1); + QCOMPARE(point1->pressed(), false); + QCOMPARE(point2->pressed(), false); + QCOMPARE(pressedSpy.count(), 1); + QCOMPARE(mpta->property("pressedCount").toInt(), 1); + QCOMPARE(updatedSpy.count(), 1); + QCOMPARE(mpta->property("updatedCount").toInt(), 1); + QCOMPARE(releasedSpy.count(), 1); + QCOMPARE(mpta->property("releasedCount").toInt(), 1); +} QTEST_MAIN(tst_QQuickMultiPointTouchArea) diff --git a/tests/auto/quick/qquickpainteditem/BLACKLIST b/tests/auto/quick/qquickpainteditem/BLACKLIST index 9b58325f6c6..6d8597b8308 100644 --- a/tests/auto/quick/qquickpainteditem/BLACKLIST +++ b/tests/auto/quick/qquickpainteditem/BLACKLIST @@ -1,27 +1,34 @@ # QTBUG-63053 [opaquePainting] b2qt +qnx # QTBUG-63053 [antialiasing] b2qt +qnx # QTBUG-63053 [mipmap] b2qt +qnx # QTBUG-63053 [performanceHints] b2qt +qnx # QTBUG-63053 [contentScale] b2qt +qnx # QTBUG-63053 [contentsBoundingRect] b2qt +qnx # QTBUG-63053 [fillColor] b2qt +qnx diff --git a/tests/auto/quick/qquickpalette/CMakeLists.txt b/tests/auto/quick/qquickpalette/CMakeLists.txt index a68873d5dce..eefecc7ac3a 100644 --- a/tests/auto/quick/qquickpalette/CMakeLists.txt +++ b/tests/auto/quick/qquickpalette/CMakeLists.txt @@ -1,8 +1,8 @@ -# Generated from qquickpalette.pro. - -##################################################################### -## tst_qquickpalette Test: -##################################################################### +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickpalette SOURCES @@ -12,7 +12,16 @@ qt_internal_add_test(tst_qquickpalette Qt::Gui Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate + TESTDATA ${test_data} +) + +qt_internal_extend_target(tst_qquickpalette CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" ) -## Scopes: -##################################################################### +qt_internal_extend_target(tst_qquickpalette CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quick/qquickpalette/data/palette-item-custom.qml b/tests/auto/quick/qquickpalette/data/palette-item-custom.qml new file mode 100644 index 00000000000..96aca3ec0d3 --- /dev/null +++ b/tests/auto/quick/qquickpalette/data/palette-item-custom.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Item { + palette.alternateBase: "aqua" + palette.base: "azure" + palette.brightText: "beige" + palette.button: "bisque" + palette.buttonText: "chocolate" + palette.dark: "coral" + palette.highlight: "crimson" + palette.highlightedText: "fuchsia" + palette.light: "gold" + palette.link: "indigo" + palette.linkVisited: "ivory" + palette.mid: "khaki" + palette.midlight: "lavender" + palette.shadow: "linen" + palette.text: "moccasin" + palette.toolTipBase: "navy" + palette.toolTipText: "orchid" + palette.window: "plum" + palette.windowText: "salmon" +} diff --git a/tests/auto/quick/qquickpalette/data/palette-item-default.qml b/tests/auto/quick/qquickpalette/data/palette-item-default.qml new file mode 100644 index 00000000000..d9dcdeceba7 --- /dev/null +++ b/tests/auto/quick/qquickpalette/data/palette-item-default.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Item { +} diff --git a/tests/auto/quick/qquickpalette/data/palette-window-custom.qml b/tests/auto/quick/qquickpalette/data/palette-window-custom.qml new file mode 100644 index 00000000000..715f973d1f2 --- /dev/null +++ b/tests/auto/quick/qquickpalette/data/palette-window-custom.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Window + +Window { + palette.alternateBase: "aqua" + palette.base: "azure" + palette.brightText: "beige" + palette.button: "bisque" + palette.buttonText: "chocolate" + palette.dark: "coral" + palette.highlight: "crimson" + palette.highlightedText: "fuchsia" + palette.light: "gold" + palette.link: "indigo" + palette.linkVisited: "ivory" + palette.mid: "khaki" + palette.midlight: "lavender" + palette.shadow: "linen" + palette.text: "moccasin" + palette.toolTipBase: "navy" + palette.toolTipText: "orchid" + palette.window: "plum" + palette.windowText: "salmon" +} diff --git a/tests/auto/quick/qquickpalette/data/palette-window-default.qml b/tests/auto/quick/qquickpalette/data/palette-window-default.qml new file mode 100644 index 00000000000..bb3358588e5 --- /dev/null +++ b/tests/auto/quick/qquickpalette/data/palette-window-default.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Window + +Window { +} diff --git a/tests/auto/quick/qquickpalette/tst_qquickpalette.cpp b/tests/auto/quick/qquickpalette/tst_qquickpalette.cpp index e211a034ee9..144bc84fda3 100644 --- a/tests/auto/quick/qquickpalette/tst_qquickpalette.cpp +++ b/tests/auto/quick/qquickpalette/tst_qquickpalette.cpp @@ -40,14 +40,28 @@ #include <QtTest/qtest.h> #include <QtTest/QSignalSpy> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlengine.h> + #include <QtQuick/private/qquickpalette_p.h> #include <QtQuick/private/qquickabstractpaletteprovider_p.h> #include <QtQuick/private/qquickpalettecolorprovider_p.h> -class tst_QQuickPalette : public QObject +#include <QtQuickTestUtils/private/qmlutils_p.h> + +// Use this to get a more descriptive failure message (QTBUG-87039). +#define COMPARE_PALETTES(actualPalette, expectedPalette) \ + QVERIFY2(actualPalette == expectedPalette, \ + qPrintable(QString::fromLatin1("\n Actual: %1\n Expected: %2") \ + .arg(QDebug::toString(actualPalette)).arg(QDebug::toString(expectedPalette)))); + +class tst_QQuickPalette : public QQmlDataTest { Q_OBJECT +public: + tst_QQuickPalette(); + private Q_SLOTS: void resolvingColor(); void resolvingColor_data(); @@ -73,11 +87,19 @@ private Q_SLOTS: void createFromQtPalette(); void convertToQtPalette(); + + void qml_data(); + void qml(); }; using GroupGetter = QQuickColorGroup* (QQuickPalette::* )() const; Q_DECLARE_METATYPE(GroupGetter); +tst_QQuickPalette::tst_QQuickPalette() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QQuickPalette::resolvingColor() { QFETCH(QPalette::ColorGroup, colorGroup); @@ -299,6 +321,58 @@ void tst_QQuickPalette::convertToQtPalette() QCOMPARE(palette.toQPalette(), somePalette.resolve(pp->defaultPalette())); } +// QTBUG-93691 +void tst_QQuickPalette::qml_data() +{ + QTest::addColumn<QString>("testFile"); + QTest::addColumn<QPalette>("expectedPalette"); + + const QPalette defaultPalette; + QTest::newRow("Item") << "palette-item-default.qml" << defaultPalette; + QTest::newRow("Window") << "palette-window-default.qml" << defaultPalette; + + QPalette customPalette; + customPalette.setColor(QPalette::AlternateBase, QColor("aqua")); + customPalette.setColor(QPalette::Base, QColor("azure")); + customPalette.setColor(QPalette::BrightText, QColor("beige")); + customPalette.setColor(QPalette::Button, QColor("bisque")); + customPalette.setColor(QPalette::ButtonText, QColor("chocolate")); + customPalette.setColor(QPalette::Dark, QColor("coral")); + customPalette.setColor(QPalette::Highlight, QColor("crimson")); + customPalette.setColor(QPalette::HighlightedText, QColor("fuchsia")); + customPalette.setColor(QPalette::Light, QColor("gold")); + customPalette.setColor(QPalette::Link, QColor("indigo")); + customPalette.setColor(QPalette::LinkVisited, QColor("ivory")); + customPalette.setColor(QPalette::Mid, QColor("khaki")); + customPalette.setColor(QPalette::Midlight, QColor("lavender")); + customPalette.setColor(QPalette::Shadow, QColor("linen")); + customPalette.setColor(QPalette::Text, QColor("moccasin")); + customPalette.setColor(QPalette::ToolTipBase, QColor("navy")); + customPalette.setColor(QPalette::ToolTipText, QColor("orchid")); + customPalette.setColor(QPalette::Window, QColor("plum")); + customPalette.setColor(QPalette::WindowText, QColor("salmon")); + + QTest::newRow("Item:custom") << "palette-item-custom.qml" << customPalette; + QTest::newRow("Window:custom") << "palette-window-custom.qml" << customPalette; +} + +void tst_QQuickPalette::qml() +{ + QFETCH(QString, testFile); + QFETCH(QPalette, expectedPalette); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl(testFile)); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + const QVariant var = object->property("palette"); + QVERIFY(var.isValid()); + COMPARE_PALETTES(var.value<QQuickPalette*>()->toQPalette(), expectedPalette); +} + QTEST_MAIN(tst_QQuickPalette) #include "tst_qquickpalette.moc" diff --git a/tests/auto/quick/qquickpath/CMakeLists.txt b/tests/auto/quick/qquickpath/CMakeLists.txt index c6165199873..fd1d003e80c 100644 --- a/tests/auto/quick/qquickpath/CMakeLists.txt +++ b/tests/auto/quick/qquickpath/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickpath SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickpath.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickpath/tst_qquickpath.cpp b/tests/auto/quick/qquickpath/tst_qquickpath.cpp index c89ce730a87..c1c34ddc06c 100644 --- a/tests/auto/quick/qquickpath/tst_qquickpath.cpp +++ b/tests/auto/quick/qquickpath/tst_qquickpath.cpp @@ -31,13 +31,13 @@ #include <QtQml/qqmlcomponent.h> #include <QtQuick/private/qquickpath_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_QuickPath : public QQmlDataTest { Q_OBJECT public: - tst_QuickPath() {} + tst_QuickPath() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void arc(); diff --git a/tests/auto/quick/qquickpathview/CMakeLists.txt b/tests/auto/quick/qquickpathview/CMakeLists.txt index 2f3bd53500c..84a234b3b86 100644 --- a/tests/auto/quick/qquickpathview/CMakeLists.txt +++ b/tests/auto/quick/qquickpathview/CMakeLists.txt @@ -12,15 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickpathview SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickpathview.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -29,6 +21,7 @@ qt_internal_add_test(tst_qquickpathview Qt::QmlPrivate Qt::QuickPrivate Qt::QuickTest + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index 733281c20d6..2b7aca72d04 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -45,16 +45,16 @@ #include <QStringListModel> #include <QFile> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> #include <math.h> Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") -using namespace QQuickViewTestUtil; -using namespace QQuickVisualTestUtil; +using namespace QQuickViewTestUtils; +using namespace QQuickVisualTestUtils; Q_DECLARE_METATYPE(QQuickPathView::HighlightRangeMode) Q_DECLARE_METATYPE(QQuickPathView::PositionMode) @@ -153,6 +153,10 @@ private slots: void objectModelMove(); void requiredPropertiesInDelegate(); void requiredPropertiesInDelegatePreventUnrelated(); + void touchMove(); + +private: + QScopedPointer<QPointingDevice> touchDevice = QScopedPointer<QPointingDevice>(QTest::createTouchDevice()); }; class TestObject : public QObject @@ -186,6 +190,7 @@ class TestObject : public QObject }; tst_QQuickPathView::tst_QQuickPathView() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } @@ -1389,8 +1394,7 @@ void tst_QQuickPathView::package() QVERIFY(window); window->setSource(testFileUrl("pathview_package.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathView = window->rootObject()->findChild<QQuickPathView*>("photoPathView"); QVERIFY(pathView); @@ -1515,12 +1519,10 @@ void tst_QQuickPathView::undefinedPath() void tst_QQuickPathView::mouseDrag() { QScopedPointer<QQuickView> window(createView()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("dragpath.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); QVERIFY(pathview != nullptr); @@ -1585,13 +1587,10 @@ void tst_QQuickPathView::mouseDrag() void tst_QQuickPathView::nestedMouseAreaDrag() { QScopedPointer<QQuickView> window(createView()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("nestedmousearea.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); - + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); QVERIFY(pathview != nullptr); @@ -1608,12 +1607,10 @@ void tst_QQuickPathView::nestedMouseAreaDrag() void tst_QQuickPathView::flickNClick() // QTBUG-77173 { QScopedPointer<QQuickView> window(createView()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("nestedmousearea2.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); QVERIFY(pathview != nullptr); @@ -1640,7 +1637,7 @@ void tst_QQuickPathView::flickNClick() // QTBUG-77173 flickStartedSpy.clear(); flickEndedSpy.clear(); // Dragging the child mouse area should animate the PathView (MA has no drag target) - flick(window.data(), QPoint(200,200), QPoint(400,200), duration); + flick(window.data(), QPoint(199,199), QPoint(399,199), duration); QVERIFY(pathview->isMoving()); QCOMPARE(movingChangedSpy.count(), 1); QCOMPARE(draggingSpy.count(), 2); @@ -1702,9 +1699,7 @@ void tst_QQuickPathView::changePreferredHighlight() window->setGeometry(0,0,400,200); window->setSource(testFileUrl("dragpath.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); QVERIFY(pathview != nullptr); @@ -1903,11 +1898,9 @@ void tst_QQuickPathView::cancelDrag() { QScopedPointer<QQuickView> window(createView()); window->setSource(testFileUrl("dragpath.qml")); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); QVERIFY(pathview != nullptr); @@ -1950,11 +1943,9 @@ void tst_QQuickPathView::maximumFlickVelocity() { QScopedPointer<QQuickView> window(createView()); window->setSource(testFileUrl("dragpath.qml")); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); QVERIFY(pathview != nullptr); @@ -1996,12 +1987,10 @@ void tst_QQuickPathView::snapToItem() QFETCH(bool, enforceRange); QScopedPointer<QQuickView> window(createView()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("panels.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = window->rootObject()->findChild<QQuickPathView*>("view"); QVERIFY(pathview != nullptr); @@ -2040,12 +2029,10 @@ void tst_QQuickPathView::snapOneItem() QFETCH(bool, enforceRange); QScopedPointer<QQuickView> window(createView()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("panels.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = window->rootObject()->findChild<QQuickPathView*>("view"); QVERIFY(pathview != nullptr); @@ -2096,9 +2083,7 @@ void tst_QQuickPathView::positionViewAtIndex() QScopedPointer<QQuickView> window(createView()); window->setSource(testFileUrl("pathview3.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); QVERIFY(pathview != nullptr); @@ -2159,9 +2144,7 @@ void tst_QQuickPathView::indexAt_itemAt() QScopedPointer<QQuickView> window(createView()); window->setSource(testFileUrl("pathview3.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); QVERIFY(pathview != nullptr); @@ -2285,8 +2268,7 @@ void tst_QQuickPathView::changePathDuringRefill() window->setSource(testFileUrl("changePathDuringRefill.qml")); window->show(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathView = qobject_cast<QQuickPathView*>(window->rootObject()); QVERIFY(pathView != nullptr); @@ -2309,12 +2291,10 @@ void tst_QQuickPathView::changePathDuringRefill() void tst_QQuickPathView::nestedinFlickable() { QScopedPointer<QQuickView> window(createView()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("nestedInFlickable.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = findItem<QQuickPathView>(window->rootObject(), "pathView"); QVERIFY(pathview != nullptr); @@ -2417,12 +2397,10 @@ void tst_QQuickPathView::nestedinFlickable() void tst_QQuickPathView::ungrabNestedinFlickable() { QScopedPointer<QQuickView> window(createView()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("ungrabNestedinFlickable.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = findItem<QQuickPathView>(window->rootObject(), "pathView"); QVERIFY(pathview != nullptr); @@ -2451,12 +2429,10 @@ void tst_QQuickPathView::ungrabNestedinFlickable() void tst_QQuickPathView::flickableDelegate() { QScopedPointer<QQuickView> window(createView()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("flickableDelegate.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); QVERIFY(pathview != nullptr); @@ -2536,8 +2512,7 @@ void tst_QQuickPathView::qtbug37815() window->setSource(testFileUrl("qtbug37815.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); // cache items will be created async. Let's wait... QTest::qWait(1000); @@ -2567,8 +2542,7 @@ void tst_QQuickPathView::qtbug42716() window->setSource(testFileUrl("qtbug42716.qml")); window->show(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathView = findItem<QQuickPathView>(window->rootObject(), "pathView"); QVERIFY(pathView != nullptr); @@ -2609,8 +2583,7 @@ void tst_QQuickPathView::qtbug53464() window->setSource(testFileUrl("qtbug53464.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathView = findItem<QQuickPathView>(window->rootObject(), "pathView"); QVERIFY(pathView != nullptr); @@ -2684,12 +2657,10 @@ void tst_QQuickPathView::movementDirection() QFETCH(qreal, tooffset); QScopedPointer<QQuickView> window(createView()); - QQuickViewTestUtil::moveMouseAway(window.data()); + QQuickVisualTestUtils::moveMouseAway(window.data()); window->setSource(testFileUrl("movementDirection.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); - QCOMPARE(window.data(), qGuiApp->focusWindow()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); QQuickPathView *pathview = window->rootObject()->findChild<QQuickPathView*>("view"); QVERIFY(pathview != nullptr); @@ -2796,6 +2767,112 @@ void tst_QQuickPathView::requiredPropertiesInDelegatePreventUnrelated() window->show(); } +void tst_QQuickPathView::touchMove() +{ + QScopedPointer<QQuickView> window(createView()); + QQuickVisualTestUtils::moveMouseAway(window.data()); + window->setSource(testFileUrl("dragpath.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); + QVERIFY(pathview != nullptr); + + QSignalSpy movingSpy(pathview, SIGNAL(movingChanged())); + QSignalSpy moveStartedSpy(pathview, SIGNAL(movementStarted())); + QSignalSpy moveEndedSpy(pathview, SIGNAL(movementEnded())); + QSignalSpy draggingSpy(pathview, SIGNAL(draggingChanged())); + QSignalSpy dragStartedSpy(pathview, SIGNAL(dragStarted())); + QSignalSpy dragEndedSpy(pathview, SIGNAL(dragEnded())); + QSignalSpy flickStartedSpy(pathview, SIGNAL(flickStarted())); + QSignalSpy flickEndedSpy(pathview, SIGNAL(flickEnded())); + + int current = pathview->currentIndex(); + + // touch move from left to right + QPoint from(250, 100); + QPoint to(10, 100); + + QTest::touchEvent(window.data(), touchDevice.data()).press(0, from, window.data()); + QQuickTouchUtils::flush(window.data()); + + QVERIFY(!pathview->isMoving()); + QVERIFY(!pathview->isDragging()); + QCOMPARE(movingSpy.count(), 0); + QCOMPARE(moveStartedSpy.count(), 0); + QCOMPARE(moveEndedSpy.count(), 0); + QCOMPARE(draggingSpy.count(), 0); + QCOMPARE(dragStartedSpy.count(), 0); + QCOMPARE(dragEndedSpy.count(), 0); + QCOMPARE(flickStartedSpy.count(), 0); + QCOMPARE(flickEndedSpy.count(), 0); + + from -= QPoint(QGuiApplication::styleHints()->startDragDistance() + 1, 0); + QTest::touchEvent(window.data(), touchDevice.data()).move(0, from, window.data()); + QQuickTouchUtils::flush(window.data()); + + // first move does not trigger move/drag + QVERIFY(!pathview->isMoving()); + QVERIFY(!pathview->isDragging()); + QCOMPARE(movingSpy.count(), 0); + QCOMPARE(moveStartedSpy.count(), 0); + QCOMPARE(moveEndedSpy.count(), 0); + QCOMPARE(draggingSpy.count(), 0); + QCOMPARE(dragStartedSpy.count(), 0); + QCOMPARE(dragEndedSpy.count(), 0); + QCOMPARE(flickStartedSpy.count(), 0); + QCOMPARE(flickEndedSpy.count(), 0); + + QPoint diff = from - to; + int moveCount = 4; + for (int i = 1; i <= moveCount; ++i) { + QTest::touchEvent(window.data(), touchDevice.data()).move(0, from - i * diff / moveCount, window.data()); + QQuickTouchUtils::flush(window.data()); + + QVERIFY(pathview->isMoving()); + QVERIFY(pathview->isDragging()); + QCOMPARE(movingSpy.count(), 1); + QCOMPARE(moveStartedSpy.count(), 1); + QCOMPARE(moveEndedSpy.count(), 0); + QCOMPARE(draggingSpy.count(), 1); + QCOMPARE(dragStartedSpy.count(), 1); + QCOMPARE(dragEndedSpy.count(), 0); + QCOMPARE(flickStartedSpy.count(), 0); + QCOMPARE(flickEndedSpy.count(), 0); + } + QVERIFY(pathview->currentIndex() != current); + + QTest::touchEvent(window.data(), touchDevice.data()).release(0, to, window.data()); + QQuickTouchUtils::flush(window.data()); + + QVERIFY(pathview->isMoving()); + QVERIFY(!pathview->isDragging()); + QCOMPARE(movingSpy.count(), 1); + QCOMPARE(moveStartedSpy.count(), 1); + QCOMPARE(moveEndedSpy.count(), 0); + QCOMPARE(draggingSpy.count(), 2); + QCOMPARE(dragStartedSpy.count(), 1); + QCOMPARE(dragEndedSpy.count(), 1); + QCOMPARE(flickStartedSpy.count(), 1); + QCOMPARE(flickEndedSpy.count(), 0); + + // Wait for the flick to finish + QVERIFY(QTest::qWaitFor([&]() + { return !pathview->isFlicking(); } + )); + QVERIFY(!pathview->isMoving()); + QVERIFY(!pathview->isDragging()); + QCOMPARE(movingSpy.count(), 2); + QCOMPARE(moveStartedSpy.count(), 1); + QCOMPARE(moveEndedSpy.count(), 1); + QCOMPARE(draggingSpy.count(), 2); + QCOMPARE(dragStartedSpy.count(), 1); + QCOMPARE(dragEndedSpy.count(), 1); + QCOMPARE(flickStartedSpy.count(), 1); + QCOMPARE(flickEndedSpy.count(), 1); + +} + QTEST_MAIN(tst_QQuickPathView) #include "tst_qquickpathview.moc" diff --git a/tests/auto/quick/qquickpincharea/CMakeLists.txt b/tests/auto/quick/qquickpincharea/CMakeLists.txt index 4f417366a17..48e354de34e 100644 --- a/tests/auto/quick/qquickpincharea/CMakeLists.txt +++ b/tests/auto/quick/qquickpincharea/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickpincharea SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickpincharea.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickpincharea/data/pinchAreaInPathView.qml b/tests/auto/quick/qquickpincharea/data/pinchAreaInPathView.qml new file mode 100644 index 00000000000..dc909c2c7c6 --- /dev/null +++ b/tests/auto/quick/qquickpincharea/data/pinchAreaInPathView.qml @@ -0,0 +1,48 @@ +import QtQuick + +PathView { + width: 600 + height: 200 + + model: 3 + delegate: Rectangle { + width: 200 + height: 200 + color: "salmon" + opacity: PathView.isCurrentItem ? 1 : 0.5 + + property alias pinchArea: pinchArea + + Text { + text: "Test" + font.pixelSize: 100 + anchors.fill: parent + fontSizeMode: Text.Fit + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + PinchArea { + id: pinchArea + anchors.fill: parent + pinch.target: parent + pinch.dragAxis: Pinch.XAndYAxis + pinch.minimumScale: 1.0 + pinch.maximumScale: 5.0 + + onPinchFinished: (pinch) => { + parent.scale = 1 + parent.x = 0 + parent.y = 0 + } + } + } + path: Path { + startX: 100 + startY: 100 + PathLine { + x: 700 + y: 100 + } + } +} diff --git a/tests/auto/quick/qquickpincharea/data/pinchproperties.qml b/tests/auto/quick/qquickpincharea/data/pinchproperties.qml index 899c6380da5..42096d0b77c 100644 --- a/tests/auto/quick/qquickpincharea/data/pinchproperties.qml +++ b/tests/auto/quick/qquickpincharea/data/pinchproperties.qml @@ -31,18 +31,18 @@ Rectangle { pinch.maximumScale: 2.0 pinch.minimumRotation: 0.0 pinch.maximumRotation: 90.0 - onPinchStarted: { + onPinchStarted: (pinch) => { whiteRect.center = pinch.center whiteRect.scale = pinch.scale whiteRect.pointCount = pinch.pointCount; whiteRect.pinchActive = true; } - onPinchUpdated: { + onPinchUpdated: (pinch) => { whiteRect.center = pinch.center whiteRect.scale = pinch.scale whiteRect.pointCount = pinch.pointCount; } - onPinchFinished: { + onPinchFinished: (pinch) => { whiteRect.center = pinch.center whiteRect.scale = pinch.scale whiteRect.pointCount = pinch.pointCount; diff --git a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp index 55fb07f744a..d845e9ef90a 100644 --- a/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp +++ b/tests/auto/quick/qquickpincharea/tst_qquickpincharea.cpp @@ -26,23 +26,26 @@ ** ****************************************************************************/ +#include <QtCore/private/qvariantanimation_p.h> #include <QtTest/QtTest> #include <QtTest/QSignalSpy> #include <QtGui/QStyleHints> #include <QtGui/private/qevent_p.h> +#include <QtGui/private/qeventpoint_p.h> #include <qpa/qwindowsysteminterface.h> #include <private/qquickpincharea_p.h> +#include <QtQuick/private/qquickpathview_p.h> #include <QtQuick/private/qquickrectangle_p.h> #include <QtQuick/qquickview.h> #include <QtQml/qqmlcontext.h> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> class tst_QQuickPinchArea: public QQmlDataTest { Q_OBJECT public: - tst_QQuickPinchArea() { } + tst_QQuickPinchArea() : QQmlDataTest(QT_QMLTEST_DATADIR) { } private slots: void cleanupTestCase(); void pinchProperties(); @@ -54,6 +57,8 @@ private slots: void transformedPinchArea(); void dragTransformedPinchArea_data(); void dragTransformedPinchArea(); + void pinchAreaKeepsDragInView(); + void pinchInPathView(); private: QQuickView *createView(); @@ -642,6 +647,147 @@ void tst_QQuickPinchArea::dragTransformedPinchArea() // QTBUG-63673 QCOMPARE(pinchArea->pinch()->active(), false); } +template<typename F> +void forEachLerpStep(int steps, F &&func) +{ + for (int i = 0; i < steps; ++i) { + const qreal t = qreal(i) / steps; + func(t); + } +} + +QPoint lerpPoints(const QPoint &point1, const QPoint &point2, qreal t) +{ + return QPoint(_q_interpolate(point1.x(), point2.x(), t), _q_interpolate(point1.y(), point2.y(), t)); +}; + +// QTBUG-105058 +void tst_QQuickPinchArea::pinchAreaKeepsDragInView() +{ + QQuickView view; + view.setSource(testFileUrl("pinchAreaInPathView.qml")); + QVERIFY(view.rootObject()); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QQuickPathView *pathView = qobject_cast<QQuickPathView*>(view.rootObject()); + QVERIFY(pathView); + QCOMPARE(pathView->count(), 3); + + const QQuickItem *pinchDelegateItem = pathView->itemAtIndex(0); + QQuickPinchArea *pinchArea = pinchDelegateItem->property("pinchArea").value<QQuickPinchArea*>(); + QVERIFY(pinchArea); + + // Press. + QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(&view, device); + QPoint point1Start = { 80, 120 }; + QPoint point2Start = { 120, 80 }; + const int dragThreshold = qApp->styleHints()->startDragDistance(); + pinchSequence.press(1, pinchArea->mapToScene(point1Start).toPoint(), &view) + .press(2, pinchArea->mapToScene(point2Start).toPoint(), &view).commit(); + QQuickTouchUtils::flush(&view); + + // Move past the drag threshold to begin the pinch. + const int steps = 30; + QPoint point1End = point1Start + QPoint(-dragThreshold, dragThreshold); + QPoint point2End = point2Start + QPoint(dragThreshold, -dragThreshold); + forEachLerpStep(steps, [&](qreal t) { + pinchSequence.move(1, lerpPoints(point1Start, point1End, t), &view) + .move(2, lerpPoints(point2Start, point2End, t), &view).commit(); + QQuickTouchUtils::flush(&view); + QTest::qWait(5); + }); + QCOMPARE(pinchArea->pinch()->active(), true); + QVERIFY2(pinchDelegateItem->scale() > 1.0, qPrintable(QString::number(pinchDelegateItem->scale()))); + // The PathView contents shouldn't have moved. + QCOMPARE(pathView->offset(), 0); + + // Release a touch point. + pinchSequence.stationary(1).release(2, point2End, &view).commit(); + QQuickTouchUtils::flush(&view); + + // Press it again. + pinchSequence.stationary(1).press(2, point2End, &view).commit(); + QQuickTouchUtils::flush(&view); + QCOMPARE(pinchArea->pinch()->active(), true); + + // Drag to the right; the PathView still shouldn't move. + point1Start = point1End; + point2Start = point2End; + point1End = point1Start + QPoint(100, 0); + point2End = point2Start + QPoint(100, 0); + forEachLerpStep(steps, [&](qreal t) { + pinchSequence.move(1, lerpPoints(point1Start, point1End, t), &view) + .move(2, lerpPoints(point2Start, point2End, t), &view).commit(); + QQuickTouchUtils::flush(&view); + QTest::qWait(5); + }); + QCOMPARE(pinchArea->pinch()->active(), true); + QVERIFY2(pinchDelegateItem->scale() > 1.0, qPrintable(QString::number(pinchDelegateItem->scale()))); + QCOMPARE(pathView->offset(), 0); + + // Release pinch. + pinchSequence.release(1, point1End, &view).release(2, point2End, &view).commit(); + QQuickTouchUtils::flush(&view); + QCOMPARE(pinchArea->pinch()->active(), false); + QCOMPARE(pathView->offset(), 0); +} + +void tst_QQuickPinchArea::pinchInPathView() +{ + QQuickView view; + view.setSource(testFileUrl("pinchAreaInPathView.qml")); + QVERIFY(view.rootObject()); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QQuickPathView *pathView = qobject_cast<QQuickPathView*>(view.rootObject()); + QVERIFY(pathView); + QCOMPARE(pathView->count(), 3); + + const QQuickItem *pinchDelegateItem = pathView->itemAtIndex(0); + QQuickPinchArea *pinchArea = pinchDelegateItem->property("pinchArea").value<QQuickPinchArea*>(); + QVERIFY(pinchArea); + + // press + QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(&view, device); + QPoint point1Start = { 10, 10 }; + QPoint point2Start = { 100, 100 }; + const int dragThreshold = qApp->styleHints()->startDragDistance(); + pinchSequence.press(0, point1Start, &view) + .press(1, point2Start, &view) + .commit(); + QQuickTouchUtils::flush(&view); + QTest::qWait(20); + + // move + QPoint moveDistance = QPoint(dragThreshold * 3, dragThreshold * 3); + QPoint point2End = point2Start + moveDistance; + pinchSequence.stationary(0) + .move(1, point2End, &view) + .commit(); + QQuickTouchUtils::flush(&view); + QTest::qWait(20); + + point2End += moveDistance; + pinchSequence.stationary(0) + .move(1, point2End, &view) + .commit(); + QQuickTouchUtils::flush(&view); + QTest::qWait(20); + + QCOMPARE(pinchArea->pinch()->active(), true); + QVERIFY2(pinchDelegateItem->scale() > 1.0, qPrintable(QString::number(pinchDelegateItem->scale()))); + // PathView shouldn't have moved. + QCOMPARE(pathView->offset(), 0); + + // release pinch. + pinchSequence.release(0, point1Start, &view).release(1, point2End, &view).commit(); + QQuickTouchUtils::flush(&view); + QCOMPARE(pinchArea->pinch()->active(), false); + QCOMPARE(pathView->offset(), 0); +} + QQuickView *tst_QQuickPinchArea::createView() { QQuickView *window = new QQuickView(nullptr); diff --git a/tests/auto/quick/qquickpixmapcache/CMakeLists.txt b/tests/auto/quick/qquickpixmapcache/CMakeLists.txt index e50a6eb6a88..3e20d026579 100644 --- a/tests/auto/quick/qquickpixmapcache/CMakeLists.txt +++ b/tests/auto/quick/qquickpixmapcache/CMakeLists.txt @@ -12,11 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickpixmapcache SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h tst_qquickpixmapcache.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Concurrent Qt::CorePrivate @@ -25,6 +21,7 @@ qt_internal_add_test(tst_qquickpixmapcache Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp b/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp index 13a33789057..88c0feac6ad 100644 --- a/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp +++ b/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp @@ -32,8 +32,8 @@ #include <QtQuick/qquickimageprovider.h> #include <QtQml/QQmlComponent> #include <QNetworkReply> -#include "../../shared/util.h" -#include "testhttpserver.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/testhttpserver_p.h> #if QT_CONFIG(concurrent) #include <qtconcurrentrun.h> @@ -46,7 +46,7 @@ class tst_qquickpixmapcache : public QQmlDataTest { Q_OBJECT public: - tst_qquickpixmapcache() {} + tst_qquickpixmapcache() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void initTestCase() override; diff --git a/tests/auto/quick/qquickpositioners/CMakeLists.txt b/tests/auto/quick/qquickpositioners/CMakeLists.txt index e72958c6cd7..d62bb4b0e1a 100644 --- a/tests/auto/quick/qquickpositioners/CMakeLists.txt +++ b/tests/auto/quick/qquickpositioners/CMakeLists.txt @@ -12,15 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickpositioners SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickpositioners.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -28,6 +20,7 @@ qt_internal_add_test(tst_qquickpositioners Qt::QmlPrivate Qt::QuickPrivate Qt::QuickTest + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp index 3885dd4a9af..2da96a60b75 100644 --- a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp +++ b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp @@ -34,12 +34,12 @@ #include <QtQuickTest/QtQuickTest> #include <private/qquickitem_p.h> #include <qqmlexpression.h> -#include "../shared/viewtestutil.h" -#include "../shared/visualtestutil.h" -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> -using namespace QQuickViewTestUtil; -using namespace QQuickVisualTestUtil; +using namespace QQuickViewTestUtils; +using namespace QQuickVisualTestUtils; Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") @@ -306,6 +306,7 @@ void tst_qquickpositioners::moveTransitions_flow_data() } tst_qquickpositioners::tst_qquickpositioners() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } @@ -1023,7 +1024,7 @@ void tst_qquickpositioners::populateTransitions(const QString &positionerObjectN QaimModel model_targetItems_transitionFrom; QaimModel model_displacedItems_transitionVia; - QScopedPointer<QQuickView> window(QQuickViewTestUtil::createView()); + QScopedPointer<QQuickView> window(QQuickViewTestUtils::createView()); window->setInitialProperties({ {"usePopulateTransition", usePopulateTransition}, @@ -1111,7 +1112,7 @@ void tst_qquickpositioners::addTransitions(const QString &positionerObjectName) QaimModel model_targetItems_transitionFrom; QaimModel model_displacedItems_transitionVia; - QScopedPointer<QQuickView> window(QQuickViewTestUtil::createView()); + QScopedPointer<QQuickView> window(QQuickViewTestUtils::createView()); window->setInitialProperties({ {"usePopulateTransition", QVariant(false)}, {"enableAddTransition", QVariant(true)}, @@ -1235,7 +1236,7 @@ void tst_qquickpositioners::moveTransitions(const QString &positionerObjectName) QaimModel model_targetItems_transitionFrom; QaimModel model_displacedItems_transitionVia; - QScopedPointer<QQuickView> window(QQuickViewTestUtil::createView()); + QScopedPointer<QQuickView> window(QQuickViewTestUtils::createView()); window->setInitialProperties({ {"usePopulateTransition", QVariant(false)}, {"enableAddTransition", QVariant(false)}, @@ -2986,7 +2987,9 @@ void tst_qquickpositioners::test_propertychanges() QCOMPARE(columnsSpy.count(),1); QCOMPARE(rowsSpy.count(),1); + QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*QML Grid: Grid contains more visible items \\(20\\) than rows\\*columns \\(6\\)")); grid->setColumns(2); + QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*QML Grid: Grid contains more visible items \\(20\\) than rows\\*columns \\(4\\)")); grid->setRows(2); QCOMPARE(columnsSpy.count(),2); QCOMPARE(rowsSpy.count(),2); diff --git a/tests/auto/quick/qquickrectangle/CMakeLists.txt b/tests/auto/quick/qquickrectangle/CMakeLists.txt index 5ccb12a3f74..b56171af947 100644 --- a/tests/auto/quick/qquickrectangle/CMakeLists.txt +++ b/tests/auto/quick/qquickrectangle/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickrectangle SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickrectangle.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp b/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp index 536280337a5..cb2f26e49fc 100644 --- a/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp +++ b/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp @@ -35,7 +35,7 @@ #include <private/qquickitem_p.h> #include <private/qquickrectangle_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickrectangle : public QQmlDataTest { @@ -57,11 +57,16 @@ private slots: }; tst_qquickrectangle::tst_qquickrectangle() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } void tst_qquickrectangle::color() { +#ifdef Q_OS_ANDROID + QSKIP("Test does not work on Android because of QTBUG-102345"); +#endif + if (QGuiApplication::primaryScreen()->depth() < 24) QSKIP("This test does not work at display depths < 24"); diff --git a/tests/auto/quick/qquickrendercontrol/BLACKLIST b/tests/auto/quick/qquickrendercontrol/BLACKLIST new file mode 100644 index 00000000000..5c4846d8211 --- /dev/null +++ b/tests/auto/quick/qquickrendercontrol/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-103258 +[renderAndReadBackWithRhi] +android diff --git a/tests/auto/quick/qquickrendercontrol/CMakeLists.txt b/tests/auto/quick/qquickrendercontrol/CMakeLists.txt index 46cfc1513cd..90bfc57ebdb 100644 --- a/tests/auto/quick/qquickrendercontrol/CMakeLists.txt +++ b/tests/auto/quick/qquickrendercontrol/CMakeLists.txt @@ -4,18 +4,23 @@ ## tst_qquickrendercontrol Test: ##################################################################### +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + qt_internal_add_test(tst_qquickrendercontrol SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickrendercontrol.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate + TESTDATA ${test_data} ) #### Keys ignored in scope 1:.:.:qquickrendercontrol.pro:<TRUE>: diff --git a/tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp b/tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp index 539ac25adbc..3b2ce38c4b6 100644 --- a/tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp +++ b/tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp @@ -39,7 +39,7 @@ #include <QQmlEngine> #include <QQmlComponent> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtGui/private/qguiapplication_p.h> #include <QtGui/qpa/qplatformintegration.h> @@ -79,6 +79,9 @@ class tst_RenderControl : public QQmlDataTest { Q_OBJECT +public: + tst_RenderControl(); + private slots: void initTestCase() override; void cleanupTestCase(); @@ -93,6 +96,11 @@ private slots: AnimationDriver *animDriver; }; +tst_RenderControl::tst_RenderControl() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_RenderControl::initTestCase() { QQmlDataTest::initTestCase(); @@ -128,8 +136,7 @@ void tst_RenderControl::renderAndReadBackWithRhi_data() QTest::newRow("Vulkan") << QSGRendererInterface::VulkanRhi; #endif #ifdef Q_OS_WIN - if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7) - QTest::newRow("D3D11") << QSGRendererInterface::Direct3D11Rhi; + QTest::newRow("D3D11") << QSGRendererInterface::Direct3D11Rhi; #endif #if defined(Q_OS_MACOS) || defined(Q_OS_IOS) QTest::newRow("Metal") << QSGRendererInterface::MetalRhi; @@ -144,6 +151,12 @@ void tst_RenderControl::renderAndReadBackWithRhi() QSKIP("Skipping Vulkan-based QRhi readback test due to failing to create a VkInstance"); #endif +#ifdef Q_OS_ANDROID + // QTBUG-102780 + if (api == QSGRendererInterface::VulkanRhi) + QSKIP("Vulkan-based rendering tests on Android are flaky."); +#endif + // Changing the graphics api is not possible once a QQuickWindow et al is // created, however we do support changing it once all QQuickWindow, // QQuickRenderControl, etc. instances are destroyed, before creating new diff --git a/tests/auto/quick/qquickrepeater/CMakeLists.txt b/tests/auto/quick/qquickrepeater/CMakeLists.txt index 3e7fda53c08..0f34764e446 100644 --- a/tests/auto/quick/qquickrepeater/CMakeLists.txt +++ b/tests/auto/quick/qquickrepeater/CMakeLists.txt @@ -12,15 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickrepeater SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickrepeater.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -28,6 +20,7 @@ qt_internal_add_test(tst_qquickrepeater Qt::QmlModelsPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp index 3634a3ea3c1..168c0561d01 100644 --- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp +++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp @@ -39,12 +39,12 @@ #include <QtQmlModels/private/qqmlobjectmodel_p.h> #include <QtGui/qstandarditemmodel.h> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> -using namespace QQuickViewTestUtil; -using namespace QQuickVisualTestUtil; +using namespace QQuickViewTestUtils; +using namespace QQuickVisualTestUtils; class tst_QQuickRepeater : public QQmlDataTest @@ -109,6 +109,7 @@ class TestObject : public QObject }; tst_QQuickRepeater::tst_QQuickRepeater() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } diff --git a/tests/auto/quick/qquickscreen/CMakeLists.txt b/tests/auto/quick/qquickscreen/CMakeLists.txt index 65c5538be3d..d78b38d16ef 100644 --- a/tests/auto/quick/qquickscreen/CMakeLists.txt +++ b/tests/auto/quick/qquickscreen/CMakeLists.txt @@ -4,18 +4,23 @@ ## tst_qquickscreen Test: ##################################################################### +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + qt_internal_add_test(tst_qquickscreen SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickscreen.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate + TESTDATA ${test_data} ) ## Scopes: diff --git a/tests/auto/quick/qquickscreen/tst_qquickscreen.cpp b/tests/auto/quick/qquickscreen/tst_qquickscreen.cpp index ff6031619ce..a77839afa43 100644 --- a/tests/auto/quick/qquickscreen/tst_qquickscreen.cpp +++ b/tests/auto/quick/qquickscreen/tst_qquickscreen.cpp @@ -32,18 +32,26 @@ #include <QtQuick/QQuickItem> #include <QtQuick/QQuickView> #include <QtGui/QScreen> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtQuick/private/qquickscreen_p.h> #include <QDebug> class tst_qquickscreen : public QQmlDataTest { Q_OBJECT +public: + tst_qquickscreen(); + private slots: void basicProperties(); void screenOnStartup(); void fullScreenList(); }; +tst_qquickscreen::tst_qquickscreen() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qquickscreen::basicProperties() { QQuickView view; diff --git a/tests/auto/quick/qquickshadereffect/CMakeLists.txt b/tests/auto/quick/qquickshadereffect/CMakeLists.txt index 6eebadeedf3..100890ff5b4 100644 --- a/tests/auto/quick/qquickshadereffect/CMakeLists.txt +++ b/tests/auto/quick/qquickshadereffect/CMakeLists.txt @@ -6,16 +6,14 @@ qt_internal_add_test(tst_qquickshadereffect SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickshadereffect.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate ) # Resources: diff --git a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp index 4115c279107..a9027f86bb1 100644 --- a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp +++ b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp @@ -32,9 +32,11 @@ #include <QByteArray> #include <private/qquickshadereffect_p.h> #include <QMatrix4x4> -#include <QtQuick/QQuickView> #include <QtQml/QQmlEngine> -#include "../../shared/util.h" +#include <QtQuick/QQuickView> +#include <QtQuick/private/qquickshadereffectsource_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> class TestShaderEffect : public QQuickShaderEffect { @@ -56,8 +58,15 @@ class TestShaderEffect : public QQuickShaderEffect int signalsConnected = 0; protected: - void connectNotify(const QMetaMethod &) override { ++signalsConnected; } - void disconnectNotify(const QMetaMethod &) override { --signalsConnected; } + void connectNotify(const QMetaMethod &s) override { + if (s.name() == "sourceChanged") + ++signalsConnected; + } + void disconnectNotify(const QMetaMethod &s) override + { + if (s.name() == "sourceChanged") + --signalsConnected; + } signals: void dummyChanged(); @@ -95,6 +104,7 @@ private slots: }; tst_qquickshadereffect::tst_qquickshadereffect() + : QQmlDataTest(QT_QMLTEST_DATADIR) { qmlRegisterType<TestShaderEffect>("ShaderEffectTest", 1, 0, "TestShaderEffect"); } @@ -111,17 +121,17 @@ void tst_qquickshadereffect::cleanupTestCase() void tst_qquickshadereffect::testConnection() { // verify that the property notify signal is connected - QQuickView *view = new QQuickView(nullptr); - view->setSource(QUrl(QStringLiteral("qrc:/data/connections.qml"))); + QQuickView view; + QVERIFY(QQuickTest::initView(view, QStringLiteral("qrc:/data/connections.qml"))); - auto *shaderEffectItem = qobject_cast<TestShaderEffect*>(view->rootObject()); + auto *shaderEffectItem = qobject_cast<TestShaderEffect*>(view.rootObject()); QVERIFY(shaderEffectItem); QCOMPARE(shaderEffectItem->signalsConnected, 0); - view->show(); - QVERIFY(QTest::qWaitForWindowExposed(view)); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); - QSGRendererInterface *rif = view->rendererInterface(); + QSGRendererInterface *rif = view.rendererInterface(); if (rif && rif->graphicsApi() != QSGRendererInterface::Software) QCOMPARE(shaderEffectItem->signalsConnected, 1); } @@ -129,66 +139,55 @@ void tst_qquickshadereffect::testConnection() void tst_qquickshadereffect::deleteSourceItem() { // purely to ensure that deleting the sourceItem of a shader doesn't cause a crash - QQuickView *view = new QQuickView(nullptr); - view->setSource(QUrl(QStringLiteral("qrc:/data/deleteSourceItem.qml"))); - view->show(); - QVERIFY(QTest::qWaitForWindowExposed(view)); - QVERIFY(view); - QObject *obj = view->rootObject(); + QQuickView view; + QVERIFY(QQuickTest::showView(view, QStringLiteral("qrc:/data/deleteSourceItem.qml"))); + QObject *obj = view.rootObject(); QVERIFY(obj); QMetaObject::invokeMethod(obj, "setDeletedSourceItem"); - QTest::qWait(50); - delete view; + const auto shaderEffectSource = obj->findChild<QQuickShaderEffectSource*>(); + QVERIFY(shaderEffectSource); + QTRY_VERIFY(!shaderEffectSource->sourceItem()); } void tst_qquickshadereffect::deleteShaderEffectSource() { - // purely to ensure that deleting the sourceItem of a shader doesn't cause a crash - QQuickView *view = new QQuickView(nullptr); - view->setSource(QUrl(QStringLiteral("qrc:/data/deleteShaderEffectSource.qml"))); - view->show(); - QVERIFY(QTest::qWaitForWindowExposed(view)); - QVERIFY(view); - QObject *obj = view->rootObject(); + // purely to ensure that deleting the ShaderEffectSource doesn't cause a crash + QQuickView view; + QVERIFY(QQuickTest::showView(view, QStringLiteral("qrc:/data/deleteShaderEffectSource.qml"))); + QObject *obj = view.rootObject(); QVERIFY(obj); + const QPointer<QQuickShaderEffectSource> shaderEffectSource = obj->findChild<QQuickShaderEffectSource*>(); + QVERIFY(shaderEffectSource); QMetaObject::invokeMethod(obj, "setDeletedShaderEffectSource"); - QTest::qWait(50); - delete view; + QTRY_VERIFY(shaderEffectSource); } void tst_qquickshadereffect::twoImagesOneShaderEffect() { // Don't crash when having a ShaderEffect and an Image sharing the texture via supportsAtlasTextures - QQuickView *view = new QQuickView(nullptr); - view->setSource(QUrl(QStringLiteral("qrc:/data/twoImagesOneShaderEffect.qml"))); - view->show(); - QVERIFY(QTest::qWaitForWindowExposed(view)); - QVERIFY(view); - QObject *obj = view->rootObject(); + QQuickView view; + QVERIFY(QQuickTest::showView(view, QStringLiteral("qrc:/data/twoImagesOneShaderEffect.qml"))); + QObject *obj = view.rootObject(); QVERIFY(obj); - delete view; } void tst_qquickshadereffect::withoutQmlEngine() { // using a shader without QML engine used to crash - auto window = new QQuickWindow; - auto shaderEffect = new TestShaderEffect(window->contentItem()); + const QQuickWindow window; + auto shaderEffect = new TestShaderEffect(window.contentItem()); shaderEffect->setVertexShader(QUrl()); QVERIFY(shaderEffect->isComponentComplete()); - delete window; } // QTBUG-86402: hiding the parent of an item that uses an effect should not cause a crash. void tst_qquickshadereffect::hideParent() { - QScopedPointer<QQuickView> view(new QQuickView); - view->setSource(QUrl(QStringLiteral("qrc:/data/hideParent.qml"))); - QCOMPARE(view->status(), QQuickView::Ready); - view->show(); - QVERIFY(QTest::qWaitForWindowExposed(view.data())); + QQuickView view; + view.setSource(QUrl(QStringLiteral("qrc:/data/hideParent.qml"))); + QVERIFY(QQuickTest::showView(view, QStringLiteral("qrc:/data/hideParent.qml"))); // Should finish without crashing. - QTRY_VERIFY(view->rootObject()->property("finished").toBool()); + QTRY_VERIFY(view.rootObject()->property("finished").toBool()); } QTEST_MAIN(tst_qquickshadereffect) diff --git a/tests/auto/quick/qquickshape/BLACKLIST b/tests/auto/quick/qquickshape/BLACKLIST new file mode 100644 index 00000000000..f0d5bcd351e --- /dev/null +++ b/tests/auto/quick/qquickshape/BLACKLIST @@ -0,0 +1,19 @@ +# QTBUG-103094 +[render] +android +[renderWithMultipleSp] +android +[radialGrad] +android +[conicalGrad] +android +[renderPolyline] +android +[renderMultiline] +android +[polylineDataTypes] +android +[multilineDataTypes] +android +[multilineStronglyTyped] +android diff --git a/tests/auto/quick/qquickshape/CMakeLists.txt b/tests/auto/quick/qquickshape/CMakeLists.txt index 325d812ed27..eaff007e8c7 100644 --- a/tests/auto/quick/qquickshape/CMakeLists.txt +++ b/tests/auto/quick/qquickshape/CMakeLists.txt @@ -12,15 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickshape SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickshape.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -28,6 +20,7 @@ qt_internal_add_test(tst_qquickshape Qt::QmlPrivate Qt::QuickPrivate Qt::QuickShapesPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickshape/tst_qquickshape.cpp b/tests/auto/quick/qquickshape/tst_qquickshape.cpp index 3a26f7e3823..60b9df89f4a 100644 --- a/tests/auto/quick/qquickshape/tst_qquickshape.cpp +++ b/tests/auto/quick/qquickshape/tst_qquickshape.cpp @@ -36,12 +36,12 @@ #include <QtQuickShapes/private/qquickshape_p.h> #include <QStandardPaths> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> -using namespace QQuickViewTestUtil; -using namespace QQuickVisualTestUtil; +using namespace QQuickViewTestUtils; +using namespace QQuickVisualTestUtils; class PolygonProvider : public QObject { @@ -93,6 +93,7 @@ private slots: }; tst_QQuickShape::tst_QQuickShape() + : QQmlDataTest(QT_QMLTEST_DATADIR) { // Force the software backend to get reliable rendering results regardless of the hw and drivers. QQuickWindow::setGraphicsApi(QSGRendererInterface::Software); @@ -288,12 +289,12 @@ void tst_QQuickShape::render() QImage img = window->grabWindow(); QVERIFY(!img.isNull()); - QImage refImg(testFileUrl("pathitem3.png").toLocalFile()); + QImage refImg(testFile("pathitem3.png")); QVERIFY(!refImg.isNull()); QString errorMessage; const QImage actualImg = img.convertToFormat(refImg.format()); - QVERIFY2(QQuickVisualTestUtil::compareImages(actualImg, refImg, &errorMessage), + QVERIFY2(QQuickVisualTestUtils::compareImages(actualImg, refImg, &errorMessage), qPrintable(errorMessage)); } @@ -312,12 +313,12 @@ void tst_QQuickShape::renderWithMultipleSp() QImage img = window->grabWindow(); QVERIFY(!img.isNull()); - QImage refImg(testFileUrl("pathitem4.png").toLocalFile()); + QImage refImg(testFile("pathitem4.png")); QVERIFY(!refImg.isNull()); QString errorMessage; const QImage actualImg = img.convertToFormat(refImg.format()); - QVERIFY2(QQuickVisualTestUtil::compareImages(actualImg, refImg, &errorMessage), + QVERIFY2(QQuickVisualTestUtils::compareImages(actualImg, refImg, &errorMessage), qPrintable(errorMessage)); } @@ -336,12 +337,12 @@ void tst_QQuickShape::radialGrad() QImage img = window->grabWindow(); QVERIFY(!img.isNull()); - QImage refImg(testFileUrl("pathitem5.png").toLocalFile()); + QImage refImg(testFile("pathitem5.png")); QVERIFY(!refImg.isNull()); QString errorMessage; const QImage actualImg = img.convertToFormat(refImg.format()); - QVERIFY2(QQuickVisualTestUtil::compareImages(actualImg, refImg, &errorMessage), + QVERIFY2(QQuickVisualTestUtils::compareImages(actualImg, refImg, &errorMessage), qPrintable(errorMessage)); } @@ -360,12 +361,12 @@ void tst_QQuickShape::conicalGrad() QImage img = window->grabWindow(); QVERIFY(!img.isNull()); - QImage refImg(testFileUrl("pathitem6.png").toLocalFile()); + QImage refImg(testFile("pathitem6.png")); QVERIFY(!refImg.isNull()); QString errorMessage; const QImage actualImg = img.convertToFormat(refImg.format()); - QVERIFY2(QQuickVisualTestUtil::compareImages(actualImg, refImg, &errorMessage), + QVERIFY2(QQuickVisualTestUtils::compareImages(actualImg, refImg, &errorMessage), qPrintable(errorMessage)); } @@ -384,12 +385,12 @@ void tst_QQuickShape::renderPolyline() QImage img = window->grabWindow(); QVERIFY(!img.isNull()); - QImage refImg(testFileUrl("pathitem3.png").toLocalFile()); // It's a recreation of pathitem3 using PathPolyline + QImage refImg(testFile("pathitem3.png")); // It's a recreation of pathitem3 using PathPolyline QVERIFY(!refImg.isNull()); QString errorMessage; const QImage actualImg = img.convertToFormat(refImg.format()); - const bool res = QQuickVisualTestUtil::compareImages(actualImg, refImg, &errorMessage); + const bool res = QQuickVisualTestUtils::compareImages(actualImg, refImg, &errorMessage); if (!res) { // For visual inspection purposes. QTest::qWait(5000); const QString &tempLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation); @@ -413,12 +414,12 @@ void tst_QQuickShape::renderMultiline() QImage img = window->grabWindow(); QVERIFY(!img.isNull()); - QImage refImg(testFileUrl("pathitem8.png").toLocalFile()); + QImage refImg(testFile("pathitem8.png")); QVERIFY(!refImg.isNull()); QString errorMessage; const QImage actualImg = img.convertToFormat(refImg.format()); - const bool res = QQuickVisualTestUtil::compareImages(actualImg, refImg, &errorMessage); + const bool res = QQuickVisualTestUtils::compareImages(actualImg, refImg, &errorMessage); if (!res) { // For visual inspection purposes. QTest::qWait(5000); const QString &tempLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation); @@ -479,12 +480,12 @@ void tst_QQuickShape::polylineDataTypes() QImage img = window->grabWindow(); QVERIFY(!img.isNull()); - QImage refImg(testFileUrl("polyline.png").toLocalFile()); + QImage refImg(testFile("polyline.png")); QVERIFY(!refImg.isNull()); QString errorMessage; const QImage actualImg = img.convertToFormat(refImg.format()); - const bool res = QQuickVisualTestUtil::compareImages(actualImg, refImg, &errorMessage); + const bool res = QQuickVisualTestUtils::compareImages(actualImg, refImg, &errorMessage); if (!res) { // For visual inspection purposes. QTest::qWait(5000); const QString &tempLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation); @@ -630,12 +631,12 @@ void tst_QQuickShape::multilineDataTypes() QImage img = window->grabWindow(); QVERIFY(!img.isNull()); - QImage refImg(testFileUrl("multiline.png").toLocalFile()); + QImage refImg(testFile("multiline.png")); QVERIFY(!refImg.isNull()); QString errorMessage; const QImage actualImg = img.convertToFormat(refImg.format()); - const bool res = QQuickVisualTestUtil::compareImages(actualImg, refImg, &errorMessage); + const bool res = QQuickVisualTestUtils::compareImages(actualImg, refImg, &errorMessage); if (!res) { // For visual inspection purposes. QTest::qWait(5000); const QString &tempLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation); @@ -678,12 +679,12 @@ void tst_QQuickShape::multilineStronglyTyped() QImage img = window->grabWindow(); QVERIFY(!img.isNull()); - QImage refImg(testFileUrl("multiline.png").toLocalFile()); + QImage refImg(testFile("multiline.png")); QVERIFY(!refImg.isNull()); QString errorMessage; const QImage actualImg = img.convertToFormat(refImg.format()); - const bool res = QQuickVisualTestUtil::compareImages(actualImg, refImg, &errorMessage); + const bool res = QQuickVisualTestUtils::compareImages(actualImg, refImg, &errorMessage); if (!res) { // For visual inspection purposes. QTest::qWait(5000); const QString &tempLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation); diff --git a/tests/auto/quick/qquickshortcut/CMakeLists.txt b/tests/auto/quick/qquickshortcut/CMakeLists.txt index dda488abff0..8887b9ba23b 100644 --- a/tests/auto/quick/qquickshortcut/CMakeLists.txt +++ b/tests/auto/quick/qquickshortcut/CMakeLists.txt @@ -12,14 +12,12 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickshortcut SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickshortcut.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Qml Qt::Quick + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickshortcut/tst_qquickshortcut.cpp b/tests/auto/quick/qquickshortcut/tst_qquickshortcut.cpp index 6351b97fb3c..0655b053e3a 100644 --- a/tests/auto/quick/qquickshortcut/tst_qquickshortcut.cpp +++ b/tests/auto/quick/qquickshortcut/tst_qquickshortcut.cpp @@ -35,12 +35,15 @@ #include <QtQuickWidgets/qquickwidget.h> #endif -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_QQuickShortcut : public QQmlDataTest { Q_OBJECT +public: + tst_QQuickShortcut(); + private slots: void standardShortcuts_data(); void standardShortcuts(); @@ -83,6 +86,11 @@ static QVariant shortcutMap(const QVariant &key, bool enabled = true, bool autoR return shortcutMap(key, Qt::WindowShortcut, enabled, autoRepeat); } +tst_QQuickShortcut::tst_QQuickShortcut() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_QQuickShortcut::standardShortcuts_data() { QTest::addColumn<QKeySequence::StandardKey>("standardKey"); diff --git a/tests/auto/quick/qquicksmoothedanimation/CMakeLists.txt b/tests/auto/quick/qquicksmoothedanimation/CMakeLists.txt index f487e786ab1..18dc389ad21 100644 --- a/tests/auto/quick/qquicksmoothedanimation/CMakeLists.txt +++ b/tests/auto/quick/qquicksmoothedanimation/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquicksmoothedanimation SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquicksmoothedanimation.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquicksmoothedanimation/tst_qquicksmoothedanimation.cpp b/tests/auto/quick/qquicksmoothedanimation/tst_qquicksmoothedanimation.cpp index 14d2e858e80..fee7068825a 100644 --- a/tests/auto/quick/qquicksmoothedanimation/tst_qquicksmoothedanimation.cpp +++ b/tests/auto/quick/qquicksmoothedanimation/tst_qquicksmoothedanimation.cpp @@ -31,7 +31,7 @@ #include <QtQuick/private/qquicksmoothedanimation_p.h> #include <QtQuick/private/qquickrectangle_p.h> #include <private/qqmlvaluetype_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquicksmoothedanimation : public QQmlDataTest { @@ -55,6 +55,7 @@ private slots: }; tst_qquicksmoothedanimation::tst_qquicksmoothedanimation() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } diff --git a/tests/auto/quick/qquickspringanimation/CMakeLists.txt b/tests/auto/quick/qquickspringanimation/CMakeLists.txt index b90f76cdf6f..04fa4fde531 100644 --- a/tests/auto/quick/qquickspringanimation/CMakeLists.txt +++ b/tests/auto/quick/qquickspringanimation/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickspringanimation SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickspringanimation.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickspringanimation/tst_qquickspringanimation.cpp b/tests/auto/quick/qquickspringanimation/tst_qquickspringanimation.cpp index 9042e94c75f..6e545e62f27 100644 --- a/tests/auto/quick/qquickspringanimation/tst_qquickspringanimation.cpp +++ b/tests/auto/quick/qquickspringanimation/tst_qquickspringanimation.cpp @@ -31,7 +31,7 @@ #include <QtQuick/qquickview.h> #include <private/qquickspringanimation_p.h> #include <private/qqmlvaluetype_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquickspringanimation : public QQmlDataTest { @@ -50,6 +50,7 @@ private slots: }; tst_qquickspringanimation::tst_qquickspringanimation() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } diff --git a/tests/auto/quick/qquickspritesequence/CMakeLists.txt b/tests/auto/quick/qquickspritesequence/CMakeLists.txt index 3955536260a..27aac12df18 100644 --- a/tests/auto/quick/qquickspritesequence/CMakeLists.txt +++ b/tests/auto/quick/qquickspritesequence/CMakeLists.txt @@ -12,10 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickspritesequence SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickspritesequence.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -23,6 +20,7 @@ qt_internal_add_test(tst_qquickspritesequence Qt::Network Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp b/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp index e5d55a6871b..6af58990f78 100644 --- a/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp +++ b/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp @@ -26,7 +26,7 @@ ** ****************************************************************************/ #include <QtTest/QtTest> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtQuick/qquickview.h> #include <private/qquickspritesequence_p.h> @@ -34,7 +34,7 @@ class tst_qquickspritesequence : public QQmlDataTest { Q_OBJECT public: - tst_qquickspritesequence(){} + tst_qquickspritesequence() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: void test_properties(); diff --git a/tests/auto/quick/qquickstates/CMakeLists.txt b/tests/auto/quick/qquickstates/CMakeLists.txt index 00b259e763d..657e11b392b 100644 --- a/tests/auto/quick/qquickstates/CMakeLists.txt +++ b/tests/auto/quick/qquickstates/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickstates SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickstates.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickstates/data/anchorRewind.qml b/tests/auto/quick/qquickstates/data/anchorRewind.qml new file mode 100644 index 00000000000..740c94cf423 --- /dev/null +++ b/tests/auto/quick/qquickstates/data/anchorRewind.qml @@ -0,0 +1,31 @@ +import QtQuick + +Item { + width: 400 + height: 400 + Item { + id: outer + anchors.fill: parent + Item { + id: inner + width: parent.width / 2 + height: parent.height / 2 + anchors.left: parent.right + anchors.top: parent.bottom + } + states: [ + State { + when: true + AnchorChanges { + target: inner + anchors.left: outer.left + anchors.top: outer.top + } + } + ] + transitions: Transition { + AnchorAnimation {} + } + } +} + diff --git a/tests/auto/quick/qquickstates/data/anchorRewindSize.qml b/tests/auto/quick/qquickstates/data/anchorRewindSize.qml new file mode 100644 index 00000000000..8fbae05c6de --- /dev/null +++ b/tests/auto/quick/qquickstates/data/anchorRewindSize.qml @@ -0,0 +1,30 @@ +import QtQuick + +Item { + id: root + width: 400 + height: 400 + property bool changeState: false + Item { + id: outer + anchors.fill: parent + Item { + id: inner + width: 100 + height: 100 + anchors.left: outer.left + anchors.top: outer.top + } + states: [ + State { + when: root.changeState + AnchorChanges { + target: inner + anchors.right: outer.right + anchors.bottom: outer.bottom + } + } + ] + } +} + diff --git a/tests/auto/quick/qquickstates/data/jsValueWhen.qml b/tests/auto/quick/qquickstates/data/jsValueWhen.qml new file mode 100644 index 00000000000..6d5eb1600c9 --- /dev/null +++ b/tests/auto/quick/qquickstates/data/jsValueWhen.qml @@ -0,0 +1,18 @@ +import QtQuick 2.15 + +Item { + id: root + property var prop: null + property bool works: false + states: [ + State { + name: "mystate" + when: root.prop + PropertyChanges { + target: root + works: "works" + } + } + ] + Component.onCompleted: root.prop = new Object +} diff --git a/tests/auto/quick/qquickstates/data/jsValueWhen2.qml b/tests/auto/quick/qquickstates/data/jsValueWhen2.qml new file mode 100644 index 00000000000..e1f173138ed --- /dev/null +++ b/tests/auto/quick/qquickstates/data/jsValueWhen2.qml @@ -0,0 +1,20 @@ +import QtQuick 2.15 + +Item { + id: root + property var prop: null + property bool works: false + states: [ + State { + name: "mystate" + when: root.prop + PropertyChanges { + target: root + works: "works" + } + } + ] + Component.onCompleted: root.prop = Qt.createQmlObject( + "import QtQml 2.15\nQtObject {}", + root, "dynamicSnippet") +} diff --git a/tests/auto/quick/qquickstates/data/noStateOsciallation.qml b/tests/auto/quick/qquickstates/data/noStateOsciallation.qml new file mode 100644 index 00000000000..f0d7aeeb6d8 --- /dev/null +++ b/tests/auto/quick/qquickstates/data/noStateOsciallation.qml @@ -0,0 +1,22 @@ +import QtQuick 2.15 + +Item { + id: root + property int number: 2 + property int stateChangeCounter: 0 + + Item { + id: item + onStateChanged: ++stateChangeCounter + states: [ + State { + name: "n1" + when: root.number === 1 + }, + State { + name: "n2" + when: root.number === 2 + } + ] + } +} diff --git a/tests/auto/quick/qquickstates/data/parentChangeInvolvingBindings.qml b/tests/auto/quick/qquickstates/data/parentChangeInvolvingBindings.qml new file mode 100644 index 00000000000..d3873883cd2 --- /dev/null +++ b/tests/auto/quick/qquickstates/data/parentChangeInvolvingBindings.qml @@ -0,0 +1,43 @@ +import QtQuick + +Item { + id: root + property alias childWidth: firstChild.width + property alias childX: firstChild.x + property alias childRotation: firstChild.rotation + property double myrotation: 100 + property double myrotation2: 200 + height: 400 + y: 40 + + Item { + id: firstChild + height: parent.height + width: height + y: parent.y + x: y + rotation: root.myrotation + + Item { + id: inner + anchors.fill: parent + } + } + + states: State { + name: "reparented" + ParentChange { + target: firstChild + parent: otherChild + width: 2 *height + x: 2 * y + rotation: root.myrotation2 + } + } + + Item { + height: parent.height + y: parent.y + id: otherChild + } +} diff --git a/tests/auto/quick/qquickstates/data/removeBindingWithTransition.qml b/tests/auto/quick/qquickstates/data/removeBindingWithTransition.qml new file mode 100644 index 00000000000..6936fe55ce6 --- /dev/null +++ b/tests/auto/quick/qquickstates/data/removeBindingWithTransition.qml @@ -0,0 +1,23 @@ +import QtQuick + +Item { + id: root + property bool toggle: true + property int state1Width: 500 + + states: [ + State { + when: root.toggle + PropertyChanges { target: root; width: root.state1Width } + }, + State { + when: !root.toggle + PropertyChanges { target: root; width: 300 } + } + ] + + transitions: Transition { + id: transition + SmoothedAnimation { target: root; property: "width"; velocity: 200 } + } +} diff --git a/tests/auto/quick/qquickstates/tst_qquickstates.cpp b/tests/auto/quick/qquickstates/tst_qquickstates.cpp index 9fad509187d..224e17fc7b9 100644 --- a/tests/auto/quick/qquickstates/tst_qquickstates.cpp +++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp @@ -37,7 +37,8 @@ #include <QtQuick/private/qquickstategroup_p.h> #include <private/qquickitem_p.h> #include <private/qqmlproperty_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtTest/qsignalspy.h> class MyAttached : public QObject { @@ -143,7 +144,7 @@ class tst_qquickstates : public QQmlDataTest { Q_OBJECT public: - tst_qquickstates() {} + tst_qquickstates() : QQmlDataTest(QT_QMLTEST_DATADIR) {} private: QByteArray fullDataPath(const QString &path) const; @@ -199,9 +200,16 @@ private slots: void revertListMemoryLeak(); void duplicateStateName(); void trivialWhen(); + void jsValueWhen_data(); + void jsValueWhen(); + void noStateOsciallation(); void parentChangeCorrectReversal(); void revertNullObjectBinding(); void bindableProperties(); + void parentChangeInvolvingBindings(); + void rewindAnchorChange(); + void rewindAnchorChangeSize(); + void bindingProperlyRemovedWithTransition(); }; void tst_qquickstates::initTestCase() @@ -1053,23 +1061,23 @@ void tst_qquickstates::anchorRewindBug() QQuickItem * column = rect->findChild<QQuickItem*>("column"); QVERIFY(column != nullptr); - QVERIFY(!QQuickItemPrivate::get(column)->heightValid); - QVERIFY(!QQuickItemPrivate::get(column)->widthValid); + QVERIFY(!QQuickItemPrivate::get(column)->heightValid()); + QVERIFY(!QQuickItemPrivate::get(column)->widthValid()); QCOMPARE(column->height(), 200.0); QQuickItemPrivate::get(rect)->setState("reanchored"); // column height and width should stay implicit // and column's implicit resizing should still work - QVERIFY(!QQuickItemPrivate::get(column)->heightValid); - QVERIFY(!QQuickItemPrivate::get(column)->widthValid); + QVERIFY(!QQuickItemPrivate::get(column)->heightValid()); + QVERIFY(!QQuickItemPrivate::get(column)->widthValid()); QTRY_COMPARE(column->height(), 100.0); QQuickItemPrivate::get(rect)->setState(""); // column height and width should stay implicit // and column's implicit resizing should still work - QVERIFY(!QQuickItemPrivate::get(column)->heightValid); - QVERIFY(!QQuickItemPrivate::get(column)->widthValid); + QVERIFY(!QQuickItemPrivate::get(column)->heightValid()); + QVERIFY(!QQuickItemPrivate::get(column)->widthValid()); QTRY_COMPARE(column->height(), 200.0); } @@ -1713,6 +1721,39 @@ void tst_qquickstates::trivialWhen() QVERIFY(root); } + +void tst_qquickstates::jsValueWhen_data() +{ + QTest::addColumn<QByteArray>("fileName"); + QTest::addRow("jsObject") << QByteArray("jsValueWhen.qml"); + QTest::addRow("qmlObject") << QByteArray("jsValueWhen2.qml"); +} + +void tst_qquickstates::jsValueWhen() +{ + QFETCH(QByteArray, fileName); + QQmlEngine engine; + + QQmlComponent c(&engine, testFileUrl(fileName.constData())); + QScopedPointer<QObject> root(c.create()); + QVERIFY(root); + QVERIFY(root->property("works").toBool()); +} + +void tst_qquickstates::noStateOsciallation() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("noStateOsciallation.qml")); + QScopedPointer<QObject> root {component.create()}; + QVERIFY(root); + // set to 1 on initial transition from "" to "n2" + QCOMPARE(root->property("stateChangeCounter").toInt(), 1); + root->setProperty("number", 1); + // setting number to 1 changes directly from "n2" to "n1" + // without any intermediate transition to "" + QCOMPARE(root->property("stateChangeCounter").toInt(), 2); +} + void tst_qquickstates::parentChangeCorrectReversal() { QQmlEngine engine; @@ -1779,6 +1820,205 @@ void tst_qquickstates::bindableProperties() } } +struct Listener : QQuickItemChangeListener +{ + // We want to get notified about all the states. + constexpr static const QRectF expectations[] = { + QRectF(40, 40, 400, 400), + QRectF(40, 0, 400, 400), + QRectF(0, 0, 400, 400), + QRectF(0, 0, 800, 400), + QRectF(0, 0, 800, 200), + QRectF(0, 0, 400, 200), + QRectF(0, 20, 400, 200), + QRectF(40, 20, 400, 200), + QRectF(84, 42, 400, 200), + QRectF(84, 42, 86, 43), + QRectF(40, 40, 86, 43), + QRectF(40, 40, 400, 400), + QRectF(40, 20, 400, 400), + QRectF(40, 20, 400, 200), + QRectF(20, 20, 400, 200), + QRectF(20, 20, 200, 200), + QRectF(20, 20, 200, 300), + QRectF(20, 20, 300, 300), + QRectF(20, 30, 300, 300), + QRectF(30, 30, 300, 300), + }; + + int position = 0; + bool ok = true; + + void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &rect) override + { + if (rect != expectations[position]) { + qDebug() << position << rect; + ok = false; + } + ++position; + } +}; + +void tst_qquickstates::parentChangeInvolvingBindings() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("parentChangeInvolvingBindings.qml")); + QScopedPointer<QQuickItem> root { qobject_cast<QQuickItem *>(c.create()) }; + QVERIFY2(root, qPrintable(c.errorString())); + + QObject *child = qmlContext(root.data())->objectForName(QStringLiteral("firstChild")); + QVERIFY(child); + QQuickItem *childItem = qobject_cast<QQuickItem *>(child); + QVERIFY(childItem); + Listener listener; + QQuickItemPrivate::get(childItem)->addItemChangeListener(&listener, QQuickItemPrivate::Geometry); + + + QCOMPARE(root->property("childWidth").toInt(), 400); + QCOMPARE(root->property("childX").toInt(), 40); + QCOMPARE(root->property("childRotation").toInt(), 100); + root->setState("reparented"); + + QCOMPARE(root->property("childWidth").toInt(), 800); + QCOMPARE(root->property("childX").toInt(), 0); // x gets zeroed here, from unrelated place. + QCOMPARE(root->property("childRotation").toInt(), 200); + + root->setProperty("myrotation2", 300); + root->setHeight(200); + root->setY(20); + QCOMPARE(root->property("childRotation").toInt(), 300); + QCOMPARE(root->property("childWidth").toInt(), 400); + QCOMPARE(root->property("childX").toInt(), 40); + + QObject *inner = qmlContext(root.data())->objectForName(QStringLiteral("inner")); + QVERIFY(inner); + QQuickItem *innerItem = qobject_cast<QQuickItem *>(inner); + QVERIFY(innerItem); + + QCOMPARE(innerItem->size(), childItem->size()); + + // Does not break bindings and does not survive the state change. + // However, since the binding between x and y stays intact, we don't know + // whether x is set another time from the new y. We pass a pair of numbers that + // matches the binding. + childItem->setPosition(QPointF(84, 42)); + QCOMPARE(root->property("childX").toInt(), 84); + QVERIFY(listener.ok); + childItem->setSize(QSizeF(86, 43)); + QCOMPARE(root->property("childWidth").toInt(), 86); + QVERIFY(listener.ok); + + QCOMPARE(innerItem->size(), childItem->size()); + + QSignalSpy xSpy(childItem, SIGNAL(xChanged())); + QSignalSpy widthSpy(childItem, SIGNAL(widthChanged())); + + root->setState(""); + + QVERIFY(listener.ok); + QCOMPARE(root->property("childRotation").toInt(), 100); + + // First change to 40 via reverse(), then to 20 via binding. + QCOMPARE(xSpy.count(), 2); + + // First change to 400 via reverse(), then to 200 via binding. + QCOMPARE(widthSpy.count(), 2); + + QCOMPARE(root->property("childX").toInt(), 20); + QCOMPARE(root->property("childWidth").toInt(), 200); + + QCOMPARE(innerItem->size(), childItem->size()); + + root->setProperty("myrotation", 50); + root->setHeight(300); + QVERIFY(listener.ok); + root->setY(30); + QVERIFY(listener.ok); + QCOMPARE(root->property("childWidth").toInt(), 300); + QCOMPARE(root->property("childX").toInt(), 30); + QCOMPARE(root->property("childRotation").toInt(), 50); + + QCOMPARE(innerItem->size(), childItem->size()); +} + +void tst_qquickstates::rewindAnchorChange() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("anchorRewind.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> root(c.create()); + QVERIFY(root); + + QQmlContext *context = qmlContext(root.data()); + QVERIFY(context); + + QObject *inner = context->objectForName(QStringLiteral("inner")); + QVERIFY(inner); + + QQuickItem *innerRect = qobject_cast<QQuickItem *>(inner); + QVERIFY(innerRect); + + QTRY_COMPARE(innerRect->x(), 0); + QTRY_COMPARE(innerRect->y(), 0); + QTRY_COMPARE(innerRect->width(), 200); + QTRY_COMPARE(innerRect->height(), 200); +} + +void tst_qquickstates::rewindAnchorChangeSize() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("anchorRewindSize.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + std::unique_ptr<QObject> root(c.create()); + QVERIFY(root); + + QQmlContext *context = qmlContext(root.get()); + QVERIFY(context); + + QObject *inner = context->objectForName(QStringLiteral("inner")); + QVERIFY(inner); + + QQuickItem *innerRect = qobject_cast<QQuickItem *>(inner); + QVERIFY(innerRect); + + QCOMPARE(innerRect->x(), 0); + QCOMPARE(innerRect->y(), 0); + QCOMPARE(innerRect->width(), 100); + QCOMPARE(innerRect->height(), 100); + + root->setProperty("changeState", true); + QCOMPARE(innerRect->x(), 0); + QCOMPARE(innerRect->y(), 0); + QCOMPARE(innerRect->width(), 400); + QCOMPARE(innerRect->height(), 400); + + root->setProperty("changeState", false); + QCOMPARE(innerRect->x(), 0); + QCOMPARE(innerRect->y(), 0); + QCOMPARE(innerRect->width(), 100); + QCOMPARE(innerRect->height(), 100); +} + +void tst_qquickstates::bindingProperlyRemovedWithTransition() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("removeBindingWithTransition.qml")); + QVERIFY2(c.isReady(), qPrintable(c.errorString())); + QScopedPointer<QObject> root(c.create()); + QVERIFY(root); + QQuickItem *item = qobject_cast<QQuickItem *>(root.get()); + QVERIFY(item); + + item->setProperty("toggle", false); + QTRY_COMPARE(item->width(), 300); + + item->setProperty("state1Width", 100); + QCOMPARE(item->width(), 300); + + item->setProperty("toggle", true); + QTRY_COMPARE(item->width(), 100); +} + QTEST_MAIN(tst_qquickstates) #include "tst_qquickstates.moc" diff --git a/tests/auto/quick/qquicksystempalette/CMakeLists.txt b/tests/auto/quick/qquicksystempalette/CMakeLists.txt index 5951dc1d079..45b527ce508 100644 --- a/tests/auto/quick/qquicksystempalette/CMakeLists.txt +++ b/tests/auto/quick/qquicksystempalette/CMakeLists.txt @@ -4,6 +4,12 @@ ## tst_qquicksystempalette Test: ##################################################################### +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + qt_internal_add_test(tst_qquicksystempalette SOURCES tst_qquicksystempalette.cpp @@ -13,6 +19,8 @@ qt_internal_add_test(tst_qquicksystempalette Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate + TESTDATA ${test_data} ) ## Scopes: @@ -22,3 +30,13 @@ qt_internal_extend_target(tst_qquicksystempalette CONDITION TARGET Qt::Widgets PUBLIC_LIBRARIES Qt::Widgets ) + +qt_internal_extend_target(tst_qquicksystempalette CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquicksystempalette CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quick/qquicksystempalette/data/systemPalette.qml b/tests/auto/quick/qquicksystempalette/data/systemPalette.qml new file mode 100644 index 00000000000..3a1395ec187 --- /dev/null +++ b/tests/auto/quick/qquicksystempalette/data/systemPalette.qml @@ -0,0 +1,4 @@ +import QtQuick 2.0 + +SystemPalette { +} diff --git a/tests/auto/quick/qquicksystempalette/data/systemPaletteDisabled.qml b/tests/auto/quick/qquicksystempalette/data/systemPaletteDisabled.qml new file mode 100644 index 00000000000..3eaeac89855 --- /dev/null +++ b/tests/auto/quick/qquicksystempalette/data/systemPaletteDisabled.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +SystemPalette { + colorGroup: SystemPalette.Disabled +} diff --git a/tests/auto/quick/qquicksystempalette/data/systemPaletteInactive.qml b/tests/auto/quick/qquicksystempalette/data/systemPaletteInactive.qml new file mode 100644 index 00000000000..f43e7073c6c --- /dev/null +++ b/tests/auto/quick/qquicksystempalette/data/systemPaletteInactive.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +SystemPalette { + colorGroup: SystemPalette.Inactive +} diff --git a/tests/auto/quick/qquicksystempalette/tst_qquicksystempalette.cpp b/tests/auto/quick/qquicksystempalette/tst_qquicksystempalette.cpp index 071dcafc975..b18a2cc6662 100644 --- a/tests/auto/quick/qquicksystempalette/tst_qquicksystempalette.cpp +++ b/tests/auto/quick/qquicksystempalette/tst_qquicksystempalette.cpp @@ -32,8 +32,9 @@ #include <QtQml/qqmlcomponent.h> #include <QtQuick/private/qquicksystempalette_p.h> #include <qpalette.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> -class tst_qquicksystempalette : public QObject +class tst_qquicksystempalette : public QQmlDataTest { Q_OBJECT public: @@ -51,15 +52,11 @@ private slots: QQmlEngine engine; }; -tst_qquicksystempalette::tst_qquicksystempalette() -{ -} +tst_qquicksystempalette::tst_qquicksystempalette() : QQmlDataTest(QT_QMLTEST_DATADIR) { } void tst_qquicksystempalette::activePalette() { - QString componentStr = "import QtQuick 2.0\nSystemPalette { }"; - QQmlComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQmlComponent component(&engine, testFileUrl("systemPalette.qml")); QQuickSystemPalette *object = qobject_cast<QQuickSystemPalette*>(component.create()); QVERIFY(object != nullptr); @@ -86,9 +83,7 @@ void tst_qquicksystempalette::activePalette() void tst_qquicksystempalette::inactivePalette() { - QString componentStr = "import QtQuick 2.0\nSystemPalette { colorGroup: SystemPalette.Inactive }"; - QQmlComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQmlComponent component(&engine, testFileUrl("systemPaletteInactive.qml")); QQuickSystemPalette *object = qobject_cast<QQuickSystemPalette*>(component.create()); QVERIFY(object != nullptr); @@ -116,9 +111,7 @@ void tst_qquicksystempalette::inactivePalette() void tst_qquicksystempalette::disabledPalette() { - QString componentStr = "import QtQuick 2.0\nSystemPalette { colorGroup: SystemPalette.Disabled }"; - QQmlComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQmlComponent component(&engine, testFileUrl("systemPaletteDisabled.qml")); QQuickSystemPalette *object = qobject_cast<QQuickSystemPalette*>(component.create()); QVERIFY(object != nullptr); @@ -147,9 +140,7 @@ void tst_qquicksystempalette::disabledPalette() #ifndef QT_NO_WIDGETS void tst_qquicksystempalette::paletteChanged() { - QString componentStr = "import QtQuick 2.0\nSystemPalette { }"; - QQmlComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQmlComponent component(&engine, testFileUrl("systemPalette.qml")); QQuickSystemPalette *object = qobject_cast<QQuickSystemPalette*>(component.create()); QVERIFY(object != nullptr); diff --git a/tests/auto/quick/qquicktableview/CMakeLists.txt b/tests/auto/quick/qquicktableview/CMakeLists.txt index 04842aaae2f..708d2cd5164 100644 --- a/tests/auto/quick/qquicktableview/CMakeLists.txt +++ b/tests/auto/quick/qquicktableview/CMakeLists.txt @@ -12,16 +12,8 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquicktableview SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h testmodel.h tst_qquicktableview.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -30,6 +22,7 @@ qt_internal_add_test(tst_qquicktableview Qt::QmlPrivate Qt::QuickPrivate Qt::QuickTest + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquicktableview/data/deletedDelegate.qml b/tests/auto/quick/qquicktableview/data/deletedDelegate.qml new file mode 100644 index 00000000000..ec3161bbac4 --- /dev/null +++ b/tests/auto/quick/qquicktableview/data/deletedDelegate.qml @@ -0,0 +1,25 @@ +import QtQuick 2.15 + +Item { + width: 800 + height: 600 + + Component { + id: dyn + Item { + property Component comp: Item {} + } + } + + TableView { + id: tv + anchors.fill: parent + objectName: "tableview" + } + + Component.onCompleted: { + let o = dyn.createObject(); + tv.delegate = o.comp; + o.destroy(); + } +} diff --git a/tests/auto/quick/qquicktableview/data/resetJsModelData.qml b/tests/auto/quick/qquicktableview/data/resetJsModelData.qml new file mode 100644 index 00000000000..def5346147e --- /dev/null +++ b/tests/auto/quick/qquicktableview/data/resetJsModelData.qml @@ -0,0 +1,19 @@ +import QtQuick + +Item { + width: 100 + height: 300 + + property alias tableView: tableView + + TableView { + id: tableView + anchors.fill: parent + property int modelUpdated: 0 + onModelChanged: { ++modelUpdated } + delegate: Item { + implicitHeight: 10 + implicitWidth: 10 + } + } +} diff --git a/tests/auto/quick/qquicktableview/data/resetModelData.qml b/tests/auto/quick/qquicktableview/data/resetModelData.qml new file mode 100644 index 00000000000..f7b3ec3009f --- /dev/null +++ b/tests/auto/quick/qquicktableview/data/resetModelData.qml @@ -0,0 +1,25 @@ +import QtQuick + +Item { + width: 640 + height: 450 + + property alias tableView: tableView + + TableView { + id: tableView + anchors.fill: parent + height: 300 + width: 200 + + property bool success: false + + delegate: Rectangle { + required property var model + implicitWidth: 100 + implicitHeight: 50 + property var mydata: model?.custom ?? model.display + onMydataChanged: tableView.success = mydata === 42 + } + } +} diff --git a/tests/auto/quick/qquicktableview/data/syncviewsimple.qml b/tests/auto/quick/qquicktableview/data/syncviewsimple.qml index 012cceaa9d4..fc75e97a0f7 100644 --- a/tests/auto/quick/qquicktableview/data/syncviewsimple.qml +++ b/tests/auto/quick/qquicktableview/data/syncviewsimple.qml @@ -49,6 +49,9 @@ Item { property alias tableViewV: tableViewV property alias tableViewHV: tableViewHV + property real delegateWidth: 30 + property real delegateHeight: 60 + Column { spacing: 10 TableView { @@ -93,7 +96,7 @@ Item { height: 100 anchors.margins: 1 clip: true - delegate: tableViewDelegate + delegate: tableViewDelegateMainView columnSpacing: 1 rowSpacing: 1 @@ -104,12 +107,29 @@ Item { Component { id: tableViewDelegate + Rectangle { + objectName: "tableViewDelegate" + color: "lightblue" + border.width: 1 + implicitWidth: 100 + implicitHeight: 100 + + Text { + anchors.centerIn: parent + font.pixelSize: 10 + text: parent.TableView.view.objectName + "\n" + column + ", " + row + } + } + } + + Component { + id: tableViewDelegateMainView Rectangle { objectName: "tableViewDelegate" color: "lightgray" border.width: 1 - implicitWidth: 30 - implicitHeight: 60 + implicitWidth: delegateWidth + implicitHeight: delegateHeight Text { anchors.centerIn: parent diff --git a/tests/auto/quick/qquicktableview/testmodel.h b/tests/auto/quick/qquicktableview/testmodel.h index 3db32938be3..46e9b446d56 100644 --- a/tests/auto/quick/qquicktableview/testmodel.h +++ b/tests/auto/quick/qquicktableview/testmodel.h @@ -61,13 +61,27 @@ class TestModel : public QAbstractTableModel QVariant data(const QModelIndex &index, int role) const override { - if (!index.isValid() || role != Qt::DisplayRole) + if (!index.isValid()) return QVariant(); - int serializedIndex = index.row() + (index.column() * m_columns); - if (modelData.contains(serializedIndex)) - return modelData.value(serializedIndex); - return QStringLiteral("%1").arg(index.row()); + QVariant ret; + + switch (role) { + case Qt::UserRole: + ret = 42; + break; + case Qt::DisplayRole: { + int serializedIndex = index.row() + (index.column() * m_columns); + if (modelData.contains(serializedIndex)) + ret = modelData.value(serializedIndex); + else + ret = QStringLiteral("%1").arg(index.row()); } + break; + default: + break; + } + + return ret; } Q_INVOKABLE QVariant dataFromSerializedIndex(int index) const @@ -79,9 +93,18 @@ class TestModel : public QAbstractTableModel QHash<int, QByteArray> roleNames() const override { + if (m_useCustomRoleNames) + return { { Qt::UserRole, "custom"} }; return { {Qt::DisplayRole, "display"} }; } + Q_INVOKABLE void useCustomRoleNames(bool use) + { + beginResetModel(); + m_useCustomRoleNames = use; + endResetModel(); + } + Q_INVOKABLE void setModelData(const QPoint &cell, const QSize &span, const QString &string) { for (int c = 0; c < span.width(); ++c) { @@ -192,6 +215,7 @@ class TestModel : public QAbstractTableModel int m_rows = 0; int m_columns = 0; bool m_dataCanBeFetched = false; + bool m_useCustomRoleNames = false; QHash<int, QString> modelData; }; diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp index 340c44fdb57..ec568a21e4b 100644 --- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp +++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp @@ -43,12 +43,12 @@ #include "testmodel.h" -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> -using namespace QQuickViewTestUtil; -using namespace QQuickVisualTestUtil; +using namespace QQuickViewTestUtils; +using namespace QQuickVisualTestUtils; static const char* kDelegateObjectName = "tableViewDelegate"; static const char *kDelegatesCreatedCountProp = "delegatesCreatedCount"; @@ -73,7 +73,7 @@ Q_DECLARE_METATYPE(QMarginsF); view->show(); \ QVERIFY(QTest::qWaitForWindowActive(view)); \ auto loader = view->rootObject()->property("loader").value<QQuickLoader *>(); \ - loader->setSource(QUrl::fromLocalFile("data/" fileName)); \ + loader->setSource(testFileUrl(fileName)); \ QTRY_VERIFY(loader->item()); \ QCOMPARE(loader->status(), QQuickLoader::Status::Ready); \ GET_QML_TABLEVIEW(tableView) @@ -122,7 +122,7 @@ private slots: void isColumnLoadedAndIsRowLoaded(); void checkForceLayoutFunction(); void checkForceLayoutEndUpDoingALayout(); - void checkForceLayoutDuringModelChange(); + void checkForceLayoutInbetweenAddingRowsToModel(); void checkForceLayoutWhenAllItemsAreHidden(); void checkContentWidthAndHeight(); void checkContentWidthAndHeightForSmallTables(); @@ -179,10 +179,12 @@ private slots: void checkSyncView_childViews_data(); void checkSyncView_childViews(); void checkSyncView_differentSizedModels(); + void checkSyncView_differentGeometry(); void checkSyncView_connect_late_data(); void checkSyncView_connect_late(); void checkSyncView_pageFlicking(); void checkSyncView_emptyModel(); + void checkSyncView_topLeftChanged(); void delegateWithRequiredProperties(); void checkThatFetchMoreIsCalledWhenScrolledToTheEndOfTable(); void replaceModel(); @@ -192,6 +194,10 @@ private slots: void positionViewAtRow(); void positionViewAtColumn_data(); void positionViewAtColumn(); + void positionViewAtRowClamped_data(); + void positionViewAtRowClamped(); + void positionViewAtColumnClamped_data(); + void positionViewAtColumnClamped(); void itemAtCell_data(); void itemAtCell(); void leftRightTopBottomProperties_data(); @@ -206,9 +212,13 @@ private slots: void testSelectableStartPosEndPos(); void testSelectableStartPosEndPosOutsideView(); void testSelectableScrollTowardsPos(); + void resettingRolesRespected(); + void deletedDelegate(); + void checkRebuildJsModel(); }; tst_QQuickTableView::tst_QQuickTableView() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } @@ -673,10 +683,11 @@ void tst_QQuickTableView::checkForceLayoutEndUpDoingALayout() QCOMPARE(tableView->contentHeight(), (9 * (newDelegateSize + rowSpacing)) - rowSpacing); } -void tst_QQuickTableView::checkForceLayoutDuringModelChange() +void tst_QQuickTableView::checkForceLayoutInbetweenAddingRowsToModel() { - // Check that TableView doesn't assert if we call - // forceLayout() in the middle of a model change. + // Check that TableView doesn't assert if we call forceLayout() while waiting + // for a callback from the model that the row count has changed. Also make sure + // that we don't move the contentItem while doing so. LOAD_TABLEVIEW("plaintableview.qml"); const int initialRowCount = 10; @@ -691,9 +702,13 @@ void tst_QQuickTableView::checkForceLayoutDuringModelChange() WAIT_UNTIL_POLISHED; + const int contentY = 10; + tableView->setContentY(contentY); QCOMPARE(tableView->rows(), initialRowCount); + QCOMPARE(tableView->contentY(), contentY); model.addRow(0); QCOMPARE(tableView->rows(), initialRowCount + 1); + QCOMPARE(tableView->contentY(), contentY); } void tst_QQuickTableView::checkForceLayoutWhenAllItemsAreHidden() @@ -2637,6 +2652,18 @@ void tst_QQuickTableView::checkSyncView_rootView() QCOMPARE(tableViewVPrivate->loadedTableOuterRect.left(), 0); QCOMPARE(tableViewHVPrivate->loadedTableOuterRect, tableViewPrivate->loadedTableOuterRect); + + // Check that the column widths are in sync + for (int column = tableView->leftColumn(); column < tableView->rightColumn(); ++column) { + QCOMPARE(tableViewH->columnWidth(column), tableView->columnWidth(column)); + QCOMPARE(tableViewHV->columnWidth(column), tableView->columnWidth(column)); + } + + // Check that the row heights are in sync + for (int row = tableView->topRow(); row < tableView->bottomRow(); ++row) { + QCOMPARE(tableViewV->rowHeight(row), tableView->rowHeight(row)); + QCOMPARE(tableViewHV->rowHeight(row), tableView->rowHeight(row)); + } } void tst_QQuickTableView::checkSyncView_childViews_data() @@ -2742,6 +2769,18 @@ void tst_QQuickTableView::checkSyncView_childViews() QCOMPARE(tableViewHVPrivate->bottomRow(), tableViewPrivate->bottomRow()); QCOMPARE(tableViewHVPrivate->loadedTableOuterRect, tableViewPrivate->loadedTableOuterRect); } + + // Check that the column widths are in sync + for (int column = tableView->leftColumn(); column < tableView->rightColumn(); ++column) { + QCOMPARE(tableViewH->columnWidth(column), tableView->columnWidth(column)); + QCOMPARE(tableViewHV->columnWidth(column), tableView->columnWidth(column)); + } + + // Check that the row heights are in sync + for (int row = tableView->topRow(); row < tableView->bottomRow(); ++row) { + QCOMPARE(tableViewV->rowHeight(row), tableView->rowHeight(row)); + QCOMPARE(tableViewHV->rowHeight(row), tableView->rowHeight(row)); + } } void tst_QQuickTableView::checkSyncView_differentSizedModels() @@ -2807,6 +2846,61 @@ void tst_QQuickTableView::checkSyncView_differentSizedModels() QVERIFY(tableViewHVPrivate->loadedColumns.isEmpty()); } +void tst_QQuickTableView::checkSyncView_differentGeometry() +{ + // Check that you can have two tables in a syncView relation, where + // the sync "child" is larger than the sync view. This means that the + // child will display more rows and columns than the parent. + // In that case, the sync view will anyway need to load the same rows + // and columns as the child, otherwise the column and row sizes + // cannot be determined for the child. + LOAD_TABLEVIEW("syncviewsimple.qml"); + GET_QML_TABLEVIEW(tableViewH); + GET_QML_TABLEVIEW(tableViewV); + GET_QML_TABLEVIEW(tableViewHV); + + tableView->setWidth(40); + tableView->setHeight(40); + + auto tableViewModel = TestModelAsVariant(100, 100); + + tableView->setModel(tableViewModel); + tableViewH->setModel(tableViewModel); + tableViewV->setModel(tableViewModel); + tableViewHV->setModel(tableViewModel); + + WAIT_UNTIL_POLISHED; + + // Check that the column widths are in sync + for (int column = tableViewH->leftColumn(); column < tableViewH->rightColumn(); ++column) { + QCOMPARE(tableViewH->columnWidth(column), tableView->columnWidth(column)); + QCOMPARE(tableViewHV->columnWidth(column), tableView->columnWidth(column)); + } + + // Check that the row heights are in sync + for (int row = tableViewV->topRow(); row < tableViewV->bottomRow(); ++row) { + QCOMPARE(tableViewV->rowHeight(row), tableView->rowHeight(row)); + QCOMPARE(tableViewHV->rowHeight(row), tableView->rowHeight(row)); + } + + // Flick a bit, and do the same test again + tableView->setContentX(200); + tableView->setContentY(200); + WAIT_UNTIL_POLISHED; + + // Check that the column widths are in sync + for (int column = tableViewH->leftColumn(); column < tableViewH->rightColumn(); ++column) { + QCOMPARE(tableViewH->columnWidth(column), tableView->columnWidth(column)); + QCOMPARE(tableViewHV->columnWidth(column), tableView->columnWidth(column)); + } + + // Check that the row heights are in sync + for (int row = tableViewV->topRow(); row < tableViewV->bottomRow(); ++row) { + QCOMPARE(tableViewV->rowHeight(row), tableView->rowHeight(row)); + QCOMPARE(tableViewHV->rowHeight(row), tableView->rowHeight(row)); + } +} + void tst_QQuickTableView::checkSyncView_connect_late_data() { QTest::addColumn<qreal>("flickToPos"); @@ -2974,6 +3068,42 @@ void tst_QQuickTableView::checkSyncView_emptyModel() QCOMPARE(tableViewVPrivate->loadedTableOuterRect.left(), 0); } +void tst_QQuickTableView::checkSyncView_topLeftChanged() +{ + LOAD_TABLEVIEW("syncviewsimple.qml"); + GET_QML_TABLEVIEW(tableViewH); + GET_QML_TABLEVIEW(tableViewV); + GET_QML_TABLEVIEW(tableViewHV); + QQuickTableView *views[] = {tableViewH, tableViewV, tableViewHV}; + + auto model = TestModelAsVariant(100, 100); + tableView->setModel(model); + + for (auto view : views) + view->setModel(model); + + tableView->setColumnWidthProvider(QJSValue()); + tableView->setRowHeightProvider(QJSValue()); + view->rootObject()->setProperty("delegateWidth", 300); + view->rootObject()->setProperty("delegateHeight", 300); + tableView->forceLayout(); + + tableViewHV->setContentX(350); + tableViewHV->setContentY(350); + + WAIT_UNTIL_POLISHED; + + QCOMPARE(tableViewH->leftColumn(), tableView->leftColumn()); + QCOMPARE(tableViewV->topRow(), tableView->topRow()); + + view->rootObject()->setProperty("delegateWidth", 50); + view->rootObject()->setProperty("delegateHeight", 50); + tableView->forceLayout(); + + QCOMPARE(tableViewH->leftColumn(), tableView->leftColumn()); + QCOMPARE(tableViewV->topRow(), tableView->topRow()); +} + void tst_QQuickTableView::checkThatFetchMoreIsCalledWhenScrolledToTheEndOfTable() { LOAD_TABLEVIEW("plaintableview.qml"); @@ -3137,48 +3267,30 @@ void tst_QQuickTableView::positionViewAtRow_data() QTest::newRow("AlignTop 1") << 1 << Qt::AlignTop << 0. << 50.; QTest::newRow("AlignTop 50") << 50 << Qt::AlignTop << 0. << -1.; QTest::newRow("AlignTop 0") << 0 << Qt::AlignTop << 0. << -1.; - QTest::newRow("AlignTop 99") << 99 << Qt::AlignTop << 0. << -1.; - - QTest::newRow("AlignTop 0") << 0 << Qt::AlignTop << -10. << 0.; QTest::newRow("AlignTop 1") << 1 << Qt::AlignTop << -10. << 0.; QTest::newRow("AlignTop 1") << 1 << Qt::AlignTop << -10. << 50.; QTest::newRow("AlignTop 50") << 50 << Qt::AlignTop << -10. << -1.; - QTest::newRow("AlignTop 0") << 0 << Qt::AlignTop << -10. << -1.; - QTest::newRow("AlignTop 99") << 99 << Qt::AlignTop << -10. << -1.; - QTest::newRow("AlignBottom 0") << 0 << Qt::AlignBottom << 0. << 0.; - QTest::newRow("AlignBottom 1") << 1 << Qt::AlignBottom << 0. << 0.; - QTest::newRow("AlignBottom 1") << 1 << Qt::AlignBottom << 0. << 50.; QTest::newRow("AlignBottom 50") << 50 << Qt::AlignBottom << 0. << -1.; - QTest::newRow("AlignBottom 0") << 0 << Qt::AlignBottom << 0. << -1.; + QTest::newRow("AlignBottom 98") << 98 << Qt::AlignBottom << 0. << -1.; QTest::newRow("AlignBottom 99") << 99 << Qt::AlignBottom << 0. << -1.; + QTest::newRow("AlignBottom 50") << 40 << Qt::AlignBottom << 10. << -1.; + QTest::newRow("AlignBottom 40") << 50 << Qt::AlignBottom << -10. << -1.; + QTest::newRow("AlignBottom 98") << 98 << Qt::AlignBottom << 10. << -1.; + QTest::newRow("AlignBottom 99") << 99 << Qt::AlignBottom << -10. << -1.; - QTest::newRow("AlignBottom 0") << 0 << Qt::AlignBottom << 10. << 0.; - QTest::newRow("AlignBottom 1") << 1 << Qt::AlignBottom << 10. << 0.; - QTest::newRow("AlignBottom 1") << 1 << Qt::AlignBottom << 10. << 50.; - QTest::newRow("AlignBottom 50") << 50 << Qt::AlignBottom << 10. << -1.; - QTest::newRow("AlignBottom 0") << 0 << Qt::AlignBottom << 10. << -1.; - QTest::newRow("AlignBottom 99") << 99 << Qt::AlignBottom << 10. << -1.; - - QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << 0. << 0.; - QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << 0. << 0.; - QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << 0. << 50.; + QTest::newRow("AlignCenter 40") << 40 << Qt::AlignCenter << 0. << -1.; QTest::newRow("AlignCenter 50") << 50 << Qt::AlignCenter << 0. << -1.; - QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << 0. << -1.; - QTest::newRow("AlignCenter 99") << 99 << Qt::AlignCenter << 0. << -1.; - - QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << -10. << 0.; - QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << -10. << 0.; - QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << -10. << 50.; + QTest::newRow("AlignCenter 40") << 40 << Qt::AlignCenter << 10. << -1.; QTest::newRow("AlignCenter 50") << 50 << Qt::AlignCenter << -10. << -1.; - QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << -10. << -1.; - QTest::newRow("AlignCenter 99") << 99 << Qt::AlignCenter << -10. << -1.; } void tst_QQuickTableView::positionViewAtRow() { // Check that positionViewAtRow actually flicks the view - // to the right position so that the row becomes visible + // to the right position so that the row becomes visible. + // For this test, we only check cells that can be placed exactly + // according to the given alignment. QFETCH(int, row); QFETCH(Qt::AlignmentFlag, alignment); QFETCH(qreal, offset); @@ -3228,48 +3340,27 @@ void tst_QQuickTableView::positionViewAtColumn_data() QTest::newRow("AlignLeft 1") << 1 << Qt::AlignLeft << 0. << 50.; QTest::newRow("AlignLeft 50") << 50 << Qt::AlignLeft << 0. << -1.; QTest::newRow("AlignLeft 0") << 0 << Qt::AlignLeft << 0. << -1.; - QTest::newRow("AlignLeft 99") << 99 << Qt::AlignLeft << 0. << -1.; - - QTest::newRow("AlignLeft 0") << 0 << Qt::AlignLeft << -10. << 0.; QTest::newRow("AlignLeft 1") << 1 << Qt::AlignLeft << -10. << 0.; QTest::newRow("AlignLeft 1") << 1 << Qt::AlignLeft << -10. << 50.; QTest::newRow("AlignLeft 50") << 50 << Qt::AlignLeft << -10. << -1.; - QTest::newRow("AlignLeft 0") << 0 << Qt::AlignLeft << -10. << -1.; - QTest::newRow("AlignLeft 99") << 99 << Qt::AlignLeft << -10. << -1.; - QTest::newRow("AlignRight 0") << 0 << Qt::AlignRight << 0. << 0.; - QTest::newRow("AlignRight 1") << 1 << Qt::AlignRight << 0. << 0.; - QTest::newRow("AlignRight 1") << 1 << Qt::AlignRight << 0. << 50.; QTest::newRow("AlignRight 50") << 50 << Qt::AlignRight << 0. << -1.; - QTest::newRow("AlignRight 0") << 0 << Qt::AlignRight << 0. << -1.; QTest::newRow("AlignRight 99") << 99 << Qt::AlignRight << 0. << -1.; - - QTest::newRow("AlignRight 0") << 0 << Qt::AlignRight << 10. << 0.; - QTest::newRow("AlignRight 1") << 1 << Qt::AlignRight << 10. << 0.; - QTest::newRow("AlignRight 1") << 1 << Qt::AlignRight << 10. << 50.; QTest::newRow("AlignRight 50") << 50 << Qt::AlignRight << 10. << -1.; - QTest::newRow("AlignRight 0") << 0 << Qt::AlignRight << 10. << -1.; - QTest::newRow("AlignRight 99") << 99 << Qt::AlignRight << 10. << -1.; + QTest::newRow("AlignRight 99") << 99 << Qt::AlignRight << -10. << -1.; - QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << 0. << 0.; - QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << 0. << 0.; - QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << 0. << 50.; + QTest::newRow("AlignCenter 40") << 50 << Qt::AlignCenter << 0. << -1.; QTest::newRow("AlignCenter 50") << 50 << Qt::AlignCenter << 0. << -1.; - QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << 0. << -1.; - QTest::newRow("AlignCenter 99") << 99 << Qt::AlignCenter << 0. << -1.; - - QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << -10. << 0.; - QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << -10. << 0.; - QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << -10. << 50.; + QTest::newRow("AlignCenter 40") << 50 << Qt::AlignCenter << 10. << -1.; QTest::newRow("AlignCenter 50") << 50 << Qt::AlignCenter << -10. << -1.; - QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << -10. << -1.; - QTest::newRow("AlignCenter 99") << 99 << Qt::AlignCenter << -10. << -1.; } void tst_QQuickTableView::positionViewAtColumn() { // Check that positionViewAtColumn actually flicks the view - // to the right position so that the row becomes visible + // to the right position so that the row becomes visible. + // For this test, we only check cells that can be placed exactly + // according to the given alignment. QFETCH(int, column); QFETCH(Qt::AlignmentFlag, alignment); QFETCH(qreal, offset); @@ -3307,6 +3398,134 @@ void tst_QQuickTableView::positionViewAtColumn() } } +void tst_QQuickTableView::positionViewAtRowClamped_data() +{ + QTest::addColumn<int>("row"); + QTest::addColumn<Qt::AlignmentFlag>("alignment"); + QTest::addColumn<qreal>("offset"); + QTest::addColumn<qreal>("contentYStartPos"); + + QTest::newRow("AlignTop 0") << 0 << Qt::AlignTop << -10. << 0.; + QTest::newRow("AlignTop 0") << 0 << Qt::AlignTop << -10. << -1.; + QTest::newRow("AlignTop 99") << 99 << Qt::AlignTop << 0. << -1.; + QTest::newRow("AlignTop 99") << 99 << Qt::AlignTop << -10. << -1.; + + QTest::newRow("AlignBottom 0") << 0 << Qt::AlignBottom << 0. << 0.; + QTest::newRow("AlignBottom 1") << 1 << Qt::AlignBottom << 0. << 0.; + QTest::newRow("AlignBottom 1") << 1 << Qt::AlignBottom << 0. << 50.; + QTest::newRow("AlignBottom 0") << 0 << Qt::AlignBottom << 0. << -1.; + + QTest::newRow("AlignBottom 0") << 0 << Qt::AlignBottom << 10. << 0.; + QTest::newRow("AlignBottom 1") << 1 << Qt::AlignBottom << 10. << 0.; + QTest::newRow("AlignBottom 1") << 1 << Qt::AlignBottom << 10. << 50.; + QTest::newRow("AlignBottom 0") << 0 << Qt::AlignBottom << 10. << -1.; + QTest::newRow("AlignBottom 99") << 99 << Qt::AlignBottom << 10. << -1.; + + QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << 0. << 0.; + QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << 0. << 0.; + QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << 0. << 50.; + QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << 0. << -1.; + QTest::newRow("AlignCenter 99") << 99 << Qt::AlignCenter << 0. << -1.; + + QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << -10. << 0.; + QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << -10. << 0.; + QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << -10. << 50.; + QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << -10. << -1.; + QTest::newRow("AlignCenter 99") << 99 << Qt::AlignCenter << -10. << -1.; +} + +void tst_QQuickTableView::positionViewAtRowClamped() +{ + // Check that positionViewAtRow actually flicks the table to the + // right position so that the row becomes visible. For this test, we + // only test cells that cannot be placed exactly at the given alignment, + // because it would cause the table to overshoot. Instead the + // table should be flicked to the edge of the viewport, close to the + // requested alignment. + QFETCH(int, row); + QFETCH(Qt::AlignmentFlag, alignment); + QFETCH(qreal, offset); + QFETCH(qreal, contentYStartPos); + + LOAD_TABLEVIEW("plaintableview.qml"); + auto model = TestModelAsVariant(100, 100); + tableView->setModel(model); + if (contentYStartPos >= 0) + tableView->setContentY(contentYStartPos); + + WAIT_UNTIL_POLISHED; + + tableView->positionViewAtRow(row, alignment, offset); + + WAIT_UNTIL_POLISHED; + + QCOMPARE(tableView->contentY(), row < 50 ? 0 : tableView->contentHeight() - tableView->height()); +} + +void tst_QQuickTableView::positionViewAtColumnClamped_data() +{ + QTest::addColumn<int>("column"); + QTest::addColumn<Qt::AlignmentFlag>("alignment"); + QTest::addColumn<qreal>("offset"); + QTest::addColumn<qreal>("contentXStartPos"); + + QTest::newRow("AlignLeft 0") << 0 << Qt::AlignLeft << -10. << 0.; + QTest::newRow("AlignLeft 0") << 0 << Qt::AlignLeft << -10. << -1.; + QTest::newRow("AlignLeft 99") << 99 << Qt::AlignLeft << 0. << -1.; + QTest::newRow("AlignLeft 99") << 99 << Qt::AlignLeft << -10. << -1.; + + QTest::newRow("AlignRight 0") << 0 << Qt::AlignRight << 0. << 0.; + QTest::newRow("AlignRight 1") << 1 << Qt::AlignRight << 0. << 0.; + QTest::newRow("AlignRight 1") << 1 << Qt::AlignRight << 0. << 50.; + QTest::newRow("AlignRight 0") << 0 << Qt::AlignRight << 0. << -1.; + + QTest::newRow("AlignRight 0") << 0 << Qt::AlignRight << 10. << 0.; + QTest::newRow("AlignRight 1") << 1 << Qt::AlignRight << 10. << 0.; + QTest::newRow("AlignRight 1") << 1 << Qt::AlignRight << 10. << 50.; + QTest::newRow("AlignRight 0") << 0 << Qt::AlignRight << 10. << -1.; + QTest::newRow("AlignRight 99") << 99 << Qt::AlignRight << 10. << -1.; + + QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << 0. << 0.; + QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << 0. << 0.; + QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << 0. << 50.; + QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << 0. << -1.; + QTest::newRow("AlignCenter 99") << 99 << Qt::AlignCenter << 0. << -1.; + + QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << -10. << 0.; + QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << -10. << 0.; + QTest::newRow("AlignCenter 1") << 1 << Qt::AlignCenter << -10. << 50.; + QTest::newRow("AlignCenter 0") << 0 << Qt::AlignCenter << -10. << -1.; + QTest::newRow("AlignCenter 99") << 99 << Qt::AlignCenter << -10. << -1.; +} + +void tst_QQuickTableView::positionViewAtColumnClamped() +{ + // Check that positionViewAtColumn actually flicks the table to the + // right position so that the column becomes visible. For this test, we + // only test cells that cannot be placed exactly at the given alignment, + // because it would cause the table to overshoot. Instead the + // table should be flicked to the edge of the viewport, close to the + // requested alignment. + QFETCH(int, column); + QFETCH(Qt::AlignmentFlag, alignment); + QFETCH(qreal, offset); + QFETCH(qreal, contentXStartPos); + + LOAD_TABLEVIEW("plaintableview.qml"); + auto model = TestModelAsVariant(100, 100); + tableView->setModel(model); + if (contentXStartPos >= 0) + tableView->setContentX(contentXStartPos); + + WAIT_UNTIL_POLISHED; + + tableView->positionViewAtColumn(column, alignment, offset); + + WAIT_UNTIL_POLISHED; + + QCOMPARE(tableView->contentX(), column < 50 ? 0 : tableView->contentWidth() - tableView->width()); +} + void tst_QQuickTableView::itemAtCell_data() { QTest::addColumn<QPoint>("cell"); @@ -3763,6 +3982,59 @@ void tst_QQuickTableView::testSelectableScrollTowardsPos() QCOMPARE(tableView->contentY(), 0); } +void tst_QQuickTableView::resettingRolesRespected() +{ + LOAD_TABLEVIEW("resetModelData.qml"); + + TestModel model(1, 1); + tableView->setModel(QVariant::fromValue(&model)); + + WAIT_UNTIL_POLISHED; + + QVERIFY(!tableView->property("success").toBool()); + model.useCustomRoleNames(true); + QTRY_VERIFY(tableView->property("success").toBool()); +} + +void tst_QQuickTableView::deletedDelegate() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("deletedDelegate.qml")); + std::unique_ptr<QObject> root(component.create()); + QVERIFY(root); + auto tv = root->findChild<QQuickTableView *>("tableview"); + QVERIFY(tv); + // we need one event loop iteration for the deferred delete to trigger + // thus the QTRY_VERIFY + QTRY_COMPARE(tv->delegate(), nullptr); +} + +void tst_QQuickTableView::checkRebuildJsModel() +{ + LOAD_TABLEVIEW("resetJsModelData.qml"); // gives us 'tableView' variable + + // Generate javascript model + const int size = 5; + const char* modelUpdated = "modelUpdated"; + + QJSEngine jsEngine; + QJSValue jsArray; + jsArray = jsEngine.newArray(size); + for (int i = 0; i < size; ++i) + jsArray.setProperty(i, QRandomGenerator::global()->generate()); + + QVariant jsModel = QVariant::fromValue(jsArray); + tableView->setModel(jsModel); + WAIT_UNTIL_POLISHED; + + // Model change would be triggered for the first time + QCOMPARE(tableView->property(modelUpdated).toInt(), 1); + + // Set the same model once again and check if model changes + tableView->setModel(jsModel); + QCOMPARE(tableView->property(modelUpdated).toInt(), 1); +} + QTEST_MAIN(tst_QQuickTableView) #include "tst_qquicktableview.moc" diff --git a/tests/auto/quick/qquicktext/BLACKLIST b/tests/auto/quick/qquicktext/BLACKLIST index 1a3ea5492f1..bc5f66da33d 100644 --- a/tests/auto/quick/qquicktext/BLACKLIST +++ b/tests/auto/quick/qquicktext/BLACKLIST @@ -10,3 +10,17 @@ sles ci b2qt 32bit [baselineOffset] ci b2qt 32bit +# QTBUG-102721 +[hAlignWidthDependsOnImplicitWidth] +android +[hAlignImplicitWidth] +android +[transparentBackground] +android + +# QTBUG-103096 +[largeTextObservesViewport] +android +[baselineOffset] +android + diff --git a/tests/auto/quick/qquicktext/CMakeLists.txt b/tests/auto/quick/qquicktext/CMakeLists.txt index 569347e2870..90c7f30a932 100644 --- a/tests/auto/quick/qquicktext/CMakeLists.txt +++ b/tests/auto/quick/qquicktext/CMakeLists.txt @@ -12,11 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquicktext SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h tst_qquicktext.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -25,6 +21,7 @@ qt_internal_add_test(tst_qquicktext Qt::QmlPrivate Qt::QuickPrivate Qt::QuickTest + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquicktext/data/padding.qml b/tests/auto/quick/qquicktext/data/padding.qml index ab0a37d0411..f830af0e407 100644 --- a/tests/auto/quick/qquicktext/data/padding.qml +++ b/tests/auto/quick/qquicktext/data/padding.qml @@ -9,4 +9,30 @@ Text { leftPadding: 30 rightPadding: 40 bottomPadding: 50 + + Rectangle { + width: parent.leftPadding + height: parent.height + color: "#6600FF00" + } + + Rectangle { + width: parent.width + height: parent.topPadding + color: "#66888800" + } + + Rectangle { + x: parent.width - parent.rightPadding + width: parent.rightPadding + height: parent.height + color: "#6600FFFF" + } + + Rectangle { + y: parent.height - parent.bottomPadding + width: parent.width + height: parent.bottomPadding + color: "#66880088" + } } diff --git a/tests/auto/quick/qquicktext/data/paddingInLoader.qml b/tests/auto/quick/qquicktext/data/paddingInLoader.qml new file mode 100644 index 00000000000..6ef7c25a9b1 --- /dev/null +++ b/tests/auto/quick/qquicktext/data/paddingInLoader.qml @@ -0,0 +1,14 @@ +import QtQuick 2.12 + +Item { + width: 30 + height: 30 + Loader { + anchors.fill: parent + sourceComponent: Text { + rightPadding: 30 + text: "Some text" + elide: Text.ElideRight + } + } +} diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index 339bea0e6fd..476297918d0 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -44,8 +44,9 @@ #include <private/qguiapplication_p.h> #include <limits.h> #include <QtGui/QMouseEvent> -#include "../../shared/util.h" -#include "testhttpserver.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/testhttpserver_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) @@ -153,6 +154,7 @@ private slots: void growFromZeroWidth(); void padding(); + void paddingInLoader(); void hintingPreference(); @@ -198,6 +200,7 @@ void tst_qquicktext::cleanup() } tst_qquicktext::tst_qquicktext() + : QQmlDataTest(QT_QMLTEST_DATADIR) { standard << "the quick brown fox jumped over the lazy dog" << "the quick brown fox\n jumped over the lazy dog"; @@ -2364,6 +2367,10 @@ void tst_qquicktext::implicitSize_data() void tst_qquicktext::implicitSize() { +#ifdef Q_OS_ANDROID + QSKIP("This segfaults on Android, QTBUG-103096"); +#endif + QFETCH(QString, text); QFETCH(QString, width); QFETCH(QString, format); @@ -3165,12 +3172,12 @@ void tst_qquicktext::imgTagsAlign_data() QTest::addColumn<QString>("src"); QTest::addColumn<int>("imgHeight"); QTest::addColumn<QString>("align"); - QTest::newRow("heart-bottom") << "data/images/heart200.png" << 181 << "bottom"; - QTest::newRow("heart-middle") << "data/images/heart200.png" << 181 << "middle"; - QTest::newRow("heart-top") << "data/images/heart200.png" << 181 << "top"; - QTest::newRow("starfish-bottom") << "data/images/starfish_2.png" << 217 << "bottom"; - QTest::newRow("starfish-middle") << "data/images/starfish_2.png" << 217 << "middle"; - QTest::newRow("starfish-top") << "data/images/starfish_2.png" << 217 << "top"; + QTest::newRow("heart-bottom") << "images/heart200.png" << 181 << "bottom"; + QTest::newRow("heart-middle") << "images/heart200.png" << 181 << "middle"; + QTest::newRow("heart-top") << "images/heart200.png" << 181 << "top"; + QTest::newRow("starfish-bottom") << "images/starfish_2.png" << 217 << "bottom"; + QTest::newRow("starfish-middle") << "images/starfish_2.png" << 217 << "middle"; + QTest::newRow("starfish-top") << "images/starfish_2.png" << 217 << "top"; } void tst_qquicktext::imgTagsAlign() @@ -3180,7 +3187,7 @@ void tst_qquicktext::imgTagsAlign() QFETCH(QString, align); QString componentStr = "import QtQuick 2.0\nText { text: \"This is a test <img src=\\\"" + src + "\\\" align=\\\"" + align + "\\\"> of image.\" }"; QQmlComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(".")); + textComponent.setData(componentStr.toLatin1(), testFileUrl(".")); QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); QVERIFY(textObject != nullptr); @@ -3202,10 +3209,10 @@ void tst_qquicktext::imgTagsAlign() void tst_qquicktext::imgTagsMultipleImages() { - QString componentStr = "import QtQuick 2.0\nText { text: \"This is a starfish<img src=\\\"data/images/starfish_2.png\\\" width=\\\"60\\\" height=\\\"60\\\" > and another one<img src=\\\"data/images/heart200.png\\\" width=\\\"85\\\" height=\\\"85\\\">.\" }"; + QString componentStr = "import QtQuick 2.0\nText { text: \"This is a starfish<img src=\\\"images/starfish_2.png\\\" width=\\\"60\\\" height=\\\"60\\\" > and another one<img src=\\\"images/heart200.png\\\" width=\\\"85\\\" height=\\\"85\\\">.\" }"; QQmlComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(".")); + textComponent.setData(componentStr.toLatin1(), testFileUrl(".")); QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); QVERIFY(textObject != nullptr); @@ -3261,11 +3268,15 @@ void tst_qquicktext::imgTagsUpdates() void tst_qquicktext::imgTagsError() { - QString componentStr = "import QtQuick 2.0\nText { text: \"This is a starfish<img src=\\\"data/images/starfish_2.pn\\\" width=\\\"60\\\" height=\\\"60\\\">.\" }"; + QString componentStr = "import QtQuick 2.0\nText { text: \"This is a starfish<img src=\\\"images/starfish_2.pn\\\" width=\\\"60\\\" height=\\\"60\\\">.\" }"; QQmlComponent textComponent(&engine); - QTest::ignoreMessage(QtWarningMsg, "<Unknown File>:2:1: QML Text: Cannot open: file:data/images/starfish_2.pn"); - textComponent.setData(componentStr.toLatin1(), QUrl("file:")); + const QString expectedMessage( + testFileUrl(".").toString() + + ":2:1: QML Text: Cannot open: " + + testFileUrl("images/starfish_2.pn").toString()); + QTest::ignoreMessage(QtWarningMsg, expectedMessage.toLatin1()); + textComponent.setData(componentStr.toLatin1(), testFileUrl(".")); QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); QVERIFY(textObject != nullptr); @@ -3513,6 +3524,46 @@ void tst_qquicktext::fontSizeMode() myText->setElideMode(QQuickText::ElideNone); QVERIFY(QQuickTest::qWaitForItemPolished(myText)); + + // Growing height needs to update the baselineOffset when AlignBottom is used + // and text is NOT wrapped + myText->setVAlign(QQuickText::AlignBottom); + myText->setFontSizeMode(QQuickText::Fit); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); + + int baselineOffset = myText->baselineOffset(); + myText->setHeight(myText->height() * 2); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); + QVERIFY(myText->baselineOffset() > baselineOffset); + + // Growing height needs to update the baselineOffset when AlignBottom is used + // and the text is wrapped + myText->setVAlign(QQuickText::AlignBottom); + myText->setFontSizeMode(QQuickText::Fit); + myText->setWrapMode(QQuickText::NoWrap); + myText->resetMaximumLineCount(); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); + + baselineOffset = myText->baselineOffset(); + myText->setHeight(myText->height() * 2); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); + QVERIFY(myText->baselineOffset() > baselineOffset); + + // Check baselineOffset for the HorizontalFit case + myText->setVAlign(QQuickText::AlignBottom); + myText->setFontSizeMode(QQuickText::HorizontalFit); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); + QSignalSpy baselineOffsetSpy(myText, SIGNAL(baselineOffsetChanged(qreal))); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); + const qreal oldBaselineOffset = myText->baselineOffset(); + myText->setHeight(myText->height() + 42); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); + QCOMPARE(baselineOffsetSpy.count(), 1); + QCOMPARE(myText->baselineOffset(), oldBaselineOffset + 42); + myText->setHeight(myText->height() - 42); + QVERIFY(QQuickTest::qWaitForItemPolished(myText)); + QCOMPARE(baselineOffsetSpy.count(), 2); + QCOMPARE(myText->baselineOffset(), oldBaselineOffset); } void tst_qquicktext::fontSizeModeMultiline_data() @@ -3851,13 +3902,11 @@ void tst_qquicktext::fontFormatSizes() QFETCH(QString, textWithTag); QFETCH(bool, fontIsBigger); - QQuickView *view = new QQuickView; { - view->setSource(testFileUrl("pointFontSizes.qml")); - view->show(); - - QQuickText *qtext = view->rootObject()->findChild<QQuickText*>("text"); - QQuickText *qtextWithTag = view->rootObject()->findChild<QQuickText*>("textWithTag"); + QQuickView view; + QVERIFY(QQuickTest::showView(view, testFileUrl("pointFontSizes.qml"))); + QQuickText *qtext = view.rootObject()->findChild<QQuickText*>("text"); + QQuickText *qtextWithTag = view.rootObject()->findChild<QQuickText*>("textWithTag"); QVERIFY(qtext != nullptr); QVERIFY(qtextWithTag != nullptr); @@ -3865,7 +3914,7 @@ void tst_qquicktext::fontFormatSizes() qtextWithTag->setText(textWithTag); for (int size = 6; size < 100; size += 4) { - view->rootObject()->setProperty("pointSize", size); + view.rootObject()->setProperty("pointSize", size); if (fontIsBigger) QVERIFY(qtext->height() <= qtextWithTag->height()); else @@ -3874,9 +3923,10 @@ void tst_qquicktext::fontFormatSizes() } { - view->setSource(testFileUrl("pixelFontSizes.qml")); - QQuickText *qtext = view->rootObject()->findChild<QQuickText*>("text"); - QQuickText *qtextWithTag = view->rootObject()->findChild<QQuickText*>("textWithTag"); + QQuickView view; + QVERIFY(QQuickTest::showView(view, testFileUrl("pixelFontSizes.qml"))); + QQuickText *qtext = view.rootObject()->findChild<QQuickText*>("text"); + QQuickText *qtextWithTag = view.rootObject()->findChild<QQuickText*>("textWithTag"); QVERIFY(qtext != nullptr); QVERIFY(qtextWithTag != nullptr); @@ -3884,14 +3934,13 @@ void tst_qquicktext::fontFormatSizes() qtextWithTag->setText(textWithTag); for (int size = 6; size < 100; size += 4) { - view->rootObject()->setProperty("pixelSize", size); + view.rootObject()->setProperty("pixelSize", size); if (fontIsBigger) QVERIFY(qtext->height() <= qtextWithTag->height()); else QVERIFY(qtext->height() >= qtextWithTag->height()); } } - delete view; } typedef qreal (*ExpectedBaseline)(QQuickText *item); @@ -3943,7 +3992,11 @@ static qreal expectedBaselineScaled(QQuickText *item) { QFont font = item->font(); QTextLayout layout(item->text().replace(QLatin1Char('\n'), QChar::LineSeparator)); - do { + + qreal low = 0; + qreal high = 10000; + + while (low < high) { layout.setFont(font); qreal width = 0; layout.beginLayout(); @@ -3953,12 +4006,23 @@ static qreal expectedBaselineScaled(QQuickText *item) } layout.endLayout(); - if (width < item->width()) { - QFontMetricsF fm(layout.font()); - return fm.ascent() + item->topPadding(); + if (width > item->width()) { + high = font.pointSizeF(); + font.setPointSizeF((high + low) / 2); + } else { + low = font.pointSizeF(); + + // When fontSizeMode != FixedSize, the font size will be scaled to a value + // The goal is to find a pointSize that uses as much space as possible while + // still fitting inside the available space. 0.01 is chosen as the threshold. + if ((high - low) < qreal(0.01)) { + QFontMetricsF fm(layout.font()); + return fm.ascent() + item->topPadding(); + } + + font.setPointSizeF((high + low) / 2); } - font.setPointSize(font.pointSize() - 1); - } while (font.pointSize() > 0); + } return item->topPadding(); } @@ -4380,6 +4444,18 @@ void tst_qquicktext::padding() obj->setElideMode(QQuickText::ElideRight); QCOMPARE(obj->implicitWidth(), cw + obj->leftPadding() + obj->rightPadding()); QCOMPARE(obj->implicitHeight(), ch + obj->topPadding() + obj->bottomPadding()); + + obj->setLeftPadding(0); + QCOMPARE(obj->implicitWidth(), cw + obj->leftPadding() + obj->rightPadding()); + + obj->setWidth(cw); + obj->setRightPadding(cw); + QCOMPARE(obj->contentWidth(), 0); + + for (int incr = 1; incr < 50 && qFuzzyIsNull(obj->contentWidth()); ++incr) + obj->setWidth(cw + incr); + QVERIFY(obj->contentWidth() > 0); + obj->setElideMode(QQuickText::ElideNone); obj->resetWidth(); @@ -4424,6 +4500,32 @@ void tst_qquicktext::padding() delete root; } +void tst_qquicktext::paddingInLoader() // QTBUG-83413 +{ + QQuickView view; + QVERIFY(QQuickTest::showView(view, testFileUrl("paddingInLoader.qml"))); + QQuickText *qtext = view.rootObject()->findChild<QQuickText*>(); + QVERIFY(qtext); + QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(qtext); + QVERIFY(textPrivate); + QCOMPARE(qtext->contentWidth(), 0); // does not render text, because width == rightPadding + QCOMPARE(textPrivate->availableWidth(), 0); + + qtext->setLeftPadding(qtext->width()); + qtext->setRightPadding(0); + QCOMPARE(qtext->contentWidth(), 0); // does not render text, because width == leftPadding + QCOMPARE(textPrivate->availableWidth(), 0); + + qtext->setRightPadding(qtext->width()); + QCOMPARE(qtext->contentWidth(), 0); // does not render text: available space is negative + QCOMPARE(textPrivate->availableWidth(), -qtext->width()); + + qtext->setLeftPadding(2); + qtext->setRightPadding(2); + QVERIFY(qtext->contentWidth() > 0); // finally space is available to render text + QCOMPARE(textPrivate->availableWidth(), qtext->width() - 4); +} + void tst_qquicktext::hintingPreference() { { diff --git a/tests/auto/quick/qquicktextdocument/CMakeLists.txt b/tests/auto/quick/qquicktextdocument/CMakeLists.txt index c2e52317fef..5533bbbdc49 100644 --- a/tests/auto/quick/qquicktextdocument/CMakeLists.txt +++ b/tests/auto/quick/qquicktextdocument/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquicktextdocument SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquicktextdocument.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquicktextdocument/tst_qquicktextdocument.cpp b/tests/auto/quick/qquicktextdocument/tst_qquicktextdocument.cpp index e9c699db6a5..dd6c3751397 100644 --- a/tests/auto/quick/qquicktextdocument/tst_qquicktextdocument.cpp +++ b/tests/auto/quick/qquicktextdocument/tst_qquicktextdocument.cpp @@ -36,11 +36,14 @@ #include <QtGui/QTextDocumentWriter> #include <QtQml/QQmlEngine> #include <QtQml/QQmlComponent> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_qquicktextdocument : public QQmlDataTest { Q_OBJECT +public: + tst_qquicktextdocument(); + private slots: void textDocumentWriter(); void textDocumentWithImage(); @@ -48,6 +51,11 @@ private slots: QString text = QStringLiteral("foo bar"); +tst_qquicktextdocument::tst_qquicktextdocument() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_qquicktextdocument::textDocumentWriter() { QQmlEngine e; diff --git a/tests/auto/quick/qquicktextedit/BLACKLIST b/tests/auto/quick/qquicktextedit/BLACKLIST index 48108566e0b..a8516a2411b 100644 --- a/tests/auto/quick/qquicktextedit/BLACKLIST +++ b/tests/auto/quick/qquicktextedit/BLACKLIST @@ -11,3 +11,18 @@ macos ci [hAlignVisual] sles + +# QTBUG-103098 +[hAlignVisual] +android +[linkHover] +android +[cursorVisible] +android +[transparentSelectionColor] +android + +# QTBUG-100991 +[selectionOnFocusOut] +android + diff --git a/tests/auto/quick/qquicktextedit/CMakeLists.txt b/tests/auto/quick/qquicktextedit/CMakeLists.txt index 57a955877b2..ebf481d85d1 100644 --- a/tests/auto/quick/qquicktextedit/CMakeLists.txt +++ b/tests/auto/quick/qquicktextedit/CMakeLists.txt @@ -12,16 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquicktextedit SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquicktextedit.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -29,6 +20,7 @@ qt_internal_add_test(tst_qquicktextedit Qt::NetworkPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquicktextedit/data/keyEventPropagation.qml b/tests/auto/quick/qquicktextedit/data/keyEventPropagation.qml new file mode 100644 index 00000000000..7793827b77d --- /dev/null +++ b/tests/auto/quick/qquicktextedit/data/keyEventPropagation.qml @@ -0,0 +1,31 @@ +import QtQuick + +FocusScope { + Component.onCompleted: edit.forceActiveFocus() + + anchors.fill: parent + + Keys.onPressed: function(event) { keyDown(event.key) } + Keys.onReleased: function(event) { keyUp(event.key) } + signal keyDown(int key) + signal keyUp(int key) + + TextEdit { + id: edit + anchors.centerIn: parent + width: 50 + height: 50 + Keys.onPressed: function(event) { + event.accepted = event.key == Qt.Key_A || event.key == Qt.Key_Right + } + Keys.onReleased: function(event) { + event.accepted = event.key == Qt.Key_A + } + Rectangle { + anchors.fill: parent + anchors.margins: -5 + color: "transparent" + border.width: 1 + } + } +} diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index ab35e374c70..583cb6b8d77 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -27,7 +27,7 @@ ****************************************************************************/ #include <qtest.h> #include <QtTest/QSignalSpy> -#include "../../shared/testhttpserver.h" +#include <QtQuickTestUtils/private/testhttpserver_p.h> #include <math.h> #include <QFile> #include <QTextDocument> @@ -50,10 +50,11 @@ #include <QClipboard> #include <QMimeData> #include <private/qquicktextcontrol_p.h> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" -#include "../../shared/platformquirks.h" -#include "../../shared/platforminputcontext.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTestUtils/private/platformquirks_p.h> +#include <QtQuickTestUtils/private/platforminputcontext_p.h> #include <private/qinputmethod_p.h> #include <QtGui/qstylehints.h> #include <qmath.h> @@ -232,6 +233,8 @@ private slots: void inFlickableTouch_data(); void inFlickableTouch(); + void keyEventPropagation(); + private: void simulateKeys(QWindow *window, const QList<Key> &keys); #if QT_CONFIG(shortcut) @@ -315,6 +318,7 @@ QList<Key> &operator <<(QList<Key> &keys, Qt::Key key) } tst_qquicktextedit::tst_qquicktextedit() + : QQmlDataTest(QT_QMLTEST_DATADIR) { qRegisterMetaType<QQuickTextEdit::TextFormat>(); qRegisterMetaType<QQuickTextEdit::SelectionMode>(); @@ -928,7 +932,7 @@ void tst_qquicktextedit::hAlignVisual() // Try to check whether alignment works by checking the number of black // pixels in the thirds of the grabbed image. - const int windowWidth = 200; + const int windowWidth = view.width(); const int textWidth = qCeil(text->implicitWidth()); QVERIFY2(textWidth < windowWidth, "System font too large."); const int sectionWidth = textWidth / 3; @@ -976,7 +980,7 @@ void tst_qquicktextedit::hAlignVisual() { // Left Align QImage image = view.grabWindow(); - int x = qCeil(text->implicitWidth()); + int x = qCeil(text->implicitWidth() * view.devicePixelRatio()); int left = numberOfNonWhitePixels(0, x, image); int right = numberOfNonWhitePixels(x, image.width() - x, image); QVERIFY2(left > 0, msgNotGreaterThan(left, 0).constData()); @@ -986,7 +990,7 @@ void tst_qquicktextedit::hAlignVisual() // HCenter Align text->setHAlign(QQuickText::AlignHCenter); QImage image = view.grabWindow(); - int x1 = qFloor(image.width() - text->implicitWidth()) / 2; + int x1 = qFloor(image.width() - text->implicitWidth() * view.devicePixelRatio()) / 2; int x2 = image.width() - x1; int left = numberOfNonWhitePixels(0, x1, image); int mid = numberOfNonWhitePixels(x1, x2 - x1, image); @@ -999,7 +1003,7 @@ void tst_qquicktextedit::hAlignVisual() // Right Align text->setHAlign(QQuickText::AlignRight); QImage image = view.grabWindow(); - int x = image.width() - qCeil(text->implicitWidth()); + int x = image.width() - qCeil(text->implicitWidth() * view.devicePixelRatio()); int left = numberOfNonWhitePixels(0, x, image); int right = numberOfNonWhitePixels(x, image.width() - x, image); QCOMPARE(left, 0); @@ -1361,7 +1365,7 @@ void tst_qquicktextedit::selectionOnFocusOut() QVERIFY(edit2->hasActiveFocus()); edit2->setFocus(false, Qt::PopupFocusReason); - QVERIFY(edit2->hasActiveFocus()); + QVERIFY(!edit2->hasActiveFocus()); QCOMPARE(edit2->selectedText(), QLatin1String("text 2")); } @@ -2581,8 +2585,8 @@ void tst_qquicktextedit::linkHover() QQuickView window(testFileUrl("linkInteraction.qml")); window.setFlag(Qt::FramelessWindowHint); QVERIFY(window.rootObject() != nullptr); - QQuickViewTestUtil::centerOnScreen(&window); - QQuickViewTestUtil::moveMouseAway(&window); + QQuickVisualTestUtils::centerOnScreen(&window); + QQuickVisualTestUtils::moveMouseAway(&window); window.show(); window.requestActivate(); QVERIFY(QTest::qWaitForWindowActive(&window)); @@ -2623,8 +2627,8 @@ void tst_qquicktextedit::linkInteraction() { QQuickView window(testFileUrl("linkInteraction.qml")); QVERIFY(window.rootObject() != nullptr); - QQuickViewTestUtil::centerOnScreen(&window); - QQuickViewTestUtil::moveMouseAway(&window); + QQuickVisualTestUtils::centerOnScreen(&window); + QQuickVisualTestUtils::moveMouseAway(&window); window.show(); window.requestActivate(); QVERIFY(QTest::qWaitForWindowActive(&window)); @@ -3322,6 +3326,8 @@ void tst_qquicktextedit::inFlickableTouch() QCOMPARE(flick->isMoving(), bool(expectFlickingAfter)); if (expectFlickingAfter) { qCDebug(lcTests) << "flickable started moving after" << i << "moves, when we got to" << p; + if (i == expectFlickingAfter - 1) + QEXPECT_FAIL("", "flicking a little prematurely: OpenSuse perhaps?", Continue); QCOMPARE(i, expectFlickingAfter); } QTest::touchEvent(&view, touchDevice).release(1, p, &view); @@ -6002,6 +6008,47 @@ void tst_qquicktextedit::transparentSelectionColor() QVERIFY(color.green() < 10); } +void tst_qquicktextedit::keyEventPropagation() +{ + QQuickView view; + view.setSource(testFileUrl("keyEventPropagation.qml")); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + QObject *root = view.rootObject(); + QVERIFY(root); + + QSignalSpy downSpy(root, SIGNAL(keyDown(int))); + QSignalSpy upSpy(root, SIGNAL(keyUp(int))); + + QQuickTextEdit *textEdit = root->findChild<QQuickTextEdit *>(); + QVERIFY(textEdit->hasActiveFocus()); + simulateKey(&view, Qt::Key_Back); + QCOMPARE(downSpy.count(), 1); + QCOMPARE(upSpy.count(), 1); + auto downKey = downSpy.takeFirst(); + auto upKey = upSpy.takeFirst(); + QCOMPARE(downKey.at(0).toInt(), Qt::Key_Back); + QCOMPARE(upKey.at(0).toInt(), Qt::Key_Back); + + simulateKey(&view, Qt::Key_Shift); + QCOMPARE(downSpy.count(), 1); + QCOMPARE(upSpy.count(), 1); + downKey = downSpy.takeFirst(); + upKey = upSpy.takeFirst(); + QCOMPARE(downKey.at(0).toInt(), Qt::Key_Shift); + QCOMPARE(upKey.at(0).toInt(), Qt::Key_Shift); + + simulateKey(&view, Qt::Key_A); + QCOMPARE(downSpy.count(), 0); + QCOMPARE(upSpy.count(), 0); + + simulateKey(&view, Qt::Key_Right); + QCOMPARE(downSpy.count(), 0); + QCOMPARE(upSpy.count(), 1); + upKey = upSpy.takeFirst(); + QCOMPARE(upKey.at(0).toInt(), Qt::Key_Right); +} + QTEST_MAIN(tst_qquicktextedit) #include "tst_qquicktextedit.moc" diff --git a/tests/auto/quick/qquicktextinput/BLACKLIST b/tests/auto/quick/qquicktextinput/BLACKLIST index 7f3128d7fcb..55ee6aa0436 100644 --- a/tests/auto/quick/qquicktextinput/BLACKLIST +++ b/tests/auto/quick/qquicktextinput/BLACKLIST @@ -9,3 +9,23 @@ macos ci # QTQAINFRA-4127 [passwordCharacter] ci b2qt 32bit + +# QTBUG-95940 +[canPaste] +opensuse-leap + +# QTBUG-95940 +[canPasteEmpty] +opensuse-leap + +# QTBUG-95940 +[copyAndPaste] +opensuse-leap + +# QTBUG-95940 +[copyAndPasteKeySequence] +opensuse-leap + +# QTBUG-103256 +[copyAndPasteKeySequence] +android diff --git a/tests/auto/quick/qquicktextinput/CMakeLists.txt b/tests/auto/quick/qquicktextinput/CMakeLists.txt index 6e8d855a58a..8f49477a302 100644 --- a/tests/auto/quick/qquicktextinput/CMakeLists.txt +++ b/tests/auto/quick/qquicktextinput/CMakeLists.txt @@ -12,17 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquicktextinput SOURCES - ../../shared/testhttpserver.cpp ../../shared/testhttpserver.h - ../../shared/util.cpp ../../shared/util.h tst_qquicktextinput.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquicktextinput/data/cursorTest.qml b/tests/auto/quick/qquicktextinput/data/cursorTest.qml index 363d37174b3..44e81f95222 100644 --- a/tests/auto/quick/qquicktextinput/data/cursorTest.qml +++ b/tests/auto/quick/qquicktextinput/data/cursorTest.qml @@ -2,7 +2,7 @@ import QtQuick 2.0 Rectangle { id:rect; width: 300; height: 300; color: "white" property string contextualProperty: "Hello" - TextInput { text: "Hello world!"; id: textInputObject; objectName: "textInputObject" + TextInput { text: "Hello my wonderful world!"; id: textInputObject; objectName: "textInputObject" width: 300; height: 300 resources: [ Component { id:cursor; Item { id:cursorInstance; objectName: "cursorInstance"; property string localProperty: contextualProperty } } ] cursorDelegate: cursor diff --git a/tests/auto/quick/qquicktextinput/data/cursorTestExternal.qml b/tests/auto/quick/qquicktextinput/data/cursorTestExternal.qml index 31ee01db996..1e2c91e9cc0 100644 --- a/tests/auto/quick/qquicktextinput/data/cursorTestExternal.qml +++ b/tests/auto/quick/qquicktextinput/data/cursorTestExternal.qml @@ -3,7 +3,7 @@ import QtQuick 2.0 Rectangle { width: 300; height: 300; color: "white" property string contextualProperty: "Hello" TextInput { - text: "Hello world!" + text: "Hello my wonderful world!" id: textInputObject; objectName: "textInputObject" width: 300; height: 300 diff --git a/tests/auto/quick/qquicktextinput/data/cursorTestInline.qml b/tests/auto/quick/qquicktextinput/data/cursorTestInline.qml index b699ed27521..b7ad69962e4 100644 --- a/tests/auto/quick/qquicktextinput/data/cursorTestInline.qml +++ b/tests/auto/quick/qquicktextinput/data/cursorTestInline.qml @@ -3,7 +3,7 @@ import QtQuick 2.0 Rectangle { width: 300; height: 300; color: "white" property string contextualProperty: "Hello" TextInput { - text: "Hello world!" + text: "Hello my wonderful world!" id: textInputObject objectName: "textInputObject" width: 300; height: 300 diff --git a/tests/auto/quick/qquicktextinput/data/focusReason.qml b/tests/auto/quick/qquicktextinput/data/focusReason.qml new file mode 100644 index 00000000000..7ac913d3637 --- /dev/null +++ b/tests/auto/quick/qquicktextinput/data/focusReason.qml @@ -0,0 +1,39 @@ +import QtQuick 2.2 + +Rectangle { + width: 400 + height: 400 + + Column { + spacing: 5 + TextInput { + id: first + objectName: "first" + width: 100 + Rectangle { anchors.fill: parent; color: parent.activeFocus ? "red" : "blue"; opacity: 0.3 } + KeyNavigation.backtab: third + KeyNavigation.tab: second + KeyNavigation.down: second + } + TextInput { + id: second + objectName: "second" + width: 100 + Rectangle { anchors.fill: parent; color: parent.activeFocus ? "red" : "blue"; opacity: 0.3 } + KeyNavigation.up: first + KeyNavigation.backtab: first + KeyNavigation.tab: third + } + TextInput { + objectName: "third" + id: third + width: 100 + Rectangle { anchors.fill: parent; color: parent.activeFocus ? "red" : "blue"; opacity: 0.3 } + KeyNavigation.backtab: second + KeyNavigation.tab: first + } + Component.onCompleted: { + first.focus = true + } + } +} diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index eada215781a..a87adf91309 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -27,8 +27,8 @@ ****************************************************************************/ #include <qtest.h> #include <QtTest/QSignalSpy> -#include "../../shared/util.h" -#include "../../shared/testhttpserver.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/testhttpserver_p.h> #include <private/qinputmethod_p.h> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlexpression.h> @@ -51,8 +51,8 @@ #endif #include "qplatformdefs.h" -#include "../../shared/platformquirks.h" -#include "../../shared/platforminputcontext.h" +#include <QtQuickTestUtils/private/platformquirks_p.h> +#include <QtQuickTestUtils/private/platforminputcontext_p.h> Q_DECLARE_METATYPE(QQuickTextInput::SelectionMode) Q_DECLARE_METATYPE(QQuickTextInput::EchoMode) @@ -239,6 +239,8 @@ private slots: void QTBUG_77814_InsertRemoveNoSelection(); void checkCursorDelegateWhenPaddingChanged(); + + void focusReason(); private: void simulateKeys(QWindow *window, const QList<Key> &keys); #if QT_CONFIG(shortcut) @@ -300,6 +302,7 @@ void tst_qquicktextinput::cleanup() } tst_qquicktextinput::tst_qquicktextinput() + : QQmlDataTest(QT_QMLTEST_DATADIR) { standard << "the quick brown fox jumped over the lazy dog" << "It's supercalifragisiticexpialidocious!" @@ -2880,7 +2883,7 @@ void tst_qquicktextinput::cursorDelegate() // Test delegate gets moved on mouse press. textInputObject->setSelectByMouse(true); textInputObject->setCursorPosition(0); - const QPoint point1 = textInputObject->positionToRectangle(5).center().toPoint(); + const QPoint point1 = textInputObject->positionToRectangle(10).center().toPoint(); QTest::qWait(400); //ensure this isn't treated as a double-click QTest::mouseClick(&view, Qt::LeftButton, Qt::NoModifier, point1); QTest::qWait(50); @@ -2890,7 +2893,7 @@ void tst_qquicktextinput::cursorDelegate() // Test delegate gets moved on mouse drag textInputObject->setCursorPosition(0); - const QPoint point2 = textInputObject->positionToRectangle(10).center().toPoint(); + const QPoint point2 = textInputObject->positionToRectangle(15).center().toPoint(); QTest::qWait(400); //ensure this isn't treated as a double-click QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, point1); QMouseEvent mv(QEvent::MouseMove, point2, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); @@ -2903,7 +2906,7 @@ void tst_qquicktextinput::cursorDelegate() textInputObject->setReadOnly(true); textInputObject->setCursorPosition(0); QTest::qWait(400); //ensure this isn't treated as a double-click - QTest::mouseClick(&view, Qt::LeftButton, Qt::NoModifier, textInputObject->positionToRectangle(5).center().toPoint()); + QTest::mouseClick(&view, Qt::LeftButton, Qt::NoModifier, textInputObject->positionToRectangle(10).center().toPoint()); QTest::qWait(50); QTRY_VERIFY(textInputObject->cursorPosition() != 0); QCOMPARE(textInputObject->cursorRectangle().x(), delegateObject->x()); @@ -2911,7 +2914,7 @@ void tst_qquicktextinput::cursorDelegate() textInputObject->setCursorPosition(0); QTest::qWait(400); //ensure this isn't treated as a double-click - QTest::mouseClick(&view, Qt::LeftButton, Qt::NoModifier, textInputObject->positionToRectangle(5).center().toPoint()); + QTest::mouseClick(&view, Qt::LeftButton, Qt::NoModifier, textInputObject->positionToRectangle(10).center().toPoint()); QTest::qWait(50); QTRY_VERIFY(textInputObject->cursorPosition() != 0); QCOMPARE(textInputObject->cursorRectangle().x(), delegateObject->x()); @@ -3753,8 +3756,6 @@ void tst_qquicktextinput::focusOutNotClearSelection() input.setFocus(false, Qt::PopupFocusReason); QGuiApplication::processEvents(); QTRY_COMPARE(input.selectedText(), QLatin1String("llo")); - // QTBUG-36332 and 36292: a popup window does not take focus - QTRY_COMPARE(input.hasActiveFocus(), true); input.setFocus(true); QTRY_COMPARE(input.hasActiveFocus(), true); @@ -5891,6 +5892,7 @@ void tst_qquicktextinput::clear() textInput->clear(); QVERIFY(textInput->text().isEmpty()); + QVERIFY2(textInput->preeditText().isEmpty(), "Pre-edit text must be empty after clear"); QCOMPARE(spy.count(), 3); @@ -5899,6 +5901,7 @@ void tst_qquicktextinput::clear() QVERIFY(!textInput->canUndo()); QCOMPARE(spy.count(), 4); QCOMPARE(textInput->text(), QString("I am Legend")); + QVERIFY2(textInput->preeditText().isEmpty(), "Pre-edit text must be empty after undo"); } void tst_qquicktextinput::backspaceSurrogatePairs() @@ -7053,6 +7056,84 @@ void tst_qquicktextinput::checkCursorDelegateWhenPaddingChanged() QCOMPARE(cursorDelegate->y(), textInput->topPadding()); } +/*! + Verifies that TextInput items get focus in/out events with the + correct focus reason set. + + Up and Down keys translates to Backtab and Tab focus reasons. + + See QTBUG-75862. +*/ +void tst_qquicktextinput::focusReason() +{ + QQuickView view; + view.setSource(testFileUrl("focusReason.qml")); + + QQuickTextInput *first = view.rootObject()->findChild<QQuickTextInput *>("first"); + QQuickTextInput *second = view.rootObject()->findChild<QQuickTextInput *>("second"); + QQuickTextInput *third = view.rootObject()->findChild<QQuickTextInput *>("third"); + QVERIFY(first && second && third); + + class FocusEventFilter : public QObject + { + public: + using QObject::QObject; + + QHash<QObject*, Qt::FocusReason> lastFocusReason; + protected: + bool eventFilter(QObject *o, QEvent *e) + { + if (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut) { + QFocusEvent *fe = static_cast<QFocusEvent*>(e); + lastFocusReason[o] = fe->reason(); + } + return QObject::eventFilter(o, e); + } + } eventFilter; + first->installEventFilter(&eventFilter); + second->installEventFilter(&eventFilter); + third->installEventFilter(&eventFilter); + + view.show(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QCOMPARE(qApp->focusObject(), first); + // on some platforms we don't get ActiveWindowFocusReason; tolerate this, + // it's not what we are testing in this test + if (eventFilter.lastFocusReason[first] != Qt::ActiveWindowFocusReason) { + QEXPECT_FAIL("", qPrintable(QString("No window activation event on the %1 platform") + .arg(QGuiApplication::platformName())), + Continue); + } + QCOMPARE(eventFilter.lastFocusReason[first], Qt::ActiveWindowFocusReason); + + QTest::mouseClick(&view, Qt::LeftButton, {}, + (second->boundingRect().center() + second->position()).toPoint()); + QTRY_COMPARE(qApp->focusObject(), second); + QCOMPARE(eventFilter.lastFocusReason[first], Qt::MouseFocusReason); + QCOMPARE(eventFilter.lastFocusReason[second], Qt::MouseFocusReason); + + QTest::keyClick(&view, Qt::Key_Tab); + QCOMPARE(qApp->focusObject(), third); + QCOMPARE(eventFilter.lastFocusReason[second], Qt::TabFocusReason); + QCOMPARE(eventFilter.lastFocusReason[third], Qt::TabFocusReason); + + QTest::keyClick(&view, Qt::Key_Backtab); + QCOMPARE(qApp->focusObject(), second); + QCOMPARE(eventFilter.lastFocusReason[third], Qt::BacktabFocusReason); + QCOMPARE(eventFilter.lastFocusReason[second], Qt::BacktabFocusReason); + + QTest::keyClick(&view, Qt::Key_Up); + QCOMPARE(qApp->focusObject(), first); + QCOMPARE(eventFilter.lastFocusReason[second], Qt::BacktabFocusReason); + QCOMPARE(eventFilter.lastFocusReason[first], Qt::BacktabFocusReason); + + QTest::keyClick(&view, Qt::Key_Down); + QCOMPARE(qApp->focusObject(), second); + QCOMPARE(eventFilter.lastFocusReason[second], Qt::TabFocusReason); + QCOMPARE(eventFilter.lastFocusReason[first], Qt::TabFocusReason); +} + QTEST_MAIN(tst_qquicktextinput) #include "tst_qquicktextinput.moc" diff --git a/tests/auto/quick/qquickview/CMakeLists.txt b/tests/auto/quick/qquickview/CMakeLists.txt index 16babb106a7..5f83f564e12 100644 --- a/tests/auto/quick/qquickview/CMakeLists.txt +++ b/tests/auto/quick/qquickview/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickview SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickview.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickview/tst_qquickview.cpp b/tests/auto/quick/qquickview/tst_qquickview.cpp index 7e47e0ca593..068acc77332 100644 --- a/tests/auto/quick/qquickview/tst_qquickview.cpp +++ b/tests/auto/quick/qquickview/tst_qquickview.cpp @@ -31,12 +31,12 @@ #include <QtQml/qqmlcontext.h> #include <QtQuick/qquickview.h> #include <QtQuick/qquickitem.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtGui/QWindow> #include <QtCore/QDebug> #include <QtQml/qqmlengine.h> -#include "../shared/geometrytestutil.h" +#include <QtQuickTestUtils/private/geometrytestutils_p.h> class tst_QQuickView : public QQmlDataTest { @@ -54,6 +54,7 @@ private slots: tst_QQuickView::tst_QQuickView() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } diff --git a/tests/auto/quick/qquickview_extra/CMakeLists.txt b/tests/auto/quick/qquickview_extra/CMakeLists.txt index 4fa75da811c..29b43b6c2bb 100644 --- a/tests/auto/quick/qquickview_extra/CMakeLists.txt +++ b/tests/auto/quick/qquickview_extra/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickview_extra SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickview_extra.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickview_extra/tst_qquickview_extra.cpp b/tests/auto/quick/qquickview_extra/tst_qquickview_extra.cpp index f697a438bd5..1ad248d899d 100644 --- a/tests/auto/quick/qquickview_extra/tst_qquickview_extra.cpp +++ b/tests/auto/quick/qquickview_extra/tst_qquickview_extra.cpp @@ -30,7 +30,7 @@ #include <QtQuick/qquickview.h> #include <QtQuick/qquickitem.h> #include <QtQml/qqmlengine.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtCore/QDebug> #include <QtCore/QTimer> @@ -45,7 +45,7 @@ private slots: void qtbug_87228(); }; -tst_QQuickViewExtra::tst_QQuickViewExtra() { } +tst_QQuickViewExtra::tst_QQuickViewExtra() : QQmlDataTest(QT_QMLTEST_DATADIR) { } void tst_QQuickViewExtra::qtbug_87228() { diff --git a/tests/auto/quick/qquickvisualdatamodel/CMakeLists.txt b/tests/auto/quick/qquickvisualdatamodel/CMakeLists.txt index 8222fd001f4..237837b5f89 100644 --- a/tests/auto/quick/qquickvisualdatamodel/CMakeLists.txt +++ b/tests/auto/quick/qquickvisualdatamodel/CMakeLists.txt @@ -12,15 +12,7 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickvisualdatamodel SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickvisualdatamodel.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -28,6 +20,7 @@ qt_internal_add_test(tst_qquickvisualdatamodel Qt::QmlModelsPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickvisualdatamodel/data/setDelegateNoDoubleChange.qml b/tests/auto/quick/qquickvisualdatamodel/data/setDelegateNoDoubleChange.qml new file mode 100644 index 00000000000..b4739d036ed --- /dev/null +++ b/tests/auto/quick/qquickvisualdatamodel/data/setDelegateNoDoubleChange.qml @@ -0,0 +1,43 @@ +import QtQuick + +Item { + width: 200 + height: 200 + id: root + property int creationCount: 0 + property bool testStarted: false + + ListModel { + id: mymodel + ListElement {message: "This is my alarm"} + } + + Component { + id: aDelegate + Rectangle { + color: "blue" + width: 100 + height: 100 + } + } + + Component { + id: bDelegate + Rectangle { + color: "red" + width: 100 + height: 100 + Text {text: model.message } + Component.onCompleted: root.creationCount++ + } + } + + + ListView { + width: 200 + height: 200 + id: myListView + model: mymodel + delegate: testStarted ? bDelegate : aDelegate + } +} diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp index 00377470435..c47d566d51c 100644 --- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp +++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp @@ -25,9 +25,9 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "../../shared/util.h" -#include "../shared/visualtestutil.h" -#include "../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> #include <qtest.h> #include <QtCore/qregularexpression.h> @@ -47,8 +47,8 @@ #include <math.h> #include <QtGui/qstandarditemmodel.h> -using namespace QQuickVisualTestUtil; -using namespace QQuickViewTestUtil; +using namespace QQuickVisualTestUtils; +using namespace QQuickViewTestUtils; template <typename T, int N> int lengthOf(const T (&)[N]) { return N; } @@ -434,6 +434,7 @@ private slots: void invalidContext(); void externalManagedModel(); void delegateModelChangeDelegate(); + void noDoubleDelegateUpdate(); void checkFilterGroupForDelegate(); void readFromProxyObject(); @@ -502,6 +503,7 @@ void tst_qquickvisualdatamodel::cleanupTestCase() } tst_qquickvisualdatamodel::tst_qquickvisualdatamodel() + : QQmlDataTest(QT_QMLTEST_DATADIR) { } @@ -4349,6 +4351,20 @@ void tst_qquickvisualdatamodel::delegateModelChangeDelegate() QCOMPARE(visualModel->count(), 3); } +void tst_qquickvisualdatamodel::noDoubleDelegateUpdate() +{ + // changing a delegate only refreshes its instances once + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("setDelegateNoDoubleChange.qml")); + + QScopedPointer<QObject> root(component.create()); + QVERIFY(root); + + bool ok = root->setProperty("testStarted", true); + QVERIFY(ok); + QCOMPARE(root->property("creationCount").toInt(), 1); +} + void tst_qquickvisualdatamodel::checkFilterGroupForDelegate() { QQuickView view; diff --git a/tests/auto/quick/qquickwindow/BLACKLIST b/tests/auto/quick/qquickwindow/BLACKLIST index b4b7d2d761e..6c3888daa1d 100644 --- a/tests/auto/quick/qquickwindow/BLACKLIST +++ b/tests/auto/quick/qquickwindow/BLACKLIST @@ -1,3 +1,15 @@ [openglContextCreatedSignal] opensuse-42.3 opensuse-leap + +# QTBUG-103078 +[defaultState] +android +[grab] +android +[requestActivate] +android +[contentItemSize] +android +[attachedProperty] +android diff --git a/tests/auto/quick/qquickwindow/CMakeLists.txt b/tests/auto/quick/qquickwindow/CMakeLists.txt index 4b353cb2770..0b934101e95 100644 --- a/tests/auto/quick/qquickwindow/CMakeLists.txt +++ b/tests/auto/quick/qquickwindow/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickwindow SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_qquickwindow.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/qquickwindow/data/conflictingVisibleFalse.qml b/tests/auto/quick/qquickwindow/data/conflictingVisibleFalse.qml new file mode 100644 index 00000000000..98f374a7416 --- /dev/null +++ b/tests/auto/quick/qquickwindow/data/conflictingVisibleFalse.qml @@ -0,0 +1,6 @@ +import QtQuick + +Window { + visibility: Window.Windowed + visible: false +} diff --git a/tests/auto/quick/qquickwindow/data/conflictingVisibleTrue.qml b/tests/auto/quick/qquickwindow/data/conflictingVisibleTrue.qml new file mode 100644 index 00000000000..52d9b2fc346 --- /dev/null +++ b/tests/auto/quick/qquickwindow/data/conflictingVisibleTrue.qml @@ -0,0 +1,6 @@ +import QtQuick + +Window { + visibility: Window.Hidden + visible: true +} diff --git a/tests/auto/quick/qquickwindow/data/earlyGrab.qml b/tests/auto/quick/qquickwindow/data/earlyGrab.qml new file mode 100644 index 00000000000..74427c94927 --- /dev/null +++ b/tests/auto/quick/qquickwindow/data/earlyGrab.qml @@ -0,0 +1,25 @@ +import QtQuick +import Test + +Window { + id: window + width: 400 + height: 400 + color: "red" + + // Important for the test to set visible early on, not wait until + // show() from C++. What is really verified here is that the + // content grabbing takes the real window state into account + // (visible vs. exposed). + visible: true + + Grabber { + id: grabber + objectName: "grabber" + } + + Item { + anchors.fill: parent + Component.onCompleted: grabber.grab(window) + } +} diff --git a/tests/auto/quick/qquickwindow/data/maximized.qml b/tests/auto/quick/qquickwindow/data/maximized.qml new file mode 100644 index 00000000000..4d7054645b1 --- /dev/null +++ b/tests/auto/quick/qquickwindow/data/maximized.qml @@ -0,0 +1,5 @@ +import QtQuick + +Window { + visibility: Window.Maximized +} diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index 1a04d317ce9..992709b8657 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -38,9 +38,9 @@ #include <QtQuick/private/qquickrectangle_p.h> #include <QtQuick/private/qquickloader_p.h> #include <QtQuick/private/qquickmousearea_p.h> -#include "../../shared/util.h" -#include "../shared/visualtestutil.h" -#include "../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> #include <QSignalSpy> #include <private/qquickwindow_p.h> #include <private/qguiapplication_p.h> @@ -50,6 +50,7 @@ #include <QQuickRenderControl> #include <QOperatingSystemVersion> #include <functional> +#include <QtGui/private/qeventpoint_p.h> #include <QtGui/private/qrhi_p.h> #if QT_CONFIG(opengl) #include <QOpenGLContext> @@ -327,30 +328,68 @@ Q_OBJECT } }; -class MouseRecordingWindow : public QQuickWindow +class PointerRecordingWindow : public QQuickWindow { public: - explicit MouseRecordingWindow(QWindow *parent = nullptr) : QQuickWindow(parent) { } + explicit PointerRecordingWindow(QWindow *parent = nullptr) : QQuickWindow(parent) { } protected: + bool event(QEvent *event) override { + if (event->isPointerEvent()) { + qCDebug(lcTests) << event; + m_events << PointerEvent { event->type(), static_cast<QPointerEvent *>(event)->pointingDevice() }; + } + return QQuickWindow::event(event); + } + void mousePressEvent(QMouseEvent *event) override { qCDebug(lcTests) << event; - m_mouseEvents << event->source(); + m_mouseEvents << PointerEvent { event->type(), event->pointingDevice() }; QQuickWindow::mousePressEvent(event); } void mouseMoveEvent(QMouseEvent *event) override { qCDebug(lcTests) << event; - m_mouseEvents << event->source(); + m_mouseEvents << PointerEvent { event->type(), event->pointingDevice() }; QQuickWindow::mouseMoveEvent(event); } void mouseReleaseEvent(QMouseEvent *event) override { qCDebug(lcTests) << event; - m_mouseEvents << event->source(); + m_mouseEvents << PointerEvent { event->type(), event->pointingDevice() }; QQuickWindow::mouseReleaseEvent(event); } + void touchEvent(QTouchEvent * event) override { + qCDebug(lcTests) << event; + m_touchEvents << PointerEvent { event->type(), event->pointingDevice() }; + QQuickWindow::touchEvent(event); + } + +#if QT_CONFIG(tabletevent) + void tabletEvent(QTabletEvent * event) override { + qCDebug(lcTests) << event; + m_tabletEvents << PointerEvent { event->type(), event->pointingDevice() }; + QQuickWindow::tabletEvent(event); + } +#endif + +#if QT_CONFIG(wheelevent) + void wheelEvent(QWheelEvent * event) override { + qCDebug(lcTests) << event; + m_tabletEvents << PointerEvent { event->type(), event->pointingDevice() }; + QQuickWindow::wheelEvent(event); + } +#endif + public: - QList<Qt::MouseEventSource> m_mouseEvents; + struct PointerEvent + { + QEvent::Type type; + const QPointingDevice *device; + }; + QList<PointerEvent> m_events; + QList<PointerEvent> m_mouseEvents; + QList<PointerEvent> m_touchEvents; + QList<PointerEvent> m_tabletEvents; }; class MouseRecordingItem : public QQuickItem @@ -402,9 +441,13 @@ class tst_qquickwindow : public QQmlDataTest Q_OBJECT public: tst_qquickwindow() - : touchDevice(QTest::createTouchDevice()) + : QQmlDataTest(QT_QMLTEST_DATADIR) + , touchDevice(QTest::createTouchDevice()) , touchDeviceWithVelocity(QTest::createTouchDevice(QInputDevice::DeviceType::TouchScreen, QInputDevice::Capability::Position | QPointingDevice::Capability::Velocity)) + , tabletStylusDevice(QPointingDevicePrivate::tabletDevice(QInputDevice::DeviceType::Stylus, + QPointingDevice::PointerType::Pen, + QPointingDeviceUniqueId::fromNumericId(1234567890))) { QQuickWindow::setDefaultAlphaBuffer(true); } @@ -446,6 +489,7 @@ private slots: void grab_data(); void grab(); + void earlyGrab(); void multipleWindows(); void animationsWhileHidden(); @@ -509,6 +553,9 @@ private slots: void testChildMouseEventFilter_data(); void cleanupGrabsOnRelease(); + void subclassWithPointerEventVirtualOverrides_data(); + void subclassWithPointerEventVirtualOverrides(); + #if QT_CONFIG(shortcut) void testShortCut(); #endif @@ -518,9 +565,13 @@ private slots: void rendererInterfaceWithRenderControl_data(); void rendererInterfaceWithRenderControl(); + void visibleVsVisibility_data(); + void visibleVsVisibility(); + private: - QPointingDevice *touchDevice; - QPointingDevice *touchDeviceWithVelocity; + QPointingDevice *touchDevice; // TODO make const after fixing QTBUG-107864 + const QPointingDevice *touchDeviceWithVelocity; + const QPointingDevice *tabletStylusDevice; }; #if QT_CONFIG(opengl) @@ -1248,7 +1299,7 @@ void tst_qquickwindow::synthMouseFromTouch() QFETCH(bool, acceptTouch); QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, synthMouse); - QScopedPointer<MouseRecordingWindow> window(new MouseRecordingWindow); + QScopedPointer<PointerRecordingWindow> window(new PointerRecordingWindow); QScopedPointer<MouseRecordingItem> item(new MouseRecordingItem(acceptTouch, nullptr)); item->setParentItem(window->contentItem()); window->resize(250, 250); @@ -1293,7 +1344,7 @@ void tst_qquickwindow::synthMouseDoubleClickFromTouch() QFETCH(bool, expectedSynthesizedDoubleClickEvent); QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true); - QScopedPointer<MouseRecordingWindow> window(new MouseRecordingWindow); + QScopedPointer<PointerRecordingWindow> window(new PointerRecordingWindow); QScopedPointer<MouseRecordingItem> item(new MouseRecordingItem(false, nullptr)); item->setParentItem(window->contentItem()); window->resize(250, 250); @@ -1526,8 +1577,7 @@ void tst_qquickwindow::grab() } QImage content = window.grabWindow(); - QCOMPARE(content.width(), int(window.width() * window.devicePixelRatio())); - QCOMPARE(content.height(), int(window.height() * window.devicePixelRatio())); + QCOMPARE(content.size(), window.size() * window.devicePixelRatio()); if (alpha) { QCOMPARE((uint) content.convertToFormat(QImage::Format_ARGB32_Premultiplied).pixel(0, 0), (uint) 0x00000000); @@ -1542,8 +1592,7 @@ void tst_qquickwindow::grab() // never was renderable before grabbing. window.hide(); QImage content = window.grabWindow(); - QCOMPARE(content.width(), int(window.width() * window.devicePixelRatio())); - QCOMPARE(content.height(), int(window.height() * window.devicePixelRatio())); + QCOMPARE(content.size(), window.size() * window.devicePixelRatio()); if (alpha) { QCOMPARE((uint) content.convertToFormat(QImage::Format_ARGB32_Premultiplied).pixel(0, 0), (uint) 0x00000000); } else { @@ -1554,8 +1603,7 @@ void tst_qquickwindow::grab() window.show(); QVERIFY(QTest::qWaitForWindowExposed(&window)); content = window.grabWindow(); - QCOMPARE(content.width(), int(window.width() * window.devicePixelRatio())); - QCOMPARE(content.height(), int(window.height() * window.devicePixelRatio())); + QCOMPARE(content.size(), window.size() * window.devicePixelRatio()); if (alpha) { QCOMPARE((uint) content.convertToFormat(QImage::Format_ARGB32_Premultiplied).pixel(0, 0), (uint) 0x00000000); } else { @@ -1564,6 +1612,40 @@ void tst_qquickwindow::grab() } } +class Grabber : public QObject +{ + Q_OBJECT +public: + Q_INVOKABLE void grab(QObject *obj) { + QQuickWindow *window = qobject_cast<QQuickWindow *>(obj); + images.append(window->grabWindow()); + } + QVector<QImage> images; +}; + +void tst_qquickwindow::earlyGrab() +{ + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms"); + + qmlRegisterType<Grabber>("Test", 1, 0, "Grabber"); + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("earlyGrab.qml")); + QScopedPointer<QQuickWindow> window(qobject_cast<QQuickWindow *>(component.create())); + QVERIFY(!window.isNull()); + window->setTitle(QTest::currentTestFunction()); + + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + Grabber *grabber = qobject_cast<Grabber *>(window->findChild<QObject *>("grabber")); + QVERIFY(grabber); + QCOMPARE(grabber->images.count(), 1); + QVERIFY(!grabber->images[0].isNull()); + QCOMPARE(grabber->images[0].convertToFormat(QImage::Format_RGBX8888).pixel(10, 20), QColor(Qt::red).rgb()); +} + void tst_qquickwindow::multipleWindows() { QList<QQuickWindow *> windows; @@ -1666,7 +1748,7 @@ void tst_qquickwindow::headless() // Verify that the visual output is the same QImage newContent = window->grabWindow(); QString errorMessage; - QVERIFY2(QQuickVisualTestUtil::compareImages(newContent, originalContent, &errorMessage), + QVERIFY2(QQuickVisualTestUtils::compareImages(newContent, originalContent, &errorMessage), qPrintable(errorMessage)); } @@ -1701,7 +1783,7 @@ void tst_qquickwindow::destroyShowWithoutHide() QImage newContent = window->grabWindow(); QString errorMessage; - QVERIFY2(QQuickVisualTestUtil::compareImages(newContent, originalContent, &errorMessage), + QVERIFY2(QQuickVisualTestUtils::compareImages(newContent, originalContent, &errorMessage), qPrintable(errorMessage)); } @@ -2088,6 +2170,10 @@ void tst_qquickwindow::testExpose() void tst_qquickwindow::requestActivate() { +#ifdef Q_OS_ANDROID + QSKIP("tst_qquickwindow::requestActivate crashes on Android, see QTBUG-103078."); +#endif + QQmlEngine engine; QQmlComponent component(&engine); component.loadUrl(testFileUrl("active.qml")); @@ -2114,7 +2200,7 @@ void tst_qquickwindow::requestActivate() QTRY_COMPARE(QGuiApplication::focusWindow(), window1.data()); QVERIFY(window1->isActive()); - QQuickItem *item = QQuickVisualTestUtil::findItem<QQuickItem>(window1->contentItem(), "item1"); + QQuickItem *item = QQuickVisualTestUtils::findItem<QQuickItem>(window1->contentItem(), "item1"); QVERIFY(item); //copied from src/qmltest/quicktestevent.cpp @@ -2123,18 +2209,14 @@ void tst_qquickwindow::requestActivate() { QMouseEvent me(QEvent::MouseButtonPress, pos, window1->mapToGlobal(pos), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QSpontaneKeyEvent::setSpontaneous(&me); - if (!qApp->notify(window1.data(), &me)) { - QString warning = QString::fromLatin1("Mouse event MousePress not accepted by receiving window"); - QWARN(warning.toLatin1().data()); - } + if (!qApp->notify(window1.data(), &me)) + qWarning("Mouse event MousePress not accepted by receiving window"); } { QMouseEvent me = QMouseEvent(QEvent::MouseButtonPress, pos, window1->mapToGlobal(pos), Qt::LeftButton, {}, Qt::NoModifier); QSpontaneKeyEvent::setSpontaneous(&me); - if (!qApp->notify(window1.data(), &me)) { - QString warning = QString::fromLatin1("Mouse event MouseRelease not accepted by receiving window"); - QWARN(warning.toLatin1().data()); - } + if (!qApp->notify(window1.data(), &me)) + qWarning("Mouse event MouseRelease not accepted by receiving window"); } QTRY_COMPARE(QGuiApplication::focusWindow(), windows.at(0)); @@ -2143,6 +2225,10 @@ void tst_qquickwindow::requestActivate() void tst_qquickwindow::testWindowVisibilityOrder() { +#ifdef Q_OS_ANDROID + QSKIP("tst_qquickwindow::testWindowVisibilityOrder crashes on Android, see QTBUG-103078."); +#endif + QQmlEngine engine; QQmlComponent component(&engine); component.loadUrl(testFileUrl("windoworder.qml")); @@ -2260,6 +2346,10 @@ void tst_qquickwindow::unloadSubWindow() // QTBUG-52573 void tst_qquickwindow::changeVisibilityInCompleted() { +#ifdef Q_OS_ANDROID + QSKIP("tst_qquickwindow::changeVisibilityInCompleted crashes on Android, see QTBUG-103078."); +#endif + QQmlEngine engine; QQmlComponent component(&engine); component.loadUrl(testFileUrl("changeVisibilityInCompleted.qml")); @@ -3549,6 +3639,48 @@ void tst_qquickwindow::cleanupGrabsOnRelease() QCOMPARE(parent->mouseUngrabEventCount, 1); } +void tst_qquickwindow::subclassWithPointerEventVirtualOverrides_data() +{ + QTest::addColumn<const QPointingDevice *>("device"); + + QTest::newRow("mouse click") << QPointingDevice::primaryPointingDevice(); + QTest::newRow("touch tap") << static_cast<const QPointingDevice*>(touchDevice); // TODO QTBUG-107864 + QTest::newRow("stylus tap") << tabletStylusDevice; +} + +void tst_qquickwindow::subclassWithPointerEventVirtualOverrides() // QTBUG-97859 +{ + QFETCH(const QPointingDevice *, device); + + PointerRecordingWindow window; + window.resize(250, 250); + window.setPosition(100, 100); + window.setTitle(QTest::currentTestFunction()); + window.show(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + const QPoint pos(120, 120); + + QQuickTest::pointerPress(device, &window, 0, pos); + QQuickTest::pointerRelease(device, &window, 0, pos); + + switch (device->type()) { + case QPointingDevice::DeviceType::Mouse: + QTRY_COMPARE(window.m_mouseEvents.size(), 3); // separate move before press + QCOMPARE(window.m_events.size(), 3); + break; + case QPointingDevice::DeviceType::TouchScreen: + QTRY_COMPARE(window.m_touchEvents.size(), 2); + QCOMPARE(window.m_events.size(), 2); + break; + case QPointingDevice::DeviceType::Stylus: + QTRY_COMPARE(window.m_tabletEvents.size(), 2); + QVERIFY(window.m_events.size() >= window.m_tabletEvents.size()); // tablet + synth-mouse events + break; + default: + break; + } +} + #if QT_CONFIG(shortcut) void tst_qquickwindow::testShortCut() { @@ -3688,8 +3820,7 @@ void tst_qquickwindow::rendererInterfaceWithRenderControl_data() QTest::newRow("Vulkan") << QSGRendererInterface::VulkanRhi; #endif #ifdef Q_OS_WIN - if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7) - QTest::newRow("D3D11") << QSGRendererInterface::Direct3D11Rhi; + QTest::newRow("D3D11") << QSGRendererInterface::Direct3D11Rhi; #endif #if defined(Q_OS_MACOS) || defined(Q_OS_IOS) QTest::newRow("Metal") << QSGRendererInterface::MetalRhi; @@ -3890,6 +4021,42 @@ void tst_qquickwindow::rendererInterfaceWithRenderControl() QQuickWindow::setGraphicsApi(QSGRendererInterface::Unknown); } +void tst_qquickwindow::visibleVsVisibility_data() +{ + QTest::addColumn<QUrl>("qmlfile"); + QTest::addColumn<bool>("expectVisible"); + QTest::addColumn<bool>("expectConflictingPropertyWarning"); + + QTest::newRow("default invisible") << testFileUrl("window.qml") << false << false; + QTest::newRow("just visibility") << testFileUrl("maximized.qml") << true << false; + // In these conflicting cases, the 'visibility' property "wins" (see QQuickWindowQmlImpl::setWindowVisibility()) + QTest::newRow("conflicting invisible") << testFileUrl("conflictingVisibleFalse.qml") << true << true; + QTest::newRow("conflicting visible") << testFileUrl("conflictingVisibleTrue.qml") << false << true; +} + +void tst_qquickwindow::visibleVsVisibility() +{ + QFETCH(QUrl, qmlfile); + QFETCH(bool, expectVisible); + QFETCH(bool, expectConflictingPropertyWarning); + + const QString warningMsg = qmlfile.toString() + ": Conflicting properties 'visible' and 'visibility'"; + + if (expectConflictingPropertyWarning) + QTest::ignoreMessage(QtWarningMsg, warningMsg.toUtf8().data()); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(qmlfile); + QObject *created = component.create(); + QScopedPointer<QObject> cleanup(created); + QVERIFY(created); + + QQuickWindow *window = qobject_cast<QQuickWindow*>(created); + QVERIFY(window); + QCOMPARE(window->isVisible(), expectVisible); +} + QTEST_MAIN(tst_qquickwindow) #include "tst_qquickwindow.moc" diff --git a/tests/auto/quick/rendernode/CMakeLists.txt b/tests/auto/quick/rendernode/CMakeLists.txt index 037ff858437..2c0ff2a5c27 100644 --- a/tests/auto/quick/rendernode/CMakeLists.txt +++ b/tests/auto/quick/rendernode/CMakeLists.txt @@ -12,16 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_rendernode SOURCES - ../../shared/util.cpp ../../shared/util.h tst_rendernode.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/rendernode/tst_rendernode.cpp b/tests/auto/quick/rendernode/tst_rendernode.cpp index 98d0970ca0c..1dd622a51d1 100644 --- a/tests/auto/quick/rendernode/tst_rendernode.cpp +++ b/tests/auto/quick/rendernode/tst_rendernode.cpp @@ -35,7 +35,7 @@ #include <QtGui/qscreen.h> #include <private/qsgrendernode_p.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class tst_rendernode: public QQmlDataTest { @@ -182,6 +182,7 @@ class MessUpItem : public QQuickItem }; tst_rendernode::tst_rendernode() + : QQmlDataTest(QT_QMLTEST_DATADIR) { qmlRegisterType<ClearItem>("Test", 1, 0, "ClearItem"); qmlRegisterType<MessUpItem>("Test", 1, 0, "MessUpItem"); diff --git a/tests/auto/quick/scenegraph/BLACKLIST b/tests/auto/quick/scenegraph/BLACKLIST new file mode 100644 index 00000000000..80f39de9ab9 --- /dev/null +++ b/tests/auto/quick/scenegraph/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-102589 +[render] +android diff --git a/tests/auto/quick/scenegraph/CMakeLists.txt b/tests/auto/quick/scenegraph/CMakeLists.txt index 046629ba04f..05fd9dc9ecf 100644 --- a/tests/auto/quick/scenegraph/CMakeLists.txt +++ b/tests/auto/quick/scenegraph/CMakeLists.txt @@ -4,23 +4,23 @@ ## tst_scenegraph Test: ##################################################################### +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + qt_internal_add_test(tst_scenegraph SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_scenegraph.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate + TESTDATA ${test_data} ) #### Keys ignored in scope 1:.:.:scenegraph.pro:<TRUE>: diff --git a/tests/auto/quick/scenegraph/tst_scenegraph.cpp b/tests/auto/quick/scenegraph/tst_scenegraph.cpp index 9803412703b..96518dbcfa5 100644 --- a/tests/auto/quick/scenegraph/tst_scenegraph.cpp +++ b/tests/auto/quick/scenegraph/tst_scenegraph.cpp @@ -45,13 +45,13 @@ #include <private/qsgrenderloop_p.h> #include <private/qsgrhisupport_p.h> -#include "../../shared/util.h" -#include "../shared/visualtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> #include <QtGui/private/qguiapplication_p.h> #include <QtGui/qpa/qplatformintegration.h> -using namespace QQuickVisualTestUtil; +using namespace QQuickVisualTestUtils; class PerPixelRect : public QQuickItem { @@ -102,6 +102,9 @@ class tst_SceneGraph : public QQmlDataTest { Q_OBJECT +public: + tst_SceneGraph(); + private slots: void initTestCase() override; @@ -126,6 +129,11 @@ template <typename T> class ScopedList : public QList<T> { ~ScopedList() { qDeleteAll(*this); } }; +tst_SceneGraph::tst_SceneGraph() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_SceneGraph::initTestCase() { qmlRegisterType<PerPixelRect>("SceneGraphTest", 1, 0, "PerPixelRect"); diff --git a/tests/auto/quick/shared/geometrytestutil.cpp b/tests/auto/quick/shared/geometrytestutil.cpp deleted file mode 100644 index 07a755e9a5b..00000000000 --- a/tests/auto/quick/shared/geometrytestutil.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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 "geometrytestutil.h" - -#include <QQuickItem> - -QSizeChangeListener::QSizeChangeListener(QQuickItem *item) : - item(item) -{ - connect(item, &QQuickItem::widthChanged, this, &QSizeChangeListener::onSizeChanged); - connect(item, &QQuickItem::heightChanged, this, &QSizeChangeListener::onSizeChanged); -} - -void QSizeChangeListener::onSizeChanged() -{ - append(QSize(item->width(), item->height())); -} diff --git a/tests/auto/quick/shared/geometrytestutil.h b/tests/auto/quick/shared/geometrytestutil.h deleted file mode 100644 index 2cf19ed7ff2..00000000000 --- a/tests/auto/quick/shared/geometrytestutil.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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 QQUICKGEOMETRYTESTUTIL_H -#define QQUICKGEOMETRYTESTUTIL_H - -#include <QObject> -#include <QVector> -#include <QSize> - -QT_FORWARD_DECLARE_CLASS(QQuickItem) - -class QSizeChangeListener : public QObject, public QVector<QSize> -{ - Q_OBJECT -public: - explicit QSizeChangeListener(QQuickItem *item); -private slots: - void onSizeChanged(); -private: - QQuickItem *item; -}; - -#endif // QQUICKGEOMETRYTESTUTIL_H diff --git a/tests/auto/quick/shared/viewtestutil.cpp b/tests/auto/quick/shared/viewtestutil.cpp deleted file mode 100644 index 5d9e6ba8dcf..00000000000 --- a/tests/auto/quick/shared/viewtestutil.cpp +++ /dev/null @@ -1,531 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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 "viewtestutil.h" - -#include <QtCore/QRandomGenerator> -#include <QtQuick/QQuickView> -#include <QtQuick/QQuickView> -#include <QtGui/QScreen> - -#include <QtTest/QTest> - -#include <QtQuick/private/qquickdeliveryagent_p_p.h> -#include <QtQuick/private/qquickitemview_p_p.h> -#include <QtQuick/private/qquickwindow_p.h> - -QT_BEGIN_NAMESPACE - -QQuickView *QQuickViewTestUtil::createView() -{ - QQuickView *window = new QQuickView(0); - const QSize size(240, 320); - window->resize(size); - QQuickViewTestUtil::centerOnScreen(window, size); - return window; -} - -void QQuickViewTestUtil::centerOnScreen(QQuickView *window, const QSize &size) -{ - const QRect screenGeometry = window->screen()->availableGeometry(); - const QPoint offset = QPoint(size.width() / 2, size.height() / 2); - window->setFramePosition(screenGeometry.center() - offset); -} - -void QQuickViewTestUtil::centerOnScreen(QQuickView *window) -{ - QQuickViewTestUtil::centerOnScreen(window, window->size()); -} - -void QQuickViewTestUtil::moveMouseAway(QQuickView *window) -{ -#if QT_CONFIG(cursor) // Get the cursor out of the way. - QCursor::setPos(window->geometry().topRight() + QPoint(100, 100)); -#else - Q_UNUSED(window); -#endif -} - -void QQuickViewTestUtil::moveAndRelease(QQuickView *window, const QPoint &position) -{ - QTest::mouseMove(window, position); - QTest::mouseRelease(window, Qt::LeftButton, {}, position); -} - -void QQuickViewTestUtil::moveAndPress(QQuickView *window, const QPoint &position) -{ - QTest::mouseMove(window, position); - QTest::mousePress(window, Qt::LeftButton, {}, position); -} - -void QQuickViewTestUtil::flick(QQuickView *window, const QPoint &from, const QPoint &to, int duration) -{ - const int pointCount = 5; - QPoint diff = to - from; - - // send press, five equally spaced moves, and release. - moveAndPress(window, from); - - for (int i = 0; i < pointCount; ++i) - QTest::mouseMove(window, from + (i+1)*diff/pointCount, duration / pointCount); - - moveAndRelease(window, to); - QTest::qWait(50); -} - -QList<int> QQuickViewTestUtil::adjustIndexesForAddDisplaced(const QList<int> &indexes, int index, int count) -{ - QList<int> result; - for (int i=0; i<indexes.count(); i++) { - int num = indexes[i]; - if (num >= index) { - num += count; - } - result << num; - } - return result; -} - -QList<int> QQuickViewTestUtil::adjustIndexesForMove(const QList<int> &indexes, int from, int to, int count) -{ - QList<int> result; - for (int i=0; i<indexes.count(); i++) { - int num = indexes[i]; - if (from < to) { - if (num >= from && num < from + count) - num += (to - from); // target - else if (num >= from && num < to + count) - num -= count; // displaced - } else if (from > to) { - if (num >= from && num < from + count) - num -= (from - to); // target - else if (num >= to && num < from + count) - num += count; // displaced - } - result << num; - } - return result; -} - -QList<int> QQuickViewTestUtil::adjustIndexesForRemoveDisplaced(const QList<int> &indexes, int index, int count) -{ - QList<int> result; - for (int i=0; i<indexes.count(); i++) { - int num = indexes[i]; - if (num >= index) - num -= count; - result << num; - } - return result; -} - -QQuickViewTestUtil::QaimModel::QaimModel(QObject *parent) - : QAbstractListModel(parent) -{ -} - -int QQuickViewTestUtil::QaimModel::rowCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent); - return list.count(); -} - -int QQuickViewTestUtil::QaimModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent); - return columns; -} - -QHash<int,QByteArray> QQuickViewTestUtil::QaimModel::roleNames() const -{ - QHash<int,QByteArray> roles = QAbstractListModel::roleNames(); - roles.insert(Name, "name"); - roles.insert(Number, "number"); - return roles; -} - -QVariant QQuickViewTestUtil::QaimModel::data(const QModelIndex &index, int role) const -{ - QVariant rv; - if (role == Name) - rv = list.at(index.row()).first; - else if (role == Number) - rv = list.at(index.row()).second; - - return rv; -} - -int QQuickViewTestUtil::QaimModel::count() const -{ - return rowCount() * columnCount(); -} - -QString QQuickViewTestUtil::QaimModel::name(int index) const -{ - return list.at(index).first; -} - -QString QQuickViewTestUtil::QaimModel::number(int index) const -{ - return list.at(index).second; -} - -void QQuickViewTestUtil::QaimModel::addItem(const QString &name, const QString &number) -{ - emit beginInsertRows(QModelIndex(), list.count(), list.count()); - list.append(QPair<QString,QString>(name, number)); - emit endInsertRows(); -} - -void QQuickViewTestUtil::QaimModel::addItems(const QList<QPair<QString, QString> > &items) -{ - emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1); - for (int i=0; i<items.count(); i++) - list.append(QPair<QString,QString>(items[i].first, items[i].second)); - emit endInsertRows(); -} - -void QQuickViewTestUtil::QaimModel::insertItem(int index, const QString &name, const QString &number) -{ - emit beginInsertRows(QModelIndex(), index, index); - list.insert(index, QPair<QString,QString>(name, number)); - emit endInsertRows(); -} - -void QQuickViewTestUtil::QaimModel::insertItems(int index, const QList<QPair<QString, QString> > &items) -{ - emit beginInsertRows(QModelIndex(), index, index+items.count()-1); - for (int i=0; i<items.count(); i++) - list.insert(index + i, QPair<QString,QString>(items[i].first, items[i].second)); - emit endInsertRows(); -} - -void QQuickViewTestUtil::QaimModel::removeItem(int index) -{ - emit beginRemoveRows(QModelIndex(), index, index); - list.removeAt(index); - emit endRemoveRows(); -} - -void QQuickViewTestUtil::QaimModel::removeItems(int index, int count) -{ - emit beginRemoveRows(QModelIndex(), index, index+count-1); - while (count--) - list.removeAt(index); - emit endRemoveRows(); -} - -void QQuickViewTestUtil::QaimModel::moveItem(int from, int to) -{ - emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); - list.move(from, to); - emit endMoveRows(); -} - -void QQuickViewTestUtil::QaimModel::moveItems(int from, int to, int count) -{ - emit beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to); - qquickmodelviewstestutil_move(from, to, count, &list); - emit endMoveRows(); -} - -void QQuickViewTestUtil::QaimModel::modifyItem(int idx, const QString &name, const QString &number) -{ - list[idx] = QPair<QString,QString>(name, number); - emit dataChanged(index(idx,0), index(idx,0)); -} - -void QQuickViewTestUtil::QaimModel::clear() -{ - int count = list.count(); - if (count > 0) { - beginRemoveRows(QModelIndex(), 0, count-1); - list.clear(); - endRemoveRows(); - } -} - -void QQuickViewTestUtil::QaimModel::reset() -{ - emit beginResetModel(); - emit endResetModel(); -} - -void QQuickViewTestUtil::QaimModel::resetItems(const QList<QPair<QString, QString> > &items) -{ - beginResetModel(); - list = items; - endResetModel(); -} - -class ScopedPrintable -{ - Q_DISABLE_COPY_MOVE(ScopedPrintable) - -public: - ScopedPrintable(const QString &string) : data(QTest::toString(string)) {} - ~ScopedPrintable() { delete[] data; } - - operator const char*() const { return data; } - -private: - const char *data; -}; - -void QQuickViewTestUtil::QaimModel::matchAgainst(const QList<QPair<QString, QString> > &other, const QString &error1, const QString &error2) { - for (int i=0; i<other.count(); i++) { - QVERIFY2(list.contains(other[i]), - ScopedPrintable(other[i].first + QLatin1Char(' ') + other[i].second + QLatin1Char(' ') + error1)); - } - for (int i=0; i<list.count(); i++) { - QVERIFY2(other.contains(list[i]), - ScopedPrintable(list[i].first + QLatin1Char(' ') + list[i].second + QLatin1Char(' ') + error2)); - } -} - - - -QQuickViewTestUtil::ListRange::ListRange() - : valid(false) -{ -} - -QQuickViewTestUtil::ListRange::ListRange(const ListRange &other) - : valid(other.valid) -{ - indexes = other.indexes; -} - -QQuickViewTestUtil::ListRange::ListRange(int start, int end) - : valid(true) -{ - for (int i=start; i<=end; i++) - indexes << i; -} - -QQuickViewTestUtil::ListRange::~ListRange() -{ -} - -QQuickViewTestUtil::ListRange QQuickViewTestUtil::ListRange::operator+(const ListRange &other) const -{ - if (other == *this) - return *this; - ListRange a(*this); - a.indexes.append(other.indexes); - return a; -} - -bool QQuickViewTestUtil::ListRange::operator==(const ListRange &other) const -{ - return QSet<int>(indexes.cbegin(), indexes.cend()) - == QSet<int>(other.indexes.cbegin(), other.indexes.cend()); -} - -bool QQuickViewTestUtil::ListRange::operator!=(const ListRange &other) const -{ - return !(*this == other); -} - -bool QQuickViewTestUtil::ListRange::isValid() const -{ - return valid; -} - -int QQuickViewTestUtil::ListRange::count() const -{ - return indexes.count(); -} - -QList<QPair<QString,QString> > QQuickViewTestUtil::ListRange::getModelDataValues(const QaimModel &model) -{ - QList<QPair<QString,QString> > data; - if (!valid) - return data; - for (int i=0; i<indexes.count(); i++) - data.append(qMakePair(model.name(indexes[i]), model.number(indexes[i]))); - return data; -} - -QQuickViewTestUtil::StressTestModel::StressTestModel() - : QAbstractListModel() - , m_rowCount(20) -{ - QTimer *t = new QTimer(this); - t->setInterval(500); - t->start(); - - connect(t, &QTimer::timeout, this, &StressTestModel::updateModel); -} - -int QQuickViewTestUtil::StressTestModel::rowCount(const QModelIndex &) const -{ - return m_rowCount; -} - -QVariant QQuickViewTestUtil::StressTestModel::data(const QModelIndex &, int) const -{ - return QVariant(); -} - -void QQuickViewTestUtil::StressTestModel::updateModel() -{ - if (m_rowCount > 10) { - for (int i = 0; i < 10; ++i) { - int rnum = QRandomGenerator::global()->bounded(m_rowCount); - beginRemoveRows(QModelIndex(), rnum, rnum); - m_rowCount--; - endRemoveRows(); - } - } - if (m_rowCount < 20) { - for (int i = 0; i < 10; ++i) { - int rnum = QRandomGenerator::global()->bounded(m_rowCount); - beginInsertRows(QModelIndex(), rnum, rnum); - m_rowCount++; - endInsertRows(); - } - } -} - -bool QQuickViewTestUtil::testVisibleItems(const QQuickItemViewPrivate *priv, bool *nonUnique, FxViewItem **failItem, int *expectedIdx) -{ - QHash<QQuickItem*, int> uniqueItems; - - int skip = 0; - for (int i = 0; i < priv->visibleItems.count(); ++i) { - FxViewItem *item = priv->visibleItems.at(i); - if (!item) { - *failItem = nullptr; - return false; - } -#if 0 - qDebug() << "\t" << item->index - << item->item - << item->position() - << (!item->item || QQuickItemPrivate::get(item->item)->culled ? "hidden" : "visible"); -#endif - if (item->index == -1) { - ++skip; - } else if (item->index != priv->visibleIndex + i - skip) { - *nonUnique = false; - *failItem = item; - *expectedIdx = priv->visibleIndex + i - skip; - return false; - } else if (uniqueItems.contains(item->item)) { - *nonUnique = true; - *failItem = item; - *expectedIdx = uniqueItems.find(item->item).value(); - return false; - } - - uniqueItems.insert(item->item, item->index); - } - - return true; -} - -namespace QQuickTouchUtils { - - /* QQuickWindow does event compression and only delivers events just - * before it is about to render the next frame. Since some tests - * rely on events being delivered immediately AND that no other - * event processing has occurred in the meanwhile, we flush the - * event manually and immediately. - */ - void flush(QQuickWindow *window) { - if (!window) - return; - QQuickDeliveryAgentPrivate *da = QQuickWindowPrivate::get(window)->deliveryAgentPrivate(); - if (!da || !da->delayedTouch) - return; - da->deliverDelayedTouchEvent(); - } - -} - -namespace QQuickTest { - - /*! \internal - Initialize \a view, set \a url, center in available geometry, move mouse away if desired. - If \a errorMessage is given, QQuickView::errors() will be concatenated into it; - otherwise, the QWARN messages are generally enough to debug the test. - - Returns \c false if the view fails to load the QML. That should be fatal in most tests, - so normally the return value should be checked with QVERIFY. - */ - bool initView(QQuickView &view, const QUrl &url, bool moveMouseOut, QByteArray *errorMessage) - { - view.setSource(url); - while (view.status() == QQuickView::Loading) - QTest::qWait(10); - if (view.status() != QQuickView::Ready) { - if (errorMessage) { - for (const QQmlError &e : view.errors()) - errorMessage->append(e.toString().toLocal8Bit() + '\n'); - } - return false; - } - const QRect screenGeometry = view.screen()->availableGeometry(); - const QSize size = view.size(); - const QPoint offset = QPoint(size.width() / 2, size.height() / 2); - view.setFramePosition(screenGeometry.center() - offset); - #if QT_CONFIG(cursor) // Get the cursor out of the way. - if (moveMouseOut) - QCursor::setPos(view.geometry().topRight() + QPoint(100, 100)); - #else - Q_UNUSED(moveMouseOut); - #endif - return true; - } - - /*! \internal - Initialize \a view, set \a url, center in available geometry, move mouse away, - show the \a view, wait for it to be exposed, and verify that its rootObject is not null. - - Returns \c false if anything fails, which should be fatal in most tests. - The usual way to call this function is - \code - QQuickView window; - QVERIFY(QQuickTest::showView(window, testFileUrl("myitems.qml"))); - \endcode - */ - bool showView(QQuickView &view, const QUrl &url) - { - if (!initView(view, url)) - return false; - view.show(); - if (!QTest::qWaitForWindowExposed(&view)) - return false; - if (!view.rootObject()) - return false; - return true; - } -} - -QT_END_NAMESPACE diff --git a/tests/auto/quick/shared/viewtestutil.h b/tests/auto/quick/shared/viewtestutil.h deleted file mode 100644 index 377296b095a..00000000000 --- a/tests/auto/quick/shared/viewtestutil.h +++ /dev/null @@ -1,203 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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 QQUICKVIEWTESTUTIL_H -#define QQUICKVIEWTESTUTIL_H - -#include <QtQuick/QQuickItem> -#include <QtQml/QQmlExpression> -#include <QtCore/QAbstractListModel> - -QT_FORWARD_DECLARE_CLASS(QQuickView) -QT_FORWARD_DECLARE_CLASS(QQuickItemViewPrivate) -QT_FORWARD_DECLARE_CLASS(FxViewItem) - -QT_BEGIN_NAMESPACE - -namespace QQuickViewTestUtil -{ - QQuickView *createView(); - - void flick(QQuickView *window, const QPoint &from, const QPoint &to, int duration); - void centerOnScreen(QQuickView *window, const QSize &size); - void centerOnScreen(QQuickView *window); - void moveMouseAway(QQuickView *window); - void moveAndPress(QQuickView *window, const QPoint &position); - void moveAndRelease(QQuickView *window, const QPoint &position); - - QList<int> adjustIndexesForAddDisplaced(const QList<int> &indexes, int index, int count); - QList<int> adjustIndexesForMove(const QList<int> &indexes, int from, int to, int count); - QList<int> adjustIndexesForRemoveDisplaced(const QList<int> &indexes, int index, int count); - - struct ListChange { - enum { Inserted, Removed, Moved, SetCurrent, SetContentY, Polish } type; - int index; - int count; - int to; // Move - qreal pos; // setContentY - - static ListChange insert(int index, int count = 1) { ListChange c = { Inserted, index, count, -1, 0.0 }; return c; } - static ListChange remove(int index, int count = 1) { ListChange c = { Removed, index, count, -1, 0.0 }; return c; } - static ListChange move(int index, int to, int count) { ListChange c = { Moved, index, count, to, 0.0 }; return c; } - static ListChange setCurrent(int index) { ListChange c = { SetCurrent, index, -1, -1, 0.0 }; return c; } - static ListChange setContentY(qreal pos) { ListChange c = { SetContentY, -1, -1, -1, pos }; return c; } - static ListChange polish() { ListChange c = { Polish, -1, -1, -1, 0.0 }; return c; } - }; - - class QaimModel : public QAbstractListModel - { - Q_OBJECT - public: - enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 }; - - QaimModel(QObject *parent=0); - - int rowCount(const QModelIndex &parent=QModelIndex()) const override; - int columnCount(const QModelIndex &parent=QModelIndex()) const override; - QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override; - QHash<int,QByteArray> roleNames() const override; - - int count() const; - QString name(int index) const; - QString number(int index) const; - - Q_INVOKABLE void addItem(const QString &name, const QString &number); - void addItems(const QList<QPair<QString, QString> > &items); - void insertItem(int index, const QString &name, const QString &number); - void insertItems(int index, const QList<QPair<QString, QString> > &items); - - Q_INVOKABLE void removeItem(int index); - void removeItems(int index, int count); - - void moveItem(int from, int to); - void moveItems(int from, int to, int count); - - void modifyItem(int idx, const QString &name, const QString &number); - - void clear(); - void reset(); - void resetItems(const QList<QPair<QString, QString> > &items); - - void matchAgainst(const QList<QPair<QString, QString> > &other, const QString &error1, const QString &error2); - - using QAbstractListModel::dataChanged; - - int columns = 1; - - private: - QList<QPair<QString,QString> > list; - }; - - class ListRange - { - public: - ListRange(); - ListRange(const ListRange &other); - ListRange(int start, int end); - - ~ListRange(); - - ListRange operator+(const ListRange &other) const; - bool operator==(const ListRange &other) const; - bool operator!=(const ListRange &other) const; - - bool isValid() const; - int count() const; - - QList<QPair<QString,QString> > getModelDataValues(const QaimModel &model); - - QList<int> indexes; - bool valid; - }; - - template<typename T> - static void qquickmodelviewstestutil_move(int from, int to, int n, T *items) - { - if (from > to) { - // Only move forwards - flip if backwards moving - int tfrom = from; - int tto = to; - from = tto; - to = tto+n; - n = tfrom-tto; - } - - T replaced; - int i=0; - typename T::ConstIterator it=items->begin(); it += from+n; - for (; i<to-from; ++i,++it) - replaced.append(*it); - i=0; - it=items->begin(); it += from; - for (; i<n; ++i,++it) - replaced.append(*it); - typename T::ConstIterator f=replaced.begin(); - typename T::Iterator t=items->begin(); t += from; - for (; f != replaced.end(); ++f, ++t) - *t = *f; - } - - class StressTestModel : public QAbstractListModel - { - Q_OBJECT - - public: - - StressTestModel(); - - int rowCount(const QModelIndex &) const override; - QVariant data(const QModelIndex &, int) const override; - - public Q_SLOTS: - void updateModel(); - - private: - int m_rowCount; - }; - - bool testVisibleItems(const QQuickItemViewPrivate *priv, bool *nonUnique, FxViewItem **failItem, int *expectedIdx); -} - -namespace QQuickTouchUtils { - void flush(QQuickWindow *window); -} - -namespace QQuickTest { - bool initView(QQuickView &v, const QUrl &url, bool moveMouseOut = true, QByteArray *errorMessage = nullptr); - bool showView(QQuickView &v, const QUrl &url); -} - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QQuickViewTestUtil::QaimModel*) -Q_DECLARE_METATYPE(QQuickViewTestUtil::ListChange) -Q_DECLARE_METATYPE(QList<QQuickViewTestUtil::ListChange>) -Q_DECLARE_METATYPE(QQuickViewTestUtil::ListRange) - - -#endif // QQUICKVIEWTESTUTIL_H diff --git a/tests/auto/quick/shared/visualtestutil.cpp b/tests/auto/quick/shared/visualtestutil.cpp deleted file mode 100644 index 06f73869020..00000000000 --- a/tests/auto/quick/shared/visualtestutil.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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 "visualtestutil.h" - -#include <QtQuick/QQuickItem> -#include <QtCore/QDebug> - -bool QQuickVisualTestUtil::delegateVisible(QQuickItem *item) -{ - return item->isVisible() && !QQuickItemPrivate::get(item)->culled; -} - -QQuickItem *QQuickVisualTestUtil::findVisibleChild(QQuickItem *parent, const QString &objectName) -{ - QQuickItem *item = 0; - QList<QQuickItem*> items = parent->findChildren<QQuickItem*>(objectName); - for (int i = 0; i < items.count(); ++i) { - if (items.at(i)->isVisible() && !QQuickItemPrivate::get(items.at(i))->culled) { - item = items.at(i); - break; - } - } - return item; -} - -void QQuickVisualTestUtil::dumpTree(QQuickItem *parent, int depth) -{ - static QString padding(" "); - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i)); - if (!item) - continue; - qDebug() << padding.left(depth*2) << item; - dumpTree(item, depth+1); - } -} - -// A custom compare function to avoid issues such as: -// When running on native Nvidia graphics cards on linux, the -// distance field glyph pixels have a measurable, but not visible -// pixel error. This was GT-216 with the ubuntu "nvidia-319" driver package. -// llvmpipe does not show the same issue. - -bool QQuickVisualTestUtil::compareImages(const QImage &ia, const QImage &ib, QString *errorMessage) -{ - if (ia.size() != ib.size()) { - QDebug(errorMessage) << "Images are of different size:" << ia.size() << ib.size() - << "DPR:" << ia.devicePixelRatio() << ib.devicePixelRatio(); - return false; - } - if (ia.format() != ib.format()) { - QDebug(errorMessage) << "Images are of different formats:" << ia.format() << ib.format(); - return false; - } - - int w = ia.width(); - int h = ia.height(); - const int tolerance = 5; - for (int y=0; y<h; ++y) { - const uint *as= (const uint *) ia.constScanLine(y); - const uint *bs= (const uint *) ib.constScanLine(y); - for (int x=0; x<w; ++x) { - uint a = as[x]; - uint b = bs[x]; - - // No tolerance for error in the alpha. - if ((a & 0xff000000) != (b & 0xff000000) - || qAbs(qRed(a) - qRed(b)) > tolerance - || qAbs(qRed(a) - qRed(b)) > tolerance - || qAbs(qRed(a) - qRed(b)) > tolerance) { - QDebug(errorMessage) << "Mismatch at:" << x << y << ':' - << Qt::hex << Qt::showbase << a << b; - return false; - } - } - } - return true; -} diff --git a/tests/auto/quick/shared/visualtestutil.h b/tests/auto/quick/shared/visualtestutil.h deleted file mode 100644 index c07cecfa475..00000000000 --- a/tests/auto/quick/shared/visualtestutil.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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 QQUICKVISUALTESTUTIL_H -#define QQUICKVISUALTESTUTIL_H - -#include <QtQuick/QQuickItem> -#include <QtQml/QQmlExpression> - -#include <QtQuick/private/qquickitem_p.h> - -namespace QQuickVisualTestUtil -{ - QQuickItem *findVisibleChild(QQuickItem *parent, const QString &objectName); - - void dumpTree(QQuickItem *parent, int depth = 0); - - bool delegateVisible(QQuickItem *item); - - /* - Find an item with the specified objectName. If index is supplied then the - item must also evaluate the {index} expression equal to index - */ - template<typename T> - T *findItem(QQuickItem *parent, const QString &objectName, int index = -1) - { - const QMetaObject &mo = T::staticMetaObject; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i)); - if (!item) - continue; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { - if (index != -1) { - QQmlExpression e(qmlContext(item), item, "index"); - if (e.evaluate().toInt() == index) - return static_cast<T*>(item); - } else { - return static_cast<T*>(item); - } - } - item = findItem<T>(item, objectName, index); - if (item) - return static_cast<T*>(item); - } - - return 0; - } - - template<typename T> - QList<T*> findItems(QQuickItem *parent, const QString &objectName, bool visibleOnly = true) - { - QList<T*> items; - const QMetaObject &mo = T::staticMetaObject; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i)); - if (!item || (visibleOnly && (!item->isVisible() || QQuickItemPrivate::get(item)->culled))) - continue; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) - items.append(static_cast<T*>(item)); - items += findItems<T>(item, objectName); - } - - return items; - } - - template<typename T> - QList<T*> findItems(QQuickItem *parent, const QString &objectName, const QList<int> &indexes) - { - QList<T*> items; - for (int i=0; i<indexes.count(); i++) - items << qobject_cast<QQuickItem*>(findItem<T>(parent, objectName, indexes[i])); - return items; - } - - bool compareImages(const QImage &ia, const QImage &ib, QString *errorMessage); - - struct SignalMultiSpy : public QObject - { - Q_OBJECT - public: - QList<QObject *> senders; - QList<QByteArray> signalNames; - - template <typename Func1> - QMetaObject::Connection connectToSignal(const typename QtPrivate::FunctionPointer<Func1>::Object *obj, Func1 signal, - Qt::ConnectionType type = Qt::AutoConnection) - { - return connect(obj, signal, this, &SignalMultiSpy::receive, type); - } - - void clear() { - senders.clear(); - signalNames.clear(); - } - - public slots: - void receive() { - QMetaMethod m = sender()->metaObject()->method(senderSignalIndex()); - senders << sender(); - signalNames << m.name(); - } - }; -} - -#endif // QQUICKVISUALTESTUTIL_H diff --git a/tests/auto/quick/sharedimage/tst_sharedimage.cpp b/tests/auto/quick/sharedimage/tst_sharedimage.cpp index afadb76ad02..c11ed7e180e 100644 --- a/tests/auto/quick/sharedimage/tst_sharedimage.cpp +++ b/tests/auto/quick/sharedimage/tst_sharedimage.cpp @@ -49,6 +49,14 @@ void tst_sharedimage::initTestCase() #if !QT_CONFIG(systemsemaphore) QSKIP("Shared image not supported"); #endif + +#ifdef Q_OS_ANDROID + /* + * On Android, images are usually in resources, not in + * files on the file system. + */ + QSKIP("Shared image not useful on Android, skipping test"); +#endif } void tst_sharedimage::compareToPlainLoad_data() diff --git a/tests/auto/quick/touchmouse/CMakeLists.txt b/tests/auto/quick/touchmouse/CMakeLists.txt index 703f4f75782..c0a9da1224d 100644 --- a/tests/auto/quick/touchmouse/CMakeLists.txt +++ b/tests/auto/quick/touchmouse/CMakeLists.txt @@ -12,21 +12,14 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_touchmouse SOURCES - ../../shared/util.cpp ../../shared/util.h - ../shared/geometrytestutil.cpp ../shared/geometrytestutil.h - ../shared/viewtestutil.cpp ../shared/viewtestutil.h - ../shared/visualtestutil.cpp ../shared/visualtestutil.h tst_touchmouse.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quick/touchmouse/data/oneMouseArea.qml b/tests/auto/quick/touchmouse/data/oneMouseArea.qml new file mode 100644 index 00000000000..dccc5792c80 --- /dev/null +++ b/tests/auto/quick/touchmouse/data/oneMouseArea.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Item { + width: 320; height: 240 + + Rectangle { + width: parent.width / 2; height: parent.height; x: width + color: ma.containsPress ? "steelblue" : "lightsteelblue" + MouseArea { + id: ma + anchors.fill: parent + } + } +} diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp index ef0df0cddb8..c80ceddcc3b 100644 --- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp +++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp @@ -46,8 +46,8 @@ #include <QtQml/qqmlengine.h> #include <QtQml/qqmlproperty.h> -#include "../../shared/util.h" -#include "../shared/viewtestutil.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") @@ -150,6 +150,12 @@ class EventItem : public QQuickItem ++touchUngrabCount; } + void dumpEventList() + { + for (const auto &event : eventList) + qDebug() << event; + } + bool event(QEvent *event) override { return QQuickItem::event(event); } @@ -185,12 +191,22 @@ class GrabMonitor : public QObject { public: QObject *exclusiveGrabber = nullptr; + int transitionCount = 0; bool fromMouseEvent = false; bool canceled = false; + void reset() + { + exclusiveGrabber = nullptr; + transitionCount = 0; + fromMouseEvent = false; + canceled = false; + } + void onGrabChanged(QObject *grabber, QPointingDevice::GrabTransition transition, const QPointerEvent *event, const QEventPoint &point) { qCDebug(lcTests) << grabber << transition << event << point << point.device(); + ++transitionCount; switch (transition) { case QPointingDevice::GrabTransition::GrabExclusive: exclusiveGrabber = grabber; @@ -217,6 +233,7 @@ class tst_TouchMouse : public QQmlDataTest Q_OBJECT public: tst_TouchMouse() + : QQmlDataTest(QT_QMLTEST_DATADIR) {} private slots: @@ -246,6 +263,11 @@ private slots: void hoverEnabled(); void implicitUngrab(); + void touchCancelWillCancelMousePress(); + + void oneTouchInsideAndOneOutside(); + + void strayTouchDoesntAutograb(); protected: bool eventFilter(QObject *, QEvent *event) override @@ -429,7 +451,7 @@ void tst_TouchMouse::testEventFilter() // QScopedPointer<QQuickView> window(createView()); // window.setSource(testFileUrl("singleitem.qml")); // window.show(); -// QQuickViewTestUtil::centerOnScreen(&window); +// QQuickVisualTestUtils::centerOnScreen(&window); // QVERIFY(QTest::qWaitForWindowActive(&window)); // QVERIFY(window->rootObject() != 0); @@ -716,7 +738,7 @@ void tst_TouchMouse::touchButtonOnFlickable() QTRY_COMPARE(eventItem2->touchUngrabCount, 1); qCDebug(lcTests) << "expected delivered events: press(touch) move(touch)" << eventItem2->eventList; - QCOMPARE(eventItem2->eventList.size(), 2); + QCOMPARE(eventItem2->eventList.size(), 3); QCOMPARE(eventItem2->eventList.at(1).type, QEvent::TouchUpdate); QCOMPARE(grabMonitor.exclusiveGrabber, flickable); // both EventItem and Flickable handled the actual touch, so synth-mouse doesn't happen @@ -1545,6 +1567,117 @@ void tst_TouchMouse::implicitUngrab() QCOMPARE(eventItem->eventList.at(0).type, QEvent::UngrabMouse); QTest::touchEvent(&window, device).release(0, p1); // clean up potential state } + +void tst_TouchMouse::touchCancelWillCancelMousePress() +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("singleitem.qml"))); + QQuickItem *root = window.rootObject(); + QVERIFY(root != nullptr); + + EventItem *eventItem = root->findChild<EventItem*>("eventItem1"); + eventItem->acceptMouse = true; + eventItem->setAcceptTouchEvents(false); + QPoint p1(20, 20); + + // Begin a new touch, that gets converted to a mouse press + QTest::touchEvent(&window, device).press(0, p1); + QCOMPARE(eventItem->eventList.count(), 1); + QCOMPARE(eventItem->eventList.at(0).type, QEvent::MouseButtonPress); + + // Cancel it... + QTouchEvent cancelEvent(QEvent::TouchCancel, device); + QCoreApplication::sendEvent(&window, &cancelEvent); + QCOMPARE(eventItem->eventList.count(), 3); + QCOMPARE(eventItem->eventList.at(1).type, QEvent::TouchCancel); + QCOMPARE(eventItem->eventList.at(2).type, QEvent::UngrabMouse); + + // Begin a second touch. Since the last one was cancelled, this + // should end up as a new mouse press on the target item. + QTest::touchEvent(&window, device).press(0, p1); + QVERIFY(eventItem->eventList.count() >= 5); + QCOMPARE(eventItem->eventList.at(3).type, QEvent::MouseButtonPress); + + QTest::touchEvent(&window, device).release(0, p1); // clean up potential state +} + +void tst_TouchMouse::oneTouchInsideAndOneOutside() // QTBUG-102996 +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("oneMouseArea.qml"))); + QQuickItem *root = window.rootObject(); + QVERIFY(root); + QQuickMouseArea *ma = root->findChild<QQuickMouseArea*>(); + QVERIFY(ma); + + // Press the MouseArea + QPoint p1 = ma->mapToScene(ma->boundingRect().center()).toPoint(); + QTest::touchEvent(&window, device).press(1, p1); + QQuickTouchUtils::flush(&window); + QVERIFY(ma->pressed()); + + // Tap outside the MouseArea with a second finger + QPoint p2(100, 100); + QTest::touchEvent(&window, device).stationary(1).press(2, p2); + QQuickTouchUtils::flush(&window); + QTest::touchEvent(&window, device).stationary(1).release(2, p2); + QQuickTouchUtils::flush(&window); + QVERIFY(ma->pressed()); + + // Press again outside the MouseArea with a second finger + QTest::touchEvent(&window, device).stationary(1).press(2, p2); + + // Release the first finger: MouseArea should be released + QTest::touchEvent(&window, device).release(1, p1).stationary(2); + QQuickTouchUtils::flush(&window); + QCOMPARE(ma->pressed(), false); + + // Release the second finger + QTest::touchEvent(&window, device).release(2, p2); + QQuickTouchUtils::flush(&window); +} + +void tst_TouchMouse::strayTouchDoesntAutograb() // QTBUG-107867 +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("singleitem.qml"))); + QQuickItem *root = window.rootObject(); + QVERIFY(root); + EventItem *eventItem = root->findChild<EventItem*>(); + QVERIFY(eventItem); + // This item accepts (synth-)mouse events but NOT touch + eventItem->acceptMouse = true; + QCOMPARE(eventItem->acceptTouchEvents(), false); // the default in Qt 6 + QPoint p1(6, 6); + grabMonitor.reset(); + + // Begin a new touch, that gets converted to a mouse press + QTest::touchEvent(&window, device).press(0, p1); + QQuickTouchUtils::flush(&window); + qCDebug(lcTests) << "after touch press:" << eventItem->eventList; + QCOMPARE(eventItem->eventList.size(), 1); + QCOMPARE(eventItem->eventList.at(0).type, QEvent::MouseButtonPress); + QCOMPARE(grabMonitor.exclusiveGrabber, eventItem); + + // Drag + for (int i = 0; i < 3; ++i) { + QTest::touchEvent(&window, device).move(0, p1 + QPoint(i * 5, i * 5), &window); + QQuickTouchUtils::flush(&window); + QCOMPARE(grabMonitor.transitionCount, 1); // no new grab + QCOMPARE(eventItem->eventList.size(), i + 2); + QCOMPARE(eventItem->eventList.last().type, QEvent::MouseMove); + } + + // Press an extra point: EventItem should see nothing + QTest::touchEvent(&window, device).stationary(0).press(1, p1); + QQuickTouchUtils::flush(&window); + qCDebug(lcTests) << "after press of second touchpoint:" << eventItem->eventList; + QCOMPARE(eventItem->eventList.size(), 4); + QCOMPARE(grabMonitor.transitionCount, 1); // no new grab + + QTest::touchEvent(&window, device).release(0, p1).release(1, p1); +} + QTEST_MAIN(tst_TouchMouse) #include "tst_touchmouse.moc" diff --git a/tests/auto/quickcontrols2/CMakeLists.txt b/tests/auto/quickcontrols2/CMakeLists.txt new file mode 100644 index 00000000000..4004fbecdfc --- /dev/null +++ b/tests/auto/quickcontrols2/CMakeLists.txt @@ -0,0 +1,43 @@ +# Generated from auto.pro. + +add_subdirectory(accessibility) +if(NOT ANDROID) # temporarily disabled until QTBUG-100991 is fixed +add_subdirectory(controls) +endif() +add_subdirectory(cursor) +add_subdirectory(customization) +add_subdirectory(deferred) +add_subdirectory(designer) +if(NOT ANDROID) # QTBUG-100258 +add_subdirectory(focus) +endif() +add_subdirectory(font) +add_subdirectory(palette) +add_subdirectory(platform) +add_subdirectory(pointerhandlers) +add_subdirectory(pressandhold) +add_subdirectory(qquickapplicationwindow) +add_subdirectory(qquickcolor) +add_subdirectory(qquickdrawer) +add_subdirectory(qquickheaderview) +add_subdirectory(qquickiconimage) +add_subdirectory(qquickiconlabel) +add_subdirectory(qquickimaginestyle) +add_subdirectory(qquickmaterialstyle) +add_subdirectory(qquickmaterialstyleconf) +add_subdirectory(qquickmenu) +add_subdirectory(qquickmenubar) +add_subdirectory(qquickninepatchimage) +add_subdirectory(qquickpopup) +add_subdirectory(qquickstyle) +add_subdirectory(qquickuniversalstyle) +add_subdirectory(qquickuniversalstyleconf) +add_subdirectory(revisions) +if(NOT ANDROID) # QTBUG-100191 +add_subdirectory(sanity) +add_subdirectory(snippets) +endif() +add_subdirectory(styleimports) +add_subdirectory(styleimportscompiletimematerial) +add_subdirectory(styleimportscompiletimeqmlonly) +add_subdirectory(translation) diff --git a/tests/auto/quickcontrols2/accessibility/BLACKLIST b/tests/auto/quickcontrols2/accessibility/BLACKLIST new file mode 100644 index 00000000000..fe7a87f847f --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/BLACKLIST @@ -0,0 +1,2 @@ +[a11y:Label] +opensuse-leap diff --git a/tests/auto/quickcontrols2/accessibility/CMakeLists.txt b/tests/auto/quickcontrols2/accessibility/CMakeLists.txt new file mode 100644 index 00000000000..704b2d45cd5 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/CMakeLists.txt @@ -0,0 +1,52 @@ +# Generated from accessibility.pro. + +if(NOT QT_FEATURE_accessibility) + return() +endif() + +##################################################################### +## tst_accessibility Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_accessibility + SOURCES + tst_accessibility.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:accessibility.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" +# _REQUIREMENTS = "qtConfig(accessibility)" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_accessibility CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_accessibility CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/abstractbutton.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/abstractbutton.qml new file mode 100644 index 00000000000..29d6b3c0a00 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/abstractbutton.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +AbstractButton { + text: "AbstractButton" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/busyindicator.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/busyindicator.qml new file mode 100644 index 00000000000..baaa9ba80b4 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/busyindicator.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +BusyIndicator { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/button.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/button.qml new file mode 100644 index 00000000000..0359b3ac15b --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/button.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Button { + text: "Button" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/checkbox.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/checkbox.qml new file mode 100644 index 00000000000..c912be5791e --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/checkbox.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +CheckBox { + text: "CheckBox" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/checkdelegate.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/checkdelegate.qml new file mode 100644 index 00000000000..df62bc89d5f --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/checkdelegate.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +CheckDelegate { + text: "CheckDelegate" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/combobox.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/combobox.qml new file mode 100644 index 00000000000..bfeac723dac --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/combobox.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +ComboBox { + model: ["ComboBox"] +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/container.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/container.qml new file mode 100644 index 00000000000..7d29fec4261 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/container.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +Container { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/control.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/control.qml new file mode 100644 index 00000000000..280cfd29623 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/control.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +Control { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/dial.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/dial.qml new file mode 100644 index 00000000000..d7e700b5dfa --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/dial.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +Dial { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/dialog.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/dialog.qml new file mode 100644 index 00000000000..d88fd36d8ed --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/dialog.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Dialog { + title: "Dialog" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/drawer.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/drawer.qml new file mode 100644 index 00000000000..60a35171b2d --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/drawer.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +Drawer { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/frame.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/frame.qml new file mode 100644 index 00000000000..b70ccb556c5 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/frame.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +Frame { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/groupbox.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/groupbox.qml new file mode 100644 index 00000000000..24f3a294b8c --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/groupbox.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +GroupBox { + title: "GroupBox" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/itemdelegate.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/itemdelegate.qml new file mode 100644 index 00000000000..5ec95fe07e9 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/itemdelegate.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +ItemDelegate { + text: "ItemDelegate" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/label.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/label.qml new file mode 100644 index 00000000000..5f6a98cd746 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/label.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Label { + text: "Label" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/menu.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/menu.qml new file mode 100644 index 00000000000..07fef72849e --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/menu.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +Menu { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/menuitem.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/menuitem.qml new file mode 100644 index 00000000000..194fa988c87 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/menuitem.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +MenuItem { + text: "MenuItem" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/page.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/page.qml new file mode 100644 index 00000000000..cd1f78e170f --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/page.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Page { + title: "Page" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/pageindicator.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/pageindicator.qml new file mode 100644 index 00000000000..d64d5657065 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/pageindicator.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +PageIndicator { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/pane.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/pane.qml new file mode 100644 index 00000000000..765c98a394b --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/pane.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +Pane { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/popup.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/popup.qml new file mode 100644 index 00000000000..c599bd4c0be --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/popup.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +Popup { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/progressbar.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/progressbar.qml new file mode 100644 index 00000000000..b3e287c33c8 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/progressbar.qml @@ -0,0 +1,8 @@ +import QtQuick +import QtQuick.Controls + +ProgressBar { + from: 0 + to: 100 + value: 50 +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/radiobutton.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/radiobutton.qml new file mode 100644 index 00000000000..d796b37e17d --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/radiobutton.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +RadioButton { + text: "RadioButton" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/radiodelegate.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/radiodelegate.qml new file mode 100644 index 00000000000..d002b985328 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/radiodelegate.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +RadioDelegate { + text: "RadioDelegate" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/rangeslider.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/rangeslider.qml new file mode 100644 index 00000000000..7bd364c4433 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/rangeslider.qml @@ -0,0 +1,11 @@ +import QtQuick +import QtQuick.Controls + +RangeSlider { + from: 0 + to: 100 + first.value: 25 + second.value: 75 + stepSize: 1 + orientation: Qt.Horizontal +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/roundbutton.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/roundbutton.qml new file mode 100644 index 00000000000..6c78c0a47d1 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/roundbutton.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +RoundButton { + text: "RoundButton" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/scrollbar.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/scrollbar.qml new file mode 100644 index 00000000000..c36b1534b16 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/scrollbar.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +ScrollBar { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/scrollindicator.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/scrollindicator.qml new file mode 100644 index 00000000000..5b2f44b674b --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/scrollindicator.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +ScrollIndicator { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/slider.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/slider.qml new file mode 100644 index 00000000000..fd60a198445 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/slider.qml @@ -0,0 +1,10 @@ +import QtQuick +import QtQuick.Controls + +Slider { + from: 0 + to: 100 + value: 50 + stepSize: 1 + orientation: Qt.Horizontal +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/spinbox.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/spinbox.qml new file mode 100644 index 00000000000..159e1f4676e --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/spinbox.qml @@ -0,0 +1,9 @@ +import QtQuick +import QtQuick.Controls + +SpinBox { + from: 0 + to: 100 + value: 50 + stepSize: 1 +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/stackview.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/stackview.qml new file mode 100644 index 00000000000..bd540b91a07 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/stackview.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +StackView { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/swipedelegate.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/swipedelegate.qml new file mode 100644 index 00000000000..d3724d4dc2b --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/swipedelegate.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +SwipeDelegate { + text: "SwipeDelegate" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/swipeview.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/swipeview.qml new file mode 100644 index 00000000000..9eb82216663 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/swipeview.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +SwipeView { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/switch.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/switch.qml new file mode 100644 index 00000000000..00213086aac --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/switch.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Switch { + text: "Switch" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/switchdelegate.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/switchdelegate.qml new file mode 100644 index 00000000000..9f71ed68489 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/switchdelegate.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +SwitchDelegate { + text: "SwitchDelegate" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/tabbar.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/tabbar.qml new file mode 100644 index 00000000000..423bfea9032 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/tabbar.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +TabBar { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/tabbutton.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/tabbutton.qml new file mode 100644 index 00000000000..ab9ea8ae2cb --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/tabbutton.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +TabButton { + text: "TabButton" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/textarea.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/textarea.qml new file mode 100644 index 00000000000..9a1f31d0298 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/textarea.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +TextArea { + text: "TextArea" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/textfield.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/textfield.qml new file mode 100644 index 00000000000..42a16bae786 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/textfield.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +TextField { + text: "TextField" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/toolbar.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/toolbar.qml new file mode 100644 index 00000000000..01b93d7d91a --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/toolbar.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +ToolBar { } diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/toolbutton.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/toolbutton.qml new file mode 100644 index 00000000000..40e1152edcc --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/toolbutton.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +ToolButton { + text: "ToolButton" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/tooltip.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/tooltip.qml new file mode 100644 index 00000000000..f1c3cebee57 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/tooltip.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +ToolTip { + text: "ToolTip" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/defaults/tumbler.qml b/tests/auto/quickcontrols2/accessibility/data/defaults/tumbler.qml new file mode 100644 index 00000000000..e3db175bd25 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/defaults/tumbler.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +Tumbler { } diff --git a/tests/auto/quickcontrols2/accessibility/data/ordering/page.qml b/tests/auto/quickcontrols2/accessibility/data/ordering/page.qml new file mode 100644 index 00000000000..8efafe32327 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/ordering/page.qml @@ -0,0 +1,23 @@ +import QtQuick +import QtQuick.Controls + +Page { + title: "Page" + Accessible.role: Accessible.Pane + + header: Label { + text: "Header" + } + + footer: Label { + text: "Footer" + } + + Label { + text: "Content item 1" + } + + Label { + text: "Content item 2" + } +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/abstractbutton.qml b/tests/auto/quickcontrols2/accessibility/data/override/abstractbutton.qml new file mode 100644 index 00000000000..ac8efe26018 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/abstractbutton.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +AbstractButton { + text: "AbstractButton" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/busyindicator.qml b/tests/auto/quickcontrols2/accessibility/data/override/busyindicator.qml new file mode 100644 index 00000000000..439788d1218 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/busyindicator.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +BusyIndicator { + Accessible.name: "BusyIndicatorOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/button.qml b/tests/auto/quickcontrols2/accessibility/data/override/button.qml new file mode 100644 index 00000000000..578af86c783 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/button.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +Button { + text: "Button" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/checkbox.qml b/tests/auto/quickcontrols2/accessibility/data/override/checkbox.qml new file mode 100644 index 00000000000..5df735091e6 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/checkbox.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +CheckBox { + text: "CheckBox" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/checkdelegate.qml b/tests/auto/quickcontrols2/accessibility/data/override/checkdelegate.qml new file mode 100644 index 00000000000..43f65d50834 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/checkdelegate.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +CheckDelegate { + text: "CheckDelegate" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/combobox.qml b/tests/auto/quickcontrols2/accessibility/data/override/combobox.qml new file mode 100644 index 00000000000..fa6ed3b4bf8 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/combobox.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +ComboBox { + model: ["ComboBox"] + Accessible.name: model[0] + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/container.qml b/tests/auto/quickcontrols2/accessibility/data/override/container.qml new file mode 100644 index 00000000000..4e73f341d66 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/container.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Container { + Accessible.name: "ContainerOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/control.qml b/tests/auto/quickcontrols2/accessibility/data/override/control.qml new file mode 100644 index 00000000000..9c2be4617f2 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/control.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Control { + Accessible.name: "ControlOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/dial.qml b/tests/auto/quickcontrols2/accessibility/data/override/dial.qml new file mode 100644 index 00000000000..8dbf0e37648 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/dial.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Dial { + Accessible.name: "DialOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/dialog.qml b/tests/auto/quickcontrols2/accessibility/data/override/dialog.qml new file mode 100644 index 00000000000..d1f31971968 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/dialog.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +Dialog { + title: "Dialog" + Accessible.name: title + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/drawer.qml b/tests/auto/quickcontrols2/accessibility/data/override/drawer.qml new file mode 100644 index 00000000000..02e973e2cc3 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/drawer.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Drawer { + Accessible.name: "DrawerOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/frame.qml b/tests/auto/quickcontrols2/accessibility/data/override/frame.qml new file mode 100644 index 00000000000..55086b35c04 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/frame.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Frame { + Accessible.name: "FrameOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/groupbox.qml b/tests/auto/quickcontrols2/accessibility/data/override/groupbox.qml new file mode 100644 index 00000000000..d09d0845c94 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/groupbox.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +GroupBox { + title: "GroupBox" + Accessible.name: title + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/itemdelegate.qml b/tests/auto/quickcontrols2/accessibility/data/override/itemdelegate.qml new file mode 100644 index 00000000000..2f32cb75144 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/itemdelegate.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +ItemDelegate { + text: "ItemDelegate" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/label.qml b/tests/auto/quickcontrols2/accessibility/data/override/label.qml new file mode 100644 index 00000000000..5c1310f8755 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/label.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +Label { + text: "Label" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/menu.qml b/tests/auto/quickcontrols2/accessibility/data/override/menu.qml new file mode 100644 index 00000000000..57a1b3d61f4 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/menu.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Menu { + Accessible.name: "MenuOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/menuitem.qml b/tests/auto/quickcontrols2/accessibility/data/override/menuitem.qml new file mode 100644 index 00000000000..e1c064f3b5d --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/menuitem.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +MenuItem { + text: "MenuItem" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/page.qml b/tests/auto/quickcontrols2/accessibility/data/override/page.qml new file mode 100644 index 00000000000..b3b87e8ab64 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/page.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +Page { + title: "Page" + Accessible.name: title + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/pageindicator.qml b/tests/auto/quickcontrols2/accessibility/data/override/pageindicator.qml new file mode 100644 index 00000000000..f366464df76 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/pageindicator.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +PageIndicator { + Accessible.name: "PageIndicatorOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/pane.qml b/tests/auto/quickcontrols2/accessibility/data/override/pane.qml new file mode 100644 index 00000000000..7b57e9a9f54 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/pane.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Pane { + Accessible.name: "PaneOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/popup.qml b/tests/auto/quickcontrols2/accessibility/data/override/popup.qml new file mode 100644 index 00000000000..9d8d58550ac --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/popup.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Popup { + Accessible.name: "PopupOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/progressbar.qml b/tests/auto/quickcontrols2/accessibility/data/override/progressbar.qml new file mode 100644 index 00000000000..58bd2ae1bde --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/progressbar.qml @@ -0,0 +1,10 @@ +import QtQuick +import QtQuick.Controls + +ProgressBar { + from: 0 + to: 100 + value: 50 + + Accessible.name: "ProgressBarOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/radiobutton.qml b/tests/auto/quickcontrols2/accessibility/data/override/radiobutton.qml new file mode 100644 index 00000000000..3c555256b89 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/radiobutton.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +RadioButton { + text: "RadioButton" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/radiodelegate.qml b/tests/auto/quickcontrols2/accessibility/data/override/radiodelegate.qml new file mode 100644 index 00000000000..883f963c5cc --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/radiodelegate.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +RadioDelegate { + text: "RadioDelegate" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/rangeslider.qml b/tests/auto/quickcontrols2/accessibility/data/override/rangeslider.qml new file mode 100644 index 00000000000..675c34aad17 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/rangeslider.qml @@ -0,0 +1,13 @@ +import QtQuick +import QtQuick.Controls + +RangeSlider { + from: 0 + to: 100 + first.value: 25 + second.value: 75 + stepSize: 1 + orientation: Qt.Horizontal + + Accessible.name: "RangeSliderOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/roundbutton.qml b/tests/auto/quickcontrols2/accessibility/data/override/roundbutton.qml new file mode 100644 index 00000000000..a793ee2833c --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/roundbutton.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +RoundButton { + text: "RoundButton" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/scrollbar.qml b/tests/auto/quickcontrols2/accessibility/data/override/scrollbar.qml new file mode 100644 index 00000000000..6b3e613c42c --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/scrollbar.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +ScrollBar { + Accessible.name: "ScrollBarOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/scrollindicator.qml b/tests/auto/quickcontrols2/accessibility/data/override/scrollindicator.qml new file mode 100644 index 00000000000..5cc1e5d4b83 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/scrollindicator.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +ScrollIndicator { + Accessible.name: "ScrollIndicatorOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/slider.qml b/tests/auto/quickcontrols2/accessibility/data/override/slider.qml new file mode 100644 index 00000000000..9239f8db992 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/slider.qml @@ -0,0 +1,11 @@ +import QtQuick +import QtQuick.Controls + +Slider { + from: 0 + to: 100 + value: 50 + stepSize: 1 + orientation: Qt.Horizontal + Accessible.name: "SliderOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/spinbox.qml b/tests/auto/quickcontrols2/accessibility/data/override/spinbox.qml new file mode 100644 index 00000000000..327f2a6d4aa --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/spinbox.qml @@ -0,0 +1,10 @@ +import QtQuick +import QtQuick.Controls + +SpinBox { + from: 0 + to: 100 + value: 50 + stepSize: 1 + Accessible.name: "SpinBoxOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/stackview.qml b/tests/auto/quickcontrols2/accessibility/data/override/stackview.qml new file mode 100644 index 00000000000..dd3b8342f76 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/stackview.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +StackView { + Accessible.name: "StackViewOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/swipedelegate.qml b/tests/auto/quickcontrols2/accessibility/data/override/swipedelegate.qml new file mode 100644 index 00000000000..bc97fc93bcf --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/swipedelegate.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +SwipeDelegate { + text: "SwipeDelegate" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/swipeview.qml b/tests/auto/quickcontrols2/accessibility/data/override/swipeview.qml new file mode 100644 index 00000000000..809b536210a --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/swipeview.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +SwipeView { + Accessible.name: "SwipeViewOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/switch.qml b/tests/auto/quickcontrols2/accessibility/data/override/switch.qml new file mode 100644 index 00000000000..18e3eb70ce0 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/switch.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +Switch { + text: "Switch" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/switchdelegate.qml b/tests/auto/quickcontrols2/accessibility/data/override/switchdelegate.qml new file mode 100644 index 00000000000..0c66f9e9e9f --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/switchdelegate.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +SwitchDelegate { + text: "SwitchDelegate" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/tabbar.qml b/tests/auto/quickcontrols2/accessibility/data/override/tabbar.qml new file mode 100644 index 00000000000..a959f68cae9 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/tabbar.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +TabBar { + Accessible.name: "TabBarOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/tabbutton.qml b/tests/auto/quickcontrols2/accessibility/data/override/tabbutton.qml new file mode 100644 index 00000000000..1530a2d1bc5 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/tabbutton.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +TabButton { + text: "TabButton" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/textarea.qml b/tests/auto/quickcontrols2/accessibility/data/override/textarea.qml new file mode 100644 index 00000000000..2b1422252fc --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/textarea.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +TextArea { + text: "TextArea" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/textfield.qml b/tests/auto/quickcontrols2/accessibility/data/override/textfield.qml new file mode 100644 index 00000000000..42098b6640b --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/textfield.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +TextField { + text: "TextField" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/toolbar.qml b/tests/auto/quickcontrols2/accessibility/data/override/toolbar.qml new file mode 100644 index 00000000000..97406f8ca59 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/toolbar.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +ToolBar { + Accessible.name: "ToolBarOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/toolbutton.qml b/tests/auto/quickcontrols2/accessibility/data/override/toolbutton.qml new file mode 100644 index 00000000000..5ecb427baf8 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/toolbutton.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +ToolButton { + text: "ToolButton" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/tooltip.qml b/tests/auto/quickcontrols2/accessibility/data/override/tooltip.qml new file mode 100644 index 00000000000..1a4c3a994f8 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/tooltip.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls + +ToolTip { + text: "ToolTip" + Accessible.name: text + "Override" +} diff --git a/tests/auto/quickcontrols2/accessibility/data/override/tumbler.qml b/tests/auto/quickcontrols2/accessibility/data/override/tumbler.qml new file mode 100644 index 00000000000..947f66cd70f --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/data/override/tumbler.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls + +Tumbler { + Accessible.name: "TumblerOverride" +} diff --git a/tests/auto/quickcontrols2/accessibility/tst_accessibility.cpp b/tests/auto/quickcontrols2/accessibility/tst_accessibility.cpp new file mode 100644 index 00000000000..cd6c4082303 --- /dev/null +++ b/tests/auto/quickcontrols2/accessibility/tst_accessibility.cpp @@ -0,0 +1,312 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlcontext.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p.h> + +#if QT_CONFIG(accessibility) +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/qpa/qplatformintegration.h> +#include <QtGui/qpa/qplatformaccessibility.h> +#include <QtQuick/private/qquickaccessibleattached_p.h> +#endif + +class tst_accessibility : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_accessibility(); + +private slots: + void a11y_data(); + void a11y(); + + void override_data(); + void override(); + + void ordering(); +private: + QQmlEngine engine; +}; + +#if QT_CONFIG(accessibility) +static QPlatformAccessibility *platformAccessibility() +{ + QPlatformIntegration *pfIntegration = QGuiApplicationPrivate::platformIntegration(); + return pfIntegration ? pfIntegration->accessibility() : nullptr; +} +#endif + +QString adjustFileBaseName(const QString &fileBaseName) +{ +#if !QT_CONFIG(accessibility) + if (fileBaseName == QLatin1Literal("dayofweekrow") + || fileBaseName == QLatin1Literal("monthgrid") + || fileBaseName == QLatin1Literal("weeknumbercolumn")) + return fileBaseName += QLatin1Literal("-2"); +#else + return fileBaseName; +#endif +} + +QQuickItem *findItem(QObject *object) +{ + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (!item) { + QQuickPopup *popup = qobject_cast<QQuickPopup *>(object); + if (popup) + item = popup->popupItem(); + } + return item; +} + +tst_accessibility::tst_accessibility() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_accessibility::a11y_data() +{ + QTest::addColumn<QString>("fileBaseName"); + QTest::addColumn<QAccessible::Role>("role"); + QTest::addColumn<QString>("text"); + + QTest::newRow("AbstractButton") << "abstractbutton" << QAccessible::Button << "AbstractButton"; + QTest::newRow("BusyIndicator") << "busyindicator" << QAccessible::Indicator << ""; + QTest::newRow("Button") << "button" << QAccessible::Button << "Button"; + QTest::newRow("CheckBox") << "checkbox" << QAccessible::CheckBox << "CheckBox"; + QTest::newRow("CheckDelegate") << "checkdelegate" << QAccessible::CheckBox << "CheckDelegate"; + QTest::newRow("ComboBox") << "combobox" << QAccessible::ComboBox << "ComboBox"; + QTest::newRow("Container") << "container" << QAccessible::NoRole << ""; + QTest::newRow("Control") << "control" << QAccessible::NoRole << ""; + QTest::newRow("Dial") << "dial" << QAccessible::Dial << ""; + QTest::newRow("Dialog") << "dialog" << QAccessible::Dialog << "Dialog"; + QTest::newRow("Drawer") << "drawer" << QAccessible::Dialog << ""; + QTest::newRow("Frame") << "frame" << QAccessible::Border << ""; + QTest::newRow("GroupBox") << "groupbox" << QAccessible::Grouping << "GroupBox"; + QTest::newRow("ItemDelegate") << "itemdelegate" << QAccessible::ListItem << "ItemDelegate"; + QTest::newRow("Label") << "label" << QAccessible::StaticText << "Label"; + QTest::newRow("Menu") << "menu" << QAccessible::PopupMenu << ""; + QTest::newRow("MenuItem") << "menuitem" << QAccessible::MenuItem << "MenuItem"; + QTest::newRow("Page") << "page" << QAccessible::PageTab << "Page"; + QTest::newRow("PageIndicator") << "pageindicator" << QAccessible::Indicator << ""; + QTest::newRow("Pane") << "pane" << QAccessible::Pane << ""; + QTest::newRow("Popup") << "popup" << QAccessible::Dialog << ""; + QTest::newRow("ProgressBar") << "progressbar" << QAccessible::ProgressBar << ""; + QTest::newRow("RadioButton") << "radiobutton" << QAccessible::RadioButton << "RadioButton"; + QTest::newRow("RadioDelegate") << "radiodelegate" << QAccessible::RadioButton << "RadioDelegate"; + QTest::newRow("RangeSlider") << "rangeslider" << QAccessible::Slider << ""; + QTest::newRow("RoundButton") << "roundbutton" << QAccessible::Button << "RoundButton"; + QTest::newRow("ScrollBar") << "scrollbar" << QAccessible::ScrollBar << ""; + QTest::newRow("ScrollIndicator") << "scrollindicator" << QAccessible::Indicator << ""; + QTest::newRow("Slider") << "slider" << QAccessible::Slider << ""; + QTest::newRow("SpinBox") << "spinbox" << QAccessible::SpinBox << ""; + QTest::newRow("StackView") << "stackview" << QAccessible::LayeredPane << ""; + QTest::newRow("SwipeDelegate") << "swipedelegate" << QAccessible::ListItem << "SwipeDelegate"; + QTest::newRow("SwipeView") << "swipeview" << QAccessible::PageTabList << ""; + QTest::newRow("Switch") << "switch" << QAccessible::CheckBox << "Switch"; + QTest::newRow("SwitchDelegate") << "switchdelegate" << QAccessible::ListItem << "SwitchDelegate"; + QTest::newRow("TabBar") << "tabbar" << QAccessible::PageTabList << ""; + QTest::newRow("TabButton") << "tabbutton" << QAccessible::PageTab << "TabButton"; + QTest::newRow("TextArea") << "textarea" << QAccessible::EditableText << ""; + QTest::newRow("TextField") << "textfield" << QAccessible::EditableText << ""; + QTest::newRow("ToolBar") << "toolbar" << QAccessible::ToolBar << ""; + QTest::newRow("ToolButton") << "toolbutton" << QAccessible::Button << "ToolButton"; + QTest::newRow("ToolTip") << "tooltip" << QAccessible::ToolTip << "ToolTip"; + QTest::newRow("Tumbler") << "tumbler" << QAccessible::NoRole << ""; // TODO +} + +void tst_accessibility::a11y() +{ + QFETCH(QString, fileBaseName); + QFETCH(QAccessible::Role, role); + QFETCH(QString, text); + + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("defaults/" + adjustFileBaseName(fileBaseName) + ".qml")); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + QQuickItem *item = findItem(object.data()); + QVERIFY(item); + +#if QT_CONFIG(accessibility) + QQuickAccessibleAttached *attached = QQuickAccessibleAttached::attachedProperties(item); + if (QAccessible::isActive()) { + QVERIFY(attached); + } else { + QVERIFY(!attached); + QPlatformAccessibility *accessibility = platformAccessibility(); + if (!accessibility) + QSKIP("No QPlatformAccessibility available."); + accessibility->setActive(true); + attached = QQuickAccessibleAttached::attachedProperties(item); + } + QVERIFY(attached); + QCOMPARE(attached->role(), role); + QCOMPARE(attached->name(), text); +#else + Q_UNUSED(role); + Q_UNUSED(text); +#endif +} + +void tst_accessibility::override_data() +{ + QTest::addColumn<QAccessible::Role>("role"); + + QTest::newRow("AbstractButton") << QAccessible::Button; + QTest::newRow("BusyIndicator") << QAccessible::Indicator; + QTest::newRow("Button") << QAccessible::Button; + QTest::newRow("CheckBox") << QAccessible::CheckBox; + QTest::newRow("CheckDelegate") << QAccessible::CheckBox; + QTest::newRow("ComboBox") << QAccessible::ComboBox; + QTest::newRow("Container") << QAccessible::NoRole; + QTest::newRow("Control") << QAccessible::NoRole; + QTest::newRow("Dial") << QAccessible::Dial; + QTest::newRow("Dialog") << QAccessible::Dialog; + QTest::newRow("Drawer") << QAccessible::Dialog; + QTest::newRow("Frame") << QAccessible::Border; + QTest::newRow("GroupBox") << QAccessible::Grouping; + QTest::newRow("ItemDelegate") << QAccessible::ListItem; + QTest::newRow("Label") << QAccessible::StaticText; + QTest::newRow("Menu") << QAccessible::PopupMenu; + QTest::newRow("MenuItem") << QAccessible::MenuItem; + QTest::newRow("Page") << QAccessible::PageTab; + QTest::newRow("PageIndicator") << QAccessible::Indicator; + QTest::newRow("Pane") << QAccessible::Pane; + QTest::newRow("Popup") << QAccessible::Dialog; + QTest::newRow("ProgressBar") << QAccessible::ProgressBar; + QTest::newRow("RadioButton") << QAccessible::RadioButton; + QTest::newRow("RadioDelegate") << QAccessible::RadioButton; + QTest::newRow("RangeSlider") << QAccessible::Slider; + QTest::newRow("RoundButton") << QAccessible::Button; + QTest::newRow("ScrollBar") << QAccessible::ScrollBar; + QTest::newRow("ScrollIndicator") << QAccessible::Indicator; + QTest::newRow("Slider") << QAccessible::Slider; + QTest::newRow("SpinBox") << QAccessible::SpinBox; + QTest::newRow("StackView") << QAccessible::LayeredPane; + QTest::newRow("SwipeDelegate") << QAccessible::ListItem; + QTest::newRow("SwipeView") << QAccessible::PageTabList; + QTest::newRow("Switch") << QAccessible::CheckBox; + QTest::newRow("SwitchDelegate") << QAccessible::ListItem; + QTest::newRow("TabBar") << QAccessible::PageTabList; + QTest::newRow("TabButton") << QAccessible::PageTab; + QTest::newRow("TextArea") << QAccessible::EditableText; + QTest::newRow("TextField") << QAccessible::EditableText; + QTest::newRow("ToolBar") << QAccessible::ToolBar; + QTest::newRow("ToolButton") << QAccessible::Button; + QTest::newRow("ToolTip") << QAccessible::ToolTip; + QTest::newRow("Tumbler") << QAccessible::NoRole; +} + +void tst_accessibility::override() +{ + QFETCH(QAccessible::Role, role); + + const QString name = QTest::currentDataTag(); + const QString fileBaseName = name.toLower(); + + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("override/" + adjustFileBaseName(fileBaseName) + ".qml")); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + QQuickItem *item = findItem(object.data()); + QVERIFY(item); + +#if QT_CONFIG(accessibility) + QQuickAccessibleAttached *attached = QQuickAccessibleAttached::attachedProperties(item); + if (QAccessible::isActive()) { + QVERIFY(attached); + } else { + QPlatformAccessibility *accessibility = platformAccessibility(); + if (!accessibility) + QSKIP("No QPlatformAccessibility available."); + accessibility->setActive(true); + if (!attached) + attached = QQuickAccessibleAttached::attachedProperties(item); + } + + QVERIFY(attached); + QCOMPARE(attached->role(), role); + QCOMPARE(attached->name(), name + "Override"); +#else + Q_UNUSED(role); + Q_UNUSED(text); +#endif +} +template <typename Predicate> +void a11yDescendants(QAccessibleInterface *iface, Predicate pred) +{ + for (int i = 0; i < iface->childCount(); ++i) { + if (QAccessibleInterface *child = iface->child(i)) { + pred(child); + a11yDescendants(child, pred); + } + } +} + +void tst_accessibility::ordering() +{ + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("ordering/page.qml")); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + +#if QT_CONFIG(accessibility) + QQuickItem *item = findItem(object.data()); + QVERIFY(item); + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(item); + QVERIFY(iface); + QStringList strings; + a11yDescendants(iface, [&](QAccessibleInterface *iface) {strings << iface->text(QAccessible::Name);}); + QCOMPARE(strings.join(QLatin1String(", ")), "Header, Content item 1, Content item 2, Footer"); +#endif +} + +QTEST_MAIN(tst_accessibility) + +#include "tst_accessibility.moc" diff --git a/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.10.0.linux-gcc-amd64.txt b/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.10.0.linux-gcc-amd64.txt new file mode 100644 index 00000000000..1b41ce037f4 --- /dev/null +++ b/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.10.0.linux-gcc-amd64.txt @@ -0,0 +1,10983 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7fba168d6720) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7fba16930ea0) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7fba1645e120) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7fba1645e360) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7fba1645e5a0) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7fba1645e720) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7fba1645eae0) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7fba165172a0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7fba16517360) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7fba165176c0) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7fba16517780) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7fba16517840) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7fba16517900) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7fba16517ba0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7fba16517d80) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7fba16595240) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7fba165952a0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7fba165cff00) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7fba165cff60) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7fba16547340) 0 empty + std::input_iterator_tag (0x0x7fba165fe000) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7fba165473a8) 0 empty + std::forward_iterator_tag (0x0x7fba16547410) 0 empty + std::input_iterator_tag (0x0x7fba165fe060) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7fba16547478) 0 empty + std::bidirectional_iterator_tag (0x0x7fba165474e0) 0 empty + std::forward_iterator_tag (0x0x7fba16547548) 0 empty + std::input_iterator_tag (0x0x7fba165fe0c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7fba165fed20) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7fba165fed80) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7fba165fede0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7fba165fee40) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7fba165feea0) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7fba162c19c0) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7fba162c1c00) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7fba162c1cc0) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7fba162c1d20) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7fba162c1de0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7fba162c1e40) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7fba16365300) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7fba16365360) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7fba163653c0) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7fba16547a90) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7fba16365420) 0 nearly-empty + primary-for std::bad_exception (0x0x7fba16547a90) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7fba16365480) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7fba163654e0) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7fba16547c98) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7fba16365900) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fba16547c98) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7fba16547d00) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7fba16547d68) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7fba16547d00) + std::exception (0x0x7fba16365960) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fba16547d68) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7fba163659c0) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7fba160da600) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7fba15eec300) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7fba15eec360) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7fba15f8d240) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7fba15f8d2a0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7fba15f8d360) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7fba15f8d3c0) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7fba15f8d420) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7fba15f8d480) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7fba15f8d5a0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7fba15f8d600) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7fba15f8da20) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7fba15f8da80) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7fba15aac2a0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7fba15aac300) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7fba15b7d2a0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7fba159350c0) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7fba15ac6af8) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7fba15935180) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7fba15ac6b60) 0 + std::_Bit_iterator_base (0x0x7fba15ac6bc8) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7fba159351e0) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7fba15ac6c30) 0 + std::_Bit_iterator_base (0x0x7fba15ac6c98) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7fba15935240) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7fba15756060) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7fba15756de0) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7fba15756d80) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7fba1549fd80) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7fba140858a0) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7fba14085900) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7fba1416e3c0) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7fba1416e420) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7fba1416e480) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7fba1416e4e0) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7fba1416e780) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7fba1416ecc0) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7fba1415f9c0) 0 + std::__atomic_flag_base (0x0x7fba1416ed20) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7fba13d91138) 0 + QAtomicInteger<int> (0x0x7fba13d911a0) 0 + QBasicAtomicInteger<int> (0x0x7fba13d0e480) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7fba13bc5a20) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7fba139c7a80) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7fba139c7ba0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7fba13b97bc8) 0 + QGenericArgument (0x0x7fba139c7c00) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7fba139c7d80) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7fba139c7e40) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7fba13681ea0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7fba13681f00) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7fba1372b1e0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7fba1372b240) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7fba1372b5a0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7fba1372b600) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7fba1372b660) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7fba1372b6c0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7fba1372b720) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7fba1372bae0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7fba1342f138) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7fba1372bba0) 0 nearly-empty + primary-for std::logic_error (0x0x7fba1342f138) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7fba1342f1a0) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7fba1342f208) 0 + primary-for std::domain_error (0x0x7fba1342f1a0) + std::exception (0x0x7fba1372bc00) 0 nearly-empty + primary-for std::logic_error (0x0x7fba1342f208) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7fba1342f270) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7fba1342f2d8) 0 + primary-for std::invalid_argument (0x0x7fba1342f270) + std::exception (0x0x7fba1372bc60) 0 nearly-empty + primary-for std::logic_error (0x0x7fba1342f2d8) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7fba1342f340) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7fba1342f3a8) 0 + primary-for std::length_error (0x0x7fba1342f340) + std::exception (0x0x7fba1372bcc0) 0 nearly-empty + primary-for std::logic_error (0x0x7fba1342f3a8) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7fba1342f410) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7fba1342f478) 0 + primary-for std::out_of_range (0x0x7fba1342f410) + std::exception (0x0x7fba1372bd20) 0 nearly-empty + primary-for std::logic_error (0x0x7fba1342f478) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7fba1342f4e0) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7fba1372bd80) 0 nearly-empty + primary-for std::runtime_error (0x0x7fba1342f4e0) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7fba1342f548) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7fba1342f5b0) 0 + primary-for std::range_error (0x0x7fba1342f548) + std::exception (0x0x7fba1372bde0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fba1342f5b0) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7fba1342f618) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7fba1342f680) 0 + primary-for std::overflow_error (0x0x7fba1342f618) + std::exception (0x0x7fba1372be40) 0 nearly-empty + primary-for std::runtime_error (0x0x7fba1342f680) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7fba1342f6e8) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7fba1342f750) 0 + primary-for std::underflow_error (0x0x7fba1342f6e8) + std::exception (0x0x7fba1372bea0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fba1342f750) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7fba1346e060) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7fba1346e2a0) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7fba1346e420) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7fba1342fc30) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7fba1342fc98) 0 + primary-for std::system_error (0x0x7fba1342fc30) + std::exception (0x0x7fba1346e660) 0 nearly-empty + primary-for std::runtime_error (0x0x7fba1342fc98) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7fba134cc888) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7fba134cc8f0) 0 + primary-for std::ios_base::failure (0x0x7fba134cc888) + std::runtime_error (0x0x7fba134cc958) 0 + primary-for std::system_error (0x0x7fba134cc8f0) + std::exception (0x0x7fba1346e960) 0 nearly-empty + primary-for std::runtime_error (0x0x7fba134cc958) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7fba1346e9c0) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7fba1346ea20) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7fba1346ea80) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7fba1346e900) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7fba131a2240) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7fba131a2900) 0 empty + +VTT for std::basic_ostream<char> +std::basic_ostream<char>::_ZTTSo: 2u entries +0 ((& std::basic_ostream<char>::_ZTVSo) + 24u) +8 ((& std::basic_ostream<char>::_ZTVSo) + 64u) + +VTT for std::basic_ostream<wchar_t> +std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream<char> +std::basic_istream<char>::_ZTTSi: 2u entries +0 ((& std::basic_istream<char>::_ZTVSi) + 24u) +8 ((& std::basic_istream<char>::_ZTVSi) + 64u) + +VTT for std::basic_istream<wchar_t> +std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream<char> (0x0x7fba1318e208 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream<char> (0x0x7fba1318e2d8 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream<char> +std::basic_iostream<char>::_ZTTSd: 7u entries +0 ((& std::basic_iostream<char>::_ZTVSd) + 24u) +8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream<char>::_ZTVSd) + 104u) +48 ((& std::basic_iostream<char>::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7fba1318e680 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7fba1318e750 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7fba12ddd180) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7fba12ddd1e0) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7fba12edb540) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7fba12edb8a0) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7fba12edbd20) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7fba12c09ba0) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7fba12c98240) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7fba12c981e0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7fba12a41300) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7fba12a41f00) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7fba1283fb40) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7fba1283fba0) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7fba1283fc00) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7fba12676000) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7fba12676060) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7fba125bd1a0) 0 empty + QListData::NotIndirectLayout (0x0x7fba126760c0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7fba12679150) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fba12676120) 0 empty + QListData::NotIndirectLayout (0x0x7fba12676180) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7fba125bd208) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fba126761e0) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7fba12676240) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7fba1283ff60) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7fba126766c0) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7fba12420900) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7fba124208a0) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7fba1241fc30) 0 + QList<QString> (0x0x7fba1241fc98) 0 + QListSpecialMethods<QString> (0x0x7fba12420ae0) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7fba12420f00) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7fba124c2a20) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7fba122c70c0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7fba122c7240) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7fba122c7300) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7fba1249c5b0) 0 + std::__uses_alloc_base (0x0x7fba122c72a0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7fba11fb7360) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7fba11fb75a0) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7fba11fb7660) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7fba11fb7780) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7fba11fb7900) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7fba11fb7d20) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7fba11fb7e40) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7fba1211c7e0) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7fba1211cc00) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7fba1211cf00) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7fba11c0a780) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7fba11d59600) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7fba11d59660) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7fba11d59840) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7fba11d597e0) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7fba11a1fae0) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7fba11a1fb40) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7fba11a1fc00) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7fba11a487b8) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7fba11a1fba0) 0 + primary-for QAbstractAnimation (0x0x7fba11a487b8) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7fba11a1fcc0) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7fba11a48820) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7fba11a1fc60) 0 + primary-for QAnimationDriver (0x0x7fba11a48820) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7fba11a1fd80) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7fba11a48888) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7fba11a1fd20) 0 + primary-for QEventLoop (0x0x7fba11a48888) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7fba11a1ff60) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7fba11ad8060) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7fba11ad80c0) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7fba11a489c0) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7fba11ad8000) 0 + primary-for QAbstractEventDispatcher (0x0x7fba11a489c0) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7fba11ad8360) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7fba11a48bc8) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7fba11ad83c0) 0 nearly-empty + primary-for std::bad_cast (0x0x7fba11a48bc8) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7fba11a48c30) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7fba11ad8420) 0 nearly-empty + primary-for std::bad_typeid (0x0x7fba11a48c30) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7fba11799ea0) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7fba118714e0) 0 nearly-empty + primary-for std::bad_function_call (0x0x7fba11799ea0) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7fba118715a0) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7fba11871600) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7fba11871720) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7fba11871c00) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7fba11923180) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7fba11923540) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7fba119234e0) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7fba119235a0) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7fba11923e40) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7fba11923f00) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7fba11923ea0) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7fba11923f60) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7fba11923de0) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7fba11400a80) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7fba114a8120) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7fba114a80c0) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7fba114a81e0) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7fba114a8180) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7fba111c24e0) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7fba111c2ba0) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7fba10f97300) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7fba10f81c30) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7fba10f972a0) 0 + primary-for QAbstractItemModel (0x0x7fba10f81c30) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7fba10f97660) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7fba10f81e38) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7fba10f81ea0) 0 + primary-for QAbstractTableModel (0x0x7fba10f81e38) + QObject (0x0x7fba10f97600) 0 + primary-for QAbstractItemModel (0x0x7fba10f81ea0) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7fba10f97720) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7fba10f81f08) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7fba10f81f70) 0 + primary-for QAbstractListModel (0x0x7fba10f81f08) + QObject (0x0x7fba10f976c0) 0 + primary-for QAbstractItemModel (0x0x7fba10f81f70) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7fba10f979c0) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7fba10f97a80) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7fba1106e0d0) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7fba1106e138) 0 + primary-for QAbstractProxyModel (0x0x7fba1106e0d0) + QObject (0x0x7fba10f97a20) 0 + primary-for QAbstractItemModel (0x0x7fba1106e138) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7fba10f97b40) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7fba1106e1a0) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7fba10f97ae0) 0 + primary-for QAbstractState (0x0x7fba1106e1a0) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7fba10f97c00) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7fba1106e208) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7fba10f97ba0) 0 + primary-for QAbstractTransition (0x0x7fba1106e208) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7fba10f97cc0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7fba1106e270) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7fba1106e2d8) 0 + primary-for QAnimationGroup (0x0x7fba1106e270) + QObject (0x0x7fba10f97c60) 0 + primary-for QAbstractAnimation (0x0x7fba1106e2d8) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7fba1110fa20) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7fba1110fcc0) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7fba1110fd80) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7fba10da20c0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7fba1106e958) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7fba10da2060) 0 + primary-for QIODevice (0x0x7fba1106e958) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7fba10da2300) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7fba1106ea90) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7fba1106eaf8) 0 + primary-for QBuffer (0x0x7fba1106ea90) + QObject (0x0x7fba10da22a0) 0 + primary-for QIODevice (0x0x7fba1106eaf8) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7fba10da23c0) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7fba10da2360) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7fba10da24e0) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7fba10da2480) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7fba10da26c0) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7fba10da28a0) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7fba10da2ea0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7fba10da2f60) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7fba10b89f60) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7fba10bc0420) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7fba10c19000) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7fba10bc0480) 0 + primary-for QTimerEvent (0x0x7fba10c19000) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7fba10c19068) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7fba10bc04e0) 0 + primary-for QChildEvent (0x0x7fba10c19068) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7fba10c195b0) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7fba10bc09c0) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7fba10c195b0) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7fba10c19618) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7fba10bc0a20) 0 + primary-for QDeferredDeleteEvent (0x0x7fba10c19618) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7fba10bc0ae0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7fba10c19680) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7fba10bc0a80) 0 + primary-for QCoreApplication (0x0x7fba10c19680) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7fba10bc0b40) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7fba10bc0ba0) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7fba10caa1e0) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7fba10caa240) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7fba10caa300) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7fba10caa7e0) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7fba10caaa80) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7fba1097d240) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7fba1097d2a0) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7fba1097d1e0) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7fba10a263c0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7fba10a268a0) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7fba10744840) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7fba10744ae0) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7fba10744d20) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7fba10744ea0) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7fba1088f420) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7fba1088f3c0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7fba105e1900) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7fba105e19c0) 0 empty + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7fba106b1b40) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7fba106c75b0) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7fba106c7618) 0 + primary-for QFileDevice (0x0x7fba106c75b0) + QObject (0x0x7fba106b1ae0) 0 + primary-for QIODevice (0x0x7fba106c7618) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7fba106b1d80) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7fba106c7750) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7fba106c77b8) 0 + primary-for QFile (0x0x7fba106c7750) + QIODevice (0x0x7fba106c7820) 0 + primary-for QFileDevice (0x0x7fba106c77b8) + QObject (0x0x7fba106b1d20) 0 + primary-for QIODevice (0x0x7fba106c7820) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7fba106b1f60) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7fba103633c0) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7fba10363d80) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7fba10458000) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7fba104e5420) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7fba104d8a28) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7fba104d8a90) 0 + primary-for QEventTransition (0x0x7fba104d8a28) + QObject (0x0x7fba104e53c0) 0 + primary-for QAbstractTransition (0x0x7fba104d8a90) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7fba104d8af8) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7fba104e5480) 0 nearly-empty + primary-for QException (0x0x7fba104d8af8) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7fba104d8b60) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7fba104d8bc8) 0 nearly-empty + primary-for QUnhandledException (0x0x7fba104d8b60) + std::exception (0x0x7fba104e54e0) 0 nearly-empty + primary-for QException (0x0x7fba104d8bc8) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7fba104e5540) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7fba104e5600) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7fba104e5660) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7fba104e5780) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7fba104d8c30) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7fba104e5720) 0 + primary-for QFileSelector (0x0x7fba104d8c30) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7fba104e5840) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7fba104d8c98) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7fba104e57e0) 0 + primary-for QFileSystemWatcher (0x0x7fba104d8c98) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7fba104e5900) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7fba104d8d00) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7fba104d8d68) 0 + primary-for QFinalState (0x0x7fba104d8d00) + QObject (0x0x7fba104e58a0) 0 + primary-for QAbstractState (0x0x7fba104d8d68) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7fba104e5960) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7fba104e59c0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7fba104d8ea0) 0 + QBasicMutex (0x0x7fba104e5ba0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7fba104e5c00) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7fba104e5c60) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7fba104e5cc0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7fba104e5de0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7fba10268660) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7fba10268e40) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7fba10316000) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7fba10268de0) 0 + primary-for QFutureWatcherBase (0x0x7fba10316000) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7fba0ff46480) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7fba103168f0) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7fba10316958) 0 + primary-for QHistoryState (0x0x7fba103168f0) + QObject (0x0x7fba0ff46420) 0 + primary-for QAbstractState (0x0x7fba10316958) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7fba0ff46540) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7fba103169c0) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7fba10316a28) 0 + primary-for QIdentityProxyModel (0x0x7fba103169c0) + QAbstractItemModel (0x0x7fba10316a90) 0 + primary-for QAbstractProxyModel (0x0x7fba10316a28) + QObject (0x0x7fba0ff464e0) 0 + primary-for QAbstractItemModel (0x0x7fba10316a90) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7fba0ff465a0) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7fba0ff46c60) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7fba0ffb52d8) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7fba0ff46c00) 0 + primary-for QItemSelectionModel (0x0x7fba0ffb52d8) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7fba0ffb54e0) 0 + QList<QItemSelectionRange> (0x0x7fba0ffb5548) 0 + QListSpecialMethods<QItemSelectionRange> (0x0x7fba0ff46f60) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7fba1003f480) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7fba0fdb3ba0) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7fba0fe18120) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7fba0fe18180) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7fba0fe18360) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7fba0fe183c0) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7fba0fe18300) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7fba0fed4600) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7fba0fed4660) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7fba0fed4cc0) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7fba0fed4d20) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7fba0fed4c60) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7fba0fc1e000) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7fba0fbdc888) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7fba0fbc2f60) 0 + primary-for QLibrary (0x0x7fba0fbdc888) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7fba0fc1e6c0) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7fba0fc1e1e0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7fba0fc1eba0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7fba0fc1ec00) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7fba0fc1eea0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7fba0f926180) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7fba0f926ae0) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7fba0f9b4480) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7fba0f9b47e0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7fba0f9b4960) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7fba0f9b4900) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7fba0f9b4ae0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7fba0f9b4d80) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7fba0f739420) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7fba0f739480) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7fba0f739a80) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7fba0f739d80) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7fba0f739de0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7fba0f7ef120) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7fba0f756af8) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7fba0f7ef0c0) 0 + primary-for QMimeData (0x0x7fba0f756af8) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7fba0f7ef180) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7fba0f7ef480) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7fba0f7ef540) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7fba0f756d00) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7fba0f7ef4e0) 0 + primary-for QObjectCleanupHandler (0x0x7fba0f756d00) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7fba0f7ef5a0) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7fba0f7efd20) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7fba0f851410) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7fba0f851478) 0 + primary-for QParallelAnimationGroup (0x0x7fba0f851410) + QAbstractAnimation (0x0x7fba0f8514e0) 0 + primary-for QAnimationGroup (0x0x7fba0f851478) + QObject (0x0x7fba0f7efcc0) 0 + primary-for QAbstractAnimation (0x0x7fba0f8514e0) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7fba0f7efde0) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7fba0f851548) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7fba0f8515b0) 0 + primary-for QPauseAnimation (0x0x7fba0f851548) + QObject (0x0x7fba0f7efd80) 0 + primary-for QAbstractAnimation (0x0x7fba0f8515b0) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7fba0f8a2000) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7fba0f8a2300) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7fba0f8517b8) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7fba0f8a22a0) 0 + primary-for QPluginLoader (0x0x7fba0f8517b8) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7fba0f8a2360) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7fba0f8a2a20) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7fba0f851e38) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7fba0f851ea0) 0 + primary-for QProcess (0x0x7fba0f851e38) + QObject (0x0x7fba0f8a29c0) 0 + primary-for QIODevice (0x0x7fba0f851ea0) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7fba0f8a2ae0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7fba0f851f08) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7fba0f851f70) 0 + primary-for QVariantAnimation (0x0x7fba0f851f08) + QObject (0x0x7fba0f8a2a80) 0 + primary-for QAbstractAnimation (0x0x7fba0f851f70) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7fba0f8a2ba0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7fba0f52a068) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7fba0f52a0d0) 0 + primary-for QPropertyAnimation (0x0x7fba0f52a068) + QAbstractAnimation (0x0x7fba0f52a138) 0 + primary-for QVariantAnimation (0x0x7fba0f52a0d0) + QObject (0x0x7fba0f8a2b40) 0 + primary-for QAbstractAnimation (0x0x7fba0f52a138) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7fba0f8a2cc0) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7fba0f8a2c60) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7fba0f5ca410) 0 + QRandomGenerator (0x0x7fba0f5adc60) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7fba0f5add20) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7fba0f66a000) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7fba0f66a0c0) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7fba0f66a180) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7fba0f66a420) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7fba0f66a6c0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7fba0f66a960) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7fba0f66ac00) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7fba0f46a240) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7fba0f46a540) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7fba0f46a840) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7fba0f46a9c0) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7fba0f441618) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7fba0f441680) 0 + primary-for QSaveFile (0x0x7fba0f441618) + QIODevice (0x0x7fba0f4416e8) 0 + primary-for QFileDevice (0x0x7fba0f441680) + QObject (0x0x7fba0f46a960) 0 + primary-for QIODevice (0x0x7fba0f4416e8) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7fba0f46aa80) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7fba0f46aae0) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7fba0f1ee120) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7fba0f1d0f08) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7fba0f1d0f70) 0 + primary-for QSequentialAnimationGroup (0x0x7fba0f1d0f08) + QAbstractAnimation (0x0x7fba0f1f1000) 0 + primary-for QAnimationGroup (0x0x7fba0f1d0f70) + QObject (0x0x7fba0f1ee0c0) 0 + primary-for QAbstractAnimation (0x0x7fba0f1f1000) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7fba0f1ee1e0) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7fba0f1f1068) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7fba0f1ee180) 0 + primary-for QSettings (0x0x7fba0f1f1068) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7fba0f1ee2a0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7fba0f1f10d0) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7fba0f1ee240) 0 + primary-for QSharedMemory (0x0x7fba0f1f10d0) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7fba0f1ee360) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7fba0f1f1138) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7fba0f1ee300) 0 + primary-for QSignalMapper (0x0x7fba0f1f1138) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7fba0f1ee420) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7fba0f1f11a0) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7fba0f1f1208) 0 + primary-for QSignalTransition (0x0x7fba0f1f11a0) + QObject (0x0x7fba0f1ee3c0) 0 + primary-for QAbstractTransition (0x0x7fba0f1f1208) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7fba0f1ee4e0) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7fba0f1f1270) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7fba0f1ee480) 0 + primary-for QSocketNotifier (0x0x7fba0f1f1270) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7fba0f1ee5a0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7fba0f1f12d8) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7fba0f1f1340) 0 + primary-for QSortFilterProxyModel (0x0x7fba0f1f12d8) + QAbstractItemModel (0x0x7fba0f1f13a8) 0 + primary-for QAbstractProxyModel (0x0x7fba0f1f1340) + QObject (0x0x7fba0f1ee540) 0 + primary-for QAbstractItemModel (0x0x7fba0f1f13a8) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7fba0f1ee660) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7fba0f1ee8a0) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7fba0f1f1548) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7fba0f1f15b0) 0 + primary-for QState (0x0x7fba0f1f1548) + QObject (0x0x7fba0f1ee840) 0 + primary-for QAbstractState (0x0x7fba0f1f15b0) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7fba0f1ee9c0) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7fba0f1f1750) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7fba0f1eea20) 0 + primary-for QStateMachine::SignalEvent (0x0x7fba0f1f1750) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7fba0f1f17b8) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7fba0f1eea80) 0 + primary-for QStateMachine::WrappedEvent (0x0x7fba0f1f17b8) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7fba0f1f1618) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7fba0f1f1680) 0 + primary-for QStateMachine (0x0x7fba0f1f1618) + QAbstractState (0x0x7fba0f1f16e8) 0 + primary-for QState (0x0x7fba0f1f1680) + QObject (0x0x7fba0f1ee960) 0 + primary-for QAbstractState (0x0x7fba0f1f16e8) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7fba0f1eeae0) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7fba0ef37a20) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7fba0efad540) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7fba0ef55c98) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7fba0ef55d00) 0 + primary-for QStringListModel (0x0x7fba0ef55c98) + QAbstractItemModel (0x0x7fba0ef55d68) 0 + primary-for QAbstractListModel (0x0x7fba0ef55d00) + QObject (0x0x7fba0efad4e0) 0 + primary-for QAbstractItemModel (0x0x7fba0ef55d68) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7fba0efad5a0) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7fba0efad660) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7fba0efad780) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7fba0ef55dd0) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7fba0ef55e38) 0 + primary-for QTemporaryFile (0x0x7fba0ef55dd0) + QFileDevice (0x0x7fba0ef55ea0) 0 + primary-for QFile (0x0x7fba0ef55e38) + QIODevice (0x0x7fba0ef55f08) 0 + primary-for QFileDevice (0x0x7fba0ef55ea0) + QObject (0x0x7fba0efad720) 0 + primary-for QIODevice (0x0x7fba0ef55f08) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7fba0efad7e0) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7fba0efada20) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7fba0efad9c0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7fba0efadc00) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7fba0efadc60) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7fba0efadcc0) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7fba0efadd20) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7fba0f033138) 0 + std::__mutex_base (0x0x7fba0efadd80) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7fba0f0331a0) 0 + std::__recursive_mutex_base (0x0x7fba0efadde0) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7fba0f0bff50) 0 + std::__mutex_base (0x0x7fba0efadf00) 0 + std::__timed_mutex_impl<std::timed_mutex> (0x0x7fba0efadf60) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7fba0f0d6bd0) 0 + std::__recursive_mutex_base (0x0x7fba0f0e2060) 0 + std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7fba0f0e20c0) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7fba0f0e2120) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7fba0f0e2180) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7fba0f0e21e0) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7fba0f0e2420) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7fba0f0332d8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7fba0f0e24e0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7fba0f0332d8) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7fba0f033340) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7fba0f0e25a0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7fba0f033340) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7fba0f0333a8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7fba0f0e2660) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7fba0f0333a8) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7fba0f033478) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7fba0f0e2720) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7fba0f033478) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7fba0f0e27e0) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7fba0f0e2840) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7fba0f0e28a0) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7fba0f0e2900) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7fba0f033750) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7fba0f0e2c60) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7fba0f033750) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7fba0ee304e0) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7fba0ee30cc0) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7fba0ee30ea0) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7fba0ee30f00) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7fba0ee30e40) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7fba0ecddb40) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7fba0ecddc00) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7fba0ecddc60) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7fba0e9ca300) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7fba0e9c5a90) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7fba0e9c5af8) 0 + primary-for std::future_error (0x0x7fba0e9c5a90) + std::exception (0x0x7fba0e9ca420) 0 nearly-empty + primary-for std::logic_error (0x0x7fba0e9c5af8) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7fba0e9ca540) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7fba0e9ca4e0) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7fba0e707a80) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7fba0e7280d0) 0 + std::__at_thread_exit_elt (0x0x7fba0e707b40) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7fba0e9ca6c0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7fba0e9ca480) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7fba0e470c98) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7fba0e472a20) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7fba0e470c98) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7fba0e0f3180) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7fba0e4d4750) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7fba0e0f3120) 0 + primary-for QThread (0x0x7fba0e4d4750) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7fba0e0f32a0) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7fba0e4d47b8) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7fba0e0f3240) 0 + primary-for QThreadPool (0x0x7fba0e4d47b8) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7fba0e0f3300) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7fba0e0f3420) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7fba0e4d4820) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7fba0e0f33c0) 0 + primary-for QTimeLine (0x0x7fba0e4d4820) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7fba0e0f34e0) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7fba0e4d4888) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7fba0e0f3480) 0 + primary-for QTimer (0x0x7fba0e4d4888) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7fba0e0f3ba0) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7fba0e0f3b40) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7fba0e1c3180) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7fba0e1bc2d8) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7fba0e1c3120) 0 + primary-for QTranslator (0x0x7fba0e1bc2d8) + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7fba0e1c32a0) 0 + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7fba0e2da960) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7fba0df79000) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7fba0df79600) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7fba0df79660) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7fba0df79960) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7fba0df78dd0) 0 + QVector<QXmlStreamAttribute> (0x0x7fba0df79d20) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7fba0df79d80) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7fba0e064060) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7fba0e064300) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7fba0e0645a0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7fba0e064600) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7fba0dd12060) 0 + +Class QRgba64 + size=8 align=8 + base size=8 base align=8 +QRgba64 (0x0x7fba0dd12180) 0 + +Class QColor + size=16 align=4 + base size=14 base align=4 +QColor (0x0x7fba0dd12420) 0 + +Class QRegion::QRegionData + size=16 align=8 + base size=16 base align=8 +QRegion::QRegionData (0x0x7fba0dd12de0) 0 + +Class QRegion + size=8 align=8 + base size=8 base align=8 +QRegion (0x0x7fba0dd12d80) 0 + +Class QKeySequence + size=8 align=8 + base size=8 base align=8 +QKeySequence (0x0x7fba0decb180) 0 + +Class QVector2D + size=8 align=4 + base size=8 base align=4 +QVector2D (0x0x7fba0db656c0) 0 + +Class QTouchDevice + size=8 align=8 + base size=8 base align=8 +QTouchDevice (0x0x7fba0db65960) 0 + +Vtable for QInputEvent +QInputEvent::_ZTV11QInputEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QInputEvent) +16 (int (*)(...))QInputEvent::~QInputEvent +24 (int (*)(...))QInputEvent::~QInputEvent + +Class QInputEvent + size=32 align=8 + base size=32 base align=8 +QInputEvent (0x0x7fba0db64bc8) 0 + vptr=((& QInputEvent::_ZTV11QInputEvent) + 16u) + QEvent (0x0x7fba0db65b40) 0 + primary-for QInputEvent (0x0x7fba0db64bc8) + +Vtable for QEnterEvent +QEnterEvent::_ZTV11QEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QEnterEvent) +16 (int (*)(...))QEnterEvent::~QEnterEvent +24 (int (*)(...))QEnterEvent::~QEnterEvent + +Class QEnterEvent + size=72 align=8 + base size=72 base align=8 +QEnterEvent (0x0x7fba0db64c30) 0 + vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16u) + QEvent (0x0x7fba0db65ba0) 0 + primary-for QEnterEvent (0x0x7fba0db64c30) + +Vtable for QMouseEvent +QMouseEvent::_ZTV11QMouseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMouseEvent) +16 (int (*)(...))QMouseEvent::~QMouseEvent +24 (int (*)(...))QMouseEvent::~QMouseEvent + +Class QMouseEvent + size=104 align=8 + base size=100 base align=8 +QMouseEvent (0x0x7fba0db64c98) 0 + vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16u) + QInputEvent (0x0x7fba0db64d00) 0 + primary-for QMouseEvent (0x0x7fba0db64c98) + QEvent (0x0x7fba0db65c00) 0 + primary-for QInputEvent (0x0x7fba0db64d00) + +Vtable for QHoverEvent +QHoverEvent::_ZTV11QHoverEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHoverEvent) +16 (int (*)(...))QHoverEvent::~QHoverEvent +24 (int (*)(...))QHoverEvent::~QHoverEvent + +Class QHoverEvent + size=64 align=8 + base size=64 base align=8 +QHoverEvent (0x0x7fba0db64d68) 0 + vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16u) + QInputEvent (0x0x7fba0db64dd0) 0 + primary-for QHoverEvent (0x0x7fba0db64d68) + QEvent (0x0x7fba0db65c60) 0 + primary-for QInputEvent (0x0x7fba0db64dd0) + +Vtable for QWheelEvent +QWheelEvent::_ZTV11QWheelEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWheelEvent) +16 (int (*)(...))QWheelEvent::~QWheelEvent +24 (int (*)(...))QWheelEvent::~QWheelEvent + +Class QWheelEvent + size=96 align=8 + base size=96 base align=8 +QWheelEvent (0x0x7fba0db64e38) 0 + vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16u) + QInputEvent (0x0x7fba0db64ea0) 0 + primary-for QWheelEvent (0x0x7fba0db64e38) + QEvent (0x0x7fba0db65cc0) 0 + primary-for QInputEvent (0x0x7fba0db64ea0) + +Vtable for QTabletEvent +QTabletEvent::_ZTV12QTabletEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTabletEvent) +16 (int (*)(...))QTabletEvent::~QTabletEvent +24 (int (*)(...))QTabletEvent::~QTabletEvent + +Class QTabletEvent + size=128 align=8 + base size=128 base align=8 +QTabletEvent (0x0x7fba0db64f08) 0 + vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16u) + QInputEvent (0x0x7fba0db64f70) 0 + primary-for QTabletEvent (0x0x7fba0db64f08) + QEvent (0x0x7fba0db65d20) 0 + primary-for QInputEvent (0x0x7fba0db64f70) + +Vtable for QNativeGestureEvent +QNativeGestureEvent::_ZTV19QNativeGestureEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNativeGestureEvent) +16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent + +Class QNativeGestureEvent + size=112 align=8 + base size=112 base align=8 +QNativeGestureEvent (0x0x7fba0dc6f000) 0 + vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16u) + QInputEvent (0x0x7fba0dc6f068) 0 + primary-for QNativeGestureEvent (0x0x7fba0dc6f000) + QEvent (0x0x7fba0db65d80) 0 + primary-for QInputEvent (0x0x7fba0dc6f068) + +Vtable for QKeyEvent +QKeyEvent::_ZTV9QKeyEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QKeyEvent) +16 (int (*)(...))QKeyEvent::~QKeyEvent +24 (int (*)(...))QKeyEvent::~QKeyEvent + +Class QKeyEvent + size=64 align=8 + base size=59 base align=8 +QKeyEvent (0x0x7fba0dc6f0d0) 0 + vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16u) + QInputEvent (0x0x7fba0dc6f138) 0 + primary-for QKeyEvent (0x0x7fba0dc6f0d0) + QEvent (0x0x7fba0db65de0) 0 + primary-for QInputEvent (0x0x7fba0dc6f138) + +Vtable for QFocusEvent +QFocusEvent::_ZTV11QFocusEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusEvent) +16 (int (*)(...))QFocusEvent::~QFocusEvent +24 (int (*)(...))QFocusEvent::~QFocusEvent + +Class QFocusEvent + size=24 align=8 + base size=24 base align=8 +QFocusEvent (0x0x7fba0dc6f1a0) 0 + vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16u) + QEvent (0x0x7fba0db65e40) 0 + primary-for QFocusEvent (0x0x7fba0dc6f1a0) + +Vtable for QPaintEvent +QPaintEvent::_ZTV11QPaintEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPaintEvent) +16 (int (*)(...))QPaintEvent::~QPaintEvent +24 (int (*)(...))QPaintEvent::~QPaintEvent + +Class QPaintEvent + size=56 align=8 + base size=49 base align=8 +QPaintEvent (0x0x7fba0dc6f208) 0 + vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16u) + QEvent (0x0x7fba0db65ea0) 0 + primary-for QPaintEvent (0x0x7fba0dc6f208) + +Vtable for QMoveEvent +QMoveEvent::_ZTV10QMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QMoveEvent) +16 (int (*)(...))QMoveEvent::~QMoveEvent +24 (int (*)(...))QMoveEvent::~QMoveEvent + +Class QMoveEvent + size=40 align=8 + base size=36 base align=8 +QMoveEvent (0x0x7fba0dc6f270) 0 + vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16u) + QEvent (0x0x7fba0db65f00) 0 + primary-for QMoveEvent (0x0x7fba0dc6f270) + +Vtable for QExposeEvent +QExposeEvent::_ZTV12QExposeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QExposeEvent) +16 (int (*)(...))QExposeEvent::~QExposeEvent +24 (int (*)(...))QExposeEvent::~QExposeEvent + +Class QExposeEvent + size=32 align=8 + base size=32 base align=8 +QExposeEvent (0x0x7fba0dc6f2d8) 0 + vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16u) + QEvent (0x0x7fba0db65f60) 0 + primary-for QExposeEvent (0x0x7fba0dc6f2d8) + +Vtable for QPlatformSurfaceEvent +QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent) +16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent + +Class QPlatformSurfaceEvent + size=24 align=8 + base size=24 base align=8 +QPlatformSurfaceEvent (0x0x7fba0dc6f340) 0 + vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16u) + QEvent (0x0x7fba0dca4000) 0 + primary-for QPlatformSurfaceEvent (0x0x7fba0dc6f340) + +Vtable for QResizeEvent +QResizeEvent::_ZTV12QResizeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QResizeEvent) +16 (int (*)(...))QResizeEvent::~QResizeEvent +24 (int (*)(...))QResizeEvent::~QResizeEvent + +Class QResizeEvent + size=40 align=8 + base size=36 base align=8 +QResizeEvent (0x0x7fba0dc6f3a8) 0 + vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16u) + QEvent (0x0x7fba0dca4060) 0 + primary-for QResizeEvent (0x0x7fba0dc6f3a8) + +Vtable for QCloseEvent +QCloseEvent::_ZTV11QCloseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QCloseEvent) +16 (int (*)(...))QCloseEvent::~QCloseEvent +24 (int (*)(...))QCloseEvent::~QCloseEvent + +Class QCloseEvent + size=24 align=8 + base size=20 base align=8 +QCloseEvent (0x0x7fba0dc6f410) 0 + vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16u) + QEvent (0x0x7fba0dca40c0) 0 + primary-for QCloseEvent (0x0x7fba0dc6f410) + +Vtable for QIconDragEvent +QIconDragEvent::_ZTV14QIconDragEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QIconDragEvent) +16 (int (*)(...))QIconDragEvent::~QIconDragEvent +24 (int (*)(...))QIconDragEvent::~QIconDragEvent + +Class QIconDragEvent + size=24 align=8 + base size=20 base align=8 +QIconDragEvent (0x0x7fba0dc6f478) 0 + vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16u) + QEvent (0x0x7fba0dca4120) 0 + primary-for QIconDragEvent (0x0x7fba0dc6f478) + +Vtable for QShowEvent +QShowEvent::_ZTV10QShowEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QShowEvent) +16 (int (*)(...))QShowEvent::~QShowEvent +24 (int (*)(...))QShowEvent::~QShowEvent + +Class QShowEvent + size=24 align=8 + base size=20 base align=8 +QShowEvent (0x0x7fba0dc6f4e0) 0 + vptr=((& QShowEvent::_ZTV10QShowEvent) + 16u) + QEvent (0x0x7fba0dca4180) 0 + primary-for QShowEvent (0x0x7fba0dc6f4e0) + +Vtable for QHideEvent +QHideEvent::_ZTV10QHideEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHideEvent) +16 (int (*)(...))QHideEvent::~QHideEvent +24 (int (*)(...))QHideEvent::~QHideEvent + +Class QHideEvent + size=24 align=8 + base size=20 base align=8 +QHideEvent (0x0x7fba0dc6f548) 0 + vptr=((& QHideEvent::_ZTV10QHideEvent) + 16u) + QEvent (0x0x7fba0dca41e0) 0 + primary-for QHideEvent (0x0x7fba0dc6f548) + +Vtable for QContextMenuEvent +QContextMenuEvent::_ZTV17QContextMenuEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QContextMenuEvent) +16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent + +Class QContextMenuEvent + size=56 align=8 + base size=49 base align=8 +QContextMenuEvent (0x0x7fba0dc6f5b0) 0 + vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16u) + QInputEvent (0x0x7fba0dc6f618) 0 + primary-for QContextMenuEvent (0x0x7fba0dc6f5b0) + QEvent (0x0x7fba0dca4240) 0 + primary-for QInputEvent (0x0x7fba0dc6f618) + +Class QInputMethodEvent::Attribute + size=32 align=8 + base size=32 base align=8 +QInputMethodEvent::Attribute (0x0x7fba0dca4300) 0 + +Vtable for QInputMethodEvent +QInputMethodEvent::_ZTV17QInputMethodEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QInputMethodEvent) +16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent + +Class QInputMethodEvent + size=56 align=8 + base size=56 base align=8 +QInputMethodEvent (0x0x7fba0dc6f680) 0 + vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16u) + QEvent (0x0x7fba0dca42a0) 0 + primary-for QInputMethodEvent (0x0x7fba0dc6f680) + +Class QInputMethodQueryEvent::QueryPair + size=24 align=8 + base size=24 base align=8 +QInputMethodQueryEvent::QueryPair (0x0x7fba0dca4780) 0 + +Vtable for QInputMethodQueryEvent +QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent) +16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent + +Class QInputMethodQueryEvent + size=32 align=8 + base size=32 base align=8 +QInputMethodQueryEvent (0x0x7fba0dc6f9c0) 0 + vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16u) + QEvent (0x0x7fba0dca4720) 0 + primary-for QInputMethodQueryEvent (0x0x7fba0dc6f9c0) + +Vtable for QDropEvent +QDropEvent::_ZTV10QDropEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDropEvent) +16 (int (*)(...))QDropEvent::~QDropEvent +24 (int (*)(...))QDropEvent::~QDropEvent + +Class QDropEvent + size=72 align=8 + base size=72 base align=8 +QDropEvent (0x0x7fba0dc6fc98) 0 + vptr=((& QDropEvent::_ZTV10QDropEvent) + 16u) + QEvent (0x0x7fba0dca4ae0) 0 + primary-for QDropEvent (0x0x7fba0dc6fc98) + +Vtable for QDragMoveEvent +QDragMoveEvent::_ZTV14QDragMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDragMoveEvent) +16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent + +Class QDragMoveEvent + size=88 align=8 + base size=88 base align=8 +QDragMoveEvent (0x0x7fba0dc6fd00) 0 + vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16u) + QDropEvent (0x0x7fba0dc6fd68) 0 + primary-for QDragMoveEvent (0x0x7fba0dc6fd00) + QEvent (0x0x7fba0dca4b40) 0 + primary-for QDropEvent (0x0x7fba0dc6fd68) + +Vtable for QDragEnterEvent +QDragEnterEvent::_ZTV15QDragEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragEnterEvent) +16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent + +Class QDragEnterEvent + size=88 align=8 + base size=88 base align=8 +QDragEnterEvent (0x0x7fba0dc6fdd0) 0 + vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16u) + QDragMoveEvent (0x0x7fba0dc6fe38) 0 + primary-for QDragEnterEvent (0x0x7fba0dc6fdd0) + QDropEvent (0x0x7fba0dc6fea0) 0 + primary-for QDragMoveEvent (0x0x7fba0dc6fe38) + QEvent (0x0x7fba0dca4ba0) 0 + primary-for QDropEvent (0x0x7fba0dc6fea0) + +Vtable for QDragLeaveEvent +QDragLeaveEvent::_ZTV15QDragLeaveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragLeaveEvent) +16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent + +Class QDragLeaveEvent + size=24 align=8 + base size=20 base align=8 +QDragLeaveEvent (0x0x7fba0dc6ff08) 0 + vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16u) + QEvent (0x0x7fba0dca4c00) 0 + primary-for QDragLeaveEvent (0x0x7fba0dc6ff08) + +Vtable for QHelpEvent +QHelpEvent::_ZTV10QHelpEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHelpEvent) +16 (int (*)(...))QHelpEvent::~QHelpEvent +24 (int (*)(...))QHelpEvent::~QHelpEvent + +Class QHelpEvent + size=40 align=8 + base size=36 base align=8 +QHelpEvent (0x0x7fba0dc6ff70) 0 + vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16u) + QEvent (0x0x7fba0dca4c60) 0 + primary-for QHelpEvent (0x0x7fba0dc6ff70) + +Vtable for QStatusTipEvent +QStatusTipEvent::_ZTV15QStatusTipEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QStatusTipEvent) +16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent + +Class QStatusTipEvent + size=32 align=8 + base size=32 base align=8 +QStatusTipEvent (0x0x7fba0d972000) 0 + vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16u) + QEvent (0x0x7fba0dca4cc0) 0 + primary-for QStatusTipEvent (0x0x7fba0d972000) + +Vtable for QWhatsThisClickedEvent +QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent) +16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent + +Class QWhatsThisClickedEvent + size=32 align=8 + base size=32 base align=8 +QWhatsThisClickedEvent (0x0x7fba0d972068) 0 + vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16u) + QEvent (0x0x7fba0dca4d20) 0 + primary-for QWhatsThisClickedEvent (0x0x7fba0d972068) + +Vtable for QActionEvent +QActionEvent::_ZTV12QActionEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionEvent) +16 (int (*)(...))QActionEvent::~QActionEvent +24 (int (*)(...))QActionEvent::~QActionEvent + +Class QActionEvent + size=40 align=8 + base size=40 base align=8 +QActionEvent (0x0x7fba0d9720d0) 0 + vptr=((& QActionEvent::_ZTV12QActionEvent) + 16u) + QEvent (0x0x7fba0dca4d80) 0 + primary-for QActionEvent (0x0x7fba0d9720d0) + +Vtable for QFileOpenEvent +QFileOpenEvent::_ZTV14QFileOpenEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QFileOpenEvent) +16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent + +Class QFileOpenEvent + size=40 align=8 + base size=40 base align=8 +QFileOpenEvent (0x0x7fba0d972138) 0 + vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16u) + QEvent (0x0x7fba0dca4de0) 0 + primary-for QFileOpenEvent (0x0x7fba0d972138) + +Vtable for QToolBarChangeEvent +QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QToolBarChangeEvent) +16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent + +Class QToolBarChangeEvent + size=24 align=8 + base size=21 base align=8 +QToolBarChangeEvent (0x0x7fba0d9721a0) 0 + vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16u) + QEvent (0x0x7fba0dca4e40) 0 + primary-for QToolBarChangeEvent (0x0x7fba0d9721a0) + +Vtable for QShortcutEvent +QShortcutEvent::_ZTV14QShortcutEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QShortcutEvent) +16 (int (*)(...))QShortcutEvent::~QShortcutEvent +24 (int (*)(...))QShortcutEvent::~QShortcutEvent + +Class QShortcutEvent + size=40 align=8 + base size=40 base align=8 +QShortcutEvent (0x0x7fba0d972208) 0 + vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16u) + QEvent (0x0x7fba0dca4ea0) 0 + primary-for QShortcutEvent (0x0x7fba0d972208) + +Vtable for QWindowStateChangeEvent +QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent) +16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent + +Class QWindowStateChangeEvent + size=32 align=8 + base size=25 base align=8 +QWindowStateChangeEvent (0x0x7fba0d972270) 0 + vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16u) + QEvent (0x0x7fba0dca4f00) 0 + primary-for QWindowStateChangeEvent (0x0x7fba0d972270) + +Class QPointingDeviceUniqueId + size=8 align=8 + base size=8 base align=8 +QPointingDeviceUniqueId (0x0x7fba0dca4f60) 0 + +Class QTouchEvent::TouchPoint + size=8 align=8 + base size=8 base align=8 +QTouchEvent::TouchPoint (0x0x7fba0d9a0660) 0 + +Vtable for QTouchEvent +QTouchEvent::_ZTV11QTouchEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTouchEvent) +16 (int (*)(...))QTouchEvent::~QTouchEvent +24 (int (*)(...))QTouchEvent::~QTouchEvent + +Class QTouchEvent + size=72 align=8 + base size=72 base align=8 +QTouchEvent (0x0x7fba0d9728f0) 0 + vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16u) + QInputEvent (0x0x7fba0d972958) 0 + primary-for QTouchEvent (0x0x7fba0d9728f0) + QEvent (0x0x7fba0d9a0600) 0 + primary-for QInputEvent (0x0x7fba0d972958) + +Vtable for QScrollPrepareEvent +QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollPrepareEvent) +16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent + +Class QScrollPrepareEvent + size=112 align=8 + base size=112 base align=8 +QScrollPrepareEvent (0x0x7fba0da831a0) 0 + vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16u) + QEvent (0x0x7fba0da6acc0) 0 + primary-for QScrollPrepareEvent (0x0x7fba0da831a0) + +Vtable for QScrollEvent +QScrollEvent::_ZTV12QScrollEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QScrollEvent) +16 (int (*)(...))QScrollEvent::~QScrollEvent +24 (int (*)(...))QScrollEvent::~QScrollEvent + +Class QScrollEvent + size=64 align=8 + base size=60 base align=8 +QScrollEvent (0x0x7fba0da83208) 0 + vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16u) + QEvent (0x0x7fba0da6ad20) 0 + primary-for QScrollEvent (0x0x7fba0da83208) + +Vtable for QScreenOrientationChangeEvent +QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent) +16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent + +Class QScreenOrientationChangeEvent + size=40 align=8 + base size=36 base align=8 +QScreenOrientationChangeEvent (0x0x7fba0da83270) 0 + vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16u) + QEvent (0x0x7fba0da6ad80) 0 + primary-for QScreenOrientationChangeEvent (0x0x7fba0da83270) + +Vtable for QApplicationStateChangeEvent +QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent) +16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent + +Class QApplicationStateChangeEvent + size=24 align=8 + base size=24 base align=8 +QApplicationStateChangeEvent (0x0x7fba0da832d8) 0 + vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16u) + QEvent (0x0x7fba0da6ade0) 0 + primary-for QApplicationStateChangeEvent (0x0x7fba0da832d8) + +Class QFont + size=16 align=8 + base size=12 base align=8 +QFont (0x0x7fba0da6ae40) 0 + +Class QPolygon + size=8 align=8 + base size=8 base align=8 +QPolygon (0x0x7fba0d751068) 0 + QVector<QPoint> (0x0x7fba0d71bb40) 0 + +Class QPolygonF + size=8 align=8 + base size=8 base align=8 +QPolygonF (0x0x7fba0d751410) 0 + QVector<QPointF> (0x0x7fba0d7cf000) 0 + +Class QMatrix + size=48 align=8 + base size=48 base align=8 +QMatrix (0x0x7fba0d7cf3c0) 0 + +Class QPainterPath::Element + size=24 align=8 + base size=24 base align=8 +QPainterPath::Element (0x0x7fba0d7cf6c0) 0 + +Class QPainterPath + size=8 align=8 + base size=8 base align=8 +QPainterPath (0x0x7fba0d7cf660) 0 + +Class QPainterPathStroker + size=8 align=8 + base size=8 base align=8 +QPainterPathStroker (0x0x7fba0d89f0c0) 0 + +Class QTransform + size=88 align=8 + base size=88 base align=8 +QTransform (0x0x7fba0d89f1e0) 0 + +Vtable for QPaintDevice +QPaintDevice::_ZTV12QPaintDevice: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDevice + size=24 align=8 + base size=24 base align=8 +QPaintDevice (0x0x7fba0d89f900) 0 + vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u) + +Class QPixelFormat + size=8 align=8 + base size=8 base align=8 +QPixelFormat (0x0x7fba0d89f960) 0 + +Vtable for QImage +QImage::_ZTV6QImage: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QImage) +16 (int (*)(...))QImage::~QImage +24 (int (*)(...))QImage::~QImage +32 (int (*)(...))QImage::devType +40 (int (*)(...))QImage::paintEngine +48 (int (*)(...))QImage::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QImage + size=32 align=8 + base size=32 base align=8 +QImage (0x0x7fba0d5c72d8) 0 + vptr=((& QImage::_ZTV6QImage) + 16u) + QPaintDevice (0x0x7fba0d5c2420) 0 + primary-for QImage (0x0x7fba0d5c72d8) + +Vtable for QPixmap +QPixmap::_ZTV7QPixmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QPixmap) +16 (int (*)(...))QPixmap::~QPixmap +24 (int (*)(...))QPixmap::~QPixmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPixmap + size=32 align=8 + base size=32 base align=8 +QPixmap (0x0x7fba0d68ae38) 0 + vptr=((& QPixmap::_ZTV7QPixmap) + 16u) + QPaintDevice (0x0x7fba0d6953c0) 0 + primary-for QPixmap (0x0x7fba0d68ae38) + +Class QBrush + size=8 align=8 + base size=8 base align=8 +QBrush (0x0x7fba0d6956c0) 0 + +Class QBrushData + size=112 align=8 + base size=112 base align=8 +QBrushData (0x0x7fba0d695e40) 0 + +Class QGradient + size=64 align=8 + base size=64 base align=8 +QGradient (0x0x7fba0d695ea0) 0 + +Class QLinearGradient + size=64 align=8 + base size=64 base align=8 +QLinearGradient (0x0x7fba0d1f27b8) 0 + QGradient (0x0x7fba0d26f180) 0 + +Class QRadialGradient + size=64 align=8 + base size=64 base align=8 +QRadialGradient (0x0x7fba0d1f2820) 0 + QGradient (0x0x7fba0d26f1e0) 0 + +Class QConicalGradient + size=64 align=8 + base size=64 base align=8 +QConicalGradient (0x0x7fba0d1f2888) 0 + QGradient (0x0x7fba0d26f240) 0 + +Class QPen + size=8 align=8 + base size=8 base align=8 +QPen (0x0x7fba0d26f2a0) 0 + +Class QTextOption::Tab + size=16 align=8 + base size=14 base align=8 +QTextOption::Tab (0x0x7fba0d3174e0) 0 + +Class QTextOption + size=32 align=8 + base size=32 base align=8 +QTextOption (0x0x7fba0d317480) 0 + +Class QTextLength + size=16 align=8 + base size=16 base align=8 +QTextLength (0x0x7fba0d317c60) 0 + +Class QTextFormat + size=16 align=8 + base size=12 base align=8 +QTextFormat (0x0x7fba0d39e3c0) 0 + +Class QTextCharFormat + size=16 align=8 + base size=12 base align=8 +QTextCharFormat (0x0x7fba0d013958) 0 + QTextFormat (0x0x7fba0d06f240) 0 + +Class QTextBlockFormat + size=16 align=8 + base size=12 base align=8 +QTextBlockFormat (0x0x7fba0d013b60) 0 + QTextFormat (0x0x7fba0d06f4e0) 0 + +Class QTextListFormat + size=16 align=8 + base size=12 base align=8 +QTextListFormat (0x0x7fba0d013dd0) 0 + QTextFormat (0x0x7fba0d06f780) 0 + +Class QTextImageFormat + size=16 align=8 + base size=12 base align=8 +QTextImageFormat (0x0x7fba0d0130d0) 0 + QTextCharFormat (0x0x7fba0d013270) 0 + QTextFormat (0x0x7fba0d06fa20) 0 + +Class QTextFrameFormat + size=16 align=8 + base size=12 base align=8 +QTextFrameFormat (0x0x7fba0d12f0d0) 0 + QTextFormat (0x0x7fba0d06fcc0) 0 + +Class QTextTableFormat + size=16 align=8 + base size=12 base align=8 +QTextTableFormat (0x0x7fba0d12f2d8) 0 + QTextFrameFormat (0x0x7fba0d12f340) 0 + QTextFormat (0x0x7fba0d06ff60) 0 + +Class QTextTableCellFormat + size=16 align=8 + base size=12 base align=8 +QTextTableCellFormat (0x0x7fba0d12f548) 0 + QTextCharFormat (0x0x7fba0d12f5b0) 0 + QTextFormat (0x0x7fba0d16b2a0) 0 + +Class QFontDatabase + size=8 align=8 + base size=8 base align=8 +QFontDatabase (0x0x7fba0d16b540) 0 + +Class QRawFont + size=8 align=8 + base size=8 base align=8 +QRawFont (0x0x7fba0d16b5a0) 0 + +Class QGlyphRun + size=8 align=8 + base size=8 base align=8 +QGlyphRun (0x0x7fba0d16ba80) 0 + +Class QTextCursor + size=8 align=8 + base size=8 base align=8 +QTextCursor (0x0x7fba0d16bd80) 0 + +Class QTextInlineObject + size=16 align=8 + base size=16 base align=8 +QTextInlineObject (0x0x7fba0ce5b0c0) 0 + +Class QTextLayout::FormatRange + size=24 align=8 + base size=24 base align=8 +QTextLayout::FormatRange (0x0x7fba0ce5b180) 0 + +Class QTextLayout + size=8 align=8 + base size=8 base align=8 +QTextLayout (0x0x7fba0ce5b120) 0 + +Class QTextLine + size=16 align=8 + base size=16 base align=8 +QTextLine (0x0x7fba0ce5bba0) 0 + +Vtable for QAbstractUndoItem +QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractUndoItem) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAbstractUndoItem + size=8 align=8 + base size=8 base align=8 +QAbstractUndoItem (0x0x7fba0ce5bc00) 0 nearly-empty + vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16u) + +Class QTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextDocument::QPrivateSignal (0x0x7fba0ce5bcc0) 0 empty + +Vtable for QTextDocument +QTextDocument::_ZTV13QTextDocument: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QTextDocument) +16 (int (*)(...))QTextDocument::metaObject +24 (int (*)(...))QTextDocument::qt_metacast +32 (int (*)(...))QTextDocument::qt_metacall +40 (int (*)(...))QTextDocument::~QTextDocument +48 (int (*)(...))QTextDocument::~QTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextDocument::clear +120 (int (*)(...))QTextDocument::createObject +128 (int (*)(...))QTextDocument::loadResource + +Class QTextDocument + size=16 align=8 + base size=16 base align=8 +QTextDocument (0x0x7fba0ceb78f0) 0 + vptr=((& QTextDocument::_ZTV13QTextDocument) + 16u) + QObject (0x0x7fba0ce5bc60) 0 + primary-for QTextDocument (0x0x7fba0ceb78f0) + +Class QPalette::Data + size=4 align=4 + base size=4 base align=4 +QPalette::Data (0x0x7fba0ce5bf00) 0 + +Class QPalette + size=16 align=8 + base size=12 base align=8 +QPalette (0x0x7fba0ce5bea0) 0 + +Class QAbstractTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTextDocumentLayout::QPrivateSignal (0x0x7fba0cc12000) 0 empty + +Class QAbstractTextDocumentLayout::Selection + size=24 align=8 + base size=24 base align=8 +QAbstractTextDocumentLayout::Selection (0x0x7fba0cc12060) 0 + +Class QAbstractTextDocumentLayout::PaintContext + size=64 align=8 + base size=64 base align=8 +QAbstractTextDocumentLayout::PaintContext (0x0x7fba0cc120c0) 0 + +Vtable for QAbstractTextDocumentLayout +QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout) +16 (int (*)(...))QAbstractTextDocumentLayout::metaObject +24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast +32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QAbstractTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QAbstractTextDocumentLayout (0x0x7fba0cbed618) 0 + vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16u) + QObject (0x0x7fba0cfcdf60) 0 + primary-for QAbstractTextDocumentLayout (0x0x7fba0cbed618) + +Vtable for QTextObjectInterface +QTextObjectInterface::_ZTV20QTextObjectInterface: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextObjectInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QTextObjectInterface + size=8 align=8 + base size=8 base align=8 +QTextObjectInterface (0x0x7fba0cc12660) 0 nearly-empty + vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16u) + +Class QAccessible::State + size=8 align=8 + base size=5 base align=8 +QAccessible::State (0x0x7fba0cc12780) 0 + +Vtable for QAccessible::ActivationObserver +QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAccessible::ActivationObserver + size=8 align=8 + base size=8 base align=8 +QAccessible::ActivationObserver (0x0x7fba0cc127e0) 0 nearly-empty + vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16u) + +Class QAccessible + size=1 align=1 + base size=0 base align=1 +QAccessible (0x0x7fba0cc12720) 0 empty + +Vtable for QAccessibleInterface +QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAccessibleInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleInterface (0x0x7fba0cc129c0) 0 nearly-empty + vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16u) + +Vtable for QAccessibleTextInterface +QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAccessibleTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset +104 (int (*)(...))QAccessibleTextInterface::textAfterOffset +112 (int (*)(...))QAccessibleTextInterface::textAtOffset +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTextInterface (0x0x7fba0cc12a20) 0 nearly-empty + vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16u) + +Vtable for QAccessibleEditableTextInterface +QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleEditableTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleEditableTextInterface (0x0x7fba0cc12a80) 0 nearly-empty + vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16u) + +Vtable for QAccessibleValueInterface +QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleValueInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleValueInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleValueInterface (0x0x7fba0cc12ae0) 0 nearly-empty + vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16u) + +Vtable for QAccessibleTableCellInterface +QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableCellInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableCellInterface (0x0x7fba0cc12b40) 0 nearly-empty + vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16u) + +Vtable for QAccessibleTableInterface +QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleTableInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableInterface (0x0x7fba0cc12ba0) 0 nearly-empty + vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16u) + +Vtable for QAccessibleActionInterface +QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleActionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QAccessibleActionInterface::localizedActionName +48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleActionInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleActionInterface (0x0x7fba0cc12c00) 0 nearly-empty + vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16u) + +Vtable for QAccessibleImageInterface +QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleImageInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleImageInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleImageInterface (0x0x7fba0cc12c60) 0 nearly-empty + vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16u) + +Vtable for QAccessibleEvent +QAccessibleEvent::_ZTV16QAccessibleEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAccessibleEvent) +16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleEvent + size=32 align=8 + base size=28 base align=8 +QAccessibleEvent (0x0x7fba0cc12cc0) 0 + vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16u) + +Vtable for QAccessibleStateChangeEvent +QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent) +16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleStateChangeEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleStateChangeEvent (0x0x7fba0cd13068) 0 + vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16u) + QAccessibleEvent (0x0x7fba0cd0d240) 0 + primary-for QAccessibleStateChangeEvent (0x0x7fba0cd13068) + +Vtable for QAccessibleTextCursorEvent +QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent) +16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextCursorEvent + size=32 align=8 + base size=32 base align=8 +QAccessibleTextCursorEvent (0x0x7fba0cd130d0) 0 + vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16u) + QAccessibleEvent (0x0x7fba0cd0d2a0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7fba0cd130d0) + +Vtable for QAccessibleTextSelectionEvent +QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent) +16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextSelectionEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleTextSelectionEvent (0x0x7fba0cd13138) 0 + vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7fba0cd131a0) 0 + primary-for QAccessibleTextSelectionEvent (0x0x7fba0cd13138) + QAccessibleEvent (0x0x7fba0cd0d300) 0 + primary-for QAccessibleTextCursorEvent (0x0x7fba0cd131a0) + +Vtable for QAccessibleTextInsertEvent +QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent) +16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextInsertEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextInsertEvent (0x0x7fba0cd13208) 0 + vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7fba0cd13270) 0 + primary-for QAccessibleTextInsertEvent (0x0x7fba0cd13208) + QAccessibleEvent (0x0x7fba0cd0d360) 0 + primary-for QAccessibleTextCursorEvent (0x0x7fba0cd13270) + +Vtable for QAccessibleTextRemoveEvent +QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent) +16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextRemoveEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextRemoveEvent (0x0x7fba0cd132d8) 0 + vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7fba0cd13340) 0 + primary-for QAccessibleTextRemoveEvent (0x0x7fba0cd132d8) + QAccessibleEvent (0x0x7fba0cd0d3c0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7fba0cd13340) + +Vtable for QAccessibleTextUpdateEvent +QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent) +16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextUpdateEvent + size=56 align=8 + base size=56 base align=8 +QAccessibleTextUpdateEvent (0x0x7fba0cd133a8) 0 + vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7fba0cd13410) 0 + primary-for QAccessibleTextUpdateEvent (0x0x7fba0cd133a8) + QAccessibleEvent (0x0x7fba0cd0d420) 0 + primary-for QAccessibleTextCursorEvent (0x0x7fba0cd13410) + +Vtable for QAccessibleValueChangeEvent +QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent) +16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleValueChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleValueChangeEvent (0x0x7fba0cd13478) 0 + vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16u) + QAccessibleEvent (0x0x7fba0cd0d480) 0 + primary-for QAccessibleValueChangeEvent (0x0x7fba0cd13478) + +Vtable for QAccessibleTableModelChangeEvent +QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent) +16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTableModelChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTableModelChangeEvent (0x0x7fba0cd134e0) 0 + vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16u) + QAccessibleEvent (0x0x7fba0cd0d4e0) 0 + primary-for QAccessibleTableModelChangeEvent (0x0x7fba0cd134e0) + +Vtable for QAccessibleBridge +QAccessibleBridge::_ZTV17QAccessibleBridge: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleBridge) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridge + size=8 align=8 + base size=8 base align=8 +QAccessibleBridge (0x0x7fba0cd0d5a0) 0 nearly-empty + vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16u) + +Class QAccessibleBridgePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessibleBridgePlugin::QPrivateSignal (0x0x7fba0cd0d660) 0 empty + +Vtable for QAccessibleBridgePlugin +QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin) +16 (int (*)(...))QAccessibleBridgePlugin::metaObject +24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast +32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridgePlugin + size=16 align=8 + base size=16 base align=8 +QAccessibleBridgePlugin (0x0x7fba0cd13548) 0 + vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16u) + QObject (0x0x7fba0cd0d600) 0 + primary-for QAccessibleBridgePlugin (0x0x7fba0cd13548) + +Vtable for QAccessibleObject +QAccessibleObject::_ZTV17QAccessibleObject: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleObject) +16 0u +24 0u +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleObject + size=16 align=8 + base size=16 base align=8 +QAccessibleObject (0x0x7fba0cd135b0) 0 + vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16u) + QAccessibleInterface (0x0x7fba0cd0d6c0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7fba0cd135b0) + +Vtable for QAccessibleApplication +QAccessibleApplication::_ZTV22QAccessibleApplication: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QAccessibleApplication) +16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleApplication::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleApplication::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleApplication::parent +88 (int (*)(...))QAccessibleApplication::child +96 (int (*)(...))QAccessibleApplication::childCount +104 (int (*)(...))QAccessibleApplication::indexOfChild +112 (int (*)(...))QAccessibleApplication::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))QAccessibleApplication::role +144 (int (*)(...))QAccessibleApplication::state +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleApplication + size=16 align=8 + base size=16 base align=8 +QAccessibleApplication (0x0x7fba0cd13618) 0 + vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16u) + QAccessibleObject (0x0x7fba0cd13680) 0 + primary-for QAccessibleApplication (0x0x7fba0cd13618) + QAccessibleInterface (0x0x7fba0cd0d720) 0 nearly-empty + primary-for QAccessibleObject (0x0x7fba0cd13680) + +Class QAccessiblePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessiblePlugin::QPrivateSignal (0x0x7fba0cd0d7e0) 0 empty + +Vtable for QAccessiblePlugin +QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessiblePlugin) +16 (int (*)(...))QAccessiblePlugin::metaObject +24 (int (*)(...))QAccessiblePlugin::qt_metacast +32 (int (*)(...))QAccessiblePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessiblePlugin + size=16 align=8 + base size=16 base align=8 +QAccessiblePlugin (0x0x7fba0cd136e8) 0 + vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16u) + QObject (0x0x7fba0cd0d780) 0 + primary-for QAccessiblePlugin (0x0x7fba0cd136e8) + +Class QSurfaceFormat + size=8 align=8 + base size=8 base align=8 +QSurfaceFormat (0x0x7fba0cd0d840) 0 + +Vtable for QSurface +QSurface::_ZTV8QSurface: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSurface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QSurface + size=24 align=8 + base size=24 base align=8 +QSurface (0x0x7fba0cd0da20) 0 + vptr=((& QSurface::_ZTV8QSurface) + 16u) + +Class QIcon + size=8 align=8 + base size=8 base align=8 +QIcon (0x0x7fba0cd0dba0) 0 + +Class QCursor + size=8 align=8 + base size=8 base align=8 +QCursor (0x0x7fba0cacbf60) 0 + +Class QWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWindow::QPrivateSignal (0x0x7fba0cb7f5a0) 0 empty + +Vtable for QWindow +QWindow::_ZTV7QWindow: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWindow) +16 (int (*)(...))QWindow::metaObject +24 (int (*)(...))QWindow::qt_metacast +32 (int (*)(...))QWindow::qt_metacall +40 (int (*)(...))QWindow::~QWindow +48 (int (*)(...))QWindow::~QWindow +56 (int (*)(...))QWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI7QWindow) +312 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev +320 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QWindow + size=40 align=8 + base size=40 base align=8 +QWindow (0x0x7fba0cb8a150) 0 + vptr=((& QWindow::_ZTV7QWindow) + 16u) + QObject (0x0x7fba0cb7f4e0) 0 + primary-for QWindow (0x0x7fba0cb8a150) + QSurface (0x0x7fba0cb7f540) 16 + vptr=((& QWindow::_ZTV7QWindow) + 312u) + +Class QBackingStore + size=8 align=8 + base size=8 base align=8 +QBackingStore (0x0x7fba0cb7f6c0) 0 + +Vtable for QBitmap +QBitmap::_ZTV7QBitmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBitmap) +16 (int (*)(...))QBitmap::~QBitmap +24 (int (*)(...))QBitmap::~QBitmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QBitmap + size=32 align=8 + base size=32 base align=8 +QBitmap (0x0x7fba0cb78750) 0 + vptr=((& QBitmap::_ZTV7QBitmap) + 16u) + QPixmap (0x0x7fba0cb787b8) 0 + primary-for QBitmap (0x0x7fba0cb78750) + QPaintDevice (0x0x7fba0cb7f780) 0 + primary-for QPixmap (0x0x7fba0cb787b8) + +Class QClipboard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QClipboard::QPrivateSignal (0x0x7fba0cb7fae0) 0 empty + +Vtable for QClipboard +QClipboard::_ZTV10QClipboard: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QClipboard) +16 (int (*)(...))QClipboard::metaObject +24 (int (*)(...))QClipboard::qt_metacast +32 (int (*)(...))QClipboard::qt_metacall +40 (int (*)(...))QClipboard::~QClipboard +48 (int (*)(...))QClipboard::~QClipboard +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QClipboard + size=16 align=8 + base size=16 base align=8 +QClipboard (0x0x7fba0cb78a28) 0 + vptr=((& QClipboard::_ZTV10QClipboard) + 16u) + QObject (0x0x7fba0cb7fa80) 0 + primary-for QClipboard (0x0x7fba0cb78a28) + +Class QDesktopServices + size=1 align=1 + base size=0 base align=1 +QDesktopServices (0x0x7fba0cb7fb40) 0 empty + +Class QDrag::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDrag::QPrivateSignal (0x0x7fba0cb7fc00) 0 empty + +Vtable for QDrag +QDrag::_ZTV5QDrag: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDrag) +16 (int (*)(...))QDrag::metaObject +24 (int (*)(...))QDrag::qt_metacast +32 (int (*)(...))QDrag::qt_metacall +40 (int (*)(...))QDrag::~QDrag +48 (int (*)(...))QDrag::~QDrag +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDrag + size=16 align=8 + base size=16 base align=8 +QDrag (0x0x7fba0cb78a90) 0 + vptr=((& QDrag::_ZTV5QDrag) + 16u) + QObject (0x0x7fba0cb7fba0) 0 + primary-for QDrag (0x0x7fba0cb78a90) + +Class QFontInfo + size=8 align=8 + base size=8 base align=8 +QFontInfo (0x0x7fba0cb7fc60) 0 + +Class QFontMetrics + size=8 align=8 + base size=8 base align=8 +QFontMetrics (0x0x7fba0cb7ff00) 0 + +Class QFontMetricsF + size=8 align=8 + base size=8 base align=8 +QFontMetricsF (0x0x7fba0c84e240) 0 + +Class QGenericPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGenericPlugin::QPrivateSignal (0x0x7fba0c91d9c0) 0 empty + +Vtable for QGenericPlugin +QGenericPlugin::_ZTV14QGenericPlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGenericPlugin) +16 (int (*)(...))QGenericPlugin::metaObject +24 (int (*)(...))QGenericPlugin::qt_metacast +32 (int (*)(...))QGenericPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGenericPlugin + size=16 align=8 + base size=16 base align=8 +QGenericPlugin (0x0x7fba0c8815b0) 0 + vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16u) + QObject (0x0x7fba0c91d960) 0 + primary-for QGenericPlugin (0x0x7fba0c8815b0) + +Class QGenericPluginFactory + size=1 align=1 + base size=0 base align=1 +QGenericPluginFactory (0x0x7fba0c91da20) 0 empty + +Class QInputMethod::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputMethod::QPrivateSignal (0x0x7fba0c91dae0) 0 empty + +Vtable for QInputMethod +QInputMethod::_ZTV12QInputMethod: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputMethod) +16 (int (*)(...))QInputMethod::metaObject +24 (int (*)(...))QInputMethod::qt_metacast +32 (int (*)(...))QInputMethod::qt_metacall +40 (int (*)(...))QInputMethod::~QInputMethod +48 (int (*)(...))QInputMethod::~QInputMethod +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputMethod + size=16 align=8 + base size=16 base align=8 +QInputMethod (0x0x7fba0c881618) 0 + vptr=((& QInputMethod::_ZTV12QInputMethod) + 16u) + QObject (0x0x7fba0c91da80) 0 + primary-for QInputMethod (0x0x7fba0c881618) + +Class QGuiApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGuiApplication::QPrivateSignal (0x0x7fba0c91dba0) 0 empty + +Vtable for QGuiApplication +QGuiApplication::_ZTV15QGuiApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGuiApplication) +16 (int (*)(...))QGuiApplication::metaObject +24 (int (*)(...))QGuiApplication::qt_metacast +32 (int (*)(...))QGuiApplication::qt_metacall +40 (int (*)(...))QGuiApplication::~QGuiApplication +48 (int (*)(...))QGuiApplication::~QGuiApplication +56 (int (*)(...))QGuiApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGuiApplication::notify +120 (int (*)(...))QGuiApplication::compressEvent + +Class QGuiApplication + size=16 align=8 + base size=16 base align=8 +QGuiApplication (0x0x7fba0c881680) 0 + vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16u) + QCoreApplication (0x0x7fba0c8816e8) 0 + primary-for QGuiApplication (0x0x7fba0c881680) + QObject (0x0x7fba0c91db40) 0 + primary-for QCoreApplication (0x0x7fba0c8816e8) + +Class QIconEngine::AvailableSizesArgument + size=16 align=8 + base size=16 base align=8 +QIconEngine::AvailableSizesArgument (0x0x7fba0c603120) 0 + +Class QIconEngine::ScaledPixmapArgument + size=56 align=8 + base size=56 base align=8 +QIconEngine::ScaledPixmapArgument (0x0x7fba0c6032a0) 0 + +Vtable for QIconEngine +QIconEngine::_ZTV11QIconEngine: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QIconEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QIconEngine::actualSize +48 (int (*)(...))QIconEngine::pixmap +56 (int (*)(...))QIconEngine::addPixmap +64 (int (*)(...))QIconEngine::addFile +72 (int (*)(...))QIconEngine::key +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QIconEngine::read +96 (int (*)(...))QIconEngine::write +104 (int (*)(...))QIconEngine::availableSizes +112 (int (*)(...))QIconEngine::iconName +120 (int (*)(...))QIconEngine::virtual_hook + +Class QIconEngine + size=8 align=8 + base size=8 base align=8 +QIconEngine (0x0x7fba0c6030c0) 0 nearly-empty + vptr=((& QIconEngine::_ZTV11QIconEngine) + 16u) + +Class QIconEnginePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIconEnginePlugin::QPrivateSignal (0x0x7fba0c603360) 0 empty + +Vtable for QIconEnginePlugin +QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QIconEnginePlugin) +16 (int (*)(...))QIconEnginePlugin::metaObject +24 (int (*)(...))QIconEnginePlugin::qt_metacast +32 (int (*)(...))QIconEnginePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QIconEnginePlugin + size=16 align=8 + base size=16 base align=8 +QIconEnginePlugin (0x0x7fba0c881d00) 0 + vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16u) + QObject (0x0x7fba0c603300) 0 + primary-for QIconEnginePlugin (0x0x7fba0c881d00) + +Vtable for QImageIOHandler +QImageIOHandler::_ZTV15QImageIOHandler: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QImageIOHandler) +16 0u +24 0u +32 (int (*)(...))QImageIOHandler::name +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QImageIOHandler::write +64 (int (*)(...))QImageIOHandler::option +72 (int (*)(...))QImageIOHandler::setOption +80 (int (*)(...))QImageIOHandler::supportsOption +88 (int (*)(...))QImageIOHandler::jumpToNextImage +96 (int (*)(...))QImageIOHandler::jumpToImage +104 (int (*)(...))QImageIOHandler::loopCount +112 (int (*)(...))QImageIOHandler::imageCount +120 (int (*)(...))QImageIOHandler::nextImageDelay +128 (int (*)(...))QImageIOHandler::currentImageNumber +136 (int (*)(...))QImageIOHandler::currentImageRect + +Class QImageIOHandler + size=16 align=8 + base size=16 base align=8 +QImageIOHandler (0x0x7fba0c6033c0) 0 + vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16u) + +Class QImageIOPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QImageIOPlugin::QPrivateSignal (0x0x7fba0c603540) 0 empty + +Vtable for QImageIOPlugin +QImageIOPlugin::_ZTV14QImageIOPlugin: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QImageIOPlugin) +16 (int (*)(...))QImageIOPlugin::metaObject +24 (int (*)(...))QImageIOPlugin::qt_metacast +32 (int (*)(...))QImageIOPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QImageIOPlugin + size=16 align=8 + base size=16 base align=8 +QImageIOPlugin (0x0x7fba0c881d68) 0 + vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16u) + QObject (0x0x7fba0c6034e0) 0 + primary-for QImageIOPlugin (0x0x7fba0c881d68) + +Class QImageReader + size=8 align=8 + base size=8 base align=8 +QImageReader (0x0x7fba0c603720) 0 + +Class QImageWriter + size=8 align=8 + base size=8 base align=8 +QImageWriter (0x0x7fba0c603780) 0 + +Class QVector3D + size=12 align=4 + base size=12 base align=4 +QVector3D (0x0x7fba0c6037e0) 0 + +Class QVector4D + size=16 align=4 + base size=16 base align=4 +QVector4D (0x0x7fba0c603a80) 0 + +Class QQuaternion + size=16 align=4 + base size=16 base align=4 +QQuaternion (0x0x7fba0c603d20) 0 + +Class QMatrix4x4 + size=68 align=4 + base size=68 base align=4 +QMatrix4x4 (0x0x7fba0c7b5360) 0 + +Class QMovie::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMovie::QPrivateSignal (0x0x7fba0c7b5ae0) 0 empty + +Vtable for QMovie +QMovie::_ZTV6QMovie: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QMovie) +16 (int (*)(...))QMovie::metaObject +24 (int (*)(...))QMovie::qt_metacast +32 (int (*)(...))QMovie::qt_metacall +40 (int (*)(...))QMovie::~QMovie +48 (int (*)(...))QMovie::~QMovie +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QMovie + size=16 align=8 + base size=16 base align=8 +QMovie (0x0x7fba0c72ff08) 0 + vptr=((& QMovie::_ZTV6QMovie) + 16u) + QObject (0x0x7fba0c7b5a80) 0 + primary-for QMovie (0x0x7fba0c72ff08) + +Class QOffscreenSurface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOffscreenSurface::QPrivateSignal (0x0x7fba0c7b5c00) 0 empty + +Vtable for QOffscreenSurface +QOffscreenSurface::_ZTV17QOffscreenSurface: 26u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOffscreenSurface) +16 (int (*)(...))QOffscreenSurface::metaObject +24 (int (*)(...))QOffscreenSurface::qt_metacast +32 (int (*)(...))QOffscreenSurface::qt_metacall +40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOffscreenSurface::surfaceType +120 (int (*)(...))QOffscreenSurface::format +128 (int (*)(...))QOffscreenSurface::size +136 (int (*)(...))QOffscreenSurface::surfaceHandle +144 (int (*)(...))-16 +152 (int (*)(...))(& _ZTI17QOffscreenSurface) +160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev +168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev +176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv +184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv +192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv +200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv + +Class QOffscreenSurface + size=40 align=8 + base size=40 base align=8 +QOffscreenSurface (0x0x7fba0c4fae00) 0 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16u) + QObject (0x0x7fba0c7b5b40) 0 + primary-for QOffscreenSurface (0x0x7fba0c4fae00) + QSurface (0x0x7fba0c7b5ba0) 16 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160u) + +Class QOpenGLBuffer + size=8 align=8 + base size=8 base align=8 +QOpenGLBuffer (0x0x7fba0c7b5cc0) 0 + +Class QOpenGLVersionStatus + size=12 align=4 + base size=12 base align=4 +QOpenGLVersionStatus (0x0x7fba0c7b5ea0) 0 + +Class QOpenGLVersionFunctionsBackend + size=16 align=8 + base size=12 base align=8 +QOpenGLVersionFunctionsBackend (0x0x7fba0bea89c0) 0 + +Class QOpenGLVersionFunctionsStorage + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionFunctionsStorage (0x0x7fba0bea8a20) 0 + +Class QAbstractOpenGLFunctionsPrivate + size=16 align=8 + base size=9 base align=8 +QAbstractOpenGLFunctionsPrivate (0x0x7fba0bea8a80) 0 + +Vtable for QAbstractOpenGLFunctions +QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions) +16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions + +Class QAbstractOpenGLFunctions + size=16 align=8 + base size=16 base align=8 +QAbstractOpenGLFunctions (0x0x7fba0bea8ae0) 0 + vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16u) + +Class QOpenGLFunctions_1_0_CoreBackend::Functions + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7fba0bea8ba0) 0 + +Class QOpenGLFunctions_1_0_CoreBackend + size=400 align=8 + base size=400 base align=8 +QOpenGLFunctions_1_0_CoreBackend (0x0x7fba0bec21a0) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bea8b40) 0 + +Class QOpenGLFunctions_1_1_CoreBackend::Functions + size=128 align=8 + base size=128 base align=8 +QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7fba0bea8cc0) 0 + +Class QOpenGLFunctions_1_1_CoreBackend + size=144 align=8 + base size=144 base align=8 +QOpenGLFunctions_1_1_CoreBackend (0x0x7fba0bec2208) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bea8c60) 0 + +Class QOpenGLFunctions_1_2_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7fba0bea8de0) 0 + +Class QOpenGLFunctions_1_2_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_1_2_CoreBackend (0x0x7fba0bec2270) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bea8d80) 0 + +Class QOpenGLFunctions_1_3_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7fba0bea8f00) 0 + +Class QOpenGLFunctions_1_3_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_1_3_CoreBackend (0x0x7fba0bec22d8) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bea8ea0) 0 + +Class QOpenGLFunctions_1_4_CoreBackend::Functions + size=56 align=8 + base size=56 base align=8 +QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7fba0bf090c0) 0 + +Class QOpenGLFunctions_1_4_CoreBackend + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_4_CoreBackend (0x0x7fba0bec2340) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf09060) 0 + +Class QOpenGLFunctions_1_5_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7fba0bf091e0) 0 + +Class QOpenGLFunctions_1_5_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_1_5_CoreBackend (0x0x7fba0bec23a8) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf09180) 0 + +Class QOpenGLFunctions_2_0_CoreBackend::Functions + size=744 align=8 + base size=744 base align=8 +QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7fba0bf09300) 0 + +Class QOpenGLFunctions_2_0_CoreBackend + size=760 align=8 + base size=760 base align=8 +QOpenGLFunctions_2_0_CoreBackend (0x0x7fba0bec2410) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf092a0) 0 + +Class QOpenGLFunctions_2_1_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7fba0bf09420) 0 + +Class QOpenGLFunctions_2_1_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_2_1_CoreBackend (0x0x7fba0bec2478) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf093c0) 0 + +Class QOpenGLFunctions_3_0_CoreBackend::Functions + size=672 align=8 + base size=672 base align=8 +QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7fba0bf09540) 0 + +Class QOpenGLFunctions_3_0_CoreBackend + size=688 align=8 + base size=688 base align=8 +QOpenGLFunctions_3_0_CoreBackend (0x0x7fba0bec24e0) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf094e0) 0 + +Class QOpenGLFunctions_3_1_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7fba0bf09660) 0 + +Class QOpenGLFunctions_3_1_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_3_1_CoreBackend (0x0x7fba0bec2548) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf09600) 0 + +Class QOpenGLFunctions_3_2_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7fba0bf09780) 0 + +Class QOpenGLFunctions_3_2_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_3_2_CoreBackend (0x0x7fba0bec25b0) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf09720) 0 + +Class QOpenGLFunctions_3_3_CoreBackend::Functions + size=464 align=8 + base size=464 base align=8 +QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7fba0bf098a0) 0 + +Class QOpenGLFunctions_3_3_CoreBackend + size=480 align=8 + base size=480 base align=8 +QOpenGLFunctions_3_3_CoreBackend (0x0x7fba0bec2618) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf09840) 0 + +Class QOpenGLFunctions_4_0_CoreBackend::Functions + size=368 align=8 + base size=368 base align=8 +QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7fba0bf099c0) 0 + +Class QOpenGLFunctions_4_0_CoreBackend + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_4_0_CoreBackend (0x0x7fba0bec2680) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf09960) 0 + +Class QOpenGLFunctions_4_1_CoreBackend::Functions + size=704 align=8 + base size=704 base align=8 +QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7fba0bf09ae0) 0 + +Class QOpenGLFunctions_4_1_CoreBackend + size=720 align=8 + base size=720 base align=8 +QOpenGLFunctions_4_1_CoreBackend (0x0x7fba0bec26e8) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf09a80) 0 + +Class QOpenGLFunctions_4_2_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7fba0bf09c00) 0 + +Class QOpenGLFunctions_4_2_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_2_CoreBackend (0x0x7fba0bec2750) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf09ba0) 0 + +Class QOpenGLFunctions_4_3_CoreBackend::Functions + size=344 align=8 + base size=344 base align=8 +QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7fba0bf09d20) 0 + +Class QOpenGLFunctions_4_3_CoreBackend + size=360 align=8 + base size=360 base align=8 +QOpenGLFunctions_4_3_CoreBackend (0x0x7fba0bec27b8) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf09cc0) 0 + +Class QOpenGLFunctions_4_4_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7fba0bf09e40) 0 + +Class QOpenGLFunctions_4_4_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_4_4_CoreBackend (0x0x7fba0bec2820) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf09de0) 0 + +Class QOpenGLFunctions_4_5_CoreBackend::Functions + size=848 align=8 + base size=848 base align=8 +QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7fba0bc01000) 0 + +Class QOpenGLFunctions_4_5_CoreBackend + size=864 align=8 + base size=864 base align=8 +QOpenGLFunctions_4_5_CoreBackend (0x0x7fba0bec2888) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bf09f60) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions + size=2064 align=8 + base size=2064 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7fba0bc01120) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend + size=2080 align=8 + base size=2080 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7fba0bec28f0) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bc010c0) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions + size=136 align=8 + base size=136 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7fba0bc01240) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7fba0bec2958) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bc011e0) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7fba0bc01360) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend + size=272 align=8 + base size=272 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7fba0bec29c0) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bc01300) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions + size=296 align=8 + base size=296 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7fba0bc01480) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend + size=312 align=8 + base size=312 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7fba0bec2a28) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bc01420) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7fba0bc015a0) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend + size=320 align=8 + base size=320 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7fba0bec2a90) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bc01540) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions + size=288 align=8 + base size=288 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7fba0bc016c0) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7fba0bec2af8) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bc01660) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions + size=160 align=8 + base size=160 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7fba0bc017e0) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend + size=176 align=8 + base size=176 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7fba0bec2b60) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bc01780) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions + size=240 align=8 + base size=240 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7fba0bc01900) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7fba0bec2bc8) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bc018a0) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7fba0bc01a20) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7fba0bec2c30) 0 + QOpenGLVersionFunctionsBackend (0x0x7fba0bc019c0) 0 + +Class QOpenGLVersionProfile + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionProfile (0x0x7fba0bc01ae0) 0 + +Class QOpenGLContextGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContextGroup::QPrivateSignal (0x0x7fba0bd0d4e0) 0 empty + +Vtable for QOpenGLContextGroup +QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QOpenGLContextGroup) +16 (int (*)(...))QOpenGLContextGroup::metaObject +24 (int (*)(...))QOpenGLContextGroup::qt_metacast +32 (int (*)(...))QOpenGLContextGroup::qt_metacall +40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContextGroup + size=16 align=8 + base size=16 base align=8 +QOpenGLContextGroup (0x0x7fba0bd03680) 0 + vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16u) + QObject (0x0x7fba0bd0d480) 0 + primary-for QOpenGLContextGroup (0x0x7fba0bd03680) + +Class QOpenGLContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContext::QPrivateSignal (0x0x7fba0bd0d5a0) 0 empty + +Vtable for QOpenGLContext +QOpenGLContext::_ZTV14QOpenGLContext: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QOpenGLContext) +16 (int (*)(...))QOpenGLContext::metaObject +24 (int (*)(...))QOpenGLContext::qt_metacast +32 (int (*)(...))QOpenGLContext::qt_metacall +40 (int (*)(...))QOpenGLContext::~QOpenGLContext +48 (int (*)(...))QOpenGLContext::~QOpenGLContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContext + size=16 align=8 + base size=16 base align=8 +QOpenGLContext (0x0x7fba0bd036e8) 0 + vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16u) + QObject (0x0x7fba0bd0d540) 0 + primary-for QOpenGLContext (0x0x7fba0bd036e8) + +Class QOpenGLDebugMessage + size=8 align=8 + base size=8 base align=8 +QOpenGLDebugMessage (0x0x7fba0bd0d600) 0 + +Class QOpenGLDebugLogger::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLDebugLogger::QPrivateSignal (0x0x7fba0bd0dde0) 0 empty + +Vtable for QOpenGLDebugLogger +QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger) +16 (int (*)(...))QOpenGLDebugLogger::metaObject +24 (int (*)(...))QOpenGLDebugLogger::qt_metacast +32 (int (*)(...))QOpenGLDebugLogger::qt_metacall +40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLDebugLogger + size=16 align=8 + base size=16 base align=8 +QOpenGLDebugLogger (0x0x7fba0bd03b60) 0 + vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16u) + QObject (0x0x7fba0bd0dd80) 0 + primary-for QOpenGLDebugLogger (0x0x7fba0bd03b60) + +Class QOpenGLFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLFunctions (0x0x7fba0bd0df60) 0 + +Class QOpenGLFunctionsPrivate::Functions + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate::Functions (0x0x7fba0ba5b1e0) 0 + +Class QOpenGLFunctionsPrivate + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate (0x0x7fba0ba5b180) 0 + +Class QOpenGLExtraFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLExtraFunctions (0x0x7fba0bd03dd0) 0 + QOpenGLFunctions (0x0x7fba0bb7f900) 0 + +Class QOpenGLExtraFunctionsPrivate::Functions + size=1728 align=8 + base size=1728 base align=8 +QOpenGLExtraFunctionsPrivate::Functions (0x0x7fba0bb7f9c0) 0 + +Class QOpenGLExtraFunctionsPrivate + size=2880 align=8 + base size=2880 base align=8 +QOpenGLExtraFunctionsPrivate (0x0x7fba0bd03e38) 0 + QOpenGLFunctionsPrivate (0x0x7fba0bb7f960) 0 + +Vtable for QOpenGLFramebufferObject +QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject) +16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject +24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject + +Class QOpenGLFramebufferObject + size=16 align=8 + base size=16 base align=8 +QOpenGLFramebufferObject (0x0x7fba0b5e20c0) 0 + vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16u) + +Class QOpenGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QOpenGLFramebufferObjectFormat (0x0x7fba0b5e21e0) 0 + +Vtable for QOpenGLPaintDevice +QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice) +16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +32 (int (*)(...))QOpenGLPaintDevice::devType +40 (int (*)(...))QOpenGLPaintDevice::paintEngine +48 (int (*)(...))QOpenGLPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget + +Class QOpenGLPaintDevice + size=32 align=8 + base size=32 base align=8 +QOpenGLPaintDevice (0x0x7fba0b9b1138) 0 + vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16u) + QPaintDevice (0x0x7fba0b5e2240) 0 + primary-for QOpenGLPaintDevice (0x0x7fba0b9b1138) + +Class QOpenGLPixelTransferOptions + size=8 align=8 + base size=8 base align=8 +QOpenGLPixelTransferOptions (0x0x7fba0b5e2360) 0 + +Class QOpenGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShader::QPrivateSignal (0x0x7fba0b5e26c0) 0 empty + +Vtable for QOpenGLShader +QOpenGLShader::_ZTV13QOpenGLShader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLShader) +16 (int (*)(...))QOpenGLShader::metaObject +24 (int (*)(...))QOpenGLShader::qt_metacast +32 (int (*)(...))QOpenGLShader::qt_metacall +40 (int (*)(...))QOpenGLShader::~QOpenGLShader +48 (int (*)(...))QOpenGLShader::~QOpenGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLShader + size=16 align=8 + base size=16 base align=8 +QOpenGLShader (0x0x7fba0b9b1340) 0 + vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16u) + QObject (0x0x7fba0b5e2660) 0 + primary-for QOpenGLShader (0x0x7fba0b9b1340) + +Class QOpenGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShaderProgram::QPrivateSignal (0x0x7fba0b5e2900) 0 empty + +Vtable for QOpenGLShaderProgram +QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram) +16 (int (*)(...))QOpenGLShaderProgram::metaObject +24 (int (*)(...))QOpenGLShaderProgram::qt_metacast +32 (int (*)(...))QOpenGLShaderProgram::qt_metacall +40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOpenGLShaderProgram::link + +Class QOpenGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QOpenGLShaderProgram (0x0x7fba0b9b1478) 0 + vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16u) + QObject (0x0x7fba0b5e28a0) 0 + primary-for QOpenGLShaderProgram (0x0x7fba0b9b1478) + +Class QOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QOpenGLTexture (0x0x7fba0b5e2960) 0 + +Class QOpenGLTextureBlitter + size=8 align=8 + base size=8 base align=8 +QOpenGLTextureBlitter (0x0x7fba0b5e2c00) 0 + +Class QOpenGLTimerQuery::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimerQuery::QPrivateSignal (0x0x7fba0b5e2d80) 0 empty + +Vtable for QOpenGLTimerQuery +QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery) +16 (int (*)(...))QOpenGLTimerQuery::metaObject +24 (int (*)(...))QOpenGLTimerQuery::qt_metacast +32 (int (*)(...))QOpenGLTimerQuery::qt_metacall +40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimerQuery + size=16 align=8 + base size=16 base align=8 +QOpenGLTimerQuery (0x0x7fba0b9b15b0) 0 + vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16u) + QObject (0x0x7fba0b5e2d20) 0 + primary-for QOpenGLTimerQuery (0x0x7fba0b9b15b0) + +Class QOpenGLTimeMonitor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimeMonitor::QPrivateSignal (0x0x7fba0b5e2e40) 0 empty + +Vtable for QOpenGLTimeMonitor +QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor) +16 (int (*)(...))QOpenGLTimeMonitor::metaObject +24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast +32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall +40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimeMonitor + size=16 align=8 + base size=16 base align=8 +QOpenGLTimeMonitor (0x0x7fba0b9b1618) 0 + vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16u) + QObject (0x0x7fba0b5e2de0) 0 + primary-for QOpenGLTimeMonitor (0x0x7fba0b9b1618) + +Class QOpenGLVertexArrayObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLVertexArrayObject::QPrivateSignal (0x0x7fba0b5e2f00) 0 empty + +Class QOpenGLVertexArrayObject::Binder + size=8 align=8 + base size=8 base align=8 +QOpenGLVertexArrayObject::Binder (0x0x7fba0b5e2f60) 0 + +Vtable for QOpenGLVertexArrayObject +QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject) +16 (int (*)(...))QOpenGLVertexArrayObject::metaObject +24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast +32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall +40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLVertexArrayObject + size=16 align=8 + base size=16 base align=8 +QOpenGLVertexArrayObject (0x0x7fba0b9b1680) 0 + vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16u) + QObject (0x0x7fba0b5e2ea0) 0 + primary-for QOpenGLVertexArrayObject (0x0x7fba0b9b1680) + +Class QPaintDeviceWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPaintDeviceWindow::QPrivateSignal (0x0x7fba0b7b7120) 0 empty + +Vtable for QPaintDeviceWindow +QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 58u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +16 (int (*)(...))QPaintDeviceWindow::metaObject +24 (int (*)(...))QPaintDeviceWindow::qt_metacast +32 (int (*)(...))QPaintDeviceWindow::qt_metacall +40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QPaintDeviceWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))-16 +328 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +336 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev +344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +384 (int (*)(...))-40 +392 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +400 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev +408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev +416 (int (*)(...))QPaintDevice::devType +424 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE +440 (int (*)(...))QPaintDevice::initPainter +448 (int (*)(...))QPaintDevice::redirected +456 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDeviceWindow + size=64 align=8 + base size=64 base align=8 +QPaintDeviceWindow (0x0x7fba0b7b0850) 0 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16u) + QWindow (0x0x7fba0b7b08c0) 0 + primary-for QPaintDeviceWindow (0x0x7fba0b7b0850) + QObject (0x0x7fba0b7b7000) 0 + primary-for QWindow (0x0x7fba0b7b08c0) + QSurface (0x0x7fba0b7b7060) 16 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 336u) + QPaintDevice (0x0x7fba0b7b70c0) 40 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 400u) + +Class QOpenGLWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWindow::QPrivateSignal (0x0x7fba0b7b72a0) 0 empty + +Vtable for QOpenGLWindow +QOpenGLWindow::_ZTV13QOpenGLWindow: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWindow) +16 (int (*)(...))QOpenGLWindow::metaObject +24 (int (*)(...))QOpenGLWindow::qt_metacast +32 (int (*)(...))QOpenGLWindow::qt_metacall +40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QOpenGLWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QOpenGLWindow::paintEvent +304 (int (*)(...))QOpenGLWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QOpenGLWindow::initializeGL +328 (int (*)(...))QOpenGLWindow::resizeGL +336 (int (*)(...))QOpenGLWindow::paintGL +344 (int (*)(...))QOpenGLWindow::paintUnderGL +352 (int (*)(...))QOpenGLWindow::paintOverGL +360 (int (*)(...))QOpenGLWindow::redirected +368 (int (*)(...))-16 +376 (int (*)(...))(& _ZTI13QOpenGLWindow) +384 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev +392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev +400 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +408 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +416 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +424 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +432 (int (*)(...))-40 +440 (int (*)(...))(& _ZTI13QOpenGLWindow) +448 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev +456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev +464 (int (*)(...))QPaintDevice::devType +472 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +480 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QPaintDevice::initPainter +496 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint +504 (int (*)(...))QPaintDevice::sharedPainter + +Class QOpenGLWindow + size=64 align=8 + base size=64 base align=8 +QOpenGLWindow (0x0x7fba0b9b1750) 0 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16u) + QPaintDeviceWindow (0x0x7fba0b7b0e00) 0 + primary-for QOpenGLWindow (0x0x7fba0b9b1750) + QWindow (0x0x7fba0b7b0e70) 0 + primary-for QPaintDeviceWindow (0x0x7fba0b7b0e00) + QObject (0x0x7fba0b7b7180) 0 + primary-for QWindow (0x0x7fba0b7b0e70) + QSurface (0x0x7fba0b7b71e0) 16 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 384u) + QPaintDevice (0x0x7fba0b7b7240) 40 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 448u) + +Class QPageSize + size=8 align=8 + base size=8 base align=8 +QPageSize (0x0x7fba0b7b7300) 0 + +Class QPageLayout + size=8 align=8 + base size=8 base align=8 +QPageLayout (0x0x7fba0b7b7cc0) 0 + +Class QPagedPaintDevice::Margins + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice::Margins (0x0x7fba0b45d720) 0 + +Vtable for QPagedPaintDevice +QPagedPaintDevice::_ZTV17QPagedPaintDevice: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QPagedPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QPagedPaintDevice::setPageSize +96 (int (*)(...))QPagedPaintDevice::setPageSizeMM +104 (int (*)(...))QPagedPaintDevice::setMargins + +Class QPagedPaintDevice + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice (0x0x7fba0b460478) 0 + vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16u) + QPaintDevice (0x0x7fba0b45d6c0) 0 + primary-for QPagedPaintDevice (0x0x7fba0b460478) + +Class QPainter::PixmapFragment + size=80 align=8 + base size=80 base align=8 +QPainter::PixmapFragment (0x0x7fba0b45d7e0) 0 + +Class QPainter + size=8 align=8 + base size=8 base align=8 +QPainter (0x0x7fba0b45d780) 0 + +Class QTextItem + size=1 align=1 + base size=0 base align=1 +QTextItem (0x0x7fba0b5bd600) 0 empty + +Vtable for QPaintEngine +QPaintEngine::_ZTV12QPaintEngine: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QPaintEngine::drawRects +64 (int (*)(...))QPaintEngine::drawRects +72 (int (*)(...))QPaintEngine::drawLines +80 (int (*)(...))QPaintEngine::drawLines +88 (int (*)(...))QPaintEngine::drawEllipse +96 (int (*)(...))QPaintEngine::drawEllipse +104 (int (*)(...))QPaintEngine::drawPath +112 (int (*)(...))QPaintEngine::drawPoints +120 (int (*)(...))QPaintEngine::drawPoints +128 (int (*)(...))QPaintEngine::drawPolygon +136 (int (*)(...))QPaintEngine::drawPolygon +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QPaintEngine::drawTextItem +160 (int (*)(...))QPaintEngine::drawTiledPixmap +168 (int (*)(...))QPaintEngine::drawImage +176 (int (*)(...))QPaintEngine::coordinateOffset +184 (int (*)(...))__cxa_pure_virtual + +Class QPaintEngine + size=32 align=8 + base size=32 base align=8 +QPaintEngine (0x0x7fba0b5bd8a0) 0 + vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16u) + +Class QPaintEngineState + size=4 align=4 + base size=4 base align=4 +QPaintEngineState (0x0x7fba0b5bdb40) 0 + +Class QPdfWriter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPdfWriter::QPrivateSignal (0x0x7fba0b5bdf60) 0 empty + +Vtable for QPdfWriter +QPdfWriter::_ZTV10QPdfWriter: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QPdfWriter) +16 (int (*)(...))QPdfWriter::metaObject +24 (int (*)(...))QPdfWriter::qt_metacast +32 (int (*)(...))QPdfWriter::qt_metacall +40 (int (*)(...))QPdfWriter::~QPdfWriter +48 (int (*)(...))QPdfWriter::~QPdfWriter +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPdfWriter::newPage +120 (int (*)(...))QPdfWriter::setPageSize +128 (int (*)(...))QPdfWriter::setPageSizeMM +136 (int (*)(...))QPdfWriter::setMargins +144 (int (*)(...))QPdfWriter::paintEngine +152 (int (*)(...))QPdfWriter::metric +160 (int (*)(...))-16 +168 (int (*)(...))(& _ZTI10QPdfWriter) +176 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev +184 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev +192 (int (*)(...))QPaintDevice::devType +200 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv +208 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE +216 (int (*)(...))QPaintDevice::initPainter +224 (int (*)(...))QPaintDevice::redirected +232 (int (*)(...))QPaintDevice::sharedPainter +240 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv +248 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter11setPageSizeEN17QPagedPaintDevice8PageSizeE +256 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter13setPageSizeMMERK6QSizeF +264 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter10setMarginsERKN17QPagedPaintDevice7MarginsE + +Class QPdfWriter + size=48 align=8 + base size=48 base align=8 +QPdfWriter (0x0x7fba0b34d230) 0 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16u) + QObject (0x0x7fba0b5bdea0) 0 + primary-for QPdfWriter (0x0x7fba0b34d230) + QPagedPaintDevice (0x0x7fba0b26c4e0) 16 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 176u) + QPaintDevice (0x0x7fba0b5bdf00) 16 + primary-for QPagedPaintDevice (0x0x7fba0b26c4e0) + +Vtable for QPicture +QPicture::_ZTV8QPicture: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPicture) +16 (int (*)(...))QPicture::~QPicture +24 (int (*)(...))QPicture::~QPicture +32 (int (*)(...))QPicture::devType +40 (int (*)(...))QPicture::paintEngine +48 (int (*)(...))QPicture::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPicture::setData + +Class QPicture + size=32 align=8 + base size=32 base align=8 +QPicture (0x0x7fba0b26c548) 0 + vptr=((& QPicture::_ZTV8QPicture) + 16u) + QPaintDevice (0x0x7fba0b36c120) 0 + primary-for QPicture (0x0x7fba0b26c548) + +Class QPictureIO + size=8 align=8 + base size=8 base align=8 +QPictureIO (0x0x7fba0b36c420) 0 + +Class QPictureFormatPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPictureFormatPlugin::QPrivateSignal (0x0x7fba0b36c4e0) 0 empty + +Vtable for QPictureFormatPlugin +QPictureFormatPlugin::_ZTV20QPictureFormatPlugin: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QPictureFormatPlugin) +16 (int (*)(...))QPictureFormatPlugin::metaObject +24 (int (*)(...))QPictureFormatPlugin::qt_metacast +32 (int (*)(...))QPictureFormatPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPictureFormatPlugin::loadPicture +120 (int (*)(...))QPictureFormatPlugin::savePicture +128 (int (*)(...))__cxa_pure_virtual + +Class QPictureFormatPlugin + size=16 align=8 + base size=16 base align=8 +QPictureFormatPlugin (0x0x7fba0b26c750) 0 + vptr=((& QPictureFormatPlugin::_ZTV20QPictureFormatPlugin) + 16u) + QObject (0x0x7fba0b36c480) 0 + primary-for QPictureFormatPlugin (0x0x7fba0b26c750) + +Class QPixmapCache::Key + size=8 align=8 + base size=8 base align=8 +QPixmapCache::Key (0x0x7fba0b36c5a0) 0 + +Class QPixmapCache + size=1 align=1 + base size=0 base align=1 +QPixmapCache (0x0x7fba0b36c540) 0 empty + +Class QRasterWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRasterWindow::QPrivateSignal (0x0x7fba0b028720) 0 empty + +Vtable for QRasterWindow +QRasterWindow::_ZTV13QRasterWindow: 59u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QRasterWindow) +16 (int (*)(...))QRasterWindow::metaObject +24 (int (*)(...))QRasterWindow::qt_metacast +32 (int (*)(...))QRasterWindow::qt_metacall +40 (int (*)(...))QRasterWindow::~QRasterWindow +48 (int (*)(...))QRasterWindow::~QRasterWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QRasterWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QRasterWindow::redirected +328 (int (*)(...))-16 +336 (int (*)(...))(& _ZTI13QRasterWindow) +344 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev +352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +392 (int (*)(...))-40 +400 (int (*)(...))(& _ZTI13QRasterWindow) +408 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev +416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev +424 (int (*)(...))QPaintDevice::devType +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +440 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE +448 (int (*)(...))QPaintDevice::initPainter +456 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint +464 (int (*)(...))QPaintDevice::sharedPainter + +Class QRasterWindow + size=64 align=8 + base size=64 base align=8 +QRasterWindow (0x0x7fba0b020e38) 0 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16u) + QPaintDeviceWindow (0x0x7fba0b02d930) 0 + primary-for QRasterWindow (0x0x7fba0b020e38) + QWindow (0x0x7fba0b02d9a0) 0 + primary-for QPaintDeviceWindow (0x0x7fba0b02d930) + QObject (0x0x7fba0b028600) 0 + primary-for QWindow (0x0x7fba0b02d9a0) + QSurface (0x0x7fba0b028660) 16 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 344u) + QPaintDevice (0x0x7fba0b0286c0) 40 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 408u) + +Class QScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScreen::QPrivateSignal (0x0x7fba0b0287e0) 0 empty + +Vtable for QScreen +QScreen::_ZTV7QScreen: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QScreen) +16 (int (*)(...))QScreen::metaObject +24 (int (*)(...))QScreen::qt_metacast +32 (int (*)(...))QScreen::qt_metacall +40 (int (*)(...))QScreen::~QScreen +48 (int (*)(...))QScreen::~QScreen +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScreen + size=16 align=8 + base size=16 base align=8 +QScreen (0x0x7fba0b020f08) 0 + vptr=((& QScreen::_ZTV7QScreen) + 16u) + QObject (0x0x7fba0b028780) 0 + primary-for QScreen (0x0x7fba0b020f08) + +Class QSessionManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSessionManager::QPrivateSignal (0x0x7fba0b0288a0) 0 empty + +Vtable for QSessionManager +QSessionManager::_ZTV15QSessionManager: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSessionManager) +16 (int (*)(...))QSessionManager::metaObject +24 (int (*)(...))QSessionManager::qt_metacast +32 (int (*)(...))QSessionManager::qt_metacall +40 (int (*)(...))QSessionManager::~QSessionManager +48 (int (*)(...))QSessionManager::~QSessionManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSessionManager + size=16 align=8 + base size=16 base align=8 +QSessionManager (0x0x7fba0b020f70) 0 + vptr=((& QSessionManager::_ZTV15QSessionManager) + 16u) + QObject (0x0x7fba0b028840) 0 + primary-for QSessionManager (0x0x7fba0b020f70) + +Vtable for QStandardItem +QStandardItem::_ZTV13QStandardItem: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStandardItem) +16 (int (*)(...))QStandardItem::~QStandardItem +24 (int (*)(...))QStandardItem::~QStandardItem +32 (int (*)(...))QStandardItem::data +40 (int (*)(...))QStandardItem::setData +48 (int (*)(...))QStandardItem::clone +56 (int (*)(...))QStandardItem::type +64 (int (*)(...))QStandardItem::read +72 (int (*)(...))QStandardItem::write +80 (int (*)(...))QStandardItem::operator< + +Class QStandardItem + size=16 align=8 + base size=16 base align=8 +QStandardItem (0x0x7fba0b028900) 0 + vptr=((& QStandardItem::_ZTV13QStandardItem) + 16u) + +Class QStandardItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStandardItemModel::QPrivateSignal (0x0x7fba0b13c060) 0 empty + +Vtable for QStandardItemModel +QStandardItemModel::_ZTV18QStandardItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QStandardItemModel) +16 (int (*)(...))QStandardItemModel::metaObject +24 (int (*)(...))QStandardItemModel::qt_metacast +32 (int (*)(...))QStandardItemModel::qt_metacall +40 (int (*)(...))QStandardItemModel::~QStandardItemModel +48 (int (*)(...))QStandardItemModel::~QStandardItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStandardItemModel::index +120 (int (*)(...))QStandardItemModel::parent +128 (int (*)(...))QStandardItemModel::sibling +136 (int (*)(...))QStandardItemModel::rowCount +144 (int (*)(...))QStandardItemModel::columnCount +152 (int (*)(...))QStandardItemModel::hasChildren +160 (int (*)(...))QStandardItemModel::data +168 (int (*)(...))QStandardItemModel::setData +176 (int (*)(...))QStandardItemModel::headerData +184 (int (*)(...))QStandardItemModel::setHeaderData +192 (int (*)(...))QStandardItemModel::itemData +200 (int (*)(...))QStandardItemModel::setItemData +208 (int (*)(...))QStandardItemModel::mimeTypes +216 (int (*)(...))QStandardItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QStandardItemModel::dropMimeData +240 (int (*)(...))QStandardItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStandardItemModel::insertRows +264 (int (*)(...))QStandardItemModel::insertColumns +272 (int (*)(...))QStandardItemModel::removeRows +280 (int (*)(...))QStandardItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStandardItemModel::flags +328 (int (*)(...))QStandardItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStandardItemModel + size=16 align=8 + base size=16 base align=8 +QStandardItemModel (0x0x7fba0b0b8618) 0 + vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16u) + QAbstractItemModel (0x0x7fba0b0b8680) 0 + primary-for QStandardItemModel (0x0x7fba0b0b8618) + QObject (0x0x7fba0b13c000) 0 + primary-for QAbstractItemModel (0x0x7fba0b0b8680) + +Class QStaticText + size=8 align=8 + base size=8 base align=8 +QStaticText (0x0x7fba0b13c0c0) 0 + +Class QStyleHints::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyleHints::QPrivateSignal (0x0x7fba0b13c540) 0 empty + +Vtable for QStyleHints +QStyleHints::_ZTV11QStyleHints: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QStyleHints) +16 (int (*)(...))QStyleHints::metaObject +24 (int (*)(...))QStyleHints::qt_metacast +32 (int (*)(...))QStyleHints::qt_metacall +40 (int (*)(...))QStyleHints::~QStyleHints +48 (int (*)(...))QStyleHints::~QStyleHints +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QStyleHints + size=16 align=8 + base size=16 base align=8 +QStyleHints (0x0x7fba0b0b8888) 0 + vptr=((& QStyleHints::_ZTV11QStyleHints) + 16u) + QObject (0x0x7fba0b13c4e0) 0 + primary-for QStyleHints (0x0x7fba0b0b8888) + +Class QTextObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextObject::QPrivateSignal (0x0x7fba0b13c600) 0 empty + +Vtable for QTextObject +QTextObject::_ZTV11QTextObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextObject) +16 (int (*)(...))QTextObject::metaObject +24 (int (*)(...))QTextObject::qt_metacast +32 (int (*)(...))QTextObject::qt_metacall +40 (int (*)(...))QTextObject::~QTextObject +48 (int (*)(...))QTextObject::~QTextObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextObject + size=16 align=8 + base size=16 base align=8 +QTextObject (0x0x7fba0b0b88f0) 0 + vptr=((& QTextObject::_ZTV11QTextObject) + 16u) + QObject (0x0x7fba0b13c5a0) 0 + primary-for QTextObject (0x0x7fba0b0b88f0) + +Class QTextBlockGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBlockGroup::QPrivateSignal (0x0x7fba0b13c6c0) 0 empty + +Vtable for QTextBlockGroup +QTextBlockGroup::_ZTV15QTextBlockGroup: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTextBlockGroup) +16 (int (*)(...))QTextBlockGroup::metaObject +24 (int (*)(...))QTextBlockGroup::qt_metacast +32 (int (*)(...))QTextBlockGroup::qt_metacall +40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextBlockGroup + size=16 align=8 + base size=16 base align=8 +QTextBlockGroup (0x0x7fba0b0b8958) 0 + vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16u) + QTextObject (0x0x7fba0b0b89c0) 0 + primary-for QTextBlockGroup (0x0x7fba0b0b8958) + QObject (0x0x7fba0b13c660) 0 + primary-for QTextObject (0x0x7fba0b0b89c0) + +Vtable for QTextFrameLayoutData +QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextFrameLayoutData) +16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData +24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData + +Class QTextFrameLayoutData + size=8 align=8 + base size=8 base align=8 +QTextFrameLayoutData (0x0x7fba0b13c720) 0 nearly-empty + vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16u) + +Class QTextFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextFrame::QPrivateSignal (0x0x7fba0b13c7e0) 0 empty + +Class QTextFrame::iterator + size=32 align=8 + base size=28 base align=8 +QTextFrame::iterator (0x0x7fba0b13c840) 0 + +Vtable for QTextFrame +QTextFrame::_ZTV10QTextFrame: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextFrame) +16 (int (*)(...))QTextFrame::metaObject +24 (int (*)(...))QTextFrame::qt_metacast +32 (int (*)(...))QTextFrame::qt_metacall +40 (int (*)(...))QTextFrame::~QTextFrame +48 (int (*)(...))QTextFrame::~QTextFrame +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextFrame + size=16 align=8 + base size=16 base align=8 +QTextFrame (0x0x7fba0b0b8a28) 0 + vptr=((& QTextFrame::_ZTV10QTextFrame) + 16u) + QTextObject (0x0x7fba0b0b8a90) 0 + primary-for QTextFrame (0x0x7fba0b0b8a28) + QObject (0x0x7fba0b13c780) 0 + primary-for QTextObject (0x0x7fba0b0b8a90) + +Vtable for QTextBlockUserData +QTextBlockUserData::_ZTV18QTextBlockUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTextBlockUserData) +16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData +24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData + +Class QTextBlockUserData + size=8 align=8 + base size=8 base align=8 +QTextBlockUserData (0x0x7fba0b13cae0) 0 nearly-empty + vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16u) + +Class QTextBlock::iterator + size=24 align=8 + base size=20 base align=8 +QTextBlock::iterator (0x0x7fba0b13cba0) 0 + +Class QTextBlock + size=16 align=8 + base size=12 base align=8 +QTextBlock (0x0x7fba0b13cb40) 0 + +Class QTextFragment + size=16 align=8 + base size=16 base align=8 +QTextFragment (0x0x7fba0ae2f0c0) 0 + +Class QSyntaxHighlighter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSyntaxHighlighter::QPrivateSignal (0x0x7fba0ae2f3c0) 0 empty + +Vtable for QSyntaxHighlighter +QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSyntaxHighlighter) +16 (int (*)(...))QSyntaxHighlighter::metaObject +24 (int (*)(...))QSyntaxHighlighter::qt_metacast +32 (int (*)(...))QSyntaxHighlighter::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSyntaxHighlighter + size=16 align=8 + base size=16 base align=8 +QSyntaxHighlighter (0x0x7fba0ae451a0) 0 + vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16u) + QObject (0x0x7fba0ae2f360) 0 + primary-for QSyntaxHighlighter (0x0x7fba0ae451a0) + +Class QTextDocumentFragment + size=8 align=8 + base size=8 base align=8 +QTextDocumentFragment (0x0x7fba0ae2f420) 0 + +Class QTextDocumentWriter + size=8 align=8 + base size=8 base align=8 +QTextDocumentWriter (0x0x7fba0ae2f480) 0 + +Class QTextList::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextList::QPrivateSignal (0x0x7fba0ae2f540) 0 empty + +Vtable for QTextList +QTextList::_ZTV9QTextList: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextList) +16 (int (*)(...))QTextList::metaObject +24 (int (*)(...))QTextList::qt_metacast +32 (int (*)(...))QTextList::qt_metacall +40 (int (*)(...))QTextList::~QTextList +48 (int (*)(...))QTextList::~QTextList +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextList + size=16 align=8 + base size=16 base align=8 +QTextList (0x0x7fba0ae45208) 0 + vptr=((& QTextList::_ZTV9QTextList) + 16u) + QTextBlockGroup (0x0x7fba0ae45270) 0 + primary-for QTextList (0x0x7fba0ae45208) + QTextObject (0x0x7fba0ae452d8) 0 + primary-for QTextBlockGroup (0x0x7fba0ae45270) + QObject (0x0x7fba0ae2f4e0) 0 + primary-for QTextObject (0x0x7fba0ae452d8) + +Class QTextTableCell + size=16 align=8 + base size=12 base align=8 +QTextTableCell (0x0x7fba0ae2f5a0) 0 + +Class QTextTable::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextTable::QPrivateSignal (0x0x7fba0ae2f660) 0 empty + +Vtable for QTextTable +QTextTable::_ZTV10QTextTable: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextTable) +16 (int (*)(...))QTextTable::metaObject +24 (int (*)(...))QTextTable::qt_metacast +32 (int (*)(...))QTextTable::qt_metacall +40 (int (*)(...))QTextTable::~QTextTable +48 (int (*)(...))QTextTable::~QTextTable +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextTable + size=16 align=8 + base size=16 base align=8 +QTextTable (0x0x7fba0ae45340) 0 + vptr=((& QTextTable::_ZTV10QTextTable) + 16u) + QTextFrame (0x0x7fba0ae453a8) 0 + primary-for QTextTable (0x0x7fba0ae45340) + QTextObject (0x0x7fba0ae45410) 0 + primary-for QTextFrame (0x0x7fba0ae453a8) + QObject (0x0x7fba0ae2f600) 0 + primary-for QTextObject (0x0x7fba0ae45410) + +Class QValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QValidator::QPrivateSignal (0x0x7fba0ae2f720) 0 empty + +Vtable for QValidator +QValidator::_ZTV10QValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QValidator) +16 (int (*)(...))QValidator::metaObject +24 (int (*)(...))QValidator::qt_metacast +32 (int (*)(...))QValidator::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QValidator::fixup + +Class QValidator + size=16 align=8 + base size=16 base align=8 +QValidator (0x0x7fba0ae45478) 0 + vptr=((& QValidator::_ZTV10QValidator) + 16u) + QObject (0x0x7fba0ae2f6c0) 0 + primary-for QValidator (0x0x7fba0ae45478) + +Class QIntValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIntValidator::QPrivateSignal (0x0x7fba0ae2f7e0) 0 empty + +Vtable for QIntValidator +QIntValidator::_ZTV13QIntValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QIntValidator) +16 (int (*)(...))QIntValidator::metaObject +24 (int (*)(...))QIntValidator::qt_metacast +32 (int (*)(...))QIntValidator::qt_metacall +40 (int (*)(...))QIntValidator::~QIntValidator +48 (int (*)(...))QIntValidator::~QIntValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIntValidator::validate +120 (int (*)(...))QIntValidator::fixup +128 (int (*)(...))QIntValidator::setRange + +Class QIntValidator + size=24 align=8 + base size=24 base align=8 +QIntValidator (0x0x7fba0ae454e0) 0 + vptr=((& QIntValidator::_ZTV13QIntValidator) + 16u) + QValidator (0x0x7fba0ae45548) 0 + primary-for QIntValidator (0x0x7fba0ae454e0) + QObject (0x0x7fba0ae2f780) 0 + primary-for QValidator (0x0x7fba0ae45548) + +Class QDoubleValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleValidator::QPrivateSignal (0x0x7fba0ae2f8a0) 0 empty + +Vtable for QDoubleValidator +QDoubleValidator::_ZTV16QDoubleValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDoubleValidator) +16 (int (*)(...))QDoubleValidator::metaObject +24 (int (*)(...))QDoubleValidator::qt_metacast +32 (int (*)(...))QDoubleValidator::qt_metacall +40 (int (*)(...))QDoubleValidator::~QDoubleValidator +48 (int (*)(...))QDoubleValidator::~QDoubleValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDoubleValidator::validate +120 (int (*)(...))QValidator::fixup +128 (int (*)(...))QDoubleValidator::setRange + +Class QDoubleValidator + size=40 align=8 + base size=36 base align=8 +QDoubleValidator (0x0x7fba0ae455b0) 0 + vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16u) + QValidator (0x0x7fba0ae45618) 0 + primary-for QDoubleValidator (0x0x7fba0ae455b0) + QObject (0x0x7fba0ae2f840) 0 + primary-for QValidator (0x0x7fba0ae45618) + +Class QRegExpValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegExpValidator::QPrivateSignal (0x0x7fba0ae2f9c0) 0 empty + +Vtable for QRegExpValidator +QRegExpValidator::_ZTV16QRegExpValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QRegExpValidator) +16 (int (*)(...))QRegExpValidator::metaObject +24 (int (*)(...))QRegExpValidator::qt_metacast +32 (int (*)(...))QRegExpValidator::qt_metacall +40 (int (*)(...))QRegExpValidator::~QRegExpValidator +48 (int (*)(...))QRegExpValidator::~QRegExpValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegExpValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegExpValidator + size=24 align=8 + base size=24 base align=8 +QRegExpValidator (0x0x7fba0ae45680) 0 + vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16u) + QValidator (0x0x7fba0ae456e8) 0 + primary-for QRegExpValidator (0x0x7fba0ae45680) + QObject (0x0x7fba0ae2f960) 0 + primary-for QValidator (0x0x7fba0ae456e8) + +Class QRegularExpressionValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegularExpressionValidator::QPrivateSignal (0x0x7fba0ae2fa80) 0 empty + +Vtable for QRegularExpressionValidator +QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QRegularExpressionValidator) +16 (int (*)(...))QRegularExpressionValidator::metaObject +24 (int (*)(...))QRegularExpressionValidator::qt_metacast +32 (int (*)(...))QRegularExpressionValidator::qt_metacall +40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegularExpressionValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegularExpressionValidator + size=16 align=8 + base size=16 base align=8 +QRegularExpressionValidator (0x0x7fba0ae45750) 0 + vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16u) + QValidator (0x0x7fba0ae457b8) 0 + primary-for QRegularExpressionValidator (0x0x7fba0ae45750) + QObject (0x0x7fba0ae2fa20) 0 + primary-for QValidator (0x0x7fba0ae457b8) + +Class QNetworkRequest + size=8 align=8 + base size=8 base align=8 +QNetworkRequest (0x0x7fba0ae2fae0) 0 + +Class QNetworkCacheMetaData + size=8 align=8 + base size=8 base align=8 +QNetworkCacheMetaData (0x0x7fba0af2b060) 0 + +Class QAbstractNetworkCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractNetworkCache::QPrivateSignal (0x0x7fba0af2b720) 0 empty + +Vtable for QAbstractNetworkCache +QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractNetworkCache) +16 (int (*)(...))QAbstractNetworkCache::metaObject +24 (int (*)(...))QAbstractNetworkCache::qt_metacast +32 (int (*)(...))QAbstractNetworkCache::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNetworkCache + size=16 align=8 + base size=16 base align=8 +QAbstractNetworkCache (0x0x7fba0af57000) 0 + vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16u) + QObject (0x0x7fba0af2b6c0) 0 + primary-for QAbstractNetworkCache (0x0x7fba0af57000) + +Class QAbstractSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSocket::QPrivateSignal (0x0x7fba0af2b7e0) 0 empty + +Vtable for QAbstractSocket +QAbstractSocket::_ZTV15QAbstractSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSocket) +16 (int (*)(...))QAbstractSocket::metaObject +24 (int (*)(...))QAbstractSocket::qt_metacast +32 (int (*)(...))QAbstractSocket::qt_metacall +40 (int (*)(...))QAbstractSocket::~QAbstractSocket +48 (int (*)(...))QAbstractSocket::~QAbstractSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QAbstractSocket + size=16 align=8 + base size=16 base align=8 +QAbstractSocket (0x0x7fba0af57068) 0 + vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16u) + QIODevice (0x0x7fba0af570d0) 0 + primary-for QAbstractSocket (0x0x7fba0af57068) + QObject (0x0x7fba0af2b780) 0 + primary-for QIODevice (0x0x7fba0af570d0) + +Class QAuthenticator + size=8 align=8 + base size=8 base align=8 +QAuthenticator (0x0x7fba0af2bd80) 0 + +Class QDnsDomainNameRecord + size=8 align=8 + base size=8 base align=8 +QDnsDomainNameRecord (0x0x7fba0af2bde0) 0 + +Class QDnsHostAddressRecord + size=8 align=8 + base size=8 base align=8 +QDnsHostAddressRecord (0x0x7fba0ac2f120) 0 + +Class QDnsMailExchangeRecord + size=8 align=8 + base size=8 base align=8 +QDnsMailExchangeRecord (0x0x7fba0ac2f420) 0 + +Class QDnsServiceRecord + size=8 align=8 + base size=8 base align=8 +QDnsServiceRecord (0x0x7fba0ac2f720) 0 + +Class QDnsTextRecord + size=8 align=8 + base size=8 base align=8 +QDnsTextRecord (0x0x7fba0ac2fa20) 0 + +Class QDnsLookup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDnsLookup::QPrivateSignal (0x0x7fba0ac2fd80) 0 empty + +Vtable for QDnsLookup +QDnsLookup::_ZTV10QDnsLookup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDnsLookup) +16 (int (*)(...))QDnsLookup::metaObject +24 (int (*)(...))QDnsLookup::qt_metacast +32 (int (*)(...))QDnsLookup::qt_metacall +40 (int (*)(...))QDnsLookup::~QDnsLookup +48 (int (*)(...))QDnsLookup::~QDnsLookup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDnsLookup + size=16 align=8 + base size=16 base align=8 +QDnsLookup (0x0x7fba0af57af8) 0 + vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16u) + QObject (0x0x7fba0ac2fd20) 0 + primary-for QDnsLookup (0x0x7fba0af57af8) + +Class QIPv6Address + size=16 align=1 + base size=16 base align=1 +QIPv6Address (0x0x7fba0ac2fde0) 0 + +Class QHostAddress + size=8 align=8 + base size=8 base align=8 +QHostAddress (0x0x7fba0ac2fe40) 0 + +Class QHostInfo + size=8 align=8 + base size=8 base align=8 +QHostInfo (0x0x7fba0acdb660) 0 + +Class QHstsPolicy + size=8 align=8 + base size=8 base align=8 +QHstsPolicy (0x0x7fba0acdbb40) 0 + +Class QHttpPart + size=8 align=8 + base size=8 base align=8 +QHttpPart (0x0x7fba0ada8360) 0 + +Class QHttpMultiPart::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHttpMultiPart::QPrivateSignal (0x0x7fba0ada86c0) 0 empty + +Vtable for QHttpMultiPart +QHttpMultiPart::_ZTV14QHttpMultiPart: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QHttpMultiPart) +16 (int (*)(...))QHttpMultiPart::metaObject +24 (int (*)(...))QHttpMultiPart::qt_metacast +32 (int (*)(...))QHttpMultiPart::qt_metacall +40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QHttpMultiPart + size=16 align=8 + base size=16 base align=8 +QHttpMultiPart (0x0x7fba0ad15d68) 0 + vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16u) + QObject (0x0x7fba0ada8660) 0 + primary-for QHttpMultiPart (0x0x7fba0ad15d68) + +Class QLocalServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalServer::QPrivateSignal (0x0x7fba0ada8780) 0 empty + +Vtable for QLocalServer +QLocalServer::_ZTV12QLocalServer: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalServer) +16 (int (*)(...))QLocalServer::metaObject +24 (int (*)(...))QLocalServer::qt_metacast +32 (int (*)(...))QLocalServer::qt_metacall +40 (int (*)(...))QLocalServer::~QLocalServer +48 (int (*)(...))QLocalServer::~QLocalServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalServer::hasPendingConnections +120 (int (*)(...))QLocalServer::nextPendingConnection +128 (int (*)(...))QLocalServer::incomingConnection + +Class QLocalServer + size=16 align=8 + base size=16 base align=8 +QLocalServer (0x0x7fba0ad15dd0) 0 + vptr=((& QLocalServer::_ZTV12QLocalServer) + 16u) + QObject (0x0x7fba0ada8720) 0 + primary-for QLocalServer (0x0x7fba0ad15dd0) + +Class QLocalSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalSocket::QPrivateSignal (0x0x7fba0ada89c0) 0 empty + +Vtable for QLocalSocket +QLocalSocket::_ZTV12QLocalSocket: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalSocket) +16 (int (*)(...))QLocalSocket::metaObject +24 (int (*)(...))QLocalSocket::qt_metacast +32 (int (*)(...))QLocalSocket::qt_metacall +40 (int (*)(...))QLocalSocket::~QLocalSocket +48 (int (*)(...))QLocalSocket::~QLocalSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalSocket::isSequential +120 (int (*)(...))QLocalSocket::open +128 (int (*)(...))QLocalSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QLocalSocket::bytesAvailable +184 (int (*)(...))QLocalSocket::bytesToWrite +192 (int (*)(...))QLocalSocket::canReadLine +200 (int (*)(...))QLocalSocket::waitForReadyRead +208 (int (*)(...))QLocalSocket::waitForBytesWritten +216 (int (*)(...))QLocalSocket::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QLocalSocket::writeData + +Class QLocalSocket + size=16 align=8 + base size=16 base align=8 +QLocalSocket (0x0x7fba0ad15f70) 0 + vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16u) + QIODevice (0x0x7fba0aa23000) 0 + primary-for QLocalSocket (0x0x7fba0ad15f70) + QObject (0x0x7fba0ada8960) 0 + primary-for QIODevice (0x0x7fba0aa23000) + +Class QTcpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpSocket::QPrivateSignal (0x0x7fba0ada8a80) 0 empty + +Vtable for QTcpSocket +QTcpSocket::_ZTV10QTcpSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpSocket) +16 (int (*)(...))QTcpSocket::metaObject +24 (int (*)(...))QTcpSocket::qt_metacast +32 (int (*)(...))QTcpSocket::qt_metacall +40 (int (*)(...))QTcpSocket::~QTcpSocket +48 (int (*)(...))QTcpSocket::~QTcpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QTcpSocket + size=16 align=8 + base size=16 base align=8 +QTcpSocket (0x0x7fba0aa23068) 0 + vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16u) + QAbstractSocket (0x0x7fba0aa230d0) 0 + primary-for QTcpSocket (0x0x7fba0aa23068) + QIODevice (0x0x7fba0aa23138) 0 + primary-for QAbstractSocket (0x0x7fba0aa230d0) + QObject (0x0x7fba0ada8a20) 0 + primary-for QIODevice (0x0x7fba0aa23138) + +Class QSslCertificate + size=8 align=8 + base size=8 base align=8 +QSslCertificate (0x0x7fba0ada8c60) 0 + +Class QSslError + size=8 align=8 + base size=8 base align=8 +QSslError (0x0x7fba0aab20c0) 0 + +Class QSslSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSslSocket::QPrivateSignal (0x0x7fba0aab2a20) 0 empty + +Vtable for QSslSocket +QSslSocket::_ZTV10QSslSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSslSocket) +16 (int (*)(...))QSslSocket::metaObject +24 (int (*)(...))QSslSocket::qt_metacast +32 (int (*)(...))QSslSocket::qt_metacall +40 (int (*)(...))QSslSocket::~QSslSocket +48 (int (*)(...))QSslSocket::~QSslSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QSslSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QSslSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QSslSocket::bytesAvailable +184 (int (*)(...))QSslSocket::bytesToWrite +192 (int (*)(...))QSslSocket::canReadLine +200 (int (*)(...))QSslSocket::waitForReadyRead +208 (int (*)(...))QSslSocket::waitForBytesWritten +216 (int (*)(...))QSslSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QSslSocket::writeData +240 (int (*)(...))QSslSocket::resume +248 (int (*)(...))QSslSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QSslSocket::disconnectFromHost +272 (int (*)(...))QSslSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QSslSocket::setSocketDescriptor +296 (int (*)(...))QSslSocket::setSocketOption +304 (int (*)(...))QSslSocket::socketOption +312 (int (*)(...))QSslSocket::waitForConnected +320 (int (*)(...))QSslSocket::waitForDisconnected + +Class QSslSocket + size=16 align=8 + base size=16 base align=8 +QSslSocket (0x0x7fba0aa23af8) 0 + vptr=((& QSslSocket::_ZTV10QSslSocket) + 16u) + QTcpSocket (0x0x7fba0aa23b60) 0 + primary-for QSslSocket (0x0x7fba0aa23af8) + QAbstractSocket (0x0x7fba0aa23bc8) 0 + primary-for QTcpSocket (0x0x7fba0aa23b60) + QIODevice (0x0x7fba0aa23c30) 0 + primary-for QAbstractSocket (0x0x7fba0aa23bc8) + QObject (0x0x7fba0aab29c0) 0 + primary-for QIODevice (0x0x7fba0aa23c30) + +Class QSslConfiguration + size=8 align=8 + base size=8 base align=8 +QSslConfiguration (0x0x7fba0aab2a80) 0 + +Class QSslPreSharedKeyAuthenticator + size=8 align=8 + base size=8 base align=8 +QSslPreSharedKeyAuthenticator (0x0x7fba0ab6d240) 0 + +Class QNetworkAccessManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkAccessManager::QPrivateSignal (0x0x7fba0ab6db40) 0 empty + +Vtable for QNetworkAccessManager +QNetworkAccessManager::_ZTV21QNetworkAccessManager: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QNetworkAccessManager) +16 (int (*)(...))QNetworkAccessManager::metaObject +24 (int (*)(...))QNetworkAccessManager::qt_metacast +32 (int (*)(...))QNetworkAccessManager::qt_metacall +40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkAccessManager::createRequest + +Class QNetworkAccessManager + size=16 align=8 + base size=16 base align=8 +QNetworkAccessManager (0x0x7fba0ab698f0) 0 + vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16u) + QObject (0x0x7fba0ab6dae0) 0 + primary-for QNetworkAccessManager (0x0x7fba0ab698f0) + +Class QNetworkConfiguration + size=8 align=8 + base size=8 base align=8 +QNetworkConfiguration (0x0x7fba0ab6dba0) 0 + +Class QNetworkConfigurationManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkConfigurationManager::QPrivateSignal (0x0x7fba0a7fa060) 0 empty + +Vtable for QNetworkConfigurationManager +QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QNetworkConfigurationManager) +16 (int (*)(...))QNetworkConfigurationManager::metaObject +24 (int (*)(...))QNetworkConfigurationManager::qt_metacast +32 (int (*)(...))QNetworkConfigurationManager::qt_metacall +40 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager +48 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QNetworkConfigurationManager + size=16 align=8 + base size=16 base align=8 +QNetworkConfigurationManager (0x0x7fba0ab69af8) 0 + vptr=((& QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager) + 16u) + QObject (0x0x7fba0a7fa000) 0 + primary-for QNetworkConfigurationManager (0x0x7fba0ab69af8) + +Class QNetworkCookie + size=8 align=8 + base size=8 base align=8 +QNetworkCookie (0x0x7fba0a7fa3c0) 0 + +Class QNetworkCookieJar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkCookieJar::QPrivateSignal (0x0x7fba0a7faba0) 0 empty + +Vtable for QNetworkCookieJar +QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkCookieJar) +16 (int (*)(...))QNetworkCookieJar::metaObject +24 (int (*)(...))QNetworkCookieJar::qt_metacast +32 (int (*)(...))QNetworkCookieJar::qt_metacall +40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkCookieJar::cookiesForUrl +120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl +128 (int (*)(...))QNetworkCookieJar::insertCookie +136 (int (*)(...))QNetworkCookieJar::updateCookie +144 (int (*)(...))QNetworkCookieJar::deleteCookie +152 (int (*)(...))QNetworkCookieJar::validateCookie + +Class QNetworkCookieJar + size=16 align=8 + base size=16 base align=8 +QNetworkCookieJar (0x0x7fba0a877340) 0 + vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16u) + QObject (0x0x7fba0a7fab40) 0 + primary-for QNetworkCookieJar (0x0x7fba0a877340) + +Class QNetworkDatagram + size=8 align=8 + base size=8 base align=8 +QNetworkDatagram (0x0x7fba0a7fac00) 0 + +Class QNetworkDiskCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkDiskCache::QPrivateSignal (0x0x7fba0a910c00) 0 empty + +Vtable for QNetworkDiskCache +QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkDiskCache) +16 (int (*)(...))QNetworkDiskCache::metaObject +24 (int (*)(...))QNetworkDiskCache::qt_metacast +32 (int (*)(...))QNetworkDiskCache::qt_metacall +40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkDiskCache::metaData +120 (int (*)(...))QNetworkDiskCache::updateMetaData +128 (int (*)(...))QNetworkDiskCache::data +136 (int (*)(...))QNetworkDiskCache::remove +144 (int (*)(...))QNetworkDiskCache::cacheSize +152 (int (*)(...))QNetworkDiskCache::prepare +160 (int (*)(...))QNetworkDiskCache::insert +168 (int (*)(...))QNetworkDiskCache::clear +176 (int (*)(...))QNetworkDiskCache::expire + +Class QNetworkDiskCache + size=16 align=8 + base size=16 base align=8 +QNetworkDiskCache (0x0x7fba0a915d68) 0 + vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16u) + QAbstractNetworkCache (0x0x7fba0a915dd0) 0 + primary-for QNetworkDiskCache (0x0x7fba0a915d68) + QObject (0x0x7fba0a910ba0) 0 + primary-for QAbstractNetworkCache (0x0x7fba0a915dd0) + +Class QNetworkAddressEntry + size=8 align=8 + base size=8 base align=8 +QNetworkAddressEntry (0x0x7fba0a910c60) 0 + +Class QNetworkInterface + size=8 align=8 + base size=8 base align=8 +QNetworkInterface (0x0x7fba0a966360) 0 + +Class QNetworkProxyQuery + size=8 align=8 + base size=8 base align=8 +QNetworkProxyQuery (0x0x7fba0a966a80) 0 + +Class QNetworkProxy + size=8 align=8 + base size=8 base align=8 +QNetworkProxy (0x0x7fba0a5fc120) 0 + +Vtable for QNetworkProxyFactory +QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QNetworkProxyFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QNetworkProxyFactory + size=8 align=8 + base size=8 base align=8 +QNetworkProxyFactory (0x0x7fba0a5fc900) 0 nearly-empty + vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16u) + +Class QNetworkReply::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkReply::QPrivateSignal (0x0x7fba0a5fcae0) 0 empty + +Vtable for QNetworkReply +QNetworkReply::_ZTV13QNetworkReply: 36u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QNetworkReply) +16 (int (*)(...))QNetworkReply::metaObject +24 (int (*)(...))QNetworkReply::qt_metacast +32 (int (*)(...))QNetworkReply::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkReply::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QNetworkReply::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QNetworkReply::writeData +240 (int (*)(...))QNetworkReply::setReadBufferSize +248 (int (*)(...))__cxa_pure_virtual +256 (int (*)(...))QNetworkReply::ignoreSslErrors +264 (int (*)(...))QNetworkReply::sslConfigurationImplementation +272 (int (*)(...))QNetworkReply::setSslConfigurationImplementation +280 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation + +Class QNetworkReply + size=16 align=8 + base size=16 base align=8 +QNetworkReply (0x0x7fba0a623478) 0 + vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16u) + QIODevice (0x0x7fba0a6234e0) 0 + primary-for QNetworkReply (0x0x7fba0a623478) + QObject (0x0x7fba0a5fca80) 0 + primary-for QIODevice (0x0x7fba0a6234e0) + +Class QNetworkSession::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkSession::QPrivateSignal (0x0x7fba0a5fccc0) 0 empty + +Vtable for QNetworkSession +QNetworkSession::_ZTV15QNetworkSession: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QNetworkSession) +16 (int (*)(...))QNetworkSession::metaObject +24 (int (*)(...))QNetworkSession::qt_metacast +32 (int (*)(...))QNetworkSession::qt_metacall +40 (int (*)(...))QNetworkSession::~QNetworkSession +48 (int (*)(...))QNetworkSession::~QNetworkSession +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QNetworkSession::connectNotify +104 (int (*)(...))QNetworkSession::disconnectNotify + +Class QNetworkSession + size=24 align=8 + base size=24 base align=8 +QNetworkSession (0x0x7fba0a623548) 0 + vptr=((& QNetworkSession::_ZTV15QNetworkSession) + 16u) + QObject (0x0x7fba0a5fcc60) 0 + primary-for QNetworkSession (0x0x7fba0a623548) + +Class QTcpServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpServer::QPrivateSignal (0x0x7fba0a6c22a0) 0 empty + +Vtable for QTcpServer +QTcpServer::_ZTV10QTcpServer: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpServer) +16 (int (*)(...))QTcpServer::metaObject +24 (int (*)(...))QTcpServer::qt_metacast +32 (int (*)(...))QTcpServer::qt_metacall +40 (int (*)(...))QTcpServer::~QTcpServer +48 (int (*)(...))QTcpServer::~QTcpServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTcpServer::hasPendingConnections +120 (int (*)(...))QTcpServer::nextPendingConnection +128 (int (*)(...))QTcpServer::incomingConnection + +Class QTcpServer + size=16 align=8 + base size=16 base align=8 +QTcpServer (0x0x7fba0a623680) 0 + vptr=((& QTcpServer::_ZTV10QTcpServer) + 16u) + QObject (0x0x7fba0a6c2240) 0 + primary-for QTcpServer (0x0x7fba0a623680) + +Class QSslCertificateExtension + size=8 align=8 + base size=8 base align=8 +QSslCertificateExtension (0x0x7fba0a6c2300) 0 + +Class QSslCipher + size=8 align=8 + base size=8 base align=8 +QSslCipher (0x0x7fba0a6c2600) 0 + +Class QSslDiffieHellmanParameters + size=8 align=8 + base size=8 base align=8 +QSslDiffieHellmanParameters (0x0x7fba0a6c2de0) 0 + +Class QSslEllipticCurve + size=4 align=4 + base size=4 base align=4 +QSslEllipticCurve (0x0x7fba0a7b3900) 0 + +Class QSslKey + size=8 align=8 + base size=8 base align=8 +QSslKey (0x0x7fba0a3e6060) 0 + +Class QUdpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUdpSocket::QPrivateSignal (0x0x7fba0a3e63c0) 0 empty + +Vtable for QUdpSocket +QUdpSocket::_ZTV10QUdpSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUdpSocket) +16 (int (*)(...))QUdpSocket::metaObject +24 (int (*)(...))QUdpSocket::qt_metacast +32 (int (*)(...))QUdpSocket::qt_metacall +40 (int (*)(...))QUdpSocket::~QUdpSocket +48 (int (*)(...))QUdpSocket::~QUdpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QUdpSocket + size=16 align=8 + base size=16 base align=8 +QUdpSocket (0x0x7fba0a7bec30) 0 + vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16u) + QAbstractSocket (0x0x7fba0a7bec98) 0 + primary-for QUdpSocket (0x0x7fba0a7bec30) + QIODevice (0x0x7fba0a7bed00) 0 + primary-for QAbstractSocket (0x0x7fba0a7bec98) + QObject (0x0x7fba0a3e6360) 0 + primary-for QIODevice (0x0x7fba0a7bed00) + +Class QJSValue + size=8 align=8 + base size=8 base align=8 +QJSValue (0x0x7fba0a3e6420) 0 + +Class QJSEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QJSEngine::QPrivateSignal (0x0x7fba0a3e6720) 0 empty + +Vtable for QJSEngine +QJSEngine::_ZTV9QJSEngine: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QJSEngine) +16 (int (*)(...))QJSEngine::metaObject +24 (int (*)(...))QJSEngine::qt_metacast +32 (int (*)(...))QJSEngine::qt_metacall +40 (int (*)(...))QJSEngine::~QJSEngine +48 (int (*)(...))QJSEngine::~QJSEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QJSEngine + size=24 align=8 + base size=24 base align=8 +QJSEngine (0x0x7fba0a7bee38) 0 + vptr=((& QJSEngine::_ZTV9QJSEngine) + 16u) + QObject (0x0x7fba0a3e66c0) 0 + primary-for QJSEngine (0x0x7fba0a7bee38) + +Class QJSValueIterator + size=8 align=8 + base size=8 base align=8 +QJSValueIterator (0x0x7fba0a3e6900) 0 + +Class QQmlPrivate::RegisterType + size=128 align=8 + base size=124 base align=8 +QQmlPrivate::RegisterType (0x0x7fba0a3e6de0) 0 + +Class QQmlPrivate::RegisterInterface + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::RegisterInterface (0x0x7fba0a3e6e40) 0 + +Class QQmlPrivate::RegisterAutoParent + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterAutoParent (0x0x7fba0a3e6ea0) 0 + +Class QQmlPrivate::RegisterSingletonType + size=64 align=8 + base size=64 base align=8 +QQmlPrivate::RegisterSingletonType (0x0x7fba0a3e6f00) 0 + +Class QQmlPrivate::RegisterCompositeType + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::RegisterCompositeType (0x0x7fba0a3e6f60) 0 + +Class QQmlPrivate::RegisterCompositeSingletonType + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::RegisterCompositeSingletonType (0x0x7fba0a4e5000) 0 + +Class QQmlPrivate::CachedQmlUnit + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::CachedQmlUnit (0x0x7fba0a4e5060) 0 + +Class QQmlPrivate::RegisterQmlUnitCacheHook + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterQmlUnitCacheHook (0x0x7fba0a4e50c0) 0 + +Vtable for QQmlParserStatus +QQmlParserStatus::_ZTV16QQmlParserStatus: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlParserStatus) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlParserStatus + size=16 align=8 + base size=16 base align=8 +QQmlParserStatus (0x0x7fba0a4e5120) 0 + vptr=((& QQmlParserStatus::_ZTV16QQmlParserStatus) + 16u) + +Vtable for QQmlPropertyValueSource +QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQmlPropertyValueSource) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlPropertyValueSource + size=8 align=8 + base size=8 base align=8 +QQmlPropertyValueSource (0x0x7fba0a4e51e0) 0 nearly-empty + vptr=((& QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource) + 16u) + +Class QQmlListReference + size=8 align=8 + base size=8 base align=8 +QQmlListReference (0x0x7fba0a4e5300) 0 + +Vtable for QQmlAbstractUrlInterceptor +QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QQmlAbstractUrlInterceptor) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlAbstractUrlInterceptor + size=8 align=8 + base size=8 base align=8 +QQmlAbstractUrlInterceptor (0x0x7fba0a4e5960) 0 nearly-empty + vptr=((& QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor) + 16u) + +Class QQmlError + size=8 align=8 + base size=8 base align=8 +QQmlError (0x0x7fba0a4e59c0) 0 + +Class QQmlDebuggingEnabler + size=1 align=1 + base size=0 base align=1 +QQmlDebuggingEnabler (0x0x7fba0a4e5c60) 0 empty + +Vtable for QQmlImageProviderBase +QQmlImageProviderBase::_ZTV21QQmlImageProviderBase: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlImageProviderBase) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlImageProviderBase + size=8 align=8 + base size=8 base align=8 +QQmlImageProviderBase (0x0x7fba0a4e5cc0) 0 nearly-empty + vptr=((& QQmlImageProviderBase::_ZTV21QQmlImageProviderBase) + 16u) + +Class QQmlEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngine::QPrivateSignal (0x0x7fba0a4e5f00) 0 empty + +Vtable for QQmlEngine +QQmlEngine::_ZTV10QQmlEngine: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQmlEngine) +16 (int (*)(...))QQmlEngine::metaObject +24 (int (*)(...))QQmlEngine::qt_metacast +32 (int (*)(...))QQmlEngine::qt_metacall +40 (int (*)(...))QQmlEngine::~QQmlEngine +48 (int (*)(...))QQmlEngine::~QQmlEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlEngine + size=24 align=8 + base size=24 base align=8 +QQmlEngine (0x0x7fba0a4cb478) 0 + vptr=((& QQmlEngine::_ZTV10QQmlEngine) + 16u) + QJSEngine (0x0x7fba0a4cb4e0) 0 + primary-for QQmlEngine (0x0x7fba0a4cb478) + QObject (0x0x7fba0a4e5ea0) 0 + primary-for QJSEngine (0x0x7fba0a4cb4e0) + +Class QQmlApplicationEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlApplicationEngine::QPrivateSignal (0x0x7fba0a241000) 0 empty + +Vtable for QQmlApplicationEngine +QQmlApplicationEngine::_ZTV21QQmlApplicationEngine: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlApplicationEngine) +16 (int (*)(...))QQmlApplicationEngine::metaObject +24 (int (*)(...))QQmlApplicationEngine::qt_metacast +32 (int (*)(...))QQmlApplicationEngine::qt_metacall +40 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +48 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlApplicationEngine + size=24 align=8 + base size=24 base align=8 +QQmlApplicationEngine (0x0x7fba0a4cb548) 0 + vptr=((& QQmlApplicationEngine::_ZTV21QQmlApplicationEngine) + 16u) + QQmlEngine (0x0x7fba0a4cb5b0) 0 + primary-for QQmlApplicationEngine (0x0x7fba0a4cb548) + QJSEngine (0x0x7fba0a4cb618) 0 + primary-for QQmlEngine (0x0x7fba0a4cb5b0) + QObject (0x0x7fba0a4e5f60) 0 + primary-for QJSEngine (0x0x7fba0a4cb618) + +Class QQmlComponent::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlComponent::QPrivateSignal (0x0x7fba0a2410c0) 0 empty + +Vtable for QQmlComponent +QQmlComponent::_ZTV13QQmlComponent: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlComponent) +16 (int (*)(...))QQmlComponent::metaObject +24 (int (*)(...))QQmlComponent::qt_metacast +32 (int (*)(...))QQmlComponent::qt_metacall +40 (int (*)(...))QQmlComponent::~QQmlComponent +48 (int (*)(...))QQmlComponent::~QQmlComponent +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlComponent::create +120 (int (*)(...))QQmlComponent::beginCreate +128 (int (*)(...))QQmlComponent::completeCreate + +Class QQmlComponent + size=16 align=8 + base size=16 base align=8 +QQmlComponent (0x0x7fba0a4cb680) 0 + vptr=((& QQmlComponent::_ZTV13QQmlComponent) + 16u) + QObject (0x0x7fba0a241060) 0 + primary-for QQmlComponent (0x0x7fba0a4cb680) + +Class QQmlContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlContext::QPrivateSignal (0x0x7fba0a241900) 0 empty + +Vtable for QQmlContext +QQmlContext::_ZTV11QQmlContext: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QQmlContext) +16 (int (*)(...))QQmlContext::metaObject +24 (int (*)(...))QQmlContext::qt_metacast +32 (int (*)(...))QQmlContext::qt_metacall +40 (int (*)(...))QQmlContext::~QQmlContext +48 (int (*)(...))QQmlContext::~QQmlContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlContext + size=16 align=8 + base size=16 base align=8 +QQmlContext (0x0x7fba0a4cbbc8) 0 + vptr=((& QQmlContext::_ZTV11QQmlContext) + 16u) + QObject (0x0x7fba0a2418a0) 0 + primary-for QQmlContext (0x0x7fba0a4cbbc8) + +Class QQmlScriptString + size=8 align=8 + base size=8 base align=8 +QQmlScriptString (0x0x7fba0a241a80) 0 + +Class QQmlExpression::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExpression::QPrivateSignal (0x0x7fba0a241cc0) 0 empty + +Vtable for QQmlExpression +QQmlExpression::_ZTV14QQmlExpression: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QQmlExpression) +16 (int (*)(...))QQmlExpression::metaObject +24 (int (*)(...))QQmlExpression::qt_metacast +32 (int (*)(...))QQmlExpression::qt_metacall +40 (int (*)(...))QQmlExpression::~QQmlExpression +48 (int (*)(...))QQmlExpression::~QQmlExpression +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlExpression + size=16 align=8 + base size=16 base align=8 +QQmlExpression (0x0x7fba0a4cbc30) 0 + vptr=((& QQmlExpression::_ZTV14QQmlExpression) + 16u) + QObject (0x0x7fba0a241c60) 0 + primary-for QQmlExpression (0x0x7fba0a4cbc30) + +Vtable for QQmlTypesExtensionInterface +QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QQmlTypesExtensionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlTypesExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlTypesExtensionInterface (0x0x7fba0a241d20) 0 nearly-empty + vptr=((& QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface) + 16u) + +Vtable for QQmlExtensionInterface +QQmlExtensionInterface::_ZTV22QQmlExtensionInterface: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QQmlExtensionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlExtensionInterface (0x0x7fba0a4cbc98) 0 nearly-empty + vptr=((& QQmlExtensionInterface::_ZTV22QQmlExtensionInterface) + 16u) + QQmlTypesExtensionInterface (0x0x7fba0a241d80) 0 nearly-empty + primary-for QQmlExtensionInterface (0x0x7fba0a4cbc98) + +Class QQmlExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExtensionPlugin::QPrivateSignal (0x0x7fba0a241f60) 0 empty + +Vtable for QQmlExtensionPlugin +QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin: 22u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +16 (int (*)(...))QQmlExtensionPlugin::metaObject +24 (int (*)(...))QQmlExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlExtensionPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQmlExtensionPlugin::initializeEngine +128 (int (*)(...))-16 +136 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +144 0u +152 0u +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QQmlExtensionPlugin::_ZThn16_N19QQmlExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlExtensionPlugin (0x0x7fba0a2ea7e0) 0 + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 16u) + QObject (0x0x7fba0a241ea0) 0 + primary-for QQmlExtensionPlugin (0x0x7fba0a2ea7e0) + QQmlExtensionInterface (0x0x7fba0a4cbd00) 16 nearly-empty + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 144u) + QQmlTypesExtensionInterface (0x0x7fba0a241f00) 16 nearly-empty + primary-for QQmlExtensionInterface (0x0x7fba0a4cbd00) + +Class QQmlFile + size=8 align=8 + base size=8 base align=8 +QQmlFile (0x0x7fba0a302000) 0 + +Class QQmlFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlFileSelector::QPrivateSignal (0x0x7fba0a3020c0) 0 empty + +Vtable for QQmlFileSelector +QQmlFileSelector::_ZTV16QQmlFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlFileSelector) +16 (int (*)(...))QQmlFileSelector::metaObject +24 (int (*)(...))QQmlFileSelector::qt_metacast +32 (int (*)(...))QQmlFileSelector::qt_metacall +40 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +48 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlFileSelector + size=16 align=8 + base size=16 base align=8 +QQmlFileSelector (0x0x7fba0a4cbdd0) 0 + vptr=((& QQmlFileSelector::_ZTV16QQmlFileSelector) + 16u) + QObject (0x0x7fba0a302060) 0 + primary-for QQmlFileSelector (0x0x7fba0a4cbdd0) + +Vtable for QQmlIncubator +QQmlIncubator::_ZTV13QQmlIncubator: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlIncubator) +16 (int (*)(...))QQmlIncubator::~QQmlIncubator +24 (int (*)(...))QQmlIncubator::~QQmlIncubator +32 (int (*)(...))QQmlIncubator::statusChanged +40 (int (*)(...))QQmlIncubator::setInitialState + +Class QQmlIncubator + size=16 align=8 + base size=16 base align=8 +QQmlIncubator (0x0x7fba0a302120) 0 + vptr=((& QQmlIncubator::_ZTV13QQmlIncubator) + 16u) + +Vtable for QQmlIncubationController +QQmlIncubationController::_ZTV24QQmlIncubationController: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQmlIncubationController) +16 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +24 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +32 (int (*)(...))QQmlIncubationController::incubatingObjectCountChanged + +Class QQmlIncubationController + size=16 align=8 + base size=16 base align=8 +QQmlIncubationController (0x0x7fba0a302180) 0 + vptr=((& QQmlIncubationController::_ZTV24QQmlIncubationController) + 16u) + +Class QQmlInfo + size=16 align=8 + base size=16 base align=8 +QQmlInfo (0x0x7fba0a4cbe38) 0 + QDebug (0x0x7fba0a3021e0) 0 + +Vtable for QQmlNetworkAccessManagerFactory +QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI31QQmlNetworkAccessManagerFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlNetworkAccessManagerFactory + size=8 align=8 + base size=8 base align=8 +QQmlNetworkAccessManagerFactory (0x0x7fba0a3b60c0) 0 nearly-empty + vptr=((& QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory) + 16u) + +Class QQmlProperty + size=8 align=8 + base size=8 base align=8 +QQmlProperty (0x0x7fba0a3b6120) 0 + +Class QQmlPropertyMap::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlPropertyMap::QPrivateSignal (0x0x7fba0a3b6c60) 0 empty + +Vtable for QQmlPropertyMap +QQmlPropertyMap::_ZTV15QQmlPropertyMap: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQmlPropertyMap) +16 (int (*)(...))QQmlPropertyMap::metaObject +24 (int (*)(...))QQmlPropertyMap::qt_metacast +32 (int (*)(...))QQmlPropertyMap::qt_metacall +40 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +48 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlPropertyMap::updateValue + +Class QQmlPropertyMap + size=16 align=8 + base size=16 base align=8 +QQmlPropertyMap (0x0x7fba0a3d9680) 0 + vptr=((& QQmlPropertyMap::_ZTV15QQmlPropertyMap) + 16u) + QObject (0x0x7fba0a3b6c00) 0 + primary-for QQmlPropertyMap (0x0x7fba0a3d9680) + +Class QQuickTransform::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTransform::QPrivateSignal (0x0x7fba0a3b6d20) 0 empty + +Vtable for QQuickTransform +QQuickTransform::_ZTV15QQuickTransform: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQuickTransform) +16 (int (*)(...))QQuickTransform::metaObject +24 (int (*)(...))QQuickTransform::qt_metacast +32 (int (*)(...))QQuickTransform::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QQuickTransform + size=16 align=8 + base size=16 base align=8 +QQuickTransform (0x0x7fba0a3d96e8) 0 + vptr=((& QQuickTransform::_ZTV15QQuickTransform) + 16u) + QObject (0x0x7fba0a3b6cc0) 0 + primary-for QQuickTransform (0x0x7fba0a3d96e8) + +Class QQuickItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItem::QPrivateSignal (0x0x7fba0a3b6e40) 0 empty + +Class QQuickItem::ItemChangeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::ItemChangeData (0x0x7fba0a3b6ea0) 0 + +Class QQuickItem::UpdatePaintNodeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::UpdatePaintNodeData (0x0x7fba0a3b6f00) 0 + +Vtable for QQuickItem +QQuickItem::_ZTV10QQuickItem: 55u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickItem) +16 (int (*)(...))QQuickItem::metaObject +24 (int (*)(...))QQuickItem::qt_metacast +32 (int (*)(...))QQuickItem::qt_metacall +40 (int (*)(...))QQuickItem::~QQuickItem +48 (int (*)(...))QQuickItem::~QQuickItem +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickItem::isTextureProvider +152 (int (*)(...))QQuickItem::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickItem::geometryChanged +368 (int (*)(...))QQuickItem::updatePaintNode +376 (int (*)(...))QQuickItem::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))-16 +400 (int (*)(...))(& _ZTI10QQuickItem) +408 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD1Ev +416 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD0Ev +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickItem + size=32 align=8 + base size=32 base align=8 +QQuickItem (0x0x7fba09ff45b0) 0 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 16u) + QObject (0x0x7fba0a3b6d80) 0 + primary-for QQuickItem (0x0x7fba09ff45b0) + QQmlParserStatus (0x0x7fba0a3b6de0) 16 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 408u) + +Class QQuickFramebufferObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickFramebufferObject::QPrivateSignal (0x0x7fba0a05a720) 0 empty + +Vtable for QQuickFramebufferObject::Renderer +QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN23QQuickFramebufferObject8RendererE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QQuickFramebufferObject::Renderer::createFramebufferObject +48 (int (*)(...))QQuickFramebufferObject::Renderer::synchronize + +Class QQuickFramebufferObject::Renderer + size=16 align=8 + base size=16 base align=8 +QQuickFramebufferObject::Renderer (0x0x7fba0a05a780) 0 + vptr=((& QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE) + 16u) + +Vtable for QQuickFramebufferObject +QQuickFramebufferObject::_ZTV23QQuickFramebufferObject: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +16 (int (*)(...))QQuickFramebufferObject::metaObject +24 (int (*)(...))QQuickFramebufferObject::qt_metacast +32 (int (*)(...))QQuickFramebufferObject::qt_metacall +40 0u +48 0u +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickFramebufferObject::isTextureProvider +152 (int (*)(...))QQuickFramebufferObject::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickFramebufferObject::geometryChanged +368 (int (*)(...))QQuickFramebufferObject::updatePaintNode +376 (int (*)(...))QQuickFramebufferObject::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))-16 +408 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +416 0u +424 0u +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickFramebufferObject + size=32 align=8 + base size=32 base align=8 +QQuickFramebufferObject (0x0x7fba0a3d9820) 0 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 16u) + QQuickItem (0x0x7fba0a0a3bd0) 0 + primary-for QQuickFramebufferObject (0x0x7fba0a3d9820) + QObject (0x0x7fba0a05a660) 0 + primary-for QQuickItem (0x0x7fba0a0a3bd0) + QQmlParserStatus (0x0x7fba0a05a6c0) 16 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 416u) + +Vtable for QQuickTextureFactory +QQuickTextureFactory::_ZTV20QQuickTextureFactory: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickTextureFactory) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))QQuickTextureFactory::image + +Class QQuickTextureFactory + size=16 align=8 + base size=16 base align=8 +QQuickTextureFactory (0x0x7fba0a3d9888) 0 + vptr=((& QQuickTextureFactory::_ZTV20QQuickTextureFactory) + 16u) + QObject (0x0x7fba0a05a7e0) 0 + primary-for QQuickTextureFactory (0x0x7fba0a3d9888) + +Class QQuickImageResponse::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickImageResponse::QPrivateSignal (0x0x7fba0a05a8a0) 0 empty + +Vtable for QQuickImageResponse +QQuickImageResponse::_ZTV19QQuickImageResponse: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageResponse) +16 (int (*)(...))QQuickImageResponse::metaObject +24 (int (*)(...))QQuickImageResponse::qt_metacast +32 (int (*)(...))QQuickImageResponse::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQuickImageResponse::errorString +128 (int (*)(...))QQuickImageResponse::cancel + +Class QQuickImageResponse + size=16 align=8 + base size=16 base align=8 +QQuickImageResponse (0x0x7fba0a3d98f0) 0 + vptr=((& QQuickImageResponse::_ZTV19QQuickImageResponse) + 16u) + QObject (0x0x7fba0a05a840) 0 + primary-for QQuickImageResponse (0x0x7fba0a3d98f0) + +Vtable for QQuickImageProvider +QQuickImageProvider::_ZTV19QQuickImageProvider: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageProvider) +16 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +24 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +32 (int (*)(...))QQuickImageProvider::imageType +40 (int (*)(...))QQuickImageProvider::flags +48 (int (*)(...))QQuickImageProvider::requestImage +56 (int (*)(...))QQuickImageProvider::requestPixmap +64 (int (*)(...))QQuickImageProvider::requestTexture + +Class QQuickImageProvider + size=16 align=8 + base size=16 base align=8 +QQuickImageProvider (0x0x7fba0a3d9958) 0 + vptr=((& QQuickImageProvider::_ZTV19QQuickImageProvider) + 16u) + QQmlImageProviderBase (0x0x7fba0a05a900) 0 nearly-empty + primary-for QQuickImageProvider (0x0x7fba0a3d9958) + +Vtable for QQuickAsyncImageProvider +QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQuickAsyncImageProvider) +16 0u +24 0u +32 (int (*)(...))QQuickImageProvider::imageType +40 (int (*)(...))QQuickImageProvider::flags +48 (int (*)(...))QQuickImageProvider::requestImage +56 (int (*)(...))QQuickImageProvider::requestPixmap +64 (int (*)(...))QQuickImageProvider::requestTexture +72 (int (*)(...))__cxa_pure_virtual + +Class QQuickAsyncImageProvider + size=24 align=8 + base size=24 base align=8 +QQuickAsyncImageProvider (0x0x7fba0a3d99c0) 0 + vptr=((& QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider) + 16u) + QQuickImageProvider (0x0x7fba0a3d9a28) 0 + primary-for QQuickAsyncImageProvider (0x0x7fba0a3d99c0) + QQmlImageProviderBase (0x0x7fba0a05a960) 0 nearly-empty + primary-for QQuickImageProvider (0x0x7fba0a3d9a28) + +Class QQuickItemGrabResult::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItemGrabResult::QPrivateSignal (0x0x7fba0a05aa20) 0 empty + +Vtable for QQuickItemGrabResult +QQuickItemGrabResult::_ZTV20QQuickItemGrabResult: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickItemGrabResult) +16 (int (*)(...))QQuickItemGrabResult::metaObject +24 (int (*)(...))QQuickItemGrabResult::qt_metacast +32 (int (*)(...))QQuickItemGrabResult::qt_metacall +40 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +48 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +56 (int (*)(...))QQuickItemGrabResult::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickItemGrabResult + size=16 align=8 + base size=16 base align=8 +QQuickItemGrabResult (0x0x7fba0a3d9a90) 0 + vptr=((& QQuickItemGrabResult::_ZTV20QQuickItemGrabResult) + 16u) + QObject (0x0x7fba0a05a9c0) 0 + primary-for QQuickItemGrabResult (0x0x7fba0a3d9a90) + +Class QQuickPaintedItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickPaintedItem::QPrivateSignal (0x0x7fba0a05ab40) 0 empty + +Vtable for QQuickPaintedItem +QQuickPaintedItem::_ZTV17QQuickPaintedItem: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QQuickPaintedItem) +16 (int (*)(...))QQuickPaintedItem::metaObject +24 (int (*)(...))QQuickPaintedItem::qt_metacast +32 (int (*)(...))QQuickPaintedItem::qt_metacall +40 0u +48 0u +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickPaintedItem::isTextureProvider +152 (int (*)(...))QQuickPaintedItem::textureProvider +160 (int (*)(...))QQuickPaintedItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickItem::geometryChanged +368 (int (*)(...))QQuickPaintedItem::updatePaintNode +376 (int (*)(...))QQuickPaintedItem::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))-16 +408 (int (*)(...))(& _ZTI17QQuickPaintedItem) +416 0u +424 0u +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickPaintedItem + size=32 align=8 + base size=32 base align=8 +QQuickPaintedItem (0x0x7fba0a3d9af8) 0 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 16u) + QQuickItem (0x0x7fba0a0d5e00) 0 + primary-for QQuickPaintedItem (0x0x7fba0a3d9af8) + QObject (0x0x7fba0a05aa80) 0 + primary-for QQuickItem (0x0x7fba0a0d5e00) + QQmlParserStatus (0x0x7fba0a05aae0) 16 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 416u) + +Class QQuickRenderControl::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickRenderControl::QPrivateSignal (0x0x7fba0a05ad80) 0 empty + +Vtable for QQuickRenderControl +QQuickRenderControl::_ZTV19QQuickRenderControl: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickRenderControl) +16 (int (*)(...))QQuickRenderControl::metaObject +24 (int (*)(...))QQuickRenderControl::qt_metacast +32 (int (*)(...))QQuickRenderControl::qt_metacall +40 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +48 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickRenderControl::renderWindow + +Class QQuickRenderControl + size=16 align=8 + base size=16 base align=8 +QQuickRenderControl (0x0x7fba0a3d9c98) 0 + vptr=((& QQuickRenderControl::_ZTV19QQuickRenderControl) + 16u) + QObject (0x0x7fba0a05ad20) 0 + primary-for QQuickRenderControl (0x0x7fba0a3d9c98) + +Class QQuickTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextDocument::QPrivateSignal (0x0x7fba0a05ae40) 0 empty + +Vtable for QQuickTextDocument +QQuickTextDocument::_ZTV18QQuickTextDocument: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QQuickTextDocument) +16 (int (*)(...))QQuickTextDocument::metaObject +24 (int (*)(...))QQuickTextDocument::qt_metacast +32 (int (*)(...))QQuickTextDocument::qt_metacall +40 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +48 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickTextDocument + size=16 align=8 + base size=16 base align=8 +QQuickTextDocument (0x0x7fba0a3d9d00) 0 + vptr=((& QQuickTextDocument::_ZTV18QQuickTextDocument) + 16u) + QObject (0x0x7fba0a05ade0) 0 + primary-for QQuickTextDocument (0x0x7fba0a3d9d00) + +Class QSGGeometry::Attribute + size=16 align=4 + base size=16 base align=4 +QSGGeometry::Attribute (0x0x7fba0a1741e0) 0 + +Class QSGGeometry::AttributeSet + size=16 align=8 + base size=16 base align=8 +QSGGeometry::AttributeSet (0x0x7fba0a174240) 0 + +Class QSGGeometry::Point2D + size=8 align=4 + base size=8 base align=4 +QSGGeometry::Point2D (0x0x7fba0a1742a0) 0 + +Class QSGGeometry::TexturedPoint2D + size=16 align=4 + base size=16 base align=4 +QSGGeometry::TexturedPoint2D (0x0x7fba0a174300) 0 + +Class QSGGeometry::ColoredPoint2D + size=12 align=4 + base size=12 base align=4 +QSGGeometry::ColoredPoint2D (0x0x7fba0a174360) 0 + +Vtable for QSGGeometry +QSGGeometry::_ZTV11QSGGeometry: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGGeometry) +16 (int (*)(...))QSGGeometry::~QSGGeometry +24 (int (*)(...))QSGGeometry::~QSGGeometry + +Class QSGGeometry + size=128 align=8 + base size=128 base align=8 +QSGGeometry (0x0x7fba0a174180) 0 + vptr=((& QSGGeometry::_ZTV11QSGGeometry) + 16u) + +Vtable for QSGNode +QSGNode::_ZTV7QSGNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QSGNode) +16 (int (*)(...))QSGNode::~QSGNode +24 (int (*)(...))QSGNode::~QSGNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGNode + size=80 align=8 + base size=80 base align=8 +QSGNode (0x0x7fba0a174840) 0 + vptr=((& QSGNode::_ZTV7QSGNode) + 16u) + +Vtable for QSGBasicGeometryNode +QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGBasicGeometryNode) +16 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +24 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGBasicGeometryNode + size=112 align=8 + base size=112 base align=8 +QSGBasicGeometryNode (0x0x7fba0a1aa410) 0 + vptr=((& QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode) + 16u) + QSGNode (0x0x7fba0a174c00) 0 + primary-for QSGBasicGeometryNode (0x0x7fba0a1aa410) + +Vtable for QSGGeometryNode +QSGGeometryNode::_ZTV15QSGGeometryNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSGGeometryNode) +16 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +24 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGGeometryNode + size=144 align=8 + base size=144 base align=8 +QSGGeometryNode (0x0x7fba0a1aa478) 0 + vptr=((& QSGGeometryNode::_ZTV15QSGGeometryNode) + 16u) + QSGBasicGeometryNode (0x0x7fba0a1aa4e0) 0 + primary-for QSGGeometryNode (0x0x7fba0a1aa478) + QSGNode (0x0x7fba0a174c60) 0 + primary-for QSGBasicGeometryNode (0x0x7fba0a1aa4e0) + +Vtable for QSGClipNode +QSGClipNode::_ZTV11QSGClipNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGClipNode) +16 (int (*)(...))QSGClipNode::~QSGClipNode +24 (int (*)(...))QSGClipNode::~QSGClipNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGClipNode + size=152 align=8 + base size=152 base align=8 +QSGClipNode (0x0x7fba0a1aa548) 0 + vptr=((& QSGClipNode::_ZTV11QSGClipNode) + 16u) + QSGBasicGeometryNode (0x0x7fba0a1aa5b0) 0 + primary-for QSGClipNode (0x0x7fba0a1aa548) + QSGNode (0x0x7fba0a174cc0) 0 + primary-for QSGBasicGeometryNode (0x0x7fba0a1aa5b0) + +Vtable for QSGTransformNode +QSGTransformNode::_ZTV16QSGTransformNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGTransformNode) +16 (int (*)(...))QSGTransformNode::~QSGTransformNode +24 (int (*)(...))QSGTransformNode::~QSGTransformNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGTransformNode + size=216 align=8 + base size=216 base align=8 +QSGTransformNode (0x0x7fba0a1aa618) 0 + vptr=((& QSGTransformNode::_ZTV16QSGTransformNode) + 16u) + QSGNode (0x0x7fba0a174d20) 0 + primary-for QSGTransformNode (0x0x7fba0a1aa618) + +Vtable for QSGRootNode +QSGRootNode::_ZTV11QSGRootNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGRootNode) +16 (int (*)(...))QSGRootNode::~QSGRootNode +24 (int (*)(...))QSGRootNode::~QSGRootNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGRootNode + size=88 align=8 + base size=88 base align=8 +QSGRootNode (0x0x7fba0a1aa680) 0 + vptr=((& QSGRootNode::_ZTV11QSGRootNode) + 16u) + QSGNode (0x0x7fba0a174d80) 0 + primary-for QSGRootNode (0x0x7fba0a1aa680) + +Vtable for QSGOpacityNode +QSGOpacityNode::_ZTV14QSGOpacityNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGOpacityNode) +16 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +24 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +32 (int (*)(...))QSGOpacityNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGOpacityNode + size=96 align=8 + base size=96 base align=8 +QSGOpacityNode (0x0x7fba0a1aa820) 0 + vptr=((& QSGOpacityNode::_ZTV14QSGOpacityNode) + 16u) + QSGNode (0x0x7fba0a174f00) 0 + primary-for QSGOpacityNode (0x0x7fba0a1aa820) + +Vtable for QSGNodeVisitor +QSGNodeVisitor::_ZTV14QSGNodeVisitor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGNodeVisitor) +16 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +24 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +32 (int (*)(...))QSGNodeVisitor::enterTransformNode +40 (int (*)(...))QSGNodeVisitor::leaveTransformNode +48 (int (*)(...))QSGNodeVisitor::enterClipNode +56 (int (*)(...))QSGNodeVisitor::leaveClipNode +64 (int (*)(...))QSGNodeVisitor::enterGeometryNode +72 (int (*)(...))QSGNodeVisitor::leaveGeometryNode +80 (int (*)(...))QSGNodeVisitor::enterOpacityNode +88 (int (*)(...))QSGNodeVisitor::leaveOpacityNode +96 (int (*)(...))QSGNodeVisitor::visitNode +104 (int (*)(...))QSGNodeVisitor::visitChildren + +Class QSGNodeVisitor + size=8 align=8 + base size=8 base align=8 +QSGNodeVisitor (0x0x7fba0a174f60) 0 nearly-empty + vptr=((& QSGNodeVisitor::_ZTV14QSGNodeVisitor) + 16u) + +Vtable for QSGRendererInterface +QSGRendererInterface::_ZTV20QSGRendererInterface: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGRendererInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QSGRendererInterface::getResource +48 (int (*)(...))QSGRendererInterface::getResource +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRendererInterface + size=8 align=8 + base size=8 base align=8 +QSGRendererInterface (0x0x7fba09efb000) 0 nearly-empty + vptr=((& QSGRendererInterface::_ZTV20QSGRendererInterface) + 16u) + +Class QQuickWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickWindow::QPrivateSignal (0x0x7fba09efb420) 0 empty + +Vtable for QQuickWindow +QQuickWindow::_ZTV12QQuickWindow: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QQuickWindow) +16 (int (*)(...))QQuickWindow::metaObject +24 (int (*)(...))QQuickWindow::qt_metacast +32 (int (*)(...))QQuickWindow::qt_metacall +40 (int (*)(...))QQuickWindow::~QQuickWindow +48 (int (*)(...))QQuickWindow::~QQuickWindow +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QQuickWindow::focusInEvent +184 (int (*)(...))QQuickWindow::focusOutEvent +192 (int (*)(...))QQuickWindow::showEvent +200 (int (*)(...))QQuickWindow::hideEvent +208 (int (*)(...))QQuickWindow::keyPressEvent +216 (int (*)(...))QQuickWindow::keyReleaseEvent +224 (int (*)(...))QQuickWindow::mousePressEvent +232 (int (*)(...))QQuickWindow::mouseReleaseEvent +240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +248 (int (*)(...))QQuickWindow::mouseMoveEvent +256 (int (*)(...))QQuickWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI12QQuickWindow) +312 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD1Ev +320 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickWindow + size=40 align=8 + base size=40 base align=8 +QQuickWindow (0x0x7fba0a1aaa28) 0 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 16u) + QWindow (0x0x7fba09f37e00) 0 + primary-for QQuickWindow (0x0x7fba0a1aaa28) + QObject (0x0x7fba09efb360) 0 + primary-for QWindow (0x0x7fba09f37e00) + QSurface (0x0x7fba09efb3c0) 16 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 312u) + +Class QQuickView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickView::QPrivateSignal (0x0x7fba09efb7e0) 0 empty + +Vtable for QQuickView +QQuickView::_ZTV10QQuickView: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickView) +16 (int (*)(...))QQuickView::metaObject +24 (int (*)(...))QQuickView::qt_metacast +32 (int (*)(...))QQuickView::qt_metacall +40 (int (*)(...))QQuickView::~QQuickView +48 (int (*)(...))QQuickView::~QQuickView +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QQuickView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickView::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QQuickWindow::focusInEvent +184 (int (*)(...))QQuickWindow::focusOutEvent +192 (int (*)(...))QQuickWindow::showEvent +200 (int (*)(...))QQuickWindow::hideEvent +208 (int (*)(...))QQuickView::keyPressEvent +216 (int (*)(...))QQuickView::keyReleaseEvent +224 (int (*)(...))QQuickView::mousePressEvent +232 (int (*)(...))QQuickView::mouseReleaseEvent +240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +248 (int (*)(...))QQuickView::mouseMoveEvent +256 (int (*)(...))QQuickWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI10QQuickView) +312 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD1Ev +320 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickView + size=40 align=8 + base size=40 base align=8 +QQuickView (0x0x7fba0a1aab60) 0 + vptr=((& QQuickView::_ZTV10QQuickView) + 16u) + QQuickWindow (0x0x7fba0a1aabc8) 0 + primary-for QQuickView (0x0x7fba0a1aab60) + QWindow (0x0x7fba09fa84d0) 0 + primary-for QQuickWindow (0x0x7fba0a1aabc8) + QObject (0x0x7fba09efb720) 0 + primary-for QWindow (0x0x7fba09fa84d0) + QSurface (0x0x7fba09efb780) 16 + vptr=((& QQuickView::_ZTV10QQuickView) + 312u) + +Class QSGAbstractRenderer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGAbstractRenderer::QPrivateSignal (0x0x7fba09efb8a0) 0 empty + +Vtable for QSGAbstractRenderer +QSGAbstractRenderer::_ZTV19QSGAbstractRenderer: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QSGAbstractRenderer) +16 (int (*)(...))QSGAbstractRenderer::metaObject +24 (int (*)(...))QSGAbstractRenderer::qt_metacast +32 (int (*)(...))QSGAbstractRenderer::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QSGAbstractRenderer + size=16 align=8 + base size=16 base align=8 +QSGAbstractRenderer (0x0x7fba0a1aac30) 0 + vptr=((& QSGAbstractRenderer::_ZTV19QSGAbstractRenderer) + 16u) + QObject (0x0x7fba09efb840) 0 + primary-for QSGAbstractRenderer (0x0x7fba0a1aac30) + +Class QSGEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGEngine::QPrivateSignal (0x0x7fba09efbae0) 0 empty + +Vtable for QSGEngine +QSGEngine::_ZTV9QSGEngine: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSGEngine) +16 (int (*)(...))QSGEngine::metaObject +24 (int (*)(...))QSGEngine::qt_metacast +32 (int (*)(...))QSGEngine::qt_metacall +40 (int (*)(...))QSGEngine::~QSGEngine +48 (int (*)(...))QSGEngine::~QSGEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSGEngine + size=16 align=8 + base size=16 base align=8 +QSGEngine (0x0x7fba0a1aad68) 0 + vptr=((& QSGEngine::_ZTV9QSGEngine) + 16u) + QObject (0x0x7fba09efba80) 0 + primary-for QSGEngine (0x0x7fba0a1aad68) + +Class QSGMaterialShader::RenderState + size=16 align=8 + base size=16 base align=8 +QSGMaterialShader::RenderState (0x0x7fba09efbd80) 0 + +Vtable for QSGMaterialShader +QSGMaterialShader::_ZTV17QSGMaterialShader: 12u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGMaterialShader) +16 0u +24 0u +32 (int (*)(...))QSGMaterialShader::activate +40 (int (*)(...))QSGMaterialShader::deactivate +48 (int (*)(...))QSGMaterialShader::updateState +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QSGMaterialShader::compile +72 (int (*)(...))QSGMaterialShader::initialize +80 (int (*)(...))QSGMaterialShader::vertexShader +88 (int (*)(...))QSGMaterialShader::fragmentShader + +Class QSGMaterialShader + size=32 align=8 + base size=32 base align=8 +QSGMaterialShader (0x0x7fba09efbd20) 0 + vptr=((& QSGMaterialShader::_ZTV17QSGMaterialShader) + 16u) + +Class QSGMaterialType + size=1 align=1 + base size=0 base align=1 +QSGMaterialType (0x0x7fba09c6e060) 0 empty + +Vtable for QSGMaterial +QSGMaterial::_ZTV11QSGMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGMaterial) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QSGMaterial::compare + +Class QSGMaterial + size=24 align=8 + base size=24 base align=8 +QSGMaterial (0x0x7fba09c6e0c0) 0 + vptr=((& QSGMaterial::_ZTV11QSGMaterial) + 16u) + +Vtable for QSGFlatColorMaterial +QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGFlatColorMaterial) +16 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +24 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +32 (int (*)(...))QSGFlatColorMaterial::type +40 (int (*)(...))QSGFlatColorMaterial::createShader +48 (int (*)(...))QSGFlatColorMaterial::compare + +Class QSGFlatColorMaterial + size=40 align=8 + base size=40 base align=8 +QSGFlatColorMaterial (0x0x7fba09c7a0d0) 0 + vptr=((& QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial) + 16u) + QSGMaterial (0x0x7fba09c6e2a0) 0 + primary-for QSGFlatColorMaterial (0x0x7fba09c7a0d0) + +Class QSGTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTexture::QPrivateSignal (0x0x7fba09c6e360) 0 empty + +Vtable for QSGTexture +QSGTexture::_ZTV10QSGTexture: 22u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSGTexture) +16 (int (*)(...))QSGTexture::metaObject +24 (int (*)(...))QSGTexture::qt_metacast +32 (int (*)(...))QSGTexture::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QSGTexture::normalizedTextureSubRect +152 (int (*)(...))QSGTexture::isAtlasTexture +160 (int (*)(...))QSGTexture::removedFromAtlas +168 (int (*)(...))__cxa_pure_virtual + +Class QSGTexture + size=16 align=8 + base size=16 base align=8 +QSGTexture (0x0x7fba09c7a138) 0 + vptr=((& QSGTexture::_ZTV10QSGTexture) + 16u) + QObject (0x0x7fba09c6e300) 0 + primary-for QSGTexture (0x0x7fba09c7a138) + +Class QSGDynamicTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGDynamicTexture::QPrivateSignal (0x0x7fba09c6e420) 0 empty + +Vtable for QSGDynamicTexture +QSGDynamicTexture::_ZTV17QSGDynamicTexture: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGDynamicTexture) +16 (int (*)(...))QSGDynamicTexture::metaObject +24 (int (*)(...))QSGDynamicTexture::qt_metacast +32 (int (*)(...))QSGDynamicTexture::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QSGTexture::normalizedTextureSubRect +152 (int (*)(...))QSGTexture::isAtlasTexture +160 (int (*)(...))QSGTexture::removedFromAtlas +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QSGDynamicTexture + size=16 align=8 + base size=16 base align=8 +QSGDynamicTexture (0x0x7fba09c7a1a0) 0 + vptr=((& QSGDynamicTexture::_ZTV17QSGDynamicTexture) + 16u) + QSGTexture (0x0x7fba09c7a208) 0 + primary-for QSGDynamicTexture (0x0x7fba09c7a1a0) + QObject (0x0x7fba09c6e3c0) 0 + primary-for QSGTexture (0x0x7fba09c7a208) + +Vtable for QSGImageNode +QSGImageNode::_ZTV12QSGImageNode: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QSGImageNode) +16 0u +24 0u +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QSGImageNode + size=144 align=8 + base size=144 base align=8 +QSGImageNode (0x0x7fba09c7a270) 0 + vptr=((& QSGImageNode::_ZTV12QSGImageNode) + 16u) + QSGGeometryNode (0x0x7fba09c7a2d8) 0 + primary-for QSGImageNode (0x0x7fba09c7a270) + QSGBasicGeometryNode (0x0x7fba09c7a340) 0 + primary-for QSGGeometryNode (0x0x7fba09c7a2d8) + QSGNode (0x0x7fba09c6e480) 0 + primary-for QSGBasicGeometryNode (0x0x7fba09c7a340) + +Vtable for QSGNinePatchNode +QSGNinePatchNode::_ZTV16QSGNinePatchNode: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGNinePatchNode) +16 0u +24 0u +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual + +Class QSGNinePatchNode + size=144 align=8 + base size=144 base align=8 +QSGNinePatchNode (0x0x7fba09c7a478) 0 + vptr=((& QSGNinePatchNode::_ZTV16QSGNinePatchNode) + 16u) + QSGGeometryNode (0x0x7fba09c7a4e0) 0 + primary-for QSGNinePatchNode (0x0x7fba09c7a478) + QSGBasicGeometryNode (0x0x7fba09c7a548) 0 + primary-for QSGGeometryNode (0x0x7fba09c7a4e0) + QSGNode (0x0x7fba09c6e660) 0 + primary-for QSGBasicGeometryNode (0x0x7fba09c7a548) + +Vtable for QSGRectangleNode +QSGRectangleNode::_ZTV16QSGRectangleNode: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGRectangleNode) +16 0u +24 0u +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRectangleNode + size=144 align=8 + base size=144 base align=8 +QSGRectangleNode (0x0x7fba09c7a5b0) 0 + vptr=((& QSGRectangleNode::_ZTV16QSGRectangleNode) + 16u) + QSGGeometryNode (0x0x7fba09c7a618) 0 + primary-for QSGRectangleNode (0x0x7fba09c7a5b0) + QSGBasicGeometryNode (0x0x7fba09c7a680) 0 + primary-for QSGGeometryNode (0x0x7fba09c7a618) + QSGNode (0x0x7fba09c6e6c0) 0 + primary-for QSGBasicGeometryNode (0x0x7fba09c7a680) + +Vtable for QSGRenderNode::RenderState +QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QSGRenderNode11RenderStateE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))QSGRenderNode::RenderState::get + +Class QSGRenderNode::RenderState + size=8 align=8 + base size=8 base align=8 +QSGRenderNode::RenderState (0x0x7fba09c6e780) 0 nearly-empty + vptr=((& QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE) + 16u) + +Vtable for QSGRenderNode +QSGRenderNode::_ZTV13QSGRenderNode: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSGRenderNode) +16 0u +24 0u +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))QSGRenderNode::changedStates +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QSGRenderNode::releaseResources +72 (int (*)(...))QSGRenderNode::flags +80 (int (*)(...))QSGRenderNode::rect + +Class QSGRenderNode + size=88 align=8 + base size=88 base align=8 +QSGRenderNode (0x0x7fba09c7a6e8) 0 + vptr=((& QSGRenderNode::_ZTV13QSGRenderNode) + 16u) + QSGNode (0x0x7fba09c6e720) 0 + primary-for QSGRenderNode (0x0x7fba09c7a6e8) + +Vtable for QSGSimpleRectNode +QSGSimpleRectNode::_ZTV17QSGSimpleRectNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGSimpleRectNode) +16 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +24 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleRectNode + size=320 align=8 + base size=320 base align=8 +QSGSimpleRectNode (0x0x7fba09c7ab60) 0 + vptr=((& QSGSimpleRectNode::_ZTV17QSGSimpleRectNode) + 16u) + QSGGeometryNode (0x0x7fba09c7abc8) 0 + primary-for QSGSimpleRectNode (0x0x7fba09c7ab60) + QSGBasicGeometryNode (0x0x7fba09c7ac30) 0 + primary-for QSGGeometryNode (0x0x7fba09c7abc8) + QSGNode (0x0x7fba09c6ed80) 0 + primary-for QSGBasicGeometryNode (0x0x7fba09c7ac30) + +Vtable for QSGOpaqueTextureMaterial +QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QSGOpaqueTextureMaterial) +16 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +24 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +32 (int (*)(...))QSGOpaqueTextureMaterial::type +40 (int (*)(...))QSGOpaqueTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGOpaqueTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGOpaqueTextureMaterial (0x0x7fba09c7ac98) 0 + vptr=((& QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial) + 16u) + QSGMaterial (0x0x7fba09c6ede0) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7fba09c7ac98) + +Vtable for QSGTextureMaterial +QSGTextureMaterial::_ZTV18QSGTextureMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureMaterial) +16 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +24 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +32 (int (*)(...))QSGTextureMaterial::type +40 (int (*)(...))QSGTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGTextureMaterial (0x0x7fba09c7ad00) 0 + vptr=((& QSGTextureMaterial::_ZTV18QSGTextureMaterial) + 16u) + QSGOpaqueTextureMaterial (0x0x7fba09c7ad68) 0 + primary-for QSGTextureMaterial (0x0x7fba09c7ad00) + QSGMaterial (0x0x7fba09c6ee40) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7fba09c7ad68) + +Vtable for QSGSimpleTextureNode +QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGSimpleTextureNode) +16 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +24 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleTextureNode + size=384 align=8 + base size=384 base align=8 +QSGSimpleTextureNode (0x0x7fba09c7add0) 0 + vptr=((& QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode) + 16u) + QSGGeometryNode (0x0x7fba09c7ae38) 0 + primary-for QSGSimpleTextureNode (0x0x7fba09c7add0) + QSGBasicGeometryNode (0x0x7fba09c7aea0) 0 + primary-for QSGGeometryNode (0x0x7fba09c7ae38) + QSGNode (0x0x7fba09c6eea0) 0 + primary-for QSGBasicGeometryNode (0x0x7fba09c7aea0) + +Class QSGTextureProvider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTextureProvider::QPrivateSignal (0x0x7fba09a37180) 0 empty + +Vtable for QSGTextureProvider +QSGTextureProvider::_ZTV18QSGTextureProvider: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureProvider) +16 (int (*)(...))QSGTextureProvider::metaObject +24 (int (*)(...))QSGTextureProvider::qt_metacast +32 (int (*)(...))QSGTextureProvider::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSGTextureProvider + size=16 align=8 + base size=16 base align=8 +QSGTextureProvider (0x0x7fba09a3a068) 0 + vptr=((& QSGTextureProvider::_ZTV18QSGTextureProvider) + 16u) + QObject (0x0x7fba09a37120) 0 + primary-for QSGTextureProvider (0x0x7fba09a3a068) + +Vtable for QSGVertexColorMaterial +QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QSGVertexColorMaterial) +16 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +24 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +32 (int (*)(...))QSGVertexColorMaterial::type +40 (int (*)(...))QSGVertexColorMaterial::createShader +48 (int (*)(...))QSGVertexColorMaterial::compare + +Class QSGVertexColorMaterial + size=24 align=8 + base size=24 base align=8 +QSGVertexColorMaterial (0x0x7fba09a3a0d0) 0 + vptr=((& QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial) + 16u) + QSGMaterial (0x0x7fba09a371e0) 0 + primary-for QSGVertexColorMaterial (0x0x7fba09a3a0d0) + +Class QQuickStyle + size=1 align=1 + base size=0 base align=1 +QQuickStyle (0x0x7fba09a37240) 0 empty + diff --git a/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.11.0.linux-gcc-amd64.txt b/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.11.0.linux-gcc-amd64.txt new file mode 100644 index 00000000000..4c7accb3159 --- /dev/null +++ b/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.11.0.linux-gcc-amd64.txt @@ -0,0 +1,10993 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f64f1187e40) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f64f0d9a600) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f64f0d9a840) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f64f0d9aa80) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f64f0d9acc0) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f64f0d9ae40) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f64f0dce240) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f64f0e539c0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f64f0e53a80) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f64f0e53de0) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f64f0e53ea0) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f64f0e53f60) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f64f0e8b060) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f64f0e8b300) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f64f0e8b4e0) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f64f0e8b960) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f64f0e8b9c0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f64f0f38660) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f64f0f386c0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f64f0e993a8) 0 empty + std::input_iterator_tag (0x0x7f64f0f38720) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f64f0e99410) 0 empty + std::forward_iterator_tag (0x0x7f64f0e99478) 0 empty + std::input_iterator_tag (0x0x7f64f0f38780) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f64f0e994e0) 0 empty + std::bidirectional_iterator_tag (0x0x7f64f0e99548) 0 empty + std::forward_iterator_tag (0x0x7f64f0e995b0) 0 empty + std::input_iterator_tag (0x0x7f64f0f387e0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f64f0f7d480) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f64f0f7d4e0) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f64f0f7d540) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f64f0f7d5a0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f64f0f7d600) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f64f0c84120) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f64f0c84360) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f64f0c84420) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f64f0c84480) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f64f0c84540) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f64f0c845a0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f64f0c84a20) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f64f0c84a80) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f64f0c84ae0) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f64f0e99af8) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f64f0c84b40) 0 nearly-empty + primary-for std::bad_exception (0x0x7f64f0e99af8) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f64f0c84ba0) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f64f0c84c00) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f64f0e99d00) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f64f09b1060) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f64f0e99d00) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f64f0e99d68) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7f64f0e99dd0) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f64f0e99d68) + std::exception (0x0x7f64f09b10c0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f64f0e99dd0) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f64f09b1120) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f64f09b1d20) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f64f07b0a20) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f64f07b0a80) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f64f08b7960) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f64f08b79c0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f64f08b7a80) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f64f08b7ae0) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f64f08b7b40) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f64f08b7ba0) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f64f08b7cc0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f64f08b7d20) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f64f0621180) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f64f06211e0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f64f04079c0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f64f0407a20) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f64f043d9c0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f64f02247e0) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f64f0434b60) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f64f02248a0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f64f0434bc8) 0 + std::_Bit_iterator_base (0x0x7f64f0434c30) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f64f0224900) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f64f0434c98) 0 + std::_Bit_iterator_base (0x0x7f64f0434d00) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f64f0224960) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f64f0072780) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f64f0145540) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f64f01454e0) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f64efef84e0) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f64eeabf000) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f64eeabf060) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f64ee753ae0) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f64ee753b40) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f64ee753ba0) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f64ee753c00) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f64ee753ea0) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f64ee7c1420) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f64ee759a28) 0 + std::__atomic_flag_base (0x0x7f64ee7c1480) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f64ee6d51a0) 0 + QAtomicInteger<int> (0x0x7f64ee6d5208) 0 + QBasicAtomicInteger<int> (0x0x7f64ee5e2ba0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f64edf6a180) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f64edfdc1e0) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f64edfdc300) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f64ee196c30) 0 + QGenericArgument (0x0x7f64edfdc360) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f64edfdc4e0) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f64edfdc5a0) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f64ee0ba600) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f64ee0ba660) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f64ee0ba900) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f64ee0ba960) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f64ee0bacc0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f64ee0bad20) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f64ee0bad80) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f64ee0bade0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f64ee0bae40) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f64ede40240) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f64ede5a208) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f64ede40300) 0 nearly-empty + primary-for std::logic_error (0x0x7f64ede5a208) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f64ede5a270) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f64ede5a2d8) 0 + primary-for std::domain_error (0x0x7f64ede5a270) + std::exception (0x0x7f64ede40360) 0 nearly-empty + primary-for std::logic_error (0x0x7f64ede5a2d8) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f64ede5a340) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f64ede5a3a8) 0 + primary-for std::invalid_argument (0x0x7f64ede5a340) + std::exception (0x0x7f64ede403c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f64ede5a3a8) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f64ede5a410) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f64ede5a478) 0 + primary-for std::length_error (0x0x7f64ede5a410) + std::exception (0x0x7f64ede40420) 0 nearly-empty + primary-for std::logic_error (0x0x7f64ede5a478) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f64ede5a4e0) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f64ede5a548) 0 + primary-for std::out_of_range (0x0x7f64ede5a4e0) + std::exception (0x0x7f64ede40480) 0 nearly-empty + primary-for std::logic_error (0x0x7f64ede5a548) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f64ede5a5b0) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f64ede404e0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f64ede5a5b0) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f64ede5a618) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f64ede5a680) 0 + primary-for std::range_error (0x0x7f64ede5a618) + std::exception (0x0x7f64ede40540) 0 nearly-empty + primary-for std::runtime_error (0x0x7f64ede5a680) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f64ede5a6e8) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f64ede5a750) 0 + primary-for std::overflow_error (0x0x7f64ede5a6e8) + std::exception (0x0x7f64ede405a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f64ede5a750) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f64ede5a7b8) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f64ede5a820) 0 + primary-for std::underflow_error (0x0x7f64ede5a7b8) + std::exception (0x0x7f64ede40600) 0 nearly-empty + primary-for std::runtime_error (0x0x7f64ede5a820) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f64ede40780) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f64ede409c0) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f64ede40b40) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f64ede5ad00) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7f64ede5ad68) 0 + primary-for std::system_error (0x0x7f64ede5ad00) + std::exception (0x0x7f64ede40d80) 0 nearly-empty + primary-for std::runtime_error (0x0x7f64ede5ad68) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f64edaf28f0) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7f64edaf2958) 0 + primary-for std::ios_base::failure (0x0x7f64edaf28f0) + std::runtime_error (0x0x7f64edaf29c0) 0 + primary-for std::system_error (0x0x7f64edaf2958) + std::exception (0x0x7f64edb200c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f64edaf29c0) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f64edb20120) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f64edb20180) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f64edb201e0) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f64edb20060) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f64edb20960) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f64edca1060) 0 empty + +VTT for std::basic_ostream<char> +std::basic_ostream<char>::_ZTTSo: 2u entries +0 ((& std::basic_ostream<char>::_ZTVSo) + 24u) +8 ((& std::basic_ostream<char>::_ZTVSo) + 64u) + +VTT for std::basic_ostream<wchar_t> +std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream<char> +std::basic_istream<char>::_ZTTSi: 2u entries +0 ((& std::basic_istream<char>::_ZTVSi) + 24u) +8 ((& std::basic_istream<char>::_ZTVSi) + 64u) + +VTT for std::basic_istream<wchar_t> +std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream<char> (0x0x7f64ed7be270 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream<char> (0x0x7f64ed7be340 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream<char> +std::basic_iostream<char>::_ZTTSd: 7u entries +0 ((& std::basic_iostream<char>::_ZTVSd) + 24u) +8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream<char>::_ZTVSd) + 104u) +48 ((& std::basic_iostream<char>::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f64ed7be6e8 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f64ed7be7b8 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f64eda9e8a0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f64eda9e900) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f64ed506c60) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f64ed5f1000) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f64ed5f1480) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f64ed685300) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f64ed685960) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f64ed685900) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f64ed466a20) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f64ed205660) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f64ed012300) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f64ed012360) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f64ed0123c0) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f64ed012780) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f64ed0127e0) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f64ed017270) 0 empty + QListData::NotIndirectLayout (0x0x7f64ed012840) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f64ed0dd540) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f64ed0128a0) 0 empty + QListData::NotIndirectLayout (0x0x7f64ed012900) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f64ed0172d8) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f64ed012960) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f64ed0129c0) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f64ed012720) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f64ed012e40) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f64ece8d0c0) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f64ece8d060) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f64ece7dd00) 0 + QList<QString> (0x0x7f64ece7dd68) 0 + QListSpecialMethods<QString> (0x0x7f64ece8d2a0) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f64ece8d6c0) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f64ecbaf2a0) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f64ecbaf900) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f64ecbafa80) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f64ecbafb40) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f64ecafa680) 0 + std::__uses_alloc_base (0x0x7f64ecbafae0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f64ec9b4ba0) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f64ec9b4de0) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f64ec9b4ea0) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f64ec6fb000) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f64ec6fb180) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f64ec6fb5a0) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f64ec6fb6c0) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f64ec81f060) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f64ec81f480) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f64ec81f780) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f64ec2fb000) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f64ec3c6e40) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f64ec3c6ea0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f64ec4110c0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f64ec411060) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f64ec0d3360) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f64ec0d33c0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f64ec0d3480) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f64ec0c4888) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f64ec0d3420) 0 + primary-for QAbstractAnimation (0x0x7f64ec0c4888) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f64ec0d3540) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f64ec0c48f0) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f64ec0d34e0) 0 + primary-for QAnimationDriver (0x0x7f64ec0c48f0) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f64ec0d3600) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f64ec0c4958) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f64ec0d35a0) 0 + primary-for QEventLoop (0x0x7f64ec0c4958) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f64ec0d37e0) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f64ec0d38a0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f64ec0d3900) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f64ec0c4a90) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f64ec0d3840) 0 + primary-for QAbstractEventDispatcher (0x0x7f64ec0c4a90) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f64ec0d3ba0) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f64ec0c4c98) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7f64ec0d3c00) 0 nearly-empty + primary-for std::bad_cast (0x0x7f64ec0c4c98) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f64ec0c4d00) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7f64ec0d3c60) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f64ec0c4d00) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f64ec218f70) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7f64ec293d20) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f64ec218f70) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f64ec293de0) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f64ec293e40) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f64ec293f60) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f64ebf36480) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f64ebf369c0) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f64ebf36d80) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f64ebf36d20) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f64ebf36de0) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f64ebccf6c0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f64ebccf780) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f64ebccf720) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f64ebccf7e0) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f64ebccf660) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f64ebb24300) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f64ebb24960) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f64ebb24900) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f64ebb24a20) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f64ebb249c0) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f64ebc4ed20) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f64eb993420) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f64eba30b40) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f64eba33d00) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f64eba30ae0) 0 + primary-for QAbstractItemModel (0x0x7f64eba33d00) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f64eba94420) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f64eba90410) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f64eba90478) 0 + primary-for QAbstractTableModel (0x0x7f64eba90410) + QObject (0x0x7f64eba943c0) 0 + primary-for QAbstractItemModel (0x0x7f64eba90478) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f64eba944e0) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f64eba904e0) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f64eba90548) 0 + primary-for QAbstractListModel (0x0x7f64eba904e0) + QObject (0x0x7f64eba94480) 0 + primary-for QAbstractItemModel (0x0x7f64eba90548) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f64eba94780) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f64eba94840) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f64eba90680) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f64eba906e8) 0 + primary-for QAbstractProxyModel (0x0x7f64eba90680) + QObject (0x0x7f64eba947e0) 0 + primary-for QAbstractItemModel (0x0x7f64eba906e8) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f64eba94900) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f64eba90750) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f64eba948a0) 0 + primary-for QAbstractState (0x0x7f64eba90750) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f64eba949c0) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f64eba907b8) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f64eba94960) 0 + primary-for QAbstractTransition (0x0x7f64eba907b8) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f64eba94a80) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f64eba90820) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f64eba90888) 0 + primary-for QAnimationGroup (0x0x7f64eba90820) + QObject (0x0x7f64eba94a20) 0 + primary-for QAbstractAnimation (0x0x7f64eba90888) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f64eb8037e0) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f64eb803a80) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f64eb803b40) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f64eb803e40) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f64eba90f08) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f64eb803de0) 0 + primary-for QIODevice (0x0x7f64eba90f08) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f64eb4c40c0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f64eb4bd068) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f64eb4bd0d0) 0 + primary-for QBuffer (0x0x7f64eb4bd068) + QObject (0x0x7f64eb4c4060) 0 + primary-for QIODevice (0x0x7f64eb4bd0d0) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f64eb4c4180) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f64eb4c4120) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f64eb4c42a0) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f64eb4c4240) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f64eb4c4480) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f64eb4c4660) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f64eb4c4c60) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f64eb4c4d20) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f64eb28bd20) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f64eb2cb1e0) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f64eb2a05b0) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f64eb2cb240) 0 + primary-for QTimerEvent (0x0x7f64eb2a05b0) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f64eb2a0618) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f64eb2cb2a0) 0 + primary-for QChildEvent (0x0x7f64eb2a0618) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f64eb2a0b60) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f64eb2cb780) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f64eb2a0b60) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f64eb2a0bc8) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f64eb2cb7e0) 0 + primary-for QDeferredDeleteEvent (0x0x7f64eb2a0bc8) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f64eb2cb8a0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f64eb2a0c30) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f64eb2cb840) 0 + primary-for QCoreApplication (0x0x7f64eb2a0c30) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f64eb2cb900) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f64eb2cb960) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f64eb2cbf60) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f64eb3bf000) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f64eb3bf0c0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f64eb3bf5a0) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f64eb3bf840) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f64eb07a000) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f64eb07a060) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f64eb3bff60) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f64eb122180) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f64eb122660) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f64eb264600) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f64eb2648a0) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f64eb264ae0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f64eb264c60) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f64eaff11e0) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f64eaff1180) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f64eacea6c0) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f64eacea780) 0 empty + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f64eadbf900) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f64eadc5d68) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f64eadc5dd0) 0 + primary-for QFileDevice (0x0x7f64eadc5d68) + QObject (0x0x7f64eadbf8a0) 0 + primary-for QIODevice (0x0x7f64eadc5dd0) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f64eadbfb40) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f64eadc5f08) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f64eadc5f70) 0 + primary-for QFile (0x0x7f64eadc5f08) + QIODevice (0x0x7f64eadc51a0) 0 + primary-for QFileDevice (0x0x7f64eadc5f70) + QObject (0x0x7f64eadbfae0) 0 + primary-for QIODevice (0x0x7f64eadc51a0) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f64eadbfd20) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f64eaa81180) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f64eaa81780) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f64eaa819c0) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f64eabd4de0) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f64eabd6c30) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f64eabd6c98) 0 + primary-for QEventTransition (0x0x7f64eabd6c30) + QObject (0x0x7f64eabd4d80) 0 + primary-for QAbstractTransition (0x0x7f64eabd6c98) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f64eabd6d00) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f64eabd4e40) 0 nearly-empty + primary-for QException (0x0x7f64eabd6d00) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f64eabd6d68) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f64eabd6dd0) 0 nearly-empty + primary-for QUnhandledException (0x0x7f64eabd6d68) + std::exception (0x0x7f64eabd4ea0) 0 nearly-empty + primary-for QException (0x0x7f64eabd6dd0) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f64eabd4f00) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f64eac50000) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f64eac50060) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f64eac50180) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f64eabd6e38) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f64eac50120) 0 + primary-for QFileSelector (0x0x7f64eabd6e38) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f64eac50240) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f64eabd6ea0) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f64eac501e0) 0 + primary-for QFileSystemWatcher (0x0x7f64eabd6ea0) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f64eac50300) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f64eabd6f08) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f64eabd6f70) 0 + primary-for QFinalState (0x0x7f64eabd6f08) + QObject (0x0x7f64eac502a0) 0 + primary-for QAbstractState (0x0x7f64eabd6f70) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f64eac50360) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f64eac503c0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f64ea8bd0d0) 0 + QBasicMutex (0x0x7f64eac505a0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f64eac50600) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f64eac50660) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f64eac506c0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f64eac507e0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f64ea979060) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f64ea979840) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f64ea9fc208) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f64ea9797e0) 0 + primary-for QFutureWatcherBase (0x0x7f64ea9fc208) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f64ea979e40) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f64ea9fcaf8) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f64ea9fcb60) 0 + primary-for QHistoryState (0x0x7f64ea9fcaf8) + QObject (0x0x7f64ea979de0) 0 + primary-for QAbstractState (0x0x7f64ea9fcb60) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f64ea979f00) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f64ea9fcbc8) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f64ea9fcc30) 0 + primary-for QIdentityProxyModel (0x0x7f64ea9fcbc8) + QAbstractItemModel (0x0x7f64ea9fcc98) 0 + primary-for QAbstractProxyModel (0x0x7f64ea9fcc30) + QObject (0x0x7f64ea979ea0) 0 + primary-for QAbstractItemModel (0x0x7f64ea9fcc98) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f64ea979f60) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f64ea69a660) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f64ea6c34e0) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f64ea69a600) 0 + primary-for QItemSelectionModel (0x0x7f64ea6c34e0) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f64ea6c36e8) 0 + QList<QItemSelectionRange> (0x0x7f64ea6c3750) 0 + QListSpecialMethods<QItemSelectionRange> (0x0x7f64ea69a960) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f64ea69ae40) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f64ea4d15a0) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f64ea4d1ae0) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f64ea4d1b40) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f64ea4d1d20) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f64ea4d1d80) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f64ea4d1cc0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f64ea63f000) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f64ea63f060) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f64ea63f6c0) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f64ea63f720) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f64ea63f660) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f64ea2f09c0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f64ea2efa90) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f64ea2f0960) 0 + primary-for QLibrary (0x0x7f64ea2efa90) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f64ea37f0c0) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f64ea2f0ba0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f64ea37f5a0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f64ea37f600) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f64ea37f8a0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f64ea37fb40) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f64ea0774e0) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f64ea077e40) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f64ea1161e0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f64ea116360) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f64ea116300) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f64ea1164e0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f64ea116780) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f64ea116de0) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f64ea116e40) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f64e9ee5480) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f64e9ee5780) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f64e9ee57e0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f64e9ee5ae0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f64e9e73d00) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f64e9ee5a80) 0 + primary-for QMimeData (0x0x7f64e9e73d00) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f64e9ee5b40) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f64e9ee5e40) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f64e9ee5f00) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f64e9e73f08) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f64e9ee5ea0) 0 + primary-for QObjectCleanupHandler (0x0x7f64e9e73f08) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f64e9ee5f60) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f64e9f6e720) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f64e9f74618) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f64e9f74680) 0 + primary-for QParallelAnimationGroup (0x0x7f64e9f74618) + QAbstractAnimation (0x0x7f64e9f746e8) 0 + primary-for QAnimationGroup (0x0x7f64e9f74680) + QObject (0x0x7f64e9f6e6c0) 0 + primary-for QAbstractAnimation (0x0x7f64e9f746e8) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f64e9f6e7e0) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f64e9f74750) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f64e9f747b8) 0 + primary-for QPauseAnimation (0x0x7f64e9f74750) + QObject (0x0x7f64e9f6e780) 0 + primary-for QAbstractAnimation (0x0x7f64e9f747b8) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f64e9f6e9c0) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f64e9f6ecc0) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f64e9f749c0) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f64e9f6ec60) 0 + primary-for QPluginLoader (0x0x7f64e9f749c0) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f64e9f6ed20) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f64e9ff2420) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f64e9ffc068) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f64e9ffc0d0) 0 + primary-for QProcess (0x0x7f64e9ffc068) + QObject (0x0x7f64e9ff23c0) 0 + primary-for QIODevice (0x0x7f64e9ffc0d0) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f64e9ff24e0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f64e9ffc138) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f64e9ffc1a0) 0 + primary-for QVariantAnimation (0x0x7f64e9ffc138) + QObject (0x0x7f64e9ff2480) 0 + primary-for QAbstractAnimation (0x0x7f64e9ffc1a0) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f64e9ff25a0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f64e9ffc270) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f64e9ffc2d8) 0 + primary-for QPropertyAnimation (0x0x7f64e9ffc270) + QAbstractAnimation (0x0x7f64e9ffc340) 0 + primary-for QVariantAnimation (0x0x7f64e9ffc2d8) + QObject (0x0x7f64e9ff2540) 0 + primary-for QAbstractAnimation (0x0x7f64e9ffc340) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f64e9ff26c0) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f64e9ff2660) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f64e9cdc618) 0 + QRandomGenerator (0x0x7f64e9cdf660) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f64e9cdf720) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f64e9cdf9c0) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f64e9cdfa80) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f64e9cdfb40) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f64e9cdfde0) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f64e9df80c0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f64e9df8360) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f64e9df8600) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f64e9df8c00) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f64e9df8f00) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f64e9bfc240) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f64e9bfc3c0) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f64e9ae6820) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f64e9ae6888) 0 + primary-for QSaveFile (0x0x7f64e9ae6820) + QIODevice (0x0x7f64e9ae68f0) 0 + primary-for QFileDevice (0x0x7f64e9ae6888) + QObject (0x0x7f64e9bfc360) 0 + primary-for QIODevice (0x0x7f64e9ae68f0) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f64e9bfc480) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f64e9bfc600) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f64e9942c00) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f64e995e1a0) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f64e995e208) 0 + primary-for QSequentialAnimationGroup (0x0x7f64e995e1a0) + QAbstractAnimation (0x0x7f64e995e270) 0 + primary-for QAnimationGroup (0x0x7f64e995e208) + QObject (0x0x7f64e9942ba0) 0 + primary-for QAbstractAnimation (0x0x7f64e995e270) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f64e9942cc0) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f64e995e2d8) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f64e9942c60) 0 + primary-for QSettings (0x0x7f64e995e2d8) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f64e9942d80) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f64e995e340) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f64e9942d20) 0 + primary-for QSharedMemory (0x0x7f64e995e340) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f64e9942e40) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f64e995e3a8) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f64e9942de0) 0 + primary-for QSignalMapper (0x0x7f64e995e3a8) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f64e9942f00) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f64e995e410) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f64e995e478) 0 + primary-for QSignalTransition (0x0x7f64e995e410) + QObject (0x0x7f64e9942ea0) 0 + primary-for QAbstractTransition (0x0x7f64e995e478) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f64e99cf000) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f64e995e4e0) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f64e9942f60) 0 + primary-for QSocketNotifier (0x0x7f64e995e4e0) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f64e99cf0c0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f64e995e548) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f64e995e5b0) 0 + primary-for QSortFilterProxyModel (0x0x7f64e995e548) + QAbstractItemModel (0x0x7f64e995e618) 0 + primary-for QAbstractProxyModel (0x0x7f64e995e5b0) + QObject (0x0x7f64e99cf060) 0 + primary-for QAbstractItemModel (0x0x7f64e995e618) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f64e99cf180) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f64e99cf3c0) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f64e995e7b8) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f64e995e820) 0 + primary-for QState (0x0x7f64e995e7b8) + QObject (0x0x7f64e99cf360) 0 + primary-for QAbstractState (0x0x7f64e995e820) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f64e99cf4e0) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f64e995e9c0) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f64e99cf540) 0 + primary-for QStateMachine::SignalEvent (0x0x7f64e995e9c0) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f64e995ea28) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f64e99cf5a0) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f64e995ea28) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f64e995e888) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f64e995e8f0) 0 + primary-for QStateMachine (0x0x7f64e995e888) + QAbstractState (0x0x7f64e995e958) 0 + primary-for QState (0x0x7f64e995e8f0) + QObject (0x0x7f64e99cf480) 0 + primary-for QAbstractState (0x0x7f64e995e958) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f64e99cf600) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f64e96c5540) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f64e974a900) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f64e974fa28) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f64e974fa90) 0 + primary-for QStringListModel (0x0x7f64e974fa28) + QAbstractItemModel (0x0x7f64e974faf8) 0 + primary-for QAbstractListModel (0x0x7f64e974fa90) + QObject (0x0x7f64e974a8a0) 0 + primary-for QAbstractItemModel (0x0x7f64e974faf8) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f64e974a960) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f64e974aa20) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f64e974ab40) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f64e974fb60) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f64e974fbc8) 0 + primary-for QTemporaryFile (0x0x7f64e974fb60) + QFileDevice (0x0x7f64e974fc30) 0 + primary-for QFile (0x0x7f64e974fbc8) + QIODevice (0x0x7f64e974fc98) 0 + primary-for QFileDevice (0x0x7f64e974fc30) + QObject (0x0x7f64e974aae0) 0 + primary-for QIODevice (0x0x7f64e974fc98) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f64e974aba0) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f64e974ade0) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f64e974ad80) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f64e9836000) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f64e9836060) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f64e98360c0) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f64e9836120) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f64e974fea0) 0 + std::__mutex_base (0x0x7f64e9836180) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f64e974ff08) 0 + std::__recursive_mutex_base (0x0x7f64e98361e0) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f64e9461690) 0 + std::__mutex_base (0x0x7f64e9836300) 0 + std::__timed_mutex_impl<std::timed_mutex> (0x0x7f64e9836360) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f64e947b070) 0 + std::__recursive_mutex_base (0x0x7f64e9836420) 0 + std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7f64e9836480) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f64e98364e0) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f64e9836540) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f64e98365a0) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f64e98367e0) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f64e94c8068) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7f64e98368a0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f64e94c8068) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f64e94c80d0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7f64e9836960) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f64e94c80d0) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f64e94c8138) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7f64e9836a20) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f64e94c8138) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f64e94c8208) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7f64e9836ae0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f64e94c8208) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f64e9836ba0) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f64e9836c00) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f64e9836c60) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f64e9836cc0) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f64e94c84e0) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7f64e958a060) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f64e94c84e0) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f64e958a8a0) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f64e93060c0) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f64e93062a0) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7f64e9306300) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f64e9306240) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f64e9082f00) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f64e90e4000) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f64e90e4060) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f64e916f6c0) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f64e9170820) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7f64e9170888) 0 + primary-for std::future_error (0x0x7f64e9170820) + std::exception (0x0x7f64e916f7e0) 0 nearly-empty + primary-for std::logic_error (0x0x7f64e9170888) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f64e916f900) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f64e916f8a0) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f64e8e28e40) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f64e8e2be38) 0 + std::__at_thread_exit_elt (0x0x7f64e8e28f00) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f64e916fa80) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f64e916f840) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f64e8c25a28) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7f64e8c11de0) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f64e8c25a28) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f64e8880540) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f64e88864e0) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f64e88804e0) 0 + primary-for QThread (0x0x7f64e88864e0) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f64e8880660) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f64e8886548) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f64e8880600) 0 + primary-for QThreadPool (0x0x7f64e8886548) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f64e88806c0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f64e88807e0) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f64e88865b0) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f64e8880780) 0 + primary-for QTimeLine (0x0x7f64e88865b0) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f64e88808a0) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f64e8886618) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f64e8880840) 0 + primary-for QTimer (0x0x7f64e8886618) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f64e8880f60) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f64e8880f00) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f64e895b540) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f64e8978068) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f64e895b4e0) 0 + primary-for QTranslator (0x0x7f64e8978068) + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f64e895b660) 0 + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f64e867dd20) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f64e871f3c0) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f64e871f9c0) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f64e871fa20) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f64e871fcc0) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f64e874faf8) 0 + QVector<QXmlStreamAttribute> (0x0x7f64e87ca0c0) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f64e87ca120) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f64e87ca3c0) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f64e87ca660) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f64e87ca900) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f64e87ca960) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f64e84c43c0) 0 + +Class QRgba64 + size=8 align=8 + base size=8 base align=8 +QRgba64 (0x0x7f64e84c44e0) 0 + +Class QColor + size=16 align=4 + base size=14 base align=4 +QColor (0x0x7f64e84c4780) 0 + +Class QRegion::QRegionData + size=16 align=8 + base size=16 base align=8 +QRegion::QRegionData (0x0x7f64e85cc180) 0 + +Class QRegion + size=8 align=8 + base size=8 base align=8 +QRegion (0x0x7f64e85cc120) 0 + +Class QKeySequence + size=8 align=8 + base size=8 base align=8 +QKeySequence (0x0x7f64e826c4e0) 0 + +Class QVector2D + size=8 align=4 + base size=8 base align=4 +QVector2D (0x0x7f64e831aa20) 0 + +Class QTouchDevice + size=8 align=8 + base size=8 base align=8 +QTouchDevice (0x0x7f64e831acc0) 0 + +Vtable for QInputEvent +QInputEvent::_ZTV11QInputEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QInputEvent) +16 (int (*)(...))QInputEvent::~QInputEvent +24 (int (*)(...))QInputEvent::~QInputEvent + +Class QInputEvent + size=32 align=8 + base size=32 base align=8 +QInputEvent (0x0x7f64e83218f0) 0 + vptr=((& QInputEvent::_ZTV11QInputEvent) + 16u) + QEvent (0x0x7f64e831aea0) 0 + primary-for QInputEvent (0x0x7f64e83218f0) + +Vtable for QEnterEvent +QEnterEvent::_ZTV11QEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QEnterEvent) +16 (int (*)(...))QEnterEvent::~QEnterEvent +24 (int (*)(...))QEnterEvent::~QEnterEvent + +Class QEnterEvent + size=72 align=8 + base size=72 base align=8 +QEnterEvent (0x0x7f64e8321958) 0 + vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16u) + QEvent (0x0x7f64e831af00) 0 + primary-for QEnterEvent (0x0x7f64e8321958) + +Vtable for QMouseEvent +QMouseEvent::_ZTV11QMouseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMouseEvent) +16 (int (*)(...))QMouseEvent::~QMouseEvent +24 (int (*)(...))QMouseEvent::~QMouseEvent + +Class QMouseEvent + size=104 align=8 + base size=100 base align=8 +QMouseEvent (0x0x7f64e83219c0) 0 + vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16u) + QInputEvent (0x0x7f64e8321a28) 0 + primary-for QMouseEvent (0x0x7f64e83219c0) + QEvent (0x0x7f64e831af60) 0 + primary-for QInputEvent (0x0x7f64e8321a28) + +Vtable for QHoverEvent +QHoverEvent::_ZTV11QHoverEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHoverEvent) +16 (int (*)(...))QHoverEvent::~QHoverEvent +24 (int (*)(...))QHoverEvent::~QHoverEvent + +Class QHoverEvent + size=64 align=8 + base size=64 base align=8 +QHoverEvent (0x0x7f64e8321a90) 0 + vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16u) + QInputEvent (0x0x7f64e8321af8) 0 + primary-for QHoverEvent (0x0x7f64e8321a90) + QEvent (0x0x7f64e83eb000) 0 + primary-for QInputEvent (0x0x7f64e8321af8) + +Vtable for QWheelEvent +QWheelEvent::_ZTV11QWheelEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWheelEvent) +16 (int (*)(...))QWheelEvent::~QWheelEvent +24 (int (*)(...))QWheelEvent::~QWheelEvent + +Class QWheelEvent + size=96 align=8 + base size=96 base align=8 +QWheelEvent (0x0x7f64e8321b60) 0 + vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16u) + QInputEvent (0x0x7f64e8321bc8) 0 + primary-for QWheelEvent (0x0x7f64e8321b60) + QEvent (0x0x7f64e83eb060) 0 + primary-for QInputEvent (0x0x7f64e8321bc8) + +Vtable for QTabletEvent +QTabletEvent::_ZTV12QTabletEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTabletEvent) +16 (int (*)(...))QTabletEvent::~QTabletEvent +24 (int (*)(...))QTabletEvent::~QTabletEvent + +Class QTabletEvent + size=128 align=8 + base size=128 base align=8 +QTabletEvent (0x0x7f64e8321c30) 0 + vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16u) + QInputEvent (0x0x7f64e8321c98) 0 + primary-for QTabletEvent (0x0x7f64e8321c30) + QEvent (0x0x7f64e83eb0c0) 0 + primary-for QInputEvent (0x0x7f64e8321c98) + +Vtable for QNativeGestureEvent +QNativeGestureEvent::_ZTV19QNativeGestureEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNativeGestureEvent) +16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent + +Class QNativeGestureEvent + size=112 align=8 + base size=112 base align=8 +QNativeGestureEvent (0x0x7f64e8321d00) 0 + vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16u) + QInputEvent (0x0x7f64e8321d68) 0 + primary-for QNativeGestureEvent (0x0x7f64e8321d00) + QEvent (0x0x7f64e83eb120) 0 + primary-for QInputEvent (0x0x7f64e8321d68) + +Vtable for QKeyEvent +QKeyEvent::_ZTV9QKeyEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QKeyEvent) +16 (int (*)(...))QKeyEvent::~QKeyEvent +24 (int (*)(...))QKeyEvent::~QKeyEvent + +Class QKeyEvent + size=64 align=8 + base size=59 base align=8 +QKeyEvent (0x0x7f64e8321dd0) 0 + vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16u) + QInputEvent (0x0x7f64e8321e38) 0 + primary-for QKeyEvent (0x0x7f64e8321dd0) + QEvent (0x0x7f64e83eb180) 0 + primary-for QInputEvent (0x0x7f64e8321e38) + +Vtable for QFocusEvent +QFocusEvent::_ZTV11QFocusEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusEvent) +16 (int (*)(...))QFocusEvent::~QFocusEvent +24 (int (*)(...))QFocusEvent::~QFocusEvent + +Class QFocusEvent + size=24 align=8 + base size=24 base align=8 +QFocusEvent (0x0x7f64e8321ea0) 0 + vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16u) + QEvent (0x0x7f64e83eb1e0) 0 + primary-for QFocusEvent (0x0x7f64e8321ea0) + +Vtable for QPaintEvent +QPaintEvent::_ZTV11QPaintEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPaintEvent) +16 (int (*)(...))QPaintEvent::~QPaintEvent +24 (int (*)(...))QPaintEvent::~QPaintEvent + +Class QPaintEvent + size=56 align=8 + base size=49 base align=8 +QPaintEvent (0x0x7f64e8321f08) 0 + vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16u) + QEvent (0x0x7f64e83eb240) 0 + primary-for QPaintEvent (0x0x7f64e8321f08) + +Vtable for QMoveEvent +QMoveEvent::_ZTV10QMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QMoveEvent) +16 (int (*)(...))QMoveEvent::~QMoveEvent +24 (int (*)(...))QMoveEvent::~QMoveEvent + +Class QMoveEvent + size=40 align=8 + base size=36 base align=8 +QMoveEvent (0x0x7f64e8321f70) 0 + vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16u) + QEvent (0x0x7f64e83eb2a0) 0 + primary-for QMoveEvent (0x0x7f64e8321f70) + +Vtable for QExposeEvent +QExposeEvent::_ZTV12QExposeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QExposeEvent) +16 (int (*)(...))QExposeEvent::~QExposeEvent +24 (int (*)(...))QExposeEvent::~QExposeEvent + +Class QExposeEvent + size=32 align=8 + base size=32 base align=8 +QExposeEvent (0x0x7f64e8064000) 0 + vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16u) + QEvent (0x0x7f64e83eb300) 0 + primary-for QExposeEvent (0x0x7f64e8064000) + +Vtable for QPlatformSurfaceEvent +QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent) +16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent + +Class QPlatformSurfaceEvent + size=24 align=8 + base size=24 base align=8 +QPlatformSurfaceEvent (0x0x7f64e8064068) 0 + vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16u) + QEvent (0x0x7f64e83eb360) 0 + primary-for QPlatformSurfaceEvent (0x0x7f64e8064068) + +Vtable for QResizeEvent +QResizeEvent::_ZTV12QResizeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QResizeEvent) +16 (int (*)(...))QResizeEvent::~QResizeEvent +24 (int (*)(...))QResizeEvent::~QResizeEvent + +Class QResizeEvent + size=40 align=8 + base size=36 base align=8 +QResizeEvent (0x0x7f64e80640d0) 0 + vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16u) + QEvent (0x0x7f64e83eb3c0) 0 + primary-for QResizeEvent (0x0x7f64e80640d0) + +Vtable for QCloseEvent +QCloseEvent::_ZTV11QCloseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QCloseEvent) +16 (int (*)(...))QCloseEvent::~QCloseEvent +24 (int (*)(...))QCloseEvent::~QCloseEvent + +Class QCloseEvent + size=24 align=8 + base size=20 base align=8 +QCloseEvent (0x0x7f64e8064138) 0 + vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16u) + QEvent (0x0x7f64e83eb420) 0 + primary-for QCloseEvent (0x0x7f64e8064138) + +Vtable for QIconDragEvent +QIconDragEvent::_ZTV14QIconDragEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QIconDragEvent) +16 (int (*)(...))QIconDragEvent::~QIconDragEvent +24 (int (*)(...))QIconDragEvent::~QIconDragEvent + +Class QIconDragEvent + size=24 align=8 + base size=20 base align=8 +QIconDragEvent (0x0x7f64e80641a0) 0 + vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16u) + QEvent (0x0x7f64e83eb480) 0 + primary-for QIconDragEvent (0x0x7f64e80641a0) + +Vtable for QShowEvent +QShowEvent::_ZTV10QShowEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QShowEvent) +16 (int (*)(...))QShowEvent::~QShowEvent +24 (int (*)(...))QShowEvent::~QShowEvent + +Class QShowEvent + size=24 align=8 + base size=20 base align=8 +QShowEvent (0x0x7f64e8064208) 0 + vptr=((& QShowEvent::_ZTV10QShowEvent) + 16u) + QEvent (0x0x7f64e83eb4e0) 0 + primary-for QShowEvent (0x0x7f64e8064208) + +Vtable for QHideEvent +QHideEvent::_ZTV10QHideEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHideEvent) +16 (int (*)(...))QHideEvent::~QHideEvent +24 (int (*)(...))QHideEvent::~QHideEvent + +Class QHideEvent + size=24 align=8 + base size=20 base align=8 +QHideEvent (0x0x7f64e8064270) 0 + vptr=((& QHideEvent::_ZTV10QHideEvent) + 16u) + QEvent (0x0x7f64e83eb540) 0 + primary-for QHideEvent (0x0x7f64e8064270) + +Vtable for QContextMenuEvent +QContextMenuEvent::_ZTV17QContextMenuEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QContextMenuEvent) +16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent + +Class QContextMenuEvent + size=56 align=8 + base size=49 base align=8 +QContextMenuEvent (0x0x7f64e80642d8) 0 + vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16u) + QInputEvent (0x0x7f64e8064340) 0 + primary-for QContextMenuEvent (0x0x7f64e80642d8) + QEvent (0x0x7f64e83eb5a0) 0 + primary-for QInputEvent (0x0x7f64e8064340) + +Class QInputMethodEvent::Attribute + size=32 align=8 + base size=32 base align=8 +QInputMethodEvent::Attribute (0x0x7f64e83eb660) 0 + +Vtable for QInputMethodEvent +QInputMethodEvent::_ZTV17QInputMethodEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QInputMethodEvent) +16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent + +Class QInputMethodEvent + size=56 align=8 + base size=56 base align=8 +QInputMethodEvent (0x0x7f64e80643a8) 0 + vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16u) + QEvent (0x0x7f64e83eb600) 0 + primary-for QInputMethodEvent (0x0x7f64e80643a8) + +Class QInputMethodQueryEvent::QueryPair + size=24 align=8 + base size=24 base align=8 +QInputMethodQueryEvent::QueryPair (0x0x7f64e83ebae0) 0 + +Vtable for QInputMethodQueryEvent +QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent) +16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent + +Class QInputMethodQueryEvent + size=32 align=8 + base size=32 base align=8 +QInputMethodQueryEvent (0x0x7f64e80646e8) 0 + vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16u) + QEvent (0x0x7f64e83eba80) 0 + primary-for QInputMethodQueryEvent (0x0x7f64e80646e8) + +Vtable for QDropEvent +QDropEvent::_ZTV10QDropEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDropEvent) +16 (int (*)(...))QDropEvent::~QDropEvent +24 (int (*)(...))QDropEvent::~QDropEvent + +Class QDropEvent + size=72 align=8 + base size=72 base align=8 +QDropEvent (0x0x7f64e80649c0) 0 + vptr=((& QDropEvent::_ZTV10QDropEvent) + 16u) + QEvent (0x0x7f64e83ebe40) 0 + primary-for QDropEvent (0x0x7f64e80649c0) + +Vtable for QDragMoveEvent +QDragMoveEvent::_ZTV14QDragMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDragMoveEvent) +16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent + +Class QDragMoveEvent + size=88 align=8 + base size=88 base align=8 +QDragMoveEvent (0x0x7f64e8064a28) 0 + vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16u) + QDropEvent (0x0x7f64e8064a90) 0 + primary-for QDragMoveEvent (0x0x7f64e8064a28) + QEvent (0x0x7f64e83ebea0) 0 + primary-for QDropEvent (0x0x7f64e8064a90) + +Vtable for QDragEnterEvent +QDragEnterEvent::_ZTV15QDragEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragEnterEvent) +16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent + +Class QDragEnterEvent + size=88 align=8 + base size=88 base align=8 +QDragEnterEvent (0x0x7f64e8064af8) 0 + vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16u) + QDragMoveEvent (0x0x7f64e8064b60) 0 + primary-for QDragEnterEvent (0x0x7f64e8064af8) + QDropEvent (0x0x7f64e8064bc8) 0 + primary-for QDragMoveEvent (0x0x7f64e8064b60) + QEvent (0x0x7f64e83ebf00) 0 + primary-for QDropEvent (0x0x7f64e8064bc8) + +Vtable for QDragLeaveEvent +QDragLeaveEvent::_ZTV15QDragLeaveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragLeaveEvent) +16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent + +Class QDragLeaveEvent + size=24 align=8 + base size=20 base align=8 +QDragLeaveEvent (0x0x7f64e8064c30) 0 + vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16u) + QEvent (0x0x7f64e83ebf60) 0 + primary-for QDragLeaveEvent (0x0x7f64e8064c30) + +Vtable for QHelpEvent +QHelpEvent::_ZTV10QHelpEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHelpEvent) +16 (int (*)(...))QHelpEvent::~QHelpEvent +24 (int (*)(...))QHelpEvent::~QHelpEvent + +Class QHelpEvent + size=40 align=8 + base size=36 base align=8 +QHelpEvent (0x0x7f64e8064c98) 0 + vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16u) + QEvent (0x0x7f64e8132000) 0 + primary-for QHelpEvent (0x0x7f64e8064c98) + +Vtable for QStatusTipEvent +QStatusTipEvent::_ZTV15QStatusTipEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QStatusTipEvent) +16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent + +Class QStatusTipEvent + size=32 align=8 + base size=32 base align=8 +QStatusTipEvent (0x0x7f64e8064d00) 0 + vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16u) + QEvent (0x0x7f64e8132060) 0 + primary-for QStatusTipEvent (0x0x7f64e8064d00) + +Vtable for QWhatsThisClickedEvent +QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent) +16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent + +Class QWhatsThisClickedEvent + size=32 align=8 + base size=32 base align=8 +QWhatsThisClickedEvent (0x0x7f64e8064d68) 0 + vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16u) + QEvent (0x0x7f64e81320c0) 0 + primary-for QWhatsThisClickedEvent (0x0x7f64e8064d68) + +Vtable for QActionEvent +QActionEvent::_ZTV12QActionEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionEvent) +16 (int (*)(...))QActionEvent::~QActionEvent +24 (int (*)(...))QActionEvent::~QActionEvent + +Class QActionEvent + size=40 align=8 + base size=40 base align=8 +QActionEvent (0x0x7f64e8064dd0) 0 + vptr=((& QActionEvent::_ZTV12QActionEvent) + 16u) + QEvent (0x0x7f64e8132120) 0 + primary-for QActionEvent (0x0x7f64e8064dd0) + +Vtable for QFileOpenEvent +QFileOpenEvent::_ZTV14QFileOpenEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QFileOpenEvent) +16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent + +Class QFileOpenEvent + size=40 align=8 + base size=40 base align=8 +QFileOpenEvent (0x0x7f64e8064e38) 0 + vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16u) + QEvent (0x0x7f64e8132180) 0 + primary-for QFileOpenEvent (0x0x7f64e8064e38) + +Vtable for QToolBarChangeEvent +QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QToolBarChangeEvent) +16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent + +Class QToolBarChangeEvent + size=24 align=8 + base size=21 base align=8 +QToolBarChangeEvent (0x0x7f64e8064ea0) 0 + vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16u) + QEvent (0x0x7f64e81321e0) 0 + primary-for QToolBarChangeEvent (0x0x7f64e8064ea0) + +Vtable for QShortcutEvent +QShortcutEvent::_ZTV14QShortcutEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QShortcutEvent) +16 (int (*)(...))QShortcutEvent::~QShortcutEvent +24 (int (*)(...))QShortcutEvent::~QShortcutEvent + +Class QShortcutEvent + size=40 align=8 + base size=40 base align=8 +QShortcutEvent (0x0x7f64e8064f08) 0 + vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16u) + QEvent (0x0x7f64e8132240) 0 + primary-for QShortcutEvent (0x0x7f64e8064f08) + +Vtable for QWindowStateChangeEvent +QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent) +16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent + +Class QWindowStateChangeEvent + size=32 align=8 + base size=25 base align=8 +QWindowStateChangeEvent (0x0x7f64e8064f70) 0 + vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16u) + QEvent (0x0x7f64e81322a0) 0 + primary-for QWindowStateChangeEvent (0x0x7f64e8064f70) + +Class QPointingDeviceUniqueId + size=8 align=8 + base size=8 base align=8 +QPointingDeviceUniqueId (0x0x7f64e8132300) 0 + +Class QTouchEvent::TouchPoint + size=8 align=8 + base size=8 base align=8 +QTouchEvent::TouchPoint (0x0x7f64e81329c0) 0 + +Vtable for QTouchEvent +QTouchEvent::_ZTV11QTouchEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTouchEvent) +16 (int (*)(...))QTouchEvent::~QTouchEvent +24 (int (*)(...))QTouchEvent::~QTouchEvent + +Class QTouchEvent + size=72 align=8 + base size=72 base align=8 +QTouchEvent (0x0x7f64e8167618) 0 + vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16u) + QInputEvent (0x0x7f64e8167680) 0 + primary-for QTouchEvent (0x0x7f64e8167618) + QEvent (0x0x7f64e8132960) 0 + primary-for QInputEvent (0x0x7f64e8167680) + +Vtable for QScrollPrepareEvent +QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollPrepareEvent) +16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent + +Class QScrollPrepareEvent + size=112 align=8 + base size=112 base align=8 +QScrollPrepareEvent (0x0x7f64e7d2bea0) 0 + vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16u) + QEvent (0x0x7f64e7d59060) 0 + primary-for QScrollPrepareEvent (0x0x7f64e7d2bea0) + +Vtable for QScrollEvent +QScrollEvent::_ZTV12QScrollEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QScrollEvent) +16 (int (*)(...))QScrollEvent::~QScrollEvent +24 (int (*)(...))QScrollEvent::~QScrollEvent + +Class QScrollEvent + size=64 align=8 + base size=60 base align=8 +QScrollEvent (0x0x7f64e7d2bf08) 0 + vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16u) + QEvent (0x0x7f64e7d590c0) 0 + primary-for QScrollEvent (0x0x7f64e7d2bf08) + +Vtable for QScreenOrientationChangeEvent +QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent) +16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent + +Class QScreenOrientationChangeEvent + size=40 align=8 + base size=36 base align=8 +QScreenOrientationChangeEvent (0x0x7f64e7d2bf70) 0 + vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16u) + QEvent (0x0x7f64e7d59120) 0 + primary-for QScreenOrientationChangeEvent (0x0x7f64e7d2bf70) + +Vtable for QApplicationStateChangeEvent +QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent) +16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent + +Class QApplicationStateChangeEvent + size=24 align=8 + base size=24 base align=8 +QApplicationStateChangeEvent (0x0x7f64e7d89000) 0 + vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16u) + QEvent (0x0x7f64e7d59180) 0 + primary-for QApplicationStateChangeEvent (0x0x7f64e7d89000) + +Class QFont + size=16 align=8 + base size=12 base align=8 +QFont (0x0x7f64e7d591e0) 0 + +Class QPolygon + size=8 align=8 + base size=8 base align=8 +QPolygon (0x0x7f64e7d89d68) 0 + QVector<QPoint> (0x0x7f64e7d59ea0) 0 + +Class QPolygonF + size=8 align=8 + base size=8 base align=8 +QPolygonF (0x0x7f64e7e5d138) 0 + QVector<QPointF> (0x0x7f64e7e50360) 0 + +Class QMatrix + size=48 align=8 + base size=48 base align=8 +QMatrix (0x0x7f64e7e50720) 0 + +Class QPainterPath::Element + size=24 align=8 + base size=24 base align=8 +QPainterPath::Element (0x0x7f64e7e50a20) 0 + +Class QPainterPath + size=8 align=8 + base size=8 base align=8 +QPainterPath (0x0x7f64e7e509c0) 0 + +Class QPainterPathStroker + size=8 align=8 + base size=8 base align=8 +QPainterPathStroker (0x0x7f64e7b60420) 0 + +Class QTransform + size=88 align=8 + base size=88 base align=8 +QTransform (0x0x7f64e7b60540) 0 + +Vtable for QPaintDevice +QPaintDevice::_ZTV12QPaintDevice: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDevice + size=24 align=8 + base size=24 base align=8 +QPaintDevice (0x0x7f64e7b60c60) 0 + vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u) + +Class QPixelFormat + size=8 align=8 + base size=8 base align=8 +QPixelFormat (0x0x7f64e7b60cc0) 0 + +Vtable for QImage +QImage::_ZTV6QImage: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QImage) +16 (int (*)(...))QImage::~QImage +24 (int (*)(...))QImage::~QImage +32 (int (*)(...))QImage::devType +40 (int (*)(...))QImage::paintEngine +48 (int (*)(...))QImage::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QImage + size=32 align=8 + base size=32 base align=8 +QImage (0x0x7f64e7cb6000) 0 + vptr=((& QImage::_ZTV6QImage) + 16u) + QPaintDevice (0x0x7f64e7c87780) 0 + primary-for QImage (0x0x7f64e7cb6000) + +Vtable for QPixmap +QPixmap::_ZTV7QPixmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QPixmap) +16 (int (*)(...))QPixmap::~QPixmap +24 (int (*)(...))QPixmap::~QPixmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPixmap + size=32 align=8 + base size=32 base align=8 +QPixmap (0x0x7f64e795fb60) 0 + vptr=((& QPixmap::_ZTV7QPixmap) + 16u) + QPaintDevice (0x0x7f64e7960720) 0 + primary-for QPixmap (0x0x7f64e795fb60) + +Class QBrush + size=8 align=8 + base size=8 base align=8 +QBrush (0x0x7f64e7960a20) 0 + +Class QBrushData + size=112 align=8 + base size=112 base align=8 +QBrushData (0x0x7f64e79f91e0) 0 + +Class QGradient + size=64 align=8 + base size=64 base align=8 +QGradient (0x0x7f64e79f9240) 0 + +Class QLinearGradient + size=64 align=8 + base size=64 base align=8 +QLinearGradient (0x0x7f64e79f44e0) 0 + QGradient (0x0x7f64e79f94e0) 0 + +Class QRadialGradient + size=64 align=8 + base size=64 base align=8 +QRadialGradient (0x0x7f64e79f4548) 0 + QGradient (0x0x7f64e79f9540) 0 + +Class QConicalGradient + size=64 align=8 + base size=64 base align=8 +QConicalGradient (0x0x7f64e79f45b0) 0 + QGradient (0x0x7f64e79f95a0) 0 + +Class QPen + size=8 align=8 + base size=8 base align=8 +QPen (0x0x7f64e79f9600) 0 + +Class QTextOption::Tab + size=16 align=8 + base size=14 base align=8 +QTextOption::Tab (0x0x7f64e7ae0840) 0 + +Class QTextOption + size=32 align=8 + base size=32 base align=8 +QTextOption (0x0x7f64e7ae07e0) 0 + +Class QTextLength + size=16 align=8 + base size=16 base align=8 +QTextLength (0x0x7f64e7763000) 0 + +Class QTextFormat + size=16 align=8 + base size=12 base align=8 +QTextFormat (0x0x7f64e7763720) 0 + +Class QTextCharFormat + size=16 align=8 + base size=12 base align=8 +QTextCharFormat (0x0x7f64e77eb548) 0 + QTextFormat (0x0x7f64e77ea5a0) 0 + +Class QTextBlockFormat + size=16 align=8 + base size=12 base align=8 +QTextBlockFormat (0x0x7f64e77eb750) 0 + QTextFormat (0x0x7f64e77ea840) 0 + +Class QTextListFormat + size=16 align=8 + base size=12 base align=8 +QTextListFormat (0x0x7f64e77eb9c0) 0 + QTextFormat (0x0x7f64e77eaae0) 0 + +Class QTextImageFormat + size=16 align=8 + base size=12 base align=8 +QTextImageFormat (0x0x7f64e77ebbc8) 0 + QTextCharFormat (0x0x7f64e77ebc30) 0 + QTextFormat (0x0x7f64e77ead80) 0 + +Class QTextFrameFormat + size=16 align=8 + base size=12 base align=8 +QTextFrameFormat (0x0x7f64e77ebe38) 0 + QTextFormat (0x0x7f64e790b060) 0 + +Class QTextTableFormat + size=16 align=8 + base size=12 base align=8 +QTextTableFormat (0x0x7f64e7540000) 0 + QTextFrameFormat (0x0x7f64e7540068) 0 + QTextFormat (0x0x7f64e790b300) 0 + +Class QTextTableCellFormat + size=16 align=8 + base size=12 base align=8 +QTextTableCellFormat (0x0x7f64e7540270) 0 + QTextCharFormat (0x0x7f64e75402d8) 0 + QTextFormat (0x0x7f64e790b600) 0 + +Class QFontDatabase + size=8 align=8 + base size=8 base align=8 +QFontDatabase (0x0x7f64e790b8a0) 0 + +Class QRawFont + size=8 align=8 + base size=8 base align=8 +QRawFont (0x0x7f64e790b900) 0 + +Class QGlyphRun + size=8 align=8 + base size=8 base align=8 +QGlyphRun (0x0x7f64e790bde0) 0 + +Class QTextCursor + size=8 align=8 + base size=8 base align=8 +QTextCursor (0x0x7f64e7607120) 0 + +Class QTextInlineObject + size=16 align=8 + base size=16 base align=8 +QTextInlineObject (0x0x7f64e7607420) 0 + +Class QTextLayout::FormatRange + size=24 align=8 + base size=24 base align=8 +QTextLayout::FormatRange (0x0x7f64e76074e0) 0 + +Class QTextLayout + size=8 align=8 + base size=8 base align=8 +QTextLayout (0x0x7f64e7607480) 0 + +Class QTextLine + size=16 align=8 + base size=16 base align=8 +QTextLine (0x0x7f64e7607f00) 0 + +Vtable for QAbstractUndoItem +QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractUndoItem) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAbstractUndoItem + size=8 align=8 + base size=8 base align=8 +QAbstractUndoItem (0x0x7f64e7607f60) 0 nearly-empty + vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16u) + +Class QTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextDocument::QPrivateSignal (0x0x7f64e76cc060) 0 empty + +Vtable for QTextDocument +QTextDocument::_ZTV13QTextDocument: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QTextDocument) +16 (int (*)(...))QTextDocument::metaObject +24 (int (*)(...))QTextDocument::qt_metacast +32 (int (*)(...))QTextDocument::qt_metacall +40 (int (*)(...))QTextDocument::~QTextDocument +48 (int (*)(...))QTextDocument::~QTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextDocument::clear +120 (int (*)(...))QTextDocument::createObject +128 (int (*)(...))QTextDocument::loadResource + +Class QTextDocument + size=16 align=8 + base size=16 base align=8 +QTextDocument (0x0x7f64e76a4618) 0 + vptr=((& QTextDocument::_ZTV13QTextDocument) + 16u) + QObject (0x0x7f64e76cc000) 0 + primary-for QTextDocument (0x0x7f64e76a4618) + +Class QPalette::Data + size=4 align=4 + base size=4 base align=4 +QPalette::Data (0x0x7f64e76cc2a0) 0 + +Class QPalette + size=16 align=8 + base size=12 base align=8 +QPalette (0x0x7f64e76cc240) 0 + +Class QAbstractTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTextDocumentLayout::QPrivateSignal (0x0x7f64e73d2360) 0 empty + +Class QAbstractTextDocumentLayout::Selection + size=24 align=8 + base size=24 base align=8 +QAbstractTextDocumentLayout::Selection (0x0x7f64e73d23c0) 0 + +Class QAbstractTextDocumentLayout::PaintContext + size=64 align=8 + base size=64 base align=8 +QAbstractTextDocumentLayout::PaintContext (0x0x7f64e73d2420) 0 + +Vtable for QAbstractTextDocumentLayout +QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout) +16 (int (*)(...))QAbstractTextDocumentLayout::metaObject +24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast +32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QAbstractTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QAbstractTextDocumentLayout (0x0x7f64e73d3340) 0 + vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16u) + QObject (0x0x7f64e73d2300) 0 + primary-for QAbstractTextDocumentLayout (0x0x7f64e73d3340) + +Vtable for QTextObjectInterface +QTextObjectInterface::_ZTV20QTextObjectInterface: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextObjectInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QTextObjectInterface + size=8 align=8 + base size=8 base align=8 +QTextObjectInterface (0x0x7f64e73d29c0) 0 nearly-empty + vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16u) + +Class QAccessible::State + size=8 align=8 + base size=5 base align=8 +QAccessible::State (0x0x7f64e73d2ae0) 0 + +Vtable for QAccessible::ActivationObserver +QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAccessible::ActivationObserver + size=8 align=8 + base size=8 base align=8 +QAccessible::ActivationObserver (0x0x7f64e73d2b40) 0 nearly-empty + vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16u) + +Class QAccessible + size=1 align=1 + base size=0 base align=1 +QAccessible (0x0x7f64e73d2a80) 0 empty + +Vtable for QAccessibleInterface +QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAccessibleInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleInterface (0x0x7f64e73d2d20) 0 nearly-empty + vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16u) + +Vtable for QAccessibleTextInterface +QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAccessibleTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset +104 (int (*)(...))QAccessibleTextInterface::textAfterOffset +112 (int (*)(...))QAccessibleTextInterface::textAtOffset +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTextInterface (0x0x7f64e73d2d80) 0 nearly-empty + vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16u) + +Vtable for QAccessibleEditableTextInterface +QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleEditableTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleEditableTextInterface (0x0x7f64e73d2de0) 0 nearly-empty + vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16u) + +Vtable for QAccessibleValueInterface +QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleValueInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleValueInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleValueInterface (0x0x7f64e73d2e40) 0 nearly-empty + vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16u) + +Vtable for QAccessibleTableCellInterface +QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableCellInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableCellInterface (0x0x7f64e73d2ea0) 0 nearly-empty + vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16u) + +Vtable for QAccessibleTableInterface +QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleTableInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableInterface (0x0x7f64e73d2f00) 0 nearly-empty + vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16u) + +Vtable for QAccessibleActionInterface +QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleActionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QAccessibleActionInterface::localizedActionName +48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleActionInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleActionInterface (0x0x7f64e73d2f60) 0 nearly-empty + vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16u) + +Vtable for QAccessibleImageInterface +QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleImageInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleImageInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleImageInterface (0x0x7f64e74df000) 0 nearly-empty + vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16u) + +Vtable for QAccessibleEvent +QAccessibleEvent::_ZTV16QAccessibleEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAccessibleEvent) +16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleEvent + size=32 align=8 + base size=28 base align=8 +QAccessibleEvent (0x0x7f64e74df060) 0 + vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16u) + +Vtable for QAccessibleStateChangeEvent +QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent) +16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleStateChangeEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleStateChangeEvent (0x0x7f64e73d3d68) 0 + vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16u) + QAccessibleEvent (0x0x7f64e74df5a0) 0 + primary-for QAccessibleStateChangeEvent (0x0x7f64e73d3d68) + +Vtable for QAccessibleTextCursorEvent +QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent) +16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextCursorEvent + size=32 align=8 + base size=32 base align=8 +QAccessibleTextCursorEvent (0x0x7f64e73d3dd0) 0 + vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16u) + QAccessibleEvent (0x0x7f64e74df600) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f64e73d3dd0) + +Vtable for QAccessibleTextSelectionEvent +QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent) +16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextSelectionEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleTextSelectionEvent (0x0x7f64e73d3e38) 0 + vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f64e73d3ea0) 0 + primary-for QAccessibleTextSelectionEvent (0x0x7f64e73d3e38) + QAccessibleEvent (0x0x7f64e74df660) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f64e73d3ea0) + +Vtable for QAccessibleTextInsertEvent +QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent) +16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextInsertEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextInsertEvent (0x0x7f64e73d3f08) 0 + vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f64e73d3f70) 0 + primary-for QAccessibleTextInsertEvent (0x0x7f64e73d3f08) + QAccessibleEvent (0x0x7f64e74df6c0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f64e73d3f70) + +Vtable for QAccessibleTextRemoveEvent +QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent) +16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextRemoveEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextRemoveEvent (0x0x7f64e7170000) 0 + vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f64e7170068) 0 + primary-for QAccessibleTextRemoveEvent (0x0x7f64e7170000) + QAccessibleEvent (0x0x7f64e74df720) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f64e7170068) + +Vtable for QAccessibleTextUpdateEvent +QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent) +16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextUpdateEvent + size=56 align=8 + base size=56 base align=8 +QAccessibleTextUpdateEvent (0x0x7f64e71700d0) 0 + vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f64e7170138) 0 + primary-for QAccessibleTextUpdateEvent (0x0x7f64e71700d0) + QAccessibleEvent (0x0x7f64e74df780) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f64e7170138) + +Vtable for QAccessibleValueChangeEvent +QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent) +16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleValueChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleValueChangeEvent (0x0x7f64e71701a0) 0 + vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16u) + QAccessibleEvent (0x0x7f64e74df7e0) 0 + primary-for QAccessibleValueChangeEvent (0x0x7f64e71701a0) + +Vtable for QAccessibleTableModelChangeEvent +QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent) +16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTableModelChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTableModelChangeEvent (0x0x7f64e7170208) 0 + vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16u) + QAccessibleEvent (0x0x7f64e74df840) 0 + primary-for QAccessibleTableModelChangeEvent (0x0x7f64e7170208) + +Vtable for QAccessibleBridge +QAccessibleBridge::_ZTV17QAccessibleBridge: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleBridge) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridge + size=8 align=8 + base size=8 base align=8 +QAccessibleBridge (0x0x7f64e74df900) 0 nearly-empty + vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16u) + +Class QAccessibleBridgePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessibleBridgePlugin::QPrivateSignal (0x0x7f64e74df9c0) 0 empty + +Vtable for QAccessibleBridgePlugin +QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin) +16 (int (*)(...))QAccessibleBridgePlugin::metaObject +24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast +32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridgePlugin + size=16 align=8 + base size=16 base align=8 +QAccessibleBridgePlugin (0x0x7f64e7170270) 0 + vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16u) + QObject (0x0x7f64e74df960) 0 + primary-for QAccessibleBridgePlugin (0x0x7f64e7170270) + +Vtable for QAccessibleObject +QAccessibleObject::_ZTV17QAccessibleObject: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleObject) +16 0u +24 0u +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleObject + size=16 align=8 + base size=16 base align=8 +QAccessibleObject (0x0x7f64e71702d8) 0 + vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16u) + QAccessibleInterface (0x0x7f64e74dfa20) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f64e71702d8) + +Vtable for QAccessibleApplication +QAccessibleApplication::_ZTV22QAccessibleApplication: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QAccessibleApplication) +16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleApplication::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleApplication::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleApplication::parent +88 (int (*)(...))QAccessibleApplication::child +96 (int (*)(...))QAccessibleApplication::childCount +104 (int (*)(...))QAccessibleApplication::indexOfChild +112 (int (*)(...))QAccessibleApplication::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))QAccessibleApplication::role +144 (int (*)(...))QAccessibleApplication::state +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleApplication + size=16 align=8 + base size=16 base align=8 +QAccessibleApplication (0x0x7f64e7170340) 0 + vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16u) + QAccessibleObject (0x0x7f64e71703a8) 0 + primary-for QAccessibleApplication (0x0x7f64e7170340) + QAccessibleInterface (0x0x7f64e74dfa80) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f64e71703a8) + +Class QAccessiblePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessiblePlugin::QPrivateSignal (0x0x7f64e74dfb40) 0 empty + +Vtable for QAccessiblePlugin +QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessiblePlugin) +16 (int (*)(...))QAccessiblePlugin::metaObject +24 (int (*)(...))QAccessiblePlugin::qt_metacast +32 (int (*)(...))QAccessiblePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessiblePlugin + size=16 align=8 + base size=16 base align=8 +QAccessiblePlugin (0x0x7f64e7170410) 0 + vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16u) + QObject (0x0x7f64e74dfae0) 0 + primary-for QAccessiblePlugin (0x0x7f64e7170410) + +Class QSurfaceFormat + size=8 align=8 + base size=8 base align=8 +QSurfaceFormat (0x0x7f64e74dfba0) 0 + +Vtable for QSurface +QSurface::_ZTV8QSurface: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSurface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QSurface + size=24 align=8 + base size=24 base align=8 +QSurface (0x0x7f64e74dfd80) 0 + vptr=((& QSurface::_ZTV8QSurface) + 16u) + +Class QIcon + size=8 align=8 + base size=8 base align=8 +QIcon (0x0x7f64e74dff00) 0 + +Class QCursor + size=8 align=8 + base size=8 base align=8 +QCursor (0x0x7f64e72d4300) 0 + +Class QWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWindow::QPrivateSignal (0x0x7f64e6f5e900) 0 empty + +Vtable for QWindow +QWindow::_ZTV7QWindow: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWindow) +16 (int (*)(...))QWindow::metaObject +24 (int (*)(...))QWindow::qt_metacast +32 (int (*)(...))QWindow::qt_metacall +40 (int (*)(...))QWindow::~QWindow +48 (int (*)(...))QWindow::~QWindow +56 (int (*)(...))QWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI7QWindow) +312 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev +320 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QWindow + size=40 align=8 + base size=40 base align=8 +QWindow (0x0x7f64e6f73230) 0 + vptr=((& QWindow::_ZTV7QWindow) + 16u) + QObject (0x0x7f64e6f5e840) 0 + primary-for QWindow (0x0x7f64e6f73230) + QSurface (0x0x7f64e6f5e8a0) 16 + vptr=((& QWindow::_ZTV7QWindow) + 312u) + +Class QBackingStore + size=8 align=8 + base size=8 base align=8 +QBackingStore (0x0x7f64e6f5ea20) 0 + +Vtable for QBitmap +QBitmap::_ZTV7QBitmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBitmap) +16 (int (*)(...))QBitmap::~QBitmap +24 (int (*)(...))QBitmap::~QBitmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QBitmap + size=32 align=8 + base size=32 base align=8 +QBitmap (0x0x7f64e6f70478) 0 + vptr=((& QBitmap::_ZTV7QBitmap) + 16u) + QPixmap (0x0x7f64e6f704e0) 0 + primary-for QBitmap (0x0x7f64e6f70478) + QPaintDevice (0x0x7f64e6f5eae0) 0 + primary-for QPixmap (0x0x7f64e6f704e0) + +Class QClipboard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QClipboard::QPrivateSignal (0x0x7f64e6f5ee40) 0 empty + +Vtable for QClipboard +QClipboard::_ZTV10QClipboard: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QClipboard) +16 (int (*)(...))QClipboard::metaObject +24 (int (*)(...))QClipboard::qt_metacast +32 (int (*)(...))QClipboard::qt_metacall +40 (int (*)(...))QClipboard::~QClipboard +48 (int (*)(...))QClipboard::~QClipboard +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QClipboard + size=16 align=8 + base size=16 base align=8 +QClipboard (0x0x7f64e6f70750) 0 + vptr=((& QClipboard::_ZTV10QClipboard) + 16u) + QObject (0x0x7f64e6f5ede0) 0 + primary-for QClipboard (0x0x7f64e6f70750) + +Class QDesktopServices + size=1 align=1 + base size=0 base align=1 +QDesktopServices (0x0x7f64e6f5eea0) 0 empty + +Class QDrag::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDrag::QPrivateSignal (0x0x7f64e6f5ef60) 0 empty + +Vtable for QDrag +QDrag::_ZTV5QDrag: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDrag) +16 (int (*)(...))QDrag::metaObject +24 (int (*)(...))QDrag::qt_metacast +32 (int (*)(...))QDrag::qt_metacall +40 (int (*)(...))QDrag::~QDrag +48 (int (*)(...))QDrag::~QDrag +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDrag + size=16 align=8 + base size=16 base align=8 +QDrag (0x0x7f64e6f707b8) 0 + vptr=((& QDrag::_ZTV5QDrag) + 16u) + QObject (0x0x7f64e6f5ef00) 0 + primary-for QDrag (0x0x7f64e6f707b8) + +Class QFontInfo + size=8 align=8 + base size=8 base align=8 +QFontInfo (0x0x7f64e7016000) 0 + +Class QFontMetrics + size=8 align=8 + base size=8 base align=8 +QFontMetrics (0x0x7f64e70162a0) 0 + +Class QFontMetricsF + size=8 align=8 + base size=8 base align=8 +QFontMetricsF (0x0x7f64e70165a0) 0 + +Class QGenericPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGenericPlugin::QPrivateSignal (0x0x7f64e70cbd20) 0 empty + +Vtable for QGenericPlugin +QGenericPlugin::_ZTV14QGenericPlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGenericPlugin) +16 (int (*)(...))QGenericPlugin::metaObject +24 (int (*)(...))QGenericPlugin::qt_metacast +32 (int (*)(...))QGenericPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGenericPlugin + size=16 align=8 + base size=16 base align=8 +QGenericPlugin (0x0x7f64e70c9270) 0 + vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16u) + QObject (0x0x7f64e70cbcc0) 0 + primary-for QGenericPlugin (0x0x7f64e70c9270) + +Class QGenericPluginFactory + size=1 align=1 + base size=0 base align=1 +QGenericPluginFactory (0x0x7f64e70cbd80) 0 empty + +Class QInputMethod::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputMethod::QPrivateSignal (0x0x7f64e70cbe40) 0 empty + +Vtable for QInputMethod +QInputMethod::_ZTV12QInputMethod: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputMethod) +16 (int (*)(...))QInputMethod::metaObject +24 (int (*)(...))QInputMethod::qt_metacast +32 (int (*)(...))QInputMethod::qt_metacall +40 (int (*)(...))QInputMethod::~QInputMethod +48 (int (*)(...))QInputMethod::~QInputMethod +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputMethod + size=16 align=8 + base size=16 base align=8 +QInputMethod (0x0x7f64e70c92d8) 0 + vptr=((& QInputMethod::_ZTV12QInputMethod) + 16u) + QObject (0x0x7f64e70cbde0) 0 + primary-for QInputMethod (0x0x7f64e70c92d8) + +Class QGuiApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGuiApplication::QPrivateSignal (0x0x7f64e70cbf00) 0 empty + +Vtable for QGuiApplication +QGuiApplication::_ZTV15QGuiApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGuiApplication) +16 (int (*)(...))QGuiApplication::metaObject +24 (int (*)(...))QGuiApplication::qt_metacast +32 (int (*)(...))QGuiApplication::qt_metacall +40 (int (*)(...))QGuiApplication::~QGuiApplication +48 (int (*)(...))QGuiApplication::~QGuiApplication +56 (int (*)(...))QGuiApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGuiApplication::notify +120 (int (*)(...))QGuiApplication::compressEvent + +Class QGuiApplication + size=16 align=8 + base size=16 base align=8 +QGuiApplication (0x0x7f64e70c9340) 0 + vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16u) + QCoreApplication (0x0x7f64e70c93a8) 0 + primary-for QGuiApplication (0x0x7f64e70c9340) + QObject (0x0x7f64e70cbea0) 0 + primary-for QCoreApplication (0x0x7f64e70c93a8) + +Class QIconEngine::AvailableSizesArgument + size=16 align=8 + base size=16 base align=8 +QIconEngine::AvailableSizesArgument (0x0x7f64e6dee480) 0 + +Class QIconEngine::ScaledPixmapArgument + size=56 align=8 + base size=56 base align=8 +QIconEngine::ScaledPixmapArgument (0x0x7f64e6dee600) 0 + +Vtable for QIconEngine +QIconEngine::_ZTV11QIconEngine: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QIconEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QIconEngine::actualSize +48 (int (*)(...))QIconEngine::pixmap +56 (int (*)(...))QIconEngine::addPixmap +64 (int (*)(...))QIconEngine::addFile +72 (int (*)(...))QIconEngine::key +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QIconEngine::read +96 (int (*)(...))QIconEngine::write +104 (int (*)(...))QIconEngine::availableSizes +112 (int (*)(...))QIconEngine::iconName +120 (int (*)(...))QIconEngine::virtual_hook + +Class QIconEngine + size=8 align=8 + base size=8 base align=8 +QIconEngine (0x0x7f64e6dee420) 0 nearly-empty + vptr=((& QIconEngine::_ZTV11QIconEngine) + 16u) + +Class QIconEnginePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIconEnginePlugin::QPrivateSignal (0x0x7f64e6dee6c0) 0 empty + +Vtable for QIconEnginePlugin +QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QIconEnginePlugin) +16 (int (*)(...))QIconEnginePlugin::metaObject +24 (int (*)(...))QIconEnginePlugin::qt_metacast +32 (int (*)(...))QIconEnginePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QIconEnginePlugin + size=16 align=8 + base size=16 base align=8 +QIconEnginePlugin (0x0x7f64e70c99c0) 0 + vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16u) + QObject (0x0x7f64e6dee660) 0 + primary-for QIconEnginePlugin (0x0x7f64e70c99c0) + +Vtable for QImageIOHandler +QImageIOHandler::_ZTV15QImageIOHandler: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QImageIOHandler) +16 0u +24 0u +32 (int (*)(...))QImageIOHandler::name +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QImageIOHandler::write +64 (int (*)(...))QImageIOHandler::option +72 (int (*)(...))QImageIOHandler::setOption +80 (int (*)(...))QImageIOHandler::supportsOption +88 (int (*)(...))QImageIOHandler::jumpToNextImage +96 (int (*)(...))QImageIOHandler::jumpToImage +104 (int (*)(...))QImageIOHandler::loopCount +112 (int (*)(...))QImageIOHandler::imageCount +120 (int (*)(...))QImageIOHandler::nextImageDelay +128 (int (*)(...))QImageIOHandler::currentImageNumber +136 (int (*)(...))QImageIOHandler::currentImageRect + +Class QImageIOHandler + size=16 align=8 + base size=16 base align=8 +QImageIOHandler (0x0x7f64e6dee720) 0 + vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16u) + +Class QImageIOPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QImageIOPlugin::QPrivateSignal (0x0x7f64e6dee8a0) 0 empty + +Vtable for QImageIOPlugin +QImageIOPlugin::_ZTV14QImageIOPlugin: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QImageIOPlugin) +16 (int (*)(...))QImageIOPlugin::metaObject +24 (int (*)(...))QImageIOPlugin::qt_metacast +32 (int (*)(...))QImageIOPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QImageIOPlugin + size=16 align=8 + base size=16 base align=8 +QImageIOPlugin (0x0x7f64e70c9a28) 0 + vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16u) + QObject (0x0x7f64e6dee840) 0 + primary-for QImageIOPlugin (0x0x7f64e70c9a28) + +Class QImageReader + size=8 align=8 + base size=8 base align=8 +QImageReader (0x0x7f64e6deea80) 0 + +Class QImageWriter + size=8 align=8 + base size=8 base align=8 +QImageWriter (0x0x7f64e6deeae0) 0 + +Class QVector3D + size=12 align=4 + base size=12 base align=4 +QVector3D (0x0x7f64e6deeb40) 0 + +Class QVector4D + size=16 align=4 + base size=16 base align=4 +QVector4D (0x0x7f64e6deede0) 0 + +Class QQuaternion + size=16 align=4 + base size=16 base align=4 +QQuaternion (0x0x7f64e6b250c0) 0 + +Class QMatrix4x4 + size=68 align=4 + base size=68 base align=4 +QMatrix4x4 (0x0x7f64e6b256c0) 0 + +Class QMovie::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMovie::QPrivateSignal (0x0x7f64e6b25e40) 0 empty + +Vtable for QMovie +QMovie::_ZTV6QMovie: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QMovie) +16 (int (*)(...))QMovie::metaObject +24 (int (*)(...))QMovie::qt_metacast +32 (int (*)(...))QMovie::qt_metacall +40 (int (*)(...))QMovie::~QMovie +48 (int (*)(...))QMovie::~QMovie +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QMovie + size=16 align=8 + base size=16 base align=8 +QMovie (0x0x7f64e6b7dc30) 0 + vptr=((& QMovie::_ZTV6QMovie) + 16u) + QObject (0x0x7f64e6b25de0) 0 + primary-for QMovie (0x0x7f64e6b7dc30) + +Class QOffscreenSurface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOffscreenSurface::QPrivateSignal (0x0x7f64e6b25f60) 0 empty + +Vtable for QOffscreenSurface +QOffscreenSurface::_ZTV17QOffscreenSurface: 26u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOffscreenSurface) +16 (int (*)(...))QOffscreenSurface::metaObject +24 (int (*)(...))QOffscreenSurface::qt_metacast +32 (int (*)(...))QOffscreenSurface::qt_metacall +40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOffscreenSurface::surfaceType +120 (int (*)(...))QOffscreenSurface::format +128 (int (*)(...))QOffscreenSurface::size +136 (int (*)(...))QOffscreenSurface::surfaceHandle +144 (int (*)(...))-16 +152 (int (*)(...))(& _ZTI17QOffscreenSurface) +160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev +168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev +176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv +184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv +192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv +200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv + +Class QOffscreenSurface + size=40 align=8 + base size=40 base align=8 +QOffscreenSurface (0x0x7f64e6ccbd20) 0 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16u) + QObject (0x0x7f64e6b25ea0) 0 + primary-for QOffscreenSurface (0x0x7f64e6ccbd20) + QSurface (0x0x7f64e6b25f00) 16 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160u) + +Class QOpenGLBuffer + size=8 align=8 + base size=8 base align=8 +QOpenGLBuffer (0x0x7f64e6a81060) 0 + +Class QOpenGLVersionStatus + size=12 align=4 + base size=12 base align=4 +QOpenGLVersionStatus (0x0x7f64e6a81240) 0 + +Class QOpenGLVersionFunctionsBackend + size=16 align=8 + base size=12 base align=8 +QOpenGLVersionFunctionsBackend (0x0x7f64e669dd20) 0 + +Class QOpenGLVersionFunctionsStorage + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionFunctionsStorage (0x0x7f64e669dd80) 0 + +Class QAbstractOpenGLFunctionsPrivate + size=16 align=8 + base size=9 base align=8 +QAbstractOpenGLFunctionsPrivate (0x0x7f64e669dde0) 0 + +Vtable for QAbstractOpenGLFunctions +QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions) +16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions + +Class QAbstractOpenGLFunctions + size=16 align=8 + base size=16 base align=8 +QAbstractOpenGLFunctions (0x0x7f64e669de40) 0 + vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16u) + +Class QOpenGLFunctions_1_0_CoreBackend::Functions + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7f64e669df00) 0 + +Class QOpenGLFunctions_1_0_CoreBackend + size=400 align=8 + base size=400 base align=8 +QOpenGLFunctions_1_0_CoreBackend (0x0x7f64e669eea0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e669dea0) 0 + +Class QOpenGLFunctions_1_1_CoreBackend::Functions + size=128 align=8 + base size=128 base align=8 +QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7f64e66e8060) 0 + +Class QOpenGLFunctions_1_1_CoreBackend + size=144 align=8 + base size=144 base align=8 +QOpenGLFunctions_1_1_CoreBackend (0x0x7f64e669ef08) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e8000) 0 + +Class QOpenGLFunctions_1_2_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7f64e66e8180) 0 + +Class QOpenGLFunctions_1_2_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_1_2_CoreBackend (0x0x7f64e669ef70) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e8120) 0 + +Class QOpenGLFunctions_1_3_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7f64e66e82a0) 0 + +Class QOpenGLFunctions_1_3_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_1_3_CoreBackend (0x0x7f64e66fd000) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e8240) 0 + +Class QOpenGLFunctions_1_4_CoreBackend::Functions + size=56 align=8 + base size=56 base align=8 +QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7f64e66e8420) 0 + +Class QOpenGLFunctions_1_4_CoreBackend + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_4_CoreBackend (0x0x7f64e66fd068) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e83c0) 0 + +Class QOpenGLFunctions_1_5_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7f64e66e8540) 0 + +Class QOpenGLFunctions_1_5_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_1_5_CoreBackend (0x0x7f64e66fd0d0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e84e0) 0 + +Class QOpenGLFunctions_2_0_CoreBackend::Functions + size=744 align=8 + base size=744 base align=8 +QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7f64e66e8660) 0 + +Class QOpenGLFunctions_2_0_CoreBackend + size=760 align=8 + base size=760 base align=8 +QOpenGLFunctions_2_0_CoreBackend (0x0x7f64e66fd138) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e8600) 0 + +Class QOpenGLFunctions_2_1_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7f64e66e8780) 0 + +Class QOpenGLFunctions_2_1_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_2_1_CoreBackend (0x0x7f64e66fd1a0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e8720) 0 + +Class QOpenGLFunctions_3_0_CoreBackend::Functions + size=672 align=8 + base size=672 base align=8 +QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7f64e66e88a0) 0 + +Class QOpenGLFunctions_3_0_CoreBackend + size=688 align=8 + base size=688 base align=8 +QOpenGLFunctions_3_0_CoreBackend (0x0x7f64e66fd208) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e8840) 0 + +Class QOpenGLFunctions_3_1_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7f64e66e89c0) 0 + +Class QOpenGLFunctions_3_1_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_3_1_CoreBackend (0x0x7f64e66fd270) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e8960) 0 + +Class QOpenGLFunctions_3_2_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7f64e66e8ae0) 0 + +Class QOpenGLFunctions_3_2_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_3_2_CoreBackend (0x0x7f64e66fd2d8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e8a80) 0 + +Class QOpenGLFunctions_3_3_CoreBackend::Functions + size=464 align=8 + base size=464 base align=8 +QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7f64e66e8c00) 0 + +Class QOpenGLFunctions_3_3_CoreBackend + size=480 align=8 + base size=480 base align=8 +QOpenGLFunctions_3_3_CoreBackend (0x0x7f64e66fd340) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e8ba0) 0 + +Class QOpenGLFunctions_4_0_CoreBackend::Functions + size=368 align=8 + base size=368 base align=8 +QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7f64e66e8d20) 0 + +Class QOpenGLFunctions_4_0_CoreBackend + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_4_0_CoreBackend (0x0x7f64e66fd3a8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e8cc0) 0 + +Class QOpenGLFunctions_4_1_CoreBackend::Functions + size=704 align=8 + base size=704 base align=8 +QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7f64e66e8e40) 0 + +Class QOpenGLFunctions_4_1_CoreBackend + size=720 align=8 + base size=720 base align=8 +QOpenGLFunctions_4_1_CoreBackend (0x0x7f64e66fd410) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e8de0) 0 + +Class QOpenGLFunctions_4_2_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7f64e66e8f60) 0 + +Class QOpenGLFunctions_4_2_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_2_CoreBackend (0x0x7f64e66fd478) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e66e8f00) 0 + +Class QOpenGLFunctions_4_3_CoreBackend::Functions + size=344 align=8 + base size=344 base align=8 +QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7f64e63d40c0) 0 + +Class QOpenGLFunctions_4_3_CoreBackend + size=360 align=8 + base size=360 base align=8 +QOpenGLFunctions_4_3_CoreBackend (0x0x7f64e66fd4e0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e63d4060) 0 + +Class QOpenGLFunctions_4_4_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7f64e63d41e0) 0 + +Class QOpenGLFunctions_4_4_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_4_4_CoreBackend (0x0x7f64e66fd548) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e63d4180) 0 + +Class QOpenGLFunctions_4_5_CoreBackend::Functions + size=848 align=8 + base size=848 base align=8 +QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7f64e63d4360) 0 + +Class QOpenGLFunctions_4_5_CoreBackend + size=864 align=8 + base size=864 base align=8 +QOpenGLFunctions_4_5_CoreBackend (0x0x7f64e66fd5b0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e63d4300) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions + size=2064 align=8 + base size=2064 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7f64e63d4480) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend + size=2080 align=8 + base size=2080 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7f64e66fd618) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e63d4420) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions + size=136 align=8 + base size=136 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7f64e63d45a0) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7f64e66fd680) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e63d4540) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7f64e63d46c0) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend + size=272 align=8 + base size=272 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7f64e66fd6e8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e63d4660) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions + size=296 align=8 + base size=296 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7f64e63d47e0) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend + size=312 align=8 + base size=312 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7f64e66fd750) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e63d4780) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7f64e63d4900) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend + size=320 align=8 + base size=320 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7f64e66fd7b8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e63d48a0) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions + size=288 align=8 + base size=288 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7f64e63d4a20) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7f64e66fd820) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e63d49c0) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions + size=160 align=8 + base size=160 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7f64e63d4b40) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend + size=176 align=8 + base size=176 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7f64e66fd888) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e63d4ae0) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions + size=240 align=8 + base size=240 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7f64e63d4c60) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7f64e66fd8f0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e63d4c00) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7f64e63d4d80) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7f64e66fd958) 0 + QOpenGLVersionFunctionsBackend (0x0x7f64e63d4d20) 0 + +Class QOpenGLVersionProfile + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionProfile (0x0x7f64e63d4e40) 0 + +Class QOpenGLContextGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContextGroup::QPrivateSignal (0x0x7f64e64fb840) 0 empty + +Vtable for QOpenGLContextGroup +QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QOpenGLContextGroup) +16 (int (*)(...))QOpenGLContextGroup::metaObject +24 (int (*)(...))QOpenGLContextGroup::qt_metacast +32 (int (*)(...))QOpenGLContextGroup::qt_metacall +40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContextGroup + size=16 align=8 + base size=16 base align=8 +QOpenGLContextGroup (0x0x7f64e650a3a8) 0 + vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16u) + QObject (0x0x7f64e64fb7e0) 0 + primary-for QOpenGLContextGroup (0x0x7f64e650a3a8) + +Class QOpenGLContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContext::QPrivateSignal (0x0x7f64e64fb900) 0 empty + +Vtable for QOpenGLContext +QOpenGLContext::_ZTV14QOpenGLContext: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QOpenGLContext) +16 (int (*)(...))QOpenGLContext::metaObject +24 (int (*)(...))QOpenGLContext::qt_metacast +32 (int (*)(...))QOpenGLContext::qt_metacall +40 (int (*)(...))QOpenGLContext::~QOpenGLContext +48 (int (*)(...))QOpenGLContext::~QOpenGLContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContext + size=16 align=8 + base size=16 base align=8 +QOpenGLContext (0x0x7f64e650a410) 0 + vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16u) + QObject (0x0x7f64e64fb8a0) 0 + primary-for QOpenGLContext (0x0x7f64e650a410) + +Class QOpenGLDebugMessage + size=8 align=8 + base size=8 base align=8 +QOpenGLDebugMessage (0x0x7f64e64fb960) 0 + +Class QOpenGLDebugLogger::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLDebugLogger::QPrivateSignal (0x0x7f64e61b7180) 0 empty + +Vtable for QOpenGLDebugLogger +QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger) +16 (int (*)(...))QOpenGLDebugLogger::metaObject +24 (int (*)(...))QOpenGLDebugLogger::qt_metacast +32 (int (*)(...))QOpenGLDebugLogger::qt_metacall +40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLDebugLogger + size=16 align=8 + base size=16 base align=8 +QOpenGLDebugLogger (0x0x7f64e650a888) 0 + vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16u) + QObject (0x0x7f64e61b7120) 0 + primary-for QOpenGLDebugLogger (0x0x7f64e650a888) + +Class QOpenGLFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLFunctions (0x0x7f64e61b7300) 0 + +Class QOpenGLFunctionsPrivate::Functions + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate::Functions (0x0x7f64e61b7540) 0 + +Class QOpenGLFunctionsPrivate + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate (0x0x7f64e61b74e0) 0 + +Class QOpenGLExtraFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLExtraFunctions (0x0x7f64e650aaf8) 0 + QOpenGLFunctions (0x0x7f64e5f6ec60) 0 + +Class QOpenGLExtraFunctionsPrivate::Functions + size=1728 align=8 + base size=1728 base align=8 +QOpenGLExtraFunctionsPrivate::Functions (0x0x7f64e5f6ed20) 0 + +Class QOpenGLExtraFunctionsPrivate + size=2880 align=8 + base size=2880 base align=8 +QOpenGLExtraFunctionsPrivate (0x0x7f64e650ab60) 0 + QOpenGLFunctionsPrivate (0x0x7f64e5f6ecc0) 0 + +Vtable for QOpenGLFramebufferObject +QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject) +16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject +24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject + +Class QOpenGLFramebufferObject + size=16 align=8 + base size=16 base align=8 +QOpenGLFramebufferObject (0x0x7f64e5dd7420) 0 + vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16u) + +Class QOpenGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QOpenGLFramebufferObjectFormat (0x0x7f64e5dd7540) 0 + +Vtable for QOpenGLPaintDevice +QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice) +16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +32 (int (*)(...))QOpenGLPaintDevice::devType +40 (int (*)(...))QOpenGLPaintDevice::paintEngine +48 (int (*)(...))QOpenGLPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget + +Class QOpenGLPaintDevice + size=32 align=8 + base size=32 base align=8 +QOpenGLPaintDevice (0x0x7f64e650ae38) 0 + vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16u) + QPaintDevice (0x0x7f64e5dd75a0) 0 + primary-for QOpenGLPaintDevice (0x0x7f64e650ae38) + +Class QOpenGLPixelTransferOptions + size=8 align=8 + base size=8 base align=8 +QOpenGLPixelTransferOptions (0x0x7f64e5dd76c0) 0 + +Class QOpenGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShader::QPrivateSignal (0x0x7f64e5dd7a20) 0 empty + +Vtable for QOpenGLShader +QOpenGLShader::_ZTV13QOpenGLShader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLShader) +16 (int (*)(...))QOpenGLShader::metaObject +24 (int (*)(...))QOpenGLShader::qt_metacast +32 (int (*)(...))QOpenGLShader::qt_metacall +40 (int (*)(...))QOpenGLShader::~QOpenGLShader +48 (int (*)(...))QOpenGLShader::~QOpenGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLShader + size=16 align=8 + base size=16 base align=8 +QOpenGLShader (0x0x7f64e5e41068) 0 + vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16u) + QObject (0x0x7f64e5dd79c0) 0 + primary-for QOpenGLShader (0x0x7f64e5e41068) + +Class QOpenGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShaderProgram::QPrivateSignal (0x0x7f64e5dd7c60) 0 empty + +Vtable for QOpenGLShaderProgram +QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram) +16 (int (*)(...))QOpenGLShaderProgram::metaObject +24 (int (*)(...))QOpenGLShaderProgram::qt_metacast +32 (int (*)(...))QOpenGLShaderProgram::qt_metacall +40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOpenGLShaderProgram::link + +Class QOpenGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QOpenGLShaderProgram (0x0x7f64e5e411a0) 0 + vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16u) + QObject (0x0x7f64e5dd7c00) 0 + primary-for QOpenGLShaderProgram (0x0x7f64e5e411a0) + +Class QOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QOpenGLTexture (0x0x7f64e5dd7cc0) 0 + +Class QOpenGLTextureBlitter + size=8 align=8 + base size=8 base align=8 +QOpenGLTextureBlitter (0x0x7f64e5dd7f60) 0 + +Class QOpenGLTimerQuery::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimerQuery::QPrivateSignal (0x0x7f64e5b81120) 0 empty + +Vtable for QOpenGLTimerQuery +QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery) +16 (int (*)(...))QOpenGLTimerQuery::metaObject +24 (int (*)(...))QOpenGLTimerQuery::qt_metacast +32 (int (*)(...))QOpenGLTimerQuery::qt_metacall +40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimerQuery + size=16 align=8 + base size=16 base align=8 +QOpenGLTimerQuery (0x0x7f64e5e412d8) 0 + vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16u) + QObject (0x0x7f64e5b810c0) 0 + primary-for QOpenGLTimerQuery (0x0x7f64e5e412d8) + +Class QOpenGLTimeMonitor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimeMonitor::QPrivateSignal (0x0x7f64e5b811e0) 0 empty + +Vtable for QOpenGLTimeMonitor +QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor) +16 (int (*)(...))QOpenGLTimeMonitor::metaObject +24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast +32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall +40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimeMonitor + size=16 align=8 + base size=16 base align=8 +QOpenGLTimeMonitor (0x0x7f64e5e41340) 0 + vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16u) + QObject (0x0x7f64e5b81180) 0 + primary-for QOpenGLTimeMonitor (0x0x7f64e5e41340) + +Class QOpenGLVertexArrayObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLVertexArrayObject::QPrivateSignal (0x0x7f64e5b812a0) 0 empty + +Class QOpenGLVertexArrayObject::Binder + size=8 align=8 + base size=8 base align=8 +QOpenGLVertexArrayObject::Binder (0x0x7f64e5b81300) 0 + +Vtable for QOpenGLVertexArrayObject +QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject) +16 (int (*)(...))QOpenGLVertexArrayObject::metaObject +24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast +32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall +40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLVertexArrayObject + size=16 align=8 + base size=16 base align=8 +QOpenGLVertexArrayObject (0x0x7f64e5e413a8) 0 + vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16u) + QObject (0x0x7f64e5b81240) 0 + primary-for QOpenGLVertexArrayObject (0x0x7f64e5e413a8) + +Class QPaintDeviceWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPaintDeviceWindow::QPrivateSignal (0x0x7f64e5b81480) 0 empty + +Vtable for QPaintDeviceWindow +QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 58u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +16 (int (*)(...))QPaintDeviceWindow::metaObject +24 (int (*)(...))QPaintDeviceWindow::qt_metacast +32 (int (*)(...))QPaintDeviceWindow::qt_metacall +40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QPaintDeviceWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))-16 +328 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +336 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev +344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +384 (int (*)(...))-40 +392 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +400 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev +408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev +416 (int (*)(...))QPaintDevice::devType +424 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE +440 (int (*)(...))QPaintDevice::initPainter +448 (int (*)(...))QPaintDevice::redirected +456 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDeviceWindow + size=64 align=8 + base size=64 base align=8 +QPaintDeviceWindow (0x0x7f64e5baabd0) 0 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16u) + QWindow (0x0x7f64e5baac40) 0 + primary-for QPaintDeviceWindow (0x0x7f64e5baabd0) + QObject (0x0x7f64e5b81360) 0 + primary-for QWindow (0x0x7f64e5baac40) + QSurface (0x0x7f64e5b813c0) 16 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 336u) + QPaintDevice (0x0x7f64e5b81420) 40 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 400u) + +Class QOpenGLWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWindow::QPrivateSignal (0x0x7f64e5b81600) 0 empty + +Vtable for QOpenGLWindow +QOpenGLWindow::_ZTV13QOpenGLWindow: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWindow) +16 (int (*)(...))QOpenGLWindow::metaObject +24 (int (*)(...))QOpenGLWindow::qt_metacast +32 (int (*)(...))QOpenGLWindow::qt_metacall +40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QOpenGLWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QOpenGLWindow::paintEvent +304 (int (*)(...))QOpenGLWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QOpenGLWindow::initializeGL +328 (int (*)(...))QOpenGLWindow::resizeGL +336 (int (*)(...))QOpenGLWindow::paintGL +344 (int (*)(...))QOpenGLWindow::paintUnderGL +352 (int (*)(...))QOpenGLWindow::paintOverGL +360 (int (*)(...))QOpenGLWindow::redirected +368 (int (*)(...))-16 +376 (int (*)(...))(& _ZTI13QOpenGLWindow) +384 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev +392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev +400 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +408 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +416 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +424 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +432 (int (*)(...))-40 +440 (int (*)(...))(& _ZTI13QOpenGLWindow) +448 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev +456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev +464 (int (*)(...))QPaintDevice::devType +472 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +480 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QPaintDevice::initPainter +496 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint +504 (int (*)(...))QPaintDevice::sharedPainter + +Class QOpenGLWindow + size=64 align=8 + base size=64 base align=8 +QOpenGLWindow (0x0x7f64e5e41478) 0 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16u) + QPaintDeviceWindow (0x0x7f64e5bd5000) 0 + primary-for QOpenGLWindow (0x0x7f64e5e41478) + QWindow (0x0x7f64e5bd5070) 0 + primary-for QPaintDeviceWindow (0x0x7f64e5bd5000) + QObject (0x0x7f64e5b814e0) 0 + primary-for QWindow (0x0x7f64e5bd5070) + QSurface (0x0x7f64e5b81540) 16 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 384u) + QPaintDevice (0x0x7f64e5b815a0) 40 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 448u) + +Class QPageSize + size=8 align=8 + base size=8 base align=8 +QPageSize (0x0x7f64e5b81660) 0 + +Class QPageLayout + size=8 align=8 + base size=8 base align=8 +QPageLayout (0x0x7f64e5c40060) 0 + +Class QPagedPaintDevice::Margins + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice::Margins (0x0x7f64e5c40a80) 0 + +Vtable for QPagedPaintDevice +QPagedPaintDevice::_ZTV17QPagedPaintDevice: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QPagedPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QPagedPaintDevice::setPageSize +96 (int (*)(...))QPagedPaintDevice::setPageSizeMM +104 (int (*)(...))QPagedPaintDevice::setMargins + +Class QPagedPaintDevice + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice (0x0x7f64e5c701a0) 0 + vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16u) + QPaintDevice (0x0x7f64e5c40a20) 0 + primary-for QPagedPaintDevice (0x0x7f64e5c701a0) + +Class QPainter::PixmapFragment + size=80 align=8 + base size=80 base align=8 +QPainter::PixmapFragment (0x0x7f64e5c40b40) 0 + +Class QPainter + size=8 align=8 + base size=8 base align=8 +QPainter (0x0x7f64e5c40ae0) 0 + +Class QTextItem + size=1 align=1 + base size=0 base align=1 +QTextItem (0x0x7f64e5942960) 0 empty + +Vtable for QPaintEngine +QPaintEngine::_ZTV12QPaintEngine: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QPaintEngine::drawRects +64 (int (*)(...))QPaintEngine::drawRects +72 (int (*)(...))QPaintEngine::drawLines +80 (int (*)(...))QPaintEngine::drawLines +88 (int (*)(...))QPaintEngine::drawEllipse +96 (int (*)(...))QPaintEngine::drawEllipse +104 (int (*)(...))QPaintEngine::drawPath +112 (int (*)(...))QPaintEngine::drawPoints +120 (int (*)(...))QPaintEngine::drawPoints +128 (int (*)(...))QPaintEngine::drawPolygon +136 (int (*)(...))QPaintEngine::drawPolygon +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QPaintEngine::drawTextItem +160 (int (*)(...))QPaintEngine::drawTiledPixmap +168 (int (*)(...))QPaintEngine::drawImage +176 (int (*)(...))QPaintEngine::coordinateOffset +184 (int (*)(...))__cxa_pure_virtual + +Class QPaintEngine + size=32 align=8 + base size=32 base align=8 +QPaintEngine (0x0x7f64e5942c00) 0 + vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16u) + +Class QPaintEngineState + size=4 align=4 + base size=4 base align=4 +QPaintEngineState (0x0x7f64e5942ea0) 0 + +Class QPdfWriter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPdfWriter::QPrivateSignal (0x0x7f64e5af6300) 0 empty + +Vtable for QPdfWriter +QPdfWriter::_ZTV10QPdfWriter: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QPdfWriter) +16 (int (*)(...))QPdfWriter::metaObject +24 (int (*)(...))QPdfWriter::qt_metacast +32 (int (*)(...))QPdfWriter::qt_metacall +40 (int (*)(...))QPdfWriter::~QPdfWriter +48 (int (*)(...))QPdfWriter::~QPdfWriter +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPdfWriter::newPage +120 (int (*)(...))QPdfWriter::setPageSize +128 (int (*)(...))QPdfWriter::setPageSizeMM +136 (int (*)(...))QPdfWriter::setMargins +144 (int (*)(...))QPdfWriter::paintEngine +152 (int (*)(...))QPdfWriter::metric +160 (int (*)(...))-16 +168 (int (*)(...))(& _ZTI10QPdfWriter) +176 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev +184 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev +192 (int (*)(...))QPaintDevice::devType +200 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv +208 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE +216 (int (*)(...))QPaintDevice::initPainter +224 (int (*)(...))QPaintDevice::redirected +232 (int (*)(...))QPaintDevice::sharedPainter +240 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv +248 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter11setPageSizeEN17QPagedPaintDevice8PageSizeE +256 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter13setPageSizeMMERK6QSizeF +264 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter10setMarginsERKN17QPagedPaintDevice7MarginsE + +Class QPdfWriter + size=48 align=8 + base size=48 base align=8 +QPdfWriter (0x0x7f64e57544d0) 0 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16u) + QObject (0x0x7f64e5af6240) 0 + primary-for QPdfWriter (0x0x7f64e57544d0) + QPagedPaintDevice (0x0x7f64e5abc208) 16 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 176u) + QPaintDevice (0x0x7f64e5af62a0) 16 + primary-for QPagedPaintDevice (0x0x7f64e5abc208) + +Vtable for QPicture +QPicture::_ZTV8QPicture: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPicture) +16 (int (*)(...))QPicture::~QPicture +24 (int (*)(...))QPicture::~QPicture +32 (int (*)(...))QPicture::devType +40 (int (*)(...))QPicture::paintEngine +48 (int (*)(...))QPicture::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPicture::setData + +Class QPicture + size=32 align=8 + base size=32 base align=8 +QPicture (0x0x7f64e5abc270) 0 + vptr=((& QPicture::_ZTV8QPicture) + 16u) + QPaintDevice (0x0x7f64e5af6480) 0 + primary-for QPicture (0x0x7f64e5abc270) + +Class QPictureIO + size=8 align=8 + base size=8 base align=8 +QPictureIO (0x0x7f64e5af6780) 0 + +Class QPictureFormatPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPictureFormatPlugin::QPrivateSignal (0x0x7f64e5af6840) 0 empty + +Vtable for QPictureFormatPlugin +QPictureFormatPlugin::_ZTV20QPictureFormatPlugin: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QPictureFormatPlugin) +16 (int (*)(...))QPictureFormatPlugin::metaObject +24 (int (*)(...))QPictureFormatPlugin::qt_metacast +32 (int (*)(...))QPictureFormatPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPictureFormatPlugin::loadPicture +120 (int (*)(...))QPictureFormatPlugin::savePicture +128 (int (*)(...))__cxa_pure_virtual + +Class QPictureFormatPlugin + size=16 align=8 + base size=16 base align=8 +QPictureFormatPlugin (0x0x7f64e5abc478) 0 + vptr=((& QPictureFormatPlugin::_ZTV20QPictureFormatPlugin) + 16u) + QObject (0x0x7f64e5af67e0) 0 + primary-for QPictureFormatPlugin (0x0x7f64e5abc478) + +Class QPixmapCache::Key + size=8 align=8 + base size=8 base align=8 +QPixmapCache::Key (0x0x7f64e5af6900) 0 + +Class QPixmapCache + size=1 align=1 + base size=0 base align=1 +QPixmapCache (0x0x7f64e5af68a0) 0 empty + +Class QRasterWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRasterWindow::QPrivateSignal (0x0x7f64e583ca80) 0 empty + +Vtable for QRasterWindow +QRasterWindow::_ZTV13QRasterWindow: 59u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QRasterWindow) +16 (int (*)(...))QRasterWindow::metaObject +24 (int (*)(...))QRasterWindow::qt_metacast +32 (int (*)(...))QRasterWindow::qt_metacall +40 (int (*)(...))QRasterWindow::~QRasterWindow +48 (int (*)(...))QRasterWindow::~QRasterWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QRasterWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QRasterWindow::redirected +328 (int (*)(...))-16 +336 (int (*)(...))(& _ZTI13QRasterWindow) +344 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev +352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +392 (int (*)(...))-40 +400 (int (*)(...))(& _ZTI13QRasterWindow) +408 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev +416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev +424 (int (*)(...))QPaintDevice::devType +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +440 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE +448 (int (*)(...))QPaintDevice::initPainter +456 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint +464 (int (*)(...))QPaintDevice::sharedPainter + +Class QRasterWindow + size=64 align=8 + base size=64 base align=8 +QRasterWindow (0x0x7f64e583db60) 0 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16u) + QPaintDeviceWindow (0x0x7f64e584b2a0) 0 + primary-for QRasterWindow (0x0x7f64e583db60) + QWindow (0x0x7f64e584b310) 0 + primary-for QPaintDeviceWindow (0x0x7f64e584b2a0) + QObject (0x0x7f64e583c960) 0 + primary-for QWindow (0x0x7f64e584b310) + QSurface (0x0x7f64e583c9c0) 16 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 344u) + QPaintDevice (0x0x7f64e583ca20) 40 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 408u) + +Class QScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScreen::QPrivateSignal (0x0x7f64e583cb40) 0 empty + +Vtable for QScreen +QScreen::_ZTV7QScreen: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QScreen) +16 (int (*)(...))QScreen::metaObject +24 (int (*)(...))QScreen::qt_metacast +32 (int (*)(...))QScreen::qt_metacall +40 (int (*)(...))QScreen::~QScreen +48 (int (*)(...))QScreen::~QScreen +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScreen + size=16 align=8 + base size=16 base align=8 +QScreen (0x0x7f64e583dc30) 0 + vptr=((& QScreen::_ZTV7QScreen) + 16u) + QObject (0x0x7f64e583cae0) 0 + primary-for QScreen (0x0x7f64e583dc30) + +Class QSessionManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSessionManager::QPrivateSignal (0x0x7f64e583cc00) 0 empty + +Vtable for QSessionManager +QSessionManager::_ZTV15QSessionManager: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSessionManager) +16 (int (*)(...))QSessionManager::metaObject +24 (int (*)(...))QSessionManager::qt_metacast +32 (int (*)(...))QSessionManager::qt_metacall +40 (int (*)(...))QSessionManager::~QSessionManager +48 (int (*)(...))QSessionManager::~QSessionManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSessionManager + size=16 align=8 + base size=16 base align=8 +QSessionManager (0x0x7f64e583dc98) 0 + vptr=((& QSessionManager::_ZTV15QSessionManager) + 16u) + QObject (0x0x7f64e583cba0) 0 + primary-for QSessionManager (0x0x7f64e583dc98) + +Vtable for QStandardItem +QStandardItem::_ZTV13QStandardItem: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStandardItem) +16 (int (*)(...))QStandardItem::~QStandardItem +24 (int (*)(...))QStandardItem::~QStandardItem +32 (int (*)(...))QStandardItem::data +40 (int (*)(...))QStandardItem::setData +48 (int (*)(...))QStandardItem::clone +56 (int (*)(...))QStandardItem::type +64 (int (*)(...))QStandardItem::read +72 (int (*)(...))QStandardItem::write +80 (int (*)(...))QStandardItem::operator< + +Class QStandardItem + size=16 align=8 + base size=16 base align=8 +QStandardItem (0x0x7f64e583cc60) 0 + vptr=((& QStandardItem::_ZTV13QStandardItem) + 16u) + +Class QStandardItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStandardItemModel::QPrivateSignal (0x0x7f64e58d63c0) 0 empty + +Vtable for QStandardItemModel +QStandardItemModel::_ZTV18QStandardItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QStandardItemModel) +16 (int (*)(...))QStandardItemModel::metaObject +24 (int (*)(...))QStandardItemModel::qt_metacast +32 (int (*)(...))QStandardItemModel::qt_metacall +40 (int (*)(...))QStandardItemModel::~QStandardItemModel +48 (int (*)(...))QStandardItemModel::~QStandardItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStandardItemModel::index +120 (int (*)(...))QStandardItemModel::parent +128 (int (*)(...))QStandardItemModel::sibling +136 (int (*)(...))QStandardItemModel::rowCount +144 (int (*)(...))QStandardItemModel::columnCount +152 (int (*)(...))QStandardItemModel::hasChildren +160 (int (*)(...))QStandardItemModel::data +168 (int (*)(...))QStandardItemModel::setData +176 (int (*)(...))QStandardItemModel::headerData +184 (int (*)(...))QStandardItemModel::setHeaderData +192 (int (*)(...))QStandardItemModel::itemData +200 (int (*)(...))QStandardItemModel::setItemData +208 (int (*)(...))QStandardItemModel::mimeTypes +216 (int (*)(...))QStandardItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QStandardItemModel::dropMimeData +240 (int (*)(...))QStandardItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStandardItemModel::insertRows +264 (int (*)(...))QStandardItemModel::insertColumns +272 (int (*)(...))QStandardItemModel::removeRows +280 (int (*)(...))QStandardItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStandardItemModel::flags +328 (int (*)(...))QStandardItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStandardItemModel + size=16 align=8 + base size=16 base align=8 +QStandardItemModel (0x0x7f64e58d8340) 0 + vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16u) + QAbstractItemModel (0x0x7f64e58d83a8) 0 + primary-for QStandardItemModel (0x0x7f64e58d8340) + QObject (0x0x7f64e58d6360) 0 + primary-for QAbstractItemModel (0x0x7f64e58d83a8) + +Class QStaticText + size=8 align=8 + base size=8 base align=8 +QStaticText (0x0x7f64e58d6420) 0 + +Class QStyleHints::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyleHints::QPrivateSignal (0x0x7f64e58d68a0) 0 empty + +Vtable for QStyleHints +QStyleHints::_ZTV11QStyleHints: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QStyleHints) +16 (int (*)(...))QStyleHints::metaObject +24 (int (*)(...))QStyleHints::qt_metacast +32 (int (*)(...))QStyleHints::qt_metacall +40 (int (*)(...))QStyleHints::~QStyleHints +48 (int (*)(...))QStyleHints::~QStyleHints +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QStyleHints + size=16 align=8 + base size=16 base align=8 +QStyleHints (0x0x7f64e58d85b0) 0 + vptr=((& QStyleHints::_ZTV11QStyleHints) + 16u) + QObject (0x0x7f64e58d6840) 0 + primary-for QStyleHints (0x0x7f64e58d85b0) + +Class QTextObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextObject::QPrivateSignal (0x0x7f64e58d6960) 0 empty + +Vtable for QTextObject +QTextObject::_ZTV11QTextObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextObject) +16 (int (*)(...))QTextObject::metaObject +24 (int (*)(...))QTextObject::qt_metacast +32 (int (*)(...))QTextObject::qt_metacall +40 (int (*)(...))QTextObject::~QTextObject +48 (int (*)(...))QTextObject::~QTextObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextObject + size=16 align=8 + base size=16 base align=8 +QTextObject (0x0x7f64e58d8618) 0 + vptr=((& QTextObject::_ZTV11QTextObject) + 16u) + QObject (0x0x7f64e58d6900) 0 + primary-for QTextObject (0x0x7f64e58d8618) + +Class QTextBlockGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBlockGroup::QPrivateSignal (0x0x7f64e58d6a20) 0 empty + +Vtable for QTextBlockGroup +QTextBlockGroup::_ZTV15QTextBlockGroup: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTextBlockGroup) +16 (int (*)(...))QTextBlockGroup::metaObject +24 (int (*)(...))QTextBlockGroup::qt_metacast +32 (int (*)(...))QTextBlockGroup::qt_metacall +40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextBlockGroup + size=16 align=8 + base size=16 base align=8 +QTextBlockGroup (0x0x7f64e58d8680) 0 + vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16u) + QTextObject (0x0x7f64e58d86e8) 0 + primary-for QTextBlockGroup (0x0x7f64e58d8680) + QObject (0x0x7f64e58d69c0) 0 + primary-for QTextObject (0x0x7f64e58d86e8) + +Vtable for QTextFrameLayoutData +QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextFrameLayoutData) +16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData +24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData + +Class QTextFrameLayoutData + size=8 align=8 + base size=8 base align=8 +QTextFrameLayoutData (0x0x7f64e58d6a80) 0 nearly-empty + vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16u) + +Class QTextFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextFrame::QPrivateSignal (0x0x7f64e58d6b40) 0 empty + +Class QTextFrame::iterator + size=32 align=8 + base size=28 base align=8 +QTextFrame::iterator (0x0x7f64e58d6ba0) 0 + +Vtable for QTextFrame +QTextFrame::_ZTV10QTextFrame: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextFrame) +16 (int (*)(...))QTextFrame::metaObject +24 (int (*)(...))QTextFrame::qt_metacast +32 (int (*)(...))QTextFrame::qt_metacall +40 (int (*)(...))QTextFrame::~QTextFrame +48 (int (*)(...))QTextFrame::~QTextFrame +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextFrame + size=16 align=8 + base size=16 base align=8 +QTextFrame (0x0x7f64e58d8750) 0 + vptr=((& QTextFrame::_ZTV10QTextFrame) + 16u) + QTextObject (0x0x7f64e58d87b8) 0 + primary-for QTextFrame (0x0x7f64e58d8750) + QObject (0x0x7f64e58d6ae0) 0 + primary-for QTextObject (0x0x7f64e58d87b8) + +Vtable for QTextBlockUserData +QTextBlockUserData::_ZTV18QTextBlockUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTextBlockUserData) +16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData +24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData + +Class QTextBlockUserData + size=8 align=8 + base size=8 base align=8 +QTextBlockUserData (0x0x7f64e58d6e40) 0 nearly-empty + vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16u) + +Class QTextBlock::iterator + size=24 align=8 + base size=20 base align=8 +QTextBlock::iterator (0x0x7f64e58d6f00) 0 + +Class QTextBlock + size=16 align=8 + base size=12 base align=8 +QTextBlock (0x0x7f64e58d6ea0) 0 + +Class QTextFragment + size=16 align=8 + base size=16 base align=8 +QTextFragment (0x0x7f64e5645420) 0 + +Class QSyntaxHighlighter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSyntaxHighlighter::QPrivateSignal (0x0x7f64e5645720) 0 empty + +Vtable for QSyntaxHighlighter +QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSyntaxHighlighter) +16 (int (*)(...))QSyntaxHighlighter::metaObject +24 (int (*)(...))QSyntaxHighlighter::qt_metacast +32 (int (*)(...))QSyntaxHighlighter::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSyntaxHighlighter + size=16 align=8 + base size=16 base align=8 +QSyntaxHighlighter (0x0x7f64e58d8ea0) 0 + vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16u) + QObject (0x0x7f64e56456c0) 0 + primary-for QSyntaxHighlighter (0x0x7f64e58d8ea0) + +Class QTextDocumentFragment + size=8 align=8 + base size=8 base align=8 +QTextDocumentFragment (0x0x7f64e5645780) 0 + +Class QTextDocumentWriter + size=8 align=8 + base size=8 base align=8 +QTextDocumentWriter (0x0x7f64e56457e0) 0 + +Class QTextList::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextList::QPrivateSignal (0x0x7f64e56458a0) 0 empty + +Vtable for QTextList +QTextList::_ZTV9QTextList: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextList) +16 (int (*)(...))QTextList::metaObject +24 (int (*)(...))QTextList::qt_metacast +32 (int (*)(...))QTextList::qt_metacall +40 (int (*)(...))QTextList::~QTextList +48 (int (*)(...))QTextList::~QTextList +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextList + size=16 align=8 + base size=16 base align=8 +QTextList (0x0x7f64e58d8f08) 0 + vptr=((& QTextList::_ZTV9QTextList) + 16u) + QTextBlockGroup (0x0x7f64e58d8f70) 0 + primary-for QTextList (0x0x7f64e58d8f08) + QTextObject (0x0x7f64e5686000) 0 + primary-for QTextBlockGroup (0x0x7f64e58d8f70) + QObject (0x0x7f64e5645840) 0 + primary-for QTextObject (0x0x7f64e5686000) + +Class QTextTableCell + size=16 align=8 + base size=12 base align=8 +QTextTableCell (0x0x7f64e5645900) 0 + +Class QTextTable::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextTable::QPrivateSignal (0x0x7f64e56459c0) 0 empty + +Vtable for QTextTable +QTextTable::_ZTV10QTextTable: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextTable) +16 (int (*)(...))QTextTable::metaObject +24 (int (*)(...))QTextTable::qt_metacast +32 (int (*)(...))QTextTable::qt_metacall +40 (int (*)(...))QTextTable::~QTextTable +48 (int (*)(...))QTextTable::~QTextTable +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextTable + size=16 align=8 + base size=16 base align=8 +QTextTable (0x0x7f64e5686068) 0 + vptr=((& QTextTable::_ZTV10QTextTable) + 16u) + QTextFrame (0x0x7f64e56860d0) 0 + primary-for QTextTable (0x0x7f64e5686068) + QTextObject (0x0x7f64e5686138) 0 + primary-for QTextFrame (0x0x7f64e56860d0) + QObject (0x0x7f64e5645960) 0 + primary-for QTextObject (0x0x7f64e5686138) + +Class QValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QValidator::QPrivateSignal (0x0x7f64e5645a80) 0 empty + +Vtable for QValidator +QValidator::_ZTV10QValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QValidator) +16 (int (*)(...))QValidator::metaObject +24 (int (*)(...))QValidator::qt_metacast +32 (int (*)(...))QValidator::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QValidator::fixup + +Class QValidator + size=16 align=8 + base size=16 base align=8 +QValidator (0x0x7f64e56861a0) 0 + vptr=((& QValidator::_ZTV10QValidator) + 16u) + QObject (0x0x7f64e5645a20) 0 + primary-for QValidator (0x0x7f64e56861a0) + +Class QIntValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIntValidator::QPrivateSignal (0x0x7f64e5645b40) 0 empty + +Vtable for QIntValidator +QIntValidator::_ZTV13QIntValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QIntValidator) +16 (int (*)(...))QIntValidator::metaObject +24 (int (*)(...))QIntValidator::qt_metacast +32 (int (*)(...))QIntValidator::qt_metacall +40 (int (*)(...))QIntValidator::~QIntValidator +48 (int (*)(...))QIntValidator::~QIntValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIntValidator::validate +120 (int (*)(...))QIntValidator::fixup +128 (int (*)(...))QIntValidator::setRange + +Class QIntValidator + size=24 align=8 + base size=24 base align=8 +QIntValidator (0x0x7f64e5686208) 0 + vptr=((& QIntValidator::_ZTV13QIntValidator) + 16u) + QValidator (0x0x7f64e5686270) 0 + primary-for QIntValidator (0x0x7f64e5686208) + QObject (0x0x7f64e5645ae0) 0 + primary-for QValidator (0x0x7f64e5686270) + +Class QDoubleValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleValidator::QPrivateSignal (0x0x7f64e5645c00) 0 empty + +Vtable for QDoubleValidator +QDoubleValidator::_ZTV16QDoubleValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDoubleValidator) +16 (int (*)(...))QDoubleValidator::metaObject +24 (int (*)(...))QDoubleValidator::qt_metacast +32 (int (*)(...))QDoubleValidator::qt_metacall +40 (int (*)(...))QDoubleValidator::~QDoubleValidator +48 (int (*)(...))QDoubleValidator::~QDoubleValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDoubleValidator::validate +120 (int (*)(...))QValidator::fixup +128 (int (*)(...))QDoubleValidator::setRange + +Class QDoubleValidator + size=40 align=8 + base size=36 base align=8 +QDoubleValidator (0x0x7f64e56862d8) 0 + vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16u) + QValidator (0x0x7f64e5686340) 0 + primary-for QDoubleValidator (0x0x7f64e56862d8) + QObject (0x0x7f64e5645ba0) 0 + primary-for QValidator (0x0x7f64e5686340) + +Class QRegExpValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegExpValidator::QPrivateSignal (0x0x7f64e5645d20) 0 empty + +Vtable for QRegExpValidator +QRegExpValidator::_ZTV16QRegExpValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QRegExpValidator) +16 (int (*)(...))QRegExpValidator::metaObject +24 (int (*)(...))QRegExpValidator::qt_metacast +32 (int (*)(...))QRegExpValidator::qt_metacall +40 (int (*)(...))QRegExpValidator::~QRegExpValidator +48 (int (*)(...))QRegExpValidator::~QRegExpValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegExpValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegExpValidator + size=24 align=8 + base size=24 base align=8 +QRegExpValidator (0x0x7f64e56863a8) 0 + vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16u) + QValidator (0x0x7f64e5686410) 0 + primary-for QRegExpValidator (0x0x7f64e56863a8) + QObject (0x0x7f64e5645cc0) 0 + primary-for QValidator (0x0x7f64e5686410) + +Class QRegularExpressionValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegularExpressionValidator::QPrivateSignal (0x0x7f64e5645de0) 0 empty + +Vtable for QRegularExpressionValidator +QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QRegularExpressionValidator) +16 (int (*)(...))QRegularExpressionValidator::metaObject +24 (int (*)(...))QRegularExpressionValidator::qt_metacast +32 (int (*)(...))QRegularExpressionValidator::qt_metacall +40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegularExpressionValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegularExpressionValidator + size=16 align=8 + base size=16 base align=8 +QRegularExpressionValidator (0x0x7f64e5686478) 0 + vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16u) + QValidator (0x0x7f64e56864e0) 0 + primary-for QRegularExpressionValidator (0x0x7f64e5686478) + QObject (0x0x7f64e5645d80) 0 + primary-for QValidator (0x0x7f64e56864e0) + +Class QNetworkRequest + size=8 align=8 + base size=8 base align=8 +QNetworkRequest (0x0x7f64e5645e40) 0 + +Class QNetworkCacheMetaData + size=8 align=8 + base size=8 base align=8 +QNetworkCacheMetaData (0x0x7f64e53393c0) 0 + +Class QAbstractNetworkCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractNetworkCache::QPrivateSignal (0x0x7f64e5339a80) 0 empty + +Vtable for QAbstractNetworkCache +QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractNetworkCache) +16 (int (*)(...))QAbstractNetworkCache::metaObject +24 (int (*)(...))QAbstractNetworkCache::qt_metacast +32 (int (*)(...))QAbstractNetworkCache::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNetworkCache + size=16 align=8 + base size=16 base align=8 +QAbstractNetworkCache (0x0x7f64e5686d00) 0 + vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16u) + QObject (0x0x7f64e5339a20) 0 + primary-for QAbstractNetworkCache (0x0x7f64e5686d00) + +Class QAbstractSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSocket::QPrivateSignal (0x0x7f64e5339b40) 0 empty + +Vtable for QAbstractSocket +QAbstractSocket::_ZTV15QAbstractSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSocket) +16 (int (*)(...))QAbstractSocket::metaObject +24 (int (*)(...))QAbstractSocket::qt_metacast +32 (int (*)(...))QAbstractSocket::qt_metacall +40 (int (*)(...))QAbstractSocket::~QAbstractSocket +48 (int (*)(...))QAbstractSocket::~QAbstractSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QAbstractSocket + size=16 align=8 + base size=16 base align=8 +QAbstractSocket (0x0x7f64e5686d68) 0 + vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16u) + QIODevice (0x0x7f64e5686dd0) 0 + primary-for QAbstractSocket (0x0x7f64e5686d68) + QObject (0x0x7f64e5339ae0) 0 + primary-for QIODevice (0x0x7f64e5686dd0) + +Class QAuthenticator + size=8 align=8 + base size=8 base align=8 +QAuthenticator (0x0x7f64e542d120) 0 + +Class QDnsDomainNameRecord + size=8 align=8 + base size=8 base align=8 +QDnsDomainNameRecord (0x0x7f64e542d180) 0 + +Class QDnsHostAddressRecord + size=8 align=8 + base size=8 base align=8 +QDnsHostAddressRecord (0x0x7f64e542d480) 0 + +Class QDnsMailExchangeRecord + size=8 align=8 + base size=8 base align=8 +QDnsMailExchangeRecord (0x0x7f64e542d780) 0 + +Class QDnsServiceRecord + size=8 align=8 + base size=8 base align=8 +QDnsServiceRecord (0x0x7f64e542da80) 0 + +Class QDnsTextRecord + size=8 align=8 + base size=8 base align=8 +QDnsTextRecord (0x0x7f64e542dd80) 0 + +Class QDnsLookup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDnsLookup::QPrivateSignal (0x0x7f64e54b8120) 0 empty + +Vtable for QDnsLookup +QDnsLookup::_ZTV10QDnsLookup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDnsLookup) +16 (int (*)(...))QDnsLookup::metaObject +24 (int (*)(...))QDnsLookup::qt_metacast +32 (int (*)(...))QDnsLookup::qt_metacall +40 (int (*)(...))QDnsLookup::~QDnsLookup +48 (int (*)(...))QDnsLookup::~QDnsLookup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDnsLookup + size=16 align=8 + base size=16 base align=8 +QDnsLookup (0x0x7f64e5452820) 0 + vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16u) + QObject (0x0x7f64e54b80c0) 0 + primary-for QDnsLookup (0x0x7f64e5452820) + +Class QIPv6Address + size=16 align=1 + base size=16 base align=1 +QIPv6Address (0x0x7f64e54b8180) 0 + +Class QHostAddress + size=8 align=8 + base size=8 base align=8 +QHostAddress (0x0x7f64e54b81e0) 0 + +Class QHostInfo + size=8 align=8 + base size=8 base align=8 +QHostInfo (0x0x7f64e54b89c0) 0 + +Class QHstsPolicy + size=8 align=8 + base size=8 base align=8 +QHstsPolicy (0x0x7f64e54b8ea0) 0 + +Class QHttpPart + size=8 align=8 + base size=8 base align=8 +QHttpPart (0x0x7f64e51976c0) 0 + +Class QHttpMultiPart::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHttpMultiPart::QPrivateSignal (0x0x7f64e5197a20) 0 empty + +Vtable for QHttpMultiPart +QHttpMultiPart::_ZTV14QHttpMultiPart: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QHttpMultiPart) +16 (int (*)(...))QHttpMultiPart::metaObject +24 (int (*)(...))QHttpMultiPart::qt_metacast +32 (int (*)(...))QHttpMultiPart::qt_metacall +40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QHttpMultiPart + size=16 align=8 + base size=16 base align=8 +QHttpMultiPart (0x0x7f64e516ca90) 0 + vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16u) + QObject (0x0x7f64e51979c0) 0 + primary-for QHttpMultiPart (0x0x7f64e516ca90) + +Class QLocalServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalServer::QPrivateSignal (0x0x7f64e5197ae0) 0 empty + +Vtable for QLocalServer +QLocalServer::_ZTV12QLocalServer: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalServer) +16 (int (*)(...))QLocalServer::metaObject +24 (int (*)(...))QLocalServer::qt_metacast +32 (int (*)(...))QLocalServer::qt_metacall +40 (int (*)(...))QLocalServer::~QLocalServer +48 (int (*)(...))QLocalServer::~QLocalServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalServer::hasPendingConnections +120 (int (*)(...))QLocalServer::nextPendingConnection +128 (int (*)(...))QLocalServer::incomingConnection + +Class QLocalServer + size=16 align=8 + base size=16 base align=8 +QLocalServer (0x0x7f64e516caf8) 0 + vptr=((& QLocalServer::_ZTV12QLocalServer) + 16u) + QObject (0x0x7f64e5197a80) 0 + primary-for QLocalServer (0x0x7f64e516caf8) + +Class QLocalSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalSocket::QPrivateSignal (0x0x7f64e5197d20) 0 empty + +Vtable for QLocalSocket +QLocalSocket::_ZTV12QLocalSocket: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalSocket) +16 (int (*)(...))QLocalSocket::metaObject +24 (int (*)(...))QLocalSocket::qt_metacast +32 (int (*)(...))QLocalSocket::qt_metacall +40 (int (*)(...))QLocalSocket::~QLocalSocket +48 (int (*)(...))QLocalSocket::~QLocalSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalSocket::isSequential +120 (int (*)(...))QLocalSocket::open +128 (int (*)(...))QLocalSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QLocalSocket::bytesAvailable +184 (int (*)(...))QLocalSocket::bytesToWrite +192 (int (*)(...))QLocalSocket::canReadLine +200 (int (*)(...))QLocalSocket::waitForReadyRead +208 (int (*)(...))QLocalSocket::waitForBytesWritten +216 (int (*)(...))QLocalSocket::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QLocalSocket::writeData + +Class QLocalSocket + size=16 align=8 + base size=16 base align=8 +QLocalSocket (0x0x7f64e516cc98) 0 + vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16u) + QIODevice (0x0x7f64e516cd00) 0 + primary-for QLocalSocket (0x0x7f64e516cc98) + QObject (0x0x7f64e5197cc0) 0 + primary-for QIODevice (0x0x7f64e516cd00) + +Class QTcpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpSocket::QPrivateSignal (0x0x7f64e5197de0) 0 empty + +Vtable for QTcpSocket +QTcpSocket::_ZTV10QTcpSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpSocket) +16 (int (*)(...))QTcpSocket::metaObject +24 (int (*)(...))QTcpSocket::qt_metacast +32 (int (*)(...))QTcpSocket::qt_metacall +40 (int (*)(...))QTcpSocket::~QTcpSocket +48 (int (*)(...))QTcpSocket::~QTcpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QTcpSocket + size=16 align=8 + base size=16 base align=8 +QTcpSocket (0x0x7f64e516cd68) 0 + vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16u) + QAbstractSocket (0x0x7f64e516cdd0) 0 + primary-for QTcpSocket (0x0x7f64e516cd68) + QIODevice (0x0x7f64e516ce38) 0 + primary-for QAbstractSocket (0x0x7f64e516cdd0) + QObject (0x0x7f64e5197d80) 0 + primary-for QIODevice (0x0x7f64e516ce38) + +Class QSslCertificate + size=8 align=8 + base size=8 base align=8 +QSslCertificate (0x0x7f64e52ac000) 0 + +Class QSslError + size=8 align=8 + base size=8 base align=8 +QSslError (0x0x7f64e52ac420) 0 + +Class QSslSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSslSocket::QPrivateSignal (0x0x7f64e52acd80) 0 empty + +Vtable for QSslSocket +QSslSocket::_ZTV10QSslSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSslSocket) +16 (int (*)(...))QSslSocket::metaObject +24 (int (*)(...))QSslSocket::qt_metacast +32 (int (*)(...))QSslSocket::qt_metacall +40 (int (*)(...))QSslSocket::~QSslSocket +48 (int (*)(...))QSslSocket::~QSslSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QSslSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QSslSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QSslSocket::bytesAvailable +184 (int (*)(...))QSslSocket::bytesToWrite +192 (int (*)(...))QSslSocket::canReadLine +200 (int (*)(...))QSslSocket::waitForReadyRead +208 (int (*)(...))QSslSocket::waitForBytesWritten +216 (int (*)(...))QSslSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QSslSocket::writeData +240 (int (*)(...))QSslSocket::resume +248 (int (*)(...))QSslSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QSslSocket::disconnectFromHost +272 (int (*)(...))QSslSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QSslSocket::setSocketDescriptor +296 (int (*)(...))QSslSocket::setSocketOption +304 (int (*)(...))QSslSocket::socketOption +312 (int (*)(...))QSslSocket::waitForConnected +320 (int (*)(...))QSslSocket::waitForDisconnected + +Class QSslSocket + size=16 align=8 + base size=16 base align=8 +QSslSocket (0x0x7f64e52d4820) 0 + vptr=((& QSslSocket::_ZTV10QSslSocket) + 16u) + QTcpSocket (0x0x7f64e52d4888) 0 + primary-for QSslSocket (0x0x7f64e52d4820) + QAbstractSocket (0x0x7f64e52d48f0) 0 + primary-for QTcpSocket (0x0x7f64e52d4888) + QIODevice (0x0x7f64e52d4958) 0 + primary-for QAbstractSocket (0x0x7f64e52d48f0) + QObject (0x0x7f64e52acd20) 0 + primary-for QIODevice (0x0x7f64e52d4958) + +Class QSslConfiguration + size=8 align=8 + base size=8 base align=8 +QSslConfiguration (0x0x7f64e52acde0) 0 + +Class QSslPreSharedKeyAuthenticator + size=8 align=8 + base size=8 base align=8 +QSslPreSharedKeyAuthenticator (0x0x7f64e4fab600) 0 + +Class QNetworkAccessManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkAccessManager::QPrivateSignal (0x0x7f64e4fabf00) 0 empty + +Vtable for QNetworkAccessManager +QNetworkAccessManager::_ZTV21QNetworkAccessManager: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QNetworkAccessManager) +16 (int (*)(...))QNetworkAccessManager::metaObject +24 (int (*)(...))QNetworkAccessManager::qt_metacast +32 (int (*)(...))QNetworkAccessManager::qt_metacall +40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkAccessManager::createRequest + +Class QNetworkAccessManager + size=16 align=8 + base size=16 base align=8 +QNetworkAccessManager (0x0x7f64e4fdb618) 0 + vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16u) + QObject (0x0x7f64e4fabea0) 0 + primary-for QNetworkAccessManager (0x0x7f64e4fdb618) + +Class QNetworkConfiguration + size=8 align=8 + base size=8 base align=8 +QNetworkConfiguration (0x0x7f64e4fabf60) 0 + +Class QNetworkConfigurationManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkConfigurationManager::QPrivateSignal (0x0x7f64e5025420) 0 empty + +Vtable for QNetworkConfigurationManager +QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QNetworkConfigurationManager) +16 (int (*)(...))QNetworkConfigurationManager::metaObject +24 (int (*)(...))QNetworkConfigurationManager::qt_metacast +32 (int (*)(...))QNetworkConfigurationManager::qt_metacall +40 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager +48 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QNetworkConfigurationManager + size=16 align=8 + base size=16 base align=8 +QNetworkConfigurationManager (0x0x7f64e4fdb820) 0 + vptr=((& QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager) + 16u) + QObject (0x0x7f64e50253c0) 0 + primary-for QNetworkConfigurationManager (0x0x7f64e4fdb820) + +Class QNetworkCookie + size=8 align=8 + base size=8 base align=8 +QNetworkCookie (0x0x7f64e5025780) 0 + +Class QNetworkCookieJar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkCookieJar::QPrivateSignal (0x0x7f64e5025f60) 0 empty + +Vtable for QNetworkCookieJar +QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkCookieJar) +16 (int (*)(...))QNetworkCookieJar::metaObject +24 (int (*)(...))QNetworkCookieJar::qt_metacast +32 (int (*)(...))QNetworkCookieJar::qt_metacall +40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkCookieJar::cookiesForUrl +120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl +128 (int (*)(...))QNetworkCookieJar::insertCookie +136 (int (*)(...))QNetworkCookieJar::updateCookie +144 (int (*)(...))QNetworkCookieJar::deleteCookie +152 (int (*)(...))QNetworkCookieJar::validateCookie + +Class QNetworkCookieJar + size=16 align=8 + base size=16 base align=8 +QNetworkCookieJar (0x0x7f64e50c7068) 0 + vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16u) + QObject (0x0x7f64e5025f00) 0 + primary-for QNetworkCookieJar (0x0x7f64e50c7068) + +Class QNetworkDatagram + size=8 align=8 + base size=8 base align=8 +QNetworkDatagram (0x0x7f64e50e1000) 0 + +Class QNetworkDiskCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkDiskCache::QPrivateSignal (0x0x7f64e4d7e000) 0 empty + +Vtable for QNetworkDiskCache +QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkDiskCache) +16 (int (*)(...))QNetworkDiskCache::metaObject +24 (int (*)(...))QNetworkDiskCache::qt_metacast +32 (int (*)(...))QNetworkDiskCache::qt_metacall +40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkDiskCache::metaData +120 (int (*)(...))QNetworkDiskCache::updateMetaData +128 (int (*)(...))QNetworkDiskCache::data +136 (int (*)(...))QNetworkDiskCache::remove +144 (int (*)(...))QNetworkDiskCache::cacheSize +152 (int (*)(...))QNetworkDiskCache::prepare +160 (int (*)(...))QNetworkDiskCache::insert +168 (int (*)(...))QNetworkDiskCache::clear +176 (int (*)(...))QNetworkDiskCache::expire + +Class QNetworkDiskCache + size=16 align=8 + base size=16 base align=8 +QNetworkDiskCache (0x0x7f64e4d5fa90) 0 + vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16u) + QAbstractNetworkCache (0x0x7f64e4d5faf8) 0 + primary-for QNetworkDiskCache (0x0x7f64e4d5fa90) + QObject (0x0x7f64e4d46f60) 0 + primary-for QAbstractNetworkCache (0x0x7f64e4d5faf8) + +Class QNetworkAddressEntry + size=8 align=8 + base size=8 base align=8 +QNetworkAddressEntry (0x0x7f64e4d7e060) 0 + +Class QNetworkInterface + size=8 align=8 + base size=8 base align=8 +QNetworkInterface (0x0x7f64e4d7e720) 0 + +Class QNetworkProxyQuery + size=8 align=8 + base size=8 base align=8 +QNetworkProxyQuery (0x0x7f64e4d7ede0) 0 + +Class QNetworkProxy + size=8 align=8 + base size=8 base align=8 +QNetworkProxy (0x0x7f64e4e4a480) 0 + +Vtable for QNetworkProxyFactory +QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QNetworkProxyFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QNetworkProxyFactory + size=8 align=8 + base size=8 base align=8 +QNetworkProxyFactory (0x0x7f64e4e4ac60) 0 nearly-empty + vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16u) + +Class QNetworkReply::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkReply::QPrivateSignal (0x0x7f64e4e4ae40) 0 empty + +Vtable for QNetworkReply +QNetworkReply::_ZTV13QNetworkReply: 36u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QNetworkReply) +16 (int (*)(...))QNetworkReply::metaObject +24 (int (*)(...))QNetworkReply::qt_metacast +32 (int (*)(...))QNetworkReply::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkReply::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QNetworkReply::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QNetworkReply::writeData +240 (int (*)(...))QNetworkReply::setReadBufferSize +248 (int (*)(...))__cxa_pure_virtual +256 (int (*)(...))QNetworkReply::ignoreSslErrors +264 (int (*)(...))QNetworkReply::sslConfigurationImplementation +272 (int (*)(...))QNetworkReply::setSslConfigurationImplementation +280 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation + +Class QNetworkReply + size=16 align=8 + base size=16 base align=8 +QNetworkReply (0x0x7f64e4e841a0) 0 + vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16u) + QIODevice (0x0x7f64e4e84208) 0 + primary-for QNetworkReply (0x0x7f64e4e841a0) + QObject (0x0x7f64e4e4ade0) 0 + primary-for QIODevice (0x0x7f64e4e84208) + +Class QNetworkSession::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkSession::QPrivateSignal (0x0x7f64e4eee060) 0 empty + +Vtable for QNetworkSession +QNetworkSession::_ZTV15QNetworkSession: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QNetworkSession) +16 (int (*)(...))QNetworkSession::metaObject +24 (int (*)(...))QNetworkSession::qt_metacast +32 (int (*)(...))QNetworkSession::qt_metacall +40 (int (*)(...))QNetworkSession::~QNetworkSession +48 (int (*)(...))QNetworkSession::~QNetworkSession +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QNetworkSession::connectNotify +104 (int (*)(...))QNetworkSession::disconnectNotify + +Class QNetworkSession + size=24 align=8 + base size=24 base align=8 +QNetworkSession (0x0x7f64e4e84270) 0 + vptr=((& QNetworkSession::_ZTV15QNetworkSession) + 16u) + QObject (0x0x7f64e4eee000) 0 + primary-for QNetworkSession (0x0x7f64e4e84270) + +Class QTcpServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpServer::QPrivateSignal (0x0x7f64e4eee600) 0 empty + +Vtable for QTcpServer +QTcpServer::_ZTV10QTcpServer: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpServer) +16 (int (*)(...))QTcpServer::metaObject +24 (int (*)(...))QTcpServer::qt_metacast +32 (int (*)(...))QTcpServer::qt_metacall +40 (int (*)(...))QTcpServer::~QTcpServer +48 (int (*)(...))QTcpServer::~QTcpServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTcpServer::hasPendingConnections +120 (int (*)(...))QTcpServer::nextPendingConnection +128 (int (*)(...))QTcpServer::incomingConnection + +Class QTcpServer + size=16 align=8 + base size=16 base align=8 +QTcpServer (0x0x7f64e4e843a8) 0 + vptr=((& QTcpServer::_ZTV10QTcpServer) + 16u) + QObject (0x0x7f64e4eee5a0) 0 + primary-for QTcpServer (0x0x7f64e4e843a8) + +Class QSslCertificateExtension + size=8 align=8 + base size=8 base align=8 +QSslCertificateExtension (0x0x7f64e4eee660) 0 + +Class QSslCipher + size=8 align=8 + base size=8 base align=8 +QSslCipher (0x0x7f64e4eee960) 0 + +Class QSslDiffieHellmanParameters + size=8 align=8 + base size=8 base align=8 +QSslDiffieHellmanParameters (0x0x7f64e4b8b180) 0 + +Class QSslEllipticCurve + size=4 align=4 + base size=4 base align=4 +QSslEllipticCurve (0x0x7f64e4bf9c60) 0 + +Class QSslKey + size=8 align=8 + base size=8 base align=8 +QSslKey (0x0x7f64e4c323c0) 0 + +Class QUdpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUdpSocket::QPrivateSignal (0x0x7f64e4c32720) 0 empty + +Vtable for QUdpSocket +QUdpSocket::_ZTV10QUdpSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUdpSocket) +16 (int (*)(...))QUdpSocket::metaObject +24 (int (*)(...))QUdpSocket::qt_metacast +32 (int (*)(...))QUdpSocket::qt_metacall +40 (int (*)(...))QUdpSocket::~QUdpSocket +48 (int (*)(...))QUdpSocket::~QUdpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QUdpSocket + size=16 align=8 + base size=16 base align=8 +QUdpSocket (0x0x7f64e4c19958) 0 + vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16u) + QAbstractSocket (0x0x7f64e4c199c0) 0 + primary-for QUdpSocket (0x0x7f64e4c19958) + QIODevice (0x0x7f64e4c19a28) 0 + primary-for QAbstractSocket (0x0x7f64e4c199c0) + QObject (0x0x7f64e4c326c0) 0 + primary-for QIODevice (0x0x7f64e4c19a28) + +Class QJSValue + size=8 align=8 + base size=8 base align=8 +QJSValue (0x0x7f64e4c32780) 0 + +Class QQmlDebuggingEnabler + size=1 align=1 + base size=0 base align=1 +QQmlDebuggingEnabler (0x0x7f64e4c32a20) 0 empty + +Class QJSEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QJSEngine::QPrivateSignal (0x0x7f64e4c32ae0) 0 empty + +Vtable for QJSEngine +QJSEngine::_ZTV9QJSEngine: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QJSEngine) +16 (int (*)(...))QJSEngine::metaObject +24 (int (*)(...))QJSEngine::qt_metacast +32 (int (*)(...))QJSEngine::qt_metacall +40 (int (*)(...))QJSEngine::~QJSEngine +48 (int (*)(...))QJSEngine::~QJSEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QJSEngine + size=24 align=8 + base size=24 base align=8 +QJSEngine (0x0x7f64e4c19b60) 0 + vptr=((& QJSEngine::_ZTV9QJSEngine) + 16u) + QObject (0x0x7f64e4c32a80) 0 + primary-for QJSEngine (0x0x7f64e4c19b60) + +Class QJSValueIterator + size=8 align=8 + base size=8 base align=8 +QJSValueIterator (0x0x7f64e4c32cc0) 0 + +Class QQmlPrivate::RegisterType + size=128 align=8 + base size=124 base align=8 +QQmlPrivate::RegisterType (0x0x7f64e49311e0) 0 + +Class QQmlPrivate::RegisterInterface + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::RegisterInterface (0x0x7f64e4931240) 0 + +Class QQmlPrivate::RegisterAutoParent + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterAutoParent (0x0x7f64e49312a0) 0 + +Class QQmlPrivate::RegisterSingletonType + size=64 align=8 + base size=64 base align=8 +QQmlPrivate::RegisterSingletonType (0x0x7f64e4931300) 0 + +Class QQmlPrivate::RegisterCompositeType + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::RegisterCompositeType (0x0x7f64e4931360) 0 + +Class QQmlPrivate::RegisterCompositeSingletonType + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::RegisterCompositeSingletonType (0x0x7f64e49313c0) 0 + +Class QQmlPrivate::CachedQmlUnit + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::CachedQmlUnit (0x0x7f64e4931420) 0 + +Class QQmlPrivate::RegisterQmlUnitCacheHook + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterQmlUnitCacheHook (0x0x7f64e4931480) 0 + +Vtable for QQmlParserStatus +QQmlParserStatus::_ZTV16QQmlParserStatus: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlParserStatus) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlParserStatus + size=16 align=8 + base size=16 base align=8 +QQmlParserStatus (0x0x7f64e49314e0) 0 + vptr=((& QQmlParserStatus::_ZTV16QQmlParserStatus) + 16u) + +Vtable for QQmlPropertyValueSource +QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQmlPropertyValueSource) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlPropertyValueSource + size=8 align=8 + base size=8 base align=8 +QQmlPropertyValueSource (0x0x7f64e49315a0) 0 nearly-empty + vptr=((& QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource) + 16u) + +Class QQmlListReference + size=8 align=8 + base size=8 base align=8 +QQmlListReference (0x0x7f64e49316c0) 0 + +Vtable for QQmlAbstractUrlInterceptor +QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QQmlAbstractUrlInterceptor) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlAbstractUrlInterceptor + size=8 align=8 + base size=8 base align=8 +QQmlAbstractUrlInterceptor (0x0x7f64e4931d20) 0 nearly-empty + vptr=((& QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor) + 16u) + +Class QQmlError + size=8 align=8 + base size=8 base align=8 +QQmlError (0x0x7f64e4931d80) 0 + +Vtable for QQmlImageProviderBase +QQmlImageProviderBase::_ZTV21QQmlImageProviderBase: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlImageProviderBase) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlImageProviderBase + size=8 align=8 + base size=8 base align=8 +QQmlImageProviderBase (0x0x7f64e4a4a060) 0 nearly-empty + vptr=((& QQmlImageProviderBase::_ZTV21QQmlImageProviderBase) + 16u) + +Class QQmlEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngine::QPrivateSignal (0x0x7f64e4a4a2a0) 0 empty + +Vtable for QQmlEngine +QQmlEngine::_ZTV10QQmlEngine: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQmlEngine) +16 (int (*)(...))QQmlEngine::metaObject +24 (int (*)(...))QQmlEngine::qt_metacast +32 (int (*)(...))QQmlEngine::qt_metacall +40 (int (*)(...))QQmlEngine::~QQmlEngine +48 (int (*)(...))QQmlEngine::~QQmlEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlEngine + size=24 align=8 + base size=24 base align=8 +QQmlEngine (0x0x7f64e4a4c1a0) 0 + vptr=((& QQmlEngine::_ZTV10QQmlEngine) + 16u) + QJSEngine (0x0x7f64e4a4c208) 0 + primary-for QQmlEngine (0x0x7f64e4a4c1a0) + QObject (0x0x7f64e4a4a240) 0 + primary-for QJSEngine (0x0x7f64e4a4c208) + +Class QQmlApplicationEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlApplicationEngine::QPrivateSignal (0x0x7f64e4a4a360) 0 empty + +Vtable for QQmlApplicationEngine +QQmlApplicationEngine::_ZTV21QQmlApplicationEngine: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlApplicationEngine) +16 (int (*)(...))QQmlApplicationEngine::metaObject +24 (int (*)(...))QQmlApplicationEngine::qt_metacast +32 (int (*)(...))QQmlApplicationEngine::qt_metacall +40 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +48 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlApplicationEngine + size=24 align=8 + base size=24 base align=8 +QQmlApplicationEngine (0x0x7f64e4a4c270) 0 + vptr=((& QQmlApplicationEngine::_ZTV21QQmlApplicationEngine) + 16u) + QQmlEngine (0x0x7f64e4a4c2d8) 0 + primary-for QQmlApplicationEngine (0x0x7f64e4a4c270) + QJSEngine (0x0x7f64e4a4c340) 0 + primary-for QQmlEngine (0x0x7f64e4a4c2d8) + QObject (0x0x7f64e4a4a300) 0 + primary-for QJSEngine (0x0x7f64e4a4c340) + +Class QQmlComponent::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlComponent::QPrivateSignal (0x0x7f64e4a4a420) 0 empty + +Vtable for QQmlComponent +QQmlComponent::_ZTV13QQmlComponent: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlComponent) +16 (int (*)(...))QQmlComponent::metaObject +24 (int (*)(...))QQmlComponent::qt_metacast +32 (int (*)(...))QQmlComponent::qt_metacall +40 (int (*)(...))QQmlComponent::~QQmlComponent +48 (int (*)(...))QQmlComponent::~QQmlComponent +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlComponent::create +120 (int (*)(...))QQmlComponent::beginCreate +128 (int (*)(...))QQmlComponent::completeCreate + +Class QQmlComponent + size=16 align=8 + base size=16 base align=8 +QQmlComponent (0x0x7f64e4a4c3a8) 0 + vptr=((& QQmlComponent::_ZTV13QQmlComponent) + 16u) + QObject (0x0x7f64e4a4a3c0) 0 + primary-for QQmlComponent (0x0x7f64e4a4c3a8) + +Class QQmlContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlContext::QPrivateSignal (0x0x7f64e4a4ac60) 0 empty + +Class QQmlContext::PropertyPair + size=24 align=8 + base size=24 base align=8 +QQmlContext::PropertyPair (0x0x7f64e4a4acc0) 0 + +Vtable for QQmlContext +QQmlContext::_ZTV11QQmlContext: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QQmlContext) +16 (int (*)(...))QQmlContext::metaObject +24 (int (*)(...))QQmlContext::qt_metacast +32 (int (*)(...))QQmlContext::qt_metacall +40 (int (*)(...))QQmlContext::~QQmlContext +48 (int (*)(...))QQmlContext::~QQmlContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlContext + size=16 align=8 + base size=16 base align=8 +QQmlContext (0x0x7f64e4a4c8f0) 0 + vptr=((& QQmlContext::_ZTV11QQmlContext) + 16u) + QObject (0x0x7f64e4a4ac00) 0 + primary-for QQmlContext (0x0x7f64e4a4c8f0) + +Class QQmlScriptString + size=8 align=8 + base size=8 base align=8 +QQmlScriptString (0x0x7f64e4a4ae40) 0 + +Class QQmlExpression::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExpression::QPrivateSignal (0x0x7f64e472a0c0) 0 empty + +Vtable for QQmlExpression +QQmlExpression::_ZTV14QQmlExpression: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QQmlExpression) +16 (int (*)(...))QQmlExpression::metaObject +24 (int (*)(...))QQmlExpression::qt_metacast +32 (int (*)(...))QQmlExpression::qt_metacall +40 (int (*)(...))QQmlExpression::~QQmlExpression +48 (int (*)(...))QQmlExpression::~QQmlExpression +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlExpression + size=16 align=8 + base size=16 base align=8 +QQmlExpression (0x0x7f64e4a4c958) 0 + vptr=((& QQmlExpression::_ZTV14QQmlExpression) + 16u) + QObject (0x0x7f64e472a060) 0 + primary-for QQmlExpression (0x0x7f64e4a4c958) + +Vtable for QQmlTypesExtensionInterface +QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QQmlTypesExtensionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlTypesExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlTypesExtensionInterface (0x0x7f64e472a120) 0 nearly-empty + vptr=((& QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface) + 16u) + +Vtable for QQmlExtensionInterface +QQmlExtensionInterface::_ZTV22QQmlExtensionInterface: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QQmlExtensionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlExtensionInterface (0x0x7f64e4a4c9c0) 0 nearly-empty + vptr=((& QQmlExtensionInterface::_ZTV22QQmlExtensionInterface) + 16u) + QQmlTypesExtensionInterface (0x0x7f64e472a180) 0 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f64e4a4c9c0) + +Class QQmlExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExtensionPlugin::QPrivateSignal (0x0x7f64e472a360) 0 empty + +Vtable for QQmlExtensionPlugin +QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin: 22u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +16 (int (*)(...))QQmlExtensionPlugin::metaObject +24 (int (*)(...))QQmlExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlExtensionPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQmlExtensionPlugin::initializeEngine +128 (int (*)(...))-16 +136 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +144 0u +152 0u +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QQmlExtensionPlugin::_ZThn16_N19QQmlExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlExtensionPlugin (0x0x7f64e4754150) 0 + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 16u) + QObject (0x0x7f64e472a2a0) 0 + primary-for QQmlExtensionPlugin (0x0x7f64e4754150) + QQmlExtensionInterface (0x0x7f64e4a4ca28) 16 nearly-empty + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 144u) + QQmlTypesExtensionInterface (0x0x7f64e472a300) 16 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f64e4a4ca28) + +Class QQmlFile + size=8 align=8 + base size=8 base align=8 +QQmlFile (0x0x7f64e472a3c0) 0 + +Class QQmlFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlFileSelector::QPrivateSignal (0x0x7f64e472a480) 0 empty + +Vtable for QQmlFileSelector +QQmlFileSelector::_ZTV16QQmlFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlFileSelector) +16 (int (*)(...))QQmlFileSelector::metaObject +24 (int (*)(...))QQmlFileSelector::qt_metacast +32 (int (*)(...))QQmlFileSelector::qt_metacall +40 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +48 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlFileSelector + size=16 align=8 + base size=16 base align=8 +QQmlFileSelector (0x0x7f64e4a4caf8) 0 + vptr=((& QQmlFileSelector::_ZTV16QQmlFileSelector) + 16u) + QObject (0x0x7f64e472a420) 0 + primary-for QQmlFileSelector (0x0x7f64e4a4caf8) + +Vtable for QQmlIncubator +QQmlIncubator::_ZTV13QQmlIncubator: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlIncubator) +16 (int (*)(...))QQmlIncubator::~QQmlIncubator +24 (int (*)(...))QQmlIncubator::~QQmlIncubator +32 (int (*)(...))QQmlIncubator::statusChanged +40 (int (*)(...))QQmlIncubator::setInitialState + +Class QQmlIncubator + size=16 align=8 + base size=16 base align=8 +QQmlIncubator (0x0x7f64e472a4e0) 0 + vptr=((& QQmlIncubator::_ZTV13QQmlIncubator) + 16u) + +Vtable for QQmlIncubationController +QQmlIncubationController::_ZTV24QQmlIncubationController: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQmlIncubationController) +16 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +24 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +32 (int (*)(...))QQmlIncubationController::incubatingObjectCountChanged + +Class QQmlIncubationController + size=16 align=8 + base size=16 base align=8 +QQmlIncubationController (0x0x7f64e472a540) 0 + vptr=((& QQmlIncubationController::_ZTV24QQmlIncubationController) + 16u) + +Class QQmlInfo + size=16 align=8 + base size=16 base align=8 +QQmlInfo (0x0x7f64e4a4cb60) 0 + QDebug (0x0x7f64e472a5a0) 0 + +Vtable for QQmlNetworkAccessManagerFactory +QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI31QQmlNetworkAccessManagerFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlNetworkAccessManagerFactory + size=8 align=8 + base size=8 base align=8 +QQmlNetworkAccessManagerFactory (0x0x7f64e480b480) 0 nearly-empty + vptr=((& QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory) + 16u) + +Class QQmlProperty + size=8 align=8 + base size=8 base align=8 +QQmlProperty (0x0x7f64e480b4e0) 0 + +Class QQmlPropertyMap::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlPropertyMap::QPrivateSignal (0x0x7f64e4848060) 0 empty + +Vtable for QQmlPropertyMap +QQmlPropertyMap::_ZTV15QQmlPropertyMap: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQmlPropertyMap) +16 (int (*)(...))QQmlPropertyMap::metaObject +24 (int (*)(...))QQmlPropertyMap::qt_metacast +32 (int (*)(...))QQmlPropertyMap::qt_metacall +40 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +48 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlPropertyMap::updateValue + +Class QQmlPropertyMap + size=16 align=8 + base size=16 base align=8 +QQmlPropertyMap (0x0x7f64e48393a8) 0 + vptr=((& QQmlPropertyMap::_ZTV15QQmlPropertyMap) + 16u) + QObject (0x0x7f64e4848000) 0 + primary-for QQmlPropertyMap (0x0x7f64e48393a8) + +Class QQuickTransform::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTransform::QPrivateSignal (0x0x7f64e4848120) 0 empty + +Vtable for QQuickTransform +QQuickTransform::_ZTV15QQuickTransform: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQuickTransform) +16 (int (*)(...))QQuickTransform::metaObject +24 (int (*)(...))QQuickTransform::qt_metacast +32 (int (*)(...))QQuickTransform::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QQuickTransform + size=16 align=8 + base size=16 base align=8 +QQuickTransform (0x0x7f64e4839410) 0 + vptr=((& QQuickTransform::_ZTV15QQuickTransform) + 16u) + QObject (0x0x7f64e48480c0) 0 + primary-for QQuickTransform (0x0x7f64e4839410) + +Class QQuickItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItem::QPrivateSignal (0x0x7f64e4848240) 0 empty + +Class QQuickItem::ItemChangeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::ItemChangeData (0x0x7f64e48482a0) 0 + +Class QQuickItem::UpdatePaintNodeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::UpdatePaintNodeData (0x0x7f64e4848300) 0 + +Vtable for QQuickItem +QQuickItem::_ZTV10QQuickItem: 55u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickItem) +16 (int (*)(...))QQuickItem::metaObject +24 (int (*)(...))QQuickItem::qt_metacast +32 (int (*)(...))QQuickItem::qt_metacall +40 (int (*)(...))QQuickItem::~QQuickItem +48 (int (*)(...))QQuickItem::~QQuickItem +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickItem::isTextureProvider +152 (int (*)(...))QQuickItem::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickItem::geometryChanged +368 (int (*)(...))QQuickItem::updatePaintNode +376 (int (*)(...))QQuickItem::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))-16 +400 (int (*)(...))(& _ZTI10QQuickItem) +408 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD1Ev +416 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD0Ev +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickItem + size=32 align=8 + base size=32 base align=8 +QQuickItem (0x0x7f64e4842cb0) 0 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 16u) + QObject (0x0x7f64e4848180) 0 + primary-for QQuickItem (0x0x7f64e4842cb0) + QQmlParserStatus (0x0x7f64e48481e0) 16 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 408u) + +Class QQuickFramebufferObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickFramebufferObject::QPrivateSignal (0x0x7f64e4848ae0) 0 empty + +Vtable for QQuickFramebufferObject::Renderer +QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN23QQuickFramebufferObject8RendererE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QQuickFramebufferObject::Renderer::createFramebufferObject +48 (int (*)(...))QQuickFramebufferObject::Renderer::synchronize + +Class QQuickFramebufferObject::Renderer + size=16 align=8 + base size=16 base align=8 +QQuickFramebufferObject::Renderer (0x0x7f64e4848b40) 0 + vptr=((& QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE) + 16u) + +Vtable for QQuickFramebufferObject +QQuickFramebufferObject::_ZTV23QQuickFramebufferObject: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +16 (int (*)(...))QQuickFramebufferObject::metaObject +24 (int (*)(...))QQuickFramebufferObject::qt_metacast +32 (int (*)(...))QQuickFramebufferObject::qt_metacall +40 0u +48 0u +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickFramebufferObject::isTextureProvider +152 (int (*)(...))QQuickFramebufferObject::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickFramebufferObject::geometryChanged +368 (int (*)(...))QQuickFramebufferObject::updatePaintNode +376 (int (*)(...))QQuickFramebufferObject::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))-16 +408 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +416 0u +424 0u +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickFramebufferObject + size=32 align=8 + base size=32 base align=8 +QQuickFramebufferObject (0x0x7f64e4839548) 0 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 16u) + QQuickItem (0x0x7f64e49134d0) 0 + primary-for QQuickFramebufferObject (0x0x7f64e4839548) + QObject (0x0x7f64e4848a20) 0 + primary-for QQuickItem (0x0x7f64e49134d0) + QQmlParserStatus (0x0x7f64e4848a80) 16 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 416u) + +Class QQuickTextureFactory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextureFactory::QPrivateSignal (0x0x7f64e4848c00) 0 empty + +Vtable for QQuickTextureFactory +QQuickTextureFactory::_ZTV20QQuickTextureFactory: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickTextureFactory) +16 (int (*)(...))QQuickTextureFactory::metaObject +24 (int (*)(...))QQuickTextureFactory::qt_metacast +32 (int (*)(...))QQuickTextureFactory::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))QQuickTextureFactory::image + +Class QQuickTextureFactory + size=16 align=8 + base size=16 base align=8 +QQuickTextureFactory (0x0x7f64e48395b0) 0 + vptr=((& QQuickTextureFactory::_ZTV20QQuickTextureFactory) + 16u) + QObject (0x0x7f64e4848ba0) 0 + primary-for QQuickTextureFactory (0x0x7f64e48395b0) + +Class QQuickImageResponse::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickImageResponse::QPrivateSignal (0x0x7f64e4848cc0) 0 empty + +Vtable for QQuickImageResponse +QQuickImageResponse::_ZTV19QQuickImageResponse: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageResponse) +16 (int (*)(...))QQuickImageResponse::metaObject +24 (int (*)(...))QQuickImageResponse::qt_metacast +32 (int (*)(...))QQuickImageResponse::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQuickImageResponse::errorString +128 (int (*)(...))QQuickImageResponse::cancel + +Class QQuickImageResponse + size=16 align=8 + base size=16 base align=8 +QQuickImageResponse (0x0x7f64e4839618) 0 + vptr=((& QQuickImageResponse::_ZTV19QQuickImageResponse) + 16u) + QObject (0x0x7f64e4848c60) 0 + primary-for QQuickImageResponse (0x0x7f64e4839618) + +Vtable for QQuickImageProvider +QQuickImageProvider::_ZTV19QQuickImageProvider: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageProvider) +16 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +24 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +32 (int (*)(...))QQuickImageProvider::imageType +40 (int (*)(...))QQuickImageProvider::flags +48 (int (*)(...))QQuickImageProvider::requestImage +56 (int (*)(...))QQuickImageProvider::requestPixmap +64 (int (*)(...))QQuickImageProvider::requestTexture + +Class QQuickImageProvider + size=16 align=8 + base size=16 base align=8 +QQuickImageProvider (0x0x7f64e4839680) 0 + vptr=((& QQuickImageProvider::_ZTV19QQuickImageProvider) + 16u) + QQmlImageProviderBase (0x0x7f64e4848d20) 0 nearly-empty + primary-for QQuickImageProvider (0x0x7f64e4839680) + +Vtable for QQuickAsyncImageProvider +QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQuickAsyncImageProvider) +16 0u +24 0u +32 (int (*)(...))QQuickImageProvider::imageType +40 (int (*)(...))QQuickImageProvider::flags +48 (int (*)(...))QQuickImageProvider::requestImage +56 (int (*)(...))QQuickImageProvider::requestPixmap +64 (int (*)(...))QQuickImageProvider::requestTexture +72 (int (*)(...))__cxa_pure_virtual + +Class QQuickAsyncImageProvider + size=24 align=8 + base size=24 base align=8 +QQuickAsyncImageProvider (0x0x7f64e48396e8) 0 + vptr=((& QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider) + 16u) + QQuickImageProvider (0x0x7f64e4839750) 0 + primary-for QQuickAsyncImageProvider (0x0x7f64e48396e8) + QQmlImageProviderBase (0x0x7f64e4848d80) 0 nearly-empty + primary-for QQuickImageProvider (0x0x7f64e4839750) + +Class QQuickItemGrabResult::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItemGrabResult::QPrivateSignal (0x0x7f64e4848e40) 0 empty + +Vtable for QQuickItemGrabResult +QQuickItemGrabResult::_ZTV20QQuickItemGrabResult: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickItemGrabResult) +16 (int (*)(...))QQuickItemGrabResult::metaObject +24 (int (*)(...))QQuickItemGrabResult::qt_metacast +32 (int (*)(...))QQuickItemGrabResult::qt_metacall +40 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +48 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +56 (int (*)(...))QQuickItemGrabResult::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickItemGrabResult + size=16 align=8 + base size=16 base align=8 +QQuickItemGrabResult (0x0x7f64e48397b8) 0 + vptr=((& QQuickItemGrabResult::_ZTV20QQuickItemGrabResult) + 16u) + QObject (0x0x7f64e4848de0) 0 + primary-for QQuickItemGrabResult (0x0x7f64e48397b8) + +Class QQuickPaintedItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickPaintedItem::QPrivateSignal (0x0x7f64e4848f60) 0 empty + +Vtable for QQuickPaintedItem +QQuickPaintedItem::_ZTV17QQuickPaintedItem: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QQuickPaintedItem) +16 (int (*)(...))QQuickPaintedItem::metaObject +24 (int (*)(...))QQuickPaintedItem::qt_metacast +32 (int (*)(...))QQuickPaintedItem::qt_metacall +40 0u +48 0u +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickPaintedItem::isTextureProvider +152 (int (*)(...))QQuickPaintedItem::textureProvider +160 (int (*)(...))QQuickPaintedItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickItem::geometryChanged +368 (int (*)(...))QQuickPaintedItem::updatePaintNode +376 (int (*)(...))QQuickPaintedItem::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))-16 +408 (int (*)(...))(& _ZTI17QQuickPaintedItem) +416 0u +424 0u +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickPaintedItem + size=32 align=8 + base size=32 base align=8 +QQuickPaintedItem (0x0x7f64e4839820) 0 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 16u) + QQuickItem (0x0x7f64e455a2a0) 0 + primary-for QQuickPaintedItem (0x0x7f64e4839820) + QObject (0x0x7f64e4848ea0) 0 + primary-for QQuickItem (0x0x7f64e455a2a0) + QQmlParserStatus (0x0x7f64e4848f00) 16 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 416u) + +Class QQuickRenderControl::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickRenderControl::QPrivateSignal (0x0x7f64e45861e0) 0 empty + +Vtable for QQuickRenderControl +QQuickRenderControl::_ZTV19QQuickRenderControl: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickRenderControl) +16 (int (*)(...))QQuickRenderControl::metaObject +24 (int (*)(...))QQuickRenderControl::qt_metacast +32 (int (*)(...))QQuickRenderControl::qt_metacall +40 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +48 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickRenderControl::renderWindow + +Class QQuickRenderControl + size=16 align=8 + base size=16 base align=8 +QQuickRenderControl (0x0x7f64e48399c0) 0 + vptr=((& QQuickRenderControl::_ZTV19QQuickRenderControl) + 16u) + QObject (0x0x7f64e4586180) 0 + primary-for QQuickRenderControl (0x0x7f64e48399c0) + +Class QQuickTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextDocument::QPrivateSignal (0x0x7f64e45862a0) 0 empty + +Vtable for QQuickTextDocument +QQuickTextDocument::_ZTV18QQuickTextDocument: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QQuickTextDocument) +16 (int (*)(...))QQuickTextDocument::metaObject +24 (int (*)(...))QQuickTextDocument::qt_metacast +32 (int (*)(...))QQuickTextDocument::qt_metacall +40 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +48 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickTextDocument + size=16 align=8 + base size=16 base align=8 +QQuickTextDocument (0x0x7f64e4839a28) 0 + vptr=((& QQuickTextDocument::_ZTV18QQuickTextDocument) + 16u) + QObject (0x0x7f64e4586240) 0 + primary-for QQuickTextDocument (0x0x7f64e4839a28) + +Class QSGGeometry::Attribute + size=16 align=4 + base size=16 base align=4 +QSGGeometry::Attribute (0x0x7f64e4586600) 0 + +Class QSGGeometry::AttributeSet + size=16 align=8 + base size=16 base align=8 +QSGGeometry::AttributeSet (0x0x7f64e4586660) 0 + +Class QSGGeometry::Point2D + size=8 align=4 + base size=8 base align=4 +QSGGeometry::Point2D (0x0x7f64e45866c0) 0 + +Class QSGGeometry::TexturedPoint2D + size=16 align=4 + base size=16 base align=4 +QSGGeometry::TexturedPoint2D (0x0x7f64e4586720) 0 + +Class QSGGeometry::ColoredPoint2D + size=12 align=4 + base size=12 base align=4 +QSGGeometry::ColoredPoint2D (0x0x7f64e4586780) 0 + +Vtable for QSGGeometry +QSGGeometry::_ZTV11QSGGeometry: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGGeometry) +16 (int (*)(...))QSGGeometry::~QSGGeometry +24 (int (*)(...))QSGGeometry::~QSGGeometry + +Class QSGGeometry + size=128 align=8 + base size=128 base align=8 +QSGGeometry (0x0x7f64e45865a0) 0 + vptr=((& QSGGeometry::_ZTV11QSGGeometry) + 16u) + +Vtable for QSGNode +QSGNode::_ZTV7QSGNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QSGNode) +16 (int (*)(...))QSGNode::~QSGNode +24 (int (*)(...))QSGNode::~QSGNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGNode + size=80 align=8 + base size=80 base align=8 +QSGNode (0x0x7f64e4586c60) 0 + vptr=((& QSGNode::_ZTV7QSGNode) + 16u) + +Vtable for QSGBasicGeometryNode +QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGBasicGeometryNode) +16 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +24 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGBasicGeometryNode + size=112 align=8 + base size=112 base align=8 +QSGBasicGeometryNode (0x0x7f64e4692138) 0 + vptr=((& QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode) + 16u) + QSGNode (0x0x7f64e46b7060) 0 + primary-for QSGBasicGeometryNode (0x0x7f64e4692138) + +Vtable for QSGGeometryNode +QSGGeometryNode::_ZTV15QSGGeometryNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSGGeometryNode) +16 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +24 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGGeometryNode + size=144 align=8 + base size=144 base align=8 +QSGGeometryNode (0x0x7f64e46921a0) 0 + vptr=((& QSGGeometryNode::_ZTV15QSGGeometryNode) + 16u) + QSGBasicGeometryNode (0x0x7f64e4692208) 0 + primary-for QSGGeometryNode (0x0x7f64e46921a0) + QSGNode (0x0x7f64e46b70c0) 0 + primary-for QSGBasicGeometryNode (0x0x7f64e4692208) + +Vtable for QSGClipNode +QSGClipNode::_ZTV11QSGClipNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGClipNode) +16 (int (*)(...))QSGClipNode::~QSGClipNode +24 (int (*)(...))QSGClipNode::~QSGClipNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGClipNode + size=152 align=8 + base size=152 base align=8 +QSGClipNode (0x0x7f64e4692270) 0 + vptr=((& QSGClipNode::_ZTV11QSGClipNode) + 16u) + QSGBasicGeometryNode (0x0x7f64e46922d8) 0 + primary-for QSGClipNode (0x0x7f64e4692270) + QSGNode (0x0x7f64e46b7120) 0 + primary-for QSGBasicGeometryNode (0x0x7f64e46922d8) + +Vtable for QSGTransformNode +QSGTransformNode::_ZTV16QSGTransformNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGTransformNode) +16 (int (*)(...))QSGTransformNode::~QSGTransformNode +24 (int (*)(...))QSGTransformNode::~QSGTransformNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGTransformNode + size=216 align=8 + base size=216 base align=8 +QSGTransformNode (0x0x7f64e4692340) 0 + vptr=((& QSGTransformNode::_ZTV16QSGTransformNode) + 16u) + QSGNode (0x0x7f64e46b7180) 0 + primary-for QSGTransformNode (0x0x7f64e4692340) + +Vtable for QSGRootNode +QSGRootNode::_ZTV11QSGRootNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGRootNode) +16 (int (*)(...))QSGRootNode::~QSGRootNode +24 (int (*)(...))QSGRootNode::~QSGRootNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGRootNode + size=88 align=8 + base size=88 base align=8 +QSGRootNode (0x0x7f64e46923a8) 0 + vptr=((& QSGRootNode::_ZTV11QSGRootNode) + 16u) + QSGNode (0x0x7f64e46b71e0) 0 + primary-for QSGRootNode (0x0x7f64e46923a8) + +Vtable for QSGOpacityNode +QSGOpacityNode::_ZTV14QSGOpacityNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGOpacityNode) +16 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +24 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +32 (int (*)(...))QSGOpacityNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGOpacityNode + size=96 align=8 + base size=96 base align=8 +QSGOpacityNode (0x0x7f64e4692548) 0 + vptr=((& QSGOpacityNode::_ZTV14QSGOpacityNode) + 16u) + QSGNode (0x0x7f64e46b7360) 0 + primary-for QSGOpacityNode (0x0x7f64e4692548) + +Vtable for QSGNodeVisitor +QSGNodeVisitor::_ZTV14QSGNodeVisitor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGNodeVisitor) +16 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +24 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +32 (int (*)(...))QSGNodeVisitor::enterTransformNode +40 (int (*)(...))QSGNodeVisitor::leaveTransformNode +48 (int (*)(...))QSGNodeVisitor::enterClipNode +56 (int (*)(...))QSGNodeVisitor::leaveClipNode +64 (int (*)(...))QSGNodeVisitor::enterGeometryNode +72 (int (*)(...))QSGNodeVisitor::leaveGeometryNode +80 (int (*)(...))QSGNodeVisitor::enterOpacityNode +88 (int (*)(...))QSGNodeVisitor::leaveOpacityNode +96 (int (*)(...))QSGNodeVisitor::visitNode +104 (int (*)(...))QSGNodeVisitor::visitChildren + +Class QSGNodeVisitor + size=8 align=8 + base size=8 base align=8 +QSGNodeVisitor (0x0x7f64e46b73c0) 0 nearly-empty + vptr=((& QSGNodeVisitor::_ZTV14QSGNodeVisitor) + 16u) + +Vtable for QSGRendererInterface +QSGRendererInterface::_ZTV20QSGRendererInterface: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGRendererInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QSGRendererInterface::getResource +48 (int (*)(...))QSGRendererInterface::getResource +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRendererInterface + size=8 align=8 + base size=8 base align=8 +QSGRendererInterface (0x0x7f64e46b7420) 0 nearly-empty + vptr=((& QSGRendererInterface::_ZTV20QSGRendererInterface) + 16u) + +Class QQuickWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickWindow::QPrivateSignal (0x0x7f64e46b7840) 0 empty + +Vtable for QQuickWindow +QQuickWindow::_ZTV12QQuickWindow: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QQuickWindow) +16 (int (*)(...))QQuickWindow::metaObject +24 (int (*)(...))QQuickWindow::qt_metacast +32 (int (*)(...))QQuickWindow::qt_metacall +40 (int (*)(...))QQuickWindow::~QQuickWindow +48 (int (*)(...))QQuickWindow::~QQuickWindow +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QQuickWindow::focusInEvent +184 (int (*)(...))QQuickWindow::focusOutEvent +192 (int (*)(...))QQuickWindow::showEvent +200 (int (*)(...))QQuickWindow::hideEvent +208 (int (*)(...))QQuickWindow::keyPressEvent +216 (int (*)(...))QQuickWindow::keyReleaseEvent +224 (int (*)(...))QQuickWindow::mousePressEvent +232 (int (*)(...))QQuickWindow::mouseReleaseEvent +240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +248 (int (*)(...))QQuickWindow::mouseMoveEvent +256 (int (*)(...))QQuickWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI12QQuickWindow) +312 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD1Ev +320 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickWindow + size=40 align=8 + base size=40 base align=8 +QQuickWindow (0x0x7f64e4692750) 0 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 16u) + QWindow (0x0x7f64e43a7930) 0 + primary-for QQuickWindow (0x0x7f64e4692750) + QObject (0x0x7f64e46b7780) 0 + primary-for QWindow (0x0x7f64e43a7930) + QSurface (0x0x7f64e46b77e0) 16 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 312u) + +Class QQuickView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickView::QPrivateSignal (0x0x7f64e46b7c00) 0 empty + +Vtable for QQuickView +QQuickView::_ZTV10QQuickView: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickView) +16 (int (*)(...))QQuickView::metaObject +24 (int (*)(...))QQuickView::qt_metacast +32 (int (*)(...))QQuickView::qt_metacall +40 (int (*)(...))QQuickView::~QQuickView +48 (int (*)(...))QQuickView::~QQuickView +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QQuickView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickView::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QQuickWindow::focusInEvent +184 (int (*)(...))QQuickWindow::focusOutEvent +192 (int (*)(...))QQuickWindow::showEvent +200 (int (*)(...))QQuickWindow::hideEvent +208 (int (*)(...))QQuickView::keyPressEvent +216 (int (*)(...))QQuickView::keyReleaseEvent +224 (int (*)(...))QQuickView::mousePressEvent +232 (int (*)(...))QQuickView::mouseReleaseEvent +240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +248 (int (*)(...))QQuickView::mouseMoveEvent +256 (int (*)(...))QQuickWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI10QQuickView) +312 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD1Ev +320 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickView + size=40 align=8 + base size=40 base align=8 +QQuickView (0x0x7f64e4692888) 0 + vptr=((& QQuickView::_ZTV10QQuickView) + 16u) + QQuickWindow (0x0x7f64e46928f0) 0 + primary-for QQuickView (0x0x7f64e4692888) + QWindow (0x0x7f64e43e1bd0) 0 + primary-for QQuickWindow (0x0x7f64e46928f0) + QObject (0x0x7f64e46b7b40) 0 + primary-for QWindow (0x0x7f64e43e1bd0) + QSurface (0x0x7f64e46b7ba0) 16 + vptr=((& QQuickView::_ZTV10QQuickView) + 312u) + +Class QSGAbstractRenderer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGAbstractRenderer::QPrivateSignal (0x0x7f64e46b7cc0) 0 empty + +Vtable for QSGAbstractRenderer +QSGAbstractRenderer::_ZTV19QSGAbstractRenderer: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QSGAbstractRenderer) +16 (int (*)(...))QSGAbstractRenderer::metaObject +24 (int (*)(...))QSGAbstractRenderer::qt_metacast +32 (int (*)(...))QSGAbstractRenderer::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QSGAbstractRenderer + size=16 align=8 + base size=16 base align=8 +QSGAbstractRenderer (0x0x7f64e4692958) 0 + vptr=((& QSGAbstractRenderer::_ZTV19QSGAbstractRenderer) + 16u) + QObject (0x0x7f64e46b7c60) 0 + primary-for QSGAbstractRenderer (0x0x7f64e4692958) + +Class QSGEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGEngine::QPrivateSignal (0x0x7f64e46b7f00) 0 empty + +Vtable for QSGEngine +QSGEngine::_ZTV9QSGEngine: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSGEngine) +16 (int (*)(...))QSGEngine::metaObject +24 (int (*)(...))QSGEngine::qt_metacast +32 (int (*)(...))QSGEngine::qt_metacall +40 (int (*)(...))QSGEngine::~QSGEngine +48 (int (*)(...))QSGEngine::~QSGEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSGEngine + size=16 align=8 + base size=16 base align=8 +QSGEngine (0x0x7f64e4692a90) 0 + vptr=((& QSGEngine::_ZTV9QSGEngine) + 16u) + QObject (0x0x7f64e46b7ea0) 0 + primary-for QSGEngine (0x0x7f64e4692a90) + +Class QSGMaterialShader::RenderState + size=16 align=8 + base size=16 base align=8 +QSGMaterialShader::RenderState (0x0x7f64e44911e0) 0 + +Vtable for QSGMaterialShader +QSGMaterialShader::_ZTV17QSGMaterialShader: 12u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGMaterialShader) +16 0u +24 0u +32 (int (*)(...))QSGMaterialShader::activate +40 (int (*)(...))QSGMaterialShader::deactivate +48 (int (*)(...))QSGMaterialShader::updateState +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QSGMaterialShader::compile +72 (int (*)(...))QSGMaterialShader::initialize +80 (int (*)(...))QSGMaterialShader::vertexShader +88 (int (*)(...))QSGMaterialShader::fragmentShader + +Class QSGMaterialShader + size=32 align=8 + base size=32 base align=8 +QSGMaterialShader (0x0x7f64e4491180) 0 + vptr=((& QSGMaterialShader::_ZTV17QSGMaterialShader) + 16u) + +Class QSGMaterialType + size=1 align=1 + base size=0 base align=1 +QSGMaterialType (0x0x7f64e4491480) 0 empty + +Vtable for QSGMaterial +QSGMaterial::_ZTV11QSGMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGMaterial) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QSGMaterial::compare + +Class QSGMaterial + size=24 align=8 + base size=24 base align=8 +QSGMaterial (0x0x7f64e44914e0) 0 + vptr=((& QSGMaterial::_ZTV11QSGMaterial) + 16u) + +Vtable for QSGFlatColorMaterial +QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGFlatColorMaterial) +16 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +24 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +32 (int (*)(...))QSGFlatColorMaterial::type +40 (int (*)(...))QSGFlatColorMaterial::createShader +48 (int (*)(...))QSGFlatColorMaterial::compare + +Class QSGFlatColorMaterial + size=40 align=8 + base size=40 base align=8 +QSGFlatColorMaterial (0x0x7f64e4692dd0) 0 + vptr=((& QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial) + 16u) + QSGMaterial (0x0x7f64e44916c0) 0 + primary-for QSGFlatColorMaterial (0x0x7f64e4692dd0) + +Class QSGTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTexture::QPrivateSignal (0x0x7f64e4491780) 0 empty + +Vtable for QSGTexture +QSGTexture::_ZTV10QSGTexture: 22u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSGTexture) +16 (int (*)(...))QSGTexture::metaObject +24 (int (*)(...))QSGTexture::qt_metacast +32 (int (*)(...))QSGTexture::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QSGTexture::normalizedTextureSubRect +152 (int (*)(...))QSGTexture::isAtlasTexture +160 (int (*)(...))QSGTexture::removedFromAtlas +168 (int (*)(...))__cxa_pure_virtual + +Class QSGTexture + size=16 align=8 + base size=16 base align=8 +QSGTexture (0x0x7f64e4692e38) 0 + vptr=((& QSGTexture::_ZTV10QSGTexture) + 16u) + QObject (0x0x7f64e4491720) 0 + primary-for QSGTexture (0x0x7f64e4692e38) + +Class QSGDynamicTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGDynamicTexture::QPrivateSignal (0x0x7f64e4491840) 0 empty + +Vtable for QSGDynamicTexture +QSGDynamicTexture::_ZTV17QSGDynamicTexture: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGDynamicTexture) +16 (int (*)(...))QSGDynamicTexture::metaObject +24 (int (*)(...))QSGDynamicTexture::qt_metacast +32 (int (*)(...))QSGDynamicTexture::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QSGTexture::normalizedTextureSubRect +152 (int (*)(...))QSGTexture::isAtlasTexture +160 (int (*)(...))QSGTexture::removedFromAtlas +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QSGDynamicTexture + size=16 align=8 + base size=16 base align=8 +QSGDynamicTexture (0x0x7f64e4692ea0) 0 + vptr=((& QSGDynamicTexture::_ZTV17QSGDynamicTexture) + 16u) + QSGTexture (0x0x7f64e4692f08) 0 + primary-for QSGDynamicTexture (0x0x7f64e4692ea0) + QObject (0x0x7f64e44917e0) 0 + primary-for QSGTexture (0x0x7f64e4692f08) + +Vtable for QSGImageNode +QSGImageNode::_ZTV12QSGImageNode: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QSGImageNode) +16 0u +24 0u +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QSGImageNode + size=144 align=8 + base size=144 base align=8 +QSGImageNode (0x0x7f64e4692f70) 0 + vptr=((& QSGImageNode::_ZTV12QSGImageNode) + 16u) + QSGGeometryNode (0x0x7f64e4168000) 0 + primary-for QSGImageNode (0x0x7f64e4692f70) + QSGBasicGeometryNode (0x0x7f64e4168068) 0 + primary-for QSGGeometryNode (0x0x7f64e4168000) + QSGNode (0x0x7f64e44918a0) 0 + primary-for QSGBasicGeometryNode (0x0x7f64e4168068) + +Vtable for QSGNinePatchNode +QSGNinePatchNode::_ZTV16QSGNinePatchNode: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGNinePatchNode) +16 0u +24 0u +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual + +Class QSGNinePatchNode + size=144 align=8 + base size=144 base align=8 +QSGNinePatchNode (0x0x7f64e41681a0) 0 + vptr=((& QSGNinePatchNode::_ZTV16QSGNinePatchNode) + 16u) + QSGGeometryNode (0x0x7f64e4168208) 0 + primary-for QSGNinePatchNode (0x0x7f64e41681a0) + QSGBasicGeometryNode (0x0x7f64e4168270) 0 + primary-for QSGGeometryNode (0x0x7f64e4168208) + QSGNode (0x0x7f64e4491a80) 0 + primary-for QSGBasicGeometryNode (0x0x7f64e4168270) + +Vtable for QSGRectangleNode +QSGRectangleNode::_ZTV16QSGRectangleNode: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGRectangleNode) +16 0u +24 0u +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRectangleNode + size=144 align=8 + base size=144 base align=8 +QSGRectangleNode (0x0x7f64e41682d8) 0 + vptr=((& QSGRectangleNode::_ZTV16QSGRectangleNode) + 16u) + QSGGeometryNode (0x0x7f64e4168340) 0 + primary-for QSGRectangleNode (0x0x7f64e41682d8) + QSGBasicGeometryNode (0x0x7f64e41683a8) 0 + primary-for QSGGeometryNode (0x0x7f64e4168340) + QSGNode (0x0x7f64e4491ae0) 0 + primary-for QSGBasicGeometryNode (0x0x7f64e41683a8) + +Vtable for QSGRenderNode::RenderState +QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QSGRenderNode11RenderStateE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))QSGRenderNode::RenderState::get + +Class QSGRenderNode::RenderState + size=8 align=8 + base size=8 base align=8 +QSGRenderNode::RenderState (0x0x7f64e4491ba0) 0 nearly-empty + vptr=((& QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE) + 16u) + +Vtable for QSGRenderNode +QSGRenderNode::_ZTV13QSGRenderNode: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSGRenderNode) +16 0u +24 0u +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))QSGRenderNode::changedStates +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QSGRenderNode::releaseResources +72 (int (*)(...))QSGRenderNode::flags +80 (int (*)(...))QSGRenderNode::rect + +Class QSGRenderNode + size=88 align=8 + base size=88 base align=8 +QSGRenderNode (0x0x7f64e4168410) 0 + vptr=((& QSGRenderNode::_ZTV13QSGRenderNode) + 16u) + QSGNode (0x0x7f64e4491b40) 0 + primary-for QSGRenderNode (0x0x7f64e4168410) + +Vtable for QSGSimpleRectNode +QSGSimpleRectNode::_ZTV17QSGSimpleRectNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGSimpleRectNode) +16 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +24 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleRectNode + size=320 align=8 + base size=320 base align=8 +QSGSimpleRectNode (0x0x7f64e4168888) 0 + vptr=((& QSGSimpleRectNode::_ZTV17QSGSimpleRectNode) + 16u) + QSGGeometryNode (0x0x7f64e41688f0) 0 + primary-for QSGSimpleRectNode (0x0x7f64e4168888) + QSGBasicGeometryNode (0x0x7f64e4168958) 0 + primary-for QSGGeometryNode (0x0x7f64e41688f0) + QSGNode (0x0x7f64e424b1e0) 0 + primary-for QSGBasicGeometryNode (0x0x7f64e4168958) + +Vtable for QSGOpaqueTextureMaterial +QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QSGOpaqueTextureMaterial) +16 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +24 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +32 (int (*)(...))QSGOpaqueTextureMaterial::type +40 (int (*)(...))QSGOpaqueTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGOpaqueTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGOpaqueTextureMaterial (0x0x7f64e41689c0) 0 + vptr=((& QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial) + 16u) + QSGMaterial (0x0x7f64e424b240) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7f64e41689c0) + +Vtable for QSGTextureMaterial +QSGTextureMaterial::_ZTV18QSGTextureMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureMaterial) +16 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +24 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +32 (int (*)(...))QSGTextureMaterial::type +40 (int (*)(...))QSGTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGTextureMaterial (0x0x7f64e4168a28) 0 + vptr=((& QSGTextureMaterial::_ZTV18QSGTextureMaterial) + 16u) + QSGOpaqueTextureMaterial (0x0x7f64e4168a90) 0 + primary-for QSGTextureMaterial (0x0x7f64e4168a28) + QSGMaterial (0x0x7f64e424b2a0) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7f64e4168a90) + +Vtable for QSGSimpleTextureNode +QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGSimpleTextureNode) +16 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +24 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleTextureNode + size=384 align=8 + base size=384 base align=8 +QSGSimpleTextureNode (0x0x7f64e4168af8) 0 + vptr=((& QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode) + 16u) + QSGGeometryNode (0x0x7f64e4168b60) 0 + primary-for QSGSimpleTextureNode (0x0x7f64e4168af8) + QSGBasicGeometryNode (0x0x7f64e4168bc8) 0 + primary-for QSGGeometryNode (0x0x7f64e4168b60) + QSGNode (0x0x7f64e424b300) 0 + primary-for QSGBasicGeometryNode (0x0x7f64e4168bc8) + +Class QSGTextureProvider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTextureProvider::QPrivateSignal (0x0x7f64e424b5a0) 0 empty + +Vtable for QSGTextureProvider +QSGTextureProvider::_ZTV18QSGTextureProvider: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureProvider) +16 (int (*)(...))QSGTextureProvider::metaObject +24 (int (*)(...))QSGTextureProvider::qt_metacast +32 (int (*)(...))QSGTextureProvider::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSGTextureProvider + size=16 align=8 + base size=16 base align=8 +QSGTextureProvider (0x0x7f64e4168d68) 0 + vptr=((& QSGTextureProvider::_ZTV18QSGTextureProvider) + 16u) + QObject (0x0x7f64e424b540) 0 + primary-for QSGTextureProvider (0x0x7f64e4168d68) + +Vtable for QSGVertexColorMaterial +QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QSGVertexColorMaterial) +16 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +24 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +32 (int (*)(...))QSGVertexColorMaterial::type +40 (int (*)(...))QSGVertexColorMaterial::createShader +48 (int (*)(...))QSGVertexColorMaterial::compare + +Class QSGVertexColorMaterial + size=24 align=8 + base size=24 base align=8 +QSGVertexColorMaterial (0x0x7f64e4168dd0) 0 + vptr=((& QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial) + 16u) + QSGMaterial (0x0x7f64e424b600) 0 + primary-for QSGVertexColorMaterial (0x0x7f64e4168dd0) + +Class QQuickStyle + size=1 align=1 + base size=0 base align=1 +QQuickStyle (0x0x7f64e424b660) 0 empty + diff --git a/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.12.0.linux-gcc-amd64.txt b/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 00000000000..fdac69d6432 --- /dev/null +++ b/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,11123 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f5a2fe2c660) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f5a2fa18de0) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f5a2fa43060) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f5a2fa432a0) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f5a2fa434e0) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f5a2fa43660) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f5a2fa43a20) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f5a2fafd1e0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f5a2fafd2a0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f5a2fafd600) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f5a2fafd6c0) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f5a2fafd780) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f5a2fafd840) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f5a2fafdae0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f5a2fafdcc0) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f5a2fb7d180) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f5a2fb7d1e0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f5a2fbb7e40) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f5a2fbb7ea0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f5a2fb06680) 0 empty + std::input_iterator_tag (0x0x7f5a2fbb7f00) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f5a2fb066e8) 0 empty + std::forward_iterator_tag (0x0x7f5a2fb06750) 0 empty + std::input_iterator_tag (0x0x7f5a2fbb7f60) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f5a2fb067b8) 0 empty + std::bidirectional_iterator_tag (0x0x7f5a2fb06820) 0 empty + std::forward_iterator_tag (0x0x7f5a2fb06888) 0 empty + std::input_iterator_tag (0x0x7f5a2fbe3000) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f5a2fbe3c60) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f5a2fbe3cc0) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f5a2fbe3d20) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f5a2fbe3d80) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f5a2fbe3de0) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f5a2f8b4900) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f5a2f8b4b40) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f5a2f8b4c00) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f5a2f8b4c60) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f5a2f8b4d20) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f5a2f8b4d80) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f5a2f958240) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f5a2f9582a0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f5a2f958300) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f5a2fb06dd0) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f5a2f958360) 0 nearly-empty + primary-for std::bad_exception (0x0x7f5a2fb06dd0) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f5a2f9583c0) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f5a2f958420) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f5a2f645000) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f5a2f958840) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f5a2f645000) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f5a2f645068) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7f5a2f6450d0) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f5a2f645068) + std::exception (0x0x7f5a2f9588a0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f5a2f6450d0) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f5a2f958900) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f5a2f6cc540) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f5a2f4ec240) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f5a2f4ec2a0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f5a2f58f180) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f5a2f58f1e0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f5a2f58f2a0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f5a2f58f300) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f5a2f58f360) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f5a2f58f3c0) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f5a2f58f4e0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f5a2f58f540) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f5a2f58f960) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f5a2f58f9c0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f5a2f0b01e0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f5a2f0b0240) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f5a2f18d1e0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f5a2efa3000) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f5a2f0aee38) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f5a2efa30c0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f5a2f0aeea0) 0 + std::_Bit_iterator_base (0x0x7f5a2f0aef08) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f5a2efa3120) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f5a2f0aef70) 0 + std::_Bit_iterator_base (0x0x7f5a2f0ae618) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f5a2efa3180) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f5a2efa3f60) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f5a2ed85d20) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f5a2ed85cc0) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f5a2eabacc0) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f5a2d7187e0) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f5a2d718840) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f5a2d3fb300) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f5a2d3fb360) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f5a2d3fb3c0) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f5a2d3fb420) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f5a2d3fb6c0) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f5a2d3fbc00) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f5a2d3e0d00) 0 + std::__atomic_flag_base (0x0x7f5a2d3fbc60) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f5a2d277478) 0 + QAtomicInteger<int> (0x0x7f5a2d2774e0) 0 + QBasicAtomicInteger<int> (0x0x7f5a2cfb33c0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f5a2cede960) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f5a2cc82b40) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f5a2cc82c60) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f5a2ccd70d0) 0 + QGenericArgument (0x0x7f5a2cc82cc0) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f5a2cc82e40) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f5a2cc82f00) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f5a2cd7bf60) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f5a2c96a000) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f5a2c96a2a0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f5a2c96a300) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f5a2c96a660) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f5a2c96a6c0) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f5a2c96a720) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f5a2c96a780) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f5a2c96a7e0) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f5a2c96aba0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f5a2ca756e8) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f5a2c96ac60) 0 nearly-empty + primary-for std::logic_error (0x0x7f5a2ca756e8) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f5a2ca75750) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f5a2ca757b8) 0 + primary-for std::domain_error (0x0x7f5a2ca75750) + std::exception (0x0x7f5a2c96acc0) 0 nearly-empty + primary-for std::logic_error (0x0x7f5a2ca757b8) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f5a2ca75820) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f5a2ca75888) 0 + primary-for std::invalid_argument (0x0x7f5a2ca75820) + std::exception (0x0x7f5a2c96ad20) 0 nearly-empty + primary-for std::logic_error (0x0x7f5a2ca75888) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f5a2ca758f0) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f5a2ca75958) 0 + primary-for std::length_error (0x0x7f5a2ca758f0) + std::exception (0x0x7f5a2c96ad80) 0 nearly-empty + primary-for std::logic_error (0x0x7f5a2ca75958) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f5a2ca759c0) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f5a2ca75a28) 0 + primary-for std::out_of_range (0x0x7f5a2ca759c0) + std::exception (0x0x7f5a2c96ade0) 0 nearly-empty + primary-for std::logic_error (0x0x7f5a2ca75a28) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f5a2ca75a90) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f5a2c96ae40) 0 nearly-empty + primary-for std::runtime_error (0x0x7f5a2ca75a90) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f5a2ca75af8) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f5a2ca75b60) 0 + primary-for std::range_error (0x0x7f5a2ca75af8) + std::exception (0x0x7f5a2c96aea0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f5a2ca75b60) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f5a2ca75bc8) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f5a2ca75c30) 0 + primary-for std::overflow_error (0x0x7f5a2ca75bc8) + std::exception (0x0x7f5a2c96af00) 0 nearly-empty + primary-for std::runtime_error (0x0x7f5a2ca75c30) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f5a2ca75c98) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f5a2ca75d00) 0 + primary-for std::underflow_error (0x0x7f5a2ca75c98) + std::exception (0x0x7f5a2c96af60) 0 nearly-empty + primary-for std::runtime_error (0x0x7f5a2ca75d00) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f5a2cb2e120) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f5a2cb2e360) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f5a2cb2e4e0) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f5a2c76e138) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7f5a2c76e1a0) 0 + primary-for std::system_error (0x0x7f5a2c76e138) + std::exception (0x0x7f5a2cb2e720) 0 nearly-empty + primary-for std::runtime_error (0x0x7f5a2c76e1a0) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f5a2c76ed68) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7f5a2c76edd0) 0 + primary-for std::ios_base::failure (0x0x7f5a2c76ed68) + std::runtime_error (0x0x7f5a2c76ee38) 0 + primary-for std::system_error (0x0x7f5a2c76edd0) + std::exception (0x0x7f5a2cb2ea20) 0 nearly-empty + primary-for std::runtime_error (0x0x7f5a2c76ee38) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f5a2cb2ea80) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f5a2cb2eae0) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f5a2cb2eb40) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f5a2cb2e9c0) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f5a2c864300) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f5a2c8649c0) 0 empty + +VTT for std::basic_ostream<char> +std::basic_ostream<char>::_ZTTSo: 2u entries +0 ((& std::basic_ostream<char>::_ZTVSo) + 24u) +8 ((& std::basic_ostream<char>::_ZTVSo) + 64u) + +VTT for std::basic_ostream<wchar_t> +std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream<char> +std::basic_istream<char>::_ZTTSi: 2u entries +0 ((& std::basic_istream<char>::_ZTVSi) + 24u) +8 ((& std::basic_istream<char>::_ZTVSi) + 64u) + +VTT for std::basic_istream<wchar_t> +std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream<char> (0x0x7f5a2c429750 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream<char> (0x0x7f5a2c429820 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream<char> +std::basic_iostream<char>::_ZTTSd: 7u entries +0 ((& std::basic_iostream<char>::_ZTVSd) + 24u) +8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream<char>::_ZTVSd) + 104u) +48 ((& std::basic_iostream<char>::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f5a2c429bc8 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f5a2c429c98 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f5a2c486240) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f5a2c4862a0) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f5a2c1a9600) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f5a2c1a9960) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f5a2c1a9de0) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f5a2c2dcc60) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f5a2bf6d300) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f5a2bf6d2a0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f5a2c1163c0) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f5a2bedf000) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f5a2bedfc60) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f5a2bedfcc0) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f5a2bedfd20) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f5a2bcf6120) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f5a2bcf6180) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f5a2bc736e8) 0 empty + QListData::NotIndirectLayout (0x0x7f5a2bcf61e0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f5a2b973f50) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f5a2bcf6240) 0 empty + QListData::NotIndirectLayout (0x0x7f5a2bcf62a0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f5a2bc73750) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f5a2bcf6300) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f5a2bcf6360) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f5a2bcf60c0) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f5a2bcf67e0) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f5a2bb2ca20) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f5a2bb2c9c0) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f5a2bb3c1a0) 0 + QList<QString> (0x0x7f5a2bb3c208) 0 + QListSpecialMethods<QString> (0x0x7f5a2bb2cc00) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f5a2b7cf060) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f5a2b7cfc00) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f5a2b5592a0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f5a2b559420) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f5a2b5594e0) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f5a2bb3caf8) 0 + std::__uses_alloc_base (0x0x7f5a2b559480) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f5a2b6d9540) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f5a2b6d9780) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f5a2b6d9840) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f5a2b6d9960) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f5a2b6d9ae0) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f5a2b6d9f00) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f5a2b432060) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f5a2b4329c0) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f5a2b432de0) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f5a2b525120) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f5a2b334ae0) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f5a2b090960) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f5a2b0909c0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f5a2b090ba0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f5a2b090b40) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f5a2ad40e40) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f5a2ad40ea0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f5a2ad40f60) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f5a2ad5eea0) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f5a2ad40f00) 0 + primary-for QAbstractAnimation (0x0x7f5a2ad5eea0) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f5a2adcc060) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f5a2ad5ef08) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f5a2adcc000) 0 + primary-for QAnimationDriver (0x0x7f5a2ad5ef08) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f5a2adcc120) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f5a2ad5ef70) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f5a2adcc0c0) 0 + primary-for QEventLoop (0x0x7f5a2ad5ef70) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f5a2adcc300) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f5a2adcc3c0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f5a2adcc420) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f5a2ad5e2d8) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f5a2adcc360) 0 + primary-for QAbstractEventDispatcher (0x0x7f5a2ad5e2d8) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f5a2adcc6c0) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f5a2ae2f138) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7f5a2adcc720) 0 nearly-empty + primary-for std::bad_cast (0x0x7f5a2ae2f138) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f5a2ae2f1a0) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7f5a2adcc780) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f5a2ae2f1a0) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f5a2ab9d410) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7f5a2ab53840) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f5a2ab9d410) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f5a2ab53900) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f5a2ab53960) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f5a2ab53a80) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f5a2ab53f60) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f5a2ac514e0) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f5a2ac518a0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f5a2ac51840) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f5a2ac51900) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f5a2aa631e0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f5a2aa632a0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f5a2aa63240) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f5a2aa63300) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f5a2aa63180) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f5a2a730de0) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f5a2a7dd480) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f5a2a7dd420) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f5a2a7dd540) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f5a2a7dd4e0) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f5a2a901840) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f5a2a901f00) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f5a2a6ec660) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f5a2a6f71a0) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f5a2a6ec600) 0 + primary-for QAbstractItemModel (0x0x7f5a2a6f71a0) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f5a2a6ecf00) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f5a2a6f7888) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f5a2a6f78f0) 0 + primary-for QAbstractTableModel (0x0x7f5a2a6f7888) + QObject (0x0x7f5a2a6ecea0) 0 + primary-for QAbstractItemModel (0x0x7f5a2a6f78f0) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f5a2a3de000) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f5a2a6f7958) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f5a2a6f79c0) 0 + primary-for QAbstractListModel (0x0x7f5a2a6f7958) + QObject (0x0x7f5a2a6ecf60) 0 + primary-for QAbstractItemModel (0x0x7f5a2a6f79c0) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f5a2a3de2a0) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f5a2a3de360) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f5a2a6f7af8) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f5a2a6f7b60) 0 + primary-for QAbstractProxyModel (0x0x7f5a2a6f7af8) + QObject (0x0x7f5a2a3de300) 0 + primary-for QAbstractItemModel (0x0x7f5a2a6f7b60) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f5a2a3de420) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f5a2a6f7bc8) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f5a2a3de3c0) 0 + primary-for QAbstractState (0x0x7f5a2a6f7bc8) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f5a2a3de4e0) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f5a2a6f7c30) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f5a2a3de480) 0 + primary-for QAbstractTransition (0x0x7f5a2a6f7c30) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f5a2a3de5a0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f5a2a6f7c98) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f5a2a6f7d00) 0 + primary-for QAnimationGroup (0x0x7f5a2a6f7c98) + QObject (0x0x7f5a2a3de540) 0 + primary-for QAbstractAnimation (0x0x7f5a2a6f7d00) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f5a2a4b7300) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f5a2a4b75a0) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f5a2a4b7660) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f5a2a4b7960) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f5a2a4e13a8) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f5a2a4b7900) 0 + primary-for QIODevice (0x0x7f5a2a4e13a8) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f5a2a4b7ba0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f5a2a4e14e0) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f5a2a4e1548) 0 + primary-for QBuffer (0x0x7f5a2a4e14e0) + QObject (0x0x7f5a2a4b7b40) 0 + primary-for QIODevice (0x0x7f5a2a4e1548) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f5a2a4b7c60) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f5a2a4b7c00) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f5a2a4b7d80) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f5a2a4b7d20) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f5a2a4b7f60) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f5a2a1e9180) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f5a2a1e9420) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f5a2a1e9ba0) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f5a2a1e9c00) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f5a2a1e9b40) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f5a2a30bd20) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f5a29fd4360) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f5a29fd4600) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f5a29fd4840) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f5a29fd4f00) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f5a29d060c0) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f5a29d06600) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f5a29d065a0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f5a29b15900) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f5a29b159c0) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f5a29b93d20) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f5a29b93ea0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f5a29bf94e0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f5a29bf97e0) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f5a29bf9ba0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f5a299952a0) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7f5a299958a0) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f5a29995900) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f5a29851900) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f5a29851ea0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f5a29851f00) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f5a29851e40) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f5a29581f60) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f5a29620000) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f5a29581f00) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f5a29333b40) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f5a29333f00) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f5a2949f900) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f5a2949ff60) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f5a29146060) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f5a291df060) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f5a291df4e0) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f5a291d0af8) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f5a291df540) 0 + primary-for QTimerEvent (0x0x7f5a291d0af8) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f5a291d0b60) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f5a291df5a0) 0 + primary-for QChildEvent (0x0x7f5a291d0b60) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f5a292570d0) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f5a291dfa80) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f5a292570d0) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f5a29257138) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f5a291dfae0) 0 + primary-for QDeferredDeleteEvent (0x0x7f5a29257138) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f5a291dfba0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f5a292571a0) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f5a291dfb40) 0 + primary-for QCoreApplication (0x0x7f5a292571a0) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f5a291dfc00) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f5a291dfc60) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f5a291dfcc0) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f5a291dfd80) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f5a28eb02a0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f5a28eb0780) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f5a29019600) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f5a2901a618) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f5a2901a680) 0 + primary-for QFileDevice (0x0x7f5a2901a618) + QObject (0x0x7f5a290195a0) 0 + primary-for QIODevice (0x0x7f5a2901a680) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f5a29019840) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f5a2901a7b8) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f5a2901a820) 0 + primary-for QFile (0x0x7f5a2901a7b8) + QIODevice (0x0x7f5a2901a888) 0 + primary-for QFileDevice (0x0x7f5a2901a820) + QObject (0x0x7f5a290197e0) 0 + primary-for QIODevice (0x0x7f5a2901a888) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f5a29019a20) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f5a29019e40) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f5a28d09480) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f5a28d096c0) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f5a28e23ae0) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f5a28e26888) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f5a28e268f0) 0 + primary-for QEventTransition (0x0x7f5a28e26888) + QObject (0x0x7f5a28e23a80) 0 + primary-for QAbstractTransition (0x0x7f5a28e268f0) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f5a28e26958) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f5a28e23b40) 0 nearly-empty + primary-for QException (0x0x7f5a28e26958) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f5a28e269c0) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f5a28e26a28) 0 nearly-empty + primary-for QUnhandledException (0x0x7f5a28e269c0) + std::exception (0x0x7f5a28e23ba0) 0 nearly-empty + primary-for QException (0x0x7f5a28e26a28) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f5a28e23c00) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f5a28e23cc0) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f5a28e23d20) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f5a28e23e40) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f5a28e26a90) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f5a28e23de0) 0 + primary-for QFileSelector (0x0x7f5a28e26a90) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f5a28e23f00) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f5a28e26af8) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f5a28e23ea0) 0 + primary-for QFileSystemWatcher (0x0x7f5a28e26af8) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f5a28ad8000) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f5a28e26b60) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f5a28e26bc8) 0 + primary-for QFinalState (0x0x7f5a28e26b60) + QObject (0x0x7f5a28e23f60) 0 + primary-for QAbstractState (0x0x7f5a28e26bc8) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f5a28ad8060) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f5a28ad80c0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f5a28e26d00) 0 + QBasicMutex (0x0x7f5a28ad82a0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f5a28ad8300) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f5a28ad8360) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f5a28ad83c0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f5a28ad84e0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f5a28ad8d20) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f5a28c54540) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f5a28bcee38) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f5a28c544e0) 0 + primary-for QFutureWatcherBase (0x0x7f5a28bcee38) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f5a28c54b40) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f5a28c98750) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f5a28c987b8) 0 + primary-for QHistoryState (0x0x7f5a28c98750) + QObject (0x0x7f5a28c54ae0) 0 + primary-for QAbstractState (0x0x7f5a28c987b8) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f5a28c54c00) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f5a28c98820) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f5a28c98888) 0 + primary-for QIdentityProxyModel (0x0x7f5a28c98820) + QAbstractItemModel (0x0x7f5a28c988f0) 0 + primary-for QAbstractProxyModel (0x0x7f5a28c98888) + QObject (0x0x7f5a28c54ba0) 0 + primary-for QAbstractItemModel (0x0x7f5a28c988f0) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f5a28c54c60) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f5a28925360) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f5a28938138) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f5a28925300) 0 + primary-for QItemSelectionModel (0x0x7f5a28938138) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f5a28938340) 0 + QList<QItemSelectionRange> (0x0x7f5a289383a8) 0 + QListSpecialMethods<QItemSelectionRange> (0x0x7f5a28925660) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f5a28925b40) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f5a287362a0) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f5a287367e0) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f5a28736840) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f5a28736a20) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f5a28736a80) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f5a287369c0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f5a28846cc0) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f5a28846d20) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f5a284c13c0) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f5a284c1420) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f5a284c1360) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f5a285786c0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f5a285806e8) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f5a28578660) 0 + primary-for QLibrary (0x0x7f5a285806e8) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f5a28578d80) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f5a285788a0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f5a286672a0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f5a28667300) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f5a286675a0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f5a28667ba0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f5a2830c540) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f5a2830cb40) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f5a2830cea0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f5a28448060) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f5a28448000) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f5a284481e0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f5a28448480) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f5a28448ae0) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f5a28448b40) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f5a2817f180) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f5a2817f480) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f5a2817f4e0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f5a2817f7e0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f5a28176958) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f5a2817f780) 0 + primary-for QMimeData (0x0x7f5a28176958) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f5a2817f840) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f5a2817fb40) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f5a2817fc00) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f5a28176b60) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f5a2817fba0) 0 + primary-for QObjectCleanupHandler (0x0x7f5a28176b60) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f5a2817fc60) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f5a2820a420) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f5a2820e270) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f5a2820e2d8) 0 + primary-for QParallelAnimationGroup (0x0x7f5a2820e270) + QAbstractAnimation (0x0x7f5a2820e340) 0 + primary-for QAnimationGroup (0x0x7f5a2820e2d8) + QObject (0x0x7f5a2820a3c0) 0 + primary-for QAbstractAnimation (0x0x7f5a2820e340) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f5a2820a4e0) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f5a2820e3a8) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f5a2820e410) 0 + primary-for QPauseAnimation (0x0x7f5a2820e3a8) + QObject (0x0x7f5a2820a480) 0 + primary-for QAbstractAnimation (0x0x7f5a2820e410) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f5a2820a6c0) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f5a2820a9c0) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f5a2820e618) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f5a2820a960) 0 + primary-for QPluginLoader (0x0x7f5a2820e618) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f5a2820aa20) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f5a28294120) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f5a2820ec98) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f5a2820ed00) 0 + primary-for QProcess (0x0x7f5a2820ec98) + QObject (0x0x7f5a282940c0) 0 + primary-for QIODevice (0x0x7f5a2820ed00) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f5a282941e0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f5a2820ed68) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f5a2820edd0) 0 + primary-for QVariantAnimation (0x0x7f5a2820ed68) + QObject (0x0x7f5a28294180) 0 + primary-for QAbstractAnimation (0x0x7f5a2820edd0) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f5a282942a0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f5a2820eea0) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f5a2820ef08) 0 + primary-for QPropertyAnimation (0x0x7f5a2820eea0) + QAbstractAnimation (0x0x7f5a2820ef70) 0 + primary-for QVariantAnimation (0x0x7f5a2820ef08) + QObject (0x0x7f5a28294240) 0 + primary-for QAbstractAnimation (0x0x7f5a2820ef70) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f5a282943c0) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f5a28294360) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f5a27e8c270) 0 + QRandomGenerator (0x0x7f5a27e87360) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f5a27e87420) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f5a27e876c0) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f5a27e87780) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f5a27e87840) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f5a27e87ae0) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f5a27e87d80) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f5a27be5060) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f5a27be5300) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f5a27be5480) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f5a27e8cdd0) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f5a27e8ce38) 0 + primary-for QSaveFile (0x0x7f5a27e8cdd0) + QIODevice (0x0x7f5a27e8cea0) 0 + primary-for QFileDevice (0x0x7f5a27e8ce38) + QObject (0x0x7f5a27be5420) 0 + primary-for QIODevice (0x0x7f5a27e8cea0) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f5a27be55a0) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f5a27be5720) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f5a27a2cd20) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f5a27a41750) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f5a27a417b8) 0 + primary-for QSequentialAnimationGroup (0x0x7f5a27a41750) + QAbstractAnimation (0x0x7f5a27a41820) 0 + primary-for QAnimationGroup (0x0x7f5a27a417b8) + QObject (0x0x7f5a27a2ccc0) 0 + primary-for QAbstractAnimation (0x0x7f5a27a41820) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f5a27a2cde0) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f5a27a41888) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f5a27a2cd80) 0 + primary-for QSettings (0x0x7f5a27a41888) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f5a27a2cea0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f5a27a418f0) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f5a27a2ce40) 0 + primary-for QSharedMemory (0x0x7f5a27a418f0) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f5a27a2cf60) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f5a27a41958) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f5a27a2cf00) 0 + primary-for QSignalMapper (0x0x7f5a27a41958) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f5a27aa7060) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f5a27a419c0) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f5a27a41a28) 0 + primary-for QSignalTransition (0x0x7f5a27a419c0) + QObject (0x0x7f5a27aa7000) 0 + primary-for QAbstractTransition (0x0x7f5a27a41a28) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f5a27aa7120) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f5a27a41a90) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f5a27aa70c0) 0 + primary-for QSocketNotifier (0x0x7f5a27a41a90) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f5a27aa71e0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f5a27a41af8) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f5a27a41b60) 0 + primary-for QSortFilterProxyModel (0x0x7f5a27a41af8) + QAbstractItemModel (0x0x7f5a27a41bc8) 0 + primary-for QAbstractProxyModel (0x0x7f5a27a41b60) + QObject (0x0x7f5a27aa7180) 0 + primary-for QAbstractItemModel (0x0x7f5a27a41bc8) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f5a27aa72a0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f5a27aa74e0) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f5a27a41d68) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f5a27a41dd0) 0 + primary-for QState (0x0x7f5a27a41d68) + QObject (0x0x7f5a27aa7480) 0 + primary-for QAbstractState (0x0x7f5a27a41dd0) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f5a27aa7600) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f5a27a41f70) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f5a27aa7660) 0 + primary-for QStateMachine::SignalEvent (0x0x7f5a27a41f70) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f5a27b57000) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f5a27aa76c0) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f5a27b57000) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f5a27a41e38) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f5a27a41ea0) 0 + primary-for QStateMachine (0x0x7f5a27a41e38) + QAbstractState (0x0x7f5a27a41f08) 0 + primary-for QState (0x0x7f5a27a41ea0) + QObject (0x0x7f5a27aa75a0) 0 + primary-for QAbstractState (0x0x7f5a27a41f08) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f5a27aa7720) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f5a277ad660) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f5a27834a20) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f5a27864000) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f5a27864068) 0 + primary-for QStringListModel (0x0x7f5a27864000) + QAbstractItemModel (0x0x7f5a278640d0) 0 + primary-for QAbstractListModel (0x0x7f5a27864068) + QObject (0x0x7f5a278349c0) 0 + primary-for QAbstractItemModel (0x0x7f5a278640d0) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f5a27834a80) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f5a27834b40) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f5a27834c60) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f5a27864138) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f5a278641a0) 0 + primary-for QTemporaryFile (0x0x7f5a27864138) + QFileDevice (0x0x7f5a27864208) 0 + primary-for QFile (0x0x7f5a278641a0) + QIODevice (0x0x7f5a27864270) 0 + primary-for QFileDevice (0x0x7f5a27864208) + QObject (0x0x7f5a27834c00) 0 + primary-for QIODevice (0x0x7f5a27864270) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f5a27834cc0) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f5a27834f00) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f5a27834ea0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f5a278e6120) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f5a278e6180) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f5a278e61e0) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f5a278e6240) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f5a27864478) 0 + std::__mutex_base (0x0x7f5a278e62a0) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f5a278644e0) 0 + std::__recursive_mutex_base (0x0x7f5a278e6300) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f5a27950070) 0 + std::__mutex_base (0x0x7f5a278e6420) 0 + std::__timed_mutex_impl<std::timed_mutex> (0x0x7f5a278e6480) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f5a27950a10) 0 + std::__recursive_mutex_base (0x0x7f5a278e6540) 0 + std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7f5a278e65a0) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f5a278e6600) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f5a278e6660) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f5a278e66c0) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f5a278e6900) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f5a27864618) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7f5a278e69c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f5a27864618) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f5a27864680) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7f5a278e6a80) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f5a27864680) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f5a278646e8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7f5a278e6b40) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f5a278646e8) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f5a278647b8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7f5a278e6c00) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f5a278647b8) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f5a278e6cc0) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f5a278e6d20) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f5a278e6d80) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f5a278e6de0) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f5a27864a90) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7f5a27632180) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f5a27864a90) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f5a276329c0) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f5a273e01e0) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f5a273e03c0) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7f5a273e0420) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f5a273e0360) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f5a275a1060) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f5a275a1120) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f5a275a1180) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f5a272537e0) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f5a27248dd0) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7f5a27248e38) 0 + primary-for std::future_error (0x0x7f5a27248dd0) + std::exception (0x0x7f5a27253900) 0 nearly-empty + primary-for std::logic_error (0x0x7f5a27248e38) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f5a27253a20) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f5a272539c0) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f5a272ebf60) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f5a26fd5410) 0 + std::__at_thread_exit_elt (0x0x7f5a26ff9060) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f5a27253ba0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f5a27253960) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f5a26d7c000) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7f5a26d1bf00) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f5a26d7c000) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f5a26d84660) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f5a26d7ca90) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f5a26d84600) 0 + primary-for QThread (0x0x7f5a26d7ca90) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f5a26d84780) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f5a26d7caf8) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f5a26d84720) 0 + primary-for QThreadPool (0x0x7f5a26d7caf8) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f5a26d847e0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f5a26d84900) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f5a26d7cb60) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f5a26d848a0) 0 + primary-for QTimeLine (0x0x7f5a26d7cb60) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f5a26d849c0) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f5a26d7cbc8) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f5a26d84960) 0 + primary-for QTimer (0x0x7f5a26d7cbc8) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f5a26a4a120) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f5a26a4a0c0) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f5a26a4a6c0) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f5a26a41750) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f5a26a4a660) 0 + primary-for QTranslator (0x0x7f5a26a41750) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f5a26a4a720) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f5a26a4ad80) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f5a26a4ade0) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f5a26af70c0) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f5a26b06478) 0 + QVector<QXmlStreamAttribute> (0x0x7f5a26af7480) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f5a26af74e0) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f5a26af7780) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f5a26af7a20) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f5a26af7cc0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f5a26af7d20) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f5a26802780) 0 + +Class QRgba64 + size=8 align=8 + base size=8 base align=8 +QRgba64 (0x0x7f5a268028a0) 0 + +Class QColor + size=16 align=4 + base size=14 base align=4 +QColor (0x0x7f5a26802b40) 0 + +Class QRegion::QRegionData + size=16 align=8 + base size=16 base align=8 +QRegion::QRegionData (0x0x7f5a26926540) 0 + +Class QRegion + size=8 align=8 + base size=8 base align=8 +QRegion (0x0x7f5a269264e0) 0 + +Class QKeySequence + size=8 align=8 + base size=8 base align=8 +QKeySequence (0x0x7f5a265d78a0) 0 + +Class QVector2D + size=8 align=4 + base size=8 base align=4 +QVector2D (0x0x7f5a26688de0) 0 + +Class QTouchDevice + size=8 align=8 + base size=8 base align=8 +QTouchDevice (0x0x7f5a266d30c0) 0 + +Vtable for QInputEvent +QInputEvent::_ZTV11QInputEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QInputEvent) +16 (int (*)(...))QInputEvent::~QInputEvent +24 (int (*)(...))QInputEvent::~QInputEvent + +Class QInputEvent + size=32 align=8 + base size=32 base align=8 +QInputEvent (0x0x7f5a266d1270) 0 + vptr=((& QInputEvent::_ZTV11QInputEvent) + 16u) + QEvent (0x0x7f5a266d32a0) 0 + primary-for QInputEvent (0x0x7f5a266d1270) + +Vtable for QEnterEvent +QEnterEvent::_ZTV11QEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QEnterEvent) +16 (int (*)(...))QEnterEvent::~QEnterEvent +24 (int (*)(...))QEnterEvent::~QEnterEvent + +Class QEnterEvent + size=72 align=8 + base size=72 base align=8 +QEnterEvent (0x0x7f5a266d12d8) 0 + vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16u) + QEvent (0x0x7f5a266d3300) 0 + primary-for QEnterEvent (0x0x7f5a266d12d8) + +Vtable for QMouseEvent +QMouseEvent::_ZTV11QMouseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMouseEvent) +16 (int (*)(...))QMouseEvent::~QMouseEvent +24 (int (*)(...))QMouseEvent::~QMouseEvent + +Class QMouseEvent + size=104 align=8 + base size=100 base align=8 +QMouseEvent (0x0x7f5a266d1340) 0 + vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16u) + QInputEvent (0x0x7f5a266d13a8) 0 + primary-for QMouseEvent (0x0x7f5a266d1340) + QEvent (0x0x7f5a266d3360) 0 + primary-for QInputEvent (0x0x7f5a266d13a8) + +Vtable for QHoverEvent +QHoverEvent::_ZTV11QHoverEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHoverEvent) +16 (int (*)(...))QHoverEvent::~QHoverEvent +24 (int (*)(...))QHoverEvent::~QHoverEvent + +Class QHoverEvent + size=64 align=8 + base size=64 base align=8 +QHoverEvent (0x0x7f5a266d1410) 0 + vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16u) + QInputEvent (0x0x7f5a266d1478) 0 + primary-for QHoverEvent (0x0x7f5a266d1410) + QEvent (0x0x7f5a266d33c0) 0 + primary-for QInputEvent (0x0x7f5a266d1478) + +Vtable for QWheelEvent +QWheelEvent::_ZTV11QWheelEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWheelEvent) +16 (int (*)(...))QWheelEvent::~QWheelEvent +24 (int (*)(...))QWheelEvent::~QWheelEvent + +Class QWheelEvent + size=96 align=8 + base size=96 base align=8 +QWheelEvent (0x0x7f5a266d14e0) 0 + vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16u) + QInputEvent (0x0x7f5a266d1548) 0 + primary-for QWheelEvent (0x0x7f5a266d14e0) + QEvent (0x0x7f5a266d3420) 0 + primary-for QInputEvent (0x0x7f5a266d1548) + +Vtable for QTabletEvent +QTabletEvent::_ZTV12QTabletEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTabletEvent) +16 (int (*)(...))QTabletEvent::~QTabletEvent +24 (int (*)(...))QTabletEvent::~QTabletEvent + +Class QTabletEvent + size=128 align=8 + base size=128 base align=8 +QTabletEvent (0x0x7f5a266d15b0) 0 + vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16u) + QInputEvent (0x0x7f5a266d1618) 0 + primary-for QTabletEvent (0x0x7f5a266d15b0) + QEvent (0x0x7f5a266d3480) 0 + primary-for QInputEvent (0x0x7f5a266d1618) + +Vtable for QNativeGestureEvent +QNativeGestureEvent::_ZTV19QNativeGestureEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNativeGestureEvent) +16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent + +Class QNativeGestureEvent + size=112 align=8 + base size=112 base align=8 +QNativeGestureEvent (0x0x7f5a266d1680) 0 + vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16u) + QInputEvent (0x0x7f5a266d16e8) 0 + primary-for QNativeGestureEvent (0x0x7f5a266d1680) + QEvent (0x0x7f5a266d34e0) 0 + primary-for QInputEvent (0x0x7f5a266d16e8) + +Vtable for QKeyEvent +QKeyEvent::_ZTV9QKeyEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QKeyEvent) +16 (int (*)(...))QKeyEvent::~QKeyEvent +24 (int (*)(...))QKeyEvent::~QKeyEvent + +Class QKeyEvent + size=64 align=8 + base size=59 base align=8 +QKeyEvent (0x0x7f5a266d1750) 0 + vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16u) + QInputEvent (0x0x7f5a266d17b8) 0 + primary-for QKeyEvent (0x0x7f5a266d1750) + QEvent (0x0x7f5a266d3540) 0 + primary-for QInputEvent (0x0x7f5a266d17b8) + +Vtable for QFocusEvent +QFocusEvent::_ZTV11QFocusEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusEvent) +16 (int (*)(...))QFocusEvent::~QFocusEvent +24 (int (*)(...))QFocusEvent::~QFocusEvent + +Class QFocusEvent + size=24 align=8 + base size=24 base align=8 +QFocusEvent (0x0x7f5a266d1820) 0 + vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16u) + QEvent (0x0x7f5a266d35a0) 0 + primary-for QFocusEvent (0x0x7f5a266d1820) + +Vtable for QPaintEvent +QPaintEvent::_ZTV11QPaintEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPaintEvent) +16 (int (*)(...))QPaintEvent::~QPaintEvent +24 (int (*)(...))QPaintEvent::~QPaintEvent + +Class QPaintEvent + size=56 align=8 + base size=49 base align=8 +QPaintEvent (0x0x7f5a266d1888) 0 + vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16u) + QEvent (0x0x7f5a266d3600) 0 + primary-for QPaintEvent (0x0x7f5a266d1888) + +Vtable for QMoveEvent +QMoveEvent::_ZTV10QMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QMoveEvent) +16 (int (*)(...))QMoveEvent::~QMoveEvent +24 (int (*)(...))QMoveEvent::~QMoveEvent + +Class QMoveEvent + size=40 align=8 + base size=36 base align=8 +QMoveEvent (0x0x7f5a266d18f0) 0 + vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16u) + QEvent (0x0x7f5a266d3660) 0 + primary-for QMoveEvent (0x0x7f5a266d18f0) + +Vtable for QExposeEvent +QExposeEvent::_ZTV12QExposeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QExposeEvent) +16 (int (*)(...))QExposeEvent::~QExposeEvent +24 (int (*)(...))QExposeEvent::~QExposeEvent + +Class QExposeEvent + size=32 align=8 + base size=32 base align=8 +QExposeEvent (0x0x7f5a266d1958) 0 + vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16u) + QEvent (0x0x7f5a266d36c0) 0 + primary-for QExposeEvent (0x0x7f5a266d1958) + +Vtable for QPlatformSurfaceEvent +QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent) +16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent + +Class QPlatformSurfaceEvent + size=24 align=8 + base size=24 base align=8 +QPlatformSurfaceEvent (0x0x7f5a266d19c0) 0 + vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16u) + QEvent (0x0x7f5a266d3720) 0 + primary-for QPlatformSurfaceEvent (0x0x7f5a266d19c0) + +Vtable for QResizeEvent +QResizeEvent::_ZTV12QResizeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QResizeEvent) +16 (int (*)(...))QResizeEvent::~QResizeEvent +24 (int (*)(...))QResizeEvent::~QResizeEvent + +Class QResizeEvent + size=40 align=8 + base size=36 base align=8 +QResizeEvent (0x0x7f5a266d1a28) 0 + vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16u) + QEvent (0x0x7f5a266d3780) 0 + primary-for QResizeEvent (0x0x7f5a266d1a28) + +Vtable for QCloseEvent +QCloseEvent::_ZTV11QCloseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QCloseEvent) +16 (int (*)(...))QCloseEvent::~QCloseEvent +24 (int (*)(...))QCloseEvent::~QCloseEvent + +Class QCloseEvent + size=24 align=8 + base size=20 base align=8 +QCloseEvent (0x0x7f5a266d1a90) 0 + vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16u) + QEvent (0x0x7f5a266d37e0) 0 + primary-for QCloseEvent (0x0x7f5a266d1a90) + +Vtable for QIconDragEvent +QIconDragEvent::_ZTV14QIconDragEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QIconDragEvent) +16 (int (*)(...))QIconDragEvent::~QIconDragEvent +24 (int (*)(...))QIconDragEvent::~QIconDragEvent + +Class QIconDragEvent + size=24 align=8 + base size=20 base align=8 +QIconDragEvent (0x0x7f5a266d1af8) 0 + vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16u) + QEvent (0x0x7f5a266d3840) 0 + primary-for QIconDragEvent (0x0x7f5a266d1af8) + +Vtable for QShowEvent +QShowEvent::_ZTV10QShowEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QShowEvent) +16 (int (*)(...))QShowEvent::~QShowEvent +24 (int (*)(...))QShowEvent::~QShowEvent + +Class QShowEvent + size=24 align=8 + base size=20 base align=8 +QShowEvent (0x0x7f5a266d1b60) 0 + vptr=((& QShowEvent::_ZTV10QShowEvent) + 16u) + QEvent (0x0x7f5a266d38a0) 0 + primary-for QShowEvent (0x0x7f5a266d1b60) + +Vtable for QHideEvent +QHideEvent::_ZTV10QHideEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHideEvent) +16 (int (*)(...))QHideEvent::~QHideEvent +24 (int (*)(...))QHideEvent::~QHideEvent + +Class QHideEvent + size=24 align=8 + base size=20 base align=8 +QHideEvent (0x0x7f5a266d1bc8) 0 + vptr=((& QHideEvent::_ZTV10QHideEvent) + 16u) + QEvent (0x0x7f5a266d3900) 0 + primary-for QHideEvent (0x0x7f5a266d1bc8) + +Vtable for QContextMenuEvent +QContextMenuEvent::_ZTV17QContextMenuEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QContextMenuEvent) +16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent + +Class QContextMenuEvent + size=56 align=8 + base size=49 base align=8 +QContextMenuEvent (0x0x7f5a266d1c30) 0 + vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16u) + QInputEvent (0x0x7f5a266d1c98) 0 + primary-for QContextMenuEvent (0x0x7f5a266d1c30) + QEvent (0x0x7f5a266d3960) 0 + primary-for QInputEvent (0x0x7f5a266d1c98) + +Class QInputMethodEvent::Attribute + size=32 align=8 + base size=32 base align=8 +QInputMethodEvent::Attribute (0x0x7f5a266d3a20) 0 + +Vtable for QInputMethodEvent +QInputMethodEvent::_ZTV17QInputMethodEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QInputMethodEvent) +16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent + +Class QInputMethodEvent + size=56 align=8 + base size=56 base align=8 +QInputMethodEvent (0x0x7f5a266d1d00) 0 + vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16u) + QEvent (0x0x7f5a266d39c0) 0 + primary-for QInputMethodEvent (0x0x7f5a266d1d00) + +Class QInputMethodQueryEvent::QueryPair + size=24 align=8 + base size=24 base align=8 +QInputMethodQueryEvent::QueryPair (0x0x7f5a266d3ea0) 0 + +Vtable for QInputMethodQueryEvent +QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent) +16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent + +Class QInputMethodQueryEvent + size=32 align=8 + base size=32 base align=8 +QInputMethodQueryEvent (0x0x7f5a26447068) 0 + vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16u) + QEvent (0x0x7f5a266d3e40) 0 + primary-for QInputMethodQueryEvent (0x0x7f5a26447068) + +Vtable for QDropEvent +QDropEvent::_ZTV10QDropEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDropEvent) +16 (int (*)(...))QDropEvent::~QDropEvent +24 (int (*)(...))QDropEvent::~QDropEvent + +Class QDropEvent + size=72 align=8 + base size=72 base align=8 +QDropEvent (0x0x7f5a26447340) 0 + vptr=((& QDropEvent::_ZTV10QDropEvent) + 16u) + QEvent (0x0x7f5a2647e240) 0 + primary-for QDropEvent (0x0x7f5a26447340) + +Vtable for QDragMoveEvent +QDragMoveEvent::_ZTV14QDragMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDragMoveEvent) +16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent + +Class QDragMoveEvent + size=88 align=8 + base size=88 base align=8 +QDragMoveEvent (0x0x7f5a264473a8) 0 + vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16u) + QDropEvent (0x0x7f5a26447410) 0 + primary-for QDragMoveEvent (0x0x7f5a264473a8) + QEvent (0x0x7f5a2647e2a0) 0 + primary-for QDropEvent (0x0x7f5a26447410) + +Vtable for QDragEnterEvent +QDragEnterEvent::_ZTV15QDragEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragEnterEvent) +16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent + +Class QDragEnterEvent + size=88 align=8 + base size=88 base align=8 +QDragEnterEvent (0x0x7f5a26447478) 0 + vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16u) + QDragMoveEvent (0x0x7f5a264474e0) 0 + primary-for QDragEnterEvent (0x0x7f5a26447478) + QDropEvent (0x0x7f5a26447548) 0 + primary-for QDragMoveEvent (0x0x7f5a264474e0) + QEvent (0x0x7f5a2647e300) 0 + primary-for QDropEvent (0x0x7f5a26447548) + +Vtable for QDragLeaveEvent +QDragLeaveEvent::_ZTV15QDragLeaveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragLeaveEvent) +16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent + +Class QDragLeaveEvent + size=24 align=8 + base size=20 base align=8 +QDragLeaveEvent (0x0x7f5a264475b0) 0 + vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16u) + QEvent (0x0x7f5a2647e360) 0 + primary-for QDragLeaveEvent (0x0x7f5a264475b0) + +Vtable for QHelpEvent +QHelpEvent::_ZTV10QHelpEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHelpEvent) +16 (int (*)(...))QHelpEvent::~QHelpEvent +24 (int (*)(...))QHelpEvent::~QHelpEvent + +Class QHelpEvent + size=40 align=8 + base size=36 base align=8 +QHelpEvent (0x0x7f5a26447618) 0 + vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16u) + QEvent (0x0x7f5a2647e3c0) 0 + primary-for QHelpEvent (0x0x7f5a26447618) + +Vtable for QStatusTipEvent +QStatusTipEvent::_ZTV15QStatusTipEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QStatusTipEvent) +16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent + +Class QStatusTipEvent + size=32 align=8 + base size=32 base align=8 +QStatusTipEvent (0x0x7f5a26447680) 0 + vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16u) + QEvent (0x0x7f5a2647e420) 0 + primary-for QStatusTipEvent (0x0x7f5a26447680) + +Vtable for QWhatsThisClickedEvent +QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent) +16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent + +Class QWhatsThisClickedEvent + size=32 align=8 + base size=32 base align=8 +QWhatsThisClickedEvent (0x0x7f5a264476e8) 0 + vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16u) + QEvent (0x0x7f5a2647e480) 0 + primary-for QWhatsThisClickedEvent (0x0x7f5a264476e8) + +Vtable for QActionEvent +QActionEvent::_ZTV12QActionEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionEvent) +16 (int (*)(...))QActionEvent::~QActionEvent +24 (int (*)(...))QActionEvent::~QActionEvent + +Class QActionEvent + size=40 align=8 + base size=40 base align=8 +QActionEvent (0x0x7f5a26447750) 0 + vptr=((& QActionEvent::_ZTV12QActionEvent) + 16u) + QEvent (0x0x7f5a2647e4e0) 0 + primary-for QActionEvent (0x0x7f5a26447750) + +Vtable for QFileOpenEvent +QFileOpenEvent::_ZTV14QFileOpenEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QFileOpenEvent) +16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent + +Class QFileOpenEvent + size=40 align=8 + base size=40 base align=8 +QFileOpenEvent (0x0x7f5a264477b8) 0 + vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16u) + QEvent (0x0x7f5a2647e540) 0 + primary-for QFileOpenEvent (0x0x7f5a264477b8) + +Vtable for QToolBarChangeEvent +QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QToolBarChangeEvent) +16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent + +Class QToolBarChangeEvent + size=24 align=8 + base size=21 base align=8 +QToolBarChangeEvent (0x0x7f5a26447820) 0 + vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16u) + QEvent (0x0x7f5a2647e5a0) 0 + primary-for QToolBarChangeEvent (0x0x7f5a26447820) + +Vtable for QShortcutEvent +QShortcutEvent::_ZTV14QShortcutEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QShortcutEvent) +16 (int (*)(...))QShortcutEvent::~QShortcutEvent +24 (int (*)(...))QShortcutEvent::~QShortcutEvent + +Class QShortcutEvent + size=40 align=8 + base size=40 base align=8 +QShortcutEvent (0x0x7f5a26447888) 0 + vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16u) + QEvent (0x0x7f5a2647e600) 0 + primary-for QShortcutEvent (0x0x7f5a26447888) + +Vtable for QWindowStateChangeEvent +QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent) +16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent + +Class QWindowStateChangeEvent + size=32 align=8 + base size=25 base align=8 +QWindowStateChangeEvent (0x0x7f5a264478f0) 0 + vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16u) + QEvent (0x0x7f5a2647e660) 0 + primary-for QWindowStateChangeEvent (0x0x7f5a264478f0) + +Class QPointingDeviceUniqueId + size=8 align=8 + base size=8 base align=8 +QPointingDeviceUniqueId (0x0x7f5a2647e6c0) 0 + +Class QTouchEvent::TouchPoint + size=8 align=8 + base size=8 base align=8 +QTouchEvent::TouchPoint (0x0x7f5a2647ed80) 0 + +Vtable for QTouchEvent +QTouchEvent::_ZTV11QTouchEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTouchEvent) +16 (int (*)(...))QTouchEvent::~QTouchEvent +24 (int (*)(...))QTouchEvent::~QTouchEvent + +Class QTouchEvent + size=72 align=8 + base size=72 base align=8 +QTouchEvent (0x0x7f5a26447f70) 0 + vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16u) + QInputEvent (0x0x7f5a264ed000) 0 + primary-for QTouchEvent (0x0x7f5a26447f70) + QEvent (0x0x7f5a2647ed20) 0 + primary-for QInputEvent (0x0x7f5a264ed000) + +Vtable for QScrollPrepareEvent +QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollPrepareEvent) +16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent + +Class QScrollPrepareEvent + size=112 align=8 + base size=112 base align=8 +QScrollPrepareEvent (0x0x7f5a261ac820) 0 + vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16u) + QEvent (0x0x7f5a261b0420) 0 + primary-for QScrollPrepareEvent (0x0x7f5a261ac820) + +Vtable for QScrollEvent +QScrollEvent::_ZTV12QScrollEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QScrollEvent) +16 (int (*)(...))QScrollEvent::~QScrollEvent +24 (int (*)(...))QScrollEvent::~QScrollEvent + +Class QScrollEvent + size=64 align=8 + base size=60 base align=8 +QScrollEvent (0x0x7f5a261ac888) 0 + vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16u) + QEvent (0x0x7f5a261b0480) 0 + primary-for QScrollEvent (0x0x7f5a261ac888) + +Vtable for QScreenOrientationChangeEvent +QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent) +16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent + +Class QScreenOrientationChangeEvent + size=40 align=8 + base size=36 base align=8 +QScreenOrientationChangeEvent (0x0x7f5a261ac8f0) 0 + vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16u) + QEvent (0x0x7f5a261b04e0) 0 + primary-for QScreenOrientationChangeEvent (0x0x7f5a261ac8f0) + +Vtable for QApplicationStateChangeEvent +QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent) +16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent + +Class QApplicationStateChangeEvent + size=24 align=8 + base size=24 base align=8 +QApplicationStateChangeEvent (0x0x7f5a261ac958) 0 + vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16u) + QEvent (0x0x7f5a261b0540) 0 + primary-for QApplicationStateChangeEvent (0x0x7f5a261ac958) + +Class QFont + size=16 align=8 + base size=12 base align=8 +QFont (0x0x7f5a261b05a0) 0 + +Class QPolygon + size=8 align=8 + base size=8 base align=8 +QPolygon (0x0x7f5a262646e8) 0 + QVector<QPoint> (0x0x7f5a2626f2a0) 0 + +Class QPolygonF + size=8 align=8 + base size=8 base align=8 +QPolygonF (0x0x7f5a26264a90) 0 + QVector<QPointF> (0x0x7f5a2626f720) 0 + +Class QMatrix + size=48 align=8 + base size=48 base align=8 +QMatrix (0x0x7f5a2626fae0) 0 + +Class QPainterPath::Element + size=24 align=8 + base size=24 base align=8 +QPainterPath::Element (0x0x7f5a2626fde0) 0 + +Class QPainterPath + size=8 align=8 + base size=8 base align=8 +QPainterPath (0x0x7f5a2626fd80) 0 + +Class QPainterPathStroker + size=8 align=8 + base size=8 base align=8 +QPainterPathStroker (0x0x7f5a25fb77e0) 0 + +Class QTransform + size=88 align=8 + base size=88 base align=8 +QTransform (0x0x7f5a25fb7900) 0 + +Vtable for QPaintDevice +QPaintDevice::_ZTV12QPaintDevice: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDevice + size=24 align=8 + base size=24 base align=8 +QPaintDevice (0x0x7f5a26055060) 0 + vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u) + +Class QPixelFormat + size=8 align=8 + base size=8 base align=8 +QPixelFormat (0x0x7f5a260550c0) 0 + +Vtable for QImage +QImage::_ZTV6QImage: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QImage) +16 (int (*)(...))QImage::~QImage +24 (int (*)(...))QImage::~QImage +32 (int (*)(...))QImage::devType +40 (int (*)(...))QImage::paintEngine +48 (int (*)(...))QImage::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QImage + size=32 align=8 + base size=32 base align=8 +QImage (0x0x7f5a26108958) 0 + vptr=((& QImage::_ZTV6QImage) + 16u) + QPaintDevice (0x0x7f5a26055b40) 0 + primary-for QImage (0x0x7f5a26108958) + +Vtable for QPixmap +QPixmap::_ZTV7QPixmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QPixmap) +16 (int (*)(...))QPixmap::~QPixmap +24 (int (*)(...))QPixmap::~QPixmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPixmap + size=32 align=8 + base size=32 base align=8 +QPixmap (0x0x7f5a25df04e0) 0 + vptr=((& QPixmap::_ZTV7QPixmap) + 16u) + QPaintDevice (0x0x7f5a25ddfae0) 0 + primary-for QPixmap (0x0x7f5a25df04e0) + +Class QBrush + size=8 align=8 + base size=8 base align=8 +QBrush (0x0x7f5a25ddfde0) 0 + +Class QBrushData + size=112 align=8 + base size=112 base align=8 +QBrushData (0x0x7f5a25e775a0) 0 + +Class QGradient + size=64 align=8 + base size=64 base align=8 +QGradient (0x0x7f5a25e77600) 0 + +Class QLinearGradient + size=64 align=8 + base size=64 base align=8 +QLinearGradient (0x0x7f5a25df0e38) 0 + QGradient (0x0x7f5a25e778a0) 0 + +Class QRadialGradient + size=64 align=8 + base size=64 base align=8 +QRadialGradient (0x0x7f5a25df0ea0) 0 + QGradient (0x0x7f5a25e77900) 0 + +Class QConicalGradient + size=64 align=8 + base size=64 base align=8 +QConicalGradient (0x0x7f5a25df0f08) 0 + QGradient (0x0x7f5a25e77960) 0 + +Class QPen + size=8 align=8 + base size=8 base align=8 +QPen (0x0x7f5a25e779c0) 0 + +Class QTextOption::Tab + size=16 align=8 + base size=14 base align=8 +QTextOption::Tab (0x0x7f5a25f70c00) 0 + +Class QTextOption + size=32 align=8 + base size=32 base align=8 +QTextOption (0x0x7f5a25f70ba0) 0 + +Class QTextLength + size=16 align=8 + base size=16 base align=8 +QTextLength (0x0x7f5a25ba93c0) 0 + +Class QTextFormat + size=16 align=8 + base size=12 base align=8 +QTextFormat (0x0x7f5a25ba9ae0) 0 + +Class QTextCharFormat + size=16 align=8 + base size=12 base align=8 +QTextCharFormat (0x0x7f5a25c167b8) 0 + QTextFormat (0x0x7f5a25c59960) 0 + +Class QTextBlockFormat + size=16 align=8 + base size=12 base align=8 +QTextBlockFormat (0x0x7f5a25d4a068) 0 + QTextFormat (0x0x7f5a25c59c00) 0 + +Class QTextListFormat + size=16 align=8 + base size=12 base align=8 +QTextListFormat (0x0x7f5a25d4a2d8) 0 + QTextFormat (0x0x7f5a25c59ea0) 0 + +Class QTextImageFormat + size=16 align=8 + base size=12 base align=8 +QTextImageFormat (0x0x7f5a25d4a4e0) 0 + QTextCharFormat (0x0x7f5a25d4a548) 0 + QTextFormat (0x0x7f5a25d87180) 0 + +Class QTextFrameFormat + size=16 align=8 + base size=12 base align=8 +QTextFrameFormat (0x0x7f5a25d4a750) 0 + QTextFormat (0x0x7f5a25d87420) 0 + +Class QTextTableFormat + size=16 align=8 + base size=12 base align=8 +QTextTableFormat (0x0x7f5a25d4a958) 0 + QTextFrameFormat (0x0x7f5a25d4a9c0) 0 + QTextFormat (0x0x7f5a25d876c0) 0 + +Class QTextTableCellFormat + size=16 align=8 + base size=12 base align=8 +QTextTableCellFormat (0x0x7f5a25d4abc8) 0 + QTextCharFormat (0x0x7f5a25d4ac30) 0 + QTextFormat (0x0x7f5a25d879c0) 0 + +Class QFontDatabase + size=8 align=8 + base size=8 base align=8 +QFontDatabase (0x0x7f5a25d87c60) 0 + +Class QRawFont + size=8 align=8 + base size=8 base align=8 +QRawFont (0x0x7f5a25d87cc0) 0 + +Class QGlyphRun + size=8 align=8 + base size=8 base align=8 +QGlyphRun (0x0x7f5a25a481e0) 0 + +Class QTextCursor + size=8 align=8 + base size=8 base align=8 +QTextCursor (0x0x7f5a25a484e0) 0 + +Class QTextInlineObject + size=16 align=8 + base size=16 base align=8 +QTextInlineObject (0x0x7f5a25a487e0) 0 + +Class QTextLayout::FormatRange + size=24 align=8 + base size=24 base align=8 +QTextLayout::FormatRange (0x0x7f5a25a488a0) 0 + +Class QTextLayout + size=8 align=8 + base size=8 base align=8 +QTextLayout (0x0x7f5a25a48840) 0 + +Class QTextLine + size=16 align=8 + base size=16 base align=8 +QTextLine (0x0x7f5a25b36300) 0 + +Vtable for QAbstractUndoItem +QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractUndoItem) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAbstractUndoItem + size=8 align=8 + base size=8 base align=8 +QAbstractUndoItem (0x0x7f5a25b36360) 0 nearly-empty + vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16u) + +Class QTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextDocument::QPrivateSignal (0x0x7f5a25b36420) 0 empty + +Vtable for QTextDocument +QTextDocument::_ZTV13QTextDocument: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QTextDocument) +16 (int (*)(...))QTextDocument::metaObject +24 (int (*)(...))QTextDocument::qt_metacast +32 (int (*)(...))QTextDocument::qt_metacall +40 (int (*)(...))QTextDocument::~QTextDocument +48 (int (*)(...))QTextDocument::~QTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextDocument::clear +120 (int (*)(...))QTextDocument::createObject +128 (int (*)(...))QTextDocument::loadResource + +Class QTextDocument + size=16 align=8 + base size=16 base align=8 +QTextDocument (0x0x7f5a25a4c478) 0 + vptr=((& QTextDocument::_ZTV13QTextDocument) + 16u) + QObject (0x0x7f5a25b363c0) 0 + primary-for QTextDocument (0x0x7f5a25a4c478) + +Class QPalette::Data + size=4 align=4 + base size=4 base align=4 +QPalette::Data (0x0x7f5a25b36660) 0 + +Class QPalette + size=16 align=8 + base size=12 base align=8 +QPalette (0x0x7f5a25b36600) 0 + +Class QAbstractTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTextDocumentLayout::QPrivateSignal (0x0x7f5a25854720) 0 empty + +Class QAbstractTextDocumentLayout::Selection + size=24 align=8 + base size=24 base align=8 +QAbstractTextDocumentLayout::Selection (0x0x7f5a25854780) 0 + +Class QAbstractTextDocumentLayout::PaintContext + size=64 align=8 + base size=64 base align=8 +QAbstractTextDocumentLayout::PaintContext (0x0x7f5a258547e0) 0 + +Vtable for QAbstractTextDocumentLayout +QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout) +16 (int (*)(...))QAbstractTextDocumentLayout::metaObject +24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast +32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QAbstractTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QAbstractTextDocumentLayout (0x0x7f5a25851c98) 0 + vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16u) + QObject (0x0x7f5a258546c0) 0 + primary-for QAbstractTextDocumentLayout (0x0x7f5a25851c98) + +Vtable for QTextObjectInterface +QTextObjectInterface::_ZTV20QTextObjectInterface: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextObjectInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QTextObjectInterface + size=8 align=8 + base size=8 base align=8 +QTextObjectInterface (0x0x7f5a25854d80) 0 nearly-empty + vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16u) + +Class QAccessible::State + size=8 align=8 + base size=5 base align=8 +QAccessible::State (0x0x7f5a25854ea0) 0 + +Vtable for QAccessible::ActivationObserver +QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAccessible::ActivationObserver + size=8 align=8 + base size=8 base align=8 +QAccessible::ActivationObserver (0x0x7f5a25854f00) 0 nearly-empty + vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16u) + +Class QAccessible + size=1 align=1 + base size=0 base align=1 +QAccessible (0x0x7f5a25854e40) 0 empty + +Vtable for QAccessibleInterface +QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAccessibleInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleInterface (0x0x7f5a25909120) 0 nearly-empty + vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16u) + +Vtable for QAccessibleTextInterface +QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAccessibleTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset +104 (int (*)(...))QAccessibleTextInterface::textAfterOffset +112 (int (*)(...))QAccessibleTextInterface::textAtOffset +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTextInterface (0x0x7f5a25909180) 0 nearly-empty + vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16u) + +Vtable for QAccessibleEditableTextInterface +QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleEditableTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleEditableTextInterface (0x0x7f5a259091e0) 0 nearly-empty + vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16u) + +Vtable for QAccessibleValueInterface +QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleValueInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleValueInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleValueInterface (0x0x7f5a25909240) 0 nearly-empty + vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16u) + +Vtable for QAccessibleTableCellInterface +QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableCellInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableCellInterface (0x0x7f5a259092a0) 0 nearly-empty + vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16u) + +Vtable for QAccessibleTableInterface +QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleTableInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableInterface (0x0x7f5a25909300) 0 nearly-empty + vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16u) + +Vtable for QAccessibleActionInterface +QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleActionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QAccessibleActionInterface::localizedActionName +48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleActionInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleActionInterface (0x0x7f5a25909360) 0 nearly-empty + vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16u) + +Vtable for QAccessibleImageInterface +QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleImageInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleImageInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleImageInterface (0x0x7f5a259093c0) 0 nearly-empty + vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16u) + +Vtable for QAccessibleEvent +QAccessibleEvent::_ZTV16QAccessibleEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAccessibleEvent) +16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleEvent + size=32 align=8 + base size=28 base align=8 +QAccessibleEvent (0x0x7f5a25909420) 0 + vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16u) + +Vtable for QAccessibleStateChangeEvent +QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent) +16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleStateChangeEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleStateChangeEvent (0x0x7f5a258d56e8) 0 + vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16u) + QAccessibleEvent (0x0x7f5a25909960) 0 + primary-for QAccessibleStateChangeEvent (0x0x7f5a258d56e8) + +Vtable for QAccessibleTextCursorEvent +QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent) +16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextCursorEvent + size=32 align=8 + base size=32 base align=8 +QAccessibleTextCursorEvent (0x0x7f5a258d5750) 0 + vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16u) + QAccessibleEvent (0x0x7f5a259099c0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f5a258d5750) + +Vtable for QAccessibleTextSelectionEvent +QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent) +16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextSelectionEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleTextSelectionEvent (0x0x7f5a258d57b8) 0 + vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f5a258d5820) 0 + primary-for QAccessibleTextSelectionEvent (0x0x7f5a258d57b8) + QAccessibleEvent (0x0x7f5a25909a20) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f5a258d5820) + +Vtable for QAccessibleTextInsertEvent +QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent) +16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextInsertEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextInsertEvent (0x0x7f5a258d5888) 0 + vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f5a258d58f0) 0 + primary-for QAccessibleTextInsertEvent (0x0x7f5a258d5888) + QAccessibleEvent (0x0x7f5a25909a80) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f5a258d58f0) + +Vtable for QAccessibleTextRemoveEvent +QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent) +16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextRemoveEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextRemoveEvent (0x0x7f5a258d5958) 0 + vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f5a258d59c0) 0 + primary-for QAccessibleTextRemoveEvent (0x0x7f5a258d5958) + QAccessibleEvent (0x0x7f5a25909ae0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f5a258d59c0) + +Vtable for QAccessibleTextUpdateEvent +QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent) +16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextUpdateEvent + size=56 align=8 + base size=56 base align=8 +QAccessibleTextUpdateEvent (0x0x7f5a258d5a28) 0 + vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f5a258d5a90) 0 + primary-for QAccessibleTextUpdateEvent (0x0x7f5a258d5a28) + QAccessibleEvent (0x0x7f5a25909b40) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f5a258d5a90) + +Vtable for QAccessibleValueChangeEvent +QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent) +16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleValueChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleValueChangeEvent (0x0x7f5a258d5af8) 0 + vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16u) + QAccessibleEvent (0x0x7f5a25909ba0) 0 + primary-for QAccessibleValueChangeEvent (0x0x7f5a258d5af8) + +Vtable for QAccessibleTableModelChangeEvent +QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent) +16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTableModelChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTableModelChangeEvent (0x0x7f5a258d5b60) 0 + vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16u) + QAccessibleEvent (0x0x7f5a25909c00) 0 + primary-for QAccessibleTableModelChangeEvent (0x0x7f5a258d5b60) + +Vtable for QAccessibleBridge +QAccessibleBridge::_ZTV17QAccessibleBridge: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleBridge) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridge + size=8 align=8 + base size=8 base align=8 +QAccessibleBridge (0x0x7f5a25909cc0) 0 nearly-empty + vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16u) + +Class QAccessibleBridgePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessibleBridgePlugin::QPrivateSignal (0x0x7f5a25909d80) 0 empty + +Vtable for QAccessibleBridgePlugin +QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin) +16 (int (*)(...))QAccessibleBridgePlugin::metaObject +24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast +32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridgePlugin + size=16 align=8 + base size=16 base align=8 +QAccessibleBridgePlugin (0x0x7f5a258d5bc8) 0 + vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16u) + QObject (0x0x7f5a25909d20) 0 + primary-for QAccessibleBridgePlugin (0x0x7f5a258d5bc8) + +Vtable for QAccessibleObject +QAccessibleObject::_ZTV17QAccessibleObject: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleObject) +16 0u +24 0u +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleObject + size=16 align=8 + base size=16 base align=8 +QAccessibleObject (0x0x7f5a258d5c30) 0 + vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16u) + QAccessibleInterface (0x0x7f5a25909de0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f5a258d5c30) + +Vtable for QAccessibleApplication +QAccessibleApplication::_ZTV22QAccessibleApplication: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QAccessibleApplication) +16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleApplication::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleApplication::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleApplication::parent +88 (int (*)(...))QAccessibleApplication::child +96 (int (*)(...))QAccessibleApplication::childCount +104 (int (*)(...))QAccessibleApplication::indexOfChild +112 (int (*)(...))QAccessibleApplication::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))QAccessibleApplication::role +144 (int (*)(...))QAccessibleApplication::state +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleApplication + size=16 align=8 + base size=16 base align=8 +QAccessibleApplication (0x0x7f5a258d5c98) 0 + vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16u) + QAccessibleObject (0x0x7f5a258d5d00) 0 + primary-for QAccessibleApplication (0x0x7f5a258d5c98) + QAccessibleInterface (0x0x7f5a25909e40) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f5a258d5d00) + +Class QAccessiblePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessiblePlugin::QPrivateSignal (0x0x7f5a25909f00) 0 empty + +Vtable for QAccessiblePlugin +QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessiblePlugin) +16 (int (*)(...))QAccessiblePlugin::metaObject +24 (int (*)(...))QAccessiblePlugin::qt_metacast +32 (int (*)(...))QAccessiblePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessiblePlugin + size=16 align=8 + base size=16 base align=8 +QAccessiblePlugin (0x0x7f5a258d5d68) 0 + vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16u) + QObject (0x0x7f5a25909ea0) 0 + primary-for QAccessiblePlugin (0x0x7f5a258d5d68) + +Class QSurfaceFormat + size=8 align=8 + base size=8 base align=8 +QSurfaceFormat (0x0x7f5a25909f60) 0 + +Vtable for QSurface +QSurface::_ZTV8QSurface: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSurface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QSurface + size=24 align=8 + base size=24 base align=8 +QSurface (0x0x7f5a25693180) 0 + vptr=((& QSurface::_ZTV8QSurface) + 16u) + +Class QIcon + size=8 align=8 + base size=8 base align=8 +QIcon (0x0x7f5a25693300) 0 + +Class QCursor + size=8 align=8 + base size=8 base align=8 +QCursor (0x0x7f5a2575c6c0) 0 + +Class QWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWindow::QPrivateSignal (0x0x7f5a253e7cc0) 0 empty + +Vtable for QWindow +QWindow::_ZTV7QWindow: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWindow) +16 (int (*)(...))QWindow::metaObject +24 (int (*)(...))QWindow::qt_metacast +32 (int (*)(...))QWindow::qt_metacall +40 (int (*)(...))QWindow::~QWindow +48 (int (*)(...))QWindow::~QWindow +56 (int (*)(...))QWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI7QWindow) +312 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev +320 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QWindow + size=40 align=8 + base size=40 base align=8 +QWindow (0x0x7f5a253ff380) 0 + vptr=((& QWindow::_ZTV7QWindow) + 16u) + QObject (0x0x7f5a253e7c00) 0 + primary-for QWindow (0x0x7f5a253ff380) + QSurface (0x0x7f5a253e7c60) 16 + vptr=((& QWindow::_ZTV7QWindow) + 312u) + +Class QBackingStore + size=8 align=8 + base size=8 base align=8 +QBackingStore (0x0x7f5a253e7de0) 0 + +Vtable for QBitmap +QBitmap::_ZTV7QBitmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBitmap) +16 (int (*)(...))QBitmap::~QBitmap +24 (int (*)(...))QBitmap::~QBitmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QBitmap + size=32 align=8 + base size=32 base align=8 +QBitmap (0x0x7f5a253eadd0) 0 + vptr=((& QBitmap::_ZTV7QBitmap) + 16u) + QPixmap (0x0x7f5a253eae38) 0 + primary-for QBitmap (0x0x7f5a253eadd0) + QPaintDevice (0x0x7f5a253e7ea0) 0 + primary-for QPixmap (0x0x7f5a253eae38) + +Class QClipboard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QClipboard::QPrivateSignal (0x0x7f5a25479240) 0 empty + +Vtable for QClipboard +QClipboard::_ZTV10QClipboard: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QClipboard) +16 (int (*)(...))QClipboard::metaObject +24 (int (*)(...))QClipboard::qt_metacast +32 (int (*)(...))QClipboard::qt_metacall +40 (int (*)(...))QClipboard::~QClipboard +48 (int (*)(...))QClipboard::~QClipboard +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QClipboard + size=16 align=8 + base size=16 base align=8 +QClipboard (0x0x7f5a2547d0d0) 0 + vptr=((& QClipboard::_ZTV10QClipboard) + 16u) + QObject (0x0x7f5a254791e0) 0 + primary-for QClipboard (0x0x7f5a2547d0d0) + +Class QDesktopServices + size=1 align=1 + base size=0 base align=1 +QDesktopServices (0x0x7f5a254792a0) 0 empty + +Class QDrag::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDrag::QPrivateSignal (0x0x7f5a25479360) 0 empty + +Vtable for QDrag +QDrag::_ZTV5QDrag: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDrag) +16 (int (*)(...))QDrag::metaObject +24 (int (*)(...))QDrag::qt_metacast +32 (int (*)(...))QDrag::qt_metacall +40 (int (*)(...))QDrag::~QDrag +48 (int (*)(...))QDrag::~QDrag +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDrag + size=16 align=8 + base size=16 base align=8 +QDrag (0x0x7f5a2547d138) 0 + vptr=((& QDrag::_ZTV5QDrag) + 16u) + QObject (0x0x7f5a25479300) 0 + primary-for QDrag (0x0x7f5a2547d138) + +Class QFontInfo + size=8 align=8 + base size=8 base align=8 +QFontInfo (0x0x7f5a254793c0) 0 + +Class QFontMetrics + size=8 align=8 + base size=8 base align=8 +QFontMetrics (0x0x7f5a25479660) 0 + +Class QFontMetricsF + size=8 align=8 + base size=8 base align=8 +QFontMetricsF (0x0x7f5a25479960) 0 + +Class QGenericPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGenericPlugin::QPrivateSignal (0x0x7f5a2554ee40) 0 empty + +Vtable for QGenericPlugin +QGenericPlugin::_ZTV14QGenericPlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGenericPlugin) +16 (int (*)(...))QGenericPlugin::metaObject +24 (int (*)(...))QGenericPlugin::qt_metacast +32 (int (*)(...))QGenericPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGenericPlugin + size=16 align=8 + base size=16 base align=8 +QGenericPlugin (0x0x7f5a2547d9c0) 0 + vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16u) + QObject (0x0x7f5a2554ede0) 0 + primary-for QGenericPlugin (0x0x7f5a2547d9c0) + +Class QGenericPluginFactory + size=1 align=1 + base size=0 base align=1 +QGenericPluginFactory (0x0x7f5a2554eea0) 0 empty + +Class QInputMethod::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputMethod::QPrivateSignal (0x0x7f5a2554ef60) 0 empty + +Vtable for QInputMethod +QInputMethod::_ZTV12QInputMethod: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputMethod) +16 (int (*)(...))QInputMethod::metaObject +24 (int (*)(...))QInputMethod::qt_metacast +32 (int (*)(...))QInputMethod::qt_metacall +40 (int (*)(...))QInputMethod::~QInputMethod +48 (int (*)(...))QInputMethod::~QInputMethod +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputMethod + size=16 align=8 + base size=16 base align=8 +QInputMethod (0x0x7f5a2547da28) 0 + vptr=((& QInputMethod::_ZTV12QInputMethod) + 16u) + QObject (0x0x7f5a2554ef00) 0 + primary-for QInputMethod (0x0x7f5a2547da28) + +Class QGuiApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGuiApplication::QPrivateSignal (0x0x7f5a2525f060) 0 empty + +Vtable for QGuiApplication +QGuiApplication::_ZTV15QGuiApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGuiApplication) +16 (int (*)(...))QGuiApplication::metaObject +24 (int (*)(...))QGuiApplication::qt_metacast +32 (int (*)(...))QGuiApplication::qt_metacall +40 (int (*)(...))QGuiApplication::~QGuiApplication +48 (int (*)(...))QGuiApplication::~QGuiApplication +56 (int (*)(...))QGuiApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGuiApplication::notify +120 (int (*)(...))QGuiApplication::compressEvent + +Class QGuiApplication + size=16 align=8 + base size=16 base align=8 +QGuiApplication (0x0x7f5a2547da90) 0 + vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16u) + QCoreApplication (0x0x7f5a2547daf8) 0 + primary-for QGuiApplication (0x0x7f5a2547da90) + QObject (0x0x7f5a2525f000) 0 + primary-for QCoreApplication (0x0x7f5a2547daf8) + +Class QIconEngine::AvailableSizesArgument + size=16 align=8 + base size=16 base align=8 +QIconEngine::AvailableSizesArgument (0x0x7f5a2525f5a0) 0 + +Class QIconEngine::ScaledPixmapArgument + size=56 align=8 + base size=56 base align=8 +QIconEngine::ScaledPixmapArgument (0x0x7f5a2525f720) 0 + +Vtable for QIconEngine +QIconEngine::_ZTV11QIconEngine: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QIconEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QIconEngine::actualSize +48 (int (*)(...))QIconEngine::pixmap +56 (int (*)(...))QIconEngine::addPixmap +64 (int (*)(...))QIconEngine::addFile +72 (int (*)(...))QIconEngine::key +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QIconEngine::read +96 (int (*)(...))QIconEngine::write +104 (int (*)(...))QIconEngine::availableSizes +112 (int (*)(...))QIconEngine::iconName +120 (int (*)(...))QIconEngine::virtual_hook + +Class QIconEngine + size=8 align=8 + base size=8 base align=8 +QIconEngine (0x0x7f5a2525f540) 0 nearly-empty + vptr=((& QIconEngine::_ZTV11QIconEngine) + 16u) + +Class QIconEnginePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIconEnginePlugin::QPrivateSignal (0x0x7f5a2525f7e0) 0 empty + +Vtable for QIconEnginePlugin +QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QIconEnginePlugin) +16 (int (*)(...))QIconEnginePlugin::metaObject +24 (int (*)(...))QIconEnginePlugin::qt_metacast +32 (int (*)(...))QIconEnginePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QIconEnginePlugin + size=16 align=8 + base size=16 base align=8 +QIconEnginePlugin (0x0x7f5a25294068) 0 + vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16u) + QObject (0x0x7f5a2525f780) 0 + primary-for QIconEnginePlugin (0x0x7f5a25294068) + +Vtable for QImageIOHandler +QImageIOHandler::_ZTV15QImageIOHandler: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QImageIOHandler) +16 0u +24 0u +32 (int (*)(...))QImageIOHandler::name +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QImageIOHandler::write +64 (int (*)(...))QImageIOHandler::option +72 (int (*)(...))QImageIOHandler::setOption +80 (int (*)(...))QImageIOHandler::supportsOption +88 (int (*)(...))QImageIOHandler::jumpToNextImage +96 (int (*)(...))QImageIOHandler::jumpToImage +104 (int (*)(...))QImageIOHandler::loopCount +112 (int (*)(...))QImageIOHandler::imageCount +120 (int (*)(...))QImageIOHandler::nextImageDelay +128 (int (*)(...))QImageIOHandler::currentImageNumber +136 (int (*)(...))QImageIOHandler::currentImageRect + +Class QImageIOHandler + size=16 align=8 + base size=16 base align=8 +QImageIOHandler (0x0x7f5a2525f840) 0 + vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16u) + +Class QImageIOPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QImageIOPlugin::QPrivateSignal (0x0x7f5a2525f9c0) 0 empty + +Vtable for QImageIOPlugin +QImageIOPlugin::_ZTV14QImageIOPlugin: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QImageIOPlugin) +16 (int (*)(...))QImageIOPlugin::metaObject +24 (int (*)(...))QImageIOPlugin::qt_metacast +32 (int (*)(...))QImageIOPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QImageIOPlugin + size=16 align=8 + base size=16 base align=8 +QImageIOPlugin (0x0x7f5a252940d0) 0 + vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16u) + QObject (0x0x7f5a2525f960) 0 + primary-for QImageIOPlugin (0x0x7f5a252940d0) + +Class QImageReader + size=8 align=8 + base size=8 base align=8 +QImageReader (0x0x7f5a2525fba0) 0 + +Class QImageWriter + size=8 align=8 + base size=8 base align=8 +QImageWriter (0x0x7f5a2525fc00) 0 + +Class QVector3D + size=12 align=4 + base size=12 base align=4 +QVector3D (0x0x7f5a2525fc60) 0 + +Class QVector4D + size=16 align=4 + base size=16 base align=4 +QVector4D (0x0x7f5a2525ff00) 0 + +Class QQuaternion + size=16 align=4 + base size=16 base align=4 +QQuaternion (0x0x7f5a24fac1e0) 0 + +Class QMatrix4x4 + size=68 align=4 + base size=68 base align=4 +QMatrix4x4 (0x0x7f5a24fac7e0) 0 + +Class QMovie::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMovie::QPrivateSignal (0x0x7f5a24facf60) 0 empty + +Vtable for QMovie +QMovie::_ZTV6QMovie: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QMovie) +16 (int (*)(...))QMovie::metaObject +24 (int (*)(...))QMovie::qt_metacast +32 (int (*)(...))QMovie::qt_metacall +40 (int (*)(...))QMovie::~QMovie +48 (int (*)(...))QMovie::~QMovie +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QMovie + size=16 align=8 + base size=16 base align=8 +QMovie (0x0x7f5a250b42d8) 0 + vptr=((& QMovie::_ZTV6QMovie) + 16u) + QObject (0x0x7f5a24facf00) 0 + primary-for QMovie (0x0x7f5a250b42d8) + +Class QOffscreenSurface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOffscreenSurface::QPrivateSignal (0x0x7f5a24db60c0) 0 empty + +Vtable for QOffscreenSurface +QOffscreenSurface::_ZTV17QOffscreenSurface: 26u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOffscreenSurface) +16 (int (*)(...))QOffscreenSurface::metaObject +24 (int (*)(...))QOffscreenSurface::qt_metacast +32 (int (*)(...))QOffscreenSurface::qt_metacall +40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOffscreenSurface::surfaceType +120 (int (*)(...))QOffscreenSurface::format +128 (int (*)(...))QOffscreenSurface::size +136 (int (*)(...))QOffscreenSurface::surfaceHandle +144 (int (*)(...))-16 +152 (int (*)(...))(& _ZTI17QOffscreenSurface) +160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev +168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev +176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv +184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv +192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv +200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv + +Class QOffscreenSurface + size=40 align=8 + base size=40 base align=8 +QOffscreenSurface (0x0x7f5a25175b60) 0 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16u) + QObject (0x0x7f5a24db6000) 0 + primary-for QOffscreenSurface (0x0x7f5a25175b60) + QSurface (0x0x7f5a24db6060) 16 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160u) + +Class QOpenGLBuffer + size=8 align=8 + base size=8 base align=8 +QOpenGLBuffer (0x0x7f5a24db6180) 0 + +Class QOpenGLVersionStatus + size=12 align=4 + base size=12 base align=4 +QOpenGLVersionStatus (0x0x7f5a24db6360) 0 + +Class QOpenGLVersionFunctionsBackend + size=16 align=8 + base size=12 base align=8 +QOpenGLVersionFunctionsBackend (0x0x7f5a24b1be40) 0 + +Class QOpenGLVersionFunctionsStorage + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionFunctionsStorage (0x0x7f5a24b1bea0) 0 + +Class QAbstractOpenGLFunctionsPrivate + size=16 align=8 + base size=9 base align=8 +QAbstractOpenGLFunctionsPrivate (0x0x7f5a24b1bf00) 0 + +Vtable for QAbstractOpenGLFunctions +QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions) +16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions + +Class QAbstractOpenGLFunctions + size=16 align=8 + base size=16 base align=8 +QAbstractOpenGLFunctions (0x0x7f5a24b1bf60) 0 + vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16u) + +Class QOpenGLFunctions_1_0_CoreBackend::Functions + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7f5a24b67060) 0 + +Class QOpenGLFunctions_1_0_CoreBackend + size=400 align=8 + base size=400 base align=8 +QOpenGLFunctions_1_0_CoreBackend (0x0x7f5a24b3f548) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67000) 0 + +Class QOpenGLFunctions_1_1_CoreBackend::Functions + size=128 align=8 + base size=128 base align=8 +QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7f5a24b67180) 0 + +Class QOpenGLFunctions_1_1_CoreBackend + size=144 align=8 + base size=144 base align=8 +QOpenGLFunctions_1_1_CoreBackend (0x0x7f5a24b3f5b0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67120) 0 + +Class QOpenGLFunctions_1_2_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7f5a24b672a0) 0 + +Class QOpenGLFunctions_1_2_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_1_2_CoreBackend (0x0x7f5a24b3f618) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67240) 0 + +Class QOpenGLFunctions_1_3_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7f5a24b673c0) 0 + +Class QOpenGLFunctions_1_3_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_1_3_CoreBackend (0x0x7f5a24b3f680) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67360) 0 + +Class QOpenGLFunctions_1_4_CoreBackend::Functions + size=56 align=8 + base size=56 base align=8 +QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7f5a24b67540) 0 + +Class QOpenGLFunctions_1_4_CoreBackend + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_4_CoreBackend (0x0x7f5a24b3f6e8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b674e0) 0 + +Class QOpenGLFunctions_1_5_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7f5a24b67660) 0 + +Class QOpenGLFunctions_1_5_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_1_5_CoreBackend (0x0x7f5a24b3f750) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67600) 0 + +Class QOpenGLFunctions_2_0_CoreBackend::Functions + size=744 align=8 + base size=744 base align=8 +QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7f5a24b67780) 0 + +Class QOpenGLFunctions_2_0_CoreBackend + size=760 align=8 + base size=760 base align=8 +QOpenGLFunctions_2_0_CoreBackend (0x0x7f5a24b3f7b8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67720) 0 + +Class QOpenGLFunctions_2_1_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7f5a24b678a0) 0 + +Class QOpenGLFunctions_2_1_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_2_1_CoreBackend (0x0x7f5a24b3f820) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67840) 0 + +Class QOpenGLFunctions_3_0_CoreBackend::Functions + size=672 align=8 + base size=672 base align=8 +QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7f5a24b679c0) 0 + +Class QOpenGLFunctions_3_0_CoreBackend + size=688 align=8 + base size=688 base align=8 +QOpenGLFunctions_3_0_CoreBackend (0x0x7f5a24b3f888) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67960) 0 + +Class QOpenGLFunctions_3_1_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7f5a24b67ae0) 0 + +Class QOpenGLFunctions_3_1_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_3_1_CoreBackend (0x0x7f5a24b3f8f0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67a80) 0 + +Class QOpenGLFunctions_3_2_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7f5a24b67c00) 0 + +Class QOpenGLFunctions_3_2_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_3_2_CoreBackend (0x0x7f5a24b3f958) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67ba0) 0 + +Class QOpenGLFunctions_3_3_CoreBackend::Functions + size=464 align=8 + base size=464 base align=8 +QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7f5a24b67d20) 0 + +Class QOpenGLFunctions_3_3_CoreBackend + size=480 align=8 + base size=480 base align=8 +QOpenGLFunctions_3_3_CoreBackend (0x0x7f5a24b3f9c0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67cc0) 0 + +Class QOpenGLFunctions_4_0_CoreBackend::Functions + size=368 align=8 + base size=368 base align=8 +QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7f5a24b67e40) 0 + +Class QOpenGLFunctions_4_0_CoreBackend + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_4_0_CoreBackend (0x0x7f5a24b3fa28) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67de0) 0 + +Class QOpenGLFunctions_4_1_CoreBackend::Functions + size=704 align=8 + base size=704 base align=8 +QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7f5a24b67f60) 0 + +Class QOpenGLFunctions_4_1_CoreBackend + size=720 align=8 + base size=720 base align=8 +QOpenGLFunctions_4_1_CoreBackend (0x0x7f5a24b3fa90) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a24b67f00) 0 + +Class QOpenGLFunctions_4_2_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7f5a2485e0c0) 0 + +Class QOpenGLFunctions_4_2_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_2_CoreBackend (0x0x7f5a24b3faf8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485e060) 0 + +Class QOpenGLFunctions_4_3_CoreBackend::Functions + size=344 align=8 + base size=344 base align=8 +QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7f5a2485e1e0) 0 + +Class QOpenGLFunctions_4_3_CoreBackend + size=360 align=8 + base size=360 base align=8 +QOpenGLFunctions_4_3_CoreBackend (0x0x7f5a24b3fb60) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485e180) 0 + +Class QOpenGLFunctions_4_4_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7f5a2485e300) 0 + +Class QOpenGLFunctions_4_4_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_4_4_CoreBackend (0x0x7f5a24b3fbc8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485e2a0) 0 + +Class QOpenGLFunctions_4_5_CoreBackend::Functions + size=848 align=8 + base size=848 base align=8 +QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7f5a2485e480) 0 + +Class QOpenGLFunctions_4_5_CoreBackend + size=864 align=8 + base size=864 base align=8 +QOpenGLFunctions_4_5_CoreBackend (0x0x7f5a24b3fc30) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485e420) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions + size=2064 align=8 + base size=2064 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7f5a2485e5a0) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend + size=2080 align=8 + base size=2080 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7f5a24b3fc98) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485e540) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions + size=136 align=8 + base size=136 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7f5a2485e6c0) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7f5a24b3fd00) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485e660) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7f5a2485e7e0) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend + size=272 align=8 + base size=272 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7f5a24b3fd68) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485e780) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions + size=296 align=8 + base size=296 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7f5a2485e900) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend + size=312 align=8 + base size=312 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7f5a24b3fdd0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485e8a0) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7f5a2485ea20) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend + size=320 align=8 + base size=320 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7f5a24b3fe38) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485e9c0) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions + size=288 align=8 + base size=288 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7f5a2485eb40) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7f5a24b3fea0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485eae0) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions + size=160 align=8 + base size=160 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7f5a2485ec60) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend + size=176 align=8 + base size=176 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7f5a24b3ff08) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485ec00) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions + size=240 align=8 + base size=240 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7f5a2485ed80) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7f5a24b3ff70) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485ed20) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7f5a2485eea0) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7f5a24972000) 0 + QOpenGLVersionFunctionsBackend (0x0x7f5a2485ee40) 0 + +Class QOpenGLVersionProfile + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionProfile (0x0x7f5a2485ef60) 0 + +Class QOpenGLContextGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContextGroup::QPrivateSignal (0x0x7f5a2498c960) 0 empty + +Vtable for QOpenGLContextGroup +QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QOpenGLContextGroup) +16 (int (*)(...))QOpenGLContextGroup::metaObject +24 (int (*)(...))QOpenGLContextGroup::qt_metacast +32 (int (*)(...))QOpenGLContextGroup::qt_metacall +40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContextGroup + size=16 align=8 + base size=16 base align=8 +QOpenGLContextGroup (0x0x7f5a24972a28) 0 + vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16u) + QObject (0x0x7f5a2498c900) 0 + primary-for QOpenGLContextGroup (0x0x7f5a24972a28) + +Class QOpenGLContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContext::QPrivateSignal (0x0x7f5a2498ca20) 0 empty + +Vtable for QOpenGLContext +QOpenGLContext::_ZTV14QOpenGLContext: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QOpenGLContext) +16 (int (*)(...))QOpenGLContext::metaObject +24 (int (*)(...))QOpenGLContext::qt_metacast +32 (int (*)(...))QOpenGLContext::qt_metacall +40 (int (*)(...))QOpenGLContext::~QOpenGLContext +48 (int (*)(...))QOpenGLContext::~QOpenGLContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContext + size=16 align=8 + base size=16 base align=8 +QOpenGLContext (0x0x7f5a24972a90) 0 + vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16u) + QObject (0x0x7f5a2498c9c0) 0 + primary-for QOpenGLContext (0x0x7f5a24972a90) + +Class QOpenGLDebugMessage + size=8 align=8 + base size=8 base align=8 +QOpenGLDebugMessage (0x0x7f5a2498ca80) 0 + +Class QOpenGLDebugLogger::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLDebugLogger::QPrivateSignal (0x0x7f5a2461d2a0) 0 empty + +Vtable for QOpenGLDebugLogger +QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger) +16 (int (*)(...))QOpenGLDebugLogger::metaObject +24 (int (*)(...))QOpenGLDebugLogger::qt_metacast +32 (int (*)(...))QOpenGLDebugLogger::qt_metacall +40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLDebugLogger + size=16 align=8 + base size=16 base align=8 +QOpenGLDebugLogger (0x0x7f5a24972f08) 0 + vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16u) + QObject (0x0x7f5a2461d240) 0 + primary-for QOpenGLDebugLogger (0x0x7f5a24972f08) + +Class QOpenGLFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLFunctions (0x0x7f5a2461d420) 0 + +Class QOpenGLFunctionsPrivate::Functions + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate::Functions (0x0x7f5a2461d660) 0 + +Class QOpenGLFunctionsPrivate + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate (0x0x7f5a2461d600) 0 + +Class QOpenGLExtraFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLExtraFunctions (0x0x7f5a246e61a0) 0 + QOpenGLFunctions (0x0x7f5a243efd80) 0 + +Class QOpenGLExtraFunctionsPrivate::Functions + size=1728 align=8 + base size=1728 base align=8 +QOpenGLExtraFunctionsPrivate::Functions (0x0x7f5a243efe40) 0 + +Class QOpenGLExtraFunctionsPrivate + size=2880 align=8 + base size=2880 base align=8 +QOpenGLExtraFunctionsPrivate (0x0x7f5a246e6208) 0 + QOpenGLFunctionsPrivate (0x0x7f5a243efde0) 0 + +Vtable for QOpenGLFramebufferObject +QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject) +16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject +24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject + +Class QOpenGLFramebufferObject + size=16 align=8 + base size=16 base align=8 +QOpenGLFramebufferObject (0x0x7f5a2425a540) 0 + vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16u) + +Class QOpenGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QOpenGLFramebufferObjectFormat (0x0x7f5a2425a660) 0 + +Vtable for QOpenGLPaintDevice +QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice) +16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +32 (int (*)(...))QOpenGLPaintDevice::devType +40 (int (*)(...))QOpenGLPaintDevice::paintEngine +48 (int (*)(...))QOpenGLPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget + +Class QOpenGLPaintDevice + size=32 align=8 + base size=32 base align=8 +QOpenGLPaintDevice (0x0x7f5a246e64e0) 0 + vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16u) + QPaintDevice (0x0x7f5a2425a6c0) 0 + primary-for QOpenGLPaintDevice (0x0x7f5a246e64e0) + +Class QOpenGLPixelTransferOptions + size=8 align=8 + base size=8 base align=8 +QOpenGLPixelTransferOptions (0x0x7f5a2425a7e0) 0 + +Class QOpenGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShader::QPrivateSignal (0x0x7f5a2425ab40) 0 empty + +Vtable for QOpenGLShader +QOpenGLShader::_ZTV13QOpenGLShader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLShader) +16 (int (*)(...))QOpenGLShader::metaObject +24 (int (*)(...))QOpenGLShader::qt_metacast +32 (int (*)(...))QOpenGLShader::qt_metacall +40 (int (*)(...))QOpenGLShader::~QOpenGLShader +48 (int (*)(...))QOpenGLShader::~QOpenGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLShader + size=16 align=8 + base size=16 base align=8 +QOpenGLShader (0x0x7f5a246e66e8) 0 + vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16u) + QObject (0x0x7f5a2425aae0) 0 + primary-for QOpenGLShader (0x0x7f5a246e66e8) + +Class QOpenGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShaderProgram::QPrivateSignal (0x0x7f5a2425ad80) 0 empty + +Vtable for QOpenGLShaderProgram +QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram) +16 (int (*)(...))QOpenGLShaderProgram::metaObject +24 (int (*)(...))QOpenGLShaderProgram::qt_metacast +32 (int (*)(...))QOpenGLShaderProgram::qt_metacall +40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOpenGLShaderProgram::link + +Class QOpenGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QOpenGLShaderProgram (0x0x7f5a246e6820) 0 + vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16u) + QObject (0x0x7f5a2425ad20) 0 + primary-for QOpenGLShaderProgram (0x0x7f5a246e6820) + +Class QOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QOpenGLTexture (0x0x7f5a2425ade0) 0 + +Class QOpenGLTextureBlitter + size=8 align=8 + base size=8 base align=8 +QOpenGLTextureBlitter (0x0x7f5a23fce0c0) 0 + +Class QOpenGLTimerQuery::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimerQuery::QPrivateSignal (0x0x7f5a23fce240) 0 empty + +Vtable for QOpenGLTimerQuery +QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery) +16 (int (*)(...))QOpenGLTimerQuery::metaObject +24 (int (*)(...))QOpenGLTimerQuery::qt_metacast +32 (int (*)(...))QOpenGLTimerQuery::qt_metacall +40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimerQuery + size=16 align=8 + base size=16 base align=8 +QOpenGLTimerQuery (0x0x7f5a246e6958) 0 + vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16u) + QObject (0x0x7f5a23fce1e0) 0 + primary-for QOpenGLTimerQuery (0x0x7f5a246e6958) + +Class QOpenGLTimeMonitor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimeMonitor::QPrivateSignal (0x0x7f5a23fce300) 0 empty + +Vtable for QOpenGLTimeMonitor +QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor) +16 (int (*)(...))QOpenGLTimeMonitor::metaObject +24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast +32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall +40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimeMonitor + size=16 align=8 + base size=16 base align=8 +QOpenGLTimeMonitor (0x0x7f5a246e69c0) 0 + vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16u) + QObject (0x0x7f5a23fce2a0) 0 + primary-for QOpenGLTimeMonitor (0x0x7f5a246e69c0) + +Class QOpenGLVertexArrayObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLVertexArrayObject::QPrivateSignal (0x0x7f5a23fce3c0) 0 empty + +Class QOpenGLVertexArrayObject::Binder + size=8 align=8 + base size=8 base align=8 +QOpenGLVertexArrayObject::Binder (0x0x7f5a23fce420) 0 + +Vtable for QOpenGLVertexArrayObject +QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject) +16 (int (*)(...))QOpenGLVertexArrayObject::metaObject +24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast +32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall +40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLVertexArrayObject + size=16 align=8 + base size=16 base align=8 +QOpenGLVertexArrayObject (0x0x7f5a246e6a28) 0 + vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16u) + QObject (0x0x7f5a23fce360) 0 + primary-for QOpenGLVertexArrayObject (0x0x7f5a246e6a28) + +Class QPaintDeviceWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPaintDeviceWindow::QPrivateSignal (0x0x7f5a23fce5a0) 0 empty + +Vtable for QPaintDeviceWindow +QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 58u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +16 (int (*)(...))QPaintDeviceWindow::metaObject +24 (int (*)(...))QPaintDeviceWindow::qt_metacast +32 (int (*)(...))QPaintDeviceWindow::qt_metacall +40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QPaintDeviceWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))-16 +328 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +336 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev +344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +384 (int (*)(...))-40 +392 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +400 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev +408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev +416 (int (*)(...))QPaintDevice::devType +424 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE +440 (int (*)(...))QPaintDevice::initPainter +448 (int (*)(...))QPaintDevice::redirected +456 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDeviceWindow + size=64 align=8 + base size=64 base align=8 +QPaintDeviceWindow (0x0x7f5a24036a80) 0 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16u) + QWindow (0x0x7f5a24036af0) 0 + primary-for QPaintDeviceWindow (0x0x7f5a24036a80) + QObject (0x0x7f5a23fce480) 0 + primary-for QWindow (0x0x7f5a24036af0) + QSurface (0x0x7f5a23fce4e0) 16 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 336u) + QPaintDevice (0x0x7f5a23fce540) 40 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 400u) + +Class QOpenGLWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWindow::QPrivateSignal (0x0x7f5a23fce720) 0 empty + +Vtable for QOpenGLWindow +QOpenGLWindow::_ZTV13QOpenGLWindow: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWindow) +16 (int (*)(...))QOpenGLWindow::metaObject +24 (int (*)(...))QOpenGLWindow::qt_metacast +32 (int (*)(...))QOpenGLWindow::qt_metacall +40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QOpenGLWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QOpenGLWindow::paintEvent +304 (int (*)(...))QOpenGLWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QOpenGLWindow::initializeGL +328 (int (*)(...))QOpenGLWindow::resizeGL +336 (int (*)(...))QOpenGLWindow::paintGL +344 (int (*)(...))QOpenGLWindow::paintUnderGL +352 (int (*)(...))QOpenGLWindow::paintOverGL +360 (int (*)(...))QOpenGLWindow::redirected +368 (int (*)(...))-16 +376 (int (*)(...))(& _ZTI13QOpenGLWindow) +384 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev +392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev +400 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +408 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +416 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +424 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +432 (int (*)(...))-40 +440 (int (*)(...))(& _ZTI13QOpenGLWindow) +448 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev +456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev +464 (int (*)(...))QPaintDevice::devType +472 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +480 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QPaintDevice::initPainter +496 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint +504 (int (*)(...))QPaintDevice::sharedPainter + +Class QOpenGLWindow + size=64 align=8 + base size=64 base align=8 +QOpenGLWindow (0x0x7f5a246e6af8) 0 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16u) + QPaintDeviceWindow (0x0x7f5a24036e70) 0 + primary-for QOpenGLWindow (0x0x7f5a246e6af8) + QWindow (0x0x7f5a24036ee0) 0 + primary-for QPaintDeviceWindow (0x0x7f5a24036e70) + QObject (0x0x7f5a23fce600) 0 + primary-for QWindow (0x0x7f5a24036ee0) + QSurface (0x0x7f5a23fce660) 16 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 384u) + QPaintDevice (0x0x7f5a23fce6c0) 40 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 448u) + +Class QPageSize + size=8 align=8 + base size=8 base align=8 +QPageSize (0x0x7f5a23fce780) 0 + +Class QPageLayout + size=8 align=8 + base size=8 base align=8 +QPageLayout (0x0x7f5a240b3180) 0 + +Class QPagedPaintDevice::Margins + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice::Margins (0x0x7f5a240b3ba0) 0 + +Vtable for QPagedPaintDevice +QPagedPaintDevice::_ZTV17QPagedPaintDevice: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QPagedPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QPagedPaintDevice::setPageSize +96 (int (*)(...))QPagedPaintDevice::setPageSizeMM +104 (int (*)(...))QPagedPaintDevice::setMargins + +Class QPagedPaintDevice + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice (0x0x7f5a240a0820) 0 + vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16u) + QPaintDevice (0x0x7f5a240b3b40) 0 + primary-for QPagedPaintDevice (0x0x7f5a240a0820) + +Class QPainter::PixmapFragment + size=80 align=8 + base size=80 base align=8 +QPainter::PixmapFragment (0x0x7f5a240b3c60) 0 + +Class QPainter + size=8 align=8 + base size=8 base align=8 +QPainter (0x0x7f5a240b3c00) 0 + +Class QTextItem + size=1 align=1 + base size=0 base align=1 +QTextItem (0x0x7f5a23da7a80) 0 empty + +Vtable for QPaintEngine +QPaintEngine::_ZTV12QPaintEngine: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QPaintEngine::drawRects +64 (int (*)(...))QPaintEngine::drawRects +72 (int (*)(...))QPaintEngine::drawLines +80 (int (*)(...))QPaintEngine::drawLines +88 (int (*)(...))QPaintEngine::drawEllipse +96 (int (*)(...))QPaintEngine::drawEllipse +104 (int (*)(...))QPaintEngine::drawPath +112 (int (*)(...))QPaintEngine::drawPoints +120 (int (*)(...))QPaintEngine::drawPoints +128 (int (*)(...))QPaintEngine::drawPolygon +136 (int (*)(...))QPaintEngine::drawPolygon +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QPaintEngine::drawTextItem +160 (int (*)(...))QPaintEngine::drawTiledPixmap +168 (int (*)(...))QPaintEngine::drawImage +176 (int (*)(...))QPaintEngine::coordinateOffset +184 (int (*)(...))__cxa_pure_virtual + +Class QPaintEngine + size=32 align=8 + base size=32 base align=8 +QPaintEngine (0x0x7f5a23da7d20) 0 + vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16u) + +Class QPaintEngineState + size=4 align=4 + base size=4 base align=4 +QPaintEngineState (0x0x7f5a23f73000) 0 + +Class QPdfWriter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPdfWriter::QPrivateSignal (0x0x7f5a23f73420) 0 empty + +Vtable for QPdfWriter +QPdfWriter::_ZTV10QPdfWriter: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QPdfWriter) +16 (int (*)(...))QPdfWriter::metaObject +24 (int (*)(...))QPdfWriter::qt_metacast +32 (int (*)(...))QPdfWriter::qt_metacall +40 (int (*)(...))QPdfWriter::~QPdfWriter +48 (int (*)(...))QPdfWriter::~QPdfWriter +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPdfWriter::newPage +120 (int (*)(...))QPdfWriter::setPageSize +128 (int (*)(...))QPdfWriter::setPageSizeMM +136 (int (*)(...))QPdfWriter::setMargins +144 (int (*)(...))QPdfWriter::paintEngine +152 (int (*)(...))QPdfWriter::metric +160 (int (*)(...))-16 +168 (int (*)(...))(& _ZTI10QPdfWriter) +176 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev +184 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev +192 (int (*)(...))QPaintDevice::devType +200 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv +208 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE +216 (int (*)(...))QPaintDevice::initPainter +224 (int (*)(...))QPaintDevice::redirected +232 (int (*)(...))QPaintDevice::sharedPainter +240 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv +248 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter11setPageSizeEN17QPagedPaintDevice8PageSizeE +256 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter13setPageSizeMMERK6QSizeF +264 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter10setMarginsERKN17QPagedPaintDevice7MarginsE + +Class QPdfWriter + size=48 align=8 + base size=48 base align=8 +QPdfWriter (0x0x7f5a23bb3e00) 0 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16u) + QObject (0x0x7f5a23f73360) 0 + primary-for QPdfWriter (0x0x7f5a23bb3e00) + QPagedPaintDevice (0x0x7f5a23f02888) 16 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 176u) + QPaintDevice (0x0x7f5a23f733c0) 16 + primary-for QPagedPaintDevice (0x0x7f5a23f02888) + +Vtable for QPicture +QPicture::_ZTV8QPicture: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPicture) +16 (int (*)(...))QPicture::~QPicture +24 (int (*)(...))QPicture::~QPicture +32 (int (*)(...))QPicture::devType +40 (int (*)(...))QPicture::paintEngine +48 (int (*)(...))QPicture::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPicture::setData + +Class QPicture + size=32 align=8 + base size=32 base align=8 +QPicture (0x0x7f5a23f028f0) 0 + vptr=((& QPicture::_ZTV8QPicture) + 16u) + QPaintDevice (0x0x7f5a23f735a0) 0 + primary-for QPicture (0x0x7f5a23f028f0) + +Class QPictureIO + size=8 align=8 + base size=8 base align=8 +QPictureIO (0x0x7f5a23f738a0) 0 + +Class QPictureFormatPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPictureFormatPlugin::QPrivateSignal (0x0x7f5a23f73960) 0 empty + +Vtable for QPictureFormatPlugin +QPictureFormatPlugin::_ZTV20QPictureFormatPlugin: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QPictureFormatPlugin) +16 (int (*)(...))QPictureFormatPlugin::metaObject +24 (int (*)(...))QPictureFormatPlugin::qt_metacast +32 (int (*)(...))QPictureFormatPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPictureFormatPlugin::loadPicture +120 (int (*)(...))QPictureFormatPlugin::savePicture +128 (int (*)(...))__cxa_pure_virtual + +Class QPictureFormatPlugin + size=16 align=8 + base size=16 base align=8 +QPictureFormatPlugin (0x0x7f5a23f02af8) 0 + vptr=((& QPictureFormatPlugin::_ZTV20QPictureFormatPlugin) + 16u) + QObject (0x0x7f5a23f73900) 0 + primary-for QPictureFormatPlugin (0x0x7f5a23f02af8) + +Class QPixmapCache::Key + size=8 align=8 + base size=8 base align=8 +QPixmapCache::Key (0x0x7f5a23f73a20) 0 + +Class QPixmapCache + size=1 align=1 + base size=0 base align=1 +QPixmapCache (0x0x7f5a23f739c0) 0 empty + +Class QRasterWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRasterWindow::QPrivateSignal (0x0x7f5a23cb4ba0) 0 empty + +Vtable for QRasterWindow +QRasterWindow::_ZTV13QRasterWindow: 59u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QRasterWindow) +16 (int (*)(...))QRasterWindow::metaObject +24 (int (*)(...))QRasterWindow::qt_metacast +32 (int (*)(...))QRasterWindow::qt_metacall +40 (int (*)(...))QRasterWindow::~QRasterWindow +48 (int (*)(...))QRasterWindow::~QRasterWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QRasterWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QRasterWindow::redirected +328 (int (*)(...))-16 +336 (int (*)(...))(& _ZTI13QRasterWindow) +344 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev +352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +392 (int (*)(...))-40 +400 (int (*)(...))(& _ZTI13QRasterWindow) +408 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev +416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev +424 (int (*)(...))QPaintDevice::devType +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +440 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE +448 (int (*)(...))QPaintDevice::initPainter +456 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint +464 (int (*)(...))QPaintDevice::sharedPainter + +Class QRasterWindow + size=64 align=8 + base size=64 base align=8 +QRasterWindow (0x0x7f5a23cc1208) 0 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16u) + QPaintDeviceWindow (0x0x7f5a23cbbbd0) 0 + primary-for QRasterWindow (0x0x7f5a23cc1208) + QWindow (0x0x7f5a23cbbc40) 0 + primary-for QPaintDeviceWindow (0x0x7f5a23cbbbd0) + QObject (0x0x7f5a23cb4a80) 0 + primary-for QWindow (0x0x7f5a23cbbc40) + QSurface (0x0x7f5a23cb4ae0) 16 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 344u) + QPaintDevice (0x0x7f5a23cb4b40) 40 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 408u) + +Class QScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScreen::QPrivateSignal (0x0x7f5a23cb4c60) 0 empty + +Vtable for QScreen +QScreen::_ZTV7QScreen: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QScreen) +16 (int (*)(...))QScreen::metaObject +24 (int (*)(...))QScreen::qt_metacast +32 (int (*)(...))QScreen::qt_metacall +40 (int (*)(...))QScreen::~QScreen +48 (int (*)(...))QScreen::~QScreen +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScreen + size=16 align=8 + base size=16 base align=8 +QScreen (0x0x7f5a23cc12d8) 0 + vptr=((& QScreen::_ZTV7QScreen) + 16u) + QObject (0x0x7f5a23cb4c00) 0 + primary-for QScreen (0x0x7f5a23cc12d8) + +Class QSessionManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSessionManager::QPrivateSignal (0x0x7f5a23cb4d20) 0 empty + +Vtable for QSessionManager +QSessionManager::_ZTV15QSessionManager: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSessionManager) +16 (int (*)(...))QSessionManager::metaObject +24 (int (*)(...))QSessionManager::qt_metacast +32 (int (*)(...))QSessionManager::qt_metacall +40 (int (*)(...))QSessionManager::~QSessionManager +48 (int (*)(...))QSessionManager::~QSessionManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSessionManager + size=16 align=8 + base size=16 base align=8 +QSessionManager (0x0x7f5a23cc1340) 0 + vptr=((& QSessionManager::_ZTV15QSessionManager) + 16u) + QObject (0x0x7f5a23cb4cc0) 0 + primary-for QSessionManager (0x0x7f5a23cc1340) + +Vtable for QStandardItem +QStandardItem::_ZTV13QStandardItem: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStandardItem) +16 (int (*)(...))QStandardItem::~QStandardItem +24 (int (*)(...))QStandardItem::~QStandardItem +32 (int (*)(...))QStandardItem::data +40 (int (*)(...))QStandardItem::setData +48 (int (*)(...))QStandardItem::clone +56 (int (*)(...))QStandardItem::type +64 (int (*)(...))QStandardItem::read +72 (int (*)(...))QStandardItem::write +80 (int (*)(...))QStandardItem::operator< + +Class QStandardItem + size=16 align=8 + base size=16 base align=8 +QStandardItem (0x0x7f5a23cb4d80) 0 + vptr=((& QStandardItem::_ZTV13QStandardItem) + 16u) + +Class QStandardItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStandardItemModel::QPrivateSignal (0x0x7f5a23d524e0) 0 empty + +Vtable for QStandardItemModel +QStandardItemModel::_ZTV18QStandardItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QStandardItemModel) +16 (int (*)(...))QStandardItemModel::metaObject +24 (int (*)(...))QStandardItemModel::qt_metacast +32 (int (*)(...))QStandardItemModel::qt_metacall +40 (int (*)(...))QStandardItemModel::~QStandardItemModel +48 (int (*)(...))QStandardItemModel::~QStandardItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStandardItemModel::index +120 (int (*)(...))QStandardItemModel::parent +128 (int (*)(...))QStandardItemModel::sibling +136 (int (*)(...))QStandardItemModel::rowCount +144 (int (*)(...))QStandardItemModel::columnCount +152 (int (*)(...))QStandardItemModel::hasChildren +160 (int (*)(...))QStandardItemModel::data +168 (int (*)(...))QStandardItemModel::setData +176 (int (*)(...))QStandardItemModel::headerData +184 (int (*)(...))QStandardItemModel::setHeaderData +192 (int (*)(...))QStandardItemModel::itemData +200 (int (*)(...))QStandardItemModel::setItemData +208 (int (*)(...))QStandardItemModel::mimeTypes +216 (int (*)(...))QStandardItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QStandardItemModel::dropMimeData +240 (int (*)(...))QStandardItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStandardItemModel::insertRows +264 (int (*)(...))QStandardItemModel::insertColumns +272 (int (*)(...))QStandardItemModel::removeRows +280 (int (*)(...))QStandardItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStandardItemModel::flags +328 (int (*)(...))QStandardItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStandardItemModel + size=16 align=8 + base size=16 base align=8 +QStandardItemModel (0x0x7f5a23cc19c0) 0 + vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16u) + QAbstractItemModel (0x0x7f5a23cc1a28) 0 + primary-for QStandardItemModel (0x0x7f5a23cc19c0) + QObject (0x0x7f5a23d52480) 0 + primary-for QAbstractItemModel (0x0x7f5a23cc1a28) + +Class QStaticText + size=8 align=8 + base size=8 base align=8 +QStaticText (0x0x7f5a23d52540) 0 + +Class QStyleHints::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyleHints::QPrivateSignal (0x0x7f5a23d529c0) 0 empty + +Vtable for QStyleHints +QStyleHints::_ZTV11QStyleHints: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QStyleHints) +16 (int (*)(...))QStyleHints::metaObject +24 (int (*)(...))QStyleHints::qt_metacast +32 (int (*)(...))QStyleHints::qt_metacall +40 (int (*)(...))QStyleHints::~QStyleHints +48 (int (*)(...))QStyleHints::~QStyleHints +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QStyleHints + size=16 align=8 + base size=16 base align=8 +QStyleHints (0x0x7f5a23cc1c30) 0 + vptr=((& QStyleHints::_ZTV11QStyleHints) + 16u) + QObject (0x0x7f5a23d52960) 0 + primary-for QStyleHints (0x0x7f5a23cc1c30) + +Class QTextObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextObject::QPrivateSignal (0x0x7f5a23d52a80) 0 empty + +Vtable for QTextObject +QTextObject::_ZTV11QTextObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextObject) +16 (int (*)(...))QTextObject::metaObject +24 (int (*)(...))QTextObject::qt_metacast +32 (int (*)(...))QTextObject::qt_metacall +40 (int (*)(...))QTextObject::~QTextObject +48 (int (*)(...))QTextObject::~QTextObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextObject + size=16 align=8 + base size=16 base align=8 +QTextObject (0x0x7f5a23cc1c98) 0 + vptr=((& QTextObject::_ZTV11QTextObject) + 16u) + QObject (0x0x7f5a23d52a20) 0 + primary-for QTextObject (0x0x7f5a23cc1c98) + +Class QTextBlockGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBlockGroup::QPrivateSignal (0x0x7f5a23d52b40) 0 empty + +Vtable for QTextBlockGroup +QTextBlockGroup::_ZTV15QTextBlockGroup: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTextBlockGroup) +16 (int (*)(...))QTextBlockGroup::metaObject +24 (int (*)(...))QTextBlockGroup::qt_metacast +32 (int (*)(...))QTextBlockGroup::qt_metacall +40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextBlockGroup + size=16 align=8 + base size=16 base align=8 +QTextBlockGroup (0x0x7f5a23cc1d00) 0 + vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16u) + QTextObject (0x0x7f5a23cc1d68) 0 + primary-for QTextBlockGroup (0x0x7f5a23cc1d00) + QObject (0x0x7f5a23d52ae0) 0 + primary-for QTextObject (0x0x7f5a23cc1d68) + +Vtable for QTextFrameLayoutData +QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextFrameLayoutData) +16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData +24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData + +Class QTextFrameLayoutData + size=8 align=8 + base size=8 base align=8 +QTextFrameLayoutData (0x0x7f5a23d52ba0) 0 nearly-empty + vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16u) + +Class QTextFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextFrame::QPrivateSignal (0x0x7f5a23d52c60) 0 empty + +Class QTextFrame::iterator + size=32 align=8 + base size=28 base align=8 +QTextFrame::iterator (0x0x7f5a23d52cc0) 0 + +Vtable for QTextFrame +QTextFrame::_ZTV10QTextFrame: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextFrame) +16 (int (*)(...))QTextFrame::metaObject +24 (int (*)(...))QTextFrame::qt_metacast +32 (int (*)(...))QTextFrame::qt_metacall +40 (int (*)(...))QTextFrame::~QTextFrame +48 (int (*)(...))QTextFrame::~QTextFrame +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextFrame + size=16 align=8 + base size=16 base align=8 +QTextFrame (0x0x7f5a23cc1dd0) 0 + vptr=((& QTextFrame::_ZTV10QTextFrame) + 16u) + QTextObject (0x0x7f5a23cc1e38) 0 + primary-for QTextFrame (0x0x7f5a23cc1dd0) + QObject (0x0x7f5a23d52c00) 0 + primary-for QTextObject (0x0x7f5a23cc1e38) + +Vtable for QTextBlockUserData +QTextBlockUserData::_ZTV18QTextBlockUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTextBlockUserData) +16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData +24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData + +Class QTextBlockUserData + size=8 align=8 + base size=8 base align=8 +QTextBlockUserData (0x0x7f5a23d52f60) 0 nearly-empty + vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16u) + +Class QTextBlock::iterator + size=24 align=8 + base size=20 base align=8 +QTextBlock::iterator (0x0x7f5a23a9d060) 0 + +Class QTextBlock + size=16 align=8 + base size=12 base align=8 +QTextBlock (0x0x7f5a23a9d000) 0 + +Class QTextFragment + size=16 align=8 + base size=16 base align=8 +QTextFragment (0x0x7f5a23a9d540) 0 + +Class QSyntaxHighlighter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSyntaxHighlighter::QPrivateSignal (0x0x7f5a23a9d840) 0 empty + +Vtable for QSyntaxHighlighter +QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSyntaxHighlighter) +16 (int (*)(...))QSyntaxHighlighter::metaObject +24 (int (*)(...))QSyntaxHighlighter::qt_metacast +32 (int (*)(...))QSyntaxHighlighter::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSyntaxHighlighter + size=16 align=8 + base size=16 base align=8 +QSyntaxHighlighter (0x0x7f5a23a97548) 0 + vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16u) + QObject (0x0x7f5a23a9d7e0) 0 + primary-for QSyntaxHighlighter (0x0x7f5a23a97548) + +Class QTextDocumentFragment + size=8 align=8 + base size=8 base align=8 +QTextDocumentFragment (0x0x7f5a23a9d8a0) 0 + +Class QTextDocumentWriter + size=8 align=8 + base size=8 base align=8 +QTextDocumentWriter (0x0x7f5a23a9d900) 0 + +Class QTextList::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextList::QPrivateSignal (0x0x7f5a23a9d9c0) 0 empty + +Vtable for QTextList +QTextList::_ZTV9QTextList: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextList) +16 (int (*)(...))QTextList::metaObject +24 (int (*)(...))QTextList::qt_metacast +32 (int (*)(...))QTextList::qt_metacall +40 (int (*)(...))QTextList::~QTextList +48 (int (*)(...))QTextList::~QTextList +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextList + size=16 align=8 + base size=16 base align=8 +QTextList (0x0x7f5a23a975b0) 0 + vptr=((& QTextList::_ZTV9QTextList) + 16u) + QTextBlockGroup (0x0x7f5a23a97618) 0 + primary-for QTextList (0x0x7f5a23a975b0) + QTextObject (0x0x7f5a23a97680) 0 + primary-for QTextBlockGroup (0x0x7f5a23a97618) + QObject (0x0x7f5a23a9d960) 0 + primary-for QTextObject (0x0x7f5a23a97680) + +Class QTextTableCell + size=16 align=8 + base size=12 base align=8 +QTextTableCell (0x0x7f5a23a9da20) 0 + +Class QTextTable::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextTable::QPrivateSignal (0x0x7f5a23a9dae0) 0 empty + +Vtable for QTextTable +QTextTable::_ZTV10QTextTable: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextTable) +16 (int (*)(...))QTextTable::metaObject +24 (int (*)(...))QTextTable::qt_metacast +32 (int (*)(...))QTextTable::qt_metacall +40 (int (*)(...))QTextTable::~QTextTable +48 (int (*)(...))QTextTable::~QTextTable +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextTable + size=16 align=8 + base size=16 base align=8 +QTextTable (0x0x7f5a23a976e8) 0 + vptr=((& QTextTable::_ZTV10QTextTable) + 16u) + QTextFrame (0x0x7f5a23a97750) 0 + primary-for QTextTable (0x0x7f5a23a976e8) + QTextObject (0x0x7f5a23a977b8) 0 + primary-for QTextFrame (0x0x7f5a23a97750) + QObject (0x0x7f5a23a9da80) 0 + primary-for QTextObject (0x0x7f5a23a977b8) + +Class QValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QValidator::QPrivateSignal (0x0x7f5a23a9dba0) 0 empty + +Vtable for QValidator +QValidator::_ZTV10QValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QValidator) +16 (int (*)(...))QValidator::metaObject +24 (int (*)(...))QValidator::qt_metacast +32 (int (*)(...))QValidator::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QValidator::fixup + +Class QValidator + size=16 align=8 + base size=16 base align=8 +QValidator (0x0x7f5a23a97820) 0 + vptr=((& QValidator::_ZTV10QValidator) + 16u) + QObject (0x0x7f5a23a9db40) 0 + primary-for QValidator (0x0x7f5a23a97820) + +Class QIntValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIntValidator::QPrivateSignal (0x0x7f5a23a9dc60) 0 empty + +Vtable for QIntValidator +QIntValidator::_ZTV13QIntValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QIntValidator) +16 (int (*)(...))QIntValidator::metaObject +24 (int (*)(...))QIntValidator::qt_metacast +32 (int (*)(...))QIntValidator::qt_metacall +40 (int (*)(...))QIntValidator::~QIntValidator +48 (int (*)(...))QIntValidator::~QIntValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIntValidator::validate +120 (int (*)(...))QIntValidator::fixup +128 (int (*)(...))QIntValidator::setRange + +Class QIntValidator + size=24 align=8 + base size=24 base align=8 +QIntValidator (0x0x7f5a23a97888) 0 + vptr=((& QIntValidator::_ZTV13QIntValidator) + 16u) + QValidator (0x0x7f5a23a978f0) 0 + primary-for QIntValidator (0x0x7f5a23a97888) + QObject (0x0x7f5a23a9dc00) 0 + primary-for QValidator (0x0x7f5a23a978f0) + +Class QDoubleValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleValidator::QPrivateSignal (0x0x7f5a23a9dd20) 0 empty + +Vtable for QDoubleValidator +QDoubleValidator::_ZTV16QDoubleValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDoubleValidator) +16 (int (*)(...))QDoubleValidator::metaObject +24 (int (*)(...))QDoubleValidator::qt_metacast +32 (int (*)(...))QDoubleValidator::qt_metacall +40 (int (*)(...))QDoubleValidator::~QDoubleValidator +48 (int (*)(...))QDoubleValidator::~QDoubleValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDoubleValidator::validate +120 (int (*)(...))QValidator::fixup +128 (int (*)(...))QDoubleValidator::setRange + +Class QDoubleValidator + size=40 align=8 + base size=36 base align=8 +QDoubleValidator (0x0x7f5a23a97958) 0 + vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16u) + QValidator (0x0x7f5a23a979c0) 0 + primary-for QDoubleValidator (0x0x7f5a23a97958) + QObject (0x0x7f5a23a9dcc0) 0 + primary-for QValidator (0x0x7f5a23a979c0) + +Class QRegExpValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegExpValidator::QPrivateSignal (0x0x7f5a23a9de40) 0 empty + +Vtable for QRegExpValidator +QRegExpValidator::_ZTV16QRegExpValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QRegExpValidator) +16 (int (*)(...))QRegExpValidator::metaObject +24 (int (*)(...))QRegExpValidator::qt_metacast +32 (int (*)(...))QRegExpValidator::qt_metacall +40 (int (*)(...))QRegExpValidator::~QRegExpValidator +48 (int (*)(...))QRegExpValidator::~QRegExpValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegExpValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegExpValidator + size=24 align=8 + base size=24 base align=8 +QRegExpValidator (0x0x7f5a23a97a28) 0 + vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16u) + QValidator (0x0x7f5a23a97a90) 0 + primary-for QRegExpValidator (0x0x7f5a23a97a28) + QObject (0x0x7f5a23a9dde0) 0 + primary-for QValidator (0x0x7f5a23a97a90) + +Class QRegularExpressionValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegularExpressionValidator::QPrivateSignal (0x0x7f5a23a9df00) 0 empty + +Vtable for QRegularExpressionValidator +QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QRegularExpressionValidator) +16 (int (*)(...))QRegularExpressionValidator::metaObject +24 (int (*)(...))QRegularExpressionValidator::qt_metacast +32 (int (*)(...))QRegularExpressionValidator::qt_metacall +40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegularExpressionValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegularExpressionValidator + size=16 align=8 + base size=16 base align=8 +QRegularExpressionValidator (0x0x7f5a23a97af8) 0 + vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16u) + QValidator (0x0x7f5a23a97b60) 0 + primary-for QRegularExpressionValidator (0x0x7f5a23a97af8) + QObject (0x0x7f5a23a9dea0) 0 + primary-for QValidator (0x0x7f5a23a97b60) + +Class QNetworkRequest + size=8 align=8 + base size=8 base align=8 +QNetworkRequest (0x0x7f5a23a9df60) 0 + +Class QNetworkCacheMetaData + size=8 align=8 + base size=8 base align=8 +QNetworkCacheMetaData (0x0x7f5a237a94e0) 0 + +Class QAbstractNetworkCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractNetworkCache::QPrivateSignal (0x0x7f5a237a9ba0) 0 empty + +Vtable for QAbstractNetworkCache +QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractNetworkCache) +16 (int (*)(...))QAbstractNetworkCache::metaObject +24 (int (*)(...))QAbstractNetworkCache::qt_metacast +32 (int (*)(...))QAbstractNetworkCache::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNetworkCache + size=16 align=8 + base size=16 base align=8 +QAbstractNetworkCache (0x0x7f5a237ee3a8) 0 + vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16u) + QObject (0x0x7f5a237a9b40) 0 + primary-for QAbstractNetworkCache (0x0x7f5a237ee3a8) + +Class QAbstractSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSocket::QPrivateSignal (0x0x7f5a237a9c60) 0 empty + +Vtable for QAbstractSocket +QAbstractSocket::_ZTV15QAbstractSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSocket) +16 (int (*)(...))QAbstractSocket::metaObject +24 (int (*)(...))QAbstractSocket::qt_metacast +32 (int (*)(...))QAbstractSocket::qt_metacall +40 (int (*)(...))QAbstractSocket::~QAbstractSocket +48 (int (*)(...))QAbstractSocket::~QAbstractSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QAbstractSocket + size=16 align=8 + base size=16 base align=8 +QAbstractSocket (0x0x7f5a237ee410) 0 + vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16u) + QIODevice (0x0x7f5a237ee478) 0 + primary-for QAbstractSocket (0x0x7f5a237ee410) + QObject (0x0x7f5a237a9c00) 0 + primary-for QIODevice (0x0x7f5a237ee478) + +Class QAuthenticator + size=8 align=8 + base size=8 base align=8 +QAuthenticator (0x0x7f5a2389d240) 0 + +Class QDnsDomainNameRecord + size=8 align=8 + base size=8 base align=8 +QDnsDomainNameRecord (0x0x7f5a2389d2a0) 0 + +Class QDnsHostAddressRecord + size=8 align=8 + base size=8 base align=8 +QDnsHostAddressRecord (0x0x7f5a2389d5a0) 0 + +Class QDnsMailExchangeRecord + size=8 align=8 + base size=8 base align=8 +QDnsMailExchangeRecord (0x0x7f5a2389d8a0) 0 + +Class QDnsServiceRecord + size=8 align=8 + base size=8 base align=8 +QDnsServiceRecord (0x0x7f5a2389dba0) 0 + +Class QDnsTextRecord + size=8 align=8 + base size=8 base align=8 +QDnsTextRecord (0x0x7f5a2389dea0) 0 + +Class QDnsLookup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDnsLookup::QPrivateSignal (0x0x7f5a2392f240) 0 empty + +Vtable for QDnsLookup +QDnsLookup::_ZTV10QDnsLookup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDnsLookup) +16 (int (*)(...))QDnsLookup::metaObject +24 (int (*)(...))QDnsLookup::qt_metacast +32 (int (*)(...))QDnsLookup::qt_metacall +40 (int (*)(...))QDnsLookup::~QDnsLookup +48 (int (*)(...))QDnsLookup::~QDnsLookup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDnsLookup + size=16 align=8 + base size=16 base align=8 +QDnsLookup (0x0x7f5a237eeea0) 0 + vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16u) + QObject (0x0x7f5a2392f1e0) 0 + primary-for QDnsLookup (0x0x7f5a237eeea0) + +Class QTcpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpSocket::QPrivateSignal (0x0x7f5a2392f300) 0 empty + +Vtable for QTcpSocket +QTcpSocket::_ZTV10QTcpSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpSocket) +16 (int (*)(...))QTcpSocket::metaObject +24 (int (*)(...))QTcpSocket::qt_metacast +32 (int (*)(...))QTcpSocket::qt_metacall +40 (int (*)(...))QTcpSocket::~QTcpSocket +48 (int (*)(...))QTcpSocket::~QTcpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QTcpSocket + size=16 align=8 + base size=16 base align=8 +QTcpSocket (0x0x7f5a237eef08) 0 + vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16u) + QAbstractSocket (0x0x7f5a237eef70) 0 + primary-for QTcpSocket (0x0x7f5a237eef08) + QIODevice (0x0x7f5a2394e000) 0 + primary-for QAbstractSocket (0x0x7f5a237eef70) + QObject (0x0x7f5a2392f2a0) 0 + primary-for QIODevice (0x0x7f5a2394e000) + +Class QSslCertificate + size=8 align=8 + base size=8 base align=8 +QSslCertificate (0x0x7f5a2392f4e0) 0 + +Class QSslError + size=8 align=8 + base size=8 base align=8 +QSslError (0x0x7f5a2392f900) 0 + +Class QSslSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSslSocket::QPrivateSignal (0x0x7f5a235f72a0) 0 empty + +Vtable for QSslSocket +QSslSocket::_ZTV10QSslSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSslSocket) +16 (int (*)(...))QSslSocket::metaObject +24 (int (*)(...))QSslSocket::qt_metacast +32 (int (*)(...))QSslSocket::qt_metacall +40 (int (*)(...))QSslSocket::~QSslSocket +48 (int (*)(...))QSslSocket::~QSslSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QSslSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QSslSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QSslSocket::bytesAvailable +184 (int (*)(...))QSslSocket::bytesToWrite +192 (int (*)(...))QSslSocket::canReadLine +200 (int (*)(...))QSslSocket::waitForReadyRead +208 (int (*)(...))QSslSocket::waitForBytesWritten +216 (int (*)(...))QSslSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QSslSocket::writeData +240 (int (*)(...))QSslSocket::resume +248 (int (*)(...))QSslSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QSslSocket::disconnectFromHost +272 (int (*)(...))QSslSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QSslSocket::setSocketDescriptor +296 (int (*)(...))QSslSocket::setSocketOption +304 (int (*)(...))QSslSocket::socketOption +312 (int (*)(...))QSslSocket::waitForConnected +320 (int (*)(...))QSslSocket::waitForDisconnected + +Class QSslSocket + size=16 align=8 + base size=16 base align=8 +QSslSocket (0x0x7f5a2394e9c0) 0 + vptr=((& QSslSocket::_ZTV10QSslSocket) + 16u) + QTcpSocket (0x0x7f5a2394ea28) 0 + primary-for QSslSocket (0x0x7f5a2394e9c0) + QAbstractSocket (0x0x7f5a2394ea90) 0 + primary-for QTcpSocket (0x0x7f5a2394ea28) + QIODevice (0x0x7f5a2394eaf8) 0 + primary-for QAbstractSocket (0x0x7f5a2394ea90) + QObject (0x0x7f5a235f7240) 0 + primary-for QIODevice (0x0x7f5a2394eaf8) + +Class QDtlsClientVerifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtlsClientVerifier::QPrivateSignal (0x0x7f5a235f7360) 0 empty + +Class QDtlsClientVerifier::GeneratorParameters + size=16 align=8 + base size=16 base align=8 +QDtlsClientVerifier::GeneratorParameters (0x0x7f5a235f73c0) 0 + +Vtable for QDtlsClientVerifier +QDtlsClientVerifier::_ZTV19QDtlsClientVerifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QDtlsClientVerifier) +16 (int (*)(...))QDtlsClientVerifier::metaObject +24 (int (*)(...))QDtlsClientVerifier::qt_metacast +32 (int (*)(...))QDtlsClientVerifier::qt_metacall +40 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +48 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtlsClientVerifier + size=16 align=8 + base size=16 base align=8 +QDtlsClientVerifier (0x0x7f5a2394eb60) 0 + vptr=((& QDtlsClientVerifier::_ZTV19QDtlsClientVerifier) + 16u) + QObject (0x0x7f5a235f7300) 0 + primary-for QDtlsClientVerifier (0x0x7f5a2394eb60) + +Class QDtls::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtls::QPrivateSignal (0x0x7f5a235f7480) 0 empty + +Vtable for QDtls +QDtls::_ZTV5QDtls: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDtls) +16 (int (*)(...))QDtls::metaObject +24 (int (*)(...))QDtls::qt_metacast +32 (int (*)(...))QDtls::qt_metacall +40 (int (*)(...))QDtls::~QDtls +48 (int (*)(...))QDtls::~QDtls +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtls + size=16 align=8 + base size=16 base align=8 +QDtls (0x0x7f5a2394ebc8) 0 + vptr=((& QDtls::_ZTV5QDtls) + 16u) + QObject (0x0x7f5a235f7420) 0 + primary-for QDtls (0x0x7f5a2394ebc8) + +Class QIPv6Address + size=16 align=1 + base size=16 base align=1 +QIPv6Address (0x0x7f5a235f7540) 0 + +Class QHostAddress + size=8 align=8 + base size=8 base align=8 +QHostAddress (0x0x7f5a235f75a0) 0 + +Class QHostInfo + size=8 align=8 + base size=8 base align=8 +QHostInfo (0x0x7f5a235f7d80) 0 + +Class QHstsPolicy + size=8 align=8 + base size=8 base align=8 +QHstsPolicy (0x0x7f5a237132a0) 0 + +Class QHttpPart + size=8 align=8 + base size=8 base align=8 +QHttpPart (0x0x7f5a23713a80) 0 + +Class QHttpMultiPart::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHttpMultiPart::QPrivateSignal (0x0x7f5a23713de0) 0 empty + +Vtable for QHttpMultiPart +QHttpMultiPart::_ZTV14QHttpMultiPart: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QHttpMultiPart) +16 (int (*)(...))QHttpMultiPart::metaObject +24 (int (*)(...))QHttpMultiPart::qt_metacast +32 (int (*)(...))QHttpMultiPart::qt_metacall +40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QHttpMultiPart + size=16 align=8 + base size=16 base align=8 +QHttpMultiPart (0x0x7f5a236dae38) 0 + vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16u) + QObject (0x0x7f5a23713d80) 0 + primary-for QHttpMultiPart (0x0x7f5a236dae38) + +Class QLocalServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalServer::QPrivateSignal (0x0x7f5a23713ea0) 0 empty + +Vtable for QLocalServer +QLocalServer::_ZTV12QLocalServer: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalServer) +16 (int (*)(...))QLocalServer::metaObject +24 (int (*)(...))QLocalServer::qt_metacast +32 (int (*)(...))QLocalServer::qt_metacall +40 (int (*)(...))QLocalServer::~QLocalServer +48 (int (*)(...))QLocalServer::~QLocalServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalServer::hasPendingConnections +120 (int (*)(...))QLocalServer::nextPendingConnection +128 (int (*)(...))QLocalServer::incomingConnection + +Class QLocalServer + size=16 align=8 + base size=16 base align=8 +QLocalServer (0x0x7f5a236daea0) 0 + vptr=((& QLocalServer::_ZTV12QLocalServer) + 16u) + QObject (0x0x7f5a23713e40) 0 + primary-for QLocalServer (0x0x7f5a236daea0) + +Class QLocalSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalSocket::QPrivateSignal (0x0x7f5a233ba120) 0 empty + +Vtable for QLocalSocket +QLocalSocket::_ZTV12QLocalSocket: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalSocket) +16 (int (*)(...))QLocalSocket::metaObject +24 (int (*)(...))QLocalSocket::qt_metacast +32 (int (*)(...))QLocalSocket::qt_metacall +40 (int (*)(...))QLocalSocket::~QLocalSocket +48 (int (*)(...))QLocalSocket::~QLocalSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalSocket::isSequential +120 (int (*)(...))QLocalSocket::open +128 (int (*)(...))QLocalSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QLocalSocket::bytesAvailable +184 (int (*)(...))QLocalSocket::bytesToWrite +192 (int (*)(...))QLocalSocket::canReadLine +200 (int (*)(...))QLocalSocket::waitForReadyRead +208 (int (*)(...))QLocalSocket::waitForBytesWritten +216 (int (*)(...))QLocalSocket::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QLocalSocket::writeData + +Class QLocalSocket + size=16 align=8 + base size=16 base align=8 +QLocalSocket (0x0x7f5a233bb068) 0 + vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16u) + QIODevice (0x0x7f5a233bb0d0) 0 + primary-for QLocalSocket (0x0x7f5a233bb068) + QObject (0x0x7f5a233ba0c0) 0 + primary-for QIODevice (0x0x7f5a233bb0d0) + +Class QSslConfiguration + size=8 align=8 + base size=8 base align=8 +QSslConfiguration (0x0x7f5a233ba180) 0 + +Class QSslPreSharedKeyAuthenticator + size=8 align=8 + base size=8 base align=8 +QSslPreSharedKeyAuthenticator (0x0x7f5a233ba960) 0 + +Class QNetworkAccessManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkAccessManager::QPrivateSignal (0x0x7f5a2347e2a0) 0 empty + +Vtable for QNetworkAccessManager +QNetworkAccessManager::_ZTV21QNetworkAccessManager: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QNetworkAccessManager) +16 (int (*)(...))QNetworkAccessManager::metaObject +24 (int (*)(...))QNetworkAccessManager::qt_metacast +32 (int (*)(...))QNetworkAccessManager::qt_metacall +40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkAccessManager::createRequest + +Class QNetworkAccessManager + size=16 align=8 + base size=16 base align=8 +QNetworkAccessManager (0x0x7f5a233bbd68) 0 + vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16u) + QObject (0x0x7f5a2347e240) 0 + primary-for QNetworkAccessManager (0x0x7f5a233bbd68) + +Class QNetworkConfiguration + size=8 align=8 + base size=8 base align=8 +QNetworkConfiguration (0x0x7f5a2347e300) 0 + +Class QNetworkConfigurationManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkConfigurationManager::QPrivateSignal (0x0x7f5a2347e780) 0 empty + +Vtable for QNetworkConfigurationManager +QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QNetworkConfigurationManager) +16 (int (*)(...))QNetworkConfigurationManager::metaObject +24 (int (*)(...))QNetworkConfigurationManager::qt_metacast +32 (int (*)(...))QNetworkConfigurationManager::qt_metacall +40 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager +48 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QNetworkConfigurationManager + size=16 align=8 + base size=16 base align=8 +QNetworkConfigurationManager (0x0x7f5a233bbf70) 0 + vptr=((& QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager) + 16u) + QObject (0x0x7f5a2347e720) 0 + primary-for QNetworkConfigurationManager (0x0x7f5a233bbf70) + +Class QNetworkCookie + size=8 align=8 + base size=8 base align=8 +QNetworkCookie (0x0x7f5a2347eae0) 0 + +Class QNetworkCookieJar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkCookieJar::QPrivateSignal (0x0x7f5a23556300) 0 empty + +Vtable for QNetworkCookieJar +QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkCookieJar) +16 (int (*)(...))QNetworkCookieJar::metaObject +24 (int (*)(...))QNetworkCookieJar::qt_metacast +32 (int (*)(...))QNetworkCookieJar::qt_metacall +40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkCookieJar::cookiesForUrl +120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl +128 (int (*)(...))QNetworkCookieJar::insertCookie +136 (int (*)(...))QNetworkCookieJar::updateCookie +144 (int (*)(...))QNetworkCookieJar::deleteCookie +152 (int (*)(...))QNetworkCookieJar::validateCookie + +Class QNetworkCookieJar + size=16 align=8 + base size=16 base align=8 +QNetworkCookieJar (0x0x7f5a234ec7b8) 0 + vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16u) + QObject (0x0x7f5a235562a0) 0 + primary-for QNetworkCookieJar (0x0x7f5a234ec7b8) + +Class QNetworkDatagram + size=8 align=8 + base size=8 base align=8 +QNetworkDatagram (0x0x7f5a23556360) 0 + +Class QNetworkDiskCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkDiskCache::QPrivateSignal (0x0x7f5a23202360) 0 empty + +Vtable for QNetworkDiskCache +QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkDiskCache) +16 (int (*)(...))QNetworkDiskCache::metaObject +24 (int (*)(...))QNetworkDiskCache::qt_metacast +32 (int (*)(...))QNetworkDiskCache::qt_metacall +40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkDiskCache::metaData +120 (int (*)(...))QNetworkDiskCache::updateMetaData +128 (int (*)(...))QNetworkDiskCache::data +136 (int (*)(...))QNetworkDiskCache::remove +144 (int (*)(...))QNetworkDiskCache::cacheSize +152 (int (*)(...))QNetworkDiskCache::prepare +160 (int (*)(...))QNetworkDiskCache::insert +168 (int (*)(...))QNetworkDiskCache::clear +176 (int (*)(...))QNetworkDiskCache::expire + +Class QNetworkDiskCache + size=16 align=8 + base size=16 base align=8 +QNetworkDiskCache (0x0x7f5a231fc208) 0 + vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16u) + QAbstractNetworkCache (0x0x7f5a231fc270) 0 + primary-for QNetworkDiskCache (0x0x7f5a231fc208) + QObject (0x0x7f5a23202300) 0 + primary-for QAbstractNetworkCache (0x0x7f5a231fc270) + +Class QNetworkAddressEntry + size=8 align=8 + base size=8 base align=8 +QNetworkAddressEntry (0x0x7f5a232023c0) 0 + +Class QNetworkInterface + size=8 align=8 + base size=8 base align=8 +QNetworkInterface (0x0x7f5a23202a80) 0 + +Class QNetworkProxyQuery + size=8 align=8 + base size=8 base align=8 +QNetworkProxyQuery (0x0x7f5a232ac180) 0 + +Class QNetworkProxy + size=8 align=8 + base size=8 base align=8 +QNetworkProxy (0x0x7f5a232ac7e0) 0 + +Vtable for QNetworkProxyFactory +QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QNetworkProxyFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QNetworkProxyFactory + size=8 align=8 + base size=8 base align=8 +QNetworkProxyFactory (0x0x7f5a23345000) 0 nearly-empty + vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16u) + +Class QNetworkReply::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkReply::QPrivateSignal (0x0x7f5a233451e0) 0 empty + +Vtable for QNetworkReply +QNetworkReply::_ZTV13QNetworkReply: 36u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QNetworkReply) +16 (int (*)(...))QNetworkReply::metaObject +24 (int (*)(...))QNetworkReply::qt_metacast +32 (int (*)(...))QNetworkReply::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkReply::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QNetworkReply::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QNetworkReply::writeData +240 (int (*)(...))QNetworkReply::setReadBufferSize +248 (int (*)(...))__cxa_pure_virtual +256 (int (*)(...))QNetworkReply::ignoreSslErrors +264 (int (*)(...))QNetworkReply::sslConfigurationImplementation +272 (int (*)(...))QNetworkReply::setSslConfigurationImplementation +280 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation + +Class QNetworkReply + size=16 align=8 + base size=16 base align=8 +QNetworkReply (0x0x7f5a232e18f0) 0 + vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16u) + QIODevice (0x0x7f5a232e1958) 0 + primary-for QNetworkReply (0x0x7f5a232e18f0) + QObject (0x0x7f5a23345180) 0 + primary-for QIODevice (0x0x7f5a232e1958) + +Class QNetworkSession::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkSession::QPrivateSignal (0x0x7f5a233453c0) 0 empty + +Vtable for QNetworkSession +QNetworkSession::_ZTV15QNetworkSession: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QNetworkSession) +16 (int (*)(...))QNetworkSession::metaObject +24 (int (*)(...))QNetworkSession::qt_metacast +32 (int (*)(...))QNetworkSession::qt_metacall +40 (int (*)(...))QNetworkSession::~QNetworkSession +48 (int (*)(...))QNetworkSession::~QNetworkSession +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QNetworkSession::connectNotify +104 (int (*)(...))QNetworkSession::disconnectNotify + +Class QNetworkSession + size=24 align=8 + base size=24 base align=8 +QNetworkSession (0x0x7f5a232e19c0) 0 + vptr=((& QNetworkSession::_ZTV15QNetworkSession) + 16u) + QObject (0x0x7f5a23345360) 0 + primary-for QNetworkSession (0x0x7f5a232e19c0) + +Class QTcpServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpServer::QPrivateSignal (0x0x7f5a23345960) 0 empty + +Vtable for QTcpServer +QTcpServer::_ZTV10QTcpServer: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpServer) +16 (int (*)(...))QTcpServer::metaObject +24 (int (*)(...))QTcpServer::qt_metacast +32 (int (*)(...))QTcpServer::qt_metacall +40 (int (*)(...))QTcpServer::~QTcpServer +48 (int (*)(...))QTcpServer::~QTcpServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTcpServer::hasPendingConnections +120 (int (*)(...))QTcpServer::nextPendingConnection +128 (int (*)(...))QTcpServer::incomingConnection + +Class QTcpServer + size=16 align=8 + base size=16 base align=8 +QTcpServer (0x0x7f5a232e1af8) 0 + vptr=((& QTcpServer::_ZTV10QTcpServer) + 16u) + QObject (0x0x7f5a23345900) 0 + primary-for QTcpServer (0x0x7f5a232e1af8) + +Class QSslCertificateExtension + size=8 align=8 + base size=8 base align=8 +QSslCertificateExtension (0x0x7f5a233459c0) 0 + +Class QSslCipher + size=8 align=8 + base size=8 base align=8 +QSslCipher (0x0x7f5a23345cc0) 0 + +Class QSslDiffieHellmanParameters + size=8 align=8 + base size=8 base align=8 +QSslDiffieHellmanParameters (0x0x7f5a230104e0) 0 + +Class QSslEllipticCurve + size=4 align=4 + base size=4 base align=4 +QSslEllipticCurve (0x0x7f5a230af000) 0 + +Class QSslKey + size=8 align=8 + base size=8 base align=8 +QSslKey (0x0x7f5a230af720) 0 + +Class QUdpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUdpSocket::QPrivateSignal (0x0x7f5a230afa80) 0 empty + +Vtable for QUdpSocket +QUdpSocket::_ZTV10QUdpSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUdpSocket) +16 (int (*)(...))QUdpSocket::metaObject +24 (int (*)(...))QUdpSocket::qt_metacast +32 (int (*)(...))QUdpSocket::qt_metacall +40 (int (*)(...))QUdpSocket::~QUdpSocket +48 (int (*)(...))QUdpSocket::~QUdpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QUdpSocket + size=16 align=8 + base size=16 base align=8 +QUdpSocket (0x0x7f5a230f00d0) 0 + vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16u) + QAbstractSocket (0x0x7f5a230f0138) 0 + primary-for QUdpSocket (0x0x7f5a230f00d0) + QIODevice (0x0x7f5a230f01a0) 0 + primary-for QAbstractSocket (0x0x7f5a230f0138) + QObject (0x0x7f5a230afa20) 0 + primary-for QIODevice (0x0x7f5a230f01a0) + +Class QJSValue + size=8 align=8 + base size=8 base align=8 +QJSValue (0x0x7f5a230afae0) 0 + +Class QQmlDebuggingEnabler + size=1 align=1 + base size=0 base align=1 +QQmlDebuggingEnabler (0x0x7f5a230afd80) 0 empty + +Class QJSEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QJSEngine::QPrivateSignal (0x0x7f5a230afe40) 0 empty + +Vtable for QJSEngine +QJSEngine::_ZTV9QJSEngine: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QJSEngine) +16 (int (*)(...))QJSEngine::metaObject +24 (int (*)(...))QJSEngine::qt_metacast +32 (int (*)(...))QJSEngine::qt_metacall +40 (int (*)(...))QJSEngine::~QJSEngine +48 (int (*)(...))QJSEngine::~QJSEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QJSEngine + size=24 align=8 + base size=24 base align=8 +QJSEngine (0x0x7f5a230f02d8) 0 + vptr=((& QJSEngine::_ZTV9QJSEngine) + 16u) + QObject (0x0x7f5a230afde0) 0 + primary-for QJSEngine (0x0x7f5a230f02d8) + +Class QJSValueIterator + size=8 align=8 + base size=8 base align=8 +QJSValueIterator (0x0x7f5a23182060) 0 + +Class QQmlPrivate::RegisterType + size=128 align=8 + base size=124 base align=8 +QQmlPrivate::RegisterType (0x0x7f5a23182540) 0 + +Class QQmlPrivate::RegisterInterface + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::RegisterInterface (0x0x7f5a231825a0) 0 + +Class QQmlPrivate::RegisterAutoParent + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterAutoParent (0x0x7f5a23182600) 0 + +Class QQmlPrivate::RegisterSingletonType + size=64 align=8 + base size=64 base align=8 +QQmlPrivate::RegisterSingletonType (0x0x7f5a23182660) 0 + +Class QQmlPrivate::RegisterCompositeType + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::RegisterCompositeType (0x0x7f5a231826c0) 0 + +Class QQmlPrivate::RegisterCompositeSingletonType + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::RegisterCompositeSingletonType (0x0x7f5a23182720) 0 + +Class QQmlPrivate::CachedQmlUnit + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::CachedQmlUnit (0x0x7f5a23182780) 0 + +Class QQmlPrivate::RegisterQmlUnitCacheHook + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterQmlUnitCacheHook (0x0x7f5a231827e0) 0 + +Vtable for QQmlParserStatus +QQmlParserStatus::_ZTV16QQmlParserStatus: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlParserStatus) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlParserStatus + size=16 align=8 + base size=16 base align=8 +QQmlParserStatus (0x0x7f5a23182840) 0 + vptr=((& QQmlParserStatus::_ZTV16QQmlParserStatus) + 16u) + +Vtable for QQmlPropertyValueSource +QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQmlPropertyValueSource) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlPropertyValueSource + size=8 align=8 + base size=8 base align=8 +QQmlPropertyValueSource (0x0x7f5a23182900) 0 nearly-empty + vptr=((& QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource) + 16u) + +Class QQmlListReference + size=8 align=8 + base size=8 base align=8 +QQmlListReference (0x0x7f5a23182a20) 0 + +Vtable for QQmlAbstractUrlInterceptor +QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QQmlAbstractUrlInterceptor) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlAbstractUrlInterceptor + size=8 align=8 + base size=8 base align=8 +QQmlAbstractUrlInterceptor (0x0x7f5a22e880c0) 0 nearly-empty + vptr=((& QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor) + 16u) + +Class QQmlError + size=8 align=8 + base size=8 base align=8 +QQmlError (0x0x7f5a22e88120) 0 + +Vtable for QQmlImageProviderBase +QQmlImageProviderBase::_ZTV21QQmlImageProviderBase: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlImageProviderBase) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlImageProviderBase + size=8 align=8 + base size=8 base align=8 +QQmlImageProviderBase (0x0x7f5a22e883c0) 0 nearly-empty + vptr=((& QQmlImageProviderBase::_ZTV21QQmlImageProviderBase) + 16u) + +Class QQmlEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngine::QPrivateSignal (0x0x7f5a22e88600) 0 empty + +Vtable for QQmlEngine +QQmlEngine::_ZTV10QQmlEngine: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQmlEngine) +16 (int (*)(...))QQmlEngine::metaObject +24 (int (*)(...))QQmlEngine::qt_metacast +32 (int (*)(...))QQmlEngine::qt_metacall +40 (int (*)(...))QQmlEngine::~QQmlEngine +48 (int (*)(...))QQmlEngine::~QQmlEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlEngine + size=24 align=8 + base size=24 base align=8 +QQmlEngine (0x0x7f5a230f08f0) 0 + vptr=((& QQmlEngine::_ZTV10QQmlEngine) + 16u) + QJSEngine (0x0x7f5a230f0958) 0 + primary-for QQmlEngine (0x0x7f5a230f08f0) + QObject (0x0x7f5a22e885a0) 0 + primary-for QJSEngine (0x0x7f5a230f0958) + +Class QQmlApplicationEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlApplicationEngine::QPrivateSignal (0x0x7f5a22e886c0) 0 empty + +Vtable for QQmlApplicationEngine +QQmlApplicationEngine::_ZTV21QQmlApplicationEngine: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlApplicationEngine) +16 (int (*)(...))QQmlApplicationEngine::metaObject +24 (int (*)(...))QQmlApplicationEngine::qt_metacast +32 (int (*)(...))QQmlApplicationEngine::qt_metacall +40 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +48 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlApplicationEngine + size=24 align=8 + base size=24 base align=8 +QQmlApplicationEngine (0x0x7f5a230f0a28) 0 + vptr=((& QQmlApplicationEngine::_ZTV21QQmlApplicationEngine) + 16u) + QQmlEngine (0x0x7f5a230f0a90) 0 + primary-for QQmlApplicationEngine (0x0x7f5a230f0a28) + QJSEngine (0x0x7f5a230f0af8) 0 + primary-for QQmlEngine (0x0x7f5a230f0a90) + QObject (0x0x7f5a22e88660) 0 + primary-for QJSEngine (0x0x7f5a230f0af8) + +Class QQmlComponent::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlComponent::QPrivateSignal (0x0x7f5a22e88780) 0 empty + +Vtable for QQmlComponent +QQmlComponent::_ZTV13QQmlComponent: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlComponent) +16 (int (*)(...))QQmlComponent::metaObject +24 (int (*)(...))QQmlComponent::qt_metacast +32 (int (*)(...))QQmlComponent::qt_metacall +40 (int (*)(...))QQmlComponent::~QQmlComponent +48 (int (*)(...))QQmlComponent::~QQmlComponent +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlComponent::create +120 (int (*)(...))QQmlComponent::beginCreate +128 (int (*)(...))QQmlComponent::completeCreate + +Class QQmlComponent + size=16 align=8 + base size=16 base align=8 +QQmlComponent (0x0x7f5a230f0b60) 0 + vptr=((& QQmlComponent::_ZTV13QQmlComponent) + 16u) + QObject (0x0x7f5a22e88720) 0 + primary-for QQmlComponent (0x0x7f5a230f0b60) + +Class QQmlContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlContext::QPrivateSignal (0x0x7f5a22f51000) 0 empty + +Class QQmlContext::PropertyPair + size=24 align=8 + base size=24 base align=8 +QQmlContext::PropertyPair (0x0x7f5a22f51060) 0 + +Vtable for QQmlContext +QQmlContext::_ZTV11QQmlContext: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QQmlContext) +16 (int (*)(...))QQmlContext::metaObject +24 (int (*)(...))QQmlContext::qt_metacast +32 (int (*)(...))QQmlContext::qt_metacall +40 (int (*)(...))QQmlContext::~QQmlContext +48 (int (*)(...))QQmlContext::~QQmlContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlContext + size=16 align=8 + base size=16 base align=8 +QQmlContext (0x0x7f5a22f490d0) 0 + vptr=((& QQmlContext::_ZTV11QQmlContext) + 16u) + QObject (0x0x7f5a22e88f60) 0 + primary-for QQmlContext (0x0x7f5a22f490d0) + +Class QQmlScriptString + size=8 align=8 + base size=8 base align=8 +QQmlScriptString (0x0x7f5a22f511e0) 0 + +Class QQmlExpression::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExpression::QPrivateSignal (0x0x7f5a22f51420) 0 empty + +Vtable for QQmlExpression +QQmlExpression::_ZTV14QQmlExpression: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QQmlExpression) +16 (int (*)(...))QQmlExpression::metaObject +24 (int (*)(...))QQmlExpression::qt_metacast +32 (int (*)(...))QQmlExpression::qt_metacall +40 (int (*)(...))QQmlExpression::~QQmlExpression +48 (int (*)(...))QQmlExpression::~QQmlExpression +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlExpression + size=16 align=8 + base size=16 base align=8 +QQmlExpression (0x0x7f5a22f49138) 0 + vptr=((& QQmlExpression::_ZTV14QQmlExpression) + 16u) + QObject (0x0x7f5a22f513c0) 0 + primary-for QQmlExpression (0x0x7f5a22f49138) + +Vtable for QQmlTypesExtensionInterface +QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QQmlTypesExtensionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlTypesExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlTypesExtensionInterface (0x0x7f5a22f51480) 0 nearly-empty + vptr=((& QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface) + 16u) + +Vtable for QQmlExtensionInterface +QQmlExtensionInterface::_ZTV22QQmlExtensionInterface: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QQmlExtensionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlExtensionInterface (0x0x7f5a22f491a0) 0 nearly-empty + vptr=((& QQmlExtensionInterface::_ZTV22QQmlExtensionInterface) + 16u) + QQmlTypesExtensionInterface (0x0x7f5a22f514e0) 0 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f5a22f491a0) + +Class QQmlExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExtensionPlugin::QPrivateSignal (0x0x7f5a22f516c0) 0 empty + +Vtable for QQmlExtensionPlugin +QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin: 22u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +16 (int (*)(...))QQmlExtensionPlugin::metaObject +24 (int (*)(...))QQmlExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlExtensionPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQmlExtensionPlugin::initializeEngine +128 (int (*)(...))-16 +136 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +144 0u +152 0u +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QQmlExtensionPlugin::_ZThn16_N19QQmlExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlExtensionPlugin (0x0x7f5a22ba8540) 0 + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 16u) + QObject (0x0x7f5a22f51600) 0 + primary-for QQmlExtensionPlugin (0x0x7f5a22ba8540) + QQmlExtensionInterface (0x0x7f5a22f49208) 16 nearly-empty + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 144u) + QQmlTypesExtensionInterface (0x0x7f5a22f51660) 16 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f5a22f49208) + +Class QQmlFile + size=8 align=8 + base size=8 base align=8 +QQmlFile (0x0x7f5a22f51720) 0 + +Class QQmlFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlFileSelector::QPrivateSignal (0x0x7f5a22f517e0) 0 empty + +Vtable for QQmlFileSelector +QQmlFileSelector::_ZTV16QQmlFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlFileSelector) +16 (int (*)(...))QQmlFileSelector::metaObject +24 (int (*)(...))QQmlFileSelector::qt_metacast +32 (int (*)(...))QQmlFileSelector::qt_metacall +40 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +48 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlFileSelector + size=16 align=8 + base size=16 base align=8 +QQmlFileSelector (0x0x7f5a22f492d8) 0 + vptr=((& QQmlFileSelector::_ZTV16QQmlFileSelector) + 16u) + QObject (0x0x7f5a22f51780) 0 + primary-for QQmlFileSelector (0x0x7f5a22f492d8) + +Vtable for QQmlIncubator +QQmlIncubator::_ZTV13QQmlIncubator: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlIncubator) +16 (int (*)(...))QQmlIncubator::~QQmlIncubator +24 (int (*)(...))QQmlIncubator::~QQmlIncubator +32 (int (*)(...))QQmlIncubator::statusChanged +40 (int (*)(...))QQmlIncubator::setInitialState + +Class QQmlIncubator + size=16 align=8 + base size=16 base align=8 +QQmlIncubator (0x0x7f5a22f51840) 0 + vptr=((& QQmlIncubator::_ZTV13QQmlIncubator) + 16u) + +Vtable for QQmlIncubationController +QQmlIncubationController::_ZTV24QQmlIncubationController: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQmlIncubationController) +16 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +24 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +32 (int (*)(...))QQmlIncubationController::incubatingObjectCountChanged + +Class QQmlIncubationController + size=16 align=8 + base size=16 base align=8 +QQmlIncubationController (0x0x7f5a22f518a0) 0 + vptr=((& QQmlIncubationController::_ZTV24QQmlIncubationController) + 16u) + +Class QQmlInfo + size=16 align=8 + base size=16 base align=8 +QQmlInfo (0x0x7f5a22f49340) 0 + QDebug (0x0x7f5a22f51900) 0 + +Vtable for QQmlNetworkAccessManagerFactory +QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI31QQmlNetworkAccessManagerFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlNetworkAccessManagerFactory + size=8 align=8 + base size=8 base align=8 +QQmlNetworkAccessManagerFactory (0x0x7f5a22c2c120) 0 nearly-empty + vptr=((& QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory) + 16u) + +Class QQmlProperty + size=8 align=8 + base size=8 base align=8 +QQmlProperty (0x0x7f5a22c2c180) 0 + +Class QQmlPropertyMap::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlPropertyMap::QPrivateSignal (0x0x7f5a22c2ccc0) 0 empty + +Vtable for QQmlPropertyMap +QQmlPropertyMap::_ZTV15QQmlPropertyMap: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQmlPropertyMap) +16 (int (*)(...))QQmlPropertyMap::metaObject +24 (int (*)(...))QQmlPropertyMap::qt_metacast +32 (int (*)(...))QQmlPropertyMap::qt_metacall +40 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +48 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlPropertyMap::updateValue + +Class QQmlPropertyMap + size=16 align=8 + base size=16 base align=8 +QQmlPropertyMap (0x0x7f5a22c4e8f0) 0 + vptr=((& QQmlPropertyMap::_ZTV15QQmlPropertyMap) + 16u) + QObject (0x0x7f5a22c2cc60) 0 + primary-for QQmlPropertyMap (0x0x7f5a22c4e8f0) + +Class QQuickTransform::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTransform::QPrivateSignal (0x0x7f5a22c2cd80) 0 empty + +Vtable for QQuickTransform +QQuickTransform::_ZTV15QQuickTransform: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQuickTransform) +16 (int (*)(...))QQuickTransform::metaObject +24 (int (*)(...))QQuickTransform::qt_metacast +32 (int (*)(...))QQuickTransform::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QQuickTransform + size=16 align=8 + base size=16 base align=8 +QQuickTransform (0x0x7f5a22c4e958) 0 + vptr=((& QQuickTransform::_ZTV15QQuickTransform) + 16u) + QObject (0x0x7f5a22c2cd20) 0 + primary-for QQuickTransform (0x0x7f5a22c4e958) + +Class QQuickItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItem::QPrivateSignal (0x0x7f5a22c2cea0) 0 empty + +Class QQuickItem::ItemChangeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::ItemChangeData (0x0x7f5a22c2cf00) 0 + +Class QQuickItem::UpdatePaintNodeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::UpdatePaintNodeData (0x0x7f5a22c2cf60) 0 + +Vtable for QQuickItem +QQuickItem::_ZTV10QQuickItem: 55u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickItem) +16 (int (*)(...))QQuickItem::metaObject +24 (int (*)(...))QQuickItem::qt_metacast +32 (int (*)(...))QQuickItem::qt_metacall +40 (int (*)(...))QQuickItem::~QQuickItem +48 (int (*)(...))QQuickItem::~QQuickItem +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickItem::isTextureProvider +152 (int (*)(...))QQuickItem::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickItem::geometryChanged +368 (int (*)(...))QQuickItem::updatePaintNode +376 (int (*)(...))QQuickItem::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))-16 +400 (int (*)(...))(& _ZTI10QQuickItem) +408 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD1Ev +416 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD0Ev +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickItem + size=32 align=8 + base size=32 base align=8 +QQuickItem (0x0x7f5a22c6e380) 0 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 16u) + QObject (0x0x7f5a22c2cde0) 0 + primary-for QQuickItem (0x0x7f5a22c6e380) + QQmlParserStatus (0x0x7f5a22c2ce40) 16 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 408u) + +Class QQuickFramebufferObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickFramebufferObject::QPrivateSignal (0x0x7f5a22ccc780) 0 empty + +Vtable for QQuickFramebufferObject::Renderer +QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN23QQuickFramebufferObject8RendererE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QQuickFramebufferObject::Renderer::createFramebufferObject +48 (int (*)(...))QQuickFramebufferObject::Renderer::synchronize + +Class QQuickFramebufferObject::Renderer + size=16 align=8 + base size=16 base align=8 +QQuickFramebufferObject::Renderer (0x0x7f5a22ccc7e0) 0 + vptr=((& QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE) + 16u) + +Vtable for QQuickFramebufferObject +QQuickFramebufferObject::_ZTV23QQuickFramebufferObject: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +16 (int (*)(...))QQuickFramebufferObject::metaObject +24 (int (*)(...))QQuickFramebufferObject::qt_metacast +32 (int (*)(...))QQuickFramebufferObject::qt_metacall +40 0u +48 0u +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickFramebufferObject::isTextureProvider +152 (int (*)(...))QQuickFramebufferObject::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickFramebufferObject::geometryChanged +368 (int (*)(...))QQuickFramebufferObject::updatePaintNode +376 (int (*)(...))QQuickFramebufferObject::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))-16 +408 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +416 0u +424 0u +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickFramebufferObject + size=32 align=8 + base size=32 base align=8 +QQuickFramebufferObject (0x0x7f5a22c4ea90) 0 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 16u) + QQuickItem (0x0x7f5a22d11c40) 0 + primary-for QQuickFramebufferObject (0x0x7f5a22c4ea90) + QObject (0x0x7f5a22ccc6c0) 0 + primary-for QQuickItem (0x0x7f5a22d11c40) + QQmlParserStatus (0x0x7f5a22ccc720) 16 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 416u) + +Class QQuickTextureFactory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextureFactory::QPrivateSignal (0x0x7f5a22ccc8a0) 0 empty + +Vtable for QQuickTextureFactory +QQuickTextureFactory::_ZTV20QQuickTextureFactory: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickTextureFactory) +16 (int (*)(...))QQuickTextureFactory::metaObject +24 (int (*)(...))QQuickTextureFactory::qt_metacast +32 (int (*)(...))QQuickTextureFactory::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))QQuickTextureFactory::image + +Class QQuickTextureFactory + size=16 align=8 + base size=16 base align=8 +QQuickTextureFactory (0x0x7f5a22c4eaf8) 0 + vptr=((& QQuickTextureFactory::_ZTV20QQuickTextureFactory) + 16u) + QObject (0x0x7f5a22ccc840) 0 + primary-for QQuickTextureFactory (0x0x7f5a22c4eaf8) + +Class QQuickImageResponse::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickImageResponse::QPrivateSignal (0x0x7f5a22ccc960) 0 empty + +Vtable for QQuickImageResponse +QQuickImageResponse::_ZTV19QQuickImageResponse: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageResponse) +16 (int (*)(...))QQuickImageResponse::metaObject +24 (int (*)(...))QQuickImageResponse::qt_metacast +32 (int (*)(...))QQuickImageResponse::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQuickImageResponse::errorString +128 (int (*)(...))QQuickImageResponse::cancel + +Class QQuickImageResponse + size=16 align=8 + base size=16 base align=8 +QQuickImageResponse (0x0x7f5a22c4eb60) 0 + vptr=((& QQuickImageResponse::_ZTV19QQuickImageResponse) + 16u) + QObject (0x0x7f5a22ccc900) 0 + primary-for QQuickImageResponse (0x0x7f5a22c4eb60) + +Vtable for QQuickImageProvider +QQuickImageProvider::_ZTV19QQuickImageProvider: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageProvider) +16 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +24 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +32 (int (*)(...))QQuickImageProvider::imageType +40 (int (*)(...))QQuickImageProvider::flags +48 (int (*)(...))QQuickImageProvider::requestImage +56 (int (*)(...))QQuickImageProvider::requestPixmap +64 (int (*)(...))QQuickImageProvider::requestTexture + +Class QQuickImageProvider + size=16 align=8 + base size=16 base align=8 +QQuickImageProvider (0x0x7f5a22c4ebc8) 0 + vptr=((& QQuickImageProvider::_ZTV19QQuickImageProvider) + 16u) + QQmlImageProviderBase (0x0x7f5a22ccc9c0) 0 nearly-empty + primary-for QQuickImageProvider (0x0x7f5a22c4ebc8) + +Vtable for QQuickAsyncImageProvider +QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQuickAsyncImageProvider) +16 0u +24 0u +32 (int (*)(...))QQuickImageProvider::imageType +40 (int (*)(...))QQuickImageProvider::flags +48 (int (*)(...))QQuickImageProvider::requestImage +56 (int (*)(...))QQuickImageProvider::requestPixmap +64 (int (*)(...))QQuickImageProvider::requestTexture +72 (int (*)(...))__cxa_pure_virtual + +Class QQuickAsyncImageProvider + size=24 align=8 + base size=24 base align=8 +QQuickAsyncImageProvider (0x0x7f5a22c4ec30) 0 + vptr=((& QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider) + 16u) + QQuickImageProvider (0x0x7f5a22c4ec98) 0 + primary-for QQuickAsyncImageProvider (0x0x7f5a22c4ec30) + QQmlImageProviderBase (0x0x7f5a22ccca20) 0 nearly-empty + primary-for QQuickImageProvider (0x0x7f5a22c4ec98) + +Class QQuickItemGrabResult::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItemGrabResult::QPrivateSignal (0x0x7f5a22cccae0) 0 empty + +Vtable for QQuickItemGrabResult +QQuickItemGrabResult::_ZTV20QQuickItemGrabResult: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickItemGrabResult) +16 (int (*)(...))QQuickItemGrabResult::metaObject +24 (int (*)(...))QQuickItemGrabResult::qt_metacast +32 (int (*)(...))QQuickItemGrabResult::qt_metacall +40 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +48 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +56 (int (*)(...))QQuickItemGrabResult::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickItemGrabResult + size=16 align=8 + base size=16 base align=8 +QQuickItemGrabResult (0x0x7f5a22c4ed00) 0 + vptr=((& QQuickItemGrabResult::_ZTV20QQuickItemGrabResult) + 16u) + QObject (0x0x7f5a22ccca80) 0 + primary-for QQuickItemGrabResult (0x0x7f5a22c4ed00) + +Class QQuickPaintedItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickPaintedItem::QPrivateSignal (0x0x7f5a22cccc00) 0 empty + +Vtable for QQuickPaintedItem +QQuickPaintedItem::_ZTV17QQuickPaintedItem: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QQuickPaintedItem) +16 (int (*)(...))QQuickPaintedItem::metaObject +24 (int (*)(...))QQuickPaintedItem::qt_metacast +32 (int (*)(...))QQuickPaintedItem::qt_metacall +40 0u +48 0u +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickPaintedItem::isTextureProvider +152 (int (*)(...))QQuickPaintedItem::textureProvider +160 (int (*)(...))QQuickPaintedItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickItem::geometryChanged +368 (int (*)(...))QQuickPaintedItem::updatePaintNode +376 (int (*)(...))QQuickPaintedItem::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))-16 +408 (int (*)(...))(& _ZTI17QQuickPaintedItem) +416 0u +424 0u +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickPaintedItem + size=32 align=8 + base size=32 base align=8 +QQuickPaintedItem (0x0x7f5a22c4ed68) 0 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 16u) + QQuickItem (0x0x7f5a22d4caf0) 0 + primary-for QQuickPaintedItem (0x0x7f5a22c4ed68) + QObject (0x0x7f5a22cccb40) 0 + primary-for QQuickItem (0x0x7f5a22d4caf0) + QQmlParserStatus (0x0x7f5a22cccba0) 16 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 416u) + +Class QQuickRenderControl::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickRenderControl::QPrivateSignal (0x0x7f5a22ccce40) 0 empty + +Vtable for QQuickRenderControl +QQuickRenderControl::_ZTV19QQuickRenderControl: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickRenderControl) +16 (int (*)(...))QQuickRenderControl::metaObject +24 (int (*)(...))QQuickRenderControl::qt_metacast +32 (int (*)(...))QQuickRenderControl::qt_metacall +40 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +48 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickRenderControl::renderWindow + +Class QQuickRenderControl + size=16 align=8 + base size=16 base align=8 +QQuickRenderControl (0x0x7f5a22c4ef08) 0 + vptr=((& QQuickRenderControl::_ZTV19QQuickRenderControl) + 16u) + QObject (0x0x7f5a22cccde0) 0 + primary-for QQuickRenderControl (0x0x7f5a22c4ef08) + +Class QQuickTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextDocument::QPrivateSignal (0x0x7f5a22cccf00) 0 empty + +Vtable for QQuickTextDocument +QQuickTextDocument::_ZTV18QQuickTextDocument: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QQuickTextDocument) +16 (int (*)(...))QQuickTextDocument::metaObject +24 (int (*)(...))QQuickTextDocument::qt_metacast +32 (int (*)(...))QQuickTextDocument::qt_metacall +40 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +48 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickTextDocument + size=16 align=8 + base size=16 base align=8 +QQuickTextDocument (0x0x7f5a22c4ef70) 0 + vptr=((& QQuickTextDocument::_ZTV18QQuickTextDocument) + 16u) + QObject (0x0x7f5a22cccea0) 0 + primary-for QQuickTextDocument (0x0x7f5a22c4ef70) + +Class QSGGeometry::Attribute + size=16 align=4 + base size=16 base align=4 +QSGGeometry::Attribute (0x0x7f5a347c6060) 0 + +Class QSGGeometry::AttributeSet + size=16 align=8 + base size=16 base align=8 +QSGGeometry::AttributeSet (0x0x7f5a347c60c0) 0 + +Class QSGGeometry::Point2D + size=8 align=4 + base size=8 base align=4 +QSGGeometry::Point2D (0x0x7f5a347c6120) 0 + +Class QSGGeometry::TexturedPoint2D + size=16 align=4 + base size=16 base align=4 +QSGGeometry::TexturedPoint2D (0x0x7f5a347c6180) 0 + +Class QSGGeometry::ColoredPoint2D + size=12 align=4 + base size=12 base align=4 +QSGGeometry::ColoredPoint2D (0x0x7f5a347c6660) 0 + +Vtable for QSGGeometry +QSGGeometry::_ZTV11QSGGeometry: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGGeometry) +16 (int (*)(...))QSGGeometry::~QSGGeometry +24 (int (*)(...))QSGGeometry::~QSGGeometry + +Class QSGGeometry + size=128 align=8 + base size=128 base align=8 +QSGGeometry (0x0x7f5a34750660) 0 + vptr=((& QSGGeometry::_ZTV11QSGGeometry) + 16u) + +Vtable for QSGNode +QSGNode::_ZTV7QSGNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QSGNode) +16 (int (*)(...))QSGNode::~QSGNode +24 (int (*)(...))QSGNode::~QSGNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGNode + size=80 align=8 + base size=80 base align=8 +QSGNode (0x0x7f5a2cd3a120) 0 + vptr=((& QSGNode::_ZTV7QSGNode) + 16u) + +Vtable for QSGBasicGeometryNode +QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGBasicGeometryNode) +16 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +24 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGBasicGeometryNode + size=112 align=8 + base size=112 base align=8 +QSGBasicGeometryNode (0x0x7f5a2daabd00) 0 + vptr=((& QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode) + 16u) + QSGNode (0x0x7f5a2cd5cae0) 0 + primary-for QSGBasicGeometryNode (0x0x7f5a2daabd00) + +Vtable for QSGGeometryNode +QSGGeometryNode::_ZTV15QSGGeometryNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSGGeometryNode) +16 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +24 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGGeometryNode + size=144 align=8 + base size=144 base align=8 +QSGGeometryNode (0x0x7f5a2daabd68) 0 + vptr=((& QSGGeometryNode::_ZTV15QSGGeometryNode) + 16u) + QSGBasicGeometryNode (0x0x7f5a2d2777b8) 0 + primary-for QSGGeometryNode (0x0x7f5a2daabd68) + QSGNode (0x0x7f5a2cd5cb40) 0 + primary-for QSGBasicGeometryNode (0x0x7f5a2d2777b8) + +Vtable for QSGClipNode +QSGClipNode::_ZTV11QSGClipNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGClipNode) +16 (int (*)(...))QSGClipNode::~QSGClipNode +24 (int (*)(...))QSGClipNode::~QSGClipNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGClipNode + size=152 align=8 + base size=152 base align=8 +QSGClipNode (0x0x7f5a2d277820) 0 + vptr=((& QSGClipNode::_ZTV11QSGClipNode) + 16u) + QSGBasicGeometryNode (0x0x7f5a2ccd7af8) 0 + primary-for QSGClipNode (0x0x7f5a2d277820) + QSGNode (0x0x7f5a2cd5cea0) 0 + primary-for QSGBasicGeometryNode (0x0x7f5a2ccd7af8) + +Vtable for QSGTransformNode +QSGTransformNode::_ZTV16QSGTransformNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGTransformNode) +16 (int (*)(...))QSGTransformNode::~QSGTransformNode +24 (int (*)(...))QSGTransformNode::~QSGTransformNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGTransformNode + size=216 align=8 + base size=216 base align=8 +QSGTransformNode (0x0x7f5a2ccd7b60) 0 + vptr=((& QSGTransformNode::_ZTV16QSGTransformNode) + 16u) + QSGNode (0x0x7f5a2cd5cf00) 0 + primary-for QSGTransformNode (0x0x7f5a2ccd7b60) + +Vtable for QSGRootNode +QSGRootNode::_ZTV11QSGRootNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGRootNode) +16 (int (*)(...))QSGRootNode::~QSGRootNode +24 (int (*)(...))QSGRootNode::~QSGRootNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGRootNode + size=88 align=8 + base size=88 base align=8 +QSGRootNode (0x0x7f5a2cd51068) 0 + vptr=((& QSGRootNode::_ZTV11QSGRootNode) + 16u) + QSGNode (0x0x7f5a2cd7b600) 0 + primary-for QSGRootNode (0x0x7f5a2cd51068) + +Vtable for QSGOpacityNode +QSGOpacityNode::_ZTV14QSGOpacityNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGOpacityNode) +16 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +24 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +32 (int (*)(...))QSGOpacityNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGOpacityNode + size=96 align=8 + base size=96 base align=8 +QSGOpacityNode (0x0x7f5a2cd74888) 0 + vptr=((& QSGOpacityNode::_ZTV14QSGOpacityNode) + 16u) + QSGNode (0x0x7f5a2cb2e1e0) 0 + primary-for QSGOpacityNode (0x0x7f5a2cd74888) + +Vtable for QSGNodeVisitor +QSGNodeVisitor::_ZTV14QSGNodeVisitor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGNodeVisitor) +16 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +24 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +32 (int (*)(...))QSGNodeVisitor::enterTransformNode +40 (int (*)(...))QSGNodeVisitor::leaveTransformNode +48 (int (*)(...))QSGNodeVisitor::enterClipNode +56 (int (*)(...))QSGNodeVisitor::leaveClipNode +64 (int (*)(...))QSGNodeVisitor::enterGeometryNode +72 (int (*)(...))QSGNodeVisitor::leaveGeometryNode +80 (int (*)(...))QSGNodeVisitor::enterOpacityNode +88 (int (*)(...))QSGNodeVisitor::leaveOpacityNode +96 (int (*)(...))QSGNodeVisitor::visitNode +104 (int (*)(...))QSGNodeVisitor::visitChildren + +Class QSGNodeVisitor + size=8 align=8 + base size=8 base align=8 +QSGNodeVisitor (0x0x7f5a2cb2e240) 0 nearly-empty + vptr=((& QSGNodeVisitor::_ZTV14QSGNodeVisitor) + 16u) + +Vtable for QSGRendererInterface +QSGRendererInterface::_ZTV20QSGRendererInterface: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGRendererInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QSGRendererInterface::getResource +48 (int (*)(...))QSGRendererInterface::getResource +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRendererInterface + size=8 align=8 + base size=8 base align=8 +QSGRendererInterface (0x0x7f5a2cb2e300) 0 nearly-empty + vptr=((& QSGRendererInterface::_ZTV20QSGRendererInterface) + 16u) + +Class QQuickWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickWindow::QPrivateSignal (0x0x7f5a2c8640c0) 0 empty + +Vtable for QQuickWindow +QQuickWindow::_ZTV12QQuickWindow: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QQuickWindow) +16 (int (*)(...))QQuickWindow::metaObject +24 (int (*)(...))QQuickWindow::qt_metacast +32 (int (*)(...))QQuickWindow::qt_metacall +40 (int (*)(...))QQuickWindow::~QQuickWindow +48 (int (*)(...))QQuickWindow::~QQuickWindow +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QQuickWindow::focusInEvent +184 (int (*)(...))QQuickWindow::focusOutEvent +192 (int (*)(...))QQuickWindow::showEvent +200 (int (*)(...))QQuickWindow::hideEvent +208 (int (*)(...))QQuickWindow::keyPressEvent +216 (int (*)(...))QQuickWindow::keyReleaseEvent +224 (int (*)(...))QQuickWindow::mousePressEvent +232 (int (*)(...))QQuickWindow::mouseReleaseEvent +240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +248 (int (*)(...))QQuickWindow::mouseMoveEvent +256 (int (*)(...))QQuickWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI12QQuickWindow) +312 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD1Ev +320 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickWindow + size=40 align=8 + base size=40 base align=8 +QQuickWindow (0x0x7f5a2c9575b0) 0 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 16u) + QWindow (0x0x7f5a2faed380) 0 + primary-for QQuickWindow (0x0x7f5a2c9575b0) + QObject (0x0x7f5a2c864000) 0 + primary-for QWindow (0x0x7f5a2faed380) + QSurface (0x0x7f5a2c864060) 16 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 312u) + +Class QQuickView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickView::QPrivateSignal (0x0x7f5a2c5f67e0) 0 empty + +Vtable for QQuickView +QQuickView::_ZTV10QQuickView: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickView) +16 (int (*)(...))QQuickView::metaObject +24 (int (*)(...))QQuickView::qt_metacast +32 (int (*)(...))QQuickView::qt_metacall +40 (int (*)(...))QQuickView::~QQuickView +48 (int (*)(...))QQuickView::~QQuickView +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QQuickView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickView::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QQuickWindow::focusInEvent +184 (int (*)(...))QQuickWindow::focusOutEvent +192 (int (*)(...))QQuickWindow::showEvent +200 (int (*)(...))QQuickWindow::hideEvent +208 (int (*)(...))QQuickView::keyPressEvent +216 (int (*)(...))QQuickView::keyReleaseEvent +224 (int (*)(...))QQuickView::mousePressEvent +232 (int (*)(...))QQuickView::mouseReleaseEvent +240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +248 (int (*)(...))QQuickView::mouseMoveEvent +256 (int (*)(...))QQuickWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI10QQuickView) +312 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD1Ev +320 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickView + size=40 align=8 + base size=40 base align=8 +QQuickView (0x0x7f5a2c76e2d8) 0 + vptr=((& QQuickView::_ZTV10QQuickView) + 16u) + QQuickWindow (0x0x7f5a2c76e340) 0 + primary-for QQuickView (0x0x7f5a2c76e2d8) + QWindow (0x0x7f5a2fb0a9a0) 0 + primary-for QQuickWindow (0x0x7f5a2c76e340) + QObject (0x0x7f5a2c5f66c0) 0 + primary-for QWindow (0x0x7f5a2fb0a9a0) + QSurface (0x0x7f5a2c5f6720) 16 + vptr=((& QQuickView::_ZTV10QQuickView) + 312u) + +Class QSGAbstractRenderer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGAbstractRenderer::QPrivateSignal (0x0x7f5a2c4868a0) 0 empty + +Vtable for QSGAbstractRenderer +QSGAbstractRenderer::_ZTV19QSGAbstractRenderer: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QSGAbstractRenderer) +16 (int (*)(...))QSGAbstractRenderer::metaObject +24 (int (*)(...))QSGAbstractRenderer::qt_metacast +32 (int (*)(...))QSGAbstractRenderer::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QSGAbstractRenderer + size=16 align=8 + base size=16 base align=8 +QSGAbstractRenderer (0x0x7f5a2c76e3a8) 0 + vptr=((& QSGAbstractRenderer::_ZTV19QSGAbstractRenderer) + 16u) + QObject (0x0x7f5a2c5f6840) 0 + primary-for QSGAbstractRenderer (0x0x7f5a2c76e3a8) + +Class QSGEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGEngine::QPrivateSignal (0x0x7f5a2c1587e0) 0 empty + +Vtable for QSGEngine +QSGEngine::_ZTV9QSGEngine: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSGEngine) +16 (int (*)(...))QSGEngine::metaObject +24 (int (*)(...))QSGEngine::qt_metacast +32 (int (*)(...))QSGEngine::qt_metacall +40 (int (*)(...))QSGEngine::~QSGEngine +48 (int (*)(...))QSGEngine::~QSGEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSGEngine + size=16 align=8 + base size=16 base align=8 +QSGEngine (0x0x7f5a2c76e4e0) 0 + vptr=((& QSGEngine::_ZTV9QSGEngine) + 16u) + QObject (0x0x7f5a2c158780) 0 + primary-for QSGEngine (0x0x7f5a2c76e4e0) + +Class QSGMaterialShader::RenderState + size=16 align=8 + base size=16 base align=8 +QSGMaterialShader::RenderState (0x0x7f5a2c1a9300) 0 + +Vtable for QSGMaterialShader +QSGMaterialShader::_ZTV17QSGMaterialShader: 12u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGMaterialShader) +16 0u +24 0u +32 (int (*)(...))QSGMaterialShader::activate +40 (int (*)(...))QSGMaterialShader::deactivate +48 (int (*)(...))QSGMaterialShader::updateState +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QSGMaterialShader::compile +72 (int (*)(...))QSGMaterialShader::initialize +80 (int (*)(...))QSGMaterialShader::vertexShader +88 (int (*)(...))QSGMaterialShader::fragmentShader + +Class QSGMaterialShader + size=32 align=8 + base size=32 base align=8 +QSGMaterialShader (0x0x7f5a2c180ae0) 0 + vptr=((& QSGMaterialShader::_ZTV17QSGMaterialShader) + 16u) + +Class QSGMaterialType + size=1 align=1 + base size=0 base align=1 +QSGMaterialType (0x0x7f5a2bcf6ba0) 0 empty + +Vtable for QSGMaterial +QSGMaterial::_ZTV11QSGMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGMaterial) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QSGMaterial::compare + +Class QSGMaterial + size=24 align=8 + base size=24 base align=8 +QSGMaterial (0x0x7f5a2bad8000) 0 + vptr=((& QSGMaterial::_ZTV11QSGMaterial) + 16u) + +Vtable for QSGFlatColorMaterial +QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGFlatColorMaterial) +16 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +24 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +32 (int (*)(...))QSGFlatColorMaterial::type +40 (int (*)(...))QSGFlatColorMaterial::createShader +48 (int (*)(...))QSGFlatColorMaterial::compare + +Class QSGFlatColorMaterial + size=40 align=8 + base size=40 base align=8 +QSGFlatColorMaterial (0x0x7f5a2c76e820) 0 + vptr=((& QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial) + 16u) + QSGMaterial (0x0x7f5a2bad85a0) 0 + primary-for QSGFlatColorMaterial (0x0x7f5a2c76e820) + +Class QSGTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTexture::QPrivateSignal (0x0x7f5a2bad8720) 0 empty + +Vtable for QSGTexture +QSGTexture::_ZTV10QSGTexture: 22u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSGTexture) +16 (int (*)(...))QSGTexture::metaObject +24 (int (*)(...))QSGTexture::qt_metacast +32 (int (*)(...))QSGTexture::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QSGTexture::normalizedTextureSubRect +152 (int (*)(...))QSGTexture::isAtlasTexture +160 (int (*)(...))QSGTexture::removedFromAtlas +168 (int (*)(...))__cxa_pure_virtual + +Class QSGTexture + size=16 align=8 + base size=16 base align=8 +QSGTexture (0x0x7f5a2c76e888) 0 + vptr=((& QSGTexture::_ZTV10QSGTexture) + 16u) + QObject (0x0x7f5a2bad8660) 0 + primary-for QSGTexture (0x0x7f5a2c76e888) + +Class QSGDynamicTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGDynamicTexture::QPrivateSignal (0x0x7f5a2bafd360) 0 empty + +Vtable for QSGDynamicTexture +QSGDynamicTexture::_ZTV17QSGDynamicTexture: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGDynamicTexture) +16 (int (*)(...))QSGDynamicTexture::metaObject +24 (int (*)(...))QSGDynamicTexture::qt_metacast +32 (int (*)(...))QSGDynamicTexture::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QSGTexture::normalizedTextureSubRect +152 (int (*)(...))QSGTexture::isAtlasTexture +160 (int (*)(...))QSGTexture::removedFromAtlas +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QSGDynamicTexture + size=16 align=8 + base size=16 base align=8 +QSGDynamicTexture (0x0x7f5a2c76e8f0) 0 + vptr=((& QSGDynamicTexture::_ZTV17QSGDynamicTexture) + 16u) + QSGTexture (0x0x7f5a2c76e958) 0 + primary-for QSGDynamicTexture (0x0x7f5a2c76e8f0) + QObject (0x0x7f5a2bad8780) 0 + primary-for QSGTexture (0x0x7f5a2c76e958) + +Vtable for QSGImageNode +QSGImageNode::_ZTV12QSGImageNode: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QSGImageNode) +16 0u +24 0u +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QSGImageNode + size=144 align=8 + base size=144 base align=8 +QSGImageNode (0x0x7f5a2c76e9c0) 0 + vptr=((& QSGImageNode::_ZTV12QSGImageNode) + 16u) + QSGGeometryNode (0x0x7f5a2c76ea28) 0 + primary-for QSGImageNode (0x0x7f5a2c76e9c0) + QSGBasicGeometryNode (0x0x7f5a2c76ea90) 0 + primary-for QSGGeometryNode (0x0x7f5a2c76ea28) + QSGNode (0x0x7f5a2bafd3c0) 0 + primary-for QSGBasicGeometryNode (0x0x7f5a2c76ea90) + +Vtable for QSGNinePatchNode +QSGNinePatchNode::_ZTV16QSGNinePatchNode: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGNinePatchNode) +16 0u +24 0u +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual + +Class QSGNinePatchNode + size=144 align=8 + base size=144 base align=8 +QSGNinePatchNode (0x0x7f5a2c863000) 0 + vptr=((& QSGNinePatchNode::_ZTV16QSGNinePatchNode) + 16u) + QSGGeometryNode (0x0x7f5a2c8630d0) 0 + primary-for QSGNinePatchNode (0x0x7f5a2c863000) + QSGBasicGeometryNode (0x0x7f5a2c863138) 0 + primary-for QSGGeometryNode (0x0x7f5a2c8630d0) + QSGNode (0x0x7f5a2afbe4e0) 0 + primary-for QSGBasicGeometryNode (0x0x7f5a2c863138) + +Vtable for QSGRectangleNode +QSGRectangleNode::_ZTV16QSGRectangleNode: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGRectangleNode) +16 0u +24 0u +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRectangleNode + size=144 align=8 + base size=144 base align=8 +QSGRectangleNode (0x0x7f5a2c8631a0) 0 + vptr=((& QSGRectangleNode::_ZTV16QSGRectangleNode) + 16u) + QSGGeometryNode (0x0x7f5a2c863208) 0 + primary-for QSGRectangleNode (0x0x7f5a2c8631a0) + QSGBasicGeometryNode (0x0x7f5a2c863270) 0 + primary-for QSGGeometryNode (0x0x7f5a2c863208) + QSGNode (0x0x7f5a2afbe540) 0 + primary-for QSGBasicGeometryNode (0x0x7f5a2c863270) + +Vtable for QSGRenderNode::RenderState +QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QSGRenderNode11RenderStateE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))QSGRenderNode::RenderState::get + +Class QSGRenderNode::RenderState + size=8 align=8 + base size=8 base align=8 +QSGRenderNode::RenderState (0x0x7f5a2afbe9c0) 0 nearly-empty + vptr=((& QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE) + 16u) + +Vtable for QSGRenderNode +QSGRenderNode::_ZTV13QSGRenderNode: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSGRenderNode) +16 0u +24 0u +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))QSGRenderNode::changedStates +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QSGRenderNode::releaseResources +72 (int (*)(...))QSGRenderNode::flags +80 (int (*)(...))QSGRenderNode::rect + +Class QSGRenderNode + size=88 align=8 + base size=88 base align=8 +QSGRenderNode (0x0x7f5a2c8632d8) 0 + vptr=((& QSGRenderNode::_ZTV13QSGRenderNode) + 16u) + QSGNode (0x0x7f5a2afbe960) 0 + primary-for QSGRenderNode (0x0x7f5a2c8632d8) + +Vtable for QSGSimpleRectNode +QSGSimpleRectNode::_ZTV17QSGSimpleRectNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGSimpleRectNode) +16 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +24 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleRectNode + size=320 align=8 + base size=320 base align=8 +QSGSimpleRectNode (0x0x7f5a2c729680) 0 + vptr=((& QSGSimpleRectNode::_ZTV17QSGSimpleRectNode) + 16u) + QSGGeometryNode (0x0x7f5a2c729958) 0 + primary-for QSGSimpleRectNode (0x0x7f5a2c729680) + QSGBasicGeometryNode (0x0x7f5a2c7299c0) 0 + primary-for QSGGeometryNode (0x0x7f5a2c729958) + QSGNode (0x0x7f5a2b090660) 0 + primary-for QSGBasicGeometryNode (0x0x7f5a2c7299c0) + +Vtable for QSGOpaqueTextureMaterial +QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QSGOpaqueTextureMaterial) +16 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +24 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +32 (int (*)(...))QSGOpaqueTextureMaterial::type +40 (int (*)(...))QSGOpaqueTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGOpaqueTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGOpaqueTextureMaterial (0x0x7f5a2c729bc8) 0 + vptr=((& QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial) + 16u) + QSGMaterial (0x0x7f5a2b0906c0) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7f5a2c729bc8) + +Vtable for QSGTextureMaterial +QSGTextureMaterial::_ZTV18QSGTextureMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureMaterial) +16 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +24 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +32 (int (*)(...))QSGTextureMaterial::type +40 (int (*)(...))QSGTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGTextureMaterial (0x0x7f5a2c729c30) 0 + vptr=((& QSGTextureMaterial::_ZTV18QSGTextureMaterial) + 16u) + QSGOpaqueTextureMaterial (0x0x7f5a2c729c98) 0 + primary-for QSGTextureMaterial (0x0x7f5a2c729c30) + QSGMaterial (0x0x7f5a2ad40840) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7f5a2c729c98) + +Vtable for QSGSimpleTextureNode +QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGSimpleTextureNode) +16 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +24 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleTextureNode + size=384 align=8 + base size=384 base align=8 +QSGSimpleTextureNode (0x0x7f5a2c729d00) 0 + vptr=((& QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode) + 16u) + QSGGeometryNode (0x0x7f5a2c429e38) 0 + primary-for QSGSimpleTextureNode (0x0x7f5a2c729d00) + QSGBasicGeometryNode (0x0x7f5a2c429ea0) 0 + primary-for QSGGeometryNode (0x0x7f5a2c429e38) + QSGNode (0x0x7f5a2ad408a0) 0 + primary-for QSGBasicGeometryNode (0x0x7f5a2c429ea0) + +Class QSGTextureProvider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTextureProvider::QPrivateSignal (0x0x7f5a2aa63720) 0 empty + +Vtable for QSGTextureProvider +QSGTextureProvider::_ZTV18QSGTextureProvider: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureProvider) +16 (int (*)(...))QSGTextureProvider::metaObject +24 (int (*)(...))QSGTextureProvider::qt_metacast +32 (int (*)(...))QSGTextureProvider::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSGTextureProvider + size=16 align=8 + base size=16 base align=8 +QSGTextureProvider (0x0x7f5a2c429958) 0 + vptr=((& QSGTextureProvider::_ZTV18QSGTextureProvider) + 16u) + QObject (0x0x7f5a2aa636c0) 0 + primary-for QSGTextureProvider (0x0x7f5a2c429958) + +Vtable for QSGVertexColorMaterial +QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QSGVertexColorMaterial) +16 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +24 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +32 (int (*)(...))QSGVertexColorMaterial::type +40 (int (*)(...))QSGVertexColorMaterial::createShader +48 (int (*)(...))QSGVertexColorMaterial::compare + +Class QSGVertexColorMaterial + size=24 align=8 + base size=24 base align=8 +QSGVertexColorMaterial (0x0x7f5a2c4299c0) 0 + vptr=((& QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial) + 16u) + QSGMaterial (0x0x7f5a2aaec240) 0 + primary-for QSGVertexColorMaterial (0x0x7f5a2c4299c0) + +Class QQuickStyle + size=1 align=1 + base size=0 base align=1 +QQuickStyle (0x0x7f5a2aaec2a0) 0 empty + diff --git a/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.13.0.linux-gcc-amd64.txt b/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.13.0.linux-gcc-amd64.txt new file mode 100644 index 00000000000..07ba810c43f --- /dev/null +++ b/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.13.0.linux-gcc-amd64.txt @@ -0,0 +1,11498 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f22c330aae0) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f22c33982a0) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f22c33984e0) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f22c3398720) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f22c3398960) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f22c3398ae0) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f22c3398ea0) 0 empty + +Class std::__do_is_implicitly_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_implicitly_default_constructible_impl (0x0x7f22c3403000) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f22c30586c0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f22c3058780) 0 empty + +Class std::__invoke_memfun_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_ref (0x0x7f22c3058b40) 0 empty + +Class std::__invoke_memfun_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_deref (0x0x7f22c3058ba0) 0 empty + +Class std::__invoke_memobj_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_ref (0x0x7f22c3058c00) 0 empty + +Class std::__invoke_memobj_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_deref (0x0x7f22c3058c60) 0 empty + +Class std::__invoke_other + size=1 align=1 + base size=0 base align=1 +std::__invoke_other (0x0x7f22c3058cc0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f22c3058d80) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f22c3058e40) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f22c3058f00) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f22c308a000) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f22c308a360) 0 empty + +Class std::__swappable_details::__do_is_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_swappable_impl (0x0x7f22c308a6c0) 0 empty + +Class std::__swappable_details::__do_is_nothrow_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_nothrow_swappable_impl (0x0x7f22c308a720) 0 empty + +Class std::__nonesuch + size=1 align=1 + base size=0 base align=1 +std::__nonesuch (0x0x7f22c308acc0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f22c30d3360) 0 empty + +Class std::__nonesuch_no_braces + size=1 align=1 + base size=1 base align=1 +std::__nonesuch_no_braces (0x0x7f22c30f6000) 0 empty + std::__nonesuch (0x0x7f22c30d3840) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f22c31551e0) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f22c3155240) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f22c3188f00) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f22c3188f60) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f22c30f64e0) 0 empty + std::input_iterator_tag (0x0x7f22c31b2000) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f22c30f6548) 0 empty + std::forward_iterator_tag (0x0x7f22c30f65b0) 0 empty + std::input_iterator_tag (0x0x7f22c31b2060) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f22c30f6618) 0 empty + std::bidirectional_iterator_tag (0x0x7f22c30f6680) 0 empty + std::forward_iterator_tag (0x0x7f22c30f66e8) 0 empty + std::input_iterator_tag (0x0x7f22c31b20c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f22c323eba0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f22c323ecc0) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f22c2e63000) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f22c2e63300) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f22c2e63420) 0 empty + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f22c2ef3720) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f22c2ef3a20) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f22c2ef3a80) 0 + +Class __pthread_rwlock_arch_t + size=56 align=8 + base size=56 base align=8 +__pthread_rwlock_arch_t (0x0x7f22c2ef3b40) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f22c2ef3ba0) 0 + +Class __pthread_mutex_s + size=40 align=8 + base size=40 base align=8 +__pthread_mutex_s (0x0x7f22c2ef3c00) 0 + +Class __pthread_cond_s + size=48 align=8 + base size=48 base align=8 +__pthread_cond_s (0x0x7f22c2ef3c60) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f22c2ef3f00) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f22c2f311e0) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f22c2f31240) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f22c2feb000) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f22c30f6a28) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16) + std::exception (0x0x7f22c2feb1e0) 0 nearly-empty + primary-for std::bad_exception (0x0x7f22c30f6a28) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f22c2feb3c0) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f22c30f6a90) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16) + std::exception (0x0x7f22c2feb780) 0 nearly-empty + primary-for std::bad_cast (0x0x7f22c30f6a90) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f22c30f6af8) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16) + std::exception (0x0x7f22c2feb960) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f22c30f6af8) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f22c2febb40) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f22c3022120) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f22c30f6b60) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16) + std::exception (0x0x7f22c30227e0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f22c30f6b60) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f22c30f6bc8) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16) + std::bad_alloc (0x0x7f22c30f6c30) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f22c30f6bc8) + std::exception (0x0x7f22c30229c0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f22c30f6c30) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f22c3022ba0) 0 empty + +Class std::__allocator_traits_base + size=1 align=1 + base size=0 base align=1 +std::__allocator_traits_base (0x0x7f22c3022d80) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f22c2cc92a0) 0 empty + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f22c2a7fd20) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f22c2a7fde0) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f22c2941780) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f22c29418a0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f22c2941c00) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f22c297f180) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f22c29c0900) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f22c2652d20) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f22c29fea90) 0 + std::__atomic_flag_base (0x0x7f22c2652d80) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f22c24b7208) 0 + QAtomicInteger<int> (0x0x7f22c24b7270) 0 + QBasicAtomicInteger<int> (0x0x7f22c258ad20) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f22c21bc060) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f22c2201600) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f22c2201d20) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f22c23aadd0) 0 + QGenericArgument (0x0x7f22c223f000) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f22c223f420) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f22c223f840) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f22c1ef3360) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f22c1ef3600) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f22c1fbe420) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f22c1fbe780) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f22c2021a80) 0 empty + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f22c1d18300) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f22c1d183c0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f22c1dcb4e0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f22c1dcb5a0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f22c1dcb600) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f22c1dcb660) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f22c1dcb6c0) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f22c1dcb7e0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f22c1dcb840) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f22c1b0c7e0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f22c1b0c840) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f22c18c18a0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f22c18c1a20) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f22c1a39ba0) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f22c1a39f60) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f22c168a240) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f22c168a420) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f22c16d1420) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f22c18def08) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16) + std::exception (0x0x7f22c16d14e0) 0 nearly-empty + primary-for std::logic_error (0x0x7f22c18def08) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f22c18def70) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16) + std::logic_error (0x0x7f22c18de410) 0 + primary-for std::domain_error (0x0x7f22c18def70) + std::exception (0x0x7f22c16d1540) 0 nearly-empty + primary-for std::logic_error (0x0x7f22c18de410) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f22c18de478) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16) + std::logic_error (0x0x7f22c18de7b8) 0 + primary-for std::invalid_argument (0x0x7f22c18de478) + std::exception (0x0x7f22c16d15a0) 0 nearly-empty + primary-for std::logic_error (0x0x7f22c18de7b8) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f22c18de820) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16) + std::logic_error (0x0x7f22c16f9000) 0 + primary-for std::length_error (0x0x7f22c18de820) + std::exception (0x0x7f22c16d1600) 0 nearly-empty + primary-for std::logic_error (0x0x7f22c16f9000) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f22c16f9068) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16) + std::logic_error (0x0x7f22c16f90d0) 0 + primary-for std::out_of_range (0x0x7f22c16f9068) + std::exception (0x0x7f22c16d1660) 0 nearly-empty + primary-for std::logic_error (0x0x7f22c16f90d0) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f22c16f9138) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16) + std::exception (0x0x7f22c16d16c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f22c16f9138) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f22c16f91a0) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16) + std::runtime_error (0x0x7f22c16f9208) 0 + primary-for std::range_error (0x0x7f22c16f91a0) + std::exception (0x0x7f22c16d1720) 0 nearly-empty + primary-for std::runtime_error (0x0x7f22c16f9208) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f22c16f9270) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16) + std::runtime_error (0x0x7f22c16f92d8) 0 + primary-for std::overflow_error (0x0x7f22c16f9270) + std::exception (0x0x7f22c16d1780) 0 nearly-empty + primary-for std::runtime_error (0x0x7f22c16f92d8) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f22c16f9340) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16) + std::runtime_error (0x0x7f22c16f93a8) 0 + primary-for std::underflow_error (0x0x7f22c16f9340) + std::exception (0x0x7f22c16d17e0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f22c16f93a8) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f22c16d1960) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f22c16d1cc0) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f22c172d540) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f22c16f97b8) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16) + std::runtime_error (0x0x7f22c16f9820) 0 + primary-for std::system_error (0x0x7f22c16f97b8) + std::exception (0x0x7f22c1758120) 0 nearly-empty + primary-for std::runtime_error (0x0x7f22c16f9820) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f22c16f9a90) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16) + std::system_error (0x0x7f22c16f9af8) 0 + primary-for std::ios_base::failure (0x0x7f22c16f9a90) + std::runtime_error (0x0x7f22c16f9b60) 0 + primary-for std::system_error (0x0x7f22c16f9af8) + std::exception (0x0x7f22c17886c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f22c16f9b60) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f22c1788720) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f22c1788780) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f22c17887e0) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f22c1788660) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f22c147a120) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f22c1554300) 0 empty + +VTT for std::basic_ostream<char> +std::basic_ostream<char>::_ZTTSo: 2 entries +0 ((& std::basic_ostream<char>::_ZTVSo) + 24) +8 ((& std::basic_ostream<char>::_ZTVSo) + 64) + +VTT for std::basic_ostream<wchar_t> +std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64) + +VTT for std::basic_istream<char> +std::basic_istream<char>::_ZTTSi: 2 entries +0 ((& std::basic_istream<char>::_ZTVSi) + 24) +8 ((& std::basic_istream<char>::_ZTVSi) + 64) + +VTT for std::basic_istream<wchar_t> +std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64) + +Construction vtable for std::basic_istream<char> (0x0x7f22c10e4270 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd0_Si: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream<char> (0x0x7f22c10e4340 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd16_So: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::basic_iostream<char> +std::basic_iostream<char>::_ZTTSd: 7 entries +0 ((& std::basic_iostream<char>::_ZTVSd) + 24) +8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24) +16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64) +24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24) +32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64) +40 ((& std::basic_iostream<char>::_ZTVSd) + 104) +48 ((& std::basic_iostream<char>::_ZTVSd) + 64) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f22c1131000 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f22c11310d0 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7 entries +0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24) +16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64) +24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24) +32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64) +40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104) +48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f22c1121c60) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f22c1121cc0) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f22c0e8c0c0) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f22c0f08f00) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f22c0f333c0) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f22c0ffc180) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f22c0c7cba0) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f22c0c7cb40) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f22c0a5dd20) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f22c0bf95a0) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f22c0a118a0) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f22c0a11960) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f22c06dae40) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f22c0a24410) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f22c06f85a0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f22c0a24548) 0 + std::_Bit_iterator_base (0x0x7f22c0a245b0) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f22c06f8c00) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f22c0a24618) 0 + std::_Bit_iterator_base (0x0x7f22c0a24680) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f22c0729420) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f22c04dea80) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f22c05dd840) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f22c05dd8a0) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f22c05470d0) 0 empty + QListData::NotIndirectLayout (0x0x7f22c05dd900) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f22c0492cb0) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f22c05dd960) 0 empty + QListData::NotIndirectLayout (0x0x7f22c05dd9c0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f22c0547138) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f22c05dda20) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f22c05dda80) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f22c05dd7e0) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f22c02cac60) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f22c03c7300) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f22c03c72a0) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f22c03b4e38) 0 + QList<QString> (0x0x7f22c03b4ea0) 0 + QListSpecialMethods<QString> (0x0x7f22c03c7540) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f22c00950c0) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f22c01191e0) 0 + +Class std::_Rb_tree_header + size=40 align=8 + base size=40 base align=8 +std::_Rb_tree_header (0x0x7f22c0119540) 0 + +Class std::__erased_type + size=1 align=1 + base size=0 base align=1 +std::__erased_type (0x0x7f22bfefcae0) 0 empty + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f22bfefcb40) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f22bfefccc0) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f22bfefcd80) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f22bff0c208) 0 + std::__uses_alloc_base (0x0x7f22bfefcd20) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f22bfc8f120) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f22bfd1e5a0) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f22bfd1e900) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f22bfd1ee40) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f22bfd453c0) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f22bfdb05a0) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f22bfdb0c60) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f22bfdfeae0) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f22bfabc1e0) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f22bfb15720) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f22bf9da540) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f22bf709000) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f22bf709060) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f22bf709240) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f22bf7091e0) 0 + vptr=((& QObject::_ZTV7QObject) + 16) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f22bf7d4060) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f22bf7d41e0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f22bf7d4a80) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f22bf7cc410) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16) + QObject (0x0x7f22bf7d4a20) 0 + primary-for QAbstractAnimation (0x0x7f22bf7cc410) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f22bf7d4e40) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f22bf7cc478) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16) + QObject (0x0x7f22bf7d4de0) 0 + primary-for QAnimationDriver (0x0x7f22bf7cc478) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f22bf8140c0) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f22bf7cc4e0) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16) + QObject (0x0x7f22bf814060) 0 + primary-for QEventLoop (0x0x7f22bf7cc4e0) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f22bf814960) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f22bf814a20) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f22bf814a80) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f22bf7cc618) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16) + QObject (0x0x7f22bf8149c0) 0 + primary-for QAbstractEventDispatcher (0x0x7f22bf7cc618) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f22bf497f70) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16) + std::exception (0x0x7f22bf4ed120) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f22bf497f70) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f22bf4ed1e0) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f22bf4ed240) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f22bf4ed540) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f22bf2e24e0) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f22bf31a180) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f22bf3e7ae0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f22bf3e7a80) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f22bf3e7d80) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f22bf10f360) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f22bf10f420) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f22bf10f3c0) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f22bf10f480) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f22bf10f300) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f22bee67720) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f22beeabd80) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f22beeabd20) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f22beeabea0) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f22beeabe40) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f22bef98060) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f22befe5c60) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f22becb9a80) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f22becb8b60) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16) + QObject (0x0x7f22becb9a20) 0 + primary-for QAbstractItemModel (0x0x7f22becb8b60) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f22bed1de40) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f22bed071a0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16) + QAbstractItemModel (0x0x7f22bed07208) 0 + primary-for QAbstractTableModel (0x0x7f22bed071a0) + QObject (0x0x7f22bed1dde0) 0 + primary-for QAbstractItemModel (0x0x7f22bed07208) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f22beda5000) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f22bed07270) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16) + QAbstractItemModel (0x0x7f22bed072d8) 0 + primary-for QAbstractListModel (0x0x7f22bed07270) + QObject (0x0x7f22bed1df60) 0 + primary-for QAbstractItemModel (0x0x7f22bed072d8) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f22beda5720) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f22beda57e0) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f22bed073a8) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16) + QAbstractItemModel (0x0x7f22bed07410) 0 + primary-for QAbstractProxyModel (0x0x7f22bed073a8) + QObject (0x0x7f22beda5780) 0 + primary-for QAbstractItemModel (0x0x7f22bed07410) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f22beda5a20) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f22bed07478) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16) + QObject (0x0x7f22beda59c0) 0 + primary-for QAbstractState (0x0x7f22bed07478) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f22beda5c60) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f22bed074e0) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16) + QObject (0x0x7f22beda5c00) 0 + primary-for QAbstractTransition (0x0x7f22bed074e0) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f22beda5f60) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f22bed07548) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16) + QAbstractAnimation (0x0x7f22bed075b0) 0 + primary-for QAnimationGroup (0x0x7f22bed07548) + QObject (0x0x7f22beda5f00) 0 + primary-for QAbstractAnimation (0x0x7f22bed075b0) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f22bea82300) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f22beabf6c0) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f22beb14b40) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f22beb68f00) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f22beb71af8) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16) + QObject (0x0x7f22beb68ea0) 0 + primary-for QIODevice (0x0x7f22beb71af8) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f22beb9e8a0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f22beb71c30) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16) + QIODevice (0x0x7f22beb71c98) 0 + primary-for QBuffer (0x0x7f22beb71c30) + QObject (0x0x7f22beb9e840) 0 + primary-for QIODevice (0x0x7f22beb71c98) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f22beb9eb40) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f22beb9eae0) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f22beb9ecc0) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f22beb9ec60) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f22bebfaba0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f22bec44b40) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f22be8b3420) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f22be91c0c0) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f22be91c120) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f22be91c060) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f22be9f37e0) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f22be6dbd80) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f22be740660) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f22be7e7180) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f22be813de0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f22be813f60) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f22be4c2ba0) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f22be4c2b40) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f22be26cc00) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f22be26ccc0) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f22be319000) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f22be319780) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f22be3c8660) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f22be42f420) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f22be086e40) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f22be1cade0) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7f22bde5c960) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f22bde5ca20) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f22bdcd1a20) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f22bdd6d480) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f22bdd6d4e0) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f22bdd6d420) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f22bda5bea0) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f22bda5bf00) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f22bda5be40) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f22bd872660) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f22bd92d600) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f22bd962360) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f22bd9e4480) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f22bd9e4660) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f22bd6dac00) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f22bd766360) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f22bd731e38) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16) + QEvent (0x0x7f22bd766720) 0 + primary-for QTimerEvent (0x0x7f22bd731e38) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f22bd731ea0) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16) + QEvent (0x0x7f22bd7667e0) 0 + primary-for QChildEvent (0x0x7f22bd731ea0) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f22bd791410) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16) + QEvent (0x0x7f22bd766e40) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f22bd791410) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f22bd791478) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16) + QEvent (0x0x7f22bd766f00) 0 + primary-for QDeferredDeleteEvent (0x0x7f22bd791478) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f22bd7a9060) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f22bd7914e0) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16) + QObject (0x0x7f22bd7a9000) 0 + primary-for QCoreApplication (0x0x7f22bd7914e0) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f22bd7a92a0) 0 + +Class QConcatenateTablesProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QConcatenateTablesProxyModel::QPrivateSignal (0x0x7f22bd7a9420) 0 empty + +Vtable for QConcatenateTablesProxyModel +QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QConcatenateTablesProxyModel) +16 (int (*)(...))QConcatenateTablesProxyModel::metaObject +24 (int (*)(...))QConcatenateTablesProxyModel::qt_metacast +32 (int (*)(...))QConcatenateTablesProxyModel::qt_metacall +40 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +48 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QConcatenateTablesProxyModel::index +120 (int (*)(...))QConcatenateTablesProxyModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QConcatenateTablesProxyModel::rowCount +144 (int (*)(...))QConcatenateTablesProxyModel::columnCount +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))QConcatenateTablesProxyModel::data +168 (int (*)(...))QConcatenateTablesProxyModel::setData +176 (int (*)(...))QConcatenateTablesProxyModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QConcatenateTablesProxyModel::itemData +200 (int (*)(...))QConcatenateTablesProxyModel::setItemData +208 (int (*)(...))QConcatenateTablesProxyModel::mimeTypes +216 (int (*)(...))QConcatenateTablesProxyModel::mimeData +224 (int (*)(...))QConcatenateTablesProxyModel::canDropMimeData +232 (int (*)(...))QConcatenateTablesProxyModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QConcatenateTablesProxyModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QConcatenateTablesProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QConcatenateTablesProxyModel + size=16 align=8 + base size=16 base align=8 +QConcatenateTablesProxyModel (0x0x7f22bd791548) 0 + vptr=((& QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel) + 16) + QAbstractItemModel (0x0x7f22bd7915b0) 0 + primary-for QConcatenateTablesProxyModel (0x0x7f22bd791548) + QObject (0x0x7f22bd7a93c0) 0 + primary-for QAbstractItemModel (0x0x7f22bd7915b0) + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f22bd7a9600) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f22bd7a9720) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f22bd7a98a0) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f22bd465000) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f22bd465720) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f22bd5a7480) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f22bd59f7b8) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16) + QIODevice (0x0x7f22bd59f820) 0 + primary-for QFileDevice (0x0x7f22bd59f7b8) + QObject (0x0x7f22bd5a7420) 0 + primary-for QIODevice (0x0x7f22bd59f820) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f22bd5a7d80) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f22bd59f958) 0 + vptr=((& QFile::_ZTV5QFile) + 16) + QFileDevice (0x0x7f22bd59f9c0) 0 + primary-for QFile (0x0x7f22bd59f958) + QIODevice (0x0x7f22bd59fa28) 0 + primary-for QFileDevice (0x0x7f22bd59f9c0) + QObject (0x0x7f22bd5a7d20) 0 + primary-for QIODevice (0x0x7f22bd59fa28) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f22bd61d420) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f22bd2747e0) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f22bd322b40) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f22bd37a300) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f22bd07b420) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f22bd42ec98) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16) + QAbstractTransition (0x0x7f22bd42ed00) 0 + primary-for QEventTransition (0x0x7f22bd42ec98) + QObject (0x0x7f22bd07b3c0) 0 + primary-for QAbstractTransition (0x0x7f22bd42ed00) + +Vtable for QException +QException::_ZTV10QException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f22bd42ed68) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16) + std::exception (0x0x7f22bd07b600) 0 nearly-empty + primary-for QException (0x0x7f22bd42ed68) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f22bd42edd0) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16) + QException (0x0x7f22bd42ee38) 0 nearly-empty + primary-for QUnhandledException (0x0x7f22bd42edd0) + std::exception (0x0x7f22bd07b660) 0 nearly-empty + primary-for QException (0x0x7f22bd42ee38) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f22bd07b6c0) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f22bd07b780) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f22bd07b7e0) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f22bd07ba20) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f22bd42eea0) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16) + QObject (0x0x7f22bd07b9c0) 0 + primary-for QFileSelector (0x0x7f22bd42eea0) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f22bd07bc60) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f22bd42ef08) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16) + QObject (0x0x7f22bd07bc00) 0 + primary-for QFileSystemWatcher (0x0x7f22bd42ef08) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f22bd07bea0) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f22bd42ef70) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16) + QAbstractState (0x0x7f22bd0ce000) 0 + primary-for QFinalState (0x0x7f22bd42ef70) + QObject (0x0x7f22bd07be40) 0 + primary-for QAbstractState (0x0x7f22bd0ce000) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f22bd0d70c0) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f22bd0d7360) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f22bd0ce0d0) 0 + QBasicMutex (0x0x7f22bd154000) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f22bd154240) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f22bd1546c0) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f22bd154cc0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f22bd154ea0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f22bd1f66c0) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f22bce999c0) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f22bd2306e8) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16) + QObject (0x0x7f22bce99960) 0 + primary-for QFutureWatcherBase (0x0x7f22bd2306e8) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f22bcec4d20) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f22bd230f08) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16) + QAbstractState (0x0x7f22bd230f70) 0 + primary-for QHistoryState (0x0x7f22bd230f08) + QObject (0x0x7f22bcec4cc0) 0 + primary-for QAbstractState (0x0x7f22bd230f70) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f22bceef060) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f22bceee000) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16) + QAbstractProxyModel (0x0x7f22bceee068) 0 + primary-for QIdentityProxyModel (0x0x7f22bceee000) + QAbstractItemModel (0x0x7f22bceee0d0) 0 + primary-for QAbstractProxyModel (0x0x7f22bceee068) + QObject (0x0x7f22bceef000) 0 + primary-for QAbstractItemModel (0x0x7f22bceee0d0) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f22bceef240) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f22bcfafb40) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f22bcfb1a28) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16) + QObject (0x0x7f22bcfafae0) 0 + primary-for QItemSelectionModel (0x0x7f22bcfb1a28) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f22bcfb1bc8) 0 + QList<QItemSelectionRange> (0x0x7f22bcfb1c30) 0 + QListSpecialMethods<QItemSelectionRange> (0x0x7f22bcfef660) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f22bcc56f60) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f22bcdde180) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f22bce19120) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f22bce193c0) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f22bca5e720) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f22bca5e780) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f22bca5e6c0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f22bcb8e660) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f22bcb8e6c0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f22bcbdbea0) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f22bcbdbf00) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f22bcbdbe40) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f22c350a2a0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f22c34f6c98) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16) + QObject (0x0x7f22c350a240) 0 + primary-for QLibrary (0x0x7f22c34f6c98) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f22c3556120) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f22c350ac00) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f22c35ea840) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f22c35ea8a0) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f22bc45d6c0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f22bc4cd840) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f22bc53cc00) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f22bc5b6ea0) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f22bc27b060) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f22bc27b2a0) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f22bc27b240) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f22bc27b6c0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f22bc337600) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f22bc17ade0) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f22bc17ae40) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f22bc2066c0) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f22bc248900) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f22bc248a20) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f22bbea7000) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f22bbe968f0) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16) + QObject (0x0x7f22bbe88f60) 0 + primary-for QMimeData (0x0x7f22bbe968f0) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f22bbea71e0) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f22bbf06300) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f22bbf063c0) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f22bbef4c30) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16) + QObject (0x0x7f22bbf06360) 0 + primary-for QObjectCleanupHandler (0x0x7f22bbef4c30) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f22bbf064e0) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f22bbf6fc60) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f22bbf7f4e0) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16) + QAnimationGroup (0x0x7f22bbf7f548) 0 + primary-for QParallelAnimationGroup (0x0x7f22bbf7f4e0) + QAbstractAnimation (0x0x7f22bbf7f5b0) 0 + primary-for QAnimationGroup (0x0x7f22bbf7f548) + QObject (0x0x7f22bbf6fc00) 0 + primary-for QAbstractAnimation (0x0x7f22bbf7f5b0) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f22bbf6fea0) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f22bbf7f618) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16) + QAbstractAnimation (0x0x7f22bbf7f680) 0 + primary-for QPauseAnimation (0x0x7f22bbf7f618) + QObject (0x0x7f22bbf6fe40) 0 + primary-for QAbstractAnimation (0x0x7f22bbf7f680) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f22bbfa5ae0) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f22bbfe7c60) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f22bbfef9c0) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16) + QObject (0x0x7f22bbfe7c00) 0 + primary-for QPluginLoader (0x0x7f22bbfef9c0) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f22bbfe7d80) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f22bbc60420) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f22bbc5c618) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16) + QIODevice (0x0x7f22bbc5c680) 0 + primary-for QProcess (0x0x7f22bbc5c618) + QObject (0x0x7f22bbc603c0) 0 + primary-for QIODevice (0x0x7f22bbc5c680) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f22bbc60ae0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f22bbc5c6e8) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16) + QAbstractAnimation (0x0x7f22bbc5c750) 0 + primary-for QVariantAnimation (0x0x7f22bbc5c6e8) + QObject (0x0x7f22bbc60a80) 0 + primary-for QAbstractAnimation (0x0x7f22bbc5c750) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f22bbc60d80) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f22bbc5c820) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16) + QVariantAnimation (0x0x7f22bbc5c888) 0 + primary-for QPropertyAnimation (0x0x7f22bbc5c820) + QAbstractAnimation (0x0x7f22bbc5c8f0) 0 + primary-for QVariantAnimation (0x0x7f22bbc5c888) + QObject (0x0x7f22bbc60d20) 0 + primary-for QAbstractAnimation (0x0x7f22bbc5c8f0) + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f22bbd314e0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f22bbe2e240) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f22bbe2e1e0) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f22bbbf5f60) 0 + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f22bba2ac00) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f22bba2aba0) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f22bb6bb5b0) 0 + QRandomGenerator (0x0x7f22bb6d3720) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f22bb6f1300) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f22bb6f15a0) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f22bb6f1a80) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f22bb6f1f60) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f22bb7c6d80) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f22bb83fd20) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f22bb4e9d80) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f22bb5acea0) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f22bb5fb180) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f22bb572f70) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16) + QFileDevice (0x0x7f22bb5fd000) 0 + primary-for QSaveFile (0x0x7f22bb572f70) + QIODevice (0x0x7f22bb5fd068) 0 + primary-for QFileDevice (0x0x7f22bb5fd000) + QObject (0x0x7f22bb5fb120) 0 + primary-for QIODevice (0x0x7f22bb5fd068) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f22bb5fb780) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f22bb5fb900) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f22bb31aba0) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f22bb31dd68) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16) + QAnimationGroup (0x0x7f22bb31ddd0) 0 + primary-for QSequentialAnimationGroup (0x0x7f22bb31dd68) + QAbstractAnimation (0x0x7f22bb31de38) 0 + primary-for QAnimationGroup (0x0x7f22bb31ddd0) + QObject (0x0x7f22bb31ab40) 0 + primary-for QAbstractAnimation (0x0x7f22bb31de38) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f22bb31ade0) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f22bb31dea0) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16) + QObject (0x0x7f22bb31ad80) 0 + primary-for QSettings (0x0x7f22bb31dea0) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f22bb3582a0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f22bb31df08) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16) + QObject (0x0x7f22bb358240) 0 + primary-for QSharedMemory (0x0x7f22bb31df08) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f22bb3584e0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f22bb31df70) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16) + QObject (0x0x7f22bb358480) 0 + primary-for QSignalMapper (0x0x7f22bb31df70) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f22bb358720) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f22bb37a000) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16) + QAbstractTransition (0x0x7f22bb37a068) 0 + primary-for QSignalTransition (0x0x7f22bb37a000) + QObject (0x0x7f22bb3586c0) 0 + primary-for QAbstractTransition (0x0x7f22bb37a068) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f22bb3589c0) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f22bb37a0d0) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16) + QObject (0x0x7f22bb358960) 0 + primary-for QSocketNotifier (0x0x7f22bb37a0d0) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f22bb358c00) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f22bb37a138) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16) + QAbstractProxyModel (0x0x7f22bb37a1a0) 0 + primary-for QSortFilterProxyModel (0x0x7f22bb37a138) + QAbstractItemModel (0x0x7f22bb37a208) 0 + primary-for QAbstractProxyModel (0x0x7f22bb37a1a0) + QObject (0x0x7f22bb358ba0) 0 + primary-for QAbstractItemModel (0x0x7f22bb37a208) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f22bb3c2060) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f22bb3c2960) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f22bb37a3a8) 0 + vptr=((& QState::_ZTV6QState) + 16) + QAbstractState (0x0x7f22bb37a410) 0 + primary-for QState (0x0x7f22bb37a3a8) + QObject (0x0x7f22bb3c2900) 0 + primary-for QAbstractState (0x0x7f22bb37a410) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f22bb3c2de0) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f22bb37a5b0) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16) + QEvent (0x0x7f22bb3c2e40) 0 + primary-for QStateMachine::SignalEvent (0x0x7f22bb37a5b0) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f22bb37a618) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16) + QEvent (0x0x7f22bb3c2ea0) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f22bb37a618) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f22bb37a478) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16) + QState (0x0x7f22bb37a4e0) 0 + primary-for QStateMachine (0x0x7f22bb37a478) + QAbstractState (0x0x7f22bb37a548) 0 + primary-for QState (0x0x7f22bb37a4e0) + QObject (0x0x7f22bb3c2d80) 0 + primary-for QAbstractState (0x0x7f22bb37a548) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f22bb4312a0) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f22bb0b62a0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f22bb13e600) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QStringListModel::itemData +200 (int (*)(...))QStringListModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QStringListModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f22bb134750) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16) + QAbstractListModel (0x0x7f22bb1347b8) 0 + primary-for QStringListModel (0x0x7f22bb134750) + QAbstractItemModel (0x0x7f22bb134820) 0 + primary-for QAbstractListModel (0x0x7f22bb1347b8) + QObject (0x0x7f22bb13e5a0) 0 + primary-for QAbstractItemModel (0x0x7f22bb134820) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f22bb13e720) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f22bb13e7e0) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f22bb13e900) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f22bb134888) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16) + QFile (0x0x7f22bb1348f0) 0 + primary-for QTemporaryFile (0x0x7f22bb134888) + QFileDevice (0x0x7f22bb134958) 0 + primary-for QFile (0x0x7f22bb1348f0) + QIODevice (0x0x7f22bb1349c0) 0 + primary-for QFileDevice (0x0x7f22bb134958) + QObject (0x0x7f22bb13e8a0) 0 + primary-for QIODevice (0x0x7f22bb1349c0) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f22bb13ec60) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f22bb1be4e0) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0 +64 0 + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f22bb1be480) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f22bb1beea0) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f22bb2120c0) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f22bb2122a0) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f22bb134bc8) 0 + std::__mutex_base (0x0x7f22bb212300) 0 + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f22bb2124e0) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f22bb212540) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f22bb2125a0) 0 empty + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f22bae51000) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f22bb134c30) 0 + std::__recursive_mutex_base (0x0x7f22bae51060) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f22bb226af0) 0 + std::__mutex_base (0x0x7f22bae51420) 0 + std::__timed_mutex_impl<std::timed_mutex> (0x0x7f22bae51480) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f22bb226e70) 0 + std::__recursive_mutex_base (0x0x7f22bae517e0) 0 + std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7f22bae51840) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f22bae51f60) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f22bb134d68) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16) + std::exception (0x0x7f22bae9b4e0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f22bb134d68) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f22bb134dd0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16) + std::exception (0x0x7f22bae9b600) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f22bb134dd0) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f22bb134e38) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16) + std::exception (0x0x7f22bae9b720) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f22bb134e38) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f22bb134f08) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16) + std::exception (0x0x7f22bae9b840) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f22bb134f08) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f22baec38a0) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f22baec3ba0) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f22baec3ea0) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f22baee7240) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f22bb134f70) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16) + std::exception (0x0x7f22baf63420) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f22bb134f70) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f22bafce3c0) 0 empty + +Class std::__sp_array_delete + size=1 align=1 + base size=0 base align=1 +std::__sp_array_delete (0x0x7f22bafce7e0) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f22bad17660) 0 + +Vtable for std::thread::_State +std::thread::_State::_ZTVNSt6thread6_StateE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread6_StateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_State + size=8 align=8 + base size=8 base align=8 +std::thread::_State (0x0x7f22bad44ae0) 0 nearly-empty + vptr=((& std::thread::_State::_ZTVNSt6thread6_StateE) + 16) + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f22bad44b40) 0 + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f22bad44a80) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f22babdaf00) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f22bac10300) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f22bac10360) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f22ba98c660) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f22ba983820) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16) + std::logic_error (0x0x7f22ba983888) 0 + primary-for std::future_error (0x0x7f22ba983820) + std::exception (0x0x7f22ba98cd80) 0 nearly-empty + primary-for std::logic_error (0x0x7f22ba983888) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f22ba9ba4e0) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f22ba9ba480) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f22ba77cc00) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f22ba7aa0d0) 0 + std::__at_thread_exit_elt (0x0x7f22ba77ccc0) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f22ba9ba660) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f22ba9ba420) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f22b9f10dd0) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16) + std::__future_base::_State_baseV2 (0x0x7f22b9f3acc0) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f22b9f10dd0) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f22b9f745a0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f22b9f7b138) 0 + vptr=((& QThread::_ZTV7QThread) + 16) + QObject (0x0x7f22b9f74540) 0 + primary-for QThread (0x0x7f22b9f7b138) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f22b9f74960) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f22b9f7b1a0) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16) + QObject (0x0x7f22b9f74900) 0 + primary-for QThreadPool (0x0x7f22b9f7b1a0) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f22b9f74b40) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f22b9fb9240) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f22b9f7b208) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16) + QObject (0x0x7f22b9fb91e0) 0 + primary-for QTimeLine (0x0x7f22b9f7b208) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f22b9fb9480) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f22b9f7b270) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16) + QObject (0x0x7f22b9fb9420) 0 + primary-for QTimer (0x0x7f22b9f7b270) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f22ba002de0) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f22ba002d80) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f22b9ca3ea0) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f22b9cae958) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16) + QObject (0x0x7f22b9ca3e40) 0 + primary-for QTranslator (0x0x7f22b9cae958) + +Class QTransposeProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTransposeProxyModel::QPrivateSignal (0x0x7f22b9cca120) 0 empty + +Vtable for QTransposeProxyModel +QTransposeProxyModel::_ZTV20QTransposeProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTransposeProxyModel) +16 (int (*)(...))QTransposeProxyModel::metaObject +24 (int (*)(...))QTransposeProxyModel::qt_metacast +32 (int (*)(...))QTransposeProxyModel::qt_metacall +40 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +48 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTransposeProxyModel::index +120 (int (*)(...))QTransposeProxyModel::parent +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))QTransposeProxyModel::rowCount +144 (int (*)(...))QTransposeProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QTransposeProxyModel::headerData +184 (int (*)(...))QTransposeProxyModel::setHeaderData +192 (int (*)(...))QTransposeProxyModel::itemData +200 (int (*)(...))QTransposeProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QTransposeProxyModel::insertRows +264 (int (*)(...))QTransposeProxyModel::insertColumns +272 (int (*)(...))QTransposeProxyModel::removeRows +280 (int (*)(...))QTransposeProxyModel::removeColumns +288 (int (*)(...))QTransposeProxyModel::moveRows +296 (int (*)(...))QTransposeProxyModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QTransposeProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QTransposeProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QTransposeProxyModel::setSourceModel +392 (int (*)(...))QTransposeProxyModel::mapToSource +400 (int (*)(...))QTransposeProxyModel::mapFromSource +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QTransposeProxyModel + size=16 align=8 + base size=16 base align=8 +QTransposeProxyModel (0x0x7f22b9cae9c0) 0 + vptr=((& QTransposeProxyModel::_ZTV20QTransposeProxyModel) + 16) + QAbstractProxyModel (0x0x7f22b9caea28) 0 + primary-for QTransposeProxyModel (0x0x7f22b9cae9c0) + QAbstractItemModel (0x0x7f22b9caea90) 0 + primary-for QAbstractProxyModel (0x0x7f22b9caea28) + QObject (0x0x7f22b9cca0c0) 0 + primary-for QAbstractItemModel (0x0x7f22b9caea90) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f22b9cca300) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f22b9d44cc0) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f22b9d44de0) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f22b9def1e0) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f22b9a5f138) 0 + QVector<QXmlStreamAttribute> (0x0x7f22b9a55900) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f22b9a55c00) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f22b9ad3ba0) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f22b9b31ba0) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f22b9b9cc60) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f22b9b9ccc0) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f22b9bdaba0) 0 + +Class QRgba64 + size=8 align=8 + base size=8 base align=8 +QRgba64 (0x0x7f22b9c2c1e0) 0 + +Class QColor + size=16 align=4 + base size=14 base align=4 +QColor (0x0x7f22b98c7240) 0 + +Class QRegion::QRegionData + size=16 align=8 + base size=16 base align=8 +QRegion::QRegionData (0x0x7f22b99626c0) 0 + +Class QRegion + size=8 align=8 + base size=8 base align=8 +QRegion (0x0x7f22b9962660) 0 + +Class QKeySequence + size=8 align=8 + base size=8 base align=8 +QKeySequence (0x0x7f22b964f300) 0 + +Class QVector2D + size=8 align=4 + base size=8 base align=4 +QVector2D (0x0x7f22b971be40) 0 + +Class QTouchDevice + size=8 align=8 + base size=8 base align=8 +QTouchDevice (0x0x7f22b978df00) 0 + +Vtable for QInputEvent +QInputEvent::_ZTV11QInputEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QInputEvent) +16 (int (*)(...))QInputEvent::~QInputEvent +24 (int (*)(...))QInputEvent::~QInputEvent + +Class QInputEvent + size=32 align=8 + base size=32 base align=8 +QInputEvent (0x0x7f22b97843a8) 0 + vptr=((& QInputEvent::_ZTV11QInputEvent) + 16) + QEvent (0x0x7f22b97be7e0) 0 + primary-for QInputEvent (0x0x7f22b97843a8) + +Vtable for QEnterEvent +QEnterEvent::_ZTV11QEnterEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QEnterEvent) +16 (int (*)(...))QEnterEvent::~QEnterEvent +24 (int (*)(...))QEnterEvent::~QEnterEvent + +Class QEnterEvent + size=72 align=8 + base size=72 base align=8 +QEnterEvent (0x0x7f22b9784410) 0 + vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16) + QEvent (0x0x7f22b97be9c0) 0 + primary-for QEnterEvent (0x0x7f22b9784410) + +Vtable for QMouseEvent +QMouseEvent::_ZTV11QMouseEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMouseEvent) +16 (int (*)(...))QMouseEvent::~QMouseEvent +24 (int (*)(...))QMouseEvent::~QMouseEvent + +Class QMouseEvent + size=104 align=8 + base size=100 base align=8 +QMouseEvent (0x0x7f22b9784478) 0 + vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16) + QInputEvent (0x0x7f22b97844e0) 0 + primary-for QMouseEvent (0x0x7f22b9784478) + QEvent (0x0x7f22b97bed80) 0 + primary-for QInputEvent (0x0x7f22b97844e0) + +Vtable for QHoverEvent +QHoverEvent::_ZTV11QHoverEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHoverEvent) +16 (int (*)(...))QHoverEvent::~QHoverEvent +24 (int (*)(...))QHoverEvent::~QHoverEvent + +Class QHoverEvent + size=64 align=8 + base size=64 base align=8 +QHoverEvent (0x0x7f22b9784548) 0 + vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16) + QInputEvent (0x0x7f22b97845b0) 0 + primary-for QHoverEvent (0x0x7f22b9784548) + QEvent (0x0x7f22b980b2a0) 0 + primary-for QInputEvent (0x0x7f22b97845b0) + +Vtable for QWheelEvent +QWheelEvent::_ZTV11QWheelEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWheelEvent) +16 (int (*)(...))QWheelEvent::~QWheelEvent +24 (int (*)(...))QWheelEvent::~QWheelEvent + +Class QWheelEvent + size=96 align=8 + base size=96 base align=8 +QWheelEvent (0x0x7f22b9784618) 0 + vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16) + QInputEvent (0x0x7f22b9784680) 0 + primary-for QWheelEvent (0x0x7f22b9784618) + QEvent (0x0x7f22b980b480) 0 + primary-for QInputEvent (0x0x7f22b9784680) + +Vtable for QTabletEvent +QTabletEvent::_ZTV12QTabletEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTabletEvent) +16 (int (*)(...))QTabletEvent::~QTabletEvent +24 (int (*)(...))QTabletEvent::~QTabletEvent + +Class QTabletEvent + size=128 align=8 + base size=128 base align=8 +QTabletEvent (0x0x7f22b97846e8) 0 + vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16) + QInputEvent (0x0x7f22b9784750) 0 + primary-for QTabletEvent (0x0x7f22b97846e8) + QEvent (0x0x7f22b980bae0) 0 + primary-for QInputEvent (0x0x7f22b9784750) + +Vtable for QNativeGestureEvent +QNativeGestureEvent::_ZTV19QNativeGestureEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNativeGestureEvent) +16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent + +Class QNativeGestureEvent + size=112 align=8 + base size=112 base align=8 +QNativeGestureEvent (0x0x7f22b97847b8) 0 + vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16) + QInputEvent (0x0x7f22b9784820) 0 + primary-for QNativeGestureEvent (0x0x7f22b97847b8) + QEvent (0x0x7f22b944d420) 0 + primary-for QInputEvent (0x0x7f22b9784820) + +Vtable for QKeyEvent +QKeyEvent::_ZTV9QKeyEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QKeyEvent) +16 (int (*)(...))QKeyEvent::~QKeyEvent +24 (int (*)(...))QKeyEvent::~QKeyEvent + +Class QKeyEvent + size=64 align=8 + base size=59 base align=8 +QKeyEvent (0x0x7f22b9784888) 0 + vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16) + QInputEvent (0x0x7f22b97848f0) 0 + primary-for QKeyEvent (0x0x7f22b9784888) + QEvent (0x0x7f22b944d720) 0 + primary-for QInputEvent (0x0x7f22b97848f0) + +Vtable for QFocusEvent +QFocusEvent::_ZTV11QFocusEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusEvent) +16 (int (*)(...))QFocusEvent::~QFocusEvent +24 (int (*)(...))QFocusEvent::~QFocusEvent + +Class QFocusEvent + size=24 align=8 + base size=24 base align=8 +QFocusEvent (0x0x7f22b9784958) 0 + vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16) + QEvent (0x0x7f22b944da20) 0 + primary-for QFocusEvent (0x0x7f22b9784958) + +Vtable for QPaintEvent +QPaintEvent::_ZTV11QPaintEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPaintEvent) +16 (int (*)(...))QPaintEvent::~QPaintEvent +24 (int (*)(...))QPaintEvent::~QPaintEvent + +Class QPaintEvent + size=56 align=8 + base size=49 base align=8 +QPaintEvent (0x0x7f22b97849c0) 0 + vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16) + QEvent (0x0x7f22b944db40) 0 + primary-for QPaintEvent (0x0x7f22b97849c0) + +Vtable for QMoveEvent +QMoveEvent::_ZTV10QMoveEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QMoveEvent) +16 (int (*)(...))QMoveEvent::~QMoveEvent +24 (int (*)(...))QMoveEvent::~QMoveEvent + +Class QMoveEvent + size=40 align=8 + base size=36 base align=8 +QMoveEvent (0x0x7f22b9784a28) 0 + vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16) + QEvent (0x0x7f22b944dc60) 0 + primary-for QMoveEvent (0x0x7f22b9784a28) + +Vtable for QExposeEvent +QExposeEvent::_ZTV12QExposeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QExposeEvent) +16 (int (*)(...))QExposeEvent::~QExposeEvent +24 (int (*)(...))QExposeEvent::~QExposeEvent + +Class QExposeEvent + size=32 align=8 + base size=32 base align=8 +QExposeEvent (0x0x7f22b9784a90) 0 + vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16) + QEvent (0x0x7f22b944dd80) 0 + primary-for QExposeEvent (0x0x7f22b9784a90) + +Vtable for QPlatformSurfaceEvent +QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent) +16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent + +Class QPlatformSurfaceEvent + size=24 align=8 + base size=24 base align=8 +QPlatformSurfaceEvent (0x0x7f22b9784af8) 0 + vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16) + QEvent (0x0x7f22b944de40) 0 + primary-for QPlatformSurfaceEvent (0x0x7f22b9784af8) + +Vtable for QResizeEvent +QResizeEvent::_ZTV12QResizeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QResizeEvent) +16 (int (*)(...))QResizeEvent::~QResizeEvent +24 (int (*)(...))QResizeEvent::~QResizeEvent + +Class QResizeEvent + size=40 align=8 + base size=36 base align=8 +QResizeEvent (0x0x7f22b9784b60) 0 + vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16) + QEvent (0x0x7f22b944df00) 0 + primary-for QResizeEvent (0x0x7f22b9784b60) + +Vtable for QCloseEvent +QCloseEvent::_ZTV11QCloseEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QCloseEvent) +16 (int (*)(...))QCloseEvent::~QCloseEvent +24 (int (*)(...))QCloseEvent::~QCloseEvent + +Class QCloseEvent + size=24 align=8 + base size=20 base align=8 +QCloseEvent (0x0x7f22b9784bc8) 0 + vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16) + QEvent (0x0x7f22b9491060) 0 + primary-for QCloseEvent (0x0x7f22b9784bc8) + +Vtable for QIconDragEvent +QIconDragEvent::_ZTV14QIconDragEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QIconDragEvent) +16 (int (*)(...))QIconDragEvent::~QIconDragEvent +24 (int (*)(...))QIconDragEvent::~QIconDragEvent + +Class QIconDragEvent + size=24 align=8 + base size=20 base align=8 +QIconDragEvent (0x0x7f22b9784c30) 0 + vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16) + QEvent (0x0x7f22b94910c0) 0 + primary-for QIconDragEvent (0x0x7f22b9784c30) + +Vtable for QShowEvent +QShowEvent::_ZTV10QShowEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QShowEvent) +16 (int (*)(...))QShowEvent::~QShowEvent +24 (int (*)(...))QShowEvent::~QShowEvent + +Class QShowEvent + size=24 align=8 + base size=20 base align=8 +QShowEvent (0x0x7f22b9784c98) 0 + vptr=((& QShowEvent::_ZTV10QShowEvent) + 16) + QEvent (0x0x7f22b9491120) 0 + primary-for QShowEvent (0x0x7f22b9784c98) + +Vtable for QHideEvent +QHideEvent::_ZTV10QHideEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHideEvent) +16 (int (*)(...))QHideEvent::~QHideEvent +24 (int (*)(...))QHideEvent::~QHideEvent + +Class QHideEvent + size=24 align=8 + base size=20 base align=8 +QHideEvent (0x0x7f22b9784d00) 0 + vptr=((& QHideEvent::_ZTV10QHideEvent) + 16) + QEvent (0x0x7f22b9491180) 0 + primary-for QHideEvent (0x0x7f22b9784d00) + +Vtable for QContextMenuEvent +QContextMenuEvent::_ZTV17QContextMenuEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QContextMenuEvent) +16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent + +Class QContextMenuEvent + size=56 align=8 + base size=49 base align=8 +QContextMenuEvent (0x0x7f22b9784d68) 0 + vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16) + QInputEvent (0x0x7f22b9784dd0) 0 + primary-for QContextMenuEvent (0x0x7f22b9784d68) + QEvent (0x0x7f22b94911e0) 0 + primary-for QInputEvent (0x0x7f22b9784dd0) + +Class QInputMethodEvent::Attribute + size=32 align=8 + base size=32 base align=8 +QInputMethodEvent::Attribute (0x0x7f22b9491540) 0 + +Vtable for QInputMethodEvent +QInputMethodEvent::_ZTV17QInputMethodEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QInputMethodEvent) +16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent + +Class QInputMethodEvent + size=56 align=8 + base size=56 base align=8 +QInputMethodEvent (0x0x7f22b9784e38) 0 + vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16) + QEvent (0x0x7f22b94914e0) 0 + primary-for QInputMethodEvent (0x0x7f22b9784e38) + +Class QInputMethodQueryEvent::QueryPair + size=24 align=8 + base size=24 base align=8 +QInputMethodQueryEvent::QueryPair (0x0x7f22b95168a0) 0 + +Vtable for QInputMethodQueryEvent +QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent) +16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent + +Class QInputMethodQueryEvent + size=32 align=8 + base size=32 base align=8 +QInputMethodQueryEvent (0x0x7f22b9527068) 0 + vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16) + QEvent (0x0x7f22b9516840) 0 + primary-for QInputMethodQueryEvent (0x0x7f22b9527068) + +Vtable for QDropEvent +QDropEvent::_ZTV10QDropEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDropEvent) +16 (int (*)(...))QDropEvent::~QDropEvent +24 (int (*)(...))QDropEvent::~QDropEvent + +Class QDropEvent + size=72 align=8 + base size=72 base align=8 +QDropEvent (0x0x7f22b9598138) 0 + vptr=((& QDropEvent::_ZTV10QDropEvent) + 16) + QEvent (0x0x7f22b9590600) 0 + primary-for QDropEvent (0x0x7f22b9598138) + +Vtable for QDragMoveEvent +QDragMoveEvent::_ZTV14QDragMoveEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDragMoveEvent) +16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent + +Class QDragMoveEvent + size=88 align=8 + base size=88 base align=8 +QDragMoveEvent (0x0x7f22b95981a0) 0 + vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16) + QDropEvent (0x0x7f22b9598208) 0 + primary-for QDragMoveEvent (0x0x7f22b95981a0) + QEvent (0x0x7f22b95909c0) 0 + primary-for QDropEvent (0x0x7f22b9598208) + +Vtable for QDragEnterEvent +QDragEnterEvent::_ZTV15QDragEnterEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragEnterEvent) +16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent + +Class QDragEnterEvent + size=88 align=8 + base size=88 base align=8 +QDragEnterEvent (0x0x7f22b9598270) 0 + vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16) + QDragMoveEvent (0x0x7f22b95982d8) 0 + primary-for QDragEnterEvent (0x0x7f22b9598270) + QDropEvent (0x0x7f22b9598340) 0 + primary-for QDragMoveEvent (0x0x7f22b95982d8) + QEvent (0x0x7f22b9590c00) 0 + primary-for QDropEvent (0x0x7f22b9598340) + +Vtable for QDragLeaveEvent +QDragLeaveEvent::_ZTV15QDragLeaveEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragLeaveEvent) +16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent + +Class QDragLeaveEvent + size=24 align=8 + base size=20 base align=8 +QDragLeaveEvent (0x0x7f22b95983a8) 0 + vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16) + QEvent (0x0x7f22b9590c60) 0 + primary-for QDragLeaveEvent (0x0x7f22b95983a8) + +Vtable for QHelpEvent +QHelpEvent::_ZTV10QHelpEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHelpEvent) +16 (int (*)(...))QHelpEvent::~QHelpEvent +24 (int (*)(...))QHelpEvent::~QHelpEvent + +Class QHelpEvent + size=40 align=8 + base size=36 base align=8 +QHelpEvent (0x0x7f22b9598410) 0 + vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16) + QEvent (0x0x7f22b9590cc0) 0 + primary-for QHelpEvent (0x0x7f22b9598410) + +Vtable for QStatusTipEvent +QStatusTipEvent::_ZTV15QStatusTipEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QStatusTipEvent) +16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent + +Class QStatusTipEvent + size=32 align=8 + base size=32 base align=8 +QStatusTipEvent (0x0x7f22b9598478) 0 + vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16) + QEvent (0x0x7f22b9590f60) 0 + primary-for QStatusTipEvent (0x0x7f22b9598478) + +Vtable for QWhatsThisClickedEvent +QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent) +16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent + +Class QWhatsThisClickedEvent + size=32 align=8 + base size=32 base align=8 +QWhatsThisClickedEvent (0x0x7f22b95984e0) 0 + vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16) + QEvent (0x0x7f22b95c3060) 0 + primary-for QWhatsThisClickedEvent (0x0x7f22b95984e0) + +Vtable for QActionEvent +QActionEvent::_ZTV12QActionEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionEvent) +16 (int (*)(...))QActionEvent::~QActionEvent +24 (int (*)(...))QActionEvent::~QActionEvent + +Class QActionEvent + size=40 align=8 + base size=40 base align=8 +QActionEvent (0x0x7f22b9598548) 0 + vptr=((& QActionEvent::_ZTV12QActionEvent) + 16) + QEvent (0x0x7f22b95c3120) 0 + primary-for QActionEvent (0x0x7f22b9598548) + +Vtable for QFileOpenEvent +QFileOpenEvent::_ZTV14QFileOpenEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QFileOpenEvent) +16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent + +Class QFileOpenEvent + size=40 align=8 + base size=40 base align=8 +QFileOpenEvent (0x0x7f22b95985b0) 0 + vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16) + QEvent (0x0x7f22b95c3240) 0 + primary-for QFileOpenEvent (0x0x7f22b95985b0) + +Vtable for QToolBarChangeEvent +QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QToolBarChangeEvent) +16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent + +Class QToolBarChangeEvent + size=24 align=8 + base size=21 base align=8 +QToolBarChangeEvent (0x0x7f22b9598618) 0 + vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16) + QEvent (0x0x7f22b95c3360) 0 + primary-for QToolBarChangeEvent (0x0x7f22b9598618) + +Vtable for QShortcutEvent +QShortcutEvent::_ZTV14QShortcutEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QShortcutEvent) +16 (int (*)(...))QShortcutEvent::~QShortcutEvent +24 (int (*)(...))QShortcutEvent::~QShortcutEvent + +Class QShortcutEvent + size=40 align=8 + base size=40 base align=8 +QShortcutEvent (0x0x7f22b9598680) 0 + vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16) + QEvent (0x0x7f22b95c3420) 0 + primary-for QShortcutEvent (0x0x7f22b9598680) + +Vtable for QWindowStateChangeEvent +QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent) +16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent + +Class QWindowStateChangeEvent + size=32 align=8 + base size=25 base align=8 +QWindowStateChangeEvent (0x0x7f22b95986e8) 0 + vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16) + QEvent (0x0x7f22b95c35a0) 0 + primary-for QWindowStateChangeEvent (0x0x7f22b95986e8) + +Class QPointingDeviceUniqueId + size=8 align=8 + base size=8 base align=8 +QPointingDeviceUniqueId (0x0x7f22b95c3720) 0 + +Class QTouchEvent::TouchPoint + size=8 align=8 + base size=8 base align=8 +QTouchEvent::TouchPoint (0x0x7f22b961dae0) 0 + +Vtable for QTouchEvent +QTouchEvent::_ZTV11QTouchEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTouchEvent) +16 (int (*)(...))QTouchEvent::~QTouchEvent +24 (int (*)(...))QTouchEvent::~QTouchEvent + +Class QTouchEvent + size=72 align=8 + base size=72 base align=8 +QTouchEvent (0x0x7f22b9618f08) 0 + vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16) + QInputEvent (0x0x7f22b9618f70) 0 + primary-for QTouchEvent (0x0x7f22b9618f08) + QEvent (0x0x7f22b961da80) 0 + primary-for QInputEvent (0x0x7f22b9618f70) + +Vtable for QScrollPrepareEvent +QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollPrepareEvent) +16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent + +Class QScrollPrepareEvent + size=112 align=8 + base size=112 base align=8 +QScrollPrepareEvent (0x0x7f22b932dc30) 0 + vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16) + QEvent (0x0x7f22b93610c0) 0 + primary-for QScrollPrepareEvent (0x0x7f22b932dc30) + +Vtable for QScrollEvent +QScrollEvent::_ZTV12QScrollEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QScrollEvent) +16 (int (*)(...))QScrollEvent::~QScrollEvent +24 (int (*)(...))QScrollEvent::~QScrollEvent + +Class QScrollEvent + size=64 align=8 + base size=60 base align=8 +QScrollEvent (0x0x7f22b932dc98) 0 + vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16) + QEvent (0x0x7f22b9361120) 0 + primary-for QScrollEvent (0x0x7f22b932dc98) + +Vtable for QScreenOrientationChangeEvent +QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent) +16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent + +Class QScreenOrientationChangeEvent + size=40 align=8 + base size=36 base align=8 +QScreenOrientationChangeEvent (0x0x7f22b932dd00) 0 + vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16) + QEvent (0x0x7f22b9361180) 0 + primary-for QScreenOrientationChangeEvent (0x0x7f22b932dd00) + +Vtable for QApplicationStateChangeEvent +QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent) +16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent + +Class QApplicationStateChangeEvent + size=24 align=8 + base size=24 base align=8 +QApplicationStateChangeEvent (0x0x7f22b932dd68) 0 + vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16) + QEvent (0x0x7f22b93611e0) 0 + primary-for QApplicationStateChangeEvent (0x0x7f22b932dd68) + +Class QFont + size=16 align=8 + base size=12 base align=8 +QFont (0x0x7f22b9361240) 0 + +Class QPolygon + size=8 align=8 + base size=8 base align=8 +QPolygon (0x0x7f22b93fb9c0) 0 + QVector<QPoint> (0x0x7f22b94006c0) 0 + +Class QPolygonF + size=8 align=8 + base size=8 base align=8 +QPolygonF (0x0x7f22b908cd00) 0 + QVector<QPointF> (0x0x7f22b909e780) 0 + +Class QMatrix + size=48 align=8 + base size=48 base align=8 +QMatrix (0x0x7f22b9139600) 0 + +Class QPainterPath::Element + size=24 align=8 + base size=24 base align=8 +QPainterPath::Element (0x0x7f22b91a3420) 0 + +Class QPainterPath + size=8 align=8 + base size=8 base align=8 +QPainterPath (0x0x7f22b91a33c0) 0 + +Class QPainterPathStroker + size=8 align=8 + base size=8 base align=8 +QPainterPathStroker (0x0x7f22b8ede780) 0 + +Class QTransform + size=88 align=8 + base size=88 base align=8 +QTransform (0x0x7f22b8edee40) 0 + +Vtable for QPaintDevice +QPaintDevice::_ZTV12QPaintDevice: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintDevice) +16 0 +24 0 +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDevice + size=24 align=8 + base size=24 base align=8 +QPaintDevice (0x0x7f22b8f9d900) 0 + vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16) + +Class QPixelFormat + size=8 align=8 + base size=8 base align=8 +QPixelFormat (0x0x7f22b8f9df00) 0 + +Vtable for QImage +QImage::_ZTV6QImage: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QImage) +16 (int (*)(...))QImage::~QImage +24 (int (*)(...))QImage::~QImage +32 (int (*)(...))QImage::devType +40 (int (*)(...))QImage::paintEngine +48 (int (*)(...))QImage::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QImage + size=32 align=8 + base size=32 base align=8 +QImage (0x0x7f22b8c64b60) 0 + vptr=((& QImage::_ZTV6QImage) + 16) + QPaintDevice (0x0x7f22b8c73840) 0 + primary-for QImage (0x0x7f22b8c64b60) + +Vtable for QPixmap +QPixmap::_ZTV7QPixmap: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QPixmap) +16 (int (*)(...))QPixmap::~QPixmap +24 (int (*)(...))QPixmap::~QPixmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPixmap + size=32 align=8 + base size=32 base align=8 +QPixmap (0x0x7f22b8d825b0) 0 + vptr=((& QPixmap::_ZTV7QPixmap) + 16) + QPaintDevice (0x0x7f22b8d84600) 0 + primary-for QPixmap (0x0x7f22b8d825b0) + +Class QBrush + size=8 align=8 + base size=8 base align=8 +QBrush (0x0x7f22b8df7ae0) 0 + +Class QBrushData + size=112 align=8 + base size=112 base align=8 +QBrushData (0x0x7f22b8ad5060) 0 + +Class QGradient + size=64 align=8 + base size=64 base align=8 +QGradient (0x0x7f22b8ad52a0) 0 + +Class QLinearGradient + size=64 align=8 + base size=64 base align=8 +QLinearGradient (0x0x7f22b8ac9750) 0 + QGradient (0x0x7f22b8ad59c0) 0 + +Class QRadialGradient + size=64 align=8 + base size=64 base align=8 +QRadialGradient (0x0x7f22b8ac97b8) 0 + QGradient (0x0x7f22b8ad5ae0) 0 + +Class QConicalGradient + size=64 align=8 + base size=64 base align=8 +QConicalGradient (0x0x7f22b8ac9820) 0 + QGradient (0x0x7f22b8ad5c00) 0 + +Class QPen + size=8 align=8 + base size=8 base align=8 +QPen (0x0x7f22b8ad5cc0) 0 + +Class QTextOption::Tab + size=16 align=8 + base size=14 base align=8 +QTextOption::Tab (0x0x7f22b8bf1660) 0 + +Class QTextOption + size=32 align=8 + base size=32 base align=8 +QTextOption (0x0x7f22b8bf1600) 0 + +Class QTextLength + size=16 align=8 + base size=16 base align=8 +QTextLength (0x0x7f22b8c29d80) 0 + +Class QTextFormat + size=16 align=8 + base size=12 base align=8 +QTextFormat (0x0x7f22b88b4720) 0 + +Class QTextCharFormat + size=16 align=8 + base size=12 base align=8 +QTextCharFormat (0x0x7f22b89a28f0) 0 + QTextFormat (0x0x7f22b89ce300) 0 + +Class QTextBlockFormat + size=16 align=8 + base size=12 base align=8 +QTextBlockFormat (0x0x7f22b8a40d00) 0 + QTextFormat (0x0x7f22b8a46cc0) 0 + +Class QTextListFormat + size=16 align=8 + base size=12 base align=8 +QTextListFormat (0x0x7f22b86b2270) 0 + QTextFormat (0x0x7f22b86a99c0) 0 + +Class QTextImageFormat + size=16 align=8 + base size=12 base align=8 +QTextImageFormat (0x0x7f22b86f8680) 0 + QTextCharFormat (0x0x7f22b86f86e8) 0 + QTextFormat (0x0x7f22b8702180) 0 + +Class QTextFrameFormat + size=16 align=8 + base size=12 base align=8 +QTextFrameFormat (0x0x7f22b8736c30) 0 + QTextFormat (0x0x7f22b873f7e0) 0 + +Class QTextTableFormat + size=16 align=8 + base size=12 base align=8 +QTextTableFormat (0x0x7f22b87a11a0) 0 + QTextFrameFormat (0x0x7f22b87a1208) 0 + QTextFormat (0x0x7f22b87a6420) 0 + +Class QTextTableCellFormat + size=16 align=8 + base size=12 base align=8 +QTextTableCellFormat (0x0x7f22b87f5750) 0 + QTextCharFormat (0x0x7f22b87f57b8) 0 + QTextFormat (0x0x7f22b87eacc0) 0 + +Class QFontDatabase + size=8 align=8 + base size=8 base align=8 +QFontDatabase (0x0x7f22b844e120) 0 + +Class QRawFont + size=8 align=8 + base size=8 base align=8 +QRawFont (0x0x7f22b844e300) 0 + +Class QGlyphRun + size=8 align=8 + base size=8 base align=8 +QGlyphRun (0x0x7f22b84bccc0) 0 + +Class QTextCursor + size=8 align=8 + base size=8 base align=8 +QTextCursor (0x0x7f22b8532de0) 0 + +Class QTextInlineObject + size=16 align=8 + base size=16 base align=8 +QTextInlineObject (0x0x7f22b859af60) 0 + +Class QTextLayout::FormatRange + size=24 align=8 + base size=24 base align=8 +QTextLayout::FormatRange (0x0x7f22b85bc3c0) 0 + +Class QTextLayout + size=8 align=8 + base size=8 base align=8 +QTextLayout (0x0x7f22b85bc360) 0 + +Class QTextLine + size=16 align=8 + base size=16 base align=8 +QTextLine (0x0x7f22b8645a80) 0 + +Vtable for QAbstractUndoItem +QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractUndoItem) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAbstractUndoItem + size=8 align=8 + base size=8 base align=8 +QAbstractUndoItem (0x0x7f22b8645f00) 0 nearly-empty + vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16) + +Class QTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextDocument::QPrivateSignal (0x0x7f22b82721e0) 0 empty + +Vtable for QTextDocument +QTextDocument::_ZTV13QTextDocument: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QTextDocument) +16 (int (*)(...))QTextDocument::metaObject +24 (int (*)(...))QTextDocument::qt_metacast +32 (int (*)(...))QTextDocument::qt_metacall +40 (int (*)(...))QTextDocument::~QTextDocument +48 (int (*)(...))QTextDocument::~QTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextDocument::clear +120 (int (*)(...))QTextDocument::createObject +128 (int (*)(...))QTextDocument::loadResource + +Class QTextDocument + size=16 align=8 + base size=16 base align=8 +QTextDocument (0x0x7f22b825b2d8) 0 + vptr=((& QTextDocument::_ZTV13QTextDocument) + 16) + QObject (0x0x7f22b8272180) 0 + primary-for QTextDocument (0x0x7f22b825b2d8) + +Class QPalette::Data + size=4 align=4 + base size=4 base align=4 +QPalette::Data (0x0x7f22b8272cc0) 0 + +Class QPalette + size=16 align=8 + base size=12 base align=8 +QPalette (0x0x7f22b8272c60) 0 + +Class QAbstractTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTextDocumentLayout::QPrivateSignal (0x0x7f22b83be0c0) 0 empty + +Class QAbstractTextDocumentLayout::Selection + size=24 align=8 + base size=24 base align=8 +QAbstractTextDocumentLayout::Selection (0x0x7f22b83be120) 0 + +Class QAbstractTextDocumentLayout::PaintContext + size=64 align=8 + base size=64 base align=8 +QAbstractTextDocumentLayout::PaintContext (0x0x7f22b83be180) 0 + +Vtable for QAbstractTextDocumentLayout +QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout) +16 (int (*)(...))QAbstractTextDocumentLayout::metaObject +24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast +32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QAbstractTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QAbstractTextDocumentLayout (0x0x7f22b83c0000) 0 + vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16) + QObject (0x0x7f22b83be060) 0 + primary-for QAbstractTextDocumentLayout (0x0x7f22b83c0000) + +Vtable for QTextObjectInterface +QTextObjectInterface::_ZTV20QTextObjectInterface: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextObjectInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QTextObjectInterface + size=8 align=8 + base size=8 base align=8 +QTextObjectInterface (0x0x7f22b8068d20) 0 nearly-empty + vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16) + +Class QAccessible::State + size=8 align=8 + base size=5 base align=8 +QAccessible::State (0x0x7f22b8068f60) 0 + +Vtable for QAccessible::ActivationObserver +QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAccessible::ActivationObserver + size=8 align=8 + base size=8 base align=8 +QAccessible::ActivationObserver (0x0x7f22b80a6000) 0 nearly-empty + vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16) + +Class QAccessible + size=1 align=1 + base size=0 base align=1 +QAccessible (0x0x7f22b8068f00) 0 empty + +Vtable for QAccessibleInterface +QAccessibleInterface::_ZTV20QAccessibleInterface: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAccessibleInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleInterface (0x0x7f22b80a6ba0) 0 nearly-empty + vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16) + +Vtable for QAccessibleTextInterface +QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAccessibleTextInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset +104 (int (*)(...))QAccessibleTextInterface::textAfterOffset +112 (int (*)(...))QAccessibleTextInterface::textAtOffset +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTextInterface (0x0x7f22b80a6f00) 0 nearly-empty + vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16) + +Vtable for QAccessibleEditableTextInterface +QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleEditableTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleEditableTextInterface (0x0x7f22b80a6f60) 0 nearly-empty + vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16) + +Vtable for QAccessibleValueInterface +QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleValueInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleValueInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleValueInterface (0x0x7f22b80f9000) 0 nearly-empty + vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16) + +Vtable for QAccessibleTableCellInterface +QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableCellInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableCellInterface (0x0x7f22b80f9060) 0 nearly-empty + vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16) + +Vtable for QAccessibleTableInterface +QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleTableInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableInterface (0x0x7f22b80f90c0) 0 nearly-empty + vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16) + +Vtable for QAccessibleActionInterface +QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleActionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QAccessibleActionInterface::localizedActionName +48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleActionInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleActionInterface (0x0x7f22b80f9120) 0 nearly-empty + vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16) + +Vtable for QAccessibleImageInterface +QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleImageInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleImageInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleImageInterface (0x0x7f22b80f9240) 0 nearly-empty + vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16) + +Vtable for QAccessibleEvent +QAccessibleEvent::_ZTV16QAccessibleEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAccessibleEvent) +16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleEvent + size=32 align=8 + base size=28 base align=8 +QAccessibleEvent (0x0x7f22b80f92a0) 0 + vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16) + +Vtable for QAccessibleStateChangeEvent +QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent) +16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleStateChangeEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleStateChangeEvent (0x0x7f22b8087618) 0 + vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16) + QAccessibleEvent (0x0x7f22b80f9c60) 0 + primary-for QAccessibleStateChangeEvent (0x0x7f22b8087618) + +Vtable for QAccessibleTextCursorEvent +QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent) +16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextCursorEvent + size=32 align=8 + base size=32 base align=8 +QAccessibleTextCursorEvent (0x0x7f22b8087680) 0 + vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16) + QAccessibleEvent (0x0x7f22b8175060) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f22b8087680) + +Vtable for QAccessibleTextSelectionEvent +QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent) +16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextSelectionEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleTextSelectionEvent (0x0x7f22b80876e8) 0 + vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f22b8087750) 0 + primary-for QAccessibleTextSelectionEvent (0x0x7f22b80876e8) + QAccessibleEvent (0x0x7f22b8175480) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f22b8087750) + +Vtable for QAccessibleTextInsertEvent +QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent) +16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextInsertEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextInsertEvent (0x0x7f22b80877b8) 0 + vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f22b8087820) 0 + primary-for QAccessibleTextInsertEvent (0x0x7f22b80877b8) + QAccessibleEvent (0x0x7f22b8175900) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f22b8087820) + +Vtable for QAccessibleTextRemoveEvent +QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent) +16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextRemoveEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextRemoveEvent (0x0x7f22b8087888) 0 + vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f22b80878f0) 0 + primary-for QAccessibleTextRemoveEvent (0x0x7f22b8087888) + QAccessibleEvent (0x0x7f22b8175d20) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f22b80878f0) + +Vtable for QAccessibleTextUpdateEvent +QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent) +16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextUpdateEvent + size=56 align=8 + base size=56 base align=8 +QAccessibleTextUpdateEvent (0x0x7f22b8087958) 0 + vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f22b80879c0) 0 + primary-for QAccessibleTextUpdateEvent (0x0x7f22b8087958) + QAccessibleEvent (0x0x7f22b81a2180) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f22b80879c0) + +Vtable for QAccessibleValueChangeEvent +QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent) +16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleValueChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleValueChangeEvent (0x0x7f22b8087a28) 0 + vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16) + QAccessibleEvent (0x0x7f22b81a2600) 0 + primary-for QAccessibleValueChangeEvent (0x0x7f22b8087a28) + +Vtable for QAccessibleTableModelChangeEvent +QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent) +16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTableModelChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTableModelChangeEvent (0x0x7f22b8087a90) 0 + vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16) + QAccessibleEvent (0x0x7f22b81a2a20) 0 + primary-for QAccessibleTableModelChangeEvent (0x0x7f22b8087a90) + +Vtable for QAccessibleBridge +QAccessibleBridge::_ZTV17QAccessibleBridge: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleBridge) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridge + size=8 align=8 + base size=8 base align=8 +QAccessibleBridge (0x0x7f22b81d5300) 0 nearly-empty + vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16) + +Class QAccessibleBridgePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessibleBridgePlugin::QPrivateSignal (0x0x7f22b81d55a0) 0 empty + +Vtable for QAccessibleBridgePlugin +QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin) +16 (int (*)(...))QAccessibleBridgePlugin::metaObject +24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast +32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridgePlugin + size=16 align=8 + base size=16 base align=8 +QAccessibleBridgePlugin (0x0x7f22b8087af8) 0 + vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16) + QObject (0x0x7f22b81d5540) 0 + primary-for QAccessibleBridgePlugin (0x0x7f22b8087af8) + +Vtable for QAccessibleObject +QAccessibleObject::_ZTV17QAccessibleObject: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleObject) +16 0 +24 0 +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleObject + size=16 align=8 + base size=16 base align=8 +QAccessibleObject (0x0x7f22b8087b60) 0 + vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16) + QAccessibleInterface (0x0x7f22b81d56c0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f22b8087b60) + +Vtable for QAccessibleApplication +QAccessibleApplication::_ZTV22QAccessibleApplication: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QAccessibleApplication) +16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleApplication::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleApplication::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleApplication::parent +88 (int (*)(...))QAccessibleApplication::child +96 (int (*)(...))QAccessibleApplication::childCount +104 (int (*)(...))QAccessibleApplication::indexOfChild +112 (int (*)(...))QAccessibleApplication::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))QAccessibleApplication::role +144 (int (*)(...))QAccessibleApplication::state +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleApplication + size=16 align=8 + base size=16 base align=8 +QAccessibleApplication (0x0x7f22b8087bc8) 0 + vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16) + QAccessibleObject (0x0x7f22b8087c30) 0 + primary-for QAccessibleApplication (0x0x7f22b8087bc8) + QAccessibleInterface (0x0x7f22b81d5720) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f22b8087c30) + +Class QAccessiblePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessiblePlugin::QPrivateSignal (0x0x7f22b81d57e0) 0 empty + +Vtable for QAccessiblePlugin +QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessiblePlugin) +16 (int (*)(...))QAccessiblePlugin::metaObject +24 (int (*)(...))QAccessiblePlugin::qt_metacast +32 (int (*)(...))QAccessiblePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessiblePlugin + size=16 align=8 + base size=16 base align=8 +QAccessiblePlugin (0x0x7f22b8087c98) 0 + vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16) + QObject (0x0x7f22b81d5780) 0 + primary-for QAccessiblePlugin (0x0x7f22b8087c98) + +Class QSurfaceFormat + size=8 align=8 + base size=8 base align=8 +QSurfaceFormat (0x0x7f22b81d5900) 0 + +Vtable for QSurface +QSurface::_ZTV8QSurface: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSurface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QSurface + size=24 align=8 + base size=24 base align=8 +QSurface (0x0x7f22b823d480) 0 + vptr=((& QSurface::_ZTV8QSurface) + 16) + +Class QIcon + size=8 align=8 + base size=8 base align=8 +QIcon (0x0x7f22b823d840) 0 + +Class QCursor + size=8 align=8 + base size=8 base align=8 +QCursor (0x0x7f22b7f203c0) 0 + +Class QWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWindow::QPrivateSignal (0x0x7f22b7fed180) 0 empty + +Vtable for QWindow +QWindow::_ZTV7QWindow: 45 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWindow) +16 (int (*)(...))QWindow::metaObject +24 (int (*)(...))QWindow::qt_metacast +32 (int (*)(...))QWindow::qt_metacall +40 (int (*)(...))QWindow::~QWindow +48 (int (*)(...))QWindow::~QWindow +56 (int (*)(...))QWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI7QWindow) +312 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev +320 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QWindow + size=40 align=8 + base size=40 base align=8 +QWindow (0x0x7f22b7fdea10) 0 + vptr=((& QWindow::_ZTV7QWindow) + 16) + QObject (0x0x7f22b7fed0c0) 0 + primary-for QWindow (0x0x7f22b7fdea10) + QSurface (0x0x7f22b7fed120) 16 + vptr=((& QWindow::_ZTV7QWindow) + 312) + +Class QBackingStore + size=8 align=8 + base size=8 base align=8 +QBackingStore (0x0x7f22b7feda20) 0 + +Vtable for QBitmap +QBitmap::_ZTV7QBitmap: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBitmap) +16 (int (*)(...))QBitmap::~QBitmap +24 (int (*)(...))QBitmap::~QBitmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QBitmap + size=32 align=8 + base size=32 base align=8 +QBitmap (0x0x7f22b7fcdf70) 0 + vptr=((& QBitmap::_ZTV7QBitmap) + 16) + QPixmap (0x0x7f22b8041000) 0 + primary-for QBitmap (0x0x7f22b7fcdf70) + QPaintDevice (0x0x7f22b7fedae0) 0 + primary-for QPixmap (0x0x7f22b8041000) + +Class QClipboard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QClipboard::QPrivateSignal (0x0x7f22b7c90060) 0 empty + +Vtable for QClipboard +QClipboard::_ZTV10QClipboard: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QClipboard) +16 (int (*)(...))QClipboard::metaObject +24 (int (*)(...))QClipboard::qt_metacast +32 (int (*)(...))QClipboard::qt_metacall +40 (int (*)(...))QClipboard::~QClipboard +48 (int (*)(...))QClipboard::~QClipboard +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QClipboard + size=16 align=8 + base size=16 base align=8 +QClipboard (0x0x7f22b7c8a2d8) 0 + vptr=((& QClipboard::_ZTV10QClipboard) + 16) + QObject (0x0x7f22b7c90000) 0 + primary-for QClipboard (0x0x7f22b7c8a2d8) + +Class QDesktopServices + size=1 align=1 + base size=0 base align=1 +QDesktopServices (0x0x7f22b7c90180) 0 empty + +Class QDrag::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDrag::QPrivateSignal (0x0x7f22b7c90240) 0 empty + +Vtable for QDrag +QDrag::_ZTV5QDrag: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDrag) +16 (int (*)(...))QDrag::metaObject +24 (int (*)(...))QDrag::qt_metacast +32 (int (*)(...))QDrag::qt_metacall +40 (int (*)(...))QDrag::~QDrag +48 (int (*)(...))QDrag::~QDrag +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDrag + size=16 align=8 + base size=16 base align=8 +QDrag (0x0x7f22b7c8a340) 0 + vptr=((& QDrag::_ZTV5QDrag) + 16) + QObject (0x0x7f22b7c901e0) 0 + primary-for QDrag (0x0x7f22b7c8a340) + +Class QFontInfo + size=8 align=8 + base size=8 base align=8 +QFontInfo (0x0x7f22b7c90420) 0 + +Class QFontMetrics + size=8 align=8 + base size=8 base align=8 +QFontMetrics (0x0x7f22b7cf8480) 0 + +Class QFontMetricsF + size=8 align=8 + base size=8 base align=8 +QFontMetricsF (0x0x7f22b7d427e0) 0 + +Class QGenericPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGenericPlugin::QPrivateSignal (0x0x7f22b7a6e8a0) 0 empty + +Vtable for QGenericPlugin +QGenericPlugin::_ZTV14QGenericPlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGenericPlugin) +16 (int (*)(...))QGenericPlugin::metaObject +24 (int (*)(...))QGenericPlugin::qt_metacast +32 (int (*)(...))QGenericPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGenericPlugin + size=16 align=8 + base size=16 base align=8 +QGenericPlugin (0x0x7f22b7d88ea0) 0 + vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16) + QObject (0x0x7f22b7a6e840) 0 + primary-for QGenericPlugin (0x0x7f22b7d88ea0) + +Class QGenericPluginFactory + size=1 align=1 + base size=0 base align=1 +QGenericPluginFactory (0x0x7f22b7a6e9c0) 0 empty + +Class QInputMethod::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputMethod::QPrivateSignal (0x0x7f22b7a6ea80) 0 empty + +Vtable for QInputMethod +QInputMethod::_ZTV12QInputMethod: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputMethod) +16 (int (*)(...))QInputMethod::metaObject +24 (int (*)(...))QInputMethod::qt_metacast +32 (int (*)(...))QInputMethod::qt_metacall +40 (int (*)(...))QInputMethod::~QInputMethod +48 (int (*)(...))QInputMethod::~QInputMethod +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputMethod + size=16 align=8 + base size=16 base align=8 +QInputMethod (0x0x7f22b7d88f08) 0 + vptr=((& QInputMethod::_ZTV12QInputMethod) + 16) + QObject (0x0x7f22b7a6ea20) 0 + primary-for QInputMethod (0x0x7f22b7d88f08) + +Class QGuiApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGuiApplication::QPrivateSignal (0x0x7f22b7a6ed80) 0 empty + +Vtable for QGuiApplication +QGuiApplication::_ZTV15QGuiApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGuiApplication) +16 (int (*)(...))QGuiApplication::metaObject +24 (int (*)(...))QGuiApplication::qt_metacast +32 (int (*)(...))QGuiApplication::qt_metacall +40 (int (*)(...))QGuiApplication::~QGuiApplication +48 (int (*)(...))QGuiApplication::~QGuiApplication +56 (int (*)(...))QGuiApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGuiApplication::notify +120 (int (*)(...))QGuiApplication::compressEvent + +Class QGuiApplication + size=16 align=8 + base size=16 base align=8 +QGuiApplication (0x0x7f22b7d88f70) 0 + vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16) + QCoreApplication (0x0x7f22b7ae8000) 0 + primary-for QGuiApplication (0x0x7f22b7d88f70) + QObject (0x0x7f22b7a6ed20) 0 + primary-for QCoreApplication (0x0x7f22b7ae8000) + +Class QIconEngine::AvailableSizesArgument + size=16 align=8 + base size=16 base align=8 +QIconEngine::AvailableSizesArgument (0x0x7f22b7b02540) 0 + +Class QIconEngine::ScaledPixmapArgument + size=56 align=8 + base size=56 base align=8 +QIconEngine::ScaledPixmapArgument (0x0x7f22b7b026c0) 0 + +Vtable for QIconEngine +QIconEngine::_ZTV11QIconEngine: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QIconEngine) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QIconEngine::actualSize +48 (int (*)(...))QIconEngine::pixmap +56 (int (*)(...))QIconEngine::addPixmap +64 (int (*)(...))QIconEngine::addFile +72 (int (*)(...))QIconEngine::key +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QIconEngine::read +96 (int (*)(...))QIconEngine::write +104 (int (*)(...))QIconEngine::availableSizes +112 (int (*)(...))QIconEngine::iconName +120 (int (*)(...))QIconEngine::virtual_hook + +Class QIconEngine + size=8 align=8 + base size=8 base align=8 +QIconEngine (0x0x7f22b7b024e0) 0 nearly-empty + vptr=((& QIconEngine::_ZTV11QIconEngine) + 16) + +Class QIconEnginePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIconEnginePlugin::QPrivateSignal (0x0x7f22b7b02780) 0 empty + +Vtable for QIconEnginePlugin +QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QIconEnginePlugin) +16 (int (*)(...))QIconEnginePlugin::metaObject +24 (int (*)(...))QIconEnginePlugin::qt_metacast +32 (int (*)(...))QIconEnginePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QIconEnginePlugin + size=16 align=8 + base size=16 base align=8 +QIconEnginePlugin (0x0x7f22b7ae85b0) 0 + vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16) + QObject (0x0x7f22b7b02720) 0 + primary-for QIconEnginePlugin (0x0x7f22b7ae85b0) + +Vtable for QImageIOHandler +QImageIOHandler::_ZTV15QImageIOHandler: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QImageIOHandler) +16 0 +24 0 +32 (int (*)(...))QImageIOHandler::name +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QImageIOHandler::write +64 (int (*)(...))QImageIOHandler::option +72 (int (*)(...))QImageIOHandler::setOption +80 (int (*)(...))QImageIOHandler::supportsOption +88 (int (*)(...))QImageIOHandler::jumpToNextImage +96 (int (*)(...))QImageIOHandler::jumpToImage +104 (int (*)(...))QImageIOHandler::loopCount +112 (int (*)(...))QImageIOHandler::imageCount +120 (int (*)(...))QImageIOHandler::nextImageDelay +128 (int (*)(...))QImageIOHandler::currentImageNumber +136 (int (*)(...))QImageIOHandler::currentImageRect + +Class QImageIOHandler + size=16 align=8 + base size=16 base align=8 +QImageIOHandler (0x0x7f22b7b028a0) 0 + vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16) + +Class QImageIOPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QImageIOPlugin::QPrivateSignal (0x0x7f22b7b02ae0) 0 empty + +Vtable for QImageIOPlugin +QImageIOPlugin::_ZTV14QImageIOPlugin: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QImageIOPlugin) +16 (int (*)(...))QImageIOPlugin::metaObject +24 (int (*)(...))QImageIOPlugin::qt_metacast +32 (int (*)(...))QImageIOPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QImageIOPlugin + size=16 align=8 + base size=16 base align=8 +QImageIOPlugin (0x0x7f22b7ae8618) 0 + vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16) + QObject (0x0x7f22b7b02a80) 0 + primary-for QImageIOPlugin (0x0x7f22b7ae8618) + +Class QImageReader + size=8 align=8 + base size=8 base align=8 +QImageReader (0x0x7f22b7b91300) 0 + +Class QImageWriter + size=8 align=8 + base size=8 base align=8 +QImageWriter (0x0x7f22b7b91420) 0 + +Class QVector3D + size=12 align=4 + base size=12 base align=4 +QVector3D (0x0x7f22b7b91540) 0 + +Class QVector4D + size=16 align=4 + base size=16 base align=4 +QVector4D (0x0x7f22b7c236c0) 0 + +Class QQuaternion + size=16 align=4 + base size=16 base align=4 +QQuaternion (0x0x7f22b78a7900) 0 + +Class QMatrix4x4 + size=68 align=4 + base size=68 base align=4 +QMatrix4x4 (0x0x7f22b7971240) 0 + +Class QMovie::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMovie::QPrivateSignal (0x0x7f22b76ee0c0) 0 empty + +Vtable for QMovie +QMovie::_ZTV6QMovie: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QMovie) +16 (int (*)(...))QMovie::metaObject +24 (int (*)(...))QMovie::qt_metacast +32 (int (*)(...))QMovie::qt_metacall +40 (int (*)(...))QMovie::~QMovie +48 (int (*)(...))QMovie::~QMovie +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QMovie + size=16 align=8 + base size=16 base align=8 +QMovie (0x0x7f22b79d8d68) 0 + vptr=((& QMovie::_ZTV6QMovie) + 16) + QObject (0x0x7f22b76ee060) 0 + primary-for QMovie (0x0x7f22b79d8d68) + +Class QOffscreenSurface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOffscreenSurface::QPrivateSignal (0x0x7f22b76ee4e0) 0 empty + +Vtable for QOffscreenSurface +QOffscreenSurface::_ZTV17QOffscreenSurface: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOffscreenSurface) +16 (int (*)(...))QOffscreenSurface::metaObject +24 (int (*)(...))QOffscreenSurface::qt_metacast +32 (int (*)(...))QOffscreenSurface::qt_metacall +40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOffscreenSurface::surfaceType +120 (int (*)(...))QOffscreenSurface::format +128 (int (*)(...))QOffscreenSurface::size +136 (int (*)(...))QOffscreenSurface::surfaceHandle +144 (int (*)(...))-16 +152 (int (*)(...))(& _ZTI17QOffscreenSurface) +160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev +168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev +176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv +184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv +192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv +200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv + +Class QOffscreenSurface + size=40 align=8 + base size=40 base align=8 +QOffscreenSurface (0x0x7f22b79ef850) 0 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16) + QObject (0x0x7f22b76ee420) 0 + primary-for QOffscreenSurface (0x0x7f22b79ef850) + QSurface (0x0x7f22b76ee480) 16 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160) + +Class QOpenGLBuffer + size=8 align=8 + base size=8 base align=8 +QOpenGLBuffer (0x0x7f22b76ee720) 0 + +Class QOpenGLVersionStatus + size=12 align=4 + base size=12 base align=4 +QOpenGLVersionStatus (0x0x7f22b76eef60) 0 + +Class QOpenGLVersionFunctionsBackend + size=16 align=8 + base size=12 base align=8 +QOpenGLVersionFunctionsBackend (0x0x7f22b739db40) 0 + +Class QOpenGLVersionFunctionsStorage + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionFunctionsStorage (0x0x7f22b739dd20) 0 + +Class QAbstractOpenGLFunctionsPrivate + size=16 align=8 + base size=9 base align=8 +QAbstractOpenGLFunctionsPrivate (0x0x7f22b739dd80) 0 + +Vtable for QAbstractOpenGLFunctions +QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions) +16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions + +Class QAbstractOpenGLFunctions + size=16 align=8 + base size=16 base align=8 +QAbstractOpenGLFunctions (0x0x7f22b739df60) 0 + vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16) + +Class QOpenGLFunctions_1_0_CoreBackend::Functions + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7f22b73cb180) 0 + +Class QOpenGLFunctions_1_0_CoreBackend + size=400 align=8 + base size=400 base align=8 +QOpenGLFunctions_1_0_CoreBackend (0x0x7f22b739cc30) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b73cb120) 0 + +Class QOpenGLFunctions_1_1_CoreBackend::Functions + size=128 align=8 + base size=128 base align=8 +QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7f22b73cb480) 0 + +Class QOpenGLFunctions_1_1_CoreBackend + size=144 align=8 + base size=144 base align=8 +QOpenGLFunctions_1_1_CoreBackend (0x0x7f22b739cc98) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b73cb420) 0 + +Class QOpenGLFunctions_1_2_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7f22b73cb780) 0 + +Class QOpenGLFunctions_1_2_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_1_2_CoreBackend (0x0x7f22b739cd00) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b73cb720) 0 + +Class QOpenGLFunctions_1_3_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7f22b73cba80) 0 + +Class QOpenGLFunctions_1_3_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_1_3_CoreBackend (0x0x7f22b739cd68) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b73cba20) 0 + +Class QOpenGLFunctions_1_4_CoreBackend::Functions + size=56 align=8 + base size=56 base align=8 +QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7f22b73cbde0) 0 + +Class QOpenGLFunctions_1_4_CoreBackend + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_4_CoreBackend (0x0x7f22b739cdd0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b73cbd80) 0 + +Class QOpenGLFunctions_1_5_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7f22b7400120) 0 + +Class QOpenGLFunctions_1_5_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_1_5_CoreBackend (0x0x7f22b739ce38) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b74000c0) 0 + +Class QOpenGLFunctions_2_0_CoreBackend::Functions + size=744 align=8 + base size=744 base align=8 +QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7f22b7400420) 0 + +Class QOpenGLFunctions_2_0_CoreBackend + size=760 align=8 + base size=760 base align=8 +QOpenGLFunctions_2_0_CoreBackend (0x0x7f22b739cea0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b74003c0) 0 + +Class QOpenGLFunctions_2_1_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7f22b7400720) 0 + +Class QOpenGLFunctions_2_1_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_2_1_CoreBackend (0x0x7f22b739cf08) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b74006c0) 0 + +Class QOpenGLFunctions_3_0_CoreBackend::Functions + size=672 align=8 + base size=672 base align=8 +QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7f22b7400a20) 0 + +Class QOpenGLFunctions_3_0_CoreBackend + size=688 align=8 + base size=688 base align=8 +QOpenGLFunctions_3_0_CoreBackend (0x0x7f22b739cf70) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b74009c0) 0 + +Class QOpenGLFunctions_3_1_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7f22b7400d20) 0 + +Class QOpenGLFunctions_3_1_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_3_1_CoreBackend (0x0x7f22b7446000) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b7400cc0) 0 + +Class QOpenGLFunctions_3_2_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7f22b704f060) 0 + +Class QOpenGLFunctions_3_2_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_3_2_CoreBackend (0x0x7f22b7446068) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b704f000) 0 + +Class QOpenGLFunctions_3_3_CoreBackend::Functions + size=464 align=8 + base size=464 base align=8 +QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7f22b704f360) 0 + +Class QOpenGLFunctions_3_3_CoreBackend + size=480 align=8 + base size=480 base align=8 +QOpenGLFunctions_3_3_CoreBackend (0x0x7f22b74460d0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b704f300) 0 + +Class QOpenGLFunctions_4_0_CoreBackend::Functions + size=368 align=8 + base size=368 base align=8 +QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7f22b704f660) 0 + +Class QOpenGLFunctions_4_0_CoreBackend + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_4_0_CoreBackend (0x0x7f22b7446138) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b704f600) 0 + +Class QOpenGLFunctions_4_1_CoreBackend::Functions + size=704 align=8 + base size=704 base align=8 +QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7f22b704f960) 0 + +Class QOpenGLFunctions_4_1_CoreBackend + size=720 align=8 + base size=720 base align=8 +QOpenGLFunctions_4_1_CoreBackend (0x0x7f22b74461a0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b704f900) 0 + +Class QOpenGLFunctions_4_2_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7f22b704fc60) 0 + +Class QOpenGLFunctions_4_2_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_2_CoreBackend (0x0x7f22b7446208) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b704fc00) 0 + +Class QOpenGLFunctions_4_3_CoreBackend::Functions + size=344 align=8 + base size=344 base align=8 +QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7f22b704ff60) 0 + +Class QOpenGLFunctions_4_3_CoreBackend + size=360 align=8 + base size=360 base align=8 +QOpenGLFunctions_4_3_CoreBackend (0x0x7f22b7446270) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b704ff00) 0 + +Class QOpenGLFunctions_4_4_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7f22b70b92a0) 0 + +Class QOpenGLFunctions_4_4_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_4_4_CoreBackend (0x0x7f22b74462d8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b70b9240) 0 + +Class QOpenGLFunctions_4_5_CoreBackend::Functions + size=848 align=8 + base size=848 base align=8 +QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7f22b70b9600) 0 + +Class QOpenGLFunctions_4_5_CoreBackend + size=864 align=8 + base size=864 base align=8 +QOpenGLFunctions_4_5_CoreBackend (0x0x7f22b7446340) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b70b95a0) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions + size=2064 align=8 + base size=2064 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7f22b70b9900) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend + size=2080 align=8 + base size=2080 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7f22b74463a8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b70b98a0) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions + size=136 align=8 + base size=136 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7f22b70b9c00) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7f22b7446410) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b70b9ba0) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7f22b70b9f00) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend + size=272 align=8 + base size=272 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7f22b7446478) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b70b9ea0) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions + size=296 align=8 + base size=296 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7f22b7142240) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend + size=312 align=8 + base size=312 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7f22b74464e0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b71421e0) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7f22b7142540) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend + size=320 align=8 + base size=320 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7f22b7446548) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b71424e0) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions + size=288 align=8 + base size=288 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7f22b7142840) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7f22b74465b0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b71427e0) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions + size=160 align=8 + base size=160 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7f22b7142b40) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend + size=176 align=8 + base size=176 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7f22b7446618) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b7142ae0) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions + size=240 align=8 + base size=240 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7f22b7142e40) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7f22b7446680) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b7142de0) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7f22b717d180) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7f22b74466e8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f22b717d120) 0 + +Class QOpenGLVersionProfile + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionProfile (0x0x7f22b717d420) 0 + +Class QOpenGLContextGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContextGroup::QPrivateSignal (0x0x7f22b717df00) 0 empty + +Vtable for QOpenGLContextGroup +QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QOpenGLContextGroup) +16 (int (*)(...))QOpenGLContextGroup::metaObject +24 (int (*)(...))QOpenGLContextGroup::qt_metacast +32 (int (*)(...))QOpenGLContextGroup::qt_metacall +40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContextGroup + size=16 align=8 + base size=16 base align=8 +QOpenGLContextGroup (0x0x7f22b71ac138) 0 + vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16) + QObject (0x0x7f22b717dea0) 0 + primary-for QOpenGLContextGroup (0x0x7f22b71ac138) + +Class QOpenGLContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContext::QPrivateSignal (0x0x7f22b71b9180) 0 empty + +Vtable for QOpenGLContext +QOpenGLContext::_ZTV14QOpenGLContext: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QOpenGLContext) +16 (int (*)(...))QOpenGLContext::metaObject +24 (int (*)(...))QOpenGLContext::qt_metacast +32 (int (*)(...))QOpenGLContext::qt_metacall +40 (int (*)(...))QOpenGLContext::~QOpenGLContext +48 (int (*)(...))QOpenGLContext::~QOpenGLContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContext + size=16 align=8 + base size=16 base align=8 +QOpenGLContext (0x0x7f22b71ac1a0) 0 + vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16) + QObject (0x0x7f22b71b9120) 0 + primary-for QOpenGLContext (0x0x7f22b71ac1a0) + +Class QOpenGLDebugMessage + size=8 align=8 + base size=8 base align=8 +QOpenGLDebugMessage (0x0x7f22b71b93c0) 0 + +Class QOpenGLDebugLogger::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLDebugLogger::QPrivateSignal (0x0x7f22b6e70b40) 0 empty + +Vtable for QOpenGLDebugLogger +QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger) +16 (int (*)(...))QOpenGLDebugLogger::metaObject +24 (int (*)(...))QOpenGLDebugLogger::qt_metacast +32 (int (*)(...))QOpenGLDebugLogger::qt_metacall +40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLDebugLogger + size=16 align=8 + base size=16 base align=8 +QOpenGLDebugLogger (0x0x7f22b721dbc8) 0 + vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16) + QObject (0x0x7f22b6e70ae0) 0 + primary-for QOpenGLDebugLogger (0x0x7f22b721dbc8) + +Class QOpenGLFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLFunctions (0x0x7f22b6ec7000) 0 + +Class QOpenGLFunctionsPrivate::Functions + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate::Functions (0x0x7f22b6ec7960) 0 + +Class QOpenGLFunctionsPrivate + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate (0x0x7f22b6ec7900) 0 + +Class QOpenGLExtraFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLExtraFunctions (0x0x7f22b721df70) 0 + QOpenGLFunctions (0x0x7f22b7015720) 0 + +Class QOpenGLExtraFunctionsPrivate::Functions + size=1728 align=8 + base size=1728 base align=8 +QOpenGLExtraFunctionsPrivate::Functions (0x0x7f22b7015a80) 0 + +Class QOpenGLExtraFunctionsPrivate + size=2880 align=8 + base size=2880 base align=8 +QOpenGLExtraFunctionsPrivate (0x0x7f22b6c8b000) 0 + QOpenGLFunctionsPrivate (0x0x7f22b7015a20) 0 + +Vtable for QOpenGLFramebufferObject +QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject) +16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject +24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject + +Class QOpenGLFramebufferObject + size=16 align=8 + base size=16 base align=8 +QOpenGLFramebufferObject (0x0x7f22b6df3540) 0 + vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16) + +Class QOpenGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QOpenGLFramebufferObjectFormat (0x0x7f22b6df37e0) 0 + +Vtable for QOpenGLPaintDevice +QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice) +16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +32 (int (*)(...))QOpenGLPaintDevice::devType +40 (int (*)(...))QOpenGLPaintDevice::paintEngine +48 (int (*)(...))QOpenGLPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget + +Class QOpenGLPaintDevice + size=32 align=8 + base size=32 base align=8 +QOpenGLPaintDevice (0x0x7f22b6ddbd68) 0 + vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16) + QPaintDevice (0x0x7f22b6df3840) 0 + primary-for QOpenGLPaintDevice (0x0x7f22b6ddbd68) + +Class QOpenGLPixelTransferOptions + size=8 align=8 + base size=8 base align=8 +QOpenGLPixelTransferOptions (0x0x7f22b6df3a80) 0 + +Class QOpenGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShader::QPrivateSignal (0x0x7f22b6a848a0) 0 empty + +Vtable for QOpenGLShader +QOpenGLShader::_ZTV13QOpenGLShader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLShader) +16 (int (*)(...))QOpenGLShader::metaObject +24 (int (*)(...))QOpenGLShader::qt_metacast +32 (int (*)(...))QOpenGLShader::qt_metacall +40 (int (*)(...))QOpenGLShader::~QOpenGLShader +48 (int (*)(...))QOpenGLShader::~QOpenGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLShader + size=16 align=8 + base size=16 base align=8 +QOpenGLShader (0x0x7f22b6a75ea0) 0 + vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16) + QObject (0x0x7f22b6a84840) 0 + primary-for QOpenGLShader (0x0x7f22b6a75ea0) + +Class QOpenGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShaderProgram::QPrivateSignal (0x0x7f22b6ac11e0) 0 empty + +Vtable for QOpenGLShaderProgram +QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram) +16 (int (*)(...))QOpenGLShaderProgram::metaObject +24 (int (*)(...))QOpenGLShaderProgram::qt_metacast +32 (int (*)(...))QOpenGLShaderProgram::qt_metacall +40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOpenGLShaderProgram::link + +Class QOpenGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QOpenGLShaderProgram (0x0x7f22b6aca000) 0 + vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16) + QObject (0x0x7f22b6ac1180) 0 + primary-for QOpenGLShaderProgram (0x0x7f22b6aca000) + +Class QOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QOpenGLTexture (0x0x7f22b6ac13c0) 0 + +Class QOpenGLTextureBlitter + size=8 align=8 + base size=8 base align=8 +QOpenGLTextureBlitter (0x0x7f22b6b7a8a0) 0 + +Class QOpenGLTimerQuery::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimerQuery::QPrivateSignal (0x0x7f22b6b7aae0) 0 empty + +Vtable for QOpenGLTimerQuery +QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery) +16 (int (*)(...))QOpenGLTimerQuery::metaObject +24 (int (*)(...))QOpenGLTimerQuery::qt_metacast +32 (int (*)(...))QOpenGLTimerQuery::qt_metacall +40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimerQuery + size=16 align=8 + base size=16 base align=8 +QOpenGLTimerQuery (0x0x7f22b6aca138) 0 + vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16) + QObject (0x0x7f22b6b7aa80) 0 + primary-for QOpenGLTimerQuery (0x0x7f22b6aca138) + +Class QOpenGLTimeMonitor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimeMonitor::QPrivateSignal (0x0x7f22b6b7ad20) 0 empty + +Vtable for QOpenGLTimeMonitor +QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor) +16 (int (*)(...))QOpenGLTimeMonitor::metaObject +24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast +32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall +40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimeMonitor + size=16 align=8 + base size=16 base align=8 +QOpenGLTimeMonitor (0x0x7f22b6aca1a0) 0 + vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16) + QObject (0x0x7f22b6b7acc0) 0 + primary-for QOpenGLTimeMonitor (0x0x7f22b6aca1a0) + +Class QOpenGLVertexArrayObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLVertexArrayObject::QPrivateSignal (0x0x7f22b6b7af60) 0 empty + +Class QOpenGLVertexArrayObject::Binder + size=8 align=8 + base size=8 base align=8 +QOpenGLVertexArrayObject::Binder (0x0x7f22b6bdb000) 0 + +Vtable for QOpenGLVertexArrayObject +QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject) +16 (int (*)(...))QOpenGLVertexArrayObject::metaObject +24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast +32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall +40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLVertexArrayObject + size=16 align=8 + base size=16 base align=8 +QOpenGLVertexArrayObject (0x0x7f22b6aca208) 0 + vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16) + QObject (0x0x7f22b6b7af00) 0 + primary-for QOpenGLVertexArrayObject (0x0x7f22b6aca208) + +Class QPaintDeviceWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPaintDeviceWindow::QPrivateSignal (0x0x7f22b6bdb6c0) 0 empty + +Vtable for QPaintDeviceWindow +QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 58 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +16 (int (*)(...))QPaintDeviceWindow::metaObject +24 (int (*)(...))QPaintDeviceWindow::qt_metacast +32 (int (*)(...))QPaintDeviceWindow::qt_metacall +40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QPaintDeviceWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))-16 +328 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +336 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev +344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +384 (int (*)(...))-40 +392 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +400 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev +408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev +416 (int (*)(...))QPaintDevice::devType +424 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE +440 (int (*)(...))QPaintDevice::initPainter +448 (int (*)(...))QPaintDevice::redirected +456 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDeviceWindow + size=64 align=8 + base size=64 base align=8 +QPaintDeviceWindow (0x0x7f22b6b93e70) 0 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16) + QWindow (0x0x7f22b6b93ee0) 0 + primary-for QPaintDeviceWindow (0x0x7f22b6b93e70) + QObject (0x0x7f22b6bdb5a0) 0 + primary-for QWindow (0x0x7f22b6b93ee0) + QSurface (0x0x7f22b6bdb600) 16 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 336) + QPaintDevice (0x0x7f22b6bdb660) 40 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 400) + +Class QOpenGLWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWindow::QPrivateSignal (0x0x7f22b6bdb9c0) 0 empty + +Vtable for QOpenGLWindow +QOpenGLWindow::_ZTV13QOpenGLWindow: 64 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWindow) +16 (int (*)(...))QOpenGLWindow::metaObject +24 (int (*)(...))QOpenGLWindow::qt_metacast +32 (int (*)(...))QOpenGLWindow::qt_metacall +40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QOpenGLWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QOpenGLWindow::paintEvent +304 (int (*)(...))QOpenGLWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QOpenGLWindow::initializeGL +328 (int (*)(...))QOpenGLWindow::resizeGL +336 (int (*)(...))QOpenGLWindow::paintGL +344 (int (*)(...))QOpenGLWindow::paintUnderGL +352 (int (*)(...))QOpenGLWindow::paintOverGL +360 (int (*)(...))QOpenGLWindow::redirected +368 (int (*)(...))-16 +376 (int (*)(...))(& _ZTI13QOpenGLWindow) +384 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev +392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev +400 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +408 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +416 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +424 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +432 (int (*)(...))-40 +440 (int (*)(...))(& _ZTI13QOpenGLWindow) +448 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev +456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev +464 (int (*)(...))QPaintDevice::devType +472 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +480 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QPaintDevice::initPainter +496 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint +504 (int (*)(...))QPaintDevice::sharedPainter + +Class QOpenGLWindow + size=64 align=8 + base size=64 base align=8 +QOpenGLWindow (0x0x7f22b6aca2d8) 0 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16) + QPaintDeviceWindow (0x0x7f22b6bfd0e0) 0 + primary-for QOpenGLWindow (0x0x7f22b6aca2d8) + QWindow (0x0x7f22b6bfd150) 0 + primary-for QPaintDeviceWindow (0x0x7f22b6bfd0e0) + QObject (0x0x7f22b6bdb8a0) 0 + primary-for QWindow (0x0x7f22b6bfd150) + QSurface (0x0x7f22b6bdb900) 16 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 384) + QPaintDevice (0x0x7f22b6bdb960) 40 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 448) + +Class QPageSize + size=8 align=8 + base size=8 base align=8 +QPageSize (0x0x7f22b6bdbba0) 0 + +Class QPageLayout + size=8 align=8 + base size=8 base align=8 +QPageLayout (0x0x7f22b6882600) 0 + +Class QPagedPaintDevice::Margins + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice::Margins (0x0x7f22b6916180) 0 + +Vtable for QPagedPaintDevice +QPagedPaintDevice::_ZTV17QPagedPaintDevice: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QPagedPaintDevice) +16 0 +24 0 +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QPagedPaintDevice::setPageSize +96 (int (*)(...))QPagedPaintDevice::setPageSizeMM +104 (int (*)(...))QPagedPaintDevice::setMargins + +Class QPagedPaintDevice + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice (0x0x7f22b68fe270) 0 + vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16) + QPaintDevice (0x0x7f22b6916120) 0 + primary-for QPagedPaintDevice (0x0x7f22b68fe270) + +Class QPainter::PixmapFragment + size=80 align=8 + base size=80 base align=8 +QPainter::PixmapFragment (0x0x7f22b6916240) 0 + +Class QPainter + size=8 align=8 + base size=8 base align=8 +QPainter (0x0x7f22b69161e0) 0 + +Class QTextItem + size=1 align=1 + base size=0 base align=1 +QTextItem (0x0x7f22b67385a0) 0 empty + +Vtable for QPaintEngine +QPaintEngine::_ZTV12QPaintEngine: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintEngine) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QPaintEngine::drawRects +64 (int (*)(...))QPaintEngine::drawRects +72 (int (*)(...))QPaintEngine::drawLines +80 (int (*)(...))QPaintEngine::drawLines +88 (int (*)(...))QPaintEngine::drawEllipse +96 (int (*)(...))QPaintEngine::drawEllipse +104 (int (*)(...))QPaintEngine::drawPath +112 (int (*)(...))QPaintEngine::drawPoints +120 (int (*)(...))QPaintEngine::drawPoints +128 (int (*)(...))QPaintEngine::drawPolygon +136 (int (*)(...))QPaintEngine::drawPolygon +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QPaintEngine::drawTextItem +160 (int (*)(...))QPaintEngine::drawTiledPixmap +168 (int (*)(...))QPaintEngine::drawImage +176 (int (*)(...))QPaintEngine::coordinateOffset +184 (int (*)(...))__cxa_pure_virtual + +Class QPaintEngine + size=32 align=8 + base size=32 base align=8 +QPaintEngine (0x0x7f22b677f4e0) 0 + vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16) + +Class QPaintEngineState + size=4 align=4 + base size=4 base align=4 +QPaintEngineState (0x0x7f22b677fcc0) 0 + +Class QPdfWriter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPdfWriter::QPrivateSignal (0x0x7f22b6837480) 0 empty + +Vtable for QPdfWriter +QPdfWriter::_ZTV10QPdfWriter: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QPdfWriter) +16 (int (*)(...))QPdfWriter::metaObject +24 (int (*)(...))QPdfWriter::qt_metacast +32 (int (*)(...))QPdfWriter::qt_metacall +40 (int (*)(...))QPdfWriter::~QPdfWriter +48 (int (*)(...))QPdfWriter::~QPdfWriter +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPdfWriter::newPage +120 (int (*)(...))QPdfWriter::setPageSize +128 (int (*)(...))QPdfWriter::setPageSizeMM +136 (int (*)(...))QPdfWriter::setMargins +144 (int (*)(...))QPdfWriter::paintEngine +152 (int (*)(...))QPdfWriter::metric +160 (int (*)(...))-16 +168 (int (*)(...))(& _ZTI10QPdfWriter) +176 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev +184 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev +192 (int (*)(...))QPaintDevice::devType +200 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv +208 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE +216 (int (*)(...))QPaintDevice::initPainter +224 (int (*)(...))QPaintDevice::redirected +232 (int (*)(...))QPaintDevice::sharedPainter +240 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv +248 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter11setPageSizeEN17QPagedPaintDevice8PageSizeE +256 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter13setPageSizeMMERK6QSizeF +264 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter10setMarginsERKN17QPagedPaintDevice7MarginsE + +Class QPdfWriter + size=48 align=8 + base size=48 base align=8 +QPdfWriter (0x0x7f22b683b1c0) 0 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16) + QObject (0x0x7f22b68373c0) 0 + primary-for QPdfWriter (0x0x7f22b683b1c0) + QPagedPaintDevice (0x0x7f22b6781618) 16 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 176) + QPaintDevice (0x0x7f22b6837420) 16 + primary-for QPagedPaintDevice (0x0x7f22b6781618) + +Vtable for QPicture +QPicture::_ZTV8QPicture: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPicture) +16 (int (*)(...))QPicture::~QPicture +24 (int (*)(...))QPicture::~QPicture +32 (int (*)(...))QPicture::devType +40 (int (*)(...))QPicture::paintEngine +48 (int (*)(...))QPicture::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPicture::setData + +Class QPicture + size=32 align=8 + base size=32 base align=8 +QPicture (0x0x7f22b6781680) 0 + vptr=((& QPicture::_ZTV8QPicture) + 16) + QPaintDevice (0x0x7f22b6837780) 0 + primary-for QPicture (0x0x7f22b6781680) + +Class QPictureIO + size=8 align=8 + base size=8 base align=8 +QPictureIO (0x0x7f22b64a1a20) 0 + +Class QPictureFormatPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPictureFormatPlugin::QPrivateSignal (0x0x7f22b64a1ae0) 0 empty + +Vtable for QPictureFormatPlugin +QPictureFormatPlugin::_ZTV20QPictureFormatPlugin: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QPictureFormatPlugin) +16 (int (*)(...))QPictureFormatPlugin::metaObject +24 (int (*)(...))QPictureFormatPlugin::qt_metacast +32 (int (*)(...))QPictureFormatPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPictureFormatPlugin::loadPicture +120 (int (*)(...))QPictureFormatPlugin::savePicture +128 (int (*)(...))__cxa_pure_virtual + +Class QPictureFormatPlugin + size=16 align=8 + base size=16 base align=8 +QPictureFormatPlugin (0x0x7f22b64a7820) 0 + vptr=((& QPictureFormatPlugin::_ZTV20QPictureFormatPlugin) + 16) + QObject (0x0x7f22b64a1a80) 0 + primary-for QPictureFormatPlugin (0x0x7f22b64a7820) + +Class QPixmapCache::Key + size=8 align=8 + base size=8 base align=8 +QPixmapCache::Key (0x0x7f22b64a1c60) 0 + +Class QPixmapCache + size=1 align=1 + base size=0 base align=1 +QPixmapCache (0x0x7f22b64a1c00) 0 empty + +Class QRasterWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRasterWindow::QPrivateSignal (0x0x7f22b657c420) 0 empty + +Vtable for QRasterWindow +QRasterWindow::_ZTV13QRasterWindow: 59 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QRasterWindow) +16 (int (*)(...))QRasterWindow::metaObject +24 (int (*)(...))QRasterWindow::qt_metacast +32 (int (*)(...))QRasterWindow::qt_metacall +40 (int (*)(...))QRasterWindow::~QRasterWindow +48 (int (*)(...))QRasterWindow::~QRasterWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QRasterWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QRasterWindow::redirected +328 (int (*)(...))-16 +336 (int (*)(...))(& _ZTI13QRasterWindow) +344 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev +352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +392 (int (*)(...))-40 +400 (int (*)(...))(& _ZTI13QRasterWindow) +408 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev +416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev +424 (int (*)(...))QPaintDevice::devType +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +440 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE +448 (int (*)(...))QPaintDevice::initPainter +456 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint +464 (int (*)(...))QPaintDevice::sharedPainter + +Class QRasterWindow + size=64 align=8 + base size=64 base align=8 +QRasterWindow (0x0x7f22b6577478) 0 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16) + QPaintDeviceWindow (0x0x7f22b6585000) 0 + primary-for QRasterWindow (0x0x7f22b6577478) + QWindow (0x0x7f22b6585070) 0 + primary-for QPaintDeviceWindow (0x0x7f22b6585000) + QObject (0x0x7f22b657c300) 0 + primary-for QWindow (0x0x7f22b6585070) + QSurface (0x0x7f22b657c360) 16 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 344) + QPaintDevice (0x0x7f22b657c3c0) 40 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 408) + +Class QScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScreen::QPrivateSignal (0x0x7f22b657c660) 0 empty + +Vtable for QScreen +QScreen::_ZTV7QScreen: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QScreen) +16 (int (*)(...))QScreen::metaObject +24 (int (*)(...))QScreen::qt_metacast +32 (int (*)(...))QScreen::qt_metacall +40 (int (*)(...))QScreen::~QScreen +48 (int (*)(...))QScreen::~QScreen +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScreen + size=16 align=8 + base size=16 base align=8 +QScreen (0x0x7f22b6577548) 0 + vptr=((& QScreen::_ZTV7QScreen) + 16) + QObject (0x0x7f22b657c600) 0 + primary-for QScreen (0x0x7f22b6577548) + +Class QSessionManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSessionManager::QPrivateSignal (0x0x7f22b657c8a0) 0 empty + +Vtable for QSessionManager +QSessionManager::_ZTV15QSessionManager: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSessionManager) +16 (int (*)(...))QSessionManager::metaObject +24 (int (*)(...))QSessionManager::qt_metacast +32 (int (*)(...))QSessionManager::qt_metacall +40 (int (*)(...))QSessionManager::~QSessionManager +48 (int (*)(...))QSessionManager::~QSessionManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSessionManager + size=16 align=8 + base size=16 base align=8 +QSessionManager (0x0x7f22b65775b0) 0 + vptr=((& QSessionManager::_ZTV15QSessionManager) + 16) + QObject (0x0x7f22b657c840) 0 + primary-for QSessionManager (0x0x7f22b65775b0) + +Vtable for QStandardItem +QStandardItem::_ZTV13QStandardItem: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStandardItem) +16 (int (*)(...))QStandardItem::~QStandardItem +24 (int (*)(...))QStandardItem::~QStandardItem +32 (int (*)(...))QStandardItem::data +40 (int (*)(...))QStandardItem::setData +48 (int (*)(...))QStandardItem::clone +56 (int (*)(...))QStandardItem::type +64 (int (*)(...))QStandardItem::read +72 (int (*)(...))QStandardItem::write +80 (int (*)(...))QStandardItem::operator< + +Class QStandardItem + size=16 align=8 + base size=16 base align=8 +QStandardItem (0x0x7f22b657ca80) 0 + vptr=((& QStandardItem::_ZTV13QStandardItem) + 16) + +Class QStandardItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStandardItemModel::QPrivateSignal (0x0x7f22b6276240) 0 empty + +Vtable for QStandardItemModel +QStandardItemModel::_ZTV18QStandardItemModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QStandardItemModel) +16 (int (*)(...))QStandardItemModel::metaObject +24 (int (*)(...))QStandardItemModel::qt_metacast +32 (int (*)(...))QStandardItemModel::qt_metacall +40 (int (*)(...))QStandardItemModel::~QStandardItemModel +48 (int (*)(...))QStandardItemModel::~QStandardItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStandardItemModel::index +120 (int (*)(...))QStandardItemModel::parent +128 (int (*)(...))QStandardItemModel::sibling +136 (int (*)(...))QStandardItemModel::rowCount +144 (int (*)(...))QStandardItemModel::columnCount +152 (int (*)(...))QStandardItemModel::hasChildren +160 (int (*)(...))QStandardItemModel::data +168 (int (*)(...))QStandardItemModel::setData +176 (int (*)(...))QStandardItemModel::headerData +184 (int (*)(...))QStandardItemModel::setHeaderData +192 (int (*)(...))QStandardItemModel::itemData +200 (int (*)(...))QStandardItemModel::setItemData +208 (int (*)(...))QStandardItemModel::mimeTypes +216 (int (*)(...))QStandardItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QStandardItemModel::dropMimeData +240 (int (*)(...))QStandardItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStandardItemModel::insertRows +264 (int (*)(...))QStandardItemModel::insertColumns +272 (int (*)(...))QStandardItemModel::removeRows +280 (int (*)(...))QStandardItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStandardItemModel::flags +328 (int (*)(...))QStandardItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStandardItemModel + size=16 align=8 + base size=16 base align=8 +QStandardItemModel (0x0x7f22b6577b60) 0 + vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16) + QAbstractItemModel (0x0x7f22b6577bc8) 0 + primary-for QStandardItemModel (0x0x7f22b6577b60) + QObject (0x0x7f22b62761e0) 0 + primary-for QAbstractItemModel (0x0x7f22b6577bc8) + +Class QStaticText + size=8 align=8 + base size=8 base align=8 +QStaticText (0x0x7f22b6276600) 0 + +Class QStyleHints::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyleHints::QPrivateSignal (0x0x7f22b62f99c0) 0 empty + +Vtable for QStyleHints +QStyleHints::_ZTV11QStyleHints: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QStyleHints) +16 (int (*)(...))QStyleHints::metaObject +24 (int (*)(...))QStyleHints::qt_metacast +32 (int (*)(...))QStyleHints::qt_metacall +40 (int (*)(...))QStyleHints::~QStyleHints +48 (int (*)(...))QStyleHints::~QStyleHints +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QStyleHints + size=16 align=8 + base size=16 base align=8 +QStyleHints (0x0x7f22b62edf08) 0 + vptr=((& QStyleHints::_ZTV11QStyleHints) + 16) + QObject (0x0x7f22b62f9960) 0 + primary-for QStyleHints (0x0x7f22b62edf08) + +Class QTextObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextObject::QPrivateSignal (0x0x7f22b62f9c00) 0 empty + +Vtable for QTextObject +QTextObject::_ZTV11QTextObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextObject) +16 (int (*)(...))QTextObject::metaObject +24 (int (*)(...))QTextObject::qt_metacast +32 (int (*)(...))QTextObject::qt_metacall +40 (int (*)(...))QTextObject::~QTextObject +48 (int (*)(...))QTextObject::~QTextObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextObject + size=16 align=8 + base size=16 base align=8 +QTextObject (0x0x7f22b62edf70) 0 + vptr=((& QTextObject::_ZTV11QTextObject) + 16) + QObject (0x0x7f22b62f9ba0) 0 + primary-for QTextObject (0x0x7f22b62edf70) + +Class QTextBlockGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBlockGroup::QPrivateSignal (0x0x7f22b62f9e40) 0 empty + +Vtable for QTextBlockGroup +QTextBlockGroup::_ZTV15QTextBlockGroup: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTextBlockGroup) +16 (int (*)(...))QTextBlockGroup::metaObject +24 (int (*)(...))QTextBlockGroup::qt_metacast +32 (int (*)(...))QTextBlockGroup::qt_metacall +40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextBlockGroup + size=16 align=8 + base size=16 base align=8 +QTextBlockGroup (0x0x7f22b6328000) 0 + vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16) + QTextObject (0x0x7f22b6328068) 0 + primary-for QTextBlockGroup (0x0x7f22b6328000) + QObject (0x0x7f22b62f9de0) 0 + primary-for QTextObject (0x0x7f22b6328068) + +Vtable for QTextFrameLayoutData +QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextFrameLayoutData) +16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData +24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData + +Class QTextFrameLayoutData + size=8 align=8 + base size=8 base align=8 +QTextFrameLayoutData (0x0x7f22b6337060) 0 nearly-empty + vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16) + +Class QTextFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextFrame::QPrivateSignal (0x0x7f22b6337120) 0 empty + +Class QTextFrame::iterator + size=32 align=8 + base size=28 base align=8 +QTextFrame::iterator (0x0x7f22b6337180) 0 + +Vtable for QTextFrame +QTextFrame::_ZTV10QTextFrame: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextFrame) +16 (int (*)(...))QTextFrame::metaObject +24 (int (*)(...))QTextFrame::qt_metacast +32 (int (*)(...))QTextFrame::qt_metacall +40 (int (*)(...))QTextFrame::~QTextFrame +48 (int (*)(...))QTextFrame::~QTextFrame +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextFrame + size=16 align=8 + base size=16 base align=8 +QTextFrame (0x0x7f22b63280d0) 0 + vptr=((& QTextFrame::_ZTV10QTextFrame) + 16) + QTextObject (0x0x7f22b6328138) 0 + primary-for QTextFrame (0x0x7f22b63280d0) + QObject (0x0x7f22b63370c0) 0 + primary-for QTextObject (0x0x7f22b6328138) + +Vtable for QTextBlockUserData +QTextBlockUserData::_ZTV18QTextBlockUserData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTextBlockUserData) +16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData +24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData + +Class QTextBlockUserData + size=8 align=8 + base size=8 base align=8 +QTextBlockUserData (0x0x7f22b6391ae0) 0 nearly-empty + vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16) + +Class QTextBlock::iterator + size=24 align=8 + base size=20 base align=8 +QTextBlock::iterator (0x0x7f22b6391ba0) 0 + +Class QTextBlock + size=16 align=8 + base size=12 base align=8 +QTextBlock (0x0x7f22b6391b40) 0 + +Class QTextFragment + size=16 align=8 + base size=16 base align=8 +QTextFragment (0x0x7f22b64378a0) 0 + +Class QSyntaxHighlighter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSyntaxHighlighter::QPrivateSignal (0x0x7f22b60910c0) 0 empty + +Vtable for QSyntaxHighlighter +QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSyntaxHighlighter) +16 (int (*)(...))QSyntaxHighlighter::metaObject +24 (int (*)(...))QSyntaxHighlighter::qt_metacast +32 (int (*)(...))QSyntaxHighlighter::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSyntaxHighlighter + size=16 align=8 + base size=16 base align=8 +QSyntaxHighlighter (0x0x7f22b608c3a8) 0 + vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16) + QObject (0x0x7f22b6091060) 0 + primary-for QSyntaxHighlighter (0x0x7f22b608c3a8) + +Class QTextDocumentFragment + size=8 align=8 + base size=8 base align=8 +QTextDocumentFragment (0x0x7f22b60912a0) 0 + +Class QTextDocumentWriter + size=8 align=8 + base size=8 base align=8 +QTextDocumentWriter (0x0x7f22b6091300) 0 + +Class QTextList::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextList::QPrivateSignal (0x0x7f22b60913c0) 0 empty + +Vtable for QTextList +QTextList::_ZTV9QTextList: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextList) +16 (int (*)(...))QTextList::metaObject +24 (int (*)(...))QTextList::qt_metacast +32 (int (*)(...))QTextList::qt_metacall +40 (int (*)(...))QTextList::~QTextList +48 (int (*)(...))QTextList::~QTextList +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextList + size=16 align=8 + base size=16 base align=8 +QTextList (0x0x7f22b608c410) 0 + vptr=((& QTextList::_ZTV9QTextList) + 16) + QTextBlockGroup (0x0x7f22b608c478) 0 + primary-for QTextList (0x0x7f22b608c410) + QTextObject (0x0x7f22b608c4e0) 0 + primary-for QTextBlockGroup (0x0x7f22b608c478) + QObject (0x0x7f22b6091360) 0 + primary-for QTextObject (0x0x7f22b608c4e0) + +Class QTextTableCell + size=16 align=8 + base size=12 base align=8 +QTextTableCell (0x0x7f22b60919c0) 0 + +Class QTextTable::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextTable::QPrivateSignal (0x0x7f22b60d2240) 0 empty + +Vtable for QTextTable +QTextTable::_ZTV10QTextTable: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextTable) +16 (int (*)(...))QTextTable::metaObject +24 (int (*)(...))QTextTable::qt_metacast +32 (int (*)(...))QTextTable::qt_metacall +40 (int (*)(...))QTextTable::~QTextTable +48 (int (*)(...))QTextTable::~QTextTable +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextTable + size=16 align=8 + base size=16 base align=8 +QTextTable (0x0x7f22b608c548) 0 + vptr=((& QTextTable::_ZTV10QTextTable) + 16) + QTextFrame (0x0x7f22b608c5b0) 0 + primary-for QTextTable (0x0x7f22b608c548) + QTextObject (0x0x7f22b608c618) 0 + primary-for QTextFrame (0x0x7f22b608c5b0) + QObject (0x0x7f22b60d21e0) 0 + primary-for QTextObject (0x0x7f22b608c618) + +Class QValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QValidator::QPrivateSignal (0x0x7f22b60d27e0) 0 empty + +Vtable for QValidator +QValidator::_ZTV10QValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QValidator) +16 (int (*)(...))QValidator::metaObject +24 (int (*)(...))QValidator::qt_metacast +32 (int (*)(...))QValidator::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QValidator::fixup + +Class QValidator + size=16 align=8 + base size=16 base align=8 +QValidator (0x0x7f22b608c680) 0 + vptr=((& QValidator::_ZTV10QValidator) + 16) + QObject (0x0x7f22b60d2780) 0 + primary-for QValidator (0x0x7f22b608c680) + +Class QIntValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIntValidator::QPrivateSignal (0x0x7f22b60d2a20) 0 empty + +Vtable for QIntValidator +QIntValidator::_ZTV13QIntValidator: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QIntValidator) +16 (int (*)(...))QIntValidator::metaObject +24 (int (*)(...))QIntValidator::qt_metacast +32 (int (*)(...))QIntValidator::qt_metacall +40 (int (*)(...))QIntValidator::~QIntValidator +48 (int (*)(...))QIntValidator::~QIntValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIntValidator::validate +120 (int (*)(...))QIntValidator::fixup +128 (int (*)(...))QIntValidator::setRange + +Class QIntValidator + size=24 align=8 + base size=24 base align=8 +QIntValidator (0x0x7f22b608c6e8) 0 + vptr=((& QIntValidator::_ZTV13QIntValidator) + 16) + QValidator (0x0x7f22b608c750) 0 + primary-for QIntValidator (0x0x7f22b608c6e8) + QObject (0x0x7f22b60d29c0) 0 + primary-for QValidator (0x0x7f22b608c750) + +Class QDoubleValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleValidator::QPrivateSignal (0x0x7f22b60d2c60) 0 empty + +Vtable for QDoubleValidator +QDoubleValidator::_ZTV16QDoubleValidator: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDoubleValidator) +16 (int (*)(...))QDoubleValidator::metaObject +24 (int (*)(...))QDoubleValidator::qt_metacast +32 (int (*)(...))QDoubleValidator::qt_metacall +40 (int (*)(...))QDoubleValidator::~QDoubleValidator +48 (int (*)(...))QDoubleValidator::~QDoubleValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDoubleValidator::validate +120 (int (*)(...))QValidator::fixup +128 (int (*)(...))QDoubleValidator::setRange + +Class QDoubleValidator + size=40 align=8 + base size=36 base align=8 +QDoubleValidator (0x0x7f22b608c7b8) 0 + vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16) + QValidator (0x0x7f22b608c820) 0 + primary-for QDoubleValidator (0x0x7f22b608c7b8) + QObject (0x0x7f22b60d2c00) 0 + primary-for QValidator (0x0x7f22b608c820) + +Class QRegExpValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegExpValidator::QPrivateSignal (0x0x7f22b611b120) 0 empty + +Vtable for QRegExpValidator +QRegExpValidator::_ZTV16QRegExpValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QRegExpValidator) +16 (int (*)(...))QRegExpValidator::metaObject +24 (int (*)(...))QRegExpValidator::qt_metacast +32 (int (*)(...))QRegExpValidator::qt_metacall +40 (int (*)(...))QRegExpValidator::~QRegExpValidator +48 (int (*)(...))QRegExpValidator::~QRegExpValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegExpValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegExpValidator + size=24 align=8 + base size=24 base align=8 +QRegExpValidator (0x0x7f22b608c888) 0 + vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16) + QValidator (0x0x7f22b608c8f0) 0 + primary-for QRegExpValidator (0x0x7f22b608c888) + QObject (0x0x7f22b611b0c0) 0 + primary-for QValidator (0x0x7f22b608c8f0) + +Class QRegularExpressionValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegularExpressionValidator::QPrivateSignal (0x0x7f22b611b300) 0 empty + +Vtable for QRegularExpressionValidator +QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QRegularExpressionValidator) +16 (int (*)(...))QRegularExpressionValidator::metaObject +24 (int (*)(...))QRegularExpressionValidator::qt_metacast +32 (int (*)(...))QRegularExpressionValidator::qt_metacall +40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegularExpressionValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegularExpressionValidator + size=16 align=8 + base size=16 base align=8 +QRegularExpressionValidator (0x0x7f22b608c958) 0 + vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16) + QValidator (0x0x7f22b608c9c0) 0 + primary-for QRegularExpressionValidator (0x0x7f22b608c958) + QObject (0x0x7f22b611b2a0) 0 + primary-for QValidator (0x0x7f22b608c9c0) + +Class QNetworkRequest + size=8 align=8 + base size=8 base align=8 +QNetworkRequest (0x0x7f22b611b4e0) 0 + +Class QNetworkCacheMetaData + size=8 align=8 + base size=8 base align=8 +QNetworkCacheMetaData (0x0x7f22b6186e40) 0 + +Class QAbstractNetworkCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractNetworkCache::QPrivateSignal (0x0x7f22b61fa420) 0 empty + +Vtable for QAbstractNetworkCache +QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractNetworkCache) +16 (int (*)(...))QAbstractNetworkCache::metaObject +24 (int (*)(...))QAbstractNetworkCache::qt_metacast +32 (int (*)(...))QAbstractNetworkCache::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNetworkCache + size=16 align=8 + base size=16 base align=8 +QAbstractNetworkCache (0x0x7f22b61f4618) 0 + vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16) + QObject (0x0x7f22b61fa3c0) 0 + primary-for QAbstractNetworkCache (0x0x7f22b61f4618) + +Class QAbstractSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSocket::QPrivateSignal (0x0x7f22b61fa660) 0 empty + +Vtable for QAbstractSocket +QAbstractSocket::_ZTV15QAbstractSocket: 41 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSocket) +16 (int (*)(...))QAbstractSocket::metaObject +24 (int (*)(...))QAbstractSocket::qt_metacast +32 (int (*)(...))QAbstractSocket::qt_metacall +40 (int (*)(...))QAbstractSocket::~QAbstractSocket +48 (int (*)(...))QAbstractSocket::~QAbstractSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QAbstractSocket + size=16 align=8 + base size=16 base align=8 +QAbstractSocket (0x0x7f22b61f4680) 0 + vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16) + QIODevice (0x0x7f22b61f46e8) 0 + primary-for QAbstractSocket (0x0x7f22b61f4680) + QObject (0x0x7f22b61fa600) 0 + primary-for QIODevice (0x0x7f22b61f46e8) + +Class QAuthenticator + size=8 align=8 + base size=8 base align=8 +QAuthenticator (0x0x7f22b5e64d80) 0 + +Class QDnsDomainNameRecord + size=8 align=8 + base size=8 base align=8 +QDnsDomainNameRecord (0x0x7f22b5e64e40) 0 + +Class QDnsHostAddressRecord + size=8 align=8 + base size=8 base align=8 +QDnsHostAddressRecord (0x0x7f22b5f01000) 0 + +Class QDnsMailExchangeRecord + size=8 align=8 + base size=8 base align=8 +QDnsMailExchangeRecord (0x0x7f22b5f4d180) 0 + +Class QDnsServiceRecord + size=8 align=8 + base size=8 base align=8 +QDnsServiceRecord (0x0x7f22b5f9c240) 0 + +Class QDnsTextRecord + size=8 align=8 + base size=8 base align=8 +QDnsTextRecord (0x0x7f22b5fe44e0) 0 + +Class QDnsLookup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDnsLookup::QPrivateSignal (0x0x7f22b602da20) 0 empty + +Vtable for QDnsLookup +QDnsLookup::_ZTV10QDnsLookup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDnsLookup) +16 (int (*)(...))QDnsLookup::metaObject +24 (int (*)(...))QDnsLookup::qt_metacast +32 (int (*)(...))QDnsLookup::qt_metacall +40 (int (*)(...))QDnsLookup::~QDnsLookup +48 (int (*)(...))QDnsLookup::~QDnsLookup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDnsLookup + size=16 align=8 + base size=16 base align=8 +QDnsLookup (0x0x7f22b6024c98) 0 + vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16) + QObject (0x0x7f22b602d9c0) 0 + primary-for QDnsLookup (0x0x7f22b6024c98) + +Class QTcpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpSocket::QPrivateSignal (0x0x7f22b602dde0) 0 empty + +Vtable for QTcpSocket +QTcpSocket::_ZTV10QTcpSocket: 41 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpSocket) +16 (int (*)(...))QTcpSocket::metaObject +24 (int (*)(...))QTcpSocket::qt_metacast +32 (int (*)(...))QTcpSocket::qt_metacall +40 (int (*)(...))QTcpSocket::~QTcpSocket +48 (int (*)(...))QTcpSocket::~QTcpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QTcpSocket + size=16 align=8 + base size=16 base align=8 +QTcpSocket (0x0x7f22b6024d00) 0 + vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16) + QAbstractSocket (0x0x7f22b6024d68) 0 + primary-for QTcpSocket (0x0x7f22b6024d00) + QIODevice (0x0x7f22b6024dd0) 0 + primary-for QAbstractSocket (0x0x7f22b6024d68) + QObject (0x0x7f22b602dd80) 0 + primary-for QIODevice (0x0x7f22b6024dd0) + +Class QSslCertificate + size=8 align=8 + base size=8 base align=8 +QSslCertificate (0x0x7f22b5c676c0) 0 + +Class QSslError + size=8 align=8 + base size=8 base align=8 +QSslError (0x0x7f22b5cdfe40) 0 + +Class QSslSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSslSocket::QPrivateSignal (0x0x7f22b5df4060) 0 empty + +Vtable for QSslSocket +QSslSocket::_ZTV10QSslSocket: 41 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSslSocket) +16 (int (*)(...))QSslSocket::metaObject +24 (int (*)(...))QSslSocket::qt_metacast +32 (int (*)(...))QSslSocket::qt_metacall +40 (int (*)(...))QSslSocket::~QSslSocket +48 (int (*)(...))QSslSocket::~QSslSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QSslSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QSslSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QSslSocket::bytesAvailable +184 (int (*)(...))QSslSocket::bytesToWrite +192 (int (*)(...))QSslSocket::canReadLine +200 (int (*)(...))QSslSocket::waitForReadyRead +208 (int (*)(...))QSslSocket::waitForBytesWritten +216 (int (*)(...))QSslSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QSslSocket::writeData +240 (int (*)(...))QSslSocket::resume +248 (int (*)(...))QSslSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QSslSocket::disconnectFromHost +272 (int (*)(...))QSslSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QSslSocket::setSocketDescriptor +296 (int (*)(...))QSslSocket::setSocketOption +304 (int (*)(...))QSslSocket::socketOption +312 (int (*)(...))QSslSocket::waitForConnected +320 (int (*)(...))QSslSocket::waitForDisconnected + +Class QSslSocket + size=16 align=8 + base size=16 base align=8 +QSslSocket (0x0x7f22b5dbd138) 0 + vptr=((& QSslSocket::_ZTV10QSslSocket) + 16) + QTcpSocket (0x0x7f22b5dbd1a0) 0 + primary-for QSslSocket (0x0x7f22b5dbd138) + QAbstractSocket (0x0x7f22b5dbd208) 0 + primary-for QTcpSocket (0x0x7f22b5dbd1a0) + QIODevice (0x0x7f22b5dbd270) 0 + primary-for QAbstractSocket (0x0x7f22b5dbd208) + QObject (0x0x7f22b5df4000) 0 + primary-for QIODevice (0x0x7f22b5dbd270) + +Class QDtlsClientVerifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtlsClientVerifier::QPrivateSignal (0x0x7f22b5df42a0) 0 empty + +Class QDtlsClientVerifier::GeneratorParameters + size=16 align=8 + base size=16 base align=8 +QDtlsClientVerifier::GeneratorParameters (0x0x7f22b5df4300) 0 + +Vtable for QDtlsClientVerifier +QDtlsClientVerifier::_ZTV19QDtlsClientVerifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QDtlsClientVerifier) +16 (int (*)(...))QDtlsClientVerifier::metaObject +24 (int (*)(...))QDtlsClientVerifier::qt_metacast +32 (int (*)(...))QDtlsClientVerifier::qt_metacall +40 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +48 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtlsClientVerifier + size=16 align=8 + base size=16 base align=8 +QDtlsClientVerifier (0x0x7f22b5dbd2d8) 0 + vptr=((& QDtlsClientVerifier::_ZTV19QDtlsClientVerifier) + 16) + QObject (0x0x7f22b5df4240) 0 + primary-for QDtlsClientVerifier (0x0x7f22b5dbd2d8) + +Class QDtls::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtls::QPrivateSignal (0x0x7f22b5df4540) 0 empty + +Vtable for QDtls +QDtls::_ZTV5QDtls: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDtls) +16 (int (*)(...))QDtls::metaObject +24 (int (*)(...))QDtls::qt_metacast +32 (int (*)(...))QDtls::qt_metacall +40 (int (*)(...))QDtls::~QDtls +48 (int (*)(...))QDtls::~QDtls +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtls + size=16 align=8 + base size=16 base align=8 +QDtls (0x0x7f22b5dbd340) 0 + vptr=((& QDtls::_ZTV5QDtls) + 16) + QObject (0x0x7f22b5df44e0) 0 + primary-for QDtls (0x0x7f22b5dbd340) + +Class QIPv6Address + size=16 align=1 + base size=16 base align=1 +QIPv6Address (0x0x7f22b5df4780) 0 + +Class QHostAddress + size=8 align=8 + base size=8 base align=8 +QHostAddress (0x0x7f22b5df48a0) 0 + +Class QHostInfo + size=8 align=8 + base size=8 base align=8 +QHostInfo (0x0x7f22b5a4e660) 0 + +Class QHstsPolicy + size=8 align=8 + base size=8 base align=8 +QHstsPolicy (0x0x7f22b5b29480) 0 + +Class QHttpPart + size=8 align=8 + base size=8 base align=8 +QHttpPart (0x0x7f22b5bbb0c0) 0 + +Class QHttpMultiPart::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHttpMultiPart::QPrivateSignal (0x0x7f22b580c240) 0 empty + +Vtable for QHttpMultiPart +QHttpMultiPart::_ZTV14QHttpMultiPart: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QHttpMultiPart) +16 (int (*)(...))QHttpMultiPart::metaObject +24 (int (*)(...))QHttpMultiPart::qt_metacast +32 (int (*)(...))QHttpMultiPart::qt_metacall +40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QHttpMultiPart + size=16 align=8 + base size=16 base align=8 +QHttpMultiPart (0x0x7f22b580d138) 0 + vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16) + QObject (0x0x7f22b580c1e0) 0 + primary-for QHttpMultiPart (0x0x7f22b580d138) + +Class QLocalServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalServer::QPrivateSignal (0x0x7f22c6235f00) 0 empty + +Vtable for QLocalServer +QLocalServer::_ZTV12QLocalServer: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalServer) +16 (int (*)(...))QLocalServer::metaObject +24 (int (*)(...))QLocalServer::qt_metacast +32 (int (*)(...))QLocalServer::qt_metacall +40 (int (*)(...))QLocalServer::~QLocalServer +48 (int (*)(...))QLocalServer::~QLocalServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalServer::hasPendingConnections +120 (int (*)(...))QLocalServer::nextPendingConnection +128 (int (*)(...))QLocalServer::incomingConnection + +Class QLocalServer + size=16 align=8 + base size=16 base align=8 +QLocalServer (0x0x7f22ba1a3270) 0 + vptr=((& QLocalServer::_ZTV12QLocalServer) + 16) + QObject (0x0x7f22c6235d80) 0 + primary-for QLocalServer (0x0x7f22ba1a3270) + +Class QLocalSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalSocket::QPrivateSignal (0x0x7f22c2b5ad80) 0 empty + +Vtable for QLocalSocket +QLocalSocket::_ZTV12QLocalSocket: 30 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalSocket) +16 (int (*)(...))QLocalSocket::metaObject +24 (int (*)(...))QLocalSocket::qt_metacast +32 (int (*)(...))QLocalSocket::qt_metacall +40 (int (*)(...))QLocalSocket::~QLocalSocket +48 (int (*)(...))QLocalSocket::~QLocalSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalSocket::isSequential +120 (int (*)(...))QLocalSocket::open +128 (int (*)(...))QLocalSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QLocalSocket::bytesAvailable +184 (int (*)(...))QLocalSocket::bytesToWrite +192 (int (*)(...))QLocalSocket::canReadLine +200 (int (*)(...))QLocalSocket::waitForReadyRead +208 (int (*)(...))QLocalSocket::waitForBytesWritten +216 (int (*)(...))QLocalSocket::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QLocalSocket::writeData + +Class QLocalSocket + size=16 align=8 + base size=16 base align=8 +QLocalSocket (0x0x7f22ba1a3ea0) 0 + vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16) + QIODevice (0x0x7f22ba1a3f08) 0 + primary-for QLocalSocket (0x0x7f22ba1a3ea0) + QObject (0x0x7f22c2b5ad20) 0 + primary-for QIODevice (0x0x7f22ba1a3f08) + +Class QSslConfiguration + size=8 align=8 + base size=8 base align=8 +QSslConfiguration (0x0x7f22c2b972a0) 0 + +Class QSslPreSharedKeyAuthenticator + size=8 align=8 + base size=8 base align=8 +QSslPreSharedKeyAuthenticator (0x0x7f22c29f88a0) 0 + +Class QNetworkAccessManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkAccessManager::QPrivateSignal (0x0x7f22c0f08540) 0 empty + +Vtable for QNetworkAccessManager +QNetworkAccessManager::_ZTV21QNetworkAccessManager: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QNetworkAccessManager) +16 (int (*)(...))QNetworkAccessManager::metaObject +24 (int (*)(...))QNetworkAccessManager::qt_metacast +32 (int (*)(...))QNetworkAccessManager::qt_metacall +40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkAccessManager::createRequest + +Class QNetworkAccessManager + size=16 align=8 + base size=16 base align=8 +QNetworkAccessManager (0x0x7f22c0dda8f0) 0 + vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16) + QObject (0x0x7f22c0eecf00) 0 + primary-for QNetworkAccessManager (0x0x7f22c0dda8f0) + +Class QNetworkConfiguration + size=8 align=8 + base size=8 base align=8 +QNetworkConfiguration (0x0x7f22c0fc1600) 0 + +Class QNetworkConfigurationManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkConfigurationManager::QPrivateSignal (0x0x7f22bf9dac60) 0 empty + +Vtable for QNetworkConfigurationManager +QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QNetworkConfigurationManager) +16 (int (*)(...))QNetworkConfigurationManager::metaObject +24 (int (*)(...))QNetworkConfigurationManager::qt_metacast +32 (int (*)(...))QNetworkConfigurationManager::qt_metacall +40 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager +48 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QNetworkConfigurationManager + size=16 align=8 + base size=16 base align=8 +QNetworkConfigurationManager (0x0x7f22bf594f08) 0 + vptr=((& QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager) + 16) + QObject (0x0x7f22c0069300) 0 + primary-for QNetworkConfigurationManager (0x0x7f22bf594f08) + +Class QNetworkCookie + size=8 align=8 + base size=8 base align=8 +QNetworkCookie (0x0x7f22bf7a3b40) 0 + +Class QNetworkCookieJar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkCookieJar::QPrivateSignal (0x0x7f22bf1a2240) 0 empty + +Vtable for QNetworkCookieJar +QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkCookieJar) +16 (int (*)(...))QNetworkCookieJar::metaObject +24 (int (*)(...))QNetworkCookieJar::qt_metacast +32 (int (*)(...))QNetworkCookieJar::qt_metacall +40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkCookieJar::cookiesForUrl +120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl +128 (int (*)(...))QNetworkCookieJar::insertCookie +136 (int (*)(...))QNetworkCookieJar::updateCookie +144 (int (*)(...))QNetworkCookieJar::deleteCookie +152 (int (*)(...))QNetworkCookieJar::validateCookie + +Class QNetworkCookieJar + size=16 align=8 + base size=16 base align=8 +QNetworkCookieJar (0x0x7f22bec58478) 0 + vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16) + QObject (0x0x7f22bf1a2180) 0 + primary-for QNetworkCookieJar (0x0x7f22bec58478) + +Class QNetworkDatagram + size=8 align=8 + base size=8 base align=8 +QNetworkDatagram (0x0x7f22bee8e3c0) 0 + +Class QNetworkDiskCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkDiskCache::QPrivateSignal (0x0x7f22bdfd6540) 0 empty + +Vtable for QNetworkDiskCache +QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkDiskCache) +16 (int (*)(...))QNetworkDiskCache::metaObject +24 (int (*)(...))QNetworkDiskCache::qt_metacast +32 (int (*)(...))QNetworkDiskCache::qt_metacall +40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkDiskCache::metaData +120 (int (*)(...))QNetworkDiskCache::updateMetaData +128 (int (*)(...))QNetworkDiskCache::data +136 (int (*)(...))QNetworkDiskCache::remove +144 (int (*)(...))QNetworkDiskCache::cacheSize +152 (int (*)(...))QNetworkDiskCache::prepare +160 (int (*)(...))QNetworkDiskCache::insert +168 (int (*)(...))QNetworkDiskCache::clear +176 (int (*)(...))QNetworkDiskCache::expire + +Class QNetworkDiskCache + size=16 align=8 + base size=16 base align=8 +QNetworkDiskCache (0x0x7f22bd6d1f70) 0 + vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16) + QAbstractNetworkCache (0x0x7f22bd6e7888) 0 + primary-for QNetworkDiskCache (0x0x7f22bd6d1f70) + QObject (0x0x7f22bdfb29c0) 0 + primary-for QAbstractNetworkCache (0x0x7f22bd6e7888) + +Class QNetworkAddressEntry + size=8 align=8 + base size=8 base align=8 +QNetworkAddressEntry (0x0x7f22bdff4600) 0 + +Class QNetworkInterface + size=8 align=8 + base size=8 base align=8 +QNetworkInterface (0x0x7f22bd1d6f00) 0 + +Class QNetworkProxyQuery + size=8 align=8 + base size=8 base align=8 +QNetworkProxyQuery (0x0x7f22bcbc0420) 0 + +Class QNetworkProxy + size=8 align=8 + base size=8 base align=8 +QNetworkProxy (0x0x7f22bc59aae0) 0 + +Vtable for QNetworkProxyFactory +QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QNetworkProxyFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNetworkProxyFactory + size=8 align=8 + base size=8 base align=8 +QNetworkProxyFactory (0x0x7f22bb801660) 0 nearly-empty + vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16) + +Class QNetworkReply::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkReply::QPrivateSignal (0x0x7f22bb820ba0) 0 empty + +Vtable for QNetworkReply +QNetworkReply::_ZTV13QNetworkReply: 36 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QNetworkReply) +16 (int (*)(...))QNetworkReply::metaObject +24 (int (*)(...))QNetworkReply::qt_metacast +32 (int (*)(...))QNetworkReply::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkReply::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QNetworkReply::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QNetworkReply::writeData +240 (int (*)(...))QNetworkReply::setReadBufferSize +248 (int (*)(...))__cxa_pure_virtual +256 (int (*)(...))QNetworkReply::ignoreSslErrors +264 (int (*)(...))QNetworkReply::sslConfigurationImplementation +272 (int (*)(...))QNetworkReply::setSslConfigurationImplementation +280 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation + +Class QNetworkReply + size=16 align=8 + base size=16 base align=8 +QNetworkReply (0x0x7f22ba217958) 0 + vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16) + QIODevice (0x0x7f22ba2179c0) 0 + primary-for QNetworkReply (0x0x7f22ba217958) + QObject (0x0x7f22bb820b40) 0 + primary-for QIODevice (0x0x7f22ba2179c0) + +Class QNetworkSession::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkSession::QPrivateSignal (0x0x7f22bb542900) 0 empty + +Vtable for QNetworkSession +QNetworkSession::_ZTV15QNetworkSession: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QNetworkSession) +16 (int (*)(...))QNetworkSession::metaObject +24 (int (*)(...))QNetworkSession::qt_metacast +32 (int (*)(...))QNetworkSession::qt_metacall +40 (int (*)(...))QNetworkSession::~QNetworkSession +48 (int (*)(...))QNetworkSession::~QNetworkSession +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QNetworkSession::connectNotify +104 (int (*)(...))QNetworkSession::disconnectNotify + +Class QNetworkSession + size=24 align=8 + base size=24 base align=8 +QNetworkSession (0x0x7f22ba22e0d0) 0 + vptr=((& QNetworkSession::_ZTV15QNetworkSession) + 16) + QObject (0x0x7f22bb49ed80) 0 + primary-for QNetworkSession (0x0x7f22ba22e0d0) + +Class QOcspResponse + size=8 align=8 + base size=8 base align=8 +QOcspResponse (0x0x7f22bb2b0cc0) 0 + +Class QTcpServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpServer::QPrivateSignal (0x0x7f22ba91cf00) 0 empty + +Vtable for QTcpServer +QTcpServer::_ZTV10QTcpServer: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpServer) +16 (int (*)(...))QTcpServer::metaObject +24 (int (*)(...))QTcpServer::qt_metacast +32 (int (*)(...))QTcpServer::qt_metacall +40 (int (*)(...))QTcpServer::~QTcpServer +48 (int (*)(...))QTcpServer::~QTcpServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTcpServer::hasPendingConnections +120 (int (*)(...))QTcpServer::nextPendingConnection +128 (int (*)(...))QTcpServer::incomingConnection + +Class QTcpServer + size=16 align=8 + base size=16 base align=8 +QTcpServer (0x0x7f22b98ad478) 0 + vptr=((& QTcpServer::_ZTV10QTcpServer) + 16) + QObject (0x0x7f22ba91cae0) 0 + primary-for QTcpServer (0x0x7f22b98ad478) + +Class QSslCertificateExtension + size=8 align=8 + base size=8 base align=8 +QSslCertificateExtension (0x0x7f22ba9f7480) 0 + +Class QSslCipher + size=8 align=8 + base size=8 base align=8 +QSslCipher (0x0x7f22ba1c8420) 0 + +Class QSslDiffieHellmanParameters + size=8 align=8 + base size=8 base align=8 +QSslDiffieHellmanParameters (0x0x7f22b905f9c0) 0 + +Class QSslEllipticCurve + size=4 align=4 + base size=4 base align=4 +QSslEllipticCurve (0x0x7f22b8bd7cc0) 0 + +Class QSslKey + size=8 align=8 + base size=8 base align=8 +QSslKey (0x0x7f22b87893c0) 0 + +Class QUdpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUdpSocket::QPrivateSignal (0x0x7f22b7e89ae0) 0 empty + +Vtable for QUdpSocket +QUdpSocket::_ZTV10QUdpSocket: 41 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUdpSocket) +16 (int (*)(...))QUdpSocket::metaObject +24 (int (*)(...))QUdpSocket::qt_metacast +32 (int (*)(...))QUdpSocket::qt_metacall +40 (int (*)(...))QUdpSocket::~QUdpSocket +48 (int (*)(...))QUdpSocket::~QUdpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QUdpSocket + size=16 align=8 + base size=16 base align=8 +QUdpSocket (0x0x7f22c0c0c208) 0 + vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16) + QAbstractSocket (0x0x7f22c0c0c270) 0 + primary-for QUdpSocket (0x0x7f22c0c0c208) + QIODevice (0x0x7f22c0c0c2d8) 0 + primary-for QAbstractSocket (0x0x7f22c0c0c270) + QObject (0x0x7f22b7e89a80) 0 + primary-for QIODevice (0x0x7f22c0c0c2d8) + +Class QJSValue + size=8 align=8 + base size=8 base align=8 +QJSValue (0x0x7f22b7eca1e0) 0 + +Class QQmlDebuggingEnabler + size=1 align=1 + base size=0 base align=1 +QQmlDebuggingEnabler (0x0x7f22b7f015a0) 0 empty + +Class QJSEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QJSEngine::QPrivateSignal (0x0x7f22b7f01720) 0 empty + +Vtable for QJSEngine +QJSEngine::_ZTV9QJSEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QJSEngine) +16 (int (*)(...))QJSEngine::metaObject +24 (int (*)(...))QJSEngine::qt_metacast +32 (int (*)(...))QJSEngine::qt_metacall +40 (int (*)(...))QJSEngine::~QJSEngine +48 (int (*)(...))QJSEngine::~QJSEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QJSEngine + size=24 align=8 + base size=24 base align=8 +QJSEngine (0x0x7f22c0c0c3a8) 0 + vptr=((& QJSEngine::_ZTV9QJSEngine) + 16) + QObject (0x0x7f22b7f01660) 0 + primary-for QJSEngine (0x0x7f22c0c0c3a8) + +Class QJSValueIterator + size=8 align=8 + base size=8 base align=8 +QJSValueIterator (0x0x7f22b7fb2d20) 0 + +Class QQmlPrivate::RegisterType + size=128 align=8 + base size=124 base align=8 +QQmlPrivate::RegisterType (0x0x7f22b7d25120) 0 + +Class QQmlPrivate::RegisterInterface + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::RegisterInterface (0x0x7f22b7d25180) 0 + +Class QQmlPrivate::RegisterAutoParent + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterAutoParent (0x0x7f22b7d253c0) 0 + +Class QQmlPrivate::RegisterSingletonType + size=64 align=8 + base size=64 base align=8 +QQmlPrivate::RegisterSingletonType (0x0x7f22b7d25420) 0 + +Class QQmlPrivate::RegisterCompositeType + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::RegisterCompositeType (0x0x7f22b7d25f00) 0 + +Class QQmlPrivate::RegisterCompositeSingletonType + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::RegisterCompositeSingletonType (0x0x7f22b7d25f60) 0 + +Class QQmlPrivate::CachedQmlUnit + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::CachedQmlUnit (0x0x7f22b7d422a0) 0 + +Class QQmlPrivate::RegisterQmlUnitCacheHook + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterQmlUnitCacheHook (0x0x7f22b7d42300) 0 + +Vtable for QQmlParserStatus +QQmlParserStatus::_ZTV16QQmlParserStatus: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlParserStatus) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlParserStatus + size=16 align=8 + base size=16 base align=8 +QQmlParserStatus (0x0x7f22b7d6f060) 0 + vptr=((& QQmlParserStatus::_ZTV16QQmlParserStatus) + 16) + +Vtable for QQmlPropertyValueSource +QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQmlPropertyValueSource) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlPropertyValueSource + size=8 align=8 + base size=8 base align=8 +QQmlPropertyValueSource (0x0x7f22b7d6f4e0) 0 nearly-empty + vptr=((& QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource) + 16) + +Class QQmlListReference + size=8 align=8 + base size=8 base align=8 +QQmlListReference (0x0x7f22b7c095a0) 0 + +Vtable for QQmlAbstractUrlInterceptor +QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QQmlAbstractUrlInterceptor) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlAbstractUrlInterceptor + size=8 align=8 + base size=8 base align=8 +QQmlAbstractUrlInterceptor (0x0x7f22b6d8bf60) 0 nearly-empty + vptr=((& QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor) + 16) + +Class QQmlError + size=8 align=8 + base size=8 base align=8 +QQmlError (0x0x7f22b6dbf600) 0 + +Vtable for QQmlImageProviderBase +QQmlImageProviderBase::_ZTV21QQmlImageProviderBase: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlImageProviderBase) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlImageProviderBase + size=8 align=8 + base size=8 base align=8 +QQmlImageProviderBase (0x0x7f22b6391300) 0 nearly-empty + vptr=((& QQmlImageProviderBase::_ZTV21QQmlImageProviderBase) + 16) + +Class QQmlEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngine::QPrivateSignal (0x0x7f22b6437120) 0 empty + +Vtable for QQmlEngine +QQmlEngine::_ZTV10QQmlEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQmlEngine) +16 (int (*)(...))QQmlEngine::metaObject +24 (int (*)(...))QQmlEngine::qt_metacast +32 (int (*)(...))QQmlEngine::qt_metacall +40 (int (*)(...))QQmlEngine::~QQmlEngine +48 (int (*)(...))QQmlEngine::~QQmlEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlEngine + size=24 align=8 + base size=24 base align=8 +QQmlEngine (0x0x7f22bea17a90) 0 + vptr=((& QQmlEngine::_ZTV10QQmlEngine) + 16) + QJSEngine (0x0x7f22bea17af8) 0 + primary-for QQmlEngine (0x0x7f22bea17a90) + QObject (0x0x7f22b6437060) 0 + primary-for QJSEngine (0x0x7f22bea17af8) + +Class QQmlApplicationEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlApplicationEngine::QPrivateSignal (0x0x7f22b6057660) 0 empty + +Vtable for QQmlApplicationEngine +QQmlApplicationEngine::_ZTV21QQmlApplicationEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlApplicationEngine) +16 (int (*)(...))QQmlApplicationEngine::metaObject +24 (int (*)(...))QQmlApplicationEngine::qt_metacast +32 (int (*)(...))QQmlApplicationEngine::qt_metacall +40 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +48 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlApplicationEngine + size=24 align=8 + base size=24 base align=8 +QQmlApplicationEngine (0x0x7f22bea17bc8) 0 + vptr=((& QQmlApplicationEngine::_ZTV21QQmlApplicationEngine) + 16) + QQmlEngine (0x0x7f22bea17c30) 0 + primary-for QQmlApplicationEngine (0x0x7f22bea17bc8) + QJSEngine (0x0x7f22bea17c98) 0 + primary-for QQmlEngine (0x0x7f22bea17c30) + QObject (0x0x7f22b6057600) 0 + primary-for QJSEngine (0x0x7f22bea17c98) + +Class QQmlComponent::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlComponent::QPrivateSignal (0x0x7f22b6073720) 0 empty + +Vtable for QQmlComponent +QQmlComponent::_ZTV13QQmlComponent: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlComponent) +16 (int (*)(...))QQmlComponent::metaObject +24 (int (*)(...))QQmlComponent::qt_metacast +32 (int (*)(...))QQmlComponent::qt_metacall +40 (int (*)(...))QQmlComponent::~QQmlComponent +48 (int (*)(...))QQmlComponent::~QQmlComponent +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlComponent::create +120 (int (*)(...))QQmlComponent::beginCreate +128 (int (*)(...))QQmlComponent::completeCreate + +Class QQmlComponent + size=16 align=8 + base size=16 base align=8 +QQmlComponent (0x0x7f22bea17d00) 0 + vptr=((& QQmlComponent::_ZTV13QQmlComponent) + 16) + QObject (0x0x7f22b6057ae0) 0 + primary-for QQmlComponent (0x0x7f22bea17d00) + +Class QQmlContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlContext::QPrivateSignal (0x0x7f22b61fa180) 0 empty + +Class QQmlContext::PropertyPair + size=24 align=8 + base size=24 base align=8 +QQmlContext::PropertyPair (0x0x7f22b61fa240) 0 + +Vtable for QQmlContext +QQmlContext::_ZTV11QQmlContext: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QQmlContext) +16 (int (*)(...))QQmlContext::metaObject +24 (int (*)(...))QQmlContext::qt_metacast +32 (int (*)(...))QQmlContext::qt_metacall +40 (int (*)(...))QQmlContext::~QQmlContext +48 (int (*)(...))QQmlContext::~QQmlContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlContext + size=16 align=8 + base size=16 base align=8 +QQmlContext (0x0x7f22bda81270) 0 + vptr=((& QQmlContext::_ZTV11QQmlContext) + 16) + QObject (0x0x7f22b61fa120) 0 + primary-for QQmlContext (0x0x7f22bda81270) + +Class QQmlScriptString + size=8 align=8 + base size=8 base align=8 +QQmlScriptString (0x0x7f22b5ee6e40) 0 + +Class QQmlExpression::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExpression::QPrivateSignal (0x0x7f22b5f31ea0) 0 empty + +Vtable for QQmlExpression +QQmlExpression::_ZTV14QQmlExpression: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QQmlExpression) +16 (int (*)(...))QQmlExpression::metaObject +24 (int (*)(...))QQmlExpression::qt_metacast +32 (int (*)(...))QQmlExpression::qt_metacall +40 (int (*)(...))QQmlExpression::~QQmlExpression +48 (int (*)(...))QQmlExpression::~QQmlExpression +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlExpression + size=16 align=8 + base size=16 base align=8 +QQmlExpression (0x0x7f22bda812d8) 0 + vptr=((& QQmlExpression::_ZTV14QQmlExpression) + 16) + QObject (0x0x7f22b5f31ba0) 0 + primary-for QQmlExpression (0x0x7f22bda812d8) + +Vtable for QQmlTypesExtensionInterface +QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QQmlTypesExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlTypesExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlTypesExtensionInterface (0x0x7f22b5f7e9c0) 0 nearly-empty + vptr=((& QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface) + 16) + +Vtable for QQmlExtensionInterface +QQmlExtensionInterface::_ZTV22QQmlExtensionInterface: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QQmlExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlExtensionInterface (0x0x7f22bda81340) 0 nearly-empty + vptr=((& QQmlExtensionInterface::_ZTV22QQmlExtensionInterface) + 16) + QQmlTypesExtensionInterface (0x0x7f22b5f7ea20) 0 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f22bda81340) + +Class QQmlExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExtensionPlugin::QPrivateSignal (0x0x7f22b5fca660) 0 empty + +Vtable for QQmlExtensionPlugin +QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +16 (int (*)(...))QQmlExtensionPlugin::metaObject +24 (int (*)(...))QQmlExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlExtensionPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQmlExtensionPlugin::initializeEngine +128 (int (*)(...))-16 +136 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +144 0 +152 0 +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QQmlExtensionPlugin::_ZThn16_N19QQmlExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlExtensionPlugin (0x0x7f22c10e87e0) 0 + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 16) + QObject (0x0x7f22b5fca0c0) 0 + primary-for QQmlExtensionPlugin (0x0x7f22c10e87e0) + QQmlExtensionInterface (0x0x7f22bda813a8) 16 nearly-empty + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 144) + QQmlTypesExtensionInterface (0x0x7f22b5fca600) 16 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f22bda813a8) + +Class QQmlFile + size=8 align=8 + base size=8 base align=8 +QQmlFile (0x0x7f22b5fe42a0) 0 + +Class QQmlFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlFileSelector::QPrivateSignal (0x0x7f22b5fe4b40) 0 empty + +Vtable for QQmlFileSelector +QQmlFileSelector::_ZTV16QQmlFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlFileSelector) +16 (int (*)(...))QQmlFileSelector::metaObject +24 (int (*)(...))QQmlFileSelector::qt_metacast +32 (int (*)(...))QQmlFileSelector::qt_metacall +40 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +48 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlFileSelector + size=16 align=8 + base size=16 base align=8 +QQmlFileSelector (0x0x7f22bda81478) 0 + vptr=((& QQmlFileSelector::_ZTV16QQmlFileSelector) + 16) + QObject (0x0x7f22b5fe4360) 0 + primary-for QQmlFileSelector (0x0x7f22bda81478) + +Vtable for QQmlIncubator +QQmlIncubator::_ZTV13QQmlIncubator: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlIncubator) +16 (int (*)(...))QQmlIncubator::~QQmlIncubator +24 (int (*)(...))QQmlIncubator::~QQmlIncubator +32 (int (*)(...))QQmlIncubator::statusChanged +40 (int (*)(...))QQmlIncubator::setInitialState + +Class QQmlIncubator + size=16 align=8 + base size=16 base align=8 +QQmlIncubator (0x0x7f22b5fe4f00) 0 + vptr=((& QQmlIncubator::_ZTV13QQmlIncubator) + 16) + +Vtable for QQmlIncubationController +QQmlIncubationController::_ZTV24QQmlIncubationController: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQmlIncubationController) +16 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +24 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +32 (int (*)(...))QQmlIncubationController::incubatingObjectCountChanged + +Class QQmlIncubationController + size=16 align=8 + base size=16 base align=8 +QQmlIncubationController (0x0x7f22b6010120) 0 + vptr=((& QQmlIncubationController::_ZTV24QQmlIncubationController) + 16) + +Class QQmlInfo + size=16 align=8 + base size=16 base align=8 +QQmlInfo (0x0x7f22bda814e0) 0 + QDebug (0x0x7f22b6010180) 0 + +Vtable for QQmlNetworkAccessManagerFactory +QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI31QQmlNetworkAccessManagerFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlNetworkAccessManagerFactory + size=8 align=8 + base size=8 base align=8 +QQmlNetworkAccessManagerFactory (0x0x7f22b5a0c8a0) 0 nearly-empty + vptr=((& QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory) + 16) + +Class QQmlProperty + size=8 align=8 + base size=8 base align=8 +QQmlProperty (0x0x7f22b5a0c960) 0 + +Class QQmlPropertyMap::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlPropertyMap::QPrivateSignal (0x0x7f22b9665f00) 0 empty + +Vtable for QQmlPropertyMap +QQmlPropertyMap::_ZTV15QQmlPropertyMap: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQmlPropertyMap) +16 (int (*)(...))QQmlPropertyMap::metaObject +24 (int (*)(...))QQmlPropertyMap::qt_metacast +32 (int (*)(...))QQmlPropertyMap::qt_metacall +40 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +48 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlPropertyMap::updateValue + +Class QQmlPropertyMap + size=16 align=8 + base size=16 base align=8 +QQmlPropertyMap (0x0x7f22b973db60) 0 + vptr=((& QQmlPropertyMap::_ZTV15QQmlPropertyMap) + 16) + QObject (0x0x7f22b9665ea0) 0 + primary-for QQmlPropertyMap (0x0x7f22b973db60) + +Class QQuickTransform::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTransform::QPrivateSignal (0x0x7f22b91461e0) 0 empty + +Vtable for QQuickTransform +QQuickTransform::_ZTV15QQuickTransform: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQuickTransform) +16 (int (*)(...))QQuickTransform::metaObject +24 (int (*)(...))QQuickTransform::qt_metacast +32 (int (*)(...))QQuickTransform::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QQuickTransform + size=16 align=8 + base size=16 base align=8 +QQuickTransform (0x0x7f22b973dbc8) 0 + vptr=((& QQuickTransform::_ZTV15QQuickTransform) + 16) + QObject (0x0x7f22b9146180) 0 + primary-for QQuickTransform (0x0x7f22b973dbc8) + +Class QQuickItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItem::QPrivateSignal (0x0x7f22b9146480) 0 empty + +Class QQuickItem::ItemChangeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::ItemChangeData (0x0x7f22b91464e0) 0 + +Class QQuickItem::UpdatePaintNodeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::UpdatePaintNodeData (0x0x7f22b9146540) 0 + +Vtable for QQuickItem +QQuickItem::_ZTV10QQuickItem: 55 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickItem) +16 (int (*)(...))QQuickItem::metaObject +24 (int (*)(...))QQuickItem::qt_metacast +32 (int (*)(...))QQuickItem::qt_metacall +40 (int (*)(...))QQuickItem::~QQuickItem +48 (int (*)(...))QQuickItem::~QQuickItem +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickItem::isTextureProvider +152 (int (*)(...))QQuickItem::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickItem::geometryChanged +368 (int (*)(...))QQuickItem::updatePaintNode +376 (int (*)(...))QQuickItem::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))-16 +400 (int (*)(...))(& _ZTI10QQuickItem) +408 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD1Ev +416 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD0Ev +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickItem + size=32 align=8 + base size=32 base align=8 +QQuickItem (0x0x7f22c0f1aa80) 0 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 16) + QObject (0x0x7f22b91463c0) 0 + primary-for QQuickItem (0x0x7f22c0f1aa80) + QQmlParserStatus (0x0x7f22b9146420) 16 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 408) + +Class QQuickFramebufferObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickFramebufferObject::QPrivateSignal (0x0x7f22b8125ea0) 0 empty + +Vtable for QQuickFramebufferObject::Renderer +QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN23QQuickFramebufferObject8RendererE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QQuickFramebufferObject::Renderer::createFramebufferObject +48 (int (*)(...))QQuickFramebufferObject::Renderer::synchronize + +Class QQuickFramebufferObject::Renderer + size=16 align=8 + base size=16 base align=8 +QQuickFramebufferObject::Renderer (0x0x7f22b8125f00) 0 + vptr=((& QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE) + 16) + +Vtable for QQuickFramebufferObject +QQuickFramebufferObject::_ZTV23QQuickFramebufferObject: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +16 (int (*)(...))QQuickFramebufferObject::metaObject +24 (int (*)(...))QQuickFramebufferObject::qt_metacast +32 (int (*)(...))QQuickFramebufferObject::qt_metacall +40 0 +48 0 +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickFramebufferObject::isTextureProvider +152 (int (*)(...))QQuickFramebufferObject::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickFramebufferObject::geometryChanged +368 (int (*)(...))QQuickFramebufferObject::updatePaintNode +376 (int (*)(...))QQuickFramebufferObject::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))-16 +408 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +416 0 +424 0 +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickFramebufferObject + size=32 align=8 + base size=32 base align=8 +QQuickFramebufferObject (0x0x7f22b973dd00) 0 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 16) + QQuickItem (0x0x7f22c0ff9d20) 0 + primary-for QQuickFramebufferObject (0x0x7f22b973dd00) + QObject (0x0x7f22b8125de0) 0 + primary-for QQuickItem (0x0x7f22c0ff9d20) + QQmlParserStatus (0x0x7f22b8125e40) 16 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 416) + +Class QQuickTextureFactory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextureFactory::QPrivateSignal (0x0x7f22b7bc1180) 0 empty + +Vtable for QQuickTextureFactory +QQuickTextureFactory::_ZTV20QQuickTextureFactory: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickTextureFactory) +16 (int (*)(...))QQuickTextureFactory::metaObject +24 (int (*)(...))QQuickTextureFactory::qt_metacast +32 (int (*)(...))QQuickTextureFactory::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))QQuickTextureFactory::image + +Class QQuickTextureFactory + size=16 align=8 + base size=16 base align=8 +QQuickTextureFactory (0x0x7f22b973dd68) 0 + vptr=((& QQuickTextureFactory::_ZTV20QQuickTextureFactory) + 16) + QObject (0x0x7f22b7bc1120) 0 + primary-for QQuickTextureFactory (0x0x7f22b973dd68) + +Class QQuickImageResponse::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickImageResponse::QPrivateSignal (0x0x7f22b7bc1300) 0 empty + +Vtable for QQuickImageResponse +QQuickImageResponse::_ZTV19QQuickImageResponse: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageResponse) +16 (int (*)(...))QQuickImageResponse::metaObject +24 (int (*)(...))QQuickImageResponse::qt_metacast +32 (int (*)(...))QQuickImageResponse::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQuickImageResponse::errorString +128 (int (*)(...))QQuickImageResponse::cancel + +Class QQuickImageResponse + size=16 align=8 + base size=16 base align=8 +QQuickImageResponse (0x0x7f22b973ddd0) 0 + vptr=((& QQuickImageResponse::_ZTV19QQuickImageResponse) + 16) + QObject (0x0x7f22b7bc12a0) 0 + primary-for QQuickImageResponse (0x0x7f22b973ddd0) + +Vtable for QQuickImageProvider +QQuickImageProvider::_ZTV19QQuickImageProvider: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageProvider) +16 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +24 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +32 (int (*)(...))QQuickImageProvider::imageType +40 (int (*)(...))QQuickImageProvider::flags +48 (int (*)(...))QQuickImageProvider::requestImage +56 (int (*)(...))QQuickImageProvider::requestPixmap +64 (int (*)(...))QQuickImageProvider::requestTexture + +Class QQuickImageProvider + size=16 align=8 + base size=16 base align=8 +QQuickImageProvider (0x0x7f22b973de38) 0 + vptr=((& QQuickImageProvider::_ZTV19QQuickImageProvider) + 16) + QQmlImageProviderBase (0x0x7f22b7bc14e0) 0 nearly-empty + primary-for QQuickImageProvider (0x0x7f22b973de38) + +Vtable for QQuickAsyncImageProvider +QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQuickAsyncImageProvider) +16 0 +24 0 +32 (int (*)(...))QQuickImageProvider::imageType +40 (int (*)(...))QQuickImageProvider::flags +48 (int (*)(...))QQuickImageProvider::requestImage +56 (int (*)(...))QQuickImageProvider::requestPixmap +64 (int (*)(...))QQuickImageProvider::requestTexture +72 (int (*)(...))__cxa_pure_virtual + +Class QQuickAsyncImageProvider + size=24 align=8 + base size=24 base align=8 +QQuickAsyncImageProvider (0x0x7f22b973dea0) 0 + vptr=((& QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider) + 16) + QQuickImageProvider (0x0x7f22b973df08) 0 + primary-for QQuickAsyncImageProvider (0x0x7f22b973dea0) + QQmlImageProviderBase (0x0x7f22b7bc1720) 0 nearly-empty + primary-for QQuickImageProvider (0x0x7f22b973df08) + +Class QQuickItemGrabResult::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItemGrabResult::QPrivateSignal (0x0x7f22b7bc17e0) 0 empty + +Vtable for QQuickItemGrabResult +QQuickItemGrabResult::_ZTV20QQuickItemGrabResult: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickItemGrabResult) +16 (int (*)(...))QQuickItemGrabResult::metaObject +24 (int (*)(...))QQuickItemGrabResult::qt_metacast +32 (int (*)(...))QQuickItemGrabResult::qt_metacall +40 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +48 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +56 (int (*)(...))QQuickItemGrabResult::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickItemGrabResult + size=16 align=8 + base size=16 base align=8 +QQuickItemGrabResult (0x0x7f22b973df70) 0 + vptr=((& QQuickItemGrabResult::_ZTV20QQuickItemGrabResult) + 16) + QObject (0x0x7f22b7bc1780) 0 + primary-for QQuickItemGrabResult (0x0x7f22b973df70) + +Class QQuickPaintedItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickPaintedItem::QPrivateSignal (0x0x7f22b7bc1a80) 0 empty + +Vtable for QQuickPaintedItem +QQuickPaintedItem::_ZTV17QQuickPaintedItem: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QQuickPaintedItem) +16 (int (*)(...))QQuickPaintedItem::metaObject +24 (int (*)(...))QQuickPaintedItem::qt_metacast +32 (int (*)(...))QQuickPaintedItem::qt_metacall +40 0 +48 0 +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickPaintedItem::isTextureProvider +152 (int (*)(...))QQuickPaintedItem::textureProvider +160 (int (*)(...))QQuickPaintedItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickItem::geometryChanged +368 (int (*)(...))QQuickPaintedItem::updatePaintNode +376 (int (*)(...))QQuickPaintedItem::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))-16 +408 (int (*)(...))(& _ZTI17QQuickPaintedItem) +416 0 +424 0 +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickPaintedItem + size=32 align=8 + base size=32 base align=8 +QQuickPaintedItem (0x0x7f22b79fd000) 0 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 16) + QQuickItem (0x0x7f22c102d3f0) 0 + primary-for QQuickPaintedItem (0x0x7f22b79fd000) + QObject (0x0x7f22b7bc19c0) 0 + primary-for QQuickItem (0x0x7f22c102d3f0) + QQmlParserStatus (0x0x7f22b7bc1a20) 16 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 416) + +Class QQuickRenderControl::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickRenderControl::QPrivateSignal (0x0x7f22b7a2e540) 0 empty + +Vtable for QQuickRenderControl +QQuickRenderControl::_ZTV19QQuickRenderControl: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickRenderControl) +16 (int (*)(...))QQuickRenderControl::metaObject +24 (int (*)(...))QQuickRenderControl::qt_metacast +32 (int (*)(...))QQuickRenderControl::qt_metacall +40 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +48 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickRenderControl::renderWindow + +Class QQuickRenderControl + size=16 align=8 + base size=16 base align=8 +QQuickRenderControl (0x0x7f22b79fd1a0) 0 + vptr=((& QQuickRenderControl::_ZTV19QQuickRenderControl) + 16) + QObject (0x0x7f22b7a2e4e0) 0 + primary-for QQuickRenderControl (0x0x7f22b79fd1a0) + +Class QQuickTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextDocument::QPrivateSignal (0x0x7f22b7a2e7e0) 0 empty + +Vtable for QQuickTextDocument +QQuickTextDocument::_ZTV18QQuickTextDocument: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QQuickTextDocument) +16 (int (*)(...))QQuickTextDocument::metaObject +24 (int (*)(...))QQuickTextDocument::qt_metacast +32 (int (*)(...))QQuickTextDocument::qt_metacall +40 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +48 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickTextDocument + size=16 align=8 + base size=16 base align=8 +QQuickTextDocument (0x0x7f22b79fd208) 0 + vptr=((& QQuickTextDocument::_ZTV18QQuickTextDocument) + 16) + QObject (0x0x7f22b7a2e780) 0 + primary-for QQuickTextDocument (0x0x7f22b79fd208) + +Class QSGGeometry::Attribute + size=16 align=4 + base size=16 base align=4 +QSGGeometry::Attribute (0x0x7f22b7a2ee40) 0 + +Class QSGGeometry::AttributeSet + size=16 align=8 + base size=16 base align=8 +QSGGeometry::AttributeSet (0x0x7f22b7a2eea0) 0 + +Class QSGGeometry::Point2D + size=8 align=4 + base size=8 base align=4 +QSGGeometry::Point2D (0x0x7f22b7a2ef00) 0 + +Class QSGGeometry::TexturedPoint2D + size=16 align=4 + base size=16 base align=4 +QSGGeometry::TexturedPoint2D (0x0x7f22b7a2ef60) 0 + +Class QSGGeometry::ColoredPoint2D + size=12 align=4 + base size=12 base align=4 +QSGGeometry::ColoredPoint2D (0x0x7f22b691d000) 0 + +Vtable for QSGGeometry +QSGGeometry::_ZTV11QSGGeometry: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGGeometry) +16 (int (*)(...))QSGGeometry::~QSGGeometry +24 (int (*)(...))QSGGeometry::~QSGGeometry + +Class QSGGeometry + size=128 align=8 + base size=128 base align=8 +QSGGeometry (0x0x7f22b7a2ede0) 0 + vptr=((& QSGGeometry::_ZTV11QSGGeometry) + 16) + +Vtable for QSGNode +QSGNode::_ZTV7QSGNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QSGNode) +16 (int (*)(...))QSGNode::~QSGNode +24 (int (*)(...))QSGNode::~QSGNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGNode + size=80 align=8 + base size=80 base align=8 +QSGNode (0x0x7f22bb8cf000) 0 + vptr=((& QSGNode::_ZTV7QSGNode) + 16) + +Vtable for QSGBasicGeometryNode +QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGBasicGeometryNode) +16 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +24 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGBasicGeometryNode + size=112 align=8 + base size=112 base align=8 +QSGBasicGeometryNode (0x0x7f22b79fd8f0) 0 + vptr=((& QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode) + 16) + QSGNode (0x0x7f22bb8cf960) 0 + primary-for QSGBasicGeometryNode (0x0x7f22b79fd8f0) + +Vtable for QSGGeometryNode +QSGGeometryNode::_ZTV15QSGGeometryNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSGGeometryNode) +16 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +24 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGGeometryNode + size=144 align=8 + base size=144 base align=8 +QSGGeometryNode (0x0x7f22b79fd958) 0 + vptr=((& QSGGeometryNode::_ZTV15QSGGeometryNode) + 16) + QSGBasicGeometryNode (0x0x7f22b79fd9c0) 0 + primary-for QSGGeometryNode (0x0x7f22b79fd958) + QSGNode (0x0x7f22bb8cfc00) 0 + primary-for QSGBasicGeometryNode (0x0x7f22b79fd9c0) + +Vtable for QSGClipNode +QSGClipNode::_ZTV11QSGClipNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGClipNode) +16 (int (*)(...))QSGClipNode::~QSGClipNode +24 (int (*)(...))QSGClipNode::~QSGClipNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGClipNode + size=152 align=8 + base size=152 base align=8 +QSGClipNode (0x0x7f22b79fda28) 0 + vptr=((& QSGClipNode::_ZTV11QSGClipNode) + 16) + QSGBasicGeometryNode (0x0x7f22b79fda90) 0 + primary-for QSGClipNode (0x0x7f22b79fda28) + QSGNode (0x0x7f22bb8cfde0) 0 + primary-for QSGBasicGeometryNode (0x0x7f22b79fda90) + +Vtable for QSGTransformNode +QSGTransformNode::_ZTV16QSGTransformNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGTransformNode) +16 (int (*)(...))QSGTransformNode::~QSGTransformNode +24 (int (*)(...))QSGTransformNode::~QSGTransformNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGTransformNode + size=216 align=8 + base size=216 base align=8 +QSGTransformNode (0x0x7f22b79fdaf8) 0 + vptr=((& QSGTransformNode::_ZTV16QSGTransformNode) + 16) + QSGNode (0x0x7f22bb8cff00) 0 + primary-for QSGTransformNode (0x0x7f22b79fdaf8) + +Vtable for QSGRootNode +QSGRootNode::_ZTV11QSGRootNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGRootNode) +16 (int (*)(...))QSGRootNode::~QSGRootNode +24 (int (*)(...))QSGRootNode::~QSGRootNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGRootNode + size=88 align=8 + base size=88 base align=8 +QSGRootNode (0x0x7f22b79fdb60) 0 + vptr=((& QSGRootNode::_ZTV11QSGRootNode) + 16) + QSGNode (0x0x7f22b77ff060) 0 + primary-for QSGRootNode (0x0x7f22b79fdb60) + +Vtable for QSGOpacityNode +QSGOpacityNode::_ZTV14QSGOpacityNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGOpacityNode) +16 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +24 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +32 (int (*)(...))QSGOpacityNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGOpacityNode + size=96 align=8 + base size=96 base align=8 +QSGOpacityNode (0x0x7f22b79fdc30) 0 + vptr=((& QSGOpacityNode::_ZTV14QSGOpacityNode) + 16) + QSGNode (0x0x7f22b77ff1e0) 0 + primary-for QSGOpacityNode (0x0x7f22b79fdc30) + +Vtable for QSGNodeVisitor +QSGNodeVisitor::_ZTV14QSGNodeVisitor: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGNodeVisitor) +16 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +24 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +32 (int (*)(...))QSGNodeVisitor::enterTransformNode +40 (int (*)(...))QSGNodeVisitor::leaveTransformNode +48 (int (*)(...))QSGNodeVisitor::enterClipNode +56 (int (*)(...))QSGNodeVisitor::leaveClipNode +64 (int (*)(...))QSGNodeVisitor::enterGeometryNode +72 (int (*)(...))QSGNodeVisitor::leaveGeometryNode +80 (int (*)(...))QSGNodeVisitor::enterOpacityNode +88 (int (*)(...))QSGNodeVisitor::leaveOpacityNode +96 (int (*)(...))QSGNodeVisitor::visitNode +104 (int (*)(...))QSGNodeVisitor::visitChildren + +Class QSGNodeVisitor + size=8 align=8 + base size=8 base align=8 +QSGNodeVisitor (0x0x7f22b77ff300) 0 nearly-empty + vptr=((& QSGNodeVisitor::_ZTV14QSGNodeVisitor) + 16) + +Vtable for QSGRendererInterface +QSGRendererInterface::_ZTV20QSGRendererInterface: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGRendererInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QSGRendererInterface::getResource +48 (int (*)(...))QSGRendererInterface::getResource +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRendererInterface + size=8 align=8 + base size=8 base align=8 +QSGRendererInterface (0x0x7f22b7846120) 0 nearly-empty + vptr=((& QSGRendererInterface::_ZTV20QSGRendererInterface) + 16) + +Class QQuickWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickWindow::QPrivateSignal (0x0x7f22b747d000) 0 empty + +Vtable for QQuickWindow +QQuickWindow::_ZTV12QQuickWindow: 45 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QQuickWindow) +16 (int (*)(...))QQuickWindow::metaObject +24 (int (*)(...))QQuickWindow::qt_metacast +32 (int (*)(...))QQuickWindow::qt_metacall +40 (int (*)(...))QQuickWindow::~QQuickWindow +48 (int (*)(...))QQuickWindow::~QQuickWindow +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QQuickWindow::focusInEvent +184 (int (*)(...))QQuickWindow::focusOutEvent +192 (int (*)(...))QQuickWindow::showEvent +200 (int (*)(...))QQuickWindow::hideEvent +208 (int (*)(...))QQuickWindow::keyPressEvent +216 (int (*)(...))QQuickWindow::keyReleaseEvent +224 (int (*)(...))QQuickWindow::mousePressEvent +232 (int (*)(...))QQuickWindow::mouseReleaseEvent +240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +248 (int (*)(...))QQuickWindow::mouseMoveEvent +256 (int (*)(...))QQuickWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI12QQuickWindow) +312 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD1Ev +320 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickWindow + size=40 align=8 + base size=40 base align=8 +QQuickWindow (0x0x7f22b79fde38) 0 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 16) + QWindow (0x0x7f22c0beb0e0) 0 + primary-for QQuickWindow (0x0x7f22b79fde38) + QObject (0x0x7f22b7846f00) 0 + primary-for QWindow (0x0x7f22c0beb0e0) + QSurface (0x0x7f22b7846f60) 16 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 312) + +Class QQuickView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickView::QPrivateSignal (0x0x7f22b747da20) 0 empty + +Vtable for QQuickView +QQuickView::_ZTV10QQuickView: 45 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickView) +16 (int (*)(...))QQuickView::metaObject +24 (int (*)(...))QQuickView::qt_metacast +32 (int (*)(...))QQuickView::qt_metacall +40 (int (*)(...))QQuickView::~QQuickView +48 (int (*)(...))QQuickView::~QQuickView +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QQuickView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickView::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QQuickWindow::focusInEvent +184 (int (*)(...))QQuickWindow::focusOutEvent +192 (int (*)(...))QQuickWindow::showEvent +200 (int (*)(...))QQuickWindow::hideEvent +208 (int (*)(...))QQuickView::keyPressEvent +216 (int (*)(...))QQuickView::keyReleaseEvent +224 (int (*)(...))QQuickView::mousePressEvent +232 (int (*)(...))QQuickView::mouseReleaseEvent +240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +248 (int (*)(...))QQuickView::mouseMoveEvent +256 (int (*)(...))QQuickWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI10QQuickView) +312 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD1Ev +320 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickView + size=40 align=8 + base size=40 base align=8 +QQuickView (0x0x7f22b79fdf70) 0 + vptr=((& QQuickView::_ZTV10QQuickView) + 16) + QQuickWindow (0x0x7f22b74b5000) 0 + primary-for QQuickView (0x0x7f22b79fdf70) + QWindow (0x0x7f22c0c04310) 0 + primary-for QQuickWindow (0x0x7f22b74b5000) + QObject (0x0x7f22b747d960) 0 + primary-for QWindow (0x0x7f22c0c04310) + QSurface (0x0x7f22b747d9c0) 16 + vptr=((& QQuickView::_ZTV10QQuickView) + 312) + +Class QSGAbstractRenderer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGAbstractRenderer::QPrivateSignal (0x0x7f22b747dde0) 0 empty + +Vtable for QSGAbstractRenderer +QSGAbstractRenderer::_ZTV19QSGAbstractRenderer: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QSGAbstractRenderer) +16 (int (*)(...))QSGAbstractRenderer::metaObject +24 (int (*)(...))QSGAbstractRenderer::qt_metacast +32 (int (*)(...))QSGAbstractRenderer::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QSGAbstractRenderer + size=16 align=8 + base size=16 base align=8 +QSGAbstractRenderer (0x0x7f22b74b5068) 0 + vptr=((& QSGAbstractRenderer::_ZTV19QSGAbstractRenderer) + 16) + QObject (0x0x7f22b747dd80) 0 + primary-for QSGAbstractRenderer (0x0x7f22b74b5068) + +Class QSGEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGEngine::QPrivateSignal (0x0x7f22b74de8a0) 0 empty + +Vtable for QSGEngine +QSGEngine::_ZTV9QSGEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSGEngine) +16 (int (*)(...))QSGEngine::metaObject +24 (int (*)(...))QSGEngine::qt_metacast +32 (int (*)(...))QSGEngine::qt_metacall +40 (int (*)(...))QSGEngine::~QSGEngine +48 (int (*)(...))QSGEngine::~QSGEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSGEngine + size=16 align=8 + base size=16 base align=8 +QSGEngine (0x0x7f22b74b51a0) 0 + vptr=((& QSGEngine::_ZTV9QSGEngine) + 16) + QObject (0x0x7f22b74de840) 0 + primary-for QSGEngine (0x0x7f22b74b51a0) + +Class QSGMaterialShader::RenderState + size=16 align=8 + base size=16 base align=8 +QSGMaterialShader::RenderState (0x0x7f22b74def60) 0 + +Vtable for QSGMaterialShader +QSGMaterialShader::_ZTV17QSGMaterialShader: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGMaterialShader) +16 0 +24 0 +32 (int (*)(...))QSGMaterialShader::activate +40 (int (*)(...))QSGMaterialShader::deactivate +48 (int (*)(...))QSGMaterialShader::updateState +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QSGMaterialShader::compile +72 (int (*)(...))QSGMaterialShader::initialize +80 (int (*)(...))QSGMaterialShader::vertexShader +88 (int (*)(...))QSGMaterialShader::fragmentShader + +Class QSGMaterialShader + size=32 align=8 + base size=32 base align=8 +QSGMaterialShader (0x0x7f22b74def00) 0 + vptr=((& QSGMaterialShader::_ZTV17QSGMaterialShader) + 16) + +Class QSGMaterialType + size=1 align=1 + base size=0 base align=1 +QSGMaterialType (0x0x7f22b7517540) 0 empty + +Vtable for QSGMaterial +QSGMaterial::_ZTV11QSGMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGMaterial) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QSGMaterial::compare + +Class QSGMaterial + size=24 align=8 + base size=24 base align=8 +QSGMaterial (0x0x7f22b75175a0) 0 + vptr=((& QSGMaterial::_ZTV11QSGMaterial) + 16) + +Vtable for QSGFlatColorMaterial +QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGFlatColorMaterial) +16 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +24 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +32 (int (*)(...))QSGFlatColorMaterial::type +40 (int (*)(...))QSGFlatColorMaterial::createShader +48 (int (*)(...))QSGFlatColorMaterial::compare + +Class QSGFlatColorMaterial + size=40 align=8 + base size=40 base align=8 +QSGFlatColorMaterial (0x0x7f22b74b54e0) 0 + vptr=((& QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial) + 16) + QSGMaterial (0x0x7f22b75582a0) 0 + primary-for QSGFlatColorMaterial (0x0x7f22b74b54e0) + +Class QSGTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTexture::QPrivateSignal (0x0x7f22b75583c0) 0 empty + +Vtable for QSGTexture +QSGTexture::_ZTV10QSGTexture: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSGTexture) +16 (int (*)(...))QSGTexture::metaObject +24 (int (*)(...))QSGTexture::qt_metacast +32 (int (*)(...))QSGTexture::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QSGTexture::normalizedTextureSubRect +152 (int (*)(...))QSGTexture::isAtlasTexture +160 (int (*)(...))QSGTexture::removedFromAtlas +168 (int (*)(...))__cxa_pure_virtual + +Class QSGTexture + size=16 align=8 + base size=16 base align=8 +QSGTexture (0x0x7f22b74b5548) 0 + vptr=((& QSGTexture::_ZTV10QSGTexture) + 16) + QObject (0x0x7f22b7558360) 0 + primary-for QSGTexture (0x0x7f22b74b5548) + +Class QSGDynamicTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGDynamicTexture::QPrivateSignal (0x0x7f22b7558660) 0 empty + +Vtable for QSGDynamicTexture +QSGDynamicTexture::_ZTV17QSGDynamicTexture: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGDynamicTexture) +16 (int (*)(...))QSGDynamicTexture::metaObject +24 (int (*)(...))QSGDynamicTexture::qt_metacast +32 (int (*)(...))QSGDynamicTexture::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QSGTexture::normalizedTextureSubRect +152 (int (*)(...))QSGTexture::isAtlasTexture +160 (int (*)(...))QSGTexture::removedFromAtlas +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QSGDynamicTexture + size=16 align=8 + base size=16 base align=8 +QSGDynamicTexture (0x0x7f22b74b55b0) 0 + vptr=((& QSGDynamicTexture::_ZTV17QSGDynamicTexture) + 16) + QSGTexture (0x0x7f22b74b5618) 0 + primary-for QSGDynamicTexture (0x0x7f22b74b55b0) + QObject (0x0x7f22b7558600) 0 + primary-for QSGTexture (0x0x7f22b74b5618) + +Vtable for QSGImageNode +QSGImageNode::_ZTV12QSGImageNode: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QSGImageNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QSGImageNode + size=144 align=8 + base size=144 base align=8 +QSGImageNode (0x0x7f22b74b5680) 0 + vptr=((& QSGImageNode::_ZTV12QSGImageNode) + 16) + QSGGeometryNode (0x0x7f22b74b56e8) 0 + primary-for QSGImageNode (0x0x7f22b74b5680) + QSGBasicGeometryNode (0x0x7f22b74b5750) 0 + primary-for QSGGeometryNode (0x0x7f22b74b56e8) + QSGNode (0x0x7f22b7558780) 0 + primary-for QSGBasicGeometryNode (0x0x7f22b74b5750) + +Vtable for QSGNinePatchNode +QSGNinePatchNode::_ZTV16QSGNinePatchNode: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGNinePatchNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual + +Class QSGNinePatchNode + size=144 align=8 + base size=144 base align=8 +QSGNinePatchNode (0x0x7f22b74b5888) 0 + vptr=((& QSGNinePatchNode::_ZTV16QSGNinePatchNode) + 16) + QSGGeometryNode (0x0x7f22b74b58f0) 0 + primary-for QSGNinePatchNode (0x0x7f22b74b5888) + QSGBasicGeometryNode (0x0x7f22b74b5958) 0 + primary-for QSGGeometryNode (0x0x7f22b74b58f0) + QSGNode (0x0x7f22b7558f60) 0 + primary-for QSGBasicGeometryNode (0x0x7f22b74b5958) + +Vtable for QSGRectangleNode +QSGRectangleNode::_ZTV16QSGRectangleNode: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGRectangleNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRectangleNode + size=144 align=8 + base size=144 base align=8 +QSGRectangleNode (0x0x7f22b74b59c0) 0 + vptr=((& QSGRectangleNode::_ZTV16QSGRectangleNode) + 16) + QSGGeometryNode (0x0x7f22b74b5a28) 0 + primary-for QSGRectangleNode (0x0x7f22b74b59c0) + QSGBasicGeometryNode (0x0x7f22b74b5a90) 0 + primary-for QSGGeometryNode (0x0x7f22b74b5a28) + QSGNode (0x0x7f22b7596000) 0 + primary-for QSGBasicGeometryNode (0x0x7f22b74b5a90) + +Vtable for QSGRenderNode::RenderState +QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QSGRenderNode11RenderStateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))QSGRenderNode::RenderState::get + +Class QSGRenderNode::RenderState + size=8 align=8 + base size=8 base align=8 +QSGRenderNode::RenderState (0x0x7f22b7596120) 0 nearly-empty + vptr=((& QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE) + 16) + +Vtable for QSGRenderNode +QSGRenderNode::_ZTV13QSGRenderNode: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSGRenderNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))QSGRenderNode::changedStates +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QSGRenderNode::releaseResources +72 (int (*)(...))QSGRenderNode::flags +80 (int (*)(...))QSGRenderNode::rect + +Class QSGRenderNode + size=88 align=8 + base size=88 base align=8 +QSGRenderNode (0x0x7f22b74b5af8) 0 + vptr=((& QSGRenderNode::_ZTV13QSGRenderNode) + 16) + QSGNode (0x0x7f22b75960c0) 0 + primary-for QSGRenderNode (0x0x7f22b74b5af8) + +Vtable for QSGSimpleRectNode +QSGSimpleRectNode::_ZTV17QSGSimpleRectNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGSimpleRectNode) +16 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +24 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleRectNode + size=320 align=8 + base size=320 base align=8 +QSGSimpleRectNode (0x0x7f22b74b5f70) 0 + vptr=((& QSGSimpleRectNode::_ZTV17QSGSimpleRectNode) + 16) + QSGGeometryNode (0x0x7f22b75f6000) 0 + primary-for QSGSimpleRectNode (0x0x7f22b74b5f70) + QSGBasicGeometryNode (0x0x7f22b75f6068) 0 + primary-for QSGGeometryNode (0x0x7f22b75f6000) + QSGNode (0x0x7f22b75d3840) 0 + primary-for QSGBasicGeometryNode (0x0x7f22b75f6068) + +Vtable for QSGOpaqueTextureMaterial +QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QSGOpaqueTextureMaterial) +16 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +24 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +32 (int (*)(...))QSGOpaqueTextureMaterial::type +40 (int (*)(...))QSGOpaqueTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGOpaqueTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGOpaqueTextureMaterial (0x0x7f22b75f60d0) 0 + vptr=((& QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial) + 16) + QSGMaterial (0x0x7f22b75d3900) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7f22b75f60d0) + +Vtable for QSGTextureMaterial +QSGTextureMaterial::_ZTV18QSGTextureMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureMaterial) +16 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +24 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +32 (int (*)(...))QSGTextureMaterial::type +40 (int (*)(...))QSGTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGTextureMaterial (0x0x7f22b75f6138) 0 + vptr=((& QSGTextureMaterial::_ZTV18QSGTextureMaterial) + 16) + QSGOpaqueTextureMaterial (0x0x7f22b75f61a0) 0 + primary-for QSGTextureMaterial (0x0x7f22b75f6138) + QSGMaterial (0x0x7f22b75d3d80) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7f22b75f61a0) + +Vtable for QSGSimpleTextureNode +QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGSimpleTextureNode) +16 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +24 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleTextureNode + size=384 align=8 + base size=384 base align=8 +QSGSimpleTextureNode (0x0x7f22b75f6208) 0 + vptr=((& QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode) + 16) + QSGGeometryNode (0x0x7f22b75f6270) 0 + primary-for QSGSimpleTextureNode (0x0x7f22b75f6208) + QSGBasicGeometryNode (0x0x7f22b75f62d8) 0 + primary-for QSGGeometryNode (0x0x7f22b75f6270) + QSGNode (0x0x7f22b75d3de0) 0 + primary-for QSGBasicGeometryNode (0x0x7f22b75f62d8) + +Class QSGTextureProvider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTextureProvider::QPrivateSignal (0x0x7f22b7614780) 0 empty + +Vtable for QSGTextureProvider +QSGTextureProvider::_ZTV18QSGTextureProvider: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureProvider) +16 (int (*)(...))QSGTextureProvider::metaObject +24 (int (*)(...))QSGTextureProvider::qt_metacast +32 (int (*)(...))QSGTextureProvider::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSGTextureProvider + size=16 align=8 + base size=16 base align=8 +QSGTextureProvider (0x0x7f22b75f6478) 0 + vptr=((& QSGTextureProvider::_ZTV18QSGTextureProvider) + 16) + QObject (0x0x7f22b7614720) 0 + primary-for QSGTextureProvider (0x0x7f22b75f6478) + +Vtable for QSGVertexColorMaterial +QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QSGVertexColorMaterial) +16 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +24 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +32 (int (*)(...))QSGVertexColorMaterial::type +40 (int (*)(...))QSGVertexColorMaterial::createShader +48 (int (*)(...))QSGVertexColorMaterial::compare + +Class QSGVertexColorMaterial + size=24 align=8 + base size=24 base align=8 +QSGVertexColorMaterial (0x0x7f22b75f64e0) 0 + vptr=((& QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial) + 16) + QSGMaterial (0x0x7f22b76148a0) 0 + primary-for QSGVertexColorMaterial (0x0x7f22b75f64e0) + +Class QQuickStyle + size=1 align=1 + base size=0 base align=1 +QQuickStyle (0x0x7f22b7614900) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b7250c00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b7250f60) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b7270180) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b72704e0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b72706c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b7270a20) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b7270c00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b7270f60) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b729c180) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b729c4e0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b729c6c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b729ca20) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b729cc00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b729cf60) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b72c3180) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b72c34e0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b72da9c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b72dad20) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b72daea0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b72f7240) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b72f73c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b72f7720) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b72f78a0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b72f7c00) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b72f7d80) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b731a120) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b731a2a0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b731a600) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b731a780) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b731aae0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f22b731ac60) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f22b73f3000) 0 empty + diff --git a/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.14.0.linux-gcc-amd64.txt b/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.14.0.linux-gcc-amd64.txt new file mode 100644 index 00000000000..db7b454b591 --- /dev/null +++ b/tests/auto/quickcontrols2/bic/data/QtQuickControls2.5.14.0.linux-gcc-amd64.txt @@ -0,0 +1,11603 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f31cd96d000) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f31cd9b7780) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f31cd9b79c0) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f31cd9b7c00) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f31cd9b7e40) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f31cd9e3000) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f31cd9e33c0) 0 empty + +Class std::__do_is_implicitly_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_implicitly_default_constructible_impl (0x0x7f31cda214e0) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f31cd677ba0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f31cd677c60) 0 empty + +Class std::__invoke_memfun_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_ref (0x0x7f31cd6a7060) 0 empty + +Class std::__invoke_memfun_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_deref (0x0x7f31cd6a70c0) 0 empty + +Class std::__invoke_memobj_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_ref (0x0x7f31cd6a7120) 0 empty + +Class std::__invoke_memobj_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_deref (0x0x7f31cd6a7180) 0 empty + +Class std::__invoke_other + size=1 align=1 + base size=0 base align=1 +std::__invoke_other (0x0x7f31cd6a71e0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f31cd6a72a0) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f31cd6a7360) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f31cd6a7420) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f31cd6a74e0) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f31cd6a7840) 0 empty + +Class std::__swappable_details::__do_is_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_swappable_impl (0x0x7f31cd6a7ba0) 0 empty + +Class std::__swappable_details::__do_is_nothrow_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_nothrow_swappable_impl (0x0x7f31cd6a7c00) 0 empty + +Class std::__nonesuch + size=1 align=1 + base size=0 base align=1 +std::__nonesuch (0x0x7f31cd6f01e0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f31cd6f0840) 0 empty + +Class std::__nonesuch_no_braces + size=1 align=1 + base size=1 base align=1 +std::__nonesuch_no_braces (0x0x7f31cd6e9270) 0 empty + std::__nonesuch (0x0x7f31cd6f0d20) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f31cd7726c0) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f31cd772720) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f31cd7cc420) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f31cd7cc480) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f31cd6e9750) 0 empty + std::input_iterator_tag (0x0x7f31cd7cc4e0) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f31cd6e97b8) 0 empty + std::forward_iterator_tag (0x0x7f31cd6e9820) 0 empty + std::input_iterator_tag (0x0x7f31cd7cc540) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f31cd6e9888) 0 empty + std::bidirectional_iterator_tag (0x0x7f31cd6e98f0) 0 empty + std::forward_iterator_tag (0x0x7f31cd6e9958) 0 empty + std::input_iterator_tag (0x0x7f31cd7cc5a0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f31cd4800c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f31cd4801e0) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f31cd4804e0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f31cd4807e0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f31cd480900) 0 empty + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f31cd50bc00) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f31cd50bf00) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f31cd50bf60) 0 + +Class __pthread_rwlock_arch_t + size=56 align=8 + base size=56 base align=8 +__pthread_rwlock_arch_t (0x0x7f31cd553060) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f31cd5530c0) 0 + +Class __pthread_mutex_s + size=40 align=8 + base size=40 base align=8 +__pthread_mutex_s (0x0x7f31cd553120) 0 + +Class __pthread_cond_s + size=48 align=8 + base size=48 base align=8 +__pthread_cond_s (0x0x7f31cd553180) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f31cd553420) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f31cd5536c0) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f31cd553720) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f31cd6094e0) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f31cd6e9c98) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16) + std::exception (0x0x7f31cd6096c0) 0 nearly-empty + primary-for std::bad_exception (0x0x7f31cd6e9c98) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f31cd6098a0) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f31cd6e9d00) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16) + std::exception (0x0x7f31cd609c60) 0 nearly-empty + primary-for std::bad_cast (0x0x7f31cd6e9d00) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f31cd6e9d68) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16) + std::exception (0x0x7f31cd609e40) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f31cd6e9d68) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f31cd63a060) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f31cd63a600) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f31cd6e9dd0) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16) + std::exception (0x0x7f31cd63acc0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f31cd6e9dd0) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f31cd6e9e38) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16) + std::bad_alloc (0x0x7f31cd6e9ea0) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f31cd6e9e38) + std::exception (0x0x7f31cd63aea0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f31cd6e9ea0) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f31cd2740c0) 0 empty + +Class std::__allocator_traits_base + size=1 align=1 + base size=0 base align=1 +std::__allocator_traits_base (0x0x7f31cd2742a0) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f31cd2e5780) 0 empty + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f31ccf5fcc0) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f31ccf5fde0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f31ccf92000) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f31ccf926c0) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f31ccfdbe40) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f31ccc8b360) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f31cd022d00) 0 + std::__atomic_flag_base (0x0x7f31ccc8b3c0) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f31cce2b478) 0 + QAtomicInteger<int> (0x0x7f31cce2b4e0) 0 + QBasicAtomicInteger<int> (0x0x7f31ccbc0600) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f31cc819180) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f31cc45c720) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f31cc45ce40) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f31cc493138) 0 + QGenericArgument (0x0x7f31cc49c120) 0 + +Class QMetaObject::SuperData + size=8 align=8 + base size=8 base align=8 +QMetaObject::SuperData (0x0x7f31cc49c5a0) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f31cc49c540) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f31cc49ce40) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f31cc54f960) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f31cc5720c0) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f31cc61fea0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f31cc644240) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f31cc2a7540) 0 empty + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f31cc355d80) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f31cc355e40) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f31cc41df60) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f31cc04e060) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f31cc04e0c0) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f31cc04e120) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f31cc04e180) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f31cc04e2a0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f31cc04e300) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f31cc1912a0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f31cc191300) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f31cbf43360) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f31cbf434e0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f31cbcbd660) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f31cbcbda20) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f31cbcbdcc0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f31cbcbdea0) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f31cbd17ea0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f31cbd520d0) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16) + std::exception (0x0x7f31cbd17f60) 0 nearly-empty + primary-for std::logic_error (0x0x7f31cbd520d0) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f31cbd52138) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16) + std::logic_error (0x0x7f31cbd521a0) 0 + primary-for std::domain_error (0x0x7f31cbd52138) + std::exception (0x0x7f31cbd68000) 0 nearly-empty + primary-for std::logic_error (0x0x7f31cbd521a0) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f31cbd52208) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16) + std::logic_error (0x0x7f31cbd52270) 0 + primary-for std::invalid_argument (0x0x7f31cbd52208) + std::exception (0x0x7f31cbd68060) 0 nearly-empty + primary-for std::logic_error (0x0x7f31cbd52270) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f31cbd522d8) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16) + std::logic_error (0x0x7f31cbd52340) 0 + primary-for std::length_error (0x0x7f31cbd522d8) + std::exception (0x0x7f31cbd680c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f31cbd52340) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f31cbd523a8) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16) + std::logic_error (0x0x7f31cbd52410) 0 + primary-for std::out_of_range (0x0x7f31cbd523a8) + std::exception (0x0x7f31cbd68120) 0 nearly-empty + primary-for std::logic_error (0x0x7f31cbd52410) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f31cbd52478) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16) + std::exception (0x0x7f31cbd68180) 0 nearly-empty + primary-for std::runtime_error (0x0x7f31cbd52478) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f31cbd524e0) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16) + std::runtime_error (0x0x7f31cbd52548) 0 + primary-for std::range_error (0x0x7f31cbd524e0) + std::exception (0x0x7f31cbd681e0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f31cbd52548) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f31cbd525b0) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16) + std::runtime_error (0x0x7f31cbd52618) 0 + primary-for std::overflow_error (0x0x7f31cbd525b0) + std::exception (0x0x7f31cbd68240) 0 nearly-empty + primary-for std::runtime_error (0x0x7f31cbd52618) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f31cbd52680) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16) + std::runtime_error (0x0x7f31cbd526e8) 0 + primary-for std::underflow_error (0x0x7f31cbd52680) + std::exception (0x0x7f31cbd682a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f31cbd526e8) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f31cbd68420) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f31cbd68780) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f31cbdac000) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f31cbd52af8) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16) + std::runtime_error (0x0x7f31cbd52b60) 0 + primary-for std::system_error (0x0x7f31cbd52af8) + std::exception (0x0x7f31cbdacba0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f31cbd52b60) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f31cbd52dd0) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16) + std::system_error (0x0x7f31cbd52e38) 0 + primary-for std::ios_base::failure (0x0x7f31cbd52dd0) + std::runtime_error (0x0x7f31cbd52ea0) 0 + primary-for std::system_error (0x0x7f31cbd52e38) + std::exception (0x0x7f31cbe0a180) 0 nearly-empty + primary-for std::runtime_error (0x0x7f31cbd52ea0) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f31cbe0a1e0) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f31cbe0a240) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f31cbe0a2a0) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f31cbe0a120) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f31cbad8ba0) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f31cbb81d80) 0 empty + +VTT for std::basic_ostream<char> +std::basic_ostream<char>::_ZTTSo: 2 entries +0 ((& std::basic_ostream<char>::_ZTVSo) + 24) +8 ((& std::basic_ostream<char>::_ZTVSo) + 64) + +VTT for std::basic_ostream<wchar_t> +std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64) + +VTT for std::basic_istream<char> +std::basic_istream<char>::_ZTTSi: 2 entries +0 ((& std::basic_istream<char>::_ZTVSi) + 24) +8 ((& std::basic_istream<char>::_ZTVSi) + 64) + +VTT for std::basic_istream<wchar_t> +std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64) + +Construction vtable for std::basic_istream<char> (0x0x7f31cb7505b0 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd0_Si: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream<char> (0x0x7f31cb750680 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd16_So: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::basic_iostream<char> +std::basic_iostream<char>::_ZTTSd: 7 entries +0 ((& std::basic_iostream<char>::_ZTVSd) + 24) +8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24) +16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64) +24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24) +32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64) +40 ((& std::basic_iostream<char>::_ZTVSd) + 104) +48 ((& std::basic_iostream<char>::_ZTVSd) + 64) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f31cb792340 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f31cb792410 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7 entries +0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24) +16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64) +24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24) +32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64) +40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104) +48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f31cb7ba720) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f31cb7ba780) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f31cb4e7b40) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f31cb58d9c0) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f31cb58de40) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f31cb26df00) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f31cb323ea0) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f31cb323d80) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f31cb1e2d20) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f31caf7c900) 0 + +Class QtPrivate::ArgBase + size=1 align=1 + base size=1 base align=1 +QtPrivate::ArgBase (0x0x7f31cad02720) 0 + +Class QtPrivate::QStringViewArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QStringViewArg (0x0x7f31cb022270) 0 + QtPrivate::ArgBase (0x0x7f31cad02780) 0 + +Class QtPrivate::QLatin1StringArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QLatin1StringArg (0x0x7f31cb0222d8) 0 + QtPrivate::ArgBase (0x0x7f31cad02960) 0 + +Class std::__erased_type + size=1 align=1 + base size=0 base align=1 +std::__erased_type (0x0x7f31cadd68a0) 0 empty + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f31cadd6900) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f31cadd6a80) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f31cadd6b40) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f31cb022680) 0 + std::__uses_alloc_base (0x0x7f31cadd6ae0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f31cab34ea0) 0 empty + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f31cab9b8f0) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16) + std::exception (0x0x7f31cabac7e0) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f31cab9b8f0) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f31cabac8a0) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f31cabac900) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f31cabacc00) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f31ca9e20c0) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f31ca9e2180) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f31cdae28a0) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f31caa20478) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f31cdb08000) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f31caa205b0) 0 + std::_Bit_iterator_base (0x0x7f31caa20618) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f31cdb08660) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f31caa20680) 0 + std::_Bit_iterator_base (0x0x7f31caa206e8) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f31cdb08e40) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f31ca3569c0) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f31ca42c780) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f31ca42c7e0) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f31ca36e208) 0 empty + QListData::NotIndirectLayout (0x0x7f31ca42c840) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f31ca380930) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f31ca42c8a0) 0 empty + QListData::NotIndirectLayout (0x0x7f31ca42c900) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f31ca36e270) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f31ca42c960) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f31ca42c9c0) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f31ca42c720) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f31ca121b40) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f31ca2190c0) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f31ca219060) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f31ca204f08) 0 + QList<QString> (0x0x7f31ca204f70) 0 + QListSpecialMethods<QString> (0x0x7f31ca219300) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f31c9efd240) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f31c9f80480) 0 + +Class std::_Rb_tree_header + size=40 align=8 + base size=40 base align=8 +std::_Rb_tree_header (0x0x7f31c9f807e0) 0 + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f31c9dccde0) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f31c9de7180) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f31c9de76c0) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f31c9de7c00) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f31c9e3ade0) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f31c9a734e0) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f31c9b0a360) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f31c9b60a20) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f31c9bb6f60) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f31c967f540) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f31c97ae000) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f31c97ae060) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f31c97ae240) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f31c97ae1e0) 0 + vptr=((& QObject::_ZTV7QObject) + 16) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f31c9480060) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f31c94801e0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f31c9480a80) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f31c947b0d0) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16) + QObject (0x0x7f31c9480a20) 0 + primary-for QAbstractAnimation (0x0x7f31c947b0d0) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f31c9480e40) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f31c947b138) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16) + QObject (0x0x7f31c9480de0) 0 + primary-for QAnimationDriver (0x0x7f31c947b138) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f31c94c50c0) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f31c947b1a0) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16) + QObject (0x0x7f31c94c5060) 0 + primary-for QEventLoop (0x0x7f31c947b1a0) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f31c94c5960) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f31c94c5a20) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f31c94c5a80) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f31c947b2d8) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16) + QObject (0x0x7f31c94c59c0) 0 + primary-for QAbstractEventDispatcher (0x0x7f31c947b2d8) + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f31c9537a80) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f31c9564720) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f31c92530c0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f31c9253060) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f31c9253360) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f31c9366a80) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f31c9366b40) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f31c9366ae0) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f31c9366ba0) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f31c9366a20) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f31c9057e40) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f31c91264e0) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f31c9126480) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f31c9126600) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f31c91265a0) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f31c91ef780) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f31c8e633c0) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f31c8f311e0) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f31c8f2f478) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16) + QObject (0x0x7f31c8f31180) 0 + primary-for QAbstractItemModel (0x0x7f31c8f2f478) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f31c8ff95a0) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f31c8f2fa90) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16) + QAbstractItemModel (0x0x7f31c8f2faf8) 0 + primary-for QAbstractTableModel (0x0x7f31c8f2fa90) + QObject (0x0x7f31c8ff9540) 0 + primary-for QAbstractItemModel (0x0x7f31c8f2faf8) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f31c8ff9720) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f31c8f2fb60) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16) + QAbstractItemModel (0x0x7f31c8f2fbc8) 0 + primary-for QAbstractListModel (0x0x7f31c8f2fb60) + QObject (0x0x7f31c8ff96c0) 0 + primary-for QAbstractItemModel (0x0x7f31c8f2fbc8) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f31c8ff9e40) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f31c8ff9f00) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f31c8f2fc98) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16) + QAbstractItemModel (0x0x7f31c8f2fd00) 0 + primary-for QAbstractProxyModel (0x0x7f31c8f2fc98) + QObject (0x0x7f31c8ff9ea0) 0 + primary-for QAbstractItemModel (0x0x7f31c8f2fd00) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f31c8c7e180) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f31c8f2fd68) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16) + QObject (0x0x7f31c8c7e120) 0 + primary-for QAbstractState (0x0x7f31c8f2fd68) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f31c8c7e3c0) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f31c8f2fdd0) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16) + QObject (0x0x7f31c8c7e360) 0 + primary-for QAbstractTransition (0x0x7f31c8f2fdd0) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f31c8c7e6c0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f31c8f2fe38) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16) + QAbstractAnimation (0x0x7f31c8f2fea0) 0 + primary-for QAnimationGroup (0x0x7f31c8f2fe38) + QObject (0x0x7f31c8c7e660) 0 + primary-for QAbstractAnimation (0x0x7f31c8f2fea0) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f31c8cee9c0) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f31c8d86360) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f31c8dd87e0) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f31c8e2ca80) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f31c8e39478) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16) + QObject (0x0x7f31c8e2ca20) 0 + primary-for QIODevice (0x0x7f31c8e39478) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f31c8a7a420) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f31c8e395b0) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16) + QIODevice (0x0x7f31c8e39618) 0 + primary-for QBuffer (0x0x7f31c8e395b0) + QObject (0x0x7f31c8a7a3c0) 0 + primary-for QIODevice (0x0x7f31c8e39618) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f31c8a7a6c0) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f31c8a7a660) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f31c8a7a840) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f31c8a7a7e0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f31c8ac9720) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f31c8b0c600) 0 + +Class QCalendar::YearMonthDay + size=12 align=4 + base size=12 base align=4 +QCalendar::YearMonthDay (0x0x7f31c8866ae0) 0 + +Class QCalendar + size=8 align=8 + base size=8 base align=8 +QCalendar (0x0x7f31c8866a80) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f31c88af300) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f31c8904ba0) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f31c8974840) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f31c89748a0) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f31c89747e0) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f31c8a44f60) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f31c8686840) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f31c87384e0) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f31c8659618) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16) + std::exception (0x0x7f31c8787360) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f31c8659618) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f31c8659680) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16) + std::exception (0x0x7f31c8787480) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f31c8659680) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f31c86596e8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16) + std::exception (0x0x7f31c87875a0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f31c86596e8) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f31c86597b8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16) + std::exception (0x0x7f31c87876c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f31c86597b8) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f31c87ac720) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f31c87aca20) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f31c87acd20) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f31c87d10c0) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f31c8659820) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16) + std::exception (0x0x7f31c844e2a0) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f31c8659820) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f31c84b6240) 0 empty + +Class std::__sp_array_delete + size=1 align=1 + base size=0 base align=1 +std::__sp_array_delete (0x0x7f31c84b6660) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f31c85f54e0) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f31c862b9c0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f31c862bb40) 0 + +Class QtPrivate::EnableInternalData + size=1 align=1 + base size=0 base align=1 +QtPrivate::EnableInternalData (0x0x7f31c82b4480) 0 empty + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f31c82deb40) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f31c82deae0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f31c8073480) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f31c8073540) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f31c80f7780) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f31c80f7f00) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f31c81b2de0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f31c8217ba0) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f31c7e95600) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f31c7fdf5a0) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7f31c7c63120) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f31c7c631e0) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f31c7aa4d80) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f31c7b5d7e0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f31c7b5d840) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f31c7b5d780) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f31c78d7420) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f31c78d7480) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f31c78d73c0) 0 + +Class qfloat16::Wrap + size=2 align=2 + base size=2 base align=2 +qfloat16::Wrap (0x0x7f31c76e1c00) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f31c76e1ba0) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f31c77c58a0) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f31c77fa600) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f31c747f720) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f31c747f900) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f31c7578f00) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f31c7270480) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f31c7251270) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16) + QEvent (0x0x7f31c7270840) 0 + primary-for QTimerEvent (0x0x7f31c7251270) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f31c72512d8) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16) + QEvent (0x0x7f31c7270900) 0 + primary-for QChildEvent (0x0x7f31c72512d8) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f31c7251820) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16) + QEvent (0x0x7f31c7270f60) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f31c7251820) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f31c7251888) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16) + QEvent (0x0x7f31c72b3060) 0 + primary-for QDeferredDeleteEvent (0x0x7f31c7251888) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f31c72b3180) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f31c72518f0) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16) + QObject (0x0x7f31c72b3120) 0 + primary-for QCoreApplication (0x0x7f31c72518f0) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f31c72b33c0) 0 + +Class QConcatenateTablesProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QConcatenateTablesProxyModel::QPrivateSignal (0x0x7f31c72b3540) 0 empty + +Vtable for QConcatenateTablesProxyModel +QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QConcatenateTablesProxyModel) +16 (int (*)(...))QConcatenateTablesProxyModel::metaObject +24 (int (*)(...))QConcatenateTablesProxyModel::qt_metacast +32 (int (*)(...))QConcatenateTablesProxyModel::qt_metacall +40 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +48 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QConcatenateTablesProxyModel::index +120 (int (*)(...))QConcatenateTablesProxyModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QConcatenateTablesProxyModel::rowCount +144 (int (*)(...))QConcatenateTablesProxyModel::columnCount +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))QConcatenateTablesProxyModel::data +168 (int (*)(...))QConcatenateTablesProxyModel::setData +176 (int (*)(...))QConcatenateTablesProxyModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QConcatenateTablesProxyModel::itemData +200 (int (*)(...))QConcatenateTablesProxyModel::setItemData +208 (int (*)(...))QConcatenateTablesProxyModel::mimeTypes +216 (int (*)(...))QConcatenateTablesProxyModel::mimeData +224 (int (*)(...))QConcatenateTablesProxyModel::canDropMimeData +232 (int (*)(...))QConcatenateTablesProxyModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QConcatenateTablesProxyModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QConcatenateTablesProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QConcatenateTablesProxyModel + size=16 align=8 + base size=16 base align=8 +QConcatenateTablesProxyModel (0x0x7f31c7251958) 0 + vptr=((& QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel) + 16) + QAbstractItemModel (0x0x7f31c72519c0) 0 + primary-for QConcatenateTablesProxyModel (0x0x7f31c7251958) + QObject (0x0x7f31c72b34e0) 0 + primary-for QAbstractItemModel (0x0x7f31c72519c0) + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f31c72b3720) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f31c72b3840) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f31c72b39c0) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f31c736f120) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f31c736f840) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f31c70b3540) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f31c70a3bc8) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16) + QIODevice (0x0x7f31c70a3c30) 0 + primary-for QFileDevice (0x0x7f31c70a3bc8) + QObject (0x0x7f31c70b34e0) 0 + primary-for QIODevice (0x0x7f31c70a3c30) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f31c70b3e40) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f31c70a3d68) 0 + vptr=((& QFile::_ZTV5QFile) + 16) + QFileDevice (0x0x7f31c70a3dd0) 0 + primary-for QFile (0x0x7f31c70a3d68) + QIODevice (0x0x7f31c70a3e38) 0 + primary-for QFileDevice (0x0x7f31c70a3dd0) + QObject (0x0x7f31c70b3de0) 0 + primary-for QIODevice (0x0x7f31c70a3e38) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f31c71234e0) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f31c71f33c0) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f31c6f103c0) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f31c6f10b40) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f31c6c4cc60) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f31c7016af8) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16) + QAbstractTransition (0x0x7f31c7016b60) 0 + primary-for QEventTransition (0x0x7f31c7016af8) + QObject (0x0x7f31c6c4cc00) 0 + primary-for QAbstractTransition (0x0x7f31c7016b60) + +Vtable for QException +QException::_ZTV10QException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f31c7016bc8) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16) + std::exception (0x0x7f31c6c4ce40) 0 nearly-empty + primary-for QException (0x0x7f31c7016bc8) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f31c7016c30) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16) + QException (0x0x7f31c7016c98) 0 nearly-empty + primary-for QUnhandledException (0x0x7f31c7016c30) + std::exception (0x0x7f31c6c4cea0) 0 nearly-empty + primary-for QException (0x0x7f31c7016c98) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f31c6c4cf00) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f31c6c92000) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f31c6c92060) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f31c6c922a0) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f31c7016d00) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16) + QObject (0x0x7f31c6c92240) 0 + primary-for QFileSelector (0x0x7f31c7016d00) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f31c6c924e0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f31c7016d68) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16) + QObject (0x0x7f31c6c92480) 0 + primary-for QFileSystemWatcher (0x0x7f31c7016d68) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f31c6c92720) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f31c7016dd0) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16) + QAbstractState (0x0x7f31c7016e38) 0 + primary-for QFinalState (0x0x7f31c7016dd0) + QObject (0x0x7f31c6c926c0) 0 + primary-for QAbstractState (0x0x7f31c7016e38) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f31c6c92900) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f31c6c92ba0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f31c7016f08) 0 + QBasicMutex (0x0x7f31c6d2f840) 0 + +Class QRecursiveMutex + size=8 align=8 + base size=8 base align=8 +QRecursiveMutex (0x0x7f31c7016f70) 0 + QMutex (0x0x7f31c6d49000) 0 + QBasicMutex (0x0x7f31c6d2fa80) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f31c6d2fae0) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f31c6d5b120) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f31c6d5b720) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f31c6d5b900) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16) + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f31c6dec120) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f31c6de18f0) 0 + std::__mutex_base (0x0x7f31c6dec180) 0 + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f31c6dec360) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f31c6dec3c0) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f31c6dec420) 0 empty + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f31c6dece40) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f31c6de1958) 0 + std::__recursive_mutex_base (0x0x7f31c6decea0) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f31c6deeb60) 0 + std::__mutex_base (0x0x7f31c6e282a0) 0 + std::__timed_mutex_impl<std::timed_mutex> (0x0x7f31c6e28300) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f31c6deeee0) 0 + std::__recursive_mutex_base (0x0x7f31c6e28660) 0 + std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7f31c6e286c0) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f31c6e28de0) 0 + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f31c6a6f060) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f31c6b173c0) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f31c6a9e750) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16) + QObject (0x0x7f31c6b17360) 0 + primary-for QFutureWatcherBase (0x0x7f31c6a9e750) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f31c6b3f720) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f31c6a9ef70) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16) + QAbstractState (0x0x7f31c6b4f000) 0 + primary-for QHistoryState (0x0x7f31c6a9ef70) + QObject (0x0x7f31c6b3f6c0) 0 + primary-for QAbstractState (0x0x7f31c6b4f000) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f31c6b3fa20) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f31c6b4f068) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16) + QAbstractProxyModel (0x0x7f31c6b4f0d0) 0 + primary-for QIdentityProxyModel (0x0x7f31c6b4f068) + QAbstractItemModel (0x0x7f31c6b4f138) 0 + primary-for QAbstractProxyModel (0x0x7f31c6b4f0d0) + QObject (0x0x7f31c6b3f9c0) 0 + primary-for QAbstractItemModel (0x0x7f31c6b4f138) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f31c6b3fc00) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f31c6c26540) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f31c6c22a90) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16) + QObject (0x0x7f31c6c264e0) 0 + primary-for QItemSelectionModel (0x0x7f31c6c22a90) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f31c6c22c30) 0 + QList<QItemSelectionRange> (0x0x7f31c6c22c98) 0 + QListSpecialMethods<QItemSelectionRange> (0x0x7f31c6874060) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f31c68d9960) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f31c6a2e600) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f31c66805a0) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f31c6680840) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f31c66c0ba0) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f31c66c0c00) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f31c66c0b40) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f31c67f0ae0) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f31c67f0b40) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f31c645d360) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f31c645d3c0) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f31c645d300) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f31c65807e0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f31c657d8f0) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16) + QObject (0x0x7f31c6580780) 0 + primary-for QLibrary (0x0x7f31c657d8f0) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f31c65c3660) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f31c65c3180) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f31c6262de0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f31c6262e40) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f31c62d4cc0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f31c6345ea0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f31c63d62a0) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f31c6052540) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f31c60f6a80) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f31c60f6cc0) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f31c60f6c60) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f31c6167120) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f31c61ea060) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f31c601d840) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f31c601d8a0) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f31c5ca7120) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f31c5cec300) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f31c5cec420) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f31c5d2d9c0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f31c5d32548) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16) + QObject (0x0x7f31c5d2d960) 0 + primary-for QMimeData (0x0x7f31c5d32548) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f31c5d2dba0) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f31c5df7ae0) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f31c5df7ba0) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f31c5e0a0d0) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16) + QObject (0x0x7f31c5df7b40) 0 + primary-for QObjectCleanupHandler (0x0x7f31c5e0a0d0) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f31c5df7cc0) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f31c5a89480) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f31c5a83958) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16) + QAnimationGroup (0x0x7f31c5a839c0) 0 + primary-for QParallelAnimationGroup (0x0x7f31c5a83958) + QAbstractAnimation (0x0x7f31c5a83a28) 0 + primary-for QAnimationGroup (0x0x7f31c5a839c0) + QObject (0x0x7f31c5a89420) 0 + primary-for QAbstractAnimation (0x0x7f31c5a83a28) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f31c5a896c0) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f31c5a83a90) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16) + QAbstractAnimation (0x0x7f31c5a83af8) 0 + primary-for QPauseAnimation (0x0x7f31c5a83a90) + QObject (0x0x7f31c5a89660) 0 + primary-for QAbstractAnimation (0x0x7f31c5a83af8) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f31c5abf240) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f31c5afc3c0) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f31c5aeae38) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16) + QObject (0x0x7f31c5afc360) 0 + primary-for QPluginLoader (0x0x7f31c5aeae38) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f31c5afc4e0) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f31c5bcb960) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f31c5bd32d8) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16) + QIODevice (0x0x7f31c5bd3340) 0 + primary-for QProcess (0x0x7f31c5bd32d8) + QObject (0x0x7f31c5bcb900) 0 + primary-for QIODevice (0x0x7f31c5bd3340) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f31c5c09060) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f31c5bd33a8) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16) + QAbstractAnimation (0x0x7f31c5bd3410) 0 + primary-for QVariantAnimation (0x0x7f31c5bd33a8) + QObject (0x0x7f31c5c09000) 0 + primary-for QAbstractAnimation (0x0x7f31c5bd3410) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f31c5c09300) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f31c5bd34e0) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16) + QVariantAnimation (0x0x7f31c5bd3548) 0 + primary-for QPropertyAnimation (0x0x7f31c5bd34e0) + QAbstractAnimation (0x0x7f31c5bd35b0) 0 + primary-for QVariantAnimation (0x0x7f31c5bd3548) + QObject (0x0x7f31c5c092a0) 0 + primary-for QAbstractAnimation (0x0x7f31c5bd35b0) + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f31c5893a20) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f31c599b780) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f31c599b720) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f31c578f4e0) 0 + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f31c55c4180) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f31c55c4120) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f31c5645270) 0 + QRandomGenerator (0x0x7f31c5642c60) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f31c5268840) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f31c5268ae0) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f31c52ee000) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f31c52ee4e0) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f31c53603c0) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f31c53db420) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f31c5090480) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f31c51525a0) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f31c5152840) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f31c50f6c30) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16) + QFileDevice (0x0x7f31c50f6c98) 0 + primary-for QSaveFile (0x0x7f31c50f6c30) + QIODevice (0x0x7f31c50f6d00) 0 + primary-for QFileDevice (0x0x7f31c50f6c98) + QObject (0x0x7f31c51527e0) 0 + primary-for QIODevice (0x0x7f31c50f6d00) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f31c5152e40) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f31c51e7000) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f31c4e4fc00) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f31c4e634e0) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16) + QAnimationGroup (0x0x7f31c4e63548) 0 + primary-for QSequentialAnimationGroup (0x0x7f31c4e634e0) + QAbstractAnimation (0x0x7f31c4e635b0) 0 + primary-for QAnimationGroup (0x0x7f31c4e63548) + QObject (0x0x7f31c4e4fba0) 0 + primary-for QAbstractAnimation (0x0x7f31c4e635b0) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f31c4e4fe40) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f31c4e63618) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16) + QObject (0x0x7f31c4e4fde0) 0 + primary-for QSettings (0x0x7f31c4e63618) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f31c4e96300) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f31c4e63680) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16) + QObject (0x0x7f31c4e962a0) 0 + primary-for QSharedMemory (0x0x7f31c4e63680) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f31c4e96540) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f31c4e636e8) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16) + QObject (0x0x7f31c4e964e0) 0 + primary-for QSignalMapper (0x0x7f31c4e636e8) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f31c4e96780) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f31c4e63750) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16) + QAbstractTransition (0x0x7f31c4e637b8) 0 + primary-for QSignalTransition (0x0x7f31c4e63750) + QObject (0x0x7f31c4e96720) 0 + primary-for QAbstractTransition (0x0x7f31c4e637b8) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f31c4e96a20) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f31c4e63820) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16) + QObject (0x0x7f31c4e969c0) 0 + primary-for QSocketNotifier (0x0x7f31c4e63820) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f31c4e96c60) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f31c4e63888) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16) + QAbstractProxyModel (0x0x7f31c4e638f0) 0 + primary-for QSortFilterProxyModel (0x0x7f31c4e63888) + QAbstractItemModel (0x0x7f31c4e63958) 0 + primary-for QAbstractProxyModel (0x0x7f31c4e638f0) + QObject (0x0x7f31c4e96c00) 0 + primary-for QAbstractItemModel (0x0x7f31c4e63958) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f31c4f060c0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f31c4f069c0) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f31c4e63af8) 0 + vptr=((& QState::_ZTV6QState) + 16) + QAbstractState (0x0x7f31c4e63b60) 0 + primary-for QState (0x0x7f31c4e63af8) + QObject (0x0x7f31c4f06960) 0 + primary-for QAbstractState (0x0x7f31c4e63b60) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f31c4f06e40) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f31c4e63d00) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16) + QEvent (0x0x7f31c4f06ea0) 0 + primary-for QStateMachine::SignalEvent (0x0x7f31c4e63d00) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f31c4e63d68) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16) + QEvent (0x0x7f31c4f06f00) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f31c4e63d68) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f31c4e63bc8) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16) + QState (0x0x7f31c4e63c30) 0 + primary-for QStateMachine (0x0x7f31c4e63bc8) + QAbstractState (0x0x7f31c4e63c98) 0 + primary-for QState (0x0x7f31c4e63c30) + QObject (0x0x7f31c4f06de0) 0 + primary-for QAbstractState (0x0x7f31c4e63c98) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f31c4f74300) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f31c4c6a0c0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f31c4cf3420) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QStringListModel::itemData +200 (int (*)(...))QStringListModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QStringListModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f31c4ce0680) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16) + QAbstractListModel (0x0x7f31c4ce06e8) 0 + primary-for QStringListModel (0x0x7f31c4ce0680) + QAbstractItemModel (0x0x7f31c4ce0750) 0 + primary-for QAbstractListModel (0x0x7f31c4ce06e8) + QObject (0x0x7f31c4cf33c0) 0 + primary-for QAbstractItemModel (0x0x7f31c4ce0750) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f31c4cf3540) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f31c4cf3600) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f31c4cf3720) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f31c4ce07b8) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16) + QFile (0x0x7f31c4ce0820) 0 + primary-for QTemporaryFile (0x0x7f31c4ce07b8) + QFileDevice (0x0x7f31c4ce0888) 0 + primary-for QFile (0x0x7f31c4ce0820) + QIODevice (0x0x7f31c4ce08f0) 0 + primary-for QFileDevice (0x0x7f31c4ce0888) + QObject (0x0x7f31c4cf36c0) 0 + primary-for QIODevice (0x0x7f31c4ce08f0) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f31c4cf3a80) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f31c4d6f300) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0 +64 0 + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f31c4d6f2a0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f31c4d6fcc0) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f31c4d6fea0) 0 + +Vtable for std::thread::_State +std::thread::_State::_ZTVNSt6thread6_StateE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread6_StateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_State + size=8 align=8 + base size=8 base align=8 +std::thread::_State (0x0x7f31c4dc9120) 0 nearly-empty + vptr=((& std::thread::_State::_ZTVNSt6thread6_StateE) + 16) + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f31c4dc9180) 0 + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f31c4dc90c0) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f31c4857540) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f31c4857900) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f31c4857960) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f31c49e8c60) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f31c49ebc98) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16) + std::logic_error (0x0x7f31c49ebd00) 0 + primary-for std::future_error (0x0x7f31c49ebc98) + std::exception (0x0x7f31c4a163c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f31c49ebd00) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f31c4a16ae0) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f31c4a16a80) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f31c4821240) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f31c4814548) 0 + std::__at_thread_exit_elt (0x0x7f31c4821300) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f31c4a16c60) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f31c4a16a20) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f31c3fab270) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16) + std::__future_base::_State_baseV2 (0x0x7f31c3fcc300) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f31c3fab270) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f31c3fccba0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f31c3fab5b0) 0 + vptr=((& QThread::_ZTV7QThread) + 16) + QObject (0x0x7f31c3fccb40) 0 + primary-for QThread (0x0x7f31c3fab5b0) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f31c3fccf60) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f31c3fab618) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16) + QObject (0x0x7f31c3fccf00) 0 + primary-for QThreadPool (0x0x7f31c3fab618) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f31c4013180) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f31c4013840) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f31c3fab680) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16) + QObject (0x0x7f31c40137e0) 0 + primary-for QTimeLine (0x0x7f31c3fab680) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f31c4013a80) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f31c3fab6e8) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16) + QObject (0x0x7f31c4013a20) 0 + primary-for QTimer (0x0x7f31c3fab6e8) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f31c3c85420) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f31c3c853c0) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f31c3d1f4e0) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f31c3d11dd0) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16) + QObject (0x0x7f31c3d1f480) 0 + primary-for QTranslator (0x0x7f31c3d11dd0) + +Class QTransposeProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTransposeProxyModel::QPrivateSignal (0x0x7f31c3d1f720) 0 empty + +Vtable for QTransposeProxyModel +QTransposeProxyModel::_ZTV20QTransposeProxyModel: 53 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTransposeProxyModel) +16 (int (*)(...))QTransposeProxyModel::metaObject +24 (int (*)(...))QTransposeProxyModel::qt_metacast +32 (int (*)(...))QTransposeProxyModel::qt_metacall +40 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +48 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTransposeProxyModel::index +120 (int (*)(...))QTransposeProxyModel::parent +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))QTransposeProxyModel::rowCount +144 (int (*)(...))QTransposeProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QTransposeProxyModel::headerData +184 (int (*)(...))QTransposeProxyModel::setHeaderData +192 (int (*)(...))QTransposeProxyModel::itemData +200 (int (*)(...))QTransposeProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QTransposeProxyModel::insertRows +264 (int (*)(...))QTransposeProxyModel::insertColumns +272 (int (*)(...))QTransposeProxyModel::removeRows +280 (int (*)(...))QTransposeProxyModel::removeColumns +288 (int (*)(...))QTransposeProxyModel::moveRows +296 (int (*)(...))QTransposeProxyModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QTransposeProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QTransposeProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QTransposeProxyModel::setSourceModel +392 (int (*)(...))QTransposeProxyModel::mapToSource +400 (int (*)(...))QTransposeProxyModel::mapFromSource +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QTransposeProxyModel + size=16 align=8 + base size=16 base align=8 +QTransposeProxyModel (0x0x7f31c3d11e38) 0 + vptr=((& QTransposeProxyModel::_ZTV20QTransposeProxyModel) + 16) + QAbstractProxyModel (0x0x7f31c3d11ea0) 0 + primary-for QTransposeProxyModel (0x0x7f31c3d11e38) + QAbstractItemModel (0x0x7f31c3d11f08) 0 + primary-for QAbstractProxyModel (0x0x7f31c3d11ea0) + QObject (0x0x7f31c3d1f6c0) 0 + primary-for QAbstractItemModel (0x0x7f31c3d11f08) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f31c3d1f900) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f31c3e1bde0) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f31c3e1bf00) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f31c3aca300) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f31c3b38208) 0 + QVector<QXmlStreamAttribute> (0x0x7f31c3b31a20) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f31c3b31d20) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f31c3bb0cc0) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f31c3c0dcc0) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f31c387ad80) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f31c387ade0) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f31c38b4cc0) 0 + +Class QRgba64 + size=8 align=8 + base size=8 base align=8 +QRgba64 (0x0x7f31c3908300) 0 + +Class QColor::CT + size=10 align=2 + base size=10 base align=2 +QColor::CT (0x0x7f31c39aa3c0) 0 + +Class QColor + size=16 align=4 + base size=14 base align=4 +QColor (0x0x7f31c39aa360) 0 + +Class QRegion::QRegionData + size=16 align=8 + base size=16 base align=8 +QRegion::QRegionData (0x0x7f31c366e2a0) 0 + +Class QRegion + size=8 align=8 + base size=8 base align=8 +QRegion (0x0x7f31c366e240) 0 + +Class QKeySequence + size=8 align=8 + base size=8 base align=8 +QKeySequence (0x0x7f31c37d9ea0) 0 + +Class QVector2D + size=8 align=4 + base size=8 base align=4 +QVector2D (0x0x7f31c34c7a20) 0 + +Class QTouchDevice + size=8 align=8 + base size=8 base align=8 +QTouchDevice (0x0x7f31c3534ae0) 0 + +Vtable for QInputEvent +QInputEvent::_ZTV11QInputEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QInputEvent) +16 (int (*)(...))QInputEvent::~QInputEvent +24 (int (*)(...))QInputEvent::~QInputEvent + +Class QInputEvent + size=32 align=8 + base size=32 base align=8 +QInputEvent (0x0x7f31c35218f0) 0 + vptr=((& QInputEvent::_ZTV11QInputEvent) + 16) + QEvent (0x0x7f31c357b3c0) 0 + primary-for QInputEvent (0x0x7f31c35218f0) + +Vtable for QEnterEvent +QEnterEvent::_ZTV11QEnterEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QEnterEvent) +16 (int (*)(...))QEnterEvent::~QEnterEvent +24 (int (*)(...))QEnterEvent::~QEnterEvent + +Class QEnterEvent + size=72 align=8 + base size=72 base align=8 +QEnterEvent (0x0x7f31c3521958) 0 + vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16) + QEvent (0x0x7f31c357b5a0) 0 + primary-for QEnterEvent (0x0x7f31c3521958) + +Vtable for QMouseEvent +QMouseEvent::_ZTV11QMouseEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMouseEvent) +16 (int (*)(...))QMouseEvent::~QMouseEvent +24 (int (*)(...))QMouseEvent::~QMouseEvent + +Class QMouseEvent + size=104 align=8 + base size=100 base align=8 +QMouseEvent (0x0x7f31c35219c0) 0 + vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16) + QInputEvent (0x0x7f31c3521a28) 0 + primary-for QMouseEvent (0x0x7f31c35219c0) + QEvent (0x0x7f31c357b960) 0 + primary-for QInputEvent (0x0x7f31c3521a28) + +Vtable for QHoverEvent +QHoverEvent::_ZTV11QHoverEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHoverEvent) +16 (int (*)(...))QHoverEvent::~QHoverEvent +24 (int (*)(...))QHoverEvent::~QHoverEvent + +Class QHoverEvent + size=64 align=8 + base size=64 base align=8 +QHoverEvent (0x0x7f31c3521a90) 0 + vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16) + QInputEvent (0x0x7f31c3521af8) 0 + primary-for QHoverEvent (0x0x7f31c3521a90) + QEvent (0x0x7f31c357be40) 0 + primary-for QInputEvent (0x0x7f31c3521af8) + +Vtable for QWheelEvent +QWheelEvent::_ZTV11QWheelEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWheelEvent) +16 (int (*)(...))QWheelEvent::~QWheelEvent +24 (int (*)(...))QWheelEvent::~QWheelEvent + +Class QWheelEvent + size=96 align=8 + base size=96 base align=8 +QWheelEvent (0x0x7f31c3521b60) 0 + vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16) + QInputEvent (0x0x7f31c3521bc8) 0 + primary-for QWheelEvent (0x0x7f31c3521b60) + QEvent (0x0x7f31c35b6060) 0 + primary-for QInputEvent (0x0x7f31c3521bc8) + +Vtable for QTabletEvent +QTabletEvent::_ZTV12QTabletEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTabletEvent) +16 (int (*)(...))QTabletEvent::~QTabletEvent +24 (int (*)(...))QTabletEvent::~QTabletEvent + +Class QTabletEvent + size=128 align=8 + base size=128 base align=8 +QTabletEvent (0x0x7f31c3521c30) 0 + vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16) + QInputEvent (0x0x7f31c3521c98) 0 + primary-for QTabletEvent (0x0x7f31c3521c30) + QEvent (0x0x7f31c35b6780) 0 + primary-for QInputEvent (0x0x7f31c3521c98) + +Vtable for QNativeGestureEvent +QNativeGestureEvent::_ZTV19QNativeGestureEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNativeGestureEvent) +16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent + +Class QNativeGestureEvent + size=112 align=8 + base size=112 base align=8 +QNativeGestureEvent (0x0x7f31c3521d00) 0 + vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16) + QInputEvent (0x0x7f31c3521d68) 0 + primary-for QNativeGestureEvent (0x0x7f31c3521d00) + QEvent (0x0x7f31c35f10c0) 0 + primary-for QInputEvent (0x0x7f31c3521d68) + +Vtable for QKeyEvent +QKeyEvent::_ZTV9QKeyEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QKeyEvent) +16 (int (*)(...))QKeyEvent::~QKeyEvent +24 (int (*)(...))QKeyEvent::~QKeyEvent + +Class QKeyEvent + size=64 align=8 + base size=59 base align=8 +QKeyEvent (0x0x7f31c3521dd0) 0 + vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16) + QInputEvent (0x0x7f31c3521e38) 0 + primary-for QKeyEvent (0x0x7f31c3521dd0) + QEvent (0x0x7f31c35f13c0) 0 + primary-for QInputEvent (0x0x7f31c3521e38) + +Vtable for QFocusEvent +QFocusEvent::_ZTV11QFocusEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusEvent) +16 (int (*)(...))QFocusEvent::~QFocusEvent +24 (int (*)(...))QFocusEvent::~QFocusEvent + +Class QFocusEvent + size=24 align=8 + base size=24 base align=8 +QFocusEvent (0x0x7f31c3521ea0) 0 + vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16) + QEvent (0x0x7f31c35f16c0) 0 + primary-for QFocusEvent (0x0x7f31c3521ea0) + +Vtable for QPaintEvent +QPaintEvent::_ZTV11QPaintEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPaintEvent) +16 (int (*)(...))QPaintEvent::~QPaintEvent +24 (int (*)(...))QPaintEvent::~QPaintEvent + +Class QPaintEvent + size=56 align=8 + base size=49 base align=8 +QPaintEvent (0x0x7f31c3521f08) 0 + vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16) + QEvent (0x0x7f31c35f17e0) 0 + primary-for QPaintEvent (0x0x7f31c3521f08) + +Vtable for QMoveEvent +QMoveEvent::_ZTV10QMoveEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QMoveEvent) +16 (int (*)(...))QMoveEvent::~QMoveEvent +24 (int (*)(...))QMoveEvent::~QMoveEvent + +Class QMoveEvent + size=40 align=8 + base size=36 base align=8 +QMoveEvent (0x0x7f31c3521f70) 0 + vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16) + QEvent (0x0x7f31c35f1900) 0 + primary-for QMoveEvent (0x0x7f31c3521f70) + +Vtable for QExposeEvent +QExposeEvent::_ZTV12QExposeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QExposeEvent) +16 (int (*)(...))QExposeEvent::~QExposeEvent +24 (int (*)(...))QExposeEvent::~QExposeEvent + +Class QExposeEvent + size=32 align=8 + base size=32 base align=8 +QExposeEvent (0x0x7f31c3626000) 0 + vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16) + QEvent (0x0x7f31c35f1a20) 0 + primary-for QExposeEvent (0x0x7f31c3626000) + +Vtable for QPlatformSurfaceEvent +QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent) +16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent + +Class QPlatformSurfaceEvent + size=24 align=8 + base size=24 base align=8 +QPlatformSurfaceEvent (0x0x7f31c3626068) 0 + vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16) + QEvent (0x0x7f31c35f1ae0) 0 + primary-for QPlatformSurfaceEvent (0x0x7f31c3626068) + +Vtable for QResizeEvent +QResizeEvent::_ZTV12QResizeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QResizeEvent) +16 (int (*)(...))QResizeEvent::~QResizeEvent +24 (int (*)(...))QResizeEvent::~QResizeEvent + +Class QResizeEvent + size=40 align=8 + base size=36 base align=8 +QResizeEvent (0x0x7f31c36260d0) 0 + vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16) + QEvent (0x0x7f31c35f1ba0) 0 + primary-for QResizeEvent (0x0x7f31c36260d0) + +Vtable for QCloseEvent +QCloseEvent::_ZTV11QCloseEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QCloseEvent) +16 (int (*)(...))QCloseEvent::~QCloseEvent +24 (int (*)(...))QCloseEvent::~QCloseEvent + +Class QCloseEvent + size=24 align=8 + base size=20 base align=8 +QCloseEvent (0x0x7f31c3626138) 0 + vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16) + QEvent (0x0x7f31c35f1cc0) 0 + primary-for QCloseEvent (0x0x7f31c3626138) + +Vtable for QIconDragEvent +QIconDragEvent::_ZTV14QIconDragEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QIconDragEvent) +16 (int (*)(...))QIconDragEvent::~QIconDragEvent +24 (int (*)(...))QIconDragEvent::~QIconDragEvent + +Class QIconDragEvent + size=24 align=8 + base size=20 base align=8 +QIconDragEvent (0x0x7f31c36261a0) 0 + vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16) + QEvent (0x0x7f31c35f1d20) 0 + primary-for QIconDragEvent (0x0x7f31c36261a0) + +Vtable for QShowEvent +QShowEvent::_ZTV10QShowEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QShowEvent) +16 (int (*)(...))QShowEvent::~QShowEvent +24 (int (*)(...))QShowEvent::~QShowEvent + +Class QShowEvent + size=24 align=8 + base size=20 base align=8 +QShowEvent (0x0x7f31c3626208) 0 + vptr=((& QShowEvent::_ZTV10QShowEvent) + 16) + QEvent (0x0x7f31c35f1d80) 0 + primary-for QShowEvent (0x0x7f31c3626208) + +Vtable for QHideEvent +QHideEvent::_ZTV10QHideEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHideEvent) +16 (int (*)(...))QHideEvent::~QHideEvent +24 (int (*)(...))QHideEvent::~QHideEvent + +Class QHideEvent + size=24 align=8 + base size=20 base align=8 +QHideEvent (0x0x7f31c3626270) 0 + vptr=((& QHideEvent::_ZTV10QHideEvent) + 16) + QEvent (0x0x7f31c35f1de0) 0 + primary-for QHideEvent (0x0x7f31c3626270) + +Vtable for QContextMenuEvent +QContextMenuEvent::_ZTV17QContextMenuEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QContextMenuEvent) +16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent + +Class QContextMenuEvent + size=56 align=8 + base size=49 base align=8 +QContextMenuEvent (0x0x7f31c36262d8) 0 + vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16) + QInputEvent (0x0x7f31c3626340) 0 + primary-for QContextMenuEvent (0x0x7f31c36262d8) + QEvent (0x0x7f31c35f1e40) 0 + primary-for QInputEvent (0x0x7f31c3626340) + +Class QInputMethodEvent::Attribute + size=32 align=8 + base size=32 base align=8 +QInputMethodEvent::Attribute (0x0x7f31c36461e0) 0 + +Vtable for QInputMethodEvent +QInputMethodEvent::_ZTV17QInputMethodEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QInputMethodEvent) +16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent + +Class QInputMethodEvent + size=56 align=8 + base size=56 base align=8 +QInputMethodEvent (0x0x7f31c36263a8) 0 + vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16) + QEvent (0x0x7f31c3646180) 0 + primary-for QInputMethodEvent (0x0x7f31c36263a8) + +Class QInputMethodQueryEvent::QueryPair + size=24 align=8 + base size=24 base align=8 +QInputMethodQueryEvent::QueryPair (0x0x7f31c32bf540) 0 + +Vtable for QInputMethodQueryEvent +QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent) +16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent + +Class QInputMethodQueryEvent + size=32 align=8 + base size=32 base align=8 +QInputMethodQueryEvent (0x0x7f31c32c05b0) 0 + vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16) + QEvent (0x0x7f31c32bf4e0) 0 + primary-for QInputMethodQueryEvent (0x0x7f31c32c05b0) + +Vtable for QDropEvent +QDropEvent::_ZTV10QDropEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDropEvent) +16 (int (*)(...))QDropEvent::~QDropEvent +24 (int (*)(...))QDropEvent::~QDropEvent + +Class QDropEvent + size=72 align=8 + base size=72 base align=8 +QDropEvent (0x0x7f31c3335680) 0 + vptr=((& QDropEvent::_ZTV10QDropEvent) + 16) + QEvent (0x0x7f31c333e2a0) 0 + primary-for QDropEvent (0x0x7f31c3335680) + +Vtable for QDragMoveEvent +QDragMoveEvent::_ZTV14QDragMoveEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDragMoveEvent) +16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent + +Class QDragMoveEvent + size=88 align=8 + base size=88 base align=8 +QDragMoveEvent (0x0x7f31c33356e8) 0 + vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16) + QDropEvent (0x0x7f31c3335750) 0 + primary-for QDragMoveEvent (0x0x7f31c33356e8) + QEvent (0x0x7f31c333e660) 0 + primary-for QDropEvent (0x0x7f31c3335750) + +Vtable for QDragEnterEvent +QDragEnterEvent::_ZTV15QDragEnterEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragEnterEvent) +16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent + +Class QDragEnterEvent + size=88 align=8 + base size=88 base align=8 +QDragEnterEvent (0x0x7f31c33357b8) 0 + vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16) + QDragMoveEvent (0x0x7f31c3335820) 0 + primary-for QDragEnterEvent (0x0x7f31c33357b8) + QDropEvent (0x0x7f31c3335888) 0 + primary-for QDragMoveEvent (0x0x7f31c3335820) + QEvent (0x0x7f31c333e8a0) 0 + primary-for QDropEvent (0x0x7f31c3335888) + +Vtable for QDragLeaveEvent +QDragLeaveEvent::_ZTV15QDragLeaveEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragLeaveEvent) +16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent + +Class QDragLeaveEvent + size=24 align=8 + base size=20 base align=8 +QDragLeaveEvent (0x0x7f31c33358f0) 0 + vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16) + QEvent (0x0x7f31c333e900) 0 + primary-for QDragLeaveEvent (0x0x7f31c33358f0) + +Vtable for QHelpEvent +QHelpEvent::_ZTV10QHelpEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHelpEvent) +16 (int (*)(...))QHelpEvent::~QHelpEvent +24 (int (*)(...))QHelpEvent::~QHelpEvent + +Class QHelpEvent + size=40 align=8 + base size=36 base align=8 +QHelpEvent (0x0x7f31c3335958) 0 + vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16) + QEvent (0x0x7f31c333e960) 0 + primary-for QHelpEvent (0x0x7f31c3335958) + +Vtable for QStatusTipEvent +QStatusTipEvent::_ZTV15QStatusTipEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QStatusTipEvent) +16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent + +Class QStatusTipEvent + size=32 align=8 + base size=32 base align=8 +QStatusTipEvent (0x0x7f31c33359c0) 0 + vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16) + QEvent (0x0x7f31c333ec00) 0 + primary-for QStatusTipEvent (0x0x7f31c33359c0) + +Vtable for QWhatsThisClickedEvent +QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent) +16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent + +Class QWhatsThisClickedEvent + size=32 align=8 + base size=32 base align=8 +QWhatsThisClickedEvent (0x0x7f31c3335a28) 0 + vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16) + QEvent (0x0x7f31c333ecc0) 0 + primary-for QWhatsThisClickedEvent (0x0x7f31c3335a28) + +Vtable for QActionEvent +QActionEvent::_ZTV12QActionEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionEvent) +16 (int (*)(...))QActionEvent::~QActionEvent +24 (int (*)(...))QActionEvent::~QActionEvent + +Class QActionEvent + size=40 align=8 + base size=40 base align=8 +QActionEvent (0x0x7f31c3335a90) 0 + vptr=((& QActionEvent::_ZTV12QActionEvent) + 16) + QEvent (0x0x7f31c333ed80) 0 + primary-for QActionEvent (0x0x7f31c3335a90) + +Vtable for QFileOpenEvent +QFileOpenEvent::_ZTV14QFileOpenEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QFileOpenEvent) +16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent + +Class QFileOpenEvent + size=40 align=8 + base size=40 base align=8 +QFileOpenEvent (0x0x7f31c3335af8) 0 + vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16) + QEvent (0x0x7f31c333eea0) 0 + primary-for QFileOpenEvent (0x0x7f31c3335af8) + +Vtable for QToolBarChangeEvent +QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QToolBarChangeEvent) +16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent + +Class QToolBarChangeEvent + size=24 align=8 + base size=21 base align=8 +QToolBarChangeEvent (0x0x7f31c3335b60) 0 + vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16) + QEvent (0x0x7f31c3379000) 0 + primary-for QToolBarChangeEvent (0x0x7f31c3335b60) + +Vtable for QShortcutEvent +QShortcutEvent::_ZTV14QShortcutEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QShortcutEvent) +16 (int (*)(...))QShortcutEvent::~QShortcutEvent +24 (int (*)(...))QShortcutEvent::~QShortcutEvent + +Class QShortcutEvent + size=40 align=8 + base size=40 base align=8 +QShortcutEvent (0x0x7f31c3335bc8) 0 + vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16) + QEvent (0x0x7f31c33790c0) 0 + primary-for QShortcutEvent (0x0x7f31c3335bc8) + +Vtable for QWindowStateChangeEvent +QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent) +16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent + +Class QWindowStateChangeEvent + size=32 align=8 + base size=25 base align=8 +QWindowStateChangeEvent (0x0x7f31c3335c30) 0 + vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16) + QEvent (0x0x7f31c3379240) 0 + primary-for QWindowStateChangeEvent (0x0x7f31c3335c30) + +Class QPointingDeviceUniqueId + size=8 align=8 + base size=8 base align=8 +QPointingDeviceUniqueId (0x0x7f31c33793c0) 0 + +Class QTouchEvent::TouchPoint + size=8 align=8 + base size=8 base align=8 +QTouchEvent::TouchPoint (0x0x7f31c33ca780) 0 + +Vtable for QTouchEvent +QTouchEvent::_ZTV11QTouchEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTouchEvent) +16 (int (*)(...))QTouchEvent::~QTouchEvent +24 (int (*)(...))QTouchEvent::~QTouchEvent + +Class QTouchEvent + size=72 align=8 + base size=72 base align=8 +QTouchEvent (0x0x7f31c33d4478) 0 + vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16) + QInputEvent (0x0x7f31c33d44e0) 0 + primary-for QTouchEvent (0x0x7f31c33d4478) + QEvent (0x0x7f31c33ca720) 0 + primary-for QInputEvent (0x0x7f31c33d44e0) + +Vtable for QScrollPrepareEvent +QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollPrepareEvent) +16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent + +Class QScrollPrepareEvent + size=112 align=8 + base size=112 base align=8 +QScrollPrepareEvent (0x0x7f31c30e31a0) 0 + vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16) + QEvent (0x0x7f31c30dcd20) 0 + primary-for QScrollPrepareEvent (0x0x7f31c30e31a0) + +Vtable for QScrollEvent +QScrollEvent::_ZTV12QScrollEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QScrollEvent) +16 (int (*)(...))QScrollEvent::~QScrollEvent +24 (int (*)(...))QScrollEvent::~QScrollEvent + +Class QScrollEvent + size=64 align=8 + base size=60 base align=8 +QScrollEvent (0x0x7f31c30e3208) 0 + vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16) + QEvent (0x0x7f31c30dcd80) 0 + primary-for QScrollEvent (0x0x7f31c30e3208) + +Vtable for QScreenOrientationChangeEvent +QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent) +16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent + +Class QScreenOrientationChangeEvent + size=40 align=8 + base size=36 base align=8 +QScreenOrientationChangeEvent (0x0x7f31c30e3270) 0 + vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16) + QEvent (0x0x7f31c30dcde0) 0 + primary-for QScreenOrientationChangeEvent (0x0x7f31c30e3270) + +Vtable for QApplicationStateChangeEvent +QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent) +16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent + +Class QApplicationStateChangeEvent + size=24 align=8 + base size=24 base align=8 +QApplicationStateChangeEvent (0x0x7f31c30e32d8) 0 + vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16) + QEvent (0x0x7f31c30dce40) 0 + primary-for QApplicationStateChangeEvent (0x0x7f31c30e32d8) + +Class QFont + size=16 align=8 + base size=12 base align=8 +QFont (0x0x7f31c30dcea0) 0 + +Class QPolygon + size=8 align=8 + base size=8 base align=8 +QPolygon (0x0x7f31c3219750) 0 + QVector<QPoint> (0x0x7f31c3209f00) 0 + +Class QPolygonF + size=8 align=8 + base size=8 base align=8 +QPolygonF (0x0x7f31c2e3aa90) 0 + QVector<QPointF> (0x0x7f31c2e61060) 0 + +Class QMatrix + size=48 align=8 + base size=48 base align=8 +QMatrix (0x0x7f31c2ecef00) 0 + +Class QPainterPath::Element + size=24 align=8 + base size=24 base align=8 +QPainterPath::Element (0x0x7f31c2f3fd20) 0 + +Class QPainterPath + size=8 align=8 + base size=8 base align=8 +QPainterPath (0x0x7f31c2f3fcc0) 0 + +Class QPainterPathStroker + size=8 align=8 + base size=8 base align=8 +QPainterPathStroker (0x0x7f31c2c920c0) 0 + +Class QTransform + size=88 align=8 + base size=88 base align=8 +QTransform (0x0x7f31c2c92780) 0 + +Vtable for QPaintDevice +QPaintDevice::_ZTV12QPaintDevice: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintDevice) +16 0 +24 0 +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDevice + size=24 align=8 + base size=24 base align=8 +QPaintDevice (0x0x7f31c2d6d240) 0 + vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16) + +Class QPixelFormat + size=8 align=8 + base size=8 base align=8 +QPixelFormat (0x0x7f31c2d6d840) 0 + +Vtable for QImage +QImage::_ZTV6QImage: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QImage) +16 (int (*)(...))QImage::~QImage +24 (int (*)(...))QImage::~QImage +32 (int (*)(...))QImage::devType +40 (int (*)(...))QImage::paintEngine +48 (int (*)(...))QImage::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QImage + size=32 align=8 + base size=32 base align=8 +QImage (0x0x7f31c2a1b8f0) 0 + vptr=((& QImage::_ZTV6QImage) + 16) + QPaintDevice (0x0x7f31c2a3a180) 0 + primary-for QImage (0x0x7f31c2a1b8f0) + +Vtable for QPixmap +QPixmap::_ZTV7QPixmap: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QPixmap) +16 (int (*)(...))QPixmap::~QPixmap +24 (int (*)(...))QPixmap::~QPixmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPixmap + size=32 align=8 + base size=32 base align=8 +QPixmap (0x0x7f31c2b35340) 0 + vptr=((& QPixmap::_ZTV7QPixmap) + 16) + QPaintDevice (0x0x7f31c2b23f00) 0 + primary-for QPixmap (0x0x7f31c2b35340) + +Class QBrush + size=8 align=8 + base size=8 base align=8 +QBrush (0x0x7f31c281d240) 0 + +Class QBrushData + size=112 align=8 + base size=112 base align=8 +QBrushData (0x0x7f31c28e0780) 0 + +Class QGradient + size=64 align=8 + base size=64 base align=8 +QGradient (0x0x7f31c28e09c0) 0 + +Class QLinearGradient + size=64 align=8 + base size=64 base align=8 +QLinearGradient (0x0x7f31c28d6d00) 0 + QGradient (0x0x7f31c2948120) 0 + +Class QRadialGradient + size=64 align=8 + base size=64 base align=8 +QRadialGradient (0x0x7f31c28d6d68) 0 + QGradient (0x0x7f31c2948240) 0 + +Class QConicalGradient + size=64 align=8 + base size=64 base align=8 +QConicalGradient (0x0x7f31c28d6dd0) 0 + QGradient (0x0x7f31c2948360) 0 + +Class QPen + size=8 align=8 + base size=8 base align=8 +QPen (0x0x7f31c2948420) 0 + +Class QTextOption::Tab + size=16 align=8 + base size=14 base align=8 +QTextOption::Tab (0x0x7f31c2606d80) 0 + +Class QTextOption + size=32 align=8 + base size=32 base align=8 +QTextOption (0x0x7f31c2606d20) 0 + +Class QTextLength + size=16 align=8 + base size=16 base align=8 +QTextLength (0x0x7f31c26704e0) 0 + +Class QTextFormat + size=16 align=8 + base size=12 base align=8 +QTextFormat (0x0x7f31c26c6e40) 0 + +Class QTextCharFormat + size=16 align=8 + base size=12 base align=8 +QTextCharFormat (0x0x7f31c2435af8) 0 + QTextFormat (0x0x7f31c2461540) 0 + +Class QTextBlockFormat + size=16 align=8 + base size=12 base align=8 +QTextBlockFormat (0x0x7f31c24d6f08) 0 + QTextFormat (0x0x7f31c24d7f00) 0 + +Class QTextListFormat + size=16 align=8 + base size=12 base align=8 +QTextListFormat (0x0x7f31c2547478) 0 + QTextFormat (0x0x7f31c253acc0) 0 + +Class QTextImageFormat + size=16 align=8 + base size=12 base align=8 +QTextImageFormat (0x0x7f31c258f888) 0 + QTextCharFormat (0x0x7f31c258f8f0) 0 + QTextFormat (0x0x7f31c2598480) 0 + +Class QTextFrameFormat + size=16 align=8 + base size=12 base align=8 +QTextFrameFormat (0x0x7f31c21cfe38) 0 + QTextFormat (0x0x7f31c21d9ae0) 0 + +Class QTextTableFormat + size=16 align=8 + base size=12 base align=8 +QTextTableFormat (0x0x7f31c22373a8) 0 + QTextFrameFormat (0x0x7f31c2237410) 0 + QTextFormat (0x0x7f31c223d720) 0 + +Class QTextTableCellFormat + size=16 align=8 + base size=12 base align=8 +QTextTableCellFormat (0x0x7f31c228f958) 0 + QTextCharFormat (0x0x7f31c228f9c0) 0 + QTextFormat (0x0x7f31c22a00c0) 0 + +Class QFontDatabase + size=8 align=8 + base size=8 base align=8 +QFontDatabase (0x0x7f31c22f1f00) 0 + +Class QRawFont + size=8 align=8 + base size=8 base align=8 +QRawFont (0x0x7f31c231f120) 0 + +Class QGlyphRun + size=8 align=8 + base size=8 base align=8 +QGlyphRun (0x0x7f31c1ff9900) 0 + +Class QTextCursor + size=8 align=8 + base size=8 base align=8 +QTextCursor (0x0x7f31c20e4840) 0 + +Class QTextInlineObject + size=16 align=8 + base size=16 base align=8 +QTextInlineObject (0x0x7f31c21bf4e0) 0 + +Class QTextLayout::FormatRange + size=24 align=8 + base size=24 base align=8 +QTextLayout::FormatRange (0x0x7f31c21bf900) 0 + +Class QTextLayout + size=8 align=8 + base size=8 base align=8 +QTextLayout (0x0x7f31c21bf8a0) 0 + +Class QTextLine + size=16 align=8 + base size=16 base align=8 +QTextLine (0x0x7f31c1e75000) 0 + +Vtable for QAbstractUndoItem +QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractUndoItem) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAbstractUndoItem + size=8 align=8 + base size=8 base align=8 +QAbstractUndoItem (0x0x7f31c1e75480) 0 nearly-empty + vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16) + +Class QTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextDocument::QPrivateSignal (0x0x7f31c1e75720) 0 empty + +Vtable for QTextDocument +QTextDocument::_ZTV13QTextDocument: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QTextDocument) +16 (int (*)(...))QTextDocument::metaObject +24 (int (*)(...))QTextDocument::qt_metacast +32 (int (*)(...))QTextDocument::qt_metacall +40 (int (*)(...))QTextDocument::~QTextDocument +48 (int (*)(...))QTextDocument::~QTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextDocument::clear +120 (int (*)(...))QTextDocument::createObject +128 (int (*)(...))QTextDocument::loadResource + +Class QTextDocument + size=16 align=8 + base size=16 base align=8 +QTextDocument (0x0x7f31c1e741a0) 0 + vptr=((& QTextDocument::_ZTV13QTextDocument) + 16) + QObject (0x0x7f31c1e756c0) 0 + primary-for QTextDocument (0x0x7f31c1e741a0) + +Class QPalette::Data + size=4 align=4 + base size=4 base align=4 +QPalette::Data (0x0x7f31c1ee8720) 0 + +Class QPalette + size=16 align=8 + base size=12 base align=8 +QPalette (0x0x7f31c1ee86c0) 0 + +Class QAbstractTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTextDocumentLayout::QPrivateSignal (0x0x7f31c1bdaae0) 0 empty + +Class QAbstractTextDocumentLayout::Selection + size=24 align=8 + base size=24 base align=8 +QAbstractTextDocumentLayout::Selection (0x0x7f31c1bdab40) 0 + +Class QAbstractTextDocumentLayout::PaintContext + size=64 align=8 + base size=64 base align=8 +QAbstractTextDocumentLayout::PaintContext (0x0x7f31c1bdaba0) 0 + +Vtable for QAbstractTextDocumentLayout +QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout) +16 (int (*)(...))QAbstractTextDocumentLayout::metaObject +24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast +32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QAbstractTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QAbstractTextDocumentLayout (0x0x7f31c1bcff70) 0 + vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16) + QObject (0x0x7f31c1bdaa80) 0 + primary-for QAbstractTextDocumentLayout (0x0x7f31c1bcff70) + +Vtable for QTextObjectInterface +QTextObjectInterface::_ZTV20QTextObjectInterface: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextObjectInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QTextObjectInterface + size=8 align=8 + base size=8 base align=8 +QTextObjectInterface (0x0x7f31c1ca8780) 0 nearly-empty + vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16) + +Class QAccessible::State + size=8 align=8 + base size=5 base align=8 +QAccessible::State (0x0x7f31c1ca89c0) 0 + +Vtable for QAccessible::ActivationObserver +QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAccessible::ActivationObserver + size=8 align=8 + base size=8 base align=8 +QAccessible::ActivationObserver (0x0x7f31c1ca8a20) 0 nearly-empty + vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16) + +Class QAccessible + size=1 align=1 + base size=0 base align=1 +QAccessible (0x0x7f31c1ca8960) 0 empty + +Vtable for QAccessibleInterface +QAccessibleInterface::_ZTV20QAccessibleInterface: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAccessibleInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleInterface (0x0x7f31c1ce3600) 0 nearly-empty + vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16) + +Vtable for QAccessibleTextInterface +QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAccessibleTextInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset +104 (int (*)(...))QAccessibleTextInterface::textAfterOffset +112 (int (*)(...))QAccessibleTextInterface::textAtOffset +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTextInterface (0x0x7f31c1ce3960) 0 nearly-empty + vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16) + +Vtable for QAccessibleEditableTextInterface +QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleEditableTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleEditableTextInterface (0x0x7f31c1ce39c0) 0 nearly-empty + vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16) + +Vtable for QAccessibleValueInterface +QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleValueInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleValueInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleValueInterface (0x0x7f31c1ce3a20) 0 nearly-empty + vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16) + +Vtable for QAccessibleTableCellInterface +QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableCellInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableCellInterface (0x0x7f31c1ce3a80) 0 nearly-empty + vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16) + +Vtable for QAccessibleTableInterface +QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleTableInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableInterface (0x0x7f31c1ce3ae0) 0 nearly-empty + vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16) + +Vtable for QAccessibleActionInterface +QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleActionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QAccessibleActionInterface::localizedActionName +48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleActionInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleActionInterface (0x0x7f31c1ce3b40) 0 nearly-empty + vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16) + +Vtable for QAccessibleImageInterface +QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleImageInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleImageInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleImageInterface (0x0x7f31c1ce3c60) 0 nearly-empty + vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16) + +Vtable for QAccessibleEvent +QAccessibleEvent::_ZTV16QAccessibleEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAccessibleEvent) +16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleEvent + size=32 align=8 + base size=28 base align=8 +QAccessibleEvent (0x0x7f31c1ce3cc0) 0 + vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16) + +Vtable for QAccessibleStateChangeEvent +QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent) +16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleStateChangeEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleStateChangeEvent (0x0x7f31c1ce05b0) 0 + vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16) + QAccessibleEvent (0x0x7f31c1d476c0) 0 + primary-for QAccessibleStateChangeEvent (0x0x7f31c1ce05b0) + +Vtable for QAccessibleTextCursorEvent +QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent) +16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextCursorEvent + size=32 align=8 + base size=32 base align=8 +QAccessibleTextCursorEvent (0x0x7f31c1ce0618) 0 + vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16) + QAccessibleEvent (0x0x7f31c1d47a80) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f31c1ce0618) + +Vtable for QAccessibleTextSelectionEvent +QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent) +16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextSelectionEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleTextSelectionEvent (0x0x7f31c1ce0680) 0 + vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f31c1ce06e8) 0 + primary-for QAccessibleTextSelectionEvent (0x0x7f31c1ce0680) + QAccessibleEvent (0x0x7f31c1d47ea0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f31c1ce06e8) + +Vtable for QAccessibleTextInsertEvent +QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent) +16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextInsertEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextInsertEvent (0x0x7f31c1ce0750) 0 + vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f31c1ce07b8) 0 + primary-for QAccessibleTextInsertEvent (0x0x7f31c1ce0750) + QAccessibleEvent (0x0x7f31c1db7360) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f31c1ce07b8) + +Vtable for QAccessibleTextRemoveEvent +QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent) +16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextRemoveEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextRemoveEvent (0x0x7f31c1ce0820) 0 + vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f31c1ce0888) 0 + primary-for QAccessibleTextRemoveEvent (0x0x7f31c1ce0820) + QAccessibleEvent (0x0x7f31c1db7780) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f31c1ce0888) + +Vtable for QAccessibleTextUpdateEvent +QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent) +16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextUpdateEvent + size=56 align=8 + base size=56 base align=8 +QAccessibleTextUpdateEvent (0x0x7f31c1ce08f0) 0 + vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f31c1ce0958) 0 + primary-for QAccessibleTextUpdateEvent (0x0x7f31c1ce08f0) + QAccessibleEvent (0x0x7f31c1db7ba0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f31c1ce0958) + +Vtable for QAccessibleValueChangeEvent +QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent) +16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleValueChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleValueChangeEvent (0x0x7f31c1ce09c0) 0 + vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16) + QAccessibleEvent (0x0x7f31c19e4060) 0 + primary-for QAccessibleValueChangeEvent (0x0x7f31c1ce09c0) + +Vtable for QAccessibleTableModelChangeEvent +QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent) +16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTableModelChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTableModelChangeEvent (0x0x7f31c1ce0a28) 0 + vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16) + QAccessibleEvent (0x0x7f31c19e4480) 0 + primary-for QAccessibleTableModelChangeEvent (0x0x7f31c1ce0a28) + +Vtable for QAccessibleBridge +QAccessibleBridge::_ZTV17QAccessibleBridge: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleBridge) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridge + size=8 align=8 + base size=8 base align=8 +QAccessibleBridge (0x0x7f31c19e4d20) 0 nearly-empty + vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16) + +Class QAccessibleBridgePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessibleBridgePlugin::QPrivateSignal (0x0x7f31c1a14000) 0 empty + +Vtable for QAccessibleBridgePlugin +QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin) +16 (int (*)(...))QAccessibleBridgePlugin::metaObject +24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast +32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridgePlugin + size=16 align=8 + base size=16 base align=8 +QAccessibleBridgePlugin (0x0x7f31c1ce0a90) 0 + vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16) + QObject (0x0x7f31c19e4f60) 0 + primary-for QAccessibleBridgePlugin (0x0x7f31c1ce0a90) + +Vtable for QAccessibleObject +QAccessibleObject::_ZTV17QAccessibleObject: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleObject) +16 0 +24 0 +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleObject + size=16 align=8 + base size=16 base align=8 +QAccessibleObject (0x0x7f31c1ce0af8) 0 + vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16) + QAccessibleInterface (0x0x7f31c1a14120) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f31c1ce0af8) + +Vtable for QAccessibleApplication +QAccessibleApplication::_ZTV22QAccessibleApplication: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QAccessibleApplication) +16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleApplication::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleApplication::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleApplication::parent +88 (int (*)(...))QAccessibleApplication::child +96 (int (*)(...))QAccessibleApplication::childCount +104 (int (*)(...))QAccessibleApplication::indexOfChild +112 (int (*)(...))QAccessibleApplication::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))QAccessibleApplication::role +144 (int (*)(...))QAccessibleApplication::state +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleApplication + size=16 align=8 + base size=16 base align=8 +QAccessibleApplication (0x0x7f31c1ce0b60) 0 + vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16) + QAccessibleObject (0x0x7f31c1ce0bc8) 0 + primary-for QAccessibleApplication (0x0x7f31c1ce0b60) + QAccessibleInterface (0x0x7f31c1a14180) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f31c1ce0bc8) + +Class QAccessiblePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessiblePlugin::QPrivateSignal (0x0x7f31c1a14240) 0 empty + +Vtable for QAccessiblePlugin +QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessiblePlugin) +16 (int (*)(...))QAccessiblePlugin::metaObject +24 (int (*)(...))QAccessiblePlugin::qt_metacast +32 (int (*)(...))QAccessiblePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessiblePlugin + size=16 align=8 + base size=16 base align=8 +QAccessiblePlugin (0x0x7f31c1ce0c30) 0 + vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16) + QObject (0x0x7f31c1a141e0) 0 + primary-for QAccessiblePlugin (0x0x7f31c1ce0c30) + +Class QSurfaceFormat + size=8 align=8 + base size=8 base align=8 +QSurfaceFormat (0x0x7f31c1a14360) 0 + +Vtable for QSurface +QSurface::_ZTV8QSurface: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSurface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QSurface + size=24 align=8 + base size=24 base align=8 +QSurface (0x0x7f31c1a14ea0) 0 + vptr=((& QSurface::_ZTV8QSurface) + 16) + +Class QIcon + size=8 align=8 + base size=8 base align=8 +QIcon (0x0x7f31c1a852a0) 0 + +Class QCursor + size=8 align=8 + base size=8 base align=8 +QCursor (0x0x7f31c1b3fde0) 0 + +Class QWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWindow::QPrivateSignal (0x0x7f31c180aba0) 0 empty + +Vtable for QWindow +QWindow::_ZTV7QWindow: 45 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWindow) +16 (int (*)(...))QWindow::metaObject +24 (int (*)(...))QWindow::qt_metacast +32 (int (*)(...))QWindow::qt_metacall +40 (int (*)(...))QWindow::~QWindow +48 (int (*)(...))QWindow::~QWindow +56 (int (*)(...))QWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI7QWindow) +312 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev +320 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QWindow + size=40 align=8 + base size=40 base align=8 +QWindow (0x0x7f31c1810770) 0 + vptr=((& QWindow::_ZTV7QWindow) + 16) + QObject (0x0x7f31c180aae0) 0 + primary-for QWindow (0x0x7f31c1810770) + QSurface (0x0x7f31c180ab40) 16 + vptr=((& QWindow::_ZTV7QWindow) + 312) + +Class QBackingStore + size=8 align=8 + base size=8 base align=8 +QBackingStore (0x0x7f31c185b480) 0 + +Vtable for QBitmap +QBitmap::_ZTV7QBitmap: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBitmap) +16 (int (*)(...))QBitmap::~QBitmap +24 (int (*)(...))QBitmap::~QBitmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QBitmap + size=32 align=8 + base size=32 base align=8 +QBitmap (0x0x7f31c17fef08) 0 + vptr=((& QBitmap::_ZTV7QBitmap) + 16) + QPixmap (0x0x7f31c17fef70) 0 + primary-for QBitmap (0x0x7f31c17fef08) + QPaintDevice (0x0x7f31c185b540) 0 + primary-for QPixmap (0x0x7f31c17fef70) + +Class QClipboard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QClipboard::QPrivateSignal (0x0x7f31c18b3a80) 0 empty + +Vtable for QClipboard +QClipboard::_ZTV10QClipboard: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QClipboard) +16 (int (*)(...))QClipboard::metaObject +24 (int (*)(...))QClipboard::qt_metacast +32 (int (*)(...))QClipboard::qt_metacall +40 (int (*)(...))QClipboard::~QClipboard +48 (int (*)(...))QClipboard::~QClipboard +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QClipboard + size=16 align=8 + base size=16 base align=8 +QClipboard (0x0x7f31c18bb270) 0 + vptr=((& QClipboard::_ZTV10QClipboard) + 16) + QObject (0x0x7f31c18b3a20) 0 + primary-for QClipboard (0x0x7f31c18bb270) + +Class QColorTransform + size=8 align=8 + base size=8 base align=8 +QColorTransform (0x0x7f31c18b3ba0) 0 + +Class QColorSpace + size=8 align=8 + base size=8 base align=8 +QColorSpace (0x0x7f31c1978d20) 0 + +Class QDesktopServices + size=1 align=1 + base size=0 base align=1 +QDesktopServices (0x0x7f31c1650ae0) 0 empty + +Class QDrag::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDrag::QPrivateSignal (0x0x7f31c1650ba0) 0 empty + +Vtable for QDrag +QDrag::_ZTV5QDrag: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDrag) +16 (int (*)(...))QDrag::metaObject +24 (int (*)(...))QDrag::qt_metacast +32 (int (*)(...))QDrag::qt_metacall +40 (int (*)(...))QDrag::~QDrag +48 (int (*)(...))QDrag::~QDrag +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDrag + size=16 align=8 + base size=16 base align=8 +QDrag (0x0x7f31c164cf08) 0 + vptr=((& QDrag::_ZTV5QDrag) + 16) + QObject (0x0x7f31c1650b40) 0 + primary-for QDrag (0x0x7f31c164cf08) + +Class QFontInfo + size=8 align=8 + base size=8 base align=8 +QFontInfo (0x0x7f31c1650d80) 0 + +Class QFontMetrics + size=8 align=8 + base size=8 base align=8 +QFontMetrics (0x0x7f31c16a9de0) 0 + +Class QFontMetricsF + size=8 align=8 + base size=8 base align=8 +QFontMetricsF (0x0x7f31c1712180) 0 + +Class QGenericPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGenericPlugin::QPrivateSignal (0x0x7f31c147d300) 0 empty + +Vtable for QGenericPlugin +QGenericPlugin::_ZTV14QGenericPlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGenericPlugin) +16 (int (*)(...))QGenericPlugin::metaObject +24 (int (*)(...))QGenericPlugin::qt_metacast +32 (int (*)(...))QGenericPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGenericPlugin + size=16 align=8 + base size=16 base align=8 +QGenericPlugin (0x0x7f31c1758af8) 0 + vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16) + QObject (0x0x7f31c147d2a0) 0 + primary-for QGenericPlugin (0x0x7f31c1758af8) + +Class QGenericPluginFactory + size=1 align=1 + base size=0 base align=1 +QGenericPluginFactory (0x0x7f31c147d420) 0 empty + +Class QInputMethod::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputMethod::QPrivateSignal (0x0x7f31c147d4e0) 0 empty + +Vtable for QInputMethod +QInputMethod::_ZTV12QInputMethod: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputMethod) +16 (int (*)(...))QInputMethod::metaObject +24 (int (*)(...))QInputMethod::qt_metacast +32 (int (*)(...))QInputMethod::qt_metacall +40 (int (*)(...))QInputMethod::~QInputMethod +48 (int (*)(...))QInputMethod::~QInputMethod +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputMethod + size=16 align=8 + base size=16 base align=8 +QInputMethod (0x0x7f31c1758b60) 0 + vptr=((& QInputMethod::_ZTV12QInputMethod) + 16) + QObject (0x0x7f31c147d480) 0 + primary-for QInputMethod (0x0x7f31c1758b60) + +Class QGuiApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGuiApplication::QPrivateSignal (0x0x7f31c147d7e0) 0 empty + +Vtable for QGuiApplication +QGuiApplication::_ZTV15QGuiApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGuiApplication) +16 (int (*)(...))QGuiApplication::metaObject +24 (int (*)(...))QGuiApplication::qt_metacast +32 (int (*)(...))QGuiApplication::qt_metacall +40 (int (*)(...))QGuiApplication::~QGuiApplication +48 (int (*)(...))QGuiApplication::~QGuiApplication +56 (int (*)(...))QGuiApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGuiApplication::notify +120 (int (*)(...))QGuiApplication::compressEvent + +Class QGuiApplication + size=16 align=8 + base size=16 base align=8 +QGuiApplication (0x0x7f31c1758bc8) 0 + vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16) + QCoreApplication (0x0x7f31c1758c30) 0 + primary-for QGuiApplication (0x0x7f31c1758bc8) + QObject (0x0x7f31c147d780) 0 + primary-for QCoreApplication (0x0x7f31c1758c30) + +Class QIconEngine::AvailableSizesArgument + size=16 align=8 + base size=16 base align=8 +QIconEngine::AvailableSizesArgument (0x0x7f31c147df60) 0 + +Class QIconEngine::ScaledPixmapArgument + size=56 align=8 + base size=56 base align=8 +QIconEngine::ScaledPixmapArgument (0x0x7f31c14de120) 0 + +Vtable for QIconEngine +QIconEngine::_ZTV11QIconEngine: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QIconEngine) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QIconEngine::actualSize +48 (int (*)(...))QIconEngine::pixmap +56 (int (*)(...))QIconEngine::addPixmap +64 (int (*)(...))QIconEngine::addFile +72 (int (*)(...))QIconEngine::key +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QIconEngine::read +96 (int (*)(...))QIconEngine::write +104 (int (*)(...))QIconEngine::availableSizes +112 (int (*)(...))QIconEngine::iconName +120 (int (*)(...))QIconEngine::virtual_hook + +Class QIconEngine + size=8 align=8 + base size=8 base align=8 +QIconEngine (0x0x7f31c147df00) 0 nearly-empty + vptr=((& QIconEngine::_ZTV11QIconEngine) + 16) + +Class QIconEnginePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIconEnginePlugin::QPrivateSignal (0x0x7f31c14de1e0) 0 empty + +Vtable for QIconEnginePlugin +QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QIconEnginePlugin) +16 (int (*)(...))QIconEnginePlugin::metaObject +24 (int (*)(...))QIconEnginePlugin::qt_metacast +32 (int (*)(...))QIconEnginePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QIconEnginePlugin + size=16 align=8 + base size=16 base align=8 +QIconEnginePlugin (0x0x7f31c14cc208) 0 + vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16) + QObject (0x0x7f31c14de180) 0 + primary-for QIconEnginePlugin (0x0x7f31c14cc208) + +Vtable for QImageIOHandler +QImageIOHandler::_ZTV15QImageIOHandler: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QImageIOHandler) +16 0 +24 0 +32 (int (*)(...))QImageIOHandler::name +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QImageIOHandler::write +64 (int (*)(...))QImageIOHandler::option +72 (int (*)(...))QImageIOHandler::setOption +80 (int (*)(...))QImageIOHandler::supportsOption +88 (int (*)(...))QImageIOHandler::jumpToNextImage +96 (int (*)(...))QImageIOHandler::jumpToImage +104 (int (*)(...))QImageIOHandler::loopCount +112 (int (*)(...))QImageIOHandler::imageCount +120 (int (*)(...))QImageIOHandler::nextImageDelay +128 (int (*)(...))QImageIOHandler::currentImageNumber +136 (int (*)(...))QImageIOHandler::currentImageRect + +Class QImageIOHandler + size=16 align=8 + base size=16 base align=8 +QImageIOHandler (0x0x7f31c14de300) 0 + vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16) + +Class QImageIOPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QImageIOPlugin::QPrivateSignal (0x0x7f31c14de540) 0 empty + +Vtable for QImageIOPlugin +QImageIOPlugin::_ZTV14QImageIOPlugin: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QImageIOPlugin) +16 (int (*)(...))QImageIOPlugin::metaObject +24 (int (*)(...))QImageIOPlugin::qt_metacast +32 (int (*)(...))QImageIOPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QImageIOPlugin + size=16 align=8 + base size=16 base align=8 +QImageIOPlugin (0x0x7f31c14cc270) 0 + vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16) + QObject (0x0x7f31c14de4e0) 0 + primary-for QImageIOPlugin (0x0x7f31c14cc270) + +Class QImageReader + size=8 align=8 + base size=8 base align=8 +QImageReader (0x0x7f31c14ded20) 0 + +Class QImageWriter + size=8 align=8 + base size=8 base align=8 +QImageWriter (0x0x7f31c14dee40) 0 + +Class QVector3D + size=12 align=4 + base size=12 base align=4 +QVector3D (0x0x7f31c14def60) 0 + +Class QVector4D + size=16 align=4 + base size=16 base align=4 +QVector4D (0x0x7f31c118a120) 0 + +Class QQuaternion + size=16 align=4 + base size=16 base align=4 +QQuaternion (0x0x7f31c120a360) 0 + +Class QMatrix4x4 + size=68 align=4 + base size=68 base align=4 +QMatrix4x4 (0x0x7f31c129dc60) 0 + +Class QMovie::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMovie::QPrivateSignal (0x0x7f31c0f83ae0) 0 empty + +Vtable for QMovie +QMovie::_ZTV6QMovie: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QMovie) +16 (int (*)(...))QMovie::metaObject +24 (int (*)(...))QMovie::qt_metacast +32 (int (*)(...))QMovie::qt_metacall +40 (int (*)(...))QMovie::~QMovie +48 (int (*)(...))QMovie::~QMovie +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QMovie + size=16 align=8 + base size=16 base align=8 +QMovie (0x0x7f31c13269c0) 0 + vptr=((& QMovie::_ZTV6QMovie) + 16) + QObject (0x0x7f31c0f83a80) 0 + primary-for QMovie (0x0x7f31c13269c0) + +Class QOffscreenSurface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOffscreenSurface::QPrivateSignal (0x0x7f31c0f83f00) 0 empty + +Vtable for QOffscreenSurface +QOffscreenSurface::_ZTV17QOffscreenSurface: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOffscreenSurface) +16 (int (*)(...))QOffscreenSurface::metaObject +24 (int (*)(...))QOffscreenSurface::qt_metacast +32 (int (*)(...))QOffscreenSurface::qt_metacall +40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOffscreenSurface::surfaceType +120 (int (*)(...))QOffscreenSurface::format +128 (int (*)(...))QOffscreenSurface::size +136 (int (*)(...))QOffscreenSurface::surfaceHandle +144 (int (*)(...))-16 +152 (int (*)(...))(& _ZTI17QOffscreenSurface) +160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev +168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev +176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv +184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv +192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv +200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv + +Class QOffscreenSurface + size=40 align=8 + base size=40 base align=8 +QOffscreenSurface (0x0x7f31c133a770) 0 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16) + QObject (0x0x7f31c0f83e40) 0 + primary-for QOffscreenSurface (0x0x7f31c133a770) + QSurface (0x0x7f31c0f83ea0) 16 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160) + +Class QOpenGLBuffer + size=8 align=8 + base size=8 base align=8 +QOpenGLBuffer (0x0x7f31c1065180) 0 + +Class QOpenGLVersionStatus + size=12 align=4 + base size=12 base align=4 +QOpenGLVersionStatus (0x0x7f31c10659c0) 0 + +Class QOpenGLVersionFunctionsBackend + size=16 align=8 + base size=12 base align=8 +QOpenGLVersionFunctionsBackend (0x0x7f31c0d135a0) 0 + +Class QOpenGLVersionFunctionsStorage + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionFunctionsStorage (0x0x7f31c0d13780) 0 + +Class QAbstractOpenGLFunctionsPrivate + size=16 align=8 + base size=9 base align=8 +QAbstractOpenGLFunctionsPrivate (0x0x7f31c0d137e0) 0 + +Vtable for QAbstractOpenGLFunctions +QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions) +16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions + +Class QAbstractOpenGLFunctions + size=16 align=8 + base size=16 base align=8 +QAbstractOpenGLFunctions (0x0x7f31c0d139c0) 0 + vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16) + +Class QOpenGLFunctions_1_0_CoreBackend::Functions + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7f31c0d13ba0) 0 + +Class QOpenGLFunctions_1_0_CoreBackend + size=400 align=8 + base size=400 base align=8 +QOpenGLFunctions_1_0_CoreBackend (0x0x7f31c0d0f888) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0d13b40) 0 + +Class QOpenGLFunctions_1_1_CoreBackend::Functions + size=128 align=8 + base size=128 base align=8 +QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7f31c0d13ea0) 0 + +Class QOpenGLFunctions_1_1_CoreBackend + size=144 align=8 + base size=144 base align=8 +QOpenGLFunctions_1_1_CoreBackend (0x0x7f31c0d0f8f0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0d13e40) 0 + +Class QOpenGLFunctions_1_2_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7f31c09521e0) 0 + +Class QOpenGLFunctions_1_2_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_1_2_CoreBackend (0x0x7f31c0d0f958) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0952180) 0 + +Class QOpenGLFunctions_1_3_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7f31c09524e0) 0 + +Class QOpenGLFunctions_1_3_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_1_3_CoreBackend (0x0x7f31c0d0f9c0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0952480) 0 + +Class QOpenGLFunctions_1_4_CoreBackend::Functions + size=56 align=8 + base size=56 base align=8 +QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7f31c0952840) 0 + +Class QOpenGLFunctions_1_4_CoreBackend + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_4_CoreBackend (0x0x7f31c0d0fa28) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c09527e0) 0 + +Class QOpenGLFunctions_1_5_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7f31c0952b40) 0 + +Class QOpenGLFunctions_1_5_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_1_5_CoreBackend (0x0x7f31c0d0fa90) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0952ae0) 0 + +Class QOpenGLFunctions_2_0_CoreBackend::Functions + size=744 align=8 + base size=744 base align=8 +QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7f31c0952e40) 0 + +Class QOpenGLFunctions_2_0_CoreBackend + size=760 align=8 + base size=760 base align=8 +QOpenGLFunctions_2_0_CoreBackend (0x0x7f31c0d0faf8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0952de0) 0 + +Class QOpenGLFunctions_2_1_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7f31c0991180) 0 + +Class QOpenGLFunctions_2_1_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_2_1_CoreBackend (0x0x7f31c0d0fb60) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0991120) 0 + +Class QOpenGLFunctions_3_0_CoreBackend::Functions + size=672 align=8 + base size=672 base align=8 +QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7f31c0991480) 0 + +Class QOpenGLFunctions_3_0_CoreBackend + size=688 align=8 + base size=688 base align=8 +QOpenGLFunctions_3_0_CoreBackend (0x0x7f31c0d0fbc8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0991420) 0 + +Class QOpenGLFunctions_3_1_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7f31c0991780) 0 + +Class QOpenGLFunctions_3_1_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_3_1_CoreBackend (0x0x7f31c0d0fc30) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0991720) 0 + +Class QOpenGLFunctions_3_2_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7f31c0991a80) 0 + +Class QOpenGLFunctions_3_2_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_3_2_CoreBackend (0x0x7f31c0d0fc98) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0991a20) 0 + +Class QOpenGLFunctions_3_3_CoreBackend::Functions + size=464 align=8 + base size=464 base align=8 +QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7f31c0991d80) 0 + +Class QOpenGLFunctions_3_3_CoreBackend + size=480 align=8 + base size=480 base align=8 +QOpenGLFunctions_3_3_CoreBackend (0x0x7f31c0d0fd00) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0991d20) 0 + +Class QOpenGLFunctions_4_0_CoreBackend::Functions + size=368 align=8 + base size=368 base align=8 +QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7f31c09dd0c0) 0 + +Class QOpenGLFunctions_4_0_CoreBackend + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_4_0_CoreBackend (0x0x7f31c0d0fd68) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c09dd060) 0 + +Class QOpenGLFunctions_4_1_CoreBackend::Functions + size=704 align=8 + base size=704 base align=8 +QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7f31c09dd3c0) 0 + +Class QOpenGLFunctions_4_1_CoreBackend + size=720 align=8 + base size=720 base align=8 +QOpenGLFunctions_4_1_CoreBackend (0x0x7f31c0d0fdd0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c09dd360) 0 + +Class QOpenGLFunctions_4_2_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7f31c09dd6c0) 0 + +Class QOpenGLFunctions_4_2_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_2_CoreBackend (0x0x7f31c0d0fe38) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c09dd660) 0 + +Class QOpenGLFunctions_4_3_CoreBackend::Functions + size=344 align=8 + base size=344 base align=8 +QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7f31c09dd9c0) 0 + +Class QOpenGLFunctions_4_3_CoreBackend + size=360 align=8 + base size=360 base align=8 +QOpenGLFunctions_4_3_CoreBackend (0x0x7f31c0d0fea0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c09dd960) 0 + +Class QOpenGLFunctions_4_4_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7f31c09ddcc0) 0 + +Class QOpenGLFunctions_4_4_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_4_4_CoreBackend (0x0x7f31c0d0ff08) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c09ddc60) 0 + +Class QOpenGLFunctions_4_5_CoreBackend::Functions + size=848 align=8 + base size=848 base align=8 +QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7f31c0a2f060) 0 + +Class QOpenGLFunctions_4_5_CoreBackend + size=864 align=8 + base size=864 base align=8 +QOpenGLFunctions_4_5_CoreBackend (0x0x7f31c0d0ff70) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0a2f000) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions + size=2064 align=8 + base size=2064 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7f31c0a2f360) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend + size=2080 align=8 + base size=2080 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7f31c0a5a000) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0a2f300) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions + size=136 align=8 + base size=136 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7f31c0a2f660) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7f31c0a5a068) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0a2f600) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7f31c0a2f960) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend + size=272 align=8 + base size=272 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7f31c0a5a0d0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0a2f900) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions + size=296 align=8 + base size=296 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7f31c0a2fc60) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend + size=312 align=8 + base size=312 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7f31c0a5a138) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0a2fc00) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7f31c0a2ff60) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend + size=320 align=8 + base size=320 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7f31c0a5a1a0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0a2ff00) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions + size=288 align=8 + base size=288 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7f31c0ac32a0) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7f31c0a5a208) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0ac3240) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions + size=160 align=8 + base size=160 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7f31c0ac35a0) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend + size=176 align=8 + base size=176 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7f31c0a5a270) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0ac3540) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions + size=240 align=8 + base size=240 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7f31c0ac38a0) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7f31c0a5a2d8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0ac3840) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7f31c0ac3ba0) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7f31c0a5a340) 0 + QOpenGLVersionFunctionsBackend (0x0x7f31c0ac3b40) 0 + +Class QOpenGLVersionProfile + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionProfile (0x0x7f31c0ac3e40) 0 + +Class QOpenGLContextGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContextGroup::QPrivateSignal (0x0x7f31c0b01960) 0 empty + +Vtable for QOpenGLContextGroup +QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QOpenGLContextGroup) +16 (int (*)(...))QOpenGLContextGroup::metaObject +24 (int (*)(...))QOpenGLContextGroup::qt_metacast +32 (int (*)(...))QOpenGLContextGroup::qt_metacall +40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContextGroup + size=16 align=8 + base size=16 base align=8 +QOpenGLContextGroup (0x0x7f31c0a5ad68) 0 + vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16) + QObject (0x0x7f31c0b01900) 0 + primary-for QOpenGLContextGroup (0x0x7f31c0a5ad68) + +Class QOpenGLContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContext::QPrivateSignal (0x0x7f31c0b01ba0) 0 empty + +Vtable for QOpenGLContext +QOpenGLContext::_ZTV14QOpenGLContext: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QOpenGLContext) +16 (int (*)(...))QOpenGLContext::metaObject +24 (int (*)(...))QOpenGLContext::qt_metacast +32 (int (*)(...))QOpenGLContext::qt_metacall +40 (int (*)(...))QOpenGLContext::~QOpenGLContext +48 (int (*)(...))QOpenGLContext::~QOpenGLContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContext + size=16 align=8 + base size=16 base align=8 +QOpenGLContext (0x0x7f31c0a5add0) 0 + vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16) + QObject (0x0x7f31c0b01b40) 0 + primary-for QOpenGLContext (0x0x7f31c0a5add0) + +Class QOpenGLDebugMessage + size=8 align=8 + base size=8 base align=8 +QOpenGLDebugMessage (0x0x7f31c0b01de0) 0 + +Class QOpenGLDebugLogger::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLDebugLogger::QPrivateSignal (0x0x7f31c087e3c0) 0 empty + +Vtable for QOpenGLDebugLogger +QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger) +16 (int (*)(...))QOpenGLDebugLogger::metaObject +24 (int (*)(...))QOpenGLDebugLogger::qt_metacast +32 (int (*)(...))QOpenGLDebugLogger::qt_metacall +40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLDebugLogger + size=16 align=8 + base size=16 base align=8 +QOpenGLDebugLogger (0x0x7f31c0860068) 0 + vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16) + QObject (0x0x7f31c087e360) 0 + primary-for QOpenGLDebugLogger (0x0x7f31c0860068) + +Class QOpenGLFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLFunctions (0x0x7f31c087e840) 0 + +Class QOpenGLFunctionsPrivate::Functions + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate::Functions (0x0x7f31c090c1e0) 0 + +Class QOpenGLFunctionsPrivate + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate (0x0x7f31c090c180) 0 + +Class QOpenGLExtraFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLExtraFunctions (0x0x7f31c0860410) 0 + QOpenGLFunctions (0x0x7f31c05e4f60) 0 + +Class QOpenGLExtraFunctionsPrivate::Functions + size=1728 align=8 + base size=1728 base align=8 +QOpenGLExtraFunctionsPrivate::Functions (0x0x7f31c0669300) 0 + +Class QOpenGLExtraFunctionsPrivate + size=2880 align=8 + base size=2880 base align=8 +QOpenGLExtraFunctionsPrivate (0x0x7f31c0860478) 0 + QOpenGLFunctionsPrivate (0x0x7f31c06692a0) 0 + +Vtable for QOpenGLFramebufferObject +QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject) +16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject +24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject + +Class QOpenGLFramebufferObject + size=16 align=8 + base size=16 base align=8 +QOpenGLFramebufferObject (0x0x7f31c03b3d80) 0 + vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16) + +Class QOpenGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QOpenGLFramebufferObjectFormat (0x0x7f31c0405060) 0 + +Vtable for QOpenGLPaintDevice +QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice) +16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +32 (int (*)(...))QOpenGLPaintDevice::devType +40 (int (*)(...))QOpenGLPaintDevice::paintEngine +48 (int (*)(...))QOpenGLPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget + +Class QOpenGLPaintDevice + size=32 align=8 + base size=32 base align=8 +QOpenGLPaintDevice (0x0x7f31c03e2208) 0 + vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16) + QPaintDevice (0x0x7f31c04050c0) 0 + primary-for QOpenGLPaintDevice (0x0x7f31c03e2208) + +Class QOpenGLPixelTransferOptions + size=8 align=8 + base size=8 base align=8 +QOpenGLPixelTransferOptions (0x0x7f31c0405300) 0 + +Class QOpenGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShader::QPrivateSignal (0x0x7f31c0470120) 0 empty + +Vtable for QOpenGLShader +QOpenGLShader::_ZTV13QOpenGLShader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLShader) +16 (int (*)(...))QOpenGLShader::metaObject +24 (int (*)(...))QOpenGLShader::qt_metacast +32 (int (*)(...))QOpenGLShader::qt_metacall +40 (int (*)(...))QOpenGLShader::~QOpenGLShader +48 (int (*)(...))QOpenGLShader::~QOpenGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLShader + size=16 align=8 + base size=16 base align=8 +QOpenGLShader (0x0x7f31c046b340) 0 + vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16) + QObject (0x0x7f31c04700c0) 0 + primary-for QOpenGLShader (0x0x7f31c046b340) + +Class QOpenGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShaderProgram::QPrivateSignal (0x0x7f31c0470a20) 0 empty + +Vtable for QOpenGLShaderProgram +QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram) +16 (int (*)(...))QOpenGLShaderProgram::metaObject +24 (int (*)(...))QOpenGLShaderProgram::qt_metacast +32 (int (*)(...))QOpenGLShaderProgram::qt_metacall +40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOpenGLShaderProgram::link + +Class QOpenGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QOpenGLShaderProgram (0x0x7f31c046b478) 0 + vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16) + QObject (0x0x7f31c04709c0) 0 + primary-for QOpenGLShaderProgram (0x0x7f31c046b478) + +Class QOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QOpenGLTexture (0x0x7f31c0470c00) 0 + +Class QOpenGLTextureBlitter + size=8 align=8 + base size=8 base align=8 +QOpenGLTextureBlitter (0x0x7f31c0189120) 0 + +Class QOpenGLTimerQuery::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimerQuery::QPrivateSignal (0x0x7f31c0189360) 0 empty + +Vtable for QOpenGLTimerQuery +QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery) +16 (int (*)(...))QOpenGLTimerQuery::metaObject +24 (int (*)(...))QOpenGLTimerQuery::qt_metacast +32 (int (*)(...))QOpenGLTimerQuery::qt_metacall +40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimerQuery + size=16 align=8 + base size=16 base align=8 +QOpenGLTimerQuery (0x0x7f31c046b5b0) 0 + vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16) + QObject (0x0x7f31c0189300) 0 + primary-for QOpenGLTimerQuery (0x0x7f31c046b5b0) + +Class QOpenGLTimeMonitor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimeMonitor::QPrivateSignal (0x0x7f31c01895a0) 0 empty + +Vtable for QOpenGLTimeMonitor +QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor) +16 (int (*)(...))QOpenGLTimeMonitor::metaObject +24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast +32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall +40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimeMonitor + size=16 align=8 + base size=16 base align=8 +QOpenGLTimeMonitor (0x0x7f31c046b618) 0 + vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16) + QObject (0x0x7f31c0189540) 0 + primary-for QOpenGLTimeMonitor (0x0x7f31c046b618) + +Class QOpenGLVertexArrayObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLVertexArrayObject::QPrivateSignal (0x0x7f31c01897e0) 0 empty + +Class QOpenGLVertexArrayObject::Binder + size=8 align=8 + base size=8 base align=8 +QOpenGLVertexArrayObject::Binder (0x0x7f31c0189840) 0 + +Vtable for QOpenGLVertexArrayObject +QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject) +16 (int (*)(...))QOpenGLVertexArrayObject::metaObject +24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast +32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall +40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLVertexArrayObject + size=16 align=8 + base size=16 base align=8 +QOpenGLVertexArrayObject (0x0x7f31c046b680) 0 + vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16) + QObject (0x0x7f31c0189780) 0 + primary-for QOpenGLVertexArrayObject (0x0x7f31c046b680) + +Class QPaintDeviceWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPaintDeviceWindow::QPrivateSignal (0x0x7f31c0189f00) 0 empty + +Vtable for QPaintDeviceWindow +QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 58 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +16 (int (*)(...))QPaintDeviceWindow::metaObject +24 (int (*)(...))QPaintDeviceWindow::qt_metacast +32 (int (*)(...))QPaintDeviceWindow::qt_metacall +40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QPaintDeviceWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))-16 +328 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +336 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev +344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +384 (int (*)(...))-40 +392 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +400 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev +408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev +416 (int (*)(...))QPaintDevice::devType +424 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE +440 (int (*)(...))QPaintDevice::initPainter +448 (int (*)(...))QPaintDevice::redirected +456 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDeviceWindow + size=64 align=8 + base size=64 base align=8 +QPaintDeviceWindow (0x0x7f31c01ae7e0) 0 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16) + QWindow (0x0x7f31c01ae850) 0 + primary-for QPaintDeviceWindow (0x0x7f31c01ae7e0) + QObject (0x0x7f31c0189de0) 0 + primary-for QWindow (0x0x7f31c01ae850) + QSurface (0x0x7f31c0189e40) 16 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 336) + QPaintDevice (0x0x7f31c0189ea0) 40 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 400) + +Class QOpenGLWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWindow::QPrivateSignal (0x0x7f31c01e1240) 0 empty + +Vtable for QOpenGLWindow +QOpenGLWindow::_ZTV13QOpenGLWindow: 64 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWindow) +16 (int (*)(...))QOpenGLWindow::metaObject +24 (int (*)(...))QOpenGLWindow::qt_metacast +32 (int (*)(...))QOpenGLWindow::qt_metacall +40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QOpenGLWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QOpenGLWindow::paintEvent +304 (int (*)(...))QOpenGLWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QOpenGLWindow::initializeGL +328 (int (*)(...))QOpenGLWindow::resizeGL +336 (int (*)(...))QOpenGLWindow::paintGL +344 (int (*)(...))QOpenGLWindow::paintUnderGL +352 (int (*)(...))QOpenGLWindow::paintOverGL +360 (int (*)(...))QOpenGLWindow::redirected +368 (int (*)(...))-16 +376 (int (*)(...))(& _ZTI13QOpenGLWindow) +384 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev +392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev +400 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +408 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +416 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +424 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +432 (int (*)(...))-40 +440 (int (*)(...))(& _ZTI13QOpenGLWindow) +448 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev +456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev +464 (int (*)(...))QPaintDevice::devType +472 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +480 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QPaintDevice::initPainter +496 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint +504 (int (*)(...))QPaintDevice::sharedPainter + +Class QOpenGLWindow + size=64 align=8 + base size=64 base align=8 +QOpenGLWindow (0x0x7f31c046b750) 0 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16) + QPaintDeviceWindow (0x0x7f31c01aea10) 0 + primary-for QOpenGLWindow (0x0x7f31c046b750) + QWindow (0x0x7f31c01aea80) 0 + primary-for QPaintDeviceWindow (0x0x7f31c01aea10) + QObject (0x0x7f31c01e1120) 0 + primary-for QWindow (0x0x7f31c01aea80) + QSurface (0x0x7f31c01e1180) 16 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 384) + QPaintDevice (0x0x7f31c01e11e0) 40 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 448) + +Class QPageSize + size=8 align=8 + base size=8 base align=8 +QPageSize (0x0x7f31c01e1420) 0 + +Class QPageLayout + size=8 align=8 + base size=8 base align=8 +QPageLayout (0x0x7f31c02d7960) 0 + +Class QPagedPaintDevice::Margins + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice::Margins (0x0x7f31bffd3420) 0 + +Vtable for QPagedPaintDevice +QPagedPaintDevice::_ZTV17QPagedPaintDevice: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QPagedPaintDevice) +16 0 +24 0 +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QPagedPaintDevice::setPageSize +96 (int (*)(...))QPagedPaintDevice::setPageSizeMM +104 (int (*)(...))QPagedPaintDevice::setMargins + +Class QPagedPaintDevice + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice (0x0x7f31bffb6b60) 0 + vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16) + QPaintDevice (0x0x7f31bffd33c0) 0 + primary-for QPagedPaintDevice (0x0x7f31bffb6b60) + +Class QPainter::PixmapFragment + size=80 align=8 + base size=80 base align=8 +QPainter::PixmapFragment (0x0x7f31bffd34e0) 0 + +Class QPainter + size=8 align=8 + base size=8 base align=8 +QPainter (0x0x7f31bffd3480) 0 + +Class QTextItem + size=1 align=1 + base size=0 base align=1 +QTextItem (0x0x7f31cce6bcc0) 0 empty + +Vtable for QPaintEngine +QPaintEngine::_ZTV12QPaintEngine: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintEngine) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QPaintEngine::drawRects +64 (int (*)(...))QPaintEngine::drawRects +72 (int (*)(...))QPaintEngine::drawLines +80 (int (*)(...))QPaintEngine::drawLines +88 (int (*)(...))QPaintEngine::drawEllipse +96 (int (*)(...))QPaintEngine::drawEllipse +104 (int (*)(...))QPaintEngine::drawPath +112 (int (*)(...))QPaintEngine::drawPoints +120 (int (*)(...))QPaintEngine::drawPoints +128 (int (*)(...))QPaintEngine::drawPolygon +136 (int (*)(...))QPaintEngine::drawPolygon +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QPaintEngine::drawTextItem +160 (int (*)(...))QPaintEngine::drawTiledPixmap +168 (int (*)(...))QPaintEngine::drawImage +176 (int (*)(...))QPaintEngine::coordinateOffset +184 (int (*)(...))__cxa_pure_virtual + +Class QPaintEngine + size=32 align=8 + base size=32 base align=8 +QPaintEngine (0x0x7f31cc513f60) 0 + vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16) + +Class QPaintEngineState + size=4 align=4 + base size=4 base align=4 +QPaintEngineState (0x0x7f31cc603f60) 0 + +Class QPdfWriter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPdfWriter::QPrivateSignal (0x0x7f31cb56a9c0) 0 empty + +Vtable for QPdfWriter +QPdfWriter::_ZTV10QPdfWriter: 34 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QPdfWriter) +16 (int (*)(...))QPdfWriter::metaObject +24 (int (*)(...))QPdfWriter::qt_metacast +32 (int (*)(...))QPdfWriter::qt_metacall +40 (int (*)(...))QPdfWriter::~QPdfWriter +48 (int (*)(...))QPdfWriter::~QPdfWriter +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPdfWriter::newPage +120 (int (*)(...))QPdfWriter::setPageSize +128 (int (*)(...))QPdfWriter::setPageSizeMM +136 (int (*)(...))QPdfWriter::setMargins +144 (int (*)(...))QPdfWriter::paintEngine +152 (int (*)(...))QPdfWriter::metric +160 (int (*)(...))-16 +168 (int (*)(...))(& _ZTI10QPdfWriter) +176 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev +184 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev +192 (int (*)(...))QPaintDevice::devType +200 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv +208 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE +216 (int (*)(...))QPaintDevice::initPainter +224 (int (*)(...))QPaintDevice::redirected +232 (int (*)(...))QPaintDevice::sharedPainter +240 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv +248 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter11setPageSizeEN17QPagedPaintDevice8PageSizeE +256 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter13setPageSizeMMERK6QSizeF +264 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter10setMarginsERKN17QPagedPaintDevice7MarginsE + +Class QPdfWriter + size=48 align=8 + base size=48 base align=8 +QPdfWriter (0x0x7f31c55bc000) 0 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16) + QObject (0x0x7f31cb56a420) 0 + primary-for QPdfWriter (0x0x7f31c55bc000) + QPagedPaintDevice (0x0x7f31cc558b60) 16 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 176) + QPaintDevice (0x0x7f31cb56a960) 16 + primary-for QPagedPaintDevice (0x0x7f31cc558b60) + +Vtable for QPicture +QPicture::_ZTV8QPicture: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPicture) +16 (int (*)(...))QPicture::~QPicture +24 (int (*)(...))QPicture::~QPicture +32 (int (*)(...))QPicture::devType +40 (int (*)(...))QPicture::paintEngine +48 (int (*)(...))QPicture::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPicture::setData + +Class QPicture + size=32 align=8 + base size=32 base align=8 +QPicture (0x0x7f31cc558e38) 0 + vptr=((& QPicture::_ZTV8QPicture) + 16) + QPaintDevice (0x0x7f31cb250420) 0 + primary-for QPicture (0x0x7f31cc558e38) + +Class QPictureIO + size=8 align=8 + base size=8 base align=8 +QPictureIO (0x0x7f31c9706060) 0 + +Class QPictureFormatPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPictureFormatPlugin::QPrivateSignal (0x0x7f31c97061e0) 0 empty + +Vtable for QPictureFormatPlugin +QPictureFormatPlugin::_ZTV20QPictureFormatPlugin: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QPictureFormatPlugin) +16 (int (*)(...))QPictureFormatPlugin::metaObject +24 (int (*)(...))QPictureFormatPlugin::qt_metacast +32 (int (*)(...))QPictureFormatPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPictureFormatPlugin::loadPicture +120 (int (*)(...))QPictureFormatPlugin::savePicture +128 (int (*)(...))__cxa_pure_virtual + +Class QPictureFormatPlugin + size=16 align=8 + base size=16 base align=8 +QPictureFormatPlugin (0x0x7f31c96ebbc8) 0 + vptr=((& QPictureFormatPlugin::_ZTV20QPictureFormatPlugin) + 16) + QObject (0x0x7f31c97060c0) 0 + primary-for QPictureFormatPlugin (0x0x7f31c96ebbc8) + +Class QPixmapCache::Key + size=8 align=8 + base size=8 base align=8 +QPixmapCache::Key (0x0x7f31c9706f60) 0 + +Class QPixmapCache + size=1 align=1 + base size=0 base align=1 +QPixmapCache (0x0x7f31c97064e0) 0 empty + +Class QRasterWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRasterWindow::QPrivateSignal (0x0x7f31c834cba0) 0 empty + +Vtable for QRasterWindow +QRasterWindow::_ZTV13QRasterWindow: 59 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QRasterWindow) +16 (int (*)(...))QRasterWindow::metaObject +24 (int (*)(...))QRasterWindow::qt_metacast +32 (int (*)(...))QRasterWindow::qt_metacall +40 (int (*)(...))QRasterWindow::~QRasterWindow +48 (int (*)(...))QRasterWindow::~QRasterWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QRasterWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QRasterWindow::redirected +328 (int (*)(...))-16 +336 (int (*)(...))(& _ZTI13QRasterWindow) +344 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev +352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +392 (int (*)(...))-40 +400 (int (*)(...))(& _ZTI13QRasterWindow) +408 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev +416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev +424 (int (*)(...))QPaintDevice::devType +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +440 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE +448 (int (*)(...))QPaintDevice::initPainter +456 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint +464 (int (*)(...))QPaintDevice::sharedPainter + +Class QRasterWindow + size=64 align=8 + base size=64 base align=8 +QRasterWindow (0x0x7f31c7e455b0) 0 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16) + QPaintDeviceWindow (0x0x7f31cd66aa80) 0 + primary-for QRasterWindow (0x0x7f31c7e455b0) + QWindow (0x0x7f31cd66aaf0) 0 + primary-for QPaintDeviceWindow (0x0x7f31cd66aa80) + QObject (0x0x7f31c834c960) 0 + primary-for QWindow (0x0x7f31cd66aaf0) + QSurface (0x0x7f31c834ca80) 16 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 344) + QPaintDevice (0x0x7f31c834cae0) 40 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 408) + +Class QScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScreen::QPrivateSignal (0x0x7f31c83873c0) 0 empty + +Vtable for QScreen +QScreen::_ZTV7QScreen: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QScreen) +16 (int (*)(...))QScreen::metaObject +24 (int (*)(...))QScreen::qt_metacast +32 (int (*)(...))QScreen::qt_metacall +40 (int (*)(...))QScreen::~QScreen +48 (int (*)(...))QScreen::~QScreen +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScreen + size=16 align=8 + base size=16 base align=8 +QScreen (0x0x7f31c7e45958) 0 + vptr=((& QScreen::_ZTV7QScreen) + 16) + QObject (0x0x7f31c8387360) 0 + primary-for QScreen (0x0x7f31c7e45958) + +Class QSessionManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSessionManager::QPrivateSignal (0x0x7f31c8436d20) 0 empty + +Vtable for QSessionManager +QSessionManager::_ZTV15QSessionManager: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSessionManager) +16 (int (*)(...))QSessionManager::metaObject +24 (int (*)(...))QSessionManager::qt_metacast +32 (int (*)(...))QSessionManager::qt_metacall +40 (int (*)(...))QSessionManager::~QSessionManager +48 (int (*)(...))QSessionManager::~QSessionManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSessionManager + size=16 align=8 + base size=16 base align=8 +QSessionManager (0x0x7f31c7e459c0) 0 + vptr=((& QSessionManager::_ZTV15QSessionManager) + 16) + QObject (0x0x7f31c8436cc0) 0 + primary-for QSessionManager (0x0x7f31c7e459c0) + +Vtable for QStandardItem +QStandardItem::_ZTV13QStandardItem: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStandardItem) +16 (int (*)(...))QStandardItem::~QStandardItem +24 (int (*)(...))QStandardItem::~QStandardItem +32 (int (*)(...))QStandardItem::data +40 (int (*)(...))QStandardItem::setData +48 (int (*)(...))QStandardItem::clone +56 (int (*)(...))QStandardItem::type +64 (int (*)(...))QStandardItem::read +72 (int (*)(...))QStandardItem::write +80 (int (*)(...))QStandardItem::operator< + +Class QStandardItem + size=16 align=8 + base size=16 base align=8 +QStandardItem (0x0x7f31c80731e0) 0 + vptr=((& QStandardItem::_ZTV13QStandardItem) + 16) + +Class QStandardItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStandardItemModel::QPrivateSignal (0x0x7f31c7d39240) 0 empty + +Vtable for QStandardItemModel +QStandardItemModel::_ZTV18QStandardItemModel: 48 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QStandardItemModel) +16 (int (*)(...))QStandardItemModel::metaObject +24 (int (*)(...))QStandardItemModel::qt_metacast +32 (int (*)(...))QStandardItemModel::qt_metacall +40 (int (*)(...))QStandardItemModel::~QStandardItemModel +48 (int (*)(...))QStandardItemModel::~QStandardItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStandardItemModel::index +120 (int (*)(...))QStandardItemModel::parent +128 (int (*)(...))QStandardItemModel::sibling +136 (int (*)(...))QStandardItemModel::rowCount +144 (int (*)(...))QStandardItemModel::columnCount +152 (int (*)(...))QStandardItemModel::hasChildren +160 (int (*)(...))QStandardItemModel::data +168 (int (*)(...))QStandardItemModel::setData +176 (int (*)(...))QStandardItemModel::headerData +184 (int (*)(...))QStandardItemModel::setHeaderData +192 (int (*)(...))QStandardItemModel::itemData +200 (int (*)(...))QStandardItemModel::setItemData +208 (int (*)(...))QStandardItemModel::mimeTypes +216 (int (*)(...))QStandardItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QStandardItemModel::dropMimeData +240 (int (*)(...))QStandardItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStandardItemModel::insertRows +264 (int (*)(...))QStandardItemModel::insertColumns +272 (int (*)(...))QStandardItemModel::removeRows +280 (int (*)(...))QStandardItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStandardItemModel::flags +328 (int (*)(...))QStandardItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStandardItemModel + size=16 align=8 + base size=16 base align=8 +QStandardItemModel (0x0x7f31c78d1208) 0 + vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16) + QAbstractItemModel (0x0x7f31c78d1270) 0 + primary-for QStandardItemModel (0x0x7f31c78d1208) + QObject (0x0x7f31c7d391e0) 0 + primary-for QAbstractItemModel (0x0x7f31c78d1270) + +Class QStaticText + size=8 align=8 + base size=8 base align=8 +QStaticText (0x0x7f31c7d7b840) 0 + +Class QStyleHints::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyleHints::QPrivateSignal (0x0x7f31c6ef57e0) 0 empty + +Vtable for QStyleHints +QStyleHints::_ZTV11QStyleHints: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QStyleHints) +16 (int (*)(...))QStyleHints::metaObject +24 (int (*)(...))QStyleHints::qt_metacast +32 (int (*)(...))QStyleHints::qt_metacall +40 (int (*)(...))QStyleHints::~QStyleHints +48 (int (*)(...))QStyleHints::~QStyleHints +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QStyleHints + size=16 align=8 + base size=16 base align=8 +QStyleHints (0x0x7f31c69288f0) 0 + vptr=((& QStyleHints::_ZTV11QStyleHints) + 16) + QObject (0x0x7f31c6ef5780) 0 + primary-for QStyleHints (0x0x7f31c69288f0) + +Class QTextObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextObject::QPrivateSignal (0x0x7f31c6f81960) 0 empty + +Vtable for QTextObject +QTextObject::_ZTV11QTextObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextObject) +16 (int (*)(...))QTextObject::metaObject +24 (int (*)(...))QTextObject::qt_metacast +32 (int (*)(...))QTextObject::qt_metacall +40 (int (*)(...))QTextObject::~QTextObject +48 (int (*)(...))QTextObject::~QTextObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextObject + size=16 align=8 + base size=16 base align=8 +QTextObject (0x0x7f31c6928958) 0 + vptr=((& QTextObject::_ZTV11QTextObject) + 16) + QObject (0x0x7f31c6f81780) 0 + primary-for QTextObject (0x0x7f31c6928958) + +Class QTextBlockGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBlockGroup::QPrivateSignal (0x0x7f31c6fa7c00) 0 empty + +Vtable for QTextBlockGroup +QTextBlockGroup::_ZTV15QTextBlockGroup: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTextBlockGroup) +16 (int (*)(...))QTextBlockGroup::metaObject +24 (int (*)(...))QTextBlockGroup::qt_metacast +32 (int (*)(...))QTextBlockGroup::qt_metacall +40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextBlockGroup + size=16 align=8 + base size=16 base align=8 +QTextBlockGroup (0x0x7f31c6954410) 0 + vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16) + QTextObject (0x0x7f31c6954478) 0 + primary-for QTextBlockGroup (0x0x7f31c6954410) + QObject (0x0x7f31c6fa7b40) 0 + primary-for QTextObject (0x0x7f31c6954478) + +Vtable for QTextFrameLayoutData +QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextFrameLayoutData) +16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData +24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData + +Class QTextFrameLayoutData + size=8 align=8 + base size=8 base align=8 +QTextFrameLayoutData (0x0x7f31c6fc17e0) 0 nearly-empty + vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16) + +Class QTextFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextFrame::QPrivateSignal (0x0x7f31c6fc1a20) 0 empty + +Class QTextFrame::iterator + size=32 align=8 + base size=28 base align=8 +QTextFrame::iterator (0x0x7f31c6fe2a80) 0 + +Vtable for QTextFrame +QTextFrame::_ZTV10QTextFrame: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextFrame) +16 (int (*)(...))QTextFrame::metaObject +24 (int (*)(...))QTextFrame::qt_metacast +32 (int (*)(...))QTextFrame::qt_metacall +40 (int (*)(...))QTextFrame::~QTextFrame +48 (int (*)(...))QTextFrame::~QTextFrame +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextFrame + size=16 align=8 + base size=16 base align=8 +QTextFrame (0x0x7f31c6954888) 0 + vptr=((& QTextFrame::_ZTV10QTextFrame) + 16) + QTextObject (0x0x7f31c69548f0) 0 + primary-for QTextFrame (0x0x7f31c6954888) + QObject (0x0x7f31c6fc19c0) 0 + primary-for QTextObject (0x0x7f31c69548f0) + +Vtable for QTextBlockUserData +QTextBlockUserData::_ZTV18QTextBlockUserData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTextBlockUserData) +16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData +24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData + +Class QTextBlockUserData + size=8 align=8 + base size=8 base align=8 +QTextBlockUserData (0x0x7f31c670db40) 0 nearly-empty + vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16) + +Class QTextBlock::iterator + size=24 align=8 + base size=20 base align=8 +QTextBlock::iterator (0x0x7f31c670dde0) 0 + +Class QTextBlock + size=16 align=8 + base size=12 base align=8 +QTextBlock (0x0x7f31c670dc00) 0 + +Class QTextFragment + size=16 align=8 + base size=16 base align=8 +QTextFragment (0x0x7f31c5dddcc0) 0 + +Class QSyntaxHighlighter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSyntaxHighlighter::QPrivateSignal (0x0x7f31c4fd5ae0) 0 empty + +Vtable for QSyntaxHighlighter +QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSyntaxHighlighter) +16 (int (*)(...))QSyntaxHighlighter::metaObject +24 (int (*)(...))QSyntaxHighlighter::qt_metacast +32 (int (*)(...))QSyntaxHighlighter::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSyntaxHighlighter + size=16 align=8 + base size=16 base align=8 +QSyntaxHighlighter (0x0x7f31c40f42d8) 0 + vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16) + QObject (0x0x7f31c4fd5360) 0 + primary-for QSyntaxHighlighter (0x0x7f31c40f42d8) + +Class QTextDocumentFragment + size=8 align=8 + base size=8 base align=8 +QTextDocumentFragment (0x0x7f31c4ff0060) 0 + +Class QTextDocumentWriter + size=8 align=8 + base size=8 base align=8 +QTextDocumentWriter (0x0x7f31c4ff04e0) 0 + +Class QTextList::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextList::QPrivateSignal (0x0x7f31c4ff0600) 0 empty + +Vtable for QTextList +QTextList::_ZTV9QTextList: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextList) +16 (int (*)(...))QTextList::metaObject +24 (int (*)(...))QTextList::qt_metacast +32 (int (*)(...))QTextList::qt_metacall +40 (int (*)(...))QTextList::~QTextList +48 (int (*)(...))QTextList::~QTextList +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextList + size=16 align=8 + base size=16 base align=8 +QTextList (0x0x7f31c423b270) 0 + vptr=((& QTextList::_ZTV9QTextList) + 16) + QTextBlockGroup (0x0x7f31c423b2d8) 0 + primary-for QTextList (0x0x7f31c423b270) + QTextObject (0x0x7f31c423b340) 0 + primary-for QTextBlockGroup (0x0x7f31c423b2d8) + QObject (0x0x7f31c4ff0540) 0 + primary-for QTextObject (0x0x7f31c423b340) + +Class QTextTableCell + size=16 align=8 + base size=12 base align=8 +QTextTableCell (0x0x7f31c50459c0) 0 + +Class QTextTable::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextTable::QPrivateSignal (0x0x7f31c4e383c0) 0 empty + +Vtable for QTextTable +QTextTable::_ZTV10QTextTable: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextTable) +16 (int (*)(...))QTextTable::metaObject +24 (int (*)(...))QTextTable::qt_metacast +32 (int (*)(...))QTextTable::qt_metacall +40 (int (*)(...))QTextTable::~QTextTable +48 (int (*)(...))QTextTable::~QTextTable +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextTable + size=16 align=8 + base size=16 base align=8 +QTextTable (0x0x7f31c423b3a8) 0 + vptr=((& QTextTable::_ZTV10QTextTable) + 16) + QTextFrame (0x0x7f31c423b478) 0 + primary-for QTextTable (0x0x7f31c423b3a8) + QTextObject (0x0x7f31c423b4e0) 0 + primary-for QTextFrame (0x0x7f31c423b478) + QObject (0x0x7f31c4e1dd20) 0 + primary-for QTextObject (0x0x7f31c423b4e0) + +Class QValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QValidator::QPrivateSignal (0x0x7f31c4c1b180) 0 empty + +Vtable for QValidator +QValidator::_ZTV10QValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QValidator) +16 (int (*)(...))QValidator::metaObject +24 (int (*)(...))QValidator::qt_metacast +32 (int (*)(...))QValidator::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QValidator::fixup + +Class QValidator + size=16 align=8 + base size=16 base align=8 +QValidator (0x0x7f31c423b548) 0 + vptr=((& QValidator::_ZTV10QValidator) + 16) + QObject (0x0x7f31c4c1b0c0) 0 + primary-for QValidator (0x0x7f31c423b548) + +Class QIntValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIntValidator::QPrivateSignal (0x0x7f31c49a20c0) 0 empty + +Vtable for QIntValidator +QIntValidator::_ZTV13QIntValidator: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QIntValidator) +16 (int (*)(...))QIntValidator::metaObject +24 (int (*)(...))QIntValidator::qt_metacast +32 (int (*)(...))QIntValidator::qt_metacall +40 (int (*)(...))QIntValidator::~QIntValidator +48 (int (*)(...))QIntValidator::~QIntValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIntValidator::validate +120 (int (*)(...))QIntValidator::fixup +128 (int (*)(...))QIntValidator::setRange + +Class QIntValidator + size=24 align=8 + base size=24 base align=8 +QIntValidator (0x0x7f31c423b5b0) 0 + vptr=((& QIntValidator::_ZTV13QIntValidator) + 16) + QValidator (0x0x7f31c423b750) 0 + primary-for QIntValidator (0x0x7f31c423b5b0) + QObject (0x0x7f31c496acc0) 0 + primary-for QValidator (0x0x7f31c423b750) + +Class QDoubleValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleValidator::QPrivateSignal (0x0x7f31c49e8de0) 0 empty + +Vtable for QDoubleValidator +QDoubleValidator::_ZTV16QDoubleValidator: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDoubleValidator) +16 (int (*)(...))QDoubleValidator::metaObject +24 (int (*)(...))QDoubleValidator::qt_metacast +32 (int (*)(...))QDoubleValidator::qt_metacall +40 (int (*)(...))QDoubleValidator::~QDoubleValidator +48 (int (*)(...))QDoubleValidator::~QDoubleValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDoubleValidator::validate +120 (int (*)(...))QValidator::fixup +128 (int (*)(...))QDoubleValidator::setRange + +Class QDoubleValidator + size=40 align=8 + base size=36 base align=8 +QDoubleValidator (0x0x7f31c423b7b8) 0 + vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16) + QValidator (0x0x7f31c423b8f0) 0 + primary-for QDoubleValidator (0x0x7f31c423b7b8) + QObject (0x0x7f31c49a2780) 0 + primary-for QValidator (0x0x7f31c423b8f0) + +Class QRegExpValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegExpValidator::QPrivateSignal (0x0x7f31c4821000) 0 empty + +Vtable for QRegExpValidator +QRegExpValidator::_ZTV16QRegExpValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QRegExpValidator) +16 (int (*)(...))QRegExpValidator::metaObject +24 (int (*)(...))QRegExpValidator::qt_metacast +32 (int (*)(...))QRegExpValidator::qt_metacall +40 (int (*)(...))QRegExpValidator::~QRegExpValidator +48 (int (*)(...))QRegExpValidator::~QRegExpValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegExpValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegExpValidator + size=24 align=8 + base size=24 base align=8 +QRegExpValidator (0x0x7f31c423ba90) 0 + vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16) + QValidator (0x0x7f31c423bb60) 0 + primary-for QRegExpValidator (0x0x7f31c423ba90) + QObject (0x0x7f31c47e14e0) 0 + primary-for QValidator (0x0x7f31c423bb60) + +Class QRegularExpressionValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegularExpressionValidator::QPrivateSignal (0x0x7f31c448aea0) 0 empty + +Vtable for QRegularExpressionValidator +QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QRegularExpressionValidator) +16 (int (*)(...))QRegularExpressionValidator::metaObject +24 (int (*)(...))QRegularExpressionValidator::qt_metacast +32 (int (*)(...))QRegularExpressionValidator::qt_metacall +40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegularExpressionValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegularExpressionValidator + size=16 align=8 + base size=16 base align=8 +QRegularExpressionValidator (0x0x7f31c423bbc8) 0 + vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16) + QValidator (0x0x7f31c423bd00) 0 + primary-for QRegularExpressionValidator (0x0x7f31c423bbc8) + QObject (0x0x7f31c448ae40) 0 + primary-for QValidator (0x0x7f31c423bd00) + +Class QNetworkRequest + size=8 align=8 + base size=8 base align=8 +QNetworkRequest (0x0x7f31c44e1780) 0 + +Class QNetworkCacheMetaData + size=8 align=8 + base size=8 base align=8 +QNetworkCacheMetaData (0x0x7f31c34c74e0) 0 + +Class QAbstractNetworkCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractNetworkCache::QPrivateSignal (0x0x7f31c288a300) 0 empty + +Vtable for QAbstractNetworkCache +QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractNetworkCache) +16 (int (*)(...))QAbstractNetworkCache::metaObject +24 (int (*)(...))QAbstractNetworkCache::qt_metacast +32 (int (*)(...))QAbstractNetworkCache::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNetworkCache + size=16 align=8 + base size=16 base align=8 +QAbstractNetworkCache (0x0x7f31c2225dd0) 0 + vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16) + QObject (0x0x7f31c288a2a0) 0 + primary-for QAbstractNetworkCache (0x0x7f31c2225dd0) + +Class QAbstractSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSocket::QPrivateSignal (0x0x7f31c28a5d20) 0 empty + +Vtable for QAbstractSocket +QAbstractSocket::_ZTV15QAbstractSocket: 41 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSocket) +16 (int (*)(...))QAbstractSocket::metaObject +24 (int (*)(...))QAbstractSocket::qt_metacast +32 (int (*)(...))QAbstractSocket::qt_metacall +40 (int (*)(...))QAbstractSocket::~QAbstractSocket +48 (int (*)(...))QAbstractSocket::~QAbstractSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QAbstractSocket + size=16 align=8 + base size=16 base align=8 +QAbstractSocket (0x0x7f31c2237138) 0 + vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16) + QIODevice (0x0x7f31c22371a0) 0 + primary-for QAbstractSocket (0x0x7f31c2237138) + QObject (0x0x7f31c28a50c0) 0 + primary-for QIODevice (0x0x7f31c22371a0) + +Class QAuthenticator + size=8 align=8 + base size=8 base align=8 +QAuthenticator (0x0x7f31c242bba0) 0 + +Class QDnsDomainNameRecord + size=8 align=8 + base size=8 base align=8 +QDnsDomainNameRecord (0x0x7f31c24be000) 0 + +Class QDnsHostAddressRecord + size=8 align=8 + base size=8 base align=8 +QDnsHostAddressRecord (0x0x7f31c1b3f000) 0 + +Class QDnsMailExchangeRecord + size=8 align=8 + base size=8 base align=8 +QDnsMailExchangeRecord (0x0x7f31c07f2600) 0 + +Class QDnsServiceRecord + size=8 align=8 + base size=8 base align=8 +QDnsServiceRecord (0x0x7f31cb810780) 0 + +Class QDnsTextRecord + size=8 align=8 + base size=8 base align=8 +QDnsTextRecord (0x0x7f31cb395660) 0 + +Class QDnsLookup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDnsLookup::QPrivateSignal (0x0x7f31c9b786c0) 0 empty + +Vtable for QDnsLookup +QDnsLookup::_ZTV10QDnsLookup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDnsLookup) +16 (int (*)(...))QDnsLookup::metaObject +24 (int (*)(...))QDnsLookup::qt_metacast +32 (int (*)(...))QDnsLookup::qt_metacall +40 (int (*)(...))QDnsLookup::~QDnsLookup +48 (int (*)(...))QDnsLookup::~QDnsLookup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDnsLookup + size=16 align=8 + base size=16 base align=8 +QDnsLookup (0x0x7f31c9e18b60) 0 + vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16) + QObject (0x0x7f31c9b78660) 0 + primary-for QDnsLookup (0x0x7f31c9e18b60) + +Class QTcpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpSocket::QPrivateSignal (0x0x7f31c9b78a80) 0 empty + +Vtable for QTcpSocket +QTcpSocket::_ZTV10QTcpSocket: 41 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpSocket) +16 (int (*)(...))QTcpSocket::metaObject +24 (int (*)(...))QTcpSocket::qt_metacast +32 (int (*)(...))QTcpSocket::qt_metacall +40 (int (*)(...))QTcpSocket::~QTcpSocket +48 (int (*)(...))QTcpSocket::~QTcpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QTcpSocket + size=16 align=8 + base size=16 base align=8 +QTcpSocket (0x0x7f31c9e18bc8) 0 + vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16) + QAbstractSocket (0x0x7f31c9e18c30) 0 + primary-for QTcpSocket (0x0x7f31c9e18bc8) + QIODevice (0x0x7f31c9e18c98) 0 + primary-for QAbstractSocket (0x0x7f31c9e18c30) + QObject (0x0x7f31c9b78a20) 0 + primary-for QIODevice (0x0x7f31c9e18c98) + +Class QSslCertificate + size=8 align=8 + base size=8 base align=8 +QSslCertificate (0x0x7f31c8b59360) 0 + +Class QSslError + size=8 align=8 + base size=8 base align=8 +QSslError (0x0x7f31c7d9eba0) 0 + +Class QSslSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSslSocket::QPrivateSignal (0x0x7f31c6925e40) 0 empty + +Vtable for QSslSocket +QSslSocket::_ZTV10QSslSocket: 41 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSslSocket) +16 (int (*)(...))QSslSocket::metaObject +24 (int (*)(...))QSslSocket::qt_metacast +32 (int (*)(...))QSslSocket::qt_metacall +40 (int (*)(...))QSslSocket::~QSslSocket +48 (int (*)(...))QSslSocket::~QSslSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QSslSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QSslSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QSslSocket::bytesAvailable +184 (int (*)(...))QSslSocket::bytesToWrite +192 (int (*)(...))QSslSocket::canReadLine +200 (int (*)(...))QSslSocket::waitForReadyRead +208 (int (*)(...))QSslSocket::waitForBytesWritten +216 (int (*)(...))QSslSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QSslSocket::writeData +240 (int (*)(...))QSslSocket::resume +248 (int (*)(...))QSslSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QSslSocket::disconnectFromHost +272 (int (*)(...))QSslSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QSslSocket::setSocketDescriptor +296 (int (*)(...))QSslSocket::setSocketOption +304 (int (*)(...))QSslSocket::socketOption +312 (int (*)(...))QSslSocket::waitForConnected +320 (int (*)(...))QSslSocket::waitForDisconnected + +Class QSslSocket + size=16 align=8 + base size=16 base align=8 +QSslSocket (0x0x7f31c698e958) 0 + vptr=((& QSslSocket::_ZTV10QSslSocket) + 16) + QTcpSocket (0x0x7f31c698e9c0) 0 + primary-for QSslSocket (0x0x7f31c698e958) + QAbstractSocket (0x0x7f31c698ea28) 0 + primary-for QTcpSocket (0x0x7f31c698e9c0) + QIODevice (0x0x7f31c698ea90) 0 + primary-for QAbstractSocket (0x0x7f31c698ea28) + QObject (0x0x7f31c6925de0) 0 + primary-for QIODevice (0x0x7f31c698ea90) + +Class QDtlsClientVerifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtlsClientVerifier::QPrivateSignal (0x0x7f31c5bdd0c0) 0 empty + +Class QDtlsClientVerifier::GeneratorParameters + size=16 align=8 + base size=16 base align=8 +QDtlsClientVerifier::GeneratorParameters (0x0x7f31c5bdd120) 0 + +Vtable for QDtlsClientVerifier +QDtlsClientVerifier::_ZTV19QDtlsClientVerifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QDtlsClientVerifier) +16 (int (*)(...))QDtlsClientVerifier::metaObject +24 (int (*)(...))QDtlsClientVerifier::qt_metacast +32 (int (*)(...))QDtlsClientVerifier::qt_metacall +40 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +48 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtlsClientVerifier + size=16 align=8 + base size=16 base align=8 +QDtlsClientVerifier (0x0x7f31c698eaf8) 0 + vptr=((& QDtlsClientVerifier::_ZTV19QDtlsClientVerifier) + 16) + QObject (0x0x7f31c5bdd060) 0 + primary-for QDtlsClientVerifier (0x0x7f31c698eaf8) + +Class QDtls::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtls::QPrivateSignal (0x0x7f31c5bdd360) 0 empty + +Vtable for QDtls +QDtls::_ZTV5QDtls: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDtls) +16 (int (*)(...))QDtls::metaObject +24 (int (*)(...))QDtls::qt_metacast +32 (int (*)(...))QDtls::qt_metacall +40 (int (*)(...))QDtls::~QDtls +48 (int (*)(...))QDtls::~QDtls +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtls + size=16 align=8 + base size=16 base align=8 +QDtls (0x0x7f31c698eb60) 0 + vptr=((& QDtls::_ZTV5QDtls) + 16) + QObject (0x0x7f31c5bdd300) 0 + primary-for QDtls (0x0x7f31c698eb60) + +Class QIPv6Address + size=16 align=1 + base size=16 base align=1 +QIPv6Address (0x0x7f31c5bdd5a0) 0 + +Class QHostAddress + size=8 align=8 + base size=8 base align=8 +QHostAddress (0x0x7f31c5bdd6c0) 0 + +Class QHostInfo + size=8 align=8 + base size=8 base align=8 +QHostInfo (0x0x7f31c34e1480) 0 + +Class QHstsPolicy + size=8 align=8 + base size=8 base align=8 +QHstsPolicy (0x0x7f31c2a2cb40) 0 + +Class QHttp2Configuration + size=8 align=8 + base size=8 base align=8 +QHttp2Configuration (0x0x7f31c158e2a0) 0 + +Class QHttpPart + size=8 align=8 + base size=8 base align=8 +QHttpPart (0x0x7f31c12d57e0) 0 + +Class QHttpMultiPart::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHttpMultiPart::QPrivateSignal (0x0x7f31c0525480) 0 empty + +Vtable for QHttpMultiPart +QHttpMultiPart::_ZTV14QHttpMultiPart: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QHttpMultiPart) +16 (int (*)(...))QHttpMultiPart::metaObject +24 (int (*)(...))QHttpMultiPart::qt_metacast +32 (int (*)(...))QHttpMultiPart::qt_metacall +40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QHttpMultiPart + size=16 align=8 + base size=16 base align=8 +QHttpMultiPart (0x0x7f31c05382d8) 0 + vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16) + QObject (0x0x7f31c0525420) 0 + primary-for QHttpMultiPart (0x0x7f31c05382d8) + +Class QLocalServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalServer::QPrivateSignal (0x0x7f31c05256c0) 0 empty + +Vtable for QLocalServer +QLocalServer::_ZTV12QLocalServer: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalServer) +16 (int (*)(...))QLocalServer::metaObject +24 (int (*)(...))QLocalServer::qt_metacast +32 (int (*)(...))QLocalServer::qt_metacall +40 (int (*)(...))QLocalServer::~QLocalServer +48 (int (*)(...))QLocalServer::~QLocalServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalServer::hasPendingConnections +120 (int (*)(...))QLocalServer::nextPendingConnection +128 (int (*)(...))QLocalServer::incomingConnection + +Class QLocalServer + size=16 align=8 + base size=16 base align=8 +QLocalServer (0x0x7f31c0538340) 0 + vptr=((& QLocalServer::_ZTV12QLocalServer) + 16) + QObject (0x0x7f31c0525660) 0 + primary-for QLocalServer (0x0x7f31c0538340) + +Class QLocalSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalSocket::QPrivateSignal (0x0x7f31c53f0180) 0 empty + +Vtable for QLocalSocket +QLocalSocket::_ZTV12QLocalSocket: 30 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalSocket) +16 (int (*)(...))QLocalSocket::metaObject +24 (int (*)(...))QLocalSocket::qt_metacast +32 (int (*)(...))QLocalSocket::qt_metacall +40 (int (*)(...))QLocalSocket::~QLocalSocket +48 (int (*)(...))QLocalSocket::~QLocalSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalSocket::isSequential +120 (int (*)(...))QLocalSocket::open +128 (int (*)(...))QLocalSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QLocalSocket::bytesAvailable +184 (int (*)(...))QLocalSocket::bytesToWrite +192 (int (*)(...))QLocalSocket::canReadLine +200 (int (*)(...))QLocalSocket::waitForReadyRead +208 (int (*)(...))QLocalSocket::waitForBytesWritten +216 (int (*)(...))QLocalSocket::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QLocalSocket::writeData + +Class QLocalSocket + size=16 align=8 + base size=16 base align=8 +QLocalSocket (0x0x7f31c05384e0) 0 + vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16) + QIODevice (0x0x7f31c0538548) 0 + primary-for QLocalSocket (0x0x7f31c05384e0) + QObject (0x0x7f31c53f0120) 0 + primary-for QIODevice (0x0x7f31c0538548) + +Class QSslConfiguration + size=8 align=8 + base size=8 base align=8 +QSslConfiguration (0x0x7f31c53f0360) 0 + +Class QSslPreSharedKeyAuthenticator + size=8 align=8 + base size=8 base align=8 +QSslPreSharedKeyAuthenticator (0x0x7f31c0de7840) 0 + +Class QNetworkAccessManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkAccessManager::QPrivateSignal (0x0x7f31c0e96ea0) 0 empty + +Vtable for QNetworkAccessManager +QNetworkAccessManager::_ZTV21QNetworkAccessManager: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QNetworkAccessManager) +16 (int (*)(...))QNetworkAccessManager::metaObject +24 (int (*)(...))QNetworkAccessManager::qt_metacast +32 (int (*)(...))QNetworkAccessManager::qt_metacall +40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkAccessManager::createRequest + +Class QNetworkAccessManager + size=16 align=8 + base size=16 base align=8 +QNetworkAccessManager (0x0x7f31c0ea5a28) 0 + vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16) + QObject (0x0x7f31c0e96e40) 0 + primary-for QNetworkAccessManager (0x0x7f31c0ea5a28) + +Class QNetworkConfiguration + size=8 align=8 + base size=8 base align=8 +QNetworkConfiguration (0x0x7f31c0ed5180) 0 + +Class QNetworkConfigurationManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkConfigurationManager::QPrivateSignal (0x0x7f31c0b7e540) 0 empty + +Vtable for QNetworkConfigurationManager +QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QNetworkConfigurationManager) +16 (int (*)(...))QNetworkConfigurationManager::metaObject +24 (int (*)(...))QNetworkConfigurationManager::qt_metacast +32 (int (*)(...))QNetworkConfigurationManager::qt_metacall +40 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager +48 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QNetworkConfigurationManager + size=16 align=8 + base size=16 base align=8 +QNetworkConfigurationManager (0x0x7f31c0b70d00) 0 + vptr=((& QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager) + 16) + QObject (0x0x7f31c0b7e4e0) 0 + primary-for QNetworkConfigurationManager (0x0x7f31c0b70d00) + +Class QNetworkCookie + size=8 align=8 + base size=8 base align=8 +QNetworkCookie (0x0x7f31c0bc90c0) 0 + +Class QNetworkCookieJar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkCookieJar::QPrivateSignal (0x0x7f31c0c746c0) 0 empty + +Vtable for QNetworkCookieJar +QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkCookieJar) +16 (int (*)(...))QNetworkCookieJar::metaObject +24 (int (*)(...))QNetworkCookieJar::qt_metacast +32 (int (*)(...))QNetworkCookieJar::qt_metacall +40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkCookieJar::cookiesForUrl +120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl +128 (int (*)(...))QNetworkCookieJar::insertCookie +136 (int (*)(...))QNetworkCookieJar::updateCookie +144 (int (*)(...))QNetworkCookieJar::deleteCookie +152 (int (*)(...))QNetworkCookieJar::validateCookie + +Class QNetworkCookieJar + size=16 align=8 + base size=16 base align=8 +QNetworkCookieJar (0x0x7f31c0c67f70) 0 + vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16) + QObject (0x0x7f31c0c74660) 0 + primary-for QNetworkCookieJar (0x0x7f31c0c67f70) + +Class QNetworkDatagram + size=8 align=8 + base size=8 base align=8 +QNetworkDatagram (0x0x7f31c0c748a0) 0 + +Class QNetworkDiskCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkDiskCache::QPrivateSignal (0x0x7f31c0a3c420) 0 empty + +Vtable for QNetworkDiskCache +QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkDiskCache) +16 (int (*)(...))QNetworkDiskCache::metaObject +24 (int (*)(...))QNetworkDiskCache::qt_metacast +32 (int (*)(...))QNetworkDiskCache::qt_metacall +40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkDiskCache::metaData +120 (int (*)(...))QNetworkDiskCache::updateMetaData +128 (int (*)(...))QNetworkDiskCache::data +136 (int (*)(...))QNetworkDiskCache::remove +144 (int (*)(...))QNetworkDiskCache::cacheSize +152 (int (*)(...))QNetworkDiskCache::prepare +160 (int (*)(...))QNetworkDiskCache::insert +168 (int (*)(...))QNetworkDiskCache::clear +176 (int (*)(...))QNetworkDiskCache::expire + +Class QNetworkDiskCache + size=16 align=8 + base size=16 base align=8 +QNetworkDiskCache (0x0x7f31c0a20e38) 0 + vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16) + QAbstractNetworkCache (0x0x7f31c0a20ea0) 0 + primary-for QNetworkDiskCache (0x0x7f31c0a20e38) + QObject (0x0x7f31c0a3c3c0) 0 + primary-for QAbstractNetworkCache (0x0x7f31c0a20ea0) + +Class QNetworkAddressEntry + size=8 align=8 + base size=8 base align=8 +QNetworkAddressEntry (0x0x7f31c0a3c600) 0 + +Class QNetworkInterface + size=8 align=8 + base size=8 base align=8 +QNetworkInterface (0x0x7f31c09245a0) 0 + +Class QNetworkProxyQuery + size=8 align=8 + base size=8 base align=8 +QNetworkProxyQuery (0x0x7f31ccd9f0c0) 0 + +Class QNetworkProxy + size=8 align=8 + base size=8 base align=8 +QNetworkProxy (0x0x7f31ca1ae3c0) 0 + +Vtable for QNetworkProxyFactory +QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QNetworkProxyFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNetworkProxyFactory + size=8 align=8 + base size=8 base align=8 +QNetworkProxyFactory (0x0x7f31c89f7c00) 0 nearly-empty + vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16) + +Class QNetworkReply::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkReply::QPrivateSignal (0x0x7f31c89f7ea0) 0 empty + +Vtable for QNetworkReply +QNetworkReply::_ZTV13QNetworkReply: 36 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QNetworkReply) +16 (int (*)(...))QNetworkReply::metaObject +24 (int (*)(...))QNetworkReply::qt_metacast +32 (int (*)(...))QNetworkReply::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkReply::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QNetworkReply::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QNetworkReply::writeData +240 (int (*)(...))QNetworkReply::setReadBufferSize +248 (int (*)(...))__cxa_pure_virtual +256 (int (*)(...))QNetworkReply::ignoreSslErrors +264 (int (*)(...))QNetworkReply::sslConfigurationImplementation +272 (int (*)(...))QNetworkReply::setSslConfigurationImplementation +280 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation + +Class QNetworkReply + size=16 align=8 + base size=16 base align=8 +QNetworkReply (0x0x7f31c86e12d8) 0 + vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16) + QIODevice (0x0x7f31c86e1340) 0 + primary-for QNetworkReply (0x0x7f31c86e12d8) + QObject (0x0x7f31c89f7e40) 0 + primary-for QIODevice (0x0x7f31c86e1340) + +Class QNetworkSession::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkSession::QPrivateSignal (0x0x7f31c803d3c0) 0 empty + +Vtable for QNetworkSession +QNetworkSession::_ZTV15QNetworkSession: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QNetworkSession) +16 (int (*)(...))QNetworkSession::metaObject +24 (int (*)(...))QNetworkSession::qt_metacast +32 (int (*)(...))QNetworkSession::qt_metacall +40 (int (*)(...))QNetworkSession::~QNetworkSession +48 (int (*)(...))QNetworkSession::~QNetworkSession +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QNetworkSession::connectNotify +104 (int (*)(...))QNetworkSession::disconnectNotify + +Class QNetworkSession + size=24 align=8 + base size=24 base align=8 +QNetworkSession (0x0x7f31c86e13a8) 0 + vptr=((& QNetworkSession::_ZTV15QNetworkSession) + 16) + QObject (0x0x7f31c803d360) 0 + primary-for QNetworkSession (0x0x7f31c86e13a8) + +Class QOcspResponse + size=8 align=8 + base size=8 base align=8 +QOcspResponse (0x0x7f31c803dc00) 0 + +Class QTcpServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpServer::QPrivateSignal (0x0x7f31c75d8480) 0 empty + +Vtable for QTcpServer +QTcpServer::_ZTV10QTcpServer: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpServer) +16 (int (*)(...))QTcpServer::metaObject +24 (int (*)(...))QTcpServer::qt_metacast +32 (int (*)(...))QTcpServer::qt_metacall +40 (int (*)(...))QTcpServer::~QTcpServer +48 (int (*)(...))QTcpServer::~QTcpServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTcpServer::hasPendingConnections +120 (int (*)(...))QTcpServer::nextPendingConnection +128 (int (*)(...))QTcpServer::incomingConnection + +Class QTcpServer + size=16 align=8 + base size=16 base align=8 +QTcpServer (0x0x7f31c74eac30) 0 + vptr=((& QTcpServer::_ZTV10QTcpServer) + 16) + QObject (0x0x7f31c75d8420) 0 + primary-for QTcpServer (0x0x7f31c74eac30) + +Class QSslCertificateExtension + size=8 align=8 + base size=8 base align=8 +QSslCertificateExtension (0x0x7f31c75d8660) 0 + +Class QSslCipher + size=8 align=8 + base size=8 base align=8 +QSslCipher (0x0x7f31c6529600) 0 + +Class QSslDiffieHellmanParameters + size=8 align=8 + base size=8 base align=8 +QSslDiffieHellmanParameters (0x0x7f31c4e366c0) 0 + +Class QSslEllipticCurve + size=4 align=4 + base size=4 base align=4 +QSslEllipticCurve (0x0x7f31c3f77420) 0 + +Class QSslKey + size=8 align=8 + base size=8 base align=8 +QSslKey (0x0x7f31c39eed80) 0 + +Class QUdpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUdpSocket::QPrivateSignal (0x0x7f31c29b4c60) 0 empty + +Vtable for QUdpSocket +QUdpSocket::_ZTV10QUdpSocket: 41 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUdpSocket) +16 (int (*)(...))QUdpSocket::metaObject +24 (int (*)(...))QUdpSocket::qt_metacast +32 (int (*)(...))QUdpSocket::qt_metacall +40 (int (*)(...))QUdpSocket::~QUdpSocket +48 (int (*)(...))QUdpSocket::~QUdpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QUdpSocket + size=16 align=8 + base size=16 base align=8 +QUdpSocket (0x0x7f31c26b1208) 0 + vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16) + QAbstractSocket (0x0x7f31c26b1270) 0 + primary-for QUdpSocket (0x0x7f31c26b1208) + QIODevice (0x0x7f31c26b12d8) 0 + primary-for QAbstractSocket (0x0x7f31c26b1270) + QObject (0x0x7f31c29b4c00) 0 + primary-for QIODevice (0x0x7f31c26b12d8) + +Class QJSValue + size=8 align=8 + base size=8 base align=8 +QJSValue (0x0x7f31c29b4ea0) 0 + +Class QQmlDebuggingEnabler + size=1 align=1 + base size=0 base align=1 +QQmlDebuggingEnabler (0x0x7f31c22d0420) 0 empty + +Class QJSEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QJSEngine::QPrivateSignal (0x0x7f31c22d04e0) 0 empty + +Vtable for QJSEngine +QJSEngine::_ZTV9QJSEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QJSEngine) +16 (int (*)(...))QJSEngine::metaObject +24 (int (*)(...))QJSEngine::qt_metacast +32 (int (*)(...))QJSEngine::qt_metacall +40 (int (*)(...))QJSEngine::~QJSEngine +48 (int (*)(...))QJSEngine::~QJSEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QJSEngine + size=24 align=8 + base size=24 base align=8 +QJSEngine (0x0x7f31c26b13a8) 0 + vptr=((& QJSEngine::_ZTV9QJSEngine) + 16) + QObject (0x0x7f31c22d0480) 0 + primary-for QJSEngine (0x0x7f31c26b13a8) + +Class QJSValueIterator + size=8 align=8 + base size=8 base align=8 +QJSValueIterator (0x0x7f31c1b76060) 0 + +Class QQmlPrivate::RegisterType + size=128 align=8 + base size=124 base align=8 +QQmlPrivate::RegisterType (0x0x7f31c1b76c00) 0 + +Class QQmlPrivate::RegisterInterface + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::RegisterInterface (0x0x7f31c1b76c60) 0 + +Class QQmlPrivate::RegisterAutoParent + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterAutoParent (0x0x7f31c1b76cc0) 0 + +Class QQmlPrivate::RegisterSingletonType + size=96 align=8 + base size=96 base align=8 +QQmlPrivate::RegisterSingletonType (0x0x7f31c1b76d20) 0 + +Class QQmlPrivate::RegisterCompositeType + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::RegisterCompositeType (0x0x7f31c1b76f00) 0 + +Class QQmlPrivate::RegisterCompositeSingletonType + size=32 align=8 + base size=32 base align=8 +QQmlPrivate::RegisterCompositeSingletonType (0x0x7f31c1b76f60) 0 + +Class QQmlPrivate::CachedQmlUnit + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::CachedQmlUnit (0x0x7f31c125b000) 0 + +Class QQmlPrivate::RegisterQmlUnitCacheHook + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterQmlUnitCacheHook (0x0x7f31c125b060) 0 + +Class QQmlPrivate::RegisterSingletonFunctor + size=24 align=8 + base size=17 base align=8 +QQmlPrivate::RegisterSingletonFunctor (0x0x7f31c125b0c0) 0 + +Vtable for QQmlParserStatus +QQmlParserStatus::_ZTV16QQmlParserStatus: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlParserStatus) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlParserStatus + size=16 align=8 + base size=16 base align=8 +QQmlParserStatus (0x0x7f31c125b480) 0 + vptr=((& QQmlParserStatus::_ZTV16QQmlParserStatus) + 16) + +Vtable for QQmlPropertyValueSource +QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQmlPropertyValueSource) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlPropertyValueSource + size=8 align=8 + base size=8 base align=8 +QQmlPropertyValueSource (0x0x7f31c125b660) 0 nearly-empty + vptr=((& QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource) + 16) + +Class QQmlListReference + size=8 align=8 + base size=8 base align=8 +QQmlListReference (0x0x7f31c125bc00) 0 + +Vtable for QQmlAbstractUrlInterceptor +QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QQmlAbstractUrlInterceptor) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlAbstractUrlInterceptor + size=8 align=8 + base size=8 base align=8 +QQmlAbstractUrlInterceptor (0x0x7f31cb002420) 0 nearly-empty + vptr=((& QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor) + 16) + +Class QQmlError + size=8 align=8 + base size=8 base align=8 +QQmlError (0x0x7f31cb002480) 0 + +Vtable for QQmlImageProviderBase +QQmlImageProviderBase::_ZTV21QQmlImageProviderBase: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlImageProviderBase) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlImageProviderBase + size=8 align=8 + base size=8 base align=8 +QQmlImageProviderBase (0x0x7f31c95173c0) 0 nearly-empty + vptr=((& QQmlImageProviderBase::_ZTV21QQmlImageProviderBase) + 16) + +Class QQmlEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngine::QPrivateSignal (0x0x7f31c9517b40) 0 empty + +Vtable for QQmlEngine +QQmlEngine::_ZTV10QQmlEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQmlEngine) +16 (int (*)(...))QQmlEngine::metaObject +24 (int (*)(...))QQmlEngine::qt_metacast +32 (int (*)(...))QQmlEngine::qt_metacall +40 (int (*)(...))QQmlEngine::~QQmlEngine +48 (int (*)(...))QQmlEngine::~QQmlEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlEngine + size=24 align=8 + base size=24 base align=8 +QQmlEngine (0x0x7f31c96fedd0) 0 + vptr=((& QQmlEngine::_ZTV10QQmlEngine) + 16) + QJSEngine (0x0x7f31c96fee38) 0 + primary-for QQmlEngine (0x0x7f31c96fedd0) + QObject (0x0x7f31c9517ae0) 0 + primary-for QJSEngine (0x0x7f31c96fee38) + +Class QQmlApplicationEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlApplicationEngine::QPrivateSignal (0x0x7f31c9517de0) 0 empty + +Vtable for QQmlApplicationEngine +QQmlApplicationEngine::_ZTV21QQmlApplicationEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlApplicationEngine) +16 (int (*)(...))QQmlApplicationEngine::metaObject +24 (int (*)(...))QQmlApplicationEngine::qt_metacast +32 (int (*)(...))QQmlApplicationEngine::qt_metacall +40 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +48 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlApplicationEngine + size=24 align=8 + base size=24 base align=8 +QQmlApplicationEngine (0x0x7f31c96feea0) 0 + vptr=((& QQmlApplicationEngine::_ZTV21QQmlApplicationEngine) + 16) + QQmlEngine (0x0x7f31c96fef08) 0 + primary-for QQmlApplicationEngine (0x0x7f31c96feea0) + QJSEngine (0x0x7f31c96fef70) 0 + primary-for QQmlEngine (0x0x7f31c96fef08) + QObject (0x0x7f31c9517d80) 0 + primary-for QJSEngine (0x0x7f31c96fef70) + +Class QQmlComponent::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlComponent::QPrivateSignal (0x0x7f31c89d8060) 0 empty + +Vtable for QQmlComponent +QQmlComponent::_ZTV13QQmlComponent: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlComponent) +16 (int (*)(...))QQmlComponent::metaObject +24 (int (*)(...))QQmlComponent::qt_metacast +32 (int (*)(...))QQmlComponent::qt_metacall +40 (int (*)(...))QQmlComponent::~QQmlComponent +48 (int (*)(...))QQmlComponent::~QQmlComponent +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlComponent::create +120 (int (*)(...))QQmlComponent::beginCreate +128 (int (*)(...))QQmlComponent::completeCreate + +Class QQmlComponent + size=16 align=8 + base size=16 base align=8 +QQmlComponent (0x0x7f31c89b6000) 0 + vptr=((& QQmlComponent::_ZTV13QQmlComponent) + 16) + QObject (0x0x7f31c89d8000) 0 + primary-for QQmlComponent (0x0x7f31c89b6000) + +Class QQmlContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlContext::QPrivateSignal (0x0x7f31c89d8d20) 0 empty + +Class QQmlContext::PropertyPair + size=24 align=8 + base size=24 base align=8 +QQmlContext::PropertyPair (0x0x7f31c89d8d80) 0 + +Vtable for QQmlContext +QQmlContext::_ZTV11QQmlContext: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QQmlContext) +16 (int (*)(...))QQmlContext::metaObject +24 (int (*)(...))QQmlContext::qt_metacast +32 (int (*)(...))QQmlContext::qt_metacall +40 (int (*)(...))QQmlContext::~QQmlContext +48 (int (*)(...))QQmlContext::~QQmlContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlContext + size=16 align=8 + base size=16 base align=8 +QQmlContext (0x0x7f31c89b6548) 0 + vptr=((& QQmlContext::_ZTV11QQmlContext) + 16) + QObject (0x0x7f31c89d8cc0) 0 + primary-for QQmlContext (0x0x7f31c89b6548) + +Class QQmlScriptString + size=8 align=8 + base size=8 base align=8 +QQmlScriptString (0x0x7f31c7dde180) 0 + +Class QQmlExpression::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExpression::QPrivateSignal (0x0x7f31c7dde480) 0 empty + +Vtable for QQmlExpression +QQmlExpression::_ZTV14QQmlExpression: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QQmlExpression) +16 (int (*)(...))QQmlExpression::metaObject +24 (int (*)(...))QQmlExpression::qt_metacast +32 (int (*)(...))QQmlExpression::qt_metacall +40 (int (*)(...))QQmlExpression::~QQmlExpression +48 (int (*)(...))QQmlExpression::~QQmlExpression +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlExpression + size=16 align=8 + base size=16 base align=8 +QQmlExpression (0x0x7f31c89b65b0) 0 + vptr=((& QQmlExpression::_ZTV14QQmlExpression) + 16) + QObject (0x0x7f31c7dde420) 0 + primary-for QQmlExpression (0x0x7f31c89b65b0) + +Vtable for QQmlTypesExtensionInterface +QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QQmlTypesExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlTypesExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlTypesExtensionInterface (0x0x7f31c7dde660) 0 nearly-empty + vptr=((& QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface) + 16) + +Vtable for QQmlExtensionInterface +QQmlExtensionInterface::_ZTV22QQmlExtensionInterface: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QQmlExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlExtensionInterface (0x0x7f31c89b6618) 0 nearly-empty + vptr=((& QQmlExtensionInterface::_ZTV22QQmlExtensionInterface) + 16) + QQmlTypesExtensionInterface (0x0x7f31c7dde6c0) 0 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f31c89b6618) + +Class QQmlExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExtensionPlugin::QPrivateSignal (0x0x7f31c7ddeae0) 0 empty + +Vtable for QQmlExtensionPlugin +QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +16 (int (*)(...))QQmlExtensionPlugin::metaObject +24 (int (*)(...))QQmlExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlExtensionPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQmlExtensionPlugin::initializeEngine +128 (int (*)(...))-16 +136 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +144 0 +152 0 +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QQmlExtensionPlugin::_ZThn16_N19QQmlExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlExtensionPlugin (0x0x7f31c53c4ee0) 0 + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 16) + QObject (0x0x7f31c7ddea20) 0 + primary-for QQmlExtensionPlugin (0x0x7f31c53c4ee0) + QQmlExtensionInterface (0x0x7f31c89b6680) 16 nearly-empty + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 144) + QQmlTypesExtensionInterface (0x0x7f31c7ddea80) 16 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f31c89b6680) + +Class QQmlFile + size=8 align=8 + base size=8 base align=8 +QQmlFile (0x0x7f31c7ddecc0) 0 + +Class QQmlFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlFileSelector::QPrivateSignal (0x0x7f31c7dded80) 0 empty + +Vtable for QQmlFileSelector +QQmlFileSelector::_ZTV16QQmlFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlFileSelector) +16 (int (*)(...))QQmlFileSelector::metaObject +24 (int (*)(...))QQmlFileSelector::qt_metacast +32 (int (*)(...))QQmlFileSelector::qt_metacall +40 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +48 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlFileSelector + size=16 align=8 + base size=16 base align=8 +QQmlFileSelector (0x0x7f31c89b6750) 0 + vptr=((& QQmlFileSelector::_ZTV16QQmlFileSelector) + 16) + QObject (0x0x7f31c7dded20) 0 + primary-for QQmlFileSelector (0x0x7f31c89b6750) + +Vtable for QQmlIncubator +QQmlIncubator::_ZTV13QQmlIncubator: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlIncubator) +16 (int (*)(...))QQmlIncubator::~QQmlIncubator +24 (int (*)(...))QQmlIncubator::~QQmlIncubator +32 (int (*)(...))QQmlIncubator::statusChanged +40 (int (*)(...))QQmlIncubator::setInitialState + +Class QQmlIncubator + size=16 align=8 + base size=16 base align=8 +QQmlIncubator (0x0x7f31c7ddef60) 0 + vptr=((& QQmlIncubator::_ZTV13QQmlIncubator) + 16) + +Vtable for QQmlIncubationController +QQmlIncubationController::_ZTV24QQmlIncubationController: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQmlIncubationController) +16 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +24 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +32 (int (*)(...))QQmlIncubationController::incubatingObjectCountChanged + +Class QQmlIncubationController + size=16 align=8 + base size=16 base align=8 +QQmlIncubationController (0x0x7f31c6bf3000) 0 + vptr=((& QQmlIncubationController::_ZTV24QQmlIncubationController) + 16) + +Class QQmlInfo + size=16 align=8 + base size=16 base align=8 +QQmlInfo (0x0x7f31c89b67b8) 0 + QDebug (0x0x7f31c6bf3060) 0 + +Vtable for QQmlNetworkAccessManagerFactory +QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI31QQmlNetworkAccessManagerFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlNetworkAccessManagerFactory + size=8 align=8 + base size=8 base align=8 +QQmlNetworkAccessManagerFactory (0x0x7f31c64cb000) 0 nearly-empty + vptr=((& QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory) + 16) + +Class QQmlProperty + size=8 align=8 + base size=8 base align=8 +QQmlProperty (0x0x7f31c64cb060) 0 + +Class QQmlPropertyMap::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlPropertyMap::QPrivateSignal (0x0x7f31c53918a0) 0 empty + +Vtable for QQmlPropertyMap +QQmlPropertyMap::_ZTV15QQmlPropertyMap: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQmlPropertyMap) +16 (int (*)(...))QQmlPropertyMap::metaObject +24 (int (*)(...))QQmlPropertyMap::qt_metacast +32 (int (*)(...))QQmlPropertyMap::qt_metacall +40 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +48 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlPropertyMap::updateValue + +Class QQmlPropertyMap + size=16 align=8 + base size=16 base align=8 +QQmlPropertyMap (0x0x7f31c5baddd0) 0 + vptr=((& QQmlPropertyMap::_ZTV15QQmlPropertyMap) + 16) + QObject (0x0x7f31c5391840) 0 + primary-for QQmlPropertyMap (0x0x7f31c5baddd0) + +Class QQuickTransform::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTransform::QPrivateSignal (0x0x7f31c5391b40) 0 empty + +Vtable for QQuickTransform +QQuickTransform::_ZTV15QQuickTransform: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQuickTransform) +16 (int (*)(...))QQuickTransform::metaObject +24 (int (*)(...))QQuickTransform::qt_metacast +32 (int (*)(...))QQuickTransform::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QQuickTransform + size=16 align=8 + base size=16 base align=8 +QQuickTransform (0x0x7f31c5bade38) 0 + vptr=((& QQuickTransform::_ZTV15QQuickTransform) + 16) + QObject (0x0x7f31c5391ae0) 0 + primary-for QQuickTransform (0x0x7f31c5bade38) + +Class QQuickItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItem::QPrivateSignal (0x0x7f31c5391de0) 0 empty + +Class QQuickItem::ItemChangeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::ItemChangeData (0x0x7f31c5391e40) 0 + +Class QQuickItem::UpdatePaintNodeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::UpdatePaintNodeData (0x0x7f31c5391ea0) 0 + +Vtable for QQuickItem +QQuickItem::_ZTV10QQuickItem: 55 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickItem) +16 (int (*)(...))QQuickItem::metaObject +24 (int (*)(...))QQuickItem::qt_metacast +32 (int (*)(...))QQuickItem::qt_metacall +40 (int (*)(...))QQuickItem::~QQuickItem +48 (int (*)(...))QQuickItem::~QQuickItem +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickItem::isTextureProvider +152 (int (*)(...))QQuickItem::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickItem::geometryChanged +368 (int (*)(...))QQuickItem::updatePaintNode +376 (int (*)(...))QQuickItem::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))-16 +400 (int (*)(...))(& _ZTI10QQuickItem) +408 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD1Ev +416 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD0Ev +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickItem + size=32 align=8 + base size=32 base align=8 +QQuickItem (0x0x7f31c4c4f150) 0 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 16) + QObject (0x0x7f31c5391d20) 0 + primary-for QQuickItem (0x0x7f31c4c4f150) + QQmlParserStatus (0x0x7f31c5391d80) 16 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 408) + +Class QQuickFramebufferObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickFramebufferObject::QPrivateSignal (0x0x7f31c2e1a840) 0 empty + +Vtable for QQuickFramebufferObject::Renderer +QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN23QQuickFramebufferObject8RendererE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QQuickFramebufferObject::Renderer::createFramebufferObject +48 (int (*)(...))QQuickFramebufferObject::Renderer::synchronize + +Class QQuickFramebufferObject::Renderer + size=16 align=8 + base size=16 base align=8 +QQuickFramebufferObject::Renderer (0x0x7f31c2e1a8a0) 0 + vptr=((& QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE) + 16) + +Vtable for QQuickFramebufferObject +QQuickFramebufferObject::_ZTV23QQuickFramebufferObject: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +16 (int (*)(...))QQuickFramebufferObject::metaObject +24 (int (*)(...))QQuickFramebufferObject::qt_metacast +32 (int (*)(...))QQuickFramebufferObject::qt_metacall +40 0 +48 0 +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickFramebufferObject::isTextureProvider +152 (int (*)(...))QQuickFramebufferObject::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickFramebufferObject::geometryChanged +368 (int (*)(...))QQuickFramebufferObject::updatePaintNode +376 (int (*)(...))QQuickFramebufferObject::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))-16 +408 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +416 0 +424 0 +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickFramebufferObject + size=32 align=8 + base size=32 base align=8 +QQuickFramebufferObject (0x0x7f31c5badf70) 0 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 16) + QQuickItem (0x0x7f31c4cc77e0) 0 + primary-for QQuickFramebufferObject (0x0x7f31c5badf70) + QObject (0x0x7f31c2e1a780) 0 + primary-for QQuickItem (0x0x7f31c4cc77e0) + QQmlParserStatus (0x0x7f31c2e1a7e0) 16 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 416) + +Class QQuickTextureFactory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextureFactory::QPrivateSignal (0x0x7f31c2e1aae0) 0 empty + +Vtable for QQuickTextureFactory +QQuickTextureFactory::_ZTV20QQuickTextureFactory: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickTextureFactory) +16 (int (*)(...))QQuickTextureFactory::metaObject +24 (int (*)(...))QQuickTextureFactory::qt_metacast +32 (int (*)(...))QQuickTextureFactory::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))QQuickTextureFactory::image + +Class QQuickTextureFactory + size=16 align=8 + base size=16 base align=8 +QQuickTextureFactory (0x0x7f31c26bb000) 0 + vptr=((& QQuickTextureFactory::_ZTV20QQuickTextureFactory) + 16) + QObject (0x0x7f31c2e1aa80) 0 + primary-for QQuickTextureFactory (0x0x7f31c26bb000) + +Class QQuickImageResponse::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickImageResponse::QPrivateSignal (0x0x7f31c2e1ac60) 0 empty + +Vtable for QQuickImageResponse +QQuickImageResponse::_ZTV19QQuickImageResponse: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageResponse) +16 (int (*)(...))QQuickImageResponse::metaObject +24 (int (*)(...))QQuickImageResponse::qt_metacast +32 (int (*)(...))QQuickImageResponse::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQuickImageResponse::errorString +128 (int (*)(...))QQuickImageResponse::cancel + +Class QQuickImageResponse + size=16 align=8 + base size=16 base align=8 +QQuickImageResponse (0x0x7f31c26bb068) 0 + vptr=((& QQuickImageResponse::_ZTV19QQuickImageResponse) + 16) + QObject (0x0x7f31c2e1ac00) 0 + primary-for QQuickImageResponse (0x0x7f31c26bb068) + +Vtable for QQuickImageProvider +QQuickImageProvider::_ZTV19QQuickImageProvider: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageProvider) +16 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +24 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +32 (int (*)(...))QQuickImageProvider::imageType +40 (int (*)(...))QQuickImageProvider::flags +48 (int (*)(...))QQuickImageProvider::requestImage +56 (int (*)(...))QQuickImageProvider::requestPixmap +64 (int (*)(...))QQuickImageProvider::requestTexture + +Class QQuickImageProvider + size=16 align=8 + base size=16 base align=8 +QQuickImageProvider (0x0x7f31c26bb0d0) 0 + vptr=((& QQuickImageProvider::_ZTV19QQuickImageProvider) + 16) + QQmlImageProviderBase (0x0x7f31c2e1ae40) 0 nearly-empty + primary-for QQuickImageProvider (0x0x7f31c26bb0d0) + +Vtable for QQuickAsyncImageProvider +QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQuickAsyncImageProvider) +16 0 +24 0 +32 (int (*)(...))QQuickImageProvider::imageType +40 (int (*)(...))QQuickImageProvider::flags +48 (int (*)(...))QQuickImageProvider::requestImage +56 (int (*)(...))QQuickImageProvider::requestPixmap +64 (int (*)(...))QQuickImageProvider::requestTexture +72 (int (*)(...))__cxa_pure_virtual + +Class QQuickAsyncImageProvider + size=24 align=8 + base size=24 base align=8 +QQuickAsyncImageProvider (0x0x7f31c26bb138) 0 + vptr=((& QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider) + 16) + QQuickImageProvider (0x0x7f31c26bb1a0) 0 + primary-for QQuickAsyncImageProvider (0x0x7f31c26bb138) + QQmlImageProviderBase (0x0x7f31c22760c0) 0 nearly-empty + primary-for QQuickImageProvider (0x0x7f31c26bb1a0) + +Class QQuickItemGrabResult::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItemGrabResult::QPrivateSignal (0x0x7f31c2276180) 0 empty + +Vtable for QQuickItemGrabResult +QQuickItemGrabResult::_ZTV20QQuickItemGrabResult: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickItemGrabResult) +16 (int (*)(...))QQuickItemGrabResult::metaObject +24 (int (*)(...))QQuickItemGrabResult::qt_metacast +32 (int (*)(...))QQuickItemGrabResult::qt_metacall +40 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +48 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +56 (int (*)(...))QQuickItemGrabResult::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickItemGrabResult + size=16 align=8 + base size=16 base align=8 +QQuickItemGrabResult (0x0x7f31c26bb208) 0 + vptr=((& QQuickItemGrabResult::_ZTV20QQuickItemGrabResult) + 16) + QObject (0x0x7f31c2276120) 0 + primary-for QQuickItemGrabResult (0x0x7f31c26bb208) + +Class QQuickPaintedItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickPaintedItem::QPrivateSignal (0x0x7f31c2276420) 0 empty + +Vtable for QQuickPaintedItem +QQuickPaintedItem::_ZTV17QQuickPaintedItem: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QQuickPaintedItem) +16 (int (*)(...))QQuickPaintedItem::metaObject +24 (int (*)(...))QQuickPaintedItem::qt_metacast +32 (int (*)(...))QQuickPaintedItem::qt_metacall +40 0 +48 0 +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickPaintedItem::isTextureProvider +152 (int (*)(...))QQuickPaintedItem::textureProvider +160 (int (*)(...))QQuickPaintedItem::itemChange +168 (int (*)(...))QQuickItem::classBegin +176 (int (*)(...))QQuickItem::componentComplete +184 (int (*)(...))QQuickItem::keyPressEvent +192 (int (*)(...))QQuickItem::keyReleaseEvent +200 (int (*)(...))QQuickItem::inputMethodEvent +208 (int (*)(...))QQuickItem::focusInEvent +216 (int (*)(...))QQuickItem::focusOutEvent +224 (int (*)(...))QQuickItem::mousePressEvent +232 (int (*)(...))QQuickItem::mouseMoveEvent +240 (int (*)(...))QQuickItem::mouseReleaseEvent +248 (int (*)(...))QQuickItem::mouseDoubleClickEvent +256 (int (*)(...))QQuickItem::mouseUngrabEvent +264 (int (*)(...))QQuickItem::touchUngrabEvent +272 (int (*)(...))QQuickItem::wheelEvent +280 (int (*)(...))QQuickItem::touchEvent +288 (int (*)(...))QQuickItem::hoverEnterEvent +296 (int (*)(...))QQuickItem::hoverMoveEvent +304 (int (*)(...))QQuickItem::hoverLeaveEvent +312 (int (*)(...))QQuickItem::dragEnterEvent +320 (int (*)(...))QQuickItem::dragMoveEvent +328 (int (*)(...))QQuickItem::dragLeaveEvent +336 (int (*)(...))QQuickItem::dropEvent +344 (int (*)(...))QQuickItem::childMouseEventFilter +352 (int (*)(...))QQuickItem::windowDeactivateEvent +360 (int (*)(...))QQuickItem::geometryChanged +368 (int (*)(...))QQuickPaintedItem::updatePaintNode +376 (int (*)(...))QQuickPaintedItem::releaseResources +384 (int (*)(...))QQuickItem::updatePolish +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))-16 +408 (int (*)(...))(& _ZTI17QQuickPaintedItem) +416 0 +424 0 +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickPaintedItem + size=32 align=8 + base size=32 base align=8 +QQuickPaintedItem (0x0x7f31c26bb270) 0 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 16) + QQuickItem (0x0x7f31c4cc7ee0) 0 + primary-for QQuickPaintedItem (0x0x7f31c26bb270) + QObject (0x0x7f31c2276360) 0 + primary-for QQuickItem (0x0x7f31c4cc7ee0) + QQmlParserStatus (0x0x7f31c22763c0) 16 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 416) + +Class QQuickRenderControl::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickRenderControl::QPrivateSignal (0x0x7f31c2276ea0) 0 empty + +Vtable for QQuickRenderControl +QQuickRenderControl::_ZTV19QQuickRenderControl: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickRenderControl) +16 (int (*)(...))QQuickRenderControl::metaObject +24 (int (*)(...))QQuickRenderControl::qt_metacast +32 (int (*)(...))QQuickRenderControl::qt_metacall +40 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +48 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickRenderControl::renderWindow + +Class QQuickRenderControl + size=16 align=8 + base size=16 base align=8 +QQuickRenderControl (0x0x7f31c26bb410) 0 + vptr=((& QQuickRenderControl::_ZTV19QQuickRenderControl) + 16) + QObject (0x0x7f31c2276e40) 0 + primary-for QQuickRenderControl (0x0x7f31c26bb410) + +Class QQuickTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextDocument::QPrivateSignal (0x0x7f31c19ca180) 0 empty + +Vtable for QQuickTextDocument +QQuickTextDocument::_ZTV18QQuickTextDocument: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QQuickTextDocument) +16 (int (*)(...))QQuickTextDocument::metaObject +24 (int (*)(...))QQuickTextDocument::qt_metacast +32 (int (*)(...))QQuickTextDocument::qt_metacall +40 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +48 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickTextDocument + size=16 align=8 + base size=16 base align=8 +QQuickTextDocument (0x0x7f31c26bb478) 0 + vptr=((& QQuickTextDocument::_ZTV18QQuickTextDocument) + 16) + QObject (0x0x7f31c19ca120) 0 + primary-for QQuickTextDocument (0x0x7f31c26bb478) + +Class QSGGeometry::Attribute + size=16 align=4 + base size=16 base align=4 +QSGGeometry::Attribute (0x0x7f31c19ca7e0) 0 + +Class QSGGeometry::AttributeSet + size=16 align=8 + base size=16 base align=8 +QSGGeometry::AttributeSet (0x0x7f31c19ca840) 0 + +Class QSGGeometry::Point2D + size=8 align=4 + base size=8 base align=4 +QSGGeometry::Point2D (0x0x7f31c19ca8a0) 0 + +Class QSGGeometry::TexturedPoint2D + size=16 align=4 + base size=16 base align=4 +QSGGeometry::TexturedPoint2D (0x0x7f31c19ca900) 0 + +Class QSGGeometry::ColoredPoint2D + size=12 align=4 + base size=12 base align=4 +QSGGeometry::ColoredPoint2D (0x0x7f31c19ca960) 0 + +Vtable for QSGGeometry +QSGGeometry::_ZTV11QSGGeometry: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGGeometry) +16 (int (*)(...))QSGGeometry::~QSGGeometry +24 (int (*)(...))QSGGeometry::~QSGGeometry + +Class QSGGeometry + size=128 align=8 + base size=128 base align=8 +QSGGeometry (0x0x7f31c19ca780) 0 + vptr=((& QSGGeometry::_ZTV11QSGGeometry) + 16) + +Vtable for QSGNode +QSGNode::_ZTV7QSGNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QSGNode) +16 (int (*)(...))QSGNode::~QSGNode +24 (int (*)(...))QSGNode::~QSGNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGNode + size=80 align=8 + base size=80 base align=8 +QSGNode (0x0x7f31c3071960) 0 + vptr=((& QSGNode::_ZTV7QSGNode) + 16) + +Vtable for QSGBasicGeometryNode +QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGBasicGeometryNode) +16 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +24 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGBasicGeometryNode + size=112 align=8 + base size=112 base align=8 +QSGBasicGeometryNode (0x0x7f31c26bbb60) 0 + vptr=((& QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode) + 16) + QSGNode (0x0x7f31c3d8e300) 0 + primary-for QSGBasicGeometryNode (0x0x7f31c26bbb60) + +Vtable for QSGGeometryNode +QSGGeometryNode::_ZTV15QSGGeometryNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSGGeometryNode) +16 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +24 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGGeometryNode + size=144 align=8 + base size=144 base align=8 +QSGGeometryNode (0x0x7f31c26bbbc8) 0 + vptr=((& QSGGeometryNode::_ZTV15QSGGeometryNode) + 16) + QSGBasicGeometryNode (0x0x7f31c26bbc30) 0 + primary-for QSGGeometryNode (0x0x7f31c26bbbc8) + QSGNode (0x0x7f31c3d8e5a0) 0 + primary-for QSGBasicGeometryNode (0x0x7f31c26bbc30) + +Vtable for QSGClipNode +QSGClipNode::_ZTV11QSGClipNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGClipNode) +16 (int (*)(...))QSGClipNode::~QSGClipNode +24 (int (*)(...))QSGClipNode::~QSGClipNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGClipNode + size=152 align=8 + base size=152 base align=8 +QSGClipNode (0x0x7f31c26bbc98) 0 + vptr=((& QSGClipNode::_ZTV11QSGClipNode) + 16) + QSGBasicGeometryNode (0x0x7f31c26bbd00) 0 + primary-for QSGClipNode (0x0x7f31c26bbc98) + QSGNode (0x0x7f31c3d8e780) 0 + primary-for QSGBasicGeometryNode (0x0x7f31c26bbd00) + +Vtable for QSGTransformNode +QSGTransformNode::_ZTV16QSGTransformNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGTransformNode) +16 (int (*)(...))QSGTransformNode::~QSGTransformNode +24 (int (*)(...))QSGTransformNode::~QSGTransformNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGTransformNode + size=216 align=8 + base size=216 base align=8 +QSGTransformNode (0x0x7f31c26bbd68) 0 + vptr=((& QSGTransformNode::_ZTV16QSGTransformNode) + 16) + QSGNode (0x0x7f31c3d8e8a0) 0 + primary-for QSGTransformNode (0x0x7f31c26bbd68) + +Vtable for QSGRootNode +QSGRootNode::_ZTV11QSGRootNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGRootNode) +16 (int (*)(...))QSGRootNode::~QSGRootNode +24 (int (*)(...))QSGRootNode::~QSGRootNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGRootNode + size=88 align=8 + base size=88 base align=8 +QSGRootNode (0x0x7f31c26bbdd0) 0 + vptr=((& QSGRootNode::_ZTV11QSGRootNode) + 16) + QSGNode (0x0x7f31c3d8e9c0) 0 + primary-for QSGRootNode (0x0x7f31c26bbdd0) + +Vtable for QSGOpacityNode +QSGOpacityNode::_ZTV14QSGOpacityNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGOpacityNode) +16 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +24 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +32 (int (*)(...))QSGOpacityNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGOpacityNode + size=96 align=8 + base size=96 base align=8 +QSGOpacityNode (0x0x7f31c26bbea0) 0 + vptr=((& QSGOpacityNode::_ZTV14QSGOpacityNode) + 16) + QSGNode (0x0x7f31c3d8eb40) 0 + primary-for QSGOpacityNode (0x0x7f31c26bbea0) + +Vtable for QSGNodeVisitor +QSGNodeVisitor::_ZTV14QSGNodeVisitor: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGNodeVisitor) +16 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +24 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +32 (int (*)(...))QSGNodeVisitor::enterTransformNode +40 (int (*)(...))QSGNodeVisitor::leaveTransformNode +48 (int (*)(...))QSGNodeVisitor::enterClipNode +56 (int (*)(...))QSGNodeVisitor::leaveClipNode +64 (int (*)(...))QSGNodeVisitor::enterGeometryNode +72 (int (*)(...))QSGNodeVisitor::leaveGeometryNode +80 (int (*)(...))QSGNodeVisitor::enterOpacityNode +88 (int (*)(...))QSGNodeVisitor::leaveOpacityNode +96 (int (*)(...))QSGNodeVisitor::visitNode +104 (int (*)(...))QSGNodeVisitor::visitChildren + +Class QSGNodeVisitor + size=8 align=8 + base size=8 base align=8 +QSGNodeVisitor (0x0x7f31c3d8ec60) 0 nearly-empty + vptr=((& QSGNodeVisitor::_ZTV14QSGNodeVisitor) + 16) + +Vtable for QSGRendererInterface +QSGRendererInterface::_ZTV20QSGRendererInterface: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGRendererInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QSGRendererInterface::getResource +48 (int (*)(...))QSGRendererInterface::getResource +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRendererInterface + size=8 align=8 + base size=8 base align=8 +QSGRendererInterface (0x0x7f31c5847a80) 0 nearly-empty + vptr=((& QSGRendererInterface::_ZTV20QSGRendererInterface) + 16) + +Class QQuickWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickWindow::QPrivateSignal (0x0x7f31c3494960) 0 empty + +Class QQuickWindow::GraphicsStateInfo + size=8 align=4 + base size=8 base align=4 +QQuickWindow::GraphicsStateInfo (0x0x7f31c34949c0) 0 + +Vtable for QQuickWindow +QQuickWindow::_ZTV12QQuickWindow: 45 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QQuickWindow) +16 (int (*)(...))QQuickWindow::metaObject +24 (int (*)(...))QQuickWindow::qt_metacast +32 (int (*)(...))QQuickWindow::qt_metacall +40 (int (*)(...))QQuickWindow::~QQuickWindow +48 (int (*)(...))QQuickWindow::~QQuickWindow +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QQuickWindow::focusInEvent +184 (int (*)(...))QQuickWindow::focusOutEvent +192 (int (*)(...))QQuickWindow::showEvent +200 (int (*)(...))QQuickWindow::hideEvent +208 (int (*)(...))QQuickWindow::keyPressEvent +216 (int (*)(...))QQuickWindow::keyReleaseEvent +224 (int (*)(...))QQuickWindow::mousePressEvent +232 (int (*)(...))QQuickWindow::mouseReleaseEvent +240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +248 (int (*)(...))QQuickWindow::mouseMoveEvent +256 (int (*)(...))QQuickWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI12QQuickWindow) +312 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD1Ev +320 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickWindow + size=40 align=8 + base size=40 base align=8 +QQuickWindow (0x0x7f31c31650d0) 0 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 16) + QWindow (0x0x7f31c49f32a0) 0 + primary-for QQuickWindow (0x0x7f31c31650d0) + QObject (0x0x7f31c34948a0) 0 + primary-for QWindow (0x0x7f31c49f32a0) + QSurface (0x0x7f31c3494900) 16 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 312) + +Class QQuickView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickView::QPrivateSignal (0x0x7f31c17ae4e0) 0 empty + +Vtable for QQuickView +QQuickView::_ZTV10QQuickView: 45 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickView) +16 (int (*)(...))QQuickView::metaObject +24 (int (*)(...))QQuickView::qt_metacast +32 (int (*)(...))QQuickView::qt_metacall +40 (int (*)(...))QQuickView::~QQuickView +48 (int (*)(...))QQuickView::~QQuickView +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QQuickView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickView::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QQuickWindow::focusInEvent +184 (int (*)(...))QQuickWindow::focusOutEvent +192 (int (*)(...))QQuickWindow::showEvent +200 (int (*)(...))QQuickWindow::hideEvent +208 (int (*)(...))QQuickView::keyPressEvent +216 (int (*)(...))QQuickView::keyReleaseEvent +224 (int (*)(...))QQuickView::mousePressEvent +232 (int (*)(...))QQuickView::mouseReleaseEvent +240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +248 (int (*)(...))QQuickView::mouseMoveEvent +256 (int (*)(...))QQuickWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI10QQuickView) +312 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD1Ev +320 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickView + size=40 align=8 + base size=40 base align=8 +QQuickView (0x0x7f31c3165208) 0 + vptr=((& QQuickView::_ZTV10QQuickView) + 16) + QQuickWindow (0x0x7f31c3165270) 0 + primary-for QQuickView (0x0x7f31c3165208) + QWindow (0x0x7f31c4a2a8c0) 0 + primary-for QQuickWindow (0x0x7f31c3165270) + QObject (0x0x7f31c17ae420) 0 + primary-for QWindow (0x0x7f31c4a2a8c0) + QSurface (0x0x7f31c17ae480) 16 + vptr=((& QQuickView::_ZTV10QQuickView) + 312) + +Class QSGAbstractRenderer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGAbstractRenderer::QPrivateSignal (0x0x7f31c17ae8a0) 0 empty + +Vtable for QSGAbstractRenderer +QSGAbstractRenderer::_ZTV19QSGAbstractRenderer: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QSGAbstractRenderer) +16 (int (*)(...))QSGAbstractRenderer::metaObject +24 (int (*)(...))QSGAbstractRenderer::qt_metacast +32 (int (*)(...))QSGAbstractRenderer::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QSGAbstractRenderer + size=16 align=8 + base size=16 base align=8 +QSGAbstractRenderer (0x0x7f31c31652d8) 0 + vptr=((& QSGAbstractRenderer::_ZTV19QSGAbstractRenderer) + 16) + QObject (0x0x7f31c17ae840) 0 + primary-for QSGAbstractRenderer (0x0x7f31c31652d8) + +Class QSGEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGEngine::QPrivateSignal (0x0x7f31c09ff5a0) 0 empty + +Vtable for QSGEngine +QSGEngine::_ZTV9QSGEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSGEngine) +16 (int (*)(...))QSGEngine::metaObject +24 (int (*)(...))QSGEngine::qt_metacast +32 (int (*)(...))QSGEngine::qt_metacall +40 (int (*)(...))QSGEngine::~QSGEngine +48 (int (*)(...))QSGEngine::~QSGEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSGEngine + size=16 align=8 + base size=16 base align=8 +QSGEngine (0x0x7f31c31654e0) 0 + vptr=((& QSGEngine::_ZTV9QSGEngine) + 16) + QObject (0x0x7f31c09ff540) 0 + primary-for QSGEngine (0x0x7f31c31654e0) + +Class QSGMaterialType + size=1 align=1 + base size=0 base align=1 +QSGMaterialType (0x0x7f31c09ffc00) 0 empty + +Class QSGMaterialShader::RenderState + size=16 align=8 + base size=16 base align=8 +QSGMaterialShader::RenderState (0x0x7f31c09ffcc0) 0 + +Vtable for QSGMaterialShader +QSGMaterialShader::_ZTV17QSGMaterialShader: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGMaterialShader) +16 0 +24 0 +32 (int (*)(...))QSGMaterialShader::activate +40 (int (*)(...))QSGMaterialShader::deactivate +48 (int (*)(...))QSGMaterialShader::updateState +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QSGMaterialShader::compile +72 (int (*)(...))QSGMaterialShader::initialize +80 (int (*)(...))QSGMaterialShader::vertexShader +88 (int (*)(...))QSGMaterialShader::fragmentShader + +Class QSGMaterialShader + size=32 align=8 + base size=32 base align=8 +QSGMaterialShader (0x0x7f31c09ffc60) 0 + vptr=((& QSGMaterialShader::_ZTV17QSGMaterialShader) + 16) + +Class QSGMaterialRhiShader::RenderState + size=16 align=8 + base size=16 base align=8 +QSGMaterialRhiShader::RenderState (0x0x7f31c082e840) 0 + +Class QSGMaterialRhiShader::GraphicsPipelineState + size=36 align=4 + base size=36 base align=4 +QSGMaterialRhiShader::GraphicsPipelineState (0x0x7f31c082e8a0) 0 + +Vtable for QSGMaterialRhiShader +QSGMaterialRhiShader::_ZTV20QSGMaterialRhiShader: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGMaterialRhiShader) +16 (int (*)(...))QSGMaterialRhiShader::~QSGMaterialRhiShader +24 (int (*)(...))QSGMaterialRhiShader::~QSGMaterialRhiShader +32 (int (*)(...))QSGMaterialShader::activate +40 (int (*)(...))QSGMaterialShader::deactivate +48 (int (*)(...))QSGMaterialShader::updateState +56 (int (*)(...))QSGMaterialRhiShader::attributeNames +64 (int (*)(...))QSGMaterialShader::compile +72 (int (*)(...))QSGMaterialShader::initialize +80 (int (*)(...))QSGMaterialShader::vertexShader +88 (int (*)(...))QSGMaterialShader::fragmentShader +96 (int (*)(...))QSGMaterialRhiShader::updateUniformData +104 (int (*)(...))QSGMaterialRhiShader::updateSampledImage +112 (int (*)(...))QSGMaterialRhiShader::updateGraphicsPipelineState + +Class QSGMaterialRhiShader + size=40 align=8 + base size=40 base align=8 +QSGMaterialRhiShader (0x0x7f31c31656e8) 0 + vptr=((& QSGMaterialRhiShader::_ZTV20QSGMaterialRhiShader) + 16) + QSGMaterialShader (0x0x7f31c082e7e0) 0 + primary-for QSGMaterialRhiShader (0x0x7f31c31656e8) + +Vtable for QSGMaterial +QSGMaterial::_ZTV11QSGMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGMaterial) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QSGMaterial::compare + +Class QSGMaterial + size=24 align=8 + base size=24 base align=8 +QSGMaterial (0x0x7f31c0680960) 0 + vptr=((& QSGMaterial::_ZTV11QSGMaterial) + 16) + +Vtable for QSGFlatColorMaterial +QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGFlatColorMaterial) +16 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +24 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +32 (int (*)(...))QSGFlatColorMaterial::type +40 (int (*)(...))QSGFlatColorMaterial::createShader +48 (int (*)(...))QSGFlatColorMaterial::compare + +Class QSGFlatColorMaterial + size=40 align=8 + base size=40 base align=8 +QSGFlatColorMaterial (0x0x7f31c3165a28) 0 + vptr=((& QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial) + 16) + QSGMaterial (0x0x7f31c022a120) 0 + primary-for QSGFlatColorMaterial (0x0x7f31c3165a28) + +Class QSGTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTexture::QPrivateSignal (0x0x7f31c022a240) 0 empty + +Vtable for QSGTexture +QSGTexture::_ZTV10QSGTexture: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSGTexture) +16 (int (*)(...))QSGTexture::metaObject +24 (int (*)(...))QSGTexture::qt_metacast +32 (int (*)(...))QSGTexture::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QSGTexture::normalizedTextureSubRect +152 (int (*)(...))QSGTexture::isAtlasTexture +160 (int (*)(...))QSGTexture::removedFromAtlas +168 (int (*)(...))__cxa_pure_virtual + +Class QSGTexture + size=16 align=8 + base size=16 base align=8 +QSGTexture (0x0x7f31c3165a90) 0 + vptr=((& QSGTexture::_ZTV10QSGTexture) + 16) + QObject (0x0x7f31c022a1e0) 0 + primary-for QSGTexture (0x0x7f31c3165a90) + +Class QSGDynamicTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGDynamicTexture::QPrivateSignal (0x0x7f31c022a4e0) 0 empty + +Vtable for QSGDynamicTexture +QSGDynamicTexture::_ZTV17QSGDynamicTexture: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGDynamicTexture) +16 (int (*)(...))QSGDynamicTexture::metaObject +24 (int (*)(...))QSGDynamicTexture::qt_metacast +32 (int (*)(...))QSGDynamicTexture::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QSGTexture::normalizedTextureSubRect +152 (int (*)(...))QSGTexture::isAtlasTexture +160 (int (*)(...))QSGTexture::removedFromAtlas +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual + +Class QSGDynamicTexture + size=16 align=8 + base size=16 base align=8 +QSGDynamicTexture (0x0x7f31c3165af8) 0 + vptr=((& QSGDynamicTexture::_ZTV17QSGDynamicTexture) + 16) + QSGTexture (0x0x7f31c3165b60) 0 + primary-for QSGDynamicTexture (0x0x7f31c3165af8) + QObject (0x0x7f31c022a480) 0 + primary-for QSGTexture (0x0x7f31c3165b60) + +Vtable for QSGImageNode +QSGImageNode::_ZTV12QSGImageNode: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QSGImageNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QSGImageNode + size=144 align=8 + base size=144 base align=8 +QSGImageNode (0x0x7f31c3165bc8) 0 + vptr=((& QSGImageNode::_ZTV12QSGImageNode) + 16) + QSGGeometryNode (0x0x7f31c3165c30) 0 + primary-for QSGImageNode (0x0x7f31c3165bc8) + QSGBasicGeometryNode (0x0x7f31c3165c98) 0 + primary-for QSGGeometryNode (0x0x7f31c3165c30) + QSGNode (0x0x7f31c022a600) 0 + primary-for QSGBasicGeometryNode (0x0x7f31c3165c98) + +Vtable for QSGNinePatchNode +QSGNinePatchNode::_ZTV16QSGNinePatchNode: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGNinePatchNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual + +Class QSGNinePatchNode + size=144 align=8 + base size=144 base align=8 +QSGNinePatchNode (0x0x7f31c3165dd0) 0 + vptr=((& QSGNinePatchNode::_ZTV16QSGNinePatchNode) + 16) + QSGGeometryNode (0x0x7f31c3165e38) 0 + primary-for QSGNinePatchNode (0x0x7f31c3165dd0) + QSGBasicGeometryNode (0x0x7f31c3165ea0) 0 + primary-for QSGGeometryNode (0x0x7f31c3165e38) + QSGNode (0x0x7f31c022ade0) 0 + primary-for QSGBasicGeometryNode (0x0x7f31c3165ea0) + +Vtable for QSGRectangleNode +QSGRectangleNode::_ZTV16QSGRectangleNode: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGRectangleNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRectangleNode + size=144 align=8 + base size=144 base align=8 +QSGRectangleNode (0x0x7f31c3165f08) 0 + vptr=((& QSGRectangleNode::_ZTV16QSGRectangleNode) + 16) + QSGGeometryNode (0x0x7f31c3165f70) 0 + primary-for QSGRectangleNode (0x0x7f31c3165f08) + QSGBasicGeometryNode (0x0x7f31ca88f000) 0 + primary-for QSGGeometryNode (0x0x7f31c3165f70) + QSGNode (0x0x7f31c022ae40) 0 + primary-for QSGBasicGeometryNode (0x0x7f31ca88f000) + +Vtable for QSGRenderNode::RenderState +QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QSGRenderNode11RenderStateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))QSGRenderNode::RenderState::get + +Class QSGRenderNode::RenderState + size=8 align=8 + base size=8 base align=8 +QSGRenderNode::RenderState (0x0x7f31c022af60) 0 nearly-empty + vptr=((& QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE) + 16) + +Vtable for QSGRenderNode +QSGRenderNode::_ZTV13QSGRenderNode: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSGRenderNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))QSGRenderNode::changedStates +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QSGRenderNode::releaseResources +72 (int (*)(...))QSGRenderNode::flags +80 (int (*)(...))QSGRenderNode::rect + +Class QSGRenderNode + size=88 align=8 + base size=88 base align=8 +QSGRenderNode (0x0x7f31ca88f068) 0 + vptr=((& QSGRenderNode::_ZTV13QSGRenderNode) + 16) + QSGNode (0x0x7f31c022af00) 0 + primary-for QSGRenderNode (0x0x7f31ca88f068) + +Vtable for QSGSimpleRectNode +QSGSimpleRectNode::_ZTV17QSGSimpleRectNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGSimpleRectNode) +16 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +24 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleRectNode + size=320 align=8 + base size=320 base align=8 +QSGSimpleRectNode (0x0x7f31ca88f4e0) 0 + vptr=((& QSGSimpleRectNode::_ZTV17QSGSimpleRectNode) + 16) + QSGGeometryNode (0x0x7f31ca88f548) 0 + primary-for QSGSimpleRectNode (0x0x7f31ca88f4e0) + QSGBasicGeometryNode (0x0x7f31ca88f5b0) 0 + primary-for QSGGeometryNode (0x0x7f31ca88f548) + QSGNode (0x0x7f31c765d6c0) 0 + primary-for QSGBasicGeometryNode (0x0x7f31ca88f5b0) + +Vtable for QSGOpaqueTextureMaterial +QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QSGOpaqueTextureMaterial) +16 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +24 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +32 (int (*)(...))QSGOpaqueTextureMaterial::type +40 (int (*)(...))QSGOpaqueTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGOpaqueTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGOpaqueTextureMaterial (0x0x7f31ca88f618) 0 + vptr=((& QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial) + 16) + QSGMaterial (0x0x7f31c765d780) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7f31ca88f618) + +Vtable for QSGTextureMaterial +QSGTextureMaterial::_ZTV18QSGTextureMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureMaterial) +16 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +24 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +32 (int (*)(...))QSGTextureMaterial::type +40 (int (*)(...))QSGTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGTextureMaterial (0x0x7f31ca88f680) 0 + vptr=((& QSGTextureMaterial::_ZTV18QSGTextureMaterial) + 16) + QSGOpaqueTextureMaterial (0x0x7f31ca88f6e8) 0 + primary-for QSGTextureMaterial (0x0x7f31ca88f680) + QSGMaterial (0x0x7f31c765dc00) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7f31ca88f6e8) + +Vtable for QSGSimpleTextureNode +QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGSimpleTextureNode) +16 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +24 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleTextureNode + size=384 align=8 + base size=384 base align=8 +QSGSimpleTextureNode (0x0x7f31ca88f750) 0 + vptr=((& QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode) + 16) + QSGGeometryNode (0x0x7f31ca88f7b8) 0 + primary-for QSGSimpleTextureNode (0x0x7f31ca88f750) + QSGBasicGeometryNode (0x0x7f31ca88f820) 0 + primary-for QSGGeometryNode (0x0x7f31ca88f7b8) + QSGNode (0x0x7f31c765dc60) 0 + primary-for QSGBasicGeometryNode (0x0x7f31ca88f820) + +Class QSGTextureProvider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTextureProvider::QPrivateSignal (0x0x7f31c6a41600) 0 empty + +Vtable for QSGTextureProvider +QSGTextureProvider::_ZTV18QSGTextureProvider: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureProvider) +16 (int (*)(...))QSGTextureProvider::metaObject +24 (int (*)(...))QSGTextureProvider::qt_metacast +32 (int (*)(...))QSGTextureProvider::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSGTextureProvider + size=16 align=8 + base size=16 base align=8 +QSGTextureProvider (0x0x7f31ca88f9c0) 0 + vptr=((& QSGTextureProvider::_ZTV18QSGTextureProvider) + 16) + QObject (0x0x7f31c6a415a0) 0 + primary-for QSGTextureProvider (0x0x7f31ca88f9c0) + +Vtable for QSGVertexColorMaterial +QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QSGVertexColorMaterial) +16 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +24 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +32 (int (*)(...))QSGVertexColorMaterial::type +40 (int (*)(...))QSGVertexColorMaterial::createShader +48 (int (*)(...))QSGVertexColorMaterial::compare + +Class QSGVertexColorMaterial + size=24 align=8 + base size=24 base align=8 +QSGVertexColorMaterial (0x0x7f31ca88fa28) 0 + vptr=((& QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial) + 16) + QSGMaterial (0x0x7f31c6a41720) 0 + primary-for QSGVertexColorMaterial (0x0x7f31ca88fa28) + +Class QQuickStyle + size=1 align=1 + base size=0 base align=1 +QQuickStyle (0x0x7f31c6a41780) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c3aeba80) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c3aebde0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c38b0000) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c38b0360) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c38b0540) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c38b08a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c38b0a80) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c38b0de0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c3944000) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c3944360) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c3944540) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c39448a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c3944a80) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c3944de0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c367b000) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c367b360) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c36bd840) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c36bdba0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c36bdd20) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c38070c0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c3807240) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c38075a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c3807720) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c3807a80) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c3807c00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c3807f60) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c2f9f120) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c2f9f480) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c2f9f600) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c2f9f960) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f31c2f9fae0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f31c2f9fe40) 0 empty + diff --git a/tests/auto/quickcontrols2/bic/data/QtQuickControls2.6.0.0.linux-gcc-amd64.txt b/tests/auto/quickcontrols2/bic/data/QtQuickControls2.6.0.0.linux-gcc-amd64.txt new file mode 100644 index 00000000000..21b78d63497 --- /dev/null +++ b/tests/auto/quickcontrols2/bic/data/QtQuickControls2.6.0.0.linux-gcc-amd64.txt @@ -0,0 +1,14468 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f4475a49840) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f4475adc060) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f4475adc2a0) 0 empty + +Class std::__do_is_implicitly_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_implicitly_default_constructible_impl (0x0x7f4475b0e3c0) 0 empty + +Class std::__make_unsigned_selector_base + size=1 align=1 + base size=0 base align=1 +std::__make_unsigned_selector_base (0x0x7f447573eba0) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f44757b79c0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f44757b7a80) 0 empty + +Class std::__invoke_memfun_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_ref (0x0x7f44757b7f60) 0 empty + +Class std::__invoke_memfun_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memfun_deref (0x0x7f44757e6000) 0 empty + +Class std::__invoke_memobj_ref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_ref (0x0x7f44757e6060) 0 empty + +Class std::__invoke_memobj_deref + size=1 align=1 + base size=0 base align=1 +std::__invoke_memobj_deref (0x0x7f44757e60c0) 0 empty + +Class std::__invoke_other + size=1 align=1 + base size=0 base align=1 +std::__invoke_other (0x0x7f44757e6120) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f44757e61e0) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f44757e62a0) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f44757e6360) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f44757e6420) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f44757e6780) 0 empty + +Class std::__swappable_details::__do_is_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_swappable_impl (0x0x7f44757e6ae0) 0 empty + +Class std::__swappable_details::__do_is_nothrow_swappable_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_details::__do_is_nothrow_swappable_impl (0x0x7f44757e6b40) 0 empty + +Class std::__swappable_with_details::__do_is_swappable_with_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_with_details::__do_is_swappable_with_impl (0x0x7f44757e6de0) 0 empty + +Class std::__swappable_with_details::__do_is_nothrow_swappable_with_impl + size=1 align=1 + base size=0 base align=1 +std::__swappable_with_details::__do_is_nothrow_swappable_with_impl (0x0x7f44757e6e40) 0 empty + +Class std::__nonesuch + size=1 align=1 + base size=0 base align=1 +std::__nonesuch (0x0x7f44758376c0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f4475883c60) 0 empty + +Class std::__nonesuch_no_braces + size=1 align=1 + base size=1 base align=1 +std::__nonesuch_no_braces (0x0x7f44758880d0) 0 empty + std::__nonesuch (0x0x7f44758bd180) 0 empty + +Class std::in_place_t + size=1 align=1 + base size=0 base align=1 +std::in_place_t (0x0x7f4475903ea0) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f4475936180) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f44759361e0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f4475d6df00) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f4475d6df60) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f4475888618) 0 empty + std::input_iterator_tag (0x0x7f4475d95000) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f4475888680) 0 empty + std::forward_iterator_tag (0x0x7f44758886e8) 0 empty + std::input_iterator_tag (0x0x7f4475d95060) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f4475888750) 0 empty + std::bidirectional_iterator_tag (0x0x7f44758887b8) 0 empty + std::forward_iterator_tag (0x0x7f4475888820) 0 empty + std::input_iterator_tag (0x0x7f4475d950c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f4475e1ed80) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f4475e1eea0) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f4475e4e1e0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f4475e4e4e0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f4475e4e600) 0 empty + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f4475ed7de0) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f4475f21180) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f4475f211e0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f4475f212a0) 0 + +Class __pthread_internal_slist + size=8 align=8 + base size=8 base align=8 +__pthread_internal_slist (0x0x7f4475f21300) 0 + +Class __pthread_mutex_s + size=40 align=8 + base size=40 base align=8 +__pthread_mutex_s (0x0x7f4475f21360) 0 + +Class __pthread_rwlock_arch_t + size=56 align=8 + base size=56 base align=8 +__pthread_rwlock_arch_t (0x0x7f4475f213c0) 0 + +Class __pthread_cond_s + size=48 align=8 + base size=48 base align=8 +__pthread_cond_s (0x0x7f4475f21420) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f4475f216c0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f4475f21960) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f4475f219c0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f4475bd1780) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f4475888bc8) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16) + std::exception (0x0x7f4475bd1960) 0 nearly-empty + primary-for std::bad_exception (0x0x7f4475888bc8) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f4475bd1b40) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f4475888c30) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16) + std::exception (0x0x7f4475bd1f00) 0 nearly-empty + primary-for std::bad_cast (0x0x7f4475888c30) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f4475888c98) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16) + std::exception (0x0x7f4475c07120) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f4475888c98) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f4475c07300) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f4475c07840) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f4475888d00) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16) + std::exception (0x0x7f4475c07f00) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f4475888d00) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f4475888d68) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16) + std::bad_alloc (0x0x7f4475888dd0) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f4475888d68) + std::exception (0x0x7f4475c3c120) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f4475888dd0) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f4475c3c300) 0 empty + +Class std::__allocator_traits_base + size=1 align=1 + base size=0 base align=1 +std::__allocator_traits_base (0x0x7f4475c3c540) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f4475cbecc0) 0 empty + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f4474ce30c0) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f4474ce3180) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f4474940060) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f4474940120) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f4474940180) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f44749401e0) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f4474940240) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f4474940360) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f44749403c0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f44749d7a20) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f44749d7ba0) 0 empty + +Class _G_fpos_t + size=16 align=8 + base size=16 base align=8 +_G_fpos_t (0x0x7f44747f6a20) 0 + +Class _G_fpos64_t + size=16 align=8 + base size=16 base align=8 +_G_fpos64_t (0x0x7f44747f6a80) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f44747f6ae0) 0 + +Class _IO_cookie_io_functions_t + size=32 align=8 + base size=32 base align=8 +_IO_cookie_io_functions_t (0x0x7f44747f6b40) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f4474450300) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f44743ced68) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16) + std::exception (0x0x7f44744503c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f44743ced68) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f44743cedd0) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16) + std::logic_error (0x0x7f44743cee38) 0 + primary-for std::domain_error (0x0x7f44743cedd0) + std::exception (0x0x7f4474450420) 0 nearly-empty + primary-for std::logic_error (0x0x7f44743cee38) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f44743ceea0) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16) + std::logic_error (0x0x7f44743cef08) 0 + primary-for std::invalid_argument (0x0x7f44743ceea0) + std::exception (0x0x7f4474450480) 0 nearly-empty + primary-for std::logic_error (0x0x7f44743cef08) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f44743cef70) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16) + std::logic_error (0x0x7f4474474000) 0 + primary-for std::length_error (0x0x7f44743cef70) + std::exception (0x0x7f44744504e0) 0 nearly-empty + primary-for std::logic_error (0x0x7f4474474000) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f4474474068) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16) + std::logic_error (0x0x7f44744740d0) 0 + primary-for std::out_of_range (0x0x7f4474474068) + std::exception (0x0x7f4474450540) 0 nearly-empty + primary-for std::logic_error (0x0x7f44744740d0) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f4474474138) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16) + std::exception (0x0x7f44744505a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f4474474138) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f44744741a0) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16) + std::runtime_error (0x0x7f4474474208) 0 + primary-for std::range_error (0x0x7f44744741a0) + std::exception (0x0x7f4474450600) 0 nearly-empty + primary-for std::runtime_error (0x0x7f4474474208) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f4474474270) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16) + std::runtime_error (0x0x7f44744742d8) 0 + primary-for std::overflow_error (0x0x7f4474474270) + std::exception (0x0x7f4474450660) 0 nearly-empty + primary-for std::runtime_error (0x0x7f44744742d8) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f4474474340) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16) + std::runtime_error (0x0x7f44744743a8) 0 + primary-for std::underflow_error (0x0x7f4474474340) + std::exception (0x0x7f44744506c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f44744743a8) + +Class std::__erased_type + size=1 align=1 + base size=0 base align=1 +std::__erased_type (0x0x7f44744b89c0) 0 empty + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f44744b8a20) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f44744b8ba0) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f44744b8c60) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f4474474618) 0 + std::__uses_alloc_base (0x0x7f44744b8c00) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f44742582a0) 0 empty + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f44742d1a28) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16) + std::exception (0x0x7f44742f2960) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f44742d1a28) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f44742f2a20) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f44742f2a80) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f44742f2d80) 0 + +Class std::__detail::_Identity + size=1 align=1 + base size=0 base align=1 +std::__detail::_Identity (0x0x7f4473fcbc00) 0 empty + +Class std::__detail::_Select1st + size=1 align=1 + base size=0 base align=1 +std::__detail::_Select1st (0x0x7f4473fcbcc0) 0 empty + +Class std::__detail::_Hash_node_base + size=8 align=8 + base size=8 base align=8 +std::__detail::_Hash_node_base (0x0x7f4473ff51e0) 0 + +Class std::__detail::_Mod_range_hashing + size=1 align=1 + base size=0 base align=1 +std::__detail::_Mod_range_hashing (0x0x7f447401c060) 0 empty + +Class std::__detail::_Default_ranged_hash + size=1 align=1 + base size=0 base align=1 +std::__detail::_Default_ranged_hash (0x0x7f447401c120) 0 empty + +Class std::__detail::_Prime_rehash_policy + size=16 align=8 + base size=16 base align=8 +std::__detail::_Prime_rehash_policy (0x0x7f447401c180) 0 + +Class std::__detail::_Mask_range_hashing + size=1 align=1 + base size=0 base align=1 +std::__detail::_Mask_range_hashing (0x0x7f447401c540) 0 empty + +Class std::__detail::_Power2_rehash_policy + size=16 align=8 + base size=16 base align=8 +std::__detail::_Power2_rehash_policy (0x0x7f447401c660) 0 + +Class std::__detail::_Equality_base + size=1 align=1 + base size=0 base align=1 +std::__detail::_Equality_base (0x0x7f4473e00720) 0 empty + +Class std::_Enable_default_constructor_tag + size=1 align=1 + base size=0 base align=1 +std::_Enable_default_constructor_tag (0x0x7f4473e3d000) 0 empty + +Class std::nullopt_t + size=1 align=1 + base size=0 base align=1 +std::nullopt_t (0x0x7f4473e3d9c0) 0 empty + +Vtable for std::bad_optional_access +std::bad_optional_access::_ZTVSt19bad_optional_access: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt19bad_optional_access) +16 (int (*)(...))std::bad_optional_access::~bad_optional_access +24 (int (*)(...))std::bad_optional_access::~bad_optional_access +32 (int (*)(...))std::bad_optional_access::what + +Class std::bad_optional_access + size=8 align=8 + base size=8 base align=8 +std::bad_optional_access (0x0x7f4473e21958) 0 nearly-empty + vptr=((& std::bad_optional_access::_ZTVSt19bad_optional_access) + 16) + std::exception (0x0x7f4473e3dc00) 0 nearly-empty + primary-for std::bad_optional_access (0x0x7f4473e21958) + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f44739185a0) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f4473808478) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f4473918d20) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f4473808548) 0 + std::_Bit_iterator_base (0x0x7f44738085b0) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f447354a300) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f4473808680) 0 + std::_Bit_iterator_base (0x0x7f44738086e8) 0 + std::iterator<std::random_access_iterator_tag, bool> (0x0x7f447354aae0) 0 empty + +Class __pstl::execution::v1::sequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::sequenced_policy (0x0x7f447335a000) 0 empty + +Class __pstl::execution::v1::parallel_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::parallel_policy (0x0x7f447335a180) 0 empty + +Class __pstl::execution::v1::parallel_unsequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::parallel_unsequenced_policy (0x0x7f447335a300) 0 empty + +Class __pstl::execution::v1::unsequenced_policy + size=1 align=1 + base size=0 base align=1 +__pstl::execution::v1::unsequenced_policy (0x0x7f447335a480) 0 empty + +Class std::__detail::__variant::__variant_cookie + size=1 align=1 + base size=0 base align=1 +std::__detail::__variant::__variant_cookie (0x0x7f4473456f60) 0 empty + +Class std::__detail::__variant::__variant_idx_cookie + size=1 align=1 + base size=0 base align=1 +std::__detail::__variant::__variant_idx_cookie (0x0x7f4473496000) 0 empty + +Class std::monostate + size=1 align=1 + base size=0 base align=1 +std::monostate (0x0x7f447351ca80) 0 empty + +Vtable for std::bad_variant_access +std::bad_variant_access::_ZTVSt18bad_variant_access: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt18bad_variant_access) +16 (int (*)(...))std::bad_variant_access::~bad_variant_access +24 (int (*)(...))std::bad_variant_access::~bad_variant_access +32 (int (*)(...))std::bad_variant_access::what + +Class std::bad_variant_access + size=16 align=8 + base size=16 base align=8 +std::bad_variant_access (0x0x7f4473478a90) 0 + vptr=((& std::bad_variant_access::_ZTVSt18bad_variant_access) + 16) + std::exception (0x0x7f4473183000) 0 nearly-empty + primary-for std::bad_variant_access (0x0x7f4473478a90) + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f44732199c0) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f4473219a20) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f4473219cc0) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f44732614e0) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f4473296600) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f4473329420) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f44732c2d00) 0 + std::__atomic_flag_base (0x0x7f4473329480) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f4472ee3000) 0 + QAtomicInteger<int> (0x0x7f4472ee3068) 0 + QBasicAtomicInteger<int> (0x0x7f4472eb2360) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f4472b1b660) 0 empty + +Class QKeyCombination + size=4 align=4 + base size=4 base align=4 +QKeyCombination (0x0x7f4472b1b6c0) 0 + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f44727d39c0) 0 + +Class QMethodRawArguments + size=8 align=8 + base size=8 base align=8 +QMethodRawArguments (0x0x7f4472811120) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f4472811180) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f44727e1478) 0 + QGenericArgument (0x0x7f4472811420) 0 + +Class QMetaObject::SuperData + size=8 align=8 + base size=8 base align=8 +QMetaObject::SuperData (0x0x7f4472811900) 0 + +Class QMetaObject::Data + size=56 align=8 + base size=56 base align=8 +QMetaObject::Data (0x0x7f4472811960) 0 + +Class QMetaObject + size=56 align=8 + base size=56 base align=8 +QMetaObject (0x0x7f44728118a0) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f447285d300) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f447288dd20) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f44728b3720) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f447258c240) 0 + +Class QArrayData + size=16 align=8 + base size=16 base align=8 +QArrayData (0x0x7f447258c5a0) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f447261ef60) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f44726450c0) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f4472645480) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f4472645720) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f4472645900) 0 + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f44726a1a20) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f44726a1d80) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f44726e75a0) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f4472641958) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16) + std::runtime_error (0x0x7f44726419c0) 0 + primary-for std::system_error (0x0x7f4472641958) + std::exception (0x0x7f4472712180) 0 nearly-empty + primary-for std::runtime_error (0x0x7f44726419c0) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f4472641d00) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16) + std::system_error (0x0x7f4472641d68) 0 + primary-for std::ios_base::failure (0x0x7f4472641d00) + std::runtime_error (0x0x7f4472641dd0) 0 + primary-for std::system_error (0x0x7f4472641d68) + std::exception (0x0x7f4472348900) 0 nearly-empty + primary-for std::runtime_error (0x0x7f4472641dd0) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f4472348960) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f44723489c0) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f4472348a20) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f44723488a0) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f4472401660) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f44724b9960) 0 empty + +VTT for std::basic_ostream<char> +std::basic_ostream<char>::_ZTTSo: 2 entries +0 ((& std::basic_ostream<char>::_ZTVSo) + 24) +8 ((& std::basic_ostream<char>::_ZTVSo) + 64) + +VTT for std::basic_ostream<wchar_t> +std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64) + +VTT for std::basic_istream<char> +std::basic_istream<char>::_ZTTSi: 2 entries +0 ((& std::basic_istream<char>::_ZTVSi) + 24) +8 ((& std::basic_istream<char>::_ZTVSi) + 64) + +VTT for std::basic_istream<wchar_t> +std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2 entries +0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64) + +Construction vtable for std::basic_istream<char> (0x0x7f4472021958 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd0_Si: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0 +72 0 + +Construction vtable for std::basic_ostream<char> (0x0x7f4472021a28 instance) in std::basic_iostream<char> +std::basic_iostream<char>::_ZTCSd16_So: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0 +72 0 + +VTT for std::basic_iostream<char> +std::basic_iostream<char>::_ZTTSd: 7 entries +0 ((& std::basic_iostream<char>::_ZTVSd) + 24) +8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24) +16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64) +24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24) +32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64) +40 ((& std::basic_iostream<char>::_ZTVSd) + 104) +48 ((& std::basic_iostream<char>::_ZTVSd) + 64) + +Construction vtable for std::basic_istream<wchar_t> (0x0x7f4472021f70 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10 entries +0 24 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551592 +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0 +72 0 + +Construction vtable for std::basic_ostream<wchar_t> (0x0x7f4472021b60 instance) in std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10 entries +0 8 +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0 +32 0 +40 18446744073709551608 +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0 +72 0 + +VTT for std::basic_iostream<wchar_t> +std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7 entries +0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24) +8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24) +16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64) +24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24) +32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64) +40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104) +48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64) + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f44720944e0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16) + std::exception (0x0x7f44720ac360) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f44720944e0) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f4472094548) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16) + std::exception (0x0x7f44720ac480) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f4472094548) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f44720945b0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16) + std::exception (0x0x7f44720ac5a0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f44720945b0) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f4472094680) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16) + std::exception (0x0x7f44720ac6c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f4472094680) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f44720acf60) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f44720d8300) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f44720d8600) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f44720d8960) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f44720947b8) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16) + std::exception (0x0x7f4471d88120) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f44720947b8) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f4471dc8ea0) 0 empty + +Class std::__sp_array_delete + size=1 align=1 + base size=0 base align=1 +std::__sp_array_delete (0x0x7f4471def420) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f4471f35240) 0 + +Class QByteArrayView + size=16 align=8 + base size=16 base align=8 +QByteArrayView (0x0x7f4471c660c0) 0 + +Class QByteArray + size=24 align=8 + base size=24 base align=8 +QByteArray (0x0x7f447194ea80) 0 + +Class QByteArray::FromBase64Result + size=32 align=8 + base size=28 base align=8 +QByteArray::FromBase64Result (0x0x7f44717ac180) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f4471819c60) 0 + +Class QChar::fromUcs4(char32_t)::R + size=4 align=2 + base size=4 base align=2 +QChar::fromUcs4(char32_t)::R (0x0x7f4471578000) 0 + +Class QtPrivate::hide_char8_t + size=1 align=1 + base size=0 base align=1 +QtPrivate::hide_char8_t (0x0x7f4471578420) 0 empty + +Class QtPrivate::wrap_char + size=1 align=1 + base size=0 base align=1 +QtPrivate::wrap_char (0x0x7f4471578480) 0 empty + +Class QAnyStringView + size=16 align=8 + base size=16 base align=8 +QAnyStringView (0x0x7f44715fc600) 0 + +Class QStringTokenizerBaseBase::tokenizer_state + size=24 align=8 + base size=24 base align=8 +QStringTokenizerBaseBase::tokenizer_state (0x0x7f44716dbc00) 0 + +Class QStringTokenizerBaseBase + size=8 align=4 + base size=8 base align=4 +QStringTokenizerBaseBase (0x0x7f44716dbba0) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f447171dc60) 0 + +Class QString + size=24 align=8 + base size=24 base align=8 +QString (0x0x7f4471480f60) 0 + +Class QtPrivate::ArgBase + size=1 align=1 + base size=1 base align=1 +QtPrivate::ArgBase (0x0x7f44710a7300) 0 + +Class QtPrivate::QStringViewArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QStringViewArg (0x0x7f4471099548) 0 + QtPrivate::ArgBase (0x0x7f44710a7360) 0 + +Class QtPrivate::QLatin1StringArg + size=24 align=8 + base size=24 base align=8 +QtPrivate::QLatin1StringArg (0x0x7f4471099618) 0 + QtPrivate::ArgBase (0x0x7f44710a75a0) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f4471124d80) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f4471124e40) 0 empty + +Class QStringMatcher + size=312 align=8 + base size=312 base align=8 +QStringMatcher (0x0x7f4470b43060) 0 + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f4470bdc120) 0 empty + +Class QtPrivate::CompareAgainstLiteralZero + size=1 align=1 + base size=0 base align=1 +QtPrivate::CompareAgainstLiteralZero (0x0x7f4470bdcde0) 0 empty + +Class QPartialOrdering + size=1 align=1 + base size=1 base align=1 +QPartialOrdering (0x0x7f4470c00060) 0 + +Class QIODeviceBase + size=1 align=1 + base size=0 base align=1 +QIODeviceBase (0x0x7f4470c92120) 0 empty + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f4470db4af8) 0 + QIODeviceBase (0x0x7f4470c92180) 0 empty + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f4470c92300) 0 + +Class QtMetaContainerPrivate::QMetaContainerInterface + size=120 align=8 + base size=120 base align=8 +QtMetaContainerPrivate::QMetaContainerInterface (0x0x7f4470949720) 0 + +Class QtMetaContainerPrivate::QMetaSequenceInterface + size=216 align=8 + base size=216 base align=8 +QtMetaContainerPrivate::QMetaSequenceInterface (0x0x7f447094a2d8) 0 + QtMetaContainerPrivate::QMetaContainerInterface (0x0x7f44709497e0) 0 + +Class QtMetaContainerPrivate::QMetaAssociationInterface + size=240 align=8 + base size=240 base align=8 +QtMetaContainerPrivate::QMetaAssociationInterface (0x0x7f447094a3a8) 0 + QtMetaContainerPrivate::QMetaContainerInterface (0x0x7f44709498a0) 0 + +Class QMetaContainer + size=8 align=8 + base size=8 base align=8 +QMetaContainer (0x0x7f4470a363c0) 0 + +Class QMetaSequence + size=8 align=8 + base size=8 base align=8 +QMetaSequence (0x0x7f447094a750) 0 + QMetaContainer (0x0x7f4470a365a0) 0 + +Class QMetaAssociation + size=8 align=8 + base size=8 base align=8 +QMetaAssociation (0x0x7f447094a7b8) 0 + QMetaContainer (0x0x7f4470a36960) 0 + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f447066d000) 0 + +Class std::__detail::_List_node_header + size=24 align=8 + base size=24 base align=8 +std::__detail::_List_node_header (0x0x7f44705fe820) 0 + std::__detail::_List_node_base (0x0x7f447066d060) 0 + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f4470347120) 0 + +Class std::_Rb_tree_header + size=40 align=8 + base size=40 base align=8 +std::_Rb_tree_header (0x0x7f4470347480) 0 + +Class QMetaType + size=8 align=8 + base size=8 base align=8 +QMetaType (0x0x7f44701aaa80) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f4470238120) 0 + +Class QtPrivate::QMetaTypeInterface + size=112 align=8 + base size=112 base align=8 +QtPrivate::QMetaTypeInterface (0x0x7f4470120f60) 0 + +Class QtPrivate::QTypeNormalizer + size=16 align=8 + base size=16 base align=8 +QtPrivate::QTypeNormalizer (0x0x7f446fd52000) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f446fc5d6c0) 0 + +Class QAdoptSharedDataTag + size=1 align=1 + base size=0 base align=1 +QAdoptSharedDataTag (0x0x7f446fc5da20) 0 empty + +Class QtPrivate::RefCounted + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCounted (0x0x7f446fcc7a80) 0 + +Class QPropertyBindingPrivatePtr + size=8 align=8 + base size=8 base align=8 +QPropertyBindingPrivatePtr (0x0x7f446fcc7ba0) 0 + +Class QUntypedPropertyData::InheritsQUntypedPropertyData + size=1 align=1 + base size=0 base align=1 +QUntypedPropertyData::InheritsQUntypedPropertyData (0x0x7f446fd33240) 0 empty + +Class QUntypedPropertyData + size=1 align=1 + base size=0 base align=1 +QUntypedPropertyData (0x0x7f446fd331e0) 0 empty + +Class QtPrivate::BindingFunctionVTable + size=32 align=8 + base size=32 base align=8 +QtPrivate::BindingFunctionVTable (0x0x7f446fd332a0) 0 + +Class QtPrivate::QPropertyBindingFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::QPropertyBindingFunction (0x0x7f446fd33720) 0 + +Class QtPrivate::QPropertyBindingData + size=8 align=8 + base size=8 base align=8 +QtPrivate::QPropertyBindingData (0x0x7f446fd33780) 0 + +Class std::experimental::fundamentals_v2::source_location + size=24 align=8 + base size=24 base align=8 +std::experimental::fundamentals_v2::source_location (0x0x7f446fd33d80) 0 + +Class QPropertyBindingSourceLocation + size=24 align=8 + base size=24 base align=8 +QPropertyBindingSourceLocation (0x0x7f446f95f4e0) 0 + +Class QPropertyBindingError + size=8 align=8 + base size=8 base align=8 +QPropertyBindingError (0x0x7f446f95f7e0) 0 + +Class QUntypedPropertyBinding + size=8 align=8 + base size=8 base align=8 +QUntypedPropertyBinding (0x0x7f446f95f900) 0 + +Class QPropertyObserverBase + size=24 align=8 + base size=24 base align=8 +QPropertyObserverBase (0x0x7f446f95fba0) 0 + +Class QPropertyObserver + size=24 align=8 + base size=24 base align=8 +QPropertyObserver (0x0x7f446fd2c958) 0 + QPropertyObserverBase (0x0x7f446f95fd20) 0 + +Class QtPrivate::QBindableInterface + size=56 align=8 + base size=56 base align=8 +QtPrivate::QBindableInterface (0x0x7f446f9c5c00) 0 + +Class QUntypedBindable + size=16 align=8 + base size=16 base align=8 +QUntypedBindable (0x0x7f446f9ee840) 0 + +Class QBindingStatus + size=16 align=8 + base size=16 base align=8 +QBindingStatus (0x0x7f446fa20ae0) 0 + +Class QBindingStorage + size=16 align=8 + base size=16 base align=8 +QBindingStorage (0x0x7f446fa20b40) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f446fb28720) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f446f7d8480) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=80 align=8 + base size=80 base align=8 +QObjectData (0x0x7f446f818de0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f446f8c9780) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f446f8c9720) 0 + vptr=((& QObject::_ZTV7QObject) + 16) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f446f57f6c0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f446f57ff60) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f446f885b60) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16) + QObject (0x0x7f446f57ff00) 0 + primary-for QAbstractAnimation (0x0x7f446f885b60) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f446f5bb300) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f446f885bc8) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16) + QObject (0x0x7f446f5bb2a0) 0 + primary-for QAnimationDriver (0x0x7f446f885bc8) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f446f5bb4e0) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f446f885c30) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16) + QObject (0x0x7f446f5bb480) 0 + primary-for QEventLoop (0x0x7f446f885c30) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f446f5bb960) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f446f5bba20) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f446f5bba80) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))QAbstractEventDispatcher::startingUp +200 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f446f885dd0) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16) + QObject (0x0x7f446f5bb9c0) 0 + primary-for QAbstractEventDispatcher (0x0x7f446f885dd0) + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f446f63f240) 0 empty + +Class QStringConverterBase::State + size=48 align=8 + base size=48 base align=8 +QStringConverterBase::State (0x0x7f446f4e7cc0) 0 + +Class QStringConverterBase + size=1 align=1 + base size=0 base align=1 +QStringConverterBase (0x0x7f446f4e7c60) 0 empty + +Class QStringConverter::Interface + size=40 align=8 + base size=40 base align=8 +QStringConverter::Interface (0x0x7f446f507900) 0 + +Class QStringConverter + size=56 align=8 + base size=56 base align=8 +QStringConverter (0x0x7f446f13f000) 0 + QStringConverterBase (0x0x7f446f5078a0) 0 empty + +Class QStringEncoder + size=56 align=8 + base size=56 base align=8 +QStringEncoder (0x0x7f446f13f068) 0 + QStringConverter (0x0x7f446f13f0d0) 0 + QStringConverterBase (0x0x7f446f15a300) 0 empty + +Class QStringDecoder + size=56 align=8 + base size=56 base align=8 +QStringDecoder (0x0x7f446f13f138) 0 + QStringConverter (0x0x7f446f13f1a0) 0 + QStringConverterBase (0x0x7f446f17e180) 0 empty + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f446f13f208) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16) + QIODeviceBase (0x0x7f446f17ee40) 0 empty + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f446f1d1540) 0 + +Class QContiguousCacheData + size=40 align=8 + base size=40 base align=8 +QContiguousCacheData (0x0x7f446f2735a0) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f446f2c9000) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f446f2c9180) 0 + +Class QtPrivate::EnableInternalData + size=1 align=1 + base size=0 base align=1 +QtPrivate::EnableInternalData (0x0x7f446ef73360) 0 empty + +Class QDebug::Stream + size=88 align=8 + base size=88 base align=8 +QDebug::Stream (0x0x7f446ef98360) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f446ef46c98) 0 + QIODeviceBase (0x0x7f446ef98300) 0 empty + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f446f0c02a0) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f446f0c0360) 0 empty + +Class QVariant::PrivateShared + size=8 align=8 + base size=8 base align=8 +QVariant::PrivateShared (0x0x7f446ee67d80) 0 + +Class QVariant::Private + size=32 align=8 + base size=32 base align=8 +QVariant::Private (0x0x7f446ee67de0) 0 + +Class QVariant + size=32 align=8 + base size=32 base align=8 +QVariant (0x0x7f446ee67d20) 0 + +Class QtPrivate::QVariantTypeCoercer + size=32 align=8 + base size=32 base align=8 +QtPrivate::QVariantTypeCoercer (0x0x7f446ec371e0) 0 + +Class QVariantConstPointer + size=32 align=8 + base size=32 base align=8 +QVariantConstPointer (0x0x7f446ec37420) 0 + +Class QModelRoleData + size=40 align=8 + base size=40 base align=8 +QModelRoleData (0x0x7f446ec37600) 0 + +Class QModelRoleDataSpan + size=16 align=8 + base size=16 base align=8 +QModelRoleDataSpan (0x0x7f446ec77540) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f446ecc2540) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f446ed0f720) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f446e9a2000) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractItemModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractItemModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f446e98dd68) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16) + QObject (0x0x7f446e981f60) 0 + primary-for QAbstractItemModel (0x0x7f446e98dd68) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f446eaa9cc0) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractTableModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractTableModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f446e9ed618) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16) + QAbstractItemModel (0x0x7f446e9ed680) 0 + primary-for QAbstractTableModel (0x0x7f446e9ed618) + QObject (0x0x7f446eaa9c60) 0 + primary-for QAbstractItemModel (0x0x7f446e9ed680) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f446eaa9de0) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractListModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QAbstractListModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f446e9ed6e8) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16) + QAbstractItemModel (0x0x7f446e9ed750) 0 + primary-for QAbstractListModel (0x0x7f446e9ed6e8) + QObject (0x0x7f446eaa9d80) 0 + primary-for QAbstractItemModel (0x0x7f446e9ed750) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f446eb21240) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f446eb21300) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QAbstractProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QAbstractProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QAbstractProxyModel::setSourceModel +416 (int (*)(...))__cxa_pure_virtual +424 (int (*)(...))__cxa_pure_virtual +432 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +440 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f446eb1aaf8) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16) + QAbstractItemModel (0x0x7f446eb1ab60) 0 + primary-for QAbstractProxyModel (0x0x7f446eb1aaf8) + QObject (0x0x7f446eb212a0) 0 + primary-for QAbstractItemModel (0x0x7f446eb1ab60) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f446eb214e0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0 +48 0 +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f446eb1abc8) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16) + QAbstractAnimation (0x0x7f446eb1ac30) 0 + primary-for QAnimationGroup (0x0x7f446eb1abc8) + QObject (0x0x7f446eb21480) 0 + primary-for QAbstractAnimation (0x0x7f446eb1ac30) + +Class QAssociativeIterator + size=16 align=8 + base size=16 base align=8 +QAssociativeIterator (0x0x7f446eb1ad68) 0 + QIterator<QMetaAssociation> (0x0x7f446eb1add0) 0 + QBaseIterator<QMetaAssociation> (0x0x7f446eb21900) 0 + +Class QAssociativeConstIterator + size=16 align=8 + base size=16 base align=8 +QAssociativeConstIterator (0x0x7f446eb1af08) 0 + QConstIterator<QMetaAssociation> (0x0x7f446eb1af70) 0 + QBaseIterator<QMetaAssociation> (0x0x7f446eb21ea0) 0 + +Class QAssociativeIterable + size=24 align=8 + base size=24 base align=8 +QAssociativeIterable (0x0x7f446e797000) 0 + QIterable<QMetaAssociation> (0x0x7f446e78e3c0) 0 + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f446e870ea0) 0 + +Class QBitArray + size=24 align=8 + base size=24 base align=8 +QBitArray (0x0x7f446e8cec00) 0 + +Class QBitRef + size=16 align=8 + base size=16 base align=8 +QBitRef (0x0x7f446e8fab40) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f446e5426c0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f446e5471c0) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16) + QObject (0x0x7f446e542600) 0 + primary-for QIODevice (0x0x7f446e5471c0) + QIODeviceBase (0x0x7f446e542660) 0 empty + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f446e542a20) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f446e932f70) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16) + QIODevice (0x0x7f446e547230) 0 + primary-for QBuffer (0x0x7f446e932f70) + QObject (0x0x7f446e542960) 0 + primary-for QIODevice (0x0x7f446e547230) + QIODeviceBase (0x0x7f446e5429c0) 0 empty + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f446e542c60) 0 + +Class QByteArrayMatcher + size=1056 align=8 + base size=1056 base align=8 +QByteArrayMatcher (0x0x7f446e542c00) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f446e542de0) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f446e542d80) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f446e5ed540) 0 + +Class QCalendar::YearMonthDay + size=12 align=4 + base size=12 base align=4 +QCalendar::YearMonthDay (0x0x7f446e6fd300) 0 + +Class QCalendar + size=8 align=8 + base size=8 base align=8 +QCalendar (0x0x7f446e6fd2a0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f446e6fd660) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f446e388c60) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f446e3d2ea0) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f446e3d2f00) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f446e3d2e40) 0 + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f446e47b180) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f446e47b9c0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f446e525ba0) 0 + +Class QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel + size=1 align=1 + base size=0 base align=1 +QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel (0x0x7f446e1aa3c0) 0 empty + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f446e1aa420) 0 + +Class QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator + size=24 align=8 + base size=17 base align=8 +QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator (0x0x7f446e1aa600) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f446e236300) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f446e2fde40) 0 + +Class QCborParserError + size=16 align=8 + base size=16 base align=8 +QCborParserError (0x0x7f446df95000) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f446df950c0) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f446e0af960) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f446e0e6ea0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f446e0e6f00) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f446e0e6e40) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f446ddf64e0) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f446ddf6540) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f446ddf6480) 0 + +Class qfloat16::Wrap + size=2 align=2 + base size=2 base align=2 +qfloat16::Wrap (0x0x7f446dc0b5a0) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f446dc0b540) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f446dcc9d80) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f446dd2e720) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f446d95e180) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f446d95e360) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f446da02d80) 0 + +Class QEvent::InputEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::InputEventTag (0x0x7f446da8c660) 0 empty + +Class QEvent::PointerEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::PointerEventTag (0x0x7f446da8c6c0) 0 empty + +Class QEvent::SinglePointEventTag + size=1 align=1 + base size=0 base align=1 +QEvent::SinglePointEventTag (0x0x7f446da8c720) 0 empty + +Vtable for QEvent +QEvent::_ZTV6QEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QEvent + size=16 align=8 + base size=16 base align=8 +QEvent (0x0x7f446da8c600) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QTimerEvent::clone + +Class QTimerEvent + size=24 align=8 + base size=20 base align=8 +QTimerEvent (0x0x7f446da83d68) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16) + QEvent (0x0x7f446dae90c0) 0 + primary-for QTimerEvent (0x0x7f446da83d68) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QChildEvent::clone + +Class QChildEvent + size=24 align=8 + base size=24 base align=8 +QChildEvent (0x0x7f446da83dd0) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16) + QEvent (0x0x7f446dae95a0) 0 + primary-for QChildEvent (0x0x7f446da83dd0) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDynamicPropertyChangeEvent::clone + +Class QDynamicPropertyChangeEvent + size=40 align=8 + base size=40 base align=8 +QDynamicPropertyChangeEvent (0x0x7f446da83e38) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16) + QEvent (0x0x7f446dae99c0) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f446da83e38) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDeferredDeleteEvent::clone + +Class QDeferredDeleteEvent + size=24 align=8 + base size=20 base align=8 +QDeferredDeleteEvent (0x0x7f446da83ea0) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16) + QEvent (0x0x7f446dae9c60) 0 + primary-for QDeferredDeleteEvent (0x0x7f446da83ea0) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f446db24000) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f446da83f08) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16) + QObject (0x0x7f446dae9f60) 0 + primary-for QCoreApplication (0x0x7f446da83f08) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f446db241e0) 0 + +Class QConcatenateTablesProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QConcatenateTablesProxyModel::QPrivateSignal (0x0x7f446db24300) 0 empty + +Vtable for QConcatenateTablesProxyModel +QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QConcatenateTablesProxyModel) +16 (int (*)(...))QConcatenateTablesProxyModel::metaObject +24 (int (*)(...))QConcatenateTablesProxyModel::qt_metacast +32 (int (*)(...))QConcatenateTablesProxyModel::qt_metacall +40 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +48 (int (*)(...))QConcatenateTablesProxyModel::~QConcatenateTablesProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QConcatenateTablesProxyModel::index +120 (int (*)(...))QConcatenateTablesProxyModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QConcatenateTablesProxyModel::rowCount +144 (int (*)(...))QConcatenateTablesProxyModel::columnCount +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))QConcatenateTablesProxyModel::data +168 (int (*)(...))QConcatenateTablesProxyModel::setData +176 (int (*)(...))QConcatenateTablesProxyModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QConcatenateTablesProxyModel::itemData +200 (int (*)(...))QConcatenateTablesProxyModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QConcatenateTablesProxyModel::mimeTypes +224 (int (*)(...))QConcatenateTablesProxyModel::mimeData +232 (int (*)(...))QConcatenateTablesProxyModel::canDropMimeData +240 (int (*)(...))QConcatenateTablesProxyModel::dropMimeData +248 (int (*)(...))QAbstractItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QConcatenateTablesProxyModel::flags +336 (int (*)(...))QAbstractItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QConcatenateTablesProxyModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QConcatenateTablesProxyModel + size=16 align=8 + base size=16 base align=8 +QConcatenateTablesProxyModel (0x0x7f446da83f70) 0 + vptr=((& QConcatenateTablesProxyModel::_ZTV28QConcatenateTablesProxyModel) + 16) + QAbstractItemModel (0x0x7f446d747000) 0 + primary-for QConcatenateTablesProxyModel (0x0x7f446da83f70) + QObject (0x0x7f446db242a0) 0 + primary-for QAbstractItemModel (0x0x7f446d747000) + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f446db24480) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f446db245a0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f446db248a0) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f446d84f9c0) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QFileDevice::fileName +256 (int (*)(...))QFileDevice::resize +264 (int (*)(...))QFileDevice::permissions +272 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f446d85b208) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16) + QIODevice (0x0x7f446d7f4770) 0 + primary-for QFileDevice (0x0x7f446d85b208) + QObject (0x0x7f446d84f900) 0 + primary-for QIODevice (0x0x7f446d7f4770) + QIODeviceBase (0x0x7f446d84f960) 0 empty + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f446d8b7540) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QFile::fileName +256 (int (*)(...))QFile::resize +264 (int (*)(...))QFile::permissions +272 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f446d85b618) 0 + vptr=((& QFile::_ZTV5QFile) + 16) + QFileDevice (0x0x7f446d85b680) 0 + primary-for QFile (0x0x7f446d85b618) + QIODevice (0x0x7f446d868700) 0 + primary-for QFileDevice (0x0x7f446d85b680) + QObject (0x0x7f446d8b7480) 0 + primary-for QIODevice (0x0x7f446d868700) + QIODeviceBase (0x0x7f446d8b74e0) 0 empty + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f446d8b77e0) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f446d58b240) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f446d6444e0) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f446d6448a0) 0 + +Vtable for QException +QException::_ZTV10QException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f446d71e270) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16) + std::exception (0x0x7f446d35f000) 0 nearly-empty + primary-for QException (0x0x7f446d71e270) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=16 align=8 + base size=16 base align=8 +QUnhandledException (0x0x7f446d71e2d8) 0 + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16) + QException (0x0x7f446d71e340) 0 nearly-empty + primary-for QUnhandledException (0x0x7f446d71e2d8) + std::exception (0x0x7f446d35f060) 0 nearly-empty + primary-for QException (0x0x7f446d71e340) + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f446d35fea0) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f446d35ff00) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f446d3a9180) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f446d39f548) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16) + QObject (0x0x7f446d3a9120) 0 + primary-for QFileSelector (0x0x7f446d39f548) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f446d3a9360) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f446d39f5b0) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16) + QObject (0x0x7f446d3a9300) 0 + primary-for QFileSystemWatcher (0x0x7f446d39f5b0) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class QRunnable + size=16 align=8 + base size=9 base align=8 +QRunnable (0x0x7f446d3a94e0) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f446d3a96c0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f446d39f680) 0 + QBasicMutex (0x0x7f446d420420) 0 + +Class QRecursiveMutex + size=24 align=8 + base size=24 base align=8 +QRecursiveMutex (0x0x7f446d420840) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f446d420e40) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f446d491480) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f446d1c2120) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16) + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f446d1f4b40) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f446d1fd8f0) 0 + std::__mutex_base (0x0x7f446d1f4ba0) 0 + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f446d1f4d80) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f446d1f4de0) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f446d1f4e40) 0 empty + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f446d224840) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f446d1fd958) 0 + std::__recursive_mutex_base (0x0x7f446d2248a0) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f446d6b2f50) 0 + std::__mutex_base (0x0x7f446d224c60) 0 + std::__timed_mutex_impl<std::timed_mutex> (0x0x7f446d224cc0) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f446d6b2ee0) 0 + std::__recursive_mutex_base (0x0x7f446d25f0c0) 0 + std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7f446d25f120) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f446d25ff00) 0 + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f446d297180) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16) + +Vtable for std::thread::_State +std::thread::_State::_ZTVNSt6thread6_StateE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread6_StateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_State + size=8 align=8 + base size=8 base align=8 +std::thread::_State (0x0x7f446d2e70c0) 0 nearly-empty + vptr=((& std::thread::_State::_ZTVNSt6thread6_StateE) + 16) + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f446d2e7120) 0 + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f446d2e7060) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f446d0c8360) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f446d0c8720) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f446d0c8780) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f446cd76d20) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f446d0fbb60) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16) + std::logic_error (0x0x7f446d0fbbc8) 0 + primary-for std::future_error (0x0x7f446d0fbb60) + std::exception (0x0x7f446cdb5420) 0 nearly-empty + primary-for std::logic_error (0x0x7f446d0fbbc8) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f446cdb5b40) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0 +32 0 + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f446cdb5ae0) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f446cf265a0) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f446cf283a8) 0 + std::__at_thread_exit_elt (0x0x7f446cf26660) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f446cdb5cc0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f446cdb5a80) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f446c7dc7b8) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16) + std::__future_base::_State_baseV2 (0x0x7f446c82a360) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f446c7dc7b8) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f446c82ac00) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f446c7dcaf8) 0 + vptr=((& QThread::_ZTV7QThread) + 16) + QObject (0x0x7f446c82aba0) 0 + primary-for QThread (0x0x7f446c7dcaf8) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f446c867000) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f446c7dcb60) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16) + QObject (0x0x7f446c82af60) 0 + primary-for QThreadPool (0x0x7f446c7dcb60) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f446c627720) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f446c5f57b8) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16) + QObject (0x0x7f446c6276c0) 0 + primary-for QFutureWatcherBase (0x0x7f446c5f57b8) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f446c627c60) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QIdentityProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QIdentityProxyModel::insertRows +272 (int (*)(...))QIdentityProxyModel::insertColumns +280 (int (*)(...))QIdentityProxyModel::removeRows +288 (int (*)(...))QIdentityProxyModel::removeColumns +296 (int (*)(...))QIdentityProxyModel::moveRows +304 (int (*)(...))QIdentityProxyModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QAbstractProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QIdentityProxyModel::match +360 (int (*)(...))QAbstractProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QIdentityProxyModel::setSourceModel +416 (int (*)(...))QIdentityProxyModel::mapToSource +424 (int (*)(...))QIdentityProxyModel::mapFromSource +432 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +440 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f446c5f59c0) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16) + QAbstractProxyModel (0x0x7f446c5f5a28) 0 + primary-for QIdentityProxyModel (0x0x7f446c5f59c0) + QAbstractItemModel (0x0x7f446c5f5a90) 0 + primary-for QAbstractProxyModel (0x0x7f446c5f5a28) + QObject (0x0x7f446c627c00) 0 + primary-for QAbstractItemModel (0x0x7f446c5f5a90) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f446c627de0) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f446c6b49c0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f446c6ba820) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16) + QObject (0x0x7f446c6b4960) 0 + primary-for QItemSelectionModel (0x0x7f446c6ba820) + +Class QItemSelection + size=24 align=8 + base size=24 base align=8 +QItemSelection (0x0x7f446c6bad00) 0 + QList<QItemSelectionRange> (0x0x7f446c6bad68) 0 + QListSpecialMethods<QItemSelectionRange> (0x0x7f446c6badd0) 0 empty + QListSpecialMethodsBase<QItemSelectionRange> (0x0x7f446c7103c0) 0 empty + +Class QJsonValue + size=24 align=8 + base size=24 base align=8 +QJsonValue (0x0x7f446c3a60c0) 0 + +Class QJsonValueRef + size=16 align=8 + base size=16 base align=8 +QJsonValueRef (0x0x7f446c3a65a0) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=16 base align=8 +QJsonArray::iterator (0x0x7f446c4007e0) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=16 base align=8 +QJsonArray::const_iterator (0x0x7f446c400840) 0 + +Class QJsonArray + size=8 align=8 + base size=8 base align=8 +QJsonArray (0x0x7f446c400780) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f446c4ad240) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f446c4ad2a0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=16 base align=8 +QJsonObject::iterator (0x0x7f446c2427e0) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=16 base align=8 +QJsonObject::const_iterator (0x0x7f446c242840) 0 + +Class QJsonObject + size=8 align=8 + base size=8 base align=8 +QJsonObject (0x0x7f446c242780) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f446c2f8360) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=24 align=8 + base size=24 base align=8 +QLibrary (0x0x7f446c2eaea0) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16) + QObject (0x0x7f446c2f8300) 0 + primary-for QLibrary (0x0x7f446c2eaea0) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f446c2f8960) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f446c2f8900) 0 + +Class QTypeRevision + size=2 align=1 + base size=2 base align=1 +QTypeRevision (0x0x7f446c010120) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f446c0668a0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f446c066960) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f446c0e5000) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f446c1336c0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f446bd7fcc0) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f446bdf34e0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f446bdf3720) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f446bdf36c0) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f446be3d600) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f446bedb060) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f446bf2a900) 0 + +Class QMetaMethod::Data + size=8 align=8 + base size=8 base align=8 +QMetaMethod::Data (0x0x7f446bf2a9c0) 0 + +Class QMetaMethod + size=16 align=8 + base size=16 base align=8 +QMetaMethod (0x0x7f446bf2a960) 0 + +Class QMetaEnum::Data + size=8 align=8 + base size=8 base align=8 +QMetaEnum::Data (0x0x7f446bba8c00) 0 + +Class QMetaEnum + size=16 align=8 + base size=16 base align=8 +QMetaEnum (0x0x7f446bba8ba0) 0 + +Class QMetaProperty::Data + size=8 align=8 + base size=8 base align=8 +QMetaProperty::Data (0x0x7f446bbee960) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f446bbee900) 0 + +Class QMetaClassInfo::Data + size=8 align=8 + base size=8 base align=8 +QMetaClassInfo::Data (0x0x7f446bc19000) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=16 base align=8 +QMetaClassInfo (0x0x7f446bbee9c0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f446bc37e40) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f446bc43958) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16) + QObject (0x0x7f446bc37de0) 0 + primary-for QMimeData (0x0x7f446bc43958) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f446bc37ba0) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f446bcca9c0) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f446bccaa80) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=40 align=8 + base size=40 base align=8 +QObjectCleanupHandler (0x0x7f446bccf7b8) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16) + QObject (0x0x7f446bccaa20) 0 + primary-for QObjectCleanupHandler (0x0x7f446bccf7b8) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f446bccab40) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f446bd27780) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f446bd32208) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16) + QAnimationGroup (0x0x7f446bd32270) 0 + primary-for QParallelAnimationGroup (0x0x7f446bd32208) + QAbstractAnimation (0x0x7f446bd322d8) 0 + primary-for QAnimationGroup (0x0x7f446bd32270) + QObject (0x0x7f446bd27720) 0 + primary-for QAbstractAnimation (0x0x7f446bd322d8) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f446bd27960) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f446bd32340) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16) + QAbstractAnimation (0x0x7f446bd323a8) 0 + primary-for QPauseAnimation (0x0x7f446bd32340) + QObject (0x0x7f446bd27900) 0 + primary-for QAbstractAnimation (0x0x7f446bd323a8) + +Class QPluginMetaData + size=16 align=8 + base size=16 base align=8 +QPluginMetaData (0x0x7f446b95e480) 0 + +Class QStaticPlugin + size=24 align=8 + base size=24 base align=8 +QStaticPlugin (0x0x7f446b95e4e0) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f446b97df00) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f446b984f70) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16) + QObject (0x0x7f446b97dea0) 0 + primary-for QPluginLoader (0x0x7f446b984f70) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f446b9a7000) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f446ba0c720) 0 empty + +Class QProcess::Use_setChildProcessModifier_Instead + size=1 align=1 + base size=0 base align=1 +QProcess::Use_setChildProcessModifier_Instead (0x0x7f446ba0c780) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 32 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QProcess::writeData +248 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f446ba1a000) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16) + QIODevice (0x0x7f446ba18070) 0 + primary-for QProcess (0x0x7f446ba1a000) + QObject (0x0x7f446ba0c660) 0 + primary-for QIODevice (0x0x7f446ba18070) + QIODeviceBase (0x0x7f446ba0c6c0) 0 empty + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f446ba55540) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f446ba1a068) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16) + QAbstractAnimation (0x0x7f446ba1a0d0) 0 + primary-for QVariantAnimation (0x0x7f446ba1a068) + QObject (0x0x7f446ba554e0) 0 + primary-for QAbstractAnimation (0x0x7f446ba1a0d0) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f446ba55780) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f446ba1a1a0) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16) + QVariantAnimation (0x0x7f446ba1a208) 0 + primary-for QPropertyAnimation (0x0x7f446ba1a1a0) + QAbstractAnimation (0x0x7f446ba1a270) 0 + primary-for QVariantAnimation (0x0x7f446ba1a208) + QObject (0x0x7f446ba55720) 0 + primary-for QAbstractAnimation (0x0x7f446ba1a270) + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f446bae4ea0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f446b7fd360) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f446b7fd300) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f446b5b4ae0) 0 + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f446b3d4a20) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f446b3d49c0) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f446b42df08) 0 + QRandomGenerator (0x0x7f446b450cc0) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f446b475900) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f446b475b40) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f446b4e2060) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f446b4e2540) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f446b534f60) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f446b1b3780) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f446b28b5a0) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f446af6b120) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f446af6b420) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QSaveFile::writeData +248 (int (*)(...))QSaveFile::fileName +256 (int (*)(...))QFileDevice::resize +264 (int (*)(...))QFileDevice::permissions +272 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f446b2fd1a0) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16) + QFileDevice (0x0x7f446b2fd208) 0 + primary-for QSaveFile (0x0x7f446b2fd1a0) + QIODevice (0x0x7f446b301230) 0 + primary-for QFileDevice (0x0x7f446b2fd208) + QObject (0x0x7f446af6b360) 0 + primary-for QIODevice (0x0x7f446b301230) + QIODeviceBase (0x0x7f446af6b3c0) 0 empty + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f446af6ba20) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f446aff1240) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f446b039f00) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f446b04ed68) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16) + QAnimationGroup (0x0x7f446b04edd0) 0 + primary-for QSequentialAnimationGroup (0x0x7f446b04ed68) + QAbstractAnimation (0x0x7f446b04ee38) 0 + primary-for QAnimationGroup (0x0x7f446b04edd0) + QObject (0x0x7f446b039ea0) 0 + primary-for QAbstractAnimation (0x0x7f446b04ee38) + +Class QSequentialIterator + size=16 align=8 + base size=16 base align=8 +QSequentialIterator (0x0x7f446b04ef70) 0 + QIterator<QMetaSequence> (0x0x7f446b04eea0) 0 + QBaseIterator<QMetaSequence> (0x0x7f446b0662a0) 0 + +Class QSequentialConstIterator + size=16 align=8 + base size=16 base align=8 +QSequentialConstIterator (0x0x7f446b09a068) 0 + QConstIterator<QMetaSequence> (0x0x7f446b09a0d0) 0 + QBaseIterator<QMetaSequence> (0x0x7f446b066840) 0 + +Class QSequentialIterable + size=24 align=8 + base size=24 base align=8 +QSequentialIterable (0x0x7f446b09a138) 0 + QIterable<QMetaSequence> (0x0x7f446b066d80) 0 + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f446ad8e360) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f446ad8b5b0) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16) + QObject (0x0x7f446ad8e300) 0 + primary-for QSettings (0x0x7f446ad8b5b0) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f446ad8e780) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f446ad8b618) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16) + QObject (0x0x7f446ad8e720) 0 + primary-for QSharedMemory (0x0x7f446ad8b618) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f446ad8e960) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f446ad8b680) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16) + QObject (0x0x7f446ad8e900) 0 + primary-for QSignalMapper (0x0x7f446ad8b680) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f4469d823c0) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f4469d4e4e0) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16) + QObject (0x0x7f4469d82360) 0 + primary-for QSocketNotifier (0x0x7f4469d4e4e0) + +Class QSocketDescriptor + size=4 align=4 + base size=4 base align=4 +QSocketDescriptor (0x0x7f4469d82540) 0 + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f4469d82c00) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 59 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QSortFilterProxyModel::mimeTypes +224 (int (*)(...))QSortFilterProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QSortFilterProxyModel::dropMimeData +248 (int (*)(...))QSortFilterProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QSortFilterProxyModel::insertRows +272 (int (*)(...))QSortFilterProxyModel::insertColumns +280 (int (*)(...))QSortFilterProxyModel::removeRows +288 (int (*)(...))QSortFilterProxyModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QSortFilterProxyModel::fetchMore +320 (int (*)(...))QSortFilterProxyModel::canFetchMore +328 (int (*)(...))QSortFilterProxyModel::flags +336 (int (*)(...))QSortFilterProxyModel::sort +344 (int (*)(...))QSortFilterProxyModel::buddy +352 (int (*)(...))QSortFilterProxyModel::match +360 (int (*)(...))QSortFilterProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QSortFilterProxyModel::setSourceModel +416 (int (*)(...))QSortFilterProxyModel::mapToSource +424 (int (*)(...))QSortFilterProxyModel::mapFromSource +432 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +440 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +448 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +456 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +464 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f4469d4e548) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16) + QAbstractProxyModel (0x0x7f4469d4e5b0) 0 + primary-for QSortFilterProxyModel (0x0x7f4469d4e548) + QAbstractItemModel (0x0x7f4469d4e618) 0 + primary-for QAbstractProxyModel (0x0x7f4469d4e5b0) + QObject (0x0x7f4469d82ba0) 0 + primary-for QAbstractItemModel (0x0x7f4469d4e618) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f4469dd4000) 0 empty + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f4469dd4900) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f4469e872a0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f4469ae9ae0) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QStringListModel::itemData +200 (int (*)(...))QStringListModel::setItemData +208 (int (*)(...))QStringListModel::clearItemData +216 (int (*)(...))QAbstractItemModel::mimeTypes +224 (int (*)(...))QAbstractItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QAbstractListModel::dropMimeData +248 (int (*)(...))QStringListModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QStringListModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QStringListModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QStringListModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QStringListModel::flags +336 (int (*)(...))QStringListModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QAbstractItemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QStringListModel + size=40 align=8 + base size=40 base align=8 +QStringListModel (0x0x7f4469afa138) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16) + QAbstractListModel (0x0x7f4469afa1a0) 0 + primary-for QStringListModel (0x0x7f4469afa138) + QAbstractItemModel (0x0x7f4469afa208) 0 + primary-for QAbstractListModel (0x0x7f4469afa1a0) + QObject (0x0x7f4469ae9a80) 0 + primary-for QAbstractItemModel (0x0x7f4469afa208) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f4469ae9ba0) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f4469ae9c60) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f4469ae9de0) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 35 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QFileDevice::writeData +248 (int (*)(...))QTemporaryFile::fileName +256 (int (*)(...))QFile::resize +264 (int (*)(...))QFile::permissions +272 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f4469afa270) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16) + QFile (0x0x7f4469afa2d8) 0 + primary-for QTemporaryFile (0x0x7f4469afa270) + QFileDevice (0x0x7f4469afa340) 0 + primary-for QFile (0x0x7f4469afa2d8) + QIODevice (0x0x7f4469aef620) 0 + primary-for QFileDevice (0x0x7f4469afa340) + QObject (0x0x7f4469ae9d20) 0 + primary-for QIODevice (0x0x7f4469aef620) + QIODeviceBase (0x0x7f4469ae9d80) 0 empty + +Class QTextBoundaryFinder + size=72 align=8 + base size=72 base align=8 +QTextBoundaryFinder (0x0x7f4469b54060) 0 + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f4469b54600) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f4469b54cc0) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f4469afa4e0) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16) + QObject (0x0x7f4469b54c60) 0 + primary-for QTimeLine (0x0x7f4469afa4e0) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f4469b54ea0) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=16 align=8 + base size=16 base align=8 +QTimer (0x0x7f4469afa548) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16) + QObject (0x0x7f4469b54e40) 0 + primary-for QTimer (0x0x7f4469afa548) + +Class QTimeZone::OffsetData + size=48 align=8 + base size=44 base align=8 +QTimeZone::OffsetData (0x0x7f4469bcbcc0) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f4469bcbc60) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f4469c57d20) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f4469c66270) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16) + QObject (0x0x7f4469c57cc0) 0 + primary-for QTranslator (0x0x7f4469c66270) + +Class QTransposeProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTransposeProxyModel::QPrivateSignal (0x0x7f4469c57f00) 0 empty + +Vtable for QTransposeProxyModel +QTransposeProxyModel::_ZTV20QTransposeProxyModel: 56 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTransposeProxyModel) +16 (int (*)(...))QTransposeProxyModel::metaObject +24 (int (*)(...))QTransposeProxyModel::qt_metacast +32 (int (*)(...))QTransposeProxyModel::qt_metacall +40 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +48 (int (*)(...))QTransposeProxyModel::~QTransposeProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTransposeProxyModel::index +120 (int (*)(...))QTransposeProxyModel::parent +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))QTransposeProxyModel::rowCount +144 (int (*)(...))QTransposeProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QTransposeProxyModel::headerData +184 (int (*)(...))QTransposeProxyModel::setHeaderData +192 (int (*)(...))QTransposeProxyModel::itemData +200 (int (*)(...))QTransposeProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::clearItemData +216 (int (*)(...))QAbstractProxyModel::mimeTypes +224 (int (*)(...))QAbstractProxyModel::mimeData +232 (int (*)(...))QAbstractProxyModel::canDropMimeData +240 (int (*)(...))QAbstractProxyModel::dropMimeData +248 (int (*)(...))QAbstractProxyModel::supportedDropActions +256 (int (*)(...))QAbstractProxyModel::supportedDragActions +264 (int (*)(...))QTransposeProxyModel::insertRows +272 (int (*)(...))QTransposeProxyModel::insertColumns +280 (int (*)(...))QTransposeProxyModel::removeRows +288 (int (*)(...))QTransposeProxyModel::removeColumns +296 (int (*)(...))QTransposeProxyModel::moveRows +304 (int (*)(...))QTransposeProxyModel::moveColumns +312 (int (*)(...))QAbstractProxyModel::fetchMore +320 (int (*)(...))QAbstractProxyModel::canFetchMore +328 (int (*)(...))QAbstractProxyModel::flags +336 (int (*)(...))QTransposeProxyModel::sort +344 (int (*)(...))QAbstractProxyModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QTransposeProxyModel::span +368 (int (*)(...))QAbstractProxyModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractProxyModel::submit +392 (int (*)(...))QAbstractProxyModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData +408 (int (*)(...))QTransposeProxyModel::setSourceModel +416 (int (*)(...))QTransposeProxyModel::mapToSource +424 (int (*)(...))QTransposeProxyModel::mapFromSource +432 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +440 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QTransposeProxyModel + size=16 align=8 + base size=16 base align=8 +QTransposeProxyModel (0x0x7f4469c662d8) 0 + vptr=((& QTransposeProxyModel::_ZTV20QTransposeProxyModel) + 16) + QAbstractProxyModel (0x0x7f4469c66340) 0 + primary-for QTransposeProxyModel (0x0x7f4469c662d8) + QAbstractItemModel (0x0x7f4469c663a8) 0 + primary-for QAbstractProxyModel (0x0x7f4469c66340) + QObject (0x0x7f4469c57ea0) 0 + primary-for QAbstractItemModel (0x0x7f4469c663a8) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f4469c950c0) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f44699528a0) 0 + +Class QtPrivate::QXmlString + size=24 align=8 + base size=24 base align=8 +QtPrivate::QXmlString (0x0x7f44699529c0) 0 + +Class QXmlStreamAttribute + size=104 align=8 + base size=97 base align=8 +QXmlStreamAttribute (0x0x7f446999a840) 0 + +Class QXmlStreamAttributes + size=24 align=8 + base size=24 base align=8 +QXmlStreamAttributes (0x0x7f44699f4270) 0 + QList<QXmlStreamAttribute> (0x0x7f44699f42d8) 0 + QListSpecialMethods<QXmlStreamAttribute> (0x0x7f44699f4340) 0 empty + QListSpecialMethodsBase<QXmlStreamAttribute> (0x0x7f44699e5960) 0 empty + +Class QXmlStreamNamespaceDeclaration + size=48 align=8 + base size=48 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f4469a5a1e0) 0 + +Class QXmlStreamNotationDeclaration + size=72 align=8 + base size=72 base align=8 +QXmlStreamNotationDeclaration (0x0x7f4469a7d8a0) 0 + +Class QXmlStreamEntityDeclaration + size=120 align=8 + base size=120 base align=8 +QXmlStreamEntityDeclaration (0x0x7f4469aa7f00) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f44696f56c0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f44696f5720) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f44696f5cc0) 0 + +Vtable for QPaintDevice +QPaintDevice::_ZTV12QPaintDevice: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintDevice) +16 0 +24 0 +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDevice + size=16 align=8 + base size=10 base align=8 +QPaintDevice (0x0x7f44696f5ea0) 0 + vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16) + +Class QRgba64 + size=8 align=8 + base size=8 base align=8 +QRgba64 (0x0x7f4469755960) 0 + +Class QColor::CT + size=10 align=2 + base size=10 base align=2 +QColor::CT (0x0x7f4469801660) 0 + +Class QColor + size=16 align=4 + base size=14 base align=4 +QColor (0x0x7f4469801600) 0 + +Class QPixelFormat + size=8 align=8 + base size=8 base align=8 +QPixelFormat (0x0x7f44698936c0) 0 + +Class QPolygon + size=24 align=8 + base size=24 base align=8 +QPolygon (0x0x7f4473a17340) 0 + QList<QPoint> (0x0x7f4473a173a8) 0 + QListSpecialMethods<QPoint> (0x0x7f4473a172d8) 0 empty + QListSpecialMethodsBase<QPoint> (0x0x7f4473d43d20) 0 empty + +Class QPolygonF + size=24 align=8 + base size=24 base align=8 +QPolygonF (0x0x7f4473d6a270) 0 + QList<QPointF> (0x0x7f4473d6a2d8) 0 + QListSpecialMethods<QPointF> (0x0x7f4473d6a340) 0 empty + QListSpecialMethodsBase<QPointF> (0x0x7f44723e2a20) 0 empty + +Class QRegion::QRegionData + size=16 align=8 + base size=16 base align=8 +QRegion::QRegionData (0x0x7f447155ce40) 0 + +Class QRegion + size=8 align=8 + base size=8 base align=8 +QRegion (0x0x7f447155cde0) 0 + +Class QTransform::Affine + size=8 align=8 + base size=8 base align=8 +QTransform::Affine (0x0x7f446e93e960) 0 + +Class QTransform + size=80 align=8 + base size=74 base align=8 +QTransform (0x0x7f446e93e8a0) 0 + +Vtable for QImage +QImage::_ZTV6QImage: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QImage) +16 (int (*)(...))QImage::~QImage +24 (int (*)(...))QImage::~QImage +32 (int (*)(...))QImage::devType +40 (int (*)(...))QImage::paintEngine +48 (int (*)(...))QImage::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QImage + size=24 align=8 + base size=24 base align=8 +QImage (0x0x7f4473c4d820) 0 + vptr=((& QImage::_ZTV6QImage) + 16) + QPaintDevice (0x0x7f446e2fd2a0) 0 + primary-for QImage (0x0x7f4473c4d820) + +Vtable for QPixmap +QPixmap::_ZTV7QPixmap: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QPixmap) +16 (int (*)(...))QPixmap::~QPixmap +24 (int (*)(...))QPixmap::~QPixmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPixmap + size=24 align=8 + base size=24 base align=8 +QPixmap (0x0x7f447396c270) 0 + vptr=((& QPixmap::_ZTV7QPixmap) + 16) + QPaintDevice (0x0x7f446d6440c0) 0 + primary-for QPixmap (0x0x7f447396c270) + +Class QIcon + size=8 align=8 + base size=8 base align=8 +QIcon (0x0x7f446c6b4840) 0 + +Vtable for QAbstractFileIconProvider +QAbstractFileIconProvider::_ZTV25QAbstractFileIconProvider: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAbstractFileIconProvider) +16 (int (*)(...))QAbstractFileIconProvider::~QAbstractFileIconProvider +24 (int (*)(...))QAbstractFileIconProvider::~QAbstractFileIconProvider +32 (int (*)(...))QAbstractFileIconProvider::icon +40 (int (*)(...))QAbstractFileIconProvider::icon +48 (int (*)(...))QAbstractFileIconProvider::type +56 (int (*)(...))QAbstractFileIconProvider::setOptions +64 (int (*)(...))QAbstractFileIconProvider::options + +Class QAbstractFileIconProvider + size=16 align=8 + base size=16 base align=8 +QAbstractFileIconProvider (0x0x7f446bb89cc0) 0 + vptr=((& QAbstractFileIconProvider::_ZTV25QAbstractFileIconProvider) + 16) + +Class QVector2D + size=8 align=4 + base size=8 base align=4 +QVector2D (0x0x7f446bbee7e0) 0 + +Class QVector3D + size=12 align=4 + base size=12 base align=4 +QVector3D (0x0x7f446b2dd1e0) 0 + +Class QVector4D + size=16 align=4 + base size=16 base align=4 +QVector4D (0x0x7f44699c68a0) 0 + +Class QScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScreen::QPrivateSignal (0x0x7f446bb0f360) 0 empty + +Vtable for QScreen +QScreen::_ZTV7QScreen: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QScreen) +16 (int (*)(...))QScreen::metaObject +24 (int (*)(...))QScreen::qt_metacast +32 (int (*)(...))QScreen::qt_metacall +40 (int (*)(...))QScreen::~QScreen +48 (int (*)(...))QScreen::~QScreen +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScreen + size=16 align=8 + base size=16 base align=8 +QScreen (0x0x7f4473a42888) 0 + vptr=((& QScreen::_ZTV7QScreen) + 16) + QObject (0x0x7f446bb0f300) 0 + primary-for QScreen (0x0x7f4473a42888) + +Class QInputDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputDevice::QPrivateSignal (0x0x7f446bb0f540) 0 empty + +Vtable for QInputDevice +QInputDevice::_ZTV12QInputDevice: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputDevice) +16 (int (*)(...))QInputDevice::metaObject +24 (int (*)(...))QInputDevice::qt_metacast +32 (int (*)(...))QInputDevice::qt_metacall +40 (int (*)(...))QInputDevice::~QInputDevice +48 (int (*)(...))QInputDevice::~QInputDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputDevice + size=16 align=8 + base size=16 base align=8 +QInputDevice (0x0x7f4473a428f0) 0 + vptr=((& QInputDevice::_ZTV12QInputDevice) + 16) + QObject (0x0x7f446bb0f4e0) 0 + primary-for QInputDevice (0x0x7f4473a428f0) + +Class QPointingDeviceUniqueId + size=8 align=8 + base size=8 base align=8 +QPointingDeviceUniqueId (0x0x7f446bb0fe40) 0 + +Class QPointingDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPointingDevice::QPrivateSignal (0x0x7f446e8ef7e0) 0 empty + +Vtable for QPointingDevice +QPointingDevice::_ZTV15QPointingDevice: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPointingDevice) +16 (int (*)(...))QPointingDevice::metaObject +24 (int (*)(...))QPointingDevice::qt_metacast +32 (int (*)(...))QPointingDevice::qt_metacall +40 (int (*)(...))QPointingDevice::~QPointingDevice +48 (int (*)(...))QPointingDevice::~QPointingDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPointingDevice + size=16 align=8 + base size=16 base align=8 +QPointingDevice (0x0x7f4473a53958) 0 + vptr=((& QPointingDevice::_ZTV15QPointingDevice) + 16) + QInputDevice (0x0x7f4473a539c0) 0 + primary-for QPointingDevice (0x0x7f4473a53958) + QObject (0x0x7f446e8ef780) 0 + primary-for QInputDevice (0x0x7f4473a539c0) + +Class QEventPoint + size=8 align=8 + base size=8 base align=8 +QEventPoint (0x0x7f446e8efe40) 0 + +Class QKeySequence + size=8 align=8 + base size=8 base align=8 +QKeySequence (0x0x7f4472fcbc60) 0 + +Vtable for QInputEvent +QInputEvent::_ZTV11QInputEvent: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QInputEvent) +16 (int (*)(...))QInputEvent::~QInputEvent +24 (int (*)(...))QInputEvent::~QInputEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QInputEvent::clone +48 (int (*)(...))QInputEvent::setTimestamp + +Class QInputEvent + size=40 align=8 + base size=40 base align=8 +QInputEvent (0x0x7f4473a663a8) 0 + vptr=((& QInputEvent::_ZTV11QInputEvent) + 16) + QEvent (0x0x7f44728e3c00) 0 + primary-for QInputEvent (0x0x7f4473a663a8) + +Vtable for QPointerEvent +QPointerEvent::_ZTV13QPointerEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPointerEvent) +16 (int (*)(...))QPointerEvent::~QPointerEvent +24 (int (*)(...))QPointerEvent::~QPointerEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QPointerEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QPointerEvent::isBeginEvent +64 (int (*)(...))QPointerEvent::isUpdateEvent +72 (int (*)(...))QPointerEvent::isEndEvent + +Class QPointerEvent + size=64 align=8 + base size=64 base align=8 +QPointerEvent (0x0x7f4473a66410) 0 + vptr=((& QPointerEvent::_ZTV13QPointerEvent) + 16) + QInputEvent (0x0x7f4473a66478) 0 + primary-for QPointerEvent (0x0x7f4473a66410) + QEvent (0x0x7f44724ae120) 0 + primary-for QInputEvent (0x0x7f4473a66478) + +Vtable for QSinglePointEvent +QSinglePointEvent::_ZTV17QSinglePointEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSinglePointEvent) +16 (int (*)(...))QSinglePointEvent::~QSinglePointEvent +24 (int (*)(...))QSinglePointEvent::~QSinglePointEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QSinglePointEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QSinglePointEvent + size=80 align=8 + base size=80 base align=8 +QSinglePointEvent (0x0x7f4473a66c30) 0 + vptr=((& QSinglePointEvent::_ZTV17QSinglePointEvent) + 16) + QPointerEvent (0x0x7f4473a66820) 0 + primary-for QSinglePointEvent (0x0x7f4473a66c30) + QInputEvent (0x0x7f4473a66d00) 0 + primary-for QPointerEvent (0x0x7f4473a66820) + QEvent (0x0x7f4471b36000) 0 + primary-for QInputEvent (0x0x7f4473a66d00) + +Vtable for QEnterEvent +QEnterEvent::_ZTV11QEnterEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QEnterEvent) +16 (int (*)(...))QEnterEvent::~QEnterEvent +24 (int (*)(...))QEnterEvent::~QEnterEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QEnterEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QEnterEvent + size=80 align=8 + base size=80 base align=8 +QEnterEvent (0x0x7f4473a66d68) 0 + vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16) + QSinglePointEvent (0x0x7f4473a66dd0) 0 + primary-for QEnterEvent (0x0x7f4473a66d68) + QPointerEvent (0x0x7f4473a66e38) 0 + primary-for QSinglePointEvent (0x0x7f4473a66dd0) + QInputEvent (0x0x7f4473a66ea0) 0 + primary-for QPointerEvent (0x0x7f4473a66e38) + QEvent (0x0x7f4471b364e0) 0 + primary-for QInputEvent (0x0x7f4473a66ea0) + +Vtable for QMouseEvent +QMouseEvent::_ZTV11QMouseEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMouseEvent) +16 (int (*)(...))QMouseEvent::~QMouseEvent +24 (int (*)(...))QMouseEvent::~QMouseEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QMouseEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QMouseEvent + size=80 align=8 + base size=80 base align=8 +QMouseEvent (0x0x7f4473a66f08) 0 + vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16) + QSinglePointEvent (0x0x7f4473a66f70) 0 + primary-for QMouseEvent (0x0x7f4473a66f08) + QPointerEvent (0x0x7f4473a69000) 0 + primary-for QSinglePointEvent (0x0x7f4473a66f70) + QInputEvent (0x0x7f4473a69068) 0 + primary-for QPointerEvent (0x0x7f4473a69000) + QEvent (0x0x7f4471b36c60) 0 + primary-for QInputEvent (0x0x7f4473a69068) + +Vtable for QHoverEvent +QHoverEvent::_ZTV11QHoverEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHoverEvent) +16 (int (*)(...))QHoverEvent::~QHoverEvent +24 (int (*)(...))QHoverEvent::~QHoverEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QHoverEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QHoverEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QHoverEvent + size=96 align=8 + base size=96 base align=8 +QHoverEvent (0x0x7f4473a690d0) 0 + vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16) + QSinglePointEvent (0x0x7f4473a69138) 0 + primary-for QHoverEvent (0x0x7f4473a690d0) + QPointerEvent (0x0x7f4473a691a0) 0 + primary-for QSinglePointEvent (0x0x7f4473a69138) + QInputEvent (0x0x7f4473a69208) 0 + primary-for QPointerEvent (0x0x7f4473a691a0) + QEvent (0x0x7f44714df240) 0 + primary-for QInputEvent (0x0x7f4473a69208) + +Vtable for QWheelEvent +QWheelEvent::_ZTV11QWheelEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWheelEvent) +16 (int (*)(...))QWheelEvent::~QWheelEvent +24 (int (*)(...))QWheelEvent::~QWheelEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QWheelEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QWheelEvent::isBeginEvent +64 (int (*)(...))QWheelEvent::isUpdateEvent +72 (int (*)(...))QWheelEvent::isEndEvent + +Class QWheelEvent + size=96 align=8 + base size=96 base align=8 +QWheelEvent (0x0x7f4473a69270) 0 + vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16) + QSinglePointEvent (0x0x7f4473a692d8) 0 + primary-for QWheelEvent (0x0x7f4473a69270) + QPointerEvent (0x0x7f4473a693a8) 0 + primary-for QSinglePointEvent (0x0x7f4473a692d8) + QInputEvent (0x0x7f4473a69410) 0 + primary-for QPointerEvent (0x0x7f4473a693a8) + QEvent (0x0x7f44714df660) 0 + primary-for QInputEvent (0x0x7f4473a69410) + +Vtable for QTabletEvent +QTabletEvent::_ZTV12QTabletEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTabletEvent) +16 (int (*)(...))QTabletEvent::~QTabletEvent +24 (int (*)(...))QTabletEvent::~QTabletEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QTabletEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QTabletEvent + size=96 align=8 + base size=96 base align=8 +QTabletEvent (0x0x7f4473a69478) 0 + vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16) + QSinglePointEvent (0x0x7f4473a694e0) 0 + primary-for QTabletEvent (0x0x7f4473a69478) + QPointerEvent (0x0x7f4473a69548) 0 + primary-for QSinglePointEvent (0x0x7f4473a694e0) + QInputEvent (0x0x7f4473a695b0) 0 + primary-for QPointerEvent (0x0x7f4473a69548) + QEvent (0x0x7f44714dfb40) 0 + primary-for QInputEvent (0x0x7f4473a695b0) + +Vtable for QNativeGestureEvent +QNativeGestureEvent::_ZTV19QNativeGestureEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNativeGestureEvent) +16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QNativeGestureEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QSinglePointEvent::isBeginEvent +64 (int (*)(...))QSinglePointEvent::isUpdateEvent +72 (int (*)(...))QSinglePointEvent::isEndEvent + +Class QNativeGestureEvent + size=112 align=8 + base size=112 base align=8 +QNativeGestureEvent (0x0x7f4473a69618) 0 + vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16) + QSinglePointEvent (0x0x7f4473a69680) 0 + primary-for QNativeGestureEvent (0x0x7f4473a69618) + QPointerEvent (0x0x7f4473a696e8) 0 + primary-for QSinglePointEvent (0x0x7f4473a69680) + QInputEvent (0x0x7f4473a69750) 0 + primary-for QPointerEvent (0x0x7f4473a696e8) + QEvent (0x0x7f447153a420) 0 + primary-for QInputEvent (0x0x7f4473a69750) + +Vtable for QKeyEvent +QKeyEvent::_ZTV9QKeyEvent: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QKeyEvent) +16 (int (*)(...))QKeyEvent::~QKeyEvent +24 (int (*)(...))QKeyEvent::~QKeyEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QKeyEvent::clone +48 (int (*)(...))QInputEvent::setTimestamp + +Class QKeyEvent + size=88 align=8 + base size=82 base align=8 +QKeyEvent (0x0x7f4473a697b8) 0 + vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16) + QInputEvent (0x0x7f4473a69820) 0 + primary-for QKeyEvent (0x0x7f4473a697b8) + QEvent (0x0x7f447153a900) 0 + primary-for QInputEvent (0x0x7f4473a69820) + +Vtable for QFocusEvent +QFocusEvent::_ZTV11QFocusEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusEvent) +16 (int (*)(...))QFocusEvent::~QFocusEvent +24 (int (*)(...))QFocusEvent::~QFocusEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QFocusEvent::clone + +Class QFocusEvent + size=24 align=8 + base size=20 base align=8 +QFocusEvent (0x0x7f4473a69888) 0 + vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16) + QEvent (0x0x7f447153af00) 0 + primary-for QFocusEvent (0x0x7f4473a69888) + +Vtable for QPaintEvent +QPaintEvent::_ZTV11QPaintEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPaintEvent) +16 (int (*)(...))QPaintEvent::~QPaintEvent +24 (int (*)(...))QPaintEvent::~QPaintEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QPaintEvent::clone + +Class QPaintEvent + size=48 align=8 + base size=41 base align=8 +QPaintEvent (0x0x7f4473a698f0) 0 + vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16) + QEvent (0x0x7f4470c982a0) 0 + primary-for QPaintEvent (0x0x7f4473a698f0) + +Vtable for QMoveEvent +QMoveEvent::_ZTV10QMoveEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QMoveEvent) +16 (int (*)(...))QMoveEvent::~QMoveEvent +24 (int (*)(...))QMoveEvent::~QMoveEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QMoveEvent::clone + +Class QMoveEvent + size=32 align=8 + base size=32 base align=8 +QMoveEvent (0x0x7f4473a699c0) 0 + vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16) + QEvent (0x0x7f4470c985a0) 0 + primary-for QMoveEvent (0x0x7f4473a699c0) + +Vtable for QExposeEvent +QExposeEvent::_ZTV12QExposeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QExposeEvent) +16 (int (*)(...))QExposeEvent::~QExposeEvent +24 (int (*)(...))QExposeEvent::~QExposeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QExposeEvent::clone + +Class QExposeEvent + size=24 align=8 + base size=24 base align=8 +QExposeEvent (0x0x7f4473a69a28) 0 + vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16) + QEvent (0x0x7f4470c98900) 0 + primary-for QExposeEvent (0x0x7f4473a69a28) + +Vtable for QPlatformSurfaceEvent +QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent) +16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QPlatformSurfaceEvent::clone + +Class QPlatformSurfaceEvent + size=24 align=8 + base size=20 base align=8 +QPlatformSurfaceEvent (0x0x7f4473a69a90) 0 + vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16) + QEvent (0x0x7f4470c98ba0) 0 + primary-for QPlatformSurfaceEvent (0x0x7f4473a69a90) + +Vtable for QResizeEvent +QResizeEvent::_ZTV12QResizeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QResizeEvent) +16 (int (*)(...))QResizeEvent::~QResizeEvent +24 (int (*)(...))QResizeEvent::~QResizeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QResizeEvent::clone + +Class QResizeEvent + size=32 align=8 + base size=32 base align=8 +QResizeEvent (0x0x7f4473a69af8) 0 + vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16) + QEvent (0x0x7f4470c98ea0) 0 + primary-for QResizeEvent (0x0x7f4473a69af8) + +Vtable for QCloseEvent +QCloseEvent::_ZTV11QCloseEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QCloseEvent) +16 (int (*)(...))QCloseEvent::~QCloseEvent +24 (int (*)(...))QCloseEvent::~QCloseEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QCloseEvent + size=16 align=8 + base size=16 base align=8 +QCloseEvent (0x0x7f4473a69b60) 0 + vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16) + QEvent (0x0x7f44701dc240) 0 + primary-for QCloseEvent (0x0x7f4473a69b60) + +Vtable for QIconDragEvent +QIconDragEvent::_ZTV14QIconDragEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QIconDragEvent) +16 (int (*)(...))QIconDragEvent::~QIconDragEvent +24 (int (*)(...))QIconDragEvent::~QIconDragEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QIconDragEvent + size=16 align=8 + base size=16 base align=8 +QIconDragEvent (0x0x7f4473a69bc8) 0 + vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16) + QEvent (0x0x7f44701dc2a0) 0 + primary-for QIconDragEvent (0x0x7f4473a69bc8) + +Vtable for QShowEvent +QShowEvent::_ZTV10QShowEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QShowEvent) +16 (int (*)(...))QShowEvent::~QShowEvent +24 (int (*)(...))QShowEvent::~QShowEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QShowEvent + size=16 align=8 + base size=16 base align=8 +QShowEvent (0x0x7f4473a69c30) 0 + vptr=((& QShowEvent::_ZTV10QShowEvent) + 16) + QEvent (0x0x7f44701dc300) 0 + primary-for QShowEvent (0x0x7f4473a69c30) + +Vtable for QHideEvent +QHideEvent::_ZTV10QHideEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHideEvent) +16 (int (*)(...))QHideEvent::~QHideEvent +24 (int (*)(...))QHideEvent::~QHideEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QHideEvent + size=16 align=8 + base size=16 base align=8 +QHideEvent (0x0x7f4473a69d00) 0 + vptr=((& QHideEvent::_ZTV10QHideEvent) + 16) + QEvent (0x0x7f44701dc360) 0 + primary-for QHideEvent (0x0x7f4473a69d00) + +Vtable for QContextMenuEvent +QContextMenuEvent::_ZTV17QContextMenuEvent: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QContextMenuEvent) +16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QContextMenuEvent::clone +48 (int (*)(...))QInputEvent::setTimestamp + +Class QContextMenuEvent + size=64 align=8 + base size=57 base align=8 +QContextMenuEvent (0x0x7f4473a69d68) 0 + vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16) + QInputEvent (0x0x7f4473a69dd0) 0 + primary-for QContextMenuEvent (0x0x7f4473a69d68) + QEvent (0x0x7f44701dc3c0) 0 + primary-for QInputEvent (0x0x7f4473a69dd0) + +Class QInputMethodEvent::Attribute + size=48 align=8 + base size=48 base align=8 +QInputMethodEvent::Attribute (0x0x7f44701dc960) 0 + +Vtable for QInputMethodEvent +QInputMethodEvent::_ZTV17QInputMethodEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QInputMethodEvent) +16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QInputMethodEvent::clone + +Class QInputMethodEvent + size=96 align=8 + base size=96 base align=8 +QInputMethodEvent (0x0x7f4473a69e38) 0 + vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16) + QEvent (0x0x7f44701dc900) 0 + primary-for QInputMethodEvent (0x0x7f4473a69e38) + +Class QInputMethodQueryEvent::QueryPair + size=40 align=8 + base size=40 base align=8 +QInputMethodQueryEvent::QueryPair (0x0x7f446eea9180) 0 + +Vtable for QInputMethodQueryEvent +QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent) +16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QInputMethodQueryEvent::clone + +Class QInputMethodQueryEvent + size=48 align=8 + base size=48 base align=8 +QInputMethodQueryEvent (0x0x7f4473a76138) 0 + vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16) + QEvent (0x0x7f446eea9120) 0 + primary-for QInputMethodQueryEvent (0x0x7f4473a76138) + +Vtable for QDropEvent +QDropEvent::_ZTV10QDropEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDropEvent) +16 (int (*)(...))QDropEvent::~QDropEvent +24 (int (*)(...))QDropEvent::~QDropEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDropEvent::clone + +Class QDropEvent + size=64 align=8 + base size=64 base align=8 +QDropEvent (0x0x7f4473a7d3a8) 0 + vptr=((& QDropEvent::_ZTV10QDropEvent) + 16) + QEvent (0x0x7f446e15b2a0) 0 + primary-for QDropEvent (0x0x7f4473a7d3a8) + +Vtable for QDragMoveEvent +QDragMoveEvent::_ZTV14QDragMoveEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDragMoveEvent) +16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDragMoveEvent::clone + +Class QDragMoveEvent + size=80 align=8 + base size=80 base align=8 +QDragMoveEvent (0x0x7f4473a7d478) 0 + vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16) + QDropEvent (0x0x7f4473a7d4e0) 0 + primary-for QDragMoveEvent (0x0x7f4473a7d478) + QEvent (0x0x7f446e15b9c0) 0 + primary-for QDropEvent (0x0x7f4473a7d4e0) + +Vtable for QDragEnterEvent +QDragEnterEvent::_ZTV15QDragEnterEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragEnterEvent) +16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QDragMoveEvent::clone + +Class QDragEnterEvent + size=80 align=8 + base size=80 base align=8 +QDragEnterEvent (0x0x7f4473a7d548) 0 + vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16) + QDragMoveEvent (0x0x7f4473a7d5b0) 0 + primary-for QDragEnterEvent (0x0x7f4473a7d548) + QDropEvent (0x0x7f4473a7d618) 0 + primary-for QDragMoveEvent (0x0x7f4473a7d5b0) + QEvent (0x0x7f446e15be40) 0 + primary-for QDropEvent (0x0x7f4473a7d618) + +Vtable for QDragLeaveEvent +QDragLeaveEvent::_ZTV15QDragLeaveEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragLeaveEvent) +16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QEvent::clone + +Class QDragLeaveEvent + size=16 align=8 + base size=16 base align=8 +QDragLeaveEvent (0x0x7f4473a7d680) 0 + vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16) + QEvent (0x0x7f446e15bea0) 0 + primary-for QDragLeaveEvent (0x0x7f4473a7d680) + +Vtable for QHelpEvent +QHelpEvent::_ZTV10QHelpEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHelpEvent) +16 (int (*)(...))QHelpEvent::~QHelpEvent +24 (int (*)(...))QHelpEvent::~QHelpEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QHelpEvent::clone + +Class QHelpEvent + size=32 align=8 + base size=32 base align=8 +QHelpEvent (0x0x7f4473a7d6e8) 0 + vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16) + QEvent (0x0x7f446e15bf00) 0 + primary-for QHelpEvent (0x0x7f4473a7d6e8) + +Vtable for QStatusTipEvent +QStatusTipEvent::_ZTV15QStatusTipEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QStatusTipEvent) +16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QStatusTipEvent::clone + +Class QStatusTipEvent + size=40 align=8 + base size=40 base align=8 +QStatusTipEvent (0x0x7f4473a7d750) 0 + vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16) + QEvent (0x0x7f446e085420) 0 + primary-for QStatusTipEvent (0x0x7f4473a7d750) + +Vtable for QWhatsThisClickedEvent +QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent) +16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QWhatsThisClickedEvent::clone + +Class QWhatsThisClickedEvent + size=40 align=8 + base size=40 base align=8 +QWhatsThisClickedEvent (0x0x7f4473a7d820) 0 + vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16) + QEvent (0x0x7f446e0856c0) 0 + primary-for QWhatsThisClickedEvent (0x0x7f4473a7d820) + +Vtable for QActionEvent +QActionEvent::_ZTV12QActionEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionEvent) +16 (int (*)(...))QActionEvent::~QActionEvent +24 (int (*)(...))QActionEvent::~QActionEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QActionEvent::clone + +Class QActionEvent + size=32 align=8 + base size=32 base align=8 +QActionEvent (0x0x7f4473a7d888) 0 + vptr=((& QActionEvent::_ZTV12QActionEvent) + 16) + QEvent (0x0x7f446e085960) 0 + primary-for QActionEvent (0x0x7f4473a7d888) + +Vtable for QFileOpenEvent +QFileOpenEvent::_ZTV14QFileOpenEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QFileOpenEvent) +16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QFileOpenEvent::clone + +Class QFileOpenEvent + size=48 align=8 + base size=48 base align=8 +QFileOpenEvent (0x0x7f4473a7d8f0) 0 + vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16) + QEvent (0x0x7f446e085cc0) 0 + primary-for QFileOpenEvent (0x0x7f4473a7d8f0) + +Vtable for QToolBarChangeEvent +QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QToolBarChangeEvent) +16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QToolBarChangeEvent::clone + +Class QToolBarChangeEvent + size=24 align=8 + base size=17 base align=8 +QToolBarChangeEvent (0x0x7f4473a7d958) 0 + vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16) + QEvent (0x0x7f446dd50000) 0 + primary-for QToolBarChangeEvent (0x0x7f4473a7d958) + +Vtable for QShortcutEvent +QShortcutEvent::_ZTV14QShortcutEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QShortcutEvent) +16 (int (*)(...))QShortcutEvent::~QShortcutEvent +24 (int (*)(...))QShortcutEvent::~QShortcutEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QShortcutEvent::clone + +Class QShortcutEvent + size=32 align=8 + base size=29 base align=8 +QShortcutEvent (0x0x7f4473a7d9c0) 0 + vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16) + QEvent (0x0x7f446dd50300) 0 + primary-for QShortcutEvent (0x0x7f4473a7d9c0) + +Vtable for QWindowStateChangeEvent +QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent) +16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QWindowStateChangeEvent::clone + +Class QWindowStateChangeEvent + size=24 align=8 + base size=21 base align=8 +QWindowStateChangeEvent (0x0x7f4473a7da28) 0 + vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16) + QEvent (0x0x7f446dd50660) 0 + primary-for QWindowStateChangeEvent (0x0x7f4473a7da28) + +Vtable for QTouchEvent +QTouchEvent::_ZTV11QTouchEvent: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTouchEvent) +16 (int (*)(...))QTouchEvent::~QTouchEvent +24 (int (*)(...))QTouchEvent::~QTouchEvent +32 (int (*)(...))QPointerEvent::setAccepted +40 (int (*)(...))QTouchEvent::clone +48 (int (*)(...))QPointerEvent::setTimestamp +56 (int (*)(...))QTouchEvent::isBeginEvent +64 (int (*)(...))QTouchEvent::isUpdateEvent +72 (int (*)(...))QTouchEvent::isEndEvent + +Class QTouchEvent + size=80 align=8 + base size=79 base align=8 +QTouchEvent (0x0x7f4473a7da90) 0 + vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16) + QPointerEvent (0x0x7f4473a7daf8) 0 + primary-for QTouchEvent (0x0x7f4473a7da90) + QInputEvent (0x0x7f4473a7db60) 0 + primary-for QPointerEvent (0x0x7f4473a7daf8) + QEvent (0x0x7f446dd50960) 0 + primary-for QInputEvent (0x0x7f4473a7db60) + +Vtable for QScrollPrepareEvent +QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollPrepareEvent) +16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QScrollPrepareEvent::clone + +Class QScrollPrepareEvent + size=96 align=8 + base size=96 base align=8 +QScrollPrepareEvent (0x0x7f4473a7dc30) 0 + vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16) + QEvent (0x0x7f446dd50cc0) 0 + primary-for QScrollPrepareEvent (0x0x7f4473a7dc30) + +Vtable for QScrollEvent +QScrollEvent::_ZTV12QScrollEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QScrollEvent) +16 (int (*)(...))QScrollEvent::~QScrollEvent +24 (int (*)(...))QScrollEvent::~QScrollEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QScrollEvent::clone + +Class QScrollEvent + size=56 align=8 + base size=52 base align=8 +QScrollEvent (0x0x7f4473a7dc98) 0 + vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16) + QEvent (0x0x7f446dc1f120) 0 + primary-for QScrollEvent (0x0x7f4473a7dc98) + +Vtable for QScreenOrientationChangeEvent +QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent) +16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QScreenOrientationChangeEvent::clone + +Class QScreenOrientationChangeEvent + size=32 align=8 + base size=28 base align=8 +QScreenOrientationChangeEvent (0x0x7f4473a7dd00) 0 + vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16) + QEvent (0x0x7f446dc1f4e0) 0 + primary-for QScreenOrientationChangeEvent (0x0x7f4473a7dd00) + +Vtable for QApplicationStateChangeEvent +QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent) +16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +32 (int (*)(...))QEvent::setAccepted +40 (int (*)(...))QApplicationStateChangeEvent::clone + +Class QApplicationStateChangeEvent + size=24 align=8 + base size=20 base align=8 +QApplicationStateChangeEvent (0x0x7f4473a7dd68) 0 + vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16) + QEvent (0x0x7f446dc1f840) 0 + primary-for QApplicationStateChangeEvent (0x0x7f4473a7dd68) + +Class QFont + size=16 align=8 + base size=12 base align=8 +QFont (0x0x7f446dc1fb40) 0 + +Class QFontDatabase + size=1 align=1 + base size=0 base align=1 +QFontDatabase (0x0x7f446c306ba0) 0 empty + +Class QRawFont + size=8 align=8 + base size=8 base align=8 +QRawFont (0x0x7f446c306d80) 0 + +Class QGlyphRun + size=8 align=8 + base size=8 base align=8 +QGlyphRun (0x0x7f446b25ac60) 0 + +Class QBrush + size=8 align=8 + base size=8 base align=8 +QBrush (0x0x7f4469560360) 0 + +Class QBrushData + size=104 align=8 + base size=104 base align=8 +QBrushData (0x0x7f446ef02ea0) 0 + +Class QGradient::QGradientData + size=48 align=8 + base size=48 base align=8 +QGradient::QGradientData (0x0x7f4475b21120) 0 + +Class QGradient + size=88 align=8 + base size=88 base align=8 +QGradient (0x0x7f4475b210c0) 0 + +Class QLinearGradient + size=88 align=8 + base size=88 base align=8 +QLinearGradient (0x0x7f447377d208) 0 + QGradient (0x0x7f4475b21a80) 0 + +Class QRadialGradient + size=88 align=8 + base size=88 base align=8 +QRadialGradient (0x0x7f447377d270) 0 + QGradient (0x0x7f44712b90c0) 0 + +Class QConicalGradient + size=88 align=8 + base size=88 base align=8 +QConicalGradient (0x0x7f447377d2d8) 0 + QGradient (0x0x7f44712b91e0) 0 + +Class QPen + size=8 align=8 + base size=8 base align=8 +QPen (0x0x7f44712b92a0) 0 + +Class QTextOption::Tab + size=16 align=8 + base size=14 base align=8 +QTextOption::Tab (0x0x7f446e8a7360) 0 + +Class QTextOption + size=24 align=8 + base size=24 base align=8 +QTextOption (0x0x7f446e8a7300) 0 + +Class QTextLength + size=16 align=8 + base size=16 base align=8 +QTextLength (0x0x7f446db610c0) 0 + +Class QTextFormat + size=16 align=8 + base size=12 base align=8 +QTextFormat (0x0x7f446d83fd80) 0 + +Class QTextCharFormat + size=16 align=8 + base size=12 base align=8 +QTextCharFormat (0x0x7f4473797b60) 0 + QTextFormat (0x0x7f4469845420) 0 + +Class QTextBlockFormat + size=16 align=8 + base size=12 base align=8 +QTextBlockFormat (0x0x7f447379eaf8) 0 + QTextFormat (0x0x7f446e33c720) 0 + +Class QTextListFormat + size=16 align=8 + base size=12 base align=8 +QTextListFormat (0x0x7f44737a1a28) 0 + QTextFormat (0x0x7f446b675c60) 0 + +Class QTextImageFormat + size=16 align=8 + base size=12 base align=8 +QTextImageFormat (0x0x7f44737a7820) 0 + QTextCharFormat (0x0x7f44737a78f0) 0 + QTextFormat (0x0x7f44694beb40) 0 + +Class QTextFrameFormat + size=16 align=8 + base size=12 base align=8 +QTextFrameFormat (0x0x7f44737ad820) 0 + QTextFormat (0x0x7f44695359c0) 0 + +Class QTextTableFormat + size=16 align=8 + base size=12 base align=8 +QTextTableFormat (0x0x7f44737b4750) 0 + QTextFrameFormat (0x0x7f44737b47b8) 0 + QTextFormat (0x0x7f446a6a0de0) 0 + +Class QTextTableCellFormat + size=16 align=8 + base size=12 base align=8 +QTextTableCellFormat (0x0x7f44737b8750) 0 + QTextCharFormat (0x0x7f44737b8820) 0 + QTextFormat (0x0x7f446a94a0c0) 0 + +Class QTextCursor + size=8 align=8 + base size=8 base align=8 +QTextCursor (0x0x7f4472c3e600) 0 + +Class QTextInlineObject + size=16 align=8 + base size=16 base align=8 +QTextInlineObject (0x0x7f44698b8c60) 0 + +Class QTextLayout::FormatRange + size=24 align=8 + base size=24 base align=8 +QTextLayout::FormatRange (0x0x7f44694e70c0) 0 + +Class QTextLayout + size=8 align=8 + base size=8 base align=8 +QTextLayout (0x0x7f44694e7060) 0 + +Class QTextLine + size=16 align=8 + base size=16 base align=8 +QTextLine (0x0x7f44692e8180) 0 + +Vtable for QAbstractUndoItem +QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractUndoItem) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAbstractUndoItem + size=8 align=8 + base size=8 base align=8 +QAbstractUndoItem (0x0x7f44692e8600) 0 nearly-empty + vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16) + +Class QTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextDocument::QPrivateSignal (0x0x7f44692e88a0) 0 empty + +Vtable for QTextDocument +QTextDocument::_ZTV13QTextDocument: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QTextDocument) +16 (int (*)(...))QTextDocument::metaObject +24 (int (*)(...))QTextDocument::qt_metacast +32 (int (*)(...))QTextDocument::qt_metacall +40 (int (*)(...))QTextDocument::~QTextDocument +48 (int (*)(...))QTextDocument::~QTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextDocument::clear +120 (int (*)(...))QTextDocument::createObject +128 (int (*)(...))QTextDocument::loadResource + +Class QTextDocument + size=16 align=8 + base size=16 base align=8 +QTextDocument (0x0x7f446f335d00) 0 + vptr=((& QTextDocument::_ZTV13QTextDocument) + 16) + QObject (0x0x7f44692e8840) 0 + primary-for QTextDocument (0x0x7f446f335d00) + +Class QPalette + size=16 align=8 + base size=12 base align=8 +QPalette (0x0x7f446931c0c0) 0 + +Class QAbstractTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTextDocumentLayout::QPrivateSignal (0x0x7f446935d420) 0 empty + +Class QAbstractTextDocumentLayout::Selection + size=24 align=8 + base size=24 base align=8 +QAbstractTextDocumentLayout::Selection (0x0x7f446935d480) 0 + +Class QAbstractTextDocumentLayout::PaintContext + size=80 align=8 + base size=80 base align=8 +QAbstractTextDocumentLayout::PaintContext (0x0x7f446935d4e0) 0 + +Vtable for QAbstractTextDocumentLayout +QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout) +16 (int (*)(...))QAbstractTextDocumentLayout::metaObject +24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast +32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QAbstractTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QAbstractTextDocumentLayout (0x0x7f446d56d1a0) 0 + vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16) + QObject (0x0x7f446935d3c0) 0 + primary-for QAbstractTextDocumentLayout (0x0x7f446d56d1a0) + +Vtable for QTextObjectInterface +QTextObjectInterface::_ZTV20QTextObjectInterface: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextObjectInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QTextObjectInterface + size=8 align=8 + base size=8 base align=8 +QTextObjectInterface (0x0x7f44693ada80) 0 nearly-empty + vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16) + +Class QAccessible::State + size=8 align=8 + base size=5 base align=8 +QAccessible::State (0x0x7f44693adcc0) 0 + +Vtable for QAccessible::ActivationObserver +QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QAccessible::ActivationObserver + size=8 align=8 + base size=8 base align=8 +QAccessible::ActivationObserver (0x0x7f44693add20) 0 nearly-empty + vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16) + +Class QAccessible + size=1 align=1 + base size=0 base align=1 +QAccessible (0x0x7f44693adc60) 0 empty + +Vtable for QAccessibleInterface +QAccessibleInterface::_ZTV20QAccessibleInterface: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAccessibleInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleInterface (0x0x7f44693ca5a0) 0 nearly-empty + vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16) + +Vtable for QAccessibleTextInterface +QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAccessibleTextInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset +104 (int (*)(...))QAccessibleTextInterface::textAfterOffset +112 (int (*)(...))QAccessibleTextInterface::textAtOffset +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTextInterface (0x0x7f44693ca900) 0 nearly-empty + vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16) + +Vtable for QAccessibleEditableTextInterface +QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleEditableTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleEditableTextInterface (0x0x7f44693ca960) 0 nearly-empty + vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16) + +Vtable for QAccessibleValueInterface +QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleValueInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleValueInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleValueInterface (0x0x7f44693ca9c0) 0 nearly-empty + vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16) + +Vtable for QAccessibleTableCellInterface +QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableCellInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableCellInterface (0x0x7f44693caa20) 0 nearly-empty + vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16) + +Vtable for QAccessibleTableInterface +QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleTableInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableInterface (0x0x7f44693caa80) 0 nearly-empty + vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16) + +Vtable for QAccessibleActionInterface +QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleActionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QAccessibleActionInterface::localizedActionName +48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleActionInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleActionInterface (0x0x7f44693caae0) 0 nearly-empty + vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16) + +Vtable for QAccessibleImageInterface +QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleImageInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleImageInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleImageInterface (0x0x7f44693caba0) 0 nearly-empty + vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16) + +Vtable for QAccessibleEvent +QAccessibleEvent::_ZTV16QAccessibleEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAccessibleEvent) +16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleEvent + size=32 align=8 + base size=28 base align=8 +QAccessibleEvent (0x0x7f44693cac00) 0 + vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16) + +Vtable for QAccessibleStateChangeEvent +QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent) +16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleStateChangeEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleStateChangeEvent (0x0x7f446c325888) 0 + vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16) + QAccessibleEvent (0x0x7f44693f2180) 0 + primary-for QAccessibleStateChangeEvent (0x0x7f446c325888) + +Vtable for QAccessibleTextCursorEvent +QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent) +16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextCursorEvent + size=32 align=8 + base size=32 base align=8 +QAccessibleTextCursorEvent (0x0x7f446c3258f0) 0 + vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16) + QAccessibleEvent (0x0x7f44693f2540) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f446c3258f0) + +Vtable for QAccessibleTextSelectionEvent +QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent) +16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextSelectionEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleTextSelectionEvent (0x0x7f446bffc0d0) 0 + vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f446bffc138) 0 + primary-for QAccessibleTextSelectionEvent (0x0x7f446bffc0d0) + QAccessibleEvent (0x0x7f44693f2960) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f446bffc138) + +Vtable for QAccessibleTextInsertEvent +QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent) +16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextInsertEvent + size=64 align=8 + base size=64 base align=8 +QAccessibleTextInsertEvent (0x0x7f446bffc5b0) 0 + vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f446bffc618) 0 + primary-for QAccessibleTextInsertEvent (0x0x7f446bffc5b0) + QAccessibleEvent (0x0x7f44693f2de0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f446bffc618) + +Vtable for QAccessibleTextRemoveEvent +QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent) +16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextRemoveEvent + size=64 align=8 + base size=64 base align=8 +QAccessibleTextRemoveEvent (0x0x7f446bffcf70) 0 + vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f446c011000) 0 + primary-for QAccessibleTextRemoveEvent (0x0x7f446bffcf70) + QAccessibleEvent (0x0x7f4469405240) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f446c011000) + +Vtable for QAccessibleTextUpdateEvent +QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent) +16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextUpdateEvent + size=88 align=8 + base size=88 base align=8 +QAccessibleTextUpdateEvent (0x0x7f446c011618) 0 + vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16) + QAccessibleTextCursorEvent (0x0x7f446c011680) 0 + primary-for QAccessibleTextUpdateEvent (0x0x7f446c011618) + QAccessibleEvent (0x0x7f4469405660) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f446c011680) + +Vtable for QAccessibleValueChangeEvent +QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent) +16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleValueChangeEvent + size=64 align=8 + base size=64 base align=8 +QAccessibleValueChangeEvent (0x0x7f446c011e38) 0 + vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16) + QAccessibleEvent (0x0x7f4469405ae0) 0 + primary-for QAccessibleValueChangeEvent (0x0x7f446c011e38) + +Vtable for QAccessibleTableModelChangeEvent +QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent) +16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTableModelChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTableModelChangeEvent (0x0x7f446c011ea0) 0 + vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16) + QAccessibleEvent (0x0x7f4469405f00) 0 + primary-for QAccessibleTableModelChangeEvent (0x0x7f446c011ea0) + +Vtable for QAccessibleBridge +QAccessibleBridge::_ZTV17QAccessibleBridge: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleBridge) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridge + size=8 align=8 + base size=8 base align=8 +QAccessibleBridge (0x0x7f44694187e0) 0 nearly-empty + vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16) + +Class QAccessibleBridgePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessibleBridgePlugin::QPrivateSignal (0x0x7f4469418a80) 0 empty + +Vtable for QAccessibleBridgePlugin +QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin) +16 (int (*)(...))QAccessibleBridgePlugin::metaObject +24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast +32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridgePlugin + size=16 align=8 + base size=16 base align=8 +QAccessibleBridgePlugin (0x0x7f446c05d340) 0 + vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16) + QObject (0x0x7f4469418a20) 0 + primary-for QAccessibleBridgePlugin (0x0x7f446c05d340) + +Vtable for QAccessibleObject +QAccessibleObject::_ZTV17QAccessibleObject: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleObject) +16 0 +24 0 +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleObject + size=16 align=8 + base size=16 base align=8 +QAccessibleObject (0x0x7f446c05d3a8) 0 + vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16) + QAccessibleInterface (0x0x7f4469418b40) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f446c05d3a8) + +Vtable for QAccessibleApplication +QAccessibleApplication::_ZTV22QAccessibleApplication: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QAccessibleApplication) +16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleApplication::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleApplication::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleApplication::parent +88 (int (*)(...))QAccessibleApplication::child +96 (int (*)(...))QAccessibleApplication::childCount +104 (int (*)(...))QAccessibleApplication::indexOfChild +112 (int (*)(...))QAccessibleApplication::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))QAccessibleApplication::role +144 (int (*)(...))QAccessibleApplication::state +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleApplication + size=16 align=8 + base size=16 base align=8 +QAccessibleApplication (0x0x7f446c05dd00) 0 + vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16) + QAccessibleObject (0x0x7f446c05dd68) 0 + primary-for QAccessibleApplication (0x0x7f446c05dd00) + QAccessibleInterface (0x0x7f4469418ba0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f446c05dd68) + +Class QAccessiblePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessiblePlugin::QPrivateSignal (0x0x7f4469418c60) 0 empty + +Vtable for QAccessiblePlugin +QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessiblePlugin) +16 (int (*)(...))QAccessiblePlugin::metaObject +24 (int (*)(...))QAccessiblePlugin::qt_metacast +32 (int (*)(...))QAccessiblePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessiblePlugin + size=16 align=8 + base size=16 base align=8 +QAccessiblePlugin (0x0x7f446c0a4618) 0 + vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16) + QObject (0x0x7f4469418c00) 0 + primary-for QAccessiblePlugin (0x0x7f446c0a4618) + +Class QAction::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAction::QPrivateSignal (0x0x7f4469418d80) 0 empty + +Vtable for QAction +QAction::_ZTV7QAction: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QAction) +16 (int (*)(...))QAction::metaObject +24 (int (*)(...))QAction::qt_metacast +32 (int (*)(...))QAction::qt_metacall +40 (int (*)(...))QAction::~QAction +48 (int (*)(...))QAction::~QAction +56 (int (*)(...))QAction::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QAction + size=16 align=8 + base size=16 base align=8 +QAction (0x0x7f446c0a4680) 0 + vptr=((& QAction::_ZTV7QAction) + 16) + QObject (0x0x7f4469418d20) 0 + primary-for QAction (0x0x7f446c0a4680) + +Class QActionGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QActionGroup::QPrivateSignal (0x0x7f446943c6c0) 0 empty + +Vtable for QActionGroup +QActionGroup::_ZTV12QActionGroup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionGroup) +16 (int (*)(...))QActionGroup::metaObject +24 (int (*)(...))QActionGroup::qt_metacast +32 (int (*)(...))QActionGroup::qt_metacall +40 (int (*)(...))QActionGroup::~QActionGroup +48 (int (*)(...))QActionGroup::~QActionGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QActionGroup + size=16 align=8 + base size=16 base align=8 +QActionGroup (0x0x7f446c0c10d0) 0 + vptr=((& QActionGroup::_ZTV12QActionGroup) + 16) + QObject (0x0x7f446943c660) 0 + primary-for QActionGroup (0x0x7f446c0c10d0) + +Class QSurfaceFormat + size=8 align=8 + base size=8 base align=8 +QSurfaceFormat (0x0x7f446943c960) 0 + +Vtable for QSurface +QSurface::_ZTV8QSurface: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSurface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QSurface + size=24 align=8 + base size=24 base align=8 +QSurface (0x0x7f446945f1e0) 0 + vptr=((& QSurface::_ZTV8QSurface) + 16) + +Vtable for QBitmap +QBitmap::_ZTV7QBitmap: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBitmap) +16 (int (*)(...))QBitmap::~QBitmap +24 (int (*)(...))QBitmap::~QBitmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QBitmap + size=24 align=8 + base size=24 base align=8 +QBitmap (0x0x7f446c10e0d0) 0 + vptr=((& QBitmap::_ZTV7QBitmap) + 16) + QPixmap (0x0x7f446c10e138) 0 + primary-for QBitmap (0x0x7f446c10e0d0) + QPaintDevice (0x0x7f446945f4e0) 0 + primary-for QPixmap (0x0x7f446c10e138) + +Class QCursor + size=8 align=8 + base size=8 base align=8 +QCursor (0x0x7f4469476de0) 0 + +Class QWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWindow::QPrivateSignal (0x0x7f44694a5000) 0 empty + +Vtable for QWindow +QWindow::_ZTV7QWindow: 47 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWindow) +16 (int (*)(...))QWindow::metaObject +24 (int (*)(...))QWindow::qt_metacast +32 (int (*)(...))QWindow::qt_metacall +40 (int (*)(...))QWindow::~QWindow +48 (int (*)(...))QWindow::~QWindow +56 (int (*)(...))QWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QWindow::focusInEvent +192 (int (*)(...))QWindow::focusOutEvent +200 (int (*)(...))QWindow::showEvent +208 (int (*)(...))QWindow::hideEvent +216 (int (*)(...))QWindow::closeEvent +224 (int (*)(...))QWindow::keyPressEvent +232 (int (*)(...))QWindow::keyReleaseEvent +240 (int (*)(...))QWindow::mousePressEvent +248 (int (*)(...))QWindow::mouseReleaseEvent +256 (int (*)(...))QWindow::mouseDoubleClickEvent +264 (int (*)(...))QWindow::mouseMoveEvent +272 (int (*)(...))QWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))-16 +320 (int (*)(...))(& _ZTI7QWindow) +328 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev +336 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QWindow + size=40 align=8 + base size=40 base align=8 +QWindow (0x0x7f446948c4d0) 0 + vptr=((& QWindow::_ZTV7QWindow) + 16) + QObject (0x0x7f446949af00) 0 + primary-for QWindow (0x0x7f446948c4d0) + QSurface (0x0x7f446949af60) 16 + vptr=((& QWindow::_ZTV7QWindow) + 328) + +Class QBackingStore + size=8 align=8 + base size=8 base align=8 +QBackingStore (0x0x7f44694a5840) 0 + +Class QClipboard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QClipboard::QPrivateSignal (0x0x7f44694a5960) 0 empty + +Vtable for QClipboard +QClipboard::_ZTV10QClipboard: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QClipboard) +16 (int (*)(...))QClipboard::metaObject +24 (int (*)(...))QClipboard::qt_metacast +32 (int (*)(...))QClipboard::qt_metacall +40 (int (*)(...))QClipboard::~QClipboard +48 (int (*)(...))QClipboard::~QClipboard +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QClipboard + size=16 align=8 + base size=16 base align=8 +QClipboard (0x0x7f446988caf8) 0 + vptr=((& QClipboard::_ZTV10QClipboard) + 16) + QObject (0x0x7f44694a5900) 0 + primary-for QClipboard (0x0x7f446988caf8) + +Class QColorTransform + size=8 align=8 + base size=8 base align=8 +QColorTransform (0x0x7f44694a5a80) 0 + +Class QColorSpace + size=8 align=8 + base size=8 base align=8 +QColorSpace (0x0x7f44690f1a20) 0 + +Class QDesktopServices + size=1 align=1 + base size=0 base align=1 +QDesktopServices (0x0x7f44691246c0) 0 empty + +Class QDrag::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDrag::QPrivateSignal (0x0x7f4469124780) 0 empty + +Vtable for QDrag +QDrag::_ZTV5QDrag: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDrag) +16 (int (*)(...))QDrag::metaObject +24 (int (*)(...))QDrag::qt_metacast +32 (int (*)(...))QDrag::qt_metacall +40 (int (*)(...))QDrag::~QDrag +48 (int (*)(...))QDrag::~QDrag +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDrag + size=16 align=8 + base size=16 base align=8 +QDrag (0x0x7f44691254e0) 0 + vptr=((& QDrag::_ZTV5QDrag) + 16) + QObject (0x0x7f4469124720) 0 + primary-for QDrag (0x0x7f44691254e0) + +Class QFileSystemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemModel::QPrivateSignal (0x0x7f4469124960) 0 empty + +Vtable for QFileSystemModel +QFileSystemModel::_ZTV16QFileSystemModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QFileSystemModel) +16 (int (*)(...))QFileSystemModel::metaObject +24 (int (*)(...))QFileSystemModel::qt_metacast +32 (int (*)(...))QFileSystemModel::qt_metacall +40 (int (*)(...))QFileSystemModel::~QFileSystemModel +48 (int (*)(...))QFileSystemModel::~QFileSystemModel +56 (int (*)(...))QFileSystemModel::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QFileSystemModel::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileSystemModel::index +120 (int (*)(...))QFileSystemModel::parent +128 (int (*)(...))QFileSystemModel::sibling +136 (int (*)(...))QFileSystemModel::rowCount +144 (int (*)(...))QFileSystemModel::columnCount +152 (int (*)(...))QFileSystemModel::hasChildren +160 (int (*)(...))QFileSystemModel::data +168 (int (*)(...))QFileSystemModel::setData +176 (int (*)(...))QFileSystemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::clearItemData +216 (int (*)(...))QFileSystemModel::mimeTypes +224 (int (*)(...))QFileSystemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QFileSystemModel::dropMimeData +248 (int (*)(...))QFileSystemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QAbstractItemModel::insertRows +272 (int (*)(...))QAbstractItemModel::insertColumns +280 (int (*)(...))QAbstractItemModel::removeRows +288 (int (*)(...))QAbstractItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QFileSystemModel::fetchMore +320 (int (*)(...))QFileSystemModel::canFetchMore +328 (int (*)(...))QFileSystemModel::flags +336 (int (*)(...))QFileSystemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QFileSystemModel::roleNames +376 (int (*)(...))QAbstractItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QFileSystemModel + size=16 align=8 + base size=16 base align=8 +QFileSystemModel (0x0x7f4469125548) 0 + vptr=((& QFileSystemModel::_ZTV16QFileSystemModel) + 16) + QAbstractItemModel (0x0x7f44691255b0) 0 + primary-for QFileSystemModel (0x0x7f4469125548) + QObject (0x0x7f4469124900) 0 + primary-for QAbstractItemModel (0x0x7f44691255b0) + +Class QFontInfo + size=8 align=8 + base size=8 base align=8 +QFontInfo (0x0x7f4469124f60) 0 + +Class QFontMetrics + size=8 align=8 + base size=8 base align=8 +QFontMetrics (0x0x7f446915a8a0) 0 + +Class QFontMetricsF + size=8 align=8 + base size=8 base align=8 +QFontMetricsF (0x0x7f4469173300) 0 + +Class QGenericPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGenericPlugin::QPrivateSignal (0x0x7f44691bd120) 0 empty + +Vtable for QGenericPlugin +QGenericPlugin::_ZTV14QGenericPlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGenericPlugin) +16 (int (*)(...))QGenericPlugin::metaObject +24 (int (*)(...))QGenericPlugin::qt_metacast +32 (int (*)(...))QGenericPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGenericPlugin + size=16 align=8 + base size=16 base align=8 +QGenericPlugin (0x0x7f446918cdd0) 0 + vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16) + QObject (0x0x7f44691bd0c0) 0 + primary-for QGenericPlugin (0x0x7f446918cdd0) + +Class QGenericPluginFactory + size=1 align=1 + base size=0 base align=1 +QGenericPluginFactory (0x0x7f44691bd1e0) 0 empty + +Class QInputMethod::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputMethod::QPrivateSignal (0x0x7f44691bd2a0) 0 empty + +Vtable for QInputMethod +QInputMethod::_ZTV12QInputMethod: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputMethod) +16 (int (*)(...))QInputMethod::metaObject +24 (int (*)(...))QInputMethod::qt_metacast +32 (int (*)(...))QInputMethod::qt_metacall +40 (int (*)(...))QInputMethod::~QInputMethod +48 (int (*)(...))QInputMethod::~QInputMethod +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputMethod + size=16 align=8 + base size=16 base align=8 +QInputMethod (0x0x7f446918ce38) 0 + vptr=((& QInputMethod::_ZTV12QInputMethod) + 16) + QObject (0x0x7f44691bd240) 0 + primary-for QInputMethod (0x0x7f446918ce38) + +Class QGuiApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGuiApplication::QPrivateSignal (0x0x7f44691bd540) 0 empty + +Vtable for QGuiApplication +QGuiApplication::_ZTV15QGuiApplication: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGuiApplication) +16 (int (*)(...))QGuiApplication::metaObject +24 (int (*)(...))QGuiApplication::qt_metacast +32 (int (*)(...))QGuiApplication::qt_metacall +40 (int (*)(...))QGuiApplication::~QGuiApplication +48 (int (*)(...))QGuiApplication::~QGuiApplication +56 (int (*)(...))QGuiApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGuiApplication::notify +120 (int (*)(...))QGuiApplication::compressEvent + +Class QGuiApplication + size=16 align=8 + base size=16 base align=8 +QGuiApplication (0x0x7f446918cea0) 0 + vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16) + QCoreApplication (0x0x7f446918cf08) 0 + primary-for QGuiApplication (0x0x7f446918cea0) + QObject (0x0x7f44691bd4e0) 0 + primary-for QCoreApplication (0x0x7f446918cf08) + +Class QIconEngine::ScaledPixmapArgument + size=48 align=8 + base size=48 base align=8 +QIconEngine::ScaledPixmapArgument (0x0x7f44691bd7e0) 0 + +Vtable for QIconEngine +QIconEngine::_ZTV11QIconEngine: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QIconEngine) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QIconEngine::actualSize +48 (int (*)(...))QIconEngine::pixmap +56 (int (*)(...))QIconEngine::addPixmap +64 (int (*)(...))QIconEngine::addFile +72 (int (*)(...))QIconEngine::key +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QIconEngine::read +96 (int (*)(...))QIconEngine::write +104 (int (*)(...))QIconEngine::availableSizes +112 (int (*)(...))QIconEngine::iconName +120 (int (*)(...))QIconEngine::isNull +128 (int (*)(...))QIconEngine::scaledPixmap +136 (int (*)(...))QIconEngine::virtual_hook + +Class QIconEngine + size=8 align=8 + base size=8 base align=8 +QIconEngine (0x0x7f44691bd780) 0 nearly-empty + vptr=((& QIconEngine::_ZTV11QIconEngine) + 16) + +Class QIconEnginePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIconEnginePlugin::QPrivateSignal (0x0x7f44691bd8a0) 0 empty + +Vtable for QIconEnginePlugin +QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QIconEnginePlugin) +16 (int (*)(...))QIconEnginePlugin::metaObject +24 (int (*)(...))QIconEnginePlugin::qt_metacast +32 (int (*)(...))QIconEnginePlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QIconEnginePlugin + size=16 align=8 + base size=16 base align=8 +QIconEnginePlugin (0x0x7f446918cf70) 0 + vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16) + QObject (0x0x7f44691bd840) 0 + primary-for QIconEnginePlugin (0x0x7f446918cf70) + +Vtable for QImageIOHandler +QImageIOHandler::_ZTV15QImageIOHandler: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QImageIOHandler) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QImageIOHandler::write +56 (int (*)(...))QImageIOHandler::option +64 (int (*)(...))QImageIOHandler::setOption +72 (int (*)(...))QImageIOHandler::supportsOption +80 (int (*)(...))QImageIOHandler::jumpToNextImage +88 (int (*)(...))QImageIOHandler::jumpToImage +96 (int (*)(...))QImageIOHandler::loopCount +104 (int (*)(...))QImageIOHandler::imageCount +112 (int (*)(...))QImageIOHandler::nextImageDelay +120 (int (*)(...))QImageIOHandler::currentImageNumber +128 (int (*)(...))QImageIOHandler::currentImageRect + +Class QImageIOHandler + size=16 align=8 + base size=16 base align=8 +QImageIOHandler (0x0x7f44691bd960) 0 + vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16) + +Class QImageIOPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QImageIOPlugin::QPrivateSignal (0x0x7f44691bdba0) 0 empty + +Vtable for QImageIOPlugin +QImageIOPlugin::_ZTV14QImageIOPlugin: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QImageIOPlugin) +16 (int (*)(...))QImageIOPlugin::metaObject +24 (int (*)(...))QImageIOPlugin::qt_metacast +32 (int (*)(...))QImageIOPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QImageIOPlugin + size=16 align=8 + base size=16 base align=8 +QImageIOPlugin (0x0x7f446918c888) 0 + vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16) + QObject (0x0x7f44691bdb40) 0 + primary-for QImageIOPlugin (0x0x7f446918c888) + +Class QImageReader + size=8 align=8 + base size=8 base align=8 +QImageReader (0x0x7f44691bdf60) 0 + +Class QImageWriter + size=8 align=8 + base size=8 base align=8 +QImageWriter (0x0x7f4469205060) 0 + +Class QQuaternion + size=16 align=4 + base size=16 base align=4 +QQuaternion (0x0x7f4469205120) 0 + +Class QMatrix4x4 + size=68 align=4 + base size=68 base align=4 +QMatrix4x4 (0x0x7f446922be40) 0 + +Class QMovie::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMovie::QPrivateSignal (0x0x7f446927f300) 0 empty + +Vtable for QMovie +QMovie::_ZTV6QMovie: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QMovie) +16 (int (*)(...))QMovie::metaObject +24 (int (*)(...))QMovie::qt_metacast +32 (int (*)(...))QMovie::qt_metacall +40 (int (*)(...))QMovie::~QMovie +48 (int (*)(...))QMovie::~QMovie +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QMovie + size=16 align=8 + base size=16 base align=8 +QMovie (0x0x7f44692697b8) 0 + vptr=((& QMovie::_ZTV6QMovie) + 16) + QObject (0x0x7f446927f2a0) 0 + primary-for QMovie (0x0x7f44692697b8) + +Class QOffscreenSurface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOffscreenSurface::QPrivateSignal (0x0x7f446927f6c0) 0 empty + +Vtable for QOffscreenSurface +QOffscreenSurface::_ZTV17QOffscreenSurface: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOffscreenSurface) +16 (int (*)(...))QOffscreenSurface::metaObject +24 (int (*)(...))QOffscreenSurface::qt_metacast +32 (int (*)(...))QOffscreenSurface::qt_metacall +40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOffscreenSurface::surfaceType +120 (int (*)(...))QOffscreenSurface::format +128 (int (*)(...))QOffscreenSurface::size +136 (int (*)(...))QOffscreenSurface::surfaceHandle +144 (int (*)(...))-16 +152 (int (*)(...))(& _ZTI17QOffscreenSurface) +160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev +168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev +176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv +184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv +192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv +200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv + +Class QOffscreenSurface + size=40 align=8 + base size=40 base align=8 +QOffscreenSurface (0x0x7f446923cd20) 0 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16) + QObject (0x0x7f446927f600) 0 + primary-for QOffscreenSurface (0x0x7f446923cd20) + QSurface (0x0x7f446927f660) 16 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160) + +Class QOpenGLContextGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContextGroup::QPrivateSignal (0x0x7f446927f900) 0 empty + +Vtable for QOpenGLContextGroup +QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QOpenGLContextGroup) +16 (int (*)(...))QOpenGLContextGroup::metaObject +24 (int (*)(...))QOpenGLContextGroup::qt_metacast +32 (int (*)(...))QOpenGLContextGroup::qt_metacall +40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContextGroup + size=16 align=8 + base size=16 base align=8 +QOpenGLContextGroup (0x0x7f4469269820) 0 + vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16) + QObject (0x0x7f446927f8a0) 0 + primary-for QOpenGLContextGroup (0x0x7f4469269820) + +Class QOpenGLContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContext::QPrivateSignal (0x0x7f446927fae0) 0 empty + +Vtable for QOpenGLContext +QOpenGLContext::_ZTV14QOpenGLContext: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QOpenGLContext) +16 (int (*)(...))QOpenGLContext::metaObject +24 (int (*)(...))QOpenGLContext::qt_metacast +32 (int (*)(...))QOpenGLContext::qt_metacall +40 (int (*)(...))QOpenGLContext::~QOpenGLContext +48 (int (*)(...))QOpenGLContext::~QOpenGLContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContext + size=16 align=8 + base size=16 base align=8 +QOpenGLContext (0x0x7f4469269888) 0 + vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16) + QObject (0x0x7f446927fa80) 0 + primary-for QOpenGLContext (0x0x7f4469269888) + +Vtable for QNativeInterface::QGLXContext +QNativeInterface::QGLXContext::_ZTVN16QNativeInterface11QGLXContextE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface11QGLXContextE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QGLXContext + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QGLXContext (0x0x7f446927fc60) 0 nearly-empty + vptr=((& QNativeInterface::QGLXContext::_ZTVN16QNativeInterface11QGLXContextE) + 16) + +Vtable for QNativeInterface::QEGLContext +QNativeInterface::QEGLContext::_ZTVN16QNativeInterface11QEGLContextE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface11QEGLContextE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QEGLContext + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QEGLContext (0x0x7f446927fcc0) 0 nearly-empty + vptr=((& QNativeInterface::QEGLContext::_ZTVN16QNativeInterface11QEGLContextE) + 16) + +Class QOpenGLFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLFunctions (0x0x7f446927fd20) 0 + +Class QOpenGLFunctionsPrivate::Functions + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate::Functions (0x0x7f4466ccb300) 0 + +Class QOpenGLFunctionsPrivate + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate (0x0x7f4466ccb2a0) 0 + +Class QOpenGLExtraFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLExtraFunctions (0x0x7f4469269c98) 0 + QOpenGLFunctions (0x0x7f4466d3d0c0) 0 + +Class QOpenGLExtraFunctionsPrivate::Functions + size=1728 align=8 + base size=1728 base align=8 +QOpenGLExtraFunctionsPrivate::Functions (0x0x7f4466d3d420) 0 + +Class QOpenGLExtraFunctionsPrivate + size=2880 align=8 + base size=2880 base align=8 +QOpenGLExtraFunctionsPrivate (0x0x7f4469269d00) 0 + QOpenGLFunctionsPrivate (0x0x7f4466d3d3c0) 0 + +Class QPageSize + size=8 align=8 + base size=8 base align=8 +QPageSize (0x0x7f4466e18120) 0 + +Class QPageLayout + size=8 align=8 + base size=8 base align=8 +QPageLayout (0x0x7f4466e60ba0) 0 + +Class QPageRanges::Range + size=8 align=4 + base size=8 base align=4 +QPageRanges::Range (0x0x7f4466eb3840) 0 + +Class QPageRanges + size=8 align=8 + base size=8 base align=8 +QPageRanges (0x0x7f4466eb37e0) 0 + +Vtable for QPagedPaintDevice +QPagedPaintDevice::_ZTV17QPagedPaintDevice: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QPagedPaintDevice) +16 0 +24 0 +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QPagedPaintDevice::setPageLayout +96 (int (*)(...))QPagedPaintDevice::setPageSize +104 (int (*)(...))QPagedPaintDevice::setPageOrientation +112 (int (*)(...))QPagedPaintDevice::setPageMargins +120 (int (*)(...))QPagedPaintDevice::setPageRanges + +Class QPagedPaintDevice + size=24 align=8 + base size=24 base align=8 +QPagedPaintDevice (0x0x7f4466b1e8f0) 0 + vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16) + QPaintDevice (0x0x7f4466b1a960) 0 + primary-for QPagedPaintDevice (0x0x7f4466b1e8f0) + +Class QPaintDeviceWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPaintDeviceWindow::QPrivateSignal (0x0x7f4466b1aae0) 0 empty + +Vtable for QPaintDeviceWindow +QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 59 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +16 (int (*)(...))QPaintDeviceWindow::metaObject +24 (int (*)(...))QPaintDeviceWindow::qt_metacast +32 (int (*)(...))QPaintDeviceWindow::qt_metacall +40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QPaintDeviceWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QWindow::focusInEvent +192 (int (*)(...))QWindow::focusOutEvent +200 (int (*)(...))QWindow::showEvent +208 (int (*)(...))QWindow::hideEvent +216 (int (*)(...))QWindow::closeEvent +224 (int (*)(...))QWindow::keyPressEvent +232 (int (*)(...))QWindow::keyReleaseEvent +240 (int (*)(...))QWindow::mousePressEvent +248 (int (*)(...))QWindow::mouseReleaseEvent +256 (int (*)(...))QWindow::mouseDoubleClickEvent +264 (int (*)(...))QWindow::mouseMoveEvent +272 (int (*)(...))QWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))QPaintDeviceWindow::metric +320 (int (*)(...))QPaintDeviceWindow::paintEngine +328 (int (*)(...))-16 +336 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev +352 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +392 (int (*)(...))-40 +400 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev +416 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev +424 (int (*)(...))QPaintDevice::devType +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +440 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE +448 (int (*)(...))QPaintDevice::initPainter +456 (int (*)(...))QPaintDevice::redirected +464 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDeviceWindow + size=56 align=8 + base size=50 base align=8 +QPaintDeviceWindow (0x0x7f4466e6fe70) 0 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16) + QWindow (0x0x7f4466e6fee0) 0 + primary-for QPaintDeviceWindow (0x0x7f4466e6fe70) + QObject (0x0x7f4466b1a9c0) 0 + primary-for QWindow (0x0x7f4466e6fee0) + QSurface (0x0x7f4466b1aa20) 16 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 344) + QPaintDevice (0x0x7f4466b1aa80) 40 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 408) + +Class QPainter::PixmapFragment + size=80 align=8 + base size=80 base align=8 +QPainter::PixmapFragment (0x0x7f4466b1acc0) 0 + +Class QPainter + size=8 align=8 + base size=8 base align=8 +QPainter (0x0x7f4466b1ac60) 0 + +Class QTextItem + size=1 align=1 + base size=0 base align=1 +QTextItem (0x0x7f4466cbd840) 0 empty + +Vtable for QPaintEngine +QPaintEngine::_ZTV12QPaintEngine: 26 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintEngine) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QPaintEngine::drawRects +64 (int (*)(...))QPaintEngine::drawRects +72 (int (*)(...))QPaintEngine::drawLines +80 (int (*)(...))QPaintEngine::drawLines +88 (int (*)(...))QPaintEngine::drawEllipse +96 (int (*)(...))QPaintEngine::drawEllipse +104 (int (*)(...))QPaintEngine::drawPath +112 (int (*)(...))QPaintEngine::drawPoints +120 (int (*)(...))QPaintEngine::drawPoints +128 (int (*)(...))QPaintEngine::drawPolygon +136 (int (*)(...))QPaintEngine::drawPolygon +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QPaintEngine::drawTextItem +160 (int (*)(...))QPaintEngine::drawTiledPixmap +168 (int (*)(...))QPaintEngine::drawImage +176 (int (*)(...))QPaintEngine::coordinateOffset +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))QPaintEngine::createPixmap +200 (int (*)(...))QPaintEngine::createPixmapFromImage + +Class QPaintEngine + size=32 align=8 + base size=32 base align=8 +QPaintEngine (0x0x7f44668e7060) 0 + vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16) + +Class QPaintEngineState + size=4 align=4 + base size=4 base align=4 +QPaintEngineState (0x0x7f44668e7660) 0 + +Class QPainterPath::Element + size=24 align=8 + base size=24 base align=8 +QPainterPath::Element (0x0x7f4466945120) 0 + +Class QPainterPath + size=8 align=8 + base size=8 base align=8 +QPainterPath (0x0x7f44669450c0) 0 + +Class QPainterPathStroker + size=8 align=8 + base size=8 base align=8 +QPainterPathStroker (0x0x7f446699e420) 0 + +Class QPdfWriter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPdfWriter::QPrivateSignal (0x0x7f446699ec00) 0 empty + +Vtable for QPdfWriter +QPdfWriter::_ZTV10QPdfWriter: 33 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QPdfWriter) +16 (int (*)(...))QPdfWriter::metaObject +24 (int (*)(...))QPdfWriter::qt_metacast +32 (int (*)(...))QPdfWriter::qt_metacall +40 (int (*)(...))QPdfWriter::~QPdfWriter +48 (int (*)(...))QPdfWriter::~QPdfWriter +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPdfWriter::newPage +120 (int (*)(...))QPdfWriter::paintEngine +128 (int (*)(...))QPdfWriter::metric +136 (int (*)(...))-16 +144 (int (*)(...))(& _ZTI10QPdfWriter) +152 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev +160 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev +168 (int (*)(...))QPaintDevice::devType +176 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv +184 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE +192 (int (*)(...))QPaintDevice::initPainter +200 (int (*)(...))QPaintDevice::redirected +208 (int (*)(...))QPaintDevice::sharedPainter +216 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv +224 (int (*)(...))QPagedPaintDevice::setPageLayout +232 (int (*)(...))QPagedPaintDevice::setPageSize +240 (int (*)(...))QPagedPaintDevice::setPageOrientation +248 (int (*)(...))QPagedPaintDevice::setPageMargins +256 (int (*)(...))QPagedPaintDevice::setPageRanges + +Class QPdfWriter + size=40 align=8 + base size=40 base align=8 +QPdfWriter (0x0x7f4466975850) 0 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16) + QObject (0x0x7f446699eb40) 0 + primary-for QPdfWriter (0x0x7f4466975850) + QPagedPaintDevice (0x0x7f446699c750) 16 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 152) + QPaintDevice (0x0x7f446699eba0) 16 + primary-for QPagedPaintDevice (0x0x7f446699c750) + +Vtable for QPicture +QPicture::_ZTV8QPicture: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPicture) +16 (int (*)(...))QPicture::~QPicture +24 (int (*)(...))QPicture::~QPicture +32 (int (*)(...))QPicture::devType +40 (int (*)(...))QPicture::paintEngine +48 (int (*)(...))QPicture::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPicture::setData + +Class QPicture + size=24 align=8 + base size=24 base align=8 +QPicture (0x0x7f446699c7b8) 0 + vptr=((& QPicture::_ZTV8QPicture) + 16) + QPaintDevice (0x0x7f446699ede0) 0 + primary-for QPicture (0x0x7f446699c7b8) + +Class QPixmapCache::Key + size=8 align=8 + base size=8 base align=8 +QPixmapCache::Key (0x0x7f44669ef8a0) 0 + +Class QPixmapCache + size=1 align=1 + base size=0 base align=1 +QPixmapCache (0x0x7f44669ef840) 0 empty + +Class QRasterWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRasterWindow::QPrivateSignal (0x0x7f4466a30ae0) 0 empty + +Vtable for QRasterWindow +QRasterWindow::_ZTV13QRasterWindow: 60 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QRasterWindow) +16 (int (*)(...))QRasterWindow::metaObject +24 (int (*)(...))QRasterWindow::qt_metacast +32 (int (*)(...))QRasterWindow::qt_metacall +40 (int (*)(...))QRasterWindow::~QRasterWindow +48 (int (*)(...))QRasterWindow::~QRasterWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QPaintDeviceWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QWindow::focusInEvent +192 (int (*)(...))QWindow::focusOutEvent +200 (int (*)(...))QWindow::showEvent +208 (int (*)(...))QWindow::hideEvent +216 (int (*)(...))QWindow::closeEvent +224 (int (*)(...))QWindow::keyPressEvent +232 (int (*)(...))QWindow::keyReleaseEvent +240 (int (*)(...))QWindow::mousePressEvent +248 (int (*)(...))QWindow::mouseReleaseEvent +256 (int (*)(...))QWindow::mouseDoubleClickEvent +264 (int (*)(...))QWindow::mouseMoveEvent +272 (int (*)(...))QWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))QRasterWindow::metric +320 (int (*)(...))QPaintDeviceWindow::paintEngine +328 (int (*)(...))QRasterWindow::redirected +336 (int (*)(...))-16 +344 (int (*)(...))(& _ZTI13QRasterWindow) +352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev +360 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +392 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +400 (int (*)(...))-40 +408 (int (*)(...))(& _ZTI13QRasterWindow) +416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev +424 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev +432 (int (*)(...))QPaintDevice::devType +440 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +448 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE +456 (int (*)(...))QPaintDevice::initPainter +464 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint +472 (int (*)(...))QPaintDevice::sharedPainter + +Class QRasterWindow + size=56 align=8 + base size=50 base align=8 +QRasterWindow (0x0x7f4466a2cd00) 0 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16) + QPaintDeviceWindow (0x0x7f4466a1d460) 0 + primary-for QRasterWindow (0x0x7f4466a2cd00) + QWindow (0x0x7f4466a1d4d0) 0 + primary-for QPaintDeviceWindow (0x0x7f4466a1d460) + QObject (0x0x7f4466a309c0) 0 + primary-for QWindow (0x0x7f4466a1d4d0) + QSurface (0x0x7f4466a30a20) 16 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 352) + QPaintDevice (0x0x7f4466a30a80) 40 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 416) + +Class QSessionManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSessionManager::QPrivateSignal (0x0x7f4466a30cc0) 0 empty + +Vtable for QSessionManager +QSessionManager::_ZTV15QSessionManager: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSessionManager) +16 (int (*)(...))QSessionManager::metaObject +24 (int (*)(...))QSessionManager::qt_metacast +32 (int (*)(...))QSessionManager::qt_metacall +40 (int (*)(...))QSessionManager::~QSessionManager +48 (int (*)(...))QSessionManager::~QSessionManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSessionManager + size=16 align=8 + base size=16 base align=8 +QSessionManager (0x0x7f4466a2cdd0) 0 + vptr=((& QSessionManager::_ZTV15QSessionManager) + 16) + QObject (0x0x7f4466a30c60) 0 + primary-for QSessionManager (0x0x7f4466a2cdd0) + +Class QShortcut::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QShortcut::QPrivateSignal (0x0x7f4466a30ea0) 0 empty + +Vtable for QShortcut +QShortcut::_ZTV9QShortcut: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QShortcut) +16 (int (*)(...))QShortcut::metaObject +24 (int (*)(...))QShortcut::qt_metacast +32 (int (*)(...))QShortcut::qt_metacall +40 (int (*)(...))QShortcut::~QShortcut +48 (int (*)(...))QShortcut::~QShortcut +56 (int (*)(...))QShortcut::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QShortcut + size=16 align=8 + base size=16 base align=8 +QShortcut (0x0x7f4466a2ce38) 0 + vptr=((& QShortcut::_ZTV9QShortcut) + 16) + QObject (0x0x7f4466a30e40) 0 + primary-for QShortcut (0x0x7f4466a2ce38) + +Vtable for QStandardItem +QStandardItem::_ZTV13QStandardItem: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStandardItem) +16 (int (*)(...))QStandardItem::~QStandardItem +24 (int (*)(...))QStandardItem::~QStandardItem +32 (int (*)(...))QStandardItem::data +40 (int (*)(...))QStandardItem::multiData +48 (int (*)(...))QStandardItem::setData +56 (int (*)(...))QStandardItem::clone +64 (int (*)(...))QStandardItem::type +72 (int (*)(...))QStandardItem::read +80 (int (*)(...))QStandardItem::write +88 (int (*)(...))QStandardItem::operator< + +Class QStandardItem + size=16 align=8 + base size=16 base align=8 +QStandardItem (0x0x7f4466a603c0) 0 + vptr=((& QStandardItem::_ZTV13QStandardItem) + 16) + +Class QStandardItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStandardItemModel::QPrivateSignal (0x0x7f44666d13c0) 0 empty + +Vtable for QStandardItemModel +QStandardItemModel::_ZTV18QStandardItemModel: 51 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QStandardItemModel) +16 (int (*)(...))QStandardItemModel::metaObject +24 (int (*)(...))QStandardItemModel::qt_metacast +32 (int (*)(...))QStandardItemModel::qt_metacall +40 (int (*)(...))QStandardItemModel::~QStandardItemModel +48 (int (*)(...))QStandardItemModel::~QStandardItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStandardItemModel::index +120 (int (*)(...))QStandardItemModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QStandardItemModel::rowCount +144 (int (*)(...))QStandardItemModel::columnCount +152 (int (*)(...))QStandardItemModel::hasChildren +160 (int (*)(...))QStandardItemModel::data +168 (int (*)(...))QStandardItemModel::setData +176 (int (*)(...))QStandardItemModel::headerData +184 (int (*)(...))QStandardItemModel::setHeaderData +192 (int (*)(...))QStandardItemModel::itemData +200 (int (*)(...))QStandardItemModel::setItemData +208 (int (*)(...))QStandardItemModel::clearItemData +216 (int (*)(...))QStandardItemModel::mimeTypes +224 (int (*)(...))QStandardItemModel::mimeData +232 (int (*)(...))QAbstractItemModel::canDropMimeData +240 (int (*)(...))QStandardItemModel::dropMimeData +248 (int (*)(...))QStandardItemModel::supportedDropActions +256 (int (*)(...))QAbstractItemModel::supportedDragActions +264 (int (*)(...))QStandardItemModel::insertRows +272 (int (*)(...))QStandardItemModel::insertColumns +280 (int (*)(...))QStandardItemModel::removeRows +288 (int (*)(...))QStandardItemModel::removeColumns +296 (int (*)(...))QAbstractItemModel::moveRows +304 (int (*)(...))QAbstractItemModel::moveColumns +312 (int (*)(...))QAbstractItemModel::fetchMore +320 (int (*)(...))QAbstractItemModel::canFetchMore +328 (int (*)(...))QStandardItemModel::flags +336 (int (*)(...))QStandardItemModel::sort +344 (int (*)(...))QAbstractItemModel::buddy +352 (int (*)(...))QAbstractItemModel::match +360 (int (*)(...))QAbstractItemModel::span +368 (int (*)(...))QStandardItemModel::roleNames +376 (int (*)(...))QStandardItemModel::multiData +384 (int (*)(...))QAbstractItemModel::submit +392 (int (*)(...))QAbstractItemModel::revert +400 (int (*)(...))QAbstractItemModel::resetInternalData + +Class QStandardItemModel + size=16 align=8 + base size=16 base align=8 +QStandardItemModel (0x0x7f4466a947b8) 0 + vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16) + QAbstractItemModel (0x0x7f4466a94820) 0 + primary-for QStandardItemModel (0x0x7f4466a947b8) + QObject (0x0x7f44666d1360) 0 + primary-for QAbstractItemModel (0x0x7f4466a94820) + +Class QStaticText + size=8 align=8 + base size=8 base align=8 +QStaticText (0x0x7f44666d1720) 0 + +Class QStyleHints::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyleHints::QPrivateSignal (0x0x7f4466738060) 0 empty + +Vtable for QStyleHints +QStyleHints::_ZTV11QStyleHints: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QStyleHints) +16 (int (*)(...))QStyleHints::metaObject +24 (int (*)(...))QStyleHints::qt_metacast +32 (int (*)(...))QStyleHints::qt_metacall +40 (int (*)(...))QStyleHints::~QStyleHints +48 (int (*)(...))QStyleHints::~QStyleHints +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QStyleHints + size=16 align=8 + base size=16 base align=8 +QStyleHints (0x0x7f446672f478) 0 + vptr=((& QStyleHints::_ZTV11QStyleHints) + 16) + QObject (0x0x7f4466738000) 0 + primary-for QStyleHints (0x0x7f446672f478) + +Class QTextObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextObject::QPrivateSignal (0x0x7f4466738240) 0 empty + +Vtable for QTextObject +QTextObject::_ZTV11QTextObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextObject) +16 (int (*)(...))QTextObject::metaObject +24 (int (*)(...))QTextObject::qt_metacast +32 (int (*)(...))QTextObject::qt_metacall +40 (int (*)(...))QTextObject::~QTextObject +48 (int (*)(...))QTextObject::~QTextObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextObject + size=16 align=8 + base size=16 base align=8 +QTextObject (0x0x7f446672f4e0) 0 + vptr=((& QTextObject::_ZTV11QTextObject) + 16) + QObject (0x0x7f44667381e0) 0 + primary-for QTextObject (0x0x7f446672f4e0) + +Class QTextBlockGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBlockGroup::QPrivateSignal (0x0x7f4466738420) 0 empty + +Vtable for QTextBlockGroup +QTextBlockGroup::_ZTV15QTextBlockGroup: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTextBlockGroup) +16 (int (*)(...))QTextBlockGroup::metaObject +24 (int (*)(...))QTextBlockGroup::qt_metacast +32 (int (*)(...))QTextBlockGroup::qt_metacall +40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextBlockGroup + size=16 align=8 + base size=16 base align=8 +QTextBlockGroup (0x0x7f446672f548) 0 + vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16) + QTextObject (0x0x7f446672f5b0) 0 + primary-for QTextBlockGroup (0x0x7f446672f548) + QObject (0x0x7f44667383c0) 0 + primary-for QTextObject (0x0x7f446672f5b0) + +Vtable for QTextFrameLayoutData +QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextFrameLayoutData) +16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData +24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData + +Class QTextFrameLayoutData + size=8 align=8 + base size=8 base align=8 +QTextFrameLayoutData (0x0x7f44667385a0) 0 nearly-empty + vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16) + +Class QTextFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextFrame::QPrivateSignal (0x0x7f4466738660) 0 empty + +Class QTextFrame::iterator + size=32 align=8 + base size=28 base align=8 +QTextFrame::iterator (0x0x7f44667386c0) 0 + +Vtable for QTextFrame +QTextFrame::_ZTV10QTextFrame: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextFrame) +16 (int (*)(...))QTextFrame::metaObject +24 (int (*)(...))QTextFrame::qt_metacast +32 (int (*)(...))QTextFrame::qt_metacall +40 (int (*)(...))QTextFrame::~QTextFrame +48 (int (*)(...))QTextFrame::~QTextFrame +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextFrame + size=16 align=8 + base size=16 base align=8 +QTextFrame (0x0x7f446672f618) 0 + vptr=((& QTextFrame::_ZTV10QTextFrame) + 16) + QTextObject (0x0x7f446672f680) 0 + primary-for QTextFrame (0x0x7f446672f618) + QObject (0x0x7f4466738600) 0 + primary-for QTextObject (0x0x7f446672f680) + +Vtable for QTextBlockUserData +QTextBlockUserData::_ZTV18QTextBlockUserData: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTextBlockUserData) +16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData +24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData + +Class QTextBlockUserData + size=8 align=8 + base size=8 base align=8 +QTextBlockUserData (0x0x7f4466780540) 0 nearly-empty + vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16) + +Class QTextBlock::iterator + size=24 align=8 + base size=20 base align=8 +QTextBlock::iterator (0x0x7f4466780600) 0 + +Class QTextBlock + size=16 align=8 + base size=12 base align=8 +QTextBlock (0x0x7f44667805a0) 0 + +Class QTextFragment + size=16 align=8 + base size=16 base align=8 +QTextFragment (0x0x7f44667c2e40) 0 + +Class QSyntaxHighlighter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSyntaxHighlighter::QPrivateSignal (0x0x7f44667e7cc0) 0 empty + +Vtable for QSyntaxHighlighter +QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSyntaxHighlighter) +16 (int (*)(...))QSyntaxHighlighter::metaObject +24 (int (*)(...))QSyntaxHighlighter::qt_metacast +32 (int (*)(...))QSyntaxHighlighter::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSyntaxHighlighter + size=16 align=8 + base size=16 base align=8 +QSyntaxHighlighter (0x0x7f44667f0820) 0 + vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16) + QObject (0x0x7f44667e7c60) 0 + primary-for QSyntaxHighlighter (0x0x7f44667f0820) + +Class QTextDocumentFragment + size=8 align=8 + base size=8 base align=8 +QTextDocumentFragment (0x0x7f44667e7e40) 0 + +Class QTextDocumentWriter + size=8 align=8 + base size=8 base align=8 +QTextDocumentWriter (0x0x7f44667e7ea0) 0 + +Class QTextList::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextList::QPrivateSignal (0x0x7f44667e7f60) 0 empty + +Vtable for QTextList +QTextList::_ZTV9QTextList: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextList) +16 (int (*)(...))QTextList::metaObject +24 (int (*)(...))QTextList::qt_metacast +32 (int (*)(...))QTextList::qt_metacall +40 (int (*)(...))QTextList::~QTextList +48 (int (*)(...))QTextList::~QTextList +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextList + size=16 align=8 + base size=16 base align=8 +QTextList (0x0x7f44667f0888) 0 + vptr=((& QTextList::_ZTV9QTextList) + 16) + QTextBlockGroup (0x0x7f44667f08f0) 0 + primary-for QTextList (0x0x7f44667f0888) + QTextObject (0x0x7f44667f0958) 0 + primary-for QTextBlockGroup (0x0x7f44667f08f0) + QObject (0x0x7f44667e7f00) 0 + primary-for QTextObject (0x0x7f44667f0958) + +Class QTextTableCell + size=16 align=8 + base size=12 base align=8 +QTextTableCell (0x0x7f4466811360) 0 + +Class QTextTable::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextTable::QPrivateSignal (0x0x7f4466811ba0) 0 empty + +Vtable for QTextTable +QTextTable::_ZTV10QTextTable: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextTable) +16 (int (*)(...))QTextTable::metaObject +24 (int (*)(...))QTextTable::qt_metacast +32 (int (*)(...))QTextTable::qt_metacall +40 (int (*)(...))QTextTable::~QTextTable +48 (int (*)(...))QTextTable::~QTextTable +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextTable + size=16 align=8 + base size=16 base align=8 +QTextTable (0x0x7f44667f09c0) 0 + vptr=((& QTextTable::_ZTV10QTextTable) + 16) + QTextFrame (0x0x7f44667f0a28) 0 + primary-for QTextTable (0x0x7f44667f09c0) + QTextObject (0x0x7f44667f0a90) 0 + primary-for QTextFrame (0x0x7f44667f0a28) + QObject (0x0x7f4466811b40) 0 + primary-for QTextObject (0x0x7f44667f0a90) + +Class QUndoGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoGroup::QPrivateSignal (0x0x7f4466811f60) 0 empty + +Vtable for QUndoGroup +QUndoGroup::_ZTV10QUndoGroup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUndoGroup) +16 (int (*)(...))QUndoGroup::metaObject +24 (int (*)(...))QUndoGroup::qt_metacast +32 (int (*)(...))QUndoGroup::qt_metacall +40 (int (*)(...))QUndoGroup::~QUndoGroup +48 (int (*)(...))QUndoGroup::~QUndoGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QUndoGroup + size=16 align=8 + base size=16 base align=8 +QUndoGroup (0x0x7f44667f0af8) 0 + vptr=((& QUndoGroup::_ZTV10QUndoGroup) + 16) + QObject (0x0x7f4466811f00) 0 + primary-for QUndoGroup (0x0x7f44667f0af8) + +Vtable for QUndoCommand +QUndoCommand::_ZTV12QUndoCommand: 8 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QUndoCommand) +16 (int (*)(...))QUndoCommand::~QUndoCommand +24 (int (*)(...))QUndoCommand::~QUndoCommand +32 (int (*)(...))QUndoCommand::undo +40 (int (*)(...))QUndoCommand::redo +48 (int (*)(...))QUndoCommand::id +56 (int (*)(...))QUndoCommand::mergeWith + +Class QUndoCommand + size=16 align=8 + base size=16 base align=8 +QUndoCommand (0x0x7f4466832120) 0 + vptr=((& QUndoCommand::_ZTV12QUndoCommand) + 16) + +Class QUndoStack::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoStack::QPrivateSignal (0x0x7f44668321e0) 0 empty + +Vtable for QUndoStack +QUndoStack::_ZTV10QUndoStack: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUndoStack) +16 (int (*)(...))QUndoStack::metaObject +24 (int (*)(...))QUndoStack::qt_metacast +32 (int (*)(...))QUndoStack::qt_metacall +40 (int (*)(...))QUndoStack::~QUndoStack +48 (int (*)(...))QUndoStack::~QUndoStack +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QUndoStack + size=16 align=8 + base size=16 base align=8 +QUndoStack (0x0x7f44667f0b60) 0 + vptr=((& QUndoStack::_ZTV10QUndoStack) + 16) + QObject (0x0x7f4466832180) 0 + primary-for QUndoStack (0x0x7f44667f0b60) + +Class QValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QValidator::QPrivateSignal (0x0x7f44668323c0) 0 empty + +Vtable for QValidator +QValidator::_ZTV10QValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QValidator) +16 (int (*)(...))QValidator::metaObject +24 (int (*)(...))QValidator::qt_metacast +32 (int (*)(...))QValidator::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QValidator::fixup + +Class QValidator + size=16 align=8 + base size=16 base align=8 +QValidator (0x0x7f44667f0bc8) 0 + vptr=((& QValidator::_ZTV10QValidator) + 16) + QObject (0x0x7f4466832360) 0 + primary-for QValidator (0x0x7f44667f0bc8) + +Class QIntValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIntValidator::QPrivateSignal (0x0x7f4466832660) 0 empty + +Vtable for QIntValidator +QIntValidator::_ZTV13QIntValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QIntValidator) +16 (int (*)(...))QIntValidator::metaObject +24 (int (*)(...))QIntValidator::qt_metacast +32 (int (*)(...))QIntValidator::qt_metacall +40 (int (*)(...))QIntValidator::~QIntValidator +48 (int (*)(...))QIntValidator::~QIntValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIntValidator::validate +120 (int (*)(...))QIntValidator::fixup + +Class QIntValidator + size=24 align=8 + base size=24 base align=8 +QIntValidator (0x0x7f44667f0c30) 0 + vptr=((& QIntValidator::_ZTV13QIntValidator) + 16) + QValidator (0x0x7f44667f0c98) 0 + primary-for QIntValidator (0x0x7f44667f0c30) + QObject (0x0x7f4466832600) 0 + primary-for QValidator (0x0x7f44667f0c98) + +Class QDoubleValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleValidator::QPrivateSignal (0x0x7f4466832840) 0 empty + +Vtable for QDoubleValidator +QDoubleValidator::_ZTV16QDoubleValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDoubleValidator) +16 (int (*)(...))QDoubleValidator::metaObject +24 (int (*)(...))QDoubleValidator::qt_metacast +32 (int (*)(...))QDoubleValidator::qt_metacall +40 (int (*)(...))QDoubleValidator::~QDoubleValidator +48 (int (*)(...))QDoubleValidator::~QDoubleValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDoubleValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QDoubleValidator + size=40 align=8 + base size=36 base align=8 +QDoubleValidator (0x0x7f44667f0d00) 0 + vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16) + QValidator (0x0x7f44667f0d68) 0 + primary-for QDoubleValidator (0x0x7f44667f0d00) + QObject (0x0x7f44668327e0) 0 + primary-for QValidator (0x0x7f44667f0d68) + +Class QRegularExpressionValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegularExpressionValidator::QPrivateSignal (0x0x7f4466832c00) 0 empty + +Vtable for QRegularExpressionValidator +QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QRegularExpressionValidator) +16 (int (*)(...))QRegularExpressionValidator::metaObject +24 (int (*)(...))QRegularExpressionValidator::qt_metacast +32 (int (*)(...))QRegularExpressionValidator::qt_metacall +40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegularExpressionValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegularExpressionValidator + size=16 align=8 + base size=16 base align=8 +QRegularExpressionValidator (0x0x7f44667f0dd0) 0 + vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16) + QValidator (0x0x7f44667f0e38) 0 + primary-for QRegularExpressionValidator (0x0x7f44667f0dd0) + QObject (0x0x7f4466832ba0) 0 + primary-for QValidator (0x0x7f44667f0e38) + +Class QNetworkRequest + size=8 align=8 + base size=8 base align=8 +QNetworkRequest (0x0x7f4466832d80) 0 + +Class QNetworkCacheMetaData + size=8 align=8 + base size=8 base align=8 +QNetworkCacheMetaData (0x0x7f44668af9c0) 0 + +Class QAbstractNetworkCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractNetworkCache::QPrivateSignal (0x0x7f4466501120) 0 empty + +Vtable for QAbstractNetworkCache +QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractNetworkCache) +16 (int (*)(...))QAbstractNetworkCache::metaObject +24 (int (*)(...))QAbstractNetworkCache::qt_metacast +32 (int (*)(...))QAbstractNetworkCache::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNetworkCache + size=16 align=8 + base size=16 base align=8 +QAbstractNetworkCache (0x0x7f44664fb9c0) 0 + vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16) + QObject (0x0x7f44665010c0) 0 + primary-for QAbstractNetworkCache (0x0x7f44664fb9c0) + +Class QAbstractSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSocket::QPrivateSignal (0x0x7f4466501360) 0 empty + +Vtable for QAbstractSocket +QAbstractSocket::_ZTV15QAbstractSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSocket) +16 (int (*)(...))QAbstractSocket::metaObject +24 (int (*)(...))QAbstractSocket::qt_metacast +32 (int (*)(...))QAbstractSocket::qt_metacall +40 (int (*)(...))QAbstractSocket::~QAbstractSocket +48 (int (*)(...))QAbstractSocket::~QAbstractSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::skipData +240 (int (*)(...))QAbstractSocket::writeData +248 (int (*)(...))QAbstractSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QAbstractSocket::connectToHost +272 (int (*)(...))QAbstractSocket::disconnectFromHost +280 (int (*)(...))QAbstractSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketDescriptor +304 (int (*)(...))QAbstractSocket::setSocketOption +312 (int (*)(...))QAbstractSocket::socketOption +320 (int (*)(...))QAbstractSocket::waitForConnected +328 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QAbstractSocket + size=16 align=8 + base size=16 base align=8 +QAbstractSocket (0x0x7f44664fba28) 0 + vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16) + QIODevice (0x0x7f44668b7850) 0 + primary-for QAbstractSocket (0x0x7f44664fba28) + QObject (0x0x7f44665012a0) 0 + primary-for QIODevice (0x0x7f44668b7850) + QIODeviceBase (0x0x7f4466501300) 0 empty + +Class QAuthenticator + size=8 align=8 + base size=8 base align=8 +QAuthenticator (0x0x7f4466556120) 0 + +Class QDnsDomainNameRecord + size=8 align=8 + base size=8 base align=8 +QDnsDomainNameRecord (0x0x7f44665561e0) 0 + +Class QDnsHostAddressRecord + size=8 align=8 + base size=8 base align=8 +QDnsHostAddressRecord (0x0x7f4466595840) 0 + +Class QDnsMailExchangeRecord + size=8 align=8 + base size=8 base align=8 +QDnsMailExchangeRecord (0x0x7f44665ccea0) 0 + +Class QDnsServiceRecord + size=8 align=8 + base size=8 base align=8 +QDnsServiceRecord (0x0x7f446661b540) 0 + +Class QDnsTextRecord + size=8 align=8 + base size=8 base align=8 +QDnsTextRecord (0x0x7f4466653d80) 0 + +Class QDnsLookup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDnsLookup::QPrivateSignal (0x0x7f4466698720) 0 empty + +Vtable for QDnsLookup +QDnsLookup::_ZTV10QDnsLookup: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDnsLookup) +16 (int (*)(...))QDnsLookup::metaObject +24 (int (*)(...))QDnsLookup::qt_metacast +32 (int (*)(...))QDnsLookup::qt_metacall +40 (int (*)(...))QDnsLookup::~QDnsLookup +48 (int (*)(...))QDnsLookup::~QDnsLookup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDnsLookup + size=16 align=8 + base size=16 base align=8 +QDnsLookup (0x0x7f4466692f08) 0 + vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16) + QObject (0x0x7f44666986c0) 0 + primary-for QDnsLookup (0x0x7f4466692f08) + +Class QTcpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpSocket::QPrivateSignal (0x0x7f4466698ae0) 0 empty + +Vtable for QTcpSocket +QTcpSocket::_ZTV10QTcpSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpSocket) +16 (int (*)(...))QTcpSocket::metaObject +24 (int (*)(...))QTcpSocket::qt_metacast +32 (int (*)(...))QTcpSocket::qt_metacall +40 (int (*)(...))QTcpSocket::~QTcpSocket +48 (int (*)(...))QTcpSocket::~QTcpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::skipData +240 (int (*)(...))QAbstractSocket::writeData +248 (int (*)(...))QAbstractSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QAbstractSocket::connectToHost +272 (int (*)(...))QAbstractSocket::disconnectFromHost +280 (int (*)(...))QAbstractSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketDescriptor +304 (int (*)(...))QAbstractSocket::setSocketOption +312 (int (*)(...))QAbstractSocket::socketOption +320 (int (*)(...))QAbstractSocket::waitForConnected +328 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QTcpSocket + size=16 align=8 + base size=16 base align=8 +QTcpSocket (0x0x7f4466692f70) 0 + vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16) + QAbstractSocket (0x0x7f44666b1000) 0 + primary-for QTcpSocket (0x0x7f4466692f70) + QIODevice (0x0x7f446668e9a0) 0 + primary-for QAbstractSocket (0x0x7f44666b1000) + QObject (0x0x7f4466698a20) 0 + primary-for QIODevice (0x0x7f446668e9a0) + QIODeviceBase (0x0x7f4466698a80) 0 empty + +Class QSslCertificate + size=8 align=8 + base size=8 base align=8 +QSslCertificate (0x0x7f4466698f60) 0 + +Class QSslError + size=8 align=8 + base size=8 base align=8 +QSslError (0x0x7f4466310e40) 0 + +Class QSslSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSslSocket::QPrivateSignal (0x0x7f4466355720) 0 empty + +Vtable for QSslSocket +QSslSocket::_ZTV10QSslSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSslSocket) +16 (int (*)(...))QSslSocket::metaObject +24 (int (*)(...))QSslSocket::qt_metacast +32 (int (*)(...))QSslSocket::qt_metacall +40 (int (*)(...))QSslSocket::~QSslSocket +48 (int (*)(...))QSslSocket::~QSslSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QSslSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QSslSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QSslSocket::bytesAvailable +184 (int (*)(...))QSslSocket::bytesToWrite +192 (int (*)(...))QSslSocket::canReadLine +200 (int (*)(...))QSslSocket::waitForReadyRead +208 (int (*)(...))QSslSocket::waitForBytesWritten +216 (int (*)(...))QSslSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QSslSocket::skipData +240 (int (*)(...))QSslSocket::writeData +248 (int (*)(...))QSslSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QSslSocket::connectToHost +272 (int (*)(...))QSslSocket::disconnectFromHost +280 (int (*)(...))QSslSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QSslSocket::setSocketDescriptor +304 (int (*)(...))QSslSocket::setSocketOption +312 (int (*)(...))QSslSocket::socketOption +320 (int (*)(...))QSslSocket::waitForConnected +328 (int (*)(...))QSslSocket::waitForDisconnected + +Class QSslSocket + size=16 align=8 + base size=16 base align=8 +QSslSocket (0x0x7f44663547b8) 0 + vptr=((& QSslSocket::_ZTV10QSslSocket) + 16) + QTcpSocket (0x0x7f4466354820) 0 + primary-for QSslSocket (0x0x7f44663547b8) + QAbstractSocket (0x0x7f4466354888) 0 + primary-for QTcpSocket (0x0x7f4466354820) + QIODevice (0x0x7f4466322a80) 0 + primary-for QAbstractSocket (0x0x7f4466354888) + QObject (0x0x7f4466355660) 0 + primary-for QIODevice (0x0x7f4466322a80) + QIODeviceBase (0x0x7f44663556c0) 0 empty + +Class QDtlsClientVerifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtlsClientVerifier::QPrivateSignal (0x0x7f4466355900) 0 empty + +Class QDtlsClientVerifier::GeneratorParameters + size=32 align=8 + base size=32 base align=8 +QDtlsClientVerifier::GeneratorParameters (0x0x7f4466355960) 0 + +Vtable for QDtlsClientVerifier +QDtlsClientVerifier::_ZTV19QDtlsClientVerifier: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QDtlsClientVerifier) +16 (int (*)(...))QDtlsClientVerifier::metaObject +24 (int (*)(...))QDtlsClientVerifier::qt_metacast +32 (int (*)(...))QDtlsClientVerifier::qt_metacall +40 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +48 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtlsClientVerifier + size=16 align=8 + base size=16 base align=8 +QDtlsClientVerifier (0x0x7f44663548f0) 0 + vptr=((& QDtlsClientVerifier::_ZTV19QDtlsClientVerifier) + 16) + QObject (0x0x7f44663558a0) 0 + primary-for QDtlsClientVerifier (0x0x7f44663548f0) + +Class QDtls::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtls::QPrivateSignal (0x0x7f4466355b40) 0 empty + +Vtable for QDtls +QDtls::_ZTV5QDtls: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDtls) +16 (int (*)(...))QDtls::metaObject +24 (int (*)(...))QDtls::qt_metacast +32 (int (*)(...))QDtls::qt_metacall +40 (int (*)(...))QDtls::~QDtls +48 (int (*)(...))QDtls::~QDtls +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtls + size=16 align=8 + base size=16 base align=8 +QDtls (0x0x7f4466354958) 0 + vptr=((& QDtls::_ZTV5QDtls) + 16) + QObject (0x0x7f4466355ae0) 0 + primary-for QDtls (0x0x7f4466354958) + +Class QIPv6Address + size=16 align=1 + base size=16 base align=1 +QIPv6Address (0x0x7f4466355cc0) 0 + +Class QHostAddress + size=8 align=8 + base size=8 base align=8 +QHostAddress (0x0x7f4466355de0) 0 + +Class QHostInfo + size=8 align=8 + base size=8 base align=8 +QHostInfo (0x0x7f44663d3ba0) 0 + +Class QHstsPolicy + size=8 align=8 + base size=8 base align=8 +QHstsPolicy (0x0x7f446641ecc0) 0 + +Class QHttp2Configuration + size=8 align=8 + base size=8 base align=8 +QHttp2Configuration (0x0x7f446646d720) 0 + +Class QHttpPart + size=8 align=8 + base size=8 base align=8 +QHttpPart (0x0x7f44664b5060) 0 + +Class QHttpMultiPart::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHttpMultiPart::QPrivateSignal (0x0x7f44660ee780) 0 empty + +Vtable for QHttpMultiPart +QHttpMultiPart::_ZTV14QHttpMultiPart: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QHttpMultiPart) +16 (int (*)(...))QHttpMultiPart::metaObject +24 (int (*)(...))QHttpMultiPart::qt_metacast +32 (int (*)(...))QHttpMultiPart::qt_metacall +40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QHttpMultiPart + size=16 align=8 + base size=16 base align=8 +QHttpMultiPart (0x0x7f44660f1410) 0 + vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16) + QObject (0x0x7f44660ee720) 0 + primary-for QHttpMultiPart (0x0x7f44660f1410) + +Class QLocalServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalServer::QPrivateSignal (0x0x7f44660ee960) 0 empty + +Vtable for QLocalServer +QLocalServer::_ZTV12QLocalServer: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalServer) +16 (int (*)(...))QLocalServer::metaObject +24 (int (*)(...))QLocalServer::qt_metacast +32 (int (*)(...))QLocalServer::qt_metacall +40 (int (*)(...))QLocalServer::~QLocalServer +48 (int (*)(...))QLocalServer::~QLocalServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalServer::hasPendingConnections +120 (int (*)(...))QLocalServer::nextPendingConnection +128 (int (*)(...))QLocalServer::incomingConnection + +Class QLocalServer + size=16 align=8 + base size=16 base align=8 +QLocalServer (0x0x7f44660f1478) 0 + vptr=((& QLocalServer::_ZTV12QLocalServer) + 16) + QObject (0x0x7f44660ee900) 0 + primary-for QLocalServer (0x0x7f44660f1478) + +Class QLocalSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalSocket::QPrivateSignal (0x0x7f4466121060) 0 empty + +Vtable for QLocalSocket +QLocalSocket::_ZTV12QLocalSocket: 31 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalSocket) +16 (int (*)(...))QLocalSocket::metaObject +24 (int (*)(...))QLocalSocket::qt_metacast +32 (int (*)(...))QLocalSocket::qt_metacall +40 (int (*)(...))QLocalSocket::~QLocalSocket +48 (int (*)(...))QLocalSocket::~QLocalSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalSocket::isSequential +120 (int (*)(...))QLocalSocket::open +128 (int (*)(...))QLocalSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QLocalSocket::bytesAvailable +184 (int (*)(...))QLocalSocket::bytesToWrite +192 (int (*)(...))QLocalSocket::canReadLine +200 (int (*)(...))QLocalSocket::waitForReadyRead +208 (int (*)(...))QLocalSocket::waitForBytesWritten +216 (int (*)(...))QLocalSocket::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QLocalSocket::skipData +240 (int (*)(...))QLocalSocket::writeData + +Class QLocalSocket + size=16 align=8 + base size=16 base align=8 +QLocalSocket (0x0x7f44660f1618) 0 + vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16) + QIODevice (0x0x7f4466102230) 0 + primary-for QLocalSocket (0x0x7f44660f1618) + QObject (0x0x7f44660eef60) 0 + primary-for QIODevice (0x0x7f4466102230) + QIODeviceBase (0x0x7f4466121000) 0 empty + +Class QSslConfiguration + size=8 align=8 + base size=8 base align=8 +QSslConfiguration (0x0x7f44661211e0) 0 + +Class QSslPreSharedKeyAuthenticator + size=8 align=8 + base size=8 base align=8 +QSslPreSharedKeyAuthenticator (0x0x7f4466196240) 0 + +Class QNetworkAccessManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkAccessManager::QPrivateSignal (0x0x7f44661cfba0) 0 empty + +Vtable for QNetworkAccessManager +QNetworkAccessManager::_ZTV21QNetworkAccessManager: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QNetworkAccessManager) +16 (int (*)(...))QNetworkAccessManager::metaObject +24 (int (*)(...))QNetworkAccessManager::qt_metacast +32 (int (*)(...))QNetworkAccessManager::qt_metacall +40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkAccessManager::supportedSchemes +120 (int (*)(...))QNetworkAccessManager::createRequest + +Class QNetworkAccessManager + size=16 align=8 + base size=16 base align=8 +QNetworkAccessManager (0x0x7f44661db068) 0 + vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16) + QObject (0x0x7f44661cfb40) 0 + primary-for QNetworkAccessManager (0x0x7f44661db068) + +Class QNetworkCookie + size=8 align=8 + base size=8 base align=8 +QNetworkCookie (0x0x7f44661cfd20) 0 + +Class QNetworkCookieJar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkCookieJar::QPrivateSignal (0x0x7f4466231840) 0 empty + +Vtable for QNetworkCookieJar +QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkCookieJar) +16 (int (*)(...))QNetworkCookieJar::metaObject +24 (int (*)(...))QNetworkCookieJar::qt_metacast +32 (int (*)(...))QNetworkCookieJar::qt_metacall +40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkCookieJar::cookiesForUrl +120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl +128 (int (*)(...))QNetworkCookieJar::insertCookie +136 (int (*)(...))QNetworkCookieJar::updateCookie +144 (int (*)(...))QNetworkCookieJar::deleteCookie +152 (int (*)(...))QNetworkCookieJar::validateCookie + +Class QNetworkCookieJar + size=16 align=8 + base size=16 base align=8 +QNetworkCookieJar (0x0x7f446622cdd0) 0 + vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16) + QObject (0x0x7f44662317e0) 0 + primary-for QNetworkCookieJar (0x0x7f446622cdd0) + +Class QNetworkDatagram + size=8 align=8 + base size=8 base align=8 +QNetworkDatagram (0x0x7f44662319c0) 0 + +Class QNetworkDiskCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkDiskCache::QPrivateSignal (0x0x7f446627dd80) 0 empty + +Vtable for QNetworkDiskCache +QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkDiskCache) +16 (int (*)(...))QNetworkDiskCache::metaObject +24 (int (*)(...))QNetworkDiskCache::qt_metacast +32 (int (*)(...))QNetworkDiskCache::qt_metacall +40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkDiskCache::metaData +120 (int (*)(...))QNetworkDiskCache::updateMetaData +128 (int (*)(...))QNetworkDiskCache::data +136 (int (*)(...))QNetworkDiskCache::remove +144 (int (*)(...))QNetworkDiskCache::cacheSize +152 (int (*)(...))QNetworkDiskCache::prepare +160 (int (*)(...))QNetworkDiskCache::insert +168 (int (*)(...))QNetworkDiskCache::clear +176 (int (*)(...))QNetworkDiskCache::expire + +Class QNetworkDiskCache + size=16 align=8 + base size=16 base align=8 +QNetworkDiskCache (0x0x7f446627fc98) 0 + vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16) + QAbstractNetworkCache (0x0x7f446627fd00) 0 + primary-for QNetworkDiskCache (0x0x7f446627fc98) + QObject (0x0x7f446627dd20) 0 + primary-for QAbstractNetworkCache (0x0x7f446627fd00) + +Class QNetworkAddressEntry + size=8 align=8 + base size=8 base align=8 +QNetworkAddressEntry (0x0x7f446627df00) 0 + +Class QNetworkInterface + size=8 align=8 + base size=8 base align=8 +QNetworkInterface (0x0x7f4465ec9480) 0 + +Class QNetworkProxyQuery + size=8 align=8 + base size=8 base align=8 +QNetworkProxyQuery (0x0x7f4465f253c0) 0 + +Class QNetworkProxy + size=8 align=8 + base size=8 base align=8 +QNetworkProxy (0x0x7f4465f6ba20) 0 + +Vtable for QNetworkProxyFactory +QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QNetworkProxyFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNetworkProxyFactory + size=8 align=8 + base size=8 base align=8 +QNetworkProxyFactory (0x0x7f4465fbd3c0) 0 nearly-empty + vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16) + +Class QNetworkReply::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkReply::QPrivateSignal (0x0x7f4465fbd600) 0 empty + +Vtable for QNetworkReply +QNetworkReply::_ZTV13QNetworkReply: 37 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QNetworkReply) +16 (int (*)(...))QNetworkReply::metaObject +24 (int (*)(...))QNetworkReply::qt_metacast +32 (int (*)(...))QNetworkReply::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkReply::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QNetworkReply::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QIODevice::skipData +240 (int (*)(...))QNetworkReply::writeData +248 (int (*)(...))QNetworkReply::setReadBufferSize +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))QNetworkReply::ignoreSslErrors +272 (int (*)(...))QNetworkReply::sslConfigurationImplementation +280 (int (*)(...))QNetworkReply::setSslConfigurationImplementation +288 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation + +Class QNetworkReply + size=16 align=8 + base size=16 base align=8 +QNetworkReply (0x0x7f4465fb67b8) 0 + vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16) + QIODevice (0x0x7f4465fbf1c0) 0 + primary-for QNetworkReply (0x0x7f4465fb67b8) + QObject (0x0x7f4465fbd540) 0 + primary-for QIODevice (0x0x7f4465fbf1c0) + QIODeviceBase (0x0x7f4465fbd5a0) 0 empty + +Class QOcspResponse + size=8 align=8 + base size=8 base align=8 +QOcspResponse (0x0x7f4465fbd960) 0 + +Class QTcpServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpServer::QPrivateSignal (0x0x7f4466017480) 0 empty + +Vtable for QTcpServer +QTcpServer::_ZTV10QTcpServer: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpServer) +16 (int (*)(...))QTcpServer::metaObject +24 (int (*)(...))QTcpServer::qt_metacast +32 (int (*)(...))QTcpServer::qt_metacall +40 (int (*)(...))QTcpServer::~QTcpServer +48 (int (*)(...))QTcpServer::~QTcpServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTcpServer::hasPendingConnections +120 (int (*)(...))QTcpServer::nextPendingConnection +128 (int (*)(...))QTcpServer::incomingConnection + +Class QTcpServer + size=16 align=8 + base size=16 base align=8 +QTcpServer (0x0x7f44660153a8) 0 + vptr=((& QTcpServer::_ZTV10QTcpServer) + 16) + QObject (0x0x7f4466017420) 0 + primary-for QTcpServer (0x0x7f44660153a8) + +Class QSslCertificateExtension + size=8 align=8 + base size=8 base align=8 +QSslCertificateExtension (0x0x7f4466017600) 0 + +Class QSslCipher + size=8 align=8 + base size=8 base align=8 +QSslCipher (0x0x7f4466054d20) 0 + +Class QSslDiffieHellmanParameters + size=8 align=8 + base size=8 base align=8 +QSslDiffieHellmanParameters (0x0x7f446609e360) 0 + +Class QSslEllipticCurve + size=4 align=4 + base size=4 base align=4 +QSslEllipticCurve (0x0x7f4465ce6060) 0 + +Class QSslKey + size=8 align=8 + base size=8 base align=8 +QSslKey (0x0x7f4465cfbea0) 0 + +Class QUdpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUdpSocket::QPrivateSignal (0x0x7f4465d4a600) 0 empty + +Vtable for QUdpSocket +QUdpSocket::_ZTV10QUdpSocket: 42 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUdpSocket) +16 (int (*)(...))QUdpSocket::metaObject +24 (int (*)(...))QUdpSocket::qt_metacast +32 (int (*)(...))QUdpSocket::qt_metacall +40 (int (*)(...))QUdpSocket::~QUdpSocket +48 (int (*)(...))QUdpSocket::~QUdpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::skipData +240 (int (*)(...))QAbstractSocket::writeData +248 (int (*)(...))QAbstractSocket::resume +256 (int (*)(...))QAbstractSocket::bind +264 (int (*)(...))QAbstractSocket::connectToHost +272 (int (*)(...))QAbstractSocket::disconnectFromHost +280 (int (*)(...))QAbstractSocket::setReadBufferSize +288 (int (*)(...))QAbstractSocket::socketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketDescriptor +304 (int (*)(...))QAbstractSocket::setSocketOption +312 (int (*)(...))QAbstractSocket::socketOption +320 (int (*)(...))QAbstractSocket::waitForConnected +328 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QUdpSocket + size=16 align=8 + base size=16 base align=8 +QUdpSocket (0x0x7f4465d42ea0) 0 + vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16) + QAbstractSocket (0x0x7f4465d42f08) 0 + primary-for QUdpSocket (0x0x7f4465d42ea0) + QIODevice (0x0x7f4465ccaaf0) 0 + primary-for QAbstractSocket (0x0x7f4465d42f08) + QObject (0x0x7f4465d4a540) 0 + primary-for QIODevice (0x0x7f4465ccaaf0) + QIODeviceBase (0x0x7f4465d4a5a0) 0 empty + +Class QJSValue + size=8 align=8 + base size=8 base align=8 +QJSValue (0x0x7f4465d4a7e0) 0 + +Class QQmlDebuggingEnabler + size=1 align=1 + base size=0 base align=1 +QQmlDebuggingEnabler (0x0x7f4465d8f9c0) 0 empty + +Class QJSEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QJSEngine::QPrivateSignal (0x0x7f4465d8fc60) 0 empty + +Vtable for QJSEngine +QJSEngine::_ZTV9QJSEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QJSEngine) +16 (int (*)(...))QJSEngine::metaObject +24 (int (*)(...))QJSEngine::qt_metacast +32 (int (*)(...))QJSEngine::qt_metacall +40 (int (*)(...))QJSEngine::~QJSEngine +48 (int (*)(...))QJSEngine::~QJSEngine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QJSEngine + size=24 align=8 + base size=24 base align=8 +QJSEngine (0x0x7f4465d73750) 0 + vptr=((& QJSEngine::_ZTV9QJSEngine) + 16) + QObject (0x0x7f4465d8fc00) 0 + primary-for QJSEngine (0x0x7f4465d73750) + +Class QJSValueIterator + size=8 align=8 + base size=8 base align=8 +QJSValueIterator (0x0x7f4465dcc300) 0 + +Vtable for QQmlParserStatus +QQmlParserStatus::_ZTV16QQmlParserStatus: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlParserStatus) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlParserStatus + size=16 align=8 + base size=16 base align=8 +QQmlParserStatus (0x0x7f4465dcc4e0) 0 + vptr=((& QQmlParserStatus::_ZTV16QQmlParserStatus) + 16) + +Class QQmlListReference + size=8 align=8 + base size=8 base align=8 +QQmlListReference (0x0x7f4465dfc000) 0 + +Vtable for QQmlPropertyValueSource +QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQmlPropertyValueSource) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlPropertyValueSource + size=8 align=8 + base size=8 base align=8 +QQmlPropertyValueSource (0x0x7f4465dfc1e0) 0 nearly-empty + vptr=((& QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource) + 16) + +Class QQmlPrivate::RegisterType + size=176 align=8 + base size=170 base align=8 +QQmlPrivate::RegisterType (0x0x7f4465e21960) 0 + +Class QQmlPrivate::RegisterTypeAndRevisions + size=152 align=8 + base size=152 base align=8 +QQmlPrivate::RegisterTypeAndRevisions (0x0x7f4465e219c0) 0 + +Class QQmlPrivate::RegisterInterface + size=48 align=8 + base size=42 base align=8 +QQmlPrivate::RegisterInterface (0x0x7f4465e21a20) 0 + +Class QQmlPrivate::RegisterAutoParent + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterAutoParent (0x0x7f4465e21a80) 0 + +Class QQmlPrivate::RegisterSingletonType + size=136 align=8 + base size=130 base align=8 +QQmlPrivate::RegisterSingletonType (0x0x7f4465e21ae0) 0 + +Class QQmlPrivate::RegisterSingletonTypeAndRevisions + size=104 align=8 + base size=104 base align=8 +QQmlPrivate::RegisterSingletonTypeAndRevisions (0x0x7f4465e21e40) 0 + +Class QQmlPrivate::RegisterCompositeType + size=40 align=8 + base size=40 base align=8 +QQmlPrivate::RegisterCompositeType (0x0x7f4465e21f00) 0 + +Class QQmlPrivate::RegisterCompositeSingletonType + size=40 align=8 + base size=40 base align=8 +QQmlPrivate::RegisterCompositeSingletonType (0x0x7f4465e21f60) 0 + +Class QQmlPrivate::RegisterSequentialContainer + size=56 align=8 + base size=50 base align=8 +QQmlPrivate::RegisterSequentialContainer (0x0x7f4465e52000) 0 + +Class QQmlPrivate::RegisterSequentialContainerAndRevisions + size=56 align=8 + base size=56 base align=8 +QQmlPrivate::RegisterSequentialContainerAndRevisions (0x0x7f4465e52060) 0 + +Class QQmlPrivate::AOTCompiledFunction + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::AOTCompiledFunction (0x0x7f4465e520c0) 0 + +Class QQmlPrivate::CachedQmlUnit + size=24 align=8 + base size=24 base align=8 +QQmlPrivate::CachedQmlUnit (0x0x7f4465e52120) 0 + +Class QQmlPrivate::RegisterQmlUnitCacheHook + size=16 align=8 + base size=16 base align=8 +QQmlPrivate::RegisterQmlUnitCacheHook (0x0x7f4465e52180) 0 + +Class QQmlPrivate::SingletonFunctor + size=24 align=8 + base size=17 base align=8 +QQmlPrivate::SingletonFunctor (0x0x7f4465e521e0) 0 + +Vtable for QQmlAbstractUrlInterceptor +QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QQmlAbstractUrlInterceptor) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlAbstractUrlInterceptor + size=8 align=8 + base size=8 base align=8 +QQmlAbstractUrlInterceptor (0x0x7f4465b03180) 0 nearly-empty + vptr=((& QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor) + 16) + +Class QQmlError + size=8 align=8 + base size=8 base align=8 +QQmlError (0x0x7f4465b031e0) 0 + +Class QQmlImageProviderBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlImageProviderBase::QPrivateSignal (0x0x7f4465b1da20) 0 empty + +Vtable for QQmlImageProviderBase +QQmlImageProviderBase::_ZTV21QQmlImageProviderBase: 16 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlImageProviderBase) +16 (int (*)(...))QQmlImageProviderBase::metaObject +24 (int (*)(...))QQmlImageProviderBase::qt_metacast +32 (int (*)(...))QQmlImageProviderBase::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QQmlImageProviderBase + size=16 align=8 + base size=16 base align=8 +QQmlImageProviderBase (0x0x7f4465b24270) 0 + vptr=((& QQmlImageProviderBase::_ZTV21QQmlImageProviderBase) + 16) + QObject (0x0x7f4465b1d9c0) 0 + primary-for QQmlImageProviderBase (0x0x7f4465b24270) + +Class QQmlEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngine::QPrivateSignal (0x0x7f4465b1de40) 0 empty + +Vtable for QQmlEngine +QQmlEngine::_ZTV10QQmlEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQmlEngine) +16 (int (*)(...))QQmlEngine::metaObject +24 (int (*)(...))QQmlEngine::qt_metacast +32 (int (*)(...))QQmlEngine::qt_metacall +40 (int (*)(...))QQmlEngine::~QQmlEngine +48 (int (*)(...))QQmlEngine::~QQmlEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlEngine + size=24 align=8 + base size=24 base align=8 +QQmlEngine (0x0x7f4465b24410) 0 + vptr=((& QQmlEngine::_ZTV10QQmlEngine) + 16) + QJSEngine (0x0x7f4465b24478) 0 + primary-for QQmlEngine (0x0x7f4465b24410) + QObject (0x0x7f4465b1dde0) 0 + primary-for QJSEngine (0x0x7f4465b24478) + +Class QQmlApplicationEngine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlApplicationEngine::QPrivateSignal (0x0x7f4465b51180) 0 empty + +Vtable for QQmlApplicationEngine +QQmlApplicationEngine::_ZTV21QQmlApplicationEngine: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QQmlApplicationEngine) +16 (int (*)(...))QQmlApplicationEngine::metaObject +24 (int (*)(...))QQmlApplicationEngine::qt_metacast +32 (int (*)(...))QQmlApplicationEngine::qt_metacall +40 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +48 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine +56 (int (*)(...))QQmlEngine::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlApplicationEngine + size=24 align=8 + base size=24 base align=8 +QQmlApplicationEngine (0x0x7f4465b244e0) 0 + vptr=((& QQmlApplicationEngine::_ZTV21QQmlApplicationEngine) + 16) + QQmlEngine (0x0x7f4465b24548) 0 + primary-for QQmlApplicationEngine (0x0x7f4465b244e0) + QJSEngine (0x0x7f4465b245b0) 0 + primary-for QQmlEngine (0x0x7f4465b24548) + QObject (0x0x7f4465b51120) 0 + primary-for QJSEngine (0x0x7f4465b245b0) + +Class QQmlComponent::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlComponent::QPrivateSignal (0x0x7f4465b51360) 0 empty + +Vtable for QQmlComponent +QQmlComponent::_ZTV13QQmlComponent: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlComponent) +16 (int (*)(...))QQmlComponent::metaObject +24 (int (*)(...))QQmlComponent::qt_metacast +32 (int (*)(...))QQmlComponent::qt_metacall +40 (int (*)(...))QQmlComponent::~QQmlComponent +48 (int (*)(...))QQmlComponent::~QQmlComponent +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlComponent::create +120 (int (*)(...))QQmlComponent::beginCreate +128 (int (*)(...))QQmlComponent::completeCreate + +Class QQmlComponent + size=16 align=8 + base size=16 base align=8 +QQmlComponent (0x0x7f4465b24618) 0 + vptr=((& QQmlComponent::_ZTV13QQmlComponent) + 16) + QObject (0x0x7f4465b51300) 0 + primary-for QQmlComponent (0x0x7f4465b24618) + +Class QQmlContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlContext::QPrivateSignal (0x0x7f4465b519c0) 0 empty + +Class QQmlContext::PropertyPair + size=56 align=8 + base size=56 base align=8 +QQmlContext::PropertyPair (0x0x7f4465b51a20) 0 + +Vtable for QQmlContext +QQmlContext::_ZTV11QQmlContext: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QQmlContext) +16 (int (*)(...))QQmlContext::metaObject +24 (int (*)(...))QQmlContext::qt_metacast +32 (int (*)(...))QQmlContext::qt_metacall +40 (int (*)(...))QQmlContext::~QQmlContext +48 (int (*)(...))QQmlContext::~QQmlContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlContext + size=16 align=8 + base size=16 base align=8 +QQmlContext (0x0x7f4465b24680) 0 + vptr=((& QQmlContext::_ZTV11QQmlContext) + 16) + QObject (0x0x7f4465b51960) 0 + primary-for QQmlContext (0x0x7f4465b24680) + +Class QQmlScriptString + size=8 align=8 + base size=8 base align=8 +QQmlScriptString (0x0x7f4465b51cc0) 0 + +Class QQmlExpression::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExpression::QPrivateSignal (0x0x7f4465b51f00) 0 empty + +Vtable for QQmlExpression +QQmlExpression::_ZTV14QQmlExpression: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QQmlExpression) +16 (int (*)(...))QQmlExpression::metaObject +24 (int (*)(...))QQmlExpression::qt_metacast +32 (int (*)(...))QQmlExpression::qt_metacall +40 (int (*)(...))QQmlExpression::~QQmlExpression +48 (int (*)(...))QQmlExpression::~QQmlExpression +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlExpression + size=16 align=8 + base size=16 base align=8 +QQmlExpression (0x0x7f4465b246e8) 0 + vptr=((& QQmlExpression::_ZTV14QQmlExpression) + 16) + QObject (0x0x7f4465b51ea0) 0 + primary-for QQmlExpression (0x0x7f4465b246e8) + +Vtable for QQmlTypesExtensionInterface +QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QQmlTypesExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlTypesExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlTypesExtensionInterface (0x0x7f4465ba50c0) 0 nearly-empty + vptr=((& QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface) + 16) + +Vtable for QQmlExtensionInterface +QQmlExtensionInterface::_ZTV22QQmlExtensionInterface: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QQmlExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QQmlExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlExtensionInterface (0x0x7f4465b24750) 0 nearly-empty + vptr=((& QQmlExtensionInterface::_ZTV22QQmlExtensionInterface) + 16) + QQmlTypesExtensionInterface (0x0x7f4465ba5120) 0 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f4465b24750) + +Vtable for QQmlEngineExtensionInterface +QQmlEngineExtensionInterface::_ZTV28QQmlEngineExtensionInterface: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QQmlEngineExtensionInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlEngineExtensionInterface + size=8 align=8 + base size=8 base align=8 +QQmlEngineExtensionInterface (0x0x7f4465ba5180) 0 nearly-empty + vptr=((& QQmlEngineExtensionInterface::_ZTV28QQmlEngineExtensionInterface) + 16) + +Class QQmlExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlExtensionPlugin::QPrivateSignal (0x0x7f4465ba5720) 0 empty + +Vtable for QQmlExtensionPlugin +QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +16 (int (*)(...))QQmlExtensionPlugin::metaObject +24 (int (*)(...))QQmlExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlExtensionPlugin::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQmlExtensionPlugin::unregisterTypes +128 (int (*)(...))QQmlExtensionPlugin::initializeEngine +136 (int (*)(...))-16 +144 (int (*)(...))(& _ZTI19QQmlExtensionPlugin) +152 0 +160 0 +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))QQmlExtensionPlugin::_ZThn16_N19QQmlExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlExtensionPlugin (0x0x7f4465b98070) 0 + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 16) + QObject (0x0x7f4465ba5660) 0 + primary-for QQmlExtensionPlugin (0x0x7f4465b98070) + QQmlExtensionInterface (0x0x7f4465b247b8) 16 nearly-empty + vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 152) + QQmlTypesExtensionInterface (0x0x7f4465ba56c0) 16 nearly-empty + primary-for QQmlExtensionInterface (0x0x7f4465b247b8) + +Class QQmlEngineExtensionPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlEngineExtensionPlugin::QPrivateSignal (0x0x7f4465ba5960) 0 empty + +Vtable for QQmlEngineExtensionPlugin +QQmlEngineExtensionPlugin::_ZTV25QQmlEngineExtensionPlugin: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QQmlEngineExtensionPlugin) +16 (int (*)(...))QQmlEngineExtensionPlugin::metaObject +24 (int (*)(...))QQmlEngineExtensionPlugin::qt_metacast +32 (int (*)(...))QQmlEngineExtensionPlugin::qt_metacall +40 (int (*)(...))QQmlEngineExtensionPlugin::~QQmlEngineExtensionPlugin +48 (int (*)(...))QQmlEngineExtensionPlugin::~QQmlEngineExtensionPlugin +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlEngineExtensionPlugin::initializeEngine +120 (int (*)(...))-16 +128 (int (*)(...))(& _ZTI25QQmlEngineExtensionPlugin) +136 (int (*)(...))QQmlEngineExtensionPlugin::_ZThn16_N25QQmlEngineExtensionPluginD1Ev +144 (int (*)(...))QQmlEngineExtensionPlugin::_ZThn16_N25QQmlEngineExtensionPluginD0Ev +152 (int (*)(...))QQmlEngineExtensionPlugin::_ZThn16_N25QQmlEngineExtensionPlugin16initializeEngineEP10QQmlEnginePKc + +Class QQmlEngineExtensionPlugin + size=24 align=8 + base size=24 base align=8 +QQmlEngineExtensionPlugin (0x0x7f4465b980e0) 0 + vptr=((& QQmlEngineExtensionPlugin::_ZTV25QQmlEngineExtensionPlugin) + 16) + QObject (0x0x7f4465ba58a0) 0 + primary-for QQmlEngineExtensionPlugin (0x0x7f4465b980e0) + QQmlEngineExtensionInterface (0x0x7f4465ba5900) 16 nearly-empty + vptr=((& QQmlEngineExtensionPlugin::_ZTV25QQmlEngineExtensionPlugin) + 136) + +Class QQmlFile + size=8 align=8 + base size=8 base align=8 +QQmlFile (0x0x7f4465ba5a20) 0 + +Class QQmlFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlFileSelector::QPrivateSignal (0x0x7f4465ba5ae0) 0 empty + +Vtable for QQmlFileSelector +QQmlFileSelector::_ZTV16QQmlFileSelector: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QQmlFileSelector) +16 (int (*)(...))QQmlFileSelector::metaObject +24 (int (*)(...))QQmlFileSelector::qt_metacast +32 (int (*)(...))QQmlFileSelector::qt_metacall +40 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +48 (int (*)(...))QQmlFileSelector::~QQmlFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQmlFileSelector + size=16 align=8 + base size=16 base align=8 +QQmlFileSelector (0x0x7f4465b24888) 0 + vptr=((& QQmlFileSelector::_ZTV16QQmlFileSelector) + 16) + QObject (0x0x7f4465ba5a80) 0 + primary-for QQmlFileSelector (0x0x7f4465b24888) + +Vtable for QQmlIncubator +QQmlIncubator::_ZTV13QQmlIncubator: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QQmlIncubator) +16 (int (*)(...))QQmlIncubator::~QQmlIncubator +24 (int (*)(...))QQmlIncubator::~QQmlIncubator +32 (int (*)(...))QQmlIncubator::statusChanged +40 (int (*)(...))QQmlIncubator::setInitialState + +Class QQmlIncubator + size=16 align=8 + base size=16 base align=8 +QQmlIncubator (0x0x7f4465ba5c60) 0 + vptr=((& QQmlIncubator::_ZTV13QQmlIncubator) + 16) + +Vtable for QQmlIncubationController +QQmlIncubationController::_ZTV24QQmlIncubationController: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQmlIncubationController) +16 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +24 (int (*)(...))QQmlIncubationController::~QQmlIncubationController +32 (int (*)(...))QQmlIncubationController::incubatingObjectCountChanged + +Class QQmlIncubationController + size=16 align=8 + base size=16 base align=8 +QQmlIncubationController (0x0x7f4465ba5cc0) 0 + vptr=((& QQmlIncubationController::_ZTV24QQmlIncubationController) + 16) + +Class QQmlInfo + size=16 align=8 + base size=16 base align=8 +QQmlInfo (0x0x7f4465b248f0) 0 + QDebug (0x0x7f4465b24958) 0 + QIODeviceBase (0x0x7f4465ba5d20) 0 empty + +Class QQmlModuleRegistration + size=8 align=8 + base size=8 base align=8 +QQmlModuleRegistration (0x0x7f4465c33420) 0 + +Vtable for QQmlNetworkAccessManagerFactory +QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI31QQmlNetworkAccessManagerFactory) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QQmlNetworkAccessManagerFactory + size=8 align=8 + base size=8 base align=8 +QQmlNetworkAccessManagerFactory (0x0x7f4465c33480) 0 nearly-empty + vptr=((& QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory) + 16) + +Class QQmlProperty + size=8 align=8 + base size=8 base align=8 +QQmlProperty (0x0x7f4465c334e0) 0 + +Class QQmlPropertyMap::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQmlPropertyMap::QPrivateSignal (0x0x7f4465c6f720) 0 empty + +Vtable for QQmlPropertyMap +QQmlPropertyMap::_ZTV15QQmlPropertyMap: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQmlPropertyMap) +16 (int (*)(...))QQmlPropertyMap::metaObject +24 (int (*)(...))QQmlPropertyMap::qt_metacast +32 (int (*)(...))QQmlPropertyMap::qt_metacall +40 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +48 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQmlPropertyMap::updateValue + +Class QQmlPropertyMap + size=16 align=8 + base size=16 base align=8 +QQmlPropertyMap (0x0x7f4465c6ae38) 0 + vptr=((& QQmlPropertyMap::_ZTV15QQmlPropertyMap) + 16) + QObject (0x0x7f4465c6f6c0) 0 + primary-for QQmlPropertyMap (0x0x7f4465c6ae38) + +Class QOpenGLBuffer + size=8 align=8 + base size=8 base align=8 +QOpenGLBuffer (0x0x7f4465c6f900) 0 + +Class QOpenGLDebugMessage + size=8 align=8 + base size=8 base align=8 +QOpenGLDebugMessage (0x0x7f4465c6fd80) 0 + +Class QOpenGLDebugLogger::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLDebugLogger::QPrivateSignal (0x0x7f44658f8d80) 0 empty + +Vtable for QOpenGLDebugLogger +QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger) +16 (int (*)(...))QOpenGLDebugLogger::metaObject +24 (int (*)(...))QOpenGLDebugLogger::qt_metacast +32 (int (*)(...))QOpenGLDebugLogger::qt_metacall +40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLDebugLogger + size=16 align=8 + base size=16 base align=8 +QOpenGLDebugLogger (0x0x7f44658fe3a8) 0 + vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16) + QObject (0x0x7f44658f8d20) 0 + primary-for QOpenGLDebugLogger (0x0x7f44658fe3a8) + +Vtable for QOpenGLFramebufferObject +QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject) +16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject +24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject + +Class QOpenGLFramebufferObject + size=16 align=8 + base size=16 base align=8 +QOpenGLFramebufferObject (0x0x7f4465964120) 0 + vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16) + +Class QOpenGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QOpenGLFramebufferObjectFormat (0x0x7f44659643c0) 0 + +Vtable for QOpenGLPaintDevice +QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice) +16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +32 (int (*)(...))QOpenGLPaintDevice::devType +40 (int (*)(...))QOpenGLPaintDevice::paintEngine +48 (int (*)(...))QOpenGLPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget + +Class QOpenGLPaintDevice + size=24 align=8 + base size=24 base align=8 +QOpenGLPaintDevice (0x0x7f44658fe410) 0 + vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16) + QPaintDevice (0x0x7f4465964420) 0 + primary-for QOpenGLPaintDevice (0x0x7f44658fe410) + +Class QOpenGLPixelTransferOptions + size=8 align=8 + base size=8 base align=8 +QOpenGLPixelTransferOptions (0x0x7f4465964660) 0 + +Class QOpenGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShader::QPrivateSignal (0x0x7f44659b5d20) 0 empty + +Vtable for QOpenGLShader +QOpenGLShader::_ZTV13QOpenGLShader: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLShader) +16 (int (*)(...))QOpenGLShader::metaObject +24 (int (*)(...))QOpenGLShader::qt_metacast +32 (int (*)(...))QOpenGLShader::qt_metacall +40 (int (*)(...))QOpenGLShader::~QOpenGLShader +48 (int (*)(...))QOpenGLShader::~QOpenGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLShader + size=16 align=8 + base size=16 base align=8 +QOpenGLShader (0x0x7f44659bcdd0) 0 + vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16) + QObject (0x0x7f44659b5cc0) 0 + primary-for QOpenGLShader (0x0x7f44659bcdd0) + +Class QOpenGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShaderProgram::QPrivateSignal (0x0x7f44659d8240) 0 empty + +Vtable for QOpenGLShaderProgram +QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram) +16 (int (*)(...))QOpenGLShaderProgram::metaObject +24 (int (*)(...))QOpenGLShaderProgram::qt_metacast +32 (int (*)(...))QOpenGLShaderProgram::qt_metacall +40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOpenGLShaderProgram::link + +Class QOpenGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QOpenGLShaderProgram (0x0x7f44659bcf70) 0 + vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16) + QObject (0x0x7f44659d81e0) 0 + primary-for QOpenGLShaderProgram (0x0x7f44659bcf70) + +Class QOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QOpenGLTexture (0x0x7f44659d83c0) 0 + +Class QOpenGLTextureBlitter + size=8 align=8 + base size=8 base align=8 +QOpenGLTextureBlitter (0x0x7f4465a7e4e0) 0 + +Class QOpenGLTimerQuery::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimerQuery::QPrivateSignal (0x0x7f4465a7e720) 0 empty + +Vtable for QOpenGLTimerQuery +QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery) +16 (int (*)(...))QOpenGLTimerQuery::metaObject +24 (int (*)(...))QOpenGLTimerQuery::qt_metacast +32 (int (*)(...))QOpenGLTimerQuery::qt_metacall +40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimerQuery + size=16 align=8 + base size=16 base align=8 +QOpenGLTimerQuery (0x0x7f4465a82138) 0 + vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16) + QObject (0x0x7f4465a7e6c0) 0 + primary-for QOpenGLTimerQuery (0x0x7f4465a82138) + +Class QOpenGLTimeMonitor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimeMonitor::QPrivateSignal (0x0x7f4465a7e900) 0 empty + +Vtable for QOpenGLTimeMonitor +QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor) +16 (int (*)(...))QOpenGLTimeMonitor::metaObject +24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast +32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall +40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimeMonitor + size=16 align=8 + base size=16 base align=8 +QOpenGLTimeMonitor (0x0x7f4465a821a0) 0 + vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16) + QObject (0x0x7f4465a7e8a0) 0 + primary-for QOpenGLTimeMonitor (0x0x7f4465a821a0) + +Class QOpenGLVersionStatus + size=12 align=4 + base size=12 base align=4 +QOpenGLVersionStatus (0x0x7f4465a7ea80) 0 + +Class QOpenGLVersionFunctionsBackend + size=16 align=8 + base size=12 base align=8 +QOpenGLVersionFunctionsBackend (0x0x7f4465732ae0) 0 + +Class QOpenGLVersionFunctionsStorage + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionFunctionsStorage (0x0x7f4465732cc0) 0 + +Class QAbstractOpenGLFunctionsPrivate + size=16 align=8 + base size=9 base align=8 +QAbstractOpenGLFunctionsPrivate (0x0x7f4465732d20) 0 + +Vtable for QAbstractOpenGLFunctions +QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions) +16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions + +Class QAbstractOpenGLFunctions + size=16 align=8 + base size=16 base align=8 +QAbstractOpenGLFunctions (0x0x7f4465732f00) 0 + vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16) + +Class QOpenGLFunctions_1_0_CoreBackend::Functions + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7f4465750120) 0 + +Class QOpenGLFunctions_1_0_CoreBackend + size=400 align=8 + base size=400 base align=8 +QOpenGLFunctions_1_0_CoreBackend (0x0x7f4465729a28) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44657500c0) 0 + +Class QOpenGLFunctions_1_1_CoreBackend::Functions + size=128 align=8 + base size=128 base align=8 +QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7f4465750480) 0 + +Class QOpenGLFunctions_1_1_CoreBackend + size=144 align=8 + base size=144 base align=8 +QOpenGLFunctions_1_1_CoreBackend (0x0x7f4465729a90) 0 + QOpenGLVersionFunctionsBackend (0x0x7f4465750420) 0 + +Class QOpenGLFunctions_1_2_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7f44657507e0) 0 + +Class QOpenGLFunctions_1_2_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_1_2_CoreBackend (0x0x7f4465729af8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f4465750780) 0 + +Class QOpenGLFunctions_1_3_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7f4465750b40) 0 + +Class QOpenGLFunctions_1_3_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_1_3_CoreBackend (0x0x7f4465729b60) 0 + QOpenGLVersionFunctionsBackend (0x0x7f4465750ae0) 0 + +Class QOpenGLFunctions_1_4_CoreBackend::Functions + size=56 align=8 + base size=56 base align=8 +QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7f4465750ea0) 0 + +Class QOpenGLFunctions_1_4_CoreBackend + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_4_CoreBackend (0x0x7f4465729bc8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f4465750e40) 0 + +Class QOpenGLFunctions_1_5_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7f4465775240) 0 + +Class QOpenGLFunctions_1_5_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_1_5_CoreBackend (0x0x7f4465729c30) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44657751e0) 0 + +Class QOpenGLFunctions_2_0_CoreBackend::Functions + size=744 align=8 + base size=744 base align=8 +QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7f44657755a0) 0 + +Class QOpenGLFunctions_2_0_CoreBackend + size=760 align=8 + base size=760 base align=8 +QOpenGLFunctions_2_0_CoreBackend (0x0x7f4465729c98) 0 + QOpenGLVersionFunctionsBackend (0x0x7f4465775540) 0 + +Class QOpenGLFunctions_2_1_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7f4465775900) 0 + +Class QOpenGLFunctions_2_1_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_2_1_CoreBackend (0x0x7f4465729d00) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44657758a0) 0 + +Class QOpenGLFunctions_3_0_CoreBackend::Functions + size=672 align=8 + base size=672 base align=8 +QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7f4465775c60) 0 + +Class QOpenGLFunctions_3_0_CoreBackend + size=688 align=8 + base size=688 base align=8 +QOpenGLFunctions_3_0_CoreBackend (0x0x7f4465729d68) 0 + QOpenGLVersionFunctionsBackend (0x0x7f4465775c00) 0 + +Class QOpenGLFunctions_3_1_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7f44657a4000) 0 + +Class QOpenGLFunctions_3_1_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_3_1_CoreBackend (0x0x7f4465729dd0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f4465775f60) 0 + +Class QOpenGLFunctions_3_2_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7f44657a4360) 0 + +Class QOpenGLFunctions_3_2_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_3_2_CoreBackend (0x0x7f4465729e38) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44657a4300) 0 + +Class QOpenGLFunctions_3_3_CoreBackend::Functions + size=464 align=8 + base size=464 base align=8 +QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7f44657a46c0) 0 + +Class QOpenGLFunctions_3_3_CoreBackend + size=480 align=8 + base size=480 base align=8 +QOpenGLFunctions_3_3_CoreBackend (0x0x7f4465729ea0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44657a4660) 0 + +Class QOpenGLFunctions_4_0_CoreBackend::Functions + size=368 align=8 + base size=368 base align=8 +QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7f44657a4a20) 0 + +Class QOpenGLFunctions_4_0_CoreBackend + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_4_0_CoreBackend (0x0x7f4465729f08) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44657a49c0) 0 + +Class QOpenGLFunctions_4_1_CoreBackend::Functions + size=704 align=8 + base size=704 base align=8 +QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7f44657a4d80) 0 + +Class QOpenGLFunctions_4_1_CoreBackend + size=720 align=8 + base size=720 base align=8 +QOpenGLFunctions_4_1_CoreBackend (0x0x7f4465729f70) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44657a4d20) 0 + +Class QOpenGLFunctions_4_2_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7f44657dd120) 0 + +Class QOpenGLFunctions_4_2_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_2_CoreBackend (0x0x7f44657de000) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44657dd0c0) 0 + +Class QOpenGLFunctions_4_3_CoreBackend::Functions + size=344 align=8 + base size=344 base align=8 +QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7f44657dd480) 0 + +Class QOpenGLFunctions_4_3_CoreBackend + size=360 align=8 + base size=360 base align=8 +QOpenGLFunctions_4_3_CoreBackend (0x0x7f44657de068) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44657dd420) 0 + +Class QOpenGLFunctions_4_4_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7f44657dd7e0) 0 + +Class QOpenGLFunctions_4_4_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_4_4_CoreBackend (0x0x7f44657de0d0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44657dd780) 0 + +Class QOpenGLFunctions_4_5_CoreBackend::Functions + size=848 align=8 + base size=848 base align=8 +QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7f44657ddb40) 0 + +Class QOpenGLFunctions_4_5_CoreBackend + size=864 align=8 + base size=864 base align=8 +QOpenGLFunctions_4_5_CoreBackend (0x0x7f44657de138) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44657ddae0) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions + size=2064 align=8 + base size=2064 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7f44657ddea0) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend + size=2080 align=8 + base size=2080 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7f44657de1a0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44657dde40) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions + size=136 align=8 + base size=136 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7f4465834240) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7f44657de208) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44658341e0) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7f44658345a0) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend + size=272 align=8 + base size=272 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7f44657de270) 0 + QOpenGLVersionFunctionsBackend (0x0x7f4465834540) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions + size=296 align=8 + base size=296 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7f4465834900) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend + size=312 align=8 + base size=312 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7f44657de2d8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f44658348a0) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7f4465834c60) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend + size=320 align=8 + base size=320 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7f44657de340) 0 + QOpenGLVersionFunctionsBackend (0x0x7f4465834c00) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions + size=288 align=8 + base size=288 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7f446585a000) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7f44657de3a8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f4465834f60) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions + size=160 align=8 + base size=160 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7f446585a360) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend + size=176 align=8 + base size=176 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7f44657de410) 0 + QOpenGLVersionFunctionsBackend (0x0x7f446585a300) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions + size=240 align=8 + base size=240 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7f446585a6c0) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7f44657de478) 0 + QOpenGLVersionFunctionsBackend (0x0x7f446585a660) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7f446585aa20) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7f44657de4e0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f446585a9c0) 0 + +Class QOpenGLVersionProfile + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionProfile (0x0x7f446585ad20) 0 + +Class QOpenGLVersionFunctionsFactory + size=1 align=1 + base size=0 base align=1 +QOpenGLVersionFunctionsFactory (0x0x7f446585aea0) 0 empty + +Class QOpenGLVertexArrayObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLVertexArrayObject::QPrivateSignal (0x0x7f4465880000) 0 empty + +Class QOpenGLVertexArrayObject::Binder + size=8 align=8 + base size=8 base align=8 +QOpenGLVertexArrayObject::Binder (0x0x7f4465880060) 0 + +Vtable for QOpenGLVertexArrayObject +QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject) +16 (int (*)(...))QOpenGLVertexArrayObject::metaObject +24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast +32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall +40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLVertexArrayObject + size=16 align=8 + base size=16 base align=8 +QOpenGLVertexArrayObject (0x0x7f44657de548) 0 + vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16) + QObject (0x0x7f446585af60) 0 + primary-for QOpenGLVertexArrayObject (0x0x7f44657de548) + +Class QOpenGLWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWindow::QPrivateSignal (0x0x7f44658806c0) 0 empty + +Vtable for QOpenGLWindow +QOpenGLWindow::_ZTV13QOpenGLWindow: 65 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWindow) +16 (int (*)(...))QOpenGLWindow::metaObject +24 (int (*)(...))QOpenGLWindow::qt_metacast +32 (int (*)(...))QOpenGLWindow::qt_metacall +40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QOpenGLWindow::resizeEvent +168 (int (*)(...))QOpenGLWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QWindow::focusInEvent +192 (int (*)(...))QWindow::focusOutEvent +200 (int (*)(...))QWindow::showEvent +208 (int (*)(...))QWindow::hideEvent +216 (int (*)(...))QWindow::closeEvent +224 (int (*)(...))QWindow::keyPressEvent +232 (int (*)(...))QWindow::keyReleaseEvent +240 (int (*)(...))QWindow::mousePressEvent +248 (int (*)(...))QWindow::mouseReleaseEvent +256 (int (*)(...))QWindow::mouseDoubleClickEvent +264 (int (*)(...))QWindow::mouseMoveEvent +272 (int (*)(...))QWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))QOpenGLWindow::metric +320 (int (*)(...))QPaintDeviceWindow::paintEngine +328 (int (*)(...))QOpenGLWindow::initializeGL +336 (int (*)(...))QOpenGLWindow::resizeGL +344 (int (*)(...))QOpenGLWindow::paintGL +352 (int (*)(...))QOpenGLWindow::paintUnderGL +360 (int (*)(...))QOpenGLWindow::paintOverGL +368 (int (*)(...))QOpenGLWindow::redirected +376 (int (*)(...))-16 +384 (int (*)(...))(& _ZTI13QOpenGLWindow) +392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev +400 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev +408 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +416 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +424 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +432 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +440 (int (*)(...))-40 +448 (int (*)(...))(& _ZTI13QOpenGLWindow) +456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev +464 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev +472 (int (*)(...))QPaintDevice::devType +480 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +488 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QPaintDevice::initPainter +504 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint +512 (int (*)(...))QPaintDevice::sharedPainter + +Class QOpenGLWindow + size=56 align=8 + base size=50 base align=8 +QOpenGLWindow (0x0x7f44657de618) 0 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16) + QPaintDeviceWindow (0x0x7f4465744540) 0 + primary-for QOpenGLWindow (0x0x7f44657de618) + QWindow (0x0x7f44657445b0) 0 + primary-for QPaintDeviceWindow (0x0x7f4465744540) + QObject (0x0x7f44658805a0) 0 + primary-for QWindow (0x0x7f44657445b0) + QSurface (0x0x7f4465880600) 16 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 392) + QPaintDevice (0x0x7f4465880660) 40 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 456) + +Class QQuickTransform::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTransform::QPrivateSignal (0x0x7f44658808a0) 0 empty + +Vtable for QQuickTransform +QQuickTransform::_ZTV15QQuickTransform: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QQuickTransform) +16 (int (*)(...))QQuickTransform::metaObject +24 (int (*)(...))QQuickTransform::qt_metacast +32 (int (*)(...))QQuickTransform::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QQuickTransform + size=16 align=8 + base size=16 base align=8 +QQuickTransform (0x0x7f44657de6e8) 0 + vptr=((& QQuickTransform::_ZTV15QQuickTransform) + 16) + QObject (0x0x7f4465880840) 0 + primary-for QQuickTransform (0x0x7f44657de6e8) + +Class QQuickItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItem::QPrivateSignal (0x0x7f4465880ae0) 0 empty + +Class QQuickItem::ItemChangeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::ItemChangeData (0x0x7f4465880b40) 0 + +Class QQuickItem::UpdatePaintNodeData + size=8 align=8 + base size=8 base align=8 +QQuickItem::UpdatePaintNodeData (0x0x7f4465880ba0) 0 + +Vtable for QQuickItem +QQuickItem::_ZTV10QQuickItem: 54 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickItem) +16 (int (*)(...))QQuickItem::metaObject +24 (int (*)(...))QQuickItem::qt_metacast +32 (int (*)(...))QQuickItem::qt_metacall +40 (int (*)(...))QQuickItem::~QQuickItem +48 (int (*)(...))QQuickItem::~QQuickItem +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickItem::isTextureProvider +152 (int (*)(...))QQuickItem::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickItem::geometryChange +176 (int (*)(...))QQuickItem::classBegin +184 (int (*)(...))QQuickItem::componentComplete +192 (int (*)(...))QQuickItem::keyPressEvent +200 (int (*)(...))QQuickItem::keyReleaseEvent +208 (int (*)(...))QQuickItem::inputMethodEvent +216 (int (*)(...))QQuickItem::focusInEvent +224 (int (*)(...))QQuickItem::focusOutEvent +232 (int (*)(...))QQuickItem::mousePressEvent +240 (int (*)(...))QQuickItem::mouseMoveEvent +248 (int (*)(...))QQuickItem::mouseReleaseEvent +256 (int (*)(...))QQuickItem::mouseDoubleClickEvent +264 (int (*)(...))QQuickItem::mouseUngrabEvent +272 (int (*)(...))QQuickItem::touchUngrabEvent +280 (int (*)(...))QQuickItem::wheelEvent +288 (int (*)(...))QQuickItem::touchEvent +296 (int (*)(...))QQuickItem::hoverEnterEvent +304 (int (*)(...))QQuickItem::hoverMoveEvent +312 (int (*)(...))QQuickItem::hoverLeaveEvent +320 (int (*)(...))QQuickItem::dragEnterEvent +328 (int (*)(...))QQuickItem::dragMoveEvent +336 (int (*)(...))QQuickItem::dragLeaveEvent +344 (int (*)(...))QQuickItem::dropEvent +352 (int (*)(...))QQuickItem::childMouseEventFilter +360 (int (*)(...))QQuickItem::updatePaintNode +368 (int (*)(...))QQuickItem::releaseResources +376 (int (*)(...))QQuickItem::updatePolish +384 (int (*)(...))-16 +392 (int (*)(...))(& _ZTI10QQuickItem) +400 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD1Ev +408 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD0Ev +416 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickItem + size=32 align=8 + base size=32 base align=8 +QQuickItem (0x0x7f4465744770) 0 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 16) + QObject (0x0x7f4465880a20) 0 + primary-for QQuickItem (0x0x7f4465744770) + QQmlParserStatus (0x0x7f4465880a80) 16 + vptr=((& QQuickItem::_ZTV10QQuickItem) + 400) + +Class QQuickFramebufferObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickFramebufferObject::QPrivateSignal (0x0x7f44654ecd20) 0 empty + +Vtable for QQuickFramebufferObject::Renderer +QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN23QQuickFramebufferObject8RendererE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QQuickFramebufferObject::Renderer::createFramebufferObject +48 (int (*)(...))QQuickFramebufferObject::Renderer::synchronize + +Class QQuickFramebufferObject::Renderer + size=16 align=8 + base size=16 base align=8 +QQuickFramebufferObject::Renderer (0x0x7f44654ecd80) 0 + vptr=((& QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE) + 16) + +Vtable for QQuickFramebufferObject +QQuickFramebufferObject::_ZTV23QQuickFramebufferObject: 55 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +16 (int (*)(...))QQuickFramebufferObject::metaObject +24 (int (*)(...))QQuickFramebufferObject::qt_metacast +32 (int (*)(...))QQuickFramebufferObject::qt_metacall +40 0 +48 0 +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickFramebufferObject::isTextureProvider +152 (int (*)(...))QQuickFramebufferObject::textureProvider +160 (int (*)(...))QQuickItem::itemChange +168 (int (*)(...))QQuickFramebufferObject::geometryChange +176 (int (*)(...))QQuickItem::classBegin +184 (int (*)(...))QQuickItem::componentComplete +192 (int (*)(...))QQuickItem::keyPressEvent +200 (int (*)(...))QQuickItem::keyReleaseEvent +208 (int (*)(...))QQuickItem::inputMethodEvent +216 (int (*)(...))QQuickItem::focusInEvent +224 (int (*)(...))QQuickItem::focusOutEvent +232 (int (*)(...))QQuickItem::mousePressEvent +240 (int (*)(...))QQuickItem::mouseMoveEvent +248 (int (*)(...))QQuickItem::mouseReleaseEvent +256 (int (*)(...))QQuickItem::mouseDoubleClickEvent +264 (int (*)(...))QQuickItem::mouseUngrabEvent +272 (int (*)(...))QQuickItem::touchUngrabEvent +280 (int (*)(...))QQuickItem::wheelEvent +288 (int (*)(...))QQuickItem::touchEvent +296 (int (*)(...))QQuickItem::hoverEnterEvent +304 (int (*)(...))QQuickItem::hoverMoveEvent +312 (int (*)(...))QQuickItem::hoverLeaveEvent +320 (int (*)(...))QQuickItem::dragEnterEvent +328 (int (*)(...))QQuickItem::dragMoveEvent +336 (int (*)(...))QQuickItem::dragLeaveEvent +344 (int (*)(...))QQuickItem::dropEvent +352 (int (*)(...))QQuickItem::childMouseEventFilter +360 (int (*)(...))QQuickFramebufferObject::updatePaintNode +368 (int (*)(...))QQuickFramebufferObject::releaseResources +376 (int (*)(...))QQuickItem::updatePolish +384 (int (*)(...))__cxa_pure_virtual +392 (int (*)(...))-16 +400 (int (*)(...))(& _ZTI23QQuickFramebufferObject) +408 0 +416 0 +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickFramebufferObject + size=32 align=8 + base size=32 base align=8 +QQuickFramebufferObject (0x0x7f44657de888) 0 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 16) + QQuickItem (0x0x7f44658b3700) 0 + primary-for QQuickFramebufferObject (0x0x7f44657de888) + QObject (0x0x7f44654ecc60) 0 + primary-for QQuickItem (0x0x7f44658b3700) + QQmlParserStatus (0x0x7f44654eccc0) 16 + vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 408) + +Class QQuickGraphicsConfiguration + size=8 align=8 + base size=8 base align=8 +QQuickGraphicsConfiguration (0x0x7f44654ecf00) 0 + +Class VkApplicationInfo + size=48 align=8 + base size=48 base align=8 +VkApplicationInfo (0x0x7f44654ecf60) 0 + +Class VkInstanceCreateInfo + size=64 align=8 + base size=64 base align=8 +VkInstanceCreateInfo (0x0x7f4465589000) 0 + +Class VkAllocationCallbacks + size=48 align=8 + base size=48 base align=8 +VkAllocationCallbacks (0x0x7f4465589060) 0 + +Class VkPhysicalDeviceFeatures + size=220 align=4 + base size=220 base align=4 +VkPhysicalDeviceFeatures (0x0x7f44655890c0) 0 + +Class VkFormatProperties + size=12 align=4 + base size=12 base align=4 +VkFormatProperties (0x0x7f4465589120) 0 + +Class VkExtent3D + size=12 align=4 + base size=12 base align=4 +VkExtent3D (0x0x7f4465589180) 0 + +Class VkImageFormatProperties + size=32 align=8 + base size=32 base align=8 +VkImageFormatProperties (0x0x7f44655891e0) 0 + +Class VkPhysicalDeviceLimits + size=504 align=8 + base size=504 base align=8 +VkPhysicalDeviceLimits (0x0x7f4465589240) 0 + +Class VkPhysicalDeviceSparseProperties + size=20 align=4 + base size=20 base align=4 +VkPhysicalDeviceSparseProperties (0x0x7f44655892a0) 0 + +Class VkPhysicalDeviceProperties + size=824 align=8 + base size=824 base align=8 +VkPhysicalDeviceProperties (0x0x7f4465589300) 0 + +Class VkQueueFamilyProperties + size=24 align=4 + base size=24 base align=4 +VkQueueFamilyProperties (0x0x7f4465589360) 0 + +Class VkMemoryType + size=8 align=4 + base size=8 base align=4 +VkMemoryType (0x0x7f44655893c0) 0 + +Class VkMemoryHeap + size=16 align=8 + base size=16 base align=8 +VkMemoryHeap (0x0x7f4465589420) 0 + +Class VkPhysicalDeviceMemoryProperties + size=520 align=8 + base size=520 base align=8 +VkPhysicalDeviceMemoryProperties (0x0x7f4465589480) 0 + +Class VkDeviceQueueCreateInfo + size=40 align=8 + base size=40 base align=8 +VkDeviceQueueCreateInfo (0x0x7f44655894e0) 0 + +Class VkDeviceCreateInfo + size=72 align=8 + base size=72 base align=8 +VkDeviceCreateInfo (0x0x7f4465589540) 0 + +Class VkExtensionProperties + size=260 align=4 + base size=260 base align=4 +VkExtensionProperties (0x0x7f4465589600) 0 + +Class VkLayerProperties + size=520 align=4 + base size=520 base align=4 +VkLayerProperties (0x0x7f4465589660) 0 + +Class VkSubmitInfo + size=72 align=8 + base size=72 base align=8 +VkSubmitInfo (0x0x7f44655896c0) 0 + +Class VkMemoryAllocateInfo + size=32 align=8 + base size=32 base align=8 +VkMemoryAllocateInfo (0x0x7f4465589720) 0 + +Class VkMappedMemoryRange + size=40 align=8 + base size=40 base align=8 +VkMappedMemoryRange (0x0x7f4465589780) 0 + +Class VkMemoryRequirements + size=24 align=8 + base size=24 base align=8 +VkMemoryRequirements (0x0x7f44655897e0) 0 + +Class VkSparseImageFormatProperties + size=20 align=4 + base size=20 base align=4 +VkSparseImageFormatProperties (0x0x7f4465589840) 0 + +Class VkSparseImageMemoryRequirements + size=48 align=8 + base size=48 base align=8 +VkSparseImageMemoryRequirements (0x0x7f44655898a0) 0 + +Class VkSparseMemoryBind + size=40 align=8 + base size=40 base align=8 +VkSparseMemoryBind (0x0x7f4465589900) 0 + +Class VkSparseBufferMemoryBindInfo + size=24 align=8 + base size=24 base align=8 +VkSparseBufferMemoryBindInfo (0x0x7f4465589960) 0 + +Class VkSparseImageOpaqueMemoryBindInfo + size=24 align=8 + base size=24 base align=8 +VkSparseImageOpaqueMemoryBindInfo (0x0x7f44655899c0) 0 + +Class VkImageSubresource + size=12 align=4 + base size=12 base align=4 +VkImageSubresource (0x0x7f4465589a20) 0 + +Class VkOffset3D + size=12 align=4 + base size=12 base align=4 +VkOffset3D (0x0x7f4465589a80) 0 + +Class VkSparseImageMemoryBind + size=64 align=8 + base size=64 base align=8 +VkSparseImageMemoryBind (0x0x7f4465589ae0) 0 + +Class VkSparseImageMemoryBindInfo + size=24 align=8 + base size=24 base align=8 +VkSparseImageMemoryBindInfo (0x0x7f4465589b40) 0 + +Class VkBindSparseInfo + size=96 align=8 + base size=96 base align=8 +VkBindSparseInfo (0x0x7f4465589ba0) 0 + +Class VkFenceCreateInfo + size=24 align=8 + base size=24 base align=8 +VkFenceCreateInfo (0x0x7f4465589c00) 0 + +Class VkSemaphoreCreateInfo + size=24 align=8 + base size=24 base align=8 +VkSemaphoreCreateInfo (0x0x7f4465589c60) 0 + +Class VkEventCreateInfo + size=24 align=8 + base size=24 base align=8 +VkEventCreateInfo (0x0x7f4465589cc0) 0 + +Class VkQueryPoolCreateInfo + size=32 align=8 + base size=32 base align=8 +VkQueryPoolCreateInfo (0x0x7f4465589d20) 0 + +Class VkBufferCreateInfo + size=56 align=8 + base size=56 base align=8 +VkBufferCreateInfo (0x0x7f4465589d80) 0 + +Class VkBufferViewCreateInfo + size=56 align=8 + base size=56 base align=8 +VkBufferViewCreateInfo (0x0x7f4465589de0) 0 + +Class VkImageCreateInfo + size=88 align=8 + base size=88 base align=8 +VkImageCreateInfo (0x0x7f4465589e40) 0 + +Class VkSubresourceLayout + size=40 align=8 + base size=40 base align=8 +VkSubresourceLayout (0x0x7f4465589ea0) 0 + +Class VkComponentMapping + size=16 align=4 + base size=16 base align=4 +VkComponentMapping (0x0x7f4465589f00) 0 + +Class VkImageSubresourceRange + size=20 align=4 + base size=20 base align=4 +VkImageSubresourceRange (0x0x7f4465589f60) 0 + +Class VkImageViewCreateInfo + size=80 align=8 + base size=80 base align=8 +VkImageViewCreateInfo (0x0x7f44655a8000) 0 + +Class VkShaderModuleCreateInfo + size=40 align=8 + base size=40 base align=8 +VkShaderModuleCreateInfo (0x0x7f44655a8060) 0 + +Class VkPipelineCacheCreateInfo + size=40 align=8 + base size=40 base align=8 +VkPipelineCacheCreateInfo (0x0x7f44655a80c0) 0 + +Class VkSpecializationMapEntry + size=16 align=8 + base size=16 base align=8 +VkSpecializationMapEntry (0x0x7f44655a8120) 0 + +Class VkSpecializationInfo + size=32 align=8 + base size=32 base align=8 +VkSpecializationInfo (0x0x7f44655a8180) 0 + +Class VkPipelineShaderStageCreateInfo + size=48 align=8 + base size=48 base align=8 +VkPipelineShaderStageCreateInfo (0x0x7f44655a81e0) 0 + +Class VkVertexInputBindingDescription + size=12 align=4 + base size=12 base align=4 +VkVertexInputBindingDescription (0x0x7f44655a8240) 0 + +Class VkVertexInputAttributeDescription + size=16 align=4 + base size=16 base align=4 +VkVertexInputAttributeDescription (0x0x7f44655a82a0) 0 + +Class VkPipelineVertexInputStateCreateInfo + size=48 align=8 + base size=48 base align=8 +VkPipelineVertexInputStateCreateInfo (0x0x7f44655a8300) 0 + +Class VkPipelineInputAssemblyStateCreateInfo + size=32 align=8 + base size=32 base align=8 +VkPipelineInputAssemblyStateCreateInfo (0x0x7f44655a8360) 0 + +Class VkPipelineTessellationStateCreateInfo + size=24 align=8 + base size=24 base align=8 +VkPipelineTessellationStateCreateInfo (0x0x7f44655a83c0) 0 + +Class VkViewport + size=24 align=4 + base size=24 base align=4 +VkViewport (0x0x7f44655a8420) 0 + +Class VkOffset2D + size=8 align=4 + base size=8 base align=4 +VkOffset2D (0x0x7f44655a8480) 0 + +Class VkExtent2D + size=8 align=4 + base size=8 base align=4 +VkExtent2D (0x0x7f44655a84e0) 0 + +Class VkRect2D + size=16 align=4 + base size=16 base align=4 +VkRect2D (0x0x7f44655a8540) 0 + +Class VkPipelineViewportStateCreateInfo + size=48 align=8 + base size=48 base align=8 +VkPipelineViewportStateCreateInfo (0x0x7f44655a85a0) 0 + +Class VkPipelineRasterizationStateCreateInfo + size=64 align=8 + base size=64 base align=8 +VkPipelineRasterizationStateCreateInfo (0x0x7f44655a8600) 0 + +Class VkPipelineMultisampleStateCreateInfo + size=48 align=8 + base size=48 base align=8 +VkPipelineMultisampleStateCreateInfo (0x0x7f44655a8660) 0 + +Class VkStencilOpState + size=28 align=4 + base size=28 base align=4 +VkStencilOpState (0x0x7f44655a86c0) 0 + +Class VkPipelineDepthStencilStateCreateInfo + size=104 align=8 + base size=104 base align=8 +VkPipelineDepthStencilStateCreateInfo (0x0x7f44655a8720) 0 + +Class VkPipelineColorBlendAttachmentState + size=32 align=4 + base size=32 base align=4 +VkPipelineColorBlendAttachmentState (0x0x7f44655a8780) 0 + +Class VkPipelineColorBlendStateCreateInfo + size=56 align=8 + base size=56 base align=8 +VkPipelineColorBlendStateCreateInfo (0x0x7f44655a87e0) 0 + +Class VkPipelineDynamicStateCreateInfo + size=32 align=8 + base size=32 base align=8 +VkPipelineDynamicStateCreateInfo (0x0x7f44655a8840) 0 + +Class VkGraphicsPipelineCreateInfo + size=144 align=8 + base size=144 base align=8 +VkGraphicsPipelineCreateInfo (0x0x7f44655a88a0) 0 + +Class VkComputePipelineCreateInfo + size=96 align=8 + base size=96 base align=8 +VkComputePipelineCreateInfo (0x0x7f44655a8900) 0 + +Class VkPushConstantRange + size=12 align=4 + base size=12 base align=4 +VkPushConstantRange (0x0x7f44655a8960) 0 + +Class VkPipelineLayoutCreateInfo + size=48 align=8 + base size=48 base align=8 +VkPipelineLayoutCreateInfo (0x0x7f44655a89c0) 0 + +Class VkSamplerCreateInfo + size=80 align=8 + base size=80 base align=8 +VkSamplerCreateInfo (0x0x7f44655a8a20) 0 + +Class VkDescriptorSetLayoutBinding + size=24 align=8 + base size=24 base align=8 +VkDescriptorSetLayoutBinding (0x0x7f44655a8a80) 0 + +Class VkDescriptorSetLayoutCreateInfo + size=32 align=8 + base size=32 base align=8 +VkDescriptorSetLayoutCreateInfo (0x0x7f44655a8ae0) 0 + +Class VkDescriptorPoolSize + size=8 align=4 + base size=8 base align=4 +VkDescriptorPoolSize (0x0x7f44655a8b40) 0 + +Class VkDescriptorPoolCreateInfo + size=40 align=8 + base size=40 base align=8 +VkDescriptorPoolCreateInfo (0x0x7f44655a8ba0) 0 + +Class VkDescriptorSetAllocateInfo + size=40 align=8 + base size=40 base align=8 +VkDescriptorSetAllocateInfo (0x0x7f44655a8c00) 0 + +Class VkDescriptorImageInfo + size=24 align=8 + base size=24 base align=8 +VkDescriptorImageInfo (0x0x7f44655a8c60) 0 + +Class VkDescriptorBufferInfo + size=24 align=8 + base size=24 base align=8 +VkDescriptorBufferInfo (0x0x7f44655a8cc0) 0 + +Class VkWriteDescriptorSet + size=64 align=8 + base size=64 base align=8 +VkWriteDescriptorSet (0x0x7f44655a8d20) 0 + +Class VkCopyDescriptorSet + size=56 align=8 + base size=56 base align=8 +VkCopyDescriptorSet (0x0x7f44655a8de0) 0 + +Class VkFramebufferCreateInfo + size=64 align=8 + base size=64 base align=8 +VkFramebufferCreateInfo (0x0x7f44655a8e40) 0 + +Class VkAttachmentDescription + size=36 align=4 + base size=36 base align=4 +VkAttachmentDescription (0x0x7f44655a8ea0) 0 + +Class VkAttachmentReference + size=8 align=4 + base size=8 base align=4 +VkAttachmentReference (0x0x7f44655a8f00) 0 + +Class VkSubpassDescription + size=72 align=8 + base size=72 base align=8 +VkSubpassDescription (0x0x7f44655a8f60) 0 + +Class VkSubpassDependency + size=28 align=4 + base size=28 base align=4 +VkSubpassDependency (0x0x7f44655c4060) 0 + +Class VkRenderPassCreateInfo + size=64 align=8 + base size=64 base align=8 +VkRenderPassCreateInfo (0x0x7f44655c40c0) 0 + +Class VkCommandPoolCreateInfo + size=24 align=8 + base size=24 base align=8 +VkCommandPoolCreateInfo (0x0x7f44655c4120) 0 + +Class VkCommandBufferAllocateInfo + size=32 align=8 + base size=32 base align=8 +VkCommandBufferAllocateInfo (0x0x7f44655c4180) 0 + +Class VkCommandBufferInheritanceInfo + size=56 align=8 + base size=56 base align=8 +VkCommandBufferInheritanceInfo (0x0x7f44655c41e0) 0 + +Class VkCommandBufferBeginInfo + size=32 align=8 + base size=32 base align=8 +VkCommandBufferBeginInfo (0x0x7f44655c4240) 0 + +Class VkBufferCopy + size=24 align=8 + base size=24 base align=8 +VkBufferCopy (0x0x7f44655c42a0) 0 + +Class VkImageSubresourceLayers + size=16 align=4 + base size=16 base align=4 +VkImageSubresourceLayers (0x0x7f44655c4300) 0 + +Class VkImageCopy + size=68 align=4 + base size=68 base align=4 +VkImageCopy (0x0x7f44655c4360) 0 + +Class VkImageBlit + size=80 align=4 + base size=80 base align=4 +VkImageBlit (0x0x7f44655c43c0) 0 + +Class VkBufferImageCopy + size=56 align=8 + base size=56 base align=8 +VkBufferImageCopy (0x0x7f44655c4420) 0 + +Class VkClearColorValue + size=16 align=4 + base size=16 base align=4 +VkClearColorValue (0x0x7f44655c4480) 0 + +Class VkClearDepthStencilValue + size=8 align=4 + base size=8 base align=4 +VkClearDepthStencilValue (0x0x7f44655c44e0) 0 + +Class VkClearValue + size=16 align=4 + base size=16 base align=4 +VkClearValue (0x0x7f44655c4540) 0 + +Class VkClearAttachment + size=24 align=4 + base size=24 base align=4 +VkClearAttachment (0x0x7f44655c45a0) 0 + +Class VkClearRect + size=24 align=4 + base size=24 base align=4 +VkClearRect (0x0x7f44655c4600) 0 + +Class VkImageResolve + size=68 align=4 + base size=68 base align=4 +VkImageResolve (0x0x7f44655c4660) 0 + +Class VkMemoryBarrier + size=24 align=8 + base size=24 base align=8 +VkMemoryBarrier (0x0x7f44655c46c0) 0 + +Class VkBufferMemoryBarrier + size=56 align=8 + base size=56 base align=8 +VkBufferMemoryBarrier (0x0x7f44655c4720) 0 + +Class VkImageMemoryBarrier + size=72 align=8 + base size=72 base align=8 +VkImageMemoryBarrier (0x0x7f44655c4780) 0 + +Class VkRenderPassBeginInfo + size=64 align=8 + base size=64 base align=8 +VkRenderPassBeginInfo (0x0x7f44655c4840) 0 + +Class VkDispatchIndirectCommand + size=12 align=4 + base size=12 base align=4 +VkDispatchIndirectCommand (0x0x7f44655c48a0) 0 + +Class VkDrawIndexedIndirectCommand + size=20 align=4 + base size=20 base align=4 +VkDrawIndexedIndirectCommand (0x0x7f44655c4900) 0 + +Class VkDrawIndirectCommand + size=16 align=4 + base size=16 base align=4 +VkDrawIndirectCommand (0x0x7f44655c4960) 0 + +Class VkBaseOutStructure + size=16 align=8 + base size=16 base align=8 +VkBaseOutStructure (0x0x7f44655c49c0) 0 + +Class VkBaseInStructure + size=16 align=8 + base size=16 base align=8 +VkBaseInStructure (0x0x7f44655c4a20) 0 + +Class VkPhysicalDeviceSubgroupProperties + size=32 align=8 + base size=32 base align=8 +VkPhysicalDeviceSubgroupProperties (0x0x7f44655c4a80) 0 + +Class VkBindBufferMemoryInfo + size=40 align=8 + base size=40 base align=8 +VkBindBufferMemoryInfo (0x0x7f44655c4ae0) 0 + +Class VkBindImageMemoryInfo + size=40 align=8 + base size=40 base align=8 +VkBindImageMemoryInfo (0x0x7f44655c4b40) 0 + +Class VkPhysicalDevice16BitStorageFeatures + size=32 align=8 + base size=32 base align=8 +VkPhysicalDevice16BitStorageFeatures (0x0x7f44655c4ba0) 0 + +Class VkMemoryDedicatedRequirements + size=24 align=8 + base size=24 base align=8 +VkMemoryDedicatedRequirements (0x0x7f44655c4c00) 0 + +Class VkMemoryDedicatedAllocateInfo + size=32 align=8 + base size=32 base align=8 +VkMemoryDedicatedAllocateInfo (0x0x7f44655c4c60) 0 + +Class VkMemoryAllocateFlagsInfo + size=24 align=8 + base size=24 base align=8 +VkMemoryAllocateFlagsInfo (0x0x7f44655c4cc0) 0 + +Class VkDeviceGroupRenderPassBeginInfo + size=32 align=8 + base size=32 base align=8 +VkDeviceGroupRenderPassBeginInfo (0x0x7f44655c4d20) 0 + +Class VkDeviceGroupCommandBufferBeginInfo + size=24 align=8 + base size=24 base align=8 +VkDeviceGroupCommandBufferBeginInfo (0x0x7f44655c4d80) 0 + +Class VkDeviceGroupSubmitInfo + size=64 align=8 + base size=64 base align=8 +VkDeviceGroupSubmitInfo (0x0x7f44655c4de0) 0 + +Class VkDeviceGroupBindSparseInfo + size=24 align=8 + base size=24 base align=8 +VkDeviceGroupBindSparseInfo (0x0x7f44655c4e40) 0 + +Class VkBindBufferMemoryDeviceGroupInfo + size=32 align=8 + base size=32 base align=8 +VkBindBufferMemoryDeviceGroupInfo (0x0x7f44655c4ea0) 0 + +Class VkBindImageMemoryDeviceGroupInfo + size=48 align=8 + base size=48 base align=8 +VkBindImageMemoryDeviceGroupInfo (0x0x7f44655c4f00) 0 + +Class VkPhysicalDeviceGroupProperties + size=288 align=8 + base size=288 base align=8 +VkPhysicalDeviceGroupProperties (0x0x7f44655c4f60) 0 + +Class VkDeviceGroupDeviceCreateInfo + size=32 align=8 + base size=32 base align=8 +VkDeviceGroupDeviceCreateInfo (0x0x7f446562a000) 0 + +Class VkBufferMemoryRequirementsInfo2 + size=24 align=8 + base size=24 base align=8 +VkBufferMemoryRequirementsInfo2 (0x0x7f446562a060) 0 + +Class VkImageMemoryRequirementsInfo2 + size=24 align=8 + base size=24 base align=8 +VkImageMemoryRequirementsInfo2 (0x0x7f446562a0c0) 0 + +Class VkImageSparseMemoryRequirementsInfo2 + size=24 align=8 + base size=24 base align=8 +VkImageSparseMemoryRequirementsInfo2 (0x0x7f446562a120) 0 + +Class VkMemoryRequirements2 + size=40 align=8 + base size=40 base align=8 +VkMemoryRequirements2 (0x0x7f446562a180) 0 + +Class VkSparseImageMemoryRequirements2 + size=64 align=8 + base size=64 base align=8 +VkSparseImageMemoryRequirements2 (0x0x7f446562a1e0) 0 + +Class VkPhysicalDeviceFeatures2 + size=240 align=8 + base size=240 base align=8 +VkPhysicalDeviceFeatures2 (0x0x7f446562a240) 0 + +Class VkPhysicalDeviceProperties2 + size=840 align=8 + base size=840 base align=8 +VkPhysicalDeviceProperties2 (0x0x7f446562a2a0) 0 + +Class VkFormatProperties2 + size=32 align=8 + base size=32 base align=8 +VkFormatProperties2 (0x0x7f446562a300) 0 + +Class VkImageFormatProperties2 + size=48 align=8 + base size=48 base align=8 +VkImageFormatProperties2 (0x0x7f446562a360) 0 + +Class VkPhysicalDeviceImageFormatInfo2 + size=40 align=8 + base size=40 base align=8 +VkPhysicalDeviceImageFormatInfo2 (0x0x7f446562a3c0) 0 + +Class VkQueueFamilyProperties2 + size=40 align=8 + base size=40 base align=8 +VkQueueFamilyProperties2 (0x0x7f446562a420) 0 + +Class VkPhysicalDeviceMemoryProperties2 + size=536 align=8 + base size=536 base align=8 +VkPhysicalDeviceMemoryProperties2 (0x0x7f446562a480) 0 + +Class VkSparseImageFormatProperties2 + size=40 align=8 + base size=40 base align=8 +VkSparseImageFormatProperties2 (0x0x7f446562a4e0) 0 + +Class VkPhysicalDeviceSparseImageFormatInfo2 + size=40 align=8 + base size=40 base align=8 +VkPhysicalDeviceSparseImageFormatInfo2 (0x0x7f446562a540) 0 + +Class VkPhysicalDevicePointClippingProperties + size=24 align=8 + base size=24 base align=8 +VkPhysicalDevicePointClippingProperties (0x0x7f446562a5a0) 0 + +Class VkInputAttachmentAspectReference + size=12 align=4 + base size=12 base align=4 +VkInputAttachmentAspectReference (0x0x7f446562a600) 0 + +Class VkRenderPassInputAttachmentAspectCreateInfo + size=32 align=8 + base size=32 base align=8 +VkRenderPassInputAttachmentAspectCreateInfo (0x0x7f446562a660) 0 + +Class VkImageViewUsageCreateInfo + size=24 align=8 + base size=24 base align=8 +VkImageViewUsageCreateInfo (0x0x7f446562a6c0) 0 + +Class VkPipelineTessellationDomainOriginStateCreateInfo + size=24 align=8 + base size=24 base align=8 +VkPipelineTessellationDomainOriginStateCreateInfo (0x0x7f446562a720) 0 + +Class VkRenderPassMultiviewCreateInfo + size=64 align=8 + base size=64 base align=8 +VkRenderPassMultiviewCreateInfo (0x0x7f446562a780) 0 + +Class VkPhysicalDeviceMultiviewFeatures + size=32 align=8 + base size=32 base align=8 +VkPhysicalDeviceMultiviewFeatures (0x0x7f446562a7e0) 0 + +Class VkPhysicalDeviceMultiviewProperties + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceMultiviewProperties (0x0x7f446562a840) 0 + +Class VkPhysicalDeviceVariablePointersFeatures + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceVariablePointersFeatures (0x0x7f446562a8a0) 0 + +Class VkPhysicalDeviceProtectedMemoryFeatures + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceProtectedMemoryFeatures (0x0x7f446562a900) 0 + +Class VkPhysicalDeviceProtectedMemoryProperties + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceProtectedMemoryProperties (0x0x7f446562a960) 0 + +Class VkDeviceQueueInfo2 + size=32 align=8 + base size=32 base align=8 +VkDeviceQueueInfo2 (0x0x7f446562a9c0) 0 + +Class VkProtectedSubmitInfo + size=24 align=8 + base size=24 base align=8 +VkProtectedSubmitInfo (0x0x7f446562aa20) 0 + +Class VkSamplerYcbcrConversionCreateInfo + size=64 align=8 + base size=64 base align=8 +VkSamplerYcbcrConversionCreateInfo (0x0x7f446562aa80) 0 + +Class VkSamplerYcbcrConversionInfo + size=24 align=8 + base size=24 base align=8 +VkSamplerYcbcrConversionInfo (0x0x7f446562ab40) 0 + +Class VkBindImagePlaneMemoryInfo + size=24 align=8 + base size=24 base align=8 +VkBindImagePlaneMemoryInfo (0x0x7f446562aba0) 0 + +Class VkImagePlaneMemoryRequirementsInfo + size=24 align=8 + base size=24 base align=8 +VkImagePlaneMemoryRequirementsInfo (0x0x7f446562ac00) 0 + +Class VkPhysicalDeviceSamplerYcbcrConversionFeatures + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceSamplerYcbcrConversionFeatures (0x0x7f446562ac60) 0 + +Class VkSamplerYcbcrConversionImageFormatProperties + size=24 align=8 + base size=24 base align=8 +VkSamplerYcbcrConversionImageFormatProperties (0x0x7f446562acc0) 0 + +Class VkDescriptorUpdateTemplateEntry + size=32 align=8 + base size=32 base align=8 +VkDescriptorUpdateTemplateEntry (0x0x7f446562ad20) 0 + +Class VkDescriptorUpdateTemplateCreateInfo + size=72 align=8 + base size=72 base align=8 +VkDescriptorUpdateTemplateCreateInfo (0x0x7f446562ad80) 0 + +Class VkExternalMemoryProperties + size=12 align=4 + base size=12 base align=4 +VkExternalMemoryProperties (0x0x7f446562ae40) 0 + +Class VkPhysicalDeviceExternalImageFormatInfo + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceExternalImageFormatInfo (0x0x7f446562aea0) 0 + +Class VkExternalImageFormatProperties + size=32 align=8 + base size=32 base align=8 +VkExternalImageFormatProperties (0x0x7f446562af00) 0 + +Class VkPhysicalDeviceExternalBufferInfo + size=32 align=8 + base size=32 base align=8 +VkPhysicalDeviceExternalBufferInfo (0x0x7f446562af60) 0 + +Class VkExternalBufferProperties + size=32 align=8 + base size=32 base align=8 +VkExternalBufferProperties (0x0x7f446563e000) 0 + +Class VkPhysicalDeviceIDProperties + size=64 align=8 + base size=64 base align=8 +VkPhysicalDeviceIDProperties (0x0x7f446563e060) 0 + +Class VkExternalMemoryImageCreateInfo + size=24 align=8 + base size=24 base align=8 +VkExternalMemoryImageCreateInfo (0x0x7f446563e0c0) 0 + +Class VkExternalMemoryBufferCreateInfo + size=24 align=8 + base size=24 base align=8 +VkExternalMemoryBufferCreateInfo (0x0x7f446563e120) 0 + +Class VkExportMemoryAllocateInfo + size=24 align=8 + base size=24 base align=8 +VkExportMemoryAllocateInfo (0x0x7f446563e180) 0 + +Class VkPhysicalDeviceExternalFenceInfo + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceExternalFenceInfo (0x0x7f446563e1e0) 0 + +Class VkExternalFenceProperties + size=32 align=8 + base size=32 base align=8 +VkExternalFenceProperties (0x0x7f446563e240) 0 + +Class VkExportFenceCreateInfo + size=24 align=8 + base size=24 base align=8 +VkExportFenceCreateInfo (0x0x7f446563e2a0) 0 + +Class VkExportSemaphoreCreateInfo + size=24 align=8 + base size=24 base align=8 +VkExportSemaphoreCreateInfo (0x0x7f446563e300) 0 + +Class VkPhysicalDeviceExternalSemaphoreInfo + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceExternalSemaphoreInfo (0x0x7f446563e360) 0 + +Class VkExternalSemaphoreProperties + size=32 align=8 + base size=32 base align=8 +VkExternalSemaphoreProperties (0x0x7f446563e3c0) 0 + +Class VkPhysicalDeviceMaintenance3Properties + size=32 align=8 + base size=32 base align=8 +VkPhysicalDeviceMaintenance3Properties (0x0x7f446563e420) 0 + +Class VkDescriptorSetLayoutSupport + size=24 align=8 + base size=24 base align=8 +VkDescriptorSetLayoutSupport (0x0x7f446563e480) 0 + +Class VkPhysicalDeviceShaderDrawParametersFeatures + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceShaderDrawParametersFeatures (0x0x7f446563e4e0) 0 + +Class VkPhysicalDeviceVulkan11Features + size=64 align=8 + base size=64 base align=8 +VkPhysicalDeviceVulkan11Features (0x0x7f446563e540) 0 + +Class VkPhysicalDeviceVulkan11Properties + size=112 align=8 + base size=112 base align=8 +VkPhysicalDeviceVulkan11Properties (0x0x7f446563e5a0) 0 + +Class VkPhysicalDeviceVulkan12Features + size=208 align=8 + base size=208 base align=8 +VkPhysicalDeviceVulkan12Features (0x0x7f446563e600) 0 + +Class VkConformanceVersion + size=4 align=1 + base size=4 base align=1 +VkConformanceVersion (0x0x7f446563e660) 0 + +Class VkPhysicalDeviceVulkan12Properties + size=736 align=8 + base size=736 base align=8 +VkPhysicalDeviceVulkan12Properties (0x0x7f446563e6c0) 0 + +Class VkImageFormatListCreateInfo + size=32 align=8 + base size=32 base align=8 +VkImageFormatListCreateInfo (0x0x7f446563e720) 0 + +Class VkAttachmentDescription2 + size=56 align=8 + base size=56 base align=8 +VkAttachmentDescription2 (0x0x7f446563e780) 0 + +Class VkAttachmentReference2 + size=32 align=8 + base size=32 base align=8 +VkAttachmentReference2 (0x0x7f446563e7e0) 0 + +Class VkSubpassDescription2 + size=88 align=8 + base size=88 base align=8 +VkSubpassDescription2 (0x0x7f446563e840) 0 + +Class VkSubpassDependency2 + size=48 align=8 + base size=48 base align=8 +VkSubpassDependency2 (0x0x7f446563e8a0) 0 + +Class VkRenderPassCreateInfo2 + size=80 align=8 + base size=80 base align=8 +VkRenderPassCreateInfo2 (0x0x7f446563e960) 0 + +Class VkSubpassBeginInfo + size=24 align=8 + base size=24 base align=8 +VkSubpassBeginInfo (0x0x7f446563e9c0) 0 + +Class VkSubpassEndInfo + size=16 align=8 + base size=16 base align=8 +VkSubpassEndInfo (0x0x7f446563ea20) 0 + +Class VkPhysicalDevice8BitStorageFeatures + size=32 align=8 + base size=32 base align=8 +VkPhysicalDevice8BitStorageFeatures (0x0x7f446563ea80) 0 + +Class VkPhysicalDeviceDriverProperties + size=536 align=8 + base size=536 base align=8 +VkPhysicalDeviceDriverProperties (0x0x7f446563eae0) 0 + +Class VkPhysicalDeviceShaderAtomicInt64Features + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceShaderAtomicInt64Features (0x0x7f446563eb40) 0 + +Class VkPhysicalDeviceShaderFloat16Int8Features + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceShaderFloat16Int8Features (0x0x7f446563eba0) 0 + +Class VkPhysicalDeviceFloatControlsProperties + size=88 align=8 + base size=88 base align=8 +VkPhysicalDeviceFloatControlsProperties (0x0x7f446563ec00) 0 + +Class VkDescriptorSetLayoutBindingFlagsCreateInfo + size=32 align=8 + base size=32 base align=8 +VkDescriptorSetLayoutBindingFlagsCreateInfo (0x0x7f446563ec60) 0 + +Class VkPhysicalDeviceDescriptorIndexingFeatures + size=96 align=8 + base size=96 base align=8 +VkPhysicalDeviceDescriptorIndexingFeatures (0x0x7f446563ecc0) 0 + +Class VkPhysicalDeviceDescriptorIndexingProperties + size=112 align=8 + base size=112 base align=8 +VkPhysicalDeviceDescriptorIndexingProperties (0x0x7f446563ed20) 0 + +Class VkDescriptorSetVariableDescriptorCountAllocateInfo + size=32 align=8 + base size=32 base align=8 +VkDescriptorSetVariableDescriptorCountAllocateInfo (0x0x7f446563ed80) 0 + +Class VkDescriptorSetVariableDescriptorCountLayoutSupport + size=24 align=8 + base size=24 base align=8 +VkDescriptorSetVariableDescriptorCountLayoutSupport (0x0x7f446563ede0) 0 + +Class VkSubpassDescriptionDepthStencilResolve + size=32 align=8 + base size=32 base align=8 +VkSubpassDescriptionDepthStencilResolve (0x0x7f446563ee40) 0 + +Class VkPhysicalDeviceDepthStencilResolveProperties + size=32 align=8 + base size=32 base align=8 +VkPhysicalDeviceDepthStencilResolveProperties (0x0x7f446563eea0) 0 + +Class VkPhysicalDeviceScalarBlockLayoutFeatures + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceScalarBlockLayoutFeatures (0x0x7f446563ef00) 0 + +Class VkImageStencilUsageCreateInfo + size=24 align=8 + base size=24 base align=8 +VkImageStencilUsageCreateInfo (0x0x7f446563ef60) 0 + +Class VkSamplerReductionModeCreateInfo + size=24 align=8 + base size=24 base align=8 +VkSamplerReductionModeCreateInfo (0x0x7f4465670000) 0 + +Class VkPhysicalDeviceSamplerFilterMinmaxProperties + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceSamplerFilterMinmaxProperties (0x0x7f4465670060) 0 + +Class VkPhysicalDeviceVulkanMemoryModelFeatures + size=32 align=8 + base size=32 base align=8 +VkPhysicalDeviceVulkanMemoryModelFeatures (0x0x7f44656700c0) 0 + +Class VkPhysicalDeviceImagelessFramebufferFeatures + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceImagelessFramebufferFeatures (0x0x7f4465670120) 0 + +Class VkFramebufferAttachmentImageInfo + size=48 align=8 + base size=48 base align=8 +VkFramebufferAttachmentImageInfo (0x0x7f4465670180) 0 + +Class VkFramebufferAttachmentsCreateInfo + size=32 align=8 + base size=32 base align=8 +VkFramebufferAttachmentsCreateInfo (0x0x7f44656701e0) 0 + +Class VkRenderPassAttachmentBeginInfo + size=32 align=8 + base size=32 base align=8 +VkRenderPassAttachmentBeginInfo (0x0x7f4465670240) 0 + +Class VkPhysicalDeviceUniformBufferStandardLayoutFeatures + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceUniformBufferStandardLayoutFeatures (0x0x7f44656702a0) 0 + +Class VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures (0x0x7f4465670300) 0 + +Class VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures (0x0x7f4465670360) 0 + +Class VkAttachmentReferenceStencilLayout + size=24 align=8 + base size=24 base align=8 +VkAttachmentReferenceStencilLayout (0x0x7f44656703c0) 0 + +Class VkAttachmentDescriptionStencilLayout + size=24 align=8 + base size=24 base align=8 +VkAttachmentDescriptionStencilLayout (0x0x7f4465670420) 0 + +Class VkPhysicalDeviceHostQueryResetFeatures + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceHostQueryResetFeatures (0x0x7f4465670480) 0 + +Class VkPhysicalDeviceTimelineSemaphoreFeatures + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceTimelineSemaphoreFeatures (0x0x7f44656704e0) 0 + +Class VkPhysicalDeviceTimelineSemaphoreProperties + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceTimelineSemaphoreProperties (0x0x7f4465670540) 0 + +Class VkSemaphoreTypeCreateInfo + size=32 align=8 + base size=32 base align=8 +VkSemaphoreTypeCreateInfo (0x0x7f44656705a0) 0 + +Class VkTimelineSemaphoreSubmitInfo + size=48 align=8 + base size=48 base align=8 +VkTimelineSemaphoreSubmitInfo (0x0x7f4465670600) 0 + +Class VkSemaphoreWaitInfo + size=40 align=8 + base size=40 base align=8 +VkSemaphoreWaitInfo (0x0x7f4465670660) 0 + +Class VkSemaphoreSignalInfo + size=32 align=8 + base size=32 base align=8 +VkSemaphoreSignalInfo (0x0x7f44656706c0) 0 + +Class VkPhysicalDeviceBufferDeviceAddressFeatures + size=32 align=8 + base size=32 base align=8 +VkPhysicalDeviceBufferDeviceAddressFeatures (0x0x7f4465670720) 0 + +Class VkBufferDeviceAddressInfo + size=24 align=8 + base size=24 base align=8 +VkBufferDeviceAddressInfo (0x0x7f4465670780) 0 + +Class VkBufferOpaqueCaptureAddressCreateInfo + size=24 align=8 + base size=24 base align=8 +VkBufferOpaqueCaptureAddressCreateInfo (0x0x7f44656707e0) 0 + +Class VkMemoryOpaqueCaptureAddressAllocateInfo + size=24 align=8 + base size=24 base align=8 +VkMemoryOpaqueCaptureAddressAllocateInfo (0x0x7f4465670840) 0 + +Class VkDeviceMemoryOpaqueCaptureAddressInfo + size=24 align=8 + base size=24 base align=8 +VkDeviceMemoryOpaqueCaptureAddressInfo (0x0x7f44656708a0) 0 + +Class VkSurfaceCapabilitiesKHR + size=52 align=4 + base size=52 base align=4 +VkSurfaceCapabilitiesKHR (0x0x7f4465670900) 0 + +Class VkSurfaceFormatKHR + size=8 align=4 + base size=8 base align=4 +VkSurfaceFormatKHR (0x0x7f44656709c0) 0 + +Class VkSwapchainCreateInfoKHR + size=104 align=8 + base size=104 base align=8 +VkSwapchainCreateInfoKHR (0x0x7f4465670a20) 0 + +Class VkPresentInfoKHR + size=64 align=8 + base size=64 base align=8 +VkPresentInfoKHR (0x0x7f4465670a80) 0 + +Class VkImageSwapchainCreateInfoKHR + size=24 align=8 + base size=24 base align=8 +VkImageSwapchainCreateInfoKHR (0x0x7f4465670ae0) 0 + +Class VkBindImageMemorySwapchainInfoKHR + size=32 align=8 + base size=32 base align=8 +VkBindImageMemorySwapchainInfoKHR (0x0x7f4465670b40) 0 + +Class VkAcquireNextImageInfoKHR + size=56 align=8 + base size=56 base align=8 +VkAcquireNextImageInfoKHR (0x0x7f4465670ba0) 0 + +Class VkDeviceGroupPresentCapabilitiesKHR + size=152 align=8 + base size=152 base align=8 +VkDeviceGroupPresentCapabilitiesKHR (0x0x7f4465670c00) 0 + +Class VkDeviceGroupPresentInfoKHR + size=40 align=8 + base size=40 base align=8 +VkDeviceGroupPresentInfoKHR (0x0x7f4465670c60) 0 + +Class VkDeviceGroupSwapchainCreateInfoKHR + size=24 align=8 + base size=24 base align=8 +VkDeviceGroupSwapchainCreateInfoKHR (0x0x7f4465670cc0) 0 + +Class VkDisplayPropertiesKHR + size=48 align=8 + base size=48 base align=8 +VkDisplayPropertiesKHR (0x0x7f4465670d20) 0 + +Class VkDisplayModeParametersKHR + size=12 align=4 + base size=12 base align=4 +VkDisplayModeParametersKHR (0x0x7f4465670d80) 0 + +Class VkDisplayModePropertiesKHR + size=24 align=8 + base size=24 base align=8 +VkDisplayModePropertiesKHR (0x0x7f4465670de0) 0 + +Class VkDisplayModeCreateInfoKHR + size=32 align=8 + base size=32 base align=8 +VkDisplayModeCreateInfoKHR (0x0x7f4465670e40) 0 + +Class VkDisplayPlaneCapabilitiesKHR + size=68 align=4 + base size=68 base align=4 +VkDisplayPlaneCapabilitiesKHR (0x0x7f4465670ea0) 0 + +Class VkDisplayPlanePropertiesKHR + size=16 align=8 + base size=16 base align=8 +VkDisplayPlanePropertiesKHR (0x0x7f4465670f00) 0 + +Class VkDisplaySurfaceCreateInfoKHR + size=64 align=8 + base size=64 base align=8 +VkDisplaySurfaceCreateInfoKHR (0x0x7f4465670f60) 0 + +Class VkDisplayPresentInfoKHR + size=56 align=8 + base size=56 base align=8 +VkDisplayPresentInfoKHR (0x0x7f4465699060) 0 + +Class VkImportMemoryFdInfoKHR + size=24 align=8 + base size=24 base align=8 +VkImportMemoryFdInfoKHR (0x0x7f44656990c0) 0 + +Class VkMemoryFdPropertiesKHR + size=24 align=8 + base size=24 base align=8 +VkMemoryFdPropertiesKHR (0x0x7f4465699120) 0 + +Class VkMemoryGetFdInfoKHR + size=32 align=8 + base size=32 base align=8 +VkMemoryGetFdInfoKHR (0x0x7f4465699180) 0 + +Class VkImportSemaphoreFdInfoKHR + size=40 align=8 + base size=40 base align=8 +VkImportSemaphoreFdInfoKHR (0x0x7f44656991e0) 0 + +Class VkSemaphoreGetFdInfoKHR + size=32 align=8 + base size=32 base align=8 +VkSemaphoreGetFdInfoKHR (0x0x7f4465699240) 0 + +Class VkPhysicalDevicePushDescriptorPropertiesKHR + size=24 align=8 + base size=24 base align=8 +VkPhysicalDevicePushDescriptorPropertiesKHR (0x0x7f44656992a0) 0 + +Class VkRectLayerKHR + size=20 align=4 + base size=20 base align=4 +VkRectLayerKHR (0x0x7f4465699300) 0 + +Class VkPresentRegionKHR + size=16 align=8 + base size=16 base align=8 +VkPresentRegionKHR (0x0x7f4465699360) 0 + +Class VkPresentRegionsKHR + size=32 align=8 + base size=32 base align=8 +VkPresentRegionsKHR (0x0x7f44656993c0) 0 + +Class VkSharedPresentSurfaceCapabilitiesKHR + size=24 align=8 + base size=24 base align=8 +VkSharedPresentSurfaceCapabilitiesKHR (0x0x7f4465699420) 0 + +Class VkImportFenceFdInfoKHR + size=40 align=8 + base size=40 base align=8 +VkImportFenceFdInfoKHR (0x0x7f4465699480) 0 + +Class VkFenceGetFdInfoKHR + size=32 align=8 + base size=32 base align=8 +VkFenceGetFdInfoKHR (0x0x7f44656994e0) 0 + +Class VkPhysicalDevicePerformanceQueryFeaturesKHR + size=24 align=8 + base size=24 base align=8 +VkPhysicalDevicePerformanceQueryFeaturesKHR (0x0x7f4465699540) 0 + +Class VkPhysicalDevicePerformanceQueryPropertiesKHR + size=24 align=8 + base size=24 base align=8 +VkPhysicalDevicePerformanceQueryPropertiesKHR (0x0x7f44656995a0) 0 + +Class VkPerformanceCounterKHR + size=48 align=8 + base size=48 base align=8 +VkPerformanceCounterKHR (0x0x7f4465699600) 0 + +Class VkPerformanceCounterDescriptionKHR + size=792 align=8 + base size=792 base align=8 +VkPerformanceCounterDescriptionKHR (0x0x7f4465699660) 0 + +Class VkQueryPoolPerformanceCreateInfoKHR + size=32 align=8 + base size=32 base align=8 +VkQueryPoolPerformanceCreateInfoKHR (0x0x7f44656996c0) 0 + +Class VkPerformanceCounterResultKHR + size=8 align=8 + base size=8 base align=8 +VkPerformanceCounterResultKHR (0x0x7f4465699720) 0 + +Class VkAcquireProfilingLockInfoKHR + size=32 align=8 + base size=32 base align=8 +VkAcquireProfilingLockInfoKHR (0x0x7f4465699780) 0 + +Class VkPerformanceQuerySubmitInfoKHR + size=24 align=8 + base size=24 base align=8 +VkPerformanceQuerySubmitInfoKHR (0x0x7f44656997e0) 0 + +Class VkPhysicalDeviceSurfaceInfo2KHR + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceSurfaceInfo2KHR (0x0x7f4465699840) 0 + +Class VkSurfaceCapabilities2KHR + size=72 align=8 + base size=72 base align=8 +VkSurfaceCapabilities2KHR (0x0x7f44656998a0) 0 + +Class VkSurfaceFormat2KHR + size=24 align=8 + base size=24 base align=8 +VkSurfaceFormat2KHR (0x0x7f4465699900) 0 + +Class VkDisplayProperties2KHR + size=64 align=8 + base size=64 base align=8 +VkDisplayProperties2KHR (0x0x7f4465699960) 0 + +Class VkDisplayPlaneProperties2KHR + size=32 align=8 + base size=32 base align=8 +VkDisplayPlaneProperties2KHR (0x0x7f44656999c0) 0 + +Class VkDisplayModeProperties2KHR + size=40 align=8 + base size=40 base align=8 +VkDisplayModeProperties2KHR (0x0x7f4465699a20) 0 + +Class VkDisplayPlaneInfo2KHR + size=32 align=8 + base size=32 base align=8 +VkDisplayPlaneInfo2KHR (0x0x7f4465699a80) 0 + +Class VkDisplayPlaneCapabilities2KHR + size=88 align=8 + base size=88 base align=8 +VkDisplayPlaneCapabilities2KHR (0x0x7f4465699ae0) 0 + +Class VkPhysicalDeviceShaderClockFeaturesKHR + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceShaderClockFeaturesKHR (0x0x7f4465699b40) 0 + +Class VkSurfaceProtectedCapabilitiesKHR + size=24 align=8 + base size=24 base align=8 +VkSurfaceProtectedCapabilitiesKHR (0x0x7f4465699ba0) 0 + +Class VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR + size=24 align=8 + base size=24 base align=8 +VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR (0x0x7f4465699c00) 0 + +Class VkPipelineInfoKHR + size=24 align=8 + base size=24 base align=8 +VkPipelineInfoKHR (0x0x7f4465699c60) 0 + +Class VkPipelineExecutablePropertiesKHR + size=536 align=8 + base size=536 base align=8 +VkPipelineExecutablePropertiesKHR (0x0x7f4465699cc0) 0 + +Class VkPipelineExecutableInfoKHR + size=32 align=8 + base size=32 base align=8 +VkPipelineExecutableInfoKHR (0x0x7f4465699d20) 0 + +Class VkPipelineExecutableStatisticValueKHR + size=8 align=8 + base size=8 base align=8 +VkPipelineExecutableStatisticValueKHR (0x0x7f4465699d80) 0 + +Class VkPipelineExecutableStatisticKHR + size=544 align=8 + base size=544 base align=8 +VkPipelineExecutableStatisticKHR (0x0x7f4465699de0) 0 + +Class VkPipelineExecutableInternalRepresentationKHR + size=552 align=8 + base size=552 base align=8 +VkPipelineExecutableInternalRepresentationKHR (0x0x7f4465699e40) 0 + +Class VkDebugReportCallbackCreateInfoEXT + size=40 align=8 + base size=40 base align=8 +VkDebugReportCallbackCreateInfoEXT (0x0x7f4465699ea0) 0 + +Class VkPipelineRasterizationStateRasterizationOrderAMD + size=24 align=8 + base size=24 base align=8 +VkPipelineRasterizationStateRasterizationOrderAMD (0x0x7f4465699f00) 0 + +Class VkDebugMarkerObjectNameInfoEXT + size=40 align=8 + base size=40 base align=8 +VkDebugMarkerObjectNameInfoEXT (0x0x7f4465699f60) 0 + +Class VkDebugMarkerObjectTagInfoEXT + size=56 align=8 + base size=56 base align=8 +VkDebugMarkerObjectTagInfoEXT (0x0x7f44652db000) 0 + +Class VkDebugMarkerMarkerInfoEXT + size=40 align=8 + base size=40 base align=8 +VkDebugMarkerMarkerInfoEXT (0x0x7f44652db060) 0 + +Class VkDedicatedAllocationImageCreateInfoNV + size=24 align=8 + base size=24 base align=8 +VkDedicatedAllocationImageCreateInfoNV (0x0x7f44652db0c0) 0 + +Class VkDedicatedAllocationBufferCreateInfoNV + size=24 align=8 + base size=24 base align=8 +VkDedicatedAllocationBufferCreateInfoNV (0x0x7f44652db120) 0 + +Class VkDedicatedAllocationMemoryAllocateInfoNV + size=32 align=8 + base size=32 base align=8 +VkDedicatedAllocationMemoryAllocateInfoNV (0x0x7f44652db180) 0 + +Class VkPhysicalDeviceTransformFeedbackFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceTransformFeedbackFeaturesEXT (0x0x7f44652db1e0) 0 + +Class VkPhysicalDeviceTransformFeedbackPropertiesEXT + size=64 align=8 + base size=64 base align=8 +VkPhysicalDeviceTransformFeedbackPropertiesEXT (0x0x7f44652db240) 0 + +Class VkPipelineRasterizationStateStreamCreateInfoEXT + size=24 align=8 + base size=24 base align=8 +VkPipelineRasterizationStateStreamCreateInfoEXT (0x0x7f44652db2a0) 0 + +Class VkImageViewHandleInfoNVX + size=40 align=8 + base size=40 base align=8 +VkImageViewHandleInfoNVX (0x0x7f44652db300) 0 + +Class VkTextureLODGatherFormatPropertiesAMD + size=24 align=8 + base size=24 base align=8 +VkTextureLODGatherFormatPropertiesAMD (0x0x7f44652db360) 0 + +Class VkShaderResourceUsageAMD + size=32 align=8 + base size=32 base align=8 +VkShaderResourceUsageAMD (0x0x7f44652db3c0) 0 + +Class VkShaderStatisticsInfoAMD + size=72 align=8 + base size=72 base align=8 +VkShaderStatisticsInfoAMD (0x0x7f44652db420) 0 + +Class VkPhysicalDeviceCornerSampledImageFeaturesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceCornerSampledImageFeaturesNV (0x0x7f44652db480) 0 + +Class VkExternalImageFormatPropertiesNV + size=48 align=8 + base size=48 base align=8 +VkExternalImageFormatPropertiesNV (0x0x7f44652db4e0) 0 + +Class VkExternalMemoryImageCreateInfoNV + size=24 align=8 + base size=24 base align=8 +VkExternalMemoryImageCreateInfoNV (0x0x7f44652db540) 0 + +Class VkExportMemoryAllocateInfoNV + size=24 align=8 + base size=24 base align=8 +VkExportMemoryAllocateInfoNV (0x0x7f44652db5a0) 0 + +Class VkValidationFlagsEXT + size=32 align=8 + base size=32 base align=8 +VkValidationFlagsEXT (0x0x7f44652db600) 0 + +Class VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT (0x0x7f44652db660) 0 + +Class VkImageViewASTCDecodeModeEXT + size=24 align=8 + base size=24 base align=8 +VkImageViewASTCDecodeModeEXT (0x0x7f44652db6c0) 0 + +Class VkPhysicalDeviceASTCDecodeFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceASTCDecodeFeaturesEXT (0x0x7f44652db720) 0 + +Class VkConditionalRenderingBeginInfoEXT + size=40 align=8 + base size=40 base align=8 +VkConditionalRenderingBeginInfoEXT (0x0x7f44652db780) 0 + +Class VkPhysicalDeviceConditionalRenderingFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceConditionalRenderingFeaturesEXT (0x0x7f44652db7e0) 0 + +Class VkCommandBufferInheritanceConditionalRenderingInfoEXT + size=24 align=8 + base size=24 base align=8 +VkCommandBufferInheritanceConditionalRenderingInfoEXT (0x0x7f44652db840) 0 + +Class VkDeviceGeneratedCommandsFeaturesNVX + size=24 align=8 + base size=24 base align=8 +VkDeviceGeneratedCommandsFeaturesNVX (0x0x7f44652db8a0) 0 + +Class VkDeviceGeneratedCommandsLimitsNVX + size=40 align=8 + base size=40 base align=8 +VkDeviceGeneratedCommandsLimitsNVX (0x0x7f44652db900) 0 + +Class VkIndirectCommandsTokenNVX + size=24 align=8 + base size=24 base align=8 +VkIndirectCommandsTokenNVX (0x0x7f44652db960) 0 + +Class VkIndirectCommandsLayoutTokenNVX + size=16 align=4 + base size=16 base align=4 +VkIndirectCommandsLayoutTokenNVX (0x0x7f44652db9c0) 0 + +Class VkIndirectCommandsLayoutCreateInfoNVX + size=40 align=8 + base size=40 base align=8 +VkIndirectCommandsLayoutCreateInfoNVX (0x0x7f44652dba20) 0 + +Class VkCmdProcessCommandsInfoNVX + size=96 align=8 + base size=96 base align=8 +VkCmdProcessCommandsInfoNVX (0x0x7f44652dba80) 0 + +Class VkCmdReserveSpaceForCommandsInfoNVX + size=40 align=8 + base size=40 base align=8 +VkCmdReserveSpaceForCommandsInfoNVX (0x0x7f44652dbae0) 0 + +Class VkObjectTableCreateInfoNVX + size=72 align=8 + base size=72 base align=8 +VkObjectTableCreateInfoNVX (0x0x7f44652dbb40) 0 + +Class VkObjectTableEntryNVX + size=8 align=4 + base size=8 base align=4 +VkObjectTableEntryNVX (0x0x7f44652dbba0) 0 + +Class VkObjectTablePipelineEntryNVX + size=16 align=8 + base size=16 base align=8 +VkObjectTablePipelineEntryNVX (0x0x7f44652dbc00) 0 + +Class VkObjectTableDescriptorSetEntryNVX + size=24 align=8 + base size=24 base align=8 +VkObjectTableDescriptorSetEntryNVX (0x0x7f44652dbc60) 0 + +Class VkObjectTableVertexBufferEntryNVX + size=16 align=8 + base size=16 base align=8 +VkObjectTableVertexBufferEntryNVX (0x0x7f44652dbcc0) 0 + +Class VkObjectTableIndexBufferEntryNVX + size=24 align=8 + base size=24 base align=8 +VkObjectTableIndexBufferEntryNVX (0x0x7f44652dbd20) 0 + +Class VkObjectTablePushConstantEntryNVX + size=24 align=8 + base size=24 base align=8 +VkObjectTablePushConstantEntryNVX (0x0x7f44652dbd80) 0 + +Class VkViewportWScalingNV + size=8 align=4 + base size=8 base align=4 +VkViewportWScalingNV (0x0x7f44652dbde0) 0 + +Class VkPipelineViewportWScalingStateCreateInfoNV + size=32 align=8 + base size=32 base align=8 +VkPipelineViewportWScalingStateCreateInfoNV (0x0x7f44652dbe40) 0 + +Class VkSurfaceCapabilities2EXT + size=72 align=8 + base size=72 base align=8 +VkSurfaceCapabilities2EXT (0x0x7f44652dbea0) 0 + +Class VkDisplayPowerInfoEXT + size=24 align=8 + base size=24 base align=8 +VkDisplayPowerInfoEXT (0x0x7f44652dbf00) 0 + +Class VkDeviceEventInfoEXT + size=24 align=8 + base size=24 base align=8 +VkDeviceEventInfoEXT (0x0x7f44652dbf60) 0 + +Class VkDisplayEventInfoEXT + size=24 align=8 + base size=24 base align=8 +VkDisplayEventInfoEXT (0x0x7f4465308000) 0 + +Class VkSwapchainCounterCreateInfoEXT + size=24 align=8 + base size=24 base align=8 +VkSwapchainCounterCreateInfoEXT (0x0x7f4465308060) 0 + +Class VkRefreshCycleDurationGOOGLE + size=8 align=8 + base size=8 base align=8 +VkRefreshCycleDurationGOOGLE (0x0x7f44653080c0) 0 + +Class VkPastPresentationTimingGOOGLE + size=40 align=8 + base size=40 base align=8 +VkPastPresentationTimingGOOGLE (0x0x7f4465308120) 0 + +Class VkPresentTimeGOOGLE + size=16 align=8 + base size=16 base align=8 +VkPresentTimeGOOGLE (0x0x7f4465308180) 0 + +Class VkPresentTimesInfoGOOGLE + size=32 align=8 + base size=32 base align=8 +VkPresentTimesInfoGOOGLE (0x0x7f44653081e0) 0 + +Class VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX (0x0x7f4465308240) 0 + +Class VkViewportSwizzleNV + size=16 align=4 + base size=16 base align=4 +VkViewportSwizzleNV (0x0x7f44653082a0) 0 + +Class VkPipelineViewportSwizzleStateCreateInfoNV + size=32 align=8 + base size=32 base align=8 +VkPipelineViewportSwizzleStateCreateInfoNV (0x0x7f4465308300) 0 + +Class VkPhysicalDeviceDiscardRectanglePropertiesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceDiscardRectanglePropertiesEXT (0x0x7f4465308360) 0 + +Class VkPipelineDiscardRectangleStateCreateInfoEXT + size=40 align=8 + base size=40 base align=8 +VkPipelineDiscardRectangleStateCreateInfoEXT (0x0x7f44653083c0) 0 + +Class VkPhysicalDeviceConservativeRasterizationPropertiesEXT + size=56 align=8 + base size=56 base align=8 +VkPhysicalDeviceConservativeRasterizationPropertiesEXT (0x0x7f4465308420) 0 + +Class VkPipelineRasterizationConservativeStateCreateInfoEXT + size=32 align=8 + base size=32 base align=8 +VkPipelineRasterizationConservativeStateCreateInfoEXT (0x0x7f4465308480) 0 + +Class VkPhysicalDeviceDepthClipEnableFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceDepthClipEnableFeaturesEXT (0x0x7f44653084e0) 0 + +Class VkPipelineRasterizationDepthClipStateCreateInfoEXT + size=24 align=8 + base size=24 base align=8 +VkPipelineRasterizationDepthClipStateCreateInfoEXT (0x0x7f4465308540) 0 + +Class VkXYColorEXT + size=8 align=4 + base size=8 base align=4 +VkXYColorEXT (0x0x7f44653085a0) 0 + +Class VkHdrMetadataEXT + size=64 align=8 + base size=64 base align=8 +VkHdrMetadataEXT (0x0x7f4465308600) 0 + +Class VkDebugUtilsObjectNameInfoEXT + size=40 align=8 + base size=40 base align=8 +VkDebugUtilsObjectNameInfoEXT (0x0x7f44653086c0) 0 + +Class VkDebugUtilsObjectTagInfoEXT + size=56 align=8 + base size=56 base align=8 +VkDebugUtilsObjectTagInfoEXT (0x0x7f4465308720) 0 + +Class VkDebugUtilsLabelEXT + size=40 align=8 + base size=40 base align=8 +VkDebugUtilsLabelEXT (0x0x7f4465308780) 0 + +Class VkDebugUtilsMessengerCallbackDataEXT + size=96 align=8 + base size=96 base align=8 +VkDebugUtilsMessengerCallbackDataEXT (0x0x7f44653087e0) 0 + +Class VkDebugUtilsMessengerCreateInfoEXT + size=48 align=8 + base size=48 base align=8 +VkDebugUtilsMessengerCreateInfoEXT (0x0x7f4465308840) 0 + +Class VkPhysicalDeviceInlineUniformBlockFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceInlineUniformBlockFeaturesEXT (0x0x7f44653088a0) 0 + +Class VkPhysicalDeviceInlineUniformBlockPropertiesEXT + size=40 align=8 + base size=40 base align=8 +VkPhysicalDeviceInlineUniformBlockPropertiesEXT (0x0x7f4465308900) 0 + +Class VkWriteDescriptorSetInlineUniformBlockEXT + size=32 align=8 + base size=32 base align=8 +VkWriteDescriptorSetInlineUniformBlockEXT (0x0x7f4465308960) 0 + +Class VkDescriptorPoolInlineUniformBlockCreateInfoEXT + size=24 align=8 + base size=24 base align=8 +VkDescriptorPoolInlineUniformBlockCreateInfoEXT (0x0x7f44653089c0) 0 + +Class VkSampleLocationEXT + size=8 align=4 + base size=8 base align=4 +VkSampleLocationEXT (0x0x7f4465308a20) 0 + +Class VkSampleLocationsInfoEXT + size=40 align=8 + base size=40 base align=8 +VkSampleLocationsInfoEXT (0x0x7f4465308a80) 0 + +Class VkAttachmentSampleLocationsEXT + size=48 align=8 + base size=48 base align=8 +VkAttachmentSampleLocationsEXT (0x0x7f4465308ae0) 0 + +Class VkSubpassSampleLocationsEXT + size=48 align=8 + base size=48 base align=8 +VkSubpassSampleLocationsEXT (0x0x7f4465308b40) 0 + +Class VkRenderPassSampleLocationsBeginInfoEXT + size=48 align=8 + base size=48 base align=8 +VkRenderPassSampleLocationsBeginInfoEXT (0x0x7f4465308ba0) 0 + +Class VkPipelineSampleLocationsStateCreateInfoEXT + size=64 align=8 + base size=64 base align=8 +VkPipelineSampleLocationsStateCreateInfoEXT (0x0x7f4465308c00) 0 + +Class VkPhysicalDeviceSampleLocationsPropertiesEXT + size=48 align=8 + base size=48 base align=8 +VkPhysicalDeviceSampleLocationsPropertiesEXT (0x0x7f4465308c60) 0 + +Class VkMultisamplePropertiesEXT + size=24 align=8 + base size=24 base align=8 +VkMultisamplePropertiesEXT (0x0x7f4465308cc0) 0 + +Class VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT (0x0x7f4465308d20) 0 + +Class VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT + size=40 align=8 + base size=40 base align=8 +VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT (0x0x7f4465308d80) 0 + +Class VkPipelineColorBlendAdvancedStateCreateInfoEXT + size=32 align=8 + base size=32 base align=8 +VkPipelineColorBlendAdvancedStateCreateInfoEXT (0x0x7f4465308de0) 0 + +Class VkPipelineCoverageToColorStateCreateInfoNV + size=32 align=8 + base size=32 base align=8 +VkPipelineCoverageToColorStateCreateInfoNV (0x0x7f4465308e40) 0 + +Class VkPipelineCoverageModulationStateCreateInfoNV + size=40 align=8 + base size=40 base align=8 +VkPipelineCoverageModulationStateCreateInfoNV (0x0x7f4465308ea0) 0 + +Class VkPhysicalDeviceShaderSMBuiltinsPropertiesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceShaderSMBuiltinsPropertiesNV (0x0x7f4465308f00) 0 + +Class VkPhysicalDeviceShaderSMBuiltinsFeaturesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceShaderSMBuiltinsFeaturesNV (0x0x7f4465308f60) 0 + +Class VkDrmFormatModifierPropertiesEXT + size=16 align=8 + base size=16 base align=8 +VkDrmFormatModifierPropertiesEXT (0x0x7f4465330000) 0 + +Class VkDrmFormatModifierPropertiesListEXT + size=32 align=8 + base size=32 base align=8 +VkDrmFormatModifierPropertiesListEXT (0x0x7f4465330060) 0 + +Class VkPhysicalDeviceImageDrmFormatModifierInfoEXT + size=40 align=8 + base size=40 base align=8 +VkPhysicalDeviceImageDrmFormatModifierInfoEXT (0x0x7f44653300c0) 0 + +Class VkImageDrmFormatModifierListCreateInfoEXT + size=32 align=8 + base size=32 base align=8 +VkImageDrmFormatModifierListCreateInfoEXT (0x0x7f4465330120) 0 + +Class VkImageDrmFormatModifierExplicitCreateInfoEXT + size=40 align=8 + base size=40 base align=8 +VkImageDrmFormatModifierExplicitCreateInfoEXT (0x0x7f4465330180) 0 + +Class VkImageDrmFormatModifierPropertiesEXT + size=24 align=8 + base size=24 base align=8 +VkImageDrmFormatModifierPropertiesEXT (0x0x7f44653301e0) 0 + +Class VkValidationCacheCreateInfoEXT + size=40 align=8 + base size=40 base align=8 +VkValidationCacheCreateInfoEXT (0x0x7f4465330240) 0 + +Class VkShaderModuleValidationCacheCreateInfoEXT + size=24 align=8 + base size=24 base align=8 +VkShaderModuleValidationCacheCreateInfoEXT (0x0x7f44653302a0) 0 + +Class VkShadingRatePaletteNV + size=16 align=8 + base size=16 base align=8 +VkShadingRatePaletteNV (0x0x7f4465330300) 0 + +Class VkPipelineViewportShadingRateImageStateCreateInfoNV + size=32 align=8 + base size=32 base align=8 +VkPipelineViewportShadingRateImageStateCreateInfoNV (0x0x7f4465330360) 0 + +Class VkPhysicalDeviceShadingRateImageFeaturesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceShadingRateImageFeaturesNV (0x0x7f44653303c0) 0 + +Class VkPhysicalDeviceShadingRateImagePropertiesNV + size=32 align=8 + base size=32 base align=8 +VkPhysicalDeviceShadingRateImagePropertiesNV (0x0x7f4465330420) 0 + +Class VkCoarseSampleLocationNV + size=12 align=4 + base size=12 base align=4 +VkCoarseSampleLocationNV (0x0x7f4465330480) 0 + +Class VkCoarseSampleOrderCustomNV + size=24 align=8 + base size=24 base align=8 +VkCoarseSampleOrderCustomNV (0x0x7f44653304e0) 0 + +Class VkPipelineViewportCoarseSampleOrderStateCreateInfoNV + size=32 align=8 + base size=32 base align=8 +VkPipelineViewportCoarseSampleOrderStateCreateInfoNV (0x0x7f4465330540) 0 + +Class VkRayTracingShaderGroupCreateInfoNV + size=40 align=8 + base size=40 base align=8 +VkRayTracingShaderGroupCreateInfoNV (0x0x7f44653305a0) 0 + +Class VkRayTracingPipelineCreateInfoNV + size=80 align=8 + base size=80 base align=8 +VkRayTracingPipelineCreateInfoNV (0x0x7f4465330600) 0 + +Class VkGeometryTrianglesNV + size=96 align=8 + base size=96 base align=8 +VkGeometryTrianglesNV (0x0x7f4465330660) 0 + +Class VkGeometryAABBNV + size=40 align=8 + base size=40 base align=8 +VkGeometryAABBNV (0x0x7f44653306c0) 0 + +Class VkGeometryDataNV + size=136 align=8 + base size=136 base align=8 +VkGeometryDataNV (0x0x7f4465330720) 0 + +Class VkGeometryNV + size=168 align=8 + base size=168 base align=8 +VkGeometryNV (0x0x7f4465330780) 0 + +Class VkAccelerationStructureInfoNV + size=40 align=8 + base size=40 base align=8 +VkAccelerationStructureInfoNV (0x0x7f44653307e0) 0 + +Class VkAccelerationStructureCreateInfoNV + size=64 align=8 + base size=64 base align=8 +VkAccelerationStructureCreateInfoNV (0x0x7f4465330840) 0 + +Class VkBindAccelerationStructureMemoryInfoNV + size=56 align=8 + base size=56 base align=8 +VkBindAccelerationStructureMemoryInfoNV (0x0x7f44653308a0) 0 + +Class VkWriteDescriptorSetAccelerationStructureNV + size=32 align=8 + base size=32 base align=8 +VkWriteDescriptorSetAccelerationStructureNV (0x0x7f4465330900) 0 + +Class VkAccelerationStructureMemoryRequirementsInfoNV + size=32 align=8 + base size=32 base align=8 +VkAccelerationStructureMemoryRequirementsInfoNV (0x0x7f4465330960) 0 + +Class VkPhysicalDeviceRayTracingPropertiesNV + size=64 align=8 + base size=64 base align=8 +VkPhysicalDeviceRayTracingPropertiesNV (0x0x7f44653309c0) 0 + +Class VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV (0x0x7f4465330a80) 0 + +Class VkPipelineRepresentativeFragmentTestStateCreateInfoNV + size=24 align=8 + base size=24 base align=8 +VkPipelineRepresentativeFragmentTestStateCreateInfoNV (0x0x7f4465330ae0) 0 + +Class VkPhysicalDeviceImageViewImageFormatInfoEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceImageViewImageFormatInfoEXT (0x0x7f4465330b40) 0 + +Class VkFilterCubicImageViewImageFormatPropertiesEXT + size=24 align=8 + base size=24 base align=8 +VkFilterCubicImageViewImageFormatPropertiesEXT (0x0x7f4465330ba0) 0 + +Class VkDeviceQueueGlobalPriorityCreateInfoEXT + size=24 align=8 + base size=24 base align=8 +VkDeviceQueueGlobalPriorityCreateInfoEXT (0x0x7f4465330c00) 0 + +Class VkImportMemoryHostPointerInfoEXT + size=32 align=8 + base size=32 base align=8 +VkImportMemoryHostPointerInfoEXT (0x0x7f4465330c60) 0 + +Class VkMemoryHostPointerPropertiesEXT + size=24 align=8 + base size=24 base align=8 +VkMemoryHostPointerPropertiesEXT (0x0x7f4465330cc0) 0 + +Class VkPhysicalDeviceExternalMemoryHostPropertiesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceExternalMemoryHostPropertiesEXT (0x0x7f4465330d20) 0 + +Class VkPipelineCompilerControlCreateInfoAMD + size=24 align=8 + base size=24 base align=8 +VkPipelineCompilerControlCreateInfoAMD (0x0x7f4465330d80) 0 + +Class VkCalibratedTimestampInfoEXT + size=24 align=8 + base size=24 base align=8 +VkCalibratedTimestampInfoEXT (0x0x7f4465330de0) 0 + +Class VkPhysicalDeviceShaderCorePropertiesAMD + size=72 align=8 + base size=72 base align=8 +VkPhysicalDeviceShaderCorePropertiesAMD (0x0x7f4465330e40) 0 + +Class VkDeviceMemoryOverallocationCreateInfoAMD + size=24 align=8 + base size=24 base align=8 +VkDeviceMemoryOverallocationCreateInfoAMD (0x0x7f4465330ea0) 0 + +Class VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT (0x0x7f4465330f00) 0 + +Class VkVertexInputBindingDivisorDescriptionEXT + size=8 align=4 + base size=8 base align=4 +VkVertexInputBindingDivisorDescriptionEXT (0x0x7f4465330f60) 0 + +Class VkPipelineVertexInputDivisorStateCreateInfoEXT + size=32 align=8 + base size=32 base align=8 +VkPipelineVertexInputDivisorStateCreateInfoEXT (0x0x7f4465360000) 0 + +Class VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT (0x0x7f4465360060) 0 + +Class VkPipelineCreationFeedbackEXT + size=16 align=8 + base size=16 base align=8 +VkPipelineCreationFeedbackEXT (0x0x7f44653600c0) 0 + +Class VkPipelineCreationFeedbackCreateInfoEXT + size=40 align=8 + base size=40 base align=8 +VkPipelineCreationFeedbackCreateInfoEXT (0x0x7f4465360120) 0 + +Class VkPhysicalDeviceComputeShaderDerivativesFeaturesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceComputeShaderDerivativesFeaturesNV (0x0x7f4465360180) 0 + +Class VkPhysicalDeviceMeshShaderFeaturesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceMeshShaderFeaturesNV (0x0x7f44653601e0) 0 + +Class VkPhysicalDeviceMeshShaderPropertiesNV + size=88 align=8 + base size=88 base align=8 +VkPhysicalDeviceMeshShaderPropertiesNV (0x0x7f4465360240) 0 + +Class VkDrawMeshTasksIndirectCommandNV + size=8 align=4 + base size=8 base align=4 +VkDrawMeshTasksIndirectCommandNV (0x0x7f44653602a0) 0 + +Class VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV (0x0x7f4465360300) 0 + +Class VkPhysicalDeviceShaderImageFootprintFeaturesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceShaderImageFootprintFeaturesNV (0x0x7f4465360360) 0 + +Class VkPipelineViewportExclusiveScissorStateCreateInfoNV + size=32 align=8 + base size=32 base align=8 +VkPipelineViewportExclusiveScissorStateCreateInfoNV (0x0x7f44653603c0) 0 + +Class VkPhysicalDeviceExclusiveScissorFeaturesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceExclusiveScissorFeaturesNV (0x0x7f4465360420) 0 + +Class VkQueueFamilyCheckpointPropertiesNV + size=24 align=8 + base size=24 base align=8 +VkQueueFamilyCheckpointPropertiesNV (0x0x7f4465360480) 0 + +Class VkCheckpointDataNV + size=32 align=8 + base size=32 base align=8 +VkCheckpointDataNV (0x0x7f44653604e0) 0 + +Class VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL (0x0x7f4465360540) 0 + +Class VkPerformanceValueDataINTEL + size=8 align=8 + base size=8 base align=8 +VkPerformanceValueDataINTEL (0x0x7f44653605a0) 0 + +Class VkPerformanceValueINTEL + size=16 align=8 + base size=16 base align=8 +VkPerformanceValueINTEL (0x0x7f4465360600) 0 + +Class VkInitializePerformanceApiInfoINTEL + size=24 align=8 + base size=24 base align=8 +VkInitializePerformanceApiInfoINTEL (0x0x7f4465360660) 0 + +Class VkQueryPoolCreateInfoINTEL + size=24 align=8 + base size=24 base align=8 +VkQueryPoolCreateInfoINTEL (0x0x7f44653606c0) 0 + +Class VkPerformanceMarkerInfoINTEL + size=24 align=8 + base size=24 base align=8 +VkPerformanceMarkerInfoINTEL (0x0x7f4465360720) 0 + +Class VkPerformanceStreamMarkerInfoINTEL + size=24 align=8 + base size=24 base align=8 +VkPerformanceStreamMarkerInfoINTEL (0x0x7f4465360780) 0 + +Class VkPerformanceOverrideInfoINTEL + size=32 align=8 + base size=32 base align=8 +VkPerformanceOverrideInfoINTEL (0x0x7f44653607e0) 0 + +Class VkPerformanceConfigurationAcquireInfoINTEL + size=24 align=8 + base size=24 base align=8 +VkPerformanceConfigurationAcquireInfoINTEL (0x0x7f4465360840) 0 + +Class VkPhysicalDevicePCIBusInfoPropertiesEXT + size=32 align=8 + base size=32 base align=8 +VkPhysicalDevicePCIBusInfoPropertiesEXT (0x0x7f44653608a0) 0 + +Class VkDisplayNativeHdrSurfaceCapabilitiesAMD + size=24 align=8 + base size=24 base align=8 +VkDisplayNativeHdrSurfaceCapabilitiesAMD (0x0x7f4465360900) 0 + +Class VkSwapchainDisplayNativeHdrCreateInfoAMD + size=24 align=8 + base size=24 base align=8 +VkSwapchainDisplayNativeHdrCreateInfoAMD (0x0x7f4465360960) 0 + +Class VkPhysicalDeviceFragmentDensityMapFeaturesEXT + size=32 align=8 + base size=32 base align=8 +VkPhysicalDeviceFragmentDensityMapFeaturesEXT (0x0x7f44653609c0) 0 + +Class VkPhysicalDeviceFragmentDensityMapPropertiesEXT + size=40 align=8 + base size=40 base align=8 +VkPhysicalDeviceFragmentDensityMapPropertiesEXT (0x0x7f4465360a20) 0 + +Class VkRenderPassFragmentDensityMapCreateInfoEXT + size=24 align=8 + base size=24 base align=8 +VkRenderPassFragmentDensityMapCreateInfoEXT (0x0x7f4465360a80) 0 + +Class VkPhysicalDeviceSubgroupSizeControlFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceSubgroupSizeControlFeaturesEXT (0x0x7f4465360ae0) 0 + +Class VkPhysicalDeviceSubgroupSizeControlPropertiesEXT + size=32 align=8 + base size=32 base align=8 +VkPhysicalDeviceSubgroupSizeControlPropertiesEXT (0x0x7f4465360b40) 0 + +Class VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT + size=24 align=8 + base size=24 base align=8 +VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT (0x0x7f4465360ba0) 0 + +Class VkPhysicalDeviceShaderCoreProperties2AMD + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceShaderCoreProperties2AMD (0x0x7f4465360c00) 0 + +Class VkPhysicalDeviceCoherentMemoryFeaturesAMD + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceCoherentMemoryFeaturesAMD (0x0x7f4465360c60) 0 + +Class VkPhysicalDeviceMemoryBudgetPropertiesEXT + size=272 align=8 + base size=272 base align=8 +VkPhysicalDeviceMemoryBudgetPropertiesEXT (0x0x7f4465360cc0) 0 + +Class VkPhysicalDeviceMemoryPriorityFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceMemoryPriorityFeaturesEXT (0x0x7f4465360d20) 0 + +Class VkMemoryPriorityAllocateInfoEXT + size=24 align=8 + base size=24 base align=8 +VkMemoryPriorityAllocateInfoEXT (0x0x7f4465360d80) 0 + +Class VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV (0x0x7f4465360de0) 0 + +Class VkPhysicalDeviceBufferDeviceAddressFeaturesEXT + size=32 align=8 + base size=32 base align=8 +VkPhysicalDeviceBufferDeviceAddressFeaturesEXT (0x0x7f4465360e40) 0 + +Class VkBufferDeviceAddressCreateInfoEXT + size=24 align=8 + base size=24 base align=8 +VkBufferDeviceAddressCreateInfoEXT (0x0x7f4465360ea0) 0 + +Class VkPhysicalDeviceToolPropertiesEXT + size=1048 align=8 + base size=1048 base align=8 +VkPhysicalDeviceToolPropertiesEXT (0x0x7f4465360f00) 0 + +Class VkValidationFeaturesEXT + size=48 align=8 + base size=48 base align=8 +VkValidationFeaturesEXT (0x0x7f4465360f60) 0 + +Class VkCooperativeMatrixPropertiesNV + size=48 align=8 + base size=48 base align=8 +VkCooperativeMatrixPropertiesNV (0x0x7f4465385000) 0 + +Class VkPhysicalDeviceCooperativeMatrixFeaturesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceCooperativeMatrixFeaturesNV (0x0x7f44653850c0) 0 + +Class VkPhysicalDeviceCooperativeMatrixPropertiesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceCooperativeMatrixPropertiesNV (0x0x7f4465385120) 0 + +Class VkPhysicalDeviceCoverageReductionModeFeaturesNV + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceCoverageReductionModeFeaturesNV (0x0x7f4465385180) 0 + +Class VkPipelineCoverageReductionStateCreateInfoNV + size=24 align=8 + base size=24 base align=8 +VkPipelineCoverageReductionStateCreateInfoNV (0x0x7f44653851e0) 0 + +Class VkFramebufferMixedSamplesCombinationNV + size=32 align=8 + base size=32 base align=8 +VkFramebufferMixedSamplesCombinationNV (0x0x7f4465385240) 0 + +Class VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT + size=32 align=8 + base size=32 base align=8 +VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT (0x0x7f44653852a0) 0 + +Class VkPhysicalDeviceYcbcrImageArraysFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceYcbcrImageArraysFeaturesEXT (0x0x7f4465385300) 0 + +Class VkHeadlessSurfaceCreateInfoEXT + size=24 align=8 + base size=24 base align=8 +VkHeadlessSurfaceCreateInfoEXT (0x0x7f4465385360) 0 + +Class VkPhysicalDeviceLineRasterizationFeaturesEXT + size=40 align=8 + base size=40 base align=8 +VkPhysicalDeviceLineRasterizationFeaturesEXT (0x0x7f44653853c0) 0 + +Class VkPhysicalDeviceLineRasterizationPropertiesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceLineRasterizationPropertiesEXT (0x0x7f4465385420) 0 + +Class VkPipelineRasterizationLineStateCreateInfoEXT + size=32 align=8 + base size=32 base align=8 +VkPipelineRasterizationLineStateCreateInfoEXT (0x0x7f4465385480) 0 + +Class VkPhysicalDeviceIndexTypeUint8FeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceIndexTypeUint8FeaturesEXT (0x0x7f44653854e0) 0 + +Class VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT (0x0x7f4465385540) 0 + +Class VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT + size=24 align=8 + base size=24 base align=8 +VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT (0x0x7f44653855a0) 0 + +Class VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT + size=48 align=8 + base size=48 base align=8 +VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT (0x0x7f4465385600) 0 + +Class QVulkanLayer + size=64 align=8 + base size=64 base align=8 +QVulkanLayer (0x0x7f4465385660) 0 + +Class QVulkanExtension + size=32 align=8 + base size=28 base align=8 +QVulkanExtension (0x0x7f44653ba300) 0 + +Class QVulkanInstance + size=8 align=8 + base size=8 base align=8 +QVulkanInstance (0x0x7f44653e3180) 0 + +Class QQuickGraphicsDevice + size=8 align=8 + base size=8 base align=8 +QQuickGraphicsDevice (0x0x7f44653e3540) 0 + +Class QQuickTextureFactory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextureFactory::QPrivateSignal (0x0x7f44653e3600) 0 empty + +Vtable for QQuickTextureFactory +QQuickTextureFactory::_ZTV20QQuickTextureFactory: 18 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickTextureFactory) +16 (int (*)(...))QQuickTextureFactory::metaObject +24 (int (*)(...))QQuickTextureFactory::qt_metacast +32 (int (*)(...))QQuickTextureFactory::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))QQuickTextureFactory::image + +Class QQuickTextureFactory + size=16 align=8 + base size=16 base align=8 +QQuickTextureFactory (0x0x7f44653d4888) 0 + vptr=((& QQuickTextureFactory::_ZTV20QQuickTextureFactory) + 16) + QObject (0x0x7f44653e35a0) 0 + primary-for QQuickTextureFactory (0x0x7f44653d4888) + +Class QQuickImageResponse::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickImageResponse::QPrivateSignal (0x0x7f44653e3720) 0 empty + +Vtable for QQuickImageResponse +QQuickImageResponse::_ZTV19QQuickImageResponse: 17 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageResponse) +16 (int (*)(...))QQuickImageResponse::metaObject +24 (int (*)(...))QQuickImageResponse::qt_metacast +32 (int (*)(...))QQuickImageResponse::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QQuickImageResponse::errorString +128 (int (*)(...))QQuickImageResponse::cancel + +Class QQuickImageResponse + size=16 align=8 + base size=16 base align=8 +QQuickImageResponse (0x0x7f44653d48f0) 0 + vptr=((& QQuickImageResponse::_ZTV19QQuickImageResponse) + 16) + QObject (0x0x7f44653e36c0) 0 + primary-for QQuickImageResponse (0x0x7f44653d48f0) + +Class QQuickImageProvider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickImageProvider::QPrivateSignal (0x0x7f44653e3900) 0 empty + +Vtable for QQuickImageProvider +QQuickImageProvider::_ZTV19QQuickImageProvider: 19 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickImageProvider) +16 (int (*)(...))QQuickImageProvider::metaObject +24 (int (*)(...))QQuickImageProvider::qt_metacast +32 (int (*)(...))QQuickImageProvider::qt_metacall +40 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +48 (int (*)(...))QQuickImageProvider::~QQuickImageProvider +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickImageProvider::imageType +120 (int (*)(...))QQuickImageProvider::flags +128 (int (*)(...))QQuickImageProvider::requestImage +136 (int (*)(...))QQuickImageProvider::requestPixmap +144 (int (*)(...))QQuickImageProvider::requestTexture + +Class QQuickImageProvider + size=24 align=8 + base size=24 base align=8 +QQuickImageProvider (0x0x7f44653d4958) 0 + vptr=((& QQuickImageProvider::_ZTV19QQuickImageProvider) + 16) + QQmlImageProviderBase (0x0x7f44653d49c0) 0 + primary-for QQuickImageProvider (0x0x7f44653d4958) + QObject (0x0x7f44653e38a0) 0 + primary-for QQmlImageProviderBase (0x0x7f44653d49c0) + +Vtable for QQuickAsyncImageProvider +QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider: 20 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QQuickAsyncImageProvider) +16 (int (*)(...))QQuickImageProvider::metaObject +24 (int (*)(...))QQuickImageProvider::qt_metacast +32 (int (*)(...))QQuickImageProvider::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickImageProvider::imageType +120 (int (*)(...))QQuickImageProvider::flags +128 (int (*)(...))QQuickImageProvider::requestImage +136 (int (*)(...))QQuickImageProvider::requestPixmap +144 (int (*)(...))QQuickImageProvider::requestTexture +152 (int (*)(...))__cxa_pure_virtual + +Class QQuickAsyncImageProvider + size=32 align=8 + base size=32 base align=8 +QQuickAsyncImageProvider (0x0x7f44653d4a28) 0 + vptr=((& QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider) + 16) + QQuickImageProvider (0x0x7f44653d4a90) 0 + primary-for QQuickAsyncImageProvider (0x0x7f44653d4a28) + QQmlImageProviderBase (0x0x7f44653d4af8) 0 + primary-for QQuickImageProvider (0x0x7f44653d4a90) + QObject (0x0x7f44653e39c0) 0 + primary-for QQmlImageProviderBase (0x0x7f44653d4af8) + +Class QQuickItemGrabResult::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickItemGrabResult::QPrivateSignal (0x0x7f44653e3a80) 0 empty + +Vtable for QQuickItemGrabResult +QQuickItemGrabResult::_ZTV20QQuickItemGrabResult: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QQuickItemGrabResult) +16 (int (*)(...))QQuickItemGrabResult::metaObject +24 (int (*)(...))QQuickItemGrabResult::qt_metacast +32 (int (*)(...))QQuickItemGrabResult::qt_metacall +40 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +48 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult +56 (int (*)(...))QQuickItemGrabResult::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickItemGrabResult + size=16 align=8 + base size=16 base align=8 +QQuickItemGrabResult (0x0x7f44653d4b60) 0 + vptr=((& QQuickItemGrabResult::_ZTV20QQuickItemGrabResult) + 16) + QObject (0x0x7f44653e3a20) 0 + primary-for QQuickItemGrabResult (0x0x7f44653d4b60) + +Class QQuickPaintedItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickPaintedItem::QPrivateSignal (0x0x7f44653e3cc0) 0 empty + +Vtable for QQuickPaintedItem +QQuickPaintedItem::_ZTV17QQuickPaintedItem: 55 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QQuickPaintedItem) +16 (int (*)(...))QQuickPaintedItem::metaObject +24 (int (*)(...))QQuickPaintedItem::qt_metacast +32 (int (*)(...))QQuickPaintedItem::qt_metacall +40 0 +48 0 +56 (int (*)(...))QQuickItem::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickItem::boundingRect +120 (int (*)(...))QQuickItem::clipRect +128 (int (*)(...))QQuickItem::contains +136 (int (*)(...))QQuickItem::inputMethodQuery +144 (int (*)(...))QQuickPaintedItem::isTextureProvider +152 (int (*)(...))QQuickPaintedItem::textureProvider +160 (int (*)(...))QQuickPaintedItem::itemChange +168 (int (*)(...))QQuickItem::geometryChange +176 (int (*)(...))QQuickItem::classBegin +184 (int (*)(...))QQuickItem::componentComplete +192 (int (*)(...))QQuickItem::keyPressEvent +200 (int (*)(...))QQuickItem::keyReleaseEvent +208 (int (*)(...))QQuickItem::inputMethodEvent +216 (int (*)(...))QQuickItem::focusInEvent +224 (int (*)(...))QQuickItem::focusOutEvent +232 (int (*)(...))QQuickItem::mousePressEvent +240 (int (*)(...))QQuickItem::mouseMoveEvent +248 (int (*)(...))QQuickItem::mouseReleaseEvent +256 (int (*)(...))QQuickItem::mouseDoubleClickEvent +264 (int (*)(...))QQuickItem::mouseUngrabEvent +272 (int (*)(...))QQuickItem::touchUngrabEvent +280 (int (*)(...))QQuickItem::wheelEvent +288 (int (*)(...))QQuickItem::touchEvent +296 (int (*)(...))QQuickItem::hoverEnterEvent +304 (int (*)(...))QQuickItem::hoverMoveEvent +312 (int (*)(...))QQuickItem::hoverLeaveEvent +320 (int (*)(...))QQuickItem::dragEnterEvent +328 (int (*)(...))QQuickItem::dragMoveEvent +336 (int (*)(...))QQuickItem::dragLeaveEvent +344 (int (*)(...))QQuickItem::dropEvent +352 (int (*)(...))QQuickItem::childMouseEventFilter +360 (int (*)(...))QQuickPaintedItem::updatePaintNode +368 (int (*)(...))QQuickPaintedItem::releaseResources +376 (int (*)(...))QQuickItem::updatePolish +384 (int (*)(...))__cxa_pure_virtual +392 (int (*)(...))-16 +400 (int (*)(...))(& _ZTI17QQuickPaintedItem) +408 0 +416 0 +424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv +432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv + +Class QQuickPaintedItem + size=32 align=8 + base size=32 base align=8 +QQuickPaintedItem (0x0x7f44653d4bc8) 0 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 16) + QQuickItem (0x0x7f44653b0540) 0 + primary-for QQuickPaintedItem (0x0x7f44653d4bc8) + QObject (0x0x7f44653e3c00) 0 + primary-for QQuickItem (0x0x7f44653b0540) + QQmlParserStatus (0x0x7f44653e3c60) 16 + vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 408) + +Class QQuickRenderControl::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickRenderControl::QPrivateSignal (0x0x7f4465451360) 0 empty + +Vtable for QQuickRenderControl +QQuickRenderControl::_ZTV19QQuickRenderControl: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QQuickRenderControl) +16 (int (*)(...))QQuickRenderControl::metaObject +24 (int (*)(...))QQuickRenderControl::qt_metacast +32 (int (*)(...))QQuickRenderControl::qt_metacall +40 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +48 (int (*)(...))QQuickRenderControl::~QQuickRenderControl +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QQuickRenderControl::renderWindow + +Class QQuickRenderControl + size=16 align=8 + base size=16 base align=8 +QQuickRenderControl (0x0x7f44653d4d68) 0 + vptr=((& QQuickRenderControl::_ZTV19QQuickRenderControl) + 16) + QObject (0x0x7f4465451300) 0 + primary-for QQuickRenderControl (0x0x7f44653d4d68) + +Class QQuickRenderTarget + size=8 align=8 + base size=8 base align=8 +QQuickRenderTarget (0x0x7f4465451540) 0 + +Class QQuickTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickTextDocument::QPrivateSignal (0x0x7f44654516c0) 0 empty + +Vtable for QQuickTextDocument +QQuickTextDocument::_ZTV18QQuickTextDocument: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QQuickTextDocument) +16 (int (*)(...))QQuickTextDocument::metaObject +24 (int (*)(...))QQuickTextDocument::qt_metacast +32 (int (*)(...))QQuickTextDocument::qt_metacall +40 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +48 (int (*)(...))QQuickTextDocument::~QQuickTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QQuickTextDocument + size=16 align=8 + base size=16 base align=8 +QQuickTextDocument (0x0x7f44653d4dd0) 0 + vptr=((& QQuickTextDocument::_ZTV18QQuickTextDocument) + 16) + QObject (0x0x7f4465451660) 0 + primary-for QQuickTextDocument (0x0x7f44653d4dd0) + +Class QSGGeometry::Attribute + size=16 align=4 + base size=16 base align=4 +QSGGeometry::Attribute (0x0x7f4465451ae0) 0 + +Class QSGGeometry::AttributeSet + size=16 align=8 + base size=16 base align=8 +QSGGeometry::AttributeSet (0x0x7f4465451b40) 0 + +Class QSGGeometry::Point2D + size=8 align=4 + base size=8 base align=4 +QSGGeometry::Point2D (0x0x7f4465451ba0) 0 + +Class QSGGeometry::TexturedPoint2D + size=16 align=4 + base size=16 base align=4 +QSGGeometry::TexturedPoint2D (0x0x7f4465451c00) 0 + +Class QSGGeometry::ColoredPoint2D + size=12 align=4 + base size=12 base align=4 +QSGGeometry::ColoredPoint2D (0x0x7f4465451c60) 0 + +Vtable for QSGGeometry +QSGGeometry::_ZTV11QSGGeometry: 4 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGGeometry) +16 (int (*)(...))QSGGeometry::~QSGGeometry +24 (int (*)(...))QSGGeometry::~QSGGeometry + +Class QSGGeometry + size=128 align=8 + base size=128 base align=8 +QSGGeometry (0x0x7f4465451a80) 0 + vptr=((& QSGGeometry::_ZTV11QSGGeometry) + 16) + +Vtable for QSGNode +QSGNode::_ZTV7QSGNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QSGNode) +16 (int (*)(...))QSGNode::~QSGNode +24 (int (*)(...))QSGNode::~QSGNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGNode + size=72 align=8 + base size=72 base align=8 +QSGNode (0x0x7f446549e660) 0 + vptr=((& QSGNode::_ZTV7QSGNode) + 16) + +Vtable for QSGBasicGeometryNode +QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGBasicGeometryNode) +16 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +24 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGBasicGeometryNode + size=104 align=8 + base size=104 base align=8 +QSGBasicGeometryNode (0x0x7f44650d20d0) 0 + vptr=((& QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode) + 16) + QSGNode (0x0x7f446549eea0) 0 + primary-for QSGBasicGeometryNode (0x0x7f44650d20d0) + +Vtable for QSGGeometryNode +QSGGeometryNode::_ZTV15QSGGeometryNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSGGeometryNode) +16 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +24 (int (*)(...))QSGGeometryNode::~QSGGeometryNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGGeometryNode + size=136 align=8 + base size=136 base align=8 +QSGGeometryNode (0x0x7f44650d2138) 0 + vptr=((& QSGGeometryNode::_ZTV15QSGGeometryNode) + 16) + QSGBasicGeometryNode (0x0x7f44650d21a0) 0 + primary-for QSGGeometryNode (0x0x7f44650d2138) + QSGNode (0x0x7f44650ee180) 0 + primary-for QSGBasicGeometryNode (0x0x7f44650d21a0) + +Vtable for QSGClipNode +QSGClipNode::_ZTV11QSGClipNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGClipNode) +16 (int (*)(...))QSGClipNode::~QSGClipNode +24 (int (*)(...))QSGClipNode::~QSGClipNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGClipNode + size=144 align=8 + base size=144 base align=8 +QSGClipNode (0x0x7f44650d2208) 0 + vptr=((& QSGClipNode::_ZTV11QSGClipNode) + 16) + QSGBasicGeometryNode (0x0x7f44650d2270) 0 + primary-for QSGClipNode (0x0x7f44650d2208) + QSGNode (0x0x7f44650ee360) 0 + primary-for QSGBasicGeometryNode (0x0x7f44650d2270) + +Vtable for QSGTransformNode +QSGTransformNode::_ZTV16QSGTransformNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGTransformNode) +16 (int (*)(...))QSGTransformNode::~QSGTransformNode +24 (int (*)(...))QSGTransformNode::~QSGTransformNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGTransformNode + size=208 align=8 + base size=208 base align=8 +QSGTransformNode (0x0x7f44650d22d8) 0 + vptr=((& QSGTransformNode::_ZTV16QSGTransformNode) + 16) + QSGNode (0x0x7f44650ee480) 0 + primary-for QSGTransformNode (0x0x7f44650d22d8) + +Vtable for QSGRootNode +QSGRootNode::_ZTV11QSGRootNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGRootNode) +16 (int (*)(...))QSGRootNode::~QSGRootNode +24 (int (*)(...))QSGRootNode::~QSGRootNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGRootNode + size=96 align=8 + base size=96 base align=8 +QSGRootNode (0x0x7f44650d2340) 0 + vptr=((& QSGRootNode::_ZTV11QSGRootNode) + 16) + QSGNode (0x0x7f44650ee5a0) 0 + primary-for QSGRootNode (0x0x7f44650d2340) + +Vtable for QSGOpacityNode +QSGOpacityNode::_ZTV14QSGOpacityNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGOpacityNode) +16 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +24 (int (*)(...))QSGOpacityNode::~QSGOpacityNode +32 (int (*)(...))QSGOpacityNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGOpacityNode + size=88 align=8 + base size=88 base align=8 +QSGOpacityNode (0x0x7f44650d2c30) 0 + vptr=((& QSGOpacityNode::_ZTV14QSGOpacityNode) + 16) + QSGNode (0x0x7f44650eef60) 0 + primary-for QSGOpacityNode (0x0x7f44650d2c30) + +Vtable for QSGNodeVisitor +QSGNodeVisitor::_ZTV14QSGNodeVisitor: 14 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSGNodeVisitor) +16 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +24 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor +32 (int (*)(...))QSGNodeVisitor::enterTransformNode +40 (int (*)(...))QSGNodeVisitor::leaveTransformNode +48 (int (*)(...))QSGNodeVisitor::enterClipNode +56 (int (*)(...))QSGNodeVisitor::leaveClipNode +64 (int (*)(...))QSGNodeVisitor::enterGeometryNode +72 (int (*)(...))QSGNodeVisitor::leaveGeometryNode +80 (int (*)(...))QSGNodeVisitor::enterOpacityNode +88 (int (*)(...))QSGNodeVisitor::leaveOpacityNode +96 (int (*)(...))QSGNodeVisitor::visitNode +104 (int (*)(...))QSGNodeVisitor::visitChildren + +Class QSGNodeVisitor + size=8 align=8 + base size=8 base align=8 +QSGNodeVisitor (0x0x7f4465146060) 0 nearly-empty + vptr=((& QSGNodeVisitor::_ZTV14QSGNodeVisitor) + 16) + +Vtable for QSGRendererInterface +QSGRendererInterface::_ZTV20QSGRendererInterface: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGRendererInterface) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QSGRendererInterface::getResource +48 (int (*)(...))QSGRendererInterface::getResource +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRendererInterface + size=8 align=8 + base size=8 base align=8 +QSGRendererInterface (0x0x7f4465146600) 0 nearly-empty + vptr=((& QSGRendererInterface::_ZTV20QSGRendererInterface) + 16) + +Class QQuickWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickWindow::QPrivateSignal (0x0x7f4465146d20) 0 empty + +Class QQuickWindow::GraphicsStateInfo + size=8 align=4 + base size=8 base align=4 +QQuickWindow::GraphicsStateInfo (0x0x7f4465146d80) 0 + +Vtable for QQuickWindow +QQuickWindow::_ZTV12QQuickWindow: 47 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QQuickWindow) +16 (int (*)(...))QQuickWindow::metaObject +24 (int (*)(...))QQuickWindow::qt_metacast +32 (int (*)(...))QQuickWindow::qt_metacall +40 (int (*)(...))QQuickWindow::~QQuickWindow +48 (int (*)(...))QQuickWindow::~QQuickWindow +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickWindow::resizeEvent +168 (int (*)(...))QWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QQuickWindow::focusInEvent +192 (int (*)(...))QQuickWindow::focusOutEvent +200 (int (*)(...))QQuickWindow::showEvent +208 (int (*)(...))QQuickWindow::hideEvent +216 (int (*)(...))QQuickWindow::closeEvent +224 (int (*)(...))QQuickWindow::keyPressEvent +232 (int (*)(...))QQuickWindow::keyReleaseEvent +240 (int (*)(...))QQuickWindow::mousePressEvent +248 (int (*)(...))QQuickWindow::mouseReleaseEvent +256 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +264 (int (*)(...))QQuickWindow::mouseMoveEvent +272 (int (*)(...))QQuickWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QQuickWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))-16 +320 (int (*)(...))(& _ZTI12QQuickWindow) +328 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD1Ev +336 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD0Ev +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickWindow + size=40 align=8 + base size=40 base align=8 +QQuickWindow (0x0x7f44650d2f08) 0 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 16) + QWindow (0x0x7f446516c230) 0 + primary-for QQuickWindow (0x0x7f44650d2f08) + QObject (0x0x7f4465146c60) 0 + primary-for QWindow (0x0x7f446516c230) + QSurface (0x0x7f4465146cc0) 16 + vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 328) + +Class QQuickView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QQuickView::QPrivateSignal (0x0x7f44651c9540) 0 empty + +Vtable for QQuickView +QQuickView::_ZTV10QQuickView: 47 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QQuickView) +16 (int (*)(...))QQuickView::metaObject +24 (int (*)(...))QQuickView::qt_metacast +32 (int (*)(...))QQuickView::qt_metacall +40 (int (*)(...))QQuickView::~QQuickView +48 (int (*)(...))QQuickView::~QQuickView +56 (int (*)(...))QQuickWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QQuickView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QQuickWindow::accessibleRoot +144 (int (*)(...))QQuickWindow::focusObject +152 (int (*)(...))QQuickWindow::exposeEvent +160 (int (*)(...))QQuickView::resizeEvent +168 (int (*)(...))QWindow::paintEvent +176 (int (*)(...))QWindow::moveEvent +184 (int (*)(...))QQuickWindow::focusInEvent +192 (int (*)(...))QQuickWindow::focusOutEvent +200 (int (*)(...))QQuickWindow::showEvent +208 (int (*)(...))QQuickWindow::hideEvent +216 (int (*)(...))QQuickWindow::closeEvent +224 (int (*)(...))QQuickView::keyPressEvent +232 (int (*)(...))QQuickView::keyReleaseEvent +240 (int (*)(...))QQuickView::mousePressEvent +248 (int (*)(...))QQuickView::mouseReleaseEvent +256 (int (*)(...))QQuickWindow::mouseDoubleClickEvent +264 (int (*)(...))QQuickView::mouseMoveEvent +272 (int (*)(...))QQuickWindow::wheelEvent +280 (int (*)(...))QWindow::touchEvent +288 (int (*)(...))QQuickWindow::tabletEvent +296 (int (*)(...))QWindow::nativeEvent +304 (int (*)(...))QWindow::surfaceHandle +312 (int (*)(...))-16 +320 (int (*)(...))(& _ZTI10QQuickView) +328 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD1Ev +336 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD0Ev +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QQuickView + size=40 align=8 + base size=40 base align=8 +QQuickView (0x0x7f44651cb068) 0 + vptr=((& QQuickView::_ZTV10QQuickView) + 16) + QQuickWindow (0x0x7f44651cb0d0) 0 + primary-for QQuickView (0x0x7f44651cb068) + QWindow (0x0x7f446516c9a0) 0 + primary-for QQuickWindow (0x0x7f44651cb0d0) + QObject (0x0x7f44651c9480) 0 + primary-for QWindow (0x0x7f446516c9a0) + QSurface (0x0x7f44651c94e0) 16 + vptr=((& QQuickView::_ZTV10QQuickView) + 328) + +Class QSGMaterialType + size=1 align=1 + base size=0 base align=1 +QSGMaterialType (0x0x7f44651c9840) 0 empty + +Class QSGMaterialShader::RenderState + size=16 align=8 + base size=16 base align=8 +QSGMaterialShader::RenderState (0x0x7f44651c9900) 0 + +Class QSGMaterialShader::GraphicsPipelineState + size=36 align=4 + base size=36 base align=4 +QSGMaterialShader::GraphicsPipelineState (0x0x7f44651c9b40) 0 + +Vtable for QSGMaterialShader +QSGMaterialShader::_ZTV17QSGMaterialShader: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGMaterialShader) +16 (int (*)(...))QSGMaterialShader::~QSGMaterialShader +24 (int (*)(...))QSGMaterialShader::~QSGMaterialShader +32 (int (*)(...))QSGMaterialShader::updateUniformData +40 (int (*)(...))QSGMaterialShader::updateSampledImage +48 (int (*)(...))QSGMaterialShader::updateGraphicsPipelineState + +Class QSGMaterialShader + size=16 align=8 + base size=16 base align=8 +QSGMaterialShader (0x0x7f44651c98a0) 0 + vptr=((& QSGMaterialShader::_ZTV17QSGMaterialShader) + 16) + +Vtable for QSGMaterial +QSGMaterial::_ZTV11QSGMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSGMaterial) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QSGMaterial::compare + +Class QSGMaterial + size=24 align=8 + base size=24 base align=8 +QSGMaterial (0x0x7f44652286c0) 0 + vptr=((& QSGMaterial::_ZTV11QSGMaterial) + 16) + +Vtable for QSGFlatColorMaterial +QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGFlatColorMaterial) +16 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +24 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial +32 (int (*)(...))QSGFlatColorMaterial::type +40 (int (*)(...))QSGFlatColorMaterial::createShader +48 (int (*)(...))QSGFlatColorMaterial::compare + +Class QSGFlatColorMaterial + size=40 align=8 + base size=40 base align=8 +QSGFlatColorMaterial (0x0x7f44651cb618) 0 + vptr=((& QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial) + 16) + QSGMaterial (0x0x7f4465228a80) 0 + primary-for QSGFlatColorMaterial (0x0x7f44651cb618) + +Vtable for QNativeInterface::QSGOpenGLTexture +QNativeInterface::QSGOpenGLTexture::_ZTVN16QNativeInterface16QSGOpenGLTextureE: 5 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface16QSGOpenGLTextureE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QSGOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QSGOpenGLTexture (0x0x7f4465228b40) 0 nearly-empty + vptr=((& QNativeInterface::QSGOpenGLTexture::_ZTVN16QNativeInterface16QSGOpenGLTextureE) + 16) + +Vtable for QNativeInterface::QSGVulkanTexture +QNativeInterface::QSGVulkanTexture::_ZTVN16QNativeInterface16QSGVulkanTextureE: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN16QNativeInterface16QSGVulkanTextureE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QNativeInterface::QSGVulkanTexture + size=8 align=8 + base size=8 base align=8 +QNativeInterface::QSGVulkanTexture (0x0x7f4465228c00) 0 nearly-empty + vptr=((& QNativeInterface::QSGVulkanTexture::_ZTVN16QNativeInterface16QSGVulkanTextureE) + 16) + +Class QSGTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTexture::QPrivateSignal (0x0x7f4465228d20) 0 empty + +Vtable for QSGTexture +QSGTexture::_ZTV10QSGTexture: 23 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSGTexture) +16 (int (*)(...))QSGTexture::metaObject +24 (int (*)(...))QSGTexture::qt_metacast +32 (int (*)(...))QSGTexture::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QSGTexture::rhiTexture +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QSGTexture::normalizedTextureSubRect +160 (int (*)(...))QSGTexture::isAtlasTexture +168 (int (*)(...))QSGTexture::removedFromAtlas +176 (int (*)(...))QSGTexture::commitTextureOperations + +Class QSGTexture + size=16 align=8 + base size=16 base align=8 +QSGTexture (0x0x7f44651cb680) 0 + vptr=((& QSGTexture::_ZTV10QSGTexture) + 16) + QObject (0x0x7f4465228cc0) 0 + primary-for QSGTexture (0x0x7f44651cb680) + +Class QSGDynamicTexture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGDynamicTexture::QPrivateSignal (0x0x7f4465228f60) 0 empty + +Vtable for QSGDynamicTexture +QSGDynamicTexture::_ZTV17QSGDynamicTexture: 24 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGDynamicTexture) +16 (int (*)(...))QSGDynamicTexture::metaObject +24 (int (*)(...))QSGDynamicTexture::qt_metacast +32 (int (*)(...))QSGDynamicTexture::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QSGTexture::rhiTexture +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QSGTexture::normalizedTextureSubRect +160 (int (*)(...))QSGTexture::isAtlasTexture +168 (int (*)(...))QSGTexture::removedFromAtlas +176 (int (*)(...))QSGTexture::commitTextureOperations +184 (int (*)(...))__cxa_pure_virtual + +Class QSGDynamicTexture + size=16 align=8 + base size=16 base align=8 +QSGDynamicTexture (0x0x7f44651cb6e8) 0 + vptr=((& QSGDynamicTexture::_ZTV17QSGDynamicTexture) + 16) + QSGTexture (0x0x7f44651cb750) 0 + primary-for QSGDynamicTexture (0x0x7f44651cb6e8) + QObject (0x0x7f4465228f00) 0 + primary-for QSGTexture (0x0x7f44651cb750) + +Vtable for QSGImageNode +QSGImageNode::_ZTV12QSGImageNode: 22 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QSGImageNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QSGImageNode + size=136 align=8 + base size=136 base align=8 +QSGImageNode (0x0x7f44651cb7b8) 0 + vptr=((& QSGImageNode::_ZTV12QSGImageNode) + 16) + QSGGeometryNode (0x0x7f44651cb820) 0 + primary-for QSGImageNode (0x0x7f44651cb7b8) + QSGBasicGeometryNode (0x0x7f44651cb888) 0 + primary-for QSGGeometryNode (0x0x7f44651cb820) + QSGNode (0x0x7f44652ab060) 0 + primary-for QSGBasicGeometryNode (0x0x7f44651cb888) + +Vtable for QSGNinePatchNode +QSGNinePatchNode::_ZTV16QSGNinePatchNode: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGNinePatchNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual + +Class QSGNinePatchNode + size=136 align=8 + base size=136 base align=8 +QSGNinePatchNode (0x0x7f44651cba28) 0 + vptr=((& QSGNinePatchNode::_ZTV16QSGNinePatchNode) + 16) + QSGGeometryNode (0x0x7f44651cba90) 0 + primary-for QSGNinePatchNode (0x0x7f44651cba28) + QSGBasicGeometryNode (0x0x7f44651cbaf8) 0 + primary-for QSGGeometryNode (0x0x7f44651cba90) + QSGNode (0x0x7f44652ab480) 0 + primary-for QSGBasicGeometryNode (0x0x7f44651cbaf8) + +Vtable for QSGRectangleNode +QSGRectangleNode::_ZTV16QSGRectangleNode: 10 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSGRectangleNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QSGRectangleNode + size=136 align=8 + base size=136 base align=8 +QSGRectangleNode (0x0x7f44651cbb60) 0 + vptr=((& QSGRectangleNode::_ZTV16QSGRectangleNode) + 16) + QSGGeometryNode (0x0x7f44651cbbc8) 0 + primary-for QSGRectangleNode (0x0x7f44651cbb60) + QSGBasicGeometryNode (0x0x7f44651cbc30) 0 + primary-for QSGGeometryNode (0x0x7f44651cbbc8) + QSGNode (0x0x7f44652ab4e0) 0 + primary-for QSGBasicGeometryNode (0x0x7f44651cbc30) + +Vtable for QSGRenderNode::RenderState +QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE: 11 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QSGRenderNode11RenderStateE) +16 0 +24 0 +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))QSGRenderNode::RenderState::get + +Class QSGRenderNode::RenderState + size=8 align=8 + base size=8 base align=8 +QSGRenderNode::RenderState (0x0x7f44652ab600) 0 nearly-empty + vptr=((& QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE) + 16) + +Vtable for QSGRenderNode +QSGRenderNode::_ZTV13QSGRenderNode: 12 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSGRenderNode) +16 0 +24 0 +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess +48 (int (*)(...))QSGRenderNode::changedStates +56 (int (*)(...))QSGRenderNode::prepare +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))QSGRenderNode::releaseResources +80 (int (*)(...))QSGRenderNode::flags +88 (int (*)(...))QSGRenderNode::rect + +Class QSGRenderNode + size=80 align=8 + base size=80 base align=8 +QSGRenderNode (0x0x7f44651cbc98) 0 + vptr=((& QSGRenderNode::_ZTV13QSGRenderNode) + 16) + QSGNode (0x0x7f44652ab5a0) 0 + primary-for QSGRenderNode (0x0x7f44651cbc98) + +Vtable for QSGSimpleRectNode +QSGSimpleRectNode::_ZTV17QSGSimpleRectNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSGSimpleRectNode) +16 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +24 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleRectNode + size=312 align=8 + base size=312 base align=8 +QSGSimpleRectNode (0x0x7f44651cbf70) 0 + vptr=((& QSGSimpleRectNode::_ZTV17QSGSimpleRectNode) + 16) + QSGGeometryNode (0x0x7f4464f16000) 0 + primary-for QSGSimpleRectNode (0x0x7f44651cbf70) + QSGBasicGeometryNode (0x0x7f4464f16068) 0 + primary-for QSGGeometryNode (0x0x7f4464f16000) + QSGNode (0x0x7f44652abc60) 0 + primary-for QSGBasicGeometryNode (0x0x7f4464f16068) + +Vtable for QSGOpaqueTextureMaterial +QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QSGOpaqueTextureMaterial) +16 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +24 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial +32 (int (*)(...))QSGOpaqueTextureMaterial::type +40 (int (*)(...))QSGOpaqueTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGOpaqueTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGOpaqueTextureMaterial (0x0x7f4464f160d0) 0 + vptr=((& QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial) + 16) + QSGMaterial (0x0x7f44652abd20) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7f4464f160d0) + +Vtable for QSGTextureMaterial +QSGTextureMaterial::_ZTV18QSGTextureMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureMaterial) +16 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +24 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial +32 (int (*)(...))QSGTextureMaterial::type +40 (int (*)(...))QSGTextureMaterial::createShader +48 (int (*)(...))QSGOpaqueTextureMaterial::compare + +Class QSGTextureMaterial + size=40 align=8 + base size=36 base align=8 +QSGTextureMaterial (0x0x7f4464f16138) 0 + vptr=((& QSGTextureMaterial::_ZTV18QSGTextureMaterial) + 16) + QSGOpaqueTextureMaterial (0x0x7f4464f161a0) 0 + primary-for QSGTextureMaterial (0x0x7f4464f16138) + QSGMaterial (0x0x7f4464f261e0) 0 + primary-for QSGOpaqueTextureMaterial (0x0x7f4464f161a0) + +Vtable for QSGSimpleTextureNode +QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode: 6 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QSGSimpleTextureNode) +16 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +24 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode +32 (int (*)(...))QSGNode::isSubtreeBlocked +40 (int (*)(...))QSGNode::preprocess + +Class QSGSimpleTextureNode + size=376 align=8 + base size=376 base align=8 +QSGSimpleTextureNode (0x0x7f4464f16208) 0 + vptr=((& QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode) + 16) + QSGGeometryNode (0x0x7f4464f16270) 0 + primary-for QSGSimpleTextureNode (0x0x7f4464f16208) + QSGBasicGeometryNode (0x0x7f4464f162d8) 0 + primary-for QSGGeometryNode (0x0x7f4464f16270) + QSGNode (0x0x7f4464f26240) 0 + primary-for QSGBasicGeometryNode (0x0x7f4464f162d8) + +Class QSGTextureProvider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSGTextureProvider::QPrivateSignal (0x0x7f4464f26900) 0 empty + +Vtable for QSGTextureProvider +QSGTextureProvider::_ZTV18QSGTextureProvider: 15 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSGTextureProvider) +16 (int (*)(...))QSGTextureProvider::metaObject +24 (int (*)(...))QSGTextureProvider::qt_metacast +32 (int (*)(...))QSGTextureProvider::qt_metacall +40 0 +48 0 +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSGTextureProvider + size=16 align=8 + base size=16 base align=8 +QSGTextureProvider (0x0x7f4464f16478) 0 + vptr=((& QSGTextureProvider::_ZTV18QSGTextureProvider) + 16) + QObject (0x0x7f4464f268a0) 0 + primary-for QSGTextureProvider (0x0x7f4464f16478) + +Vtable for QSGVertexColorMaterial +QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial: 7 entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QSGVertexColorMaterial) +16 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +24 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial +32 (int (*)(...))QSGVertexColorMaterial::type +40 (int (*)(...))QSGVertexColorMaterial::createShader +48 (int (*)(...))QSGVertexColorMaterial::compare + +Class QSGVertexColorMaterial + size=24 align=8 + base size=24 base align=8 +QSGVertexColorMaterial (0x0x7f4464f164e0) 0 + vptr=((& QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial) + 16) + QSGMaterial (0x0x7f4464f269c0) 0 + primary-for QSGVertexColorMaterial (0x0x7f4464f164e0) + +Class QQuickStyle + size=1 align=1 + base size=0 base align=1 +QQuickStyle (0x0x7f4464f26a20) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464f5ee40) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464f6d1e0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464f6d3c0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464f6d720) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464f6d900) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464f6dc60) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464f6dde0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464f8d120) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464f8d300) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = char; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464f8d660) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464f8d840) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464f8dba0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464f8dd80) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464faa120) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464faa300) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = char; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464faa660) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464fc8f00) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464fe12a0) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464fe1420) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long int; _Ret = long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464fe1780) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464fe1900) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long unsigned int; _Ret = long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464fe1c60) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464fe1de0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long int; _Ret = long long int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464ffc180) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464ffc300) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long long unsigned int; _Ret = long long unsigned int; _CharT = wchar_t; _Base = {int}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464ffc660) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464ffc7e0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = float; _Ret = float; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4464ffcb40) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f4464ffccc0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = double; _Ret = double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4465018060) 0 empty + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno + size=4 align=4 + base size=4 base align=4 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Save_errno (0x0x7f44650181e0) 0 + +Class __gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__stoa(_TRet (*)(const _CharT*, _CharT**, _Base ...), const char*, const _CharT*, std::size_t*, _Base ...) [with _TRet = long double; _Ret = long double; _CharT = wchar_t; _Base = {}; std::size_t = long unsigned int]::_Range_chk (0x0x7f4465018540) 0 empty + diff --git a/tests/auto/quickcontrols2/cmake/CMakeLists.txt b/tests/auto/quickcontrols2/cmake/CMakeLists.txt new file mode 100644 index 00000000000..7e9eb89a7df --- /dev/null +++ b/tests/auto/quickcontrols2/cmake/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.16) + +project(qmake_cmake_files) + +enable_testing() + +find_package(Qt5Core REQUIRED) + +include("${_Qt5CTestMacros}") + +test_module_includes( + QuickControls2 QQuickStyle +) diff --git a/tests/auto/quickcontrols2/controls/CMakeLists.txt b/tests/auto/quickcontrols2/controls/CMakeLists.txt new file mode 100644 index 00000000000..f3fa8382b60 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/CMakeLists.txt @@ -0,0 +1,10 @@ +# Generated from controls.pro. + +add_subdirectory(basic) +add_subdirectory(fusion) +add_subdirectory(imagine) +add_subdirectory(material) +add_subdirectory(universal) +if(WIN32) + add_subdirectory(windows) +endif() diff --git a/tests/auto/quickcontrols2/controls/basic/BLACKLIST b/tests/auto/quickcontrols2/controls/basic/BLACKLIST new file mode 100644 index 00000000000..bdb2af0b464 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/basic/BLACKLIST @@ -0,0 +1,10 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format + +# QTBUG-70597 +[Tumbler::test_itemsCorrectlyPositioned] +* + +# QTBUG-95750 +[RangeSlider::test_overlappingHandles] +b2qt +qnx diff --git a/tests/auto/quickcontrols2/controls/basic/CMakeLists.txt b/tests/auto/quickcontrols2/controls/basic/CMakeLists.txt new file mode 100644 index 00000000000..6ae45f14605 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/basic/CMakeLists.txt @@ -0,0 +1,40 @@ +# Generated from basic.pro. + +##################################################################### +## tst_basic Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_basic + GUI + QMLTEST + SOURCES + tst_basic.cpp + DEFINES + TST_CONTROLS_DATA=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../data\\\" + PUBLIC_LIBRARIES + Qt::Gui + Qt::QuickControls2 + Qt::QuickTemplates2 + TESTDATA ${test_data} +) + +# Make the QML files available to Creator's locator. +target_sources(tst_basic + PRIVATE + ${test_data} +) + +set_source_files_properties(${test_data} + PROPERTIES + HEADER_FILE_ONLY ON +) + +#### Keys ignored in scope 1:.:.:basic.pro:<TRUE>: +# OTHER_FILES = "$$PWD/../data/*.qml" +# TEMPLATE = "app" diff --git a/tests/auto/quickcontrols2/controls/basic/dependencies.qml b/tests/auto/quickcontrols2/controls/basic/dependencies.qml new file mode 100644 index 00000000000..f7d87422b5d --- /dev/null +++ b/tests/auto/quickcontrols2/controls/basic/dependencies.qml @@ -0,0 +1,5 @@ +import QtTest +import QtQuick +import QtQuick.Controls + +TestCase { } diff --git a/tests/auto/quickcontrols2/controls/basic/dummy_imports.qml b/tests/auto/quickcontrols2/controls/basic/dummy_imports.qml new file mode 100644 index 00000000000..580db56d124 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/basic/dummy_imports.qml @@ -0,0 +1,12 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQml +import QtQuick +import QtQuick.NativeStyle +import QtQuick.Layouts +import Qt.labs.settings +import Qt.labs.qmlmodels + +QtObject { } diff --git a/tests/auto/quickcontrols2/controls/basic/tst_basic.cpp b/tests/auto/quickcontrols2/controls/basic/tst_basic.cpp new file mode 100644 index 00000000000..95d7e36a38b --- /dev/null +++ b/tests/auto/quickcontrols2/controls/basic/tst_basic.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTest/quicktest.h> +#include <QtQuickControls2/qquickstyle.h> + +int main(int argc, char *argv[]) +{ + QTEST_SET_MAIN_SOURCE_PATH + qputenv("QML_NO_TOUCH_COMPRESSION", "1"); + QQuickStyle::setStyle("Basic"); + return quick_test_main(argc, argv, "tst_controls::Basic", TST_CONTROLS_DATA); +} diff --git a/tests/auto/quickcontrols2/controls/data/SignalSequenceSpy.qml b/tests/auto/quickcontrols2/controls/data/SignalSequenceSpy.qml new file mode 100644 index 00000000000..40718c09103 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/SignalSequenceSpy.qml @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +QtObject { + property QtObject target: null + // We could just listen to all signals (try { signal.connect(/*...*/) } catch (e)) + // if it weren't for the fact the spy is often declared as a property of the control, + // which creates a "spyChanged" signal, which leads to an unexpected spyChanged signal + // emission. However, we don't know what the property will be called, so the signals + // have to be listed explicitly. + property var signals: [] + property var expectedSequence: [] + property int sequenceIndex: 0 + property bool sequenceFailure: false + readonly property bool success: !sequenceFailure && sequenceIndex === expectedSequence.length + + function reset() { + sequenceIndex = 0 + sequenceFailure = false + } + + property QtObject __oldTarget: null + property var __connections: [] + + onExpectedSequenceChanged: reset() + + // We may call __setup from onTargetChanged and as we would read the signals property + // inside __setup, we may be initializing the binding for signals for the first time, which + // will write the value to the property and trigger onSignalsChanged and call __setup + // again. One easy way to protect against it is to evaluate those two dependencies upfront + onTargetChanged: __setup(target, signals) + onSignalsChanged: __setup(target, signals) + + function __setup(target, signals) { + if (__oldTarget) { + __connections.forEach(function (cx) { + __oldTarget[cx.name].disconnect(cx.method) + }) + __oldTarget = null + } + + __connections = [] + + if (!!target && !!signals && signals.length > 0) { + signals.forEach(function (signalName) { + var handlerName = "on" + signalName.substr(0, 1).toUpperCase() + signalName.substr(1) + var method = function() { __checkSignal(signalName, arguments) } + target[handlerName].connect(method) + __connections.push({ "name": handlerName, "method": method }) + }) + __oldTarget = target + } + } + + function __checkSignal(signalName, signalArgs) { + if (sequenceFailure) + return; + + if (sequenceIndex >= expectedSequence.length) { + console.warn("SignalSequenceSpy: Received unexpected signal '" + signalName + "' (none expected).") + sequenceFailure = true + return + } + + var expectedSignal = expectedSequence[sequenceIndex] + if (typeof expectedSignal === "string") { + if (expectedSignal === signalName) { + sequenceIndex++ + return + } + } else if (typeof expectedSignal === "object") { + var expectedSignalData = expectedSignal + expectedSignal = expectedSignalData[0] + if (expectedSignal === signalName) { + var expectedValues = expectedSignalData[1] + for (var p in expectedValues) { + if (target[p] != expectedValues[p]) { + console.warn("SignalSequenceSpy: Value mismatch for property '" + p + "' after '" + signalName + "' signal." + + __mismatchValuesFormat(target[p], expectedValues[p])) + sequenceFailure = true + return + } + } + sequenceIndex++ + return + } + } + console.warn("SignalSequenceSpy: Received unexpected signal (is \"" + expectedSignal + "\" listed in the signals array?)" + + __mismatchValuesFormat(signalName, expectedSignal)) + sequenceFailure = true + } + + function __mismatchValuesFormat(actual, expected) { + return "\n Actual : " + actual + + "\n Expected : " + expected + + "\n Sequence index: " + sequenceIndex + } +} diff --git a/tests/auto/quickcontrols2/controls/data/TestItem.qml b/tests/auto/quickcontrols2/controls/data/TestItem.qml new file mode 100644 index 00000000000..df81269ce18 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/TestItem.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Item { + id: item + property var createdCallback + property var destroyedCallback + Component.onCompleted: if (createdCallback) createdCallback(item) + Component.onDestruction: if (destroyedCallback) destroyedCallback(item) +} diff --git a/tests/auto/quickcontrols2/controls/data/TumblerDatePicker.qml b/tests/auto/quickcontrols2/controls/data/TumblerDatePicker.qml new file mode 100644 index 00000000000..c11b504b75d --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/TumblerDatePicker.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Row { + id: datePicker + + readonly property var days: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + + property alias dayTumbler: dayTumbler + property alias monthTumbler: monthTumbler + property alias yearTumbler: yearTumbler + + Tumbler { + id: dayTumbler + objectName: "dayTumbler" + + Component.onCompleted: updateModel() + + function updateModel() { + var previousIndex = dayTumbler.currentIndex; + var array = []; + var newDays = datePicker.days[monthTumbler.currentIndex]; + for (var i = 0; i < newDays; ++i) { + array.push(i + 1); + } + dayTumbler.model = array; + dayTumbler.currentIndex = Math.min(newDays - 1, previousIndex); + } + } + Tumbler { + id: monthTumbler + objectName: "monthTumbler" + model: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + onCurrentIndexChanged: dayTumbler.updateModel() + } + Tumbler { + id: yearTumbler + objectName: "yearTumbler" + model: ListModel { + objectName: "yearTumblerListModel" + Component.onCompleted: { + for (var i = 2000; i < 2100; ++i) { + append({value: i.toString()}); + } + } + } + } +} diff --git a/tests/auto/quickcontrols2/controls/data/TumblerListView.qml b/tests/auto/quickcontrols2/controls/data/TumblerListView.qml new file mode 100644 index 00000000000..a581c4327d6 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/TumblerListView.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ListView { + implicitWidth: 60 + implicitHeight: 200 + snapMode: ListView.SnapToItem + highlightRangeMode: ListView.StrictlyEnforceRange + preferredHighlightBegin: height / 2 - (height / parent.visibleItemCount / 2) + preferredHighlightEnd: height / 2 + (height / parent.visibleItemCount / 2) + clip: true + model: parent.model + delegate: Text { + objectName: text + text: "Custom" + modelData + opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2) + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } +} diff --git a/tests/auto/quickcontrols2/controls/data/TumblerPathView.qml b/tests/auto/quickcontrols2/controls/data/TumblerPathView.qml new file mode 100644 index 00000000000..0f9be0e929a --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/TumblerPathView.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +PathView { + id: pathView + implicitWidth: 60 + implicitHeight: 200 + clip: true + pathItemCount: parent.visibleItemCount + 1 + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + dragMargin: width / 2 + model: parent.model + delegate: Text { + objectName: text + text: "Custom" + modelData + opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2) + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + path: Path { + startX: pathView.width / 2 + startY: -pathView.delegateHeight / 2 + PathLine { + x: pathView.width / 2 + y: pathView.pathItemCount * pathView.delegateHeight - pathView.delegateHeight / 2 + } + } + + property real delegateHeight: parent.availableHeight / parent.visibleItemCount +} diff --git a/tests/auto/quickcontrols2/controls/data/splitview/fillItemInMiddle.qml b/tests/auto/quickcontrols2/controls/data/splitview/fillItemInMiddle.qml new file mode 100644 index 00000000000..0acac9eb22f --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/splitview/fillItemInMiddle.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +SplitView { + anchors.fill: parent + + Rectangle { + objectName: "salmon" + color: objectName + implicitWidth: 25 + implicitHeight: 25 + } + Rectangle { + objectName: "navajowhite" + color: objectName + implicitWidth: 100 + implicitHeight: 100 + + SplitView.fillWidth: true + } + Rectangle { + objectName: "steelblue" + color: objectName + implicitWidth: 200 + implicitHeight: 200 + } +} diff --git a/tests/auto/quickcontrols2/controls/data/splitview/fillItemOnLeft.qml b/tests/auto/quickcontrols2/controls/data/splitview/fillItemOnLeft.qml new file mode 100644 index 00000000000..6f9c6e0b676 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/splitview/fillItemOnLeft.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +SplitView { + anchors.fill: parent + + Rectangle { + objectName: "salmon" + color: objectName + implicitWidth: 25 + implicitHeight: 25 + + SplitView.fillWidth: true + } + Rectangle { + objectName: "navajowhite" + color: objectName + implicitWidth: 200 + implicitHeight: 200 + } + Rectangle { + objectName: "steelblue" + color: objectName + implicitWidth: 200 + implicitHeight: 200 + } +} diff --git a/tests/auto/quickcontrols2/controls/data/splitview/fillItemOnTop.qml b/tests/auto/quickcontrols2/controls/data/splitview/fillItemOnTop.qml new file mode 100644 index 00000000000..2955aa61eba --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/splitview/fillItemOnTop.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +SplitView { + anchors.fill: parent + orientation: Qt.Vertical + + Rectangle { + objectName: "salmon" + color: objectName + implicitWidth: 25 + implicitHeight: 25 + + SplitView.fillHeight: true + } + Rectangle { + objectName: "navajowhite" + color: objectName + implicitWidth: 200 + implicitHeight: 200 + } + Rectangle { + objectName: "steelblue" + color: objectName + implicitWidth: 200 + implicitHeight: 200 + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_abstractbutton.qml b/tests/auto/quickcontrols2/controls/data/tst_abstractbutton.qml new file mode 100644 index 00000000000..2c9ce4d9ed8 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_abstractbutton.qml @@ -0,0 +1,976 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "AbstractButton" + + Component { + id: button + AbstractButton { + width: 100 + height: 50 + } + } + + Component { + id: item + Item { } + } + + Component { + id: action + Action { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_text() { + var control = createTemporaryObject(button, testCase); + verify(control); + + compare(control.text, ""); + control.text = "Button"; + compare(control.text, "Button"); + control.text = ""; + compare(control.text, ""); + } + + function test_baseline() { + var control = createTemporaryObject(button, testCase, {padding: 6}) + verify(control) + compare(control.baselineOffset, 0) + control.contentItem = item.createObject(control, {baselineOffset: 12}) + compare(control.baselineOffset, 18) + } + + function test_implicitSize() { + var control = createTemporaryObject(button, testCase) + verify(control) + + compare(control.implicitWidth, 0) + compare(control.implicitHeight, 0) + + control.contentItem = item.createObject(control, {implicitWidth: 10, implicitHeight: 20}) + compare(control.implicitWidth, 10) + compare(control.implicitHeight, 20) + + control.background = item.createObject(control, {implicitWidth: 20, implicitHeight: 30}) + compare(control.implicitWidth, 20) + compare(control.implicitHeight, 30) + + control.padding = 100 + compare(control.implicitWidth, 210) + compare(control.implicitHeight, 220) + } + + function test_pressPoint_data() { + return [ + { tag: "mouse", mouse: true }, + { tag: "touch", touch: true } + ] + } + + function test_pressPoint(data) { + var control = createTemporaryObject(button, testCase, {width: 100, height: 40}) + verify(control) + + var pressXChanges = 0 + var pressYChanges = 0 + + var pressXSpy = signalSpy.createObject(control, {target: control, signalName: "pressXChanged"}) + verify(pressXSpy.valid) + + var pressYSpy = signalSpy.createObject(control, {target: control, signalName: "pressYChanged"}) + verify(pressYSpy.valid) + + compare(control.pressX, 0) + compare(control.pressY, 0) + + var touch = data.touch ? touchEvent(control) : null + + if (data.touch) + touch.press(0, control, control.width / 2, control.height / 2).commit() + else + mousePress(control, control.width / 2, control.height / 2) + compare(control.pressX, control.width / 2) + compare(control.pressY, control.height / 2) + compare(pressXSpy.count, ++pressXChanges) + compare(pressYSpy.count, ++pressYChanges) + + if (data.touch) + touch.move(0, control, control.width / 2, control.height / 2).commit() + else + mouseMove(control, control.width / 2, control.height / 2) + compare(control.pressX, control.width / 2) + compare(control.pressY, control.height / 2) + compare(pressXSpy.count, pressXChanges) + compare(pressYSpy.count, pressYChanges) + + if (data.touch) + touch.move(0, control, control.width / 4, control.height / 4).commit() + else + mouseMove(control, control.width / 4, control.height / 4) + compare(control.pressX, control.width / 4) + compare(control.pressY, control.height / 4) + compare(pressXSpy.count, ++pressXChanges) + compare(pressYSpy.count, ++pressYChanges) + + if (data.touch) + touch.move(0, control, 0, 0).commit() + else + mouseMove(control, 0, 0) + compare(control.pressX, 0) + compare(control.pressY, 0) + compare(pressXSpy.count, ++pressXChanges) + compare(pressYSpy.count, ++pressYChanges) + + if (data.touch) + touch.move(0, control, -control.width / 2, -control.height / 2).commit() + else + mouseMove(control, -control.width / 2, -control.height / 2) + compare(control.pressX, -control.width / 2) + compare(control.pressY, -control.height / 2) + compare(pressXSpy.count, ++pressXChanges) + compare(pressYSpy.count, ++pressYChanges) + + if (data.touch) + touch.release(0, control, -control.width / 2, -control.height / 2).commit() + else + mouseRelease(control, -control.width / 2, -control.height / 2) + compare(control.pressX, -control.width / 2) + compare(control.pressY, -control.height / 2) + compare(pressXSpy.count, pressXChanges) + compare(pressYSpy.count, pressYChanges) + + if (data.touch) + touch.press(0, control, control.width - 1, control.height - 1).commit() + else + mousePress(control, control.width - 1, control.height - 1) + compare(control.pressX, control.width - 1) + compare(control.pressY, control.height - 1) + compare(pressXSpy.count, ++pressXChanges) + compare(pressYSpy.count, ++pressYChanges) + + if (data.touch) + touch.move(0, control, control.width + 1, control.height + 1).commit() + else + mouseMove(control, control.width + 1, control.height + 1) + compare(control.pressX, control.width + 1) + compare(control.pressY, control.height + 1) + compare(pressXSpy.count, ++pressXChanges) + compare(pressYSpy.count, ++pressYChanges) + + if (data.touch) + touch.release(0, control, control.width + 2, control.height + 2).commit() + else + mouseRelease(control, control.width + 2, control.height + 2) + compare(control.pressX, control.width + 2) + compare(control.pressY, control.height + 2) + compare(pressXSpy.count, ++pressXChanges) + compare(pressYSpy.count, ++pressYChanges) + } + + function test_pressAndHold() { + var control = createTemporaryObject(button, testCase, {checkable: true}) + verify(control) + + var pressAndHoldSpy = signalSpy.createObject(control, {target: control, signalName: "pressAndHold"}) + verify(pressAndHoldSpy.valid) + + mousePress(control) + pressAndHoldSpy.wait() + compare(control.checked, false) + + mouseRelease(control) + compare(control.checked, false) + } + + Component { + id: keyCatcher + Item { + property int lastKeyPress: -1 + property int lastKeyRelease: -1 + Keys.onPressed: lastKeyPress = event.key + Keys.onReleased: lastKeyRelease = event.key + } + } + + function test_keyEvents_data() { + return [ + { tag: "space", key: Qt.Key_Space, result: -1 }, + { tag: "backspace", key: Qt.Key_Backspace, result: Qt.Key_Backspace } + ] + } + + function test_keyEvents(data) { + var container = createTemporaryObject(keyCatcher, testCase) + verify(container) + + var control = button.createObject(container) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + + keyPress(data.key) + compare(container.lastKeyPress, data.result) + + keyRelease(data.key) + compare(container.lastKeyRelease, data.result) + } + + function test_icon() { + var control = createTemporaryObject(button, testCase) + verify(control) + compare(control.icon.name, "") + compare(control.icon.source, "") + compare(control.icon.width, 0) + compare(control.icon.height, 0) + compare(control.icon.color, "#00000000") + + var iconSpy = signalSpy.createObject(control, { target: control, signalName: "iconChanged"} ) + verify(iconSpy.valid) + + control.icon.name = "test-name" + compare(control.icon.name, "test-name") + compare(iconSpy.count, 1) + + control.icon.source = "qrc:/test-source" + compare(control.icon.source, "qrc:/test-source") + compare(iconSpy.count, 2) + + control.icon.width = 32 + compare(control.icon.width, 32) + compare(iconSpy.count, 3) + + control.icon.height = 32 + compare(control.icon.height, 32) + compare(iconSpy.count, 4) + + control.icon.color = "#ff0000" + compare(control.icon.color, "#ff0000") + compare(iconSpy.count, 5) + } + + function test_action_data() { + return [ + { tag: "implicit text", property: "text", + initButton: undefined, initAction: "Action", + assignExpected: "Action", assignChanged: true, + resetExpected: "", resetChanged: true }, + { tag: "explicit text", property: "text", + initButton: "Button", initAction: "Action", + assignExpected: "Button", assignChanged: false, + resetExpected: "Button", resetChanged: false }, + { tag: "empty button text", property: "text", + initButton: "", initAction: "Action", + assignExpected: "", assignChanged: false, + resetExpected: "", resetChanged: false }, + { tag: "empty action text", property: "text", + initButton: "Button", initAction: "", + assignExpected: "Button", assignChanged: false, + resetExpected: "Button", resetChanged: false }, + { tag: "empty both text", property: "text", + initButton: undefined, initAction: "", + assignExpected: "", assignChanged: false, + resetExpected: "", resetChanged: false }, + + { tag: "modify button text", property: "text", + initButton: undefined, initAction: "Action", + assignExpected: "Action", assignChanged: true, + modifyButton: "Button2", + modifyButtonExpected: "Button2", modifyButtonChanged: true, + resetExpected: "Button2", resetChanged: false }, + { tag: "modify implicit action text", property: "text", + initButton: undefined, initAction: "Action", + assignExpected: "Action", assignChanged: true, + modifyAction: "Action2", + modifyActionExpected: "Action2", modifyActionChanged: true, + resetExpected: "", resetChanged: true }, + { tag: "modify explicit action text", property: "text", + initButton: "Button", initAction: "Action", + assignExpected: "Button", assignChanged: false, + modifyAction: "Action2", + modifyActionExpected: "Button", modifyActionChanged: false, + resetExpected: "Button", resetChanged: false }, + ] + } + + function test_action(data) { + var control = createTemporaryObject(button, testCase) + verify(control) + control[data.property] = data.initButton + + var act = action.createObject(control) + act[data.property] = data.initAction + + var spy = signalSpy.createObject(control, {target: control, signalName: data.property + "Changed"}) + verify(spy.valid) + + // assign action + spy.clear() + control.action = act + compare(control[data.property], data.assignExpected) + compare(spy.count, data.assignChanged ? 1 : 0) + + // modify button + if (data.hasOwnProperty("modifyButton")) { + spy.clear() + control[data.property] = data.modifyButton + compare(control[data.property], data.modifyButtonExpected) + compare(spy.count, data.modifyButtonChanged ? 1 : 0) + } + + // modify action + if (data.hasOwnProperty("modifyAction")) { + spy.clear() + act[data.property] = data.modifyAction + compare(control[data.property], data.modifyActionExpected) + compare(spy.count, data.modifyActionChanged ? 1 : 0) + } + + // reset action + spy.clear() + control.action = null + compare(control[data.property], data.resetExpected) + compare(spy.count, data.resetChanged ? 1 : 0) + } + + function test_actionIcon_data() { + var data = [] + + // Save duplicating the rows by reusing them with different properties of the same type. + // This means that the first loop will test icon.name and the second one will test icon.source. + var stringPropertyValueSuffixes = [ + { propertyName: "name", valueSuffix: "IconName" }, + { propertyName: "source", valueSuffix: "IconSource" } + ] + + for (var i = 0; i < stringPropertyValueSuffixes.length; ++i) { + var propertyName = stringPropertyValueSuffixes[i].propertyName + var valueSuffix = stringPropertyValueSuffixes[i].valueSuffix + + var buttonPropertyValue = "Button" + valueSuffix + var buttonPropertyValue2 = "Button" + valueSuffix + "2" + var actionPropertyValue = "Action" + valueSuffix + var actionPropertyValue2 = "Action" + valueSuffix + "2" + + data.push({ tag: "implicit " + propertyName, property: propertyName, + initButton: undefined, initAction: actionPropertyValue, + assignExpected: actionPropertyValue, assignChanged: true, + resetExpected: "", resetChanged: true }) + data.push({ tag: "explicit " + propertyName, property: propertyName, + initButton: buttonPropertyValue, initAction: actionPropertyValue, + assignExpected: buttonPropertyValue, assignChanged: false, + resetExpected: buttonPropertyValue, resetChanged: false }) + data.push({ tag: "empty button " + propertyName, property: propertyName, + initButton: "", initAction: actionPropertyValue, + assignExpected: "", assignChanged: false, + resetExpected: "", resetChanged: false }) + data.push({ tag: "empty action " + propertyName, property: propertyName, + initButton: buttonPropertyValue, initAction: "", + assignExpected: buttonPropertyValue, assignChanged: false, + resetExpected: buttonPropertyValue, resetChanged: false }) + data.push({ tag: "empty both " + propertyName, property: propertyName, + initButton: undefined, initAction: "", + assignExpected: "", assignChanged: false, + resetExpected: "", resetChanged: false }) + data.push({ tag: "modify button " + propertyName, property: propertyName, + initButton: undefined, initAction: actionPropertyValue, + assignExpected: actionPropertyValue, assignChanged: true, + modifyButton: buttonPropertyValue2, + modifyButtonExpected: buttonPropertyValue2, modifyButtonChanged: true, + resetExpected: buttonPropertyValue2, resetChanged: false }) + data.push({ tag: "modify implicit action " + propertyName, property: propertyName, + initButton: undefined, initAction: actionPropertyValue, + assignExpected: actionPropertyValue, assignChanged: true, + modifyAction: actionPropertyValue2, + modifyActionExpected: actionPropertyValue2, modifyActionChanged: true, + resetExpected: "", resetChanged: true }) + data.push({ tag: "modify explicit action " + propertyName, property: propertyName, + initButton: buttonPropertyValue, initAction: actionPropertyValue, + assignExpected: buttonPropertyValue, assignChanged: false, + modifyAction: actionPropertyValue2, + modifyActionExpected: buttonPropertyValue, modifyActionChanged: false, + resetExpected: buttonPropertyValue, resetChanged: false }) + } + + var intPropertyNames = [ + "width", + "height", + ] + + for (i = 0; i < intPropertyNames.length; ++i) { + propertyName = intPropertyNames[i] + + buttonPropertyValue = 20 + buttonPropertyValue2 = 21 + actionPropertyValue = 40 + actionPropertyValue2 = 41 + var defaultValue = 0 + + data.push({ tag: "implicit " + propertyName, property: propertyName, + initButton: undefined, initAction: actionPropertyValue, + assignExpected: actionPropertyValue, assignChanged: true, + resetExpected: defaultValue, resetChanged: true }) + data.push({ tag: "explicit " + propertyName, property: propertyName, + initButton: buttonPropertyValue, initAction: actionPropertyValue, + assignExpected: buttonPropertyValue, assignChanged: false, + resetExpected: buttonPropertyValue, resetChanged: false }) + data.push({ tag: "default button " + propertyName, property: propertyName, + initButton: defaultValue, initAction: actionPropertyValue, + assignExpected: defaultValue, assignChanged: false, + resetExpected: defaultValue, resetChanged: false }) + data.push({ tag: "default action " + propertyName, property: propertyName, + initButton: buttonPropertyValue, initAction: defaultValue, + assignExpected: buttonPropertyValue, assignChanged: false, + resetExpected: buttonPropertyValue, resetChanged: false }) + data.push({ tag: "default both " + propertyName, property: propertyName, + initButton: undefined, initAction: defaultValue, + assignExpected: defaultValue, assignChanged: false, + resetExpected: defaultValue, resetChanged: false }) + data.push({ tag: "modify button " + propertyName, property: propertyName, + initButton: undefined, initAction: actionPropertyValue, + assignExpected: actionPropertyValue, assignChanged: true, + modifyButton: buttonPropertyValue2, + modifyButtonExpected: buttonPropertyValue2, modifyButtonChanged: true, + resetExpected: buttonPropertyValue2, resetChanged: false }) + data.push({ tag: "modify implicit action " + propertyName, property: propertyName, + initButton: undefined, initAction: actionPropertyValue, + assignExpected: actionPropertyValue, assignChanged: true, + modifyAction: actionPropertyValue2, + modifyActionExpected: actionPropertyValue2, modifyActionChanged: true, + resetExpected: defaultValue, resetChanged: true }) + data.push({ tag: "modify explicit action " + propertyName, property: propertyName, + initButton: buttonPropertyValue, initAction: actionPropertyValue, + assignExpected: buttonPropertyValue, assignChanged: false, + modifyAction: actionPropertyValue2, + modifyActionExpected: buttonPropertyValue, modifyActionChanged: false, + resetExpected: buttonPropertyValue, resetChanged: false }) + } + + propertyName = "color" + buttonPropertyValue = "#aa0000" + buttonPropertyValue2 = "#ff0000" + actionPropertyValue = "#0000aa" + actionPropertyValue2 = "#0000ff" + defaultValue = "#00000000" + + data.push({ tag: "implicit " + propertyName, property: propertyName, + initButton: undefined, initAction: actionPropertyValue, + assignExpected: actionPropertyValue, assignChanged: true, + resetExpected: defaultValue, resetChanged: true }) + data.push({ tag: "explicit " + propertyName, property: propertyName, + initButton: buttonPropertyValue, initAction: actionPropertyValue, + assignExpected: buttonPropertyValue, assignChanged: false, + resetExpected: buttonPropertyValue, resetChanged: false }) + data.push({ tag: "default button " + propertyName, property: propertyName, + initButton: defaultValue, initAction: actionPropertyValue, + assignExpected: defaultValue, assignChanged: false, + resetExpected: defaultValue, resetChanged: false }) + data.push({ tag: "default action " + propertyName, property: propertyName, + initButton: buttonPropertyValue, initAction: defaultValue, + assignExpected: buttonPropertyValue, assignChanged: false, + resetExpected: buttonPropertyValue, resetChanged: false }) + data.push({ tag: "default both " + propertyName, property: propertyName, + initButton: undefined, initAction: defaultValue, + assignExpected: defaultValue, assignChanged: false, + resetExpected: defaultValue, resetChanged: false }) + data.push({ tag: "modify button " + propertyName, property: propertyName, + initButton: undefined, initAction: actionPropertyValue, + assignExpected: actionPropertyValue, assignChanged: true, + modifyButton: buttonPropertyValue2, + modifyButtonExpected: buttonPropertyValue2, modifyButtonChanged: true, + resetExpected: buttonPropertyValue2, resetChanged: false }) + data.push({ tag: "modify implicit action " + propertyName, property: propertyName, + initButton: undefined, initAction: actionPropertyValue, + assignExpected: actionPropertyValue, assignChanged: true, + modifyAction: actionPropertyValue2, + modifyActionExpected: actionPropertyValue2, modifyActionChanged: true, + resetExpected: defaultValue, resetChanged: true }) + data.push({ tag: "modify explicit action " + propertyName, property: propertyName, + initButton: buttonPropertyValue, initAction: actionPropertyValue, + assignExpected: buttonPropertyValue, assignChanged: false, + modifyAction: actionPropertyValue2, + modifyActionExpected: buttonPropertyValue, modifyActionChanged: false, + resetExpected: buttonPropertyValue, resetChanged: false }) + + return data; + } + + function test_actionIcon(data) { + var control = createTemporaryObject(button, testCase) + verify(control) + control.icon[data.property] = data.initButton + + var act = action.createObject(control) + act.icon[data.property] = data.initAction + + var spy = signalSpy.createObject(control, {target: control, signalName: "iconChanged"}) + verify(spy.valid) + + // assign action + spy.clear() + control.action = act + compare(control.icon[data.property], data.assignExpected) + compare(spy.count, data.assignChanged ? 1 : 0) + + // modify button + if (data.hasOwnProperty("modifyButton")) { + spy.clear() + control.icon[data.property] = data.modifyButton + compare(control.icon[data.property], data.modifyButtonExpected) + compare(spy.count, data.modifyButtonChanged ? 1 : 0) + } + + // modify action + if (data.hasOwnProperty("modifyAction")) { + spy.clear() + act.icon[data.property] = data.modifyAction + compare(control.icon[data.property], data.modifyActionExpected) + compare(spy.count, data.modifyActionChanged ? 1 : 0) + } + + // reset action + spy.clear() + control.action = null + compare(control.icon[data.property], data.resetExpected) + compare(spy.count, data.resetChanged ? 1 : 0) + } + + Component { + id: actionButton + AbstractButton { + width: 100 + height: 50 + action: Action { + text: "Default" + icon.name: checked ? "checked" : "unchecked" + icon.source: "qrc:/icons/default.png" + checkable: true + checked: true + enabled: false + } + } + } + + function test_actionButton() { + var control = createTemporaryObject(actionButton, testCase) + verify(control) + + // initial values + compare(control.text, "Default") + compare(control.checkable, true) + compare(control.checked, true) + compare(control.enabled, false) + compare(control.icon.name, "checked") + + var textSpy = signalSpy.createObject(control, { target: control, signalName: "textChanged" }) + verify(textSpy.valid) + + // changes via action + control.action.text = "Action" + control.action.checkable = false + control.action.checked = false + control.action.enabled = true + compare(control.text, "Action") // propagates + compare(control.checkable, false) // propagates + compare(control.checked, false) // propagates + compare(control.enabled, true) // propagates + compare(control.icon.name, "unchecked") // propagates + compare(textSpy.count, 1) + + // changes via button + control.text = "Button" + control.checkable = true + control.checked = true + control.enabled = false + control.icon.name = "default" + compare(control.text, "Button") + compare(control.checkable, true) + compare(control.checked, true) + compare(control.enabled, false) + compare(control.icon.name, "default") + compare(control.action.text, "Action") // does NOT propagate + compare(control.action.checkable, true) // propagates + compare(control.action.checked, true) // propagates + compare(control.action.enabled, true) // does NOT propagate + compare(control.action.icon.name, control.action.checked ? "checked" : "unchecked") // does NOT propagate + compare(textSpy.count, 2) + + // remove the action so that only the button's properties are left + control.action = null + compare(control.text, "Button") + compare(control.icon.name, "default") + compare(textSpy.count, 2) + + // setting an action while button has a particular property set + // shouldn't cause a change in the button's effective property value + var secondAction = createTemporaryObject(action, testCase) + verify(secondAction) + secondAction.text = "SecondAction" + control.action = secondAction + compare(control.text, "Button") + compare(textSpy.count, 2) + + // test setting an action whose properties aren't set + var thirdAction = createTemporaryObject(action, testCase) + verify(thirdAction) + control.action = thirdAction + compare(control.text, "Button") + compare(textSpy.count, 2) + } + + Component { + id: checkableButton + AbstractButton { + width: 100 + height: 50 + checkable: true + action: Action {} + } + } + + function test_checkable_button() { + var control = createTemporaryObject(checkableButton, testCase) + verify(control) + control.checked = false + control.forceActiveFocus() + verify(control.activeFocus) + verify(!control.checked) + verify(!control.action.checked) + + keyPress(Qt.Key_Space) + keyRelease(Qt.Key_Space) + + compare(control.action.checked, true) + compare(control.checked, true) + + keyPress(Qt.Key_Space) + + compare(control.action.checked, true) + compare(control.checked, true) + + keyRelease(Qt.Key_Space) + + compare(control.action.checked, false) + compare(control.checked, false) + + var checkedSpy = signalSpy.createObject(control, {target: control.action, signalName: "checkedChanged"}) + var toggledSpy = signalSpy.createObject(control, {target: control, signalName: "toggled"}) + var actionToggledSpy = signalSpy.createObject(control, {target: control.action, signalName: "toggled"}) + + verify(checkedSpy.valid) + verify(toggledSpy.valid) + verify(actionToggledSpy.valid) + + mousePress(control) + + compare(control.action.checked, false) + compare(control.checked, false) + + mouseRelease(control) + + checkedSpy.wait() + compare(checkedSpy.count, 1) + compare(actionToggledSpy.count, 1) + compare(toggledSpy.count, 1) + + compare(control.action.checked, true) + compare(control.checked, true) + + mousePress(control) + mouseRelease(control) + + compare(control.checked, false) + compare(control.action.checked, false) + } + + function test_trigger_data() { + return [ + {tag: "click", click: true, button: true, action: true, clicked: true, triggered: true}, + {tag: "click disabled button", click: true, button: false, action: true, clicked: false, triggered: false}, + {tag: "click disabled action", click: true, button: true, action: false, clicked: true, triggered: false}, + {tag: "trigger", trigger: true, button: true, action: true, clicked: true, triggered: true}, + {tag: "trigger disabled button", trigger: true, button: false, action: true, clicked: false, triggered: true}, + {tag: "trigger disabled action", trigger: true, button: true, action: false, clicked: false, triggered: false} + ] + } + + function test_trigger(data) { + var control = createTemporaryObject(actionButton, testCase, {"action.enabled": data.action, "enabled": data.button}) + verify(control) + + compare(control.enabled, data.button) + compare(control.action.enabled, data.action) + + var buttonSpy = signalSpy.createObject(control, {target: control, signalName: "clicked"}) + verify(buttonSpy.valid) + + var actionSpy = signalSpy.createObject(control, {target: control.action, signalName: "triggered"}) + verify(actionSpy.valid) + + if (data.click) + mouseClick(control) + else if (data.trigger) + control.action.trigger() + + compare(buttonSpy.count, data.clicked ? 1 : 0) + compare(actionSpy.count, data.triggered ? 1 : 0) + } + + function test_mnemonic() { + if (Qt.platform.os === "osx" || Qt.platform.os === "macos") + skip("Mnemonics are not used on macOS") + + var control = createTemporaryObject(button, testCase) + verify(control) + + control.text = "&Hello" + compare(control.text, "&Hello") + + var clickSpy = signalSpy.createObject(control, {target: control, signalName: "clicked"}) + verify(clickSpy.valid) + + keyClick(Qt.Key_H, Qt.AltModifier) + compare(clickSpy.count, 1) + + control.visible = false + keyClick(Qt.Key_H, Qt.AltModifier) + compare(clickSpy.count, 1) + + control.visible = true + keyClick(Qt.Key_H, Qt.AltModifier) + compare(clickSpy.count, 2) + + control.text = "Te&st" + compare(control.text, "Te&st") + + keyClick(Qt.Key_H, Qt.AltModifier) + compare(clickSpy.count, 2) + + keyClick(Qt.Key_S, Qt.AltModifier) + compare(clickSpy.count, 3) + + control.visible = false + control.text = "&Hidden" + keyClick(Qt.Key_H, Qt.AltModifier) + compare(clickSpy.count, 3) + + control.visible = true + keyClick(Qt.Key_H, Qt.AltModifier) + compare(clickSpy.count, 4) + + control.text = undefined + control.action = action.createObject(control, {text: "&Action"}) + + var actionSpy = signalSpy.createObject(control, {target: control.action, signalName: "triggered"}) + verify(actionSpy.valid) + + keyClick(Qt.Key_A, Qt.AltModifier) + compare(actionSpy.count, 1) + compare(clickSpy.count, 5) + + // ungrab on destruction (don't crash) + control.Component.onDestruction.connect(function() { control = null }) + control.destroy() + wait(0) + verify(!control) + keyClick(Qt.Key_H, Qt.AltModifier) + } + + Component { + id: actionGroup + ActionGroup { + Action { id: action1; checkable: true; checked: true } + Action { id: action2; checkable: true } + Action { id: action3; checkable: true } + } + } + + function test_actionGroup() { + var group = createTemporaryObject(actionGroup, testCase) + verify(group) + + var button1 = createTemporaryObject(button, testCase, {action: group.actions[0], width: 10, height: 10}) + var button2 = createTemporaryObject(button, testCase, {action: group.actions[1], width: 10, height: 10, y: 10}) + var button3 = createTemporaryObject(button, testCase, {action: group.actions[2], width: 10, height: 10, y: 20}) + + verify(button1) + compare(button1.checked, true) + compare(button1.action.checked, true) + + verify(button2) + compare(button2.checked, false) + compare(button2.action.checked, false) + + verify(button3) + compare(button3.checked, false) + compare(button3.action.checked, false) + + mouseClick(button2) + + compare(button1.checked, false) + compare(button1.action.checked, false) + + compare(button2.checked, true) + compare(button2.action.checked, true) + + compare(button3.checked, false) + compare(button3.action.checked, false) + } + + function test_clickedAfterLongPress() { + var control = createTemporaryObject(button, testCase, { text: "Hello" }) + verify(control) + + var clickedSpy = signalSpy.createObject(control, { target: control, signalName: "clicked" }) + verify(clickedSpy.valid) + + mousePress(control) + // Ensure that clicked is emitted when no handler is defined for the pressAndHold() signal. + // Note that even though signal spies aren't considered in QObject::isSignalConnected(), + // we can't use one here to check for pressAndHold(), because otherwise clicked() won't be emitted. + wait(Qt.styleHints.mousePressAndHoldInterval + 100) + mouseRelease(control) + compare(clickedSpy.count, 1) + } + + function test_doubleClick() { + let control = createTemporaryObject(button, testCase, { text: "Hello" }) + verify(control) + + let pressedSpy = signalSpy.createObject(control, { target: control, signalName: "pressed" }) + verify(pressedSpy.valid) + + let releasedSpy = signalSpy.createObject(control, { target: control, signalName: "released" }) + verify(releasedSpy.valid) + + let clickedSpy = signalSpy.createObject(control, { target: control, signalName: "clicked" }) + verify(clickedSpy.valid) + + let doubleClickedSpy = signalSpy.createObject(control, { target: control, signalName: "doubleClicked" }) + verify(doubleClickedSpy.valid) + + mouseDoubleClickSequence(control) + compare(pressedSpy.count, 2) + compare(releasedSpy.count, 2) + compare(clickedSpy.count, 1) + compare(doubleClickedSpy.count, 1) + } + + // It should be possible to quickly click a button whose doubleClicked signal + // is not connected to anything. + function test_fastClick() { + let control = createTemporaryObject(button, testCase, { text: "Hello" }) + verify(control) + + let pressedSpy = signalSpy.createObject(control, { target: control, signalName: "pressed" }) + verify(pressedSpy.valid) + + let releasedSpy = signalSpy.createObject(control, { target: control, signalName: "released" }) + verify(releasedSpy.valid) + + let clickedSpy = signalSpy.createObject(control, { target: control, signalName: "clicked" }) + verify(clickedSpy.valid) + + // Can't listen to doubleClicked because it would cause it to be emitted. + // We instead just check that clicked is emitted twice. + + mouseDoubleClickSequence(control) + compare(pressedSpy.count, 2) + compare(releasedSpy.count, 2) + compare(clickedSpy.count, 2) + + let touch = touchEvent(control) + touch.press(0, control) + touch.commit() + compare(pressedSpy.count, 3) + compare(releasedSpy.count, 2) + compare(clickedSpy.count, 2) + + touch.release(0, control) + touch.commit() + compare(pressedSpy.count, 3) + compare(releasedSpy.count, 3) + compare(clickedSpy.count, 3) + + touch.press(0, control) + touch.commit() + compare(pressedSpy.count, 4) + compare(releasedSpy.count, 3) + compare(clickedSpy.count, 3) + + touch.release(0, control) + touch.commit() + compare(pressedSpy.count, 4) + compare(releasedSpy.count, 4) + compare(clickedSpy.count, 4) + } + + function test_checkedShouldNotSetCheckable() { + let control = createTemporaryObject(button, testCase, { checked: true }) + verify(control) + + verify(!control.checkable) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_action.qml b/tests/auto/quickcontrols2/controls/data/tst_action.qml new file mode 100644 index 00000000000..c286b953442 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_action.qml @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls +import QtQuick.Templates as T + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "Action" + + Component { + id: component + Action { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_enabled() { + var action = createTemporaryObject(component, testCase) + verify(action) + + var spy = createTemporaryObject(signalSpy, testCase, {target: action, signalName: "triggered"}) + verify(spy.valid) + + action.trigger() + compare(spy.count, 1) + + action.enabled = false + action.trigger() + compare(spy.count, 1) + + action.enabled = undefined // reset + action.trigger() + compare(spy.count, 2) + } + + Component { + id: buttonAndMenu + Item { + property alias button: button + property alias menu: menu + property alias menuItem: menuItem + property alias action: sharedAction + property var lastSource + Action { + id: sharedAction + text: "Shared" + shortcut: "Ctrl+B" + onTriggered: (source) => lastSource = source + } + Button { + id: button + action: sharedAction + Menu { + id: menu + MenuItem { + id: menuItem + action: sharedAction + } + } + } + } + } + + function test_shared() { + var container = createTemporaryObject(buttonAndMenu, testCase) + verify(container) + + keyClick(Qt.Key_B, Qt.ControlModifier) + compare(container.lastSource, container.button) + + container.menu.open() + keyClick(Qt.Key_B, Qt.ControlModifier) + compare(container.lastSource, container.menuItem) + + tryVerify(function() { return !container.menu.visible }) + keyClick(Qt.Key_B, Qt.ControlModifier) + compare(container.lastSource, container.button) + + container.button.visible = false + keyClick(Qt.Key_B, Qt.ControlModifier) + compare(container.lastSource, container.action) + } + + Component { + id: actionAndRepeater + Item { + property alias action: testAction + Action { + id: testAction + shortcut: "Ctrl+A" + } + Repeater { + model: 1 + Button { + action: testAction + } + } + } + } + + function test_repeater() { + var container = createTemporaryObject(actionAndRepeater, testCase) + verify(container) + + var spy = signalSpy.createObject(container, {target: container.action, signalName: "triggered"}) + verify(spy.valid) + + keyClick(Qt.Key_A, Qt.ControlModifier) + compare(spy.count, 1) + } + + Component { + id: shortcutBinding + Item { + Action { + id: action + shortcut: StandardKey.Copy + } + + Shortcut { + id: indirectShortcut + sequences: [ action.shortcut ] + } + + Shortcut { + id: directShortcut + sequences: [ StandardKey.Copy ] + } + + property alias indirect: indirectShortcut; + property alias direct: directShortcut + } + } + + function test_shortcutBinding() { + var container = createTemporaryObject(shortcutBinding, testCase); + verify(container) + compare(container.indirect.nativeText, container.direct.nativeText); + } + + Component { + id: shortcutCleanup + Item { + property alias page: page + property alias action: action + property alias menu: menu + Item { + id: page + Action { + id: action + text: "action" + shortcut: "Insert" + } + Menu { + id: menu + MenuItem { action: action } + } + } + } + } + + function test_shortcutCleanup() { + { + var container = createTemporaryObject(shortcutCleanup, testCase); + verify(container) + container.action.shortcut = "Delete" + container.menu.open() + container.page.destroy() + tryVerify(function() { return !container.page }) + } + keyClick(Qt.Key_Delete, Qt.NoModifier) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_actiongroup.qml b/tests/auto/quickcontrols2/controls/data/tst_actiongroup.qml new file mode 100644 index 00000000000..e4ea5679da2 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_actiongroup.qml @@ -0,0 +1,400 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "ActionGroup" + + Component { + id: actionGroup + ActionGroup { } + } + + Component { + id: nonExclusiveGroup + ActionGroup { exclusive: false } + } + + Component { + id: declarativeGroup + ActionGroup { + Action { text: "First" } + Action { text: "Second" } + Action { text: "Third" } + } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_null() { + var group = createTemporaryObject(actionGroup, testCase) + verify(group) + + group.addAction(null) + group.removeAction(null) + } + + Component { + id: action + Action { } + } + + function test_defaults() { + var group = createTemporaryObject(actionGroup, testCase) + verify(group) + compare(group.actions.length, 0) + compare(group.checkedAction, null) + compare(group.exclusive, true) + } + + function test_current() { + var group = createTemporaryObject(actionGroup, testCase) + verify(group) + + var checkedActionSpy = createTemporaryObject(signalSpy, testCase, {target: group, signalName: "checkedActionChanged"}) + verify(checkedActionSpy.valid) + verify(!group.checkedAction) + + var action1 = createTemporaryObject(action, testCase, {checked: true}) + var action2 = createTemporaryObject(action, testCase, {checked: false}) + var action3 = createTemporaryObject(action, testCase, {checked: true, objectName: "3"}) + + // add checked + group.addAction(action1) + compare(group.checkedAction, action1) + compare(action1.checked, true) + compare(action2.checked, false) + compare(action3.checked, true) + compare(checkedActionSpy.count, 1) + + // add non-checked + group.addAction(action2) + compare(group.checkedAction, action1) + compare(action1.checked, true) + compare(action2.checked, false) + compare(action3.checked, true) + compare(checkedActionSpy.count, 1) + + // add checked + group.addAction(action3) + compare(group.checkedAction, action3) + compare(action1.checked, false) + compare(action2.checked, false) + compare(action3.checked, true) + compare(checkedActionSpy.count, 2) + + // change current + group.checkedAction = action2 + compare(group.checkedAction, action2) + compare(action1.checked, false) + compare(action2.checked, true) + compare(action3.checked, false) + compare(checkedActionSpy.count, 3) + + // check + action1.checked = true + compare(group.checkedAction, action1) + compare(action1.checked, true) + compare(action2.checked, false) + compare(action3.checked, false) + compare(checkedActionSpy.count, 4) + + // remove non-checked + group.removeAction(action2) + compare(group.checkedAction, action1) + compare(action1.checked, true) + compare(action2.checked, false) + compare(action3.checked, false) + compare(checkedActionSpy.count, 4) + + // remove checked + group.removeAction(action1) + verify(!group.checkedAction) + compare(action1.checked, false) + compare(action2.checked, false) + compare(action3.checked, false) + compare(checkedActionSpy.count, 5) + } + + function test_actions() { + var group = createTemporaryObject(actionGroup, testCase) + verify(group) + + var actionsSpy = createTemporaryObject(signalSpy, testCase, {target: group, signalName: "actionsChanged"}) + verify(actionsSpy.valid) + + compare(group.actions.length, 0) + compare(group.checkedAction, null) + + var action1 = createTemporaryObject(action, testCase, {checked: true}) + var action2 = createTemporaryObject(action, testCase, {checked: false}) + + group.actions = [action1, action2] + compare(group.actions.length, 2) + compare(group.actions[0], action1) + compare(group.actions[1], action2) + compare(group.checkedAction, action1) + compare(actionsSpy.count, 2) + + var action3 = createTemporaryObject(action, testCase, {checked: true}) + + group.addAction(action3) + compare(group.actions.length, 3) + compare(group.actions[0], action1) + compare(group.actions[1], action2) + compare(group.actions[2], action3) + compare(group.checkedAction, action3) + compare(actionsSpy.count, 3) + + group.removeAction(action1) + compare(group.actions.length, 2) + compare(group.actions[0], action2) + compare(group.actions[1], action3) + compare(group.checkedAction, action3) + compare(actionsSpy.count, 4) + + group.actions = [] + compare(group.actions.length, 0) + tryCompare(group, "checkedAction", null) + compare(actionsSpy.count, 5) + } + + function test_declarative() { + var group = createTemporaryObject(declarativeGroup, testCase) + verify(group) + + compare(group.actions.length, 3) + compare(group.actions[0].text, "First") + compare(group.actions[1].text, "Second") + compare(group.actions[2].text, "Third") + } + + function test_triggered_data() { + return [ + {tag: "exclusive", exclusive: true}, + {tag: "non-exclusive", exclusive: false} + ] + } + + function test_triggered(data) { + var group = createTemporaryObject(actionGroup, testCase, {exclusive: data.exclusive}) + verify(group) + + var triggeredSpy = createTemporaryObject(signalSpy, testCase, {target: group, signalName: "triggered"}) + verify(triggeredSpy.valid) + + var action1 = createTemporaryObject(action, testCase) + var action2 = createTemporaryObject(action, testCase) + + group.addAction(action1) + group.addAction(action2) + + action1.triggered() + compare(triggeredSpy.count, 1) + compare(triggeredSpy.signalArguments[0][0], action1) + + action2.triggered() + compare(triggeredSpy.count, 2) + compare(triggeredSpy.signalArguments[1][0], action2) + } + + Component { + id: attachedGroup + Item { + property ActionGroup group: ActionGroup { id: group } + property Action action1: Action { ActionGroup.group: group } + property Action action2: Action { ActionGroup.group: group } + property Action action3: Action { ActionGroup.group: group } + } + } + + function test_attached() { + var container = createTemporaryObject(attachedGroup, testCase) + verify(container) + + verify(!container.group.checkedAction) + + container.action1.checked = true + compare(container.group.checkedAction, container.action1) + compare(container.action1.checked, true) + compare(container.action2.checked, false) + compare(container.action3.checked, false) + + container.action2.checked = true + compare(container.group.checkedAction, container.action2) + compare(container.action1.checked, false) + compare(container.action2.checked, true) + compare(container.action3.checked, false) + + container.action3.checked = true + compare(container.group.checkedAction, container.action3) + compare(container.action1.checked, false) + compare(container.action2.checked, false) + compare(container.action3.checked, true) + } + + function test_actionDestroyed() { + var group = createTemporaryObject(actionGroup, testCase) + verify(group) + + var actionsSpy = createTemporaryObject(signalSpy, testCase, {target: group, signalName: "actionsChanged"}) + verify(actionsSpy.valid) + + var action1 = createTemporaryObject(action, testCase, {objectName: "action1", checked: true}) + + group.addAction(action1) + compare(group.actions.length, 1) + compare(group.actions[0], action1) + compare(group.checkedAction, action1) + compare(actionsSpy.count, 1) + + action1.destroy() + wait(0) + compare(group.actions.length, 0) + compare(group.checkedAction, null) + compare(actionsSpy.count, 2) + } + + function test_nonExclusive() { + var group = createTemporaryObject(nonExclusiveGroup, testCase) + verify(group) + + var action1 = createTemporaryObject(action, testCase, {checked: true}) + group.addAction(action1) + compare(action1.checked, true) + compare(group.checkedAction, null) + + var action2 = createTemporaryObject(action, testCase, {checked: true}) + group.addAction(action2) + compare(action1.checked, true) + compare(action2.checked, true) + compare(group.checkedAction, null) + + action1.checked = false + compare(action1.checked, false) + compare(action2.checked, true) + compare(group.checkedAction, null) + + action2.checked = false + compare(action1.checked, false) + compare(action2.checked, false) + compare(group.checkedAction, null) + + action1.checked = true + compare(action1.checked, true) + compare(action2.checked, false) + compare(group.checkedAction, null) + + action2.checked = true + compare(action1.checked, true) + compare(action2.checked, true) + compare(group.checkedAction, null) + } + + function test_enabled() { + var group = createTemporaryObject(actionGroup, testCase) + verify(group) + + compare(group.enabled, true) + + var action1 = createTemporaryObject(action, testCase) + var action2 = createTemporaryObject(action, testCase) + compare(action1.enabled, true) + compare(action2.enabled, true) + + var action1Spy = createTemporaryObject(signalSpy, testCase, {target: action1, signalName: "enabledChanged"}) + var action2Spy = createTemporaryObject(signalSpy, testCase, {target: action2, signalName: "enabledChanged"}) + verify(action1Spy.valid && action2Spy.valid) + + group.addAction(action1) + compare(action1.enabled, true) + compare(action2.enabled, true) + compare(action1Spy.count, 0) + compare(action2Spy.count, 0) + + group.enabled = false + compare(action1.enabled, false) + compare(action2.enabled, true) + compare(action1Spy.count, 1) + compare(action1Spy.signalArguments[0][0], false) + compare(action2Spy.count, 0) + + group.addAction(action2) + compare(action1.enabled, false) + compare(action2.enabled, false) + compare(action1Spy.count, 1) + compare(action2Spy.count, 1) + compare(action2Spy.signalArguments[0][0], false) + + action1.enabled = false + compare(action1.enabled, false) + compare(action1Spy.count, 2) + compare(action1Spy.signalArguments[1][0], false) + compare(action2Spy.count, 1) + + group.enabled = true + compare(action1.enabled, false) + compare(action2.enabled, true) + compare(action1Spy.count, 2) + compare(action2Spy.count, 2) + compare(action2Spy.signalArguments[1][0], true) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_busyindicator.qml b/tests/auto/quickcontrols2/controls/data/tst_busyindicator.qml new file mode 100644 index 00000000000..9353c338281 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_busyindicator.qml @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "BusyIndicator" + + Component { + id: busyIndicator + BusyIndicator { } + } + + Component { + id: mouseArea + MouseArea { } + } + + function test_running() { + var control = createTemporaryObject(busyIndicator, testCase) + verify(control) + + compare(control.running, true) + control.running = false + compare(control.running, false) + } + + // QTBUG-61785 + function test_mouseArea() { + var ma = createTemporaryObject(mouseArea, testCase, {width: testCase.width, height: testCase.height}) + verify(ma) + + var control = busyIndicator.createObject(ma, {width: testCase.width, height: testCase.height}) + verify(control) + + mousePress(control) + verify(ma.pressed) + + mouseRelease(control) + verify(!ma.pressed) + + var touch = touchEvent(control) + touch.press(0, control).commit() + verify(ma.pressed) + + touch.release(0, control).commit() + verify(!ma.pressed) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_button.qml b/tests/auto/quickcontrols2/controls/data/tst_button.qml new file mode 100644 index 00000000000..a6ec4faad95 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_button.qml @@ -0,0 +1,511 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "Button" + + Component { + id: button + Button { } + } + + Component { + id: signalSequenceSpy + SignalSequenceSpy { + signals: ["pressed", "released", "canceled", "clicked", "toggled", "doubleClicked", "pressedChanged", "downChanged", "checkedChanged"] + } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_text() { + var control = createTemporaryObject(button, testCase) + verify(control) + + compare(control.text, "") + control.text = "Button" + compare(control.text, "Button") + control.text = "" + compare(control.text, "") + } + + function test_mouse() { + var control = createTemporaryObject(button, testCase) + verify(control) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + // click + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // release outside + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }]] + mouseMove(control, control.width * 2, control.height * 2, 0) + compare(control.pressed, false) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["canceled", { "pressed": false }]] + mouseRelease(control, control.width * 2, control.height * 2, Qt.LeftButton) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // right button + sequenceSpy.expectedSequence = [] + mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.pressed, false) + + mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // double click + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + "released", + "clicked", + ["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + "doubleClicked", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + "released"] + mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton) + verify(sequenceSpy.success) + } + + function test_touch() { + var control = createTemporaryObject(button, testCase) + verify(control) + + var touch = touchEvent(control) + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + // click + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, false) + verify(sequenceSpy.success) + + // release outside + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }]] + touch.move(0, control, control.width * 2, control.height * 2).commit() + compare(control.pressed, false) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["canceled", { "pressed": false }]] + touch.release(0, control, control.width * 2, control.height * 2).commit() + compare(control.pressed, false) + verify(sequenceSpy.success) + } + + function test_multiTouch() { + var control1 = createTemporaryObject(button, testCase) + verify(control1) + + var pressedCount1 = 0 + + var pressedSpy1 = signalSpy.createObject(control1, {target: control1, signalName: "pressedChanged"}) + verify(pressedSpy1.valid) + + var touch = touchEvent(control1) + touch.press(0, control1, 0, 0).commit().move(0, control1, control1.width - 1, control1.height - 1).commit() + + compare(pressedSpy1.count, ++pressedCount1) + compare(control1.pressed, true) + + // second touch point on the same control is ignored + touch.stationary(0).press(1, control1, 0, 0).commit() + touch.stationary(0).move(1, control1).commit() + touch.stationary(0).release(1).commit() + + compare(pressedSpy1.count, pressedCount1) + compare(control1.pressed, true) + + var control2 = createTemporaryObject(button, testCase, {y: control1.height}) + verify(control2) + + var pressedCount2 = 0 + + var pressedSpy2 = signalSpy.createObject(control2, {target: control2, signalName: "pressedChanged"}) + verify(pressedSpy2.valid) + + // press the second button + touch.stationary(0).press(2, control2, 0, 0).commit() + + compare(pressedSpy2.count, ++pressedCount2) + compare(control2.pressed, true) + + compare(pressedSpy1.count, pressedCount1) + compare(control1.pressed, true) + + // release both buttons + touch.release(0, control1).release(2, control2).commit() + + compare(pressedSpy2.count, ++pressedCount2) + compare(control2.pressed, false) + + compare(pressedSpy1.count, ++pressedCount1) + compare(control1.pressed, false) + } + + function test_keys() { + var control = createTemporaryObject(button, testCase) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + // click + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + "released", + "clicked"] + keyClick(Qt.Key_Space) + verify(sequenceSpy.success) + + // no change + sequenceSpy.expectedSequence = [] + var keys = [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab] + for (var i = 0; i < keys.length; ++i) { + sequenceSpy.reset() + keyClick(keys[i]) + verify(sequenceSpy.success) + } + } + + function eventErrorMessage(actual, expected) { + return "actual event:" + JSON.stringify(actual) + ", expected event:" + JSON.stringify(expected) + } + + function test_autoRepeat() { + var control = createTemporaryObject(button, testCase) + verify(control) + + compare(control.autoRepeat, false) + control.autoRepeat = true + compare(control.autoRepeat, true) + + control.forceActiveFocus() + verify(control.activeFocus) + + var clickSpy = signalSpy.createObject(control, {target: control, signalName: "clicked"}) + verify(clickSpy.valid) + var pressSpy = signalSpy.createObject(control, {target: control, signalName: "pressed"}) + verify(pressSpy.valid) + var releaseSpy = signalSpy.createObject(control, {target: control, signalName: "released"}) + verify(releaseSpy.valid) + + // auto-repeat mouse click + mousePress(control) + compare(control.pressed, true) + clickSpy.wait() + clickSpy.wait() + compare(pressSpy.count, clickSpy.count + 1) + compare(releaseSpy.count, clickSpy.count) + mouseRelease(control) + compare(control.pressed, false) + compare(clickSpy.count, pressSpy.count) + compare(releaseSpy.count, pressSpy.count) + + clickSpy.clear() + pressSpy.clear() + releaseSpy.clear() + + // auto-repeat key click + keyPress(Qt.Key_Space) + compare(control.pressed, true) + clickSpy.wait() + clickSpy.wait() + compare(pressSpy.count, clickSpy.count + 1) + compare(releaseSpy.count, clickSpy.count) + keyRelease(Qt.Key_Space) + compare(control.pressed, false) + compare(clickSpy.count, pressSpy.count) + compare(releaseSpy.count, pressSpy.count) + + clickSpy.clear() + pressSpy.clear() + releaseSpy.clear() + + mousePress(control) + compare(control.pressed, true) + clickSpy.wait() + compare(pressSpy.count, clickSpy.count + 1) + compare(releaseSpy.count, clickSpy.count) + + // move inside during repeat -> continue repeat + mouseMove(control, control.width / 4, control.height / 4) + clickSpy.wait() + compare(pressSpy.count, clickSpy.count + 1) + compare(releaseSpy.count, clickSpy.count) + + clickSpy.clear() + pressSpy.clear() + releaseSpy.clear() + + // move outside during repeat -> stop repeat + mouseMove(control, -1, -1) + // NOTE: The following wait() is NOT a reliable way to test that the + // auto-repeat timer is not running, but there's no way dig into the + // private APIs from QML. If this test ever fails in the future, it + // indicates that the auto-repeat timer logic is broken. + wait(125) + compare(clickSpy.count, 0) + compare(pressSpy.count, 0) + compare(releaseSpy.count, 0) + + mouseRelease(control, -1, -1) + compare(control.pressed, false) + compare(clickSpy.count, 0) + compare(pressSpy.count, 0) + compare(releaseSpy.count, 0) + } + + function test_baseline() { + var control = createTemporaryObject(button, testCase) + verify(control) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + } + + function test_checkable() { + var control = createTemporaryObject(button, testCase) + verify(control) + verify(control.hasOwnProperty("checkable")) + verify(!control.checkable) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + "released", + "clicked"] + mouseClick(control) + verify(!control.checked) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + ["checkedChanged", { "checked": true }], + "toggled", + "released", + "clicked"] + control.checkable = true + mouseClick(control) + verify(control.checked) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + ["checkedChanged", { "checked": false }], + "toggled", + "released", + "clicked"] + mouseClick(control) + verify(!control.checked) + verify(sequenceSpy.success) + } + + function test_highlighted() { + var control = createTemporaryObject(button, testCase) + verify(control) + verify(!control.highlighted) + + control.highlighted = true + verify(control.highlighted) + } + + function test_spacing() { + var control = createTemporaryObject(button, testCase, { text: "Some long, long, long text" }) + verify(control) + verify(control.contentItem.implicitWidth + control.leftPadding + control.rightPadding > control.background.implicitWidth) + + var textLabel = findChild(control.contentItem, "label") + verify(textLabel) + + // The implicitWidth of the IconLabel that all buttons use as their contentItem + // should be equal to the implicitWidth of the Text while no icon is set. + compare(control.contentItem.implicitWidth, textLabel.implicitWidth) + + // That means that spacing shouldn't affect it. + control.spacing += 100 + compare(control.contentItem.implicitWidth, textLabel.implicitWidth) + + // The implicitWidth of the Button itself should, therefore, also never include spacing while no icon is set. + compare(control.implicitWidth, textLabel.implicitWidth + control.leftPadding + control.rightPadding) + } + + function test_display_data() { + return [ + { "tag": "IconOnly", display: Button.IconOnly }, + { "tag": "TextOnly", display: Button.TextOnly }, + { "tag": "TextUnderIcon", display: Button.TextUnderIcon }, + { "tag": "TextBesideIcon", display: Button.TextBesideIcon }, + { "tag": "IconOnly, mirrored", display: Button.IconOnly, mirrored: true }, + { "tag": "TextOnly, mirrored", display: Button.TextOnly, mirrored: true }, + { "tag": "TextUnderIcon, mirrored", display: Button.TextUnderIcon, mirrored: true }, + { "tag": "TextBesideIcon, mirrored", display: Button.TextBesideIcon, mirrored: true } + ] + } + + function test_display(data) { + var control = createTemporaryObject(button, testCase, { + text: "Button", + display: data.display, + "icon.source": "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png", + "LayoutMirroring.enabled": !!data.mirrored + }) + verify(control) + compare(control.icon.source, "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png") + + var iconImage = findChild(control.contentItem, "image") + var textLabel = findChild(control.contentItem, "label") + + switch (control.display) { + case Button.IconOnly: + verify(iconImage) + verify(!textLabel) + compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + break; + case Button.TextOnly: + verify(!iconImage) + verify(textLabel) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + case Button.TextUnderIcon: + verify(iconImage) + verify(textLabel) + compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + verify(iconImage.y < textLabel.y) + break; + case Button.TextBesideIcon: + verify(iconImage) + verify(textLabel) + if (control.mirrored) + verify(textLabel.x < iconImage.x) + else + verify(iconImage.x < textLabel.x) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + } + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_buttongroup.qml b/tests/auto/quickcontrols2/controls/data/tst_buttongroup.qml new file mode 100644 index 00000000000..138c0e24415 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_buttongroup.qml @@ -0,0 +1,465 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "ButtonGroup" + + Component { + id: buttonGroup + ButtonGroup { } + } + + Component { + id: nonExclusiveGroup + ButtonGroup { exclusive: false } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_null() { + var group = createTemporaryObject(buttonGroup, testCase) + verify(group) + + group.addButton(null) + group.removeButton(null) + } + + Component { + id: button + Button { } + } + + Component { + id: nonCheckable + QtObject { } + } + + function test_defaults() { + var group = createTemporaryObject(buttonGroup, testCase) + verify(group) + compare(group.buttons.length, 0) + compare(group.checkedButton, null) + compare(group.exclusive, true) + compare(group.checkState, Qt.Unchecked) + } + + function test_current() { + var group = createTemporaryObject(buttonGroup, testCase) + verify(group) + + var checkedButtonSpy = createTemporaryObject(signalSpy, testCase, {target: group, signalName: "checkedButtonChanged"}) + verify(checkedButtonSpy.valid) + verify(!group.checkedButton) + + var button1 = createTemporaryObject(button, testCase, {checked: true}) + var button2 = createTemporaryObject(button, testCase, {checked: false}) + var button3 = createTemporaryObject(button, testCase, {checked: true, objectName: "3"}) + + // add checked + group.addButton(button1) + compare(group.checkedButton, button1) + compare(button1.checked, true) + compare(button2.checked, false) + compare(button3.checked, true) + compare(checkedButtonSpy.count, 1) + + // add non-checked + group.addButton(button2) + compare(group.checkedButton, button1) + compare(button1.checked, true) + compare(button2.checked, false) + compare(button3.checked, true) + compare(checkedButtonSpy.count, 1) + + // add checked + group.addButton(button3) + compare(group.checkedButton, button3) + compare(button1.checked, false) + compare(button2.checked, false) + compare(button3.checked, true) + compare(checkedButtonSpy.count, 2) + + // change current + group.checkedButton = button2 + compare(group.checkedButton, button2) + compare(button1.checked, false) + compare(button2.checked, true) + compare(button3.checked, false) + compare(checkedButtonSpy.count, 3) + + // check + button1.checked = true + compare(group.checkedButton, button1) + compare(button1.checked, true) + compare(button2.checked, false) + compare(button3.checked, false) + compare(checkedButtonSpy.count, 4) + + // remove non-checked + group.removeButton(button2) + compare(group.checkedButton, button1) + compare(button1.checked, true) + compare(button2.checked, false) + compare(button3.checked, false) + compare(checkedButtonSpy.count, 4) + + // remove checked + group.removeButton(button1) + verify(!group.checkedButton) + compare(button1.checked, false) + compare(button2.checked, false) + compare(button3.checked, false) + compare(checkedButtonSpy.count, 5) + } + + function test_buttons() { + var group = createTemporaryObject(buttonGroup, testCase) + verify(group) + + var buttonsSpy = createTemporaryObject(signalSpy, testCase, {target: group, signalName: "buttonsChanged"}) + verify(buttonsSpy.valid) + + compare(group.buttons.length, 0) + compare(group.checkedButton, null) + + var button1 = createTemporaryObject(button, testCase, {checked: true}) + var button2 = createTemporaryObject(button, testCase, {checked: false}) + + group.buttons = [button1, button2] + compare(group.buttons.length, 2) + compare(group.buttons[0], button1) + compare(group.buttons[1], button2) + compare(group.checkedButton, button1) + compare(buttonsSpy.count, 2) + + var button3 = createTemporaryObject(button, testCase, {checked: true}) + + group.addButton(button3) + compare(group.buttons.length, 3) + compare(group.buttons[0], button1) + compare(group.buttons[1], button2) + compare(group.buttons[2], button3) + compare(group.checkedButton, button3) + compare(buttonsSpy.count, 3) + + group.removeButton(button1) + compare(group.buttons.length, 2) + compare(group.buttons[0], button2) + compare(group.buttons[1], button3) + compare(group.checkedButton, button3) + compare(buttonsSpy.count, 4) + + group.buttons = [] + compare(group.buttons.length, 0) + tryCompare(group, "checkedButton", null) + compare(buttonsSpy.count, 5) + } + + function test_clicked_data() { + return [ + {tag: "exclusive", exclusive: true}, + {tag: "non-exclusive", exclusive: false} + ] + } + + function test_clicked(data) { + var group = createTemporaryObject(buttonGroup, testCase, {exclusive: data.exclusive}) + verify(group) + + var clickedSpy = createTemporaryObject(signalSpy, testCase, {target: group, signalName: "clicked"}) + verify(clickedSpy.valid) + + var button1 = createTemporaryObject(button, testCase) + var button2 = createTemporaryObject(button, testCase) + + group.addButton(button1) + group.addButton(button2) + + button1.clicked() + compare(clickedSpy.count, 1) + compare(clickedSpy.signalArguments[0][0], button1) + + button2.clicked() + compare(clickedSpy.count, 2) + compare(clickedSpy.signalArguments[1][0], button2) + } + + Component { + id: checkBoxes + Item { + property ButtonGroup group: ButtonGroup { id: group } + property CheckBox control1: CheckBox { ButtonGroup.group: group } + property CheckBox control2: CheckBox { ButtonGroup.group: group } + property CheckBox control3: CheckBox { ButtonGroup.group: group } + } + } + + Component { + id: radioButtons + Item { + property ButtonGroup group: ButtonGroup { id: group } + property RadioButton control1: RadioButton { ButtonGroup.group: group } + property RadioButton control2: RadioButton { ButtonGroup.group: group } + property RadioButton control3: RadioButton { ButtonGroup.group: group } + } + } + + Component { + id: switches + Item { + property ButtonGroup group: ButtonGroup { id: group } + property Switch control1: Switch { ButtonGroup.group: group } + property Switch control2: Switch { ButtonGroup.group: group } + property Switch control3: Switch { ButtonGroup.group: group } + } + } + + Component { + id: childControls + Item { + id: container + property ButtonGroup group: ButtonGroup { id: group; buttons: container.children } + property alias control1: control1 + property alias control2: control2 + property alias control3: control3 + CheckBox { id: control1 } + RadioButton { id: control2 } + Switch { id: control3 } + } + } + + function test_controls_data() { + return [ + { tag: "CheckBox", component: checkBoxes }, + { tag: "RadioButton", component: radioButtons }, + { tag: "Switch", component: switches }, + { tag: "Children", component: childControls } + ] + } + + function test_controls(data) { + var container = createTemporaryObject(data.component, testCase) + verify(container) + + verify(!container.group.checkedButton) + + container.control1.checked = true + compare(container.group.checkedButton, container.control1) + compare(container.control1.checked, true) + compare(container.control2.checked, false) + compare(container.control3.checked, false) + + container.control2.checked = true + compare(container.group.checkedButton, container.control2) + compare(container.control1.checked, false) + compare(container.control2.checked, true) + compare(container.control3.checked, false) + + container.control3.checked = true + compare(container.group.checkedButton, container.control3) + compare(container.control1.checked, false) + compare(container.control2.checked, false) + compare(container.control3.checked, true) + } + + function test_buttonDestroyed() { + var group = createTemporaryObject(buttonGroup, testCase) + verify(group) + + var buttonsSpy = createTemporaryObject(signalSpy, testCase, {target: group, signalName: "buttonsChanged"}) + verify(buttonsSpy.valid) + + var button1 = createTemporaryObject(button, testCase, {objectName: "button1", checked: true}) + + group.addButton(button1) + compare(group.buttons.length, 1) + compare(group.buttons[0], button1) + compare(group.checkedButton, button1) + compare(buttonsSpy.count, 1) + + button1.destroy() + wait(0) + compare(group.buttons.length, 0) + compare(group.checkedButton, null) + compare(buttonsSpy.count, 2) + } + + Component { + id: repeater + Column { + id: column + property ButtonGroup group: ButtonGroup { buttons: column.children } + property alias repeater: r + Repeater { + id: r + model: 3 + delegate: RadioDelegate { + checked: index == 0 + objectName: index + } + } + } + } + + function test_repeater() { + var container = createTemporaryObject(repeater, testCase) + verify(container) + + verify(container.group.checkedButton) + compare(container.group.checkedButton.objectName, "0") + } + + function test_nonExclusive() { + var group = createTemporaryObject(nonExclusiveGroup, testCase) + verify(group) + + compare(group.checkState, Qt.Unchecked) + + var button1 = createTemporaryObject(button, testCase, {checked: true}) + group.addButton(button1) + compare(button1.checked, true) + compare(group.checkedButton, null) + compare(group.checkState, Qt.Checked) + + var button2 = createTemporaryObject(button, testCase, {checked: true}) + group.addButton(button2) + compare(button1.checked, true) + compare(button2.checked, true) + compare(group.checkedButton, null) + compare(group.checkState, Qt.Checked) + + var button3 = createTemporaryObject(button, testCase, {checked: false}) + group.addButton(button3) + compare(button1.checked, true) + compare(button2.checked, true) + compare(button3.checked, false) + compare(group.checkedButton, null) + compare(group.checkState, Qt.PartiallyChecked) + + button1.checked = false + compare(button1.checked, false) + compare(button2.checked, true) + compare(button3.checked, false) + compare(group.checkedButton, null) + compare(group.checkState, Qt.PartiallyChecked) + + button2.checked = false + compare(button1.checked, false) + compare(button2.checked, false) + compare(button3.checked, false) + compare(group.checkedButton, null) + compare(group.checkState, Qt.Unchecked) + + button1.checked = true + compare(button1.checked, true) + compare(button2.checked, false) + compare(button3.checked, false) + compare(group.checkedButton, null) + compare(group.checkState, Qt.PartiallyChecked) + + button2.checked = true + compare(button1.checked, true) + compare(button2.checked, true) + compare(button3.checked, false) + compare(group.checkedButton, null) + compare(group.checkState, Qt.PartiallyChecked) + + button3.checked = true + compare(button1.checked, true) + compare(button2.checked, true) + compare(button3.checked, true) + compare(group.checkedButton, null) + compare(group.checkState, Qt.Checked) + } + + Component { + id: checkedButtonColumn + Column { + id: column + ButtonGroup { buttons: column.children } + Repeater { + id: repeater + delegate: Button { + checkable: true + text: modelData + onClicked: listModel.remove(index) + } + model: ListModel { + id: listModel + Component.onCompleted: { + for (var i = 0; i < 10; ++i) + append({text: i}) + } + } + } + } + } + + function test_checkedButtonDestroyed() { + var column = createTemporaryObject(checkedButtonColumn, testCase) + verify(column) + + waitForRendering(column) + mouseClick(column.children[0]) + wait(0) // don't crash (QTBUG-62946, QTBUG-63470) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_checkbox.qml b/tests/auto/quickcontrols2/controls/data/tst_checkbox.qml new file mode 100644 index 00000000000..81c3d6ca94c --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_checkbox.qml @@ -0,0 +1,544 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "CheckBox" + + Component { + id: checkBox + CheckBox { } + } + + Component { + id: signalSequenceSpy + SignalSequenceSpy { + signals: ["pressed", "released", "canceled", "clicked", "toggled", "pressedChanged", "checkedChanged", "checkStateChanged"] + } + } + + function test_text() { + var control = createTemporaryObject(checkBox, testCase) + verify(control) + + compare(control.text, "") + control.text = "CheckBox" + compare(control.text, "CheckBox") + control.text = "" + compare(control.text, "") + } + + function test_checked() { + var control = createTemporaryObject(checkBox, testCase) + verify(control) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [] + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["checkStateChanged", { "checked": true, "checkState": Qt.Checked }], + ["checkedChanged", { "checked": true, "checkState": Qt.Checked }]] + control.checked = true + compare(control.checked, true) + compare(control.checkState, Qt.Checked) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["checkStateChanged", { "checked": false, "checkState": Qt.Unchecked }], + ["checkedChanged", { "checked": false, "checkState": Qt.Unchecked }]] + control.checked = false + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + verify(sequenceSpy.success) + } + + function test_checkState() { + var control = createTemporaryObject(checkBox, testCase) + verify(control) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [] + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["checkStateChanged", { "checked": true, "checkState": Qt.Checked }], + ["checkedChanged", { "checked": true, "checkState": Qt.Checked }]] + control.checkState = Qt.Checked + compare(control.checked, true) + compare(control.checkState, Qt.Checked) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["checkStateChanged", { "checked": false, "checkState": Qt.Unchecked }], + ["checkedChanged", { "checked": false, "checkState": Qt.Unchecked }]] + control.checkState = Qt.Unchecked + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + verify(sequenceSpy.success) + } + + function test_mouse() { + var control = createTemporaryObject(checkBox, testCase) + verify(control) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + // check + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, true) + compare(control.checkState, Qt.Checked) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // uncheck + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + ["checkStateChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // release outside + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }]] + mouseMove(control, control.width * 2, control.height * 2, 0) + compare(control.pressed, false) + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["canceled", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }]] + mouseRelease(control, control.width * 2, control.height * 2, Qt.LeftButton) + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // right button + sequenceSpy.expectedSequence = [] + mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.pressed, false) + mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + compare(control.pressed, false) + verify(sequenceSpy.success) + } + + function test_touch() { + var control = createTemporaryObject(checkBox, testCase) + verify(control) + + var touch = touchEvent(control) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + // check + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.checked, true) + compare(control.checkState, Qt.Checked) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // uncheck + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + ["checkStateChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // release outside + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }]] + touch.move(0, control, control.width * 2, control.height * 2).commit() + compare(control.pressed, false) + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["canceled", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }]] + touch.release(0, control, control.width * 2, control.height * 2).commit() + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + compare(control.pressed, false) + verify(sequenceSpy.success) + } + + function test_keys() { + var control = createTemporaryObject(checkBox, testCase) + verify(control) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [] + control.forceActiveFocus() + verify(control.activeFocus) + verify(sequenceSpy.success) + + // check + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + "toggled", + "released", + "clicked"] + keyClick(Qt.Key_Space) + compare(control.checked, true) + compare(control.checkState, Qt.Checked) + verify(sequenceSpy.success) + + // uncheck + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + ["checkStateChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + "toggled", + "released", + "clicked"] + keyClick(Qt.Key_Space) + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + verify(sequenceSpy.success) + + // no change + sequenceSpy.expectedSequence = [] + var keys = [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab] + for (var i = 0; i < keys.length; ++i) { + sequenceSpy.reset() + keyClick(keys[i]) + compare(control.checked, false) + verify(sequenceSpy.success) + } + } + + Component { + id: checkedBoundBoxes + Item { + property CheckBox cb1: CheckBox { id: cb1 } + property CheckBox cb2: CheckBox { id: cb2; checked: cb1.checked; enabled: false } + } + } + + function test_checked_binding() { + var container = createTemporaryObject(checkedBoundBoxes, testCase) + verify(container) + + compare(container.cb1.checked, false) + compare(container.cb1.checkState, Qt.Unchecked) + compare(container.cb2.checked, false) + compare(container.cb2.checkState, Qt.Unchecked) + + container.cb1.checked = true + compare(container.cb1.checked, true) + compare(container.cb1.checkState, Qt.Checked) + compare(container.cb2.checked, true) + compare(container.cb2.checkState, Qt.Checked) + + container.cb1.checked = false + compare(container.cb1.checked, false) + compare(container.cb1.checkState, Qt.Unchecked) + compare(container.cb2.checked, false) + compare(container.cb2.checkState, Qt.Unchecked) + } + + Component { + id: checkStateBoundBoxes + Item { + property CheckBox cb1: CheckBox { id: cb1 } + property CheckBox cb2: CheckBox { id: cb2; checkState: cb1.checkState; enabled: false } + } + } + + function test_checkState_binding() { + var container = createTemporaryObject(checkStateBoundBoxes, testCase) + verify(container) + + compare(container.cb1.checked, false) + compare(container.cb1.checkState, Qt.Unchecked) + compare(container.cb2.checked, false) + compare(container.cb2.checkState, Qt.Unchecked) + + container.cb1.checkState = Qt.Checked + compare(container.cb1.checked, true) + compare(container.cb1.checkState, Qt.Checked) + compare(container.cb2.checked, true) + compare(container.cb2.checkState, Qt.Checked) + + container.cb1.checkState = Qt.Unchecked + compare(container.cb1.checked, false) + compare(container.cb1.checkState, Qt.Unchecked) + compare(container.cb2.checked, false) + compare(container.cb2.checkState, Qt.Unchecked) + + compare(container.cb1.tristate, false) + compare(container.cb2.tristate, false) + + container.cb1.checkState = Qt.PartiallyChecked + compare(container.cb1.checked, false) + compare(container.cb1.checkState, Qt.PartiallyChecked) + compare(container.cb2.checked, false) + compare(container.cb2.checkState, Qt.PartiallyChecked) + + // note: since Qt Quick Controls 2.4 (Qt 5.11), CheckBox does not + // force tristate when checkState is set to Qt.PartiallyChecked + compare(container.cb1.tristate, false) + compare(container.cb2.tristate, false) + } + + function test_tristate() { + var control = createTemporaryObject(checkBox, testCase, {tristate: true}) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [] + control.forceActiveFocus() + verify(control.activeFocus) + + compare(control.tristate, true) + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + + sequenceSpy.expectedSequence = [["checkStateChanged", { "pressed": false, "checked": false, "checkState": Qt.PartiallyChecked }]] + control.checkState = Qt.PartiallyChecked + compare(control.checked, false) + compare(control.checkState, Qt.PartiallyChecked) + verify(sequenceSpy.success) + + // key: partial -> checked + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.PartiallyChecked }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.PartiallyChecked }], + ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + "released", + "clicked"] + keyClick(Qt.Key_Space) + compare(control.checked, true) + compare(control.checkState, Qt.Checked) + verify(sequenceSpy.success) + + // key: checked -> unchecked + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + ["checkStateChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + "released", + "clicked"] + keyClick(Qt.Key_Space) + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + verify(sequenceSpy.success) + + // key: unchecked -> partial + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + ["checkStateChanged", { "pressed": false, "checked": false, "checkState": Qt.PartiallyChecked }], + "released", + "clicked"] + keyClick(Qt.Key_Space) + compare(control.checked, false) + compare(control.checkState, Qt.PartiallyChecked) + verify(sequenceSpy.success) + + // mouse: partial -> checked + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.PartiallyChecked }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.PartiallyChecked }], + ["checkStateChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + ["checkedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + "released", + "clicked"] + mouseClick(control) + compare(control.checked, true) + compare(control.checkState, Qt.Checked) + verify(sequenceSpy.success) + + // mouse: checked -> unchecked + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true, "checkState": Qt.Checked }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": true, "checkState": Qt.Checked }], + ["checkStateChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + ["checkedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + "released", + "clicked"] + mouseClick(control) + compare(control.checked, false) + compare(control.checkState, Qt.Unchecked) + verify(sequenceSpy.success) + + // mouse: unchecked -> partial + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false, "checkState": Qt.Unchecked }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": false, "checkState": Qt.Unchecked }], + ["checkStateChanged", { "pressed": false, "checked": false, "checkState": Qt.PartiallyChecked }], + "released", + "clicked"] + mouseClick(control) + compare(control.checked, false) + compare(control.checkState, Qt.PartiallyChecked) + verify(sequenceSpy.success) + } + + function test_baseline() { + var control = createTemporaryObject(checkBox, testCase) + verify(control) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + } + + Component { + id: nextCheckStateBox + CheckBox { + tristate: true + nextCheckState: function() { + if (checkState === Qt.Checked) + return Qt.Unchecked + else + return Qt.Checked + } + } + } + + function test_nextCheckState_data() { + return [ + { tag: "unchecked", checkState: Qt.Unchecked, expectedState: Qt.Checked }, + { tag: "partially-checked", checkState: Qt.PartiallyChecked, expectedState: Qt.Checked }, + { tag: "checked", checkState: Qt.Checked, expectedState: Qt.Unchecked } + ] + } + + function test_nextCheckState(data) { + var control = createTemporaryObject(nextCheckStateBox, testCase) + verify(control) + + // mouse + control.checkState = data.checkState + compare(control.checkState, data.checkState) + mouseClick(control) + compare(control.checkState, data.expectedState) + + // touch + control.checkState = data.checkState + compare(control.checkState, data.checkState) + var touch = touchEvent(control) + touch.press(0, control).commit().release(0, control).commit() + compare(control.checkState, data.expectedState) + + // keyboard + control.forceActiveFocus() + tryCompare(control, "activeFocus", true) + control.checkState = data.checkState + compare(control.checkState, data.checkState) + keyClick(Qt.Key_Space) + compare(control.checkState, data.expectedState) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_checkdelegate.qml b/tests/auto/quickcontrols2/controls/data/tst_checkdelegate.qml new file mode 100644 index 00000000000..70f1ae9dbf0 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_checkdelegate.qml @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "CheckDelegate" + + Component { + id: checkDelegate + CheckDelegate {} + } + + // TODO: data-fy tst_checkbox (rename to tst_check?) so we don't duplicate its tests here? + + function test_defaults() { + var control = createTemporaryObject(checkDelegate, testCase); + verify(control); + verify(!control.checked); + } + + function test_checked() { + var control = createTemporaryObject(checkDelegate, testCase); + verify(control); + + mouseClick(control); + verify(control.checked); + + mouseClick(control); + verify(!control.checked); + } + + function test_baseline() { + var control = createTemporaryObject(checkDelegate, testCase); + verify(control); + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset); + } + + function test_spacing() { + var control = createTemporaryObject(checkDelegate, testCase, { text: "Some long, long, long text" }) + verify(control) + verify(control.contentItem.implicitWidth + control.leftPadding + control.rightPadding > control.background.implicitWidth) + + var textLabel = findChild(control.contentItem, "label") + verify(textLabel) + + // The implicitWidth of the IconLabel that all buttons use as their contentItem should be + // equal to the implicitWidth of the Text and the check indicator + spacing while no icon is set. + compare(control.contentItem.implicitWidth, textLabel.implicitWidth + control.indicator.width + control.spacing) + + control.spacing += 100 + compare(control.contentItem.implicitWidth, textLabel.implicitWidth + control.indicator.width + control.spacing) + + compare(control.implicitWidth, textLabel.implicitWidth + control.indicator.width + control.spacing + control.leftPadding + control.rightPadding) + } + + function test_display_data() { + return [ + { "tag": "IconOnly", display: CheckDelegate.IconOnly }, + { "tag": "TextOnly", display: CheckDelegate.TextOnly }, + { "tag": "TextUnderIcon", display: CheckDelegate.TextUnderIcon }, + { "tag": "TextBesideIcon", display: CheckDelegate.TextBesideIcon }, + { "tag": "IconOnly, mirrored", display: CheckDelegate.IconOnly, mirrored: true }, + { "tag": "TextOnly, mirrored", display: CheckDelegate.TextOnly, mirrored: true }, + { "tag": "TextUnderIcon, mirrored", display: CheckDelegate.TextUnderIcon, mirrored: true }, + { "tag": "TextBesideIcon, mirrored", display: CheckDelegate.TextBesideIcon, mirrored: true } + ] + } + + function test_display(data) { + var control = createTemporaryObject(checkDelegate, testCase, { + text: "CheckDelegate", + display: data.display, + width: 400, + "icon.source": "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png", + "LayoutMirroring.enabled": !!data.mirrored + }) + verify(control) + compare(control.icon.source, "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png") + + var iconImage = findChild(control.contentItem, "image") + var textLabel = findChild(control.contentItem, "label") + + var availableWidth = control.availableWidth - control.indicator.width - control.spacing + var indicatorOffset = control.mirrored ? control.indicator.width + control.spacing : 0 + + switch (control.display) { + case CheckDelegate.IconOnly: + verify(iconImage) + verify(!textLabel) + compare(iconImage.x, indicatorOffset + (availableWidth - iconImage.width) / 2) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + break; + case CheckDelegate.TextOnly: + verify(!iconImage) + verify(textLabel) + compare(textLabel.x, control.mirrored ? control.availableWidth - textLabel.width : 0) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + case CheckDelegate.TextUnderIcon: + verify(iconImage) + verify(textLabel) + compare(iconImage.x, indicatorOffset + (availableWidth - iconImage.width) / 2) + compare(textLabel.x, indicatorOffset + (availableWidth - textLabel.width) / 2) + verify(iconImage.y < textLabel.y) + break; + case CheckDelegate.TextBesideIcon: + verify(iconImage) + verify(textLabel) + if (control.mirrored) + verify(textLabel.x < iconImage.x) + else + verify(iconImage.x < textLabel.x) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + } + } + + Component { + id: nextCheckStateDelegate + CheckDelegate { + tristate: true + nextCheckState: function() { + if (checkState === Qt.Checked) + return Qt.Unchecked + else + return Qt.Checked + } + } + } + + function test_nextCheckState_data() { + return [ + { tag: "unchecked", checkState: Qt.Unchecked, expectedState: Qt.Checked }, + { tag: "partially-checked", checkState: Qt.PartiallyChecked, expectedState: Qt.Checked }, + { tag: "checked", checkState: Qt.Checked, expectedState: Qt.Unchecked } + ] + } + + function test_nextCheckState(data) { + var control = createTemporaryObject(nextCheckStateDelegate, testCase) + verify(control) + + // mouse + control.checkState = data.checkState + compare(control.checkState, data.checkState) + mouseClick(control) + compare(control.checkState, data.expectedState) + + // touch + control.checkState = data.checkState + compare(control.checkState, data.checkState) + var touch = touchEvent(control) + touch.press(0, control).commit().release(0, control).commit() + compare(control.checkState, data.expectedState) + + // keyboard + control.forceActiveFocus() + tryCompare(control, "activeFocus", true) + control.checkState = data.checkState + compare(control.checkState, data.checkState) + keyClick(Qt.Key_Space) + compare(control.checkState, data.expectedState) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_combobox.qml b/tests/auto/quickcontrols2/controls/data/tst_combobox.qml new file mode 100644 index 00000000000..48a048945de --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_combobox.qml @@ -0,0 +1,2353 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "ComboBox" + + Component { + id: signalSpy + SignalSpy { } + } + + Component { + id: comboBox + ComboBox { } + } + + Component { + id: emptyBox + ComboBox { + delegate: ItemDelegate { + width: parent.width + } + } + } + + Component { + id: mouseArea + MouseArea { } + } + + Component { + id: customPopup + Popup { + width: 100 + implicitHeight: contentItem.implicitHeight + contentItem: TextInput { + anchors.fill: parent + } + } + } + + Component { + id: comboBoxWithShaderEffect + ComboBox { + delegate: Rectangle { + Text { + id: txt + anchors.centerIn: parent + text: "item" + index + font.pixelSize: 20 + color: "red" + } + id: rect + objectName: "rect" + width: parent.width + height: txt.implicitHeight + gradient: Gradient { + GradientStop { color: "lightsteelblue"; position: 0.0 } + GradientStop { color: "blue"; position: 1.0 } + } + layer.enabled: true + layer.effect: ShaderEffect { + objectName: "ShaderFX" + width: rect.width + height: rect.height + fragmentShader: " + uniform lowp sampler2D source; // this item + uniform lowp float qt_Opacity; // inherited opacity of this item + varying highp vec2 qt_TexCoord0; + void main() { + lowp vec4 p = texture2D(source, qt_TexCoord0); + lowp float g = dot(p.xyz, vec3(0.344, 0.5, 0.156)); + gl_FragColor = vec4(g, g, g, p.a) * qt_Opacity; + }" + + } + } + } + } + + function init() { + // QTBUG-61225: Move the mouse away to avoid QQuickWindowPrivate::flushFrameSynchronousEvents() + // delivering interfering hover events based on the last mouse position from earlier tests. For + // example, ComboBox::test_activation() kept receiving hover events for the last mouse position + // from CheckDelegate::test_checked(). + mouseMove(testCase, testCase.width - 1, testCase.height - 1) + } + + function test_defaults() { + var control = createTemporaryObject(comboBox, testCase) + verify(control) + + compare(control.count, 0) + compare(control.model, undefined) + compare(control.flat, false) + compare(control.pressed, false) + compare(control.currentIndex, -1) + compare(control.highlightedIndex, -1) + compare(control.currentText, "") + verify(control.delegate) + if (Qt.platform.pluginName !== "cocoa" && Qt.platform.pluginName !== "windows") { + // Only the non-native styles sets an indicator delegate. The native + // styles will instead draw the indicator as a part of the background. + verify(control.indicator) + } + verify(control.popup) + verify(control.acceptableInput) + compare(control.inputMethodHints, Qt.ImhNoPredictiveText) + } + + function test_array() { + var control = createTemporaryObject(comboBox, testCase) + verify(control) + + var items = [ "Banana", "Apple", "Coconut" ] + + control.model = items + compare(control.model, items) + + compare(control.count, 3) + compare(control.currentIndex, 0) + compare(control.currentText, "Banana") + + control.currentIndex = 2 + compare(control.currentIndex, 2) + compare(control.currentText, "Coconut") + + control.model = null + compare(control.model, null) + compare(control.count, 0) + compare(control.currentIndex, -1) + compare(control.currentText, "") + } + + function test_objects() { + var control = createTemporaryObject(emptyBox, testCase) + verify(control) + + var items = [ + { text: "Apple" }, + { text: "Orange" }, + { text: "Banana" } + ] + + control.model = items + compare(control.model, items) + + compare(control.count, 3) + compare(control.currentIndex, 0) + compare(control.currentText, "Apple") + + control.currentIndex = 2 + compare(control.currentIndex, 2) + compare(control.currentText, "Banana") + + control.model = null + compare(control.model, null) + compare(control.count, 0) + compare(control.currentIndex, -1) + compare(control.currentText, "") + } + + function test_qobjects() { + var control = createTemporaryObject(emptyBox, testCase, {textRole: "text"}) + verify(control) + + var obj1 = Qt.createQmlObject("import QtQml; QtObject { property string text: 'one' }", control) + var obj2 = Qt.createQmlObject("import QtQml; QtObject { property string text: 'two' }", control) + var obj3 = Qt.createQmlObject("import QtQml; QtObject { property string text: 'three' }", control) + + control.model = [obj1, obj2, obj3] + + compare(control.count, 3) + compare(control.currentIndex, 0) + compare(control.currentText, "one") + + control.currentIndex = 2 + compare(control.currentIndex, 2) + compare(control.currentText, "three") + + control.model = null + compare(control.model, null) + compare(control.count, 0) + compare(control.currentIndex, -1) + compare(control.currentText, "") + } + + function test_number() { + var control = createTemporaryObject(comboBox, testCase) + verify(control) + + control.model = 10 + compare(control.model, 10) + + compare(control.count, 10) + compare(control.currentIndex, 0) + compare(control.currentText, "0") + + control.currentIndex = 9 + compare(control.currentIndex, 9) + compare(control.currentText, "9") + + control.model = 0 + compare(control.model, 0) + compare(control.count, 0) + compare(control.currentIndex, -1) + compare(control.currentText, "") + } + + ListModel { + id: listmodel + ListElement { text: "First" } + ListElement { text: "Second" } + ListElement { text: "Third" } + ListElement { text: "Fourth" } + ListElement { text: "Fifth" } + } + + function test_listModel() { + var control = createTemporaryObject(comboBox, testCase) + verify(control) + + control.model = listmodel + compare(control.model, listmodel) + + compare(control.count, 5) + compare(control.currentIndex, 0) + compare(control.currentText, "First") + + control.currentIndex = 2 + compare(control.currentIndex, 2) + compare(control.currentText, "Third") + + control.model = undefined + compare(control.model, undefined) + compare(control.count, 0) + compare(control.currentIndex, -1) + compare(control.currentText, "") + } + + ListModel { + id: fruitmodel + ListElement { name: "Apple"; color: "red" } + ListElement { name: "Orange"; color: "orange" } + ListElement { name: "Banana"; color: "yellow" } + } + + Component { + id: fruitModelComponent + ListModel { + ListElement { name: "Apple"; color: "red" } + ListElement { name: "Orange"; color: "orange" } + ListElement { name: "Banana"; color: "yellow" } + } + } + + property var fruitarray: [ + { name: "Apple", color: "red" }, + { name: "Orange", color: "orange" }, + { name: "Banana", color: "yellow" } + ] + + Component { + id: birdModelComponent + ListModel { + ListElement { name: "Galah"; color: "pink" } + ListElement { name: "Kookaburra"; color: "brown" } + ListElement { name: "Magpie"; color: "black" } + } + } + + function test_textRole_data() { + return [ + { tag: "ListModel", model: fruitmodel }, + { tag: "ObjectArray", model: fruitarray } + ] + } + + function test_textRole(data) { + var control = createTemporaryObject(emptyBox, testCase) + verify(control) + + control.model = data.model + compare(control.count, 3) + compare(control.currentIndex, 0) + compare(control.currentText, "") + + control.textRole = "name" + compare(control.currentText, "Apple") + + control.textRole = "color" + compare(control.currentText, "red") + + control.currentIndex = 1 + compare(control.currentIndex, 1) + compare(control.currentText, "orange") + + control.textRole = "name" + compare(control.currentText, "Orange") + + control.textRole = "" + compare(control.currentText, "") + } + + function test_textAt() { + var control = createTemporaryObject(comboBox, testCase) + verify(control) + + control.model = ["Apple", "Orange", "Banana"] + compare(control.textAt(0), "Apple") + compare(control.textAt(1), "Orange") + compare(control.textAt(2), "Banana") + compare(control.textAt(-1), "") // TODO: null? + compare(control.textAt(5), "") // TODO: null? + } + + function test_find_data() { + return [ + { tag: "Banana (MatchExactly)", term: "Banana", flags: Qt.MatchExactly, index: 0 }, + { tag: "banana (MatchExactly)", term: "banana", flags: Qt.MatchExactly, index: 1 }, + { tag: "bananas (MatchExactly)", term: "bananas", flags: Qt.MatchExactly, index: -1 }, + { tag: "Cocomuffin (MatchExactly)", term: "Cocomuffin", flags: Qt.MatchExactly, index: 4 }, + + { tag: "b(an)+a (MatchRegularExpression)", term: "B(an)+a", flags: Qt.MatchRegularExpression, index: 0 }, + { tag: "b(an)+a (MatchRegularExpression|MatchCaseSensitive)", term: "b(an)+a", flags: Qt.MatchRegularExpression | Qt.MatchCaseSensitive, index: 1 }, + { tag: "[coc]+\\w+ (MatchRegularExpression)", term: "[coc]+\\w+", flags: Qt.MatchRegularExpression, index: 2 }, + + { tag: "?pp* (MatchWildcard)", term: "?pp*", flags: Qt.MatchWildcard, index: 3 }, + { tag: "app* (MatchWildcard|MatchCaseSensitive)", term: "app*", flags: Qt.MatchWildcard | Qt.MatchCaseSensitive, index: -1 }, + + { tag: "Banana (MatchFixedString)", term: "Banana", flags: Qt.MatchFixedString, index: 0 }, + { tag: "banana (MatchFixedString|MatchCaseSensitive)", term: "banana", flags: Qt.MatchFixedString | Qt.MatchCaseSensitive, index: 1 }, + + { tag: "coco (MatchStartsWith)", term: "coco", flags: Qt.MatchStartsWith, index: 2 }, + { tag: "coco (MatchStartsWith|MatchCaseSensitive)", term: "coco", flags: Qt.StartsWith | Qt.MatchCaseSensitive, index: -1 }, + + { tag: "MUFFIN (MatchEndsWith)", term: "MUFFIN", flags: Qt.MatchEndsWith, index: 4 }, + { tag: "MUFFIN (MatchEndsWith|MatchCaseSensitive)", term: "MUFFIN", flags: Qt.MatchEndsWith | Qt.MatchCaseSensitive, index: -1 }, + + { tag: "Con (MatchContains)", term: "Con", flags: Qt.MatchContains, index: 2 }, + { tag: "Con (MatchContains|MatchCaseSensitive)", term: "Con", flags: Qt.MatchContains | Qt.MatchCaseSensitive, index: -1 }, + ] + } + + function test_find(data) { + var control = createTemporaryObject(comboBox, testCase) + verify(control) + + control.model = ["Banana", "banana", "Coconut", "Apple", "Cocomuffin"] + + compare(control.find(data.term, data.flags), data.index) + } + + function test_valueRole_data() { + return [ + { tag: "ListModel", model: fruitmodel }, + { tag: "ObjectArray", model: fruitarray } + ] + } + + function test_valueRole(data) { + var control = createTemporaryObject(emptyBox, testCase, + { model: data.model, valueRole: "color" }) + verify(control) + compare(control.count, 3) + compare(control.currentIndex, 0) + compare(control.currentValue, "red") + + control.valueRole = "name" + compare(control.currentValue, "Apple") + + control.currentIndex = 1 + compare(control.currentIndex, 1) + compare(control.currentValue, "Orange") + + control.valueRole = "color" + compare(control.currentValue, "orange") + + control.model = null + compare(control.currentIndex, -1) + // An invalid QVariant is represented as undefined. + compare(control.currentValue, undefined) + + control.valueRole = "" + compare(control.currentValue, undefined) + } + + function test_valueAt() { + var control = createTemporaryObject(comboBox, testCase, + { model: fruitmodel, textRole: "name", valueRole: "color" }) + verify(control) + + compare(control.valueAt(0), "red") + compare(control.valueAt(1), "orange") + compare(control.valueAt(2), "yellow") + compare(control.valueAt(-1), undefined) + compare(control.valueAt(5), undefined) + } + + function test_indexOfValue_data() { + return [ + { tag: "red", expectedIndex: 0 }, + { tag: "orange", expectedIndex: 1 }, + { tag: "yellow", expectedIndex: 2 }, + { tag: "brown", expectedIndex: -1 }, + ] + } + + function test_indexOfValue(data) { + var control = createTemporaryObject(comboBox, testCase, + { model: fruitmodel, textRole: "name", valueRole: "color" }) + verify(control) + + compare(control.indexOfValue(data.tag), data.expectedIndex) + } + + function test_currentValueAfterModelChanged() { + let fruitModel = createTemporaryObject(fruitModelComponent, testCase) + verify(fruitModel) + + let control = createTemporaryObject(comboBox, testCase, + { model: fruitModel, textRole: "name", valueRole: "color", currentIndex: 1 }) + verify(control) + compare(control.currentText, "Orange") + compare(control.currentValue, "orange") + + // Remove "Apple"; the current item should now be "Banana", so currentValue should be "yellow". + fruitModel.remove(0) + compare(control.currentText, "Banana") + compare(control.currentValue, "yellow") + } + + function test_currentValueAfterNewModelSet() { + let control = createTemporaryObject(comboBox, testCase, + { model: fruitmodel, textRole: "name", valueRole: "color", currentIndex: 0 }) + verify(control) + compare(control.currentText, "Apple") + compare(control.currentValue, "red") + + // Swap the model out entirely. Since the currentIndex was 0 and + // is reset to 0 when a new model is set, it remains 0. + let birdModel = createTemporaryObject(birdModelComponent, testCase) + verify(birdModel) + control.model = birdModel + compare(control.currentText, "Galah") + compare(control.currentValue, "pink") + } + + function test_arrowKeys() { + var control = createTemporaryObject(comboBox, testCase, + { model: fruitmodel, textRole: "name", valueRole: "color" }) + verify(control) + + var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"}) + verify(activatedSpy.valid) + + var highlightedSpy = signalSpy.createObject(control, {target: control, signalName: "highlighted"}) + verify(highlightedSpy.valid) + + var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"}) + verify(openedSpy.valid) + + var closedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "closed"}) + verify(closedSpy.valid) + + control.forceActiveFocus() + verify(control.activeFocus) + + compare(control.currentIndex, 0) + compare(control.highlightedIndex, -1) + + keyClick(Qt.Key_Down) + compare(control.currentIndex, 1) + compare(control.highlightedIndex, -1) + compare(highlightedSpy.count, 0) + compare(activatedSpy.count, 1) + compare(activatedSpy.signalArguments[0][0], 1) + activatedSpy.clear() + + keyClick(Qt.Key_Down) + compare(control.currentIndex, 2) + compare(control.highlightedIndex, -1) + compare(highlightedSpy.count, 0) + compare(activatedSpy.count, 1) + compare(activatedSpy.signalArguments[0][0], 2) + activatedSpy.clear() + + keyClick(Qt.Key_Down) + compare(control.currentIndex, 2) + compare(control.highlightedIndex, -1) + compare(highlightedSpy.count, 0) + compare(activatedSpy.count, 0) + + keyClick(Qt.Key_Up) + compare(control.currentIndex, 1) + compare(control.highlightedIndex, -1) + compare(highlightedSpy.count, 0) + compare(activatedSpy.count, 1) + compare(activatedSpy.signalArguments[0][0], 1) + activatedSpy.clear() + + keyClick(Qt.Key_Up) + compare(control.currentIndex, 0) + compare(control.highlightedIndex, -1) + compare(highlightedSpy.count, 0) + compare(activatedSpy.count, 1) + compare(activatedSpy.signalArguments[0][0], 0) + activatedSpy.clear() + + keyClick(Qt.Key_Up) + compare(control.currentIndex, 0) + compare(control.highlightedIndex, -1) + compare(highlightedSpy.count, 0) + compare(activatedSpy.count, 0) + + // show popup + keyClick(Qt.Key_Space) + openedSpy.wait() + compare(openedSpy.count, 1) + + compare(control.currentIndex, 0) + compare(control.highlightedIndex, 0) + + keyClick(Qt.Key_Down) + compare(control.currentIndex, 0) + compare(control.highlightedIndex, 1) + compare(activatedSpy.count, 0) + compare(highlightedSpy.count, 1) + compare(highlightedSpy.signalArguments[0][0], 1) + highlightedSpy.clear() + + keyClick(Qt.Key_Down) + compare(control.currentIndex, 0) + compare(control.highlightedIndex, 2) + compare(activatedSpy.count, 0) + compare(highlightedSpy.count, 1) + compare(highlightedSpy.signalArguments[0][0], 2) + highlightedSpy.clear() + + keyClick(Qt.Key_Down) + compare(control.currentIndex, 0) + compare(control.highlightedIndex, 2) + compare(activatedSpy.count, 0) + compare(highlightedSpy.count, 0) + + keyClick(Qt.Key_Up) + compare(control.currentIndex, 0) + compare(control.highlightedIndex, 1) + compare(activatedSpy.count, 0) + compare(highlightedSpy.count, 1) + compare(highlightedSpy.signalArguments[0][0], 1) + highlightedSpy.clear() + + keyClick(Qt.Key_Up) + compare(control.currentIndex, 0) + compare(control.highlightedIndex, 0) + compare(activatedSpy.count, 0) + compare(highlightedSpy.count, 1) + compare(highlightedSpy.signalArguments[0][0], 0) + highlightedSpy.clear() + + keyClick(Qt.Key_Up) + compare(control.currentIndex, 0) + compare(control.highlightedIndex, 0) + compare(activatedSpy.count, 0) + compare(highlightedSpy.count, 0) + + keyClick(Qt.Key_Down) + compare(control.currentIndex, 0) + compare(control.highlightedIndex, 1) + compare(activatedSpy.count, 0) + compare(highlightedSpy.count, 1) + compare(highlightedSpy.signalArguments[0][0], 1) + highlightedSpy.clear() + + // hide popup + keyClick(Qt.Key_Space) + closedSpy.wait() + compare(closedSpy.count, 1) + + compare(control.currentIndex, 1) + compare(control.highlightedIndex, -1) + } + + function test_keys_space_enter_escape_data() { + return [ + { tag: "space-space", key1: Qt.Key_Space, key2: Qt.Key_Space, showPopup: true, showPress: true, hidePopup: true, hidePress: true }, + { tag: "space-enter", key1: Qt.Key_Space, key2: Qt.Key_Enter, showPopup: true, showPress: true, hidePopup: true, hidePress: true }, + { tag: "space-return", key1: Qt.Key_Space, key2: Qt.Key_Return, showPopup: true, showPress: true, hidePopup: true, hidePress: true }, + { tag: "space-escape", key1: Qt.Key_Space, key2: Qt.Key_Escape, showPopup: true, showPress: true, hidePopup: true, hidePress: false }, + { tag: "space-0", key1: Qt.Key_Space, key2: Qt.Key_0, showPopup: true, showPress: true, hidePopup: false, hidePress: false }, + { tag: "enter-enter", key1: Qt.Key_Enter, key2: Qt.Key_Enter, showPopup: false, showPress: false, hidePopup: true, hidePress: false }, + { tag: "return-return", key1: Qt.Key_Return, key2: Qt.Key_Return, showPopup: false, showPress: false, hidePopup: true, hidePress: false }, + { tag: "escape-escape", key1: Qt.Key_Escape, key2: Qt.Key_Escape, showPopup: false, showPress: false, hidePopup: true, hidePress: false } + ] + } + + function test_keys_space_enter_escape(data) { + var control = createTemporaryObject(comboBox, testCase, {model: 3}) + verify(control) + + var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"}) + verify(openedSpy.valid) + + control.forceActiveFocus() + verify(control.activeFocus) + + compare(control.pressed, false) + compare(control.popup.visible, false) + + // show popup + keyPress(data.key1) + compare(control.pressed, data.showPress) + compare(control.popup.visible, false) + keyRelease(data.key1) + compare(control.pressed, false) + compare(control.popup.visible, data.showPopup) + if (data.showPopup) + openedSpy.wait() + + // hide popup + keyPress(data.key2) + compare(control.pressed, data.hidePress) + keyRelease(data.key2) + compare(control.pressed, false) + tryCompare(control.popup, "visible", !data.hidePopup) + } + + function test_keys_home_end() { + var control = createTemporaryObject(comboBox, testCase, {model: 5}) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + compare(control.currentIndex, 0) + compare(control.highlightedIndex, -1) + + var activatedCount = 0 + var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"}) + verify(activatedSpy.valid) + + var highlightedCount = 0 + var highlightedSpy = signalSpy.createObject(control, {target: control, signalName: "highlighted"}) + verify(highlightedSpy.valid) + + var currentIndexCount = 0 + var currentIndexSpy = signalSpy.createObject(control, {target: control, signalName: "currentIndexChanged"}) + verify(currentIndexSpy.valid) + + var highlightedIndexCount = 0 + var highlightedIndexSpy = signalSpy.createObject(control, {target: control, signalName: "highlightedIndexChanged"}) + verify(highlightedIndexSpy.valid) + + // end (popup closed) + keyClick(Qt.Key_End) + compare(control.currentIndex, 4) + compare(currentIndexSpy.count, ++currentIndexCount) + + compare(control.highlightedIndex, -1) + compare(highlightedIndexSpy.count, highlightedIndexCount) + + compare(activatedSpy.count, ++activatedCount) + compare(activatedSpy.signalArguments[activatedCount-1][0], 4) + + compare(highlightedSpy.count, highlightedCount) + + // repeat (no changes/signals) + keyClick(Qt.Key_End) + compare(currentIndexSpy.count, currentIndexCount) + compare(highlightedIndexSpy.count, highlightedIndexCount) + compare(activatedSpy.count, activatedCount) + compare(highlightedSpy.count, highlightedCount) + + // home (popup closed) + keyClick(Qt.Key_Home) + compare(control.currentIndex, 0) + compare(currentIndexSpy.count, ++currentIndexCount) + + compare(control.highlightedIndex, -1) + compare(highlightedIndexSpy.count, highlightedIndexCount) + + compare(activatedSpy.count, ++activatedCount) + compare(activatedSpy.signalArguments[activatedCount-1][0], 0) + + compare(highlightedSpy.count, highlightedCount) + + // repeat (no changes/signals) + keyClick(Qt.Key_Home) + compare(currentIndexSpy.count, currentIndexCount) + compare(highlightedIndexSpy.count, highlightedIndexCount) + compare(activatedSpy.count, activatedCount) + compare(highlightedSpy.count, highlightedCount) + + control.popup.open() + compare(control.highlightedIndex, 0) + compare(highlightedIndexSpy.count, ++highlightedIndexCount) + compare(highlightedSpy.count, highlightedCount) + + // end (popup open) + keyClick(Qt.Key_End) + compare(control.currentIndex, 0) + compare(currentIndexSpy.count, currentIndexCount) + + compare(control.highlightedIndex, 4) + compare(highlightedIndexSpy.count, ++highlightedIndexCount) + + compare(activatedSpy.count, activatedCount) + + compare(highlightedSpy.count, ++highlightedCount) + compare(highlightedSpy.signalArguments[highlightedCount-1][0], 4) + + // repeat (no changes/signals) + keyClick(Qt.Key_End) + compare(currentIndexSpy.count, currentIndexCount) + compare(highlightedIndexSpy.count, highlightedIndexCount) + compare(activatedSpy.count, activatedCount) + compare(highlightedSpy.count, highlightedCount) + + // home (popup open) + keyClick(Qt.Key_Home) + compare(control.currentIndex, 0) + compare(currentIndexSpy.count, currentIndexCount) + + compare(control.highlightedIndex, 0) + compare(highlightedIndexSpy.count, ++highlightedIndexCount) + + compare(activatedSpy.count, activatedCount) + + compare(highlightedSpy.count, ++highlightedCount) + compare(highlightedSpy.signalArguments[highlightedCount-1][0], 0) + + // repeat (no changes/signals) + keyClick(Qt.Key_Home) + compare(currentIndexSpy.count, currentIndexCount) + compare(highlightedIndexSpy.count, highlightedIndexCount) + compare(activatedSpy.count, activatedCount) + compare(highlightedSpy.count, highlightedCount) + } + + function test_keySearch() { + var control = createTemporaryObject(comboBox, testCase, {model: ["Banana", "Coco", "Coconut", "Apple", "Cocomuffin"]}) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + + compare(control.currentIndex, 0) + compare(control.currentText, "Banana") + compare(control.highlightedIndex, -1) + + keyPress(Qt.Key_C) + compare(control.currentIndex, 1) + compare(control.currentText, "Coco") + compare(control.highlightedIndex, -1) + + // no match + keyPress(Qt.Key_N) + compare(control.currentIndex, 1) + compare(control.currentText, "Coco") + compare(control.highlightedIndex, -1) + + keyPress(Qt.Key_C) + compare(control.currentIndex, 2) + compare(control.currentText, "Coconut") + compare(control.highlightedIndex, -1) + + keyPress(Qt.Key_C) + compare(control.currentIndex, 4) + compare(control.currentText, "Cocomuffin") + compare(control.highlightedIndex, -1) + + // wrap + keyPress(Qt.Key_C) + compare(control.currentIndex, 1) + compare(control.currentText, "Coco") + compare(control.highlightedIndex, -1) + + keyPress(Qt.Key_A) + compare(control.currentIndex, 3) + compare(control.currentText, "Apple") + compare(control.highlightedIndex, -1) + + keyPress(Qt.Key_B) + compare(control.currentIndex, 0) + compare(control.currentText, "Banana") + compare(control.highlightedIndex, -1) + + // popup + control.popup.open() + tryCompare(control.popup, "opened", true) + + compare(control.currentIndex, 0) + compare(control.highlightedIndex, 0) + + keyClick(Qt.Key_C) + compare(control.highlightedIndex, 1) // "Coco" + compare(control.currentIndex, 0) + + // no match + keyClick(Qt.Key_N) + compare(control.highlightedIndex, 1) + compare(control.currentIndex, 0) + + keyClick(Qt.Key_C) + compare(control.highlightedIndex, 2) // "Coconut" + compare(control.currentIndex, 0) + + keyClick(Qt.Key_C) + compare(control.highlightedIndex, 4) // "Cocomuffin" + compare(control.currentIndex, 0) + + // wrap + keyClick(Qt.Key_C) + compare(control.highlightedIndex, 1) // "Coco" + compare(control.currentIndex, 0) + + keyClick(Qt.Key_B) + compare(control.highlightedIndex, 0) // "Banana" + compare(control.currentIndex, 0) + + keyClick(Qt.Key_A) + compare(control.highlightedIndex, 3) // "Apple" + compare(control.currentIndex, 0) + + verify(control.popup.visible) + + // accept + keyClick(Qt.Key_Return) + tryCompare(control.popup, "visible", false) + compare(control.currentIndex, 3) + compare(control.currentText, "Apple") + compare(control.highlightedIndex, -1) + } + + function test_popup() { + var control = createTemporaryObject(comboBox, testCase, {model: 3}) + verify(control) + + // show below + mousePress(control) + compare(control.pressed, true) + compare(control.popup.visible, false) + mouseRelease(control) + compare(control.pressed, false) + compare(control.popup.visible, true) + verify(control.popup.contentItem.y >= control.y) + + // hide + mouseClick(control) + compare(control.pressed, false) + tryCompare(control.popup, "visible", false) + + // show above + control.y = control.Window.height - control.height + mousePress(control) + compare(control.pressed, true) + compare(control.popup.visible, false) + mouseRelease(control) + compare(control.pressed, false) + compare(control.popup.visible, true) + verify(control.popup.contentItem.y < control.y) + + + // Account for when a transition of a scale from 0.9-1.0 that it is placed above right away and not below + // first just because there is room at the 0.9 scale + if (control.popup.enter !== null) { + // hide + mouseClick(control) + compare(control.pressed, false) + tryCompare(control.popup, "visible", false) + control.y = control.Window.height - (control.popup.contentItem.height * 0.99) + var popupYSpy = createTemporaryObject(signalSpy, testCase, {target: control.popup, signalName: "yChanged"}) + verify(popupYSpy.valid) + mousePress(control) + compare(control.pressed, true) + compare(control.popup.visible, false) + mouseRelease(control) + compare(control.pressed, false) + compare(control.popup.visible, true) + tryCompare(control.popup.enter, "running", false) + verify(control.popup.contentItem.y < control.y) + verify(popupYSpy.count === 1) + } + + // follow the control outside the horizontal window bounds + control.x = -control.width / 2 + compare(control.x, -control.width / 2) + compare(control.popup.contentItem.parent.x, -control.width / 2) + control.x = testCase.width - control.width / 2 + compare(control.x, testCase.width - control.width / 2) + compare(control.popup.contentItem.parent.x, testCase.width - control.width / 2) + + // close the popup when hidden (QTBUG-67684) + control.popup.open() + tryCompare(control.popup, "opened", true) + control.visible = false + tryCompare(control.popup, "visible", false) + } + + Component { + id: reopenCombo + Window { + property alias innerCombo: innerCombo + visible: true + width: 300 + height: 300 + ComboBox { + id: innerCombo + model: 10 + anchors.verticalCenter: parent.verticalCenter + } + } + } + + // This test checks that when reopening the combobox that it is still appears at the same y position as + // previously + function test_reopen_popup() { + var control = createTemporaryObject(reopenCombo, testCase) + verify(control) + var y = 0; + for (var i = 0; i < 2; ++i) { + tryCompare(control.innerCombo.popup, "visible", false) + control.innerCombo.y = control.height - (control.innerCombo.popup.contentItem.height * 0.99) + var popupYSpy = createTemporaryObject(signalSpy, testCase, {target: control.innerCombo.popup, signalName: "yChanged"}) + verify(popupYSpy.valid) + mousePress(control.innerCombo) + compare(control.innerCombo.pressed, true) + compare(control.innerCombo.popup.visible, false) + mouseRelease(control.innerCombo) + compare(control.innerCombo.pressed, false) + compare(control.innerCombo.popup.visible, true) + if (control.innerCombo.popup.enter) + tryCompare(control.innerCombo.popup.enter, "running", false) + // Check on the second opening that it has the same y position as before + if (i !== 0) { + // y should not have changed again + verify(popupYSpy.count === 0) + verify(y === control.innerCombo.popup.y) + } else { + // In some cases on the initial show, y changes more than once + verify(popupYSpy.count >= 1) + y = control.innerCombo.popup.y + mouseClick(control.innerCombo) + compare(control.innerCombo.pressed, false) + tryCompare(control.innerCombo.popup, "visible", false) + } + } + } + + function test_mouse() { + var control = createTemporaryObject(comboBox, testCase, {model: 3, hoverEnabled: false}) + verify(control) + + var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"}) + verify(activatedSpy.valid) + + mouseClick(control) + compare(control.popup.visible, true) + + var content = control.popup.contentItem + waitForRendering(content) + + // press - move - release outside - not activated - not closed + mousePress(content) + compare(activatedSpy.count, 0) + mouseMove(content, content.width * 2) + compare(activatedSpy.count, 0) + mouseRelease(content, content.width * 2) + compare(activatedSpy.count, 0) + compare(control.popup.visible, true) + + // press - move - release inside - activated - closed + mousePress(content) + compare(activatedSpy.count, 0) + mouseMove(content, content.width / 2 + 1, content.height / 2 + 1) + compare(activatedSpy.count, 0) + mouseRelease(content) + compare(activatedSpy.count, 1) + tryCompare(control.popup, "visible", false) + } + + function test_touch() { + var control = createTemporaryObject(comboBox, testCase, {model: 3}) + verify(control) + + var touch = touchEvent(control) + + var activatedSpy = signalSpy.createObject(control, {target: control, signalName: "activated"}) + verify(activatedSpy.valid) + + var highlightedSpy = signalSpy.createObject(control, {target: control, signalName: "highlighted"}) + verify(highlightedSpy.valid) + + touch.press(0, control).commit() + touch.release(0, control).commit() + compare(control.popup.visible, true) + + var content = control.popup.contentItem + waitForRendering(content) + + // press - move - release outside - not activated - not closed + touch.press(0, control).commit() + compare(activatedSpy.count, 0) + compare(highlightedSpy.count, 0) + touch.move(0, control, control.width * 2, control.height / 2).commit() + compare(activatedSpy.count, 0) + compare(highlightedSpy.count, 0) + touch.release(0, control, control.width * 2, control.height / 2).commit() + compare(activatedSpy.count, 0) + compare(highlightedSpy.count, 0) + compare(control.popup.visible, true) + + // press - move - release inside - activated - closed + touch.press(0, content).commit() + compare(activatedSpy.count, 0) + compare(highlightedSpy.count, 0) + touch.move(0, content, content.width / 2 + 1, content.height / 2 + 1).commit() + compare(activatedSpy.count, 0) + compare(highlightedSpy.count, 0) + touch.release(0, content).commit() + compare(activatedSpy.count, 1) + compare(highlightedSpy.count, 1) + tryCompare(control.popup, "visible", false) + } + + function test_down() { + var control = createTemporaryObject(comboBox, testCase, {model: 3}) + verify(control) + + // some styles position the popup over the combo button. move it out + // of the way to avoid stealing mouse presses. we want to test the + // combinations of the button being pressed and the popup being visible. + control.popup.y = control.height + + var downSpy = signalSpy.createObject(control, {target: control, signalName: "downChanged"}) + verify(downSpy.valid) + + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) + verify(pressedSpy.valid) + + mousePress(control) + compare(control.popup.visible, false) + compare(control.pressed, true) + compare(control.down, true) + compare(downSpy.count, 1) + compare(pressedSpy.count, 1) + + mouseRelease(control) + compare(control.popup.visible, true) + compare(control.pressed, false) + compare(control.down, true) + compare(downSpy.count, 3) + compare(pressedSpy.count, 2) + + compare(control.popup.y, control.height) + + control.down = false + compare(control.down, false) + compare(downSpy.count, 4) + + mousePress(control) + compare(control.popup.visible, true) + compare(control.pressed, true) + compare(control.down, false) // explicit false + compare(downSpy.count, 4) + compare(pressedSpy.count, 3) + + control.down = undefined + compare(control.down, true) + compare(downSpy.count, 5) + + mouseRelease(control) + tryCompare(control.popup, "visible", false) + compare(control.pressed, false) + compare(control.down, false) + compare(downSpy.count, 6) + compare(pressedSpy.count, 4) + + control.popup.open() + compare(control.popup.visible, true) + compare(control.pressed, false) + compare(control.down, true) + compare(downSpy.count, 7) + compare(pressedSpy.count, 4) + + control.popup.close() + tryCompare(control.popup, "visible", false) + compare(control.pressed, false) + compare(control.down, false) + compare(downSpy.count, 8) + compare(pressedSpy.count, 4) + } + + function test_focus() { + var control = createTemporaryObject(comboBox, testCase, {model: 3}) + verify(control) + + var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"}) + verify(openedSpy.valid) + + var closedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "closed"}) + verify(openedSpy.valid) + + // click - gain focus - show popup + mouseClick(control) + verify(control.activeFocus) + openedSpy.wait() + compare(openedSpy.count, 1) + compare(control.popup.visible, true) + + // lose focus - hide popup + control.focus = false + verify(!control.activeFocus) + closedSpy.wait() + compare(closedSpy.count, 1) + compare(control.popup.visible, false) + } + + function test_baseline() { + var control = createTemporaryObject(comboBox, testCase) + verify(control) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + } + + Component { + id: displayBox + ComboBox { + textRole: "key" + model: ListModel { + ListElement { key: "First"; value: 123 } + ListElement { key: "Second"; value: 456 } + ListElement { key: "Third"; value: 789 } + } + } + } + + function test_displayText() { + var control = createTemporaryObject(displayBox, testCase) + verify(control) + + compare(control.displayText, "First") + control.currentIndex = 1 + compare(control.displayText, "Second") + control.textRole = "value" + compare(control.displayText, "456") + control.displayText = "Display" + compare(control.displayText, "Display") + control.currentIndex = 2 + compare(control.displayText, "Display") + control.displayText = undefined + compare(control.displayText, "789") + } + + Component { + id: component + Pane { + id: panel + property alias button: _button; + property alias combobox: _combobox; + font.pixelSize: 30 + Column { + Button { + id: _button + text: "Button" + font.pixelSize: 20 + } + ComboBox { + id: _combobox + model: ["ComboBox", "With"] + delegate: ItemDelegate { + width: _combobox.width + text: _combobox.textRole ? (Array.isArray(_combobox.model) ? modelData[_combobox.textRole] : model[_combobox.textRole]) : modelData + objectName: "delegate" + autoExclusive: true + checked: _combobox.currentIndex === index + highlighted: _combobox.highlightedIndex === index + } + } + } + } + } + + function getChild(control, objname, idx) { + var index = idx + for (var i = index+1; i < control.children.length; i++) + { + if (control.children[i].objectName === objname) { + index = i + break + } + } + return index + } + + function test_font() { // QTBUG_50984, QTBUG-51696 + var control = createTemporaryObject(component, testCase) + verify(control) + verify(control.button) + verify(control.combobox) + + compare(control.font.pixelSize, 30) + compare(control.button.font.pixelSize, 20) + compare(control.combobox.font.pixelSize, 30) + +// verify(control.combobox.popup) +// var popup = control.combobox.popup +// popup.open() + +// verify(popup.contentItem) + +// var listview = popup.contentItem +// verify(listview.contentItem) +// waitForRendering(listview) + +// var idx1 = getChild(listview.contentItem, "delegate", -1) +// compare(listview.contentItem.children[idx1].font.pixelSize, 25) +// var idx2 = getChild(listview.contentItem, "delegate", idx1) +// compare(listview.contentItem.children[idx2].font.pixelSize, 25) + +// compare(listview.contentItem.children[idx1].font.pixelSize, 25) +// compare(listview.contentItem.children[idx2].font.pixelSize, 25) + + control.font.pixelSize = control.font.pixelSize + 10 + compare(control.combobox.font.pixelSize, 40) +// waitForRendering(listview) +// compare(listview.contentItem.children[idx1].font.pixelSize, 25) +// compare(listview.contentItem.children[idx2].font.pixelSize, 25) + + control.combobox.font.pixelSize = control.combobox.font.pixelSize + 5 + compare(control.combobox.font.pixelSize, 45) +// waitForRendering(listview) + +// idx1 = getChild(listview.contentItem, "delegate", -1) +// compare(listview.contentItem.children[idx1].font.pixelSize, 25) +// idx2 = getChild(listview.contentItem, "delegate", idx1) +// compare(listview.contentItem.children[idx2].font.pixelSize, 25) + } + + function test_wheel() { + var ma = createTemporaryObject(mouseArea, testCase, {width: 100, height: 100}) + verify(ma) + + var control = comboBox.createObject(ma, {model: 2, wheelEnabled: true}) + verify(control) + + var delta = 120 + + var spy = signalSpy.createObject(ma, {target: ma, signalName: "wheel"}) + verify(spy.valid) + + mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta) + compare(control.currentIndex, 1) + compare(spy.count, 0) // no propagation + + // reached bounds -> no change + mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta) + compare(control.currentIndex, 1) + compare(spy.count, 0) // no propagation + + mouseWheel(control, control.width / 2, control.height / 2, delta, delta) + compare(control.currentIndex, 0) + compare(spy.count, 0) // no propagation + + // reached bounds -> no change + mouseWheel(control, control.width / 2, control.height / 2, delta, delta) + compare(control.currentIndex, 0) + compare(spy.count, 0) // no propagation + } + + function test_activation_data() { + return [ + { tag: "open:enter", key: Qt.Key_Enter, open: true }, + { tag: "open:return", key: Qt.Key_Return, open: true }, + { tag: "closed:enter", key: Qt.Key_Enter, open: false }, + { tag: "closed:return", key: Qt.Key_Return, open: false } + ] + } + + // QTBUG-51645 + function test_activation(data) { + var control = createTemporaryObject(comboBox, testCase, {currentIndex: 1, model: ["Apple", "Orange", "Banana"]}) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + + if (data.open) { + var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"}) + verify(openedSpy.valid) + + keyClick(Qt.Key_Space) + openedSpy.wait() + compare(openedSpy.count, 1) + } + compare(control.popup.visible, data.open) + + compare(control.currentIndex, 1) + compare(control.currentText, "Orange") + compare(control.displayText, "Orange") + + keyClick(data.key) + + compare(control.currentIndex, 1) + compare(control.currentText, "Orange") + compare(control.displayText, "Orange") + } + + Component { + id: asyncLoader + Loader { + active: false + asynchronous: true + sourceComponent: ComboBox { + model: ["First", "Second", "Third"] + } + } + } + + // QTBUG-51972 + function test_async() { + var loader = createTemporaryObject(asyncLoader, testCase) + verify(loader) + + loader.active = true + tryCompare(loader, "status", Loader.Ready) + verify(loader.item) + compare(loader.item.currentText, "First") + compare(loader.item.displayText, "First") + } + + // QTBUG-52615 + function test_currentIndex() { + var control = createTemporaryObject(comboBox, testCase, {currentIndex: -1, model: 3}) + verify(control) + + compare(control.currentIndex, -1) + } + + ListModel { + id: resetmodel + ListElement { text: "First" } + ListElement { text: "Second" } + ListElement { text: "Third" } + } + + // QTBUG-54573 + function test_modelReset() { + var control = createTemporaryObject(comboBox, testCase, {model: resetmodel}) + verify(control) + control.popup.open() + + var listview = control.popup.contentItem + verify(listview) + + tryCompare(listview.contentItem.children, "length", resetmodel.count + 1) // + highlight item + + resetmodel.clear() + resetmodel.append({text: "Fourth"}) + resetmodel.append({text: "Fifth"}) + + tryCompare(listview.contentItem.children, "length", resetmodel.count + 1) // + highlight item + } + + // QTBUG-55118 + function test_currentText() { + var control = createTemporaryObject(comboBox, testCase, {model: listmodel}) + verify(control) + + compare(control.currentIndex, 0) + compare(control.currentText, "First") + + listmodel.setProperty(0, "text", "1st") + compare(control.currentText, "1st") + + control.currentIndex = 1 + compare(control.currentText, "Second") + + listmodel.setProperty(0, "text", "First") + compare(control.currentText, "Second") + } + + // QTBUG-55030 + function test_highlightRange() { + var control = createTemporaryObject(comboBox, testCase, {model: 100}) + verify(control) + + control.currentIndex = 50 + compare(control.currentIndex, 50) + compare(control.highlightedIndex, -1) + + var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"}) + verify(openedSpy.valid) + + control.popup.open() + compare(control.highlightedIndex, 50) + tryCompare(openedSpy, "count", 1) + + var listview = control.popup.contentItem + verify(listview) + + var first = listview.itemAt(0, listview.contentY) + verify(first) + compare(first.text, "50") + + var closedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "closed"}) + verify(closedSpy.valid) + + control.popup.close() + tryCompare(closedSpy, "count", 1) + compare(control.highlightedIndex, -1) + + control.currentIndex = 99 + compare(control.currentIndex, 99) + compare(control.highlightedIndex, -1) + + control.popup.open() + compare(control.highlightedIndex, 99) + tryCompare(openedSpy, "count", 2) + tryVerify(function() { return listview.height > 0 }) + + var last = listview.itemAt(0, listview.contentY + listview.height - 1) + verify(last) + compare(last.text, "99") + + openedSpy.target = null + closedSpy.target = null + } + + function test_mouseHighlight() { + if ((Qt.platform.pluginName === "offscreen") + || (Qt.platform.pluginName === "minimal")) + skip("Mouse highlight not functional on offscreen/minimal platforms") + var control = createTemporaryObject(comboBox, testCase, {model: 20}) + verify(control) + + compare(control.highlightedIndex, -1) + + var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"}) + verify(openedSpy.valid) + + control.popup.open() + compare(control.highlightedIndex, 0) + tryCompare(openedSpy, "count", 1) + + var listview = control.popup.contentItem + verify(listview) + waitForRendering(listview) + + // hover-highlight through all visible list items one by one + var hoverIndex = -1 + var prevHoverItem = null + for (var y = 0; y < listview.height; ++y) { + var hoverItem = listview.itemAt(0, listview.contentY + y) + if (!hoverItem || !hoverItem.visible || hoverItem === prevHoverItem) + continue + mouseMove(hoverItem, 0, 0) + tryCompare(control, "highlightedIndex", ++hoverIndex) + prevHoverItem = hoverItem + } + + mouseMove(listview, listview.width / 2, listview.height / 2) + + // wheel-highlight the rest of the items + var delta = 120 + var prevWheelItem = null + while (!listview.atYEnd) { + var prevContentY = listview.contentY + mouseWheel(listview, listview.width / 2, listview.height / 2, -delta, -delta) + tryCompare(listview, "moving", false) + verify(listview.contentY > prevContentY) + + var wheelItem = listview.itemAt(listview.width / 2, listview.contentY + listview.height / 2) + if (!wheelItem || !wheelItem.visible || wheelItem === prevWheelItem) + continue + + tryCompare(control, "highlightedIndex", parseInt(wheelItem.text)) + prevWheelItem = wheelItem + } + } + + RegularExpressionValidator { + id: regExpValidator + regularExpression: /(red|blue|green)?/ + } + + function test_validator() { + var control = createTemporaryObject(comboBox, testCase, {editable: true, validator: regExpValidator}) + + control.editText = "blu" + compare(control.acceptableInput, false) + control.editText = "blue" + compare(control.acceptableInput, true) + control.editText = "bluee" + compare(control.acceptableInput, false) + control.editText = "" + compare(control.acceptableInput, true) + control.editText = "" + control.contentItem.forceActiveFocus() + keyPress(Qt.Key_A) + compare(control.editText, "") + keyPress(Qt.Key_A) + compare(control.editText, "") + keyPress(Qt.Key_R) + compare(control.editText, "r") + keyPress(Qt.Key_A) + compare(control.editText, "r") + compare(control.acceptableInput, false) + keyPress(Qt.Key_E) + compare(control.editText, "re") + compare(control.acceptableInput, false) + keyPress(Qt.Key_D) + compare(control.editText, "red") + compare(control.acceptableInput, true) + } + + Component { + id: appendFindBox + ComboBox { + editable: true + model: ListModel { + ListElement { text:"first" } + } + onAccepted: { + if (find(editText) === -1) + model.append({text: editText}) + } + } + } + + function test_append_find() { + var control = createTemporaryObject(appendFindBox, testCase) + + compare(control.currentIndex, 0) + compare(control.currentText, "first") + control.contentItem.forceActiveFocus() + compare(control.activeFocus, true) + + control.selectAll() + keyPress(Qt.Key_T) + keyPress(Qt.Key_H) + keyPress(Qt.Key_I) + keyPress(Qt.Key_R) + keyPress(Qt.Key_D) + compare(control.count, 1) + compare(control.currentText, "first") + compare(control.editText, "third") + + keyPress(Qt.Key_Enter) + compare(control.count, 2) + compare(control.currentIndex, 1) + compare(control.currentText, "third") + } + + function test_editable() { + var control = createTemporaryObject(comboBox, testCase, {editable: true, model: ["Banana", "Coco", "Coconut", "Apple", "Cocomuffin"]}) + verify(control) + + control.contentItem.forceActiveFocus() + verify(control.activeFocus) + + var acceptCount = 0 + + var acceptSpy = signalSpy.createObject(control, {target: control, signalName: "accepted"}) + verify(acceptSpy.valid) + + compare(control.editText, "Banana") + compare(control.currentText, "Banana") + compare(control.currentIndex, 0) + compare(acceptSpy.count, 0) + control.editText = "" + + keyPress(Qt.Key_C) + compare(control.editText, "coco") + compare(control.currentText, "Banana") + compare(control.currentIndex, 0) + + keyPress(Qt.Key_Right) + keyPress(Qt.Key_N) + compare(control.editText, "coconut") + compare(control.currentText, "Banana") + compare(control.currentIndex, 0) + + keyPress(Qt.Key_Enter) // Accept + compare(control.editText, "Coconut") + compare(control.currentText, "Coconut") + compare(control.currentIndex, 2) + compare(acceptSpy.count, ++acceptCount) + + keyPress(Qt.Key_Backspace) + keyPress(Qt.Key_Backspace) + keyPress(Qt.Key_Backspace) + keyPress(Qt.Key_M) + compare(control.editText, "Cocomuffin") + compare(control.currentText, "Coconut") + compare(control.currentIndex, 2) + + keyPress(Qt.Key_Enter) // Accept + compare(control.editText, "Cocomuffin") + compare(control.currentText, "Cocomuffin") + compare(control.currentIndex, 4) + compare(acceptSpy.count, ++acceptCount) + + keyPress(Qt.Key_Return) // Accept + compare(control.editText, "Cocomuffin") + compare(control.currentText, "Cocomuffin") + compare(control.currentIndex, 4) + compare(acceptSpy.count, ++acceptCount) + + control.editText = "" + compare(control.editText, "") + compare(control.currentText, "Cocomuffin") + compare(control.currentIndex, 4) + + keyPress(Qt.Key_A) + compare(control.editText, "apple") + compare(control.currentText, "Cocomuffin") + compare(control.currentIndex, 4) + + keyPress(Qt.Key_Return) // Accept + compare(control.editText, "Apple") + compare(control.currentText, "Apple") + compare(control.currentIndex, 3) + compare(acceptSpy.count, ++acceptCount) + + control.editText = "" + keyPress(Qt.Key_A) + keyPress(Qt.Key_B) + compare(control.editText, "ab") + compare(control.currentText, "Apple") + compare(control.currentIndex, 3) + + keyPress(Qt.Key_Return) // Accept + compare(control.editText, "ab") + compare(control.currentText, "") + compare(control.currentIndex, -1) + compare(acceptSpy.count, ++acceptCount) + + control.editText = "" + compare(control.editText, "") + compare(control.currentText, "") + compare(control.currentIndex, -1) + + keyPress(Qt.Key_C) + keyPress(Qt.Key_Return) // Accept + compare(control.editText, "Coco") + compare(control.currentText, "Coco") + compare(control.currentIndex, 1) + compare(acceptSpy.count, ++acceptCount) + + keyPress(Qt.Key_Down) + compare(control.editText, "Coconut") + compare(control.currentText, "Coconut") + compare(control.currentIndex, 2) + + keyPress(Qt.Key_Up) + compare(control.editText, "Coco") + compare(control.currentText, "Coco") + compare(control.currentIndex, 1) + + control.editText = "" + compare(control.editText, "") + compare(control.currentText, "Coco") + compare(control.currentIndex, 1) + + keyPress(Qt.Key_C) + keyPress(Qt.Key_O) + keyPress(Qt.Key_C) // autocompletes "coco" + keyPress(Qt.Key_Backspace) + keyPress(Qt.Key_Return) // Accept "coc" + compare(control.editText, "coc") + compare(control.currentText, "") + compare(control.currentIndex, -1) + compare(acceptSpy.count, ++acceptCount) + + control.editText = "" + compare(control.editText, "") + compare(control.currentText, "") + compare(control.currentIndex, -1) + + keyPress(Qt.Key_C) + keyPress(Qt.Key_O) + keyPress(Qt.Key_C) // autocompletes "coc" + keyPress(Qt.Key_Space) + keyPress(Qt.Key_Return) // Accept "coc " + compare(control.editText, "coc ") + compare(control.currentText, "") + compare(control.currentIndex, -1) + compare(acceptSpy.count, ++acceptCount) + } + + Component { + id: keysAttachedBox + ComboBox { + editable: true + property bool gotit: false + Keys.onPressed: { + if (!gotit && event.key === Qt.Key_B) { + gotit = true + event.accepted = true + } + } + } + } + + function test_keys_attached() { + var control = createTemporaryObject(keysAttachedBox, testCase) + verify(control) + + control.contentItem.forceActiveFocus() + verify(control.activeFocus) + + verify(!control.gotit) + compare(control.editText, "") + + keyPress(Qt.Key_A) + verify(control.activeFocus) + verify(!control.gotit) + compare(control.editText, "a") + + keyPress(Qt.Key_B) + verify(control.activeFocus) + verify(control.gotit) + compare(control.editText, "a") + + keyPress(Qt.Key_B) + verify(control.activeFocus) + verify(control.gotit) + compare(control.editText, "ab") + } + + function test_minusOneIndexResetsSelection_QTBUG_35794_data() { + return [ + { tag: "editable", editable: true }, + { tag: "non-editable", editable: false } + ] + } + + function test_minusOneIndexResetsSelection_QTBUG_35794(data) { + var control = createTemporaryObject(comboBox, testCase, {editable: data.editable, model: ["A", "B", "C"]}) + verify(control) + + compare(control.currentIndex, 0) + compare(control.currentText, "A") + control.currentIndex = -1 + compare(control.currentIndex, -1) + compare(control.currentText, "") + control.currentIndex = 1 + compare(control.currentIndex, 1) + compare(control.currentText, "B") + } + + function test_minusOneToZeroSelection_QTBUG_38036() { + var control = createTemporaryObject(comboBox, testCase, {model: ["A", "B", "C"]}) + verify(control) + + compare(control.currentIndex, 0) + compare(control.currentText, "A") + control.currentIndex = -1 + compare(control.currentIndex, -1) + compare(control.currentText, "") + control.currentIndex = 0 + compare(control.currentIndex, 0) + compare(control.currentText, "A") + } + + function test_emptyPopupAfterModelCleared() { + var control = createTemporaryObject(comboBox, testCase, { model: 1 }) + verify(control) + compare(control.popup.implicitHeight, 0) + + // Ensure that it's open so that the popup's implicitHeight changes when we increase the model count. + control.popup.open() + tryCompare(control.popup, "visible", true) + + // Add lots of items to the model. The popup should take up the entire height of the window. + control.model = 100 + compare(control.popup.height, control.Window.height - control.popup.topMargin - control.popup.bottomMargin) + + control.popup.close() + + // Clearing the model should result in a zero height. + control.model = 0 + control.popup.open() + tryCompare(control.popup, "visible", true) + compare(control.popup.height, control.popup.topPadding + control.popup.bottomPadding) + } + + Component { + id: keysMonitor + Item { + property int pressedKeys: 0 + property int releasedKeys: 0 + property int lastPressedKey: 0 + property int lastReleasedKey: 0 + property alias comboBox: comboBox + + width: 200 + height: 200 + + Keys.onPressed: { ++pressedKeys; lastPressedKey = event.key } + Keys.onReleased: { ++releasedKeys; lastReleasedKey = event.key } + + ComboBox { + id: comboBox + } + } + } + + function test_keyClose_data() { + return [ + { tag: "Escape", key: Qt.Key_Escape }, + { tag: "Back", key: Qt.Key_Back } + ] + } + + function test_keyClose(data) { + var container = createTemporaryObject(keysMonitor, testCase) + verify(container) + + var control = comboBox.createObject(container) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + + var pressedKeys = 0 + var releasedKeys = 0 + + // popup not visible -> propagates + keyPress(data.key) + compare(container.pressedKeys, ++pressedKeys) + compare(container.lastPressedKey, data.key) + + keyRelease(data.key) + compare(container.releasedKeys, ++releasedKeys) + compare(container.lastReleasedKey, data.key) + + verify(control.activeFocus) + + // popup visible -> handled -> does not propagate + control.popup.open() + tryCompare(control.popup, "opened", true) + + keyPress(data.key) + compare(container.pressedKeys, pressedKeys) + + keyRelease(data.key) + // Popup receives the key release event if it has an exit transition, but + // not if it has been immediately closed on press, without a transition. + // ### TODO: Should Popup somehow always block the key release event? + if (!control.popup.exit) + ++releasedKeys + compare(container.releasedKeys, releasedKeys) + + tryCompare(control.popup, "visible", false) + verify(control.activeFocus) + + // popup not visible -> propagates + keyPress(data.key) + compare(container.pressedKeys, ++pressedKeys) + compare(container.lastPressedKey, data.key) + + keyRelease(data.key) + compare(container.releasedKeys, ++releasedKeys) + compare(container.lastReleasedKey, data.key) + } + + function test_popupFocus_QTBUG_74661() { + var control = createTemporaryObject(comboBox, testCase) + verify(control) + + var popup = createTemporaryObject(customPopup, testCase) + verify(popup) + + control.popup = popup + + var openedSpy = signalSpy.createObject(control, {target: popup, signalName: "opened"}) + verify(openedSpy.valid) + + var closedSpy = signalSpy.createObject(control, {target: popup, signalName: "closed"}) + verify(closedSpy.valid) + + control.forceActiveFocus() + verify(control.activeFocus) + + // show popup + keyClick(Qt.Key_Space) + openedSpy.wait() + compare(openedSpy.count, 1) + + popup.contentItem.forceActiveFocus() + verify(popup.contentItem.activeFocus) + + // type something in the text field + keyClick(Qt.Key_Space) + keyClick(Qt.Key_H) + keyClick(Qt.Key_I) + compare(popup.contentItem.text, " hi") + + compare(closedSpy.count, 0) + + // hide popup + keyClick(Qt.Key_Escape) + closedSpy.wait() + compare(closedSpy.count, 1) + } + + function test_comboBoxWithShaderEffect() { + var control = createTemporaryObject(comboBoxWithShaderEffect, testCase, {model: 9}) + verify(control) + waitForRendering(control) + control.forceActiveFocus() + var openedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "opened"}) + verify(openedSpy.valid) + + var closedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "closed"}) + verify(closedSpy.valid) + + control.popup.open() + openedSpy.wait() + compare(openedSpy.count, 1) + control.popup.close() + closedSpy.wait() + compare(closedSpy.count, 1) + } + + function test_comboBoxSelectTextByMouse() { + let control = createTemporaryObject(comboBox, testCase, + { editable: true, selectTextByMouse: true, model: [ "Some text" ], width: parent.width }) + verify(control) + waitForRendering(control) + control.forceActiveFocus() + + // Position the text cursor at the beginning of the text. + mouseClick(control, control.leftPadding, control.height / 2) + // Select all of the text. + mousePress(control, control.leftPadding, control.height / 2) + mouseMove(control, control.leftPadding + control.contentItem.width, control.height / 2) + mouseRelease(control, control.leftPadding + control.contentItem.width, control.height / 2) + compare(control.contentItem.selectedText, "Some text") + } + + // QTBUG-78885: When the edit text is changed on an editable ComboBox, + // and then that ComboBox loses focus, its currentIndex should change + // to the index of the edit text (assuming a match is found). + function test_currentIndexChangeOnLostFocus() { + if (Qt.styleHints.tabFocusBehavior !== Qt.TabFocusAllControls) + skip("This platform only allows tab focus for text controls") + + let theModel = [] + for (let i = 0; i < 10; ++i) + theModel.push("Item " + (i + 1)) + + let comboBox1 = createTemporaryObject(comboBox, testCase, + { objectName: "comboBox1", editable: true, model: theModel }) + verify(comboBox1) + compare(comboBox1.currentIndex, 0) + + let comboBox2 = createTemporaryObject(comboBox, testCase, { objectName: "comboBox2" }) + verify(comboBox2) + + // Give the first ComboBox focus and type in 0 to select "Item 10" (default is "Item 1"). + waitForRendering(comboBox1) + comboBox1.contentItem.forceActiveFocus() + verify(comboBox1.activeFocus) + keyClick(Qt.Key_0) + compare(comboBox1.editText, "Item 10") + + let currentIndexSpy = signalSpy.createObject(comboBox1, + { target: comboBox1, signalName: "currentIndexChanged" }) + verify(currentIndexSpy.valid) + + // Give focus to the other ComboBox so that the first one loses it. + // The first ComboBox's currentIndex should change to that of "Item 10". + keyClick(Qt.Key_Tab) + verify(comboBox2.activeFocus) + compare(comboBox1.currentIndex, 9) + compare(currentIndexSpy.count, 1) + + // Give focus back to the first ComboBox, and try the same thing except + // with non-existing text; the currentIndex should not change. + comboBox1.contentItem.forceActiveFocus() + verify(comboBox1.activeFocus) + keySequence(StandardKey.SelectAll) + compare(comboBox1.contentItem.selectedText, "Item 10") + keyClick(Qt.Key_N) + keyClick(Qt.Key_O) + keyClick(Qt.Key_P) + keyClick(Qt.Key_E) + compare(comboBox1.editText, "nope") + compare(comboBox1.currentIndex, 9) + compare(currentIndexSpy.count, 1) + } + + Component { + id: appFontTextFieldComponent + TextField { + objectName: "appFontTextField" + font: Qt.application.font + // We don't want the background's implicit width to interfere with our tests, + // which are about implicit width of the contentItem of ComboBox, which is by default TextField. + background: null + } + } + + Component { + id: appFontContentItemComboBoxComponent + ComboBox { + // Override the contentItem so that the font doesn't vary between styles. + contentItem: TextField { + objectName: "appFontContentItemTextField" + // We do this just to be extra sure that the font never comes from the control, + // as we want it to match that of the TextField in the appFontTextFieldComponent. + font: Qt.application.font + background: null + } + } + } + + Component { + id: twoItemListModelComponent + + ListModel { + ListElement { display: "Short" } + ListElement { display: "Kinda long" } + } + } + + function appendedToModel(model, item) { + if (Array.isArray(model)) { + let newModel = model + newModel.push(item) + return newModel + } + + if (model.hasOwnProperty("append")) { + model.append({ display: item }) + // To account for the fact that changes to a JS array are not seen by the QML engine, + // we need to reassign the entire model and hence return it. For simplicity in the + // calling code, we do it for the ListModel code path too. It should be a no-op. + return model + } + + console.warn("appendedToModel: unrecognised model") + return undefined + } + + function removedFromModel(model, index, count) { + if (Array.isArray(model)) { + let newModel = model + newModel.splice(index, count) + return newModel + } + + if (model.hasOwnProperty("remove")) { + model.remove(index, count) + return model + } + + console.warn("removedFromModel: unrecognised model") + return undefined + } + + // We don't use a data-driven test for the policy because the checks vary a lot based on which enum we're testing. + function test_implicitContentWidthPolicy_ContentItemImplicitWidth() { + // Set ContentItemImplicitWidth and ensure that implicitContentWidth is as wide as the current item + // by comparing it against the implicitWidth of an identical TextField + let control = createTemporaryObject(appFontContentItemComboBoxComponent, testCase, { + model: ["Short", "Kinda long"], + implicitContentWidthPolicy: ComboBox.ContentItemImplicitWidth + }) + verify(control) + compare(control.implicitContentWidthPolicy, ComboBox.ContentItemImplicitWidth) + + let textField = createTemporaryObject(appFontTextFieldComponent, testCase) + verify(textField) + // Don't set any text on textField because we're not accounting for the widest + // text here, so we want to compare it against an empty TextField. + compare(control.implicitContentWidth, textField.implicitWidth) + + textField.font.pixelSize *= 2 + control.font.pixelSize *= 2 + compare(control.implicitContentWidth, textField.implicitWidth) + } + + function test_implicitContentWidthPolicy_WidestText_data() { + return [ + { tag: "Array", model: ["Short", "Kinda long"] }, + { tag: "ListModel", model: twoItemListModelComponent.createObject(testCase) }, + ] + } + + function test_implicitContentWidthPolicy_WidestText(data) { + let control = createTemporaryObject(appFontContentItemComboBoxComponent, testCase, { + model: data.model, + implicitContentWidthPolicy: ComboBox.WidestText + }) + verify(control) + compare(control.implicitContentWidthPolicy, ComboBox.WidestText) + + let textField = createTemporaryObject(appFontTextFieldComponent, testCase) + verify(textField) + textField.text = "Kinda long" + // Note that we don't need to change the current index here, as the implicitContentWidth + // is set to the implicitWidth of the TextField within the ComboBox as if it had the largest + // text from the model set on it. + // We use Math.ceil because TextInput uses qCeil internally, whereas the implicitWidth + // binding for TextField does not. + compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth)) + + // Add a longer item; it should affect the implicit content width. + let modifiedModel = appendedToModel(data.model, "Moderately long") + control.model = modifiedModel + textField.text = "Moderately long" + compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth)) + + // Remove the last two items; it should use the only remaining item's width. + modifiedModel = removedFromModel(data.model, 1, 2) + control.model = modifiedModel + compare(control.count, 1) + compare(control.currentText, "Short") + textField.text = "Short" + compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth)) + + // Changes in font should result in the implicitContentWidth being updated. + textField.font.pixelSize *= 2 + // We have to change the contentItem's font size manually since we break the + // style's binding to the control's font when we set Qt.application.font to it. + control.contentItem.font.pixelSize *= 2 + control.font.pixelSize *= 2 + compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth)) + } + + function test_implicitContentWidthPolicy_WidestTextWhenCompleted_data() { + return test_implicitContentWidthPolicy_WidestText_data() + } + + function test_implicitContentWidthPolicy_WidestTextWhenCompleted(data) { + let control = createTemporaryObject(appFontContentItemComboBoxComponent, testCase, { + model: data.model, + implicitContentWidthPolicy: ComboBox.WidestTextWhenCompleted + }) + verify(control) + compare(control.implicitContentWidthPolicy, ComboBox.WidestTextWhenCompleted) + + let textField = createTemporaryObject(appFontTextFieldComponent, testCase) + verify(textField) + textField.text = "Kinda long" + compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth)) + + // Add a longer item; it should not affect the implicit content width + // since we've already accounted for it once. + let modifiedModel = appendedToModel(data.model, "Moderately long") + control.model = modifiedModel + compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth)) + + // Remove the last two items; it should still not affect the implicit content width. + modifiedModel = removedFromModel(data.model, 1, 2) + control.model = modifiedModel + compare(control.count, 1) + compare(control.currentText, "Short") + compare(Math.ceil(control.implicitContentWidth), Math.ceil(textField.implicitWidth)) + + // Changes in font should not result in the implicitContentWidth being updated. + let oldTextFieldImplicitWidth = textField.implicitWidth + // Changes in font should result in the implicitContentWidth being updated. + textField.font.pixelSize *= 2 + control.contentItem.font.pixelSize *= 2 + control.font.pixelSize *= 2 + compare(Math.ceil(control.implicitContentWidth), Math.ceil(oldTextFieldImplicitWidth)) + } + + // QTBUG-61021: text line should not be focused by default + // It causes (e.g. on Android) showing virtual keyboard when it is not needed + function test_doNotFocusTextLineByDefault() { + var control = createTemporaryObject(comboBox, testCase) + // Focus not set after creating combobox + verify(!control.activeFocus) + verify(!control.contentItem.focus) + + // After setting focus on combobox, text line should not be focused + control.forceActiveFocus() + verify(control.activeFocus) + verify(!control.contentItem.focus) + + // Text line is focused after intentional setting focus on it + control.contentItem.forceActiveFocus() + verify(control.activeFocus) + verify(control.contentItem.focus) + } + + Component { + id: intValidatorComponent + IntValidator { + bottom: 0 + top: 255 + } + } + + function test_acceptableInput_QTBUG_94307() { + let items = [ + { text: "A" }, + { text: "2" }, + { text: "3" } + ] + let control = createTemporaryObject(comboBox, testCase, {model: items, editable: true}) + verify(control) + + verify(control.acceptableInput) + compare(control.displayText, "A") + + let acceptableInputSpy = signalSpy.createObject(control, {target: control, signalName: "acceptableInputChanged"}) + verify(acceptableInputSpy.valid) + + let intValidator = intValidatorComponent.createObject(testCase) + verify(intValidator) + + control.validator = intValidator + + compare(acceptableInputSpy.count, 1) + compare(control.displayText, "A") + compare(control.acceptableInput, false) + + control.currentIndex = 1 + + compare(acceptableInputSpy.count, 2) + compare(control.displayText, "2") + compare(control.acceptableInput, true) + } + + function test_selectionCleared() { + const model = [ + { text: "Apple" }, + { text: "Banana" }, + { text: "Coconut" } + ] + let control = createTemporaryObject(comboBox, testCase, { model: model, editable: true }) + verify(control) + + compare(control.displayText, "Apple") + compare(control.editText, "Apple") + compare(control.currentIndex, 0) + + // Give the TextField focus and select the text. + let textField = control.contentItem + textField.forceActiveFocus() + textField.selectAll() + compare(textField.selectedText, "Apple") + + // Type "B" so that Banana is selected. + keyPress(Qt.Key_Shift) + keyClick(Qt.Key_B) + keyRelease(Qt.Key_Shift) + compare(control.displayText, "Apple") + expectFail("", "QTBUG-102950") + compare(control.editText, "Banana") + compare(textField.selectedText, "anana") + compare(control.currentIndex, 0) + + // Select Banana by pressing enter. + keyClick(Qt.Key_Return) + compare(control.displayText, "Banana") + compare(control.editText, "Banana") + compare(textField.selectedText, "") + compare(control.currentIndex, 1) + } + + // QTBUG-109721 - verify that an eaten press event for the space key + // doesn't open the popup when the key is released. + Component { + id: comboboxEatsSpace + ComboBox { + id: nonEditableComboBox + editable: false + model: ["NonEditable", "Delta", "Echo", "Foxtrot"] + Keys.onSpacePressed: (event) => event.accept + } + } + + function test_spacePressEaten() { + let control = createTemporaryObject(comboboxEatsSpace, testCase) + verify(control) + control.forceActiveFocus() + + var visibleChangedSpy = signalSpy.createObject(control, {target: control.popup, signalName: "visibleChanged"}) + verify(visibleChangedSpy.valid) + + // press doesn't open + keyPress(Qt.Key_Space) + verify(!control.pressed) + compare(visibleChangedSpy.count, 0) + // neither does release + keyRelease(Qt.Key_Space) + compare(visibleChangedSpy.count, 0) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_container.qml b/tests/auto/quickcontrols2/controls/data/tst_container.qml new file mode 100644 index 00000000000..5fa3137ade3 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_container.qml @@ -0,0 +1,298 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls +import QtQuick.Templates as T + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "Container" + + Component { + id: container + Container { } + } + + Component { + id: rectangle + Rectangle { } + } + + function test_implicitSize() { + var control = createTemporaryObject(container, testCase) + verify(control) + + compare(control.implicitWidth, 0) + compare(control.implicitHeight, 0) + + control.contentItem = rectangle.createObject(control, {implicitWidth: 10, implicitHeight: 20}) + compare(control.implicitWidth, 10) + compare(control.implicitHeight, 20) + + control.background = rectangle.createObject(control, {implicitWidth: 20, implicitHeight: 30}) + compare(control.implicitWidth, 20) + compare(control.implicitHeight, 30) + + control.padding = 100 + compare(control.implicitWidth, 210) + compare(control.implicitHeight, 220) + } + + function test_currentIndex() { + var control1 = createTemporaryObject(container, testCase) + verify(control1) + + var control2 = createTemporaryObject(container, testCase) + verify(control2) + + compare(control1.currentIndex, -1) + compare(control2.currentIndex, -1) + + for (var i = 0; i < 3; ++i) { + control1.addItem(rectangle.createObject(control1)) + control2.addItem(rectangle.createObject(control2)) + } + + compare(control1.count, 3) + compare(control2.count, 3) + compare(control1.currentIndex, 0) + compare(control2.currentIndex, 0) + + control1.currentIndex = Qt.binding(function() { return control2.currentIndex }) + control2.currentIndex = Qt.binding(function() { return control1.currentIndex }) + + control1.setCurrentIndex(1) + compare(control1.currentIndex, 1) + compare(control2.currentIndex, 1) + + control1.incrementCurrentIndex() + compare(control1.currentIndex, 2) + compare(control2.currentIndex, 2) + + control2.decrementCurrentIndex() + compare(control1.currentIndex, 1) + compare(control2.currentIndex, 1) + } + + Component { + id: repeaterContainer1 + Container { + id: container + Item { objectName: "0" } + Item { objectName: "1" } + Item { objectName: "2" } + Item { objectName: "3" } + contentItem: Row { + Repeater { + model: container.contentModel + } + } + } + } + + Component { + id: repeaterContainer2 + Container { + id: container + contentItem: Item { + Repeater { + model: container.contentModel + } + Rectangle { objectName: "extra" } + } + Rectangle { objectName: "0" } + Rectangle { objectName: "1" } + Rectangle { objectName: "2" } + Rectangle { objectName: "3" } + } + } + + function test_repeater_data() { + return [ + { tag: "1", component: repeaterContainer1 }, + { tag: "2", component: repeaterContainer2 } + ] + } + + // don't crash (QTBUG-61310) + function test_repeater(data) { + var control = createTemporaryObject(data.component, testCase) + verify(control) + + compare(control.itemAt(0).objectName, "0") + compare(control.itemAt(1).objectName, "1") + compare(control.itemAt(2).objectName, "2") + compare(control.itemAt(3).objectName, "3") + } + + function test_removeTakeItem() { + var control = createTemporaryObject(container, testCase) + verify(control) + + var item1 = rectangle.createObject(control) + var item2 = rectangle.createObject(control) + var item3 = rectangle.createObject(control) + + item1.Component.onDestruction.connect(function() { item1 = null }) + item2.Component.onDestruction.connect(function() { item2 = null }) + item3.Component.onDestruction.connect(function() { item3 = null }) + + control.addItem(item1) + control.addItem(item2) + control.addItem(item3) + compare(control.count, 3) + + // takeItem(int) does not destroy + compare(control.takeItem(1), item2) + compare(control.count, 2) + wait(1) + verify(item2) + + // removeItem(Item) destroys + control.removeItem(item1) + compare(control.count, 1) + wait(1) + verify(!item1) + + // removeItem(null) must not call removeItem(0) + control.removeItem(null) + compare(control.count, 1) + wait(1) + verify(item3) + } + + Component { + id: contentItemDeletionOrder1 + + Item { + objectName: "parentItem" + + Item { + id: item + objectName: "contentItem" + } + Container { + objectName: "control" + contentItem: item + } + } + } + + Component { + id: contentItemDeletionOrder2 + + Item { + objectName: "parentItem" + + Container { + objectName: "control" + contentItem: item + } + Item { + id: item + objectName: "contentItem" + } + } + } + + function test_contentItemDeletionOrder() { + var control1 = createTemporaryObject(contentItemDeletionOrder1, testCase) + verify(control1) + var control2 = createTemporaryObject(contentItemDeletionOrder2, testCase) + verify(control2) + } + + Component { + id: backgroundDeletionOrder1 + + Item { + objectName: "parentItem" + + Item { + id: item + objectName: "backgroundItem" + } + Container { + objectName: "control" + background: item + } + } + } + + Component { + id: backgroundDeletionOrder2 + + Item { + objectName: "parentItem" + + Container { + objectName: "control" + background: item + } + Item { + id: item + objectName: "backgroundItem" + } + } + } + + function test_backgroundDeletionOrder() { + var control1 = createTemporaryObject(backgroundDeletionOrder1, testCase) + verify(control1) + var control2 = createTemporaryObject(backgroundDeletionOrder2, testCase) + verify(control2) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_control.qml b/tests/auto/quickcontrols2/controls/data/tst_control.qml new file mode 100644 index 00000000000..e12cbbf4ef2 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_control.qml @@ -0,0 +1,1499 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls +import QtQuick.Templates as T + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "Control" + + Component { + id: component + Control { } + } + + Component { + id: rectangle + Rectangle { } + } + + Component { + id: button + T.Button { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_padding() { + var control = createTemporaryObject(component, testCase) + verify(control) + + var paddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "paddingChanged"}) + verify(paddingSpy.valid) + + var topPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "topPaddingChanged"}) + verify(topPaddingSpy.valid) + + var leftPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "leftPaddingChanged"}) + verify(leftPaddingSpy.valid) + + var rightPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "rightPaddingChanged"}) + verify(rightPaddingSpy.valid) + + var bottomPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "bottomPaddingChanged"}) + verify(bottomPaddingSpy.valid) + + var horizontalPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "horizontalPaddingChanged"}) + verify(horizontalPaddingSpy.valid) + + var verticalPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "verticalPaddingChanged"}) + verify(verticalPaddingSpy.valid) + + var paddingChanges = 0 + var topPaddingChanges = 0 + var leftPaddingChanges = 0 + var rightPaddingChanges = 0 + var bottomPaddingChanges = 0 + var horizontalPaddingChanges = 0 + var verticalPaddingChanges = 0 + + compare(control.padding, 0) + compare(control.topPadding, 0) + compare(control.leftPadding, 0) + compare(control.rightPadding, 0) + compare(control.bottomPadding, 0) + compare(control.horizontalPadding, 0) + compare(control.verticalPadding, 0) + compare(control.availableWidth, 0) + compare(control.availableHeight, 0) + + control.width = 100 + control.height = 100 + + control.padding = 10 + compare(control.padding, 10) + compare(control.topPadding, 10) + compare(control.leftPadding, 10) + compare(control.rightPadding, 10) + compare(control.bottomPadding, 10) + compare(control.horizontalPadding, 10) + compare(control.verticalPadding, 10) + compare(paddingSpy.count, ++paddingChanges) + compare(topPaddingSpy.count, ++topPaddingChanges) + compare(leftPaddingSpy.count, ++leftPaddingChanges) + compare(rightPaddingSpy.count, ++rightPaddingChanges) + compare(bottomPaddingSpy.count, ++bottomPaddingChanges) + compare(horizontalPaddingSpy.count, ++horizontalPaddingChanges) + compare(verticalPaddingSpy.count, ++verticalPaddingChanges) + + control.topPadding = 20 + compare(control.padding, 10) + compare(control.topPadding, 20) + compare(control.leftPadding, 10) + compare(control.rightPadding, 10) + compare(control.bottomPadding, 10) + compare(control.horizontalPadding, 10) + compare(control.verticalPadding, 10) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, ++topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + compare(horizontalPaddingSpy.count, horizontalPaddingChanges) + compare(verticalPaddingSpy.count, verticalPaddingChanges) + + control.leftPadding = 30 + compare(control.padding, 10) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 10) + compare(control.bottomPadding, 10) + compare(control.horizontalPadding, 10) + compare(control.verticalPadding, 10) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, ++leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + compare(horizontalPaddingSpy.count, horizontalPaddingChanges) + compare(verticalPaddingSpy.count, verticalPaddingChanges) + + control.rightPadding = 40 + compare(control.padding, 10) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 40) + compare(control.bottomPadding, 10) + compare(control.horizontalPadding, 10) + compare(control.verticalPadding, 10) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, ++rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + compare(horizontalPaddingSpy.count, horizontalPaddingChanges) + compare(verticalPaddingSpy.count, verticalPaddingChanges) + + control.bottomPadding = 50 + compare(control.padding, 10) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 40) + compare(control.bottomPadding, 50) + compare(control.horizontalPadding, 10) + compare(control.verticalPadding, 10) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, ++bottomPaddingChanges) + compare(horizontalPaddingSpy.count, horizontalPaddingChanges) + compare(verticalPaddingSpy.count, verticalPaddingChanges) + + control.padding = 60 + compare(control.padding, 60) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 40) + compare(control.bottomPadding, 50) + compare(control.horizontalPadding, 60) + compare(control.verticalPadding, 60) + compare(paddingSpy.count, ++paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + compare(horizontalPaddingSpy.count, ++horizontalPaddingChanges) + compare(verticalPaddingSpy.count, ++verticalPaddingChanges) + + control.horizontalPadding = 80 + compare(control.padding, 60) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 40) + compare(control.bottomPadding, 50) + compare(control.horizontalPadding, 80) + compare(control.verticalPadding, 60) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + compare(horizontalPaddingSpy.count, ++horizontalPaddingChanges) + compare(verticalPaddingSpy.count, verticalPaddingChanges) + + control.verticalPadding = 90 + compare(control.padding, 60) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 40) + compare(control.bottomPadding, 50) + compare(control.horizontalPadding, 80) + compare(control.verticalPadding, 90) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + compare(horizontalPaddingSpy.count, horizontalPaddingChanges) + compare(verticalPaddingSpy.count, ++verticalPaddingChanges) + + control.leftPadding = undefined + compare(control.padding, 60) + compare(control.topPadding, 20) + compare(control.leftPadding, 80) + compare(control.rightPadding, 40) + compare(control.bottomPadding, 50) + compare(control.horizontalPadding, 80) + compare(control.verticalPadding, 90) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, ++leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + compare(horizontalPaddingSpy.count, horizontalPaddingChanges) + compare(verticalPaddingSpy.count, verticalPaddingChanges) + + control.rightPadding = undefined + compare(control.padding, 60) + compare(control.topPadding, 20) + compare(control.leftPadding, 80) + compare(control.rightPadding, 80) + compare(control.bottomPadding, 50) + compare(control.horizontalPadding, 80) + compare(control.verticalPadding, 90) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, ++rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + compare(horizontalPaddingSpy.count, horizontalPaddingChanges) + compare(verticalPaddingSpy.count, verticalPaddingChanges) + + control.topPadding = undefined + compare(control.padding, 60) + compare(control.topPadding, 90) + compare(control.leftPadding, 80) + compare(control.rightPadding, 80) + compare(control.bottomPadding, 50) + compare(control.horizontalPadding, 80) + compare(control.verticalPadding, 90) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, ++topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + compare(horizontalPaddingSpy.count, horizontalPaddingChanges) + compare(verticalPaddingSpy.count, verticalPaddingChanges) + + control.bottomPadding = undefined + compare(control.padding, 60) + compare(control.topPadding, 90) + compare(control.leftPadding, 80) + compare(control.rightPadding, 80) + compare(control.bottomPadding, 90) + compare(control.horizontalPadding, 80) + compare(control.verticalPadding, 90) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, ++bottomPaddingChanges) + compare(horizontalPaddingSpy.count, horizontalPaddingChanges) + compare(verticalPaddingSpy.count, verticalPaddingChanges) + + control.horizontalPadding = undefined + compare(control.padding, 60) + compare(control.topPadding, 90) + compare(control.leftPadding, 60) + compare(control.rightPadding, 60) + compare(control.bottomPadding, 90) + compare(control.horizontalPadding, 60) + compare(control.verticalPadding, 90) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, ++leftPaddingChanges) + compare(rightPaddingSpy.count, ++rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + compare(horizontalPaddingSpy.count, ++horizontalPaddingChanges) + compare(verticalPaddingSpy.count, verticalPaddingChanges) + + control.verticalPadding = undefined + compare(control.padding, 60) + compare(control.topPadding, 60) + compare(control.leftPadding, 60) + compare(control.rightPadding, 60) + compare(control.bottomPadding, 60) + compare(control.horizontalPadding, 60) + compare(control.verticalPadding, 60) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, ++topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, ++bottomPaddingChanges) + compare(horizontalPaddingSpy.count, horizontalPaddingChanges) + compare(verticalPaddingSpy.count, ++verticalPaddingChanges) + } + + function test_availableSize() { + var control = createTemporaryObject(component, testCase) + verify(control) + + var availableWidthSpy = signalSpy.createObject(control, {target: control, signalName: "availableWidthChanged"}) + verify(availableWidthSpy.valid) + + var availableHeightSpy = signalSpy.createObject(control, {target: control, signalName: "availableHeightChanged"}) + verify(availableHeightSpy.valid) + + var availableWidthChanges = 0 + var availableHeightChanges = 0 + + control.width = 100 + compare(control.availableWidth, 100) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.height = 100 + compare(control.availableHeight, 100) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + + control.padding = 10 + compare(control.availableWidth, 80) + compare(control.availableHeight, 80) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + + control.topPadding = 20 + compare(control.availableWidth, 80) + compare(control.availableHeight, 70) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + + control.leftPadding = 30 + compare(control.availableWidth, 60) + compare(control.availableHeight, 70) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.rightPadding = 40 + compare(control.availableWidth, 30) + compare(control.availableHeight, 70) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.bottomPadding = 50 + compare(control.availableWidth, 30) + compare(control.availableHeight, 30) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + + control.padding = 60 + compare(control.availableWidth, 30) + compare(control.availableHeight, 30) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.width = 0 + compare(control.availableWidth, 0) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.height = 0 + compare(control.availableHeight, 0) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + } + + function test_mirrored() { + var control = createTemporaryObject(component, testCase) + verify(control) + + var mirroredSpy = signalSpy.createObject(control, {target: control, signalName: "mirroredChanged"}) + verify(mirroredSpy.valid) + + control.locale = Qt.locale("en_US") + compare(control.locale.name, "en_US") + verify(!control.LayoutMirroring.enabled) + compare(control.mirrored, false) + + control.locale = Qt.locale("ar_EG") + compare(control.mirrored, false) + compare(mirroredSpy.count, 0) + + control.LayoutMirroring.enabled = true + compare(control.mirrored, true) + compare(mirroredSpy.count, 1) + + control.locale = Qt.locale("en_US") + compare(control.mirrored, true) + compare(mirroredSpy.count, 1) + + control.LayoutMirroring.enabled = false + compare(control.mirrored, false) + compare(mirroredSpy.count, 2) + } + + function test_background() { + var control = createTemporaryObject(component, testCase) + verify(control) + + control.background = component.createObject(control) + + // background has no x or width set, so its width follows control's width + control.width = 320 + compare(control.background.width, control.width) + + // background has no y or height set, so its height follows control's height + compare(control.background.height, control.height) + control.height = 240 + + // change implicit size (QTBUG-66455) + control.background.implicitWidth = 160 + control.background.implicitHeight = 120 + compare(control.background.width, control.width) + compare(control.background.height, control.height) + + // has width => width does not follow + control.background.width /= 2 + control.width += 20 + verify(control.background.width !== control.width) + + // reset width => width follows again + control.background.width = undefined + control.width += 20 + compare(control.background.width, control.width) + + // has x => width does not follow + control.background.x = 10 + control.width += 20 + verify(control.background.width !== control.width) + + // has height => height does not follow + control.background.height /= 2 + control.height -= 20 + verify(control.background.height !== control.height) + + // reset height => height follows again + control.background.height = undefined + control.height -= 20 + compare(control.background.height, control.height) + + // has y => height does not follow + control.background.y = 10 + control.height -= 20 + verify(control.background.height !== control.height) + } + + Component { + id: component2 + T.Control { + id: item2 + objectName: "item2" + property alias item2_2: _item2_2; + property alias item2_3: _item2_3; + property alias item2_4: _item2_4; + property alias item2_5: _item2_5; + property alias item2_6: _item2_6; + font.family: "Arial" + T.Control { + id: _item2_2 + objectName: "_item2_2" + T.Control { + id: _item2_3 + objectName: "_item2_3" + } + } + T.TextArea { + id: _item2_4 + objectName: "_item2_4" + text: "Text Area" + } + T.TextField { + id: _item2_5 + objectName: "_item2_5" + text: "Text Field" + } + T.Label { + id: _item2_6 + objectName: "_item2_6" + text: "Label" + } + } + } + + function test_font() { + var control2 = createTemporaryObject(component2, testCase) + verify(control2) + verify(control2.item2_2) + verify(control2.item2_3) + verify(control2.item2_4) + verify(control2.item2_5) + verify(control2.item2_6) + + compare(control2.font.family, "Arial") + compare(control2.item2_2.font.family, control2.font.family) + compare(control2.item2_3.font.family, control2.font.family) + compare(control2.item2_4.font.family, control2.font.family) + compare(control2.item2_5.font.family, control2.font.family) + compare(control2.item2_6.font.family, control2.font.family) + + control2.font.pointSize = 48 + compare(control2.item2_2.font.pointSize, 48) + compare(control2.item2_3.font.pointSize, 48) + compare(control2.item2_4.font.pointSize, 48) + compare(control2.item2_5.font.pointSize, 48) + + control2.font.bold = true + compare(control2.item2_2.font.weight, Font.Bold) + compare(control2.item2_3.font.weight, Font.Bold) + compare(control2.item2_4.font.weight, Font.Bold) + compare(control2.item2_5.font.weight, Font.Bold) + + control2.item2_2.font.pointSize = 36 + compare(control2.item2_2.font.pointSize, 36) + compare(control2.item2_3.font.pointSize, 36) + + control2.item2_2.font.weight = Font.Light + compare(control2.item2_2.font.pointSize, 36) + compare(control2.item2_3.font.pointSize, 36) + + compare(control2.item2_3.font.family, control2.item2_2.font.family) + compare(control2.item2_3.font.pointSize, control2.item2_2.font.pointSize) + compare(control2.item2_3.font.weight, control2.item2_2.font.weight) + + control2.font.pointSize = 50 + compare(control2.item2_2.font.pointSize, 36) + compare(control2.item2_3.font.pointSize, 36) + compare(control2.item2_4.font.pointSize, 50) + compare(control2.item2_5.font.pointSize, 50) + compare(control2.item2_6.font.pointSize, 50) + + control2.item2_3.font.pointSize = 60 + compare(control2.item2_3.font.pointSize, 60) + + control2.item2_3.font.weight = Font.Normal + compare(control2.item2_3.font.weight, Font.Normal) + + control2.item2_4.font.pointSize = 16 + compare(control2.item2_4.font.pointSize, 16) + + control2.item2_4.font.weight = Font.Normal + compare(control2.item2_4.font.weight, Font.Normal) + + control2.item2_5.font.pointSize = 32 + compare(control2.item2_5.font.pointSize, 32) + + control2.item2_5.font.weight = Font.DemiBold + compare(control2.item2_5.font.weight, Font.DemiBold) + + control2.item2_6.font.pointSize = 36 + compare(control2.item2_6.font.pointSize, 36) + + control2.item2_6.font.weight = Font.Black + compare(control2.item2_6.font.weight, Font.Black) + + compare(control2.font.family, "Arial") + compare(control2.font.pointSize, 50) + compare(control2.font.weight, Font.Bold) + + compare(control2.item2_2.font.family, "Arial") + compare(control2.item2_2.font.pointSize, 36) + compare(control2.item2_2.font.weight, Font.Light) + + compare(control2.item2_3.font.family, "Arial") + compare(control2.item2_3.font.pointSize, 60) + compare(control2.item2_3.font.weight, Font.Normal) + + compare(control2.item2_4.font.family, "Arial") + compare(control2.item2_4.font.pointSize, 16) + compare(control2.item2_4.font.weight, Font.Normal) + + compare(control2.item2_5.font.family, "Arial") + compare(control2.item2_5.font.pointSize, 32) + compare(control2.item2_5.font.weight, Font.DemiBold) + + compare(control2.item2_6.font.family, "Arial") + compare(control2.item2_6.font.pointSize, 36) + compare(control2.item2_6.font.weight, Font.Black) + } + + Component { + id: component3 + T.Control { + id: item3 + objectName: "item3" + property alias item3_2: _item3_2; + property alias item3_3: _item3_3; + property alias item3_4: _item3_4; + property alias item3_5: _item3_5; + property alias item3_6: _item3_6; + property alias item3_7: _item3_7; + property alias item3_8: _item3_8; + font.family: "Arial" + Item { + id: _item3_2 + objectName: "_item3_2" + T.Control { + id: _item3_3 + objectName: "_item3_3" + Item { + id: _item3_6 + objectName: "_item3_6" + T.Control { + id: _item3_7 + objectName: "_item3_7" + } + } + } + T.TextArea { + id: _item3_4 + objectName: "_item3_4" + text: "Text Area" + } + T.TextField { + id: _item3_5 + objectName: "_item3_5" + text: "Text Field" + } + T.Label { + id: _item3_8 + objectName: "_item3_8" + text: "Label" + } + } + } + } + + function test_font_2() { + var control3 = createTemporaryObject(component3, testCase) + verify(control3) + verify(control3.item3_2) + verify(control3.item3_3) + verify(control3.item3_4) + verify(control3.item3_5) + verify(control3.item3_6) + verify(control3.item3_7) + verify(control3.item3_8) + + compare(control3.font.family, "Arial") + compare(control3.item3_3.font.family, control3.font.family) + compare(control3.item3_4.font.family, control3.font.family) + compare(control3.item3_5.font.family, control3.font.family) + compare(control3.item3_7.font.family, control3.font.family) + compare(control3.item3_8.font.family, control3.font.family) + + control3.font.pointSize = 48 + compare(control3.item3_3.font.pointSize, 48) + compare(control3.item3_4.font.pointSize, 48) + compare(control3.item3_5.font.pointSize, 48) + + control3.font.bold = true + compare(control3.item3_3.font.weight, Font.Bold) + compare(control3.item3_4.font.weight, Font.Bold) + compare(control3.item3_5.font.weight, Font.Bold) + + compare(control3.item3_3.font.family, control3.font.family) + compare(control3.item3_3.font.pointSize, control3.font.pointSize) + compare(control3.item3_3.font.weight, control3.font.weight) + compare(control3.item3_7.font.family, control3.font.family) + compare(control3.item3_7.font.pointSize, control3.font.pointSize) + compare(control3.item3_7.font.weight, control3.font.weight) + + control3.item3_3.font.pointSize = 60 + compare(control3.item3_3.font.pointSize, 60) + + control3.item3_3.font.weight = Font.Normal + compare(control3.item3_3.font.weight, Font.Normal) + + control3.item3_4.font.pointSize = 16 + compare(control3.item3_4.font.pointSize, 16) + + control3.item3_4.font.weight = Font.Normal + compare(control3.item3_4.font.weight, Font.Normal) + + control3.item3_5.font.pointSize = 32 + compare(control3.item3_5.font.pointSize, 32) + + control3.item3_5.font.weight = Font.DemiBold + compare(control3.item3_5.font.weight, Font.DemiBold) + + control3.item3_8.font.pointSize = 36 + compare(control3.item3_8.font.pointSize, 36) + + control3.item3_8.font.weight = Font.Black + compare(control3.item3_8.font.weight, Font.Black) + + control3.font.pointSize = 100 + compare(control3.font.pointSize, 100) + compare(control3.item3_3.font.pointSize, 60) + compare(control3.item3_4.font.pointSize, 16) + compare(control3.item3_5.font.pointSize, 32) + compare(control3.item3_8.font.pointSize, 36) + + compare(control3.font.family, "Arial") + compare(control3.font.pointSize, 100) + compare(control3.font.weight, Font.Bold) + + compare(control3.item3_3.font.family, "Arial") + compare(control3.item3_3.font.pointSize, 60) + compare(control3.item3_3.font.weight, Font.Normal) + compare(control3.item3_7.font.family, control3.item3_3.font.family) + compare(control3.item3_7.font.pointSize, control3.item3_3.font.pointSize) + compare(control3.item3_7.font.weight, control3.item3_3.font.weight) + + compare(control3.item3_4.font.family, "Arial") + compare(control3.item3_4.font.pointSize, 16) + compare(control3.item3_4.font.weight, Font.Normal) + + compare(control3.item3_5.font.family, "Arial") + compare(control3.item3_5.font.pointSize, 32) + compare(control3.item3_5.font.weight, Font.DemiBold) + + compare(control3.item3_8.font.family, "Arial") + compare(control3.item3_8.font.pointSize, 36) + compare(control3.item3_8.font.weight, Font.Black) + } + + Component { + id: component4 + T.Control { + id: item4 + objectName: "item4" + property alias item4_2: _item4_2; + property alias item4_3: _item4_3; + property alias item4_4: _item4_4; + T.Control { + id: _item4_2 + objectName: "_item4_2" + font.pixelSize: item4.font.pixelSize + 10 + T.Control { + id: _item4_3 + objectName: "_item4_3" + font.pixelSize: item4.font.pixelSize - 1 + } + T.Control { + id: _item4_4 + objectName: "_item4_4" + } + } + } + } + + function test_font_3() { + var control4 = createTemporaryObject(component4, testCase) + verify(control4) + verify(control4.item4_2) + verify(control4.item4_3) + verify(control4.item4_4) + + var family = control4.font.family + var ps = control4.font.pixelSize + + compare(control4.item4_2.font.family, control4.font.family) + compare(control4.item4_3.font.family, control4.font.family) + compare(control4.item4_4.font.family, control4.font.family) + + compare(control4.item4_2.font.pixelSize, control4.font.pixelSize + 10) + compare(control4.item4_3.font.pixelSize, control4.font.pixelSize - 1) + compare(control4.item4_4.font.pixelSize, control4.font.pixelSize + 10) + + control4.item4_2.font.pixelSize = control4.font.pixelSize + 15 + compare(control4.item4_2.font.pixelSize, control4.font.pixelSize + 15) + compare(control4.item4_3.font.pixelSize, control4.font.pixelSize - 1) + compare(control4.item4_4.font.pixelSize, control4.font.pixelSize + 15) + } + + function test_font_explicit_attributes_data() { + return [ + {tag: "bold", value: true}, + {tag: "capitalization", value: Font.Capitalize}, + {tag: "family", value: "Courier"}, + {tag: "italic", value: true}, + {tag: "strikeout", value: true}, + {tag: "underline", value: true}, + {tag: "weight", value: Font.Black}, + {tag: "wordSpacing", value: 55} + ] + } + + function test_font_explicit_attributes(data) { + var control = createTemporaryObject(component, testCase) + verify(control) + + var child = component.createObject(control) + verify(child) + + var controlSpy = signalSpy.createObject(control, {target: control, signalName: "fontChanged"}) + verify(controlSpy.valid) + + var childSpy = signalSpy.createObject(child, {target: child, signalName: "fontChanged"}) + verify(childSpy.valid) + + var defaultValue = control.font[data.tag] + child.font[data.tag] = defaultValue + + compare(child.font[data.tag], defaultValue) + compare(childSpy.count, 0) + + control.font[data.tag] = data.value + + compare(control.font[data.tag], data.value) + compare(controlSpy.count, 1) + + compare(child.font[data.tag], defaultValue) + compare(childSpy.count, 0) + } + + function test_locale() { + var control = createTemporaryObject(component, testCase) + verify(control) + + control.locale = Qt.locale("en_US") + compare(control.locale.name, "en_US") + + control.locale = Qt.locale("nb_NO") + compare(control.locale.name, "nb_NO") + } + + Component { + id: component5 + T.Control { + id: item2 + objectName: "item2" + property alias localespy: _lspy; + property alias mirroredspy: _mspy; + property alias localespy_2: _lspy_2; + property alias mirroredspy_2: _mspy_2; + property alias localespy_3: _lspy_3; + property alias mirroredspy_3: _mspy_3; + property alias item2_2: _item2_2; + property alias item2_3: _item2_3; + T.Control { + id: _item2_2 + objectName: "_item2_2" + T.Control { + id: _item2_3 + objectName: "_item2_3" + + SignalSpy { + id: _lspy_3 + target: item2_3 + signalName: "localeChanged" + } + + SignalSpy { + id: _mspy_3 + target: item2_3 + signalName: "mirroredChanged" + } + } + + SignalSpy { + id: _lspy_2 + target: item2_2 + signalName: "localeChanged" + } + + SignalSpy { + id: _mspy_2 + target: item2_2 + signalName: "mirroredChanged" + } + } + + SignalSpy { + id: _lspy + target: item2 + signalName: "localeChanged" + } + + SignalSpy { + id: _mspy + target: item2 + signalName: "mirroredChanged" + } + } + } + + function test_locale_2() { + var control = createTemporaryObject(component5, testCase) + verify(control) + verify(control.item2_2) + verify(control.item2_3) + + var defaultLocale = Qt.locale() + + compare(control.locale.name, defaultLocale.name) + compare(control.item2_2.locale.name, defaultLocale.name) + compare(control.item2_3.locale.name, defaultLocale.name) + + control.locale = Qt.locale("nb_NO") + control.localespy.wait() + compare(control.localespy.count, 1) + compare(control.mirroredspy.count, 0) + compare(control.locale.name, "nb_NO") + compare(control.item2_2.locale.name, "nb_NO") + compare(control.item2_3.locale.name, "nb_NO") + compare(control.localespy_2.count, 1) + compare(control.mirroredspy_2.count, 0) + compare(control.localespy_3.count, 1) + compare(control.mirroredspy_3.count, 0) + + control.locale = Qt.locale("ar_EG") + control.localespy.wait() + compare(control.localespy.count, 2) + compare(control.mirroredspy.count, 0) + compare(control.locale.name, "ar_EG") + compare(control.item2_2.locale.name, "ar_EG") + compare(control.item2_3.locale.name, "ar_EG") + compare(control.localespy_2.count, 2) + compare(control.mirroredspy_2.count, 0) + compare(control.localespy_3.count, 2) + compare(control.mirroredspy_3.count, 0) + } + + Component { + id: component6 + T.Control { + id: item6 + objectName: "item6" + property alias localespy: _lspy; + property alias mirroredspy: _mspy; + property alias localespy_5: _lspy_5; + property alias mirroredspy_5: _mspy_5; + property alias item6_2: _item6_2; + property alias item6_3: _item6_3; + property alias item6_4: _item6_4; + property alias item6_5: _item6_5; + Item { + id: _item6_2 + objectName: "_item6_2" + T.Control { + id: _item6_3 + objectName: "_item6_3" + Item { + id: _item6_4 + objectName: "_item6_4" + T.Control { + id: _item6_5 + objectName: "_item6_5" + + SignalSpy { + id: _lspy_5 + target: _item6_5 + signalName: "localeChanged" + } + + SignalSpy { + id: _mspy_5 + target: _item6_5 + signalName: "mirroredChanged" + } + } + } + } + } + + SignalSpy { + id: _lspy + target: item6 + signalName: "localeChanged" + } + + SignalSpy { + id: _mspy + target: item6 + signalName: "mirroredChanged" + } + } + } + + function test_locale_3() { + var control = createTemporaryObject(component6, testCase) + verify(control) + verify(control.item6_2) + verify(control.item6_3) + verify(control.item6_4) + verify(control.item6_5) + + var defaultLocale = Qt.locale() + + compare(control.locale.name, defaultLocale.name) + compare(control.item6_5.locale.name, defaultLocale.name) + + control.locale = Qt.locale("nb_NO") + control.localespy.wait() + compare(control.localespy.count, 1) + compare(control.mirroredspy.count, 0) + compare(control.locale.name, "nb_NO") + compare(control.item6_5.locale.name, "nb_NO") + compare(control.localespy_5.count, 1) + compare(control.mirroredspy_5.count, 0) + + control.locale = Qt.locale("ar_EG") + control.localespy.wait() + compare(control.localespy.count, 2) + compare(control.mirroredspy.count, 0) + compare(control.locale.name, "ar_EG") + compare(control.item6_5.locale.name, "ar_EG") + compare(control.localespy_5.count, 2) + compare(control.mirroredspy_5.count, 0) + } + + function test_hover_data() { + return [ + { tag: "normal", target: component, pressed: false }, + { tag: "pressed", target: button, pressed: true } + ] + } + + function test_hover(data) { + var control = createTemporaryObject(data.target, testCase, {width: 100, height: 100}) + verify(control) + + compare(control.hovered, false) + compare(control.hoverEnabled, Qt.styleHints.useHoverEffects) + + control.hoverEnabled = false + + mouseMove(control, control.width / 2, control.height / 2) + compare(control.hovered, false) + + control.hoverEnabled = true + + mouseMove(control, control.width / 2, control.height / 2) + compare(control.hovered, true) + + if (data.pressed) { + mousePress(control, control.width / 2, control.height / 2) + compare(control.hovered, true) + } + + mouseMove(control, -10, -10) + compare(control.hovered, false) + + if (data.pressed) { + mouseRelease(control, -10, control.height / 2) + compare(control.hovered, false) + } + + mouseMove(control, control.width / 2, control.height / 2) + compare(control.hovered, true) + + control.visible = false + compare(control.hovered, false) + } + + function test_hoverEnabled() { + var control = createTemporaryObject(component, testCase) + compare(control.hoverEnabled, Qt.styleHints.useHoverEffects) + + var child = component.createObject(control) + var grandChild = component.createObject(child) + + var childExplicitHoverEnabled = component.createObject(control, {hoverEnabled: true}) + var grandChildExplicitHoverDisabled = component.createObject(childExplicitHoverEnabled, {hoverEnabled: false}) + + var childExplicitHoverDisabled = component.createObject(control, {hoverEnabled: false}) + var grandChildExplicitHoverEnabled = component.createObject(childExplicitHoverDisabled, {hoverEnabled: true}) + + control.hoverEnabled = false + compare(control.hoverEnabled, false) + compare(grandChild.hoverEnabled, false) + + compare(childExplicitHoverEnabled.hoverEnabled, true) + compare(grandChildExplicitHoverDisabled.hoverEnabled, false) + + compare(childExplicitHoverDisabled.hoverEnabled, false) + compare(grandChildExplicitHoverEnabled.hoverEnabled, true) + + control.hoverEnabled = true + compare(control.hoverEnabled, true) + compare(grandChild.hoverEnabled, true) + + compare(childExplicitHoverEnabled.hoverEnabled, true) + compare(grandChildExplicitHoverDisabled.hoverEnabled, false) + + compare(childExplicitHoverDisabled.hoverEnabled, false) + compare(grandChildExplicitHoverEnabled.hoverEnabled, true) + } + + function test_implicitSize() { + var control = createTemporaryObject(component, testCase) + verify(control) + + var implicitWidthSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "implicitWidthChanged"}) + verify(implicitWidthSpy.valid) + + var implicitHeightSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "implicitHeightChanged"}) + verify(implicitHeightSpy.valid) + + var implicitContentWidthSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "implicitContentWidthChanged"}) + verify(implicitContentWidthSpy.valid) + + var implicitContentHeightSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "implicitContentHeightChanged"}) + verify(implicitContentHeightSpy.valid) + + var implicitBackgroundWidthSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "implicitBackgroundWidthChanged"}) + verify(implicitBackgroundWidthSpy.valid) + + var implicitBackgroundHeightSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "implicitBackgroundHeightChanged"}) + verify(implicitBackgroundHeightSpy.valid) + + var implicitWidthChanges = 0 + var implicitHeightChanges = 0 + var implicitContentWidthChanges = 0 + var implicitContentHeightChanges = 0 + var implicitBackgroundWidthChanges = 0 + var implicitBackgroundHeightChanges = 0 + + compare(control.implicitWidth, 0) + compare(control.implicitHeight, 0) + compare(control.implicitContentWidth, 0) + compare(control.implicitContentHeight, 0) + compare(control.implicitBackgroundWidth, 0) + compare(control.implicitBackgroundHeight, 0) + + control.contentItem = rectangle.createObject(control, {implicitWidth: 10, implicitHeight: 20}) + compare(control.implicitWidth, 10) + compare(control.implicitHeight, 20) + compare(control.implicitContentWidth, 10) + compare(control.implicitContentHeight, 20) + compare(control.implicitBackgroundWidth, 0) + compare(control.implicitBackgroundHeight, 0) + compare(implicitWidthSpy.count, ++implicitWidthChanges) + compare(implicitHeightSpy.count, ++implicitHeightChanges) + compare(implicitBackgroundWidthSpy.count, implicitBackgroundWidthChanges) + compare(implicitBackgroundHeightSpy.count, implicitBackgroundHeightChanges) + compare(implicitContentWidthSpy.count, ++implicitContentWidthChanges) + compare(implicitContentHeightSpy.count, ++implicitContentHeightChanges) + + control.contentItem.implicitWidth += 1 + control.contentItem.implicitHeight += 1 + compare(control.implicitWidth, 11) + compare(control.implicitHeight, 21) + compare(control.implicitContentWidth, 11) + compare(control.implicitContentHeight, 21) + compare(control.implicitBackgroundWidth, 0) + compare(control.implicitBackgroundHeight, 0) + compare(implicitWidthSpy.count, ++implicitWidthChanges) + compare(implicitHeightSpy.count, ++implicitHeightChanges) + compare(implicitContentWidthSpy.count, ++implicitContentWidthChanges) + compare(implicitContentHeightSpy.count, ++implicitContentHeightChanges) + compare(implicitBackgroundWidthSpy.count, implicitBackgroundWidthChanges) + compare(implicitBackgroundHeightSpy.count, implicitBackgroundHeightChanges) + + control.background = rectangle.createObject(control, {implicitWidth: 20, implicitHeight: 30}) + compare(control.implicitWidth, 20) + compare(control.implicitHeight, 30) + compare(control.implicitContentWidth,11) + compare(control.implicitContentHeight, 21) + compare(control.implicitBackgroundWidth, 20) + compare(control.implicitBackgroundHeight, 30) + compare(implicitWidthSpy.count, ++implicitWidthChanges) + compare(implicitHeightSpy.count, ++implicitHeightChanges) + compare(implicitContentWidthSpy.count, implicitContentWidthChanges) + compare(implicitContentHeightSpy.count, implicitContentHeightChanges) + compare(implicitBackgroundWidthSpy.count, ++implicitBackgroundWidthChanges) + compare(implicitBackgroundHeightSpy.count, ++implicitBackgroundHeightChanges) + + control.background.implicitWidth += 1 + control.background.implicitHeight += 1 + compare(control.implicitWidth, 21) + compare(control.implicitHeight, 31) + compare(control.implicitContentWidth, 11) + compare(control.implicitContentHeight, 21) + compare(control.implicitBackgroundWidth, 21) + compare(control.implicitBackgroundHeight, 31) + compare(implicitWidthSpy.count, ++implicitWidthChanges) + compare(implicitHeightSpy.count, ++implicitHeightChanges) + compare(implicitContentWidthSpy.count, implicitContentWidthChanges) + compare(implicitContentHeightSpy.count, implicitContentHeightChanges) + compare(implicitBackgroundWidthSpy.count, ++implicitBackgroundWidthChanges) + compare(implicitBackgroundHeightSpy.count, ++implicitBackgroundHeightChanges) + } + + function test_baseline() { + var control = createTemporaryObject(component, testCase) + verify(control) + + compare(control.baselineOffset, 0) + + var baselineSpy = signalSpy.createObject(control, {target: control, signalName: "baselineOffsetChanged"}) + verify(baselineSpy.valid) + + control.contentItem = rectangle.createObject(control, {baselineOffset: 12}) + compare(control.baselineOffset, 12) + compare(baselineSpy.count, 1) + + control.padding = 6 + compare(control.baselineOffset, 18) + compare(baselineSpy.count, 2) + + control.baselineOffset = 3 + compare(control.baselineOffset, 3) + compare(baselineSpy.count, 3) + + control.padding = 9 + compare(control.baselineOffset, 3) + compare(baselineSpy.count, 3) + + control.baselineOffset = undefined + compare(control.baselineOffset, 21) + compare(baselineSpy.count, 4) + + control.contentItem.baselineOffset = 3 + compare(control.baselineOffset, 12) + compare(baselineSpy.count, 5) + + control.contentItem = null + compare(control.baselineOffset, 0) + compare(baselineSpy.count, 6) + } + + function test_inset() { + var control = createTemporaryObject(component, testCase, {background: rectangle.createObject(control)}) + verify(control) + + var topInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "topInsetChanged"}) + verify(topInsetSpy.valid) + + var leftInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "leftInsetChanged"}) + verify(leftInsetSpy.valid) + + var rightInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "rightInsetChanged"}) + verify(rightInsetSpy.valid) + + var bottomInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "bottomInsetChanged"}) + verify(bottomInsetSpy.valid) + + var topInsetChanges = 0 + var leftInsetChanges = 0 + var rightInsetChanges = 0 + var bottomInsetChanges = 0 + + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + + control.width = 100 + control.height = 100 + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 100) + compare(control.background.height, 100) + + control.topInset = 10 + compare(control.topInset, 10) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, ++topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 10) + compare(control.background.width, 100) + compare(control.background.height, 90) + + control.leftInset = 20 + compare(control.topInset, 10) + compare(control.leftInset, 20) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, ++leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 10) + compare(control.background.width, 80) + compare(control.background.height, 90) + + control.rightInset = 30 + compare(control.topInset, 10) + compare(control.leftInset, 20) + compare(control.rightInset, 30) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, ++rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 10) + compare(control.background.width, 50) + compare(control.background.height, 90) + + control.bottomInset = 40 + compare(control.topInset, 10) + compare(control.leftInset, 20) + compare(control.rightInset, 30) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, ++bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 10) + compare(control.background.width, 50) + compare(control.background.height, 50) + + control.topInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 20) + compare(control.rightInset, 30) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, ++topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 0) + compare(control.background.width, 50) + compare(control.background.height, 60) + + control.leftInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 30) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, ++leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 70) + compare(control.background.height, 60) + + control.rightInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, ++rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 100) + compare(control.background.height, 60) + + control.bottomInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, ++bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 100) + compare(control.background.height, 100) + } + + Component { + id: contentItemDeletionOrder1 + + Item { + objectName: "parentItem" + + Item { + id: item + objectName: "contentItem" + } + Control { + objectName: "control" + contentItem: item + } + } + } + + Component { + id: contentItemDeletionOrder2 + + Item { + objectName: "parentItem" + + Control { + objectName: "control" + contentItem: item + } + Item { + id: item + objectName: "contentItem" + } + } + } + + function test_contentItemDeletionOrder() { + var control1 = createTemporaryObject(contentItemDeletionOrder1, testCase) + verify(control1) + var control2 = createTemporaryObject(contentItemDeletionOrder2, testCase) + verify(control2) + } + + Component { + id: backgroundDeletionOrder1 + + Item { + objectName: "parentItem" + + Item { + id: item + objectName: "backgroundItem" + } + Control { + objectName: "control" + background: item + } + } + } + + Component { + id: backgroundDeletionOrder2 + + Item { + objectName: "parentItem" + + Control { + objectName: "control" + background: item + } + Item { + id: item + objectName: "backgroundItem" + } + } + } + + function test_backgroundDeletionOrder() { + var control1 = createTemporaryObject(backgroundDeletionOrder1, testCase) + verify(control1) + var control2 = createTemporaryObject(backgroundDeletionOrder2, testCase) + verify(control2) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_delaybutton.qml b/tests/auto/quickcontrols2/controls/data/tst_delaybutton.qml new file mode 100644 index 00000000000..731caf8675e --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_delaybutton.qml @@ -0,0 +1,332 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "DelayButton" + + Component { + id: delayButton + DelayButton { + delay: 200 + } + } + + Component { + id: signalSequenceSpy + SignalSequenceSpy { + signals: ["pressed", "released", "canceled", "clicked", "toggled", "doubleClicked", "pressedChanged", "downChanged", "checkedChanged", "activated"] + } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_mouse() { + var control = createTemporaryObject(delayButton, testCase) + verify(control) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + // click + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + "released", + "clicked"] + mouseClick(control) + verify(sequenceSpy.success) + + // check + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + "activated"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + tryVerify(function() { return sequenceSpy.success}) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + ["checkedChanged", { "checked": true }], + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // uncheck + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + ["checkedChanged", { "checked": false }], + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // release outside + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }]] + mouseMove(control, control.width * 2, control.height * 2, 0) + compare(control.pressed, false) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["canceled", { "pressed": false }]] + mouseRelease(control, control.width * 2, control.height * 2, Qt.LeftButton) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // right button + sequenceSpy.expectedSequence = [] + mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.pressed, false) + + mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // double click + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + "released", + "clicked", + ["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + "doubleClicked", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + "released"] + mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton) + verify(sequenceSpy.success) + } + + function test_touch() { + var control = createTemporaryObject(delayButton, testCase) + verify(control) + + var touch = touchEvent(control) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + // click + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + "released", + "clicked"] + touch.press(0, control).commit() + touch.release(0, control).commit() + verify(sequenceSpy.success) + + // check + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + "activated"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + tryVerify(function() { return sequenceSpy.success}) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + ["checkedChanged", { "checked": true }], + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, false) + verify(sequenceSpy.success) + + // uncheck + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + ["checkedChanged", { "checked": false }], + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, false) + verify(sequenceSpy.success) + + // release outside + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }]] + touch.move(0, control, control.width * 2, control.height * 2).commit() + compare(control.pressed, false) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = [["canceled", { "pressed": false }]] + touch.release(0, control, control.width * 2, control.height * 2).commit() + compare(control.pressed, false) + verify(sequenceSpy.success) + } + + function test_keys() { + var control = createTemporaryObject(delayButton, testCase) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + // click + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + "released", + "clicked"] + keyClick(Qt.Key_Space) + verify(sequenceSpy.success) + + // check + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + "activated"] + keyPress(Qt.Key_Space) + tryVerify(function() { return sequenceSpy.success}) + + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + ["checkedChanged", { "checked": true }], + "released", + "clicked"] + keyRelease(Qt.Key_Space) + verify(sequenceSpy.success) + + // uncheck + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], + ["downChanged", { "down": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + ["downChanged", { "down": false }], + ["checkedChanged", { "checked": false }], + "released", + "clicked"] + keyClick(Qt.Key_Space) + verify(sequenceSpy.success) + + // no change + sequenceSpy.expectedSequence = [] + var keys = [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab] + for (var i = 0; i < keys.length; ++i) { + sequenceSpy.reset() + keyClick(keys[i]) + verify(sequenceSpy.success) + } + } + + function test_progress() { + var control = createTemporaryObject(delayButton, testCase) + verify(control) + + var progressSpy = signalSpy.createObject(control, {target: control, signalName: "progressChanged"}) + verify(progressSpy.valid) + + compare(control.progress, 0.0) + mousePress(control) + tryCompare(control, "progress", 1.0) + verify(progressSpy.count > 0) + } + + function test_baseline() { + var control = createTemporaryObject(delayButton, testCase) + verify(control) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_dial.qml b/tests/auto/quickcontrols2/controls/data/tst_dial.qml new file mode 100644 index 00000000000..2d0c702e706 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_dial.qml @@ -0,0 +1,709 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 450 + height: 450 + visible: true + when: windowShown + name: "Dial" + + Component { + id: dialComponent + Dial { + width: 100 + height: 100 + anchors.centerIn: parent + } + } + + Component { + id: signalSpy + SignalSpy {} + } + + function test_instance() { + var dial = createTemporaryObject(dialComponent, testCase); + verify(dial); + compare(dial.value, 0.0); + compare(dial.from, 0.0); + compare(dial.to, 1.0); + compare(dial.stepSize, 0.0); + verify(dial.activeFocusOnTab); + verify(!dial.pressed); + } + + function test_value() { + var dial = createTemporaryObject(dialComponent, testCase); + verify(dial); + compare(dial.value, 0.0); + + dial.value = 0.5; + compare(dial.value, 0.5); + + dial.value = 1.0; + compare(dial.value, 1.0); + + dial.value = -1.0; + compare(dial.value, 0.0); + + dial.value = 2.0; + compare(dial.value, 1.0); + } + + function test_range() { + var dial = createTemporaryObject(dialComponent, testCase); + verify(dial); + + dial.from = 0; + dial.to = 100; + dial.value = 50; + compare(dial.from, 0); + compare(dial.to, 100); + compare(dial.value, 50); + compare(dial.position, 0.5); + + dial.value = 1000 + compare(dial.value, 100); + compare(dial.position, 1); + + dial.value = -1 + compare(dial.value, 0); + compare(dial.position, 0); + + dial.from = 25 + compare(dial.from, 25); + compare(dial.value, 25); + compare(dial.position, 0); + + dial.to = 75 + compare(dial.to, 75); + compare(dial.value, 25); + compare(dial.position, 0); + + dial.value = 50 + compare(dial.value, 50); + compare(dial.position, 0.5); + } + + function test_inverted() { + var dial = createTemporaryObject(dialComponent, testCase, { from: 1.0, to: -1.0 }); + verify(dial); + compare(dial.from, 1.0); + compare(dial.to, -1.0); + compare(dial.value, 0.0); + compare(dial.position, 0.5); + + dial.value = 2.0; + compare(dial.value, 1.0); + compare(dial.position, 0.0); + + dial.value = -2.0; + compare(dial.value, -1.0); + compare(dial.position, 1.0); + + dial.value = 0.0; + compare(dial.value, 0.0); + compare(dial.position, 0.5); + } + + SignalSpy { + id: pressSpy + signalName: "pressedChanged" + } + + function test_pressed() { + var dial = createTemporaryObject(dialComponent, testCase); + verify(dial); + + pressSpy.target = dial; + verify(pressSpy.valid); + verify(!dial.pressed); + + mousePress(dial, dial.width / 2, dial.height / 2); + verify(dial.pressed); + compare(pressSpy.count, 1); + + mouseRelease(dial, dial.width / 2, dial.height / 2); + verify(!dial.pressed); + compare(pressSpy.count, 2); + + var touch = touchEvent(dial); + touch.press(0).commit(); + verify(dial.pressed); + compare(pressSpy.count, 3); + + touch.release(0).commit(); + verify(!dial.pressed); + compare(pressSpy.count, 4); + } + + SignalSpy { + id: valueSpy + signalName: "valueChanged" + } + + function test_dragging_data() { + return [ + { tag: "default", from: 0, to: 1, leftValue: 0.20, topValue: 0.5, rightValue: 0.8, bottomValue: 1.0, live: false }, + { tag: "scaled2", from: 0, to: 2, leftValue: 0.4, topValue: 1.0, rightValue: 1.6, bottomValue: 2.0, live: false }, + { tag: "scaled1", from: -1, to: 0, leftValue: -0.8, topValue: -0.5, rightValue: -0.2, bottomValue: 0.0, live: false }, + { tag: "live", from: 0, to: 1, leftValue: 0.20, topValue: 0.5, rightValue: 0.8, bottomValue: 1.0, live: true } + ] + } + + function test_dragging(data) { + var dial = createTemporaryObject(dialComponent, testCase); + verify(dial); + + dial.wrap = true; + verify(dial.wrap); + dial.from = data.from; + dial.to = data.to; + dial.live = data.live; + + valueSpy.target = dial; + verify(valueSpy.valid); + + var moveSpy = createTemporaryObject(signalSpy, testCase, {target: dial, signalName: "moved"}); + verify(moveSpy.valid); + + var minimumExpectedValueCount = data.live ? 2 : 1; + + // drag to the left + // we always add or subtract 1 to ensure we start the drag from the opposite side + // of where we're dragging to, for more reliable tests + mouseDrag(dial, dial.width / 2 + 1, dial.height / 2, -dial.width / 2, 0, Qt.LeftButton); + fuzzyCompare(dial.value, data.leftValue, 0.1); + verify(valueSpy.count >= minimumExpectedValueCount, "expected valueChanged to be emitted at least " + + minimumExpectedValueCount + " time(s), but it was only emitted " + valueSpy.count + " time(s)"); + valueSpy.clear(); + verify(moveSpy.count > 0); + moveSpy.clear(); + + // drag to the top + mouseDrag(dial, dial.width / 2, dial.height / 2 + 1, 0, -dial.height / 2, Qt.LeftButton); + fuzzyCompare(dial.value, data.topValue, 0.1); + verify(valueSpy.count >= minimumExpectedValueCount, "expected valueChanged to be emitted at least " + + minimumExpectedValueCount + " time(s), but it was only emitted " + valueSpy.count + " time(s)"); + valueSpy.clear(); + verify(moveSpy.count > 0); + moveSpy.clear(); + + // drag to the right + mouseDrag(dial, dial.width / 2 - 1, dial.height / 2, dial.width / 2, 0, Qt.LeftButton); + fuzzyCompare(dial.value, data.rightValue, 0.1); + verify(valueSpy.count >= minimumExpectedValueCount, "expected valueChanged to be emitted at least " + + minimumExpectedValueCount + " time(s), but it was only emitted " + valueSpy.count + " time(s)"); + valueSpy.clear(); + verify(moveSpy.count > 0); + moveSpy.clear(); + + // drag to the bottom (* 0.6 to ensure we don't go over to the minimum position) + mouseDrag(dial, dial.width / 2, dial.height / 2 - 1, 10, dial.height / 2, Qt.LeftButton); + fuzzyCompare(dial.value, data.bottomValue, 0.1); + verify(valueSpy.count >= minimumExpectedValueCount, "expected valueChanged to be emitted at least " + + minimumExpectedValueCount + " time(s), but it was only emitted " + valueSpy.count + " time(s)"); + valueSpy.clear(); + verify(moveSpy.count > 0); + moveSpy.clear(); + } + + function test_nonWrapping() { + var dial = createTemporaryObject(dialComponent, testCase); + verify(dial); + + compare(dial.wrap, false); + dial.value = 0; + + // Ensure that dragging from bottom left to bottom right doesn't work. + var yPos = dial.height * 0.75; + mousePress(dial, dial.width * 0.25, yPos, Qt.LeftButton); + var positionAtPress = dial.position; + mouseMove(dial, dial.width * 0.5, yPos); + compare(dial.position, positionAtPress); + mouseMove(dial, dial.width * 0.75, yPos); + compare(dial.position, positionAtPress); + mouseRelease(dial, dial.width * 0.75, yPos, Qt.LeftButton); + compare(dial.position, positionAtPress); + + // Try the same thing, but a bit higher. + yPos = dial.height * 0.6; + mousePress(dial, dial.width * 0.25, yPos, Qt.LeftButton); + positionAtPress = dial.position; + mouseMove(dial, dial.width * 0.5, yPos); + compare(dial.position, positionAtPress); + mouseMove(dial, dial.width * 0.75, yPos); + compare(dial.position, positionAtPress); + mouseRelease(dial, dial.width * 0.75, yPos, Qt.LeftButton); + compare(dial.position, positionAtPress); + + // Going from below the center of the dial to above it should work (once it gets above the center). + mousePress(dial, dial.width * 0.25, dial.height * 0.75, Qt.LeftButton); + positionAtPress = dial.position; + mouseMove(dial, dial.width * 0.5, dial.height * 0.6); + compare(dial.position, positionAtPress); + mouseMove(dial, dial.width * 0.75, dial.height * 0.4); + verify(dial.position > positionAtPress); + mouseRelease(dial, dial.width * 0.75, dial.height * 0.3, Qt.LeftButton); + verify(dial.position > positionAtPress); + } + + function test_touch() { + var dial = createTemporaryObject(dialComponent, testCase); + verify(dial); + + var touch = touchEvent(dial); + + // Ensure that dragging from bottom left to bottom right doesn't work. + var yPos = dial.height * 0.75; + touch.press(0, dial, dial.width * 0.25, yPos).commit(); + var positionAtPress = dial.position; + touch.move(0, dial, dial.width * 0.5, yPos).commit(); + compare(dial.position, positionAtPress); + touch.move(0, dial, dial.width * 0.75, yPos).commit(); + compare(dial.position, positionAtPress); + touch.release(0, dial, dial.width * 0.75, yPos).commit(); + compare(dial.position, positionAtPress); + + // Try the same thing, but a bit higher. + yPos = dial.height * 0.6; + touch.press(0, dial, dial.width * 0.25, yPos).commit(); + positionAtPress = dial.position; + touch.move(0, dial, dial.width * 0.5, yPos).commit(); + compare(dial.position, positionAtPress); + touch.move(0, dial, dial.width * 0.75, yPos).commit(); + compare(dial.position, positionAtPress); + touch.release(0, dial, dial.width * 0.75, yPos).commit(); + compare(dial.position, positionAtPress); + + // Going from below the center of the dial to above it should work (once it gets above the center). + touch.press(0, dial, dial.width * 0.25, dial.height * 0.75).commit(); + positionAtPress = dial.position; + touch.move(0, dial, dial.width * 0.5, dial.height * 0.6).commit(); + compare(dial.position, positionAtPress); + touch.move(0, dial, dial.width * 0.75, dial.height * 0.4).commit(); + verify(dial.position > positionAtPress); + touch.release(0, dial, dial.width * 0.75, dial.height * 0.3).commit(); + verify(dial.position > positionAtPress); + } + + function test_multiTouch() { + var dial1 = createTemporaryObject(dialComponent, testCase); + verify(dial1); + + var touch = touchEvent(dial1); + touch.press(0, dial1).commit().move(0, dial1, dial1.width / 4, dial1.height / 4).commit(); + compare(dial1.pressed, true); + verify(dial1.position > 0.0); + + var pos1Before = dial1.position; + + // second touch point on the same control is ignored + touch.stationary(0).press(1, dial1, 0, 0).commit() + touch.stationary(0).move(1, dial1).commit() + touch.stationary(0).release(1).commit() + compare(dial1.pressed, true); + compare(dial1.position, pos1Before); + + var dial2 = createTemporaryObject(dialComponent, testCase, {y: dial1.height}); + verify(dial2); + + // press the second dial + touch.stationary(0).press(2, dial2, 0, 0).commit(); + compare(dial2.pressed, true); + compare(dial2.position, 0.0); + + pos1Before = dial1.position; + var pos2Before = dial2.position; + + // move both dials + touch.move(0, dial1).move(2, dial2, dial2.width / 4, dial2.height / 4).commit(); + compare(dial1.pressed, true); + verify(dial1.position !== pos1Before); + compare(dial2.pressed, true); + verify(dial2.position !== pos2Before); + + // release both dials + touch.release(0, dial1).release(2, dial2).commit(); + compare(dial1.pressed, false); + compare(dial1.value, dial1.position); + compare(dial2.pressed, false); + compare(dial2.value, dial2.position); + } + + property Component focusTest: Component { + FocusScope { + signal receivedKeyPress + + Component.onCompleted: forceActiveFocus() + anchors.fill: parent + Keys.onPressed: receivedKeyPress() + } + } + + SignalSpy { + id: parentEventSpy + } + + function test_keyboardNavigation() { + var dial = createTemporaryObject(dialComponent, testCase); + verify(dial); + + var focusScope = createTemporaryObject(focusTest, testCase); + verify(focusScope); + + var moveCount = 0; + + // Tests that we've accepted events that we're interested in. + parentEventSpy.target = focusScope; + parentEventSpy.signalName = "receivedKeyPress"; + + var moveSpy = createTemporaryObject(signalSpy, testCase, {target: dial, signalName: "moved"}); + verify(moveSpy.valid); + + dial.parent = focusScope; + compare(dial.activeFocusOnTab, true); + compare(dial.value, 0); + + dial.focus = true; + compare(dial.activeFocus, true); + dial.stepSize = 0.1; + + keyClick(Qt.Key_Left); + compare(parentEventSpy.count, 0); + compare(moveSpy.count, moveCount); + compare(dial.value, 0); + + var oldValue = 0.0; + var keyPairs = [[Qt.Key_Left, Qt.Key_Right], [Qt.Key_Down, Qt.Key_Up]]; + for (var keyPairIndex = 0; keyPairIndex < 2; ++keyPairIndex) { + for (var i = 1; i <= 10; ++i) { + oldValue = dial.value; + keyClick(keyPairs[keyPairIndex][1]); + compare(parentEventSpy.count, 0); + if (oldValue !== dial.value) + compare(moveSpy.count, ++moveCount); + compare(dial.value, dial.stepSize * i); + } + + compare(dial.value, dial.to); + + for (i = 10; i > 0; --i) { + oldValue = dial.value; + keyClick(keyPairs[keyPairIndex][0]); + compare(parentEventSpy.count, 0); + if (oldValue !== dial.value) + compare(moveSpy.count, ++moveCount); + compare(dial.value, dial.stepSize * (i - 1)); + } + } + + dial.value = 0.5; + + keyClick(Qt.Key_Home); + compare(parentEventSpy.count, 0); + compare(moveSpy.count, ++moveCount); + compare(dial.value, dial.from); + + keyClick(Qt.Key_Home); + compare(parentEventSpy.count, 0); + compare(moveSpy.count, moveCount); + compare(dial.value, dial.from); + + keyClick(Qt.Key_End); + compare(parentEventSpy.count, 0); + compare(moveSpy.count, ++moveCount); + compare(dial.value, dial.to); + + keyClick(Qt.Key_End); + compare(parentEventSpy.count, 0); + compare(moveSpy.count, moveCount); + compare(dial.value, dial.to); + } + + function test_snapMode_data(immediate) { + return [ + { tag: "NoSnap", snapMode: Dial.NoSnap, from: 0, to: 2, values: [0, 0, 1], positions: [0, 0.5, 0.5] }, + { tag: "SnapAlways (0..2)", snapMode: Dial.SnapAlways, from: 0, to: 2, values: [0.0, 0.0, 1.0], positions: [0.0, 0.5, 0.5] }, + { tag: "SnapAlways (1..3)", snapMode: Dial.SnapAlways, from: 1, to: 3, values: [1.0, 1.0, 2.0], positions: [0.0, 0.5, 0.5] }, + { tag: "SnapAlways (-1..1)", snapMode: Dial.SnapAlways, from: -1, to: 1, values: [0.0, 0.0, 0.0], positions: [0.5, 0.5, 0.5] }, + { tag: "SnapAlways (1..-1)", snapMode: Dial.SnapAlways, from: 1, to: -1, values: [1.0, 1.0, 0.0], positions: [0.0, 0.5, 0.5] }, + { tag: "SnapOnRelease (0..2)", snapMode: Dial.SnapOnRelease, from: 0, to: 2, values: [0.0, 0.0, 1.0], positions: [0.0, 0.5, 0.5] }, + { tag: "SnapOnRelease (1..3)", snapMode: Dial.SnapOnRelease, from: 1, to: 3, values: [1.0, 1.0, 2.0], positions: [0.0, 0.5, 0.5] }, + { tag: "SnapOnRelease (-1..1)", snapMode: Dial.SnapOnRelease, from: -1, to: 1, values: [0.0, 0.0, 0.0], positions: [immediate ? 0.0 : 0.5, 0.5, 0.5] }, + { tag: "SnapOnRelease (1..-1)", snapMode: Dial.SnapOnRelease, from: 1, to: -1, values: [1.0, 1.0, 0.0], positions: [0.0, 0.5, 0.5] } + ] + } + + function test_snapMode_mouse_data() { + return test_snapMode_data(true) + } + + function test_snapMode_mouse(data) { + var dial = createTemporaryObject(dialComponent, testCase, {live: false}); + verify(dial); + + dial.snapMode = data.snapMode; + dial.from = data.from; + dial.to = data.to; + dial.stepSize = 0.2; + + var fuzz = 0.055; + + mousePress(dial, dial.width * 0.25, dial.height * 0.75); + fuzzyCompare(dial.value, data.values[0], fuzz); + fuzzyCompare(dial.position, data.positions[0], fuzz); + + mouseMove(dial, dial.width * 0.5, dial.height * 0.25); + fuzzyCompare(dial.value, data.values[1], fuzz); + fuzzyCompare(dial.position, data.positions[1], fuzz); + + mouseRelease(dial, dial.width * 0.5, dial.height * 0.25); + fuzzyCompare(dial.value, data.values[2], fuzz); + fuzzyCompare(dial.position, data.positions[2], fuzz); + } + + function test_snapMode_touch_data() { + return test_snapMode_data(false) + } + + function test_snapMode_touch(data) { + var dial = createTemporaryObject(dialComponent, testCase, {live: false}); + verify(dial); + + dial.snapMode = data.snapMode; + dial.from = data.from; + dial.to = data.to; + dial.stepSize = 0.2; + + var fuzz = 0.05; + + var touch = touchEvent(dial); + touch.press(0, dial, dial.width * 0.25, dial.height * 0.75).commit() + compare(dial.value, data.values[0]); + compare(dial.position, data.positions[0]); + + touch.move(0, dial, dial.width * 0.5, dial.height * 0.25).commit(); + fuzzyCompare(dial.value, data.values[1], fuzz); + fuzzyCompare(dial.position, data.positions[1], fuzz); + + touch.release(0, dial, dial.width * 0.5, dial.height * 0.25).commit(); + fuzzyCompare(dial.value, data.values[2], fuzz); + fuzzyCompare(dial.position, data.positions[2], fuzz); + } + + function test_wheel_data() { + return [ + { tag: "horizontal", orientation: Qt.Horizontal, dx: 120, dy: 0 }, + { tag: "vertical", orientation: Qt.Vertical, dx: 0, dy: 120 } + ] + } + + function test_wheel(data) { + var control = createTemporaryObject(dialComponent, testCase, {wheelEnabled: true, orientation: data.orientation}) + verify(control) + + compare(control.value, 0.0) + + mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(control.value, 0.1) + compare(control.position, 0.1) + + control.stepSize = 0.2 + + mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(control.value, 0.3) + compare(control.position, 0.3) + + control.stepSize = 10.0 + + mouseWheel(control, control.width / 2, control.height / 2, -data.dx, -data.dy) + compare(control.value, 0.0) + compare(control.position, 0.0) + + control.to = 10.0 + control.stepSize = 5.0 + + mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(control.value, 5.0) + compare(control.position, 0.5) + + mouseWheel(control, control.width / 2, control.height / 2, 0.5 * data.dx, 0.5 * data.dy) + compare(control.value, 7.5) + compare(control.position, 0.75) + + mouseWheel(control, control.width / 2, control.height / 2, -data.dx, -data.dy) + compare(control.value, 2.5) + compare(control.position, 0.25) + } + + function test_nullHandle() { + var control = createTemporaryObject(dialComponent, testCase) + verify(control) + + control.handle = null + + mousePress(control) + verify(control.pressed, true) + + mouseRelease(control) + compare(control.pressed, false) + } + + function move(inputEventType, control, x, y) { + if (inputEventType === "mouseInput") { + mouseMove(control, x, y); + } else { + var touch = touchEvent(control); + touch.move(0, control, x, y).commit(); + } + } + + function press(inputEventType, control, x, y) { + if (inputEventType === "mouseInput") { + mousePress(control, x, y); + } else { + var touch = touchEvent(control); + touch.press(0, control, x, y).commit(); + } + } + + function release(inputEventType, control, x, y) { + if (inputEventType === "mouseInput") { + mouseRelease(control, x, y); + } else { + var touch = touchEvent(control); + touch.release(0, control, x, y).commit(); + } + } + + function test_horizontalAndVertical_data() { + var data = [ + { eventType: "mouseInput", inputMode: Dial.Vertical, moveToX: 0.5, moveToY: 0.25, expectedPosition: 0.125 }, + // Horizontal movement should have no effect on a vertical dial. + { eventType: "mouseInput", inputMode: Dial.Vertical, moveToX: 2.0, moveToY: 0.25, expectedPosition: 0.125 }, + { eventType: "mouseInput", inputMode: Dial.Vertical, moveToX: 0.5, moveToY: 0.0, expectedPosition: 0.25 }, + { eventType: "mouseInput", inputMode: Dial.Vertical, moveToX: 0.5, moveToY: -1.5, expectedPosition: 1.0 }, + // Going above the drag area shouldn't make the position higher than 1.0. + { eventType: "mouseInput", inputMode: Dial.Vertical, moveToX: 0.5, moveToY: -2.0, expectedPosition: 1.0 }, + // Try to decrease the position by moving the mouse down. + // The dial's position is 0 before the press event, so nothing should happen. + { eventType: "mouseInput", inputMode: Dial.Vertical, moveToX: 0.5, moveToY: 1.25, expectedPosition: 0.0 }, + + { eventType: "mouseInput", inputMode: Dial.Horizontal, moveToX: 0.75, moveToY: 0.5, expectedPosition: 0.125 }, + // Vertical movement should have no effect on a horizontal dial. + { eventType: "mouseInput", inputMode: Dial.Horizontal, moveToX: 0.75, moveToY: 2.0, expectedPosition: 0.125 }, + { eventType: "mouseInput", inputMode: Dial.Horizontal, moveToX: 1.0, moveToY: 0.5, expectedPosition: 0.25 }, + { eventType: "mouseInput", inputMode: Dial.Horizontal, moveToX: 1.5, moveToY: 0.5, expectedPosition: 0.5 }, + { eventType: "mouseInput", inputMode: Dial.Horizontal, moveToX: 2.5, moveToY: 0.5, expectedPosition: 1.0 }, + // Going above the drag area shouldn't make the position higher than 1.0. + { eventType: "mouseInput", inputMode: Dial.Horizontal, moveToX: 2.525, moveToY: 0.5, expectedPosition: 1.0 }, + // Try to decrease the position by moving the mouse to the left. + // The dial's position is 0 before the press event, so nothing should happen. + { eventType: "mouseInput", inputMode: Dial.Vertical, moveToX: 0.25, moveToY: 0.5, expectedPosition: 0.0 } + ]; + + // Do the same tests for touch by copying the mouse tests and adding them to the end of the array. + var mouseTestCount = data.length; + for (var i = mouseTestCount; i < mouseTestCount * 2; ++i) { + // Shallow-copy the object. + data[i] = JSON.parse(JSON.stringify(data[i - mouseTestCount])); + data[i].eventType = "touchInput"; + } + + for (i = 0; i < data.length; ++i) { + var row = data[i]; + row.tag = "eventType=" + row.eventType + ", " + + "inputMode=" + (row.inputMode === Dial.Vertical ? "Vertical" : "Horizontal") + ", " + + "moveToX=" + row.moveToX + ", moveToY=" + row.moveToY + ", " + + "expectedPosition=" + row.expectedPosition; + } + + return data; + } + + function test_horizontalAndVertical(data) { + var control = createTemporaryObject(dialComponent, testCase, { inputMode: data.inputMode }); + verify(control); + + press(data.eventType, control); + compare(control.pressed, true); + // The position shouldn't change until the mouse has actually moved. + compare(control.position, 0); + + move(data.eventType, control, control.width * data.moveToX, control.width * data.moveToY); + compare(control.position, data.expectedPosition); + + release(data.eventType, control, control.width * data.moveToX, control.width * data.moveToY); + compare(control.pressed, false); + compare(control.position, data.expectedPosition); + } + + function test_integerStepping() { + var dial = createTemporaryObject(dialComponent, testCase) + verify(dial) + + dial.from = 1 + dial.to = 8 + dial.stepSize = 1 + + for (let i = 1; i < 8; ++i) { + // compare as strings to avoid a fuzzy compare; we want an exact match + compare(""+dial.value, ""+1) + keyClick(Qt.Key_Right) + } + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_dialog.qml b/tests/auto/quickcontrols2/controls/data/tst_dialog.qml new file mode 100644 index 00000000000..b227d82e1b1 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_dialog.qml @@ -0,0 +1,494 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtTest +import QtQuick.Controls +import QtQuick.Templates as T + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "Dialog" + + Component { + id: dialog + Dialog { } + } + + Component { + id: qtbug71444 + Dialog { + header: null + footer: null + } + } + + Component { + id: buttonBox + DialogButtonBox { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function init() { + tryCompare(testCase.Window.window, "active", true) + } + + function test_defaults() { + var control = createTemporaryObject(dialog, testCase) + verify(control) + verify(control.header) + verify(control.footer) + compare(control.standardButtons, 0) + } + + function test_accept() { + var control = createTemporaryObject(dialog, testCase) + + var openedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "opened"}) + verify(openedSpy.valid) + + control.open() + openedSpy.wait() + compare(openedSpy.count, 1) + verify(control.visible) + + var acceptedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "accepted"}) + verify(acceptedSpy.valid) + + var closedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "closed"}) + verify(closedSpy.valid) + + control.accept() + compare(acceptedSpy.count, 1) + compare(control.result, Dialog.Accepted) + + tryCompare(control, "visible", false) + compare(acceptedSpy.count, 1) + compare(closedSpy.count, 1) + } + + function test_reject() { + var control = createTemporaryObject(dialog, testCase) + + var openedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "opened"}) + verify(openedSpy.valid) + + control.open() + openedSpy.wait() + compare(openedSpy.count, 1) + verify(control.visible) + + var rejectedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "rejected"}) + verify(rejectedSpy.valid) + + var closedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "closed"}) + verify(closedSpy.valid) + + control.reject() + compare(rejectedSpy.count, 1) + compare(control.result, Dialog.Rejected) + + tryCompare(control, "visible", false) + compare(rejectedSpy.count, 1) + compare(closedSpy.count, 1) + + // Check that rejected() is emitted when CloseOnEscape is triggered. + control.x = 10 + control.y = 10 + control.width = 100 + control.height = 100 + control.closePolicy = Popup.CloseOnEscape + control.open() + verify(control.visible) + + keyPress(Qt.Key_Escape) + compare(rejectedSpy.count, 2) + tryCompare(control, "visible", false) + compare(rejectedSpy.count, 2) + compare(closedSpy.count, 2) + + keyRelease(Qt.Key_Escape) + compare(rejectedSpy.count, 2) + compare(closedSpy.count, 2) + + // Check that rejected() is emitted when CloseOnPressOutside is triggered. + control.closePolicy = Popup.CloseOnPressOutside + control.open() + verify(control.visible) + + mousePress(testCase, 1, 1) + compare(rejectedSpy.count, 3) + tryCompare(control, "visible", false) + compare(rejectedSpy.count, 3) + compare(closedSpy.count, 3) + + mouseRelease(testCase, 1, 1) + compare(rejectedSpy.count, 3) + compare(closedSpy.count, 3) + + // Check that rejected() is emitted when CloseOnReleaseOutside is triggered. + // For this, we need to make the dialog modal, because the overlay won't accept + // the press event because it doesn't want to block the press. + control.modal = true + control.closePolicy = Popup.CloseOnReleaseOutside + control.open() + verify(control.visible) + + mousePress(testCase, 1, 1) + compare(rejectedSpy.count, 3) + verify(control.visible) + + mouseRelease(testCase, 1, 1) + compare(rejectedSpy.count, 4) + tryCompare(control, "visible", false) + compare(rejectedSpy.count, 4) + compare(closedSpy.count, 4) + } + + function test_buttonBox_data() { + return [ + { tag: "default" }, + { tag: "custom", custom: true } + ] + } + + function test_buttonBox(data) { + var control = createTemporaryObject(dialog, testCase) + + if (data.custom) + control.footer = buttonBox.createObject(testCase) + control.standardButtons = Dialog.Ok | Dialog.Cancel + var box = control.footer + verify(box) + compare(box.standardButtons, Dialog.Ok | Dialog.Cancel) + + var acceptedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "accepted"}) + verify(acceptedSpy.valid) + box.accepted() + compare(acceptedSpy.count, 1) + + var rejectedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "rejected"}) + verify(rejectedSpy.valid) + box.rejected() + compare(rejectedSpy.count, 1) + } + + function test_qtbug71444() { + var control = createTemporaryObject(qtbug71444, testCase) + verify(control) + } + + function test_standardButtons() { + var control = createTemporaryObject(dialog, testCase) + + control.standardButtons = Dialog.Ok + + var box = control.footer ? control.footer : control.header + verify(box) + compare(box.count, 1) + var okButton = box.itemAt(0) + verify(okButton) + compare(okButton.text.toUpperCase(), "OK") + + control.standardButtons = Dialog.Cancel + compare(box.count, 1) + var cancelButton = control.footer.itemAt(0) + verify(cancelButton) + compare(cancelButton.text.toUpperCase(), "CANCEL") + + control.standardButtons = Dialog.Ok | Dialog.Cancel + compare(box.count, 2) + if (box.itemAt(0).text.toUpperCase() === "OK") { + okButton = box.itemAt(0) + cancelButton = box.itemAt(1) + } else { + okButton = box.itemAt(1) + cancelButton = box.itemAt(0) + } + verify(okButton) + verify(cancelButton) + compare(okButton.text.toUpperCase(), "OK") + compare(cancelButton.text.toUpperCase(), "CANCEL") + + control.standardButtons = 0 + compare(box.count, 0) + } + + function test_layout() { + var control = createTemporaryObject(dialog, testCase, {width: 100, height: 100}) + verify(control) + + var openedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "opened"}) + verify(openedSpy.valid) + + control.open() + openedSpy.wait() + compare(openedSpy.count, 1) + verify(control.visible) + + compare(control.width, 100) + compare(control.height, 100) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight) + + control.header = buttonBox.createObject(control.contentItem) + compare(control.header.width, control.width) + verify(control.header.height > 0) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight - control.header.height) + + control.footer = buttonBox.createObject(control.contentItem) + compare(control.footer.width, control.width) + verify(control.footer.height > 0) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight - control.header.height - control.footer.height) + + control.topPadding = 9 + control.leftPadding = 2 + control.rightPadding = 6 + control.bottomPadding = 7 + + compare(control.header.x, 0) + compare(control.header.y, 0) + compare(control.header.width, control.width) + verify(control.header.height > 0) + + compare(control.footer.x, 0) + compare(control.footer.y, control.height - control.footer.height) + compare(control.footer.width, control.width) + verify(control.footer.height > 0) + + compare(control.contentItem.x, control.leftPadding) + compare(control.contentItem.y, control.topPadding + control.header.height) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight - control.header.height - control.footer.height) + + control.header.visible = false + compare(control.contentItem.x, control.leftPadding) + compare(control.contentItem.y, control.topPadding) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight - control.footer.height) + + control.footer.visible = false + compare(control.contentItem.x, control.leftPadding) + compare(control.contentItem.y, control.topPadding) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight) + + control.contentItem.implicitWidth = 50 + control.contentItem.implicitHeight = 60 + compare(control.implicitWidth, control.contentItem.implicitWidth + control.leftPadding + control.rightPadding) + compare(control.implicitHeight, control.contentItem.implicitHeight + control.topPadding + control.bottomPadding) + + control.header.visible = true + compare(control.implicitHeight, control.contentItem.implicitHeight + control.topPadding + control.bottomPadding + + control.header.implicitHeight) + + control.footer.visible = true + compare(control.implicitHeight, control.contentItem.implicitHeight + control.topPadding + control.bottomPadding + + control.header.implicitHeight + control.footer.implicitHeight) + + control.header.implicitWidth = 150 + compare(control.implicitWidth, control.header.implicitWidth) + + control.footer.implicitWidth = 160 + compare(control.implicitWidth, control.footer.implicitWidth) + } + + function test_spacing_data() { + return [ + { tag: "content", header: false, content: true, footer: false }, + { tag: "header,content", header: true, content: true, footer: false }, + { tag: "content,footer", header: false, content: true, footer: true }, + { tag: "header,content,footer", header: true, content: true, footer: true }, + { tag: "header,footer", header: true, content: false, footer: true }, + { tag: "header", header: true, content: false, footer: false }, + { tag: "footer", header: false, content: false, footer: true }, + ] + } + + function test_spacing(data) { + var control = createTemporaryObject(dialog, testCase, {spacing: 20, width: 100, height: 100}) + verify(control) + + var openedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "opened"}) + verify(openedSpy.valid) + + control.open() + openedSpy.wait() + compare(openedSpy.count, 1) + verify(control.visible) + + control.contentItem.visible = data.content + control.header = buttonBox.createObject(control.contentItem, {visible: data.header}) + control.footer = buttonBox.createObject(control.contentItem, {visible: data.footer}) + + compare(control.header.x, 0) + compare(control.header.y, 0) + compare(control.header.width, control.width) + verify(control.header.height > 0) + + compare(control.footer.x, 0) + compare(control.footer.y, control.height - control.footer.height) + compare(control.footer.width, control.width) + verify(control.footer.height > 0) + + compare(control.contentItem.x, control.leftPadding) + compare(control.contentItem.y, control.topPadding + (data.header ? control.header.height + control.spacing : 0)) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight + - (data.header ? control.header.height + control.spacing : 0) + - (data.footer ? control.footer.height + control.spacing : 0)) + } + + function test_signals_data() { + return [ + { tag: "Ok", standardButton: Dialog.Ok, signalName: "accepted" }, + { tag: "Open", standardButton: Dialog.Open, signalName: "accepted" }, + { tag: "Save", standardButton: Dialog.Save, signalName: "accepted" }, + { tag: "Cancel", standardButton: Dialog.Cancel, signalName: "rejected" }, + { tag: "Close", standardButton: Dialog.Close, signalName: "rejected" }, + { tag: "Discard", standardButton: Dialog.Discard, signalName: "discarded" }, + { tag: "Apply", standardButton: Dialog.Apply, signalName: "applied" }, + { tag: "Reset", standardButton: Dialog.Reset, signalName: "reset" }, + { tag: "RestoreDefaults", standardButton: Dialog.RestoreDefaults, signalName: "reset" }, + { tag: "Help", standardButton: Dialog.Help, signalName: "helpRequested" }, + { tag: "SaveAll", standardButton: Dialog.SaveAll, signalName: "accepted" }, + { tag: "Yes", standardButton: Dialog.Yes, signalName: "accepted" }, + { tag: "YesToAll", standardButton: Dialog.YesToAll, signalName: "accepted" }, + { tag: "No", standardButton: Dialog.No, signalName: "rejected" }, + { tag: "NoToAll", standardButton: Dialog.NoToAll, signalName: "rejected" }, + { tag: "Abort", standardButton: Dialog.Abort, signalName: "rejected" }, + { tag: "Retry", standardButton: Dialog.Retry, signalName: "accepted" }, + { tag: "Ignore", standardButton: Dialog.Ignore, signalName: "accepted" } + ] + } + + function test_signals(data) { + var control = createTemporaryObject(dialog, testCase) + verify(control) + + control.standardButtons = data.standardButton + var button = control.standardButton(data.standardButton) + verify(button) + + var buttonSpy = signalSpy.createObject(control.contentItem, {target: control, signalName: data.signalName}) + verify(buttonSpy.valid) + + button.clicked() + compare(buttonSpy.count, 1) + } + + Component { + id: qtbug85884 + ApplicationWindow { + property alias focusItemActiveFocus: item.activeFocus + property alias focusDialogVisible: dialog.visible + function closeAndOpen() { + dialog.close() + dialog.open() + dialog.close() + } + visible: true + Item { + id: item + focus: true + } + Dialog { + id: dialog + focus: true + visible: false + onActiveFocusChanged: { + if (!activeFocus) + visible = false + } + enter: Transition { + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 10 } + } + exit: Transition { + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 10 } + } + } + } + } + + function test_focusLeavingDialog(data) { + if (Qt.platform.pluginName === "offscreen") + skip("QTBUG-89909") + + var window = createTemporaryObject(qtbug85884, testCase) + verify(window) + tryCompare(window, "focusItemActiveFocus", true) + + window.focusDialogVisible = true + tryCompare(window, "focusDialogVisible", true) + tryCompare(window, "focusItemActiveFocus", false) + + window.focusDialogVisible = false + tryCompare(window, "focusDialogVisible", false) + tryCompare(window, "focusItemActiveFocus", true) + + window.focusDialogVisible = true + tryCompare(window, "focusDialogVisible", true) + tryCompare(window, "focusItemActiveFocus", false) + window.closeAndOpen() + tryCompare(window, "focusDialogVisible", false) + tryCompare(window, "focusItemActiveFocus", true) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_dialogbuttonbox.qml b/tests/auto/quickcontrols2/controls/data/tst_dialogbuttonbox.qml new file mode 100644 index 00000000000..57216ed11c0 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_dialogbuttonbox.qml @@ -0,0 +1,613 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 600 + height: 400 + visible: true + when: windowShown + name: "DialogButtonBox" + + Component { + id: buttonBox + DialogButtonBox { } + } + + Component { + id: button + Button { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_defaults() { + var control = createTemporaryObject(buttonBox, testCase) + verify(control) + compare(control.count, 0) + verify(control.delegate) + compare(control.standardButtons, 0) + } + + function test_standardButtons() { + var control = createTemporaryObject(buttonBox, testCase) + verify(control) + compare(control.count, 0) + + control.standardButtons = DialogButtonBox.Ok + compare(control.count, 1) + var okButton = control.itemAt(0) + verify(okButton) + compare(okButton.text.toUpperCase(), "OK") + + control.standardButtons = DialogButtonBox.Cancel + compare(control.count, 1) + var cancelButton = control.itemAt(0) + verify(cancelButton) + compare(cancelButton.text.toUpperCase(), "CANCEL") + + control.standardButtons = DialogButtonBox.Ok | DialogButtonBox.Cancel + compare(control.count, 2) + if (control.itemAt(0).text.toUpperCase() === "OK") { + okButton = control.itemAt(0) + cancelButton = control.itemAt(1) + } else { + okButton = control.itemAt(1) + cancelButton = control.itemAt(0) + } + verify(okButton) + verify(cancelButton) + compare(okButton.text.toUpperCase(), "OK") + compare(cancelButton.text.toUpperCase(), "CANCEL") + compare(control.standardButton(DialogButtonBox.Ok), okButton) + compare(control.standardButton(DialogButtonBox.Cancel), cancelButton) + + control.standardButtons = 0 + compare(control.count, 0) + + compare(control.standardButton(DialogButtonBox.Ok), null) + compare(control.standardButton(DialogButtonBox.Cancel), null) + } + + function test_attached() { + var control = createTemporaryObject(buttonBox, testCase) + verify(control) + + control.standardButtons = DialogButtonBox.Ok + var okButton = control.itemAt(0) + compare(okButton.DialogButtonBox.buttonBox, control) + compare(okButton.DialogButtonBox.buttonRole, DialogButtonBox.AcceptRole) + + var saveButton = button.createObject(control, {text: "Save"}) + compare(saveButton.DialogButtonBox.buttonBox, control) + compare(saveButton.DialogButtonBox.buttonRole, DialogButtonBox.InvalidRole) + saveButton.DialogButtonBox.buttonRole = DialogButtonBox.AcceptRole + compare(saveButton.DialogButtonBox.buttonRole, DialogButtonBox.AcceptRole) + + var closeButton = createTemporaryObject(button, null, {text: "Save"}) + compare(closeButton.DialogButtonBox.buttonBox, null) + compare(closeButton.DialogButtonBox.buttonRole, DialogButtonBox.InvalidRole) + closeButton.DialogButtonBox.buttonRole = DialogButtonBox.DestructiveRole + compare(closeButton.DialogButtonBox.buttonRole, DialogButtonBox.DestructiveRole) + control.addItem(closeButton) + compare(closeButton.DialogButtonBox.buttonBox, control) + + control.contentModel.clear() + compare(okButton.DialogButtonBox.buttonBox, null) + compare(saveButton.DialogButtonBox.buttonBox, null) + compare(closeButton.DialogButtonBox.buttonBox, null) + } + + function test_signals_data() { + return [ + { tag: "Ok", standardButton: DialogButtonBox.Ok, buttonRole: DialogButtonBox.AcceptRole, signalName: "accepted" }, + { tag: "Open", standardButton: DialogButtonBox.Open, buttonRole: DialogButtonBox.AcceptRole, signalName: "accepted" }, + { tag: "Save", standardButton: DialogButtonBox.Save, buttonRole: DialogButtonBox.AcceptRole, signalName: "accepted" }, + { tag: "Cancel", standardButton: DialogButtonBox.Cancel, buttonRole: DialogButtonBox.RejectRole, signalName: "rejected" }, + { tag: "Close", standardButton: DialogButtonBox.Close, buttonRole: DialogButtonBox.RejectRole, signalName: "rejected" }, + { tag: "Discard", standardButton: DialogButtonBox.Discard, buttonRole: DialogButtonBox.DestructiveRole, signalName: "discarded" }, + { tag: "Apply", standardButton: DialogButtonBox.Apply, buttonRole: DialogButtonBox.ApplyRole, signalName: "applied" }, + { tag: "Reset", standardButton: DialogButtonBox.Reset, buttonRole: DialogButtonBox.ResetRole, signalName: "reset" }, + { tag: "RestoreDefaults", standardButton: DialogButtonBox.RestoreDefaults, buttonRole: DialogButtonBox.ResetRole, signalName: "reset" }, + { tag: "Help", standardButton: DialogButtonBox.Help, buttonRole: DialogButtonBox.HelpRole, signalName: "helpRequested" }, + { tag: "SaveAll", standardButton: DialogButtonBox.SaveAll, buttonRole: DialogButtonBox.AcceptRole, signalName: "accepted" }, + { tag: "Yes", standardButton: DialogButtonBox.Yes, buttonRole: DialogButtonBox.YesRole, signalName: "accepted" }, + { tag: "YesToAll", standardButton: DialogButtonBox.YesToAll, buttonRole: DialogButtonBox.YesRole, signalName: "accepted" }, + { tag: "No", standardButton: DialogButtonBox.No, buttonRole: DialogButtonBox.NoRole, signalName: "rejected" }, + { tag: "NoToAll", standardButton: DialogButtonBox.NoToAll, buttonRole: DialogButtonBox.NoRole, signalName: "rejected" }, + { tag: "Abort", standardButton: DialogButtonBox.Abort, buttonRole: DialogButtonBox.RejectRole, signalName: "rejected" }, + { tag: "Retry", standardButton: DialogButtonBox.Retry, buttonRole: DialogButtonBox.AcceptRole, signalName: "accepted" }, + { tag: "Ignore", standardButton: DialogButtonBox.Ignore, buttonRole: DialogButtonBox.AcceptRole, signalName: "accepted" } + ] + } + + function test_signals(data) { + var control = createTemporaryObject(buttonBox, testCase) + verify(control) + + control.standardButtons = data.standardButton + compare(control.count, 1) + var button = control.itemAt(0) + verify(button) + compare(button.DialogButtonBox.buttonRole, data.buttonRole) + + var clickedSpy = signalSpy.createObject(control, {target: control, signalName: "clicked"}) + verify(clickedSpy.valid) + var roleSpy = signalSpy.createObject(control, {target: control, signalName: data.signalName}) + verify(roleSpy.valid) + + button.clicked() + compare(clickedSpy.count, 1) + compare(clickedSpy.signalArguments[0][0], button) + compare(roleSpy.count, 1) + } + + function test_buttonLayout_data() { + return [ + { tag: "WinLayout", buttonLayout: DialogButtonBox.WinLayout, button1Role: DialogButtonBox.AcceptRole, button2Role: DialogButtonBox.RejectRole }, + { tag: "MacLayout", buttonLayout: DialogButtonBox.MacLayout, button1Role: DialogButtonBox.RejectRole, button2Role: DialogButtonBox.AcceptRole }, + { tag: "KdeLayout", buttonLayout: DialogButtonBox.KdeLayout, button1Role: DialogButtonBox.AcceptRole, button2Role: DialogButtonBox.RejectRole }, + { tag: "GnomeLayout", buttonLayout: DialogButtonBox.GnomeLayout, button1Role: DialogButtonBox.RejectRole, button2Role: DialogButtonBox.AcceptRole }, + { tag: "AndroidLayout", buttonLayout: DialogButtonBox.AndroidLayout, button1Role: DialogButtonBox.RejectRole, button2Role: DialogButtonBox.AcceptRole } + ] + } + + function test_buttonLayout(data) { + var control = createTemporaryObject(buttonBox, testCase, {buttonLayout: data.buttonLayout, standardButtons: DialogButtonBox.Ok|DialogButtonBox.Cancel}) + verify(control) + + compare(control.count, 2) + + var button1 = control.itemAt(0) + verify(button1) + compare(button1.DialogButtonBox.buttonRole, data.button1Role) + + var button2 = control.itemAt(1) + verify(button2) + compare(button2.DialogButtonBox.buttonRole, data.button2Role) + } + + function test_implicitSize_data() { + return [ + { tag: "Ok", standardButtons: DialogButtonBox.Ok }, + { tag: "Yes|No", standardButtons: DialogButtonBox.Yes | DialogButtonBox.No } + ] + } + + // QTBUG-59719 + function test_implicitSize(data) { + var control = createTemporaryObject(buttonBox, testCase, {standardButtons: data.standardButtons}) + verify(control) + + var listView = control.contentItem + verify(listView && listView.hasOwnProperty("contentWidth")) + waitForRendering(listView) + + var implicitContentWidth = control.leftPadding + control.rightPadding + for (var i = 0; i < listView.contentItem.children.length; ++i) { + var button = listView.contentItem.children[i] + if (!button.hasOwnProperty("text")) + continue + implicitContentWidth += button.implicitWidth + } + + verify(implicitContentWidth > control.leftPadding + control.rightPadding) + verify(control.implicitWidth >= implicitContentWidth, qsTr("implicit width (%1) is less than content width (%2)").arg(control.implicitWidth).arg(implicitContentWidth)) + } + + Component { + id: okCancelBox + DialogButtonBox { + Button { + text: qsTr("OK") + } + Button { + text: qsTr("Cancel") + } + } + } + + function test_buttonSize() { + var control = createTemporaryObject(okCancelBox, testCase) + verify(control) + + var okButton = control.itemAt(0) + verify(okButton) + verify(okButton.width > 0) + + var cancelButton = control.itemAt(1) + verify(cancelButton) + verify(cancelButton.width > 0) + + compare(okButton.width + cancelButton.width, control.availableWidth - control.spacing) + } + + function test_oneButtonInFixedWidthBox() { + var control = createTemporaryObject(buttonBox, testCase, + { width: 400, standardButtons: Dialog.Close }) + verify(control) + + var listView = control.contentItem + waitForRendering(listView) + + var button = control.itemAt(0) + verify(button) + + // The button should never go outside of the box. + tryVerify(function() { return button.mapToItem(control, 0, 0).x >= 0 }, + 1000, "Expected left edge of button to be within left edge of DialogButtonBox (i.e. greater than or equal to 0)" + + ", but it's " + button.mapToItem(control, 0, 0).x) + tryVerify(function() { return button.mapToItem(control, 0, 0).x + button.width <= control.width }, + 1000, "Expected right edge of button to be within right edge of DialogButtonBox (i.e. less than or equal to " + + control.width + "), but it's " + (button.mapToItem(control, 0, 0).x + button.width)) + } + + Component { + id: dialogComponent + // Based on the Basic style, where a single button fills + // half the dialog's width and is aligned to the right. + Dialog { + id: control + standardButtons: Dialog.Ok + visible: true + + footer: DialogButtonBox { + id: box + visible: count > 0 + alignment: count === 1 ? Qt.AlignRight : undefined + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + (count === 1 ? implicitContentWidth * 2 : implicitContentWidth) + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + contentWidth: contentItem.contentWidth + + delegate: Button { + width: box.count === 1 ? box.availableWidth / 2 : undefined + } + } + } + } + + // QTBUG-73860 + function test_oneButtonAlignedRightInImplicitWidthBox() { + var dialog = createTemporaryObject(dialogComponent, testCase) + verify(dialog) + + var box = dialog.footer + var listView = box.contentItem + waitForRendering(listView) + + var button = box.itemAt(0) + verify(button) + + // The button should never go outside of the box. + tryVerify(function() { return button.mapToItem(box, 0, 0).x >= 0 }, + 1000, "Expected left edge of button to be within left edge of DialogButtonBox (i.e. greater than or equal to 0)" + + ", but it's " + button.mapToItem(box, 0, 0).x) + tryVerify(function() { return button.mapToItem(box, 0, 0).x + button.width <= box.width }, + 1000, "Expected right edge of button to be within right edge of DialogButtonBox (i.e. less than or equal to " + + box.width + "), but it's " + (button.mapToItem(box, 0, 0).x + button.width)) + compare(box.width, dialog.width) + // There's a single button and we align it to the right. + compare(box.contentItem.width, button.width) + compare(box.contentItem.x, box.width - box.rightPadding - box.contentItem.width) + } + + Component { + id: customButtonBox + + DialogButtonBox { + objectName: "customButtonBox" + alignment: Qt.AlignRight + + property alias okButton: okButton + + Button { + id: okButton + text: "OK" + + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + } + } + } + + Component { + id: customButtonBoxTwoButtons + + DialogButtonBox { + objectName: "customButtonBoxTwoButtons" + alignment: Qt.AlignRight + + property alias okButton: okButton + + Button { + id: okButton + text: "OK" + + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + } + Button { + text: "Cancel" + + DialogButtonBox.buttonRole: DialogButtonBox.RejectRole + } + } + } + + function test_changeCustomButtonText_data() { + return [ + { tag: "oneButton", component: customButtonBox }, + { tag: "twoButtons", component: customButtonBoxTwoButtons }, + ] + } + + // QTBUG-72886 + function test_changeCustomButtonText(data) { + var control = createTemporaryObject(data.component, testCase, {}) + verify(control) + + var listView = control.contentItem + waitForRendering(listView) + + var button = control.okButton + verify(button) + button.text = "some longer text"; + + // The button should never go outside of the box. + tryVerify(function() { return button.mapToItem(control, 0, 0).x >= 0 }, + 1000, "Expected left edge of button to be within left edge of DialogButtonBox (i.e. greater than or equal to 0)" + + ", but it's " + button.mapToItem(control, 0, 0).x) + tryVerify(function() { return button.mapToItem(control, 0, 0).x + button.width <= control.width }, + 1000, "Expected right edge of button to be within right edge of DialogButtonBox (i.e. less than or equal to " + + control.width + "), but it's " + (button.mapToItem(control, 0, 0).x + button.width)) + } + + Component { + id: customButtonBoxInDialog + + Dialog { + width: 300 + visible: true + + footer: DialogButtonBox { + objectName: "customButtonBoxInDialog" + alignment: Qt.AlignRight + + property alias okButton: okButton + + Button { + id: okButton + text: "OK" + + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + } + } + } + } + + Component { + id: customButtonBoxTwoButtonsInDialog + + Dialog { + width: 300 + visible: true + + footer: DialogButtonBox { + objectName: "customButtonBoxTwoButtonsInDialog" + alignment: Qt.AlignRight + + property alias okButton: okButton + + Button { + id: okButton + text: "OK" + + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + } + Button { + text: "Cancel" + + DialogButtonBox.buttonRole: DialogButtonBox.RejectRole + } + } + } + } + + function test_changeCustomButtonImplicitWidth_data() { + return [ + { tag: "oneButton", component: customButtonBoxInDialog }, + { tag: "twoButtons", component: customButtonBoxTwoButtonsInDialog }, + ] + } + + // QTBUG-102558 + function test_changeCustomButtonImplicitWidth(data) { + let dialog = createTemporaryObject(data.component, testCase, {}) + verify(dialog) + + let control = dialog.footer + verify(control) + + let listView = control.contentItem + waitForRendering(listView) + + let button = control.okButton + verify(button) + button.implicitWidth *= 1.5 + + // The button should never go outside of the box. + tryVerify(function() { return button.mapToItem(control, 0, 0).x >= 0 }, + 1000, "Expected left edge of button to be within left edge of DialogButtonBox (i.e. greater than or equal to 0)" + + ", but it's " + button.mapToItem(control, 0, 0).x) + tryVerify(function() { return button.mapToItem(control, 0, 0).x + button.width <= control.width }, + 1000, "Expected right edge of button to be within right edge of DialogButtonBox (i.e. less than or equal to " + + control.width + "), but it's " + (button.mapToItem(control, 0, 0).x + button.width)) + } + + Component { + id: noRolesDialog + + Dialog { + footer: DialogButtonBox { + Button { text: "A" } + Button { text: "B" } + Button { text: "C" } + } + } + } + + function test_orderWithNoRoles() { + for (let i = 0; i < 10; ++i) { + let control = createTemporaryObject(noRolesDialog, testCase) + verify(control) + + control.open() + tryCompare(control, "opened", true) + let footer = control.footer + verify(footer) + waitForItemPolished(footer.contentItem) + compare(footer.itemAt(0).text, "A") + compare(footer.itemAt(1).text, "B") + compare(footer.itemAt(2).text, "C") + + control.destroy() + } + } + + Component { + id: contentItemDeletionOrder1 + + Item { + objectName: "parentItem" + + Item { + id: item + objectName: "contentItem" + } + DialogButtonBox { + objectName: "control" + contentItem: item + } + } + } + + Component { + id: contentItemDeletionOrder2 + + Item { + objectName: "parentItem" + + DialogButtonBox { + objectName: "control" + contentItem: item + } + Item { + id: item + objectName: "contentItem" + } + } + } + + function test_contentItemDeletionOrder() { + var control1 = createTemporaryObject(contentItemDeletionOrder1, testCase) + verify(control1) + var control2 = createTemporaryObject(contentItemDeletionOrder2, testCase) + verify(control2) + } + + Component { + id: backgroundDeletionOrder1 + + Item { + objectName: "parentItem" + + Item { + id: item + objectName: "backgroundItem" + } + DialogButtonBox { + objectName: "control" + background: item + } + } + } + + Component { + id: backgroundDeletionOrder2 + + Item { + objectName: "parentItem" + + DialogButtonBox { + objectName: "control" + background: item + } + Item { + id: item + objectName: "backgroundItem" + } + } + } + + function test_backgroundDeletionOrder() { + var control1 = createTemporaryObject(backgroundDeletionOrder1, testCase) + verify(control1) + var control2 = createTemporaryObject(backgroundDeletionOrder2, testCase) + verify(control2) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_frame.qml b/tests/auto/quickcontrols2/controls/data/tst_frame.qml new file mode 100644 index 00000000000..95c691441f8 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_frame.qml @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "Frame" + + Component { + id: frame + Frame { } + } + + Component { + id: oneChildFrame + Frame { + Item { + implicitWidth: 100 + implicitHeight: 30 + } + } + } + + Component { + id: twoChildrenFrame + Frame { + Item { + implicitWidth: 100 + implicitHeight: 30 + } + Item { + implicitWidth: 200 + implicitHeight: 60 + } + } + } + + Component { + id: contentFrame + Frame { + contentItem: Item { + implicitWidth: 100 + implicitHeight: 30 + } + } + } + + function test_empty() { + var control = createTemporaryObject(frame, testCase) + verify(control) + + verify(control.contentItem) + compare(control.contentWidth, 0) + compare(control.contentHeight, 0) + compare(control.implicitContentWidth, 0) + compare(control.implicitContentHeight, 0) + } + + function test_oneChild() { + var control = createTemporaryObject(oneChildFrame, testCase) + verify(control) + + compare(control.contentWidth, 100) + compare(control.contentHeight, 30) + compare(control.implicitContentWidth, 100) + compare(control.implicitContentHeight, 30) + verify(control.implicitWidth > 100) + verify(control.implicitHeight > 30) + } + + function test_twoChildren() { + var control = createTemporaryObject(twoChildrenFrame, testCase) + verify(control) + + compare(control.contentWidth, 0) + compare(control.contentHeight, 0) + compare(control.implicitContentWidth, 0) + compare(control.implicitContentHeight, 0) + verify(control.implicitWidth > 0) + verify(control.implicitHeight > 0) + } + + function test_contentItem() { + var control = createTemporaryObject(contentFrame, testCase) + verify(control) + + compare(control.contentWidth, 100) + compare(control.contentHeight, 30) + compare(control.implicitContentWidth, 100) + compare(control.implicitContentHeight, 30) + verify(control.implicitWidth > 100) + verify(control.implicitHeight > 30) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_groupbox.qml b/tests/auto/quickcontrols2/controls/data/tst_groupbox.qml new file mode 100644 index 00000000000..ed7148978a2 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_groupbox.qml @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "GroupBox" + + Component { + id: groupBox + GroupBox { } + } + + Component { + id: oneChildBox + GroupBox { + Item { + implicitWidth: 100 + implicitHeight: 30 + } + } + } + + Component { + id: twoChildrenBox + GroupBox { + Item { + implicitWidth: 100 + implicitHeight: 30 + } + Item { + implicitWidth: 200 + implicitHeight: 60 + } + } + } + + Component { + id: contentBox + GroupBox { + contentItem: Item { + implicitWidth: 100 + implicitHeight: 30 + } + } + } + + function test_empty() { + var control = createTemporaryObject(groupBox, testCase) + verify(control) + + verify(control.contentItem) + compare(control.contentWidth, 0) + compare(control.contentHeight, 0) + compare(control.implicitContentWidth, 0) + compare(control.implicitContentHeight, 0) + } + + function test_oneChild() { + var control = createTemporaryObject(oneChildBox, testCase) + verify(control) + + compare(control.contentWidth, 100) + compare(control.contentHeight, 30) + compare(control.implicitContentWidth, 100) + compare(control.implicitContentHeight, 30) + verify(control.implicitWidth > 100) + verify(control.implicitHeight > 30) + } + + function test_twoChildren() { + var control = createTemporaryObject(twoChildrenBox, testCase) + verify(control) + + compare(control.contentWidth, 0) + compare(control.contentHeight, 0) + compare(control.implicitContentWidth, 0) + compare(control.implicitContentHeight, 0) + verify(control.implicitWidth > 0) + verify(control.implicitHeight > 0) + } + + function test_contentItem() { + var control = createTemporaryObject(contentBox, testCase) + verify(control) + + compare(control.contentWidth, 100) + compare(control.contentHeight, 30) + compare(control.implicitContentWidth, 100) + compare(control.implicitContentHeight, 30) + verify(control.implicitWidth > 100) + verify(control.implicitHeight > 30) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_itemdelegate.qml b/tests/auto/quickcontrols2/controls/data/tst_itemdelegate.qml new file mode 100644 index 00000000000..7fa4e9e4939 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_itemdelegate.qml @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "ItemDelegate" + + Component { + id: itemDelegate + ItemDelegate { } + } + + function test_baseline() { + var control = createTemporaryObject(itemDelegate, testCase) + verify(control) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + } + + function test_highlighted() { + var control = createTemporaryObject(itemDelegate, testCase) + verify(control) + verify(!control.highlighted) + + control.highlighted = true + verify(control.highlighted) + } + + function test_spacing() { + var control = createTemporaryObject(itemDelegate, testCase, { text: "Some long, long, long text" }) + verify(control) + verify(control.contentItem.implicitWidth + control.leftPadding + control.rightPadding > control.background.implicitWidth) + + var textLabel = findChild(control.contentItem, "label") + verify(textLabel) + + // The implicitWidth of the IconLabel that all buttons use as their contentItem + // should be equal to the implicitWidth of the Text while no icon is set. + compare(control.contentItem.implicitWidth, textLabel.implicitWidth) + + // That means that spacing shouldn't affect it. + control.spacing += 100 + compare(control.contentItem.implicitWidth, textLabel.implicitWidth) + + // The implicitWidth of the ItemDelegate itself should, therefore, also never include spacing while no icon is set. + compare(control.implicitWidth, textLabel.implicitWidth + control.leftPadding + control.rightPadding) + } + + function test_display_data() { + return [ + { "tag": "IconOnly", display: ItemDelegate.IconOnly }, + { "tag": "TextOnly", display: ItemDelegate.TextOnly }, + { "tag": "TextUnderIcon", display: ItemDelegate.TextUnderIcon }, + { "tag": "TextBesideIcon", display: ItemDelegate.TextBesideIcon }, + { "tag": "IconOnly, mirrored", display: ItemDelegate.IconOnly, mirrored: true }, + { "tag": "TextOnly, mirrored", display: ItemDelegate.TextOnly, mirrored: true }, + { "tag": "TextUnderIcon, mirrored", display: ItemDelegate.TextUnderIcon, mirrored: true }, + { "tag": "TextBesideIcon, mirrored", display: ItemDelegate.TextBesideIcon, mirrored: true } + ] + } + + function test_display(data) { + var control = createTemporaryObject(itemDelegate, testCase, { + text: "ItemDelegate", + display: data.display, + width: 400, + "icon.source": "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png", + "LayoutMirroring.enabled": !!data.mirrored + }) + verify(control) + compare(control.icon.source, "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png") + + var iconImage = findChild(control.contentItem, "image") + var textLabel = findChild(control.contentItem, "label") + + switch (control.display) { + case ItemDelegate.IconOnly: + verify(iconImage) + verify(!textLabel) + compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + break; + case ItemDelegate.TextOnly: + verify(!iconImage) + verify(textLabel) + compare(textLabel.x, control.mirrored ? control.availableWidth - textLabel.width : 0) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + case ItemDelegate.TextUnderIcon: + verify(iconImage) + verify(textLabel) + compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + verify(iconImage.y < textLabel.y) + break; + case ItemDelegate.TextBesideIcon: + verify(iconImage) + verify(textLabel) + if (control.mirrored) + verify(textLabel.x < iconImage.x) + else + verify(iconImage.x < textLabel.x) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + } + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_label.qml b/tests/auto/quickcontrols2/controls/data/tst_label.qml new file mode 100644 index 00000000000..d6efb1373a5 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_label.qml @@ -0,0 +1,294 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "Label" + + Component { + id: label + Label { } + } + + Component { + id: backgroundLabel + Label { + background: Rectangle { } + } + } + + Component { + id: rectangle + Rectangle { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_creation() { + var control = createTemporaryObject(label, testCase) + verify(control) + } + + function test_font_explicit_attributes_data() { + return [ + {tag: "bold", value: true}, + {tag: "capitalization", value: Font.Capitalize}, + {tag: "family", value: "Courier"}, + {tag: "italic", value: true}, + {tag: "strikeout", value: true}, + {tag: "underline", value: true}, + {tag: "weight", value: Font.Black}, + {tag: "wordSpacing", value: 55} + ] + } + + function test_font_explicit_attributes(data) { + var control = createTemporaryObject(label, testCase) + verify(control) + + var child = label.createObject(control) + verify(child) + + var controlSpy = signalSpy.createObject(control, {target: control, signalName: "fontChanged"}) + verify(controlSpy.valid) + + var childSpy = signalSpy.createObject(child, {target: child, signalName: "fontChanged"}) + verify(childSpy.valid) + + var defaultValue = control.font[data.tag] + child.font[data.tag] = defaultValue + + compare(child.font[data.tag], defaultValue) + compare(childSpy.count, 0) + + control.font[data.tag] = data.value + + compare(control.font[data.tag], data.value) + compare(controlSpy.count, 1) + + compare(child.font[data.tag], defaultValue) + compare(childSpy.count, 0) + } + + function test_background() { + var control = createTemporaryObject(backgroundLabel, testCase, {text: "Label"}) + verify(control) + + compare(control.background.width, control.width) + compare(control.background.height, control.height) + + control.background = rectangle.createObject(control) + compare(control.background.width, control.width) + compare(control.background.height, control.height) + + // change implicit size (QTBUG-66455) + control.background.implicitWidth = 160 + control.background.implicitHeight = 120 + compare(control.background.width, control.width) + compare(control.background.height, control.height) + } + + function test_inset() { + var control = createTemporaryObject(label, testCase, {background: rectangle.createObject(control)}) + verify(control) + + var topInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "topInsetChanged"}) + verify(topInsetSpy.valid) + + var leftInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "leftInsetChanged"}) + verify(leftInsetSpy.valid) + + var rightInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "rightInsetChanged"}) + verify(rightInsetSpy.valid) + + var bottomInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "bottomInsetChanged"}) + verify(bottomInsetSpy.valid) + + var topInsetChanges = 0 + var leftInsetChanges = 0 + var rightInsetChanges = 0 + var bottomInsetChanges = 0 + + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + + control.width = 100 + control.height = 100 + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 100) + compare(control.background.height, 100) + + control.topInset = 10 + compare(control.topInset, 10) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, ++topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 10) + compare(control.background.width, 100) + compare(control.background.height, 90) + + control.leftInset = 20 + compare(control.topInset, 10) + compare(control.leftInset, 20) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, ++leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 10) + compare(control.background.width, 80) + compare(control.background.height, 90) + + control.rightInset = 30 + compare(control.topInset, 10) + compare(control.leftInset, 20) + compare(control.rightInset, 30) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, ++rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 10) + compare(control.background.width, 50) + compare(control.background.height, 90) + + control.bottomInset = 40 + compare(control.topInset, 10) + compare(control.leftInset, 20) + compare(control.rightInset, 30) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, ++bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 10) + compare(control.background.width, 50) + compare(control.background.height, 50) + + control.topInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 20) + compare(control.rightInset, 30) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, ++topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 0) + compare(control.background.width, 50) + compare(control.background.height, 60) + + control.leftInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 30) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, ++leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 70) + compare(control.background.height, 60) + + control.rightInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, ++rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 100) + compare(control.background.height, 60) + + control.bottomInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, ++bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 100) + compare(control.background.height, 100) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_menuitem.qml b/tests/auto/quickcontrols2/controls/data/tst_menuitem.qml new file mode 100644 index 00000000000..713c030efd0 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_menuitem.qml @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "MenuItem" + + Component { + id: menuItem + MenuItem { } + } + + Component { + id: menu + Menu { } + } + + function test_baseline() { + var control = createTemporaryObject(menuItem, testCase) + verify(control) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + } + + function test_checkable() { + var control = createTemporaryObject(menuItem, testCase) + verify(control) + verify(control.hasOwnProperty("checkable")) + verify(!control.checkable) + + mouseClick(control) + verify(!control.checked) + + control.checkable = true + mouseClick(control) + verify(control.checked) + + mouseClick(control) + verify(!control.checked) + } + + function test_highlighted() { + var control = createTemporaryObject(menuItem, testCase) + verify(control) + verify(!control.highlighted) + + control.highlighted = true + verify(control.highlighted) + } + + function test_display_data() { + return [ + { "tag": "IconOnly", display: MenuItem.IconOnly }, + { "tag": "TextOnly", display: MenuItem.TextOnly }, + { "tag": "TextUnderIcon", display: MenuItem.TextUnderIcon }, + { "tag": "TextBesideIcon", display: MenuItem.TextBesideIcon }, + { "tag": "IconOnly, mirrored", display: MenuItem.IconOnly, mirrored: true }, + { "tag": "TextOnly, mirrored", display: MenuItem.TextOnly, mirrored: true }, + { "tag": "TextUnderIcon, mirrored", display: MenuItem.TextUnderIcon, mirrored: true }, + { "tag": "TextBesideIcon, mirrored", display: MenuItem.TextBesideIcon, mirrored: true } + ] + } + + function test_display(data) { + var control = createTemporaryObject(menuItem, testCase, { + text: "MenuItem", + display: data.display, + "icon.source": "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png", + "LayoutMirroring.enabled": !!data.mirrored + }) + verify(control) + compare(control.icon.source, "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png") + + var padding = data.mirrored ? control.contentItem.rightPadding : control.contentItem.leftPadding + var iconImage = findChild(control.contentItem, "image") + var textLabel = findChild(control.contentItem, "label") + + switch (control.display) { + case MenuItem.IconOnly: + verify(iconImage) + verify(!textLabel) + compare(iconImage.x, control.mirrored ? control.availableWidth - iconImage.width - padding : padding) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + break; + case MenuItem.TextOnly: + verify(!iconImage) + verify(textLabel) + compare(textLabel.x, control.mirrored ? control.availableWidth - textLabel.width - padding : padding) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + case MenuItem.TextUnderIcon: + verify(iconImage) + verify(textLabel) + compare(iconImage.x, control.mirrored ? control.availableWidth - iconImage.width - (textLabel.width - iconImage.width) / 2 - padding : (textLabel.width - iconImage.width) / 2 + padding) + compare(textLabel.x, control.mirrored ? control.availableWidth - textLabel.width - padding : padding) + verify(iconImage.y < textLabel.y) + break; + case MenuItem.TextBesideIcon: + verify(iconImage) + verify(textLabel) + if (control.mirrored) + verify(textLabel.x < iconImage.x) + else + verify(iconImage.x < textLabel.x) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + } + } + + function test_menu() { + var control = createTemporaryObject(menu, testCase) + verify(control) + + var item1 = createTemporaryObject(menuItem, testCase) + verify(item1) + compare(item1.menu, null) + + var item2 = createTemporaryObject(menuItem, testCase) + verify(item2) + compare(item2.menu, null) + + control.addItem(item1) + compare(item1.menu, control) + compare(item2.menu, null) + + control.insertItem(1, item2) + compare(item1.menu, control) + compare(item2.menu, control) + + control.removeItem(control.itemAt(1)) + compare(item1.menu, control) + compare(item2.menu, null) + + control.removeItem(control.itemAt(0)) + compare(item1.menu, null) + compare(item2.menu, null) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_page.qml b/tests/auto/quickcontrols2/controls/data/tst_page.qml new file mode 100644 index 00000000000..ae78a125631 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_page.qml @@ -0,0 +1,315 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "Page" + + Component { + id: page + Page { } + } + + Component { + id: oneChildPage + Page { + Item { + implicitWidth: 100 + implicitHeight: 30 + } + } + } + + Component { + id: twoChildrenPage + Page { + Item { + implicitWidth: 100 + implicitHeight: 30 + } + Item { + implicitWidth: 200 + implicitHeight: 60 + } + } + } + + Component { + id: contentPage + Page { + contentItem: Item { + implicitWidth: 100 + implicitHeight: 30 + } + } + } + + Component { + id: headerFooterPage + Page { + header: ToolBar { } + footer: ToolBar { } + contentItem: Item { + implicitWidth: 100 + implicitHeight: 30 + } + } + } + + Component { + id: toolBar + ToolBar { } + } + + function test_defaults() { + var control = createTemporaryObject(page, testCase) + verify(control) + + verify(control.contentItem) + compare(control.header, null) + compare(control.footer, null) + } + + function test_empty() { + var control = createTemporaryObject(page, testCase) + verify(control) + + verify(control.contentItem) + compare(control.contentWidth, 0) + compare(control.contentHeight, 0) + compare(control.implicitContentWidth, 0) + compare(control.implicitContentHeight, 0) + } + + function test_oneChild() { + var control = createTemporaryObject(oneChildPage, testCase) + verify(control) + + compare(control.contentWidth, 100) + compare(control.contentHeight, 30) + compare(control.implicitContentWidth, 100) + compare(control.implicitContentHeight, 30) + compare(control.implicitWidth, 100 + control.leftPadding + control.rightPadding) + compare(control.implicitHeight, 30 + control.topPadding + control.bottomPadding) + } + + function test_twoChildren() { + var control = createTemporaryObject(twoChildrenPage, testCase) + verify(control) + + compare(control.contentWidth, 0) + compare(control.contentHeight, 0) + compare(control.implicitContentWidth, 0) + compare(control.implicitContentHeight, 0) + compare(control.implicitWidth, Math.max(control.leftPadding + control.rightPadding, + control.background ? control.background.implicitWidth : 0)) + compare(control.implicitHeight, Math.max(control.topPadding + control.bottomPadding, + control.background ? control.background.implicitHeight : 0)) + } + + function test_contentItem() { + var control = createTemporaryObject(contentPage, testCase) + verify(control) + + compare(control.contentWidth, 100) + compare(control.contentHeight, 30) + compare(control.implicitContentWidth, 100) + compare(control.implicitContentHeight, 30) + compare(control.implicitWidth, 100 + control.leftPadding + control.rightPadding) + compare(control.implicitHeight, 30 + control.topPadding + control.bottomPadding) + } + + function test_layout() { + var control = createTemporaryObject(page, testCase, {width: 100, height: 100}) + verify(control) + + compare(control.width, 100) + compare(control.height, 100) + compare(control.contentItem.width, control.width) + compare(control.contentItem.height, control.height) + + control.header = toolBar.createObject(control) + compare(control.header.width, control.width) + verify(control.header.height > 0) + compare(control.contentItem.width, control.width) + compare(control.contentItem.height, control.height - control.header.height) + + control.footer = toolBar.createObject(control) + compare(control.footer.width, control.width) + verify(control.footer.height > 0) + compare(control.contentItem.width, control.width) + compare(control.contentItem.height, control.height - control.header.height - control.footer.height) + + control.topPadding = 9 + control.leftPadding = 2 + control.rightPadding = 6 + control.bottomPadding = 7 + + compare(control.header.x, 0) + compare(control.header.y, 0) + compare(control.header.width, control.width) + verify(control.header.height > 0) + + compare(control.footer.x, 0) + compare(control.footer.y, control.height - control.footer.height) + compare(control.footer.width, control.width) + verify(control.footer.height > 0) + + compare(control.contentItem.x, control.leftPadding) + compare(control.contentItem.y, control.topPadding + control.header.height) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight - control.header.height - control.footer.height) + + control.header.visible = false + compare(control.contentItem.x, control.leftPadding) + compare(control.contentItem.y, control.topPadding) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight - control.footer.height) + + control.footer.visible = false + compare(control.contentItem.x, control.leftPadding) + compare(control.contentItem.y, control.topPadding) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight) + + control.contentItem.implicitWidth = 50 + control.contentItem.implicitHeight = 60 + compare(control.implicitWidth, control.contentItem.implicitWidth + control.leftPadding + control.rightPadding) + compare(control.implicitHeight, control.contentItem.implicitHeight + control.topPadding + control.bottomPadding) + + control.header.visible = true + compare(control.implicitHeight, control.contentItem.implicitHeight + control.topPadding + control.bottomPadding + + control.header.implicitHeight + control.spacing) + + control.footer.visible = true + compare(control.implicitHeight, control.contentItem.implicitHeight + control.topPadding + control.bottomPadding + + control.header.implicitHeight + control.footer.implicitHeight + 2 * control.spacing) + + control.header.implicitWidth = 150 + compare(control.implicitWidth, control.header.implicitWidth) + + control.footer.implicitWidth = 160 + compare(control.implicitWidth, control.footer.implicitWidth) + + control.contentItem.implicitWidth = 170 + compare(control.implicitWidth, control.contentItem.implicitWidth + control.leftPadding + control.rightPadding) + } + + function test_spacing_data() { + return [ + { tag: "content", header: false, content: true, footer: false }, + { tag: "header,content", header: true, content: true, footer: false }, + { tag: "content,footer", header: false, content: true, footer: true }, + { tag: "header,content,footer", header: true, content: true, footer: true }, + { tag: "header,footer", header: true, content: false, footer: true }, + { tag: "header", header: true, content: false, footer: false }, + { tag: "footer", header: false, content: false, footer: true }, + ] + } + + function test_spacing(data) { + var control = createTemporaryObject(page, testCase, {spacing: 20, width: 100, height: 100}) + verify(control) + + control.contentItem.visible = data.content + control.header = toolBar.createObject(control.contentItem, {visible: data.header}) + control.footer = toolBar.createObject(control.contentItem, {visible: data.footer}) + + compare(control.header.x, 0) + compare(control.header.y, 0) + compare(control.header.width, control.width) + verify(control.header.height > 0) + + compare(control.footer.x, 0) + compare(control.footer.y, control.height - control.footer.height) + compare(control.footer.width, control.width) + verify(control.footer.height > 0) + + compare(control.contentItem.x, control.leftPadding) + compare(control.contentItem.y, control.topPadding + (data.header ? control.header.height + control.spacing : 0)) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight + - (data.header ? control.header.height + control.spacing : 0) + - (data.footer ? control.footer.height + control.spacing : 0)) + } + + function test_headerFooter() { + var control = createTemporaryObject(headerFooterPage, testCase, {width: 100, height: 100}) + verify(control) + + compare(control.width, 100) + compare(control.height, 100) + + verify(control.header) + compare(control.header.x, 0) + compare(control.header.y, 0) + compare(control.header.width, control.width) + verify(control.header.height > 0) + + verify(control.footer) + compare(control.footer.x, 0) + compare(control.footer.y, control.height - control.footer.height) + compare(control.footer.width, control.width) + verify(control.footer.height > 0) + + compare(control.contentItem.x, 0) + compare(control.contentItem.y, control.header.height) + compare(control.contentItem.width, control.width) + compare(control.contentItem.height, control.height - control.header.height - control.footer.height) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_pageindicator.qml b/tests/auto/quickcontrols2/controls/data/tst_pageindicator.qml new file mode 100644 index 00000000000..765c52a77ac --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_pageindicator.qml @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "PageIndicator" + + Component { + id: pageIndicator + PageIndicator { } + } + + Component { + id: mouseArea + MouseArea { } + } + + function test_count() { + var control = createTemporaryObject(pageIndicator, testCase) + verify(control) + + compare(control.count, 0) + control.count = 3 + compare(control.count, 3) + } + + function test_currentIndex() { + var control = createTemporaryObject(pageIndicator, testCase) + verify(control) + + compare(control.currentIndex, 0) + control.currentIndex = 5 + compare(control.currentIndex, 5) + } + + function test_interactive_data() { + return [ + { tag: "mouse", touch: false }, + { tag: "touch", touch: true } + ] + } + + function test_interactive(data) { + var control = createTemporaryObject(pageIndicator, testCase, {count: 5, spacing: 10, topPadding: 10, leftPadding: 10, rightPadding: 10, bottomPadding: 10}) + verify(control) + + verify(!control.interactive) + compare(control.currentIndex, 0) + + var touch = touchEvent(control) + + if (data.touch) + touch.press(0, control).commit().release(0, control).commit() + else + mouseClick(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.currentIndex, 0) + + control.interactive = true + verify(control.interactive) + + if (data.touch) + touch.press(0, control).commit().release(0, control).commit() + else + mouseClick(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.currentIndex, 2) + + // test also clicking outside delegates => the nearest should be selected + for (var i = 0; i < control.count; ++i) { + var child = control.contentItem.children[i] + + var points = [ + Qt.point(child.width / 2, -2), // top + Qt.point(-2, child.height / 2), // left + Qt.point(child.width + 2, child.height / 2), // right + Qt.point(child.width / 2, child.height + 2), // bottom + + Qt.point(-2, -2), // top-left + Qt.point(child.width + 2, -2), // top-right + Qt.point(-2, child.height + 2), // bottom-left + Qt.point(child.width + 2, child.height + 2), // bottom-right + ] + + for (var j = 0; j < points.length; ++j) { + control.currentIndex = -1 + compare(control.currentIndex, -1) + + var point = points[j] + var pos = control.mapFromItem(child, x, y) + if (data.touch) + touch.press(0, control, pos.x, pos.y).commit().release(0, control, pos.x, pos.y).commit() + else + mouseClick(control, pos.x, pos.y, Qt.LeftButton) + compare(control.currentIndex, i) + } + } + } + + function test_mouseArea_data() { + return [ + { tag: "interactive", interactive: true }, + { tag: "non-interactive", interactive: false } + ] + } + + // QTBUG-61785 + function test_mouseArea(data) { + var ma = createTemporaryObject(mouseArea, testCase, {width: testCase.width, height: testCase.height}) + verify(ma) + + var control = pageIndicator.createObject(ma, {count: 5, interactive: data.interactive, width: testCase.width, height: testCase.height}) + verify(control) + + compare(control.interactive, data.interactive) + + mousePress(control) + compare(ma.pressed, !data.interactive) + + mouseRelease(control) + verify(!ma.pressed) + + var touch = touchEvent(control) + touch.press(0, control).commit() + compare(ma.pressed, !data.interactive) + + touch.release(0, control).commit() + verify(!ma.pressed) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_pane.qml b/tests/auto/quickcontrols2/controls/data/tst_pane.qml new file mode 100644 index 00000000000..d44d7424a68 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_pane.qml @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "Pane" + + Component { + id: pane + Pane { } + } + + Component { + id: oneChildPane + Pane { + Item { + implicitWidth: 100 + implicitHeight: 30 + } + } + } + + Component { + id: twoChildrenPane + Pane { + Item { + implicitWidth: 100 + implicitHeight: 30 + } + Item { + implicitWidth: 200 + implicitHeight: 60 + } + } + } + + Component { + id: contentPane + Pane { + contentItem: Item { + implicitWidth: 100 + implicitHeight: 30 + } + } + } + + Component { + id: pressPane + MouseArea { + width: 200 + height: 200 + property int pressCount + onPressed: ++pressCount + Pane { + anchors.fill: parent + } + } + } + + function test_empty() { + var control = createTemporaryObject(pane, testCase) + verify(control) + + verify(control.contentItem) + compare(control.contentWidth, 0) + compare(control.contentHeight, 0) + compare(control.implicitContentWidth, 0) + compare(control.implicitContentHeight, 0) + } + + function test_oneChild() { + var control = createTemporaryObject(oneChildPane, testCase) + verify(control) + + compare(control.contentWidth, 100) + compare(control.contentHeight, 30) + compare(control.implicitContentWidth, 100) + compare(control.implicitContentHeight, 30) + verify(control.implicitWidth > 100) + verify(control.implicitHeight > 30) + + compare(control.contentChildren.length, 1) + control.contentChildren[0].implicitWidth = 200 + control.contentChildren[0].implicitHeight = 40 + + compare(control.contentWidth, 200) + compare(control.contentHeight, 40) + compare(control.implicitContentWidth, 200) + compare(control.implicitContentHeight, 40) + verify(control.implicitWidth > 200) + verify(control.implicitHeight > 40) + } + + function test_twoChildren() { + var control = createTemporaryObject(twoChildrenPane, testCase) + verify(control) + + compare(control.contentWidth, 0) + compare(control.contentHeight, 0) + compare(control.implicitContentWidth, 0) + compare(control.implicitContentHeight, 0) + verify(control.implicitWidth > 0) + verify(control.implicitHeight > 0) + } + + function test_contentItem() { + var control = createTemporaryObject(contentPane, testCase) + verify(control) + + compare(control.contentWidth, 100) + compare(control.contentHeight, 30) + compare(control.implicitContentWidth, 100) + compare(control.implicitContentHeight, 30) + verify(control.implicitWidth > 100) + verify(control.implicitHeight > 30) + } + + function test_implicitContentItem() { + var control = createTemporaryObject(pane, testCase, {width: 100, height: 100}) + verify(control) + + compare(control.width, 100) + compare(control.height, 100) + compare(control.contentItem.width, control.availableWidth) + compare(control.contentItem.height, control.availableHeight) + } + + function test_press() { + var control = createTemporaryObject(pressPane, testCase) + verify(control) + + compare(control.pressCount, 0) + mouseClick(control) + compare(control.pressCount, 0) + + control.children[0].enabled = false + mouseClick(control) + compare(control.pressCount, 1) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_popup.qml b/tests/auto/quickcontrols2/controls/data/tst_popup.qml new file mode 100644 index 00000000000..acb550fdd45 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_popup.qml @@ -0,0 +1,1486 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls +import QtQuick.Templates as T + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "Popup" + + ApplicationWindow { + id: applicationWindow + width: 480 + height: 360 + } + + Component { + id: popupTemplate + T.Popup { } + } + + Component { + id: popupControl + Popup { } + } + + Component { + id: rect + Rectangle { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_padding() { + var control = createTemporaryObject(popupTemplate, testCase) + verify(control) + + var paddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "paddingChanged"}) + verify(paddingSpy.valid) + + var topPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "topPaddingChanged"}) + verify(topPaddingSpy.valid) + + var leftPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "leftPaddingChanged"}) + verify(leftPaddingSpy.valid) + + var rightPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "rightPaddingChanged"}) + verify(rightPaddingSpy.valid) + + var bottomPaddingSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "bottomPaddingChanged"}) + verify(bottomPaddingSpy.valid) + + var paddingChanges = 0 + var topPaddingChanges = 0 + var leftPaddingChanges = 0 + var rightPaddingChanges = 0 + var bottomPaddingChanges = 0 + + compare(control.padding, 0) + compare(control.topPadding, 0) + compare(control.leftPadding, 0) + compare(control.rightPadding, 0) + compare(control.bottomPadding, 0) + compare(control.availableWidth, 0) + compare(control.availableHeight, 0) + + control.width = 100 + control.height = 100 + + control.padding = 10 + compare(control.padding, 10) + compare(control.topPadding, 10) + compare(control.leftPadding, 10) + compare(control.rightPadding, 10) + compare(control.bottomPadding, 10) + compare(paddingSpy.count, ++paddingChanges) + compare(topPaddingSpy.count, ++topPaddingChanges) + compare(leftPaddingSpy.count, ++leftPaddingChanges) + compare(rightPaddingSpy.count, ++rightPaddingChanges) + compare(bottomPaddingSpy.count, ++bottomPaddingChanges) + + control.topPadding = 20 + compare(control.padding, 10) + compare(control.topPadding, 20) + compare(control.leftPadding, 10) + compare(control.rightPadding, 10) + compare(control.bottomPadding, 10) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, ++topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + + control.leftPadding = 30 + compare(control.padding, 10) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 10) + compare(control.bottomPadding, 10) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, ++leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + + control.rightPadding = 40 + compare(control.padding, 10) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 40) + compare(control.bottomPadding, 10) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, ++rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + + control.bottomPadding = 50 + compare(control.padding, 10) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 40) + compare(control.bottomPadding, 50) + compare(paddingSpy.count, paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, ++bottomPaddingChanges) + + control.padding = 60 + compare(control.padding, 60) + compare(control.topPadding, 20) + compare(control.leftPadding, 30) + compare(control.rightPadding, 40) + compare(control.bottomPadding, 50) + compare(paddingSpy.count, ++paddingChanges) + compare(topPaddingSpy.count, topPaddingChanges) + compare(leftPaddingSpy.count, leftPaddingChanges) + compare(rightPaddingSpy.count, rightPaddingChanges) + compare(bottomPaddingSpy.count, bottomPaddingChanges) + } + + function test_availableSize() { + var control = createTemporaryObject(popupTemplate, testCase) + verify(control) + + var availableWidthSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "availableWidthChanged"}) + verify(availableWidthSpy.valid) + + var availableHeightSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "availableHeightChanged"}) + verify(availableHeightSpy.valid) + + var availableWidthChanges = 0 + var availableHeightChanges = 0 + + control.width = 100 + compare(control.availableWidth, 100) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.height = 100 + compare(control.availableHeight, 100) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + + control.padding = 10 + compare(control.availableWidth, 80) + compare(control.availableHeight, 80) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + + control.topPadding = 20 + compare(control.availableWidth, 80) + compare(control.availableHeight, 70) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + + control.leftPadding = 30 + compare(control.availableWidth, 60) + compare(control.availableHeight, 70) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.rightPadding = 40 + compare(control.availableWidth, 30) + compare(control.availableHeight, 70) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.bottomPadding = 50 + compare(control.availableWidth, 30) + compare(control.availableHeight, 30) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + + control.padding = 60 + compare(control.availableWidth, 30) + compare(control.availableHeight, 30) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.width = 0 + compare(control.availableWidth, 0) + compare(availableWidthSpy.count, ++availableWidthChanges) + compare(availableHeightSpy.count, availableHeightChanges) + + control.height = 0 + compare(control.availableHeight, 0) + compare(availableWidthSpy.count, availableWidthChanges) + compare(availableHeightSpy.count, ++availableHeightChanges) + } + + function test_position() { + var control = createTemporaryObject(popupControl, testCase, {visible: true, leftMargin: 10, topMargin: 20, width: 100, height: 100}) + verify(control) + verify(control.visible) + + var xSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "xChanged"}) + verify(xSpy.valid) + + var ySpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "yChanged"}) + verify(ySpy.valid) + + // moving outside margins does not trigger change notifiers + control.x = -100 + compare(control.x, 10) + compare(control.y, 20) + compare(xSpy.count, 0) + compare(ySpy.count, 0) + + control.y = -200 + compare(control.x, 10) + compare(control.y, 20) + compare(xSpy.count, 0) + compare(ySpy.count, 0) + + // moving within margins triggers change notifiers + control.x = 30 + compare(control.x, 30) + compare(control.y, 20) + compare(xSpy.count, 1) + compare(ySpy.count, 0) + + control.y = 40 + compare(control.x, 30) + compare(control.y, 40) + compare(xSpy.count, 1) + compare(ySpy.count, 1) + + // re-parent and reset the position + control.parent = createTemporaryObject(rect, testCase, {color: "red", width: 100, height: 100}) + control.x = 0 + control.y = 0 + compare(xSpy.count, 2) + compare(ySpy.count, 2) + + // moving parent outside margins triggers change notifiers + control.parent.x = -50 + compare(control.x, 50 + control.leftMargin) + compare(xSpy.count, 3) + compare(ySpy.count, 2) + + control.parent.y = -60 + compare(control.y, 60 + control.topMargin) + compare(xSpy.count, 3) + compare(ySpy.count, 3) + } + + function test_resetSize() { + var control = createTemporaryObject(popupControl, testCase, {visible: true, margins: 0}) + verify(control) + + control.scale = 1.0 + control.width = control.implicitWidth = testCase.width + 10 + control.height = control.implicitHeight = testCase.height + 10 + + compare(control.width, testCase.width + 10) + compare(control.height, testCase.height + 10) + + control.width = undefined + control.height = undefined + compare(control.width, testCase.width) + compare(control.height, testCase.height) + } + + function test_negativeMargins() { + var control = createTemporaryObject(popupControl, testCase, {implicitWidth: testCase.width, implicitHeight: testCase.height}) + verify(control) + + control.open() + verify(control.visible) + + compare(control.x, 0) + compare(control.y, 0) + + compare(control.margins, -1) + compare(control.topMargin, -1) + compare(control.leftMargin, -1) + compare(control.rightMargin, -1) + compare(control.bottomMargin, -1) + + control.x = -10 + control.y = -10 + compare(control.x, 0) + compare(control.y, 0) + } + + function test_margins() { + var control = createTemporaryObject(popupTemplate, testCase, {width: 100, height: 100}) + verify(control) + + control.open() + verify(control.visible) + + control.margins = 10 + compare(control.margins, 10) + compare(control.topMargin, 10) + compare(control.leftMargin, 10) + compare(control.rightMargin, 10) + compare(control.bottomMargin, 10) + compare(control.contentItem.parent.x, 10) + compare(control.contentItem.parent.y, 10) + + control.topMargin = 20 + compare(control.margins, 10) + compare(control.topMargin, 20) + compare(control.leftMargin, 10) + compare(control.rightMargin, 10) + compare(control.bottomMargin, 10) + compare(control.contentItem.parent.x, 10) + compare(control.contentItem.parent.y, 20) + + control.leftMargin = 20 + compare(control.margins, 10) + compare(control.topMargin, 20) + compare(control.leftMargin, 20) + compare(control.rightMargin, 10) + compare(control.bottomMargin, 10) + compare(control.contentItem.parent.x, 20) + compare(control.contentItem.parent.y, 20) + + control.x = testCase.width + control.y = testCase.height + compare(control.contentItem.parent.x, testCase.width - control.width - 10) + compare(control.contentItem.parent.y, testCase.height - control.height - 10) + + control.rightMargin = 20 + compare(control.margins, 10) + compare(control.topMargin, 20) + compare(control.leftMargin, 20) + compare(control.rightMargin, 20) + compare(control.bottomMargin, 10) + compare(control.contentItem.parent.x, testCase.width - control.width - 20) + compare(control.contentItem.parent.y, testCase.height - control.height - 10) + + control.bottomMargin = 20 + compare(control.margins, 10) + compare(control.topMargin, 20) + compare(control.leftMargin, 20) + compare(control.rightMargin, 20) + compare(control.bottomMargin, 20) + compare(control.contentItem.parent.x, testCase.width - control.width - 20) + compare(control.contentItem.parent.y, testCase.height - control.height - 20) + + control.margins = undefined + compare(control.margins, -1) + + control.bottomMargin = undefined + compare(control.bottomMargin, -1) + compare(control.contentItem.parent.x, testCase.width - control.width - 20) + compare(control.contentItem.parent.y, testCase.height) + + control.rightMargin = undefined + compare(control.rightMargin, -1) + compare(control.contentItem.parent.x, testCase.width) + compare(control.contentItem.parent.y, testCase.height) + + control.x = -testCase.width + control.y = -testCase.height + compare(control.contentItem.parent.x, 20) + compare(control.contentItem.parent.y, 20) + + control.topMargin = undefined + compare(control.topMargin, -1) + compare(control.contentItem.parent.x, 20) + compare(control.contentItem.parent.y, -testCase.height) + + control.leftMargin = undefined + compare(control.leftMargin, -1) + compare(control.contentItem.parent.x, -testCase.width) + compare(control.contentItem.parent.y, -testCase.height) + } + + function test_background() { + var control = createTemporaryObject(popupTemplate, testCase) + verify(control) + + control.background = rect.createObject(testCase) + + // background has no x or width set, so its width follows control's width + control.width = 320 + compare(control.background.width, control.width) + + // background has no y or height set, so its height follows control's height + compare(control.background.height, control.height) + control.height = 240 + + // has width => width does not follow + control.background.width /= 2 + control.width += 20 + verify(control.background.width !== control.width) + + // reset width => width follows again + control.background.width = undefined + control.width += 20 + compare(control.background.width, control.width) + + // has x => width does not follow + control.background.x = 10 + control.width += 20 + verify(control.background.width !== control.width) + + // has height => height does not follow + control.background.height /= 2 + control.height -= 20 + verify(control.background.height !== control.height) + + // reset height => height follows again + control.background.height = undefined + control.height -= 20 + compare(control.background.height, control.height) + + // has y => height does not follow + control.background.y = 10 + control.height -= 20 + verify(control.background.height !== control.height) + } + + function getChild(control, objname, idx) { + var index = idx + for (var i = index+1; i < control.children.length; i++) + { + if (control.children[i].objectName === objname) { + index = i + break + } + } + return index + } + + Component { + id: component + ApplicationWindow { + id: _window + width: 400 + height: 400 + visible: true + font.pixelSize: 40 + property alias pane: _pane + property alias popup: _popup + property SignalSpy fontspy: SignalSpy { target: _window; signalName: "fontChanged" } + Pane { + id: _pane + property alias button: _button + font.pixelSize: 30 + property SignalSpy fontspy: SignalSpy { target: _pane; signalName: "fontChanged" } + Column { + Button { + id: _button + text: "Button" + font.pixelSize: 20 + property SignalSpy fontspy: SignalSpy { target: _button; signalName: "fontChanged" } + Popup { + id: _popup + property alias button: _button2 + property alias listview: _listview + y: _button.height + implicitHeight: Math.min(396, _listview.contentHeight) + property SignalSpy fontspy: SignalSpy { target: _popup; signalName: "fontChanged" } + contentItem: Column { + Button { + id: _button2 + text: "Button" + property SignalSpy fontspy: SignalSpy { target: _button2; signalName: "fontChanged" } + } + ListView { + id: _listview + height: _button.height * 20 + model: 2 + delegate: Button { + id: _button3 + objectName: "delegate" + width: _button.width + height: _button.height + text: "N: " + index + checkable: true + autoExclusive: true + property SignalSpy fontspy: SignalSpy { target: _button3; signalName: "fontChanged" } + } + } + } + } + } + } + } + } + } + + function test_font() { // QTBUG_50984, QTBUG-51696 + var window = createTemporaryObject(component, testCase) + verify(window) + + compare(window.font.pixelSize, 40) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.button.font.pixelSize, 20) + compare(window.popup.font.pixelSize, 40) + compare(window.popup.button.font.pixelSize, 40) + + var idx1 = getChild(window.popup.listview.contentItem, "delegate", -1) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 40) + var idx2 = getChild(window.popup.listview.contentItem, "delegate", idx1) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 40) + + window.pane.button.font.pixelSize = 30 + compare(window.font.pixelSize, 40) + compare(window.fontspy.count, 0) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.fontspy.count, 0) + compare(window.pane.button.font.pixelSize, 30) + compare(window.pane.button.fontspy.count, 1) + compare(window.popup.font.pixelSize, 40) + compare(window.popup.fontspy.count, 0) + compare(window.popup.button.font.pixelSize, 40) + compare(window.popup.button.fontspy.count, 0) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 40) + compare(window.popup.listview.contentItem.children[idx1].fontspy.count, 0) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 40) + compare(window.popup.listview.contentItem.children[idx2].fontspy.count, 0) + + window.font.pixelSize = 50 + compare(window.font.pixelSize, 50) + compare(window.fontspy.count, 1) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.fontspy.count, 0) + compare(window.pane.button.font.pixelSize, 30) + compare(window.pane.button.fontspy.count, 1) + compare(window.popup.font.pixelSize, 50) + compare(window.popup.fontspy.count, 1) + compare(window.popup.button.font.pixelSize, 50) + compare(window.popup.button.fontspy.count, 1) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 50) + compare(window.popup.listview.contentItem.children[idx1].fontspy.count, 1) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 50) + compare(window.popup.listview.contentItem.children[idx2].fontspy.count, 1) + + window.popup.button.font.pixelSize = 10 + compare(window.font.pixelSize, 50) + compare(window.fontspy.count, 1) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.fontspy.count, 0) + compare(window.pane.button.font.pixelSize, 30) + compare(window.pane.button.fontspy.count, 1) + compare(window.popup.font.pixelSize, 50) + compare(window.popup.fontspy.count, 1) + compare(window.popup.button.font.pixelSize, 10) + compare(window.popup.button.fontspy.count, 2) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 50) + compare(window.popup.listview.contentItem.children[idx1].fontspy.count, 1) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 50) + compare(window.popup.listview.contentItem.children[idx2].fontspy.count, 1) + + window.popup.font.pixelSize = 60 + compare(window.font.pixelSize, 50) + compare(window.fontspy.count, 1) + compare(window.pane.font.pixelSize, 30) + compare(window.pane.fontspy.count, 0) + compare(window.pane.button.font.pixelSize, 30) + compare(window.pane.button.fontspy.count, 1) + compare(window.popup.font.pixelSize, 60) + compare(window.popup.fontspy.count, 2) + compare(window.popup.button.font.pixelSize, 10) + compare(window.popup.button.fontspy.count, 2) + compare(window.popup.listview.contentItem.children[idx1].font.pixelSize, 60) + compare(window.popup.listview.contentItem.children[idx1].fontspy.count, 2) + compare(window.popup.listview.contentItem.children[idx2].font.pixelSize, 60) + compare(window.popup.listview.contentItem.children[idx2].fontspy.count, 2) + } + + Component { + id: localeComponent + Pane { + property alias button: _button + property alias popup: _popup + locale: Qt.locale("en_US") + Column { + Button { + id: _button + text: "Button" + locale: Qt.locale("nb_NO") + Popup { + id: _popup + property alias button1: _button1 + property alias button2: _button2 + y: _button.height + locale: Qt.locale("fi_FI") + implicitHeight: Math.min(396, _column.contentHeight) + contentItem: Column { + id: _column + Button { + id: _button1 + text: "Button 1" + objectName: "1" + } + Button { + id: _button2 + text: "Button 2" + locale: Qt.locale("nb_NO") + objectName: "2" + } + } + } + } + } + } + } + + function test_locale() { // QTBUG_50984 + // test looking up natural locale from ancestors + var control = createTemporaryObject(localeComponent, applicationWindow.contentItem) + verify(control) + + compare(control.locale.name, "en_US") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "fi_FI") + compare(control.popup.button1.locale.name, "fi_FI") + compare(control.popup.button2.locale.name, "nb_NO") + + control.ApplicationWindow.window.locale = undefined + } + + Component { + id: localeChangeComponent + Pane { + id: _pane + property alias button: _button + property alias popup: _popup + property SignalSpy localespy: SignalSpy { + target: _pane + signalName: "localeChanged" + } + property SignalSpy mirrorspy: SignalSpy { + target: _pane + signalName: "mirroredChanged" + } + Column { + Button { + id: _button + text: "Button" + property SignalSpy localespy: SignalSpy { + target: _button + signalName: "localeChanged" + } + property SignalSpy mirrorspy: SignalSpy { + target: _button + signalName: "mirroredChanged" + } + Popup { + id: _popup + property alias button1: _button1 + property alias button2: _button2 + y: _button.height + implicitHeight: Math.min(396, _column.contentHeight) + property SignalSpy localespy: SignalSpy { + target: _popup + signalName: "localeChanged" + } + contentItem: Column { + id: _column + Button { + id: _button1 + text: "Button 1" + property SignalSpy localespy: SignalSpy { + target: _button1 + signalName: "localeChanged" + } + property SignalSpy mirrorspy: SignalSpy { + target: _button1 + signalName: "mirroredChanged" + } + } + Button { + id: _button2 + text: "Button 2" + property SignalSpy localespy: SignalSpy { + target: _button2 + signalName: "localeChanged" + } + property SignalSpy mirrorspy: SignalSpy { + target: _button2 + signalName: "mirroredChanged" + } + } + } + } + } + } + } + } + + function test_locale_changes() { // QTBUG_50984 + // test default locale and locale inheritance + var control = createTemporaryObject(localeChangeComponent, applicationWindow.contentItem) + verify(control) + + var defaultLocale = Qt.locale() + compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) + compare(control.locale.name, defaultLocale.name) + compare(control.button.locale.name, defaultLocale.name) + compare(control.popup.locale.name, defaultLocale.name) + compare(control.popup.button1.locale.name, defaultLocale.name) + compare(control.popup.button2.locale.name, defaultLocale.name) + + control.ApplicationWindow.window.locale = Qt.locale("nb_NO") + compare(control.ApplicationWindow.window.locale.name, "nb_NO") + compare(control.locale.name, "nb_NO") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "nb_NO") + compare(control.popup.button1.locale.name, "nb_NO") + compare(control.popup.button2.locale.name, "nb_NO") + compare(control.localespy.count, 1) + compare(control.button.localespy.count, 1) + compare(control.popup.localespy.count, 1) + compare(control.popup.button1.localespy.count, 1) + compare(control.popup.button2.localespy.count, 1) + + control.ApplicationWindow.window.locale = undefined + compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) + compare(control.locale.name, defaultLocale.name) + compare(control.button.locale.name, defaultLocale.name) + compare(control.popup.locale.name, defaultLocale.name) + compare(control.popup.button1.locale.name, defaultLocale.name) + compare(control.popup.button2.locale.name, defaultLocale.name) + compare(control.localespy.count, 2) + compare(control.button.localespy.count, 2) + compare(control.popup.localespy.count, 2) + compare(control.popup.button1.localespy.count, 2) + compare(control.popup.button2.localespy.count, 2) + + control.locale = Qt.locale("ar_EG") + compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "ar_EG") + compare(control.popup.locale.name, defaultLocale.name) + compare(control.popup.button1.locale.name, defaultLocale.name) + compare(control.popup.button2.locale.name, defaultLocale.name) + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 3) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 2) + compare(control.popup.button1.localespy.count, 2) + compare(control.popup.button2.localespy.count, 2) + + control.ApplicationWindow.window.locale = Qt.locale("ar_EG") + compare(control.ApplicationWindow.window.locale.name, "ar_EG") + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "ar_EG") + compare(control.popup.locale.name, "ar_EG") + compare(control.popup.button1.locale.name, "ar_EG") + compare(control.popup.button2.locale.name, "ar_EG") + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 3) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 3) + compare(control.popup.button1.localespy.count, 3) + compare(control.popup.button1.mirrorspy.count, 0) + compare(control.popup.button2.localespy.count, 3) + compare(control.popup.button2.mirrorspy.count, 0) + + control.button.locale = Qt.locale("nb_NO") + compare(control.ApplicationWindow.window.locale.name, "ar_EG") + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "ar_EG") + compare(control.popup.button1.locale.name, "ar_EG") + compare(control.popup.button2.locale.name, "ar_EG") + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 3) + compare(control.popup.button1.localespy.count, 3) + compare(control.popup.button2.localespy.count, 3) + + control.locale = undefined + compare(control.ApplicationWindow.window.locale.name, "ar_EG") + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "ar_EG") + compare(control.popup.button1.locale.name, "ar_EG") + compare(control.popup.button2.locale.name, "ar_EG") + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 3) + compare(control.popup.button1.localespy.count, 3) + compare(control.popup.button2.localespy.count, 3) + + control.popup.button1.locale = Qt.locale("nb_NO") + compare(control.ApplicationWindow.window.locale.name, "ar_EG") + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "ar_EG") + compare(control.popup.button1.locale.name, "nb_NO") + compare(control.popup.button2.locale.name, "ar_EG") + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 3) + compare(control.popup.button1.localespy.count, 4) + compare(control.popup.button1.mirrorspy.count, 0) + compare(control.popup.button2.localespy.count, 3) + compare(control.popup.button2.mirrorspy.count, 0) + + control.popup.locale = Qt.locale("fi_FI") + compare(control.ApplicationWindow.window.locale.name, "ar_EG") + compare(control.locale.name, "ar_EG") + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "fi_FI") + compare(control.popup.button1.locale.name, "nb_NO") + compare(control.popup.button2.locale.name, "fi_FI") + compare(control.localespy.count, 3) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 4) + compare(control.popup.button1.localespy.count, 4) + compare(control.popup.button1.mirrorspy.count, 0) + compare(control.popup.button2.localespy.count, 4) + compare(control.popup.button2.mirrorspy.count, 0) + + control.ApplicationWindow.window.locale = undefined + compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) + compare(control.locale.name, defaultLocale.name) + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, "fi_FI") + compare(control.popup.button1.locale.name, "nb_NO") + compare(control.popup.button2.locale.name, "fi_FI") + compare(control.localespy.count, 4) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 4) + compare(control.popup.button1.localespy.count, 4) + compare(control.popup.button1.mirrorspy.count, 0) + compare(control.popup.button2.localespy.count, 4) + compare(control.popup.button2.mirrorspy.count, 0) + + control.popup.locale = undefined + compare(control.ApplicationWindow.window.locale.name, defaultLocale.name) + compare(control.locale.name, defaultLocale.name) + compare(control.button.locale.name, "nb_NO") + compare(control.popup.locale.name, defaultLocale.name) + compare(control.popup.button1.locale.name, "nb_NO") + compare(control.popup.button2.locale.name, defaultLocale.name) + compare(control.localespy.count, 4) + compare(control.mirrorspy.count, 0) + compare(control.button.localespy.count, 4) + compare(control.button.mirrorspy.count, 0) + compare(control.popup.localespy.count, 5) + compare(control.popup.button1.localespy.count, 4) + compare(control.popup.button1.mirrorspy.count, 0) + compare(control.popup.button2.localespy.count, 5) + compare(control.popup.button2.mirrorspy.count, 0) + } + + function test_size() { + var control = createTemporaryObject(popupControl, testCase) + verify(control) + + var openedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "opened"}) + verify(openedSpy.valid) + + control.open() + openedSpy.wait() + compare(openedSpy.count, 1) + verify(control.visible) + + // remove the background so that it won't affect the implicit size of the popup, + // so the implicit sizes tested below are entirely based on the content size + control.background = null + + // implicit size of the content + control.contentItem.implicitWidth = 10 + compare(control.implicitWidth, 10 + control.leftPadding + control.rightPadding) + compare(control.width, control.implicitWidth) + compare(control.contentItem.width, control.availableWidth) + + control.contentItem.implicitHeight = 20 + compare(control.implicitHeight, 20 + control.topPadding + control.bottomPadding) + compare(control.height, control.implicitHeight) + compare(control.contentItem.height, control.availableHeight) + + // implicit size of the popup + control.implicitWidth = 30 + compare(control.implicitWidth, 30) + compare(control.width, 30) + compare(control.contentItem.width, control.availableWidth) + + control.implicitHeight = 40 + compare(control.implicitHeight, 40) + compare(control.height, 40) + compare(control.contentItem.height, control.availableHeight) + + // set explicit size + control.width = 50 + compare(control.implicitWidth, 30) + compare(control.width, 50) + compare(control.contentItem.width, control.availableWidth) + + control.height = 60 + compare(control.implicitHeight, 40) + compare(control.height, 60) + compare(control.contentItem.height, control.availableHeight) + + // reset explicit size + control.width = undefined + compare(control.implicitWidth, 30) + compare(control.width, 30) + compare(control.contentItem.width, control.availableWidth) + + control.height = undefined + compare(control.implicitHeight, 40) + compare(control.height, 40) + compare(control.contentItem.height, control.availableHeight) + } + + function test_visible() { + var control = createTemporaryObject(popupTemplate, testCase, {visible: true}) + verify(control) + + // QTBUG-51989 + tryCompare(control, "visible", true) + + // QTBUG-55347 + control.parent = null + verify(!control.visible) + } + + Component { + id: overlayTest + ApplicationWindow { + property alias firstDrawer: firstDrawer + property alias secondDrawer: secondDrawer + property alias modalPopup: modalPopup + property alias modelessPopup: modelessPopup + property alias plainPopup: plainPopup + property alias modalPopupWithoutDim: modalPopupWithoutDim + visible: true + Drawer { + z: 0 + id: firstDrawer + } + Drawer { + z: 1 + id: secondDrawer + } + Popup { + id: modalPopup + z: 2 + modal: true + exit: Transition { PauseAnimation { duration: 200 } } + } + Popup { + id: modelessPopup + z: 3 + dim: true + exit: Transition { PauseAnimation { duration: 200 } } + } + Popup { + id: plainPopup + z: 4 + enter: Transition { PauseAnimation { duration: 200 } } + exit: Transition { PauseAnimation { duration: 200 } } + } + Popup { + id: modalPopupWithoutDim + z: 5 + dim: false + modal: true + exit: Transition { PauseAnimation { duration: 200 } } + } + } + } + + function indexOf(array, item) { + for (var idx = 0; idx < array.length; ++idx) { + if (item === array[idx]) + return idx; + } + return -1 + } + + function findOverlay(window, popup) { + var item = popup.contentItem.parent + var idx = indexOf(window.Overlay.overlay.children, item) + return window.Overlay.overlay.children[idx - 1] + } + + function test_overlay() { + var window = createTemporaryObject(overlayTest, testCase) + verify(window) + + window.requestActivate() + tryCompare(window, "active", true) + + compare(window.Overlay.overlay.children.length, 0) + + var firstOverlay = findOverlay(window, window.firstDrawer) + verify(!firstOverlay) + window.firstDrawer.open() + compare(window.Overlay.overlay.children.length, 2) // 1 drawer + 1 overlay + firstOverlay = findOverlay(window, window.firstDrawer) + verify(firstOverlay) + compare(firstOverlay.z, window.firstDrawer.z) + compare(indexOf(window.Overlay.overlay.children, firstOverlay), + indexOf(window.Overlay.overlay.children, window.firstDrawer.contentItem.parent) - 1) + tryCompare(firstOverlay, "opacity", 1.0) + + var secondOverlay = findOverlay(window, window.secondDrawer) + verify(!secondOverlay) + window.secondDrawer.open() + compare(window.Overlay.overlay.children.length, 4) // 2 drawers + 2 overlays + secondOverlay = findOverlay(window, window.secondDrawer) + verify(secondOverlay) + compare(secondOverlay.z, window.secondDrawer.z) + compare(indexOf(window.Overlay.overlay.children, secondOverlay), + indexOf(window.Overlay.overlay.children, window.secondDrawer.contentItem.parent) - 1) + tryCompare(secondOverlay, "opacity", 1.0) + + window.firstDrawer.close() + tryCompare(window.firstDrawer, "visible", false) + firstOverlay = findOverlay(window, window.firstDrawer) + verify(!firstOverlay) + compare(window.Overlay.overlay.children.length, 2) // 1 drawer + 1 overlay + + window.secondDrawer.close() + tryCompare(window.secondDrawer, "visible", false) + secondOverlay = findOverlay(window, window.secondDrawer) + verify(!secondOverlay) + compare(window.Overlay.overlay.children.length, 0) + + var modalOverlay = findOverlay(window, window.modalPopup) + verify(!modalOverlay) + window.modalPopup.open() + modalOverlay = findOverlay(window, window.modalPopup) + verify(modalOverlay) + compare(modalOverlay.z, window.modalPopup.z) + compare(window.modalPopup.visible, true) + tryCompare(modalOverlay, "opacity", 1.0) + compare(window.Overlay.overlay.children.length, 2) // 1 popup + 1 overlay + + var modelessOverlay = findOverlay(window, window.modelessPopup) + verify(!modelessOverlay) + window.modelessPopup.open() + modelessOverlay = findOverlay(window, window.modelessPopup) + verify(modelessOverlay) + compare(modelessOverlay.z, window.modelessPopup.z) + compare(window.modelessPopup.visible, true) + tryCompare(modelessOverlay, "opacity", 1.0) + compare(window.Overlay.overlay.children.length, 4) // 2 popups + 2 overlays + + window.modelessPopup.close() + tryCompare(window.modelessPopup, "visible", false) + modelessOverlay = findOverlay(window, window.modelessPopup) + verify(!modelessOverlay) + compare(window.Overlay.overlay.children.length, 2) // 1 popup + 1 overlay + + compare(window.modalPopup.visible, true) + compare(modalOverlay.opacity, 1.0) + + window.modalPopup.close() + tryCompare(window.modalPopup, "visible", false) + modalOverlay = findOverlay(window, window.modalPopup) + verify(!modalOverlay) + compare(window.Overlay.overlay.children.length, 0) + + window.plainPopup.open() + tryCompare(window.plainPopup, "visible", true) + compare(window.Overlay.overlay.children.length, 1) // only popup added, no overlays involved + + window.plainPopup.modal = true + compare(window.Overlay.overlay.children.length, 2) // overlay added + + window.plainPopup.close() + tryCompare(window.plainPopup, "visible", false) + compare(window.Overlay.overlay.children.length, 0) // popup + overlay removed + + window.modalPopupWithoutDim.open() + tryCompare(window.modalPopupWithoutDim, "visible", true) + compare(window.Overlay.overlay.children.length, 1) // only popup added, no overlays involved + + window.modalPopupWithoutDim.dim = true + compare(window.Overlay.overlay.children.length, 2) // overlay added + + window.modalPopupWithoutDim.close() + tryCompare(window.modalPopupWithoutDim, "visible", false) + compare(window.Overlay.overlay.children.length, 0) // popup + overlay removed + } + + function test_attached_applicationwindow() { + var control = createTemporaryObject(popupControl, applicationWindow.contentItem) + verify(control) + + var child = rect.createObject(control.contentItem) + + compare(control.ApplicationWindow.window, applicationWindow) + compare(control.contentItem.ApplicationWindow.window, applicationWindow) + compare(child.ApplicationWindow.window, applicationWindow) + + control.parent = null + compare(control.ApplicationWindow.window, null) + compare(control.contentItem.ApplicationWindow.window, null) + compare(child.ApplicationWindow.window, null) + } + + Component { + id: pausePopup + Popup { + enter: Transition { PauseAnimation { duration: 200 } } + exit: Transition { PauseAnimation { duration: 200 } } + } + } + + function test_openedClosed() { + var control = createTemporaryObject(pausePopup, testCase) + verify(control) + + var openedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "opened"}) + verify(openedSpy.valid) + var closedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "closed"}) + verify(closedSpy.valid) + var openedChangeSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "openedChanged"}) + verify(openedChangeSpy.valid) + + control.open() + compare(control.visible, true) + compare(control.opened, false) + compare(openedChangeSpy.count, 0) + compare(openedSpy.count, 0) + tryCompare(openedSpy, "count", 1) + compare(control.opened, true) + compare(openedChangeSpy.count, 1) + compare(closedSpy.count, 0) + + control.close() + compare(control.visible, true) + compare(control.opened, false) + compare(openedChangeSpy.count, 2) + compare(openedSpy.count, 1) + compare(closedSpy.count, 0) + tryCompare(closedSpy, "count", 1) + compare(control.opened, false) + compare(openedChangeSpy.count, 2) + compare(control.visible, false) + } + + Component { + id: xyBindingLoop + ApplicationWindow { + id: window + width: 360 + height: 360 + visible: true + property alias popup: popup + + Popup { + id: popup + visible: true + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + Label { + text: "Content" + anchors.fill: parent + } + } + } + } + + function test_xyBindingLoop() { + var window = createTemporaryObject(xyBindingLoop, testCase) + var control = window.popup + waitForRendering(control.contentItem) + compare(control.x, (control.parent.width - control.width) / 2) + compare(control.y, (control.parent.height - control.height) / 2) + } + + function test_windowParent() { + var control = createTemporaryObject(popupControl, applicationWindow, {width: 100, height: 100}) + verify(control) + + control.open() + verify(control.visible) + } + + function test_deferredBackgroundSize() { + var control = createTemporaryObject(popupControl, testCase, {width: 200, height: 100}) + verify(control) + + compare(control.background.width, 200 + (control.background.leftInset || 0) + (control.background.rightInset || 0)) + compare(control.background.height, 100 + (control.background.topInset || 0) + (control.background.bottomInset || 0)) + } + + function test_anchors() { + var control = createTemporaryObject(popupControl, applicationWindow.contentItem.Overlay.overlay, + { visible: true, width: 100, height: 100 }) + verify(control) + verify(control.visible) + // If there is a transition then make sure it is finished + if (control.enter !== null) + tryCompare(control.enter, "running", false) + compare(control.parent, control.Overlay.overlay) + compare(control.x, 0) + compare(control.y, 0) + + var overlay = control.Overlay.overlay + verify(overlay) + + var centerInSpy = createTemporaryObject(signalSpy, testCase, { target: control.anchors, signalName: "centerInChanged" }) + verify(centerInSpy.valid) + + applicationWindow.visible = true + verify(waitForRendering(applicationWindow.contentItem)) + verify(overlay.width > 0) + verify(overlay.height > 0) + + // Center the popup in the window via the overlay. + control.anchors.centerIn = Qt.binding(function() { return control.parent; }) + compare(centerInSpy.count, 1) + compare(control.x, (overlay.width - (control.width * control.scale)) / 2) + compare(control.y, (overlay.height - (control.width * control.scale)) / 2) + + // Ensure that it warns when trying to set it to an item that's not its parent. + var anotherItem = createTemporaryObject(rect, applicationWindow.contentItem, { x: 100, y: 100, width: 50, height: 50 }) + verify(anotherItem) + + ignoreWarning(Qt.resolvedUrl("tst_popup.qml") + ":77:9: QML Popup: Popup can only be centered within its immediate parent or Overlay.overlay") + control.anchors.centerIn = anotherItem + // The property will change, because we can't be sure that the parent + // in QQuickPopupAnchors::setCenterIn() is the final parent, as some reparenting can happen. + // We still expect the warning from QQuickPopupPositioner::reposition() though. + compare(centerInSpy.count, 2) + compare(control.anchors.centerIn, anotherItem) + + // The binding to the popup's parent was broken above, so restore it. + control.anchors.centerIn = Qt.binding(function() { return control.parent; }) + compare(centerInSpy.count, 3) + + // Change the popup's parent and ensure that it's anchored accordingly. + control.parent = Qt.binding(function() { return anotherItem; }) + compare(control.parent, anotherItem) + compare(control.anchors.centerIn, anotherItem) + compare(centerInSpy.count, 4) + compare(control.x, (anotherItem.width - (control.width * control.scale)) / 2) + compare(control.y, (anotherItem.height - (control.height * control.scale)) / 2) + + // Check that anchors.centerIn beats x and y coordinates as it does in QQuickItem. + control.x = 33; + control.y = 44; + compare(control.x, (anotherItem.width - (control.width * control.scale)) / 2) + compare(control.y, (anotherItem.height - (control.height * control.scale)) / 2) + + // Check that the popup's x and y coordinates are restored when it's no longer centered. + control.anchors.centerIn = undefined + compare(centerInSpy.count, 5) + compare(control.x, 33) + compare(control.y, 44) + + // Test centering in the overlay while having a different parent (anotherItem). + control.anchors.centerIn = overlay + compare(centerInSpy.count, 6) + compare(control.x, (overlay.width - (control.width * control.scale)) / 2) + compare(control.y, (overlay.height - (control.height * control.scale)) / 2) + + // TODO: do this properly by creating a component or something + applicationWindow.visible = false + } + + Component { + id: shortcutWindowComponent + ApplicationWindow { + id: window + width: 360 + height: 360 + visible: true + + property alias popup: popup + property alias shortcut: shortcut + + Popup { + id: popup + + Shortcut { + id: shortcut + sequence: "A" + onActivated: popup.visible = !popup.visible + } + } + } + } + + function test_shortcut() { + // Tests that a Shortcut with Qt.WindowShortcut context + // that is declared within a Popup is activated. + var window = createTemporaryObject(shortcutWindowComponent, testCase) + var control = window.popup + + window.requestActivate() + tryCompare(window, "active", true) + + var shortcutActivatedSpy = createTemporaryObject(signalSpy, testCase, + { target: window.shortcut, signalName: "activated"} ) + verify(shortcutActivatedSpy.valid) + + waitForRendering(window.contentItem) + keyClick(Qt.Key_A) + compare(shortcutActivatedSpy.count, 1) + tryCompare(control, "visible", true) + + keyClick(Qt.Key_A) + compare(shortcutActivatedSpy.count, 2) + tryCompare(control, "visible", false) + } + + Component { + id: mousePropagationComponent + ApplicationWindow { + id: window + width: 360 + height: 360 + visible: true + + property alias popup: popup + property alias popupTitle: popupTitle + property alias popupContent: popupContent + property bool gotMouseEvent: false + + MouseArea { + id: windowMouseArea + enabled: true + anchors.fill: parent + onPressed: gotMouseEvent = true + } + + + Popup { + id: popup + width: 200 + height: 200 + + background: Rectangle { + id: popupContent + color: "#505050" + Rectangle { + id: popupTitle + width: parent.width + height: 30 + color: "blue" + + property point pressedPosition: Qt.point(0, 0) + + MouseArea { + enabled: true + propagateComposedEvents: true + anchors.fill: parent + onPressed: (mouse) => { + popupTitle.pressedPosition = Qt.point(mouse.x, mouse.y) + } + onPositionChanged: (mouse) => { + popup.x += mouse.x - popupTitle.pressedPosition.x + popup.y += mouse.y - popupTitle.pressedPosition.y + } + onReleased: (mouse) => { + popupTitle.pressedPosition = Qt.point(0, 0) + } + } + } + } + + Component.onCompleted: { + x = parent.width / 2 - width / 2 + y = parent.height / 2 - height / 2 + } + } + } + } + + function test_mousePropagation() { + // Tests that Popup ignores mouse events that it doesn't handle itself + // so that they propagate correctly. + let window = createTemporaryObject(mousePropagationComponent, testCase) + window.requestActivate() + tryCompare(window, "active", true) + + let popup = window.popup + popup.open() + + // mouse clicks into the popup must not propagate to the parent + mouseClick(window) + compare(window.gotMouseEvent, false) + + let title = window.popupTitle + verify(title) + + let pressPoint = Qt.point(title.width / 2, title.height / 2) + let oldPos = Qt.point(popup.x, popup.y) + mousePress(title, pressPoint.x, pressPoint.y) + fuzzyCompare(title.pressedPosition.x, pressPoint.x, 1) + fuzzyCompare(title.pressedPosition.y, pressPoint.y, 1) + mouseMove(title, pressPoint.x + 5, pressPoint.y + 5) + fuzzyCompare(popup.x, oldPos.x + 5, 1) + fuzzyCompare(popup.y, oldPos.y + 5, 1) + mouseRelease(title, pressPoint.x, pressPoint.y) + compare(title.pressedPosition, Qt.point(0, 0)) + + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_progressbar.qml b/tests/auto/quickcontrols2/controls/data/tst_progressbar.qml new file mode 100644 index 00000000000..2d26440927f --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_progressbar.qml @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "ProgressBar" + + Component { + id: progressBar + ProgressBar { } + } + + function test_value() { + var control = createTemporaryObject(progressBar, testCase) + verify(control) + + compare(control.value, 0.0) + control.value = 0.5 + compare(control.value, 0.5) + control.value = 1.0 + compare(control.value, 1.0) + control.value = -1.0 + compare(control.value, 0.0) + control.value = 2.0 + compare(control.value, 1.0) + } + + function test_range() { + var control = createTemporaryObject(progressBar, testCase, {from: 0, to: 100, value: 50}) + verify(control) + + compare(control.from, 0) + compare(control.to, 100) + compare(control.value, 50) + compare(control.position, 0.5) + + control.value = 1000 + compare(control.value, 100) + compare(control.position, 1) + + control.value = -1 + compare(control.value, 0) + compare(control.position, 0) + + control.from = 25 + compare(control.from, 25) + compare(control.value, 25) + compare(control.position, 0) + + control.to = 75 + compare(control.to, 75) + compare(control.value, 25) + compare(control.position, 0) + + control.value = 50 + compare(control.value, 50) + compare(control.position, 0.5) + } + + function test_inverted() { + var control = createTemporaryObject(progressBar, testCase, {from: 1.0, to: -1.0}) + verify(control) + + compare(control.from, 1.0) + compare(control.to, -1.0) + compare(control.value, 0.0) + compare(control.position, 0.5) + + control.value = 2.0 + compare(control.value, 1.0) + compare(control.position, 0.0) + + control.value = -2.0 + compare(control.value, -1.0) + compare(control.position, 1.0) + + control.value = 0.0 + compare(control.value, 0.0) + compare(control.position, 0.5) + } + + function test_position() { + var control = createTemporaryObject(progressBar, testCase) + verify(control) + + compare(control.value, 0) + compare(control.position, 0) + + control.value = 0.25 + compare(control.value, 0.25) + compare(control.position, 0.25) + + control.value = 0.75 + compare(control.value, 0.75) + compare(control.position, 0.75) + } + + function test_visualPosition() { + var control = createTemporaryObject(progressBar, testCase) + verify(control) + + compare(control.value, 0) + compare(control.visualPosition, 0) + + control.value = 0.25 + compare(control.value, 0.25) + compare(control.visualPosition, 0.25) + + // RTL locale + control.locale = Qt.locale("ar_EG") + compare(control.visualPosition, 0.25) + + // RTL locale + LayoutMirroring + control.LayoutMirroring.enabled = true + compare(control.visualPosition, 0.75) + + // LTR locale + LayoutMirroring + control.locale = Qt.locale("en_US") + compare(control.visualPosition, 0.75) + + // LTR locale + control.LayoutMirroring.enabled = false + compare(control.visualPosition, 0.25) + + // LayoutMirroring + control.LayoutMirroring.enabled = true + compare(control.visualPosition, 0.75) + } + + function test_indeterminate() { + var control = createTemporaryObject(progressBar, testCase) + verify(control) + compare(control.indeterminate, false) + + wait(100) + control.indeterminate = true + wait(100) + // Shouldn't crash... + control.indeterminate = false + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_radiobutton.qml b/tests/auto/quickcontrols2/controls/data/tst_radiobutton.qml new file mode 100644 index 00000000000..42ef9a15477 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_radiobutton.qml @@ -0,0 +1,377 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "RadioButton" + + Component { + id: radioButton + RadioButton { } + } + + Component { + id: signalSequenceSpy + SignalSequenceSpy { + signals: ["pressed", "released", "canceled", "clicked", "toggled", "pressedChanged", "checkedChanged"] + } + } + + function test_text() { + var control = createTemporaryObject(radioButton, testCase) + verify(control) + + compare(control.text, "") + control.text = "RadioButton" + compare(control.text, "RadioButton") + control.text = "" + compare(control.text, "") + } + + function test_checked() { + var control = createTemporaryObject(radioButton, testCase) + verify(control) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [] // No change expected + compare(control.checked, false) + verify(sequenceSpy.success) + + sequenceSpy.expectedSequence = ["checkedChanged"] + control.checked = true + compare(control.checked, true) + verify(sequenceSpy.success) + + sequenceSpy.reset() + control.checked = false + compare(control.checked, false) + verify(sequenceSpy.success) + } + + function test_mouse() { + var control = createTemporaryObject(radioButton, testCase) + verify(control) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + // check + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, true) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // attempt uncheck + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, true) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // release outside + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }]] + mouseMove(control, control.width * 2, control.height * 2, 0) + compare(control.pressed, false) + sequenceSpy.expectedSequence = [["canceled", { "pressed": false, "checked": true }]] + mouseRelease(control, control.width * 2, control.height * 2, Qt.LeftButton) + compare(control.checked, true) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // right button + sequenceSpy.expectedSequence = [] + mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.pressed, false) + verify(sequenceSpy.success) + mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.checked, true) + compare(control.pressed, false) + verify(sequenceSpy.success) + } + + function test_touch() { + var control = createTemporaryObject(radioButton, testCase) + verify(control) + + var touch = touchEvent(control) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + // check + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.checked, true) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // attempt uncheck + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.checked, true) + compare(control.pressed, false) + verify(sequenceSpy.success) + + // release outside + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(sequenceSpy.success) + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }]] + touch.move(0, control, control.width * 2, control.height * 2).commit() + compare(control.pressed, false) + sequenceSpy.expectedSequence = [["canceled", { "pressed": false, "checked": true }]] + touch.release(0, control, control.width * 2, control.height * 2).commit() + compare(control.checked, true) + compare(control.pressed, false) + verify(sequenceSpy.success) + } + + function test_keys() { + var control = createTemporaryObject(radioButton, testCase) + verify(control) + + var sequenceSpy = signalSequenceSpy.createObject(control, {target: control}) + + sequenceSpy.expectedSequence = [] + control.forceActiveFocus() + verify(control.activeFocus) + verify(sequenceSpy.success) + + // check + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + keyClick(Qt.Key_Space) + compare(control.checked, true) + verify(sequenceSpy.success) + + // attempt uncheck + sequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": true }], + "released", + "clicked"] + keyClick(Qt.Key_Space) + compare(control.checked, true) + verify(sequenceSpy.success) + + // no change + sequenceSpy.expectedSequence = [] + var keys = [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab] + for (var i = 0; i < keys.length; ++i) { + sequenceSpy.reset() + keyClick(keys[i]) + compare(control.checked, true) + verify(sequenceSpy.success) + } + } + + Component { + id: twoRadioButtons + Item { + property RadioButton rb1: RadioButton { id: rb1 } + property RadioButton rb2: RadioButton { id: rb2; checked: rb1.checked; enabled: false } + } + } + + function test_binding() { + var container = createTemporaryObject(twoRadioButtons, testCase) + verify(container) + + compare(container.rb1.checked, false) + compare(container.rb2.checked, false) + + container.rb1.checked = true + compare(container.rb1.checked, true) + compare(container.rb2.checked, true) + + container.rb1.checked = false + compare(container.rb1.checked, false) + compare(container.rb2.checked, false) + } + + Component { + id: radioButtonGroup + Column { + // auto-exclusive buttons behave as if they were in their own exclusive group + RadioButton { } + RadioButton { } + + // explicitly grouped buttons are only exclusive with each other, not with + // auto-exclusive buttons, and the autoExclusive property is ignored + ButtonGroup { id: eg } + RadioButton { ButtonGroup.group: eg } + RadioButton { ButtonGroup.group: eg; autoExclusive: false } + + ButtonGroup { id: eg2 } + RadioButton { id: rb1; Component.onCompleted: eg2.addButton(rb1) } + RadioButton { id: rb2; Component.onCompleted: eg2.addButton(rb2) } + + // non-exclusive buttons don't affect the others + RadioButton { autoExclusive: false } + RadioButton { autoExclusive: false } + } + } + + function test_autoExclusive() { + var container = createTemporaryObject(radioButtonGroup, testCase) + compare(container.children.length, 8) + + var checkStates = [false, false, false, false, false, false, false, false] + for (var i = 0; i < 8; ++i) + compare(container.children[i].checked, checkStates[i]) + + container.children[0].checked = true + checkStates[0] = true + for (i = 0; i < 8; ++i) + compare(container.children[i].checked, checkStates[i]) + + container.children[1].checked = true + checkStates[0] = false + checkStates[1] = true + for (i = 0; i < 8; ++i) + compare(container.children[i].checked, checkStates[i]) + + container.children[2].checked = true + checkStates[2] = true + for (i = 0; i < 8; ++i) + compare(container.children[i].checked, checkStates[i]) + + container.children[3].checked = true + checkStates[2] = false + checkStates[3] = true + for (i = 0; i < 8; ++i) + compare(container.children[i].checked, checkStates[i]) + + container.children[4].checked = true + checkStates[4] = true + for (i = 0; i < 8; ++i) + compare(container.children[i].checked, checkStates[i]) + + container.children[5].checked = true + checkStates[4] = false + checkStates[5] = true + for (i = 0; i < 8; ++i) + compare(container.children[i].checked, checkStates[i]) + + container.children[6].checked = true + checkStates[6] = true + for (i = 0; i < 8; ++i) + compare(container.children[i].checked, checkStates[i]) + + container.children[7].checked = true + checkStates[7] = true + for (i = 0; i < 8; ++i) + compare(container.children[i].checked, checkStates[i]) + + container.children[0].checked = true + checkStates[0] = true + checkStates[1] = false + for (i = 0; i < 8; ++i) + compare(container.children[i].checked, checkStates[i]) + } + + function test_baseline() { + var control = createTemporaryObject(radioButton, testCase) + verify(control) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_radiodelegate.qml b/tests/auto/quickcontrols2/controls/data/tst_radiodelegate.qml new file mode 100644 index 00000000000..87984b2c151 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_radiodelegate.qml @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "RadioDelegate" + + Component { + id: radioDelegate + RadioDelegate {} + } + + // TODO: data-fy tst_radiobutton (rename to tst_radio?) so we don't duplicate its tests here? + + function test_defaults() { + var control = createTemporaryObject(radioDelegate, testCase); + verify(control); + verify(!control.checked); + } + + function test_checked() { + var control = createTemporaryObject(radioDelegate, testCase); + verify(control); + + mouseClick(control); + verify(control.checked); + + mouseClick(control); + verify(control.checked); + } + + function test_baseline() { + var control = createTemporaryObject(radioDelegate, testCase); + verify(control); + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset); + } + + function test_spacing() { + var control = createTemporaryObject(radioDelegate, testCase, { text: "Some long, long, long text" }) + verify(control) + verify(control.contentItem.implicitWidth + control.leftPadding + control.rightPadding > control.background.implicitWidth) + + var textLabel = findChild(control.contentItem, "label") + verify(textLabel) + + // The implicitWidth of the IconLabel that all buttons use as their contentItem should be + // equal to the implicitWidth of the Text and the radio indicator + spacing while no icon is set. + compare(control.contentItem.implicitWidth, textLabel.implicitWidth + control.indicator.width + control.spacing) + + control.spacing += 100 + compare(control.contentItem.implicitWidth, textLabel.implicitWidth + control.indicator.width + control.spacing) + + compare(control.implicitWidth, textLabel.implicitWidth + control.indicator.width + control.spacing + control.leftPadding + control.rightPadding) + } + + function test_display_data() { + return [ + { "tag": "IconOnly", display: RadioDelegate.IconOnly }, + { "tag": "TextOnly", display: RadioDelegate.TextOnly }, + { "tag": "TextUnderIcon", display: RadioDelegate.TextUnderIcon }, + { "tag": "TextBesideIcon", display: RadioDelegate.TextBesideIcon }, + { "tag": "IconOnly, mirrored", display: RadioDelegate.IconOnly, mirrored: true }, + { "tag": "TextOnly, mirrored", display: RadioDelegate.TextOnly, mirrored: true }, + { "tag": "TextUnderIcon, mirrored", display: RadioDelegate.TextUnderIcon, mirrored: true }, + { "tag": "TextBesideIcon, mirrored", display: RadioDelegate.TextBesideIcon, mirrored: true } + ] + } + + function test_display(data) { + var control = createTemporaryObject(radioDelegate, testCase, { + text: "RadioDelegate", + display: data.display, + width: 400, + "icon.source": "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png", + "LayoutMirroring.enabled": !!data.mirrored + }) + verify(control) + compare(control.icon.source, "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png") + + var iconImage = findChild(control.contentItem, "image") + var textLabel = findChild(control.contentItem, "label") + + var availableWidth = control.availableWidth - control.indicator.width - control.spacing + var indicatorOffset = control.mirrored ? control.indicator.width + control.spacing : 0 + + switch (control.display) { + case RadioDelegate.IconOnly: + verify(iconImage) + verify(!textLabel) + compare(iconImage.x, indicatorOffset + (availableWidth - iconImage.width) / 2) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + break; + case RadioDelegate.TextOnly: + verify(!iconImage) + verify(textLabel) + compare(textLabel.x, control.mirrored ? control.availableWidth - textLabel.width : 0) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + case RadioDelegate.TextUnderIcon: + verify(iconImage) + verify(textLabel) + compare(iconImage.x, indicatorOffset + (availableWidth - iconImage.width) / 2) + compare(textLabel.x, indicatorOffset + (availableWidth - textLabel.width) / 2) + verify(iconImage.y < textLabel.y) + break; + case RadioDelegate.TextBesideIcon: + verify(iconImage) + verify(textLabel) + if (control.mirrored) + verify(textLabel.x < iconImage.x) + else + verify(iconImage.x < textLabel.x) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + } + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_rangeslider.qml b/tests/auto/quickcontrols2/controls/data/tst_rangeslider.qml new file mode 100644 index 00000000000..7a76dd15747 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_rangeslider.qml @@ -0,0 +1,1279 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "RangeSlider" + + Component { + id: signalSpy + SignalSpy { } + } + + Component { + id: sliderComponent + RangeSlider { + id: slider + + Component.onCompleted: { + first.handle.objectName = "firstHandle" + second.handle.objectName = "secondHandle" + } + + Text { + text: "1" + parent: slider.first.handle + anchors.centerIn: parent + } + + Text { + text: "2" + parent: slider.second.handle + anchors.centerIn: parent + } + } + } + + function test_defaults() { + var control = createTemporaryObject(sliderComponent, testCase) + verify(control) + + compare(control.stepSize, 0) + compare(control.snapMode, RangeSlider.NoSnap) + compare(control.orientation, Qt.Horizontal) + compare(control.horizontal, true) + compare(control.vertical, false) + } + + function test_values() { + var control = createTemporaryObject(sliderComponent, testCase) + verify(control) + + compare(control.first.value, 0.0) + compare(control.second.value, 1.0) + control.first.value = 0.5 + compare(control.first.value, 0.5) + control.first.value = 1.0 + compare(control.first.value, 1.0) + control.first.value = -1.0 + compare(control.first.value, 0.0) + control.first.value = 2.0 + compare(control.first.value, 1.0) + + control.first.value = 0 + compare(control.first.value, 0.0) + control.second.value = 0.5 + compare(control.second.value, 0.5) + control.first.value = 1 + compare(control.first.value, 0.5) + control.second.value = 0 + compare(control.second.value, 0.5) + } + + function test_range() { + var control = createTemporaryObject(sliderComponent, testCase, { from: 0, to: 100, "first.value": 50, "second.value": 100 }) + verify(control) + + compare(control.from, 0) + compare(control.to, 100) + compare(control.first.value, 50) + compare(control.second.value, 100) + compare(control.first.position, 0.5) + compare(control.second.position, 1.0) + + control.first.value = 1000 + compare(control.first.value, 100) + compare(control.first.position, 1.0) + + control.first.value = -1 + compare(control.first.value, 0) + compare(control.first.position, 0) + + control.from = 25 + compare(control.from, 25) + compare(control.first.value, 25) + compare(control.first.position, 0) + + control.to = 75 + compare(control.to, 75) + compare(control.second.value, 75) + compare(control.second.position, 1.0) + + control.first.value = 50 + compare(control.first.value, 50) + compare(control.first.position, 0.5) + } + + function test_setToFromUpdatesHandles() { + var control = createTemporaryObject(sliderComponent, testCase, { from: 0, to: 100, "first.value": 50, "second.value": 75 }) + verify(control) + + let firstPos = control.first.position + let secondPos = control.second.position + + var firstPosChangesSpy = signalSpy.createObject(control, {target: control.first, signalName: "positionChanged"}) + verify(firstPosChangesSpy.valid) + + var secondPosChangesSpy = signalSpy.createObject(control, {target: control.second, signalName: "positionChanged"}) + verify(secondPosChangesSpy.valid) + + // Increasing the 'to' value, so the positions of the handles should be + // moved to the left (become smaller) + control.to = 200; + compare(firstPosChangesSpy.count, 1) + compare(secondPosChangesSpy.count, 1) + verify(control.first.position < firstPos) + verify(control.second.position < secondPos) + + // resetting the values + control.to = 100 + firstPosChangesSpy.clear() + secondPosChangesSpy.clear() + firstPos = control.first.position + secondPos = control.second.position + + // Decreasing the 'from' value, so the positions of the handles should + // be moved to the right (become larger) + control.from = -100 + compare(firstPosChangesSpy.count, 1) + compare(secondPosChangesSpy.count, 1) + verify(control.first.position > firstPos) + verify(control.second.position > secondPos) + } + + function test_setValues() { + var control = createTemporaryObject(sliderComponent, testCase) + verify(control) + + compare(control.from, 0) + compare(control.to, 1) + compare(control.first.value, 0) + compare(control.second.value, 1) + compare(control.first.position, 0.0) + compare(control.second.position, 1.0) + + control.setValues(100, 200) + compare(control.first.value, 1) + compare(control.second.value, 1) + compare(control.first.position, 1.0) + compare(control.second.position, 1.0) + + control.to = 300; + control.setValues(100, 200) + compare(control.first.value, 100) + compare(control.second.value, 200) + compare(control.first.position, 0.333333) + compare(control.second.position, 0.666666) + } + + function test_inverted() { + var control = createTemporaryObject(sliderComponent, testCase, { from: 1.0, to: -1.0 }) + verify(control) + + compare(control.from, 1.0) + compare(control.to, -1.0) + compare(control.first.value, 0.0) + compare(control.first.position, 0.5) + compare(control.second.value, 0.0); + compare(control.second.position, 0.5); + + control.first.value = 2.0 + compare(control.first.value, 1.0) + compare(control.first.position, 0.0) + compare(control.second.value, 0.0); + compare(control.second.position, 0.5); + + control.first.value = -2.0 + compare(control.first.value, 0.0) + compare(control.first.position, 0.5) + compare(control.second.value, 0.0); + compare(control.second.position, 0.5); + + control.first.value = 0.0 + compare(control.first.value, 0.0) + compare(control.first.position, 0.5) + compare(control.second.value, 0.0); + compare(control.second.position, 0.5); + } + + function test_visualPosition() { + var control = createTemporaryObject(sliderComponent, testCase) + verify(control) + + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.first.visualPosition, 0.0) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + compare(control.second.visualPosition, 1.0) + + control.first.value = 0.25 + compare(control.first.value, 0.25) + compare(control.first.position, 0.25) + compare(control.first.visualPosition, 0.25) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + compare(control.second.visualPosition, 1.0) + + // RTL locale + control.locale = Qt.locale("ar_EG") + compare(control.first.visualPosition, 0.25) + compare(control.second.visualPosition, 1.0) + + // RTL locale + LayoutMirroring + control.LayoutMirroring.enabled = true + compare(control.first.visualPosition, 0.75) + compare(control.second.visualPosition, 0.0) + + // LTR locale + LayoutMirroring + control.locale = Qt.locale("en_US") + compare(control.first.visualPosition, 0.75) + compare(control.second.visualPosition, 0.0) + + // LTR locale + control.LayoutMirroring.enabled = false + compare(control.first.visualPosition, 0.25) + compare(control.second.visualPosition, 1.0) + + // LayoutMirroring + control.LayoutMirroring.enabled = true + compare(control.first.visualPosition, 0.75) + compare(control.second.visualPosition, 0.0) + } + + function test_orientation() { + var control = createTemporaryObject(sliderComponent, testCase) + verify(control) + + compare(control.orientation, Qt.Horizontal) + compare(control.horizontal, true) + compare(control.vertical, false) + verify(control.width > control.height) + + control.orientation = Qt.Vertical + compare(control.orientation, Qt.Vertical) + compare(control.horizontal, false) + compare(control.vertical, true) + verify(control.width < control.height) + } + + function test_mouse_data() { + return [ + { tag: "horizontal", orientation: Qt.Horizontal, live: false }, + { tag: "vertical", orientation: Qt.Vertical, live: false }, + { tag: "horizontal:live", orientation: Qt.Horizontal, live: true }, + { tag: "vertical:live", orientation: Qt.Vertical, live: true } + ] + } + + function test_mouse(data) { + var control = createTemporaryObject(sliderComponent, testCase, { orientation: data.orientation, live: data.live }) + verify(control) + + var firstPressedSpy = signalSpy.createObject(control, {target: control.first, signalName: "pressedChanged"}) + verify(firstPressedSpy.valid) + + var firstMovedSpy = signalSpy.createObject(control, {target: control.first, signalName: "moved"}) + verify(firstMovedSpy.valid) + + var secondPressedSpy = signalSpy.createObject(control, {target: control.second, signalName: "pressedChanged"}) + verify(secondPressedSpy.valid) + + var secondMovedSpy = signalSpy.createObject(control, {target: control.second, signalName: "moved"}) + verify(secondMovedSpy.valid) + + // Press and release the first handle without moving it. + mousePress(control, control.leftPadding, control.height - control.bottomPadding - 1, Qt.LeftButton) + compare(firstPressedSpy.count, 1) + compare(firstMovedSpy.count, 0) + compare(secondPressedSpy.count, 0) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + mouseRelease(control, control.leftPadding, control.height - control.bottomPadding - 1, Qt.LeftButton) + compare(firstPressedSpy.count, 2) + compare(firstMovedSpy.count, 0) + compare(secondPressedSpy.count, 0) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, false) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + // Press and release the second handle without moving it. + mousePress(control, control.width - control.rightPadding - 1, control.topPadding, Qt.LeftButton) + compare(firstPressedSpy.count, 2) + compare(firstMovedSpy.count, 0) + compare(secondPressedSpy.count, 1) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, false) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, true) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + mouseRelease(control, control.width - control.rightPadding - 1, control.topPadding, Qt.LeftButton) + compare(firstPressedSpy.count, 2) + compare(firstMovedSpy.count, 0) + compare(secondPressedSpy.count, 2) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, false) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + // Press and release on the bottom left corner of the control without moving the handle. + mousePress(control, 0, control.height - 1, Qt.LeftButton) + compare(firstPressedSpy.count, 3) + compare(firstMovedSpy.count, 0) + compare(secondPressedSpy.count, 2) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + mouseRelease(control, 0, control.height - 1, Qt.LeftButton) + compare(firstPressedSpy.count, 4) + compare(firstMovedSpy.count, 0) + compare(secondPressedSpy.count, 2) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, false) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + // Drag the first handle. + mousePress(control, control.leftPadding, control.height - control.bottomPadding - 1, Qt.LeftButton) + compare(firstPressedSpy.count, 5) + compare(firstMovedSpy.count, 0) + compare(secondPressedSpy.count, 2) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + var horizontal = control.orientation === Qt.Horizontal + var toX = horizontal ? control.width * 0.5 : control.first.handle.x + var toY = horizontal ? control.first.handle.y : control.height * 0.5 + mouseMove(control, toX, toY) + compare(firstPressedSpy.count, 5) + compare(firstMovedSpy.count, 1) + compare(secondPressedSpy.count, 2) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, true) + compare(control.first.value, data.live ? 0.5 : 0.0) + compare(control.first.position, 0.5) + compare(control.first.visualPosition, 0.5) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + compare(control.second.visualPosition, horizontal ? 1.0 : 0.0) + + mouseRelease(control, toX, toY, Qt.LeftButton) + compare(firstPressedSpy.count, 6) + compare(firstMovedSpy.count, 1) + compare(secondPressedSpy.count, 2) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, false) + compare(control.first.value, 0.5) + compare(control.first.position, 0.5) + compare(control.first.visualPosition, 0.5) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + compare(control.second.visualPosition, horizontal ? 1.0 : 0.0) + } + + function test_touch_data() { + return [ + { tag: "horizontal", orientation: Qt.Horizontal, live: false }, + { tag: "vertical", orientation: Qt.Vertical, live: false }, + { tag: "horizontal:live", orientation: Qt.Horizontal, live: true }, + { tag: "vertical:live", orientation: Qt.Vertical, live: true } + ] + } + + function test_touch(data) { + var control = createTemporaryObject(sliderComponent, testCase, { orientation: data.orientation, live: data.live }) + verify(control) + + var firstPressedSpy = signalSpy.createObject(control, {target: control.first, signalName: "pressedChanged"}) + verify(firstPressedSpy.valid) + + var firstMovedSpy = signalSpy.createObject(control, {target: control.first, signalName: "moved"}) + verify(firstMovedSpy.valid) + + var secondPressedSpy = signalSpy.createObject(control, {target: control.second, signalName: "pressedChanged"}) + verify(secondPressedSpy.valid) + + var secondMovedSpy = signalSpy.createObject(control, {target: control.second, signalName: "moved"}) + verify(secondMovedSpy.valid) + + // Press and release the first handle without moving it. + var touch = touchEvent(control) + control.setValues(0, 1); + touch.press(0, control, control.leftPadding, control.height - control.bottomPadding - 1).commit() + compare(firstPressedSpy.count, 1) + compare(firstMovedSpy.count, 0) + compare(secondPressedSpy.count, 0) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + touch.release(0, control, control.leftPadding, control.height - control.bottomPadding - 1).commit() + compare(firstPressedSpy.count, 2) + compare(firstMovedSpy.count, 0) + compare(secondPressedSpy.count, 0) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, false) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + // Press and release the second handle without moving it. + touch.press(0, control, control.width - control.rightPadding - 1, control.topPadding).commit() + compare(firstPressedSpy.count, 2) + compare(secondPressedSpy.count, 1) + compare(control.first.pressed, false) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, true) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + touch.release(0, control, control.width - control.rightPadding - 1, control.topPadding).commit() + compare(firstPressedSpy.count, 2) + compare(secondPressedSpy.count, 2) + compare(control.first.pressed, false) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + // Press and release on the bottom left corner of the control without moving the handle. + touch.press(0, control, 0, control.height - 1).commit() + compare(firstPressedSpy.count, 3) + compare(secondPressedSpy.count, 2) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + touch.release(0, control, 0, control.height - 1).commit() + compare(firstPressedSpy.count, 4) + compare(secondPressedSpy.count, 2) + compare(control.first.pressed, false) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + touch.press(0, control, control.first.handle.x, control.first.handle.y).commit() + compare(firstPressedSpy.count, 5) + compare(secondPressedSpy.count, 2) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + + // Drag the first handle. + var horizontal = control.orientation === Qt.Horizontal + var toX = horizontal ? control.width * 0.5 : control.first.handle.x + var toY = horizontal ? control.first.handle.y : control.height * 0.5 + touch.move(0, control, toX, toY).commit() + compare(firstPressedSpy.count, 5) + compare(secondPressedSpy.count, 2) + compare(control.first.pressed, true) + compare(control.first.value, data.live ? 0.5 : 0.0) + compare(control.first.position, 0.5) + compare(control.first.visualPosition, 0.5) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + compare(control.second.visualPosition, horizontal ? 1.0 : 0.0) + + touch.release(0, control, toX, toY).commit() + compare(firstPressedSpy.count, 6) + compare(secondPressedSpy.count, 2) + compare(control.first.pressed, false) + compare(control.first.value, 0.5) + compare(control.first.position, 0.5) + compare(control.first.visualPosition, 0.5) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + compare(control.second.visualPosition, horizontal ? 1.0 : 0.0) + } + + function test_multiTouch() { + var control1 = createTemporaryObject(sliderComponent, testCase) + verify(control1) + + // press and move the first handle of the first slider + var touch = touchEvent(control1) + touch.press(0, control1, 0, 0).commit().move(0, control1, control1.width / 2, control1.height / 2).commit() + compare(control1.first.pressed, true) + compare(control1.first.position, 0.5) + compare(control1.second.pressed, false) + compare(control1.second.position, 1.0) + + // press and move the second handle of the first slider + touch.stationary(0).press(1, control1, control1.width - 1, control1.height - 1).commit() + touch.stationary(0).move(1, control1, control1.width / 2, control1.height / 2).commit() + compare(control1.first.pressed, true) + compare(control1.first.position, 0.5) + compare(control1.second.pressed, true) + compare(control1.second.position, 0.5) + + var control2 = createTemporaryObject(sliderComponent, testCase, {y: control1.height}) + verify(control2) + + // press and move the first handle of the second slider + touch.stationary(0).stationary(1).press(2, control2, 0, 0).commit() + touch.stationary(0).stationary(1).move(2, control2, control2.width / 2, control2.height / 2).commit() + compare(control1.first.pressed, true) + compare(control1.first.position, 0.5) + compare(control1.second.pressed, true) + compare(control1.second.position, 0.5) + compare(control2.first.pressed, true) + compare(control2.first.position, 0.5) + compare(control2.second.pressed, false) + compare(control2.second.position, 1.0) + + // press and move the second handle of the second slider + touch.stationary(0).stationary(1).stationary(2).press(3, control2, control2.width - 1, control2.height - 1).commit() + touch.stationary(0).stationary(1).stationary(2).move(3, control2, control2.width / 2, control2.height / 2).commit() + compare(control1.first.pressed, true) + compare(control1.first.position, 0.5) + compare(control1.second.pressed, true) + compare(control1.second.position, 0.5) + compare(control2.first.pressed, true) + compare(control2.first.position, 0.5) + compare(control2.second.pressed, true) + compare(control2.second.position, 0.5) + + // release the both handles of the both sliders + touch.release(0, control1).release(1, control1).release(2, control2).release(3, control2).commit() + compare(control1.first.pressed, false) + compare(control1.first.position, 0.5) + compare(control1.second.pressed, false) + compare(control1.second.position, 0.5) + compare(control2.first.pressed, false) + compare(control2.first.position, 0.5) + compare(control2.second.pressed, false) + compare(control2.second.position, 0.5) + } + + function test_overlappingHandles() { + var control = createTemporaryObject(sliderComponent, testCase) + verify(control) + + // By default, we force the second handle to be after the first in + // terms of stacking order *and* z value. + compare(control.second.handle.z, 1) + compare(control.first.handle.z, 0) + control.first.value = 0 + control.second.value = 0 + + // When both handles overlap, only the handle with the higher Z value + // should be hovered. + mouseMove(control, control.second.handle.x, control.second.handle.y) + compare(control.second.hovered, true) + compare(control.first.hovered, false) + + // Both are at the same position, so it doesn't matter whose coordinates we use. + mousePress(control, control.first.handle.x, control.first.handle.y, Qt.LeftButton) + verify(control.second.pressed) + compare(control.second.handle.z, 1) + compare(control.first.handle.z, 0) + + // Move the second handle out of the way. + mouseMove(control, control.width, control.first.handle.y) + mouseRelease(control, control.width, control.first.handle.y, Qt.LeftButton) + verify(!control.second.pressed) + compare(control.second.value, 1.0) + compare(control.second.handle.z, 1) + compare(control.first.handle.z, 0) + + // The first handle should not be hovered. + compare(control.first.hovered, false) + + // Move the first handle on top of the second. + mousePress(control, control.first.handle.x, control.first.handle.y, Qt.LeftButton) + verify(control.first.pressed) + compare(control.first.handle.z, 1) + compare(control.second.handle.z, 0) + + mouseMove(control, control.width, control.first.handle.y) + mouseRelease(control, control.width, control.first.handle.y, Qt.LeftButton) + verify(!control.first.pressed) + compare(control.first.handle.z, 1) + compare(control.second.handle.z, 0) + + // The most recently pressed handle (the first) should have the higher z value. + mousePress(control, control.first.handle.x, control.first.handle.y, Qt.LeftButton) + verify(control.first.pressed) + compare(control.first.handle.z, 1) + compare(control.second.handle.z, 0) + + mouseRelease(control, control.first.handle.x, control.first.handle.y, Qt.LeftButton) + verify(!control.first.pressed) + compare(control.first.handle.z, 1) + compare(control.second.handle.z, 0) + } + + function test_keys_data() { + return [ + { tag: "horizontal", orientation: Qt.Horizontal, decrease: Qt.Key_Left, increase: Qt.Key_Right }, + { tag: "vertical", orientation: Qt.Vertical, decrease: Qt.Key_Down, increase: Qt.Key_Up } + ] + } + + function test_keys(data) { + var control = createTemporaryObject(sliderComponent, testCase, { orientation: data.orientation }) + verify(control) + + var pressedCount = 0 + + var firstPressedSpy = signalSpy.createObject(control, {target: control.first, signalName: "pressedChanged"}) + verify(firstPressedSpy.valid) + + control.first.handle.forceActiveFocus() + verify(control.first.handle.activeFocus) + + control.first.value = 0.5 + + for (var d1 = 1; d1 <= 10; ++d1) { + keyPress(data.decrease) + compare(control.first.pressed, true) + compare(firstPressedSpy.count, ++pressedCount) + + compare(control.first.value, Math.max(0.0, 0.5 - d1 * 0.1)) + compare(control.first.value, control.first.position) + + keyRelease(data.decrease) + compare(control.first.pressed, false) + compare(firstPressedSpy.count, ++pressedCount) + } + + for (var i1 = 1; i1 <= 20; ++i1) { + keyPress(data.increase) + compare(control.first.pressed, true) + compare(firstPressedSpy.count, ++pressedCount) + + compare(control.first.value, Math.min(1.0, 0.0 + i1 * 0.1)) + compare(control.first.value, control.first.position) + + keyRelease(data.increase) + compare(control.first.pressed, false) + compare(firstPressedSpy.count, ++pressedCount) + } + + control.first.value = 0; + control.stepSize = 0.25 + + pressedCount = 0; + var secondPressedSpy = signalSpy.createObject(control, {target: control.second, signalName: "pressedChanged"}) + verify(secondPressedSpy.valid) + + control.second.handle.forceActiveFocus() + verify(control.second.handle.activeFocus) + + for (var d2 = 1; d2 <= 10; ++d2) { + keyPress(data.decrease) + compare(control.second.pressed, true) + compare(secondPressedSpy.count, ++pressedCount) + + compare(control.second.value, Math.max(0.0, 1.0 - d2 * 0.25)) + compare(control.second.value, control.second.position) + + keyRelease(data.decrease) + compare(control.second.pressed, false) + compare(secondPressedSpy.count, ++pressedCount) + } + + for (var i2 = 1; i2 <= 10; ++i2) { + keyPress(data.increase) + compare(control.second.pressed, true) + compare(secondPressedSpy.count, ++pressedCount) + + compare(control.second.value, Math.min(1.0, 0.0 + i2 * 0.25)) + compare(control.second.value, control.second.position) + + keyRelease(data.increase) + compare(control.second.pressed, false) + compare(secondPressedSpy.count, ++pressedCount) + } + } + + function test_padding() { + // test with "unbalanced" paddings (left padding != right padding) to ensure + // that the slider position calculation is done taking padding into account + // ==> the position is _not_ 0.5 in the middle of the control + var control = createTemporaryObject(sliderComponent, testCase, { leftPadding: 10, rightPadding: 20, live: false }) + verify(control) + + var firstPressedSpy = signalSpy.createObject(control, {target: control.first, signalName: "pressedChanged"}) + verify(firstPressedSpy.valid) + + mousePress(control, control.first.handle.x, control.first.handle.y, Qt.LeftButton) + compare(firstPressedSpy.count, 1) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.first.visualPosition, 0.0) + + mouseMove(control, control.leftPadding + control.availableWidth * 0.5, control.height * 0.5, 0) + compare(firstPressedSpy.count, 1) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + compare(control.first.position, 0.5) + compare(control.first.visualPosition, 0.5) + + mouseMove(control, control.width * 0.5, control.height * 0.5, 0) + compare(firstPressedSpy.count, 1) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + verify(control.first.position > 0.5) + verify(control.first.visualPosition > 0.5) + + mouseRelease(control, control.leftPadding + control.availableWidth * 0.5, control.height * 0.5, Qt.LeftButton) + compare(firstPressedSpy.count, 2) + compare(control.first.pressed, false) + compare(control.first.value, 0.5) + compare(control.first.position, 0.5) + compare(control.first.visualPosition, 0.5) + + // RTL + control.first.value = 0 + control.locale = Qt.locale("ar_EG") + + mousePress(control, control.first.handle.x, control.first.handle.y, Qt.LeftButton) + compare(firstPressedSpy.count, 3) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.first.visualPosition, 0.0) + + mouseMove(control, control.leftPadding + control.availableWidth * 0.5, control.height * 0.5, 0) + compare(firstPressedSpy.count, 3) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + compare(control.first.position, 0.5) + compare(control.first.visualPosition, 0.5) + + mouseMove(control, control.width * 0.5, control.height * 0.5, 0) + compare(firstPressedSpy.count, 3) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + verify(control.first.position > 0.5) + verify(control.first.visualPosition > 0.5) + + mouseRelease(control, control.leftPadding + control.availableWidth * 0.5, control.height * 0.5, Qt.LeftButton) + compare(firstPressedSpy.count, 4) + compare(control.first.pressed, false) + compare(control.first.value, 0.5) + compare(control.first.position, 0.5) + compare(control.first.visualPosition, 0.5) + } + + function test_snapMode_data(immediate) { + return [ + { tag: "NoSnap", snapMode: RangeSlider.NoSnap, from: 0, to: 2, values: [0, 0, 0.25], positions: [0, 0.1, 0.1] }, + { tag: "SnapAlways (0..2)", snapMode: RangeSlider.SnapAlways, from: 0, to: 2, values: [0.0, 0.0, 0.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapAlways (1..3)", snapMode: RangeSlider.SnapAlways, from: 1, to: 3, values: [1.0, 1.0, 1.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapAlways (-1..1)", snapMode: RangeSlider.SnapAlways, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] }, + { tag: "SnapAlways (1..-1)", snapMode: RangeSlider.SnapAlways, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] }, + { tag: "SnapOnRelease (0..2)", snapMode: RangeSlider.SnapOnRelease, from: 0, to: 2, values: [0.0, 0.0, 0.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapOnRelease (1..3)", snapMode: RangeSlider.SnapOnRelease, from: 1, to: 3, values: [1.0, 1.0, 1.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapOnRelease (-1..1)", snapMode: RangeSlider.SnapOnRelease, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] }, + { tag: "SnapOnRelease (1..-1)", snapMode: RangeSlider.SnapOnRelease, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] } + ] + } + + function test_snapMode_mouse_data() { + return test_snapMode_data(true) + } + + function test_snapMode_mouse(data) { + var control = createTemporaryObject(sliderComponent, testCase, {snapMode: data.snapMode, from: data.from, to: data.to, stepSize: 0.2, live: false}) + verify(control) + + control.first.value = 0 + control.second.value = data.to + + var fuzz = 0.05 + + mousePress(control, control.leftPadding) + compare(control.first.pressed, true) + compare(control.first.value, data.values[0]) + compare(control.first.position, data.positions[0]) + + mouseMove(control, control.leftPadding + 0.15 * (control.availableWidth + control.first.handle.width / 2)) + compare(control.first.pressed, true) + fuzzyCompare(control.first.value, data.values[1], fuzz) + fuzzyCompare(control.first.position, data.positions[1], fuzz) + + mouseRelease(control, control.leftPadding + 0.15 * (control.availableWidth + control.first.handle.width / 2)) + compare(control.first.pressed, false) + fuzzyCompare(control.first.value, data.values[2], fuzz) + fuzzyCompare(control.first.position, data.positions[2], fuzz) + } + + function test_snapMode_touch_data() { + return test_snapMode_data(false) + } + + function test_snapMode_touch(data) { + var control = createTemporaryObject(sliderComponent, testCase, {snapMode: data.snapMode, from: data.from, to: data.to, stepSize: 0.2, live: false}) + verify(control) + + control.first.value = 0 + control.second.value = data.to + + var fuzz = 0.05 + + var touch = touchEvent(control) + touch.press(0, control, control.first.handle.x, control.first.handle.y).commit() + compare(control.first.pressed, true) + compare(control.first.value, data.values[0]) + compare(control.first.position, data.positions[0]) + + touch.move(0, control, control.leftPadding + 0.15 * (control.availableWidth + control.first.handle.width / 2)).commit() + compare(control.first.pressed, true) + fuzzyCompare(control.first.value, data.values[1], fuzz) + fuzzyCompare(control.first.position, data.positions[1], fuzz) + + touch.release(0, control, control.leftPadding + 0.15 * (control.availableWidth + control.first.handle.width / 2)).commit() + compare(control.first.pressed, false) + fuzzyCompare(control.first.value, data.values[2], fuzz) + fuzzyCompare(control.first.position, data.positions[2], fuzz) + } + + function test_focus() { + var control = createTemporaryObject(sliderComponent, testCase) + verify(control) + + compare(control.activeFocus, false) + + // focus is forwarded to the first handle + control.forceActiveFocus() + compare(control.activeFocus, true) + compare(control.first.handle.activeFocus, true) + compare(control.second.handle.activeFocus, false) + + // move focus to the second handle + control.second.handle.forceActiveFocus() + compare(control.activeFocus, true) + compare(control.first.handle.activeFocus, false) + compare(control.second.handle.activeFocus, true) + + // clear focus + control.focus = false + compare(control.activeFocus, false) + compare(control.first.handle.activeFocus, false) + compare(control.second.handle.activeFocus, false) + + // focus is forwarded to the second handle (where it previously was in the focus scope) + control.forceActiveFocus() + compare(control.activeFocus, true) + compare(control.first.handle.activeFocus, false) + compare(control.second.handle.activeFocus, true) + } + + function test_hover_data() { + return [ + { tag: "first:true", node: "first", hoverEnabled: true }, + { tag: "first:false", node: "first", hoverEnabled: false }, + { tag: "second:true", node: "second", hoverEnabled: true }, + { tag: "second:false", node: "second", hoverEnabled: false } + ] + } + + function test_hover(data) { + var control = createTemporaryObject(sliderComponent, testCase, {hoverEnabled: data.hoverEnabled}) + verify(control) + + var node = control[data.node] + compare(control.hovered, false) + compare(node.hovered, false) + + mouseMove(control, node.handle.x + node.handle.width / 2, node.handle.y + node.handle.height / 2) + compare(control.hovered, data.hoverEnabled) + compare(node.hovered, data.hoverEnabled && node.handle.enabled) + + mouseMove(control, node.handle.x - 1, node.handle.y - 1) + compare(node.hovered, false) + } + + function test_nullHandles() { + var control = createTemporaryObject(sliderComponent, testCase, {"second.value": 1}) + verify(control) + + verify(control.first.handle) + verify(control.second.handle) + + control.first.handle = null + control.second.handle = null + + mousePress(control, control.leftPadding, control.height / 2) + verify(control.first.pressed, true) + compare(control.second.pressed, false) + + mouseRelease(control, control.leftPadding, control.height / 2) + compare(control.first.pressed, false) + compare(control.second.pressed, false) + + mousePress(control, control.width - control.rightPadding - 1, control.height / 2) + compare(control.first.pressed, false) + compare(control.second.pressed, true) + + mouseRelease(control, control.width - control.rightPadding - 1, control.height / 2) + compare(control.first.pressed, false) + compare(control.second.pressed, false) + } + + function test_touchDragThreshold_data() { + var d1 = 3; var d2 = 7; + return [ + { tag: "horizontal", orientation: Qt.Horizontal, dx1: d1, dy1: 0, dx2: d2, dy2: 0 }, + { tag: "vertical", orientation: Qt.Vertical, dx1: 0, dy1: -d1, dx2: 0, dy2: -d2 }, + { tag: "horizontal2", orientation: Qt.Horizontal, dx1: -d1, dy1: 0, dx2: -d2, dy2: 0 }, + { tag: "vertical2", orientation: Qt.Vertical, dx1: 0, dy1: d1, dx2: 0, dy2: d2 }, + ] + } + + function test_touchDragThreshold(data) { + var control = createTemporaryObject(sliderComponent, testCase, {touchDragThreshold: 10, live: true, orientation: data.orientation, "first.value": 0, "second.value": 1}) + verify(control) + compare(control.touchDragThreshold, 10) + + var valueChangedCount = 0 + var valueChangedSpy = signalSpy.createObject(control, {target: control, signalName: "touchDragThresholdChanged"}) + verify(valueChangedSpy.valid) + + control.touchDragThreshold = undefined + compare(control.touchDragThreshold, -1) // reset to -1 + compare(valueChangedSpy.count, ++valueChangedCount) + + var t = 5 + control.touchDragThreshold = t + compare(control.touchDragThreshold, t) + compare(valueChangedSpy.count, ++valueChangedCount) + + control.touchDragThreshold = t + compare(control.touchDragThreshold, t) + compare(valueChangedSpy.count, valueChangedCount) + + var pressedCount = 0 + var pressedCount2 = 0 + var visualPositionCount = 0 + var visualPositionCount2 = 0 + + var pressedSpy = signalSpy.createObject(control, {target: control.first, signalName: "pressedChanged"}) + verify(pressedSpy.valid) + var pressedSpy2 = signalSpy.createObject(control, {target: control.second, signalName: "pressedChanged"}) + verify(pressedSpy2.valid) + + var visualPositionSpy = signalSpy.createObject(control, {target: control.first, signalName: "visualPositionChanged"}) + verify(visualPositionSpy.valid) + var visualPositionSpy2 = signalSpy.createObject(control, {target: control.second, signalName: "visualPositionChanged"}) + verify(visualPositionSpy2.valid) + + var touch = touchEvent(control) + control.first.value = 0.4 + control.second.value = 1 + var x0 = control.first.handle.x + control.first.handle.width * 0.5 + var y0 = control.first.handle.y + control.first.handle.height * 0.5 + touch.press(0, control, x0, y0).commit() + compare(pressedSpy.count, ++pressedCount) + compare(control.first.pressed, true) + compare(visualPositionSpy.count, ++visualPositionCount) + + touch.move(0, control, x0 + data.dx1, y0 + data.dy1).commit() + compare(pressedSpy.count, pressedCount) + compare(control.first.pressed, true) + compare(visualPositionSpy.count, visualPositionCount) + + touch.move(0, control, x0 + data.dx2, y0 + data.dy2).commit() + compare(pressedSpy.count, pressedCount) + compare(control.first.pressed, true) + compare(visualPositionSpy.count, ++visualPositionCount) + + touch.release(0, control, x0 + data.dx2, y0 + data.dy2).commit() + + control.first.value = 0 + control.second.value = 0.6 + x0 = control.second.handle.x + control.second.handle.width * 0.5 + y0 = control.second.handle.y + control.second.handle.height * 0.5 + touch.press(0, control, x0, y0).commit() + compare(pressedSpy2.count, ++pressedCount2) + compare(control.second.pressed, true) + compare(visualPositionSpy2.count, ++visualPositionCount2) + + touch.move(0, control, x0 + data.dx1, y0 + data.dy1).commit() + compare(pressedSpy2.count, pressedCount2) + compare(control.second.pressed, true) + compare(visualPositionSpy2.count, visualPositionCount2) + + touch.move(0, control, x0 + data.dx2, y0 + data.dy2).commit() + compare(pressedSpy2.count, pressedCount2) + compare(control.second.pressed, true) + compare(visualPositionSpy2.count, ++visualPositionCount2) + touch.release(0, control, x0 + data.dx2, y0 + data.dy2).commit() + } + + function test_valueAt_data() { + return [ + { tag: "0.0..1.0", properties: { from: 0.0, to: 1.0 }, values: [0.0, 0.2, 0.5, 1.0] }, + { tag: "0..100", properties: { from: 0, to: 100 }, values: [0, 20, 50, 100] }, + { tag: "100..-100", properties: { from: 100, to: -100 }, values: [100, 60, 0, -100] }, + { tag: "-7..7", properties: { from: -7, to: 7, stepSize: 1.0 }, values: [-7.0, -4.0, 0.0, 7.0] }, + { tag: "-3..7", properties: { from: -3, to: 7, stepSize: 5.0 }, values: [-3.0, -3.0, 2.0, 7.0] }, + ] + } + + function test_valueAt(data) { + var control = createTemporaryObject(sliderComponent, testCase, data.properties) + verify(control) + + compare(control.valueAt(0.0), data.values[0]) + compare(control.valueAt(0.2), data.values[1]) + compare(control.valueAt(0.5), data.values[2]) + compare(control.valueAt(1.0), data.values[3]) + } + + + function test_updatePositionOnPress() { + var control = createTemporaryObject(sliderComponent, testCase) + verify(control) + + var firstPressedSpy = signalSpy.createObject(control, {target: control.first, signalName: "pressedChanged"}) + verify(firstPressedSpy.valid) + + var firstMovedSpy = signalSpy.createObject(control, {target: control.first, signalName: "moved"}) + verify(firstMovedSpy.valid) + + var secondPressedSpy = signalSpy.createObject(control, {target: control.second, signalName: "pressedChanged"}) + verify(secondPressedSpy.valid) + + var secondMovedSpy = signalSpy.createObject(control, {target: control.second, signalName: "moved"}) + verify(secondMovedSpy.valid) + + // Touch press and release on the left corner + control.setValues(0.2, 0.8) + compare(control.first.value, 0.2) + compare(control.second.value, 0.8) + var touch = touchEvent(control) + touch.press(0, control, 0, control.height * 0.75).commit() + compare(firstPressedSpy.count, 1) + compare(firstMovedSpy.count, 0) + compare(secondPressedSpy.count, 0) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, true) + compare(control.first.value, 0.2) + compare(control.first.position, 0.2) + compare(control.second.pressed, false) + compare(control.second.value, 0.8) + compare(control.second.position, 0.8) + + touch.release(0, control, 0, control.height * 0.75).commit() + compare(firstPressedSpy.count, 2) + compare(firstMovedSpy.count, 1) + compare(secondPressedSpy.count, 0) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, false) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 0.8) + compare(control.second.position, 0.8) + + firstPressedSpy.clear() + firstMovedSpy.clear() + secondPressedSpy.clear() + secondMovedSpy.clear() + + // Touch press and release on the right corner + // On touch, the handle position is updated on release + control.setValues(0.2, 0.8) + compare(control.first.value, 0.2) + compare(control.second.value, 0.8) + var touch = touchEvent(control) + touch.press(0, control, control.width - control.rightPadding - 1, control.height * 0.75).commit() + compare(secondPressedSpy.count, 1) + compare(secondMovedSpy.count, 0) + compare(firstPressedSpy.count, 0) + compare(firstMovedSpy.count, 0) + compare(control.second.pressed, true) + compare(control.second.value, 0.8) + compare(control.second.position, 0.8) + compare(control.first.pressed, false) + compare(control.first.value, 0.2) + compare(control.first.position, 0.2) + + touch.release(0, control, control.width - control.rightPadding - 1, control.height * 0.75).commit() + compare(secondPressedSpy.count, 2) + compare(secondMovedSpy.count, 1) + compare(firstPressedSpy.count, 0) + compare(firstMovedSpy.count, 0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + compare(control.first.pressed, false) + compare(control.first.value, 0.2) + compare(control.first.position, 0.2) + + firstPressedSpy.clear() + firstMovedSpy.clear() + secondPressedSpy.clear() + secondMovedSpy.clear() + + // Mouse press and release on the left corner + // On mouse, the position is immediately updated on press + control.setValues(0.2, 0.8) + compare(control.first.value, 0.2) + compare(control.second.value, 0.8) + mousePress(control, 0, control.height * 0.75, Qt.LeftButton) + compare(firstPressedSpy.count, 1) + compare(firstMovedSpy.count, 1) + compare(secondPressedSpy.count, 0) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, true) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 0.8) + compare(control.second.position, 0.8) + + mouseRelease(control, 0, control.height * 0.75, Qt.LeftButton) + compare(firstPressedSpy.count, 2) + compare(firstMovedSpy.count, 1) + compare(secondPressedSpy.count, 0) + compare(secondMovedSpy.count, 0) + compare(control.first.pressed, false) + compare(control.first.value, 0.0) + compare(control.first.position, 0.0) + compare(control.second.pressed, false) + compare(control.second.value, 0.8) + compare(control.second.position, 0.8) + + firstPressedSpy.clear() + firstMovedSpy.clear() + secondPressedSpy.clear() + secondMovedSpy.clear() + + // Mouse press and release on the right corner + control.setValues(0.2, 0.8) + compare(control.first.value, 0.2) + compare(control.second.value, 0.8) + mousePress(control, control.width - control.rightPadding - 1, control.height * 0.75, Qt.LeftButton) + compare(secondPressedSpy.count, 1) + compare(secondMovedSpy.count, 1) + compare(firstPressedSpy.count, 0) + compare(firstMovedSpy.count, 0) + compare(control.second.pressed, true) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + compare(control.first.pressed, false) + compare(control.first.value, 0.2) + compare(control.first.position, 0.2) + + mouseRelease(control, control.width - control.rightPadding - 1, control.height * 0.75, Qt.LeftButton) + compare(secondPressedSpy.count, 2) + compare(secondMovedSpy.count, 1) + compare(firstPressedSpy.count, 0) + compare(firstMovedSpy.count, 0) + compare(control.second.pressed, false) + compare(control.second.value, 1.0) + compare(control.second.position, 1.0) + compare(control.first.pressed, false) + compare(control.first.value, 0.2) + compare(control.first.position, 0.2) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_roundbutton.qml b/tests/auto/quickcontrols2/controls/data/tst_roundbutton.qml new file mode 100644 index 00000000000..d7a8832ca2f --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_roundbutton.qml @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "RoundButton" + + Component { + id: roundButton + RoundButton { } + } + + function test_radius() { + var control = createTemporaryObject(roundButton, testCase); + verify(control); + + var implicitRadius = control.radius; + compare(implicitRadius, Math.min(control.width, control.height) / 2); + + control.radius = 10; + compare(control.radius, 10); + + control.radius = undefined; + compare(control.radius, implicitRadius); + + control.width = -1; + compare(control.radius, 0); + + control.width = 10; + compare(control.radius, 5); + } + + function test_spacing() { + var control = createTemporaryObject(roundButton, testCase, { text: "Some long, long, long text" }) + verify(control) + verify(control.contentItem.implicitWidth + control.leftPadding + control.rightPadding > control.background.implicitWidth) + + var textLabel = findChild(control.contentItem, "label") + verify(textLabel) + + // The implicitWidth of the IconLabel that all buttons use as their contentItem + // should be equal to the implicitWidth of the Text while no icon is set. + compare(control.contentItem.implicitWidth, textLabel.implicitWidth) + + // That means that spacing shouldn't affect it. + control.spacing += 100 + compare(control.contentItem.implicitWidth, textLabel.implicitWidth) + + // The implicitWidth of the Button itself should, therefore, also never include spacing while no icon is set. + compare(control.implicitWidth, textLabel.implicitWidth + control.leftPadding + control.rightPadding) + } + + function test_display_data() { + return [ + { "tag": "IconOnly", display: RoundButton.IconOnly }, + { "tag": "TextOnly", display: RoundButton.TextOnly }, + { "tag": "TextUnderIcon", display: RoundButton.TextUnderIcon }, + { "tag": "TextBesideIcon", display: RoundButton.TextBesideIcon }, + { "tag": "IconOnly, mirrored", display: RoundButton.IconOnly, mirrored: true }, + { "tag": "TextOnly, mirrored", display: RoundButton.TextOnly, mirrored: true }, + { "tag": "TextUnderIcon, mirrored", display: RoundButton.TextUnderIcon, mirrored: true }, + { "tag": "TextBesideIcon, mirrored", display: RoundButton.TextBesideIcon, mirrored: true } + ] + } + + function test_display(data) { + var control = createTemporaryObject(roundButton, testCase, { + text: "RoundButton", + display: data.display, + "icon.source": "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png", + "LayoutMirroring.enabled": !!data.mirrored + }) + verify(control) + compare(control.icon.source, "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png") + + var iconImage = findChild(control.contentItem, "image") + var textLabel = findChild(control.contentItem, "label") + + switch (control.display) { + case RoundButton.IconOnly: + verify(iconImage) + verify(!textLabel) + compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + break; + case RoundButton.TextOnly: + verify(!iconImage) + verify(textLabel) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + case RoundButton.TextUnderIcon: + verify(iconImage) + verify(textLabel) + compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + verify(iconImage.y < textLabel.y) + break; + case RoundButton.TextBesideIcon: + verify(iconImage) + verify(textLabel) + if (control.mirrored) + verify(textLabel.x < iconImage.x) + else + verify(iconImage.x < textLabel.x) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + } + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_scrollbar.qml b/tests/auto/quickcontrols2/controls/data/tst_scrollbar.qml new file mode 100644 index 00000000000..7753a4cc33e --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_scrollbar.qml @@ -0,0 +1,993 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "ScrollBar" + + Component { + id: signalSpy + SignalSpy { } + } + + Component { + id: scrollBar + ScrollBar { + padding: 0 + minimumSize: 0 + } + } + + Component { + id: scrollBarWithDefaultPadding + ScrollBar { + minimumSize: 0 + } + } + + Component { + id: flickable + Flickable { + width: 100 + height: 100 + contentWidth: 200 + contentHeight: 200 + boundsBehavior: Flickable.StopAtBounds + flickableDirection: Flickable.HorizontalAndVerticalFlick + } + } + + function test_attach() { + var container = createTemporaryObject(flickable, testCase) + verify(container) + waitForRendering(container) + + var vertical = scrollBar.createObject() + verify(!vertical.parent) + compare(vertical.size, 0.0) + compare(vertical.position, 0.0) + compare(vertical.active, false) + compare(vertical.orientation, Qt.Vertical) + compare(vertical.x, 0) + compare(vertical.y, 0) + verify(vertical.width > 0) + verify(vertical.height > 0) + + container.ScrollBar.vertical = vertical + compare(vertical.parent, container) + compare(vertical.orientation, Qt.Vertical) + compare(vertical.size, container.visibleArea.heightRatio) + compare(vertical.position, container.visibleArea.yPosition) + compare(vertical.x, container.width - vertical.width) + compare(vertical.y, 0) + verify(vertical.width > 0) + compare(vertical.height, container.height) + // vertical scroll bar follows flickable's width + container.width += 10 + compare(vertical.x, container.width - vertical.width) + vertical.implicitWidth -= 2 + compare(vertical.x, container.width - vertical.width) + // ...unless explicitly positioned + vertical.x = 123 + container.width += 10 + compare(vertical.x, 123) + + var horizontal = createTemporaryObject(scrollBar, null) + verify(!horizontal.parent) + compare(horizontal.size, 0.0) + compare(horizontal.position, 0.0) + compare(horizontal.active, false) + compare(horizontal.orientation, Qt.Vertical) + compare(horizontal.x, 0) + compare(horizontal.y, 0) + verify(horizontal.width > 0) + verify(horizontal.height > 0) + + container.ScrollBar.horizontal = horizontal + compare(horizontal.parent, container) + compare(horizontal.orientation, Qt.Horizontal) + compare(horizontal.size, container.visibleArea.widthRatio) + compare(horizontal.position, container.visibleArea.xPosition) + compare(horizontal.x, 0) + compare(horizontal.y, container.height - horizontal.height) + compare(horizontal.width, container.width) + verify(horizontal.height > 0) + // horizontal scroll bar follows flickable's height + container.height += 10 + compare(horizontal.y, container.height - horizontal.height) + horizontal.implicitHeight -= 2 + compare(horizontal.y, container.height - horizontal.height) + // ...unless explicitly positioned + horizontal.y = 123 + container.height += 10 + compare(horizontal.y, 123) + + var velocity = container.maximumFlickVelocity + + compare(container.flicking, false) + container.flick(-velocity, -velocity) + compare(container.flicking, true) + tryCompare(container, "flicking", false) + + compare(vertical.size, container.visibleArea.heightRatio) + compare(vertical.position, container.visibleArea.yPosition) + compare(horizontal.size, container.visibleArea.widthRatio) + compare(horizontal.position, container.visibleArea.xPosition) + + compare(container.flicking, false) + container.flick(velocity, velocity) + compare(container.flicking, true) + tryCompare(container, "flicking", false) + + compare(vertical.size, container.visibleArea.heightRatio) + compare(vertical.position, container.visibleArea.yPosition) + compare(horizontal.size, container.visibleArea.widthRatio) + compare(horizontal.position, container.visibleArea.xPosition) + + var oldY = vertical.y + var oldHeight = vertical.height + vertical.parent = testCase + vertical.y -= 10 + container.height += 10 + compare(vertical.y, oldY - 10) + compare(vertical.height, oldHeight) + + var oldX = horizontal.x + var oldWidth = horizontal.width + horizontal.parent = testCase + horizontal.x -= 10 + container.width += 10 + compare(horizontal.x, oldX - 10) + compare(horizontal.width, oldWidth) + } + + function test_attachTwice() { + let container = createTemporaryObject(flickable, testCase) + verify(container) + waitForRendering(container) + + container.ScrollBar.vertical = scrollBar.createObject(container, { objectName: "oldVerticalScrollBar" }) + verify(container.ScrollBar.vertical) + let oldVerticalScrollBar = findChild(container, "oldVerticalScrollBar") + verify(oldVerticalScrollBar) + verify(oldVerticalScrollBar.visible) + + container.ScrollBar.horizontal = scrollBar.createObject(container, { objectName: "oldHorizontalScrollBar" }) + verify(container.ScrollBar.horizontal) + let oldHorizontalScrollBar = findChild(container, "oldHorizontalScrollBar") + verify(oldHorizontalScrollBar) + verify(oldHorizontalScrollBar.visible) + + container.ScrollBar.vertical = scrollBar.createObject(container, { objectName: "newVerticalScrollBar" }) + let newVerticalScrollBar = findChild(container, "newVerticalScrollBar") + verify(newVerticalScrollBar) + verify(newVerticalScrollBar.visible) + verify(!oldVerticalScrollBar.visible) + + container.ScrollBar.horizontal = scrollBar.createObject(container, { objectName: "newHorizontalScrollBar" }) + let newHorizontalScrollBar = findChild(container, "newHorizontalScrollBar") + verify(newHorizontalScrollBar) + verify(newHorizontalScrollBar.visible) + verify(!oldHorizontalScrollBar.visible) + } + + function getGrooveRange(scrollbar) { + return { + start: { // top left + x: scrollbar.orientation === Qt.Horizontal ? scrollbar.leftPadding : 0, + y: scrollbar.orientation === Qt.Vertical ? scrollbar.topPadding : 0 + }, + end: { // bottom right, (inclusive, last pixel position of the groove) + x: (scrollbar.orientation === Qt.Horizontal ? scrollbar.width - scrollbar.rightPadding : scrollbar.width) - 1, + y: (scrollbar.orientation === Qt.Vertical ? scrollbar.height - scrollbar.bottomPadding : scrollbar.height) - 1 + }, + width : scrollbar.width - scrollbar.leftPadding - scrollbar.rightPadding, + height: scrollbar.height - scrollbar.topPadding - scrollbar.bottomPadding + } + } + + function test_mouse_data() { + return [ + { tag: "horizontal", properties: { visible: true, orientation: Qt.Horizontal, width: testCase.width } }, + { tag: "vertical", properties: { visible: true, orientation: Qt.Vertical, height: testCase.height } } + ] + } + + function test_mouse(data) { + var control = createTemporaryObject(scrollBarWithDefaultPadding, testCase, data.properties) + verify(control) + + var grooveRange = getGrooveRange(control) + + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) + verify(pressedSpy.valid) + + mousePress(control, grooveRange.start.x, grooveRange.start.y, Qt.LeftButton) + compare(pressedSpy.count, 1) + compare(control.pressed, true) + compare(control.position, 0.0) + + mouseMove(control, -control.width, -control.height, 0) + compare(pressedSpy.count, 1) + compare(control.pressed, true) + compare(control.position, 0.0) + + mouseMove(control, control.width * 0.5, control.height * 0.5, 0) + compare(pressedSpy.count, 1) + compare(control.pressed, true) + verify(control.position, 0.5) + + mouseRelease(control, control.width * 0.5, control.height * 0.5, Qt.LeftButton) + compare(pressedSpy.count, 2) + compare(control.pressed, false) + compare(control.position, 0.5) + + mousePress(control, grooveRange.end.x, grooveRange.end.y, Qt.LeftButton) + compare(pressedSpy.count, 3) + compare(control.pressed, true) + // We can't click on right and bottom edge, so click to (grooveRange.end), + // and move mouse to (grooveRange.end.x + 1, grooveRange.end.y + 1) + mouseMove(control, grooveRange.end.x + 1, grooveRange.end.y + 1, 0) + compare(control.position, 1.0) + + mouseMove(control, control.width * 2, control.height * 2, 0) + compare(pressedSpy.count, 3) + compare(control.pressed, true) + compare(control.position, 1.0) + + mouseMove(control, grooveRange.start.x + grooveRange.width * 0.75, grooveRange.start.y + grooveRange.height * 0.75, 0) + compare(pressedSpy.count, 3) + compare(control.pressed, true) + fuzzyCompare(control.position, 0.75, 0.01) + + mouseRelease(control, grooveRange.start.x + grooveRange.width * 0.25, grooveRange.start.y + grooveRange.height * 0.25, Qt.LeftButton) + compare(pressedSpy.count, 4) + compare(control.pressed, false) + fuzzyCompare(control.position, 0.25, 0.01) + + if (control.__decreaseVisual.indicator !== null) { + var p = control.__decreaseVisual.indicator.mapToItem(control, Qt.point(0, 0)) + mousePress(control, p.x, p.y, Qt.LeftButton) + compare(pressedSpy.count, 4) + compare(control.pressed, false) + compare(control.__decreaseVisual.pressed, true) + fuzzyCompare(control.position, 0.15, 0.01) + mouseRelease(control.__decreaseVisual.indicator, 0, 0, Qt.LeftButton) + compare(control.__decreaseVisual.pressed, false) + + p = control.__increaseVisual.indicator.mapToItem(control, Qt.point(0, 0)) + mousePress(control, p.x, p.y, Qt.LeftButton) + compare(pressedSpy.count, 4) + compare(control.pressed, false) + compare(control.__increaseVisual.pressed, true) + fuzzyCompare(control.position, 0.25, 0.01) + mouseRelease(control.__increaseVisual.indicator, 0, 0, Qt.LeftButton) + compare(control.__increaseVisual.pressed, false) + } + } + + function test_touch_data() { + return [ + { tag: "horizontal", properties: { visible: true, orientation: Qt.Horizontal, width: testCase.width } }, + { tag: "vertical", properties: { visible: true, orientation: Qt.Vertical, height: testCase.height } } + ] + } + + function test_touch(data) { + var control = createTemporaryObject(scrollBar, testCase, data.properties) + verify(control) + + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) + verify(pressedSpy.valid) + + control.width += (control.leftPadding + control.rightPadding) + control.height += (control.topPadding + control.bottomPadding) + var availableSlideWidth = 0 + var availableSlideHeight = 0 + + var p0 = {} + if (control.orientation === Qt.Horizontal) { + availableSlideWidth = control.width - control.rightPadding - control.leftPadding + p0 = { x = control.leftPadding, y = control.height/2 } + } else { + availableSlideHeight = control.height - control.bottomPadding - control.topPadding + p0 = { x = control.width/2, y = control.topPadding} + } + + var touch = touchEvent(control) + + touch.press(0, control, p0.x, p0.y).commit() + compare(pressedSpy.count, 1) + compare(control.pressed, true) + compare(control.position, 0.0) + + touch.move(0, control, -control.width, -control.height).commit() + compare(pressedSpy.count, 1) + compare(control.pressed, true) + compare(control.position, 0.0) + + touch.move(0, control, p0.x + availableSlideWidth * 0.5, p0.y + availableSlideHeight * 0.5).commit() + compare(pressedSpy.count, 1) + compare(control.pressed, true) + verify(control.position, 0.5) + + touch.release(0, control, p0.x + availableSlideWidth * 0.5, p0.y + availableSlideHeight * 0.5).commit() + compare(pressedSpy.count, 2) + compare(control.pressed, false) + compare(control.position, 0.5) + + touch.press(0, control, p0.x + availableSlideWidth - 1, p0.y + availableSlideHeight - 1).commit() + compare(pressedSpy.count, 3) + compare(control.pressed, true) + compare(control.position, 0.5) + + touch.move(0, control, control.width * 2, control.height * 2).commit() + compare(pressedSpy.count, 3) + compare(control.pressed, true) + compare(control.position, 1.0) + + touch.move(0, control, p0.x + availableSlideWidth * 0.75, p0.y + availableSlideHeight * 0.75).commit() + compare(pressedSpy.count, 3) + compare(control.pressed, true) + compare(control.position, 0.75) + + touch.release(0, control, p0.x + availableSlideWidth * 0.25, p0.y + availableSlideHeight * 0.25).commit() + compare(pressedSpy.count, 4) + compare(control.pressed, false) + compare(control.position, 0.25) + } + + function test_multiTouch() { + var control1 = createTemporaryObject(scrollBar, testCase) + verify(control1) + + control1.height = 200 + (control1.topPadding + control1.bottomPadding) + + var grooveRange = getGrooveRange(control1) + + var pressedCount1 = 0 + var movedCount1 = 0 + + var pressedSpy1 = signalSpy.createObject(control1, {target: control1, signalName: "pressedChanged"}) + verify(pressedSpy1.valid) + + var positionSpy1 = signalSpy.createObject(control1, {target: control1, signalName: "positionChanged"}) + verify(positionSpy1.valid) + + var touch = touchEvent(control1) + touch.press(0, control1, grooveRange.start.x, grooveRange.start.y).commit().move(0, control1, grooveRange.end.x+1, grooveRange.end.y+1).commit() + + compare(pressedSpy1.count, ++pressedCount1) + compare(positionSpy1.count, ++movedCount1) + compare(control1.pressed, true) + compare(control1.position, 1.0) + + // second touch point on the same control is ignored + touch.stationary(0).press(1, control1, grooveRange.start.x, grooveRange.start.y).commit() + touch.stationary(0).move(1).commit() + touch.stationary(0).release(1).commit() + + compare(pressedSpy1.count, pressedCount1) + compare(positionSpy1.count, movedCount1) + compare(control1.pressed, true) + compare(control1.position, 1.0) + + var control2 = createTemporaryObject(scrollBar, testCase, {y: control1.height}) + verify(control2) + control2.height = 200 + (control2.topPadding + control2.bottomPadding) + + var pressedCount2 = 0 + var movedCount2 = 0 + + var pressedSpy2 = signalSpy.createObject(control2, {target: control2, signalName: "pressedChanged"}) + verify(pressedSpy2.valid) + + var positionSpy2 = signalSpy.createObject(control2, {target: control2, signalName: "positionChanged"}) + verify(positionSpy2.valid) + + // press the second scrollbar + touch.stationary(0).press(2, control2, grooveRange.start.x, grooveRange.start.y).commit() + + compare(pressedSpy2.count, ++pressedCount2) + compare(positionSpy2.count, movedCount2) + compare(control2.pressed, true) + compare(control2.position, 0.0) + + compare(pressedSpy1.count, pressedCount1) + compare(positionSpy1.count, movedCount1) + compare(control1.pressed, true) + compare(control1.position, 1.0) + + // move both scrollbars + touch.move(0, control1).move(2, control2).commit() + + compare(pressedSpy2.count, pressedCount2) + compare(positionSpy2.count, ++movedCount2) + compare(control2.pressed, true) + compare(control2.position, 0.5) + + compare(pressedSpy1.count, pressedCount1) + compare(positionSpy1.count, ++movedCount1) + compare(control1.pressed, true) + compare(control1.position, 0.5) + + // release both scrollbars + touch.release(0, control1).release(2, control2).commit() + + compare(pressedSpy2.count, ++pressedCount2) + compare(positionSpy2.count, movedCount2) + compare(control2.pressed, false) + compare(control2.position, 0.5) + + compare(pressedSpy1.count, ++pressedCount1) + compare(positionSpy1.count, movedCount1) + compare(control1.pressed, false) + compare(control1.position, 0.5) + } + + function test_increase_decrease_data() { + return [ + { tag: "increase:active", increase: true, active: true }, + { tag: "decrease:active", increase: false, active: true }, + { tag: "increase:inactive", increase: true, active: false }, + { tag: "decrease:inactive", increase: false, active: false } + ] + } + + function test_increase_decrease(data) { + var control = createTemporaryObject(scrollBar, testCase, {position: 0.5, active: data.active}) + verify(control) + + if (data.increase) { + control.increase() + compare(control.position, 0.6) + } else { + control.decrease() + compare(control.position, 0.4) + } + compare(control.active, data.active) + } + + function test_stepSize_data() { + return [ + { tag: "0.0", stepSize: 0.0 }, + { tag: "0.1", stepSize: 0.1 }, + { tag: "0.5", stepSize: 0.5 } + ] + } + + function test_stepSize(data) { + var control = createTemporaryObject(scrollBar, testCase, {stepSize: data.stepSize}) + verify(control) + + compare(control.stepSize, data.stepSize) + compare(control.position, 0.0) + + var count = 10 + if (data.stepSize !== 0.0) + count = 1.0 / data.stepSize + + // increase until 1.0 + for (var i = 1; i <= count; ++i) { + control.increase() + compare(control.position, i / count) + } + control.increase() + compare(control.position, 1.0) + + // decrease until 0.0 + for (var d = count - 1; d >= 0; --d) { + control.decrease() + compare(control.position, d / count) + } + control.decrease() + compare(control.position, 0.0) + } + + function test_padding_data() { + return [ + { tag: "horizontal", properties: { visible: true, orientation: Qt.Horizontal, width: testCase.width, leftPadding: testCase.width * 0.1 } }, + { tag: "vertical", properties: { visible: true, orientation: Qt.Vertical, height: testCase.height, topPadding: testCase.height * 0.1 } } + ] + } + + function test_padding(data) { + var control = createTemporaryObject(scrollBar, testCase, data.properties) + + mousePress(control, control.leftPadding + control.availableWidth * 0.5, control.topPadding + control.availableHeight * 0.5, Qt.LeftButton) + mouseRelease(control, control.leftPadding + control.availableWidth * 0.5, control.topPadding + control.availableHeight * 0.5, Qt.LeftButton) + + compare(control.position, 0.5) + } + + function test_warning() { + ignoreWarning(Qt.resolvedUrl("tst_scrollbar.qml") + ":55:1: QML TestCase: ScrollBar must be attached to a Flickable or ScrollView") + testCase.ScrollBar.vertical = null + } + + function test_mirrored() { + var container = createTemporaryObject(flickable, testCase) + verify(container) + waitForRendering(container) + + container.ScrollBar.vertical = scrollBar.createObject(container) + compare(container.ScrollBar.vertical.x, container.width - container.ScrollBar.vertical.width) + container.ScrollBar.vertical.locale = Qt.locale("ar_EG") + compare(container.ScrollBar.vertical.x, container.width - container.ScrollBar.vertical.width) + } + + function test_hover_data() { + return [ + { tag: "enabled", hoverEnabled: true, interactive: true }, + { tag: "disabled", hoverEnabled: false, interactive: true }, + { tag: "non-interactive", hoverEnabled: true, interactive: false } + ] + } + + function test_hover(data) { + var control = createTemporaryObject(scrollBar, testCase, {hoverEnabled: data.hoverEnabled, interactive: data.interactive}) + verify(control) + + compare(control.hovered, false) + + mouseMove(control, control.width / 2, control.height / 2) + compare(control.hovered, data.hoverEnabled) + compare(control.active, data.hoverEnabled && data.interactive) + + mouseMove(control, -1, -1) + compare(control.hovered, false) + compare(control.active, false) + } + + function test_snapMode_data() { + return [ + { tag: "NoSnap", snapMode: ScrollBar.NoSnap, stepSize: 0.1, size: 0.2, width: 100, steps: 80 }, /* 0.8*100 */ + { tag: "NoSnap2", snapMode: ScrollBar.NoSnap, stepSize: 0.2, size: 0.1, width: 200, steps: 180 }, /* 0.9*200 */ + + { tag: "SnapAlways", snapMode: ScrollBar.SnapAlways, stepSize: 0.1, size: 0.2, width: 100, steps: 10 }, + { tag: "SnapAlways2", snapMode: ScrollBar.SnapAlways, stepSize: 0.2, size: 0.125, width: 200, steps: 5 }, + + { tag: "SnapOnRelease", snapMode: ScrollBar.SnapOnRelease, stepSize: 0.1, size: 0.2, width: 100, steps: 80 }, /* 0.8*100 */ + { tag: "SnapOnRelease2", snapMode: ScrollBar.SnapOnRelease, stepSize: 0.2, size: 0.1, width: 200, steps: 180 }, /* 0.9*200 */ + ] + } + + function test_snapMode_mouse_data() { + return test_snapMode_data() + } + + function test_snapMode_mouse(data) { + var control = createTemporaryObject(scrollBar, testCase, {snapMode: data.snapMode, orientation: Qt.Horizontal, stepSize: data.stepSize, size: data.size, width: data.width}) + verify(control) + // In case the slider is surrounded with decrease/increase buttons + // Adjust slider width so that slider area is a whole number (to avoid rounding errors) + control.width += control.leftPadding + control.rightPadding + + function snappedPosition(pos) { + var effectiveStep = control.stepSize * (1.0 - control.size) + return Math.round(pos / effectiveStep) * effectiveStep + } + + function boundPosition(pos) { + return Math.max(0, Math.min(pos, 1.0 - control.size)) + } + + var minHandlePos = control.leftPadding + var maxHandlePos = control.width - control.rightPadding + var availableSlideWidth = maxHandlePos - minHandlePos + mousePress(control, minHandlePos, 0) + compare(control.position, 0) + + mouseMove(control, minHandlePos + availableSlideWidth * 0.3, 0) + var expectedMovePos = 0.3 + if (control.snapMode === ScrollBar.SnapAlways) { + expectedMovePos = snappedPosition(expectedMovePos) + verify(expectedMovePos !== 0.3) + } + compare(control.position, expectedMovePos) + + mouseRelease(control, minHandlePos + availableSlideWidth * 0.75, 0) + var expectedReleasePos = 0.75 + if (control.snapMode !== ScrollBar.NoSnap) { + expectedReleasePos = snappedPosition(expectedReleasePos) + verify(expectedReleasePos !== 0.75) + } + compare(control.position, expectedReleasePos) + + control.position = 0 + mousePress(control, minHandlePos, 0) + + var steps = 0 + var prevPos = 0 + + for (var x = minHandlePos; x < maxHandlePos; ++x) { + mouseMove(control, x, 0) + expectedMovePos = boundPosition((x - minHandlePos) / availableSlideWidth) + if (control.snapMode === ScrollBar.SnapAlways) + expectedMovePos = snappedPosition(expectedMovePos) + compare(control.position, expectedMovePos) + + if (control.position !== prevPos) + ++steps + prevPos = control.position + } + compare(steps, data.steps) + + mouseRelease(control, maxHandlePos - 1, 0) + } + + function test_snapMode_touch_data() { + return test_snapMode_data() + } + + function test_snapMode_touch(data) { + var control = createTemporaryObject(scrollBar, testCase, {snapMode: data.snapMode, orientation: Qt.Horizontal, stepSize: data.stepSize, size: data.size, width: data.width}) + verify(control) + // In case the slider is surrounded with decrease/increase buttons + // Adjust slider width so that slider area is a whole number (to avoid rounding errors) + control.width += control.leftPadding + control.rightPadding + + function snappedPosition(pos) { + var effectiveStep = control.stepSize * (1.0 - control.size) + return Math.round(pos / effectiveStep) * effectiveStep + } + + function boundPosition(pos) { + return Math.max(0, Math.min(pos, 1.0 - control.size)) + } + + var touch = touchEvent(control) + + var minHandlePos = control.leftPadding + var maxHandlePos = control.width - control.rightPadding + var availableSlideWidth = maxHandlePos - minHandlePos + touch.press(0, control, minHandlePos, 0).commit() + compare(control.position, 0) + + touch.move(0, control, minHandlePos + availableSlideWidth*0.3, 0).commit() + var expectedMovePos = 0.3 + if (control.snapMode === ScrollBar.SnapAlways) { + expectedMovePos = snappedPosition(expectedMovePos) + verify(expectedMovePos !== 0.3) + } + compare(control.position, expectedMovePos) + + touch.release(0, control, minHandlePos + availableSlideWidth*0.75, 0).commit() + var expectedReleasePos = 0.75 + if (control.snapMode !== ScrollBar.NoSnap) { + expectedReleasePos = snappedPosition(expectedReleasePos) + verify(expectedReleasePos !== 0.75) + } + compare(control.position, expectedReleasePos) + + control.position = 0 + touch.press(0, control, minHandlePos, 0).commit() + + var steps = 0 + var prevPos = 0 + + for (var x = minHandlePos; x < maxHandlePos; ++x) { + touch.move(0, control, x, 0).commit() + expectedMovePos = boundPosition((x - minHandlePos) / availableSlideWidth) + if (control.snapMode === ScrollBar.SnapAlways) + expectedMovePos = snappedPosition(expectedMovePos) + compare(control.position, expectedMovePos) + + if (control.position !== prevPos) + ++steps + prevPos = control.position + } + compare(steps, data.steps) + + touch.release(0, control, maxHandlePos - 1).commit() + } + + function test_interactive_data() { + return [ + { tag: "true", interactive: true }, + { tag: "false", interactive: false } + ] + } + + function test_interactive(data) { + var control = createTemporaryObject(scrollBar, testCase, {interactive: data.interactive}) + verify(control) + + compare(control.interactive, data.interactive) + // 200 pixels tall to avoid rounding errors further on + control.height = 200 + (control.topPadding + control.bottomPadding) + + // press-move-release + mousePress(control, control.width/2, control.topPadding, Qt.LeftButton) + compare(control.pressed, data.interactive) + + mouseMove(control, control.width / 2, control.height / 2) + compare(control.position, data.interactive ? 0.5 : 0.0) + + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, false) + + // change to non-interactive while pressed + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, data.interactive) + + mouseMove(control, control.width, control.height) + compare(control.position, data.interactive ? 1.0 : 0.0) + + control.interactive = false + compare(control.interactive, false) + compare(control.pressed, false) + + mouseMove(control, control.width / 2, control.height / 2) + compare(control.position, data.interactive ? 1.0 : 0.0) + + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, false) + + // change back to interactive & try press-move-release again + control.interactive = true + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + + mouseMove(control, 0, 0) + compare(control.position, 0.0) + + mouseRelease(control, 0, 0, Qt.LeftButton) + compare(control.pressed, false) + } + + function test_policy() { + var control = createTemporaryObject(scrollBar, testCase, {active: true}) + verify(control) + + compare(ScrollBar.AsNeeded, Qt.ScrollBarAsNeeded) + compare(ScrollBar.AlwaysOff, Qt.ScrollBarAlwaysOff) + compare(ScrollBar.AlwaysOn, Qt.ScrollBarAlwaysOn) + + compare(control.visible, true) + compare(control.policy, ScrollBar.AsNeeded) + + if (Qt.platform.pluginName !== "windows") { + control.size = 0.5 + verify(control.state === "active" || control.contentItem.state === "active") + + control.size = 1.0 + verify(control.state !== "active" && control.contentItem.state !== "active") + } + control.policy = ScrollBar.AlwaysOff + compare(control.visible, false) + + control.policy = ScrollBar.AlwaysOn + compare(control.visible, true) + if (Qt.platform.pluginName !== "windows") { + verify(control.state === "active" || control.contentItem.state === "active") + } + } + + function test_overshoot() { + var container = createTemporaryObject(flickable, testCase) + verify(container) + waitForRendering(container) + + var vertical = scrollBar.createObject(container, {size: 0.5}) + container.ScrollBar.vertical = vertical + + var horizontal = scrollBar.createObject(container, {size: 0.5}) + container.ScrollBar.horizontal = horizontal + + // negative vertical overshoot (pos < 0) + vertical.position = -0.1 + compare(vertical.contentItem.y, vertical.topPadding) + compare(vertical.contentItem.height, 0.4 * vertical.availableHeight) + + // positive vertical overshoot (pos + size > 1) + vertical.position = 0.8 + compare(vertical.contentItem.y, vertical.topPadding + 0.8 * vertical.availableHeight) + compare(vertical.contentItem.height, 0.2 * vertical.availableHeight) + + // negative horizontal overshoot (pos < 0) + horizontal.position = -0.1 + compare(horizontal.contentItem.x, horizontal.leftPadding) + compare(horizontal.contentItem.width, 0.4 * horizontal.availableWidth) + + // positive horizontal overshoot (pos + size > 1) + horizontal.position = 0.8 + compare(horizontal.contentItem.x, horizontal.leftPadding + 0.8 * horizontal.availableWidth) + compare(horizontal.contentItem.width, 0.2 * horizontal.availableWidth) + } + + function test_orientation() { + var control = createTemporaryObject(scrollBar, testCase) + verify(control) + + compare(control.orientation, Qt.Vertical) + compare(control.horizontal, false) + compare(control.vertical, true) + + control.orientation = Qt.Horizontal + compare(control.orientation, Qt.Horizontal) + compare(control.horizontal, true) + compare(control.vertical, false) + } + + function test_flashing() { + var control = createTemporaryObject(scrollBar, testCase, {size: 0.2}) + verify(control) + + var activeSpy = signalSpy.createObject(control, {target: control, signalName: "activeChanged"}) + verify(activeSpy.valid) + + compare(control.active, false) + if (control.contentItem && control.contentItem.opacity > 0) + // Slider handle is always visible in this style (Windows style) + return + + if (control.contentItem) + compare(control.contentItem.opacity, 0) + if (control.background) + compare(control.background.opacity, 0) + + control.increase() + compare(control.position, 0.1) + compare(control.active, false) + compare(activeSpy.count, 2) + if (control.contentItem) + verify(control.contentItem.opacity > 0) + if (control.background) + verify(control.background.opacity > 0) + if (control.contentItem) + tryCompare(control.contentItem, "opacity", 0) + if (control.background) + tryCompare(control.background, "opacity", 0) + + control.decrease() + compare(control.position, 0.0) + compare(control.active, false) + compare(activeSpy.count, 4) + if (control.contentItem) + verify(control.contentItem.opacity > 0) + if (control.background) + verify(control.background.opacity > 0) + if (control.contentItem) + tryCompare(control.contentItem, "opacity", 0) + if (control.background) + tryCompare(control.background, "opacity", 0) + } + + function test_minimumSize() { + var container = createTemporaryObject(flickable, testCase) + verify(container) + waitForRendering(container) + + var vertical = scrollBar.createObject(container, {minimumSize: 0.1}) + container.ScrollBar.vertical = vertical + + compare(container.visibleArea.heightRatio, 0.5) + compare(vertical.size, 0.5) + compare(vertical.visualSize, 0.5) + compare(vertical.contentItem.height, 0.5 * vertical.availableHeight) + + container.contentHeight = 2000 + + compare(container.visibleArea.heightRatio, 0.05) + compare(vertical.size, 0.05) + compare(vertical.visualSize, 0.1) + compare(vertical.contentItem.height, 0.1 * vertical.availableHeight) + + verify(container.atYBeginning) + compare(container.visibleArea.yPosition, 0.0) + compare(vertical.position, 0.0) + compare(vertical.visualPosition, 0.0) + compare(vertical.contentItem.y, vertical.topPadding) + + container.contentY = 1900 + + verify(container.atYEnd) + compare(container.visibleArea.yPosition, 0.95) + compare(vertical.position, 0.95) + compare(vertical.visualPosition, 0.9) + compare(vertical.contentItem.y, vertical.topPadding + 0.9 * vertical.availableHeight) + + container.contentHeight = 125 + + compare(container.visibleArea.heightRatio, 0.8) + compare(vertical.size, 0.8) + compare(vertical.visualSize, 0.8) + compare(vertical.contentItem.height, 0.8 * vertical.availableHeight) + + verify(container.atYEnd) + compare(container.visibleArea.yPosition, 0.2) + compare(vertical.position, 0.2) + compare(vertical.visualPosition, 0.2) + compare(vertical.contentItem.y, vertical.topPadding + 0.2 * vertical.availableHeight) + } + + function test_setting_invalid_property_values() { + var control = createTemporaryObject(scrollBar, testCase, {size: 2.0, minimumSize: -1.0}) + verify(control) + + // check that the values are within the expected range + compare(control.size, 1.0) + compare(control.minimumSize, 0) + + control.minimumSize = 2.0 + compare(control.minimumSize, 1.0) + + // test if setting NaN is prevented + control.size = NaN + control.minimumSize = NaN + compare(control.size, 1.0) + compare(control.minimumSize, 1.0) + + + // test if setting float infinity is prevented + control.size = Number.POSITIVE_INFINITY + control.minimumSize = Number.POSITIVE_INFINITY + compare(control.size, 1.0) + compare(control.minimumSize, 1.0) + + let oldPosition = control.position; + let oldStepSize = control.stepSize; + + control.position = NaN; + control.stepSize = NaN; + + compare(oldPosition, control.position) + compare(oldStepSize, control.stepSize) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_scrollindicator.qml b/tests/auto/quickcontrols2/controls/data/tst_scrollindicator.qml new file mode 100644 index 00000000000..363048c0bd4 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_scrollindicator.qml @@ -0,0 +1,309 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "ScrollIndicator" + + Component { + id: scrollIndicator + ScrollIndicator { } + } + + Component { + id: mouseArea + MouseArea { } + } + + Component { + id: flickable + Flickable { + width: 100 + height: 100 + contentWidth: 200 + contentHeight: 200 + boundsBehavior: Flickable.StopAtBounds + flickableDirection: Flickable.HorizontalAndVerticalFlick + } + } + + function test_attach() { + var container = createTemporaryObject(flickable, testCase) + verify(container) + waitForRendering(container) + + var vertical = createTemporaryObject(scrollIndicator, null) + verify(!vertical.parent) + compare(vertical.size, 0.0) + compare(vertical.position, 0.0) + compare(vertical.active, false) + compare(vertical.orientation, Qt.Vertical) + compare(vertical.x, 0) + compare(vertical.y, 0) + verify(vertical.width > 0) + verify(vertical.height > 0) + + container.ScrollIndicator.vertical = vertical + compare(vertical.parent, container) + compare(vertical.orientation, Qt.Vertical) + compare(vertical.size, container.visibleArea.heightRatio) + compare(vertical.position, container.visibleArea.yPosition) + compare(vertical.x, container.width - vertical.width) + compare(vertical.y, 0) + verify(vertical.width > 0) + compare(vertical.height, container.height) + // vertical scroll indicator follows flickable's width + container.width += 10 + compare(vertical.x, container.width - vertical.width) + vertical.implicitWidth -= 1 + compare(vertical.x, container.width - vertical.width) + // ...unless explicitly positioned + vertical.x = 123 + container.width += 10 + compare(vertical.x, 123) + + var horizontal = createTemporaryObject(scrollIndicator, null) + verify(!horizontal.parent) + compare(horizontal.size, 0.0) + compare(horizontal.position, 0.0) + compare(horizontal.active, false) + compare(horizontal.orientation, Qt.Vertical) + compare(horizontal.x, 0) + compare(horizontal.y, 0) + verify(horizontal.width > 0) + verify(horizontal.height > 0) + + container.ScrollIndicator.horizontal = horizontal + compare(horizontal.parent, container) + compare(horizontal.orientation, Qt.Horizontal) + compare(horizontal.size, container.visibleArea.widthRatio) + compare(horizontal.position, container.visibleArea.xPosition) + compare(horizontal.x, 0) + compare(horizontal.y, container.height - horizontal.height) + compare(horizontal.width, container.width) + verify(horizontal.height > 0) + // horizontal scroll indicator follows flickable's height + container.height += 10 + compare(horizontal.y, container.height - horizontal.height) + horizontal.implicitHeight -= 1 + compare(horizontal.y, container.height - horizontal.height) + // ...unless explicitly positioned + horizontal.y = 123 + container.height += 10 + compare(horizontal.y, 123) + + var velocity = container.maximumFlickVelocity + + compare(container.flicking, false) + container.flick(-velocity, -velocity) + compare(container.flicking, true) + tryCompare(container, "flicking", false) + + compare(vertical.size, container.visibleArea.heightRatio) + compare(vertical.position, container.visibleArea.yPosition) + compare(horizontal.size, container.visibleArea.widthRatio) + compare(horizontal.position, container.visibleArea.xPosition) + + compare(container.flicking, false) + container.flick(velocity, velocity) + compare(container.flicking, true) + tryCompare(container, "flicking", false) + + compare(vertical.size, container.visibleArea.heightRatio) + compare(vertical.position, container.visibleArea.yPosition) + compare(horizontal.size, container.visibleArea.widthRatio) + compare(horizontal.position, container.visibleArea.xPosition) + + var oldY = vertical.y + var oldHeight = vertical.height + vertical.parent = testCase + vertical.y -= 10 + container.height += 10 + compare(vertical.y, oldY - 10) + compare(vertical.height, oldHeight) + + var oldX = horizontal.x + var oldWidth = horizontal.width + horizontal.parent = testCase + horizontal.x -= 10 + container.width += 10 + compare(horizontal.x, oldX - 10) + compare(horizontal.width, oldWidth) + } + + function test_warning() { + ignoreWarning(/QML TestCase: ScrollIndicator must be attached to a Flickable/) + testCase.ScrollIndicator.vertical = null + } + + function test_overshoot() { + var container = createTemporaryObject(flickable, testCase) + verify(container) + waitForRendering(container) + + var vertical = scrollIndicator.createObject(container, {size: 0.5}) + container.ScrollIndicator.vertical = vertical + + var horizontal = scrollIndicator.createObject(container, {size: 0.5}) + container.ScrollIndicator.horizontal = horizontal + + // negative vertical overshoot (pos < 0) + vertical.position = -0.1 + compare(vertical.contentItem.y, vertical.topPadding) + compare(vertical.contentItem.height, 0.4 * vertical.availableHeight) + + // positive vertical overshoot (pos + size > 1) + vertical.position = 0.8 + compare(vertical.contentItem.y, vertical.topPadding + 0.8 * vertical.availableHeight) + compare(vertical.contentItem.height, 0.2 * vertical.availableHeight) + + // negative horizontal overshoot (pos < 0) + horizontal.position = -0.1 + compare(horizontal.contentItem.x, horizontal.leftPadding) + compare(horizontal.contentItem.width, 0.4 * horizontal.availableWidth) + + // positive horizontal overshoot (pos + size > 1) + horizontal.position = 0.8 + compare(horizontal.contentItem.x, horizontal.leftPadding + 0.8 * horizontal.availableWidth) + compare(horizontal.contentItem.width, 0.2 * horizontal.availableWidth) + } + + function test_orientation() { + var control = createTemporaryObject(scrollIndicator, testCase) + verify(control) + + compare(control.orientation, Qt.Vertical) + compare(control.horizontal, false) + compare(control.vertical, true) + + control.orientation = Qt.Horizontal + compare(control.orientation, Qt.Horizontal) + compare(control.horizontal, true) + compare(control.vertical, false) + } + + // QTBUG-61785 + function test_mouseArea() { + var ma = createTemporaryObject(mouseArea, testCase, {width: testCase.width, height: testCase.height}) + verify(ma) + + var control = scrollIndicator.createObject(ma, {active: true, size: 0.9, width: testCase.width, height: testCase.height}) + verify(control) + + mousePress(control) + verify(ma.pressed) + + mouseRelease(control) + verify(!ma.pressed) + + var touch = touchEvent(control) + touch.press(0, control).commit() + verify(ma.pressed) + + touch.release(0, control).commit() + verify(!ma.pressed) + } + + function test_minimumSize() { + var container = createTemporaryObject(flickable, testCase) + verify(container) + waitForRendering(container) + + var vertical = scrollIndicator.createObject(container, {minimumSize: 0.1}) + container.ScrollIndicator.vertical = vertical + + compare(container.visibleArea.heightRatio, 0.5) + compare(vertical.size, 0.5) + compare(vertical.visualSize, 0.5) + compare(vertical.contentItem.height, 0.5 * vertical.availableHeight) + + container.contentHeight = 2000 + + compare(container.visibleArea.heightRatio, 0.05) + compare(vertical.size, 0.05) + compare(vertical.visualSize, 0.1) + compare(vertical.contentItem.height, 0.1 * vertical.availableHeight) + + verify(container.atYBeginning) + compare(container.visibleArea.yPosition, 0.0) + compare(vertical.position, 0.0) + compare(vertical.visualPosition, 0.0) + compare(vertical.contentItem.y, vertical.topPadding) + + container.contentY = 1900 + + verify(container.atYEnd) + compare(container.visibleArea.yPosition, 0.95) + compare(vertical.position, 0.95) + compare(vertical.visualPosition, 0.9) + compare(vertical.contentItem.y, vertical.topPadding + 0.9 * vertical.availableHeight) + + container.contentHeight = 125 + + compare(container.visibleArea.heightRatio, 0.8) + compare(vertical.size, 0.8) + compare(vertical.visualSize, 0.8) + compare(vertical.contentItem.height, 0.8 * vertical.availableHeight) + + verify(container.atYEnd) + compare(container.visibleArea.yPosition, 0.2) + compare(vertical.position, 0.2) + compare(vertical.visualPosition, 0.2) + compare(vertical.contentItem.y, vertical.topPadding + 0.2 * vertical.availableHeight) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_scrollview.qml b/tests/auto/quickcontrols2/controls/data/tst_scrollview.qml new file mode 100644 index 00000000000..bcc1c44fe88 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_scrollview.qml @@ -0,0 +1,687 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "ScrollView" + + Component { + id: signalSpy + SignalSpy { } + } + + Component { + id: scrollView + ScrollView { } + } + + Component { + id: scrollBarComponent + ScrollBar {} + } + + Component { + id: scrollableLabel + ScrollView { + Label { + text: "ABC" + font.pixelSize: 512 + } + } + } + + Component { + id: scrollableLabels + ScrollView { + contentHeight: label1.implicitHeight + label2.implicitHeight + label3.implicitHeight + Label { + id: label1 + text: "First" + font.pixelSize: 96 + } + Label { + id: label2 + text: "Second" + font.pixelSize: 96 + } + Label { + id: label3 + text: "Third" + font.pixelSize: 96 + } + } + } + + Component { + id: flickableLabel + ScrollView { + Flickable { + contentWidth: label.implicitWidth + contentHeight: label.implicitHeight + Label { + id: label + text: "ABC" + font.pixelSize: 512 + } + } + } + } + + Component { + id: emptyFlickable + ScrollView { + Flickable { + } + } + } + + Component { + id: labelComponent + Label { + text: "ABC" + font.pixelSize: 512 + } + } + + Component { + id: scrollableListView + ScrollView { + ListView { + model: 3 + delegate: Label { + text: modelData + } + } + } + } + + Component { + id: scrollableFlickable + ScrollView { + Flickable { + Item { + width: 100 + height: 100 + } + } + } + } + + Component { + id: scrollableWithContentSize + ScrollView { + contentWidth: 1000 + contentHeight: 1000 + Flickable { + } + } + } + + Component { + id: scrollableAndFlicableWithContentSize + ScrollView { + contentWidth: 1000 + contentHeight: 1000 + Flickable { + contentWidth: 200 + contentHeight: 200 + } + } + } + + Component { + id: scrollableTextArea + ScrollView { + TextArea { + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas id dignissim ipsum. Nam molestie nisl turpis." + wrapMode: TextArea.WordWrap + } + } + } + Component { + id: scrollableTextAreaWithSibling + ScrollView { + Item { + } + TextArea { + } + } + } + + function test_scrollBars() { + var control = createTemporaryObject(scrollView, testCase, {width: 200, height: 200}) + verify(control) + + var vertical = control.ScrollBar.vertical + verify(vertical) + + var horizontal = control.ScrollBar.horizontal + verify(horizontal) + + control.contentHeight = 400 + verify(vertical.size > 0) + compare(control.contentItem.visibleArea.heightRatio, vertical.size) + + control.contentWidth = 400 + verify(horizontal.size > 0) + compare(control.contentItem.visibleArea.widthRatio, horizontal.size) + + vertical.increase() + verify(vertical.position > 0) + compare(control.contentItem.visibleArea.yPosition, vertical.position) + + horizontal.increase() + verify(horizontal.position > 0) + compare(control.contentItem.visibleArea.xPosition, horizontal.position) + } + + function test_oneChild_data() { + return [ + { tag: "label", component: scrollableLabel }, + { tag: "flickable", component: flickableLabel } + ] + } + + function test_oneChild(data) { + var control = createTemporaryObject(data.component, testCase) + verify(control) + + var flickable = control.contentItem + verify(flickable.hasOwnProperty("contentX")) + verify(flickable.hasOwnProperty("contentY")) + + var label = flickable.contentItem.children[0] + compare(label.text, "ABC") + + compare(control.implicitWidth, label.implicitWidth) + compare(control.implicitHeight, label.implicitHeight) + + compare(control.contentWidth, label.implicitWidth) + compare(control.contentHeight, label.implicitHeight) + + compare(flickable.contentWidth, label.implicitWidth) + compare(flickable.contentHeight, label.implicitHeight) + + control.contentWidth = 200 + compare(control.implicitWidth, 200) + compare(control.contentWidth, 200) + compare(flickable.contentWidth, 200) + + control.contentHeight = 100 + compare(control.implicitHeight, 100) + compare(control.contentHeight, 100) + compare(flickable.contentHeight, 100) + } + + function test_multipleChildren() { + var control = createTemporaryObject(scrollableLabels, testCase) + verify(control) + + var flickable = control.contentItem + verify(flickable.hasOwnProperty("contentX")) + verify(flickable.hasOwnProperty("contentY")) + + compare(control.contentChildren, flickable.contentItem.children) + + var label1 = control.contentChildren[0] + compare(label1.text, "First") + + var label2 = control.contentChildren[1] + compare(label2.text, "Second") + + var label3 = control.contentChildren[2] + compare(label3.text, "Third") + + var expectedContentHeight = label1.implicitHeight + label2.implicitHeight + label3.implicitHeight + compare(control.contentHeight, expectedContentHeight) + compare(flickable.contentHeight, expectedContentHeight) + } + + function test_listView() { + var control = createTemporaryObject(scrollableListView, testCase) + verify(control) + + var listview = control.contentItem + verify(listview.hasOwnProperty("contentX")) + verify(listview.hasOwnProperty("contentY")) + verify(listview.hasOwnProperty("model")) + + compare(control.contentWidth, listview.contentWidth) + compare(control.contentHeight, listview.contentHeight) + } + + function test_scrollableFlickable() { + // Check that if the application adds a flickable as a child of a + // scrollview, the scrollview doesn't try to calculate and change + // the flickables contentWidth/Height based on the flickables + // children, even if the flickable has an empty or negative content + // size. Some flickables (e.g ListView) sets a negative + // contentWidth on purpose, which should be respected. + var scrollview = createTemporaryObject(scrollableFlickable, testCase) + verify(scrollview) + + var flickable = scrollview.contentItem + verify(flickable.hasOwnProperty("contentX")) + verify(flickable.hasOwnProperty("contentY")) + + compare(flickable.contentWidth, -1) + compare(flickable.contentHeight, -1) + compare(scrollview.contentWidth, -1) + compare(scrollview.contentHeight, -1) + } + + function test_scrollableWithContentSize() { + // Check that if the scrollview has contentWidth/Height set, but + // not the flickable, then those values will be forwarded and used + // by the flickable (rather than trying to calculate the content size + // based on the flickables children). + var scrollview = createTemporaryObject(scrollableWithContentSize, testCase) + verify(scrollview) + + var flickable = scrollview.contentItem + verify(flickable.hasOwnProperty("contentX")) + verify(flickable.hasOwnProperty("contentY")) + + compare(flickable.contentWidth, 1000) + compare(flickable.contentHeight, 1000) + compare(scrollview.contentWidth, 1000) + compare(scrollview.contentHeight, 1000) + } + + function test_scrollableAndFlickableWithContentSize() { + // Check that if both the scrollview and the flickable has + // contentWidth/Height set (which is an inconsistency/fault + // by the app), the content size of the scrollview wins. + var scrollview = createTemporaryObject(scrollableAndFlicableWithContentSize, testCase) + verify(scrollview) + + var flickable = scrollview.contentItem + verify(flickable.hasOwnProperty("contentX")) + verify(flickable.hasOwnProperty("contentY")) + + compare(flickable.contentWidth, 1000) + compare(flickable.contentHeight, 1000) + compare(scrollview.contentWidth, 1000) + compare(scrollview.contentHeight, 1000) + } + + function test_flickableWithExplicitContentSize() { + var control = createTemporaryObject(emptyFlickable, testCase) + verify(control) + + var flickable = control.contentItem + verify(flickable.hasOwnProperty("contentX")) + verify(flickable.hasOwnProperty("contentY")) + + var flickableContentSize = 1000; + flickable.contentWidth = flickableContentSize; + flickable.contentHeight = flickableContentSize; + + compare(flickable.contentWidth, flickableContentSize) + compare(flickable.contentHeight, flickableContentSize) + compare(control.implicitWidth, flickableContentSize) + compare(control.implicitHeight, flickableContentSize) + compare(control.contentWidth, flickableContentSize) + compare(control.contentHeight, flickableContentSize) + + // Add a single child to the flickable. This should not + // trick ScrollView into taking the implicit size of + // the child as content size, since the flickable + // already has an explicit content size. + labelComponent.createObject(flickable); + + compare(flickable.contentWidth, flickableContentSize) + compare(flickable.contentHeight, flickableContentSize) + compare(control.implicitWidth, flickableContentSize) + compare(control.implicitHeight, flickableContentSize) + compare(control.contentWidth, flickableContentSize) + compare(control.contentHeight, flickableContentSize) + } + + function test_mouse() { + var control = createTemporaryObject(scrollView, testCase, {width: 200, height: 200, contentHeight: 400}) + verify(control) + + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.contentItem.contentY, 0) + + for (var y = control.height / 2; y >= 0; --y) { + mouseMove(control, control.width / 2, y, 10) + compare(control.contentItem.contentY, 0) + } + + mouseRelease(control, control.width / 2, 0, Qt.LeftButton) + compare(control.contentItem.contentY, 0) + } + + function test_hover() { + var control = createTemporaryObject(scrollView, testCase, {width: 200, height: 200, contentHeight: 400}) + verify(control) + + var vertical = control.ScrollBar.vertical + verify(vertical) + vertical.hoverEnabled = true + + mouseMove(vertical, vertical.width / 2, vertical.height / 2) + compare(vertical.visible, true) + compare(vertical.hovered, true) + compare(vertical.active, true) + compare(vertical.interactive, true) + } + + function test_wheel() { + var control = createTemporaryObject(scrollView, testCase, {width: 200, height: 200, contentHeight: 400}) + verify(control) + + var vertical = control.ScrollBar.vertical + verify(vertical) + + mouseWheel(control, control.width / 2, control.height / 2, 0, -120) + compare(vertical.visible, true) + compare(vertical.active, true) + compare(vertical.interactive, true) + } + + function test_touch() { + var control = createTemporaryObject(scrollView, testCase, {width: 200, height: 200, contentHeight: 400}) + verify(control) + + var vertical = control.ScrollBar.vertical + verify(vertical) + + var touch = touchEvent(control) + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.contentItem.contentY, 0) + + compare(vertical.active, false) + compare(vertical.interactive, false) + + var maxContentY = 0 + for (var y = control.height / 2; y >= 0; --y) { + touch.move(0, control, control.width / 2, y).commit() + maxContentY = Math.max(maxContentY, control.contentItem.contentY) + } + verify(maxContentY > 0) + + compare(vertical.active, true) + compare(vertical.interactive, false) + + touch.release(0, control, control.width / 2, 0).commit() + } + + function test_keys() { + var control = createTemporaryObject(scrollView, testCase, {width: 200, height: 200, contentWidth: 400, contentHeight: 400}) + verify(control) + // If the viewport is smaller than the size of the ScrollView + // (like windows style does due to its opaque scrollbars), + // make the ScrollView taller in order to keep the *viewport* 200x200 + control.width += (control.width - control.availableWidth) + control.height += (control.height - control.availableHeight) + + control.forceActiveFocus() + verify(control.activeFocus) + + var vertical = control.ScrollBar.vertical + verify(vertical) + + compare(vertical.position, 0.0) + for (var i = 1; i <= 10; ++i) { + keyClick(Qt.Key_Down) + compare(vertical.position, Math.min(0.5, i * 0.1)) + } + compare(vertical.position, 0.5) + for (i = 1; i <= 10; ++i) { + keyClick(Qt.Key_Up) + compare(vertical.position, Math.max(0.0, 0.5 - i * 0.1)) + } + compare(vertical.position, 0.0) + + var horizontal = control.ScrollBar.horizontal + verify(horizontal) + + compare(horizontal.position, 0.0) + for (i = 1; i <= 10; ++i) { + keyClick(Qt.Key_Right) + compare(horizontal.position, Math.min(0.5, i * 0.1)) + } + compare(horizontal.position, 0.5) + for (i = 1; i <= 10; ++i) { + keyClick(Qt.Key_Left) + compare(horizontal.position, Math.max(0.0, 0.5 - i * 0.1)) + } + compare(horizontal.position, 0.0) + } + + function test_textArea() { + // TODO: verify no binding loop warnings (QTBUG-62325) + var control = createTemporaryObject(scrollableTextArea, testCase) + verify(control) + + var flickable = control.contentItem + verify(flickable && flickable.hasOwnProperty("contentX")) + + var textArea = flickable.contentItem.children[0] + verify(textArea && textArea.hasOwnProperty("text")) + + compare(control.contentWidth, flickable.contentWidth) + compare(control.contentHeight, flickable.contentHeight) + } + + function test_textAreaWithSibling() { + // Checks that it does not crash when the ScrollView is deleted + var control = createTemporaryObject(scrollableTextAreaWithSibling, testCase) + verify(control) + } + + Component { + id: zeroSizedContentItemComponent + ScrollView { + width: 100 + height: 100 + contentItem: Item {} + } + } + + function test_zeroSizedContentItem() { + ignoreWarning(/ScrollView only supports Flickable types as its contentItem/) + let control = createTemporaryObject(zeroSizedContentItemComponent, testCase) + verify(control) + + let verticalScrollBar = control.ScrollBar.vertical + verify(verticalScrollBar) + // Scrolling a ScrollView with a zero-sized contentItem shouldn't crash. + mouseDrag(verticalScrollBar, verticalScrollBar.width / 2, verticalScrollBar.height / 2, 0, 50) + + let horizontalScrollBar = control.ScrollBar.horizontal + verify(verticalScrollBar) + mouseDrag(horizontalScrollBar, horizontalScrollBar.width / 2, horizontalScrollBar.height / 2, 50, 0) + } + + function test_customScrollBars() { + let control = createTemporaryObject(scrollView, testCase) + verify(control) + control.ScrollBar.vertical.objectName = "oldVerticalScrollBar" + control.ScrollBar.horizontal.objectName = "oldHorizontalScrollBar" + + let oldVerticalScrollBar = control.ScrollBar.vertical + verify(oldVerticalScrollBar) + compare(oldVerticalScrollBar.objectName, "oldVerticalScrollBar") + + let oldHorizontalScrollBar = control.ScrollBar.horizontal + verify(oldHorizontalScrollBar) + compare(oldHorizontalScrollBar.objectName, "oldHorizontalScrollBar") + + // Create the new scroll bars imperatively so that we can easily access the old ones. + control.ScrollBar.vertical = scrollBarComponent.createObject(control, { objectName: "newVerticalScrollBar" }) + verify(control.ScrollBar.vertical) + let newVerticalScrollBar = findChild(control, "newVerticalScrollBar") + verify(newVerticalScrollBar) + verify(newVerticalScrollBar.visible) + verify(!oldVerticalScrollBar.visible) + + control.ScrollBar.horizontal = scrollBarComponent.createObject(control, { objectName: "newHorizontalScrollBar" }) + verify(control.ScrollBar.horizontal) + let newHorizontalScrollBar = findChild(control, "newHorizontalScrollBar") + verify(newHorizontalScrollBar) + verify(newHorizontalScrollBar.visible) + verify(!oldHorizontalScrollBar.visible) + } + + Component { + id: bindingToContentItemAndStandaloneFlickable + + Item { + objectName: "container" + width: 200 + height: 200 + + property alias scrollView: scrollView + + ScrollView { + id: scrollView + anchors.fill: parent + contentItem: listView + + property Item someBinding: contentItem + } + ListView { + id: listView + model: 10 + delegate: ItemDelegate { + text: modelData + width: listView.width + } + } + } + } + + // Tests that scroll bars show up for a ScrollView where + // - its contentItem is declared as a standalone, separate item + // - there is a binding to contentItem (which causes a default Flickable to be created) + function test_bindingToContentItemAndStandaloneFlickable() { + let root = createTemporaryObject(bindingToContentItemAndStandaloneFlickable, testCase) + verify(root) + + let control = root.scrollView + let verticalScrollBar = control.ScrollBar.vertical + let horizontalScrollBar = control.ScrollBar.horizontal + compare(verticalScrollBar.parent, control) + compare(horizontalScrollBar.parent, control) + verify(verticalScrollBar.visible) + verify(horizontalScrollBar.visible) + + mouseWheel(control, control.width / 2, control.height / 2, 0, -120) + verify(verticalScrollBar.active) + verify(horizontalScrollBar.active) + } + + Component { + id: contentItemAssignedImperatively + + Item { + objectName: "container" + width: 100 + height: 100 + + property alias scrollView: scrollView + + ListView { + id: listView + model: 20 + delegate: Text { + text: modelData + } + } + + Component.onCompleted: scrollView.contentItem = listView + + ScrollView { + id: scrollView + anchors.fill: parent + + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + } + } + } + + // Tests that a ListView declared before the ScrollView (as the QObject destruction order + // is relevant for the bug) and assigned imperatively to ScrollView does not cause: + // - a crash on exit + // - scroll bars that should be hidden to be visible + function test_contentItemAssignedImperatively() { + let root = createTemporaryObject(contentItemAssignedImperatively, testCase) + verify(root) + + let control = root.scrollView + let flickable = control.contentItem + compare(flickable.parent, control) + + let horizontalScrollBar = control.ScrollBar.horizontal + let verticalScrollBar = control.ScrollBar.vertical + // The horizontal ScrollBar's policy is set to AlwaysOff, so it shouldn't ever be visible. + verify(!horizontalScrollBar.visible) + // The vertical ScrollBar should be visible... + verify(verticalScrollBar.visible) + + // ... and it should become active when the ScrollView is scrolled. + mouseWheel(control, control.width / 2, control.height / 2, 0, -120) + verify(verticalScrollBar.active) + + // Shouldn't crash. + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_selectionrectangle.qml b/tests/auto/quickcontrols2/controls/data/tst_selectionrectangle.qml new file mode 100644 index 00000000000..210c6594cd2 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_selectionrectangle.qml @@ -0,0 +1,373 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls +import Qt.labs.qmlmodels + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "SelectionRectangle" + + property real cellWidth: 50 + property real cellHeight: 20 + property Item handle: null + property bool handleWasDragged: false + + Component { + id: handleComp + Rectangle { + id: handle + width: 28 + height: width + radius: width / 2 + property bool dragging: SelectionRectangle.dragging + property Item control: SelectionRectangle.control + border.width: 1 + border.color: "red" + visible: SelectionRectangle.control.active + + SelectionRectangle.onDraggingChanged: { + if (SelectionRectangle.dragging) + testCase.handleWasDragged = true + } + + Component.onCompleted: testCase.handle = handle + } + } + + Component { + id: tableviewComp + TableView { + id: tableView + clip: true + anchors.fill: parent + + model: TableModel { + TableModelColumn { display: "c1" } + TableModelColumn { display: "c2" } + TableModelColumn { display: "c3" } + TableModelColumn { display: "c4" } + rows: [ + { "c1": "v1", "c2":"v2", "c3":"v3", "c4": "v4" }, + { "c1": "v1", "c2":"v2", "c3":"v3", "c4": "v4" }, + { "c1": "v1", "c2":"v2", "c3":"v3", "c4": "v4" }, + { "c1": "v1", "c2":"v2", "c3":"v3", "c4": "v4" }, + ] + } + + delegate: Rectangle { + required property bool selected + implicitWidth: cellWidth + implicitHeight: cellHeight + color: selected ? "lightblue" : "gray" + Text { text: "cell" } + } + + selectionModel: ItemSelectionModel { + model: tableView.model + } + + property alias selectionRectangle: selectionRectangle + SelectionRectangle { + id: selectionRectangle + target: tableView + } + } + + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_set_target() { + let tableView = createTemporaryObject(tableviewComp, testCase) + verify(tableView) + let selectionRectangle = tableView.selectionRectangle + verify(selectionRectangle) + + compare(selectionRectangle.target, tableView) + + selectionRectangle.target = null + compare(selectionRectangle.target, null) + + selectionRectangle.target = tableView + compare(selectionRectangle.target, tableView) + } + + function test_set_selectionMode() { + let tableView = createTemporaryObject(tableviewComp, testCase) + verify(tableView) + let selectionRectangle = tableView.selectionRectangle + verify(selectionRectangle) + + // Default selection mode should be Auto + compare(selectionRectangle.selectionMode, SelectionRectangle.Auto) + + selectionRectangle.selectionMode = SelectionRectangle.Drag + compare(selectionRectangle.selectionMode, SelectionRectangle.Drag) + + selectionRectangle.selectionMode = SelectionRectangle.PressAndHold + compare(selectionRectangle.selectionMode, SelectionRectangle.PressAndHold) + + selectionRectangle.selectionMode = SelectionRectangle.Auto + compare(selectionRectangle.selectionMode, SelectionRectangle.Auto) + } + + function test_set_handles() { + let tableView = createTemporaryObject(tableviewComp, testCase) + verify(tableView) + let selectionRectangle = tableView.selectionRectangle + verify(selectionRectangle) + + selectionRectangle.topLeftHandle = null + compare(selectionRectangle.topLeftHandle, null) + + selectionRectangle.bottomRightHandle = null + compare(selectionRectangle.bottomRightHandle, null) + + selectionRectangle.topLeftHandle = handleComp + compare(selectionRectangle.topLeftHandle, handleComp) + + selectionRectangle.bottomRightHandle = handleComp + compare(selectionRectangle.bottomRightHandle, handleComp) + } + + function test_drag() { + let tableView = createTemporaryObject(tableviewComp, testCase) + verify(tableView) + let selectionRectangle = tableView.selectionRectangle + verify(selectionRectangle) + + selectionRectangle.selectionMode = SelectionRectangle.Drag + + let activeSpy = signalSpy.createObject(selectionRectangle, {target: selectionRectangle, signalName: "activeChanged"}) + let draggingSpy = signalSpy.createObject(selectionRectangle, {target: selectionRectangle, signalName: "draggingChanged"}) + verify(activeSpy.valid) + verify(draggingSpy.valid) + + verify(!tableView.selectionModel.hasSelection) + mouseDrag(tableView, 1, 1, (cellWidth * 2) - 2, 1, Qt.LeftButton) + verify(tableView.selectionModel.hasSelection) + compare(tableView.selectionModel.selectedIndexes.length, 2) + verify(tableView.selectionModel.isSelected(tableView.model.index(0, 0))) + verify(tableView.selectionModel.isSelected(tableView.model.index(0, 1))) + + compare(activeSpy.count, 1) + compare(draggingSpy.count, 2) + + // Remove selection + mouseClick(tableView, 1, 1, Qt.LeftButton) + verify(!tableView.selectionModel.hasSelection) + compare(draggingSpy.count, 2) + compare(activeSpy.count, 2) + + // Ensure that a press and hold doesn't start a selection + mousePress(tableView, 1, 1, Qt.LeftButton) + mousePress(tableView, 1, 1, Qt.LeftButton, Qt.NoModifier, 1000) + verify(!tableView.selectionModel.hasSelection) + } + + function test_pressAndHold() { + let tableView = createTemporaryObject(tableviewComp, testCase) + verify(tableView) + let selectionRectangle = tableView.selectionRectangle + verify(selectionRectangle) + + selectionRectangle.selectionMode = SelectionRectangle.PressAndHold + + let activeSpy = signalSpy.createObject(selectionRectangle, {target: selectionRectangle, signalName: "activeChanged"}) + let draggingSpy = signalSpy.createObject(selectionRectangle, {target: selectionRectangle, signalName: "draggingChanged"}) + verify(activeSpy.valid) + verify(draggingSpy.valid) + + verify(!tableView.selectionModel.hasSelection) + // Do a press and hold + mousePress(tableView, 1, 1, Qt.LeftButton) + mousePress(tableView, 1, 1, Qt.LeftButton, Qt.NoModifier, 1000) + verify(tableView.selectionModel.hasSelection) + compare(tableView.selectionModel.selectedIndexes.length, 1) + verify(tableView.selectionModel.isSelected(tableView.model.index(0, 0))) + + compare(draggingSpy.count, 0) + compare(activeSpy.count, 1) + + // Remove selection + mouseClick(tableView, 1, 1, Qt.LeftButton) + verify(!tableView.selectionModel.hasSelection) + compare(draggingSpy.count, 0) + compare(activeSpy.count, 2) + + // Ensure that a drag doesn't start a selection + mouseDrag(tableView, 1, 1, (cellWidth * 2) - 2, 1, Qt.LeftButton) + verify(!tableView.selectionModel.hasSelection) + } + + function test_pressAndHold_on_top_of_handle() { + let tableView = createTemporaryObject(tableviewComp, testCase) + verify(tableView) + let selectionRectangle = tableView.selectionRectangle + verify(selectionRectangle) + + selectionRectangle.selectionMode = SelectionRectangle.PressAndHold + + let activeSpy = signalSpy.createObject(selectionRectangle, {target: selectionRectangle, signalName: "activeChanged"}) + let draggingSpy = signalSpy.createObject(selectionRectangle, {target: selectionRectangle, signalName: "draggingChanged"}) + verify(activeSpy.valid) + verify(draggingSpy.valid) + + verify(!tableView.selectionModel.hasSelection) + // Do a press and hold + mousePress(tableView, 1, 1, Qt.LeftButton) + mouseRelease(tableView, 1, 1, Qt.LeftButton, Qt.NoModifier, 2000) + verify(tableView.selectionModel.hasSelection) + compare(tableView.selectionModel.selectedIndexes.length, 1) + verify(tableView.selectionModel.isSelected(tableView.model.index(0, 0))) + + compare(draggingSpy.count, 0) + compare(activeSpy.count, 1) + + // Do another press and hold on top the part of the bottom right handle that + // also covers cell 1, 1. Without any handles, this would start a new selection + // on top of that cell. But when the handles are in front, they should block it. + mousePress(tableView, cellWidth + 1, cellHeight + 1, Qt.LeftButton) + mouseRelease(tableView, cellWidth + 1, cellHeight + 1, Qt.LeftButton, Qt.NoModifier, 2000) + compare(tableView.selectionModel.selectedIndexes.length, 1) + verify(tableView.selectionModel.isSelected(tableView.model.index(0, 0))) + } + + function test_handleDragTopLeft() { + let tableView = createTemporaryObject(tableviewComp, testCase) + verify(tableView) + let selectionRectangle = tableView.selectionRectangle + verify(selectionRectangle) + + selectionRectangle.selectionMode = SelectionRectangle.Drag + + verify(!tableView.selectionModel.hasSelection) + // Select four cells in the middle + mouseDrag(tableView, cellWidth + 1, cellHeight + 1, (cellWidth * 2) - 2, (cellHeight * 2) - 2, Qt.LeftButton) + compare(tableView.selectionModel.selectedIndexes.length, 4) + for (var x = 1; x < 3; ++x) { + for (var y = 1; y < 3; ++y) { + verify(tableView.selectionModel.isSelected(tableView.model.index(x, y))) + } + } + + // Drag on the top left handle, so that the selection extends to cell 0, 0 + mouseDrag(tableView, cellWidth, cellHeight, -cellWidth / 2, -cellHeight / 2, Qt.LeftButton) + compare(tableView.selectionModel.selectedIndexes.length, 9) + for (x = 0; x < 3; ++x) { + for (y = 0; y < 3; ++y) { + verify(tableView.selectionModel.isSelected(tableView.model.index(x, y))) + } + } + } + + function test_handleDragBottomRight_shrink() { + let tableView = createTemporaryObject(tableviewComp, testCase) + verify(tableView) + let selectionRectangle = tableView.selectionRectangle + verify(selectionRectangle) + + selectionRectangle.selectionMode = SelectionRectangle.Drag + + verify(!tableView.selectionModel.hasSelection) + // Select four cells in the middle + mouseDrag(tableView, cellWidth + 1, cellHeight + 1, (cellWidth * 2) - 2, (cellHeight * 2) - 2, Qt.LeftButton) + compare(tableView.selectionModel.selectedIndexes.length, 4) + for (var x = 1; x < 3; ++x) { + for (var y = 1; y < 3; ++y) { + verify(tableView.selectionModel.isSelected(tableView.model.index(x, y))) + } + } + + // Drag on the bottom right handle, so that the selection shrinks to cell 1, 1 + mouseDrag(tableView, (cellWidth * 3) - 1, (cellHeight * 3) - 1, -cellWidth, -cellHeight, Qt.LeftButton) + compare(tableView.selectionModel.selectedIndexes.length, 1) + verify(tableView.selectionModel.isSelected(tableView.model.index(1, 1))) + } + + function test_handleDragBottomRight_expand() { + let tableView = createTemporaryObject(tableviewComp, testCase) + verify(tableView) + let selectionRectangle = tableView.selectionRectangle + verify(selectionRectangle) + + selectionRectangle.selectionMode = SelectionRectangle.Drag + + verify(!tableView.selectionModel.hasSelection) + // Select four cells in the middle + mouseDrag(tableView, cellWidth + 1, cellHeight + 1, (cellWidth * 2) - 2, (cellHeight * 2) - 2, Qt.LeftButton) + compare(tableView.selectionModel.selectedIndexes.length, 4) + for (var x = 1; x < 3; ++x) { + for (var y = 1; y < 3; ++y) { + verify(tableView.selectionModel.isSelected(tableView.model.index(x, y))) + } + } + + // Drag on the bottom right handle, so that the selection expands to cell 9 cells + mouseDrag(tableView, cellWidth * 3, cellHeight * 3, cellWidth * 4, cellHeight * 4, Qt.LeftButton) + compare(tableView.selectionModel.selectedIndexes.length, 9) + for (x = 1; x < 4; ++x) { + for (y = 1; y < 4; ++y) { + verify(tableView.selectionModel.isSelected(tableView.model.index(x, y))) + } + } + } + +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_slider.qml b/tests/auto/quickcontrols2/controls/data/tst_slider.qml new file mode 100644 index 00000000000..39fcaa3a2e3 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_slider.qml @@ -0,0 +1,954 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "Slider" + + Component { + id: signalSpy + SignalSpy { } + } + + Component { + id: slider + Slider { } + } + + function test_defaults() { + var control = createTemporaryObject(slider, testCase) + verify(control) + + compare(control.stepSize, 0) + compare(control.snapMode, Slider.NoSnap) + compare(control.orientation, Qt.Horizontal) + compare(control.horizontal, true) + compare(control.vertical, false) + } + + function test_value() { + var control = createTemporaryObject(slider, testCase) + verify(control) + + compare(control.value, 0.0) + control.value = 0.5 + compare(control.value, 0.5) + control.value = 1.0 + compare(control.value, 1.0) + control.value = -1.0 + compare(control.value, 0.0) + control.value = 2.0 + compare(control.value, 1.0) + } + + function test_range() { + var control = createTemporaryObject(slider, testCase, {from: 0, to: 100, value: 50}) + verify(control) + + compare(control.from, 0) + compare(control.to, 100) + compare(control.value, 50) + compare(control.position, 0.5) + + control.value = 1000 + compare(control.value, 100) + compare(control.position, 1) + + control.value = -1 + compare(control.value, 0) + compare(control.position, 0) + + control.from = 25 + compare(control.from, 25) + compare(control.value, 25) + compare(control.position, 0) + + control.to = 75 + compare(control.to, 75) + compare(control.value, 25) + compare(control.position, 0) + + control.value = 50 + compare(control.value, 50) + compare(control.position, 0.5) + } + + function test_inverted() { + var control = createTemporaryObject(slider, testCase, {from: 1.0, to: -1.0}) + verify(control) + + compare(control.from, 1.0) + compare(control.to, -1.0) + compare(control.value, 0.0) + compare(control.position, 0.5) + + control.value = 2.0 + compare(control.value, 1.0) + compare(control.position, 0.0) + + control.value = -2.0 + compare(control.value, -1.0) + compare(control.position, 1.0) + + control.value = 0.0 + compare(control.value, 0.0) + compare(control.position, 0.5) + } + + function test_position() { + var control = createTemporaryObject(slider, testCase) + verify(control) + + compare(control.value, 0.0) + compare(control.position, 0.0) + + control.value = 0.25 + compare(control.value, 0.25) + compare(control.position, 0.25) + + control.value = 0.75 + compare(control.value, 0.75) + compare(control.position, 0.75) + } + + function test_visualPosition() { + var control = createTemporaryObject(slider, testCase) + verify(control) + + compare(control.value, 0.0) + compare(control.visualPosition, 0.0) + + control.value = 0.25 + compare(control.value, 0.25) + compare(control.visualPosition, 0.25) + + // RTL locale + control.locale = Qt.locale("ar_EG") + compare(control.visualPosition, 0.25) + + // RTL locale + LayoutMirroring + control.LayoutMirroring.enabled = true + compare(control.visualPosition, 0.75) + + // LTR locale + LayoutMirroring + control.locale = Qt.locale("en_US") + compare(control.visualPosition, 0.75) + + // LTR locale + control.LayoutMirroring.enabled = false + compare(control.visualPosition, 0.25) + + // LayoutMirroring + control.LayoutMirroring.enabled = true + compare(control.visualPosition, 0.75) + } + + function test_orientation() { + var control = createTemporaryObject(slider, testCase) + verify(control) + + compare(control.orientation, Qt.Horizontal) + compare(control.horizontal, true) + compare(control.vertical, false) + verify(control.width > control.height) + + control.orientation = Qt.Vertical + compare(control.orientation, Qt.Vertical) + compare(control.horizontal, false) + compare(control.vertical, true) + verify(control.width < control.height) + } + + function test_mouse_data() { + return [ + { tag: "horizontal", orientation: Qt.Horizontal, live: false }, + { tag: "vertical", orientation: Qt.Vertical, live: false }, + { tag: "horizontal:live", orientation: Qt.Horizontal, live: true }, + { tag: "vertical:live", orientation: Qt.Vertical, live: true } + ] + } + + function test_mouse(data) { + var control = createTemporaryObject(slider, testCase, {orientation: data.orientation, live: data.live}) + verify(control) + + var pressedCount = 0 + var movedCount = 0 + + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) + verify(pressedSpy.valid) + + var movedSpy = signalSpy.createObject(control, {target: control, signalName: "moved"}) + verify(movedSpy.valid) + + mousePress(control, 0, control.height - 1, Qt.LeftButton) + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) + compare(control.pressed, true) + compare(control.value, 0.0) + compare(control.position, 0.0) + + // mininum on the left in horizontal vs. at the bottom in vertical + mouseMove(control, -control.width, 2 * control.height, 0) + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, movedCount) + compare(control.pressed, true) + compare(control.value, 0.0) + compare(control.position, 0.0) + + mouseMove(control, control.width * 0.5, control.height * 0.5, 0) + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, ++movedCount) + compare(control.pressed, true) + compare(control.value, data.live ? 0.5 : 0.0) + compare(control.position, 0.5) + + mouseRelease(control, control.width * 0.5, control.height * 0.5, Qt.LeftButton) + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) + compare(control.pressed, false) + compare(control.value, 0.5) + compare(control.position, 0.5) + + mousePress(control, control.width - 1, 0, Qt.LeftButton) + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, ++movedCount) + compare(control.pressed, true) + compare(control.value, data.live ? 1.0 : 0.5) + compare(control.position, 1.0) + + // maximum on the right in horizontal vs. at the top in vertical + mouseMove(control, control.width * 2, -control.height, 0) + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, movedCount) + compare(control.pressed, true) + compare(control.value, data.live ? 1.0 : 0.5) + compare(control.position, 1.0) + + mouseMove(control, control.width * 0.75, control.height * 0.25, 0) + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, ++movedCount) + compare(control.pressed, true) + compare(control.value, data.live ? control.position : 0.5) + verify(control.position >= 0.75) + + mouseRelease(control, control.width * 0.25, control.height * 0.75, Qt.LeftButton) + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, ++movedCount) + compare(control.pressed, false) + compare(control.value, control.position) + verify(control.value <= 0.25 && control.value >= 0.0) + verify(control.position <= 0.25 && control.position >= 0.0) + + // QTBUG-53846 + mouseClick(control, control.width * 0.5, control.height * 0.5, Qt.LeftButton) + compare(movedSpy.count, ++movedCount) + compare(pressedSpy.count, pressedCount += 2) + compare(control.value, 0.5) + compare(control.position, 0.5) + } + + function test_touch_data() { + return [ + { tag: "horizontal", orientation: Qt.Horizontal, live: false }, + { tag: "vertical", orientation: Qt.Vertical, live: false }, + { tag: "horizontal:live", orientation: Qt.Horizontal, live: true }, + { tag: "vertical:live", orientation: Qt.Vertical, live: true } + ] + } + + function test_touch(data) { + var control = createTemporaryObject(slider, testCase, {orientation: data.orientation, live: data.live}) + verify(control) + + var pressedCount = 0 + var movedCount = 0 + + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) + verify(pressedSpy.valid) + + var movedSpy = signalSpy.createObject(control, {target: control, signalName: "moved"}) + verify(movedSpy.valid) + + var touch = touchEvent(control) + touch.press(0, control, 0, 0).commit() + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) + compare(control.pressed, true) + compare(control.value, 0.0) + compare(control.position, 0.0) + + // mininum on the left in horizontal vs. at the bottom in vertical + touch.move(0, control, -control.width, 2 * control.height, 0).commit() + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, movedCount) + compare(control.pressed, true) + compare(control.value, 0.0) + compare(control.position, 0.0) + + touch.move(0, control, control.width * 0.5, control.height * 0.5, 0).commit() + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, ++movedCount) + compare(control.pressed, true) + compare(control.value, data.live ? 0.5 : 0.0) + compare(control.position, 0.5) + + touch.release(0, control, control.width * 0.5, control.height * 0.5).commit() + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) + compare(control.pressed, false) + compare(control.value, 0.5) + compare(control.position, 0.5) + + touch.press(0, control, control.width - 1, control.height - 1).commit() + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) + compare(control.pressed, true) + compare(control.value, 0.5) + compare(control.position, 0.5) + + // maximum on the right in horizontal vs. at the top in vertical + touch.move(0, control, control.width * 2, -control.height, 0).commit() + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, ++movedCount) + compare(control.pressed, true) + compare(control.value, data.live ? 1.0 : 0.5) + compare(control.position, 1.0) + + touch.move(0, control, control.width * 0.75, control.height * 0.25, 0).commit() + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, ++movedCount) + compare(control.pressed, true) + compare(control.value, data.live ? control.position : 0.5) + verify(control.position >= 0.75) + + touch.release(0, control, control.width * 0.25, control.height * 0.75).commit() + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, ++movedCount) + compare(control.pressed, false) + compare(control.value, control.position) + verify(control.value <= 0.25 && control.value >= 0.0) + verify(control.position <= 0.25 && control.position >= 0.0) + + // QTBUG-53846 + touch.press(0, control).commit().release(0, control).commit() + compare(movedSpy.count, ++movedCount) + compare(pressedSpy.count, pressedCount += 2) + compare(control.value, 0.5) + compare(control.position, 0.5) + } + + function test_multiTouch() { + var control1 = createTemporaryObject(slider, testCase, {live: false}) + verify(control1) + + var pressedCount1 = 0 + var movedCount1 = 0 + + var pressedSpy1 = signalSpy.createObject(control1, {target: control1, signalName: "pressedChanged"}) + verify(pressedSpy1.valid) + + var movedSpy1 = signalSpy.createObject(control1, {target: control1, signalName: "moved"}) + verify(movedSpy1.valid) + + var touch = touchEvent(control1) + touch.press(0, control1, 0, 0).commit().move(0, control1, control1.width, control1.height).commit() + + compare(pressedSpy1.count, ++pressedCount1) + compare(movedSpy1.count, ++movedCount1) + compare(control1.pressed, true) + compare(control1.position, 1.0) + + // second touch point on the same control is ignored + touch.stationary(0).press(1, control1, 0, 0).commit() + touch.stationary(0).move(1, control1).commit() + touch.stationary(0).release(1).commit() + + compare(pressedSpy1.count, pressedCount1) + compare(movedSpy1.count, movedCount1) + compare(control1.pressed, true) + compare(control1.position, 1.0) + + var control2 = createTemporaryObject(slider, testCase, {y: control1.height, live: false}) + verify(control2) + + var pressedCount2 = 0 + var movedCount2 = 0 + + var pressedSpy2 = signalSpy.createObject(control2, {target: control2, signalName: "pressedChanged"}) + verify(pressedSpy2.valid) + + var movedSpy2 = signalSpy.createObject(control2, {target: control2, signalName: "moved"}) + verify(movedSpy2.valid) + + // press the second slider + touch.stationary(0).press(2, control2, 0, 0).commit() + + compare(pressedSpy2.count, ++pressedCount2) + compare(movedSpy2.count, movedCount2) + compare(control2.pressed, true) + compare(control2.position, 0.0) + + compare(pressedSpy1.count, pressedCount1) + compare(movedSpy1.count, movedCount1) + compare(control1.pressed, true) + compare(control1.position, 1.0) + + // move both sliders + touch.move(0, control1).move(2, control2).commit() + + compare(pressedSpy2.count, pressedCount2) + compare(movedSpy2.count, ++movedCount2) + compare(control2.pressed, true) + compare(control2.position, 0.5) + compare(control2.value, 0.0) + + compare(pressedSpy1.count, pressedCount1) + compare(movedSpy1.count, ++movedCount1) + compare(control1.pressed, true) + compare(control1.position, 0.5) + compare(control1.value, 0.0) + + // release both sliders + touch.release(0, control1).release(2, control2).commit() + + compare(pressedSpy2.count, ++pressedCount2) + compare(movedSpy2.count, movedCount2) + compare(control2.pressed, false) + compare(control2.position, 0.5) + compare(control2.value, 0.5) + + compare(pressedSpy1.count, ++pressedCount1) + compare(movedSpy1.count, movedCount1) + compare(control1.pressed, false) + compare(control1.position, 0.5) + compare(control1.value, 0.5) + } + + function test_keys_data() { + return [ + { tag: "horizontal", orientation: Qt.Horizontal, decrease: Qt.Key_Left, increase: Qt.Key_Right }, + { tag: "vertical", orientation: Qt.Vertical, decrease: Qt.Key_Down, increase: Qt.Key_Up } + ] + } + + function test_keys(data) { + var control = createTemporaryObject(slider, testCase, {orientation: data.orientation}) + verify(control) + + var pressedCount = 0 + var movedCount = 0 + + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) + verify(pressedSpy.valid) + + var movedSpy = signalSpy.createObject(control, {target: control, signalName: "moved"}) + verify(movedSpy.valid) + + control.forceActiveFocus() + verify(control.activeFocus) + + var oldValue = 0.0 + control.value = 0.5 + + for (var d1 = 1; d1 <= 10; ++d1) { + oldValue = control.value + keyPress(data.decrease) + compare(control.pressed, true) + compare(pressedSpy.count, ++pressedCount) + if (oldValue !== control.value) + compare(movedSpy.count, ++movedCount) + + compare(control.value, Math.max(0.0, 0.5 - d1 * 0.1)) + compare(control.value, control.position) + + keyRelease(data.decrease) + compare(control.pressed, false) + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) + } + + for (var i1 = 1; i1 <= 20; ++i1) { + oldValue = control.value + keyPress(data.increase) + compare(control.pressed, true) + compare(pressedSpy.count, ++pressedCount) + if (oldValue !== control.value) + compare(movedSpy.count, ++movedCount) + + compare(control.value, Math.min(1.0, 0.0 + i1 * 0.1)) + compare(control.value, control.position) + + keyRelease(data.increase) + compare(control.pressed, false) + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) + } + + control.stepSize = 0.25 + + for (var d2 = 1; d2 <= 10; ++d2) { + oldValue = control.value + keyPress(data.decrease) + compare(control.pressed, true) + compare(pressedSpy.count, ++pressedCount) + if (oldValue !== control.value) + compare(movedSpy.count, ++movedCount) + + compare(control.value, Math.max(0.0, 1.0 - d2 * 0.25)) + compare(control.value, control.position) + + keyRelease(data.decrease) + compare(control.pressed, false) + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) + } + + for (var i2 = 1; i2 <= 10; ++i2) { + oldValue = control.value + keyPress(data.increase) + compare(control.pressed, true) + compare(pressedSpy.count, ++pressedCount) + if (oldValue !== control.value) + compare(movedSpy.count, ++movedCount) + + compare(control.value, Math.min(1.0, 0.0 + i2 * 0.25)) + compare(control.value, control.position) + + keyRelease(data.increase) + compare(control.pressed, false) + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) + } + } + + function test_padding() { + // test with "unbalanced" paddings (left padding != right padding) to ensure + // that the slider position calculation is done taking padding into account + // ==> the position is _not_ 0.5 in the middle of the control + var control = createTemporaryObject(slider, testCase, {leftPadding: 10, rightPadding: 20, live: false}) + verify(control) + + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) + verify(pressedSpy.valid) + + mousePress(control, 0, 0, Qt.LeftButton) + compare(pressedSpy.count, 1) + compare(control.pressed, true) + compare(control.value, 0.0) + compare(control.position, 0.0) + compare(control.visualPosition, 0.0) + + mouseMove(control, control.leftPadding + control.availableWidth * 0.5, control.height * 0.5, 0) + compare(pressedSpy.count, 1) + compare(control.pressed, true) + compare(control.value, 0.0) + compare(control.position, 0.5) + compare(control.visualPosition, 0.5) + + mouseMove(control, control.width * 0.5, control.height * 0.5, 0) + compare(pressedSpy.count, 1) + compare(control.pressed, true) + compare(control.value, 0.0) + verify(control.position > 0.5) + verify(control.visualPosition > 0.5) + + mouseRelease(control, control.leftPadding + control.availableWidth * 0.5, control.height * 0.5, Qt.LeftButton) + compare(pressedSpy.count, 2) + compare(control.pressed, false) + compare(control.value, 0.5) + compare(control.position, 0.5) + compare(control.visualPosition, 0.5) + + // RTL + control.value = 0 + control.locale = Qt.locale("ar_EG") + + mousePress(control, 0, 0, Qt.LeftButton) + compare(pressedSpy.count, 3) + compare(control.pressed, true) + compare(control.value, 0.0) + compare(control.position, 0.0) + compare(control.visualPosition, 0.0) + + mouseMove(control, control.leftPadding + control.availableWidth * 0.5, control.height * 0.5, 0) + compare(pressedSpy.count, 3) + compare(control.pressed, true) + compare(control.value, 0.0) + compare(control.position, 0.5) + compare(control.visualPosition, 0.5) + + mouseMove(control, control.width * 0.5, control.height * 0.5, 0) + compare(pressedSpy.count, 3) + compare(control.pressed, true) + compare(control.value, 0.0) + verify(control.position > 0.5) + verify(control.visualPosition > 0.5) + + mouseRelease(control, control.leftPadding + control.availableWidth * 0.5, control.height * 0.5, Qt.LeftButton) + compare(pressedSpy.count, 4) + compare(control.pressed, false) + compare(control.value, 0.5) + compare(control.position, 0.5) + compare(control.visualPosition, 0.5) + } + + function calcMousePos(control, t) { + t = Math.min(Math.max(t, 0.0), 1.0); + return control.leftPadding + control.handle.width * 0.5 + t * (control.availableWidth - control.handle.width) + } + + function snapModeData(immediate) { + return [ + { tag: "NoSnap", snapMode: Slider.NoSnap, from: 0, to: 2, values: [0, 0, 0.25], positions: [0, 0.1, 0.1] }, + { tag: "SnapAlways (0..2)", snapMode: Slider.SnapAlways, from: 0, to: 2, values: [0.0, 0.0, 0.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapAlways (1..3)", snapMode: Slider.SnapAlways, from: 1, to: 3, values: [1.0, 1.0, 1.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapAlways (-1..1)", snapMode: Slider.SnapAlways, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] }, + { tag: "SnapAlways (1..-1)", snapMode: Slider.SnapAlways, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] }, + { tag: "SnapOnRelease (0..2)", snapMode: Slider.SnapOnRelease, from: 0, to: 2, values: [0.0, 0.0, 0.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapOnRelease (1..3)", snapMode: Slider.SnapOnRelease, from: 1, to: 3, values: [1.0, 1.0, 1.2], positions: [0.0, 0.1, 0.1] }, + { tag: "SnapOnRelease (-1..1)", snapMode: Slider.SnapOnRelease, from: -1, to: 1, values: [0.0, 0.0, -0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] }, + { tag: "SnapOnRelease (1..-1)", snapMode: Slider.SnapOnRelease, from: 1, to: -1, values: [0.0, 0.0, 0.8], positions: [immediate ? 0.0 : 0.5, 0.1, 0.1] }, + // Live + { tag: "SnapAlwaysLive", snapMode: Slider.SnapAlways, from: 0, to: 1, value: 0, stepSize: 1, live: true, sliderPos: 0.6, values: [0, 1, 1], positions: [0, 1, 1] }, + { tag: "SnapAlwaysLive", snapMode: Slider.SnapAlways, from: 0, to: 1, value: 0, stepSize: 1, live: true, sliderPos: 0.4, values: [0, 0, 0], positions: [0, 0, 0] }, + { tag: "NoSnapLive", snapMode: Slider.NoSnap, from: 0, to: 1, value: 0, stepSize: 1, live: true, sliderPos: 0.6, values: [0, 1, 1], positions: [0, 0.6, 0.6] }, + { tag: "NoSnapLive", snapMode: Slider.NoSnap, from: 0, to: 1, value: 0, stepSize: 1, live: true, sliderPos: 0.4, values: [0, 0, 0], positions: [0, 0.4, 0.4] }, + { tag: "SnapOnReleaseLive", snapMode: Slider.SnapOnRelease, from: 0, to: 1, value: 0, stepSize: 1, live: true, sliderPos: 0.6, values: [0, 1, 1], positions: [0, 0.6, 1] }, + { tag: "SnapOnReleaseLive", snapMode: Slider.SnapOnRelease, from: 0, to: 1, value: 0, stepSize: 1, live: true, sliderPos: 0.4, values: [0, 0, 0], positions: [0, 0.4, 0] }, + ] + } + + function testSnapMode(data, useMouse) { + let live = data.live !== undefined ? data.live : false + let stepSize = data.stepSize !== undefined ? data.stepSize : 0.2 + let sliderPos = data.sliderPos !== undefined ? data.sliderPos : 0.1 + let fuzz = 0.05 + + var control = createTemporaryObject(slider, testCase, {live: live, snapMode: data.snapMode, from: data.from, to: data.to, stepSize: stepSize}) + verify(control) + + // The test assumes there is no drag threshold for neither mouse or touch. + // But by default, touch has a threshold and mouse doesn't. + // In order to not get a test fail if we're trying to move the slider handle + // on a very narrow slider, we ensure the same width of all sliders + control.width = testCase.width + + var touch = useMouse ? null : touchEvent(control) + + if (useMouse) + mousePress(control, calcMousePos(control, 0.0)) + else + touch.press(0, control, calcMousePos(control, 0.0)).commit() + + fuzzyCompare(control.value, data.values[0], fuzz) + fuzzyCompare(control.position, data.positions[0], fuzz) + + if (useMouse) + mouseMove(control, calcMousePos(control, sliderPos)) + else + touch.move(0, control, calcMousePos(control, sliderPos)).commit() + + fuzzyCompare(control.value, data.values[1], fuzz) + fuzzyCompare(control.position, data.positions[1], fuzz) + + if (useMouse) + mouseRelease(control, calcMousePos(control, sliderPos)) + else + touch.release(0, control, calcMousePos(control, sliderPos)).commit() + + fuzzyCompare(control.value, data.values[2], fuzz) + fuzzyCompare(control.position, data.positions[2], fuzz) + } + + function test_snapMode_touch_data() { + return snapModeData(false) + } + + function test_snapMode_touch(data) { + return testSnapMode(data, false) + } + + function test_snapMode_mouse_data() { + return snapModeData(true) + } + + function test_snapMode_mouse(data) { + return testSnapMode(data, true) + } + + function test_wheel_data() { + return [ + { tag: "horizontal", orientation: Qt.Horizontal, dx: 120, dy: 0 }, + { tag: "vertical", orientation: Qt.Vertical, dx: 0, dy: 120 } + ] + } + + function test_wheel(data) { + var control = createTemporaryObject(slider, testCase, {wheelEnabled: true, orientation: data.orientation}) + verify(control) + + var movedCount = 0 + var movedSpy = signalSpy.createObject(control, {target: control, signalName: "moved"}) + verify(movedSpy.valid) + + compare(control.value, 0.0) + + mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(movedSpy.count, ++movedCount) + compare(control.value, 0.1) + compare(control.position, 0.1) + + control.stepSize = 0.2 + + mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(movedSpy.count, ++movedCount) + compare(control.value, 0.3) + compare(control.position, 0.3) + + control.stepSize = 10.0 + + mouseWheel(control, control.width / 2, control.height / 2, -data.dx, -data.dy) + compare(movedSpy.count, ++movedCount) + compare(control.value, 0.0) + compare(control.position, 0.0) + + // no change + mouseWheel(control, control.width / 2, control.height / 2, -data.dx, -data.dy) + compare(movedSpy.count, movedCount) + compare(control.value, 0.0) + compare(control.position, 0.0) + + control.to = 10.0 + control.stepSize = 5.0 + + mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(movedSpy.count, ++movedCount) + compare(control.value, 5.0) + compare(control.position, 0.5) + + mouseWheel(control, control.width / 2, control.height / 2, 0.5 * data.dx, 0.5 * data.dy) + compare(movedSpy.count, ++movedCount) + compare(control.value, 7.5) + compare(control.position, 0.75) + + mouseWheel(control, control.width / 2, control.height / 2, -data.dx, -data.dy) + compare(movedSpy.count, ++movedCount) + compare(control.value, 2.5) + compare(control.position, 0.25) + } + + function test_wheelPropagation_data() { + return [ + { tag: "horizontal", orientation: Qt.Horizontal, dx: 120, dy: 0 }, + { tag: "vertical", orientation: Qt.Vertical, dx: 0, dy: 120 } + ] + } + + Component { + id: mouseAreaComponent + MouseArea {} + } + + function test_wheelPropagation(data) { + var mouseArea = createTemporaryObject(mouseAreaComponent, testCase, { width: parent.width, height: parent.height }) + verify(mouseArea) + + var mouseAreaWheelSpy = signalSpy.createObject(mouseArea, { target: mouseArea, signalName: "wheel" }) + verify(mouseAreaWheelSpy.valid) + + var control = createTemporaryObject(slider, mouseArea, + { wheelEnabled: true, orientation: data.orientation, stepSize: 1 }) + verify(control) + compare(control.value, 0.0) + + var movedCount = 0 + var movedSpy = signalSpy.createObject(control, { target: control, signalName: "moved" }) + verify(movedSpy.valid) + + // Scroll the handle to the edge. + mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(control.value, 1.0) + compare(control.position, 1.0) + compare(movedSpy.count, ++movedCount) + compare(mouseAreaWheelSpy.count, 0) + + // Scroll again; the wheel event shouldn't go through to the MouseArea parent. + mouseWheel(control, control.width / 2, control.height / 2, data.dx, data.dy) + compare(control.value, 1.0) + compare(control.position, 1.0) + compare(movedSpy.count, movedCount) + compare(mouseAreaWheelSpy.count, 0) + + // Scroll the handle to the other edge. + mouseWheel(control, control.width / 2, control.height / 2, -data.dx, -data.dy) + compare(control.value, 0.0) + compare(control.position, 0.0) + compare(movedSpy.count, ++movedCount) + compare(mouseAreaWheelSpy.count, 0) + + // Scroll again; the wheel event shouldn't go through to the MouseArea parent. + mouseWheel(control, control.width / 2, control.height / 2, -data.dx, -data.dy) + compare(control.value, 0.0) + compare(control.position, 0.0) + compare(movedSpy.count, movedCount) + compare(mouseAreaWheelSpy.count, 0) + } + + function test_valueAt_data() { + return [ + { tag: "0.0..1.0", properties: { from: 0.0, to: 1.0 }, values: [0.0, 0.2, 0.5, 1.0] }, + { tag: "0..100", properties: { from: 0, to: 100 }, values: [0, 20, 50, 100] }, + { tag: "100..-100", properties: { from: 100, to: -100 }, values: [100, 60, 0, -100] }, + { tag: "-7..7", properties: { from: -7, to: 7, stepSize: 1.0 }, values: [-7.0, -4.0, 0.0, 7.0] }, + { tag: "-3..7", properties: { from: -3, to: 7, stepSize: 5.0 }, values: [-3.0, -3.0, 2.0, 7.0] }, + ] + } + + function test_valueAt(data) { + let control = createTemporaryObject(slider, testCase, data.properties) + verify(control) + + compare(control.valueAt(0.0), data.values[0]) + compare(control.valueAt(0.2), data.values[1]) + compare(control.valueAt(0.5), data.values[2]) + compare(control.valueAt(1.0), data.values[3]) + } + + function test_nullHandle() { + var control = createTemporaryObject(slider, testCase) + verify(control) + + control.handle = null + + mousePress(control) + verify(control.pressed, true) + + mouseRelease(control) + compare(control.pressed, false) + } + + function test_touchDragThreshold_data() { + var d1 = 3; var d2 = 7; + return [ + { tag: "horizontal", orientation: Qt.Horizontal, dx1: d1, dy1: 0, dx2: d2, dy2: 0 }, + { tag: "vertical", orientation: Qt.Vertical, dx1: 0, dy1: -d1, dx2: 0, dy2: -d2 }, + { tag: "horizontal2", orientation: Qt.Horizontal, dx1: -d1, dy1: 0, dx2: -d2, dy2: 0 }, + { tag: "vertical2", orientation: Qt.Vertical, dx1: 0, dy1: d1, dx2: 0, dy2: d2 } + ] + } + + function test_touchDragThreshold(data) { + var control = createTemporaryObject(slider, testCase, {touchDragThreshold: 10, live: true, orientation: data.orientation, value: 0.5}) + verify(control) + compare(control.touchDragThreshold, 10) + + var valueChangedCount = 0 + var valueChangedSpy = signalSpy.createObject(control, {target: control, signalName: "touchDragThresholdChanged"}) + verify(valueChangedSpy.valid) + + control.touchDragThreshold = undefined + compare(control.touchDragThreshold, -1) // reset to -1 + compare(valueChangedSpy.count, ++valueChangedCount) + + var t = 5 + control.touchDragThreshold = t + compare(control.touchDragThreshold, t) + compare(valueChangedSpy.count, ++valueChangedCount) + + control.touchDragThreshold = t + compare(control.touchDragThreshold, t) + compare(valueChangedSpy.count, valueChangedCount) + + var pressedCount = 0 + var movedCount = 0 + + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) + verify(pressedSpy.valid) + + var movedSpy = signalSpy.createObject(control, {target: control, signalName: "moved"}) + verify(movedSpy.valid) + + var touch = touchEvent(control) + var x0 = control.handle.x + control.handle.width * 0.5 + var y0 = control.handle.y + control.handle.height * 0.5 + touch.press(0, control, x0, y0).commit() + compare(pressedSpy.count, ++pressedCount) + compare(movedSpy.count, movedCount) + compare(control.pressed, true) + + touch.move(0, control, x0 + data.dx1, y0 + data.dy1).commit() + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, movedCount) // shouldn't move + compare(control.pressed, true) + + touch.move(0, control, x0 + data.dx2, y0 + data.dy2).commit() + compare(pressedSpy.count, pressedCount) + compare(movedSpy.count, ++movedCount) + compare(control.pressed, true) + + touch.release(0, control, x0 + data.dx2, y0 + data.dy2).commit() + } + + function test_nullTexture() { + var control = createTemporaryObject(slider, testCase, {width: -100}) + verify(control) + control.visible = true + waitForRendering(control) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_spinbox.qml b/tests/auto/quickcontrols2/controls/data/tst_spinbox.qml new file mode 100644 index 00000000000..a3d6b265e79 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_spinbox.qml @@ -0,0 +1,740 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls +import QtQuick.Window + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "SpinBox" + + Component { + id: signalSpy + SignalSpy { } + } + + Component { + id: spinBox + SpinBox { } + } + + Component { + id: mouseArea + MouseArea { } + } + + function test_defaults() { + var control = createTemporaryObject(spinBox, testCase) + verify(control) + + compare(control.from, 0) + compare(control.to, 99) + compare(control.value, 0) + compare(control.stepSize, 1) + compare(control.editable, false) + compare(control.up.pressed, false) + compare(control.up.indicator.enabled, true) + compare(control.down.pressed, false) + compare(control.down.indicator.enabled, false) + } + + function test_value() { + var control = createTemporaryObject(spinBox, testCase) + verify(control) + + compare(control.value, 0) + control.value = 50 + compare(control.value, 50) + control.value = 99 + compare(control.value, 99) + control.value = -99 + compare(control.value, 0) + control.value = 100 + compare(control.value, 99) + } + + function test_range() { + var control = createTemporaryObject(spinBox, testCase, {from: 0, to: 100, value: 50}) + verify(control) + + compare(control.from, 0) + compare(control.to, 100) + compare(control.value, 50) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, true) + + control.value = 1000 + compare(control.value, 100) + compare(control.up.indicator.enabled, false) + compare(control.down.indicator.enabled, true) + + control.wrap = true + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, true) + + control.value = -1 + compare(control.value, 0) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, true) + + control.from = 25 + compare(control.from, 25) + compare(control.value, 25) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, true) + + control.wrap = false + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, false) + + control.value = 30 + compare(control.from, 25) + compare(control.value, 30) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, true) + + control.from = 30 + compare(control.from, 30) + compare(control.value, 30) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, false) + + control.to = 75 + compare(control.to, 75) + compare(control.value, 30) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, false) + + control.value = 50 + compare(control.value, 50) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, true) + + control.to = 50 + compare(control.to, 50) + compare(control.value, 50) + compare(control.up.indicator.enabled, false) + compare(control.down.indicator.enabled, true) + + control.to = 40 + compare(control.to, 40) + compare(control.value, 40) + compare(control.up.indicator.enabled, false) + compare(control.down.indicator.enabled, true) + } + + function test_inverted() { + var control = createTemporaryObject(spinBox, testCase, {from: 100, to: -100}) + verify(control) + + compare(control.from, 100) + compare(control.to, -100) + compare(control.value, 0) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, true) + + control.value = 200 + compare(control.value, 100) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, false) + + control.value = -200 + compare(control.value, -100) + compare(control.up.indicator.enabled, false) + compare(control.down.indicator.enabled, true) + + control.value = 0 + compare(control.value, 0) + compare(control.up.indicator.enabled, true) + compare(control.down.indicator.enabled, true) + } + + function test_mouse_data() { + return [ + { tag: "up", button: "up", value: 50, enabled: true, hold: false, modified: 1, expected: 51 }, + { tag: "down", button: "down", value: 50, enabled: true, hold: false, modified: 1, expected: 49 }, + { tag: "up:disabled", button: "up", value: 99, enabled: false, hold: false, modified: 0, expected: 99 }, + { tag: "down:disabled", button: "down", value: 0, enabled: false, hold: false, modified: 0, expected: 0 }, + { tag: "up:hold", button: "up", value: 95, enabled: true, hold: true, modified: 4, expected: 99 }, + { tag: "down:hold", button: "down", value: 5, enabled: true, hold: true, modified: 5, expected: 0 } + ] + } + + function test_mouse(data) { + var control = createTemporaryObject(spinBox, testCase, {value: data.value}) + verify(control) + + var button = control[data.button] + verify(button) + + var pressedSpy = signalSpy.createObject(control, {target: button, signalName: "pressedChanged"}) + verify(pressedSpy.valid) + + var valueModifiedSpy = signalSpy.createObject(control, {target: control, signalName: "valueModified"}) + verify(valueModifiedSpy.valid) + + mousePress(button.indicator) + compare(pressedSpy.count, data.enabled ? 1 : 0) + compare(button.pressed, data.enabled) + compare(control.value, data.value) + compare(valueModifiedSpy.count, 0) + + if (data.hold) + tryCompare(control, "value", data.expected) + + mouseRelease(button.indicator) + compare(pressedSpy.count, data.enabled ? 2 : 0) + compare(button.pressed, false) + compare(control.value, data.expected) + compare(valueModifiedSpy.count, data.modified) + } + + function test_keys_data() { + return [ + { tag: "1", properties: { from: 1, to: 10, value: 1, stepSize: 1 }, upSteps: [2,3,4], downSteps: [3,2,1,1] }, + { tag: "2", properties: { from: 1, to: 10, value: 10, stepSize: 2 }, upSteps: [10,10], downSteps: [8,6,4] }, + { tag: "25", properties: { from: 0, to: 100, value: 50, stepSize: 25 }, upSteps: [75,100,100], downSteps: [75,50,25,0,0] }, + { tag: "wrap1", properties: { wrap: true, from: 1, to: 10, value: 1, stepSize: 1 }, upSteps: [2,3], downSteps: [2,1,10,9] }, + { tag: "wrap2", properties: { wrap: true, from: 1, to: 10, value: 10, stepSize: 2 }, upSteps: [1,3,5], downSteps: [3,1,10,8,6] }, + { tag: "wrap25", properties: { wrap: true, from: 0, to: 100, value: 50, stepSize: 25 }, upSteps: [75,100,0,25], downSteps: [0,100,75] } + ] + } + + function test_keys(data) { + var control = createTemporaryObject(spinBox, testCase, data.properties) + verify(control) + + var upPressedCount = 0 + var downPressedCount = 0 + var valueModifiedCount = 0 + + var upPressedSpy = signalSpy.createObject(control, {target: control.up, signalName: "pressedChanged"}) + verify(upPressedSpy.valid) + + var downPressedSpy = signalSpy.createObject(control, {target: control.down, signalName: "pressedChanged"}) + verify(downPressedSpy.valid) + + var valueModifiedSpy = signalSpy.createObject(control, {target: control, signalName: "valueModified"}) + verify(valueModifiedSpy.valid) + + control.forceActiveFocus() + verify(control.activeFocus) + + for (var u = 0; u < data.upSteps.length; ++u) { + var wasUpEnabled = control.wrap || control.value < control.to + keyPress(Qt.Key_Up) + compare(control.up.pressed, wasUpEnabled) + compare(control.down.pressed, false) + if (wasUpEnabled) { + ++upPressedCount + ++valueModifiedCount + } + compare(upPressedSpy.count, upPressedCount) + compare(valueModifiedSpy.count, valueModifiedCount) + + compare(control.value, data.upSteps[u]) + + keyRelease(Qt.Key_Up) + compare(control.down.pressed, false) + compare(control.up.pressed, false) + if (wasUpEnabled) + ++upPressedCount + compare(upPressedSpy.count, upPressedCount) + compare(valueModifiedSpy.count, valueModifiedCount) + } + + for (var d = 0; d < data.downSteps.length; ++d) { + var wasDownEnabled = control.wrap || control.value > control.from + keyPress(Qt.Key_Down) + compare(control.down.pressed, wasDownEnabled) + compare(control.up.pressed, false) + if (wasDownEnabled) { + ++downPressedCount + ++valueModifiedCount + } + compare(downPressedSpy.count, downPressedCount) + compare(valueModifiedSpy.count, valueModifiedCount) + + compare(control.value, data.downSteps[d]) + + keyRelease(Qt.Key_Down) + compare(control.down.pressed, false) + compare(control.up.pressed, false) + if (wasDownEnabled) + ++downPressedCount + compare(downPressedSpy.count, downPressedCount) + compare(valueModifiedSpy.count, valueModifiedCount) + } + } + + function test_locale() { + var control = createTemporaryObject(spinBox, testCase) + verify(control) + + control.locale = Qt.locale("ar_EG") // Arabic, Egypt + + var numbers = ["٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"] + for (var i = 0; i < 10; ++i) { + control.value = i + compare(control.contentItem.text, numbers[i]) + } + } + + function test_baseline() { + var control = createTemporaryObject(spinBox, testCase) + verify(control) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + } + + function test_focus() { + var control = createTemporaryObject(spinBox, testCase, {from: 10, to: 1000, value: 100, focus: true}) + verify(control) + + control.forceActiveFocus() + compare(control.activeFocus, true) + + compare(control.from, 10) + compare(control.to, 1000) + compare(control.value, 100) + + control.focus = false + compare(control.activeFocus, false) + + compare(control.from, 10) + compare(control.to, 1000) + compare(control.value, 100) + } + + function test_initialFocus() { + var window = testCase.Window.window + verify(window) + compare(window.activeFocusItem, window.contentItem) + + var control = createTemporaryObject(spinBox, testCase, { editable: true, focus: true }) + verify(control) + tryCompare(control.contentItem, "activeFocus", true) + } + + function test_editable() { + var control = createTemporaryObject(spinBox, testCase) + verify(control) + + var valueModifiedSpy = signalSpy.createObject(control, {target: control, signalName: "valueModified"}) + verify(valueModifiedSpy.valid) + + control.contentItem.forceActiveFocus() + compare(control.contentItem.activeFocus, true) + + compare(control.editable, false) + control.contentItem.selectAll() + keyClick(Qt.Key_5) + keyClick(Qt.Key_Return) + compare(control.value, 0) + compare(valueModifiedSpy.count, 0) + + control.editable = true + compare(control.editable, true) + control.contentItem.selectAll() + keyClick(Qt.Key_5) + keyClick(Qt.Key_Return) + compare(control.value, 5) + compare(valueModifiedSpy.count, 1) + } + + function test_wheel_data() { + return [ + { tag: "1", properties: { from: 1, to: 10, value: 1, stepSize: 1 }, upSteps: [2,3,4], downSteps: [3,2,1,1] }, + { tag: "2", properties: { from: 1, to: 10, value: 10, stepSize: 2 }, upSteps: [10,10], downSteps: [8,6,4] }, + { tag: "25", properties: { from: 0, to: 100, value: 50, stepSize: 25 }, upSteps: [75,100,100], downSteps: [75,50,25,0,0] }, + { tag: "wrap1", properties: { wrap: true, from: 1, to: 10, value: 1, stepSize: 1 }, upSteps: [2,3], downSteps: [2,1,10,9] }, + { tag: "wrap2", properties: { wrap: true, from: 1, to: 10, value: 10, stepSize: 2 }, upSteps: [1,3,5], downSteps: [3,1,10,8,6] }, + { tag: "wrap25", properties: { wrap: true, from: 0, to: 100, value: 50, stepSize: 25 }, upSteps: [75,100,0,25], downSteps: [0,100,75] } + ] + } + + function test_wheel(data) { + var ma = createTemporaryObject(mouseArea, testCase, {width: 100, height: 100}) + verify(ma) + + data.properties.wheelEnabled = true + var control = spinBox.createObject(ma, data.properties) + verify(control) + + var valueModifiedCount = 0 + var valueModifiedSpy = signalSpy.createObject(control, {target: control, signalName: "valueModified"}) + verify(valueModifiedSpy.valid) + + var delta = 120 + + var spy = signalSpy.createObject(ma, {target: ma, signalName: "wheel"}) + verify(spy.valid) + + for (var u = 0; u < data.upSteps.length; ++u) { + var wasUpEnabled = control.wrap || control.value < control.to + mouseWheel(control, control.width / 2, control.height / 2, delta, delta) + if (wasUpEnabled) + ++valueModifiedCount + compare(valueModifiedSpy.count, valueModifiedCount) + compare(spy.count, 0) // no propagation + compare(control.value, data.upSteps[u]) + } + + for (var d = 0; d < data.downSteps.length; ++d) { + var wasDownEnabled = control.wrap || control.value > control.from + mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta) + if (wasDownEnabled) + ++valueModifiedCount + compare(valueModifiedSpy.count, valueModifiedCount) + compare(spy.count, 0) // no propagation + compare(control.value, data.downSteps[d]) + } + } + + function test_initiallyDisabledIndicators_data() { + return [ + { tag: "down disabled", from: 0, value: 0, to: 99, upEnabled: true, downEnabled: false }, + { tag: "up disabled", from: 0, value: 99, to: 99, upEnabled: false, downEnabled: true }, + { tag: "inverted, down disabled", from: 99, value: 99, to: 0, upEnabled: true, downEnabled: false }, + { tag: "inverted, up disabled", from: 99, value: 0, to: 0, upEnabled: false, downEnabled: true } + ] + } + + function test_initiallyDisabledIndicators(data) { + var control = createTemporaryObject(spinBox, testCase, { from: data.from, value: data.value, to: data.to }) + verify(control) + + compare(control.up.indicator.enabled, data.upEnabled) + compare(control.down.indicator.enabled, data.downEnabled) + } + + function test_hover_data() { + return [ + { tag: "up:true", button: "up", hoverEnabled: true, value: 50 }, + { tag: "up:false", button: "up", hoverEnabled: false, value: 50 }, + { tag: "up:max", button: "up", hoverEnabled: true, value: 99 }, + { tag: "down:true", button: "down", hoverEnabled: true, value: 50 }, + { tag: "down:false", button: "down", hoverEnabled: false, value: 50 }, + { tag: "down:min", button: "down", hoverEnabled: true, value: 0 } + ] + } + + function test_hover(data) { + var control = createTemporaryObject(spinBox, testCase, {hoverEnabled: data.hoverEnabled, value: data.value}) + verify(control) + + var button = control[data.button] + compare(control.hovered, false) + compare(button.hovered, false) + + mouseMove(control, button.indicator.x + button.indicator.width / 2, button.indicator.y + button.indicator.height / 2) + compare(control.hovered, data.hoverEnabled) + compare(button.hovered, data.hoverEnabled && button.indicator.enabled) + + mouseMove(control, button.indicator.x - 1, button.indicator.y - 1) + compare(button.hovered, false) + } + + function test_hoverWhilePressed_data() { + return [ + { tag: "up" }, + { tag: "down" }, + ] + } + + // QTBUG-74688 + function test_hoverWhilePressed(data) { + var control = createTemporaryObject(spinBox, testCase, { hoverEnabled: true, value: 50 }) + verify(control) + + var button = control[data.tag] + compare(control.hovered, false) + compare(button.hovered, false) + + // Hover over the indicator. It should be hovered. + var buttonXCenter = button.indicator.x + button.indicator.width / 2 + var buttonYCenter = button.indicator.y + button.indicator.height / 2 + mouseMove(control, buttonXCenter, buttonYCenter) + compare(button.hovered, true) + + // Press on the indicator and then move the mouse outside of it. + mousePress(control, buttonXCenter, buttonYCenter) + compare(button.hovered, true) + mouseMove(control, buttonXCenter - button.indicator.width, buttonYCenter - button.indicator.height) + // It should not be pressed or hovered. + compare(button.pressed, false) + compare(button.hovered, false) + + mouseRelease(control) + } + + function test_valueFromText_data() { + return [ + { tag: "editable", editable: true }, + { tag: "non-editable", editable: false } + ] + } + + function test_valueFromText(data) { + var control = createTemporaryObject(spinBox, testCase, {editable: data.editable}) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + + var valueFromTextCalls = 0 + control.valueFromText = function(text, locale) { + ++valueFromTextCalls + return Number.fromLocaleString(locale, text); + } + + keyClick(Qt.Key_Enter) + compare(valueFromTextCalls, data.editable ? 1 : 0) + + keyClick(Qt.Key_Return) + compare(valueFromTextCalls, data.editable ? 2 : 0) + + control.focus = false + compare(valueFromTextCalls, data.editable ? 3 : 0) + } + + function test_callDefaultValueFromText() { + var control = createTemporaryObject(spinBox, testCase) + verify(control) + compare(control.valueFromText("123", control.locale), 123) + } + + function test_autoRepeat() { + var control = createTemporaryObject(spinBox, testCase) + verify(control) + + compare(control.value, 0) + + var valueSpy = signalSpy.createObject(control, {target: control, signalName: "valueChanged"}) + verify(valueSpy.valid) + + var countBefore = 0 + + // repeat up + mousePress(control.up.indicator) + verify(control.up.pressed) + compare(valueSpy.count, 0) + valueSpy.wait() + valueSpy.wait() + countBefore = valueSpy.count + mouseRelease(control.up.indicator) + verify(!control.up.pressed) + compare(valueSpy.count, countBefore) + + valueSpy.clear() + + // repeat down + mousePress(control.down.indicator) + verify(control.down.pressed) + compare(valueSpy.count, 0) + valueSpy.wait() + valueSpy.wait() + countBefore = valueSpy.count + mouseRelease(control.down.indicator) + verify(!control.down.pressed) + compare(valueSpy.count, countBefore) + + mousePress(control.up.indicator) + verify(control.up.pressed) + valueSpy.wait() + + // move inside during repeat -> continue repeat (QTBUG-57085) + mouseMove(control.up.indicator, control.up.indicator.width / 4, control.up.indicator.height / 4) + verify(control.up.pressed) + valueSpy.wait() + + valueSpy.clear() + + // move outside during repeat -> stop repeat + mouseMove(control.up.indicator, -1, -1) + verify(!control.up.pressed) + // NOTE: The following wait() is NOT a reliable way to test that the + // auto-repeat timer is not running, but there's no way dig into the + // private APIs from QML. If this test ever fails in the future, it + // indicates that the auto-repeat timer logic is broken. + wait(125) + compare(valueSpy.count, 0) + + mouseRelease(control.up.indicator, -1, -1) + verify(!control.up.pressed) + } + + function test_initialValue() { + var control = createTemporaryObject(spinBox, testCase, {from: 1000, to: 10000}) + verify(control) + compare(control.value, 1000) + } + + Component { + id: sizeBox + SpinBox { + from: 0 + to: items.length - 1 + + property var items: ["Small", "Medium", "Large"] + + validator: RegularExpressionValidator { + regularExpression: new RegExp("(Small|Medium|Large)", "i") + } + + textFromValue: function(value) { + return items[value]; + } + + valueFromText: function(text) { + for (var i = 0; i < items.length; ++i) { + if (items[i].toLowerCase().indexOf(text.toLowerCase()) === 0) + return i + } + return sb.value + } + } + } + + function test_textFromValue_data() { + return [ + { tag: "default", component: spinBox, values: [0, 10, 99], displayTexts: ["0", "10", "99"] }, + { tag: "custom", component: sizeBox, values: [0, 1, 2], displayTexts: ["Small", "Medium", "Large"] } + ] + } + + function test_textFromValue(data) { + var control = createTemporaryObject(data.component, testCase) + verify(control) + + for (var i = 0; i < data.values.length; ++i) { + control.value = data.values[i] + compare(control.value, data.values[i]) + compare(control.displayText, data.displayTexts[i]) + } + } + + function test_callDefaultTextFromValue() { + var control = createTemporaryObject(spinBox, testCase) + verify(control) + compare(control.textFromValue(123, control.locale), "123") + } + + Component { + id: overriddenSpinBox + SpinBox { + value: 50 + up.indicator: Rectangle { + property string s: "this is the one" + } + } + } + + function test_indicatorOverridden() { + var control = createTemporaryObject(overriddenSpinBox, testCase) + verify(control) + compare(control.up.indicator.s, "this is the one"); + } + + Component { + id: overriddenSpinBoxWithIds + SpinBox { + value: 50 + up.indicator: Rectangle { + id: uhOh1 + property string s: "up" + } + down.indicator: Rectangle { + id: uhOh2 + property string s: "down" + } + } + } + + function test_indicatorOverriddenWithIds() { + var control = createTemporaryObject(overriddenSpinBoxWithIds, testCase) + verify(control) + // TODO: Use failOnWarning() here when it has been implemented + // Specifying an id will result in both the default indicator implementations + // and the custom ones being created, but it shouldn't result in any TypeErrors. + compare(control.up.indicator.s, "up"); + compare(control.down.indicator.s, "down"); + } + + function test_valueEnterFromOutsideRange() { + // Check that changing from 2 to 99 goes to 98 then changing to 99 puts it back to 98 + var control = createTemporaryObject(spinBox, testCase, {from: 2, to: 98, value: 2, editable: true}) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + + keyClick(Qt.Key_Backspace) + keyClick(Qt.Key_Backspace) + keyClick(Qt.Key_9) + keyClick(Qt.Key_9) + keyClick(Qt.Key_Return) + compare(control.value, 98) + compare(control.displayText, "98") + compare(control.contentItem.text, "98") + + keyClick(Qt.Key_Backspace) + keyClick(Qt.Key_9) + keyClick(Qt.Key_Return) + compare(control.value, 98) + compare(control.displayText, "98") + compare(control.contentItem.text, "98") + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_splitview.qml b/tests/auto/quickcontrols2/controls/data/tst_splitview.qml new file mode 100644 index 00000000000..76174a3c8e9 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_splitview.qml @@ -0,0 +1,2600 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Window +import QtTest +import Qt.labs.settings + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "SplitView" + + function initTestCase() { + // For the serialization tests. + Qt.application.name = "qtquickcontrols2-splitview-auto-test" + Qt.application.domain = "org.qt-project" + Qt.application.organization = "QtProject" + } + + function findHandles(splitView) { + var handles = [] + for (var i = 0; i < splitView.children.length; ++i) { + var child = splitView.children[i] + if (child.objectName.toLowerCase().indexOf("handle") !== -1) + handles.push(child) + } + return handles + } + + function compareSizes(control, expectedGeometries, context) { + if (context === undefined) + context = "" + else + context = " (" + context + ")" + + compare(control.count, Math.floor(expectedGeometries.length / 2) + 1, + "Mismatch in actual vs expected number of split items" + context) + + var handles = findHandles(control) + compare(handles.length, Math.floor(expectedGeometries.length / 2), + "Mismatch in actual vs expected number of handle items" + context) + + for (var i = 0, splitItemIndex = 0, handleItemIndex = 0; i < expectedGeometries.length; ++i) { + var item = null + var itemType = "" + var typeSpecificIndex = -1 + if (i % 2 == 0) { + item = control.itemAt(splitItemIndex) + itemType = "split item" + typeSpecificIndex = splitItemIndex + ++splitItemIndex + } else { + item = handles[handleItemIndex] + itemType = "handle item" + typeSpecificIndex = handleItemIndex + ++handleItemIndex + } + + verify(item, itemType + " at index " + typeSpecificIndex + " should not be null" + context) + + var expectedGeometry = expectedGeometries[i] + if (expectedGeometry.hasOwnProperty("hidden")) { + // It's geometry doesn't matter because it's hidden. + verify(!item.visible, itemType + " at index " + typeSpecificIndex + " should be hidden" + context) + continue + } + + // Note that the indices mentioned here account for handles; they do not + // match the indices reported by QQuickSplitView's logging categories. + compare(item.x, expectedGeometry.x, "Mismatch in actual vs expected x value of " + + itemType + " at index " + typeSpecificIndex + context) + compare(item.y, expectedGeometry.y, "Mismatch in actual vs expected y value of " + + itemType + " at index " + typeSpecificIndex + context) + compare(item.width, expectedGeometry.width, "Mismatch in actual vs expected width value of " + + itemType + " at index " + typeSpecificIndex + context) + compare(item.height, expectedGeometry.height, "Mismatch in actual vs expected height value of " + + itemType + " at index " + typeSpecificIndex + context) + } + } + + property real defaultHorizontalHandleWidth: 10 + property real defaultVerticalHandleHeight: 10 + + + Component { + id: signalSpyComponent + SignalSpy {} + } + + Component { + id: handleComponent + Rectangle { + objectName: "handle" + implicitWidth: defaultHorizontalHandleWidth + implicitHeight: defaultVerticalHandleHeight + color: "#444" + + Text { + objectName: "handleText_" + text + text: parent.x + "," + parent.y + " " + parent.width + "x" + parent.height + color: "white" + anchors.centerIn: parent + rotation: 90 + } + } + } + + Component { + id: splitViewComponent + + SplitView { + anchors.fill: parent + handle: handleComponent + } + } + + Component { + id: rectangleComponent + + Rectangle {} + } + + function test_addItemsAfterCompletion() { + var control = createTemporaryObject(splitViewComponent, testCase) + verify(control) + + var item0 = rectangleComponent.createObject(control, { implicitWidth: 25, color: "salmon" }) + verify(item0) + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + // The last item fills the width by default, and since there is only one item... + compare(item0.x, 0) + compare(item0.y, 0) + compare(item0.width, testCase.width) + compare(item0.height, testCase.height) + + var item1 = rectangleComponent.createObject(control, { implicitWidth: 25, color: "steelblue" }) + verify(item1) + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + // Now that a second item has been added, the first item goes back to its preferred (implicit) width. + compare(item0.x, 0) + compare(item0.y, 0) + compare(item0.width, item0.implicitWidth) + compare(item0.height, testCase.height) + var handles = findHandles(control) + var handle0 = handles[0] + compare(handle0.x, item0.implicitWidth) + compare(handle0.y, 0) + compare(handle0.width, defaultHorizontalHandleWidth) + compare(handle0.height, testCase.height) + compare(item1.x, item0.implicitWidth + defaultHorizontalHandleWidth) + compare(item1.y, 0) + compare(item1.width, testCase.width - item0.implicitWidth - defaultHorizontalHandleWidth) + compare(item1.height, testCase.height) + } + + function test_addItemsWithNoSizeAfterCompletion() { + var control = createTemporaryObject(splitViewComponent, testCase) + verify(control) + + var item0 = rectangleComponent.createObject(control, { color: "salmon" }) + verify(item0) + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compare(item0.x, 0) + compare(item0.y, 0) + compare(item0.width, testCase.width) + compare(item0.height, testCase.height) + + var item1 = rectangleComponent.createObject(control, { color: "steelblue" }) + verify(item1) + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compare(item0.x, 0) + compare(item0.y, 0) + compare(item0.width, 0) + compare(item0.height, testCase.height) + var handles = findHandles(control) + var handle0 = handles[0] + compare(handle0.x, 0) + compare(handle0.y, 0) + compare(handle0.width, defaultHorizontalHandleWidth) + compare(handle0.height, testCase.height) + compare(item1.x, defaultHorizontalHandleWidth) + compare(item1.y, 0) + compare(item1.width, testCase.width - defaultHorizontalHandleWidth) + compare(item1.height, testCase.height) + } + + Component { + id: threeZeroSizedItemsComponent + + SplitView { + anchors.fill: parent + handle: handleComponent + + Rectangle { + objectName: "salmon" + color: objectName + } + Rectangle { + objectName: "navajowhite" + color: objectName + } + Rectangle { + objectName: "steelblue" + color: objectName + } + } + } + + function test_changeAttachedPropertiesAfterCompletion() { + var control = createTemporaryObject(threeZeroSizedItemsComponent, testCase) + verify(control) + + var item0 = control.itemAt(0) + compare(item0.x, 0) + compare(item0.y, 0) + compare(item0.width, 0) + compare(item0.height, testCase.height) + + var handles = findHandles(control) + var handle0 = handles[0] + compare(handle0.x, 0) + compare(handle0.y, 0) + compare(handle0.width, defaultHorizontalHandleWidth) + compare(handle0.height, testCase.height) + + var item1 = control.itemAt(1) + compare(item1.x, defaultHorizontalHandleWidth) + compare(item1.y, 0) + compare(item1.width, 0) + compare(item1.height, testCase.height) + + var handle1 = handles[1] + compare(handle1.x, defaultHorizontalHandleWidth) + compare(handle1.y, 0) + compare(handle1.width, defaultHorizontalHandleWidth) + compare(handle1.height, testCase.height) + + var item2 = control.itemAt(2) + compare(item2.x, defaultHorizontalHandleWidth * 2) + compare(item2.y, 0) + compare(item2.width, testCase.width - item2.x) + compare(item2.height, testCase.height) + + item0.SplitView.preferredWidth = 25 + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compare(item0.x, 0) + compare(item0.y, 0) + compare(item0.width, 25) + compare(item0.height, testCase.height) + compare(handle0.x, item0.width) + compare(handle0.y, 0) + compare(handle0.width, defaultHorizontalHandleWidth) + compare(handle0.height, testCase.height) + compare(item1.x, 25 + defaultHorizontalHandleWidth) + compare(item1.y, 0) + compare(item1.width, 0) + compare(item1.height, testCase.height) + compare(handle1.x, item1.x + item1.width) + compare(handle1.y, 0) + compare(handle1.width, defaultHorizontalHandleWidth) + compare(handle1.height, testCase.height) + compare(item2.x, item1.x + item1.width + defaultHorizontalHandleWidth) + compare(item2.y, 0) + compare(item2.width, testCase.width - item2.x) + compare(item2.height, testCase.height) + + item0.SplitView.minimumWidth = 50 + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compare(item0.x, 0) + compare(item0.y, 0) + compare(item0.width, 50) + compare(item0.height, testCase.height) + compare(handle0.x, item0.width) + compare(handle0.y, 0) + compare(handle0.width, defaultHorizontalHandleWidth) + compare(handle0.height, testCase.height) + compare(item1.x, 50 + defaultHorizontalHandleWidth) + compare(item1.y, 0) + compare(item1.width, 0) + compare(item1.height, testCase.height) + compare(handle1.x, item1.x + item1.width) + compare(handle1.y, 0) + compare(handle1.width, defaultHorizontalHandleWidth) + compare(handle1.height, testCase.height) + compare(item2.x, item1.x + item1.width + defaultHorizontalHandleWidth) + compare(item2.y, 0) + compare(item2.width, testCase.width - item2.x) + compare(item2.height, testCase.height) + + item0.SplitView.preferredWidth = 100 + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compare(item0.x, 0) + compare(item0.y, 0) + compare(item0.width, 100) + compare(item0.height, testCase.height) + compare(handle0.x, item0.width) + compare(handle0.y, 0) + compare(handle0.width, defaultHorizontalHandleWidth) + compare(handle0.height, testCase.height) + compare(item1.x, 100 + defaultHorizontalHandleWidth) + compare(item1.y, 0) + compare(item1.width, 0) + compare(item1.height, testCase.height) + compare(handle1.x, item1.x + item1.width) + compare(handle1.y, 0) + compare(handle1.width, defaultHorizontalHandleWidth) + compare(handle1.height, testCase.height) + compare(item2.x, item1.x + item1.width + defaultHorizontalHandleWidth) + compare(item2.y, 0) + compare(item2.width, testCase.width - item2.x) + compare(item2.height, testCase.height) + + item0.SplitView.maximumWidth = 75 + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compare(item0.x, 0) + compare(item0.y, 0) + compare(item0.width, 75) + compare(item0.height, testCase.height) + compare(handle0.x, item0.width) + compare(handle0.y, 0) + compare(handle0.width, defaultHorizontalHandleWidth) + compare(handle0.height, testCase.height) + compare(item1.x, 75 + defaultHorizontalHandleWidth) + compare(item1.y, 0) + compare(item1.width, 0) + compare(item1.height, testCase.height) + compare(handle1.x, item1.x + item1.width) + compare(handle1.y, 0) + compare(handle1.width, defaultHorizontalHandleWidth) + compare(handle1.height, testCase.height) + compare(item2.x, item1.x + item1.width + defaultHorizontalHandleWidth) + compare(item2.y, 0) + compare(item2.width, testCase.width - item2.x) + compare(item2.height, testCase.height) + + item1.SplitView.fillWidth = true + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compare(item0.x, 0) + compare(item0.y, 0) + compare(item0.width, 75) + compare(item0.height, testCase.height) + compare(handle0.x, item0.width) + compare(handle0.y, 0) + compare(handle0.width, defaultHorizontalHandleWidth) + compare(handle0.height, testCase.height) + compare(item1.x, 75 + defaultHorizontalHandleWidth) + compare(item1.y, 0) + compare(item1.width, testCase.width - 75 - defaultHorizontalHandleWidth * 2) + compare(item1.height, testCase.height) + compare(handle1.x, item1.x + item1.width) + compare(handle1.y, 0) + compare(handle1.width, defaultHorizontalHandleWidth) + compare(handle1.height, testCase.height) + compare(item2.x, testCase.width) + compare(item2.y, 0) + compare(item2.width, 0) + compare(item2.height, testCase.height) + } + + Component { + id: itemComponent + Item {} + } + + Component { + id: objectComponent + QtObject {} + } + + function test_useAttachedPropertiesIncorrectly_data() { + var properties = [ "fillWidth", "fillHeight", "minimumWidth", "minimumHeight", + "preferredWidth", "preferredHeight", "maximumWidth", "maximumHeight" ] + + var data = [] + + for (var i = 0; i < properties.length; ++i) { + var property = properties[i] + data.push({ tag: "Item," + property, component: itemComponent, property: property, + expectedWarning: /.*SplitView: attached properties must be accessed through a direct child of SplitView/ }) + } + + for (i = 0; i < properties.length; ++i) { + property = properties[i] + data.push({ tag: "QtObject," + property, component: objectComponent, property: property, + expectedWarning: /.*SplitView: attached properties can only be used on Items/ }) + } + + return data + } + + function test_useAttachedPropertiesIncorrectly(data) { + // The object (whatever it may be) is not managed by a SplitView. + var object = createTemporaryObject(data.component, testCase, { objectName: data.tag }) + verify(object) + + ignoreWarning(data.expectedWarning) + // Should warn, but not crash. + object.SplitView[data.property] = 1; + } + + function test_sizes_data() { + var splitViewWidth = testCase.width + var splitViewHeight = testCase.height + var data = [ + { + // When the combined size of items is too large, the non-fill items should just exceed + // the size of the SplitView, exactly as they would were they in a RowLayout, for example. + tag: "fillItemOnLeft", + expectedGeometries: [ + // We're the fill item, but since the combined implicitWidths + // of the other two items take up all the space, we get none. + { x: 0, y: 0, width: 0, height: splitViewHeight }, + // First handle. + { x: 0, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // The second item does not fill, so its width should be unchanged. + { x: defaultHorizontalHandleWidth, y: 0, width: 200, height: splitViewHeight }, + // Second handle. + { x: 200 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, + height: splitViewHeight }, + // The third item also gets its implicitWidth. + { x: 200 + defaultHorizontalHandleWidth * 2, y: 0, width: 200, height: splitViewHeight } + ] + }, + { + // Same as above except vertical. + tag: "fillItemOnTop", + expectedGeometries: [ + // We're the fill item, but since the combined implicitHeights + // of the other two items take up all the space, we get none. + { x: 0, y: 0, width: splitViewWidth, height: 0 }, + // First handle. + { x: 0, y: 0, width: splitViewWidth, height: defaultVerticalHandleHeight }, + // The second item does not fill, so its height should be unchanged. + { x: 0, y: defaultVerticalHandleHeight, width: splitViewWidth, height: 200 }, + // Second handle. + { x: 0, y: 200 + defaultVerticalHandleHeight, width: splitViewWidth, + height: defaultVerticalHandleHeight }, + // The third item also gets its implicitHeight. + { x: 0, y: 200 + defaultVerticalHandleHeight * 2, width: splitViewWidth, height: 200 } + ] + }, + { + tag: "fillItemInMiddle", + expectedGeometries: [ + // Our size is fixed. + { x: 0, y: 0, width: 25, height: splitViewHeight }, + // First handle. + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // The second item fills. + { x: 25 + defaultHorizontalHandleWidth, y: 0, + width: splitViewWidth - 25 - 200 - defaultHorizontalHandleWidth * 2, height: splitViewHeight }, + // Second handle. + { x: splitViewWidth - 200 - defaultHorizontalHandleWidth, y: 0, + width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // The third item's size is also fixed. + { x: splitViewWidth - 200, y: 0, width: 200, height: splitViewHeight } + ] + } + ] + return data + } + + function test_sizes(data) { + var component = Qt.createComponent("splitview/" + data.tag + ".qml") + compare(component.status, Component.Ready, component.errorString()); + var control = createTemporaryObject(component, testCase, { "handle": handleComponent }) + verify(control) + + compareSizes(control, data.expectedGeometries) + } + + Component { + id: threeSizedItemsComponent + + SplitView { + anchors.fill: parent + handle: handleComponent + + Rectangle { + objectName: "salmon" + color: objectName + implicitWidth: 25 + implicitHeight: 25 + } + Rectangle { + objectName: "navajowhite" + color: objectName + implicitWidth: 100 + implicitHeight: 100 + } + Rectangle { + objectName: "steelblue" + color: objectName + implicitWidth: 200 + implicitHeight: 200 + } + } + } + + function test_resetAttachedProperties_data() { + var splitViewWidth = testCase.width + var splitViewHeight = testCase.height + var data = [ + { + tag: "resetMinimumWidth", + orientation: Qt.Horizontal, + // Set the minimumWidth to 50. It should be used instead of implicitWidth since it's greater than 25. + splitItemIndex: 0, + propertyName: "minimumWidth", + propertyValue: 50, + expectedGeometriesBefore: [ + { x: 0, y: 0, width: 50, height: splitViewHeight }, + { x: 50, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 50 + defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 50 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, + height: splitViewHeight }, + { x: 50 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: splitViewWidth - 50 - 100 - defaultHorizontalHandleWidth * 2, height: splitViewHeight } + ], + // minimumWidth is now undefined, so implicitWidth should be used instead. + expectedGeometriesAfter: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, + height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: splitViewWidth - 25 - 100 - defaultHorizontalHandleWidth * 2, height: splitViewHeight } + ] + }, + { + tag: "resetMinimumHeight", + orientation: Qt.Vertical, + // Set the minimumHeight to 50. It should be used instead of implicitHeight since it's greater than 25. + splitItemIndex: 0, + propertyName: "minimumHeight", + propertyValue: 50, + expectedGeometriesBefore: [ + { x: 0, y: 0, width: splitViewWidth, height: 50 }, + { x: 0, y: 50, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 50 + defaultVerticalHandleHeight, width: splitViewWidth, height: 100 }, + { x: 0, y: 50 + 100 + defaultVerticalHandleHeight, width: splitViewWidth, + height: defaultVerticalHandleHeight }, + { x: 0, y: 50 + 100 + defaultVerticalHandleHeight * 2, width: splitViewWidth, + height: splitViewHeight - 50 - 100 - defaultVerticalHandleHeight * 2 } + ], + // preferredHeight is now undefined, so implicitHeight should be used instead. + expectedGeometriesAfter: [ + { x: 0, y: 0, width: splitViewWidth, height: 25 }, + { x: 0, y: 25, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + defaultVerticalHandleHeight, width: splitViewWidth, height: 100 }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight, width: splitViewWidth, + height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight * 2, width: splitViewWidth, + height: splitViewHeight - 25 - 100 - defaultVerticalHandleHeight * 2 } + ] + }, + { + tag: "resetPreferredWidth", + orientation: Qt.Horizontal, + // Set the preferredWidth to 50; it should be used instead of implicitWidth. + splitItemIndex: 0, + propertyName: "preferredWidth", + propertyValue: 50, + expectedGeometriesBefore: [ + { x: 0, y: 0, width: 50, height: splitViewHeight }, + { x: 50, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 50 + defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 50 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, + height: splitViewHeight }, + { x: 50 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: splitViewWidth - 50 - 100 - defaultHorizontalHandleWidth * 2, height: splitViewHeight } + ], + // preferredWidth is now undefined, so implicitWidth should be used instead. + expectedGeometriesAfter: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, + height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: splitViewWidth - 25 - 100 - defaultHorizontalHandleWidth * 2, height: splitViewHeight } + ] + }, + { + tag: "resetPreferredHeight", + orientation: Qt.Vertical, + // Set the preferredHeight to 50; it should be used instead of implicitHeight. + splitItemIndex: 0, + propertyName: "preferredHeight", + propertyValue: 50, + expectedGeometriesBefore: [ + { x: 0, y: 0, width: splitViewWidth, height: 50 }, + { x: 0, y: 50, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 50 + defaultVerticalHandleHeight, width: splitViewWidth, height: 100 }, + { x: 0, y: 50 + 100 + defaultVerticalHandleHeight, width: splitViewWidth, + height: defaultVerticalHandleHeight }, + { x: 0, y: 50 + 100 + defaultVerticalHandleHeight * 2, width: splitViewWidth, + height: splitViewHeight - 50 - 100 - defaultVerticalHandleHeight * 2 } + ], + // preferredHeight is now undefined, so implicitHeight should be used instead. + expectedGeometriesAfter: [ + { x: 0, y: 0, width: splitViewWidth, height: 25 }, + { x: 0, y: 25, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + defaultVerticalHandleHeight, width: splitViewWidth, height: 100 }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight, width: splitViewWidth, + height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight * 2, width: splitViewWidth, + height: splitViewHeight - 25 - 100 - defaultVerticalHandleHeight * 2 } + ] + }, + { + tag: "resetMaximumWidth", + orientation: Qt.Horizontal, + // Set the maximumWidth to 15. It should be used instead of implicitWidth since it's less than 25. + splitItemIndex: 0, + propertyName: "maximumWidth", + propertyValue: 15, + expectedGeometriesBefore: [ + { x: 0, y: 0, width: 15, height: splitViewHeight }, + { x: 15, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 15 + defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 15 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, + height: splitViewHeight }, + { x: 15 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: splitViewWidth - 15 - 100 - defaultHorizontalHandleWidth * 2, height: splitViewHeight } + ], + // maximumWidth is now undefined, so implicitWidth should be used instead. + expectedGeometriesAfter: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, + height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: splitViewWidth - 25 - 100 - defaultHorizontalHandleWidth * 2, height: splitViewHeight } + ] + }, + { + tag: "resetMaximumHeight", + orientation: Qt.Vertical, + // Set the preferredHeight to 15. It should be used instead of implicitHeight if it's not undefined. + splitItemIndex: 0, + propertyName: "maximumHeight", + propertyValue: 15, + expectedGeometriesBefore: [ + { x: 0, y: 0, width: splitViewWidth, height: 15 }, + { x: 0, y: 15, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 15 + defaultVerticalHandleHeight, width: splitViewWidth, height: 100 }, + { x: 0, y: 15 + 100 + defaultVerticalHandleHeight, width: splitViewWidth, + height: defaultVerticalHandleHeight }, + { x: 0, y: 15 + 100 + defaultVerticalHandleHeight * 2, width: splitViewWidth, + height: splitViewHeight - 15 - 100 - defaultVerticalHandleHeight * 2 } + ], + // preferredHeight is now undefined, so implicitHeight should be used instead. + expectedGeometriesAfter: [ + { x: 0, y: 0, width: splitViewWidth, height: 25 }, + { x: 0, y: 25, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + defaultVerticalHandleHeight, width: splitViewWidth, height: 100 }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight, width: splitViewWidth, + height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight * 2, width: splitViewWidth, + height: splitViewHeight - 25 - 100 - defaultVerticalHandleHeight * 2 } + ] + }, + ] + return data; + } + + function test_resetAttachedProperties(data) { + var control = createTemporaryObject(threeSizedItemsComponent, testCase, + { "orientation": data.orientation }) + verify(control) + + var splitItem = control.itemAt(data.splitItemIndex) + splitItem.SplitView[data.propertyName] = data.propertyValue + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compareSizes(control, data.expectedGeometriesBefore, "after setting attached property") + + splitItem.SplitView[data.propertyName] = undefined + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compareSizes(control, data.expectedGeometriesAfter, "after resetting attached property") + } + + function test_orientation() { + var control = createTemporaryObject(threeSizedItemsComponent, testCase) + verify(control) + + var item0 = control.itemAt(0) + compare(item0.x, 0) + compare(item0.y, 0) + compare(item0.width, item0.implicitWidth) + compare(item0.height, testCase.height) + + var handles = findHandles(control) + var handle0 = handles[0] + compare(handle0.x, item0.implicitWidth) + compare(handle0.y, 0) + compare(handle0.width, defaultHorizontalHandleWidth) + compare(handle0.height, testCase.height) + + var item1 = control.itemAt(1) + compare(item1.x, item0.width + defaultHorizontalHandleWidth) + compare(item1.y, 0) + compare(item1.width, item1.implicitWidth) + compare(item1.height, testCase.height) + + var handle1 = handles[1] + compare(handle1.x, item1.x + item1.width) + compare(handle1.y, 0) + compare(handle1.width, defaultHorizontalHandleWidth) + compare(handle1.height, testCase.height) + + var item2 = control.itemAt(2) + compare(item2.x, item0.width + item1.width + defaultHorizontalHandleWidth * 2) + compare(item2.y, 0) + compare(item2.width, testCase.width - item2.x) + compare(item2.height, testCase.height) + + control.orientation = Qt.Vertical + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compare(item0.x, 0) + compare(item0.y, 0) + compare(item0.width, testCase.width) + compare(item0.height, item0.implicitHeight) + handles = findHandles(control) + handle0 = handles[0] + compare(handle0.x, 0) + compare(handle0.y, item0.implicitHeight) + compare(handle0.width, testCase.width) + compare(handle0.height, defaultVerticalHandleHeight) + compare(item1.x, 0) + compare(item1.y, item0.height + defaultVerticalHandleHeight) + compare(item1.width, testCase.width) + compare(item1.height, item1.implicitHeight) + handle1 = handles[1] + compare(handle1.x, 0) + compare(handle1.y, item1.y + item1.height) + compare(handle1.width, testCase.width) + compare(handle1.height, defaultVerticalHandleHeight) + compare(item2.x, 0) + compare(item2.y, item0.height + item1.height + defaultVerticalHandleHeight * 2) + compare(item2.width, testCase.width) + compare(item2.height, testCase.height - item2.y) + } + + readonly property int splitViewMargins: 50 + + Component { + id: threeItemsMinSizeAndFillComponent + + SplitView { + anchors.fill: parent + handle: handleComponent + + Rectangle { + objectName: "salmon" + color: objectName + implicitWidth: 25 + implicitHeight: 25 + SplitView.minimumWidth: 25 + SplitView.minimumHeight: 25 + SplitView.fillWidth: true + SplitView.fillHeight: true + } + Rectangle { + objectName: "navajowhite" + color: objectName + implicitWidth: 100 + implicitHeight: 100 + } + Rectangle { + objectName: "steelblue" + color: objectName + implicitWidth: 200 + implicitHeight: 200 + } + } + } + + Component { + id: repeaterSplitViewComponent + + SplitView { + anchors.fill: parent + handle: handleComponent + + property alias repeater: repeater + + Repeater { + id: repeater + model: 3 + delegate: Rectangle { + objectName: "rectDelegate" + index + + SplitView.preferredWidth: 25 + + color: "#aaff0000" + + Text { + text: parent.x + "," + parent.y + " " + parent.width + "x" + parent.height + color: "white" + rotation: 90 + anchors.centerIn: parent + } + } + } + } + } + + Component { + id: hiddenItemSplitViewComponent + + SplitView { + anchors.fill: parent + handle: handleComponent + + Rectangle { + objectName: "steelblue" + color: objectName + + SplitView.minimumWidth: 50 + } + Rectangle { + objectName: "tomato" + color: objectName + + SplitView.fillWidth: true + SplitView.preferredWidth: 200 + } + Rectangle { + objectName: "navajowhite" + color: objectName + visible: false + + SplitView.minimumWidth: visible ? 100 : 0 + } + Rectangle { + objectName: "mediumseagreen" + color: objectName + + SplitView.minimumWidth: 50 + } + } + } + + function test_dragHandle_data() { + var splitViewWidth = testCase.width - splitViewMargins * 2 + var splitViewHeight = testCase.height - splitViewMargins * 2 + var data = [ + { + tag: "fillThirdItemAndDragFirstHandlePastRightSide", + component: threeSizedItemsComponent, + orientation: Qt.Horizontal, + // The index of the item that will fill. + fillIndex: 2, + // The index of the handle to be dragged. + handleIndex: 0, + // The position where the center of the handle will be. + newHandlePos: Qt.point(testCase.width + 20, testCase.height / 2), + // The expected geometry of each item managed by the SplitView before dragging the handle. + expectedGeometriesBeforeDrag: [ + // First item. + { x: 0, y: 0, width: 25, height: splitViewHeight }, + // First handle. + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // Second item. + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + // Second handle. + { x: 25 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // Third item (fills). + { x: 25 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: splitViewWidth - 25 - 100 - defaultHorizontalHandleWidth * 2, height: splitViewHeight } + ], + // The expected geometry of each item managed by the SplitView after dragging the handle. + expectedGeometriesAfterDrag: [ + // The fill item is to the right of the handle at index 0, so the handle belongs + // to the left item: us. We should consume all of the fill item's width. + { x: 0, y: 0, width: splitViewWidth - 100 - defaultHorizontalHandleWidth * 2, + height: splitViewHeight }, + // First handle. + { x: splitViewWidth - defaultHorizontalHandleWidth * 2 - 100, + y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // The second item does not fill, so its width should be unchanged. + { x: splitViewWidth - 100 - defaultHorizontalHandleWidth, + y: 0, width: 100, height: splitViewHeight }, + // Second handle. + { x: splitViewWidth - defaultHorizontalHandleWidth, + y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // The last item does fill, so it should lose all of its width. + { x: splitViewWidth, y: 0, width: 0, height: splitViewHeight } + ] + }, + { + tag: "fillThirdItemAndDragFirstHandlePastBottomSide", + component: threeSizedItemsComponent, + orientation: Qt.Vertical, + fillIndex: 2, + handleIndex: 0, + newHandlePos: Qt.point(testCase.width / 2, testCase.height + 20), + expectedGeometriesBeforeDrag: [ + { x: 0, y: 0, width: splitViewWidth, height: 25 }, + { x: 0, y: 25, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + defaultVerticalHandleHeight, width: splitViewWidth, height: 100 }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight * 2, + width: splitViewWidth, height: splitViewHeight - 25 - 100 - defaultVerticalHandleHeight * 2 } + ], + // The expected geometry of each item managed by the SplitView after dragging the handle. + expectedGeometriesAfterDrag: [ + // The fill item is to the bottom of the handle at index 0, so the handle belongs + // to the top item: us. We should consume all of the fill item's width. + { x: 0, y: 0, width: splitViewWidth, + height: splitViewHeight - 100 - defaultVerticalHandleHeight * 2 }, + // First handle. + { x: 0, y: splitViewHeight - defaultVerticalHandleHeight * 2 - 100, + width: splitViewWidth, height: defaultVerticalHandleHeight }, + // The second item does not fill, so its height should be unchanged. + { x: 0, y: splitViewWidth - 100 - defaultVerticalHandleHeight, + width: splitViewWidth, height: 100 }, + // Second handle. + { x: 0, y: splitViewHeight - defaultVerticalHandleHeight, + width: splitViewWidth, height: defaultVerticalHandleHeight }, + // The last item does fill, so it should lose all of its width. + { x: 0, y: splitViewHeight, width: splitViewWidth, height: 0 } + ] + }, + { + tag: "fillThirdItemAndDragSecondHandlePastLeftSide", + component: threeSizedItemsComponent, + orientation: Qt.Horizontal, + fillIndex: 2, + handleIndex: 1, + newHandlePos: Qt.point(-20, testCase.height / 2), + expectedGeometriesBeforeDrag: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: splitViewWidth - 25 - 100 - defaultHorizontalHandleWidth * 2, height: splitViewHeight } + ], + expectedGeometriesAfterDrag: [ + // The fill item is to the right of the handle at index 1, so the handle belongs + // to the second item; our width should be unchanged. + { x: 0, y: 0, width: 25, height: splitViewHeight }, + // First handle. + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // The second item is the one being resized, and since we're dragging its handle + // to the left, its width should decrease. + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 0, height: splitViewHeight }, + // Second handle. + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, + height: splitViewHeight }, + // The last item fills, so it should get the second item's lost width. + { x: 25 + defaultHorizontalHandleWidth * 2, y: 0, + width: splitViewWidth - 25 - defaultHorizontalHandleWidth * 2, height: splitViewHeight } + ] + }, + { + tag: "fillThirdItemAndDragSecondHandlePastTopSide", + component: threeSizedItemsComponent, + orientation: Qt.Vertical, + fillIndex: 2, + handleIndex: 1, + newHandlePos: Qt.point(testCase.width / 2, -20), + expectedGeometriesBeforeDrag: [ + { x: 0, y: 0, width: splitViewWidth, height: 25 }, + { x: 0, y: 25, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + defaultVerticalHandleHeight, width: splitViewWidth, height: 100 }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight * 2, + width: splitViewWidth, height: splitViewHeight - 25 - 100 - defaultVerticalHandleHeight * 2 } + ], + expectedGeometriesAfterDrag: [ + // The fill item is to the bottom of the handle at index 1, so the handle belongs + // to the second item; our height should be unchanged. + { x: 0, y: 0, width: splitViewWidth, height: 25 }, + // First handle. + { x: 0, y: 25, width: splitViewWidth, height: defaultVerticalHandleHeight }, + // The second item is the one being resized, and since we're dragging its handle + // to the top, its height should decrease. + { x: 0, y: 25 + defaultVerticalHandleHeight, width: splitViewWidth, height: 0 }, + // Second handle. + { x: 0, y: 25 + defaultVerticalHandleHeight, width: splitViewWidth, + height: defaultVerticalHandleHeight }, + // The last item fills, so it should get the second item's lost height. + { x: 0, y: 25 + defaultVerticalHandleHeight * 2, + width: splitViewWidth, height: splitViewHeight - 25 - defaultVerticalHandleHeight * 2 } + ] + }, + { + // First item should start off empty and then eventually take up all of 3rd item's space + // as the handle is dragged past the right side. + tag: "fillFirstItemAndDragSecondHandlePastRightSide", + component: threeSizedItemsComponent, + orientation: Qt.Horizontal, + fillIndex: 0, + handleIndex: 1, + newHandlePos: Qt.point(testCase.width + 20, testCase.height / 2), + expectedGeometriesBeforeDrag: [ + { x: 0, y: 0, width: 0, height: splitViewHeight }, + { x: 0, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 100 + defaultHorizontalHandleWidth * 2, y: 0, width: 200, height: splitViewHeight } + ], + expectedGeometriesAfterDrag: [ + // The fill item is to the left of the handle at index 1, so the handle belongs + // to the third item. Since we're moving the handle to the right side of the + // SplitView, our width should grow as we consume the width of the third item. + { x: 0, y: 0, width: splitViewWidth - 100 - defaultHorizontalHandleWidth * 2, height: splitViewHeight }, + // First handle. + { x: splitViewWidth - 100 - defaultHorizontalHandleWidth * 2, y: 0, + width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // The second item's width remains unchanged. + { x: splitViewWidth - 100 - defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + // Second handle. + { x: splitViewWidth - defaultHorizontalHandleWidth, y: 0, + width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // The last item loses its width. + { x: splitViewWidth, y: 0, width: 0, height: splitViewHeight } + ] + }, + { + // First item should start off empty and then eventually take up all of 3rd item's space + // as the handle is dragged past the bottom side. + tag: "fillFirstItemAndDragSecondHandlePastBottomSide", + component: threeSizedItemsComponent, + orientation: Qt.Vertical, + fillIndex: 0, + handleIndex: 1, + newHandlePos: Qt.point(testCase.width / 2, testCase.height + 20), + expectedGeometriesBeforeDrag: [ + { x: 0, y: 0, width: splitViewWidth, height: 0 }, + { x: 0, y: 0, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: defaultVerticalHandleHeight, width: splitViewWidth, height: 100 }, + { x: 0, y: 100 + defaultVerticalHandleHeight, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 100 + defaultVerticalHandleHeight * 2, width: splitViewWidth, height: 200 } + ], + expectedGeometriesAfterDrag: [ + // The fill item is to the top of the handle at index 1, so the handle belongs + // to the third item. Since we're moving the handle to the bottom side of the + // SplitView, our height should grow as we consume the height of the third item. + { x: 0, y: 0, width: splitViewWidth, height: splitViewHeight - 100 - defaultVerticalHandleHeight * 2 }, + // First handle. + { x: 0, y: splitViewHeight - 100 - defaultVerticalHandleHeight * 2, + width: splitViewWidth, height: defaultVerticalHandleHeight }, + // The second item's width remains unchanged. + { x: 0, y: splitViewHeight - 100 - defaultVerticalHandleHeight, width: splitViewWidth, height: 100 }, + // Second handle. + { x: 0, y: splitViewHeight - defaultVerticalHandleHeight, + width: splitViewWidth, height: defaultVerticalHandleHeight }, + // The last item loses its width. + { x: 0, y: splitViewHeight, width: splitViewHeight, height: 0 } + ] + }, + { + tag: "fillFirstItemAndDragFirstHandlePastLeftSide", + component: threeSizedItemsComponent, + orientation: Qt.Horizontal, + fillIndex: 0, + handleIndex: 0, + newHandlePos: Qt.point(-20, testCase.height / 2), + expectedGeometriesBeforeDrag: [ + { x: 0, y: 0, width: 0, height: splitViewHeight }, + { x: 0, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // The second item's implicitWidth is 100, and ours is 200. The available width is 300, + // so both items get their implicit widths. + { x: 100 + defaultHorizontalHandleWidth * 2, y: 0, width: splitViewWidth - 100, height: splitViewHeight } + ], + // Should be unchanged. + expectedGeometriesAfterDrag: [ + { x: 0, y: 0, width: 0, height: splitViewHeight }, + { x: 0, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 100 + defaultHorizontalHandleWidth * 2, y: 0, width: splitViewWidth - 100, height: splitViewHeight } + ] + }, + { + tag: "fillFirstItemWithMinWidthAndDragFirstHandlePastLeftSide", + component: threeItemsMinSizeAndFillComponent, + orientation: Qt.Horizontal, + fillIndex: 0, + handleIndex: 0, + newHandlePos: Qt.point(-20, testCase.height / 2), + expectedGeometriesBeforeDrag: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth * 2, y: 0, width: splitViewWidth - 100, height: splitViewHeight } + ], + // Should be unchanged. + expectedGeometriesAfterDrag: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth * 2, y: 0, width: splitViewWidth - 100, height: splitViewHeight } + ] + }, + { + tag: "repeater", + component: repeaterSplitViewComponent, + orientation: Qt.Horizontal, + fillIndex: 2, + handleIndex: 1, + newHandlePos: Qt.point(200, testCase.height / 2), + expectedGeometriesBeforeDrag: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 25, height: splitViewHeight }, + { x: 25 * 2 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 * 2 + defaultHorizontalHandleWidth * 2, y: 0, width: splitViewWidth - 70 , height: splitViewHeight } + ], + expectedGeometriesAfterDrag: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 105, height: splitViewHeight }, + { x: 140, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 150, y: 0, width: 150, height: splitViewHeight } + ] + }, + { + tag: "hiddenItemSplitViewComponent", + // [50] | [200 (fill)] | [hidden] | [50] + component: hiddenItemSplitViewComponent, + orientation: Qt.Horizontal, + fillIndex: 1, + handleIndex: 1, + // Drag to the horizontal centre of the SplitView. + newHandlePos: Qt.point(splitViewMargins + 150, testCase.height / 2), + expectedGeometriesBeforeDrag: [ + { x: 0, y: 0, width: 50, height: splitViewHeight }, + { x: 50, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 50 + defaultHorizontalHandleWidth, y: 0, width: 200 - defaultHorizontalHandleWidth * 2, height: splitViewHeight }, + { x: 250 - (defaultHorizontalHandleWidth * 2) + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { hidden: true }, // Third item should be hidden. + { hidden: true }, // Handle for third item should be hidden. + { x: 250 - (defaultHorizontalHandleWidth * 2) + defaultHorizontalHandleWidth * 2, y: 0, width: 50, height: splitViewHeight } + ], + expectedGeometriesAfterDrag: [ + { x: 0, y: 0, width: 50, height: splitViewHeight }, + { x: 50, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // Width of the fill item should end up smaller. + { x: 50 + defaultHorizontalHandleWidth, y: 0, width: 100 - defaultHorizontalHandleWidth * 2, height: splitViewHeight }, + { x: 150 - (defaultHorizontalHandleWidth * 2) + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { hidden: true }, // Third item should be hidden. + { hidden: true }, // Handle for third item should be hidden. + // Width of the last item should grow. + { x: 150 - (defaultHorizontalHandleWidth * 2) + defaultHorizontalHandleWidth * 2, y: 0, width: 150, height: splitViewHeight } + ] + } + ] + return data + } + + function test_dragHandle(data) { + var control = createTemporaryObject(data.component, testCase) + verify(control) + + control.orientation = data.orientation + + // Ensure that there is space to drag outside of the SplitView. + control.anchors.margins = splitViewMargins + + var fillItem = control.itemAt(data.fillIndex) + if (control.orientation === Qt.Horizontal) + fillItem.SplitView.fillWidth = true + else + fillItem.SplitView.fillHeight = true + + // Check the sizes (and visibility) of the items before the drag. + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compareSizes(control, data.expectedGeometriesBeforeDrag, "before drag") + + // Drag the handle. + var handles = findHandles(control) + var targetHandle = handles[data.handleIndex] + verify(targetHandle.visible) + mousePress(targetHandle) + verify(control.resizing) + // newHandlePos is in scene coordinates, so map it to coordinates local to the handle. + var localPos = testCase.mapToItem(targetHandle, data.newHandlePos.x, data.newHandlePos.y) + mouseMove(targetHandle, localPos.x - targetHandle.width / 2, localPos.y - targetHandle.height / 2) + verify(control.resizing) + compareSizes(control, data.expectedGeometriesAfterDrag, "after drag move") + + // The geometries should remain unchanged after releasing. + mouseRelease(targetHandle, localPos.x - targetHandle.width / 2, localPos.y - targetHandle.height / 2, Qt.LeftButton) + verify(!control.resizing) + compareSizes(control, data.expectedGeometriesAfterDrag, "after drag release") + } + + function test_splitViewGeometryChanges_data() { + var defaultSplitViewWidth = testCase.width + var defaultSplitViewHeight = testCase.height + + var data = [ + { + tag: "growWidth", + orientation: Qt.Horizontal, + splitViewWidth: 800, + expectedGeometries: [ + { x: 0, y: 0, width: 25, height: defaultSplitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: defaultSplitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 100, height: defaultSplitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, + height: defaultSplitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: 800 - 25 - 100 - defaultHorizontalHandleWidth * 2, height: defaultSplitViewHeight } + ] + }, + { + // Same as above except vertical. + tag: "growHeight", + orientation: Qt.Vertical, + splitViewHeight: 800, + expectedGeometries: [ + { x: 0, y: 0, width: defaultSplitViewWidth, height: 25 }, + { x: 0, y: 25, width: defaultSplitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + defaultVerticalHandleHeight, width: defaultSplitViewWidth, height: 100 }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight, width: defaultSplitViewWidth, + height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight * 2, width: defaultSplitViewWidth, + height: 800 - 25 - 100 - defaultVerticalHandleHeight * 2 } + ] + }, + { + tag: "shrinkWidth", + orientation: Qt.Horizontal, + splitViewWidth: 200, + expectedGeometries: [ + { x: 0, y: 0, width: 25, height: defaultSplitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: defaultSplitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 100, height: defaultSplitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, + height: defaultSplitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: 200 - 25 - 100 - defaultHorizontalHandleWidth * 2, height: defaultSplitViewHeight } + ] + }, + { + // Same as above except vertical. + tag: "shrinkHeight", + orientation: Qt.Vertical, + splitViewHeight: 200, + expectedGeometries: [ + { x: 0, y: 0, width: defaultSplitViewWidth, height: 25 }, + { x: 0, y: 25, width: defaultSplitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + defaultVerticalHandleHeight, width: defaultSplitViewWidth, height: 100 }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight, width: defaultSplitViewWidth, + height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + 100 + defaultVerticalHandleHeight * 2, width: defaultSplitViewWidth, + height: 200 - 25 - 100 - defaultVerticalHandleHeight * 2 } + ] + }, + ] + return data + } + + function test_splitViewGeometryChanges(data) { + var control = createTemporaryObject(threeSizedItemsComponent, testCase, + { "handle": handleComponent, "anchors.fill": undefined, "orientation": data.orientation }) + verify(control) + + if (data.hasOwnProperty("splitViewWidth")) + control.width = data.splitViewWidth + else + control.width = testCase.width + + if (data.hasOwnProperty("splitViewHeight")) + control.height = data.splitViewHeight + else + control.height = testCase.height + + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compareSizes(control, data.expectedGeometries) + } + + function test_splitItemImplicitSizeChanges_data() { + var defaultSplitViewWidth = testCase.width + var defaultSplitViewHeight = testCase.height + + var data = [ + { + tag: "growImplicitWidth", + orientation: Qt.Horizontal, + splitItemImplicitWidth: 50, + expectedGeometries: [ + { x: 0, y: 0, width: 50, height: defaultSplitViewHeight }, + { x: 50, y: 0, width: defaultHorizontalHandleWidth, height: defaultSplitViewHeight }, + { x: 50 + defaultHorizontalHandleWidth, y: 0, width: 100, height: defaultSplitViewHeight }, + { x: 50 + 100 + defaultHorizontalHandleWidth, y: 0, width: defaultHorizontalHandleWidth, + height: defaultSplitViewHeight }, + { x: 50 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: defaultSplitViewWidth - 50 - 100 - defaultHorizontalHandleWidth * 2, height: defaultSplitViewHeight } + ] + }, + { + tag: "growImplicitHeight", + orientation: Qt.Vertical, + splitItemImplicitHeight: 50, + expectedGeometries: [ + { x: 0, y: 0, width: defaultSplitViewWidth, height: 50 }, + { x: 0, y: 50, width: defaultSplitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 50 + defaultVerticalHandleHeight, width: defaultSplitViewWidth, height: 100 }, + { x: 0, y: 50 + 100 + defaultVerticalHandleHeight, width: defaultSplitViewWidth, + height: defaultVerticalHandleHeight }, + { x: 0, y: 50 + 100 + defaultVerticalHandleHeight * 2, width: defaultSplitViewWidth, + height: defaultSplitViewHeight - 50 - 100 - defaultVerticalHandleHeight * 2 } + ] + } + ] + return data + } + + // Tests that implicitWidth/Height changes in items are noticed by SplitView. + function test_splitItemImplicitSizeChanges(data) { + var control = createTemporaryObject(threeSizedItemsComponent, testCase, + { "handle": handleComponent, "orientation": data.orientation }) + verify(control) + + var firstItem = control.itemAt(0) + + if (data.hasOwnProperty("splitItemImplicitWidth")) + firstItem.implicitWidth = data.splitItemImplicitWidth + + if (data.hasOwnProperty("splitItemImplicitHeight")) + firstItem.implicitHeight = data.splitItemImplicitHeight + + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compareSizes(control, data.expectedGeometries) + } + + Component { + id: largerHandle + Rectangle { + objectName: "largerHandle" + implicitWidth: 20 + implicitHeight: 20 + color: "#444" + } + } + + Component { + id: smallerHandle + Rectangle { + objectName: "smallerHandle" + implicitWidth: 5 + implicitHeight: 5 + color: "#444" + } + } + + function test_handleChanges_data() { + var splitViewWidth = testCase.width + var splitViewHeight = testCase.height + + var data = [ + { + tag: "growHandleWidth", + orientation: Qt.Horizontal, + handleComponent: largerHandle, + expectedGeometries: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: 20, height: splitViewHeight }, + { x: 25 + 20, y: 0, width: 100, height: splitViewHeight }, + { x: 25 + 100 + 20, y: 0, width: 20, height: splitViewHeight }, + { x: 25 + 100 + 20 * 2, y: 0, width: splitViewWidth - 25 - 100 - 20 * 2, + height: splitViewHeight } + ] + }, + { + // Same as above except vertical. + tag: "growHandleHeight", + orientation: Qt.Vertical, + handleComponent: largerHandle, + expectedGeometries: [ + { x: 0, y: 0, width: splitViewWidth, height: 25 }, + { x: 0, y: 25, width: splitViewWidth, height: 20 }, + { x: 0, y: 25 + 20, width: splitViewWidth, height: 100 }, + { x: 0, y: 25 + 100 + 20, width: splitViewWidth, height: 20 }, + { x: 0, y: 25 + 100 + 20 * 2, width: splitViewWidth, + height: splitViewHeight - 25 - 100 - 20 * 2 } + ] + }, + { + tag: "shrinkHandleWidth", + orientation: Qt.Horizontal, + handleComponent: smallerHandle, + expectedGeometries: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: 5, height: splitViewHeight }, + { x: 25 + 5, y: 0, width: 100, height: splitViewHeight }, + { x: 25 + 100 + 5, y: 0, width: 5, height: splitViewHeight }, + { x: 25 + 100 + 5 * 2, y: 0, width: splitViewWidth - 25 - 100 - 5 * 2, + height: splitViewHeight } + ] + }, + { + // Same as above except vertical. + tag: "shrinkHandleHeight", + orientation: Qt.Vertical, + handleComponent: smallerHandle, + expectedGeometries: [ + { x: 0, y: 0, width: splitViewWidth, height: 25 }, + { x: 0, y: 25, width: splitViewWidth, height: 5 }, + { x: 0, y: 25 + 5, width: splitViewWidth, height: 100 }, + { x: 0, y: 25 + 100 + 5, width: splitViewWidth, height: 5 }, + { x: 0, y: 25 + 100 + 5 * 2, width: splitViewWidth, + height: splitViewHeight - 25 - 100 - 5 * 2 } + ] + } + ] + return data + } + + function test_handleChanges(data) { + var control = createTemporaryObject(threeSizedItemsComponent, testCase, + { "orientation": data.orientation }) + verify(control) + + control.handle = data.handleComponent + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compareSizes(control, data.expectedGeometries) + } + + function test_insertRemoveItems_data() { + var splitViewWidth = testCase.width + var splitViewHeight = testCase.height + + var data = [ + { + tag: "insertItemAtHorizontalEnd", + orientation: Qt.Horizontal, + insertItemAtIndex: 3, + expectedGeometries: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 100, height: splitViewHeight }, + { x: 25 + 100 + defaultHorizontalHandleWidth, y: 0, + width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // This was the fill item originally, but since no fill item is explicitly + // specified, and we added an item to the right of it, it is no longer the fill item + // because it's no longer last. + { x: 25 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: 200, height: splitViewHeight }, + // Handle for newly added item. + { x: 25 + 100 + 200 + defaultHorizontalHandleWidth * 2, y: 0, + width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // Newly added item. + { x: 25 + 100 + 200 + defaultHorizontalHandleWidth * 3, y: 0, + width: splitViewWidth - 25 - 100 - 200 - defaultHorizontalHandleWidth * 3, + height: splitViewHeight }, + ] + }, + { + tag: "insertItemAtHorizontalBeginning", + orientation: Qt.Horizontal, + insertItemAtIndex: 0, + expectedGeometries: [ + // Newly added item. + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, width: 25, height: splitViewHeight }, + { x: 25 * 2 + defaultHorizontalHandleWidth, y: 0, + width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 * 2 + defaultHorizontalHandleWidth * 2, y: 0, width: 100, height: splitViewHeight }, + { x: 25 * 2 + 100 + defaultHorizontalHandleWidth * 2, y: 0, + width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // Fill item doesn't change. + { x: 25 * 2 + 100 + defaultHorizontalHandleWidth * 3, y: 0, + width: splitViewWidth - 25 * 2 - 100 - defaultHorizontalHandleWidth * 3, + height: splitViewHeight }, + ] + }, + { + tag: "removeItemFromHorizontalEnd", + orientation: Qt.Horizontal, + removeItemAtIndex: 2, + expectedGeometries: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, + width: splitViewWidth - 25 - defaultHorizontalHandleWidth, height: splitViewHeight }, + ] + }, + { + tag: "removeItemFromHorizontalBeginning", + orientation: Qt.Horizontal, + removeItemAtIndex: 0, + expectedGeometries: [ + { x: 0, y: 0, width: 100, height: splitViewHeight }, + { x: 100, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 100 + defaultHorizontalHandleWidth, y: 0, + width: splitViewWidth - 100 - defaultHorizontalHandleWidth, height: splitViewHeight }, + ] + } + ] + return data + } + + Component { + id: smallRectComponent + + Rectangle { + objectName: "darkseagreen" + color: objectName + implicitWidth: 25 + implicitHeight: 25 + } + } + + function test_insertRemoveItems(data) { + var control = createTemporaryObject(threeSizedItemsComponent, testCase, + { "orientation": data.orientation }) + verify(control) + + if (data.hasOwnProperty("removeItemAtIndex")) { + var itemToRemove = control.itemAt(data.removeItemAtIndex) + verify(itemToRemove) + + control.removeItem(itemToRemove) + } else if (data.hasOwnProperty("insertItemAtIndex")) { + var itemToAdd = smallRectComponent.createObject(control) + control.insertItem(data.insertItemAtIndex, itemToAdd) + } + + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compareSizes(control, data.expectedGeometries) + } + + function test_removeAllItems() { + var control = createTemporaryObject(threeSizedItemsComponent, testCase) + verify(control) + + while (control.count > 0) + var itemToRemove = control.removeItem(control.itemAt(0)) + // Shouldn't crash. + } + + function test_hideItems_data() { + var splitViewWidth = testCase.width + var splitViewHeight = testCase.height + + var data = [ + { + tag: "hideItemAtHorizontalEnd", + orientation: Qt.Horizontal, + hideIndices: [2], + expectedGeometries: [ + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, + width: splitViewWidth - 25 - defaultHorizontalHandleWidth, height: splitViewHeight }, + { hidden: true }, // Handle for second item should be hidden. + { hidden: true } // Last item should be hidden. + ] + }, + { + tag: "hideItemAtHorizontalBeginning", + orientation: Qt.Horizontal, + hideIndices: [0], + expectedGeometries: [ + { hidden: true }, // First item should be hidden. + { hidden: true }, // Handle for first item should be hidden. + { x: 0, y: 0, width: 100, height: splitViewHeight }, + { x: 100, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 100 + defaultHorizontalHandleWidth, y: 0, + width: splitViewWidth - 100 - defaultHorizontalHandleWidth, height: splitViewHeight } + ] + }, + { + tag: "hideItemAtVerticalEnd", + orientation: Qt.Vertical, + hideIndices: [2], + expectedGeometries: [ + { x: 0, y: 0, width: splitViewWidth, height: 25 }, + { x: 0, y: 25, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 25 + defaultVerticalHandleHeight, + width: splitViewWidth, height: splitViewHeight - 25 - defaultVerticalHandleHeight }, + { hidden: true }, // Handle for second item should be hidden. + { hidden: true } // Last item should be hidden. + ] + }, + { + tag: "hideItemAtVerticalBeginning", + orientation: Qt.Vertical, + hideIndices: [0], + expectedGeometries: [ + { hidden: true }, // First item should be hidden. + { hidden: true }, // Handle for first item should be hidden. + { x: 0, y: 0, width: splitViewWidth, height: 100 }, + { x: 0, y: 100, width: splitViewWidth, height: defaultVerticalHandleHeight }, + { x: 0, y: 100 + defaultVerticalHandleHeight, + width: splitViewWidth, height: splitViewHeight - 100 - defaultVerticalHandleHeight } + ] + }, + { + // No handles should be visible when there's only one item. + tag: "hideLastTwoHorizontalItems", + orientation: Qt.Horizontal, + hideIndices: [1, 2], + expectedGeometries: [ + { x: 0, y: 0, width: splitViewWidth, height: splitViewHeight }, + { hidden: true }, // Handle for first item should be hidden. + { hidden: true }, // Second item should be hidden. + { hidden: true }, // Handle for second item should be hidden. + { hidden: true } // Third item should be hidden. + ] + } + ] + return data + } + + function test_hideItems(data) { + var control = createTemporaryObject(threeSizedItemsComponent, testCase, + { "orientation": data.orientation }) + verify(control) + + for (var i = 0; i < data.hideIndices.length; ++i) { + var itemToHide = control.itemAt(data.hideIndices[i]) + verify(itemToHide) + itemToHide.visible = false + } + + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compareSizes(control, data.expectedGeometries) + } + + function test_hideAndShowItems_data() { + var splitViewWidth = testCase.width + var splitViewHeight = testCase.height + + var data = [ + { + tag: "hideLastTwoHorizontalItems", + orientation: Qt.Horizontal, + hideIndices: [1, 2], + expectedGeometriesAfterHiding: [ + { x: 0, y: 0, width: splitViewWidth, height: splitViewHeight }, + { hidden: true }, // Handle for first item should be hidden. + { hidden: true }, // Second item should be hidden. + { hidden: true }, // Handle for second item should be hidden. + { hidden: true } // Third item should be hidden. + ], + showIndices: [1], + expectedGeometriesAfterShowing: [ + // First item should be visible with its implicit size. + { x: 0, y: 0, width: 25, height: splitViewHeight }, + // Handle for first item should be visible. + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // Second item should be visible and fill. + { x: 25 + defaultHorizontalHandleWidth, y: 0, + width: splitViewWidth - 25 - defaultHorizontalHandleWidth, height: splitViewHeight }, + { hidden: true }, // Handle for second item should be hidden. + { hidden: true } // Third item should be hidden. + ] + } + ] + return data + } + + function test_hideAndShowItems(data) { + var control = createTemporaryObject(threeSizedItemsComponent, testCase, + { "orientation": data.orientation }) + verify(control) + + for (var i = 0; i < data.hideIndices.length; ++i) { + var itemToHide = control.itemAt(data.hideIndices[i]) + verify(itemToHide) + itemToHide.visible = false + } + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compareSizes(control, data.expectedGeometriesAfterHiding, "after hiding") + + for (i = 0; i < data.showIndices.length; ++i) { + var itemToShow = control.itemAt(data.showIndices[i]) + verify(itemToShow) + itemToShow.visible = true + } + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compareSizes(control, data.expectedGeometriesAfterShowing, "after showing") + } + + function test_moveHiddenItems_data() { + var splitViewWidth = testCase.width + var splitViewHeight = testCase.height + + var data = [ + { + tag: "hideSecondItemAndMoveItToFirst", + orientation: Qt.Horizontal, + hideIndices: [1], + moveFromIndex: 1, + moveToIndex: 0, + expectedGeometriesAfterMoving: [ + { hidden: true }, // First item (was second) should be hidden. + { hidden: true }, // Handle for first item should be hidden. + // Second item (was first) should get its implicit size. + { x: 0, y: 0, width: 25, height: splitViewHeight }, + { x: 25, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 25 + defaultHorizontalHandleWidth, y: 0, + width: splitViewWidth - 25 - defaultHorizontalHandleWidth, height: splitViewHeight }, + ], + showIndices: [0], + expectedGeometriesAfterShowing: [ + // First item (was second) should be visible with its implicit size. + { x: 0, y: 0, width: 100, height: splitViewHeight }, + // Handle for first item (was second) should be visible. + { x: 100, y: 0, width: defaultHorizontalHandleWidth, height: splitViewHeight }, + // Second item (was first) should be visible with its implicit size. + { x: 100 + defaultHorizontalHandleWidth, y: 0, + width: 25, height: splitViewHeight }, + { x: 100 + 25 + defaultHorizontalHandleWidth, y: 0, + width: defaultHorizontalHandleWidth, height: splitViewHeight }, + { x: 100 + 25 + defaultHorizontalHandleWidth * 2, y: 0, + width: splitViewWidth - 100 - 25 - defaultHorizontalHandleWidth * 2, height: splitViewHeight } + ] + } + ] + return data + } + + function test_moveHiddenItems(data) { + var control = createTemporaryObject(threeSizedItemsComponent, testCase, + { "orientation": data.orientation }) + verify(control) + + for (var i = 0; i < data.hideIndices.length; ++i) { + var itemToHide = control.itemAt(data.hideIndices[i]) + verify(itemToHide) + itemToHide.visible = false + } + + control.moveItem(data.moveFromIndex, data.moveToIndex) + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compareSizes(control, data.expectedGeometriesAfterMoving, "after moving") + + for (i = 0; i < data.showIndices.length; ++i) { + var itemToShow = control.itemAt(data.showIndices[i]) + verify(itemToShow) + itemToShow.visible = true + } + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compareSizes(control, data.expectedGeometriesAfterShowing, "after showing") + } + + Component { + id: flickableComponent + + Flickable { + anchors.fill: parent + anchors.margins: 100 + } + } + + function test_draggingHandleInFlickable() { + var flickable = createTemporaryObject(flickableComponent, testCase) + verify(flickable) + + var control = threeSizedItemsComponent.createObject(flickable.contentItem) + verify(control) + + control.anchors.fill = undefined + control.width = 400 + control.height = control.parent.height - 100 + flickable.contentWidth = control.width + flickable.contentHeight = control.height + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + + var contentXSpy = signalSpyComponent.createObject(flickable, + { target: flickable, signalName: "contentXChanged" }) + verify(contentXSpy.valid) + var contentYSpy = signalSpyComponent.createObject(flickable, + { target: flickable, signalName: "contentYChanged" }) + verify(contentYSpy.valid) + + // Drag the first handle to the right; + // the flickable's contentX and contentY shouldn't change. + var firstItem = control.itemAt(0) + var firstItemOriginalWidth = firstItem.width + var handles = findHandles(control) + var firstHandle = handles[0] + // Add some vertical movement in there as well. + mouseDrag(firstHandle, firstHandle.width / 2, firstHandle.height / 2, 100, 50) + compare(contentXSpy.count, 0) + compare(contentYSpy.count, 0) + verify(firstItem.width > firstItemOriginalWidth) + + // Now do the same except vertically. + control.orientation = Qt.Vertical + control.width = control.parent.width - 100 + control.height = 400 + var firstItemOriginalHeight = firstItem.height + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + + // Add some horizontal movement in there as well. + mouseDrag(firstHandle, firstHandle.width / 2, firstHandle.height / 2, 50, 100) + compare(contentXSpy.count, 0) + compare(contentYSpy.count, 0) + verify(firstItem.height > firstItemOriginalHeight) + } + + Component { + id: splitViewHandleContainmentMaskComponent + + MouseArea { + property alias mouseArea1: mouseArea1 + property alias mouseArea2: mouseArea2 + property alias splitView: splitView + + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.LeftButton + + Rectangle { + anchors.fill: parent + color: 'green' + opacity: 0.3 + } + + SplitView { + id: splitView + + anchors { + fill: parent + margins: 100 + } + + handle: Rectangle { + id: handleRoot + + readonly property bool containsMouse: SplitHandle.hovered + readonly property int defaultSize: 2 + + implicitWidth: splitView.orientation === Qt.Horizontal ? handleRoot.defaultSize : splitView.width + implicitHeight: splitView.orientation === Qt.Vertical ? handleRoot.defaultSize : splitView.height + + color: 'red' + objectName: "handle" + + Text { + objectName: "handleText_" + text + text: parent.x + "," + parent.y + " " + parent.width + "x" + parent.height + color: "black" + anchors.centerIn: parent + rotation: 90 + } + + containmentMask: Item { + readonly property real extraOverflow: 20 + + x: splitView.orientation === Qt.Horizontal ? -extraOverflow : 0 + y: splitView.orientation === Qt.Horizontal ? 0 : -extraOverflow + width: splitView.orientation === Qt.Horizontal ? handleRoot.defaultSize + (extraOverflow * 2): handleRoot.width + height: splitView.orientation === Qt.Horizontal ? handleRoot.height : handleRoot.defaultSize + (extraOverflow * 2) + } + } + + MouseArea { + id: mouseArea1 + + SplitView.fillHeight: splitView.orientation === Qt.Horizontal + SplitView.fillWidth: splitView.orientation === Qt.Vertical + SplitView.preferredWidth: splitView.orientation === Qt.Horizontal ? parent.width / 2 : undefined + SplitView.preferredHeight: splitView.orientation === Qt.Vertical ? parent.height / 2 : undefined + hoverEnabled: true + + Rectangle { + anchors.fill: parent + color: 'cyan' + opacity: 0.3 + } + } + + MouseArea { + id: mouseArea2 + + SplitView.fillHeight: splitView.orientation === Qt.Horizontal + SplitView.fillWidth: splitView.orientation === Qt.Vertical + SplitView.preferredWidth: splitView.orientation === Qt.Horizontal ? parent.width / 2 : undefined + SplitView.preferredHeight: splitView.orientation === Qt.Vertical ? parent.height / 2 : undefined + hoverEnabled: true + + Rectangle { + anchors.fill: parent + color: 'cyan' + opacity: 0.3 + } + } + } + } + } + + function test_handleContainmentMask_data() { + const data = [ + { + tag: "handleContainmentMaskHorizontalLeftEdgeDragRight", + orientation: Qt.Horizontal, + press: { + x: (handle) => handle.containmentMask.x, + y: (handle) => handle.height / 2 + }, + dx: 25, + dy: 0, + }, + { + tag: "handleContainmentMaskHorizontalRightEdgeDragLeft", + orientation: Qt.Horizontal, + press: { + x: (handle) => handle.containmentMask.x, + y: (handle) => handle.height / 2 + }, + dx: -50, + dy: 0 + }, + { + tag: "handleContainmentMaskHorizontalTopEdgeDragRight", + orientation: Qt.Horizontal, + press: { + x: (handle) => handle.containmentMask.x + handle.containmentMask.width - 1, + y: (handle) => handle.height / 2 + }, + dx: 25, + dy: 0, + }, + { + tag: "handleContainmentMaskHorizontalBottomEdgeDragLeft", + orientation: Qt.Horizontal, + press: { + x: (handle) => handle.containmentMask.x + handle.containmentMask.width - 1, + y: (handle) => handle.containmentMask.y + }, + dx: -50, + dy: 0 + }, + { + tag: "handleContainmentMaskVerticalTopEdgeDragUp", + orientation: Qt.Vertical, + press: { + x: (handle) => handle.width / 2, + y: (handle) => handle.containmentMask.y + }, + dx: 0, + dy: -40, + }, + { + tag: "handleContainmentMaskVerticalTopEdgeDragDown", + orientation: Qt.Vertical, + press: { + x: (handle) => handle.width / 2, + y: (handle) => handle.containmentMask.y + }, + dx: 0, + dy: 70 + }, + { + tag: "handleContainmentMaskVerticalBottomEdgeDragUp", + orientation: Qt.Vertical, + press: { + x: (handle) => handle.width / 2, + y: (handle) => handle.containmentMask.y + handle.containmentMask.height - 1 + }, + dx: 0, + dy: -40, + }, + { + tag: "handleContainmentMaskVerticalBottomEdgeDragDown", + orientation: Qt.Vertical, + press: { + x: (handle) => handle.width / 2, + y: (handle) => handle.containmentMask.y + handle.containmentMask.height - 1 + }, + dx: 0, + dy: 70 + } + ] + + return data + } + + function test_handleContainmentMask(data) { + const control = createTemporaryObject(splitViewHandleContainmentMaskComponent, testCase) + verify(control) + const splitView = control.splitView + splitView.orientation = data.orientation + + const handle = findHandles(splitView)[0] + if (splitView.orientation === Qt.Vertical) + handle.height = handle.defaultHeight + + verify(isPolishScheduled(splitView)) + verify(waitForItemPolished(splitView)) + + const firstItem = control.mouseArea1 + const secondItem = control.mouseArea2 + + const backgroundMouseAreaPress = signalSpyComponent.createObject(control, + { target: control, signalName: "onPressed" }) + + const mouseArea1Press = signalSpyComponent.createObject(firstItem, + { target: firstItem, signalName: "onPressed" }) + + const mouseArea2Press = signalSpyComponent.createObject(secondItem, + { target: secondItem, signalName: "onPressed" }) + + verify(backgroundMouseAreaPress.valid) + verify(mouseArea1Press.valid) + verify(mouseArea2Press.valid) + + const firstItemWidthBeforeDrag = firstItem.width + const secondItemWidthBeforeDrag = secondItem.width + const firstItemHeightBeforeDrag = firstItem.height + const secondItemHeightBeforeDrag = secondItem.height + + const dx = data.dx + const dy = data.dy + const pressX = data.press.x(handle) + const pressY = data.press.y(handle) + + mousePress(handle, pressX, pressY, Qt.LeftButton) + mouseMove(handle, pressX + dx, pressY + dy, -1, Qt.LeftButton) + mouseRelease(handle, pressX + dx, pressY + dy, Qt.LeftButton) + + compare(firstItem.width, firstItemWidthBeforeDrag + dx) + compare(secondItem.width, secondItemWidthBeforeDrag - dx) + compare(firstItem.height, firstItemHeightBeforeDrag + dy) + compare(secondItem.height, secondItemHeightBeforeDrag - dy) + + compare(backgroundMouseAreaPress.count, 0) + compare(mouseArea1Press.count, 0) + compare(mouseArea2Press.count, 0) + } + + function test_handleContainmentMaskHovered_data() { + const data = [ + { + tag: "firstItemHorizontalHover", + orientation: Qt.Horizontal, + press: { + "x": (item) => item.width / 2, + "y": (item) => item.height / 2 + }, + hoverItem: "firstItem", + expectedHover: { + "firstItem": true, + "handle": false, + "secondItem": false + } + }, + { + tag: "handleHorizontalHoverOnTheLeft", + orientation: Qt.Horizontal, + press: { + "x": (item) => item.containmentMask.x, + "y": (item) => item.height / 2 + }, + hoverItem: "handle", + expectedHover: { + "firstItem": true, + "handle": true, + "secondItem": false + } + }, + { + tag: "handleHorizontalHoverOnTheCenter", + orientation: Qt.Horizontal, + press: { + "x": (item) => item.width / 2, + "y": (item) => item.height / 2 + }, + hoverItem: "handle", + expectedHover: { + "firstItem": false, + "handle": true, + "secondItem": false + } + }, + { + tag: "handleHorizontalHoverOnTheRight", + orientation: Qt.Horizontal, + press: { + "x": (item) => item.containmentMask.x + item.containmentMask.width - 1, + "y": (item) => item.height / 2 + }, + hoverItem: "handle", + expectedHover: { + "firstItem": false, + "handle": true, + "secondItem": true + } + }, + { + tag: "secondItemHorizontalHover", + orientation: Qt.Horizontal, + press: { + "x": (item) => item.width / 2, + "y": (item) => item.height / 2 + }, + hoverItem: "secondItem", + expectedHover: { + "firstItem": false, + "handle": false, + "secondItem": true + } + }, + { + tag: "firstItemVerticalHover", + orientation: Qt.Vertical, + press: { + "x": (item) => item.width / 2, + "y": (item) => item.height / 2 + }, + hoverItem: "firstItem", + expectedHover: { + "firstItem": true, + "handle": false, + "secondItem": false + } + }, + { + tag: "handleVerticalHoverOnTheTop", + orientation: Qt.Vertical, + press: { + "x": (item) => item.width / 2, + "y": (item) => item.containmentMask.y + }, + hoverItem: "handle", + expectedHover: { + "firstItem": true, + "handle": true, + "secondItem": false + } + }, + { + tag: "handleVerticalHoverOnTheCenter", + orientation: Qt.Vertical, + press: { + "x": (item) => item.width / 2, + "y": (item) => item.height / 2 + }, + hoverItem: "handle", + expectedHover: { + "firstItem": false, + "handle": true, + "secondItem": false + } + }, + { + tag: "handleVerticalHoverOnTheBottom", + orientation: Qt.Vertical, + press: { + "x": (item) => item.width / 2, + "y": (item) => item.containmentMask.y + item.containmentMask.height - 1 + }, + hoverItem: "handle", + expectedHover: { + "firstItem": false, + "handle": true, + "secondItem": true + } + }, + { + tag: "secondItemVerticalHover", + orientation: Qt.Vertical, + press: { + "x": (item) => item.width / 2, + "y": (item) => item.height / 2 + }, + hoverItem: "secondItem", + expectedHover: { + "firstItem": false, + "handle": false, + "secondItem": true + } + } + ] + + return data + } + + function test_handleContainmentMaskHovered(data) { + if ((Qt.platform.pluginName === "offscreen") || (Qt.platform.pluginName === "minimal")) + skip("Mouse hovering not functional on offscreen/minimal platforms") + + const control = createTemporaryObject(splitViewHandleContainmentMaskComponent, testCase) + verify(control) + const splitView = control.splitView + splitView.orientation = data.orientation + + const handle = findHandles(splitView)[0] + if (splitView.orientation === Qt.Vertical) + handle.height = handle.defaultHeight + + verify(isPolishScheduled(splitView)) + verify(waitForItemPolished(splitView)) + + const firstItem = control.mouseArea1 + const secondItem = control.mouseArea2 + + verify(!firstItem.containsMouse) + verify(!secondItem.containsMouse) + verify(!handle.containsMouse) + + const actualItem = { + "firstItem": firstItem, + "secondItem": secondItem, + "handle": handle + }[data.hoverItem] + + const pressX = data.press.x(actualItem) + const pressY = data.press.y(actualItem) + + // Test fails if we don't do two moves for some reason... + mouseMove(actualItem, pressX, pressY) + mouseMove(actualItem, pressX, pressY) + + compare(firstItem.containsMouse, data.expectedHover.firstItem) + compare(secondItem.containsMouse, data.expectedHover.secondItem) + compare(handle.containsMouse, data.expectedHover.handle) + + // Hide SplitView, then all children shouldn't be hovered + control.visible = false + + verify(isPolishScheduled(splitView)) + verify(waitForItemPolished(splitView)) + + verify(!control.containsMouse) + verify(!firstItem.containsMouse) + verify(!secondItem.containsMouse) + verify(!handle.containsMouse) + } + + function test_hoveredPressed() { + if ((Qt.platform.pluginName === "offscreen") || (Qt.platform.pluginName === "minimal")) + skip("Mouse hovering not functional on offscreen/minimal platforms") + + var control = createTemporaryObject(threeSizedItemsComponent, testCase) + verify(control) + control.anchors.margins = 50 + + var handles = findHandles(control) + var firstHandle = handles[0] + + var handleCenter = control.mapFromItem(firstHandle, firstHandle.width / 2, firstHandle.height / 2) + // Test fails if we don't do two moves for some reason... + mouseMove(control, handleCenter.x, handleCenter.y) + mouseMove(control, handleCenter.x, handleCenter.y) + verify(firstHandle.SplitHandle.hovered) + verify(!firstHandle.SplitHandle.pressed) + + mousePress(control, handleCenter.x, handleCenter.y) + verify(firstHandle.SplitHandle.hovered) + verify(firstHandle.SplitHandle.pressed) + + mouseRelease(control, handleCenter.x, handleCenter.y) + verify(firstHandle.SplitHandle.hovered) + verify(!firstHandle.SplitHandle.pressed) + + mouseMove(control, 0, 0) + verify(!firstHandle.SplitHandle.hovered) + verify(!firstHandle.SplitHandle.pressed) + } + + // Tests removing/adding/moving an item while it's pressed. + function test_modifyWhileHoveredPressed() { + if ((Qt.platform.pluginName === "offscreen") || (Qt.platform.pluginName === "minimal")) + skip("Mouse hovering not functional on offscreen/minimal platforms") + + var control = createTemporaryObject(threeSizedItemsComponent, testCase) + verify(control) + control.anchors.margins = 50 + + var handles = findHandles(control) + var firstHandle = handles[0] + + // First, ensure that the handle is hovered + pressed. + var handleCenter = control.mapFromItem(firstHandle, firstHandle.width / 2, firstHandle.height / 2) + // Test fails if we don't do two moves for some reason... + mouseMove(control, handleCenter.x, handleCenter.y) + mouseMove(control, handleCenter.x, handleCenter.y) + verify(firstHandle.SplitHandle.hovered) + verify(!firstHandle.SplitHandle.pressed) + + mousePress(control, handleCenter.x, handleCenter.y) + verify(firstHandle.SplitHandle.hovered) + verify(firstHandle.SplitHandle.pressed) + + // Then, remove it by removing the first item. + control.removeItem(control.itemAt(0)) + handles = findHandles(control) + firstHandle = null + compare(handles.length, 1) + + // No handles should be hovered/pressed. + for (var i = 0; i < handles.length; ++i) { + var handle = handles[i] + verify(!handle.SplitHandle.hovered, "handle at index " + i + " should not be hovered") + verify(!handle.SplitHandle.pressed, "handle at index " + i + " should not be hovered") + } + + mouseRelease(control, handleCenter.x, handleCenter.y) + } + + Component { + id: settingsComponent + Settings { + id: settings + } + } + + function test_saveAndRestoreState_data() { + return [ + { tag: "Horizontal", orientation: Qt.Horizontal, propertyName: "preferredWidth", propertyValue: 123 }, + { tag: "Vertical", orientation: Qt.Vertical, propertyName: "preferredHeight", propertyValue: 234 } + ] + } + + function test_saveAndRestoreState(data) { + var control = createTemporaryObject(threeSizedItemsComponent, testCase, { orientation: data.orientation }) + verify(control) + compare(control.orientation, data.orientation) + + var lastItem = control.itemAt(2) + verify(lastItem) + lastItem.SplitView[data.propertyName] = data.propertyValue + + // Save the state. + var settings = createTemporaryObject(settingsComponent, testCase) + verify(settings) + settings.setValue("splitView", control.saveState()) + + // Recreate the item to restore it to its "default" values. + control = createTemporaryObject(threeSizedItemsComponent, testCase) + lastItem = control.itemAt(2) + verify(lastItem) + compare(lastItem.SplitView[data.propertyName], -1) + + settings = createTemporaryObject(settingsComponent, testCase) + verify(settings) + + // Restore the state. + control.restoreState(settings.value("splitView")) + compare(lastItem.SplitView[data.propertyName], data.propertyValue) + } + + function test_changePreferredSizeDuringLayout() { + var control = createTemporaryObject(threeSizedItemsComponent, testCase) + verify(control) + + var firstItem = control.itemAt(0) + var secondItem = control.itemAt(1) + secondItem.widthChanged.connect(function() { + if (secondItem.width < 10) + firstItem.SplitView.preferredWidth = 50 + }) + + // Change the size of the item so that a layout happens, but + // make the size small enough that the item's onWidthChanged handler gets triggered. + // The onWidthChanged handler will set the preferredWidth of another item during the + // layout, so we need to make sure the assignment isn't lost since we return early in that case. + secondItem.implicitWidth = 5 + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compare(secondItem.width, 5) + compare(firstItem.width, 50) + + // Now do the same for height. + control.orientation = Qt.Vertical + secondItem.heightChanged.connect(function() { + if (secondItem.height < 10) + firstItem.SplitView.preferredHeight = 50 + }) + // Get the polishes for the orientation out of the way so that they + // don't intefere with our results. + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + + secondItem.implicitHeight = 5 + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + compare(secondItem.height, 5) + compare(firstItem.height, 50) + } + + // When the user drags a handle, we internally set preferredWidth/Height + // to reflect the new value. However, we also have to make sure that when + // we do so, it doesn't trigger a delayed layout. This is why we have + // m_ignoreNextDelayedLayoutRequest. This test checks that + // m_ignoreNextDelayedLayoutRequest doesn't interfere with any action from + // the user that results in a delayed layout. + function test_changePreferredSizeDuringLayoutWhileDraggingHandle() { + var control = createTemporaryObject(threeSizedItemsComponent, testCase) + verify(control) + + var firstItem = control.itemAt(0) + var secondItem = control.itemAt(1) + firstItem.widthChanged.connect(function() { + if (firstItem.width === 0) + secondItem.SplitView.preferredWidth = 50 + }) + + // Start dragging the handle. + var handles = findHandles(control) + var targetHandle = handles[0] + mousePress(targetHandle) + verify(control.resizing) + var localPos = testCase.mapToItem(targetHandle, 15, testCase.height / 2) + + // Move the handle to the very left, so that the item's width becomes zero. + mouseMove(targetHandle, -100, targetHandle.height / 2) + verify(control.resizing) + compare(firstItem.width, 0) + compare(secondItem.SplitView.preferredWidth, 50) + compare(secondItem.width, 50) + mouseRelease(targetHandle, -100, targetHandle.height / 2, Qt.LeftButton) + verify(!control.resizing) + } + + Component { + id: oneItemComponent + + SplitView { + Item {} + } + } + + // QTBUG-79270 + function test_hideSplitViewWithOneItem() { + var control = createTemporaryObject(oneItemComponent, testCase) + verify(control) + // Shouldn't be an assertion failure. + control.visible = false + } + + // QTBUG-79302: ensure that the Repeater's items are actually generated. + // test_dragHandle:repeater tests dragging behavior with a Repeater. + function test_repeater(data) { + var control = createTemporaryObject(repeaterSplitViewComponent, testCase) + verify(control) + compare(control.repeater.count, 3) + compare(control.contentChildren.length, 3) + } + + Component { + id: hoverableChildrenSplitViewComponent + + SplitView { + handle: handleComponent + anchors.fill: parent + + MouseArea { + objectName: "mouseArea1" + hoverEnabled: true + + SplitView.preferredWidth: 200 + } + MouseArea { + objectName: "mouseArea2" + hoverEnabled: true + } + } + } + + function test_hoverableChilden() { + if (Qt.platform.pluginName === "offscreen" || Qt.platform.pluginName === "minimal") + skip("Mouse hovering not functional on offscreen/minimal platforms") + + var control = createTemporaryObject(hoverableChildrenSplitViewComponent, testCase) + verify(control) + + verify(isPolishScheduled(control)) + verify(waitForItemPolished(control)) + + // Move the mouse over the handle. + var handles = findHandles(control) + var targetHandle = handles[0] + // Test fails if we don't do two moves for some reason... QTBUG-94968 + mouseMove(targetHandle, targetHandle.width / 2, targetHandle.height / 2) + mouseMove(targetHandle, targetHandle.width / 2, targetHandle.height / 2) + verify(targetHandle.SplitHandle.hovered) + + // Move the mouse to the MouseArea on the left. The handle should no longer be hovered. + mouseMove(control, 100, control.height / 2) + verify(!targetHandle.SplitHandle.hovered) + + // Move the mouse back over the handle. + mouseMove(targetHandle, targetHandle.width / 2, targetHandle.height / 2) + mouseMove(targetHandle, targetHandle.width / 2, targetHandle.height / 2) + verify(targetHandle.SplitHandle.hovered) + + // Move the mouse to the MouseArea on the right. The handle should no longer be hovered. + mouseMove(control, control.width - 100, control.height / 2) + verify(!targetHandle.SplitHandle.hovered) + } + + function test_touch() { + let control = createTemporaryObject(threeSizedItemsComponent, testCase) + verify(control) + + let touch = touchEvent(control) + + let handles = findHandles(control) + let firstHandle = handles[0] + let handleCenter = control.mapFromItem(firstHandle, firstHandle.width / 2, firstHandle.height / 2) + touch.press(0, control, handleCenter.x, handleCenter.y).commit() + verify(firstHandle.SplitHandle.pressed) + + touch.move(0, control, handleCenter.x + 100, handleCenter.y).commit() + verify(firstHandle.SplitHandle.pressed) + let firstItem = control.itemAt(0) + compare(firstItem.width, 125) + + touch.release(0, control, handleCenter.x + 100, handleCenter.y).commit() + verify(!firstHandle.SplitHandle.pressed) + compare(firstItem.width, 125) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_stackview.qml b/tests/auto/quickcontrols2/controls/data/tst_stackview.qml new file mode 100644 index 00000000000..6b530fd772b --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_stackview.qml @@ -0,0 +1,1625 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "StackView" + + Item { id: item } + Component { id: textField; TextField { } } + Component { id: component; Item { } } + + Component { + id: stackView + StackView { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + Component { id: withRequired; Item { required property int i }} + + function test_initialItem() { + var control1 = createTemporaryObject(stackView, testCase) + verify(control1) + compare(control1.currentItem, null) + control1.destroy() + + var control2 = createTemporaryObject(stackView, testCase, {initialItem: item}) + verify(control2) + compare(control2.currentItem, item) + control2.destroy() + + var control3 = createTemporaryObject(stackView, testCase, {initialItem: component}) + verify(control3) + verify(control3.currentItem) + control3.destroy() + } + + function test_currentItem() { + var control = createTemporaryObject(stackView, testCase, {initialItem: item}) + verify(control) + compare(control.currentItem, item) + control.push(component) + verify(control.currentItem !== item) + control.pop(StackView.Immediate) + compare(control.currentItem, item) + } + + function test_busy() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + compare(control.busy, false) + + var busyCount = 0 + var busySpy = signalSpy.createObject(control, {target: control, signalName: "busyChanged"}) + verify(busySpy.valid) + + control.push(component) + compare(control.busy, false) + compare(busySpy.count, busyCount) + + control.push(component) + compare(control.busy, true) + compare(busySpy.count, ++busyCount) + tryCompare(control, "busy", false) + compare(busySpy.count, ++busyCount) + + control.replace(component) + compare(control.busy, true) + compare(busySpy.count, ++busyCount) + tryCompare(control, "busy", false) + compare(busySpy.count, ++busyCount) + + control.pop() + compare(control.busy, true) + compare(busySpy.count, ++busyCount) + tryCompare(control, "busy", false) + compare(busySpy.count, ++busyCount) + + control.pushEnter = null + control.pushExit = null + + control.push(component) + compare(control.busy, false) + compare(busySpy.count, busyCount) + + control.replaceEnter = null + control.replaceExit = null + + control.replace(component) + compare(control.busy, false) + compare(busySpy.count, busyCount) + + control.popEnter = null + control.popExit = null + + control.pop() + compare(control.busy, false) + compare(busySpy.count, busyCount) + } + + function test_status() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + var item1 = component.createObject(control) + compare(item1.StackView.status, StackView.Inactive) + control.push(item1) + compare(item1.StackView.status, StackView.Active) + + var item2 = component.createObject(control) + compare(item2.StackView.status, StackView.Inactive) + control.push(item2) + compare(item2.StackView.status, StackView.Activating) + compare(item1.StackView.status, StackView.Deactivating) + tryCompare(item2.StackView, "status", StackView.Active) + tryCompare(item1.StackView, "status", StackView.Inactive) + + control.pop() + compare(item2.StackView.status, StackView.Deactivating) + compare(item1.StackView.status, StackView.Activating) + tryCompare(item2.StackView, "status", StackView.Inactive) + tryCompare(item1.StackView, "status", StackView.Active) + } + + function test_index() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + var item1 = component.createObject(control) + compare(item1.StackView.index, -1) + control.push(item1, StackView.Immediate) + compare(item1.StackView.index, 0) + + var item2 = component.createObject(control) + compare(item2.StackView.index, -1) + control.push(item2, StackView.Immediate) + compare(item2.StackView.index, 1) + compare(item1.StackView.index, 0) + + control.pop(StackView.Immediate) + compare(item2.StackView.index, -1) + compare(item1.StackView.index, 0) + } + + function test_view() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + var item1 = component.createObject(control) + compare(item1.StackView.view, null) + control.push(item1, StackView.Immediate) + compare(item1.StackView.view, control) + + var item2 = component.createObject(control) + compare(item2.StackView.view, null) + control.push(item2, StackView.Immediate) + compare(item2.StackView.view, control) + compare(item1.StackView.view, control) + + control.pop(StackView.Immediate) + compare(item2.StackView.view, null) + compare(item1.StackView.view, control) + } + + function test_depth() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + var depthChanges = 0 + var emptyChanges = 0 + var depthSpy = signalSpy.createObject(control, {target: control, signalName: "depthChanged"}) + var emptySpy = signalSpy.createObject(control, {target: control, signalName: "emptyChanged"}) + verify(depthSpy.valid) + verify(emptySpy.valid) + compare(control.depth, 0) + compare(control.empty, true) + + control.push(item, StackView.Immediate) + compare(control.depth, 1) + compare(depthSpy.count, ++depthChanges) + compare(control.empty, false) + compare(emptySpy.count, ++emptyChanges) + + control.clear() + compare(control.depth, 0) + compare(depthSpy.count, ++depthChanges) + compare(control.empty, true) + compare(emptySpy.count, ++emptyChanges) + + control.push(component, StackView.Immediate) + compare(control.depth, 1) + compare(depthSpy.count, ++depthChanges) + compare(control.empty, false) + compare(emptySpy.count, ++emptyChanges) + + control.push(component, StackView.Immediate) + compare(control.depth, 2) + compare(depthSpy.count, ++depthChanges) + compare(control.empty, false) + compare(emptySpy.count, emptyChanges) + + control.replace(component, StackView.Immediate) + compare(control.depth, 2) + compare(depthSpy.count, depthChanges) + compare(control.empty, false) + compare(emptySpy.count, emptyChanges) + + control.replace([component, component], StackView.Immediate) + compare(control.depth, 3) + compare(depthSpy.count, ++depthChanges) + compare(control.empty, false) + compare(emptySpy.count, emptyChanges) + + control.pop(null, StackView.Immediate) + compare(control.depth, 1) + compare(depthSpy.count, ++depthChanges) + compare(control.empty, false) + compare(emptySpy.count, emptyChanges) + + control.pop(StackView.Immediate) // ignored + compare(control.depth, 1) + compare(depthSpy.count, depthChanges) + compare(control.empty, false) + compare(emptySpy.count, emptyChanges) + + control.clear() + compare(control.depth, 0) + compare(depthSpy.count, ++depthChanges) + compare(control.empty, true) + compare(emptySpy.count, ++emptyChanges) + + control.clear() + compare(control.depth, 0) + compare(depthSpy.count, depthChanges) + compare(control.empty, true) + compare(emptySpy.count, emptyChanges) + + control.push(item, StackView.PushTransition) + compare(depthSpy.count, ++depthChanges) + compare(emptySpy.count, ++emptyChanges) + compare(control.depth, 1) + control.clear(StackView.PopTransition) + compare(depthSpy.count, ++depthChanges) + compare(emptySpy.count, ++emptyChanges) + compare(control.depth, 0) + } + + function test_size() { + var container = createTemporaryObject(component, testCase, {width: 200, height: 200}) + verify(container) + var control = stackView.createObject(container, {width: 100, height: 100}) + verify(control) + + container.width += 10 + container.height += 20 + compare(control.width, 100) + compare(control.height, 100) + + control.push(item, StackView.Immediate) + compare(item.width, control.width) + compare(item.height, control.height) + + control.width = 200 + control.height = 200 + compare(item.width, control.width) + compare(item.height, control.height) + + control.clear() + control.width += 10 + control.height += 20 + verify(item.width !== control.width) + verify(item.height !== control.height) + + control.push(item, StackView.Immediate) + compare(item.width, control.width) + compare(item.height, control.height) + } + + function test_focus_data() { + return [ + { tag: "true", focus: true, forceActiveFocus: false }, + { tag: "false", focus: false, forceActiveFocus: false }, + { tag: "forceActiveFocus()", focus: false, forceActiveFocus: true }, + ] + } + + function test_focus(data) { + var control = createTemporaryObject(stackView, testCase, {initialItem: item, width: 200, height: 200}) + verify(control) + + if (data.focus) + control.focus = true + if (data.forceActiveFocus) + control.forceActiveFocus() + compare(control.activeFocus, data.focus || data.forceActiveFocus) + + var page = control.push(textField, StackView.Immediate) + verify(page) + compare(control.currentItem, page) + compare(page.activeFocus, control.activeFocus) + + control.pop(StackView.Immediate) + compare(control.currentItem, item) + compare(item.activeFocus, data.focus || data.forceActiveFocus) + verify(!page.activeFocus) + } + + function test_find() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + var item1 = component.createObject(control, {objectName: "1"}) + var item2 = component.createObject(control, {objectName: "2"}) + var item3 = component.createObject(control, {objectName: "3"}) + + control.push(item1, StackView.Immediate) + control.push(item2, StackView.Immediate) + control.push(item3, StackView.Immediate) + + compare(control.find(function(item, index) { return index === 0 }), item1) + compare(control.find(function(item) { return item.objectName === "1" }), item1) + + compare(control.find(function(item, index) { return index === 1 }), item2) + compare(control.find(function(item) { return item.objectName === "2" }), item2) + + compare(control.find(function(item, index) { return index === 2 }), item3) + compare(control.find(function(item) { return item.objectName === "3" }), item3) + + compare(control.find(function() { return false }), null) + compare(control.find(function() { return true }), item3) + } + + function test_get() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + control.push([item, component, component], StackView.Immediate) + + verify(control.get(0, StackView.DontLoad)) + compare(control.get(0, StackView.ForceLoad), item) + + verify(!control.get(1, StackView.DontLoad)) + + verify(control.get(2, StackView.DontLoad)) + verify(control.get(2, StackView.ForceLoad)) + } + + function test_push() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + // missing arguments + ignoreWarning(/QML StackView: push: missing arguments/) + compare(control.push(), null) + + // nothing to push + ignoreWarning(/QML StackView: push: nothing to push/) + compare(control.push(StackView.Immediate), null) + + // unsupported type + ignoreWarning(/QML StackView: push: QtObject is not supported. Must be Item or Component./) + control.push(Qt.createQmlObject('import QtQml; QtObject { }', control)) + + // push(item) + var item1 = component.createObject(control, {objectName:"1"}) + compare(control.push(item1, StackView.Immediate), item1) + compare(control.depth, 1) + compare(control.currentItem, item1) + + // push([item]) + var item2 = component.createObject(control, {objectName:"2"}) + compare(control.push([item2], StackView.Immediate), item2) + compare(control.depth, 2) + compare(control.currentItem, item2) + + // push(item, {properties}) + var item3 = component.createObject(control) + compare(control.push(item3, {objectName:"3"}, StackView.Immediate), item3) + compare(item3.objectName, "3") + compare(control.depth, 3) + compare(control.currentItem, item3) + + // push([item, {properties}]) + var item4 = component.createObject(control) + compare(control.push([item4, {objectName:"4"}], StackView.Immediate), item4) + compare(item4.objectName, "4") + compare(control.depth, 4) + compare(control.currentItem, item4) + + // push(component, {properties}) + var item5 = control.push(component, {objectName:"5"}, StackView.Immediate) + compare(item5.objectName, "5") + compare(control.depth, 5) + compare(control.currentItem, item5) + + // push([component, {properties}]) + var item6 = control.push([component, {objectName:"6"}], StackView.Immediate) + compare(item6.objectName, "6") + compare(control.depth, 6) + compare(control.currentItem, item6) + } + + // Escape special Regexp characters with a '\' (backslash) prefix so that \a str can be + // used as a Regexp pattern. + function escapeRegExp(str) { + // "$&" is the last matched substring + return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + } + + function test_pop() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + var items = [] + for (var i = 0; i < 7; ++i) + items.push(component.createObject(control, {objectName:i})) + + control.push(items, StackView.Immediate) + + ignoreWarning(/QML StackView: pop: too many arguments/) + compare(control.pop(1, 2, 3), null) + + // pop the top most item + compare(control.pop(StackView.Immediate), items[6]) + compare(control.depth, 6) + compare(control.currentItem, items[5]) + + // pop down to the current item + compare(control.pop(control.currentItem, StackView.Immediate), null) + compare(control.depth, 6) + compare(control.currentItem, items[5]) + + // pop down to (but not including) the Nth item + compare(control.pop(items[3], StackView.Immediate), items[5]) + compare(control.depth, 4) + compare(control.currentItem, items[3]) + + // pop the top most item + compare(control.pop(undefined, StackView.Immediate), items[3]) + compare(control.depth, 3) + compare(control.currentItem, items[2]) + + // don't pop non-existent item + ignoreWarning(new RegExp(".*QML StackView: pop: unknown argument: " + escapeRegExp(testCase.toString()))) + compare(control.pop(testCase, StackView.Immediate), null) + compare(control.depth, 3) + compare(control.currentItem, items[2]) + + // pop all items down to (but not including) the 1st item + control.pop(null, StackView.Immediate) + compare(control.depth, 1) + compare(control.currentItem, items[0]) + } + + function test_replace() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + // missing arguments + ignoreWarning(/QML StackView: replace: missing arguments/) + compare(control.replace(), null) + + // nothing to push + ignoreWarning(/QML StackView: replace: nothing to push/) + compare(control.replace(StackView.Immediate), null) + + // unsupported type + ignoreWarning(/QML StackView: replace: QtObject is not supported. Must be Item or Component./) + compare(control.replace(Qt.createQmlObject('import QtQml; QtObject { }', control)), null) + + // replace(item) + var item1 = component.createObject(control, {objectName:"1"}) + compare(control.replace(item1, StackView.Immediate), item1) + compare(control.depth, 1) + compare(control.currentItem, item1) + + // replace([item]) + var item2 = component.createObject(control, {objectName:"2"}) + compare(control.replace([item2], StackView.Immediate), item2) + compare(control.depth, 1) + compare(control.currentItem, item2) + + // replace(item, {properties}) + var item3 = component.createObject(control) + compare(control.replace(item3, {objectName:"3"}, StackView.Immediate), item3) + compare(item3.objectName, "3") + compare(control.depth, 1) + compare(control.currentItem, item3) + + // replace([item, {properties}]) + var item4 = component.createObject(control) + compare(control.replace([item4, {objectName:"4"}], StackView.Immediate), item4) + compare(item4.objectName, "4") + compare(control.depth, 1) + compare(control.currentItem, item4) + + // replace(component, {properties}) + var item5 = control.replace(component, {objectName:"5"}, StackView.Immediate) + compare(item5.objectName, "5") + compare(control.depth, 1) + compare(control.currentItem, item5) + + // replace([component, {properties}]) + var item6 = control.replace([component, {objectName:"6"}], StackView.Immediate) + compare(item6.objectName, "6") + compare(control.depth, 1) + compare(control.currentItem, item6) + + // replace the topmost item + control.push(component) + compare(control.depth, 2) + var item7 = control.replace(control.get(1), component, StackView.Immediate) + compare(control.depth, 2) + compare(control.currentItem, item7) + + // replace the item in the middle + control.push(component) + control.push(component) + control.push(component) + compare(control.depth, 5) + var item8 = control.replace(control.get(2), component, StackView.Immediate) + compare(control.depth, 3) + compare(control.currentItem, item8) + } + + function test_clear() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + control.push(component, StackView.Immediate) + + control.clear() + compare(control.depth, 0) + compare(control.busy, false) + + control.push(component, StackView.Immediate) + + control.clear(StackView.PopTransition) + compare(control.depth, 0) + compare(control.busy, true) + tryCompare(control, "busy", false) + } + + function test_visibility_data() { + return [ + {tag:"default transitions", properties: {}}, + {tag:"null transitions", properties: {pushEnter: null, pushExit: null, popEnter: null, popExit: null}} + ] + } + + function test_visibility(data) { + var control = createTemporaryObject(stackView, testCase, data.properties) + verify(control) + + var item1 = component.createObject(control) + control.push(item1, StackView.Immediate) + verify(item1.visible) + + var item2 = component.createObject(control) + control.push(item2) + tryCompare(item1, "visible", false) + verify(item2.visible) + + control.pop() + verify(item1.visible) + tryCompare(item2, "visible", false) + } + + Component { + id: transitionView + StackView { + property int popEnterRuns + property int popExitRuns + property int pushEnterRuns + property int pushExitRuns + property int replaceEnterRuns + property int replaceExitRuns + popEnter: Transition { + PauseAnimation { duration: 1 } + onRunningChanged: if (!running) ++popEnterRuns + } + popExit: Transition { + PauseAnimation { duration: 1 } + onRunningChanged: if (!running) ++popExitRuns + } + pushEnter: Transition { + PauseAnimation { duration: 1 } + onRunningChanged: if (!running) ++pushEnterRuns + } + pushExit: Transition { + PauseAnimation { duration: 1 } + onRunningChanged: if (!running) ++pushExitRuns + } + replaceEnter: Transition { + PauseAnimation { duration: 1 } + onRunningChanged: if (!running) ++replaceEnterRuns + } + replaceExit: Transition { + PauseAnimation { duration: 1 } + onRunningChanged: if (!running) ++replaceExitRuns + } + } + } + + function test_transitions_data() { + return [ + { tag: "undefined", operation: undefined, + pushEnterRuns: [1,2,2,2], pushExitRuns: [0,1,1,1], replaceEnterRuns: [0,0,1,1], replaceExitRuns: [0,0,1,1], popEnterRuns: [0,0,0,1], popExitRuns: [0,0,0,1] }, + { tag: "immediate", operation: StackView.Immediate, + pushEnterRuns: [1,2,2,2], pushExitRuns: [0,1,1,1], replaceEnterRuns: [0,0,1,1], replaceExitRuns: [0,0,1,1], popEnterRuns: [0,0,0,1], popExitRuns: [0,0,0,1] }, + { tag: "push", operation: StackView.PushTransition, + pushEnterRuns: [1,2,3,4], pushExitRuns: [0,1,2,3], replaceEnterRuns: [0,0,0,0], replaceExitRuns: [0,0,0,0], popEnterRuns: [0,0,0,0], popExitRuns: [0,0,0,0] }, + { tag: "pop", operation: StackView.PopTransition, + pushEnterRuns: [0,0,0,0], pushExitRuns: [0,0,0,0], replaceEnterRuns: [0,0,0,0], replaceExitRuns: [0,0,0,0], popEnterRuns: [1,2,3,4], popExitRuns: [0,1,2,3] }, + { tag: "replace", operation: StackView.ReplaceTransition, + pushEnterRuns: [0,0,0,0], pushExitRuns: [0,0,0,0], replaceEnterRuns: [1,2,3,4], replaceExitRuns: [0,1,2,3], popEnterRuns: [0,0,0,0], popExitRuns: [0,0,0,0] }, + ] + } + + function test_transitions(data) { + var control = createTemporaryObject(transitionView, testCase) + verify(control) + + control.push(component, data.operation) + tryCompare(control, "busy", false) + compare(control.pushEnterRuns, data.pushEnterRuns[0]) + compare(control.pushExitRuns, data.pushExitRuns[0]) + compare(control.replaceEnterRuns, data.replaceEnterRuns[0]) + compare(control.replaceExitRuns, data.replaceExitRuns[0]) + compare(control.popEnterRuns, data.popEnterRuns[0]) + compare(control.popExitRuns, data.popExitRuns[0]) + + control.push(component, data.operation) + tryCompare(control, "busy", false) + compare(control.pushEnterRuns, data.pushEnterRuns[1]) + compare(control.pushExitRuns, data.pushExitRuns[1]) + compare(control.replaceEnterRuns, data.replaceEnterRuns[1]) + compare(control.replaceExitRuns, data.replaceExitRuns[1]) + compare(control.popEnterRuns, data.popEnterRuns[1]) + compare(control.popExitRuns, data.popExitRuns[1]) + + control.replace(component, data.operation) + tryCompare(control, "busy", false) + compare(control.pushEnterRuns, data.pushEnterRuns[2]) + compare(control.pushExitRuns, data.pushExitRuns[2]) + compare(control.replaceEnterRuns, data.replaceEnterRuns[2]) + compare(control.replaceExitRuns, data.replaceExitRuns[2]) + compare(control.popEnterRuns, data.popEnterRuns[2]) + compare(control.popExitRuns, data.popExitRuns[2]) + + control.pop(data.operation) + tryCompare(control, "busy", false) + compare(control.pushEnterRuns, data.pushEnterRuns[3]) + compare(control.pushExitRuns, data.pushExitRuns[3]) + compare(control.replaceEnterRuns, data.replaceEnterRuns[3]) + compare(control.replaceExitRuns, data.replaceExitRuns[3]) + compare(control.popEnterRuns, data.popEnterRuns[3]) + compare(control.popExitRuns, data.popExitRuns[3]) + } + + TestItem { + id: indestructibleItem + } + + Component { + id: destructibleComponent + TestItem { } + } + + function test_ownership_data() { + return [ + {tag:"item, transition", arg: indestructibleItem, operation: StackView.Transition, destroyed: false}, + {tag:"item, immediate", arg: indestructibleItem, operation: StackView.Immediate, destroyed: false}, + {tag:"component, transition", arg: destructibleComponent, operation: StackView.Transition, destroyed: true}, + {tag:"component, immediate", arg: destructibleComponent, operation: StackView.Immediate, destroyed: true}, + {tag:"url, transition", arg: Qt.resolvedUrl("TestItem.qml"), operation: StackView.Transition, destroyed: true}, + {tag:"url, immediate", arg: Qt.resolvedUrl("TestItem.qml"), operation: StackView.Immediate, destroyed: true} + ] + } + + function test_ownership(data) { + var control = createTemporaryObject(transitionView, testCase, {initialItem: component}) + verify(control) + + // push-pop + control.push(data.arg, StackView.Immediate) + verify(control.currentItem) + verify(control.currentItem.hasOwnProperty("destroyedCallback")) + var destroyed = false + control.currentItem.destroyedCallback = function() { destroyed = true } + control.pop(data.operation) + tryCompare(control, "busy", false) + wait(0) // deferred delete + compare(destroyed, data.destroyed) + + // push-replace + control.push(data.arg, StackView.Immediate) + verify(control.currentItem) + verify(control.currentItem.hasOwnProperty("destroyedCallback")) + destroyed = false + control.currentItem.destroyedCallback = function() { destroyed = true } + control.replace(component, data.operation) + tryCompare(control, "busy", false) + wait(0) // deferred delete + compare(destroyed, data.destroyed) + } + + Component { + id: removeComponent + + Item { + objectName: "removeItem" + StackView.onRemoved: destroy() + } + } + + function test_destroyOnRemoved() { + var control = createTemporaryObject(stackView, testCase, { initialItem: component }) + verify(control) + + var item = removeComponent.createObject(control) + verify(item) + + var removedSpy = signalSpy.createObject(control, { target: item.StackView, signalName: "removed" }) + verify(removedSpy) + verify(removedSpy.valid) + + var destructionSpy = signalSpy.createObject(control, { target: item.Component, signalName: "destruction" }) + verify(destructionSpy) + verify(destructionSpy.valid) + + // push-pop + control.push(item, StackView.Immediate) + compare(control.currentItem, item) + control.pop(StackView.Transition) + item = null + tryCompare(removedSpy, "count", 1) + tryCompare(destructionSpy, "count", 1) + compare(control.busy, false) + + item = removeComponent.createObject(control) + verify(item) + + removedSpy.target = item.StackView + verify(removedSpy.valid) + + destructionSpy.target = item.Component + verify(destructionSpy.valid) + + // push-replace + control.push(item, StackView.Immediate) + compare(control.currentItem, item) + control.replace(component, StackView.Transition) + item = null + tryCompare(removedSpy, "count", 2) + tryCompare(destructionSpy, "count", 2) + compare(control.busy, false) + } + + function test_pushOnRemoved() { + var control = createTemporaryObject(stackView, testCase, { initialItem: component }) + verify(control) + + var item = control.push(component, StackView.Immediate) + verify(item) + + item.StackView.onRemoved.connect(function() { + ignoreWarning(/.*QML StackView: cannot push while already in the process of completing a pop/) + control.push(component, StackView.Immediate) + }) + + // don't crash (QTBUG-62153) + control.pop(StackView.Immediate) + } + + Component { + id: attachedItem + Item { + property int index: StackView.index + property StackView view: StackView.view + property int status: StackView.status + } + } + + function test_attached() { + var control = createTemporaryObject(stackView, testCase, {initialItem: attachedItem}) + + compare(control.get(0).index, 0) + compare(control.get(0).view, control) + compare(control.get(0).status, StackView.Active) + + control.push(attachedItem, StackView.Immediate) + + compare(control.get(0).index, 0) + compare(control.get(0).view, control) + compare(control.get(0).status, StackView.Inactive) + + compare(control.get(1).index, 1) + compare(control.get(1).view, control) + compare(control.get(1).status, StackView.Active) + + control.pop(StackView.Immediate) + + compare(control.get(0).index, 0) + compare(control.get(0).view, control) + compare(control.get(0).status, StackView.Active) + } + + Component { + id: testButton + Button { + property int clicks: 0 + onClicked: ++clicks + } + } + + function test_interaction() { + var control = createTemporaryObject(stackView, testCase, {initialItem: testButton, width: testCase.width, height: testCase.height}) + verify(control) + + var firstButton = control.currentItem + verify(firstButton) + + var firstClicks = 0 + var secondClicks = 0 + var thirdClicks = 0 + + // push - default transition + var secondButton = control.push(testButton) + compare(control.busy, true) + mouseClick(firstButton) // filtered while busy + mouseClick(secondButton) // filtered while busy + compare(firstButton.clicks, firstClicks) + compare(secondButton.clicks, secondClicks) + tryCompare(control, "busy", false) + mouseClick(secondButton) + compare(secondButton.clicks, ++secondClicks) + + // replace - default transition + var thirdButton = control.replace(testButton) + compare(control.busy, true) + mouseClick(secondButton) // filtered while busy + mouseClick(thirdButton) // filtered while busy + compare(secondButton.clicks, secondClicks) + compare(thirdButton.clicks, thirdClicks) + tryCompare(control, "busy", false) + secondButton = null + secondClicks = 0 + mouseClick(thirdButton) + compare(thirdButton.clicks, ++thirdClicks) + + // pop - default transition + control.pop() + compare(control.busy, true) + mouseClick(firstButton) // filtered while busy + mouseClick(thirdButton) // filtered while busy + compare(firstButton.clicks, firstClicks) + compare(thirdButton.clicks, thirdClicks) + tryCompare(control, "busy", false) + thirdButton = null + thirdClicks = 0 + mouseClick(firstButton) + compare(firstButton.clicks, ++firstClicks) + + // push - immediate operation + secondButton = control.push(testButton, StackView.Immediate) + compare(control.busy, false) + mouseClick(secondButton) + compare(secondButton.clicks, ++secondClicks) + + // replace - immediate operation + thirdButton = control.replace(testButton, StackView.Immediate) + compare(control.busy, false) + secondButton = null + secondClicks = 0 + mouseClick(thirdButton) + compare(thirdButton.clicks, ++thirdClicks) + + // pop - immediate operation + control.pop(StackView.Immediate) + compare(control.busy, false) + thirdButton = null + thirdClicks = 0 + mouseClick(firstButton) + compare(firstButton.clicks, ++firstClicks) + + // push - null transition + control.pushEnter = null + control.pushExit = null + secondButton = control.push(testButton) + compare(control.busy, false) + mouseClick(secondButton) + compare(secondButton.clicks, ++secondClicks) + + // replace - null transition + control.replaceEnter = null + control.replaceExit = null + thirdButton = control.replace(testButton) + compare(control.busy, false) + secondButton = null + secondClicks = 0 + mouseClick(thirdButton) + compare(thirdButton.clicks, ++thirdClicks) + + // pop - null transition + control.popEnter = null + control.popExit = null + control.pop() + compare(control.busy, false) + thirdButton = null + thirdClicks = 0 + mouseClick(firstButton) + compare(firstButton.clicks, ++firstClicks) + } + + Component { + id: mouseArea + MouseArea { + property int presses: 0 + property int releases: 0 + property int clicks: 0 + property int doubleClicks: 0 + property int cancels: 0 + onPressed: ++presses + onReleased: ++releases + onClicked: ++clicks + onDoubleClicked: ++doubleClicks + onCanceled: ++cancels + } + } + + // QTBUG-50305 + function test_events() { + var control = createTemporaryObject(stackView, testCase, {initialItem: mouseArea, width: testCase.width, height: testCase.height}) + verify(control) + + var testItem = control.currentItem + verify(testItem) + + testItem.doubleClicked.connect(function() { + control.push(mouseArea) // ungrab -> cancel + }) + + mouseDoubleClickSequence(testItem) + compare(testItem.presses, 2) + compare(testItem.releases, 2) + compare(testItem.clicks, 1) + compare(testItem.doubleClicks, 1) + compare(testItem.pressed, false) + compare(testItem.cancels, 0) + } + + function test_ungrab() { + var control = createTemporaryObject(stackView, testCase, {initialItem: mouseArea, width: testCase.width, height: testCase.height}) + verify(control) + + var testItem = control.currentItem + verify(testItem) + + mousePress(testItem) + control.push(mouseArea) + tryCompare(control, "busy", false) + mouseRelease(testItem) + + compare(testItem.presses, 1) + compare(testItem.releases, 0) + compare(testItem.clicks, 0) + compare(testItem.doubleClicks, 0) + compare(testItem.pressed, false) + compare(testItem.cancels, 1) + } + + function test_failures() { + var control = createTemporaryObject(stackView, testCase, {initialItem: component}) + verify(control) + + ignoreWarning("QQmlComponent: Component is not ready") + ignoreWarning(/QML StackView: push: .*non-existent.qml:-1 No such file or directory/) + control.push(Qt.resolvedUrl("non-existent.qml")) + + ignoreWarning("QQmlComponent: Component is not ready") + ignoreWarning(/QML StackView: replace: .*non-existent.qml:-1 No such file or directory/) + control.replace(Qt.resolvedUrl("non-existent.qml")) + + ignoreWarning(/QML StackView: push: invalid url: x:\/\/\[v\]/) + control.push("x://[v]") + + ignoreWarning(/QML StackView: replace: invalid url: x:\/\/\[v\]/) + control.replace("x://[v]") + + control.pop() + } + + Component { + id: rectangle + Rectangle { + property color initialColor + Component.onCompleted: initialColor = color + } + } + + function test_properties() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + var rect = control.push(rectangle, {color: "#ff0000"}) + compare(rect.color, "#ff0000") + compare(rect.initialColor, "#ff0000") + } + + Component { + id: signalTest + Control { + id: ctrl + property SignalSpy activatedSpy: SignalSpy { target: ctrl.StackView; signalName: "activated" } + property SignalSpy activatingSpy: SignalSpy { target: ctrl.StackView; signalName: "activating" } + property SignalSpy deactivatedSpy: SignalSpy { target: ctrl.StackView; signalName: "deactivated" } + property SignalSpy deactivatingSpy: SignalSpy { target: ctrl.StackView; signalName: "deactivating" } + } + } + + function test_signals() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + var item1 = signalTest.createObject(control) + compare(item1.StackView.status, StackView.Inactive) + control.push(item1) + compare(item1.StackView.status, StackView.Active) + compare(item1.activatedSpy.count, 1) + compare(item1.activatingSpy.count, 1) + compare(item1.deactivatedSpy.count, 0) + compare(item1.deactivatingSpy.count, 0) + + var item2 = signalTest.createObject(control) + compare(item2.StackView.status, StackView.Inactive) + control.push(item2) + compare(item2.StackView.status, StackView.Activating) + compare(item2.activatedSpy.count, 0) + compare(item2.activatingSpy.count, 1) + compare(item2.deactivatedSpy.count, 0) + compare(item2.deactivatingSpy.count, 0) + compare(item1.StackView.status, StackView.Deactivating) + compare(item1.activatedSpy.count, 1) + compare(item1.activatingSpy.count, 1) + compare(item1.deactivatedSpy.count, 0) + compare(item1.deactivatingSpy.count, 1) + tryCompare(item2.activatedSpy, "count", 1) + tryCompare(item1.deactivatedSpy, "count", 1) + + control.pop() + compare(item2.StackView.status, StackView.Deactivating) + compare(item2.activatedSpy.count, 1) + compare(item2.activatingSpy.count, 1) + compare(item2.deactivatedSpy.count, 0) + compare(item2.deactivatingSpy.count, 1) + compare(item1.StackView.status, StackView.Activating) + compare(item1.activatedSpy.count, 1) + compare(item1.activatingSpy.count, 2) + compare(item1.deactivatedSpy.count, 1) + compare(item1.deactivatingSpy.count, 1) + tryCompare(item1.activatedSpy, "count", 2) + } + + // QTBUG-56158 + function test_repeatedPop() { + var control = createTemporaryObject(stackView, testCase, {initialItem: component, width: testCase.width, height: testCase.height}) + verify(control) + + for (var i = 0; i < 12; ++i) + control.push(component) + tryCompare(control, "busy", false) + + while (control.depth > 1) { + control.pop() + wait(50) + } + tryCompare(control, "busy", false) + } + + function test_pushSameItem() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + control.push(item, StackView.Immediate) + compare(control.currentItem, item) + compare(control.depth, 1) + + // Pushing the same Item should do nothing. + ignoreWarning(/QML StackView: push: nothing to push/) + control.push(item, StackView.Immediate) + compare(control.currentItem, item) + compare(control.depth, 1) + + // Push a component so that it becomes current. + var current = control.push(component, StackView.Immediate) + compare(control.currentItem, current) + compare(control.depth, 2) + + // Push a bunch of stuff. "item" is already in the stack, so it should be ignored. + current = control.push(component, item, StackView.Immediate) + verify(current !== item) + compare(control.currentItem, current) + compare(control.depth, 3) + } + + function test_visible() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + var item1 = component.createObject(control) + control.push(item1, StackView.Immediate) + compare(item1.visible, true) + compare(item1.StackView.visible, item1.visible) + + var item2 = component.createObject(control) + control.push(item2, StackView.Immediate) + compare(item1.visible, false) + compare(item2.visible, true) + compare(item1.StackView.visible, false) + compare(item2.StackView.visible, true) + + // keep explicitly visible + item2.StackView.visible = true + control.push(component, StackView.Immediate) + compare(item2.visible, true) + compare(item2.StackView.visible, true) + + // show underneath + item1.StackView.visible = true + compare(item1.visible, true) + compare(item1.StackView.visible, true) + + control.pop(StackView.Immediate) + compare(item2.visible, true) + compare(item2.StackView.visible, true) + + // hide the top-most + item2.StackView.visible = false + compare(item2.visible, false) + compare(item2.StackView.visible, false) + + // reset the top-most + item2.StackView.visible = undefined + compare(item2.visible, true) + compare(item2.StackView.visible, true) + + // reset underneath + item1.StackView.visible = undefined + compare(item1.visible, false) + compare(item1.StackView.visible, false) + + control.pop(StackView.Immediate) + compare(item1.visible, true) + compare(item1.StackView.visible, true) + } + + function test_resolveInitialItem() { + var control = createTemporaryObject(stackView, testCase, {initialItem: "TestItem.qml"}) + verify(control) + verify(control.currentItem) + } + + function test_resolve() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + + var item = control.push("TestItem.qml") + compare(control.depth, 1) + verify(item) + } + + // QTBUG-65084 + function test_mouseArea() { + var ma = createTemporaryObject(mouseArea, testCase, {width: testCase.width, height: testCase.height}) + verify(ma) + + var control = stackView.createObject(ma, {width: testCase.width, height: testCase.height}) + verify(control) + + mousePress(control) + verify(ma.pressed) + + mouseRelease(control) + verify(!ma.pressed) + + var touch = touchEvent(control) + touch.press(0, control).commit() + verify(ma.pressed) + + touch.release(0, control).commit() + verify(!ma.pressed) + } + + // Separate function to ensure that the temporary value created to hold the return value of the Qt.createComponent() + // call is out of scope when the caller calls gc(). + function stackViewFactory() + { + return createTemporaryObject(stackView, testCase, {initialItem: Qt.createComponent("TestItem.qml")}) + } + + function test_initalItemOwnership() + { + var control = stackViewFactory() + verify(control) + gc() + verify(control.initialItem) + } + + // Need to use this specific structure in order to reproduce the crash. + Component { + id: clearUponDestructionContainerComponent + + Item { + id: container + objectName: "container" + + property alias control: stackView + property var onDestructionCallback + + property Component clearUponDestructionComponent: Component { + id: clearUponDestructionComponent + + Item { + objectName: "clearUponDestructionItem" + Component.onDestruction: container.onDestructionCallback(stackView) + } + } + + StackView { + id: stackView + initialItem: Item { + objectName: "initialItem" + } + } + } + } + + // QTBUG-80353 + // Tests that calling clear() in Component.onDestruction in response to that + // item being removed (e.g. via an earlier call to clear()) results in a warning and not a crash. + function test_recursiveClearClear() { + let container = createTemporaryObject(clearUponDestructionContainerComponent, testCase, + { onDestructionCallback: function(stackView) { stackView.clear(StackView.Immediate) }}) + verify(container) + + let control = container.control + control.push(container.clearUponDestructionComponent, StackView.Immediate) + + // Shouldn't crash. + ignoreWarning(/.*cannot clear while already in the process of completing a clear/) + control.clear(StackView.Immediate) + } + + function test_recursivePopClear() { + let container = createTemporaryObject(clearUponDestructionContainerComponent, testCase, + { onDestructionCallback: function(stackView) { stackView.clear(StackView.Immediate) }}) + verify(container) + + let control = container.control + control.push(container.clearUponDestructionComponent, StackView.Immediate) + + // Pop all items except the first, removing the second item we pushed in the process. + // Shouldn't crash. + ignoreWarning(/.*cannot clear while already in the process of completing a pop/) + control.pop(null, StackView.Immediate) + } + + function test_recursivePopPop() { + let container = createTemporaryObject(clearUponDestructionContainerComponent, testCase, + { onDestructionCallback: function(stackView) { stackView.pop(null, StackView.Immediate) }}) + verify(container) + + let control = container.control + // Push an extra item so that we can call pop(null) and reproduce the conditions for the crash. + control.push(component, StackView.Immediate) + control.push(container.clearUponDestructionComponent, StackView.Immediate) + + // Pop the top item, then pop down to the first item in response. + ignoreWarning(/.*cannot pop while already in the process of completing a pop/) + control.pop(StackView.Immediate) + } + + function test_recursiveReplaceClear() { + let container = createTemporaryObject(clearUponDestructionContainerComponent, testCase, + { onDestructionCallback: function(stackView) { stackView.clear(StackView.Immediate) }}) + verify(container) + + let control = container.control + control.push(container.clearUponDestructionComponent, StackView.Immediate) + + // Replace the top item, then clear in response. + ignoreWarning(/.*cannot clear while already in the process of completing a replace/) + control.replace(component, StackView.Immediate) + } + + function test_recursiveClearReplace() { + let container = createTemporaryObject(clearUponDestructionContainerComponent, testCase, + { onDestructionCallback: function(stackView) { stackView.replace(component, StackView.Immediate) }}) + verify(container) + + let control = container.control + control.push(container.clearUponDestructionComponent, StackView.Immediate) + + // Replace the top item, then clear in response. + ignoreWarning(/.*cannot replace while already in the process of completing a clear/) + control.clear(StackView.Immediate) + } + + Component { + id: rectangleComponent + Rectangle {} + } + + Component { + id: qtbug57267_StackViewComponent + + StackView { + id: stackView + + popEnter: Transition { + XAnimator { from: (stackView.mirrored ? -1 : 1) * -stackView.width; to: 0; duration: 400; easing.type: Easing.Linear } + } + popExit: Transition { + XAnimator { from: 0; to: (stackView.mirrored ? -1 : 1) * stackView.width; duration: 400; easing.type: Easing.Linear } + } + pushEnter: Transition { + XAnimator { from: (stackView.mirrored ? -1 : 1) * stackView.width; to: 0; duration: 400; easing.type: Easing.Linear } + } + pushExit: Transition { + XAnimator { from: 0; to: (stackView.mirrored ? -1 : 1) * -stackView.width; duration: 400; easing.type: Easing.Linear } + } + replaceEnter: Transition { + XAnimator { from: (stackView.mirrored ? -1 : 1) * stackView.width; to: 0; duration: 400; easing.type: Easing.Linear } + } + replaceExit: Transition { + XAnimator { from: 0; to: (stackView.mirrored ? -1 : 1) * -stackView.width; duration: 400; easing.type: Easing.Linear } + } + } + } + + function test_qtbug57267() { + let redRect = createTemporaryObject(rectangleComponent, testCase, { color: "red" }) + verify(redRect) + let blueRect = createTemporaryObject(rectangleComponent, testCase, { color: "blue" }) + verify(blueRect) + let control = createTemporaryObject(qtbug57267_StackViewComponent, testCase, + { "anchors.fill": testCase, initialItem: redRect }) + verify(control) + + control.replace(blueRect) + compare(control.currentItem, blueRect) + compare(control.depth, 1) + + // Wait until the animation has started and then interrupt it by pushing the redRect. + tryCompare(control, "busy", true) + control.replace(redRect) + // The blue rect shouldn't be visible since we replaced it and therefore interrupted its animation. + tryCompare(blueRect, "visible", false) + // We did the replace very early on, so the transition for the redRect should still be happening. + compare(control.busy, true) + compare(redRect.visible, true) + + // After finishing the transition, the red rect should still be visible. + tryCompare(control, "busy", false) + compare(redRect.visible, true) + } + + // QTBUG-84381 + function test_clearAndPushAfterDepthChange() { + var control = createTemporaryObject(stackView, testCase, { + popEnter: null, popExit: null, pushEnter: null, + pushExit: null, replaceEnter: null, replaceExit: null + }) + verify(control) + + control.depthChanged.connect(function() { + if (control.depth === 2) { + // Shouldn't assert. + ignoreWarning(/.*QML StackView: cannot clear while already in the process of completing a push/) + control.clear() + // Shouldn't crash. + ignoreWarning(/.*QML StackView: cannot push while already in the process of completing a push/) + control.push(component) + } + }) + + control.push(component) + control.push(component) + } + + // QTBUG-96966 + // Generate a stack view with complex transition animations and make sure + // that the item's state is restored correctly when StackView.Immediate + // operation is used + Component { + id: qtbug96966_stackViewComponent + StackView { + id: qtbug96966_stackView + pushEnter: Transition { + ParallelAnimation { + NumberAnimation { + property: "x" + from: qtbug96966_stackView.width + to: 0 + duration: 100 + easing.type: Easing.OutCubic + } + NumberAnimation { + property: "opacity" + from: 0 + to: 1 + duration: 100 + easing.type: Easing.OutCubic + } + } + } + pushExit: Transition { + ParallelAnimation { + NumberAnimation { + property: "x" + from: 0 + to: -qtbug96966_stackView.width + duration: 100 + easing.type: Easing.OutCubic + } + NumberAnimation { + property: "opacity" + from: 1 + to: 0 + duration: 100 + easing.type: Easing.OutCubic + } + } + } + + popExit: Transition { + ParallelAnimation { + NumberAnimation { + property: "x" + from: 0 + to: qtbug96966_stackView.width + duration: 100 + easing.type: Easing.OutCubic + } + NumberAnimation { + property: "opacity" + from: 1 + to: 0 + duration: 100 + easing.type: Easing.OutCubic + } + } + } + popEnter: Transition { + ParallelAnimation { + NumberAnimation { + property: "x" + from: -qtbug96966_stackView.width + to: 0 + duration: 100 + easing.type: Easing.OutCubic + } + NumberAnimation { + property: "opacity" + from: 0 + to: 1 + duration: 100 + easing.type: Easing.OutCubic + } + } + } + } + } + + function test_immediateTransitionPropertiesApplied() { + let redRect = createTemporaryObject(rectangleComponent, testCase, { color: "red" }) + verify(redRect) + let blueRect = createTemporaryObject(rectangleComponent, testCase, { color: "blue" }) + verify(blueRect) + let control = createTemporaryObject(qtbug96966_stackViewComponent, testCase, + { "anchors.fill": testCase, initialItem: redRect }) + verify(control) + + control.push(blueRect) + // wait until the animation is finished + tryCompare(control, "busy", true) + tryCompare(control, "busy", false) + // Now the red rectangle should become invisible and move to the left + compare(redRect.x, -200) // the window width is 200 + compare(redRect.opacity, 0) + + control.pop(null, StackView.Immediate) + // The red rectangle immediately restores its initial state (both + // position and opacity). + compare(redRect.x, 0) + compare(redRect.opacity, 1) + // Blue rectangle is moved to the right and becomes invisible + compare(blueRect.x, 200) + compare(blueRect.opacity, 0) + } + + function test_requiredProperties() { + var control = createTemporaryObject(stackView, testCase) + verify(control) + let failedPush = control.push(withRequired) + compare(failedPush, null); + control.push(withRequired, {"i": 42}) + verify(control.currentItem.i === 42) + control.pop(StackView.Immediate) + } + + // QTBUG-104491 + // Tests that correctly set a busy state when the transition is stolen(canceled) + function test_continuousTransition() { + let redRect = createTemporaryObject(rectangleComponent, testCase, { color: "red" }) + verify(redRect) + let blueRect = createTemporaryObject(rectangleComponent, testCase, { color: "blue" }) + verify(blueRect) + let greenRect = createTemporaryObject(rectangleComponent, testCase, { color: "green" }) + verify(greenRect) + let yellowRect = createTemporaryObject(rectangleComponent, testCase, { color: "yellow" }) + verify(yellowRect) + let control = createTemporaryObject(qtbug96966_stackViewComponent, testCase, + { "anchors.fill": testCase, initialItem: redRect }) + verify(control) + + control.push(blueRect) + control.pop() + tryCompare(control, "busy", true) + tryCompare(control, "busy", false) + + control.push(blueRect) + control.push(greenRect) + control.push(yellowRect) + tryCompare(control, "busy", true) + tryCompare(control, "busy", false) + + control.pop() + control.pop() + control.pop() + tryCompare(control, "busy", true) + tryCompare(control, "busy", false) + } + + Component { + id: noProperties + Item {} + } + + Component { + id: invalidProperties + + StackView { + anchors.fill: parent + } + } + + function test_invalidProperties() { + let control = createTemporaryObject(invalidProperties, testCase) + verify(control) + verify(control.empty) + ignoreWarning(/Cannot resolve property "unknownProperty.test"/) + control.push(noProperties, { "unknownProperty.test": "crashes" }) + verify(!control.empty) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_swipedelegate.qml b/tests/auto/quickcontrols2/controls/data/tst_swipedelegate.qml new file mode 100644 index 00000000000..42b23b3614e --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_swipedelegate.qml @@ -0,0 +1,1746 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "SwipeDelegate" + + readonly property int dragDistance: Math.max(20, Qt.styleHints.startDragDistance + 5) + + Component { + id: backgroundFillComponent + SwipeDelegate { + background: Item { anchors.fill: parent } + } + } + + Component { + id: backgroundCenterInComponent + SwipeDelegate { + background: Item { anchors.centerIn: parent } + } + } + + Component { + id: backgroundLeftComponent + SwipeDelegate { + background: Item { anchors.left: parent.left } + } + } + + Component { + id: backgroundRightComponent + SwipeDelegate { + background: Item { anchors.right: parent.right } + } + } + + Component { + id: contentItemFillComponent + SwipeDelegate { + contentItem: Item { anchors.fill: parent } + } + } + + Component { + id: contentItemCenterInComponent + SwipeDelegate { + contentItem: Item { anchors.centerIn: parent } + } + } + + Component { + id: contentItemLeftComponent + SwipeDelegate { + contentItem: Item { anchors.left: parent.left } + } + } + + Component { + id: contentItemRightComponent + SwipeDelegate { + contentItem: Item { anchors.right: parent.right } + } + } + + function test_horizontalAnchors_data() { + return [ + { tag: "background, fill", component: backgroundFillComponent, itemName: "background", warningLocation: ":69:25" }, + { tag: "background, centerIn", component: backgroundCenterInComponent, itemName: "background", warningLocation: ":76:25" }, + { tag: "background, left", component: backgroundLeftComponent, itemName: "background", warningLocation: ":83:25" }, + { tag: "background, right", component: backgroundRightComponent, itemName: "background", warningLocation: ":90:25" }, + { tag: "contentItem, fill", component: contentItemFillComponent, itemName: "contentItem", warningLocation: ":97:26" }, + { tag: "contentItem, centerIn", component: contentItemCenterInComponent, itemName: "contentItem", warningLocation: ":104:26" }, + { tag: "contentItem, left", component: contentItemLeftComponent, itemName: "contentItem", warningLocation: ":111:26" }, + { tag: "contentItem, right", component: contentItemRightComponent, itemName: "contentItem", warningLocation: ":118:26" } + ]; + } + + function test_horizontalAnchors(data) { + var warningMessage = Qt.resolvedUrl("tst_swipedelegate.qml") + data.warningLocation + + ": QML QQuickItem: SwipeDelegate: cannot use horizontal anchors with " + data.itemName + "; unable to layout the item." + + ignoreWarning(warningMessage); + + var control = createTemporaryObject(data.component, testCase); + verify(control.contentItem); + } + + Component { + id: greenLeftComponent + + Rectangle { + objectName: "leftItem" + anchors.fill: parent + color: "green" + } + } + + Component { + id: redRightComponent + + Rectangle { + objectName: "rightItem" + anchors.fill: parent + color: "red" + } + } + + Component { + id: swipeDelegateComponent + + SwipeDelegate { + id: swipeDelegate + text: "SwipeDelegate" + width: 150 + swipe.left: greenLeftComponent + swipe.right: redRightComponent + } + } + + Component { + id: signalSpyComponent + + SignalSpy {} + } + + Component { + id: itemComponent + + Item {} + } + + // Assumes that the delegate is smaller than the width of the control. + function swipe(control, from, to) { + // Sanity check. + compare(control.swipe.position, from); + + var distance = (to - from) * control.width; + + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width / 2 + distance, control.height / 2); + mouseRelease(control, control.width / 2 + distance, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, to, "Expected swipe.position to be " + to + + " after swiping from " + from + ", but it's " + control.swipe.position); + + if (control.swipe.position === -1.0) { + if (control.swipe.right) + verify(control.swipe.rightItem); + else if (control.swipe.behind) + verify(control.swipe.behindItem); + } else if (control.swipe.position === 1.0) { + if (control.swipe.left) + verify(control.swipe.leftItem); + else if (control.swipe.behind) + verify(control.swipe.behindItem); + } + } + + function test_settingDelegates() { + var control = createTemporaryObject(swipeDelegateComponent, testCase); + verify(control); + + ignoreWarning(/QML SwipeDelegate: cannot set both behind and left\/right properties/) + control.swipe.behind = itemComponent; + + // Shouldn't be any warnings when unsetting delegates. + control.swipe.left = null; + compare(control.swipe.leftItem, null); + + // right is still set. + ignoreWarning(/QML SwipeDelegate: cannot set both behind and left\/right properties/) + control.swipe.behind = itemComponent; + + control.swipe.right = null; + compare(control.swipe.rightItem, null); + + control.swipe.behind = itemComponent; + + ignoreWarning(/QML SwipeDelegate: cannot set both behind and left\/right properties/) + control.swipe.left = itemComponent; + + ignoreWarning(/QML SwipeDelegate: cannot set both behind and left\/right properties/) + control.swipe.right = itemComponent; + + control.swipe.behind = null; + control.swipe.left = greenLeftComponent; + control.swipe.right = redRightComponent; + + // Test that the user is warned when attempting to set or unset left or + // right item while they're exposed. + // First, try the left item. + swipe(control, 0.0, 1.0); + + var oldLeft = control.swipe.left; + var oldLeftItem = control.swipe.leftItem; + ignoreWarning(/QML SwipeDelegate: left\/right\/behind properties may only be set when swipe.position is 0/) + control.swipe.left = null; + compare(control.swipe.left, oldLeft); + compare(control.swipe.leftItem, oldLeftItem); + + // Try the same thing with the right item. + swipe(control, 1.0, -1.0); + + var oldRight = control.swipe.right; + var oldRightItem = control.swipe.rightItem; + ignoreWarning(/QML SwipeDelegate: left\/right\/behind properties may only be set when swipe.position is 0/) + control.swipe.right = null; + compare(control.swipe.right, oldRight); + compare(control.swipe.rightItem, oldRightItem); + + // Return to the default position. + swipe(control, -1.0, 0.0); + + tryCompare(control.background, "x", 0, 1000); + + // Try the same thing with the behind item. + control.swipe.left = null; + verify(!control.swipe.left); + verify(!control.swipe.leftItem); + control.swipe.right = null; + verify(!control.swipe.right); + verify(!control.swipe.rightItem); + control.swipe.behind = greenLeftComponent; + verify(control.swipe.behind); + verify(!control.swipe.behindItem); + + swipe(control, 0.0, 1.0); + + var oldBehind = control.swipe.behind; + var oldBehindItem = control.swipe.behindItem; + ignoreWarning(/QML SwipeDelegate: left\/right\/behind properties may only be set when swipe.position is 0/) + control.swipe.behind = null; + compare(control.swipe.behind, oldBehind); + compare(control.swipe.behindItem, oldBehindItem); + } + + function test_defaults() { + var control = createTemporaryObject(swipeDelegateComponent, testCase); + verify(control); + + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset); + compare(control.swipe.position, 0); + verify(!control.pressed); + verify(!control.swipe.complete); + } + + SignalSequenceSpy { + id: mouseSignalSequenceSpy + signals: ["pressed", "released", "canceled", "clicked", "doubleClicked", "pressedChanged", "pressAndHold"] + } + + function test_swipe() { + var control = createTemporaryObject(swipeDelegateComponent, testCase); + verify(control); + + var overDragDistance = Math.round(dragDistance * 1.1); + + var completedSpy = signalSpyComponent.createObject(control, { target: control.swipe, signalName: "completed" }); + verify(completedSpy); + verify(completedSpy.valid); + + var openedSpy = signalSpyComponent.createObject(control, { target: control.swipe, signalName: "opened" }); + verify(openedSpy); + verify(openedSpy.valid); + + var closedSpy = signalSpyComponent.createObject(control, { target: control.swipe, signalName: "closed" }); + verify(closedSpy); + verify(closedSpy.valid); + + mouseSignalSequenceSpy.target = control; + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed"]; + mousePress(control, control.width / 2, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 0.0); + verify(!control.swipe.complete); + compare(completedSpy.count, 0); + compare(openedSpy.count, 0); + compare(closedSpy.count, 0); + verify(mouseSignalSequenceSpy.success); + verify(!control.swipe.leftItem); + verify(!control.swipe.rightItem); + + // Drag to the right so that leftItem is created and visible. + mouseMove(control, control.width / 2 + overDragDistance, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, overDragDistance / control.width); + verify(!control.swipe.complete); + compare(completedSpy.count, 0); + compare(openedSpy.count, 0); + compare(closedSpy.count, 0); + verify(control.swipe.leftItem); + verify(control.swipe.leftItem.visible); + compare(control.swipe.leftItem.parent, control); + compare(control.swipe.leftItem.objectName, "leftItem"); + verify(!control.swipe.rightItem); + + // Go back to 0. + mouseMove(control, control.width / 2, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 0.0); + verify(!control.swipe.complete); + compare(completedSpy.count, 0); + compare(openedSpy.count, 0); + compare(closedSpy.count, 0); + verify(control.swipe.leftItem); + verify(control.swipe.leftItem.visible); + compare(control.swipe.leftItem.parent, control); + compare(control.swipe.leftItem.objectName, "leftItem"); + verify(!control.swipe.rightItem); + + // Try the other direction. The right item should be created and visible, + // and the left item should be hidden. + mouseMove(control, control.width / 2 - overDragDistance, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, -overDragDistance / control.width); + verify(!control.swipe.complete); + compare(completedSpy.count, 0); + compare(openedSpy.count, 0); + compare(closedSpy.count, 0); + verify(control.swipe.leftItem); + verify(!control.swipe.leftItem.visible); + verify(control.swipe.rightItem); + verify(control.swipe.rightItem.visible); + compare(control.swipe.rightItem.parent, control); + compare(control.swipe.rightItem.objectName, "rightItem"); + + // Now release outside the right edge of the control. + mouseMove(control, control.width * 1.1, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 0.6); + verify(!control.swipe.complete); + compare(completedSpy.count, 0); + compare(openedSpy.count, 0); + compare(closedSpy.count, 0); + verify(control.swipe.leftItem); + verify(control.swipe.leftItem.visible); + verify(control.swipe.rightItem); + verify(!control.swipe.rightItem.visible); + + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "canceled"]; + mouseRelease(control, control.width / 2, control.height / 2); + verify(!control.pressed); + tryCompare(control.swipe, "position", 1.0); + tryCompare(control.swipe, "complete", true); + compare(completedSpy.count, 1); + compare(openedSpy.count, 1); + compare(closedSpy.count, 0); + verify(mouseSignalSequenceSpy.success); + verify(control.swipe.leftItem); + verify(control.swipe.leftItem.visible); + verify(control.swipe.rightItem); + verify(!control.swipe.rightItem.visible); + tryCompare(control.contentItem, "x", control.width + control.leftPadding); + + // Swiping from the right and releasing early should return position to 1.0. + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed"]; + mousePress(control, control.width / 2, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 1.0); + // complete should still be true, because we haven't moved yet, and hence + // haven't started grabbing behind's mouse events. + verify(control.swipe.complete); + compare(completedSpy.count, 1); + compare(openedSpy.count, 1); + compare(closedSpy.count, 0); + verify(mouseSignalSequenceSpy.success); + + mouseMove(control, control.width / 2 - overDragDistance, control.height / 2); + verify(control.pressed); + verify(!control.swipe.complete); + compare(completedSpy.count, 1); + compare(openedSpy.count, 1); + compare(closedSpy.count, 0); + compare(control.swipe.position, 1.0 - overDragDistance / control.width); + + // Since we went over the drag distance, we should expect canceled() to be emitted. + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "canceled"]; + mouseRelease(control, control.width * 0.4, control.height / 2); + verify(!control.pressed); + tryCompare(control.swipe, "position", 1.0); + tryCompare(control.swipe, "complete", true); + compare(completedSpy.count, 2); + compare(openedSpy.count, 2); + compare(closedSpy.count, 0); + verify(mouseSignalSequenceSpy.success); + tryCompare(control.contentItem, "x", control.width + control.leftPadding); + + // Swiping from the right and releasing should return contents to default position. + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed"]; + mousePress(control, control.width / 2, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 1.0); + verify(control.swipe.complete); + compare(completedSpy.count, 2); + compare(openedSpy.count, 2); + compare(closedSpy.count, 0); + verify(mouseSignalSequenceSpy.success); + + mouseMove(control, control.width * -0.1, control.height / 2); + verify(control.pressed); + verify(!control.swipe.complete); + compare(completedSpy.count, 2); + compare(openedSpy.count, 2); + compare(closedSpy.count, 0); + compare(control.swipe.position, 0.4); + + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "canceled"]; + mouseRelease(control, control.width * -0.1, control.height / 2); + verify(!control.pressed); + tryCompare(control.swipe, "position", 0.0); + verify(!control.swipe.complete); + compare(completedSpy.count, 2); + compare(openedSpy.count, 2); + tryCompare(closedSpy, "count", 1); + verify(mouseSignalSequenceSpy.success); + tryCompare(control.contentItem, "x", control.leftPadding); + } + + function test_swipeVelocity_data() { + return [ + { tag: "positive velocity", direction: 1 }, + { tag: "negative velocity", direction: -1 } + ]; + } + + function test_swipeVelocity(data) { + skip("QTBUG-52003"); + + var control = createTemporaryObject(swipeDelegateComponent, testCase); + verify(control); + + var distance = Math.round(dragDistance * 1.1); + if (distance >= control.width / 2) + skip("This test requires a startDragDistance that is less than half the width of the control"); + + distance *= data.direction; + + mouseSignalSequenceSpy.target = control; + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed"]; + mousePress(control, control.width / 2, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 0.0); + verify(!control.swipe.complete); + verify(mouseSignalSequenceSpy.success); + verify(!control.swipe.leftItem); + verify(!control.swipe.rightItem); + + // Swipe quickly to the side over a distance that is longer than the drag threshold, + // quicker than the expose velocity threshold, but shorter than the halfway mark. + mouseMove(control, control.width / 2 + distance, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, distance / control.width); + verify(control.swipe.position < 0.5); + verify(!control.swipe.complete); + + var expectedVisibleItem; + var expectedVisibleObjectName; + var expectedHiddenItem; + var expectedContentItemX; + if (distance > 0) { + expectedVisibleObjectName = "leftItem"; + expectedVisibleItem = control.swipe.leftItem; + expectedHiddenItem = control.swipe.rightItem; + expectedContentItemX = control.width + control.leftPadding; + } else { + expectedVisibleObjectName = "rightItem"; + expectedVisibleItem = control.swipe.rightItem; + expectedHiddenItem = control.swipe.leftItem; + expectedContentItemX = -control.width + control.leftPadding; + } + verify(expectedVisibleItem); + verify(expectedVisibleItem.visible); + compare(expectedVisibleItem.parent, control); + compare(expectedVisibleItem.objectName, expectedVisibleObjectName); + verify(!expectedHiddenItem); + + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "released", "clicked"]; + // Add a delay to ensure that the release event doesn't happen too quickly, + // and hence that the second timestamp isn't zero (can happen with e.g. release builds). + mouseRelease(control, control.width / 2 + distance, control.height / 2, Qt.LeftButton, Qt.NoModifier, 30); + verify(!control.pressed); + compare(control.swipe.position, data.direction); + verify(control.swipe.complete); + verify(mouseSignalSequenceSpy.success); + verify(expectedVisibleItem); + verify(expectedVisibleItem.visible); + verify(!expectedHiddenItem); + tryCompare(control.contentItem, "x", expectedContentItemX); + } + + Component { + id: swipeDelegateWithButtonComponent + SwipeDelegate { + text: "SwipeDelegate" + width: 150 + swipe.right: Button { + width: parent.width + height: parent.height + text: "Boo!" + } + } + } + + function test_eventsToLeftAndRight() { + var control = createTemporaryObject(swipeDelegateWithButtonComponent, testCase); + verify(control); + + var closedSpy = signalSpyComponent.createObject(control, { target: control.swipe, signalName: "closed" }); + verify(closedSpy); + verify(closedSpy.valid); + + // The button should be pressed instead of the SwipeDelegate. + mouseDrag(control, control.width / 2, 0, -control.width, 0); + // Mouse has been released by this stage. + verify(!control.pressed); + compare(control.swipe.position, -1.0); + verify(control.swipe.rightItem); + verify(control.swipe.rightItem.visible); + compare(control.swipe.rightItem.parent, control); + + var buttonPressedSpy = signalSpyComponent.createObject(control, { target: control.swipe.rightItem, signalName: "pressed" }); + verify(buttonPressedSpy); + verify(buttonPressedSpy.valid); + var buttonReleasedSpy = signalSpyComponent.createObject(control, { target: control.swipe.rightItem, signalName: "released" }); + verify(buttonReleasedSpy); + verify(buttonReleasedSpy.valid); + var buttonClickedSpy = signalSpyComponent.createObject(control, { target: control.swipe.rightItem, signalName: "clicked" }); + verify(buttonClickedSpy); + verify(buttonClickedSpy.valid); + + // Now press the button. + mousePress(control, control.width / 2, control.height / 2); + verify(!control.pressed); + var button = control.swipe.rightItem; + verify(button.pressed); + compare(buttonPressedSpy.count, 1); + compare(buttonReleasedSpy.count, 0); + compare(buttonClickedSpy.count, 0); + + mouseRelease(control, control.width / 2, control.height / 2); + verify(!button.pressed); + compare(buttonPressedSpy.count, 1); + compare(buttonReleasedSpy.count, 1); + compare(buttonClickedSpy.count, 1); + + // Returning back to a position of 0 and pressing on the control should + // result in the control being pressed. + mouseDrag(control, control.width / 2, 0, control.width * 0.6, 0); + tryCompare(closedSpy, "count", 1); + compare(control.swipe.position, 0); + mousePress(control, control.width / 2, control.height / 2); + verify(control.pressed); + verify(!button.pressed); + mouseRelease(control, control.width / 2, control.height / 2); + verify(!control.pressed); + } + + function test_mouseButtons() { + var control = createTemporaryObject(swipeDelegateComponent, testCase); + verify(control); + + // click + mouseSignalSequenceSpy.target = control; + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed"]; + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + compare(control.pressed, true); + + verify(mouseSignalSequenceSpy.success); + + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": false }], "released", "clicked"]; + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton); + compare(control.pressed, false); + verify(mouseSignalSequenceSpy.success); + + // right button + mouseSignalSequenceSpy.expectedSequence = []; + mousePress(control, control.width / 2, control.height / 2, Qt.RightButton); + compare(control.pressed, false); + + mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton); + compare(control.pressed, false); + verify(mouseSignalSequenceSpy.success); + + // double click + mouseSignalSequenceSpy.expectedSequence = [ + ["pressedChanged", { "pressed": true }], + "pressed", + ["pressedChanged", { "pressed": false }], + "released", + "clicked", + ["pressedChanged", { "pressed": true }], + "pressed", + "doubleClicked", + ["pressedChanged", { "pressed": false }], + "released" + ]; + mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton); + verify(mouseSignalSequenceSpy.success); + + // press and hold + var pressAndHoldSpy = signalSpyComponent.createObject(control, { target: control, signalName: "pressAndHold" }); + verify(pressAndHoldSpy); + verify(pressAndHoldSpy.valid); + + mouseSignalSequenceSpy.expectedSequence = [ + ["pressedChanged", { "pressed": true }], + "pressed", + "pressAndHold", + ["pressedChanged", { "pressed": false }], + "released" + ]; + mousePress(control); + compare(control.pressed, true); + tryCompare(pressAndHoldSpy, "count", 1); + + mouseRelease(control); + compare(control.pressed, false); + verify(mouseSignalSequenceSpy.success); + } + + Component { + id: removableDelegatesComponent + + ListView { + id: listView + width: 100 + height: 120 + + model: ListModel { + ListElement { name: "Apple" } + ListElement { name: "Orange" } + ListElement { name: "Pear" } + } + + delegate: SwipeDelegate { + id: rootDelegate + text: modelData + width: listView.width + + property alias removeAnimation: onRemoveAnimation + + ListView.onRemove: SequentialAnimation { + id: onRemoveAnimation + + PropertyAction { + target: rootDelegate + property: "ListView.delayRemove" + value: true + } + NumberAnimation { + target: rootDelegate + property: "height" + to: 0 + easing.type: Easing.InOutQuad + } + PropertyAction { + target: rootDelegate; + property: "ListView.delayRemove"; + value: false + } + } + + swipe.left: Rectangle { + objectName: "rectangle" + color: SwipeDelegate.pressed ? "#333" : "#444" + anchors.fill: parent + + SwipeDelegate.onClicked: listView.model.remove(index) + + Label { + objectName: "label" + text: "Remove" + color: "white" + anchors.centerIn: parent + } + } + } + } + } + + function test_removableDelegates() { + var listView = createTemporaryObject(removableDelegatesComponent, testCase); + verify(listView); + compare(listView.count, 3); + + // Expose the remove button. + var firstItem = listView.itemAt(0, 0); + mousePress(listView, firstItem.width / 2, firstItem.height / 2); + verify(firstItem.pressed); + compare(firstItem.swipe.position, 0.0); + verify(!firstItem.swipe.complete); + verify(!firstItem.swipe.leftItem); + + mouseMove(listView, firstItem.width * 1.1, firstItem.height / 2); + verify(firstItem.pressed); + compare(firstItem.swipe.position, 0.6); + verify(!firstItem.swipe.complete); + verify(firstItem.swipe.leftItem); + verify(!firstItem.swipe.leftItem.SwipeDelegate.pressed); + + mouseRelease(listView, firstItem.width / 2, firstItem.height / 2); + verify(!firstItem.pressed); + tryCompare(firstItem.swipe, "position", 1.0); + tryCompare(firstItem.swipe, "complete", true); + compare(listView.count, 3); + + // Wait for it to settle down. + tryCompare(firstItem.contentItem, "x", firstItem.leftPadding + firstItem.width); + + var leftClickedSpy = signalSpyComponent.createObject(firstItem.swipe.leftItem, + { target: firstItem.swipe.leftItem.SwipeDelegate, signalName: "clicked" }); + verify(leftClickedSpy); + verify(leftClickedSpy.valid); + + // Click the left item to remove the delegate from the list. + var contentItemX = firstItem.contentItem.x; + mousePress(listView, firstItem.width / 2, firstItem.height / 2); + verify(firstItem.swipe.leftItem.SwipeDelegate.pressed); + compare(leftClickedSpy.count, 0); + verify(firstItem.pressed); + + mouseRelease(listView, firstItem.width / 2, firstItem.height / 2); + verify(!firstItem.swipe.leftItem.SwipeDelegate.pressed); + compare(leftClickedSpy.count, 1); + verify(!firstItem.pressed); + leftClickedSpy = null; + tryCompare(firstItem.removeAnimation, "running", true); + // There was a bug where the resizeContent() would be called because the height + // of the control was changing due to the animation. contentItem would then + // change x position and hence be visible when it shouldn't be. + verify(firstItem.removeAnimation.running); + while (1) { + wait(10) + if (firstItem && firstItem.removeAnimation && firstItem.removeAnimation.running) + compare(firstItem.contentItem.x, contentItemX); + else + break; + } + compare(listView.count, 2); + } + + Component { + id: leadingTrailingXComponent + SwipeDelegate { + id: delegate + width: 150 + text: "SwipeDelegate" + + swipe.left: Rectangle { + x: delegate.background.x - width + width: delegate.width + height: delegate.height + color: "green" + } + + swipe.right: Rectangle { + x: delegate.background.x + delegate.background.width + width: delegate.width + height: delegate.height + color: "red" + } + } + } + + Component { + id: leadingTrailingAnchorsComponent + SwipeDelegate { + id: delegate + width: 150 + text: "SwipeDelegate" + + swipe.left: Rectangle { + anchors.right: delegate.background.left + width: delegate.width + height: delegate.height + color: "green" + } + + swipe.right: Rectangle { + anchors.left: delegate.background.right + width: delegate.width + height: delegate.height + color: "red" + } + } + } + + function test_leadingTrailing_data() { + return [ + { tag: "x", component: leadingTrailingXComponent }, + { tag: "anchors", component: leadingTrailingAnchorsComponent }, + ]; + } + + function test_leadingTrailing(data) { + var control = createTemporaryObject(data.component, testCase); + verify(control); + + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width, control.height / 2); + verify(control.swipe.leftItem); + compare(control.swipe.leftItem.x, -control.width / 2); + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton); + } + + function test_minMaxPosition() { + var control = createTemporaryObject(leadingTrailingXComponent, testCase); + verify(control); + + // Should be limited within the range -1.0 to 1.0. + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width * 1.5, control.height / 2); + compare(control.swipe.position, 1.0); + mouseMove(control, control.width * 1.6, control.height / 2); + compare(control.swipe.position, 1.0); + mouseMove(control, control.width * -1.6, control.height / 2); + compare(control.swipe.position, -1.0); + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton); + } + + Component { + id: emptySwipeDelegateComponent + + SwipeDelegate { + text: "SwipeDelegate" + width: 150 + } + } + + Component { + id: smallLeftComponent + + Rectangle { + width: 80 + height: 40 + color: "green" + } + } + + // swipe.position should be scaled to the width of the relevant delegate, + // and it shouldn't be possible to drag past the delegate (so that content behind the control is visible). + function test_delegateWidth() { + var control = createTemporaryObject(emptySwipeDelegateComponent, testCase); + verify(control); + + control.swipe.left = smallLeftComponent; + + // Ensure that the position is scaled to the width of the currently visible delegate. + var overDragDistance = Math.round(dragDistance * 1.1); + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width / 2 + overDragDistance, control.height / 2); + verify(control.swipe.leftItem); + compare(control.swipe.position, overDragDistance / control.swipe.leftItem.width); + + mouseMove(control, control.width / 2 + control.swipe.leftItem.width, control.height / 2); + compare(control.swipe.position, 1.0); + + // Ensure that it's not possible to drag past the (left) delegate. + mouseMove(control, control.width / 2 + control.swipe.leftItem.width + 1, control.height / 2); + compare(control.swipe.position, 1.0); + + // Now release over the right side; the position should be 1.0 and the background + // should be "anchored" to the right side of the left delegate item. + mouseMove(control, control.width / 2 + control.swipe.leftItem.width, control.height / 2); + mouseRelease(control, control.width / 2 + control.swipe.leftItem.width, control.height / 2, Qt.LeftButton); + compare(control.swipe.position, 1.0); + tryCompare(control.background, "x", control.swipe.leftItem.width, 1000); + } + + SignalSpy { + id: leftVisibleSpy + signalName: "visibleChanged" + } + + SignalSpy { + id: rightVisibleSpy + signalName: "visibleChanged" + } + + function test_positionAfterSwipeCompleted() { + var control = createTemporaryObject(swipeDelegateComponent, testCase); + verify(control); + + // Ensure that both delegates are constructed. + mousePress(control, 0, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width * 1.1, control.height / 2); + verify(control.swipe.leftItem); + mouseMove(control, control.width * -0.1, control.height / 2); + verify(control.swipe.rightItem); + + // Expose the left delegate. + mouseMove(control, control.swipe.leftItem.width, control.height / 2); + mouseRelease(control, control.swipe.leftItem.width, control.height / 2); + verify(control.swipe.complete); + compare(control.swipe.position, 1.0); + + leftVisibleSpy.target = control.swipe.leftItem; + rightVisibleSpy.target = control.swipe.rightItem; + + // Swipe from right to left without exposing the right item, + // and make sure that the right item never becomes visible + // (and hence that the left item never loses visibility). + mousePress(control, control.swipe.leftItem.width - 1, control.height / 2, Qt.LeftButton); + compare(leftVisibleSpy.count, 0); + compare(rightVisibleSpy.count, 0); + var newX = control.swipe.leftItem.width - Math.round(dragDistance * 1.1) -1; + mouseMove(control, newX, control.height / 2); + compare(leftVisibleSpy.count, 0); + compare(rightVisibleSpy.count, 0); + compare(control.swipe.position, (newX + 1) / control.swipe.leftItem.width); + + mouseMove(control, 0, control.height / 2); + compare(control.swipe.position, 1 / control.swipe.leftItem.width); + // Because we move from (width - 1) to 0, so one pixel remains + + // Test swiping over a distance that is greater than the width of the left item. + mouseMove(control, -1, control.height / 2); + verify(control.swipe.rightItem); + compare(control.swipe.position, 0); + + // Now go back to 1.0. + mouseMove(control, control.swipe.leftItem.width - 1, control.height / 2); + compare(control.swipe.position, 1.0); + tryCompare(control.background, "x", control.swipe.leftItem.width, 1000); + mouseRelease(control, control.swipe.leftItem.width, control.height / 2, Qt.LeftButton); + } + + // TODO: this somehow results in the behind item having a negative width +// Component { +// id: behindSwipeDelegateComponent +// SwipeDelegate { +// anchors.centerIn: parent +// swipe.behind: Rectangle { +// onXChanged: print("x changed", x) +// anchors.left: { +// print("anchors.left expression", swipe.position) +// swipe.position < 0 ? parent.background.right : undefined +// } +// anchors.right: { +// print("anchors.right expression", swipe.position) +// swipe.position > 0 ? parent.background.left : undefined +// } +// width: parent.width +// height: parent.height +// color: "green" +// } +// swipe.left: null +// swipe.right: null +// Rectangle { +// anchors.fill: parent +// color: "transparent" +// border.color: "darkorange" +// } +// } +// } + + Component { + id: behindSwipeDelegateComponent + SwipeDelegate { + text: "SwipeDelegate" + width: 150 + anchors.centerIn: parent + swipe.behind: Rectangle { + x: swipe.position < 0 ? parent.background.x + parent.background.width + : (swipe.position > 0 ? parent.background.x - width : 0) + width: parent.width + height: parent.height + color: "green" + } + swipe.left: null + swipe.right: null + } + } + + function test_leadingTrailingBehindItem() { + var control = createTemporaryObject(behindSwipeDelegateComponent, testCase); + verify(control); + + swipe(control, 0.0, 1.0); + verify(control.swipe.behindItem.visible); + compare(control.swipe.behindItem.x, control.background.x - control.background.width); + + swipe(control, 1.0, -1.0); + verify(control.swipe.behindItem.visible); + compare(control.swipe.behindItem.x, control.background.x + control.background.width); + + swipe(control, -1.0, 1.0); + verify(control.swipe.behindItem.visible); + compare(control.swipe.behindItem.x, control.background.x - control.background.width); + + // Should be possible to "wrap" with a behind delegate specified. + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width / 2 + control.swipe.behindItem.width * 0.8, control.height / 2); + compare(control.swipe.position, -0.2); + mouseRelease(control, control.width / 2 + control.swipe.behindItem.width * 0.8, control.height / 2, Qt.LeftButton); + tryCompare(control.swipe, "position", 0.0); + + // Try wrapping the other way. + swipe(control, 0.0, -1.0); + verify(control.swipe.behindItem.visible); + compare(control.swipe.behindItem.x, control.background.x + control.background.width); + + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width / 2 - control.swipe.behindItem.width * 0.8, control.height / 2); + compare(control.swipe.position, 0.2); + mouseRelease(control, control.width / 2 - control.swipe.behindItem.width * 0.8, control.height / 2, Qt.LeftButton); + tryCompare(control.swipe, "position", 0.0); + } + + Component { + id: closeSwipeDelegateComponent + + SwipeDelegate { + text: "SwipeDelegate" + width: 150 + + swipe.right: Rectangle { + color: "green" + width: parent.width + height: parent.height + + SwipeDelegate.onClicked: swipe.close() + } + } + } + + function test_close() { + var control = createTemporaryObject(closeSwipeDelegateComponent, testCase); + verify(control); + + var closedSpy = signalSpyComponent.createObject(control, { target: control.swipe, signalName: "closed" }); + verify(closedSpy); + verify(closedSpy.valid); + + swipe(control, 0.0, -1.0); + compare(control.swipe.rightItem.visible, true); + // Should animate, so it shouldn't change right away. + compare(control.swipe.rightItem.x, 0); + tryCompare(control.swipe.rightItem, "x", control.background.x + control.background.width); + + mousePress(control); + verify(control.swipe.rightItem.SwipeDelegate.pressed); + + mouseRelease(control); + verify(!control.swipe.rightItem.SwipeDelegate.pressed); + tryCompare(closedSpy, "count", 1); + compare(control.swipe.position, 0); + + // Swiping after closing should work as normal. + swipe(control, 0.0, -1.0); + } + + function test_callCloseWhenAlreadyClosed() { + let control = createTemporaryObject(swipeDelegateComponent, testCase) + verify(control) + + let closedSpy = signalSpyComponent.createObject(control, { target: control.swipe, signalName: "closed" }) + verify(closedSpy) + verify(closedSpy.valid) + + // Calling close() when it's already closed should have no effect. + control.swipe.close() + compare(closedSpy.count, 0) + + // The game goes for calling close() in response to a click. + control.clicked.connect(function() { control.swipe.close() }) + mouseClick(control) + compare(closedSpy.count, 0) + } + + // Can't just connect to pressed in QML, because there is a pressed property + // that conflicts with the signal. + Component { + id: swipeDelegateCloseOnPressedComponent + + SwipeDelegate { + text: "SwipeDelegate" + width: 150 + swipe.right: Rectangle { + objectName: "rightItem" + width: parent.width / 2 + height: parent.height + color: "tomato" + } + + onPressed: swipe.close() + } + } + + /* + We don't want to support closing on pressed(); released() or clicked() + should be used instead. However, calling swipe.close() in response to + a press should still not cause closed() to be emitted. + */ + function test_closeOnPressed() { + let control = createTemporaryObject(swipeDelegateCloseOnPressedComponent, testCase) + verify(control) + + swipe(control, 0.0, -1.0) + + let closedSpy = signalSpyComponent.createObject(control, { target: control.swipe, signalName: "closed" }) + verify(closedSpy) + verify(closedSpy.valid) + + mousePress(control, control.width * 0.1) + compare(closedSpy.count, 0) + compare(control.swipe.position, -1.0) + + // Simulate a somewhat realistic delay between press and release + // to ensure that the bug is triggered. + wait(100) + mouseRelease(control, control.width * 0.1) + compare(closedSpy.count, 0) + compare(control.swipe.position, -1.0) + } + + Component { + id: multiActionSwipeDelegateComponent + + SwipeDelegate { + text: "SwipeDelegate" + width: 150 + + swipe.right: Item { + objectName: "rightItemRoot" + width: parent.width + height: parent.height + + property alias firstAction: firstAction + property alias secondAction: secondAction + + property int firstClickCount: 0 + property int secondClickCount: 0 + + Row { + anchors.fill: parent + anchors.margins: 5 + + Rectangle { + id: firstAction + width: parent.width / 2 + height: parent.height + color: "tomato" + + SwipeDelegate.onClicked: ++firstClickCount + } + Rectangle { + id: secondAction + width: parent.width / 2 + height: parent.height + color: "navajowhite" + + SwipeDelegate.onClicked: ++secondClickCount + } + } + } + } + } + + // Tests that it's possible to have multiple non-interactive items in one delegate + // (e.g. left/right/behind) that can each receive clicks. + function test_multipleClickableActions() { + var control = createTemporaryObject(multiActionSwipeDelegateComponent, testCase); + verify(control); + + swipe(control, 0.0, -1.0); + verify(control.swipe.rightItem); + tryCompare(control.swipe, "complete", true); + + var firstClickedSpy = signalSpyComponent.createObject(control, + { target: control.swipe.rightItem.firstAction.SwipeDelegate, signalName: "clicked" }); + verify(firstClickedSpy); + verify(firstClickedSpy.valid); + + // Clicked within rightItem, but not within an item using the attached properties. + mousePress(control, 2, 2); + compare(control.swipe.rightItem.firstAction.SwipeDelegate.pressed, false); + compare(firstClickedSpy.count, 0); + + mouseRelease(control, 2, 2); + compare(control.swipe.rightItem.firstAction.SwipeDelegate.pressed, false); + compare(firstClickedSpy.count, 0); + + // Click within the first item. + mousePress(control.swipe.rightItem.firstAction, 0, 0); + compare(control.swipe.rightItem.firstAction.SwipeDelegate.pressed, true); + compare(firstClickedSpy.count, 0); + + mouseRelease(control.swipe.rightItem.firstAction, 0, 0); + compare(control.swipe.rightItem.firstAction.SwipeDelegate.pressed, false); + compare(firstClickedSpy.count, 1); + compare(control.swipe.rightItem.firstClickCount, 1); + + var secondClickedSpy = signalSpyComponent.createObject(control, + { target: control.swipe.rightItem.secondAction.SwipeDelegate, signalName: "clicked" }); + verify(secondClickedSpy); + verify(secondClickedSpy.valid); + + // Click within the second item. + mousePress(control.swipe.rightItem.secondAction, 0, 0); + compare(control.swipe.rightItem.secondAction.SwipeDelegate.pressed, true); + compare(secondClickedSpy.count, 0); + + mouseRelease(control.swipe.rightItem.secondAction, 0, 0); + compare(control.swipe.rightItem.secondAction.SwipeDelegate.pressed, false); + compare(secondClickedSpy.count, 1); + compare(control.swipe.rightItem.secondClickCount, 1); + } + + // Pressing on a "side action" and then dragging should eventually + // cause the ListView to grab the mouse and start changing its contentY. + // When this happens, it will grab the mouse and hence we must clear + // that action's pressed state so that it doesn't stay pressed after releasing. + function test_dragSideAction() { + var listView = createTemporaryObject(removableDelegatesComponent, testCase); + verify(listView); + + var control = listView.itemAt(0, 0); + verify(control); + + // Expose the side action. + swipe(control, 0.0, 1.0); + verify(control.swipe.leftItem); + tryCompare(control.swipe, "complete", true); + + var pressedSpy = signalSpyComponent.createObject(control, + { target: control.swipe.leftItem.SwipeDelegate, signalName: "pressedChanged" }); + verify(pressedSpy); + verify(pressedSpy.valid); + + mouseDrag(listView, 20, 20, 0, listView.height); + compare(pressedSpy.count, 2); + verify(listView.contentY !== 0); + + compare(control.swipe.leftItem.SwipeDelegate.pressed, false); + } + + // When the width of a SwipeDelegate changes (as it does upon portrait => landscape + // rotation, for example), the positions of the contentItem and background items + // should be updated accordingly. + function test_contentItemPosOnWidthChanged() { + var control = createTemporaryObject(swipeDelegateComponent, testCase); + verify(control); + + swipe(control, 0.0, 1.0); + + var oldContentItemX = control.contentItem.x; + var oldBackgroundX = control.background.x; + control.width += 100; + compare(control.contentItem.x, oldContentItemX + 100); + compare(control.background.x, oldBackgroundX + 100); + } + + function test_contentItemHeightOnHeightChanged() { + var control = createTemporaryObject(swipeDelegateComponent, testCase); + verify(control); + + // Try when swipe.complete is false. + var originalHeight = control.height; + var originalContentItemHeight = control.contentItem.height; + verify(control.height !== 10); + control.height = 10; + compare(control.contentItem.height, control.availableHeight); + verify(control.contentItem.height < originalContentItemHeight); + compare(control.contentItem.y, control.topPadding); + + // Try when swipe.complete is true. + control.height = originalHeight; + swipe(control, 0.0, 1.0); + control.height = 10; + compare(control.contentItem.height, control.availableHeight); + verify(control.contentItem.height < originalContentItemHeight); + compare(control.contentItem.y, control.topPadding); + } + + function test_releaseOutside_data() { + return [ + { tag: "no delegates", component: emptySwipeDelegateComponent }, + { tag: "delegates", component: swipeDelegateComponent }, + ]; + } + + function test_releaseOutside(data) { + var control = createTemporaryObject(data.component, testCase); + verify(control); + + // Press and then release below the control. + mouseSignalSequenceSpy.target = control; + mouseSignalSequenceSpy.expectedSequence = [["pressedChanged", { "pressed": true }], "pressed", ["pressedChanged", { "pressed": false }]]; + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width / 2, control.height + 10); + verify(mouseSignalSequenceSpy.success); + + mouseSignalSequenceSpy.expectedSequence = ["canceled"]; + mouseRelease(control, control.width / 2, control.height + 10, Qt.LeftButton); + verify(mouseSignalSequenceSpy.success); + + // Press and then release to the right of the control. + var hasDelegates = control.swipe.left || control.swipe.right || control.swipe.behind; + mouseSignalSequenceSpy.target = control; + mouseSignalSequenceSpy.expectedSequence = hasDelegates + ? [["pressedChanged", { "pressed": true }], "pressed"] + : [["pressedChanged", { "pressed": true }], "pressed", ["pressedChanged", { "pressed": false }]]; + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width + 10, control.height / 2); + if (hasDelegates) + verify(control.swipe.position > 0); + verify(mouseSignalSequenceSpy.success); + + mouseSignalSequenceSpy.expectedSequence = hasDelegates ? [["pressedChanged", { "pressed": false }], "canceled"] : ["canceled"]; + mouseRelease(control, control.width + 10, control.height / 2, Qt.LeftButton); + verify(mouseSignalSequenceSpy.success); + } + + Component { + id: leftRightWithLabelsComponent + + SwipeDelegate { + id: delegate + text: "SwipeDelegate" + width: 150 + + background.opacity: 0.5 + + swipe.left: Rectangle { + width: parent.width + height: parent.height + color: SwipeDelegate.pressed ? Qt.darker("green") : "green" + + property alias label: label + + Label { + id: label + text: "Left" + color: "white" + anchors.margins: 10 + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + } + + SwipeDelegate.onClicked: delegate.swipe.close() + } + + swipe.right: Rectangle { + width: parent.width + height: parent.height + anchors.right: parent.right + color: SwipeDelegate.pressed ? Qt.darker("green") : "red" + + property alias label: label + + Label { + id: label + text: "Right" + color: "white" + anchors.margins: 10 + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + } + + SwipeDelegate.onClicked: delegate.swipe.close() + } + } + } + + function test_beginSwipeOverRightItem() { + var control = createTemporaryObject(leftRightWithLabelsComponent, testCase); + verify(control); + + // Swipe to the left, exposing the right item. + swipe(control, 0.0, -1.0); + + // Click to close it and go back to a position of 0. + mouseClick(control); + + // TODO: Swipe to the left, with the mouse over the Label in the right item. + // The left item should not become visible at any point. + var rightLabel = control.swipe.rightItem.label; + var overDragDistance = Math.round(dragDistance * 1.1); + mousePress(rightLabel, rightLabel.width / 2, rightLabel.height / 2, Qt.rightButton); + mouseMove(rightLabel, rightLabel.width / 2 - overDragDistance, rightLabel.height / 2); + verify(!control.swipe.leftItem); + + mouseRelease(rightLabel, rightLabel.width / 2 - overDragDistance, control.height / 2, Qt.LeftButton); + verify(!control.swipe.leftItem); + } + + Component { + id: swipeDelegateDisabledComponent + + SwipeDelegate { + id: swipeDelegate + text: "SwipeDelegate" + width: parent.width + height: checked ? implicitHeight * 2 : implicitHeight + checkable: true + + swipe.enabled: false + swipe.right: Label { + text: swipeDelegate.checked ? qsTr("Expanded") : qsTr("Collapsed") + width: parent.width + height: parent.height + padding: 12 + color: "white" + verticalAlignment: Label.AlignVCenter + horizontalAlignment: Label.AlignRight + } + } + } + + function test_swipeEnabled() { + var control = createTemporaryObject(swipeDelegateDisabledComponent, testCase); + + mousePress(control, control.width / 2, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 0.0); + verify(!control.swipe.complete); + verify(!control.swipe.leftItem); + verify(!control.swipe.rightItem); + + // It shouldn't be possible to swipe. + var overDragDistance = Math.round(dragDistance * 1.1); + mouseMove(control, control.width / 2 - overDragDistance, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 0.0); + verify(!control.swipe.complete); + verify(!control.swipe.leftItem); + verify(!control.swipe.rightItem); + + // Now move outside the right edge of the control and release. + mouseMove(control, control.width * 1.1, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, 0.0); + verify(!control.swipe.complete); + verify(!control.swipe.leftItem); + verify(!control.swipe.rightItem); + + mouseRelease(control, control.width / 2, control.height / 2); + verify(!control.pressed); + compare(control.swipe.position, 0.0); + verify(!control.swipe.complete); + verify(!control.swipe.leftItem); + verify(!control.swipe.rightItem); + + // Now enabled swiping so that we can swipe to the left. + control.swipe.enabled = true; + swipe(control, 0, -1); + verify(control.swipe.complete); + + // Now that the swipe is complete, disable swiping and then try to swipe again. + // It should stay at its position of -1. + control.swipe.enabled = false; + + mousePress(control, control.width / 2, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, -1.0); + + mouseMove(control, control.width / 2 + overDragDistance, control.height / 2); + verify(control.pressed); + compare(control.swipe.position, -1.0); + verify(control.swipe.complete); + + mouseRelease(control, control.width / 2 + overDragDistance, control.height / 2); + verify(!control.pressed); + compare(control.swipe.position, -1.0); + verify(control.swipe.complete); + } + + function test_side() { + compare(SwipeDelegate.Left, 1.0); + compare(SwipeDelegate.Right, -1.0); + } + + function test_open_side_data() { + return [ + { tag: "left", side: SwipeDelegate.Left, position: 1, complete: true, left: greenLeftComponent, right: null, behind: null }, + { tag: "right", side: SwipeDelegate.Right, position: -1, complete: true, left: null, right: redRightComponent, behind: null }, + { tag: "behind,left", side: SwipeDelegate.Left, position: 1, complete: true, left: null, right: null, behind: greenLeftComponent }, + { tag: "behind,right", side: SwipeDelegate.Right, position: -1, complete: true, left: null, right: null, behind: redRightComponent }, + { tag: "left,behind", side: SwipeDelegate.Left, position: 1, complete: true, left: null, right: null, behind: greenLeftComponent }, + { tag: "right,behind", side: SwipeDelegate.Right, position: -1, complete: true, left: null, right: null, behind: redRightComponent }, + { tag: "left,null", side: SwipeDelegate.Left, position: 0, complete: false, left: null, right: null, behind: null }, + { tag: "right,null", side: SwipeDelegate.Right, position: 0, complete: false, left: null, right: null, behind: null }, + { tag: "invalid", side: 0, position: 0, complete: false, left: greenLeftComponent, right: null, behind: null } + ] + } + + function test_open_side(data) { + var control = createTemporaryObject(emptySwipeDelegateComponent, testCase, + {"swipe.left": data.left, "swipe.right": data.right, "swipe.behind": data.behind}); + verify(control); + + control.swipe.open(data.side); + tryCompare(control.swipe, "position", data.position); + tryCompare(control.swipe, "complete", data.complete); + } + + Component { + id: openSwipeDelegateComponent + + SwipeDelegate { + text: "SwipeDelegate" + width: 150 + + onClicked: swipe.open(SwipeDelegate.Right) + + swipe.right: Item { + width: parent.width + height: parent.height + } + } + } + + function test_open() { + var control = createTemporaryObject(openSwipeDelegateComponent, testCase); + verify(control); + + mouseClick(control); + tryCompare(control.swipe, "position", SwipeDelegate.Right); + tryCompare(control.background, "x", -control.background.width); + + // Swiping after opening should work as normal. + swipe(control, SwipeDelegate.Right, 0.0); + tryCompare(control.swipe, "position", 0.0); + tryCompare(control.background, "x", 0); + } + + Component { + id: animationSwipeDelegateComponent + + SwipeDelegate { + id: control + text: "SwipeDelegate" + width: 150 + swipe.left: greenLeftComponent + swipe.right: redRightComponent + swipe.transition: null + + property alias behavior: xBehavior + property alias animation: numberAnimation + + background: Rectangle { + color: control.down ? "#ccc" : "#fff" + + Behavior on x { + id: xBehavior + enabled: !control.down + + NumberAnimation { + id: numberAnimation + easing.type: Easing.InOutCubic + duration: 400 + } + } + } + } + } + + function test_animations() { + // Test that animations are run when releasing from a drag. + var control = createTemporaryObject(animationSwipeDelegateComponent, testCase); + verify(control); + + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton); + mouseMove(control, control.width - 1, control.height / 2); + verify(control.down); + verify(!control.behavior.enabled); + verify(!control.animation.running); + + mouseRelease(control, control.width - 1, control.height / 2, Qt.LeftButton); + verify(!control.down); + verify(control.behavior.enabled); + verify(control.animation.running); + } + + function test_spacing() { + var control = createTemporaryObject(swipeDelegateComponent, testCase, { text: "Some long, long, long text" }) + verify(control) + verify(control.contentItem.implicitWidth + control.leftPadding + control.rightPadding > control.background.implicitWidth) + + var textLabel = findChild(control.contentItem, "label") + verify(textLabel) + + // The implicitWidth of the IconLabel that all buttons use as their contentItem + // should be equal to the implicitWidth of the Text while no icon is set. + compare(control.contentItem.implicitWidth, textLabel.implicitWidth) + + // That means that spacing shouldn't affect it. + control.spacing += 100 + compare(control.contentItem.implicitWidth, textLabel.implicitWidth) + + // The implicitWidth of the SwipeDelegate itself should, therefore, also never include spacing while no icon is set. + compare(control.implicitWidth, textLabel.implicitWidth + control.leftPadding + control.rightPadding) + } + + function test_display_data() { + return [ + { "tag": "IconOnly", display: SwipeDelegate.IconOnly }, + { "tag": "TextOnly", display: SwipeDelegate.TextOnly }, + { "tag": "TextUnderIcon", display: SwipeDelegate.TextUnderIcon }, + { "tag": "TextBesideIcon", display: SwipeDelegate.TextBesideIcon }, + { "tag": "IconOnly, mirrored", display: SwipeDelegate.IconOnly, mirrored: true }, + { "tag": "TextOnly, mirrored", display: SwipeDelegate.TextOnly, mirrored: true }, + { "tag": "TextUnderIcon, mirrored", display: SwipeDelegate.TextUnderIcon, mirrored: true }, + { "tag": "TextBesideIcon, mirrored", display: SwipeDelegate.TextBesideIcon, mirrored: true } + ] + } + + function test_display(data) { + var control = createTemporaryObject(swipeDelegateComponent, testCase, { + text: "SwipeDelegate", + display: data.display, + width: 400, + "icon.source": "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png", + "LayoutMirroring.enabled": !!data.mirrored + }) + verify(control) + compare(control.icon.source, "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png") + + var iconImage = findChild(control.contentItem, "image") + var textLabel = findChild(control.contentItem, "label") + + switch (control.display) { + case SwipeDelegate.IconOnly: + verify(iconImage) + verify(!textLabel) + compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + break; + case SwipeDelegate.TextOnly: + verify(!iconImage) + verify(textLabel) + compare(textLabel.x, control.mirrored ? control.availableWidth - textLabel.width : 0) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + case SwipeDelegate.TextUnderIcon: + verify(iconImage) + verify(textLabel) + compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + verify(iconImage.y < textLabel.y) + break; + case SwipeDelegate.TextBesideIcon: + verify(iconImage) + verify(textLabel) + if (control.mirrored) + verify(textLabel.x < iconImage.x) + else + verify(iconImage.x < textLabel.x) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + } + } + + function test_resizeParent() { + let container = createTemporaryObject(itemComponent, testCase, { objectName: "container", width: 100, height: 200 }) + verify(container) + + let control = swipeDelegateComponent.createObject(container, { width: Qt.binding(function() { return container.width }) }) + verify(control) + + // Resize while closed. + container.width = 200 + compare(container.width, 200) + compare(control.width, 200) + compare(control.background.width, 200) + compare(control.contentItem.width, 200 - control.leftPadding - control.rightPadding) + + // Return to original size. + container.width = 100 + compare(control.width, 100) + compare(control.background.width, 100) + compare(control.contentItem.width, 100 - control.leftPadding - control.rightPadding) + + // Swipe to the left to open. + swipe(control, 0, -1.0) + // Nothing should have changed except positions. + compare(control.width, 100) + compare(control.background.width, 100) + compare(control.contentItem.width, 100 - control.leftPadding - control.rightPadding) + + // Resize while open. + container.width = 200 + // The items should fill the width as usual. + compare(control.width, 200) + compare(control.background.width, 200) + compare(control.contentItem.width, 200 - control.leftPadding - control.rightPadding) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_swipeview.qml b/tests/auto/quickcontrols2/controls/data/tst_swipeview.qml new file mode 100644 index 00000000000..61dbecd6600 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_swipeview.qml @@ -0,0 +1,737 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "SwipeView" + + Component { + id: swipeView + SwipeView { } + } + + Component { + id: page + Text { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_current() { + var control = createTemporaryObject(swipeView, testCase) + + var currentItemChangedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "currentItemChanged"}) + verify(currentItemChangedSpy.valid) + + compare(control.count, 0) + compare(control.currentIndex, -1) + compare(control.currentItem, null) + + var item0 = page.createObject(control, {text: "0"}) + control.addItem(item0) + compare(control.count, 1) + compare(control.currentIndex, 0) + compare(control.currentItem.text, "0") + compare(currentItemChangedSpy.count, 1); + compare(control.contentWidth, item0.implicitWidth) + compare(control.contentHeight, item0.implicitHeight) + + var item1 = page.createObject(control, {text: "11"}) + control.addItem(item1) + compare(control.count, 2) + compare(control.currentIndex, 0) + compare(control.currentItem.text, "0") + compare(currentItemChangedSpy.count, 1); + compare(control.contentWidth, item0.implicitWidth) + compare(control.contentHeight, item0.implicitHeight) + + var item2 = page.createObject(control, {text: "222"}) + control.addItem(item2) + compare(control.count, 3) + compare(control.currentIndex, 0) + compare(control.currentItem.text, "0") + compare(currentItemChangedSpy.count, 1); + compare(control.contentWidth, item0.implicitWidth) + compare(control.contentHeight, item0.implicitHeight) + + control.currentIndex = 1 + compare(control.currentIndex, 1) + compare(control.currentItem.text, "11") + compare(currentItemChangedSpy.count, 2); + compare(control.contentWidth, item1.implicitWidth) + compare(control.contentHeight, item1.implicitHeight) + + control.currentIndex = 2 + compare(control.currentIndex, 2) + compare(control.currentItem.text, "222") + compare(currentItemChangedSpy.count, 3); + compare(control.contentWidth, item2.implicitWidth) + compare(control.contentHeight, item2.implicitHeight) + + control.decrementCurrentIndex() + compare(control.currentIndex, 1) + compare(control.currentItem.text, "11") + compare(currentItemChangedSpy.count, 4); + compare(control.contentWidth, item1.implicitWidth) + compare(control.contentHeight, item1.implicitHeight) + + control.incrementCurrentIndex() + compare(control.currentIndex, 2) + compare(control.currentItem.text, "222") + compare(currentItemChangedSpy.count, 5); + compare(control.contentWidth, item2.implicitWidth) + compare(control.contentHeight, item2.implicitHeight) + } + + Component { + id: initialCurrentSwipeView + SwipeView { + currentIndex: 1 + + property alias item0: item0 + property alias item1: item1 + + Item { + id: item0 + } + Item { + id: item1 + } + } + } + + function test_initialCurrent() { + var control = createTemporaryObject(initialCurrentSwipeView, testCase) + + compare(control.count, 2) + compare(control.currentIndex, 1) + compare(control.currentItem, control.item1) + } + + function test_addRemove() { + var control = createTemporaryObject(swipeView, testCase) + + function verifyCurrentIndexCountDiff() { + verify(control.currentIndex < control.count) + } + control.currentIndexChanged.connect(verifyCurrentIndexCountDiff) + control.countChanged.connect(verifyCurrentIndexCountDiff) + + var currentItemChangedSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "currentItemChanged"}) + verify(currentItemChangedSpy.valid) + + compare(control.count, 0) + compare(control.currentIndex, -1) + compare(control.currentItem, null) + control.addItem(page.createObject(control, {text: "1"})) + compare(control.count, 1) + compare(control.currentIndex, 0) + compare(currentItemChangedSpy.count, 1) + compare(control.currentItem.text, "1") + control.addItem(page.createObject(control, {text: "2"})) + compare(control.count, 2) + compare(control.currentIndex, 0) + compare(currentItemChangedSpy.count, 1) + compare(control.currentItem.text, "1") + compare(control.itemAt(0).text, "1") + compare(control.itemAt(1).text, "2") + + control.currentIndex = 1 + compare(currentItemChangedSpy.count, 2) + + control.insertItem(1, page.createObject(control, {text: "3"})) + compare(control.count, 3) + compare(control.currentIndex, 2) + compare(control.currentItem.text, "2") + compare(control.itemAt(0).text, "1") + compare(control.itemAt(1).text, "3") + compare(control.itemAt(2).text, "2") + + control.insertItem(0, page.createObject(control, {text: "4"})) + compare(control.count, 4) + compare(control.currentIndex, 3) + compare(control.currentItem.text, "2") + compare(control.itemAt(0).text, "4") + compare(control.itemAt(1).text, "1") + compare(control.itemAt(2).text, "3") + compare(control.itemAt(3).text, "2") + + control.insertItem(control.count, page.createObject(control, {text: "5"})) + compare(control.count, 5) + compare(control.currentIndex, 3) + compare(control.currentItem.text, "2") + compare(control.itemAt(0).text, "4") + compare(control.itemAt(1).text, "1") + compare(control.itemAt(2).text, "3") + compare(control.itemAt(3).text, "2") + compare(control.itemAt(4).text, "5") + + control.removeItem(control.itemAt(control.count - 1)) + compare(control.count, 4) + compare(control.currentIndex, 3) + compare(control.currentItem.text, "2") + compare(control.itemAt(0).text, "4") + compare(control.itemAt(1).text, "1") + compare(control.itemAt(2).text, "3") + compare(control.itemAt(3).text, "2") + + control.removeItem(control.itemAt(0)) + compare(control.count, 3) + compare(control.currentIndex, 2) + compare(control.currentItem.text, "2") + compare(control.itemAt(0).text, "1") + compare(control.itemAt(1).text, "3") + compare(control.itemAt(2).text, "2") + + control.removeItem(control.itemAt(1)) + compare(control.count, 2) + compare(control.currentIndex, 1) + compare(control.currentItem.text, "2") + compare(control.itemAt(0).text, "1") + compare(control.itemAt(1).text, "2") + + currentItemChangedSpy.clear() + + control.removeItem(control.itemAt(1)) + compare(control.count, 1) + compare(control.currentIndex, 0) + compare(currentItemChangedSpy.count, 1) + compare(control.currentItem.text, "1") + compare(control.itemAt(0).text, "1") + + control.removeItem(control.itemAt(0)) + compare(control.count, 0) + compare(control.currentIndex, -1) + compare(currentItemChangedSpy.count, 2) + } + + Component { + id: contentView + SwipeView { + QtObject { objectName: "object" } + Item { objectName: "page1" } + Timer { objectName: "timer" } + Item { objectName: "page2" } + Component { Item { } } + } + } + + function test_content() { + var control = createTemporaryObject(contentView, testCase) + + function compareObjectNames(content, names) { + if (content.length !== names.length) + return false + for (var i = 0; i < names.length; ++i) { + if (content[i].objectName !== names[i]) + return false + } + return true + } + + verify(compareObjectNames(control.contentData, ["object", "page1", "timer", "page2", ""])) + verify(compareObjectNames(control.contentChildren, ["page1", "page2"])) + + control.addItem(page.createObject(control, {objectName: "page3"})) + verify(compareObjectNames(control.contentData, ["object", "page1", "timer", "page2", "", "page3"])) + verify(compareObjectNames(control.contentChildren, ["page1", "page2", "page3"])) + + control.insertItem(0, page.createObject(control, {objectName: "page4"})) + verify(compareObjectNames(control.contentData, ["object", "page1", "timer", "page2", "", "page3", "page4"])) + verify(compareObjectNames(control.contentChildren, ["page4", "page1", "page2", "page3"])) + + control.moveItem(1, 2) + verify(compareObjectNames(control.contentData, ["object", "page1", "timer", "page2", "", "page3", "page4"])) + verify(compareObjectNames(control.contentChildren, ["page4", "page2", "page1", "page3"])) + + control.removeItem(control.itemAt(0)) + verify(compareObjectNames(control.contentData, ["object", "page1", "timer", "page2", "", "page3"])) + verify(compareObjectNames(control.contentChildren, ["page2", "page1", "page3"])) + } + + Component { + id: repeated + SwipeView { + property alias repeater: repeater + Repeater { + id: repeater + model: 5 + Item { property int idx: index } + } + } + } + + function test_repeater() { + var control = createTemporaryObject(repeated, testCase) + verify(control) + + var model = control.contentModel + verify(model) + + var repeater = control.repeater + verify(repeater) + + compare(repeater.count, 5) + compare(model.count, 5) + + for (var i = 0; i < 5; ++i) { + var item1 = control.itemAt(i) + verify(item1) + compare(item1.idx, i) + compare(model.get(i), item1) + compare(repeater.itemAt(i), item1) + } + + repeater.model = 3 + compare(repeater.count, 3) + compare(model.count, 3) + + for (var j = 0; j < 3; ++j) { + var item2 = control.itemAt(j) + verify(item2) + compare(item2.idx, j) + compare(model.get(j), item2) + compare(repeater.itemAt(j), item2) + } + } + + Component { + id: ordered + SwipeView { + id: oview + property alias repeater: repeater + Text { text: "static_1" } + Repeater { + id: repeater + model: 2 + Text { text: "repeated_" + (index + 2) } + } + Text { text: "static_4" } + Component.onCompleted: { + addItem(page.createObject(oview, {text: "dynamic_5"})) + addItem(page.createObject(oview.contentItem, {text: "dynamic_6"})) + insertItem(0, page.createObject(oview, {text: "dynamic_0"})) + } + } + } + + function test_order() { + var control = createTemporaryObject(ordered, testCase) + verify(control) + + compare(control.count, 7) + compare(control.itemAt(0).text, "dynamic_0") + compare(control.itemAt(1).text, "static_1") + compare(control.itemAt(2).text, "repeated_2") + compare(control.itemAt(3).text, "repeated_3") + compare(control.itemAt(4).text, "static_4") + compare(control.itemAt(5).text, "dynamic_5") + compare(control.itemAt(6).text, "dynamic_6") + } + + function test_move_data() { + return [ + {tag:"0->1 (0)", from: 0, to: 1, currentBefore: 0, currentAfter: 1}, + {tag:"0->1 (1)", from: 0, to: 1, currentBefore: 1, currentAfter: 0}, + {tag:"0->1 (2)", from: 0, to: 1, currentBefore: 2, currentAfter: 2}, + + {tag:"0->2 (0)", from: 0, to: 2, currentBefore: 0, currentAfter: 2}, + {tag:"0->2 (1)", from: 0, to: 2, currentBefore: 1, currentAfter: 0}, + {tag:"0->2 (2)", from: 0, to: 2, currentBefore: 2, currentAfter: 1}, + + {tag:"1->0 (0)", from: 1, to: 0, currentBefore: 0, currentAfter: 1}, + {tag:"1->0 (1)", from: 1, to: 0, currentBefore: 1, currentAfter: 0}, + {tag:"1->0 (2)", from: 1, to: 0, currentBefore: 2, currentAfter: 2}, + + {tag:"1->2 (0)", from: 1, to: 2, currentBefore: 0, currentAfter: 0}, + {tag:"1->2 (1)", from: 1, to: 2, currentBefore: 1, currentAfter: 2}, + {tag:"1->2 (2)", from: 1, to: 2, currentBefore: 2, currentAfter: 1}, + + {tag:"2->0 (0)", from: 2, to: 0, currentBefore: 0, currentAfter: 1}, + {tag:"2->0 (1)", from: 2, to: 0, currentBefore: 1, currentAfter: 2}, + {tag:"2->0 (2)", from: 2, to: 0, currentBefore: 2, currentAfter: 0}, + + {tag:"2->1 (0)", from: 2, to: 1, currentBefore: 0, currentAfter: 0}, + {tag:"2->1 (1)", from: 2, to: 1, currentBefore: 1, currentAfter: 2}, + {tag:"2->1 (2)", from: 2, to: 1, currentBefore: 2, currentAfter: 1}, + + {tag:"0->0", from: 0, to: 0, currentBefore: 0, currentAfter: 0}, + {tag:"-1->0", from: 0, to: 0, currentBefore: 1, currentAfter: 1}, + {tag:"0->-1", from: 0, to: 0, currentBefore: 2, currentAfter: 2}, + {tag:"1->10", from: 0, to: 0, currentBefore: 0, currentAfter: 0}, + {tag:"10->2", from: 0, to: 0, currentBefore: 1, currentAfter: 1}, + {tag:"10->-1", from: 0, to: 0, currentBefore: 2, currentAfter: 2} + ] + } + + Component { + id: pageAttached + + Text { + property int index: SwipeView.index + property SwipeView view: SwipeView.view + property bool isCurrentItem: SwipeView.isCurrentItem + property bool isNextItem: SwipeView.isNextItem + property bool isPreviousItem: SwipeView.isPreviousItem + } + } + + function test_move(data) { + var control = createTemporaryObject(swipeView, testCase) + + compare(control.count, 0) + var titles = ["1", "2", "3"] + + var i = 0; + for (i = 0; i < titles.length; ++i) { + var item = pageAttached.createObject(control, {text: titles[i]}) + control.addItem(item) + } + + compare(control.count, titles.length) + for (i = 0; i < control.count; ++i) { + compare(control.itemAt(i).text, titles[i]) + compare(control.itemAt(i).SwipeView.index, i) + compare(control.itemAt(i).SwipeView.isCurrentItem, i === 0) + compare(control.itemAt(i).SwipeView.isNextItem, i === 1) + compare(control.itemAt(i).SwipeView.isPreviousItem, false) + } + + control.currentIndex = data.currentBefore + for (i = 0; i < control.count; ++i) { + compare(control.itemAt(i).SwipeView.isCurrentItem, i === data.currentBefore) + compare(control.itemAt(i).SwipeView.isNextItem, i === data.currentBefore + 1) + compare(control.itemAt(i).SwipeView.isPreviousItem, i === data.currentBefore - 1) + } + + control.moveItem(data.from, data.to) + + compare(control.count, titles.length) + compare(control.currentIndex, data.currentAfter) + + var title = titles[data.from] + titles.splice(data.from, 1) + titles.splice(data.to, 0, title) + + compare(control.count, titles.length) + for (i = 0; i < control.count; ++i) { + compare(control.itemAt(i).text, titles[i]) + compare(control.itemAt(i).SwipeView.index, i); + compare(control.itemAt(i).SwipeView.isCurrentItem, i === data.currentAfter) + compare(control.itemAt(i).SwipeView.isNextItem, i === data.currentAfter + 1) + compare(control.itemAt(i).SwipeView.isPreviousItem, i === data.currentAfter - 1) + } + } + + Component { + id: dynamicView + SwipeView { + id: dview + Text { text: "static" } + Component.onCompleted: { + addItem(page.createObject(dview, {text: "added"})) + insertItem(0, page.createObject(dview, {text: "inserted"})) + page.createObject(dview, {text: "dynamic"}) + } + } + } + + function test_dynamic() { + var control = createTemporaryObject(dynamicView, testCase) + + // insertItem(), addItem(), createObject() and static page {} + compare(control.count, 4) + compare(control.itemAt(0).text, "inserted") + + var tab = page.createObject(control, {text: "dying"}) + compare(control.count, 5) + compare(control.itemAt(4).text, "dying") + + // TODO: fix crash in QQuickItemView +// tab.destroy() +// wait(0) +// compare(control.count, 4) + } + + function test_attachedParent() { + var control = createTemporaryObject(swipeView, testCase); + + var page = createTemporaryObject(pageAttached, testCase); + compare(page.view, null); + compare(page.index, -1); + compare(page.isCurrentItem, false); + compare(page.isNextItem, false); + compare(page.isPreviousItem, false); + page.destroy(); + + page = createTemporaryObject(pageAttached, null); + compare(page.view, null); + compare(page.index, -1); + compare(page.isCurrentItem, false); + compare(page.isNextItem, false); + compare(page.isPreviousItem, false); + + control.insertItem(0, page); + compare(control.count, 1); + compare(page.parent, control.contentItem.contentItem); + compare(page.view, control); + compare(page.index, 0); + compare(page.isCurrentItem, true); + compare(page.isNextItem, false); + compare(page.isPreviousItem, false); + + control.removeItem(control.itemAt(0)); + compare(control.count, 0); + compare(page.parent, null); + compare(page.view, null); + compare(page.index, -1); + compare(page.isCurrentItem, false); + compare(page.isNextItem, false); + compare(page.isPreviousItem, false); + } + + function test_orientation() { + var control = createTemporaryObject(swipeView, testCase, {width: 200, height: 200}) + verify(control) + + for (var i = 0; i < 3; ++i) + control.addItem(page.createObject(control, {text: i})) + + compare(control.orientation, Qt.Horizontal) + compare(control.horizontal, true) + compare(control.vertical, false) + + for (i = 0; i < control.count; ++i) { + control.currentIndex = i + compare(control.itemAt(i).y, 0) + } + + control.orientation = Qt.Vertical + compare(control.orientation, Qt.Vertical) + compare(control.horizontal, false) + compare(control.vertical, true) + + for (i = 0; i < control.count; ++i) { + control.currentIndex = i + compare(control.itemAt(i).x, 0) + } + } + + Component { + id: focusSwipeViewComponent + + SwipeView { + id: swipeView + anchors.fill: parent + focus: true + + property int pressCount + property int releaseCount + property int rectanglePressCount + property int rectangleReleaseCount + + Rectangle { + focus: true + + Keys.onPressed: ++swipeView.rectanglePressCount + Keys.onReleased: ++swipeView.rectangleReleaseCount + } + + Keys.onPressed: ++pressCount + Keys.onReleased: ++releaseCount + } + } + + function test_focus() { + if (Qt.styleHints.tabFocusBehavior !== Qt.TabFocusAllControls) + skip("This platform only allows tab focus for text controls") + + var control = createTemporaryObject(focusSwipeViewComponent, testCase) + verify(control) + compare(control.focus, true) + compare(control.contentItem.focus, true) + compare(control.itemAt(0).focus, true) + compare(control.itemAt(0).activeFocus, true) + + keyPress(Qt.Key_A) + compare(control.pressCount, 1) + compare(control.releaseCount, 0) + compare(control.rectanglePressCount, 1) + compare(control.rectangleReleaseCount, 0) + + keyRelease(Qt.Key_A) + compare(control.pressCount, 1) + compare(control.releaseCount, 1) + compare(control.rectanglePressCount, 1) + compare(control.rectangleReleaseCount, 1) + } + + // We have a particular customer who came up with this hack to make SwipeView wrap around at the end. + // It's not advisible, and perhaps the test can be removed when we add a bool wrap property. + Component { + id: pathViewWorkaroundComponent + + SwipeView { + id: swipeView + anchors.left: parent.left + width: 100 + height: 100 + clip: true + Repeater { + id: repeater + objectName: "peter" + delegate: Rectangle { + id: rect + color: "#ffff00" + border.color: "black" + width: 100 + height: 100 + Text { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: 24 + text: model.index + } + } + } + contentItem: PathView { + id: pathview + + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + model: swipeView.contentModel + + path: Path { + id: path + startX: (swipeView.width / 2 * -1) * (swipeView.count - 1) + startY: swipeView.height / 2 + PathLine { + relativeX: swipeView.width * swipeView.count + relativeY: 0 + } + } + } + } + } + + function test_child_pathview() { + const control = createTemporaryObject(pathViewWorkaroundComponent, testCase) + verify(control) + const repeater = control.children[0].children[0] + const spy = signalSpy.createObject(repeater, {target: repeater, signalName: "itemAdded"}) + repeater.model = 1 + tryCompare(spy, "count", 1) + const rect = repeater.itemAt(0) + tryCompare(rect, "visible", true) + if (Qt.platform.pluginName === "offscreen") + skip("grabImage() is not functional on the offscreen platform (QTBUG-63185)") + var image = grabImage(control) + compare(image.pixel(3, 3), "#ffff00") + } + + Component { + id: translucentPages + SwipeView { + spacing: 10 + leftPadding: 10 + topPadding: 10 + rightPadding: 10 + bottomPadding: 10 + Text { text: "page 0" } + Text { text: "page 1"; font.pointSize: 16 } + Text { text: "page 2"; font.pointSize: 24 } + Text { text: "page 3"; font.pointSize: 32 } + } + } + + function test_initialPositions() { // QTBUG-102487 + const control = createTemporaryObject(translucentPages, testCase, {width: 320, height: 200}) + verify(control) + compare(control.contentItem.width, control.width - control.leftPadding - control.rightPadding) + compare(control.spacing, 10) + + compare(control.orientation, Qt.Horizontal) + for (let i = 0; i < control.count; ++i) { + const page = control.itemAt(i) + compare(page.x, i * (control.contentItem.width + control.spacing)) + compare(page.y, 0) + compare(page.width, control.contentItem.width) + compare(page.height, control.contentItem.height) + } + control.orientation = Qt.Vertical + for (let i = 0; i < control.count; ++i) { + const page = control.itemAt(i) + compare(page.y, i * (control.contentItem.height + control.spacing)) + compare(page.x, 0) + compare(page.width, control.contentItem.width) + compare(page.height, control.contentItem.height) + } + + // QTBUG-115468: add a page after startup and check that that works too. + control.orientation = Qt.Horizontal + let page4 = page.createObject(control, { text: "page 4", "font.pointSize": 40 }) + control.insertItem(control.count, page4) + compare(page4.x, (control.count - 1) * 310) + compare(page4.y, 0) + compare(page4.width, control.contentItem.width) + compare(page4.height, control.contentItem.height) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_switch.qml b/tests/auto/quickcontrols2/controls/data/tst_switch.qml new file mode 100644 index 00000000000..68d9cd78a23 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_switch.qml @@ -0,0 +1,636 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "Switch" + + Component { + id: swtch + Switch { } + } + + Component { + id: signalSequenceSpy + SignalSequenceSpy { + signals: ["pressed", "released", "canceled", "clicked", "toggled", "pressedChanged", "checkedChanged"] + } + } + + function test_text() { + var control = createTemporaryObject(swtch, testCase) + verify(control) + + compare(control.text, "") + control.text = "Switch" + compare(control.text, "Switch") + control.text = "" + compare(control.text, "") + } + + function test_checked() { + var control = createTemporaryObject(swtch, testCase) + verify(control) + + compare(control.checked, false) + + var spy = signalSequenceSpy.createObject(control, {target: control}) + spy.expectedSequence = [["checkedChanged", { "checked": true }]] + control.checked = true + compare(control.checked, true) + verify(spy.success) + + spy.expectedSequence = [["checkedChanged", { "checked": false }]] + control.checked = false + compare(control.checked, false) + verify(spy.success) + } + + function test_pressed_data() { + return [ + { tag: "indicator", x: 15 }, + { tag: "background", x: 5 } + ] + } + + function test_pressed(data) { + var control = createTemporaryObject(swtch, testCase, {padding: 10}) + verify(control) + + // stays pressed when dragged outside + compare(control.pressed, false) + mousePress(control, data.x, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + mouseMove(control, -1, control.height / 2) + compare(control.pressed, true) + mouseRelease(control, -1, control.height / 2, Qt.LeftButton) + compare(control.pressed, false) + } + + function test_mouse() { + var control = createTemporaryObject(swtch, testCase) + verify(control) + + // check + var spy = signalSequenceSpy.createObject(control, {target: control}) + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // uncheck + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // release on the right + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + mouseMove(control, control.width * 2, control.height / 2, 0) + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width * 2, control.height / 2, Qt.LeftButton) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // release on the left + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + mouseMove(control, -control.width, control.height / 2, 0) + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + mouseRelease(control, -control.width, control.height / 2, Qt.LeftButton) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // release in the middle + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, 0, 0, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + mouseMove(control, control.width / 2, control.height / 2, 0, Qt.LeftButton) + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, false) + compare(control.pressed, false) + tryCompare(control, "position", 0) // QTBUG-57944 + verify(spy.success) + + // right button + spy.expectedSequence = [] + mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.pressed, false) + verify(spy.success) + mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + } + + function test_touch() { + var control = createTemporaryObject(swtch, testCase) + verify(control) + + var touch = touchEvent(control) + + // check + var spy = signalSequenceSpy.createObject(control, {target: control}) + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // uncheck + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // release on the right + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(spy.success) + touch.move(0, control, control.width * 2, control.height / 2).commit() + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width * 2, control.height / 2).commit() + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // release on the left + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(spy.success) + touch.move(0, control, -control.width, control.height / 2).commit() + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + touch.release(0, control, -control.width, control.height / 2).commit() + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // release in the middle + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + touch.press(0, control, 0, 0).commit() + compare(control.pressed, true) + verify(spy.success) + touch.move(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.checked, false) + compare(control.pressed, false) + tryCompare(control, "position", 0) // QTBUG-57944 + verify(spy.success) + } + + function test_mouseDrag() { + var control = createTemporaryObject(swtch, testCase, {leftPadding: 100, rightPadding: 100}) + verify(control) + + var spy = signalSequenceSpy.createObject(control, {target: control}) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + + // press-drag-release inside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control.indicator, 0) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control.indicator, control.width - 1) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + mouseRelease(control.indicator, control.indicator.width - 1) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, 0) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, true) + compare(control.pressed, true) + + mouseMove(control, control.leftPadding) + compare(control.position, 0.0) + compare(control.checked, true) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width - 1) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release from and to outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width - 1) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width - 1) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + } + + function test_touchDrag() { + var control = createTemporaryObject(swtch, testCase, {leftPadding: 100, rightPadding: 100}) + verify(control) + + var touch = touchEvent(control) + + var spy = signalSequenceSpy.createObject(control, {target: control}) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + + // press-drag-release inside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + touch.press(0, control.indicator, 0).commit() + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + touch.move(0, control.indicator, control.width).commit() + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + touch.release(0, control.indicator, control.indicator.width).commit() + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + touch.press(0, control, 0).commit() + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + verify(spy.success) + + touch.move(0, control, control.width - control.rightPadding).commit() + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + + touch.move(0, control, control.width / 2).commit() + compare(control.position, 0.5) + compare(control.checked, true) + compare(control.pressed, true) + + touch.move(0, control, control.leftPadding).commit() + compare(control.position, 0.0) + compare(control.checked, true) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width).commit() + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release from and to outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) + touch.press(0, control, control.width - 1).commit() + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + touch.move(0, control, control.width - control.rightPadding).commit() + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + + touch.move(0, control, control.width / 2).commit() + compare(control.position, 0.5) + compare(control.checked, false) + compare(control.pressed, true) + + touch.move(0, control, control.width - control.rightPadding).commit() + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width).commit() + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + } + + function test_keys() { + var control = createTemporaryObject(swtch, testCase) + verify(control) + + control.forceActiveFocus() + verify(control.activeFocus) + + // check + var spy = signalSequenceSpy.createObject(control, {target: control}) + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + keyClick(Qt.Key_Space) + compare(control.checked, true) + verify(spy.success) + + // uncheck + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed", + ["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + keyClick(Qt.Key_Space) + compare(control.checked, false) + verify(spy.success) + + // no change + spy.expectedSequence = [] + var keys = [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab] + for (var i = 0; i < keys.length; ++i) { + keyClick(keys[i]) + compare(control.checked, false) + verify(spy.success) + } + } + + Component { + id: twoSwitches + Item { + property Switch sw1: Switch { id: sw1 } + property Switch sw2: Switch { id: sw2; checked: sw1.checked; enabled: false } + } + } + + function test_binding() { + var container = createTemporaryObject(twoSwitches, testCase) + verify(container) + + compare(container.sw1.checked, false) + compare(container.sw2.checked, false) + + container.sw1.checked = true + compare(container.sw1.checked, true) + compare(container.sw2.checked, true) + + container.sw1.checked = false + compare(container.sw1.checked, false) + compare(container.sw2.checked, false) + } + + function test_baseline() { + var control = createTemporaryObject(swtch, testCase) + verify(control) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + } + + function test_focus() { + var control = createTemporaryObject(swtch, testCase) + verify(control) + + verify(!control.activeFocus) + mouseClick(control.indicator) + // should not get activeFocus on mouseClick on macOS + compare(control.activeFocus, Qt.platform.os !== "osx" && Qt.platform.os !== "macos") + } + + Component { + id: deletionOrder1 + Item { + Image { id: innerImage } + Switch { indicator: innerImage } + } + } + + Component { + id: deletionOrder2 + Item { + Switch { indicator: innerImage } + Image { id: innerImage } + } + } + + function test_deletionOrder() { + var control1 = createTemporaryObject(deletionOrder1, testCase) + verify(control1) + var control2 = createTemporaryObject(deletionOrder2, testCase) + verify(control2) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_switchdelegate.qml b/tests/auto/quickcontrols2/controls/data/tst_switchdelegate.qml new file mode 100644 index 00000000000..a1ff9f4a3e8 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_switchdelegate.qml @@ -0,0 +1,608 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "SwitchDelegate" + + Component { + id: switchDelegate + SwitchDelegate {} + } + + Component { + id: signalSequenceSpy + SignalSequenceSpy { + signals: ["pressed", "released", "canceled", "clicked", "toggled", "pressedChanged", "checkedChanged"] + } + } + + // TODO: data-fy tst_checkbox (rename to tst_check?) so we don't duplicate its tests here? + + function test_defaults() { + var control = createTemporaryObject(switchDelegate, testCase); + verify(control); + verify(!control.checked); + } + + function test_checked() { + var control = createTemporaryObject(switchDelegate, testCase); + verify(control); + + mouseClick(control); + verify(control.checked); + + mouseClick(control); + verify(!control.checked); + } + + function test_baseline() { + var control = createTemporaryObject(switchDelegate, testCase); + verify(control); + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset); + } + + function test_pressed_data() { + return [ + { tag: "indicator", x: 15 }, + { tag: "background", x: 5 } + ] + } + + function test_pressed(data) { + var control = createTemporaryObject(switchDelegate, testCase, {padding: 10}) + verify(control) + + // stays pressed when dragged outside + compare(control.pressed, false) + mousePress(control, data.x, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + mouseMove(control, -1, control.height / 2) + compare(control.pressed, true) + mouseRelease(control, -1, control.height / 2, Qt.LeftButton) + compare(control.pressed, false) + } + + function test_mouse() { + var control = createTemporaryObject(switchDelegate, testCase) + verify(control) + + // check + var spy = signalSequenceSpy.createObject(control, {target: control}) + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // uncheck + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // release on the right + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + mouseMove(control, control.width * 2, control.height / 2, 0) + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width * 2, control.height / 2, Qt.LeftButton) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // release on the left + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + mouseMove(control, -control.width, control.height / 2, 0) + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + mouseRelease(control, -control.width, control.height / 2, Qt.LeftButton) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // release in the middle + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, 0, 0, Qt.LeftButton) + compare(control.pressed, true) + verify(spy.success) + mouseMove(control, control.width / 2, control.height / 2, 0, Qt.LeftButton) + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(control.checked, false) + compare(control.pressed, false) + tryCompare(control, "position", 0) // QTBUG-57944 + verify(spy.success) + + // right button + spy.expectedSequence = [] + mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.pressed, false) + verify(spy.success) + mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + } + + function test_touch() { + var control = createTemporaryObject(switchDelegate, testCase) + verify(control) + + var touch = touchEvent(control) + + // check + var spy = signalSequenceSpy.createObject(control, {target: control}) + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // uncheck + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(spy.success) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // release on the right + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(spy.success) + touch.move(0, control, control.width * 2, control.height / 2).commit() + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width * 2, control.height / 2).commit() + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // release on the left + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + touch.press(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + verify(spy.success) + touch.move(0, control, -control.width, control.height / 2).commit() + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + touch.release(0, control, -control.width, control.height / 2).commit() + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // release in the middle + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + touch.press(0, control, 0, 0).commit() + compare(control.pressed, true) + verify(spy.success) + touch.move(0, control, control.width / 2, control.height / 2).commit() + compare(control.pressed, true) + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + "released", + "clicked"] + touch.release(0, control, control.width / 2, control.height / 2).commit() + compare(control.checked, false) + compare(control.pressed, false) + tryCompare(control, "position", 0) // QTBUG-57944 + verify(spy.success) + } + + function test_mouseDrag() { + var control = createTemporaryObject(switchDelegate, testCase, {leftPadding: 100, rightPadding: 100}) + verify(control) + + var spy = signalSequenceSpy.createObject(control, {target: control}) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + + // press-drag-release inside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control.indicator, 0) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control.indicator, control.width) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + mouseRelease(control.indicator, control.indicator.width) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + mousePress(control, 0) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, true) + compare(control.pressed, true) + + mouseMove(control, control.leftPadding) + compare(control.position, 0.0) + compare(control.checked, true) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release from and to outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + mousePress(control, control.width - 1) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width / 2) + compare(control.position, 0.5) + compare(control.checked, false) + compare(control.pressed, true) + + mouseMove(control, control.width - control.rightPadding) + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + mouseRelease(control, control.width) + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + } + + function test_touchDrag() { + var control = createTemporaryObject(switchDelegate, testCase, {leftPadding: 100, rightPadding: 100}) + verify(control) + + var touch = touchEvent(control) + + var spy = signalSequenceSpy.createObject(control, {target: control}) + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + + // press-drag-release inside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + touch.press(0, control.indicator, 0).commit() + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + touch.move(0, control.indicator, control.width).commit() + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + touch.release(0, control.indicator, control.indicator.width).commit() + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": true }], + "pressed"] + touch.press(0, control, 0).commit() + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + verify(spy.success) + + touch.move(0, control, control.width - control.rightPadding).commit() + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, true) + + touch.move(0, control, control.width / 2).commit() + compare(control.position, 0.5) + compare(control.checked, true) + compare(control.pressed, true) + + touch.move(0, control, control.leftPadding).commit() + compare(control.position, 0.0) + compare(control.checked, true) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": true }], + ["checkedChanged", { "pressed": false, "checked": false }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width).commit() + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, false) + verify(spy.success) + + // press-drag-release from and to outside the indicator + spy.expectedSequence = [["pressedChanged", { "pressed": true, "checked": false }], + "pressed"] + wait(Qt.styleHints.mouseDoubleClickInterval + 50) + touch.press(0, control, control.width - 1).commit() + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + verify(spy.success) + + touch.move(0, control, control.width - control.rightPadding).commit() + compare(control.position, 0.0) + compare(control.checked, false) + compare(control.pressed, true) + + touch.move(0, control, control.width / 2).commit() + compare(control.position, 0.5) + compare(control.checked, false) + compare(control.pressed, true) + + touch.move(0, control, control.width - control.rightPadding).commit() + compare(control.position, 1.0) + compare(control.checked, false) + compare(control.pressed, true) + + spy.expectedSequence = [["pressedChanged", { "pressed": false, "checked": false }], + ["checkedChanged", { "pressed": false, "checked": true }], + "toggled", + "released", + "clicked"] + touch.release(0, control, control.width).commit() + compare(control.position, 1.0) + compare(control.checked, true) + compare(control.pressed, false) + verify(spy.success) + } + + function test_spacing() { + var control = createTemporaryObject(switchDelegate, testCase, { text: "Some long, long, long text" }) + verify(control) + verify(control.contentItem.implicitWidth + control.leftPadding + control.rightPadding > control.background.implicitWidth) + + var textLabel = findChild(control.contentItem, "label") + verify(textLabel) + + // The implicitWidth of the IconLabel that all buttons use as their contentItem should be + // equal to the implicitWidth of the Text and the switch indicator + spacing while no icon is set. + compare(control.contentItem.implicitWidth, textLabel.implicitWidth + control.indicator.width + control.spacing) + + control.spacing += 100 + compare(control.contentItem.implicitWidth, textLabel.implicitWidth + control.indicator.width + control.spacing) + + compare(control.implicitWidth, textLabel.implicitWidth + control.indicator.width + control.spacing + control.leftPadding + control.rightPadding) + } + + function test_display_data() { + return [ + { "tag": "IconOnly", display: SwitchDelegate.IconOnly }, + { "tag": "TextOnly", display: SwitchDelegate.TextOnly }, + { "tag": "TextUnderIcon", display: SwitchDelegate.TextUnderIcon }, + { "tag": "TextBesideIcon", display: SwitchDelegate.TextBesideIcon }, + { "tag": "IconOnly, mirrored", display: SwitchDelegate.IconOnly, mirrored: true }, + { "tag": "TextOnly, mirrored", display: SwitchDelegate.TextOnly, mirrored: true }, + { "tag": "TextUnderIcon, mirrored", display: SwitchDelegate.TextUnderIcon, mirrored: true }, + { "tag": "TextBesideIcon, mirrored", display: SwitchDelegate.TextBesideIcon, mirrored: true } + ] + } + + function test_display(data) { + var control = createTemporaryObject(switchDelegate, testCase, { + text: "SwitchDelegate", + display: data.display, + width: 400, + "icon.source": "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png", + "LayoutMirroring.enabled": !!data.mirrored + }) + verify(control) + compare(control.icon.source, "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png") + + var iconImage = findChild(control.contentItem, "image") + var textLabel = findChild(control.contentItem, "label") + + var availableWidth = control.availableWidth - control.indicator.width - control.spacing + var indicatorOffset = control.mirrored ? control.indicator.width + control.spacing : 0 + + switch (control.display) { + case SwitchDelegate.IconOnly: + verify(iconImage) + verify(!textLabel) + compare(iconImage.x, indicatorOffset + (availableWidth - iconImage.width) / 2) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + break; + case SwitchDelegate.TextOnly: + verify(!iconImage) + verify(textLabel) + compare(textLabel.x, control.mirrored ? control.availableWidth - textLabel.width : 0) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + case SwitchDelegate.TextUnderIcon: + verify(iconImage) + verify(textLabel) + compare(iconImage.x, indicatorOffset + (availableWidth - iconImage.width) / 2) + compare(textLabel.x, indicatorOffset + (availableWidth - textLabel.width) / 2) + verify(iconImage.y < textLabel.y) + break; + case SwitchDelegate.TextBesideIcon: + verify(iconImage) + verify(textLabel) + if (control.mirrored) + verify(textLabel.x < iconImage.x) + else + verify(iconImage.x < textLabel.x) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + } + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_tabbar.qml b/tests/auto/quickcontrols2/controls/data/tst_tabbar.qml new file mode 100644 index 00000000000..500340c57a8 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_tabbar.qml @@ -0,0 +1,775 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "TabBar" + + Component { + id: tabButton + TabButton { } + } + + Component { + id: tabBar + TabBar { } + } + + Component { + id: tabBarStaticTabs + TabBar { + TabButton { + text: "0" + } + TabButton { + text: "1" + } + } + } + + Component { + id: tabBarStaticTabsCurrent + TabBar { + currentIndex: 1 + TabButton { + text: "0" + } + TabButton { + text: "1" + } + } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_defaults() { + var control = createTemporaryObject(tabBar, testCase) + verify(control) + compare(control.count, 0) + compare(control.currentIndex, -1) + compare(control.currentItem, null) + } + + function test_current() { + var control = createTemporaryObject(tabBar, testCase) + + compare(control.count, 0) + compare(control.currentIndex, -1) + compare(control.currentItem, null) + + control.addItem(tabButton.createObject(control, {text: "0"})) + compare(control.count, 1) + compare(control.currentIndex, 0) + compare(control.currentItem.text, "0") + compare(control.currentItem.checked, true) + + control.addItem(tabButton.createObject(control, {text: "1"})) + compare(control.count, 2) + compare(control.currentIndex, 0) + compare(control.currentItem.text, "0") + compare(control.currentItem.checked, true) + + control.addItem(tabButton.createObject(control, {text: "2"})) + compare(control.count, 3) + compare(control.currentIndex, 0) + compare(control.currentItem.text, "0") + compare(control.currentItem.checked, true) + + control.currentIndex = 1 + compare(control.currentIndex, 1) + compare(control.currentItem.text, "1") + compare(control.currentItem.checked, true) + + control.currentIndex = 2 + compare(control.currentIndex, 2) + compare(control.currentItem.text, "2") + compare(control.currentItem.checked, true) + + control.decrementCurrentIndex() + compare(control.currentIndex, 1) + compare(control.currentItem.text, "1") + compare(control.currentItem.checked, true) + + control.incrementCurrentIndex() + compare(control.currentIndex, 2) + compare(control.currentItem.text, "2") + compare(control.currentItem.checked, true) + } + + function test_current_static() { + var control = createTemporaryObject(tabBarStaticTabs, testCase) + + compare(control.count, 2) + compare(control.currentIndex, 0) + compare(control.currentItem.text, "0") + compare(control.currentItem.checked, true) + + control = createTemporaryObject(tabBarStaticTabsCurrent, testCase) + + compare(control.count, 2) + compare(control.currentIndex, 1) + compare(control.currentItem.text, "1") + compare(control.currentItem.checked, true) + } + + function test_addRemove() { + var control = createTemporaryObject(tabBar, testCase) + + function verifyCurrentIndexCountDiff() { + verify(control.currentIndex < control.count) + } + control.currentIndexChanged.connect(verifyCurrentIndexCountDiff) + control.countChanged.connect(verifyCurrentIndexCountDiff) + + var contentChildrenSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "contentChildrenChanged"}) + verify(contentChildrenSpy.valid) + + compare(control.count, 0) + compare(control.currentIndex, -1) + control.addItem(tabButton.createObject(control, {text: "1"})) + compare(control.count, 1) + compare(control.currentIndex, 0) + compare(control.currentItem.text, "1") + compare(contentChildrenSpy.count, 1) + + control.addItem(tabButton.createObject(control, {text: "2"})) + compare(control.count, 2) + compare(control.currentIndex, 0) + compare(control.currentItem.text, "1") + compare(control.itemAt(0).text, "1") + compare(control.itemAt(1).text, "2") + compare(contentChildrenSpy.count, 2) + + control.currentIndex = 1 + + control.insertItem(1, tabButton.createObject(control, {text: "3"})) + compare(control.count, 3) + compare(control.currentIndex, 2) + compare(control.currentItem.text, "2") + compare(control.itemAt(0).text, "1") + compare(control.itemAt(1).text, "3") + compare(control.itemAt(2).text, "2") + compare(contentChildrenSpy.count, 4) // append + insert->move + + control.insertItem(0, tabButton.createObject(control, {text: "4"})) + compare(control.count, 4) + compare(control.currentIndex, 3) + compare(control.currentItem.text, "2") + compare(control.itemAt(0).text, "4") + compare(control.itemAt(1).text, "1") + compare(control.itemAt(2).text, "3") + compare(control.itemAt(3).text, "2") + compare(contentChildrenSpy.count, 6) // append + insert->move + + control.insertItem(control.count, tabButton.createObject(control, {text: "5"})) + compare(control.count, 5) + compare(control.currentIndex, 3) + compare(control.currentItem.text, "2") + compare(control.itemAt(0).text, "4") + compare(control.itemAt(1).text, "1") + compare(control.itemAt(2).text, "3") + compare(control.itemAt(3).text, "2") + compare(control.itemAt(4).text, "5") + compare(contentChildrenSpy.count, 7) + + control.removeItem(control.itemAt(control.count - 1)) + compare(control.count, 4) + compare(control.currentIndex, 3) + compare(control.currentItem.text, "2") + compare(control.itemAt(0).text, "4") + compare(control.itemAt(1).text, "1") + compare(control.itemAt(2).text, "3") + compare(control.itemAt(3).text, "2") + compare(contentChildrenSpy.count, 8) + + control.removeItem(control.itemAt(0)) + compare(control.count, 3) + compare(control.currentIndex, 2) + compare(control.currentItem.text, "2") + compare(control.itemAt(0).text, "1") + compare(control.itemAt(1).text, "3") + compare(control.itemAt(2).text, "2") + compare(contentChildrenSpy.count, 9) + + control.removeItem(control.itemAt(1)) + compare(control.count, 2) + compare(control.currentIndex, 1) + compare(control.currentItem.text, "2") + compare(control.itemAt(0).text, "1") + compare(control.itemAt(1).text, "2") + compare(contentChildrenSpy.count, 10) + + control.removeItem(control.itemAt(1)) + compare(control.count, 1) + compare(control.currentIndex, 0) + compare(control.currentItem.text, "1") + compare(control.itemAt(0).text, "1") + compare(contentChildrenSpy.count, 11) + + control.removeItem(control.itemAt(0)) + compare(control.count, 0) + compare(control.currentIndex, -1) + compare(contentChildrenSpy.count, 12) + } + + function test_removeCurrent() { + var control = createTemporaryObject(tabBar, testCase) + + control.addItem(tabButton.createObject(control, {text: "1"})) + control.addItem(tabButton.createObject(control, {text: "2"})) + control.addItem(tabButton.createObject(control, {text: "3"})) + control.currentIndex = 1 + compare(control.count, 3) + compare(control.currentIndex, 1) + + control.removeItem(control.itemAt(1)) + compare(control.count, 2) + compare(control.currentIndex, 0) + + control.removeItem(control.itemAt(0)) + compare(control.count, 1) + compare(control.currentIndex, 0) + + control.removeItem(control.itemAt(0)) + compare(control.count, 0) + compare(control.currentIndex, -1) + } + + Component { + id: contentBar + TabBar { + QtObject { objectName: "object" } + TabButton { objectName: "button1" } + Timer { objectName: "timer" } + TabButton { objectName: "button2" } + Component { TabButton { } } + } + } + + function test_content() { + var control = createTemporaryObject(contentBar, testCase) + + function compareObjectNames(content, names) { + if (content.length !== names.length) + return false + for (var i = 0; i < names.length; ++i) { + if (content[i].objectName !== names[i]) + return false + } + return true + } + + var contentChildrenSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "contentChildrenChanged"}) + verify(contentChildrenSpy.valid) + + verify(compareObjectNames(control.contentData, ["object", "button1", "timer", "button2", ""])) + verify(compareObjectNames(control.contentChildren, ["button1", "button2"])) + + control.addItem(tabButton.createObject(control, {objectName: "button3"})) + verify(compareObjectNames(control.contentData, ["object", "button1", "timer", "button2", "", "button3"])) + verify(compareObjectNames(control.contentChildren, ["button1", "button2", "button3"])) + compare(contentChildrenSpy.count, 1) + + control.insertItem(0, tabButton.createObject(control, {objectName: "button4"})) + verify(compareObjectNames(control.contentData, ["object", "button1", "timer", "button2", "", "button3", "button4"])) + verify(compareObjectNames(control.contentChildren, ["button4", "button1", "button2", "button3"])) + compare(contentChildrenSpy.count, 3) // append + insert->move + + control.moveItem(1, 2) + verify(compareObjectNames(control.contentData, ["object", "button1", "timer", "button2", "", "button3", "button4"])) + verify(compareObjectNames(control.contentChildren, ["button4", "button2", "button1", "button3"])) + compare(contentChildrenSpy.count, 4) + + control.removeItem(control.itemAt(0)) + verify(compareObjectNames(control.contentData, ["object", "button1", "timer", "button2", "", "button3"])) + verify(compareObjectNames(control.contentChildren, ["button2", "button1", "button3"])) + compare(contentChildrenSpy.count, 5) + } + + Component { + id: repeated + TabBar { + property alias repeater: repeater + Repeater { + id: repeater + model: 5 + TabButton { property int idx: index } + } + } + } + + function test_repeater() { + var control = createTemporaryObject(repeated, testCase) + verify(control) + + var model = control.contentModel + verify(model) + + var repeater = control.repeater + verify(repeater) + + compare(repeater.count, 5) + compare(model.count, 5) + + for (var i = 0; i < 5; ++i) { + var item1 = control.itemAt(i) + verify(item1) + compare(item1.idx, i) + compare(model.get(i), item1) + compare(repeater.itemAt(i), item1) + } + + repeater.model = 3 + compare(repeater.count, 3) + compare(model.count, 3) + + for (var j = 0; j < 3; ++j) { + var item2 = control.itemAt(j) + verify(item2) + compare(item2.idx, j) + compare(model.get(j), item2) + compare(repeater.itemAt(j), item2) + } + } + + Component { + id: ordered + TabBar { + id: obar + property alias repeater: repeater + TabButton { text: "static_1" } + Repeater { + id: repeater + model: 2 + TabButton { text: "repeated_" + (index + 2) } + } + TabButton { text: "static_4" } + Component.onCompleted: { + addItem(tabButton.createObject(obar, {text: "dynamic_5"})) + addItem(tabButton.createObject(obar.contentItem, {text: "dynamic_6"})) + insertItem(0, tabButton.createObject(obar, {text: "dynamic_0"})) + } + } + } + + function test_order() { + var control = createTemporaryObject(ordered, testCase) + verify(control) + + compare(control.count, 7) + compare(control.itemAt(0).text, "dynamic_0") + compare(control.itemAt(1).text, "static_1") + compare(control.itemAt(2).text, "repeated_2") + compare(control.itemAt(3).text, "repeated_3") + compare(control.itemAt(4).text, "static_4") + compare(control.itemAt(5).text, "dynamic_5") + compare(control.itemAt(6).text, "dynamic_6") + } + + function test_move_data() { + return [ + {tag:"0->1 (0)", from: 0, to: 1, currentBefore: 0, currentAfter: 1}, + {tag:"0->1 (1)", from: 0, to: 1, currentBefore: 1, currentAfter: 0}, + {tag:"0->1 (2)", from: 0, to: 1, currentBefore: 2, currentAfter: 2}, + + {tag:"0->2 (0)", from: 0, to: 2, currentBefore: 0, currentAfter: 2}, + {tag:"0->2 (1)", from: 0, to: 2, currentBefore: 1, currentAfter: 0}, + {tag:"0->2 (2)", from: 0, to: 2, currentBefore: 2, currentAfter: 1}, + + {tag:"1->0 (0)", from: 1, to: 0, currentBefore: 0, currentAfter: 1}, + {tag:"1->0 (1)", from: 1, to: 0, currentBefore: 1, currentAfter: 0}, + {tag:"1->0 (2)", from: 1, to: 0, currentBefore: 2, currentAfter: 2}, + + {tag:"1->2 (0)", from: 1, to: 2, currentBefore: 0, currentAfter: 0}, + {tag:"1->2 (1)", from: 1, to: 2, currentBefore: 1, currentAfter: 2}, + {tag:"1->2 (2)", from: 1, to: 2, currentBefore: 2, currentAfter: 1}, + + {tag:"2->0 (0)", from: 2, to: 0, currentBefore: 0, currentAfter: 1}, + {tag:"2->0 (1)", from: 2, to: 0, currentBefore: 1, currentAfter: 2}, + {tag:"2->0 (2)", from: 2, to: 0, currentBefore: 2, currentAfter: 0}, + + {tag:"2->1 (0)", from: 2, to: 1, currentBefore: 0, currentAfter: 0}, + {tag:"2->1 (1)", from: 2, to: 1, currentBefore: 1, currentAfter: 2}, + {tag:"2->1 (2)", from: 2, to: 1, currentBefore: 2, currentAfter: 1}, + + {tag:"0->0", from: 0, to: 0, currentBefore: 0, currentAfter: 0}, + {tag:"-1->0", from: 0, to: 0, currentBefore: 1, currentAfter: 1}, + {tag:"0->-1", from: 0, to: 0, currentBefore: 2, currentAfter: 2}, + {tag:"1->10", from: 0, to: 0, currentBefore: 0, currentAfter: 0}, + {tag:"10->2", from: 0, to: 0, currentBefore: 1, currentAfter: 1}, + {tag:"10->-1", from: 0, to: 0, currentBefore: 2, currentAfter: 2} + ] + } + + function test_move(data) { + var control = createTemporaryObject(tabBar, testCase) + + compare(control.count, 0) + var titles = ["1", "2", "3"] + + var i = 0; + for (i = 0; i < titles.length; ++i) + control.addItem(tabButton.createObject(control, {text: titles[i]})) + + compare(control.count, titles.length) + for (i = 0; i < control.count; ++i) + compare(control.itemAt(i).text, titles[i]) + + control.currentIndex = data.currentBefore + control.moveItem(data.from, data.to) + + compare(control.count, titles.length) + compare(control.currentIndex, data.currentAfter) + + var title = titles[data.from] + titles.splice(data.from, 1) + titles.splice(data.to, 0, title) + + compare(control.count, titles.length) + for (i = 0; i < control.count; ++i) + compare(control.itemAt(i).text, titles[i]) + } + + Component { + id: dynamicBar + TabBar { + id: dbar + TabButton { text: "static" } + Component.onCompleted: { + addItem(tabButton.createObject(dbar, {text: "added"})) + insertItem(0, tabButton.createObject(dbar, {text: "inserted"})) + tabButton.createObject(dbar, {text: "dynamic"}) + } + } + } + + function test_dynamic() { + var control = createTemporaryObject(dynamicBar, testCase) + + // insertItem(), addItem(), createObject() and static TabButton {} + compare(control.count, 4) + compare(control.itemAt(0).text, "inserted") + + var tab = tabButton.createObject(control, {text: "dying"}) + compare(control.count, 5) + compare(control.itemAt(4).text, "dying") + + // TODO: fix crash in QQuickItemView +// tab.destroy() +// wait(0) +// compare(control.count, 4) + } + + function test_layout_data() { + return [ + { tag: "spacing:0", spacing: 0 }, + { tag: "spacing:1", spacing: 1 }, + { tag: "spacing:10", spacing: 10 }, + ] + } + + function test_layout(data) { + var control = createTemporaryObject(tabBar, testCase, {spacing: data.spacing, width: 200}) + + // remove the background so that it won't affect the implicit size of the tabbar, + // so the implicit sizes tested below are entirely based on the content size + control.background = null + + var tab1 = tabButton.createObject(control, {text: "First"}) + control.addItem(tab1) + tryCompare(tab1, "width", control.width) + compare(tab1.height, control.height) + compare(control.implicitContentWidth, tab1.implicitWidth) + compare(control.implicitContentHeight, tab1.implicitHeight) + compare(control.contentWidth, control.implicitContentWidth) + compare(control.contentHeight, control.implicitContentHeight) + compare(control.implicitWidth, control.contentWidth + control.leftPadding + control.rightPadding) + compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding) + + var tab2 = tabButton.createObject(control, {implicitHeight: tab1.implicitHeight + 10, text: "Second"}) + control.addItem(tab2) + tryCompare(tab1, "width", (control.width - data.spacing) / 2) + compare(tab1.height, control.height) + compare(tab2.width, (control.width - data.spacing) / 2) + compare(tab2.height, control.height) + compare(control.implicitContentWidth, tab1.implicitWidth + tab2.implicitWidth + data.spacing) + compare(control.implicitContentHeight, tab2.implicitHeight) + compare(control.contentWidth, control.implicitContentWidth) + compare(control.contentHeight, control.implicitContentHeight) + compare(control.implicitWidth, control.contentWidth + control.leftPadding + control.rightPadding) + compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding) + + var tab3 = tabButton.createObject(control, {width: 50, height: tab1.implicitHeight - 10, text: "Third"}) + control.addItem(tab3) + tryCompare(tab1, "width", (control.width - 2 * data.spacing - 50) / 2) + compare(tab1.y, 0) + compare(tab1.height, control.height) + compare(tab2.y, 0) + compare(tab2.width, (control.width - 2 * data.spacing - 50) / 2) + compare(tab2.height, control.height) + verify(tab3.y > 0) + compare(tab3.y, (control.height - tab3.height) / 2) + compare(tab3.width, 50) + compare(tab3.height, tab1.implicitHeight - 10) + compare(control.implicitContentWidth, tab1.implicitWidth + tab2.implicitWidth + tab3.width + 2 * data.spacing) + compare(control.implicitContentHeight, tab2.implicitHeight) + compare(control.contentWidth, control.implicitContentWidth) + compare(control.contentHeight, control.implicitContentHeight) + compare(control.implicitWidth, control.contentWidth + control.leftPadding + control.rightPadding) + compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding) + + var expectedWidth = tab3.contentItem.implicitWidth + tab3.leftPadding + tab3.rightPadding + tab3.width = tab3.implicitWidth + tab3.height = tab3.implicitHeight + tryCompare(tab1, "width", (control.width - 2 * data.spacing - expectedWidth) / 2) + compare(tab1.height, control.height) + compare(tab2.width, (control.width - 2 * data.spacing - expectedWidth) / 2) + compare(tab2.height, control.height) + compare(tab3.width, expectedWidth) + compare(tab3.height, tab3.implicitHeight) + compare(control.implicitContentWidth, tab1.implicitWidth + tab2.implicitWidth + tab3.implicitWidth + 2 * data.spacing) + compare(control.implicitContentHeight, tab2.implicitHeight) + compare(control.contentWidth, control.implicitContentWidth) + compare(control.contentHeight, control.implicitContentHeight) + compare(control.implicitWidth, control.contentWidth + control.leftPadding + control.rightPadding) + compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding) + + tab3.width = undefined + tab3.height = undefined + control.width = undefined + + control.contentWidth = 300 + control.contentHeight = 50 + expectedWidth = (control.contentWidth - 2 * data.spacing) / 3 + tryCompare(tab1, "width", expectedWidth) + compare(tab2.width, expectedWidth) + compare(tab3.width, expectedWidth) + compare(tab1.height, control.contentHeight) + compare(tab2.height, control.contentHeight) + compare(tab3.height, control.contentHeight) + } + + Component { + id: wheelEnabledTabBar + TabBar { + wheelEnabled: true + TabButton { text: "tab1" } + TabButton { text: "tab2" } + } + } + + function test_wheelEnabled() { + let control = createTemporaryObject(wheelEnabledTabBar, testCase, {width: 100, height: 100}) + verify(control) + + let deltas = [ + 120, // common mouse wheel + 16 // high resolution mouse wheel + ] + + for (let delta of deltas) { + // increment + for (let accumulated = 0; accumulated < 120; accumulated += delta) { + // ensure index doesn't change until threshold is reached + compare(control.currentIndex, 0) + mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta) + } + compare(control.currentIndex, 1) + + // reached bounds -> no change + for (let accumulated = 0; accumulated < 120; accumulated += delta) { + mouseWheel(control, control.width / 2, control.height / 2, -delta, -delta) + } + compare(control.currentIndex, 1) + + // decrement + for (let accumulated = 0; accumulated < 120; accumulated += delta) { + // ensure index doesn't change until threshold is reached + compare(control.currentIndex, 1) + mouseWheel(control, control.width / 2, control.height / 2, delta, delta) + } + compare(control.currentIndex, 0) + + // reached bounds -> no change + for (let accumulated = 0; accumulated < 120; accumulated += delta) { + mouseWheel(control, control.width / 2, control.height / 2, delta, delta) + } + compare(control.currentIndex, 0) + } + } + + Component { + id: attachedButton + TabButton { + property int index: TabBar.index + property TabBar tabBar: TabBar.tabBar + property int position: TabBar.position + } + } + + function test_attached() { + var control = createTemporaryObject(tabBar, testCase, {position: TabBar.Footer}) + + // append + var tab1 = createTemporaryObject(attachedButton, testCase) + compare(tab1.index, -1) + compare(tab1.tabBar, null) + compare(tab1.position, TabBar.Header) + + control.addItem(tab1) + compare(tab1.index, 0) + compare(tab1.tabBar, control) + compare(tab1.position, TabBar.Footer) + + // insert in the beginning + var tab2 = createTemporaryObject(attachedButton, testCase) + compare(tab2.index, -1) + compare(tab2.tabBar, null) + compare(tab2.position, TabBar.Header) + + control.insertItem(0, tab2) + compare(tab2.index, 0) + compare(tab2.tabBar, control) + compare(tab2.position, TabBar.Footer) + + compare(tab1.index, 1) + + // insert in the middle + var tab3 = createTemporaryObject(attachedButton, testCase) + compare(tab3.index, -1) + compare(tab3.tabBar, null) + compare(tab3.position, TabBar.Header) + + control.insertItem(1, tab3) + compare(tab3.index, 1) + compare(tab3.tabBar, control) + compare(tab3.position, TabBar.Footer) + + compare(tab2.index, 0) + compare(tab1.index, 2) + + // insert in the end + var tab4 = createTemporaryObject(attachedButton, testCase) + compare(tab4.index, -1) + compare(tab4.tabBar, null) + compare(tab4.position, TabBar.Header) + + control.insertItem(-1, tab4) + compare(tab4.index, 3) + compare(tab4.tabBar, control) + compare(tab4.position, TabBar.Footer) + + compare(tab2.index, 0) + compare(tab3.index, 1) + compare(tab1.index, 2) + + // move forwards + control.moveItem(0, 1) + compare(tab3.index, 0) + compare(tab2.index, 1) + compare(tab1.index, 2) + compare(tab4.index, 3) + + control.moveItem(0, 2) + compare(tab2.index, 0) + compare(tab1.index, 1) + compare(tab3.index, 2) + compare(tab4.index, 3) + + control.moveItem(1, 3) + compare(tab2.index, 0) + compare(tab3.index, 1) + compare(tab4.index, 2) + compare(tab1.index, 3) + + // move backwards + control.moveItem(3, 2) + compare(tab2.index, 0) + compare(tab3.index, 1) + compare(tab1.index, 2) + compare(tab4.index, 3) + + control.moveItem(3, 1) + compare(tab2.index, 0) + compare(tab4.index, 1) + compare(tab3.index, 2) + compare(tab1.index, 3) + + // remove from the beginning + control.removeItem(control.itemAt(0)) + compare(tab2.index, -1) + compare(tab2.tabBar, null) + compare(tab2.position, TabBar.Header) + + compare(tab4.index, 0) + compare(tab3.index, 1) + compare(tab1.index, 2) + + // remove from the middle + control.removeItem(control.itemAt(1)) + compare(tab3.index, -1) + compare(tab3.tabBar, null) + compare(tab3.position, TabBar.Header) + + compare(tab4.index, 0) + compare(tab1.index, 1) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_tabbutton.qml b/tests/auto/quickcontrols2/controls/data/tst_tabbutton.qml new file mode 100644 index 00000000000..3f8092099b8 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_tabbutton.qml @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "TabButton" + + Component { + id: tabButton + TabButton { } + } + + Component { + id: repeater + Column { + Repeater { + model: 3 + delegate: TabButton { } + } + } + } + + function test_autoExclusive() { + var container = createTemporaryObject(repeater, testCase) + + for (var i = 0; i < 3; ++i) { + container.children[i].checked = true + compare(container.children[i].checked, true) + + // check that all other buttons are unchecked + for (var j = 0; j < 3; ++j) { + if (j !== i) + compare(container.children[j].checked, false) + } + } + } + + function test_baseline() { + var control = createTemporaryObject(tabButton, testCase) + verify(control) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + } + + function test_spacing() { + var control = createTemporaryObject(tabButton, testCase, { text: "Some long, long, long text" }) + verify(control) + if (control.background) + verify(control.contentItem.implicitWidth + control.leftPadding + control.rightPadding > control.background.implicitWidth) + + var textLabel = findChild(control.contentItem, "label") + verify(textLabel) + + // The implicitWidth of the IconLabel that all buttons use as their contentItem + // should be equal to the implicitWidth of the Text while no icon is set. + compare(control.contentItem.implicitWidth, textLabel.implicitWidth) + + // That means that spacing shouldn't affect it. + control.spacing += 100 + compare(control.contentItem.implicitWidth, textLabel.implicitWidth) + + // The implicitWidth of the TabButton itself should, therefore, also never include spacing while no icon is set. + compare(control.implicitWidth, textLabel.implicitWidth + control.leftPadding + control.rightPadding) + } + + function test_display_data() { + return [ + { "tag": "IconOnly", display: TabButton.IconOnly }, + { "tag": "TextOnly", display: TabButton.TextOnly }, + { "tag": "TextUnderIcon", display: TabButton.TextUnderIcon }, + { "tag": "TextBesideIcon", display: TabButton.TextBesideIcon }, + { "tag": "IconOnly, mirrored", display: TabButton.IconOnly, mirrored: true }, + { "tag": "TextOnly, mirrored", display: TabButton.TextOnly, mirrored: true }, + { "tag": "TextUnderIcon, mirrored", display: TabButton.TextUnderIcon, mirrored: true }, + { "tag": "TextBesideIcon, mirrored", display: TabButton.TextBesideIcon, mirrored: true } + ] + } + + function test_display(data) { + var control = createTemporaryObject(tabButton, testCase, { + text: "TabButton", + display: data.display, + "icon.source": "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png", + "LayoutMirroring.enabled": !!data.mirrored + }) + verify(control) + compare(control.icon.source, "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png") + + var iconImage = findChild(control.contentItem, "image") + var textLabel = findChild(control.contentItem, "label") + + switch (control.display) { + case TabButton.IconOnly: + verify(iconImage) + verify(!textLabel) + compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + break; + case TabButton.TextOnly: + verify(!iconImage) + verify(textLabel) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + case TabButton.TextUnderIcon: + verify(iconImage) + verify(textLabel) + compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + verify(iconImage.y < textLabel.y) + break; + case TabButton.TextBesideIcon: + verify(iconImage) + verify(textLabel) + if (control.mirrored) + verify(textLabel.x < iconImage.x) + else + verify(iconImage.x < textLabel.x) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + } + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_textarea.qml b/tests/auto/quickcontrols2/controls/data/tst_textarea.qml new file mode 100644 index 00000000000..5fcc4773dcc --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_textarea.qml @@ -0,0 +1,804 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "TextArea" + + Component { + id: textArea + TextArea { background: Item { } } + } + + Component { + id: flickable + Flickable { + width: 200 + height: 200 + TextArea.flickable: TextArea { } + } + } + + Component { + id: flickableCustomBackground + Flickable { + width: 200 + height: 200 + TextArea.flickable: TextArea { + background: Rectangle { + color: "green" + } + } + } + } + + Component { + id: signalSpy + SignalSpy { } + } + + Component { + id: rectangle + Rectangle { } + } + + FontMetrics { + id: defaultFontMetrics + } + + function test_creation() { + var control = createTemporaryObject(textArea, testCase) + verify(control) + } + + function test_implicitSize() { + var control = createTemporaryObject(textArea, testCase) + verify(control) + + var implicitWidthSpy = signalSpy.createObject(control, { target: control, signalName: "implicitWidthChanged"} ) + verify(implicitWidthSpy.valid) + + var implicitHeightSpy = signalSpy.createObject(control, { target: control, signalName: "implicitHeightChanged"} ) + verify(implicitHeightSpy.valid) + + var implicitBackgroundWidthSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "implicitBackgroundWidthChanged"}) + verify(implicitBackgroundWidthSpy.valid) + + var implicitBackgroundHeightSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "implicitBackgroundHeightChanged"}) + verify(implicitBackgroundHeightSpy.valid) + + var implicitWidthChanges = 0 + var implicitHeightChanges = 0 + var implicitBackgroundWidthChanges = 0 + var implicitBackgroundHeightChanges = 0 + + verify(control.implicitWidth >= control.leftPadding + control.rightPadding) + verify(control.implicitHeight >= control.contentHeight + control.topPadding + control.bottomPadding) + compare(control.implicitBackgroundWidth, 0) + compare(control.implicitBackgroundHeight, 0) + + control.background = rectangle.createObject(control, {implicitWidth: 400, implicitHeight: 200}) + compare(control.implicitWidth, 400) + compare(control.implicitHeight, 200) + compare(control.implicitBackgroundWidth, 400) + compare(control.implicitBackgroundHeight, 200) + compare(implicitWidthSpy.count, ++implicitWidthChanges) + compare(implicitHeightSpy.count, ++implicitHeightChanges) + compare(implicitBackgroundWidthSpy.count, ++implicitBackgroundWidthChanges) + compare(implicitBackgroundHeightSpy.count, ++implicitBackgroundHeightChanges) + + control.background = null + compare(control.implicitWidth, control.leftPadding + control.rightPadding) + verify(control.implicitHeight >= control.contentHeight + control.topPadding + control.bottomPadding) + compare(control.implicitBackgroundWidth, 0) + compare(control.implicitBackgroundHeight, 0) + compare(implicitWidthSpy.count, ++implicitWidthChanges) + compare(implicitHeightSpy.count, ++implicitHeightChanges) + compare(implicitBackgroundWidthSpy.count, ++implicitBackgroundWidthChanges) + compare(implicitBackgroundHeightSpy.count, ++implicitBackgroundHeightChanges) + + control.text = "TextArea" + compare(control.implicitWidth, control.contentWidth + control.leftPadding + control.rightPadding) + verify(control.implicitHeight >= control.contentHeight + control.topPadding + control.bottomPadding) + compare(control.implicitBackgroundWidth, 0) + compare(control.implicitBackgroundHeight, 0) + compare(implicitWidthSpy.count, ++implicitWidthChanges) + + defaultFontMetrics.font = control.font + var leading = defaultFontMetrics.leading + var ascent = defaultFontMetrics.ascent + var descent = defaultFontMetrics.descent + + var leadingOverflow = Math.ceil(ascent + descent) < Math.ceil(ascent + descent + leading) + + // If the font in use triggers QTBUG-83894, it is possible that this will cause + // the following compare to fail if the implicitHeight from the TextEdit is ued. + // Unfortunately, since some styles override implicitHeight, we cannot guarantee + // that it will fail, so we need to simply skip the test for these cases. + if (!leadingOverflow) + compare(implicitHeightSpy.count, implicitHeightChanges) + compare(implicitBackgroundWidthSpy.count, implicitBackgroundWidthChanges) + compare(implicitBackgroundHeightSpy.count, implicitBackgroundHeightChanges) + + control.placeholderText = "..." + compare(control.implicitWidth, control.contentWidth + control.leftPadding + control.rightPadding) + verify(control.implicitHeight >= control.contentHeight + control.topPadding + control.bottomPadding) + compare(control.implicitBackgroundWidth, 0) + compare(control.implicitBackgroundHeight, 0) + compare(implicitWidthSpy.count, implicitWidthChanges) + if (!leadingOverflow) + compare(implicitHeightSpy.count, implicitHeightChanges) + compare(implicitBackgroundWidthSpy.count, implicitBackgroundWidthChanges) + compare(implicitBackgroundHeightSpy.count, implicitBackgroundHeightChanges) + } + + function test_alignment_data() { + return [ + { tag: "empty", text: "", placeholderText: "", textAlignment: undefined, placeholderAlignment: Qt.AlignLeft }, + { tag: "empty,left", text: "", placeholderText: "", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "empty,center", text: "", placeholderText: "", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "empty,right", text: "", placeholderText: "", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "empty,ltr", text: "", placeholderText: "Search", textAlignment: undefined, placeholderAlignment: Qt.AlignLeft }, + { tag: "empty,ltr,left", text: "", placeholderText: "Search", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "empty,ltr,center", text: "", placeholderText: "Search", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "empty,ltr,right", text: "", placeholderText: "Search", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "empty,rtl", text: "", placeholderText: "بحث", textAlignment: undefined, placeholderAlignment: Qt.AlignRight }, + { tag: "empty,rtl,left", text: "", placeholderText: "بحث", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "empty,rtl,center", text: "", placeholderText: "بحث", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "empty,rtl,right", text: "", placeholderText: "بحث", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "ltr,empty", text: "Text", placeholderText: "", textAlignment: undefined, placeholderAlignment: Qt.AlignLeft }, + { tag: "ltr,empty,left", text: "Text", placeholderText: "", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "ltr,empty,center", text: "Text", placeholderText: "", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "ltr,empty,right", text: "Text", placeholderText: "", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "ltr,ltr", text: "Text", placeholderText: "Search", textAlignment: undefined, placeholderAlignment: Qt.AlignLeft }, + { tag: "ltr,ltr,left", text: "Text", placeholderText: "Search", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "ltr,ltr,center", text: "Text", placeholderText: "Search", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "ltr,ltr,right", text: "Text", placeholderText: "Search", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "ltr,rtl", text: "Text", placeholderText: "بحث", textAlignment: undefined, placeholderAlignment: Qt.AlignRight }, + { tag: "ltr,rtl,left", text: "Text", placeholderText: "بحث", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "ltr,rtl,center", text: "Text", placeholderText: "بحث", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "ltr,rtl,right", text: "Text", placeholderText: "بحث", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "rtl,empty", text: "نص", placeholderText: "", textAlignment: undefined, placeholderAlignment: Qt.AlignLeft }, + { tag: "rtl,empty,left", text: "نص", placeholderText: "", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "rtl,empty,center", text: "نص", placeholderText: "", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "rtl,empty,right", text: "نص", placeholderText: "", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "rtl,ltr", text: "نص", placeholderText: "Search", textAlignment: undefined, placeholderAlignment: Qt.AlignLeft }, + { tag: "rtl,ltr,left", text: "نص", placeholderText: "Search", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "rtl,ltr,center", text: "نص", placeholderText: "Search", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "rtl,ltr,right", text: "نص", placeholderText: "Search", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "rtl,rtl", text: "نص", placeholderText: "بحث", textAlignment: undefined, placeholderAlignment: Qt.AlignRight }, + { tag: "rtl,rtl,left", text: "نص", placeholderText: "بحث", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "rtl,rtl,center", text: "نص", placeholderText: "بحث", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "rtl,rtl,right", text: "نص", placeholderText: "بحث", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + ] + } + + function test_alignment(data) { + var control = createTemporaryObject(textArea, testCase, {text: data.text, placeholderText: data.placeholderText, horizontalAlignment: data.textAlignment}) + + if (data.textAlignment !== undefined) + compare(control.horizontalAlignment, data.textAlignment) + for (var i = 0; i < control.children.length; ++i) { + if (control.children[i].hasOwnProperty("horizontalAlignment")) + compare(control.children[i].effectiveHorizontalAlignment, data.placeholderAlignment) // placeholder + } + + control.verticalAlignment = TextArea.AlignBottom + compare(control.verticalAlignment, TextArea.AlignBottom) + for (var j = 0; j < control.children.length; ++j) { + if (control.children[j].hasOwnProperty("verticalAlignment")) + compare(control.children[j].verticalAlignment, Text.AlignBottom) // placeholder + } + } + + function test_font_explicit_attributes_data() { + return [ + {tag: "bold", value: true}, + {tag: "capitalization", value: Font.Capitalize}, + {tag: "family", value: "Courier"}, + {tag: "italic", value: true}, + {tag: "strikeout", value: true}, + {tag: "underline", value: true}, + {tag: "weight", value: Font.Black}, + {tag: "wordSpacing", value: 55} + ] + } + + function test_font_explicit_attributes(data) { + var control = createTemporaryObject(textArea, testCase) + verify(control) + + var child = textArea.createObject(control) + verify(child) + + var controlSpy = signalSpy.createObject(control, {target: control, signalName: "fontChanged"}) + verify(controlSpy.valid) + + var childSpy = signalSpy.createObject(child, {target: child, signalName: "fontChanged"}) + verify(childSpy.valid) + + var defaultValue = control.font[data.tag] + child.font[data.tag] = defaultValue + + compare(child.font[data.tag], defaultValue) + compare(childSpy.count, 0) + + control.font[data.tag] = data.value + + compare(control.font[data.tag], data.value) + compare(controlSpy.count, 1) + + compare(child.font[data.tag], defaultValue) + compare(childSpy.count, 0) + } + + function test_flickable() { + var control = createTemporaryObject(flickable, testCase, {text:"line0", selectByMouse: true}) + verify(control) + + var textArea = control.TextArea.flickable + verify(textArea) + + if (textArea.background) + compare(textArea.background.parent, control) + + for (var i = 1; i <= 100; ++i) + textArea.text += "line\n" + i + + verify(textArea.contentWidth > 0) + verify(textArea.contentHeight > 200) + + compare(control.contentWidth, textArea.contentWidth + textArea.leftPadding + textArea.rightPadding) + compare(control.contentHeight, textArea.contentHeight + textArea.topPadding + textArea.bottomPadding) + + compare(textArea.cursorPosition, 0) + + var center = textArea.positionAt(control.width / 2, control.height / 2) + verify(center > 0) + mouseClick(textArea, control.width / 2, control.height / 2) + compare(textArea.cursorPosition, center) + + // click inside text area, but below flickable + var below = textArea.positionAt(control.width / 2, control.height + 1) + verify(below > center) + mouseClick(textArea, control.width / 2, control.height + 1) + compare(textArea.cursorPosition, center) // no change + + // scroll down + control.contentY = -(control.contentHeight - control.height) / 2 + + // click inside textarea, but above flickable + var above = textArea.positionAt(control.width / 2, textArea.topPadding) + verify(above > 0 && above < center) + mouseClick(textArea, control.width / 2, 0) + compare(textArea.cursorPosition, center) // no change + } + + function test_flickableCustomBackground() { + // Test that the TextArea background item is parented out of the + // TextArea and into the Flicable, and that it has the same size + // as the flickable. + var flickable = createTemporaryObject(flickableCustomBackground, testCase) + verify(flickable) + + var textArea = flickable.TextArea.flickable + verify(textArea) + verify(textArea.background) + compare(textArea.background.width, flickable.width) + compare(textArea.background.height, flickable.height) + } + + function test_warning() { + ignoreWarning(/QML TestCase: TextArea must be attached to a Flickable/) + testCase.TextArea.flickable = null + } + + function test_hover_data() { + return [ + { tag: "enabled", hoverEnabled: true }, + { tag: "disabled", hoverEnabled: false }, + ] + } + + function test_hover(data) { + var control = createTemporaryObject(textArea, testCase, {text: "TextArea", hoverEnabled: data.hoverEnabled}) + verify(control) + + compare(control.hovered, false) + + mouseMove(control, control.width / 2, control.height / 2) + compare(control.hovered, data.hoverEnabled) + + mouseMove(control, -1, -1) + compare(control.hovered, false) + } + + function test_pressedReleased_data() { + return [ + { + tag: "pressed outside", x: -1, y: -1, button: Qt.LeftButton, + controlPressEvent: null, + controlReleaseEvent: null, + parentPressEvent: { + x: 0, y: 0, button: Qt.LeftButton, buttons: Qt.LeftButton, modifiers: Qt.NoModifier, wasHeld: false, isClick: false + }, + parentReleaseEvent: { + x: 0, y: 0, button: Qt.LeftButton, buttons: Qt.NoButton, modifiers: Qt.NoModifier, wasHeld: false, isClick: false + }, + }, + { + tag: "left click", x: 0, y: 0, button: Qt.LeftButton, + controlPressEvent: { + x: 0, y: 0, button: Qt.LeftButton, buttons: Qt.LeftButton, modifiers: Qt.NoModifier, wasHeld: false, isClick: false + }, + controlReleaseEvent: { + x: 0, y: 0, button: Qt.LeftButton, buttons: Qt.NoButton, modifiers: Qt.NoModifier, wasHeld: false, isClick: false + }, + parentPressEvent: null, + parentReleaseEvent: null, + }, + { + tag: "right click", x: 0, y: 0, button: Qt.RightButton, + controlPressEvent: { + x: 0, y: 0, button: Qt.RightButton, buttons: Qt.RightButton, modifiers: Qt.NoModifier, wasHeld: false, isClick: false + }, + controlReleaseEvent: { + x: 0, y: 0, button: Qt.RightButton, buttons: Qt.NoButton, modifiers: Qt.NoModifier, wasHeld: false, isClick: false + }, + parentPressEvent: null, + parentReleaseEvent: null, + }, + ]; + } + + Component { + id: mouseAreaComponent + MouseArea { + anchors.fill: parent + } + } + + function checkMouseEvent(event, expectedEvent) { + compare(event.x, expectedEvent.x) + compare(event.y, expectedEvent.y) + compare(event.button, expectedEvent.button) + compare(event.buttons, expectedEvent.buttons) + } + + function test_pressedReleased(data) { + var mouseArea = createTemporaryObject(mouseAreaComponent, testCase) + verify(mouseArea) + var control = textArea.createObject(mouseArea, {text: "TextArea"}) + verify(control) + + // Give enough room to check presses outside of the control and on the parent. + control.x = 1; + control.y = 1; + + function checkControlPressEvent(event) { + checkMouseEvent(event, data.controlPressEvent) + } + function checkControlReleaseEvent(event) { + checkMouseEvent(event, data.controlReleaseEvent) + } + function checkParentPressEvent(event) { + checkMouseEvent(event, data.parentPressEvent) + } + function checkParentReleaseEvent(event) { + checkMouseEvent(event, data.parentReleaseEvent) + } + + // Can't use signalArguments, because the event won't live that long. + if (data.controlPressEvent) + control.onPressed.connect(checkControlPressEvent) + if (data.controlReleaseEvent) + control.onReleased.connect(checkControlReleaseEvent) + if (data.parentPressEvent) + control.onPressed.connect(checkParentPressEvent) + if (data.parentReleaseEvent) + control.onReleased.connect(checkParentReleaseEvent) + + var controlPressedSpy = signalSpy.createObject(control, { target: control, signalName: "pressed" }) + verify(controlPressedSpy.valid) + var controlReleasedSpy = signalSpy.createObject(control, { target: control, signalName: "released" }) + verify(controlReleasedSpy.valid) + var parentPressedSpy = signalSpy.createObject(mouseArea, { target: mouseArea, signalName: "pressed" }) + verify(parentPressedSpy.valid) + var parentReleasedSpy = signalSpy.createObject(mouseArea, { target: mouseArea, signalName: "released" }) + verify(parentReleasedSpy.valid) + + mousePress(control, data.x, data.y, data.button) + compare(controlPressedSpy.count, data.controlPressEvent ? 1 : 0) + compare(parentPressedSpy.count, data.parentPressEvent ? 1 : 0) + mouseRelease(control, data.x, data.y, data.button) + compare(controlReleasedSpy.count, data.controlReleaseEvent ? 1 : 0) + compare(parentReleasedSpy.count, data.parentReleaseEvent ? 1 : 0) + } + + Component { + id: ignoreTextArea + + TextArea { + property bool ignorePress: false + property bool ignoreRelease: false + + onPressed: if (ignorePress) event.accepted = false + onReleased: if (ignoreRelease) event.accepted = false + } + } + + function checkEventAccepted(event) { + compare(event.accepted, true) + } + + function checkEventIgnored(event) { + compare(event.accepted, false) + } + + function test_ignorePressRelease() { + var mouseArea = createTemporaryObject(mouseAreaComponent, testCase) + verify(mouseArea) + var control = ignoreTextArea.createObject(mouseArea) + verify(control) + + var controlPressedSpy = signalSpy.createObject(control, { target: control, signalName: "pressed" }) + verify(controlPressedSpy.valid) + var controlReleasedSpy = signalSpy.createObject(control, { target: control, signalName: "released" }) + verify(controlReleasedSpy.valid) + var parentPressedSpy = signalSpy.createObject(mouseArea, { target: mouseArea, signalName: "pressed" }) + verify(parentPressedSpy.valid) + var parentReleasedSpy = signalSpy.createObject(mouseArea, { target: mouseArea, signalName: "released" }) + verify(parentReleasedSpy.valid) + + // Ignore only press events. + control.onPressed.connect(checkEventIgnored) + control.ignorePress = true + mousePress(control, 0, 0, data.button) + // The control will still get the signal, it just won't accept the event. + compare(controlPressedSpy.count, 1) + compare(parentPressedSpy.count, 1) + mouseRelease(control, 0, 0, data.button) + compare(controlReleasedSpy.count, 0) + compare(parentReleasedSpy.count, 1) + control.onPressed.disconnect(checkEventIgnored) + + // Ignore only release events. + control.onPressed.connect(checkEventAccepted) + control.onReleased.connect(checkEventIgnored) + control.ignorePress = false + control.ignoreRelease = true + mousePress(control, 0, 0, data.button) + compare(controlPressedSpy.count, 2) + compare(parentPressedSpy.count, 1) + mouseRelease(control, 0, 0, data.button) + compare(controlReleasedSpy.count, 1) + compare(parentReleasedSpy.count, 1) + control.onPressed.disconnect(checkEventAccepted) + control.onReleased.disconnect(checkEventIgnored) + } + + function test_multiClick() { + var control = createTemporaryObject(textArea, testCase, {text: "Qt Quick Controls 2 TextArea", selectByMouse: true}) + verify(control) + + waitForRendering(control) + control.width = control.contentWidth + var rect = control.positionToRectangle(12) + + // double click -> select word + mouseDoubleClickSequence(control, rect.x + rect.width / 2, rect.y + rect.height / 2) + compare(control.selectedText, "Controls") + + // tripple click -> select whole line + mouseClick(control, rect.x + rect.width / 2, rect.y + rect.height / 2) + compare(control.selectedText, "Qt Quick Controls 2 TextArea") + } + + Component { + id: scrollView + ScrollView { + TextArea { } + } + } + + function test_scrollView() { + var control = createTemporaryObject(scrollView, testCase) + verify(control) + + // don't crash (QTBUG-62292) + control.destroy() + wait(0) + } + + function test_placeholderTextColor() { + var control = createTemporaryObject(textArea, testCase) + verify(control) + + // usually default value should not be pure opacue black + verify(control.placeholderTextColor !== "#ff000000") + control.placeholderTextColor = "#12345678" + compare(control.placeholderTextColor, "#12345678") + + for (var i = 0; i < control.children.length; ++i) { + if (control.children[i].hasOwnProperty("text")) + compare(control.children[i].color, control.placeholderTextColor) // placeholder.color + } + } + + function test_inset() { + var control = createTemporaryObject(textArea, testCase, {background: rectangle.createObject(control)}) + verify(control) + + var topInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "topInsetChanged"}) + verify(topInsetSpy.valid) + + var leftInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "leftInsetChanged"}) + verify(leftInsetSpy.valid) + + var rightInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "rightInsetChanged"}) + verify(rightInsetSpy.valid) + + var bottomInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "bottomInsetChanged"}) + verify(bottomInsetSpy.valid) + + var topInsetChanges = 0 + var leftInsetChanges = 0 + var rightInsetChanges = 0 + var bottomInsetChanges = 0 + + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + + control.width = 100 + control.height = 100 + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 100) + compare(control.background.height, 100) + + control.topInset = 10 + compare(control.topInset, 10) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, ++topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 10) + compare(control.background.width, 100) + compare(control.background.height, 90) + + control.leftInset = 20 + compare(control.topInset, 10) + compare(control.leftInset, 20) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, ++leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 10) + compare(control.background.width, 80) + compare(control.background.height, 90) + + control.rightInset = 30 + compare(control.topInset, 10) + compare(control.leftInset, 20) + compare(control.rightInset, 30) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, ++rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 10) + compare(control.background.width, 50) + compare(control.background.height, 90) + + control.bottomInset = 40 + compare(control.topInset, 10) + compare(control.leftInset, 20) + compare(control.rightInset, 30) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, ++bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 10) + compare(control.background.width, 50) + compare(control.background.height, 50) + + control.topInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 20) + compare(control.rightInset, 30) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, ++topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 0) + compare(control.background.width, 50) + compare(control.background.height, 60) + + control.leftInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 30) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, ++leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 70) + compare(control.background.height, 60) + + control.rightInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, ++rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 100) + compare(control.background.height, 60) + + control.bottomInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, ++bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 100) + compare(control.background.height, 100) + } + + // QTBUG-76369 + Component { + id: testResizeBackground + Item { + width: 200 + height: 200 + property alias textArea: textArea + ScrollView { + anchors.fill: parent + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + TextArea { + id: textArea + // workaround test failing due to default insets on Imagine + topInset: undefined + leftInset: undefined + rightInset: undefined + bottomInset: undefined + wrapMode : TextEdit.WordWrap + readOnly: false + selectByMouse: true + focus: true + text: "test message" + + background: Rectangle { + y: parent.height - height - textArea.bottomPadding / 2 + implicitWidth: 120 + height: textArea.activeFocus ? 2 : 1 + } + } + } + } + } + + function test_resize_background() { + var control = createTemporaryObject(testResizeBackground, testCase) + + compare(control.textArea.background.width, control.width) + compare(control.textArea.background.height, 1) + control.width = 400 + control.height = 400 + compare(control.textArea.background.width, control.width) + compare(control.textArea.background.height, 1) + control.width = 200 + control.height = 200 + compare(control.textArea.background.width, control.width) + compare(control.textArea.background.height, 1) + + // hasBackgroundWidth=true + control.textArea.background.width = 1 + compare(control.textArea.background.width, 1) + compare(control.textArea.background.height, 1) + control.width = 400 + control.height = 400 + compare(control.textArea.background.width, 1) + compare(control.textArea.background.height, 1) + // hasBackgroundHeight=false + control.textArea.background.height = undefined + compare(control.textArea.background.width, 1) + compare(control.textArea.background.height, 0) + control.textArea.background.y = 0 + compare(control.textArea.background.width, 1) + compare(control.textArea.background.height, control.height) + control.width = 200 + control.height = 200 + compare(control.textArea.background.width, 1) + compare(control.textArea.background.height, control.height) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_textfield.qml b/tests/auto/quickcontrols2/controls/data/tst_textfield.qml new file mode 100644 index 00000000000..f9b0587fa2e --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_textfield.qml @@ -0,0 +1,663 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls +import QtQuick.Layouts + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "TextField" + + Component { + id: textField + TextField { } + } + + Component { + id: rectangle + Rectangle { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + function test_creation() { + var control = createTemporaryObject(textField, testCase) + verify(control) + } + + function test_implicitSize() { + var control = createTemporaryObject(textField, testCase) + verify(control) + + var implicitWidthSpy = signalSpy.createObject(control, { target: control, signalName: "implicitWidthChanged"} ) + verify(implicitWidthSpy.valid) + + var implicitHeightSpy = signalSpy.createObject(control, { target: control, signalName: "implicitHeightChanged"} ) + verify(implicitHeightSpy.valid) + + var implicitBackgroundWidthSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "implicitBackgroundWidthChanged"}) + verify(implicitBackgroundWidthSpy.valid) + + var implicitBackgroundHeightSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "implicitBackgroundHeightChanged"}) + verify(implicitBackgroundHeightSpy.valid) + + var implicitWidthChanges = 0 + var implicitHeightChanges = 0 + var implicitBackgroundWidthChanges = 0 + var implicitBackgroundHeightChanges = 0 + + verify(control.implicitWidth >= control.leftPadding + control.rightPadding) + verify(control.implicitHeight >= control.contentHeight + control.topPadding + control.bottomPadding) + compare(control.implicitBackgroundWidth, control.background.implicitWidth) + compare(control.implicitBackgroundHeight, control.background.implicitHeight) + + control.background = rectangle.createObject(control, {implicitWidth: 400, implicitHeight: 200}) + compare(control.implicitWidth, 400) + compare(control.implicitHeight, 200) + compare(control.implicitBackgroundWidth, 400) + compare(control.implicitBackgroundHeight, 200) + compare(implicitWidthSpy.count, ++implicitWidthChanges) + compare(implicitHeightSpy.count, ++implicitHeightChanges) + compare(implicitBackgroundWidthSpy.count, ++implicitBackgroundWidthChanges) + compare(implicitBackgroundHeightSpy.count, ++implicitBackgroundHeightChanges) + + control.background = null + compare(control.implicitWidth, control.leftPadding + control.rightPadding) + compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding) + compare(control.implicitBackgroundWidth, 0) + compare(control.implicitBackgroundHeight, 0) + compare(implicitWidthSpy.count, ++implicitWidthChanges) + compare(implicitHeightSpy.count, ++implicitHeightChanges) + compare(implicitBackgroundWidthSpy.count, ++implicitBackgroundWidthChanges) + compare(implicitBackgroundHeightSpy.count, ++implicitBackgroundHeightChanges) + + control.text = "TextField" + compare(control.implicitWidth, control.contentWidth + control.leftPadding + control.rightPadding) + compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding) + compare(control.implicitBackgroundWidth, 0) + compare(control.implicitBackgroundHeight, 0) + compare(implicitWidthSpy.count, ++implicitWidthChanges) + compare(implicitHeightSpy.count, implicitHeightChanges) + compare(implicitBackgroundWidthSpy.count, implicitBackgroundWidthChanges) + compare(implicitBackgroundHeightSpy.count, implicitBackgroundHeightChanges) + + control.placeholderText = "..." + compare(control.implicitWidth, control.contentWidth + control.leftPadding + control.rightPadding) + compare(control.implicitHeight, control.contentHeight + control.topPadding + control.bottomPadding) + compare(control.implicitBackgroundWidth, 0) + compare(control.implicitBackgroundHeight, 0) + compare(implicitWidthSpy.count, implicitWidthChanges) + compare(implicitHeightSpy.count, implicitHeightChanges) + compare(implicitBackgroundWidthSpy.count, implicitBackgroundWidthChanges) + compare(implicitBackgroundHeightSpy.count, implicitBackgroundHeightChanges) + } + + function test_alignment_data() { + return [ + { tag: "empty", text: "", placeholderText: "", textAlignment: undefined, placeholderAlignment: Qt.AlignLeft }, + { tag: "empty,left", text: "", placeholderText: "", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "empty,center", text: "", placeholderText: "", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "empty,right", text: "", placeholderText: "", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "empty,ltr", text: "", placeholderText: "Search", textAlignment: undefined, placeholderAlignment: Qt.AlignLeft }, + { tag: "empty,ltr,left", text: "", placeholderText: "Search", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "empty,ltr,center", text: "", placeholderText: "Search", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "empty,ltr,right", text: "", placeholderText: "Search", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "empty,rtl", text: "", placeholderText: "بحث", textAlignment: undefined, placeholderAlignment: Qt.AlignRight }, + { tag: "empty,rtl,left", text: "", placeholderText: "بحث", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "empty,rtl,center", text: "", placeholderText: "بحث", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "empty,rtl,right", text: "", placeholderText: "بحث", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "ltr,empty", text: "Text", placeholderText: "", textAlignment: undefined, placeholderAlignment: Qt.AlignLeft }, + { tag: "ltr,empty,left", text: "Text", placeholderText: "", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "ltr,empty,center", text: "Text", placeholderText: "", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "ltr,empty,right", text: "Text", placeholderText: "", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "ltr,ltr", text: "Text", placeholderText: "Search", textAlignment: undefined, placeholderAlignment: Qt.AlignLeft }, + { tag: "ltr,ltr,left", text: "Text", placeholderText: "Search", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "ltr,ltr,center", text: "Text", placeholderText: "Search", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "ltr,ltr,right", text: "Text", placeholderText: "Search", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "ltr,rtl", text: "Text", placeholderText: "بحث", textAlignment: undefined, placeholderAlignment: Qt.AlignRight }, + { tag: "ltr,rtl,left", text: "Text", placeholderText: "بحث", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "ltr,rtl,center", text: "Text", placeholderText: "بحث", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "ltr,rtl,right", text: "Text", placeholderText: "بحث", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "rtl,empty", text: "نص", placeholderText: "", textAlignment: undefined, placeholderAlignment: Qt.AlignLeft }, + { tag: "rtl,empty,left", text: "نص", placeholderText: "", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "rtl,empty,center", text: "نص", placeholderText: "", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "rtl,empty,right", text: "نص", placeholderText: "", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "rtl,ltr", text: "نص", placeholderText: "Search", textAlignment: undefined, placeholderAlignment: Qt.AlignLeft }, + { tag: "rtl,ltr,left", text: "نص", placeholderText: "Search", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "rtl,ltr,center", text: "نص", placeholderText: "Search", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "rtl,ltr,right", text: "نص", placeholderText: "Search", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + + { tag: "rtl,rtl", text: "نص", placeholderText: "بحث", textAlignment: undefined, placeholderAlignment: Qt.AlignRight }, + { tag: "rtl,rtl,left", text: "نص", placeholderText: "بحث", textAlignment: Qt.AlignLeft, placeholderAlignment: Qt.AlignLeft }, + { tag: "rtl,rtl,center", text: "نص", placeholderText: "بحث", textAlignment: Qt.AlignHCenter, placeholderAlignment: Qt.AlignHCenter }, + { tag: "rtl,rtl,right", text: "نص", placeholderText: "بحث", textAlignment: Qt.AlignRight, placeholderAlignment: Qt.AlignRight }, + ] + } + + function test_alignment(data) { + var control = createTemporaryObject(textField, testCase, {text: data.text, placeholderText: data.placeholderText, horizontalAlignment: data.textAlignment}) + + if (data.textAlignment !== undefined) + compare(control.horizontalAlignment, data.textAlignment) + for (var i = 0; i < control.children.length; ++i) { + if (control.children[i].hasOwnProperty("text") && control.children[i].hasOwnProperty("horizontalAlignment")) + compare(control.children[i].effectiveHorizontalAlignment, data.placeholderAlignment) // placeholder + } + + control.verticalAlignment = TextField.AlignBottom + compare(control.verticalAlignment, TextField.AlignBottom) + for (var j = 0; j < control.children.length; ++j) { + if (control.children[j].hasOwnProperty("text") && control.children[j].hasOwnProperty("verticalAlignment")) + compare(control.children[j].verticalAlignment, Text.AlignBottom) // placeholder + } + } + + function test_font_explicit_attributes_data() { + return [ + {tag: "bold", value: true}, + {tag: "capitalization", value: Font.Capitalize}, + {tag: "family", value: "Courier"}, + {tag: "italic", value: true}, + {tag: "strikeout", value: true}, + {tag: "underline", value: true}, + {tag: "weight", value: Font.Black}, + {tag: "wordSpacing", value: 55} + ] + } + + function test_font_explicit_attributes(data) { + var control = createTemporaryObject(textField, testCase) + verify(control) + + var child = textField.createObject(control) + verify(child) + + var controlSpy = signalSpy.createObject(control, {target: control, signalName: "fontChanged"}) + verify(controlSpy.valid) + + var childSpy = signalSpy.createObject(child, {target: child, signalName: "fontChanged"}) + verify(childSpy.valid) + + var defaultValue = control.font[data.tag] + child.font[data.tag] = defaultValue + + compare(child.font[data.tag], defaultValue) + compare(childSpy.count, 0) + + control.font[data.tag] = data.value + + compare(control.font[data.tag], data.value) + compare(controlSpy.count, 1) + + compare(child.font[data.tag], defaultValue) + compare(childSpy.count, 0) + } + + function test_hover_data() { + return [ + { tag: "enabled", hoverEnabled: true }, + { tag: "disabled", hoverEnabled: false }, + ] + } + + function test_hover(data) { + var control = createTemporaryObject(textField, testCase, {hoverEnabled: data.hoverEnabled}) + verify(control) + + compare(control.hovered, false) + + mouseMove(control, control.width / 2, control.height / 2) + compare(control.hovered, data.hoverEnabled) + + mouseMove(control, -1, -1) + compare(control.hovered, false) + } + + function test_pressedReleased_data() { + return [ + { + tag: "pressed outside", x: -1, y: -1, button: Qt.LeftButton, + controlPressEvent: null, + controlReleaseEvent: null, + parentPressEvent: { + x: 0, y: 0, button: Qt.LeftButton, buttons: Qt.LeftButton, modifiers: Qt.NoModifier, wasHeld: false, isClick: false + }, + parentReleaseEvent: { + x: 0, y: 0, button: Qt.LeftButton, buttons: Qt.NoButton, modifiers: Qt.NoModifier, wasHeld: false, isClick: false + }, + }, + { + tag: "left click", x: 0, y: 0, button: Qt.LeftButton, + controlPressEvent: { + x: 0, y: 0, button: Qt.LeftButton, buttons: Qt.LeftButton, modifiers: Qt.NoModifier, wasHeld: false, isClick: false + }, + controlReleaseEvent: { + x: 0, y: 0, button: Qt.LeftButton, buttons: Qt.NoButton, modifiers: Qt.NoModifier, wasHeld: false, isClick: false + }, + parentPressEvent: null, + parentReleaseEvent: null, + }, + { + tag: "right click", x: 0, y: 0, button: Qt.RightButton, + controlPressEvent: { + x: 0, y: 0, button: Qt.RightButton, buttons: Qt.RightButton, modifiers: Qt.NoModifier, wasHeld: false, isClick: false + }, + controlReleaseEvent: { + x: 0, y: 0, button: Qt.RightButton, buttons: Qt.NoButton, modifiers: Qt.NoModifier, wasHeld: false, isClick: false + }, + parentPressEvent: null, + parentReleaseEvent: null, + }, + ]; + } + + Component { + id: mouseAreaComponent + MouseArea { + anchors.fill: parent + } + } + + function checkMouseEvent(event, expectedEvent) { + compare(event.x, expectedEvent.x) + compare(event.y, expectedEvent.y) + compare(event.button, expectedEvent.button) + compare(event.buttons, expectedEvent.buttons) + } + + function test_pressedReleased(data) { + var mouseArea = createTemporaryObject(mouseAreaComponent, testCase) + verify(mouseArea) + var control = textField.createObject(mouseArea) + verify(control) + + // Give enough room to check presses outside of the control and on the parent. + control.x = 1; + control.y = 1; + + function checkControlPressEvent(event) { + checkMouseEvent(event, data.controlPressEvent) + } + function checkControlReleaseEvent(event) { + checkMouseEvent(event, data.controlReleaseEvent) + } + function checkParentPressEvent(event) { + checkMouseEvent(event, data.parentPressEvent) + } + function checkParentReleaseEvent(event) { + checkMouseEvent(event, data.parentReleaseEvent) + } + + // Can't use signalArguments, because the event won't live that long. + if (data.controlPressEvent) + control.onPressed.connect(checkControlPressEvent) + if (data.controlReleaseEvent) + control.onReleased.connect(checkControlReleaseEvent) + if (data.parentPressEvent) + control.onPressed.connect(checkParentPressEvent) + if (data.parentReleaseEvent) + control.onReleased.connect(checkParentReleaseEvent) + + var controlPressedSpy = signalSpy.createObject(control, { target: control, signalName: "pressed" }) + verify(controlPressedSpy.valid) + var controlReleasedSpy = signalSpy.createObject(control, { target: control, signalName: "released" }) + verify(controlReleasedSpy.valid) + var parentPressedSpy = signalSpy.createObject(mouseArea, { target: mouseArea, signalName: "pressed" }) + verify(parentPressedSpy.valid) + var parentReleasedSpy = signalSpy.createObject(mouseArea, { target: mouseArea, signalName: "released" }) + verify(parentReleasedSpy.valid) + + mousePress(control, data.x, data.y, data.button) + compare(controlPressedSpy.count, data.controlPressEvent ? 1 : 0) + compare(parentPressedSpy.count, data.parentPressEvent ? 1 : 0) + mouseRelease(control, data.x, data.y, data.button) + compare(controlReleasedSpy.count, data.controlReleaseEvent ? 1 : 0) + compare(parentReleasedSpy.count, data.parentReleaseEvent ? 1 : 0) + } + + Component { + id: ignoreTextField + + TextField { + property bool ignorePress: false + property bool ignoreRelease: false + + onPressed: if (ignorePress) event.accepted = false + onReleased: if (ignoreRelease) event.accepted = false + } + } + + function checkEventAccepted(event) { + compare(event.accepted, true) + } + + function checkEventIgnored(event) { + compare(event.accepted, false) + } + + function test_ignorePressRelease() { + var mouseArea = createTemporaryObject(mouseAreaComponent, testCase) + verify(mouseArea) + var control = ignoreTextField.createObject(mouseArea) + verify(control) + + var controlPressedSpy = signalSpy.createObject(control, { target: control, signalName: "pressed" }) + verify(controlPressedSpy.valid) + var controlReleasedSpy = signalSpy.createObject(control, { target: control, signalName: "released" }) + verify(controlReleasedSpy.valid) + var parentPressedSpy = signalSpy.createObject(mouseArea, { target: mouseArea, signalName: "pressed" }) + verify(parentPressedSpy.valid) + var parentReleasedSpy = signalSpy.createObject(mouseArea, { target: mouseArea, signalName: "released" }) + verify(parentReleasedSpy.valid) + + // Ignore only press events. + control.onPressed.connect(checkEventIgnored) + control.ignorePress = true + mousePress(control, 0, 0, data.button) + // The control will still get the signal, it just won't accept the event. + compare(controlPressedSpy.count, 1) + compare(parentPressedSpy.count, 1) + mouseRelease(control, 0, 0, data.button) + compare(controlReleasedSpy.count, 0) + compare(parentReleasedSpy.count, 1) + control.onPressed.disconnect(checkEventIgnored) + + // Ignore only release events. + control.onPressed.connect(checkEventAccepted) + control.onReleased.connect(checkEventIgnored) + control.ignorePress = false + control.ignoreRelease = true + mousePress(control, 0, 0, data.button) + compare(controlPressedSpy.count, 2) + compare(parentPressedSpy.count, 1) + mouseRelease(control, 0, 0, data.button) + compare(controlReleasedSpy.count, 1) + compare(parentReleasedSpy.count, 1) + control.onPressed.disconnect(checkEventAccepted) + control.onReleased.disconnect(checkEventIgnored) + } + + function test_multiClick() { + var control = createTemporaryObject(textField, testCase, {text: "Qt Quick Controls 2 TextArea", selectByMouse: true}) + verify(control) + + waitForRendering(control) + control.width = control.contentWidth + var rect = control.positionToRectangle(12) + + // double click -> select word + mouseDoubleClickSequence(control, rect.x + rect.width / 2, rect.y + rect.height / 2) + compare(control.selectedText, "Controls") + + // tripple click -> select whole line + mouseClick(control, rect.x + rect.width / 2, rect.y + rect.height / 2) + compare(control.selectedText, "Qt Quick Controls 2 TextArea") + } + + // QTBUG-64048 + function test_rightClick() { + var control = createTemporaryObject(textField, testCase, {text: "TextField", selectByMouse: true}) + verify(control) + + control.selectAll() + compare(control.selectedText, "TextField") + + mouseClick(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(control.selectedText, "TextField") + + mouseClick(control, control.width / 2, control.height / 2, Qt.LeftButton | Qt.RightButton) + compare(control.selectedText, "") + } + + // QTBUG-66260 + function test_placeholderTextColor() { + var control = createTemporaryObject(textField, testCase) + verify(control) + + // usually default value should not be pure opacue black + verify(control.placeholderTextColor !== "#ff000000") + control.placeholderTextColor = "#12345678" + compare(control.placeholderTextColor, "#12345678") + + for (var i = 0; i < control.children.length; ++i) { + if (control.children[i].hasOwnProperty("text")) + compare(control.children[i].color, control.placeholderTextColor) // placeholder.color + } + } + + function test_inset() { + var control = createTemporaryObject(textField, testCase, {background: rectangle.createObject(control)}) + verify(control) + + var topInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "topInsetChanged"}) + verify(topInsetSpy.valid) + + var leftInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "leftInsetChanged"}) + verify(leftInsetSpy.valid) + + var rightInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "rightInsetChanged"}) + verify(rightInsetSpy.valid) + + var bottomInsetSpy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: "bottomInsetChanged"}) + verify(bottomInsetSpy.valid) + + var topInsetChanges = 0 + var leftInsetChanges = 0 + var rightInsetChanges = 0 + var bottomInsetChanges = 0 + + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + + control.width = 100 + control.height = 100 + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 100) + compare(control.background.height, 100) + + control.topInset = 10 + compare(control.topInset, 10) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, ++topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 10) + compare(control.background.width, 100) + compare(control.background.height, 90) + + control.leftInset = 20 + compare(control.topInset, 10) + compare(control.leftInset, 20) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, ++leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 10) + compare(control.background.width, 80) + compare(control.background.height, 90) + + control.rightInset = 30 + compare(control.topInset, 10) + compare(control.leftInset, 20) + compare(control.rightInset, 30) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, ++rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 10) + compare(control.background.width, 50) + compare(control.background.height, 90) + + control.bottomInset = 40 + compare(control.topInset, 10) + compare(control.leftInset, 20) + compare(control.rightInset, 30) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, ++bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 10) + compare(control.background.width, 50) + compare(control.background.height, 50) + + control.topInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 20) + compare(control.rightInset, 30) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, ++topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 20) + compare(control.background.y, 0) + compare(control.background.width, 50) + compare(control.background.height, 60) + + control.leftInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 30) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, ++leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 70) + compare(control.background.height, 60) + + control.rightInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 40) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, ++rightInsetChanges) + compare(bottomInsetSpy.count, bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 100) + compare(control.background.height, 60) + + control.bottomInset = undefined + compare(control.topInset, 0) + compare(control.leftInset, 0) + compare(control.rightInset, 0) + compare(control.bottomInset, 0) + compare(topInsetSpy.count, topInsetChanges) + compare(leftInsetSpy.count, leftInsetChanges) + compare(rightInsetSpy.count, rightInsetChanges) + compare(bottomInsetSpy.count, ++bottomInsetChanges) + compare(control.background.x, 0) + compare(control.background.y, 0) + compare(control.background.width, 100) + compare(control.background.height, 100) + } + + Component { + id: layoutComponent + + ColumnLayout { + anchors.fill: parent + + property alias textField: textField + + TextField { + id: textField + placeholderText: "Placeholder" + Layout.fillWidth: true + } + } + } + + function test_inLayout() { + var layout = createTemporaryObject(layoutComponent, testCase) + verify(layout) + + var control = layout.textField + verify(control) + + compare(control.width, control.parent.width) + compare(control.background.width, control.width) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_toolbar.qml b/tests/auto/quickcontrols2/controls/data/tst_toolbar.qml new file mode 100644 index 00000000000..b35a927d3e2 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_toolbar.qml @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "ToolBar" + + Component { + id: toolBar + ToolBar { } + } + + Component { + id: oneChildBar + ToolBar { + Item { + implicitWidth: 100 + implicitHeight: 30 + } + } + } + + Component { + id: twoChildrenBar + ToolBar { + Item { + implicitWidth: 100 + implicitHeight: 30 + } + Item { + implicitWidth: 200 + implicitHeight: 60 + } + } + } + + Component { + id: contentBar + ToolBar { + contentItem: Item { + implicitWidth: 100 + implicitHeight: 30 + } + } + } + + function test_empty() { + var control = createTemporaryObject(toolBar, testCase) + verify(control) + + verify(control.contentItem) + compare(control.contentWidth, 0) + compare(control.contentHeight, 0) + compare(control.implicitContentWidth, 0) + compare(control.implicitContentHeight, 0) + } + + function test_oneChild() { + var control = createTemporaryObject(oneChildBar, testCase) + verify(control) + + compare(control.contentWidth, 100) + compare(control.contentHeight, 30) + compare(control.implicitContentWidth, 100) + compare(control.implicitContentHeight, 30) + verify(control.implicitWidth >= 100) + verify(control.implicitHeight >= 30) + } + + function test_twoChildren() { + var control = createTemporaryObject(twoChildrenBar, testCase) + verify(control) + + compare(control.contentWidth, 0) + compare(control.contentHeight, 0) + compare(control.implicitContentWidth, 0) + compare(control.implicitContentHeight, 0) + verify(control.implicitWidth >= 0) + verify(control.implicitHeight >= 0) + } + + function test_contentItem() { + var control = createTemporaryObject(contentBar, testCase) + verify(control) + + compare(control.contentWidth, 100) + compare(control.contentHeight, 30) + compare(control.implicitContentWidth, 100) + compare(control.implicitContentHeight, 30) + verify(control.implicitWidth >= 100) + verify(control.implicitHeight >= 30) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_toolbutton.qml b/tests/auto/quickcontrols2/controls/data/tst_toolbutton.qml new file mode 100644 index 00000000000..a7acd05ae45 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_toolbutton.qml @@ -0,0 +1,243 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "ToolButton" + + Component { + id: signalSpy + SignalSpy { } + } + + Component { + id: toolButton + ToolButton { } + } + + function test_text() { + var control = createTemporaryObject(toolButton, testCase) + verify(control) + + compare(control.text, "") + control.text = "ToolButton" + compare(control.text, "ToolButton") + control.text = "" + compare(control.text, "") + } + + function test_mouse() { + var control = createTemporaryObject(toolButton, testCase) + verify(control) + + var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"}) + verify(pressedSpy.valid) + + var downSpy = signalSpy.createObject(control, {target: control, signalName: "downChanged"}) + verify(downSpy.valid) + + var clickedSpy = signalSpy.createObject(control, {target: control, signalName: "clicked"}) + verify(clickedSpy.valid) + + // check + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(pressedSpy.count, 1) + compare(downSpy.count, 1) + compare(control.pressed, true) + compare(control.down, true) + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(clickedSpy.count, 1) + compare(pressedSpy.count, 2) + compare(downSpy.count, 2) + compare(control.pressed, false) + compare(control.down, false) + + // uncheck + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(pressedSpy.count, 3) + compare(downSpy.count, 3) + compare(control.pressed, true) + compare(control.down, true) + mouseRelease(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(clickedSpy.count, 2) + compare(pressedSpy.count, 4) + compare(downSpy.count, 4) + compare(control.pressed, false) + compare(control.down, false) + + // release outside + mousePress(control, control.width / 2, control.height / 2, Qt.LeftButton) + compare(pressedSpy.count, 5) + compare(downSpy.count, 5) + compare(control.pressed, true) + compare(control.down, true) + mouseMove(control, control.width * 2, control.height * 2) + compare(control.pressed, false) + compare(control.down, false) + mouseRelease(control, control.width * 2, control.height * 2, Qt.LeftButton) + compare(clickedSpy.count, 2) + compare(pressedSpy.count, 6) + compare(downSpy.count, 6) + compare(control.pressed, false) + compare(control.down, false) + + // right button + mousePress(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(pressedSpy.count, 6) + compare(downSpy.count, 6) + compare(control.pressed, false) + compare(control.down, false) + mouseRelease(control, control.width / 2, control.height / 2, Qt.RightButton) + compare(clickedSpy.count, 2) + compare(pressedSpy.count, 6) + compare(downSpy.count, 6) + compare(control.pressed, false) + compare(control.down, false) + } + + function test_keys() { + var control = createTemporaryObject(toolButton, testCase) + verify(control) + + var clickedSpy = signalSpy.createObject(control, {target: control, signalName: "clicked"}) + verify(clickedSpy.valid) + + control.forceActiveFocus() + verify(control.activeFocus) + + // check + keyClick(Qt.Key_Space) + compare(clickedSpy.count, 1) + + // uncheck + keyClick(Qt.Key_Space) + compare(clickedSpy.count, 2) + + // no change + var keys = [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab] + for (var i = 0; i < keys.length; ++i) { + keyClick(keys[i]) + compare(clickedSpy.count, 2) + } + } + + function test_baseline() { + var control = createTemporaryObject(toolButton, testCase) + verify(control) + compare(control.baselineOffset, control.contentItem.y + control.contentItem.baselineOffset) + } + + function test_display_data() { + return [ + { "tag": "IconOnly", display: ToolButton.IconOnly }, + { "tag": "TextOnly", display: ToolButton.TextOnly }, + { "tag": "TextUnderIcon", display: ToolButton.TextUnderIcon }, + { "tag": "TextBesideIcon", display: ToolButton.TextBesideIcon }, + { "tag": "IconOnly, mirrored", display: ToolButton.IconOnly, mirrored: true }, + { "tag": "TextOnly, mirrored", display: ToolButton.TextOnly, mirrored: true }, + { "tag": "TextUnderIcon, mirrored", display: ToolButton.TextUnderIcon, mirrored: true }, + { "tag": "TextBesideIcon, mirrored", display: ToolButton.TextBesideIcon, mirrored: true } + ] + } + + function test_display(data) { + var control = createTemporaryObject(toolButton, testCase, { + text: "ToolButton", + display: data.display, + "icon.source": "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png", + "LayoutMirroring.enabled": !!data.mirrored + }) + verify(control) + compare(control.icon.source, "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png") + + var iconImage = findChild(control.contentItem, "image") + var textLabel = findChild(control.contentItem, "label") + + switch (control.display) { + case ToolButton.IconOnly: + verify(iconImage) + verify(!textLabel) + compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + break; + case ToolButton.TextOnly: + verify(!iconImage) + verify(textLabel) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + case ToolButton.TextUnderIcon: + verify(iconImage) + verify(textLabel) + compare(iconImage.x, (control.availableWidth - iconImage.width) / 2) + compare(textLabel.x, (control.availableWidth - textLabel.width) / 2) + verify(iconImage.y < textLabel.y) + break; + case ToolButton.TextBesideIcon: + verify(iconImage) + verify(textLabel) + if (control.mirrored) + verify(textLabel.x < iconImage.x) + else + verify(iconImage.x < textLabel.x) + compare(iconImage.y, (control.availableHeight - iconImage.height) / 2) + compare(textLabel.y, (control.availableHeight - textLabel.height) / 2) + break; + } + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_toolseparator.qml b/tests/auto/quickcontrols2/controls/data/tst_toolseparator.qml new file mode 100644 index 00000000000..41c161dd4ba --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_toolseparator.qml @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + name: "ToolSeparator" + + Component { + id: toolSeparator + ToolSeparator {} + } + + function test_size() { + var control = createTemporaryObject(toolSeparator, testCase); + verify(control); + verify(control.width > 1); + verify(control.height > 1); + } + + Component { + id: signalSpyComponent + SignalSpy {} + } + + function test_orientation() { + var control = createTemporaryObject(toolSeparator, testCase); + verify(control); + compare(control.horizontal, false); + compare(control.vertical, true); + + var orientationSpy = signalSpyComponent.createObject(control, { target: control, signalName: "orientationChanged" }); + + var originalWidth = control.width; + var originalHeight = control.height; + control.orientation = Qt.Horizontal; + compare(control.orientation, Qt.Horizontal); + compare(control.width, originalHeight); + compare(control.height, originalWidth); + compare(control.horizontal, true); + compare(control.vertical, false); + compare(orientationSpy.count, 1); + + control.orientation = Qt.Vertical; + compare(control.orientation, Qt.Vertical); + compare(control.width, originalWidth); + compare(control.height, originalHeight); + compare(control.horizontal, false); + compare(control.vertical, true); + compare(orientationSpy.count, 2); + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_tooltip.qml b/tests/auto/quickcontrols2/controls/data/tst_tooltip.qml new file mode 100644 index 00000000000..89e179575fb --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_tooltip.qml @@ -0,0 +1,509 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "ToolTip" + + Component { + id: toolTip + ToolTip { } + } + + Component { + id: mouseArea + MouseArea { } + } + + Component { + id: signalSpy + SignalSpy { } + } + + QtObject { + id: object + } + + SignalSpy { + id: sharedSpy + target: ToolTip.toolTip + } + + function test_properties_data() { + return [ + {tag: "text", property: "text", defaultValue: "", setValue: "Hello", signalName: "textChanged"}, + {tag: "delay", property: "delay", defaultValue: 0, setValue: 1000, signalName: "delayChanged"}, + {tag: "timeout", property: "timeout", defaultValue: -1, setValue: 2000, signalName: "timeoutChanged"} + ] + } + + function test_properties(data) { + var control = createTemporaryObject(toolTip, testCase) + verify(control) + + compare(control[data.property], data.defaultValue) + + var spy = createTemporaryObject(signalSpy, testCase, {target: control, signalName: data.signalName}) + verify(spy.valid) + + control[data.property] = data.setValue + compare(control[data.property], data.setValue) + compare(spy.count, 1) + } + + function test_attached_data() { + return [ + {tag: "text", property: "text", defaultValue: "", setValue: "Hello", signalName: "textChanged"}, + {tag: "delay", property: "delay", defaultValue: 0, setValue: 1000, signalName: "delayChanged"}, + {tag: "timeout", property: "timeout", defaultValue: -1, setValue: 2000, signalName: "timeoutChanged"} + ] + } + + function test_attached(data) { + var item1 = createTemporaryObject(mouseArea, testCase) + verify(item1) + + var item2 = createTemporaryObject(mouseArea, testCase) + verify(item2) + + // Reset the properties to the expected default values, in case + // we're not the first test that uses attached properties to be run. + var sharedTip = ToolTip.toolTip + sharedTip[data.property] = data.defaultValue + + compare(item1.ToolTip[data.property], data.defaultValue) + compare(item2.ToolTip[data.property], data.defaultValue) + + var spy1 = signalSpy.createObject(item1, {target: item1.ToolTip, signalName: data.signalName}) + verify(spy1.valid) + + var spy2 = signalSpy.createObject(item2, {target: item2.ToolTip, signalName: data.signalName}) + verify(spy2.valid) + + sharedSpy.signalName = data.signalName + verify(sharedSpy.valid) + sharedSpy.clear() + + // change attached properties while the shared tooltip is not visible + item1.ToolTip[data.property] = data.setValue + compare(item1.ToolTip[data.property], data.setValue) + compare(spy1.count, 1) + + compare(spy2.count, 0) + compare(item2.ToolTip[data.property], data.defaultValue) + + // the shared tooltip is not visible for item1, so the attached + // property change should therefore not apply to the shared instance + compare(sharedSpy.count, 0) + compare(sharedTip[data.property], data.defaultValue) + + // show the shared tooltip for item2 + item2.ToolTip.visible = true + verify(item2.ToolTip.visible) + verify(sharedTip.visible) + + // change attached properties while the shared tooltip is visible + item2.ToolTip[data.property] = data.setValue + compare(item2.ToolTip[data.property], data.setValue) + compare(spy2.count, 1) + + // the shared tooltip is visible for item2, so the attached + // property change should apply to the shared instance + compare(sharedSpy.count, 1) + compare(sharedTip[data.property], data.setValue) + } + + function test_delay_data() { + return [ + {tag: "imperative:0", delay: 0, imperative: true}, + {tag: "imperative:100", delay: 100, imperative: true}, + {tag: "declarative:0", delay: 0, imperative: false}, + {tag: "declarative:100", delay: 100, imperative: false} + ] + } + + function test_delay(data) { + var control = createTemporaryObject(toolTip, testCase, {delay: data.delay}) + + compare(control.visible, false) + if (data.imperative) + control.open() + else + control.visible = true + compare(control.visible, data.delay <= 0) + tryCompare(control, "visible", true) + } + + function test_timeout_data() { + return [ + {tag: "imperative", imperative: true}, + {tag: "declarative", imperative: false} + ] + } + + function test_timeout(data) { + var control = createTemporaryObject(toolTip, testCase, {timeout: 100}) + + compare(control.visible, false) + if (data.imperative) + control.open() + else + control.visible = true + compare(control.visible, true) + // wait a bit to make sure that it's still visible + wait(50) + compare(control.visible, true) + // re-arm for another 200 ms + control.timeout = 200 + compare(control.visible, true) + // ensure that it's still visible after 150 ms (where old timeout < 150 < new timeout) + wait(150) + compare(control.visible, true) + tryCompare(control, "visible", false) + } + + function test_warning() { + ignoreWarning(new RegExp(".*QML QtObject: ToolTip must be attached to an Item")) + ignoreWarning(new RegExp(".*: QML ToolTip: cannot find any window to open popup in.")) + object.ToolTip.show("") // don't crash (QTBUG-56243) + } + + Component { + id: toolTipWithExitTransition + + ToolTip { + Component.onCompleted: contentItem.objectName = "contentItem" + + enter: Transition { + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 100 } + } + exit: Transition { + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 500 } + } + } + } + + function test_makeVisibleWhileExitTransitionRunning_data() { + return [ + { tag: "imperative", imperative: true }, + { tag: "declarative", imperative: false } + ] + } + + function test_makeVisibleWhileExitTransitionRunning(data) { + var control = createTemporaryObject(toolTipWithExitTransition, testCase) + + // Show, hide, and show the tooltip again. Its exit transition should + // start and get cancelled, and then its enter transition should run. + if (data.imperative) + control.open() + else + control.visible = true + tryCompare(control, "opacity", 1) + + if (data.imperative) + control.close() + else + control.visible = false + verify(control.exit.running) + tryVerify(function() { return control.opacity < 1; }) + + if (data.imperative) + control.open() + else + control.visible = true + tryCompare(control, "opacity", 1) + } + + Component { + id: buttonAndShortcutComponent + + Item { + property alias shortcut: shortcut + property alias button: button + + Shortcut { + id: shortcut + sequence: "A" + } + + Button { + id: button + text: "Just a button" + focusPolicy: Qt.NoFocus + + ToolTip.visible: button.hovered + ToolTip.text: qsTr("Some helpful text") + } + } + } + + function test_activateShortcutWhileToolTipVisible() { + if ((Qt.platform.pluginName === "offscreen") + || (Qt.platform.pluginName === "minimal")) + skip("Mouse hovering not functional on offscreen/minimal platforms") + + // Window shortcuts (the default context for Shortcut) require the window to have focus. + var window = testCase.Window.window + verify(window) + window.requestActivate() + tryCompare(window, "active", true) + + var root = createTemporaryObject(buttonAndShortcutComponent, testCase) + verify(root) + + mouseMove(root.button, root.button.width / 2, root.button.height / 2) + tryCompare(root.button.ToolTip.toolTip, "visible", true) + + var shortcutActivatedSpy = signalSpy.createObject(root, { target: root.shortcut, signalName: "activated" }) + verify(shortcutActivatedSpy.valid) + keyPress(Qt.Key_A) + compare(shortcutActivatedSpy.count, 1) + } + + Component { + id: hoverComponent + MouseArea { + id: hoverArea + property alias tooltip: tooltip + hoverEnabled: true + width: testCase.width + height: testCase.height + ToolTip { + id: tooltip + x: 10; y: 10 + width: 10; height: 10 + visible: hoverArea.containsMouse + } + } + } + + // QTBUG-63644 + function test_hover() { + var root = createTemporaryObject(hoverComponent, testCase) + verify(root) + + var tooltip = root.tooltip + verify(tooltip) + + for (var pos = 0; pos <= 25; pos += 5) { + mouseMove(root, pos, pos) + verify(tooltip.visible) + } + } + + Component { + id: nonAttachedToolTipComponent + ToolTip { } + } + + function test_nonAttachedToolTipShowAndHide() { + var tip = createTemporaryObject(nonAttachedToolTipComponent, testCase) + verify(tip) + tip.show("hello"); + verify(tip.visible) + verify(tip.text === "hello") + tip.hide() + tryCompare(tip, "visible", false) + tip.show("delay", 200) + verify(tip.visible) + tryCompare(tip, "visible", false) + } + + Component { + id: timeoutButtonRowComponent + + Row { + Button { + text: "Timeout: 1" + ToolTip.text: text + ToolTip.visible: down + ToolTip.timeout: 1 + } + + Button { + text: "Timeout: -1" + ToolTip.text: text + ToolTip.visible: down + } + } + } + + // QTBUG-74226 + function test_attachedTimeout() { + var row = createTemporaryObject(timeoutButtonRowComponent, testCase) + verify(row) + + // Press the button that has no timeout; it should stay visible. + var button2 = row.children[1] + mousePress(button2) + compare(button2.down, true) + tryCompare(button2.ToolTip.toolTip, "opened", true) + + // Wait a bit to make sure that it's still visible. + wait(50) + compare(button2.ToolTip.toolTip.opened, true) + + // Release and should close. + mouseRelease(button2) + compare(button2.down, false) + tryCompare(button2.ToolTip, "visible", false) + + // Now, press the first button that does have a timeout; it should close on its own eventually. + var button1 = row.children[0] + mousePress(button1) + compare(button1.down, true) + // We use a short timeout to speed up the test, but tryCompare(...opened, true) then + // fails because the dialog has already been hidden by that point, so just check that it's + // immediately visible, which is more or less the same thing. + compare(button1.ToolTip.visible, true) + tryCompare(button1.ToolTip, "visible", false) + mouseRelease(button2) + + // Now, hover over the second button again. It should still stay visible until the mouse is released. + mousePress(button2) + compare(button2.down, true) + tryCompare(button2.ToolTip.toolTip, "opened", true) + + // Wait a bit to make sure that it's still visible. + wait(50) + compare(button2.ToolTip.toolTip.opened, true) + + // Release and should close. + mouseRelease(button2) + compare(button2.down, false) + tryCompare(button2.ToolTip, "visible", false) + } + + Component { + id: wrapComponent + + Item { + ToolTip.text: "This is some very very very very very very very very very very very very" + + " very very very very very very very very very very very very very very" + + " very very very very very very very very very very very very long text" + } + } + + // QTBUG-62350 + function test_wrap() { + var item = createTemporaryObject(wrapComponent, testCase) + verify(item) + + // Avoid "cannot find window to popup in" warning that can occur if it's made visible too early. + item.ToolTip.visible = true + tryCompare(item.ToolTip.toolTip, "opened", true) + compare(item.ToolTip.toolTip.contentItem.wrapMode, Text.Wrap) + verify(item.ToolTip.toolTip.contentItem.width < item.ToolTip.toolTip.contentItem.implicitWidth) + } + + function test_timeoutAfterOpened() { + let control = createTemporaryObject(toolTipWithExitTransition, testCase, { timeout: 1, exit: null }) + verify(control) + + let openedSpy = createTemporaryObject(signalSpy, testCase, { target: control, signalName: "opened" }) + verify(openedSpy.valid) + + control.show("Test") + tryCompare(openedSpy, "count", 1) + } + + Component { + id: buttonDownToolTipComponent + + Button { + required property string toolTipText + + ToolTip.text: toolTipText + ToolTip.visible: down + } + } + + function test_attachedSizeBug() { + let shortTextButton = createTemporaryObject(buttonDownToolTipComponent, testCase, + { toolTipText: "Short text" }) + verify(shortTextButton) + + let longTextButton = createTemporaryObject(buttonDownToolTipComponent, testCase, + { x: shortTextButton.width, toolTipText: "Some reeeeeeaaaaaaallly looooooooooongggggggg text" }) + verify(longTextButton) + + shortTextButton.ToolTip.toolTip.background.objectName = "ToolTipBackground" + shortTextButton.ToolTip.toolTip.contentItem.objectName = "ToolTipText" + + // Show the tooltip with long text. + mousePress(longTextButton) + tryCompare(longTextButton.ToolTip.toolTip, "opened", true) + const longTextToolTipImplicitWidth = longTextButton.ToolTip.toolTip.implicitWidth + mouseRelease(longTextButton) + tryCompare(longTextButton.ToolTip.toolTip, "visible", false) + + // Show the tooltip with short text. + mousePress(shortTextButton) + tryCompare(shortTextButton.ToolTip.toolTip, "opened", true) + mouseRelease(shortTextButton) + tryCompare(shortTextButton.ToolTip.toolTip, "visible", false) + + // Show the tooltip with long text again. It should have its original width. + mousePress(longTextButton) + tryCompare(longTextButton.ToolTip.toolTip, "opened", true) + compare(longTextButton.ToolTip.toolTip.implicitWidth, longTextToolTipImplicitWidth) + mouseRelease(longTextButton) + tryCompare(longTextButton.ToolTip.toolTip, "visible", false) + } +} diff --git a/tests/auto/quickcontrols2/controls/data/tst_tumbler.qml b/tests/auto/quickcontrols2/controls/data/tst_tumbler.qml new file mode 100644 index 00000000000..0fc2e87b8a4 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/data/tst_tumbler.qml @@ -0,0 +1,1323 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls + +TestCase { + id: testCase + width: 300 + height: 300 + visible: true + when: windowShown + name: "Tumbler" + + property var tumbler: null + readonly property real implicitTumblerWidth: 60 + readonly property real implicitTumblerHeight: 200 + readonly property real defaultImplicitDelegateHeight: implicitTumblerHeight / 3 + readonly property real defaultListViewTumblerOffset: -defaultImplicitDelegateHeight + readonly property real tumblerDelegateHeight: tumbler ? tumbler.availableHeight / tumbler.visibleItemCount : 0 + property Item tumblerView: null + + Component { + id: tumblerComponent + + Tumbler { + visibleItemCount: 3 + } + } + + Component { + id: itemComponent + + Item { + anchors.fill: parent + } + } + + function createTumbler(args) { + tumbler = createTemporaryObject(tumblerComponent, testCase, args); + verify(tumbler, "Tumbler: failed to create an instance"); + tumblerView = findView(tumbler); + verify(tumblerView); + } + + function tumblerXCenter() { + return tumbler.leftPadding + tumbler.width / 2; + } + + function tumblerYCenter() { + return tumbler.topPadding + tumbler.height / 2; + } + + // visualItemIndex is from 0 to the amount of visible items. + function itemCenterPos(visualItemIndex) { + var halfDelegateHeight = tumblerDelegateHeight / 2; + var yCenter = tumbler.y + tumbler.topPadding + halfDelegateHeight + + (tumblerDelegateHeight * visualItemIndex); + return Qt.point(tumblerXCenter(), yCenter); + } + + function itemTopLeftPos(visualItemIndex) { + return Qt.point(tumbler.leftPadding, tumbler.topPadding + (tumblerDelegateHeight * visualItemIndex)); + } + + function checkItemSizes() { + var contentChildren = tumbler.wrap ? tumblerView.children : tumblerView.contentItem.children; + verify(contentChildren.length >= tumbler.count); + for (var i = 0; i < contentChildren.length; ++i) { + compare(contentChildren[i].width, tumbler.availableWidth); + compare(contentChildren[i].height, tumblerDelegateHeight); + } + } + + function findView(parent) { + for (var i = 0; i < parent.children.length; ++i) { + var child = parent.children[i]; + if (child.hasOwnProperty("currentIndex")) { + return child; + } + + var grandChild = findView(child); + if (grandChild) + return grandChild; + } + + return null; + } + + function findDelegateWithText(parent, text) { + for (var i = 0; i < parent.children.length; ++i) { + var child = parent.children[i]; + if (child.hasOwnProperty("text") && child.text === text) { + return child; + } + + var grandChild = findDelegateWithText(child, text); + if (grandChild) + return grandChild; + } + + return null; + } + + property Component noAttachedPropertiesDelegate: Text { + text: modelData + } + + function test_wrapWithoutAttachedProperties() { + createTumbler(); + verify(tumbler.wrap); + + tumbler.delegate = noAttachedPropertiesDelegate; + // Shouldn't assert. + tumbler.wrap = false; + verify(findView(tumbler)); + } + + // TODO: test that currentIndex is maintained between contentItem changes... +// function tst_dynamicContentItemChange() { +// } + + function test_currentIndex() { + createTumbler(); + compare(tumbler.contentItem.parent, tumbler); + + tumbler.model = 5; + + compare(tumbler.currentIndex, 0); + waitForRendering(tumbler); + + // Set it through user interaction. + var pos = Qt.point(tumblerXCenter(), tumbler.height / 2); + mouseDrag(tumbler, pos.x, pos.y, 0, tumbler.height / 3, Qt.LeftButton, Qt.NoModifier, 200); + tryCompare(tumblerView, "offset", 1); + compare(tumbler.currentIndex, 4); + compare(tumblerView.currentIndex, 4); + + // Set it manually. + tumbler.currentIndex = 2; + tryCompare(tumbler, "currentIndex", 2); + compare(tumblerView.currentIndex, 2); + + tumbler.model = null; + tryCompare(tumbler, "currentIndex", -1); + // PathView will only use 0 as the currentIndex when there are no items. + compare(tumblerView.currentIndex, 0); + + tumbler.model = ["A", "B", "C"]; + tryCompare(tumbler, "currentIndex", 0); + + // Setting a negative current index should have no effect, because the model isn't empty. + tumbler.currentIndex = -1; + compare(tumbler.currentIndex, 0); + + tumbler.model = 1; + compare(tumbler.currentIndex, 0); + + tumbler.model = 5; + compare(tumbler.count, 5); + tumblerView = findView(tumbler); + tryCompare(tumblerView, "count", 5); + tumbler.currentIndex = 4; + compare(tumbler.currentIndex, 4); + compare(tumblerView.currentIndex, 4); + + --tumbler.model; + compare(tumbler.count, 4); + compare(tumblerView.count, 4); + // Removing an item from an integer-based model will cause views to reset their currentIndex to 0. + compare(tumbler.currentIndex, 0); + compare(tumblerView.currentIndex, 0); + + tumbler.model = 0; + compare(tumbler.currentIndex, -1); + } + + Component { + id: currentIndexTumbler + + Tumbler { + model: 5 + currentIndex: 2 + visibleItemCount: 3 + } + } + + Component { + id: currentIndexTumblerNoWrap + + Tumbler { + model: 5 + currentIndex: 2 + wrap: false + visibleItemCount: 3 + } + } + + Component { + id: currentIndexTumblerNoWrapReversedOrder + + Tumbler { + model: 5 + wrap: false + currentIndex: 2 + visibleItemCount: 3 + } + } + + Component { + id: negativeCurrentIndexTumblerNoWrap + + Tumbler { + model: 5 + wrap: false + currentIndex: -1 + visibleItemCount: 3 + } + } + + Component { + id: currentIndexTooLargeTumbler + + Tumbler { + objectName: "currentIndexTooLargeTumbler" + model: 10 + currentIndex: 10 + } + } + + + function test_currentIndexAtCreation_data() { + return [ + { tag: "wrap: implicit, expected currentIndex: 2", currentIndex: 2, wrap: true, component: currentIndexTumbler }, + { tag: "wrap: false, expected currentIndex: 2", currentIndex: 2, wrap: false, component: currentIndexTumblerNoWrap }, + // Order of property assignments shouldn't matter + { tag: "wrap: false, expected currentIndex: 2, reversed property assignment order", + currentIndex: 2, wrap: false, component: currentIndexTumblerNoWrapReversedOrder }, + { tag: "wrap: false, expected currentIndex: 0", currentIndex: 0, wrap: false, component: negativeCurrentIndexTumblerNoWrap }, + { tag: "wrap: implicit, expected currentIndex: 0", currentIndex: 0, wrap: true, component: currentIndexTooLargeTumbler } + ] + } + + function test_currentIndexAtCreation(data) { + // Test setting currentIndex at creation time + tumbler = createTemporaryObject(data.component, testCase); + verify(tumbler); + // A "statically declared" currentIndex will be pending until the count has changed, + // which happens when the model is set, which happens on the TumblerView's next polish. + tryCompare(tumbler, "currentIndex", data.currentIndex); + + tumblerView = findView(tumbler); + tryVerify(function() { return tumblerView.currentItem }); + compare(tumblerView.currentIndex, data.currentIndex); + compare(tumblerView.currentItem.text, data.currentIndex.toString()); + + if (data.wrap) { + tryCompare(tumblerView, "offset", data.currentIndex > 0 ? tumblerView.count - data.currentIndex : 0); + } else { + tryCompare(tumblerView, "contentY", tumblerDelegateHeight * data.currentIndex - tumblerView.preferredHighlightBegin); + } + } + + function test_keyboardNavigation() { + createTumbler(); + + tumbler.model = 5; + tumbler.forceActiveFocus(); + tumblerView.highlightMoveDuration = 0; + + // Navigate upwards through entire wheel. + for (var j = 0; j < tumbler.count - 1; ++j) { + keyClick(Qt.Key_Up, Qt.NoModifier); + tryCompare(tumblerView, "offset", j + 1); + compare(tumbler.currentIndex, tumbler.count - 1 - j); + } + + keyClick(Qt.Key_Up, Qt.NoModifier); + tryCompare(tumblerView, "offset", 0); + compare(tumbler.currentIndex, 0); + + // Navigate downwards through entire wheel. + for (j = 0; j < tumbler.count - 1; ++j) { + keyClick(Qt.Key_Down, Qt.NoModifier); + tryCompare(tumblerView, "offset", tumbler.count - 1 - j); + compare(tumbler.currentIndex, j + 1); + } + + keyClick(Qt.Key_Down, Qt.NoModifier); + tryCompare(tumblerView, "offset", 0); + compare(tumbler.currentIndex, 0); + } + + function test_itemsCorrectlyPositioned() { + createTumbler(); + + tumbler.model = 4; + tumbler.height = 120; + compare(tumblerDelegateHeight, 40); + checkItemSizes(); + + wait(tumblerView.highlightMoveDuration); + var firstItemCenterPos = itemCenterPos(1); + var firstItem = tumblerView.itemAt(firstItemCenterPos.x, firstItemCenterPos.y); + var actualPos = testCase.mapFromItem(firstItem, 0, 0); + compare(actualPos.x, tumbler.leftPadding); + compare(actualPos.y, tumbler.topPadding + 40); + + tumbler.forceActiveFocus(); + keyClick(Qt.Key_Down); + tryCompare(tumblerView, "offset", 3.0); + tryCompare(tumbler, "moving", false); + firstItemCenterPos = itemCenterPos(0); + firstItem = tumblerView.itemAt(firstItemCenterPos.x, firstItemCenterPos.y); + verify(firstItem); + // Test QTBUG-40298. + actualPos = testCase.mapFromItem(firstItem, 0, 0); + fuzzyCompare(actualPos.x, tumbler.leftPadding, 0.0001); + fuzzyCompare(actualPos.y, tumbler.topPadding, 0.0001); + + var secondItemCenterPos = itemCenterPos(1); + var secondItem = tumblerView.itemAt(secondItemCenterPos.x, secondItemCenterPos.y); + verify(secondItem); + verify(firstItem.y < secondItem.y); + + var thirdItemCenterPos = itemCenterPos(2); + var thirdItem = tumblerView.itemAt(thirdItemCenterPos.x, thirdItemCenterPos.y); + verify(thirdItem); + verify(firstItem.y < thirdItem.y); + verify(secondItem.y < thirdItem.y); + } + + function test_focusPastTumbler() { + tumbler = createTemporaryObject(tumblerComponent, testCase); + verify(tumbler); + + var mouseArea = createTemporaryQmlObject( + "import QtQuick; TextInput { activeFocusOnTab: true; width: 50; height: 50 }", testCase, ""); + + tumbler.forceActiveFocus(); + verify(tumbler.activeFocus); + + keyClick(Qt.Key_Tab); + verify(!tumbler.activeFocus); + verify(mouseArea.activeFocus); + } + + function test_datePicker() { + var component = Qt.createComponent("TumblerDatePicker.qml"); + compare(component.status, Component.Ready, component.errorString()); + tumbler = createTemporaryObject(component, testCase); + // Should not be any warnings. + + tryCompare(tumbler.dayTumbler, "currentIndex", 0); + compare(tumbler.dayTumbler.count, 31); + compare(tumbler.monthTumbler.currentIndex, 0); + compare(tumbler.monthTumbler.count, 12); + compare(tumbler.yearTumbler.currentIndex, 0); + tryCompare(tumbler.yearTumbler, "count", 100); + + verify(findView(tumbler.dayTumbler).children.length >= tumbler.dayTumbler.visibleItemCount); + verify(findView(tumbler.monthTumbler).children.length >= tumbler.monthTumbler.visibleItemCount); + // TODO: do this properly somehow + wait(100); + verify(findView(tumbler.yearTumbler).children.length >= tumbler.yearTumbler.visibleItemCount); + + // March. + tumbler.monthTumbler.currentIndex = 2; + tryCompare(tumbler.monthTumbler, "currentIndex", 2); + + // 30th of March. + tumbler.dayTumbler.currentIndex = 29; + tryCompare(tumbler.dayTumbler, "currentIndex", 29); + + // February. + tumbler.monthTumbler.currentIndex = 1; + tryCompare(tumbler.monthTumbler, "currentIndex", 1); + tryCompare(tumbler.dayTumbler, "currentIndex", 27); + } + + Component { + id: timePickerComponent + + Row { + property alias minuteTumbler: minuteTumbler + property alias amPmTumbler: amPmTumbler + + Tumbler { + id: minuteTumbler + currentIndex: 6 + model: 60 + width: 50 + height: 150 + } + + Tumbler { + id: amPmTumbler + model: ["AM", "PM"] + width: 50 + height: 150 + contentItem: ListView { + anchors.fill: parent + model: amPmTumbler.model + delegate: amPmTumbler.delegate + } + } + } + } + + function test_listViewTimePicker() { + var root = createTemporaryObject(timePickerComponent, testCase); + verify(root); + + mouseDrag(root.minuteTumbler, root.minuteTumbler.width / 2, root.minuteTumbler.height / 2, 0, 50); + // Shouldn't crash. + mouseDrag(root.amPmTumbler, root.amPmTumbler.width / 2, root.amPmTumbler.height / 2, 0, 50); + } + + function test_displacement_data() { + var data = [ + // At 0 offset, the first item is current. + { count: 6, index: 0, offset: 0, expectedDisplacement: 0 }, + { count: 6, index: 1, offset: 0, expectedDisplacement: -1 }, + { count: 6, index: 5, offset: 0, expectedDisplacement: 1 }, + // When we start to move the first item down, the second item above it starts to become current. + { count: 6, index: 0, offset: 0.25, expectedDisplacement: -0.25 }, + { count: 6, index: 1, offset: 0.25, expectedDisplacement: -1.25 }, + { count: 6, index: 5, offset: 0.25, expectedDisplacement: 0.75 }, + { count: 6, index: 0, offset: 0.5, expectedDisplacement: -0.5 }, + { count: 6, index: 1, offset: 0.5, expectedDisplacement: -1.5 }, + { count: 6, index: 5, offset: 0.5, expectedDisplacement: 0.5 }, + // By this stage, the delegate at index 1 is destroyed, so we can't test its displacement. + { count: 6, index: 0, offset: 0.75, expectedDisplacement: -0.75 }, + { count: 6, index: 5, offset: 0.75, expectedDisplacement: 0.25 }, + { count: 6, index: 0, offset: 4.75, expectedDisplacement: 1.25 }, + { count: 6, index: 1, offset: 4.75, expectedDisplacement: 0.25 }, + { count: 6, index: 0, offset: 4.5, expectedDisplacement: 1.5 }, + { count: 6, index: 1, offset: 4.5, expectedDisplacement: 0.5 }, + { count: 6, index: 0, offset: 4.25, expectedDisplacement: 1.75 }, + { count: 6, index: 1, offset: 4.25, expectedDisplacement: 0.75 }, + // count == visibleItemCount + { count: 3, index: 0, offset: 0, expectedDisplacement: 0 }, + { count: 3, index: 1, offset: 0, expectedDisplacement: -1 }, + { count: 3, index: 2, offset: 0, expectedDisplacement: 1 }, + // count < visibleItemCount + { count: 2, index: 0, offset: 0, expectedDisplacement: 0 }, + { count: 2, index: 1, offset: 0, expectedDisplacement: 1 }, + // count == 1 + { count: 1, index: 0, offset: 0, expectedDisplacement: 0 } + ]; + for (var i = 0; i < data.length; ++i) { + var row = data[i]; + row.tag = "delegate" + row.index + " offset=" + row.offset + " expectedDisplacement=" + row.expectedDisplacement; + } + return data; + } + + property Component displacementDelegate: Text { + objectName: "delegate" + index + text: modelData + opacity: 0.2 + Math.max(0, 1 - Math.abs(Tumbler.displacement)) * 0.8 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + Text { + text: parent.displacement.toFixed(2) + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + } + + property real displacement: Tumbler.displacement + } + + function test_displacement(data) { + createTumbler(); + + // TODO: test setting these in the opposite order (delegate after model + // doesn't seem to cause a change in delegates in PathView) + tumbler.wrap = true; + tumbler.delegate = displacementDelegate; + tumbler.model = data.count; + compare(tumbler.count, data.count); + + var delegate = findChild(tumblerView, "delegate" + data.index); + verify(delegate); + + tumblerView.offset = data.offset; + compare(delegate.displacement, data.expectedDisplacement); + + // test displacement after adding and removing items + } + + function test_wrap() { + createTumbler(); + + tumbler.model = 5; + compare(tumbler.count, 5); + + tumbler.currentIndex = 2; + compare(tumblerView.currentIndex, 2); + + tumbler.wrap = false; + tumblerView = findView(tumbler); + compare(tumbler.count, 5); + compare(tumbler.currentIndex, 2); + // Tumbler's count hasn't changed (the model hasn't changed), + // but the new view needs time to instantiate its items. + tryCompare(tumblerView, "count", 5); + compare(tumblerView.currentIndex, 2); + } + + Component { + id: twoItemTumbler + + Tumbler { + model: 2 + } + } + + Component { + id: tenItemTumbler + + Tumbler { + model: 10 + } + } + + function test_countWrap() { + tumbler = createTemporaryObject(tumblerComponent, testCase); + verify(tumbler); + + // Check that a count that is less than visibleItemCount results in wrap being set to false. + verify(2 < tumbler.visibleItemCount); + tumbler.model = 2; + compare(tumbler.count, 2); + compare(tumbler.wrap, false); + } + + function test_explicitlyNonwrapping() { + // Check that explicitly setting wrap to false works even when it was implicitly false. + var explicitlyNonWrapping = createTemporaryObject(twoItemTumbler, testCase); + verify(explicitlyNonWrapping); + tryCompare(explicitlyNonWrapping, "wrap", false); + + explicitlyNonWrapping.wrap = false; + // wrap shouldn't be set to true now that there are more items than there are visible ones. + verify(10 > explicitlyNonWrapping.visibleItemCount); + explicitlyNonWrapping.model = 10; + compare(explicitlyNonWrapping.wrap, false); + + // Test resetting wrap back to the default behavior. + explicitlyNonWrapping.wrap = undefined; + compare(explicitlyNonWrapping.wrap, true); + } + + function test_explicitlyWrapping() { + // Check that explicitly setting wrap to true works even when it was implicitly true. + var explicitlyWrapping = createTemporaryObject(tenItemTumbler, testCase); + verify(explicitlyWrapping); + compare(explicitlyWrapping.wrap, true); + + explicitlyWrapping.wrap = true; + // wrap shouldn't be set to false now that there are more items than there are visible ones. + explicitlyWrapping.model = 2; + compare(explicitlyWrapping.wrap, true); + + // Test resetting wrap back to the default behavior. + explicitlyWrapping.wrap = undefined; + compare(explicitlyWrapping.wrap, false); + } + + Component { + id: customListViewTumblerComponent + + Tumbler { + id: listViewTumbler + + contentItem: ListView { + anchors.fill: parent + model: listViewTumbler.model + delegate: listViewTumbler.delegate + + snapMode: ListView.SnapToItem + highlightRangeMode: ListView.StrictlyEnforceRange + preferredHighlightBegin: height / 2 - (height / listViewTumbler.visibleItemCount / 2) + preferredHighlightEnd: height / 2 + (height / listViewTumbler.visibleItemCount / 2) + clip: true + } + } + } + + Component { + id: customPathViewTumblerComponent + + Tumbler { + id: pathViewTumbler + + contentItem: PathView { + id: pathView + model: pathViewTumbler.model + delegate: pathViewTumbler.delegate + clip: true + pathItemCount: pathViewTumbler.visibleItemCount + 1 + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + dragMargin: width / 2 + + path: Path { + startX: pathView.width / 2 + startY: -pathView.delegateHeight / 2 + PathLine { + x: pathView.width / 2 + y: pathView.pathItemCount * pathView.delegateHeight - pathView.delegateHeight / 2 + } + } + + property real delegateHeight: pathViewTumbler.availableHeight / pathViewTumbler.visibleItemCount + } + } + } + + function test_customContentItemAtConstruction_data() { + return [ + { tag: "ListView", component: customListViewTumblerComponent }, + { tag: "PathView", component: customPathViewTumblerComponent } + ]; + } + + function test_customContentItemAtConstruction(data) { + var tumbler = createTemporaryObject(data.component, testCase); + // Shouldn't assert. + + tumbler.model = 5; + compare(tumbler.count, 5); + + tumbler.currentIndex = 2; + var tumblerView = findView(tumbler); + compare(tumblerView.currentIndex, 2); + + tumblerView.incrementCurrentIndex(); + compare(tumblerView.currentIndex, 3); + compare(tumbler.currentIndex, 3); + + // Shouldn't have any affect. + tumbler.wrap = false; + compare(tumbler.count, 5); + compare(tumblerView.currentIndex, 3); + compare(tumbler.currentIndex, 3); + } + + function findFirstDelegateWithText(view, text) { + var delegate = null; + var contentItem = view.hasOwnProperty("contentItem") ? view.contentItem : view; + for (var i = 0; i < contentItem.children.length && !delegate; ++i) { + var child = contentItem.children[i]; + if (child.hasOwnProperty("text") && child.text === text) + delegate = child; + } + return delegate; + } + + function test_customContentItemAfterConstruction_data() { + return [ + { tag: "ListView", componentPath: "TumblerListView.qml" }, + { tag: "PathView", componentPath: "TumblerPathView.qml" } + ]; + } + + function test_customContentItemAfterConstruction(data) { + createTumbler(); + + tumbler.model = 5; + compare(tumbler.count, 5); + + tumbler.currentIndex = 2; + compare(tumblerView.currentIndex, 2); + + var contentItemComponent = Qt.createComponent(data.componentPath); + compare(contentItemComponent.status, Component.Ready); + + var customContentItem = createTemporaryObject(contentItemComponent, tumbler); + tumbler.contentItem = customContentItem; + compare(tumbler.count, 5); + tumblerView = findView(tumbler); + compare(tumblerView.currentIndex, 2); + + var delegate = findFirstDelegateWithText(tumblerView, "Custom2"); + verify(delegate); + compare(delegate.height, defaultImplicitDelegateHeight); + tryCompare(delegate.Tumbler, "displacement", 0); + + tumblerView.incrementCurrentIndex(); + compare(tumblerView.currentIndex, 3); + compare(tumbler.currentIndex, 3); + } + + function test_displacementListView_data() { + var offset = defaultListViewTumblerOffset; + + var data = [ + // At 0 contentY, the first item is current. + { contentY: offset, expectedDisplacements: [ + { index: 0, displacement: 0 }, + { index: 1, displacement: -1 }, + { index: 2, displacement: -2 } ] + }, + // When we start to move the first item down, the second item above it starts to become current. + { contentY: offset + defaultImplicitDelegateHeight * 0.25, expectedDisplacements: [ + { index: 0, displacement: 0.25 }, + { index: 1, displacement: -0.75 }, + { index: 2, displacement: -1.75 } ] + }, + { contentY: offset + defaultImplicitDelegateHeight * 0.5, expectedDisplacements: [ + { index: 0, displacement: 0.5 }, + { index: 1, displacement: -0.5 }, + { index: 2, displacement: -1.5 } ] + }, + { contentY: offset + defaultImplicitDelegateHeight * 0.75, expectedDisplacements: [ + { index: 0, displacement: 0.75 }, + { index: 1, displacement: -0.25 } ] + }, + { contentY: offset + defaultImplicitDelegateHeight * 3.5, expectedDisplacements: [ + { index: 3, displacement: 0.5 }, + { index: 4, displacement: -0.5 } ] + } + ]; + for (var i = 0; i < data.length; ++i) { + var row = data[i]; + row.tag = "contentY=" + row.contentY; + } + return data; + } + + function test_displacementListView(data) { + createTumbler(); + + tumbler.wrap = false; + tumbler.delegate = displacementDelegate; + tumbler.model = 5; + compare(tumbler.count, 5); + // Ensure assumptions about the tumbler used in our data() function are correct. + tumblerView = findView(tumbler); + compare(tumblerView.contentY, -defaultImplicitDelegateHeight); + var delegateCount = 0; + var listView = tumblerView; + var listViewContentItem = tumblerView.contentItem; + + // We use the mouse instead of setting contentY directly, otherwise the + // items snap back into place. This doesn't seem to be an issue for + // PathView for some reason. + // + // I tried lots of things to get this test to work with small changes + // in ListView's contentY (to match the tests for a PathView-based Tumbler), but they didn't work: + // + // - Pressing once and then directly moving the mouse to the correct location + // - Pressing once and interpolating the mouse position to the correct location + // - Pressing once and doing some dragging up and down to trigger the + // overThreshold of QQuickFlickable + // + // Even after the last item above, QQuickFlickable wouldn't consider it a drag. + // It seems that overThreshold is set too late, and because the drag distance is quite small + // to begin with, nothing changes (the displacement was always very close to 0 in the end). + + // Ensure that we at least cover the distance required to reach the desired contentY. + var distanceToReachContentY = data.contentY - defaultListViewTumblerOffset; + var distance = Math.abs(distanceToReachContentY) + tumbler.height / 2; + // If distanceToReachContentY is 0, we're testing 0 displacement, so we don't need to do anything. + if (distanceToReachContentY != 0) { + mousePress(tumbler, tumblerXCenter(), tumblerYCenter()); + + var dragDirection = distanceToReachContentY > 0 ? -1 : 1; + for (var i = 0; i < distance && Math.floor(listView.contentY) !== Math.floor(data.contentY); ++i) { + mouseMove(tumbler, tumblerXCenter(), tumblerYCenter() + i * dragDirection); + wait(1); // because Flickable pays attention to velocity, we need some time between movements (qtdeclarative ebf07c3) + } + } + + for (var i = 0; i < data.expectedDisplacements.length; ++i) { + var delegate = findChild(listViewContentItem, "delegate" + data.expectedDisplacements[i].index); + verify(delegate); + compare(delegate.height, defaultImplicitDelegateHeight); + // Due to the way we must perform this test, we can't expect high precision. + var expectedDisplacement = data.expectedDisplacements[i].displacement; + fuzzyCompare(delegate.displacement, expectedDisplacement, 0.1, + "Delegate of ListView-based Tumbler at index " + data.expectedDisplacements[i].index + + " has displacement of " + delegate.displacement + " when it should be " + expectedDisplacement); + } + + if (distanceToReachContentY != 0) + mouseRelease(tumbler, tumblerXCenter(), itemCenterPos(1) + (data.contentY - defaultListViewTumblerOffset), Qt.LeftButton); + } + + function test_listViewFlickAboveBounds_data() { + // Tests that flicking above the bounds when already at the top of the + // tumbler doesn't result in an incorrect displacement. + var data = []; + // Less than two items doesn't make sense. The default visibleItemCount + // is 3, so we test a bit more than double that. + for (var i = 2; i <= 7; ++i) { + data.push({ tag: i + " items", model: i }); + } + return data; + } + + function test_listViewFlickAboveBounds(data) { + createTumbler(); + + tumbler.wrap = false; + tumbler.delegate = displacementDelegate; + tumbler.model = data.model; + tumblerView = findView(tumbler); + + mousePress(tumbler, tumblerXCenter(), tumblerYCenter()); + + // Ensure it's stationary. + var listView = tumblerView; + compare(listView.contentY, defaultListViewTumblerOffset); + + // We could just move up until the contentY changed, but this is safer. + var distance = tumbler.height; + var changed = false; + + for (var i = 0; i < distance && !changed; ++i) { + mouseMove(tumbler, tumblerXCenter(), tumblerYCenter() + i, 10); + + // Don't test until the contentY has actually changed. + if (Math.abs(listView.contentY) - listView.preferredHighlightBegin > 0.01) { + + for (var delegateIndex = 0; delegateIndex < Math.min(tumbler.count, tumbler.visibleItemCount); ++delegateIndex) { + var delegate = findChild(listView.contentItem, "delegate" + delegateIndex); + verify(delegate); + + verify(delegate.displacement <= -delegateIndex, "Delegate at index " + delegateIndex + " has a displacement of " + + delegate.displacement + " when it should be less than or equal to " + -delegateIndex); + verify(delegate.displacement > -delegateIndex - 0.1, "Delegate at index 0 has a displacement of " + + delegate.displacement + " when it should be greater than ~ " + -delegateIndex - 0.1); + } + + changed = true; + } + } + + // Sanity check that something was actually tested. + verify(changed); + + mouseRelease(tumbler, tumblerXCenter(), tumbler.topPadding); + } + + property Component objectNameDelegate: Text { + objectName: "delegate" + index + text: modelData + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + function test_visibleItemCount_data() { + var data = [ + // e.g. {0: 2} = {delegate index: y pos / delegate height} + // Skip item at index 3, because it's out of view. + { model: 6, visibleItemCount: 5, expectedYPositions: {0: 2, 1: 3, 2: 4, 4: 0} }, + { model: 5, visibleItemCount: 3, expectedYPositions: {0: 1, 1: 2, 4: 0} }, + // Takes up the whole view. + { model: 2, visibleItemCount: 1, expectedYPositions: {0: 0} }, + ]; + + for (var i = 0; i < data.length; ++i) { + data[i].tag = "items=" + data[i].model + ", visibleItemCount=" + data[i].visibleItemCount; + } + return data; + } + + function test_visibleItemCount(data) { + createTumbler(); + + tumbler.delegate = objectNameDelegate; + tumbler.visibleItemCount = data.visibleItemCount; + + tumbler.model = data.model; + compare(tumbler.count, data.model); + + for (var delegateIndex = 0; delegateIndex < data.visibleItemCount; ++delegateIndex) { + if (data.expectedYPositions.hasOwnProperty(delegateIndex)) { + var delegate = findChild(tumblerView, "delegate" + delegateIndex); + verify(delegate, "Delegate found at index " + delegateIndex); + var expectedYPos = data.expectedYPositions[delegateIndex] * tumblerDelegateHeight; + compare(delegate.mapToItem(tumbler.contentItem, 0, 0).y, expectedYPos); + } + } + } + + property Component wrongDelegateTypeComponent: QtObject { + property real displacement: Tumbler.displacement + } + + property Component noParentDelegateComponent: Item { + property real displacement: Tumbler.displacement + } + + function test_attachedProperties() { + tumbler = createTemporaryObject(tumblerComponent, testCase); + verify(tumbler); + + // TODO: crashes somewhere in QML's guts +// tumbler.model = 5; +// tumbler.delegate = wrongDelegateTypeComponent; +// ignoreWarning("Attached properties of Tumbler must be accessed from within a delegate item"); +// // Cause displacement to be changed. The warning isn't triggered if we don't do this. +// tumbler.contentItem.offset += 1; + + ignoreWarning(/.*Tumbler: attached properties must be accessed through a delegate item that has a parent/); + createTemporaryObject(noParentDelegateComponent, null); + + ignoreWarning(/.*Tumbler: attempting to access attached property on item without an \"index\" property/); + var object = createTemporaryObject(noParentDelegateComponent, testCase); + verify(object); + } + + property Component paddingDelegate: Text { + objectName: "delegate" + index + text: modelData + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + Rectangle { + anchors.fill: parent + color: "transparent" + border.color: "red" + border.width: 1 + } + } + + function test_padding_data() { + var data = []; + + data.push({ padding: 0 }); + data.push({ padding: 10 }); + data.push({ left: 10, top: 10 }); + data.push({ right: 10, bottom: 10 }); + + for (var i = 0; i < data.length; ++i) { + var tag = ""; + + if (data[i].padding !== undefined) + tag += "padding: " + data[i].padding + " "; + if (data[i].left !== undefined) + tag += "left: " + data[i].left + " "; + if (data[i].right !== undefined) + tag += "right: " + data[i].right + " "; + if (data[i].top !== undefined) + tag += "top: " + data[i].top + " "; + if (data[i].bottom !== undefined) + tag += "bottom: " + data[i].bottom + " "; + tag = tag.slice(0, -1); + + data[i].tag = tag; + } + + return data; + } + + function test_padding(data) { + createTumbler(); + + tumbler.delegate = paddingDelegate; + tumbler.model = 5; + compare(tumbler.padding, 0); + compare(tumbler.leftPadding, 0); + compare(tumbler.rightPadding, 0); + compare(tumbler.topPadding, 0); + compare(tumbler.bottomPadding, 0); + compare(tumbler.contentItem.x, 0); + compare(tumbler.contentItem.y, 0); + + if (data.padding !== undefined) + tumbler.padding = data.padding; + if (data.left !== undefined) + tumbler.leftPadding = data.left; + if (data.right !== undefined) + tumbler.rightPadding = data.right; + if (data.top !== undefined) + tumbler.topPadding = data.top; + if (data.bottom !== undefined) + tumbler.bottomPadding = data.bottom; + + compare(tumbler.availableWidth, tumbler.implicitWidth - tumbler.leftPadding - tumbler.rightPadding); + compare(tumbler.availableHeight, tumbler.implicitHeight - tumbler.topPadding - tumbler.bottomPadding); + compare(tumbler.contentItem.x, tumbler.leftPadding); + compare(tumbler.contentItem.y, tumbler.topPadding); + + var pathView = tumbler.contentItem; + var expectedDelegateHeight = tumbler.availableHeight / tumbler.visibleItemCount; + var itemIndicesInVisualOrder = [4, 0, 1]; + for (var i = 0; i < itemIndicesInVisualOrder.length; ++i) { + var delegate = findChild(pathView, "delegate" + itemIndicesInVisualOrder[i]); + verify(delegate, "Couldn't find delegate at index " + itemIndicesInVisualOrder[i] + + " (iteration " + i + " out of " + (pathView.children.length - 1) + ")"); + + compare(delegate.width, tumbler.availableWidth); + compare(delegate.height, expectedDelegateHeight); + + var expectedY = tumbler.topPadding + i * expectedDelegateHeight; + var mappedPos = delegate.mapToItem(null, delegate.width / 2, 0); + fuzzyCompare(mappedPos.y, expectedY, 0.5, + "Tumbler's PathView delegate at index " + itemIndicesInVisualOrder[i] + + " should have a y pos of " + expectedY + ", but it's actually " + mappedPos.y.toFixed(20)); + + var expectedX = tumbler.leftPadding; + compare(delegate.mapToItem(null, 0, 0).x, expectedX, + "Tumbler's PathView delegate at index " + itemIndicesInVisualOrder[i] + + " should have a x pos of " + expectedX + ", but it's actually " + mappedPos.x.toFixed(20)); + } + + // Force new items to be created, as there was a bug where the path was correct until this happened. + compare(tumblerView.offset, 0); + ++tumbler.currentIndex; + tryCompare(tumblerView, "offset", 4, tumblerView.highlightMoveDuration * 2); + } + + function test_moving_data() { + return [ + { tag: "wrap:true", wrap: true }, + { tag: "wrap:false", wrap: false } + ] + } + + function test_moving(data) { + createTumbler({wrap: data.wrap, model: 5}) + compare(tumbler.wrap, data.wrap) + compare(tumbler.moving, false) + + waitForRendering(tumbler) + + mousePress(tumbler, tumbler.width / 2, tumbler.height / 2, Qt.LeftButton) + compare(tumbler.moving, false) + + for (var y = tumbler.height / 2; y >= tumbler.height / 4; y -= 10) + mouseMove(tumbler, tumbler.width / 2, y, 1) + compare(tumbler.moving, true) + + mouseRelease(tumbler, tumbler.width / 2, tumbler.height / 4, Qt.LeftButton) + compare(tumbler.moving, true) + tryCompare(tumbler, "moving", false) + } + + Component { + id: qtbug61374Component + + Row { + property alias tumbler: tumbler + property alias label: label + + Component.onCompleted: { + tumbler.currentIndex = 2 + } + + Tumbler { + id: tumbler + model: 5 + // ... + } + + Label { + id: label + text: tumbler.currentItem.text + } + } + } + + function test_qtbug61374() { + var row = createTemporaryObject(qtbug61374Component, testCase); + verify(row); + + var tumbler = row.tumbler; + tryCompare(tumbler, "currentIndex", 2); + + tumblerView = findView(tumbler); + + var label = row.label; + compare(label.text, "2"); + } + + function test_positionViewAtIndex_data() { + return [ + // Should be 20, 21, ... but there is a documented limitation for this in positionViewAtIndex()'s docs. + { tag: "wrap=true, mode=Beginning", wrap: true, mode: Tumbler.Beginning, expectedVisibleIndices: [21, 22, 23, 24, 25] }, + { tag: "wrap=true, mode=Center", wrap: true, mode: Tumbler.Center, expectedVisibleIndices: [18, 19, 20, 21, 22] }, + { tag: "wrap=true, mode=End", wrap: true, mode: Tumbler.End, expectedVisibleIndices: [16, 17, 18, 19, 20] }, + // Same as Beginning; should start at 20. + { tag: "wrap=true, mode=Contain", wrap: true, mode: Tumbler.Contain, expectedVisibleIndices: [21, 22, 23, 24, 25] }, + { tag: "wrap=true, mode=SnapPosition", wrap: true, mode: Tumbler.SnapPosition, expectedVisibleIndices: [18, 19, 20, 21, 22] }, + { tag: "wrap=false, mode=Beginning", wrap: false, mode: Tumbler.Beginning, expectedVisibleIndices: [20, 21, 22, 23, 24] }, + { tag: "wrap=false, mode=Center", wrap: false, mode: Tumbler.Center, expectedVisibleIndices: [18, 19, 20, 21, 22] }, + { tag: "wrap=false, mode=End", wrap: false, mode: Tumbler.End, expectedVisibleIndices: [16, 17, 18, 19, 20] }, + { tag: "wrap=false, mode=Visible", wrap: false, mode: Tumbler.Visible, expectedVisibleIndices: [16, 17, 18, 19, 20] }, + { tag: "wrap=false, mode=Contain", wrap: false, mode: Tumbler.Contain, expectedVisibleIndices: [16, 17, 18, 19, 20] }, + { tag: "wrap=false, mode=SnapPosition", wrap: false, mode: Tumbler.SnapPosition, expectedVisibleIndices: [18, 19, 20, 21, 22] } + ] + } + + function test_positionViewAtIndex(data) { + createTumbler({ wrap: data.wrap, model: 40, visibleItemCount: 5 }) + compare(tumbler.wrap, data.wrap) + + waitForRendering(tumbler) + + tumbler.positionViewAtIndex(20, data.mode) + tryCompare(tumbler, "moving", false) + + compare(tumbler.visibleItemCount, 5) + for (var i = 0; i < 5; ++i) { + // Find the item through its text, as that's easier than child/itemAt(). + var text = data.expectedVisibleIndices[i].toString() + var item = findDelegateWithText(tumblerView, text) + verify(item, "found no item with text \"" + text + "\"") + compare(item.text, data.expectedVisibleIndices[i].toString()) + + // Ensure that it's at the position we expect. + var expectedPos = itemTopLeftPos(i) + var actualPos = testCase.mapFromItem(item, 0, 0) + compare(actualPos.x, expectedPos.x, "expected delegate with text " + item.text + + " to have an x pos of " + expectedPos.x + " but it was " + actualPos.x) + compare(actualPos.y, expectedPos.y, "expected delegate with text " + item.text + + " to have an y pos of " + expectedPos.y + " but it was " + actualPos.y) + } + } + + Component { + id: setCurrentIndexOnImperativeModelChangeComponent + + Tumbler { + onModelChanged: currentIndex = model - 2 + } + } + + function test_setCurrentIndexOnImperativeModelChange() { + var tumbler = createTemporaryObject(setCurrentIndexOnImperativeModelChangeComponent, testCase); + verify(tumbler); + + tumbler.model = 4 + compare(tumbler.count, 4); + tumblerView = findView(tumbler); + tryCompare(tumblerView, "count", 4); + + // 4 - 2 = 2 + compare(tumbler.currentIndex, 2); + + ++tumbler.model; + compare(tumbler.count, 5); + compare(tumbler.wrap, true); + tumblerView = findView(tumbler); + tryCompare(tumblerView, "count", 5); + // 5 - 2 = 3 + compare(tumbler.currentIndex, 3); + } + + Component { + id: setCurrentIndexOnDeclarativeModelChangeComponent + + Item { + property alias tumbler: tumbler + + property int setting: 4 + + Tumbler { + id: tumbler + model: setting + onModelChanged: currentIndex = model - 2 + } + } + } + + function test_setCurrentIndexOnDeclarativeModelChange() { + var root = createTemporaryObject(setCurrentIndexOnDeclarativeModelChangeComponent, testCase); + verify(root); + + var tumbler = root.tumbler; + compare(tumbler.count, 4); + compare(tumbler.wrap, false); + tumblerView = findView(tumbler); + tryCompare(tumblerView, "count", 4); + // 4 - 2 = 2 + compare(tumbler.currentIndex, 2); + + ++root.setting; + compare(tumbler.count, 5); + compare(tumbler.wrap, true); + tumblerView = findView(tumbler); + tryCompare(tumblerView, "count", 5); + // 5 - 2 = 3 + compare(tumbler.currentIndex, 3); + } + + function test_displacementAfterResizing() { + createTumbler({ + width: 200, + wrap: false, + delegate: displacementDelegate, + model: 30, + visibleItemCount: 7, + currentIndex: 15 + }) + + var delegate = findChild(tumblerView, "delegate15") + verify(delegate) + + tryCompare(delegate, "displacement", 0) + + // Resizing the Tumbler shouldn't affect the displacement. + tumbler.height *= 1.4 + tryCompare(delegate, "displacement", 0) + } + + //QTBUG-84426 + Component { + id: initialCurrentIndexTumbler + + Tumbler { + anchors.centerIn: parent + width: 60 + height: 200 + delegate: Text {text: modelData} + model: 10 + currentIndex: 4 + } + } + + function test_initialCurrentIndex() { + var tumbler = createTemporaryObject(initialCurrentIndexTumbler, testCase, {wrap: true}); + compare(tumbler.currentIndex, 4); + tumbler = createTemporaryObject(initialCurrentIndexTumbler, testCase, {wrap: false}); + compare(tumbler.currentIndex, 4); + } + + // QTBUG-109995 + Component { + id: flickTumbler + Flickable { + width: 50 + height: 200 + interactive: true + contentHeight: 400 + property alias tumblerItem: noWrapTumbler + Tumbler { + id: noWrapTumbler + anchors.fill: parent + model: 20 + wrap: false + } + } + } + + function test_flick() { + let control = createTemporaryObject(flickTumbler, testCase) + verify(control) + + let tumbler = control.tumblerItem + compare(tumbler.count, 20) + compare(tumbler.wrap, false) + + let touch = touchEvent(tumbler) + let tumblerView = findView(tumbler) + let delegateHeight = tumblerView.children[0].children[0].height + + // Move delegates through touch operation and check the current index + touch.press(0, tumblerView, control.width / 2, control.height / 2).commit() + // Move slowly, otherwise its considered as flick which cause current index + // to be varied according to its velocity + var scrollOffset = control.height / 2 + for (; scrollOffset > delegateHeight / 2; scrollOffset-=5) { + touch.move(0, tumblerView, control.width / 2, scrollOffset).commit() + } + touch.release(0, tumblerView, control.width / 2, scrollOffset).commit() + tryCompare(tumblerView, "currentIndex", 2) + } +} diff --git a/tests/auto/quickcontrols2/controls/fusion/BLACKLIST b/tests/auto/quickcontrols2/controls/fusion/BLACKLIST new file mode 100644 index 00000000000..bdb2af0b464 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/fusion/BLACKLIST @@ -0,0 +1,10 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format + +# QTBUG-70597 +[Tumbler::test_itemsCorrectlyPositioned] +* + +# QTBUG-95750 +[RangeSlider::test_overlappingHandles] +b2qt +qnx diff --git a/tests/auto/quickcontrols2/controls/fusion/CMakeLists.txt b/tests/auto/quickcontrols2/controls/fusion/CMakeLists.txt new file mode 100644 index 00000000000..63817181035 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/fusion/CMakeLists.txt @@ -0,0 +1,40 @@ +# Generated from fusion.pro. + +##################################################################### +## tst_fusion Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_fusion + GUI + QMLTEST + SOURCES + tst_fusion.cpp + DEFINES + TST_CONTROLS_DATA=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../data\\\" + PUBLIC_LIBRARIES + Qt::Gui + Qt::QuickControls2 + Qt::QuickTemplates2 + TESTDATA ${test_data} +) + +# Make the QML files available to Creator's locator. +target_sources(tst_fusion + PRIVATE + ${test_data} +) + +set_source_files_properties(${test_data} + PROPERTIES + HEADER_FILE_ONLY ON +) + +#### Keys ignored in scope 1:.:.:fusion.pro:<TRUE>: +# OTHER_FILES = "$$PWD/../data/*.qml" +# TEMPLATE = "app" diff --git a/tests/auto/quickcontrols2/controls/fusion/dependencies.qml b/tests/auto/quickcontrols2/controls/fusion/dependencies.qml new file mode 100644 index 00000000000..f2e40e60594 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/fusion/dependencies.qml @@ -0,0 +1,6 @@ +import QtTest +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Fusion + +TestCase { } diff --git a/tests/auto/quickcontrols2/controls/fusion/dummy_imports.qml b/tests/auto/quickcontrols2/controls/fusion/dummy_imports.qml new file mode 100644 index 00000000000..580db56d124 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/fusion/dummy_imports.qml @@ -0,0 +1,12 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQml +import QtQuick +import QtQuick.NativeStyle +import QtQuick.Layouts +import Qt.labs.settings +import Qt.labs.qmlmodels + +QtObject { } diff --git a/tests/auto/quickcontrols2/controls/fusion/tst_fusion.cpp b/tests/auto/quickcontrols2/controls/fusion/tst_fusion.cpp new file mode 100644 index 00000000000..7528ccea2b1 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/fusion/tst_fusion.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTest/quicktest.h> +#include <QtQuickControls2/qquickstyle.h> + +int main(int argc, char *argv[]) +{ + QTEST_SET_MAIN_SOURCE_PATH + qputenv("QML_NO_TOUCH_COMPRESSION", "1"); + QQuickStyle::setStyle("Fusion"); + return quick_test_main(argc, argv, "tst_controls::Fusion", TST_CONTROLS_DATA); +} diff --git a/tests/auto/quickcontrols2/controls/imagine/BLACKLIST b/tests/auto/quickcontrols2/controls/imagine/BLACKLIST new file mode 100644 index 00000000000..72eebcd21dd --- /dev/null +++ b/tests/auto/quickcontrols2/controls/imagine/BLACKLIST @@ -0,0 +1,14 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format + +# QTBUG-70597 +[Tumbler::test_itemsCorrectlyPositioned] +* + +# QTBUG-95750 +[RangeSlider::test_overlappingHandles] +b2qt +qnx + +# QTBUG-101704 +[ToolTip::test_attachedSizeBug] +* diff --git a/tests/auto/quickcontrols2/controls/imagine/CMakeLists.txt b/tests/auto/quickcontrols2/controls/imagine/CMakeLists.txt new file mode 100644 index 00000000000..962628e1b64 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/imagine/CMakeLists.txt @@ -0,0 +1,40 @@ +# Generated from imagine.pro. + +##################################################################### +## tst_imagine Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_imagine + GUI + QMLTEST + SOURCES + tst_imagine.cpp + DEFINES + TST_CONTROLS_DATA=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../data\\\" + PUBLIC_LIBRARIES + Qt::Gui + Qt::QuickControls2 + Qt::QuickTemplates2 + TESTDATA ${test_data} +) + +# Make the QML files available to Creator's locator. +target_sources(tst_imagine + PRIVATE + ${test_data} +) + +set_source_files_properties(${test_data} + PROPERTIES + HEADER_FILE_ONLY ON +) + +#### Keys ignored in scope 1:.:.:imagine.pro:<TRUE>: +# OTHER_FILES = "$$PWD/../data/*.qml" +# TEMPLATE = "app" diff --git a/tests/auto/quickcontrols2/controls/imagine/dependencies.qml b/tests/auto/quickcontrols2/controls/imagine/dependencies.qml new file mode 100644 index 00000000000..9a31141bff7 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/imagine/dependencies.qml @@ -0,0 +1,6 @@ +import QtTest +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Imagine + +TestCase { } diff --git a/tests/auto/quickcontrols2/controls/imagine/dummy_imports.qml b/tests/auto/quickcontrols2/controls/imagine/dummy_imports.qml new file mode 100644 index 00000000000..580db56d124 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/imagine/dummy_imports.qml @@ -0,0 +1,12 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQml +import QtQuick +import QtQuick.NativeStyle +import QtQuick.Layouts +import Qt.labs.settings +import Qt.labs.qmlmodels + +QtObject { } diff --git a/tests/auto/quickcontrols2/controls/imagine/tst_imagine.cpp b/tests/auto/quickcontrols2/controls/imagine/tst_imagine.cpp new file mode 100644 index 00000000000..9db7ed4dc6a --- /dev/null +++ b/tests/auto/quickcontrols2/controls/imagine/tst_imagine.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTest/quicktest.h> +#include <QtQuickControls2/qquickstyle.h> + +int main(int argc, char *argv[]) +{ + QTEST_SET_MAIN_SOURCE_PATH + qputenv("QML_NO_TOUCH_COMPRESSION", "1"); + QQuickStyle::setStyle("Imagine"); + return quick_test_main(argc, argv, "tst_controls::Imagine", TST_CONTROLS_DATA); +} diff --git a/tests/auto/quickcontrols2/controls/macos/BLACKLIST b/tests/auto/quickcontrols2/controls/macos/BLACKLIST new file mode 100644 index 00000000000..3b77159dd27 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/macos/BLACKLIST @@ -0,0 +1,27 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format + +# QTBUG-95678 +# Blacklisted in order to get the native macOS style under +# regression control +[ComboBox::test_font] +* +[ComboBox::test_implicitContentWidthPolicy_WidestText] +* +[ComboBox::test_popup] +* +[ComboBox::test_implicitContentWidthPolicy_WidestTextWhenCompleted] +* +[Popup::test_font] +* +[ScrollBar::test_flashing] +* +[ScrollBar::test_policy] +* +[ScrollView::test_keys] +* +[Slider::test_snapMode_touch] +* +[TextArea::test_implicitSize] +* +[TextField::test_implicitSize] +* diff --git a/tests/auto/quickcontrols2/controls/material/BLACKLIST b/tests/auto/quickcontrols2/controls/material/BLACKLIST new file mode 100644 index 00000000000..bdb2af0b464 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/material/BLACKLIST @@ -0,0 +1,10 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format + +# QTBUG-70597 +[Tumbler::test_itemsCorrectlyPositioned] +* + +# QTBUG-95750 +[RangeSlider::test_overlappingHandles] +b2qt +qnx diff --git a/tests/auto/quickcontrols2/controls/material/CMakeLists.txt b/tests/auto/quickcontrols2/controls/material/CMakeLists.txt new file mode 100644 index 00000000000..b07a63e32d7 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/material/CMakeLists.txt @@ -0,0 +1,40 @@ +# Generated from material.pro. + +##################################################################### +## tst_material Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_material + GUI + QMLTEST + SOURCES + tst_material.cpp + DEFINES + TST_CONTROLS_DATA=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../data\\\" + PUBLIC_LIBRARIES + Qt::Gui + Qt::QuickControls2 + Qt::QuickTemplates2 + TESTDATA ${test_data} +) + +# Make the QML files available to Creator's locator. +target_sources(tst_material + PRIVATE + ${test_data} +) + +set_source_files_properties(${test_data} + PROPERTIES + HEADER_FILE_ONLY ON +) + +#### Keys ignored in scope 1:.:.:material.pro:<TRUE>: +# OTHER_FILES = "$$PWD/../data/*.qml" +# TEMPLATE = "app" diff --git a/tests/auto/quickcontrols2/controls/material/dependencies.qml b/tests/auto/quickcontrols2/controls/material/dependencies.qml new file mode 100644 index 00000000000..8bcf03013ce --- /dev/null +++ b/tests/auto/quickcontrols2/controls/material/dependencies.qml @@ -0,0 +1,6 @@ +import QtTest +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material + +TestCase { } diff --git a/tests/auto/quickcontrols2/controls/material/dummy_imports.qml b/tests/auto/quickcontrols2/controls/material/dummy_imports.qml new file mode 100644 index 00000000000..580db56d124 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/material/dummy_imports.qml @@ -0,0 +1,12 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQml +import QtQuick +import QtQuick.NativeStyle +import QtQuick.Layouts +import Qt.labs.settings +import Qt.labs.qmlmodels + +QtObject { } diff --git a/tests/auto/quickcontrols2/controls/material/tst_material.cpp b/tests/auto/quickcontrols2/controls/material/tst_material.cpp new file mode 100644 index 00000000000..ae8bb3a11ef --- /dev/null +++ b/tests/auto/quickcontrols2/controls/material/tst_material.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTest/quicktest.h> +#include <QtQuickControls2/qquickstyle.h> + +int main(int argc, char *argv[]) +{ + QTEST_SET_MAIN_SOURCE_PATH + qputenv("QML_NO_TOUCH_COMPRESSION", "1"); + QQuickStyle::setStyle("Material"); + return quick_test_main(argc, argv, "tst_controls::Material", TST_CONTROLS_DATA); +} diff --git a/tests/auto/quickcontrols2/controls/universal/BLACKLIST b/tests/auto/quickcontrols2/controls/universal/BLACKLIST new file mode 100644 index 00000000000..bdb2af0b464 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/universal/BLACKLIST @@ -0,0 +1,10 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format + +# QTBUG-70597 +[Tumbler::test_itemsCorrectlyPositioned] +* + +# QTBUG-95750 +[RangeSlider::test_overlappingHandles] +b2qt +qnx diff --git a/tests/auto/quickcontrols2/controls/universal/CMakeLists.txt b/tests/auto/quickcontrols2/controls/universal/CMakeLists.txt new file mode 100644 index 00000000000..0b3478a227a --- /dev/null +++ b/tests/auto/quickcontrols2/controls/universal/CMakeLists.txt @@ -0,0 +1,40 @@ +# Generated from universal.pro. + +##################################################################### +## tst_universal Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_universal + GUI + QMLTEST + SOURCES + tst_universal.cpp + DEFINES + TST_CONTROLS_DATA=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../data\\\" + PUBLIC_LIBRARIES + Qt::Gui + Qt::QuickControls2 + Qt::QuickTemplates2 + TESTDATA ${test_data} +) + +# Make the QML files available to Creator's locator. +target_sources(tst_universal + PRIVATE + ${test_data} +) + +set_source_files_properties(${test_data} + PROPERTIES + HEADER_FILE_ONLY ON +) + +#### Keys ignored in scope 1:.:.:universal.pro:<TRUE>: +# OTHER_FILES = "$$PWD/../data/*.qml" +# TEMPLATE = "app" diff --git a/tests/auto/quickcontrols2/controls/universal/dependencies.qml b/tests/auto/quickcontrols2/controls/universal/dependencies.qml new file mode 100644 index 00000000000..8ba71c83028 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/universal/dependencies.qml @@ -0,0 +1,6 @@ +import QtTest +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Universal + +TestCase { } diff --git a/tests/auto/quickcontrols2/controls/universal/dummy_imports.qml b/tests/auto/quickcontrols2/controls/universal/dummy_imports.qml new file mode 100644 index 00000000000..580db56d124 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/universal/dummy_imports.qml @@ -0,0 +1,12 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQml +import QtQuick +import QtQuick.NativeStyle +import QtQuick.Layouts +import Qt.labs.settings +import Qt.labs.qmlmodels + +QtObject { } diff --git a/tests/auto/quickcontrols2/controls/universal/tst_universal.cpp b/tests/auto/quickcontrols2/controls/universal/tst_universal.cpp new file mode 100644 index 00000000000..db5b560e019 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/universal/tst_universal.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTest/quicktest.h> +#include <QtQuickControls2/qquickstyle.h> + +int main(int argc, char *argv[]) +{ + QTEST_SET_MAIN_SOURCE_PATH + qputenv("QML_NO_TOUCH_COMPRESSION", "1"); + QQuickStyle::setStyle("Universal"); + return quick_test_main(argc, argv, "tst_controls::Universal", TST_CONTROLS_DATA); +} diff --git a/tests/auto/quickcontrols2/controls/windows/BLACKLIST b/tests/auto/quickcontrols2/controls/windows/BLACKLIST new file mode 100644 index 00000000000..476340700a0 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/windows/BLACKLIST @@ -0,0 +1,5 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format + +# QTBUG-70597 +[Tumbler::test_itemsCorrectlyPositioned] +* diff --git a/tests/auto/quickcontrols2/controls/windows/CMakeLists.txt b/tests/auto/quickcontrols2/controls/windows/CMakeLists.txt new file mode 100644 index 00000000000..c448c55d258 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/windows/CMakeLists.txt @@ -0,0 +1,29 @@ +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../data/tst_*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_windows + GUI + QMLTEST + SOURCES + tst_windows.cpp + DEFINES + TST_CONTROLS_DATA=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../data\\\" + PUBLIC_LIBRARIES + Qt::Gui + Qt::QuickControls2 + TESTDATA ${test_data} +) + +# Make the QML files available to Creator's locator. +target_sources(tst_windows + PRIVATE + ${test_data} +) + +set_source_files_properties(${test_data} + PROPERTIES + HEADER_FILE_ONLY ON +) diff --git a/tests/auto/quickcontrols2/controls/windows/dependencies.qml b/tests/auto/quickcontrols2/controls/windows/dependencies.qml new file mode 100644 index 00000000000..f7d87422b5d --- /dev/null +++ b/tests/auto/quickcontrols2/controls/windows/dependencies.qml @@ -0,0 +1,5 @@ +import QtTest +import QtQuick +import QtQuick.Controls + +TestCase { } diff --git a/tests/auto/quickcontrols2/controls/windows/tst_windows.cpp b/tests/auto/quickcontrols2/controls/windows/tst_windows.cpp new file mode 100644 index 00000000000..b4a187bca70 --- /dev/null +++ b/tests/auto/quickcontrols2/controls/windows/tst_windows.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTest/quicktest.h> +#include <QtQuickControls2/qquickstyle.h> + +int main(int argc, char *argv[]) +{ + QTEST_SET_MAIN_SOURCE_PATH + qputenv("QML_NO_TOUCH_COMPRESSION", "1"); + QQuickStyle::setStyle("Windows"); + return quick_test_main(argc, argv, "tst_controls::Windows", TST_CONTROLS_DATA); +} diff --git a/tests/auto/quickcontrols2/cursor/CMakeLists.txt b/tests/auto/quickcontrols2/cursor/CMakeLists.txt new file mode 100644 index 00000000000..4a8296a0e42 --- /dev/null +++ b/tests/auto/quickcontrols2/cursor/CMakeLists.txt @@ -0,0 +1,48 @@ +# Generated from cursor.pro. + +##################################################################### +## tst_cursor Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_cursor + SOURCES + tst_cursor.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:cursor.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_cursor CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_cursor CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/cursor/data/buttons.qml b/tests/auto/quickcontrols2/cursor/data/buttons.qml new file mode 100644 index 00000000000..eb7e27cfa4e --- /dev/null +++ b/tests/auto/quickcontrols2/cursor/data/buttons.qml @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +MouseArea { + width: column.width + height: column.height + cursorShape: Qt.ForbiddenCursor + + Column { + id: column + padding: 10 + spacing: 10 + + Button { + text: "Button" + } + CheckBox { + text: "CheckBox" + } + CheckDelegate { + text: "CheckDelegate" + } + ItemDelegate { + text: "ItemDelegate" + } + MenuItem { + text: "MenuItem" + } + RadioButton { + text: "RadioButton" + } + RadioDelegate { + text: "RadioDelegate" + } + RoundButton { + text: "X" + } + SwipeDelegate { + text: "SwipeDelegate" + } + Switch { + text: "Switch" + } + SwitchDelegate { + text: "SwitchDelegate" + } + TabButton { + text: "TabButton" + } + ToolButton { + text: "ToolButton" + } + } +} diff --git a/tests/auto/quickcontrols2/cursor/data/containers.qml b/tests/auto/quickcontrols2/cursor/data/containers.qml new file mode 100644 index 00000000000..0e72297111a --- /dev/null +++ b/tests/auto/quickcontrols2/cursor/data/containers.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +MouseArea { + width: column.width + height: column.height + cursorShape: Qt.ForbiddenCursor + + Column { + id: column + padding: 10 + spacing: 10 + + Page { + width: 200 + height: 20 + } + Pane { + width: 200 + height: 20 + } + ToolBar { + width: 200 + height: 20 + } + } +} diff --git a/tests/auto/quickcontrols2/cursor/data/editable.qml b/tests/auto/quickcontrols2/cursor/data/editable.qml new file mode 100644 index 00000000000..04bf4b7cb00 --- /dev/null +++ b/tests/auto/quickcontrols2/cursor/data/editable.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +MouseArea { + width: column.width + height: column.height + cursorShape: Qt.ForbiddenCursor + + Column { + id: column + padding: 10 + spacing: 10 + + ComboBox { + editable: true + model: "ComboBox" + } + SpinBox { + editable: true + } + } +} diff --git a/tests/auto/quickcontrols2/cursor/data/pageindicator.qml b/tests/auto/quickcontrols2/cursor/data/pageindicator.qml new file mode 100644 index 00000000000..f71fbf7563c --- /dev/null +++ b/tests/auto/quickcontrols2/cursor/data/pageindicator.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +MouseArea { + width: 200 + height: 200 + cursorShape: Qt.ForbiddenCursor + + PageIndicator { + anchors.centerIn: parent + } +} diff --git a/tests/auto/quickcontrols2/cursor/data/scrollbar.qml b/tests/auto/quickcontrols2/cursor/data/scrollbar.qml new file mode 100644 index 00000000000..997abd4b658 --- /dev/null +++ b/tests/auto/quickcontrols2/cursor/data/scrollbar.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias textArea: textArea + property alias scrollBar: scrollBar + + Flickable { + anchors.fill: parent + TextArea.flickable: TextArea { + id: textArea + } + ScrollBar.vertical: ScrollBar { + id: scrollBar + // Need to explicitly set this to account for platforms like Android, + // where the UiEffects style hint does not include HoverEffect, and + // hence QQuickControlPrivate::calcHoverEnabled() would otherwise return false. + hoverEnabled: true + } + } +} diff --git a/tests/auto/quickcontrols2/cursor/data/sliders.qml b/tests/auto/quickcontrols2/cursor/data/sliders.qml new file mode 100644 index 00000000000..687450ec051 --- /dev/null +++ b/tests/auto/quickcontrols2/cursor/data/sliders.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +MouseArea { + width: column.width + height: column.height + cursorShape: Qt.ForbiddenCursor + + Column { + id: column + padding: 10 + spacing: 10 + + Dial { + } + Slider { + } + RangeSlider { + } + } +} diff --git a/tests/auto/quickcontrols2/cursor/tst_cursor.cpp b/tests/auto/quickcontrols2/cursor/tst_cursor.cpp new file mode 100644 index 00000000000..d9f7f4cc4fb --- /dev/null +++ b/tests/auto/quickcontrols2/cursor/tst_cursor.cpp @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> + +#include <QtQuick/qquickview.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickpageindicator_p.h> +#include <QtQuickTemplates2/private/qquickscrollbar_p.h> +#include <QtQuickTemplates2/private/qquicktextarea_p.h> +#include <QtQuickControls2/qquickstyle.h> + +#if QT_CONFIG(cursor) +# include <QtGui/qscreen.h> +# include <QtGui/qcursor.h> +#endif + +using namespace QQuickControlsTestUtils; + +class tst_cursor : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_cursor(); + +private slots: + void init(); + void controls_data(); + void controls(); + void editable(); + void pageIndicator(); + void scrollBar(); +}; + +tst_cursor::tst_cursor() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ + QQuickStyle::setStyle("Basic"); +} + +void tst_cursor::init() +{ +#if QT_CONFIG(cursor) + // Ensure mouse cursor was not left by previous tests where widgets + // will appear, as it could cause events and interfere with the tests. + const QScreen *screen = QGuiApplication::primaryScreen(); + const QRect availableGeometry = screen->availableGeometry(); + QCursor::setPos(availableGeometry.topLeft()); +#endif +} + +void tst_cursor::controls_data() +{ + QTest::addColumn<QString>("testFile"); + + QTest::newRow("buttons") << "buttons.qml"; + QTest::newRow("containers") << "containers.qml"; + QTest::newRow("sliders") << "sliders.qml"; +} + +void tst_cursor::controls() +{ + QFETCH(QString, testFile); + + QQuickView view(testFileUrl(testFile)); + view.show(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickItem *mouseArea = view.rootObject(); + QVERIFY(mouseArea); + QCOMPARE(mouseArea->cursor().shape(), Qt::ForbiddenCursor); + + QQuickItem *column = mouseArea->childItems().value(0); + QVERIFY(column); + + const auto controls = column->childItems(); + for (QQuickItem *control : controls) { + QCOMPARE(control->cursor().shape(), Qt::ArrowCursor); + + QTest::mouseMove(&view, control->mapToScene(QPointF(-1, -1)).toPoint()); + QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor); + + QTest::mouseMove(&view, control->mapToScene(QPointF(0, 0)).toPoint()); + QCOMPARE(view.cursor().shape(), Qt::ArrowCursor); + + QTest::mouseMove(&view, control->mapToScene(QPointF(control->width() + 1, control->height() + 1)).toPoint()); + QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor); + } +} + +void tst_cursor::editable() +{ + QQuickView view(testFileUrl("editable.qml")); + view.show(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickItem *mouseArea = view.rootObject(); + QVERIFY(mouseArea); + QCOMPARE(mouseArea->cursor().shape(), Qt::ForbiddenCursor); + + QQuickItem *column = mouseArea->childItems().value(0); + QVERIFY(column); + + const auto children = column->childItems(); + for (QQuickItem *child : children) { + QQuickControl *control = qobject_cast<QQuickControl *>(child); + QVERIFY(control); + QCOMPARE(control->cursor().shape(), Qt::ArrowCursor); + QCOMPARE(control->contentItem()->cursor().shape(), Qt::IBeamCursor); + + QTest::mouseMove(&view, control->mapToScene(QPointF(-1, -1)).toPoint()); + QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor); + + QTest::mouseMove(&view, control->mapToScene(QPointF(control->width() / 2, control->height() / 2)).toPoint()); + QCOMPARE(view.cursor().shape(), Qt::IBeamCursor); + + control->setProperty("editable", false); + QCOMPARE(control->cursor().shape(), Qt::ArrowCursor); + QCOMPARE(control->contentItem()->cursor().shape(), Qt::ArrowCursor); + QCOMPARE(view.cursor().shape(), Qt::ArrowCursor); + + QTest::mouseMove(&view, control->mapToScene(QPointF(control->width() + 1, control->height() + 1)).toPoint()); + QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor); + } +} + +void tst_cursor::pageIndicator() +{ + QQuickView view(testFileUrl("pageindicator.qml")); + view.show(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickItem *mouseArea = view.rootObject(); + QVERIFY(mouseArea); + QCOMPARE(mouseArea->cursor().shape(), Qt::ForbiddenCursor); + + QQuickPageIndicator *indicator = qobject_cast<QQuickPageIndicator *>(mouseArea->childItems().value(0)); + QVERIFY(indicator); + + QTest::mouseMove(&view, indicator->mapToScene(QPointF(-1, -1)).toPoint()); + QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor); + + QTest::mouseMove(&view, indicator->mapToScene(QPointF(0, 0)).toPoint()); + QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor); + + indicator->setInteractive(true); + QCOMPARE(view.cursor().shape(), Qt::ArrowCursor); + + QTest::mouseMove(&view, indicator->mapToScene(QPointF(indicator->width() + 1, indicator->height() + 1)).toPoint()); + QCOMPARE(view.cursor().shape(), Qt::ForbiddenCursor); +} + +// QTBUG-59629 +void tst_cursor::scrollBar() +{ + // Ensure that the mouse cursor has the correct shape when over a scrollbar + // which is itself over a text area with IBeamCursor. + QQuickControlsApplicationHelper helper(this, QStringLiteral("scrollbar.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickScrollBar *scrollBar = helper.appWindow->property("scrollBar").value<QQuickScrollBar*>(); + QVERIFY(scrollBar); + + QQuickTextArea *textArea = helper.appWindow->property("textArea").value<QQuickTextArea*>(); + QVERIFY(textArea); + + textArea->setText(QString("\n").repeated(100)); + + const QPoint textAreaPos(window->width() / 2, window->height() / 2); + QTest::mouseMove(window, textAreaPos); + QCOMPARE(window->cursor().shape(), textArea->cursor().shape()); + QCOMPARE(textArea->cursor().shape(), Qt::CursorShape::IBeamCursor); + + const QPoint scrollBarPos(window->width() - scrollBar->width() / 2, window->height() / 2); + QTest::mouseMove(window, scrollBarPos); + + QVERIFY(scrollBar->isActive()); + QCOMPARE(window->cursor().shape(), scrollBar->cursor().shape()); + QCOMPARE(scrollBar->cursor().shape(), Qt::CursorShape::ArrowCursor); + + scrollBar->setInteractive(false); + QCOMPARE(window->cursor().shape(), textArea->cursor().shape()); +} + +QTEST_MAIN(tst_cursor) + +#include "tst_cursor.moc" diff --git a/tests/auto/quickcontrols2/customization/CMakeLists.txt b/tests/auto/quickcontrols2/customization/CMakeLists.txt new file mode 100644 index 00000000000..cf86185aca6 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/CMakeLists.txt @@ -0,0 +1,45 @@ +# Generated from customization.pro. + +##################################################################### +## tst_customization Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_customization + SOURCES + tst_customization.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_customization CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_customization CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/AbstractButton.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/AbstractButton.qml new file mode 100644 index 00000000000..b30d4a56289 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/AbstractButton.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.AbstractButton { + id: control + objectName: "abstractbutton-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/ApplicationWindow.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/ApplicationWindow.qml new file mode 100644 index 00000000000..6a1f1b098b0 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/ApplicationWindow.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ApplicationWindow { + id: control + objectName: "applicationwindow-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/BusyIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/BusyIndicator.qml new file mode 100644 index 00000000000..388de3af36a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/BusyIndicator.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.BusyIndicator { + id: control + objectName: "busyindicator-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Button.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Button.qml new file mode 100644 index 00000000000..20426d2edef --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Button.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Button { + id: control + objectName: "button-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/CheckBox.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/CheckBox.qml new file mode 100644 index 00000000000..3d8b5a8e098 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/CheckBox.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.CheckBox { + id: control + objectName: "checkbox-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/CheckDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/CheckDelegate.qml new file mode 100644 index 00000000000..a0547ec4187 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/CheckDelegate.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.CheckDelegate { + id: control + objectName: "checkdelegate-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/ComboBox.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/ComboBox.qml new file mode 100644 index 00000000000..84cf6e35e40 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/ComboBox.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ComboBox { + id: control + objectName: "combobox-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Container.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Container.qml new file mode 100644 index 00000000000..7519d7bd18d --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Container.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Container { + id: control + objectName: "container-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Control.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Control.qml new file mode 100644 index 00000000000..55a456c7645 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Control.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Control { + id: control + objectName: "control-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/DelayButton.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/DelayButton.qml new file mode 100644 index 00000000000..ce34f25f284 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/DelayButton.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.DelayButton { + id: control + objectName: "delaybutton-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Dial.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Dial.qml new file mode 100644 index 00000000000..de83e56400b --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Dial.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Dial { + id: control + objectName: "dial-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Dialog.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Dialog.qml new file mode 100644 index 00000000000..8b056a88335 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Dialog.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Dialog { + id: control + objectName: "dialog-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/DialogButtonBox.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/DialogButtonBox.qml new file mode 100644 index 00000000000..5ce5f504e11 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/DialogButtonBox.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.DialogButtonBox { + id: control + objectName: "dialogbuttonbox-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Drawer.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Drawer.qml new file mode 100644 index 00000000000..b4da57c000f --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Drawer.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Drawer { + id: control + objectName: "drawer-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Frame.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Frame.qml new file mode 100644 index 00000000000..00f4d79c7ae --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Frame.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Frame { + id: control + objectName: "frame-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/GroupBox.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/GroupBox.qml new file mode 100644 index 00000000000..900770cdba4 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/GroupBox.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.GroupBox { + id: control + objectName: "groupbox-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/ItemDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/ItemDelegate.qml new file mode 100644 index 00000000000..19de468d8a8 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/ItemDelegate.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ItemDelegate { + id: control + objectName: "itemdelegate-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Label.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Label.qml new file mode 100644 index 00000000000..bfc4a839666 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Label.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Label { + id: control + objectName: "label-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Menu.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Menu.qml new file mode 100644 index 00000000000..27b8a014312 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Menu.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Menu { + id: control + objectName: "menu-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/MenuBar.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/MenuBar.qml new file mode 100644 index 00000000000..24f7c6edf4e --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/MenuBar.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuBar { + id: control + objectName: "menubar-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/MenuBarItem.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/MenuBarItem.qml new file mode 100644 index 00000000000..d66e899a49a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/MenuBarItem.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuBarItem { + id: control + objectName: "menubaritem-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/MenuItem.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/MenuItem.qml new file mode 100644 index 00000000000..11f38a1b069 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/MenuItem.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuItem { + id: control + objectName: "menuitem-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/MenuSeparator.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/MenuSeparator.qml new file mode 100644 index 00000000000..effd32c0ed3 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/MenuSeparator.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuSeparator { + id: control + objectName: "menuseparator-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Page.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Page.qml new file mode 100644 index 00000000000..353fb9cc657 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Page.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Page { + id: control + objectName: "page-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/PageIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/PageIndicator.qml new file mode 100644 index 00000000000..98976ae255a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/PageIndicator.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.PageIndicator { + id: control + objectName: "pageindicator-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Pane.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Pane.qml new file mode 100644 index 00000000000..2429e2c6c1e --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Pane.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Pane { + id: control + objectName: "pane-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Popup.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Popup.qml new file mode 100644 index 00000000000..fdcb49ac8f2 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Popup.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Popup { + id: control + objectName: "popup-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/ProgressBar.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/ProgressBar.qml new file mode 100644 index 00000000000..a2afa03bc49 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/ProgressBar.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ProgressBar { + id: control + objectName: "progressbar-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/RadioButton.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/RadioButton.qml new file mode 100644 index 00000000000..87766292308 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/RadioButton.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RadioButton { + id: control + objectName: "radiobutton-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/RadioDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/RadioDelegate.qml new file mode 100644 index 00000000000..bbb711c7ed2 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/RadioDelegate.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RadioDelegate { + id: control + objectName: "radiodelegate-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/RangeSlider.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/RangeSlider.qml new file mode 100644 index 00000000000..0043b40775e --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/RangeSlider.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RangeSlider { + id: control + objectName: "rangeslider-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/RoundButton.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/RoundButton.qml new file mode 100644 index 00000000000..5b06801db8c --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/RoundButton.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RoundButton { + id: control + objectName: "roundbutton-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/ScrollBar.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/ScrollBar.qml new file mode 100644 index 00000000000..80a6782e34d --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/ScrollBar.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ScrollBar { + id: control + objectName: "scrollbar-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/ScrollIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/ScrollIndicator.qml new file mode 100644 index 00000000000..56c73cb8f4f --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/ScrollIndicator.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ScrollIndicator { + id: control + objectName: "scrollindicator-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/ScrollView.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/ScrollView.qml new file mode 100644 index 00000000000..198936c2b5a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/ScrollView.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ScrollView { + id: control + objectName: "scrollview-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Slider.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Slider.qml new file mode 100644 index 00000000000..6cfa3e919b7 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Slider.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Slider { + id: control + objectName: "slider-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/SpinBox.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/SpinBox.qml new file mode 100644 index 00000000000..9e334ecf35a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/SpinBox.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SpinBox { + id: control + objectName: "spinbox-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/StackView.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/StackView.qml new file mode 100644 index 00000000000..0a55abf812c --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/StackView.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.StackView { + id: control + objectName: "stackview-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/SwipeDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/SwipeDelegate.qml new file mode 100644 index 00000000000..d05f1e9c5cd --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/SwipeDelegate.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwipeDelegate { + id: control + objectName: "swipedelegate-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/SwipeView.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/SwipeView.qml new file mode 100644 index 00000000000..51b411aab9d --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/SwipeView.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwipeView { + id: control + objectName: "swipeview-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Switch.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Switch.qml new file mode 100644 index 00000000000..da00b0e8729 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Switch.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Switch { + id: control + objectName: "switch-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/SwitchDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/SwitchDelegate.qml new file mode 100644 index 00000000000..fe0a9f5222a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/SwitchDelegate.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwitchDelegate { + id: control + objectName: "switchdelegate-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/TabBar.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/TabBar.qml new file mode 100644 index 00000000000..0f38b66077a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/TabBar.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TabBar { + id: control + objectName: "tabbar-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/TabButton.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/TabButton.qml new file mode 100644 index 00000000000..6ee896366bc --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/TabButton.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TabButton { + id: control + objectName: "tabbutton-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/TextArea.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/TextArea.qml new file mode 100644 index 00000000000..e2ee786690e --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/TextArea.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TextArea { + id: control + objectName: "textarea-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/TextField.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/TextField.qml new file mode 100644 index 00000000000..3fcf63d5289 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/TextField.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TextField { + id: control + objectName: "textfield-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/ToolBar.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/ToolBar.qml new file mode 100644 index 00000000000..6696336d8f5 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/ToolBar.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolBar { + id: control + objectName: "toolbar-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/ToolButton.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/ToolButton.qml new file mode 100644 index 00000000000..8d4ef1b58a5 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/ToolButton.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolButton { + id: control + objectName: "toolbutton-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/ToolSeparator.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/ToolSeparator.qml new file mode 100644 index 00000000000..63985f7fdf7 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/ToolSeparator.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolSeparator { + id: control + objectName: "toolseparator-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/ToolTip.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/ToolTip.qml new file mode 100644 index 00000000000..a1aff94132b --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/ToolTip.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolTip { + id: control + objectName: "tooltip-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/Tumbler.qml b/tests/auto/quickcontrols2/customization/data/styles/empty/Tumbler.qml new file mode 100644 index 00000000000..c8b3bfebb76 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/Tumbler.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Tumbler { + id: control + objectName: "tumbler-empty" +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/empty/qmldir b/tests/auto/quickcontrols2/customization/data/styles/empty/qmldir new file mode 100644 index 00000000000..a5fcc4c7e55 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/empty/qmldir @@ -0,0 +1,59 @@ +module empty + +AbstractButton 6.0 AbstractButton.qml +Action 6.0 Action.qml +ActionGroup 6.0 ActionGroup.qml +ApplicationWindow 6.0 ApplicationWindow.qml +BusyIndicator 6.0 BusyIndicator.qml +Button 6.0 Button.qml +ButtonGroup 6.0 ButtonGroup.qml +CheckBox 6.0 CheckBox.qml +CheckDelegate 6.0 CheckDelegate.qml +ComboBox 6.0 ComboBox.qml +Container 6.0 Container.qml +Control 6.0 Control.qml +DelayButton 6.0 DelayButton.qml +Dial 6.0 Dial.qml +Dialog 6.0 Dialog.qml +DialogButtonBox 6.0 DialogButtonBox.qml +Drawer 6.0 Drawer.qml +Frame 6.0 Frame.qml +GroupBox 6.0 GroupBox.qml +HorizontalHeaderView 6.0 HorizontalHeaderView.qml +ItemDelegate 6.0 ItemDelegate.qml +Label 6.0 Label.qml +Menu 6.0 Menu.qml +MenuBar 6.0 MenuBar.qml +MenuBarItem 6.0 MenuBarItem.qml +MenuItem 6.0 MenuItem.qml +MenuSeparator 6.0 MenuSeparator.qml +Page 6.0 Page.qml +PageIndicator 6.0 PageIndicator.qml +Pane 6.0 Pane.qml +Popup 6.0 Popup.qml +ProgressBar 6.0 ProgressBar.qml +RadioButton 6.0 RadioButton.qml +RadioDelegate 6.0 RadioDelegate.qml +RangeSlider 6.0 RangeSlider.qml +RoundButton 6.0 RoundButton.qml +ScrollBar 6.0 ScrollBar.qml +ScrollIndicator 6.0 ScrollIndicator.qml +ScrollView 6.0 ScrollView.qml +Slider 6.0 Slider.qml +SpinBox 6.0 SpinBox.qml +SplitView 6.0 SplitView.qml +StackView 6.0 StackView.qml +SwipeDelegate 6.0 SwipeDelegate.qml +SwipeView 6.0 SwipeView.qml +Switch 6.0 Switch.qml +SwitchDelegate 6.0 SwitchDelegate.qml +TabBar 6.0 TabBar.qml +TabButton 6.0 TabButton.qml +TextArea 6.0 TextArea.qml +TextField 6.0 TextField.qml +ToolBar 6.0 ToolBar.qml +ToolButton 6.0 ToolButton.qml +ToolSeparator 6.0 ToolSeparator.qml +ToolTip 6.0 ToolTip.qml +Tumbler 6.0 Tumbler.qml +VerticalHeaderView 6.0 VerticalHeaderView.qml diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/AbstractButton.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/AbstractButton.qml new file mode 100644 index 00000000000..1c5bd31823f --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/AbstractButton.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.AbstractButton { + id: control + objectName: "abstractbutton-identified" + + indicator: Item { + id: indicator + objectName: "abstractbutton-indicator-identified" + Accessible.name: objectName + } + + contentItem: Item { + id: contentItem + objectName: "abstractbutton-contentItem-identified" + Accessible.name: objectName + } + + background: Item { + id: background + objectName: "abstractbutton-background-identified" + Accessible.name: objectName + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/ApplicationWindow.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/ApplicationWindow.qml new file mode 100644 index 00000000000..dc3f0db12c6 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/ApplicationWindow.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ApplicationWindow { + id: control + objectName: "applicationwindow-identified" + + background: Item { + id: background + objectName: "applicationwindow-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/BusyIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/BusyIndicator.qml new file mode 100644 index 00000000000..2deab679042 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/BusyIndicator.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.BusyIndicator { + id: control + objectName: "busyindicator-identified" + + contentItem: Item { + id: contentItem + objectName: "busyindicator-contentItem-identified" + } + + background: Item { + id: background + objectName: "busyindicator-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Button.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Button.qml new file mode 100644 index 00000000000..dc805080475 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Button.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Button { + id: control + objectName: "button-identified" + + contentItem: Item { + id: contentItem + objectName: "button-contentItem-identified" + } + + background: Item { + id: background + objectName: "button-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/CheckBox.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/CheckBox.qml new file mode 100644 index 00000000000..13f98af9b9b --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/CheckBox.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.CheckBox { + id: control + objectName: "checkbox-identified" + + indicator: Item { + id: indicator + objectName: "checkbox-indicator-identified" + } + + contentItem: Item { + id: contentItem + objectName: "checkbox-contentItem-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/CheckDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/CheckDelegate.qml new file mode 100644 index 00000000000..b0d8a8d2f7c --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/CheckDelegate.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.CheckDelegate { + id: control + objectName: "checkdelegate-identified" + + indicator: Item { + id: indicator + objectName: "checkdelegate-indicator-identified" + } + + contentItem: Item { + id: contentItem + objectName: "checkdelegate-contentItem-identified" + } + + background: Item { + id: background + objectName: "checkdelegate-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/ComboBox.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/ComboBox.qml new file mode 100644 index 00000000000..ff117ce8126 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/ComboBox.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Templates as T + +T.ComboBox { + id: control + objectName: "combobox-identified" + + indicator: Item { + id: indicator + objectName: "combobox-indicator-identified" + } + + contentItem: Item { + id: contentItem + objectName: "combobox-contentItem-identified" + } + + background: Item { + id: background + objectName: "combobox-background-identified" + } + + popup: T.Popup { + id: popup + objectName: "combobox-popup-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Container.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Container.qml new file mode 100644 index 00000000000..a282528d458 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Container.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Container { + id: control + objectName: "container-identified" + + contentItem: Item { + id: contentItem + objectName: "container-contentItem-identified" + } + + background: Item { + id: background + objectName: "container-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Control.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Control.qml new file mode 100644 index 00000000000..90229e4788c --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Control.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Control { + id: control + objectName: "control-identified" + + contentItem: Item { + id: contentItem + objectName: "control-contentItem-identified" + } + + background: Item { + id: background + objectName: "control-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/DelayButton.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/DelayButton.qml new file mode 100644 index 00000000000..90f980eaec3 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/DelayButton.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.DelayButton { + id: control + objectName: "delaybutton-identified" + + contentItem: Item { + id: contentItem + objectName: "delaybutton-contentItem-identified" + } + + background: Item { + id: background + objectName: "delaybutton-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Dial.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Dial.qml new file mode 100644 index 00000000000..9260972c956 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Dial.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Dial { + id: control + objectName: "dial-identified" + + handle: Item { + id: handle + objectName: "dial-handle-identified" + } + + background: Item { + id: background + objectName: "dial-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Dialog.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Dialog.qml new file mode 100644 index 00000000000..6392be7d7ba --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Dialog.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Dialog { + id: control + objectName: "dialog-identified" + + contentItem: Item { + id: contentItem + objectName: "dialog-contentItem-identified" + } + + background: Item { + id: background + objectName: "dialog-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/DialogButtonBox.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/DialogButtonBox.qml new file mode 100644 index 00000000000..11c596a1b0a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/DialogButtonBox.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.DialogButtonBox { + id: control + objectName: "dialogbuttonbox-identified" + + contentItem: Item { + id: contentItem + objectName: "dialogbuttonbox-contentItem-identified" + } + + background: Item { + id: background + objectName: "dialogbuttonbox-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Drawer.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Drawer.qml new file mode 100644 index 00000000000..6b340f2adbc --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Drawer.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Drawer { + id: control + objectName: "drawer-identified" + + contentItem: Item { + id: contentItem + objectName: "drawer-contentItem-identified" + } + + background: Item { + id: background + objectName: "drawer-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Frame.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Frame.qml new file mode 100644 index 00000000000..830ac584d04 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Frame.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Frame { + id: control + objectName: "frame-identified" + + contentItem: Item { + id: contentItem + objectName: "frame-contentItem-identified" + } + + background: Item { + id: background + objectName: "frame-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/GroupBox.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/GroupBox.qml new file mode 100644 index 00000000000..fffd44e8f6a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/GroupBox.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.GroupBox { + id: control + objectName: "groupbox-identified" + + label: Text { + id: label + objectName: "groupbox-label-identified" + } + + contentItem: Item { + id: contentItem + objectName: "groupbox-contentItem-identified" + } + + background: Item { + id: background + objectName: "groupbox-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/ItemDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/ItemDelegate.qml new file mode 100644 index 00000000000..b04d2f59e8a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/ItemDelegate.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ItemDelegate { + id: control + objectName: "itemdelegate-identified" + + contentItem: Item { + id: contentItem + objectName: "itemdelegate-contentItem-identified" + } + + background: Item { + id: background + objectName: "itemdelegate-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Label.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Label.qml new file mode 100644 index 00000000000..95d1f191802 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Label.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Label { + id: control + objectName: "label-identified" + + background: Item { + id: background + objectName: "label-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Menu.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Menu.qml new file mode 100644 index 00000000000..662392546bd --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Menu.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Menu { + id: control + objectName: "menu-identified" + + contentItem: Item { + id: contentItem + objectName: "menu-contentItem-identified" + } + + background: Item { + id: background + objectName: "menu-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/MenuBar.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/MenuBar.qml new file mode 100644 index 00000000000..f815b73fac1 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/MenuBar.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuBar { + id: control + objectName: "menubar-identified" + + contentItem: Item { + id: contentItem + objectName: "menubar-contentItem-identified" + } + + background: Item { + id: background + objectName: "menubar-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/MenuBarItem.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/MenuBarItem.qml new file mode 100644 index 00000000000..abf3be5db04 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/MenuBarItem.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuBarItem { + id: control + objectName: "menubaritem-identified" + + contentItem: Item { + id: contentItem + objectName: "menubaritem-contentItem-identified" + } + + background: Item { + id: background + objectName: "menubaritem-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/MenuItem.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/MenuItem.qml new file mode 100644 index 00000000000..3a174ecfa19 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/MenuItem.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuItem { + id: control + objectName: "menuitem-identified" + + arrow: Item { + id: arrow + objectName: "menuitem-arrow-identified" + } + + indicator: Item { + id: indicator + objectName: "menuitem-indicator-identified" + } + + contentItem: Item { + id: contentItem + objectName: "menuitem-contentItem-identified" + } + + background: Item { + id: background + objectName: "menuitem-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/MenuSeparator.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/MenuSeparator.qml new file mode 100644 index 00000000000..7ecb176b8cb --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/MenuSeparator.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuSeparator { + id: control + objectName: "menuseparator-identified" + + contentItem: Item { + id: contentItem + objectName: "menuseparator-contentItem-identified" + } + + background: Item { + id: background + objectName: "menuseparator-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Page.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Page.qml new file mode 100644 index 00000000000..b24162476fc --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Page.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Page { + id: control + objectName: "page-identified" + + contentItem: Item { + id: contentItem + objectName: "page-contentItem-identified" + } + + background: Item { + id: background + objectName: "page-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/PageIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/PageIndicator.qml new file mode 100644 index 00000000000..2370a334bf0 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/PageIndicator.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.PageIndicator { + id: control + objectName: "pageindicator-identified" + + contentItem: Item { + id: contentItem + objectName: "pageindicator-contentItem-identified" + } + + background: Item { + id: background + objectName: "pageindicator-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Pane.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Pane.qml new file mode 100644 index 00000000000..0dbf4b1c97b --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Pane.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Pane { + id: control + objectName: "pane-identified" + + contentItem: Item { + id: contentItem + objectName: "pane-contentItem-identified" + } + + background: Item { + id: background + objectName: "pane-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Popup.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Popup.qml new file mode 100644 index 00000000000..b6381170c13 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Popup.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Popup { + id: control + objectName: "popup-identified" + + contentItem: Item { + id: contentItem + objectName: "popup-contentItem-identified" + } + + background: Item { + id: background + objectName: "popup-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/ProgressBar.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/ProgressBar.qml new file mode 100644 index 00000000000..dc7d7658ef5 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/ProgressBar.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ProgressBar { + id: control + objectName: "progressbar-identified" + + contentItem: Item { + id: contentItem + objectName: "progressbar-contentItem-identified" + } + + background: Item { + id: background + objectName: "progressbar-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/RadioButton.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/RadioButton.qml new file mode 100644 index 00000000000..2b4a0b626c0 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/RadioButton.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RadioButton { + id: control + objectName: "radiobutton-identified" + + indicator: Item { + id: indicator + objectName: "radiobutton-indicator-identified" + } + + contentItem: Item { + id: contentItem + objectName: "radiobutton-contentItem-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/RadioDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/RadioDelegate.qml new file mode 100644 index 00000000000..75cda63d602 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/RadioDelegate.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RadioDelegate { + id: control + objectName: "radiodelegate-identified" + + indicator: Item { + id: indicator + objectName: "radiodelegate-indicator-identified" + } + + contentItem: Item { + id: contentItem + objectName: "radiodelegate-contentItem-identified" + } + + background: Item { + id: background + objectName: "radiodelegate-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/RangeSlider.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/RangeSlider.qml new file mode 100644 index 00000000000..fab56fcdc98 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/RangeSlider.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RangeSlider { + id: control + objectName: "rangeslider-identified" + + first.handle: Item { + id: firstHandle + objectName: "rangeslider-first.handle-identified" + } + + second.handle: Item { + id: secondHandle + objectName: "rangeslider-second.handle-identified" + } + + background: Item { + id: background + objectName: "rangeslider-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/RoundButton.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/RoundButton.qml new file mode 100644 index 00000000000..ec075db3146 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/RoundButton.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RoundButton { + id: control + objectName: "roundbutton-identified" + + contentItem: Item { + id: contentItem + objectName: "roundbutton-contentItem-identified" + } + + background: Item { + id: background + objectName: "roundbutton-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/ScrollBar.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/ScrollBar.qml new file mode 100644 index 00000000000..418f2908848 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/ScrollBar.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ScrollBar { + id: control + objectName: "scrollbar-identified" + + contentItem: Item { + id: contentItem + objectName: "scrollbar-contentItem-identified" + } + + background: Item { + id: background + objectName: "scrollbar-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/ScrollIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/ScrollIndicator.qml new file mode 100644 index 00000000000..b427b757d72 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/ScrollIndicator.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ScrollIndicator { + id: control + objectName: "scrollindicator-identified" + + contentItem: Item { + id: contentItem + objectName: "scrollindicator-contentItem-identified" + } + + background: Item { + id: background + objectName: "scrollindicator-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/ScrollView.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/ScrollView.qml new file mode 100644 index 00000000000..7f4e2c40793 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/ScrollView.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ScrollView { + id: control + objectName: "scrollview-identified" + + background: Item { + id: background + objectName: "scrollview-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Slider.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Slider.qml new file mode 100644 index 00000000000..88c5b22fce4 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Slider.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Slider { + id: control + objectName: "slider-identified" + + handle: Item { + id: handle + objectName: "slider-handle-identified" + } + + background: Item { + id: background + objectName: "slider-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/SpinBox.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/SpinBox.qml new file mode 100644 index 00000000000..0c058269a5a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/SpinBox.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SpinBox { + id: control + objectName: "spinbox-identified" + + up.indicator: Item { + id: upIndicator + objectName: "spinbox-up.indicator-identified" + } + + down.indicator: Item { + id: downIndicator + objectName: "spinbox-down.indicator-identified" + } + + contentItem: Item { + id: contentItem + objectName: "spinbox-contentItem-identified" + } + + background: Item { + id: background + objectName: "spinbox-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/StackView.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/StackView.qml new file mode 100644 index 00000000000..1bc5bf50f0a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/StackView.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.StackView { + id: control + objectName: "stackview-identified" + + contentItem: Item { + id: contentItem + objectName: "stackview-contentItem-identified" + } + + background: Item { + id: background + objectName: "stackview-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/SwipeDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/SwipeDelegate.qml new file mode 100644 index 00000000000..dadb54a5eab --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/SwipeDelegate.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwipeDelegate { + id: control + objectName: "swipedelegate-identified" + + contentItem: Item { + id: contentItem + objectName: "swipedelegate-contentItem-identified" + } + + background: Item { + id: background + objectName: "swipedelegate-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/SwipeView.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/SwipeView.qml new file mode 100644 index 00000000000..aa256d99084 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/SwipeView.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwipeView { + id: control + objectName: "swipeview-identified" + + contentItem: Item { + id: contentItem + objectName: "swipeview-contentItem-identified" + } + + background: Item { + id: background + objectName: "swipeview-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Switch.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Switch.qml new file mode 100644 index 00000000000..be10b520069 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Switch.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Switch { + id: control + objectName: "switch-identified" + + indicator: Item { + id: indicator + objectName: "switch-indicator-identified" + } + + contentItem: Item { + id: contentItem + objectName: "switch-contentItem-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/SwitchDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/SwitchDelegate.qml new file mode 100644 index 00000000000..7205c973eee --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/SwitchDelegate.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwitchDelegate { + id: control + objectName: "switchdelegate-identified" + + indicator: Item { + id: indicator + objectName: "switchdelegate-indicator-identified" + } + + contentItem: Item { + id: contentItem + objectName: "switchdelegate-contentItem-identified" + } + + background: Item { + id: background + objectName: "switchdelegate-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/TabBar.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/TabBar.qml new file mode 100644 index 00000000000..5d360cb1cf0 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/TabBar.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TabBar { + id: control + objectName: "tabbar-identified" + + contentItem: Item { + id: contentItem + objectName: "tabbar-contentItem-identified" + } + + background: Item { + id: background + objectName: "tabbar-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/TabButton.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/TabButton.qml new file mode 100644 index 00000000000..bc065b222da --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/TabButton.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TabButton { + id: control + objectName: "tabbutton-identified" + + contentItem: Item { + id: contentItem + objectName: "tabbutton-contentItem-identified" + } + + background: Item { + id: background + objectName: "tabbutton-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/TextArea.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/TextArea.qml new file mode 100644 index 00000000000..5667124028a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/TextArea.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TextArea { + id: control + objectName: "textarea-identified" + + background: Item { + id: background + objectName: "textarea-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/TextField.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/TextField.qml new file mode 100644 index 00000000000..1fef7ab523d --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/TextField.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TextField { + id: control + objectName: "textfield-identified" + + background: Item { + id: background + objectName: "textfield-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/ToolBar.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/ToolBar.qml new file mode 100644 index 00000000000..2061949cd2c --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/ToolBar.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolBar { + id: control + objectName: "toolbar-identified" + + contentItem: Item { + id: contentItem + objectName: "toolbar-contentItem-identified" + } + + background: Item { + id: background + objectName: "toolbar-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/ToolButton.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/ToolButton.qml new file mode 100644 index 00000000000..253391a8bee --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/ToolButton.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolButton { + id: control + objectName: "toolbutton-identified" + + contentItem: Item { + id: contentItem + objectName: "toolbutton-contentItem-identified" + } + + background: Item { + id: background + objectName: "toolbutton-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/ToolSeparator.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/ToolSeparator.qml new file mode 100644 index 00000000000..b8cf9daa1a8 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/ToolSeparator.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolSeparator { + id: control + objectName: "toolseparator-identified" + + contentItem: Item { + id: contentItem + objectName: "toolseparator-contentItem-identified" + } + + background: Item { + id: background + objectName: "toolseparator-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/ToolTip.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/ToolTip.qml new file mode 100644 index 00000000000..1ef95c9936b --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/ToolTip.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolTip { + id: control + objectName: "tooltip-identified" + + contentItem: Item { + id: contentItem + objectName: "tooltip-contentItem-identified" + } + + background: Item { + id: background + objectName: "tooltip-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/Tumbler.qml b/tests/auto/quickcontrols2/customization/data/styles/identified/Tumbler.qml new file mode 100644 index 00000000000..3bfdafc4284 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/Tumbler.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Tumbler { + id: control + objectName: "tumbler-identified" + + contentItem: ListView { + id: contentItem + objectName: "tumbler-contentItem-identified" + } + + background: Item { + id: background + objectName: "tumbler-background-identified" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/identified/qmldir b/tests/auto/quickcontrols2/customization/data/styles/identified/qmldir new file mode 100644 index 00000000000..1ee2a92e114 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/identified/qmldir @@ -0,0 +1,59 @@ +module identified + +AbstractButton 6.0 AbstractButton.qml +Action 6.0 Action.qml +ActionGroup 6.0 ActionGroup.qml +ApplicationWindow 6.0 ApplicationWindow.qml +BusyIndicator 6.0 BusyIndicator.qml +Button 6.0 Button.qml +ButtonGroup 6.0 ButtonGroup.qml +CheckBox 6.0 CheckBox.qml +CheckDelegate 6.0 CheckDelegate.qml +ComboBox 6.0 ComboBox.qml +Container 6.0 Container.qml +Control 6.0 Control.qml +DelayButton 6.0 DelayButton.qml +Dial 6.0 Dial.qml +Dialog 6.0 Dialog.qml +DialogButtonBox 6.0 DialogButtonBox.qml +Drawer 6.0 Drawer.qml +Frame 6.0 Frame.qml +GroupBox 6.0 GroupBox.qml +HorizontalHeaderView 6.0 HorizontalHeaderView.qml +ItemDelegate 6.0 ItemDelegate.qml +Label 6.0 Label.qml +Menu 6.0 Menu.qml +MenuBar 6.0 MenuBar.qml +MenuBarItem 6.0 MenuBarItem.qml +MenuItem 6.0 MenuItem.qml +MenuSeparator 6.0 MenuSeparator.qml +Page 6.0 Page.qml +PageIndicator 6.0 PageIndicator.qml +Pane 6.0 Pane.qml +Popup 6.0 Popup.qml +ProgressBar 6.0 ProgressBar.qml +RadioButton 6.0 RadioButton.qml +RadioDelegate 6.0 RadioDelegate.qml +RangeSlider 6.0 RangeSlider.qml +RoundButton 6.0 RoundButton.qml +ScrollBar 6.0 ScrollBar.qml +ScrollIndicator 6.0 ScrollIndicator.qml +ScrollView 6.0 ScrollView.qml +Slider 6.0 Slider.qml +SpinBox 6.0 SpinBox.qml +SplitView 6.0 SplitView.qml +StackView 6.0 StackView.qml +SwipeDelegate 6.0 SwipeDelegate.qml +SwipeView 6.0 SwipeView.qml +Switch 6.0 Switch.qml +SwitchDelegate 6.0 SwitchDelegate.qml +TabBar 6.0 TabBar.qml +TabButton 6.0 TabButton.qml +TextArea 6.0 TextArea.qml +TextField 6.0 TextField.qml +ToolBar 6.0 ToolBar.qml +ToolButton 6.0 ToolButton.qml +ToolSeparator 6.0 ToolSeparator.qml +ToolTip 6.0 ToolTip.qml +Tumbler 6.0 Tumbler.qml +VerticalHeaderView 6.0 VerticalHeaderView.qml diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/AbstractButton.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/AbstractButton.qml new file mode 100644 index 00000000000..7e3710509b7 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/AbstractButton.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.AbstractButton { + id: control + objectName: "abstractbutton-incomplete" + + indicator: Item { + objectName: "abstractbutton-indicator-incomplete" + } + + contentItem: Item { + objectName: "abstractbutton-contentItem-incomplete" + } + + background: Item { + objectName: "abstractbutton-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/ApplicationWindow.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ApplicationWindow.qml new file mode 100644 index 00000000000..8fbdd1a4b67 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ApplicationWindow.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ApplicationWindow { + id: control + objectName: "applicationwindow-incomplete" + + background: Item { + objectName: "applicationwindow-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/BusyIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/BusyIndicator.qml new file mode 100644 index 00000000000..b046163e2d5 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/BusyIndicator.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.BusyIndicator { + id: control + objectName: "busyindicator-incomplete" + + contentItem: Item { + objectName: "busyindicator-contentItem-incomplete" + } + + background: Item { + objectName: "busyindicator-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Button.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Button.qml new file mode 100644 index 00000000000..7daa248c071 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Button.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Button { + id: control + objectName: "button-incomplete" + + contentItem: Item { + objectName: "button-contentItem-incomplete" + } + + background: Item { + objectName: "button-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/CheckBox.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/CheckBox.qml new file mode 100644 index 00000000000..50bfa058ccc --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/CheckBox.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.CheckBox { + id: control + objectName: "checkbox-incomplete" + + indicator: Item { + objectName: "checkbox-indicator-incomplete" + } + + contentItem: Item { + objectName: "checkbox-contentItem-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/CheckDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/CheckDelegate.qml new file mode 100644 index 00000000000..13c0e4729f7 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/CheckDelegate.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.CheckDelegate { + id: control + objectName: "checkdelegate-incomplete" + + indicator: Item { + objectName: "checkdelegate-indicator-incomplete" + } + + contentItem: Item { + objectName: "checkdelegate-contentItem-incomplete" + } + + background: Item { + objectName: "checkdelegate-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/ComboBox.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ComboBox.qml new file mode 100644 index 00000000000..b0ff62578b7 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ComboBox.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ComboBox { + id: control + objectName: "combobox-incomplete" + + indicator: Item { + objectName: "combobox-indicator-incomplete" + } + + contentItem: Item { + objectName: "combobox-contentItem-incomplete" + } + + background: Item { + objectName: "combobox-background-incomplete" + } + + popup: T.Popup { + objectName: "combobox-popup-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Container.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Container.qml new file mode 100644 index 00000000000..0ad81beaa34 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Container.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Container { + id: control + objectName: "container-incomplete" + + contentItem: Item { + objectName: "container-contentItem-incomplete" + } + + background: Item { + objectName: "container-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Control.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Control.qml new file mode 100644 index 00000000000..6f07f5da9c3 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Control.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Control { + id: control + objectName: "control-incomplete" + + contentItem: Item { + objectName: "control-contentItem-incomplete" + } + + background: Item { + objectName: "control-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/DelayButton.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/DelayButton.qml new file mode 100644 index 00000000000..b6ab635bfd6 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/DelayButton.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.DelayButton { + id: control + objectName: "delaybutton-incomplete" + + contentItem: Item { + objectName: "delaybutton-contentItem-incomplete" + } + + background: Item { + objectName: "delaybutton-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Dial.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Dial.qml new file mode 100644 index 00000000000..66600c63c25 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Dial.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Dial { + id: control + objectName: "dial-incomplete" + + handle: Item { + objectName: "dial-handle-incomplete" + } + + background: Item { + objectName: "dial-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Dialog.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Dialog.qml new file mode 100644 index 00000000000..d8ab999e2e5 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Dialog.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Dialog { + id: control + objectName: "dialog-incomplete" + + contentItem: Item { + objectName: "dialog-contentItem-incomplete" + } + + background: Item { + objectName: "dialog-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/DialogButtonBox.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/DialogButtonBox.qml new file mode 100644 index 00000000000..d7f954befe7 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/DialogButtonBox.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.DialogButtonBox { + id: control + objectName: "dialogbuttonbox-incomplete" + + contentItem: Item { + objectName: "dialogbuttonbox-contentItem-incomplete" + } + + background: Item { + objectName: "dialogbuttonbox-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Drawer.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Drawer.qml new file mode 100644 index 00000000000..5dadbd7793c --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Drawer.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Drawer { + id: control + objectName: "drawer-incomplete" + + contentItem: Item { + objectName: "drawer-contentItem-incomplete" + } + + background: Item { + objectName: "drawer-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Frame.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Frame.qml new file mode 100644 index 00000000000..e447b5c2dfb --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Frame.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Frame { + id: control + objectName: "frame-incomplete" + + contentItem: Item { + objectName: "frame-contentItem-incomplete" + } + + background: Item { + objectName: "frame-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/GroupBox.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/GroupBox.qml new file mode 100644 index 00000000000..3597f1587de --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/GroupBox.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.GroupBox { + id: control + objectName: "groupbox-incomplete" + + label: Text { + objectName: "groupbox-label-incomplete" + } + + contentItem: Item { + objectName: "groupbox-contentItem-incomplete" + } + + background: Item { + objectName: "groupbox-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/ItemDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ItemDelegate.qml new file mode 100644 index 00000000000..79334dcbd8a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ItemDelegate.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ItemDelegate { + id: control + objectName: "itemdelegate-incomplete" + + contentItem: Item { + objectName: "itemdelegate-contentItem-incomplete" + } + + background: Item { + objectName: "itemdelegate-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Label.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Label.qml new file mode 100644 index 00000000000..e60ea00c4d2 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Label.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Label { + id: control + objectName: "label-incomplete" + + background: Item { + objectName: "label-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Menu.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Menu.qml new file mode 100644 index 00000000000..220d0038b93 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Menu.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Menu { + id: control + objectName: "menu-incomplete" + + contentItem: Item { + objectName: "menu-contentItem-incomplete" + } + + background: Item { + objectName: "menu-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/MenuBar.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/MenuBar.qml new file mode 100644 index 00000000000..b782eb4d092 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/MenuBar.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuBar { + id: control + objectName: "menubar-incomplete" + + contentItem: Item { + objectName: "menubar-contentItem-incomplete" + } + + background: Item { + objectName: "menubar-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/MenuBarItem.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/MenuBarItem.qml new file mode 100644 index 00000000000..a979ecb7fab --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/MenuBarItem.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuBarItem { + id: control + objectName: "menubaritem-incomplete" + + contentItem: Item { + objectName: "menubaritem-contentItem-incomplete" + } + + background: Item { + objectName: "menubaritem-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/MenuItem.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/MenuItem.qml new file mode 100644 index 00000000000..b14f9089a61 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/MenuItem.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuItem { + id: control + objectName: "menuitem-incomplete" + + arrow: Item { + objectName: "menuitem-arrow-incomplete" + } + + indicator: Item { + objectName: "menuitem-indicator-incomplete" + } + + contentItem: Item { + objectName: "menuitem-contentItem-incomplete" + } + + background: Item { + objectName: "menuitem-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/MenuSeparator.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/MenuSeparator.qml new file mode 100644 index 00000000000..ba6d27eceaa --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/MenuSeparator.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuSeparator { + id: control + objectName: "menuseparator-incomplete" + + contentItem: Item { + objectName: "menuseparator-contentItem-incomplete" + } + + background: Item { + objectName: "menuseparator-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Page.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Page.qml new file mode 100644 index 00000000000..dbd29521ac0 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Page.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Page { + id: control + objectName: "page-incomplete" + + contentItem: Item { + objectName: "page-contentItem-incomplete" + } + + background: Item { + objectName: "page-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/PageIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/PageIndicator.qml new file mode 100644 index 00000000000..b18363407d6 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/PageIndicator.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.PageIndicator { + id: control + objectName: "pageindicator-incomplete" + + contentItem: Item { + objectName: "pageindicator-contentItem-incomplete" + } + + background: Item { + objectName: "pageindicator-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Pane.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Pane.qml new file mode 100644 index 00000000000..ecd7cbdf21a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Pane.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Pane { + id: control + objectName: "pane-incomplete" + + contentItem: Item { + objectName: "pane-contentItem-incomplete" + } + + background: Item { + objectName: "pane-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Popup.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Popup.qml new file mode 100644 index 00000000000..a3d7d8d5dc2 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Popup.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Popup { + id: control + objectName: "popup-incomplete" + + contentItem: Item { + objectName: "popup-contentItem-incomplete" + } + + background: Item { + objectName: "popup-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/ProgressBar.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ProgressBar.qml new file mode 100644 index 00000000000..293fe25481e --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ProgressBar.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ProgressBar { + id: control + objectName: "progressbar-incomplete" + + contentItem: Item { + objectName: "progressbar-contentItem-incomplete" + } + + background: Item { + objectName: "progressbar-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/RadioButton.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/RadioButton.qml new file mode 100644 index 00000000000..f17729f7914 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/RadioButton.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RadioButton { + id: control + objectName: "radiobutton-incomplete" + + indicator: Item { + objectName: "radiobutton-indicator-incomplete" + } + + contentItem: Item { + objectName: "radiobutton-contentItem-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/RadioDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/RadioDelegate.qml new file mode 100644 index 00000000000..8dd08aea84f --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/RadioDelegate.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RadioDelegate { + id: control + objectName: "radiodelegate-incomplete" + + indicator: Item { + objectName: "radiodelegate-indicator-incomplete" + } + + contentItem: Item { + objectName: "radiodelegate-contentItem-incomplete" + } + + background: Item { + objectName: "radiodelegate-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/RangeSlider.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/RangeSlider.qml new file mode 100644 index 00000000000..3a6ba580df5 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/RangeSlider.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RangeSlider { + id: control + objectName: "rangeslider-incomplete" + + first.handle: Item { + objectName: "rangeslider-first.handle-incomplete" + } + + second.handle: Item { + objectName: "rangeslider-second.handle-incomplete" + } + + background: Item { + objectName: "rangeslider-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/RoundButton.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/RoundButton.qml new file mode 100644 index 00000000000..d51ef732f3b --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/RoundButton.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RoundButton { + id: control + objectName: "roundbutton-incomplete" + + contentItem: Item { + objectName: "roundbutton-contentItem-incomplete" + } + + background: Item { + objectName: "roundbutton-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/ScrollBar.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ScrollBar.qml new file mode 100644 index 00000000000..906a9847f8f --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ScrollBar.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ScrollBar { + id: control + objectName: "scrollbar-incomplete" + + contentItem: Item { + objectName: "scrollbar-contentItem-incomplete" + } + + background: Item { + objectName: "scrollbar-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/ScrollIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ScrollIndicator.qml new file mode 100644 index 00000000000..b34d40970dc --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ScrollIndicator.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ScrollIndicator { + id: control + objectName: "scrollindicator-incomplete" + + contentItem: Item { + objectName: "scrollindicator-contentItem-incomplete" + } + + background: Item { + objectName: "scrollindicator-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/ScrollView.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ScrollView.qml new file mode 100644 index 00000000000..a120e05f976 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ScrollView.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ScrollView { + id: control + objectName: "scrollview-incomplete" + + background: Item { + objectName: "scrollview-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Slider.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Slider.qml new file mode 100644 index 00000000000..02b06d92e45 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Slider.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Slider { + id: control + objectName: "slider-incomplete" + + handle: Item { + objectName: "slider-handle-incomplete" + } + + background: Item { + objectName: "slider-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/SpinBox.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/SpinBox.qml new file mode 100644 index 00000000000..9ec62e016e6 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/SpinBox.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SpinBox { + id: control + objectName: "spinbox-incomplete" + + up.indicator: Item { + objectName: "spinbox-up.indicator-incomplete" + } + + down.indicator: Item { + objectName: "spinbox-down.indicator-incomplete" + } + + contentItem: Item { + objectName: "spinbox-contentItem-incomplete" + } + + background: Item { + objectName: "spinbox-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/StackView.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/StackView.qml new file mode 100644 index 00000000000..4108e166783 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/StackView.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.StackView { + id: control + objectName: "stackview-incomplete" + + contentItem: Item { + objectName: "stackview-contentItem-incomplete" + } + + background: Item { + objectName: "stackview-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/SwipeDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/SwipeDelegate.qml new file mode 100644 index 00000000000..0da62d0fd90 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/SwipeDelegate.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwipeDelegate { + id: control + objectName: "swipedelegate-incomplete" + + contentItem: Item { + objectName: "swipedelegate-contentItem-incomplete" + } + + background: Item { + objectName: "swipedelegate-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/SwipeView.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/SwipeView.qml new file mode 100644 index 00000000000..434f9003611 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/SwipeView.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwipeView { + id: control + objectName: "swipeview-incomplete" + + contentItem: Item { + objectName: "swipeview-contentItem-incomplete" + } + + background: Item { + objectName: "swipeview-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Switch.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Switch.qml new file mode 100644 index 00000000000..9f24763fa68 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Switch.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Switch { + id: control + objectName: "switch-incomplete" + + indicator: Item { + objectName: "switch-indicator-incomplete" + } + + contentItem: Item { + objectName: "switch-contentItem-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/SwitchDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/SwitchDelegate.qml new file mode 100644 index 00000000000..a33809c7dfe --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/SwitchDelegate.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwitchDelegate { + id: control + objectName: "switchdelegate-incomplete" + + indicator: Item { + objectName: "switchdelegate-indicator-incomplete" + } + + contentItem: Item { + objectName: "switchdelegate-contentItem-incomplete" + } + + background: Item { + objectName: "switchdelegate-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/TabBar.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/TabBar.qml new file mode 100644 index 00000000000..68e4f627000 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/TabBar.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TabBar { + id: control + objectName: "tabbar-incomplete" + + contentItem: Item { + objectName: "tabbar-contentItem-incomplete" + } + + background: Item { + objectName: "tabbar-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/TabButton.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/TabButton.qml new file mode 100644 index 00000000000..9ab619a9347 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/TabButton.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TabButton { + id: control + objectName: "tabbutton-incomplete" + + contentItem: Item { + objectName: "tabbutton-contentItem-incomplete" + } + + background: Item { + objectName: "tabbutton-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/TextArea.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/TextArea.qml new file mode 100644 index 00000000000..42f3d2fdeb5 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/TextArea.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TextArea { + id: control + objectName: "textarea-incomplete" + + background: Item { + objectName: "textarea-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/TextField.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/TextField.qml new file mode 100644 index 00000000000..001d86b1c5c --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/TextField.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TextField { + id: control + objectName: "textfield-incomplete" + + background: Item { + objectName: "textfield-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/ToolBar.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ToolBar.qml new file mode 100644 index 00000000000..de0bdb392d2 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ToolBar.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolBar { + id: control + objectName: "toolbar-incomplete" + + contentItem: Item { + objectName: "toolbar-contentItem-incomplete" + } + + background: Item { + objectName: "toolbar-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/ToolButton.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ToolButton.qml new file mode 100644 index 00000000000..12b55b15a29 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ToolButton.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolButton { + id: control + objectName: "toolbutton-incomplete" + + contentItem: Item { + objectName: "toolbutton-contentItem-incomplete" + } + + background: Item { + objectName: "toolbutton-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/ToolSeparator.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ToolSeparator.qml new file mode 100644 index 00000000000..aa413dd0938 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ToolSeparator.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolSeparator { + id: control + objectName: "toolseparator-incomplete" + + contentItem: Item { + objectName: "toolseparator-contentItem-incomplete" + } + + background: Item { + objectName: "toolseparator-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/ToolTip.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ToolTip.qml new file mode 100644 index 00000000000..d2104f9eeb0 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/ToolTip.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolTip { + id: control + objectName: "tooltip-incomplete" + + contentItem: Item { + objectName: "tooltip-contentItem-incomplete" + } + + background: Item { + objectName: "tooltip-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/Tumbler.qml b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Tumbler.qml new file mode 100644 index 00000000000..996af0d2cdf --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/Tumbler.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Tumbler { + id: control + objectName: "tumbler-incomplete" + + contentItem: ListView { + objectName: "tumbler-contentItem-incomplete" + } + + background: Item { + objectName: "tumbler-background-incomplete" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/incomplete/qmldir b/tests/auto/quickcontrols2/customization/data/styles/incomplete/qmldir new file mode 100644 index 00000000000..e8813bd5184 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/incomplete/qmldir @@ -0,0 +1,59 @@ +module incomplete + +AbstractButton 6.0 AbstractButton.qml +Action 6.0 Action.qml +ActionGroup 6.0 ActionGroup.qml +ApplicationWindow 6.0 ApplicationWindow.qml +BusyIndicator 6.0 BusyIndicator.qml +Button 6.0 Button.qml +ButtonGroup 6.0 ButtonGroup.qml +CheckBox 6.0 CheckBox.qml +CheckDelegate 6.0 CheckDelegate.qml +ComboBox 6.0 ComboBox.qml +Container 6.0 Container.qml +Control 6.0 Control.qml +DelayButton 6.0 DelayButton.qml +Dial 6.0 Dial.qml +Dialog 6.0 Dialog.qml +DialogButtonBox 6.0 DialogButtonBox.qml +Drawer 6.0 Drawer.qml +Frame 6.0 Frame.qml +GroupBox 6.0 GroupBox.qml +HorizontalHeaderView 6.0 HorizontalHeaderView.qml +ItemDelegate 6.0 ItemDelegate.qml +Label 6.0 Label.qml +Menu 6.0 Menu.qml +MenuBar 6.0 MenuBar.qml +MenuBarItem 6.0 MenuBarItem.qml +MenuItem 6.0 MenuItem.qml +MenuSeparator 6.0 MenuSeparator.qml +Page 6.0 Page.qml +PageIndicator 6.0 PageIndicator.qml +Pane 6.0 Pane.qml +Popup 6.0 Popup.qml +ProgressBar 6.0 ProgressBar.qml +RadioButton 6.0 RadioButton.qml +RadioDelegate 6.0 RadioDelegate.qml +RangeSlider 6.0 RangeSlider.qml +RoundButton 6.0 RoundButton.qml +ScrollBar 6.0 ScrollBar.qml +ScrollIndicator 6.0 ScrollIndicator.qml +ScrollView 6.0 ScrollView.qml +Slider 6.0 Slider.qml +SpinBox 6.0 SpinBox.qml +SplitView 6.0 SplitView.qml +StackView 6.0 StackView.qml +SwipeDelegate 6.0 SwipeDelegate.qml +SwipeView 6.0 SwipeView.qml +Switch 6.0 Switch.qml +SwitchDelegate 6.0 SwitchDelegate.qml +TabBar 6.0 TabBar.qml +TabButton 6.0 TabButton.qml +TextArea 6.0 TextArea.qml +TextField 6.0 TextField.qml +ToolBar 6.0 ToolBar.qml +ToolButton 6.0 ToolButton.qml +ToolSeparator 6.0 ToolSeparator.qml +ToolTip 6.0 ToolTip.qml +Tumbler 6.0 Tumbler.qml +VerticalHeaderView 6.0 VerticalHeaderView.qml diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/AbstractButton.qml b/tests/auto/quickcontrols2/customization/data/styles/override/AbstractButton.qml new file mode 100644 index 00000000000..e8bf0b90f57 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/AbstractButton.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.AbstractButton { + id: control + objectName: "abstractbutton-override" + + indicator: Item { + objectName: "abstractbutton-indicator-override" + } + + contentItem: Item { + objectName: "abstractbutton-contentItem-override" + } + + background: Item { + objectName: "abstractbutton-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/ApplicationWindow.qml b/tests/auto/quickcontrols2/customization/data/styles/override/ApplicationWindow.qml new file mode 100644 index 00000000000..43b94010e67 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/ApplicationWindow.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.ApplicationWindow { + id: control + objectName: "applicationwindow-override" + + background: Item { + objectName: "applicationwindow-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/BusyIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/override/BusyIndicator.qml new file mode 100644 index 00000000000..12418ff720f --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/BusyIndicator.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.BusyIndicator { + id: control + objectName: "busyindicator-override" + + contentItem: Item { + objectName: "busyindicator-contentItem-override" + } + + background: Item { + objectName: "busyindicator-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Button.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Button.qml new file mode 100644 index 00000000000..692c2fda2ec --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Button.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Button { + id: control + objectName: "button-override" + + contentItem: Item { + objectName: "button-contentItem-override" + } + + background: Item { + objectName: "button-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/CheckBox.qml b/tests/auto/quickcontrols2/customization/data/styles/override/CheckBox.qml new file mode 100644 index 00000000000..9830931b16c --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/CheckBox.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.CheckBox { + id: control + objectName: "checkbox-override" + + indicator: Item { + objectName: "checkbox-indicator-override" + } + + contentItem: Item { + objectName: "checkbox-contentItem-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/CheckDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/override/CheckDelegate.qml new file mode 100644 index 00000000000..77cdf23d28b --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/CheckDelegate.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.CheckDelegate { + id: control + objectName: "checkdelegate-override" + + indicator: Item { + objectName: "checkdelegate-indicator-override" + } + + contentItem: Item { + objectName: "checkdelegate-contentItem-override" + } + + background: Item { + objectName: "checkdelegate-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/ComboBox.qml b/tests/auto/quickcontrols2/customization/data/styles/override/ComboBox.qml new file mode 100644 index 00000000000..c3276dccdfa --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/ComboBox.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T +import "../simple" as Simple + +Simple.ComboBox { + id: control + objectName: "combobox-override" + + indicator: Item { + objectName: "combobox-indicator-override" + } + + contentItem: Item { + objectName: "combobox-contentItem-override" + } + + background: Item { + objectName: "combobox-background-override" + } + + popup: T.Popup { + objectName: "combobox-popup-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Container.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Container.qml new file mode 100644 index 00000000000..b732aefa7ac --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Container.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Container { + id: control + objectName: "container-override" + + contentItem: Item { + objectName: "container-contentItem-override" + } + + background: Item { + objectName: "container-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Control.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Control.qml new file mode 100644 index 00000000000..b4fefcf57b3 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Control.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Control { + id: control + objectName: "control-override" + + contentItem: Item { + objectName: "control-contentItem-override" + } + + background: Item { + objectName: "control-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/DelayButton.qml b/tests/auto/quickcontrols2/customization/data/styles/override/DelayButton.qml new file mode 100644 index 00000000000..5ee03d57ebf --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/DelayButton.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.DelayButton { + id: control + objectName: "delaybutton-override" + + contentItem: Item { + objectName: "delaybutton-contentItem-override" + } + + background: Item { + objectName: "delaybutton-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Dial.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Dial.qml new file mode 100644 index 00000000000..d452a58f310 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Dial.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Dial { + id: control + objectName: "dial-override" + + handle: Item { + objectName: "dial-handle-override" + } + + background: Item { + objectName: "dial-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Dialog.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Dialog.qml new file mode 100644 index 00000000000..29e3d26d335 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Dialog.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Dialog { + id: control + objectName: "dialog-override" + + contentItem: Item { + objectName: "dialog-contentItem-override" + } + + background: Item { + objectName: "dialog-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/DialogButtonBox.qml b/tests/auto/quickcontrols2/customization/data/styles/override/DialogButtonBox.qml new file mode 100644 index 00000000000..c79b9f815b5 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/DialogButtonBox.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.DialogButtonBox { + id: control + objectName: "dialogbuttonbox-override" + + contentItem: Item { + objectName: "dialogbuttonbox-contentItem-override" + } + + background: Item { + objectName: "dialogbuttonbox-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Drawer.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Drawer.qml new file mode 100644 index 00000000000..65aa625c00a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Drawer.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Drawer { + id: control + objectName: "drawer-override" + + contentItem: Item { + objectName: "drawer-contentItem-override" + } + + background: Item { + objectName: "drawer-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Frame.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Frame.qml new file mode 100644 index 00000000000..b31b70aa95a --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Frame.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Frame { + id: control + objectName: "frame-override" + + contentItem: Item { + objectName: "frame-contentItem-override" + } + + background: Item { + objectName: "frame-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/GroupBox.qml b/tests/auto/quickcontrols2/customization/data/styles/override/GroupBox.qml new file mode 100644 index 00000000000..0d0bfbd9aaa --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/GroupBox.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.GroupBox { + id: control + objectName: "groupbox-override" + + label: Text { + objectName: "groupbox-label-override" + } + + contentItem: Item { + objectName: "groupbox-contentItem-override" + } + + background: Item { + objectName: "groupbox-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/ItemDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/override/ItemDelegate.qml new file mode 100644 index 00000000000..4a087c75aaf --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/ItemDelegate.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.ItemDelegate { + id: control + objectName: "itemdelegate-override" + + contentItem: Item { + objectName: "itemdelegate-contentItem-override" + } + + background: Item { + objectName: "itemdelegate-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Label.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Label.qml new file mode 100644 index 00000000000..883cff743df --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Label.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Label { + id: control + objectName: "label-override" + + background: Item { + objectName: "label-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Menu.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Menu.qml new file mode 100644 index 00000000000..f551fae8fe9 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Menu.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Menu { + id: control + objectName: "menu-override" + + contentItem: Item { + objectName: "menu-contentItem-override" + } + + background: Item { + objectName: "menu-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/MenuBar.qml b/tests/auto/quickcontrols2/customization/data/styles/override/MenuBar.qml new file mode 100644 index 00000000000..b7f54cfbac9 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/MenuBar.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.MenuBar { + id: control + objectName: "menubar-override" + + contentItem: Item { + objectName: "menubar-contentItem-override" + } + + background: Item { + objectName: "menubar-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/MenuBarItem.qml b/tests/auto/quickcontrols2/customization/data/styles/override/MenuBarItem.qml new file mode 100644 index 00000000000..513b59ce87f --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/MenuBarItem.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.MenuBarItem { + id: control + objectName: "menubaritem-override" + + contentItem: Item { + objectName: "menubaritem-contentItem-override" + } + + background: Item { + objectName: "menubaritem-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/MenuItem.qml b/tests/auto/quickcontrols2/customization/data/styles/override/MenuItem.qml new file mode 100644 index 00000000000..7f7f569a0e2 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/MenuItem.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.MenuItem { + id: control + objectName: "menuitem-override" + + arrow: Item { + objectName: "menuitem-arrow-override" + } + + indicator: Item { + objectName: "menuitem-indicator-override" + } + + contentItem: Item { + objectName: "menuitem-contentItem-override" + } + + background: Item { + objectName: "menuitem-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/MenuSeparator.qml b/tests/auto/quickcontrols2/customization/data/styles/override/MenuSeparator.qml new file mode 100644 index 00000000000..57a2db15170 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/MenuSeparator.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.MenuSeparator { + id: control + objectName: "menuseparator-override" + + contentItem: Item { + objectName: "menuseparator-contentItem-override" + } + + background: Item { + objectName: "menuseparator-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Page.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Page.qml new file mode 100644 index 00000000000..c51d1e73134 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Page.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Page { + id: control + objectName: "page-override" + + contentItem: Item { + objectName: "page-contentItem-override" + } + + background: Item { + objectName: "page-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/PageIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/override/PageIndicator.qml new file mode 100644 index 00000000000..3d58299e1b8 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/PageIndicator.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.PageIndicator { + id: control + objectName: "pageindicator-override" + + contentItem: Item { + objectName: "pageindicator-contentItem-override" + } + + background: Item { + objectName: "pageindicator-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Pane.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Pane.qml new file mode 100644 index 00000000000..70a29441790 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Pane.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Pane { + id: control + objectName: "pane-override" + + contentItem: Item { + objectName: "pane-contentItem-override" + } + + background: Item { + objectName: "pane-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Popup.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Popup.qml new file mode 100644 index 00000000000..a63879bd26f --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Popup.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Popup { + id: control + objectName: "popup-override" + + contentItem: Item { + objectName: "popup-contentItem-override" + } + + background: Item { + objectName: "popup-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/ProgressBar.qml b/tests/auto/quickcontrols2/customization/data/styles/override/ProgressBar.qml new file mode 100644 index 00000000000..2a9e636ada0 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/ProgressBar.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.ProgressBar { + id: control + objectName: "progressbar-override" + + contentItem: Item { + objectName: "progressbar-contentItem-override" + } + + background: Item { + objectName: "progressbar-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/RadioButton.qml b/tests/auto/quickcontrols2/customization/data/styles/override/RadioButton.qml new file mode 100644 index 00000000000..5bd5c721d07 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/RadioButton.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.RadioButton { + id: control + objectName: "radiobutton-override" + + indicator: Item { + objectName: "radiobutton-indicator-override" + } + + contentItem: Item { + objectName: "radiobutton-contentItem-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/RadioDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/override/RadioDelegate.qml new file mode 100644 index 00000000000..7fbe3833f1f --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/RadioDelegate.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.RadioDelegate { + id: control + objectName: "radiodelegate-override" + + indicator: Item { + objectName: "radiodelegate-indicator-override" + } + + contentItem: Item { + objectName: "radiodelegate-contentItem-override" + } + + background: Item { + objectName: "radiodelegate-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/RangeSlider.qml b/tests/auto/quickcontrols2/customization/data/styles/override/RangeSlider.qml new file mode 100644 index 00000000000..0f4cda9999f --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/RangeSlider.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.RangeSlider { + id: control + objectName: "rangeslider-override" + + first.handle: Item { + objectName: "rangeslider-first.handle-override" + } + + second.handle: Item { + objectName: "rangeslider-second.handle-override" + } + + background: Item { + objectName: "rangeslider-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/RoundButton.qml b/tests/auto/quickcontrols2/customization/data/styles/override/RoundButton.qml new file mode 100644 index 00000000000..1a0b0e05e80 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/RoundButton.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.RoundButton { + id: control + objectName: "roundbutton-override" + + contentItem: Item { + objectName: "roundbutton-contentItem-override" + } + + background: Item { + objectName: "roundbutton-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/ScrollBar.qml b/tests/auto/quickcontrols2/customization/data/styles/override/ScrollBar.qml new file mode 100644 index 00000000000..fc551710e25 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/ScrollBar.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.ScrollBar { + id: control + objectName: "scrollbar-override" + + contentItem: Item { + objectName: "scrollbar-contentItem-override" + } + + background: Item { + objectName: "scrollbar-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/ScrollIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/override/ScrollIndicator.qml new file mode 100644 index 00000000000..06497abb6e5 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/ScrollIndicator.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.ScrollIndicator { + id: control + objectName: "scrollindicator-override" + + contentItem: Item { + objectName: "scrollindicator-contentItem-override" + } + + background: Item { + objectName: "scrollindicator-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/ScrollView.qml b/tests/auto/quickcontrols2/customization/data/styles/override/ScrollView.qml new file mode 100644 index 00000000000..bc02c265838 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/ScrollView.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.ScrollView { + id: control + objectName: "scrollview-override" + + background: Item { + objectName: "scrollview-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Slider.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Slider.qml new file mode 100644 index 00000000000..052c523be30 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Slider.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Slider { + id: control + objectName: "slider-override" + + handle: Item { + objectName: "slider-handle-override" + } + + background: Item { + objectName: "slider-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/SpinBox.qml b/tests/auto/quickcontrols2/customization/data/styles/override/SpinBox.qml new file mode 100644 index 00000000000..d074ec6372c --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/SpinBox.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.SpinBox { + id: control + objectName: "spinbox-override" + + up.indicator: Item { + objectName: "spinbox-up.indicator-override" + } + + down.indicator: Item { + objectName: "spinbox-down.indicator-override" + } + + contentItem: Item { + objectName: "spinbox-contentItem-override" + } + + background: Item { + objectName: "spinbox-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/StackView.qml b/tests/auto/quickcontrols2/customization/data/styles/override/StackView.qml new file mode 100644 index 00000000000..bc33d64baec --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/StackView.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.StackView { + id: control + objectName: "stackview-override" + + contentItem: Item { + objectName: "stackview-contentItem-override" + } + + background: Item { + objectName: "stackview-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/SwipeDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/override/SwipeDelegate.qml new file mode 100644 index 00000000000..bb387370368 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/SwipeDelegate.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.SwipeDelegate { + id: control + objectName: "swipedelegate-override" + + contentItem: Item { + objectName: "swipedelegate-contentItem-override" + } + + background: Item { + objectName: "swipedelegate-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/SwipeView.qml b/tests/auto/quickcontrols2/customization/data/styles/override/SwipeView.qml new file mode 100644 index 00000000000..63646a0bbfd --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/SwipeView.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.SwipeView { + id: control + objectName: "swipeview-override" + + contentItem: Item { + objectName: "swipeview-contentItem-override" + } + + background: Item { + objectName: "swipeview-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Switch.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Switch.qml new file mode 100644 index 00000000000..57a3f8049f9 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Switch.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Switch { + id: control + objectName: "switch-override" + + indicator: Item { + objectName: "switch-indicator-override" + } + + contentItem: Item { + objectName: "switch-contentItem-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/SwitchDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/override/SwitchDelegate.qml new file mode 100644 index 00000000000..6b9986d8f68 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/SwitchDelegate.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.SwitchDelegate { + id: control + objectName: "switchdelegate-override" + + indicator: Item { + objectName: "switchdelegate-indicator-override" + } + + contentItem: Item { + objectName: "switchdelegate-contentItem-override" + } + + background: Item { + objectName: "switchdelegate-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/TabBar.qml b/tests/auto/quickcontrols2/customization/data/styles/override/TabBar.qml new file mode 100644 index 00000000000..b3e03bddad9 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/TabBar.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.TabBar { + id: control + objectName: "tabbar-override" + + contentItem: Item { + objectName: "tabbar-contentItem-override" + } + + background: Item { + objectName: "tabbar-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/TabButton.qml b/tests/auto/quickcontrols2/customization/data/styles/override/TabButton.qml new file mode 100644 index 00000000000..f2852f684fc --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/TabButton.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.TabButton { + id: control + objectName: "tabbutton-override" + + contentItem: Item { + objectName: "tabbutton-contentItem-override" + } + + background: Item { + objectName: "tabbutton-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/TextArea.qml b/tests/auto/quickcontrols2/customization/data/styles/override/TextArea.qml new file mode 100644 index 00000000000..ad4a3c7b11d --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/TextArea.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.TextArea { + id: control + objectName: "textarea-override" + + background: Item { + objectName: "textarea-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/TextField.qml b/tests/auto/quickcontrols2/customization/data/styles/override/TextField.qml new file mode 100644 index 00000000000..39bb695e342 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/TextField.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.TextField { + id: control + objectName: "textfield-override" + + background: Item { + objectName: "textfield-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/ToolBar.qml b/tests/auto/quickcontrols2/customization/data/styles/override/ToolBar.qml new file mode 100644 index 00000000000..8af7238ee36 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/ToolBar.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.ToolBar { + id: control + objectName: "toolbar-override" + + contentItem: Item { + objectName: "toolbar-contentItem-override" + } + + background: Item { + objectName: "toolbar-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/ToolButton.qml b/tests/auto/quickcontrols2/customization/data/styles/override/ToolButton.qml new file mode 100644 index 00000000000..a9e285fb5c6 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/ToolButton.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.ToolButton { + id: control + objectName: "toolbutton-override" + + contentItem: Item { + objectName: "toolbutton-contentItem-override" + } + + background: Item { + objectName: "toolbutton-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/ToolSeparator.qml b/tests/auto/quickcontrols2/customization/data/styles/override/ToolSeparator.qml new file mode 100644 index 00000000000..5c6b408d8a1 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/ToolSeparator.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.ToolSeparator { + id: control + objectName: "toolseparator-override" + + contentItem: Item { + objectName: "toolseparator-contentItem-override" + } + + background: Item { + objectName: "toolseparator-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/ToolTip.qml b/tests/auto/quickcontrols2/customization/data/styles/override/ToolTip.qml new file mode 100644 index 00000000000..642d6184002 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/ToolTip.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.ToolTip { + id: control + objectName: "tooltip-override" + + contentItem: Item { + objectName: "tooltip-contentItem-override" + } + + background: Item { + objectName: "tooltip-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/Tumbler.qml b/tests/auto/quickcontrols2/customization/data/styles/override/Tumbler.qml new file mode 100644 index 00000000000..72d68f8a318 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/Tumbler.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import "../simple" as Simple + +Simple.Tumbler { + id: control + objectName: "tumbler-override" + + contentItem: ListView { + objectName: "tumbler-contentItem-override" + } + + background: Item { + objectName: "tumbler-background-override" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/override/qmldir b/tests/auto/quickcontrols2/customization/data/styles/override/qmldir new file mode 100644 index 00000000000..f15ba96ab3b --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/override/qmldir @@ -0,0 +1,59 @@ +module override + +AbstractButton 6.0 AbstractButton.qml +Action 6.0 Action.qml +ActionGroup 6.0 ActionGroup.qml +ApplicationWindow 6.0 ApplicationWindow.qml +BusyIndicator 6.0 BusyIndicator.qml +Button 6.0 Button.qml +ButtonGroup 6.0 ButtonGroup.qml +CheckBox 6.0 CheckBox.qml +CheckDelegate 6.0 CheckDelegate.qml +ComboBox 6.0 ComboBox.qml +Container 6.0 Container.qml +Control 6.0 Control.qml +DelayButton 6.0 DelayButton.qml +Dial 6.0 Dial.qml +Dialog 6.0 Dialog.qml +DialogButtonBox 6.0 DialogButtonBox.qml +Drawer 6.0 Drawer.qml +Frame 6.0 Frame.qml +GroupBox 6.0 GroupBox.qml +HorizontalHeaderView 6.0 HorizontalHeaderView.qml +ItemDelegate 6.0 ItemDelegate.qml +Label 6.0 Label.qml +Menu 6.0 Menu.qml +MenuBar 6.0 MenuBar.qml +MenuBarItem 6.0 MenuBarItem.qml +MenuItem 6.0 MenuItem.qml +MenuSeparator 6.0 MenuSeparator.qml +Page 6.0 Page.qml +PageIndicator 6.0 PageIndicator.qml +Pane 6.0 Pane.qml +Popup 6.0 Popup.qml +ProgressBar 6.0 ProgressBar.qml +RadioButton 6.0 RadioButton.qml +RadioDelegate 6.0 RadioDelegate.qml +RangeSlider 6.0 RangeSlider.qml +RoundButton 6.0 RoundButton.qml +ScrollBar 6.0 ScrollBar.qml +ScrollIndicator 6.0 ScrollIndicator.qml +ScrollView 6.0 ScrollView.qml +Slider 6.0 Slider.qml +SpinBox 6.0 SpinBox.qml +SplitView 6.0 SplitView.qml +StackView 6.0 StackView.qml +SwipeDelegate 6.0 SwipeDelegate.qml +SwipeView 6.0 SwipeView.qml +Switch 6.0 Switch.qml +SwitchDelegate 6.0 SwitchDelegate.qml +TabBar 6.0 TabBar.qml +TabButton 6.0 TabButton.qml +TextArea 6.0 TextArea.qml +TextField 6.0 TextField.qml +ToolBar 6.0 ToolBar.qml +ToolButton 6.0 ToolButton.qml +ToolSeparator 6.0 ToolSeparator.qml +ToolTip 6.0 ToolTip.qml +Tumbler 6.0 Tumbler.qml +VerticalHeaderView 6.0 VerticalHeaderView.qml diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/AbstractButton.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/AbstractButton.qml new file mode 100644 index 00000000000..f8eaef0c251 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/AbstractButton.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.AbstractButton { + id: control + objectName: "abstractbutton-simple" + + implicitWidth: Math.max(contentItem.implicitWidth + indicator.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, indicator.implicitHeight, background.implicitHeight) + + indicator: Text { + objectName: "abstractbutton-indicator-simple" + text: control.checked ? "V" : "" + } + + contentItem: Text { + objectName: "abstractbutton-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "abstractbutton-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/ApplicationWindow.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/ApplicationWindow.qml new file mode 100644 index 00000000000..ec39193b430 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/ApplicationWindow.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ApplicationWindow { + id: control + objectName: "applicationwindow-simple" + + minimumWidth: background.implicitWidth + minimumHeight: background.implicitHeight + + background: Rectangle { + objectName: "applicationwindow-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/BusyIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/BusyIndicator.qml new file mode 100644 index 00000000000..1dcebb9b7af --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/BusyIndicator.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.BusyIndicator { + id: control + objectName: "busyindicator-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "busyindicator-contentItem-simple" + } + + background: Rectangle { + objectName: "busyindicator-background-simple" + color: control.running ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Button.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Button.qml new file mode 100644 index 00000000000..993c585bd92 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Button.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Button { + id: control + objectName: "button-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Text { + objectName: "button-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "button-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/CheckBox.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/CheckBox.qml new file mode 100644 index 00000000000..f4a95f0feb4 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/CheckBox.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.CheckBox { + id: control + objectName: "checkbox-simple" + + implicitWidth: contentItem.implicitWidth + indicator.implicitWidth + implicitHeight: Math.max(contentItem.implicitHeight, indicator.implicitHeight) + + indicator: Text { + objectName: "checkbox-indicator-simple" + text: control.checked ? "V" : "" + } + + contentItem: Text { + objectName: "checkbox-contentItem-simple" + text: control.text + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/CheckDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/CheckDelegate.qml new file mode 100644 index 00000000000..563db329453 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/CheckDelegate.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.CheckDelegate { + id: control + objectName: "checkdelegate-simple" + + implicitWidth: Math.max(contentItem.implicitWidth + indicator.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, indicator.implicitHeight, background.implicitHeight) + + indicator: Text { + objectName: "checkdelegate-indicator-simple" + text: control.checked ? "V" : "" + } + + contentItem: Text { + objectName: "checkdelegate-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "checkdelegate-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/ComboBox.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/ComboBox.qml new file mode 100644 index 00000000000..ed8613891b1 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/ComboBox.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ComboBox { + id: control + objectName: "combobox-simple" + + implicitWidth: Math.max(contentItem.implicitWidth + indicator.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, indicator.implicitHeight, background.implicitHeight) + + indicator: Text { + objectName: "combobox-indicator-simple" + text: control.comboed ? "V" : "" + } + + contentItem: Text { + objectName: "combobox-contentItem-simple" + text: control.currentText + } + + background: Rectangle { + objectName: "combobox-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.down ? "red" : "green" + } + + popup: T.Popup { + objectName: "combobox-popup-simple" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Container.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Container.qml new file mode 100644 index 00000000000..4a150096476 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Container.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Container { + id: control + objectName: "container-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "container-contentItem-simple" + } + + background: Item { + objectName: "container-background-simple" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Control.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Control.qml new file mode 100644 index 00000000000..e083f8acb18 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Control.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Control { + id: control + objectName: "control-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "control-contentItem-simple" + } + + background: Item { + objectName: "control-background-simple" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/DelayButton.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/DelayButton.qml new file mode 100644 index 00000000000..8f33c401568 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/DelayButton.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.DelayButton { + id: control + objectName: "delaybutton-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Text { + objectName: "delaybutton-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "delaybutton-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Dial.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Dial.qml new file mode 100644 index 00000000000..c1a9b50ba09 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Dial.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Dial { + id: control + objectName: "dial-simple" + + implicitWidth: Math.max(handle.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(handle.implicitHeight, background.implicitHeight) + + handle: Rectangle { + objectName: "dial-handle-simple" + color: control.pressed ? "red" : "green" + } + + background: Rectangle { + objectName: "dial-background-simple" + implicitWidth: 200 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Dialog.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Dialog.qml new file mode 100644 index 00000000000..787acca9b38 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Dialog.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Dialog { + id: control + objectName: "dialog-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Text { + objectName: "dialog-contentItem-simple" + } + + background: Rectangle { + objectName: "dialog-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/DialogButtonBox.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/DialogButtonBox.qml new file mode 100644 index 00000000000..d7da32e0ade --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/DialogButtonBox.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.DialogButtonBox { + id: control + objectName: "dialogbuttonbox-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "dialogbuttonbox-contentItem-simple" + } + + background: Item { + objectName: "dialogbuttonbox-background-simple" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Drawer.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Drawer.qml new file mode 100644 index 00000000000..8239b1afcab --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Drawer.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Drawer { + id: control + objectName: "drawer-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "drawer-contentItem-simple" + } + + background: Rectangle { + objectName: "drawer-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Frame.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Frame.qml new file mode 100644 index 00000000000..cbeb3c5dc50 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Frame.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Frame { + id: control + objectName: "frame-simple" + + implicitWidth: Math.max(background.implicitWidth, contentWidth) + implicitHeight: Math.max(background.implicitHeight, contentHeight) + + contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0) + contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0) + + contentItem: Item { + objectName: "frame-contentItem-simple" + } + + background: Rectangle { + objectName: "frame-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/GroupBox.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/GroupBox.qml new file mode 100644 index 00000000000..14dc33414d6 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/GroupBox.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.GroupBox { + id: control + objectName: "groupbox-simple" + + implicitWidth: Math.max(background.implicitWidth, contentWidth) + implicitHeight: Math.max(background.implicitHeight, contentHeight) + + contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0) + contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0) + + contentItem: Item { + objectName: "groupbox-contentItem-simple" + } + + background: Rectangle { + objectName: "groupbox-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } + + label: Text { + objectName: "groupbox-label-simple" + text: control.title + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/ItemDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/ItemDelegate.qml new file mode 100644 index 00000000000..a22ec3aa391 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/ItemDelegate.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ItemDelegate { + id: control + objectName: "itemdelegate-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Text { + objectName: "itemdelegate-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "itemdelegate-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Label.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Label.qml new file mode 100644 index 00000000000..80b34723c7c --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Label.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Label { + id: control + objectName: "label-simple" + + background: Rectangle { + objectName: "label-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Menu.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Menu.qml new file mode 100644 index 00000000000..7538bd5b7e6 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Menu.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Menu { + id: control + objectName: "menu-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: ListView { + objectName: "menu-contentItem-simple" + } + + background: Rectangle { + objectName: "menu-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/MenuBar.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/MenuBar.qml new file mode 100644 index 00000000000..a38c876e9ab --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/MenuBar.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuBar { + id: control + objectName: "menubar-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "menubar-contentItem-simple" + } + + background: Rectangle { + objectName: "menubar-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/MenuBarItem.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/MenuBarItem.qml new file mode 100644 index 00000000000..de9dc929115 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/MenuBarItem.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuBarItem { + id: control + objectName: "menubaritem-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Text { + objectName: "menubaritem-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "menubaritem-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/MenuItem.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/MenuItem.qml new file mode 100644 index 00000000000..28d5998b229 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/MenuItem.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuItem { + id: control + objectName: "menuitem-simple" + + implicitWidth: Math.max(contentItem.implicitWidth + indicator.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, indicator.implicitHeight, background.implicitHeight) + + arrow: Text { + objectName: "menuitem-arrow-simple" + text: control.mirrored ? "<" : ">" + } + + indicator: Text { + objectName: "menuitem-indicator-simple" + text: control.checked ? "V" : "" + } + + contentItem: Text { + objectName: "menuitem-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "menuitem-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/MenuSeparator.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/MenuSeparator.qml new file mode 100644 index 00000000000..3df17b5825e --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/MenuSeparator.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.MenuSeparator { + id: control + objectName: "menuseparator-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Text { + objectName: "menuseparator-contentItem-simple" + } + + background: Rectangle { + objectName: "menuseparator-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Page.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Page.qml new file mode 100644 index 00000000000..51ec6063636 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Page.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Page { + id: control + objectName: "page-simple" + + implicitWidth: Math.max(background.implicitWidth, contentWidth) + implicitHeight: Math.max(background.implicitHeight, contentHeight) + + contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0) + contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0) + + contentItem: Item { + objectName: "page-contentItem-simple" + } + + background: Rectangle { + objectName: "page-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/PageIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/PageIndicator.qml new file mode 100644 index 00000000000..d508687f1c0 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/PageIndicator.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.PageIndicator { + id: control + objectName: "pageindicator-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "pageindicator-contentItem-simple" + } + + background: Item { + objectName: "pageindicator-background-simple" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Pane.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Pane.qml new file mode 100644 index 00000000000..3b9e12b8c3d --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Pane.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Pane { + id: control + objectName: "pane-simple" + + implicitWidth: Math.max(background.implicitWidth, contentWidth) + implicitHeight: Math.max(background.implicitHeight, contentHeight) + + contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0) + contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0) + + contentItem: Item { + objectName: "pane-contentItem-simple" + } + + background: Rectangle { + objectName: "pane-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Popup.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Popup.qml new file mode 100644 index 00000000000..8b62fcade01 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Popup.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Popup { + id: control + objectName: "popup-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "popup-contentItem-simple" + } + + background: Rectangle { + objectName: "popup-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/ProgressBar.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/ProgressBar.qml new file mode 100644 index 00000000000..3f04e6b22ac --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/ProgressBar.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ProgressBar { + id: control + objectName: "progressbar-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "progressbar-contentItem-simple" + } + + background: Rectangle { + objectName: "progressbar-background-simple" + color: control.indeterminate ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/RadioButton.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/RadioButton.qml new file mode 100644 index 00000000000..7ca5973bc3b --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/RadioButton.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RadioButton { + id: control + objectName: "radiobutton-simple" + + implicitWidth: contentItem.implicitWidth + indicator.implicitWidth + implicitHeight: Math.max(contentItem.implicitHeight, indicator.implicitHeight) + + indicator: Text { + objectName: "radiobutton-indicator-simple" + text: control.checked ? "O" : "" + } + + contentItem: Text { + objectName: "radiobutton-contentItem-simple" + text: control.text + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/RadioDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/RadioDelegate.qml new file mode 100644 index 00000000000..bc96ad47aa0 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/RadioDelegate.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RadioDelegate { + id: control + objectName: "radiodelegate-simple" + + implicitWidth: Math.max(contentItem.implicitWidth + indicator.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, indicator.implicitHeight, background.implicitHeight) + + indicator: Text { + objectName: "radiodelegate-indicator-simple" + text: control.radioed ? "V" : "" + } + + contentItem: Text { + objectName: "radiodelegate-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "radiodelegate-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/RangeSlider.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/RangeSlider.qml new file mode 100644 index 00000000000..202688c48ba --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/RangeSlider.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RangeSlider { + id: control + objectName: "rangeslider-simple" + + implicitWidth: Math.max(control.first.handle.implicitWidth, control.second.handle.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(control.first.handle.implicitHeight, control.second.handle.implicitHeight, background.implicitHeight) + + first.handle: Rectangle { + objectName: "rangeslider-first.handle-simple" + color: control.first.pressed ? "red" : "green" + } + + second.handle: Rectangle { + objectName: "rangeslider-second.handle-simple" + color: control.second.pressed ? "red" : "green" + } + + background: Rectangle { + objectName: "rangeslider-background-simple" + implicitWidth: 200 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/RoundButton.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/RoundButton.qml new file mode 100644 index 00000000000..3547239f395 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/RoundButton.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.RoundButton { + id: control + objectName: "roundbutton-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Text { + objectName: "roundbutton-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "roundbutton-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + radius: control.radius + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/ScrollBar.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/ScrollBar.qml new file mode 100644 index 00000000000..25bc3e09ec9 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/ScrollBar.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ScrollBar { + id: control + objectName: "scrollbar-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "scrollbar-contentItem-simple" + } + + background: Item { + objectName: "scrollbar-background-simple" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/ScrollIndicator.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/ScrollIndicator.qml new file mode 100644 index 00000000000..a901671bba4 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/ScrollIndicator.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ScrollIndicator { + id: control + objectName: "scrollindicator-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "scrollindicator-contentItem-simple" + } + + background: Item { + objectName: "scrollindicator-background-simple" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/ScrollView.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/ScrollView.qml new file mode 100644 index 00000000000..56334d841dc --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/ScrollView.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ScrollView { + id: control + objectName: "scrollview-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + background: Rectangle { + objectName: "scrollview-background-simple" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Slider.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Slider.qml new file mode 100644 index 00000000000..d5417404f06 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Slider.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Slider { + id: control + objectName: "slider-simple" + + implicitWidth: Math.max(handle.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(handle.implicitHeight, background.implicitHeight) + + handle: Rectangle { + objectName: "slider-handle-simple" + color: control.pressed ? "red" : "green" + } + + background: Rectangle { + objectName: "slider-background-simple" + implicitWidth: 200 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/SpinBox.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/SpinBox.qml new file mode 100644 index 00000000000..0facffad597 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/SpinBox.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SpinBox { + id: control + objectName: "spinbox-simple" + + implicitWidth: Math.max(contentItem.implicitWidth + up.indicator.implicitWidth + down.indicator.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, up.indicator.implicitHeight, down.indicator.implicitHeight, background.implicitHeight) + + up.indicator: Rectangle { + objectName: "spinbox-up.indicator-simple" + color: control.up.pressed ? "red" : "green" + } + + down.indicator: Rectangle { + objectName: "spinbox-down.indicator-simple" + color: control.down.pressed ? "red" : "green" + } + + contentItem: Text { + objectName: "spinbox-contentItem-simple" + } + + background: Rectangle { + objectName: "spinbox-background-simple" + implicitWidth: 200 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/StackView.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/StackView.qml new file mode 100644 index 00000000000..e16b9938bcf --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/StackView.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.StackView { + id: control + objectName: "stackview-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "stackview-contentItem-simple" + } + + background: Item { + objectName: "stackview-background-simple" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/SwipeDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/SwipeDelegate.qml new file mode 100644 index 00000000000..fec9f120faa --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/SwipeDelegate.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwipeDelegate { + id: control + objectName: "swipedelegate-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Text { + objectName: "swipedelegate-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "swipedelegate-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/SwipeView.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/SwipeView.qml new file mode 100644 index 00000000000..cf154b6b97f --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/SwipeView.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwipeView { + id: control + objectName: "swipeview-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Item { + objectName: "swipeview-contentItem-simple" + } + + background: Item { + objectName: "swipeview-background-simple" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Switch.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Switch.qml new file mode 100644 index 00000000000..9e9613084a9 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Switch.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Switch { + id: control + objectName: "switch-simple" + + implicitWidth: contentItem.implicitWidth + indicator.implicitWidth + implicitHeight: Math.max(contentItem.implicitHeight, indicator.implicitHeight) + + indicator: Item { + objectName: "switch-indicator-simple" + } + + contentItem: Item { + objectName: "switch-contentItem-simple" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/SwitchDelegate.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/SwitchDelegate.qml new file mode 100644 index 00000000000..f7eb1d5c370 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/SwitchDelegate.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.SwitchDelegate { + id: control + objectName: "switchdelegate-simple" + + implicitWidth: Math.max(contentItem.implicitWidth + indicator.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, indicator.implicitHeight, background.implicitHeight) + + indicator: Text { + objectName: "switchdelegate-indicator-simple" + text: control.radioed ? "V" : "" + } + + contentItem: Text { + objectName: "switchdelegate-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "switchdelegate-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/TabBar.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/TabBar.qml new file mode 100644 index 00000000000..6b0f2b63271 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/TabBar.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TabBar { + id: control + objectName: "tabbar-simple" + + implicitWidth: Math.max(background.implicitWidth, contentItem.implicitWidth) + implicitHeight: Math.max(background.implicitHeight, contentItem.implicitHeight) + + contentItem: Item { + objectName: "tabbar-contentItem-simple" + } + + background: Rectangle { + objectName: "tabbar-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/TabButton.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/TabButton.qml new file mode 100644 index 00000000000..4c8a30ba819 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/TabButton.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TabButton { + id: control + objectName: "tabbutton-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Text { + objectName: "tabbutton-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "tabbutton-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/TextArea.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/TextArea.qml new file mode 100644 index 00000000000..7e906433fe4 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/TextArea.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TextArea { + id: control + objectName: "textarea-simple" + + implicitWidth: Math.max(contentWidth, background.implicitWidth) + implicitHeight: Math.max(contentHeight, background.implicitHeight) + + background: Rectangle { + objectName: "textarea-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/TextField.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/TextField.qml new file mode 100644 index 00000000000..71a685349bc --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/TextField.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.TextField { + id: control + objectName: "textfield-simple" + + implicitWidth: Math.max(contentWidth, background.implicitWidth) + implicitHeight: Math.max(contentHeight, background.implicitHeight) + + background: Rectangle { + objectName: "textfield-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/ToolBar.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/ToolBar.qml new file mode 100644 index 00000000000..30bba195e46 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/ToolBar.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolBar { + id: control + objectName: "toolbar-simple" + + implicitWidth: Math.max(background.implicitWidth, contentWidth) + implicitHeight: Math.max(background.implicitHeight, contentHeight) + + contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0) + contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0) + + contentItem: Item { + objectName: "toolbar-contentItem-simple" + } + + background: Rectangle { + objectName: "toolbar-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/ToolButton.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/ToolButton.qml new file mode 100644 index 00000000000..229b75368a8 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/ToolButton.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolButton { + id: control + objectName: "toolbutton-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Text { + objectName: "toolbutton-contentItem-simple" + text: control.text + } + + background: Rectangle { + objectName: "toolbutton-background-simple" + implicitWidth: 20 + implicitHeight: 20 + color: control.pressed ? "red" : "green" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/ToolSeparator.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/ToolSeparator.qml new file mode 100644 index 00000000000..8ee00bc36ca --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/ToolSeparator.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolSeparator { + id: control + objectName: "toolseparator-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Text { + objectName: "toolseparator-contentItem-simple" + } + + background: Rectangle { + objectName: "toolseparator-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/ToolTip.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/ToolTip.qml new file mode 100644 index 00000000000..0299adf1819 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/ToolTip.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.ToolTip { + id: control + objectName: "tooltip-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: Text { + objectName: "tooltip-contentItem-simple" + } + + background: Rectangle { + objectName: "tooltip-background-simple" + implicitWidth: 20 + implicitHeight: 20 + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/Tumbler.qml b/tests/auto/quickcontrols2/customization/data/styles/simple/Tumbler.qml new file mode 100644 index 00000000000..34f423c7eb1 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/Tumbler.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Tumbler { + id: control + objectName: "tumbler-simple" + + implicitWidth: Math.max(contentItem.implicitWidth, background.implicitWidth) + implicitHeight: Math.max(contentItem.implicitHeight, background.implicitHeight) + + contentItem: ListView { + objectName: "tumbler-contentItem-simple" + } + + background: Rectangle { + objectName: "tumbler-background-simple" + } +} diff --git a/tests/auto/quickcontrols2/customization/data/styles/simple/qmldir b/tests/auto/quickcontrols2/customization/data/styles/simple/qmldir new file mode 100644 index 00000000000..e5159885cb5 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/data/styles/simple/qmldir @@ -0,0 +1,59 @@ +module simple + +AbstractButton 6.0 AbstractButton.qml +Action 6.0 Action.qml +ActionGroup 6.0 ActionGroup.qml +ApplicationWindow 6.0 ApplicationWindow.qml +BusyIndicator 6.0 BusyIndicator.qml +Button 6.0 Button.qml +ButtonGroup 6.0 ButtonGroup.qml +CheckBox 6.0 CheckBox.qml +CheckDelegate 6.0 CheckDelegate.qml +ComboBox 6.0 ComboBox.qml +Container 6.0 Container.qml +Control 6.0 Control.qml +DelayButton 6.0 DelayButton.qml +Dial 6.0 Dial.qml +Dialog 6.0 Dialog.qml +DialogButtonBox 6.0 DialogButtonBox.qml +Drawer 6.0 Drawer.qml +Frame 6.0 Frame.qml +GroupBox 6.0 GroupBox.qml +HorizontalHeaderView 6.0 HorizontalHeaderView.qml +ItemDelegate 6.0 ItemDelegate.qml +Label 6.0 Label.qml +Menu 6.0 Menu.qml +MenuBar 6.0 MenuBar.qml +MenuBarItem 6.0 MenuBarItem.qml +MenuItem 6.0 MenuItem.qml +MenuSeparator 6.0 MenuSeparator.qml +Page 6.0 Page.qml +PageIndicator 6.0 PageIndicator.qml +Pane 6.0 Pane.qml +Popup 6.0 Popup.qml +ProgressBar 6.0 ProgressBar.qml +RadioButton 6.0 RadioButton.qml +RadioDelegate 6.0 RadioDelegate.qml +RangeSlider 6.0 RangeSlider.qml +RoundButton 6.0 RoundButton.qml +ScrollBar 6.0 ScrollBar.qml +ScrollIndicator 6.0 ScrollIndicator.qml +ScrollView 6.0 ScrollView.qml +Slider 6.0 Slider.qml +SpinBox 6.0 SpinBox.qml +SplitView 6.0 SplitView.qml +StackView 6.0 StackView.qml +SwipeDelegate 6.0 SwipeDelegate.qml +SwipeView 6.0 SwipeView.qml +Switch 6.0 Switch.qml +SwitchDelegate 6.0 SwitchDelegate.qml +TabBar 6.0 TabBar.qml +TabButton 6.0 TabButton.qml +TextArea 6.0 TextArea.qml +TextField 6.0 TextField.qml +ToolBar 6.0 ToolBar.qml +ToolButton 6.0 ToolButton.qml +ToolSeparator 6.0 ToolSeparator.qml +ToolTip 6.0 ToolTip.qml +Tumbler 6.0 Tumbler.qml +VerticalHeaderView 6.0 VerticalHeaderView.qml diff --git a/tests/auto/quickcontrols2/customization/dummy_imports.qml b/tests/auto/quickcontrols2/customization/dummy_imports.qml new file mode 100644 index 00000000000..40d9cea7120 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/dummy_imports.qml @@ -0,0 +1,9 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +QtObject { } diff --git a/tests/auto/quickcontrols2/customization/tst_customization.cpp b/tests/auto/quickcontrols2/customization/tst_customization.cpp new file mode 100644 index 00000000000..0829e29e3d3 --- /dev/null +++ b/tests/auto/quickcontrols2/customization/tst_customization.cpp @@ -0,0 +1,543 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtCore/private/qhooks_p.h> +#include <QtCore/qregularexpression.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> +#include <QtQuickControls2/qquickstyle.h> +#include <QtQuickControls2/private/qquickstyle_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p_p.h> + +using namespace QQuickControlsTestUtils; + +struct ControlInfo +{ + QString type; + QStringList delegates; +}; + +static const ControlInfo ControlInfos[] = { + { "AbstractButton", QStringList() << "background" << "contentItem" << "indicator" }, + { "ApplicationWindow", QStringList() << "background" }, + { "BusyIndicator", QStringList() << "background" << "contentItem" }, + { "Button", QStringList() << "background" << "contentItem" }, + { "CheckBox", QStringList() << "contentItem" << "indicator" }, + { "CheckDelegate", QStringList() << "background" << "contentItem" << "indicator" }, + { "ComboBox", QStringList() << "background" << "contentItem" << "indicator" }, // popup not created until needed + { "Container", QStringList() << "background" << "contentItem" }, + { "Control", QStringList() << "background" << "contentItem" }, + { "DelayButton", QStringList() << "background" << "contentItem" }, + { "Dial", QStringList() << "background" << "handle" }, + { "Dialog", QStringList() << "background" << "contentItem" }, + { "DialogButtonBox", QStringList() << "background" << "contentItem" }, + { "Drawer", QStringList() << "background" << "contentItem" }, + { "Frame", QStringList() << "background" << "contentItem" }, + { "GroupBox", QStringList() << "background" << "contentItem" << "label" }, + { "ItemDelegate", QStringList() << "background" << "contentItem" }, + { "Label", QStringList() << "background" }, + { "Menu", QStringList() << "background" << "contentItem" }, + { "MenuBar", QStringList() << "background" << "contentItem" }, + { "MenuBarItem", QStringList() << "background" << "contentItem" }, + { "MenuItem", QStringList() << "arrow" << "background" << "contentItem" << "indicator" }, + { "MenuSeparator", QStringList() << "background" << "contentItem" }, + { "Page", QStringList() << "background" << "contentItem" }, + { "PageIndicator", QStringList() << "background" << "contentItem" }, + { "Pane", QStringList() << "background" << "contentItem" }, + { "Popup", QStringList() << "background" << "contentItem" }, + { "ProgressBar", QStringList() << "background" << "contentItem" }, + { "RadioButton", QStringList() << "contentItem" << "indicator" }, + { "RadioDelegate", QStringList() << "background" << "contentItem" << "indicator" }, + { "RangeSlider", QStringList() << "background" << "first.handle" << "second.handle" }, + { "RoundButton", QStringList() << "background" << "contentItem" }, + { "ScrollBar", QStringList() << "background" << "contentItem" }, + { "ScrollIndicator", QStringList() << "background" << "contentItem" }, + { "ScrollView", QStringList() << "background" }, + { "Slider", QStringList() << "background" << "handle" }, + { "SpinBox", QStringList() << "background" << "contentItem" << "up.indicator" << "down.indicator" }, + { "StackView", QStringList() << "background" << "contentItem" }, + { "SwipeDelegate", QStringList() << "background" << "contentItem" }, + { "SwipeView", QStringList() << "background" << "contentItem" }, + { "Switch", QStringList() << "contentItem" << "indicator" }, + { "SwitchDelegate", QStringList() << "background" << "contentItem" << "indicator" }, + { "TabBar", QStringList() << "background" << "contentItem" }, + { "TabButton", QStringList() << "background" << "contentItem" }, + { "TextField", QStringList() << "background" }, + { "TextArea", QStringList() << "background" }, + { "ToolBar", QStringList() << "background" << "contentItem" }, + { "ToolButton", QStringList() << "background" << "contentItem" }, + { "ToolSeparator", QStringList() << "background" << "contentItem" }, + { "ToolTip", QStringList() << "background" << "contentItem" }, + { "Tumbler", QStringList() << "background" << "contentItem" } +}; + +class tst_customization : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_customization(); + +private slots: + void initTestCase() override; + void cleanupTestCase(); + + void init(); + void cleanup(); + + void creation_data(); + void creation(); + + void override_data(); + void override(); + + void comboPopup(); + +private: + void reset(); + void addHooks(); + void removeHooks(); + + QObject* createControl(const QString &type, const QString &qml, QString *error); + + QQmlEngine *engine = nullptr; +}; + +typedef QHash<QObject *, QString> QObjectNameHash; +Q_GLOBAL_STATIC(QObjectNameHash, qt_objectNames) +Q_GLOBAL_STATIC(QStringList, qt_createdQObjects) +Q_GLOBAL_STATIC(QStringList, qt_destroyedQObjects) +Q_GLOBAL_STATIC(QStringList, qt_destroyedParentQObjects) +static int qt_unparentedItemCount = 0; + +class ItemParentListener : public QQuickItem +{ + Q_OBJECT + +public: + ItemParentListener() + { + m_slotIndex = metaObject()->indexOfSlot("onParentChanged()"); + m_signalIndex = QMetaObjectPrivate::signalIndex(QMetaMethod::fromSignal(&QQuickItem::parentChanged)); + } + + int signalIndex() const { return m_signalIndex; } + int slotIndex() const { return m_slotIndex; } + +public slots: + void onParentChanged() + { + const QQuickItem *item = qobject_cast<QQuickItem *>(sender()); + if (!item) + return; + + if (!item->parentItem()) + ++qt_unparentedItemCount; + } + +private: + int m_slotIndex; + int m_signalIndex; +}; +static ItemParentListener *qt_itemParentListener = nullptr; + +extern "C" Q_DECL_EXPORT void qt_addQObject(QObject *object) +{ + // objectName is not set at construction time + QObject::connect(object, &QObject::objectNameChanged, [object](const QString &objectName) { + QString oldObjectName = qt_objectNames()->value(object); + if (!oldObjectName.isEmpty()) + qt_createdQObjects()->removeOne(oldObjectName); + // Only track object names from our QML files, + // not e.g. contentItem object names (like "ApplicationWindow"). + if (objectName.contains("-")) { + qt_createdQObjects()->append(objectName); + qt_objectNames()->insert(object, objectName); + } + }); + + if (qt_itemParentListener) { + static const int signalIndex = qt_itemParentListener->signalIndex(); + static const int slotIndex = qt_itemParentListener->slotIndex(); + QMetaObject::connect(object, signalIndex, qt_itemParentListener, slotIndex); + } +} + +extern "C" Q_DECL_EXPORT void qt_removeQObject(QObject *object) +{ + QString objectName = object->objectName(); + if (!objectName.isEmpty()) + qt_destroyedQObjects()->append(objectName); + qt_objectNames()->remove(object); + + QObject *parent = object->parent(); + if (parent) { + QString parentName = parent->objectName(); + if (!parentName.isEmpty()) + qt_destroyedParentQObjects()->append(parentName); + } +} + +tst_customization::tst_customization() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_customization::initTestCase() +{ + QQmlDataTest::initTestCase(); + + qt_itemParentListener = new ItemParentListener; +} + +void tst_customization::cleanupTestCase() +{ + delete qt_itemParentListener; + qt_itemParentListener = nullptr; +} + +void tst_customization::init() +{ + engine = new QQmlEngine(this); + engine->addImportPath(testFile("styles")); + + qtHookData[QHooks::AddQObject] = reinterpret_cast<quintptr>(&qt_addQObject); + qtHookData[QHooks::RemoveQObject] = reinterpret_cast<quintptr>(&qt_removeQObject); +} + +void tst_customization::cleanup() +{ + qtHookData[QHooks::AddQObject] = 0; + qtHookData[QHooks::RemoveQObject] = 0; + + delete engine; + engine = nullptr; + + qmlClearTypeRegistrations(); + + reset(); +} + +void tst_customization::reset() +{ + qt_unparentedItemCount = 0; + qt_createdQObjects()->clear(); + qt_destroyedQObjects()->clear(); + qt_destroyedParentQObjects()->clear(); +} + +QObject* tst_customization::createControl(const QString &name, const QString &qml, QString *error) +{ + QQmlComponent component(engine); + component.setData("import QtQuick; import QtQuick.Window; import QtQuick.Controls; " + name.toUtf8() + " { " + qml.toUtf8() + " }", QUrl()); + QObject *obj = component.create(); + if (!obj) + *error = component.errorString(); + return obj; +} + +void tst_customization::creation_data() +{ + QTest::addColumn<QString>("style"); + QTest::addColumn<QString>("type"); + QTest::addColumn<QStringList>("delegates"); + + // the "empty" style does not contain any delegates + for (const ControlInfo &control : ControlInfos) + QTest::newRow(qPrintable("empty:" + control.type)) << "empty" << control.type << QStringList(); + + // the "incomplete" style is missing bindings to the delegates (must be created regardless) + for (const ControlInfo &control : ControlInfos) + QTest::newRow(qPrintable("incomplete:" + control.type)) << "incomplete" << control.type << control.delegates; + + // the "identified" style has IDs in the delegates (prevents deferred execution) + for (const ControlInfo &control : ControlInfos) + QTest::newRow(qPrintable("identified:" + control.type)) << "identified" << control.type << control.delegates; + + // the "simple" style simulates a proper style and contains bindings to/in delegates + for (const ControlInfo &control : ControlInfos) + QTest::newRow(qPrintable("simple:" + control.type)) << "simple" << control.type << control.delegates; + + // the "override" style overrides all delegates in the "simple" style + for (const ControlInfo &control : ControlInfos) + QTest::newRow(qPrintable("override:" + control.type)) << "override" << control.type << control.delegates; +} + +void tst_customization::creation() +{ + QFETCH(QString, style); + QFETCH(QString, type); + QFETCH(QStringList, delegates); + + QQuickStyle::setStyle(style); + + QString error; + QScopedPointer<QObject> control(createControl(type, "", &error)); + QVERIFY2(control, qPrintable(error)); + + QByteArray templateType = "QQuick" + type.toUtf8(); + QVERIFY2(control->inherits(templateType), qPrintable(type + " does not inherit " + templateType + " (" + control->metaObject()->className() + ")")); + + // <control>-<style> + QString controlName = type.toLower() + "-" + style; + QCOMPARE(control->objectName(), controlName); + QVERIFY2(qt_createdQObjects()->removeOne(controlName), qPrintable(controlName + " was not created as expected")); + + for (QString delegate : qAsConst(delegates)) { + QStringList properties = delegate.split(".", Qt::SkipEmptyParts); + + // <control>-<delegate>-<style>(-<override>) + delegate.append("-" + style); + delegate.prepend(type.toLower() + "-"); + + QVERIFY2(qt_createdQObjects()->removeOne(delegate), qPrintable(delegate + " was not created as expected")); + + // verify that the delegate instance has the expected object name + // in case of grouped properties, we must query the properties step by step + QObject *instance = control.data(); + while (!properties.isEmpty()) { + QString property = properties.takeFirst(); + instance = instance->property(property.toUtf8()).value<QObject *>(); + QVERIFY2(instance, qPrintable("property was null: " + property)); + } + QCOMPARE(instance->objectName(), delegate); + } + + QEXPECT_FAIL("identified:ComboBox", "ComboBox::popup with an ID is created at construction time", Continue); + + QVERIFY2(qt_createdQObjects()->isEmpty(), qPrintable("unexpectedly created: " + qt_createdQObjects->join(", "))); + QVERIFY2(qt_destroyedQObjects()->isEmpty(), qPrintable("unexpectedly destroyed: " + qt_destroyedQObjects->join(", ") + " were unexpectedly destroyed")); + + QVERIFY2(qt_destroyedParentQObjects()->isEmpty(), qPrintable("delegates/children of: " + qt_destroyedParentQObjects->join(", ") + " were unexpectedly destroyed")); +} + +void tst_customization::override_data() +{ + QTest::addColumn<QString>("style"); + QTest::addColumn<QString>("type"); + QTest::addColumn<QStringList>("delegates"); + QTest::addColumn<QString>("nonDeferred"); + QTest::addColumn<bool>("identify"); + + // NOTE: delegates with IDs prevent deferred execution + + // default delegates with IDs, override with custom delegates with no IDs + for (const ControlInfo &control : ControlInfos) + QTest::newRow(qPrintable("identified:" + control.type)) << "identified" << control.type << control.delegates << "identified" << false; + + // default delegates with no IDs, override with custom delegates with IDs + for (const ControlInfo &control : ControlInfos) + QTest::newRow(qPrintable("simple:" + control.type)) << "simple" << control.type << control.delegates << "" << true; + + // default delegates with IDs, override with custom delegates with IDs + for (const ControlInfo &control : ControlInfos) + QTest::newRow(qPrintable("overidentified:" + control.type)) << "identified" << control.type << control.delegates << "identified" << true; + +#ifndef Q_OS_MACOS // QTBUG-65671 + + // test that the built-in styles don't have undesired IDs in their delegates + const QStringList styles = QQuickStylePrivate::builtInStyles(); + for (const QString &style : styles) { + for (const ControlInfo &control : ControlInfos) + QTest::newRow(qPrintable(style + ":" + control.type)) << style << control.type << control.delegates << "" << false; + } + +#endif +} + +void tst_customization::override() +{ + QFETCH(QString, style); + QFETCH(QString, type); + QFETCH(QStringList, delegates); + QFETCH(QString, nonDeferred); + QFETCH(bool, identify); + + QQuickStyle::setStyle(style); + + QString qml; + qml += QString("objectName: '%1-%2-override'; ").arg(type.toLower()).arg(style); + for (const QString &delegate : delegates) { + QString id = identify ? QString("id: %1;").arg(delegate) : QString(); + qml += QString("%1: Item { %2 objectName: '%3-%1-%4-override' } ").arg(delegate).arg(id.replace(".", "")).arg(type.toLower()).arg(style); + } + + QString error; + QScopedPointer<QObject> control(createControl(type, qml, &error)); + QVERIFY2(control, qPrintable(error)); + + // If there are no intentional IDs in the default delegates nor in the overridden custom + // delegates, no item should get un-parented during the creation process. An item being + // unparented means that a delegate got destroyed, so there must be an internal ID in one + // of the delegates in the tested style. + if (!identify && nonDeferred.isEmpty()) { + QEXPECT_FAIL("Universal:ApplicationWindow", "ApplicationWindow.qml contains an intentionally unparented FocusRectangle", Continue); + QCOMPARE(qt_unparentedItemCount, 0); + } + + // <control>-<style>-override + QString controlName = type.toLower() + "-" + style + "-override"; + QCOMPARE(control->objectName(), controlName); + QVERIFY2(qt_createdQObjects()->removeOne(controlName), qPrintable(controlName + " was not created as expected")); + + for (QString delegate : qAsConst(delegates)) { + QStringList properties = delegate.split(".", Qt::SkipEmptyParts); + + // <control>-<delegate>-<style>(-override) + delegate.append("-" + style); + delegate.prepend(type.toLower() + "-"); + + if (!nonDeferred.isEmpty()) + QVERIFY2(qt_createdQObjects()->removeOne(delegate), qPrintable(delegate + " was not created as expected")); + + delegate.append("-override"); + QVERIFY2(qt_createdQObjects()->removeOne(delegate), qPrintable(delegate + " was not created as expected")); + + // verify that the delegate instance has the expected object name + // in case of grouped properties, we must query the properties step by step + QObject *instance = control.data(); + while (!properties.isEmpty()) { + QString property = properties.takeFirst(); + instance = instance->property(property.toUtf8()).value<QObject *>(); + QVERIFY2(instance, qPrintable("property was null: " + property)); + } + QCOMPARE(instance->objectName(), delegate); + } + + QEXPECT_FAIL("identified:ComboBox", "ComboBox::popup with an ID is created at construction time", Continue); + QEXPECT_FAIL("overidentified:ComboBox", "ComboBox::popup with an ID is created at construction time", Continue); + QVERIFY2(qt_createdQObjects()->isEmpty(), qPrintable("unexpectedly created: " + qt_createdQObjects->join(", "))); + + if (!nonDeferred.isEmpty()) { + // There were items for which deferred execution was not possible. + for (QString delegateName : qAsConst(delegates)) { + if (!delegateName.contains("-")) + delegateName.append("-" + nonDeferred); + delegateName.prepend(type.toLower() + "-"); + + const int delegateIndex = qt_destroyedQObjects()->indexOf(delegateName); + QVERIFY2(delegateIndex == -1, qPrintable(delegateName + " was unexpectedly destroyed")); + + const auto controlChildren = control->children(); + const auto childIt = std::find_if(controlChildren.constBegin(), controlChildren.constEnd(), [delegateName](const QObject *child) { + return child->objectName() == delegateName; + }); + // We test other delegates (like the background) here, so make sure we don't end up with XPASSes by using the wrong delegate. + if (delegateName.contains(QLatin1String("handle"))) { + QEXPECT_FAIL("identified:RangeSlider", "For some reason, items that are belong to grouped properties fail here", Abort); + QEXPECT_FAIL("overidentified:RangeSlider", "For some reason, items that are belong to grouped properties fail here", Abort); + } + if (delegateName.contains(QLatin1String("indicator"))) { + QEXPECT_FAIL("identified:SpinBox", "For some reason, items that are belong to grouped properties fail here", Abort); + QEXPECT_FAIL("overidentified:SpinBox", "For some reason, items that are belong to grouped properties fail here", Abort); + } + QVERIFY2(childIt != controlChildren.constEnd(), qPrintable(QString::fromLatin1( + "Expected delegate \"%1\" to still be a QObject child of \"%2\"").arg(delegateName).arg(controlName))); + + const auto *delegate = qobject_cast<QQuickItem*>(*childIt); + // Ensure that the item is hidden, etc. + QVERIFY(delegate); + QCOMPARE(delegate->isVisible(), false); + QCOMPARE(delegate->parentItem(), nullptr); + } + } + + QVERIFY2(qt_destroyedQObjects()->isEmpty(), qPrintable("unexpectedly destroyed: " + qt_destroyedQObjects->join(", "))); +} + +void tst_customization::comboPopup() +{ + QQuickStyle::setStyle("simple"); + + { + // test that ComboBox::popup is created when accessed + QQmlComponent component(engine); + component.setData("import QtQuick.Controls; ComboBox { }", QUrl()); + QScopedPointer<QQuickItem> comboBox(qobject_cast<QQuickItem *>(component.create())); + QVERIFY(comboBox); + + QVERIFY(!qt_createdQObjects()->contains("combobox-popup-simple")); + + QObject *popup = comboBox->property("popup").value<QObject *>(); + QVERIFY(popup); + QVERIFY(qt_createdQObjects()->contains("combobox-popup-simple")); + } + + reset(); + + { + // test that ComboBox::popup is created when it becomes visible + QQuickWindow window; + window.resize(300, 300); + window.show(); + window.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&window)); + + QQmlComponent component(engine); + component.setData("import QtQuick.Controls; ComboBox { }", QUrl()); + QScopedPointer<QQuickItem> comboBox(qobject_cast<QQuickItem *>(component.create())); + QVERIFY(comboBox); + + comboBox->setParentItem(window.contentItem()); + QVERIFY(!qt_createdQObjects()->contains("combobox-popup-simple")); + + QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QVERIFY(qt_createdQObjects()->contains("combobox-popup-simple")); + } + + reset(); + + { + // test that ComboBox::popup is completed upon component completion (if appropriate) + QQmlComponent component(engine); + component.setData("import QtQuick; import QtQuick.Controls; ComboBox { id: control; contentItem: Item { visible: !control.popup.visible } popup: Popup { property bool wasCompleted: false; Component.onCompleted: wasCompleted = true } }", QUrl()); + QScopedPointer<QQuickItem> comboBox(qobject_cast<QQuickItem *>(component.create())); + QVERIFY(comboBox); + + QObject *popup = comboBox->property("popup").value<QObject *>(); + QVERIFY(popup); + QCOMPARE(popup->property("wasCompleted"), QVariant(true)); + } +} + +QTEST_MAIN(tst_customization) + +#include "tst_customization.moc" diff --git a/tests/auto/quickcontrols2/deferred/CMakeLists.txt b/tests/auto/quickcontrols2/deferred/CMakeLists.txt new file mode 100644 index 00000000000..900732ef4ee --- /dev/null +++ b/tests/auto/quickcontrols2/deferred/CMakeLists.txt @@ -0,0 +1,25 @@ +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickdeferred + SOURCES + tst_qquickdeferred.cpp + LIBRARIES + Qt::Qml + Qt::QmlPrivate + Qt::QuickTemplates2Private + Qt::QuickTestUtilsPrivate + TESTDATA ${test_data} +) + +qt_internal_extend_target(tst_qquickdeferred CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickdeferred CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/deferred/data/noSpuriousBinding.qml b/tests/auto/quickcontrols2/deferred/data/noSpuriousBinding.qml new file mode 100644 index 00000000000..9f6a174cf45 --- /dev/null +++ b/tests/auto/quickcontrols2/deferred/data/noSpuriousBinding.qml @@ -0,0 +1,15 @@ +import test +import QtQuick + +Item { + id: root + property bool toggle: true + property int counter: 0 + + x: toggle ? 100 : tester.objectProperty.x + + DeferredPropertyTester { + id: tester + objectProperty: Item { x: { console.log("hi"); return 300; } } + } +} diff --git a/tests/auto/quickcontrols2/deferred/tst_qquickdeferred.cpp b/tests/auto/quickcontrols2/deferred/tst_qquickdeferred.cpp new file mode 100644 index 00000000000..4d8096aa468 --- /dev/null +++ b/tests/auto/quickcontrols2/deferred/tst_qquickdeferred.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtTest/qtest.h> +#include <QQmlEngine> +#include <QtQuick/qquickitem.h> +#include <QtQuickTemplates2/private/qquickdeferredexecute_p_p.h> + +class DeferredPropertyTester : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickItem *objectProperty READ objectProperty WRITE setObjectProperty NOTIFY objectChanged) + Q_CLASSINFO("DeferredPropertyNames", "objectProperty") + +public: + DeferredPropertyTester() {} + + + QQuickItem *objectProperty() { + + if (!m_object.wasExecuted()) { + quickBeginDeferred(this, "objectProperty", m_object); + quickCompleteDeferred(this, "objectProperty", m_object); + } + + return m_object; + } + void setObjectProperty(QQuickItem *obj) { + if (m_object == obj) + return; + m_object = obj; + if (!m_object.isExecuting()) // first read + emit objectChanged(); + } + +signals: + void objectChanged(); + +private: + QQuickDeferredPointer<QQuickItem> m_object = nullptr; +}; + +class tst_qquickdeferred : public QQmlDataTest +{ + Q_OBJECT +public: + tst_qquickdeferred() : QQmlDataTest(QT_QMLTEST_DATADIR) {} +private slots: + void noSpuriousBinding(); +}; + + + +void tst_qquickdeferred::noSpuriousBinding() { + qmlRegisterType<DeferredPropertyTester>("test", 1, 0, "DeferredPropertyTester"); + + QQmlEngine engine; + QQmlComponent comp(&engine, testFileUrl("noSpuriousBinding.qml")); + std::unique_ptr<QObject> root(comp.create()); + QVERIFY2(root, qPrintable(comp.errorString())); + root->setProperty("toggle", false); +} + +QTEST_MAIN(tst_qquickdeferred) + +#include "tst_qquickdeferred.moc" diff --git a/tests/auto/quickcontrols2/designer/CMakeLists.txt b/tests/auto/quickcontrols2/designer/CMakeLists.txt new file mode 100644 index 00000000000..d13b014c936 --- /dev/null +++ b/tests/auto/quickcontrols2/designer/CMakeLists.txt @@ -0,0 +1,22 @@ +# Generated from designer.pro. + +##################################################################### +## tst_designer Test: +##################################################################### + +qt_internal_add_test(tst_designer + SOURCES + tst_designer.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Quick + Qt::QuickControls2 + Qt::QuickTemplates2 + Qt::QuickPrivate +) + +#### Keys ignored in scope 1:.:.:designer.pro:<TRUE>: +# TEMPLATE = "app" + +## Scopes: +##################################################################### diff --git a/tests/auto/quickcontrols2/designer/dummy_imports.qml b/tests/auto/quickcontrols2/designer/dummy_imports.qml new file mode 100644 index 00000000000..401692e570e --- /dev/null +++ b/tests/auto/quickcontrols2/designer/dummy_imports.qml @@ -0,0 +1,8 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQuick +import QtQuick.Controls + +QtObject { } diff --git a/tests/auto/quickcontrols2/designer/tst_designer.cpp b/tests/auto/quickcontrols2/designer/tst_designer.cpp new file mode 100644 index 00000000000..0f6598a6002 --- /dev/null +++ b/tests/auto/quickcontrols2/designer/tst_designer.cpp @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest> +#include <QtQuick> + +#include <QtQuickControls2> +#include <QQmlComponent> +#include <QDir> + +#include <private/qquickdesignersupportitems_p.h> + +class tst_Designer : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + + void test_controls(); + void test_controls_data(); +}; + + +void tst_Designer::initTestCase() +{ + QQuickStyle::setStyle("Basic"); +} + +void doComponentCompleteRecursive(QObject *object) +{ + if (object) { + QQuickItem *item = qobject_cast<QQuickItem*>(object); + + if (item && DesignerSupport::isComponentComplete(item)) + return; + + DesignerSupport::emitComponentCompleteSignalForAttachedProperty(qobject_cast<QQuickItem*>(object)); + + QList<QObject*> childList = object->children(); + + if (item) { + for (QQuickItem *childItem : item->childItems()) { + if (!childList.contains(childItem)) + childList.append(childItem); + } + } + + for (QObject *child : childList) + doComponentCompleteRecursive(child); + + if (item) { + static_cast<QQmlParserStatus*>(item)->componentComplete(); + } else { + QQmlParserStatus *qmlParserStatus = dynamic_cast< QQmlParserStatus*>(object); + if (qmlParserStatus) + qmlParserStatus->componentComplete(); + } + } +} + + +void tst_Designer::test_controls() +{ + QFETCH(QString, type); + + const QByteArray before("import QtQuick\n" + "import QtQuick.Controls\n" + "Item {\n"); + + QByteArray source = before; + source.append(type.toUtf8()); + + const QByteArray after(" {" + "}\n" + "}\n"); + + source.append(after); + + QQmlEngine engine; + QQmlComponent component(&engine); + + { + ComponentCompleteDisabler disableComponentComplete; + component.setData(source, QUrl::fromLocalFile(QDir::current().absolutePath())); + } + + QObject *root = component.create(); + QVERIFY(root); + doComponentCompleteRecursive(root); +} + +void tst_Designer::test_controls_data() +{ + QTest::addColumn<QString>("type"); + + QTest::newRow("Button") << "Button"; + QTest::newRow("CheckBox") << "CheckBox"; + QTest::newRow("ComboBox") << "ComboBox"; + QTest::newRow("DelayButton") << "DelayButton"; + QTest::newRow("Dial") << "Dial"; + QTest::newRow("Frame") << "Frame"; + QTest::newRow("GroupBox") << "GroupBox"; + QTest::newRow("Label") << "Label"; + QTest::newRow("Page") << "Page"; + QTest::newRow("Pane") << "Pane"; + QTest::newRow("ProgressBar") << "ProgressBar"; + QTest::newRow("RadioButton") << "RadioButton"; + QTest::newRow("RangeSlider") << "RangeSlider"; + QTest::newRow("RoundButton") << "RoundButton"; + QTest::newRow("ScrollView") << "ScrollView"; + QTest::newRow("Slider") << "Slider"; + QTest::newRow("SpinBox") << "SpinBox"; + QTest::newRow("StackView") << "StackView"; + QTest::newRow("SwipeView") << "SwipeView"; + QTest::newRow("Switch") << "Switch"; + QTest::newRow("Switch") << "Switch"; + QTest::newRow("TabBar") << "TabBar"; + QTest::newRow("TabButton") << "TabButton"; + QTest::newRow("TextArea") << "TextArea"; + QTest::newRow("TextField") << "TextField"; + QTest::newRow("ToolBar") << "ToolBar"; + QTest::newRow("ToolButton") << "ToolButton"; + QTest::newRow("Tumbler") << "Tumbler"; +} + +QTEST_MAIN(tst_Designer) + +#include "tst_designer.moc" diff --git a/tests/auto/quickcontrols2/focus/BLACKLIST b/tests/auto/quickcontrols2/focus/BLACKLIST new file mode 100644 index 00000000000..730d3844756 --- /dev/null +++ b/tests/auto/quickcontrols2/focus/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-78261 +[policy] +opensuse-leap diff --git a/tests/auto/quickcontrols2/focus/CMakeLists.txt b/tests/auto/quickcontrols2/focus/CMakeLists.txt new file mode 100644 index 00000000000..8f6d53f7da9 --- /dev/null +++ b/tests/auto/quickcontrols2/focus/CMakeLists.txt @@ -0,0 +1,45 @@ +# Generated from focus.pro. + +##################################################################### +## tst_focus Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_focus + SOURCES + tst_focus.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_focus CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_focus CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/focus/data/activeFocusOnTab.qml b/tests/auto/quickcontrols2/focus/data/activeFocusOnTab.qml new file mode 100644 index 00000000000..6b57f39b1ef --- /dev/null +++ b/tests/auto/quickcontrols2/focus/data/activeFocusOnTab.qml @@ -0,0 +1,203 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + id: main + objectName: "main" + width: 400 + height: 800 + focus: true + Component.onCompleted: button1.focus = true + Column { + anchors.fill: parent + id: column + objectName: "column" + BusyIndicator { + id: busyindicator + objectName: "busyindicator" + } + Button { + id: button1 + objectName: "button1" + text: "button1" + } + Button { + id: button2 + objectName: "button2" + text: "button2" + } + CheckBox { + id: checkbox + objectName: "checkbox" + text: "checkbox" + } + GroupBox { + id: groupbox1 + objectName: "groupbox1" + title: "grouppox1" + Column { + anchors.fill: parent + CheckBox { + id: checkbox1 + objectName: "checkbox1" + text: "checkbox1" + } + CheckBox { + id: checkbox2 + objectName: "checkbox2" + text: "checkbox2" + } + } + } + Label { + id: label + objectName: "label" + text: "label" + } + PageIndicator { + id: pageindicator + objectName: "pageindicator" + } + ProgressBar { + id: progressbar + objectName: "progressbar" + indeterminate: true + } + RadioButton { + id: radiobutton + objectName: "radiobutton" + text: "radiobutton" + } + GroupBox { + id: groupbox2 + objectName: "groupbox2" + title: "groupbox2" + Column { + anchors.fill: parent + RadioButton { + id: radiobutton1 + objectName: "radiobutton1" + text: "radiobutton1" + } + RadioButton { + id: radiobutton2 + objectName: "radiobutton2" + text: "radiobutton2" + } + } + } + RangeSlider { + id: rangeslider + objectName: "rangeslider" + first.handle.objectName: "rangeslider.first" + second.handle.objectName: "rangeslider.second" + } + // ScrollBar + ScrollIndicator { + id: scrollindicator + objectName: "scrollindicator" + } + Slider { + id: slider + objectName: "slider" + value: 0.5 + } + SpinBox { + id: spinbox + objectName: "spinbox" + editable: true + value: 50 + } + // StackView + Switch { + id: swtich // switch + objectName: "switch" + text: "switch" + } + TabBar { + width: parent.width + id: tabbar + objectName: "tabbar" + TabButton { + id: tabbutton1 + objectName: "tabbutton1" + text: "tabbutton1" + } + TabButton { + id: tabbutton2 + objectName: "tabbutton2" + text: "tabbutton2" + } + } + TextField { + id: textfield + objectName: "textfield" + text: "abc" + } + ToolBar { + width: parent.width + id: toolbar + objectName: "toolbar" + ToolButton { + id: toolbutton + objectName: "toolbutton" + text: "toolbutton" + } + } + TextArea { + id: textarea + objectName: "textarea" + text: "abc" + } + } +} diff --git a/tests/auto/quickcontrols2/focus/data/focusReason.qml b/tests/auto/quickcontrols2/focus/data/focusReason.qml new file mode 100644 index 00000000000..0f8a61f05e8 --- /dev/null +++ b/tests/auto/quickcontrols2/focus/data/focusReason.qml @@ -0,0 +1,99 @@ +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Item { + Component.onCompleted: control.focus = true + width: 640 + height: 480 + + Column { + anchors.top: parent.top + anchors.topMargin: 10 + spacing: 10 + + Control { + id: control + implicitWidth: 100 + implicitHeight: 20 + objectName: "control" + activeFocusOnTab: true + + Menu { + id: contextMenu + objectName: "contextMenu" + MenuItem { + text: "Hello" + } + MenuItem { + text: "World" + } + } + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: function onClicked(mouseEvent) { + if (mouseEvent.button == Qt.RightButton) + contextMenu.visible = true + } + } + } + + ComboBox { + id: combobox + objectName: "combobox" + model: ["Banana", "Apple", "Coconut"] + activeFocusOnTab: true + } + + ComboBox { + id: editcombo + objectName: "editcombo" + editable: true + model: ["Kiwi", "Mango", "Pomelo"] + activeFocusOnTab: true + } + + SpinBox { + id: spinbox + objectName: "spinbox" + from: 0 + to: 100 + value: 20 + editable: true + activeFocusOnTab: true + } + + Control { + id: customText + objectName: "customText" + implicitWidth: 100 + implicitHeight: 50 + contentItem: TextInput { + text: parent.visualFocus ? "focus" : "no focus" + } + activeFocusOnTab: true + } + + Control { + id: customItem + objectName: "customItem" + implicitWidth: 100 + implicitHeight: 50 + contentItem: Rectangle { + anchors.fill: parent + color: parent.activeFocus ? "red" : "blue" + opacity: 0.3 + } + focusPolicy: Qt.WheelFocus + activeFocusOnTab: true + } + + TextField { + id: textfield + objectName: "textfield" + text: "test123" + activeFocusOnTab: true + } + } +} diff --git a/tests/auto/quickcontrols2/focus/data/keyNavigation.qml b/tests/auto/quickcontrols2/focus/data/keyNavigation.qml new file mode 100644 index 00000000000..7ac8e014cde --- /dev/null +++ b/tests/auto/quickcontrols2/focus/data/keyNavigation.qml @@ -0,0 +1,260 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + id: main + objectName: "main" + width: 400 + height: 800 + focus: true + Component.onCompleted: button1.focus = true + Column { + anchors.fill: parent + id: column + objectName: "column" + BusyIndicator { + id: busyindicator + objectName: "busyindicator" + } + Button { + id: button1 + objectName: "button1" + text: "button1" + KeyNavigation.up: textarea + KeyNavigation.down: button2 + KeyNavigation.left: toolbutton + KeyNavigation.right: button2 + } + Button { + id: button2 + objectName: "button2" + text: "button2" + KeyNavigation.up: button1 + KeyNavigation.down: checkbox + KeyNavigation.left: button1 + KeyNavigation.right: checkbox + } + CheckBox { + id: checkbox + objectName: "checkbox" + text: "checkbox" + KeyNavigation.up: button2 + KeyNavigation.down: checkbox1 + KeyNavigation.left: button2 + KeyNavigation.right: checkbox1 + } + GroupBox { + id: groupbox1 + objectName: "groupbox1" + title: "grouppox1" + Column { + anchors.fill: parent + CheckBox { + id: checkbox1 + objectName: "checkbox1" + text: "checkbox1" + KeyNavigation.up: checkbox + KeyNavigation.down: checkbox2 + KeyNavigation.left: checkbox + KeyNavigation.right: checkbox2 + } + CheckBox { + id: checkbox2 + objectName: "checkbox2" + text: "checkbox2" + KeyNavigation.up: checkbox1 + KeyNavigation.down: radiobutton + KeyNavigation.left: checkbox1 + KeyNavigation.right: radiobutton + } + } + } + Label { + id: label + objectName: "label" + text: "label" + } + PageIndicator { + id: pageindicator + objectName: "pageindicator" + } + ProgressBar { + id: progressbar + objectName: "progressbar" + indeterminate: true + } + RadioButton { + id: radiobutton + objectName: "radiobutton" + text: "radiobutton" + KeyNavigation.up: checkbox2 + KeyNavigation.down: radiobutton1 + KeyNavigation.left: checkbox2 + KeyNavigation.right: radiobutton1 + } + GroupBox { + id: groupbox2 + objectName: "groupbox2" + title: "groupbox2" + Column { + anchors.fill: parent + RadioButton { + id: radiobutton1 + objectName: "radiobutton1" + text: "radiobutton1" + KeyNavigation.up: radiobutton + KeyNavigation.down: radiobutton2 + KeyNavigation.left: radiobutton + KeyNavigation.right: radiobutton2 + } + RadioButton { + id: radiobutton2 + objectName: "radiobutton2" + text: "radiobutton2" + KeyNavigation.up: radiobutton1 + KeyNavigation.down: rangeslider + KeyNavigation.left: radiobutton1 + KeyNavigation.right: spinbox + } + } + } + RangeSlider { + id: rangeslider + objectName: "rangeslider" + first.handle.objectName: "rangeslider.first" + second.handle.objectName: "rangeslider.second" + KeyNavigation.up: radiobutton2 + KeyNavigation.down: slider + } + // ScrollBar + ScrollIndicator { + id: scrollindicator + objectName: "scrollindicator" + } + Slider { + id: slider + objectName: "slider" + value: 0.5 + KeyNavigation.up: rangeslider + KeyNavigation.down: swtich + } + SpinBox { + id: spinbox + objectName: "spinbox" + value: 50 + KeyNavigation.left: radiobutton2 + KeyNavigation.right: swtich + } + // StackView + Switch { + id: swtich // switch + objectName: "switch" + text: "switch" + KeyNavigation.up: slider + KeyNavigation.down: tabbutton1 + KeyNavigation.left: spinbox + KeyNavigation.right: tabbutton1 + } + TabBar { + width: parent.width + id: tabbar + objectName: "tabbar" + TabButton { + id: tabbutton1 + objectName: "tabbutton1" + text: "tabbutton1" + KeyNavigation.up: swtich + KeyNavigation.down: tabbutton2 + KeyNavigation.left: swtich + KeyNavigation.right: tabbutton2 + } + TabButton { + id: tabbutton2 + objectName: "tabbutton2" + text: "tabbutton2" + KeyNavigation.up: tabbutton1 + KeyNavigation.down: textfield + KeyNavigation.left: tabbutton1 + KeyNavigation.right: toolbutton + } + } + TextField { + id: textfield + objectName: "textfield" + text: "abc" + KeyNavigation.up: tabbutton2 + KeyNavigation.down: toolbutton + } + ToolBar { + width: parent.width + id: toolbar + objectName: "toolbar" + ToolButton { + id: toolbutton + objectName: "toolbutton" + text: "toolbutton" + KeyNavigation.up: textfield + KeyNavigation.down: textarea + KeyNavigation.left: tabbutton2 + KeyNavigation.right: button1 + } + } + TextArea { + id: textarea + objectName: "textarea" + text: "abc" + KeyNavigation.up: toolbutton + KeyNavigation.down: button1 + } + } +} diff --git a/tests/auto/quickcontrols2/focus/data/visualFocus.qml b/tests/auto/quickcontrols2/focus/data/visualFocus.qml new file mode 100644 index 00000000000..2f516be7679 --- /dev/null +++ b/tests/auto/quickcontrols2/focus/data/visualFocus.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Column { + width: 400 + height: 400 + Button { + text: "Button" + property bool showFocus: visualFocus + } + TextField { + text: "TextField" + } +} diff --git a/tests/auto/quickcontrols2/focus/tst_focus.cpp b/tests/auto/quickcontrols2/focus/tst_focus.cpp new file mode 100644 index 00000000000..daa6a9991aa --- /dev/null +++ b/tests/auto/quickcontrols2/focus/tst_focus.cpp @@ -0,0 +1,549 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QtTest/QSignalSpy> +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/qpointingdevice.h> +#include <QtGui/qstylehints.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlcontext.h> +#include <QtQuick/qquickview.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickControls2/qquickstyle.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> + +using namespace QQuickVisualTestUtils; +using namespace QQuickControlsTestUtils; + +class tst_focus : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_focus(); + +private slots: + void initTestCase() override; + + void navigation_data(); + void navigation(); + + void policy_data(); + void policy(); + + void reason(); + + void visualFocus(); + + void scope_data(); + void scope(); +}; + +tst_focus::tst_focus() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_focus::initTestCase() +{ + QQuickStyle::setStyle("Basic"); + QQmlDataTest::initTestCase(); +} + +void tst_focus::navigation_data() +{ + QTest::addColumn<Qt::Key>("key"); + QTest::addColumn<QString>("testFile"); + QTest::addColumn<Qt::TabFocusBehavior>("behavior"); + QTest::addColumn<QStringList>("order"); + + QTest::newRow("tab-all-controls") << Qt::Key_Tab << QString("activeFocusOnTab.qml") << Qt::TabFocusAllControls << (QStringList() << "button2" << "checkbox" << "checkbox1" << "checkbox2" << "radiobutton" << "radiobutton1" << "radiobutton2" << "rangeslider.first" << "rangeslider.second" << "slider" << "spinbox" << "switch" << "tabbutton1" << "tabbutton2" << "textfield" << "toolbutton" << "textarea" << "button1"); + QTest::newRow("backtab-all-controls") << Qt::Key_Backtab << QString("activeFocusOnTab.qml") << Qt::TabFocusAllControls << (QStringList() << "textarea" << "toolbutton" << "textfield" << "tabbutton2" << "tabbutton1" << "switch" << "spinbox" << "slider" << "rangeslider.second" << "rangeslider.first" << "radiobutton2" << "radiobutton1" << "radiobutton" << "checkbox2" << "checkbox1" << "checkbox" << "button2" << "button1"); + + QTest::newRow("tab-text-controls") << Qt::Key_Tab << QString("activeFocusOnTab.qml") << Qt::TabFocusTextControls << (QStringList() << "spinbox" << "textfield" << "textarea"); + QTest::newRow("backtab-text-controls") << Qt::Key_Backtab << QString("activeFocusOnTab.qml") << Qt::TabFocusTextControls << (QStringList() << "textarea" << "textfield" << "spinbox"); + + QTest::newRow("key-up") << Qt::Key_Up << QString("keyNavigation.qml") << Qt::TabFocusAllControls << (QStringList() << "textarea" << "toolbutton" << "textfield" << "tabbutton2" << "tabbutton1" << "switch" << "slider" << "rangeslider.first" << "radiobutton2" << "radiobutton1" << "radiobutton" << "checkbox2" << "checkbox1" << "checkbox" << "button2" << "button1"); + QTest::newRow("key-down") << Qt::Key_Down << QString("keyNavigation.qml") << Qt::TabFocusAllControls << (QStringList() << "button2" << "checkbox" << "checkbox1" << "checkbox2" << "radiobutton" << "radiobutton1" << "radiobutton2" << "rangeslider.first" << "slider" << "switch" << "tabbutton1" << "tabbutton2" << "textfield" << "toolbutton" << "textarea" << "button1"); + QTest::newRow("key-left") << Qt::Key_Left << QString("keyNavigation.qml") << Qt::TabFocusAllControls << (QStringList() << "toolbutton" << "tabbutton2" << "tabbutton1" << "switch" << "spinbox" << "radiobutton2" << "radiobutton1" << "radiobutton" << "checkbox2" << "checkbox1" << "checkbox" << "button2" << "button1"); + QTest::newRow("key-right") << Qt::Key_Right << QString("keyNavigation.qml") << Qt::TabFocusAllControls << (QStringList() << "button2" << "checkbox" << "checkbox1" << "checkbox2" << "radiobutton" << "radiobutton1" << "radiobutton2" << "spinbox" << "switch" << "tabbutton1" << "tabbutton2" << "toolbutton" << "button1"); +} + +void tst_focus::navigation() +{ + QFETCH(Qt::Key, key); + QFETCH(QString, testFile); + QFETCH(Qt::TabFocusBehavior, behavior); + QFETCH(QStringList, order); + + QGuiApplication::styleHints()->setTabFocusBehavior(behavior); + + QQuickView view; + view.contentItem()->setObjectName("contentItem"); + + view.setSource(testFileUrl(testFile)); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + QVERIFY(QGuiApplication::focusWindow() == &view); + + for (const QString &name : qAsConst(order)) { + QKeyEvent event(QEvent::KeyPress, key, Qt::NoModifier); + QGuiApplication::sendEvent(&view, &event); + QVERIFY(event.isAccepted()); + + QQuickItem *item = findItem<QQuickItem>(view.rootObject(), name); + QVERIFY2(item, qPrintable(name)); + QVERIFY2(item->hasActiveFocus(), qPrintable(QString("expected: '%1', actual: '%2'").arg(name).arg(view.activeFocusItem() ? view.activeFocusItem()->objectName() : "null"))); + } + + QGuiApplication::styleHints()->setTabFocusBehavior(Qt::TabFocusBehavior(-1)); +} + +void tst_focus::policy_data() +{ + QTest::addColumn<QString>("name"); + + QTest::newRow("Control") << "Control"; + QTest::newRow("ComboBox") << "ComboBox"; + QTest::newRow("Button") << "Button"; + QTest::newRow("Slider") << "Slider"; + QTest::newRow("ScrollBar") << "ScrollBar"; +} + +void tst_focus::policy() +{ + QFETCH(QString, name); + + QQmlEngine engine; + QScopedPointer<QPointingDevice> device(QTest::createTouchDevice()); + QQmlComponent component(&engine); + component.setData(QString("import QtQuick.Controls; ApplicationWindow { width: 100; height: 100; %1 { anchors.fill: parent } }").arg(name).toUtf8(), QUrl()); + + QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(component.create())); + QVERIFY(window); + + QQuickControl *control = qobject_cast<QQuickControl *>(window->contentItem()->childItems().first()); + QVERIFY(control); + + QVERIFY(!control->hasActiveFocus()); + QVERIFY(!control->hasVisualFocus()); + + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + control->setFocusPolicy(Qt::NoFocus); + QCOMPARE(control->focusPolicy(), Qt::NoFocus); + + // Qt::TabFocus vs. QQuickItem::activeFocusOnTab + control->setActiveFocusOnTab(true); + QCOMPARE(control->focusPolicy(), Qt::TabFocus); + control->setActiveFocusOnTab(false); + QCOMPARE(control->focusPolicy(), Qt::NoFocus); + + control->setFocusPolicy(Qt::TabFocus); + QCOMPARE(control->focusPolicy(), Qt::TabFocus); + QCOMPARE(control->activeFocusOnTab(), true); + + // Qt::TabFocus + QGuiApplication::styleHints()->setTabFocusBehavior(Qt::TabFocusAllControls); + QTest::keyClick(window.data(), Qt::Key_Tab); + QVERIFY(control->hasActiveFocus()); + QVERIFY(control->hasVisualFocus()); + QGuiApplication::styleHints()->setTabFocusBehavior(Qt::TabFocusBehavior(-1)); + + // reset + control->setFocus(false); + QVERIFY(!control->hasActiveFocus()); + + // Qt::ClickFocus (mouse) + control->setFocusPolicy(Qt::NoFocus); + control->setAcceptedMouseButtons(Qt::LeftButton); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(control->width() / 2, control->height() / 2)); + QVERIFY(!control->hasActiveFocus()); + QVERIFY(!control->hasVisualFocus()); + + control->setFocusPolicy(Qt::ClickFocus); + QCOMPARE(control->focusPolicy(), Qt::ClickFocus); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(control->width() / 2, control->height() / 2)); + QVERIFY(control->hasActiveFocus()); + QVERIFY(!control->hasVisualFocus()); + + // reset + control->setFocus(false); + QVERIFY(!control->hasActiveFocus()); + + // Qt::ClickFocus (touch) + control->setFocusPolicy(Qt::NoFocus); + QTest::touchEvent(window.data(), device.data()).press(0, QPoint(control->width() / 2, control->height() / 2)); + QTest::touchEvent(window.data(), device.data()).release(0, QPoint(control->width() / 2, control->height() / 2)); + QVERIFY(!control->hasActiveFocus()); + QVERIFY(!control->hasVisualFocus()); + + control->setFocusPolicy(Qt::ClickFocus); + QCOMPARE(control->focusPolicy(), Qt::ClickFocus); + QTest::touchEvent(window.data(), device.data()).press(0, QPoint(control->width() / 2, control->height() / 2)); + QTest::touchEvent(window.data(), device.data()).release(0, QPoint(control->width() / 2, control->height() / 2)); + QVERIFY(control->hasActiveFocus()); + QVERIFY(!control->hasVisualFocus()); + + // reset + control->setFocus(false); + QVERIFY(!control->hasActiveFocus()); + + // Qt::WheelFocus + QWheelEvent wheelEvent(QPointF(control->width() / 2, control->height() / 2), QPointF(), + QPoint(), QPoint(0, 10), Qt::NoButton, Qt::NoModifier, + Qt::NoScrollPhase, false); + QGuiApplication::sendEvent(control, &wheelEvent); + QVERIFY(!control->hasActiveFocus()); + QVERIFY(!control->hasVisualFocus()); + + control->setFocusPolicy(Qt::WheelFocus); + QCOMPARE(control->focusPolicy(), Qt::WheelFocus); + + QGuiApplication::sendEvent(control, &wheelEvent); + QVERIFY(control->hasActiveFocus()); + QVERIFY(!control->hasVisualFocus()); +} + +void tst_focus::reason() +{ + QGuiApplication::styleHints()->setTabFocusBehavior(Qt::TabFocusAllControls); + auto resetTabFocusBehavior = qScopeGuard([]{ + QGuiApplication::styleHints()->setTabFocusBehavior(Qt::TabFocusBehavior(-1)); + }); + + QQuickView view; + view.setSource(testFileUrl("focusReason.qml")); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickControl *control = view.findChild<QQuickControl *>("control"); + QQuickControl *combobox = view.findChild<QQuickControl *>("combobox"); + QQuickControl *editcombo = view.findChild<QQuickControl *>("editcombo"); + QQuickControl *spinbox = view.findChild<QQuickControl *>("spinbox"); + QQuickControl *customText = view.findChild<QQuickControl *>("customText"); + QQuickControl *customItem = view.findChild<QQuickControl *>("customItem"); + // not a QQuickControl subclass + QQuickItem *textfield = view.findChild<QQuickItem *>("textfield"); + + // helper for clicking into a control + const auto itemCenter = [](const QQuickItem *item) -> QPoint { + return item->mapToScene(item->clipRect().center()).toPoint(); + }; + + QVERIFY(control); + QVERIFY(combobox); + QVERIFY(editcombo); + QVERIFY(spinbox); + QVERIFY(textfield); + QVERIFY(customText); + QVERIFY(customItem); + + // setting focusPolicy to Strong/WheelFocus doesn't implicitly turn on event delivery + customText->setAcceptedMouseButtons(Qt::LeftButton); + customItem->setAcceptedMouseButtons(Qt::LeftButton); + customItem->setWheelEnabled(true); + + // window activation -> ActiveWindowFocusReason + QVERIFY(control->hasFocus()); + QVERIFY(control->hasActiveFocus()); + if (control->focusReason() != Qt::ActiveWindowFocusReason + && QStringList{"windows", "offscreen"}.contains(QGuiApplication::platformName())) { + QEXPECT_FAIL("", "On Windows and offscreen platforms, window activation does not set focus reason", Continue); + } + QCOMPARE(control->focusReason(), Qt::ActiveWindowFocusReason); + + // test setter/getter + control->setFocus(false, Qt::MouseFocusReason); + QCOMPARE(control->focusReason(), Qt::MouseFocusReason); + control->setFocus(true, Qt::TabFocusReason); + QCOMPARE(control->focusReason(), Qt::TabFocusReason); + control->setFocus(false, Qt::BacktabFocusReason); + QCOMPARE(control->focusReason(), Qt::BacktabFocusReason); + control->forceActiveFocus(Qt::ShortcutFocusReason); + QCOMPARE(control->focusReason(), Qt::ShortcutFocusReason); + control->setFocusReason(Qt::PopupFocusReason); + QCOMPARE(control->focusReason(), Qt::PopupFocusReason); + + // programmatic focus changes + combobox->setFocus(true, Qt::OtherFocusReason); + QCOMPARE(control->focusReason(), Qt::OtherFocusReason); + + QVERIFY(combobox->hasFocus()); + QVERIFY(combobox->hasActiveFocus()); + QCOMPARE(combobox->focusReason(), Qt::OtherFocusReason); + + // tab focus -> TabFocusReason + QTest::keyClick(&view, Qt::Key_Tab); + QVERIFY(editcombo->hasFocus()); + QVERIFY(editcombo->hasActiveFocus()); + QCOMPARE(qApp->focusObject(), editcombo->contentItem()); + QCOMPARE(combobox->focusReason(), Qt::TabFocusReason); + QCOMPARE(editcombo->focusReason(), Qt::TabFocusReason); + editcombo->setFocusReason(Qt::NoFocusReason); // reset so that we can verify that focusOut sets it + + QTest::keyClick(&view, Qt::Key_Tab); + QVERIFY(spinbox->hasFocus()); + QVERIFY(spinbox->hasActiveFocus()); + QCOMPARE(qApp->focusObject(), spinbox->contentItem()); + QCOMPARE(editcombo->focusReason(), Qt::TabFocusReason); + QCOMPARE(spinbox->focusReason(), Qt::TabFocusReason); + spinbox->setFocusReason(Qt::NoFocusReason); + + QTest::keyClick(&view, Qt::Key_Tab); + QVERIFY(customText->hasFocus()); + QVERIFY(customText->hasActiveFocus()); + QCOMPARE(qApp->focusObject(), customText); + QCOMPARE(spinbox->focusReason(), Qt::TabFocusReason); + QCOMPARE(customText->focusReason(), Qt::TabFocusReason); + customText->setFocusReason(Qt::NoFocusReason); + + QTest::keyClick(&view, Qt::Key_Tab); + QCOMPARE(qApp->focusObject(), customItem); + QVERIFY(customItem->hasFocus()); + QVERIFY(customItem->hasActiveFocus()); + QCOMPARE(customText->focusReason(), Qt::TabFocusReason); + QCOMPARE(customItem->focusReason(), Qt::TabFocusReason); + customItem->setFocusReason(Qt::NoFocusReason); + + QTest::keyClick(&view, Qt::Key_Tab); + QVERIFY(textfield->hasFocus()); + QVERIFY(textfield->hasActiveFocus()); + QCOMPARE(qApp->focusObject(), textfield); + QCOMPARE(customItem->focusReason(), Qt::TabFocusReason); + + QTest::keyClick(&view, Qt::Key_Tab); + QVERIFY(control->hasFocus()); + QVERIFY(control->hasActiveFocus()); + QCOMPARE(control->focusReason(), Qt::TabFocusReason); + + // backtab -> BacktabFocusReason + QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier); + QVERIFY(textfield->hasFocus()); + QCOMPARE(control->focusReason(), Qt::BacktabFocusReason); + + QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier); + QVERIFY(customItem->hasFocus()); + QCOMPARE(customItem->focusReason(), Qt::BacktabFocusReason); + + QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier); + QVERIFY(customText->hasFocus()); + QCOMPARE(customText->focusReason(), Qt::BacktabFocusReason); + + QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier); + QVERIFY(spinbox->hasFocus()); + QCOMPARE(spinbox->focusReason(), Qt::BacktabFocusReason); + + QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier); + QVERIFY(editcombo->hasFocus()); + QCOMPARE(editcombo->focusReason(), Qt::BacktabFocusReason); + + QTest::keyClick(&view, Qt::Key_Tab, Qt::ShiftModifier); + QVERIFY(combobox->hasFocus()); + QCOMPARE(combobox->focusReason(), Qt::BacktabFocusReason); + + // click focus -> MouseFocusReason + QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(editcombo)); + QTRY_VERIFY(editcombo->hasFocus()); + QVERIFY(editcombo->contentItem()->hasFocus()); + QVERIFY(editcombo->hasActiveFocus()); + QVERIFY(editcombo->contentItem()->hasActiveFocus()); + QCOMPARE(editcombo->focusReason(), Qt::MouseFocusReason); + editcombo->setFocusReason(Qt::NoFocusReason); + + QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(combobox)); // opens popup + QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(combobox)); // closes popup + + QVERIFY(combobox->hasFocus()); + QVERIFY(combobox->hasActiveFocus()); + QCOMPARE(editcombo->focusReason(), Qt::MouseFocusReason); + QCOMPARE(combobox->focusReason(), Qt::MouseFocusReason); + combobox->setFocusReason(Qt::NoFocusReason); + + QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(spinbox)); + QVERIFY(spinbox->hasFocus()); + QVERIFY(spinbox->hasActiveFocus()); + QCOMPARE(combobox->focusReason(), Qt::MouseFocusReason); + QCOMPARE(spinbox->focusReason(), Qt::MouseFocusReason); + spinbox->setFocusReason(Qt::NoFocusReason); + + QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(customText)); + QTRY_VERIFY2(customText->contentItem()->hasFocus(), qPrintable(qApp->focusObject()->objectName())); + QVERIFY(customText->contentItem()->hasActiveFocus()); + QCOMPARE(spinbox->focusReason(), Qt::MouseFocusReason); + QCOMPARE(customText->focusReason(), Qt::MouseFocusReason); + customText->setFocusReason(Qt::NoFocusReason); + + QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(customItem)); + QVERIFY(customItem->hasFocus()); + QVERIFY(customItem->hasActiveFocus()); + QCOMPARE(customText->focusReason(), Qt::MouseFocusReason); + QCOMPARE(customItem->focusReason(), Qt::MouseFocusReason); + customItem->setFocusReason(Qt::NoFocusReason); + + QTest::mouseClick(&view, Qt::LeftButton, {}, itemCenter(textfield)); + QCOMPARE(customItem->focusReason(), Qt::MouseFocusReason); + customItem->setFocusReason(Qt::NoFocusReason); + customText->setFocusReason(Qt::NoFocusReason); + + // Wheel focus -> MouseFocusReason + QWheelEvent wheelEvent(QPointF(customItem->width() / 2, customItem->height() / 2), QPointF(), + QPoint(), QPoint(0, 10), Qt::NoButton, Qt::NoModifier, + Qt::NoScrollPhase, false); + QGuiApplication::sendEvent(customItem, &wheelEvent); + QVERIFY(customItem->hasActiveFocus()); + QCOMPARE(customItem->focusReason(), Qt::MouseFocusReason); + + // Popup opens -> PopupFocusReason + QTest::mouseClick(&view, Qt::RightButton, {}, itemCenter(control)); + QTRY_VERIFY(!customItem->hasActiveFocus()); + QCOMPARE(customItem->focusReason(), Qt::PopupFocusReason); + QTest::keyClick(&view, Qt::Key_Escape); // close the popup +} + +void tst_focus::visualFocus() +{ + QQuickView view; + view.setSource(testFileUrl("visualFocus.qml")); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickItem *column = view.rootObject(); + QVERIFY(column); + QCOMPARE(column->childItems().count(), 2); + + QQuickControl *button = qobject_cast<QQuickControl *>(column->childItems().first()); + QVERIFY(button); + + QQuickItem *textfield = column->childItems().last(); + QVERIFY(textfield); + + button->forceActiveFocus(Qt::TabFocusReason); + QVERIFY(button->hasActiveFocus()); + QVERIFY(button->hasVisualFocus()); + QVERIFY(button->property("showFocus").toBool()); + + QTest::mouseClick(&view, Qt::LeftButton, Qt::NoModifier, QPoint(textfield->x() + textfield->width() / 2, textfield->y() + textfield->height() / 2)); + QVERIFY(!button->hasActiveFocus()); + QVERIFY(!button->hasVisualFocus()); + QVERIFY(!button->property("showFocus").toBool()); +} + +void tst_focus::scope_data() +{ + QTest::addColumn<QString>("name"); + + QTest::newRow("Frame") << "Frame"; + QTest::newRow("GroupBox") << "Frame"; + QTest::newRow("Page") << "Page"; + QTest::newRow("Pane") << "Pane"; + QTest::newRow("StackView") << "StackView"; +} + +void tst_focus::scope() +{ + QFETCH(QString, name); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(QString("import QtQuick; import QtQuick.Controls; ApplicationWindow { property alias child: child; width: 100; height: 100; %1 { anchors.fill: parent; Item { id: child; width: 10; height: 10 } } }").arg(name).toUtf8(), QUrl()); + + QScopedPointer<QPointingDevice> device(QTest::createTouchDevice()); + QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(component.create())); + QVERIFY2(window, qPrintable(component.errorString())); + + QQuickControl *control = qobject_cast<QQuickControl *>(window->contentItem()->childItems().first()); + QVERIFY(control); + + control->setFocusPolicy(Qt::WheelFocus); + control->setAcceptedMouseButtons(Qt::LeftButton); + + QQuickItem *child = window->property("child").value<QQuickItem *>(); + QVERIFY(child); + + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + + child->forceActiveFocus(); + QVERIFY(child->hasActiveFocus()); + QVERIFY(control->hasActiveFocus()); + + // Qt::ClickFocus (mouse) + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(control->width() / 2, control->height() / 2)); + QVERIFY(!child->hasActiveFocus()); + QVERIFY(control->hasActiveFocus()); + + // reset + child->forceActiveFocus(); + QVERIFY(child->hasActiveFocus()); + QVERIFY(control->hasActiveFocus()); + + // Qt::ClickFocus (touch) + QTest::touchEvent(window.data(), device.data()).press(0, QPoint(control->width() / 2, control->height() / 2)); + QTest::touchEvent(window.data(), device.data()).release(0, QPoint(control->width() / 2, control->height() / 2)); + QVERIFY(!child->hasActiveFocus()); + QVERIFY(control->hasActiveFocus()); + + // reset + child->forceActiveFocus(); + QVERIFY(child->hasActiveFocus()); + QVERIFY(control->hasActiveFocus()); + + // Qt::WheelFocus + QWheelEvent wheelEvent(QPointF(control->width() / 2, control->height() / 2), QPointF(), + QPoint(), QPoint(0, 10), Qt::NoButton, Qt::NoModifier, + Qt::NoScrollPhase, false); + QGuiApplication::sendEvent(control, &wheelEvent); + QVERIFY(!child->hasActiveFocus()); + QVERIFY(control->hasActiveFocus()); +} + +QTEST_MAIN(tst_focus) + +#include "tst_focus.moc" diff --git a/tests/auto/quickcontrols2/font/CMakeLists.txt b/tests/auto/quickcontrols2/font/CMakeLists.txt new file mode 100644 index 00000000000..ce782668fb1 --- /dev/null +++ b/tests/auto/quickcontrols2/font/CMakeLists.txt @@ -0,0 +1,47 @@ +# Generated from font.pro. + +##################################################################### +## tst_font Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_font + SOURCES + tst_font.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:font.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_font CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_font CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/font/data/font-appwindow-custom.qml b/tests/auto/quickcontrols2/font/data/font-appwindow-custom.qml new file mode 100644 index 00000000000..9f82079e051 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/font-appwindow-custom.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + font.capitalization: Font.AllUppercase + font.family: "Courier" + font.italic: true + font.pixelSize: 60 + font.strikeout: true + font.underline: true + font.weight: Font.DemiBold +} diff --git a/tests/auto/quickcontrols2/font/data/font-appwindow-default.qml b/tests/auto/quickcontrols2/font/data/font-appwindow-default.qml new file mode 100644 index 00000000000..9f2c34fe178 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/font-appwindow-default.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { +} diff --git a/tests/auto/quickcontrols2/font/data/font-control-custom.qml b/tests/auto/quickcontrols2/font/data/font-control-custom.qml new file mode 100644 index 00000000000..8fcfc686120 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/font-control-custom.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Control { + font.capitalization: Font.AllUppercase + font.family: "Courier" + font.italic: true + font.pixelSize: 60 + font.strikeout: true + font.underline: true + font.weight: Font.DemiBold +} diff --git a/tests/auto/quickcontrols2/font/data/font-control-default.qml b/tests/auto/quickcontrols2/font/data/font-control-default.qml new file mode 100644 index 00000000000..48afa021cd5 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/font-control-default.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Control { +} diff --git a/tests/auto/quickcontrols2/font/data/font-popup-custom.qml b/tests/auto/quickcontrols2/font/data/font-popup-custom.qml new file mode 100644 index 00000000000..e3983bf5183 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/font-popup-custom.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Popup { + font.capitalization: Font.AllUppercase + font.family: "Courier" + font.italic: true + font.pixelSize: 60 + font.strikeout: true + font.underline: true + font.weight: Font.DemiBold +} diff --git a/tests/auto/quickcontrols2/font/data/font-popup-default.qml b/tests/auto/quickcontrols2/font/data/font-popup-default.qml new file mode 100644 index 00000000000..77676baccf0 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/font-popup-default.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Popup { +} diff --git a/tests/auto/quickcontrols2/font/data/inheritance-childcontrol.qml b/tests/auto/quickcontrols2/font/data/inheritance-childcontrol.qml new file mode 100644 index 00000000000..896354dfb03 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/inheritance-childcontrol.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property alias control: control + property alias child: child + property alias grandChild: grandChild + + Item { + Control { + id: control + + Control { + id: child + + Item { + Control { + id: grandChild + } + } + } + } + } +} diff --git a/tests/auto/quickcontrols2/font/data/inheritance-childpopup.qml b/tests/auto/quickcontrols2/font/data/inheritance-childpopup.qml new file mode 100644 index 00000000000..7896a558e96 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/inheritance-childpopup.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property alias control: control + property alias child: child + property alias grandChild: grandChild + + Item { + Popup { + id: control + + Control { + id: child + + Item { + Control { + id: grandChild + } + } + } + } + } +} diff --git a/tests/auto/quickcontrols2/font/data/inheritance-control.qml b/tests/auto/quickcontrols2/font/data/inheritance-control.qml new file mode 100644 index 00000000000..eb534180a82 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/inheritance-control.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property alias control: control + property alias child: child + property alias grandChild: grandChild + + Control { + id: control + + Control { + id: child + + Item { + Control { + id: grandChild + } + } + } + } +} diff --git a/tests/auto/quickcontrols2/font/data/inheritance-dynamicchildcontrol.qml b/tests/auto/quickcontrols2/font/data/inheritance-dynamicchildcontrol.qml new file mode 100644 index 00000000000..0a4e5bc6645 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/inheritance-dynamicchildcontrol.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property Control control + property Control child + property Control grandChild + + Item { + id: childItem + } + + Component { + id: component + Control { } + } + + Component.onCompleted: { + control = component.createObject(childItem) + child = component.createObject(control) + grandChild = component.createObject(child) + } +} diff --git a/tests/auto/quickcontrols2/font/data/inheritance-dynamicchildpopup.qml b/tests/auto/quickcontrols2/font/data/inheritance-dynamicchildpopup.qml new file mode 100644 index 00000000000..0e799d47f04 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/inheritance-dynamicchildpopup.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property Popup control + property Control child + property Control grandChild + + Item { + id: childItem + } + + Component { + id: popupComponent + Popup { } + } + + Component { + id: controlComponent + Control { } + } + + Component.onCompleted: { + control = popupComponent.createObject(childItem) + child = controlComponent.createObject(control.contentItem) + grandChild = controlComponent.createObject(child) + } +} diff --git a/tests/auto/quickcontrols2/font/data/inheritance-dynamiccontrol.qml b/tests/auto/quickcontrols2/font/data/inheritance-dynamiccontrol.qml new file mode 100644 index 00000000000..058d5b8b956 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/inheritance-dynamiccontrol.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property Control control + property Control child + property Control grandChild + + Component { + id: component + Control { } + } + + Component.onCompleted: { + control = component.createObject(contentItem) + child = component.createObject(control) + grandChild = component.createObject(child) + } +} diff --git a/tests/auto/quickcontrols2/font/data/inheritance-dynamicpopup.qml b/tests/auto/quickcontrols2/font/data/inheritance-dynamicpopup.qml new file mode 100644 index 00000000000..429669c7b29 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/inheritance-dynamicpopup.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property Popup control + property Control child + property Control grandChild + + Component { + id: popupComponent + Popup { } + } + + Component { + id: controlComponent + Control { } + } + + Component.onCompleted: { + control = popupComponent.createObject(window) + child = controlComponent.createObject(control.contentItem) + grandChild = controlComponent.createObject(child) + } +} diff --git a/tests/auto/quickcontrols2/font/data/inheritance-popup.qml b/tests/auto/quickcontrols2/font/data/inheritance-popup.qml new file mode 100644 index 00000000000..cd2aebb55ac --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/inheritance-popup.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property alias control: control + property alias child: child + property alias grandChild: grandChild + + Popup { + id: control + + Control { + id: child + + Item { + Control { + id: grandChild + } + } + } + } +} diff --git a/tests/auto/quickcontrols2/font/data/listview.qml b/tests/auto/quickcontrols2/font/data/listview.qml new file mode 100644 index 00000000000..7c372585198 --- /dev/null +++ b/tests/auto/quickcontrols2/font/data/listview.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 200 + height: 200 + + property alias listView: listView + + font.pixelSize: 55 + + ListView { + id: listView + anchors.fill: parent + model: 1 + delegate: Column { + property alias control: control + property alias label: label + property alias textarea: textarea + property alias textfield: textfield + + Control { id: control } + Label { id: label } + TextArea { id: textarea } + TextField { id: textfield } + } + } +} diff --git a/tests/auto/quickcontrols2/font/tst_font.cpp b/tests/auto/quickcontrols2/font/tst_font.cpp new file mode 100644 index 00000000000..a3adcfd6c41 --- /dev/null +++ b/tests/auto/quickcontrols2/font/tst_font.cpp @@ -0,0 +1,369 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> + +#include <QtGui/qfont.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p_p.h> +#include <QtQuickControls2/qquickstyle.h> + +class tst_font : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_font(); + +private slots: + void systemFont(); + + void font_data(); + void font(); + + void inheritance_data(); + void inheritance(); + + void defaultFont_data(); + void defaultFont(); + + void listView_data(); + void listView(); +}; + +static QFont testFont() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import QtQuick; import QtQuick.Controls; Text { }", QUrl()); + + QScopedPointer<QObject> object(component.create()); + Q_ASSERT_X(!object.isNull(), "testFont", qPrintable(component.errorString())); + + QVariant var = object->property("font"); + Q_ASSERT_X(var.isValid(), "testFont", var.typeName()); + return var.value<QFont>(); +} + +tst_font::tst_font() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ + QQuickStyle::setStyle("Basic"); +} + +void tst_font::systemFont() +{ + QSKIP("QTBUG-70063: qmlClearTypeRegistrations() call causes crash"); + + const QFont *originalSystemFont = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::SystemFont); + if (!originalSystemFont) + QSKIP("Cannot test the system font on a minimal platform"); + + const QFont fontBefore = testFont(); + QCOMPARE(fontBefore, *originalSystemFont); + + qmlClearTypeRegistrations(); + delete QGuiApplicationPrivate::app_font; + QGuiApplicationPrivate::app_font = nullptr; + + const QFont appFont = QGuiApplication::font(); + QCOMPARE(appFont, *originalSystemFont); + + const QFont fontAfter = testFont(); + QCOMPARE(fontAfter, *originalSystemFont); +} + +void tst_font::font_data() +{ + QTest::addColumn<QString>("testFile"); + QTest::addColumn<QFont>("expectedFont"); + + QTest::newRow("Control") << "font-control-default.qml" << QFont(); + QTest::newRow("AppWindow") << "font-appwindow-default.qml" << QFont(); + QTest::newRow("Popup") << "font-popup-default.qml" << QFont(); + + QFont customFont; + customFont.setCapitalization(QFont::AllUppercase); + customFont.setFamilies(QStringList{QLatin1String("Courier")}); + customFont.setItalic(true); + customFont.setPixelSize(60); + customFont.setStrikeOut(true); + customFont.setUnderline(true); + customFont.setWeight(QFont::DemiBold); + + QTest::newRow("Control:custom") << "font-control-custom.qml" << customFont; + QTest::newRow("AppWindow:custom") << "font-appwindow-custom.qml" << customFont; + QTest::newRow("Popup:custom") << "font-popup-custom.qml" << customFont; +} + +void tst_font::font() +{ + QFETCH(QString, testFile); + QFETCH(QFont, expectedFont); + + if (QSysInfo::productType().compare(QLatin1String("osx"), Qt::CaseInsensitive) == 0 + && qgetenv("QTEST_ENVIRONMENT").split(' ').contains("CI")) { + QSKIP("This test crashes on macOS: QTBUG-70063"); + } + + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl(testFile)); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + QVariant var = object->property("font"); + QVERIFY(var.isValid()); + + QFont actualFont = var.value<QFont>(); + QCOMPARE(actualFont, expectedFont); +} + +void tst_font::inheritance_data() +{ + QTest::addColumn<QString>("testFile"); + + QTest::newRow("Control") << "inheritance-control.qml"; + QTest::newRow("Child Control") << "inheritance-childcontrol.qml"; + QTest::newRow("Dynamic Control") << "inheritance-dynamiccontrol.qml"; + QTest::newRow("Dynamic Child Control") << "inheritance-dynamicchildcontrol.qml"; + + QTest::newRow("Popup") << "inheritance-popup.qml"; + QTest::newRow("Child Popup") << "inheritance-childpopup.qml"; + QTest::newRow("Dynamic Popup") << "inheritance-dynamicpopup.qml"; + QTest::newRow("Dynamic Child Popup") << "inheritance-dynamicchildpopup.qml"; +} + +void tst_font::inheritance() +{ + QFETCH(QString, testFile); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl(testFile)); + + QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(component.create())); + QVERIFY2(!window.isNull(), qPrintable(component.errorString())); + + QObject *control = window->property("control").value<QObject *>(); + QObject *child = window->property("child").value<QObject *>(); + QObject *grandChild = window->property("grandChild").value<QObject *>(); + QVERIFY(control && child && grandChild); + + QCOMPARE(window->font(), QFont()); + + QCOMPARE(control->property("font").value<QFont>(), QFont()); + QCOMPARE(child->property("font").value<QFont>(), QFont()); + QCOMPARE(grandChild->property("font").value<QFont>(), QFont()); + + QFont childFont; + childFont.setFamilies(QStringList{QLatin1String("Arial")}); + childFont.setPixelSize(80); + childFont.setItalic(true); + child->setProperty("font", childFont); + QCOMPARE(child->property("font").value<QFont>(), childFont); + QCOMPARE(grandChild->property("font").value<QFont>(), childFont); + + QFont grandChildFont(childFont); + grandChildFont.setFamilies(QStringList{QLatin1String("Times New Roman")}); + grandChildFont.setUnderline(true); + grandChild->setProperty("font", grandChildFont); + QCOMPARE(child->property("font").value<QFont>(), childFont); + QCOMPARE(grandChild->property("font").value<QFont>(), grandChildFont); + + QFont windowFont; + windowFont.setWeight(QFont::Thin); + window->setFont(windowFont); + QCOMPARE(window->font(), windowFont); + QCOMPARE(control->property("font").value<QFont>(), windowFont); + + childFont.setWeight(QFont::Thin); + QCOMPARE(child->property("font").value<QFont>(), childFont); + + grandChildFont.setWeight(QFont::Thin); + QCOMPARE(grandChild->property("font").value<QFont>(), grandChildFont); + + child->setProperty("font", QVariant()); + QCOMPARE(child->property("font").value<QFont>(), windowFont); + QCOMPARE(grandChild->property("font").value<QFont>(), grandChildFont); + + grandChild->setProperty("font", QVariant()); + QCOMPARE(grandChild->property("font").value<QFont>(), windowFont); +} + +class TestFontTheme : public QQuickTheme +{ +public: + static const int NFonts = QQuickTheme::Tumbler + 1; + + TestFontTheme() + { + for (int i = 0; i < NFonts; ++i) { + QFont font = QFont(); + font.setPixelSize(i + 10); + setFont(static_cast<Scope>(i), font); + } + } +}; + +Q_DECLARE_METATYPE(QQuickTheme::Scope) + +void tst_font::defaultFont_data() +{ + QTest::addColumn<QString>("control"); + QTest::addColumn<QQuickTheme::Scope>("scope"); + + QTest::newRow("AbstractButton") << "AbstractButton" << QQuickTheme::System; + QTest::newRow("ApplicationWindow") << "ApplicationWindow" << QQuickTheme::System; + QTest::newRow("Button") << "Button" << QQuickTheme::Button; + QTest::newRow("CheckBox") << "CheckBox" << QQuickTheme::CheckBox; + QTest::newRow("CheckDelegate") << "CheckDelegate" << QQuickTheme::ListView; + QTest::newRow("ComboBox") << "ComboBox" << QQuickTheme::ComboBox; + QTest::newRow("Container") << "Container" << QQuickTheme::System; + QTest::newRow("Control") << "Control" << QQuickTheme::System; + QTest::newRow("Dial") << "Dial" << QQuickTheme::System; + QTest::newRow("Dialog") << "Dialog" << QQuickTheme::System; + QTest::newRow("DialogButtonBox") << "DialogButtonBox" << QQuickTheme::System; + QTest::newRow("Drawer") << "Drawer" << QQuickTheme::System; + QTest::newRow("Frame") << "Frame" << QQuickTheme::System; + QTest::newRow("GroupBox") << "GroupBox" << QQuickTheme::GroupBox; + QTest::newRow("ItemDelegate") << "ItemDelegate" << QQuickTheme::ItemView; + QTest::newRow("Label") << "Label" << QQuickTheme::Label; + QTest::newRow("Menu") << "Menu" << QQuickTheme::Menu; + QTest::newRow("MenuItem") << "MenuItem" << QQuickTheme::Menu; + QTest::newRow("MenuSeparator") << "MenuSeparator" << QQuickTheme::Menu; + QTest::newRow("Page") << "Page" << QQuickTheme::System; + QTest::newRow("Pane") << "Pane" << QQuickTheme::System; + QTest::newRow("Popup") << "Popup" << QQuickTheme::System; + QTest::newRow("ProgressBar") << "ProgressBar" << QQuickTheme::System; + QTest::newRow("RadioButton") << "RadioButton" << QQuickTheme::RadioButton; + QTest::newRow("RadioDelegate") << "RadioDelegate" << QQuickTheme::ListView; + QTest::newRow("RangeSlider") << "RangeSlider" << QQuickTheme::System; + QTest::newRow("RoundButton") << "RoundButton" << QQuickTheme::Button; + QTest::newRow("ScrollBar") << "ScrollBar" << QQuickTheme::System; + QTest::newRow("ScrollIndicator") << "ScrollIndicator" << QQuickTheme::System; + QTest::newRow("Slider") << "Slider" << QQuickTheme::System; + QTest::newRow("SpinBox") << "SpinBox" << QQuickTheme::SpinBox; + QTest::newRow("SwipeDelegate") << "SwipeDelegate" << QQuickTheme::ListView; + QTest::newRow("Switch") << "Switch" << QQuickTheme::Switch; + QTest::newRow("SwitchDelegate") << "SwitchDelegate" << QQuickTheme::ListView; + QTest::newRow("TabBar") << "TabBar" << QQuickTheme::TabBar; + QTest::newRow("TabButton") << "TabButton" << QQuickTheme::TabBar; + QTest::newRow("TextArea") << "TextArea" << QQuickTheme::TextArea; + QTest::newRow("TextField") << "TextField" << QQuickTheme::TextField; + QTest::newRow("ToolBar") << "ToolBar" << QQuickTheme::ToolBar; + QTest::newRow("ToolButton") << "ToolButton" << QQuickTheme::ToolBar; + QTest::newRow("ToolSeparator") << "ToolSeparator" << QQuickTheme::ToolBar; + QTest::newRow("ToolTip") << "ToolTip" << QQuickTheme::ToolTip; + QTest::newRow("Tumbler") << "Tumbler" << QQuickTheme::Tumbler; +} + +void tst_font::defaultFont() +{ + QFETCH(QString, control); + QFETCH(QQuickTheme::Scope, scope); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(QString("import QtQuick.Controls; %1 { }").arg(control).toUtf8(), QUrl()); + + // The call to setData() above causes QQuickBasicTheme to be set as the current theme, + // so we must make sure we only set our theme afterwards. + QQuickThemePrivate::instance.reset(new TestFontTheme); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + QVariant var = object->property("font"); + QVERIFY(var.isValid()); + + QFont expectedFont = QQuickTheme::font(scope); + QFont actualFont = var.value<QFont>(); + QCOMPARE(actualFont, expectedFont); +} + +void tst_font::listView_data() +{ + QTest::addColumn<QString>("objectName"); + + QTest::newRow("Control") << "control"; + QTest::newRow("Label") << "label"; + QTest::newRow("TextArea") << "textarea"; + QTest::newRow("TextField") << "textfield"; +} + +void tst_font::listView() +{ + QFETCH(QString, objectName); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("listview.qml")); + + QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(component.create())); + QVERIFY2(!window.isNull(), qPrintable(component.errorString())); + + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickItem *listView = window->property("listView").value<QQuickItem *>(); + QVERIFY(listView); + + QQuickItem *contentItem = listView->property("contentItem").value<QQuickItem *>(); + QVERIFY(contentItem); + + QVERIFY(QMetaObject::invokeMethod(listView, "forceLayout")); + + QQuickItem *column = contentItem->childItems().value(0); + QVERIFY(column); + + QQuickItem *control = column->property(objectName.toUtf8()).value<QQuickItem *>(); + QVERIFY(control); + + QCOMPARE(control->property("font").value<QFont>().pixelSize(), 55); +} + +QTEST_MAIN(tst_font) + +#include "tst_font.moc" diff --git a/tests/auto/quickcontrols2/palette/CMakeLists.txt b/tests/auto/quickcontrols2/palette/CMakeLists.txt new file mode 100644 index 00000000000..e6e9128866f --- /dev/null +++ b/tests/auto/quickcontrols2/palette/CMakeLists.txt @@ -0,0 +1,61 @@ +# Generated from palette.pro. + +##################################################################### +## tst_palette Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_palette + SOURCES + tst_palette.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +# Resources: +set(qmake_immediate_resource_files + "qtquickcontrols2.conf" +) + +qt_internal_add_resource(tst_palette "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + + +#### Keys ignored in scope 1:.:.:palette.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_palette CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_palette CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/palette/data/bindings.qml b/tests/auto/quickcontrols2/palette/data/bindings.qml new file mode 100644 index 00000000000..215fb034974 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/bindings.qml @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + id: window + objectName: "window" + width: 600 + height: 800 + visible: true + + property alias disabledButton: disabledButton + property alias enabledButton: enabledButton + + palette { + active { + button: "khaki" + buttonText: "bisque" + } + + inactive { + button: "khaki" + buttonText: "bisque" + } + + disabled { + buttonText: "lavender" + button: "coral" + } + } + + ColumnLayout { + Button { + id: disabledButton + text: "Disabled" + enabled: false + + palette.disabled.button: "aqua" + palette.disabled.buttonText: "azure" + } + + Button { + id: enabledButton + text: "Enabled" + + palette: disabledButton.palette + } + } +} diff --git a/tests/auto/quickcontrols2/palette/data/inheritance-childcontrol.qml b/tests/auto/quickcontrols2/palette/data/inheritance-childcontrol.qml new file mode 100644 index 00000000000..896354dfb03 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/inheritance-childcontrol.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property alias control: control + property alias child: child + property alias grandChild: grandChild + + Item { + Control { + id: control + + Control { + id: child + + Item { + Control { + id: grandChild + } + } + } + } + } +} diff --git a/tests/auto/quickcontrols2/palette/data/inheritance-childpopup.qml b/tests/auto/quickcontrols2/palette/data/inheritance-childpopup.qml new file mode 100644 index 00000000000..7896a558e96 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/inheritance-childpopup.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property alias control: control + property alias child: child + property alias grandChild: grandChild + + Item { + Popup { + id: control + + Control { + id: child + + Item { + Control { + id: grandChild + } + } + } + } + } +} diff --git a/tests/auto/quickcontrols2/palette/data/inheritance-control.qml b/tests/auto/quickcontrols2/palette/data/inheritance-control.qml new file mode 100644 index 00000000000..eb534180a82 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/inheritance-control.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property alias control: control + property alias child: child + property alias grandChild: grandChild + + Control { + id: control + + Control { + id: child + + Item { + Control { + id: grandChild + } + } + } + } +} diff --git a/tests/auto/quickcontrols2/palette/data/inheritance-dynamicchildcontrol.qml b/tests/auto/quickcontrols2/palette/data/inheritance-dynamicchildcontrol.qml new file mode 100644 index 00000000000..0a4e5bc6645 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/inheritance-dynamicchildcontrol.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property Control control + property Control child + property Control grandChild + + Item { + id: childItem + } + + Component { + id: component + Control { } + } + + Component.onCompleted: { + control = component.createObject(childItem) + child = component.createObject(control) + grandChild = component.createObject(child) + } +} diff --git a/tests/auto/quickcontrols2/palette/data/inheritance-dynamicchildpopup.qml b/tests/auto/quickcontrols2/palette/data/inheritance-dynamicchildpopup.qml new file mode 100644 index 00000000000..0e799d47f04 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/inheritance-dynamicchildpopup.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property Popup control + property Control child + property Control grandChild + + Item { + id: childItem + } + + Component { + id: popupComponent + Popup { } + } + + Component { + id: controlComponent + Control { } + } + + Component.onCompleted: { + control = popupComponent.createObject(childItem) + child = controlComponent.createObject(control.contentItem) + grandChild = controlComponent.createObject(child) + } +} diff --git a/tests/auto/quickcontrols2/palette/data/inheritance-dynamiccontrol.qml b/tests/auto/quickcontrols2/palette/data/inheritance-dynamiccontrol.qml new file mode 100644 index 00000000000..058d5b8b956 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/inheritance-dynamiccontrol.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property Control control + property Control child + property Control grandChild + + Component { + id: component + Control { } + } + + Component.onCompleted: { + control = component.createObject(contentItem) + child = component.createObject(control) + grandChild = component.createObject(child) + } +} diff --git a/tests/auto/quickcontrols2/palette/data/inheritance-dynamicpopup.qml b/tests/auto/quickcontrols2/palette/data/inheritance-dynamicpopup.qml new file mode 100644 index 00000000000..429669c7b29 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/inheritance-dynamicpopup.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property Popup control + property Control child + property Control grandChild + + Component { + id: popupComponent + Popup { } + } + + Component { + id: controlComponent + Control { } + } + + Component.onCompleted: { + control = popupComponent.createObject(window) + child = controlComponent.createObject(control.contentItem) + grandChild = controlComponent.createObject(child) + } +} diff --git a/tests/auto/quickcontrols2/palette/data/inheritance-popup.qml b/tests/auto/quickcontrols2/palette/data/inheritance-popup.qml new file mode 100644 index 00000000000..cd2aebb55ac --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/inheritance-popup.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property alias control: control + property alias child: child + property alias grandChild: grandChild + + Popup { + id: control + + Control { + id: child + + Item { + Control { + id: grandChild + } + } + } + } +} diff --git a/tests/auto/quickcontrols2/palette/data/listview.qml b/tests/auto/quickcontrols2/palette/data/listview.qml new file mode 100644 index 00000000000..eee6531f99c --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/listview.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 200 + height: 200 + + property alias listView: listView + + palette.highlight: "red" + + ListView { + id: listView + anchors.fill: parent + model: 1 + delegate: Column { + property alias control: control + property alias label: label + property alias textarea: textarea + property alias textfield: textfield + + Control { id: control } + Label { id: label } + TextArea { id: textarea } + TextField { id: textfield } + } + } +} diff --git a/tests/auto/quickcontrols2/palette/data/palette-appwindow-custom.qml b/tests/auto/quickcontrols2/palette/data/palette-appwindow-custom.qml new file mode 100644 index 00000000000..95f9fde607e --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/palette-appwindow-custom.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + palette.alternateBase: "aqua" + palette.base: "azure" + palette.brightText: "beige" + palette.button: "bisque" + palette.buttonText: "chocolate" + palette.dark: "coral" + palette.highlight: "crimson" + palette.highlightedText: "fuchsia" + palette.light: "gold" + palette.link: "indigo" + palette.linkVisited: "ivory" + palette.mid: "khaki" + palette.midlight: "lavender" + palette.shadow: "linen" + palette.text: "moccasin" + palette.toolTipBase: "navy" + palette.toolTipText: "orchid" + palette.window: "plum" + palette.windowText: "salmon" + palette.placeholderText: "magenta" +} diff --git a/tests/auto/quickcontrols2/palette/data/palette-appwindow-default.qml b/tests/auto/quickcontrols2/palette/data/palette-appwindow-default.qml new file mode 100644 index 00000000000..9f2c34fe178 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/palette-appwindow-default.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { +} diff --git a/tests/auto/quickcontrols2/palette/data/palette-control-custom.qml b/tests/auto/quickcontrols2/palette/data/palette-control-custom.qml new file mode 100644 index 00000000000..7f3bfde5752 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/palette-control-custom.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Control { + palette.alternateBase: "aqua" + palette.base: "azure" + palette.brightText: "beige" + palette.button: "bisque" + palette.buttonText: "chocolate" + palette.dark: "coral" + palette.highlight: "crimson" + palette.highlightedText: "fuchsia" + palette.light: "gold" + palette.link: "indigo" + palette.linkVisited: "ivory" + palette.mid: "khaki" + palette.midlight: "lavender" + palette.shadow: "linen" + palette.text: "moccasin" + palette.toolTipBase: "navy" + palette.toolTipText: "orchid" + palette.window: "plum" + palette.windowText: "salmon" + palette.placeholderText: "magenta" +} diff --git a/tests/auto/quickcontrols2/palette/data/palette-control-default.qml b/tests/auto/quickcontrols2/palette/data/palette-control-default.qml new file mode 100644 index 00000000000..48afa021cd5 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/palette-control-default.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Control { +} diff --git a/tests/auto/quickcontrols2/palette/data/palette-popup-custom.qml b/tests/auto/quickcontrols2/palette/data/palette-popup-custom.qml new file mode 100644 index 00000000000..6f35f452d20 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/palette-popup-custom.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Popup { + palette.alternateBase: "aqua" + palette.base: "azure" + palette.brightText: "beige" + palette.button: "bisque" + palette.buttonText: "chocolate" + palette.dark: "coral" + palette.highlight: "crimson" + palette.highlightedText: "fuchsia" + palette.light: "gold" + palette.link: "indigo" + palette.linkVisited: "ivory" + palette.mid: "khaki" + palette.midlight: "lavender" + palette.shadow: "linen" + palette.text: "moccasin" + palette.toolTipBase: "navy" + palette.toolTipText: "orchid" + palette.window: "plum" + palette.windowText: "salmon" + palette.placeholderText: "magenta" +} diff --git a/tests/auto/quickcontrols2/palette/data/palette-popup-default.qml b/tests/auto/quickcontrols2/palette/data/palette-popup-default.qml new file mode 100644 index 00000000000..77676baccf0 --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/palette-popup-default.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Popup { +} diff --git a/tests/auto/quickcontrols2/palette/data/set-palette.qml b/tests/auto/quickcontrols2/palette/data/set-palette.qml new file mode 100644 index 00000000000..2d0fe194cec --- /dev/null +++ b/tests/auto/quickcontrols2/palette/data/set-palette.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Control { + palette { + active { + buttonText: "azure" + button: "khaki" + } + + disabled { + buttonText: "lavender" + button: "coral" + } + } +} diff --git a/tests/auto/quickcontrols2/palette/qtquickcontrols2.conf b/tests/auto/quickcontrols2/palette/qtquickcontrols2.conf new file mode 100644 index 00000000000..c5de6b36ddb --- /dev/null +++ b/tests/auto/quickcontrols2/palette/qtquickcontrols2.conf @@ -0,0 +1,5 @@ +[Basic] +Palette\Base=#efefef + +[Basic\Palette] +Text=#101010 diff --git a/tests/auto/quickcontrols2/palette/tst_palette.cpp b/tests/auto/quickcontrols2/palette/tst_palette.cpp new file mode 100644 index 00000000000..54a182ef59d --- /dev/null +++ b/tests/auto/quickcontrols2/palette/tst_palette.cpp @@ -0,0 +1,440 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtGui/qpalette.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p_p.h> +#include <QtQuickTemplates2/private/qquickbutton_p.h> +#include <QtQuickControls2/qquickstyle.h> + +//using namespace QQuickVisualTestUtils; + +// Need a more descriptive failure message: QTBUG-87039 +#define COMPARE_PALETTES(actualPalette, expectedPalette) \ + QVERIFY2(actualPalette == expectedPalette, \ + qPrintable(QString::fromLatin1("\n Actual: %1\n Expected: %2") \ + .arg(QDebug::toString(actualPalette)).arg(QDebug::toString(expectedPalette)))); + +class tst_palette : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_palette(); + +private slots: + void initTestCase() override; + + void palette_data(); + void palette(); + + void inheritance_data(); + void inheritance(); + + void defaultPalette_data(); + void defaultPalette(); + + void listView_data(); + void listView(); + + void setDynamicallyCreatedPalette(); + void createBindings(); + void updateBindings(); +}; + +tst_palette::tst_palette() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_palette::initTestCase() +{ + QQuickStyle::setStyle("Basic"); + + QQmlDataTest::initTestCase(); + + // Import QtQuick.Controls to initialize styles and themes so that + // QQuickControlPrivate::themePalette() returns a palette from the + // style's theme instead of the platform's theme. + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import QtQuick.Controls; Control { }", QUrl()); + delete component.create(); +} + +void tst_palette::palette_data() +{ + QTest::addColumn<QString>("testFile"); + QTest::addColumn<QPalette>("expectedPalette"); + + const QPalette defaultPalette = QQuickTheme::palette(QQuickTheme::System); + + QTest::newRow("Control") << "palette-control-default.qml" << defaultPalette; + QTest::newRow("AppWindow") << "palette-appwindow-default.qml" << defaultPalette; + QTest::newRow("Popup") << "palette-popup-default.qml" << defaultPalette; + + QPalette customPalette; + customPalette.setColor(QPalette::AlternateBase, QColor("aqua")); + customPalette.setColor(QPalette::Base, QColor("azure")); + customPalette.setColor(QPalette::BrightText, QColor("beige")); + customPalette.setColor(QPalette::Button, QColor("bisque")); + customPalette.setColor(QPalette::ButtonText, QColor("chocolate")); + customPalette.setColor(QPalette::Dark, QColor("coral")); + customPalette.setColor(QPalette::Highlight, QColor("crimson")); + customPalette.setColor(QPalette::HighlightedText, QColor("fuchsia")); + customPalette.setColor(QPalette::Light, QColor("gold")); + customPalette.setColor(QPalette::Link, QColor("indigo")); + customPalette.setColor(QPalette::LinkVisited, QColor("ivory")); + customPalette.setColor(QPalette::Mid, QColor("khaki")); + customPalette.setColor(QPalette::Midlight, QColor("lavender")); + customPalette.setColor(QPalette::Shadow, QColor("linen")); + customPalette.setColor(QPalette::Text, QColor("moccasin")); + customPalette.setColor(QPalette::ToolTipBase, QColor("navy")); + customPalette.setColor(QPalette::ToolTipText, QColor("orchid")); + customPalette.setColor(QPalette::Window, QColor("plum")); + customPalette.setColor(QPalette::WindowText, QColor("salmon")); + customPalette.setColor(QPalette::PlaceholderText, QColor("magenta")); + + QTest::newRow("Control:custom") << "palette-control-custom.qml" << customPalette; + QTest::newRow("AppWindow:custom") << "palette-appwindow-custom.qml" << customPalette; + QTest::newRow("Popup:custom") << "palette-popup-custom.qml" << customPalette; +} + +void tst_palette::palette() +{ + QFETCH(QString, testFile); + QFETCH(QPalette, expectedPalette); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl(testFile)); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + QVariant var = object->property("palette"); + QVERIFY(var.isValid()); + + COMPARE_PALETTES(var.value<QQuickPalette*>()->toQPalette(), expectedPalette); +} + +void tst_palette::inheritance_data() +{ + QTest::addColumn<QString>("testFile"); + + QTest::newRow("Control") << "inheritance-control.qml"; + QTest::newRow("Child Control") << "inheritance-childcontrol.qml"; + QTest::newRow("Dynamic Control") << "inheritance-dynamiccontrol.qml"; + QTest::newRow("Dynamic Child Control") << "inheritance-dynamicchildcontrol.qml"; + + QTest::newRow("Popup") << "inheritance-popup.qml"; + QTest::newRow("Child Popup") << "inheritance-childpopup.qml"; + QTest::newRow("Dynamic Popup") << "inheritance-dynamicpopup.qml"; + QTest::newRow("Dynamic Child Popup") << "inheritance-dynamicchildpopup.qml"; +} + +void tst_palette::inheritance() +{ + QFETCH(QString, testFile); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl(testFile)); + + QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(component.create())); + QVERIFY2(!window.isNull(), qPrintable(component.errorString())); + + QObject *control = window->property("control").value<QObject *>(); + QObject *child = window->property("child").value<QObject *>(); + QObject *grandChild = window->property("grandChild").value<QObject *>(); + QVERIFY(control && child && grandChild); + + const QPalette defaultPalette = QQuickTheme::palette(QQuickTheme::System); + + auto windowPalette = QQuickWindowPrivate::get(window.get())->palette(); + + QCOMPARE(windowPalette->toQPalette(), defaultPalette); + + auto controlPalette = control->property("palette").value<QQuickPalette*>(); + auto childPalette = child->property("palette").value<QQuickPalette*>(); + auto grandChildPalette = grandChild->property("palette").value<QQuickPalette*>(); + QVERIFY(controlPalette && childPalette && grandChildPalette); + + QCOMPARE(controlPalette->toQPalette(), defaultPalette); + QCOMPARE(childPalette->toQPalette(), defaultPalette); + QCOMPARE(grandChildPalette->toQPalette(), defaultPalette); + + childPalette->setBase(Qt::red); + childPalette->setText(Qt::green); + childPalette->setButton(Qt::blue); + + QCOMPARE(childPalette->base(), grandChildPalette->base()); + QCOMPARE(childPalette->text(), grandChildPalette->text()); + QCOMPARE(childPalette->button(), grandChildPalette->button()); + + windowPalette->setWindow(Qt::gray); + QCOMPARE(controlPalette->window(), windowPalette->window()); + + childPalette->setWindow(Qt::red); + QCOMPARE(childPalette->window(), Qt::red); + + grandChildPalette->setWindow(Qt::blue); + QCOMPARE(grandChildPalette->window(), Qt::blue); + + auto childMo = child->metaObject(); + childMo->property(childMo->indexOfProperty("palette")).reset(child); + QCOMPARE(childPalette->window(), windowPalette->window()); + QCOMPARE(grandChildPalette->window(), Qt::blue); + + auto grandChildMo = grandChild->metaObject(); + grandChildMo->property(grandChildMo->indexOfProperty("palette")).reset(grandChild); + QCOMPARE(grandChildPalette->window(), windowPalette->window()); +} + +class TestTheme : public QQuickTheme +{ +public: + static const uint NPalettes = QQuickTheme::Tumbler + 1; + + TestTheme() + { + for (uint i = 0; i < NPalettes; ++i) + setPalette(static_cast<Scope>(i), QPalette(QColor::fromRgb(i))); + } +}; + +Q_DECLARE_METATYPE(QQuickTheme::Scope) + +void tst_palette::defaultPalette_data() +{ + QTest::addColumn<QString>("control"); + QTest::addColumn<QQuickTheme::Scope>("scope"); + + QTest::newRow("AbstractButton") << "AbstractButton" << QQuickTheme::System; + QTest::newRow("ApplicationWindow") << "ApplicationWindow" << QQuickTheme::System; + QTest::newRow("Button") << "Button" << QQuickTheme::Button; + QTest::newRow("CheckBox") << "CheckBox" << QQuickTheme::CheckBox; + QTest::newRow("CheckDelegate") << "CheckDelegate" << QQuickTheme::ListView; + QTest::newRow("ComboBox") << "ComboBox" << QQuickTheme::ComboBox; + QTest::newRow("Container") << "Container" << QQuickTheme::System; + QTest::newRow("Control") << "Control" << QQuickTheme::System; + QTest::newRow("Dial") << "Dial" << QQuickTheme::System; + QTest::newRow("Dialog") << "Dialog" << QQuickTheme::System; + QTest::newRow("DialogButtonBox") << "DialogButtonBox" << QQuickTheme::System; + QTest::newRow("Drawer") << "Drawer" << QQuickTheme::System; + QTest::newRow("Frame") << "Frame" << QQuickTheme::System; + QTest::newRow("GroupBox") << "GroupBox" << QQuickTheme::GroupBox; + QTest::newRow("ItemDelegate") << "ItemDelegate" << QQuickTheme::ItemView; + QTest::newRow("Label") << "Label" << QQuickTheme::Label; + QTest::newRow("Menu") << "Menu" << QQuickTheme::Menu; + QTest::newRow("MenuItem") << "MenuItem" << QQuickTheme::Menu; + QTest::newRow("MenuSeparator") << "MenuSeparator" << QQuickTheme::Menu; + QTest::newRow("Page") << "Page" << QQuickTheme::System; + QTest::newRow("Pane") << "Pane" << QQuickTheme::System; + QTest::newRow("Popup") << "Popup" << QQuickTheme::System; + QTest::newRow("ProgressBar") << "ProgressBar" << QQuickTheme::System; + QTest::newRow("RadioButton") << "RadioButton" << QQuickTheme::RadioButton; + QTest::newRow("RadioDelegate") << "RadioDelegate" << QQuickTheme::ListView; + QTest::newRow("RangeSlider") << "RangeSlider" << QQuickTheme::System; + QTest::newRow("RoundButton") << "RoundButton" << QQuickTheme::Button; + QTest::newRow("ScrollBar") << "ScrollBar" << QQuickTheme::System; + QTest::newRow("ScrollIndicator") << "ScrollIndicator" << QQuickTheme::System; + QTest::newRow("Slider") << "Slider" << QQuickTheme::System; + QTest::newRow("SpinBox") << "SpinBox" << QQuickTheme::SpinBox; + QTest::newRow("SwipeDelegate") << "SwipeDelegate" << QQuickTheme::ListView; + QTest::newRow("Switch") << "Switch" << QQuickTheme::Switch; + QTest::newRow("SwitchDelegate") << "SwitchDelegate" << QQuickTheme::ListView; + QTest::newRow("TabBar") << "TabBar" << QQuickTheme::TabBar; + QTest::newRow("TabButton") << "TabButton" << QQuickTheme::TabBar; + QTest::newRow("TextArea") << "TextArea" << QQuickTheme::TextArea; + QTest::newRow("TextField") << "TextField" << QQuickTheme::TextField; + QTest::newRow("ToolBar") << "ToolBar" << QQuickTheme::ToolBar; + QTest::newRow("ToolButton") << "ToolButton" << QQuickTheme::ToolBar; + QTest::newRow("ToolSeparator") << "ToolSeparator" << QQuickTheme::ToolBar; + QTest::newRow("ToolTip") << "ToolTip" << QQuickTheme::ToolTip; + QTest::newRow("Tumbler") << "Tumbler" << QQuickTheme::Tumbler; +} + +void tst_palette::defaultPalette() +{ + QFETCH(QString, control); + QFETCH(QQuickTheme::Scope, scope); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(QString("import QtQuick.Controls; %1 { }").arg(control).toUtf8(), QUrl()); + + // The call to setData() above causes QQuickBasicTheme to be set as the current theme, + // so we must make sure we only set our theme afterwards. + std::unique_ptr<QQuickTheme> oldTheme(QQuickThemePrivate::instance.release()); + QQuickThemePrivate::instance.reset(new TestTheme); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + QVariant var = object->property("palette"); + QVERIFY(var.isValid()); + + QPalette expectedPalette = QQuickTheme::palette(scope); + auto actualPalette = var.value<QQuickPalette*>(); + QVERIFY(actualPalette); + QCOMPARE(actualPalette->toQPalette(), expectedPalette); + + QQuickThemePrivate::instance.reset(oldTheme.release()); +} + +void tst_palette::listView_data() +{ + QTest::addColumn<QString>("objectName"); + + QTest::newRow("Control") << "control"; + QTest::newRow("Label") << "label"; + QTest::newRow("TextArea") << "textarea"; + QTest::newRow("TextField") << "textfield"; +} + +void tst_palette::listView() +{ + QFETCH(QString, objectName); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("listview.qml")); + + QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(component.create())); + QVERIFY2(!window.isNull(), qPrintable(component.errorString())); + + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickItem *listView = window->property("listView").value<QQuickItem *>(); + QVERIFY(listView); + + QQuickItem *contentItem = listView->property("contentItem").value<QQuickItem *>(); + QVERIFY(contentItem); + + QVERIFY(QMetaObject::invokeMethod(listView, "forceLayout")); + + QQuickItem *column = contentItem->childItems().value(0); + QVERIFY(column); + + QQuickItem *control = column->property(objectName.toUtf8()).value<QQuickItem *>(); + QVERIFY(control); + + QCOMPARE(QQuickItemPrivate::get(control)->palette()->highlight(), Qt::red); +} + +void tst_palette::setDynamicallyCreatedPalette() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("set-palette.qml")); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + QVariant var = object->property("palette"); + QVERIFY(var.isValid()); + + auto palette = var.value<QQuickPalette*>(); + QVERIFY(palette); + + QCOMPARE(palette->buttonText(), QColor("azure")); + QCOMPARE(palette->button(), QColor("khaki")); + + QCOMPARE(palette->disabled()->buttonText(), QColor("lavender")); + QCOMPARE(palette->disabled()->button(), QColor("coral")); +} + +void tst_palette::createBindings() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("bindings.qml")); + + QScopedPointer<QObject> window(component.create()); + QVERIFY2(!window.isNull(), qPrintable(component.errorString())); + + auto disabledButton = window->property("disabledButton").value<QQuickButton*>(); + QVERIFY(disabledButton); + + auto enabledButton = window->property("enabledButton").value<QQuickButton*>(); + QVERIFY(enabledButton); + + QCOMPARE(QQuickItemPrivate::get(disabledButton)->palette()->button(), QColor("aqua")); + QCOMPARE(QQuickItemPrivate::get(disabledButton)->palette()->buttonText(), QColor("azure")); + + QCOMPARE(QQuickItemPrivate::get(enabledButton)->palette()->button(), QColor("khaki")); + QCOMPARE(QQuickItemPrivate::get(enabledButton)->palette()->buttonText(), QColor("bisque")); + + QCOMPARE(QQuickItemPrivate::get(enabledButton)->palette()->disabled()->button(), QColor("aqua")); + QCOMPARE(QQuickItemPrivate::get(enabledButton)->palette()->disabled()->buttonText(), QColor("azure")); +} + +void tst_palette::updateBindings() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("bindings.qml")); + + QScopedPointer<QObject> window(component.create()); + QVERIFY2(!window.isNull(), qPrintable(component.errorString())); + + auto disabledButton = window->property("disabledButton").value<QQuickButton*>(); + QVERIFY(disabledButton); + + auto enabledButton = window->property("enabledButton").value<QQuickButton*>(); + QVERIFY(enabledButton); + + QQuickItemPrivate::get(disabledButton)->palette()->disabled()->setButton(QColor("navy")); + enabledButton->setEnabled(false); + + QCOMPARE(QQuickItemPrivate::get(enabledButton)->palette()->button(), QColor("navy")); +} + +QTEST_MAIN(tst_palette) + +#include "tst_palette.moc" diff --git a/tests/auto/quickcontrols2/platform/CMakeLists.txt b/tests/auto/quickcontrols2/platform/CMakeLists.txt new file mode 100644 index 00000000000..8e6df7d2b48 --- /dev/null +++ b/tests/auto/quickcontrols2/platform/CMakeLists.txt @@ -0,0 +1,26 @@ +# Generated from platform.pro. + +##################################################################### +## tst_platform Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/tst_*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_platform + GUI + QMLTEST + SOURCES + tst_platform.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Qml + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:platform.pro:<TRUE>: +# OTHER_FILES = "$$PWD/data/*.qml" +# TEMPLATE = "app" diff --git a/tests/auto/quickcontrols2/platform/data/tst_colordialog.qml b/tests/auto/quickcontrols2/platform/data/tst_colordialog.qml new file mode 100644 index 00000000000..12055a5ad67 --- /dev/null +++ b/tests/auto/quickcontrols2/platform/data/tst_colordialog.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import Qt.labs.platform + +TestCase { + id: testCase + width: 200 + height: 200 + name: "ColorDialog" + + Component { + id: colorDialog + ColorDialog { } + } + + function test_instance() { + var dialog = colorDialog.createObject(testCase) + verify(dialog) + dialog.destroy() + } +} diff --git a/tests/auto/quickcontrols2/platform/data/tst_filedialog.qml b/tests/auto/quickcontrols2/platform/data/tst_filedialog.qml new file mode 100644 index 00000000000..5a63dd23903 --- /dev/null +++ b/tests/auto/quickcontrols2/platform/data/tst_filedialog.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import Qt.labs.platform + +TestCase { + id: testCase + width: 200 + height: 200 + name: "FileDialog" + + Component { + id: fileDialog + FileDialog { } + } + + function test_instance() { + var dialog = fileDialog.createObject(testCase) + verify(dialog) + dialog.destroy() + } +} diff --git a/tests/auto/quickcontrols2/platform/data/tst_folderdialog.qml b/tests/auto/quickcontrols2/platform/data/tst_folderdialog.qml new file mode 100644 index 00000000000..37881c1aef0 --- /dev/null +++ b/tests/auto/quickcontrols2/platform/data/tst_folderdialog.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import Qt.labs.platform + +TestCase { + id: testCase + width: 200 + height: 200 + name: "FolderDialog" + + Component { + id: folderDialog + FolderDialog { } + } + + function test_instance() { + var dialog = folderDialog.createObject(testCase) + verify(dialog) + dialog.destroy() + } +} diff --git a/tests/auto/quickcontrols2/platform/data/tst_fontdialog.qml b/tests/auto/quickcontrols2/platform/data/tst_fontdialog.qml new file mode 100644 index 00000000000..edb62e5226b --- /dev/null +++ b/tests/auto/quickcontrols2/platform/data/tst_fontdialog.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import Qt.labs.platform + +TestCase { + id: testCase + width: 200 + height: 200 + name: "FontDialog" + + Component { + id: fontDialog + FontDialog { } + } + + function test_instance() { + var dialog = fontDialog.createObject(testCase) + verify(dialog) + dialog.destroy() + } +} diff --git a/tests/auto/quickcontrols2/platform/data/tst_menu.qml b/tests/auto/quickcontrols2/platform/data/tst_menu.qml new file mode 100644 index 00000000000..aedf6529d70 --- /dev/null +++ b/tests/auto/quickcontrols2/platform/data/tst_menu.qml @@ -0,0 +1,335 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import Qt.labs.platform +import QtQuick.Controls as Controls +import org.qtproject.Test + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "Menu" + + Component { + id: item + MenuItem { } + } + + Component { + id: menu + Menu { } + } + + SignalSpy { + id: itemsSpy + signalName: "itemsChanged" + } + + Component { + id: signalSpyComponent + SignalSpy {} + } + + function init() { + verify(!itemsSpy.target) + compare(itemsSpy.count, 0) + } + + function cleanup() { + itemsSpy.target = null + itemsSpy.clear() + } + + function test_addRemove() { + var control = menu.createObject(testCase) + + itemsSpy.target = control + verify(itemsSpy.valid) + + control.addItem(item.createObject(control, {text: "1"})) + compare(control.items.length, 1) + compare(control.items[0].text, "1") + compare(itemsSpy.count, 1) + + control.addItem(item.createObject(control, {text: "2"})) + compare(control.items.length, 2) + compare(control.items[0].text, "1") + compare(control.items[1].text, "2") + compare(itemsSpy.count, 2) + + control.insertItem(1, item.createObject(control, {text: "3"})) + compare(control.items.length, 3) + compare(control.items[0].text, "1") + compare(control.items[1].text, "3") + compare(control.items[2].text, "2") + compare(itemsSpy.count, 3) + + control.insertItem(0, item.createObject(control, {text: "4"})) + compare(control.items.length, 4) + compare(control.items[0].text, "4") + compare(control.items[1].text, "1") + compare(control.items[2].text, "3") + compare(control.items[3].text, "2") + compare(itemsSpy.count, 4) + + control.insertItem(control.items.length, item.createObject(control, {text: "5"})) + compare(control.items.length, 5) + compare(control.items[0].text, "4") + compare(control.items[1].text, "1") + compare(control.items[2].text, "3") + compare(control.items[3].text, "2") + compare(control.items[4].text, "5") + compare(itemsSpy.count, 5) + + control.removeItem(control.items[4]) + compare(control.items.length, 4) + compare(control.items[0].text, "4") + compare(control.items[1].text, "1") + compare(control.items[2].text, "3") + compare(control.items[3].text, "2") + compare(itemsSpy.count, 6) + + control.removeItem(control.items[0]) + compare(control.items.length, 3) + compare(control.items[0].text, "1") + compare(control.items[1].text, "3") + compare(control.items[2].text, "2") + compare(itemsSpy.count, 7) + + control.removeItem(control.items[1]) + compare(control.items.length, 2) + compare(control.items[0].text, "1") + compare(control.items[1].text, "2") + compare(itemsSpy.count, 8) + + control.removeItem(control.items[1]) + compare(control.items.length, 1) + compare(control.items[0].text, "1") + compare(itemsSpy.count, 9) + + control.removeItem(control.items[0]) + compare(control.items.length, 0) + compare(itemsSpy.count, 10) + + control.destroy() + } + + Component { + id: contentMenu + Menu { + QtObject { objectName: "object" } + MenuItem { objectName: "item1" } + Timer { objectName: "timer" } + MenuItem { objectName: "item2" } + Component { MenuItem { } } + } + } + + function test_content() { + var control = contentMenu.createObject(testCase) + + function compareObjectNames(content, names) { + if (content.length !== names.length) + return false + for (var i = 0; i < names.length; ++i) { + if (content[i].objectName !== names[i]) + return false + } + return true + } + + itemsSpy.target = control + verify(itemsSpy.valid) + + verify(compareObjectNames(control.data, ["object", "item1", "timer", "item2", ""])) + verify(compareObjectNames(control.items, ["item1", "item2"])) + + control.addItem(item.createObject(control, {objectName: "item3"})) + verify(compareObjectNames(control.data, ["object", "item1", "timer", "item2", "", "item3"])) + verify(compareObjectNames(control.items, ["item1", "item2", "item3"])) + compare(itemsSpy.count, 1) + + control.insertItem(0, item.createObject(control, {objectName: "item4"})) + verify(compareObjectNames(control.data, ["object", "item1", "timer", "item2", "", "item3", "item4"])) + verify(compareObjectNames(control.items, ["item4", "item1", "item2", "item3"])) + compare(itemsSpy.count, 2) + + control.removeItem(control.items[1]) + verify(compareObjectNames(control.data, ["object", "timer", "item2", "", "item3", "item4"])) + verify(compareObjectNames(control.items, ["item4", "item2", "item3"])) + compare(itemsSpy.count, 3) + + control.destroy() + } + + Component { + id: dynamicMenu + Menu { + id: dmenu + MenuItem { text: "static" } + Component.onCompleted: { + addItem(item.createObject(dmenu, {text: "added"})) + insertItem(0, item.createObject(dmenu, {text: "inserted"})) + } + } + } + + function test_dynamic() { + var control = dynamicMenu.createObject(testCase) + + // insertItem(), addItem(), and static MenuItem {} + compare(control.items.length, 3) + compare(control.items[0].text, "inserted") + + var dying = item.createObject(control, {text: "dying"}) + control.addItem(dying) + compare(control.items.length, 4) + compare(control.items[3].text, "dying") + dying.destroy() + wait(0) + compare(control.items.length, 3) + + control.destroy() + } + + function test_type() { + // Q_ENUMS(QPlatformMenu::MenuType) + compare(Menu.DefaultMenu, 0) + compare(Menu.EditMenu, 1) + } + + function test_subMenus() { + var parentMenu = createTemporaryObject(menu, testCase) + verify(parentMenu) + + var subMenu = menu.createObject(parentMenu) + verify(subMenu) + + var subMenuItem = subMenu.menuItem + verify(subMenuItem) + + parentMenu.addMenu(subMenu) + compare(parentMenu.items.length, 1) + verify(parentMenu.items[0], subMenuItem) + + subMenu.title = "Title" + compare(subMenu.title, "Title") + compare(subMenuItem.text, "Title") + } + + Component { + id: disabledMenuItemAndActionComponent + + Item { + property alias action: action + property alias menu: menu + + Controls.Action { + id: action + shortcut: StandardKey.Copy + } + + Menu { + id: menu + + MenuItem { + enabled: !action.enabled + shortcut: StandardKey.Copy + text: "test" + } + } + } + } + + function test_shortcuts() { + if (!TestHelper.shortcutsSupported) + skip("This test requires shortcut support") + + let root = createTemporaryObject(disabledMenuItemAndActionComponent, testCase) + verify(root) + let menu = root.menu + let menuItem = menu.items[0] + verify(menuItem) + let action = root.action + + let actionTriggeredSpy = signalSpyComponent.createObject(root, + { target: action, signalName: "triggered" }) + verify(actionTriggeredSpy.valid) + let menuItemTriggeredSpy = signalSpyComponent.createObject(root, + { target: menuItem, signalName: "triggered" }) + verify(menuItemTriggeredSpy.valid) + + // Perform the shortcut; the Action should be triggered since the MenuItem is disabled. + keySequence(StandardKey.Copy) + compare(actionTriggeredSpy.count, 1) + compare(menuItemTriggeredSpy.count, 0) + + // Disable the Action, enabling the MenuItem in the process. + action.enabled = false + verify(menuItem.enabled) + // Perform the shortcut; the MenuItem should be triggered since the Action is disabled. + keySequence(StandardKey.Copy) + compare(actionTriggeredSpy.count, 1) + compare(menuItemTriggeredSpy.count, 1) + + // Re-enable the Action, disabling the MenuItem in the process. + action.enabled = true + verify(!menuItem.enabled) + // Perform the shortcut; the Action should be triggered since the MenuItem is disabled. + keySequence(StandardKey.Copy) + compare(actionTriggeredSpy.count, 2) + compare(menuItemTriggeredSpy.count, 1) + } +} diff --git a/tests/auto/quickcontrols2/platform/data/tst_menubar.qml b/tests/auto/quickcontrols2/platform/data/tst_menubar.qml new file mode 100644 index 00000000000..0dd9eb91d65 --- /dev/null +++ b/tests/auto/quickcontrols2/platform/data/tst_menubar.qml @@ -0,0 +1,239 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import Qt.labs.platform + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "MenuBar" + + Component { + id: menu + Menu { } + } + + Component { + id: menuBar + MenuBar { } + } + + SignalSpy { + id: menusSpy + signalName: "menusChanged" + } + + function init() { + verify(!menusSpy.target) + compare(menusSpy.count, 0) + } + + function cleanup() { + menusSpy.target = null + menusSpy.clear() + } + + function test_addRemove() { + var control = menuBar.createObject(testCase) + + menusSpy.target = control + verify(menusSpy.valid) + + control.addMenu(menu.createObject(control, {title: "1"})) + compare(control.menus.length, 1) + compare(control.menus[0].title, "1") + compare(menusSpy.count, 1) + + control.addMenu(menu.createObject(control, {title: "2"})) + compare(control.menus.length, 2) + compare(control.menus[0].title, "1") + compare(control.menus[1].title, "2") + compare(menusSpy.count, 2) + + control.insertMenu(1, menu.createObject(control, {title: "3"})) + compare(control.menus.length, 3) + compare(control.menus[0].title, "1") + compare(control.menus[1].title, "3") + compare(control.menus[2].title, "2") + compare(menusSpy.count, 3) + + control.insertMenu(0, menu.createObject(control, {title: "4"})) + compare(control.menus.length, 4) + compare(control.menus[0].title, "4") + compare(control.menus[1].title, "1") + compare(control.menus[2].title, "3") + compare(control.menus[3].title, "2") + compare(menusSpy.count, 4) + + control.insertMenu(control.menus.length, menu.createObject(control, {title: "5"})) + compare(control.menus.length, 5) + compare(control.menus[0].title, "4") + compare(control.menus[1].title, "1") + compare(control.menus[2].title, "3") + compare(control.menus[3].title, "2") + compare(control.menus[4].title, "5") + compare(menusSpy.count, 5) + + control.removeMenu(control.menus[4]) + compare(control.menus.length, 4) + compare(control.menus[0].title, "4") + compare(control.menus[1].title, "1") + compare(control.menus[2].title, "3") + compare(control.menus[3].title, "2") + compare(menusSpy.count, 6) + + control.removeMenu(control.menus[0]) + compare(control.menus.length, 3) + compare(control.menus[0].title, "1") + compare(control.menus[1].title, "3") + compare(control.menus[2].title, "2") + compare(menusSpy.count, 7) + + control.removeMenu(control.menus[1]) + compare(control.menus.length, 2) + compare(control.menus[0].title, "1") + compare(control.menus[1].title, "2") + compare(menusSpy.count, 8) + + control.removeMenu(control.menus[1]) + compare(control.menus.length, 1) + compare(control.menus[0].title, "1") + compare(menusSpy.count, 9) + + control.removeMenu(control.menus[0]) + compare(control.menus.length, 0) + compare(menusSpy.count, 10) + + control.destroy() + } + + Component { + id: contentBar + MenuBar { + QtObject { objectName: "object" } + Menu { objectName: "menu1" } + Timer { objectName: "timer" } + Menu { objectName: "menu2" } + Component { Menu { } } + } + } + + function test_content() { + var control = contentBar.createObject(testCase) + + function compareObjectNames(content, names) { + if (content.length !== names.length) + return false + for (var i = 0; i < names.length; ++i) { + if (content[i].objectName !== names[i]) + return false + } + return true + } + + menusSpy.target = control + verify(menusSpy.valid) + + verify(compareObjectNames(control.data, ["object", "menu1", "timer", "menu2", ""])) + verify(compareObjectNames(control.menus, ["menu1", "menu2"])) + + control.addMenu(menu.createObject(control, {objectName: "menu3"})) + verify(compareObjectNames(control.data, ["object", "menu1", "timer", "menu2", "", "menu3"])) + verify(compareObjectNames(control.menus, ["menu1", "menu2", "menu3"])) + compare(menusSpy.count, 1) + + control.insertMenu(0, menu.createObject(control, {objectName: "menu4"})) + verify(compareObjectNames(control.data, ["object", "menu1", "timer", "menu2", "", "menu3", "menu4"])) + verify(compareObjectNames(control.menus, ["menu4", "menu1", "menu2", "menu3"])) + compare(menusSpy.count, 2) + + control.removeMenu(control.menus[1]) + verify(compareObjectNames(control.data, ["object", "timer", "menu2", "", "menu3", "menu4"])) + verify(compareObjectNames(control.menus, ["menu4", "menu2", "menu3"])) + compare(menusSpy.count, 3) + + control.destroy() + } + + Component { + id: dynamicBar + MenuBar { + id: dbar + Menu { title: "static" } + Component.onCompleted: { + addMenu(menu.createObject(dbar, {title: "added"})) + insertMenu(0, menu.createObject(dbar, {title: "inserted"})) + } + } + } + + function test_dynamic() { + var control = dynamicBar.createObject(testCase) + + // insertMenu(), addMenu(), and static Menu {} + compare(control.menus.length, 3) + compare(control.menus[0].title, "inserted") + + var dying = menu.createObject(control, {title: "dying"}) + control.addMenu(dying) + compare(control.menus.length, 4) + compare(control.menus[3].title, "dying") + dying.destroy() + wait(0) + compare(control.menus.length, 3) + + control.destroy() + } +} diff --git a/tests/auto/quickcontrols2/platform/data/tst_menuitem.qml b/tests/auto/quickcontrols2/platform/data/tst_menuitem.qml new file mode 100644 index 00000000000..0120832d05c --- /dev/null +++ b/tests/auto/quickcontrols2/platform/data/tst_menuitem.qml @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import Qt.labs.platform + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "MenuItem" + + Component { + id: menuItem + // Check that icon.name can be used in this Qt.labs.platform version + MenuItem { + icon.name: "" + } + } + + Component { + id: signalSpyComponent + SignalSpy {} + } + + function test_properties_data() { + return [ + {tag: "enabled", signal: "enabledChanged", init: true, value: false}, + {tag: "visible", signal: "visibleChanged", init: true, value: false}, + {tag: "separator", signal: "separatorChanged", init: false, value: true}, + {tag: "checkable", signal: "checkableChanged", init: false, value: true}, + {tag: "checked", signal: "checkedChanged", init: false, value: true}, + {tag: "role", signal: "roleChanged", init: MenuItem.TextHeuristicRole, value: MenuItem.AboutRole}, + {tag: "text", signal: "textChanged", init: "", value: "text"}, + {tag: "icon.source", signal: "iconChanged", init: "", value: "qrc:/undo.png"}, + {tag: "icon.name", signal: "iconChanged", init: "", value: "edit-undo"}, + {tag: "shortcut", signal: "shortcutChanged", init: undefined, value: StandardKey.Undo} + ] + } + + function test_properties(data) { + let item = createTemporaryObject(menuItem, testCase) + verify(item) + + let groupedProperty = data.tag.indexOf(".") !== -1 + let spy = createTemporaryObject(signalSpyComponent, testCase, { + target: item, signalName: data.signal + }) + verify(spy) + verify(spy.valid) + + let propertyName = groupedProperty ? data.tag.split('.')[1] : data.tag + let object = !groupedProperty ? item : item.icon + compare(object[propertyName], data.init) + object[propertyName] = data.value + compare(spy.count, 1) + compare(object[propertyName], data.value) + + object[propertyName] = data.value + compare(spy.count, 1) + } + + function test_role() { + // Q_ENUMS(QPlatformMenuItem::MenuRole) + compare(MenuItem.NoRole, 0) + compare(MenuItem.TextHeuristicRole, 1) + compare(MenuItem.ApplicationSpecificRole, 2) + compare(MenuItem.AboutQtRole, 3) + compare(MenuItem.AboutRole, 4) + compare(MenuItem.PreferencesRole, 5) + compare(MenuItem.QuitRole, 6) + } +} diff --git a/tests/auto/quickcontrols2/platform/data/tst_menuitemgroup.qml b/tests/auto/quickcontrols2/platform/data/tst_menuitemgroup.qml new file mode 100644 index 00000000000..117f79ce1ab --- /dev/null +++ b/tests/auto/quickcontrols2/platform/data/tst_menuitemgroup.qml @@ -0,0 +1,390 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import Qt.labs.platform + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "MenuItemGroup" + + Component { + id: menuItemGroup + MenuItemGroup { } + } + + SignalSpy { + id: checkedItemSpy + signalName: "checkedItemChanged" + } + + SignalSpy { + id: itemsSpy + signalName: "itemsChanged" + } + + function init() { + verify(!checkedItemSpy.target) + compare(checkedItemSpy.count, 0) + + verify(!itemsSpy.target) + compare(itemsSpy.count, 0) + } + + function cleanup() { + checkedItemSpy.target = null + checkedItemSpy.clear() + + itemsSpy.target = null + itemsSpy.clear() + } + + function test_null() { + var group = menuItemGroup.createObject(testCase) + verify(group) + + group.addItem(null) + group.removeItem(null) + + group.destroy() + } + + Component { + id: item + MenuItem { } + } + + function test_exclusive() { + var group = menuItemGroup.createObject(testCase) + verify(group) + + compare(group.exclusive, true) + + checkedItemSpy.target = group + verify(checkedItemSpy.valid) + verify(!group.checkedItem) + + var item1 = item.createObject(testCase, {checked: true}) + var item2 = item.createObject(testCase, {checked: false}) + var item3 = item.createObject(testCase, {checked: true}) + + // add checked + group.addItem(item1) + compare(group.checkedItem, item1) + compare(item1.checked, true) + compare(item2.checked, false) + compare(item3.checked, true) + compare(checkedItemSpy.count, 1) + + // add non-checked + group.addItem(item2) + compare(group.checkedItem, item1) + compare(item1.checked, true) + compare(item2.checked, false) + compare(item3.checked, true) + compare(checkedItemSpy.count, 1) + + // add checked + group.addItem(item3) + compare(group.checkedItem, item3) + compare(item1.checked, false) + compare(item2.checked, false) + compare(item3.checked, true) + compare(checkedItemSpy.count, 2) + + // change checked + group.checkedItem = item2 + compare(group.checkedItem, item2) + compare(item1.checked, false) + compare(item2.checked, true) + compare(item3.checked, false) + compare(checkedItemSpy.count, 3) + + // check + item1.checked = true + compare(group.checkedItem, item1) + compare(item1.checked, true) + compare(item2.checked, false) + compare(item3.checked, false) + compare(checkedItemSpy.count, 4) + + // remove non-checked + group.removeItem(item2) + compare(group.checkedItem, item1) + compare(item1.checked, true) + compare(item2.checked, false) + compare(item3.checked, false) + compare(checkedItemSpy.count, 4) + + // remove checked + group.removeItem(item1) + compare(group.checkedItem, null) + compare(item1.checked, false) + compare(item2.checked, false) + compare(item3.checked, false) + compare(checkedItemSpy.count, 5) + + group.destroy() + } + + function test_nonExclusive() { + var group = menuItemGroup.createObject(testCase, {exclusive: false}) + verify(group) + + compare(group.exclusive, false) + + checkedItemSpy.target = group + verify(checkedItemSpy.valid) + verify(!group.checkedItem) + + var item1 = item.createObject(testCase, {checked: true}) + var item2 = item.createObject(testCase, {checked: false}) + var item3 = item.createObject(testCase, {checked: true}) + + // add checked + group.addItem(item1) + compare(group.checkedItem, null) + compare(item1.checked, true) + compare(item2.checked, false) + compare(item3.checked, true) + compare(checkedItemSpy.count, 0) + + // add non-checked + group.addItem(item2) + compare(group.checkedItem, null) + compare(item1.checked, true) + compare(item2.checked, false) + compare(item3.checked, true) + compare(checkedItemSpy.count, 0) + + // add checked + group.addItem(item3) + compare(group.checkedItem, null) + compare(item1.checked, true) + compare(item2.checked, false) + compare(item3.checked, true) + compare(checkedItemSpy.count, 0) + + // change checked + group.checkedItem = item2 + compare(group.checkedItem, item2) + compare(item1.checked, true) + compare(item2.checked, true) + compare(item3.checked, true) + compare(checkedItemSpy.count, 1) + + // check + item1.checked = false + item1.checked = true + compare(group.checkedItem, item2) + compare(item1.checked, true) + compare(item2.checked, true) + compare(item3.checked, true) + compare(checkedItemSpy.count, 1) + + // remove checked + group.removeItem(item2) + compare(group.checkedItem, null) + compare(item1.checked, true) + compare(item2.checked, false) + compare(item3.checked, true) + compare(checkedItemSpy.count, 2) + + // remove non-checked + group.removeItem(item1) + compare(group.checkedItem, null) + compare(item1.checked, true) + compare(item2.checked, false) + compare(item3.checked, true) + compare(checkedItemSpy.count, 2) + + group.destroy() + } + + function test_items() { + var group = menuItemGroup.createObject(testCase) + verify(group) + + itemsSpy.target = group + verify(itemsSpy.valid) + + compare(group.items.length, 0) + compare(group.checkedItem, null) + + var item1 = item.createObject(testCase, {checked: true}) + var item2 = item.createObject(testCase, {checked: false}) + + group.items = [item1, item2] + compare(group.items.length, 2) + compare(group.items[0], item1) + compare(group.items[1], item2) + compare(group.checkedItem, item1) + compare(itemsSpy.count, 2) + + var item3 = item.createObject(testCase, {checked: true}) + + group.addItem(item3) + compare(group.items.length, 3) + compare(group.items[0], item1) + compare(group.items[1], item2) + compare(group.items[2], item3) + compare(group.checkedItem, item3) + compare(itemsSpy.count, 3) + + group.removeItem(item1) + compare(group.items.length, 2) + compare(group.items[0], item2) + compare(group.items[1], item3) + compare(group.checkedItem, item3) + compare(itemsSpy.count, 4) + + group.items = [] + compare(group.items.length, 0) + compare(group.checkedItem, null) + compare(itemsSpy.count, 5) + + group.destroy() + } + + function test_itemDestroyed() { + var group = menuItemGroup.createObject(testCase) + verify(group) + + itemsSpy.target = group + verify(itemsSpy.valid) + + var item1 = item.createObject(testCase, {checked: true}) + + group.addItem(item1) + compare(group.items.length, 1) + compare(group.items[0], item1) + compare(group.checkedItem, item1) + compare(itemsSpy.count, 1) + + item1.destroy() + wait(0) + compare(group.items.length, 0) + compare(group.checkedItem, null) + compare(itemsSpy.count, 2) + + group.destroy() + } + + function test_visible() { + var group = menuItemGroup.createObject(testCase) + verify(group) + + compare(group.visible, true) + + for (var i = 0; i < 3; ++i) { + group.addItem(item.createObject(testCase)) + compare(group.items[i].visible, true) + } + + group.visible = false + compare(group.visible, false) + + for (i = 0; i < 3; ++i) + compare(group.items[i].visible, false) + + group.items[1].visible = true + compare(group.items[1].visible, false) + + group.items[1].visible = false + compare(group.items[1].visible, false) + + group.visible = true + compare(group.visible, true) + + compare(group.items[0].visible, true) + compare(group.items[1].visible, false) + compare(group.items[2].visible, true) + + group.destroy() + } + + function test_enabled() { + var group = menuItemGroup.createObject(testCase) + verify(group) + + compare(group.enabled, true) + + for (var i = 0; i < 3; ++i) { + group.addItem(item.createObject(testCase)) + compare(group.items[i].enabled, true) + } + + group.enabled = false + compare(group.enabled, false) + + for (i = 0; i < 3; ++i) + compare(group.items[i].enabled, false) + + group.items[1].enabled = true + compare(group.items[1].enabled, false) + + group.items[1].enabled = false + compare(group.items[1].enabled, false) + + group.enabled = true + compare(group.enabled, true) + + compare(group.items[0].enabled, true) + compare(group.items[1].enabled, false) + compare(group.items[2].enabled, true) + + group.destroy() + } +} diff --git a/tests/auto/quickcontrols2/platform/data/tst_menuseparator.qml b/tests/auto/quickcontrols2/platform/data/tst_menuseparator.qml new file mode 100644 index 00000000000..52bb349fd36 --- /dev/null +++ b/tests/auto/quickcontrols2/platform/data/tst_menuseparator.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import Qt.labs.platform + +TestCase { + id: testCase + width: 200 + height: 200 + name: "MenuSeparator" + + Component { + id: menuSeparator + MenuSeparator { } + } + + function test_separator() { + var separator = menuSeparator.createObject(testCase) + verify(separator) + + compare(separator.separator, true) + + separator.destroy() + } +} diff --git a/tests/auto/quickcontrols2/platform/data/tst_messagedialog.qml b/tests/auto/quickcontrols2/platform/data/tst_messagedialog.qml new file mode 100644 index 00000000000..23a5c821b21 --- /dev/null +++ b/tests/auto/quickcontrols2/platform/data/tst_messagedialog.qml @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import Qt.labs.platform + +TestCase { + id: testCase + width: 200 + height: 200 + name: "MessageDialog" + + Component { + id: messageDialog + MessageDialog { } + } + + SignalSpy { + id: spy + } + + function test_instance() { + var dialog = messageDialog.createObject(testCase) + verify(dialog) + dialog.destroy() + } + + function test_standardButtons() { + // Q_FLAGS(QPlatformDialogHelper::StandardButtons) + compare(MessageDialog.NoButton , 0x00000000) + compare(MessageDialog.Ok , 0x00000400) + compare(MessageDialog.Save , 0x00000800) + compare(MessageDialog.SaveAll , 0x00001000) + compare(MessageDialog.Open , 0x00002000) + compare(MessageDialog.Yes , 0x00004000) + compare(MessageDialog.YesToAll , 0x00008000) + compare(MessageDialog.No , 0x00010000) + compare(MessageDialog.NoToAll , 0x00020000) + compare(MessageDialog.Abort , 0x00040000) + compare(MessageDialog.Retry , 0x00080000) + compare(MessageDialog.Ignore , 0x00100000) + compare(MessageDialog.Close , 0x00200000) + compare(MessageDialog.Cancel , 0x00400000) + compare(MessageDialog.Discard , 0x00800000) + compare(MessageDialog.Help , 0x01000000) + compare(MessageDialog.Apply , 0x02000000) + compare(MessageDialog.Reset , 0x04000000) + compare(MessageDialog.RestoreDefaults, 0x08000000) + } + + function test_clicked() { + var dialog = messageDialog.createObject(testCase) + verify(dialog) + + spy.target = dialog + spy.signalName = "clicked" + + dialog.clicked(MessageDialog.Yes) + compare(spy.count, 1) + compare(spy.signalArguments[0][0], MessageDialog.Yes) + + spy.clear() + dialog.destroy() + } +} diff --git a/tests/auto/quickcontrols2/platform/data/tst_standardpaths.qml b/tests/auto/quickcontrols2/platform/data/tst_standardpaths.qml new file mode 100644 index 00000000000..1edc67a85ab --- /dev/null +++ b/tests/auto/quickcontrols2/platform/data/tst_standardpaths.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import Qt.labs.platform + +TestCase { + id: testCase + name: "StandardPaths" + + function test_standardLocation() { + // Q_ENUMS(QStandardPaths::StandardLocation) + compare(StandardPaths.DesktopLocation, 0) + compare(StandardPaths.DocumentsLocation, 1) + compare(StandardPaths.FontsLocation, 2) + compare(StandardPaths.ApplicationsLocation, 3) + compare(StandardPaths.MusicLocation, 4) + compare(StandardPaths.MoviesLocation, 5) + compare(StandardPaths.PicturesLocation, 6) + compare(StandardPaths.TempLocation, 7) + compare(StandardPaths.HomeLocation, 8) + compare(StandardPaths.AppLocalDataLocation, 9) + compare(StandardPaths.CacheLocation, 10) + compare(StandardPaths.GenericDataLocation, 11) + compare(StandardPaths.RuntimeLocation, 12) + compare(StandardPaths.ConfigLocation, 13) + compare(StandardPaths.DownloadLocation, 14) + compare(StandardPaths.GenericCacheLocation, 15) + compare(StandardPaths.GenericConfigLocation, 16) + compare(StandardPaths.AppDataLocation, 17) + compare(StandardPaths.AppConfigLocation, 18) + } + + function test_locateOptions() { + // Q_ENUMS(QStandardPaths::LocateOptions) + compare(StandardPaths.LocateFile, 0) + compare(StandardPaths.LocateDirectory, 1) + } +} diff --git a/tests/auto/quickcontrols2/platform/data/tst_systemtrayicon.qml b/tests/auto/quickcontrols2/platform/data/tst_systemtrayicon.qml new file mode 100644 index 00000000000..09f1026175b --- /dev/null +++ b/tests/auto/quickcontrols2/platform/data/tst_systemtrayicon.qml @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import Qt.labs.platform + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "SystemTrayIcon" + + Component { + id: systemTrayIconComponent + // Check that icon.name can be used in this Qt.labs.platform version + SystemTrayIcon { + icon.name: "" + } + } + + Component { + id: signalSpyComponent + SignalSpy {} + } + + function test_properties_data() { + return [ + {tag: "visible", signal: "visibleChanged", init: false, value: true}, + {tag: "icon.source", signal: "iconChanged", init: "", value: "qrc:/tray.png"}, + {tag: "icon.name", signal: "iconChanged", init: "", value: "icon-name"}, + {tag: "tooltip", signal: "tooltipChanged", init: "", value: "tooltip"}, + ] + } + + function test_properties(data) { + let icon = createTemporaryObject(systemTrayIconComponent, testCase) + verify(icon) + + let groupedProperty = data.tag.indexOf(".") !== -1 + let spy = createTemporaryObject(signalSpyComponent, testCase, { + target: icon, signalName: data.signal + }) + verify(spy) + verify(spy.valid) + + let propertyName = groupedProperty ? data.tag.split('.')[1] : data.tag + let object = !groupedProperty ? icon : icon.icon + compare(object[propertyName], data.init) + + object[propertyName] = data.value + compare(spy.count, 1) + compare(object[propertyName], data.value) + + object[propertyName] = data.value + compare(spy.count, 1) + } + + function test_messageIcon() { + // Q_ENUMS(QPlatformSystemTrayIcon::ActivationReason) + compare(SystemTrayIcon.NoIcon, 0) + compare(SystemTrayIcon.Information, 1) + compare(SystemTrayIcon.Warning, 2) + compare(SystemTrayIcon.Critical, 3) + } + + function test_activationReason() { + // Q_ENUMS(QPlatformSystemTrayIcon::ActivationReason) + compare(SystemTrayIcon.Unknown, 0) + compare(SystemTrayIcon.Context, 1) + compare(SystemTrayIcon.DoubleClick, 2) + compare(SystemTrayIcon.Trigger, 3) + compare(SystemTrayIcon.MiddleClick, 4) + } + + function test_activated() { + let icon = createTemporaryObject(systemTrayIconComponent, testCase) + verify(icon) + + let spy = createTemporaryObject(signalSpyComponent, testCase, { + target: icon, signalName: "activated" + }) + verify(spy) + verify(spy.valid) + + icon.activated(SystemTrayIcon.Trigger) + compare(spy.count, 1) + compare(spy.signalArguments[0][0], SystemTrayIcon.Trigger) + } +} diff --git a/tests/auto/quickcontrols2/platform/tst_platform.cpp b/tests/auto/quickcontrols2/platform/tst_platform.cpp new file mode 100644 index 00000000000..2cf4cd2c4d8 --- /dev/null +++ b/tests/auto/quickcontrols2/platform/tst_platform.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQml/qqmlengine.h> +#include <QtQuickTest/quicktest.h> + +class Setup : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool shortcutsSupported READ areShortcutsSupported CONSTANT FINAL) + +public: + bool areShortcutsSupported() const + { +#if QT_CONFIG(shortcut) + return true; +#else + return false; +#endif + } + +public slots: + void qmlEngineAvailable(QQmlEngine *) + { + qmlRegisterSingletonInstance("org.qtproject.Test", 1, 0, "TestHelper", this); + } +}; + +QUICK_TEST_MAIN_WITH_SETUP(tst_platform, Setup) + +#include "tst_platform.moc" diff --git a/tests/auto/quickcontrols2/pointerhandlers/CMakeLists.txt b/tests/auto/quickcontrols2/pointerhandlers/CMakeLists.txt new file mode 100644 index 00000000000..08790d6784e --- /dev/null +++ b/tests/auto/quickcontrols2/pointerhandlers/CMakeLists.txt @@ -0,0 +1,37 @@ +##################################################################### +## tst_pointerhandlers Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_pointerhandlers + SOURCES + tst_pointerhandlers.cpp + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlModelsPrivate + Qt::QmlPrivate + Qt::QuickPrivate + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickTemplates2Private + TESTDATA ${test_data} +) + +qt_internal_extend_target(tst_pointerhandlers CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_pointerhandlers CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/pointerhandlers/data/controlandmousearea.qml b/tests/auto/quickcontrols2/pointerhandlers/data/controlandmousearea.qml new file mode 100644 index 00000000000..00c680453ad --- /dev/null +++ b/tests/auto/quickcontrols2/pointerhandlers/data/controlandmousearea.qml @@ -0,0 +1,49 @@ +import QtQuick +import QtQuick.Controls + +Item { + width: 640 + height: 480 + visible: true + + property alias outerMouseArea: outerMouseArea + property alias buttonInTheMiddle: buttonInTheMiddle + property alias innerMouseArea: innerMouseArea + + MouseArea { + id: outerMouseArea + x: 10 + y: 10 + width: 200 + height: 200 + hoverEnabled: true + Rectangle { + anchors.fill: parent + border.width: 1 + color: outerMouseArea.containsMouse ? "cyan" : "transparent" + } + + Button { + id: buttonInTheMiddle + width: parent.width - 20 + height: parent.height - 20 + anchors.right: parent.right + anchors.bottom: parent.bottom + text: hovered ? "hovered" : "" + + MouseArea { + id: innerMouseArea + width: parent.width - 20 + height: parent.height - 20 + anchors.right: parent.right + anchors.bottom: parent.bottom + hoverEnabled: true + Rectangle { + anchors.fill: parent + border.width: 1 + color: innerMouseArea.containsMouse ? "yellow" : "transparent" + } + } + } + } +} diff --git a/tests/auto/quickcontrols2/pointerhandlers/data/controlinsidecontrol.qml b/tests/auto/quickcontrols2/pointerhandlers/data/controlinsidecontrol.qml new file mode 100644 index 00000000000..69d855ec57c --- /dev/null +++ b/tests/auto/quickcontrols2/pointerhandlers/data/controlinsidecontrol.qml @@ -0,0 +1,31 @@ +import QtQuick +import QtQuick.Controls + +Item { + width: 640 + height: 480 + visible: true + + property alias outerButton: outerButton + property alias innerButton: innerButton + + Button { + id: outerButton + x: 5 + y: 5 + width: 200 + height: 200 + hoverEnabled: true + text: hovered ? "hovered" : "" + + Button { + id: innerButton + width: parent.width - 20 + height: parent.height - 20 + anchors.right: parent.right + anchors.bottom: parent.bottom + text: hovered ? "hovered" : "" + opacity: 0.5 + } + } +} diff --git a/tests/auto/quickcontrols2/pointerhandlers/tst_pointerhandlers.cpp b/tests/auto/quickcontrols2/pointerhandlers/tst_pointerhandlers.cpp new file mode 100644 index 00000000000..d2e28b70445 --- /dev/null +++ b/tests/auto/quickcontrols2/pointerhandlers/tst_pointerhandlers.cpp @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module 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 <QtTest/QtTest> +#include <QtQuickTest/quicktest.h> + +#include <QtQuick/qquickview.h> +#include <QtQuick/private/qquickmousearea_p.h> + +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcontext.h> + +#include <QtQuickTemplates2/private/qquickbutton_p.h> + +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> + +using namespace QQuickViewTestUtils; +using namespace QQuickVisualTestUtils; + +class tst_pointerhandlers : public QQmlDataTest +{ + Q_OBJECT +public: + tst_pointerhandlers(); + +private slots: + void hover_controlInsideControl(); + void hover_controlAndMouseArea(); +}; + +tst_pointerhandlers::tst_pointerhandlers() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_pointerhandlers::hover_controlInsideControl() +{ + // Test that if you move the mouse over a control that is + // a child of another control, both controls end up hovered. + // A control should basically not block (accept) hover events. + QQuickView view(testFileUrl("controlinsidecontrol.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QQuickItem *rootItem = view.rootObject(); + QVERIFY(rootItem); + QQuickWindow *window = rootItem->window(); + QVERIFY(window); + + const auto context = qmlContext(rootItem); + auto outerButton = context->contextProperty("outerButton").value<QQuickButton *>(); + auto innerButton = context->contextProperty("innerButton").value<QQuickButton *>(); + QVERIFY(outerButton); + QVERIFY(innerButton); + + const QPoint posInWindow(1, 1); + const QPoint posOnOuterButton = rootItem->mapFromItem(outerButton, QPointF(0, 0)).toPoint(); + const QPoint posOnInnerButton = rootItem->mapFromItem(innerButton, QPointF(0, 0)).toPoint(); + + // Start by moving the mouse to the window + QTest::mouseMove(window, posInWindow); + QCOMPARE(outerButton->isHovered(), false); + QCOMPARE(innerButton->isHovered(), false); + + // Move the mouse over the outer control + QTest::mouseMove(window, posOnOuterButton); + QCOMPARE(outerButton->isHovered(), true); + QCOMPARE(innerButton->isHovered(), false); + + // Move the mouse over the inner control + QTest::mouseMove(window, posOnInnerButton); + QCOMPARE(outerButton->isHovered(), true); + QCOMPARE(innerButton->isHovered(), true); + + // Move the mouse over the outer control again + QTest::mouseMove(window, posOnOuterButton); + QCOMPARE(outerButton->isHovered(), true); + QCOMPARE(innerButton->isHovered(), false); + + // Move the mouse outside all controls + QTest::mouseMove(window, posInWindow); + QCOMPARE(outerButton->isHovered(), false); + QCOMPARE(innerButton->isHovered(), false); +} + +void tst_pointerhandlers::hover_controlAndMouseArea() +{ + QQuickView view(testFileUrl("controlandmousearea.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QQuickItem *rootItem = view.rootObject(); + QVERIFY(rootItem); + QQuickWindow *window = rootItem->window(); + QVERIFY(window); + + const auto context = qmlContext(rootItem); + auto outerMouseArea = context->contextProperty("outerMouseArea").value<QQuickMouseArea *>(); + auto buttonInTheMiddle = context->contextProperty("buttonInTheMiddle").value<QQuickButton *>(); + auto innerMouseArea = context->contextProperty("innerMouseArea").value<QQuickMouseArea *>(); + QVERIFY(outerMouseArea); + QVERIFY(buttonInTheMiddle); + QVERIFY(innerMouseArea); + + const QPoint posInWindow(1, 1); + const QPoint posOnOuterMouseArea = rootItem->mapFromItem(outerMouseArea, QPointF(0, 0)).toPoint(); + const QPoint posOnButtonInTheMiddle = rootItem->mapFromItem(buttonInTheMiddle, QPointF(0, 0)).toPoint(); + const QPoint posOnInnerMouseArea = rootItem->mapFromItem(innerMouseArea, QPointF(0, 0)).toPoint(); + + // Start by moving the mouse to the window + QTest::mouseMove(window, posInWindow); + QCOMPARE(outerMouseArea->hovered(), false); + QCOMPARE(buttonInTheMiddle->isHovered(), false); + QCOMPARE(innerMouseArea->hovered(), false); + + // Move the mouse over the outer mousearea + QTest::mouseMove(window, posOnOuterMouseArea); + QCOMPARE(outerMouseArea->hovered(), true); + QCOMPARE(buttonInTheMiddle->isHovered(), false); + QCOMPARE(innerMouseArea->hovered(), false); + + // Move the mouse over the button in the middle + QTest::mouseMove(window, posOnButtonInTheMiddle); + QCOMPARE(outerMouseArea->hovered(), true); + QCOMPARE(buttonInTheMiddle->isHovered(), true); + QCOMPARE(innerMouseArea->hovered(), false); + + // Move the mouse over the inner mousearea + QTest::mouseMove(window, posOnInnerMouseArea); + QCOMPARE(outerMouseArea->hovered(), true); + QCOMPARE(buttonInTheMiddle->isHovered(), true); + QCOMPARE(innerMouseArea->hovered(), true); + + // Move the mouse over the button in the middle again + QTest::mouseMove(window, posOnButtonInTheMiddle); + QCOMPARE(outerMouseArea->hovered(), true); + QCOMPARE(buttonInTheMiddle->isHovered(), true); + QCOMPARE(innerMouseArea->hovered(), false); + + // Move the mouse over the outer mousearea again + QTest::mouseMove(window, posOnOuterMouseArea); + QCOMPARE(outerMouseArea->hovered(), true); + QCOMPARE(buttonInTheMiddle->isHovered(), false); + QCOMPARE(innerMouseArea->hovered(), false); + + // Move the mouse outside all items + QTest::mouseMove(window, posInWindow); + QCOMPARE(outerMouseArea->hovered(), false); + QCOMPARE(buttonInTheMiddle->isHovered(), false); + QCOMPARE(innerMouseArea->hovered(), false); +} + +QTEST_MAIN(tst_pointerhandlers) + +#include "tst_pointerhandlers.moc" diff --git a/tests/auto/quickcontrols2/pressandhold/CMakeLists.txt b/tests/auto/quickcontrols2/pressandhold/CMakeLists.txt new file mode 100644 index 00000000000..cf2d92a5679 --- /dev/null +++ b/tests/auto/quickcontrols2/pressandhold/CMakeLists.txt @@ -0,0 +1,21 @@ +# Generated from pressandhold.pro. + +##################################################################### +## tst_pressandhold Test: +##################################################################### + +qt_internal_add_test(tst_pressandhold + SOURCES + tst_pressandhold.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Quick + Qt::QuickControls2 + Qt::QuickTemplates2 +) + +#### Keys ignored in scope 1:.:.:pressandhold.pro:<TRUE>: +# TEMPLATE = "app" + +## Scopes: +##################################################################### diff --git a/tests/auto/quickcontrols2/pressandhold/data/dependencies.qml b/tests/auto/quickcontrols2/pressandhold/data/dependencies.qml new file mode 100644 index 00000000000..280cfd29623 --- /dev/null +++ b/tests/auto/quickcontrols2/pressandhold/data/dependencies.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +Control { } diff --git a/tests/auto/quickcontrols2/pressandhold/tst_pressandhold.cpp b/tests/auto/quickcontrols2/pressandhold/tst_pressandhold.cpp new file mode 100644 index 00000000000..1eb5eebc9aa --- /dev/null +++ b/tests/auto/quickcontrols2/pressandhold/tst_pressandhold.cpp @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest> +#include <QtQuick> +#include <QtQuickControls2/qquickstyle.h> +#include <QStyleHints> + +class tst_PressAndHold : public QObject +{ + Q_OBJECT + +public: + tst_PressAndHold(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void pressAndHold_data(); + void pressAndHold(); + + void keepSelection_data(); + void keepSelection(); +}; + +tst_PressAndHold::tst_PressAndHold() +{ + QQuickStyle::setStyle("Basic"); +} + +void tst_PressAndHold::initTestCase() +{ + QGuiApplication::styleHints()->setMousePressAndHoldInterval(100); +} + +void tst_PressAndHold::cleanupTestCase() +{ + QGuiApplication::styleHints()->setMousePressAndHoldInterval(-1); +} + +void tst_PressAndHold::pressAndHold_data() +{ + QTest::addColumn<QByteArray>("data"); + QTest::addColumn<QByteArray>("signal"); + + QTest::newRow("Button") << QByteArray("import QtQuick.Controls; Button { text: 'Button' }") << QByteArray(SIGNAL(pressAndHold())); + QTest::newRow("SwipeDelegate") << QByteArray("import QtQuick.Controls; SwipeDelegate { text: 'SwipeDelegate' }") << QByteArray(SIGNAL(pressAndHold())); + QTest::newRow("TextField") << QByteArray("import QtQuick.Controls; TextField { text: 'TextField' }") << QByteArray(SIGNAL(pressAndHold(QQuickMouseEvent*))); + QTest::newRow("TextArea") << QByteArray("import QtQuick.Controls; TextArea { text: 'TextArea' }") << QByteArray(SIGNAL(pressAndHold(QQuickMouseEvent*))); +} + +void tst_PressAndHold::pressAndHold() +{ + QFETCH(QByteArray, data); + QFETCH(QByteArray, signal); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(data, QUrl()); + + QScopedPointer<QObject> control(component.create()); + QScopedPointer<QObject> waitControl(component.create()); + QVERIFY(!control.isNull() && !waitControl.isNull()); + + QSignalSpy spy(control.data(), signal); + QSignalSpy waitSpy(waitControl.data(), signal); + QVERIFY(spy.isValid() && waitSpy.isValid()); + + int startDragDistance = QGuiApplication::styleHints()->startDragDistance(); + QMouseEvent press(QEvent::MouseButtonPress, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QMouseEvent press2(QEvent::MouseButtonPress, QPointF(), Qt::RightButton, Qt::RightButton, Qt::NoModifier); + QMouseEvent move(QEvent::MouseMove, QPointF(2 * startDragDistance, 2 * startDragDistance), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QMouseEvent release(QEvent::MouseButtonRelease, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + + // pressAndHold() emitted + QGuiApplication::sendEvent(control.data(), &press); + QTRY_COMPARE(spy.count(), 1); + QGuiApplication::sendEvent(control.data(), &release); + QCOMPARE(spy.count(), 1); + spy.clear(); + + // pressAndHold() canceled by release + QGuiApplication::sendEvent(control.data(), &press); + QGuiApplication::processEvents(); + QGuiApplication::sendEvent(control.data(), &release); + QCOMPARE(spy.count(), 0); + + // pressAndHold() canceled by move + QGuiApplication::sendEvent(control.data(), &press); + QGuiApplication::sendEvent(control.data(), &move); // cancels pressAndHold() + QGuiApplication::sendEvent(waitControl.data(), &press); + // by the time the second control emits pressAndHold(), we can reliably + // assume that the first control would have emitted pressAndHold() if it + // wasn't canceled as appropriate by the move event above + QTRY_COMPARE(waitSpy.count(), 1); + QCOMPARE(spy.count(), 0); + QGuiApplication::sendEvent(control.data(), &release); + QGuiApplication::sendEvent(waitControl.data(), &release); + QCOMPARE(waitSpy.count(), 1); + QCOMPARE(spy.count(), 0); + waitSpy.clear(); + + // pressAndHold() canceled by 2nd press + QGuiApplication::sendEvent(control.data(), &press); + QGuiApplication::sendEvent(control.data(), &press2); // cancels pressAndHold() + QGuiApplication::sendEvent(waitControl.data(), &press); + // by the time the second control emits pressAndHold(), we can reliably + // assume that the first control would have emitted pressAndHold() if it + // wasn't canceled as appropriate by the 2nd press event above + QTRY_COMPARE(waitSpy.count(), 1); + QCOMPARE(spy.count(), 0); + QGuiApplication::sendEvent(control.data(), &release); + QGuiApplication::sendEvent(waitControl.data(), &release); + QCOMPARE(waitSpy.count(), 1); + QCOMPARE(spy.count(), 0); + waitSpy.clear(); +} + +void tst_PressAndHold::keepSelection_data() +{ + QTest::addColumn<QByteArray>("data"); + + QTest::newRow("TextField") << QByteArray("import QtQuick.Controls; TextField { text: 'TextField' }"); + QTest::newRow("TextArea") << QByteArray("import QtQuick.Controls; TextArea { text: 'TextArea' }"); +} + +void tst_PressAndHold::keepSelection() +{ + QFETCH(QByteArray, data); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(data, QUrl()); + + QScopedPointer<QObject> control(component.create()); + QScopedPointer<QObject> waitControl(component.create()); + QVERIFY(!control.isNull() && !waitControl.isNull()); + + QSignalSpy spy(control.data(), SIGNAL(pressAndHold(QQuickMouseEvent*))); + QSignalSpy waitSpy(waitControl.data(), SIGNAL(pressAndHold(QQuickMouseEvent*))); + QVERIFY(spy.isValid() && waitSpy.isValid()); + + QMouseEvent press(QEvent::MouseButtonPress, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QMouseEvent press2(QEvent::MouseButtonPress, QPointF(), Qt::RightButton, Qt::RightButton, Qt::NoModifier); + QMouseEvent release(QEvent::MouseButtonRelease, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + + QVERIFY(!control->property("text").toString().isEmpty()); + QVERIFY(QMetaObject::invokeMethod(control.data(), "selectAll")); + QCOMPARE(control->property("selectedText"), control->property("text")); + + // pressAndHold() emitted => selection remains + QGuiApplication::sendEvent(control.data(), &press); + QTRY_COMPARE(spy.count(), 1); + QGuiApplication::sendEvent(control.data(), &release); + QCOMPARE(spy.count(), 1); + QCOMPARE(control->property("selectedText"), control->property("text")); + spy.clear(); + + // pressAndHold() canceled by release => selection cleared + QGuiApplication::sendEvent(control.data(), &press); + QGuiApplication::processEvents(); + QGuiApplication::sendEvent(control.data(), &release); + QCOMPARE(spy.count(), 0); + QVERIFY(control->property("selectedText").toString().isEmpty()); + + QVERIFY(QMetaObject::invokeMethod(control.data(), "selectAll")); + QCOMPARE(control->property("selectedText"), control->property("text")); + + // pressAndHold() canceled by 2nd press => selection cleared + QGuiApplication::sendEvent(control.data(), &press); + QGuiApplication::sendEvent(control.data(), &press2); // cancels pressAndHold() + QGuiApplication::sendEvent(waitControl.data(), &press); + // by the time the second control emits pressAndHold(), we can reliably + // assume that the first control would have emitted pressAndHold() if it + // wasn't canceled as appropriate by the move event above + QTRY_COMPARE(waitSpy.count(), 1); + QCOMPARE(spy.count(), 0); + QGuiApplication::sendEvent(control.data(), &release); + QGuiApplication::sendEvent(waitControl.data(), &release); + QCOMPARE(waitSpy.count(), 1); + QCOMPARE(spy.count(), 0); + QVERIFY(control->property("selectedText").toString().isEmpty()); + waitSpy.clear(); +} + +QTEST_MAIN(tst_PressAndHold) + +#include "tst_pressandhold.moc" diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/CMakeLists.txt b/tests/auto/quickcontrols2/qquickapplicationwindow/CMakeLists.txt new file mode 100644 index 00000000000..140d78a14ee --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/CMakeLists.txt @@ -0,0 +1,48 @@ +# Generated from qquickapplicationwindow.pro. + +##################################################################### +## tst_qquickapplicationwindow Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickapplicationwindow + SOURCES + tst_qquickapplicationwindow.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:qquickapplicationwindow.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickapplicationwindow CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickapplicationwindow CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/activeFocusControl.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/activeFocusControl.qml new file mode 100644 index 00000000000..ef69499025d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/activeFocusControl.qml @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias container_column: column + property alias textInput_column: ti_column + property alias textEdit_column: te_column + property alias textField_column: tf_column + property alias textArea_column: ta_column + property alias spinBox_column: sp_column + property alias spinContent_column: sp_column.contentItem + + property alias container_frame: frame + property alias textInput_frame: ti_frame + property alias textEdit_frame: te_frame + property alias textField_frame: tf_frame + property alias textArea_frame: ta_frame + property alias spinBox_frame: sp_frame + property alias spinContent_frame: sp_frame.contentItem + + Column { + id: column + + TextInput { + id: ti_column + } + TextEdit { + id: te_column + } + TextField { + id: tf_column + } + TextArea { + id: ta_column + } + SpinBox { + id: sp_column + } + } + + Frame { + id: frame + + Column { + TextInput { + id: ti_frame + } + TextEdit { + id: te_frame + } + TextField { + id: tf_frame + } + TextArea { + id: ta_frame + } + SpinBox { + id: sp_frame + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/activefocusontab.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/activefocusontab.qml new file mode 100644 index 00000000000..07d783acee4 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/activefocusontab.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + title: "Test Application Window" + width: 100 + height: 100 + Item { + id: main + objectName: "main" + width: 100 + height: 100 + //focus: true + Column { + anchors.fill: parent + id: column + objectName: "column" + Item { + id: sub1 + objectName: "sub1" + activeFocusOnTab: true + Accessible.role: Accessible.Table + width: 100 + height: 50 + Rectangle { + anchors.fill: parent + color: parent.activeFocus ? "red" : "black" + } + } + Item { + id: sub2 + objectName: "sub2" + activeFocusOnTab: true + Accessible.role: Accessible.Table + width: 100 + height: 50 + Rectangle { + anchors.fill: parent + color: parent.activeFocus ? "red" : "black" + } + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/attachedProperties.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/attachedProperties.qml new file mode 100644 index 00000000000..d241d995f29 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/attachedProperties.qml @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +ApplicationWindow { + property alias childControl: childControl + property alias childItem: childItem + property alias childObject: childObject + + Control { + id: childControl + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusControl: ApplicationWindow.activeFocusControl + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + } + + Item { + id: childItem + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusControl: ApplicationWindow.activeFocusControl + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + } + + QtObject { + id: childObject + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusControl: ApplicationWindow.activeFocusControl + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + } + + property alias childWindow: childWindow + property alias childWindowControl: childWindowControl + property alias childWindowItem: childWindowItem + property alias childWindowObject: childWindowObject + + Window { + id: childWindow + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusControl: ApplicationWindow.activeFocusControl + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + + Control { + id: childWindowControl + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusControl: ApplicationWindow.activeFocusControl + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + } + + Item { + id: childWindowItem + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusControl: ApplicationWindow.activeFocusControl + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + } + + QtObject { + id: childWindowObject + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusControl: ApplicationWindow.activeFocusControl + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + } + } + + property alias childAppWindow: childAppWindow + property alias childAppWindowControl: childAppWindowControl + property alias childAppWindowItem: childAppWindowItem + property alias childAppWindowObject: childAppWindowObject + + ApplicationWindow { + id: childAppWindow + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusControl: ApplicationWindow.activeFocusControl + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + + Control { + id: childAppWindowControl + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusControl: ApplicationWindow.activeFocusControl + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + } + + Item { + id: childAppWindowItem + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusControl: ApplicationWindow.activeFocusControl + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + } + + QtObject { + id: childAppWindowObject + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusControl: ApplicationWindow.activeFocusControl + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + } + } +} diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/basicapplicationwindow.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/basicapplicationwindow.qml new file mode 100644 index 00000000000..738022e9e8e --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/basicapplicationwindow.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + title: "Test Application Window" +} diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/clearfocusondestruction.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/clearfocusondestruction.qml new file mode 100644 index 00000000000..bf8f61b756b --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/clearfocusondestruction.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtGraphicalEffects + +ApplicationWindow { + width: 200 + height: 200 + visible: true + + property alias textfield: textfield + + /* + * The code below is the simplest way we can trigger that the signal + * activeFocusItemChanged() is emitted during destruction of the + * ApplicationWindow. This caused a crash in QQuickApplicationWindow. + */ + FastBlur { + id: fastBlur + anchors.fill: parent + radius: 30 + source: ShaderEffectSource { + id: effectsource + sourceItem: textfield + sourceRect: Qt.rect( 0, 0, fastBlur.width, fastBlur.height ) + } + } + + TextField { + id: textfield + anchors.bottom: parent.bottom + focus: true + } +} diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/defaultFocus.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/defaultFocus.qml new file mode 100644 index 00000000000..4651c2fc789 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/defaultFocus.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + visible: true + width: 200 + height: 200 + + property bool receivedKeyPress: false + + Item { + objectName: "item" + focus: true + anchors.fill: parent + + Keys.onLeftPressed: receivedKeyPress = true + } +} + diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/fill.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/fill.qml new file mode 100644 index 00000000000..082e2409cf4 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/fill.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias stackView: stackView + property alias nextItem: nextItem + + function pushNextItem() { + stackView.push(nextItem, StackView.Immediate); + } + + Rectangle { + id: nextItem + color: "blue" + visible: false + } + + StackView { + id: stackView + anchors.fill: parent + + initialItem: Rectangle { + color: "red" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/focusAfterPopupClosed.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/focusAfterPopupClosed.qml new file mode 100644 index 00000000000..ca8da3c23bd --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/focusAfterPopupClosed.qml @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 200 + height: 200 + visible: true + + signal focusScopeKeyPressed + signal focusPopupKeyPressed + + property alias fileMenu: fileMenu + property alias toolButton: toolButton + property alias focusScope: focusScope + property alias focusPopup: focusPopup + + header: ToolBar { + ToolButton { + id: toolButton + text: qsTr("File") + onClicked: fileMenu.open() + focusPolicy: Qt.TabFocus + + Menu { + id: fileMenu + y: parent.height + + MenuItem { + text: qsTr("New") + } + MenuItem { + text: qsTr("Open") + } + MenuItem { + text: qsTr("Close") + } + } + } + } + + FocusScope { + id: focusScope + focus: true + anchors.fill: parent + + Keys.onSpacePressed: focusScopeKeyPressed() + } + + Popup { + id: focusPopup + focus: true + width: parent.width + height: parent.height + + Item { + focus: true + Keys.onSpacePressed: focusPopupKeyPressed() + } + } +} + diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/font.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/font.qml new file mode 100644 index 00000000000..f0abbb9a1e1 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/font.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T + +ApplicationWindow { + objectName: "appWin" + width: 400 + height: 400 + + property alias mainItem: mainItem + + font.family: "Arial" + + T.Control { + id: mainItem + objectName: "mainItem" + anchors.fill: parent + property alias item_2: _item_2; + property alias item_3: _item_3; + property alias item_4: _item_4; + property alias item_5: _item_5; + property alias item_6: _item_6; + T.Control { + id: _item_2 + objectName: "_item_2" + T.Control { + id: _item_3 + objectName: "_item_3" + } + } + T.TextArea { + id: _item_4 + objectName: "_item_4" + text: "Text Area" + } + T.TextField { + id: _item_5 + objectName: "_item_5" + text: "Text Field" + } + T.Label { + id: _item_6 + objectName: "_item_6" + text: "Label" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/layout.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/layout.qml new file mode 100644 index 00000000000..6d4f37946e6 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/layout.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 200 + height: 200 + visible: true + + menuBar: MenuBar { } + header: ToolBar { } + footer: ToolBar { } +} diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/layoutLayout.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/layoutLayout.qml new file mode 100644 index 00000000000..670306fa41d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/layoutLayout.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + width: 200 + height: 200 + visible: true + + header: RowLayout { + Rectangle { color: "red"; implicitWidth: 20; implicitHeight: 20; Layout.fillWidth: true} + } + footer: ColumnLayout { + Rectangle { color: "green"; implicitWidth: 20; implicitHeight: 20; Layout.fillWidth: true} + } +} diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/locale.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/locale.qml new file mode 100644 index 00000000000..243ce44089f --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/locale.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T + +ApplicationWindow { + objectName: "appWin" + width: 400 + height: 400 + + property alias mainItem: mainItem + + T.Control { + id: mainItem + objectName: "mainItem" + anchors.fill: parent + property alias item_2: _item_2; + property alias item_3: _item_3; + T.Control { + id: _item_2 + objectName: "_item_2" + T.Control { + id: _item_3 + objectName: "_item_3" + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/data/opacity.qml b/tests/auto/quickcontrols2/qquickapplicationwindow/data/opacity.qml new file mode 100644 index 00000000000..d32725223ef --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/data/opacity.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + title: "Test Application Window" + width: 300 + height: 300 + opacity: 0.5 + + property bool testActive: active +} diff --git a/tests/auto/quickcontrols2/qquickapplicationwindow/tst_qquickapplicationwindow.cpp b/tests/auto/quickcontrols2/qquickapplicationwindow/tst_qquickapplicationwindow.cpp new file mode 100644 index 00000000000..c6a5d1dca95 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickapplicationwindow/tst_qquickapplicationwindow.cpp @@ -0,0 +1,968 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QtCore/qoperatingsystemversion.h> +#include <QtTest/QSignalSpy> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlcontext.h> +#include <QtQuick/qquickview.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickoverlay_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquicklabel_p.h> +#include <QtQuickTemplates2/private/qquickmenu_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p.h> +#include <QtQuickTemplates2/private/qquicktextarea_p.h> +#include <QtQuickTemplates2/private/qquicktextfield_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p_p.h> +#include <QtQuickControls2/qquickstyle.h> + +using namespace QQuickVisualTestUtils; + +class tst_QQuickApplicationWindow : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_QQuickApplicationWindow(); + +private slots: + void qmlCreation(); + void activeFocusOnTab1(); + void activeFocusOnTab2(); + void defaultFocus(); + void implicitFill(); + void attachedProperties(); + void font(); + void defaultFont(); + void locale(); + void activeFocusControl_data(); + void activeFocusControl(); + void focusAfterPopupClosed(); + void clearFocusOnDestruction(); + void layout(); + void layoutLayout(); + void componentComplete(); + void opacity(); +}; + +tst_QQuickApplicationWindow::tst_QQuickApplicationWindow() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ + QQuickStyle::setStyle("Basic"); +} + +void tst_QQuickApplicationWindow::qmlCreation() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("basicapplicationwindow.qml")); + QObject* created = component.create(); + QScopedPointer<QObject> cleanup(created); + QVERIFY(created); + + QQuickWindow* window = qobject_cast<QQuickWindow*>(created); + QVERIFY(window); + QVERIFY(!window->isVisible()); + + QCOMPARE(created->property("title"), QVariant("Test Application Window")); + + QQuickItem* statusBar = qvariant_cast<QQuickItem*>(created->property("statusBar")); + QVERIFY(!statusBar); + + QQuickItem* header = qvariant_cast<QQuickItem*>(created->property("header")); + QVERIFY(!header); + + QQuickItem* footer = qvariant_cast<QQuickItem*>(created->property("footer")); + QVERIFY(!footer); +} + +void tst_QQuickApplicationWindow::activeFocusOnTab1() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("activefocusontab.qml")); + QObject* created = component.create(); + QScopedPointer<QObject> cleanup(created); + QVERIFY(created); + + QQuickWindow* window = qobject_cast<QQuickWindow*>(created); + QVERIFY(window); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickItem* contentItem = window->contentItem(); + QVERIFY(contentItem); + QVERIFY(contentItem->hasActiveFocus()); + + QQuickItem* item = findItem<QQuickItem>(window->contentItem(), "sub1"); + QVERIFY(item); + QVERIFY(!item->hasActiveFocus()); + + // Tab: contentItem->sub1 + { + QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->contentItem(), "sub1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + } + + // Tab: sub1->sub2 + { + QKeyEvent key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->contentItem(), "sub2"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + } + + // Tab: sub2->sub1 + { + QKeyEvent key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->contentItem(), "sub1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + } +} + +void tst_QQuickApplicationWindow::activeFocusOnTab2() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("activefocusontab.qml")); + QObject* created = component.create(); + QScopedPointer<QObject> cleanup(created); + QVERIFY(created); + + QQuickWindow* window = qobject_cast<QQuickWindow*>(created); + QVERIFY(window); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickItem* contentItem = window->contentItem(); + QVERIFY(contentItem); + QVERIFY(contentItem->hasActiveFocus()); + + QQuickItem* item = findItem<QQuickItem>(window->contentItem(), "sub2"); + QVERIFY(item); + QVERIFY(!item->hasActiveFocus()); + + // BackTab: contentItem->sub2 + { + QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->contentItem(), "sub2"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + } + + // BackTab: sub2->sub1 + { + QKeyEvent key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->contentItem(), "sub1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + } + + // BackTab: sub1->sub2 + { + QKeyEvent key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1); + QGuiApplication::sendEvent(window, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QQuickItem>(window->contentItem(), "sub2"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + } +} + +void tst_QQuickApplicationWindow::defaultFocus() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("defaultFocus.qml")); + QObject* created = component.create(); + QScopedPointer<QObject> cleanup(created); + Q_UNUSED(cleanup); + QVERIFY(created); + + QQuickWindow* window = qobject_cast<QQuickWindow*>(created); + QVERIFY(window); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickItem* contentItem = window->contentItem(); + QVERIFY(contentItem); + QVERIFY(contentItem->hasActiveFocus()); + + // A single item in an ApplicationWindow with focus: true should receive focus. + QQuickItem* item = findItem<QQuickItem>(window->contentItem(), "item"); + QVERIFY(item); + QVERIFY(item->hasFocus()); + QVERIFY(item->hasActiveFocus()); +} + +static QSizeF getExpectedElementSize() +{ +#ifndef Q_OS_ANDROID + // These values are taken from the QML file. + return QSizeF(400.0, 400.0); +#else + // On Android we have to query screen parameters at runtime, because on + // Android the Quick element will take the whole screen size. + const QSize size = QGuiApplication::primaryScreen()->availableSize(); + return QSizeF(size); +#endif +} + +void tst_QQuickApplicationWindow::implicitFill() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("fill.qml")); + QObject* created = component.create(); + QScopedPointer<QObject> cleanup(created); + QVERIFY(created); + + QQuickWindow* window = qobject_cast<QQuickWindow*>(created); + QVERIFY(window); + QVERIFY(!window->isVisible()); + QCOMPARE(window->width(), 400); + QCOMPARE(window->height(), 400); + + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + const QSizeF expectedSize = getExpectedElementSize(); + + QQuickItem *stackView = window->property("stackView").value<QQuickItem*>(); + QVERIFY(stackView); + QCOMPARE(stackView->width(), expectedSize.width()); + QCOMPARE(stackView->height(), expectedSize.height()); + + QQuickItem *nextItem = window->property("nextItem").value<QQuickItem*>(); + QVERIFY(nextItem); + + QVERIFY(QMetaObject::invokeMethod(window, "pushNextItem")); + QCOMPARE(nextItem->width(), expectedSize.width()); + QCOMPARE(nextItem->height(), expectedSize.height()); +} + +void tst_QQuickApplicationWindow::attachedProperties() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("attachedProperties.qml")); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(object.data()); + QVERIFY(window); + + QQuickItem *childControl = object->property("childControl").value<QQuickItem *>(); + QVERIFY(childControl); + QCOMPARE(childControl->property("attached_window").value<QQuickApplicationWindow *>(), window); + QCOMPARE(childControl->property("attached_contentItem").value<QQuickItem *>(), window->contentItem()); + QCOMPARE(childControl->property("attached_activeFocusControl").value<QQuickItem *>(), window->activeFocusControl()); + QCOMPARE(childControl->property("attached_header").value<QQuickItem *>(), window->header()); + QCOMPARE(childControl->property("attached_footer").value<QQuickItem *>(), window->footer()); + + QQuickItem *childItem = object->property("childItem").value<QQuickItem *>(); + QVERIFY(childItem); + QCOMPARE(childItem->property("attached_window").value<QQuickApplicationWindow *>(), window); + QCOMPARE(childItem->property("attached_contentItem").value<QQuickItem *>(), window->contentItem()); + QCOMPARE(childItem->property("attached_activeFocusControl").value<QQuickItem *>(), window->activeFocusControl()); + QCOMPARE(childItem->property("attached_header").value<QQuickItem *>(), window->header()); + QCOMPARE(childItem->property("attached_footer").value<QQuickItem *>(), window->footer()); + + QObject *childObject = object->property("childObject").value<QObject *>(); + QVERIFY(childObject); + QVERIFY(!childObject->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childObject->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childObject->property("attached_activeFocusControl").value<QQuickItem *>()); + QVERIFY(!childObject->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childObject->property("attached_footer").value<QQuickItem *>()); + + QQuickWindow *childWindow = object->property("childWindow").value<QQuickWindow *>(); + QVERIFY(childWindow); + QVERIFY(!childWindow->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childWindow->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childWindow->property("attached_activeFocusControl").value<QQuickItem *>()); + QVERIFY(!childWindow->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childWindow->property("attached_footer").value<QQuickItem *>()); + + QQuickItem *childWindowControl = object->property("childWindowControl").value<QQuickItem *>(); + QVERIFY(childWindowControl); + QVERIFY(!childWindowControl->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childWindowControl->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childWindowControl->property("attached_activeFocusControl").value<QQuickItem *>()); + QVERIFY(!childWindowControl->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childWindowControl->property("attached_footer").value<QQuickItem *>()); + + QQuickItem *childWindowItem = object->property("childWindowItem").value<QQuickItem *>(); + QVERIFY(childWindowItem); + QVERIFY(!childWindowItem->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childWindowItem->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childWindowItem->property("attached_activeFocusControl").value<QQuickItem *>()); + QVERIFY(!childWindowItem->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childWindowItem->property("attached_footer").value<QQuickItem *>()); + + QObject *childWindowObject = object->property("childWindowObject").value<QObject *>(); + QVERIFY(childWindowObject); + QVERIFY(!childWindowObject->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childWindowObject->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childWindowObject->property("attached_activeFocusControl").value<QQuickItem *>()); + QVERIFY(!childWindowObject->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childWindowObject->property("attached_footer").value<QQuickItem *>()); + + QQuickApplicationWindow *childAppWindow = object->property("childAppWindow").value<QQuickApplicationWindow *>(); + QVERIFY(childAppWindow); + QVERIFY(!childAppWindow->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childAppWindow->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childAppWindow->property("attached_activeFocusControl").value<QQuickItem *>()); + QVERIFY(!childAppWindow->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childAppWindow->property("attached_footer").value<QQuickItem *>()); + + QQuickItem *childAppWindowControl = object->property("childAppWindowControl").value<QQuickItem *>(); + QVERIFY(childAppWindowControl); + QCOMPARE(childAppWindowControl->property("attached_window").value<QQuickApplicationWindow *>(), childAppWindow); + QCOMPARE(childAppWindowControl->property("attached_contentItem").value<QQuickItem *>(), childAppWindow->contentItem()); + QCOMPARE(childAppWindowControl->property("attached_activeFocusControl").value<QQuickItem *>(), childAppWindow->activeFocusControl()); + QCOMPARE(childAppWindowControl->property("attached_header").value<QQuickItem *>(), childAppWindow->header()); + QCOMPARE(childAppWindowControl->property("attached_footer").value<QQuickItem *>(), childAppWindow->footer()); + + QQuickItem *childAppWindowItem = object->property("childAppWindowItem").value<QQuickItem *>(); + QVERIFY(childAppWindowItem); + QCOMPARE(childAppWindowItem->property("attached_window").value<QQuickApplicationWindow *>(), childAppWindow); + QCOMPARE(childAppWindowItem->property("attached_contentItem").value<QQuickItem *>(), childAppWindow->contentItem()); + QCOMPARE(childAppWindowItem->property("attached_activeFocusControl").value<QQuickItem *>(), childAppWindow->activeFocusControl()); + QCOMPARE(childAppWindowItem->property("attached_header").value<QQuickItem *>(), childAppWindow->header()); + QCOMPARE(childAppWindowItem->property("attached_footer").value<QQuickItem *>(), childAppWindow->footer()); + + QObject *childAppWindowObject = object->property("childAppWindowObject").value<QObject *>(); + QVERIFY(childAppWindowObject); + QVERIFY(!childAppWindowObject->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childAppWindowObject->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childAppWindowObject->property("attached_activeFocusControl").value<QQuickItem *>()); + QVERIFY(!childAppWindowObject->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childAppWindowObject->property("attached_footer").value<QQuickItem *>()); + + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QVERIFY(!childControl->hasActiveFocus()); + childControl->forceActiveFocus(); + QTRY_VERIFY(childControl->hasActiveFocus()); + QCOMPARE(window->activeFocusItem(), childControl); + QCOMPARE(childControl->property("attached_activeFocusControl").value<QQuickItem *>(), childControl); + + QQuickItem *header = new QQuickItem; + window->setHeader(header); + QCOMPARE(window->header(), header); + QCOMPARE(childControl->property("attached_header").value<QQuickItem *>(), header); + + QQuickItem *footer = new QQuickItem; + window->setFooter(footer); + QCOMPARE(window->footer(), footer); + QCOMPARE(childControl->property("attached_footer").value<QQuickItem *>(), footer); + + childAppWindow->show(); + childAppWindow->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(childAppWindow)); + + QVERIFY(!childAppWindowControl->hasActiveFocus()); + childAppWindowControl->forceActiveFocus(); + QTRY_VERIFY(childAppWindowControl->hasActiveFocus()); + QCOMPARE(childAppWindow->activeFocusItem(), childAppWindowControl); + QCOMPARE(childAppWindowControl->property("attached_activeFocusControl").value<QQuickItem *>(), childAppWindowControl); + + childControl->setParentItem(childAppWindow->contentItem()); + QCOMPARE(childControl->window(), childAppWindow); + QCOMPARE(childControl->property("attached_window").value<QQuickApplicationWindow *>(), childAppWindow); + QCOMPARE(childControl->property("attached_contentItem").value<QQuickItem *>(), childAppWindow->contentItem()); + QCOMPARE(childControl->property("attached_activeFocusControl").value<QQuickItem *>(), childAppWindowControl); + QCOMPARE(childControl->property("attached_header").value<QQuickItem *>(), childAppWindow->header()); + QCOMPARE(childControl->property("attached_footer").value<QQuickItem *>(), childAppWindow->footer()); + + childItem->setParentItem(childAppWindow->contentItem()); + QCOMPARE(childItem->window(), childAppWindow); + QCOMPARE(childItem->property("attached_window").value<QQuickApplicationWindow *>(), childAppWindow); + QCOMPARE(childItem->property("attached_contentItem").value<QQuickItem *>(), childAppWindow->contentItem()); + QCOMPARE(childItem->property("attached_activeFocusControl").value<QQuickItem *>(), childAppWindowControl); + QCOMPARE(childItem->property("attached_header").value<QQuickItem *>(), childAppWindow->header()); + QCOMPARE(childItem->property("attached_footer").value<QQuickItem *>(), childAppWindow->footer()); + + childControl->setParentItem(nullptr); + QVERIFY(!childControl->window()); + QVERIFY(!childControl->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childControl->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childControl->property("attached_activeFocusControl").value<QQuickItem *>()); + QVERIFY(!childControl->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childControl->property("attached_footer").value<QQuickItem *>()); + + childItem->setParentItem(nullptr); + QVERIFY(!childItem->window()); + QVERIFY(!childItem->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childItem->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childItem->property("attached_activeFocusControl").value<QQuickItem *>()); + QVERIFY(!childItem->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childItem->property("attached_footer").value<QQuickItem *>()); + childAppWindow->close(); + qApp->processEvents(); + + childWindow->show(); + childWindow->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(childWindow)); + + QVERIFY(!childWindowControl->hasActiveFocus()); + childWindowControl->forceActiveFocus(); + QTRY_VERIFY(childWindowControl->hasActiveFocus()); + QCOMPARE(childWindow->activeFocusItem(), childWindowControl); + QCOMPARE(childWindowControl->property("attached_activeFocusControl").value<QQuickItem *>(), childWindowControl); + + childControl->setParentItem(childWindow->contentItem()); + QCOMPARE(childControl->window(), childWindow); + QVERIFY(!childControl->property("attached_window").value<QQuickWindow *>()); + QCOMPARE(childControl->property("attached_activeFocusControl").value<QQuickItem *>(), childWindowControl); + QVERIFY(!childControl->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childControl->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childControl->property("attached_footer").value<QQuickItem *>()); + + childItem->setParentItem(childWindow->contentItem()); + QCOMPARE(childItem->window(), childWindow); + QVERIFY(!childControl->property("attached_window").value<QQuickWindow *>()); + QCOMPARE(childControl->property("attached_activeFocusControl").value<QQuickItem *>(), childWindowControl); + QVERIFY(!childControl->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childControl->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childControl->property("attached_footer").value<QQuickItem *>()); + + childControl->setParentItem(nullptr); + QVERIFY(!childControl->window()); + QVERIFY(!childControl->property("attached_window").value<QQuickWindow *>()); + QVERIFY(!childControl->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childControl->property("attached_activeFocusControl").value<QQuickItem *>()); + QVERIFY(!childControl->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childControl->property("attached_footer").value<QQuickItem *>()); + + childItem->setParentItem(nullptr); + QVERIFY(!childItem->window()); + QVERIFY(!childItem->property("attached_window").value<QQuickWindow *>()); + QVERIFY(!childItem->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childItem->property("attached_activeFocusControl").value<QQuickItem *>()); + QVERIFY(!childItem->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childItem->property("attached_footer").value<QQuickItem *>()); + childWindow->close(); +} + +void tst_QQuickApplicationWindow::font() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("font.qml")); + QObject* created = component.create(); + QScopedPointer<QObject> cleanup(created); + QVERIFY(created); + + QQuickApplicationWindow* window = qobject_cast<QQuickApplicationWindow*>(created); + QVERIFY(window); + QVERIFY(!window->isVisible()); + QCOMPARE(window->width(), 400); + QCOMPARE(window->height(), 400); + + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QFont font = window->font(); + + const QSizeF expectedSize = getExpectedElementSize(); + + QQuickControl *mainItem = window->property("mainItem").value<QQuickControl*>(); + QVERIFY(mainItem); + QCOMPARE(mainItem->width(), expectedSize.width()); + QCOMPARE(mainItem->height(), expectedSize.height()); + QCOMPARE(mainItem->font(), font); + + QQuickControl *item2 = mainItem->property("item_2").value<QQuickControl*>(); + QVERIFY(item2); + QQuickControl *item3 = mainItem->property("item_3").value<QQuickControl*>(); + QVERIFY(item3); + QQuickTextArea *item4 = mainItem->property("item_4").value<QQuickTextArea*>(); + QVERIFY(item4); + QQuickTextField *item5 = mainItem->property("item_5").value<QQuickTextField*>(); + QVERIFY(item5); + QQuickLabel *item6 = mainItem->property("item_6").value<QQuickLabel*>(); + QVERIFY(item6); + + QCOMPARE(item2->font(), font); + QCOMPARE(item3->font(), font); + QCOMPARE(item4->font(), font); + QCOMPARE(item5->font(), font); + QCOMPARE(item6->font(), font); + + int pointSize = font.pointSize(); + font.setPixelSize(pointSize + 5); + window->setFont(font); + + QCOMPARE(window->font(), font); + QCOMPARE(mainItem->font(), font); + QCOMPARE(item2->font(), font); + QCOMPARE(item3->font(), font); + QCOMPARE(item4->font(), font); + QCOMPARE(item5->font(), font); + QCOMPARE(item6->font(), font); +} + +class TestTheme : public QQuickTheme +{ +public: + TestTheme() + { + setFont(System, QFont("Courier")); + } +}; + +void tst_QQuickApplicationWindow::defaultFont() +{ + QQuickThemePrivate::instance.reset(new TestTheme); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import QtQuick.Controls; ApplicationWindow { }", QUrl()); + + QScopedPointer<QQuickApplicationWindow> window; + window.reset(static_cast<QQuickApplicationWindow *>(component.create())); + QVERIFY(!window.isNull()); + QCOMPARE(window->font(), QQuickTheme::font(QQuickTheme::System)); +} + +void tst_QQuickApplicationWindow::locale() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("locale.qml")); + QObject* created = component.create(); + QScopedPointer<QObject> cleanup(created); + QVERIFY(created); + + QQuickApplicationWindow* window = qobject_cast<QQuickApplicationWindow*>(created); + QVERIFY(window); + QVERIFY(!window->isVisible()); + QCOMPARE(window->width(), 400); + QCOMPARE(window->height(), 400); + + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QLocale l = window->locale(); + + const QSizeF expectedSize = getExpectedElementSize(); + + QQuickControl *mainItem = window->property("mainItem").value<QQuickControl*>(); + QVERIFY(mainItem); + QCOMPARE(mainItem->width(), expectedSize.width()); + QCOMPARE(mainItem->height(), expectedSize.height()); + QCOMPARE(mainItem->locale(), l); + + QQuickControl *item2 = mainItem->property("item_2").value<QQuickControl*>(); + QVERIFY(item2); + QQuickControl *item3 = mainItem->property("item_3").value<QQuickControl*>(); + QVERIFY(item3); + + QCOMPARE(item2->locale(), l); + QCOMPARE(item3->locale(), l); + + l = QLocale("en_US"); + window->setLocale(l); + + QCOMPARE(window->locale(), l); + QCOMPARE(mainItem->locale(), l); + QCOMPARE(item2->locale(), l); + QCOMPARE(item3->locale(), l); + + l = QLocale("ar_EG"); + window->setLocale(l); + + QCOMPARE(window->locale(), l); + QCOMPARE(mainItem->locale(), l); + QCOMPARE(item2->locale(), l); + QCOMPARE(item3->locale(), l); +} + +void tst_QQuickApplicationWindow::activeFocusControl_data() +{ + QTest::addColumn<QByteArray>("containerName"); + QTest::addColumn<QByteArray>("activeFocusItemName"); + QTest::addColumn<QByteArray>("activeFocusControlName"); + + QTest::newRow("Column:TextInput") << QByteArray("container_column") << QByteArray("textInput_column") << QByteArray(); + QTest::newRow("Column:TextEdit") << QByteArray("container_column") << QByteArray("textEdit_column") << QByteArray(); + QTest::newRow("Column:TextField") << QByteArray("container_column") << QByteArray("textField_column") << QByteArray("textField_column"); + QTest::newRow("Column:TextArea") << QByteArray("container_column") << QByteArray("textArea_column") << QByteArray("textArea_column"); + QTest::newRow("Column:SpinBox") << QByteArray("container_column") << QByteArray("spinContent_column") << QByteArray("spinBox_column"); + + QTest::newRow("Frame:TextInput") << QByteArray("container_frame") << QByteArray("textInput_frame") << QByteArray("container_frame"); + QTest::newRow("Frame:TextEdit") << QByteArray("container_frame") << QByteArray("textEdit_frame") << QByteArray("container_frame"); + QTest::newRow("Frame:TextField") << QByteArray("container_frame") << QByteArray("textField_frame") << QByteArray("textField_frame"); + QTest::newRow("Frame:TextArea") << QByteArray("container_frame") << QByteArray("textArea_frame") << QByteArray("textArea_frame"); + QTest::newRow("Frame:SpinBox") << QByteArray("container_frame") << QByteArray("spinContent_frame") << QByteArray("spinBox_frame"); +} + +void tst_QQuickApplicationWindow::activeFocusControl() +{ + QFETCH(QByteArray, containerName); + QFETCH(QByteArray, activeFocusItemName); + QFETCH(QByteArray, activeFocusControlName); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("activeFocusControl.qml")); + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + + QQuickApplicationWindow* window = qobject_cast<QQuickApplicationWindow*>(object.data()); + QVERIFY(window); + QVERIFY(!window->isVisible()); + QCOMPARE(window->width(), 400); + QCOMPARE(window->height(), 400); + + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickItem *container = window->property(containerName).value<QQuickItem*>(); + QVERIFY(container); + + QQuickItem *activeFocusItem = window->property(activeFocusItemName).value<QQuickItem*>(); + QVERIFY(activeFocusItem); + activeFocusItem->forceActiveFocus(); + QVERIFY(activeFocusItem->hasActiveFocus()); + QCOMPARE(window->activeFocusItem(), activeFocusItem); + + QQuickItem *activeFocusControl = window->property(activeFocusControlName).value<QQuickItem*>(); + if (activeFocusControlName.isEmpty()) { + QVERIFY(!activeFocusControl); + } else { + QVERIFY(activeFocusControl); + QVERIFY(activeFocusControl->hasActiveFocus()); + } + QCOMPARE(window->activeFocusControl(), activeFocusControl); +} + +void tst_QQuickApplicationWindow::focusAfterPopupClosed() +{ +#ifdef Q_OS_ANDROID + QSKIP("This test crashes in Android emulator because of GLES issues (QTBUG-100991)"); +#endif + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("focusAfterPopupClosed.qml")); + QScopedPointer<QQuickWindow> window(qobject_cast<QQuickWindow*>(component.create())); + QVERIFY(window); + + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + QVERIFY(QGuiApplication::focusWindow() == window.data()); + + QQuickItem* contentItem = window->contentItem(); + QVERIFY(contentItem); + QVERIFY(contentItem->hasActiveFocus()); + + QQuickItem* focusScope = window->property("focusScope").value<QQuickItem*>(); + QVERIFY(focusScope); + QVERIFY(focusScope->hasActiveFocus()); + + QSignalSpy focusScopeSpy(window.data(), SIGNAL(focusScopeKeyPressed())); + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(focusScopeSpy.count(), 1); + + // Open the menu. + QQuickItem* toolButton = window->property("toolButton").value<QQuickItem*>(); + QVERIFY(toolButton); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, + toolButton->mapFromScene(QPointF(toolButton->width() / 2, toolButton->height() / 2)).toPoint()); + QVERIFY(!focusScope->hasActiveFocus()); + + // The FocusScope shouldn't receive any key events while the menu is open. + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(focusScopeSpy.count(), 1); + + // Close the menu. The FocusScope should regain focus. + QTest::keyClick(window.data(), Qt::Key_Escape); + QVERIFY(focusScope->hasActiveFocus()); + + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(focusScopeSpy.count(), 2); + + QQuickPopup *focusPopup = window->property("focusPopup").value<QQuickPopup*>(); + QVERIFY(focusPopup); + QVERIFY(!focusPopup->hasActiveFocus()); + + focusPopup->open(); + QVERIFY(focusPopup->isVisible()); + + QSignalSpy focusPopupSpy(window.data(), SIGNAL(focusPopupKeyPressed())); + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(focusPopupSpy.count(), 1); + + QQuickMenu *fileMenu = window->property("fileMenu").value<QQuickMenu*>(); + QVERIFY(fileMenu); + fileMenu->open(); + QVERIFY(fileMenu->isVisible()); + + // The Popup shouldn't receive any key events while the menu is open. + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(focusPopupSpy.count(), 1); + + // Close the menu. The Popup should regain focus. + QTest::keyClick(window.data(), Qt::Key_Escape); + QVERIFY(focusPopup->hasActiveFocus()); + + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(focusPopupSpy.count(), 2); + + // Close the popup. The FocusScope should regain focus. + QTest::keyClick(window.data(), Qt::Key_Escape); + QVERIFY(focusScope->hasActiveFocus()); + + QTest::keyClick(window.data(), Qt::Key_Space); + QCOMPARE(focusScopeSpy.count(), 3); +} + +void tst_QQuickApplicationWindow::clearFocusOnDestruction() +{ + if (!canImportModule("import QtGraphicalEffects; DropShadow {}")) + QSKIP("Test requires QtGraphicalEffects"); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("clearfocusondestruction.qml")); + QScopedPointer<QQuickWindow> window(qobject_cast<QQuickWindow*>(component.create())); + QVERIFY(window); + + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + QVERIFY(QGuiApplication::focusWindow() == window.data()); + + QQuickItem* contentItem = window->contentItem(); + QVERIFY(contentItem); + QVERIFY(contentItem->hasActiveFocus()); + + QQuickItem* focusScope = window->property("textfield").value<QQuickItem*>(); + QVERIFY(focusScope); + QVERIFY(focusScope->hasActiveFocus()); + + QSignalSpy spy(window.data(), SIGNAL(activeFocusControlChanged())); + // destroy the window, do not crash + window.reset(); + + /* + QQuickWindow::activeFocusItemChanged() is emitted inconsistently and + only for certain use cases. Ideally it should be emitted whenever a + QQuickWindow with a focus item is destroyed, but it doesn't... It might + also be favorable to not emit it for performance reason. + + However, activeFocusControlChanged() is emitted more consistently, which + of course makes it inconsistent with the emission of + activeFocusItemChanged().... + + Therefore, if you have good reasons to change the behavior (and not emit + it) take the test below with a grain of salt. + */ + QCOMPARE(spy.count(), 1); +} + +void tst_QQuickApplicationWindow::layout() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("layout.qml")); + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + + QQuickApplicationWindow* window = qobject_cast<QQuickApplicationWindow*>(object.data()); + QVERIFY(window); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickItem *content = window->contentItem(); + QVERIFY(content); + QQuickItem *menuBar = window->menuBar(); + QVERIFY(menuBar); + QQuickItem *header = window->header(); + QVERIFY(header); + QQuickItem *footer = window->footer(); + QVERIFY(footer); + + QCOMPARE(menuBar->x(), 0.0); + QCOMPARE(menuBar->y(), -menuBar->height() - header->height()); + QCOMPARE(header->width(), qreal(window->width())); + QVERIFY(menuBar->height() > 0); + + QCOMPARE(header->x(), 0.0); + QCOMPARE(header->y(), -header->height()); + QCOMPARE(header->width(), qreal(window->width())); + QVERIFY(header->height() > 0); + + QCOMPARE(footer->x(), 0.0); + QCOMPARE(footer->y(), content->height()); + QCOMPARE(footer->width(), qreal(window->width())); + QVERIFY(footer->height() > 0.0); + + QCOMPARE(content->x(), 0.0); + QCOMPARE(content->y(), menuBar->height() + header->height()); + QCOMPARE(content->width(), qreal(window->width())); + QCOMPARE(content->height(), window->height() - menuBar->height() - header->height() - footer->height()); + + menuBar->setVisible(false); + QCOMPARE(content->x(), 0.0); + QCOMPARE(content->y(), header->height()); + QCOMPARE(content->width(), qreal(window->width())); + QCOMPARE(content->height(), window->height() - header->height() - footer->height()); + + header->setVisible(false); + QCOMPARE(content->x(), 0.0); + QCOMPARE(content->y(), 0.0); + QCOMPARE(content->width(), qreal(window->width())); + QCOMPARE(content->height(), window->height() - footer->height()); + + footer->setVisible(false); + QCOMPARE(content->x(), 0.0); + QCOMPARE(content->y(), 0.0); + QCOMPARE(content->width(), qreal(window->width())); + QCOMPARE(content->height(), qreal(window->height())); +} + +void tst_QQuickApplicationWindow::layoutLayout() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("layoutLayout.qml")); + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + QQuickApplicationWindow* window = qobject_cast<QQuickApplicationWindow*>(object.data()); + QVERIFY(window); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickItem *content = window->contentItem(); + QVERIFY(content); + QQuickItem *header = window->header(); + QVERIFY(header); + QQuickItem *footer = window->footer(); + QVERIFY(footer); + + QQuickItem *headerChild = header->findChild<QQuickItem*>(); + QVERIFY(headerChild); + QCOMPARE(header->x(), 0.0); + QCOMPARE(header->y(), -header->height()); + QCOMPARE(header->width(), qreal(window->width())); + QCOMPARE(headerChild->width(), qreal(window->width())); + QVERIFY(header->height() > 0); + + QQuickItem *footerChild = header->findChild<QQuickItem*>(); + QVERIFY(footerChild); + QCOMPARE(footer->x(), 0.0); + QCOMPARE(footer->y(), content->height()); + QCOMPARE(footer->width(), qreal(window->width())); + QCOMPARE(footerChild->width(), qreal(window->width())); + QVERIFY(footer->height() > 0.0); +} + +class FriendlyApplicationWindow : public QQuickApplicationWindow +{ + friend class tst_QQuickApplicationWindow; +}; + +void tst_QQuickApplicationWindow::componentComplete() +{ + FriendlyApplicationWindow cppWindow; + QVERIFY(cppWindow.isComponentComplete()); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import QtQuick.Controls; ApplicationWindow { }", QUrl()); + + FriendlyApplicationWindow *qmlWindow = static_cast<FriendlyApplicationWindow *>(component.beginCreate(engine.rootContext())); + QVERIFY(qmlWindow); + QVERIFY(!qmlWindow->isComponentComplete()); + + component.completeCreate(); + QVERIFY(qmlWindow->isComponentComplete()); +} + +void tst_QQuickApplicationWindow::opacity() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("opacity.qml")); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(object.data()); + QVERIFY(window); +} + +QTEST_MAIN(tst_QQuickApplicationWindow) + +#include "tst_qquickapplicationwindow.moc" diff --git a/tests/auto/quickcontrols2/qquickcolor/CMakeLists.txt b/tests/auto/quickcontrols2/qquickcolor/CMakeLists.txt new file mode 100644 index 00000000000..2cbbe9eb8b3 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickcolor/CMakeLists.txt @@ -0,0 +1,25 @@ +# Generated from qquickcolor.pro. + +##################################################################### +## tst_qquickcolor Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/tst_*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickcolor + GUI + QMLTEST + SOURCES + tst_qquickcolor.cpp + PUBLIC_LIBRARIES + Qt::Gui + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:qquickcolor.pro:<TRUE>: +# OTHER_FILES = "$$PWD/data/*.qml" +# TEMPLATE = "app" diff --git a/tests/auto/quickcontrols2/qquickcolor/data/tst_color.qml b/tests/auto/quickcontrols2/qquickcolor/data/tst_color.qml new file mode 100644 index 00000000000..cdd07e1481f --- /dev/null +++ b/tests/auto/quickcontrols2/qquickcolor/data/tst_color.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtTest +import QtQuick.Controls +import QtQuick.Controls.impl + +TestCase { + id: testCase + name: "Color" + + function test_transparent() { + compare(Color.transparent("red", 0.2), Qt.rgba(1, 0, 0, 0.2)) + compare(Color.transparent(Qt.rgba(0, 1, 0, 1), 0.2), Qt.rgba(0, 1, 0, 0.2)) + compare(Color.transparent("#0000ff", 0.2), Qt.rgba(0, 0, 1, 0.2)) + } +} diff --git a/tests/auto/quickcontrols2/qquickcolor/tst_qquickcolor.cpp b/tests/auto/quickcontrols2/qquickcolor/tst_qquickcolor.cpp new file mode 100644 index 00000000000..94c60080533 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickcolor/tst_qquickcolor.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTest/quicktest.h> +QUICK_TEST_MAIN(tst_qquickcolor) diff --git a/tests/auto/quickcontrols2/qquickcontrol/CMakeLists.txt b/tests/auto/quickcontrols2/qquickcontrol/CMakeLists.txt new file mode 100644 index 00000000000..e0908697447 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickcontrol/CMakeLists.txt @@ -0,0 +1,48 @@ +# Generated from qquickcontrol.pro. + +##################################################################### +## tst_qquickcontrol Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickcontrol + SOURCES + tst_qquickcontrol.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:qquickcontrol.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickcontrol CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickcontrol CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickcontrol/data/flickable.qml b/tests/auto/quickcontrols2/qquickcontrol/data/flickable.qml new file mode 100644 index 00000000000..0ac723207e1 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickcontrol/data/flickable.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias flickable: flickable + property alias button: button + + Flickable { + id: flickable + width: 300 + height: 400 + pressDelay: 50 + Button { + id: button + text: "This is a test button" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickcontrol/data/fractionalFontSize.qml b/tests/auto/quickcontrols2/qquickcontrol/data/fractionalFontSize.qml new file mode 100644 index 00000000000..a4574e460e8 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickcontrol/data/fractionalFontSize.qml @@ -0,0 +1,18 @@ +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias control: ctrl + + Control { + id: ctrl + contentItem: Text { + font.pointSize: 10.5 + elide: Text.ElideRight + text: "This is some sample text" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickcontrol/data/resizeBackgroundKeepsBindings.qml b/tests/auto/quickcontrols2/qquickcontrol/data/resizeBackgroundKeepsBindings.qml new file mode 100644 index 00000000000..9a6a159990b --- /dev/null +++ b/tests/auto/quickcontrols2/qquickcontrol/data/resizeBackgroundKeepsBindings.qml @@ -0,0 +1,42 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +ApplicationWindow { + width: 640 + height: 80 + visible: true + + Slider { + id: control + value: 0.5 + anchors.fill: parent + + background: Rectangle { + id: background + x: control.leftPadding + y: control.topPadding + control.availableHeight / 2 - height / 2 + implicitHeight: 4 + width: control.availableWidth + height: implicitHeight + radius: 2 + color: "#bdbebf" + + Rectangle { + width: control.visualPosition * parent.width + height: parent.height + color: "#21be2b" + radius: 2 + } + } + + handle: Rectangle { + x: control.leftPadding + control.visualPosition * (control.availableWidth - width) + y: control.topPadding + control.availableHeight / 2 - height / 2 + implicitWidth: 26 + implicitHeight: 26 + radius: 13 + color: control.pressed ? "#f0f0f0" : "#f6f6f6" + border.color: "#bdbebf" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickcontrol/tst_qquickcontrol.cpp b/tests/auto/quickcontrols2/qquickcontrol/tst_qquickcontrol.cpp new file mode 100644 index 00000000000..33314ae5504 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickcontrol/tst_qquickcontrol.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtGui/qpa/qwindowsysteminterface.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTemplates2/private/qquickbutton_p.h> +#include <QtQuickControlsTestUtils/private/qtest_quickcontrols_p.h> +#include <QtQuick/private/qquicktext_p_p.h> + +using namespace QQuickVisualTestUtils; + +class tst_QQuickControl : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_QQuickControl(); + +private slots: + void initTestCase() override; + void flickable(); + void fractionalFontSize(); + void resizeBackgroundKeepsBindings(); + +private: + QScopedPointer<QPointingDevice> touchDevice; +}; + +tst_QQuickControl::tst_QQuickControl() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_QQuickControl::initTestCase() +{ + QQmlDataTest::initTestCase(); + qputenv("QML_NO_TOUCH_COMPRESSION", "1"); + + touchDevice.reset(QTest::createTouchDevice()); +} + +void tst_QQuickControl::flickable() +{ + // Check that when a Button that is inside a Flickable with a pressDelay + // still gets the released and clicked signals sent due to the fact that + // Flickable sends a mouse event for the delay and not a touch event + QQuickApplicationHelper helper(this, QStringLiteral("flickable.qml")); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickButton *button = window->property("button").value<QQuickButton *>(); + QVERIFY(button); + + QSignalSpy buttonPressedSpy(button, SIGNAL(pressed())); + QVERIFY(buttonPressedSpy.isValid()); + + QSignalSpy buttonReleasedSpy(button, SIGNAL(released())); + QVERIFY(buttonReleasedSpy.isValid()); + + QSignalSpy buttonClickedSpy(button, SIGNAL(clicked())); + QVERIFY(buttonClickedSpy.isValid()); + + QTest::touchEvent(window, touchDevice.data()).press(0, QPoint(button->width() / 2, button->height() / 2)); + QTRY_COMPARE(buttonPressedSpy.count(), 1); + QTest::touchEvent(window, touchDevice.data()).release(0, QPoint(button->width() / 2, button->height() / 2)); + QTRY_COMPARE(buttonReleasedSpy.count(), 1); + QTRY_COMPARE(buttonClickedSpy.count(), 1); +} + +void tst_QQuickControl::fractionalFontSize() +{ + QQuickApplicationHelper helper(this, QStringLiteral("fractionalFontSize.qml")); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + const QQuickControl *control = window->property("control").value<QQuickControl *>(); + QVERIFY(control); + QQuickText *contentItem = qobject_cast<QQuickText *>(control->contentItem()); + QVERIFY(contentItem); + + QVERIFY(!contentItem->truncated()); + + QVERIFY2(qFuzzyCompare(contentItem->contentWidth(), + QQuickTextPrivate::get(contentItem)->layout.boundingRect().width()), + "The QQuickText::contentWidth() doesn't match the layout's preferred text width"); +} + +void tst_QQuickControl::resizeBackgroundKeepsBindings() +{ + QTest::ignoreMessage( + QtMsgType::QtInfoMsg, + QRegularExpression("Binding on background is not deferred .*")); + QQuickApplicationHelper helper(this, QStringLiteral("resizeBackgroundKeepsBindings.qml")); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + auto ctxt = qmlContext(window); + QVERIFY(ctxt); + auto background = qobject_cast<QQuickItem *>(ctxt->objectForName("background")); + QVERIFY(background); + QCOMPARE(background->height(), 4); + QVERIFY(background->bindableHeight().hasBinding()); +} + +QTEST_QUICKCONTROLS_MAIN(tst_QQuickControl) + +#include "tst_qquickcontrol.moc" diff --git a/tests/auto/quickcontrols2/qquickdrawer/BLACKLIST b/tests/auto/quickcontrols2/qquickdrawer/BLACKLIST new file mode 100644 index 00000000000..0a440d4ad3c --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/BLACKLIST @@ -0,0 +1,8 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format + +# QTBUG-77946 QTBUG-88138 +[slider] +* + +[position] +opensuse-leap diff --git a/tests/auto/quickcontrols2/qquickdrawer/CMakeLists.txt b/tests/auto/quickcontrols2/qquickdrawer/CMakeLists.txt new file mode 100644 index 00000000000..91ed6a3e500 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/CMakeLists.txt @@ -0,0 +1,48 @@ +# Generated from qquickdrawer.pro. + +##################################################################### +## tst_qquickdrawer Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickdrawer + SOURCES + tst_qquickdrawer.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:qquickdrawer.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickdrawer CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickdrawer CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/applicationwindow-button.qml b/tests/auto/quickcontrols2/qquickdrawer/data/applicationwindow-button.qml new file mode 100644 index 00000000000..a7c70e049bf --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/applicationwindow-button.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias drawer: drawer + + Drawer { + id: drawer + width: 200 + height: 200 + + Button { + text: "Button" + anchors.fill: parent + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/applicationwindow-hover.qml b/tests/auto/quickcontrols2/qquickdrawer/data/applicationwindow-hover.qml new file mode 100644 index 00000000000..8167cf4e37d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/applicationwindow-hover.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + id: root + + property alias drawer: drawer + property alias backgroundButton: backgroundButton + property alias drawerButton: drawerButton + + Button { + id: backgroundButton + text: "Background" + anchors.fill: parent + } + + Drawer { + id: drawer + width: 100 + height: root.height + topPadding: 2 + leftPadding: 2 + rightPadding: 2 + bottomPadding: 2 + + contentItem: Button { + id: drawerButton + text: "Drawer" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/applicationwindow-wheel.qml b/tests/auto/quickcontrols2/qquickdrawer/data/applicationwindow-wheel.qml new file mode 100644 index 00000000000..449fbadb24d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/applicationwindow-wheel.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 400 + height: 400 + + property alias drawer: drawer + property alias drawerSlider: drawerSlider + property alias contentSlider: contentSlider + + Slider { + id: contentSlider + anchors.fill: parent + wheelEnabled: true + } + + Drawer { + id: drawer + edge: Qt.RightEdge + width: window.width * 0.8 + height: window.height + clip: true + contentItem: Slider { + id: drawerSlider + wheelEnabled: true + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/applicationwindow.qml b/tests/auto/quickcontrols2/qquickdrawer/data/applicationwindow.qml new file mode 100644 index 00000000000..3f2ed11897d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/applicationwindow.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias drawer: drawer + + Drawer { + id: drawer + width: 200 + height: 200 + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/dragHandlerInteraction.qml b/tests/auto/quickcontrols2/qquickdrawer/data/dragHandlerInteraction.qml new file mode 100644 index 00000000000..a2774222f5f --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/dragHandlerInteraction.qml @@ -0,0 +1,23 @@ +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: root + property int changedCounter: 0 + + width: 300 + height: 300 + + Drawer { + width: 30 + height: 30 + } + + DragHandler { + target: null + onActiveChanged: { + console.log("active changed") + root.changedCounter++ + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/dragOverModalShadow.qml b/tests/auto/quickcontrols2/qquickdrawer/data/dragOverModalShadow.qml new file mode 100644 index 00000000000..6d2951f7408 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/dragOverModalShadow.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias drawer: drawer + property alias popup: popup + + Drawer { + id: drawer + width: 200 + height: parent.height + dragMargin: parent.width + } + + Popup { + id: popup + modal: true + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: parent.width / 2 + height: parent.height / 2 + + Rectangle { + objectName: "shadow" + parent: popup.background + anchors.fill: parent + anchors.margins: -20 + + z: -1 + opacity: 0.5 + color: "silver" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/flickable.qml b/tests/auto/quickcontrols2/qquickdrawer/data/flickable.qml new file mode 100644 index 00000000000..b3f98d9e582 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/flickable.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias drawer: drawer + property alias flickable: flickable + + Drawer { + id: drawer + width: 300 + height: 400 + + contentItem: ListView { + id: flickable + model: 100 + delegate: ItemDelegate { + width: flickable.width + text: index + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/grabber.qml b/tests/auto/quickcontrols2/qquickdrawer/data/grabber.qml new file mode 100644 index 00000000000..bd1b84aa5b2 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/grabber.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias drawer: drawer + property alias popup: popup + + Drawer { + id: drawer + width: 200 + height: parent.height + } + + Popup { + id: popup + x: 200 + width: 200 + height: parent.height + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/header.qml b/tests/auto/quickcontrols2/qquickdrawer/data/header.qml new file mode 100644 index 00000000000..dfd64ab1bdd --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/header.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias drawer: drawer + property alias button: button + + header: ToolBar { + ToolButton { + id: button + text: "=" + } + } + + Drawer { + id: drawer + width: 200 + height: parent.height + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/itemPartialOverlayModal.qml b/tests/auto/quickcontrols2/qquickdrawer/data/itemPartialOverlayModal.qml new file mode 100644 index 00000000000..23aa4ca3c2a --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/itemPartialOverlayModal.qml @@ -0,0 +1,13 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +Item { + width: 400; height: 400 + + Drawer { + edge: Qt.LeftEdge + height: 200 + width: 200 + modal: true + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/multiTouch.qml b/tests/auto/quickcontrols2/qquickdrawer/data/multiTouch.qml new file mode 100644 index 00000000000..3f11b10a047 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/multiTouch.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 400 + height: 400 + + property alias drawer: drawer + property alias popup: popup + property alias button: button + + Drawer { + id: drawer + width: 200 + height: parent.height + dragMargin: parent.width + } + + Popup { + id: popup + x: 10; y: 10 + width: window.width - 10 + height: window.height - 10 + + Button { + id: button + text: "Button" + anchors.fill: parent + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/multiple.qml b/tests/auto/quickcontrols2/qquickdrawer/data/multiple.qml new file mode 100644 index 00000000000..d4d5fbd60dd --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/multiple.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias leftDrawer: leftDrawer + property alias leftButton: leftButton + + property alias rightDrawer: rightDrawer + property alias rightButton: rightButton + + property alias contentButton: contentButton + + Drawer { + id: leftDrawer + width: 300 + height: 400 + z: 1 + + contentItem: Button { + id: leftButton + text: "Left" + } + } + + Button { + id: contentButton + text: "Content" + anchors.fill: parent + } + + Drawer { + id: rightDrawer + width: 300 + height: 400 + edge: Qt.RightEdge + + contentItem: Button { + id: rightButton + text: "Right" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/reposition.qml b/tests/auto/quickcontrols2/qquickdrawer/data/reposition.qml new file mode 100644 index 00000000000..e3211fab9fd --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/reposition.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 400 + height: 400 + + property alias drawer: drawer + property alias drawer2: drawer2 + + header: Item { implicitHeight: 50 } + footer: Item { implicitHeight: 50 } + + Drawer { + id: drawer + width: parent.width / 2 + implicitHeight: parent.height + } + + Drawer { + id: drawer2 + width: Math.min(window.width, window.height) / 3 * 2 + height: window.height + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/slider.qml b/tests/auto/quickcontrols2/qquickdrawer/data/slider.qml new file mode 100644 index 00000000000..b3db5a7b5b0 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/slider.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias drawer: drawer + property alias slider: slider + + Drawer { + id: drawer + width: 300 + height: 400 + position: 1.0 + visible: true + + Slider { + id: slider + value: 1 + width: parent.width + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/topEdgeScreenEdge.qml b/tests/auto/quickcontrols2/qquickdrawer/data/topEdgeScreenEdge.qml new file mode 100644 index 00000000000..d2aaf486013 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/topEdgeScreenEdge.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 400 + height: 400 + + property alias drawer: drawer + + header: Rectangle { + color: "red" + height: 40 + } + + Drawer { + id: drawer + width: window.width + height: window.height * 0.2 + parent: window.contentItem + edge: Qt.TopEdge + + Label { + anchors.centerIn: parent + text: "a drawer" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/window-button.qml b/tests/auto/quickcontrols2/qquickdrawer/data/window-button.qml new file mode 100644 index 00000000000..02247dd030d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/window-button.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 400 + height: 400 + + property alias drawer: drawer + + Drawer { + id: drawer + width: 200 + height: 200 + + Button { + text: "Button" + anchors.fill: parent + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/window-hover.qml b/tests/auto/quickcontrols2/qquickdrawer/data/window-hover.qml new file mode 100644 index 00000000000..d5eb0e6b7a6 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/window-hover.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 400 + height: 400 + id: root + + property alias drawer: drawer + property alias backgroundButton: backgroundButton + property alias drawerButton: drawerButton + + Button { + id: backgroundButton + text: "Background" + anchors.fill: parent + } + + Drawer { + id: drawer + width: 100 + height: root.height + topPadding: 2 + leftPadding: 2 + rightPadding: 2 + bottomPadding: 2 + + contentItem: Button { + id: drawerButton + text: "Drawer" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/window-wheel.qml b/tests/auto/quickcontrols2/qquickdrawer/data/window-wheel.qml new file mode 100644 index 00000000000..e9c2eb422c1 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/window-wheel.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + id: window + width: 400 + height: 400 + + property alias drawer: drawer + property alias drawerSlider: drawerSlider + property alias contentSlider: contentSlider + + Slider { + id: contentSlider + anchors.fill: parent + wheelEnabled: true + } + + Drawer { + id: drawer + edge: Qt.RightEdge + width: window.width * 0.8 + height: window.height + clip: true + contentItem: Slider { + id: drawerSlider + wheelEnabled: true + } + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/data/window.qml b/tests/auto/quickcontrols2/qquickdrawer/data/window.qml new file mode 100644 index 00000000000..4bd9c9d29c1 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/data/window.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 400 + height: 400 + + property alias drawer: drawer + + Drawer { + id: drawer + width: 200 + height: 200 + } +} diff --git a/tests/auto/quickcontrols2/qquickdrawer/tst_qquickdrawer.cpp b/tests/auto/quickcontrols2/qquickdrawer/tst_qquickdrawer.cpp new file mode 100644 index 00000000000..2c6d50a591f --- /dev/null +++ b/tests/auto/quickcontrols2/qquickdrawer/tst_qquickdrawer.cpp @@ -0,0 +1,1437 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> + +#include <QtGui/qpointingdevice.h> +#include <QtGui/qstylehints.h> +#include <QtGui/qguiapplication.h> +#include <QtGui/qpa/qwindowsysteminterface.h> +#include <QtGui/qpa/qplatformintegration.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qquickflickable_p.h> +#include <QtQuick/qquickview.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickoverlay_p_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p_p.h> +#include <QtQuickTemplates2/private/qquickdrawer_p.h> +#include <QtQuickTemplates2/private/qquickbutton_p.h> +#include <QtQuickTemplates2/private/qquickslider_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> +#include <QtQuickControlsTestUtils/private/qtest_quickcontrols_p.h> + +//using namespace QQuickVisualTestUtils; +using namespace QQuickControlsTestUtils; + +class tst_QQuickDrawer : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_QQuickDrawer(); + +private slots: + void initTestCase() override; + + void defaults(); + void invalidEdge(); + + void visible_data(); + void visible(); + + void state(); + + void position_data(); + void position(); + + void dragMargin_data(); + void dragMargin(); + + void reposition(); + void header(); + + void dragHandlerInteraction(); + + void hover_data(); + void hover(); + + void wheel_data(); + void wheel(); + + void multiple(); + + void touch_data(); + void touch(); + + void multiTouch(); + + void grabber(); + + void interactive_data(); + void interactive(); + + void flickable_data(); + void flickable(); + + void dragOverModalShadow_data(); + void dragOverModalShadow(); + + void nonModal_data(); + void nonModal(); + + void slider_data(); + void slider(); + + void topEdgeScreenEdge(); + + void touchOutsideOverlay(); + +private: + QScopedPointer<QPointingDevice> touchDevice; +}; + + +tst_QQuickDrawer::tst_QQuickDrawer() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_QQuickDrawer::initTestCase() +{ + QQmlDataTest::initTestCase(); + qputenv("QML_NO_TOUCH_COMPRESSION", "1"); + + touchDevice.reset(QTest::createTouchDevice()); +} + +void tst_QQuickDrawer::defaults() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("window.qml")); + + QScopedPointer<QObject> root(component.create()); + QVERIFY2(!root.isNull(), qPrintable(component.errorString())); + + QQuickDrawer *drawer = root->property("drawer").value<QQuickDrawer *>(); + QVERIFY(drawer); + QCOMPARE(drawer->edge(), Qt::LeftEdge); + QCOMPARE(drawer->position(), 0.0); + QCOMPARE(drawer->dragMargin(), qGuiApp->styleHints()->startDragDistance()); +} + +void tst_QQuickDrawer::invalidEdge() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("window.qml")); + + QScopedPointer<QObject> root(component.create()); + QVERIFY2(!root.isNull(), qPrintable(component.errorString())); + + QQuickDrawer *drawer = root->property("drawer").value<QQuickDrawer *>(); + QVERIFY(drawer); + + // Test an invalid value - it should warn and ignore it. + QTest::ignoreMessage(QtWarningMsg, qUtf8Printable(testFileUrl("window.qml").toString() + ":61:5: QML Drawer: invalid edge value - valid values are: Qt.TopEdge, Qt.LeftEdge, Qt.RightEdge, Qt.BottomEdge")); + drawer->setEdge(static_cast<Qt::Edge>(QQuickDrawer::Right)); + QCOMPARE(drawer->edge(), Qt::LeftEdge); +} + +void tst_QQuickDrawer::visible_data() +{ + QTest::addColumn<QString>("source"); + QTest::newRow("Window") << "window.qml"; + QTest::newRow("ApplicationWindow") << "applicationwindow.qml"; +} + +void tst_QQuickDrawer::visible() +{ + QFETCH(QString, source); + QQuickControlsApplicationHelper helper(this, source); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>(); + QVERIFY(drawer); + QQuickItem *popupItem = drawer->popupItem(); + + QCOMPARE(drawer->isVisible(), false); + QCOMPARE(drawer->position(), qreal(0.0)); + + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + QVERIFY(overlay); + QVERIFY(!overlay->childItems().contains(popupItem)); + + drawer->open(); + QVERIFY(drawer->isVisible()); + QVERIFY(overlay->childItems().contains(popupItem)); + QTRY_COMPARE(drawer->position(), qreal(1.0)); + + drawer->close(); + QTRY_VERIFY(!drawer->isVisible()); + QTRY_COMPARE(drawer->position(), qreal(0.0)); + QVERIFY(!overlay->childItems().contains(popupItem)); + + drawer->setVisible(true); + QVERIFY(drawer->isVisible()); + QVERIFY(overlay->childItems().contains(popupItem)); + QTRY_COMPARE(drawer->position(), qreal(1.0)); + + drawer->setVisible(false); + QTRY_VERIFY(!drawer->isVisible()); + QTRY_COMPARE(drawer->position(), qreal(0.0)); + QTRY_VERIFY(!overlay->childItems().contains(popupItem)); +} + +void tst_QQuickDrawer::state() +{ + QQuickControlsApplicationHelper helper(this, "applicationwindow.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>(); + QVERIFY(drawer); + + QCOMPARE(drawer->isVisible(), false); + + QSignalSpy visibleChangedSpy(drawer, SIGNAL(visibleChanged())); + QSignalSpy aboutToShowSpy(drawer, SIGNAL(aboutToShow())); + QSignalSpy aboutToHideSpy(drawer, SIGNAL(aboutToHide())); + QSignalSpy openedSpy(drawer, SIGNAL(opened())); + QSignalSpy closedSpy(drawer, SIGNAL(closed())); + + QVERIFY(visibleChangedSpy.isValid()); + QVERIFY(aboutToShowSpy.isValid()); + QVERIFY(aboutToHideSpy.isValid()); + QVERIFY(openedSpy.isValid()); + QVERIFY(closedSpy.isValid()); + + int visibleChangedCount = 0; + int aboutToShowCount = 0; + int aboutToHideCount = 0; + int openedCount = 0; + int closedCount = 0; + + // open programmatically... + drawer->open(); + QCOMPARE(visibleChangedSpy.count(), ++visibleChangedCount); + QCOMPARE(aboutToShowSpy.count(), ++aboutToShowCount); + QCOMPARE(aboutToHideSpy.count(), aboutToHideCount); + QCOMPARE(openedSpy.count(), openedCount); + QCOMPARE(closedSpy.count(), closedCount); + + // ...and wait until fully open + QVERIFY(openedSpy.wait()); + QCOMPARE(visibleChangedSpy.count(), visibleChangedCount); + QCOMPARE(aboutToShowSpy.count(), aboutToShowCount); + QCOMPARE(aboutToHideSpy.count(), aboutToHideCount); + QCOMPARE(openedSpy.count(), ++openedCount); + QCOMPARE(closedSpy.count(), closedCount); + + // close programmatically... + drawer->close(); + QCOMPARE(visibleChangedSpy.count(), visibleChangedCount); + QCOMPARE(aboutToShowSpy.count(), aboutToShowCount); + QCOMPARE(aboutToHideSpy.count(), ++aboutToHideCount); + QCOMPARE(openedSpy.count(), openedCount); + QCOMPARE(closedSpy.count(), closedCount); + + // ...and wait until fully closed + QVERIFY(closedSpy.wait()); + QCOMPARE(visibleChangedSpy.count(), ++visibleChangedCount); + QCOMPARE(aboutToShowSpy.count(), aboutToShowCount); + QCOMPARE(aboutToHideSpy.count(), aboutToHideCount); + QCOMPARE(openedSpy.count(), openedCount); + QCOMPARE(closedSpy.count(), ++closedCount); + + // open interactively... + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(0, drawer->height() / 2)); + QTest::mouseMove(window, QPoint(drawer->width() * 0.2, drawer->height() / 2), 16); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(drawer->width() * 0.8, drawer->height() / 2), 16); + QCOMPARE(visibleChangedSpy.count(), ++visibleChangedCount); + QCOMPARE(aboutToShowSpy.count(), ++aboutToShowCount); + QCOMPARE(aboutToHideSpy.count(), aboutToHideCount); + QCOMPARE(openedSpy.count(), openedCount); + QCOMPARE(closedSpy.count(), closedCount); + + // ...and wait until fully open + QVERIFY(openedSpy.wait()); + QCOMPARE(visibleChangedSpy.count(), visibleChangedCount); + QCOMPARE(aboutToShowSpy.count(), aboutToShowCount); + QCOMPARE(aboutToHideSpy.count(), aboutToHideCount); + QCOMPARE(openedSpy.count(), ++openedCount); + QCOMPARE(closedSpy.count(), closedCount); + + // close interactively... + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(drawer->width(), drawer->height() / 2)); + QTest::mouseMove(window, QPoint(drawer->width() * 0.8, drawer->height() / 2), 16); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(drawer->width() * 0.2, drawer->height() / 2), 16); + QCOMPARE(visibleChangedSpy.count(), visibleChangedCount); + QCOMPARE(aboutToShowSpy.count(), aboutToShowCount); + QCOMPARE(aboutToHideSpy.count(), ++aboutToHideCount); + QCOMPARE(openedSpy.count(), openedCount); + QCOMPARE(closedSpy.count(), closedCount); + + // ...and wait until fully closed + QVERIFY(closedSpy.wait()); + QCOMPARE(visibleChangedSpy.count(), ++visibleChangedCount); + QCOMPARE(aboutToShowSpy.count(), aboutToShowCount); + QCOMPARE(aboutToHideSpy.count(), aboutToHideCount); + QCOMPARE(openedSpy.count(), openedCount); + QCOMPARE(closedSpy.count(), ++closedCount); +} + +void tst_QQuickDrawer::position_data() +{ + QTest::addColumn<Qt::Edge>("edge"); + QTest::addColumn<QPoint>("press"); + QTest::addColumn<QPoint>("from"); + QTest::addColumn<QPoint>("to"); + QTest::addColumn<qreal>("position"); + + // We need to start swiping exactly from the selected edge, but on Android + // ApplicationWindow will be fullscreen instead of the defined size, so + // we need to extract the edge values from screen geometry. +#ifndef Q_OS_ANDROID + const int rightMargin = 399; + const int bottomMargin = 399; +#else + const QRect screenGeometry = QGuiApplication::primaryScreen()->availableGeometry(); + const int rightMargin = screenGeometry.right(); + const int bottomMargin = screenGeometry.bottom(); +#endif + + QTest::newRow("top") << Qt::TopEdge << QPoint(100, 0) << QPoint(100, 50) << QPoint(100, 150) << qreal(0.5); + QTest::newRow("left") << Qt::LeftEdge << QPoint(0, 100) << QPoint(50, 100) << QPoint(150, 100) << qreal(0.5); + QTest::newRow("right") << Qt::RightEdge << QPoint(rightMargin, 100) + << QPoint(rightMargin - 50, 100) << QPoint(rightMargin - 150, 100) + << qreal(0.5); + QTest::newRow("bottom") << Qt::BottomEdge << QPoint(100, bottomMargin) + << QPoint(100, bottomMargin - 50) << QPoint(150, bottomMargin - 150) + << qreal(0.5); +} + +void tst_QQuickDrawer::position() +{ + QFETCH(Qt::Edge, edge); + QFETCH(QPoint, press); + QFETCH(QPoint, from); + QFETCH(QPoint, to); + QFETCH(qreal, position); + + QQuickControlsApplicationHelper helper(this, QStringLiteral("applicationwindow.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = helper.appWindow->property("drawer").value<QQuickDrawer*>(); + QVERIFY(drawer); + drawer->setEdge(edge); + + // Give it some time (50 ms) before the press to avoid flakiness on OpenSUSE: QTBUG-77946 + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, press, 50); + QTest::mouseMove(window, from); + QTest::mouseMove(window, to); + QCOMPARE(drawer->position(), position); + + // moved half-way open at almost infinite speed => snap to open + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, to); + QTRY_COMPARE(drawer->position(), 1.0); +} + +void tst_QQuickDrawer::dragMargin_data() +{ + QTest::addColumn<Qt::Edge>("edge"); + QTest::addColumn<qreal>("dragMargin"); + QTest::addColumn<qreal>("dragFromLeft"); + QTest::addColumn<qreal>("dragFromRight"); + + QTest::newRow("left:0") << Qt::LeftEdge << qreal(0) << qreal(0) << qreal(0); + QTest::newRow("left:-1") << Qt::LeftEdge << qreal(-1) << qreal(0) << qreal(0); + QTest::newRow("left:startDragDistance") << Qt::LeftEdge << qreal(QGuiApplication::styleHints()->startDragDistance()) << qreal(0.45) << qreal(0); + QTest::newRow("left:startDragDistance*2") << Qt::LeftEdge << qreal(QGuiApplication::styleHints()->startDragDistance() * 2) << qreal(0.45) << qreal(0); + + QTest::newRow("right:0") << Qt::RightEdge << qreal(0) << qreal(0) << qreal(0); + QTest::newRow("right:-1") << Qt::RightEdge << qreal(-1) << qreal(0) << qreal(0); + QTest::newRow("right:startDragDistance") << Qt::RightEdge << qreal(QGuiApplication::styleHints()->startDragDistance()) << qreal(0) << qreal(0.75); + QTest::newRow("right:startDragDistance*2") << Qt::RightEdge << qreal(QGuiApplication::styleHints()->startDragDistance() * 2) << qreal(0) << qreal(0.75); +} + +void tst_QQuickDrawer::dragMargin() +{ + QFETCH(Qt::Edge, edge); + QFETCH(qreal, dragMargin); + QFETCH(qreal, dragFromLeft); + QFETCH(qreal, dragFromRight); + + QQuickControlsApplicationHelper helper(this, QStringLiteral("applicationwindow.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = helper.appWindow->property("drawer").value<QQuickDrawer*>(); + QVERIFY(drawer); + drawer->setEdge(edge); + drawer->setDragMargin(dragMargin); + + const int startDragDistance = qMax(20, QGuiApplication::styleHints()->startDragDistance() + 5) + 1; + + // drag from the left + int leftX = qMax<int>(0, dragMargin); + int leftDistance = startDragDistance + drawer->width() * 0.45; + QVERIFY(leftDistance > QGuiApplication::styleHints()->startDragDistance()); + // Give it some time (50 ms) before the press to avoid flakiness on OpenSUSE: QTBUG-77946 + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(leftX, drawer->height() / 2), 50); + QTest::mouseMove(window, QPoint(leftX + startDragDistance, drawer->height() / 2)); + QTest::mouseMove(window, QPoint(leftX + leftDistance, drawer->height() / 2)); + QCOMPARE(drawer->position(), dragFromLeft); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(leftX + leftDistance, drawer->height() / 2)); + + drawer->close(); + QTRY_COMPARE(drawer->position(), qreal(0.0)); + + // drag from the right + int rightX = qMin<int>(window->width() - 1, window->width() - dragMargin); + int rightDistance = startDragDistance + drawer->width() * 0.75; + QVERIFY(rightDistance > QGuiApplication::styleHints()->startDragDistance()); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(rightX, drawer->height() / 2)); + QTest::mouseMove(window, QPoint(rightX - startDragDistance, drawer->height() / 2)); + QTest::mouseMove(window, QPoint(rightX - rightDistance, drawer->height() / 2)); + QCOMPARE(drawer->position(), dragFromRight); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(rightX - rightDistance, drawer->height() / 2)); +} + +static QRectF geometry(const QQuickItem *item) +{ + return QRectF(item->x(), item->y(), item->width(), item->height()); +} + +void tst_QQuickDrawer::reposition() +{ + QQuickControlsApplicationHelper helper(this, QStringLiteral("reposition.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>(); + QVERIFY(drawer); + QQuickItem *popupItem = drawer->popupItem(); + QVERIFY(popupItem); + + drawer->open(); + QQuickItem *dimmer = QQuickPopupPrivate::get(drawer)->dimmer; + QVERIFY(dimmer); + + QCOMPARE(geometry(dimmer), QRectF(0, 0, window->width(), window->height())); + QTRY_COMPARE(geometry(popupItem), QRectF(0, 0, window->width() / 2., window->height())); + + drawer->setY(100); + QCOMPARE(geometry(dimmer), QRectF(0, 100, window->width(), window->height() - 100)); + QCOMPARE(geometry(popupItem), QRectF(0, 100, window->width() / 2., window->height() - 100)); + + drawer->setHeight(window->height()); + QCOMPARE(geometry(dimmer), QRectF(0, 100, window->width(), window->height())); + QCOMPARE(geometry(popupItem), QRectF(0, 100, window->width() / 2., window->height())); + + drawer->resetHeight(); + QCOMPARE(geometry(dimmer), QRectF(0, 100, window->width(), window->height() - 100)); + QCOMPARE(geometry(popupItem), QRectF(0, 100, window->width() / 2., window->height() - 100)); + + drawer->setParentItem(window->contentItem()); + QCOMPARE(geometry(dimmer), QRectF(0, 150, window->width(), window->height() - 150)); + QCOMPARE(geometry(popupItem), QRectF(0, 150, window->width() / 2., window->height() - 150)); + + drawer->setEdge(Qt::RightEdge); + QCOMPARE(geometry(dimmer), QRectF(0, 150, window->width(), window->height() - 150)); + QTRY_COMPARE(geometry(popupItem), QRectF(window->width() - drawer->width(), 150, window->width() / 2., window->height() - 150)); + + window->setWidth(window->width() + 100); + QTRY_COMPARE(geometry(dimmer), QRectF(0, 150, window->width(), window->height() - 150)); + QTRY_COMPARE(geometry(popupItem), QRectF(window->width() - drawer->width(), 150, window->width() / 2., window->height() - 150)); + + drawer->close(); + QTRY_COMPARE(geometry(popupItem), QRectF(window->width(), 150, window->width() / 2., window->height() - 150)); + + QQuickDrawer *drawer2 = window->property("drawer2").value<QQuickDrawer *>(); + QVERIFY(drawer2); + QQuickItem *popupItem2 = drawer2->popupItem(); + QVERIFY(popupItem2); + + drawer2->open(); + QVERIFY(popupItem2->isVisible()); + QCOMPARE(popupItem2->x(), -drawer2->width()); + QTRY_COMPARE(popupItem2->x(), 0.0); +} + +void tst_QQuickDrawer::header() +{ + QQuickControlsApplicationHelper helper(this, QStringLiteral("header.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickItem *content = window->contentItem(); + QVERIFY(content); + + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + QVERIFY(overlay); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>(); + QVERIFY(drawer); + QQuickItem *popupItem = drawer->popupItem(); + + QQuickButton *button = window->property("button").value<QQuickButton*>(); + QVERIFY(button); + + drawer->open(); + QVERIFY(drawer->isVisible()); + + QCOMPARE(drawer->parentItem(), overlay); + QCOMPARE(drawer->height(), overlay->height()); + QCOMPARE(popupItem->height(), overlay->height()); + + drawer->setParentItem(content); + QCOMPARE(drawer->parentItem(), content); + QCOMPARE(drawer->height(), content->height()); + QCOMPARE(popupItem->height(), content->height()); + + // must be possible to interact with the header when the drawer is below the header + QSignalSpy clickSpy(button, SIGNAL(clicked())); + QVERIFY(clickSpy.isValid()); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(button->x() + button->width() / 2, button->y() + button->height() / 2)); + QCOMPARE(clickSpy.count(), 1); +} + +void tst_QQuickDrawer::dragHandlerInteraction() +{ + QQuickControlsApplicationHelper helper(this, u"dragHandlerInteraction.qml"_qs); + QVERIFY2(helper.ready, helper.failureMessage()); + + auto window = helper.appWindow;; + QVERIFY(window); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + QTest::mousePress(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(250, 250)); + QTest::mouseMove(window, QPoint(100, 100)); + QTest::mouseRelease(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(100, 100)); + QTRY_COMPARE(window->property("changedCounter").toInt(), 2); // became active and inactive +} + +void tst_QQuickDrawer::hover_data() +{ + QTest::addColumn<QString>("source"); + QTest::addColumn<bool>("modal"); + + QTest::newRow("Window:modal") << "window-hover.qml" << true; + QTest::newRow("Window:modeless") << "window-hover.qml" << false; + QTest::newRow("ApplicationWindow:modal") << "applicationwindow-hover.qml" << true; + QTest::newRow("ApplicationWindow:modeless") << "applicationwindow-hover.qml" << false; +} + +void tst_QQuickDrawer::hover() +{ + QFETCH(QString, source); + QFETCH(bool, modal); + + QQuickControlsApplicationHelper helper(this, source); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>(); + QVERIFY(drawer); + drawer->setModal(modal); + + QQuickControl *drawerItem = qobject_cast<QQuickControl *>(drawer->popupItem()); + QVERIFY(drawerItem); + QVERIFY(drawerItem->isHoverEnabled()); + + QQuickButton *backgroundButton = window->property("backgroundButton").value<QQuickButton*>(); + QVERIFY(backgroundButton); + backgroundButton->setHoverEnabled(true); + + QQuickButton *drawerButton = window->property("drawerButton").value<QQuickButton*>(); + QVERIFY(drawerButton); + drawerButton->setHoverEnabled(true); + + QSignalSpy openedSpy(drawer, SIGNAL(opened())); + QVERIFY(openedSpy.isValid()); + drawer->open(); + QVERIFY(openedSpy.count() == 1 || openedSpy.wait()); + + // hover the background button outside the drawer + QTest::mouseMove(window, QPoint(window->width() - 1, window->height() - 1)); + QCOMPARE(backgroundButton->isHovered(), !modal); + QVERIFY(!drawerButton->isHovered()); + QVERIFY(!drawerItem->isHovered()); + + // hover the drawer background + QTest::mouseMove(window, QPoint(1, 1)); + QVERIFY(!backgroundButton->isHovered()); + QVERIFY(!drawerButton->isHovered()); + QVERIFY(drawerItem->isHovered()); + + // hover the button in a drawer + QTest::mouseMove(window, QPoint(2, 2)); + QVERIFY(!backgroundButton->isHovered()); + QVERIFY(drawerButton->isHovered()); + QVERIFY(drawerItem->isHovered()); + + QSignalSpy closedSpy(drawer, SIGNAL(closed())); + QVERIFY(closedSpy.isValid()); + drawer->close(); + QVERIFY(closedSpy.count() == 1 || closedSpy.wait()); + + // hover the background button after closing the drawer + QTest::mouseMove(window, QPoint(window->width() / 2, window->height() / 2)); + QVERIFY(backgroundButton->isHovered()); + QVERIFY(!drawerButton->isHovered()); + QVERIFY(!drawerItem->isHovered()); +} + +void tst_QQuickDrawer::wheel_data() +{ + QTest::addColumn<QString>("source"); + QTest::addColumn<bool>("modal"); + + QTest::newRow("Window:modal") << "window-wheel.qml" << true; + QTest::newRow("Window:modeless") << "window-wheel.qml" << false; + QTest::newRow("ApplicationWindow:modal") << "applicationwindow-wheel.qml" << true; + QTest::newRow("ApplicationWindow:modeless") << "applicationwindow-wheel.qml" << false; +} + +static bool sendWheelEvent(QQuickItem *item, const QPoint &localPos, int degrees) +{ + QQuickWindow *window = item->window(); + QWheelEvent wheelEvent(localPos, item->window()->mapToGlobal(localPos), QPoint(0, 0), + QPoint(0, 8 * degrees), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, + false); + QSpontaneKeyEvent::setSpontaneous(&wheelEvent); + return qGuiApp->notify(window, &wheelEvent); +} + +void tst_QQuickDrawer::wheel() +{ + QFETCH(QString, source); + QFETCH(bool, modal); + + QQuickControlsApplicationHelper helper(this, source); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickSlider *contentSlider = window->property("contentSlider").value<QQuickSlider*>(); + QVERIFY(contentSlider); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>(); + QVERIFY(drawer && drawer->contentItem()); + drawer->setModal(modal); + + QQuickSlider *drawerSlider = window->property("drawerSlider").value<QQuickSlider*>(); + QVERIFY(drawerSlider); + + { + // wheel over the content + qreal oldContentValue = contentSlider->value(); + qreal oldDrawerValue = drawerSlider->value(); + + QVERIFY(sendWheelEvent(contentSlider, QPoint(contentSlider->width() / 2, contentSlider->height() / 2), 15)); + + QVERIFY(!qFuzzyCompare(contentSlider->value(), oldContentValue)); // must have moved + QVERIFY(qFuzzyCompare(drawerSlider->value(), oldDrawerValue)); // must not have moved + } + + QSignalSpy openedSpy(drawer, SIGNAL(opened())); + QVERIFY(openedSpy.isValid()); + drawer->open(); + QVERIFY(openedSpy.count() == 1 || openedSpy.wait()); + + { + // wheel over the drawer content + qreal oldContentValue = contentSlider->value(); + qreal oldDrawerValue = drawerSlider->value(); + + QVERIFY(sendWheelEvent(drawerSlider, QPoint(drawerSlider->width() / 2, drawerSlider->height() / 2), 15)); + + QVERIFY(qFuzzyCompare(contentSlider->value(), oldContentValue)); // must not have moved + QVERIFY(!qFuzzyCompare(drawerSlider->value(), oldDrawerValue)); // must have moved + } + + { + // wheel over the overlay + qreal oldContentValue = contentSlider->value(); + qreal oldDrawerValue = drawerSlider->value(); + + QVERIFY(sendWheelEvent(QQuickOverlay::overlay(window), QPoint(0, 0), 15)); + + if (modal) { + // the content below a modal overlay must not move + QVERIFY(qFuzzyCompare(contentSlider->value(), oldContentValue)); + } else { + // the content below a modeless overlay must move + QVERIFY(!qFuzzyCompare(contentSlider->value(), oldContentValue)); + } + QVERIFY(qFuzzyCompare(drawerSlider->value(), oldDrawerValue)); // must not have moved + } +} + +void tst_QQuickDrawer::multiple() +{ + QQuickControlsApplicationHelper helper(this, QStringLiteral("multiple.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *leftDrawer = window->property("leftDrawer").value<QQuickDrawer*>(); + QVERIFY(leftDrawer); + QQuickButton *leftButton = window->property("leftButton").value<QQuickButton*>(); + QVERIFY(leftButton); + QSignalSpy leftClickSpy(leftButton, SIGNAL(clicked())); + QVERIFY(leftClickSpy.isValid()); + + QQuickDrawer *rightDrawer = window->property("rightDrawer").value<QQuickDrawer*>(); + QVERIFY(rightDrawer); + QQuickButton *rightButton = window->property("rightButton").value<QQuickButton*>(); + QVERIFY(rightButton); + QSignalSpy rightClickSpy(rightButton, SIGNAL(clicked())); + QVERIFY(rightClickSpy.isValid()); + + QQuickButton *contentButton = window->property("contentButton").value<QQuickButton*>(); + QVERIFY(contentButton); + QSignalSpy contentClickSpy(contentButton, SIGNAL(clicked())); + QVERIFY(contentClickSpy.isValid()); + + // no drawers open, click the content + QTest::mouseClick(window, Qt::LeftButton); + QCOMPARE(contentClickSpy.count(), 1); + QCOMPARE(leftClickSpy.count(), 0); + QCOMPARE(rightClickSpy.count(), 0); + + // drag the left drawer open + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(0, window->height() / 2)); + QTest::mouseMove(window, QPoint(leftDrawer->width() / 4, window->height() / 2)); + QTest::mouseMove(window, QPoint(leftDrawer->width() / 4 * 3, window->height() / 2)); + QCOMPARE(leftDrawer->position(), 0.5); + QCOMPARE(rightDrawer->position(), 0.0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(leftDrawer->width() / 2, window->height() / 2)); + QTRY_COMPARE(leftDrawer->position(), 1.0); + QCOMPARE(rightDrawer->position(), 0.0); + + // cannot drag the right drawer while the left drawer is open + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - 1, window->height() / 2)); + QTest::mouseMove(window, QPoint(window->width() - leftDrawer->width() / 2, window->height() / 2)); + QCOMPARE(leftDrawer->position(), 1.0); + QCOMPARE(rightDrawer->position(), 0.0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - leftDrawer->width() / 2, window->height() / 2)); + QCOMPARE(rightDrawer->position(), 0.0); + QCOMPARE(leftDrawer->position(), 1.0); + + // open the right drawer below the left drawer + rightDrawer->open(); + QTRY_COMPARE(rightDrawer->position(), 1.0); + + // click the left drawer's button + QTest::mouseClick(window, Qt::LeftButton); + QCOMPARE(contentClickSpy.count(), 1); + QCOMPARE(leftClickSpy.count(), 1); + QCOMPARE(rightClickSpy.count(), 0); + + // click the left drawer's background (button disabled, don't leak through to the right drawer below) + leftButton->setEnabled(false); + QTest::mouseClick(window, Qt::LeftButton); + QCOMPARE(contentClickSpy.count(), 1); + QCOMPARE(leftClickSpy.count(), 1); + QCOMPARE(rightClickSpy.count(), 0); + leftButton->setEnabled(true); + + // click the overlay of the left drawer (don't leak through to right drawer below) + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - (window->width() - leftDrawer->width()) / 2, window->height() / 2)); + QCOMPARE(contentClickSpy.count(), 1); + QCOMPARE(leftClickSpy.count(), 1); + QCOMPARE(rightClickSpy.count(), 0); + QTRY_VERIFY(!leftDrawer->isVisible()); + + // click the right drawer's button + QTest::mouseClick(window, Qt::LeftButton); + QCOMPARE(contentClickSpy.count(), 1); + QCOMPARE(leftClickSpy.count(), 1); + QCOMPARE(rightClickSpy.count(), 1); + + // cannot drag the left drawer while the right drawer is open + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(0, window->height() / 2)); + QTest::mouseMove(window, QPoint(leftDrawer->width() / 2, window->height() / 2)); + QCOMPARE(leftDrawer->position(), 0.0); + QCOMPARE(rightDrawer->position(), 1.0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(leftDrawer->width() / 2, window->height() / 2)); + QCOMPARE(leftDrawer->position(), 0.0); + QCOMPARE(rightDrawer->position(), 1.0); + + // click the right drawer's background (button disabled, don't leak through to the content below) + rightButton->setEnabled(false); + QTest::mouseClick(window, Qt::LeftButton); + QCOMPARE(contentClickSpy.count(), 1); + QCOMPARE(leftClickSpy.count(), 1); + QCOMPARE(rightClickSpy.count(), 1); + rightButton->setEnabled(true); + + // click the overlay of the right drawer (don't leak through to the content below) + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint((window->width() - rightDrawer->width()) / 2, window->height() / 2)); + QCOMPARE(contentClickSpy.count(), 1); + QCOMPARE(leftClickSpy.count(), 1); + QCOMPARE(rightClickSpy.count(), 1); + QTRY_VERIFY(!rightDrawer->isVisible()); + + // no drawers open, click the content + QTest::mouseClick(window, Qt::LeftButton); + QCOMPARE(contentClickSpy.count(), 2); + QCOMPARE(leftClickSpy.count(), 1); + QCOMPARE(rightClickSpy.count(), 1); + + // drag the right drawer open + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - 1, window->height() / 2)); + QTest::mouseMove(window, QPoint(window->width() - rightDrawer->width() / 4, window->height() / 2)); + QTest::mouseMove(window, QPoint(window->width() - rightDrawer->width() / 4 * 3, window->height() / 2)); + QCOMPARE(rightDrawer->position(), 0.5); + QCOMPARE(leftDrawer->position(), 0.0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - rightDrawer->width() / 2, window->height() / 2)); + QTRY_COMPARE(rightDrawer->position(), 1.0); + QCOMPARE(leftDrawer->position(), 0.0); +} + +void tst_QQuickDrawer::touch_data() +{ + QTest::addColumn<QString>("source"); + QTest::addColumn<QPoint>("from"); + QTest::addColumn<QPoint>("to"); + + QTest::newRow("Window:inside") << "window.qml" << QPoint(150, 100) << QPoint(50, 100); + QTest::newRow("Window:outside") << "window.qml" << QPoint(300, 100) << QPoint(100, 100); + QTest::newRow("ApplicationWindow:inside") << "applicationwindow.qml" << QPoint(150, 100) << QPoint(50, 100); + QTest::newRow("ApplicationWindow:outside") << "applicationwindow.qml" << QPoint(300, 100) << QPoint(100, 100); + + QTest::newRow("Window+Button:inside") << "window-button.qml" << QPoint(150, 100) << QPoint(50, 100); + QTest::newRow("Window+Button:outside") << "window-button.qml" << QPoint(300, 100) << QPoint(100, 100); + QTest::newRow("ApplicationWindow+Button:inside") << "applicationwindow-button.qml" << QPoint(150, 100) << QPoint(50, 100); + QTest::newRow("ApplicationWindow+Button:outside") << "applicationwindow-button.qml" << QPoint(300, 100) << QPoint(100, 100); +} + +void tst_QQuickDrawer::touch() +{ + QFETCH(QString, source); + QFETCH(QPoint, from); + QFETCH(QPoint, to); + + QQuickControlsApplicationHelper helper(this, source); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>(); + QVERIFY(drawer); + + QSignalSpy drawerOpenedSpy(drawer, SIGNAL(opened())); + QSignalSpy drawerClosedSpy(drawer, SIGNAL(closed())); + QVERIFY(drawerOpenedSpy.isValid()); + QVERIFY(drawerClosedSpy.isValid()); + + // drag to open + QTest::touchEvent(window, touchDevice.data()).press(0, QPoint(0, 100)); + QTest::touchEvent(window, touchDevice.data()).move(0, QPoint(50, 100)); + QTest::touchEvent(window, touchDevice.data()).move(0, QPoint(150, 100)); + QTest::touchEvent(window, touchDevice.data()).release(0, QPoint(150, 100)); + QVERIFY(drawerOpenedSpy.wait()); + QCOMPARE(drawer->position(), 1.0); + + // drag to close + QTest::touchEvent(window, touchDevice.data()).press(0, from); + for (int x = from.x(); x > to.x(); x -= 10) + QTest::touchEvent(window, touchDevice.data()).move(0, QPoint(x, to.y())); + QTest::touchEvent(window, touchDevice.data()).move(0, to); + QTest::touchEvent(window, touchDevice.data()).release(0, to); + QVERIFY(drawerClosedSpy.wait()); + QCOMPARE(drawer->position(), 0.0); +} + +void tst_QQuickDrawer::multiTouch() +{ + QQuickControlsApplicationHelper helper(this, QStringLiteral("multiTouch.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + QVERIFY(overlay); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer *>(); + QVERIFY(drawer); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup *>(); + QVERIFY(popup); + + QQuickButton *button = window->property("button").value<QQuickButton *>(); + QVERIFY(button); + + QSignalSpy overlayPressedSpy(overlay, SIGNAL(pressed())); + QSignalSpy overlayReleasedSpy(overlay, SIGNAL(released())); + QVERIFY(overlayPressedSpy.isValid()); + QVERIFY(overlayReleasedSpy.isValid()); + + QSignalSpy drawerOpenedSpy(drawer, SIGNAL(opened())); + QVERIFY(drawerOpenedSpy.isValid()); + + QSignalSpy buttonPressedSpy(button, SIGNAL(pressed())); + QSignalSpy buttonReleasedSpy(button, SIGNAL(released())); + QVERIFY(buttonPressedSpy.isValid()); + QVERIFY(buttonReleasedSpy.isValid()); + + popup->open(); + QVERIFY(popup->isVisible()); + + drawer->open(); + QVERIFY(drawer->isVisible()); + QVERIFY(drawerOpenedSpy.wait()); + + // 1st press + QTest::touchEvent(window, touchDevice.data()).press(0, QPoint(300, 100)); + QVERIFY(popup->isVisible()); + QVERIFY(drawer->isVisible()); + QCOMPARE(buttonPressedSpy.count(), 0); + QCOMPARE(overlayPressedSpy.count(), 1); + + // 2nd press (blocked & ignored) + QTest::touchEvent(window, touchDevice.data()).stationary(0).press(1, QPoint(300, 200)); + QVERIFY(popup->isVisible()); + QVERIFY(drawer->isVisible()); + QCOMPARE(buttonPressedSpy.count(), 0); + QCOMPARE(overlayPressedSpy.count(), 2); + + // 2nd release (blocked & ignored) + QTest::touchEvent(window, touchDevice.data()).stationary(0).release(1, QPoint(300, 200)); + QVERIFY(popup->isVisible()); + QVERIFY(drawer->isVisible()); + QCOMPARE(buttonPressedSpy.count(), 0); + QCOMPARE(buttonReleasedSpy.count(), 0); + QCOMPARE(overlayPressedSpy.count(), 2); + QCOMPARE(overlayReleasedSpy.count(), 1); + + // 1st release + QTest::touchEvent(window, touchDevice.data()).release(0, QPoint(300, 100)); + QVERIFY(popup->isVisible()); + QTRY_VERIFY(!drawer->isVisible()); + QCOMPARE(buttonPressedSpy.count(), 0); + QCOMPARE(buttonReleasedSpy.count(), 0); + QCOMPARE(overlayPressedSpy.count(), 2); + QCOMPARE(overlayReleasedSpy.count(), 2); + + drawer->open(); + QVERIFY(drawer->isVisible()); + QVERIFY(drawerOpenedSpy.wait()); + + // 1st drag + QTest::touchEvent(window, touchDevice.data()).press(0, QPoint(300, 100)); + QCOMPARE(buttonPressedSpy.count(), 0); + QCOMPARE(overlayPressedSpy.count(), 3); + for (int x = 300; x >= 100; x -= 10) { + QTest::touchEvent(window, touchDevice.data()).move(0, QPoint(x, 100)); + QVERIFY(popup->isVisible()); + QVERIFY(drawer->isVisible()); + } + QCOMPARE(drawer->position(), 0.5); + + // 2nd drag (blocked & ignored) + QTest::touchEvent(window, touchDevice.data()).stationary(0).press(1, QPoint(300, 200)); + QCOMPARE(buttonPressedSpy.count(), 0); + QCOMPARE(overlayPressedSpy.count(), 4); + for (int x = 300; x >= 0; x -= 10) { + QTest::touchEvent(window, touchDevice.data()).stationary(0).move(1, QPoint(x, 200)); + QVERIFY(popup->isVisible()); + QVERIFY(drawer->isVisible()); + } + QCOMPARE(drawer->position(), 0.5); + + // 2nd release (blocked & ignored) + QTest::touchEvent(window, touchDevice.data()).stationary(0).release(1, QPoint(300, 0)); + QVERIFY(popup->isVisible()); + QVERIFY(drawer->isVisible()); + QCOMPARE(drawer->position(), 0.5); + QCOMPARE(buttonReleasedSpy.count(), 0); + QCOMPARE(overlayReleasedSpy.count(), 3); + + // 1st release + QTest::touchEvent(window, touchDevice.data()).release(0, QPoint(300, 100)); + QVERIFY(popup->isVisible()); + QTRY_VERIFY(!drawer->isVisible()); + QCOMPARE(buttonReleasedSpy.count(), 0); + QCOMPARE(overlayReleasedSpy.count(), 4); +} + +void tst_QQuickDrawer::grabber() +{ + QQuickControlsApplicationHelper helper(this, QStringLiteral("grabber.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer *>(); + QVERIFY(drawer); + + QSignalSpy drawerOpenedSpy(drawer, SIGNAL(opened())); + QSignalSpy drawerClosedSpy(drawer, SIGNAL(closed())); + QVERIFY(drawerOpenedSpy.isValid()); + QVERIFY(drawerClosedSpy.isValid()); + + drawer->open(); + QVERIFY(drawerOpenedSpy.wait()); + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(300, 100)); + QVERIFY(drawerClosedSpy.wait()); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup *>(); + QVERIFY(popup); + + QSignalSpy popupOpenedSpy(popup, SIGNAL(opened())); + QSignalSpy popupClosedSpy(popup, SIGNAL(closed())); + QVERIFY(popupOpenedSpy.isValid()); + QVERIFY(popupClosedSpy.isValid()); + + popup->open(); + QTRY_COMPARE(popupOpenedSpy.count(), 1); + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(100, 300)); + QTRY_COMPARE(popupClosedSpy.count(), 1); +} + +void tst_QQuickDrawer::interactive_data() +{ + QTest::addColumn<QString>("source"); + QTest::newRow("Window") << "window.qml"; + QTest::newRow("ApplicationWindow") << "applicationwindow.qml"; +} + +void tst_QQuickDrawer::interactive() +{ + if (!(QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))) + QSKIP("Window activation is not supported"); + + QFETCH(QString, source); + QQuickControlsApplicationHelper helper(this, source); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer*>(); + QVERIFY(drawer); + + drawer->setInteractive(false); + + QSignalSpy openedSpy(drawer, SIGNAL(opened())); + QSignalSpy aboutToHideSpy(drawer, SIGNAL(aboutToHide())); + QVERIFY(openedSpy.isValid()); + QVERIFY(aboutToHideSpy.isValid()); + + drawer->open(); + QVERIFY(openedSpy.wait()); + + // click outside + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(300, 100)); + QCOMPARE(aboutToHideSpy.count(), 0); + + // drag inside + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(drawer->width(), 0)); + QTest::mouseMove(window, QPoint(0, 0)); + QCOMPARE(drawer->position(), 1.0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(0, 0)); + QCOMPARE(drawer->position(), 1.0); + QCOMPARE(aboutToHideSpy.count(), 0); + + // drag outside + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - 1, 0)); + QTest::mouseMove(window, QPoint(0, 0)); + QCOMPARE(drawer->position(), 1.0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(0, 0)); + QCOMPARE(drawer->position(), 1.0); + QCOMPARE(aboutToHideSpy.count(), 0); + + // close on escape + QTest::keyClick(window, Qt::Key_Escape); + QCOMPARE(aboutToHideSpy.count(), 0); +} + +void tst_QQuickDrawer::flickable_data() +{ + QTest::addColumn<bool>("mouse"); + QTest::addColumn<QPoint>("from"); + QTest::addColumn<QPoint>("to"); + + QTest::newRow("mouse,straight") << true << QPoint(200, 200) << QPoint(200, 100); + QTest::newRow("mouse,diagonal") << true << QPoint(200, 200) << QPoint(250, 100); + QTest::newRow("touch,straight") << false << QPoint(200, 200) << QPoint(200, 100); + QTest::newRow("touch,diagonal") << false << QPoint(200, 200) << QPoint(250, 100); +} + +void tst_QQuickDrawer::flickable() +{ + QFETCH(bool, mouse); + QFETCH(QPoint, from); + QFETCH(QPoint, to); + + QQuickControlsApplicationHelper helper(this, QStringLiteral("flickable.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer *>(); + QVERIFY(drawer); + + QQuickFlickable *flickable = window->property("flickable").value<QQuickFlickable *>(); + QVERIFY(flickable); + + QSignalSpy drawerOpenedSpy(drawer, SIGNAL(opened())); + QVERIFY(drawerOpenedSpy.isValid()); + + drawer->open(); + QVERIFY(drawerOpenedSpy.wait()); + + if (mouse) + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, from); + else + QTest::touchEvent(window, touchDevice.data()).press(0, from); + + static const int steps = 10; + for (int i = 0; i < steps; ++i) { + int x = i * qAbs(from.x() - to.x()) / steps; + int y = i * qAbs(from.y() - to.y()) / steps; + + if (mouse) + QTest::mouseMove(window, QPoint(x, y)); + else + QTest::touchEvent(window, touchDevice.data()).move(0, QPoint(x, y)); + QTest::qWait(1); // avoid infinite velocity + } + + QVERIFY(flickable->isDragging()); + + if (mouse) + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, to); + else + QTest::touchEvent(window, touchDevice.data()).release(0, to); + + QVERIFY(!flickable->isDragging()); +} + +void tst_QQuickDrawer::dragOverModalShadow_data() +{ + QTest::addColumn<bool>("mouse"); + QTest::newRow("mouse") << true; + QTest::newRow("touch") << false; +} + +// QTBUG-60602 +void tst_QQuickDrawer::dragOverModalShadow() +{ + QFETCH(bool, mouse); + + QQuickControlsApplicationHelper helper(this, QStringLiteral("dragOverModalShadow.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer *>(); + QVERIFY(drawer); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup *>(); + QVERIFY(popup); + + popup->open(); + QVERIFY(popup->isVisible()); + QVERIFY(!drawer->isVisible()); + + const QPoint from(popup->x(), popup->y() + popup->height() + 5); + const QPoint to(popup->x() + popup->width(), popup->y() + popup->height() + 5); + + if (mouse) + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, from); + else + QTest::touchEvent(window, touchDevice.data()).press(0, from); + QVERIFY(!drawer->isVisible()); + + static const int steps = 10; + for (int i = 0; i < steps; ++i) { + int x = from.x() + i * qAbs(from.x() - to.x()) / steps; + int y = from.y() + i * qAbs(from.y() - to.y()) / steps; + + if (mouse) + QTest::mouseMove(window, QPoint(x, y)); + else + QTest::touchEvent(window, touchDevice.data()).move(0, QPoint(x, y)); + QTest::qWait(1); // avoid infinite velocity + QVERIFY(!drawer->isVisible()); + } + + if (mouse) + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, to); + else + QTest::touchEvent(window, touchDevice.data()).release(0, to); + QVERIFY(!drawer->isVisible()); +} + +void tst_QQuickDrawer::nonModal_data() +{ + QTest::addColumn<bool>("mouse"); + QTest::newRow("mouse") << true; + QTest::newRow("touch") << false; +} + +// QTBUG-59652 +void tst_QQuickDrawer::nonModal() +{ + QFETCH(bool, mouse); + + QQuickControlsApplicationHelper helper(this, QStringLiteral("window.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer *>(); + QVERIFY(drawer); + drawer->setModal(false); + + const QPoint from(1, 1); + const QPoint to(150, 1); + + // drag to open + QSignalSpy openedSpy(drawer, SIGNAL(opened())); + QVERIFY(openedSpy.isValid()); + + if (mouse) + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, from); + else + QTest::touchEvent(window, touchDevice.data()).press(0, from); + + static const int steps = 10; + for (int i = 0; i < steps; ++i) { + int x = i * qAbs(from.x() - to.x()) / steps; + int y = i * qAbs(from.y() - to.y()) / steps; + + if (mouse) + QTest::mouseMove(window, QPoint(x, y)); + else + QTest::touchEvent(window, touchDevice.data()).move(0, QPoint(x, y)); + QTest::qWait(1); // avoid infinite velocity + } + QVERIFY(drawer->isVisible()); + + if (mouse) + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, to); + else + QTest::touchEvent(window, touchDevice.data()).release(0, to); + QVERIFY(openedSpy.wait()); + + // drag to close + QSignalSpy closedSpy(drawer, SIGNAL(closed())); + QVERIFY(closedSpy.isValid()); + + if (mouse) + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, to); + else + QTest::touchEvent(window, touchDevice.data()).press(0, to); + + for (int i = steps - 1; i >= 0; --i) { + int x = i * qAbs(from.x() - to.x()) / steps; + int y = i * qAbs(from.y() - to.y()) / steps; + + if (mouse) + QTest::mouseMove(window, QPoint(x, y)); + else + QTest::touchEvent(window, touchDevice.data()).move(0, QPoint(x, y)); + QTest::qWait(1); // avoid infinite velocity + } + QVERIFY(drawer->isVisible()); + + if (mouse) + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, from); + else + QTest::touchEvent(window, touchDevice.data()).release(0, from); + QVERIFY(closedSpy.wait()); +} + +void tst_QQuickDrawer::slider_data() +{ + QTest::addColumn<bool>("mouse"); + QTest::addColumn<int>("delta"); + + QTest::newRow("mouse") << true << 2; + QTest::newRow("touch") << false << 2; + QTest::newRow("mouse,delta") << true << 296 / 8; +} + +void tst_QQuickDrawer::slider() +{ + QFETCH(bool, mouse); + QFETCH(int, delta); + + QQuickControlsApplicationHelper helper(this, QStringLiteral("slider.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer *>(); + QVERIFY(drawer); + + QQuickSlider *slider = window->property("slider").value<QQuickSlider *>(); + QVERIFY(slider); + + QCOMPARE(slider->value(), 1.0); + QCOMPARE(drawer->position(), 1.0); + + const qreal y = slider->height() / 2; + const QPoint from(slider->width() - 1, y); + const QPoint to(1, y); + + QTest::qWait(1); + + if (mouse) + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, from); + else + QTest::touchEvent(window, touchDevice.data()).press(0, from); + + QTest::qWait(1); + + int distance = qAbs(from.x() - to.x()); + for (int dx = delta; dx <= distance; dx += delta) { + if (mouse) + QTest::mouseMove(window, from - QPoint(dx, 0)); + else + QTest::touchEvent(window, touchDevice.data()).move(0, from - QPoint(dx, 0)); + QTest::qWait(1); // avoid infinite velocity + } + + QCOMPARE(slider->value(), 0.0); + QCOMPARE(drawer->position(), 1.0); + + if (mouse) + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, to); + else + QTest::touchEvent(window, touchDevice.data()).release(0, to); +} + +void tst_QQuickDrawer::topEdgeScreenEdge() +{ + QQuickControlsApplicationHelper helper(this, QStringLiteral("topEdgeScreenEdge.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickDrawer *drawer = window->property("drawer").value<QQuickDrawer *>(); + QVERIFY(drawer); + + QVERIFY(QMetaObject::invokeMethod(drawer, "open")); + QTRY_COMPARE(drawer->position(), 1.0); +} + +void tst_QQuickDrawer::touchOutsideOverlay() // QTBUG-103811 +{ + QQuickView window; + QVERIFY(QQuickTest::showView(window, testFileUrl("itemPartialOverlayModal.qml"))); + auto *drawer = window.rootObject()->findChild<QQuickDrawer*>(); + QVERIFY(drawer); + QSignalSpy openedSpy(drawer, &QQuickDrawer::opened); + QSignalSpy closedSpy(drawer, &QQuickDrawer::closed); + + drawer->open(); + QVERIFY(openedSpy.size() == 1 || openedSpy.wait()); + QVERIFY(drawer->isOpened()); + + // tap-dance in bottom area beyond the overlay + QPoint p1(100, 250); + QPoint p2(300, 250); + QTest::touchEvent(&window, touchDevice.data()).press(1, p1); + p1 -= QPoint(1, 0); + QTest::touchEvent(&window, touchDevice.data()).move(1, p1).press(2, p2); + p2 -= QPoint(1, 0); + QTest::touchEvent(&window, touchDevice.data()).release(1, p1).move(2, p2); + QTest::touchEvent(&window, touchDevice.data()).press(1, p1).stationary(2); + QTest::touchEvent(&window, touchDevice.data()).release(1, p1).release(2, p2); + QQuickTouchUtils::flush(&window); + + // tap the overlay to try to close the drawer + QVERIFY(drawer->closePolicy().testFlag(QQuickPopup::CloseOnReleaseOutside)); + const QPoint p3(300, 100); + QTest::touchEvent(&window, touchDevice.data()).press(3, p3); + QTest::touchEvent(&window, touchDevice.data()).release(3, p3); + QQuickTouchUtils::flush(&window); + QVERIFY(closedSpy.size() == 1 || closedSpy.wait()); + QCOMPARE(drawer->isOpened(), false); +} + +QTEST_QUICKCONTROLS_MAIN(tst_QQuickDrawer) + +#include "tst_qquickdrawer.moc" diff --git a/tests/auto/quickcontrols2/qquickheaderview/CMakeLists.txt b/tests/auto/quickcontrols2/qquickheaderview/CMakeLists.txt new file mode 100644 index 00000000000..1bfae70cbb0 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickheaderview/CMakeLists.txt @@ -0,0 +1,49 @@ +# Generated from qquickheaderview.pro. + +##################################################################### +## tst_qquickheaderview Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickheaderview + SOURCES + tst_qquickheaderview.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2 + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:qquickheaderview.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickheaderview CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickheaderview CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickheaderview/data/ListModel.qml b/tests/auto/quickcontrols2/qquickheaderview/data/ListModel.qml new file mode 100644 index 00000000000..b8160a46dd4 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickheaderview/data/ListModel.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import TestTableModel + +Window { + objectName: "window" + width: 400 + height: 400 + visible: true + + Component { + id: cellDelegate + Rectangle { + implicitHeight: 25 + implicitWidth: 50 + color: "red" + Text { + text: row + "," + column + } + } + } + + HorizontalHeaderView { + id: hhv + objectName: "horizontalHeader" + model: ["AAA", "BBB", "CCC", "DDD", "EEE"] + syncView: tv + anchors.top: parent.top + x: vhv.width + } + + VerticalHeaderView { + id: vhv + objectName: "verticalHeader" + model: ["111", "222", "333", "444", "555"] + syncView: tv + anchors.left: parent.left + y: hhv.height + } + + TableView { + id: tv + objectName: "tableView" + model: TestTableModel { + id: tm + objectName: "tableModel" + rowCount: 5 + columnCount: 5 + } + delegate: cellDelegate + anchors.top: hhv.bottom + anchors.left: vhv.right + anchors.right: parent.right + anchors.bottom: parent.bottom + } +} diff --git a/tests/auto/quickcontrols2/qquickheaderview/data/Window.qml b/tests/auto/quickcontrols2/qquickheaderview/data/Window.qml new file mode 100644 index 00000000000..9bf9963c695 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickheaderview/data/Window.qml @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import TestTableModel +import TestTableModelWithHeader +import HeaderDataProxyModel + +Window { + objectName: "window" + width: 400 + height: 400 + visible: true + + Component { + id: cellDelegate + Rectangle { + implicitHeight: 25 + implicitWidth: 50 + color: "red" + Text { + text: row + "," + column + } + } + } + + HeaderDataProxyModel { + id: pm + objectName: "proxyModel" + } + + TestTableModel { + id: tm + objectName: "tableModel" + rowCount: 5 + columnCount: 10 + } + + TestTableModelWithHeader { + id: thm + objectName: "tableHeaderModel" + rowCount: 5 + columnCount: 10 + } + + HorizontalHeaderView { + id: hhv + objectName: "horizontalHeader" + width: 200 + height: 200 + model: thm + delegate: cellDelegate + } + + VerticalHeaderView { + id: vhv + objectName: "verticalHeader" + width: 200 + height: 200 + model: thm + delegate: cellDelegate + } + + TableView { + id: tv + objectName: "tableView" + width: 400 + height: 400 + model: thm + delegate:cellDelegate + } +} diff --git a/tests/auto/quickcontrols2/qquickheaderview/tst_qquickheaderview.cpp b/tests/auto/quickcontrols2/qquickheaderview/tst_qquickheaderview.cpp new file mode 100644 index 00000000000..741875c1123 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickheaderview/tst_qquickheaderview.cpp @@ -0,0 +1,411 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qsignalspy.h> +#include <QtTest/qtest.h> +#include <QtQuickTest/quicktest.h> + +#include <QAbstractItemModelTester> +#include <QtQml/QQmlEngine> +#include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qquicktext_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickheaderview_p.h> +#include <private/qquickheaderview_p_p.h> + +class TestTableModel : public QAbstractTableModel { + Q_OBJECT + Q_PROPERTY(int rowCount READ rowCount WRITE setRowCount NOTIFY rowCountChanged) + Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount NOTIFY columnCountChanged) + +public: + TestTableModel(QObject *parent = nullptr) + : QAbstractTableModel(parent) + { + } + + int rowCount(const QModelIndex &index = QModelIndex()) const override + { + if (index.isValid()) + return 0; + return m_rows; + } + virtual void setRowCount(int count) + { + beginResetModel(); + m_rows = count; + emit rowCountChanged(); + endResetModel(); + } + + int columnCount(const QModelIndex &index = QModelIndex()) const override + { + if (index.isValid()) + return 0; + return m_cols; + } + virtual void setColumnCount(int count) + { + beginResetModel(); + m_cols = count; + emit columnCountChanged(); + endResetModel(); + } + + int indexValue(const QModelIndex &index) const + { + return index.row() + (index.column() * rowCount()); + } + + Q_INVOKABLE QModelIndex toQModelIndex(int serialIndex) + { + return createIndex(serialIndex % rowCount(), serialIndex / rowCount()); + } + + Q_INVOKABLE QVariant data(int row, int col) + { + return data(createIndex(row, col), Qt::DisplayRole); + } + QVariant data(const QModelIndex &index, int role) const override + { + if (!index.isValid()) + return QVariant(); + + switch (role) { + case Qt::DisplayRole: + return QString("%1, %2, checked: %3 ") + .arg(index.row()) + .arg(index.column()) + .arg(m_checkedCells.contains(indexValue(index))); + case Qt::EditRole: + return m_checkedCells.contains(indexValue(index)); + default: + return QVariant(); + } + } + + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole) override + { + + if (role != Qt::EditRole) + return false; + + int i = indexValue(index); + bool checked = value.toBool(); + if (checked == m_checkedCells.contains(i)) + return false; + + if (checked) + m_checkedCells.insert(i); + else + m_checkedCells.remove(i); + + emit dataChanged(index, index, { role }); + return true; + } + + Q_INVOKABLE QHash<int, QByteArray> roleNames() const override + { + return { + { Qt::DisplayRole, "display" }, + { Qt::EditRole, "edit" } + }; + } + +signals: + void rowCountChanged(); + void columnCountChanged(); + +private: + int m_rows = 0; + int m_cols = 0; + + QSet<int> m_checkedCells; +}; + +class TestTableModelWithHeader : public TestTableModel { + + Q_OBJECT +public: + void setRowCount(int count) override + { + vData.resize(count); + TestTableModel::setRowCount(count); + } + + void setColumnCount(int count) override + { + hData.resize(count); + TestTableModel::setColumnCount(count); + } + Q_INVOKABLE QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const override + { + auto sectionCount = orientation == Qt::Horizontal ? columnCount() : rowCount(); + if (section < 0 || section >= sectionCount) + return QVariant(); + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: { + auto &data = orientation == Qt::Horizontal ? hData : vData; + return data[section].toString(); + } + default: + return QVariant(); + } + } + Q_INVOKABLE bool setHeaderData(int section, Qt::Orientation orientation, + const QVariant &value, int role = Qt::EditRole) override + { + qDebug() << Q_FUNC_INFO + << "section:" << section + << "orient:" << orientation + << "value:" << value + << "role:" << QAbstractItemModel::roleNames()[role]; + auto sectionCount = orientation == Qt::Horizontal ? columnCount() : rowCount(); + if (section < 0 || section >= sectionCount) + return false; + auto &data = orientation == Qt::Horizontal ? hData : vData; + data[section] = value; + emit headerDataChanged(orientation, section, section); + return true; + } + +private: + QList<QVariant> hData, vData; +}; + +class tst_QQuickHeaderView : public QQmlDataTest { + Q_OBJECT + +public: + tst_QQuickHeaderView(); + +private slots: + void initTestCase() override; + void cleanupTestCase(); + void init(); + void cleanup(); + + void defaults(); + void testHeaderDataProxyModel(); + void testOrientation(); + void testModel(); + void listModel(); + +private: + QQmlEngine *engine; + QString errorString; + + std::unique_ptr<QObject> rootObjectFromQml(const char *file) + { + auto component = new QQmlComponent(engine); + component->loadUrl(testFileUrl(file)); + auto root = component->create(); + if (!root) + errorString = component->errorString(); + return std::unique_ptr<QObject>(new QObject(root)); + } +}; + +tst_QQuickHeaderView::tst_QQuickHeaderView() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_QQuickHeaderView::initTestCase() +{ + QQmlDataTest::initTestCase(); + qmlRegisterType<TestTableModel>("TestTableModel", 0, 1, "TestTableModel"); + qmlRegisterType<TestTableModelWithHeader>("TestTableModelWithHeader", 0, 1, "TestTableModelWithHeader"); + qmlRegisterType<QHeaderDataProxyModel>("HeaderDataProxyModel", 0, 1, "HeaderDataProxyModel"); +} + +void tst_QQuickHeaderView::cleanupTestCase() +{ +} + +void tst_QQuickHeaderView::init() +{ + engine = new QQmlEngine(this); +} + +void tst_QQuickHeaderView::cleanup() +{ + if (engine) { + delete engine; + engine = nullptr; + } +} + +void tst_QQuickHeaderView::defaults() +{ + QQmlComponent component(engine); + component.loadUrl(testFileUrl("Window.qml")); + + QScopedPointer<QObject> root(component.create()); + QVERIFY2(root, qPrintable(component.errorString())); + + auto hhv = root->findChild<QQuickHorizontalHeaderView *>("horizontalHeader"); + QVERIFY(hhv); + auto vhv = root->findChild<QQuickVerticalHeaderView *>("verticalHeader"); + QVERIFY(vhv); + auto tm = root->findChild<TestTableModel *>("tableModel"); + QVERIFY(tm); + auto pm = root->findChild<QHeaderDataProxyModel *>("proxyModel"); + QVERIFY(pm); + auto tv = root->findChild<QQuickTableView *>("tableView"); + QVERIFY(tv); +} + +void tst_QQuickHeaderView::testHeaderDataProxyModel() +{ + TestTableModel model; + model.setColumnCount(10); + model.setRowCount(7); + QHeaderDataProxyModel model2; + model2.setSourceModel(&model); + QAbstractItemModelTester tester(&model2, QAbstractItemModelTester::FailureReportingMode::QtTest); +} + +void tst_QQuickHeaderView::testOrientation() +{ + QQmlComponent component(engine); + component.loadUrl(testFileUrl("Window.qml")); + + QScopedPointer<QObject> root(component.create()); + QVERIFY2(root, qPrintable(component.errorString())); + // Make sure that the window is shown at this point, so that the test + // behaves similarly on all platforms + QVERIFY(QTest::qWaitForWindowActive(qobject_cast<QWindow *>(root.data()))); + + // If we want to make use of syncDirection, we need to set syncView as well. + // For that we need to create a second dummy table view. + QQuickTableView otherView; + + auto hhv = root->findChild<QQuickHorizontalHeaderView *>("horizontalHeader"); + QVERIFY(hhv); + QCOMPARE(hhv->columns(), 10); + QCOMPARE(hhv->rows(), 1); + auto vhv = root->findChild<QQuickVerticalHeaderView *>("verticalHeader"); + QVERIFY(vhv); + + hhv->setSyncView(&otherView); + hhv->setSyncDirection(Qt::Vertical); + QVERIFY(QQuickTest::qWaitForItemPolished(hhv)); + + vhv->setSyncView(&otherView); + vhv->setSyncDirection(Qt::Horizontal); + QVERIFY(QQuickTest::qWaitForItemPolished(vhv)); + + // Explicitly setting a different synDirection is ignored + QCOMPARE(hhv->syncDirection(), Qt::Horizontal); + QCOMPARE(hhv->flickableDirection(), QQuickFlickable::HorizontalFlick); + QCOMPARE(vhv->syncDirection(), Qt::Vertical); + QCOMPARE(vhv->flickableDirection(), QQuickFlickable::VerticalFlick); +} + +void tst_QQuickHeaderView::testModel() +{ + QQmlComponent component(engine); + component.loadUrl(testFileUrl("Window.qml")); + + QScopedPointer<QObject> root(component.create()); + QVERIFY2(root, qPrintable(component.errorString())); + + auto hhv = root->findChild<QQuickHorizontalHeaderView *>("horizontalHeader"); + QVERIFY(hhv); + auto thm = root->findChild<TestTableModel *>("tableHeaderModel"); + QVERIFY(thm); + auto pm = root->findChild<QHeaderDataProxyModel *>("proxyModel"); + QVERIFY(pm); + + QSignalSpy modelChangedSpy(hhv, SIGNAL(modelChanged())); + QVERIFY(modelChangedSpy.isValid()); + + hhv->setModel(QVariant::fromValue(thm)); + QCOMPARE(modelChangedSpy.count(), 0); + + hhv->setModel(QVariant::fromValue(pm)); + QCOMPARE(modelChangedSpy.count(), 1); + + TestTableModel ttm2; + ttm2.setRowCount(100); + ttm2.setColumnCount(30); + hhv->setModel(QVariant::fromValue(&ttm2)); + QCOMPARE(modelChangedSpy.count(), 2); +} + +void tst_QQuickHeaderView::listModel() +{ + QQmlComponent component(engine); + component.loadUrl(testFileUrl("ListModel.qml")); + + QScopedPointer<QObject> root(component.create()); + QVERIFY2(root, qPrintable(component.errorString())); + + if (!QTest::qWaitForWindowActive(qobject_cast<QWindow *>(root.data()))) + QSKIP("Window failed to become active!"); + + auto hhv = root->findChild<QQuickHorizontalHeaderView *>("horizontalHeader"); + QVERIFY(hhv); + auto vhv = root->findChild<QQuickVerticalHeaderView *>("verticalHeader"); + QVERIFY(vhv); + + auto hhvCell1 = hhv->childAt(0, 0)->childAt(0, 0)->findChild<QQuickText *>(); + QVERIFY(hhvCell1); + QCOMPARE(hhvCell1->property("text"), "AAA"); + + auto hhvCell2 = hhv->childAt(hhvCell1->width() + 5, 0)-> + childAt(hhvCell1->width() + 5, 0)->findChild<QQuickText *>(); + QVERIFY(hhvCell2); + QCOMPARE(hhvCell2->property("text"), "BBB"); + + auto vhvCell1 = vhv->childAt(0, 0)->childAt(0, 0)->findChild<QQuickText *>(); + QVERIFY(vhvCell1); + QCOMPARE(vhvCell1->property("text"), "111"); + + auto vhvCell2 = vhv->childAt(0, vhvCell1->height() + 5)-> + childAt(0, vhvCell1->height() + 5)->findChild<QQuickText *>(); + QVERIFY(vhvCell2); + QCOMPARE(vhvCell2->property("text"), "222"); +} + +QTEST_MAIN(tst_QQuickHeaderView) + +#include "tst_qquickheaderview.moc" diff --git a/tests/auto/quickcontrols2/qquickiconimage/BLACKLIST b/tests/auto/quickcontrols2/qquickiconimage/BLACKLIST new file mode 100644 index 00000000000..70c935375d2 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/BLACKLIST @@ -0,0 +1,15 @@ +# QTBUG-101006 +[nameBindingSourceSize] +android +[sourceBindingSourceSize] +android +[alignment] +android +[color] +android +[fileSelectors] +android +[imageProvider] +android +[translucentColors] +android diff --git a/tests/auto/quickcontrols2/qquickiconimage/CMakeLists.txt b/tests/auto/quickcontrols2/qquickiconimage/CMakeLists.txt new file mode 100644 index 00000000000..acb9b99a1ad --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/CMakeLists.txt @@ -0,0 +1,84 @@ +# Generated from qquickiconimage.pro. + +##################################################################### +## tst_qquickiconimage Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/*.qml) +list(APPEND test_data ${test_data_glob}) +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/icons/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickiconimage + SOURCES + tst_qquickiconimage.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + LIBRARIES + Qt::QuickControls2ImplPrivate + Qt::QuickPrivate + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::Qml + Qt::QmlPrivate + Qt::Quick + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +# Resources: +set(resources_resource_files + "icons/testtheme/16x16/actions/appointment-new.png" + "icons/testtheme/22x22/actions/+testselector/appointment-new.png" + "icons/testtheme/22x22/actions/+testselector/appointment-new@2x.png" + "icons/testtheme/22x22/actions/appointment-new.png" + "icons/testtheme/22x22/actions/appointment-new@2x.png" + "icons/testtheme/22x22/actions/color-test-original.png" + "icons/testtheme/22x22/actions/color-test-original@2x.png" + "icons/testtheme/22x22/actions/color-test-tinted.png" + "icons/testtheme/22x22/actions/color-test-tinted@2x.png" + "icons/testtheme/22x22@2/actions/+testselector/appointment-new.png" + "icons/testtheme/22x22@2/actions/appointment-new.png" + "icons/testtheme/appointment-new.svg" + "icons/testtheme/index.theme" +) + +qt_internal_add_resource(tst_qquickiconimage "resources" + PREFIX + "/" + FILES + ${resources_resource_files} +) + + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickiconimage CONDITION TARGET Qt::Svg + PUBLIC_LIBRARIES + Qt::Svg +) + +qt_internal_extend_target(tst_qquickiconimage CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickiconimage CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/alignment.qml b/tests/auto/quickcontrols2/qquickiconimage/data/alignment.qml new file mode 100644 index 00000000000..e6861520b90 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/alignment.qml @@ -0,0 +1,16 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +Row { + width: 200 + height: 200 + + IconImage { + name: "appointment-new" + sourceSize: Qt.size(22, 22) + } + Image { + source: "qrc:/icons/testtheme/22x22/actions/appointment-new.png" + } +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/color.qml b/tests/auto/quickcontrols2/qquickiconimage/data/color.qml new file mode 100644 index 00000000000..b44b43885c5 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/color.qml @@ -0,0 +1,18 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +Row { + width: 200 + height: 200 + + IconImage { + source: "qrc:/icons/testtheme/22x22/actions/color-test-original.png" + sourceSize: Qt.size(22, 22) + color: "red" + } + Image { + source: "qrc:/icons/testtheme/22x22/actions/color-test-tinted.png" + fillMode: Image.Pad + } +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/fileSelectors.qml b/tests/auto/quickcontrols2/qquickiconimage/data/fileSelectors.qml new file mode 100644 index 00000000000..e6861520b90 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/fileSelectors.qml @@ -0,0 +1,16 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +Row { + width: 200 + height: 200 + + IconImage { + name: "appointment-new" + sourceSize: Qt.size(22, 22) + } + Image { + source: "qrc:/icons/testtheme/22x22/actions/appointment-new.png" + } +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/imageProvider.qml b/tests/auto/quickcontrols2/qquickiconimage/data/imageProvider.qml new file mode 100644 index 00000000000..9b18a99e353 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/imageProvider.qml @@ -0,0 +1,9 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Templates as T + +IconLabel { + icon.color: "transparent" + icon.source: "image://provider/red" +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/nameBindingNoSizes.qml b/tests/auto/quickcontrols2/qquickiconimage/data/nameBindingNoSizes.qml new file mode 100644 index 00000000000..d457d205d55 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/nameBindingNoSizes.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +IconImage { + name: "appointment-new" +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/nameBindingSourceSize.qml b/tests/auto/quickcontrols2/qquickiconimage/data/nameBindingSourceSize.qml new file mode 100644 index 00000000000..e6861520b90 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/nameBindingSourceSize.qml @@ -0,0 +1,16 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +Row { + width: 200 + height: 200 + + IconImage { + name: "appointment-new" + sourceSize: Qt.size(22, 22) + } + Image { + source: "qrc:/icons/testtheme/22x22/actions/appointment-new.png" + } +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/nameBindingSourceSizeWidthHeight.qml b/tests/auto/quickcontrols2/qquickiconimage/data/nameBindingSourceSizeWidthHeight.qml new file mode 100644 index 00000000000..5e7ebefca4c --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/nameBindingSourceSizeWidthHeight.qml @@ -0,0 +1,10 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +IconImage { + name: "appointment-new" + sourceSize: Qt.size(22, 22) + width: 16 + height: 16 +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/root.qml b/tests/auto/quickcontrols2/qquickiconimage/data/root.qml new file mode 100644 index 00000000000..ed02d2df7a6 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/root.qml @@ -0,0 +1,6 @@ +import QtQuick + +Item { + width: 200 + height: 200 +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/sourceBindingNoSizes.qml b/tests/auto/quickcontrols2/qquickiconimage/data/sourceBindingNoSizes.qml new file mode 100644 index 00000000000..34fc6b339c2 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/sourceBindingNoSizes.qml @@ -0,0 +1,15 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +Row { + width: 200 + height: 200 + + IconImage { + source: "qrc:/icons/testtheme/22x22/actions/appointment-new.png" + } + Image { + source: "qrc:/icons/testtheme/22x22/actions/appointment-new.png" + } +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/sourceBindingSourceSize.qml b/tests/auto/quickcontrols2/qquickiconimage/data/sourceBindingSourceSize.qml new file mode 100644 index 00000000000..9f1b6290741 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/sourceBindingSourceSize.qml @@ -0,0 +1,16 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +Row { + width: 200 + height: 200 + + IconImage { + source: "qrc:/icons/testtheme/22x22/actions/appointment-new.png" + sourceSize: Qt.size(22, 22) + } + Image { + source: "qrc:/icons/testtheme/22x22/actions/appointment-new.png" + } +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/sourceBindingSourceSizeWidthHeight.qml b/tests/auto/quickcontrols2/qquickiconimage/data/sourceBindingSourceSizeWidthHeight.qml new file mode 100644 index 00000000000..4dc3ac75885 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/sourceBindingSourceSizeWidthHeight.qml @@ -0,0 +1,10 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +IconImage { + source: "qrc:/icons/testtheme/22x22/actions/appointment-new.png" + sourceSize: Qt.size(22, 22) + width: 16 + height: 16 +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/sourceBindingSourceTooLarge.qml b/tests/auto/quickcontrols2/qquickiconimage/data/sourceBindingSourceTooLarge.qml new file mode 100644 index 00000000000..a54d998aa58 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/sourceBindingSourceTooLarge.qml @@ -0,0 +1,8 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +IconImage { + source: "qrc:/icons/testtheme/22x22/actions/appointment-new.png" + sourceSize: Qt.size(32, 32) +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/svgNoSizes.qml b/tests/auto/quickcontrols2/qquickiconimage/data/svgNoSizes.qml new file mode 100644 index 00000000000..e29c23c5b27 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/svgNoSizes.qml @@ -0,0 +1,15 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +Row { + width: 200 + height: 200 + + IconImage { + source: "qrc:/icons/testtheme/appointment-new.svg" + } + Image { + source: "qrc:/icons/testtheme/appointment-new.svg" + } +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/svgSourceBindingSourceSize.qml b/tests/auto/quickcontrols2/qquickiconimage/data/svgSourceBindingSourceSize.qml new file mode 100644 index 00000000000..4674e8f14b2 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/svgSourceBindingSourceSize.qml @@ -0,0 +1,17 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +Row { + width: 200 + height: 200 + + IconImage { + source: "qrc:/data/icons/testtheme/appointment-new.svg" + sourceSize: Qt.size(22, 22) + } + Image { + source: "qrc:/data/icons/testtheme/appointment-new.svg" + sourceSize: Qt.size(22, 22) + } +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/data/translucentColors.qml b/tests/auto/quickcontrols2/qquickiconimage/data/translucentColors.qml new file mode 100644 index 00000000000..ad67bfe522b --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/data/translucentColors.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +ApplicationWindow { + width: 500 + height: 500 + visible: true + + IconImage { + width: Math.min(250, parent.width) + height: Math.min(250, parent.height) + source: "qrc:/icons/testtheme/22x22/actions/color-test-original.png" + sourceSize: Qt.size(250, 0) + color: Qt.rgba(0, 0, 0, 0.5) + } +} diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/16x16/actions/appointment-new.png b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/16x16/actions/appointment-new.png new file mode 100644 index 00000000000..4356af95166 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/16x16/actions/appointment-new.png differ diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/+testselector/appointment-new.png b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/+testselector/appointment-new.png new file mode 100644 index 00000000000..d3134a55d4a Binary files /dev/null and b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/+testselector/appointment-new.png differ diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/+testselector/appointment-new@2x.png b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/+testselector/appointment-new@2x.png new file mode 100644 index 00000000000..250b94b0197 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/+testselector/appointment-new@2x.png differ diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/appointment-new.png b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/appointment-new.png new file mode 100644 index 00000000000..04cd010a682 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/appointment-new.png differ diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/appointment-new@2x.png b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/appointment-new@2x.png new file mode 100644 index 00000000000..a63bbaf4c54 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/appointment-new@2x.png differ diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/color-test-original.png b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/color-test-original.png new file mode 100644 index 00000000000..c17d1664029 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/color-test-original.png differ diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/color-test-original@2x.png b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/color-test-original@2x.png new file mode 100644 index 00000000000..d4411658f96 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/color-test-original@2x.png differ diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/color-test-tinted.png b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/color-test-tinted.png new file mode 100644 index 00000000000..6f7938e3652 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/color-test-tinted.png differ diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/color-test-tinted@2x.png b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/color-test-tinted@2x.png new file mode 100644 index 00000000000..9215fc423b6 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22/actions/color-test-tinted@2x.png differ diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22@2/actions/+testselector/appointment-new.png b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22@2/actions/+testselector/appointment-new.png new file mode 100644 index 00000000000..250b94b0197 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22@2/actions/+testselector/appointment-new.png differ diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22@2/actions/appointment-new.png b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22@2/actions/appointment-new.png new file mode 100644 index 00000000000..a63bbaf4c54 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/22x22@2/actions/appointment-new.png differ diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/appointment-new.svg b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/appointment-new.svg new file mode 100644 index 00000000000..4cb14f82f02 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/appointment-new.svg @@ -0,0 +1,425 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + inkscape:export-ydpi="90.000000" + inkscape:export-xdpi="90.000000" + inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png" + width="48px" + height="48px" + id="svg11300" + sodipodi:version="0.32" + inkscape:version="0.46" + sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/actions" + sodipodi:docname="appointment-new.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape"> + <defs + id="defs3"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 24 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="48 : 24 : 1" + inkscape:persp3d-origin="24 : 16 : 1" + id="perspective59" /> + <linearGradient + inkscape:collect="always" + id="linearGradient5204"> + <stop + style="stop-color:#c4a000;stop-opacity:1;" + offset="0" + id="stop5206" /> + <stop + style="stop-color:#c4a000;stop-opacity:0;" + offset="1" + id="stop5208" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient5196"> + <stop + style="stop-color:#c4a000;stop-opacity:1;" + offset="0" + id="stop5198" /> + <stop + style="stop-color:#c4a000;stop-opacity:0;" + offset="1" + id="stop5200" /> + </linearGradient> + <linearGradient + id="linearGradient12512"> + <stop + style="stop-color:#ffffff;stop-opacity:1.0000000;" + offset="0.0000000" + id="stop12513" /> + <stop + style="stop-color:#fff520;stop-opacity:0.89108908;" + offset="0.50000000" + id="stop12517" /> + <stop + style="stop-color:#fff300;stop-opacity:0.0000000;" + offset="1.0000000" + id="stop12514" /> + </linearGradient> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient12512" + id="radialGradient278" + gradientUnits="userSpaceOnUse" + cx="55.000000" + cy="125.00000" + fx="55.000000" + fy="125.00000" + r="14.375000" /> + <linearGradient + id="linearGradient10653"> + <stop + style="stop-color:#f3f4ff;stop-opacity:1.0000000;" + offset="0.0000000" + id="stop10655" /> + <stop + style="stop-color:#9193af;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop10657" /> + </linearGradient> + <linearGradient + id="linearGradient42174"> + <stop + style="stop-color:#a0a0a0;stop-opacity:1.0000000;" + offset="0.0000000" + id="stop42176" /> + <stop + style="stop-color:#ffffff;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop42178" /> + </linearGradient> + <linearGradient + id="linearGradient2145"> + <stop + style="stop-color:#fffffd;stop-opacity:1.0000000;" + offset="0.0000000" + id="stop2147" /> + <stop + style="stop-color:#cbcbc9;stop-opacity:1.0000000;" + offset="1.0000000" + id="stop2149" /> + </linearGradient> + <linearGradient + id="linearGradient37935"> + <stop + id="stop37937" + offset="0.0000000" + style="stop-color:#9497b3;stop-opacity:1.0000000;" /> + <stop + id="stop37939" + offset="1.0000000" + style="stop-color:#4c4059;stop-opacity:1.0000000;" /> + </linearGradient> + <linearGradient + id="linearGradient2152"> + <stop + id="stop2154" + offset="0.0000000" + style="stop-color:#9aa29a;stop-opacity:1.0000000;" /> + <stop + id="stop2156" + offset="1.0000000" + style="stop-color:#b5beb5;stop-opacity:1.0000000;" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3816"> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop3818" /> + <stop + style="stop-color:#000000;stop-opacity:0;" + offset="1" + id="stop3820" /> + </linearGradient> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3816" + id="radialGradient3822" + cx="31.112698" + cy="19.008621" + fx="31.112698" + fy="19.008621" + r="8.6620579" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2152" + id="linearGradient4307" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(3.123841,0.000000,0.000000,0.969691,-31.88758,-19.59492)" + x1="8.9156475" + y1="37.197018" + x2="9.8855033" + y2="52.090678" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient10653" + id="radialGradient4309" + gradientUnits="userSpaceOnUse" + cx="11.329200" + cy="10.583970" + fx="11.329200" + fy="10.583970" + r="15.532059" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient2145" + id="radialGradient4311" + gradientUnits="userSpaceOnUse" + cx="11.901996" + cy="10.045444" + fx="11.901996" + fy="10.045444" + r="29.292715" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient42174" + id="linearGradient4313" + gradientUnits="userSpaceOnUse" + x1="6.3422160" + y1="7.7893324" + x2="22.218424" + y2="25.884274" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient5196" + id="radialGradient5202" + cx="23.375" + cy="10.972863" + fx="23.375" + fy="10.972863" + r="3.3478092" + gradientTransform="matrix(3.630420,1.654030e-15,-1.608743e-15,3.742066,-61.48607,-29.18618)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5204" + id="linearGradient5210" + x1="19.667364" + y1="4.2570662" + x2="20.329933" + y2="5.2845874" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient37935" + id="radialGradient5212" + gradientUnits="userSpaceOnUse" + cx="8.7468252" + cy="6.8283234" + fx="8.7468252" + fy="6.8283234" + r="29.889715" /> + </defs> + <sodipodi:namedview + stroke="#c4a000" + fill="#babdb6" + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="0.25490196" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="11.313708" + inkscape:cx="13.2248" + inkscape:cy="25.106052" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:showpageshadow="false" + inkscape:window-width="833" + inkscape:window-height="772" + inkscape:window-x="305" + inkscape:window-y="76" /> + <metadata + id="metadata4"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:creator> + <cc:Agent> + <dc:title>Jakub Steiner</dc:title> + </cc:Agent> + </dc:creator> + <dc:source>http://jimmac.musichall.cz</dc:source> + <cc:license + rdf:resource="http://creativecommons.org/licenses/publicdomain/" /> + <dc:title>New Appointment</dc:title> + <dc:subject> + <rdf:Bag> + <rdf:li>appointment</rdf:li> + <rdf:li>new</rdf:li> + <rdf:li>meeting</rdf:li> + <rdf:li>rvsp</rdf:li> + </rdf:Bag> + </dc:subject> + </cc:Work> + <cc:License + rdf:about="http://creativecommons.org/licenses/publicdomain/"> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Distribution" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + </cc:License> + </rdf:RDF> + </metadata> + <g + id="layer1" + inkscape:label="Layer 1" + inkscape:groupmode="layer"> + <path + d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" + sodipodi:ry="8.6620579" + sodipodi:rx="8.6620579" + sodipodi:cy="19.008621" + sodipodi:cx="31.112698" + id="path4318" + style="opacity:1;color:#000000;fill:url(#radialGradient3822);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + sodipodi:type="arc" + transform="matrix(2.563158,0.000000,0.000000,1.219602,-55.98414,14.04144)" /> + <path + sodipodi:nodetypes="cccc" + id="path14341" + d="M 18.587591,1.403729 L 4.226755,18.096665 L 5.4854717,19.339844 L 18.587591,1.403729 z " + style="color:#000000;fill:url(#linearGradient4307);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> + <path + sodipodi:nodetypes="cccc" + id="path18921" + d="M 18.467176,1.3138035 L 5.6605716,19.072612 L 7.4900985,20.687913 L 18.467176,1.3138035 z " + style="fill:#fefefe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" /> + <path + transform="matrix(1.431529,0.000000,0.000000,1.431529,0.569459,-1.654618)" + d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z" + sodipodi:ry="14.910714" + sodipodi:rx="14.910714" + sodipodi:cy="16.910715" + sodipodi:cx="16.25" + id="path27786" + style="fill:url(#radialGradient5212);fill-opacity:1;fill-rule:evenodd;stroke:#605773;stroke-width:0.69855404;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" + sodipodi:type="arc" /> + <path + transform="matrix(1.163838,0.000000,0.000000,1.163838,4.824801,2.777556)" + d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z" + sodipodi:ry="14.910714" + sodipodi:rx="14.910714" + sodipodi:cy="16.910715" + sodipodi:cx="16.25" + id="path35549" + style="fill:url(#radialGradient4311);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4313);stroke-width:0.71139598;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" + sodipodi:type="arc" /> + <path + sodipodi:type="arc" + style="opacity:1;color:#000000;fill:url(#radialGradient5202);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5210);stroke-width:0.56498736;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + id="path4120" + sodipodi:cx="23.375" + sodipodi:cy="11.875" + sodipodi:rx="8.5" + sodipodi:ry="8.5" + d="M 16.679382,6.6387137 A 8.5,8.5 0 0 1 23.332691,3.3751053 L 23.375,11.875 z" + transform="matrix(1.769951,0.000000,0.000000,1.769951,-17.02424,1.610741)" + sodipodi:start="3.8052902" + sodipodi:end="4.7074114" /> + <path + transform="matrix(2.073295,0.000000,0.000000,2.073295,-7.310224,-13.13682)" + d="M 16.40625 17.28125 A 1.21875 1.21875 0 1 1 13.96875,17.28125 A 1.21875 1.21875 0 1 1 16.40625 17.28125 z" + sodipodi:ry="1.21875" + sodipodi:rx="1.21875" + sodipodi:cy="17.28125" + sodipodi:cx="15.1875" + id="path34778" + style="fill:#f3f3f3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.48232403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;stroke-dasharray:none" + sodipodi:type="arc" /> + <path + id="path35559" + d="M 22.176614,20.718014 L 13.155702,13.140282" + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + id="path35561" + d="M 19.408614,29.776506 L 22.368655,25.283228" + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + sodipodi:nodetypes="cc" /> + <path + transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,-12.40939)" + d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z" + sodipodi:ry="0.61871845" + sodipodi:rx="0.61871845" + sodipodi:cy="7.6932044" + sodipodi:cx="16.705399" + id="path35563" + style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1" + sodipodi:type="arc" /> + <path + transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,14.80922)" + d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z" + sodipodi:ry="0.61871845" + sodipodi:rx="0.61871845" + sodipodi:cy="7.6932044" + sodipodi:cx="16.705399" + id="path35565" + style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1" + sodipodi:type="arc" /> + <path + transform="matrix(2.749493,0.000000,0.000000,2.749493,-35.91004,1.199890)" + d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z" + sodipodi:ry="0.61871845" + sodipodi:rx="0.61871845" + sodipodi:cy="7.6932044" + sodipodi:cx="16.705399" + id="path35567" + style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1" + sodipodi:type="arc" /> + <path + transform="matrix(2.749493,0.000000,0.000000,2.749493,-8.691448,1.199890)" + d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z" + sodipodi:ry="0.61871845" + sodipodi:rx="0.61871845" + sodipodi:cy="7.6932044" + sodipodi:cx="16.705399" + id="path35569" + style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1" + sodipodi:type="arc" /> + <path + sodipodi:type="arc" + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient4309);stroke-width:0.73656511;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" + id="path10651" + sodipodi:cx="16.25" + sodipodi:cy="16.910715" + sodipodi:rx="14.910714" + sodipodi:ry="14.910714" + d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z" + transform="matrix(1.357654,0.000000,0.000000,1.357654,1.769896,-0.493735)" /> + <path + sodipodi:type="arc" + style="color:#000000;fill:url(#radialGradient278);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.25000024;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block" + id="path12511" + sodipodi:cx="55" + sodipodi:cy="125" + sodipodi:rx="14.375" + sodipodi:ry="14.375" + d="M 69.375 125 A 14.375 14.375 0 1 1 40.625,125 A 14.375 14.375 0 1 1 69.375 125 z" + transform="matrix(0.611127,0.000000,0.000000,0.611127,5.544052,-66.92818)" + inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/stock_new-16.png" + inkscape:export-xdpi="33.852203" + inkscape:export-ydpi="33.852203" /> + </g> +</svg> diff --git a/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/index.theme b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/index.theme new file mode 100644 index 00000000000..6ab6c15c42c --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/icons/testtheme/index.theme @@ -0,0 +1,21 @@ +[Icon Theme] +Name=Test +Comment=Test Theme + +Directories=16x16/actions,22x22/actions,22x22@2/actions + +[16x16/actions] +Size=16 +Context=Actions +Type=Fixed + +[22x22/actions] +Size=22 +Context=Actions +Type=Fixed + +[22x22@2/actions] +Size=22 +Context=Actions +Scale=2 +Type=Fixed diff --git a/tests/auto/quickcontrols2/qquickiconimage/resources.qrc b/tests/auto/quickcontrols2/qquickiconimage/resources.qrc new file mode 100644 index 00000000000..6558b039099 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/resources.qrc @@ -0,0 +1,17 @@ +<RCC> + <qresource prefix="/"> + <file>icons/testtheme/16x16/actions/appointment-new.png</file> + <file>icons/testtheme/22x22/actions/appointment-new.png</file> + <file>icons/testtheme/22x22/actions/appointment-new@2x.png</file> + <file>icons/testtheme/22x22@2/actions/appointment-new.png</file> + <file>icons/testtheme/22x22/actions/+testselector/appointment-new.png</file> + <file>icons/testtheme/22x22/actions/+testselector/appointment-new@2x.png</file> + <file>icons/testtheme/22x22@2/actions/+testselector/appointment-new.png</file> + <file>icons/testtheme/index.theme</file> + <file>icons/testtheme/appointment-new.svg</file> + <file>icons/testtheme/22x22/actions/color-test-original.png</file> + <file>icons/testtheme/22x22/actions/color-test-tinted.png</file> + <file>icons/testtheme/22x22/actions/color-test-original@2x.png</file> + <file>icons/testtheme/22x22/actions/color-test-tinted@2x.png</file> + </qresource> +</RCC> diff --git a/tests/auto/quickcontrols2/qquickiconimage/tst_qquickiconimage.cpp b/tests/auto/quickcontrols2/qquickiconimage/tst_qquickiconimage.cpp new file mode 100644 index 00000000000..3aaa91967e9 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconimage/tst_qquickiconimage.cpp @@ -0,0 +1,573 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <qtest.h> +#include <QtTest/qsignalspy.h> + +#include <QtCore/qmath.h> +#include <QtQml/qqmlapplicationengine.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlfileselector.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickview.h> +#include <QtQuick/qquickimageprovider.h> +#include <QtQuick/qquickitemgrabresult.h> +#include <QtQuick/private/qquickimage_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickControls2/qquickstyle.h> +#include <QtQuickControls2Impl/private/qquickiconimage_p.h> + +using namespace QQuickVisualTestUtils; + +class tst_qquickiconimage : public QQmlDataTest +{ + Q_OBJECT +public: + tst_qquickiconimage(); + +private slots: + void initTestCase() override; + void defaults(); + void nameBindingSourceSize(); + void nameBindingSourceSizeWidthHeight(); + void nameBindingNoSizes(); + void sourceBindingNoSizes(); + void sourceBindingSourceSize(); + void sourceBindingSourceSizeWidthHeight(); + void sourceBindingSourceTooLarge(); + void changeSourceSize(); + void alignment_data(); + void alignment(); + void svgNoSizes(); + void svgSourceBindingSourceSize(); + void color(); + void fileSelectors(); + void imageProvider(); + void translucentColors(); + +private: + void setTheme(); + + qreal dpr; + int integerDpr; +}; + +static QImage grabItemToImage(QQuickItem *item) +{ + QSharedPointer<QQuickItemGrabResult> result = item->grabToImage(); + QSignalSpy spy(result.data(), SIGNAL(ready())); + spy.wait(); + return result->image(); +} + +#define SKIP_IF_DPR_TOO_HIGH() \ + if (dpr > 2) \ + QSKIP("Test does not support device pixel ratio greater than 2") + +tst_qquickiconimage::tst_qquickiconimage() : + QQmlDataTest(QT_QMLTEST_DATADIR), + dpr(qGuiApp->devicePixelRatio()), + integerDpr(qCeil(dpr)) +{ + QQuickStyle::setStyle("Basic"); +} + +void tst_qquickiconimage::initTestCase() +{ + QQmlDataTest::initTestCase(); + QIcon::setThemeName(QStringLiteral("testtheme")); +} + +void tst_qquickiconimage::defaults() +{ + QQuickIconImage iconImage; + QCOMPARE(iconImage.fillMode(), QQuickImage::Pad); + QCOMPARE(iconImage.name(), QString()); + QCOMPARE(iconImage.source(), QUrl()); + QCOMPARE(iconImage.color(), QColor(Qt::transparent)); +} + +void tst_qquickiconimage::nameBindingSourceSize() +{ + // We can't have images for every DPR. + SKIP_IF_DPR_TOO_HIGH(); + + QQuickView view(testFileUrl("nameBindingSourceSize.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()->childItems().at(0)); + QVERIFY(iconImage); + + QQuickItem *image = view.rootObject()->childItems().at(1); + QVERIFY(image); + + QCOMPARE(grabItemToImage(iconImage), grabItemToImage(image)); + QCOMPARE(iconImage->sourceSize().width(), 22); + QCOMPARE(iconImage->sourceSize().height(), 22); + QCOMPARE(iconImage->implicitWidth(), 22.0); + QCOMPARE(iconImage->implicitHeight(), 22.0); + QCOMPARE(iconImage->width(), 22.0); + QCOMPARE(iconImage->height(), 22.0); + + // The requested width of 16 is less than the pixmap's size on disk which + // is 22x22. Our default fillMode, Pad, would result in the image being clipped, + // so instead we change the fillMode to PreserveAspectFit. Doing so causes + // QQuickImage::updatePaintedGeometry() to set our implicit size to 22x16 to + // ensure that the aspect ratio is respected. Since we have no explicit height, + // the height (previously 22) becomes the implicit height (16). + iconImage->setWidth(16.0); + QCOMPARE(iconImage->fillMode(), QQuickImage::PreserveAspectFit); + QCOMPARE(iconImage->sourceSize().width(), 22); + QCOMPARE(iconImage->sourceSize().height(), 22); + QCOMPARE(iconImage->implicitWidth(), 22.0); + QCOMPARE(iconImage->implicitHeight(), 16.0); + QCOMPARE(iconImage->width(), 16.0); + QCOMPARE(iconImage->height(), 16.0); +} + +void tst_qquickiconimage::nameBindingSourceSizeWidthHeight() +{ + SKIP_IF_DPR_TOO_HIGH(); + + QQuickView view(testFileUrl("nameBindingSourceSizeWidthHeight.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()); + QVERIFY(iconImage); + QCOMPARE(iconImage->sourceSize().width(), 22); + QCOMPARE(iconImage->sourceSize().height(), 22); + QCOMPARE(iconImage->implicitWidth(), 22.0); + QCOMPARE(iconImage->implicitHeight(), 22.0); + QCOMPARE(iconImage->width(), 16.0); + QCOMPARE(iconImage->height(), 16.0); +} + +void tst_qquickiconimage::nameBindingNoSizes() +{ + SKIP_IF_DPR_TOO_HIGH(); + + QQuickView view(testFileUrl("nameBindingNoSizes.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()); + QVERIFY(iconImage); + // The smallest available size will be chosen. + QCOMPARE(iconImage->sourceSize().width(), 16); + QCOMPARE(iconImage->sourceSize().height(), 16); + QCOMPARE(iconImage->implicitWidth(), 16.0); + QCOMPARE(iconImage->implicitHeight(), 16.0); + QCOMPARE(iconImage->width(), 16.0); + QCOMPARE(iconImage->height(), 16.0); +} + +void tst_qquickiconimage::sourceBindingNoSizes() +{ + SKIP_IF_DPR_TOO_HIGH(); + + QQuickView view(testFileUrl("sourceBindingNoSizes.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()->childItems().at(0)); + QVERIFY(iconImage); + + QQuickItem *image = view.rootObject()->childItems().at(1); + QVERIFY(image); + + QCOMPARE(iconImage->sourceSize().width(), 22 * integerDpr); + QCOMPARE(iconImage->sourceSize().height(), 22 * integerDpr); + QCOMPARE(iconImage->implicitWidth(), 22.0); + QCOMPARE(iconImage->implicitHeight(), 22.0); + QCOMPARE(iconImage->width(), 22.0); + QCOMPARE(iconImage->height(), 22.0); + QCOMPARE(grabItemToImage(iconImage), grabItemToImage(image)); +} + +void tst_qquickiconimage::sourceBindingSourceSize() +{ + SKIP_IF_DPR_TOO_HIGH(); + + QQuickView view(testFileUrl("sourceBindingSourceSize.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()->childItems().at(0)); + QVERIFY(iconImage); + + QQuickItem *image = view.rootObject()->childItems().at(1); + QVERIFY(image); + + QCOMPARE(iconImage->sourceSize().width(), 22); + QCOMPARE(iconImage->sourceSize().height(), 22); + QCOMPARE(iconImage->implicitWidth(), 22.0); + QCOMPARE(iconImage->implicitHeight(), 22.0); + QCOMPARE(iconImage->width(), 22.0); + QCOMPARE(iconImage->height(), 22.0); + QCOMPARE(grabItemToImage(iconImage), grabItemToImage(image)); + + // Changing width and height should not affect sourceSize. + iconImage->setWidth(50); + QCOMPARE(iconImage->sourceSize().width(), 22); + QCOMPARE(iconImage->sourceSize().height(), 22); + iconImage->setHeight(50); + QCOMPARE(iconImage->sourceSize().width(), 22); + QCOMPARE(iconImage->sourceSize().height(), 22); +} + +void tst_qquickiconimage::sourceBindingSourceSizeWidthHeight() +{ + SKIP_IF_DPR_TOO_HIGH(); + + QQuickView view(testFileUrl("sourceBindingSourceSizeWidthHeight.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()); + QVERIFY(iconImage); + QCOMPARE(iconImage->sourceSize().width(), 22); + QCOMPARE(iconImage->sourceSize().height(), 22); + QCOMPARE(iconImage->implicitWidth(), 22.0); + QCOMPARE(iconImage->implicitHeight(), 22.0); + QCOMPARE(iconImage->width(), 16.0); + QCOMPARE(iconImage->height(), 16.0); +} + +void tst_qquickiconimage::sourceBindingSourceTooLarge() +{ + SKIP_IF_DPR_TOO_HIGH(); + + QQuickView view(testFileUrl("sourceBindingSourceTooLarge.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()); + QVERIFY(iconImage); + QCOMPARE(iconImage->sourceSize().width(), 32); + QCOMPARE(iconImage->sourceSize().height(), 32); + QCOMPARE(iconImage->implicitWidth(), 22.0); + QCOMPARE(iconImage->implicitHeight(), 22.0); + QCOMPARE(iconImage->width(), 22.0); + QCOMPARE(iconImage->height(), 22.0); +} + +void tst_qquickiconimage::alignment_data() +{ + QTest::addColumn<QQuickImage::HAlignment>("horizontalAlignment"); + QTest::addColumn<QQuickImage::VAlignment>("verticalAlignment"); + + QTest::newRow("AlignLeft,AlignTop") << QQuickImage::AlignLeft << QQuickImage::AlignTop; + QTest::newRow("AlignLeft,AlignVCenter") << QQuickImage::AlignLeft << QQuickImage::AlignVCenter; + QTest::newRow("AlignLeft,AlignBottom") << QQuickImage::AlignLeft << QQuickImage::AlignBottom; + QTest::newRow("AlignHCenter,AlignTop") << QQuickImage::AlignHCenter << QQuickImage::AlignTop; + QTest::newRow("AlignHCenter,AlignVCenter") << QQuickImage::AlignHCenter << QQuickImage::AlignVCenter; + QTest::newRow("AlignHCenter,AlignBottom") << QQuickImage::AlignHCenter << QQuickImage::AlignBottom; + QTest::newRow("AlignRight,AlignTop") << QQuickImage::AlignRight << QQuickImage::AlignTop; + QTest::newRow("AlignRight,AlignVCenter") << QQuickImage::AlignRight << QQuickImage::AlignVCenter; + QTest::newRow("AlignRight,AlignBottom") << QQuickImage::AlignRight << QQuickImage::AlignBottom; +} + +void tst_qquickiconimage::alignment() +{ + SKIP_IF_DPR_TOO_HIGH(); + + QFETCH(QQuickImage::HAlignment, horizontalAlignment); + QFETCH(QQuickImage::VAlignment, verticalAlignment); + + QQuickView view(testFileUrl("alignment.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()->childItems().at(0)); + QVERIFY(iconImage); + + QQuickImage *image = qobject_cast<QQuickImage*>(view.rootObject()->childItems().at(1)); + QVERIFY(image); + + // The default fillMode for IconImage is Image::Pad, so these two grabs + // should only be equal when the device pixel ratio is 1 or 2, as there is no + // @3x version of the image, and hence the Image will be upscaled + // and therefore blurry when the ratio is higher than 2. + if (qGuiApp->devicePixelRatio() <= 2) + QCOMPARE(grabItemToImage(iconImage), grabItemToImage(image)); + else + QVERIFY(grabItemToImage(iconImage) != grabItemToImage(image)); + + // Check that the images are what we expect in different alignment configurations. + iconImage->setWidth(200); + iconImage->setHeight(100); + iconImage->setHorizontalAlignment(horizontalAlignment); + iconImage->setVerticalAlignment(verticalAlignment); + iconImage->setFillMode(QQuickImage::Pad); + image->setWidth(200); + image->setHeight(100); + image->setHorizontalAlignment(horizontalAlignment); + image->setVerticalAlignment(verticalAlignment); + image->setFillMode(QQuickImage::Pad); + + if (qGuiApp->devicePixelRatio() <= 2) + QCOMPARE(grabItemToImage(iconImage), grabItemToImage(image)); + else + QVERIFY(grabItemToImage(iconImage) != grabItemToImage(image)); +} + +void tst_qquickiconimage::svgNoSizes() +{ +#ifndef QT_SVG_LIB + QSKIP("This test requires qtsvg"); +#else + QQuickView view(testFileUrl("svgNoSizes.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()->childItems().at(0)); + QVERIFY(iconImage); + + QQuickImage *image = qobject_cast<QQuickImage*>(view.rootObject()->childItems().at(1)); + QVERIFY(image); + + QCOMPARE(iconImage->sourceSize().width(), 48); + QCOMPARE(iconImage->sourceSize().height(), 48); + QCOMPARE(iconImage->implicitWidth(), 48.0); + QCOMPARE(iconImage->implicitHeight(), 48.0); + QCOMPARE(iconImage->width(), 48.0); + QCOMPARE(iconImage->height(), 48.0); + QCOMPARE(grabItemToImage(iconImage), grabItemToImage(image)); +#endif +} + +void tst_qquickiconimage::svgSourceBindingSourceSize() +{ +#ifndef QT_SVG_LIB + QSKIP("This test requires qtsvg"); +#else + QQuickView view(testFileUrl("alignment.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()->childItems().at(0)); + QVERIFY(iconImage); + + QQuickImage *image = qobject_cast<QQuickImage*>(view.rootObject()->childItems().at(1)); + QVERIFY(image); + + QCOMPARE(iconImage->sourceSize().width(), 22); + QCOMPARE(iconImage->sourceSize().height(), 22); + QCOMPARE(iconImage->implicitWidth(), 22.0); + QCOMPARE(iconImage->implicitHeight(), 22.0); + QCOMPARE(iconImage->width(), 22.0); + QCOMPARE(iconImage->height(), 22.0); + QCOMPARE(grabItemToImage(iconImage), grabItemToImage(image)); +#endif +} + +void tst_qquickiconimage::color() +{ + SKIP_IF_DPR_TOO_HIGH(); + + if (QGuiApplication::platformName() == QLatin1String("offscreen")) + QSKIP("grabToImage() doesn't work on the \"offscreen\" platform plugin (QTBUG-63185)"); + + QQuickView view(testFileUrl("color.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()->childItems().at(0)); + QVERIFY(iconImage); + + QQuickImage *image = qobject_cast<QQuickImage*>(view.rootObject()->childItems().at(1)); + QVERIFY(image); + + QImage iconImageWindowGrab = grabItemToImage(iconImage); + QCOMPARE(iconImageWindowGrab, grabItemToImage(image)); + + // Transparent pixels should remain transparent. + QCOMPARE(iconImageWindowGrab.pixelColor(0, 0), QColor(0, 0, 0, 0)); + + // Set a color after component completion. + iconImage->setColor(QColor(Qt::green)); + iconImageWindowGrab = grabItemToImage(iconImage); + const QPoint centerPixelPos(11, 11); + QCOMPARE(iconImageWindowGrab.pixelColor(centerPixelPos), QColor(Qt::green)); + + // Set a semi-transparent color after component completion. + iconImage->setColor(QColor(0, 0, 255, 127)); + iconImageWindowGrab = grabItemToImage(iconImage); + QCOMPARE(iconImageWindowGrab.pixelColor(centerPixelPos).red(), 0); + QCOMPARE(iconImageWindowGrab.pixelColor(centerPixelPos).green(), 0); + QCOMPARE(iconImageWindowGrab.pixelColor(centerPixelPos).blue(), 255); + QCOMPARE(iconImageWindowGrab.pixelColor(centerPixelPos).alpha(), 127); +} + +void tst_qquickiconimage::changeSourceSize() +{ + QQuickView view(testFileUrl("sourceBindingSourceSize.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()->childItems().at(0)); + QVERIFY(iconImage); + + // Ensure that there isn't any infinite recursion when trying to change the sourceSize. + QSize sourceSize = iconImage->sourceSize(); + sourceSize.setWidth(sourceSize.width() - 1); + iconImage->setSourceSize(sourceSize); +} + + +void tst_qquickiconimage::fileSelectors() +{ + SKIP_IF_DPR_TOO_HIGH(); + + if (QGuiApplication::platformName() == QLatin1String("offscreen")) + QSKIP("grabToImage() doesn't work on the \"offscreen\" platform plugin (QTBUG-63185)"); + + QQuickView view; + QQmlFileSelector* fileSelector = new QQmlFileSelector(view.engine()); + fileSelector->setExtraSelectors(QStringList() << "testselector"); + view.setSource(testFileUrl("fileSelectors.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()->childItems().at(0)); + QVERIFY(iconImage); + + QQuickItem *image = view.rootObject()->childItems().at(1); + QVERIFY(image); + + QImage iconImageWindowGrab = grabItemToImage(iconImage); + QCOMPARE(iconImageWindowGrab, grabItemToImage(image)); + + QCOMPARE(iconImageWindowGrab.pixelColor(iconImageWindowGrab.width() / 2, iconImageWindowGrab.height() / 2), QColor(Qt::blue)); +} + +class TestImageProvider : public QQuickImageProvider +{ +public: + TestImageProvider() : QQuickImageProvider(QQuickImageProvider::Pixmap) { } + + QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override + { + QSize defaultSize(32, 32); + if (size) + *size = defaultSize; + + QPixmap pixmap(requestedSize.width() > 0 ? requestedSize.width() : defaultSize.width(), + requestedSize.height() > 0 ? requestedSize.height() : defaultSize.height()); + pixmap.fill(QColor(id).rgba()); + return pixmap; + } +}; + +// don't crash (QTBUG-63959) +void tst_qquickiconimage::imageProvider() +{ + if (QGuiApplication::platformName() == QLatin1String("offscreen")) + QSKIP("grabToImage() doesn't work on the \"offscreen\" platform plugin (QTBUG-63185)"); + + QQuickView view; + view.engine()->addImageProvider("provider", new TestImageProvider); + view.setSource(testFileUrl("imageProvider.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(view.rootObject()->findChild<QQuickIconImage *>()); + QVERIFY(iconImage); + + QImage image = grabItemToImage(iconImage); + QVERIFY(!image.isNull()); + QCOMPARE(image.pixelColor(image.width() / 2, image.height() / 2), QColor(Qt::red)); +} + +/* + QQuickIconImage::componentComplete() calls QQuickIconImagePrivate::updateIcon(), + which loads the icon's image via QQuickImageBase::load(). That eventually calls + QQuickImageBase::requestFinished(), which calls QQuickIconImage::pixmapChange(). + That then calls QQuickIconImagePrivate::updateFillMode(), which can in turn + cause QQuickIconImage::pixmapChange() to be called again, causing recursion. + + This was a problem because it resulted in icon.color being applied twice. + + This test checks that that doesn't happen. +*/ +void tst_qquickiconimage::translucentColors() +{ + if (QGuiApplication::platformName() == QLatin1String("offscreen")) + QSKIP("grabToImage() doesn't work on the \"offscreen\" platform plugin (QTBUG-63185)"); + + // Doesn't reproduce with QQuickView. + QQmlApplicationEngine engine; + engine.load(testFileUrl("translucentColors.qml")); + QQuickWindow *window = qobject_cast<QQuickWindow*>(engine.rootObjects().first()); + + QQuickIconImage *iconImage = qobject_cast<QQuickIconImage*>(window->findChild<QQuickIconImage*>()); + QVERIFY(iconImage); + + const QImage image = grabItemToImage(iconImage); + QVERIFY(!image.isNull()); + QCOMPARE(image.pixelColor(image.width() / 2, image.height() / 2), QColor::fromRgba(0x80000000)); +} + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + Q_UNUSED(app); + tst_qquickiconimage test; + QTEST_SET_MAIN_SOURCE_PATH + return QTest::qExec(&test, argc, argv); +} + +#include "tst_qquickiconimage.moc" diff --git a/tests/auto/quickcontrols2/qquickiconlabel/CMakeLists.txt b/tests/auto/quickcontrols2/qquickiconlabel/CMakeLists.txt new file mode 100644 index 00000000000..45c2d451601 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconlabel/CMakeLists.txt @@ -0,0 +1,50 @@ +# Generated from qquickiconlabel.pro. + +##################################################################### +## tst_qquickiconlabel Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickiconlabel + SOURCES + tst_qquickiconlabel.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + LIBRARIES + Qt::QuickControls2ImplPrivate + Qt::QuickPrivate + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::Qml + Qt::QmlPrivate + Qt::Quick + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickiconlabel CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickiconlabel CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickiconlabel/data/a.png b/tests/auto/quickcontrols2/qquickiconlabel/data/a.png new file mode 100644 index 00000000000..fe839a40e4d Binary files /dev/null and b/tests/auto/quickcontrols2/qquickiconlabel/data/a.png differ diff --git a/tests/auto/quickcontrols2/qquickiconlabel/data/colorChanges.qml b/tests/auto/quickcontrols2/qquickiconlabel/data/colorChanges.qml new file mode 100644 index 00000000000..cd69508eaf5 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconlabel/data/colorChanges.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +AbstractButton { + id: button + width: 200 + height: 200 + icon.source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png" + icon.color: enabled ? "transparent" : "red" + + IconLabel { + icon: button.icon + text: button.text + } +} diff --git a/tests/auto/quickcontrols2/qquickiconlabel/data/iconSourceContext.qml b/tests/auto/quickcontrols2/qquickiconlabel/data/iconSourceContext.qml new file mode 100644 index 00000000000..8cf09666d05 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconlabel/data/iconSourceContext.qml @@ -0,0 +1,18 @@ +import QtQuick +import QtQuick.Controls.Basic +import QtQuick.Controls.impl +import "sub" as Sub + +Item { + Image { source: "a.png" } + IconLabel { icon.source: "a.png" } + Button { + icon.color: "transparent" + icon.source: "a.png" + } + Button { + action: actions.action + icon.color: "transparent" + Sub.Actions { id: actions } + } +} diff --git a/tests/auto/quickcontrols2/qquickiconlabel/data/iconlabel.qml b/tests/auto/quickcontrols2/qquickiconlabel/data/iconlabel.qml new file mode 100644 index 00000000000..94f36a7b7ea --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconlabel/data/iconlabel.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +AbstractButton { + id: button + width: 200 + height: 200 + text: "Some text" + icon.source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png" + + IconLabel { + icon: button.icon + text: button.text + } +} diff --git a/tests/auto/quickcontrols2/qquickiconlabel/data/spacingWithOnlyIcon.qml b/tests/auto/quickcontrols2/qquickiconlabel/data/spacingWithOnlyIcon.qml new file mode 100644 index 00000000000..c00ffbb8079 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconlabel/data/spacingWithOnlyIcon.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +AbstractButton { + id: button + width: 200 + height: 200 + icon.source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png" + + IconLabel { + spacing: 10 + mirrored: true + icon: button.icon + } +} diff --git a/tests/auto/quickcontrols2/qquickiconlabel/data/spacingWithOnlyText.qml b/tests/auto/quickcontrols2/qquickiconlabel/data/spacingWithOnlyText.qml new file mode 100644 index 00000000000..20c61706b85 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconlabel/data/spacingWithOnlyText.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl + +Item { + width: 200 + height: 200 + + IconLabel { + spacing: 10 + text: "Some text" + } +} diff --git a/tests/auto/quickcontrols2/qquickiconlabel/data/sub/Actions.qml b/tests/auto/quickcontrols2/qquickiconlabel/data/sub/Actions.qml new file mode 100644 index 00000000000..20bd6a5e6b9 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconlabel/data/sub/Actions.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls.Basic + +QtObject { + readonly property Action action: Action { icon.source: "../a.png" } +} diff --git a/tests/auto/quickcontrols2/qquickiconlabel/tst_qquickiconlabel.cpp b/tests/auto/quickcontrols2/qquickiconlabel/tst_qquickiconlabel.cpp new file mode 100644 index 00000000000..13aad8b465e --- /dev/null +++ b/tests/auto/quickcontrols2/qquickiconlabel/tst_qquickiconlabel.cpp @@ -0,0 +1,372 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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/qlist.h> + +#include <qtest.h> + +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickview.h> +#include <QtQuick/qquickitemgrabresult.h> +#include <QtQuick/private/qquicktext_p.h> +#include <QtQuick/private/qquickimage_p_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickicon_p.h> +#include <QtQuickControls2Impl/private/qquickiconimage_p.h> +#include <QtQuickControls2Impl/private/qquickiconlabel_p.h> +#include <QtQuickControls2Impl/private/qquickiconlabel_p_p.h> + +using namespace QQuickVisualTestUtils; + +class tst_qquickiconlabel : public QQmlDataTest +{ + Q_OBJECT +public: + tst_qquickiconlabel(); + +private slots: + void display_data(); + void display(); + void spacingWithOneDelegate_data(); + void spacingWithOneDelegate(); + void emptyIconSource(); + void colorChanges(); + void iconSourceContext(); +}; + +tst_qquickiconlabel::tst_qquickiconlabel() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_qquickiconlabel::display_data() +{ + QTest::addColumn<QList<QQuickIconLabel::Display> >("displayTypes"); + QTest::addColumn<bool>("mirrored"); + QTest::addColumn<qreal>("labelWidth"); + QTest::addColumn<qreal>("labelHeight"); + QTest::addColumn<qreal>("spacing"); + + typedef QList<QQuickIconLabel::Display> DisplayVector; + QQuickIconLabel::Display IconOnly = QQuickIconLabel::IconOnly; + QQuickIconLabel::Display TextOnly = QQuickIconLabel::TextOnly; + QQuickIconLabel::Display TextUnderIcon = QQuickIconLabel::TextUnderIcon; + QQuickIconLabel::Display TextBesideIcon = QQuickIconLabel::TextBesideIcon; + + QTest::addRow("IconOnly") << (DisplayVector() << IconOnly) << false << -1.0 << -1.0 << 0.0; + QTest::addRow("TextOnly") << (DisplayVector() << TextOnly) << false << -1.0 << -1.0 << 0.0; + QTest::addRow("TextUnderIcon") << (DisplayVector() << TextUnderIcon) << false << -1.0 << -1.0 << 10.0; + QTest::addRow("TextBesideIcon") << (DisplayVector() << TextBesideIcon) << false << -1.0 << -1.0 << 10.0; + QTest::addRow("IconOnly, spacing=10") << (DisplayVector() << IconOnly) << false << -1.0 << -1.0 << 10.0; + QTest::addRow("TextOnly, spacing=10") << (DisplayVector() << TextOnly) << false << -1.0 << -1.0 << 10.0; + QTest::addRow("TextUnderIcon, spacing=10") << (DisplayVector() << TextUnderIcon) << false << -1.0 << -1.0 << 0.0; + QTest::addRow("TextUnderIcon => IconOnly => TextUnderIcon") + << (DisplayVector() << TextUnderIcon << IconOnly << TextUnderIcon) << false << -1.0 << -1.0 << 0.0; + QTest::addRow("TextUnderIcon => IconOnly => TextUnderIcon, labelWidth=400") + << (DisplayVector() << TextUnderIcon << IconOnly << TextUnderIcon) << false << 400.0 << -1.0 << 0.0; + QTest::addRow("TextUnderIcon => TextOnly => TextUnderIcon") + << (DisplayVector() << TextUnderIcon << TextOnly << TextUnderIcon) << false << -1.0 << -1.0 << 0.0; + QTest::addRow("TextUnderIcon => TextOnly => TextUnderIcon, labelWidth=400") + << (DisplayVector() << TextUnderIcon << TextOnly << TextUnderIcon) << false << 400.0 << -1.0 << 0.0; + QTest::addRow("TextBesideIcon, spacing=10") << (DisplayVector() << TextBesideIcon) << false << -1.0 << -1.0 << 0.0; + QTest::addRow("TextBesideIcon => IconOnly => TextBesideIcon") + << (DisplayVector() << TextBesideIcon << IconOnly << TextBesideIcon) << false << -1.0 << -1.0 << 0.0; + QTest::addRow("TextBesideIcon => IconOnly => TextBesideIcon, labelWidth=400") + << (DisplayVector() << TextBesideIcon << IconOnly << TextBesideIcon) << false << 400.0 << -1.0 << 0.0; + QTest::addRow("TextBesideIcon => TextOnly => TextBesideIcon") + << (DisplayVector() << TextBesideIcon << TextOnly << TextBesideIcon) << false << -1.0 << -1.0 << 0.0; + QTest::addRow("TextBesideIcon => TextOnly => TextBesideIcon, labelWidth=400") + << (DisplayVector() << TextBesideIcon << TextOnly << TextBesideIcon) << false << 400.0 << -1.0 << 0.0; + QTest::addRow("IconOnly, mirrored") << (DisplayVector() << IconOnly) << true << -1.0 << -1.0 << 0.0; + QTest::addRow("TextOnly, mirrored") << (DisplayVector() << TextOnly) << true << -1.0 << -1.0 << 0.0; + QTest::addRow("TextUnderIcon, mirrored") << (DisplayVector() << TextUnderIcon) << true << -1.0 << -1.0 << 0.0; + QTest::addRow("TextBesideIcon, mirrored") << (DisplayVector() << TextBesideIcon) << true << -1.0 << -1.0 << 0.0; +} + +void tst_qquickiconlabel::display() +{ + QFETCH(QList<QQuickIconLabel::Display>, displayTypes); + QFETCH(bool, mirrored); + QFETCH(qreal, labelWidth); + QFETCH(qreal, labelHeight); + QFETCH(qreal, spacing); + + QQuickView view(testFileUrl("iconlabel.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QQuickItem *rootItem = view.rootObject(); + QVERIFY(rootItem); + + QQuickIconLabel *label = rootItem->findChild<QQuickIconLabel *>(); + QVERIFY(label); + QCOMPARE(label->spacing(), 0.0); + QCOMPARE(label->display(), QQuickIconLabel::TextBesideIcon); + QCOMPARE(label->isMirrored(), false); + + // Setting labelWidth allows us to test the issue where the icon's + // width was not updated after switching between different display types. + if (!qFuzzyCompare(labelWidth, -1)) { + label->setWidth(labelWidth); + QCOMPARE(label->width(), labelWidth); + } + if (!qFuzzyCompare(labelHeight, -1)) { + label->setHeight(labelHeight); + QCOMPARE(label->height(), labelHeight); + } + + label->setMirrored(mirrored); + QCOMPARE(label->isMirrored(), mirrored); + + label->setSpacing(spacing); + QCOMPARE(label->spacing(), spacing); + + const qreal horizontalPadding = label->leftPadding() + label->rightPadding(); + const qreal verticalPadding = label->topPadding() + label->bottomPadding(); + + // Test that the icon and text are correctly positioned and sized after + // setting several different display types in succession. + for (QQuickIconLabel::Display displayType : qAsConst(displayTypes)) { + label->setDisplay(displayType); + QCOMPARE(label->display(), displayType); + + QQuickIconImage *icon = label->findChild<QQuickIconImage *>(); + QQuickText *text = label->findChild<QQuickText *>(); + + const qreal horizontalCenter = label->width() / 2; + const qreal verticalCenter = label->height() / 2; + + switch (displayType) { + case QQuickIconLabel::IconOnly: + QVERIFY(icon); + QVERIFY(!text); + QCOMPARE(icon->x(), horizontalCenter - icon->width() / 2); + QCOMPARE(icon->y(), verticalCenter - icon->height() / 2); + QCOMPARE(icon->width(), icon->implicitWidth()); + QCOMPARE(icon->height(), icon->implicitHeight()); + QCOMPARE(label->implicitWidth(), icon->implicitWidth() + horizontalPadding); + QCOMPARE(label->implicitHeight(), icon->implicitHeight() + verticalPadding); + break; + case QQuickIconLabel::TextOnly: + QVERIFY(!icon); + QVERIFY(text); + QCOMPARE(text->x(), horizontalCenter - text->width() / 2); + QCOMPARE(text->y(), verticalCenter - text->height() / 2); + QCOMPARE(text->width(), text->implicitWidth()); + QCOMPARE(text->height(), text->implicitHeight()); + QCOMPARE(label->implicitWidth(), text->implicitWidth() + horizontalPadding); + QCOMPARE(label->implicitHeight(), text->implicitHeight() + verticalPadding); + break; + case QQuickIconLabel::TextUnderIcon: { + QVERIFY(icon); + QVERIFY(text); + const qreal combinedHeight = icon->height() + label->spacing() + text->height(); + const qreal contentY = verticalCenter - combinedHeight / 2; + QCOMPARE(icon->x(), horizontalCenter - icon->width() / 2); + QCOMPARE(icon->y(), contentY); + QCOMPARE(icon->width(), icon->implicitWidth()); + QCOMPARE(icon->height(), icon->implicitHeight()); + QCOMPARE(text->x(), horizontalCenter - text->width() / 2); + QCOMPARE(text->y(), contentY + icon->height() + label->spacing()); + QCOMPARE(text->width(), text->implicitWidth()); + QCOMPARE(text->height(), text->implicitHeight()); + QCOMPARE(label->implicitWidth(), qMax(icon->implicitWidth(), text->implicitWidth()) + horizontalPadding); + QCOMPARE(label->implicitHeight(), combinedHeight + verticalPadding); + break; + } + case QQuickIconLabel::TextBesideIcon: + default: + QVERIFY(icon); + QVERIFY(text); + const qreal combinedWidth = icon->width() + label->spacing() + text->width(); + const qreal contentX = horizontalCenter - combinedWidth / 2; + QCOMPARE(icon->x(), contentX + (label->isMirrored() ? text->width() + label->spacing() : 0)); + QCOMPARE(icon->y(), verticalCenter - icon->height() / 2); + QCOMPARE(icon->width(), icon->implicitWidth()); + QCOMPARE(icon->height(), icon->implicitHeight()); + QCOMPARE(text->x(), contentX + (label->isMirrored() ? 0 : icon->width() + label->spacing())); + QCOMPARE(text->y(), verticalCenter - text->height() / 2); + QCOMPARE(text->width(), text->implicitWidth()); + QCOMPARE(text->height(), text->implicitHeight()); + QCOMPARE(label->implicitWidth(), combinedWidth + horizontalPadding); + QCOMPARE(label->implicitHeight(), qMax(icon->implicitHeight(), text->implicitHeight()) + verticalPadding); + break; + } + + if (text) + QCOMPARE(label->baselineOffset(), text->y() + text->baselineOffset()); + else + QCOMPARE(label->baselineOffset(), 0); + } +} + +void tst_qquickiconlabel::spacingWithOneDelegate_data() +{ + QTest::addColumn<QString>("qmlFileName"); + + QTest::addRow("spacingWithOnlyIcon") << QStringLiteral("spacingWithOnlyIcon.qml"); + QTest::addRow("spacingWithOnlyText") << QStringLiteral("spacingWithOnlyText.qml"); +} + +void tst_qquickiconlabel::spacingWithOneDelegate() +{ + QFETCH(QString, qmlFileName); + + QQuickView view(testFileUrl(qmlFileName)); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QQuickItem *rootItem = view.rootObject(); + QVERIFY(rootItem); + + QQuickIconLabel *label = rootItem->findChild<QQuickIconLabel *>(); + QVERIFY(label); + QQuickItem *delegate = nullptr; + if (!label->icon().isEmpty()) { + QVERIFY(!label->findChild<QQuickText *>()); + delegate = label->findChild<QQuickIconImage *>(); + } else { + QVERIFY(!label->findChild<QQuickIconImage *>()); + delegate = label->findChild<QQuickText *>(); + } + + QVERIFY(delegate); + QCOMPARE(delegate->x(), 0.0); + QCOMPARE(delegate->width(), label->width()); +} + +void tst_qquickiconlabel::emptyIconSource() +{ + QQuickView view(testFileUrl("iconlabel.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QQuickItem *rootItem = view.rootObject(); + QVERIFY(rootItem); + + QQuickIconLabel *label = rootItem->findChild<QQuickIconLabel *>(); + QVERIFY(label); + QCOMPARE(label->spacing(), 0.0); + QCOMPARE(label->display(), QQuickIconLabel::TextBesideIcon); + QCOMPARE(label->isMirrored(), false); + + QQuickItem *icon = label->findChild<QQuickIconImage *>(); + QVERIFY(icon); + + QQuickItem *text = label->findChild<QQuickText *>(); + QVERIFY(text); + qreal horizontalCenter = label->width() / 2; + const qreal combinedWidth = icon->width() + text->width(); + const qreal contentX = horizontalCenter - combinedWidth / 2; + // The text should be positioned next to an item. + QCOMPARE(text->x(), contentX + icon->width() + label->spacing()); + + // Now give the label an explicit width large enough so that implicit size + // changes in its children don't affect its implicit size. + label->setWidth(label->implicitWidth() + 200); + label->setHeight(label->implicitWidth() + 100); + QVERIFY(icon->property("source").isValid()); + label->setIcon(QQuickIcon()); + QVERIFY(!label->findChild<QQuickIconImage *>()); + horizontalCenter = label->width() / 2; + QCOMPARE(text->x(), horizontalCenter - text->width() / 2); +} + +void tst_qquickiconlabel::colorChanges() +{ + if (QGuiApplication::platformName() == QLatin1String("offscreen")) + QSKIP("grabToImage() doesn't work on the \"offscreen\" platform plugin (QTBUG-63185)"); + + QQuickView view(testFileUrl("colorChanges.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QQuickItem *rootItem = view.rootObject(); + QVERIFY(rootItem); + + QQuickIconLabel *label = rootItem->findChild<QQuickIconLabel *>(); + QVERIFY(label); + QCOMPARE(label->spacing(), 0.0); + QCOMPARE(label->display(), QQuickIconLabel::TextBesideIcon); + QCOMPARE(label->isMirrored(), false); + + QSharedPointer<QQuickItemGrabResult> grabResult = label->grabToImage(); + QTRY_VERIFY(!grabResult->image().isNull()); + const QImage enabledImageGrab = grabResult->image(); + + // The color should change to "red" when the item is disabled. + rootItem->setEnabled(false); + + grabResult = label->grabToImage(); + QTRY_VERIFY(!grabResult->image().isNull()); + QVERIFY(grabResult->image() != enabledImageGrab); +} + +void tst_qquickiconlabel::iconSourceContext() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("iconSourceContext.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + + QScopedPointer<QObject> o(component.create()); + QQuickItem *root = qobject_cast<QQuickItem *>(o.data()); + QVERIFY(root); + + for (QQuickItem *child : root->childItems()) { + QQuickImage *image = qobject_cast<QQuickImage *>(child); + if (!image) { + QQuickIconLabel *label = nullptr; + if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(child)) { + label = qobject_cast<QQuickIconLabel *>(button->contentItem()); + } else { + label = qobject_cast<QQuickIconLabel *>(child); + } + if (label) { + QQuickIconLabelPrivate *labelPrivate = static_cast<QQuickIconLabelPrivate *>( + QQuickItemPrivate::get(label)); + image = labelPrivate->image; + } + } + + QVERIFY(image); + QQuickImagePrivate *imagePrivate + = static_cast<QQuickImagePrivate *>(QQuickItemPrivate::get(image)); + QCOMPARE(imagePrivate->pix.url(), testFileUrl("a.png")); + } + +} + +QTEST_MAIN(tst_qquickiconlabel) + +#include "tst_qquickiconlabel.moc" diff --git a/tests/auto/quickcontrols2/qquickimaginestyle/BLACKLIST b/tests/auto/quickcontrols2/qquickimaginestyle/BLACKLIST new file mode 100644 index 00000000000..27e33c71b37 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickimaginestyle/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-102721 +[Imagine::test_qrcPaths] +android diff --git a/tests/auto/quickcontrols2/qquickimaginestyle/CMakeLists.txt b/tests/auto/quickcontrols2/qquickimaginestyle/CMakeLists.txt new file mode 100644 index 00000000000..2d1e534f980 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickimaginestyle/CMakeLists.txt @@ -0,0 +1,42 @@ +# Generated from qquickimaginestyle.pro. + +##################################################################### +## tst_qquickimaginestyle Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/tst_*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickimaginestyle + GUI + QMLTEST + SOURCES + tst_qquickimaginestyle.cpp + PUBLIC_LIBRARIES + Qt::Gui + TESTDATA ${test_data} +) + +# Resources: +set(qmake_immediate_resource_files + "control-assets/button-background.9.png" + "qtquickcontrols2.conf" + "test-assets/button-background-1.png" + "test-assets/button-background-2.png" + "test-assets/wobble.frag.qsb" +) + +qt_internal_add_resource(tst_qquickimaginestyle "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + + +#### Keys ignored in scope 1:.:.:qquickimaginestyle.pro:<TRUE>: +# OTHER_FILES = "$$PWD/data/*.qml" +# TEMPLATE = "app" diff --git a/tests/auto/quickcontrols2/qquickimaginestyle/control-assets/button-background.9.png b/tests/auto/quickcontrols2/qquickimaginestyle/control-assets/button-background.9.png new file mode 100644 index 00000000000..18ec9e6f4f8 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickimaginestyle/control-assets/button-background.9.png differ diff --git a/tests/auto/quickcontrols2/qquickimaginestyle/data/tst_imagine.qml b/tests/auto/quickcontrols2/qquickimaginestyle/data/tst_imagine.qml new file mode 100644 index 00000000000..c7afe4fbbfd --- /dev/null +++ b/tests/auto/quickcontrols2/qquickimaginestyle/data/tst_imagine.qml @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtTest +import QtQuick.Templates as T +import QtQuick.Controls +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "Imagine" + + Component { + id: buttonComponent + Button {} + } + + Component { + id: implicitQrcButtonComponent + Button { + Imagine.path: ":/control-assets" + } + } + + Component { + id: explicitQrcButtonComponent + Button { + Imagine.path: "qrc:/control-assets" + } + } + + function test_qrcPaths_data() { + return [ + { tag: ":/control-assets", component: implicitQrcButtonComponent }, + { tag: "qrc:/control-assets", component: explicitQrcButtonComponent } + ] + } + + function test_qrcPaths(data) { + if (Qt.platform.pluginName === "offscreen") + skip("grabImage() is not functional on the offscreen platform (QTBUG-63185)") + + var control = createTemporaryObject(data.component, testCase) + verify(control) + compare(control.Imagine.path, data.tag) + var image = grabImage(control) + compare(image.pixel(control.width / 2, control.height / 2), "#ff0000") + } + + function test_fontFromConfigFile() { + var control = createTemporaryObject(buttonComponent, testCase) + verify(control) + compare(control.font.pixelSize, 80) + } + + Component { + id: ninePatchImageComponent + + NinePatchImage { + property alias mouseArea: mouseArea + + MouseArea { + id: mouseArea + anchors.fill: parent + // The name of the images isn't important; we just want to check that + // going from regular to 9-patch to regular to regular works without crashing. + onPressed: parent.source = "qrc:/control-assets/button-background.9.png" + onReleased: parent.source = "qrc:/test-assets/button-background-1.png" + onClicked: parent.source = "qrc:/test-assets/button-background-2.png" + } + } + } + + Component { + id: signalSpyComponent + + SignalSpy {} + } + + // QTBUG-78790 + function test_switchBetween9PatchAndRegular() { + var ninePatchImage = createTemporaryObject(ninePatchImageComponent, testCase, + { source: "qrc:/test-assets/button-background-1.png" }) + verify(ninePatchImage) + + var clickSpy = signalSpyComponent.createObject(ninePatchImage, + { target: ninePatchImage.mouseArea, signalName: "clicked" }) + verify(clickSpy.valid) + + var afterRenderingSpy = signalSpyComponent.createObject(ninePatchImage, + { target: testCase.Window.window, signalName: "afterRendering" }) + verify(afterRenderingSpy.valid) + + mousePress(ninePatchImage) + // Wait max 1 second - in reality it should take a handful of milliseconds. + afterRenderingSpy.wait(1000) + mouseRelease(ninePatchImage) + compare(clickSpy.count, 1) + // Shouldn't result in a crash. + afterRenderingSpy.wait(1000) + } + + Component { + id: invalidNinePatchImageProvider + Item { + width: 200 + height: 200 + property alias ninePatchImage: np + + NinePatchImage { + id: np + source : "qrc:/test-assets/button-background-1.png" + cache: false + visible: false + } + + ShaderEffect { + width: 200 + height: 200 + property variant source: np + property real amplitude: 0.04 + property real frequency: 20 + property real time: 0 + fragmentShader: "qrc:/test-assets/wobble.frag.qsb" + } + } + } + + // QTBUG-100508 + function test_invalidNinePatchImageProvider() { + var container = createTemporaryObject(invalidNinePatchImageProvider, testCase) + verify(container); + var afterRenderingSpy = signalSpyComponent.createObject(null, + { target: testCase.Window.window, signalName: "afterRendering" }) + verify(afterRenderingSpy.valid) + + afterRenderingSpy.wait(1000) + container.ninePatchImage.source = "" + // Shouldn't result in a crash. + afterRenderingSpy.wait(1000) + } +} diff --git a/tests/auto/quickcontrols2/qquickimaginestyle/qtquickcontrols2.conf b/tests/auto/quickcontrols2/qquickimaginestyle/qtquickcontrols2.conf new file mode 100644 index 00000000000..cc58a8e3748 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickimaginestyle/qtquickcontrols2.conf @@ -0,0 +1,5 @@ +[Controls] +Style=Imagine + +[Imagine] +Font\PixelSize=80 diff --git a/tests/auto/quickcontrols2/qquickimaginestyle/test-assets/button-background-1.png b/tests/auto/quickcontrols2/qquickimaginestyle/test-assets/button-background-1.png new file mode 100644 index 00000000000..980eec3c921 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickimaginestyle/test-assets/button-background-1.png differ diff --git a/tests/auto/quickcontrols2/qquickimaginestyle/test-assets/button-background-2.png b/tests/auto/quickcontrols2/qquickimaginestyle/test-assets/button-background-2.png new file mode 100644 index 00000000000..8e2639d03b1 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickimaginestyle/test-assets/button-background-2.png differ diff --git a/tests/auto/quickcontrols2/qquickimaginestyle/test-assets/wobble.frag.qsb b/tests/auto/quickcontrols2/qquickimaginestyle/test-assets/wobble.frag.qsb new file mode 100644 index 00000000000..248c00b5262 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickimaginestyle/test-assets/wobble.frag.qsb differ diff --git a/tests/auto/quickcontrols2/qquickimaginestyle/tst_qquickimaginestyle.cpp b/tests/auto/quickcontrols2/qquickimaginestyle/tst_qquickimaginestyle.cpp new file mode 100644 index 00000000000..952428ef04f --- /dev/null +++ b/tests/auto/quickcontrols2/qquickimaginestyle/tst_qquickimaginestyle.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTest/quicktest.h> +QUICK_TEST_MAIN(tst_qquickimaginestyle) diff --git a/tests/auto/quickcontrols2/qquickmaterialstyle/CMakeLists.txt b/tests/auto/quickcontrols2/qquickmaterialstyle/CMakeLists.txt new file mode 100644 index 00000000000..332f376d9f1 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmaterialstyle/CMakeLists.txt @@ -0,0 +1,39 @@ +# Generated from qquickmaterialstyle.pro. + +##################################################################### +## tst_qquickmaterialstyle Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/tst_*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickmaterialstyle + GUI + QMLTEST + SOURCES + tst_qquickmaterialstyle.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Qml + TESTDATA ${test_data} +) + +# Resources: +set(qmake_immediate_resource_files + "qtquickcontrols2.conf" +) + +qt_internal_add_resource(tst_qquickmaterialstyle "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + + +#### Keys ignored in scope 1:.:.:qquickmaterialstyle.pro:<TRUE>: +# OTHER_FILES = "$$PWD/data/*.qml" +# TEMPLATE = "app" diff --git a/tests/auto/quickcontrols2/qquickmaterialstyle/data/tst_material.qml b/tests/auto/quickcontrols2/qquickmaterialstyle/data/tst_material.qml new file mode 100644 index 00000000000..02b71305fec --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmaterialstyle/data/tst_material.qml @@ -0,0 +1,791 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtTest +import QtQuick.Templates as T +import QtQuick.Controls +import QtQuick.Controls.Material + +import org.qtproject.Test + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "Material" + + Component { + id: button + Button { } + } + + Component { + id: styledButton + Button { + Material.theme: Material.Dark + Material.primary: Material.DeepOrange + Material.accent: Material.DeepPurple + Material.background: Material.Green + Material.foreground: Material.Blue + } + } + + Component { + id: window + Window { } + } + + Component { + id: applicationWindow + ApplicationWindow { } + } + + Component { + id: styledWindow + Window { + Material.theme: Material.Dark + Material.primary: Material.Brown + Material.accent: Material.Green + Material.background: Material.Yellow + Material.foreground: Material.Grey + } + } + + Component { + id: loader + Loader { + active: false + sourceComponent: Button { } + } + } + + Component { + id: swipeView + SwipeView { + Material.theme: Material.Dark + Button { } + } + } + + Component { + id: menu + ApplicationWindow { + Material.primary: Material.Blue + Material.accent: Material.Red + property alias menu: popup + Menu { + id: popup + Material.theme: Material.Dark + MenuItem { } + } + } + } + + Component { + id: popupComponent + ApplicationWindow { + Material.primary: Material.Blue + Material.accent: Material.Red + visible: true + property alias popup: popupInstance + property alias label: labelInstance + property alias label2: labelInstance2 + Popup { + id: popupInstance + Label { + id: labelInstance + text: "test" + color: popupInstance.Material.textSelectionColor + } + Component.onCompleted: open() + } + T.Popup { + contentItem: Label { + id: labelInstance2 + text: "test" + color: Material.textSelectionColor + } + Component.onCompleted: open() + } + } + } + + Component { + id: comboBox + ApplicationWindow { + width: 200 + height: 200 + visible: true + Material.primary: Material.Blue + Material.accent: Material.Red + property alias combo: box + ComboBox { + id: box + Material.theme: Material.Dark + model: 1 + } + } + } + + Component { + id: windowPane + ApplicationWindow { + width: 200 + height: 200 + visible: true + property alias pane: pane + Pane { id: pane } + } + } + + // need to be synced with QQuickMaterialStyle::themeShade() + function themeshade(theme) { + if (theme === Material.Light) + return Material.Shade500 + else + return Material.Shade200 + } + + function test_defaults() { + var control = button.createObject(testCase) + verify(control) + verify(control.Material) + compare(control.Material.primary, Material.color(Material.Indigo)) + compare(control.Material.accent, Material.color(Material.Pink)) + compare(control.Material.foreground, "#dd000000") + compare(control.Material.background, "#fafafa") + compare(control.Material.theme, Material.Light) + control.destroy() + } + + function test_set() { + var control = button.createObject(testCase) + verify(control) + control.Material.primary = Material.Green + control.Material.accent = Material.Brown + control.Material.background = Material.Red + control.Material.foreground = Material.Blue + control.Material.theme = Material.Dark + compare(control.Material.primary, Material.color(Material.Green)) + compare(control.Material.accent, Material.color(Material.Brown, themeshade(control.Material.theme))) + compare(control.Material.background, Material.color(Material.Red, themeshade(control.Material.theme))) + compare(control.Material.foreground, Material.color(Material.Blue)) + compare(control.Material.theme, Material.Dark) + control.destroy() + } + + function test_reset() { + var control = styledButton.createObject(testCase) + verify(control) + compare(control.Material.primary, Material.color(Material.DeepOrange)) + compare(control.Material.accent, Material.color(Material.DeepPurple, themeshade(control.Material.theme))) + compare(control.Material.background, Material.color(Material.Green, themeshade(control.Material.theme))) + compare(control.Material.foreground, Material.color(Material.Blue)) + compare(control.Material.theme, Material.Dark) + control.Material.primary = undefined + control.Material.accent = undefined + control.Material.background = undefined + control.Material.foreground = undefined + control.Material.theme = undefined + compare(control.Material.primary, testCase.Material.primary) + compare(control.Material.accent, testCase.Material.accent) + compare(control.Material.background, testCase.Material.background) + compare(control.Material.foreground, testCase.Material.foreground) + compare(control.Material.theme, testCase.Material.theme) + control.destroy() + } + + function test_inheritance_data() { + return [ + { tag: "primary", value1: Material.color(Material.Amber), value2: Material.color(Material.Indigo) }, + { tag: "accent", value1: Material.color(Material.Amber), value2: Material.color(Material.Indigo) }, + { tag: "background", value1: Material.color(Material.Amber), value2: Material.color(Material.Indigo) }, + { tag: "foreground", value1: Material.color(Material.Amber), value2: Material.color(Material.Indigo) }, + { tag: "theme", value1: Material.Dark, value2: Material.Light }, + ] + } + + function test_inheritance(data) { + var prop = data.tag + var parent = button.createObject(testCase) + parent.Material[prop] = data.value1 + compare(parent.Material[prop], data.value1) + + var child1 = button.createObject(parent) + compare(child1.Material[prop], data.value1) + + parent.Material[prop] = data.value2 + compare(parent.Material[prop], data.value2) + compare(child1.Material[prop], data.value2) + + var child2 = button.createObject(parent) + compare(child2.Material[prop], data.value2) + + child2.Material[prop] = data.value1 + compare(child2.Material[prop], data.value1) + compare(child1.Material[prop], data.value2) + compare(parent.Material[prop], data.value2) + + parent.Material[prop] = undefined + verify(parent.Material[prop] !== data.value1) + verify(parent.Material[prop] !== undefined) + compare(child1.Material[prop], parent.Material[prop]) + verify(child2.Material[prop] !== parent.Material[prop]) + + var grandChild1 = button.createObject(child1) + var grandChild2 = button.createObject(child2) + compare(grandChild1.Material[prop], child1.Material[prop]) + compare(grandChild2.Material[prop], child2.Material[prop]) + + var themelessGrandGrandChild = button.createObject(grandChild1) + var grandGrandGrandChild1 = button.createObject(themelessGrandGrandChild) + compare(grandGrandGrandChild1.Material[prop], parent.Material[prop]) + + child1.Material[prop] = data.value2 + compare(child1.Material[prop], data.value2) + compare(grandChild1.Material[prop], data.value2) + compare(grandGrandGrandChild1.Material[prop], data.value2) + + parent.destroy() + } + + function test_inheritance_popup_data() { + return [ + { tag: "primary", value1: Material.color(Material.Amber), value2: Material.color(Material.Indigo) }, + { tag: "accent", value1: Material.color(Material.Amber), value2: Material.color(Material.Indigo) }, + { tag: "theme", value1: Material.Dark, value2: Material.Light }, + ] + } + + function test_inheritance_popup(data) { + var prop = data.tag + var popupObject = popupComponent.createObject(testCase) + compare(popupObject.popup.Material.textSelectionColor.toString(), popupObject.Material.textSelectionColor.toString()) + compare(popupObject.label.color.toString(), popupObject.Material.textSelectionColor.toString()) + compare(popupObject.label2.color.toString(), popupObject.Material.textSelectionColor.toString()) + + popupObject.Material[prop] = data.value1 + compare(popupObject.Material[prop], data.value1) + compare(popupObject.popup.Material.textSelectionColor.toString(), popupObject.Material.textSelectionColor.toString()) + compare(popupObject.label.color.toString(), popupObject.Material.textSelectionColor.toString()) + compare(popupObject.label2.color.toString(), popupObject.Material.textSelectionColor.toString()) + + popupObject.Material[prop] = data.value2 + compare(popupObject.Material[prop], data.value2) + compare(popupObject.popup.Material.textSelectionColor.toString(), popupObject.Material.textSelectionColor.toString()) + compare(popupObject.label.color.toString(), popupObject.Material.textSelectionColor.toString()) + compare(popupObject.label2.color.toString(), popupObject.Material.textSelectionColor.toString()) + + popupObject.destroy() + } + + function test_window() { + var parent = window.createObject() + + var control = button.createObject(parent.contentItem) + compare(control.Material.primary, parent.Material.primary) + compare(control.Material.accent, parent.Material.accent) + compare(control.Material.background, parent.Material.background) + compare(control.Material.foreground, parent.Material.foreground) + compare(control.Material.theme, parent.Material.theme) + + var styledChild = styledWindow.createObject(window) + verify(styledChild.Material.primary !== parent.Material.primary) + verify(styledChild.Material.accent !== parent.Material.accent) + verify(styledChild.Material.background !== parent.Material.background) + verify(styledChild.Material.foreground !== parent.Material.foreground) + verify(styledChild.Material.theme !== parent.Material.theme) + + var unstyledChild = window.createObject(window) + compare(unstyledChild.Material.primary, parent.Material.primary) + compare(unstyledChild.Material.accent, parent.Material.accent) + compare(unstyledChild.Material.background, parent.Material.background) + compare(unstyledChild.Material.foreground, parent.Material.foreground) + compare(unstyledChild.Material.theme, parent.Material.theme) + + parent.Material.primary = Material.Lime + compare(control.Material.primary, Material.color(Material.Lime)) + verify(styledChild.Material.primary !== Material.color(Material.Lime)) + // ### TODO: compare(unstyledChild.Material.primary, Material.color(Material.Lime)) + + parent.Material.accent = Material.Cyan + compare(control.Material.accent, Material.color(Material.Cyan)) + verify(styledChild.Material.accent !== Material.color(Material.Cyan)) + // ### TODO: compare(unstyledChild.Material.accent, Material.color(Material.Cyan)) + + parent.Material.background = Material.Indigo + compare(control.Material.background, Material.color(Material.Indigo)) + verify(styledChild.Material.background !== Material.color(Material.Indigo)) + // ### TODO: compare(unstyledChild.Material.background, Material.color(Material.Indigo)) + + parent.Material.foreground = Material.Pink + compare(control.Material.foreground, Material.color(Material.Pink)) + verify(styledChild.Material.foreground !== Material.color(Material.Pink)) + // ### TODO: compare(unstyledChild.Material.foreground, Material.color(Material.Pink)) + + parent.destroy() + } + + function test_loader() { + var control = loader.createObject(testCase) + control.Material.primary = Material.Yellow + control.Material.accent = Material.Lime + control.Material.background = Material.LightGreen + control.Material.foreground = Material.LightBlue + control.active = true + compare(control.item.Material.primary, Material.color(Material.Yellow)) + compare(control.item.Material.accent, Material.color(Material.Lime)) + compare(control.item.Material.background, Material.color(Material.LightGreen)) + compare(control.item.Material.foreground, Material.color(Material.LightBlue)) + control.Material.primary = Material.Red + control.Material.accent = Material.Pink + control.Material.background = Material.Blue + control.Material.foreground = Material.Green + compare(control.item.Material.primary, Material.color(Material.Red)) + compare(control.item.Material.accent, Material.color(Material.Pink)) + compare(control.item.Material.background, Material.color(Material.Blue)) + compare(control.item.Material.foreground, Material.color(Material.Green)) + control.active = false + control.Material.primary = Material.Orange + control.Material.accent = Material.Brown + control.Material.background = Material.Red + control.Material.foreground = Material.Pink + control.active = true + compare(control.item.Material.primary, Material.color(Material.Orange)) + compare(control.item.Material.accent, Material.color(Material.Brown)) + compare(control.item.Material.background, Material.color(Material.Red)) + compare(control.item.Material.foreground, Material.color(Material.Pink)) + control.destroy() + } + + function test_swipeView() { + var control = swipeView.createObject(testCase) + verify(control) + var child = control.itemAt(0) + verify(child) + compare(control.Material.theme, Material.Dark) + compare(child.Material.theme, Material.Dark) + control.destroy() + } + + function test_menu() { + var container = menu.createObject(testCase) + verify(container) + verify(container.menu) + container.menu.open() + verify(container.menu.visible) + var child = container.menu.itemAt(0) + verify(child) + compare(container.Material.theme, Material.Light) + compare(container.menu.Material.theme, Material.Dark) + compare(child.Material.theme, Material.Dark) + compare(container.Material.primary, Material.color(Material.Blue)) + compare(container.menu.Material.primary, Material.color(Material.Blue)) + compare(child.Material.primary, Material.color(Material.Blue)) + compare(container.Material.accent, Material.color(Material.Red)) + compare(container.menu.Material.accent, Material.color(Material.Red, themeshade(container.menu.Material.theme))) + compare(child.Material.accent, Material.color(Material.Red, themeshade(child.Material.theme))) + container.destroy() + } + + function test_comboBox() { + var window = comboBox.createObject(testCase) + verify(window) + verify(window.combo) + waitForRendering(window.combo) + window.combo.forceActiveFocus() + verify(window.combo.activeFocus) + keyClick(Qt.Key_Space) + verify(window.combo.popup.visible) + var listView = window.combo.popup.contentItem + verify(listView) + var child = listView.contentItem.children[0] + verify(child) + compare(window.Material.theme, Material.Light) + compare(window.combo.Material.theme, Material.Dark) + compare(child.Material.theme, Material.Dark) + compare(window.Material.primary, Material.color(Material.Blue)) + compare(window.combo.Material.primary, Material.color(Material.Blue)) + compare(child.Material.primary, Material.color(Material.Blue)) + compare(window.Material.accent, Material.color(Material.Red)) + compare(window.combo.Material.accent, Material.color(Material.Red, themeshade(window.combo.Material.theme))) + compare(child.Material.accent, Material.color(Material.Red, themeshade(child.Material.theme))) + window.destroy() + } + + function test_windowChange() { + var ldr = loader.createObject() + verify(ldr) + + var wnd = window.createObject() + verify(wnd) + + wnd.Material.theme = Material.Dark + compare(wnd.Material.theme, Material.Dark) + + ldr.active = true + verify(ldr.item) + compare(ldr.item.Material.theme, Material.Light) + + ldr.parent = wnd.contentItem + compare(ldr.item.Material.theme, Material.Dark) + + wnd.destroy() + } + + function test_colors_data() { + return [ + { tag: "primary" }, { tag: "accent" }, { tag: "background" }, { tag: "foreground" } + ] + } + + function test_colors(data) { + var control = button.createObject(testCase) + verify(control) + + var prop = data.tag + + // Material.Color - enum + control.Material[prop] = Material.Red + compare(control.Material[prop], "#f44336") + + // Material.Color - string + control.Material[prop] = "BlueGrey" + compare(control.Material[prop], "#607d8b") + + // SVG named color + control.Material[prop] = "tomato" + compare(control.Material[prop], "#ff6347") + + // #rrggbb + control.Material[prop] = "#123456" + compare(control.Material[prop], "#123456") + + // #aarrggbb + control.Material[prop] = "#12345678" + compare(control.Material[prop], "#12345678") + + // Qt.rgba() - no alpha + control.Material[prop] = Qt.rgba(0.5, 0.5, 0.5) + compare(control.Material[prop], "#808080") + + // Qt.rgba() - with alpha + control.Material[prop] = Qt.rgba(0.5, 0.5, 0.5, 0.5) + compare(control.Material[prop], "#80808080") + + // unknown + ignoreWarning(new RegExp("QML Button: unknown Material." + prop + " value: 123")) + control.Material[prop] = 123 + ignoreWarning(new RegExp("QML Button: unknown Material." + prop + " value: foo")) + control.Material[prop] = "foo" + ignoreWarning(new RegExp("QML Button: unknown Material." + prop + " value: #1")) + control.Material[prop] = "#1" + + control.destroy() + } + + function test_font_data() { + return [ + {tag: "Button:pixelSize", type: "Button", attribute: "pixelSize", value: 14, window: 20, pane: 10}, + {tag: "Button:weight", type: "Button", attribute: "weight", value: Font.Medium, window: Font.Black, pane: Font.Bold}, + {tag: "Button:capitalization", type: "Button", attribute: "capitalization", value: Font.AllUppercase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "TabButton:pixelSize", type: "TabButton", attribute: "pixelSize", value: 14, window: 20, pane: 10}, + {tag: "TabButton:weight", type: "TabButton", attribute: "weight", value: Font.Medium, window: Font.Black, pane: Font.Bold}, + {tag: "TabButton:capitalization", type: "TabButton", attribute: "capitalization", value: Font.AllUppercase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "ToolButton:pixelSize", type: "ToolButton", attribute: "pixelSize", value: 14, window: 20, pane: 10}, + {tag: "ToolButton:weight", type: "ToolButton", attribute: "weight", value: Font.Medium, window: Font.Black, pane: Font.Bold}, + {tag: "ToolButton:capitalization", type: "ToolButton", attribute: "capitalization", value: Font.AllUppercase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "ItemDelegate:pixelSize", type: "ItemDelegate", attribute: "pixelSize", value: 14, window: 20, pane: 10}, + {tag: "ItemDelegate:weight", type: "ItemDelegate", attribute: "weight", value: Font.Medium, window: Font.Black, pane: Font.Bold}, + {tag: "ItemDelegate:capitalization", type: "ItemDelegate", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "CheckDelegate:pixelSize", type: "CheckDelegate", attribute: "pixelSize", value: 16, window: 20, pane: 10}, + {tag: "CheckDelegate:weight", type: "CheckDelegate", attribute: "weight", value: Font.Normal, window: Font.Black, pane: Font.Bold}, + {tag: "CheckDelegate:capitalization", type: "CheckDelegate", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "RadioDelegate:pixelSize", type: "RadioDelegate", attribute: "pixelSize", value: 16, window: 20, pane: 10}, + {tag: "RadioDelegate:weight", type: "RadioDelegate", attribute: "weight", value: Font.Normal, window: Font.Black, pane: Font.Bold}, + {tag: "RadioDelegate:capitalization", type: "RadioDelegate", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "SwitchDelegate:pixelSize", type: "SwitchDelegate", attribute: "pixelSize", value: 16, window: 20, pane: 10}, + {tag: "SwitchDelegate:weight", type: "SwitchDelegate", attribute: "weight", value: Font.Normal, window: Font.Black, pane: Font.Bold}, + {tag: "SwitchDelegate:capitalization", type: "SwitchDelegate", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "Label:pixelSize", type: "Label", attribute: "pixelSize", value: 14, window: 20, pane: 10}, + {tag: "Label:weight", type: "Label", attribute: "weight", value: Font.Normal, window: Font.Black, pane: Font.Bold}, + {tag: "Label:capitalization", type: "Label", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "CheckBox:pixelSize", type: "CheckBox", attribute: "pixelSize", value: 14, window: 20, pane: 10}, + {tag: "CheckBox:weight", type: "CheckBox", attribute: "weight", value: Font.Normal, window: Font.Black, pane: Font.Bold}, + {tag: "CheckBox:capitalization", type: "CheckBox", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "RadioButton:pixelSize", type: "RadioButton", attribute: "pixelSize", value: 14, window: 20, pane: 10}, + {tag: "RadioButton:weight", type: "RadioButton", attribute: "weight", value: Font.Normal, window: Font.Black, pane: Font.Bold}, + {tag: "RadioButton:capitalization", type: "RadioButton", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "Switch:pixelSize", type: "Switch", attribute: "pixelSize", value: 14, window: 20, pane: 10}, + {tag: "Switch:weight", type: "Switch", attribute: "weight", value: Font.Normal, window: Font.Black, pane: Font.Bold}, + {tag: "Switch:capitalization", type: "Switch", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "MenuItem:pixelSize", type: "MenuItem", attribute: "pixelSize", value: 16, window: 20, pane: 10}, + {tag: "MenuItem:weight", type: "MenuItem", attribute: "weight", value: Font.Normal, window: Font.Black, pane: Font.Bold}, + {tag: "MenuItem:capitalization", type: "MenuItem", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "ComboBox:pixelSize", type: "ComboBox", attribute: "pixelSize", value: 16, window: 20, pane: 10}, + {tag: "ComboBox:weight", type: "ComboBox", attribute: "weight", value: Font.Normal, window: Font.Black, pane: Font.Bold}, + {tag: "ComboBox:capitalization", type: "ComboBox", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "TextField:pixelSize", type: "TextField", attribute: "pixelSize", value: 16, window: 20, pane: 10}, + {tag: "TextField:weight", type: "TextField", attribute: "weight", value: Font.Normal, window: Font.Black, pane: Font.Bold}, + {tag: "TextField:capitalization", type: "TextField", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "TextArea:pixelSize", type: "TextArea", attribute: "pixelSize", value: 16, window: 20, pane: 10}, + {tag: "TextArea:weight", type: "TextArea", attribute: "weight", value: Font.Normal, window: Font.Black, pane: Font.Bold}, + {tag: "TextArea:capitalization", type: "TextArea", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase}, + + {tag: "SpinBox:pixelSize", type: "SpinBox", attribute: "pixelSize", value: 16, window: 20, pane: 10}, + {tag: "SpinBox:weight", type: "SpinBox", attribute: "weight", value: Font.Normal, window: Font.Black, pane: Font.Bold}, + {tag: "SpinBox:capitalization", type: "SpinBox", attribute: "capitalization", value: Font.MixedCase, window: Font.Capitalize, pane: Font.AllLowercase} + ] + } + + function test_font(data) { + var window = windowPane.createObject(testCase) + verify(window) + verify(window.pane) + + var control = Qt.createQmlObject("import QtQuick.Controls; " + data.type + " { }", window.pane) + verify(control) + + compare(control.font[data.attribute], data.value) + + window.font[data.attribute] = data.window + compare(window.font[data.attribute], data.window) + compare(window.pane.font[data.attribute], data.window) + compare(control.font[data.attribute], data.window) + + window.pane.font[data.attribute] = data.pane + compare(window.font[data.attribute], data.window) + compare(window.pane.font[data.attribute], data.pane) + compare(control.font[data.attribute], data.pane) + + window.pane.font = undefined + compare(window.font[data.attribute], data.window) + compare(window.pane.font[data.attribute], data.window) + compare(control.font[data.attribute], data.window) + + window.destroy() + } + + Component { + id: backgroundControls + ApplicationWindow { + id: window + property Button button: Button { } + property ComboBox combobox: ComboBox { } + property Drawer drawer: Drawer { } + property GroupBox groupbox: GroupBox { Material.elevation: 10 } + property Frame frame: Frame { Material.elevation: 10 } + property Menu menu: Menu { } + property Page page: Page { } + property Pane pane: Pane { } + property Popup popup: Popup { } + property TabBar tabbar: TabBar { } + property ToolBar toolbar: ToolBar { } + property ToolTip tooltip: ToolTip { } + } + } + + function test_background_data() { + return [ + { tag: "button", inherit: false, wait: 400 }, + { tag: "combobox", inherit: false, wait: 400 }, + { tag: "drawer", inherit: true }, + { tag: "groupbox", inherit: true }, + { tag: "frame", inherit: true }, + { tag: "menu", inherit: true }, + { tag: "page", inherit: true }, + { tag: "pane", inherit: true }, + { tag: "popup", inherit: true }, + { tag: "tabbar", inherit: true }, + { tag: "toolbar", inherit: false }, + { tag: "tooltip", inherit: false } + ] + } + + function test_background(data) { + var window = backgroundControls.createObject(testCase) + verify(window) + + var control = window[data.tag] + verify(control) + + control.parent = window.contentItem + control.visible = true + + var defaultBackground = control.background.color + + window.Material.background = "#ff0000" + compare(window.color, "#ff0000") + + // For controls that have an animated background color, we wait the length + // of the color animation to be sure that the color hasn't actually changed. + if (data.wait) + wait(data.wait) + + // We want the control's background color to be equal to the window's background + // color, because we want the color to propagate to items that might actually use + // it... Button, ComboBox, ToolBar and ToolTip have a special background color, + // so they don't use the generic background color unless explicitly set, so we + // compare the actual background rect color instead. + if (data.inherit) + compare(control.background.color, "#ff0000") + else + compare(control.background.color, defaultBackground) + + control.Material.background = "#0000ff" + tryCompare(control.background, "color", "#0000ff") + + window.destroy() + } + + Component { + id: busyIndicator + BusyIndicator { } + } + + function test_shade() { + var control = busyIndicator.createObject(testCase) + + compare(control.contentItem.color.toString(), Material.color(Material.Pink, Material.Shade500)) + control.Material.theme = Material.Dark + compare(control.contentItem.color.toString(), Material.color(Material.Pink, Material.Shade200)) + + control.destroy() + } + + // We can't declare components with JS syntax (when creating a data row), + // so we use introspection to get the list of all components we should test. + QtObject { + id: bindingLoopComponents + + property Component row_foregroundToPrimaryTextColor: Item { Material.foreground: Material.primaryTextColor } + // Not all properties can be bound without binding loops. For example, it's not possible to bind + // foreground to primaryHighlightedTextColor, because primaryHighlightedTextColor() depends on + // m_explicitForeground, which is modified when the foreground is set. + // So, we use background instead. + property Component row_backgroundToPrimaryHighlightedTextColor: Item { Material.background: Material.primaryHighlightedTextColor } + property Component row_foregroundToSecondaryTextColor: Item { Material.foreground: Material.secondaryTextColor } + property Component row_foregroundToSecondaryTextColorWithTheme: Item { + Material.foreground: Material.theme === Material.Dark ? Material.secondaryTextColor : Material.Red + } + property Component row_foregroundToHintTextColor: Item { Material.foreground: Material.secondaryTextColor } + property Component row_foregroundToTextSelectionColor: Item { Material.foreground: Material.textSelectionColor } + property Component row_foregroundToDropShadowColor: Item { Material.foreground: Material.dropShadowColor } + property Component row_foregroundToDividerColor: Item { Material.foreground: Material.dividerColor } + property Component row_foregroundToIconColor: Item { Material.foreground: Material.iconColor } + property Component row_foregroundToIconDisabledColor: Item { Material.foreground: Material.iconDisabledColor } + property Component row_foregroundToButtonColor: Item { Material.foreground: Material.buttonColor } + property Component row_foregroundToButtonDisabledColor: Item { Material.foreground: Material.buttonDisabledColor } + property Component row_foregroundToHighlightedButtonColor: Item { Material.foreground: Material.highlightedButtonColor } + property Component row_foregroundToFrameColor: Item { Material.foreground: Material.frameColor } + property Component row_foregroundToRippleColor: Item { Material.foreground: Material.rippleColor } + property Component row_foregroundToHighlightedRippleColor: Item { Material.foreground: Material.highlightedRippleColor } + property Component row_foregroundToSwitchUncheckedTrackColor: Item { Material.foreground: Material.switchUncheckedTrackColor } + property Component row_foregroundToSwitchCheckedTrackColor: Item { Material.foreground: Material.switchCheckedTrackColor } + property Component row_foregroundToSwitchUncheckedHandleColor: Item { Material.foreground: Material.switchUncheckedHandleColor } + property Component row_foregroundToSwitchCheckedHandleColor: Item { Material.foreground: Material.switchCheckedHandleColor } + property Component row_foregroundToSwitchDisabledTrackColor: Item { Material.foreground: Material.switchDisabledTrackColor } + property Component row_foregroundToSwitchDisabledHandleColor: Item { Material.foreground: Material.switchDisabledHandleColor } + property Component row_foregroundToScrollBarColor: Item { Material.foreground: Material.scrollBarColor } + property Component row_foregroundToScrollBarHoveredColor: Item { Material.foreground: Material.scrollBarHoveredColor } + property Component row_foregroundToScrollBarPressedColor: Item { Material.foreground: Material.scrollBarPressedColor } + property Component row_foregroundToDialogColor: Item { Material.foreground: Material.dialogColor } + property Component row_foregroundToBackgroundDimColor: Item { Material.foreground: Material.backgroundDimColor } + property Component row_foregroundToListHighlightColor: Item { Material.foreground: Material.listHighlightColor } + property Component row_foregroundToTooltipColor: Item { Material.foreground: Material.tooltipColor } + property Component row_foregroundToToolBarColor: Item { Material.foreground: Material.toolBarColor } + property Component row_backgroundToToolTextColor: Item { Material.background: Material.toolTextColor } + property Component row_foregroundToSpinBoxDisabledIconColor: Item { Material.foreground: Material.spinBoxDisabledIconColor } + property Component row_foregroundToSliderDisableColor: Item { Material.foreground: Material.sliderDisableColor } + } + + function test_propertyBindingLoop_data() { + let data = [] + for (let propertyName in bindingLoopComponents) { + if (!propertyName.startsWith("row_") || propertyName.endsWith("Changed")) + continue + + let row = {} + row.tag = propertyName.substr(4) + row.component = bindingLoopComponents[propertyName] + data.push(row) + } + return data + } + + /* + Test that binding attached Material properties to other (private, non-settable) + Material properties does not result in a binding loop. + */ + function test_propertyBindingLoop(data) { + let item = createTemporaryObject(data.component, testCase) + verify(item) + verify(!BindingLoopDetector.bindingLoopDetected, "Detected binding loop") + BindingLoopDetector.reset() + } +} diff --git a/tests/auto/quickcontrols2/qquickmaterialstyle/qtquickcontrols2.conf b/tests/auto/quickcontrols2/qquickmaterialstyle/qtquickcontrols2.conf new file mode 100644 index 00000000000..b6c7c87ea13 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmaterialstyle/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Material diff --git a/tests/auto/quickcontrols2/qquickmaterialstyle/tst_qquickmaterialstyle.cpp b/tests/auto/quickcontrols2/qquickmaterialstyle/tst_qquickmaterialstyle.cpp new file mode 100644 index 00000000000..269f7986dc4 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmaterialstyle/tst_qquickmaterialstyle.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcontext.h> +#include <QtQuickTest/quicktest.h> + +class Setup : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool bindingLoopDetected READ wasBindingLoopDetected FINAL) + +public: + Setup() {} + + bool wasBindingLoopDetected() const { return mBindingLoopDetected; } + +public slots: + void reset() { mBindingLoopDetected = false; } + + void qmlEngineAvailable(QQmlEngine *engine) + { + connect(engine, &QQmlEngine::warnings, this, &Setup::qmlWarnings); + + qmlRegisterSingletonInstance("org.qtproject.Test", 1, 0, "BindingLoopDetector", this); + } + + void qmlWarnings(const QList<QQmlError> &warnings) + { + for (const auto &error : warnings) { + if (error.messageType() == QtWarningMsg && error.description().contains(QStringLiteral("Binding loop detected"))) + mBindingLoopDetected = true; + } + } + +private: + bool mBindingLoopDetected = false; +}; + +QUICK_TEST_MAIN_WITH_SETUP(tst_qquickmaterialstyle, Setup) + +#include "tst_qquickmaterialstyle.moc" diff --git a/tests/auto/quickcontrols2/qquickmaterialstyleconf/CMakeLists.txt b/tests/auto/quickcontrols2/qquickmaterialstyleconf/CMakeLists.txt new file mode 100644 index 00000000000..753413c1637 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmaterialstyleconf/CMakeLists.txt @@ -0,0 +1,63 @@ +# Generated from qquickmaterialstyleconf.pro. + +##################################################################### +## tst_qquickmaterialstyleconf Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickmaterialstyleconf + SOURCES + tst_qquickmaterialstyleconf.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +# Resources: +set(qquickmaterialstyleconf_resource_files + "qtquickcontrols2.conf" + "variant-dense.conf" + "variant-normal.conf" +) + +qt_internal_add_resource(tst_qquickmaterialstyleconf "qquickmaterialstyleconf" + PREFIX + "/" + FILES + ${qquickmaterialstyleconf_resource_files} +) + + +#### Keys ignored in scope 1:.:.:qquickmaterialstyleconf.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickmaterialstyleconf CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickmaterialstyleconf CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickmaterialstyleconf/data/applicationwindow.qml b/tests/auto/quickcontrols2/qquickmaterialstyleconf/data/applicationwindow.qml new file mode 100644 index 00000000000..1ce4598de60 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmaterialstyleconf/data/applicationwindow.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material + +ApplicationWindow { + width: 400 + height: 400 + + property alias label: label + property alias button: button + + Label { + id: label + } + + Button { + id: button + } +} diff --git a/tests/auto/quickcontrols2/qquickmaterialstyleconf/qquickmaterialstyleconf.qrc b/tests/auto/quickcontrols2/qquickmaterialstyleconf/qquickmaterialstyleconf.qrc new file mode 100644 index 00000000000..49219139095 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmaterialstyleconf/qquickmaterialstyleconf.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/"> + <file>qtquickcontrols2.conf</file> + <file>variant-dense.conf</file> + <file>variant-normal.conf</file> + </qresource> +</RCC> diff --git a/tests/auto/quickcontrols2/qquickmaterialstyleconf/qtquickcontrols2.conf b/tests/auto/quickcontrols2/qquickmaterialstyleconf/qtquickcontrols2.conf new file mode 100644 index 00000000000..30cee878bef --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmaterialstyleconf/qtquickcontrols2.conf @@ -0,0 +1,10 @@ +[Controls] +Style=Material + +[Material] +Background=#444444 +Foreground=Red +Font\PixelSize=22 + +[Material\Font] +Family=Courier diff --git a/tests/auto/quickcontrols2/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp b/tests/auto/quickcontrols2/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp new file mode 100644 index 00000000000..6b145d7ac67 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickControls2/private/qquickstyle_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> + +using namespace QQuickControlsTestUtils; + +class tst_qquickmaterialstyleconf : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_qquickmaterialstyleconf(); + +private slots: + void conf(); + void variants_data(); + void variants(); +}; + +tst_qquickmaterialstyleconf::tst_qquickmaterialstyleconf() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_qquickmaterialstyleconf::conf() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("applicationwindow.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QFont customFont; + customFont.setFamilies(QStringList{QLatin1String("Courier")}); + customFont.setPixelSize(22); + + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + // We specified a custom background color and font, so the window should have them. + QCOMPARE(window->property("color").value<QColor>(), QColor("#444444")); + QCOMPARE(window->property("font").value<QFont>(), customFont); + + // We specified a custom foreground color and font, so the label should have them. + QQuickItem *label = window->property("label").value<QQuickItem*>(); + QVERIFY(label); + QCOMPARE(label->property("color").value<QColor>(), QColor("#F44336")); + QCOMPARE(label->property("font").value<QFont>(), customFont); +} + +void tst_qquickmaterialstyleconf::variants_data() +{ + QTest::addColumn<QByteArray>("confPath"); + QTest::addColumn<int>("expectedButtonHeight"); + // Just to ensure that the correct conf is loaded. + QTest::addColumn<QColor>("expectedColor"); + + // (36 button height + 12 touchable area) + QTest::newRow("normal") << QByteArray(":/variant-normal.conf") << 48 << QColor::fromRgb(0x123456); + // We specified a custom variant (dense), so the button should be small. + // (32 button height + 12 touchable area) + QTest::newRow("dense") << QByteArray(":/variant-dense.conf") << 44 << QColor::fromRgb(0x789abc); +} + +void tst_qquickmaterialstyleconf::variants() +{ + QFETCH(QByteArray, confPath); + QFETCH(int, expectedButtonHeight); + QFETCH(QColor, expectedColor); + + qmlClearTypeRegistrations(); + QQuickStylePrivate::reset(); + qputenv("QT_QUICK_CONTROLS_CONF", confPath); + + QQuickControlsApplicationHelper helper(this, QLatin1String("applicationwindow.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickItem *label = window->property("label").value<QQuickItem*>(); + QVERIFY(label); + QCOMPARE(label->property("color").value<QColor>(), expectedColor); + + QQuickItem *button = window->property("button").value<QQuickItem*>(); + QVERIFY(button); + QCOMPARE(button->height(), expectedButtonHeight); +} + +QTEST_MAIN(tst_qquickmaterialstyleconf) + +#include "tst_qquickmaterialstyleconf.moc" diff --git a/tests/auto/quickcontrols2/qquickmaterialstyleconf/variant-dense.conf b/tests/auto/quickcontrols2/qquickmaterialstyleconf/variant-dense.conf new file mode 100644 index 00000000000..6636894ea49 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmaterialstyleconf/variant-dense.conf @@ -0,0 +1,6 @@ +[Controls] +Style=Material + +[Material] +Variant=Dense +Foreground=#789abc diff --git a/tests/auto/quickcontrols2/qquickmaterialstyleconf/variant-normal.conf b/tests/auto/quickcontrols2/qquickmaterialstyleconf/variant-normal.conf new file mode 100644 index 00000000000..08778e92a4e --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmaterialstyleconf/variant-normal.conf @@ -0,0 +1,6 @@ +[Controls] +Style=Material + +[Material] +Variant=Normal +Foreground=#123456 diff --git a/tests/auto/quickcontrols2/qquickmenu/BLACKLIST b/tests/auto/quickcontrols2/qquickmenu/BLACKLIST new file mode 100644 index 00000000000..1590f58caa5 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-87018 +[subMenuDisabledMouse] +macos diff --git a/tests/auto/quickcontrols2/qquickmenu/CMakeLists.txt b/tests/auto/quickcontrols2/qquickmenu/CMakeLists.txt new file mode 100644 index 00000000000..14ef0a8fc4d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/CMakeLists.txt @@ -0,0 +1,48 @@ +# Generated from qquickmenu.pro. + +##################################################################### +## tst_qquickmenu Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickmenu + SOURCES + tst_qquickmenu.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:qquickmenu.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickmenu CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickmenu CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickmenu/data/actionShortcuts.qml b/tests/auto/quickcontrols2/qquickmenu/data/actionShortcuts.qml new file mode 100644 index 00000000000..87ad41c8c55 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/actionShortcuts.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias menu: menu + property alias subMenu: subMenu + property alias buttonMenu: buttonMenu + + Menu { + id: menu + objectName: "menu" + + Action { + objectName: text + text: "action1" + shortcut: "A" + } + + Menu { + id: subMenu + objectName: "subMenu" + + Action { + objectName: text + text: "subAction1" + shortcut: "B" + } + } + } + + Button { + text: "Menu button" + + Menu { + id: buttonMenu + + Action { + objectName: text + text: "buttonMenuAction1" + shortcut: "C" + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/actions.qml b/tests/auto/quickcontrols2/qquickmenu/data/actions.qml new file mode 100644 index 00000000000..226c94500f6 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/actions.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias menu: menu + + Menu { + id: menu + Action { text: "action1" } + MenuItem { text: "menuitem2" } + Action { text: "action3" } + MenuItem { text: "menuitem4" } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/addItem.qml b/tests/auto/quickcontrols2/qquickmenu/data/addItem.qml new file mode 100644 index 00000000000..b9d38afd59d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/addItem.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 200 + height: 200 + + property alias menu: menu + + MenuItem { + id: newMenuItem + text: qsTr("New") + } + + Menu { + id: menu + y: parent.height + + Component.onCompleted: addItem(newMenuItem) + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/applicationWindowScrollable.qml b/tests/auto/quickcontrols2/qquickmenu/data/applicationWindowScrollable.qml new file mode 100644 index 00000000000..22ab278ed0b --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/applicationWindowScrollable.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + title: "Test Application Window" + width: 300 + height: 300 + + property alias menu: menu + + Menu { + id: menu + + Repeater { + model: 20 + + delegate: MenuItem { + objectName: text + text: (index + 1) + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/applicationwindow.qml b/tests/auto/quickcontrols2/qquickmenu/data/applicationwindow.qml new file mode 100644 index 00000000000..0d1baa51900 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/applicationwindow.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + title: "Test Application Window" + width: 400 + height: 400 + + property alias emptyMenu: emptyMenu + property alias menu: menu + property alias menuButton: menuButton + property Overlay overlay: menu.Overlay.overlay + + Menu { + id: emptyMenu + } + + Menu { + id: menu + cascade: true + + MenuItem { + objectName: "firstMenuItem" + text: "A" + } + MenuItem { + objectName: "secondMenuItem" + text: "B" + } + MenuItem { + objectName: "thirdMenuItem" + text: "C" + } + } + + Button { + id: menuButton + x: 250 + visible: false + text: "Open Menu" + onClicked: menu.open() + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/delegateFromSeparateComponent.qml b/tests/auto/quickcontrols2/qquickmenu/data/delegateFromSeparateComponent.qml new file mode 100644 index 00000000000..b2af27e98e3 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/delegateFromSeparateComponent.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 800 + height: 800 + + property alias menu: menu + + Component { + id: menuItemComponent + + MenuItem { + contentItem: Text { + text: parent.text + color: "blue" + } + background: Rectangle { + color: "#00ff00" + } + } + } + + Menu { + id: menu + title: "Root Menu" + + Action { + text: "Action Item 1" + } + Menu { + title: "Sub-menu" + delegate: menuItemComponent + + Action { + text: "Sub-menu Action Item 1" + } + Menu { + title: "Sub-sub-menu" + delegate: menuItemComponent + + Action { + text: "Sub-sub-menu Action Item 1" + } + } + Action { + text: "Sub-menu Action Item 2" + } + } + Action { + text: "Action Item 2" + } + + delegate: menuItemComponent + visible: true + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/disableWhenTriggered.qml b/tests/auto/quickcontrols2/qquickmenu/data/disableWhenTriggered.qml new file mode 100644 index 00000000000..9de8868f776 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/disableWhenTriggered.qml @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + Action { + id: actionOutsideMenu + text: "Action declared outside menu" + onTriggered: enabled = false + } + + menuBar: MenuBar { + Menu { + title: "Menu" + objectName: title + + Action { + text: "Action" + objectName: text + onTriggered: enabled = false + } + MenuItem { + objectName: "MenuItem with Action" + action: Action { + text: "Action declared inside MenuItem" + objectName: text + onTriggered: enabled = false + } + } + MenuItem { + objectName: "MenuItem with Action declared outside menu" + action: actionOutsideMenu + } + MenuItem { + text: "MenuItem with no Action" + objectName: text + onTriggered: enabled = false + } + + Menu { + title: "Submenu" + objectName: title + + Action { + text: "Sub-Action" + objectName: text + onTriggered: enabled = false + } + MenuItem { + objectName: "Sub-MenuItem with Action declared inside" + action: Action { + text: "Action declared inside Sub-MenuItem" + objectName: text + onTriggered: enabled = false + } + } + MenuItem { + objectName: "Sub-MenuItem with Action declared outside menu" + action: actionOutsideMenu + } + MenuItem { + text: "Sub-MenuItem with no Action" + objectName: text + onTriggered: enabled = false + } + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/disabledMenuItemKeyNavigation.qml b/tests/auto/quickcontrols2/qquickmenu/data/disabledMenuItemKeyNavigation.qml new file mode 100644 index 00000000000..496544e9253 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/disabledMenuItemKeyNavigation.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 200 + height: 200 + + property alias menu: menu + + Menu { + id: menu + + MenuItem { + text: qsTr("Enabled 1") + } + MenuItem { + text: qsTr("Disabled 1") + enabled: false + } + MenuItem { + text: qsTr("Enabled 2") + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/giveMenuItemFocusOnButtonPress.qml b/tests/auto/quickcontrols2/qquickmenu/data/giveMenuItemFocusOnButtonPress.qml new file mode 100644 index 00000000000..78fa236fae2 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/giveMenuItemFocusOnButtonPress.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 640 + height: 480 + + property alias menuButton: menuButton + property alias menu: menu + + signal menuButtonClicked + + Button { + id: menuButton + text: "Open menu" + + // Buttons do not emit clicked() for enter/return, hence the Keys usage. + // The signal is just for the test to ensure that the return was actually handled. + Keys.onReturnPressed: { + menuButtonClicked() + menu.open() + } + } + + Menu { + id: menu + parent: menuButton + + onOpened: command1.forceActiveFocus() + + MenuItem { + id: command1 + objectName: text + text: "Command 1" + } + + MenuItem { + objectName: text + text: "Command 2" + } + + MenuItem { + objectName: text + text: "Command 3" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/menuItemWidths.qml b/tests/auto/quickcontrols2/qquickmenu/data/menuItemWidths.qml new file mode 100644 index 00000000000..e956a29f381 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/menuItemWidths.qml @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 600 + height: 600 + + property alias menu: menu + + Menu { + id: menu + MenuItem { + objectName: "MenuItem" + text: "MenuItem" + } + MenuSeparator { + objectName: "MenuSeparator" + } + Menu { + title: "Sub-menu" + objectName: "Sub-menu" + + MenuItem { + objectName: "SubMenuItem" + text: "SubMenuItem" + } + } + Rectangle { + objectName: "CustomSeparator" + height: 2 + color: "salmon" + } + Rectangle { + // Use a binding to test retranslate(), which re-evaluates all bindings. + implicitWidth: someValue + objectName: "CustomRectangleSeparator" + height: 2 + color: "salmon" + + property int someValue: 120 + } + Control { + objectName: "CustomControlSeparator" + implicitWidth: someOtherValue + height: 2 + background: Rectangle { + color: "navajowhite" + } + + property int someOtherValue: 180 + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/menuSeparator.qml b/tests/auto/quickcontrols2/qquickmenu/data/menuSeparator.qml new file mode 100644 index 00000000000..64ba601461e --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/menuSeparator.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 200 + height: 200 + + property alias menu: menu + + MenuItem { + id: newMenuItem + text: qsTr("New") + } + + MenuSeparator { + id: menuSeparator + } + + MenuItem { + id: saveMenuItem + text: qsTr("Save") + } + + Menu { + id: menu + cascade: true + + Component.onCompleted: { + addItem(newMenuItem) + addItem(menuSeparator) + addItem(saveMenuItem) + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/mnemonics.qml b/tests/auto/quickcontrols2/qquickmenu/data/mnemonics.qml new file mode 100644 index 00000000000..6525e59ed4e --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/mnemonics.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias menu: menu + property alias action: action + property alias menuItem: menuItem + property alias subMenu: subMenu + property alias subMenuItem: subMenuItem + + Menu { + id: menu + + Action { + id: action + text: "&Action" + } + + MenuItem { + id: menuItem + text: "Menu &Item" + } + + Menu { + id: subMenu + title: "Sub &Menu" + + MenuItem { + id: subMenuItem + text: "&Sub Menu Item" + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/order.qml b/tests/auto/quickcontrols2/qquickmenu/data/order.qml new file mode 100644 index 00000000000..f2f18168ded --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/order.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 200 + height: 200 + + property alias menu: menu + + Component { + id: menuItem + MenuItem { } + } + + Menu { + id: menu + property alias repeater: repeater + MenuItem { text: "static_1" } + Repeater { + id: repeater + model: 2 + MenuItem { text: "repeated_" + (index + 2) } + } + MenuItem { text: "static_4" } + Component.onCompleted: { + addItem(menuItem.createObject(menu.contentItem, {text: "dynamic_5"})) + addItem(menuItem.createObject(menu.contentItem, {text: "dynamic_6"})) + insertItem(0, menuItem.createObject(menu.contentItem, {text: "dynamic_0"})) + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/popup.qml b/tests/auto/quickcontrols2/qquickmenu/data/popup.qml new file mode 100644 index 00000000000..88c08b46e8d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/popup.qml @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 600 + + property alias menu: menu + property alias menuItem1: menuItem1 + property alias menuItem2: menuItem2 + property alias menuItem3: menuItem3 + property alias button: button + + function popupAtCursor() { + menu.popup() + } + + function popupAtPos(pos) { + menu.popup(pos) + } + + function popupAtCoord(x, y) { + menu.popup(x, y) + } + + function popupItemAtCursor(item) { + menu.popup(item) + } + + function popupItemAtPos(pos, item) { + menu.popup(pos, item) + } + + function popupItemAtCoord(x, y, item) { + menu.popup(x, y, item) + } + + function popupAtParentCursor(parent) { + menu.popup(parent) + } + + function popupAtParentPos(parent, pos) { + menu.popup(parent, pos) + } + + function popupAtParentCoord(parent, x, y) { + menu.popup(parent, x, y) + } + + function popupItemAtParentCursor(parent, item) { + menu.popup(parent, item) + } + + function popupItemAtParentPos(parent, pos, item) { + menu.popup(parent, pos, item) + } + + function popupItemAtParentCoord(parent, x, y, item) { + menu.popup(parent, x, y, item) + } + + Menu { + id: menu + MenuItem { id: menuItem1; text: "Foo" } + MenuItem { id: menuItem2; text: "Bar" } + MenuItem { id: menuItem3; text: "Baz" } + } + + Button { + id: button + text: "Button" + anchors.centerIn: parent + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/pressAndHold.qml b/tests/auto/quickcontrols2/qquickmenu/data/pressAndHold.qml new file mode 100644 index 00000000000..a16a15da809 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/pressAndHold.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias menu: menu + + MouseArea { + anchors.fill: parent + onPressAndHold: menu.open() + } + + Menu { + id: menu + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + MenuItem { text: "One" } + MenuItem { text: "Two" } + MenuItem { text: "Three" } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/removeTakeItem.qml b/tests/auto/quickcontrols2/qquickmenu/data/removeTakeItem.qml new file mode 100644 index 00000000000..cfe7585e435 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/removeTakeItem.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 200 + height: 200 + + property alias menu: menu + property alias menuItem1: menuItem1 + property alias menuItem2: menuItem2 + property alias menuItem3: menuItem3 + + function takeSecondItem() { + return menu.takeItem(1) + } + + function removeFirstItem() { + menu.removeItem(menuItem1) + } + + function removeNullItem() { + menu.removeItem(null) + } + + Menu { + id: menu + MenuItem { + id: menuItem1 + } + MenuItem { + id: menuItem2 + } + MenuItem { + id: menuItem3 + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/repeater.qml b/tests/auto/quickcontrols2/qquickmenu/data/repeater.qml new file mode 100644 index 00000000000..50c8adcb329 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/repeater.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 200 + height: 200 + + property alias menu: menu + property alias repeater: repeater + + Menu { + id: menu + Repeater { + id: repeater + model: 5 + MenuItem { property int idx: index } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/scrollableWithFixedHeight.qml b/tests/auto/quickcontrols2/qquickmenu/data/scrollableWithFixedHeight.qml new file mode 100644 index 00000000000..1156d30aefc --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/scrollableWithFixedHeight.qml @@ -0,0 +1,27 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls +import QtQuick.Window + +Window { + width: 300 + height: 300 + + property alias menu: menu + + Menu { + id: menu + anchors.centerIn: parent + height: 100 + visible: true + Repeater { + model: 10 + delegate: MenuItem { + objectName: text + text: (index + 1) + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/scrollableWithPadding.qml b/tests/auto/quickcontrols2/qquickmenu/data/scrollableWithPadding.qml new file mode 100644 index 00000000000..c8e73858faa --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/scrollableWithPadding.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Window + +Window { + title: "Test Window" + width: 300 + height: dummyItem.height * 10 + + property alias menu: menu + MenuItem { + id: dummyItem + objectName: "Dummy" + text: objectName + } + + Menu { + id: menu + topPadding: 10 + Repeater { + model: 10 + + delegate: MenuItem { + objectName: text + text: (index + 1) + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/subMenuDisabled.qml b/tests/auto/quickcontrols2/qquickmenu/data/subMenuDisabled.qml new file mode 100644 index 00000000000..e50ab7abc7d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/subMenuDisabled.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 600 + height: 400 + + property alias mainMenu: mainMenu + property alias subMenu: subMenu + + Menu { + id: mainMenu + title: "Menu" + + Menu { + id: subMenu + title: "Sub Menu" + MenuItem { + id: subMenuItem1 + text: "Sub Menu Item 1" + enabled: false + } + MenuItem { + id: subMenuItem2 + text: "Sub Menu Item 2" + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/subMenus.qml b/tests/auto/quickcontrols2/qquickmenu/data/subMenus.qml new file mode 100644 index 00000000000..8227a29fb2d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/subMenus.qml @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 600 + height: 400 + + property alias mainMenu: mainMenu + property alias subMenu1: subMenu1 + property alias subMenu2: subMenu2 + property alias subSubMenu1: subSubMenu1 + + Menu { + id: mainMenu + MenuItem { + id: mainMenuItem1 + objectName: "mainMenuItem1" + text: "Main 1" + } + + Menu { + overlap: 0 + id: subMenu1 + objectName: "subMenu1" + title: "Sub Menu 1" + + MenuItem { + id: subMenuItem1 + objectName: "subMenuItem1" + text: "Sub 1" + } + + MenuItem { + id: subMenuItem2 + objectName: "subMenuItem2" + text: "Sub 2" + } + + Menu { + overlap: 0 + id: subSubMenu1 + objectName: "subSubMenu1" + title: "Sub Sub Menu 1" + + MenuItem { + id: subSubMenuItem1 + objectName: "subSubMenuItem1" + text: "Sub Sub 1" + } + MenuItem { + id: subSubMenuItem2 + objectName: "subSubMenuItem2" + text: "Sub Sub 2" + } + } + } + + MenuItem { + id: mainMenuItem2 + objectName: "mainMenuItem2" + text: "Main 2" + } + + Menu { + id: subMenu2 + objectName: "subMenu2" + title: "Sub Menu 2" + + MenuItem { + id: subMenuItem3 + objectName: "subMenuItem3" + text: "Sub 3" + } + MenuItem { + id: subMenuItem4 + objectName: "subMenuItem4" + text: "Sub 4" + } + } + + MenuItem { + id: mainMenuItem3 + objectName: "mainMenuItem3" + text: "Main 3" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/data/windowScrollable.qml b/tests/auto/quickcontrols2/qquickmenu/data/windowScrollable.qml new file mode 100644 index 00000000000..7c3a5234fbd --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/data/windowScrollable.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Window + +Window { + title: "Test Window" + width: 300 + height: 300 + + property alias menu: menu + + Menu { + id: menu + + Repeater { + model: 20 + + delegate: MenuItem { + objectName: text + text: (index + 1) + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp b/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp new file mode 100644 index 00000000000..4b1628038d1 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenu/tst_qquickmenu.cpp @@ -0,0 +1,2072 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtGui/qcursor.h> +#if QT_CONFIG(shortcut) +#include <QtGui/qkeysequence.h> +#endif +#include <QtGui/qstylehints.h> +#include <QtGui/qpa/qplatformintegration.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlcontext.h> +#include <QtQuick/qquickview.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> +#include <QtQuickControlsTestUtils/private/qtest_quickcontrols_p.h> + +#include <QtQuickTemplates2/private/qquickaction_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickoverlay_p.h> +#include <QtQuickTemplates2/private/qquickbutton_p.h> +#include <QtQuickTemplates2/private/qquickmenu_p.h> +#include <QtQuickTemplates2/private/qquickmenuitem_p.h> +#include <QtQuickTemplates2/private/qquickmenuseparator_p.h> + +using namespace QQuickVisualTestUtils; +using namespace QQuickControlsTestUtils; + +class tst_QQuickMenu : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_QQuickMenu(); + +private slots: + void defaults(); + void count(); + void mouse(); + void pressAndHold(); + void contextMenuKeyboard(); + void disabledMenuItemKeyNavigation(); + void mnemonics(); + void menuButton(); + void addItem(); + void menuSeparator(); + void repeater(); + void order(); +#if QT_CONFIG(cursor) + void popup(); +#endif + void actions(); +#if QT_CONFIG(shortcut) + void actionShortcuts(); +#endif + void removeTakeItem(); + void subMenuMouse_data(); + void subMenuMouse(); + void subMenuDisabledMouse_data(); + void subMenuDisabledMouse(); + void subMenuKeyboard_data(); + void subMenuKeyboard(); + void subMenuDisabledKeyboard_data(); + void subMenuDisabledKeyboard(); + void subMenuPosition_data(); + void subMenuPosition(); + void addRemoveSubMenus(); + void scrollable_data(); + void scrollable(); + void disableWhenTriggered_data(); + void disableWhenTriggered(); + void menuItemWidth_data(); + void menuItemWidth(); + void menuItemWidthAfterMenuWidthChanged_data(); + void menuItemWidthAfterMenuWidthChanged(); + void menuItemWidthAfterImplicitWidthChanged_data(); + void menuItemWidthAfterImplicitWidthChanged(); + void menuItemWidthAfterRetranslate(); + void giveMenuItemFocusOnButtonPress(); + +private: + static bool hasWindowActivation(); +}; + +tst_QQuickMenu::tst_QQuickMenu() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +bool tst_QQuickMenu::hasWindowActivation() +{ + return (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)); +} + +void tst_QQuickMenu::defaults() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("applicationwindow.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickMenu *emptyMenu = helper.appWindow->property("emptyMenu").value<QQuickMenu*>(); + QCOMPARE(emptyMenu->isVisible(), false); + QCOMPARE(emptyMenu->currentIndex(), -1); + QCOMPARE(emptyMenu->contentItem()->property("currentIndex"), QVariant(-1)); + QCOMPARE(emptyMenu->count(), 0); +} + +void tst_QQuickMenu::count() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("applicationwindow.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickMenu *menu = helper.window->property("emptyMenu").value<QQuickMenu*>(); + QVERIFY(menu); + + QSignalSpy countSpy(menu, &QQuickMenu::countChanged); + QVERIFY(countSpy.isValid()); + + menu->addItem(new QQuickItem); + QCOMPARE(menu->count(), 1); + QCOMPARE(countSpy.count(), 1); + + menu->insertItem(0, new QQuickItem); + QCOMPARE(menu->count(), 2); + QCOMPARE(countSpy.count(), 2); + + menu->removeItem(menu->itemAt(1)); + QCOMPARE(menu->count(), 1); + QCOMPARE(countSpy.count(), 3); + + QScopedPointer<QQuickItem> item(menu->takeItem(0)); + QVERIFY(item); + QCOMPARE(menu->count(), 0); + QCOMPARE(countSpy.count(), 4); +} + +void tst_QQuickMenu::mouse() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QSKIP("Mouse hovering not functional on offscreen/minimal platforms"); + + QQuickControlsApplicationHelper helper(this, QLatin1String("applicationwindow.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickApplicationWindow *window = helper.appWindow; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + QVERIFY(menu); + menu->open(); + QVERIFY(menu->isVisible()); + QQuickOverlay *overlay = window->property("overlay").value<QQuickOverlay*>(); + QVERIFY(overlay); + QVERIFY(overlay->childItems().contains(menu->contentItem()->parentItem())); + QTRY_VERIFY(menu->isOpened()); + + QQuickItem *firstItem = menu->itemAt(0); + QSignalSpy clickedSpy(firstItem, SIGNAL(clicked())); + QSignalSpy triggeredSpy(firstItem, SIGNAL(triggered())); + QSignalSpy visibleSpy(menu, SIGNAL(visibleChanged())); + + // Ensure that presses cause the current index to change, + // so that the highlight acts as a way of illustrating press state. + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, + QPoint(menu->x() + menu->leftPadding() + firstItem->width() / 2, menu->y() + menu->topPadding() + firstItem->height() / 2)); + QVERIFY(firstItem->hasActiveFocus()); + QCOMPARE(menu->currentIndex(), 0); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(0)); + QVERIFY(menu->isVisible()); + + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, + QPoint(menu->x() + menu->leftPadding() + firstItem->width() / 2, menu->y() + menu->topPadding() + firstItem->height() / 2)); + QCOMPARE(clickedSpy.count(), 1); + QCOMPARE(triggeredSpy.count(), 1); + QTRY_COMPARE(visibleSpy.count(), 1); + QVERIFY(!menu->isVisible()); + QVERIFY(!overlay->childItems().contains(menu->contentItem())); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); + + menu->open(); + QCOMPARE(visibleSpy.count(), 2); + QVERIFY(menu->isVisible()); + QVERIFY(overlay->childItems().contains(menu->contentItem()->parentItem())); + QTRY_VERIFY(menu->isOpened()); + + // Ensure that we have enough space to click outside of the menu. + QVERIFY(window->width() > menu->contentItem()->width()); + QVERIFY(window->height() > menu->contentItem()->height()); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, + QPoint(menu->contentItem()->x() + menu->contentItem()->width() + 1, + menu->contentItem()->y() + menu->contentItem()->height() + 1)); + QTRY_COMPARE(visibleSpy.count(), 3); + QVERIFY(!menu->isVisible()); + QVERIFY(!overlay->childItems().contains(menu->contentItem()->parentItem())); + + menu->open(); + QCOMPARE(visibleSpy.count(), 4); + QVERIFY(menu->isVisible()); + QVERIFY(overlay->childItems().contains(menu->contentItem()->parentItem())); + QTRY_VERIFY(menu->isOpened()); + + // Hover-highlighting does not work on Android +#ifndef Q_OS_ANDROID + // Hover-highlight through the menu items one by one + QQuickItem *prevHoverItem = nullptr; + QQuickItem *listView = menu->contentItem(); + for (int y = menu->topPadding(); y < listView->height(); ++y) { + QQuickItem *hoverItem = nullptr; + QVERIFY(QMetaObject::invokeMethod(listView, "itemAt", Q_RETURN_ARG(QQuickItem *, hoverItem), Q_ARG(qreal, 0), Q_ARG(qreal, listView->property("contentY").toReal() + y))); + if (!hoverItem || !hoverItem->isVisible() || hoverItem == prevHoverItem) + continue; + QTest::mouseMove(window, QPoint( + menu->x() + menu->leftPadding() + hoverItem->x() + hoverItem->width() / 2, + menu->y() + menu->topPadding() + hoverItem->y() + hoverItem->height() / 2)); + QTRY_VERIFY(hoverItem->property("highlighted").toBool()); + if (prevHoverItem) + QVERIFY(!prevHoverItem->property("highlighted").toBool()); + prevHoverItem = hoverItem; + } +#endif + + // Try pressing within the menu and releasing outside of it; it should close. + // TODO: won't work until QQuickPopup::releasedOutside() actually gets emitted +// QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(firstItem->width() / 2, firstItem->height() / 2)); +// QVERIFY(firstItem->hasActiveFocus()); +// QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(0)); +// QVERIFY(menu->isVisible()); +// QCOMPARE(triggeredSpy.count(), 1); + +// QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(menu->contentItem()->width() + 1, firstItem->height() / 2)); +// QCOMPARE(clickedSpy.count(), 1); +// QCOMPARE(triggeredSpy.count(), 1); +// QCOMPARE(visibleSpy.count(), 5); +// QVERIFY(!menu->isVisible()); +// QVERIFY(!overlay->childItems().contains(menu->contentItem())); +// QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); +} + +void tst_QQuickMenu::pressAndHold() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("pressAndHold.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu *>(); + QVERIFY(menu); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QTRY_VERIFY(menu->isVisible()); + + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QVERIFY(menu->isVisible()); + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QTRY_VERIFY(!menu->isVisible()); +} + +void tst_QQuickMenu::contextMenuKeyboard() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls) + QSKIP("This platform only allows tab focus for text controls"); + + QQuickControlsApplicationHelper helper(this, QLatin1String("applicationwindow.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickApplicationWindow *window = helper.appWindow; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); + + QQuickMenuItem *firstItem = qobject_cast<QQuickMenuItem *>(menu->itemAt(0)); + QVERIFY(firstItem); + QSignalSpy visibleSpy(menu, SIGNAL(visibleChanged())); + + menu->setFocus(true); + menu->open(); + QCOMPARE(visibleSpy.count(), 1); + QVERIFY(menu->isVisible()); + QQuickOverlay *overlay = window->property("overlay").value<QQuickOverlay*>(); + QVERIFY(overlay); + QVERIFY(overlay->childItems().contains(menu->contentItem()->parentItem())); + QTRY_VERIFY(menu->isOpened()); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!firstItem->property("highlighted").toBool()); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); + + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(firstItem->hasActiveFocus()); + QVERIFY(firstItem->hasVisualFocus()); + QVERIFY(firstItem->isHighlighted()); + QCOMPARE(firstItem->focusReason(), Qt::TabFocusReason); + QCOMPARE(menu->currentIndex(), 0); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(0)); + + QQuickMenuItem *secondItem = qobject_cast<QQuickMenuItem *>(menu->itemAt(1)); + QVERIFY(secondItem); + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!firstItem->hasVisualFocus()); + QVERIFY(!firstItem->isHighlighted()); + QVERIFY(secondItem->hasActiveFocus()); + QVERIFY(secondItem->hasVisualFocus()); + QVERIFY(secondItem->isHighlighted()); + QCOMPARE(secondItem->focusReason(), Qt::TabFocusReason); + QCOMPARE(menu->currentIndex(), 1); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(1)); + + QSignalSpy secondTriggeredSpy(secondItem, SIGNAL(triggered())); + QTest::keyClick(window, Qt::Key_Space); + QCOMPARE(secondTriggeredSpy.count(), 1); + QTRY_COMPARE(visibleSpy.count(), 2); + QVERIFY(!menu->isVisible()); + QVERIFY(!overlay->childItems().contains(menu->contentItem())); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!firstItem->hasVisualFocus()); + QVERIFY(!firstItem->isHighlighted()); + QVERIFY(!secondItem->hasActiveFocus()); + QVERIFY(!secondItem->hasVisualFocus()); + QVERIFY(!secondItem->isHighlighted()); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); + + // Enter/return should also work. + // Open the menu. + menu->open(); + QCOMPARE(visibleSpy.count(), 3); + QVERIFY(menu->isVisible()); + QTRY_VERIFY(menu->isOpened()); + // Give the first item focus. + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(firstItem->hasActiveFocus()); + QVERIFY(firstItem->hasVisualFocus()); + QVERIFY(firstItem->isHighlighted()); + QCOMPARE(firstItem->focusReason(), Qt::TabFocusReason); + QCOMPARE(menu->currentIndex(), 0); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(0)); + // Press enter. + QSignalSpy firstTriggeredSpy(firstItem, SIGNAL(triggered())); + QTest::keyClick(window, Qt::Key_Return); + QCOMPARE(firstTriggeredSpy.count(), 1); + QTRY_COMPARE(visibleSpy.count(), 4); + QVERIFY(!menu->isVisible()); + QVERIFY(!overlay->childItems().contains(menu->contentItem())); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!firstItem->hasVisualFocus()); + QVERIFY(!firstItem->isHighlighted()); + QVERIFY(!secondItem->hasActiveFocus()); + QVERIFY(!secondItem->hasVisualFocus()); + QVERIFY(!secondItem->isHighlighted()); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); + + menu->open(); + QCOMPARE(visibleSpy.count(), 5); + QVERIFY(menu->isVisible()); + QVERIFY(overlay->childItems().contains(menu->contentItem()->parentItem())); + QTRY_VERIFY(menu->isOpened()); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!firstItem->hasVisualFocus()); + QVERIFY(!firstItem->isHighlighted()); + QVERIFY(!secondItem->hasActiveFocus()); + QVERIFY(!secondItem->hasVisualFocus()); + QVERIFY(!secondItem->isHighlighted()); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); + + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(firstItem->hasActiveFocus()); + QVERIFY(firstItem->hasVisualFocus()); + QVERIFY(firstItem->isHighlighted()); + QCOMPARE(firstItem->focusReason(), Qt::TabFocusReason); + + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(secondItem->hasActiveFocus()); + QVERIFY(secondItem->hasVisualFocus()); + QVERIFY(secondItem->isHighlighted()); + QCOMPARE(secondItem->focusReason(), Qt::TabFocusReason); + + QTest::keyClick(window, Qt::Key_Down); + QQuickMenuItem *thirdItem = qobject_cast<QQuickMenuItem *>(menu->itemAt(2)); + QVERIFY(thirdItem); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!firstItem->hasVisualFocus()); + QVERIFY(!firstItem->isHighlighted()); + QVERIFY(!secondItem->hasActiveFocus()); + QVERIFY(!secondItem->hasVisualFocus()); + QVERIFY(!secondItem->isHighlighted()); + QVERIFY(thirdItem->hasActiveFocus()); + QVERIFY(thirdItem->hasVisualFocus()); + QVERIFY(thirdItem->isHighlighted()); + QCOMPARE(thirdItem->focusReason(), Qt::TabFocusReason); + + // Key navigation shouldn't wrap by default. + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!firstItem->hasVisualFocus()); + QVERIFY(!firstItem->isHighlighted()); + QVERIFY(!secondItem->hasActiveFocus()); + QVERIFY(!secondItem->hasVisualFocus()); + QVERIFY(!secondItem->isHighlighted()); + QVERIFY(thirdItem->hasActiveFocus()); + QVERIFY(thirdItem->hasVisualFocus()); + QVERIFY(thirdItem->isHighlighted()); + QCOMPARE(thirdItem->focusReason(), Qt::TabFocusReason); + + QTest::keyClick(window, Qt::Key_Up); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!firstItem->hasVisualFocus()); + QVERIFY(!firstItem->isHighlighted()); + QVERIFY(secondItem->hasActiveFocus()); + QVERIFY(secondItem->hasVisualFocus()); + QVERIFY(secondItem->isHighlighted()); + QCOMPARE(secondItem->focusReason(), Qt::BacktabFocusReason); + QVERIFY(!thirdItem->hasActiveFocus()); + QVERIFY(!thirdItem->hasVisualFocus()); + QVERIFY(!thirdItem->isHighlighted()); + + QTest::keyClick(window, Qt::Key_Backtab); + QVERIFY(firstItem->hasActiveFocus()); + QVERIFY(firstItem->hasVisualFocus()); + QVERIFY(firstItem->isHighlighted()); + QCOMPARE(firstItem->focusReason(), Qt::BacktabFocusReason); + QVERIFY(!secondItem->hasActiveFocus()); + QVERIFY(!secondItem->hasVisualFocus()); + QVERIFY(!secondItem->isHighlighted()); + QVERIFY(!thirdItem->hasActiveFocus()); + QVERIFY(!thirdItem->hasVisualFocus()); + QVERIFY(!thirdItem->isHighlighted()); + + QTest::keyClick(window, Qt::Key_Escape); + QTRY_COMPARE(visibleSpy.count(), 6); + QVERIFY(!menu->isVisible()); +} + +// QTBUG-70181 +void tst_QQuickMenu::disabledMenuItemKeyNavigation() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls) + QSKIP("This platform only allows tab focus for text controls"); + + QQuickControlsApplicationHelper helper(this, QLatin1String("disabledMenuItemKeyNavigation.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickApplicationWindow *window = helper.appWindow; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); + + QQuickMenuItem *firstItem = qobject_cast<QQuickMenuItem *>(menu->itemAt(0)); + QVERIFY(firstItem); + + QQuickMenuItem *secondItem = qobject_cast<QQuickMenuItem *>(menu->itemAt(1)); + QVERIFY(secondItem); + + QQuickMenuItem *thirdItem = qobject_cast<QQuickMenuItem *>(menu->itemAt(2)); + QVERIFY(thirdItem); + + menu->setFocus(true); + menu->open(); + QVERIFY(menu->isVisible()); + QTRY_VERIFY(menu->isOpened()); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!firstItem->property("highlighted").toBool()); + QCOMPARE(menu->currentIndex(), -1); + + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(firstItem->hasActiveFocus()); + QVERIFY(firstItem->hasVisualFocus()); + QVERIFY(firstItem->isHighlighted()); + QCOMPARE(firstItem->focusReason(), Qt::TabFocusReason); + QCOMPARE(menu->currentIndex(), 0); + + // Shouldn't be possible to give focus to a disabled menu item. + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(!secondItem->hasActiveFocus()); + QVERIFY(!secondItem->hasVisualFocus()); + QVERIFY(!secondItem->isHighlighted()); + QVERIFY(thirdItem->hasActiveFocus()); + QVERIFY(thirdItem->hasVisualFocus()); + QVERIFY(thirdItem->isHighlighted()); + QCOMPARE(thirdItem->focusReason(), Qt::TabFocusReason); + + QTest::keyClick(window, Qt::Key_Up); + QVERIFY(firstItem->hasActiveFocus()); + QVERIFY(firstItem->hasVisualFocus()); + QVERIFY(firstItem->isHighlighted()); + QCOMPARE(firstItem->focusReason(), Qt::BacktabFocusReason); + + QTest::keyClick(window, Qt::Key_Escape); + QTRY_VERIFY(!menu->isVisible()); +} + +void tst_QQuickMenu::mnemonics() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + +#ifdef Q_OS_MACOS + QSKIP("Mnemonics are not used on macOS"); +#endif + + QQuickControlsApplicationHelper helper(this, QLatin1String("mnemonics.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + MnemonicKeySimulator keySim(window); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu *>(); + QQuickAction *action = window->property("action").value<QQuickAction *>(); + QQuickMenuItem *menuItem = window->property("menuItem").value<QQuickMenuItem *>(); + QQuickMenu *subMenu = window->property("subMenu").value<QQuickMenu *>(); + QQuickMenuItem *subMenuItem = window->property("subMenuItem").value<QQuickMenuItem *>(); + QVERIFY(menu && action && menuItem && subMenu && subMenuItem); + + keySim.press(Qt::Key_Alt); + menu->open(); + QTRY_VERIFY(menu->isOpened()); + + QSignalSpy actionSpy(action, &QQuickAction::triggered); + QVERIFY(actionSpy.isValid()); + keySim.click(Qt::Key_A); // "&Action" + QCOMPARE(actionSpy.count(), 1); + + menu->open(); + QTRY_VERIFY(menu->isOpened()); + + QSignalSpy menuItemSpy(menuItem, &QQuickMenuItem::triggered); + QVERIFY(menuItemSpy.isValid()); + keySim.click(Qt::Key_I); // "Menu &Item" + keySim.release(Qt::Key_Alt); + QCOMPARE(menuItemSpy.count(), 1); + + keySim.press(Qt::Key_Alt); + menu->open(); + QTRY_VERIFY(menu->isOpened()); + + keySim.click(Qt::Key_M); // "Sub &Menu" + QTRY_VERIFY(subMenu->isOpened()); + + QSignalSpy subMenuItemSpy(subMenuItem, &QQuickMenuItem::triggered); + QVERIFY(subMenuItemSpy.isValid()); + keySim.click(Qt::Key_S); // "&Sub Menu Item" + keySim.release(Qt::Key_Alt); + QCOMPARE(subMenuItemSpy.count(), 1); +} + +void tst_QQuickMenu::menuButton() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls) + QSKIP("This platform only allows tab focus for text controls"); + + QQuickControlsApplicationHelper helper(this, QLatin1String("applicationwindow.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + QQuickButton *menuButton = window->property("menuButton").value<QQuickButton*>(); + QSignalSpy visibleSpy(menu, SIGNAL(visibleChanged())); + + menuButton->setVisible(true); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, + menuButton->mapToScene(QPointF(menuButton->width() / 2, menuButton->height() / 2)).toPoint()); + QCOMPARE(visibleSpy.count(), 1); + QVERIFY(menu->isVisible()); + QTRY_VERIFY(menu->isOpened()); + + QTest::keyClick(window, Qt::Key_Tab); + QQuickItem *firstItem = menu->itemAt(0); + QVERIFY(firstItem->hasActiveFocus()); +} + +void tst_QQuickMenu::addItem() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("addItem.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + QVERIFY(menu); + menu->open(); + QVERIFY(menu->isVisible()); + + QQuickItem *menuItem = menu->itemAt(0); + QVERIFY(menuItem); + QTRY_VERIFY(!QQuickItemPrivate::get(menuItem)->culled); // QTBUG-53262 + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, + menuItem->mapToScene(QPointF(menuItem->width() / 2, menuItem->height() / 2)).toPoint()); + QTRY_VERIFY(!menu->isVisible()); +} + +void tst_QQuickMenu::menuSeparator() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + QQuickControlsApplicationHelper helper(this, QLatin1String("menuSeparator.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + QVERIFY(menu); + menu->open(); + QVERIFY(menu->isVisible()); + + QQuickMenuItem *newMenuItem = qobject_cast<QQuickMenuItem*>(menu->itemAt(0)); + QVERIFY(newMenuItem); + QCOMPARE(newMenuItem->text(), QStringLiteral("New")); + + QQuickMenuSeparator *menuSeparator = qobject_cast<QQuickMenuSeparator*>(menu->itemAt(1)); + QVERIFY(menuSeparator); + + QQuickMenuItem *saveMenuItem = qobject_cast<QQuickMenuItem*>(menu->itemAt(2)); + QVERIFY(saveMenuItem); + QCOMPARE(saveMenuItem->text(), QStringLiteral("Save")); + QTRY_VERIFY(!QQuickItemPrivate::get(saveMenuItem)->culled); // QTBUG-53262 + QTRY_VERIFY(menu->isOpened()); + + // Clicking on items should still close the menu. + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, + newMenuItem->mapToScene(QPointF(newMenuItem->width() / 2, newMenuItem->height() / 2)).toPoint()); + QTRY_VERIFY(!menu->isVisible()); + + menu->open(); + QTRY_VERIFY(menu->isOpened()); + + // Clicking on a separator shouldn't close the menu. + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, + menuSeparator->mapToScene(QPointF(menuSeparator->width() / 2, menuSeparator->height() / 2)).toPoint()); + QVERIFY(menu->isVisible()); + + // Clicking on items should still close the menu. + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, + saveMenuItem->mapToScene(QPointF(saveMenuItem->width() / 2, saveMenuItem->height() / 2)).toPoint()); + QTRY_VERIFY(!menu->isVisible()); + + moveMouseAway(window); + + menu->open(); + QVERIFY(menu->isVisible()); + QTRY_VERIFY(menu->isOpened()); + + // Key navigation skips separators + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(newMenuItem->hasActiveFocus()); + QVERIFY(newMenuItem->hasVisualFocus()); + QCOMPARE(newMenuItem->focusReason(), Qt::TabFocusReason); + + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(saveMenuItem->hasActiveFocus()); + QVERIFY(saveMenuItem->hasVisualFocus()); + QCOMPARE(saveMenuItem->focusReason(), Qt::TabFocusReason); + + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(saveMenuItem->hasActiveFocus()); + QVERIFY(saveMenuItem->hasVisualFocus()); + QCOMPARE(saveMenuItem->focusReason(), Qt::TabFocusReason); + + QTest::keyClick(window, Qt::Key_Up); + QVERIFY(newMenuItem->hasActiveFocus()); + QVERIFY(newMenuItem->hasVisualFocus()); + QCOMPARE(newMenuItem->focusReason(), Qt::BacktabFocusReason); + + QTest::keyClick(window, Qt::Key_Up); + QVERIFY(newMenuItem->hasActiveFocus()); + QVERIFY(newMenuItem->hasVisualFocus()); + QCOMPARE(newMenuItem->focusReason(), Qt::BacktabFocusReason); +} + +void tst_QQuickMenu::repeater() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("repeater.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + QVERIFY(menu); + menu->open(); + QVERIFY(menu->isVisible()); + + QObject *repeater = window->property("repeater").value<QObject*>(); + QVERIFY(repeater); + + int count = repeater->property("count").toInt(); + QCOMPARE(count, 5); + + for (int i = 0; i < count; ++i) { + QQuickItem *item = menu->itemAt(i); + QVERIFY(item); + QCOMPARE(item->property("idx").toInt(), i); + + QQuickItem *repeaterItem = nullptr; + QVERIFY(QMetaObject::invokeMethod(repeater, "itemAt", Q_RETURN_ARG(QQuickItem*, repeaterItem), Q_ARG(int, i))); + QCOMPARE(item, repeaterItem); + } + + repeater->setProperty("model", 3); + + count = repeater->property("count").toInt(); + QCOMPARE(count, 3); + + for (int i = 0; i < count; ++i) { + QQuickItem *item = menu->itemAt(i); + QVERIFY(item); + QCOMPARE(item->property("idx").toInt(), i); + + QQuickItem *repeaterItem = nullptr; + QVERIFY(QMetaObject::invokeMethod(repeater, "itemAt", Q_RETURN_ARG(QQuickItem*, repeaterItem), Q_ARG(int, i))); + QCOMPARE(item, repeaterItem); + } +} + +void tst_QQuickMenu::order() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("order.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + QVERIFY(menu); + menu->open(); + QVERIFY(menu->isVisible()); + + const QStringList texts = {"dynamic_0", "static_1", "repeated_2", "repeated_3", "static_4", "dynamic_5", "dynamic_6"}; + + for (int i = 0; i < texts.count(); ++i) { + QQuickItem *item = menu->itemAt(i); + QVERIFY(item); + QCOMPARE(item->property("text").toString(), texts.at(i)); + } +} + +#if QT_CONFIG(cursor) +void tst_QQuickMenu::popup() +{ +#if defined(Q_OS_ANDROID) + QSKIP("Setting cursor position is not supported on Android"); +#endif + if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"))) + QSKIP("Setting cursor position is not supported on Wayland"); + + // Try moving the cursor from the current position + // Skip if it fails since the test relies on moving the cursor + const QPoint point = QCursor::pos() + QPoint(1, 1); + QCursor::setPos(point); + if (!QTest::qWaitFor([point]{ return QCursor::pos() == point; })) + QSKIP("Setting cursor position is not supported on this platform"); + + QQuickControlsApplicationHelper helper(this, QLatin1String("popup.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu *>(); + QVERIFY(menu); + + QQuickMenuItem *menuItem1 = window->property("menuItem1").value<QQuickMenuItem *>(); + QVERIFY(menuItem1); + + QQuickMenuItem *menuItem2 = window->property("menuItem2").value<QQuickMenuItem *>(); + QVERIFY(menuItem2); + + QQuickMenuItem *menuItem3 = window->property("menuItem3").value<QQuickMenuItem *>(); + QVERIFY(menuItem3); + + QQuickItem *button = window->property("button").value<QQuickItem *>(); + QVERIFY(button); + + QPoint oldCursorPos = QCursor::pos(); + QPoint cursorPos = window->mapToGlobal(QPoint(11, 22)); + QCursor::setPos(cursorPos); + QTRY_COMPARE(QCursor::pos(), cursorPos); + + QVERIFY(QMetaObject::invokeMethod(window, "popupAtCursor")); + QCOMPARE(menu->parentItem(), window->contentItem()); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), -1); + const qreal elevenOrLeftMargin = qMax(qreal(11), menu->leftMargin()); + const qreal twentyTwoOrTopMargin = qMax(qreal(22), menu->topMargin()); + // If the Menu has large margins, it may be moved to stay within them. + // QTBUG-75503: QTRY_COMPARE doesn't use qFuzzyCompare() in all cases, + // meaning a lot of these comparisons could trigger a 10 second wait; + // use QTRY_VERIFY and qFuzzyCompare instead. + QTRY_VERIFY(qFuzzyCompare(menu->x(), elevenOrLeftMargin)); + QTRY_VERIFY(qFuzzyCompare(menu->y(), twentyTwoOrTopMargin)); + menu->close(); + + QVERIFY(QMetaObject::invokeMethod(window, "popupAtPos", Q_ARG(QVariant, QPointF(33, 44)))); + QCOMPARE(menu->parentItem(), window->contentItem()); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), -1); + QTRY_VERIFY(qFuzzyCompare(menu->x(), qMax(qreal(33), menu->leftMargin()))); + QTRY_VERIFY(qFuzzyCompare(menu->y(), qMax(qreal(44), menu->topMargin()))); + menu->close(); + + QVERIFY(QMetaObject::invokeMethod(window, "popupAtCoord", Q_ARG(QVariant, 55), Q_ARG(QVariant, 66))); + QCOMPARE(menu->parentItem(), window->contentItem()); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), -1); + QTRY_VERIFY(qFuzzyCompare(menu->x(), qMax(qreal(55), menu->leftMargin()))); + QTRY_VERIFY(qFuzzyCompare(menu->y(), qMax(qreal(66), menu->topMargin()))); + menu->close(); + + menu->setParentItem(nullptr); + QVERIFY(QMetaObject::invokeMethod(window, "popupAtParentCursor", Q_ARG(QVariant, QVariant::fromValue(button)))); + QCOMPARE(menu->parentItem(), button); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), -1); + QTRY_VERIFY(qFuzzyCompare(menu->x(), button->mapFromScene(QPointF(elevenOrLeftMargin, twentyTwoOrTopMargin)).x())); + QTRY_VERIFY(qFuzzyCompare(menu->y(), button->mapFromScene(QPointF(elevenOrLeftMargin, twentyTwoOrTopMargin)).y())); + menu->close(); + + menu->setParentItem(nullptr); + QVERIFY(QMetaObject::invokeMethod(window, "popupAtParentPos", Q_ARG(QVariant, QVariant::fromValue(button)), Q_ARG(QVariant, QPointF(-11, -22)))); + QCOMPARE(menu->parentItem(), button); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), -1); + // Don't need to worry about margins here because we're opening close + // to the center of the window. + QTRY_VERIFY(qFuzzyCompare(menu->x(), -11)); + QTRY_VERIFY(qFuzzyCompare(menu->y(), -22)); + QCOMPARE(menu->popupItem()->position(), button->mapToScene(QPointF(-11, -22))); + menu->close(); + + menu->setParentItem(nullptr); + QVERIFY(QMetaObject::invokeMethod(window, "popupAtParentCoord", Q_ARG(QVariant, QVariant::fromValue(button)), Q_ARG(QVariant, -33), Q_ARG(QVariant, -44))); + QCOMPARE(menu->parentItem(), button); + QCOMPARE(menu->currentIndex(), -1); + QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), -1); + QTRY_VERIFY(qFuzzyCompare(menu->x(), -33)); + QTRY_VERIFY(qFuzzyCompare(menu->y(), -44)); + QCOMPARE(menu->popupItem()->position(), button->mapToScene(QPointF(-33, -44))); + menu->close(); + + const qreal twelveOrLeftMargin = qMax(qreal(12), menu->leftMargin()); + cursorPos = window->mapToGlobal(QPoint(twelveOrLeftMargin, window->height() / 2)); + QCursor::setPos(cursorPos); + QTRY_COMPARE(QCursor::pos(), cursorPos); + + const QList<QQuickMenuItem *> menuItems = QList<QQuickMenuItem *>() << menuItem1 << menuItem2 << menuItem3; + for (QQuickMenuItem *menuItem : menuItems) { + menu->resetParentItem(); + + QVERIFY(QMetaObject::invokeMethod(window, "popupItemAtCursor", Q_ARG(QVariant, QVariant::fromValue(menuItem)))); + QCOMPARE(menu->currentIndex(), menuItems.indexOf(menuItem)); + QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), menuItems.indexOf(menuItem)); + QTRY_VERIFY(qFuzzyCompare(menu->x(), twelveOrLeftMargin)); + QTRY_VERIFY(qFuzzyCompare(menu->y(), window->height() / 2 - menu->topPadding() - menuItem->y())); + menu->close(); + + QVERIFY(QMetaObject::invokeMethod(window, "popupItemAtPos", Q_ARG(QVariant, QPointF(33, window->height() / 3)), Q_ARG(QVariant, QVariant::fromValue(menuItem)))); + QCOMPARE(menu->currentIndex(), menuItems.indexOf(menuItem)); + QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), menuItems.indexOf(menuItem)); + QTRY_VERIFY(qFuzzyCompare(menu->x(), 33)); + QTRY_VERIFY(qFuzzyCompare(menu->y(), window->height() / 3 - menu->topPadding() - menuItem->y())); + menu->close(); + + QVERIFY(QMetaObject::invokeMethod(window, "popupItemAtCoord", Q_ARG(QVariant, 55), Q_ARG(QVariant, window->height() / 3 * 2), Q_ARG(QVariant, QVariant::fromValue(menuItem)))); + QCOMPARE(menu->currentIndex(), menuItems.indexOf(menuItem)); + QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), menuItems.indexOf(menuItem)); + QTRY_VERIFY(qFuzzyCompare(menu->x(), 55)); + QTRY_COMPARE_WITH_TIMEOUT(menu->y(), window->height() / 3 * 2 - menu->topPadding() - menuItem->y(), 500); + menu->close(); + + menu->setParentItem(nullptr); + QVERIFY(QMetaObject::invokeMethod(window, "popupItemAtParentCursor", Q_ARG(QVariant, QVariant::fromValue(button)), Q_ARG(QVariant, QVariant::fromValue(menuItem)))); + QCOMPARE(menu->parentItem(), button); + QCOMPARE(menu->currentIndex(), menuItems.indexOf(menuItem)); + QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), menuItems.indexOf(menuItem)); + QTRY_VERIFY(qFuzzyCompare(menu->x(), button->mapFromScene(QPoint(twelveOrLeftMargin, window->height() / 2)).x())); + QTRY_VERIFY(qFuzzyCompare(menu->y(), button->mapFromScene(QPoint(twelveOrLeftMargin, window->height() / 2)).y() - menu->topPadding() - menuItem->y())); + menu->close(); + + menu->setParentItem(nullptr); + QVERIFY(QMetaObject::invokeMethod(window, "popupItemAtParentPos", Q_ARG(QVariant, QVariant::fromValue(button)), Q_ARG(QVariant, QPointF(-11, -22)), Q_ARG(QVariant, QVariant::fromValue(menuItem)))); + QCOMPARE(menu->parentItem(), button); + QCOMPARE(menu->currentIndex(), menuItems.indexOf(menuItem)); + QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), menuItems.indexOf(menuItem)); + QTRY_VERIFY(qFuzzyCompare(menu->x(), -11)); + QTRY_VERIFY(qFuzzyCompare(menu->y(), -22 - menu->topPadding() - menuItem->y())); + QCOMPARE(menu->popupItem()->position(), button->mapToScene(QPointF(-11, -22 - menu->topPadding() - menuItem->y()))); + menu->close(); + + menu->setParentItem(nullptr); + QVERIFY(QMetaObject::invokeMethod(window, "popupItemAtParentCoord", Q_ARG(QVariant, QVariant::fromValue(button)), Q_ARG(QVariant, -33), Q_ARG(QVariant, -44), Q_ARG(QVariant, QVariant::fromValue(menuItem)))); + QCOMPARE(menu->parentItem(), button); + QCOMPARE(menu->currentIndex(), menuItems.indexOf(menuItem)); + QCOMPARE(menu->contentItem()->property("currentIndex").toInt(), menuItems.indexOf(menuItem)); + QTRY_VERIFY(qFuzzyCompare(menu->x(), -33)); + QTRY_VERIFY(qFuzzyCompare(menu->y(), -44 - menu->topPadding() - menuItem->y())); + QCOMPARE(menu->popupItem()->position(), button->mapToScene(QPointF(-33, -44 - menu->topPadding() - menuItem->y()))); + menu->close(); + } + + QCursor::setPos(oldCursorPos); + QTRY_COMPARE(QCursor::pos(), oldCursorPos); +} +#endif // QT_CONFIG(cursor) + +void tst_QQuickMenu::actions() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("actions.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu *>(); + QVERIFY(menu); + + QPointer<QQuickAction> action1 = menu->actionAt(0); + QVERIFY(!action1.isNull()); + + QPointer<QQuickAction> action3 = menu->actionAt(2); + QVERIFY(!action3.isNull()); + + QVERIFY(!menu->actionAt(1)); + QVERIFY(!menu->actionAt(3)); + + QPointer<QQuickMenuItem> menuItem1 = qobject_cast<QQuickMenuItem *>(menu->itemAt(0)); + QVERIFY(!menuItem1.isNull()); + QCOMPARE(menuItem1->action(), action1.data()); + QCOMPARE(menuItem1->text(), "action1"); + + QPointer<QQuickMenuItem> menuItem2 = qobject_cast<QQuickMenuItem *>(menu->itemAt(1)); + QVERIFY(!menuItem2.isNull()); + QVERIFY(!menuItem2->action()); + QCOMPARE(menuItem2->text(), "menuitem2"); + + QPointer<QQuickMenuItem> menuItem3 = qobject_cast<QQuickMenuItem *>(menu->itemAt(2)); + QVERIFY(!menuItem3.isNull()); + QCOMPARE(menuItem3->action(), action3.data()); + QCOMPARE(menuItem3->text(), "action3"); + + QPointer<QQuickMenuItem> menuItem4 = qobject_cast<QQuickMenuItem *>(menu->itemAt(3)); + QVERIFY(!menuItem4.isNull()); + QVERIFY(!menuItem4->action()); + QCOMPARE(menuItem4->text(), "menuitem4"); + + // takeAction(int) does not destroy the action, but does destroy the respective item + QCOMPARE(menu->takeAction(0), action1.data()); + QVERIFY(!menu->itemAt(3)); + QCoreApplication::sendPostedEvents(action1, QEvent::DeferredDelete); + QVERIFY(!action1.isNull()); + QCoreApplication::sendPostedEvents(menuItem1, QEvent::DeferredDelete); + QVERIFY(menuItem1.isNull()); + + // takeAction(int) does not destroy an item that doesn't have an action + QVERIFY(!menuItem2->subMenu()); + QVERIFY(!menu->takeAction(0)); + QCoreApplication::sendPostedEvents(menuItem2, QEvent::DeferredDelete); + QVERIFY(!menuItem2.isNull()); + + // addAction(Action) re-creates the respective item in the menu + menu->addAction(action1); + menuItem1 = qobject_cast<QQuickMenuItem *>(menu->itemAt(3)); + QVERIFY(!menuItem1.isNull()); + QCOMPARE(menuItem1->action(), action1.data()); + + // removeAction(Action) destroys both the action and the respective item + menu->removeAction(action1); + QVERIFY(!menu->itemAt(3)); + QCoreApplication::sendPostedEvents(action1, QEvent::DeferredDelete); + QVERIFY(action1.isNull()); + QCoreApplication::sendPostedEvents(menuItem1, QEvent::DeferredDelete); + QVERIFY(menuItem1.isNull()); +} + +#if QT_CONFIG(shortcut) +void tst_QQuickMenu::actionShortcuts() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("actionShortcuts.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + // Try the menu's shortcut. + QQuickMenu *menu = window->property("menu").value<QQuickMenu *>(); + QVERIFY(menu); + QPointer<QQuickAction> action1 = menu->actionAt(0); + QVERIFY(action1); + QCOMPARE(action1->shortcut(), QKeySequence(Qt::Key_A)); + + QSignalSpy action1TriggeredSpy(action1, SIGNAL(triggered())); + QVERIFY(action1TriggeredSpy.isValid()); + + QTest::keyClick(window, Qt::Key_A); + QCOMPARE(action1TriggeredSpy.count(), 1); + + // Try the sub-menu. + QQuickMenu *subMenu = window->property("subMenu").value<QQuickMenu *>(); + QVERIFY(subMenu); + QPointer<QQuickAction> subMenuAction1 = subMenu->actionAt(0); + QVERIFY(subMenuAction1); + QCOMPARE(subMenuAction1->shortcut(), QKeySequence(Qt::Key_B)); + + QSignalSpy subMenuAction1TriggeredSpy(subMenuAction1, SIGNAL(triggered())); + QVERIFY(subMenuAction1TriggeredSpy.isValid()); + + QTest::keyClick(window, Qt::Key_B); + QCOMPARE(subMenuAction1TriggeredSpy.count(), 1); + + // Try the button menu. + QQuickMenu *buttonMenu = window->property("buttonMenu").value<QQuickMenu *>(); + QVERIFY(buttonMenu); + QPointer<QQuickAction> buttonMenuAction1 = buttonMenu->actionAt(0); + QVERIFY(buttonMenuAction1); + QCOMPARE(buttonMenuAction1->shortcut(), QKeySequence(Qt::Key_C)); + + QSignalSpy buttonMenuAction1TriggeredSpy(buttonMenuAction1, SIGNAL(triggered())); + QVERIFY(buttonMenuAction1TriggeredSpy.isValid()); + + QTest::keyClick(window, Qt::Key_C); + QCOMPARE(buttonMenuAction1TriggeredSpy.count(), 1); +} +#endif + +void tst_QQuickMenu::removeTakeItem() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("removeTakeItem.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu *>(); + QVERIFY(menu); + + QPointer<QQuickMenuItem> menuItem1 = window->property("menuItem1").value<QQuickMenuItem *>(); + QVERIFY(!menuItem1.isNull()); + QCOMPARE(menuItem1->menu(), menu); + + QPointer<QQuickMenuItem> menuItem2 = window->property("menuItem2").value<QQuickMenuItem *>(); + QVERIFY(!menuItem2.isNull()); + QCOMPARE(menuItem2->menu(), menu); + + QPointer<QQuickMenuItem> menuItem3 = window->property("menuItem3").value<QQuickMenuItem *>(); + QVERIFY(!menuItem3.isNull()); + QCOMPARE(menuItem3->menu(), menu); + + // takeItem(int) does not destroy + QVariant ret; + QVERIFY(QMetaObject::invokeMethod(window, "takeSecondItem", Q_RETURN_ARG(QVariant, ret))); + QCOMPARE(ret.value<QQuickMenuItem *>(), menuItem2); + QVERIFY(!menuItem2->menu()); + QCoreApplication::sendPostedEvents(menuItem2, QEvent::DeferredDelete); + QVERIFY(!menuItem2.isNull()); + + // removeItem(Item) destroys + QVERIFY(QMetaObject::invokeMethod(window, "removeFirstItem")); + QVERIFY(!menuItem1->menu()); + QCoreApplication::sendPostedEvents(menuItem1, QEvent::DeferredDelete); + QVERIFY(menuItem1.isNull()); + + // removeItem(null) must not call removeItem(0) + QVERIFY(QMetaObject::invokeMethod(window, "removeNullItem")); + QCOMPARE(menuItem3->menu(), menu); + QCoreApplication::sendPostedEvents(menuItem3, QEvent::DeferredDelete); + QVERIFY(!menuItem3.isNull()); +} + +void tst_QQuickMenu::subMenuMouse_data() +{ + QTest::addColumn<bool>("cascade"); + + QTest::newRow("cascading") << true; + QTest::newRow("non-cascading") << false; +} + +void tst_QQuickMenu::subMenuMouse() +{ + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QSKIP("Mouse hovering not functional on offscreen/minimal platforms"); + + QFETCH(bool, cascade); + + QQuickControlsApplicationHelper helper(this, QLatin1String("subMenus.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *mainMenu = window->property("mainMenu").value<QQuickMenu *>(); + QVERIFY(mainMenu); + mainMenu->setCascade(cascade); + QCOMPARE(mainMenu->cascade(), cascade); + + QQuickMenu *subMenu1 = window->property("subMenu1").value<QQuickMenu *>(); + QVERIFY(subMenu1); + subMenu1->setCascade(cascade); + QCOMPARE(subMenu1->cascade(), cascade); + + QQuickMenu *subMenu2 = window->property("subMenu2").value<QQuickMenu *>(); + QVERIFY(subMenu2); + subMenu2->setCascade(cascade); + QCOMPARE(subMenu2->cascade(), cascade); + + QQuickMenu *subSubMenu1 = window->property("subSubMenu1").value<QQuickMenu *>(); + QVERIFY(subSubMenu1); + subSubMenu1->setCascade(cascade); + QCOMPARE(subSubMenu1->cascade(), cascade); + + mainMenu->open(); + QVERIFY(mainMenu->isVisible()); + QTRY_VERIFY(mainMenu->isOpened()); + QVERIFY(!subMenu1->isVisible()); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(!subSubMenu1->isVisible()); + + // open the sub-menu with mouse click + QQuickMenuItem *subMenu1Item = qobject_cast<QQuickMenuItem *>(mainMenu->itemAt(1)); + QVERIFY(subMenu1Item); + QCOMPARE(subMenu1Item->subMenu(), subMenu1); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, subMenu1Item->mapToScene(QPoint(1, 1)).toPoint()); + QTRY_COMPARE(mainMenu->isVisible(), cascade); + QVERIFY(subMenu1->isVisible()); + QTRY_VERIFY(subMenu1->isOpened()); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(!subSubMenu1->isVisible()); + + // on Android mouse hover will not open and close sub-menus +#ifndef Q_OS_ANDROID + // open the cascading sub-sub-menu with mouse hover + QQuickMenuItem *subSubMenu1Item = qobject_cast<QQuickMenuItem *>(subMenu1->itemAt(2)); + QVERIFY(subSubMenu1Item); + QCOMPARE(subSubMenu1Item->subMenu(), subSubMenu1); + QTest::mouseMove(window, subSubMenu1Item->mapToScene(QPoint(1, 1)).toPoint()); + QCOMPARE(mainMenu->isVisible(), cascade); + QVERIFY(subMenu1->isVisible()); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(!subSubMenu1->isVisible()); + if (cascade) { + QTRY_VERIFY(subSubMenu1->isVisible()); + QTRY_VERIFY(subSubMenu1->isOpened()); + } + + // close the sub-sub-menu with mouse hover over another parent menu item + QQuickMenuItem *subMenuItem1 = qobject_cast<QQuickMenuItem *>(subMenu1->itemAt(0)); + QVERIFY(subMenuItem1); + QVERIFY(!subMenuItem1->subMenu()); + QTest::mouseMove(window, subMenuItem1->mapToScene(QPoint(1, 1)).toPoint()); + QCOMPARE(mainMenu->isVisible(), cascade); + QVERIFY(subMenu1->isVisible()); + QVERIFY(!subMenu2->isVisible()); + QTRY_VERIFY(!subSubMenu1->isVisible()); + + // re-open the sub-sub-menu with mouse hover + QTest::mouseMove(window, subSubMenu1Item->mapToScene(QPoint(1, 1)).toPoint()); + QCOMPARE(mainMenu->isVisible(), cascade); + QVERIFY(subMenu1->isVisible()); + QVERIFY(!subMenu2->isVisible()); + if (!cascade) { + QVERIFY(!subSubMenu1->isVisible()); + } else { + QTRY_VERIFY(subSubMenu1->isVisible()); + QTRY_VERIFY(subSubMenu1->isOpened()); + } + + // close sub-menu and sub-sub-menu with mouse hover in the main menu + QQuickMenuItem *mainMenuItem1 = qobject_cast<QQuickMenuItem *>(mainMenu->itemAt(0)); + QVERIFY(mainMenuItem1); + QTest::mouseMove(window, mainMenuItem1->mapToScene(QPoint(1, 1)).toPoint()); + QCOMPARE(mainMenu->isVisible(), cascade); + QTRY_COMPARE(subMenu1->isVisible(), !cascade); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(!subSubMenu1->isVisible()); +#else + QQuickMenuItem *mainMenuItem1 = qobject_cast<QQuickMenuItem *>(mainMenu->itemAt(0)); + QVERIFY(mainMenuItem1); +#endif // !Q_OS_ANDROID + + // close all menus by click triggering an item + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, mainMenuItem1->mapToScene(QPoint(1, 1)).toPoint()); + QTRY_VERIFY(!mainMenu->isVisible()); + QTRY_VERIFY(!subMenu1->isVisible()); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(!subSubMenu1->isVisible()); +} + +void tst_QQuickMenu::subMenuDisabledMouse_data() +{ + subMenuMouse_data(); +} + +// QTBUG-69540 +void tst_QQuickMenu::subMenuDisabledMouse() +{ + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QSKIP("Mouse hovering not functional on offscreen/minimal platforms"); + + QFETCH(bool, cascade); + + QQuickControlsApplicationHelper helper(this, QLatin1String("subMenuDisabled.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *mainMenu = window->property("mainMenu").value<QQuickMenu *>(); + QVERIFY(mainMenu); + mainMenu->setCascade(cascade); + QCOMPARE(mainMenu->cascade(), cascade); + + QQuickMenuItem *menuItem1 = qobject_cast<QQuickMenuItem *>(mainMenu->itemAt(0)); + QVERIFY(menuItem1); + + QQuickMenu *subMenu = window->property("subMenu").value<QQuickMenu *>(); + QVERIFY(subMenu); + + mainMenu->open(); + QTRY_VERIFY(mainMenu->isOpened()); + QVERIFY(!menuItem1->isHighlighted()); + QVERIFY(!subMenu->isVisible()); + + // Hover-highlighting does not work on Android +#ifndef Q_OS_ANDROID + // Generate a hover event to set the current index + QTest::mouseMove(window, menuItem1->mapToScene(QPoint(2, 2)).toPoint()); + QTRY_VERIFY(menuItem1->isHighlighted()); +#endif + // Open the sub-menu with a mouse click. + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, menuItem1->mapToScene(QPoint(1, 1)).toPoint()); + // Need to use the TRY variant here, + // as e.g. Material, iOS style menus have transitions and don't open/close immediately. + QTRY_COMPARE(mainMenu->isVisible(), cascade); + QTRY_VERIFY(subMenu->isOpened()); + QTRY_VERIFY(menuItem1->isHighlighted()); + // Now the sub-menu is open. The current behavior is that the first menu item + // in the new menu is highlighted; make sure that we choose the next item if + // the first is disabled. + QQuickMenuItem *subMenuItem1 = qobject_cast<QQuickMenuItem *>(subMenu->itemAt(0)); + QVERIFY(subMenuItem1); + QQuickMenuItem *subMenuItem2 = qobject_cast<QQuickMenuItem *>(subMenu->itemAt(1)); + QVERIFY(subMenuItem2); + QVERIFY(!subMenuItem1->isHighlighted()); + QVERIFY(subMenuItem2->isHighlighted()); + + // Close all menus by clicking on the item that isn't disabled. + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, subMenuItem2->mapToScene(QPoint(1, 1)).toPoint()); + QTRY_VERIFY(!mainMenu->isVisible()); + QTRY_VERIFY(!subMenu->isVisible()); +} + +void tst_QQuickMenu::subMenuKeyboard_data() +{ + QTest::addColumn<bool>("cascade"); + QTest::addColumn<bool>("mirrored"); + + QTest::newRow("cascading") << true << false; + QTest::newRow("cascading,mirrored") << true << true; + QTest::newRow("non-cascading") << false << false; + QTest::newRow("non-cascading,mirrored") << false << true; +} + +void tst_QQuickMenu::subMenuKeyboard() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + QFETCH(bool, cascade); + QFETCH(bool, mirrored); + + QQuickControlsApplicationHelper helper(this, QLatin1String("subMenus.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + if (mirrored) { + QQmlExpression mirroringExpression(qmlContext(window), window, + "LayoutMirroring.childrenInherit = true; LayoutMirroring.enabled = true"); + QVERIFY2(mirroringExpression.evaluate().isValid(), qPrintable(mirroringExpression.error().toString())); + } + + QQuickMenu *mainMenu = window->property("mainMenu").value<QQuickMenu *>(); + QVERIFY(mainMenu); + mainMenu->setCascade(cascade); + QCOMPARE(mainMenu->cascade(), cascade); + + QQuickMenu *subMenu1 = window->property("subMenu1").value<QQuickMenu *>(); + QVERIFY(subMenu1); + + QQuickMenu *subMenu2 = window->property("subMenu2").value<QQuickMenu *>(); + QVERIFY(subMenu2); + + QQuickMenu *subSubMenu1 = window->property("subSubMenu1").value<QQuickMenu *>(); + QVERIFY(subSubMenu1); + + mainMenu->open(); + QVERIFY(mainMenu->isVisible()); + QTRY_VERIFY(mainMenu->isOpened()); + QVERIFY(!subMenu1->isVisible()); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(!subSubMenu1->isVisible()); + + // navigate to the sub-menu item and trigger it to open the sub-menu + QQuickMenuItem *subMenu1Item = qobject_cast<QQuickMenuItem *>(mainMenu->itemAt(1)); + QVERIFY(subMenu1Item); + QVERIFY(!subMenu1Item->isHighlighted()); + QCOMPARE(subMenu1Item->subMenu(), subMenu1); + QTest::keyClick(window, Qt::Key_Down); + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(subMenu1Item->isHighlighted()); + QTest::keyClick(window, Qt::Key_Space); + QTRY_COMPARE(mainMenu->isVisible(), cascade); + QVERIFY(subMenu1->isVisible()); + QTRY_VERIFY(subMenu1->isOpened()); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(!subSubMenu1->isVisible()); + + // navigate to the sub-sub-menu item and open it with the arrow key + QQuickMenuItem *subSubMenu1Item = qobject_cast<QQuickMenuItem *>(subMenu1->itemAt(2)); + QVERIFY(subSubMenu1Item); + QVERIFY(!subSubMenu1Item->isHighlighted()); + QCOMPARE(subSubMenu1Item->subMenu(), subSubMenu1); + QTest::keyClick(window, Qt::Key_Down); + QTest::keyClick(window, Qt::Key_Down); + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(subSubMenu1Item->isHighlighted()); + QTRY_COMPARE(mainMenu->isVisible(), cascade); + QVERIFY(subMenu1->isVisible()); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(!subSubMenu1->isVisible()); + QTest::keyClick(window, mirrored ? Qt::Key_Left : Qt::Key_Right); + QCOMPARE(mainMenu->isVisible(), cascade); + QTRY_COMPARE(subMenu1->isVisible(), cascade); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(subSubMenu1->isVisible()); + QTRY_VERIFY(subSubMenu1->isOpened()); + + // navigate within the sub-sub-menu + QQuickMenuItem *subSubMenuItem1 = qobject_cast<QQuickMenuItem *>(subSubMenu1->itemAt(0)); + QVERIFY(subSubMenuItem1); + QQuickMenuItem *subSubMenuItem2 = qobject_cast<QQuickMenuItem *>(subSubMenu1->itemAt(1)); + QVERIFY(subSubMenuItem2); + QVERIFY(subSubMenuItem1->isHighlighted()); + QVERIFY(!subSubMenuItem2->isHighlighted()); + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(!subSubMenuItem1->isHighlighted()); + QVERIFY(subSubMenuItem2->isHighlighted()); + + // navigate to the parent menu with the arrow key + QTest::keyClick(window, mirrored ? Qt::Key_Right : Qt::Key_Left); + QVERIFY(subSubMenu1Item->isHighlighted()); + QCOMPARE(mainMenu->isVisible(), cascade); + QVERIFY(subMenu1->isVisible()); + QVERIFY(!subMenu2->isVisible()); + QTRY_VERIFY(!subSubMenu1->isVisible()); + + // navigate within the sub-menu + QQuickMenuItem *subMenuItem1 = qobject_cast<QQuickMenuItem *>(subMenu1->itemAt(0)); + QVERIFY(subMenuItem1); + QQuickMenuItem *subMenuItem2 = qobject_cast<QQuickMenuItem *>(subMenu1->itemAt(1)); + QVERIFY(subMenuItem2); + QVERIFY(!subMenuItem1->isHighlighted()); + QVERIFY(!subMenuItem2->isHighlighted()); + QVERIFY(subSubMenu1Item->isHighlighted()); + QTest::keyClick(window, Qt::Key_Up); + QVERIFY(!subMenuItem1->isHighlighted()); + QVERIFY(subMenuItem2->isHighlighted()); + QVERIFY(!subSubMenu1Item->isHighlighted()); + + // close the menus with esc + QTest::keyClick(window, Qt::Key_Escape); + QCOMPARE(mainMenu->isVisible(), cascade); + QTRY_VERIFY(!subMenu1->isVisible()); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(!subSubMenu1->isVisible()); + QTest::keyClick(window, Qt::Key_Escape); + QTRY_VERIFY(!mainMenu->isVisible()); + QVERIFY(!subMenu1->isVisible()); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(!subSubMenu1->isVisible()); +} + +void tst_QQuickMenu::subMenuDisabledKeyboard_data() +{ + subMenuKeyboard_data(); +} + +// QTBUG-69540 +void tst_QQuickMenu::subMenuDisabledKeyboard() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + QFETCH(bool, cascade); + QFETCH(bool, mirrored); + + QQuickControlsApplicationHelper helper(this, QLatin1String("subMenuDisabled.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + if (mirrored) { + QQmlExpression mirroringExpression(qmlContext(window), window, + "LayoutMirroring.childrenInherit = true; LayoutMirroring.enabled = true"); + QVERIFY2(mirroringExpression.evaluate().isValid(), qPrintable(mirroringExpression.error().toString())); + } + + QQuickMenu *mainMenu = window->property("mainMenu").value<QQuickMenu *>(); + QVERIFY(mainMenu); + mainMenu->setCascade(cascade); + QCOMPARE(mainMenu->cascade(), cascade); + + QQuickMenuItem *menuItem1 = qobject_cast<QQuickMenuItem *>(mainMenu->itemAt(0)); + QVERIFY(menuItem1); + + QQuickMenu *subMenu = window->property("subMenu").value<QQuickMenu *>(); + QVERIFY(subMenu); + + mainMenu->open(); + QVERIFY(mainMenu->isVisible()); + QTRY_VERIFY(mainMenu->isOpened()); + QVERIFY(!menuItem1->isHighlighted()); + QVERIFY(!subMenu->isVisible()); + + // Highlight the top-level menu item. + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(menuItem1->isHighlighted()); + + QQuickMenuItem *subMenuItem1 = qobject_cast<QQuickMenuItem *>(subMenu->itemAt(0)); + QVERIFY(subMenuItem1); + QQuickMenuItem *subMenuItem2 = qobject_cast<QQuickMenuItem *>(subMenu->itemAt(1)); + QVERIFY(subMenuItem2); + + // Open the sub-menu. + QTest::keyClick(window, mirrored ? Qt::Key_Left : Qt::Key_Right); + // The first sub-menu item is disabled, so it should highlight the second one. + QVERIFY(!subMenuItem1->isHighlighted()); + QVERIFY(subMenuItem2->isHighlighted()); + + // Close the menus with escape. + QTest::keyClick(window, Qt::Key_Escape); + QTRY_COMPARE(mainMenu->isVisible(), cascade); + QTRY_VERIFY(!subMenu->isVisible()); + QTest::keyClick(window, Qt::Key_Escape); + QTRY_VERIFY(!mainMenu->isVisible()); + QVERIFY(!subMenu->isVisible()); +} + +/* + QCOMPARE() compares doubles with 1-in-1e12 precision, which is too fine for these tests. + Casting to floats, compared with 1-in-1e5 precision, gives more robust results. +*/ +#define FLOAT_EQ(u, v) QCOMPARE(float(u), float(v)) + +void tst_QQuickMenu::subMenuPosition_data() +{ + QTest::addColumn<bool>("cascade"); + QTest::addColumn<bool>("flip"); + QTest::addColumn<bool>("mirrored"); + QTest::addColumn<qreal>("overlap"); + + QTest::newRow("cascading") << true << false << false << 0.0; + QTest::newRow("cascading,flip") << true << true << false << 0.0; + QTest::newRow("cascading,overlap") << true << false << false << 10.0; + QTest::newRow("cascading,flip,overlap") << true << true << false << 10.0; + QTest::newRow("cascading,mirrored") << true << false << true << 0.0; + QTest::newRow("cascading,mirrored,flip") << true << true << true << 0.0; + QTest::newRow("cascading,mirrored,overlap") << true << false << true << 10.0; + QTest::newRow("cascading,mirrored,flip,overlap") << true << true << true << 10.0; + QTest::newRow("non-cascading") << false << false << false << 0.0; +} + +void tst_QQuickMenu::subMenuPosition() +{ + QFETCH(bool, cascade); + QFETCH(bool, flip); + QFETCH(bool, mirrored); + QFETCH(qreal, overlap); + + QQuickControlsApplicationHelper helper(this, QLatin1String("subMenus.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + + // Ensure that the default size of the window fits three menus side by side. + QQuickMenu *mainMenu = window->property("mainMenu").value<QQuickMenu *>(); + QVERIFY(mainMenu); + window->setWidth(mainMenu->width() * 3 + mainMenu->leftMargin() + mainMenu->rightMargin()); + + // the default size of the window fits three menus side by side. + // when testing flipping, we resize the window so that the first + // sub-menu fits, but the second doesn't + if (flip) + window->setWidth(window->width() - mainMenu->width()); + + centerOnScreen(window); + moveMouseAway(window); +#ifndef Q_OS_ANDROID + window->show(); +#else + // On Android the desired size does not fit into the screen, so we just + // call showNormal. This will make the window larger than the screen, but + // all the geometry calculations will be correct. Otherwise we'll get + // unpredictable results + window->showNormal(); +#endif + QVERIFY(QTest::qWaitForWindowExposed(window)); + + if (mirrored) { + QQmlExpression mirroringExpression(qmlContext(window), window, + "LayoutMirroring.childrenInherit = true; LayoutMirroring.enabled = true"); + QVERIFY2(mirroringExpression.evaluate().isValid(), qPrintable(mirroringExpression.error().toString())); + } + + mainMenu->setCascade(cascade); + QCOMPARE(mainMenu->cascade(), cascade); + mainMenu->setOverlap(overlap); + QCOMPARE(mainMenu->overlap(), overlap); + + QQuickMenu *subMenu1 = window->property("subMenu1").value<QQuickMenu *>(); + QVERIFY(subMenu1); + subMenu1->setCascade(cascade); + QCOMPARE(subMenu1->cascade(), cascade); + subMenu1->setOverlap(overlap); + QCOMPARE(subMenu1->overlap(), overlap); + + QQuickMenu *subMenu2 = window->property("subMenu2").value<QQuickMenu *>(); + QVERIFY(subMenu2); + subMenu2->setCascade(cascade); + QCOMPARE(subMenu2->cascade(), cascade); + subMenu2->setOverlap(overlap); + QCOMPARE(subMenu2->overlap(), overlap); + + QQuickMenu *subSubMenu1 = window->property("subSubMenu1").value<QQuickMenu *>(); + QVERIFY(subSubMenu1); + subSubMenu1->setCascade(cascade); + QCOMPARE(subSubMenu1->cascade(), cascade); + subSubMenu1->setOverlap(overlap); + QCOMPARE(subSubMenu1->overlap(), overlap); + + // choose the main menu position so that there's room for the + // sub-menus to cascade to the left when mirrored + if (mirrored) + mainMenu->setX(window->width() - mainMenu->width()); + + mainMenu->open(); + QVERIFY(mainMenu->isVisible()); + QTRY_VERIFY(mainMenu->isOpened()); + QVERIFY(!subMenu1->isVisible()); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(!subSubMenu1->isVisible()); + + // open the sub-menu (never flips) + QQuickMenuItem *subMenu1Item = qobject_cast<QQuickMenuItem *>(mainMenu->itemAt(1)); + QVERIFY(subMenu1Item); + QCOMPARE(subMenu1Item->subMenu(), subMenu1); + emit subMenu1Item->triggered(); + QTRY_COMPARE(mainMenu->isVisible(), cascade); + QVERIFY(subMenu1->isVisible()); + QTRY_VERIFY(subMenu1->isOpened()); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(!subSubMenu1->isVisible()); + + if (cascade) { + QCOMPARE(subMenu1->parentItem(), subMenu1Item); + // vertically aligned to the parent menu item + // We cast to float here because we want to use its larger tolerance for equality (because it has less precision than double). + FLOAT_EQ(subMenu1->popupItem()->y(), mainMenu->popupItem()->y() + subMenu1Item->y()); + if (mirrored) { + // on the left of the parent menu + FLOAT_EQ(subMenu1->popupItem()->x(), mainMenu->popupItem()->x() - subMenu1->width() + overlap); + } else { + // on the right of the parent menu + FLOAT_EQ(subMenu1->popupItem()->x(), mainMenu->popupItem()->x() + mainMenu->width() - overlap); + } + } else { + QCOMPARE(subMenu1->parentItem(), mainMenu->parentItem()); + // centered over the parent menu + FLOAT_EQ(subMenu1->popupItem()->x(), mainMenu->popupItem()->x() + (mainMenu->width() - subMenu1->width()) / 2); + FLOAT_EQ(subMenu1->popupItem()->y(), mainMenu->popupItem()->y() + (mainMenu->height() - subMenu1->height()) / 2); + } + + // open the sub-sub-menu (can flip) + QQuickMenuItem *subSubMenu1Item = qobject_cast<QQuickMenuItem *>(subMenu1->itemAt(2)); + QVERIFY(subSubMenu1Item); + QCOMPARE(subSubMenu1Item->subMenu(), subSubMenu1); + emit subSubMenu1Item->triggered(); + QTRY_COMPARE(mainMenu->isVisible(), cascade); + QTRY_COMPARE(subMenu1->isVisible(), cascade); + QVERIFY(!subMenu2->isVisible()); + QVERIFY(subSubMenu1->isVisible()); + QTRY_VERIFY(subSubMenu1->isOpened()); + + if (cascade) { + QCOMPARE(subSubMenu1->parentItem(), subSubMenu1Item); + // vertically aligned to the parent menu item + FLOAT_EQ(subSubMenu1->popupItem()->y(), subMenu1->popupItem()->y() + subSubMenu1Item->y()); + if (mirrored != flip) { + // on the left of the parent menu + FLOAT_EQ(subSubMenu1->popupItem()->x(), subMenu1->popupItem()->x() - subSubMenu1->width() + overlap); + } else { + // on the right of the parent menu + FLOAT_EQ(subSubMenu1->popupItem()->x(), subMenu1->popupItem()->x() + subMenu1->width() - overlap); + } + } else { + QCOMPARE(subSubMenu1->parentItem(), subMenu1->parentItem()); + // centered over the parent menu + FLOAT_EQ(subSubMenu1->popupItem()->x(), subMenu1->popupItem()->x() + (subMenu1->width() - subSubMenu1->width()) / 2); + FLOAT_EQ(subSubMenu1->popupItem()->y(), subMenu1->popupItem()->y() + (subMenu1->height() - subSubMenu1->height()) / 2); + } +} + +#undef FLOAT_EQ + +void tst_QQuickMenu::addRemoveSubMenus() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("subMenus.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *mainMenu = window->property("mainMenu").value<QQuickMenu *>(); + QVERIFY(mainMenu); + + QVERIFY(!mainMenu->menuAt(0)); + + QPointer<QQuickMenu> subMenu1 = window->property("subMenu1").value<QQuickMenu *>(); + QVERIFY(!subMenu1.isNull()); + QCOMPARE(mainMenu->menuAt(1), subMenu1.data()); + + QVERIFY(!mainMenu->menuAt(2)); + + QPointer<QQuickMenu> subMenu2 = window->property("subMenu2").value<QQuickMenu *>(); + QVERIFY(!subMenu2.isNull()); + QCOMPARE(mainMenu->menuAt(3), subMenu2.data()); + + QVERIFY(!mainMenu->menuAt(4)); + + QPointer<QQuickMenu> subSubMenu1 = window->property("subSubMenu1").value<QQuickMenu *>(); + QVERIFY(!subSubMenu1.isNull()); + + // takeMenu(int) does not destroy the menu, but does destroy the respective item in the parent menu + QPointer<QQuickMenuItem> subSubMenu1Item = qobject_cast<QQuickMenuItem *>(subMenu1->itemAt(2)); + QVERIFY(subSubMenu1Item); + QCOMPARE(subSubMenu1Item->subMenu(), subSubMenu1.data()); + QCOMPARE(subMenu1->takeMenu(2), subSubMenu1.data()); + QVERIFY(!subMenu1->itemAt(2)); + QCoreApplication::sendPostedEvents(subSubMenu1, QEvent::DeferredDelete); + QVERIFY(!subSubMenu1.isNull()); + QCoreApplication::sendPostedEvents(subSubMenu1Item, QEvent::DeferredDelete); + QVERIFY(subSubMenu1Item.isNull()); + + // takeMenu(int) does not destroy an item that doesn't present a menu + QPointer<QQuickMenuItem> subMenuItem1 = qobject_cast<QQuickMenuItem *>(subMenu1->itemAt(0)); + QVERIFY(subMenuItem1); + QVERIFY(!subMenuItem1->subMenu()); + QVERIFY(!subMenu1->takeMenu(0)); + QCoreApplication::sendPostedEvents(subMenuItem1, QEvent::DeferredDelete); + QVERIFY(!subMenuItem1.isNull()); + + // addMenu(Menu) re-creates the respective item in the parent menu + subMenu1->addMenu(subSubMenu1); + subSubMenu1Item = qobject_cast<QQuickMenuItem *>(subMenu1->itemAt(2)); + QVERIFY(!subSubMenu1Item.isNull()); + + // removeMenu(Menu) destroys both the menu and the respective item in the parent menu + subMenu1->removeMenu(subSubMenu1); + QVERIFY(!subMenu1->itemAt(2)); + QCoreApplication::sendPostedEvents(subSubMenu1, QEvent::DeferredDelete); + QVERIFY(subSubMenu1.isNull()); + QCoreApplication::sendPostedEvents(subSubMenu1Item, QEvent::DeferredDelete); + QVERIFY(subSubMenu1Item.isNull()); +} + +void tst_QQuickMenu::scrollable_data() +{ + QTest::addColumn<QString>("qmlFilePath"); + + QTest::addRow("Window") << QString::fromLatin1("windowScrollable.qml"); + QTest::addRow("ApplicationWindow") << QString::fromLatin1("applicationWindowScrollable.qml"); + QTest::addRow("WithPadding") << QString::fromLatin1("scrollableWithPadding.qml"); + QTest::addRow("FixedHeight") << QString::fromLatin1("scrollableWithFixedHeight.qml"); +} + +void tst_QQuickMenu::scrollable() +{ + QFETCH(QString, qmlFilePath); + + QQuickControlsApplicationHelper helper(this, qmlFilePath); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; +#ifndef Q_OS_ANDROID + window->show(); +#else + window->showNormal(); +#endif + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + menu->open(); + QVERIFY(menu->isVisible()); + + QQuickItem *contentItem = menu->contentItem(); + QCOMPARE(contentItem->property("interactive").toBool(), true); +} + +void tst_QQuickMenu::disableWhenTriggered_data() +{ + QTest::addColumn<int>("menuItemIndex"); + QTest::addColumn<int>("subMenuItemIndex"); + + QTest::addRow("Action") << 0 << -1; + QTest::addRow("MenuItem with Action") << 1 << -1; + QTest::addRow("MenuItem with Action declared outside menu") << 2 << -1; + QTest::addRow("MenuItem with no Action") << 3 << -1; + + QTest::addRow("Sub-Action") << 4 << 0; + QTest::addRow("Sub-MenuItem with Action declared inside") << 4 << 1; + QTest::addRow("Sub-MenuItem with Action declared outside menu") << 4 << 2; + QTest::addRow("Sub-MenuItem with no Action") << 4 << 3; +} + +// Tests that the menu is dismissed when a menu item sets "enabled = false" in onTriggered(). +void tst_QQuickMenu::disableWhenTriggered() +{ + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QSKIP("Mouse hovering not functional on offscreen/minimal platforms"); + + QFETCH(int, menuItemIndex); + QFETCH(int, subMenuItemIndex); + + QQuickControlsApplicationHelper helper(this, QLatin1String("disableWhenTriggered.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *menu = window->findChild<QQuickMenu*>("Menu"); + QVERIFY(menu); + + menu->open(); + QVERIFY(menu->isVisible()); + QTRY_VERIFY(menu->isOpened()); + + QPointer<QQuickMenuItem> menuItem = qobject_cast<QQuickMenuItem*>(menu->itemAt(menuItemIndex)); + QVERIFY(menuItem); + + if (subMenuItemIndex == -1) { + // Click a top-level menu item. + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, + menuItem->mapToScene(QPointF(menuItem->width() / 2, menuItem->height() / 2)).toPoint()); + QCOMPARE(menuItem->isEnabled(), false); + QTRY_VERIFY(!menu->isVisible()); + } else { + // Click a sub-menu item. + QPointer<QQuickMenu> subMenu = menuItem->subMenu(); + QVERIFY(subMenu); + + QPointer<QQuickMenuItem> subMenuItem = qobject_cast<QQuickMenuItem*>(subMenu->itemAt(subMenuItemIndex)); + QVERIFY(subMenuItem); + + // First, open the sub-menu. +#ifndef Q_OS_ANDROID + QTest::mouseMove(window, menuItem->mapToScene(QPoint(1, 1)).toPoint()); +#else + // On Android mouseHover does not open sub-menu, so just click on it + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, + menuItem->mapToScene(QPointF(menuItem->width() / 2, menuItem->height() / 2)).toPoint()); +#endif + + QTRY_VERIFY(subMenu->isVisible()); +#ifndef Q_OS_ANDROID + QVERIFY(menuItem->isHovered()); + QTRY_VERIFY(subMenu->contentItem()->property("contentHeight").toReal() > 0.0); +#endif + + // Click the item. + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, + subMenuItem->mapToScene(QPointF(subMenuItem->width() / 2, subMenuItem->height() / 2)).toPoint()); + QCOMPARE(subMenuItem->isEnabled(), false); + QTRY_VERIFY(!menu->isVisible()); + } +} + +void tst_QQuickMenu::menuItemWidth_data() +{ + QTest::addColumn<bool>("mirrored"); + + QTest::newRow("non-mirrored") << false; + QTest::newRow("mirrored") << true; +} + +void tst_QQuickMenu::menuItemWidth() +{ + QFETCH(bool, mirrored); + + QQuickControlsApplicationHelper helper(this, QLatin1String("menuItemWidths.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + if (mirrored) { + QQmlExpression mirroringExpression(qmlContext(window), window, + "LayoutMirroring.childrenInherit = true; LayoutMirroring.enabled = true"); + QVERIFY2(mirroringExpression.evaluate().isValid(), qPrintable(mirroringExpression.error().toString())); + } + + QQuickMenu *menu = window->property("menu").value<QQuickMenu *>(); + QVERIFY(menu); + menu->open(); + QTRY_VERIFY(menu->isOpened()); + for (int i = 0; i < menu->count(); ++i) + QCOMPARE(menu->itemAt(i)->width(), menu->availableWidth()); +} + +void tst_QQuickMenu::menuItemWidthAfterMenuWidthChanged_data() +{ + QTest::addColumn<bool>("mirrored"); + + QTest::newRow("non-mirrored") << false; + QTest::newRow("mirrored") << true; +} + +void tst_QQuickMenu::menuItemWidthAfterMenuWidthChanged() +{ + QFETCH(bool, mirrored); + + QQuickControlsApplicationHelper helper(this, QLatin1String("menuItemWidths.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + if (mirrored) { + QQmlExpression mirroringExpression(qmlContext(window), window, + "LayoutMirroring.childrenInherit = true; LayoutMirroring.enabled = true"); + QVERIFY2(mirroringExpression.evaluate().isValid(), qPrintable(mirroringExpression.error().toString())); + } + + QQuickMenu *menu = window->property("menu").value<QQuickMenu *>(); + QVERIFY(menu); + menu->open(); + QTRY_VERIFY(menu->isOpened()); + for (int i = 0; i < menu->count(); ++i) { + // Check that the width of menu items is correct before we resize the menu. + const QQuickItem *item = menu->itemAt(i); + QVERIFY2(qFuzzyCompare(item->width(), menu->availableWidth()), + qPrintable(QString::fromLatin1("Expected width of %1 to be %2, but it's %3") + .arg(item->objectName()).arg(menu->availableWidth()).arg(item->width()))); + } + + menu->setWidth(menu->width() + 10); + + // Check that the width of menu items is correct after we resize the menu. + for (int i = 0; i < menu->count(); ++i) { + // Check that the width of menu items is correct after we resize the menu. + const QQuickItem *item = menu->itemAt(i); + QVERIFY2(qFuzzyCompare(item->width(), menu->availableWidth()), + qPrintable(QString::fromLatin1("Expected width of %1 to be %2, but it's %3") + .arg(item->objectName()).arg(menu->availableWidth()).arg(item->width()))); + } +} + +void tst_QQuickMenu::menuItemWidthAfterImplicitWidthChanged_data() +{ + QTest::addColumn<bool>("mirrored"); + + QTest::newRow("non-mirrored") << false; + QTest::newRow("mirrored") << true; +} + +void tst_QQuickMenu::menuItemWidthAfterImplicitWidthChanged() +{ + QFETCH(bool, mirrored); + + QQuickControlsApplicationHelper helper(this, QLatin1String("menuItemWidths.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + if (mirrored) { + QQmlExpression mirroringExpression(qmlContext(window), window, + "LayoutMirroring.childrenInherit = true; LayoutMirroring.enabled = true"); + QVERIFY2(mirroringExpression.evaluate().isValid(), qPrintable(mirroringExpression.error().toString())); + } + + QQuickMenu *menu = window->property("menu").value<QQuickMenu *>(); + QVERIFY(menu); + menu->open(); + QTRY_VERIFY(menu->isOpened()); + // Check that the width of the menu item is correct before we change its font size. + QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem*>(menu->itemAt(0)); + QCOMPARE(menuItem->width(), menu->availableWidth()); + + // Add some text to increase the implicitWidth of the MenuItem. + const qreal oldImplicitWidth = menuItem->implicitWidth(); + for (int i = 0; menuItem->implicitWidth() <= oldImplicitWidth; ++i) { + menuItem->setText(menuItem->text() + QLatin1String("---")); + if (i == 100) + QFAIL("Shouldn't need 100 iterations to increase MenuItem's implicitWidth; something is wrong here"); + } + + // Check that the width of the menu item is correct after we change its font size. + QCOMPARE(menuItem->width(), menu->availableWidth()); +} + +void tst_QQuickMenu::menuItemWidthAfterRetranslate() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("menuItemWidths.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu *>(); + QVERIFY(menu); + menu->open(); + QTRY_VERIFY(menu->isOpened()); + for (int i = 0; i < menu->count(); ++i) { + // Check that the width of each menu item is correct before we retranslate. + const QQuickItem *item = menu->itemAt(i); + QVERIFY2(qFuzzyCompare(item->width(), menu->availableWidth()), + qPrintable(QString::fromLatin1("Expected width of %1 to be %2, but it's %3") + .arg(item->objectName()).arg(menu->availableWidth()).arg(item->width()))); + } + + // Call retranslate() and cause all bindings to be re-evaluated. + helper.engine.retranslate(); + + for (int i = 0; i < menu->count(); ++i) { + // Check that the width of each menu item is correct after we retranslate. + const QQuickItem *item = menu->itemAt(i); + QVERIFY2(qFuzzyCompare(item->width(), menu->availableWidth()), + qPrintable(QString::fromLatin1("Expected width of %1 to be %2, but it's %3") + .arg(item->objectName()).arg(menu->availableWidth()).arg(item->width()))); + } +} + +void tst_QQuickMenu::giveMenuItemFocusOnButtonPress() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + QQuickControlsApplicationHelper helper(this, QLatin1String("giveMenuItemFocusOnButtonPress.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + // Press enter on the button to open the menu. + QQuickButton *menuButton = window->property("menuButton").value<QQuickButton*>(); + QVERIFY(menuButton); + menuButton->forceActiveFocus(); + QVERIFY(menuButton->hasActiveFocus()); + + QSignalSpy clickedSpy(window, SIGNAL(menuButtonClicked())); + QVERIFY(clickedSpy.isValid()); + + QTest::keyClick(window, Qt::Key_Return); + QCOMPARE(clickedSpy.count(), 1); + + // The menu should still be open. + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + QVERIFY(menu); + QTRY_VERIFY(menu->isOpened()); +} + +QTEST_QUICKCONTROLS_MAIN(tst_QQuickMenu) + +#include "tst_qquickmenu.moc" diff --git a/tests/auto/quickcontrols2/qquickmenubar/BLACKLIST b/tests/auto/quickcontrols2/qquickmenubar/BLACKLIST new file mode 100644 index 00000000000..44dea1552c0 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenubar/BLACKLIST @@ -0,0 +1,7 @@ +# QTBUG-100254 +[mouse] +android +[keys] +android +[mnemonics] +android diff --git a/tests/auto/quickcontrols2/qquickmenubar/CMakeLists.txt b/tests/auto/quickcontrols2/qquickmenubar/CMakeLists.txt new file mode 100644 index 00000000000..88735ad57fa --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenubar/CMakeLists.txt @@ -0,0 +1,48 @@ +# Generated from qquickmenubar.pro. + +##################################################################### +## tst_qquickmenubar Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickmenubar + SOURCES + tst_qquickmenubar.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:qquickmenubar.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickmenubar CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickmenubar CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickmenubar/data/checkHighlightWhenDismissed.qml b/tests/auto/quickcontrols2/qquickmenubar/data/checkHighlightWhenDismissed.qml new file mode 100644 index 00000000000..14ee692edad --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenubar/data/checkHighlightWhenDismissed.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 300 + height: 300 + visible: true + MenuBar { + id: mb + objectName: "menuBar" + width: parent.width + Menu { + title: "StaticMenu" + MenuItem { + text: "Cut" + } + MenuItem { + text: "Copy" + } + MenuItem { + text: "Paste" + } + } + } + Component { + id: cmp + Menu { + title: "DynamicMenu" + MenuItem { + text: "Cut" + } + MenuItem { + text: "Copy" + } + MenuItem { + text: "Paste" + } + } + } + Component.onCompleted: { + mb.addMenu(cmp.createObject(mb)) + } +} diff --git a/tests/auto/quickcontrols2/qquickmenubar/data/delegateFromSeparateComponent.qml b/tests/auto/quickcontrols2/qquickmenubar/data/delegateFromSeparateComponent.qml new file mode 100644 index 00000000000..760151901f5 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenubar/data/delegateFromSeparateComponent.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 800 + height: 800 + + Component { + id: menuBarItemComponent + + MenuBarItem { + contentItem: Text { + text: parent.text + color: "blue" + } + background: Rectangle { + color: "#00ff00" + } + } + } + + menuBar: MenuBar { + delegate: menuBarItemComponent + + Menu { + title: "Menu" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickmenubar/data/empty.qml b/tests/auto/quickcontrols2/qquickmenubar/data/empty.qml new file mode 100644 index 00000000000..6cb3c92299c --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenubar/data/empty.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +MenuBar { } diff --git a/tests/auto/quickcontrols2/qquickmenubar/data/menubar.qml b/tests/auto/quickcontrols2/qquickmenubar/data/menubar.qml new file mode 100644 index 00000000000..1436e66d0b3 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenubar/data/menubar.qml @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + readonly property Button oopsButton: oopsButton + + width: 400 + height: 400 + visible: true + + header: MenuBar { + MenuBarItem { + menu: Menu { + title: "&File" + MenuItem { text: "&Open..." } + MenuItem { text: "&Save" } + MenuItem { text: "Save &As..." } + MenuSeparator { } + MenuItem { text: "&Quit" } + } + } + MenuBarItem { + menu: Menu { + title: "&Edit" + MenuItem { text: "&Cut" } + MenuItem { text: "&Copy" } + MenuItem { text: "&Paste" } + } + } + MenuBarItem { + menu: Menu { + title: "&View" + Menu { + title: "&Alignment" + Menu { + title: "&Horizontal" + MenuItem { text: "&Left" } + MenuItem { text: "&Center" } + MenuItem { text: "&Right" } + } + Menu { + title: "&Vertical" + MenuItem { text: "&Top" } + MenuItem { text: "&Center" } + MenuItem { text: "&Bottom" } + } + } + } + } + + MenuBarItem { + menu: Menu { + title: "&Help" + MenuItem { text: "&About" } + } + } + } + + Button { + id: oopsButton + text: "&Oops" + } +} diff --git a/tests/auto/quickcontrols2/qquickmenubar/tst_qquickmenubar.cpp b/tests/auto/quickcontrols2/qquickmenubar/tst_qquickmenubar.cpp new file mode 100644 index 00000000000..20d6ad019f2 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickmenubar/tst_qquickmenubar.cpp @@ -0,0 +1,691 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/qpa/qplatformintegration.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtTest> +#include <QtQml> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickbutton_p.h> +#include <QtQuickTemplates2/private/qquickmenu_p.h> +#include <QtQuickTemplates2/private/qquickmenubar_p.h> +#include <QtQuickTemplates2/private/qquickmenubaritem_p.h> +#include <QtQuickTemplates2/private/qquickmenuitem_p.h> +#include <QtQuickControlsTestUtils/private/qtest_quickcontrols_p.h> + +using namespace QQuickVisualTestUtils; + +class tst_qquickmenubar : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_qquickmenubar(); + +private slots: + void delegate(); + void mouse(); + void keys(); + void mnemonics(); + void addRemove(); + void checkHighlightWhenMenuDismissed(); + +private: + static bool hasWindowActivation(); +}; + +tst_qquickmenubar::tst_qquickmenubar() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +bool tst_qquickmenubar::hasWindowActivation() +{ + return (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)); +} + +void tst_qquickmenubar::delegate() +{ + QQmlApplicationEngine engine(testFileUrl("empty.qml")); + QScopedPointer<QQuickMenuBar> menuBar(qobject_cast<QQuickMenuBar *>(engine.rootObjects().value(0))); + QVERIFY(menuBar); + + QQmlComponent *delegate = menuBar->delegate(); + QVERIFY(delegate); + + QScopedPointer<QQuickMenuBarItem> item(qobject_cast<QQuickMenuBarItem *>(delegate->create())); + QVERIFY(item); +} + +void tst_qquickmenubar::mouse() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QSKIP("Mouse highlight not functional on offscreen/minimal platforms"); + + QQmlApplicationEngine engine(testFileUrl("menubar.qml")); + + QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(engine.rootObjects().value(0))); + QVERIFY(window); + + centerOnScreen(window.data()); + moveMouseAway(window.data()); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickMenuBar *menuBar = window->property("header").value<QQuickMenuBar *>(); + QVERIFY(menuBar); + + QQuickMenu *fileMenuBarMenu = menuBar->menuAt(0); + QQuickMenu *editMenuBarMenu = menuBar->menuAt(1); + QQuickMenu *viewMenuBarMenu = menuBar->menuAt(2); + QQuickMenu *helpMenuBarMenu = menuBar->menuAt(3); + QVERIFY(fileMenuBarMenu && editMenuBarMenu && viewMenuBarMenu && helpMenuBarMenu); + + QQuickMenuBarItem *fileMenuBarItem = qobject_cast<QQuickMenuBarItem *>(fileMenuBarMenu->parentItem()); + QQuickMenuBarItem *editMenuBarItem = qobject_cast<QQuickMenuBarItem *>(editMenuBarMenu->parentItem()); + QQuickMenuBarItem *viewMenuBarItem = qobject_cast<QQuickMenuBarItem *>(viewMenuBarMenu->parentItem()); + QQuickMenuBarItem *helpMenuBarItem = qobject_cast<QQuickMenuBarItem *>(helpMenuBarMenu->parentItem()); + QVERIFY(fileMenuBarItem && editMenuBarItem && viewMenuBarItem && helpMenuBarItem); + + // highlight a menubar item + QTest::mouseMove(window.data(), fileMenuBarItem->mapToScene(QPointF(fileMenuBarItem->width() / 2, fileMenuBarItem->height() / 2)).toPoint()); + QVERIFY(fileMenuBarItem->isHighlighted()); + QVERIFY(!fileMenuBarMenu->isVisible()); + + // highlight another menubar item + QTest::mouseMove(window.data(), editMenuBarItem->mapToScene(QPointF(editMenuBarItem->width() / 2, editMenuBarItem->height() / 2)).toPoint()); + QVERIFY(!fileMenuBarItem->isHighlighted()); + QVERIFY(editMenuBarItem->isHighlighted()); + QVERIFY(!fileMenuBarMenu->isVisible()); + QVERIFY(!editMenuBarMenu->isVisible()); + + // trigger a menubar item to open a menu + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, editMenuBarItem->mapToScene(QPointF(editMenuBarItem->width() / 2, editMenuBarItem->height() / 2)).toPoint()); + QVERIFY(editMenuBarItem->isHighlighted()); + QVERIFY(editMenuBarMenu->isVisible()); + QTRY_VERIFY(editMenuBarMenu->isOpened()); + + // re-trigger a menubar item to hide the menu + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, editMenuBarItem->mapToScene(QPointF(editMenuBarItem->width() / 2, editMenuBarItem->height() / 2)).toPoint()); + QVERIFY(editMenuBarItem->isHighlighted()); + QVERIFY(editMenuBarItem->hasActiveFocus()); + QTRY_VERIFY(!editMenuBarMenu->isVisible()); + + // re-trigger a menubar item to show the menu again + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, editMenuBarItem->mapToScene(QPointF(editMenuBarItem->width() / 2, editMenuBarItem->height() / 2)).toPoint()); + QVERIFY(editMenuBarItem->isHighlighted()); + QVERIFY(editMenuBarMenu->isVisible()); + QTRY_VERIFY(editMenuBarMenu->isOpened()); + + // highlight another menubar item to open another menu + QTest::mouseMove(window.data(), helpMenuBarItem->mapToScene(QPointF(helpMenuBarItem->width() / 2, helpMenuBarItem->height() / 2)).toPoint()); + QVERIFY(!fileMenuBarItem->isHighlighted()); + QVERIFY(!editMenuBarItem->isHighlighted()); + QVERIFY(!viewMenuBarItem->isHighlighted()); + QVERIFY(helpMenuBarItem->isHighlighted()); + QVERIFY(!fileMenuBarMenu->isVisible()); + QVERIFY(!viewMenuBarMenu->isVisible()); + QVERIFY(helpMenuBarMenu->isVisible()); + QTRY_VERIFY(!editMenuBarMenu->isVisible()); + QTRY_VERIFY(helpMenuBarMenu->isOpened()); + + // trigger a menu item to close the menu + QQuickMenuItem *aboutMenuItem = qobject_cast<QQuickMenuItem *>(helpMenuBarMenu->itemAt(0)); + QVERIFY(aboutMenuItem); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, aboutMenuItem->mapToScene(QPointF(aboutMenuItem->width() / 2, aboutMenuItem->height() / 2)).toPoint()); + QVERIFY(!helpMenuBarItem->isHighlighted()); + QTRY_VERIFY(!helpMenuBarMenu->isVisible()); + + // highlight a menubar item + QTest::mouseMove(window.data(), editMenuBarItem->mapToScene(QPointF(editMenuBarItem->width() / 2, editMenuBarItem->height() / 2)).toPoint()); + QVERIFY(editMenuBarItem->isHighlighted()); + QVERIFY(!helpMenuBarItem->isHighlighted()); + QVERIFY(!editMenuBarMenu->isVisible()); + QVERIFY(!helpMenuBarMenu->isVisible()); + + // trigger a menubar item to open a menu + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, viewMenuBarItem->mapToScene(QPointF(viewMenuBarItem->width() / 2, viewMenuBarItem->height() / 2)).toPoint()); + QVERIFY(!editMenuBarItem->isHighlighted()); + QVERIFY(viewMenuBarItem->isHighlighted()); + QVERIFY(viewMenuBarMenu->isVisible()); + QTRY_VERIFY(viewMenuBarMenu->isOpened()); + + // trigger a menu item to open a sub-menu + QQuickMenuItem *alignmentSubMenuItem = qobject_cast<QQuickMenuItem *>(viewMenuBarMenu->itemAt(0)); + QVERIFY(alignmentSubMenuItem); + QQuickMenu *alignmentSubMenu = alignmentSubMenuItem->subMenu(); + QVERIFY(alignmentSubMenu); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, alignmentSubMenuItem->mapToScene(QPointF(alignmentSubMenuItem->width() / 2, alignmentSubMenuItem->height() / 2)).toPoint()); + QVERIFY(viewMenuBarMenu->isVisible()); + QVERIFY(alignmentSubMenu->isVisible()); + QTRY_VERIFY(alignmentSubMenu->isOpened()); + + // trigger a menu item to open a sub-sub-menu + QQuickMenuItem *verticalSubMenuItem = qobject_cast<QQuickMenuItem *>(alignmentSubMenu->itemAt(1)); + QVERIFY(verticalSubMenuItem); + QQuickMenu *verticalSubMenu = verticalSubMenuItem->subMenu(); + QVERIFY(verticalSubMenu); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, verticalSubMenuItem->mapToScene(QPointF(verticalSubMenuItem->width() / 2, verticalSubMenuItem->height() / 2)).toPoint()); + QVERIFY(viewMenuBarMenu->isVisible()); + QVERIFY(alignmentSubMenu->isVisible()); + QVERIFY(verticalSubMenu->isVisible()); + QTRY_VERIFY(verticalSubMenu->isOpened()); + + // trigger a menu item to close the whole chain of menus + QQuickMenuItem *centerMenuItem = qobject_cast<QQuickMenuItem *>(verticalSubMenu->itemAt(1)); + QVERIFY(centerMenuItem); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, centerMenuItem->mapToScene(QPointF(centerMenuItem->width() / 2, centerMenuItem->height() / 2)).toPoint()); + QVERIFY(!viewMenuBarItem->isHighlighted()); + QTRY_VERIFY(!viewMenuBarMenu->isVisible()); + QTRY_VERIFY(!alignmentSubMenu->isVisible()); + QTRY_VERIFY(!verticalSubMenu->isVisible()); + + // re-highlight the same menubar item + QTest::mouseMove(window.data(), viewMenuBarItem->mapToScene(QPointF(viewMenuBarItem->width() / 2, viewMenuBarItem->height() / 2)).toPoint()); + QVERIFY(viewMenuBarItem->isHighlighted()); + + // re-open the chain of menus + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, viewMenuBarItem->mapToScene(QPointF(viewMenuBarItem->width() / 2, viewMenuBarItem->height() / 2)).toPoint()); + QTRY_VERIFY(viewMenuBarMenu->isOpened()); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, alignmentSubMenuItem->mapToScene(QPointF(alignmentSubMenuItem->width() / 2, alignmentSubMenuItem->height() / 2)).toPoint()); + QTRY_VERIFY(alignmentSubMenu->isOpened()); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, verticalSubMenuItem->mapToScene(QPointF(verticalSubMenuItem->width() / 2, verticalSubMenuItem->height() / 2)).toPoint()); + QTRY_VERIFY(verticalSubMenu->isOpened()); + + // click outside to close the whole chain of menus + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - 1, window->height() - 1)); + QVERIFY(!viewMenuBarItem->isHighlighted()); + QTRY_VERIFY(!viewMenuBarMenu->isVisible()); + QTRY_VERIFY(!alignmentSubMenu->isVisible()); + QTRY_VERIFY(!verticalSubMenu->isVisible()); +} + +void tst_qquickmenubar::keys() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + QQmlApplicationEngine engine(testFileUrl("menubar.qml")); + + QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(engine.rootObjects().value(0))); + QVERIFY(window); + + centerOnScreen(window.data()); + moveMouseAway(window.data()); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickMenuBar *menuBar = window->property("header").value<QQuickMenuBar *>(); + QVERIFY(menuBar); + + QQuickMenu *fileMenuBarMenu = menuBar->menuAt(0); + QQuickMenu *editMenuBarMenu = menuBar->menuAt(1); + QQuickMenu *viewMenuBarMenu = menuBar->menuAt(2); + QQuickMenu *helpMenuBarMenu = menuBar->menuAt(3); + QVERIFY(fileMenuBarMenu && editMenuBarMenu && viewMenuBarMenu && helpMenuBarMenu); + + QQuickMenuBarItem *fileMenuBarItem = qobject_cast<QQuickMenuBarItem *>(fileMenuBarMenu->parentItem()); + QQuickMenuBarItem *editMenuBarItem = qobject_cast<QQuickMenuBarItem *>(editMenuBarMenu->parentItem()); + QQuickMenuBarItem *viewMenuBarItem = qobject_cast<QQuickMenuBarItem *>(viewMenuBarMenu->parentItem()); + QQuickMenuBarItem *helpMenuBarItem = qobject_cast<QQuickMenuBarItem *>(helpMenuBarMenu->parentItem()); + QVERIFY(fileMenuBarItem && editMenuBarItem && viewMenuBarItem && helpMenuBarItem); + + // trigger a menubar item to open a menu + editMenuBarItem->forceActiveFocus(); + QTest::keyClick(window.data(), Qt::Key_Space); + QVERIFY(editMenuBarItem->isHighlighted()); + QVERIFY(editMenuBarMenu->isVisible()); + QTRY_VERIFY(editMenuBarMenu->isOpened()); + QVERIFY(editMenuBarMenu->hasActiveFocus()); + + // navigate down to the menu + QQuickMenuItem *cutMenuItem = qobject_cast<QQuickMenuItem *>(editMenuBarMenu->itemAt(0)); + QVERIFY(cutMenuItem); + QVERIFY(!cutMenuItem->isHighlighted()); + QVERIFY(!cutMenuItem->hasActiveFocus()); + QTest::keyClick(window.data(), Qt::Key_Down); + QVERIFY(cutMenuItem->isHighlighted()); + QVERIFY(cutMenuItem->hasActiveFocus()); + + // navigate up, back to the menubar + QTest::keyClick(window.data(), Qt::Key_Up); + QVERIFY(editMenuBarItem->isHighlighted()); + QVERIFY(editMenuBarItem->hasActiveFocus()); + QTRY_VERIFY(!editMenuBarMenu->isVisible()); + QVERIFY(!cutMenuItem->isHighlighted()); + QVERIFY(!cutMenuItem->hasActiveFocus()); + + // navigate down to re-open the menu + QTest::keyClick(window.data(), Qt::Key_Down); + QVERIFY(editMenuBarItem->isHighlighted()); + QVERIFY(!editMenuBarItem->hasActiveFocus()); + QVERIFY(editMenuBarMenu->isVisible()); + QTRY_VERIFY(editMenuBarMenu->isOpened()); + QVERIFY(editMenuBarMenu->hasActiveFocus()); + QVERIFY(cutMenuItem->isHighlighted()); + QVERIFY(cutMenuItem->hasActiveFocus()); + + // navigate left in popup mode (menu open) + QTest::keyClick(window.data(), Qt::Key_Left); + QVERIFY(fileMenuBarItem->isHighlighted()); + QVERIFY(!editMenuBarItem->isHighlighted()); + QVERIFY(fileMenuBarMenu->isVisible()); + QTRY_VERIFY(fileMenuBarMenu->isOpened()); + QTRY_VERIFY(!editMenuBarMenu->isVisible()); + + // navigate left in popup mode (wrap) + QTest::keyClick(window.data(), Qt::Key_Left); + QVERIFY(helpMenuBarItem->isHighlighted()); + QVERIFY(!fileMenuBarItem->isHighlighted()); + QVERIFY(helpMenuBarMenu->isVisible()); + QTRY_VERIFY(helpMenuBarMenu->isOpened()); + QTRY_VERIFY(!fileMenuBarMenu->isVisible()); + + // navigate up to close the menu + QTest::keyClick(window.data(), Qt::Key_Up); + QVERIFY(helpMenuBarItem->isHighlighted()); + QTRY_VERIFY(!helpMenuBarMenu->isVisible()); + + // navigate right in non-popup mode (wrap) + QTest::keyClick(window.data(), Qt::Key_Right); + QVERIFY(fileMenuBarItem->isHighlighted()); + QVERIFY(!helpMenuBarItem->isHighlighted()); + QVERIFY(!fileMenuBarMenu->isVisible()); + QVERIFY(!helpMenuBarMenu->isVisible()); + + // navigate right in non-popup mode (menu closed) + QTest::keyClick(window.data(), Qt::Key_Right); + QVERIFY(!fileMenuBarItem->isHighlighted()); + QVERIFY(editMenuBarItem->isHighlighted()); + QVERIFY(!fileMenuBarMenu->isVisible()); + QVERIFY(!editMenuBarMenu->isVisible()); + + // open a menu + viewMenuBarItem->forceActiveFocus(); + QTest::keyClick(window.data(), Qt::Key_Space); + QVERIFY(viewMenuBarItem->isHighlighted()); + QVERIFY(viewMenuBarMenu->isVisible()); + QTRY_VERIFY(viewMenuBarMenu->isOpened()); + QVERIFY(!viewMenuBarItem->hasActiveFocus()); + QVERIFY(viewMenuBarMenu->hasActiveFocus()); + + // open a sub-menu + QQuickMenuItem *alignmentSubMenuItem = qobject_cast<QQuickMenuItem *>(viewMenuBarMenu->itemAt(0)); + QVERIFY(alignmentSubMenuItem); + QQuickMenu *alignmentSubMenu = alignmentSubMenuItem->subMenu(); + QVERIFY(alignmentSubMenu); + QTest::keyClick(window.data(), Qt::Key_Down); + QVERIFY(alignmentSubMenuItem->isHighlighted()); + QVERIFY(!alignmentSubMenu->isVisible()); + QTest::keyClick(window.data(), Qt::Key_Right); + QVERIFY(alignmentSubMenu->isVisible()); + QTRY_VERIFY(alignmentSubMenu->isOpened()); + + // open a sub-sub-menu + QQuickMenuItem *horizontalSubMenuItem = qobject_cast<QQuickMenuItem *>(alignmentSubMenu->itemAt(0)); + QVERIFY(horizontalSubMenuItem); + QVERIFY(horizontalSubMenuItem->isHighlighted()); + QQuickMenu *horizontalSubMenu = horizontalSubMenuItem->subMenu(); + QVERIFY(horizontalSubMenu); + QTest::keyClick(window.data(), Qt::Key_Right); + QVERIFY(viewMenuBarMenu->isVisible()); + QVERIFY(alignmentSubMenu->isVisible()); + QVERIFY(horizontalSubMenu->isVisible()); + QTRY_VERIFY(horizontalSubMenu->isOpened()); + + // navigate left to close a sub-menu + QTest::keyClick(window.data(), Qt::Key_Left); + QTRY_VERIFY(!horizontalSubMenu->isVisible()); + QVERIFY(viewMenuBarMenu->isVisible()); + QVERIFY(alignmentSubMenu->isVisible()); + + // navigate right to re-open the sub-menu + QTest::keyClick(window.data(), Qt::Key_Right); + QVERIFY(horizontalSubMenuItem->isHighlighted()); + QVERIFY(horizontalSubMenu->isVisible()); + QTRY_VERIFY(horizontalSubMenu->isOpened()); + + // navigate right to the next menubar menu + QTest::keyClick(window.data(), Qt::Key_Right); + QVERIFY(!viewMenuBarItem->isHighlighted()); + QVERIFY(helpMenuBarItem->isHighlighted()); + QVERIFY(helpMenuBarMenu->isVisible()); + QTRY_VERIFY(!viewMenuBarMenu->isVisible()); + QTRY_VERIFY(!alignmentSubMenu->isVisible()); + QTRY_VERIFY(!horizontalSubMenu->isVisible()); + QTRY_VERIFY(helpMenuBarMenu->isOpened()); + + // navigate back + QTest::keyClick(window.data(), Qt::Key_Left); + QVERIFY(!helpMenuBarItem->isHighlighted()); + QVERIFY(viewMenuBarItem->isHighlighted()); + QVERIFY(viewMenuBarMenu->isVisible()); + QTRY_VERIFY(!helpMenuBarMenu->isVisible()); + QTRY_VERIFY(viewMenuBarMenu->isOpened()); + + // re-open the chain of menus + QTest::keyClick(window.data(), Qt::Key_Down); + QVERIFY(alignmentSubMenuItem->isHighlighted()); + QTest::keyClick(window.data(), Qt::Key_Right); + QTRY_VERIFY(alignmentSubMenu->isOpened()); + QTest::keyClick(window.data(), Qt::Key_Right); + QTRY_VERIFY(horizontalSubMenu->isOpened()); + + // repeat escape to close the whole chain of menus one by one + QTest::keyClick(window.data(), Qt::Key_Escape); + QTRY_VERIFY(!horizontalSubMenu->isVisible()); + QVERIFY(viewMenuBarItem->isHighlighted()); + QVERIFY(viewMenuBarMenu->isVisible()); + QVERIFY(alignmentSubMenu->isVisible()); + + QTest::keyClick(window.data(), Qt::Key_Escape); + QTRY_VERIFY(!alignmentSubMenu->isVisible()); + QVERIFY(viewMenuBarItem->isHighlighted()); + QVERIFY(viewMenuBarMenu->isVisible()); + + QTest::keyClick(window.data(), Qt::Key_Escape); + QVERIFY(!viewMenuBarItem->isHighlighted()); + QTRY_VERIFY(!viewMenuBarMenu->isVisible()); +} + +void tst_qquickmenubar::mnemonics() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); +#ifdef Q_OS_MACOS + QSKIP("Mnemonics are not used on macOS"); +#endif + + QQmlApplicationEngine engine(testFileUrl("menubar.qml")); + + QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(engine.rootObjects().value(0))); + QVERIFY(window); + + centerOnScreen(window.data()); + moveMouseAway(window.data()); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + MnemonicKeySimulator keySim(window.data()); + + QQuickMenuBar *menuBar = window->property("header").value<QQuickMenuBar *>(); + QVERIFY(menuBar); + + QQuickMenu *fileMenuBarMenu = menuBar->menuAt(0); + QQuickMenu *editMenuBarMenu = menuBar->menuAt(1); + QQuickMenu *viewMenuBarMenu = menuBar->menuAt(2); + QQuickMenu *helpMenuBarMenu = menuBar->menuAt(3); + QVERIFY(fileMenuBarMenu && editMenuBarMenu && viewMenuBarMenu && helpMenuBarMenu); + + QQuickMenuBarItem *fileMenuBarItem = qobject_cast<QQuickMenuBarItem *>(fileMenuBarMenu->parentItem()); + QQuickMenuBarItem *editMenuBarItem = qobject_cast<QQuickMenuBarItem *>(editMenuBarMenu->parentItem()); + QQuickMenuBarItem *viewMenuBarItem = qobject_cast<QQuickMenuBarItem *>(viewMenuBarMenu->parentItem()); + QQuickMenuBarItem *helpMenuBarItem = qobject_cast<QQuickMenuBarItem *>(helpMenuBarMenu->parentItem()); + QVERIFY(fileMenuBarItem && editMenuBarItem && viewMenuBarItem && helpMenuBarItem); + + QQuickButton *oopsButton = window->property("oopsButton").value<QQuickButton *>(); + QVERIFY(oopsButton); + QSignalSpy oopsButtonSpy(oopsButton, &QQuickButton::clicked); + QVERIFY(oopsButtonSpy.isValid()); + + // trigger a menubar item to open a menu + keySim.press(Qt::Key_Alt); + keySim.click(Qt::Key_E); // "&Edit" + keySim.release(Qt::Key_Alt); + QVERIFY(editMenuBarItem->isHighlighted()); + QVERIFY(!editMenuBarItem->hasActiveFocus()); + QVERIFY(editMenuBarMenu->isVisible()); + QTRY_VERIFY(editMenuBarMenu->isOpened()); + QVERIFY(editMenuBarMenu->hasActiveFocus()); + + // press Alt to hide the menu + keySim.click(Qt::Key_Alt); + QVERIFY(!editMenuBarItem->isHighlighted()); + QVERIFY(!editMenuBarItem->hasActiveFocus()); + QVERIFY(!editMenuBarMenu->hasActiveFocus()); + QTRY_VERIFY(!editMenuBarMenu->isVisible()); + + // re-trigger a menubar item to show the menu again + keySim.press(Qt::Key_Alt); + keySim.click(Qt::Key_E); // "&Edit" + keySim.release(Qt::Key_Alt); + QVERIFY(editMenuBarItem->isHighlighted()); + QVERIFY(editMenuBarMenu->isVisible()); + QTRY_VERIFY(editMenuBarMenu->isOpened()); + QVERIFY(editMenuBarMenu->hasActiveFocus()); + QVERIFY(!editMenuBarItem->hasActiveFocus()); + + // trigger another menubar item to open another menu, leave Alt pressed + keySim.press(Qt::Key_Alt); + QTRY_VERIFY(!editMenuBarMenu->isVisible()); + keySim.click(Qt::Key_H); // "&Help" + QVERIFY(!editMenuBarItem->isHighlighted()); + QVERIFY(helpMenuBarItem->isHighlighted()); + QVERIFY(!viewMenuBarMenu->isVisible()); + QVERIFY(helpMenuBarMenu->isVisible()); + QTRY_VERIFY(helpMenuBarMenu->isOpened()); + + // trigger a menu item to close the menu + keySim.click(Qt::Key_A); // "&About" + keySim.release(Qt::Key_Alt); + QVERIFY(!helpMenuBarItem->isHighlighted()); + QTRY_VERIFY(!helpMenuBarMenu->isVisible()); + + // trigger a menubar item to open a menu, leave Alt pressed + keySim.press(Qt::Key_Alt); + keySim.click(Qt::Key_V); // "&View" + QVERIFY(!editMenuBarItem->isHighlighted()); + QVERIFY(viewMenuBarItem->isHighlighted()); + QVERIFY(viewMenuBarMenu->isVisible()); + QTRY_VERIFY(viewMenuBarMenu->isOpened()); + + // trigger a menu item to open a sub-menu, leave Alt pressed + QQuickMenuItem *alignmentSubMenuItem = qobject_cast<QQuickMenuItem *>(viewMenuBarMenu->itemAt(0)); + QVERIFY(alignmentSubMenuItem); + QQuickMenu *alignmentSubMenu = alignmentSubMenuItem->subMenu(); + QVERIFY(alignmentSubMenu); + keySim.click(Qt::Key_A); // "&Alignment" + QVERIFY(viewMenuBarMenu->isVisible()); + QVERIFY(alignmentSubMenu->isVisible()); + QTRY_VERIFY(alignmentSubMenu->isOpened()); + + // trigger a menu item to open a sub-sub-menu, leave Alt pressed + QQuickMenuItem *verticalSubMenuItem = qobject_cast<QQuickMenuItem *>(alignmentSubMenu->itemAt(1)); + QVERIFY(verticalSubMenuItem); + QQuickMenu *verticalSubMenu = verticalSubMenuItem->subMenu(); + QVERIFY(verticalSubMenu); + keySim.click(Qt::Key_V); // "&Vertical" + QVERIFY(viewMenuBarMenu->isVisible()); + QVERIFY(alignmentSubMenu->isVisible()); + QVERIFY(verticalSubMenu->isVisible()); + QTRY_VERIFY(verticalSubMenu->isOpened()); + + // trigger a menu item to close the whole chain of menus + keySim.click(Qt::Key_C); // "&Center" + keySim.release(Qt::Key_Alt); + QVERIFY(!viewMenuBarItem->isHighlighted()); + QTRY_VERIFY(!viewMenuBarMenu->isVisible()); + QTRY_VERIFY(!alignmentSubMenu->isVisible()); + QTRY_VERIFY(!verticalSubMenu->isVisible()); + + // trigger a menubar item to open a menu, leave Alt pressed + keySim.press(Qt::Key_Alt); + keySim.click(Qt::Key_F); // "&File" + QVERIFY(fileMenuBarItem->isHighlighted()); + QVERIFY(fileMenuBarMenu->isVisible()); + QTRY_VERIFY(fileMenuBarMenu->isOpened()); + QVERIFY(fileMenuBarMenu->hasActiveFocus()); + + // trigger a menu item to close the menu, which shouldn't trigger a button + // action behind the menu (QTBUG-86276) + QCOMPARE(oopsButtonSpy.count(), 0); + keySim.click(Qt::Key_O); // "&Open..." + keySim.release(Qt::Key_Alt); + QVERIFY(!fileMenuBarItem->isHighlighted()); + QVERIFY(!fileMenuBarMenu->isOpened()); + QTRY_VERIFY(!fileMenuBarMenu->isVisible()); + QCOMPARE(oopsButtonSpy.count(), 0); + + // trigger a button action while menu is closed + keySim.press(Qt::Key_Alt); + keySim.click(Qt::Key_O); // "&Oops" + keySim.release(Qt::Key_Alt); + QCOMPARE(oopsButtonSpy.count(), 1); +} + +void tst_qquickmenubar::addRemove() +{ + QQmlApplicationEngine engine(testFileUrl("empty.qml")); + + QScopedPointer<QQuickMenuBar> menuBar(qobject_cast<QQuickMenuBar *>(engine.rootObjects().value(0))); + QVERIFY(menuBar); + + QQmlComponent component(&engine); + component.setData("import QtQuick.Controls; Menu { }", QUrl()); + + QPointer<QQuickMenu> menu1(qobject_cast<QQuickMenu *>(component.create())); + QVERIFY(!menu1.isNull()); + menuBar->addMenu(menu1.data()); + QCOMPARE(menuBar->count(), 1); + QCOMPARE(menuBar->menuAt(0), menu1.data()); + + QPointer<QQuickMenuBarItem> menuBarItem1(qobject_cast<QQuickMenuBarItem *>(menuBar->itemAt(0))); + QVERIFY(menuBarItem1); + QCOMPARE(menuBarItem1->menu(), menu1.data()); + QCOMPARE(menuBar->itemAt(0), menuBarItem1.data()); + + QScopedPointer<QQuickMenu> menu2(qobject_cast<QQuickMenu *>(component.create())); + QVERIFY(!menu2.isNull()); + menuBar->insertMenu(0, menu2.data()); + QCOMPARE(menuBar->count(), 2); + QCOMPARE(menuBar->menuAt(0), menu2.data()); + QCOMPARE(menuBar->menuAt(1), menu1.data()); + + QPointer<QQuickMenuBarItem> menuBarItem2(qobject_cast<QQuickMenuBarItem *>(menuBar->itemAt(0))); + QVERIFY(menuBarItem2); + QCOMPARE(menuBarItem2->menu(), menu2.data()); + QCOMPARE(menuBar->itemAt(0), menuBarItem2.data()); + QCOMPARE(menuBar->itemAt(1), menuBarItem1.data()); + + // takeMenu(int) does not destroy the menu, but does destroy the respective item in the menubar + QCOMPARE(menuBar->takeMenu(1), menu1.data()); + QCOMPARE(menuBar->count(), 1); + QVERIFY(!menuBar->menuAt(1)); + QVERIFY(!menuBar->itemAt(1)); + QCoreApplication::sendPostedEvents(menu1.data(), QEvent::DeferredDelete); + QVERIFY(!menu1.isNull()); + QCoreApplication::sendPostedEvents(menuBarItem1, QEvent::DeferredDelete); + QVERIFY(menuBarItem1.isNull()); + + // addMenu(Menu) re-creates the respective item in the menubar + menuBar->addMenu(menu1.data()); + QCOMPARE(menuBar->count(), 2); + menuBarItem1 = qobject_cast<QQuickMenuBarItem *>(menuBar->itemAt(1)); + QVERIFY(!menuBarItem1.isNull()); + + // removeMenu(Menu) destroys both the menu and the respective item in the menubar + menuBar->removeMenu(menu1.data()); + QCOMPARE(menuBar->count(), 1); + QVERIFY(!menuBar->itemAt(1)); + QCoreApplication::sendPostedEvents(menu1.data(), QEvent::DeferredDelete); + QVERIFY(menu1.isNull()); + QCoreApplication::sendPostedEvents(menuBarItem1, QEvent::DeferredDelete); + QVERIFY(menuBarItem1.isNull()); +} + +void tst_qquickmenubar::checkHighlightWhenMenuDismissed() +{ + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QSKIP("Mouse highlight not functional on offscreen/minimal platforms"); + + QQmlApplicationEngine engine(testFileUrl("checkHighlightWhenDismissed.qml")); + QScopedPointer<QQuickApplicationWindow> window(qobject_cast<QQuickApplicationWindow *>(engine.rootObjects().value(0))); + QVERIFY(window); + + centerOnScreen(window.data()); + moveMouseAway(window.data()); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickMenuBar *menuBar = window->findChild<QQuickMenuBar *>("menuBar"); + QVERIFY(menuBar); + + QQuickMenu *staticMenu = menuBar->menuAt(0); + QQuickMenu *dynamicMenu = menuBar->menuAt(1); + QVERIFY(staticMenu && dynamicMenu); + QQuickMenuBarItem *staticMenuBarItem = qobject_cast<QQuickMenuBarItem *>(staticMenu->parentItem()); + QQuickMenuBarItem *dynamicMenuBarItem = qobject_cast<QQuickMenuBarItem *>(dynamicMenu->parentItem()); + QVERIFY(staticMenuBarItem && dynamicMenuBarItem); + + // highlight the static MenuBarItem and open the menu + QTest::mouseMove(window.data(), staticMenuBarItem->mapToScene( + QPointF(staticMenuBarItem->width() / 2, staticMenuBarItem->height() / 2)).toPoint()); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, + staticMenuBarItem->mapToScene(QPointF(staticMenuBarItem->width() / 2, staticMenuBarItem->height() / 2)).toPoint()); + QCOMPARE(staticMenuBarItem->isHighlighted(), true); + QCOMPARE(staticMenu->isVisible(), true); + QTRY_COMPARE(staticMenu->isOpened(), true); + + // click a menu item to dismiss the menu and unhighlight the static MenuBarItem + QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(staticMenu->itemAt(0)); + QVERIFY(menuItem); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, + menuItem->mapToScene(QPointF(menuItem->width() / 2, menuItem->height() / 2)).toPoint()); + QCOMPARE(staticMenuBarItem->isHighlighted(), false); + + // highlight the dynamic MenuBarItem and open the menu + QTest::mouseMove(window.data(), dynamicMenuBarItem->mapToScene( + QPointF(dynamicMenuBarItem->width() / 2, dynamicMenuBarItem->height() / 2)).toPoint()); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, + dynamicMenuBarItem->mapToScene(QPointF(dynamicMenuBarItem->width() / 2, dynamicMenuBarItem->height() / 2)).toPoint()); + QCOMPARE(dynamicMenuBarItem->isHighlighted(), true); + QCOMPARE(dynamicMenu->isVisible(), true); + QTRY_COMPARE(dynamicMenu->isOpened(), true); + + // click a menu item to dismiss the menu and unhighlight the dynamic MenuBarItem + menuItem = qobject_cast<QQuickMenuItem *>(dynamicMenu->itemAt(0)); + QVERIFY(menuItem); + QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, + menuItem->mapToScene(QPointF(menuItem->width() / 2, menuItem->height() / 2)).toPoint()); + QCOMPARE(dynamicMenuBarItem->isHighlighted(), false); +} + +QTEST_QUICKCONTROLS_MAIN(tst_qquickmenubar) + +#include "tst_qquickmenubar.moc" diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/CMakeLists.txt b/tests/auto/quickcontrols2/qquickninepatchimage/CMakeLists.txt new file mode 100644 index 00000000000..b0fdebd1aa1 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickninepatchimage/CMakeLists.txt @@ -0,0 +1,47 @@ +# Generated from qquickninepatchimage.pro. + +##################################################################### +## tst_qquickninepatchimage Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickninepatchimage + SOURCES + tst_qquickninepatchimage.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::Qml + Qt::QmlPrivate + Qt::Quick + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickninepatchimage CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickninepatchimage CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/foo.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/foo.9.png new file mode 100644 index 00000000000..bac09a4d1a9 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/foo.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/foo@2x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/foo@2x.9.png new file mode 100644 index 00000000000..43e4b478810 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/foo@2x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/foo@3x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/foo@3x.9.png new file mode 100644 index 00000000000..4d199c84243 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/foo@3x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/foo@4x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/foo@4x.9.png new file mode 100644 index 00000000000..018b8341a2e Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/foo@4x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-all.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-all.9.png new file mode 100644 index 00000000000..a1899429574 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-all.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-all@2x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-all@2x.9.png new file mode 100644 index 00000000000..d00d719cc27 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-all@2x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-all@3x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-all@3x.9.png new file mode 100644 index 00000000000..6130fd5020d Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-all@3x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-all@4x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-all@4x.9.png new file mode 100644 index 00000000000..2c2d1694d4c Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-all@4x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-bottomright.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-bottomright.9.png new file mode 100644 index 00000000000..2b3e58cbf1c Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-bottomright.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-bottomright@2x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-bottomright@2x.9.png new file mode 100644 index 00000000000..70aceb618f7 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-bottomright@2x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-bottomright@3x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-bottomright@3x.9.png new file mode 100644 index 00000000000..032400cedaa Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-bottomright@3x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-bottomright@4x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-bottomright@4x.9.png new file mode 100644 index 00000000000..d5cf85aa10b Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-bottomright@4x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-topleft.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-topleft.9.png new file mode 100644 index 00000000000..05a2ff703cd Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-topleft.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-topleft@2x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-topleft@2x.9.png new file mode 100644 index 00000000000..a88f87a5ce3 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-topleft@2x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-topleft@3x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-topleft@3x.9.png new file mode 100644 index 00000000000..16349d22874 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-topleft@3x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-topleft@4x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-topleft@4x.9.png new file mode 100644 index 00000000000..160fab6164e Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/inset-topleft@4x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/logo.pkm b/tests/auto/quickcontrols2/qquickninepatchimage/data/logo.pkm new file mode 100644 index 00000000000..c0987c5c36f Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/logo.pkm differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/ninepatchimage.qml b/tests/auto/quickcontrols2/qquickninepatchimage/data/ninepatchimage.qml new file mode 100644 index 00000000000..410a61f9fe6 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickninepatchimage/data/ninepatchimage.qml @@ -0,0 +1,7 @@ +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl + +NinePatchImage { +} diff --git a/tests/manual/scenegraph_lancelot/data/shared/o1_bc1.ktx b/tests/auto/quickcontrols2/qquickninepatchimage/data/o1_bc1.ktx similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/o1_bc1.ktx rename to tests/auto/quickcontrols2/qquickninepatchimage/data/o1_bc1.ktx diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/padding.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/padding.9.png new file mode 100644 index 00000000000..8a65afadec3 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/padding.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/padding@2x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/padding@2x.9.png new file mode 100644 index 00000000000..101fc0cbbed Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/padding@2x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/padding@3x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/padding@3x.9.png new file mode 100644 index 00000000000..e07a93a2311 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/padding@3x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/padding@4x.9.png b/tests/auto/quickcontrols2/qquickninepatchimage/data/padding@4x.9.png new file mode 100644 index 00000000000..a3506444b17 Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/padding@4x.9.png differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/data/qt4.astc b/tests/auto/quickcontrols2/qquickninepatchimage/data/qt4.astc new file mode 100644 index 00000000000..7f7a3f4739b Binary files /dev/null and b/tests/auto/quickcontrols2/qquickninepatchimage/data/qt4.astc differ diff --git a/tests/auto/quickcontrols2/qquickninepatchimage/tst_qquickninepatchimage.cpp b/tests/auto/quickcontrols2/qquickninepatchimage/tst_qquickninepatchimage.cpp new file mode 100644 index 00000000000..1c615230933 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickninepatchimage/tst_qquickninepatchimage.cpp @@ -0,0 +1,319 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtCore/qmath.h> +#include <QtCore/qsize.h> +#include <QtGui/private/qhighdpiscaling_p.h> +#include <QtQml/qqmlengine.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickview.h> +#include <QtQuick/qquickitemgrabresult.h> +#include <QtQuick/private/qquickimage_p.h> +#include <QtQuick/private/qquickimage_p_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtGui/private/qrhi_p.h> + +using namespace QQuickVisualTestUtils; + +class tst_qquickninepatchimage : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_qquickninepatchimage(); + +private slots: + void ninePatch_data(); + void ninePatch(); + void padding_data(); + void padding(); + void inset_data(); + void inset(); + void implicitSize_data(); + void implicitSize(); + void hwCompressedImages_data(); + void hwCompressedImages(); +}; + +static QImage grabItemToImage(QQuickItem *item) +{ + QSharedPointer<QQuickItemGrabResult> result = item->grabToImage(); + QSignalSpy spy(result.data(), SIGNAL(ready())); + spy.wait(); + return result->image(); +} + +tst_qquickninepatchimage::tst_qquickninepatchimage() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_qquickninepatchimage::ninePatch_data() +{ + QTest::addColumn<int>("dpr"); + QTest::addColumn<QSize>("size"); + + // original size, downsized, stretched + const QList<QSize> sizes = QList<QSize>() + << QSize(40, 40) // original + << QSize(10, 40) // downsized (h) + << QSize(40, 10) // downsized (v) + << QSize(10, 10) // downsized (h & v) + << QSize(80, 40) // stretched (h) + << QSize(40, 80) // stretched (v) + << QSize(80, 80) // stretched (h & v) + << QSize(8, 8); // minimal (borders only) + + for (const QSize &sz : sizes) { + for (int dpr = 1; dpr <= 4; ++dpr) + QTest::newRow(qPrintable(QString::fromLatin1("DPR=%1, %2x%3").arg(dpr).arg(sz.width()).arg(sz.height()))) << dpr << sz; + } +} + +void tst_qquickninepatchimage::ninePatch() +{ + QFETCH(int, dpr); + QFETCH(QSize, size); + + QHighDpiScaling::setGlobalFactor(dpr); + + QQuickView view(testFileUrl("ninepatchimage.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickImage *ninePatchImage = qobject_cast<QQuickImage *>(view.rootObject()); + QVERIFY(ninePatchImage); + ninePatchImage->setSource(testFileUrl("foo.9.png")); + ninePatchImage->setSize(size); + + const QImage ninePatchImageGrab = grabItemToImage(ninePatchImage).scaled(size * dpr); + + // Generate an image to compare against the actual 9-patch image. + QImage generatedImage(size * dpr, ninePatchImageGrab.format()); + generatedImage.fill(Qt::red); + + QImage blueRect(4 * dpr, 4 * dpr, ninePatchImageGrab.format()); + blueRect.fill(Qt::blue); + + QPainter painter(&generatedImage); + // Top-left + painter.drawImage(0, 0, blueRect); + // Top-right + painter.drawImage(generatedImage.width() - blueRect.width(), 0, blueRect); + // Bottom-right + painter.drawImage(generatedImage.width() - blueRect.width(), generatedImage.height() - blueRect.height(), blueRect); + // Bottom-left + painter.drawImage(0, generatedImage.height() - blueRect.height(), blueRect); + + if ((QGuiApplication::platformName() == QLatin1String("offscreen")) + || (QGuiApplication::platformName() == QLatin1String("minimal"))) + QEXPECT_FAIL("", "Grabbing does not work on offscreen/minimal platforms", Abort); + + QCOMPARE(ninePatchImageGrab, generatedImage); +} + +void tst_qquickninepatchimage::padding_data() +{ + QTest::addColumn<int>("dpr"); + + for (int dpr = 1; dpr <= 4; ++dpr) + QTest::newRow(qPrintable(QString::fromLatin1("DPR=%1").arg(dpr))) << dpr; +} + +void tst_qquickninepatchimage::padding() +{ + QFETCH(int, dpr); + + QHighDpiScaling::setGlobalFactor(dpr); + + QQuickView view(testFileUrl("ninepatchimage.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickImage *ninePatchImage = qobject_cast<QQuickImage *>(view.rootObject()); + QVERIFY(ninePatchImage); + ninePatchImage->setSource(testFileUrl("padding.9.png")); + + QCOMPARE(ninePatchImage->property("topPadding").toReal(), 8); + QCOMPARE(ninePatchImage->property("leftPadding").toReal(), 18); + QCOMPARE(ninePatchImage->property("rightPadding").toReal(), 20); + QCOMPARE(ninePatchImage->property("bottomPadding").toReal(), 10); +} + +void tst_qquickninepatchimage::inset_data() +{ + QTest::addColumn<int>("dpr"); + QTest::addColumn<QString>("file"); + QTest::addColumn<QMarginsF>("insets"); + + const QStringList files = QStringList() << "inset-all.9.png" << "inset-topleft.9.png" << "inset-bottomright.9.png"; + const QList<QMarginsF> insets = QList<QMarginsF>() << QMarginsF(2, 1, 3, 4) << QMarginsF(2, 1, 0, 0) << QMarginsF(0, 0, 3, 4); + + for (int i = 0; i < files.count(); ++i) { + QString file = files.at(i); + for (int dpr = 1; dpr <= 4; ++dpr) + QTest::newRow(qPrintable(QString::fromLatin1("%1 DPR=%2").arg(file).arg(dpr))) << dpr << file << insets.at(i); + } +} + +Q_DECLARE_METATYPE(QMarginsF) + +void tst_qquickninepatchimage::inset() +{ + QFETCH(int, dpr); + QFETCH(QString, file); + QFETCH(QMarginsF, insets); + + QHighDpiScaling::setGlobalFactor(dpr); + + QQuickView view(testFileUrl("ninepatchimage.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickImage *ninePatchImage = qobject_cast<QQuickImage *>(view.rootObject()); + QVERIFY(ninePatchImage); + ninePatchImage->setSource(testFileUrl(file)); + + QCOMPARE(ninePatchImage->property("topInset").toReal(), insets.top()); + QCOMPARE(ninePatchImage->property("leftInset").toReal(), insets.left()); + QCOMPARE(ninePatchImage->property("rightInset").toReal(), insets.right()); + QCOMPARE(ninePatchImage->property("bottomInset").toReal(), insets.bottom()); +} + +void tst_qquickninepatchimage::implicitSize_data() +{ + QTest::addColumn<int>("dpr"); + QTest::addColumn<QString>("file"); + QTest::addColumn<QSizeF>("implicitSize"); + + const struct TestFile { + QString name; + QSizeF sizeHint; + } testFiles [] = { + { "foo.9.png", QSizeF(40, 40) }, + { "padding.9.png", QSizeF(40, 40) }, + { "inset-all.9.png", QSizeF(45, 45) }, + { "inset-topleft.9.png", QSizeF(42, 41) }, + { "inset-bottomright.9.png", QSizeF(43, 44) } + }; + + for (const TestFile &file : testFiles) { + for (int dpr = 1; dpr <= 4; ++dpr) + QTest::newRow(qPrintable(QString::fromLatin1("%1 DPR=%2").arg(file.name).arg(dpr))) << dpr << file.name << file.sizeHint; + } +} + +void tst_qquickninepatchimage::implicitSize() +{ + QFETCH(int, dpr); + QFETCH(QString, file); + QFETCH(QSizeF, implicitSize); + + QHighDpiScaling::setGlobalFactor(dpr); + + QQuickView view(testFileUrl("ninepatchimage.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + view.requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickImage *ninePatchImage = qobject_cast<QQuickImage *>(view.rootObject()); + QVERIFY(ninePatchImage); + ninePatchImage->setSource(testFileUrl(file)); + + QCOMPARE(ninePatchImage->implicitWidth(), implicitSize.width()); + QCOMPARE(ninePatchImage->implicitHeight(), implicitSize.height()); +} + +void tst_qquickninepatchimage::hwCompressedImages_data() +{ + QTest::addColumn<int>("dpr"); + QTest::addColumn<QString>("file"); + QTest::addColumn<QSize>("size"); + QTest::addColumn<QRhiTexture::Format>("format"); + + const struct TestFile { + QString name; + QSize size; + QRhiTexture::Format format; + } testFiles [] = { + { "o1_bc1.ktx", QSize(64, 64), QRhiTexture::BC1 }, + { "logo.pkm", QSize(256, 256), QRhiTexture::ETC2_RGB8 }, + { "qt4.astc", QSize(250, 200), QRhiTexture::ASTC_8x8 } + }; + + for (const TestFile &file : testFiles) { + for (int dpr = 1; dpr <= 4; ++dpr) + QTest::newRow(qPrintable(QString::fromLatin1("%1 DPR=%2").arg(file.name).arg(dpr))) << dpr << file.name << file.size << file.format; + } +} + +void tst_qquickninepatchimage::hwCompressedImages() +{ + QFETCH(int, dpr); + QFETCH(QString, file); + QFETCH(QSize, size); + QFETCH(QRhiTexture::Format, format); + + QHighDpiScaling::setGlobalFactor(dpr); + + QQuickView view(testFileUrl("ninepatchimage.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + if (!QSGRendererInterface::isApiRhiBased(view.rendererInterface()->graphicsApi())) + QSKIP("Skipping due to using software backend"); + + QRhi *rhi = static_cast<QRhi *>(view.rendererInterface()->getResource(&view, QSGRendererInterface::RhiResource)); + if (!rhi->isTextureFormatSupported(format)) + QSKIP(qPrintable(QString::fromLatin1("%1 not supported, skip").arg(format))); + + QQuickImage *ninePatchImage = qobject_cast<QQuickImage *>(view.rootObject()); + QVERIFY(ninePatchImage); + ninePatchImage->setSource(testFileUrl(file)); + ninePatchImage->setSize(size); + QSignalSpy spy(&view, SIGNAL(afterSynchronizing())); + QTRY_VERIFY(spy.size() >= 1); + + QQuickImagePrivate *ninePatchImagePrivate = static_cast<QQuickImagePrivate *>(QQuickItemPrivate::get(ninePatchImage)); + QVERIFY(ninePatchImagePrivate->paintNode); +} + +QTEST_MAIN(tst_qquickninepatchimage) + +#include "tst_qquickninepatchimage.moc" diff --git a/tests/auto/quickcontrols2/qquickpopup/BLACKLIST b/tests/auto/quickcontrols2/qquickpopup/BLACKLIST new file mode 100644 index 00000000000..4aa2bfeb6e7 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/BLACKLIST @@ -0,0 +1,17 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format + +[overlay] +macos # QTBUG-89938 + +[zOrder] +macos # QTBUG-89938 + +[closePolicy] +macos # QTBUG-89938 + +# QTBUG-94251 +[closePolicy] +opensuse-leap + +[cursorShape] +opensuse-leap diff --git a/tests/auto/quickcontrols2/qquickpopup/CMakeLists.txt b/tests/auto/quickcontrols2/qquickpopup/CMakeLists.txt new file mode 100644 index 00000000000..715cf5868cf --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/CMakeLists.txt @@ -0,0 +1,48 @@ +# Generated from qquickpopup.pro. + +##################################################################### +## tst_qquickpopup Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickpopup + SOURCES + tst_qquickpopup.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:qquickpopup.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickpopup CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickpopup CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickpopup/data/activeFocusAfterExit.qml b/tests/auto/quickcontrols2/qquickpopup/data/activeFocusAfterExit.qml new file mode 100644 index 00000000000..0a716ccd748 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/activeFocusAfterExit.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias popup1: popup1 + property alias popup2: popup2 + property alias popup3: popup3 + + Popup { + id: popup1 + focus: true + z: 1 + } + + Popup { + id: popup2 + focus: false + z: 2 + } + + Popup { + id: popup3 + focus: true + z: 3 + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnClose1.qml b/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnClose1.qml new file mode 100644 index 00000000000..9a76ebea974 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnClose1.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias focusedPopup: focusedPopup + property alias nonFocusedPopup: nonFocusedPopup + + Popup { + id: focusedPopup + focus: true + } + + Popup { + id: nonFocusedPopup + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnClose2.qml b/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnClose2.qml new file mode 100644 index 00000000000..6d004b17214 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnClose2.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias popup1: popup1 + property alias popup2: popup2 + property alias closePopup2Button: closePopup2Button + + Popup { + id: popup1 + focus: true + } + + Popup { + id: popup2 + focus: true + + Button { + id: closePopup2Button + onClicked: { + popup1.contentItem.forceActiveFocus(); + popup2.close(); + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnClose3.qml b/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnClose3.qml new file mode 100644 index 00000000000..8a68246853f --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnClose3.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias popup1: popup1 + property alias popup2: popup2 + + Button { + focus: true + } + + Popup { + id: popup1 + focus: true + enter: Transition { PauseAnimation { duration: 200 } } + exit: Transition { PauseAnimation { duration: 200 } } + } + + Popup { + id: popup2 + focus: true + enter: Transition { PauseAnimation { duration: 100 } } + exit: Transition { PauseAnimation { duration: 100 } } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnClosingSeveralPopups.qml b/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnClosingSeveralPopups.qml new file mode 100644 index 00000000000..adf23637ab0 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnClosingSeveralPopups.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias button: button + property alias popup1: popup1 + property alias popup2: popup2 + + Button { + id: button + focus: true + } + + Popup { + id: popup1 + focus: true + enter: Transition { NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 200 } } + exit: Transition { NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 200 } } + } + + Popup { + id: popup2 + focus: true + enter: Transition { NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 100 } } + exit: Transition { NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 100 } } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnDelayedEnter.qml b/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnDelayedEnter.qml new file mode 100644 index 00000000000..1ceea99c096 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/activeFocusOnDelayedEnter.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Controls 2.12 + +ApplicationWindow { + width: 400 + height: 400 + + property alias popup1: popup1 + property alias popup2: popup2 + + Popup { + id: popup1 + focus: true + enter: Transition { + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 100 } + } + } + + Popup { + id: popup2 + focus: true + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/applicationwindow-hover.qml b/tests/auto/quickcontrols2/qquickpopup/data/applicationwindow-hover.qml new file mode 100644 index 00000000000..fc93d16d917 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/applicationwindow-hover.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias popup: popup + property alias parentButton: parentButton + property alias childButton: childButton + + Button { + id: parentButton + text: "Parent" + anchors.fill: parent + + Popup { + id: popup + x: 1 + y: 1 + leftPadding: 1 + rightPadding: 1 + topPadding: 1 + bottomPadding: 1 + + + Button { + anchors.centerIn: parent + id: childButton + text: "Child" + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/applicationwindow-wheel.qml b/tests/auto/quickcontrols2/qquickpopup/data/applicationwindow-wheel.qml new file mode 100644 index 00000000000..163cf779969 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/applicationwindow-wheel.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 400 + height: 400 + + property alias popup: popup + property alias nestedPopup: nestedPopup + property alias popupSlider: popupSlider + property alias contentSlider: contentSlider + + Slider { + id: contentSlider + anchors.fill: parent + wheelEnabled: true + } + + Popup { + id: popup + x: 50; y: 50 + implicitWidth: parent.width - 100 + implicitHeight: parent.height - 100 + clip: true + contentItem: Slider { + id: popupSlider + wheelEnabled: true + } + + Popup { + id: nestedPopup + x: 0; y: 0 + clip: true + implicitWidth: 50 + implicitHeight: 50 + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/applicationwindow.qml b/tests/auto/quickcontrols2/qquickpopup/data/applicationwindow.qml new file mode 100644 index 00000000000..399f1c67c13 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/applicationwindow.qml @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias popup: popup + property alias popup2: popup2 + property alias popup3: popup3 + property alias button: button + property alias slider: slider + + Button { + id: button + text: "Open" + anchors.centerIn: parent + anchors.verticalCenterOffset: -height + + Popup { + id: popup + y: parent.height + + Text { + color: "white" + text: "Hello, world!" + + MouseArea { + anchors.fill: parent + onClicked: popup.close() + } + } + } + + Popup { + id: popup3 + y: parent.height + + Slider { + id: slider + } + } + } + + Popup { + id: popup2 + y: popup.y + z: 1 + contentItem: Text { + text: "Popup2" + font.pixelSize: 36 + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/centerInOverlayWithinStackViewItem.qml b/tests/auto/quickcontrols2/qquickpopup/data/centerInOverlayWithinStackViewItem.qml new file mode 100644 index 00000000000..aa25863aed3 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/centerInOverlayWithinStackViewItem.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property Popup popup: stackView.currentItem.popup + + StackView { + id: stackView + objectName: "stackView" + anchors.fill: parent + + initialItem: Rectangle { + objectName: "rectangle" + + property alias popup: popup + + Popup { + id: popup + objectName: "popup" + width: 100 + height: 100 + visible: true + anchors.centerIn: Overlay.overlay + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/closeOnEscapeWithNestedPopups.qml b/tests/auto/quickcontrols2/qquickpopup/data/closeOnEscapeWithNestedPopups.qml new file mode 100644 index 00000000000..71ec4e2b109 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/closeOnEscapeWithNestedPopups.qml @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + header: ToolBar { + ToolButton { + objectName: "optionsToolButton" + text: "Options" + onClicked: optionsMenu.open() + + Menu { + id: optionsMenu + objectName: "optionsMenu" + x: parent.width - width + transformOrigin: Menu.TopRight + + MenuItem { + objectName: "settingsMenuItem" + text: "Settings" + onTriggered: settingsDialog.open() + } + } + } + } + + Shortcut { + sequence: "Esc" + enabled: stackView.depth > 1 + onActivated: stackView.pop() + } + + Component { + id: itemComponent + + Item {} + } + + StackView { + id: stackView + objectName: "stackView" + anchors.fill: parent + initialItem: Item { + objectName: "initialStackViewItem" + } + + Component.onCompleted: push(itemComponent) + } + + Dialog { + id: settingsDialog + objectName: "settingsDialog" + modal: true + + contentItem: ComboBox { + objectName: "comboBox" + model: 10 + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/closeOnEscapeWithVisiblePopup.qml b/tests/auto/quickcontrols2/qquickpopup/data/closeOnEscapeWithVisiblePopup.qml new file mode 100644 index 00000000000..b65e4ec0c03 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/closeOnEscapeWithVisiblePopup.qml @@ -0,0 +1,16 @@ +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 400 + height: 400 + Popup { + objectName: "popup" + visible: true + width: 200 + height: 200 + anchors.centerIn: parent + closePolicy: Popup.CloseOnEscape + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/countChanged.qml b/tests/auto/quickcontrols2/qquickpopup/data/countChanged.qml new file mode 100644 index 00000000000..fd59433251e --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/countChanged.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 640 + height: 480 + property bool isModel1: true + property alias comboBox: comboBox + property int count: comboBox.count + ListModel { + id: model1 + ListElement { + display: "one" + } + } + ListModel { + id: model2 + ListElement { + display: "one" + } + ListElement { + display: "two" + } + } + ComboBox { + id: comboBox + model: isModel1 ? model1 : model2 + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/cursor.qml b/tests/auto/quickcontrols2/qquickpopup/data/cursor.qml new file mode 100644 index 00000000000..e2a6e38e311 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/cursor.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias popup: popup + property alias textField: textField + + TextField { + id: textField + } + Popup { + id: popup + x: textField.x + textField.width / 2 + y: textField.y + textField.height / 2 - height / 2 + width: 100 + height: 100 + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/destroyDuringExitTransition.qml b/tests/auto/quickcontrols2/qquickpopup/data/destroyDuringExitTransition.qml new file mode 100644 index 00000000000..67fca2e78e0 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/destroyDuringExitTransition.qml @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 400 + height: 400 + title: "destroyDuringExitTransition" + + property Dialog dialog1 + property Dialog dialog2 + + Component { + id: dlg + + Dialog { + dim: true + modal: true + closePolicy: Popup.CloseOnEscape + visible: true + + property alias button: button + + Column { + Text { + text: "button is " + (button.down ? "down" : "up") + } + + Button { + id: button + text: "Try to press this button" + } + } + } + } + + Component { + id: brokenDlg + Dialog { + dim: true + modal: true + closePolicy: Popup.CloseOnEscape + visible: true + + Text { + text: "Press Esc key to reject this dialog" + } + + exit: Transition { + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 100 } + } + } + } + + + Component.onCompleted: { + dialog1 = dlg.createObject(window) + dialog2 = brokenDlg.createObject(window) + + dialog2.onRejected.connect(function(){ + dialog2.destroy() + }) + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/dialog.qml b/tests/auto/quickcontrols2/qquickpopup/data/dialog.qml new file mode 100644 index 00000000000..75c0e1c689f --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/dialog.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Item { + width: 400 + height: 400 + objectName: "Rectangle" + + property alias dialog: dialog + + Dialog { + id: dialog + objectName: "Dialog" + width: 200 + height: 200 + anchors.centerIn: parent + visible: true + + Component.onCompleted: { + background.objectName = "DialogBackground" + contentItem.objectName = "DialogContentItem" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/dimmerContainmentMask.qml b/tests/auto/quickcontrols2/qquickpopup/data/dimmerContainmentMask.qml new file mode 100644 index 00000000000..c18c4c4054d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/dimmerContainmentMask.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 400 + height: 400 + title: "dimmerContainmentMask" + + property alias modalPopup: modalPopup + property int clickCount: 0 + + MouseArea { + anchors.fill: parent + onClicked: ++clickCount; + } + + Popup { + id: modalPopup + modal: true + x: 100 + y: 100 + width: 200 + height: 200 + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/disabledPalette.qml b/tests/auto/quickcontrols2/qquickpopup/data/disabledPalette.qml new file mode 100644 index 00000000000..f1608aae11d --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/disabledPalette.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias popup: popup + + function disableOverlay() { + popup.Overlay.overlay.enabled = false + } + + Popup { + id: popup + width: 200 + height: 200 + background: Rectangle { + color: popup.palette.base + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/grabber.qml b/tests/auto/quickcontrols2/qquickpopup/data/grabber.qml new file mode 100644 index 00000000000..507cc3b587a --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/grabber.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias menu: menu + property alias popup: popup + property alias combo: combo.popup + + Menu { + id: menu + MenuItem { + onTriggered: popup.open() + } + } + + Popup { + id: popup + modal: true + width: 200 + height: 200 + + ComboBox { + id: combo + model: 3 + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/invisibleToolTipOpen.qml b/tests/auto/quickcontrols2/qquickpopup/data/invisibleToolTipOpen.qml new file mode 100644 index 00000000000..aaed154b9cf --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/invisibleToolTipOpen.qml @@ -0,0 +1,28 @@ +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 400 + height: 400 + property alias mouseArea: mouseArea + property alias loader: loader + MouseArea { + id: mouseArea + property bool isToolTipVisible: false + width: 200 + height: 200 + hoverEnabled: true + ToolTip.text: "static tooltip" + ToolTip.visible: containsMouse + ToolTip.onVisibleChanged: isToolTipVisible = ToolTip.visible + } + Loader { + id: loader + active: false + sourceComponent: Rectangle { + ToolTip.text: "dynamic tooltip" + ToolTip.visible: false + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/mirroredCombobox.qml b/tests/auto/quickcontrols2/qquickpopup/data/mirroredCombobox.qml new file mode 100644 index 00000000000..ed48179bced --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/mirroredCombobox.qml @@ -0,0 +1,26 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +Window { + width: 400 + height: 400 + + contentItem.rotation: 180 + + ComboBox { + objectName: "first" + x: 100 + y: 300 // is missing space, needs to unroll in the "mirrored" direction + model: ["First", "Second", "Third", "Fourth", "Fifth"] + } + + ComboBox { + objectName: "second" + x: 200 + y: 100 // has enough space to unroll + model: ["A", "B", "C"] + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/modelessOnModalOnModeless.qml b/tests/auto/quickcontrols2/qquickpopup/data/modelessOnModalOnModeless.qml new file mode 100644 index 00000000000..b5909b7feb1 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/modelessOnModalOnModeless.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias modelessPopup: modelessPopup + property alias button: button + property alias modalPopup: modalPopup + property alias tooltip: tooltip + + Popup { + id: modelessPopup + modal: false + closePolicy: Popup.NoAutoClose + width: 200 + height: 200 + anchors.centerIn: parent + + Button { + id: button + checkable: true + x: 0 + y: 0 + text: "Click me" + } + + Popup { + id: modalPopup + modal: true + closePolicy: Popup.NoAutoClose + width: 100 + height: 100 + anchors.centerIn: parent + + Popup { + id: tooltip + modal: false + closePolicy: Popup.NoAutoClose + width: 50 + height: 50 + anchors.centerIn: parent + } + } + } + +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/nested.qml b/tests/auto/quickcontrols2/qquickpopup/data/nested.qml new file mode 100644 index 00000000000..03269cd194b --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/nested.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + + property alias modalPopup: modalPopup + property alias modelessPopup: modelessPopup + + Popup { + id: modalPopup + modal: true + width: 200 + height: 200 + } + + Popup { + id: modelessPopup + modal: false + width: 100 + height: 100 + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/orientation.qml b/tests/auto/quickcontrols2/qquickpopup/data/orientation.qml new file mode 100644 index 00000000000..9730a9e14c2 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/orientation.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 600 + height: 300 + + property alias popup: popup + + Rectangle { + width: 60 + height: 30 + anchors.centerIn: parent + border.width: 1 + + Popup { + id: popup + x: parent.width + y: parent.height + width: 30 + height: 60 + visible: true + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/releaseAfterExitTransition.qml b/tests/auto/quickcontrols2/qquickpopup/data/releaseAfterExitTransition.qml new file mode 100644 index 00000000000..cfd9a9473de --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/releaseAfterExitTransition.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 400 + height: 400 + title: "releaseAfterExitTransition" + + property alias popup: popup + property alias modalPopup: modalPopup + + Popup { + id: popup + y: parent.height - height + width: 50 + height: 50 + } + + Popup { + id: modalPopup + modal: true + y: parent.height - height + width: 50 + height: 50 + exit: Transition { PauseAnimation { duration: 100 } } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/rotatedCombobox.qml b/tests/auto/quickcontrols2/qquickpopup/data/rotatedCombobox.qml new file mode 100644 index 00000000000..df217be4b76 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/rotatedCombobox.qml @@ -0,0 +1,26 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +Window { + width: 400 + height: 400 + + contentItem.rotation: 90 + + ComboBox { + objectName: "first" + x: 100 + y: 320 // is missing space, needs to unroll in the "mirrored" direction + model: ["First", "Second", "Third", "Fourth", "Fifth"] + } + + ComboBox { + objectName: "second" + x: 200 + y: 100 // has enough space to unroll + model: ["A", "B", "C"] + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/shrinkPopupThatWasLargerThanWindowHeight.qml b/tests/auto/quickcontrols2/qquickpopup/data/shrinkPopupThatWasLargerThanWindowHeight.qml new file mode 100644 index 00000000000..09765802ac3 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/shrinkPopupThatWasLargerThanWindowHeight.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: root + width: 400 + height: 400 + + property alias popup: popup + property int model: 40 + + Popup { + id: popup + width: 100 + + contentItem: ListView { + implicitHeight: contentHeight + model: root.model + delegate: Text { text: modelData } + clip: true + + ScrollIndicator.vertical: ScrollIndicator {} + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/shrinkPopupThatWasLargerThanWindowWidth.qml b/tests/auto/quickcontrols2/qquickpopup/data/shrinkPopupThatWasLargerThanWindowWidth.qml new file mode 100644 index 00000000000..80639aed40c --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/shrinkPopupThatWasLargerThanWindowWidth.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: root + width: 400 + height: 400 + + property alias popup: popup + property int model: 40 + + Popup { + id: popup + height: 100 + + contentItem: ListView { + implicitWidth: contentWidth + model: root.model + delegate: Text { text: modelData } + clip: true + orientation: Qt.Horizontal + + ScrollIndicator.horizontal: ScrollIndicator {} + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/tabFence.qml b/tests/auto/quickcontrols2/qquickpopup/data/tabFence.qml new file mode 100644 index 00000000000..ce5b54177cf --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/tabFence.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Window +import QtQuick.Controls + +ApplicationWindow { + width: 400 + height: 400 + objectName: "Rectangle" + + property alias dialog: dialog + property alias outsideButton1: outsideButton1 + property alias outsideButton2: outsideButton2 + property alias dialogButton1: dialogButton1 + property alias dialogButton2: dialogButton2 + + ColumnLayout { + Button { + id: outsideButton1 + text: "Button1" + } + Button { + id: outsideButton2 + text: "Button2" + } + } + + Dialog { + id: dialog + objectName: "Dialog" + width: 200 + height: 200 + anchors.centerIn: parent + visible: true + + ColumnLayout { + Button { + id: dialogButton1 + text: "Button3" + } + Button { + id: dialogButton2 + text: "Button4" + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/toolTipCrashOnClose.qml b/tests/auto/quickcontrols2/qquickpopup/data/toolTipCrashOnClose.qml new file mode 100644 index 00000000000..33452182fe2 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/toolTipCrashOnClose.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtGraphicalEffects + +Window { + width: 640 + height: 480 + + readonly property bool toolTipOpened: mouseArea.ToolTip.toolTip.opened + + Component.onCompleted: contentItem.objectName = "windowContentItem" + + // For the setOverlayParentToNull test. + function nullifyOverlayParent() { + Overlay.overlay.parent = null + } + + Item { + objectName: "outerItem" + anchors.fill: parent + + Item { + objectName: "innerItem" + anchors.fill: parent + + ColorOverlay { + objectName: "colorOverlay" + source: parent + anchors.fill: parent + } + + MouseArea { + id: mouseArea + objectName: "mouseArea" + anchors.fill: parent + hoverEnabled: true + + ToolTip.visible: containsMouse + ToolTip.text: "ToolTip text" + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/window-hover.qml b/tests/auto/quickcontrols2/qquickpopup/data/window-hover.qml new file mode 100644 index 00000000000..5064fda7bce --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/window-hover.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 400 + height: 400 + + property alias popup: popup + property alias parentButton: parentButton + property alias childButton: childButton + + Button { + id: parentButton + text: "Parent" + anchors.fill: parent + + Popup { + id: popup + x: 1 + y: 1 + topPadding: 1 + bottomPadding: 1 + leftPadding: 1 + rightPadding: 1 + + Button { + anchors.centerIn: parent + id: childButton + text: "Child" + } + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/window-wheel.qml b/tests/auto/quickcontrols2/qquickpopup/data/window-wheel.qml new file mode 100644 index 00000000000..8eb5260cf3f --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/window-wheel.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + id: window + width: 400 + height: 400 + + property alias popup: popup + property alias nestedPopup: nestedPopup + property alias popupSlider: popupSlider + property alias contentSlider: contentSlider + + Slider { + id: contentSlider + anchors.fill: parent + wheelEnabled: true + } + + Popup { + id: popup + x: 50; y: 50 + implicitWidth: parent.width - 100 + implicitHeight: parent.height - 100 + clip: true + contentItem: Slider { + id: popupSlider + wheelEnabled: true + } + + Popup { + id: nestedPopup + x: 0; y: 0 + clip: true + implicitWidth: 50 + implicitHeight: 50 + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/data/window.qml b/tests/auto/quickcontrols2/qquickpopup/data/window.qml new file mode 100644 index 00000000000..d46d8ccbf1e --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/data/window.qml @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 400 + height: 400 + + property alias popup: popup + property alias popup2: popup2 + property alias popup3: popup3 + property alias button: button + property alias slider: slider + + Button { + id: button + text: "Open" + anchors.centerIn: parent + anchors.verticalCenterOffset: -height + + Popup { + id: popup + y: parent.height + + Text { + color: "white" + text: "Hello, world!" + + MouseArea { + anchors.fill: parent + onClicked: popup.close() + } + } + } + + Popup { + id: popup3 + y: parent.height + + Slider { + id: slider + } + } + } + + Popup { + id: popup2 + y: popup.y + z: 1 + contentItem: Text { + text: "Popup2" + font.pixelSize: 36 + } + } +} diff --git a/tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp b/tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp new file mode 100644 index 00000000000..a587c085a4a --- /dev/null +++ b/tests/auto/quickcontrols2/qquickpopup/tst_qquickpopup.cpp @@ -0,0 +1,2043 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> + +#include <QtCore/qoperatingsystemversion.h> +#include <QtGui/qpa/qwindowsysteminterface.h> +#include <QtGui/qpa/qplatformintegration.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtQuick/qquickview.h> +#include <QtQuick/private/qquickpalette_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include <QtQuickTemplates2/private/qquickoverlay_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p.h> +#include <QtQuickTemplates2/private/qquickpopupitem_p_p.h> +#include <QtQuickTemplates2/private/qquickbutton_p.h> +#include <QtQuickTemplates2/private/qquickslider_p.h> +#include <QtQuickTemplates2/private/qquickstackview_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p_p.h> +#include <QtQuickTemplates2/private/qquicktooltip_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> +#include <QtQuickControlsTestUtils/private/qtest_quickcontrols_p.h> + +using namespace QQuickVisualTestUtils; +using namespace QQuickControlsTestUtils; + +class tst_QQuickPopup : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_QQuickPopup(); + +private slots: + void initTestCase() override; + void visible_data(); + void visible(); + void state(); + void overlay_data(); + void overlay(); + void zOrder_data(); + void zOrder(); + void windowChange(); + void closePolicy_data(); + void closePolicy(); + void closePolicy_grabberInside_data(); + void closePolicy_grabberInside(); + void activeFocusOnClose1(); + void activeFocusOnClose2(); + void activeFocusOnClose3(); + void activeFocusOnClosingSeveralPopups(); + void activeFocusAfterExit(); + void activeFocusOnDelayedEnter(); + void hover_data(); + void hover(); + void wheel_data(); + void wheel(); + void parentDestroyed(); + void nested(); + void modelessOnModalOnModeless(); + void grabber(); + void cursorShape(); + void componentComplete(); + void closeOnEscapeWithNestedPopups(); + void closeOnEscapeWithVisiblePopup(); + void enabled(); + void orientation_data(); + void orientation(); + void qquickview(); + void disabledPalette(); + void disabledParentPalette(); + void countChanged(); + void toolTipCrashOnClose(); + void setOverlayParentToNull(); + void tabFence(); + void invisibleToolTipOpen(); + void centerInOverlayWithinStackViewItem(); + void destroyDuringExitTransition(); + void releaseAfterExitTransition(); + void dimmerContainmentMask(); + void shrinkPopupThatWasLargerThanWindow_data(); + void shrinkPopupThatWasLargerThanWindow(); + void mirroredCombobox(); + void rotatedCombobox(); + +private: + static bool hasWindowActivation(); + QScopedPointer<QPointingDevice> touchScreen = QScopedPointer<QPointingDevice>(QTest::createTouchDevice()); +}; + +tst_QQuickPopup::tst_QQuickPopup() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_QQuickPopup::initTestCase() +{ + QQmlDataTest::initTestCase(); + qputenv("QML_NO_TOUCH_COMPRESSION", "1"); +} + +void tst_QQuickPopup::visible_data() +{ + QTest::addColumn<QString>("source"); + QTest::newRow("Window") << "window.qml"; + QTest::newRow("ApplicationWindow") << "applicationwindow.qml"; +} + +bool tst_QQuickPopup::hasWindowActivation() +{ + return (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)); +} + +void tst_QQuickPopup::visible() +{ + QFETCH(QString, source); + QQuickControlsApplicationHelper helper(this, source); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup); + QQuickItem *popupItem = popup->popupItem(); + + popup->open(); + QVERIFY(popup->isVisible()); + + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + QVERIFY(overlay); + QVERIFY(overlay->childItems().contains(popupItem)); + + popup->close(); + QTRY_VERIFY(!popup->isVisible()); + QVERIFY(!overlay->childItems().contains(popupItem)); + + popup->setVisible(true); + QVERIFY(popup->isVisible()); + QVERIFY(overlay->childItems().contains(popupItem)); + + popup->setVisible(false); + QTRY_VERIFY(!popup->isVisible()); + QVERIFY(!overlay->childItems().contains(popupItem)); +} + +void tst_QQuickPopup::state() +{ + QQuickControlsApplicationHelper helper(this, "applicationwindow.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup); + + QCOMPARE(popup->isVisible(), false); + + QSignalSpy visibleChangedSpy(popup, SIGNAL(visibleChanged())); + QSignalSpy aboutToShowSpy(popup, SIGNAL(aboutToShow())); + QSignalSpy aboutToHideSpy(popup, SIGNAL(aboutToHide())); + QSignalSpy openedSpy(popup, SIGNAL(opened())); + QSignalSpy closedSpy(popup, SIGNAL(closed())); + + QVERIFY(visibleChangedSpy.isValid()); + QVERIFY(aboutToShowSpy.isValid()); + QVERIFY(aboutToHideSpy.isValid()); + QVERIFY(openedSpy.isValid()); + QVERIFY(closedSpy.isValid()); + + popup->open(); + QCOMPARE(visibleChangedSpy.count(), 1); + QCOMPARE(aboutToShowSpy.count(), 1); + QCOMPARE(aboutToHideSpy.count(), 0); + QTRY_COMPARE(openedSpy.count(), 1); + QCOMPARE(closedSpy.count(), 0); + + popup->close(); + QTRY_COMPARE(visibleChangedSpy.count(), 2); + QCOMPARE(aboutToShowSpy.count(), 1); + QCOMPARE(aboutToHideSpy.count(), 1); + QCOMPARE(openedSpy.count(), 1); + QTRY_COMPARE(closedSpy.count(), 1); +} + +void tst_QQuickPopup::overlay_data() +{ + QTest::addColumn<QString>("source"); + QTest::addColumn<bool>("modal"); + QTest::addColumn<bool>("dim"); + + QTest::newRow("Window") << "window.qml" << false << false; + QTest::newRow("Window,dim") << "window.qml" << false << true; + QTest::newRow("Window,modal") << "window.qml" << true << false; + QTest::newRow("Window,modal,dim") << "window.qml" << true << true; + + QTest::newRow("ApplicationWindow") << "applicationwindow.qml" << false << false; + QTest::newRow("ApplicationWindow,dim") << "applicationwindow.qml" << false << true; + QTest::newRow("ApplicationWindow,modal") << "applicationwindow.qml" << true << false; + QTest::newRow("ApplicationWindow,modal,dim") << "applicationwindow.qml" << true << true; +} + +void tst_QQuickPopup::overlay() +{ + QFETCH(QString, source); + QFETCH(bool, modal); + QFETCH(bool, dim); + + QQuickControlsApplicationHelper helper(this, source); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + QVERIFY(overlay); + + QSignalSpy overlayPressedSignal(overlay, SIGNAL(pressed())); + QSignalSpy overlayReleasedSignal(overlay, SIGNAL(released())); + QVERIFY(overlayPressedSignal.isValid()); + QVERIFY(overlayReleasedSignal.isValid()); + + QVERIFY(!overlay->isVisible()); // no popups open + + QTest::mouseClick(window, Qt::LeftButton); + QCOMPARE(overlayPressedSignal.count(), 0); + QCOMPARE(overlayReleasedSignal.count(), 0); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup); + + QQuickOverlayAttached *overlayAttached = qobject_cast<QQuickOverlayAttached *>(qmlAttachedPropertiesObject<QQuickOverlay>(popup)); + QVERIFY(overlayAttached); + QCOMPARE(overlayAttached->overlay(), overlay); + + QSignalSpy overlayAttachedPressedSignal(overlayAttached, SIGNAL(pressed())); + QSignalSpy overlayAttachedReleasedSignal(overlayAttached, SIGNAL(released())); + QVERIFY(overlayAttachedPressedSignal.isValid()); + QVERIFY(overlayAttachedReleasedSignal.isValid()); + + QQuickButton *button = window->property("button").value<QQuickButton*>(); + QVERIFY(button); + + int overlayPressCount = 0; + int overlayReleaseCount = 0; + + popup->open(); + QVERIFY(popup->isVisible()); + QVERIFY(overlay->isVisible()); + QTRY_VERIFY(popup->isOpened()); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount); + QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount); + + QTRY_VERIFY(!popup->isVisible()); + QVERIFY(!overlay->isVisible()); + + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QCOMPARE(overlayPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount); // no modal-popups open + QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount); + + popup->setDim(dim); + popup->setModal(modal); + popup->setClosePolicy(QQuickPopup::CloseOnReleaseOutside); + + // mouse + popup->open(); + QVERIFY(popup->isVisible()); + QVERIFY(overlay->isVisible()); + QTRY_VERIFY(popup->isOpened()); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount); + QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount); + + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QCOMPARE(overlayPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), ++overlayReleaseCount); + QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount); + + QTRY_VERIFY(!popup->isVisible()); + QVERIFY(!overlay->isVisible()); + + // touch + popup->open(); + QVERIFY(popup->isVisible()); + QVERIFY(overlay->isVisible()); + + + QTest::touchEvent(window, touchScreen.data()).press(0, QPoint(1, 1)); + QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount); + QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount); + + QTest::touchEvent(window, touchScreen.data()).release(0, QPoint(1, 1)); + QCOMPARE(overlayPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), ++overlayReleaseCount); + QCOMPARE(overlayAttachedPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayAttachedReleasedSignal.count(), overlayReleaseCount); + + QTRY_VERIFY(!popup->isVisible()); + QVERIFY(!overlay->isVisible()); + + // multi-touch + popup->open(); + QVERIFY(popup->isVisible()); + QVERIFY(overlay->isVisible()); + QVERIFY(!button->isPressed()); + + QTest::touchEvent(window, touchScreen.data()).press(0, button->mapToScene(QPointF(1, 1)).toPoint()); + QVERIFY(popup->isVisible()); + QVERIFY(overlay->isVisible()); + QCOMPARE(button->isPressed(), !modal); + QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount); + + QTest::touchEvent(window, touchScreen.data()).stationary(0).press(1, button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint()); + QVERIFY(popup->isVisible()); + QVERIFY(overlay->isVisible()); + QCOMPARE(button->isPressed(), !modal); + QCOMPARE(overlayPressedSignal.count(), ++overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount); + + QTest::touchEvent(window, touchScreen.data()).release(0, button->mapToScene(QPointF(1, 1)).toPoint()).stationary(1); + QTRY_VERIFY(!popup->isVisible()); + QVERIFY(!overlay->isVisible()); + QVERIFY(!button->isPressed()); + QCOMPARE(overlayPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), ++overlayReleaseCount); + + QTest::touchEvent(window, touchScreen.data()).release(1, button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint()); + QVERIFY(!popup->isVisible()); + QVERIFY(!overlay->isVisible()); + QVERIFY(!button->isPressed()); + QCOMPARE(overlayPressedSignal.count(), overlayPressCount); + QCOMPARE(overlayReleasedSignal.count(), overlayReleaseCount); +} + +void tst_QQuickPopup::zOrder_data() +{ + QTest::addColumn<QString>("source"); + QTest::newRow("Window") << "window.qml"; + QTest::newRow("ApplicationWindow") << "applicationwindow.qml"; +} + +void tst_QQuickPopup::zOrder() +{ + QFETCH(QString, source); + QQuickControlsApplicationHelper helper(this, source); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup); + popup->setModal(true); + + QQuickPopup *popup2 = window->property("popup2").value<QQuickPopup*>(); + QVERIFY(popup2); + popup2->setModal(true); + + // show popups in reverse order. popup2 has higher z-order so it appears + // on top and must be closed first, even if the other popup was opened last + popup2->open(); + popup->open(); + QVERIFY(popup2->isVisible()); + QVERIFY(popup->isVisible()); + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QTRY_VERIFY(!popup2->isVisible()); + QVERIFY(popup->isVisible()); + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QVERIFY(!popup2->isVisible()); + QTRY_VERIFY(!popup->isVisible()); +} + +void tst_QQuickPopup::windowChange() +{ + QQuickPopup popup; + QSignalSpy spy(&popup, SIGNAL(windowChanged(QQuickWindow*))); + QVERIFY(spy.isValid()); + + QQuickItem item; + popup.setParentItem(&item); + QVERIFY(!popup.window()); + QCOMPARE(spy.count(), 0); + + QQuickWindow window; + item.setParentItem(window.contentItem()); + QCOMPARE(popup.window(), &window); + QCOMPARE(spy.count(), 1); + + item.setParentItem(nullptr); + QVERIFY(!popup.window()); + QCOMPARE(spy.count(), 2); + + popup.setParentItem(window.contentItem()); + QCOMPARE(popup.window(), &window); + QCOMPARE(spy.count(), 3); + + popup.resetParentItem(); + QVERIFY(!popup.window()); + QCOMPARE(spy.count(), 4); + + popup.setParent(&window); + popup.resetParentItem(); + QCOMPARE(popup.window(), &window); + QCOMPARE(spy.count(), 5); + + popup.setParent(this); + popup.resetParentItem(); + QVERIFY(!popup.window()); + QCOMPARE(spy.count(), 6); + + item.setParentItem(window.contentItem()); + popup.setParent(&item); + popup.resetParentItem(); + QCOMPARE(popup.window(), &window); + QCOMPARE(spy.count(), 7); + + popup.setParent(nullptr); +} + +Q_DECLARE_METATYPE(QQuickPopup::ClosePolicy) + +void tst_QQuickPopup::closePolicy_data() +{ + qRegisterMetaType<QQuickPopup::ClosePolicy>(); + + QTest::addColumn<QString>("source"); + QTest::addColumn<QQuickPopup::ClosePolicy>("closePolicy"); + + QTest::newRow("Window:NoAutoClose") << "window.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose); + QTest::newRow("Window:CloseOnPressOutside") << "window.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside); + QTest::newRow("Window:CloseOnPressOutsideParent") << "window.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent); + QTest::newRow("Window:CloseOnPressOutside|Parent") << "window.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent); + QTest::newRow("Window:CloseOnReleaseOutside") << "window.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside); + QTest::newRow("Window:CloseOnReleaseOutside|Parent") << "window.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent); + QTest::newRow("Window:CloseOnEscape") << "window.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape); + + QTest::newRow("ApplicationWindow:NoAutoClose") << "applicationwindow.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::NoAutoClose); + QTest::newRow("ApplicationWindow:CloseOnPressOutside") << "applicationwindow.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside); + QTest::newRow("ApplicationWindow:CloseOnPressOutsideParent") << "applicationwindow.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutsideParent); + QTest::newRow("ApplicationWindow:CloseOnPressOutside|Parent") << "applicationwindow.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent); + QTest::newRow("ApplicationWindow:CloseOnReleaseOutside") << "applicationwindow.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside); + QTest::newRow("ApplicationWindow:CloseOnReleaseOutside|Parent") << "applicationwindow.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent); + QTest::newRow("ApplicationWindow:CloseOnEscape") << "applicationwindow.qml" << static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnEscape); +} + +void tst_QQuickPopup::closePolicy() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + QFETCH(QString, source); + QFETCH(QQuickPopup::ClosePolicy, closePolicy); + + QQuickControlsApplicationHelper helper(this, source); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup); + + QQuickButton *button = window->property("button").value<QQuickButton*>(); + QVERIFY(button); + + popup->setModal(true); + popup->setFocus(true); + popup->setClosePolicy(closePolicy); + + popup->open(); + QVERIFY(popup->isVisible()); + QTRY_VERIFY(popup->isOpened()); + + // wait for dimmer + QTest::qWait(50); + + for (int i = 0; i < 2; ++i) { + // press outside popup and its parent + QTest::touchEvent(window, touchScreen.data()).press(0, {1, 1}); + QQuickTouchUtils::flush(window); + if (closePolicy.testFlag(QQuickPopup::CloseOnPressOutside) || closePolicy.testFlag(QQuickPopup::CloseOnPressOutsideParent)) + QTRY_VERIFY(!popup->isVisible()); + else + QVERIFY(popup->isOpened()); + + popup->open(); + QVERIFY(popup->isVisible()); + QTRY_VERIFY(popup->isOpened()); + + // release outside popup and its parent + QTest::touchEvent(window, touchScreen.data()).release(0, {1, 1}); + QQuickTouchUtils::flush(window); + if (closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutside) || closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutsideParent)) + QTRY_VERIFY(!popup->isVisible()); + else + QVERIFY(popup->isOpened()); + + popup->open(); + QVERIFY(popup->isVisible()); + QTRY_VERIFY(popup->isOpened()); + + // press outside popup but inside its parent + QTest::touchEvent(window, touchScreen.data()).press(0, QPoint(button->x() + 1, button->y() + 1)); + QQuickTouchUtils::flush(window); + if (closePolicy.testFlag(QQuickPopup::CloseOnPressOutside) && !closePolicy.testFlag(QQuickPopup::CloseOnPressOutsideParent)) + QTRY_VERIFY(!popup->isVisible()); + else + QVERIFY(popup->isOpened()); + + popup->open(); + QVERIFY(popup->isVisible()); + QTRY_VERIFY(popup->isOpened()); + + // release outside popup but inside its parent + QTest::touchEvent(window, touchScreen.data()).release(0, QPoint(button->x() + 1, button->y() + 1)); + QQuickTouchUtils::flush(window); + if (closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutside) && !closePolicy.testFlag(QQuickPopup::CloseOnReleaseOutsideParent)) + QTRY_VERIFY(!popup->isVisible()); + else + QVERIFY(popup->isOpened()); + + popup->open(); + QVERIFY(popup->isVisible()); + QTRY_VERIFY(popup->isOpened()); + + // press inside and release outside + QTest::touchEvent(window, touchScreen.data()).press(0, QPoint(button->x() + popup->x() + 1, + button->y() + popup->y() + 1)); + QQuickTouchUtils::flush(window); + QVERIFY(popup->isOpened()); + QTest::touchEvent(window, touchScreen.data()).release(0, {1, 1}); + QQuickTouchUtils::flush(window); + QVERIFY(popup->isOpened()); + } + + // escape + QTest::keyClick(window, Qt::Key_Escape); + if (closePolicy.testFlag(QQuickPopup::CloseOnEscape)) + QTRY_VERIFY(!popup->isVisible()); + else + QVERIFY(popup->isVisible()); +} + +void tst_QQuickPopup::closePolicy_grabberInside_data() +{ + qRegisterMetaType<QQuickPopup::ClosePolicy>(); + + QTest::addColumn<QString>("source"); + QTest::addColumn<QQuickPopup::ClosePolicy>("closePolicy"); + + QTest::newRow("Window:CloseOnReleaseOutside") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside); + QTest::newRow("Window:CloseOnReleaseOutside|Parent") << "window.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent); + + QTest::newRow("ApplicationWindow:CloseOnReleaseOutside") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside); + QTest::newRow("ApplicationWindow:CloseOnReleaseOutside|Parent") << "applicationwindow.qml"<< static_cast<QQuickPopup::ClosePolicy>(QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent); +} + +void tst_QQuickPopup::closePolicy_grabberInside() +{ + QFETCH(QString, source); + QFETCH(QQuickPopup::ClosePolicy, closePolicy); + + QQuickControlsApplicationHelper helper(this, source); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *popup = window->property("popup3").value<QQuickPopup*>(); + QVERIFY(popup); + + QQuickSlider *slider = window->property("slider").value<QQuickSlider*>(); + QVERIFY(slider); + + popup->setModal(true); + popup->setClosePolicy(closePolicy); + + popup->open(); + QVERIFY(popup->isVisible()); + QTRY_VERIFY(popup->isOpened()); + + // press on a mouse grabber inside and release outside + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, + slider->handle()->mapToItem(window->contentItem(),slider->handle()->boundingRect().center()).toPoint()); + + QVERIFY(popup->isOpened()); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QVERIFY(popup->isOpened()); +} + +void tst_QQuickPopup::activeFocusOnClose1() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + // Test that a popup that never sets focus: true (e.g. ToolTip) doesn't affect + // the active focus item when it closes. + QQuickControlsApplicationHelper helper(this, QStringLiteral("activeFocusOnClose1.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickPopup *focusedPopup = helper.appWindow->property("focusedPopup").value<QQuickPopup*>(); + QVERIFY(focusedPopup); + + QQuickPopup *nonFocusedPopup = helper.appWindow->property("nonFocusedPopup").value<QQuickPopup*>(); + QVERIFY(nonFocusedPopup); + + focusedPopup->open(); + QVERIFY(focusedPopup->isVisible()); + QTRY_VERIFY(focusedPopup->isOpened()); + QVERIFY(focusedPopup->hasActiveFocus()); + + nonFocusedPopup->open(); + QVERIFY(nonFocusedPopup->isVisible()); + QTRY_VERIFY(nonFocusedPopup->isOpened()); + QVERIFY(focusedPopup->hasActiveFocus()); + + nonFocusedPopup->close(); + QTRY_VERIFY(!nonFocusedPopup->isVisible()); + QVERIFY(focusedPopup->hasActiveFocus()); + + // QTBUG-66113: force active focus on a popup that did not request focus + nonFocusedPopup->open(); + nonFocusedPopup->forceActiveFocus(); + QVERIFY(nonFocusedPopup->isVisible()); + QTRY_VERIFY(nonFocusedPopup->isOpened()); + QVERIFY(nonFocusedPopup->hasActiveFocus()); + + nonFocusedPopup->close(); + QTRY_VERIFY(!nonFocusedPopup->isVisible()); + QVERIFY(focusedPopup->hasActiveFocus()); +} + +void tst_QQuickPopup::activeFocusOnClose2() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + // Test that a popup that sets focus: true but relinquishes focus (e.g. by + // calling forceActiveFocus() on another item) before it closes doesn't + // affect the active focus item when it closes. + QQuickControlsApplicationHelper helper(this, QStringLiteral("activeFocusOnClose2.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickPopup *popup1 = helper.appWindow->property("popup1").value<QQuickPopup*>(); + QVERIFY(popup1); + + QQuickPopup *popup2 = helper.appWindow->property("popup2").value<QQuickPopup*>(); + QVERIFY(popup2); + + QQuickButton *closePopup2Button = helper.appWindow->property("closePopup2Button").value<QQuickButton*>(); + QVERIFY(closePopup2Button); + + popup1->open(); + QVERIFY(popup1->isVisible()); + QTRY_VERIFY(popup1->isOpened()); + QVERIFY(popup1->hasActiveFocus()); + + popup2->open(); + QVERIFY(popup2->isVisible()); + QTRY_VERIFY(popup2->isOpened()); + QVERIFY(popup2->hasActiveFocus()); + + // Causes popup1.contentItem.forceActiveFocus() to be called, then closes popup2. + QTRY_VERIFY(closePopup2Button->width() > 0); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, + closePopup2Button->mapToScene(QPointF(closePopup2Button->width() / 2, closePopup2Button->height() / 2)).toPoint()); + QTRY_VERIFY(!popup2->isVisible()); + QVERIFY(popup1->hasActiveFocus()); +} + +void tst_QQuickPopup::activeFocusOnClose3() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + // Test that a closing popup that had focus doesn't steal focus from + // another popup that the focus was transferred to. + QQuickControlsApplicationHelper helper(this, QStringLiteral("activeFocusOnClose3.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickPopup *popup1 = helper.appWindow->property("popup1").value<QQuickPopup*>(); + QVERIFY(popup1); + + QQuickPopup *popup2 = helper.appWindow->property("popup2").value<QQuickPopup*>(); + QVERIFY(popup2); + + popup1->open(); + QVERIFY(popup1->isVisible()); + QTRY_VERIFY(popup1->hasActiveFocus()); + + popup2->open(); + popup1->close(); + + QSignalSpy closedSpy(popup1, SIGNAL(closed())); + QVERIFY(closedSpy.isValid()); + QVERIFY(closedSpy.wait()); + + QVERIFY(!popup1->isVisible()); + QVERIFY(popup2->isVisible()); + QTRY_VERIFY(popup2->hasActiveFocus()); +} + +void tst_QQuickPopup::activeFocusOnClosingSeveralPopups() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + // Test that active focus isn't lost when multiple popup closing simultaneously + QQuickControlsApplicationHelper helper(this, QStringLiteral("activeFocusOnClosingSeveralPopups.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickItem *button = window->property("button").value<QQuickItem *>(); + QVERIFY(button); + + QQuickPopup *popup1 = window->property("popup1").value<QQuickPopup *>(); + QVERIFY(popup1); + + QQuickPopup *popup2 = window->property("popup2").value<QQuickPopup *>(); + QVERIFY(popup2); + + QCOMPARE(button->hasActiveFocus(), true); + popup1->open(); + QTRY_VERIFY(popup1->isOpened()); + QVERIFY(popup1->hasActiveFocus()); + popup2->open(); + QTRY_VERIFY(popup2->isOpened()); + QVERIFY(popup2->hasActiveFocus()); + QTRY_COMPARE(button->hasActiveFocus(), false); + // close the unfocused popup first + popup1->close(); + popup2->close(); + QTRY_VERIFY(!popup1->isVisible()); + QTRY_VERIFY(!popup2->isVisible()); + QTRY_COMPARE(button->hasActiveFocus(), true); + + popup1->open(); + QTRY_VERIFY(popup1->isOpened()); + QVERIFY(popup1->hasActiveFocus()); + popup2->open(); + QTRY_VERIFY(popup2->isOpened()); + QVERIFY(popup2->hasActiveFocus()); + QTRY_COMPARE(button->hasActiveFocus(), false); + // close the focused popup first + popup2->close(); + popup1->close(); + QTRY_VERIFY(!popup1->isVisible()); + QTRY_VERIFY(!popup2->isVisible()); + QTRY_COMPARE(button->hasActiveFocus(), true); +} + +void tst_QQuickPopup::activeFocusAfterExit() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + // Test that after closing a popup the highest one in z-order receives it instead. + QQuickControlsApplicationHelper helper(this, QStringLiteral("activeFocusAfterExit.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickPopup *popup1 = window->property("popup1").value<QQuickPopup*>(); + QVERIFY(popup1); + + QQuickPopup *popup2 = window->property("popup2").value<QQuickPopup*>(); + QVERIFY(popup2); + QSignalSpy closedSpy2(popup2, SIGNAL(closed())); + QVERIFY(closedSpy2.isValid()); + + QQuickPopup *popup3 = window->property("popup3").value<QQuickPopup*>(); + QVERIFY(popup3); + QSignalSpy closedSpy3(popup3, SIGNAL(closed())); + QVERIFY(closedSpy3.isValid()); + + popup1->open(); + QVERIFY(popup1->isVisible()); + QTRY_VERIFY(popup1->hasActiveFocus()); + + popup2->open(); + QVERIFY(popup2->isVisible()); + QTRY_VERIFY(!popup2->hasActiveFocus()); + + popup3->open(); + QVERIFY(popup3->isVisible()); + QTRY_VERIFY(popup3->hasActiveFocus()); + + popup3->close(); + closedSpy3.wait(); + QVERIFY(!popup3->isVisible()); + QTRY_VERIFY(!popup3->hasActiveFocus()); + QTRY_VERIFY(!popup2->hasActiveFocus()); + QTRY_VERIFY(popup1->hasActiveFocus()); + + popup2->close(); + closedSpy2.wait(); + QVERIFY(!popup2->isVisible()); + QTRY_VERIFY(!popup2->hasActiveFocus()); + QTRY_VERIFY(popup1->hasActiveFocus()); +} + +void tst_QQuickPopup::activeFocusOnDelayedEnter() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + // Test that after opening two popups, first of which has an animation, does not cause + // the first one to receive focus after the animation stops. + QQuickControlsApplicationHelper helper(this, QStringLiteral("activeFocusOnDelayedEnter.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickPopup *popup1 = window->property("popup1").value<QQuickPopup*>(); + QVERIFY(popup1); + QSignalSpy openedSpy(popup1, SIGNAL(opened())); + + QQuickPopup *popup2 = window->property("popup2").value<QQuickPopup*>(); + QVERIFY(popup2); + + popup1->open(); + popup2->open(); + openedSpy.wait(); + QTRY_VERIFY(popup2->hasActiveFocus()); +} + +void tst_QQuickPopup::hover_data() +{ + QTest::addColumn<QString>("source"); + QTest::addColumn<bool>("modal"); + + QTest::newRow("Window:modal") << "window-hover.qml" << true; + QTest::newRow("Window:modeless") << "window-hover.qml" << false; + QTest::newRow("ApplicationWindow:modal") << "applicationwindow-hover.qml" << true; + QTest::newRow("ApplicationWindow:modeless") << "applicationwindow-hover.qml" << false; +} + +void tst_QQuickPopup::hover() +{ + QFETCH(QString, source); + QFETCH(bool, modal); + + QQuickControlsApplicationHelper helper(this, source); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup); + popup->setModal(modal); + + QQuickButton *parentButton = window->property("parentButton").value<QQuickButton*>(); + QVERIFY(parentButton); + parentButton->setHoverEnabled(true); + + QQuickButton *childButton = window->property("childButton").value<QQuickButton*>(); + QVERIFY(childButton); + childButton->setHoverEnabled(true); + + QSignalSpy openedSpy(popup, SIGNAL(opened())); + QVERIFY(openedSpy.isValid()); + popup->open(); + QVERIFY(openedSpy.count() == 1 || openedSpy.wait()); + QTRY_VERIFY(popup->width() > 10); // somehow this can take a short time with macOS style + + // hover the parent button outside the popup + QTest::mouseMove(window, QPoint(window->width() - 1, window->height() - 1)); + QCOMPARE(parentButton->isHovered(), !modal); + QVERIFY(!childButton->isHovered()); + + // hover the popup background + QTest::mouseMove(window, QPoint(1, 1)); + QVERIFY(!parentButton->isHovered()); + QVERIFY(!childButton->isHovered()); + + // hover the child button in a popup + QTest::mouseMove(window, QPoint(popup->x() + popup->width() / 2, popup->y() + popup->height() / 2)); + QVERIFY(!parentButton->isHovered()); + QVERIFY(childButton->isHovered()); + + QSignalSpy closedSpy(popup, SIGNAL(closed())); + QVERIFY(closedSpy.isValid()); + popup->close(); + QVERIFY(closedSpy.count() == 1 || closedSpy.wait()); + + // hover the parent button after closing the popup + QTest::mouseMove(window, QPoint(window->width() / 2, window->height() / 2)); + QVERIFY(parentButton->isHovered()); +} + +void tst_QQuickPopup::wheel_data() +{ + QTest::addColumn<QString>("source"); + QTest::addColumn<bool>("modal"); + + QTest::newRow("Window:modal") << "window-wheel.qml" << true; + QTest::newRow("Window:modeless") << "window-wheel.qml" << false; + QTest::newRow("ApplicationWindow:modal") << "applicationwindow-wheel.qml" << true; + QTest::newRow("ApplicationWindow:modeless") << "applicationwindow-wheel.qml" << false; +} + +static bool sendWheelEvent(QQuickItem *item, const QPoint &localPos, int degrees) +{ + QQuickWindow *window = item->window(); + QWheelEvent wheelEvent(localPos, item->window()->mapToGlobal(localPos), QPoint(0, 0), + QPoint(0, 8 * degrees), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, + false); + QSpontaneKeyEvent::setSpontaneous(&wheelEvent); + return qGuiApp->notify(window, &wheelEvent); +} + +void tst_QQuickPopup::wheel() +{ + QFETCH(QString, source); + QFETCH(bool, modal); + + QQuickControlsApplicationHelper helper(this, source); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickSlider *contentSlider = window->property("contentSlider").value<QQuickSlider*>(); + QVERIFY(contentSlider); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup && popup->contentItem()); + popup->setModal(modal); + + QQuickPopup *nestedPopup = window->property("nestedPopup").value<QQuickPopup*>(); + QVERIFY(nestedPopup && nestedPopup->contentItem()); + nestedPopup->setModal(modal); + + QQuickSlider *popupSlider = window->property("popupSlider").value<QQuickSlider*>(); + QVERIFY(popupSlider); + + { + // wheel over the content + qreal oldContentValue = contentSlider->value(); + qreal oldPopupValue = popupSlider->value(); + + QVERIFY(sendWheelEvent(contentSlider, QPoint(contentSlider->width() / 2, contentSlider->height() / 2), 15)); + + QVERIFY(!qFuzzyCompare(contentSlider->value(), oldContentValue)); // must have moved + QVERIFY(qFuzzyCompare(popupSlider->value(), oldPopupValue)); // must not have moved + } + + QSignalSpy openedSpy(popup, SIGNAL(opened())); + QVERIFY(openedSpy.isValid()); + popup->open(); + QVERIFY(openedSpy.count() == 1 || openedSpy.wait()); + + { + // wheel over the popup content + qreal oldContentValue = contentSlider->value(); + qreal oldPopupValue = popupSlider->value(); + + QVERIFY(sendWheelEvent(popupSlider, QPoint(popupSlider->width() / 2, popupSlider->height() / 2), 15)); + + QVERIFY(qFuzzyCompare(contentSlider->value(), oldContentValue)); // must not have moved + QVERIFY(!qFuzzyCompare(popupSlider->value(), oldPopupValue)); // must have moved + } + + QSignalSpy nestedOpenedSpy(nestedPopup, SIGNAL(opened())); + QVERIFY(nestedOpenedSpy.isValid()); + nestedPopup->open(); + QVERIFY(nestedOpenedSpy.size() == 1 || nestedOpenedSpy.wait()); + + { + // wheel over the popup content + qreal oldContentValue = contentSlider->value(); + qreal oldPopupValue = popupSlider->value(); + + QVERIFY(sendWheelEvent(popupSlider, QPoint(popupSlider->width() / 2, popupSlider->height() / 2), 15)); + + QVERIFY(qFuzzyCompare(contentSlider->value(), oldContentValue)); // must not have moved + QCOMPARE(qFuzzyCompare(popupSlider->value(), oldPopupValue), modal); // must not have moved unless modeless + } + + { + // wheel over the overlay + qreal oldContentValue = contentSlider->value(); + qreal oldPopupValue = popupSlider->value(); + + QVERIFY(sendWheelEvent(QQuickOverlay::overlay(window), QPoint(0, 0), 15)); + + if (modal) { + // the content below a modal overlay must not move + QVERIFY(qFuzzyCompare(contentSlider->value(), oldContentValue)); + } else { + // the content below a modeless overlay must move + QVERIFY(!qFuzzyCompare(contentSlider->value(), oldContentValue)); + } + QVERIFY(qFuzzyCompare(popupSlider->value(), oldPopupValue)); // must not have moved + } +} + +void tst_QQuickPopup::parentDestroyed() +{ + QQuickPopup popup; + popup.setParentItem(new QQuickItem); + delete popup.parentItem(); + QVERIFY(!popup.parentItem()); +} + +void tst_QQuickPopup::nested() +{ + QQuickControlsApplicationHelper helper(this, QStringLiteral("nested.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *modalPopup = window->property("modalPopup").value<QQuickPopup *>(); + QVERIFY(modalPopup); + + QQuickPopup *modelessPopup = window->property("modelessPopup").value<QQuickPopup *>(); + QVERIFY(modelessPopup); + + modalPopup->open(); + QCOMPARE(modalPopup->isVisible(), true); + + modelessPopup->open(); + QCOMPARE(modelessPopup->isVisible(), true); + + // click outside the modeless popup on the top, but inside the modal popup below + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(150, 150)); + + QTRY_COMPARE(modelessPopup->isVisible(), false); + QCOMPARE(modalPopup->isVisible(), true); +} + +void tst_QQuickPopup::modelessOnModalOnModeless() +{ + QQuickControlsApplicationHelper helper(this, QStringLiteral("modelessOnModalOnModeless.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *modelessPopup = window->property("modelessPopup").value<QQuickPopup *>(); + QVERIFY(modelessPopup); + + QQuickButton *button = window->property("button").value<QQuickButton *>(); + QVERIFY(button); + QQuickPopup *modalPopup = window->property("modalPopup").value<QQuickPopup *>(); + QVERIFY(modalPopup); + QQuickPopup *tooltip = window->property("tooltip").value<QQuickPopup *>(); + QVERIFY(modalPopup); + + modelessPopup->open(); + QCOMPARE(modelessPopup->isVisible(), true); + QTRY_COMPARE(modelessPopup->isOpened(), true); + + const auto buttonPoint = button->mapToScene(button->boundingRect().center()).toPoint(); + // click into the button, should not be blocked + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, buttonPoint); + QVERIFY(button->isChecked()); + + modalPopup->open(); + QCOMPARE(modalPopup->isVisible(), true); + QTRY_COMPARE(modalPopup->isOpened(), true); + // click into the button, should be blocked + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, buttonPoint); + QVERIFY(button->isChecked()); + + tooltip->setVisible(true); + QCOMPARE(tooltip->isVisible(), true); + QTRY_COMPARE(tooltip->isOpened(), true); + // click into the button, should be blocked + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, buttonPoint); + QVERIFY(button->isChecked()); +} + +// QTBUG-56697 +void tst_QQuickPopup::grabber() +{ + QQuickControlsApplicationHelper helper(this, QStringLiteral("grabber.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *menu = window->property("menu").value<QQuickPopup *>(); + QVERIFY(menu); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup *>(); + QVERIFY(popup); + + QQuickPopup *combo = window->property("combo").value<QQuickPopup *>(); + QVERIFY(combo); + + menu->open(); + QTRY_COMPARE(menu->isOpened(), true); + QCOMPARE(popup->isVisible(), false); + QCOMPARE(combo->isVisible(), false); + + // click a menu item to open the popup + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(menu->x() + menu->width() / 2, menu->y() + menu->height() / 2)); + QTRY_COMPARE(menu->isVisible(), false); + QTRY_COMPARE(popup->isOpened(), true); + QCOMPARE(combo->isVisible(), false); + + combo->open(); + QCOMPARE(menu->isVisible(), false); + QCOMPARE(popup->isVisible(), true); + QTRY_COMPARE(combo->isOpened(), true); + + // click outside to close both the combo popup and the parent popup + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - 1, window->height() - 1)); + QCOMPARE(menu->isVisible(), false); + QTRY_COMPARE(popup->isVisible(), false); + QTRY_COMPARE(combo->isVisible(), false); + + menu->open(); + QTRY_COMPARE(menu->isOpened(), true); + QCOMPARE(popup->isVisible(), false); + QCOMPARE(combo->isVisible(), false); + + // click outside the menu to close it (QTBUG-56697) + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() - 1, window->height() - 1)); + QTRY_COMPARE(menu->isVisible(), false); + QCOMPARE(popup->isVisible(), false); + QCOMPARE(combo->isVisible(), false); +} + +void tst_QQuickPopup::cursorShape() +{ + // Ensure that the mouse cursor has the correct shape when over a popup + // which is itself over an item with a different shape. + QQuickControlsApplicationHelper helper(this, QStringLiteral("cursor.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *popup = helper.appWindow->property("popup").value<QQuickPopup*>(); + QVERIFY(popup); + + popup->open(); + QVERIFY(popup->isVisible()); + QTRY_VERIFY(popup->isOpened()); + + QQuickItem *textField = helper.appWindow->property("textField").value<QQuickItem*>(); + QVERIFY(textField); + + // Move the mouse over the text field. + const QPoint textFieldPos(popup->x() - 1, textField->height() / 2); + QVERIFY(textField->contains(textField->mapFromScene(textFieldPos))); + QTest::mouseMove(window, textFieldPos); + QCOMPARE(window->cursor().shape(), textField->cursor().shape()); + + // Move the mouse over the popup where it overlaps with the text field. + const QPoint textFieldOverlapPos(popup->x() + 1, textField->height() / 2); + QTest::mouseMove(window, textFieldOverlapPos); + QCOMPARE(window->cursor().shape(), popup->popupItem()->cursor().shape()); + + popup->close(); + QTRY_VERIFY(!popup->isVisible()); +} + +class FriendlyPopup : public QQuickPopup +{ + friend class tst_QQuickPopup; +}; + +void tst_QQuickPopup::componentComplete() +{ + FriendlyPopup cppPopup; + QVERIFY(cppPopup.isComponentComplete()); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import QtQuick.Controls; Popup { }", QUrl()); + + FriendlyPopup *qmlPopup = static_cast<FriendlyPopup *>(component.beginCreate(engine.rootContext())); + QVERIFY(qmlPopup); + QVERIFY(!qmlPopup->isComponentComplete()); + + component.completeCreate(); + QVERIFY(qmlPopup->isComponentComplete()); +} + +void tst_QQuickPopup::closeOnEscapeWithNestedPopups() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + // Tests the scenario in the Gallery example, where there are nested popups that should + // close in the correct order when the Escape key is pressed. + QQuickControlsApplicationHelper helper(this, QStringLiteral("closeOnEscapeWithNestedPopups.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + // The stack view should have two items, and it should pop the second when escape is pressed + // and it has focus. + QQuickStackView *stackView = window->findChild<QQuickStackView*>("stackView"); + QVERIFY(stackView); + QCOMPARE(stackView->depth(), 2); + + QQuickItem *optionsToolButton = window->findChild<QQuickItem*>("optionsToolButton"); + QVERIFY(optionsToolButton); + + // Click on the options tool button. The settings menu should pop up. + const QPoint optionsToolButtonCenter = optionsToolButton->mapToScene( + QPointF(optionsToolButton->width() / 2, optionsToolButton->height() / 2)).toPoint(); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, optionsToolButtonCenter); + + QQuickPopup *optionsMenu = window->findChild<QQuickPopup*>("optionsMenu"); + QVERIFY(optionsMenu); + QTRY_VERIFY(optionsMenu->isVisible()); + + QQuickItem *settingsMenuItem = window->findChild<QQuickItem*>("settingsMenuItem"); + QVERIFY(settingsMenuItem); + + // Click on the settings menu item. The settings dialog should pop up. + const QPoint settingsMenuItemCenter = settingsMenuItem->mapToScene( + QPointF(settingsMenuItem->width() / 2, settingsMenuItem->height() / 2)).toPoint(); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, settingsMenuItemCenter); + + QQuickPopup *settingsDialog = window->contentItem()->findChild<QQuickPopup*>("settingsDialog"); + QVERIFY(settingsDialog); + QTRY_VERIFY(!optionsMenu->isVisible()); + QTRY_VERIFY(settingsDialog->isVisible()); + + QQuickComboBox *comboBox = window->contentItem()->findChild<QQuickComboBox*>("comboBox"); + QVERIFY(comboBox); + + // Click on the combo box button. The combo box popup should pop up. + const QPoint comboBoxCenter = comboBox->mapToScene( + QPointF(comboBox->width() / 2, comboBox->height() / 2)).toPoint(); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, comboBoxCenter); + QTRY_VERIFY(comboBox->popup()->isVisible()); + + // Close the combo box popup with the escape key. The settings dialog should still be visible. + QTest::keyClick(window, Qt::Key_Escape); + QTRY_VERIFY(!comboBox->popup()->isVisible()); + QVERIFY(settingsDialog->isVisible()); + + // Close the settings dialog with the escape key. + QTest::keyClick(window, Qt::Key_Escape); + QTRY_VERIFY(!settingsDialog->isVisible()); + + // The stack view should still have two items. + QCOMPARE(stackView->depth(), 2); + + // Remove one by pressing the Escape key (the Shortcut should be activated). + QTest::keyClick(window, Qt::Key_Escape); + QCOMPARE(stackView->depth(), 1); +} + +void tst_QQuickPopup::closeOnEscapeWithVisiblePopup() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + QQuickControlsApplicationHelper helper(this, QStringLiteral("closeOnEscapeWithVisiblePopup.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickPopup *popup = window->findChild<QQuickPopup *>("popup"); + QVERIFY(popup); + QTRY_VERIFY(popup->isOpened()); + + QTRY_VERIFY(window->activeFocusItem()); + QTest::keyClick(window, Qt::Key_Escape); + QTRY_VERIFY(!popup->isVisible()); +} + +void tst_QQuickPopup::enabled() +{ + QQuickPopup popup; + QVERIFY(popup.isEnabled()); + QVERIFY(popup.popupItem()->isEnabled()); + + QSignalSpy enabledSpy(&popup, &QQuickPopup::enabledChanged); + QVERIFY(enabledSpy.isValid()); + + popup.setEnabled(false); + QVERIFY(!popup.isEnabled()); + QVERIFY(!popup.popupItem()->isEnabled()); + QCOMPARE(enabledSpy.count(), 1); + + popup.popupItem()->setEnabled(true); + QVERIFY(popup.isEnabled()); + QVERIFY(popup.popupItem()->isEnabled()); + QCOMPARE(enabledSpy.count(), 2); +} + +void tst_QQuickPopup::orientation_data() +{ + QTest::addColumn<Qt::ScreenOrientation>("orientation"); + QTest::addColumn<QPointF>("position"); + + // On Android the screen size will usually be smaller than the 600x300 + // size of a Window in orientation.qml + // Because of that we need to calculate proper positions at runtime. +#ifndef Q_OS_ANDROID + QQuickControlsApplicationHelper helper(this, "orientation.qml"); + const QSize availableSize = helper.window->size(); +#else + const QSize availableSize = QGuiApplication::primaryScreen()->availableSize(); +#endif + const int width = availableSize.width(); + const int height = availableSize.height(); + + // The width & height might be odd numbers, so we calculate center in a way + // similar to anchors.centerIn. + // Also note that when we emulate the screen orientation change (by calling + // window->reportContentOrientationChange() in the test), these values need + // to be adjusted, because the "logical" (0, 0) of the screen changes. + const int widthCenter = (width % 2) ? (width + 1) / 2 : width / 2; + const int heightCenter = (height % 2) ? (height + 1) / 2 : height / 2; + + // Rectangle is (60x30); popup is (30x60). + // Rectangle is using "anchors.centerIn: parent", and popup is positioned at + // (rectangle.width, rectangle.height) + QTest::newRow("Portrait") << Qt::PortraitOrientation + << QPointF(widthCenter - 30 + 60, heightCenter - 15 + 30); + // in landscape orientation the top left corner of physical screen + // (not rotated) becomes (0, 0), so we need to adjust our widthCenter + QTest::newRow("Landscape") << Qt::LandscapeOrientation + << QPointF(heightCenter - 15 + 30, (width - widthCenter) + 30 - 60); + // In inverted portrait orientation the bottom right corner of physical + // screen (not rotated) becomes (0, 0), so we need to adjust both + // widthCenter and heightCenter + QTest::newRow("InvertedPortrait") << Qt::InvertedPortraitOrientation + << QPointF((width - widthCenter) + 30 - 60, (height - heightCenter) + 15 - 30); + // In inverted landscape orientation the bottom right corner of physical + // screen (not rotated) becomes (0, 0), so we need to adjust heightCenter + QTest::newRow("InvertedLandscape") << Qt::InvertedLandscapeOrientation + << QPointF((height - heightCenter) + 15 - 30, widthCenter - 30 + 60); +} + +void tst_QQuickPopup::orientation() +{ + QFETCH(Qt::ScreenOrientation, orientation); + QFETCH(QPointF, position); + + QQuickControlsApplicationHelper helper(this, "orientation.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->reportContentOrientationChange(orientation); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup); + popup->open(); + + QCOMPARE(popup->popupItem()->position(), position); +} + +void tst_QQuickPopup::qquickview() +{ + QQuickView view; + view.setObjectName("QQuickView"); + view.resize(400, 400); + view.setSource(testFileUrl("dialog.qml")); + QVERIFY(view.status() != QQuickView::Error); + view.contentItem()->setObjectName("QQuickViewContentItem"); + view.show(); + + QQuickDialog *dialog = view.rootObject()->property("dialog").value<QQuickDialog*>(); + QVERIFY(dialog); + QTRY_COMPARE(dialog->property("opened").toBool(), true); + + dialog->close(); + QTRY_COMPARE(dialog->property("visible").toBool(), false); + + // QTBUG-72746: shouldn't crash on application exit after closing a Dialog when using QQuickView. +} + +// TODO: also test it out without setting enabled directly on menu, but on a parent + +// QTBUG-73447 +void tst_QQuickPopup::disabledPalette() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + QQuickControlsApplicationHelper helper(this, "disabledPalette.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup); + + QSignalSpy popupEnabledSpy(popup, &QQuickPopup::enabledChanged); + QVERIFY(popupEnabledSpy.isValid()); + QSignalSpy popupPaletteSpy(popup, &QQuickPopup::paletteChanged); + QVERIFY(popupPaletteSpy.isValid()); + + QSignalSpy popupItemEnabledSpy(popup->popupItem(), &QQuickItem::enabledChanged); + QVERIFY(popupItemEnabledSpy.isValid()); + QSignalSpy popupItemPaletteSpy(popup->popupItem(), &QQuickItem::paletteChanged); + QVERIFY(popupItemPaletteSpy.isValid()); + + auto palette = QQuickPopupPrivate::get(popup)->palette(); + palette->setBase(Qt::green); + palette->disabled()->setBase(Qt::red); + QCOMPARE(popupPaletteSpy.count(), 2); + QCOMPARE(popupItemPaletteSpy.count(), 2); + QCOMPARE(popup->background()->property("color").value<QColor>(), Qt::green); + + popup->setEnabled(false); + QCOMPARE(popupEnabledSpy.count(), 1); + QCOMPARE(popupItemEnabledSpy.count(), 1); + QCOMPARE(popupPaletteSpy.count(), 3); + QCOMPARE(popupItemPaletteSpy.count(), 3); + QCOMPARE(popup->background()->property("color").value<QColor>(), Qt::red); +} + +void tst_QQuickPopup::disabledParentPalette() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + QQuickControlsApplicationHelper helper(this, "disabledPalette.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup); + + QSignalSpy popupEnabledSpy(popup, SIGNAL(enabledChanged())); + QVERIFY(popupEnabledSpy.isValid()); + QSignalSpy popupPaletteSpy(popup, SIGNAL(paletteChanged())); + QVERIFY(popupPaletteSpy.isValid()); + + QSignalSpy popupItemEnabledSpy(popup->popupItem(), SIGNAL(enabledChanged())); + QVERIFY(popupItemEnabledSpy.isValid()); + QSignalSpy popupItemPaletteSpy(popup->popupItem(), SIGNAL(paletteChanged())); + QVERIFY(popupItemPaletteSpy.isValid()); + + auto palette = QQuickPopupPrivate::get(popup)->palette(); + palette->setBase(Qt::green); + palette->disabled()->setBase(Qt::red); + QCOMPARE(popupPaletteSpy.count(), 2); + QCOMPARE(popupItemPaletteSpy.count(), 2); + QCOMPARE(popup->background()->property("color").value<QColor>(), Qt::green); + + // Disable the overlay (which is QQuickPopupItem's parent) to ensure that + // the palette is changed when the popup is indirectly disabled. + popup->open(); + QTRY_VERIFY(popup->isOpened()); + QVERIFY(QMetaObject::invokeMethod(window, "disableOverlay")); + QVERIFY(!popup->isEnabled()); + QVERIFY(!popup->popupItem()->isEnabled()); + QCOMPARE(popup->background()->property("color").value<QColor>(), Qt::red); + QCOMPARE(popupEnabledSpy.count(), 1); + QCOMPARE(popupItemEnabledSpy.count(), 1); + QCOMPARE(popupPaletteSpy.count(), 3); + QCOMPARE(popupItemPaletteSpy.count(), 3); + + popup->close(); + QTRY_VERIFY(!popup->isVisible()); +} + +void tst_QQuickPopup::countChanged() +{ + QQuickControlsApplicationHelper helper(this, "countChanged.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickComboBox *comboBox = window->property("comboBox").value<QQuickComboBox*>(); + QVERIFY(comboBox); + QCOMPARE(window->property("count").toInt(), 1); + + QVERIFY(window->setProperty("isModel1", false)); + QTRY_COMPARE(window->property("count").toInt(), 2); +} + +// QTBUG-73243 +void tst_QQuickPopup::toolTipCrashOnClose() +{ + if (!canImportModule("import QtGraphicalEffects; DropShadow {}")) + QSKIP("Test requires QtGraphicalEffects"); + + QQuickControlsApplicationHelper helper(this, "toolTipCrashOnClose.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QTest::mouseMove(window, QPoint(window->width() / 2, window->height() / 2)); + QTRY_VERIFY(window->property("toolTipOpened").toBool()); + + QVERIFY(window->close()); + // Shouldn't crash. +} + +void tst_QQuickPopup::setOverlayParentToNull() +{ + if (!canImportModule("import QtGraphicalEffects; DropShadow {}")) + QSKIP("Test requires QtGraphicalEffects"); + + QQuickControlsApplicationHelper helper(this, "toolTipCrashOnClose.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QVERIFY(QMetaObject::invokeMethod(window, "nullifyOverlayParent")); + + QTest::mouseMove(window, QPoint(window->width() / 2, window->height() / 2)); + QTRY_VERIFY(window->property("toolTipOpened").toBool()); + + QVERIFY(window->close()); + // While nullifying the overlay parent doesn't make much sense, it shouldn't crash. +} + +void tst_QQuickPopup::tabFence() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls) + QSKIP("This platform only allows tab focus for text controls"); + + QQuickControlsApplicationHelper helper(this, "tabFence.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickPopup *popup = window->property("dialog").value<QQuickPopup*>(); + QVERIFY(popup); + popup->open(); + popup->setModal(true); + + QQuickButton *outsideButton1 = window->property("outsideButton1").value<QQuickButton*>(); + QVERIFY(outsideButton1); + QQuickButton *outsideButton2 = window->property("outsideButton2").value<QQuickButton*>(); + QVERIFY(outsideButton2); + QQuickButton *dialogButton1 = window->property("dialogButton1").value<QQuickButton*>(); + QVERIFY(dialogButton1); + QQuickButton *dialogButton2 = window->property("dialogButton2").value<QQuickButton*>(); + QVERIFY(dialogButton2); + + // When modal, focus loops between the two external buttons + outsideButton1->forceActiveFocus(); + QVERIFY(outsideButton1->hasActiveFocus()); + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(outsideButton2->hasActiveFocus()); + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(outsideButton1->hasActiveFocus()); + + // Same thing for dialog's buttons + dialogButton1->forceActiveFocus(); + QVERIFY(dialogButton1->hasActiveFocus()); + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(dialogButton2->hasActiveFocus()); + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(dialogButton1->hasActiveFocus()); + + popup->setModal(false); + + // When not modal, focus goes in and out of the dialog + outsideButton1->forceActiveFocus(); + QVERIFY(outsideButton1->hasActiveFocus()); + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(outsideButton2->hasActiveFocus()); + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(dialogButton1->hasActiveFocus()); + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(dialogButton2->hasActiveFocus()); + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(outsideButton1->hasActiveFocus()); +} + +void tst_QQuickPopup::invisibleToolTipOpen() +{ + QQuickControlsApplicationHelper helper(this, "invisibleToolTipOpen.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + centerOnScreen(window); + moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickItem *mouseArea = qvariant_cast<QQuickItem *>(window->property("mouseArea")); + QVERIFY(mouseArea); + QObject *loader = qvariant_cast<QObject *>(window->property("loader")); + QVERIFY(loader); + + // Send an extra move event, otherwise the test fails on subsequent runs for different styles for some reason... + // As an added bonus, this is also slightly more realistic. :D + QTest::mouseMove(window, QPoint(mouseArea->width() / 2 - 1, mouseArea->height() / 2 - 1)); + QTest::mouseMove(window, QPoint(mouseArea->width() / 2, mouseArea->height() / 2)); + QTRY_VERIFY(mouseArea->property("isToolTipVisible").toBool()); + + QSignalSpy componentLoadedSpy(loader, SIGNAL(loaded())); + QVERIFY(componentLoadedSpy.isValid()); + + loader->setProperty("active", true); + QTRY_COMPARE(componentLoadedSpy.count(), 1); + + QTRY_VERIFY(mouseArea->property("isToolTipVisible").toBool()); +} + +void tst_QQuickPopup::centerInOverlayWithinStackViewItem() +{ + QQuickControlsApplicationHelper helper(this, "centerInOverlayWithinStackViewItem.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup); + QTRY_COMPARE(popup->isVisible(), true); + + // Shouldn't crash on exit. +} + +void tst_QQuickPopup::destroyDuringExitTransition() +{ + if (!hasWindowActivation()) + QSKIP("Window activation is not supported"); + + QQuickControlsApplicationHelper helper(this, "destroyDuringExitTransition.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QPointer<QQuickPopup> dialog2 = window->property("dialog2").value<QQuickPopup*>(); + QVERIFY(dialog2); + QTRY_COMPARE(dialog2->isVisible(), true); + + // Close the second dialog, destroying it before its exit transition can finish. + QTest::keyClick(window, Qt::Key_Escape); + QTRY_VERIFY(!dialog2); + + // Events should go through to the dialog underneath. + QQuickPopup *dialog1 = window->property("dialog1").value<QQuickPopup*>(); + QVERIFY(dialog1); + QQuickButton *button = dialog1->property("button").value<QQuickButton*>(); + QVERIFY(button); + const auto buttonClickPos = button->mapToScene(QPointF(button->width() / 2, button->height() / 2)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, buttonClickPos); + QVERIFY(button->isDown()); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, buttonClickPos); + QVERIFY(!button->isDown()); +} + +void tst_QQuickPopup::releaseAfterExitTransition() +{ + QQuickApplicationHelper helper(this, "releaseAfterExitTransition.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + QQuickPopup *modalPopup = window->property("modalPopup").value<QQuickPopup *>(); + QQuickPopup *popup = window->property("popup").value<QQuickPopup *>(); + + modalPopup->open(); + QTRY_VERIFY(modalPopup->isOpened()); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + // wait until the transition is finished and the overlay hides itself + QTRY_VERIFY(!overlay->isVisible()); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + + popup->open(); + QTRY_VERIFY(popup->isOpened()); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QTRY_VERIFY(!popup->isOpened()); +} + +class ContainmentMask : public QObject +{ + Q_OBJECT +public: + mutable bool called = false; + Q_INVOKABLE bool contains(const QPointF &point) const + { + called = true; + // let clicks at {1, 1} through the dimmer + return point != QPoint(1, 1); + } +}; + +/* + Test case for behavior we rely on in the virtual keyboard: + To prevent the virtual keyboard from being blocked by modal popups, + it sets a containment mask on the dimmer item, and lets clicks through + that hit the virtual keyboard. +*/ +void tst_QQuickPopup::dimmerContainmentMask() +{ + ContainmentMask containmentMask; + int expectedClickCount = 0; + + QQuickApplicationHelper helper(this, "dimmerContainmentMask.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QCOMPARE(window->property("clickCount").toInt(), expectedClickCount); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + QQuickPopup *modalPopup = window->property("modalPopup").value<QQuickPopup *>(); + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QCOMPARE(window->property("clickCount"), ++expectedClickCount); + + modalPopup->open(); + QTRY_VERIFY(modalPopup->isOpened()); + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QCOMPARE(window->property("clickCount"), expectedClickCount); // blocked by modal + QTRY_VERIFY(!modalPopup->isOpened()); // auto-close + + modalPopup->open(); + QTRY_VERIFY(modalPopup->isOpened()); + + QPointer<QQuickItem> dimmer = overlay->property("_q_dimmerItem").value<QQuickItem *>(); + QVERIFY(dimmer); + dimmer->setContainmentMask(&containmentMask); + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QVERIFY(containmentMask.called); + QCOMPARE(window->property("clickCount"), ++expectedClickCount); // let through by containment mask + QVERIFY(modalPopup->isOpened()); // no auto-close + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(2, 2)); + QCOMPARE(window->property("clickCount"), expectedClickCount); // blocked by modal + QTRY_VERIFY(!modalPopup->isOpened()); // auto-close + QTRY_VERIFY(!dimmer); + + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1)); + QCOMPARE(window->property("clickCount"), ++expectedClickCount); // no mask left behind + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(2, 2)); + QCOMPARE(window->property("clickCount"), ++expectedClickCount); // no mask left behind +} + +void tst_QQuickPopup::shrinkPopupThatWasLargerThanWindow_data() +{ + QTest::addColumn<QString>("fileName"); + + QTest::newRow("vertical") << "shrinkPopupThatWasLargerThanWindowHeight.qml"; + QTest::newRow("horizontal") << "shrinkPopupThatWasLargerThanWindowWidth.qml"; +} + +void tst_QQuickPopup::shrinkPopupThatWasLargerThanWindow() +{ + QFETCH(QString, fileName); + + QQuickApplicationHelper helper(this, fileName); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickPopup *popup = window->property("popup").value<QQuickPopup*>(); + QVERIFY(popup); + + popup->open(); + QTRY_VERIFY(popup->isOpened()); + + // Shrink the popup by reducing the model count. + QVERIFY(window->setProperty("model", 1)); + + QVERIFY2(popup->implicitWidth() < window->width(), qPrintable(QString::fromLatin1( + "Expected popup's implicitWidth (%1) to be less than the window's width (%2)") + .arg(popup->implicitWidth()).arg(window->width()))); + QVERIFY2(popup->width() < window->width(), qPrintable(QString::fromLatin1( + "Expected popup's width (%1) to be less than the window's width (%2)") + .arg(popup->width()).arg(window->width()))); + + QVERIFY2(popup->implicitHeight() < window->height(), qPrintable(QString::fromLatin1( + "Expected popup's implicitHeight (%1) to be less than the window's height (%2)") + .arg(popup->implicitHeight()).arg(window->height()))); + QVERIFY2(popup->height() < window->height(), qPrintable(QString::fromLatin1( + "Expected popup's height (%1) to be less than the window's height (%2)") + .arg(popup->height()).arg(window->height()))); +} + +void tst_QQuickPopup::mirroredCombobox() +{ +#ifdef Q_OS_ANDROID + // Android screens might be pretty small, such that additional + // repositioning (apart from the mirroring) will happen to the + // popups and mess up the expected positions below. + QSKIP("Skipping test for Android."); +#endif + QStringList nativeStyles; + nativeStyles.append("macOS"); + nativeStyles.append("iOS"); + nativeStyles.append("Windows"); + if (nativeStyles.contains(QQuickStyle::name())) + QSKIP("Skipping test for native styles: they might rearrange their combobox the way they " + "want."); + + QQuickControlsApplicationHelper helper(this, "mirroredCombobox.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + { + QQuickComboBox *comboBox = window->findChild<QQuickComboBox *>("first"); + QVERIFY(comboBox); + QQuickPopup *popup = comboBox->popup(); + QVERIFY(popup); + popup->open(); + QTRY_COMPARE(popup->isVisible(), true); + const QPointF popupPos(popup->contentItem()->mapToItem(comboBox->parentItem(), + popup->contentItem()->position())); + const QSizeF popupSize(popup->contentItem()->size()); + + // ignore popup.{top,bottom}Padding() as not included in popup->contentItem()->size() + // some styles prefer to draw the popup "over" (in z-axis direction) the combobox to hide + // the combobox + const bool styleDrawsPopupOverCombobox = + comboBox->position().y() - popupSize.height() + comboBox->size().height() + == popupPos.y(); + // some styles prefer to draw the popup below (in y-axis direction) the combobox + const bool styleDrawsPopupBelowCombobox = + comboBox->position().y() - popupSize.height() + comboBox->topPadding() + == popupPos.y(); + + QVERIFY(styleDrawsPopupOverCombobox || styleDrawsPopupBelowCombobox); + + popup->close(); + } + + { + QQuickComboBox *comboBox = window->findChild<QQuickComboBox *>("second"); + QVERIFY(comboBox); + QQuickPopup *popup = comboBox->popup(); + QVERIFY(popup); + popup->open(); + QTRY_COMPARE(popup->isVisible(), true); + const QPointF popupPos(popup->contentItem()->mapToItem(comboBox->parentItem(), + popup->contentItem()->position())); + + // some styles prefer to draw the popup "over" (in z-axis direction) the combobox to hide + // the combobox + const bool styleDrawsPopupOverCombobox = comboBox->position().y() + comboBox->topPadding() + + popup->topPadding() + popup->bottomPadding() + == popupPos.y(); + // some styles prefer to draw the popup above (in y-axis direction) the combobox + const bool styleDrawsPopupAboveCombobox = + comboBox->position().y() + comboBox->height() - comboBox->topPadding() + == popupPos.y(); + + QVERIFY(styleDrawsPopupOverCombobox || styleDrawsPopupAboveCombobox); + + popup->close(); + } +} + +void tst_QQuickPopup::rotatedCombobox() +{ +#ifdef Q_OS_ANDROID + // Android screens might be pretty small, such that additional + // repositioning (apart from the rotating) will happen to the + // popups and mess up the expected positions below. + QSKIP("Skipping test for Android."); +#endif + QStringList nativeStyles; + nativeStyles.append("macOS"); + nativeStyles.append("iOS"); + nativeStyles.append("Windows"); + if (nativeStyles.contains(QQuickStyle::name())) + QSKIP("Skipping test for native styles: they might rearrange their combobox the way they " + "want."); + + QQuickControlsApplicationHelper helper(this, "rotatedCombobox.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + { + QQuickComboBox *comboBox = window->findChild<QQuickComboBox *>("first"); + QVERIFY(comboBox); + QQuickPopup *popup = comboBox->popup(); + QVERIFY(popup); + popup->open(); + QTRY_COMPARE(popup->isVisible(), true); + const QPointF popupPos(popup->contentItem()->mapToItem(comboBox->parentItem(), + popup->contentItem()->position())); + const QSizeF popupSize(popup->contentItem()->size()); + + // ignore popup.{left,right}Padding() as not included in popup->contentItem()->size() + // some styles prefer to draw the popup "over" (in z-axis direction) the combobox to hide + // the combobox + const bool styleDrawsPopupOverCombobox = + comboBox->position().x() - popupSize.width() + comboBox->width() == popupPos.x(); + // some styles prefer to draw the popup right (in x-axis direction) of the combobox + const bool styleDrawsPopupBelowCombobox = + comboBox->position().x() - popupSize.width() - comboBox->leftPadding() + == popupPos.x(); + + QVERIFY(styleDrawsPopupOverCombobox || styleDrawsPopupBelowCombobox); + } + + { + QQuickComboBox *comboBox = window->findChild<QQuickComboBox *>("second"); + QVERIFY(comboBox); + QQuickPopup *popup = comboBox->popup(); + QVERIFY(popup); + popup->open(); + QTRY_COMPARE(popup->isVisible(), true); + const QPointF popupPos(popup->contentItem()->mapToItem(comboBox->parentItem(), + popup->contentItem()->position())); + + // some styles prefer to draw the popup "over" (in z-axis direction) the combobox to hide + // the combobox + const bool styleDrawsPopupOverCombobox = comboBox->position().x() + comboBox->leftPadding() + + popup->leftPadding() + popup->rightPadding() + == popupPos.x(); + // some styles prefer to draw the popup left (in y-axis direction) of the combobox + const bool styleDrawsPopupAboveCombobox = + comboBox->position().x() + comboBox->width() - comboBox->leftPadding() + == popupPos.x(); + + QVERIFY(styleDrawsPopupOverCombobox || styleDrawsPopupAboveCombobox); + + popup->close(); + } +} + +QTEST_QUICKCONTROLS_MAIN(tst_QQuickPopup) + +#include "tst_qquickpopup.moc" diff --git a/tests/auto/quickcontrols2/qquickstyle/CMakeLists.txt b/tests/auto/quickcontrols2/qquickstyle/CMakeLists.txt new file mode 100644 index 00000000000..c39a9a04e62 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/CMakeLists.txt @@ -0,0 +1,62 @@ +# Generated from qquickstyle.pro. + +##################################################################### +## tst_qquickstyle Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickstyle + SOURCES + tst_qquickstyle.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +# Resources: +set(qmake_custom_resource_files + "data/Custom/Label.qml" + "data/Custom/qmldir" +) + +qt_internal_add_resource(tst_qquickstyle "qmake_custom" + PREFIX + "/" + FILES + ${qmake_custom_resource_files} +) + + +#### Keys ignored in scope 1:.:.:qquickstyle.pro:<TRUE>: +# OTHER_FILES = "data/CmdLineArgStyle/Control.qml" "data/CmdLineArgStyle/qmldir" "data/EnvVarStyle/Control.qml" "data/EnvVarStyle/qmldir" "data/EnvVarFallbackStyle/Control.qml" "data/EnvVarFallbackStyle/qmldir" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickstyle CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickstyle CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickstyle/data/CmdLineArgStyle/Control.qml b/tests/auto/quickcontrols2/qquickstyle/data/CmdLineArgStyle/Control.qml new file mode 100644 index 00000000000..744dcd8f089 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/CmdLineArgStyle/Control.qml @@ -0,0 +1,2 @@ +import QtQuick.Templates as T +T.Label {} diff --git a/tests/auto/quickcontrols2/qquickstyle/data/CmdLineArgStyle/qmldir b/tests/auto/quickcontrols2/qquickstyle/data/CmdLineArgStyle/qmldir new file mode 100644 index 00000000000..c2cc85c263a --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/CmdLineArgStyle/qmldir @@ -0,0 +1,2 @@ +module CmdLineArgStyle +Control 1.0 Control.qml diff --git a/tests/auto/quickcontrols2/qquickstyle/data/Custom/Label.qml b/tests/auto/quickcontrols2/qquickstyle/data/Custom/Label.qml new file mode 100644 index 00000000000..744dcd8f089 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/Custom/Label.qml @@ -0,0 +1,2 @@ +import QtQuick.Templates as T +T.Label {} diff --git a/tests/auto/quickcontrols2/qquickstyle/data/Custom/qmldir b/tests/auto/quickcontrols2/qquickstyle/data/Custom/qmldir new file mode 100644 index 00000000000..08de6fa8041 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/Custom/qmldir @@ -0,0 +1,2 @@ +module Custom +Label 1.0 Label.qml diff --git a/tests/auto/quickcontrols2/qquickstyle/data/EnvVarFallbackStyle/Control.qml b/tests/auto/quickcontrols2/qquickstyle/data/EnvVarFallbackStyle/Control.qml new file mode 100644 index 00000000000..744dcd8f089 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/EnvVarFallbackStyle/Control.qml @@ -0,0 +1,2 @@ +import QtQuick.Templates as T +T.Label {} diff --git a/tests/auto/quickcontrols2/qquickstyle/data/EnvVarFallbackStyle/qmldir b/tests/auto/quickcontrols2/qquickstyle/data/EnvVarFallbackStyle/qmldir new file mode 100644 index 00000000000..bebd8e07c6f --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/EnvVarFallbackStyle/qmldir @@ -0,0 +1,2 @@ +module EnvVarFallbackStyle +Control 1.0 Control.qml diff --git a/tests/auto/quickcontrols2/qquickstyle/data/EnvVarStyle/Control.qml b/tests/auto/quickcontrols2/qquickstyle/data/EnvVarStyle/Control.qml new file mode 100644 index 00000000000..744dcd8f089 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/EnvVarStyle/Control.qml @@ -0,0 +1,2 @@ +import QtQuick.Templates as T +T.Label {} diff --git a/tests/auto/quickcontrols2/qquickstyle/data/EnvVarStyle/qmldir b/tests/auto/quickcontrols2/qquickstyle/data/EnvVarStyle/qmldir new file mode 100644 index 00000000000..42223a19304 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/EnvVarStyle/qmldir @@ -0,0 +1,2 @@ +module EnvVarStyle +Control 1.0 Control.qml diff --git a/tests/auto/quickcontrols2/qquickstyle/data/basic.conf b/tests/auto/quickcontrols2/qquickstyle/data/basic.conf new file mode 100644 index 00000000000..17ef59ee027 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/basic.conf @@ -0,0 +1,6 @@ +[Controls] +Style=Basic + +[Basic] +Font\PixelSize=3 +Palette\WindowText=#ff0000 diff --git a/tests/auto/quickcontrols2/qquickstyle/data/custom.conf b/tests/auto/quickcontrols2/qquickstyle/data/custom.conf new file mode 100644 index 00000000000..ac79338ce55 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/custom.conf @@ -0,0 +1,6 @@ +[Controls] +Style=Custom + +[Custom] +Font\PixelSize=3 +Palette\WindowText=#ff0000 diff --git a/tests/auto/quickcontrols2/qquickstyle/data/dependencies.qml b/tests/auto/quickcontrols2/qquickstyle/data/dependencies.qml new file mode 100644 index 00000000000..280cfd29623 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/dependencies.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +Control { } diff --git a/tests/auto/quickcontrols2/qquickstyle/data/designer/ButtonSpecifics.qml b/tests/auto/quickcontrols2/qquickstyle/data/designer/ButtonSpecifics.qml new file mode 100644 index 00000000000..21226ed2a7f --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/designer/ButtonSpecifics.qml @@ -0,0 +1,3 @@ +import HelperWidgets + +ButtonSection { } diff --git a/tests/auto/quickcontrols2/qquickstyle/data/dummy.dSYM/empty b/tests/auto/quickcontrols2/qquickstyle/data/dummy.dSYM/empty new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/auto/quickcontrols2/qquickstyle/data/dummyStyles/DummyStyle/Button.qml b/tests/auto/quickcontrols2/qquickstyle/data/dummyStyles/DummyStyle/Button.qml new file mode 100644 index 00000000000..dcacc01140c --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/dummyStyles/DummyStyle/Button.qml @@ -0,0 +1,2 @@ +import QtQuick.Templates as T +T.Button { } diff --git a/tests/auto/quickcontrols2/qquickstyle/data/fusion.conf b/tests/auto/quickcontrols2/qquickstyle/data/fusion.conf new file mode 100644 index 00000000000..1f343e656fd --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/fusion.conf @@ -0,0 +1,6 @@ +[Controls] +Style=Fusion + +[Fusion] +Font\PixelSize=3 +Palette\WindowText=#ff0000 diff --git a/tests/auto/quickcontrols2/qquickstyle/data/imagine.conf b/tests/auto/quickcontrols2/qquickstyle/data/imagine.conf new file mode 100644 index 00000000000..919bbcf09e1 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/imagine.conf @@ -0,0 +1,6 @@ +[Controls] +Style=Imagine + +[Imagine] +Font\PixelSize=3 +Palette\WindowText=#ff0000 diff --git a/tests/auto/quickcontrols2/qquickstyle/data/material.conf b/tests/auto/quickcontrols2/qquickstyle/data/material.conf new file mode 100644 index 00000000000..27c7931a920 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/material.conf @@ -0,0 +1,6 @@ +[Controls] +Style=Material + +[Material] +Font\PixelSize=3 +Palette\WindowText=#ff0000 diff --git a/tests/auto/quickcontrols2/qquickstyle/data/universal.conf b/tests/auto/quickcontrols2/qquickstyle/data/universal.conf new file mode 100644 index 00000000000..a5ac3ca3f03 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/data/universal.conf @@ -0,0 +1,6 @@ +[Controls] +Style=Universal + +[Universal] +Font\PixelSize=3 +Palette\WindowText=#ff0000 diff --git a/tests/auto/quickcontrols2/qquickstyle/tst_qquickstyle.cpp b/tests/auto/quickcontrols2/qquickstyle/tst_qquickstyle.cpp new file mode 100644 index 00000000000..aeb37945ace --- /dev/null +++ b/tests/auto/quickcontrols2/qquickstyle/tst_qquickstyle.cpp @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickControls2/qquickstyle.h> +#include <QtQuickControls2/private/qquickstyle_p.h> +#include <QtQuickTemplates2/private/qquicklabel_p.h> +#include <QtQuickTemplates2/private/qquicklabel_p_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> +#include <QtGui/private/qguiapplication_p.h> + +class tst_QQuickStyle : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_QQuickStyle(); + +private slots: + void cleanup(); + void lookup(); + void configurationFile_data(); + void configurationFile(); + void commandLineArgument(); + void environmentVariables(); + +private: + Q_REQUIRED_RESULT bool loadControls(); + void unloadControls(); +}; + +tst_QQuickStyle::tst_QQuickStyle() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_QQuickStyle::cleanup() +{ + unloadControls(); + + QGuiApplicationPrivate::styleOverride.clear(); + qunsetenv("QT_QUICK_CONTROLS_STYLE"); + qunsetenv("QT_QUICK_CONTROLS_FALLBACK_STYLE"); + qunsetenv("QT_QUICK_CONTROLS_CONF"); +} + +bool tst_QQuickStyle::loadControls() +{ + QQmlEngine engine; + engine.addImportPath(dataDirectory()); + QQmlComponent component(&engine); + component.setData("import QtQuick; import QtQuick.Controls; Control { }", QUrl()); + + QScopedPointer<QObject> object(component.create()); + if (object.isNull()) { + qWarning() << component.errorString(); + return false; + } + return true; +} + +void tst_QQuickStyle::unloadControls() +{ + qmlClearTypeRegistrations(); +} + +void tst_QQuickStyle::lookup() +{ + QQuickStyle::setStyle("Material"); + QCOMPARE(QQuickStyle::name(), QString("Material")); + + QVERIFY(loadControls()); + + // The font size for editors in the (default) Normal variant is 16. + // If this is wrong, the style plugin may not have been loaded. + QCOMPARE(QQuickTheme::instance()->font(QQuickTheme::TextArea).pixelSize(), 16); + + QCOMPARE(QQuickStyle::name(), QString("Material")); +} + +void tst_QQuickStyle::configurationFile_data() +{ + QTest::addColumn<QString>("fileName"); + QTest::addColumn<QString>("expectedStyle"); + + QTest::newRow("Basic") << "basic.conf" << "Basic"; + QTest::newRow("Fusion") << "fusion.conf" << "Fusion"; + QTest::newRow("Imagine") << "imagine.conf" << "Imagine"; + QTest::newRow("Material") << "material.conf" << "Material"; + QTest::newRow("Universal") << "universal.conf" << "Universal"; + QTest::newRow("Custom") << "custom.conf" << "Custom"; +} + +void tst_QQuickStyle::configurationFile() +{ + QFETCH(QString, fileName); + QFETCH(QString, expectedStyle); + + qputenv("QT_QUICK_CONTROLS_CONF", testFile(fileName).toLocal8Bit()); + + // Load a control. The import causes the configuration file to be read. + QQmlEngine engine; + engine.addImportPath(":/data"); + QQmlComponent labelComponent(&engine); + labelComponent.setData("import QtQuick; import QtQuick.Controls; Label {}", QUrl()); + + QScopedPointer<QObject> object(labelComponent.create()); + QVERIFY2(!object.isNull(), qPrintable(labelComponent.errorString())); + + QCOMPARE(QQuickStyle::name(), expectedStyle); + QVERIFY(!QQuickStylePrivate::isUsingDefaultStyle()); + + // Test that fonts and palettes specified in configuration files are respected. + QQuickLabel *label = qobject_cast<QQuickLabel *>(object.data()); + QVERIFY(label); + // Make it small so that there's less possibility for the default/system + // pixel size to match it and give us false positives. + QCOMPARE(label->font().pixelSize(), 3); +#ifdef QT_BUILD_INTERNAL + QCOMPARE(QQuickLabelPrivate::get(label)->palette()->windowText(), Qt::red); +#endif +} + +void tst_QQuickStyle::commandLineArgument() +{ + QGuiApplicationPrivate::styleOverride = "CmdLineArgStyle"; + + QVERIFY(loadControls()); + + QCOMPARE(QQuickStyle::name(), QString("CmdLineArgStyle")); +} + +void tst_QQuickStyle::environmentVariables() +{ + qputenv("QT_QUICK_CONTROLS_STYLE", "EnvVarStyle"); + qputenv("QT_QUICK_CONTROLS_FALLBACK_STYLE", "EnvVarFallbackStyle"); + QTest::ignoreMessage(QtWarningMsg, "QT_QUICK_CONTROLS_FALLBACK_STYLE: the specified fallback style" \ + " \"EnvVarFallbackStyle\" is not one of the built-in Qt Quick Controls 2 styles"); + QCOMPARE(QQuickStyle::name(), QString("EnvVarStyle")); + QCOMPARE(QQuickStylePrivate::fallbackStyle(), QString()); +} + +QTEST_MAIN(tst_QQuickStyle) + +#include "tst_qquickstyle.moc" diff --git a/tests/auto/quickcontrols2/qquickuniversalstyle/CMakeLists.txt b/tests/auto/quickcontrols2/qquickuniversalstyle/CMakeLists.txt new file mode 100644 index 00000000000..43d4c10d123 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickuniversalstyle/CMakeLists.txt @@ -0,0 +1,38 @@ +# Generated from qquickuniversalstyle.pro. + +##################################################################### +## tst_qquickuniversalstyle Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/tst_*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickuniversalstyle + GUI + QMLTEST + SOURCES + tst_qquickuniversalstyle.cpp + PUBLIC_LIBRARIES + Qt::Gui + TESTDATA ${test_data} +) + +# Resources: +set(qmake_immediate_resource_files + "qtquickcontrols2.conf" +) + +qt_internal_add_resource(tst_qquickuniversalstyle "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + + +#### Keys ignored in scope 1:.:.:qquickuniversalstyle.pro:<TRUE>: +# OTHER_FILES = "$$PWD/data/*.qml" +# TEMPLATE = "app" diff --git a/tests/auto/quickcontrols2/qquickuniversalstyle/data/tst_universal.qml b/tests/auto/quickcontrols2/qquickuniversalstyle/data/tst_universal.qml new file mode 100644 index 00000000000..356df7311e7 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickuniversalstyle/data/tst_universal.qml @@ -0,0 +1,441 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtTest +import QtQuick.Controls +import QtQuick.Controls.Universal + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "Universal" + + Component { + id: button + Button { } + } + + Component { + id: styledButton + Button { + Universal.theme: Universal.Dark + Universal.accent: Universal.Violet + Universal.foreground: Universal.Brown + Universal.background: Universal.Yellow + } + } + + Component { + id: window + Window { } + } + + Component { + id: styledWindow + Window { + Universal.theme: Universal.Dark + Universal.accent: Universal.Green + } + } + + Component { + id: loader + Loader { + active: false + sourceComponent: Button { } + } + } + + Component { + id: swipeView + SwipeView { + Universal.theme: Universal.Dark + Button { } + } + } + + Component { + id: menu + ApplicationWindow { + Universal.accent: Universal.Red + property alias menu: popup + Menu { + id: popup + Universal.theme: Universal.Dark + MenuItem { } + } + } + } + + Component { + id: comboBox + ApplicationWindow { + width: 200 + height: 200 + visible: true + Universal.accent: Universal.Red + property alias combo: box + ComboBox { + id: box + Universal.theme: Universal.Dark + model: 1 + } + } + } + + Component { + id: windowPane + ApplicationWindow { + width: 200 + height: 200 + visible: true + property alias pane: pane + Pane { id: pane } + } + } + + function test_defaults() { + var control = button.createObject(testCase) + verify(control) + verify(control.Universal) + compare(control.Universal.accent, "#3e65ff") // Universal.Cobalt + compare(control.Universal.foreground, "#000000") // SystemBaseHighColor + compare(control.Universal.background, "#ffffff") // SystemAltHighColor + compare(control.Universal.theme, Universal.Light) + control.destroy() + } + + function test_set() { + var control = button.createObject(testCase) + verify(control) + control.Universal.accent = Universal.Steel + control.Universal.foreground = Universal.Red + control.Universal.background = Universal.Green + control.Universal.theme = Universal.Dark + compare(control.Universal.accent, "#647687") // Universal.Steel + compare(control.Universal.foreground, "#e51400") // Universal.Red + compare(control.Universal.background, "#60a917") // Universal.Green + compare(control.Universal.theme, Universal.Dark) + control.destroy() + } + + function test_reset() { + var control = styledButton.createObject(testCase) + verify(control) + compare(control.Universal.accent, "#aa00ff") // Universal.Violet + compare(control.Universal.foreground, "#825a2c") // Universal.Brown + compare(control.Universal.background, "#e3c800") // Universal.Yellow + compare(control.Universal.theme, Universal.Dark) + control.Universal.accent = undefined + control.Universal.foreground = undefined + control.Universal.background = undefined + control.Universal.theme = undefined + compare(control.Universal.accent, testCase.Universal.accent) + compare(control.Universal.foreground, testCase.Universal.foreground) + compare(control.Universal.background, testCase.Universal.background) + compare(control.Universal.theme, testCase.Universal.theme) + control.destroy() + } + + function test_inheritance_data() { + return [ + { tag: "accent", value1: "#a20025" /*Universal.Crimson*/, value2: "#6a00ff" /*Universal.Indigo*/ }, + { tag: "foreground", value1: "#a20025" /*Universal.Crimson*/, value2: "#6a00ff" /*Universal.Indigo*/ }, + { tag: "background", value1: "#a20025" /*Universal.Crimson*/, value2: "#6a00ff" /*Universal.Indigo*/ }, + { tag: "theme", value1: Universal.Dark, value2: Universal.Light }, + ] + } + + function test_inheritance(data) { + var prop = data.tag + var parent = button.createObject(testCase) + parent.Universal[prop] = data.value1 + compare(parent.Universal[prop], data.value1) + + var child1 = button.createObject(parent) + compare(child1.Universal[prop], data.value1) + + parent.Universal[prop] = data.value2 + compare(parent.Universal[prop], data.value2) + compare(child1.Universal[prop], data.value2) + + var child2 = button.createObject(parent) + compare(child2.Universal[prop], data.value2) + + child2.Universal[prop] = data.value1 + compare(child2.Universal[prop], data.value1) + compare(child1.Universal[prop], data.value2) + compare(parent.Universal[prop], data.value2) + + parent.Universal[prop] = undefined + verify(parent.Universal[prop] !== data.value1) + verify(parent.Universal[prop] !== undefined) + compare(child1.Universal[prop], parent.Universal[prop]) + verify(child2.Universal[prop] !== parent.Universal[prop]) + + var grandChild1 = button.createObject(child1) + var grandChild2 = button.createObject(child2) + compare(grandChild1.Universal[prop], child1.Universal[prop]) + compare(grandChild2.Universal[prop], child2.Universal[prop]) + + var themelessGrandGrandChild = button.createObject(grandChild1) + var grandGrandGrandChild1 = button.createObject(themelessGrandGrandChild) + compare(grandGrandGrandChild1.Universal[prop], parent.Universal[prop]) + + child1.Universal[prop] = data.value2 + compare(child1.Universal[prop], data.value2) + compare(grandChild1.Universal[prop], data.value2) + compare(grandGrandGrandChild1.Universal[prop], data.value2) + + parent.destroy() + } + + function test_window() { + var parent = window.createObject() + + var control = button.createObject(parent.contentItem) + compare(control.Universal.accent, parent.Universal.accent) + compare(control.Universal.theme, parent.Universal.theme) + + var styledChild = styledWindow.createObject(window) + verify(styledChild.Universal.accent !== parent.Universal.accent) + verify(styledChild.Universal.theme !== parent.Universal.theme) + + var unstyledChild = window.createObject(window) + compare(unstyledChild.Universal.accent, parent.Universal.accent) + compare(unstyledChild.Universal.theme, parent.Universal.theme) + + parent.Universal.accent = Universal.Cyan + compare(control.Universal.accent, "#1ba1e2") // Universal.Cyan + verify(styledChild.Universal.accent !== Universal.Cyan) + // ### TODO: compare(unstyledChild.Universal.accent, Universal.Cyan) + + parent.destroy() + } + + function test_loader() { + var control = loader.createObject(testCase) + control.Universal.accent = Universal.Lime + control.active = true + compare(control.item.Universal.accent, "#a4c400") // Universal.Lime + control.Universal.accent = Universal.Pink + compare(control.item.Universal.accent, "#f472d0") // Universal.Pink + control.active = false + control.Universal.accent = Universal.Brown + control.active = true + compare(control.item.Universal.accent, "#825a2c") // Universal.Brown + control.destroy() + } + + function test_swipeView() { + var control = swipeView.createObject(testCase) + verify(control) + var child = control.itemAt(0) + verify(child) + compare(control.Universal.theme, Universal.Dark) + compare(child.Universal.theme, Universal.Dark) + control.destroy() + } + + function test_menu() { + var container = menu.createObject(testCase) + verify(container) + verify(container.menu) + container.menu.open() + verify(container.menu.visible) + var child = container.menu.itemAt(0) + verify(child) + compare(container.Universal.theme, Universal.Light) + compare(container.menu.Universal.theme, Universal.Dark) + compare(child.Universal.theme, Universal.Dark) + compare(container.Universal.accent, "#e51400") // Red + compare(container.menu.Universal.accent, "#e51400") // Red + compare(child.Universal.accent, "#e51400") // Red + container.destroy() + } + + function test_comboBox() { + var window = comboBox.createObject(testCase) + verify(window) + verify(window.combo) + waitForRendering(window.combo) + window.combo.forceActiveFocus() + verify(window.combo.activeFocus) + keyClick(Qt.Key_Space) + verify(window.combo.popup.visible) + var listView = window.combo.popup.contentItem + verify(listView) + var child = listView.contentItem.children[0] + verify(child) + compare(window.Universal.theme, Universal.Light) + compare(window.combo.Universal.theme, Universal.Dark) + compare(child.Universal.theme, Universal.Dark) + compare(window.Universal.accent, "#e51400") // Red + compare(window.combo.Universal.accent, "#e51400") // Red + compare(child.Universal.accent, "#e51400") // Red + window.destroy() + } + + function test_windowChange() { + var ldr = loader.createObject() + verify(ldr) + + var wnd = window.createObject() + verify(wnd) + + wnd.Universal.theme = Universal.Dark + compare(wnd.Universal.theme, Universal.Dark) + + ldr.active = true + verify(ldr.item) + compare(ldr.item.Universal.theme, Universal.Light) + + ldr.parent = wnd.contentItem + compare(ldr.item.Universal.theme, Universal.Dark) + + wnd.destroy() + } + + function test_colors_data() { + return [ + { tag: "accent" }, { tag: "background" }, { tag: "foreground" } + ] + } + + function test_colors(data) { + var control = button.createObject(testCase) + verify(control) + + var prop = data.tag + + // Universal.Color - enum + control.Universal[prop] = Universal.Red + compare(control.Universal[prop], "#e51400") + + // Universal.Color - string + control.Universal[prop] = "Emerald" + compare(control.Universal[prop], "#008a00") + + // SVG named color + control.Universal[prop] = "tomato" + compare(control.Universal[prop], "#ff6347") + + // #rrggbb + control.Universal[prop] = "#123456" + compare(control.Universal[prop], "#123456") + + // #aarrggbb + control.Universal[prop] = "#12345678" + compare(control.Universal[prop], "#12345678") + + // Qt.rgba() - no alpha + control.Universal[prop] = Qt.rgba(0.5, 0.5, 0.5) + compare(control.Universal[prop], "#808080") + + // Qt.rgba() - with alpha + control.Universal[prop] = Qt.rgba(0.5, 0.5, 0.5, 0.5) + compare(control.Universal[prop], "#80808080") + + // unknown + ignoreWarning(Qt.resolvedUrl("tst_universal.qml") + ":67:9: QML Button: unknown Universal." + prop + " value: 123") + control.Universal[prop] = 123 + ignoreWarning(Qt.resolvedUrl("tst_universal.qml") + ":67:9: QML Button: unknown Universal." + prop + " value: foo") + control.Universal[prop] = "foo" + ignoreWarning(Qt.resolvedUrl("tst_universal.qml") + ":67:9: QML Button: unknown Universal." + prop + " value: #1") + control.Universal[prop] = "#1" + + control.destroy() + } + + function test_font_data() { + return [ + {tag: "Control:pixelSize", type: "Control", attribute: "pixelSize", value: 15, window: 20, pane: 10}, + + {tag: "GroupBox:pixelSize", type: "GroupBox", attribute: "pixelSize", value: 15, window: 20, pane: 10}, + {tag: "GroupBox:weight", type: "GroupBox", attribute: "weight", value: Font.DemiBold, window: Font.Light, pane: Font.Medium}, + + {tag: "TabButton:pixelSize", type: "TabButton", attribute: "pixelSize", value: 24, window: 20, pane: 10}, + {tag: "TabButton:weight", type: "TabButton", attribute: "weight", value: Font.Light, window: Font.Black, pane: Font.Bold} + ] + } + + function test_font(data) { + var window = windowPane.createObject(testCase) + verify(window) + verify(window.pane) + + var control = Qt.createQmlObject("import QtQuick.Controls; " + data.type + " { }", window.pane) + verify(control) + + compare(control.font[data.attribute], data.value) + + window.font[data.attribute] = data.window + compare(window.font[data.attribute], data.window) + compare(window.pane.font[data.attribute], data.window) + compare(control.font[data.attribute], data.window) + + window.pane.font[data.attribute] = data.pane + compare(window.font[data.attribute], data.window) + compare(window.pane.font[data.attribute], data.pane) + compare(control.font[data.attribute], data.pane) + + window.pane.font = undefined + compare(window.font[data.attribute], data.window) + compare(window.pane.font[data.attribute], data.window) + compare(control.font[data.attribute], data.window) + + window.destroy() + } +} diff --git a/tests/auto/quickcontrols2/qquickuniversalstyle/qtquickcontrols2.conf b/tests/auto/quickcontrols2/qquickuniversalstyle/qtquickcontrols2.conf new file mode 100644 index 00000000000..8c6dd807e3f --- /dev/null +++ b/tests/auto/quickcontrols2/qquickuniversalstyle/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Universal diff --git a/tests/auto/quickcontrols2/qquickuniversalstyle/tst_qquickuniversalstyle.cpp b/tests/auto/quickcontrols2/qquickuniversalstyle/tst_qquickuniversalstyle.cpp new file mode 100644 index 00000000000..c5b6b566cfc --- /dev/null +++ b/tests/auto/quickcontrols2/qquickuniversalstyle/tst_qquickuniversalstyle.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQuickTest/quicktest.h> +QUICK_TEST_MAIN(tst_qquickuniversalstyle) diff --git a/tests/auto/quickcontrols2/qquickuniversalstyleconf/CMakeLists.txt b/tests/auto/quickcontrols2/qquickuniversalstyleconf/CMakeLists.txt new file mode 100644 index 00000000000..55c7d782996 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickuniversalstyleconf/CMakeLists.txt @@ -0,0 +1,61 @@ +# Generated from qquickuniversalstyleconf.pro. + +##################################################################### +## tst_qquickuniversalstyleconf Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickuniversalstyleconf + SOURCES + tst_qquickuniversalstyleconf.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +# Resources: +set(qquickuniversalstyleconf_resource_files + "qtquickcontrols2.conf" +) + +qt_internal_add_resource(tst_qquickuniversalstyleconf "qquickuniversalstyleconf" + PREFIX + "/" + FILES + ${qquickuniversalstyleconf_resource_files} +) + + +#### Keys ignored in scope 1:.:.:qquickuniversalstyleconf.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_qquickuniversalstyleconf CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickuniversalstyleconf CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/qquickuniversalstyleconf/data/applicationwindow.qml b/tests/auto/quickcontrols2/qquickuniversalstyleconf/data/applicationwindow.qml new file mode 100644 index 00000000000..bb16254a157 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickuniversalstyleconf/data/applicationwindow.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Universal + +ApplicationWindow { + width: 400 + height: 400 + + property alias label: label + + Label { + id: label + } +} diff --git a/tests/auto/quickcontrols2/qquickuniversalstyleconf/qquickuniversalstyleconf.qrc b/tests/auto/quickcontrols2/qquickuniversalstyleconf/qquickuniversalstyleconf.qrc new file mode 100644 index 00000000000..53ba645049b --- /dev/null +++ b/tests/auto/quickcontrols2/qquickuniversalstyleconf/qquickuniversalstyleconf.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>qtquickcontrols2.conf</file> +</qresource> +</RCC> diff --git a/tests/auto/quickcontrols2/qquickuniversalstyleconf/qtquickcontrols2.conf b/tests/auto/quickcontrols2/qquickuniversalstyleconf/qtquickcontrols2.conf new file mode 100644 index 00000000000..0ec1325871b --- /dev/null +++ b/tests/auto/quickcontrols2/qquickuniversalstyleconf/qtquickcontrols2.conf @@ -0,0 +1,10 @@ +[Controls] +Style=Universal + +[Universal] +Background=#444444 +Foreground=Red +Font\PixelSize=22 + +[Universal\Font] +Family=Courier diff --git a/tests/auto/quickcontrols2/qquickuniversalstyleconf/tst_qquickuniversalstyleconf.cpp b/tests/auto/quickcontrols2/qquickuniversalstyleconf/tst_qquickuniversalstyleconf.cpp new file mode 100644 index 00000000000..1892dd3cf74 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickuniversalstyleconf/tst_qquickuniversalstyleconf.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickControls2/private/qquickstyle_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> + +using namespace QQuickControlsTestUtils; + +class tst_qquickuniversalstyleconf : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_qquickuniversalstyleconf(); + +private slots: + void conf(); +}; + +tst_qquickuniversalstyleconf::tst_qquickuniversalstyleconf() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_qquickuniversalstyleconf::conf() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("applicationwindow.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + QFont customFont; + customFont.setFamilies(QStringList{QLatin1String("Courier")}); + customFont.setPixelSize(22); + + QQuickApplicationWindow *window = helper.appWindow; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + // We specified a custom background color and font, so the window should have them. + QCOMPARE(window->property("color").value<QColor>(), QColor("#444444")); + QCOMPARE(window->property("font").value<QFont>(), customFont); + + // We specified a custom foreground color and font, so the label should have them. + QQuickItem *label = window->property("label").value<QQuickItem*>(); + QVERIFY(label); + QCOMPARE(label->property("color").value<QColor>(), QColor("#E51400")); + QCOMPARE(label->property("font").value<QFont>(), customFont); +} + +QTEST_MAIN(tst_qquickuniversalstyleconf) + +#include "tst_qquickuniversalstyleconf.moc" diff --git a/tests/auto/quickcontrols2/revisions/CMakeLists.txt b/tests/auto/quickcontrols2/revisions/CMakeLists.txt new file mode 100644 index 00000000000..801dd6d66da --- /dev/null +++ b/tests/auto/quickcontrols2/revisions/CMakeLists.txt @@ -0,0 +1,18 @@ +# Generated from revisions.pro. + +##################################################################### +## tst_revisions Test: +##################################################################### + +qt_internal_add_test(tst_revisions + SOURCES + tst_revisions.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Qml + Qt::QuickControls2 + Qt::QuickTemplates2 +) + +## Scopes: +##################################################################### diff --git a/tests/auto/quickcontrols2/revisions/data/dependencies.qml b/tests/auto/quickcontrols2/revisions/data/dependencies.qml new file mode 100644 index 00000000000..bb954219956 --- /dev/null +++ b/tests/auto/quickcontrols2/revisions/data/dependencies.qml @@ -0,0 +1,6 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Controls.Universal + +Control { } diff --git a/tests/auto/quickcontrols2/revisions/tst_revisions.cpp b/tests/auto/quickcontrols2/revisions/tst_revisions.cpp new file mode 100644 index 00000000000..0d4518cc20d --- /dev/null +++ b/tests/auto/quickcontrols2/revisions/tst_revisions.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQuickControls2/qquickstyle.h> + +class tst_revisions : public QObject +{ + Q_OBJECT + +public: + tst_revisions(); + +private slots: + void revisions_data(); + void revisions(); + + void window_data(); + void window(); +}; + +tst_revisions::tst_revisions() +{ + QQuickStyle::setStyle("Basic"); +} + +void tst_revisions::revisions_data() +{ + QTest::addColumn<int>("revision"); + + // Qt 5.7: 2.0, Qt 5.8: 2.1, Qt 5.9: 2.2... + for (int i = 0; i <= 15; ++i) + QTest::newRow(qPrintable(QString("2.%1").arg(i))) << i; +} + +void tst_revisions::revisions() +{ + QFETCH(int, revision); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(QString("import QtQuick; \ + import QtQuick.Templates 2.%1 as T; \ + import QtQuick.Controls 2.%1; \ + import QtQuick.Controls.impl 2.%1; \ + import QtQuick.Controls.Material 2.%1; \ + import QtQuick.Controls.Material.impl 2.%1; \ + import QtQuick.Controls.Universal 2.%1; \ + import QtQuick.Controls.Universal.impl 2.%1; \ + Control { }").arg(revision).toUtf8(), QUrl()); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); +} + +void tst_revisions::window_data() +{ + QTest::addColumn<int>("revision"); + QTest::addColumn<QString>("qml"); + QTest::addColumn<QString>("error"); + + // Qt 5.7: 2.0, Qt 5.8: 2.1, Qt 5.9: 2.2 + // Note that we can no longer map the same Screen type to different versions + // in QtQuick and QtQuick.Controls anymore. + for (int i = 0; i <= 2; ++i) + QTest::newRow(qPrintable(QString("screen:2.%1").arg(i))) << i << "screen: null" << QString(":1 \"ApplicationWindow.screen\" is not available in QtQuick.Templates 2.%1").arg(i); + + // Qt 5.10: 2.3... + for (int i = 3; i <= 15; ++i) + QTest::newRow(qPrintable(QString("screen:2.%1").arg(i))) << i << "screen: null" << ""; +} + +void tst_revisions::window() +{ + QFETCH(int, revision); + QFETCH(QString, qml); + QFETCH(QString, error); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(QString("import QtQuick.Templates 2.%1; ApplicationWindow { %2 }").arg(revision).arg(qml).toUtf8(), QUrl()); + QScopedPointer<QObject> window(component.create()); + QCOMPARE(window.isNull(), !error.isEmpty()); +} + +QTEST_MAIN(tst_revisions) + +#include "tst_revisions.moc" diff --git a/tests/auto/quickcontrols2/sanity/BLACKLIST b/tests/auto/quickcontrols2/sanity/BLACKLIST new file mode 100644 index 00000000000..214c6e7c3eb --- /dev/null +++ b/tests/auto/quickcontrols2/sanity/BLACKLIST @@ -0,0 +1,24 @@ +[attachedObjects:material/Switch.qml] +* +[attachedObjects:material/SwitchDelegate.qml] +* +[ids:basic/HorizontalHeaderView.qml] +* +[ids:basic/VerticalHeaderView.qml] +* +[ids:fusion/HorizontalHeaderView.qml] +* +[ids:fusion/VerticalHeaderView.qml] +* +[ids:imagine/HorizontalHeaderView.qml] +* +[ids:imagine/VerticalHeaderView.qml] +* +[ids:material/HorizontalHeaderView.qml] +* +[ids:material/VerticalHeaderView.qml] +* +[ids:universal/HorizontalHeaderView.qml] +* +[ids:universal/VerticalHeaderView.qml] +* diff --git a/tests/auto/quickcontrols2/sanity/CMakeLists.txt b/tests/auto/quickcontrols2/sanity/CMakeLists.txt new file mode 100644 index 00000000000..f81efb0bc19 --- /dev/null +++ b/tests/auto/quickcontrols2/sanity/CMakeLists.txt @@ -0,0 +1,43 @@ +# Generated from sanity.pro. + +##################################################################### +## tst_sanity Test: +##################################################################### + +qt_internal_add_test(tst_sanity + SOURCES + tst_sanity.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::Qml + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate +) + +#### Keys ignored in scope 1:.:.:sanity.pro:<TRUE>: +# OTHER_FILES = "$$PWD/BLACKLIST" +# TEMPLATE = "app" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_sanity CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_sanity CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/sanity/data/dependencies.qml b/tests/auto/quickcontrols2/sanity/data/dependencies.qml new file mode 100644 index 00000000000..280cfd29623 --- /dev/null +++ b/tests/auto/quickcontrols2/sanity/data/dependencies.qml @@ -0,0 +1,4 @@ +import QtQuick +import QtQuick.Controls + +Control { } diff --git a/tests/auto/quickcontrols2/sanity/tst_sanity.cpp b/tests/auto/quickcontrols2/sanity/tst_sanity.cpp new file mode 100644 index 00000000000..dc1a4b3836f --- /dev/null +++ b/tests/auto/quickcontrols2/sanity/tst_sanity.cpp @@ -0,0 +1,671 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest> +#include <QtQml> +#include <QtCore/private/qhooks_p.h> +#include <QtCore/qpair.h> +#include <QtCore/qscopedpointer.h> +#include <QtCore/qset.h> +#include <QtQml/private/qqmljsengine_p.h> +#include <QtQml/private/qqmljslexer_p.h> +#include <QtQml/private/qqmljsparser_p.h> +#include <QtQml/private/qqmljsast_p.h> +#include <QtQml/private/qqmljsastvisitor_p.h> +#include <QtQml/private/qqmlmetatype_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> + +using namespace QQuickVisualTestUtils; +using namespace QQuickControlsTestUtils; + +Q_GLOBAL_STATIC(QObjectList, qt_qobjects) + +extern "C" Q_DECL_EXPORT void qt_addQObject(QObject *object) +{ + qt_qobjects->append(object); +} + +extern "C" Q_DECL_EXPORT void qt_removeQObject(QObject *object) +{ + qt_qobjects->removeAll(object); +} + +class tst_Sanity : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + void initTestCase(); + + void jsFiles(); + void functions(); + void functions_data(); + void signalHandlers(); + void signalHandlers_data(); + void anchors(); + void anchors_data(); + void attachedObjects(); + void attachedObjects_data(); + void ids(); + void ids_data(); + +private: + QMap<QString, QString> sourceQmlFiles; + QMap<QString, QString> installedQmlFiles; + QQuickStyleHelper styleHelper; +}; + +void tst_Sanity::init() +{ + qtHookData[QHooks::AddQObject] = reinterpret_cast<quintptr>(&qt_addQObject); + qtHookData[QHooks::RemoveQObject] = reinterpret_cast<quintptr>(&qt_removeQObject); +} + +void tst_Sanity::cleanup() +{ + qt_qobjects->clear(); + qtHookData[QHooks::AddQObject] = 0; + qtHookData[QHooks::RemoveQObject] = 0; +} + +class BaseValidator : public QQmlJS::AST::Visitor +{ +public: + QString errors() const { return m_errors.join(", "); } + + bool validate(const QString& filePath) + { + m_errors.clear(); + m_fileName = QFileInfo(filePath).fileName(); + + QFile file(filePath); + if (!file.open(QFile::ReadOnly)) { + m_errors += QString("%1: failed to open (%2)").arg(m_fileName, file.errorString()); + return false; + } + + QQmlJS::Engine engine; + QQmlJS::Lexer lexer(&engine); + lexer.setCode(QString::fromUtf8(file.readAll()), /*line = */ 1); + + QQmlJS::Parser parser(&engine); + if (!parser.parse()) { + const auto diagnosticMessages = parser.diagnosticMessages(); + for (const QQmlJS::DiagnosticMessage &msg : diagnosticMessages) + m_errors += QString("%s:%d : %s").arg(m_fileName).arg(msg.loc.startLine).arg(msg.message); + return false; + } + + QQmlJS::AST::UiProgram* ast = parser.ast(); + ast->accept(this); + return m_errors.isEmpty(); + } + +protected: + void addError(const QString& error, QQmlJS::AST::Node *node) + { + m_errors += QString("%1:%2 : %3").arg(m_fileName).arg(node->firstSourceLocation().startLine).arg(error); + } + + void throwRecursionDepthError() final + { + m_errors += QString::fromLatin1("%1: Maximum statement or expression depth exceeded") + .arg(m_fileName); + } + +private: + QString m_fileName; + QStringList m_errors; +}; + +void tst_Sanity::initTestCase() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(QString("import QtQuick.Templates 2.%1; Control { }").arg(15).toUtf8(), QUrl()); + + const QStringList qmlTypeNames = QQmlMetaType::qmlTypeNames(); + + // Collect the files from each style in the source tree. + QDirIterator it(QQC2_IMPORT_PATH, QStringList() << "*.qml" << "*.js", QDir::Files, QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + QFileInfo info = it.fileInfo(); + if (qmlTypeNames.contains(QStringLiteral("QtQuick.Templates/") + info.baseName())) + sourceQmlFiles.insert(info.dir().dirName() + "/" + info.fileName(), info.filePath()); + } + + // Then, collect the files from each installed style directory. + const QVector<QPair<QString, QString>> styleRelativePaths = { + { "basic", "QtQuick/Controls/Basic" }, + { "fusion", "QtQuick/Controls/Fusion" }, + { "material", "QtQuick/Controls/Material" }, + { "universal", "QtQuick/Controls/Universal" }, + // TODO: add native styles: QTBUG-87108 + }; + for (const auto &stylePathPair : styleRelativePaths) { + forEachControl(&engine, QQC2_IMPORT_PATH, stylePathPair.first, stylePathPair.second, QStringList(), + [&](const QString &relativePath, const QUrl &absoluteUrl) { + installedQmlFiles.insert(relativePath, absoluteUrl.toLocalFile()); + }); + } +} + +void tst_Sanity::jsFiles() +{ + QMap<QString, QString>::const_iterator it; + for (it = sourceQmlFiles.constBegin(); it != sourceQmlFiles.constEnd(); ++it) { + if (QFileInfo(it.value()).suffix() == QStringLiteral("js")) + QFAIL(qPrintable(it.value() + ": JS files are not allowed")); + } +} + +class FunctionValidator : public BaseValidator +{ +protected: + bool visit(QQmlJS::AST::FunctionDeclaration *node) override + { + addError("function declarations are not allowed", node); + return true; + } +}; + +void tst_Sanity::functions() +{ + QFETCH(QString, control); + QFETCH(QString, filePath); + + FunctionValidator validator; + if (!validator.validate(filePath)) + QFAIL(qPrintable(validator.errors())); +} + +void tst_Sanity::functions_data() +{ + QTest::addColumn<QString>("control"); + QTest::addColumn<QString>("filePath"); + + QMap<QString, QString>::const_iterator it; + for (it = sourceQmlFiles.constBegin(); it != sourceQmlFiles.constEnd(); ++it) + QTest::newRow(qPrintable(it.key())) << it.key() << it.value(); +} + +class SignalHandlerValidator : public BaseValidator +{ +protected: + static bool isSignalHandler(QStringView name) + { + return name.length() > 2 && name.startsWith(QLatin1String("on")) && name.at(2).isUpper(); + } + + bool visit(QQmlJS::AST::UiScriptBinding *node) override + { + QQmlJS::AST::UiQualifiedId* id = node->qualifiedId; + if ((id && isSignalHandler(id->name)) || (id && id->next && isSignalHandler(id->next->name))) + addError("signal handlers are not allowed", node); + return true; + } +}; + +void tst_Sanity::signalHandlers() +{ + QFETCH(QString, control); + QFETCH(QString, filePath); + + SignalHandlerValidator validator; + if (!validator.validate(filePath)) + QFAIL(qPrintable(validator.errors())); +} + +void tst_Sanity::signalHandlers_data() +{ + QTest::addColumn<QString>("control"); + QTest::addColumn<QString>("filePath"); + + QMap<QString, QString>::const_iterator it; + for (it = sourceQmlFiles.constBegin(); it != sourceQmlFiles.constEnd(); ++it) + QTest::newRow(qPrintable(it.key())) << it.key() << it.value(); +} + +class AnchorValidator : public BaseValidator +{ +protected: + bool visit(QQmlJS::AST::UiScriptBinding *node) override + { + QQmlJS::AST::UiQualifiedId* id = node->qualifiedId; + if (id && id->name == QStringLiteral("anchors")) + addError("anchors are not allowed", node); + return true; + } +}; + +void tst_Sanity::anchors() +{ + QFETCH(QString, control); + QFETCH(QString, filePath); + + AnchorValidator validator; + if (!validator.validate(filePath)) + QFAIL(qPrintable(validator.errors())); +} + +void tst_Sanity::anchors_data() +{ + QTest::addColumn<QString>("control"); + QTest::addColumn<QString>("filePath"); + + QMap<QString, QString>::const_iterator it; + for (it = sourceQmlFiles.constBegin(); it != sourceQmlFiles.constEnd(); ++it) + QTest::newRow(qPrintable(it.key())) << it.key() << it.value(); +} + +class IdValidator : public BaseValidator +{ +public: + IdValidator() : m_depth(0) { } + +protected: + bool visit(QQmlJS::AST::UiObjectBinding *) override + { + ++m_depth; + return true; + } + + void endVisit(QQmlJS::AST::UiObjectBinding *) override + { + --m_depth; + } + + bool visit(QQmlJS::AST::UiScriptBinding *node) override + { + if (m_depth == 0) + return true; + + QQmlJS::AST::UiQualifiedId *id = node->qualifiedId; + if (id && id->name == QStringLiteral("id")) + addError(QString("Internal IDs are not allowed (%1)").arg(extractName(node->statement)), node); + return true; + } + +private: + QString extractName(QQmlJS::AST::Statement *statement) + { + QQmlJS::AST::ExpressionStatement *expressionStatement = static_cast<QQmlJS::AST::ExpressionStatement *>(statement); + if (!expressionStatement) + return QString(); + + QQmlJS::AST::IdentifierExpression *expression = static_cast<QQmlJS::AST::IdentifierExpression *>(expressionStatement->expression); + if (!expression) + return QString(); + + return expression->name.toString(); + } + + int m_depth; +}; + +void tst_Sanity::ids() +{ + QFETCH(QString, control); + QFETCH(QString, filePath); + + IdValidator validator; + if (!validator.validate(filePath)) + QFAIL(qPrintable(validator.errors())); +} + +void tst_Sanity::ids_data() +{ + QTest::addColumn<QString>("control"); + QTest::addColumn<QString>("filePath"); + + QMap<QString, QString>::const_iterator it; + for (it = sourceQmlFiles.constBegin(); it != sourceQmlFiles.constEnd(); ++it) + QTest::newRow(qPrintable(it.key())) << it.key() << it.value(); +} + +typedef QPair<QString, QString> StringPair; +typedef QSet<StringPair> StringPairSet; + +void tst_Sanity::attachedObjects() +{ + QFETCH(QStringList, ignoredAttachedClassNames); + QFETCH(StringPairSet, expectedAttachedClassNames); + + const QString tagStr = QString::fromLatin1(QTest::currentDataTag()); + QStringList styleAndFileName = tagStr.split('/'); + QCOMPARE(styleAndFileName.size(), 2); + QString style = styleAndFileName.first(); + + if (styleHelper.updateStyle(style)) + qt_qobjects->clear(); + + QString styleRelativePath = tagStr; + styleRelativePath[0] = styleRelativePath.at(0).toLower(); + // Get the absolute path to the installed file. + const QString controlFilePath = installedQmlFiles.value(styleRelativePath); + + QQmlComponent component(styleHelper.engine.data()); + component.loadUrl(QUrl::fromLocalFile(controlFilePath)); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(object.data(), qPrintable(component.errorString())); + + // The goal of this test is to check that every unique attached type is used only once + // within each QML file. To track this, we remove expected pairs of class names as we + // encounter them, so that we know when something unexpected shows up. + StringPairSet remainingAttachedClassNames = expectedAttachedClassNames; + + // Intentional copy, as QDebug creates a QObject-derived instance which would modify the list. + const auto qobjectsCopy = *qt_qobjects; + for (QObject *object : qobjectsCopy) { + const QString attachedClassName = object->metaObject()->className(); + if (object->parent() == styleHelper.engine.data()) + continue; // allow "global" instances + + // objects without parents would be singletons such as QQuickFusionStyle, and we're not interested in them. + if ((attachedClassName.endsWith("Attached") || attachedClassName.endsWith("Style")) && object->parent()) { + QString attacheeClassName = QString::fromLatin1(object->parent()->metaObject()->className()); + const QString qmlTypeToken = QStringLiteral("QMLTYPE"); + if (attacheeClassName.contains(qmlTypeToken)) { + // Remove the numbers from the class name, as they can change between runs; e.g.: + // Menu_QMLTYPE_222 => Menu_QMLTYPE + const int qmlTypeTokenIndex = attacheeClassName.indexOf(qmlTypeToken); + QVERIFY(qmlTypeTokenIndex != -1); + attacheeClassName = attacheeClassName.mid(0, attacheeClassName.indexOf(qmlTypeToken) + qmlTypeToken.size()); + } + + const StringPair classNamePair = { attachedClassName, attacheeClassName }; + QVERIFY2(remainingAttachedClassNames.contains(classNamePair), qPrintable(QString::fromLatin1( + "Found an unexpected usage of an attached type: %1 is attached to %2. Either an incorrect usage was added, or the list of expected usages needs to be updated. Expected attached class names for %3 are:\n %4") + .arg(attachedClassName).arg(attacheeClassName).arg(tagStr).arg(QDebug::toString(expectedAttachedClassNames)))); + remainingAttachedClassNames.remove(classNamePair); + } + } + + QVERIFY2(remainingAttachedClassNames.isEmpty(), qPrintable(QString::fromLatin1( + "Not all expected attached class name usages were found; the following usages are missing:\n %1") + .arg(QDebug::toString(remainingAttachedClassNames)))); +} + +void tst_Sanity::attachedObjects_data() +{ + QTest::addColumn<QStringList>("ignoredAttachedClassNames"); + QTest::addColumn<StringPairSet>("expectedAttachedClassNames"); + + QStringList ignoredNames; + + // We used to just check that there were no duplicate QMetaObject class names, + // but that doesn't account for attached objects loaded by composite controls, + // such as DialogButtonBox, which is loaded by Dialog. + // So now we list all controls and the attached types we expect them to use. + + QTest::newRow("Basic/AbstractButton.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Action.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/ActionGroup.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/ApplicationWindow.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/BusyIndicator.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Button.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/ButtonGroup.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/CheckBox.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/CheckDelegate.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/ComboBox.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Container.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Control.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/DelayButton.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Dial.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Dialog.qml") << ignoredNames << StringPairSet {{ "QQuickOverlayAttached", "Dialog_QMLTYPE" }}; + QTest::newRow("Basic/DialogButtonBox.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Drawer.qml") << ignoredNames << StringPairSet {{ "QQuickOverlayAttached", "Drawer_QMLTYPE" }}; + QTest::newRow("Basic/Frame.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/GroupBox.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/HorizontalHeaderView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/ItemDelegate.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Label.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/MenuBar.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/MenuBarItem.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/MenuItem.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/MenuSeparator.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Page.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/PageIndicator.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Pane.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Popup.qml") << ignoredNames << StringPairSet {{ "QQuickOverlayAttached", "Popup_QMLTYPE" }}; + QTest::newRow("Basic/ProgressBar.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/RadioButton.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/RadioDelegate.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/RangeSlider.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/RoundButton.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/ScrollBar.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/ScrollIndicator.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/ScrollView.qml") << ignoredNames << StringPairSet {{ "QQuickScrollBarAttached", "ScrollView_QMLTYPE" }}; + QTest::newRow("Basic/Slider.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/SpinBox.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/SplitView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/StackView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/SwipeDelegate.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/SwipeView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Switch.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/SwitchDelegate.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/TabBar.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/TabButton.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/TextArea.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/TextField.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/ToolBar.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/ToolButton.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/ToolSeparator.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/ToolTip.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/Tumbler.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Basic/VerticalHeaderView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/ApplicationWindow.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/BusyIndicator.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/Button.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/CheckBox.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/CheckDelegate.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/ComboBox.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/DelayButton.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/Dial.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/Dialog.qml") << ignoredNames << StringPairSet {{ "QQuickOverlayAttached", "Dialog_QMLTYPE" }}; + QTest::newRow("Fusion/DialogButtonBox.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/Drawer.qml") << ignoredNames << StringPairSet {{ "QQuickOverlayAttached", "Drawer_QMLTYPE" }}; + QTest::newRow("Fusion/Frame.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/GroupBox.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/HorizontalHeaderView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/ItemDelegate.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/Label.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/MenuBar.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/MenuBarItem.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/MenuItem.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/MenuSeparator.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/Page.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/PageIndicator.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/Pane.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/Popup.qml") << ignoredNames << StringPairSet {{ "QQuickOverlayAttached", "Popup_QMLTYPE" }}; + QTest::newRow("Fusion/ProgressBar.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/RadioButton.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/RadioDelegate.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/RangeSlider.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/RoundButton.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/ScrollBar.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/ScrollIndicator.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/Slider.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/SpinBox.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/SplitView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/SwipeDelegate.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/Switch.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/SwitchDelegate.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/TabBar.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/TabButton.qml") << ignoredNames << StringPairSet {{ "QQuickTabBarAttached", "TabButton_QMLTYPE" }}; + QTest::newRow("Fusion/TextArea.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/TextField.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/ToolBar.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/ToolButton.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/ToolSeparator.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/ToolTip.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/Tumbler.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Fusion/VerticalHeaderView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Material/ApplicationWindow.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "ApplicationWindow_QMLTYPE" }}; + QTest::newRow("Material/BusyIndicator.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "BusyIndicator_QMLTYPE" }}; + QTest::newRow("Material/Button.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "Button_QMLTYPE" }}; + QTest::newRow("Material/CheckBox.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "CheckBox_QMLTYPE" }}; + QTest::newRow("Material/CheckDelegate.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "CheckDelegate_QMLTYPE" }}; + QTest::newRow("Material/ComboBox.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "ComboBox_QMLTYPE" }}; + QTest::newRow("Material/DelayButton.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "DelayButton_QMLTYPE" }}; + QTest::newRow("Material/Dial.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "Dial_QMLTYPE" }}; + QTest::newRow("Material/Dialog.qml") << ignoredNames << StringPairSet { + { "QQuickMaterialStyle", "DialogButtonBox_QMLTYPE" }, + { "QQuickOverlayAttached", "Dialog_QMLTYPE" }, + { "QQuickMaterialStyle", "Dialog_QMLTYPE" }, + { "QQuickMaterialStyle", "Label_QMLTYPE" } + }; + QTest::newRow("Material/DialogButtonBox.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "DialogButtonBox_QMLTYPE" }}; + QTest::newRow("Material/Drawer.qml") << ignoredNames << StringPairSet { + { "QQuickOverlayAttached", "Drawer_QMLTYPE" }, + { "QQuickMaterialStyle", "Drawer_QMLTYPE" } + }; + QTest::newRow("Material/Frame.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "Frame_QMLTYPE" }}; + QTest::newRow("Material/GroupBox.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "GroupBox_QMLTYPE" }}; + QTest::newRow("Material/HorizontalHeaderView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Material/ItemDelegate.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "ItemDelegate_QMLTYPE" }}; + QTest::newRow("Material/Label.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "Label_QMLTYPE" }}; + QTest::newRow("Material/MenuBar.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "MenuBar_QMLTYPE" }}; + QTest::newRow("Material/MenuBarItem.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "MenuBarItem_QMLTYPE" }}; + QTest::newRow("Material/MenuItem.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "MenuItem_QMLTYPE" }}; + QTest::newRow("Material/MenuSeparator.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "MenuSeparator_QMLTYPE" }}; + QTest::newRow("Material/Page.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "Page_QMLTYPE" }}; + QTest::newRow("Material/PageIndicator.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Material/Pane.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "Pane_QMLTYPE" }}; + QTest::newRow("Material/Popup.qml") << ignoredNames << StringPairSet { + { "QQuickOverlayAttached", "Popup_QMLTYPE" }, + { "QQuickMaterialStyle", "Popup_QMLTYPE" } + }; + QTest::newRow("Material/ProgressBar.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "ProgressBar_QMLTYPE" }}; + QTest::newRow("Material/RadioButton.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "RadioButton_QMLTYPE" }}; + QTest::newRow("Material/RadioDelegate.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "RadioDelegate_QMLTYPE" }}; + QTest::newRow("Material/RangeSlider.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "RangeSlider_QMLTYPE" }}; + QTest::newRow("Material/RoundButton.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "RoundButton_QMLTYPE" }}; + QTest::newRow("Material/ScrollBar.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "ScrollBar_QMLTYPE" }}; + QTest::newRow("Material/ScrollIndicator.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "ScrollIndicator_QMLTYPE" }}; + QTest::newRow("Material/Slider.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "Slider_QMLTYPE" }}; + QTest::newRow("Material/SpinBox.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "SpinBox_QMLTYPE" }}; + QTest::newRow("Material/SplitView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Material/StackView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Material/SwipeDelegate.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "SwipeDelegate_QMLTYPE" }}; + QTest::newRow("Material/SwipeView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Material/Switch.qml") << ignoredNames << StringPairSet { + { "QQuickMaterialStyle", "SwitchIndicator_QMLTYPE" }, + { "QQuickMaterialStyle", "Switch_QMLTYPE" } + }; + QTest::newRow("Material/SwitchDelegate.qml") << ignoredNames << StringPairSet { + { "QQuickMaterialStyle", "SwitchDelegate_QMLTYPE" }, + { "QQuickMaterialStyle", "SwitchIndicator_QMLTYPE" } + }; + QTest::newRow("Material/TabBar.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "TabBar_QMLTYPE" }}; + QTest::newRow("Material/TabButton.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "TabButton_QMLTYPE" }}; + QTest::newRow("Material/TextArea.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "TextArea_QMLTYPE" }}; + QTest::newRow("Material/TextField.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "TextField_QMLTYPE" }}; + QTest::newRow("Material/ToolBar.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "ToolBar_QMLTYPE" }}; + QTest::newRow("Material/ToolButton.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "ToolButton_QMLTYPE" }}; + QTest::newRow("Material/ToolSeparator.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "ToolSeparator_QMLTYPE" }}; + QTest::newRow("Material/ToolTip.qml") << ignoredNames << StringPairSet {{ "QQuickMaterialStyle", "ToolTip_QMLTYPE" }}; + QTest::newRow("Material/Tumbler.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Material/VerticalHeaderView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Universal/ApplicationWindow.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "ApplicationWindow_QMLTYPE" }}; + QTest::newRow("Universal/BusyIndicator.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "BusyIndicator_QMLTYPE" }}; + QTest::newRow("Universal/Button.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "Button_QMLTYPE" }}; + QTest::newRow("Universal/CheckBox.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "CheckBox_QMLTYPE" }}; + QTest::newRow("Universal/CheckDelegate.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "CheckDelegate_QMLTYPE" }}; + QTest::newRow("Universal/ComboBox.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "ComboBox_QMLTYPE" }}; + QTest::newRow("Universal/DelayButton.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "DelayButton_QMLTYPE" }}; + QTest::newRow("Universal/Dial.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "Dial_QMLTYPE" }}; + QTest::newRow("Universal/Dialog.qml") << ignoredNames << StringPairSet { + { "QQuickOverlayAttached", "Dialog_QMLTYPE" }, + { "QQuickUniversalStyle", "Label_QMLTYPE" }, + { "QQuickUniversalStyle", "Dialog_QMLTYPE" }, + { "QQuickUniversalStyle", "DialogButtonBox_QMLTYPE" } + }; + QTest::newRow("Universal/DialogButtonBox.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "DialogButtonBox_QMLTYPE" }}; + QTest::newRow("Universal/Drawer.qml") << ignoredNames << StringPairSet { + { "QQuickOverlayAttached", "Drawer_QMLTYPE" }, + { "QQuickUniversalStyle", "Drawer_QMLTYPE" } + }; + QTest::newRow("Universal/Frame.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "Frame_QMLTYPE" }}; + QTest::newRow("Universal/GroupBox.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "GroupBox_QMLTYPE" }}; + QTest::newRow("Universal/HorizontalHeaderView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Universal/ItemDelegate.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "ItemDelegate_QMLTYPE" }}; + QTest::newRow("Universal/Label.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "Label_QMLTYPE" }}; + QTest::newRow("Universal/MenuBar.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "MenuBar_QMLTYPE" }}; + QTest::newRow("Universal/MenuBarItem.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "MenuBarItem_QMLTYPE" }}; + QTest::newRow("Universal/MenuItem.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "MenuItem_QMLTYPE" }}; + QTest::newRow("Universal/MenuSeparator.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "MenuSeparator_QMLTYPE" }}; + QTest::newRow("Universal/Page.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "Page_QMLTYPE" }}; + QTest::newRow("Universal/PageIndicator.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Universal/Pane.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "Pane_QMLTYPE" }}; + QTest::newRow("Universal/Popup.qml") << ignoredNames << StringPairSet { + { "QQuickOverlayAttached", "Popup_QMLTYPE" }, + { "QQuickUniversalStyle", "Popup_QMLTYPE" } + }; + QTest::newRow("Universal/ProgressBar.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "ProgressBar_QMLTYPE" }}; + QTest::newRow("Universal/RadioButton.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "RadioButton_QMLTYPE" }}; + QTest::newRow("Universal/RadioDelegate.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "RadioDelegate_QMLTYPE" }}; + QTest::newRow("Universal/RangeSlider.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "RangeSlider_QMLTYPE" }}; + QTest::newRow("Universal/RoundButton.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "RoundButton_QMLTYPE" }}; + QTest::newRow("Universal/ScrollBar.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "ScrollBar_QMLTYPE" }}; + QTest::newRow("Universal/ScrollIndicator.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "ScrollIndicator_QMLTYPE" }}; + QTest::newRow("Universal/Slider.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "Slider_QMLTYPE" }}; + QTest::newRow("Universal/SpinBox.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "SpinBox_QMLTYPE" }}; + QTest::newRow("Universal/SplitView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Universal/StackView.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Universal/SwipeDelegate.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "SwipeDelegate_QMLTYPE" }}; + QTest::newRow("Universal/Switch.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "Switch_QMLTYPE" }}; + QTest::newRow("Universal/SwitchDelegate.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "SwitchDelegate_QMLTYPE" }}; + QTest::newRow("Universal/TabBar.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "TabBar_QMLTYPE" }}; + QTest::newRow("Universal/TabButton.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "TabButton_QMLTYPE" }}; + QTest::newRow("Universal/TextArea.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "TextArea_QMLTYPE" }}; + QTest::newRow("Universal/TextField.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "TextField_QMLTYPE" }}; + QTest::newRow("Universal/ToolBar.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "ToolBar_QMLTYPE" }}; + QTest::newRow("Universal/ToolButton.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "ToolButton_QMLTYPE" }}; + QTest::newRow("Universal/ToolSeparator.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "ToolSeparator_QMLTYPE" }}; + QTest::newRow("Universal/ToolTip.qml") << ignoredNames << StringPairSet {{ "QQuickUniversalStyle", "ToolTip_QMLTYPE" }}; + QTest::newRow("Universal/Tumbler.qml") << ignoredNames << StringPairSet {}; + QTest::newRow("Universal/VerticalHeaderView.qml") << ignoredNames << StringPairSet {}; +} + +QTEST_MAIN(tst_Sanity) + +#include "tst_sanity.moc" diff --git a/tests/auto/quickcontrols2/snippets/CMakeLists.txt b/tests/auto/quickcontrols2/snippets/CMakeLists.txt new file mode 100644 index 00000000000..ce76c4fbc58 --- /dev/null +++ b/tests/auto/quickcontrols2/snippets/CMakeLists.txt @@ -0,0 +1,45 @@ +# Generated from snippets.pro. + +##################################################################### +## tst_snippets Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_snippets + SOURCES + tst_snippets.cpp + DEFINES + QQC2_SNIPPETS_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2/doc/snippets\\\" + PUBLIC_LIBRARIES + Qt::Gui + Qt::Quick + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickTemplates2 + TESTDATA ${test_data} +) + +# Resources: +set(qmake_immediate_resource_files + "qtquickcontrols2.conf" +) + +qt_internal_add_resource(tst_snippets "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + + +#### Keys ignored in scope 1:.:.:snippets.pro:<TRUE>: +# OTHER_FILES = "$$PWD/data/*.qml" +# TEMPLATE = "app" + +## Scopes: +##################################################################### diff --git a/tests/auto/quickcontrols2/snippets/data/dependencies.qml b/tests/auto/quickcontrols2/snippets/data/dependencies.qml new file mode 100644 index 00000000000..8785d0b08e8 --- /dev/null +++ b/tests/auto/quickcontrols2/snippets/data/dependencies.qml @@ -0,0 +1,7 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Controls.Universal + +Control { } diff --git a/tests/auto/quickcontrols2/snippets/qtquickcontrols2.conf b/tests/auto/quickcontrols2/snippets/qtquickcontrols2.conf new file mode 100644 index 00000000000..bd157776843 --- /dev/null +++ b/tests/auto/quickcontrols2/snippets/qtquickcontrols2.conf @@ -0,0 +1,3 @@ +# Specify the style here so that it can be overridden by e.g. command line arguments. +[Controls] +Style=Basic diff --git a/tests/auto/quickcontrols2/snippets/tst_snippets.cpp b/tests/auto/quickcontrols2/snippets/tst_snippets.cpp new file mode 100644 index 00000000000..6be53d274e1 --- /dev/null +++ b/tests/auto/quickcontrols2/snippets/tst_snippets.cpp @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest> +#include <QtQuick> +#include <QtQuickControls2/qquickstyle.h> +#include <QtQuickControls2/private/qquickstyle_p.h> + +typedef QPair<QString, QString> QStringPair; + +class tst_Snippets : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + + void verify(); + void verify_data(); + +private: + void loadSnippet(const QString &source); + + bool takeScreenshots; + QMap<QString, QStringPair> snippetPaths; +}; + +static QMap<QString, QStringPair> findSnippets(const QDir &inputDir, const QDir &outputDir = QDir()) +{ + QMap<QString, QStringPair> snippetPaths; + QDirIterator it(inputDir.path(), QStringList() << "qtquick*.qml" << "qtlabs*.qml", QDir::Files | QDir::Readable); + while (it.hasNext()) { + QFileInfo fi(it.next()); + const QString outDirPath = !outputDir.path().isEmpty() ? outputDir.filePath(fi.baseName() + ".png") : QString(); + snippetPaths.insert(fi.baseName(), qMakePair(fi.filePath(), outDirPath)); + } + return snippetPaths; +} + +void tst_Snippets::initTestCase() +{ + qInfo() << "Snippets are taken from" << QQC2_SNIPPETS_PATH; + + QDir snippetsDir(QQC2_SNIPPETS_PATH); + QVERIFY(!snippetsDir.path().isEmpty()); + + QDir screenshotsDir(QDir::current().filePath("screenshots")); + + takeScreenshots = qEnvironmentVariableIntValue("SCREENSHOTS"); + if (takeScreenshots) + QVERIFY(screenshotsDir.exists() || QDir::current().mkpath("screenshots")); + + snippetPaths = findSnippets(snippetsDir, screenshotsDir); + QVERIFY(!snippetPaths.isEmpty()); +} + +Q_DECLARE_METATYPE(QList<QQmlError>) + +void tst_Snippets::verify() +{ + QFETCH(QString, input); + QFETCH(QString, output); + + QQmlEngine engine; + QQmlComponent component(&engine); + + qRegisterMetaType<QList<QQmlError> >(); + QSignalSpy warnings(&engine, SIGNAL(warnings(QList<QQmlError>))); + QVERIFY(warnings.isValid()); + + QUrl url = QUrl::fromLocalFile(input); + component.loadUrl(url); + + QScopedPointer<QObject> root(component.create()); + QVERIFY2(!root.isNull(), qPrintable(component.errorString())); + + QCOMPARE(component.status(), QQmlComponent::Ready); + QVERIFY(component.errors().isEmpty()); + + QVERIFY(warnings.isEmpty()); + + if (takeScreenshots) { + const QString currentDataTag = QLatin1String(QTest::currentDataTag()); + static const QString applicationStyle = QQuickStyle::name().isEmpty() ? "Basic" : QQuickStyle::name(); + static const QStringList builtInStyles = QQuickStylePrivate::builtInStyles(); + + bool isStyledSnippet = false; + const QString snippetStyle = currentDataTag.section("-", 1, 1); + for (const QString &style : builtInStyles) { + if (!snippetStyle.compare(style, Qt::CaseInsensitive)) { + if (applicationStyle != style) + QSKIP(qPrintable(QString("%1 style specific snippet. Running with the %2 style.").arg(style, applicationStyle))); + isStyledSnippet = true; + } + } + + if (!isStyledSnippet && !applicationStyle.isEmpty()) { + int index = output.indexOf("-", output.lastIndexOf("/")); + if (index != -1) + output.insert(index, "-" + applicationStyle.toLower()); + } + + QQuickWindow *window = qobject_cast<QQuickWindow *>(root.data()); + if (!window) { + QQuickView *view = new QQuickView; + view->setContent(url, &component, root.data()); + window = view; + } + + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QSharedPointer<QQuickItemGrabResult> result = window->contentItem()->grabToImage(); + QSignalSpy spy(result.data(), SIGNAL(ready())); + QVERIFY(spy.isValid()); + QVERIFY(spy.wait()); + QVERIFY(result->saveToFile(output)); + + window->close(); + } +} + +void tst_Snippets::verify_data() +{ + QTest::addColumn<QString>("input"); + QTest::addColumn<QString>("output"); + + QMap<QString, QStringPair>::const_iterator it; + for (it = snippetPaths.constBegin(); it != snippetPaths.constEnd(); ++it) + QTest::newRow(qPrintable(it.key())) << it.value().first << it.value().second; +} + +QTEST_MAIN(tst_Snippets) + +#include "tst_snippets.moc" diff --git a/tests/auto/quickcontrols2/styleimports/CMakeLists.txt b/tests/auto/quickcontrols2/styleimports/CMakeLists.txt new file mode 100644 index 00000000000..0bdcce6774d --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/CMakeLists.txt @@ -0,0 +1,65 @@ +# Generated from styleimports.pro. + +##################################################################### +## tst_styleimports Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_styleimports + SOURCES + tst_styleimports.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2ImplPrivate + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +# Resources: +set(qmake_resourcestyle_resource_files + "resources/ResourceStyle/Button.qml" + "resources/ResourceStyle/qmldir" +) + +qt_internal_add_resource(tst_styleimports "qmake_resourcestyle" + PREFIX + "/" + BASE + "resources" + FILES + ${qmake_resourcestyle_resource_files} +) + + +#### Keys ignored in scope 1:.:.:styleimports.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" "data/qmldir" "data/FileSystemStyle/*.qml" "data/FileSystemStyle/qmldir" "data/PlatformStyle/*.qml" "data/PlatformStyle/+linux/*.qml" "data/PlatformStyle/+macos/*.qml" "data/PlatformStyle/+windows/*.qml" "data/PlatformStyle/qmldir" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_styleimports CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_styleimports CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/styleimports/data/+FileSystemStyle/CustomComponent.qml b/tests/auto/quickcontrols2/styleimports/data/+FileSystemStyle/CustomComponent.qml new file mode 100644 index 00000000000..ee5ffe1151c --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/+FileSystemStyle/CustomComponent.qml @@ -0,0 +1,5 @@ +import QtQuick + +Item { + objectName: "+FileSystemStyle/CustomComponent.qml" +} diff --git a/tests/auto/quickcontrols2/styleimports/data/CustomComponent.qml b/tests/auto/quickcontrols2/styleimports/data/CustomComponent.qml new file mode 100644 index 00000000000..220630f8120 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/CustomComponent.qml @@ -0,0 +1,5 @@ +import QtQuick + +Item { + objectName: "CustomComponent.qml" +} diff --git a/tests/auto/quickcontrols2/styleimports/data/applicationWindowWithButton.qml b/tests/auto/quickcontrols2/styleimports/data/applicationWindowWithButton.qml new file mode 100644 index 00000000000..ba6af22ce9e --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/applicationWindowWithButton.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + title: "Test Application Window" + width: 400 + height: 400 + + property alias button: button + + Button { + id: button + } +} diff --git a/tests/auto/quickcontrols2/styleimports/data/customStyleSelector.qml b/tests/auto/quickcontrols2/styleimports/data/customStyleSelector.qml new file mode 100644 index 00000000000..7d368421318 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/customStyleSelector.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + title: "Test Application Window" + width: 400 + height: 400 + + property alias customComponent: customComponent + + CustomComponent { + id: customComponent + } +} diff --git a/tests/auto/quickcontrols2/styleimports/data/styles/FileSystemStyle/Action.qml b/tests/auto/quickcontrols2/styleimports/data/styles/FileSystemStyle/Action.qml new file mode 100644 index 00000000000..fcf336e983a --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/styles/FileSystemStyle/Action.qml @@ -0,0 +1,4 @@ +import QtQuick.Templates as T +T.Action { + objectName: "FileSystemStyle" +} diff --git a/tests/auto/quickcontrols2/styleimports/data/styles/FileSystemStyle/Button.qml b/tests/auto/quickcontrols2/styleimports/data/styles/FileSystemStyle/Button.qml new file mode 100644 index 00000000000..a5078b14c2a --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/styles/FileSystemStyle/Button.qml @@ -0,0 +1,4 @@ +import QtQuick.Templates as T +T.Button { + objectName: "FileSystemStyle" +} diff --git a/tests/auto/quickcontrols2/styleimports/data/styles/FileSystemStyle/Label.qml b/tests/auto/quickcontrols2/styleimports/data/styles/FileSystemStyle/Label.qml new file mode 100644 index 00000000000..3233d3646b1 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/styles/FileSystemStyle/Label.qml @@ -0,0 +1,4 @@ +import QtQuick.Templates as T +T.Label { + objectName: "FileSystemStyle" +} diff --git a/tests/auto/quickcontrols2/styleimports/data/styles/FileSystemStyle/qmldir b/tests/auto/quickcontrols2/styleimports/data/styles/FileSystemStyle/qmldir new file mode 100644 index 00000000000..5deb93b6539 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/styles/FileSystemStyle/qmldir @@ -0,0 +1,4 @@ +module FileSystemStyle +Action 2.15 Action.qml +Button 2.15 Button.qml +Label 2.15 Label.qml diff --git a/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/+linux/Button.qml b/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/+linux/Button.qml new file mode 100644 index 00000000000..15c04d77214 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/+linux/Button.qml @@ -0,0 +1,4 @@ +import QtQuick.Templates as T +T.Button { + objectName: "PlatformStyle/+linux" +} diff --git a/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/+macos/Button.qml b/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/+macos/Button.qml new file mode 100644 index 00000000000..6c07ec028a0 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/+macos/Button.qml @@ -0,0 +1,4 @@ +import QtQuick.Templates as T +T.Button { + objectName: "PlatformStyle/+macos" +} diff --git a/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/+windows/Button.qml b/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/+windows/Button.qml new file mode 100644 index 00000000000..6a94679c2b6 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/+windows/Button.qml @@ -0,0 +1,4 @@ +import QtQuick.Templates as T +T.Button { + objectName: "PlatformStyle/+windows" +} diff --git a/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/Button.qml b/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/Button.qml new file mode 100644 index 00000000000..fce35efdf77 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/Button.qml @@ -0,0 +1,4 @@ +import QtQuick.Templates as T +T.Button { + objectName: "PlatformStyle/Button.qml" +} diff --git a/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/qmldir b/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/qmldir new file mode 100644 index 00000000000..ce2545171bf --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/data/styles/PlatformStyle/qmldir @@ -0,0 +1,2 @@ +module PlatformStyle +Button 2.15 Button.qml diff --git a/tests/auto/quickcontrols2/styleimports/resources/ResourceStyle/Button.qml b/tests/auto/quickcontrols2/styleimports/resources/ResourceStyle/Button.qml new file mode 100644 index 00000000000..3a97e9de1f2 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/resources/ResourceStyle/Button.qml @@ -0,0 +1,9 @@ +import QtQuick.Controls.impl 2.15 +import QtQuick.Templates 2.15 as T +T.Button { + objectName: "ResourceStyle" + + contentItem: IconLabel { + color: "salmon" + } +} diff --git a/tests/auto/quickcontrols2/styleimports/resources/ResourceStyle/qmldir b/tests/auto/quickcontrols2/styleimports/resources/ResourceStyle/qmldir new file mode 100644 index 00000000000..4cb1a835bdf --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/resources/ResourceStyle/qmldir @@ -0,0 +1,2 @@ +module ResourceStyle +Button 2.15 Button.qml diff --git a/tests/auto/quickcontrols2/styleimports/tst_styleimports.cpp b/tests/auto/quickcontrols2/styleimports/tst_styleimports.cpp new file mode 100644 index 00000000000..bdd3a40cea4 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimports/tst_styleimports.cpp @@ -0,0 +1,273 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qregularexpression.h> +#include <QtTest/qtest.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlapplicationengine.h> +#include <QtQml/qqmlengine.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickControls2/qquickstyle.h> +#include <QtQuickControls2/private/qquickstyle_p.h> +#include <QtQuickControls2Impl/private/qquickiconlabel_p.h> + +class tst_StyleImports : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_StyleImports(); + +private slots: + void initTestCase() override; + + void cleanup(); + + void select_data(); + void select(); + + void platformSelectors(); + void customStyleSelector(); + + void fallbackStyleShouldNotOverwriteTheme_data(); + void fallbackStyleShouldNotOverwriteTheme(); +}; + +tst_StyleImports::tst_StyleImports() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_StyleImports::initTestCase() +{ + QQmlDataTest::initTestCase(); +} + +void tst_StyleImports::cleanup() +{ + qmlClearTypeRegistrations(); +} + +void tst_StyleImports::select_data() +{ + QTest::addColumn<QString>("file"); + QTest::addColumn<QString>("style"); + QTest::addColumn<QString>("fallback"); + QTest::addColumn<QString>("expected"); + + // Action.qml exists in the FileSystemStyle style and the Basic style. + QTest::newRow("control=Action,style=basic,fallback=empty") << "Action.qml" << "Basic" << "" << "Basic"; + QTest::newRow("control=Action,style=fs,fallback=empty") << "Action.qml" << "FileSystemStyle" << "" << "FileSystemStyle"; + QTest::newRow("control=Action,style=qrc,fallback=empty") << "Action.qml" << "ResourceStyle" << "" << "Basic"; + QTest::newRow("control=Action,style=nosuch,fallback=empty") << "Action.qml" << "NoSuchStyle" << "" << "Basic"; + + QTest::newRow("control=Action,style=basic,fallback=mat") << "Action.qml" << "Basic" << "Material" << ""; + QTest::newRow("control=Action,style=fs,fallback=mat") << "Action.qml" << "FileSystemStyle" << "Material" << "FileSystemStyle"; + QTest::newRow("control=Action,style=qrc,fallback=mat") << "Action.qml" << "ResourceStyle" << "Material" << "Basic"; + QTest::newRow("control=Action,style=nosuch,fallback=mat") << "Action.qml" << "NoSuchStyle" << "Material" << "Basic"; + + // Amongst the styles we're testing here, ScrollView.qml only exists in the Basic style. + QTest::newRow("control=ScrollView,style=basic,fallback=empty") << "ScrollView.qml" << "Basic" << "" << "Basic"; + QTest::newRow("control=ScrollView,style=fs,fallback=empty") << "ScrollView.qml" << "FileSystemStyle" << "" << "Basic"; + QTest::newRow("control=ScrollView,style=qrc,fallback=empty") << "ScrollView.qml" << "ResourceStyle" << "" << "Basic"; + QTest::newRow("control=ScrollView,style=nosuch,fallback=empty") << "ScrollView.qml" << "NoSuchStyle" << "" << "Basic"; + + QTest::newRow("control=ScrollView,style=basic,fallback=mat") << "ScrollView.qml" << "Basic" << "Material" << "Basic"; + QTest::newRow("control=ScrollView,style=fs,fallback=mat") << "ScrollView.qml" << "FileSystemStyle" << "Material" << "Basic"; + QTest::newRow("control=ScrollView,style=qrc,fallback=mat") << "ScrollView.qml" << "ResourceStyle" << "Material" << "Basic"; + QTest::newRow("control=ScrollView,style=nosuch,fallback=mat") << "ScrollView.qml" << "NoSuchStyle" << "Material" << "Basic"; + + // Label.qml exists in the FileSystemStyle, Basic and Material styles. + QTest::newRow("control=Label,style=basic,fallback=empty") << "Label.qml" << "Basic" << "" << "Basic"; + QTest::newRow("control=Label,style=fs,fallback=empty") << "Label.qml" << "FileSystemStyle" << "" << "FileSystemStyle"; + QTest::newRow("control=Label,style=qrc,fallback=empty") << "Label.qml" << "ResourceStyle" << "" << "Basic"; + QTest::newRow("control=Label,style=nosuch,fallback=empty") << "Label.qml" << "NoSuchStyle" << "" << "Basic"; + + QTest::newRow("control=Label,style=basic,fallback=mat") << "Label.qml" << "Basic" << "Material" << "Basic"; + QTest::newRow("control=Label,style=fs,fallback=mat") << "Label.qml" << "FileSystemStyle" << "Material" << "FileSystemStyle"; + QTest::newRow("control=Label,style=qrc,fallback=mat") << "Label.qml" << "ResourceStyle" << "Material" << "Basic"; + QTest::newRow("control=Label,style=nosuch,fallback=mat") << "Label.qml" << "NoSuchStyle" << "Material" << "Basic"; + + // Button.qml exists in all styles including the fs and qrc styles + QTest::newRow("control=Button,style=basic,fallback=empty") << "Button.qml" << "Basic" << "" << "Basic"; + QTest::newRow("control=Button,style=fs,fallback=empty") << "Button.qml" << "FileSystemStyle" << "" << "FileSystemStyle"; + QTest::newRow("control=Button,style=qrc,fallback=empty") << "Button.qml" << "ResourceStyle" << "" << "ResourceStyle"; + QTest::newRow("control=Button,style=nosuch,fallback=empty") << "Button.qml" << "NoSuchStyle" << "" << "Basic"; + + QTest::newRow("control=Button,style=basic,fallback=mat") << "Button.qml" << "Basic" << "Material" << "Basic"; + QTest::newRow("control=Button,style=fs,fallback=mat") << "Button.qml" << "FileSystemStyle" << "Material" << "FileSystemStyle"; + QTest::newRow("control=Button,style=qrc,fallback=mat") << "Button.qml" << "ResourceStyle" << "Material" << "ResourceStyle"; + QTest::newRow("control=Button,style=nosuch,fallback=mat") << "Button.qml" << "NoSuchStyle" << "Material" << "Basic"; +} + +void tst_StyleImports::select() +{ + QFETCH(QString, file); + QFETCH(QString, style); + QFETCH(QString, fallback); + QFETCH(QString, expected); + + // In Qt 5, there were several accepted forms for style names. + // In Qt 6, the only accepted form is the base name of the style directory. + const bool invalidStyleName = style.contains(QLatin1Char('/')); + if (invalidStyleName) + QTest::ignoreMessage(QtWarningMsg, + "Style names must not contain paths; see the \"Definition of a Style\" documentation for more information"); + QQuickStyle::setStyle(style); + QQuickStyle::setFallbackStyle(fallback); + + QQmlEngine engine; + engine.addImportPath(QLatin1String(":/")); +// engine.addImportPath(directory()); + engine.addImportPath(dataDirectory() + QLatin1String("/styles")); + QQmlComponent component(&engine); + const QString controlName = file.mid(0, file.indexOf(QLatin1Char('.'))); + component.setData(QString::fromLatin1("import QtQuick; import QtQuick.Controls; %1 { }").arg(controlName).toUtf8(), QUrl()); + + const bool nonExistentStyle = style == QLatin1String("NoSuchStyle"); + if (nonExistentStyle) + QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready"); + QScopedPointer<QObject> object(component.create()); + if (nonExistentStyle) { + QVERIFY(object.isNull()); + return; + } + + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + // TODO: test built-in styles below too + // We can't check for the attached style object since that API is in a plugin, + // and it's not possible to use e.g. the baseUrl of the QQmlContext + // nor the metaObject to test it either. + + if (!QQuickStylePrivate::builtInStyles().contains(expected)) { + // We're expecting a custom style. + QCOMPARE(object->objectName(), expected); + } +} + +// Tests that the various platforms are available as selectors. +void tst_StyleImports::platformSelectors() +{ + QQuickStyle::setStyle(QLatin1String("PlatformStyle")); + + QQmlApplicationEngine engine; + engine.addImportPath(dataDirectory() + QLatin1String("/styles")); + engine.load(testFileUrl("applicationWindowWithButton.qml")); + QVERIFY(!engine.rootObjects().isEmpty()); + QQuickWindow *window = qobject_cast<QQuickWindow*>(engine.rootObjects().first()); + QVERIFY(window); + + QObject *button = window->property("button").value<QObject*>(); + QVERIFY(button); + +#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) + QCOMPARE(button->objectName(), "PlatformStyle/+linux"); +#elif defined(Q_OS_MACOS) + QCOMPARE(button->objectName(), "PlatformStyle/+macos"); +#elif defined(Q_OS_WIN) + QCOMPARE(button->objectName(), "PlatformStyle/+windows"); +#else + QCOMPARE(button->objectName(), "PlatformStyle/Button.qml"); +#endif +} + +// Tests that a file selector is added for custom styles. +// Note that this is different to the regular QML import mechanism +// that results in e.g. FileSystemStyle/Button.qml being found; +// it allows non-template (Controls), custom user types to be +// picked up via selectors. +void tst_StyleImports::customStyleSelector() +{ + QQuickStyle::setStyle(QLatin1String("FileSystemStyle")); + + QQmlApplicationEngine engine; + engine.addImportPath(dataDirectory() + QLatin1String("/styles")); + engine.load(testFileUrl("customStyleSelector.qml")); + QVERIFY(!engine.rootObjects().isEmpty()); + QQuickWindow *window = qobject_cast<QQuickWindow*>(engine.rootObjects().first()); + QVERIFY(window); + + QObject *customComponent = window->property("customComponent").value<QObject*>(); + QVERIFY(customComponent); + QCOMPARE(customComponent->objectName(), "+FileSystemStyle/CustomComponent.qml"); +} + +void tst_StyleImports::fallbackStyleShouldNotOverwriteTheme_data() +{ + QTest::addColumn<QString>("style"); + QTest::addColumn<QString>("fallbackStyle"); + QTest::addColumn<QColor>("expectedContentItemColor"); + + QTest::addRow("style=Fusion,fallbackStyle=Material") + << QString::fromLatin1("Fusion") << QString::fromLatin1("Material") << QColor::fromRgb(0x252525); + QTest::addRow("style=ResourceStyle,fallbackStyle=Material") + << QString::fromLatin1("ResourceStyle") << QString::fromLatin1("Material") << QColor("salmon"); +} + +void tst_StyleImports::fallbackStyleShouldNotOverwriteTheme() +{ + QFETCH(QString, style); + QFETCH(QString, fallbackStyle); + QFETCH(QColor, expectedContentItemColor); + + QQuickStyle::setStyle(style); + QQuickStyle::setFallbackStyle(fallbackStyle); + + QQmlApplicationEngine engine; + engine.addImportPath(QLatin1String(":/")); + engine.addImportPath(dataDirectory()); + engine.load(testFileUrl("applicationWindowWithButton.qml")); + QVERIFY(!engine.rootObjects().isEmpty()); + QQuickWindow *window = qobject_cast<QQuickWindow*>(engine.rootObjects().first()); + QVERIFY(window); + + QObject *button = window->property("button").value<QObject*>(); + QVERIFY(button); + + QQuickIconLabel *contentItem = button->property("contentItem").value<QQuickIconLabel*>(); + QVERIFY(contentItem); + + // For example: the Fusion style provides Button.qml, so the Button's text color + // should be that of QPalette::ButtonText from QQuickFusionTheme. + QCOMPARE(contentItem->color(), expectedContentItemColor); +} + +QTEST_MAIN(tst_StyleImports) + +#include "tst_styleimports.moc" diff --git a/tests/auto/quickcontrols2/styleimportscompiletimematerial/CMakeLists.txt b/tests/auto/quickcontrols2/styleimportscompiletimematerial/CMakeLists.txt new file mode 100644 index 00000000000..361ceb9f171 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimportscompiletimematerial/CMakeLists.txt @@ -0,0 +1,48 @@ +# Generated from styleimportscompiletimematerial.pro. + +##################################################################### +## tst_styleimportscompiletimematerial Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_styleimportscompiletimematerial + SOURCES + tst_styleimportscompiletimematerial.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:styleimportscompiletimematerial.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_styleimportscompiletimematerial CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_styleimportscompiletimematerial CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/styleimportscompiletimematerial/data/importMaterialStyleWithoutControls.qml b/tests/auto/quickcontrols2/styleimportscompiletimematerial/data/importMaterialStyleWithoutControls.qml new file mode 100644 index 00000000000..7cb4fd5883f --- /dev/null +++ b/tests/auto/quickcontrols2/styleimportscompiletimematerial/data/importMaterialStyleWithoutControls.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls.Material + +ApplicationWindow { + title: "Test Application Window" + width: 400 + height: 400 + + property alias button: button + + Button { + id: button + text: "Material Button" + } +} diff --git a/tests/auto/quickcontrols2/styleimportscompiletimematerial/tst_styleimportscompiletimematerial.cpp b/tests/auto/quickcontrols2/styleimportscompiletimematerial/tst_styleimportscompiletimematerial.cpp new file mode 100644 index 00000000000..52833c52ec9 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimportscompiletimematerial/tst_styleimportscompiletimematerial.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qregularexpression.h> +#include <QtTest/qtest.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlapplicationengine.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/private/qqmlmetatype_p.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickControls2/qquickstyle.h> +#include <QtQuickControls2/private/qquickstyle_p.h> +#include <QtQuickTemplates2/private/qquickbutton_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> + +using namespace QQuickVisualTestUtils; +using namespace QQuickControlsTestUtils; + +class tst_StyleImportsCompileTimeMaterial : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_StyleImportsCompileTimeMaterial(); + +private slots: + void importMaterialStyleWithoutControls(); +}; + +tst_StyleImportsCompileTimeMaterial::tst_StyleImportsCompileTimeMaterial() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_StyleImportsCompileTimeMaterial::importMaterialStyleWithoutControls() +{ + QQuickControlsApplicationHelper helper(this, QLatin1String("importMaterialStyleWithoutControls.qml")); + QVERIFY2(helper.ready, helper.failureMessage()); + + auto button = helper.window->property("button").value<QQuickButton*>(); + QVERIFY(button); + // The Material style sets a size 14 font for Button. + QCOMPARE(button->font().pixelSize(), 14); + const QTypeRevision latestControlsRevision = QQmlMetaType::latestModuleVersion(QLatin1String("QtQuick.Controls")); + QVERIFY2(!latestControlsRevision.isValid(), "QtQuick.Controls should not be imported when using compile-time style selection"); +} + +QTEST_MAIN(tst_StyleImportsCompileTimeMaterial) + +#include "tst_styleimportscompiletimematerial.moc" diff --git a/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/CMakeLists.txt b/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/CMakeLists.txt new file mode 100644 index 00000000000..ca1a4f51ba8 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/CMakeLists.txt @@ -0,0 +1,48 @@ +# Generated from styleimportscompiletimeqmlonly.pro. + +##################################################################### +## tst_styleimportscompiletimeqmlonly Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_styleimportscompiletimeqmlonly + SOURCES + tst_styleimportscompiletimeqmlonly.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:styleimportscompiletimeqmlonly.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" "data/QmlOnly/*.qml" "data/QmlOnly/qmldir" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_styleimportscompiletimeqmlonly CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_styleimportscompiletimeqmlonly CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/data/QmlOnly/Button.qml b/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/data/QmlOnly/Button.qml new file mode 100644 index 00000000000..73d94c1ce1c --- /dev/null +++ b/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/data/QmlOnly/Button.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Templates as T + +T.Button { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + horizontalPadding: padding + 2 + spacing: 6 + font.pixelSize: 8 + + contentItem: T.Label { + text: control.text + font: control.font + color: control.checked || control.highlighted ? control.palette.brightText : + control.flat && !control.down ? (control.visualFocus ? control.palette.highlight : control.palette.windowText) : control.palette.buttonText + verticalAlignment: T.Label.AlignVCenter + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + visible: !control.flat || control.down || control.checked || control.highlighted + color: "#ccc" + border.color: control.palette.highlight + border.width: control.visualFocus ? 2 : 0 + } +} diff --git a/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/data/QmlOnly/qmldir b/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/data/QmlOnly/qmldir new file mode 100644 index 00000000000..5e60f095342 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/data/QmlOnly/qmldir @@ -0,0 +1,3 @@ +module QmlOnly +Button 1.0 Button.qml +import QtQuick.Controls.Basic diff --git a/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/data/importQmlOnlyStyleWithoutControls.qml b/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/data/importQmlOnlyStyleWithoutControls.qml new file mode 100644 index 00000000000..027d5636be9 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/data/importQmlOnlyStyleWithoutControls.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QmlOnly + +ApplicationWindow { + title: "Test Application Window" + width: 400 + height: 400 + + property alias button: button + + Button { + id: button + text: "QmlOnly Button" + } +} diff --git a/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/dummy_imports.qml b/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/dummy_imports.qml new file mode 100644 index 00000000000..aa37fd14b0e --- /dev/null +++ b/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/dummy_imports.qml @@ -0,0 +1,8 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQuick +import QtQuick.Controls.Basic + +QtObject { } diff --git a/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/tst_styleimportscompiletimeqmlonly.cpp b/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/tst_styleimportscompiletimeqmlonly.cpp new file mode 100644 index 00000000000..3734d7df9e7 --- /dev/null +++ b/tests/auto/quickcontrols2/styleimportscompiletimeqmlonly/tst_styleimportscompiletimeqmlonly.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qregularexpression.h> +#include <QtTest/qtest.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlapplicationengine.h> +#include <QtQml/qqmlengine.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> +#include <QtQuickControls2/qquickstyle.h> +#include <QtQuickControls2/private/qquickstyle_p.h> +#include <QtQuickTemplates2/private/qquickbutton_p.h> + +using namespace QQuickControlsTestUtils; + +class tst_StyleImportsCompileTimeQmlOnly : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_StyleImportsCompileTimeQmlOnly(); + +private slots: + void importQmlOnlyStyleWithoutControls(); +}; + +tst_StyleImportsCompileTimeQmlOnly::tst_StyleImportsCompileTimeQmlOnly() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_StyleImportsCompileTimeQmlOnly::importQmlOnlyStyleWithoutControls() +{ + QQuickControlsApplicationHelper helper(this, + QLatin1String("importQmlOnlyStyleWithoutControls.qml"), {}, QStringList() << dataDirectory()); + QVERIFY2(helper.ready, helper.failureMessage()); + + auto button = helper.window->property("button").value<QQuickButton*>(); + QVERIFY(button); + QCOMPARE(button->font().pixelSize(), 8); +} + +QTEST_MAIN(tst_StyleImportsCompileTimeQmlOnly) + +#include "tst_styleimportscompiletimeqmlonly.moc" diff --git a/tests/auto/quickcontrols2/translation/CMakeLists.txt b/tests/auto/quickcontrols2/translation/CMakeLists.txt new file mode 100644 index 00000000000..cbb8b30c955 --- /dev/null +++ b/tests/auto/quickcontrols2/translation/CMakeLists.txt @@ -0,0 +1,62 @@ +# Generated from translation.pro. + +##################################################################### +## tst_translation Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_translation + SOURCES + tst_translation.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +# Resources: +set(qmake_immediate_resource_files + "qml_jp.qm" + "qtbase_fr.qm" +) + +qt_internal_add_resource(tst_translation "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + + +#### Keys ignored in scope 1:.:.:translation.pro:<TRUE>: +# OTHER_FILES = "data/*.qml" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_translation CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_translation CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickcontrols2/translation/data/comboBox.qml b/tests/auto/quickcontrols2/translation/data/comboBox.qml new file mode 100644 index 00000000000..cba1cf0c232 --- /dev/null +++ b/tests/auto/quickcontrols2/translation/data/comboBox.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +ComboBox { + objectName: "comboBox" + textRole: "label" + model: ListModel { + ListElement { + label: qsTr("Hello") + } + ListElement { + label: qsTr("ListView") + } + } +} diff --git a/tests/auto/quickcontrols2/translation/data/dialogButtonBox.qml b/tests/auto/quickcontrols2/translation/data/dialogButtonBox.qml new file mode 100644 index 00000000000..fd8f9548a2e --- /dev/null +++ b/tests/auto/quickcontrols2/translation/data/dialogButtonBox.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + property Dialog dialog: Dialog { + width: 300 + height: 300 + visible: true + standardButtons: DialogButtonBox.Save | DialogButtonBox.Discard + } +} diff --git a/tests/auto/quickcontrols2/translation/data/dialogButtonBoxWithCustomButtons.qml b/tests/auto/quickcontrols2/translation/data/dialogButtonBoxWithCustomButtons.qml new file mode 100644 index 00000000000..bf0fb512a79 --- /dev/null +++ b/tests/auto/quickcontrols2/translation/data/dialogButtonBoxWithCustomButtons.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + property Dialog dialog: Dialog { + width: 300 + height: 300 + visible: true + + footer: DialogButtonBox { + Button { + objectName: "okButton" + text: qsTr("OK") + + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + } + Button { + objectName: "cancelButton" + text: qsTr("Cancel") + + DialogButtonBox.buttonRole: DialogButtonBox.RejectRole + } + } + } +} diff --git a/tests/auto/quickcontrols2/translation/data/stackView.qml b/tests/auto/quickcontrols2/translation/data/stackView.qml new file mode 100644 index 00000000000..55748d219a5 --- /dev/null +++ b/tests/auto/quickcontrols2/translation/data/stackView.qml @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Window + +Window { + id: window + width: 640 + height: 480 + + property var engine + + signal calledTranslate + + property int pagesCreated: 0 + + Component { + id: translatePageComponent + Item { + id: root + + Component.onCompleted: objectName = "translatePageRootItem" + pagesCreated++ + + StackView.onActivating: { + retranslateTimer.start() + } + + Timer { + id: retranslateTimer + objectName: "retranslateTimer" + interval: 100 + repeat: true + + property int count: 0 + + onTriggered: { + + // This triggers the crash without retranslate(). + // retranslate() got cleverer in 6.2, sidestepping the issue. + replaceExit.animations[0].target = null; + replaceExit.animations[0].target = replaceExit.ViewTransition.item + + console.log("timer within", root, "is about to call retranslate") + window.engine.retranslate() + window.calledTranslate() + count++ + if(count >= 10) { + stop() + count = 0 + } + } + } + + Button { + objectName: "button" + text: qsTr("Push") + onClicked: root.StackView.view.replace(translatePageComponent) + } + } + } + + StackView { + id: stack + objectName: "stackView" + anchors.fill: parent + initialItem: translatePageComponent + + replaceEnter: Transition { + id: replaceEnter + objectName: "enterTransition" + + PropertyAnimation { + objectName: replaceEnter.objectName + "PropertyAnimation" + target: replaceEnter.ViewTransition.item + property: "opacity" + from: 0 + to: 1 + duration: 10 + } + + } + + replaceExit: Transition { + id: replaceExit + objectName: "exitTransition" + + PropertyAnimation { + objectName: replaceExit.objectName + "PropertyAnimation" + target: replaceExit.ViewTransition.item + property: "opacity" + from: 1 + to: 0 + duration: 10 + } + } + } +} + diff --git a/tests/auto/quickcontrols2/translation/qml_jp.qm b/tests/auto/quickcontrols2/translation/qml_jp.qm new file mode 100644 index 00000000000..a3712e9964e Binary files /dev/null and b/tests/auto/quickcontrols2/translation/qml_jp.qm differ diff --git a/tests/auto/quickcontrols2/translation/qml_jp.ts b/tests/auto/quickcontrols2/translation/qml_jp.ts new file mode 100644 index 00000000000..303c142fd8e --- /dev/null +++ b/tests/auto/quickcontrols2/translation/qml_jp.ts @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="ja_JP"> +<context> + <name>main</name> + <message> + <location filename="../main.qml" line="8"/> + <source>Hello World</source> + <translation>こんにちは世界</translation> + </message> + <message> + <location filename="../main.qml" line="12"/> + <source>Hello Text</source> + <translation>ハローテキスト</translation> + </message> + <message> + <location filename="../main.qml" line="35"/> + <source>Hello</source> + <translation>こんにちは</translation> + </message> + <message> + <location filename="../main.qml" line="38"/> + <source>ListView</source> + <translation>リストビュー</translation> + </message> +</context> +</TS> + diff --git a/tests/auto/quickcontrols2/translation/qtbase_fr.qm b/tests/auto/quickcontrols2/translation/qtbase_fr.qm new file mode 100644 index 00000000000..176675a8204 Binary files /dev/null and b/tests/auto/quickcontrols2/translation/qtbase_fr.qm differ diff --git a/tests/auto/quickcontrols2/translation/qtbase_fr.ts b/tests/auto/quickcontrols2/translation/qtbase_fr.ts new file mode 100644 index 00000000000..7aff8bd7601 --- /dev/null +++ b/tests/auto/quickcontrols2/translation/qtbase_fr.ts @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="fr_FR"> +<context> + <name>QPlatformTheme</name> + <message> + <source>Save</source> + <translation>Enregistrer</translation> + </message> + <message> + <source>Discard</source> + <translation>Ne pas tenir compte</translation> + </message> +</context> +<context> + <name>QGnomeTheme</name> + <message> + <source>&Save</source> + <translation>&Enregistrer</translation> + </message> +</context> +</TS> + diff --git a/tests/auto/quickcontrols2/translation/tst_translation.cpp b/tests/auto/quickcontrols2/translation/tst_translation.cpp new file mode 100644 index 00000000000..5d215df8289 --- /dev/null +++ b/tests/auto/quickcontrols2/translation/tst_translation.cpp @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qsignalspy.h> +#include <QtTest/qtest.h> +#include <QtCore/qtranslator.h> +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtQuick/qquickview.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h> +#include <QtQuickTemplates2/private/qquicktextfield_p.h> +#include <QtQuickControls2/qquickstyle.h> + +using namespace QQuickControlsTestUtils; +using namespace QQuickVisualTestUtils; + +class tst_translation : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_translation(); + +private slots: + void dialogButtonBox(); + void dialogButtonBoxWithCustomButtons(); + void comboBox(); + void stackView(); +}; + +tst_translation::tst_translation() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ + QQuickStyle::setStyle("Basic"); +} + +void tst_translation::dialogButtonBox() +{ + QQuickView view(testFileUrl("dialogButtonBox.qml")); + if (view.status() != QQuickView::Ready) + QFAIL("Failed to load QML file"); + view.show(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickDialog *dialog = view.rootObject()->property("dialog").value<QQuickDialog*>(); + QVERIFY(dialog); + + QQuickDialogButtonBox *dialogButtonBox = qobject_cast<QQuickDialogButtonBox*>(dialog->footer()); + QVERIFY(dialogButtonBox); + + QQuickAbstractButton *saveButton = dialogButtonBox->standardButton(QPlatformDialogHelper::Save); + QVERIFY(saveButton); + QString defaultSaveText = QGuiApplicationPrivate::platformTheme()->standardButtonText(QPlatformDialogHelper::Save); + defaultSaveText = QPlatformTheme::removeMnemonics(defaultSaveText); + QCOMPARE(saveButton->text(), defaultSaveText); + + QQuickAbstractButton *discardButton = dialogButtonBox->standardButton(QPlatformDialogHelper::Discard); + QVERIFY(discardButton); + QString defaultDiscardText = QGuiApplicationPrivate::platformTheme()->standardButtonText(QPlatformDialogHelper::Discard); + defaultDiscardText = QPlatformTheme::removeMnemonics(defaultDiscardText); + QCOMPARE(discardButton->text(), defaultDiscardText); + + QTranslator translator; + QVERIFY(translator.load("qtbase_fr.qm", ":/")); + QVERIFY(qApp->installTranslator(&translator)); + qApp->sendPostedEvents(); + view.engine()->retranslate(); + + QString translatedSaveText = QGuiApplicationPrivate::platformTheme()->standardButtonText(QPlatformDialogHelper::Save); + translatedSaveText = QPlatformTheme::removeMnemonics(translatedSaveText); + QCOMPARE(saveButton->text(), translatedSaveText); + + QString translatedDiscardText = QGuiApplicationPrivate::platformTheme()->standardButtonText(QPlatformDialogHelper::Discard); + translatedDiscardText = QPlatformTheme::removeMnemonics(translatedDiscardText); + QCOMPARE(discardButton->text(), translatedDiscardText); +} + +// Test that custom buttons with explicitly specified text +// do not have that text overwritten on language changes. +void tst_translation::dialogButtonBoxWithCustomButtons() +{ + // This is just a way of simulating the translator going out of scope + // after the QML has been loaded. + QScopedPointer<QTranslator> translator(new QTranslator); + // Doesn't matter which language it is, as we won't be using it anyway. + QVERIFY(translator->load("qtbase_fr.qm", ":/")); + QVERIFY(qApp->installTranslator(translator.data())); + + QQuickView view(testFileUrl("dialogButtonBoxWithCustomButtons.qml")); + if (view.status() != QQuickView::Ready) + QFAIL("Failed to load QML file"); + view.show(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQuickDialog *dialog = view.rootObject()->property("dialog").value<QQuickDialog*>(); + QVERIFY(dialog); + + QQuickDialogButtonBox *dialogButtonBox = qobject_cast<QQuickDialogButtonBox*>(dialog->footer()); + QVERIFY(dialogButtonBox); + + auto okButton = dialogButtonBox->findChild<QQuickAbstractButton*>("okButton"); + QVERIFY(okButton); + QCOMPARE(okButton->text(), QLatin1String("OK")); + + QQuickAbstractButton *cancelButton = dialogButtonBox->findChild<QQuickAbstractButton*>("cancelButton"); + QVERIFY(cancelButton); + QCOMPARE(cancelButton->text(), QLatin1String("Cancel")); + + // Delete the translator and hence cause a LanguageChange event, + // but _without_ calling QQmlEngine::retranslate(), which would + // restore the original bindings and hence not reproduce the issue. + translator.reset(); + QCOMPARE(okButton->text(), QLatin1String("OK")); + QCOMPARE(cancelButton->text(), QLatin1String("Cancel")); +} + +void tst_translation::comboBox() +{ + QQuickView view(testFileUrl("comboBox.qml")); + + QQuickComboBox *comboBox = qobject_cast<QQuickComboBox*>(view.rootObject()); + QVERIFY(comboBox); + QCOMPARE(comboBox->displayText(), QLatin1String("Hello")); + + QQuickTextField *contentItem = qobject_cast<QQuickTextField*>(comboBox->contentItem()); + QVERIFY(contentItem); + QCOMPARE(contentItem->text(), QLatin1String("Hello")); + + QTranslator translator; + QVERIFY(translator.load("qml_jp.qm", ":/")); + QVERIFY(qApp->installTranslator(&translator)); + view.engine()->retranslate(); + QTRY_COMPARE(comboBox->displayText(), QString::fromUtf8("こんにちは")); + QCOMPARE(contentItem->text(), QString::fromUtf8("こんにちは")); +} + +void tst_translation::stackView() +{ + QQuickControlsApplicationHelper helper(this, "stackView.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + QVERIFY(window->setProperty("engine", QVariant::fromValue(&helper.engine))); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QSignalSpy calledTranslateSpy(window, SIGNAL(calledTranslate())); + QVERIFY(calledTranslateSpy.isValid()); + + QQuickAbstractButton *button = window->findChild<QQuickAbstractButton*>("button"); + QVERIFY(button); + // Shouldn't crash when calling retranslate. + QVERIFY(clickButton(button)); + QTRY_COMPARE(calledTranslateSpy.count(), 1); +} + +QTEST_MAIN(tst_translation) + +#include "tst_translation.moc" diff --git a/tests/auto/quickdialogs/CMakeLists.txt b/tests/auto/quickdialogs/CMakeLists.txt new file mode 100644 index 00000000000..d26f42818ea --- /dev/null +++ b/tests/auto/quickdialogs/CMakeLists.txt @@ -0,0 +1,4 @@ +if(NOT ANDROID) # temporarily disabled until QTBUG-100991 is fixed +add_subdirectory(qquickfiledialogimpl) +add_subdirectory(qquickfontdialogimpl) +endif() diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/BLACKLIST b/tests/auto/quickdialogs/qquickfiledialogimpl/BLACKLIST new file mode 100644 index 00000000000..7601025475b --- /dev/null +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/BLACKLIST @@ -0,0 +1,11 @@ +# QTBUG-92094 +[tabFocusNavigation] +* + +# QTBUG-92585 +[fileMode:OpenFiles] +* + +# QTBUG-101488 +[goUpIntoLargeFolder] +* diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/CMakeLists.txt b/tests/auto/quickdialogs/qquickfiledialogimpl/CMakeLists.txt new file mode 100644 index 00000000000..64022f62939 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/CMakeLists.txt @@ -0,0 +1,39 @@ +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickfiledialogimpl + SOURCES + tst_qquickfiledialogimpl.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickDialogs2Private + Qt::QuickDialogs2QuickImplPrivate + Qt::QuickDialogs2UtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +qt_internal_extend_target(tst_qquickfiledialogimpl CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickfiledialogimpl CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/data/acceptRejectLabel.qml b/tests/auto/quickdialogs/qquickfiledialogimpl/data/acceptRejectLabel.qml new file mode 100644 index 00000000000..3cd526e3af2 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/data/acceptRejectLabel.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs + +ApplicationWindow { + id: window + width: 640 + height: 480 + + property alias dialog: dialog + + FileDialog { + id: dialog + acceptLabel: "AcceptTest" + rejectLabel: "RejectTest" + } +} diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/data/bindAllTxtHtmlNameFilters.qml b/tests/auto/quickdialogs/qquickfiledialogimpl/data/bindAllTxtHtmlNameFilters.qml new file mode 100644 index 00000000000..5010c4226b7 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/data/bindAllTxtHtmlNameFilters.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs + +ApplicationWindow { + width: 640 + height: 480 + + property alias dialog: dialog + + FileDialog { + id: dialog + objectName: "FileDialog" + nameFilters: ["All files (*)", "Text files (*.txt)", "HTML files (*.html)"] + } +} diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/data/bindCurrentFolder.qml b/tests/auto/quickdialogs/qquickfiledialogimpl/data/bindCurrentFolder.qml new file mode 100644 index 00000000000..03cd61bc315 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/data/bindCurrentFolder.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs + +ApplicationWindow { + id: window + width: 640 + height: 480 + + property alias dialog: dialog + required property url initialFolder + + FileDialog { + id: dialog + objectName: "FileDialog" + currentFolder: window.initialFolder + } +} diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/data/bindTitle.qml b/tests/auto/quickdialogs/qquickfiledialogimpl/data/bindTitle.qml new file mode 100644 index 00000000000..60657f58687 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/data/bindTitle.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs + +ApplicationWindow { + width: 640 + height: 480 + + property alias dialog: dialog + + FileDialog { + id: dialog + title: "Test Title" + } +} diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/data/bindTxtHtmlNameFilters.qml b/tests/auto/quickdialogs/qquickfiledialogimpl/data/bindTxtHtmlNameFilters.qml new file mode 100644 index 00000000000..1e312fbc079 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/data/bindTxtHtmlNameFilters.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs + +ApplicationWindow { + width: 640 + height: 480 + + property alias dialog: dialog + + FileDialog { + id: dialog + objectName: "FileDialog" + nameFilters: ["Text files (*.txt)", "HTML files (*.html)"] + } +} diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/data/fileDialog.qml b/tests/auto/quickdialogs/qquickfiledialogimpl/data/fileDialog.qml new file mode 100644 index 00000000000..febad45ca61 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/data/fileDialog.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs + +ApplicationWindow { + width: 640 + height: 480 + + property alias dialog: dialog + + function doneAccepted() { + dialog.done(FileDialog.Accepted) + } + + function doneRejected() { + dialog.done(FileDialog.Rejected) + } + + FileDialog { + id: dialog + objectName: "FileDialog" + } +} diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/dummy_imports.qml b/tests/auto/quickdialogs/qquickfiledialogimpl/dummy_imports.qml new file mode 100644 index 00000000000..4ea33de671f --- /dev/null +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/dummy_imports.qml @@ -0,0 +1,9 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQuick.Controls +import QtQuick.Layouts +import Qt.labs.folderlistmodel + +QtObject { } diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/qquickfiledialogimpl.pro b/tests/auto/quickdialogs/qquickfiledialogimpl/qquickfiledialogimpl.pro new file mode 100644 index 00000000000..3f6e83d7fd9 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/qquickfiledialogimpl.pro @@ -0,0 +1,14 @@ +CONFIG += testcase +TARGET = tst_qquickfiledialogimpl +SOURCES += tst_qquickfiledialogimpl.cpp + +macos:CONFIG -= app_bundle + +QT += core-private gui-private testlib qml-private quick-private qmltest quicktemplates2-private + +include (../../shared/util.pri) + +TESTDATA = data/* + +OTHER_FILES += \ + data/*.qml diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp b/tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp new file mode 100644 index 00000000000..833b4808435 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp @@ -0,0 +1,1358 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtQml/qqmlfile.h> +#include <QtQuick/private/qquicklistview_p.h> +#include <QtQuickTest/quicktest.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> +#include <QtQuickControlsTestUtils/private/dialogstestutils_p.h> +#include <QtQuickDialogs2/private/qquickfiledialog_p.h> +#include <QtQuickDialogs2QuickImpl/private/qquickplatformfiledialog_p.h> +#include <QtQuickDialogs2QuickImpl/private/qquickfiledialogdelegate_p.h> +#include <QtQuickDialogs2QuickImpl/private/qquickfolderbreadcrumbbar_p.h> +#include <QtQuickDialogs2QuickImpl/private/qquickfolderbreadcrumbbar_p_p.h> +#include <QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p_p.h> +#include <QtQuickTemplates2/private/qquicklabel_p.h> +#include <QtQuickTemplates2/private/qquickoverlay_p.h> +#include <QtQuickControls2/qquickstyle.h> + +using namespace QQuickVisualTestUtils; +using namespace QQuickDialogTestUtils; +using namespace QQuickControlsTestUtils; + +class tst_QQuickFileDialogImpl : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_QQuickFileDialogImpl(); + static void initMain() + { + // We need to set this attribute. + QCoreApplication::setAttribute(Qt::AA_DontUseNativeDialogs); + // We also don't want to run this for every style, as each one will have + // different ways of implementing the dialogs. + // For now we only test one style. + QQuickStyle::setStyle("Basic"); + } + +private slots: + void initTestCase() override; + void cleanupTestCase(); + + void defaults(); + void chooseFileViaStandardButtons(); + void chooseFileViaDoubleClick(); + void chooseFileViaTextEdit(); + void chooseFileViaEnter(); + void bindCurrentFolder_data(); + void bindCurrentFolder(); + void changeFolderViaStandardButtons(); + void changeFolderViaDoubleClick(); + void chooseFolderViaTextEdit(); + void chooseFolderViaEnter(); + void chooseFileAndThenFolderViaTextEdit(); + void cancelDialogWhileTextEditHasFocus(); + void closingDialogCancels(); + void goUp(); + void goUpWhileTextEditHasFocus(); + void goIntoLargeFolder(); + void keyAndShortcutHandling(); + void bindNameFilters(); + void changeNameFilters(); + void changeNameFiltersAfterChangingFolder(); + void tabFocusNavigation(); + void acceptRejectLabel(); + void bindTitle(); + void itemsDisabledWhenNecessary(); + void fileMode_data(); + void fileMode(); + void defaultSuffix_data(); + void defaultSuffix(); + void done_data(); + void done(); + +private: + QTemporaryDir tempDir; + QScopedPointer<QFile> tempFile1; + QScopedPointer<QFile> tempFile2; + QDir tempSubDir; + QDir tempSubSubDir; + QScopedPointer<QFile> tempSubFile1; + QScopedPointer<QFile> tempSubFile2; + QDir oldCurrentDir; +}; + +tst_QQuickFileDialogImpl::tst_QQuickFileDialogImpl() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_QQuickFileDialogImpl::initTestCase() +{ + QQmlDataTest::initTestCase(); + + QVERIFY(tempDir.isValid()); + // QTEST_QUICKCONTROLS_MAIN constructs the test case object once, + // and then calls qRun() for each style, and qRun() calls initTestCase(). + // So, we need to check if we've already made the temporary directory. + // Note that this is only necessary if the test is run with more than one style. + if (!QDir(tempDir.path()).isEmpty()) + return; + + /* + Create a couple of files within the temporary directory. The structure is: + + [temp directory] + ├── sub-dir + │ ├── sub-sub-dir + │ ├── sub-file1.txt + │ └── sub-file2.txt + ├── file1.txt + └── file2.txt + */ + tempSubDir = QDir(tempDir.path()); + QVERIFY2(tempSubDir.mkdir("sub-dir"), qPrintable(QString::fromLatin1( + "Failed to make sub-directory \"sub-dir\" in %1. Permissions are: %2") + .arg(tempDir.path()).arg(QDebug::toString(QFileInfo(tempDir.path()).permissions())))); + QVERIFY(tempSubDir.cd("sub-dir")); + + tempSubSubDir = QDir(tempSubDir.path()); + QVERIFY2(tempSubSubDir.mkdir("sub-sub-dir"), qPrintable(QString::fromLatin1( + "Failed to make sub-directory \"sub-sub-dir\" in %1. Permissions are: %2") + .arg(tempSubDir.path()).arg(QDebug::toString(QFileInfo(tempSubDir.path()).permissions())))); + QVERIFY(tempSubSubDir.cd("sub-sub-dir")); + + tempSubFile1.reset(new QFile(tempSubDir.path() + "/sub-file1.txt")); + QVERIFY(tempSubFile1->open(QIODevice::ReadWrite)); + + tempSubFile2.reset(new QFile(tempSubDir.path() + "/sub-file2.txt")); + QVERIFY(tempSubFile2->open(QIODevice::ReadWrite)); + + tempFile1.reset(new QFile(tempDir.path() + "/file1.txt")); + QVERIFY(tempFile1->open(QIODevice::ReadWrite)); + + tempFile2.reset(new QFile(tempDir.path() + "/file2.txt")); + QVERIFY(tempFile2->open(QIODevice::ReadWrite)); + + // Ensure that each test starts off in the temporary directory. + oldCurrentDir = QDir::current(); + QDir::setCurrent(tempDir.path()); +} + +void tst_QQuickFileDialogImpl::cleanupTestCase() +{ + // Just in case... + QDir::setCurrent(oldCurrentDir.path()); +} + +void tst_QQuickFileDialogImpl::defaults() +{ + QQuickApplicationHelper helper(this, "fileDialog.qml"); + QVERIFY2(helper.ready, helper.failureMessage()); + + QQuickWindow *window = helper.window; + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickFileDialog *dialog = window->property("dialog").value<QQuickFileDialog*>(); + QVERIFY(dialog); + COMPARE_URL(dialog->selectedFile(), QUrl()); + // It should default to the current directory. + COMPARE_URL(dialog->currentFolder(), QUrl::fromLocalFile(QDir().absolutePath())); + // The first file in the directory should be selected, but not until the dialog is actually open, + // as QQuickFileDialogImpl hasn't been created yet. + COMPARE_URL(dialog->currentFile(), QUrl()); + COMPARE_URLS(dialog->currentFiles(), {}); + QCOMPARE(dialog->title(), QString()); + + dialog->open(); + QQuickFileDialogImpl *quickDialog = window->findChild<QQuickFileDialogImpl*>(); + QTRY_VERIFY(quickDialog->isOpened()); + QVERIFY(quickDialog); + COMPARE_URL(quickDialog->selectedFile(), QUrl()); + COMPARE_URL(quickDialog->currentFolder(), QUrl::fromLocalFile(QDir().absolutePath())); + COMPARE_URL(dialog->currentFile(), QUrl::fromLocalFile(tempSubDir.path())); + COMPARE_URLS(dialog->currentFiles(), { QUrl::fromLocalFile(tempSubDir.path()) }); + COMPARE_URL(quickDialog->currentFile(), QUrl::fromLocalFile(tempSubDir.path())); + QCOMPARE(quickDialog->title(), QString()); +} + +void tst_QQuickFileDialogImpl::chooseFileViaStandardButtons() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Select the delegate by clicking once. + QSignalSpy dialogFileChangedSpy(dialogHelper.dialog, SIGNAL(selectedFileChanged())); + QVERIFY(dialogFileChangedSpy.isValid()); + QSignalSpy dialogCurrentFileChangedSpy(dialogHelper.dialog, SIGNAL(currentFileChanged())); + QVERIFY(dialogCurrentFileChangedSpy.isValid()); + QSignalSpy quickDialogCurrentFileChangedSpy(dialogHelper.quickDialog, SIGNAL(currentFileChanged(const QUrl &))); + QVERIFY(quickDialogCurrentFileChangedSpy.isValid()); + + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QQuickFileDialogDelegate *delegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 2, delegate)); + COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempFile2->fileName())); + QVERIFY(clickButton(delegate)); + COMPARE_URL(dialogHelper.quickDialog->currentFile(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); + // Only currentFile-related signals should be emitted. + QCOMPARE(dialogFileChangedSpy.count(), 0); + QCOMPARE(dialogCurrentFileChangedSpy.count(), 1); + QCOMPARE(quickDialogCurrentFileChangedSpy.count(), 1); + + // Click the "Open" button. + QVERIFY(dialogHelper.quickDialog->footer()); + auto dialogButtonBox = dialogHelper.quickDialog->footer()->findChild<QQuickDialogButtonBox*>(); + QVERIFY(dialogButtonBox); + QQuickAbstractButton* openButton = findDialogButton(dialogButtonBox, "Open"); + QVERIFY(openButton); + QVERIFY(clickButton(openButton)); + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); + QCOMPARE(dialogFileChangedSpy.count(), 1); + COMPARE_URL(dialogHelper.quickDialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); + QVERIFY(!dialogHelper.dialog->isVisible()); +} + +void tst_QQuickFileDialogImpl::chooseFileViaDoubleClick() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Select the delegate by double-clicking. + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QQuickFileDialogDelegate *delegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 2, delegate)); + COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempFile2->fileName())) + QVERIFY(doubleClickButton(delegate)); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile2->fileName())) + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }) + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())) + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }) + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); +} + +void tst_QQuickFileDialogImpl::chooseFileViaTextEdit() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Get the text edit visible with Ctrl+L. + const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L); + QTest::keySequence(dialogHelper.window(), editPathKeySequence); + auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); + QVERIFY(breadcrumbBar); + QVERIFY(breadcrumbBar->textField()->isVisible()); + QCOMPARE(breadcrumbBar->textField()->text(), dialogHelper.dialog->currentFolder().toLocalFile()); + QCOMPARE(breadcrumbBar->textField()->selectedText(), breadcrumbBar->textField()->text()); + + // Enter the path to the file in the text edit. + enterText(dialogHelper.window(), tempFile2->fileName()); + QCOMPARE(breadcrumbBar->textField()->text(), tempFile2->fileName()); + + // Hit enter to accept. + QTest::keyClick(dialogHelper.window(), Qt::Key_Return); + COMPARE_URL(dialogHelper.quickDialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); +} + +void tst_QQuickFileDialogImpl::chooseFileViaEnter() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Before moving down, the first delegate in the view should be selected and have focus. + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempSubDir.path())); + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QQuickFileDialogDelegate *subDirDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subDirDelegate)); + COMPARE_URL(subDirDelegate->file(), QUrl::fromLocalFile(tempSubDir.path())); + QVERIFY(subDirDelegate->hasActiveFocus()); + + // Select the first file in the view by navigating with the down key. + QTest::keyClick(dialogHelper.window(), Qt::Key_Down); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile1->fileName())); + + // Select the delegate by pressing enter. + QTest::keyClick(dialogHelper.window(), Qt::Key_Return); + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile1->fileName())); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile1->fileName()) }); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); + QCOMPARE(dialogHelper.dialog->result(), QQuickFileDialog::Accepted); +} + +void tst_QQuickFileDialogImpl::bindCurrentFolder_data() +{ + QTest::addColumn<QUrl>("initialFolder"); + QTest::addColumn<QUrl>("expectedFolder"); + QTest::addColumn<QStringList>("expectedVisibleFiles"); + + const auto currentDirUrl = QUrl::fromLocalFile(QDir::current().path()); + const auto tempSubDirUrl = QUrl::fromLocalFile(tempSubDir.path()); + const auto tempSubFile1Url = QUrl::fromLocalFile(tempSubFile1->fileName()); + + const QStringList currentDirFiles = { tempSubDir.path(), tempFile1->fileName(), tempFile2->fileName() }; + const QStringList tempSubDirFiles = { tempSubSubDir.path(), tempSubFile1->fileName(), tempSubFile2->fileName() }; + + // Setting the folder to "sub-dir" should result in "sub-file1.txt" and "sub-file2.txt" being visible. + QTest::addRow("sub-dir") << tempSubDirUrl << tempSubDirUrl << tempSubDirFiles; + // Setting a file as the folder shouldn't work, and the dialog shouldn't change its folder. + QTest::addRow("sub-dir/sub-file1.txt") << tempSubFile1Url << currentDirUrl << currentDirFiles; +} + +void tst_QQuickFileDialogImpl::bindCurrentFolder() +{ + QFETCH(QUrl, initialFolder); + QFETCH(QUrl, expectedFolder); + QFETCH(QStringList, expectedVisibleFiles); + + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "bindCurrentFolder.qml", {}, + {{ "initialFolder", initialFolder }}); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + COMPARE_URL(dialogHelper.dialog->currentFolder(), expectedFolder); + + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QString failureMessage; + // Even waiting for ListView polish and that the FolderListModel's status is ready aren't enough + // on Windows, apparently, as sometimes there just aren't any delegates by the time we do the check. + // So, we use QTRY_VERIFY2 each time we call this function just to be safe. + QTRY_VERIFY2(verifyFileDialogDelegates(fileDialogListView, expectedVisibleFiles, failureMessage), qPrintable(failureMessage)); + + // Check that the breadcrumb bar is correct by constructing the expected files from the expectedFolder. + auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); + QVERIFY(breadcrumbBar); + QVERIFY2(verifyBreadcrumbDelegates(breadcrumbBar, expectedFolder, failureMessage), qPrintable(failureMessage)); +} + +void tst_QQuickFileDialogImpl::changeFolderViaStandardButtons() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Select the delegate by clicking once. + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QQuickFileDialogDelegate *delegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, delegate)); + COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempSubDir.path())); + QVERIFY(clickButton(delegate)); + // The selectedFile and currentFolder shouldn't change yet. + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl()); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), {}); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path())); + // The currentFile should, though. + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempSubDir.path())); + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempSubDir.path()) }); + + // Click the "Open" button. The dialog should navigate to that directory, but still be open. + QVERIFY(dialogHelper.quickDialog->footer()); + auto dialogButtonBox = dialogHelper.quickDialog->footer()->findChild<QQuickDialogButtonBox*>(); + QVERIFY(dialogButtonBox); + QQuickAbstractButton* openButton = findDialogButton(dialogButtonBox, "Open"); + QVERIFY(openButton); + QVERIFY(clickButton(openButton)); + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl()); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); + QVERIFY(dialogHelper.dialog->isVisible()); + + dialogHelper.dialog->close(); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); +} + +void tst_QQuickFileDialogImpl::changeFolderViaDoubleClick() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Select the "sub-dir" delegate by double-clicking. + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QQuickFileDialogDelegate *subDirDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subDirDelegate)); + COMPARE_URL(subDirDelegate->file(), QUrl::fromLocalFile(tempSubDir.path())); + QVERIFY(doubleClickButton(subDirDelegate)); + // The first file in the directory should be selected, which is "sub-sub-dir". + const QStringList expectedVisibleFiles = { tempSubSubDir.path(), tempSubFile1->fileName(), tempSubFile2->fileName() }; + QString failureMessage; + QTRY_VERIFY2(verifyFileDialogDelegates(fileDialogListView, expectedVisibleFiles, failureMessage), qPrintable(failureMessage)); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempSubSubDir.path())); + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempSubSubDir.path()) }); + QQuickFileDialogDelegate *subSubDirDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subSubDirDelegate)); + QCOMPARE(subSubDirDelegate->isHighlighted(), true); + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl()); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), {}); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); + // Since we only chose a folder, the dialog should still be open. + QVERIFY(dialogHelper.dialog->isVisible()); + + dialogHelper.dialog->close(); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); +} + +void tst_QQuickFileDialogImpl::chooseFolderViaTextEdit() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Get the text edit visible with Ctrl+L. + const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L); + QTest::keySequence(dialogHelper.window(), editPathKeySequence); + auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); + QVERIFY(breadcrumbBar); + QVERIFY(breadcrumbBar->textField()->isVisible()); + QCOMPARE(breadcrumbBar->textField()->text(), dialogHelper.dialog->currentFolder().toLocalFile()); + QCOMPARE(breadcrumbBar->textField()->selectedText(), breadcrumbBar->textField()->text()); + + // Enter the path to the folder in the text edit. + enterText(dialogHelper.window(), tempSubDir.path()); + QCOMPARE(breadcrumbBar->textField()->text(), tempSubDir.path()); + + // Hit enter to accept. + QTest::keyClick(dialogHelper.window(), Qt::Key_Return); + // The first file in the directory should be selected, which is "sub-sub-dir". + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempSubSubDir.path())); + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QQuickFileDialogDelegate *subSubDirDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subSubDirDelegate)); + QCOMPARE(subSubDirDelegate->isHighlighted(), true); + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl()); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), {}); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); + QTRY_VERIFY(dialogHelper.dialog->isVisible()); + + dialogHelper.dialog->close(); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); +} + +void tst_QQuickFileDialogImpl::chooseFolderViaEnter() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // The first delegate in the view should be selected and have focus. + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path())); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempSubDir.path())); + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempSubDir.path()) }); + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QQuickFileDialogDelegate *subDirDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subDirDelegate)); + COMPARE_URL(subDirDelegate->file(), QUrl::fromLocalFile(tempSubDir.path())); + QVERIFY(subDirDelegate->hasActiveFocus()); + + // Select the delegate by pressing enter. + QTest::keyClick(dialogHelper.window(), Qt::Key_Return); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); + const QStringList expectedVisibleFiles = { tempSubSubDir.path(), tempSubFile1->fileName(), tempSubFile2->fileName() }; + QString failureMessage; + QTRY_VERIFY2(verifyFileDialogDelegates(fileDialogListView, expectedVisibleFiles, failureMessage), qPrintable(failureMessage)); + // The first file in the new directory should be selected, which is "sub-sub-dir". + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempSubSubDir.path())); + // Since we only chose a folder, the dialog should still be open. + QVERIFY(dialogHelper.dialog->isVisible()); + + dialogHelper.dialog->close(); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); +} + +void tst_QQuickFileDialogImpl::chooseFileAndThenFolderViaTextEdit() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Get the text edit visible with Ctrl+L. + const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L); + QTest::keySequence(dialogHelper.window(), editPathKeySequence); + auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); + QVERIFY(breadcrumbBar); + QVERIFY(breadcrumbBar->textField()->isVisible()); + QCOMPARE(breadcrumbBar->textField()->text(), dialogHelper.dialog->currentFolder().toLocalFile()); + QCOMPARE(breadcrumbBar->textField()->selectedText(), breadcrumbBar->textField()->text()); + + // Enter the path to the file in the text edit. + enterText(dialogHelper.window(), tempFile2->fileName()); + QCOMPARE(breadcrumbBar->textField()->text(), tempFile2->fileName()); + + // Hit enter to accept. + QTest::keyClick(dialogHelper.window(), Qt::Key_Return); + COMPARE_URL(dialogHelper.quickDialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); + // Check that the text edit is hidden and breadcrumbs are shown instead. + QVERIFY(!breadcrumbBar->textField()->isVisible()); + + // Re-open the dialog. + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + // The breadcrumbs should be visible after opening, not the text edit. + QVERIFY(!breadcrumbBar->textField()->isVisible()); + + // Get the text edit visible with Ctrl+L. + QTest::keySequence(dialogHelper.window(), editPathKeySequence); + QVERIFY(breadcrumbBar->textField()->isVisible()); + // The text edit should show the directory that contains the last file that was selected. + QCOMPARE(breadcrumbBar->textField()->text(), tempDir.path()); + QCOMPARE(breadcrumbBar->textField()->selectedText(), breadcrumbBar->textField()->text()); + + // Enter the path to the folder in the text edit. + enterText(dialogHelper.window(), tempSubDir.path()); + QCOMPARE(breadcrumbBar->textField()->text(), tempSubDir.path()); + + // Hit enter to accept. + QTest::keyClick(dialogHelper.window(), Qt::Key_Return); + // The first file in the directory should be selected, which is "sub-sub-dir". + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempSubSubDir.path())); + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QQuickFileDialogDelegate *subSubDirDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subSubDirDelegate)); + QCOMPARE(subSubDirDelegate->isHighlighted(), true); + // We just changed directories, so the actual selected file shouldn't change. + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); + QTRY_VERIFY(dialogHelper.dialog->isVisible()); + + // Close the dialog. + dialogHelper.dialog->close(); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); +} + +void tst_QQuickFileDialogImpl::cancelDialogWhileTextEditHasFocus() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Get the text edit visible with Ctrl+L. + const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L); + QTest::keySequence(dialogHelper.window(), editPathKeySequence); + auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); + QVERIFY(breadcrumbBar); + QVERIFY(breadcrumbBar->textField()->hasActiveFocus()); + + // Close it via the cancel button. + auto dialogButtonBox = dialogHelper.quickDialog->footer()->findChild<QQuickDialogButtonBox*>(); + QVERIFY(dialogButtonBox); + const QString cancelText = QQuickDialogButtonBoxPrivate::buttonText(QPlatformDialogHelper::Cancel); + auto cancelButton = findDialogButton(dialogButtonBox, cancelText); + QVERIFY(cancelButton); + QVERIFY(clickButton(cancelButton)); + + // Open it again. The text field should not be visible, but the breadcrumb bar itself should be. + dialogHelper.dialog->open(); + QVERIFY(dialogHelper.dialog->isVisible()); + QTRY_VERIFY(dialogHelper.quickDialog->isOpened()); + QVERIFY(breadcrumbBar->isVisible()); + // The ListView that contains the breadcrumb delegates should be visible. + QVERIFY(breadcrumbBar->contentItem()->isVisible()); + QVERIFY(!breadcrumbBar->textField()->isVisible()); +} + +void tst_QQuickFileDialogImpl::closingDialogCancels() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + OPEN_QUICK_DIALOG(); + + QSignalSpy accepted(dialogHelper.dialog, &QQuickAbstractDialog::accepted); + QSignalSpy rejected(dialogHelper.dialog, &QQuickAbstractDialog::rejected); + + // Accept the dialog. + QVERIFY(QMetaObject::invokeMethod(dialogHelper.window(), "doneAccepted")); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); + QCOMPARE(accepted.size(), 1); + QCOMPARE(rejected.size(), 0); + + // Re-open the dialog. + accepted.clear(); + OPEN_QUICK_DIALOG(); + + // Close the dialog. + CLOSE_QUICK_DIALOG(); + QCOMPARE(accepted.size(), 0); + QCOMPARE(rejected.size(), 1); +} + +void tst_QQuickFileDialogImpl::goUp() +{ + // Open the dialog. Start off in "sub-dir". + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "bindCurrentFolder.qml", {}, + {{ "initialFolder", QUrl::fromLocalFile(tempSubDir.path()) }}); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Go up a directory via the button next to the breadcrumb bar. + auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); + QVERIFY(breadcrumbBar); + auto barListView = qobject_cast<QQuickListView*>(breadcrumbBar->contentItem()); + QVERIFY(barListView); + if (QQuickTest::qIsPolishScheduled(barListView)) + QVERIFY(QQuickTest::qWaitForItemPolished(barListView)); + QVERIFY(clickButton(breadcrumbBar->upButton())); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path())); + // The previous directory that we were in should now be selected (matches e.g. Windows and Ubuntu). + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempSubDir.path())); + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempSubDir.path()) }); + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QQuickFileDialogDelegate *subDirDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subDirDelegate)); + QCOMPARE(subDirDelegate->isHighlighted(), true); + + // Go up a directory via the keyboard shortcut. + const auto goUpKeySequence = QKeySequence(Qt::ALT | Qt::Key_Up); + QTest::keySequence(dialogHelper.window(), goUpKeySequence); + QDir tempParentDir(tempDir.path()); + QVERIFY(tempParentDir.cdUp()); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempParentDir.path())); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempDir.path())); + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempDir.path()) }); +} + +void tst_QQuickFileDialogImpl::goUpWhileTextEditHasFocus() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "bindCurrentFolder.qml", {}, + {{ "initialFolder", QUrl::fromLocalFile(tempSubDir.path()) }}); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Get the text edit visible with Ctrl+L. + const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L); + QTest::keySequence(dialogHelper.window(), editPathKeySequence); + auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); + QVERIFY(breadcrumbBar); + QVERIFY(breadcrumbBar->textField()->hasActiveFocus()); + + // Go up a directory via the button next to the breadcrumb bar. + auto barListView = qobject_cast<QQuickListView*>(breadcrumbBar->contentItem()); + QVERIFY(barListView); + if (QQuickTest::qIsPolishScheduled(barListView)) + QVERIFY(QQuickTest::qWaitForItemPolished(barListView)); + QVERIFY(clickButton(breadcrumbBar->upButton())); + // The path should have changed to the parent directory. + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path())); + // The text edit should be hidden when it loses focus. + QVERIFY(!breadcrumbBar->textField()->hasActiveFocus()); + QVERIFY(!breadcrumbBar->textField()->isVisible()); + // The focus should be given to the first delegate. + QVERIFY(dialogHelper.window()->activeFocusItem()); + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QQuickFileDialogDelegate *firstDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, firstDelegate)); + QCOMPARE(dialogHelper.window()->activeFocusItem(), firstDelegate); +} + +void tst_QQuickFileDialogImpl::goIntoLargeFolder() +{ + // Create a throwaway directory with a lot of folders within it... + QTemporaryDir anotherTempDir; + QVERIFY(anotherTempDir.isValid()); + for (int i = 0; i < 30; ++i) { + QDir newDir(anotherTempDir.path()); + QVERIFY(newDir.exists()); + // Pad with zeroes so that the directories are ordered as we expect. + QVERIFY(newDir.mkdir(QString::fromLatin1("dir%1").arg(i, 2, 10, QLatin1Char('0')))); + } + + // ... and within one of those folders, more folders. + QDir dir20(anotherTempDir.path() + "/dir20"); + QVERIFY(dir20.exists()); + for (int i = 0; i < 30; ++i) { + QDir newDir(dir20.path()); + QVERIFY(newDir.exists()); + QVERIFY(newDir.mkdir(QString::fromLatin1("subdir%1").arg(i, 2, 10, QLatin1Char('0')))); + } + + // Open the dialog. Start off in the throwaway directory. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "bindCurrentFolder.qml", {}, + {{ "initialFolder", QUrl::fromLocalFile(anotherTempDir.path()) }}); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // If the screen is so tall that the contentItem is not vertically larger than the view, + // then the test makes no sense. + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + if (QQuickTest::qIsPolishScheduled(fileDialogListView)) + QVERIFY(QQuickTest::qWaitForItemPolished(fileDialogListView)); + // Just to be safe, make sure it's at least twice as big. + if (fileDialogListView->contentItem()->height() < fileDialogListView->height() * 2) { + QSKIP(qPrintable(QString::fromLatin1("Expected height of fileDialogListView's contentItem (%1)" \ + " to be at least twice as big as the ListView's height (%2)") + .arg(fileDialogListView->contentItem()->height()).arg(fileDialogListView->height()))); + } + + // Scroll down to dir20. The view should be somewhere past the middle. + QVERIFY(QMetaObject::invokeMethod(fileDialogListView, "positionViewAtIndex", Qt::DirectConnection, + Q_ARG(int, 20), Q_ARG(int, QQuickItemView::PositionMode::Center))); + QVERIFY(fileDialogListView->contentY() > 0); + + // Go into it. The view should start at the top of the directory, not at the same contentY + // that it had in the previous directory. + QQuickFileDialogDelegate *dir20Delegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 20, dir20Delegate)); + COMPARE_URL(dir20Delegate->file(), QUrl::fromLocalFile(dir20.path())); + QVERIFY(doubleClickButton(dir20Delegate)); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(dir20.path())); + COMPARE_URL(dialogHelper.quickDialog->currentFolder(), QUrl::fromLocalFile(dir20.path())); + QCOMPARE(fileDialogListView->contentY(), 0); +} + +void tst_QQuickFileDialogImpl::keyAndShortcutHandling() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Get the text edit visible with Ctrl+L. + const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L); + QTest::keySequence(dialogHelper.window(), editPathKeySequence); + auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); + QVERIFY(breadcrumbBar); + QVERIFY(breadcrumbBar->textField()->isVisible()); + QCOMPARE(breadcrumbBar->textField()->text(), dialogHelper.dialog->currentFolder().toLocalFile()); + QCOMPARE(breadcrumbBar->textField()->selectedText(), breadcrumbBar->textField()->text()); + + // Ctrl+L shouldn't hide it. + QTest::keySequence(dialogHelper.window(), editPathKeySequence); + QVERIFY(breadcrumbBar->textField()->isVisible()); + + // Cancel it with the escape key. + QTest::keyClick(dialogHelper.window(), Qt::Key_Escape); + QVERIFY(!breadcrumbBar->textField()->isVisible()); + QVERIFY(dialogHelper.dialog->isVisible()); + + // Make it visible. + QTest::keySequence(dialogHelper.window(), editPathKeySequence); + QVERIFY(breadcrumbBar->textField()->isVisible()); + + // Cancel it with the escape key again. + QTest::keyClick(dialogHelper.window(), Qt::Key_Escape); + QVERIFY(!breadcrumbBar->textField()->isVisible()); + QVERIFY(dialogHelper.dialog->isVisible()); + + // Pressing escape now should close the dialog. + QTest::keyClick(dialogHelper.window(), Qt::Key_Escape); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); +} + +void tst_QQuickFileDialogImpl::bindNameFilters() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "bindTxtHtmlNameFilters.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Only "sub-dir", "text1.txt" and "text2.txt" should be visible, since *.txt is the first filter. + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QString failureMessage; + QTRY_VERIFY2(verifyFileDialogDelegates(fileDialogListView, + { tempSubDir.path(), tempFile1->fileName(), tempFile2->fileName() }, failureMessage), qPrintable(failureMessage)); +} + +void tst_QQuickFileDialogImpl::changeNameFilters() +{ + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + + // Open the dialog and check that selectedNameFilter is correct. + // By default, QFileDialogOptions::defaultNameFilterString() is used. + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + QCOMPARE(dialogHelper.dialog->selectedNameFilter()->name(), "All Files"); + QCOMPARE(dialogHelper.quickDialog->selectedNameFilter()->name(), "All Files"); + QCOMPARE(dialogHelper.dialog->selectedNameFilter()->index(), 0); + QCOMPARE(dialogHelper.quickDialog->selectedNameFilter()->index(), 0); + QCOMPARE(dialogHelper.dialog->selectedNameFilter()->extensions(), { "*" }); + QCOMPARE(dialogHelper.quickDialog->selectedNameFilter()->extensions(), { "*" }); + QCOMPARE(dialogHelper.dialog->selectedNameFilter()->globs(), { "*" }); + QCOMPARE(dialogHelper.quickDialog->selectedNameFilter()->globs(), { "*" }); + + // Close the dialog. + dialogHelper.dialog->close(); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); + + // Set .txt and .html filters. + QSignalSpy nameFiltersChangedSpy(dialogHelper.dialog, SIGNAL(nameFiltersChanged())); + QVERIFY(nameFiltersChangedSpy.isValid()); + const QStringList nameFilters = { "Text files (*.txt)", "HTML files (*.html)" }; + dialogHelper.dialog->setNameFilters(nameFilters); + QCOMPARE(dialogHelper.dialog->nameFilters(), nameFilters); + QCOMPARE(nameFiltersChangedSpy.count(), 1); + QCOMPARE(dialogHelper.dialog->selectedNameFilter()->name(), "Text files"); + QCOMPARE(dialogHelper.dialog->selectedNameFilter()->index(), 0); + QCOMPARE(dialogHelper.dialog->selectedNameFilter()->extensions(), { "txt" }); + QCOMPARE(dialogHelper.dialog->selectedNameFilter()->globs(), { "*.txt" }); + + // Re-open the dialog. + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + // QQuickFileDialogImpl's values only get set before opening. + QCOMPARE(dialogHelper.quickDialog->selectedNameFilter()->name(), "Text files"); + QCOMPARE(dialogHelper.quickDialog->selectedNameFilter()->index(), 0); + QCOMPARE(dialogHelper.quickDialog->selectedNameFilter()->extensions(), { "txt" }); + QCOMPARE(dialogHelper.quickDialog->selectedNameFilter()->globs(), { "*.txt" }); + + // Only "sub-dir", "text1.txt" and "text2.txt" should be visible, since *.txt is the first filter. + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QString failureMessage; + QTRY_VERIFY2(verifyFileDialogDelegates(fileDialogListView, + { tempSubDir.path(), tempFile1->fileName(), tempFile2->fileName() }, failureMessage), qPrintable(failureMessage)); + + // Open the ComboBox's popup. + const QQuickComboBox *comboBox = dialogHelper.quickDialog->findChild<QQuickComboBox*>(); + QVERIFY(comboBox); + const QPoint comboBoxCenterPos = comboBox->mapToScene({ comboBox->width() / 2, comboBox->height() / 2 }).toPoint(); + QTest::mouseClick(dialogHelper.window(), Qt::LeftButton, Qt::NoModifier, comboBoxCenterPos); + QTRY_VERIFY(comboBox->popup()->isOpened()); + + // Select the .html delegate and close the combobox popup. The only visible entry should be the sub-dir. + QQuickListView *comboBoxPopupListView = qobject_cast<QQuickListView*>(comboBox->popup()->contentItem()); + QVERIFY(comboBoxPopupListView); + { + QQuickAbstractButton *htmlDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(comboBoxPopupListView, 1, htmlDelegate)); + QVERIFY(clickButton(htmlDelegate)); + } + QTRY_VERIFY(!comboBox->popup()->isVisible()); + // Use QTRY_VERIFY2 here to fix a failure on QEMU armv7 (QT_QPA_PLATFORM=offscreen). + // Not sure why it's necessary. + QTRY_VERIFY2(verifyFileDialogDelegates(fileDialogListView, { tempSubDir.path() }, failureMessage), qPrintable(failureMessage)); + + // Open the popup again. + QTest::mouseClick(dialogHelper.window(), Qt::LeftButton, Qt::NoModifier, comboBoxCenterPos); + QTRY_VERIFY(comboBox->popup()->isOpened()); + + // Select .txt and close the combobox popup. The original entries should be visible. + { + QQuickAbstractButton *txtDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(comboBoxPopupListView, 0, txtDelegate)); + QCOMPARE(txtDelegate->text(), nameFilters.at(0)); + QVERIFY(clickButton(txtDelegate)); + } + QTRY_VERIFY(!comboBox->popup()->isVisible()); + QTRY_VERIFY2(verifyFileDialogDelegates(fileDialogListView, + { tempSubDir.path(), tempFile1->fileName(), tempFile2->fileName() }, failureMessage), qPrintable(failureMessage)); +} + +void tst_QQuickFileDialogImpl::changeNameFiltersAfterChangingFolder() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "bindAllTxtHtmlNameFilters.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Go into the "sub-dir" folder. + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QString failureMessage; + QTRY_VERIFY2(verifyFileDialogDelegates(fileDialogListView, + { tempSubDir.path(), tempFile1->fileName(), tempFile2->fileName() }, failureMessage), qPrintable(failureMessage)); + QQuickFileDialogDelegate *subDirDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, subDirDelegate)); + QVERIFY(doubleClickButton(subDirDelegate)); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); + COMPARE_URL(dialogHelper.quickDialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); + + // Open the ComboBox's popup. + const QQuickComboBox *comboBox = dialogHelper.quickDialog->findChild<QQuickComboBox*>(); + QVERIFY(comboBox); + const QPoint comboBoxCenterPos = comboBox->mapToScene({ comboBox->width() / 2, comboBox->height() / 2 }).toPoint(); + QTest::mouseClick(dialogHelper.window(), Qt::LeftButton, Qt::NoModifier, comboBoxCenterPos); + QTRY_VERIFY(comboBox->popup()->isOpened()); + + // Select the .html delegate, close the combobox popup, and ensure that the change had an effect. + QQuickListView *comboBoxPopupListView = qobject_cast<QQuickListView*>(comboBox->popup()->contentItem()); + QVERIFY(comboBoxPopupListView); + { + QQuickAbstractButton *htmlDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(comboBoxPopupListView, 2, htmlDelegate)); + QVERIFY(clickButton(htmlDelegate)); + } + QTRY_VERIFY(!comboBox->popup()->isVisible()); + // There are no HTML files in "sub-dir", so there should only be the one "sub-sub-dir" delegate. + QTRY_VERIFY2(verifyFileDialogDelegates(fileDialogListView, { tempSubSubDir.path() }, failureMessage), qPrintable(failureMessage)); +} + +void tst_QQuickFileDialogImpl::tabFocusNavigation() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "bindTxtHtmlNameFilters.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + QList<QQuickItem*> expectedFocusItems; + + // The initial focus should be on the first delegate. + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QQuickFileDialogDelegate *firstDelegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, firstDelegate)); + expectedFocusItems << firstDelegate; + + // Tab should move to the name filters combobox. + QQuickComboBox *comboBox = dialogHelper.quickDialog->findChild<QQuickComboBox*>(); + QVERIFY(comboBox); + expectedFocusItems << comboBox; + + // Next, the left-most dialog button. + auto dialogButtonBox = dialogHelper.quickDialog->footer()->findChild<QQuickDialogButtonBox*>(); + QVERIFY(dialogButtonBox); + QCOMPARE(dialogButtonBox->count(), 2); + auto leftMostButton = qobject_cast<QQuickAbstractButton*>(dialogButtonBox->itemAt(0)); + QVERIFY(leftMostButton); + expectedFocusItems << leftMostButton; + + // Then, the right-most dialog button. + auto rightMostButton = qobject_cast<QQuickAbstractButton*>(dialogButtonBox->itemAt(1)); + QVERIFY(rightMostButton); + expectedFocusItems << rightMostButton; + + // Then, the up button. + auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); + QVERIFY(breadcrumbBar); + expectedFocusItems << breadcrumbBar->upButton(); + + // Finally, add each bread crumb delegate. + for (int i = 0; i < fileDialogListView->count(); ++i) { + QQuickFileDialogDelegate *delegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, i, delegate)); + expectedFocusItems << delegate; + } + + // Tab through each item, checking the focus after each. + for (auto expectedFocusItem : qAsConst(expectedFocusItems)) { + // Check the focus item first so that we account for the first item. + // Print detailed failure message as workaround for QTBUG-92102. + QVERIFY2(dialogHelper.window()->activeFocusItem() == expectedFocusItem, qPrintable(QString::fromLatin1( + "\n Actual: %1\n Expected: %2").arg(QDebug::toString(dialogHelper.window()->activeFocusItem())) + .arg(QDebug::toString(expectedFocusItem)))); + + if (expectedFocusItem != expectedFocusItems.last()) + QTest::keyClick(dialogHelper.window(), Qt::Key_Tab); + } + + // Ensure the order is reversed when shift-tabbing. + std::reverse(expectedFocusItems.begin(), expectedFocusItems.end()); + // We know the first (last) item has focus already, so skip it. + expectedFocusItems.removeFirst(); + for (auto expectedFocusItem : qAsConst(expectedFocusItems)) { + QTest::keyClick(dialogHelper.window(), Qt::Key_Tab, Qt::ShiftModifier); + + QCOMPARE(dialogHelper.window()->activeFocusItem(), expectedFocusItem); + } +} + +void tst_QQuickFileDialogImpl::acceptRejectLabel() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "acceptRejectLabel.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Check that the accept and reject buttons' labels have changed. + auto dialogButtonBox = dialogHelper.quickDialog->footer()->findChild<QQuickDialogButtonBox*>(); + QVERIFY(dialogButtonBox); + QVERIFY(findDialogButton(dialogButtonBox, "AcceptTest")); + QVERIFY(findDialogButton(dialogButtonBox, "RejectTest")); + + // Close the dialog. + dialogHelper.dialog->close(); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); + + // Reset back to the default text. + dialogHelper.dialog->resetAcceptLabel(); + dialogHelper.dialog->resetRejectLabel(); + + // Re-open the dialog. + dialogHelper.dialog->open(); + QVERIFY(dialogHelper.dialog->isVisible()); + QTRY_VERIFY(dialogHelper.quickDialog->isOpened()); + + // Check that the defaults are back. + const QString openText = QQuickDialogButtonBoxPrivate::buttonText(QPlatformDialogHelper::Open); + QVERIFY2(findDialogButton(dialogButtonBox, openText), qPrintable(QString::fromLatin1( + "Failed to find dialog button with text \"%1\"").arg(openText))); + const QString cancelText = QQuickDialogButtonBoxPrivate::buttonText(QPlatformDialogHelper::Cancel); + QVERIFY2(findDialogButton(dialogButtonBox, cancelText), qPrintable(QString::fromLatin1( + "Failed to find dialog button with text \"%1\"").arg(cancelText))); +} + +void tst_QQuickFileDialogImpl::bindTitle() +{ + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "bindTitle.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Open the dialog and check that the correct title is displayed. + QQuickFileDialog *dialog = dialogHelper.window()->property("dialog").value<QQuickFileDialog*>(); + QVERIFY(dialog); + const QString expectedTitle = QLatin1String("Test Title"); + QCOMPARE(dialogHelper.dialog->title(), expectedTitle); + QCOMPARE(dialogHelper.quickDialog->title(), expectedTitle); + auto header = dialogHelper.quickDialog->header(); + QVERIFY(header); + auto dialogTitleBarLabel = dialogHelper.quickDialog->header()->findChild<QQuickLabel*>("dialogTitleBarLabel"); + QVERIFY(dialogTitleBarLabel); + QCOMPARE(dialogTitleBarLabel->text(), expectedTitle); +} + +void tst_QQuickFileDialogImpl::itemsDisabledWhenNecessary() +{ + QTemporaryDir anotherTempDir; + QVERIFY(anotherTempDir.isValid()); + QDir subDir(anotherTempDir.path()); + QVERIFY(subDir.mkdir("emptyDir")); + QVERIFY(subDir.cd("emptyDir")); + + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "bindCurrentFolder.qml", {}, + {{ "initialFolder", QUrl::fromLocalFile(subDir.path()) }}); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(subDir.path())); + COMPARE_URL(dialogHelper.quickDialog->currentFolder(), QUrl::fromLocalFile(subDir.path())); + + // We opened it in a folder that has no files, so the Open button should be disabled. + QVERIFY(dialogHelper.quickDialog->footer()); + auto dialogButtonBox = dialogHelper.quickDialog->footer()->findChild<QQuickDialogButtonBox*>(); + QVERIFY(dialogButtonBox); + QQuickAbstractButton* openButton = findDialogButton(dialogButtonBox, "Open"); + QVERIFY(openButton); + QCOMPARE(openButton->isEnabled(), false); + + // Now go up. The Open button should now be enabled. + auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); + QVERIFY(breadcrumbBar); + QVERIFY(clickButton(breadcrumbBar->upButton())); + QCOMPARE(openButton->isEnabled(), true); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(anotherTempDir.path())); + COMPARE_URL(dialogHelper.quickDialog->currentFolder(), QUrl::fromLocalFile(anotherTempDir.path())); + + // Get the text edit visible with Ctrl+L. The Open button should now be disabled. + const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L); + QTest::keySequence(dialogHelper.window(), editPathKeySequence); + QVERIFY(breadcrumbBar->textField()->isVisible()); + QCOMPARE(openButton->isEnabled(), false); + + // Hide it with the escape key. The Open button should now be enabled. + QTest::keyClick(dialogHelper.window(), Qt::Key_Escape); + QVERIFY(!breadcrumbBar->textField()->isVisible()); + QCOMPARE(openButton->isEnabled(), true); +} + +void tst_QQuickFileDialogImpl::fileMode_data() +{ + QTest::addColumn<QQuickFileDialog::FileMode>("fileMode"); + + QTest::newRow("OpenFile") << QQuickFileDialog::OpenFile; + QTest::newRow("OpenFiles") << QQuickFileDialog::OpenFiles; + QTest::newRow("SaveFile") << QQuickFileDialog::SaveFile; +} + +void tst_QQuickFileDialogImpl::fileMode() +{ + QFETCH(QQuickFileDialog::FileMode, fileMode); + + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + dialogHelper.dialog->setFileMode(fileMode); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Select the first file (not a directory). + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QQuickFileDialogDelegate *tempFile1Delegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 1, tempFile1Delegate)); + COMPARE_URL(tempFile1Delegate->file(), QUrl::fromLocalFile(tempFile1->fileName())); + QVERIFY(clickButton(tempFile1Delegate)); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile1->fileName())); + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile1->fileName()) }); + + // All modes should support opening an existing file, so the Open button should be enabled. + QVERIFY(dialogHelper.quickDialog->footer()); + auto dialogButtonBox = dialogHelper.quickDialog->footer()->findChild<QQuickDialogButtonBox*>(); + QVERIFY(dialogButtonBox); + QQuickAbstractButton* openButton = findDialogButton(dialogButtonBox, "Open"); + QVERIFY(openButton); + QCOMPARE(openButton->isEnabled(), true); + + // Only the OpenFiles mode should allow multiple files to be selected, however. + QQuickFileDialogDelegate *tempFile2Delegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 2, tempFile2Delegate)); + COMPARE_URL(tempFile2Delegate->file(), QUrl::fromLocalFile(tempFile2->fileName())); + QTest::keyPress(dialogHelper.window(), Qt::Key_Shift); + QVERIFY(clickButton(tempFile2Delegate)); + QTest::keyRelease(dialogHelper.window(), Qt::Key_Shift); + if (fileMode == QQuickFileDialog::OpenFiles) { + // currentFile() always points to the first file in the list of selected files. + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile1->fileName())); + const QList<QUrl> expectedSelectedFiles = { + QUrl::fromLocalFile(tempFile1->fileName()), QUrl::fromLocalFile(tempFile2->fileName()) }; + COMPARE_URLS(dialogHelper.dialog->currentFiles(), expectedSelectedFiles); + } else { + // OpenFile and SaveFile dialogs should have tempFile2 selected since it was clicked, + // but the shift should do nothing, so tempFile1 should no longer be selected. + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); + } + + // Get the text edit visible with Ctrl+L. + const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L); + QTest::keySequence(dialogHelper.window(), editPathKeySequence); + auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); + QVERIFY(breadcrumbBar); + QVERIFY(breadcrumbBar->textField()->isVisible()); + + // Typing in the name of an non-existent file should only work for SaveFile. + const QString nonExistentFilePath = "/foo/bar.txt"; + enterText(dialogHelper.window(), nonExistentFilePath); + QCOMPARE(breadcrumbBar->textField()->text(), nonExistentFilePath); + QTest::keyClick(dialogHelper.window(), Qt::Key_Return); + if (fileMode == QQuickFileDialog::SaveFile) { + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(nonExistentFilePath)); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(nonExistentFilePath) }); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); + } else { + // For OpenFile(s), we do what Qt Quick Dialogs 1.x did, and restore the previous (valid) dir path. + // The currentFile(s) should remain unchanged too. + QVERIFY(dialogHelper.dialog->isVisible()); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path())); + QCOMPARE(breadcrumbBar->textField()->text(), tempDir.path()); + + // Should be unchanged from the last time. + if (fileMode == QQuickFileDialog::OpenFiles) { + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile1->fileName())); + const QList<QUrl> expectedSelectedFiles = { + QUrl::fromLocalFile(tempFile1->fileName()), QUrl::fromLocalFile(tempFile2->fileName()) }; + COMPARE_URLS(dialogHelper.dialog->currentFiles(), expectedSelectedFiles); + } else { // OpenFile + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); + } + } +} + +void tst_QQuickFileDialogImpl::defaultSuffix_data() +{ + QTest::addColumn<QString>("defaultSuffix"); + + QTest::newRow("txt") << "txt"; + QTest::newRow(".txt") << ".txt"; +} + +void tst_QQuickFileDialogImpl::defaultSuffix() +{ + QFETCH(QString, defaultSuffix); + + // Simplify the test by using a directory with no files, and add a single file there. + QFile tempFile1(tempSubSubDir.path() + "/file1"); + QVERIFY(tempFile1.open(QIODevice::ReadWrite)); + + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "bindCurrentFolder.qml", {}, + {{ "initialFolder", QUrl::fromLocalFile(tempSubSubDir.path()) }}); + dialogHelper.dialog->setDefaultSuffix(defaultSuffix); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubSubDir.path())); + + // There should be one extension-less file: "file1". + auto fileDialogListView = dialogHelper.quickDialog->findChild<QQuickListView*>("fileDialogListView"); + QVERIFY(fileDialogListView); + QString failureMessage; + const QStringList expectedVisibleFiles = { tempFile1.fileName() }; + QTRY_VERIFY2(verifyFileDialogDelegates(fileDialogListView, expectedVisibleFiles, failureMessage), qPrintable(failureMessage)); + + // Choose the delegate. The suffix should be added to the delegates. + QQuickFileDialogDelegate *file1Delegate = nullptr; + QTRY_VERIFY(findViewDelegateItem(fileDialogListView, 0, file1Delegate)); + COMPARE_URL(file1Delegate->file(), QUrl::fromLocalFile(tempFile1.fileName())); + QVERIFY(doubleClickButton(file1Delegate)); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); + const QUrl fileUrlWithSuffix = QUrl::fromLocalFile(tempFile1.fileName() + ".txt"); + COMPARE_URL(dialogHelper.dialog->selectedFile(), fileUrlWithSuffix); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { fileUrlWithSuffix }); +} + +void tst_QQuickFileDialogImpl::done_data() +{ + QTest::addColumn<QQuickFileDialog::StandardCode>("result"); + + QTest::newRow("Accepted") << QQuickFileDialog::Accepted; + QTest::newRow("Rejected") << QQuickFileDialog::Rejected; +} + +void tst_QQuickFileDialogImpl::done() +{ + QFETCH(QQuickFileDialog::StandardCode, result); + + // Open the dialog. + DialogTestHelper<QQuickFileDialog, QQuickFileDialogImpl> dialogHelper(this, "fileDialog.qml"); + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); + QVERIFY(dialogHelper.waitForWindowActive()); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + switch (result) { + case QQuickFileDialog::Accepted: + QVERIFY(QMetaObject::invokeMethod(dialogHelper.window(), "doneAccepted")); + break; + case QQuickFileDialog::Rejected: + QVERIFY(QMetaObject::invokeMethod(dialogHelper.window(), "doneRejected")); + break; + } + + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); + QCOMPARE(dialogHelper.dialog->result(), result); +} + +QTEST_MAIN(tst_QQuickFileDialogImpl) + +#include "tst_qquickfiledialogimpl.moc" diff --git a/tests/auto/quickdialogs/qquickfolderdialogimpl/dummy_imports.qml b/tests/auto/quickdialogs/qquickfolderdialogimpl/dummy_imports.qml new file mode 100644 index 00000000000..7faa9b98e09 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfolderdialogimpl/dummy_imports.qml @@ -0,0 +1,10 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Qt.labs.folderlistmodel + +QtObject { } diff --git a/tests/auto/quickdialogs/qquickfontdialogimpl/BLACKLIST b/tests/auto/quickdialogs/qquickfontdialogimpl/BLACKLIST new file mode 100644 index 00000000000..7d88c9868a9 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfontdialogimpl/BLACKLIST @@ -0,0 +1,4 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format +# QTBUG-94225 +[clickAroundInTheFamilyListView] +b2qt diff --git a/tests/auto/quickdialogs/qquickfontdialogimpl/CMakeLists.txt b/tests/auto/quickdialogs/qquickfontdialogimpl/CMakeLists.txt new file mode 100644 index 00000000000..1b21daded05 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfontdialogimpl/CMakeLists.txt @@ -0,0 +1,39 @@ +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + +qt_internal_add_test(tst_qquickfontdialogimpl + SOURCES + tst_qquickfontdialogimpl.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickDialogs2Private + Qt::QuickDialogs2QuickImplPrivate + Qt::QuickDialogs2UtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +qt_internal_extend_target(tst_qquickfontdialogimpl CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_qquickfontdialogimpl CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/auto/quickdialogs/qquickfontdialogimpl/data/fontDialog.qml b/tests/auto/quickdialogs/qquickfontdialogimpl/data/fontDialog.qml new file mode 100644 index 00000000000..4979d473f36 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfontdialogimpl/data/fontDialog.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs + +ApplicationWindow { + width: 640 + height: 480 + + property alias dialog: dialog + + FontDialog { + id: dialog + objectName: "FontDialog" + } +} diff --git a/tests/auto/quickdialogs/qquickfontdialogimpl/dummy_imports.qml b/tests/auto/quickdialogs/qquickfontdialogimpl/dummy_imports.qml new file mode 100644 index 00000000000..5b8af918ea4 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfontdialogimpl/dummy_imports.qml @@ -0,0 +1,8 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQuick +import QtQuick.Layouts + +QtObject { } diff --git a/tests/auto/quickdialogs/qquickfontdialogimpl/tst_qquickfontdialogimpl.cpp b/tests/auto/quickdialogs/qquickfontdialogimpl/tst_qquickfontdialogimpl.cpp new file mode 100644 index 00000000000..cd8f98eb545 --- /dev/null +++ b/tests/auto/quickdialogs/qquickfontdialogimpl/tst_qquickfontdialogimpl.cpp @@ -0,0 +1,641 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtQml/qqmlfile.h> +#include <QtQuick/private/qquicklistview_p.h> +#include <QtQuickTemplates2/private/qquickitemdelegate_p.h> +#include <QtQuickDialogs2/private/qquickfontdialog_p.h> +#include <QtQuickDialogs2QuickImpl/private/qquickfontdialogimpl_p.h> +#include <QtQuickTest/quicktest.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> +#include <QtQuickControlsTestUtils/private/dialogstestutils_p.h> +#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h> +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquicktextfield_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p_p.h> +#include <QtQuickTemplates2/private/qquicklabel_p.h> +#include <QtQuickTemplates2/private/qquickoverlay_p.h> +#include <QtQuickControls2/qquickstyle.h> + +using namespace QQuickVisualTestUtils; +using namespace QQuickDialogTestUtils; +using namespace QQuickControlsTestUtils; + +class tst_QQuickFontDialogImpl : public QQmlDataTest +{ + Q_OBJECT + +public: + tst_QQuickFontDialogImpl(); + static void initMain() + { + // We need to set this attribute. + QCoreApplication::setAttribute(Qt::AA_DontUseNativeDialogs); + // We don't want to run this test for every style, as each one will have + // different ways of implementing the dialogs. + // For now we only test one style. + // TODO: use Basic + QQuickStyle::setStyle("Fusion"); + } + +private slots: + void changingWritingSystem(); + void clickAroundInTheFamilyListView(); + void settingUnderlineAndStrikeoutEffects(); + void changeFontSize(); + void changeDialogTitle(); + void searchFamily(); + void setCurrentFontFromApi(); + void sensibleDefaults(); + +private: + QQuickAbstractButton *findDialogButton(QQuickDialogButtonBox *box, const QString &buttonText) + { + for (int i = 0; i < box->count(); ++i) { + auto button = qobject_cast<QQuickAbstractButton *>(box->itemAt(i)); + if (button && button->text().toUpper() == buttonText.toUpper()) + return button; + } + return nullptr; + } + + bool closePopup(DialogTestHelper<QQuickFontDialog, QQuickFontDialogImpl> *dialogHelper, + QString dialogButton, QString &failureMessage) + { + auto dialogButtonBox = + dialogHelper->quickDialog->footer()->findChild<QQuickDialogButtonBox *>(); + + if (!dialogButtonBox) { + failureMessage = QLatin1String("dialogButtonBox is null"); + return false; + } + + QQuickAbstractButton *openButton = findDialogButton(dialogButtonBox, dialogButton); + + if (!openButton) { + failureMessage = + QLatin1String("Couldn't find a button with text '%1'").arg(dialogButton); + return false; + } + + bool clicked = clickButton(openButton); + + if (!clicked) { + failureMessage = QLatin1String("'%1' button was never clicked").arg(dialogButton); + return false; + } + + bool visible = dialogHelper->dialog->isVisible(); + if (visible) { + failureMessage = QLatin1String("Dialog is still visible after clicking the '%1' button") + .arg(dialogButton); + return false; + } + return true; + } +}; + +#define CREATE_DIALOG_TEST_HELPER \ + DialogTestHelper<QQuickFontDialog, QQuickFontDialogImpl> dialogHelper(this, "fontDialog.qml"); \ + QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); \ + QVERIFY(dialogHelper.waitForWindowActive()); + +#define CLOSE_DIALOG(BUTTON) \ + QString errorMessage; \ + QVERIFY2(closePopup(&dialogHelper, BUTTON, errorMessage), qPrintable(errorMessage)); \ + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); + +tst_QQuickFontDialogImpl::tst_QQuickFontDialogImpl() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +void tst_QQuickFontDialogImpl::changingWritingSystem() +{ + CREATE_DIALOG_TEST_HELPER + + // Open the dialog. + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + const QQuickTextEdit *sampleEdit = + dialogHelper.quickDialog->findChild<QQuickTextEdit *>("sampleEdit"); + QVERIFY(sampleEdit); + + QCOMPARE(sampleEdit->text(), QFontDatabase::writingSystemSample(QFontDatabase::Any)); + + // Check that the font family list view exist and add signal spy. + const QQuickListView *fontFamilyListView = + dialogHelper.quickDialog->findChild<QQuickListView *>("familyListView"); + QVERIFY(fontFamilyListView); + QSignalSpy fontFamilyModelSpy(fontFamilyListView, SIGNAL(modelChanged())); + + // Open the ComboBox's popup. + const QQuickComboBox *writingSystemComboBox = dialogHelper.quickDialog->findChild<QQuickComboBox*>(); + QVERIFY(writingSystemComboBox); + const QPoint comboBoxCenterPos = writingSystemComboBox->mapToScene({ writingSystemComboBox->width() / 2, writingSystemComboBox->height() / 2 }).toPoint(); + QTest::mouseClick(dialogHelper.window(), Qt::LeftButton, Qt::NoModifier, comboBoxCenterPos); + QTRY_VERIFY(writingSystemComboBox->popup()->isOpened()); + + // "Any" should be selected by default. + QQuickListView *comboBoxPopupListView = qobject_cast<QQuickListView*>(writingSystemComboBox->popup()->contentItem()); + QVERIFY(comboBoxPopupListView); + const int anyIndex = QFontDatabase::Any; + QQuickAbstractButton *anyDelegate = qobject_cast<QQuickAbstractButton*>(findViewDelegateItem(comboBoxPopupListView, anyIndex)); + QVERIFY(anyDelegate); + QCOMPARE(anyDelegate->text(), QFontDatabase::writingSystemName(QFontDatabase::Any)); + + QCOMPARE(fontFamilyModelSpy.count(), 0); + + // Select "Japanese" from the ComboBox. + const int japaneseIndex = QFontDatabase::Japanese; + QQuickAbstractButton *japaneseDelegate = qobject_cast<QQuickAbstractButton*>(findViewDelegateItem(comboBoxPopupListView, japaneseIndex)); + QVERIFY(japaneseDelegate); + QCOMPARE(japaneseDelegate->text(), QFontDatabase::writingSystemName(QFontDatabase::Japanese)); + QVERIFY(clickButton(japaneseDelegate)); + QTRY_VERIFY(!writingSystemComboBox->popup()->isVisible()); + + // Check that the contents of the font family listview changed + QCOMPARE(fontFamilyModelSpy.count(), 1); + + // And that the sample text is correctly set + QCOMPARE(sampleEdit->text(), QFontDatabase::writingSystemSample(QFontDatabase::Japanese)); + + // Then accept it to close it. + auto dialogButtonBox = dialogHelper.quickDialog->footer()->findChild<QQuickDialogButtonBox*>(); + QVERIFY(dialogButtonBox); + QQuickAbstractButton* openButton = findDialogButton(dialogButtonBox, "Ok"); + QVERIFY(openButton); + QVERIFY(clickButton(openButton)); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); +} + +void tst_QQuickFontDialogImpl::clickAroundInTheFamilyListView() +{ + CREATE_DIALOG_TEST_HELPER + + // Open the dialog. + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + QQuickListView *fontFamilyListView = + dialogHelper.quickDialog->findChild<QQuickListView *>("familyListView"); + QVERIFY(fontFamilyListView); + + const QQuickListView *fontStyleListView = + dialogHelper.quickDialog->findChild<QQuickListView *>("styleListView"); + QVERIFY(fontStyleListView); + + const QQuickListView *fontSizeListView = + dialogHelper.quickDialog->findChild<QQuickListView *>("sizeListView"); + QVERIFY(fontSizeListView); + + QSignalSpy currentFontSpy(dialogHelper.dialog, SIGNAL(currentFontChanged())); + QSignalSpy styleModelSpy(fontStyleListView, SIGNAL(modelChanged())); + QSignalSpy sizeModelSpy(fontSizeListView, SIGNAL(modelChanged())); + + QCOMPARE(fontFamilyListView->currentIndex(), 0); + QCOMPARE(fontStyleListView->currentIndex(), 0); + QCOMPARE(fontSizeListView->currentIndex(), 0); + + auto fontListModel = QFontDatabase::families(QFontDatabase::WritingSystem::Any); + fontListModel.removeIf(QFontDatabase::isPrivateFamily); + + // In case the font database contains a significant number of font families + const int maxNumberOfFamiliesToTest = 10; + + for (auto i = 1; i < qMin(fontListModel.size(), maxNumberOfFamiliesToTest); ++i) { + currentFontSpy.clear(); + styleModelSpy.clear(); + sizeModelSpy.clear(); + + const QString err = QString("LOOP INDEX %1, EXPECTED %2, ACTUAL %3").arg(i); + + const QFont currentFont = dialogHelper.dialog->currentFont(); + + const auto oldStyleModel = fontStyleListView->model(); + const auto oldSizeModel = fontSizeListView->model(); + + const QString expected1 = fontListModel[i - 1], actual1 = currentFont.family(); + QVERIFY2(expected1 == actual1, qPrintable(err.arg(expected1, actual1))); + + QQuickAbstractButton *fontDelegate = + qobject_cast<QQuickAbstractButton *>(findViewDelegateItem(fontFamilyListView, i)); + QVERIFY2(fontDelegate, qPrintable(QString("LOOP INDEX %1").arg(i))); + + QVERIFY2(clickButton(fontDelegate), qPrintable(QString("LOOP INDEX %1").arg(i))); + + const QString expected2 = fontListModel[i], + actual2 = dialogHelper.dialog->currentFont().family(); + QVERIFY2(expected2 == actual2, qPrintable(err.arg(expected2, actual2).append(", FONT ").append(fontDelegate->text()))); + const int currentFontSpyCount = currentFontSpy.count(); + QVERIFY2(currentFontSpyCount == 1, qPrintable(err.arg(1).arg(currentFontSpyCount).append(", FONT ").append(fontDelegate->text()))); + QVERIFY2((oldStyleModel == fontStyleListView->model()) != (styleModelSpy.count() == 1), + qPrintable(QString("LOOP INDEX %1").arg(i))); + QVERIFY2((oldSizeModel == fontSizeListView->model()) != (sizeModelSpy.count() == 1), + qPrintable(QString("LOOP INDEX %1").arg(i))); + } + + // Then accept it to close it. + QVERIFY(dialogHelper.dialog->currentFont() != dialogHelper.dialog->selectedFont()); + + CLOSE_DIALOG("Ok"); + + QVERIFY(dialogHelper.dialog->currentFont() == dialogHelper.dialog->selectedFont()); +} + +void tst_QQuickFontDialogImpl::settingUnderlineAndStrikeoutEffects() +{ + CREATE_DIALOG_TEST_HELPER + + // Open the dialog. + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + QSignalSpy currentFontSpy(dialogHelper.dialog, SIGNAL(currentFontChanged())); + + QQuickCheckBox *underlineCheckBox = + dialogHelper.quickDialog->findChild<QQuickCheckBox *>("underlineEffect"); + QVERIFY(underlineCheckBox); + + QQuickCheckBox *strikeoutCheckBox = + dialogHelper.quickDialog->findChild<QQuickCheckBox *>("strikeoutEffect"); + QVERIFY(strikeoutCheckBox); + + QVERIFY(!dialogHelper.dialog->currentFont().underline()); + QVERIFY(!dialogHelper.dialog->currentFont().strikeOut()); + + QVERIFY(clickButton(underlineCheckBox)); + + QCOMPARE(currentFontSpy.count(), 1); + QVERIFY(dialogHelper.dialog->currentFont().underline()); + QVERIFY(!dialogHelper.dialog->currentFont().strikeOut()); + + QVERIFY(clickButton(underlineCheckBox)); + + QCOMPARE(currentFontSpy.count(), 2); + QVERIFY(!dialogHelper.dialog->currentFont().underline()); + QVERIFY(!dialogHelper.dialog->currentFont().strikeOut()); + + QVERIFY(clickButton(strikeoutCheckBox)); + + QCOMPARE(currentFontSpy.count(), 3); + QVERIFY(!dialogHelper.dialog->currentFont().underline()); + QVERIFY(dialogHelper.dialog->currentFont().strikeOut()); + + QVERIFY(clickButton(strikeoutCheckBox)); + + QCOMPARE(currentFontSpy.count(), 4); + QVERIFY(!dialogHelper.dialog->currentFont().underline()); + QVERIFY(!dialogHelper.dialog->currentFont().strikeOut()); + + // Then accept it to close it. + CLOSE_DIALOG("Ok"); +} + +void tst_QQuickFontDialogImpl::changeFontSize() +{ + CREATE_DIALOG_TEST_HELPER + + // Open the dialog. + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + QQuickTextField *sizeEdit = dialogHelper.quickDialog->findChild<QQuickTextField *>("sizeEdit"); + QVERIFY(sizeEdit); + + QQuickListView *fontSizeListView = + dialogHelper.quickDialog->findChild<QQuickListView *>("sizeListView"); + QVERIFY(fontSizeListView); + + const QQuickItemDelegate *firstSizeDelegate = + qobject_cast<QQuickItemDelegate *>(findViewDelegateItem(fontSizeListView, 0)); + + QCOMPARE(dialogHelper.dialog->currentFont().pointSize(), firstSizeDelegate->text().toInt()); + + sizeEdit->setText("15"); + QCOMPARE(dialogHelper.dialog->currentFont().pointSize(), 15); + + sizeEdit->setText("22"); + QCOMPARE(dialogHelper.dialog->currentFont().pointSize(), 22); + + QVERIFY(dialogHelper.dialog->currentFont() != dialogHelper.dialog->selectedFont()); + + // Then accept it to close it. + CLOSE_DIALOG("Ok"); + + QVERIFY(dialogHelper.dialog->currentFont() == dialogHelper.dialog->selectedFont()); +} + +void tst_QQuickFontDialogImpl::changeDialogTitle() +{ + CREATE_DIALOG_TEST_HELPER + + // Open the dialog. + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + const auto dialogButtonBox = + dialogHelper.quickDialog->footer()->findChild<QQuickDialogButtonBox *>(); + QVERIFY(dialogButtonBox); + QQuickAbstractButton *cancelButton = findDialogButton(dialogButtonBox, "Cancel"); + QVERIFY(cancelButton); + + const QQuickLabel *titleLabel = dialogHelper.quickDialog->header()->findChild<QQuickLabel *>(); + QVERIFY(titleLabel); + + QCOMPARE(titleLabel->text(), QString()); + + const QString newTitle1 = QLatin1String("Some random title #1"); + + // Dialog must be closed for the title to update + QVERIFY(clickButton(cancelButton)); + QVERIFY(!dialogHelper.dialog->isVisible()); + QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); + + dialogHelper.dialog->setTitle(newTitle1); + + // Reopen the dialog + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + QVERIFY(dialogHelper.dialog->isVisible()); + QTRY_VERIFY(dialogHelper.quickDialog->isVisible()); + + QCOMPARE(titleLabel->text(), newTitle1); + + const QString newTitle2 = QLatin1String("Some random other title #2"); + + dialogHelper.dialog->setTitle(newTitle2); + + // Shouldn't update unless you reopen the dialog + QCOMPARE(titleLabel->text(), newTitle1); + + QVERIFY(clickButton(cancelButton)); + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + // Should now be updated + QCOMPARE(titleLabel->text(), newTitle2); + + CLOSE_DIALOG("Ok"); +} + +/* + Represents the expected search logic we use when the user types text into + one of the read-only text edits. + + As we test against real fonts installed on the system and hence cannot use + a hard-coded list, we need this helper to ensure that the (non-trivial) + searching behavior matches what we expect. +*/ +class ListSearchHelper +{ +public: + ListSearchHelper(const QStringList &model) + : m_model(model) + { + } + + int expectedCurrentIndexForSearch(const QString &searchText) + { + bool redo = false; + + do { + m_searchText.append(searchText); + + for (int i = 0; i < m_model.count(); ++i) { + if (m_model.at(i).startsWith(m_searchText, Qt::CaseInsensitive)) + return i; + } + + m_searchText.clear(); + + redo = !redo; + } while (redo); + + return -1; + } + +private: + QStringList m_model; + QString m_searchText; +}; + +void tst_QQuickFontDialogImpl::searchFamily() +{ + CREATE_DIALOG_TEST_HELPER + + // Open the dialog. + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + const QQuickTextField *familyEdit = + dialogHelper.quickDialog->findChild<QQuickTextField *>("familyEdit"); + QVERIFY(familyEdit); + + QQuickListView *fontFamilyListView = + dialogHelper.quickDialog->findChild<QQuickListView *>("familyListView"); + QVERIFY(fontFamilyListView); + + const QPoint familyEditCenterPos = + familyEdit->mapToScene({ familyEdit->width() / 2, familyEdit->height() / 2 }).toPoint(); + QTest::mouseClick(dialogHelper.window(), Qt::LeftButton, Qt::NoModifier, familyEditCenterPos); + QVERIFY(familyEdit->hasActiveFocus()); + + QSignalSpy familyListViewCurrentIndexSpy(fontFamilyListView, SIGNAL(currentIndexChanged())); + QVERIFY(familyListViewCurrentIndexSpy.isValid()); + + const QString alphabet("abcdefghijklmnopqrstuvwxyz"); + QStringList model = QFontDatabase::families(QFontDatabase::WritingSystem::Any); + model.removeIf(QFontDatabase::isPrivateFamily); + + ListSearchHelper listSearchHelper(model); + + // For each letter in the alphabet, press the corresponding key + // and check that the relevant delegate item in familyListView is selected. + for (auto alphabet_it = alphabet.cbegin(); alphabet_it != alphabet.cend(); alphabet_it++) { + const int previousIndex = fontFamilyListView->currentIndex(); + + const char keyEntered = alphabet_it->toLatin1(); + QTest::keyClick(dialogHelper.window(), keyEntered); + + int expectedListViewIndex = listSearchHelper.expectedCurrentIndexForSearch(QString(keyEntered)); + if (expectedListViewIndex == -1) { + // There was no match, so the currentIndex should remain unchanged. + expectedListViewIndex = previousIndex; + } + if (fontFamilyListView->currentIndex() == expectedListViewIndex) { + // Working as expected; keep testing. + continue; + } + + // Get the actual text of the current delegate item and the expected text. + auto currentDelegateItem = findViewDelegateItem(fontFamilyListView, fontFamilyListView->currentIndex()); + QVERIFY(currentDelegateItem); + const auto actualDelegateText = currentDelegateItem->property("text").toString(); + const auto expectedDelegateText = expectedListViewIndex != -1 ? model.at(expectedListViewIndex) : "(none)"; + + QFAIL(qPrintable(QString::fromLatin1("Expected fontFamilyListView to" + " change its currentIndex to %1 (%2) after typing '%3', but it is %4 (%5)") + .arg(expectedListViewIndex) + .arg(expectedDelegateText) + .arg(keyEntered) + .arg(fontFamilyListView->currentIndex()) + .arg(actualDelegateText))); + } + + CLOSE_DIALOG("Ok"); +} + +void tst_QQuickFontDialogImpl::setCurrentFontFromApi() +{ + CREATE_DIALOG_TEST_HELPER + + QSignalSpy currentFontSpy(dialogHelper.dialog, SIGNAL(currentFontChanged())); + + // Open the dialog. + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + QQuickListView *fontFamilyListView = + dialogHelper.quickDialog->findChild<QQuickListView *>("familyListView"); + QVERIFY(fontFamilyListView); + + QQuickListView *fontStyleListView = + dialogHelper.quickDialog->findChild<QQuickListView *>("styleListView"); + QVERIFY(fontStyleListView); + + QQuickListView *fontSizeListView = + dialogHelper.quickDialog->findChild<QQuickListView *>("sizeListView"); + QVERIFY(fontSizeListView); + + QQuickTextField *fontSizeEdit = + dialogHelper.quickDialog->findChild<QQuickTextField *>("sizeEdit"); + QVERIFY(fontSizeEdit); + + // From when the listviews are populated + QCOMPARE(currentFontSpy.count(), 1); + + currentFontSpy.clear(); + + // testing some available fonts + const auto familyModel = fontFamilyListView->model().toStringList(); + int spyCounter = 0; + const int maxNumberOfFontFamilies = 10, maxNumberOfStyles = 3; + int size = 10; + int familyCounter = 0; + for (auto family = familyModel.cbegin(); family != familyModel.cend() && familyCounter < maxNumberOfFontFamilies; family++, familyCounter++) + { + const QString style = QFontDatabase::styles(*family).constFirst(); + + const QFont f = QFontDatabase::font(*family, style, size); + dialogHelper.dialog->setCurrentFont(f); + + const int familyIndex = fontFamilyListView->currentIndex(); + QVERIFY(familyIndex >= 0); + QCOMPARE(familyModel.at(familyIndex), *family); + + const QStringList styleModel = fontStyleListView->model().toStringList(); + QVERIFY(!styleModel.isEmpty()); // Any valid font should always have at least one style. + QCOMPARE(styleModel.at(fontStyleListView->currentIndex()), style); + QCOMPARE(fontSizeEdit->text(), QString::number(size++)); + + QCOMPARE(currentFontSpy.count(), ++spyCounter); + + for (int styleIt = 0; styleIt < qMin(styleModel.count(), maxNumberOfStyles); ++styleIt) { + const QString currentStyle = styleModel.at(styleIt); + + const QFont f = QFontDatabase::font(*family, currentStyle, size); + dialogHelper.dialog->setCurrentFont(f); + + QCOMPARE(styleModel.at(fontStyleListView->currentIndex()), currentStyle); + QCOMPARE(currentFontSpy.count(), ++spyCounter); + } + } + + CLOSE_DIALOG("Ok"); +} + +void tst_QQuickFontDialogImpl::sensibleDefaults() +{ + CREATE_DIALOG_TEST_HELPER + + // Open the dialog. + QVERIFY(dialogHelper.openDialog()); + QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); + + QQuickListView *fontFamilyListView = + dialogHelper.quickDialog->findChild<QQuickListView *>("familyListView"); + QVERIFY(fontFamilyListView); + QQuickListView *fontStyleListView = + dialogHelper.quickDialog->findChild<QQuickListView *>("styleListView"); + QVERIFY(fontStyleListView); + QQuickListView *fontSizeListView = + dialogHelper.quickDialog->findChild<QQuickListView *>("sizeListView"); + QVERIFY(fontSizeListView); + QQuickTextField *fontFamilyTextField = + dialogHelper.quickDialog->findChild<QQuickTextField *>("familyEdit"); + QVERIFY(fontFamilyTextField); + QQuickTextField *fontStyleTextField = + dialogHelper.quickDialog->findChild<QQuickTextField *>("styleEdit"); + QVERIFY(fontStyleTextField); + + // The indexes should initially be 0. + QCOMPARE(fontFamilyListView->currentIndex(), 0); + QCOMPARE(fontStyleListView->currentIndex(), 0); + QCOMPARE(fontSizeListView->currentIndex(), 0); + + // Setting the family to an empty model + fontFamilyListView->setModel(QStringList()); + + // The listviews for font family and style should now have an empty model with indexes set to -1 + QVERIFY(fontFamilyListView->model().toStringList().isEmpty()); + QVERIFY(fontStyleListView->model().toStringList().isEmpty()); + QCOMPARE(fontFamilyListView->currentIndex(), -1); + QCOMPARE(fontStyleListView->currentIndex(), -1); + QVERIFY(fontFamilyTextField->text().isEmpty()); + QVERIFY(fontStyleTextField->text().isEmpty()); + + CLOSE_DIALOG("Ok"); +} + +QTEST_MAIN(tst_QQuickFontDialogImpl) + +#include "tst_qquickfontdialogimpl.moc" diff --git a/tests/auto/quickdialogs/qquickmessagedialogimpl/dummy_imports.qml b/tests/auto/quickdialogs/qquickmessagedialogimpl/dummy_imports.qml new file mode 100644 index 00000000000..5b8af918ea4 --- /dev/null +++ b/tests/auto/quickdialogs/qquickmessagedialogimpl/dummy_imports.qml @@ -0,0 +1,8 @@ +// This file exists for the sole purpose for qmlimportscanner to find +// which modules it needs to extract for deployment. +// Otherwise, it fails to find the imports that are expressed in C++. + +import QtQuick +import QtQuick.Layouts + +QtObject { } diff --git a/tests/auto/quicktest/CMakeLists.txt b/tests/auto/quicktest/CMakeLists.txt index 45c763eec93..07b7cd72465 100644 --- a/tests/auto/quicktest/CMakeLists.txt +++ b/tests/auto/quicktest/CMakeLists.txt @@ -3,5 +3,7 @@ add_subdirectory(polish) add_subdirectory(signalspy) add_subdirectory(quicktestmainwithsetup) -add_subdirectory(testfiltering) +if(QT_FEATURE_process AND NOT ANDROID) # QTBUG-100175 + add_subdirectory(testfiltering) +endif() add_subdirectory(testswithcomponents) diff --git a/tests/auto/quicktest/polish-qml/CMakeLists.txt b/tests/auto/quicktest/polish-qml/CMakeLists.txt index ff09b1e82ec..0cf36f9ab47 100644 --- a/tests/auto/quicktest/polish-qml/CMakeLists.txt +++ b/tests/auto/quicktest/polish-qml/CMakeLists.txt @@ -13,14 +13,12 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_polish-qml QMLTEST SOURCES - ../../shared/util.cpp ../../shared/util.h tst_polish-qml.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Quick Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quicktest/polish-qml/tst_polish-qml.cpp b/tests/auto/quicktest/polish-qml/tst_polish-qml.cpp index e525a8a5af1..a378af58af4 100644 --- a/tests/auto/quicktest/polish-qml/tst_polish-qml.cpp +++ b/tests/auto/quicktest/polish-qml/tst_polish-qml.cpp @@ -33,8 +33,6 @@ #include <QtQuick/qquickview.h> #include <QtQuickTest/quicktest.h> -#include "../../shared/util.h" - class CustomItem : public QQuickItem { Q_OBJECT diff --git a/tests/auto/quicktest/polish/CMakeLists.txt b/tests/auto/quicktest/polish/CMakeLists.txt index d980935c885..acb29bab9d8 100644 --- a/tests/auto/quicktest/polish/CMakeLists.txt +++ b/tests/auto/quicktest/polish/CMakeLists.txt @@ -13,14 +13,12 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_polish QMLTEST SOURCES - ../../shared/util.cpp ../../shared/util.h tst_polish.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Quick Qt::QuickPrivate + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quicktest/polish/tst_polish.cpp b/tests/auto/quicktest/polish/tst_polish.cpp index 3b96002cd22..ec0580c15d8 100644 --- a/tests/auto/quicktest/polish/tst_polish.cpp +++ b/tests/auto/quicktest/polish/tst_polish.cpp @@ -33,7 +33,7 @@ #include <QQuickView> #include <QtQuickTest/quicktest.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> class CustomItem : public QQuickItem { @@ -62,6 +62,7 @@ private slots: }; tst_Polish::tst_Polish() + : QQmlDataTest(QT_QMLTEST_DATADIR) { qmlRegisterType<CustomItem>("Test", 1, 0, "CustomItem"); } diff --git a/tests/auto/quicktest/quicktestmainwithsetup/CMakeLists.txt b/tests/auto/quicktest/quicktestmainwithsetup/CMakeLists.txt index 9d627dbe437..bca7d7fb002 100644 --- a/tests/auto/quicktest/quicktestmainwithsetup/CMakeLists.txt +++ b/tests/auto/quicktest/quicktestmainwithsetup/CMakeLists.txt @@ -10,16 +10,19 @@ file(GLOB_RECURSE test_data_glob ${CMAKE_CURRENT_SOURCE_DIR}/data/*.qml) list(APPEND test_data ${test_data_glob}) +file(GLOB_RECURSE test_imports_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/imports/*) +list(APPEND test_data ${test_imports_glob}) + qt_internal_add_test(tst_quicktestmainwithsetup QMLTEST SOURCES - ../../shared/util.cpp ../../shared/util.h tst_quicktestmainwithsetup.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Quick + Qt::QuickTestUtilsPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quicktest/quicktestmainwithsetup/tst_quicktestmainwithsetup.cpp b/tests/auto/quicktest/quicktestmainwithsetup/tst_quicktestmainwithsetup.cpp index b5deeceac4f..38b50bd6173 100644 --- a/tests/auto/quicktest/quicktestmainwithsetup/tst_quicktestmainwithsetup.cpp +++ b/tests/auto/quicktest/quicktestmainwithsetup/tst_quicktestmainwithsetup.cpp @@ -33,8 +33,6 @@ #include <QtQuick/qquickview.h> #include <QtQuickTest/quicktest.h> -#include "../../shared/util.h" - class QmlRegisterTypeCppType : public QObject { Q_OBJECT diff --git a/tests/auto/quicktest/signalspy/CMakeLists.txt b/tests/auto/quicktest/signalspy/CMakeLists.txt index cda19b605a3..2618073cf37 100644 --- a/tests/auto/quicktest/signalspy/CMakeLists.txt +++ b/tests/auto/quicktest/signalspy/CMakeLists.txt @@ -4,16 +4,20 @@ ## tst_signalspy Test: ##################################################################### +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + qt_internal_add_test(tst_signalspy SOURCES - ../../shared/util.cpp ../../shared/util.h mypropertymap.cpp mypropertymap.h tst_signalspy.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::Gui Qt::Quick + Qt::QuickTestUtilsPrivate + TESTDATA ${test_data} ) ## Scopes: diff --git a/tests/auto/quicktest/signalspy/data/signalspy2.qml b/tests/auto/quicktest/signalspy/data/signalspy2.qml new file mode 100644 index 00000000000..b314e4f1876 --- /dev/null +++ b/tests/auto/quicktest/signalspy/data/signalspy2.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtTest 1.1 +import MyImport 1.0 + +Rectangle { + id:rect + width: 200 + height: 200 + color:"red" + + MouseArea { + id: mouseArea + anchors.fill: parent + } + + MyPropertyMap { + id: propertyMap + objectName: "propertyMap" + } + + SignalSpy { + objectName: "mouseSpy" + signalName: "pressed" + target: mouseArea + } + + SignalSpy { + objectName: "propertyMapSpy" + signalName: "mySignal" + target: propertyMap + } +} diff --git a/tests/auto/quicktest/signalspy/tst_signalspy.cpp b/tests/auto/quicktest/signalspy/tst_signalspy.cpp index 0806f43c1c0..120e4394e1e 100644 --- a/tests/auto/quicktest/signalspy/tst_signalspy.cpp +++ b/tests/auto/quicktest/signalspy/tst_signalspy.cpp @@ -32,7 +32,7 @@ #include <qquickitem.h> #include <qquickview.h> -#include "../../shared/util.h" +#include <QtQuickTestUtils/private/qmlutils_p.h> #include "mypropertymap.h" class tst_SignalSpy : public QQmlDataTest @@ -50,6 +50,7 @@ private slots: }; tst_SignalSpy::tst_SignalSpy() + : QQmlDataTest(QT_QMLTEST_DATADIR) { qmlRegisterType<MyPropertyMap>("MyImport", 1, 0, "MyPropertyMap"); } @@ -69,25 +70,32 @@ void tst_SignalSpy::testValid() void tst_SignalSpy::testCount() { - QQuickView window; - window.resize(200, 200); - window.setSource(testFileUrl("signalspy.qml")); - window.show(); - QVERIFY(QTest::qWaitForWindowActive(&window)); - QVERIFY(window.rootObject() != nullptr); - - QObject *mouseSpy = window.rootObject()->findChild<QObject*>("mouseSpy"); - QCOMPARE(mouseSpy->property("count").toInt(), 0); - - QObject *propertyMapSpy = window.rootObject()->findChild<QObject*>("propertyMapSpy"); - QCOMPARE(propertyMapSpy->property("count").toInt(), 0); - - QTest::mouseClick(&window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(100, 100)); - QTRY_COMPARE(mouseSpy->property("count").toInt(), 1); - - MyPropertyMap *propertyMap = static_cast<MyPropertyMap *>(window.rootObject()->findChild<QObject*>("propertyMap")); - Q_EMIT propertyMap->mySignal(); - QCOMPARE(propertyMapSpy->property("count").toInt(), 1); + const QUrl urls[] = { + testFileUrl("signalspy.qml"), + testFileUrl("signalspy2.qml"), + }; + for (const auto &url : urls) { + QQuickView window; + window.resize(200, 200); + window.setSource(url); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + QVERIFY(window.rootObject() != nullptr); + + QObject *mouseSpy = window.rootObject()->findChild<QObject *>("mouseSpy"); + QCOMPARE(mouseSpy->property("count").toInt(), 0); + + QObject *propertyMapSpy = window.rootObject()->findChild<QObject *>("propertyMapSpy"); + QCOMPARE(propertyMapSpy->property("count").toInt(), 0); + + QTest::mouseClick(&window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(100, 100)); + QTRY_COMPARE(mouseSpy->property("count").toInt(), 1); + + MyPropertyMap *propertyMap = static_cast<MyPropertyMap *>( + window.rootObject()->findChild<QObject *>("propertyMap")); + Q_EMIT propertyMap->mySignal(); + QCOMPARE(propertyMapSpy->property("count").toInt(), 1); + } } QTEST_MAIN(tst_SignalSpy) diff --git a/tests/auto/quickwidgets/qquickwidget/BLACKLIST b/tests/auto/quickwidgets/qquickwidget/BLACKLIST index 44ab3e93970..095e9ee4849 100644 --- a/tests/auto/quickwidgets/qquickwidget/BLACKLIST +++ b/tests/auto/quickwidgets/qquickwidget/BLACKLIST @@ -3,5 +3,3 @@ opensuse-42.3 opensuse-leap [enterLeave] macos -[synthMouseFromTouch] # QTBUG-86729 -* diff --git a/tests/auto/quickwidgets/qquickwidget/CMakeLists.txt b/tests/auto/quickwidgets/qquickwidget/CMakeLists.txt index 9018d5544d6..5ce5cf31254 100644 --- a/tests/auto/quickwidgets/qquickwidget/CMakeLists.txt +++ b/tests/auto/quickwidgets/qquickwidget/CMakeLists.txt @@ -12,19 +12,19 @@ list(APPEND test_data ${test_data_glob}) qt_internal_add_test(tst_qquickwidget SOURCES - ../../shared/util.cpp ../../shared/util.h tst_qquickwidget.cpp - INCLUDE_DIRECTORIES - ../../shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate Qt::QmlPrivate Qt::QuickPrivate + Qt::QuickTemplates2Private Qt::QuickWidgets Qt::QuickWidgetsPrivate Qt::WidgetsPrivate + Qt::QuickTestUtilsPrivate + Qt::TestPrivate TESTDATA ${test_data} ) diff --git a/tests/auto/quickwidgets/qquickwidget/data/FocusOnClick.qml b/tests/auto/quickwidgets/qquickwidget/data/FocusOnClick.qml new file mode 100644 index 00000000000..6b1ca0f15af --- /dev/null +++ b/tests/auto/quickwidgets/qquickwidget/data/FocusOnClick.qml @@ -0,0 +1,33 @@ +import QtQuick + +Rectangle { + width: 300 + height: 100 + color: "lightblue" + Column { + Rectangle { + width: 150 + height: 50 + color: text1.activeFocus ? "pink" : "gray" + TextInput + { + id: text1 + objectName: "text1" + anchors.fill: parent + text: "Enter text" + } + } + Rectangle { + width: 150 + height: 50 + color: text2.activeFocus ? "yellow" : "lightgreen" + TextInput + { + id: text2 + objectName: "text2" + anchors.fill: parent + text: "Enter text" + } + } + } +} diff --git a/tests/auto/quickwidgets/qquickwidget/data/button.qml b/tests/auto/quickwidgets/qquickwidget/data/button.qml new file mode 100644 index 00000000000..30698908d77 --- /dev/null +++ b/tests/auto/quickwidgets/qquickwidget/data/button.qml @@ -0,0 +1,27 @@ +import QtQuick +import QtQuick.Controls.Basic + +Item { + width: 100 + height: 100 + visible: true + + property bool wasPressed: false + property bool wasReleased: false + property bool wasClicked: false + + Popup { + closePolicy: Popup.NoAutoClose + visible: true + + Button { + objectName: "button" + text: "TAP ME" + anchors.fill: parent + + onPressed: wasPressed = true + onReleased: wasReleased = true + onClicked: wasClicked = true + } + } +} diff --git a/tests/auto/quickwidgets/qquickwidget/data/controls.qml b/tests/auto/quickwidgets/qquickwidget/data/controls.qml new file mode 100644 index 00000000000..3e415f33dab --- /dev/null +++ b/tests/auto/quickwidgets/qquickwidget/data/controls.qml @@ -0,0 +1,23 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Rectangle { + id: root + ColumnLayout { + anchors.fill: parent + ComboBox { + } + Button { + text: "Button" + } + CheckBox { + text: "CheckBox" + } + RadioButton { + text: "RadioButton" + } + TextField { + } + } +} diff --git a/tests/auto/quickwidgets/qquickwidget/data/mouse.qml b/tests/auto/quickwidgets/qquickwidget/data/mouse.qml index 5d1c6e84436..25a7329a081 100644 --- a/tests/auto/quickwidgets/qquickwidget/data/mouse.qml +++ b/tests/auto/quickwidgets/qquickwidget/data/mouse.qml @@ -7,8 +7,10 @@ Rectangle { property bool wasClicked: false property bool wasDoubleClicked: false property bool wasMoved: false + color: ma.pressed ? "wheat" : "lightsteelblue" MouseArea { + id: ma anchors.fill: parent hoverEnabled: true onClicked: wasClicked = true diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp index 6ae0dc12acb..54673b70ceb 100644 --- a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp +++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp @@ -29,12 +29,15 @@ #include <qtest.h> #include <qtesttouch.h> #include <QtTest/QSignalSpy> +#include <QtTest/private/qtesthelpers_p.h> #include <QtQml/qqmlcomponent.h> #include <QtQml/qqmlcontext.h> #include <QtQuick/qquickview.h> #include <QtQuick/qquickitem.h> #include <QtQuick/private/qquickitem_p.h> -#include "../../shared/util.h" +#include <QtQuick/private/qquickmousearea_p.h> +#include <QtQuickTemplates2/private/qquickbutton_p.h> +#include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtGui/QWindow> #include <QtGui/QScreen> #include <QtGui/QImage> @@ -48,6 +51,10 @@ #include <QtQuickWidgets/QQuickWidget> +#if QT_CONFIG(graphicsview) +# include <QtWidgets/QGraphicsView> +# include <QtWidgets/QGraphicsProxyWidget> +#endif Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") class MouseRecordingQQWidget : public QQuickWidget @@ -81,17 +88,18 @@ class MouseRecordingQQWidget : public QQuickWidget class MouseRecordingItem : public QQuickItem { public: - MouseRecordingItem(bool acceptTouch, QQuickItem *parent = nullptr) + MouseRecordingItem(bool acceptTouch, bool acceptTouchPress, QQuickItem *parent = nullptr) : QQuickItem(parent) - , m_acceptTouch(acceptTouch) + , m_acceptTouchPress(acceptTouchPress) { setSize(QSizeF(300, 300)); setAcceptedMouseButtons(Qt::LeftButton); + setAcceptTouchEvents(acceptTouch); } protected: void touchEvent(QTouchEvent* event) override { - event->setAccepted(m_acceptTouch); + event->setAccepted(m_acceptTouchPress); m_touchEvents << event->type(); qCDebug(lcTests) << "accepted?" << event->isAccepted() << event; } @@ -113,7 +121,7 @@ class MouseRecordingItem : public QQuickItem QList<QEvent::Type> m_touchEvents; private: - bool m_acceptTouch; + bool m_acceptTouchPress; }; class tst_qquickwidget : public QQmlDataTest @@ -142,8 +150,16 @@ private slots: void mouseEventWindowPos(); void synthMouseFromTouch_data(); void synthMouseFromTouch(); + void touchTapMouseArea(); + void touchTapButton(); + void touchMultipleWidgets(); void tabKey(); void resizeOverlay(); + void controls(); + void focusOnClick(); +#if QT_CONFIG(graphicsview) + void focusOnClickInProxyWidget(); +#endif private: QPointingDevice *device = QTest::createTouchDevice(); @@ -151,6 +167,7 @@ private slots: }; tst_qquickwidget::tst_qquickwidget() + : QQmlDataTest(QT_QMLTEST_DATADIR) { QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi); } @@ -438,6 +455,9 @@ void tst_qquickwidget::grabBeforeShow() void tst_qquickwidget::reparentToNewWindow() { +#ifdef Q_OS_ANDROID + QSKIP("This test crashes on Android (see QTBUG-100173)"); +#endif QWidget window1; QWidget window2; @@ -533,6 +553,9 @@ void tst_qquickwidget::shortcuts() void tst_qquickwidget::enterLeave() { +#ifdef Q_OS_ANDROID + QSKIP("Android has no cursor"); +#endif QQuickWidget view; view.setSource(testFileUrl("enterleave.qml")); @@ -608,7 +631,7 @@ void tst_qquickwidget::synthMouseFromTouch() QWidget window; window.setAttribute(Qt::WA_AcceptTouchEvents); QScopedPointer<MouseRecordingQQWidget> childView(new MouseRecordingQQWidget(&window)); - MouseRecordingItem *item = new MouseRecordingItem(acceptTouch, nullptr); + MouseRecordingItem *item = new MouseRecordingItem(!synthMouse, acceptTouch, nullptr); childView->setContent(QUrl(), nullptr, item); window.resize(300, 300); childView->resize(300, 300); @@ -623,13 +646,106 @@ void tst_qquickwidget::synthMouseFromTouch() QTest::touchEvent(&window, device).move(0, p2, &window); QTest::touchEvent(&window, device).release(0, p2, &window); - QCOMPARE(item->m_touchEvents.count(), !synthMouse && !acceptTouch ? 1 : 3); - QCOMPARE(item->m_mouseEvents.count(), (acceptTouch || !synthMouse) ? 0 : 3); + qCDebug(lcTests) << item->m_touchEvents << item->m_mouseEvents; + QCOMPARE(item->m_touchEvents.count(), synthMouse ? 0 : (acceptTouch ? 3 : 1)); + QCOMPARE(item->m_mouseEvents.count(), synthMouse ? 3 : 0); QCOMPARE(childView->m_mouseEvents.count(), 0); for (const auto &ev : item->m_mouseEvents) QCOMPARE(ev, Qt::MouseEventSynthesizedByQt); } +void tst_qquickwidget::touchTapMouseArea() +{ + QWidget window; + window.resize(100, 100); + window.setObjectName("window widget"); + window.setAttribute(Qt::WA_AcceptTouchEvents); + QVERIFY(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)); + QQuickWidget *quick = new QQuickWidget(&window); + quick->setSource(testFileUrl("mouse.qml")); + quick->move(50, 50); + quick->setObjectName("quick widget"); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + QQuickItem *rootItem = quick->rootObject(); + QVERIFY(rootItem); + QQuickMouseArea *ma = rootItem->findChild<QQuickMouseArea *>(); + QVERIFY(ma); + + QPoint p1 = QPoint(70, 70); + QTest::touchEvent(&window, device).press(0, p1, &window); + QTRY_COMPARE(ma->pressed(), true); + QTest::touchEvent(&window, device).move(0, p1, &window); + QTest::touchEvent(&window, device).release(0, p1, &window); + QTRY_COMPARE(ma->pressed(), false); + QVERIFY(rootItem->property("wasClicked").toBool()); +} + +void tst_qquickwidget::touchTapButton() +{ + QWidget window; + QQuickWidget *quick = new QQuickWidget; + quick->setSource(testFileUrl("button.qml")); + + QHBoxLayout hbox; + hbox.addWidget(quick); + window.setLayout(&hbox); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + QQuickItem *rootItem = quick->rootObject(); + QVERIFY(rootItem); + QQuickButton *button = rootItem->findChild<QQuickButton *>("button"); + QVERIFY(button); + + const QPoint point = quick->mapTo(&window, button->mapToScene(button->boundingRect().center()).toPoint()); + QTest::touchEvent(&window, device).press(0, point, &window).commit(); + QTRY_VERIFY(rootItem->property("wasPressed").toBool()); + QTest::touchEvent(&window, device).release(0, point, &window).commit(); + QTRY_VERIFY(rootItem->property("wasReleased").toBool()); + QTRY_VERIFY(rootItem->property("wasClicked").toBool()); +} + +void tst_qquickwidget::touchMultipleWidgets() +{ + QWidget window; + QQuickWidget *leftQuick = new QQuickWidget; + leftQuick->setSource(testFileUrl("button.qml")); + QQuickWidget *rightQuick = new QQuickWidget; + rightQuick->setSource(testFileUrl("button.qml")); + + QHBoxLayout hbox; + hbox.addWidget(leftQuick); + hbox.addWidget(rightQuick); + window.setLayout(&hbox); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + QQuickItem *leftRootItem = leftQuick->rootObject(); + QQuickItem *rightRootItem = rightQuick->rootObject(); + QVERIFY(leftRootItem); + QVERIFY(rightRootItem); + QQuickButton *leftButton = leftRootItem->findChild<QQuickButton *>("button"); + QQuickButton *rightButton = rightRootItem->findChild<QQuickButton *>("button"); + QVERIFY(leftButton); + QVERIFY(rightButton); + + const QPoint leftPoint = leftQuick->mapTo(&window, leftButton->mapToScene( + leftButton->boundingRect().center()).toPoint()); + const QPoint rightPoint = rightQuick->mapTo(&window, rightButton->mapToScene( + rightButton->boundingRect().center()).toPoint()); + QTest::touchEvent(&window, device).press(0, leftPoint, &window).commit(); + QTRY_VERIFY(leftRootItem->property("wasPressed").toBool()); + QTest::touchEvent(&window, device).press(1, rightPoint, &window).commit(); + QTRY_VERIFY(rightRootItem->property("wasPressed").toBool()); + QTest::touchEvent(&window, device).release(1, rightPoint, &window).commit(); + QTRY_VERIFY(rightRootItem->property("wasReleased").toBool()); + QVERIFY(rightRootItem->property("wasClicked").toBool()); + QTest::touchEvent(&window, device).release(0, leftPoint, &window).commit(); + QTRY_VERIFY(leftRootItem->property("wasReleased").toBool()); + QVERIFY(leftRootItem->property("wasClicked").toBool()); +} + void tst_qquickwidget::tabKey() { if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls) @@ -722,7 +838,7 @@ void tst_qquickwidget::resizeOverlay() overlay->startListening(); widget.resize(200, 200); - widget.show(); + QTestPrivate::androidCompatibleShow(&widget); QCOMPARE(rootItem->width(), 200); QCOMPARE(rootItem->height(), 200); QCOMPARE(overlay->width(), rootItem->width()); @@ -735,6 +851,122 @@ void tst_qquickwidget::resizeOverlay() QCOMPARE(overlay->height(), rootItem->height()); } +void tst_qquickwidget::controls() +{ + // Smoke test for having some basic Quick Controls in a scene in a QQuickWidget. + QWidget widget; + QVBoxLayout *contentVerticalLayout = new QVBoxLayout(&widget); + QQuickWidget *quickWidget = new QQuickWidget(testFileUrl("controls.qml"), &widget); + QCOMPARE(quickWidget->status(), QQuickWidget::Ready); + quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + contentVerticalLayout->addWidget(quickWidget); + + widget.resize(400, 400); + widget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&widget)); + + QQuickItem *rootItem = qobject_cast<QQuickItem *>(quickWidget->rootObject()); + QVERIFY(rootItem); + QCOMPARE(rootItem->size(), quickWidget->size()); + QSize oldSize = quickWidget->size(); + + // Verify that QTBUG-95937 no longer occurs. (on Windows with the default + // native windows style this used to assert in debug builds) + widget.resize(300, 300); + QTRY_VERIFY(quickWidget->width() < oldSize.width()); + QTRY_COMPARE(rootItem->size(), quickWidget->size()); + + widget.hide(); + widget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&widget)); +} + +void tst_qquickwidget::focusOnClick() +{ + QQuickWidget quick; + quick.setSource(testFileUrl("FocusOnClick.qml")); + quick.show(); + QVERIFY(QTest::qWaitForWindowExposed(&quick)); + QQuickItem *rootItem = quick.rootObject(); + QVERIFY(rootItem); + QWindow *window = quick.windowHandle(); + QVERIFY(window); + + QQuickItem *text1 = rootItem->findChild<QQuickItem *>("text1"); + QVERIFY(text1); + QQuickItem *text2 = rootItem->findChild<QQuickItem *>("text2"); + QVERIFY(text2); + + QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(75, 25)); + QTRY_VERIFY(text1->hasActiveFocus()); + QVERIFY(!text2->hasActiveFocus()); + + QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(75, 75)); + QTRY_VERIFY(text2->hasActiveFocus()); + QVERIFY(!text1->hasActiveFocus()); + +} + +#if QT_CONFIG(graphicsview) +void tst_qquickwidget::focusOnClickInProxyWidget() +{ + QGraphicsScene scene(0,0,400,400); + + QGraphicsView view1(&scene); + view1.setFrameStyle(QFrame::NoFrame); + view1.resize(400,400); + QTestPrivate::androidCompatibleShow(&view1); + + + + QQuickWidget* quick = new QQuickWidget(testFileUrl("FocusOnClick.qml")); + quick->resize(300,100); + quick->setAttribute(Qt::WA_AcceptTouchEvents); + QGraphicsProxyWidget* proxy = scene.addWidget(quick); + proxy->setAcceptTouchEvents(true); + + // QTRY_VERIFY(quick->rootObject()); + QQuickItem *rootItem = quick->rootObject(); + QVERIFY(rootItem); + QQuickItem *text1 = rootItem->findChild<QQuickItem *>("text1"); + QVERIFY(text1); + QQuickItem *text2 = rootItem->findChild<QQuickItem *>("text2"); + QVERIFY(text2); + + QVERIFY(QTest::qWaitForWindowExposed(&view1)); + QWindow *window1 = view1.windowHandle(); + QVERIFY(window1); + + // Click in the QGraphicsView, outside the QuickWidget + QTest::mouseClick(window1, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(300, 300)); + QTRY_VERIFY(!text1->hasActiveFocus()); + QTRY_VERIFY(!text2->hasActiveFocus()); + + // Click on text1 + QTest::mouseClick(window1, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(75, 25)); + QTRY_VERIFY(text1->hasActiveFocus()); + QVERIFY(!text2->hasActiveFocus()); + + + // Now create a second view and repeat, in order to verify that we handle one QQuickItem being in multiple windows + QGraphicsView view2(&scene); + view2.resize(400,400); + QTestPrivate::androidCompatibleShow(&view2); + + QVERIFY(QTest::qWaitForWindowExposed(&view2)); + QWindow *window2 = view2.windowHandle(); + QVERIFY(window2); + + QTest::mouseClick(window2, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(300, 300)); + QTRY_VERIFY(!text1->hasActiveFocus()); + QTRY_VERIFY(!text2->hasActiveFocus()); + + QTest::mouseClick(window2, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(75, 25)); + QTRY_VERIFY(text1->hasActiveFocus()); + QVERIFY(!text2->hasActiveFocus()); +} +#endif + QTEST_MAIN(tst_qquickwidget) #include "tst_qquickwidget.moc" diff --git a/tests/auto/shared/platforminputcontext.h b/tests/auto/shared/platforminputcontext.h deleted file mode 100644 index bcb6f52c151..00000000000 --- a/tests/auto/shared/platforminputcontext.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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 <qpa/qplatforminputcontext.h> -#include <QtGui/QInputMethod> - -class PlatformInputContext : public QPlatformInputContext -{ -public: - PlatformInputContext() - : m_visible(false), m_action(QInputMethod::Click), m_cursorPosition(0), - m_invokeActionCallCount(0), m_showInputPanelCallCount(0), m_hideInputPanelCallCount(0), - m_updateCallCount(0), m_direction(Qt::LeftToRight) - { - } - - void showInputPanel() override - { - m_visible = true; - m_showInputPanelCallCount++; - } - void hideInputPanel() override - { - m_visible = false; - m_hideInputPanelCallCount++; - } - bool isInputPanelVisible() const override - { - return m_visible; - } - void invokeAction(QInputMethod::Action action, int cursorPosition) override - { - m_invokeActionCallCount++; - m_action = action; - m_cursorPosition = cursorPosition; - } - void update(Qt::InputMethodQueries) override - { - m_updateCallCount++; - } - - QLocale locale() const override - { - if (m_direction == Qt::RightToLeft) - return QLocale(QLocale::Arabic); - else - return QLocale(QLocale::English); - } - - Qt::LayoutDirection inputDirection() const override - { - return m_direction; - } - - void setInputDirection(Qt::LayoutDirection direction) { - m_direction = direction; - emitLocaleChanged(); - emitInputDirectionChanged(inputDirection()); - } - - void clear() { - m_cursorPosition = 0; - m_invokeActionCallCount = 0; - m_visible = false; - m_showInputPanelCallCount = 0; - m_hideInputPanelCallCount = 0; - m_updateCallCount = 0; - } - - bool m_visible; - QInputMethod::Action m_action; - int m_cursorPosition; - int m_invokeActionCallCount; - int m_showInputPanelCallCount; - int m_hideInputPanelCallCount; - int m_updateCallCount; - Qt::LayoutDirection m_direction; -}; diff --git a/tests/auto/shared/platformquirks.h b/tests/auto/shared/platformquirks.h deleted file mode 100644 index 5252e8cfe2e..00000000000 --- a/tests/auto/shared/platformquirks.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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 PLATFORMQUIRKS_H -#define PLATFORMQUIRKS_H - -#include <qglobal.h> - -#ifdef Q_OS_OSX -#include <Carbon/Carbon.h> -#endif - -struct PlatformQuirks -{ - static inline bool isClipboardAvailable() - { -#if !QT_CONFIG(clipboard) - return false; -#elif defined(Q_OS_OSX) - PasteboardRef pasteboard; - OSStatus status = PasteboardCreate(0, &pasteboard); - if (status == noErr) - CFRelease(pasteboard); - return status == noErr; -#else - return true; -#endif - } -}; - -#endif diff --git a/tests/auto/shared/qqmljsastdumper.h b/tests/auto/shared/qqmljsastdumper.h deleted file mode 100644 index 839dd999425..00000000000 --- a/tests/auto/shared/qqmljsastdumper.h +++ /dev/null @@ -1,449 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module 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 ASTDUMPER_H -#define ASTDUMPER_H - - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qqmljsglobal_p.h> -#include <private/qqmljsastvisitor_p.h> -#include <QtCore/QString> -#include <functional> -#include <ostream> - -QT_BEGIN_NAMESPACE -class QDebug; - -namespace QQmlJS { - -enum class DumperOptions { - None=0, - NoLocations=0x1, - NoAnnotations=0x2, - DumpNode=0x4 -}; -bool operator & (DumperOptions lhs, DumperOptions rhs); -DumperOptions operator | (DumperOptions lhs, DumperOptions rhs); - -// no export, currently just a supporting file... -class AstDumper: public AST::BaseVisitor -{ -public: - static QString printNode2(AST::Node *); - - static QString diff(AST::Node *n1, AST::Node *n2, int nContext=3, DumperOptions opt=DumperOptions::None, int indent=0); - static QString printNode(AST::Node *n, DumperOptions opt=DumperOptions::None, int indent=1, int baseIndent=0); - - AstDumper(const std::function <void (const QString &)> &dumper, DumperOptions options=DumperOptions::None, - int indent=1, int baseIndent=0); - - void start(const QString &str); - void start(const char *str); - void stop(const QString &str); - void stop(const char *str); - - QString qs(const QString &s); - QString qs(const char *s); - QString qs(QStringView s); - - QString loc(const SourceLocation &s); - - QString boolStr(bool v); - - bool preVisit(AST::Node *el) override; - void postVisit(AST::Node *el) override; - - // Ui - bool visit(AST::UiProgram *el) override; - bool visit(AST::UiHeaderItemList *) override; - bool visit(AST::UiPragma *el) override; - bool visit(AST::UiImport *el) override; - bool visit(AST::UiPublicMember *el) override; - bool visit(AST::UiSourceElement *) override; - bool visit(AST::UiObjectDefinition *) override; - bool visit(AST::UiObjectInitializer *) override; - bool visit(AST::UiObjectBinding *) override; - bool visit(AST::UiScriptBinding *) override; - bool visit(AST::UiArrayBinding *) override; - bool visit(AST::UiParameterList *) override; - bool visit(AST::UiObjectMemberList *) override; - bool visit(AST::UiArrayMemberList *) override; - bool visit(AST::UiQualifiedId *) override; - bool visit(AST::UiEnumDeclaration *) override; - bool visit(AST::UiEnumMemberList *) override; - bool visit(AST::UiVersionSpecifier *) override; - bool visit(AST::UiInlineComponent *) override; - bool visit(AST::UiRequired *) override; - bool visit(AST::UiAnnotation *) override; - bool visit(AST::UiAnnotationList *) override; - - void endVisit(AST::UiProgram *) override; - void endVisit(AST::UiImport *) override; - void endVisit(AST::UiHeaderItemList *) override; - void endVisit(AST::UiPragma *) override; - void endVisit(AST::UiPublicMember *) override; - void endVisit(AST::UiSourceElement *) override; - void endVisit(AST::UiObjectDefinition *) override; - void endVisit(AST::UiObjectInitializer *) override; - void endVisit(AST::UiObjectBinding *) override; - void endVisit(AST::UiScriptBinding *) override; - void endVisit(AST::UiArrayBinding *) override; - void endVisit(AST::UiParameterList *) override; - void endVisit(AST::UiObjectMemberList *) override; - void endVisit(AST::UiArrayMemberList *) override; - void endVisit(AST::UiQualifiedId *) override; - void endVisit(AST::UiEnumDeclaration *) override; - void endVisit(AST::UiEnumMemberList *) override; - void endVisit(AST::UiVersionSpecifier *) override; - void endVisit(AST::UiInlineComponent *) override; - void endVisit(AST::UiRequired *) override; - void endVisit(AST::UiAnnotation *) override; - void endVisit(AST::UiAnnotationList *) override; - - // QQmlJS - bool visit(AST::TypeExpression *) override; - void endVisit(AST::TypeExpression *) override; - - bool visit(AST::ThisExpression *) override; - void endVisit(AST::ThisExpression *) override; - - bool visit(AST::IdentifierExpression *) override; - void endVisit(AST::IdentifierExpression *) override; - - bool visit(AST::NullExpression *) override; - void endVisit(AST::NullExpression *) override; - - bool visit(AST::TrueLiteral *) override; - void endVisit(AST::TrueLiteral *) override; - - bool visit(AST::FalseLiteral *) override; - void endVisit(AST::FalseLiteral *) override; - - bool visit(AST::SuperLiteral *) override; - void endVisit(AST::SuperLiteral *) override; - - bool visit(AST::StringLiteral *) override; - void endVisit(AST::StringLiteral *) override; - - bool visit(AST::TemplateLiteral *) override; - void endVisit(AST::TemplateLiteral *) override; - - bool visit(AST::NumericLiteral *) override; - void endVisit(AST::NumericLiteral *) override; - - bool visit(AST::RegExpLiteral *) override; - void endVisit(AST::RegExpLiteral *) override; - - bool visit(AST::ArrayPattern *) override; - void endVisit(AST::ArrayPattern *) override; - - bool visit(AST::ObjectPattern *) override; - void endVisit(AST::ObjectPattern *) override; - - bool visit(AST::PatternElementList *) override; - void endVisit(AST::PatternElementList *) override; - - bool visit(AST::PatternPropertyList *) override; - void endVisit(AST::PatternPropertyList *) override; - - bool visit(AST::PatternElement *) override; - void endVisit(AST::PatternElement *) override; - - bool visit(AST::PatternProperty *) override; - void endVisit(AST::PatternProperty *) override; - - bool visit(AST::Elision *) override; - void endVisit(AST::Elision *) override; - - bool visit(AST::NestedExpression *) override; - void endVisit(AST::NestedExpression *) override; - - bool visit(AST::IdentifierPropertyName *) override; - void endVisit(AST::IdentifierPropertyName *) override; - - bool visit(AST::StringLiteralPropertyName *) override; - void endVisit(AST::StringLiteralPropertyName *) override; - - bool visit(AST::NumericLiteralPropertyName *) override; - void endVisit(AST::NumericLiteralPropertyName *) override; - - bool visit(AST::ComputedPropertyName *) override; - void endVisit(AST::ComputedPropertyName *) override; - - bool visit(AST::ArrayMemberExpression *) override; - void endVisit(AST::ArrayMemberExpression *) override; - - bool visit(AST::FieldMemberExpression *) override; - void endVisit(AST::FieldMemberExpression *) override; - - bool visit(AST::TaggedTemplate *) override; - void endVisit(AST::TaggedTemplate *) override; - - bool visit(AST::NewMemberExpression *) override; - void endVisit(AST::NewMemberExpression *) override; - - bool visit(AST::NewExpression *) override; - void endVisit(AST::NewExpression *) override; - - bool visit(AST::CallExpression *) override; - void endVisit(AST::CallExpression *) override; - - bool visit(AST::ArgumentList *) override; - void endVisit(AST::ArgumentList *) override; - - bool visit(AST::PostIncrementExpression *) override; - void endVisit(AST::PostIncrementExpression *) override; - - bool visit(AST::PostDecrementExpression *) override; - void endVisit(AST::PostDecrementExpression *) override; - - bool visit(AST::DeleteExpression *) override; - void endVisit(AST::DeleteExpression *) override; - - bool visit(AST::VoidExpression *) override; - void endVisit(AST::VoidExpression *) override; - - bool visit(AST::TypeOfExpression *) override; - void endVisit(AST::TypeOfExpression *) override; - - bool visit(AST::PreIncrementExpression *) override; - void endVisit(AST::PreIncrementExpression *) override; - - bool visit(AST::PreDecrementExpression *) override; - void endVisit(AST::PreDecrementExpression *) override; - - bool visit(AST::UnaryPlusExpression *) override; - void endVisit(AST::UnaryPlusExpression *) override; - - bool visit(AST::UnaryMinusExpression *) override; - void endVisit(AST::UnaryMinusExpression *) override; - - bool visit(AST::TildeExpression *) override; - void endVisit(AST::TildeExpression *) override; - - bool visit(AST::NotExpression *) override; - void endVisit(AST::NotExpression *) override; - - bool visit(AST::BinaryExpression *) override; - void endVisit(AST::BinaryExpression *) override; - - bool visit(AST::ConditionalExpression *) override; - void endVisit(AST::ConditionalExpression *) override; - - bool visit(AST::Expression *) override; - void endVisit(AST::Expression *) override; - - bool visit(AST::Block *) override; - void endVisit(AST::Block *) override; - - bool visit(AST::StatementList *) override; - void endVisit(AST::StatementList *) override; - - bool visit(AST::VariableStatement *) override; - void endVisit(AST::VariableStatement *) override; - - bool visit(AST::VariableDeclarationList *) override; - void endVisit(AST::VariableDeclarationList *) override; - - bool visit(AST::EmptyStatement *) override; - void endVisit(AST::EmptyStatement *) override; - - bool visit(AST::ExpressionStatement *) override; - void endVisit(AST::ExpressionStatement *) override; - - bool visit(AST::IfStatement *) override; - void endVisit(AST::IfStatement *) override; - - bool visit(AST::DoWhileStatement *) override; - void endVisit(AST::DoWhileStatement *) override; - - bool visit(AST::WhileStatement *) override; - void endVisit(AST::WhileStatement *) override; - - bool visit(AST::ForStatement *) override; - void endVisit(AST::ForStatement *) override; - - bool visit(AST::ForEachStatement *) override; - void endVisit(AST::ForEachStatement *) override; - - bool visit(AST::ContinueStatement *) override; - void endVisit(AST::ContinueStatement *) override; - - bool visit(AST::BreakStatement *) override; - void endVisit(AST::BreakStatement *) override; - - bool visit(AST::ReturnStatement *) override; - void endVisit(AST::ReturnStatement *) override; - - bool visit(AST::YieldExpression *) override; - void endVisit(AST::YieldExpression *) override; - - bool visit(AST::WithStatement *) override; - void endVisit(AST::WithStatement *) override; - - bool visit(AST::SwitchStatement *) override; - void endVisit(AST::SwitchStatement *) override; - - bool visit(AST::CaseBlock *) override; - void endVisit(AST::CaseBlock *) override; - - bool visit(AST::CaseClauses *) override; - void endVisit(AST::CaseClauses *) override; - - bool visit(AST::CaseClause *) override; - void endVisit(AST::CaseClause *) override; - - bool visit(AST::DefaultClause *) override; - void endVisit(AST::DefaultClause *) override; - - bool visit(AST::LabelledStatement *) override; - void endVisit(AST::LabelledStatement *) override; - - bool visit(AST::ThrowStatement *) override; - void endVisit(AST::ThrowStatement *) override; - - bool visit(AST::TryStatement *) override; - void endVisit(AST::TryStatement *) override; - - bool visit(AST::Catch *) override; - void endVisit(AST::Catch *) override; - - bool visit(AST::Finally *) override; - void endVisit(AST::Finally *) override; - - bool visit(AST::FunctionDeclaration *) override; - void endVisit(AST::FunctionDeclaration *) override; - - bool visit(AST::FunctionExpression *) override; - void endVisit(AST::FunctionExpression *) override; - - bool visit(AST::FormalParameterList *) override; - void endVisit(AST::FormalParameterList *) override; - - bool visit(AST::ClassExpression *) override; - void endVisit(AST::ClassExpression *) override; - - bool visit(AST::ClassDeclaration *) override; - void endVisit(AST::ClassDeclaration *) override; - - bool visit(AST::ClassElementList *) override; - void endVisit(AST::ClassElementList *) override; - - bool visit(AST::Program *) override; - void endVisit(AST::Program *) override; - - bool visit(AST::NameSpaceImport *) override; - void endVisit(AST::NameSpaceImport *) override; - - bool visit(AST::ImportSpecifier *) override; - void endVisit(AST::ImportSpecifier *) override; - - bool visit(AST::ImportsList *) override; - void endVisit(AST::ImportsList *) override; - - bool visit(AST::NamedImports *) override; - void endVisit(AST::NamedImports *) override; - - bool visit(AST::FromClause *) override; - void endVisit(AST::FromClause *) override; - - bool visit(AST::ImportClause *) override; - void endVisit(AST::ImportClause *) override; - - bool visit(AST::ImportDeclaration *) override; - void endVisit(AST::ImportDeclaration *) override; - - bool visit(AST::ExportSpecifier *) override; - void endVisit(AST::ExportSpecifier *) override; - - bool visit(AST::ExportsList *) override; - void endVisit(AST::ExportsList *) override; - - bool visit(AST::ExportClause *) override; - void endVisit(AST::ExportClause *) override; - - bool visit(AST::ExportDeclaration *) override; - void endVisit(AST::ExportDeclaration *) override; - - bool visit(AST::ESModule *) override; - void endVisit(AST::ESModule *) override; - - bool visit(AST::DebuggerStatement *) override; - void endVisit(AST::DebuggerStatement *) override; - - bool visit(AST::Type *) override; - void endVisit(AST::Type *) override; - - bool visit(AST::TypeArgumentList *) override; - void endVisit(AST::TypeArgumentList *) override; - - bool visit(AST::TypeAnnotation *) override; - void endVisit(AST::TypeAnnotation *) override; - - void throwRecursionDepthError() override; - -private: - // attributes - std::function <void (const QString &)> dumper; - DumperOptions options = DumperOptions::None; - int indent = 0; - int baseIndent = 0; - bool dumpNode(); - bool noLocations(); - bool noAnnotations(); -}; - -QDebug operator<<(QDebug d, AST::Node *n); - -std::ostream &operator<<(std::ostream &stream, AST::Node *n); - -} // namespace AST - -QT_END_NAMESPACE - -#endif // ASTDUMPER_H diff --git a/tests/auto/shared/testhttpserver.h b/tests/auto/shared/testhttpserver.h deleted file mode 100644 index 42cc50e028a..00000000000 --- a/tests/auto/shared/testhttpserver.h +++ /dev/null @@ -1,128 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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 TESTHTTPSERVER_H -#define TESTHTTPSERVER_H - -#include <QTcpServer> -#include <QUrl> -#include <QPair> -#include <QThread> -#include <QMutex> -#include <QWaitCondition> - -class TestHTTPServer : public QObject -{ - Q_OBJECT -public: - TestHTTPServer(); - - bool listen(); - quint16 port() const; - QUrl baseUrl() const; - QUrl url(const QString &documentPath) const; - QString urlString(const QString &documentPath) const; - QString errorString() const; - - enum Mode { Normal, Delay, Disconnect }; - bool serveDirectory(const QString &, Mode = Normal); - - bool wait(const QUrl &expect, const QUrl &reply, const QUrl &body); - bool hasFailed() const; - - void addAlias(const QString &filename, const QString &aliasName); - void addRedirect(const QString &filename, const QString &redirectName); - - void registerFileNameForContentSubstitution(const QString &fileName); - - // In Delay mode, each item needs one call to this function to be sent - void sendDelayedItem(); - -private slots: - void newConnection(); - void disconnected(); - void readyRead(); - void sendOne(); - -private: - enum State { - AwaitingHeader, - AwaitingData, - Failed - }; - - void serveGET(QTcpSocket *, const QByteArray &); - bool reply(QTcpSocket *, const QByteArray &); - - QList<QPair<QString, Mode> > m_directories; - QHash<QTcpSocket *, QByteArray> m_dataCache; - QList<QPair<QTcpSocket *, QByteArray> > m_toSend; - QSet<QString> m_contentSubstitutedFileNames; - - struct WaitData { - QList<QByteArray> headerExactMatches; - QList<QByteArray> headerPrefixes; - QByteArray body; - } m_waitData; - QByteArray m_replyData; - QByteArray m_bodyData; - QByteArray m_data; - State m_state; - - QHash<QString, QString> m_aliases; - QHash<QString, QString> m_redirects; - - QTcpServer m_server; -}; - -class ThreadedTestHTTPServer : public QThread -{ - Q_OBJECT -public: - ThreadedTestHTTPServer(const QString &dir, TestHTTPServer::Mode mode = TestHTTPServer::Normal); - ThreadedTestHTTPServer(const QHash<QString, TestHTTPServer::Mode> &dirs); - ~ThreadedTestHTTPServer(); - - QUrl baseUrl() const; - QUrl url(const QString &documentPath) const; - QString urlString(const QString &documentPath) const; - -protected: - void run() override; - -private: - void start(); - - QHash<QString, TestHTTPServer::Mode> m_dirs; - quint16 m_port; - QMutex m_mutex; - QWaitCondition m_condition; -}; - -#endif // TESTHTTPSERVER_H - diff --git a/tests/auto/shared/util.cpp b/tests/auto/shared/util.cpp deleted file mode 100644 index 96876428f66..00000000000 --- a/tests/auto/shared/util.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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 "util.h" - -#include <QtCore/QDebug> -#include <QtCore/QMutexLocker> - -QQmlDataTest *QQmlDataTest::m_instance = 0; - -QQmlDataTest::QQmlDataTest() : -#ifdef QT_TESTCASE_BUILDDIR - m_dataDirectory(QTest::qFindTestData("data", QT_QMLTEST_DATADIR, 0, QT_TESTCASE_BUILDDIR)), -#else - m_dataDirectory(QTest::qFindTestData("data", QT_QMLTEST_DATADIR, 0)), -#endif - - m_dataDirectoryUrl(m_dataDirectory.startsWith(QLatin1Char(':')) - ? QUrl(QLatin1String("qrc") + m_dataDirectory) - : QUrl::fromLocalFile(m_dataDirectory + QLatin1Char('/'))) -{ - m_instance = this; -} - -QQmlDataTest::~QQmlDataTest() -{ - m_instance = 0; -} - -void QQmlDataTest::initTestCase() -{ - QVERIFY2(!m_dataDirectory.isEmpty(), "'data' directory not found"); - m_directory = QFileInfo(m_dataDirectory).absolutePath(); - if (m_dataDirectoryUrl.scheme() != QLatin1String("qrc")) - QVERIFY2(QDir::setCurrent(m_directory), qPrintable(QLatin1String("Could not chdir to ") + m_directory)); -} - -QString QQmlDataTest::testFile(const QString &fileName) const -{ - if (m_directory.isEmpty()) - qFatal("QQmlDataTest::initTestCase() not called."); - QString result = m_dataDirectory; - result += QLatin1Char('/'); - result += fileName; - return result; -} - -Q_GLOBAL_STATIC(QMutex, qQmlTestMessageHandlerMutex) - -QQmlTestMessageHandler *QQmlTestMessageHandler::m_instance = 0; - -void QQmlTestMessageHandler::messageHandler(QtMsgType, const QMessageLogContext &context, const QString &message) -{ - QMutexLocker locker(qQmlTestMessageHandlerMutex()); - if (QQmlTestMessageHandler::m_instance) { - if (QQmlTestMessageHandler::m_instance->m_includeCategories) - QQmlTestMessageHandler::m_instance->m_messages.push_back(QString("%1: %2").arg(context.category, message)); - else - QQmlTestMessageHandler::m_instance->m_messages.push_back(message); - } -} - -QQmlTestMessageHandler::QQmlTestMessageHandler() -{ - QMutexLocker locker(qQmlTestMessageHandlerMutex()); - Q_ASSERT(!QQmlTestMessageHandler::m_instance); - QQmlTestMessageHandler::m_instance = this; - m_oldHandler = qInstallMessageHandler(messageHandler); - m_includeCategories = false; -} - -QQmlTestMessageHandler::~QQmlTestMessageHandler() -{ - QMutexLocker locker(qQmlTestMessageHandlerMutex()); - Q_ASSERT(QQmlTestMessageHandler::m_instance); - qInstallMessageHandler(m_oldHandler); - QQmlTestMessageHandler::m_instance = 0; -} diff --git a/tests/auto/shared/util.h b/tests/auto/shared/util.h deleted file mode 100644 index 20882583786..00000000000 --- a/tests/auto/shared/util.h +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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 QQMLTESTUTILS_H -#define QQMLTESTUTILS_H - -#include <QtCore/QDir> -#include <QtCore/QUrl> -#include <QtCore/QCoreApplication> -#include <QtCore/QStringList> -#include <QtTest/QTest> - -/* Base class for tests with data that are located in a "data" subfolder. */ - -class QQmlDataTest : public QObject -{ - Q_OBJECT -public: - QQmlDataTest(); - virtual ~QQmlDataTest(); - - QString testFile(const QString &fileName) const; - inline QString testFile(const char *fileName) const - { return testFile(QLatin1String(fileName)); } - inline QUrl testFileUrl(const QString &fileName) const - { - const QString fn = testFile(fileName); - return fn.startsWith(QLatin1Char(':')) - ? QUrl(QLatin1String("qrc") + fn) - : QUrl::fromLocalFile(fn); - } - inline QUrl testFileUrl(const char *fileName) const - { return testFileUrl(QLatin1String(fileName)); } - - inline QString dataDirectory() const { return m_dataDirectory; } - inline QUrl dataDirectoryUrl() const { return m_dataDirectoryUrl; } - inline QString directory() const { return m_directory; } - - static inline QQmlDataTest *instance() { return m_instance; } - -public slots: - virtual void initTestCase(); - -private: - static QQmlDataTest *m_instance; - - const QString m_dataDirectory; - const QUrl m_dataDirectoryUrl; - QString m_directory; -}; - -class QQmlTestMessageHandler -{ - Q_DISABLE_COPY(QQmlTestMessageHandler) -public: - QQmlTestMessageHandler(); - ~QQmlTestMessageHandler(); - - const QStringList &messages() const { return m_messages; } - const QString messageString() const { return m_messages.join(QLatin1Char('\n')); } - - void clear() { m_messages.clear(); } - - void setIncludeCategoriesEnabled(bool enabled) { m_includeCategories = enabled; } - -private: - static void messageHandler(QtMsgType, const QMessageLogContext &context, const QString &message); - - static QQmlTestMessageHandler *m_instance; - QStringList m_messages; - QtMessageHandler m_oldHandler; - bool m_includeCategories; -}; - -#endif // QQMLTESTUTILS_H diff --git a/tests/baseline/CMakeLists.txt b/tests/baseline/CMakeLists.txt new file mode 100644 index 00000000000..3f178924a39 --- /dev/null +++ b/tests/baseline/CMakeLists.txt @@ -0,0 +1,8 @@ +if(NOT TARGET Qt::qsb) + return() +endif() + +# Special case: test includes the QBaselineTest module sources from qtbase directly +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../../qtbase/tests/baseline/shared") + add_subdirectory(scenegraph) +endif() diff --git a/tests/manual/scenegraph_lancelot/CMakeLists.txt b/tests/baseline/scenegraph/CMakeLists.txt similarity index 100% rename from tests/manual/scenegraph_lancelot/CMakeLists.txt rename to tests/baseline/scenegraph/CMakeLists.txt diff --git a/tests/manual/scenegraph_lancelot/data/Ignore b/tests/baseline/scenegraph/data/Ignore similarity index 100% rename from tests/manual/scenegraph_lancelot/data/Ignore rename to tests/baseline/scenegraph/data/Ignore diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/SimpleBorderImage.qml b/tests/baseline/scenegraph/data/borderimages/SimpleBorderImage.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/SimpleBorderImage.qml rename to tests/baseline/scenegraph/data/borderimages/SimpleBorderImage.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/SimpleNoBorder.qml b/tests/baseline/scenegraph/data/borderimages/SimpleNoBorder.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/SimpleNoBorder.qml rename to tests/baseline/scenegraph/data/borderimages/SimpleNoBorder.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage.qml b/tests/baseline/scenegraph/data/borderimages/borderimage.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_borders_exceed_height.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_borders_exceed_height.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_borders_exceed_height.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_borders_exceed_height.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_borders_exceed_width.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_borders_exceed_width.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_borders_exceed_width.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_borders_exceed_width.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_no_border.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_no_border.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_no_border.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_no_border.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_smoothed.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_rotated_smoothed.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_smoothed.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_rotated_smoothed.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_border_overlap.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_border_overlap.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_border_overlap.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_border_overlap.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_negative_borders.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_negative_borders.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_negative_borders.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_negative_borders.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_borders.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_borders.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_borders.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_borders.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_bottom.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_bottom.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_bottom.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_bottom.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_center.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_center.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_center.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_center.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_left.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_left.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_left.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_left.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_right.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_right.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_right.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_right.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_right_left.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_right_left.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_right_left.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_right_left.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_top.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_top.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_top.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_top.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_top_bottom.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_top_bottom.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_rotated_unsmoothed_no_top_bottom.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_rotated_unsmoothed_no_top_bottom.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_smoothed.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_smoothed.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_smoothed.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_smoothed.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_tiling_horizontal.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_tiling_horizontal.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_tiling_horizontal.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_tiling_horizontal.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_tiling_vertical.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_tiling_vertical.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_tiling_vertical.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_tiling_vertical.qml diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_unsmoothed.qml b/tests/baseline/scenegraph/data/borderimages/borderimage_unsmoothed.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/borderimages/borderimage_unsmoothed.qml rename to tests/baseline/scenegraph/data/borderimages/borderimage_unsmoothed.qml diff --git a/tests/manual/scenegraph_lancelot/data/gradients/gradients.qml b/tests/baseline/scenegraph/data/gradients/gradients.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/gradients/gradients.qml rename to tests/baseline/scenegraph/data/gradients/gradients.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/compressed_tex.qml b/tests/baseline/scenegraph/data/images/compressed_tex.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/compressed_tex.qml rename to tests/baseline/scenegraph/data/images/compressed_tex.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/fill_mode.qml b/tests/baseline/scenegraph/data/images/fill_mode.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/fill_mode.qml rename to tests/baseline/scenegraph/data/images/fill_mode.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/images_1.qml b/tests/baseline/scenegraph/data/images/images_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/images_1.qml rename to tests/baseline/scenegraph/data/images/images_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/images_2.qml b/tests/baseline/scenegraph/data/images/images_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/images_2.qml rename to tests/baseline/scenegraph/data/images/images_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/jpeg_full.qml b/tests/baseline/scenegraph/data/images/jpeg_full.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/jpeg_full.qml rename to tests/baseline/scenegraph/data/images/jpeg_full.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/jpeg_scaled.qml b/tests/baseline/scenegraph/data/images/jpeg_scaled.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/jpeg_scaled.qml rename to tests/baseline/scenegraph/data/images/jpeg_scaled.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_1.qml b/tests/baseline/scenegraph/data/images/linear_smooth_0_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_1.qml rename to tests/baseline/scenegraph/data/images/linear_smooth_0_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_2.qml b/tests/baseline/scenegraph/data/images/linear_smooth_0_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_2.qml rename to tests/baseline/scenegraph/data/images/linear_smooth_0_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_3.qml b/tests/baseline/scenegraph/data/images/linear_smooth_0_3.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_3.qml rename to tests/baseline/scenegraph/data/images/linear_smooth_0_3.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_4.qml b/tests/baseline/scenegraph/data/images/linear_smooth_0_4.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_4.qml rename to tests/baseline/scenegraph/data/images/linear_smooth_0_4.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_5.qml b/tests/baseline/scenegraph/data/images/linear_smooth_0_5.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_5.qml rename to tests/baseline/scenegraph/data/images/linear_smooth_0_5.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_6.qml b/tests/baseline/scenegraph/data/images/linear_smooth_0_6.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_6.qml rename to tests/baseline/scenegraph/data/images/linear_smooth_0_6.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_7.qml b/tests/baseline/scenegraph/data/images/linear_smooth_0_7.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_7.qml rename to tests/baseline/scenegraph/data/images/linear_smooth_0_7.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_8.qml b/tests/baseline/scenegraph/data/images/linear_smooth_0_8.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_8.qml rename to tests/baseline/scenegraph/data/images/linear_smooth_0_8.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_9.qml b/tests/baseline/scenegraph/data/images/linear_smooth_0_9.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/linear_smooth_0_9.qml rename to tests/baseline/scenegraph/data/images/linear_smooth_0_9.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/linear_smooth_1_0.qml b/tests/baseline/scenegraph/data/images/linear_smooth_1_0.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/linear_smooth_1_0.qml rename to tests/baseline/scenegraph/data/images/linear_smooth_1_0.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/mirror.qml b/tests/baseline/scenegraph/data/images/mirror.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/mirror.qml rename to tests/baseline/scenegraph/data/images/mirror.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/overlap.qml b/tests/baseline/scenegraph/data/images/overlap.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/overlap.qml rename to tests/baseline/scenegraph/data/images/overlap.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/tiling.qml b/tests/baseline/scenegraph/data/images/tiling.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/tiling.qml rename to tests/baseline/scenegraph/data/images/tiling.qml diff --git a/tests/manual/scenegraph_lancelot/data/images/transform.qml b/tests/baseline/scenegraph/data/images/transform.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/images/transform.qml rename to tests/baseline/scenegraph/data/images/transform.qml diff --git a/tests/manual/scenegraph_lancelot/data/opacity/opacity.qml b/tests/baseline/scenegraph/data/opacity/opacity.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/opacity/opacity.qml rename to tests/baseline/scenegraph/data/opacity/opacity.qml diff --git a/tests/manual/scenegraph_lancelot/data/rectangles/rectangles.qml b/tests/baseline/scenegraph/data/rectangles/rectangles.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/rectangles/rectangles.qml rename to tests/baseline/scenegraph/data/rectangles/rectangles.qml diff --git a/tests/manual/scenegraph_lancelot/data/rectangles/rectangles_smoothed.qml b/tests/baseline/scenegraph/data/rectangles/rectangles_smoothed.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/rectangles/rectangles_smoothed.qml rename to tests/baseline/scenegraph/data/rectangles/rectangles_smoothed.qml diff --git a/tests/manual/scenegraph_lancelot/data/rectangles/rectangles_unsmoothed.qml b/tests/baseline/scenegraph/data/rectangles/rectangles_unsmoothed.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/rectangles/rectangles_unsmoothed.qml rename to tests/baseline/scenegraph/data/rectangles/rectangles_unsmoothed.qml diff --git a/tests/manual/scenegraph_lancelot/data/rectangles/test-rectangles.qml b/tests/baseline/scenegraph/data/rectangles/test-rectangles.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/rectangles/test-rectangles.qml rename to tests/baseline/scenegraph/data/rectangles/test-rectangles.qml diff --git a/tests/manual/scenegraph_lancelot/data/rotation/rotation.qml b/tests/baseline/scenegraph/data/rotation/rotation.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/rotation/rotation.qml rename to tests/baseline/scenegraph/data/rotation/rotation.qml diff --git a/tests/manual/scenegraph_lancelot/data/rotation/rotation_2.qml b/tests/baseline/scenegraph/data/rotation/rotation_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/rotation/rotation_2.qml rename to tests/baseline/scenegraph/data/rotation/rotation_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/rotation/rotation_clip_multi.qml b/tests/baseline/scenegraph/data/rotation/rotation_clip_multi.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/rotation/rotation_clip_multi.qml rename to tests/baseline/scenegraph/data/rotation/rotation_clip_multi.qml diff --git a/tests/manual/scenegraph_lancelot/data/rotation/rotation_clip_scissor.qml b/tests/baseline/scenegraph/data/rotation/rotation_clip_scissor.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/rotation/rotation_clip_scissor.qml rename to tests/baseline/scenegraph/data/rotation/rotation_clip_scissor.qml diff --git a/tests/manual/scenegraph_lancelot/data/rotation/rotation_clip_stencil.qml b/tests/baseline/scenegraph/data/rotation/rotation_clip_stencil.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/rotation/rotation_clip_stencil.qml rename to tests/baseline/scenegraph/data/rotation/rotation_clip_stencil.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/activity/activity.qml b/tests/baseline/scenegraph/data/shaders/activity/activity.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/activity/activity.qml rename to tests/baseline/scenegraph/data/shaders/activity/activity.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/atlas/atlas.qml b/tests/baseline/scenegraph/data/shaders/atlas/atlas.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/atlas/atlas.qml rename to tests/baseline/scenegraph/data/shaders/atlas/atlas.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/basic/basic.qml b/tests/baseline/scenegraph/data/shaders/basic/basic.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/basic/basic.qml rename to tests/baseline/scenegraph/data/shaders/basic/basic.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/basic/basic_alpha.qml b/tests/baseline/scenegraph/data/shaders/basic/basic_alpha.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/basic/basic_alpha.qml rename to tests/baseline/scenegraph/data/shaders/basic/basic_alpha.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/culling/culling_1.qml b/tests/baseline/scenegraph/data/shaders/culling/culling_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/culling/culling_1.qml rename to tests/baseline/scenegraph/data/shaders/culling/culling_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/culling/culling_2.qml b/tests/baseline/scenegraph/data/shaders/culling/culling_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/culling/culling_2.qml rename to tests/baseline/scenegraph/data/shaders/culling/culling_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/gridmesh/resolution_1.qml b/tests/baseline/scenegraph/data/shaders/gridmesh/resolution_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/gridmesh/resolution_1.qml rename to tests/baseline/scenegraph/data/shaders/gridmesh/resolution_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/gridmesh/resolution_16.qml b/tests/baseline/scenegraph/data/shaders/gridmesh/resolution_16.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/gridmesh/resolution_16.qml rename to tests/baseline/scenegraph/data/shaders/gridmesh/resolution_16.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/gridmesh/resolution_2.qml b/tests/baseline/scenegraph/data/shaders/gridmesh/resolution_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/gridmesh/resolution_2.qml rename to tests/baseline/scenegraph/data/shaders/gridmesh/resolution_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/gridmesh/resolution_4.qml b/tests/baseline/scenegraph/data/shaders/gridmesh/resolution_4.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/gridmesh/resolution_4.qml rename to tests/baseline/scenegraph/data/shaders/gridmesh/resolution_4.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/gridmesh/resolution_8.qml b/tests/baseline/scenegraph/data/shaders/gridmesh/resolution_8.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/gridmesh/resolution_8.qml rename to tests/baseline/scenegraph/data/shaders/gridmesh/resolution_8.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/hiddensource/hiddensource_1.qml b/tests/baseline/scenegraph/data/shaders/hiddensource/hiddensource_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/hiddensource/hiddensource_1.qml rename to tests/baseline/scenegraph/data/shaders/hiddensource/hiddensource_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/hiddensource/hiddensource_2.qml b/tests/baseline/scenegraph/data/shaders/hiddensource/hiddensource_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/hiddensource/hiddensource_2.qml rename to tests/baseline/scenegraph/data/shaders/hiddensource/hiddensource_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/hiddensource/unhidden_1.qml b/tests/baseline/scenegraph/data/shaders/hiddensource/unhidden_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/hiddensource/unhidden_1.qml rename to tests/baseline/scenegraph/data/shaders/hiddensource/unhidden_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/hiddensource/unhidden_2.qml b/tests/baseline/scenegraph/data/shaders/hiddensource/unhidden_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/hiddensource/unhidden_2.qml rename to tests/baseline/scenegraph/data/shaders/hiddensource/unhidden_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/image/async.qml b/tests/baseline/scenegraph/data/shaders/image/async.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/image/async.qml rename to tests/baseline/scenegraph/data/shaders/image/async.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/image/face-smile.png b/tests/baseline/scenegraph/data/shaders/image/face-smile.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/image/face-smile.png rename to tests/baseline/scenegraph/data/shaders/image/face-smile.png diff --git a/tests/manual/scenegraph_lancelot/data/shaders/image/source.qml b/tests/baseline/scenegraph/data/shaders/image/source.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/image/source.qml rename to tests/baseline/scenegraph/data/shaders/image/source.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/layer/layer.qml b/tests/baseline/scenegraph/data/shaders/layer/layer.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/layer/layer.qml rename to tests/baseline/scenegraph/data/shaders/layer/layer.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/live/liveonce_1.qml b/tests/baseline/scenegraph/data/shaders/live/liveonce_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/live/liveonce_1.qml rename to tests/baseline/scenegraph/data/shaders/live/liveonce_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/live/liveonce_2.qml b/tests/baseline/scenegraph/data/shaders/live/liveonce_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/live/liveonce_2.qml rename to tests/baseline/scenegraph/data/shaders/live/liveonce_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/live/livetwice_1.qml b/tests/baseline/scenegraph/data/shaders/live/livetwice_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/live/livetwice_1.qml rename to tests/baseline/scenegraph/data/shaders/live/livetwice_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/live/livetwice_2.qml b/tests/baseline/scenegraph/data/shaders/live/livetwice_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/live/livetwice_2.qml rename to tests/baseline/scenegraph/data/shaders/live/livetwice_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/live/samesource.qml b/tests/baseline/scenegraph/data/shaders/live/samesource.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/live/samesource.qml rename to tests/baseline/scenegraph/data/shaders/live/samesource.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/mimap/mimap_1.qml b/tests/baseline/scenegraph/data/shaders/mimap/mimap_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/mimap/mimap_1.qml rename to tests/baseline/scenegraph/data/shaders/mimap/mimap_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/mimap/mimap_2.qml b/tests/baseline/scenegraph/data/shaders/mimap/mimap_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/mimap/mimap_2.qml rename to tests/baseline/scenegraph/data/shaders/mimap/mimap_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/mimap/mimap_3.qml b/tests/baseline/scenegraph/data/shaders/mimap/mimap_3.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/mimap/mimap_3.qml rename to tests/baseline/scenegraph/data/shaders/mimap/mimap_3.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/mimap/mimap_4.qml b/tests/baseline/scenegraph/data/shaders/mimap/mimap_4.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/mimap/mimap_4.qml rename to tests/baseline/scenegraph/data/shaders/mimap/mimap_4.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/nesting/nesting.qml b/tests/baseline/scenegraph/data/shaders/nesting/nesting.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/nesting/nesting.qml rename to tests/baseline/scenegraph/data/shaders/nesting/nesting.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/propertyanimation/property.qml b/tests/baseline/scenegraph/data/shaders/propertyanimation/property.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/propertyanimation/property.qml rename to tests/baseline/scenegraph/data/shaders/propertyanimation/property.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/propertyanimation/uniformanimator.qml b/tests/baseline/scenegraph/data/shaders/propertyanimation/uniformanimator.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/propertyanimation/uniformanimator.qml rename to tests/baseline/scenegraph/data/shaders/propertyanimation/uniformanimator.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/propertyanimation/uniformanimator_stall.qml b/tests/baseline/scenegraph/data/shaders/propertyanimation/uniformanimator_stall.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/propertyanimation/uniformanimator_stall.qml rename to tests/baseline/scenegraph/data/shaders/propertyanimation/uniformanimator_stall.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/recursive/recursive_1.qml b/tests/baseline/scenegraph/data/shaders/recursive/recursive_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/recursive/recursive_1.qml rename to tests/baseline/scenegraph/data/shaders/recursive/recursive_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/source/one-source.qml b/tests/baseline/scenegraph/data/shaders/source/one-source.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/source/one-source.qml rename to tests/baseline/scenegraph/data/shaders/source/one-source.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/source/rect.qml b/tests/baseline/scenegraph/data/shaders/source/rect.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/source/rect.qml rename to tests/baseline/scenegraph/data/shaders/source/rect.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/source/switch_1.qml b/tests/baseline/scenegraph/data/shaders/source/switch_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/source/switch_1.qml rename to tests/baseline/scenegraph/data/shaders/source/switch_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/source/switch_2.qml b/tests/baseline/scenegraph/data/shaders/source/switch_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/source/switch_2.qml rename to tests/baseline/scenegraph/data/shaders/source/switch_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/source/switch_3.qml b/tests/baseline/scenegraph/data/shaders/source/switch_3.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/source/switch_3.qml rename to tests/baseline/scenegraph/data/shaders/source/switch_3.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/source/two-sources.qml b/tests/baseline/scenegraph/data/shaders/source/two-sources.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/source/two-sources.qml rename to tests/baseline/scenegraph/data/shaders/source/two-sources.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/source/visible_1.qml b/tests/baseline/scenegraph/data/shaders/source/visible_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/source/visible_1.qml rename to tests/baseline/scenegraph/data/shaders/source/visible_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/source/visible_2.qml b/tests/baseline/scenegraph/data/shaders/source/visible_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/source/visible_2.qml rename to tests/baseline/scenegraph/data/shaders/source/visible_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/texture/size.qml b/tests/baseline/scenegraph/data/shaders/texture/size.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/texture/size.qml rename to tests/baseline/scenegraph/data/shaders/texture/size.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/tree/hiddentree_1.qml b/tests/baseline/scenegraph/data/shaders/tree/hiddentree_1.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/tree/hiddentree_1.qml rename to tests/baseline/scenegraph/data/shaders/tree/hiddentree_1.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/tree/hiddentree_2.qml b/tests/baseline/scenegraph/data/shaders/tree/hiddentree_2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/tree/hiddentree_2.qml rename to tests/baseline/scenegraph/data/shaders/tree/hiddentree_2.qml diff --git a/tests/manual/scenegraph_lancelot/data/shaders/wrap/modes.qml b/tests/baseline/scenegraph/data/shaders/wrap/modes.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shaders/wrap/modes.qml rename to tests/baseline/scenegraph/data/shaders/wrap/modes.qml diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_arc.qml b/tests/baseline/scenegraph/data/shape/shape_arc.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shape/shape_arc.qml rename to tests/baseline/scenegraph/data/shape/shape_arc.qml diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_arc_fill.qml b/tests/baseline/scenegraph/data/shape/shape_arc_fill.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shape/shape_arc_fill.qml rename to tests/baseline/scenegraph/data/shape/shape_arc_fill.qml diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_cubic.qml b/tests/baseline/scenegraph/data/shape/shape_cubic.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shape/shape_cubic.qml rename to tests/baseline/scenegraph/data/shape/shape_cubic.qml diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_linear_gradient.qml b/tests/baseline/scenegraph/data/shape/shape_linear_gradient.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shape/shape_linear_gradient.qml rename to tests/baseline/scenegraph/data/shape/shape_linear_gradient.qml diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_lines.qml b/tests/baseline/scenegraph/data/shape/shape_lines.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shape/shape_lines.qml rename to tests/baseline/scenegraph/data/shape/shape_lines.qml diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_multiline.qml b/tests/baseline/scenegraph/data/shape/shape_multiline.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shape/shape_multiline.qml rename to tests/baseline/scenegraph/data/shape/shape_multiline.qml diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_quad.qml b/tests/baseline/scenegraph/data/shape/shape_quad.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shape/shape_quad.qml rename to tests/baseline/scenegraph/data/shape/shape_quad.qml diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_spread.qml b/tests/baseline/scenegraph/data/shape/shape_spread.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shape/shape_spread.qml rename to tests/baseline/scenegraph/data/shape/shape_spread.qml diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_text.qml b/tests/baseline/scenegraph/data/shape/shape_text.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shape/shape_text.qml rename to tests/baseline/scenegraph/data/shape/shape_text.qml diff --git a/tests/manual/scenegraph_lancelot/data/shared/blue_72x96.png b/tests/baseline/scenegraph/data/shared/blue_72x96.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/blue_72x96.png rename to tests/baseline/scenegraph/data/shared/blue_72x96.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/bw_1535x2244.jpg b/tests/baseline/scenegraph/data/shared/bw_1535x2244.jpg similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/bw_1535x2244.jpg rename to tests/baseline/scenegraph/data/shared/bw_1535x2244.jpg diff --git a/tests/manual/scenegraph_lancelot/data/shared/circle_16x16.png b/tests/baseline/scenegraph/data/shared/circle_16x16.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/circle_16x16.png rename to tests/baseline/scenegraph/data/shared/circle_16x16.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/col320x480.jpg b/tests/baseline/scenegraph/data/shared/col320x480.jpg similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/col320x480.jpg rename to tests/baseline/scenegraph/data/shared/col320x480.jpg diff --git a/tests/manual/scenegraph_lancelot/data/shared/cyan_72x96.png b/tests/baseline/scenegraph/data/shared/cyan_72x96.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/cyan_72x96.png rename to tests/baseline/scenegraph/data/shared/cyan_72x96.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/green_72x96.png b/tests/baseline/scenegraph/data/shared/green_72x96.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/green_72x96.png rename to tests/baseline/scenegraph/data/shared/green_72x96.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/o1.png b/tests/baseline/scenegraph/data/shared/o1.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/o1.png rename to tests/baseline/scenegraph/data/shared/o1.png diff --git a/tests/baseline/scenegraph/data/shared/o1_bc1.ktx b/tests/baseline/scenegraph/data/shared/o1_bc1.ktx new file mode 100644 index 00000000000..d61194a745b Binary files /dev/null and b/tests/baseline/scenegraph/data/shared/o1_bc1.ktx differ diff --git a/tests/manual/scenegraph_lancelot/data/shared/o2.png b/tests/baseline/scenegraph/data/shared/o2.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/o2.png rename to tests/baseline/scenegraph/data/shared/o2.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/o2_bc1.ktx b/tests/baseline/scenegraph/data/shared/o2_bc1.ktx similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/o2_bc1.ktx rename to tests/baseline/scenegraph/data/shared/o2_bc1.ktx diff --git a/tests/manual/scenegraph_lancelot/data/shared/orange_72x96.png b/tests/baseline/scenegraph/data/shared/orange_72x96.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/orange_72x96.png rename to tests/baseline/scenegraph/data/shared/orange_72x96.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/red_72x96.png b/tests/baseline/scenegraph/data/shared/red_72x96.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/red_72x96.png rename to tests/baseline/scenegraph/data/shared/red_72x96.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/sample_1.png b/tests/baseline/scenegraph/data/shared/sample_1.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/sample_1.png rename to tests/baseline/scenegraph/data/shared/sample_1.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/sand_16x16.png b/tests/baseline/scenegraph/data/shared/sand_16x16.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/sand_16x16.png rename to tests/baseline/scenegraph/data/shared/sand_16x16.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/basic.frag b/tests/baseline/scenegraph/data/shared/shaders/basic.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/basic.frag rename to tests/baseline/scenegraph/data/shared/shaders/basic.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/basic_alpha.frag b/tests/baseline/scenegraph/data/shared/shaders/basic_alpha.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/basic_alpha.frag rename to tests/baseline/scenegraph/data/shared/shaders/basic_alpha.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/cmyk.frag b/tests/baseline/scenegraph/data/shared/shaders/cmyk.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/cmyk.frag rename to tests/baseline/scenegraph/data/shared/shaders/cmyk.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/culling.frag b/tests/baseline/scenegraph/data/shared/shaders/culling.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/culling.frag rename to tests/baseline/scenegraph/data/shared/shaders/culling.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/desaturate.frag b/tests/baseline/scenegraph/data/shared/shaders/desaturate.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/desaturate.frag rename to tests/baseline/scenegraph/data/shared/shaders/desaturate.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/edge.frag b/tests/baseline/scenegraph/data/shared/shaders/edge.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/edge.frag rename to tests/baseline/scenegraph/data/shared/shaders/edge.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/gradient.frag b/tests/baseline/scenegraph/data/shared/shaders/gradient.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/gradient.frag rename to tests/baseline/scenegraph/data/shared/shaders/gradient.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/gradient2.frag b/tests/baseline/scenegraph/data/shared/shaders/gradient2.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/gradient2.frag rename to tests/baseline/scenegraph/data/shared/shaders/gradient2.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/gradient3.frag b/tests/baseline/scenegraph/data/shared/shaders/gradient3.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/gradient3.frag rename to tests/baseline/scenegraph/data/shared/shaders/gradient3.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/gradient4.frag b/tests/baseline/scenegraph/data/shared/shaders/gradient4.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/gradient4.frag rename to tests/baseline/scenegraph/data/shared/shaders/gradient4.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/gradient5.frag b/tests/baseline/scenegraph/data/shared/shaders/gradient5.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/gradient5.frag rename to tests/baseline/scenegraph/data/shared/shaders/gradient5.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/gradientgrid.frag b/tests/baseline/scenegraph/data/shared/shaders/gradientgrid.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/gradientgrid.frag rename to tests/baseline/scenegraph/data/shared/shaders/gradientgrid.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/property.frag b/tests/baseline/scenegraph/data/shared/shaders/property.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/property.frag rename to tests/baseline/scenegraph/data/shared/shaders/property.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/shadow.frag b/tests/baseline/scenegraph/data/shared/shaders/shadow.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/shadow.frag rename to tests/baseline/scenegraph/data/shared/shaders/shadow.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/stencil.frag b/tests/baseline/scenegraph/data/shared/shaders/stencil.frag similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/stencil.frag rename to tests/baseline/scenegraph/data/shared/shaders/stencil.frag diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/subrect.vert b/tests/baseline/scenegraph/data/shared/shaders/subrect.vert similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/subrect.vert rename to tests/baseline/scenegraph/data/shared/shaders/subrect.vert diff --git a/tests/manual/scenegraph_lancelot/data/shared/shaders/wave.vert b/tests/baseline/scenegraph/data/shared/shaders/wave.vert similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/shaders/wave.vert rename to tests/baseline/scenegraph/data/shared/shaders/wave.vert diff --git a/tests/manual/scenegraph_lancelot/data/shared/square_16x16.png b/tests/baseline/scenegraph/data/shared/square_16x16.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/square_16x16.png rename to tests/baseline/scenegraph/data/shared/square_16x16.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/star_16x16.png b/tests/baseline/scenegraph/data/shared/star_16x16.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/star_16x16.png rename to tests/baseline/scenegraph/data/shared/star_16x16.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/t1.png b/tests/baseline/scenegraph/data/shared/t1.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/t1.png rename to tests/baseline/scenegraph/data/shared/t1.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/t1_bc2.ktx b/tests/baseline/scenegraph/data/shared/t1_bc2.ktx similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/t1_bc2.ktx rename to tests/baseline/scenegraph/data/shared/t1_bc2.ktx diff --git a/tests/manual/scenegraph_lancelot/data/shared/t2.png b/tests/baseline/scenegraph/data/shared/t2.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/t2.png rename to tests/baseline/scenegraph/data/shared/t2.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/t2_bc2.ktx b/tests/baseline/scenegraph/data/shared/t2_bc2.ktx similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/t2_bc2.ktx rename to tests/baseline/scenegraph/data/shared/t2_bc2.ktx diff --git a/tests/manual/scenegraph_lancelot/data/shared/tile.png b/tests/baseline/scenegraph/data/shared/tile.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/tile.png rename to tests/baseline/scenegraph/data/shared/tile.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/uniquepixels.png b/tests/baseline/scenegraph/data/shared/uniquepixels.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/uniquepixels.png rename to tests/baseline/scenegraph/data/shared/uniquepixels.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/violet_72x96.png b/tests/baseline/scenegraph/data/shared/violet_72x96.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/violet_72x96.png rename to tests/baseline/scenegraph/data/shared/violet_72x96.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/winter.png b/tests/baseline/scenegraph/data/shared/winter.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/winter.png rename to tests/baseline/scenegraph/data/shared/winter.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/world.png b/tests/baseline/scenegraph/data/shared/world.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/world.png rename to tests/baseline/scenegraph/data/shared/world.png diff --git a/tests/manual/scenegraph_lancelot/data/shared/yellow_72x96.png b/tests/baseline/scenegraph/data/shared/yellow_72x96.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/shared/yellow_72x96.png rename to tests/baseline/scenegraph/data/shared/yellow_72x96.png diff --git a/tests/manual/scenegraph_lancelot/data/text/data/logo.png b/tests/baseline/scenegraph/data/text/data/logo.png similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/data/logo.png rename to tests/baseline/scenegraph/data/text/data/logo.png diff --git a/tests/manual/scenegraph_lancelot/data/text/element_sizes.qml b/tests/baseline/scenegraph/data/text/element_sizes.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/element_sizes.qml rename to tests/baseline/scenegraph/data/text/element_sizes.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/scale_smoothed.qml b/tests/baseline/scenegraph/data/text/scale_smoothed.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/scale_smoothed.qml rename to tests/baseline/scenegraph/data/text/scale_smoothed.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_1000_chinese_characters.qml b/tests/baseline/scenegraph/data/text/text_1000_chinese_characters.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_1000_chinese_characters.qml rename to tests/baseline/scenegraph/data/text/text_1000_chinese_characters.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_2500_chinese_characters.qml b/tests/baseline/scenegraph/data/text/text_2500_chinese_characters.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_2500_chinese_characters.qml rename to tests/baseline/scenegraph/data/text/text_2500_chinese_characters.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_advance_bidi_ltr.qml b/tests/baseline/scenegraph/data/text/text_advance_bidi_ltr.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_advance_bidi_ltr.qml rename to tests/baseline/scenegraph/data/text/text_advance_bidi_ltr.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_advance_hebrew.qml b/tests/baseline/scenegraph/data/text/text_advance_hebrew.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_advance_hebrew.qml rename to tests/baseline/scenegraph/data/text/text_advance_hebrew.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_advance_latin.qml b/tests/baseline/scenegraph/data/text/text_advance_latin.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_advance_latin.qml rename to tests/baseline/scenegraph/data/text/text_advance_latin.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_advance_multiline.qml b/tests/baseline/scenegraph/data/text/text_advance_multiline.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_advance_multiline.qml rename to tests/baseline/scenegraph/data/text/text_advance_multiline.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_advance_multiparagraph.qml b/tests/baseline/scenegraph/data/text/text_advance_multiparagraph.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_advance_multiparagraph.qml rename to tests/baseline/scenegraph/data/text/text_advance_multiparagraph.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_advance_multiparagraph_multifontsizes.qml b/tests/baseline/scenegraph/data/text/text_advance_multiparagraph_multifontsizes.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_advance_multiparagraph_multifontsizes.qml rename to tests/baseline/scenegraph/data/text/text_advance_multiparagraph_multifontsizes.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_arabic.qml b/tests/baseline/scenegraph/data/text/text_arabic.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_arabic.qml rename to tests/baseline/scenegraph/data/text/text_arabic.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_background_color.qml b/tests/baseline/scenegraph/data/text/text_background_color.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_background_color.qml rename to tests/baseline/scenegraph/data/text/text_background_color.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_background_color_styledtext.qml b/tests/baseline/scenegraph/data/text/text_background_color_styledtext.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_background_color_styledtext.qml rename to tests/baseline/scenegraph/data/text/text_background_color_styledtext.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_bengali.qml b/tests/baseline/scenegraph/data/text/text_bengali.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_bengali.qml rename to tests/baseline/scenegraph/data/text/text_bengali.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_bengali_noshaping.qml b/tests/baseline/scenegraph/data/text/text_bengali_noshaping.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_bengali_noshaping.qml rename to tests/baseline/scenegraph/data/text/text_bengali_noshaping.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_bidi.qml b/tests/baseline/scenegraph/data/text/text_bidi.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_bidi.qml rename to tests/baseline/scenegraph/data/text/text_bidi.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_bidi_control_character_left_elide.qml b/tests/baseline/scenegraph/data/text/text_bidi_control_character_left_elide.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_bidi_control_character_left_elide.qml rename to tests/baseline/scenegraph/data/text/text_bidi_control_character_left_elide.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_bidi_control_character_right_elide.qml b/tests/baseline/scenegraph/data/text/text_bidi_control_character_right_elide.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_bidi_control_character_right_elide.qml rename to tests/baseline/scenegraph/data/text/text_bidi_control_character_right_elide.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_bidi_left_elide.qml b/tests/baseline/scenegraph/data/text/text_bidi_left_elide.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_bidi_left_elide.qml rename to tests/baseline/scenegraph/data/text/text_bidi_left_elide.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_bidi_right_elide.qml b/tests/baseline/scenegraph/data/text/text_bidi_right_elide.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_bidi_right_elide.qml rename to tests/baseline/scenegraph/data/text/text_bidi_right_elide.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_bidi_underline.qml b/tests/baseline/scenegraph/data/text/text_bidi_underline.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_bidi_underline.qml rename to tests/baseline/scenegraph/data/text/text_bidi_underline.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_bitmapfont.qml b/tests/baseline/scenegraph/data/text/text_bitmapfont.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_bitmapfont.qml rename to tests/baseline/scenegraph/data/text/text_bitmapfont.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_capitalization.qml b/tests/baseline/scenegraph/data/text/text_capitalization.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_capitalization.qml rename to tests/baseline/scenegraph/data/text/text_capitalization.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_chinese.qml b/tests/baseline/scenegraph/data/text/text_chinese.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_chinese.qml rename to tests/baseline/scenegraph/data/text/text_chinese.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_colored_background.qml b/tests/baseline/scenegraph/data/text/text_colored_background.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_colored_background.qml rename to tests/baseline/scenegraph/data/text/text_colored_background.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_colored_text.qml b/tests/baseline/scenegraph/data/text/text_colored_text.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_colored_text.qml rename to tests/baseline/scenegraph/data/text/text_colored_text.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_cyrillic.qml b/tests/baseline/scenegraph/data/text/text_cyrillic.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_cyrillic.qml rename to tests/baseline/scenegraph/data/text/text_cyrillic.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_devanagari.qml b/tests/baseline/scenegraph/data/text/text_devanagari.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_devanagari.qml rename to tests/baseline/scenegraph/data/text/text_devanagari.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_emoji.qml b/tests/baseline/scenegraph/data/text/text_emoji.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_emoji.qml rename to tests/baseline/scenegraph/data/text/text_emoji.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_emoji_hebrew.qml b/tests/baseline/scenegraph/data/text/text_emoji_hebrew.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_emoji_hebrew.qml rename to tests/baseline/scenegraph/data/text/text_emoji_hebrew.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_emoji_zwj.qml b/tests/baseline/scenegraph/data/text/text_emoji_zwj.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_emoji_zwj.qml rename to tests/baseline/scenegraph/data/text/text_emoji_zwj.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_floating_image_left.qml b/tests/baseline/scenegraph/data/text/text_floating_image_left.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_floating_image_left.qml rename to tests/baseline/scenegraph/data/text/text_floating_image_left.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_floating_image_right.qml b/tests/baseline/scenegraph/data/text/text_floating_image_right.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_floating_image_right.qml rename to tests/baseline/scenegraph/data/text/text_floating_image_right.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_flow_image_start_ltr.qml b/tests/baseline/scenegraph/data/text/text_flow_image_start_ltr.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_flow_image_start_ltr.qml rename to tests/baseline/scenegraph/data/text/text_flow_image_start_ltr.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_flow_image_start_rtl.qml b/tests/baseline/scenegraph/data/text/text_flow_image_start_rtl.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_flow_image_start_rtl.qml rename to tests/baseline/scenegraph/data/text/text_flow_image_start_rtl.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_fonts.qml b/tests/baseline/scenegraph/data/text/text_fonts.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_fonts.qml rename to tests/baseline/scenegraph/data/text/text_fonts.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_georgian.qml b/tests/baseline/scenegraph/data/text/text_georgian.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_georgian.qml rename to tests/baseline/scenegraph/data/text/text_georgian.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_hebrew.qml b/tests/baseline/scenegraph/data/text/text_hebrew.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_hebrew.qml rename to tests/baseline/scenegraph/data/text/text_hebrew.qml diff --git a/tests/baseline/scenegraph/data/text/text_horizontal_rule.qml b/tests/baseline/scenegraph/data/text/text_horizontal_rule.qml new file mode 100644 index 00000000000..21b4fdc5795 --- /dev/null +++ b/tests/baseline/scenegraph/data/text/text_horizontal_rule.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +Item { + width: 320 + height: 480 + + Text { + anchors.fill: parent + anchors.margins: 10 + font.pixelSize: 18 + textFormat: Text.RichText + text: '<hr>' + + '<hr/>' + + '<hr width="50%"/>' + + '<hr width="70%" style="background-color:#c0fefe; border-width: 1;"/>' + + '<hr width="80" style="background-color:darkblue;"/>' + + '<hr style="background-color:maroon; height: 1px; border-width: 0;"/>' + } +} diff --git a/tests/manual/scenegraph_lancelot/data/text/text_html_center_tag.qml b/tests/baseline/scenegraph/data/text/text_html_center_tag.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_html_center_tag.qml rename to tests/baseline/scenegraph/data/text/text_html_center_tag.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_inline_image.qml b/tests/baseline/scenegraph/data/text/text_inline_image.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_inline_image.qml rename to tests/baseline/scenegraph/data/text/text_inline_image.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_italic_bold.qml b/tests/baseline/scenegraph/data/text/text_italic_bold.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_italic_bold.qml rename to tests/baseline/scenegraph/data/text/text_italic_bold.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_italic_bold_chinese.qml b/tests/baseline/scenegraph/data/text/text_italic_bold_chinese.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_italic_bold_chinese.qml rename to tests/baseline/scenegraph/data/text/text_italic_bold_chinese.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_khmer.qml b/tests/baseline/scenegraph/data/text/text_khmer.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_khmer.qml rename to tests/baseline/scenegraph/data/text/text_khmer.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_latin_noshaping.qml b/tests/baseline/scenegraph/data/text/text_latin_noshaping.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_latin_noshaping.qml rename to tests/baseline/scenegraph/data/text/text_latin_noshaping.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_list_circle.qml b/tests/baseline/scenegraph/data/text/text_list_circle.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_list_circle.qml rename to tests/baseline/scenegraph/data/text/text_list_circle.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_list_inline_image.qml b/tests/baseline/scenegraph/data/text/text_list_inline_image.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_list_inline_image.qml rename to tests/baseline/scenegraph/data/text/text_list_inline_image.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_list_ordered.qml b/tests/baseline/scenegraph/data/text/text_list_ordered.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_list_ordered.qml rename to tests/baseline/scenegraph/data/text/text_list_ordered.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_list_ordered_lower_alpha.qml b/tests/baseline/scenegraph/data/text/text_list_ordered_lower_alpha.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_list_ordered_lower_alpha.qml rename to tests/baseline/scenegraph/data/text/text_list_ordered_lower_alpha.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_list_ordered_lower_roman.qml b/tests/baseline/scenegraph/data/text/text_list_ordered_lower_roman.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_list_ordered_lower_roman.qml rename to tests/baseline/scenegraph/data/text/text_list_ordered_lower_roman.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_list_ordered_upper_alpha.qml b/tests/baseline/scenegraph/data/text/text_list_ordered_upper_alpha.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_list_ordered_upper_alpha.qml rename to tests/baseline/scenegraph/data/text/text_list_ordered_upper_alpha.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_list_ordered_upper_roman.qml b/tests/baseline/scenegraph/data/text/text_list_ordered_upper_roman.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_list_ordered_upper_roman.qml rename to tests/baseline/scenegraph/data/text/text_list_ordered_upper_roman.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_list_square.qml b/tests/baseline/scenegraph/data/text/text_list_square.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_list_square.qml rename to tests/baseline/scenegraph/data/text/text_list_square.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_multiline.qml b/tests/baseline/scenegraph/data/text/text_multiline.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_multiline.qml rename to tests/baseline/scenegraph/data/text/text_multiline.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_multiline_overline.qml b/tests/baseline/scenegraph/data/text/text_multiline_overline.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_multiline_overline.qml rename to tests/baseline/scenegraph/data/text/text_multiline_overline.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_multiline_partial_underline.qml b/tests/baseline/scenegraph/data/text/text_multiline_partial_underline.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_multiline_partial_underline.qml rename to tests/baseline/scenegraph/data/text/text_multiline_partial_underline.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_multiline_strikeout.qml b/tests/baseline/scenegraph/data/text/text_multiline_strikeout.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_multiline_strikeout.qml rename to tests/baseline/scenegraph/data/text/text_multiline_strikeout.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_multiline_underline.qml b/tests/baseline/scenegraph/data/text/text_multiline_underline.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_multiline_underline.qml rename to tests/baseline/scenegraph/data/text/text_multiline_underline.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_multiparagraph.qml b/tests/baseline/scenegraph/data/text/text_multiparagraph.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_multiparagraph.qml rename to tests/baseline/scenegraph/data/text/text_multiparagraph.qml diff --git a/tests/baseline/scenegraph/data/text/text_nativerendering_no_antialiasing.qml b/tests/baseline/scenegraph/data/text/text_nativerendering_no_antialiasing.qml new file mode 100644 index 00000000000..92598eb490e --- /dev/null +++ b/tests/baseline/scenegraph/data/text/text_nativerendering_no_antialiasing.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +//vary font style, native rendering without antialiasing + +Item { + id: topLevel + width: 320 + height: 580 + + Repeater { + model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken] + Text { + y: 20 * index + clip: true + renderType: Text.NativeRendering + width: parent.width + wrapMode: Text.Wrap + font.pointSize: 10 + style: modelData + styleColor: "green" + antialiasing: false + text: "The quick fox jumps in style " + modelData + } + } +} diff --git a/tests/baseline/scenegraph/data/text/text_nativerendering_subpixelpositions.qml b/tests/baseline/scenegraph/data/text/text_nativerendering_subpixelpositions.qml new file mode 100644 index 00000000000..c60fc4d8b06 --- /dev/null +++ b/tests/baseline/scenegraph/data/text/text_nativerendering_subpixelpositions.qml @@ -0,0 +1,91 @@ +import QtQuick 2.0 + +//vary font style, native rendering at non-integer offsets + +Item { + id: topLevel + width: 320 + height: 580 + + Repeater { + model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken] + Text { + y: 20 * index + clip: true + renderType: Text.NativeRendering + width: parent.width + wrapMode: Text.Wrap + font.pointSize: 10 + style: modelData + styleColor: "green" + text: "The quick fox jumps in style " + modelData + } + } + + Repeater { + model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken] + Text { + y: 100.5 + 20 * index + clip: true + renderType: Text.NativeRendering + width: parent.width + wrapMode: Text.Wrap + font.pointSize: 10 + style: modelData + styleColor: "green" + text: "The quick fox jumps in style " + modelData + } + } + + Repeater { + model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken] + Text { + y: 200.5 + 20 * index + x: 0.5 + clip: true + renderType: Text.NativeRendering + width: parent.width + wrapMode: Text.Wrap + font.pointSize: 10 + style: modelData + styleColor: "green" + text: "The quick fox jumps in style " + modelData + } + } + + Repeater { + model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken] + Text { + y: 300.5 + 20 * index + x: 0.5 + clip: true + renderType: Text.NativeRendering + width: parent.width + wrapMode: Text.Wrap + font.pointSize: 10 + style: modelData + styleColor: "green" + text: "The quick fox jumps in style " + modelData + } + } + + Repeater { + model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken] + Rectangle { + y: 400.5 + 20 * index + x: 0.5 + width: topLevel.width + height: topLevel.height + clip: true + Text { + renderType: Text.NativeRendering + width: parent.width + wrapMode: Text.Wrap + font.pointSize: 10 + style: modelData + styleColor: "green" + text: "The quick fox jumps in style " + modelData + } + } + } +} diff --git a/tests/manual/scenegraph_lancelot/data/text/text_nokerning_latin.qml b/tests/baseline/scenegraph/data/text/text_nokerning_latin.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_nokerning_latin.qml rename to tests/baseline/scenegraph/data/text/text_nokerning_latin.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_overline_multisize.qml b/tests/baseline/scenegraph/data/text/text_overline_multisize.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_overline_multisize.qml rename to tests/baseline/scenegraph/data/text/text_overline_multisize.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_partially_colored_ligature.qml b/tests/baseline/scenegraph/data/text/text_partially_colored_ligature.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_partially_colored_ligature.qml rename to tests/baseline/scenegraph/data/text/text_partially_colored_ligature.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_resize_glyph_cache.qml b/tests/baseline/scenegraph/data/text/text_resize_glyph_cache.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_resize_glyph_cache.qml rename to tests/baseline/scenegraph/data/text/text_resize_glyph_cache.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_rotation_smoothed.qml b/tests/baseline/scenegraph/data/text/text_rotation_smoothed.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_rotation_smoothed.qml rename to tests/baseline/scenegraph/data/text/text_rotation_smoothed.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_rotation_unsmoothed.qml b/tests/baseline/scenegraph/data/text/text_rotation_unsmoothed.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_rotation_unsmoothed.qml rename to tests/baseline/scenegraph/data/text/text_rotation_unsmoothed.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_scale_unsmoothed.qml b/tests/baseline/scenegraph/data/text/text_scale_unsmoothed.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_scale_unsmoothed.qml rename to tests/baseline/scenegraph/data/text/text_scale_unsmoothed.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_sinhala.qml b/tests/baseline/scenegraph/data/text/text_sinhala.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_sinhala.qml rename to tests/baseline/scenegraph/data/text/text_sinhala.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_strikeout_multisize.qml b/tests/baseline/scenegraph/data/text/text_strikeout_multisize.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_strikeout_multisize.qml rename to tests/baseline/scenegraph/data/text/text_strikeout_multisize.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_style.qml b/tests/baseline/scenegraph/data/text/text_style.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_style.qml rename to tests/baseline/scenegraph/data/text/text_style.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_style2.qml b/tests/baseline/scenegraph/data/text/text_style2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_style2.qml rename to tests/baseline/scenegraph/data/text/text_style2.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_style_color.qml b/tests/baseline/scenegraph/data/text/text_style_color.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_style_color.qml rename to tests/baseline/scenegraph/data/text/text_style_color.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_table.qml b/tests/baseline/scenegraph/data/text/text_table.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_table.qml rename to tests/baseline/scenegraph/data/text/text_table.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_table_inline_image.qml b/tests/baseline/scenegraph/data/text/text_table_inline_image.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_table_inline_image.qml rename to tests/baseline/scenegraph/data/text/text_table_inline_image.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_table_selected.qml b/tests/baseline/scenegraph/data/text/text_table_selected.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_table_selected.qml rename to tests/baseline/scenegraph/data/text/text_table_selected.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_table_vertically_aligned_image.qml b/tests/baseline/scenegraph/data/text/text_table_vertically_aligned_image.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_table_vertically_aligned_image.qml rename to tests/baseline/scenegraph/data/text/text_table_vertically_aligned_image.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_tamil.qml b/tests/baseline/scenegraph/data/text/text_tamil.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_tamil.qml rename to tests/baseline/scenegraph/data/text/text_tamil.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_thai.qml b/tests/baseline/scenegraph/data/text/text_thai.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_thai.qml rename to tests/baseline/scenegraph/data/text/text_thai.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_underline_merged.qml b/tests/baseline/scenegraph/data/text/text_underline_merged.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_underline_merged.qml rename to tests/baseline/scenegraph/data/text/text_underline_merged.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_underline_merged_colored.qml b/tests/baseline/scenegraph/data/text/text_underline_merged_colored.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_underline_merged_colored.qml rename to tests/baseline/scenegraph/data/text/text_underline_merged_colored.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_underline_multisize.qml b/tests/baseline/scenegraph/data/text/text_underline_multisize.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_underline_multisize.qml rename to tests/baseline/scenegraph/data/text/text_underline_multisize.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_weight.qml b/tests/baseline/scenegraph/data/text/text_weight.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_weight.qml rename to tests/baseline/scenegraph/data/text/text_weight.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_wrap_elide.qml b/tests/baseline/scenegraph/data/text/text_wrap_elide.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_wrap_elide.qml rename to tests/baseline/scenegraph/data/text/text_wrap_elide.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/text_wrap_elide_maxlines.qml b/tests/baseline/scenegraph/data/text/text_wrap_elide_maxlines.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/text_wrap_elide_maxlines.qml rename to tests/baseline/scenegraph/data/text/text_wrap_elide_maxlines.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_arabic.qml b/tests/baseline/scenegraph/data/text/textedit_arabic.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_arabic.qml rename to tests/baseline/scenegraph/data/text/textedit_arabic.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_background_color.qml b/tests/baseline/scenegraph/data/text/textedit_background_color.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_background_color.qml rename to tests/baseline/scenegraph/data/text/textedit_background_color.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_bidi.qml b/tests/baseline/scenegraph/data/text/textedit_bidi.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_bidi.qml rename to tests/baseline/scenegraph/data/text/textedit_bidi.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_bidi_selected.qml b/tests/baseline/scenegraph/data/text/textedit_bidi_selected.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_bidi_selected.qml rename to tests/baseline/scenegraph/data/text/textedit_bidi_selected.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_bidi_selected_first.qml b/tests/baseline/scenegraph/data/text/textedit_bidi_selected_first.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_bidi_selected_first.qml rename to tests/baseline/scenegraph/data/text/textedit_bidi_selected_first.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_capitalization.qml b/tests/baseline/scenegraph/data/text/textedit_capitalization.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_capitalization.qml rename to tests/baseline/scenegraph/data/text/textedit_capitalization.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_chinese.qml b/tests/baseline/scenegraph/data/text/textedit_chinese.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_chinese.qml rename to tests/baseline/scenegraph/data/text/textedit_chinese.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_cyrillic.qml b/tests/baseline/scenegraph/data/text/textedit_cyrillic.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_cyrillic.qml rename to tests/baseline/scenegraph/data/text/textedit_cyrillic.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_cyrillic_selected.qml b/tests/baseline/scenegraph/data/text/textedit_cyrillic_selected.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_cyrillic_selected.qml rename to tests/baseline/scenegraph/data/text/textedit_cyrillic_selected.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_cyrillic_selected_all.qml b/tests/baseline/scenegraph/data/text/textedit_cyrillic_selected_all.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_cyrillic_selected_all.qml rename to tests/baseline/scenegraph/data/text/textedit_cyrillic_selected_all.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_devanagari.qml b/tests/baseline/scenegraph/data/text/textedit_devanagari.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_devanagari.qml rename to tests/baseline/scenegraph/data/text/textedit_devanagari.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_floating_image_left.qml b/tests/baseline/scenegraph/data/text/textedit_floating_image_left.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_floating_image_left.qml rename to tests/baseline/scenegraph/data/text/textedit_floating_image_left.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_floating_image_right.qml b/tests/baseline/scenegraph/data/text/textedit_floating_image_right.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_floating_image_right.qml rename to tests/baseline/scenegraph/data/text/textedit_floating_image_right.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_hebrew.qml b/tests/baseline/scenegraph/data/text/textedit_hebrew.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_hebrew.qml rename to tests/baseline/scenegraph/data/text/textedit_hebrew.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_list_circle.qml b/tests/baseline/scenegraph/data/text/textedit_list_circle.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_list_circle.qml rename to tests/baseline/scenegraph/data/text/textedit_list_circle.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_list_selected.qml b/tests/baseline/scenegraph/data/text/textedit_list_selected.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_list_selected.qml rename to tests/baseline/scenegraph/data/text/textedit_list_selected.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_center_aligned.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_center_aligned.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_center_aligned.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_center_aligned.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_center_aligned_selected.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_center_aligned_selected.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_center_aligned_selected.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_center_aligned_selected.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_center_aligned_selected_eol.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_center_aligned_selected_eol.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_center_aligned_selected_eol.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_center_aligned_selected_eol.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_center_aligned_underline.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_center_aligned_underline.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_center_aligned_underline.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_center_aligned_underline.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_center_aligned_underline_selected.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_center_aligned_underline_selected.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_center_aligned_underline_selected.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_center_aligned_underline_selected.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_hebrew_selected.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_hebrew_selected.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_hebrew_selected.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_hebrew_selected.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_partial_underline.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_partial_underline.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_partial_underline.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_partial_underline.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_right_aligned.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_right_aligned.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_right_aligned.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_right_aligned.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_right_aligned_selected.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_right_aligned_selected.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_right_aligned_selected.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_right_aligned_selected.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_eol.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_selected_eol.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_eol.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_selected_eol.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_first_line.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_selected_first_line.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_first_line.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_selected_first_line.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_linebreaks_and_linewraps.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_selected_linebreaks_and_linewraps.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_linebreaks_and_linewraps.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_selected_linebreaks_and_linewraps.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_linebreaks_and_linewraps2.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_selected_linebreaks_and_linewraps2.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_linebreaks_and_linewraps2.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_selected_linebreaks_and_linewraps2.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_long.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_selected_long.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_long.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_selected_long.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_two_first_lines.qml b/tests/baseline/scenegraph/data/text/textedit_multiline_selected_two_first_lines.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiline_selected_two_first_lines.qml rename to tests/baseline/scenegraph/data/text/textedit_multiline_selected_two_first_lines.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiparagraph_overline.qml b/tests/baseline/scenegraph/data/text/textedit_multiparagraph_overline.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiparagraph_overline.qml rename to tests/baseline/scenegraph/data/text/textedit_multiparagraph_overline.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiparagraph_partial_underline.qml b/tests/baseline/scenegraph/data/text/textedit_multiparagraph_partial_underline.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiparagraph_partial_underline.qml rename to tests/baseline/scenegraph/data/text/textedit_multiparagraph_partial_underline.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiparagraph_selected.qml b/tests/baseline/scenegraph/data/text/textedit_multiparagraph_selected.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiparagraph_selected.qml rename to tests/baseline/scenegraph/data/text/textedit_multiparagraph_selected.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiparagraph_strikeout.qml b/tests/baseline/scenegraph/data/text/textedit_multiparagraph_strikeout.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiparagraph_strikeout.qml rename to tests/baseline/scenegraph/data/text/textedit_multiparagraph_strikeout.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_multiparagraph_underline.qml b/tests/baseline/scenegraph/data/text/textedit_multiparagraph_underline.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_multiparagraph_underline.qml rename to tests/baseline/scenegraph/data/text/textedit_multiparagraph_underline.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_overline_multisize.qml b/tests/baseline/scenegraph/data/text/textedit_overline_multisize.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_overline_multisize.qml rename to tests/baseline/scenegraph/data/text/textedit_overline_multisize.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_resize_glyph_cache.qml b/tests/baseline/scenegraph/data/text/textedit_resize_glyph_cache.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_resize_glyph_cache.qml rename to tests/baseline/scenegraph/data/text/textedit_resize_glyph_cache.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_selected_inline_image.qml b/tests/baseline/scenegraph/data/text/textedit_selected_inline_image.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_selected_inline_image.qml rename to tests/baseline/scenegraph/data/text/textedit_selected_inline_image.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_selected_inline_image_selection_outside.qml b/tests/baseline/scenegraph/data/text/textedit_selected_inline_image_selection_outside.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_selected_inline_image_selection_outside.qml rename to tests/baseline/scenegraph/data/text/textedit_selected_inline_image_selection_outside.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_selected_ligature.qml b/tests/baseline/scenegraph/data/text/textedit_selected_ligature.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_selected_ligature.qml rename to tests/baseline/scenegraph/data/text/textedit_selected_ligature.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_selected_space.qml b/tests/baseline/scenegraph/data/text/textedit_selected_space.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_selected_space.qml rename to tests/baseline/scenegraph/data/text/textedit_selected_space.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_selected_space_at_eol.qml b/tests/baseline/scenegraph/data/text/textedit_selected_space_at_eol.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_selected_space_at_eol.qml rename to tests/baseline/scenegraph/data/text/textedit_selected_space_at_eol.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_selection_color.qml b/tests/baseline/scenegraph/data/text/textedit_selection_color.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_selection_color.qml rename to tests/baseline/scenegraph/data/text/textedit_selection_color.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_selection_color_separate_item.qml b/tests/baseline/scenegraph/data/text/textedit_selection_color_separate_item.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_selection_color_separate_item.qml rename to tests/baseline/scenegraph/data/text/textedit_selection_color_separate_item.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_strikeout_multisize.qml b/tests/baseline/scenegraph/data/text/textedit_strikeout_multisize.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_strikeout_multisize.qml rename to tests/baseline/scenegraph/data/text/textedit_strikeout_multisize.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_table.qml b/tests/baseline/scenegraph/data/text/textedit_table.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_table.qml rename to tests/baseline/scenegraph/data/text/textedit_table.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_table_selected.qml b/tests/baseline/scenegraph/data/text/textedit_table_selected.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_table_selected.qml rename to tests/baseline/scenegraph/data/text/textedit_table_selected.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_underline_multisize.qml b/tests/baseline/scenegraph/data/text/textedit_underline_multisize.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_underline_multisize.qml rename to tests/baseline/scenegraph/data/text/textedit_underline_multisize.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_weight.qml b/tests/baseline/scenegraph/data/text/textedit_weight.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textedit_weight.qml rename to tests/baseline/scenegraph/data/text/textedit_weight.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_arabic.qml b/tests/baseline/scenegraph/data/text/textinput_arabic.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_arabic.qml rename to tests/baseline/scenegraph/data/text/textinput_arabic.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_bidi_selected.qml b/tests/baseline/scenegraph/data/text/textinput_bidi_selected.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_bidi_selected.qml rename to tests/baseline/scenegraph/data/text/textinput_bidi_selected.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_capitalization.qml b/tests/baseline/scenegraph/data/text/textinput_capitalization.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_capitalization.qml rename to tests/baseline/scenegraph/data/text/textinput_capitalization.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_chinese.qml b/tests/baseline/scenegraph/data/text/textinput_chinese.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_chinese.qml rename to tests/baseline/scenegraph/data/text/textinput_chinese.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_cyrillic.qml b/tests/baseline/scenegraph/data/text/textinput_cyrillic.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_cyrillic.qml rename to tests/baseline/scenegraph/data/text/textinput_cyrillic.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_devanagari.qml b/tests/baseline/scenegraph/data/text/textinput_devanagari.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_devanagari.qml rename to tests/baseline/scenegraph/data/text/textinput_devanagari.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_echomodes.qml b/tests/baseline/scenegraph/data/text/textinput_echomodes.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_echomodes.qml rename to tests/baseline/scenegraph/data/text/textinput_echomodes.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_hebrew.qml b/tests/baseline/scenegraph/data/text/textinput_hebrew.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_hebrew.qml rename to tests/baseline/scenegraph/data/text/textinput_hebrew.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_italic_selected.qml b/tests/baseline/scenegraph/data/text/textinput_italic_selected.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_italic_selected.qml rename to tests/baseline/scenegraph/data/text/textinput_italic_selected.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_resize_glyph_cache.qml b/tests/baseline/scenegraph/data/text/textinput_resize_glyph_cache.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_resize_glyph_cache.qml rename to tests/baseline/scenegraph/data/text/textinput_resize_glyph_cache.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_selected_fallback_font.qml b/tests/baseline/scenegraph/data/text/textinput_selected_fallback_font.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_selected_fallback_font.qml rename to tests/baseline/scenegraph/data/text/textinput_selected_fallback_font.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_selected_ligature.qml b/tests/baseline/scenegraph/data/text/textinput_selected_ligature.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_selected_ligature.qml rename to tests/baseline/scenegraph/data/text/textinput_selected_ligature.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_selected_space.qml b/tests/baseline/scenegraph/data/text/textinput_selected_space.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_selected_space.qml rename to tests/baseline/scenegraph/data/text/textinput_selected_space.qml diff --git a/tests/manual/scenegraph_lancelot/data/text/textinput_weight.qml b/tests/baseline/scenegraph/data/text/textinput_weight.qml similarity index 100% rename from tests/manual/scenegraph_lancelot/data/text/textinput_weight.qml rename to tests/baseline/scenegraph/data/text/textinput_weight.qml diff --git a/tests/baseline/scenegraph/scenegrabber/CMakeLists.txt b/tests/baseline/scenegraph/scenegrabber/CMakeLists.txt new file mode 100644 index 00000000000..e635287cee9 --- /dev/null +++ b/tests/baseline/scenegraph/scenegrabber/CMakeLists.txt @@ -0,0 +1,38 @@ +##################################################################### +## qmlscenegrabber Binary: +##################################################################### + +qt_internal_add_manual_test(qmlscenegrabber + OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.." # special case + SOURCES + main.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Quick +) + +qt6_add_shaders(qmlscenegrabber "qmlscenegrabber_shaders" + BATCHABLE + PREFIX + "/" + BASE + "../data/shared" + FILES + "../data/shared/shaders/basic_alpha.frag" + "../data/shared/shaders/basic.frag" + "../data/shared/shaders/cmyk.frag" + "../data/shared/shaders/culling.frag" + "../data/shared/shaders/desaturate.frag" + "../data/shared/shaders/edge.frag" + "../data/shared/shaders/gradient2.frag" + "../data/shared/shaders/gradient3.frag" + "../data/shared/shaders/gradient4.frag" + "../data/shared/shaders/gradient5.frag" + "../data/shared/shaders/gradient.frag" + "../data/shared/shaders/gradientgrid.frag" + "../data/shared/shaders/property.frag" + "../data/shared/shaders/shadow.frag" + "../data/shared/shaders/stencil.frag" + "../data/shared/shaders/subrect.vert" + "../data/shared/shaders/wave.vert" +) diff --git a/tests/baseline/scenegraph/scenegrabber/main.cpp b/tests/baseline/scenegraph/scenegrabber/main.cpp new file mode 100644 index 00000000000..f9e1dc8fbb3 --- /dev/null +++ b/tests/baseline/scenegraph/scenegrabber/main.cpp @@ -0,0 +1,228 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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/QTimer> +#include <QtCore/QDebug> +#include <QtCore/QFileInfo> +#include <QtCore/QHashFunctions> +#include <QtGui/QGuiApplication> +#include <QtGui/QImage> + +#include <QtQuick/QQuickView> +#include <QtQuick/QQuickItem> + +#ifdef Q_OS_WIN +# include <fcntl.h> +# include <io.h> +#endif // Q_OS_WIN + +// Timeout values: + +// A valid screen grab requires the scene to not change +// for SCENE_STABLE_TIME ms +#define SCENE_STABLE_TIME 200 + +// Give up after SCENE_TIMEOUT ms +#define SCENE_TIMEOUT 6000 + +//#define GRABBERDEBUG + +static const QSize DefaultGrabSize(320, 480); + +class GrabbingView : public QQuickView +{ + Q_OBJECT + +public: + GrabbingView(const QString &outputFile) + : ofile(outputFile), grabNo(0), isGrabbing(false), initDone(false), justShow(outputFile.isEmpty()) + { + if (justShow) + return; + grabTimer = new QTimer(this); + grabTimer->setSingleShot(true); + grabTimer->setInterval(SCENE_STABLE_TIME); + connect(grabTimer, SIGNAL(timeout()), SLOT(grab())); + + connect(this, SIGNAL(afterRendering()), SLOT(startGrabbing())); + + QTimer::singleShot(SCENE_TIMEOUT, this, SLOT(timedOut())); + } + +private slots: + void startGrabbing() + { + if (!initDone) { + initDone = true; + grabTimer->start(); + } + } + + void grab() + { + if (isGrabbing) + return; + isGrabbing = true; + grabNo++; +#ifdef GRABBERDEBUG + printf("grab no. %i\n", grabNo); +#endif + QImage img = grabWindow(); + if (!img.isNull() && img == lastGrab) { + sceneStabilized(); + } else { + lastGrab = img; + grabTimer->start(); + } + + isGrabbing = false; + } + + void sceneStabilized() + { +#ifdef GRABBERDEBUG + printf("...sceneStabilized IN\n"); +#endif + if (QGuiApplication::platformName() == QLatin1String("eglfs")) { + QSize grabSize = initialSize().isEmpty() ? DefaultGrabSize : initialSize(); + lastGrab = lastGrab.copy(QRect(QPoint(0, 0), grabSize)); + } + + if (ofile == "-") { // Write to stdout + QFile of; +#ifdef Q_OS_WIN + // Make sure write to stdout doesn't do LF->CRLF + _setmode(_fileno(stdout), _O_BINARY); +#endif // Q_OS_WIN + if (!of.open(1, QIODevice::WriteOnly) || !lastGrab.save(&of, "ppm")) { + qWarning() << "Error: failed to write grabbed image to stdout."; + QGuiApplication::exit(2); + return; + } + } else { + if (!lastGrab.save(ofile)) { + qWarning() << "Error: failed to store grabbed image to" << ofile; + QGuiApplication::exit(2); + return; + } + } + QGuiApplication::exit(0); +#ifdef GRABBERDEBUG + printf("...sceneStabilized OUT\n"); +#endif + } + + void timedOut() + { + qWarning() << "Error: timed out waiting for scene to stabilize." << grabNo << "grab(s) done. Last grab was" << (lastGrab.isNull() ? "invalid." : "valid."); + QGuiApplication::exit(3); + } + +private: + QImage lastGrab; + QTimer *grabTimer = nullptr; + QString ofile; + int grabNo; + bool isGrabbing; + bool initDone; + bool justShow; +}; + + +int main(int argc, char *argv[]) +{ + qSetGlobalQHashSeed(0); + + QGuiApplication a(argc, argv); + + // Parse command line + QString ifile, ofile; + bool noText = false; + bool justShow = false; + QStringList args = a.arguments(); + int i = 0; + bool argError = false; + while (++i < args.size()) { + QString arg = args.at(i); + if ((arg == "-o") && (i < args.size()-1)) { + ofile = args.at(++i); + } + else if (arg == "-notext") { + noText = true; + } + else if (arg == "--cache-distance-fields") { + ; + } + else if (arg == "-viewonly") { + justShow = true; + } + else if (ifile.isEmpty()) { + ifile = arg; + } + else { + argError = true; + break; + } + } + if (argError || ifile.isEmpty() || (ofile.isEmpty() && !justShow)) { + qWarning() << "Usage:" << args.at(0).toLatin1().constData() << "[-notext] <qml-infile> {-o <outfile or - for ppm on stdout>|-viewonly}"; + return 1; + } + + QFileInfo ifi(ifile); + if (!ifi.exists() || !ifi.isReadable() || !ifi.isFile()) { + qWarning() << args.at(0).toLatin1().constData() << " error: unreadable input file" << ifile; + return 1; + } + // End parsing + + GrabbingView v(ofile); + v.setSource(QUrl::fromLocalFile(ifile)); + + if (noText) { + const QList<QQuickItem*> items = v.rootObject()->findChildren<QQuickItem*>(); + for (QQuickItem *item : items) { + if (QByteArray(item->metaObject()->className()).contains("Text")) + item->setVisible(false); + } + } + + if (v.initialSize().isEmpty()) + v.resize(DefaultGrabSize); + + v.show(); + + int retVal = a.exec(); +#ifdef GRABBERDEBUG + printf("...retVal=%i\n", retVal); +#endif + + return retVal; +} + +#include "main.moc" diff --git a/tests/baseline/scenegraph/scenegraph/CMakeLists.txt b/tests/baseline/scenegraph/scenegraph/CMakeLists.txt new file mode 100644 index 00000000000..15e96ea09a0 --- /dev/null +++ b/tests/baseline/scenegraph/scenegraph/CMakeLists.txt @@ -0,0 +1,23 @@ +##################################################################### +## tst_baseline_scenegraph Test: +##################################################################### + +# Collect test data +list(APPEND test_data "../data") + +qt_internal_add_test(tst_baseline_scenegraph + OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.." + SOURCES + ../../../../../qtbase/tests/baseline/shared/baselineprotocol.cpp + ../../../../../qtbase/tests/baseline/shared/baselineprotocol.h + ../../../../../qtbase/tests/baseline/shared/lookup3.cpp + ../../../../../qtbase/tests/baseline/shared/qbaselinetest.cpp + ../../../../../qtbase/tests/baseline/shared/qbaselinetest.h + tst_baseline_scenegraph.cpp + INCLUDE_DIRECTORIES + ../../../../../qtbase/tests/baseline/shared + PUBLIC_LIBRARIES + Qt::Gui + Qt::Network + TESTDATA ${test_data} +) diff --git a/tests/baseline/scenegraph/scenegraph/tst_baseline_scenegraph.cpp b/tests/baseline/scenegraph/scenegraph/tst_baseline_scenegraph.cpp new file mode 100644 index 00000000000..8155a5e7593 --- /dev/null +++ b/tests/baseline/scenegraph/scenegraph/tst_baseline_scenegraph.cpp @@ -0,0 +1,297 @@ + +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <qbaselinetest.h> + +#include <QtCore/QCoreApplication> +#include <QtCore/QDirIterator> +#include <QtCore/QDebug> +#include <QtCore/QProcess> +#include <QtGui/QImage> + +#include <algorithm> + +QString blockify(const QByteArray& s) +{ + const char* indent = "\n | "; + QByteArray block = s.trimmed(); + block.replace('\n', indent); + block.prepend(indent); + block.append('\n'); + return block; +} + +//#define TEXTLESS_TEST + +class tst_Scenegraph : public QObject +{ + Q_OBJECT + +public: + tst_Scenegraph(); + +private Q_SLOTS: + void initTestCase(); + void cleanup(); +#ifdef TEXTLESS_TEST + void testNoTextRendering_data(); + void testNoTextRendering(); +#endif + void testRendering_data(); + void testRendering(); + +private: + void setupTestSuite(const QByteArray& filter = QByteArray()); + void runTest(const QStringList& extraArgs = QStringList()); + bool renderAndGrab(const QString& qmlFile, const QStringList& extraArgs, QImage *screenshot, QString *errMsg); + quint16 checksumFileOrDir(const QString &path); + + QString testSuitePath; + QString grabberPath; + int consecutiveErrors; // Not test failures (image mismatches), but system failures (so no image at all) + bool aborted; // This run given up because of too many system failures +}; + + +tst_Scenegraph::tst_Scenegraph() + : consecutiveErrors(0), aborted(false) +{ +} + + +void tst_Scenegraph::initTestCase() +{ + QString dataDir = QFINDTESTDATA("../data/."); + if (dataDir.isEmpty()) + dataDir = QStringLiteral("data"); + QFileInfo fi(dataDir); + if (!fi.exists() || !fi.isDir() || !fi.isReadable()) + QSKIP("Test suite data directory missing or unreadable: " + fi.canonicalFilePath().toLatin1()); + testSuitePath = fi.canonicalFilePath(); + +#if defined(Q_OS_WIN) + grabberPath = QFINDTESTDATA("qmlscenegrabber.exe"); +#elif defined(Q_OS_DARWIN) + grabberPath = QFINDTESTDATA("qmlscenegrabber.app/Contents/MacOS/qmlscenegrabber"); +#else + grabberPath = QFINDTESTDATA("qmlscenegrabber"); +#endif + if (grabberPath.isEmpty()) + grabberPath = QCoreApplication::applicationDirPath() + "/qmlscenegrabber"; + + const char *backendVarName = "QT_QUICK_BACKEND"; + const QString backend = qEnvironmentVariable(backendVarName, QString::fromLatin1("default")); + QBaselineTest::addClientProperty(QString::fromLatin1(backendVarName), backend); + + QString stack = backend; + if (stack != QLatin1String("software")) { +#if defined(Q_OS_WIN) + const char *defaultRhiBackend = "d3d11"; +#elif defined(Q_OS_DARWIN) + const char *defaultRhiBackend = "metal"; +#else + const char *defaultRhiBackend = "opengl"; +#endif + const QString rhiBackend = qEnvironmentVariable("QSG_RHI_BACKEND", QString::fromLatin1(defaultRhiBackend)); + stack = QString::fromLatin1("RHI_%1").arg(rhiBackend); + } + QBaselineTest::addClientProperty(QString::fromLatin1("GraphicsStack"), stack); + + QByteArray msg; + if (!QBaselineTest::connectToBaselineServer(&msg)) + QSKIP(msg); +} + + +void tst_Scenegraph::cleanup() +{ + // Allow subsystems time to settle + if (!aborted) + QTest::qWait(20); +} + +#ifdef TEXTLESS_TEST +void tst_Scenegraph::testNoTextRendering_data() +{ + setupTestSuite("text/"); + consecutiveErrors = 0; + aborted = false; +} + + +void tst_Scenegraph::testNoTextRendering() +{ + runTest(QStringList() << "-notext"); +} +#endif + +void tst_Scenegraph::testRendering_data() +{ + setupTestSuite(); + consecutiveErrors = 0; + aborted = false; +} + + +void tst_Scenegraph::testRendering() +{ + runTest(); +} + + +void tst_Scenegraph::setupTestSuite(const QByteArray& filter) +{ + QTest::addColumn<QString>("qmlFile"); + int numItems = 0; + + QStringList ignoreItems; + QFile ignoreFile(testSuitePath + "/Ignore"); + if (ignoreFile.open(QIODevice::ReadOnly)) { + while (!ignoreFile.atEnd()) { + QByteArray line = ignoreFile.readLine().trimmed(); + if (!line.isEmpty() && !line.startsWith('#')) + ignoreItems += line; + } + } + + QStringList itemFiles; + QDirIterator it(testSuitePath, QDirIterator::Subdirectories); + while (it.hasNext()) { + QString fp = it.next(); + if (fp.endsWith(".qml")) { + QString itemName = fp.mid(testSuitePath.length() + 1); + if (!ignoreItems.contains(itemName) && (filter.isEmpty() || !itemName.startsWith(filter))) + itemFiles.append(it.filePath()); + } + } + + std::sort(itemFiles.begin(), itemFiles.end()); + for (const QString &filePath : qAsConst(itemFiles)) { + QByteArray itemName = filePath.mid(testSuitePath.length() + 1).toLatin1(); + QBaselineTest::newRow(itemName, checksumFileOrDir(filePath)) << filePath; + numItems++; + } + + if (!numItems) + QSKIP("No .qml test files found in " + testSuitePath.toLatin1()); +} + + +void tst_Scenegraph::runTest(const QStringList& extraArgs) +{ + // qDebug() << "Rendering" << QTest::currentDataTag(); + + if (aborted) + QSKIP("System too unstable."); + + QFETCH(QString, qmlFile); + + QImage screenShot; + QString errorMessage; + if (renderAndGrab(qmlFile, extraArgs, &screenShot, &errorMessage)) { + consecutiveErrors = 0; + } + else { + if (++consecutiveErrors >= 3) + aborted = true; // Just give up if screen grabbing fails 3 times in a row + QFAIL(qPrintable("QuickView grabbing failed: " + errorMessage)); + } + + QBASELINE_TEST(screenShot); +} + + +bool tst_Scenegraph::renderAndGrab(const QString& qmlFile, const QStringList& extraArgs, QImage *screenshot, QString *errMsg) +{ + bool usePipe = true; // Whether to transport the grabbed image using temp. file or pipe. TBD: cmdline option + QProcess grabber; + grabber.setProcessChannelMode(QProcess::ForwardedErrorChannel); + QStringList args = extraArgs; + QString tmpfile = usePipe ? QString("-") : QString("/tmp/qmlscenegrabber-%1-out.ppm").arg(QCoreApplication::applicationPid()); + args << qmlFile << "-o" << tmpfile; + grabber.start(grabberPath, args, QIODevice::ReadOnly); + grabber.waitForFinished(17000); //### hardcoded, must be larger than the scene timeout in qmlscenegrabber + if (grabber.state() != QProcess::NotRunning) { + grabber.terminate(); + grabber.waitForFinished(3000); + } + QImage img; + bool res = usePipe ? img.load(&grabber, "ppm") : img.load(tmpfile); + if (!res || img.isNull()) { + if (errMsg) { + QString s("Failed to grab screen. qmlscenegrabber exitcode: %1. Process error: %2. Stderr:%3"); + *errMsg = s.arg(grabber.exitCode()).arg(grabber.errorString()).arg(blockify(grabber.readAllStandardError())); + } + if (!usePipe) + QFile::remove(tmpfile); + return false; + } + if (screenshot) + *screenshot = img; + if (!usePipe) + QFile::remove(tmpfile); + return true; +} + + +quint16 tst_Scenegraph::checksumFileOrDir(const QString &path) +{ + QFileInfo fi(path); + if (!fi.exists() || !fi.isReadable()) + return 0; + if (fi.isFile()) { + QFile f(path); + f.open(QIODevice::ReadOnly); + QByteArray contents = f.readAll(); + return qChecksum(contents); + } + if (fi.isDir()) { + static const QStringList nameFilters = QStringList() << "*.qml" << "*.cpp" << "*.png" << "*.jpg"; + quint16 cs = 0; + const auto entryList = QDir(fi.filePath()).entryList(nameFilters, + QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); + for (const QString &item : entryList) + cs ^= checksumFileOrDir(path + QLatin1Char('/') + item); + return cs; + } + return 0; +} + + +#define main _realmain +QTEST_MAIN(tst_Scenegraph) +#undef main + +int main(int argc, char *argv[]) +{ + QBaselineTest::handleCmdLineArgs(&argc, &argv); + return _realmain(argc, argv); +} + +#include "tst_baseline_scenegraph.moc" diff --git a/tests/benchmarks/CMakeLists.txt b/tests/benchmarks/CMakeLists.txt index 0ce6f79ce1e..481b27d2706 100644 --- a/tests/benchmarks/CMakeLists.txt +++ b/tests/benchmarks/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory(quick) if(QT_FEATURE_private_tests) add_subdirectory(particles) endif() +add_subdirectory(quickcontrols2) diff --git a/tests/benchmarks/qml/qqmlchangeset/CMakeLists.txt b/tests/benchmarks/qml/qqmlchangeset/CMakeLists.txt index 2d6461eefd0..ee61a372afe 100644 --- a/tests/benchmarks/qml/qqmlchangeset/CMakeLists.txt +++ b/tests/benchmarks/qml/qqmlchangeset/CMakeLists.txt @@ -1,10 +1,10 @@ # Generated from qqmlchangeset.pro. ##################################################################### -## tst_qqmlchangeset Binary: +## tst_bench_qqmlchangeset Binary: ##################################################################### -qt_internal_add_benchmark(tst_qqmlchangeset +qt_internal_add_benchmark(tst_bench_qqmlchangeset SOURCES tst_qqmlchangeset.cpp DEFINES diff --git a/tests/benchmarks/quick/events/CMakeLists.txt b/tests/benchmarks/quick/events/CMakeLists.txt index 29ee7bc803f..6e49bdc14ee 100644 --- a/tests/benchmarks/quick/events/CMakeLists.txt +++ b/tests/benchmarks/quick/events/CMakeLists.txt @@ -6,15 +6,7 @@ qt_internal_add_benchmark(tst_qevents SOURCES - ../../../auto/quick/shared/geometrytestutil.cpp ../../../auto/quick/shared/geometrytestutil.h - ../../../auto/quick/shared/viewtestutil.cpp ../../../auto/quick/shared/viewtestutil.h - ../../../auto/quick/shared/visualtestutil.cpp ../../../auto/quick/shared/visualtestutil.h - ../../../auto/shared/util.cpp ../../../auto/shared/util.h tst_events.cpp - DEFINES - QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" - INCLUDE_DIRECTORIES - ../../../auto/shared PUBLIC_LIBRARIES Qt::CorePrivate Qt::Gui @@ -24,6 +16,7 @@ qt_internal_add_benchmark(tst_qevents Qt::Quick Qt::QuickPrivate Qt::Test + Qt::QuickTestUtilsPrivate ) #### Keys ignored in scope 1:.:.:events.pro:<TRUE>: diff --git a/tests/benchmarks/quick/events/tst_events.cpp b/tests/benchmarks/quick/events/tst_events.cpp index 1033dc30b63..df4239a503b 100644 --- a/tests/benchmarks/quick/events/tst_events.cpp +++ b/tests/benchmarks/quick/events/tst_events.cpp @@ -30,9 +30,8 @@ #include <QtQuick> #include <QtQuick/private/qquickmousearea_p.h> #include <QDebug> -#include "../../../auto/shared/util.h" -#include "../../../auto/quick/shared/viewtestutil.h" - +#include <QtQuickTestUtils/private/qmlutils_p.h> +#include <QtQuickTestUtils/private/viewtestutils_p.h> class TestView : public QQuickView { @@ -45,6 +44,9 @@ class tst_events : public QQmlDataTest { Q_OBJECT +public: + tst_events(); + private slots: void mousePressRelease(); void mouseMove(); @@ -64,6 +66,11 @@ public slots: TestView window; }; +tst_events::tst_events() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + void tst_events::mousePressRelease() { QQuickMouseArea *mouseArea = window.rootObject()->findChild<QQuickMouseArea *>("mouseArea"); diff --git a/tests/benchmarks/quickcontrols2/CMakeLists.txt b/tests/benchmarks/quickcontrols2/CMakeLists.txt new file mode 100644 index 00000000000..3f2bf2f96cf --- /dev/null +++ b/tests/benchmarks/quickcontrols2/CMakeLists.txt @@ -0,0 +1,4 @@ +# Generated from benchmarks.pro. + +add_subdirectory(creationtime) +add_subdirectory(objectcount) diff --git a/tests/benchmarks/quickcontrols2/benchmarks.pro b/tests/benchmarks/quickcontrols2/benchmarks.pro new file mode 100644 index 00000000000..7c4ca2243b5 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/benchmarks.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS += \ + creationtime \ + objectcount diff --git a/tests/benchmarks/quickcontrols2/creationtime/CMakeLists.txt b/tests/benchmarks/quickcontrols2/creationtime/CMakeLists.txt new file mode 100644 index 00000000000..ad39b3ea0b6 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/creationtime/CMakeLists.txt @@ -0,0 +1,48 @@ +# Generated from creationtime.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_creationtime LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## tst_creationtime Test: +##################################################################### + +qt_internal_add_test(tst_creationtime + SOURCES + tst_creationtime.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::Qml + Qt::QmlPrivate + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate +) + +#### Keys ignored in scope 1:.:.:creationtime.pro:<TRUE>: +# TEMPLATE = "app" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_creationtime CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_creationtime CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/benchmarks/quickcontrols2/creationtime/creationtime.pro b/tests/benchmarks/quickcontrols2/creationtime/creationtime.pro new file mode 100644 index 00000000000..7d15ebd445c --- /dev/null +++ b/tests/benchmarks/quickcontrols2/creationtime/creationtime.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = tst_creationtime + +QT += qml testlib quickcontrols2 +CONFIG += testcase +macos:CONFIG -= app_bundle + +include(../../../auto/shared/util.pri) + +SOURCES += \ + tst_creationtime.cpp diff --git a/tests/benchmarks/quickcontrols2/creationtime/data/dependencies.qml b/tests/benchmarks/quickcontrols2/creationtime/data/dependencies.qml new file mode 100644 index 00000000000..3b8476177fa --- /dev/null +++ b/tests/benchmarks/quickcontrols2/creationtime/data/dependencies.qml @@ -0,0 +1,8 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Fusion +import QtQuick.Controls.Imagine +import QtQuick.Controls.Material +import QtQuick.Controls.Universal + +Control { } diff --git a/tests/benchmarks/quickcontrols2/creationtime/tst_creationtime.cpp b/tests/benchmarks/quickcontrols2/creationtime/tst_creationtime.cpp new file mode 100644 index 00000000000..d0259e9a01a --- /dev/null +++ b/tests/benchmarks/quickcontrols2/creationtime/tst_creationtime.cpp @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qscopedpointer.h> +#include <QtTest> +#include <QtQml> +#include <QtQuickControls2/qquickstyle.h> + +#include <QtQuickTestUtils/private/viewtestutils_p.h> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> + +using namespace QQuickControlsTestUtils; +using namespace QQuickVisualTestUtils; + +class tst_CreationTime : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void init(); + + void basicStyle(); + void basicStyle_data(); + + void fusion(); + void fusion_data(); + + void imagine(); + void imagine_data(); + + void material(); + void material_data(); + + void universal(); + void universal_data(); + +private: + QQuickStyleHelper styleHelper; +}; + +void tst_CreationTime::initTestCase() +{ + styleHelper.engine.reset(new QQmlEngine); +} + +void tst_CreationTime::init() +{ + styleHelper.engine->clearComponentCache(); +} + +static void doBenchmark(QQuickStyleHelper &styleHelper, const QUrl &url) +{ + const QString tagStr = QString::fromLatin1(QTest::currentDataTag()); + QStringList styleAndFileName = tagStr.split('/'); + QCOMPARE(styleAndFileName.size(), 2); + QString style = styleAndFileName.first(); + style[0] = style.at(0).toUpper(); + styleHelper.updateStyle(style); + + QQmlComponent component(styleHelper.engine.data()); + component.loadUrl(url); + + QObjectList objects; + objects.reserve(4096); + QBENCHMARK { + QObject *object = component.create(); + QVERIFY2(object, qPrintable(component.errorString())); + objects += object; + } + qDeleteAll(objects); +} + +void tst_CreationTime::basicStyle() +{ + QFETCH(QUrl, url); + doBenchmark(styleHelper, url); +} + +void tst_CreationTime::basicStyle_data() +{ + QTest::addColumn<QUrl>("url"); + addTestRowForEachControl(styleHelper.engine.data(), QQC2_IMPORT_PATH, "basic", "QtQuick/Controls/Basic", + QStringList() << "ApplicationWindow"); +} + +void tst_CreationTime::fusion() +{ + QFETCH(QUrl, url); + doBenchmark(styleHelper, url); +} + +void tst_CreationTime::fusion_data() +{ + QTest::addColumn<QUrl>("url"); + addTestRowForEachControl(styleHelper.engine.data(), QQC2_IMPORT_PATH, "fusion", "QtQuick/Controls/Fusion", + QStringList() << "ApplicationWindow" << "ButtonPanel" << "CheckIndicator" + << "RadioIndicator" << "SliderGroove" << "SliderHandle" << "SwitchIndicator"); +} + +void tst_CreationTime::imagine() +{ + QFETCH(QUrl, url); + doBenchmark(styleHelper, url); +} + +void tst_CreationTime::imagine_data() +{ + QTest::addColumn<QUrl>("url"); + addTestRowForEachControl(styleHelper.engine.data(), QQC2_IMPORT_PATH, "imagine", "QtQuick/Controls/Imagine", + QStringList() << "ApplicationWindow"); +} + +void tst_CreationTime::material() +{ + QFETCH(QUrl, url); + doBenchmark(styleHelper, url); +} + +void tst_CreationTime::material_data() +{ + QTest::addColumn<QUrl>("url"); + addTestRowForEachControl(styleHelper.engine.data(), QQC2_IMPORT_PATH, "material", "QtQuick/Controls/Material", + QStringList() << "ApplicationWindow" << "Ripple" << "SliderHandle" << "CheckIndicator" << "RadioIndicator" + << "SwitchIndicator" << "BoxShadow" << "ElevationEffect" << "CursorDelegate"); +} + +void tst_CreationTime::universal() +{ + QFETCH(QUrl, url); + doBenchmark(styleHelper, url); +} + +void tst_CreationTime::universal_data() +{ + QTest::addColumn<QUrl>("url"); + addTestRowForEachControl(styleHelper.engine.data(), QQC2_IMPORT_PATH, "universal", "QtQuick/Controls/Universal", + QStringList() << "ApplicationWindow" << "CheckIndicator" << "RadioIndicator" << "SwitchIndicator"); +} + +QTEST_MAIN(tst_CreationTime) + +#include "tst_creationtime.moc" diff --git a/tests/benchmarks/quickcontrols2/objectcount/CMakeLists.txt b/tests/benchmarks/quickcontrols2/objectcount/CMakeLists.txt new file mode 100644 index 00000000000..e0434a08eb0 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/objectcount/CMakeLists.txt @@ -0,0 +1,55 @@ +# Generated from objectcount.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_objectcount LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## tst_objectcount Test: +##################################################################### + +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + data/*) +list(APPEND test_data ${test_data_glob}) + + +qt_internal_add_test(tst_objectcount + SOURCES + tst_objectcount.cpp + DEFINES + QQC2_IMPORT_PATH=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/quickcontrols2\\\" + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::QmlPrivate + Qt::Quick + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickControlsTestUtilsPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + Qt::QuickTest + Qt::QuickTestUtilsPrivate + Qt::TestPrivate + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:objectcount.pro:<TRUE>: +# TEMPLATE = "app" + +## Scopes: +##################################################################### + +qt_internal_extend_target(tst_objectcount CONDITION ANDROID OR IOS + DEFINES + QT_QMLTEST_DATADIR=\\\":/data\\\" +) + +qt_internal_extend_target(tst_objectcount CONDITION NOT ANDROID AND NOT IOS + DEFINES + QT_QMLTEST_DATADIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/data\\\" +) diff --git a/tests/benchmarks/quickcontrols2/objectcount/data/dependencies.qml b/tests/benchmarks/quickcontrols2/objectcount/data/dependencies.qml new file mode 100644 index 00000000000..3b8476177fa --- /dev/null +++ b/tests/benchmarks/quickcontrols2/objectcount/data/dependencies.qml @@ -0,0 +1,8 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Fusion +import QtQuick.Controls.Imagine +import QtQuick.Controls.Material +import QtQuick.Controls.Universal + +Control { } diff --git a/tests/benchmarks/quickcontrols2/objectcount/objectcount.pro b/tests/benchmarks/quickcontrols2/objectcount/objectcount.pro new file mode 100644 index 00000000000..f2f2879a94d --- /dev/null +++ b/tests/benchmarks/quickcontrols2/objectcount/objectcount.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = tst_objectcount + +QT += quick testlib core-private +CONFIG += testcase +macos:CONFIG -= app_bundle + +include(../../../auto/shared/util.pri) + +SOURCES += \ + tst_objectcount.cpp diff --git a/tests/benchmarks/quickcontrols2/objectcount/tst_objectcount.cpp b/tests/benchmarks/quickcontrols2/objectcount/tst_objectcount.cpp new file mode 100644 index 00000000000..14785a5a955 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/objectcount/tst_objectcount.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest> +#include <QtQuick> +#include <QtCore/private/qhooks_p.h> +#include <iostream> +#include <QtQuickTestUtils/private/visualtestutils_p.h> +#include <QtQuickControlsTestUtils/private/controlstestutils_p.h> + +using namespace QQuickVisualTestUtils; +using namespace QQuickControlsTestUtils; + +static int qt_verbose = qEnvironmentVariableIntValue("VERBOSE") != 0; + +Q_GLOBAL_STATIC(QObjectList, qt_qobjects) + +extern "C" Q_DECL_EXPORT void qt_addQObject(QObject *object) +{ + qt_qobjects->append(object); +} + +extern "C" Q_DECL_EXPORT void qt_removeQObject(QObject *object) +{ + qt_qobjects->removeAll(object); +} + +class tst_ObjectCount : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void cleanup(); + + void qobjects(); + void qobjects_data(); + + void qquickitems(); + void qquickitems_data(); + +private: + QQmlEngine engine; +}; + +void tst_ObjectCount::init() +{ + qtHookData[QHooks::AddQObject] = reinterpret_cast<quintptr>(&qt_addQObject); + qtHookData[QHooks::RemoveQObject] = reinterpret_cast<quintptr>(&qt_removeQObject); + + // warmup + QQmlComponent component(&engine); + component.setData("import QtQuick; import QtQuick.Controls; Item { Button {} }", QUrl()); + delete component.create(); +} + +void tst_ObjectCount::cleanup() +{ + qtHookData[QHooks::AddQObject] = 0; + qtHookData[QHooks::RemoveQObject] = 0; +} + +static void initTestRows(QQmlEngine *engine) +{ + addTestRowForEachControl(engine, QQC2_IMPORT_PATH, "basic", "QtQuick/Controls/Basic"); + addTestRowForEachControl(engine, QQC2_IMPORT_PATH, "fusion", "QtQuick/Controls/Fusion", + QStringList() << "ButtonPanel" << "CheckIndicator" << "RadioIndicator" << "SliderGroove" << "SliderHandle" << "SwitchIndicator"); + addTestRowForEachControl(engine, QQC2_IMPORT_PATH, "imagine", "QtQuick/Controls/Imagine"); + addTestRowForEachControl(engine, QQC2_IMPORT_PATH, "material", "QtQuick/Controls/Material", + QStringList() << "Ripple" << "SliderHandle" << "CheckIndicator" << "RadioIndicator" + << "SwitchIndicator" << "BoxShadow" << "ElevationEffect" << "CursorDelegate"); + addTestRowForEachControl(engine, QQC2_IMPORT_PATH, "universal", "QtQuick/Controls/Universal", + QStringList() << "CheckIndicator" << "RadioIndicator" << "SwitchIndicator"); +} + +template <typename T> +static void doBenchmark(QQmlEngine *engine, const QUrl &url) +{ + QQmlComponent component(engine); + + qt_qobjects->clear(); + + component.loadUrl(url); + QScopedPointer<QObject> object(component.create()); + QVERIFY2(object.data(), qPrintable(component.errorString())); + + QObjectList objects; + for (QObject *object : qAsConst(*qt_qobjects())) { + if (qobject_cast<T *>(object)) + objects += object; + } + + if (qt_verbose) { + for (QObject *object : objects) + qInfo() << "\t" << object; + } + + QTest::setBenchmarkResult(objects.count(), QTest::Events); +} + +void tst_ObjectCount::qobjects() +{ + QFETCH(QUrl, url); + doBenchmark<QObject>(&engine, url); +} + +void tst_ObjectCount::qobjects_data() +{ + QTest::addColumn<QUrl>("url"); + initTestRows(&engine); +} + +void tst_ObjectCount::qquickitems() +{ + QFETCH(QUrl, url); + doBenchmark<QQuickItem>(&engine, url); +} + +void tst_ObjectCount::qquickitems_data() +{ + QTest::addColumn<QUrl>("url"); + initTestRows(&engine); +} + +QTEST_MAIN(tst_ObjectCount) + +#include "tst_objectcount.moc" diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_abstractbutton.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_abstractbutton.qml new file mode 100644 index 00000000000..87b137fb228 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_abstractbutton.qml @@ -0,0 +1,16 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 2000 + delegate: AbstractButton { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + checkable: index % 2 + checked: index % 2 + down: index % 3 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_busyindicator.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_busyindicator.qml new file mode 100644 index 00000000000..bc0be402432 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_busyindicator.qml @@ -0,0 +1,14 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: BusyIndicator { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + running: index % 2 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_button.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_button.qml new file mode 100644 index 00000000000..9505ebf0826 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_button.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: Button { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "Button" + down: index % 2 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_checkbox.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_checkbox.qml new file mode 100644 index 00000000000..67d9e38236f --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_checkbox.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: CheckBox { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "CheckBox" + checked: index % 2 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_checkdelegate.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_checkdelegate.qml new file mode 100644 index 00000000000..bd7b64cc236 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_checkdelegate.qml @@ -0,0 +1,16 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: CheckDelegate { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "CheckDelegate" + checked: index % 2 + down: index % 3 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_combobox.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_combobox.qml new file mode 100644 index 00000000000..f8552b74159 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_combobox.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 250 + delegate: ComboBox { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + model: 5 + currentIndex: index % count + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_container.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_container.qml new file mode 100644 index 00000000000..238e95e3df7 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_container.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 2000 + delegate: Container { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + width: 100 + height: 100 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_control.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_control.qml new file mode 100644 index 00000000000..20f09477ce7 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_control.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 2000 + delegate: Control { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + width: 100 + height: 100 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_delaybutton.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_delaybutton.qml new file mode 100644 index 00000000000..05ec87483e9 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_delaybutton.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: DelayButton { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "DelayButton" + down: index % 2 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_dial.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_dial.qml new file mode 100644 index 00000000000..de742c7b7ec --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_dial.qml @@ -0,0 +1,14 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 500 + delegate: Dial { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + value: index / root.staticCount + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_dialog.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_dialog.qml new file mode 100644 index 00000000000..686149f7b00 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_dialog.qml @@ -0,0 +1,28 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 200 + delegate: Item { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + width: dialog.width + height: dialog.height + Dialog { + id: dialog + visible: true + title: "Dialog" + modal: (index % 100) === 0 + width: parent.width + height: parent.height + standardButtons: Dialog.Ok | Dialog.Cancel + Item { + implicitWidth: 200 + implicitHeight: 200 + } + } + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_dialogbuttonbox.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_dialogbuttonbox.qml new file mode 100644 index 00000000000..f13d65c5071 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_dialogbuttonbox.qml @@ -0,0 +1,14 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: DialogButtonBox { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + standardButtons: DialogButtonBox.Ok | DialogButtonBox.Cancel + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_drawer.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_drawer.qml new file mode 100644 index 00000000000..3f7290a41f8 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_drawer.qml @@ -0,0 +1,21 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 250 + delegate: Item { + width: root.width + height: root.height + Drawer { + id: drawer + visible: true + position: 1.0 + edge: index % 2 ? Qt.LeftEdge : Qt.RightEdge + width: root.width / 3 + height: parent.height + } + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_frame.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_frame.qml new file mode 100644 index 00000000000..2d3c9a66247 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_frame.qml @@ -0,0 +1,17 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 2000 + delegate: Frame { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + Item { + implicitWidth: 100 + implicitHeight: 100 + } + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_groupbox.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_groupbox.qml new file mode 100644 index 00000000000..3696f8476a0 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_groupbox.qml @@ -0,0 +1,18 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: GroupBox { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + title: "GroupBox" + Item { + implicitWidth: 100 + implicitHeight: 100 + } + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_itemdelegate.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_itemdelegate.qml new file mode 100644 index 00000000000..07128da1d2b --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_itemdelegate.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: ItemDelegate { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "ItemDelegate" + down: index % 2 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_label.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_label.qml new file mode 100644 index 00000000000..788006a48df --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_label.qml @@ -0,0 +1,14 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: Label { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "Label" + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_menu.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_menu.qml new file mode 100644 index 00000000000..fd8e53b4f9c --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_menu.qml @@ -0,0 +1,22 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 200 + delegate: Item { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + width: menu.width + height: menu.height + Menu { + id: menu + visible: true + MenuItem { text: "MenuItem1" } + MenuItem { text: "MenuItem2" } + MenuItem { text: "MenuItem3" } + } + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_menuitem.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_menuitem.qml new file mode 100644 index 00000000000..6732bc184c7 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_menuitem.qml @@ -0,0 +1,17 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: MenuItem { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "MenuItem" + checkable: index % 2 + checked: index % 2 + down: index % 3 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_menuseparator.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_menuseparator.qml new file mode 100644 index 00000000000..8effa173054 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_menuseparator.qml @@ -0,0 +1,13 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 2000 + delegate: MenuSeparator { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_page.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_page.qml new file mode 100644 index 00000000000..f9d06b38af8 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_page.qml @@ -0,0 +1,18 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 2000 + delegate: Page { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + width: 100 + height: 100 + header: Item { } + footer: Item { } + Item { } + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_pageindicator.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_pageindicator.qml new file mode 100644 index 00000000000..9b5a691821e --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_pageindicator.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: PageIndicator { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + count: 5 + currentIndex: index % 5 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_pane.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_pane.qml new file mode 100644 index 00000000000..a391f695576 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_pane.qml @@ -0,0 +1,17 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 2000 + delegate: Pane { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + Item { + implicitWidth: 100 + implicitHeight: 100 + } + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_popup.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_popup.qml new file mode 100644 index 00000000000..c2cdaab573d --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_popup.qml @@ -0,0 +1,26 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 500 + delegate: Item { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + width: popup.width + height: popup.height + Popup { + id: popup + visible: true + modal: (index % 100) === 0 + width: parent.width + height: parent.height + Item { + implicitWidth: 100 + implicitHeight: 100 + } + } + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_progressbar.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_progressbar.qml new file mode 100644 index 00000000000..d50d9d2681a --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_progressbar.qml @@ -0,0 +1,14 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: ProgressBar { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + value: index / root.staticCount + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_radiobutton.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_radiobutton.qml new file mode 100644 index 00000000000..f596e852c11 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_radiobutton.qml @@ -0,0 +1,16 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: RadioButton { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "RadioButton" + autoExclusive: false + checked: index % 2 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_radiodelegate.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_radiodelegate.qml new file mode 100644 index 00000000000..7f5734664a0 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_radiodelegate.qml @@ -0,0 +1,17 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: RadioDelegate { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "RadioDelegate" + autoExclusive: false + checked: index % 2 + down: index % 3 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_rangeslider.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_rangeslider.qml new file mode 100644 index 00000000000..725cab29d80 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_rangeslider.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: RangeSlider { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + first.value: (index / root.staticCount) * 0.5 + second.value: 0.5 + (index / root.staticCount) * 0.5 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_roundbutton.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_roundbutton.qml new file mode 100644 index 00000000000..0337a66db8a --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_roundbutton.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: RoundButton { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "X" + down: index % 2 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_scrollbar.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_scrollbar.qml new file mode 100644 index 00000000000..2635240f890 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_scrollbar.qml @@ -0,0 +1,17 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: ScrollBar { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + height: 100 + size: index / root.staticCount + pressed: index % 2 + active: true + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_scrollindicator.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_scrollindicator.qml new file mode 100644 index 00000000000..4e2b90a3b39 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_scrollindicator.qml @@ -0,0 +1,16 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: ScrollIndicator { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + height: 100 + size: index / root.staticCount + active: true + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_scrollview.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_scrollview.qml new file mode 100644 index 00000000000..b5f155cb1df --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_scrollview.qml @@ -0,0 +1,23 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 250 + delegate: ScrollView { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + width: 100 + height: 100 + Item { + implicitWidth: 200 + implicitHeight: 200 + } + ScrollBar.vertical.active: true + ScrollBar.vertical.pressed: index % 3 === 1 + ScrollBar.horizontal.active: true + ScrollBar.horizontal.pressed: index % 3 === 2 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_slider.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_slider.qml new file mode 100644 index 00000000000..0ef3b3faf43 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_slider.qml @@ -0,0 +1,14 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: Slider { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + value: index / root.staticCount + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_spinbox.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_spinbox.qml new file mode 100644 index 00000000000..9120a92162f --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_spinbox.qml @@ -0,0 +1,14 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 250 + delegate: SpinBox { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + value: index / root.staticCount * to + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_stackview.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_stackview.qml new file mode 100644 index 00000000000..cb6cee10fc8 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_stackview.qml @@ -0,0 +1,18 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 2000 + delegate: StackView { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + width: 100 + height: 100 + initialItem: Item { + focus: StackView.status === StackView.Active + } + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_swipedelegate.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_swipedelegate.qml new file mode 100644 index 00000000000..5147bbb6d23 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_swipedelegate.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: SwitchDelegate { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "SwipeDelegate" + down: index % 2 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_swipeview.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_swipeview.qml new file mode 100644 index 00000000000..b263e620a91 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_swipeview.qml @@ -0,0 +1,24 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: SwipeView { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + width: 100 + height: 100 + Item { + focus: SwipeView.isCurrentItem + } + Item { + focus: SwipeView.isCurrentItem + } + Item { + focus: SwipeView.isCurrentItem + } + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_switch.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_switch.qml new file mode 100644 index 00000000000..79cc48e3d05 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_switch.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: Switch { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "Switch" + checked: index % 2 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_switchdelegate.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_switchdelegate.qml new file mode 100644 index 00000000000..f6f8a7df52b --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_switchdelegate.qml @@ -0,0 +1,16 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: SwitchDelegate { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "SwitchDelegate" + checked: index % 2 + down: index % 3 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_tabbar.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_tabbar.qml new file mode 100644 index 00000000000..37f6a463716 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_tabbar.qml @@ -0,0 +1,23 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 250 + delegate: TabBar { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + currentIndex: index / root.staticCount * count + TabButton { + text: "Tab1" + } + TabButton { + text: "Tab2" + } + TabButton { + text: "Tab3" + } + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_tabbutton.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_tabbutton.qml new file mode 100644 index 00000000000..27442a7d2cf --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_tabbutton.qml @@ -0,0 +1,16 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: TabButton { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "TabButton" + checked: index % 2 + down: index % 3 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_textarea.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_textarea.qml new file mode 100644 index 00000000000..88454c0bf1b --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_textarea.qml @@ -0,0 +1,14 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 500 + delegate: TextArea { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "Text\nArea" + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_textfield.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_textfield.qml new file mode 100644 index 00000000000..eb279724e3c --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_textfield.qml @@ -0,0 +1,14 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: TextField { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "TextField" + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_toolbutton.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_toolbutton.qml new file mode 100644 index 00000000000..7dcd85a3fbe --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_toolbutton.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 1000 + delegate: ToolButton { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + text: "ToolButton" + down: index % 2 + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_toolseparator.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_toolseparator.qml new file mode 100644 index 00000000000..48cdd352cc8 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_toolseparator.qml @@ -0,0 +1,13 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 2000 + delegate: ToolSeparator { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_tooltip.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_tooltip.qml new file mode 100644 index 00000000000..85e864943c2 --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_tooltip.qml @@ -0,0 +1,20 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 500 + delegate: Item { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + width: tooltip.width + height: tooltip.height + ToolTip { + id: tooltip + visible: true + text: "ToolTip" + } + } +} diff --git a/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_tumbler.qml b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_tumbler.qml new file mode 100644 index 00000000000..da747e2300b --- /dev/null +++ b/tests/benchmarks/quickcontrols2/qmlbench/creation/delegates_tumbler.qml @@ -0,0 +1,15 @@ +import QtQuick +import QmlBench +import QtQuick.Controls + +CreationBenchmark { + id: root + count: 20 + staticCount: 250 + delegate: Tumbler { + x: QmlBench.getRandom() * root.width - width + y: QmlBench.getRandom() * root.height - height + model: 5 + currentIndex: index % count + } +} diff --git a/tests/global/global.cfg b/tests/global/global.cfg index 3d70bf1d1f2..c604b7dbcbd 100644 --- a/tests/global/global.cfg +++ b/tests/global/global.cfg @@ -4,5 +4,6 @@ <module name="QtQuick" qtname="quick"/> <module name="QtQuickTest" qtname="qmltest"/> <module name="QtQuickWidgets" qtname="quickwidgets"/> +<module name="QtQuickControls2" qtname="quickcontrols2"/> </modules> </config> diff --git a/tests/libfuzzer/qml/jsapi/evaluate/CMakeLists.txt b/tests/libfuzzer/qml/jsapi/evaluate/CMakeLists.txt index ff408aa0428..9d42e6b7495 100644 --- a/tests/libfuzzer/qml/jsapi/evaluate/CMakeLists.txt +++ b/tests/libfuzzer/qml/jsapi/evaluate/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(evaluate LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) diff --git a/tests/libfuzzer/qml/qml/qqmlcomponent/create/CMakeLists.txt b/tests/libfuzzer/qml/qml/qqmlcomponent/create/CMakeLists.txt index 2bd22088f4c..dd79291843b 100644 --- a/tests/libfuzzer/qml/qml/qqmlcomponent/create/CMakeLists.txt +++ b/tests/libfuzzer/qml/qml/qqmlcomponent/create/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(create LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt index 24edc3e70c3..91628f0e511 100644 --- a/tests/manual/CMakeLists.txt +++ b/tests/manual/CMakeLists.txt @@ -7,9 +7,10 @@ add_subdirectory(pointer) # add_subdirectory(qmltypememory) # TODO: C++ API changed # add_subdirectory(quickwidgetviewer) # TODO: C++ API changed add_subdirectory(scalablepath) -add_subdirectory(scenegraph_lancelot) add_subdirectory(shapestest) add_subdirectory(tableview) add_subdirectory(text) add_subdirectory(touch) # add_subdirectory(v4) # TODO: port if needed +add_subdirectory(quickcontrols2) +add_subdirectory(quickdialogs) diff --git a/tests/manual/pointer/CMakeLists.txt b/tests/manual/pointer/CMakeLists.txt deleted file mode 100644 index aa8e15306b6..00000000000 --- a/tests/manual/pointer/CMakeLists.txt +++ /dev/null @@ -1,110 +0,0 @@ -# Generated from pointer.pro. - -##################################################################### -## pointer Binary: -##################################################################### - -# special case begin -if(NOT TARGET Qt::Svg OR NOT TARGET Qt::Quick OR NOT TARGET Qt::Qml) - return() -endif() -# special case end - -qt_internal_add_manual_test(pointer - GUI - SOURCES - inputinspector.cpp inputinspector.h - main.cpp - PUBLIC_LIBRARIES - Qt::Gui - Qt::Qml - Qt::Quick - Qt::QuickPrivate - Qt::Svg -) - -# Resources: -set(qml_resource_files - "content/CheckBox.qml" - "content/FakeFlickable.qml" - "content/FlashAnimation.qml" - "content/MomentumAnimation.qml" - "content/MouseAreaButton.qml" - "content/MouseAreaSlider.qml" - "content/MouseFeedbackSprite.qml" - "content/MptaButton.qml" - "content/MultiButton.qml" - "content/ScrollBar.qml" - "content/Slider.qml" - "content/TapHandlerButton.qml" - "content/TextBox.qml" - "content/TouchpointFeedbackSprite.qml" - "fakeFlickable.qml" - "flickablesWithHandlers.qml" - "flingAnimation.qml" - "joystick.qml" - "main.qml" - "map.qml" - "map2.qml" - "mixer.qml" - "multibuttons.qml" - "photosurface.qml" - "pinchHandler.qml" - "pointerDrag.qml" - "resources/arrowhead.png" - "resources/balloon.png" - "resources/cursor-airbrush.png" - "resources/cursor-eraser.png" - "resources/cursor-felt-marker.png" - "resources/cursor-pencil.png" - "resources/fighter.png" - "resources/fingersprite.png" - "resources/grabbing-location.svg" - "resources/joystick-outer-case-pov.jpg" - "resources/map.svgz" - "resources/missile.png" - "resources/mixer-knob.png" - "resources/mouse.png" - "resources/mouse_left.png" - "resources/mouse_middle.png" - "resources/mouse_right.png" - "resources/redball.png" - "sidebar.qml" - "singlePointHandlerProperties.qml" - "tabletCanvasDrawing.qml" - "tapHandler.qml" -) - -qt_internal_add_resource(pointer "qml" - PREFIX - "/" - FILES - ${qml_resource_files} -) -set(quick_shared_resource_files - "../../../examples/quick/shared/Button.qml" - "../../../examples/quick/shared/CheckBox.qml" - "../../../examples/quick/shared/Label.qml" - "../../../examples/quick/shared/LauncherList.qml" - "../../../examples/quick/shared/SimpleLauncherDelegate.qml" - "../../../examples/quick/shared/Slider.qml" - "../../../examples/quick/shared/TextField.qml" - "../../../examples/quick/shared/images/back.png" - "../../../examples/quick/shared/images/checkmark.png" - "../../../examples/quick/shared/images/next.png" - "../../../examples/quick/shared/images/slider_handle.png" -) - -qt_internal_add_resource(pointer "quick_shared" - PREFIX - "/quick/shared" - BASE - "../../../examples/quick/shared" - FILES - ${quick_shared_resource_files} -) - -qt_import_qml_plugins(pointer) # special case - -#### Keys ignored in scope 1:.:.:pointer.pro:<TRUE>: -# TEMPLATE = "app" diff --git a/tests/manual/pointer/content/FakeFlickable.qml b/tests/manual/pointer/content/FakeFlickable.qml deleted file mode 100644 index 636399ba2c3..00000000000 --- a/tests/manual/pointer/content/FakeFlickable.qml +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick 2.14 -import Qt.labs.animation 1.0 - -Item { - id: root - objectName: "viewport" - default property alias data: __contentItem.data - property alias velocity: anim.velocity - property alias contentX: __contentItem.x // sign is reversed compared to Flickable.contentX - property alias contentY: __contentItem.y // sign is reversed compared to Flickable.contentY - property alias contentWidth: __contentItem.width - property alias contentHeight: __contentItem.height - signal flickStarted - signal flickEnded - - Item { - id: __contentItem - objectName: "__contentItem" - width: childrenRect.width - height: childrenRect.height - - BoundaryRule on x { - id: xbr - minimum: root.width - __contentItem.width - maximum: 0 - minimumOvershoot: 100 - maximumOvershoot: 100 - overshootFilter: BoundaryRule.Peak - } - - BoundaryRule on y { - id: ybr - minimum: root.height - __contentItem.height - maximum: 0 - minimumOvershoot: 100 - maximumOvershoot: 100 - overshootFilter: BoundaryRule.Peak - } - - DragHandler { - id: dragHandler - onActiveChanged: - if (active) { - anim.stop() - root.flickStarted() - } else { - var vel = centroid.velocity - if (xbr.returnToBounds()) - vel.x = 0 - if (ybr.returnToBounds()) - vel.y = 0 - if (vel.x !== 0 || vel.y !== 0) - anim.restart(vel) - else - root.flickEnded() - } - } - WheelHandler { - rotationScale: 15 - property: "x" - orientation: Qt.Horizontal - acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad - onActiveChanged: - // emitting signals in both instances is redundant but hard to avoid - // when the touchpad is flicking along both axes - if (active) { - anim.stop() - root.flickStarted() - } else { - xbr.returnToBounds() - root.flickEnded() - } - } - WheelHandler { - rotationScale: 15 - property: "y" - orientation: Qt.Vertical - acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad - onActiveChanged: - if (active) { - anim.stop() - root.flickStarted() - } else { - ybr.returnToBounds() - root.flickEnded() - } - } - MomentumAnimation { - id: anim - target: __contentItem - onStarted: root.flickStarted() - onStopped: { - xbr.returnToBounds() - ybr.returnToBounds() - root.flickEnded() - } - } - } -} diff --git a/tests/manual/pointer/content/LeftDrawer.qml b/tests/manual/pointer/content/LeftDrawer.qml deleted file mode 100644 index 6e93fd4933b..00000000000 --- a/tests/manual/pointer/content/LeftDrawer.qml +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ -import QtQuick 2.14 -import Qt.labs.animation 1.0 -import QtGraphicalEffects 1.14 - -Item { - id: root - objectName: "LeftHandlerDrawer" - width: 100 - height: 400 - property real stickout: 4 - property real xOpen: rect.radius * -2 - property real xClosed: stickout - width - x: xClosed - y: 10 - - function close() { - openCloseAnimation.to = xClosed - openCloseAnimation.start() - } - function open() { - openCloseAnimation.to = xOpen - openCloseAnimation.start() - } - - DragHandler { - id: dragHandler - yAxis.enabled: false - xAxis.minimum: -1000 - margin: 20 - onActiveChanged: - if (!active) { - if (xbr.returnToBounds()) - return; - if (activeTranslation.x > 0) - open() - if (activeTranslation.x < 0) - close() - } - } - - BoundaryRule on x { - id: xbr - minimum: xClosed - maximum: xOpen - minimumOvershoot: rect.radius - maximumOvershoot: rect.radius - } - - NumberAnimation on x { - id: openCloseAnimation - duration: 300 - easing { type: Easing.OutBounce; overshoot: 5 } - } - - RectangularGlow { - id: effect - anchors.fill: parent - glowRadius: dragHandler.margin - spread: 0.2 - color: "cyan" - cornerRadius: rect.radius + glowRadius - } - - Rectangle { - id: rect - anchors.fill: parent - anchors.margins: 3 - color: "#333" - border.color: "cyan" - border.width: 2 - radius: 10 - antialiasing: true - } -} diff --git a/tests/manual/pointer/content/MultiButton.qml b/tests/manual/pointer/content/MultiButton.qml deleted file mode 100644 index 485784a8759..00000000000 --- a/tests/manual/pointer/content/MultiButton.qml +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick 2.12 - -Rectangle { - id: root - property alias label: label.text - property alias pressed: tap.pressed - property bool checked: false - property alias gesturePolicy: tap.gesturePolicy - property alias margin: tap.margin - signal tapped - - width: label.implicitWidth * 1.5; height: label.implicitHeight * 2.0 - border.color: "#9f9d9a"; border.width: 1; radius: height / 4; antialiasing: true - - gradient: Gradient { - GradientStop { position: 0.0; color: tap.pressed ? "#b8b5b2" : "#efebe7" } - GradientStop { position: 1.0; color: "#b8b5b2" } - } - - TapHandler { - id: tap - objectName: label.text - onTapped: { - tapFlash.start() - root.tapped() - } - } - - Text { - id: label - font.pointSize: 14 - text: "Button" - anchors.centerIn: parent - } - - Rectangle { - anchors.fill: parent - color: "transparent" - border.width: 2; radius: root.radius; antialiasing: true - opacity: tapFlash.running ? 1 : 0 - FlashAnimation on visible { - id: tapFlash - } - } -} diff --git a/tests/manual/pointer/content/ScrollBar.qml b/tests/manual/pointer/content/ScrollBar.qml deleted file mode 100644 index 9928433d1f9..00000000000 --- a/tests/manual/pointer/content/ScrollBar.qml +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick 2.12 - -Rectangle { - id: root - property real contentHeight: 100 - property FakeFlickable flick: null - property real position - - onPositionChanged: if (flick && (drag.active || tap.active)) { - if (knob.state === "horizontal") - flick.contentX = position * knob.scrollDistance - else if (knob.state === "vertical") - flick.contentY = position * knob.scrollDistance - } - - SystemPalette { id: palette } - - color: palette.button - border.color: Qt.darker(palette.button, 1.5) - gradient: Gradient { - GradientStop { position: 0; color: Qt.darker(palette.button, 1.3) } - GradientStop { position: 1; color: palette.button } - } - antialiasing: true - radius: Math.min(width, height) / 6 - width: 20 - height: 20 - - TapHandler { - id: tap - onTapped: { - if (knob.state === "horizontal") - knob.x = position.x - knob.width / 2 - else if (knob.state === "vertical") - knob.y = position.y - knob.height / 2 - } - } - - Rectangle { - id: knob - border.color: "black" - border.width: 1 - gradient: Gradient { - GradientStop { position: 0; color: palette.button } - GradientStop { position: 1; color: Qt.darker(palette.button, 1.3) } - } - radius: 2 - antialiasing: true - state: root.height > root.width ? "vertical" : root.height < root.width ? "horizontal" : "" - property real scrollDistance: 0 - property real scrolledX: 0 - property real scrolledY: 0 - property real max: 0 - - Binding on x { - value: knob.scrolledX - when: !drag.active - } - - Binding on y { - value: knob.scrolledY - when: !drag.active - } - - states: [ - // We will control the horizontal. We will control the vertical. - State { - name: "horizontal" - PropertyChanges { - target: knob - max: root.width - knob.width - scrolledX: Math.min(max, Math.max(0, max * flick.contentX / (flick.width - flick.contentWidth))) - scrolledY: 1 - scrollDistance: flick.width - flick.contentWidth - width: flick.width * (flick.width / flick.contentWidth) - (height - anchors.margins) * 2 - height: root.height - 2 - } - PropertyChanges { - target: drag - xAxis.minimum: 0 - xAxis.maximum: knob.max - yAxis.minimum: 1 - yAxis.maximum: 1 - } - PropertyChanges { - target: root - position: knob.x / drag.xAxis.maximum - } - }, - State { - name: "vertical" - PropertyChanges { - target: knob - max: root.height - knob.height - scrolledX: 1 - scrolledY: Math.min(max, Math.max(0, max * flick.contentY / (flick.height - flick.contentHeight))) - scrollDistance: flick.height - flick.contentHeight - width: root.width - 2 - height: root.width - 2 - } - PropertyChanges { - target: drag - xAxis.minimum: 1 - xAxis.maximum: 1 - yAxis.minimum: 0 - yAxis.maximum: knob.max - } - PropertyChanges { - target: root - position: knob.y / drag.yAxis.maximum - } - } - ] - - DragHandler { - id: drag - } - } -} diff --git a/tests/manual/pointer/fakeFlickable.qml b/tests/manual/pointer/fakeFlickable.qml deleted file mode 100644 index be52e4dbaa3..00000000000 --- a/tests/manual/pointer/fakeFlickable.qml +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick 2.12 -import "content" - -Rectangle { - id: root - color: "#444" - width: 480 - height: 640 - - FakeFlickable { - id: ff - anchors.fill: parent - anchors.leftMargin: 20 - anchors.rightMargin: rightSB.width - - Text { - id: text - color: "beige" - font.family: "mono" - font.pointSize: slider.value - onTextChanged: console.log("text geom " + width + "x" + height + - ", parent " + parent + " geom " + parent.width + "x" + parent.height) - } - - onFlickStarted: { - root.border.color = "green" - console.log("flick started with velocity " + velocity) - } - onFlickEnded: { - root.border.color = "transparent" - console.log("flick ended with velocity " + velocity) - } - - Component.onCompleted: { - var request = new XMLHttpRequest() - request.open('GET', 'content/FakeFlickable.qml') - request.onreadystatechange = function(event) { - if (request.readyState === XMLHttpRequest.DONE) - text.text = request.responseText - } - request.send() - } - } - - ScrollBar { - id: rightSB - objectName: "rightSB" - flick: ff - height: parent.height - width - anchors.right: parent.right - } - - ScrollBar { - id: bottomSB - objectName: "bottomSB" - flick: ff - width: parent.width - height - anchors.bottom: parent.bottom - } - - Rectangle { - id: cornerCover - color: "lightgray" - width: rightSB.width - height: bottomSB.height - anchors { - right: parent.right - bottom: parent.bottom - } - } - - LeftDrawer { - width: 100 - anchors.verticalCenter: parent.verticalCenter - Slider { - id: slider - label: "font\nsize" - anchors.fill: parent - anchors.margins: 10 - maximumValue: 36 - value: 14 - } - } -} diff --git a/tests/manual/pointer/flickablesWithHandlers.qml b/tests/manual/pointer/flickablesWithHandlers.qml index 3a854b2d144..a94af1c329e 100644 --- a/tests/manual/pointer/flickablesWithHandlers.qml +++ b/tests/manual/pointer/flickablesWithHandlers.qml @@ -27,7 +27,6 @@ ****************************************************************************/ import QtQuick -import "qrc:/quick/shared/" as Examples import "content" Rectangle { @@ -59,10 +58,10 @@ Rectangle { height: pressDelayCB.implicitHeight + 12 x: 6 color: "lightgray" - Examples.CheckBox { + CheckBox { x: 6; y: 6 id: pressDelayCB - text: "press delay" + label: "press delay" } } diff --git a/tests/manual/pointer/flingAnimation.qml b/tests/manual/pointer/flingAnimation.qml deleted file mode 100644 index 4ec84789cdc..00000000000 --- a/tests/manual/pointer/flingAnimation.qml +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick 2.12 -import "content" - -Rectangle { - id: root - width: 640 - height: 480 - color: "black" - - Repeater { - model: 2 - - Image { - id: ball - objectName: "ball" + index - source: "resources/redball.png" - property real homeX: 200 + index * 200 - property real homeY: 200 - width: 80; height: 80; x: homeX; y: 200 - - Text { - anchors.centerIn: parent - color: "white" - text: momentum.velocity.x.toFixed(2) + "," + momentum.velocity.y.toFixed(2) - } - - SequentialAnimation { - id: anim - - function restart(vel) { - stop() - momentum.velocity = vel - start() - } - - MomentumAnimation { id: momentum; target: ball } - - PauseAnimation { duration: 500 } - - ParallelAnimation { - id: ballReturn - NumberAnimation { - target: ball - property: "x" - to: homeX - duration: 1000 - easing.period: 50 - easing.type: Easing.OutElastic - } - NumberAnimation { - target: ball - property: "y" - to: homeY - duration: 1000 - easing.type: Easing.OutElastic - } - } - } - - DragHandler { - id: dragHandler - objectName: "dragHandler" + index - onActiveChanged: { - if (!active) - anim.restart(centroid.velocity) - } - } - Rectangle { - visible: dragHandler.active - anchors.fill: parent - anchors.margins: -5 - radius: width / 2 - opacity: 0.25 - } - - Rectangle { - visible: width > 0 - width: dragHandler.centroid.velocity.length() / 10 - height: 2 - x: ball.width / 2 - y: ball.height / 2 - z: -1 - rotation: Math.atan2(dragHandler.centroid.velocity.y, dragHandler.centroid.velocity.x) * 180 / Math.PI - transformOrigin: Item.BottomLeft - antialiasing: true - - Image { - source: "resources/arrowhead.png" - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - width: 16 - height: 12 - antialiasing: true - } - } - } - } -} diff --git a/tests/manual/pointer/inputinspector.cpp b/tests/manual/pointer/inputinspector.cpp deleted file mode 100644 index ee1b4e70c00..00000000000 --- a/tests/manual/pointer/inputinspector.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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 "inputinspector.h" -#include <QtQuick/QQuickItem> -#include <QtQuick/private/qquickpointerhandler_p.h> -#include <QtGui/private/qpointingdevice_p.h> -#include <QtCore/QSet> - -static const int timerInterval = 100; - -InputInspector::InputInspector(QObject *parent) : QObject(parent) -{ -} - -InputInspector::~InputInspector() -{ - m_window = nullptr; - killTimer(m_timerId); -} - -QString InputInspector::mouseGrabber() const -{ - QString name; - if (m_window) { - if (QQuickItem *grabber = m_window->mouseGrabberItem()) { - name = objectIdentifier(grabber); - } else { - name = QLatin1String("no grabber"); - } - } else { - name = "ERROR: need a source window"; - } - return name; -} - -QString InputInspector::passiveGrabbers() const -{ - return vectorStringJoin(passiveGrabbers_helper()); -} - -QString InputInspector::exclusiveGrabbers() const -{ - return vectorStringJoin(exclusiveGrabbers_helper()); -} - -QString InputInspector::vectorStringJoin(const QVector<QObject*> &arr) const -{ - QString res; - for (QObject* obj: arr) { - if (!res.isEmpty()) - res += QLatin1String(" , "); - res += objectIdentifier(obj); - } - res.prepend(QLatin1String("[")); - res += QLatin1String("]"); - return res; -} - -QQuickWindow *InputInspector::source() const -{ - return m_window; -} - -void InputInspector::setSource(QQuickWindow *window) -{ - m_window = window; - if (m_window && !m_timerId) - m_timerId = startTimer(timerInterval); - emit sourceChanged(); -} - -void InputInspector::update() -{ - const QString mouseGrabberName = mouseGrabber(); - if (lastState.mouseGrabber != mouseGrabberName) { - emit mouseGrabberChanged(); - lastState.mouseGrabber = mouseGrabberName; - } - - const QString tempPassiveGrabbers = passiveGrabbers(); - if (lastState.passiveGrabbers != tempPassiveGrabbers) { - emit passiveGrabbersChanged(); - lastState.passiveGrabbers = tempPassiveGrabbers; - } - - const QString tempExclusiveGrabbers = exclusiveGrabbers(); - if (lastState.exclusiveGrabbers != tempExclusiveGrabbers) { - emit exclusiveGrabbersChanged(); - lastState.exclusiveGrabbers = tempExclusiveGrabbers; - } -} - -void InputInspector::timerEvent(QTimerEvent *event) -{ - if (event->timerId() == m_timerId) - update(); -} - -const QPointingDevice *InputInspector::pointerDevice() const -{ - const QPointingDevice *device = nullptr; - for (const auto dev : QInputDevice::devices()) { - if (dev->type() == QInputDevice::DeviceType::TouchScreen) { - device = static_cast<const QPointingDevice *>(dev); - break; - } - } - if (!device) - device = QPointingDevice::primaryPointingDevice(); - return device; -} - -QVector<QObject*> InputInspector::passiveGrabbers_helper(int pointId /*= 0*/) const -{ - QVector<QObject*> result; - const QPointingDevice *device = pointerDevice(); - if (device && source()) { - for (auto &epd : QPointingDevicePrivate::get(device)->activePoints.values()) { - if (!pointId || epd.eventPoint.id() == pointId) { - for (auto pg : epd.passiveGrabbers) { - if (!result.contains(pg)) - result << pg; - } - } - } - } - return result; -} - -QVector<QObject*> InputInspector::exclusiveGrabbers_helper(int pointId /*= 0*/) const -{ - QVector<QObject*> result; - const QPointingDevice *device = pointerDevice(); - if (device && source()) { - for (auto &epd : QPointingDevicePrivate::get(device)->activePoints.values()) { - if (!pointId || epd.eventPoint.id() == pointId) { - if (auto g = epd.exclusiveGrabber.data()) { - if (!result.contains(g)) - result << g; - } - } - } - } - return result; -} - -QString InputInspector::objectIdentifier(QObject *o) -{ - QString name; - name = o->objectName(); - if (name.isEmpty()) - name = o->property("text").toString(); - if (name.isEmpty()) - name = o->metaObject()->className(); - if (name.isEmpty()) - name = QLatin1String("unknown"); - - return name; -} diff --git a/tests/manual/pointer/inputinspector.h b/tests/manual/pointer/inputinspector.h deleted file mode 100644 index 31d99cf25d8..00000000000 --- a/tests/manual/pointer/inputinspector.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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 INPUTINSPECTOR_H -#define INPUTINSPECTOR_H - -#include <QObject> -#include <QtQuick/QQuickWindow> -class QQuickPointerHandler; -class QPointingDevice; - -class InputInspector : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString mouseGrabber READ mouseGrabber NOTIFY mouseGrabberChanged) - Q_PROPERTY(QString passiveGrabbers READ passiveGrabbers NOTIFY passiveGrabbersChanged) - Q_PROPERTY(QString exclusiveGrabbers READ exclusiveGrabbers NOTIFY exclusiveGrabbersChanged) - Q_PROPERTY(QQuickWindow * source READ source WRITE setSource NOTIFY sourceChanged) -public: - explicit InputInspector(QObject *parent = nullptr); - ~InputInspector(); - QString mouseGrabber() const; - QString passiveGrabbers() const; - QString exclusiveGrabbers() const; - QQuickWindow *source() const; - void setSource(QQuickWindow *window); - - void timerEvent(QTimerEvent *event); - Q_INVOKABLE void update(); - -signals: - void mouseGrabberChanged(); - void passiveGrabbersChanged(); - void exclusiveGrabbersChanged(); - void sourceChanged(); -private: - QVector<QObject*> passiveGrabbers_helper(int pointId = 0) const; - QVector<QObject*> exclusiveGrabbers_helper(int pointId = 0) const; - static QString objectIdentifier(QObject *o); - const QPointingDevice *pointerDevice() const; - QString vectorStringJoin(const QVector<QObject*> &arr) const; - -private: - mutable struct LastState { - QString mouseGrabber; - QString passiveGrabbers; - QString exclusiveGrabbers; - } lastState; - - QQuickWindow *m_window = nullptr; - int m_timerId = 0; -}; - -#endif // INPUTINSPECTOR_H diff --git a/tests/manual/pointer/joystick.qml b/tests/manual/pointer/joystick.qml deleted file mode 100644 index c8880f91008..00000000000 --- a/tests/manual/pointer/joystick.qml +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick 2.12 - -Item { - width: image.implicitWidth; height: image.implicitHeight - Image { - id: image - anchors.centerIn: parent - source: "resources/joystick-outer-case-pov.jpg" - property real margin: 50 - - Image { - id: knob - source: "resources/redball.png" - DragHandler { - id: dragHandler - xAxis { - minimum: image.margin - maximum: image.width - image.margin - knob.width - } - yAxis { - minimum: image.margin - maximum: image.height - image.margin - knob.height - } - } - - anchors { - horizontalCenter: parent.horizontalCenter - verticalCenter: parent.verticalCenter - } - states: [ - State { - when: dragHandler.active - AnchorChanges { - target: knob - anchors.horizontalCenter: undefined - anchors.verticalCenter: undefined - } - } - ] - transitions: [ - Transition { - AnchorAnimation { easing.type: Easing.OutElastic } - } - ] - } - } -} diff --git a/tests/manual/pointer/main.cpp b/tests/manual/pointer/main.cpp deleted file mode 100644 index 87a38382c1b..00000000000 --- a/tests/manual/pointer/main.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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 <QGuiApplication> -#include <QQmlApplicationEngine> -#include <QQuickItem> -#include <QQuickWindow> -#include "inputinspector.h" - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - qmlRegisterType<InputInspector>("org.qtproject.Test", 1, 0, "InputInspector"); - - QQmlApplicationEngine engine; - engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); - if (engine.rootObjects().isEmpty()) - return -1; - if (!app.arguments().isEmpty()) { - QQuickWindow * win = static_cast<QQuickWindow *>(engine.rootObjects().first()); - auto lastArg = app.arguments().last(); - if (lastArg.endsWith(QLatin1String(".qml"))) { - auto root = win->findChild<QQuickItem *>("LauncherList"); - int showExampleIdx = -1; - for (int i = root->metaObject()->methodCount(); showExampleIdx < 0 && i >= 0; --i) - if (root->metaObject()->method(i).name() == QByteArray("showExample")) - showExampleIdx = i; - QMetaMethod showExampleFn = root->metaObject()->method(showExampleIdx); - showExampleFn.invoke(root, Q_ARG(QVariant, QVariant(QLatin1String("../../") + lastArg))); - } - } - - return app.exec(); -} diff --git a/tests/manual/pointer/main.qml b/tests/manual/pointer/main.qml deleted file mode 100644 index c7c1380c643..00000000000 --- a/tests/manual/pointer/main.qml +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick 2.12 -import QtQuick.Window 2.12 -import QtQuick.Layouts 1.2 -import org.qtproject.Test 1.0 -import "qrc:/quick/shared/" as Examples -import "content" - -Window { - id: window - width: 800 - height: 600 - visible: true - Examples.LauncherList { - id: ll - objectName: "LauncherList" - anchors.fill: parent - Component.onCompleted: { - addExample("single point handler", "QQuickPointerSingleHandler: test properties copied from events", Qt.resolvedUrl("singlePointHandlerProperties.qml")) - addExample("hover", "ensure that a hierarchy of items can share the hover state", Qt.resolvedUrl("sidebar.qml")) - addExample("joystick", "DragHandler: move one item inside another with any pointing device", Qt.resolvedUrl("joystick.qml")) - addExample("mixer", "mixing console", Qt.resolvedUrl("mixer.qml")) - addExample("pinch", "PinchHandler: scale, rotate and drag", Qt.resolvedUrl("pinchHandler.qml")) - addExample("map", "scale and pan", Qt.resolvedUrl("map.qml")) - addExample("custom map", "scale and pan", Qt.resolvedUrl("map2.qml")) - addExample("fling animation", "DragHandler: after dragging, use an animation to simulate momentum", Qt.resolvedUrl("flingAnimation.qml")) - addExample("fake Flickable", "implementation of a simplified Flickable using only Items, DragHandler and MomentumAnimation", Qt.resolvedUrl("fakeFlickable.qml")) - addExample("photo surface", "re-implementation of the existing photo surface demo using Handlers", Qt.resolvedUrl("photosurface.qml")) - addExample("tap", "TapHandler: device-agnostic tap/click detection for buttons", Qt.resolvedUrl("tapHandler.qml")) - addExample("multibuttons", "TapHandler: gesturePolicy (99 red balloons)", Qt.resolvedUrl("multibuttons.qml")) - addExample("flickables with Handlers", "Parallel Flickables with buttons, sliders etc. implemented in various ways", Qt.resolvedUrl("flickablesWithHandlers.qml")) - addExample("tap and drag", "Flickable with all possible combinations of TapHandler and DragHandler children", Qt.resolvedUrl("pointerDrag.qml")) - addExample("tablet canvas", "PointHandler and HoverHandler with a tablet: detect the stylus, and draw", Qt.resolvedUrl("tabletCanvasDrawing.qml")) - } - } - Item { - id: glassPane - objectName: "glassPane" - z: 10000 - anchors.fill: parent - - // TODO use Instantiator to create these... but we need to be able to set their parents to glassPane somehow (QTBUG-64546) - TouchpointFeedbackSprite { } - TouchpointFeedbackSprite { } - TouchpointFeedbackSprite { } - TouchpointFeedbackSprite { } - TouchpointFeedbackSprite { } - TouchpointFeedbackSprite { } - - MouseFeedbackSprite { } - - InputInspector { - id: inspector - source: window - } - - Rectangle { - anchors.bottom: parent.bottom - anchors.right: parent.right - anchors.margins: 4 - radius: 5 - width: Math.max(grid.implicitWidth, 400) - implicitHeight: grid.implicitHeight - color: "#40404080" - GridLayout { - id: grid - width: parent.width - columns: 3 - Text { text: "mouseGrabber" } Text { text: inspector.mouseGrabber } Item { Layout.fillWidth: true } - Text { text: "passiveGrabbers" } Text { text: inspector.passiveGrabbers } Item { Layout.fillWidth: true } - Text { text: "exclusiveGrabbers" } Text { text: inspector.exclusiveGrabbers } Item { Layout.fillWidth: true } - } - } - } -} diff --git a/tests/manual/pointer/map.qml b/tests/manual/pointer/map.qml deleted file mode 100644 index a45443f562c..00000000000 --- a/tests/manual/pointer/map.qml +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick - -Item { - width: 640 - height: 480 - - Rectangle { - id: map - color: "aqua" - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 - width: image.width - height: image.height - transform: Rotation { - id: tilt - origin.x: width / 2 - origin.y: height / 2 - axis { x: 1; y: 0; z: 0 } - angle: tiltHandler.persistentTranslation.y / -2 - } - - WheelHandler { - id: wheelHandler - objectName: "vertical mouse wheel for scaling" - property: "scale" - onWheel: console.log("rotation " + event.angleDelta + " scaled " + rotation + " @ " + point.position + " => " + map.scale) - } - - WheelHandler { - id: horizontalWheelHandler - objectName: "horizontal mouse wheel for side-scrolling" - property: "x" - orientation: Qt.Horizontal - } - - Image { - id: image - anchors.centerIn: parent - fillMode: Image.PreserveAspectFit - source: "resources/map.svgz" - Component.onCompleted: { width = implicitWidth; height = implicitHeight } - } - - Text { - anchors.centerIn: parent - text: image.sourceSize.width + " x " + image.sourceSize.height + - " scale " + map.scale.toFixed(2) + " active scale " + pinch.activeScale.toFixed(2) - } - } - - DragHandler { - objectName: "single-point drag" - target: map - } - - DragHandler { - id: tiltHandler - objectName: "two-point tilt" - minimumPointCount: 2 - maximumPointCount: 2 - xAxis.enabled: false - target: null - } - - PinchHandler { - id: pinch - objectName: "two-point pinch" - target: map - minimumScale: 0.1 - maximumScale: 10 - xAxis.enabled: false - yAxis.enabled: false - onActiveChanged: if (!active) reRenderIfNecessary() - grabPermissions: PinchHandler.TakeOverForbidden // don't allow takeover if pinch has started - } - - function reRenderIfNecessary() { - var newSourceWidth = image.sourceSize.width * pinch.scale - var ratio = newSourceWidth / image.sourceSize.width - if (ratio > 1.1 || ratio < 0.9) - image.sourceSize.width = newSourceWidth - } -} diff --git a/tests/manual/pointer/mixer.qml b/tests/manual/pointer/mixer.qml deleted file mode 100644 index 6044b596332..00000000000 --- a/tests/manual/pointer/mixer.qml +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick 2.12 -import "content" - -Rectangle { - id: root - width: 1280 - height: 960 - objectName: "root" - color: "#222222" - - ListView { - id: list - objectName: "listView" - anchors.fill: parent - anchors.margins: 10 - orientation: Qt.Horizontal - - model: 20 - - delegate: Item { - objectName: "delegateItem" + index - width: 154 - height: list.height - - Slider { - anchors.fill: parent - label: "Channel " + (index + 1) - } - } - } -} diff --git a/tests/manual/pointer/multibuttons.qml b/tests/manual/pointer/multibuttons.qml deleted file mode 100644 index d143134a3a0..00000000000 --- a/tests/manual/pointer/multibuttons.qml +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick 2.12 -import QtQuick.Particles 2.0 -import QtQuick.Layouts 1.0 -import "content" - -Item { - width: 800 - height: 800 - ColumnLayout { - anchors.right: parent.right - spacing: 20 - Text { text: "protagonist"; font.pointSize: 12 } - MultiButton { - id: balloonsButton - label: "Launch Balloons" - Layout.fillWidth: true - gesturePolicy: TapHandler.WithinBounds - margin: 10 - } - Text { text: "the goons"; font.pointSize: 12 } - MultiButton { - id: missilesButton - label: "Launch Missile" - Layout.fillWidth: true - gesturePolicy: TapHandler.ReleaseWithinBounds - margin: 10 - onTapped: missileEmitter.burst(1) - } - MultiButton { - id: fightersButton - label: "Launch Fighters" - Layout.fillWidth: true - gesturePolicy: TapHandler.DragThreshold - margin: 10 - } - } - ParticleSystem { - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.leftMargin: 150 - ImageParticle { source: "resources/balloon.png" } - Emitter { anchors.bottom: parent.bottom; enabled: balloonsButton.pressed; lifeSpan: 5000; size: 64 - maximumEmitted: 99 - emitRate: 50; velocity: PointDirection { x: 10; y: -150; yVariation: 30; xVariation: 50 } } } - ParticleSystem { - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - ImageParticle { source: "resources/fighter.png" } - Emitter { anchors.bottom: parent.bottom; enabled: fightersButton.pressed; lifeSpan: 15000; size: 204 - emitRate: 3; velocity: PointDirection { x: -1000; y: -250; yVariation: 150; xVariation: 50 } } } - ParticleSystem { - anchors.bottom: parent.bottom - anchors.right: parent.right - anchors.rightMargin: 100 - ImageParticle { source: "resources/missile.png"; autoRotation: true; rotation: 90 } - Emitter { id: missileEmitter; anchors.bottom: parent.bottom; lifeSpan: 5000; size: 128; - emitRate: 0; velocity: PointDirection { x: -200; y: -350; yVariation: 200; xVariation: 100 } } } -} diff --git a/tests/manual/pointer/pinchFlickable.qml b/tests/manual/pointer/pinchFlickable.qml new file mode 100644 index 00000000000..48a00b4b1b8 --- /dev/null +++ b/tests/manual/pointer/pinchFlickable.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the manual tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Item { + width: 300 + height: 300 + + Flickable { + id: flickable + anchors.fill: parent + contentHeight: column.height + + Column { + id: column + width: parent.width + + Repeater { + model: 255 + + delegate: Rectangle { + width: column.width + height: 50 + color: flickable.dragging ? "steelblue" : "gray" + Text { + anchors.centerIn: parent + text: index + } + } + } + } + } + PinchHandler { + target: flickable + } +} diff --git a/tests/manual/pointer/pinchNullTarget.qml b/tests/manual/pointer/pinchNullTarget.qml new file mode 100644 index 00000000000..79c60479917 --- /dev/null +++ b/tests/manual/pointer/pinchNullTarget.qml @@ -0,0 +1,50 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick 2.15 + +Rectangle { + width: 1024; height: 600 + color: "#eee" + + function getTransformationDetails(item, pinchhandler) { + return "\n\npinch.scale:" + pinchhandler.scale.toFixed(2) + + "\npinch.activeScale:" + pinchhandler.activeScale.toFixed(2) + + "\npinch.rotation:" + pinchhandler.rotation.toFixed(2) + + "\npinch.translation:" + "(" + pinchhandler.translation.x.toFixed(2) + "," + pinchhandler.translation.y.toFixed(2) + ")" + + "\nrect.scale: " + item.scale.toFixed(2) + + "\nrect.rotation: " + item.rotation.toFixed(2) + + "\nrect.position: " + "(" + item.x.toFixed(2) + "," + item.y.toFixed(2) + ")" + } + + Rectangle { + width: parent.width - 100; height: parent.height - 100; x: 50; y: 50 + color: "lightsteelblue" + antialiasing: true + scale: pinch.scale + + PinchHandler { + id: pinch + target: null + minimumScale: 0.5 + maximumScale: 3 + } + + Text { + text: "Pinch with 2 fingers to scale, rotate and translate" + + getTransformationDetails(parent, pinch) + } + } + + Rectangle { + id: centroidIndicator + x: pinch.centroid.scenePosition.x - radius + y: pinch.centroid.scenePosition.y - radius + z: 1 + visible: pinch.active + radius: width / 2 + width: 10 + height: width + color: "red" + } +} diff --git a/tests/manual/pointer/qml.qrc b/tests/manual/pointer/qml.qrc deleted file mode 100644 index 79df367391b..00000000000 --- a/tests/manual/pointer/qml.qrc +++ /dev/null @@ -1,52 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>flingAnimation.qml</file> - <file>main.qml</file> - <file>fakeFlickable.qml</file> - <file>flickablesWithHandlers.qml</file> - <file>joystick.qml</file> - <file>map.qml</file> - <file>mixer.qml</file> - <file>multibuttons.qml</file> - <file>photosurface.qml</file> - <file>pinchHandler.qml</file> - <file>pointerDrag.qml</file> - <file>singlePointHandlerProperties.qml</file> - <file>sidebar.qml</file> - <file>tabletCanvasDrawing.qml</file> - <file>tapHandler.qml</file> - <file>content/CheckBox.qml</file> - <file>content/FakeFlickable.qml</file> - <file>content/FlashAnimation.qml</file> - <file>content/MomentumAnimation.qml</file> - <file>content/MouseAreaButton.qml</file> - <file>content/MouseAreaSlider.qml</file> - <file>content/MouseFeedbackSprite.qml</file> - <file>content/MptaButton.qml</file> - <file>content/MultiButton.qml</file> - <file>content/ScrollBar.qml</file> - <file>content/Slider.qml</file> - <file>content/TapHandlerButton.qml</file> - <file>content/TextBox.qml</file> - <file>content/TouchpointFeedbackSprite.qml</file> - <file>resources/arrowhead.png</file> - <file>resources/balloon.png</file> - <file>resources/cursor-airbrush.png</file> - <file>resources/cursor-eraser.png</file> - <file>resources/cursor-felt-marker.png</file> - <file>resources/cursor-pencil.png</file> - <file>resources/fighter.png</file> - <file>resources/fingersprite.png</file> - <file>resources/grabbing-location.svg</file> - <file>resources/joystick-outer-case-pov.jpg</file> - <file>resources/map.svgz</file> - <file>resources/missile.png</file> - <file>resources/mixer-knob.png</file> - <file>resources/mouse.png</file> - <file>resources/mouse_left.png</file> - <file>resources/mouse_middle.png</file> - <file>resources/mouse_right.png</file> - <file>resources/redball.png</file> - <file>map2.qml</file> - </qresource> -</RCC> diff --git a/tests/manual/pointer/sidebar.qml b/tests/manual/pointer/sidebar.qml deleted file mode 100644 index b7370a4fb71..00000000000 --- a/tests/manual/pointer/sidebar.qml +++ /dev/null @@ -1,190 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick 2.15 -import "content" - -Rectangle { - id: root - width: 640 - height: 480 - color: "#444" - - Component { - id: buttonsAndStuff - Column { - anchors.fill: parent - anchors.margins: 8 - spacing: 8 - - Rectangle { - objectName: "buttonWithMA" - width: parent.width - height: 30 - color: buttonMA.pressed ? "lightsteelblue" : "#999" - border.color: buttonMA.containsMouse ? "cyan" : "transparent" - - MouseArea { - id: buttonMA - objectName: "buttonMA" - hoverEnabled: true - cursorShape: Qt.UpArrowCursor - anchors.fill: parent - onClicked: console.log("clicked MA") - } - - Text { - anchors.centerIn: parent - text: "MouseArea" - } - } - - Rectangle { - objectName: "buttonWithHH" - width: parent.width - height: 30 - color: flash ? "#999" : "white" - border.color: buttonHH.hovered ? "cyan" : "transparent" - property bool flash: true - - HoverHandler { - id: buttonHH - objectName: "buttonHH" - acceptedDevices: PointerDevice.AllDevices - cursorShape: tapHandler.pressed ? Qt.BusyCursor : Qt.PointingHandCursor - } - - TapHandler { - id: tapHandler - onTapped: tapFlash.start() - } - - Text { - anchors.centerIn: parent - text: "HoverHandler" - } - - FlashAnimation on flash { - id: tapFlash - } - } - } - } - - Rectangle { - id: paddle - width: 100 - height: 40 - color: paddleHH.hovered ? "indianred" : "#888" - y: parent.height - 100 - radius: 10 - - HoverHandler { - id: paddleHH - objectName: "paddleHH" - } - - SequentialAnimation on x { - NumberAnimation { - to: root.width - paddle.width - duration: 2000 - easing { type: Easing.InOutQuad } - } - PauseAnimation { duration: 100 } - NumberAnimation { - to: 0 - duration: 2000 - easing { type: Easing.InOutQuad } - } - PauseAnimation { duration: 100 } - loops: Animation.Infinite - } - } - - Rectangle { - objectName: "topSidebar" - radius: 5 - antialiasing: true - x: -radius - y: -radius - width: 120 - height: 200 - border.color: topSidebarHH.hovered ? "cyan" : "black" - color: "#777" - - Rectangle { - color: "cyan" - width: 10 - height: width - radius: width / 2 - visible: topSidebarHH.hovered - x: topSidebarHH.point.position.x - width / 2 - y: topSidebarHH.point.position.y - height / 2 - z: 100 - } - - HoverHandler { - id: topSidebarHH - objectName: "topSidebarHH" - cursorShape: Qt.OpenHandCursor - } - - Loader { - objectName: "topSidebarLoader" - sourceComponent: buttonsAndStuff - anchors.fill: parent - } - } - - Rectangle { - objectName: "bottomSidebar" - radius: 5 - antialiasing: true - x: -radius - anchors.bottom: parent.bottom - anchors.bottomMargin: -radius - width: 120 - height: 200 - border.color: bottomSidebarMA.containsMouse ? "cyan" : "black" - color: "#777" - - MouseArea { - id: bottomSidebarMA - objectName: "bottomSidebarMA" - hoverEnabled: true - cursorShape: Qt.ClosedHandCursor - anchors.fill: parent - } - - Loader { - objectName: "bottomSidebarLoader" - sourceComponent: buttonsAndStuff - anchors.fill: parent - } - } -} diff --git a/tests/manual/pointer/singlePointHandlerProperties.qml b/tests/manual/pointer/singlePointHandlerProperties.qml deleted file mode 100644 index 9bebf238109..00000000000 --- a/tests/manual/pointer/singlePointHandlerProperties.qml +++ /dev/null @@ -1,153 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick 2.12 - -Rectangle { - id: root - width: 480 - height: 480 - color: "black" - - Item { - id: crosshairs - x: pointHandler.point.position.x - width / 2 - y: pointHandler.point.position.y - height / 2 - width: parent.width / 2; height: parent.height / 2 - visible: pointHandler.active - rotation: pointHandler.point.rotation - - Rectangle { - color: "goldenrod" - anchors.centerIn: parent - width: 2; height: parent.height - antialiasing: true - } - Rectangle { - color: "goldenrod" - anchors.centerIn: parent - width: parent.width; height: 2 - antialiasing: true - } - Rectangle { - color: "goldenrod" - width: Math.max(2, 50 * pointHandler.point.pressure) - height: width - radius: width / 2 - anchors.centerIn: parent - antialiasing: true - Rectangle { - y: -56 - anchors.horizontalCenter: parent.horizontalCenter - color: "lightsteelblue" - implicitWidth: label.implicitWidth - implicitHeight: label.implicitHeight - Text { - id: label - text: 'seat: ' + pointHandler.point.device.seatName + '\ndevice: ' + pointHandler.point.device.name + - '\nid: ' + pointHandler.point.id.toString(16) + " uid: " + pointHandler.point.uniqueId.numericId + - '\npos: (' + pointHandler.point.position.x.toFixed(2) + ', ' + pointHandler.point.position.y.toFixed(2) + ')' + - '\nmodifiers: ' + pointHandler.point.modifiers.toString(16) - } - } - } - Rectangle { - color: "transparent" - border.color: "white" - antialiasing: true - width: pointHandler.point.ellipseDiameters.width - height: pointHandler.point.ellipseDiameters.height - radius: Math.min(width / 2, height / 2) - anchors.centerIn: parent - } - } - Rectangle { - id: velocityVector - visible: width > 0 - width: pointHandler.point.velocity.length() * 100 - height: 2 - x: pointHandler.point.position.x - y: pointHandler.point.position.y - rotation: Math.atan2(pointHandler.point.velocity.y, pointHandler.point.velocity.x) * 180 / Math.PI - transformOrigin: Item.BottomLeft - antialiasing: true - - Image { - source: "resources/arrowhead.png" - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - width: 16 - height: 12 - antialiasing: true - } - } - - Component { - id: grabbingLocationIndicator - Image { - source: "resources/grabbing-location.svg" - sourceSize.width: 32 - sourceSize.height: 32 - } - } - - Component { - id: mouseButtonIndicator - Image { - property int buttons - source: "resources/mouse.png" - Image { - source: "resources/mouse_left.png" - visible: buttons & Qt.LeftButton - } - Image { - source: "resources/mouse_middle.png" - visible: buttons & Qt.MiddleButton - } - Image { - source: "resources/mouse_right.png" - visible: buttons & Qt.RightButton - } - } - } - - PointHandler { - id: pointHandler - target: null - acceptedButtons: Qt.AllButtons - onGrabChanged: if (active) { // 'point' is an implicit parameter referencing to a QEventPoint instance - console.log("grabbed " + point.pointId + " @ " + point.sceneGrabPos) - grabbingLocationIndicator.createObject(root, {"x": point.sceneGrabPosition.x, "y": point.sceneGrabPosition.y - 16}) - } - onPointChanged: { - // Here, 'point' is referring to the property of the PointHandler - if (point.pressedButtons) - mouseButtonIndicator.createObject(root, {"x": point.pressPosition.x - 44, "y": point.pressPosition.y - 64, "buttons": point.pressedButtons}) - } - } -} diff --git a/tests/manual/pointer/tapHandler.qml b/tests/manual/pointer/tapHandler.qml deleted file mode 100644 index 6e51fc6fda6..00000000000 --- a/tests/manual/pointer/tapHandler.qml +++ /dev/null @@ -1,184 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the manual tests 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$ -** -****************************************************************************/ - -import QtQuick 2.12 -import "qrc:/quick/shared/" as Examples - -Item { - width: 480 - height: 320 - - Rectangle { - id: rect - anchors.fill: parent; anchors.margins: 40 - border.width: 3; border.color: "transparent" - color: handler.pressed ? "lightsteelblue" : "darkgrey" - - TapHandler { - id: handler - acceptedButtons: (leftAllowedCB.checked ? Qt.LeftButton : Qt.NoButton) | - (middleAllowedCB.checked ? Qt.MiddleButton : Qt.NoButton) | - (rightAllowedCB.checked ? Qt.RightButton : Qt.NoButton) - gesturePolicy: (policyDragThresholdCB.checked ? TapHandler.DragThreshold : - policyWithinBoundsCB.checked ? TapHandler.WithinBounds : - TapHandler.ReleaseWithinBounds) - - onCanceled: { - console.log("canceled @ " + point.position) - borderBlink.blinkColor = "red" - borderBlink.start() - } - onTapped: { // 'eventPoint' is a signal parameter of type QEventPoint* - console.log("tapped button " + eventPoint.event.button + " @ " + eventPoint.scenePosition + - " on device '" + eventPoint.event.device.name + "' " + (tapCount > 1 ? (tapCount + " times") : "for the first time")) - if (tapCount > 1) { - tapCountLabel.text = tapCount - flashAnimation.start() - } else { - borderBlink.tapFeedback(eventPoint.event.button) - } - } - onLongPressed: longPressFeedback.createObject(rect, - {"x": point.position.x, "y": point.position.y, - "text": handler.timeHeld.toFixed(3) + " sec", - "color": buttonToBlinkColor(point.pressedButtons)}) - } - - Text { - id: tapCountLabel - anchors.centerIn: parent - font.pixelSize: 72 - font.weight: Font.Black - SequentialAnimation { - id: flashAnimation - PropertyAction { target: tapCountLabel; property: "visible"; value: true } - PropertyAction { target: tapCountLabel; property: "opacity"; value: 1.0 } - PropertyAction { target: tapCountLabel; property: "scale"; value: 1.0 } - ParallelAnimation { - NumberAnimation { - target: tapCountLabel - property: "opacity" - to: 0 - duration: 500 - } - NumberAnimation { - target: tapCountLabel - property: "scale" - to: 1.5 - duration: 500 - } - } - } - } - - Rectangle { - id: expandingCircle - radius: handler.timeHeld * 100 - visible: radius > 0 && handler.pressed - border.width: 3 - border.color: buttonToBlinkColor(handler.point.pressedButtons) - color: "transparent" - width: radius * 2 - height: radius * 2 - x: handler.point.pressPosition.x - radius - y: handler.point.pressPosition.y - radius - opacity: 0.25 - } - - Component { - id: longPressFeedback - Text { } - } - - SequentialAnimation { - id: borderBlink - property color blinkColor: "red" - function tapFeedback(button) { - blinkColor = buttonToBlinkColor(button); - start(); - } - loops: 3 - ScriptAction { script: rect.border.color = borderBlink.blinkColor } - PauseAnimation { duration: 100 } - ScriptAction { script: rect.border.color = "transparent" } - PauseAnimation { duration: 100 } - } - } - - function buttonToBlinkColor(button) { - switch (button) { - case Qt.MiddleButton: return "orange"; - case Qt.RightButton: return "magenta"; - default: return "green"; - } - } - - Row { - spacing: 6 - Text { text: "accepted mouse clicks:"; anchors.verticalCenter: leftAllowedCB.verticalCenter } - Examples.CheckBox { - id: leftAllowedCB - checked: true - text: "left click" - } - Examples.CheckBox { - id: middleAllowedCB - text: "middle click" - } - Examples.CheckBox { - id: rightAllowedCB - text: "right click" - } - Text { text: " gesture policy:"; anchors.verticalCenter: leftAllowedCB.verticalCenter } - Examples.CheckBox { - id: policyDragThresholdCB - text: "drag threshold" - onCheckedChanged: if (checked) { - policyWithinBoundsCB.checked = false; - policyReleaseWithinBoundsCB.checked = false; - } - } - Examples.CheckBox { - id: policyWithinBoundsCB - text: "within bounds" - onCheckedChanged: if (checked) { - policyDragThresholdCB.checked = false; - policyReleaseWithinBoundsCB.checked = false; - } - } - Examples.CheckBox { - id: policyReleaseWithinBoundsCB - checked: true - text: "release within bounds" - onCheckedChanged: if (checked) { - policyDragThresholdCB.checked = false; - policyWithinBoundsCB.checked = false; - } - } - } -} diff --git a/tests/manual/quickcontrols2/CMakeLists.txt b/tests/manual/quickcontrols2/CMakeLists.txt new file mode 100644 index 00000000000..921e307121d --- /dev/null +++ b/tests/manual/quickcontrols2/CMakeLists.txt @@ -0,0 +1,17 @@ +# Generated from manual.pro. + +add_subdirectory(buttons) +add_subdirectory(fonts) +add_subdirectory(gifs) +add_subdirectory(headerview) +add_subdirectory(qquickdialog) +add_subdirectory(screenshots) +add_subdirectory(styles) +add_subdirectory(styles-cover-flow) +add_subdirectory(testbench) +if(QT_FEATURE_systemtrayicon) + add_subdirectory(systemtrayicon) +endif() +if(TARGET Qt::Widgets AND TARGET Qt::QuickWidgets) + add_subdirectory(viewinqwidget) +endif() diff --git a/tests/manual/quickcontrols2/buttons/ButtonLoader.qml b/tests/manual/quickcontrols2/buttons/ButtonLoader.qml new file mode 100644 index 00000000000..bc92a5452a0 --- /dev/null +++ b/tests/manual/quickcontrols2/buttons/ButtonLoader.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T + +Item { + id: root + implicitWidth: activeButton.implicitWidth + implicitHeight: activeButton.implicitHeight + + property bool round: false + + property string text + property bool flat + property bool hoverEnabled + property bool highlighted + property bool checked + property var down: undefined + + property T.AbstractButton activeButton: round ? roundButton : button + + Button { + id: button + visible: !round + text: root.text + flat: root.flat + hoverEnabled: root.hoverEnabled + highlighted: root.highlighted + checked: root.checked + down: root.down + enabled: root.enabled + } + + RoundButton { + id: roundButton + visible: round + text: "\u2713" + flat: root.flat + hoverEnabled: root.hoverEnabled + highlighted: root.highlighted + checked: root.checked + down: root.down + enabled: root.enabled + + Label { + text: root.text + font.pixelSize: roundButton.font.pixelSize * 0.5 + anchors.top: parent.bottom + anchors.topMargin: 2 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/tests/manual/quickcontrols2/buttons/CMakeLists.txt b/tests/manual/quickcontrols2/buttons/CMakeLists.txt new file mode 100644 index 00000000000..57f80c88d98 --- /dev/null +++ b/tests/manual/quickcontrols2/buttons/CMakeLists.txt @@ -0,0 +1,42 @@ +# Generated from buttons.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(buttons LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## buttons Binary: +##################################################################### + +qt_internal_add_manual_test(buttons + GUI + SOURCES + buttons.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Qml + Qt::QuickControls2 +) + +file(GLOB resource_glob_0 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.qml") +foreach(file IN LISTS resource_glob_0) + set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}") +endforeach() + +# Resources: +set(qmake_immediate_resource_files + ${resource_glob_0} +) + +qt_internal_add_resource(buttons "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + + +#### Keys ignored in scope 1:.:.:buttons.pro:<TRUE>: +# TEMPLATE = "app" diff --git a/tests/manual/quickcontrols2/buttons/buttons.cpp b/tests/manual/quickcontrols2/buttons/buttons.cpp new file mode 100644 index 00000000000..0272522a508 --- /dev/null +++ b/tests/manual/quickcontrols2/buttons/buttons.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/buttons.qml")); + + return app.exec(); +} diff --git a/tests/manual/quickcontrols2/buttons/buttons.pro b/tests/manual/quickcontrols2/buttons/buttons.pro new file mode 100644 index 00000000000..2cb1c14c542 --- /dev/null +++ b/tests/manual/quickcontrols2/buttons/buttons.pro @@ -0,0 +1,6 @@ +TEMPLATE = app +TARGET = buttons +QT += qml quickcontrols2 + +SOURCES += buttons.cpp +RESOURCES += $$files(*.qml) diff --git a/tests/manual/quickcontrols2/buttons/buttons.qml b/tests/manual/quickcontrols2/buttons/buttons.qml new file mode 100644 index 00000000000..26969440de1 --- /dev/null +++ b/tests/manual/quickcontrols2/buttons/buttons.qml @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Controls.Universal + +ApplicationWindow { + id: window + visible: true + title: "Buttons" + + Component.onCompleted: { + var pane = repeater.itemAt(0) + width = pane.implicitWidth * 2 + flickable.leftMargin + flickable.rightMargin + flow.spacing + height = header.height + pane.implicitHeight * 2 + flickable.topMargin + flickable.bottomMargin + flow.spacing + } + + header: ToolBar { + Row { + spacing: 20 + anchors.right: parent.right + CheckBox { + id: hoverBox + text: "Hover" + checked: true + } + CheckBox { + id: roundBox + text: "Round" + checked: false + } + } + } + + Flickable { + id: flickable + anchors.fill: parent + + topMargin: 40 + leftMargin: 40 + rightMargin: 40 + bottomMargin: 40 + + contentHeight: flow.implicitHeight + + Flow { + id: flow + spacing: 40 + width: flickable.width - flickable.leftMargin - flickable.rightMargin + + Repeater { + id: repeater + + model: [ + { title: "Normal", theme: Material.Light, flat: false }, + { title: "Flat", theme: Material.Light, flat: true }, + { title: "Normal", theme: Material.Dark, flat: false }, + { title: "Flat", theme: Material.Dark, flat: true } + ] + + Pane { + Material.elevation: 8 + Material.theme: modelData.theme + Universal.theme: modelData.theme + + GroupBox { + title: modelData.title + background.visible: false + + Grid { + columns: 4 + spacing: 20 + padding: 20 + + ButtonLoader { text: "Normal"; flat: modelData.flat; hoverEnabled: hoverBox.checked; round: roundBox.checked } + ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; enabled: false; round: roundBox.checked } + ButtonLoader { text: "Down"; flat: modelData.flat; hoverEnabled: hoverBox.checked; down: true; round: roundBox.checked } + ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; down: true; enabled: false; round: roundBox.checked } + + ButtonLoader { text: "Checked"; flat: modelData.flat; hoverEnabled: hoverBox.checked; checked: true; round: roundBox.checked } + ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; checked: true; enabled: false; round: roundBox.checked } + ButtonLoader { text: "Down"; flat: modelData.flat; hoverEnabled: hoverBox.checked; checked: true; down: true; round: roundBox.checked } + ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; checked: true; down: true; enabled: false; round: roundBox.checked } + + ButtonLoader { text: "Highlighted"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; round: roundBox.checked } + ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; enabled: false; round: roundBox.checked } + ButtonLoader { text: "Down"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; down: true; round: roundBox.checked } + ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; down: true; enabled: false; round: roundBox.checked } + + ButtonLoader { text: "Hi-checked"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; checked: true; round: roundBox.checked } + ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; checked: true; enabled: false; round: roundBox.checked } + ButtonLoader { text: "Down"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; checked: true; down: true; round: roundBox.checked } + ButtonLoader { text: "Disabled"; flat: modelData.flat; hoverEnabled: hoverBox.checked; highlighted: true; checked: true; down: true; enabled: false; round: roundBox.checked } + } + } + } + } + } + + ScrollIndicator.vertical: ScrollIndicator { } + } +} diff --git a/tests/manual/quickcontrols2/fonts/CMakeLists.txt b/tests/manual/quickcontrols2/fonts/CMakeLists.txt new file mode 100644 index 00000000000..6160ff11624 --- /dev/null +++ b/tests/manual/quickcontrols2/fonts/CMakeLists.txt @@ -0,0 +1,50 @@ +# Generated from fonts.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(fonts LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## fonts Binary: +##################################################################### + +qt_internal_add_manual_test(fonts + GUI + SOURCES + main.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Qml + Qt::Quick +) + +# Resources: +set(qml_resource_files + "main.qml" +) + +qt_internal_add_resource(fonts "qml" + PREFIX + "/" + FILES + ${qml_resource_files} +) + + +#### Keys ignored in scope 1:.:.:fonts.pro:<TRUE>: +# QML_IMPORT_PATH = <EMPTY> +# TEMPLATE = "app" + +## Scopes: +##################################################################### + +#### Keys ignored in scope 3:.:.:deployment.pri:UNIX AND NOT ANDROID: +# INSTALLS = "target" + +#### Keys ignored in scope 5:.:.:deployment.pri:QNX: +# target.path = "/tmp/$${TARGET}/bin" + +#### Keys ignored in scope 6:.:.:deployment.pri:else: +# target.path = "/opt/$${TARGET}/bin" diff --git a/tests/manual/quickcontrols2/fonts/deployment.pri b/tests/manual/quickcontrols2/fonts/deployment.pri new file mode 100644 index 00000000000..c89af25a853 --- /dev/null +++ b/tests/manual/quickcontrols2/fonts/deployment.pri @@ -0,0 +1,14 @@ +unix:!android { + isEmpty(target.path) { + qnx { + target.path = /tmp/$${TARGET}/bin + } else { + target.path = /opt/$${TARGET}/bin + } + export(target.path) + } + INSTALLS += target +} + +export(INSTALLS) + diff --git a/tests/manual/quickcontrols2/fonts/fonts.pro b/tests/manual/quickcontrols2/fonts/fonts.pro new file mode 100644 index 00000000000..36e70f7e18e --- /dev/null +++ b/tests/manual/quickcontrols2/fonts/fonts.pro @@ -0,0 +1,14 @@ +TEMPLATE = app + +QT += qml quick + +SOURCES += main.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Default rules for deployment. +include(deployment.pri) + diff --git a/tests/manual/quickcontrols2/fonts/main.cpp b/tests/manual/quickcontrols2/fonts/main.cpp new file mode 100644 index 00000000000..43e58bdd35a --- /dev/null +++ b/tests/manual/quickcontrols2/fonts/main.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + + return app.exec(); +} + diff --git a/tests/manual/quickcontrols2/fonts/main.qml b/tests/manual/quickcontrols2/fonts/main.qml new file mode 100644 index 00000000000..8d3464a0058 --- /dev/null +++ b/tests/manual/quickcontrols2/fonts/main.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T +import QtQuick.Layouts + +ApplicationWindow { + visible: true + width: 480 + height: 640 + title: qsTr("Hello World") + + header: ToolBar { + Slider { + from: 16 + to: 48 + stepSize: 1 + onValueChanged: control.font.pointSize = value + } + } + + Flickable { + anchors.fill: parent + contentWidth: control.width + contentHeight: control.height + + T.Control { + id: control + width: layout.implicitWidth + 40 + height: layout.implicitHeight + 40 + ColumnLayout { + id: layout + anchors.fill: parent + anchors.margins: 20 + Button { text: "Button" } + CheckBox { text: "CheckBox" } + GroupBox { title: "GroupBox" } + RadioButton { text: "RadioButton" } + Switch { text: "Switch" } + TabButton { + text: "TabButton" + font.pointSize: control.font.pointSize + } + TextField { placeholderText: "TextField" } + TextArea { placeholderText: "TextArea" } + ToolButton { text: "ToolButton" } + Tumbler { model: 3 } + } + } + + ScrollBar.vertical: ScrollBar { } + } +} diff --git a/tests/manual/quickcontrols2/fonts/qml.qrc b/tests/manual/quickcontrols2/fonts/qml.qrc new file mode 100644 index 00000000000..0ff3892d9ce --- /dev/null +++ b/tests/manual/quickcontrols2/fonts/qml.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + </qresource> +</RCC> + diff --git a/tests/manual/quickcontrols2/gifs/CMakeLists.txt b/tests/manual/quickcontrols2/gifs/CMakeLists.txt new file mode 100644 index 00000000000..a2fc53554d6 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/CMakeLists.txt @@ -0,0 +1,35 @@ +# Generated from gifs.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_gifs LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## tst_gifs Test: +##################################################################### + +# Collect test data +file(GLOB_RECURSE test_data_glob + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/*) +list(APPEND test_data ${test_data_glob}) + +qt_add_test(tst_gifs + SOURCES + capturedevent.cpp capturedevent.h + eventcapturer.cpp eventcapturer.h + gifrecorder.cpp gifrecorder.h + tst_gifs.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Quick + TESTDATA ${test_data} +) + +#### Keys ignored in scope 1:.:.:gifs.pro:<TRUE>: +# TEMPLATE = "app" + +## Scopes: +##################################################################### diff --git a/tests/manual/quickcontrols2/gifs/capturedevent.cpp b/tests/manual/quickcontrols2/gifs/capturedevent.cpp new file mode 100644 index 00000000000..cec5e97a6b1 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/capturedevent.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "capturedevent.h" + +#include <QMetaEnum> +#include <QMouseEvent> + +namespace { + static inline bool isMouseEvent(const QEvent &event) + { + return event.type() >= QEvent::MouseButtonPress && event.type() <= QEvent::MouseMove; + } +} + +CapturedEvent::CapturedEvent() +{ +} + +CapturedEvent::CapturedEvent(const QEvent &event, int delay) +{ + setEvent(event); + setDelay(delay); +} + +void CapturedEvent::setEvent(const QEvent &event) +{ + mType = event.type(); + + if (isMouseEvent(event)) { + const QMouseEvent *mouseEvent = static_cast<const QMouseEvent*>(&event); + mPos = mouseEvent->pos(); + mMouseButton = mouseEvent->button(); + } +} + +QEvent::Type CapturedEvent::type() const +{ + return mType; +} + +int CapturedEvent::delay() const +{ + return mDelay; +} + +void CapturedEvent::setDelay(int delay) +{ + mDelay = delay; + + mCppCommand.clear(); + + // We generate the C++ command here instead of when the event is captured, + // because events() might trim some events, causing the delay of some events to change. + // If we did it earlier, the events wouldn't have correct delays. + if (mType == QEvent::MouseMove) { + mCppCommand = QString::fromLatin1("QTest::mouseMove(&view, QPoint(%1, %2), %3);") + .arg(mPos.x()) + .arg(mPos.y()) + .arg(mDelay); + + } else if (mType >= QEvent::MouseButtonPress && mType <= QEvent::MouseButtonDblClick) { + QString eventTestFunctionName = (mType == QEvent::MouseButtonPress + ? "mousePress" : (mType == QEvent::MouseButtonRelease + ? "mouseRelease" : "mouseDClick")); + QString buttonStr = QMetaEnum::fromType<Qt::MouseButtons>().valueToKey(mMouseButton); + mCppCommand = QString::fromLatin1("QTest::%1(&view, Qt::%2, Qt::NoModifier, QPoint(%3, %4), %5);") + .arg(eventTestFunctionName) + .arg(buttonStr) + .arg(mPos.x()) + .arg(mPos.y()) + .arg(mDelay); + } +} + +QString CapturedEvent::cppCommand() const +{ + return mCppCommand; +} + diff --git a/tests/manual/quickcontrols2/gifs/capturedevent.h b/tests/manual/quickcontrols2/gifs/capturedevent.h new file mode 100644 index 00000000000..28ed510a8d6 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/capturedevent.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CAPTUREDEVENT_H +#define CAPTUREDEVENT_H + +#include <QEvent> +#include <QPoint> +#include <QString> + +class CapturedEvent +{ +public: + CapturedEvent(); + CapturedEvent(const QEvent &event, int delay); + + void setEvent(const QEvent &event); + + int delay() const; + void setDelay(int delay); + + QEvent::Type type() const; + + QString cppCommand() const; + +private: + QEvent::Type mType; + QPoint mPos; + Qt::MouseButton mMouseButton; + int mDelay; + QString mCppCommand; +}; + +#endif // CAPTUREDEVENT_H diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-busyindicator.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-busyindicator.qml new file mode 100644 index 00000000000..37dc5c7fd96 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-busyindicator.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: busyIndicator.implicitWidth + height: busyIndicator.implicitHeight + visible: true + + property alias busyIndicator: busyIndicator + + BusyIndicator { + id: busyIndicator + running: true + anchors.centerIn: parent + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-button-flat.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-button-flat.qml new file mode 100644 index 00000000000..dd07926ff1b --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-button-flat.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: button.width + height: button.height + visible: true + + Button { + id: button + text: pressed ? "Pressed" : "Button" + flat: true + anchors.centerIn: parent + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-button-highlighted.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-button-highlighted.qml new file mode 100644 index 00000000000..4af50d6b2ca --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-button-highlighted.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: button.width + height: button.height + visible: true + + Button { + id: button + text: pressed ? "Pressed" : "Button" + highlighted: true + anchors.centerIn: parent + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-button.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-button.qml new file mode 100644 index 00000000000..8336855c46f --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-button.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: button.width + height: button.height + visible: true + + Button { + id: button + text: pressed ? "Pressed" : "Button" + anchors.centerIn: parent + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-checkbox-tristate.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-checkbox-tristate.qml new file mode 100644 index 00000000000..b0bee6cd54c --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-checkbox-tristate.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Window + +Window { + width: column.implicitWidth + height: column.implicitHeight + visible: true + + property alias english: english + property alias norwegian: norwegian + + ColumnLayout { + id: column + anchors.centerIn: parent + + CheckBox { + text: qsTr("Languages") + checkState: english.checked && norwegian.checked + ? Qt.Checked : (english.checked || norwegian.checked) ? Qt.PartiallyChecked : Qt.Unchecked + tristate: true + } + CheckBox { + id: english + text: qsTr("English") + checked: true + leftPadding: indicator.width + } + CheckBox { + id: norwegian + text: qsTr("Norwegian") + checked: true + leftPadding: indicator.width + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-checkbox.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-checkbox.qml new file mode 100644 index 00000000000..46cdc073aaa --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-checkbox.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Window + +Window { + width: column.implicitWidth + height: column.implicitHeight + visible: true + + property alias control2: control2 + property alias control3: control3 + + ColumnLayout { + id: column + anchors.centerIn: parent + + CheckBox { + checked: true + text: qsTr("First") + } + CheckBox { + id: control2 + text: qsTr("Second") + } + CheckBox { + id: control3 + checked: true + text: qsTr("Third") + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-checkdelegate-tristate.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-checkdelegate-tristate.qml new file mode 100644 index 00000000000..585aea27049 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-checkdelegate-tristate.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Window + +Window { + id: window + width: 170 + height: column.implicitHeight + visible: true + + property alias english: english + property alias norwegian: norwegian + + ColumnLayout { + id: column + anchors.fill: parent + + CheckDelegate { + text: qsTr("Languages") + checkState: english.checked && norwegian.checked + ? Qt.Checked : (english.checked || norwegian.checked) ? Qt.PartiallyChecked : Qt.Unchecked + tristate: true + Layout.fillWidth: true + } + CheckDelegate { + id: english + text: qsTr("English") + checked: true + leftPadding: indicator.width + 14 + Layout.fillWidth: true + } + CheckDelegate { + id: norwegian + text: qsTr("Norwegian") + checked: true + leftPadding: indicator.width + 14 + Layout.fillWidth: true + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-checkdelegate.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-checkdelegate.qml new file mode 100644 index 00000000000..704a0601145 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-checkdelegate.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: column.implicitWidth + height: column.implicitHeight + visible: true + + property var delegate: repeater.count > 0 ? repeater.itemAt(0) : null + + Column { + id: column + anchors.centerIn: parent + + Repeater { + id: repeater + model: ["Option 1", "Option 2", "Option 3"] + delegate: CheckDelegate { + text: modelData + } + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-combobox.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-combobox.qml new file mode 100644 index 00000000000..274f2efe612 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-combobox.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Window + +Window { + width: 140 + height: 180 + visible: true + + property alias comboBox: comboBox + + ComboBox { + id: comboBox + model: ["First", "Second", "Third"] + y: 10 + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-delaybutton.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-delaybutton.qml new file mode 100644 index 00000000000..8eaa3df24a9 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-delaybutton.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: button.width + height: button.height + visible: true + + DelayButton { + id: button + progress: 0.69 + text: "DelayButton" + anchors.centerIn: parent + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-dial-no-wrap.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-dial-no-wrap.qml new file mode 100644 index 00000000000..3b9b14668f9 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-dial-no-wrap.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: dial.implicitWidth + 20 + height: dial.implicitHeight + 20 + visible: true + + property alias dial: dial + + Dial { + id: dial + anchors.centerIn: parent + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-dial-wrap.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-dial-wrap.qml new file mode 100644 index 00000000000..317d81d27ba --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-dial-wrap.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: dial.implicitWidth + 20 + height: dial.implicitHeight + 20 + visible: true + + property alias dial: dial + + Dial { + id: dial + wrap: true + anchors.centerIn: parent + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-drawer.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-drawer.qml new file mode 100644 index 00000000000..32efcba8c4c --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-drawer.qml @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Window + +ApplicationWindow { + id: window + width: 300 + height: 300 + visible: true + + property alias drawer: drawer + + Drawer { + id: drawer + width: window.width * 0.66 + height: window.height + rightPadding: 0 + + Rectangle { + border.width: 1 + anchors.fill: parent + + Label { + text: "Drawer" + font.pixelSize: 32 + anchors.centerIn: parent + } + } + } + + Rectangle { + border.width: 1 + anchors.fill: parent + + Label { + text: "Content" + font.pixelSize: 32 + anchors.centerIn: parent + } + } + + Rectangle { + z: 1 + color: "black" + width: 1 + height: parent.height + parent: window.overlay + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-itemdelegate.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-itemdelegate.qml new file mode 100644 index 00000000000..1ef9e2c0c64 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-itemdelegate.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: column.implicitWidth + height: column.implicitHeight + visible: true + + property var delegate: repeater.count > 0 ? repeater.itemAt(0) : null + + Column { + id: column + + Repeater { + id: repeater + model: ["Option 1", "Option 2", "Option 3"] + delegate: ItemDelegate { + text: modelData + } + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-menu.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-menu.qml new file mode 100644 index 00000000000..80f2c86d516 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-menu.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +// TODO: restore and finish https://codereview.qt-project.org/#/c/123948/ +ApplicationWindow { + width: menu.contentItem.width + 20 + height: menu.contentItem.height + fileButton.height + 20 + + property alias fileButton: fileButton + property alias menu: menu + + Button { + id: fileButton + text: "File" + onClicked: menu.open() + x: 10 + y: 10 + } + Menu { + id: menu + // TODO + contentItem.x: fileButton.x + contentItem.y: fileButton.y + fileButton.height + + MenuItem { + text: "New..." + } + MenuItem { + text: "Open..." + } + MenuItem { + text: "Save" + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-progressbar-indeterminate.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-progressbar-indeterminate.qml new file mode 100644 index 00000000000..4679ea03c88 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-progressbar-indeterminate.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: progressBar.implicitWidth + height: 64 + visible: true + + property alias progressBar: progressBar + + ProgressBar { + id: progressBar + indeterminate: true + anchors.centerIn: parent + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-progressbar.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-progressbar.qml new file mode 100644 index 00000000000..994af450b7d --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-progressbar.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: progressBar.implicitWidth + height: 64 + visible: true + + property alias progressBar: progressBar + + ProgressBar { + id: progressBar + value: 0.5 + anchors.centerIn: parent + + Timer { + running: true + interval: 500 + onTriggered: animation.start() + } + + NumberAnimation { + id: animation + target: progressBar + property: "value" + to: 1 + duration: 2000 + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-radiobutton.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-radiobutton.qml new file mode 100644 index 00000000000..fec7ec9b018 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-radiobutton.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Window + +Window { + width: column.implicitWidth + height: column.implicitHeight + visible: true + + property alias control1: control1 + property alias control2: control2 + property alias control3: control3 + + ColumnLayout { + id: column + anchors.centerIn: parent + + RadioButton { + id: control1 + text: qsTr("First") + checked: true + } + RadioButton { + id: control2 + text: qsTr("Second") + } + RadioButton { + id: control3 + text: qsTr("Third") + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-radiodelegate.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-radiodelegate.qml new file mode 100644 index 00000000000..a00f320927b --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-radiodelegate.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: column.implicitWidth + height: column.implicitHeight + visible: true + + property var delegate: repeater.count > 0 ? repeater.itemAt(0) : null + + ButtonGroup { + id: buttonGroup + } + + Column { + id: column + anchors.centerIn: parent + + Repeater { + id: repeater + model: ["Option 1", "Option 2", "Option 3"] + delegate: RadioDelegate { + checked: index == 0 + text: modelData + ButtonGroup.group: buttonGroup + } + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-rangeslider.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-rangeslider.qml new file mode 100644 index 00000000000..c648f9983a6 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-rangeslider.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: slider.implicitWidth + height: slider.implicitHeight + visible: true + + property alias slider: slider + + RangeSlider { + id: slider + anchors.centerIn: parent + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-scrollbar-snap.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-scrollbar-snap.qml new file mode 100644 index 00000000000..cc4d6dc2fad --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-scrollbar-snap.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 100 + maximumHeight: 20 + visible: true + + property alias scrollbar: scrollbar + + ScrollBar { + id: scrollbar + size: 0.2 + stepSize: 0.25 + active: true + width: parent.width + anchors.centerIn: parent + orientation: Qt.Horizontal + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-scrollbar.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-scrollbar.qml new file mode 100644 index 00000000000..e838673a2a1 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-scrollbar.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 100 + height: 120 + visible: true + color: "#eeeeee" + + property alias scrollBar: scrollBar + + ListView { + anchors.fill: parent + + ScrollBar.vertical: ScrollBar { + id: scrollBar + active: true + } + + model: 10 + delegate: Label { + text: qsTr("Item %1").arg(index + 1) + width: 100 + height: 40 + leftPadding: 10 + verticalAlignment: Text.AlignVCenter + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-scrollindicator.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-scrollindicator.qml new file mode 100644 index 00000000000..be23df3b251 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-scrollindicator.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 100 + height: 120 + visible: true + color: "#eeeeee" + + ListView { + anchors.fill: parent + + ScrollIndicator.vertical: ScrollIndicator { + active: true + } + + model: 10 + delegate: Label { + text: qsTr("Item %1").arg(index + 1) + width: 100 + height: 40 + leftPadding: 10 + verticalAlignment: Text.AlignVCenter + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-slider-snap.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-slider-snap.qml new file mode 100644 index 00000000000..26066770e78 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-slider-snap.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: slider.implicitWidth + height: slider.implicitHeight + visible: true + + property alias slider: slider + + Slider { + id: slider + stepSize: 0.2 + anchors.centerIn: parent + + Rectangle { + anchors.fill: slider.handle + radius: width / 2 + color: slider.pressed ? "#aa666666" : "transparent" + } + + contentItem: Item { + Repeater { + id: repeater + model: 6 + + Rectangle { + x: ((slider.contentItem.width - slider.handle.width) * (index / (repeater.count - 1))) + - width / 2 + slider.handle.width / 2 + y: parent.height + width: 1 + height: 4 + color: "#888" + } + } + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-slider.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-slider.qml new file mode 100644 index 00000000000..83f652aa261 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-slider.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: slider.implicitWidth + height: slider.implicitHeight + visible: true + + property alias slider: slider + + Slider { + id: slider + anchors.centerIn: parent + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-stackview-pop.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-stackview-pop.qml new file mode 100644 index 00000000000..7ddd8db8034 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-stackview-pop.qml @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +ApplicationWindow { + width: 160 + height: 160 + visible: true + color: "#eeeeee" + + property int maxDepth: 3 + + function itemText(index) { + return String.fromCharCode(65 + index); + } + + Component { + id: labelComponent + + Label { + font.pixelSize: 60 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + StackView { + id: stackView + anchors.fill: parent + + Component.onCompleted: { + for (var i = 0; i < maxDepth; ++i) { + stackView.push(labelComponent, { text: itemText(i) }, StackView.Immediate); + } + } + } + + Label { + id: operationLabel + text: "pop()" + font.pixelSize: 16 + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 10 + } + + Timer { + id: operationTimer + running: true + interval: 1500 + onTriggered: { + stackView.pop(); + hideOperationTimer.start(); + } + } + + Timer { + id: hideOperationTimer + interval: operationTimer.interval + onTriggered: operationLabel.visible = false + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-stackview-push.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-stackview-push.qml new file mode 100644 index 00000000000..88229fce7e9 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-stackview-push.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +ApplicationWindow { + width: 160 + height: 160 + visible: true + color: "#eeeeee" + + property int itemIndex: 0 + property int maxDepth: 3 + + function itemText(index) { + return String.fromCharCode(65 + index); + } + + Component { + id: labelComponent + + Label { + font.pixelSize: 60 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + StackView { + id: stackView + anchors.fill: parent + } + + Label { + id: operationLabel + text: "push(" + itemText(Math.max(0, Math.min(maxDepth - 1, itemIndex - 1))) + ")" + font.pixelSize: 16 + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 10 + } + + Timer { + id: operationTimer + running: true + interval: 1500 + repeat: stackView.depth < maxDepth - 1 + onRepeatChanged: if (!repeat) hideOperationTimer.start() + + onTriggered: stackView.push(labelComponent, { text: itemText(itemIndex++) }) + } + + Timer { + id: hideOperationTimer + interval: operationTimer.interval * 2 + onTriggered: operationLabel.visible = false + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-stackview-replace.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-stackview-replace.qml new file mode 100644 index 00000000000..59885745c1b --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-stackview-replace.qml @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +ApplicationWindow { + width: 160 + height: 160 + visible: true + color: "#eeeeee" + + property int maxDepth: 3 + + function itemText(index) { + return String.fromCharCode(65 + index); + } + + Component { + id: labelComponent + + Label { + font.pixelSize: 60 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + StackView { + id: stackView + anchors.fill: parent + + Component.onCompleted: { + for (var i = 0; i < maxDepth; ++i) { + stackView.push(labelComponent, { text: itemText(i) }, StackView.Immediate); + } + } + } + + Label { + id: operationLabel + text: "replace(D)" + font.pixelSize: 16 + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 10 + } + + Timer { + id: operationTimer + running: true + interval: 1500 + onTriggered: { + stackView.replace(labelComponent, { text: "D" }); + hideOperationTimer.start(); + } + } + + Timer { + id: hideOperationTimer + interval: operationTimer.interval + onTriggered: operationLabel.visible = false + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-stackview-unwind.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-stackview-unwind.qml new file mode 100644 index 00000000000..a7435d2ac77 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-stackview-unwind.qml @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +ApplicationWindow { + width: 160 + height: 160 + visible: true + color: "#eeeeee" + + property int maxDepth: 3 + + function itemText(index) { + return String.fromCharCode(65 + index); + } + + Component { + id: labelComponent + + Label { + font.pixelSize: 60 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + StackView { + id: stackView + anchors.fill: parent + + Component.onCompleted: { + for (var i = 0; i < maxDepth; ++i) { + stackView.push(labelComponent, { text: itemText(i) }, StackView.Immediate); + } + } + } + + Label { + id: operationLabel + text: "pop(null)" + font.pixelSize: 16 + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.margins: 10 + } + + Timer { + id: operationTimer + running: true + interval: 1500 + onTriggered: { + stackView.pop(null); + hideOperationTimer.start(); + } + } + + Timer { + id: hideOperationTimer + interval: operationTimer.interval + onTriggered: operationLabel.visible = false + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-swipedelegate-behind.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-swipedelegate-behind.qml new file mode 100644 index 00000000000..0b18c6a3362 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-swipedelegate-behind.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: swipeDelegate.implicitWidth + height: swipeDelegate.implicitHeight + visible: true + + property alias swipeDelegate: swipeDelegate + + SwipeDelegate { + id: swipeDelegate + text: "SwipeDelegate" + anchors.centerIn: parent + + swipe.left: null + swipe.right: null + swipe.behind: Rectangle { + width: swipeDelegate.width + height: swipeDelegate.height + color: swipeDelegate.pressed ? "#333" : "#444" + + Label { + text: "Behind Action" + color: "#fff" + anchors.centerIn: parent + } + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-swipedelegate-leading-trailing.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-swipedelegate-leading-trailing.qml new file mode 100644 index 00000000000..789fb86f551 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-swipedelegate-leading-trailing.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: swipeDelegate.implicitWidth + height: swipeDelegate.implicitHeight + visible: true + + property alias swipeDelegate: swipeDelegate + + SwipeDelegate { + id: swipeDelegate + text: "SwipeDelegate" + anchors.centerIn: parent + + swipe.left: Rectangle { + width: swipeDelegate.width + height: swipeDelegate.height + color: swipeDelegate.pressed ? "#333" : "#444" + anchors.right: parent.left + + Label { + text: "Left Action" + color: "#fff" + anchors.centerIn: parent + } + } + + swipe.right: Rectangle { + width: swipeDelegate.width + height: swipeDelegate.height + color: swipeDelegate.pressed ? "#333" : "#444" + anchors.left: parent.right + + Label { + text: "Right Action" + color: "#fff" + anchors.centerIn: parent + } + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-swipedelegate.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-swipedelegate.qml new file mode 100644 index 00000000000..c78fc6d4f9f --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-swipedelegate.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: swipeDelegate.implicitWidth + height: swipeDelegate.implicitHeight + visible: true + + property alias swipeDelegate: swipeDelegate + + SwipeDelegate { + id: swipeDelegate + text: "SwipeDelegate" + anchors.centerIn: parent + + swipe.left: Rectangle { + width: swipeDelegate.width + height: swipeDelegate.height + color: swipeDelegate.pressed ? "#333" : "#444" + + Label { + text: "Left Action" + color: "#fff" + anchors.centerIn: parent + } + } + + swipe.right: Rectangle { + anchors.fill: parent + width: swipeDelegate.width + height: swipeDelegate.height + color: swipeDelegate.pressed ? "#333" : "#444" + + Label { + text: "Right Action" + color: "#fff" + anchors.centerIn: parent + } + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-swipeview.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-swipeview.qml new file mode 100644 index 00000000000..9004ff183b5 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-swipeview.qml @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 300 + height: 300 + visible: true + + property alias swipeView: view + + Rectangle { + border.width: 1 + anchors.fill: parent + } + + SwipeView { + id: view + anchors.fill: parent + + Label { + text: "First\nPage" + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + } + + Label { + text: "Second\nPage" + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + } + + Label { + text: "Third\nPage" + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + } + } + + PageIndicator { + id: indicator + + count: view.count + currentIndex: view.currentIndex + + anchors.bottom: view.bottom + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-switch.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-switch.qml new file mode 100644 index 00000000000..a9497bded54 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-switch.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 100 + height: 50 + visible: true + + Switch { + id: theSwitch + anchors.centerIn: parent + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-switchdelegate.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-switchdelegate.qml new file mode 100644 index 00000000000..1caece5b162 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-switchdelegate.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: column.implicitWidth + height: column.implicitHeight + visible: true + + property var delegate: repeater.count > 0 ? repeater.itemAt(0) : null + + Column { + id: column + anchors.centerIn: parent + + Repeater { + id: repeater + model: ["Option 1", "Option 2", "Option 3"] + delegate: SwitchDelegate { + text: modelData + } + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-tabbar.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-tabbar.qml new file mode 100644 index 00000000000..a973cef8c4b --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-tabbar.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: 300 + height: tabBar.height + visible: true + + TabBar { + id: tabBar + width: parent.width + + TabButton { text: qsTr("Home") } + TabButton { text: qsTr("Discover") } + TabButton { text: qsTr("Activity") } + } +} diff --git a/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-tumbler-wrap.qml b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-tumbler-wrap.qml new file mode 100644 index 00000000000..bfad311e252 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/data/qtquickcontrols2-tumbler-wrap.qml @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + width: frame.implicitWidth + 10 + height: frame.implicitHeight + 10 + visible: true + + function formatText(count, modelData) { + var data = count === 12 ? modelData + 1 : modelData; + return data.toString().length < 2 ? "0" + data : data; + } + + Component { + id: delegateComponent + + Label { + text: formatText(Tumbler.tumbler.count, modelData) + opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2) + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + Frame { + id: frame + padding: 0 + anchors.centerIn: parent + + Row { + id: row + + Tumbler { + id: hoursTumbler + model: 12 + delegate: delegateComponent + } + + Tumbler { + id: minutesTumbler + model: 60 + delegate: delegateComponent + } + + Tumbler { + id: amPmTumbler + wrap: false + model: ["AM", "PM"] + delegate: delegateComponent + } + } + } +} diff --git a/tests/manual/quickcontrols2/gifs/eventcapturer.cpp b/tests/manual/quickcontrols2/gifs/eventcapturer.cpp new file mode 100644 index 00000000000..ad88b1dbf92 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/eventcapturer.cpp @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "eventcapturer.h" + +#include <QDebug> +#include <QMetaEnum> +#include <QMouseEvent> +#include <QTimer> + +/*! + Installs an event filter on a particular object to record specific events + that can be retrieved as C++ source code. + + For example: + + \code + EventCapturer eventCapturer; + + view.show(); + + eventCapturer.startCapturing(&view, 5000); + + // interact with the view here, in order for the events to be captured + + qDebug() << "\n"; + const auto capturedEvents = eventCapturer.capturedEvents(); + for (CapturedEvent event : capturedEvents) + qDebug().noquote() << event.cppCommand(); + \endcode + + It is recommended to set the \c Qt::FramelessWindowHint flag on the view + (this code has not been tested under other usage): + + view.setFlags(view.flags() | Qt::FramelessWindowHint); +*/ + +EventCapturer::EventCapturer(QObject *parent) : + QObject(parent), + mEventSource(nullptr), + mStopCaptureKey(Qt::Key_Escape), + mMoveEventTrimFlags(TrimNone), + mDuration(0), + mLastCaptureTime(0) +{ + mCapturedEventTypes << QEvent::MouseButtonPress << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick << QEvent::MouseMove; +} + +void EventCapturer::startCapturing(QObject *eventSource, int duration) +{ + mEventSource = eventSource; + + if (!mEventSource) + return; + + mEventSource->installEventFilter(this); + mDelayTimer.start(); + mDuration = duration; + mLastCaptureTime = 0; + + QTimer::singleShot(mDuration, this, SLOT(stopCapturing())); +} + +void EventCapturer::setStopCaptureKey(Qt::Key stopCaptureKey) +{ + mStopCaptureKey = stopCaptureKey; +} + +/*! + Move events generate a lot of clutter, and for most cases they're not + necessary. Here's a list of scenarios where various trim flags make sense: + + Scenario Flags + + Record the mouse cursor TrimNone + Record mouseover/hover effects TrimNone + Dragging/flicking TrimAll +*/ +void EventCapturer::setMoveEventTrimFlags(MoveEventTrimFlags trimFlags) +{ + mMoveEventTrimFlags = trimFlags; +} + +QSet<QEvent::Type> EventCapturer::capturedEventTypes() +{ + return mCapturedEventTypes; +} + +void EventCapturer::setCapturedEventTypes(QSet<QEvent::Type> types) +{ + mCapturedEventTypes = types; +} + +QList<CapturedEvent> EventCapturer::capturedEvents() const +{ + if (mMoveEventTrimFlags == TrimNone || mEvents.isEmpty()) + return mEvents; + + // We can't easily trim "trailing" move events as they come in without + // storing them in some form, so we just do it all here. + + int firstEventIndex = 0; + int lastEventIndex = mEvents.size() - 1; + // The accumulated delay of all of the move events that we remove. + // We keep this in order to maintain the correct timing between events. + int accumulatedDelay = 0; + + bool encounteredNonMoveEvent = false; + if (mMoveEventTrimFlags.testFlag(TrimLeading)) { + for (int eventIndex = 0; !encounteredNonMoveEvent && eventIndex < mEvents.size(); ++eventIndex) { + const CapturedEvent event = mEvents.at(eventIndex); + if (event.type() != QEvent::MouseMove) { + encounteredNonMoveEvent = true; + firstEventIndex = eventIndex; + } else { + accumulatedDelay += event.delay(); + } + } + } + + if (mMoveEventTrimFlags.testFlag(TrimTrailing)) { + encounteredNonMoveEvent = false; + for (int eventIndex = mEvents.size() - 1; !encounteredNonMoveEvent && eventIndex >= 0; --eventIndex) { + const CapturedEvent event = mEvents.at(eventIndex); + if (event.type() != QEvent::MouseMove) { + encounteredNonMoveEvent = true; + lastEventIndex = eventIndex; + // Don't need to bother with delays for trailing mouse moves, as there is nothing after them. + } + } + } + + // Before we go any further, we need to copy the subset of commands while + // the indices are still valid - we could be removing from the middle of + // the commands next. Also, the function is const, so we can't remove from + // mEvents anyway. :) + QList<CapturedEvent> events = mEvents.mid(firstEventIndex, (lastEventIndex - firstEventIndex) + 1); + + if (mMoveEventTrimFlags.testFlag(TrimAfterReleases)) { + bool lastNonMoveEventWasRelease = false; + for (int eventIndex = 0; eventIndex < events.size(); ) { + CapturedEvent &event = events[eventIndex]; + if (event.type() == QEvent::MouseMove && lastNonMoveEventWasRelease) { + accumulatedDelay += event.delay(); + events.remove(eventIndex); + } else { + lastNonMoveEventWasRelease = event.type() == QEvent::MouseButtonRelease; + if (event.type() == QEvent::MouseButtonPress) { + event.setDelay(event.delay() + accumulatedDelay); + accumulatedDelay = 0; + } + ++eventIndex; + } + } + } + + return events; +} + +bool EventCapturer::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::KeyPress && static_cast<QKeyEvent*>(event)->key() == mStopCaptureKey) { + stopCapturing(); + return true; + } + + if (object != mEventSource) + return false; + + if (!mCapturedEventTypes.contains(event->type())) + return false; + + if (event->type() == QEvent::MouseButtonPress) { + captureEvent(event); + } else if (event->type() == QEvent::MouseButtonRelease) { + captureEvent(event); + } else if (event->type() == QEvent::MouseButtonDblClick) { + captureEvent(event); + } else if (event->type() == QEvent::MouseMove) { + captureEvent(event); + } else { + qWarning() << "No support for event type" << QMetaEnum::fromType<QEvent::Type>().valueToKey(event->type()); + } + return false; +} + +void EventCapturer::stopCapturing() +{ + if (mEventSource) { + mEventSource->removeEventFilter(this); + mEventSource = 0; + mDuration = 0; + mLastCaptureTime = 0; + } +} + +void EventCapturer::captureEvent(const QEvent *event) +{ + qDebug() << "captured" << event->type(); + CapturedEvent capturedEvent(*event, mDelayTimer.elapsed() - mLastCaptureTime); + mEvents.append(capturedEvent); + mLastCaptureTime = mDelayTimer.elapsed(); +} diff --git a/tests/manual/quickcontrols2/gifs/eventcapturer.h b/tests/manual/quickcontrols2/gifs/eventcapturer.h new file mode 100644 index 00000000000..ea01299f54d --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/eventcapturer.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EVENTCAPTURER_H +#define EVENTCAPTURER_H + +#include <QObject> +#include <QElapsedTimer> +#include <QEvent> +#include <QList> +#include <QPoint> +#include <QSet> + +#include "capturedevent.h" + +class EventCapturer : public QObject +{ + Q_OBJECT + +public: + EventCapturer(QObject *parent = 0); + + enum MoveEventTrimFlag + { + TrimNone = 0x0, + TrimLeading = 0x1, + TrimTrailing = 0x2, + TrimAfterReleases = 0x4, + TrimAll = TrimLeading | TrimTrailing | TrimAfterReleases + }; + + Q_DECLARE_FLAGS(MoveEventTrimFlags, MoveEventTrimFlag) + + void setStopCaptureKey(Qt::Key stopCaptureKey); + void setMoveEventTrimFlags(MoveEventTrimFlags trimFlags); + + void startCapturing(QObject *eventSource, int duration); + + QSet<QEvent::Type> capturedEventTypes(); + void setCapturedEventTypes(QSet<QEvent::Type> types); + + QList<CapturedEvent> capturedEvents() const; +protected: + bool eventFilter(QObject *object, QEvent *event) override; + +private slots: + void stopCapturing(); + +private: + void captureEvent(const QEvent *event); + + QObject *mEventSource; + QSet<QEvent::Type> mCapturedEventTypes; + Qt::Key mStopCaptureKey; + MoveEventTrimFlags mMoveEventTrimFlags; + QElapsedTimer mDelayTimer; + QList<CapturedEvent> mEvents; + int mDuration; + int mLastCaptureTime; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(EventCapturer::MoveEventTrimFlags) + +#endif // EVENTCAPTURER_H diff --git a/tests/manual/quickcontrols2/gifs/gifrecorder.cpp b/tests/manual/quickcontrols2/gifs/gifrecorder.cpp new file mode 100644 index 00000000000..4bc7c9cdf07 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/gifrecorder.cpp @@ -0,0 +1,327 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gifrecorder.h" + +#include <QLoggingCategory> +#include <QQmlComponent> +#include <QQuickItem> +#include <QtTest> + +/*! + QProcess wrapper around byzanz-record (sudo apt-get install byzanz). + + \note The following programs must be installed if \c setHighQuality(true) + is called: + + \li \e ffmpeg (sudo apt-get install ffmpeg) + \li \e convert (sudo apt-get install imagemagick) + \li \e gifsicle (sudo apt-get install gifsicle) + + It is recommended to set the \c Qt::FramelessWindowHint flag on the view + (this code has not been tested under other usage): + + view.setFlags(view.flags() | Qt::FramelessWindowHint); +*/ + +Q_LOGGING_CATEGORY(lcGifRecorder, "qt.gifrecorder") + +namespace { + static const char *byzanzProcessName = "byzanz-record"; +} + +GifRecorder::GifRecorder() : + QObject(nullptr), + mWindow(nullptr), + mHighQuality(false), + mRecordingDuration(0), + mRecordCursor(false), + mByzanzProcessFinished(false) +{ + if (lcGifRecorder().isDebugEnabled()) { + // Ensures output from the process goes directly into the console. + mByzanzProcess.setProcessChannelMode(QProcess::ForwardedChannels); + } + + connect(&mByzanzProcess, SIGNAL(errorOccurred(QProcess::ProcessError)), this, SLOT(onByzanzError())); + connect(&mByzanzProcess, SIGNAL(finished(int)), this, SLOT(onByzanzFinished())); +} + +void GifRecorder::setRecordingDuration(int duration) +{ + QVERIFY2(duration >= 1, qPrintable(QString::fromLatin1("Recording duration %1 must be larger than 1 second").arg(duration))); + QVERIFY2(duration < 20, qPrintable(QString::fromLatin1("Recording duration %1 must be less than 20 seconds").arg(duration))); + + mRecordingDuration = duration; +} + +void GifRecorder::setRecordCursor(bool recordCursor) +{ + mRecordCursor = recordCursor; +} + +void GifRecorder::setDataDirPath(const QString &path) +{ + QVERIFY2(!path.isEmpty(), "Data directory path cannot be empty"); + mDataDirPath = path; +} + +void GifRecorder::setOutputDir(const QDir &dir) +{ + QVERIFY2(dir.exists(), "Output directory must exist"); + mOutputDir = dir; +} + +void GifRecorder::setOutputFileBaseName(const QString &fileBaseName) +{ + mOutputFileBaseName = fileBaseName; +} + +void GifRecorder::setQmlFileName(const QString &fileName) +{ + QVERIFY2(!fileName.isEmpty(), "QML file name cannot be empty"); + mQmlInputFileName = fileName; +} + +void GifRecorder::setView(QQuickWindow *view) +{ + this->mWindow = view; +} + +/*! + If \a highQuality is \c true, records as .flv (lossless) and then converts + to .gif in order to retain more color information, at the expense of a + larger file size. Otherwise, records directly to .gif using a limited + amount of colors, resulting in a smaller file size. + + Set this to \c true if any of the items have transparency, for example. + + The default value is \c false. +*/ +void GifRecorder::setHighQuality(bool highQuality) +{ + mHighQuality = highQuality; +} + +QQuickWindow *GifRecorder::window() const +{ + return mWindow; +} + +namespace { + struct ProcessWaitResult { + bool success; + QString errorMessage; + }; + + ProcessWaitResult waitForProcessToStart(QProcess &process, const QString &processName, const QString &args) + { + qCDebug(lcGifRecorder) << "Starting" << processName << "with the following arguments:" << args; + const QString command = processName + QLatin1Char(' ') + args; + process.start(command); + if (!process.waitForStarted(1000)) { + QString errorMessage = QString::fromLatin1("Could not launch %1 with the following arguments: %2\nError:\n%3"); + errorMessage = errorMessage.arg(processName).arg(args).arg(process.errorString()); + return { false, errorMessage }; + } + + qCDebug(lcGifRecorder) << "Successfully started" << processName; + return { true, QString() }; + } + + ProcessWaitResult waitForProcessToFinish(QProcess &process, const QString &processName, int waitDuration) + { + if (!process.waitForFinished(waitDuration) || process.exitCode() != 0) { + QString errorMessage = QString::fromLatin1("\"%1\" failed to finish (exit code %2): %3"); + errorMessage = errorMessage.arg(processName).arg(process.exitCode()).arg(process.errorString()); + return { false, errorMessage }; + } + + qCDebug(lcGifRecorder) << processName << "finished"; + return { true, QString() }; + } +} + +void GifRecorder::start() +{ + QDir gifQmlDir(mDataDirPath); + QVERIFY(gifQmlDir.entryList().contains(mQmlInputFileName)); + + const QString qmlPath = gifQmlDir.absoluteFilePath(mQmlInputFileName); + mEngine.load(QUrl::fromLocalFile(qmlPath)); + mWindow = qobject_cast<QQuickWindow*>(mEngine.rootObjects().first()); + QVERIFY2(mWindow, "Top level item must be a window"); + + mWindow->setFlags(mWindow->flags() | Qt::FramelessWindowHint); + + mWindow->show(); + mWindow->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(mWindow, 500)); + QVERIFY(QTest::qWaitForWindowExposed(mWindow, 500)); + // For some reason, whatever is behind the window is sometimes + // in the recording, so add this delay to be extra sure that it isn't. + QTest::qWait(200); + + if (mOutputFileBaseName.isEmpty()) { + mOutputFileBaseName = mOutputDir.absoluteFilePath(mQmlInputFileName); + mOutputFileBaseName.replace(".qml", ""); + } + + mByzanzOutputFileName = mOutputDir.absoluteFilePath(mOutputFileBaseName); + if (mHighQuality) { + mByzanzOutputFileName.append(QLatin1String(".flv")); + mGifFileName = mByzanzOutputFileName; + mGifFileName.replace(QLatin1String(".flv"), QLatin1String(".gif")); + } else { + mByzanzOutputFileName.append(QLatin1String(".gif")); + } + + const QPoint globalWindowPos = mWindow->mapToGlobal(QPoint(0, 0)); + QString args = QLatin1String("-d %1 -v %2 -x %3 -y %4 -w %5 -h %6 %7"); + args = args.arg(QString::number(mRecordingDuration)) + .arg(mRecordCursor ? QStringLiteral("-c") : QString()) + .arg(QString::number(globalWindowPos.x())) + .arg(QString::number(globalWindowPos.y())) + .arg(QString::number(mWindow->width())) + .arg(QString::number(mWindow->height())) + .arg(mByzanzOutputFileName); + + + // https://bugs.launchpad.net/ubuntu/+source/byzanz/+bug/1483581 + // It seems that byzanz-record will cut a recording short if there are no + // screen repaints, no matter what format it outputs. This can be tested + // manually from the command line by recording any section of the screen + // without moving the mouse and then running avprobe on the resulting .flv. + // Our workaround is to force view updates. + connect(&mEventTimer, SIGNAL(timeout()), mWindow, SLOT(update())); + mEventTimer.start(100); + + const ProcessWaitResult result = waitForProcessToStart(mByzanzProcess, byzanzProcessName, args); + if (!result.success) + QFAIL(qPrintable(result.errorMessage)); +} + +void GifRecorder::waitForFinish() +{ + // Give it an extra couple of seconds on top of its recording duration. + const int recordingDurationMs = mRecordingDuration * 1000; + const int waitDuration = recordingDurationMs + 2000; + QTRY_VERIFY_WITH_TIMEOUT(mByzanzProcessFinished, waitDuration); + + mEventTimer.stop(); + + if (!QFileInfo::exists(mByzanzOutputFileName)) { + const QString message = QString::fromLatin1( + "The process said it finished successfully, but %1 was not generated.").arg(mByzanzOutputFileName); + QFAIL(qPrintable(message)); + } + + if (mHighQuality) { + // Indicate the end of recording and the beginning of conversion. + QQmlComponent busyComponent(&mEngine); + busyComponent.setData("import QtQuick; import QtQuick.Controls; Rectangle { anchors.fill: parent; " \ + "BusyIndicator { width: 32; height: 32; anchors.centerIn: parent } }", QUrl()); + QCOMPARE(busyComponent.status(), QQmlComponent::Ready); + QQuickItem *busyRect = qobject_cast<QQuickItem*>(busyComponent.create()); + QVERIFY(busyRect); + busyRect->setParentItem(mWindow->contentItem()); + QSignalSpy spy(mWindow, SIGNAL(frameSwapped())); + QVERIFY(spy.wait()); + + // Start ffmpeg and send its output to imagemagick's convert command. + // Based on the example in the documentation for QProcess::setStandardOutputProcess(). + QProcess ffmpegProcess; + QProcess convertProcess; + ffmpegProcess.setStandardOutputProcess(&convertProcess); + + const QString ffmpegProcessName = QStringLiteral("ffmpeg"); + const QString ffmpegArgs = QString::fromLatin1("-i %1 -r 20 -f image2pipe -vcodec ppm -").arg(mByzanzOutputFileName); + ProcessWaitResult result = waitForProcessToStart(ffmpegProcess, ffmpegProcessName, ffmpegArgs); + if (!result.success) + QFAIL(qPrintable(result.errorMessage)); + + const QString convertProcessName = QStringLiteral("convert"); + const QString convertArgs = QString::fromLatin1("-delay 5 -loop 0 - %1").arg(mGifFileName); + + result = waitForProcessToStart(convertProcess, convertProcessName, convertArgs); + if (!result.success) + QFAIL(qPrintable(result.errorMessage)); + + result = waitForProcessToFinish(ffmpegProcess, ffmpegProcessName, waitDuration); + if (!result.success) + QFAIL(qPrintable(result.errorMessage)); + // Conversion can take a bit longer, so double the wait time. + result = waitForProcessToFinish(convertProcess, convertProcessName, waitDuration * 2); + if (!result.success) + QFAIL(qPrintable(result.errorMessage)); + + const QString gifsicleProcessName = QStringLiteral("gifsicle"); + const QString verbose = lcGifRecorder().isDebugEnabled() ? QStringLiteral("-V") : QString(); + + // --colors 256 stops the warning about local color tables being used, and results in smaller files, + // but it seems to affect the duration of the GIF (checked with exiftool), so we don't use it. + // For example, the slider GIF has the following attributes with and without the option: + // With Without + // Frame Count 57 61 + // Duration 2.85 seconds 3.05 seconds + // File size 11 kB 13 kB + const QString gifsicleArgs = QString::fromLatin1("%1 -b -O %2").arg(verbose).arg(mGifFileName); + QProcess gifsicleProcess; + if (lcGifRecorder().isDebugEnabled()) + gifsicleProcess.setProcessChannelMode(QProcess::ForwardedChannels); + result = waitForProcessToStart(gifsicleProcess, gifsicleProcessName, gifsicleArgs); + if (!result.success) + QFAIL(qPrintable(result.errorMessage)); + result = waitForProcessToFinish(gifsicleProcess, gifsicleProcessName, waitDuration); + if (!result.success) + QFAIL(qPrintable(result.errorMessage)); + + if (QFile::exists(mByzanzOutputFileName)) + QVERIFY(QFile::remove(mByzanzOutputFileName)); + } +} + +void GifRecorder::onByzanzError() +{ + const QString message = QString::fromLatin1("%1 failed to finish: %2"); + QFAIL(qPrintable(message.arg(byzanzProcessName).arg(mByzanzProcess.errorString()))); +} + +void GifRecorder::onByzanzFinished() +{ + qCDebug(lcGifRecorder) << byzanzProcessName << "finished"; + mByzanzProcessFinished = true; +} diff --git a/tests/manual/quickcontrols2/gifs/gifrecorder.h b/tests/manual/quickcontrols2/gifs/gifrecorder.h new file mode 100644 index 00000000000..30d06b111a4 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/gifrecorder.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GIFRECORDER_H +#define GIFRECORDER_H + +#include <QObject> +#include <QProcess> +#include <QQmlApplicationEngine> +#include <QQuickWindow> +#include <QDir> +#include <QString> +#include <QTimer> + +class GifRecorder : public QObject +{ + Q_OBJECT + +public: + GifRecorder(); + + void setRecordingDuration(int duration); + void setRecordCursor(bool recordCursor); + void setDataDirPath(const QString &path); + void setOutputDir(const QDir &dir); + void setOutputFileBaseName(const QString &fileBaseName); + void setQmlFileName(const QString &fileName); + void setView(QQuickWindow *mWindow); + void setHighQuality(bool highQuality); + + QQuickWindow *window() const; + + void start(); + bool hasStarted() const; + void waitForFinish(); + +private slots: + void onByzanzError(); + void onByzanzFinished(); + +private: + QString mDataDirPath; + QDir mOutputDir; + QString mOutputFileBaseName; + QString mByzanzOutputFileName; + QString mGifFileName; + QString mQmlInputFileName; + QQmlApplicationEngine mEngine; + QQuickWindow *mWindow; + bool mHighQuality; + int mRecordingDuration; + bool mRecordCursor; + + QProcess mByzanzProcess; + bool mByzanzProcessFinished; + QTimer mEventTimer; +}; + +#endif // GIFRECORDER_H diff --git a/tests/manual/quickcontrols2/gifs/gifs.pro b/tests/manual/quickcontrols2/gifs/gifs.pro new file mode 100644 index 00000000000..a5bb72c7926 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/gifs.pro @@ -0,0 +1,20 @@ +TEMPLATE = app +TARGET = tst_gifs + +QT += quick testlib +CONFIG += testcase +macos:CONFIG -= app_bundle + +HEADERS += \ + $$PWD/gifrecorder.h \ + $$PWD/eventcapturer.h \ + capturedevent.h + +SOURCES += \ + $$PWD/tst_gifs.cpp \ + $$PWD/gifrecorder.cpp \ + $$PWD/eventcapturer.cpp \ + capturedevent.cpp + +TESTDATA += \ + $$PWD/data/* diff --git a/tests/manual/quickcontrols2/gifs/tst_gifs.cpp b/tests/manual/quickcontrols2/gifs/tst_gifs.cpp new file mode 100644 index 00000000000..80c3fd9fef5 --- /dev/null +++ b/tests/manual/quickcontrols2/gifs/tst_gifs.cpp @@ -0,0 +1,1052 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest> +#include <QtQuick> + +#include "gifrecorder.h" +#include "eventcapturer.h" + +//#define GENERATE_EVENT_CODE + +class tst_Gifs : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + + void tumblerWrap(); + void slider(); + void sliderSnap_data(); + void sliderSnap(); + void rangeSlider(); + void busyIndicator(); + void switchGif(); + void button_data(); + void button(); + void tabBar(); + void menu(); + void swipeView(); + void swipeDelegate_data(); + void swipeDelegate(); + void swipeDelegateBehind(); + void delegates_data(); + void delegates(); + void dial_data(); + void dial(); + void scrollBar(); + void scrollBarSnap_data(); + void scrollBarSnap(); + void scrollIndicator(); + void progressBar_data(); + void progressBar(); + void triState_data(); + void triState(); + void checkables_data(); + void checkables(); + void comboBox(); + void stackView_data(); + void stackView(); + void drawer(); + void delayButton(); + +private: + void moveSmoothly(QQuickWindow *window, const QPoint &from, const QPoint &to, int movements, + QEasingCurve::Type easingCurveType = QEasingCurve::OutQuint, int movementDelay = 15); + void moveSmoothlyAlongArc(QQuickWindow *window, QPoint arcCenter, qreal distanceFromCenter, + qreal startAngleRadians, qreal endAngleRadians, QEasingCurve::Type easingCurveType = QEasingCurve::OutQuint); + + QString dataDirPath; + QDir outputDir; +}; + +void tst_Gifs::initTestCase() +{ + dataDirPath = QFINDTESTDATA("data"); + QVERIFY(!dataDirPath.isEmpty()); + qInfo() << "data directory:" << dataDirPath; + + outputDir = QDir(QDir::current().filePath("gifs")); + QVERIFY(outputDir.exists() || QDir::current().mkpath("gifs")); + qInfo() << "output directory:" << outputDir.absolutePath(); +} + +void tst_Gifs::moveSmoothly(QQuickWindow *window, const QPoint &from, const QPoint &to, + int movements, QEasingCurve::Type easingCurveType, int movementDelay) +{ + QEasingCurve curve(easingCurveType); + int xDifference = to.x() - from.x(); + int yDifference = to.y() - from.y(); + for (int movement = 0; movement < movements; ++movement) { + QPoint pos = QPoint( + from.x() + qRound(curve.valueForProgress(movement / qreal(qAbs(xDifference))) * xDifference), + from.y() + qRound(curve.valueForProgress(movement / qreal(qAbs(yDifference))) * yDifference)); + QTest::mouseMove(window, pos, movementDelay); + } +} + +QPoint posAlongArc(QPoint arcCenter, qreal startAngleRadians, qreal endAngleRadians, + qreal distanceFromCenter, qreal progress, QEasingCurve::Type easingCurveType) +{ + QEasingCurve curve(easingCurveType); + const qreal angle = startAngleRadians + curve.valueForProgress(progress) * (endAngleRadians - startAngleRadians); + return (arcCenter - QTransform().rotateRadians(angle).map(QPointF(0, distanceFromCenter))).toPoint(); +} + +void tst_Gifs::moveSmoothlyAlongArc(QQuickWindow *window, QPoint arcCenter, qreal distanceFromCenter, + qreal startAngleRadians, qreal endAngleRadians, QEasingCurve::Type easingCurveType) +{ + QEasingCurve curve(easingCurveType); + const qreal angleSpan = endAngleRadians - startAngleRadians; + const int movements = qAbs(angleSpan) * 20 + 20; + + for (int movement = 0; movement < movements; ++movement) { + const qreal progress = movement / qreal(movements); + const QPoint pos = posAlongArc(arcCenter, startAngleRadians, endAngleRadians, + distanceFromCenter, progress, easingCurveType); + QTest::mouseMove(window, pos, 15); + } +} + +void tst_Gifs::tumblerWrap() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(5); + gifRecorder.setQmlFileName("qtquickcontrols2-tumbler-wrap.qml"); + + gifRecorder.start(); + + // Left as an example. Usually EventCapturer code would be removed after + // the GIF has been generated. + QQuickWindow *window = gifRecorder.window(); + EventCapturer eventCapturer; +#ifdef GENERATE_EVENT_CODE + eventCapturer.setMoveEventTrimFlags(EventCapturer::TrimAll); + eventCapturer.startCapturing(window, 4000); +#else + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(89, 75), 326); + QTest::mouseMove(window, QPoint(89, 76), 31); + QTest::mouseMove(window, QPoint(89, 80), 10); + QTest::mouseMove(window, QPoint(93, 93), 10); + QTest::mouseMove(window, QPoint(95, 101), 10); + QTest::mouseMove(window, QPoint(97, 109), 11); + QTest::mouseMove(window, QPoint(101, 125), 10); + QTest::mouseMove(window, QPoint(103, 133), 11); + QTest::mouseMove(window, QPoint(103, 141), 11); + QTest::mouseMove(window, QPoint(105, 158), 10); + QTest::mouseMove(window, QPoint(105, 162), 13); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(105, 162), 0); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(154, 100), 1098); + QTest::mouseMove(window, QPoint(154, 99), 16); + QTest::mouseMove(window, QPoint(153, 98), 16); + QTest::mouseMove(window, QPoint(153, 95), 16); + QTest::mouseMove(window, QPoint(152, 91), 15); + QTest::mouseMove(window, QPoint(152, 87), 14); + QTest::mouseMove(window, QPoint(151, 83), 13); + QTest::mouseMove(window, QPoint(151, 86), 13); + QTest::mouseMove(window, QPoint(150, 79), 12); + QTest::mouseMove(window, QPoint(148, 73), 12); + QTest::mouseMove(window, QPoint(148, 68), 12); + QTest::mouseMove(window, QPoint(148, 60), 10); + QTest::mouseMove(window, QPoint(147, 50), 10); + QTest::mouseMove(window, QPoint(147, 40), 9); + QTest::mouseMove(window, QPoint(147, 30), 8); + QTest::mouseMove(window, QPoint(147, 20), 7); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(147, 20), 0); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(154, 100), 1000); + QTest::mouseMove(window, QPoint(147, 101), 16); + QTest::mouseMove(window, QPoint(147, 102), 16); + QTest::mouseMove(window, QPoint(147, 105), 16); + QTest::mouseMove(window, QPoint(148, 109), 15); + QTest::mouseMove(window, QPoint(148, 115), 14); + QTest::mouseMove(window, QPoint(148, 120), 13); + QTest::mouseMove(window, QPoint(150, 125), 13); + QTest::mouseMove(window, QPoint(151, 130), 12); + QTest::mouseMove(window, QPoint(151, 135), 12); + QTest::mouseMove(window, QPoint(153, 140), 12); + QTest::mouseMove(window, QPoint(153, 150), 10); + QTest::mouseMove(window, QPoint(153, 160), 10); + QTest::mouseMove(window, QPoint(153, 170), 9); + QTest::mouseMove(window, QPoint(155, 180), 8); + QTest::mouseMove(window, QPoint(155, 188), 7); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(20, 188), 0); +#endif + + gifRecorder.waitForFinish(); + + const auto capturedEvents = eventCapturer.capturedEvents(); + for (CapturedEvent event : capturedEvents) + qDebug().noquote() << event.cppCommand(); +} + +void tst_Gifs::slider() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(5); + gifRecorder.setHighQuality(true); + gifRecorder.setQmlFileName("qtquickcontrols2-slider.qml"); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *slider = window->property("slider").value<QQuickItem*>(); + QVERIFY(slider); + QQuickItem *handle = slider->property("handle").value<QQuickItem*>(); + QVERIFY(handle); + + const QPoint handleCenter = handle->mapToItem(window->contentItem(), + QPoint(handle->width() / 2, handle->height() / 2)).toPoint(); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, handleCenter, 100); + QPoint pos1 = handleCenter + QPoint(slider->width() * 0.3, 0); + moveSmoothly(window, handleCenter, pos1, pos1.x() - handleCenter.x(), QEasingCurve::OutQuint, 10); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos1, 20); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, handleCenter, 100); + const QPoint pos2 = QPoint(slider->width() - handleCenter.x() + slider->property("rightPadding").toInt(), handleCenter.y()); + moveSmoothly(window, pos1, pos2, pos2.x() - pos1.x(), QEasingCurve::OutQuint, 10); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos2, 20); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, pos2, 100); + moveSmoothly(window, pos2, handleCenter, qAbs(handleCenter.x() - pos2.x()), QEasingCurve::OutQuint, 10); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, handleCenter, 20); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::sliderSnap_data() +{ + QTest::addColumn<QString>("gifBaseName"); + QTest::addColumn<int>("snapMode"); + QTest::newRow("NoSnap") << "qtquickcontrols2-slider-nosnap" << 0; + QTest::newRow("SnapAlways") << "qtquickcontrols2-slider-snapalways" << 1; + QTest::newRow("SnapOnRelease") << "qtquickcontrols2-slider-snaponrelease" << 2; +} + +void tst_Gifs::sliderSnap() +{ + QFETCH(QString, gifBaseName); + QFETCH(int, snapMode); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(8); + gifRecorder.setHighQuality(true); + gifRecorder.setQmlFileName("qtquickcontrols2-slider-snap.qml"); + gifRecorder.setOutputFileBaseName(gifBaseName); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *slider = window->property("slider").value<QQuickItem*>(); + QVERIFY(slider); + QVERIFY(slider->setProperty("snapMode", QVariant(snapMode))); + QCOMPARE(slider->property("snapMode").toInt(), snapMode); + QQuickItem *handle = slider->property("handle").value<QQuickItem*>(); + QVERIFY(handle); + + const QPoint startPos(slider->property("leftPadding").toReal(), slider->height() / 2); + const int trackWidth = slider->property("availableWidth").toReal(); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, startPos, 200); + QPoint pos1 = startPos + QPoint(trackWidth * 0.3, 0); + moveSmoothly(window, startPos, pos1, pos1.x() - startPos.x(), QEasingCurve::OutQuint, 30); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos1, 0); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, startPos, 400); + const QPoint pos2 = startPos + QPoint(trackWidth * 0.6, 0); + moveSmoothly(window, pos1, pos2, pos2.x() - pos1.x(), QEasingCurve::OutQuint, 30); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos2, 0); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, pos2, 400); + moveSmoothly(window, pos2, startPos, qAbs(startPos.x() - pos2.x()) / 2, QEasingCurve::OutQuint, 30); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, startPos, 0); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::rangeSlider() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(7); + gifRecorder.setHighQuality(true); + gifRecorder.setQmlFileName("qtquickcontrols2-rangeslider.qml"); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *slider = window->property("slider").value<QQuickItem*>(); + QVERIFY(slider); + QObject *first = slider->property("first").value<QObject*>(); + QVERIFY(first); + QQuickItem *firstHandle = first->property("handle").value<QQuickItem*>(); + QVERIFY(firstHandle); + QObject *second = slider->property("second").value<QObject*>(); + QVERIFY(second); + QQuickItem *secondHandle = second->property("handle").value<QQuickItem*>(); + QVERIFY(secondHandle); + + const QPoint firstCenter = firstHandle->mapToItem(slider, + QPoint(firstHandle->width() / 2, firstHandle->height() / 2)).toPoint(); + const QPoint secondCenter = secondHandle->mapToItem(slider, + QPoint(secondHandle->width() / 2, secondHandle->height() / 2)).toPoint(); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, firstCenter, 100); + const QPoint firstTarget = firstCenter + QPoint(slider->width() * 0.25, 0); + moveSmoothly(window, firstCenter, firstTarget, firstTarget.x() - firstCenter.x()); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, firstTarget, 20); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, secondCenter, 100); + const QPoint secondTarget = secondCenter - QPoint(slider->width() * 0.25, 0); + moveSmoothly(window, secondCenter, secondTarget, qAbs(secondTarget.x() - secondCenter.x())); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, secondTarget, 20); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, secondTarget, 100); + moveSmoothly(window, secondTarget, secondCenter, qAbs(secondTarget.x() - secondCenter.x())); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, secondCenter, 20); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, firstTarget, 100); + moveSmoothly(window, firstTarget, firstCenter, firstTarget.x() - firstCenter.x()); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, firstCenter, 20); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::busyIndicator() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(6); + gifRecorder.setHighQuality(true); + gifRecorder.setQmlFileName("qtquickcontrols2-busyindicator.qml"); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + // Record nothing for a bit to make it smoother. + QTest::qWait(800 * 2); + + QQuickItem *busyIndicator = window->property("busyIndicator").value<QQuickItem*>(); + QVERIFY(busyIndicator); + + busyIndicator->setProperty("running", false); + + // 800 ms is the duration of one rotation animation cycle for BusyIndicator. + QTest::qWait(800 * 2); + + busyIndicator->setProperty("running", true); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::switchGif() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(3); + gifRecorder.setQmlFileName("qtquickcontrols2-switch.qml"); + gifRecorder.setHighQuality(true); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.8, window->height() / 2), 0); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.2, window->height() / 2), 800); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::button_data() +{ + QTest::addColumn<QString>("qmlFileName"); + QTest::newRow("button") << QString::fromLatin1("qtquickcontrols2-button.qml"); + QTest::newRow("button-flat") << QString::fromLatin1("qtquickcontrols2-button-flat.qml"); + QTest::newRow("button-highlighted") << QString::fromLatin1("qtquickcontrols2-button-highlighted.qml"); +} + +void tst_Gifs::button() +{ + QFETCH(QString, qmlFileName); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(3); + gifRecorder.setQmlFileName(qmlFileName); + // Seems to be necessary to show the Default button background. + gifRecorder.setHighQuality(true); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 700); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::tabBar() +{ + const QString qmlFileName = QStringLiteral("qtquickcontrols2-tabbar.qml"); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(4); + gifRecorder.setQmlFileName(qmlFileName); + gifRecorder.setHighQuality(true); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.6, window->height() / 2), 0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.6, window->height() / 2), 50); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.9, window->height() / 2), 400); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.9, window->height() / 2), 50); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.6, window->height() / 2), 800); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.6, window->height() / 2), 50); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.3, window->height() / 2), 400); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.3, window->height() / 2), 50); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::menu() +{ + const QString qmlFileName = QStringLiteral("qtquickcontrols2-menu.qml"); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(3); + gifRecorder.setQmlFileName(qmlFileName); + gifRecorder.setHighQuality(true); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + const QQuickItem *fileButton = window->property("fileButton").value<QQuickItem*>(); + QVERIFY(fileButton); + + const QPoint fileButtonCenter = fileButton->mapToScene(QPointF(fileButton->width() / 2, fileButton->height() / 2)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, fileButtonCenter, 0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, fileButtonCenter, 200); + + const QObject *menu = window->property("menu").value<QObject*>(); + QVERIFY(menu); + const QQuickItem *menuContentItem = menu->property("contentItem").value<QQuickItem*>(); + QVERIFY(menuContentItem); + + const QPoint lastItemPos = menuContentItem->mapToScene(QPointF(menuContentItem->width() / 2, menuContentItem->height() - 10)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, lastItemPos, 1000); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, lastItemPos, 300); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::swipeView() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(8); + gifRecorder.setQmlFileName(QStringLiteral("qtquickcontrols2-swipeview.qml")); + gifRecorder.setHighQuality(true); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *swipeView = window->property("swipeView").value<QQuickItem*>(); + QVERIFY(swipeView); + + QTest::qWait(1200); + swipeView->setProperty("currentIndex", 1); + QTest::qWait(2000); + swipeView->setProperty("currentIndex", 2); + QTest::qWait(2000); + swipeView->setProperty("currentIndex", 0); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::swipeDelegate_data() +{ + QTest::addColumn<QString>("qmlFileName"); + QTest::newRow("qtquickcontrols2-swipedelegate.qml") << QString::fromLatin1("qtquickcontrols2-swipedelegate.qml"); + QTest::newRow("qtquickcontrols2-swipedelegate-leading-trailing.qml") << QString::fromLatin1("qtquickcontrols2-swipedelegate-leading-trailing.qml"); +} + +void tst_Gifs::swipeDelegate() +{ + QFETCH(QString, qmlFileName); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(10); + gifRecorder.setQmlFileName(qmlFileName); + gifRecorder.setHighQuality(true); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *swipeDelegate = window->property("swipeDelegate").value<QQuickItem*>(); + QVERIFY(swipeDelegate); + + // Show left item. + const QPoint leftTarget = QPoint(swipeDelegate->width() * 0.2, 0); + const QPoint rightTarget = QPoint(swipeDelegate->width() * 0.8, 0); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, leftTarget, 100); + const int movements = rightTarget.x() - leftTarget.x(); + moveSmoothly(window, leftTarget, rightTarget, movements, QEasingCurve::OutQuint, 5); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, rightTarget, 20); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, rightTarget, 1000); + moveSmoothly(window, rightTarget, leftTarget, movements, QEasingCurve::OutQuint, 5); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, leftTarget, 20); + + QTest::qWait(1000); + + // Show right item. + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, rightTarget, 1000); + moveSmoothly(window, rightTarget, leftTarget, movements, QEasingCurve::OutQuint, 5); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, leftTarget, 20); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, leftTarget, 1000); + moveSmoothly(window, leftTarget, rightTarget, movements, QEasingCurve::OutQuint, 5); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, rightTarget, 20); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::swipeDelegateBehind() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(14); + gifRecorder.setQmlFileName(QStringLiteral("qtquickcontrols2-swipedelegate-behind.qml")); + gifRecorder.setHighQuality(true); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *swipeDelegate = window->property("swipeDelegate").value<QQuickItem*>(); + QVERIFY(swipeDelegate); + + // Show wrapping around left item. + const QPoint leftTarget = QPoint(swipeDelegate->width() * 0.2, 0); + const QPoint rightTarget = QPoint(swipeDelegate->width() * 0.8, 0); + const int movements = rightTarget.x() - leftTarget.x(); + for (int i = 0; i < 4; ++i) { + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, leftTarget, 100); + moveSmoothly(window, leftTarget, rightTarget, movements, QEasingCurve::OutQuint, 5); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, rightTarget, 20); + + QTest::qWait(500); + } + + QTest::qWait(1000); + + // Show wrapping around right item. + for (int i = 0; i < 4; ++i) { + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, rightTarget, 100); + moveSmoothly(window, rightTarget, leftTarget, movements, QEasingCurve::OutQuint, 5); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, leftTarget, 20); + + QTest::qWait(500); + } + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::delegates_data() +{ + QTest::addColumn<QString>("name"); + QTest::addColumn<QList<int> >("pressIndices"); + QTest::addColumn<int>("duration"); + + QTest::newRow("ItemDelegate") << "itemdelegate" << (QList<int> { 0, 1, 2 }) << 5; + QTest::newRow("CheckDelegate") << "checkdelegate" << (QList<int> { 0, 0 }) << 5; + QTest::newRow("RadioDelegate") << "radiodelegate" << (QList<int> { 1, 0 }) << 5; + QTest::newRow("SwitchDelegate") << "switchdelegate" << (QList<int> { 0, 0 }) << 5; +} + +void tst_Gifs::delegates() +{ + QFETCH(QString, name); + QFETCH(QList<int>, pressIndices); + QFETCH(int, duration); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(duration); + gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-%1.qml").arg(name)); + gifRecorder.setHighQuality(true); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *delegate = window->property("delegate").value<QQuickItem*>(); + QVERIFY(delegate); + + for (int i = 0; i < pressIndices.size(); ++i) { + const int pressIndex = pressIndices.at(i); + const QPoint delegateCenter(delegate->mapToScene(QPointF( + delegate->width() / 2, delegate->height() / 2 + delegate->height() * pressIndex)).toPoint()); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, delegateCenter, i == 0 ? 200 : 1000); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, delegateCenter, 400); + } + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::dial_data() +{ + QTest::addColumn<QString>("name"); + + QTest::newRow("dial-wrap") << "wrap"; + QTest::newRow("dial-no-wrap") << "no-wrap"; +} + +void tst_Gifs::dial() +{ + QFETCH(QString, name); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(10); + gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-dial-%1.qml").arg(name)); + gifRecorder.setHighQuality(false); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *dial = window->property("dial").value<QQuickItem*>(); + QVERIFY(dial); + + const QPoint arcCenter = dial->mapToScene(QPoint(dial->width() / 2, dial->height() / 2)).toPoint(); + const qreal distanceFromCenter = dial->height() * 0.25; + // Go a bit past the actual min/max to ensure that we get the full range. + const qreal minAngle = qDegreesToRadians(-170.0); + const qreal maxAngle = qDegreesToRadians(170.0); + // Drag from start to end. + qreal startAngle = minAngle; + qreal endAngle = maxAngle; + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, posAlongArc( + arcCenter, startAngle, endAngle, distanceFromCenter, 0, QEasingCurve::InOutQuad), 30); + + moveSmoothlyAlongArc(window, arcCenter, distanceFromCenter, startAngle, endAngle, QEasingCurve::InOutQuad); + + // Come back from the end a bit. + startAngle = endAngle; + endAngle -= qDegreesToRadians(50.0); + moveSmoothlyAlongArc(window, arcCenter, distanceFromCenter, startAngle, endAngle, QEasingCurve::InOutQuad); + + // Try to drag over max to show what happens with different wrap settings. + startAngle = endAngle; + endAngle = qDegreesToRadians(270.0); + moveSmoothlyAlongArc(window, arcCenter, distanceFromCenter, startAngle, endAngle, QEasingCurve::InOutQuad); + + // Go back to the start so that it loops nicely. + startAngle = endAngle; + endAngle = minAngle; + moveSmoothlyAlongArc(window, arcCenter, distanceFromCenter, startAngle, endAngle, QEasingCurve::InOutQuad); + + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, posAlongArc( + arcCenter, startAngle, endAngle, distanceFromCenter, 1, QEasingCurve::InOutQuad), 30); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::checkables_data() +{ + QTest::addColumn<QString>("name"); + QTest::addColumn<QList<int> >("pressIndices"); + + QTest::newRow("checkbox") << "checkbox" << (QList<int> { 1, 2, 2, 1 }); + QTest::newRow("radiobutton") << "radiobutton" << (QList<int> { 1, 2, 1, 0 }); +} + +void tst_Gifs::checkables() +{ + QFETCH(QString, name); + QFETCH(QList<int>, pressIndices); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(6); + gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-%1.qml").arg(name)); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + + for (int i = 0; i < pressIndices.size(); ++i) { + const int pressIndex = pressIndices.at(i); + const QString controlId = QString::fromLatin1("control%1").arg(pressIndex + 1); + QQuickItem *control = window->property(qPrintable(controlId)).value<QQuickItem*>(); + QVERIFY(control); + + const QPoint pos = control->mapToScene(QPointF(control->width() / 2, control->height() / 2)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, pos, 800); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, pos, 300); + } + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::comboBox() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(6); + gifRecorder.setQmlFileName(QStringLiteral("qtquickcontrols2-combobox.qml")); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *comboBox = window->property("comboBox").value<QQuickItem*>(); + QVERIFY(comboBox); + + // Open the popup. + const QPoint center = comboBox->mapToScene( + QPoint(comboBox->width() / 2, comboBox->height() / 2)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, center, 800); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, center, 80); + + // Select the third item. + QObject *popup = comboBox->property("popup").value<QObject*>(); + QVERIFY(popup); + QQuickItem *popupContent = popup->property("contentItem").value<QQuickItem*>(); + QVERIFY(popupContent); + const QPoint lastItemPos = popupContent->mapToScene( + QPoint(popupContent->width() / 2, popupContent->height() * 0.8)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, lastItemPos, 600); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, lastItemPos, 200); + + // Open the popup. + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, center, 1500); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, center, 80); + + // Select the first item. + const QPoint firstItemPos = popupContent->mapToScene( + QPoint(popupContent->width() / 2, popupContent->height() * 0.2)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, firstItemPos, 600); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, firstItemPos, 200); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::triState_data() +{ + QTest::addColumn<QString>("name"); + + QTest::newRow("checkbox-tristate") << "checkbox-tristate"; + QTest::newRow("checkdelegate-tristate") << "checkdelegate-tristate"; +} + +void tst_Gifs::triState() +{ + QFETCH(QString, name); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(6); + gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-%1.qml").arg(name)); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *english = window->property("english").value<QQuickItem*>(); + QVERIFY(english); + QQuickItem *norwegian = window->property("norwegian").value<QQuickItem*>(); + QVERIFY(norwegian); + + const QPoint englishCenter = english->mapToScene( + QPointF(english->width() / 2, english->height() / 2)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, englishCenter, 1000); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, englishCenter, 300); + + const QPoint norwegianCenter = norwegian->mapToScene( + QPointF(norwegian->width() / 2, norwegian->height() / 2)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, norwegianCenter, 1000); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, norwegianCenter, 300); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, norwegianCenter, 1000); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, norwegianCenter, 300); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, englishCenter, 1000); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, englishCenter, 300); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::scrollBar() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(6); + gifRecorder.setQmlFileName("qtquickcontrols2-scrollbar.qml"); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *scrollBar = window->property("scrollBar").value<QQuickItem*>(); + QVERIFY(scrollBar); + + // Flick in the center of the screen to show that there's a scroll bar. + const QPoint lhsWindowBottom = QPoint(0, window->height() - 1); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, lhsWindowBottom, 100); + QTest::mouseMove(window, lhsWindowBottom - QPoint(0, 10), 30); + QTest::mouseMove(window, lhsWindowBottom - QPoint(0, 30), 30); + QTest::mouseMove(window, lhsWindowBottom - QPoint(0, 60), 30); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, lhsWindowBottom - QPoint(0, 100), 30); + + // Scroll with the scroll bar. + const QPoint rhsWindowBottom = QPoint(window->width() - 1, window->height() - 1); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, rhsWindowBottom, 2000); + const QPoint rhsWindowTop = QPoint(window->width() - 1, 1); + moveSmoothly(window, rhsWindowBottom, rhsWindowTop, + qAbs(rhsWindowTop.y() - rhsWindowBottom.y()), QEasingCurve::InCubic, 10); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, rhsWindowTop, 20); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::scrollBarSnap_data() +{ + QTest::addColumn<QString>("gifBaseName"); + QTest::addColumn<int>("snapMode"); + QTest::newRow("NoSnap") << "qtquickcontrols2-scrollbar-nosnap" << 0; + QTest::newRow("SnapAlways") << "qtquickcontrols2-scrollbar-snapalways" << 1; + QTest::newRow("SnapOnRelease") << "qtquickcontrols2-scrollbar-snaponrelease" << 2; +} + +void tst_Gifs::scrollBarSnap() +{ + QFETCH(QString, gifBaseName); + QFETCH(int, snapMode); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(8); + gifRecorder.setHighQuality(true); + gifRecorder.setQmlFileName("qtquickcontrols2-scrollbar-snap.qml"); + gifRecorder.setOutputFileBaseName(gifBaseName); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QQuickItem *scrollbar = window->property("scrollbar").value<QQuickItem*>(); + QVERIFY(scrollbar); + QVERIFY(scrollbar->setProperty("snapMode", QVariant(snapMode))); + QCOMPARE(scrollbar->property("snapMode").toInt(), snapMode); + + const QPoint startPos(scrollbar->property("leftPadding").toReal(), scrollbar->y() + scrollbar->height() / 2); + const int availableWidth = scrollbar->property("availableWidth").toReal(); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, startPos, 200); + const QPoint pos1 = startPos + QPoint(availableWidth * 0.3, 0); + moveSmoothly(window, startPos, pos1, pos1.x() - startPos.x(), QEasingCurve::OutQuint, 30); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos1, 0); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, pos1, 400); + const QPoint pos2 = startPos + QPoint(availableWidth * 0.6, 0); + moveSmoothly(window, pos1, pos2, pos2.x() - pos1.x(), QEasingCurve::OutQuint, 30); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos2, 0); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, pos2, 400); + moveSmoothly(window, pos2, startPos, pos2.x() - startPos.x(), QEasingCurve::OutQuint, 30); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, startPos, 0); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::scrollIndicator() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(6); + gifRecorder.setQmlFileName("qtquickcontrols2-scrollindicator.qml"); + + gifRecorder.start(); + + // Flick in the center of the screen to show that there's a scroll indicator. + QQuickWindow *window = gifRecorder.window(); + const QPoint windowBottom = QPoint(0, window->height() - 1); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, windowBottom, 100); + QTest::mouseMove(window, windowBottom - QPoint(0, 10), 30); + QTest::mouseMove(window, windowBottom - QPoint(0, 30), 30); + QTest::mouseMove(window, windowBottom - QPoint(0, 60), 30); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, windowBottom - QPoint(0, 100), 30); + + // Scroll back down. + const QPoint windowTop = QPoint(0, 0); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, windowTop, 2000); + QTest::mouseMove(window, windowTop + QPoint(0, 10), 30); + QTest::mouseMove(window, windowTop + QPoint(0, 30), 30); + QTest::mouseMove(window, windowTop + QPoint(0, 60), 30); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, windowTop + QPoint(0, 100), 30); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::progressBar_data() +{ + QTest::addColumn<bool>("indeterminate"); + + QTest::newRow("indeterminate:false") << false; + QTest::newRow("indeterminate:true") << true; +} + +void tst_Gifs::progressBar() +{ + QFETCH(bool, indeterminate); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(4); + gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-progressbar%1").arg( + indeterminate ? QLatin1String("-indeterminate.qml") : QLatin1String(".qml"))); + + gifRecorder.start(); + gifRecorder.waitForFinish(); +} + +void tst_Gifs::stackView_data() +{ + QTest::addColumn<QString>("name"); + QTest::addColumn<int>("duration"); + + QTest::newRow("push") << "push" << 8; + QTest::newRow("pop") << "pop" << 6; + QTest::newRow("unwind") << "unwind" << 6; + QTest::newRow("replace") << "replace" << 6; +} + +void tst_Gifs::stackView() +{ + QFETCH(QString, name); + QFETCH(int, duration); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(duration); + gifRecorder.setHighQuality(true); + gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-stackview-%1.qml").arg(name)); + + gifRecorder.start(); + gifRecorder.waitForFinish(); +} + +void tst_Gifs::drawer() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(4); + gifRecorder.setHighQuality(true); + gifRecorder.setQmlFileName("qtquickcontrols2-drawer.qml"); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QObject *drawer = window->property("drawer").value<QObject*>(); + qreal width = drawer->property("width").toReal(); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1), 100); + moveSmoothly(window, QPoint(1, 1), QPoint(width, 1), width, QEasingCurve::InOutBack, 1); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(width, 1), 30); + + QTest::qWait(1000); + QMetaObject::invokeMethod(drawer, "close"); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::delayButton() +{ + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(9); + gifRecorder.setQmlFileName("qtquickcontrols2-delaybutton.qml"); + + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 1500); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 1000); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 200); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 1500); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 1730); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 1000); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 2070); // 0.69 * 3000 + + gifRecorder.waitForFinish(); +} + +QTEST_MAIN(tst_Gifs) + +#include "tst_gifs.moc" diff --git a/tests/manual/quickcontrols2/headerview/CMakeLists.txt b/tests/manual/quickcontrols2/headerview/CMakeLists.txt new file mode 100644 index 00000000000..4c4ae94a56e --- /dev/null +++ b/tests/manual/quickcontrols2/headerview/CMakeLists.txt @@ -0,0 +1,54 @@ +# Generated from headerview.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(headerview LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## headerview Binary: +##################################################################### + +qt_internal_add_manual_test(headerview + GUI + SOURCES + main.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Qml + Qt::Quick + Qt::QuickControls2 + Qt::QuickControls2Private + Qt::QuickPrivate + Qt::QuickTemplates2 + Qt::QuickTemplates2Private +) + +# Resources: +set(qmake_immediate_resource_files + "main.qml" +) + +qt_internal_add_resource(headerview "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + + +#### Keys ignored in scope 1:.:.:headerview.pro:<TRUE>: +# TEMPLATE = "app" + +## Scopes: +##################################################################### + +#### Keys ignored in scope 2:.:.:headerview.pro:QNX: +# target.path = "/tmp/$${TARGET}/bin" + +#### Keys ignored in scope 4:.:.:headerview.pro:UNIX AND NOT ANDROID: +# target.path = "/opt/$${TARGET}/bin" + +#### Keys ignored in scope 5:.:.:headerview.pro:NOT target.path_ISEMPTY: +# INSTALLS = "target" diff --git a/tests/manual/quickcontrols2/headerview/headerview.pro b/tests/manual/quickcontrols2/headerview/headerview.pro new file mode 100644 index 00000000000..474cc9214a5 --- /dev/null +++ b/tests/manual/quickcontrols2/headerview/headerview.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = headerview +QT += qml quick quick-private quickcontrols2 quickcontrols2-private \ + quicktemplates2-private quicktemplates2 +SOURCES += main.cpp +RESOURCES += main.qml +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target diff --git a/tests/manual/quickcontrols2/headerview/main.cpp b/tests/manual/quickcontrols2/headerview/main.cpp new file mode 100644 index 00000000000..a11f862704f --- /dev/null +++ b/tests/manual/quickcontrols2/headerview/main.cpp @@ -0,0 +1,217 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module 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 <QAbstractTableModel> +#include <QDebug> +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +class TestTableModel : public QAbstractTableModel { + Q_OBJECT + Q_PROPERTY(int rowCount READ rowCount WRITE setRowCount NOTIFY rowCountChanged) + Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount NOTIFY columnCountChanged) + +public: + TestTableModel(QObject *parent = nullptr) + : QAbstractTableModel(parent) + { + } + + int rowCount(const QModelIndex & = QModelIndex()) const override + { + return m_rows; + } + virtual void setRowCount(int count) + { + beginResetModel(); + m_rows = count; + emit rowCountChanged(); + endResetModel(); + } + + int columnCount(const QModelIndex & = QModelIndex()) const override + { + return m_cols; + } + virtual void setColumnCount(int count) + { + beginResetModel(); + m_cols = count; + emit columnCountChanged(); + endResetModel(); + } + + int indexValue(const QModelIndex &index) const + { + return index.row() + (index.column() * rowCount()); + } + + Q_INVOKABLE QModelIndex toQModelIndex(int serialIndex) + { + return createIndex(serialIndex % rowCount(), serialIndex / rowCount()); + } + + Q_INVOKABLE QVariant data(int row, int col) + { + return data(createIndex(row, col), Qt::DisplayRole); + } + QVariant data(const QModelIndex &index, int role) const override + { + if (!index.isValid()) + return QVariant(); + + switch (role) { + case Qt::DisplayRole: + return QLatin1String("Foo"); + case Qt::EditRole: + return m_checkedCells.contains(indexValue(index)); + default: + return QVariant(); + } + } + + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole) override + { + + if (role != Qt::EditRole) + return false; + + int i = indexValue(index); + bool checked = value.toBool(); + if (checked == m_checkedCells.contains(i)) + return false; + + if (checked) + m_checkedCells.insert(i); + else + m_checkedCells.remove(i); + + emit dataChanged(index, index, { role }); + return true; + } + + Q_INVOKABLE QHash<int, QByteArray> roleNames() const override + { + return { + { Qt::DisplayRole, "display" }, + { Qt::EditRole, "edit" } + }; + } + +signals: + void rowCountChanged(); + void columnCountChanged(); + +private: + int m_rows = 0; + int m_cols = 0; + + QSet<int> m_checkedCells; +}; + +class TestTableModelWithHeader : public TestTableModel { + + Q_OBJECT +public: + void setRowCount(int count) override + { + vData.resize(count); + TestTableModel::setRowCount(count); + } + + void setColumnCount(int count) override + { + hData.resize(count); + TestTableModel::setColumnCount(count); + } + + Q_INVOKABLE QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const override + { + const bool isHorizontal = orientation == Qt::Horizontal; + auto sectionCount = isHorizontal ? columnCount() : rowCount(); + if (section < 0 || section >= sectionCount) + return QVariant(); + switch (role) { + case Qt::DisplayRole: + return (isHorizontal ? QString::fromLatin1("Column %1") : QString::fromLatin1("Row %1")).arg(section); + case Qt::EditRole: { + auto &data = isHorizontal ? hData : vData; + return data[section].toString(); + } + default: + return QVariant(); + } + } + + Q_INVOKABLE bool setHeaderData(int section, Qt::Orientation orientation, + const QVariant &value, int role = Qt::EditRole) override + { + qDebug() << Q_FUNC_INFO + << "section:" << section + << "orient:" << orientation + << "value:" << value + << "role:" << QAbstractItemModel::roleNames()[role]; + auto sectionCount = orientation == Qt::Horizontal ? columnCount() : rowCount(); + if (section < 0 || section >= sectionCount) + return false; + auto &data = orientation == Qt::Horizontal ? hData : vData; + data[section] = value; + emit headerDataChanged(orientation, section, section); + return true; + } + +private: + QList<QVariant> hData, vData; +}; + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType<TestTableModel>("TestTableModel", 0, 1, "TestTableModel"); + qmlRegisterType<TestTableModelWithHeader>("TestTableModelWithHeader", 0, 1, "TestTableModelWithHeader"); + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + + return app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/quickcontrols2/headerview/main.qml b/tests/manual/quickcontrols2/headerview/main.qml new file mode 100644 index 00000000000..abce1c00e04 --- /dev/null +++ b/tests/manual/quickcontrols2/headerview/main.qml @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQml.Models +import QtQuick +import QtQuick.Controls +import QtQuick.Shapes +import QtQuick.Window +import Qt.labs.qmlmodels +import TestTableModelWithHeader + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("HeaderView Test") + + TestTableModelWithHeader { + id: tableModel + rowCount: 50 + columnCount: 80 + } + + TableView { + id: tableView + anchors.top: parent.top + anchors.topMargin: horizontalHeader.height + rowSpacing + anchors.left: parent.left + anchors.leftMargin: verticalHeader.width + columnSpacing + model: tableModel + rightMargin: 100 + bottomMargin: 100 + columnSpacing: 4 + rowSpacing: 4 + syncDirection: Qt.Vertical | Qt.Horizontal + implicitWidth: parent.width + columnSpacing + implicitHeight: parent.height + rowSpacing + clip: true + delegate: Rectangle { + implicitWidth: 150 + implicitHeight: 50 + color: "#e6ecf5" + + CheckBox { + anchors.fill: parent + text: model.display + checked: model.edit + leftPadding: 12 + onClicked: model.edit = checked + } + } + } + + HorizontalHeaderView { + id: horizontalHeader + objectName: "horizontalHeader" + anchors.top: parent.top + anchors.left: tableView.left + syncView: tableView + clip: true + } + + VerticalHeaderView { + id: verticalHeader + objectName: "verticalHeader" + anchors.top: tableView.top + syncView: tableView + clip: true + } + + ToolButton { + width: verticalHeader.width + height: horizontalHeader.height + onClicked: { + horizontalHeader.contentX = 0 + verticalHeader.contentY = 0 + } + } +} diff --git a/tests/manual/quickcontrols2/manual.pro b/tests/manual/quickcontrols2/manual.pro new file mode 100644 index 00000000000..7010d902f1d --- /dev/null +++ b/tests/manual/quickcontrols2/manual.pro @@ -0,0 +1,17 @@ +TEMPLATE = subdirs +SUBDIRS += \ + buttons \ + fonts \ + gifs \ + headerview \ + qquickdialog \ + screenshots \ + styles \ + styles-cover-flow \ + systemtrayicon \ + testbench \ + viewinqwidget + +qtConfig(systemtrayicon): SUBDIRS += systemtrayicon + +qtHaveModule(widgets): SUBDIRS += viewinqwidget diff --git a/tests/manual/quickcontrols2/nativestyle/.gitignore b/tests/manual/quickcontrols2/nativestyle/.gitignore new file mode 100644 index 00000000000..fab7372d796 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/tests/manual/quickcontrols2/nativestyle/Buttons.qml b/tests/manual/quickcontrols2/nativestyle/Buttons.qml new file mode 100644 index 00000000000..d5eb2a9cd3d --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/Buttons.qml @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "Buttons" + + Row { + spacing: container.rowSpacing + + Button { + text: "Default" + } + + Button { + text: "Disabled" + enabled: false + } + + Button { + text: "Small" + property bool qqc2_style_small + } + + Button { + text: "Mini" + property bool qqc2_style_mini + } + } + + Row { + spacing: container.rowSpacing + + Button { + text: "Explicit height" + height: 50 + } + + Button { + text: "Explicit width" + width: 200 + } + } + + Row { + spacing: container.rowSpacing + + Button { + text: "Highlighted" + highlighted: true + } + + Button { + text: "Flat" + flat: true + } + + Button { + text: "Checkable" + checkable: true + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/CMakeLists.txt b/tests/manual/quickcontrols2/nativestyle/CMakeLists.txt new file mode 100644 index 00000000000..bea89a339b2 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CMakeLists.txt @@ -0,0 +1,84 @@ +# Generated from desktopgallery.pro. +# special case skip regeneration +# Remove the skip, after somebody figures out if this is supposed +# to be a manual test, or a full-blown project like it is now +# because it was copied over from an example. + +cmake_minimum_required(VERSION 3.16) +project(desktopgallery LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/desktopgallery") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS QuickControls2) + +qt_add_executable(desktopgallery + main.cpp +) +target_link_libraries(desktopgallery PUBLIC + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) + + +# Resources: +set(qmake_immediate_resource_files + "Buttons.qml" + "CheckBoxes.qml" + "ComboBoxes.qml" + "ControlContainer.qml" + "CustomButtons.qml" + "CustomCheckBoxes.qml" + "CustomComboBoxes.qml" + "CustomDials.qml" + "CustomFrames.qml" + "CustomProgressBars.qml" + "CustomRadioButtons.qml" + "CustomScrollBars.qml" + "CustomSliders.qml" + "CustomSpinBoxes.qml" + "CustomTextAreas.qml" + "CustomTextFields.qml" + "Dials.qml" + "Frames.qml" + "ProgressBars.qml" + "RadioButtons.qml" + "ScrollBars.qml" + "Sliders.qml" + "SlidersMini.qml" + "SlidersSmall.qml" + "SpinBoxes.qml" + "TextAreas.qml" + "TextFields.qml" + "checkbox-icon.png" + "checkbox-icon16.png" + "checkbox-icon@2x.png" + "main.qml" +) + +qt6_add_resources(desktopgallery "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + +install(TARGETS desktopgallery + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/tests/manual/quickcontrols2/nativestyle/CheckBoxes.qml b/tests/manual/quickcontrols2/nativestyle/CheckBoxes.qml new file mode 100644 index 00000000000..c24e9a54d9b --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CheckBoxes.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "CheckBoxes" + + Row { + spacing: container.rowSpacing + + CheckBox { + text: "Default" + checked: true + } + + CheckBox { + text: "Disabled" + enabled: false + } + + CheckBox { + text: "Tri-state" + tristate: true + checkState: Qt.PartiallyChecked + } + + CheckBox { + text: "Small" + property bool qqc2_style_small + } + + CheckBox { + text: "Mini" + property bool qqc2_style_mini + checked: true + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/ComboBoxes.qml b/tests/manual/quickcontrols2/nativestyle/ComboBoxes.qml new file mode 100644 index 00000000000..21dd5b091ca --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/ComboBoxes.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "ComboBoxes" + + Row { + spacing: container.rowSpacing + + ComboBox { + model: [ "Default", "Banana", "Apple", "Coconut" ] + } + + ComboBox { + model: [ "Disabled", "Banana", "Apple", "Coconut" ] + enabled: false + } + + ComboBox { + model: [ "Small", "Banana", "Apple", "Coconut" ] + property bool qqc2_style_small + } + + ComboBox { + model: [ "Mini", "Banana", "Apple", "Coconut" ] + property bool qqc2_style_mini + } + } + + Row { + spacing: container.rowSpacing + + ComboBox { + model: [ "Default", "Banana", "Apple", "Coconut" ] + editable: true + } + + ComboBox { + model: [ "Disabled", "Banana", "Apple", "Coconut" ] + enabled: false + editable: true + } + + ComboBox { + model: [ "Small", "Banana", "Apple", "Coconut" ] + editable: true + property bool qqc2_style_small + } + + ComboBox { + model: [ "Mini", "Banana", "Apple", "Coconut" ] + editable: true + property bool qqc2_style_mini + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/ControlContainer.qml b/tests/manual/quickcontrols2/nativestyle/ControlContainer.qml new file mode 100644 index 00000000000..5ac9f6bb182 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/ControlContainer.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: 7 + implicitHeight: groupBox.height + + property alias title: groupBox.title + property real rowSpacing: 20 + + default property alias data: layout.data + + GroupBox { + id: groupBox + anchors.left: parent.left + anchors.right: parent.right + + ColumnLayout { + id: layout + spacing: 15 + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/CustomButtons.qml b/tests/manual/quickcontrols2/nativestyle/CustomButtons.qml new file mode 100644 index 00000000000..6a01faeda59 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CustomButtons.qml @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "Buttons" + + Row { + spacing: container.rowSpacing + + Button { + id: buttonWithCustomContentItem + text: "Custom contentItem" + contentItem: Rectangle { + implicitWidth: 120 + implicitHeight: il.implicitHeight + color: buttonWithCustomContentItem.pressed ? "green" : "lightGreen" + Text { + id: il + text: buttonWithCustomContentItem.text + anchors.centerIn: parent + } + } + } + + Button { + id: cb + text: "Custom background" + background: Rectangle { + implicitWidth: 200 + implicitHeight: 30 + radius: 5 + color: cb.pressed ? "LightGray" : "gray" + } + } + + Button { + id: cb2 + text: "All custom" + background: Rectangle { + implicitWidth: 200 + implicitHeight: 30 + radius: 5 + color: cb2.pressed ? "LightGray" : "gray" + } + contentItem: Rectangle { + implicitWidth: il2.implicitWidth + implicitHeight: il2.implicitHeight + radius: 3 + color: "lightgray" + Text { + id: il2 + text: cb2.text + anchors.centerIn: parent + } + } + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/CustomCheckBoxes.qml b/tests/manual/quickcontrols2/nativestyle/CustomCheckBoxes.qml new file mode 100644 index 00000000000..00dc7378f4c --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CustomCheckBoxes.qml @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.impl + +ControlContainer { + id: container + title: "CheckBoxes" + + Row { + spacing: container.rowSpacing + + CheckBox { + id: customContentItem + text: "Custom content item" + contentItem: Text { + text: customContentItem.text + color: "green" + leftPadding: customContentItem.indicator.width + customContentItem.spacing + } + } + + CheckBox { + id: customIndicator + text: "Custom indicator" + indicator: Rectangle { + implicitWidth: 15 + implicitHeight: 15 + + x: customIndicator.text ? customIndicator.leftPadding : customIndicator.leftPadding + (customIndicator.availableWidth - width) / 2 + y: customIndicator.topPadding + (customIndicator.availableHeight - height) / 2 + + color: customIndicator.down ? customIndicator.palette.light : customIndicator.palette.base + border.color: "green" + border.width: 2 + + ColorImage { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + defaultColor: "#353637" + scale: 0.5 + color: "green" + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png" + visible: customIndicator.checkState === Qt.Checked + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 16 + height: 3 + color: customIndicator.palette.text + visible: customIndicator.checkState === Qt.PartiallyChecked + } + } + } + + CheckBox { + id: allCustom + text: "All custom" + + contentItem: Text { + text: allCustom.text + color: "green" + leftPadding: allCustom.indicator.width + allCustom.spacing + rightPadding: allCustom.indicator.width + allCustom.spacing + } + + indicator: Rectangle { + implicitWidth: 15 + implicitHeight: 15 + + x: allCustom.text ? allCustom.leftPadding : allCustom.leftPadding + (allCustom.availableWidth - width) / 2 + y: allCustom.topPadding + (allCustom.availableHeight - height) / 2 + + color: allCustom.down ? allCustom.palette.light : allCustom.palette.base + border.color: "green" + border.width: 2 + + ColorImage { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + defaultColor: "#353637" + scale: 0.5 + color: "green" + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png" + visible: allCustom.checkState === Qt.Checked + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 16 + height: 3 + color: "green" + visible: allCustom.checkState === Qt.PartiallyChecked + } + } + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/CustomComboBoxes.qml b/tests/manual/quickcontrols2/nativestyle/CustomComboBoxes.qml new file mode 100644 index 00000000000..a51cca94016 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CustomComboBoxes.qml @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.impl + +ControlContainer { + id: container + title: "ComboBoxes" + + Row { + spacing: container.rowSpacing + + ComboBox { + id: control + model: [ "Custom background", "Banana", "Apple", "Coconut" ] + background: Rectangle { + implicitWidth: 200 + implicitHeight: 20 + color: control.down ? control.palette.mid : control.palette.button + border.color: "green" + border.width: 1 + } + indicator: ColorImage { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + color: control.palette.dark + defaultColor: "#353637" + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/double-arrow.png" + opacity: enabled ? 1 : 0.3 + } + } + + ComboBox { + model: [ "Banana", "Apple", "Coconut" ] + contentItem: Rectangle { + implicitWidth: text.implicitWidth + color: "lightGreen" + Text { + id: text + text: "Custom content item" + anchors.centerIn: parent + } + } + } + + } + + Row { + spacing: container.rowSpacing + + ComboBox { + id: control2 + model: [ "Custom background", "Banana", "Apple", "Coconut" ] + editable: true + background: Rectangle { + implicitWidth: 200 + implicitHeight: 20 + color: control2.down ? control2.palette.mid : control2.palette.button + border.color: "green" + border.width: 1 + } + indicator: ColorImage { + x: control2.mirrored ? control2.padding : control2.width - width - control2.padding + y: control2.topPadding + (control2.availableHeight - height) / 2 + color: control2.palette.dark + defaultColor: "#353637" + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/double-arrow.png" + opacity: enabled ? 1 : 0.3 + } + } + + ComboBox { + model: [ "Banana", "Apple", "Coconut" ] + editable: true + contentItem: Rectangle { + implicitWidth: text2.implicitWidth + color: "lightGreen" + TextEdit { + id: text2 + text: "Custom content item" + anchors.centerIn: parent + } + } + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/CustomDials.qml b/tests/manual/quickcontrols2/nativestyle/CustomDials.qml new file mode 100644 index 00000000000..b0df77b603e --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CustomDials.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick dial1s 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Basic.impl +import QtQuick.Layouts + +ControlContainer { + id: container + title: "Dials" + + Row { + spacing: container.rowSpacing + + Dial { + id: dial1 + width: 50 + height: 50 + from: 0 + to: 10 + value: 5 + + background: DialImpl { + implicitWidth: 184 + implicitHeight: 184 + color: "darkgray" + progress: dial1.position + opacity: dial1.enabled ? 1 : 0.3 + } + + handle: ColorImage { + x: dial1.background.x + dial1.background.width / 2 - width / 2 + y: dial1.background.y + dial1.background.height / 2 - height / 2 + width: 14 + height: 10 + color: "green" + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/dial-indicator.png" + antialiasing: true + opacity: dial1.enabled ? 1 : 0.3 + transform: [ + Translate { + y: -Math.min(dial1.background.width, dial1.background.height) * 0.4 + dial1.handle.height / 2 + }, + Rotation { + angle: dial1.angle + origin.x: dial1.handle.width / 2 + origin.y: dial1.handle.height / 2 + } + ] + } + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/CustomFrames.qml b/tests/manual/quickcontrols2/nativestyle/CustomFrames.qml new file mode 100644 index 00000000000..e2b045a5cd7 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CustomFrames.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "Frames" + + Row { + spacing: container.rowSpacing + + Frame { + width: 200 + height: 50 + background: Rectangle { + border.width: 1 + border.color: "green" + Text { + anchors.centerIn: parent + color: "green" + text: "Custom background" + } + } + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/CustomProgressBars.qml b/tests/manual/quickcontrols2/nativestyle/CustomProgressBars.qml new file mode 100644 index 00000000000..6ace8f20bc3 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CustomProgressBars.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Basic.impl + +ControlContainer { + id: container + title: "ProgressBars" + + property int time: 0 + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: { + time++ + if (time > 10) + time = 0 + } + } + + Row { + spacing: container.rowSpacing + + ProgressBar { + id: c3 + width: 100 + from: 0 + to: 10 + value: time + indeterminate: false + padding: 5 + background: Rectangle { + implicitWidth: 100 + implicitHeight: 6 + color: "darkgray" + } + contentItem: ProgressBarImpl { + implicitHeight: 6 + implicitWidth: 100 + progress: c3.position + indeterminate: false + color: "lightgreen" + } + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/CustomRadioButtons.qml b/tests/manual/quickcontrols2/nativestyle/CustomRadioButtons.qml new file mode 100644 index 00000000000..8a657cdd5f3 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CustomRadioButtons.qml @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.impl + +ControlContainer { + id: container + title: "RadioButtons" + + Row { + spacing: container.rowSpacing + + RadioButton { + id: customContentItem + text: "Custom content item" + contentItem: Text { + text: customContentItem.text + color: "green" + leftPadding: customContentItem.indicator.width + customContentItem.spacing + } + } + + RadioButton { + id: customIndicator + text: "Custom indicator" + indicator: Rectangle { + implicitWidth: 14 + implicitHeight: 14 + + x: customIndicator.text ? customIndicator.leftPadding : customIndicator.leftPadding + (customIndicator.availableWidth - width) / 2 + y: customIndicator.topPadding + (customIndicator.availableHeight - height) / 2 + + radius: width / 2 + color: customIndicator.down ? customIndicator.palette.light : customIndicator.palette.base + border.width: 2 + border.color: "green" + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 5 + height: 5 + radius: width / 2 + color: "green" + visible: customIndicator.checked + } + } + } + + RadioButton { + id: allCustom + text: "All custom" + + contentItem: Text { + text: allCustom.text + color: "green" + leftPadding: allCustom.indicator.width + allCustom.spacing + } + + indicator: Rectangle { + implicitWidth: 14 + implicitHeight: 14 + + x: allCustom.text ? allCustom.leftPadding : allCustom.leftPadding + (allCustom.availableWidth - width) / 2 + y: allCustom.topPadding + (allCustom.availableHeight - height) / 2 + + radius: width / 2 + color: allCustom.down ? allCustom.palette.light : allCustom.palette.base + border.width: 2 + border.color: "green" + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 5 + height: 5 + radius: width / 2 + color: "green" + visible: allCustom.checked + } + } + } + } + +} diff --git a/tests/manual/quickcontrols2/nativestyle/CustomScrollBars.qml b/tests/manual/quickcontrols2/nativestyle/CustomScrollBars.qml new file mode 100644 index 00000000000..0731995247c --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CustomScrollBars.qml @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "ScrollBars" + + Row { + spacing: container.rowSpacing + + ScrollBar { + height: 200 + orientation: Qt.Vertical + size: 0.2 + policy: ScrollBar.AlwaysOn + background: Rectangle { + color: "lightgray" + border.color: "gray" + border.width: 1 + } + } + + ScrollBar { + height: 200 + orientation: Qt.Vertical + size: 0.2 + policy: ScrollBar.AlwaysOn + contentItem: Rectangle { + color: "lightgreen" + border.color: "green" + border.width: 1 + } + } + + ScrollBar { + height: 200 + orientation: Qt.Vertical + size: 0.2 + policy: ScrollBar.AlwaysOn + background: Rectangle { + color: "lightgray" + border.color: "gray" + border.width: 1 + } + contentItem: Rectangle { + implicitWidth: 15 + color: "lightgreen" + border.color: "green" + border.width: 1 + } + } + + Column { + spacing: container.rowSpacing + + ScrollBar { + width: 300 + orientation: Qt.Horizontal + size: 0.2 + policy: ScrollBar.AlwaysOn + background: Rectangle { + color: "lightgray" + border.color: "gray" + border.width: 1 + } + } + + ScrollBar { + width: 300 + orientation: Qt.Horizontal + size: 0.2 + policy: ScrollBar.AlwaysOn + contentItem: Rectangle { + color: "lightgray" + border.color: "gray" + border.width: 1 + } + } + + ScrollBar { + width: 300 + orientation: Qt.Horizontal + size: 0.2 + policy: ScrollBar.AlwaysOn + background: Rectangle { + color: "lightgray" + border.color: "gray" + border.width: 1 + } + contentItem: Rectangle { + implicitHeight: 15 + color: "lightgreen" + border.color: "green" + border.width: 1 + } + } + } + } + +} diff --git a/tests/manual/quickcontrols2/nativestyle/CustomSliders.qml b/tests/manual/quickcontrols2/nativestyle/CustomSliders.qml new file mode 100644 index 00000000000..075c10d3262 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CustomSliders.qml @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "Sliders" + property int sliderWidth: 300 + property int sliderHeight: 140 + + Row { + spacing: 40 + + Column { + spacing: 15 + + Slider { + id: customHandle + width: sliderWidth + height: 20 + from: 0 + to: 10 + value: 5 + handle: Rectangle { + id: handle + width: 12 + height: customHandle.height + color: "white" + border.width: 2 + + x: customHandle.visualPosition * (customHandle.availableWidth - width) + y: (customHandle.availableHeight - height) / 2 + } + } + + Slider { + id: customBackground + width: sliderWidth + from: 0 + to: 10 + background: Rectangle { + implicitHeight: 5 + color: "lightgray" + border.width: 1 + } + } + + Slider { + id: customAll + width: sliderWidth + height: 20 + from: 0 + to: 10 + background: Rectangle { + implicitHeight: customAll.height + color: "lightgray" + border.width: 1 + } + handle: Rectangle { + width: 12 + height: customAll.height + color: "white" + border.width: 2 + + x: customAll.visualPosition * (customAll.availableWidth - width) + y: (customAll.availableHeight - height) / 2 + } + } + } + + Row { + spacing: 20 + + Slider { + id: customVHandle + width: 20 + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 10 + value: 5 + handle: Rectangle { + height: 12 + width: customVHandle.width + color: "white" + border.width: 2 + + x: (customVHandle.availableWidth - width) / 2 + y: customVHandle.visualPosition * (customVHandle.availableHeight - height) + } + } + + Slider { + id: customVBackground + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 10 + background: Rectangle { + implicitWidth: 5 + color: "lightgray" + border.width: 1 + } + } + + Slider { + id: customVAll + width: 20 + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 10 + value: 5 + handle: Rectangle { + height: 12 + width: customVHandle.width + color: "white" + border.width: 2 + + x: (customVAll.availableWidth - width) / 2 + y: customVAll.visualPosition * (customVAll.availableHeight - height) + } + background: Rectangle { + implicitWidth: 5 + color: "lightgray" + border.width: 1 + } + } + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/CustomSpinBoxes.qml b/tests/manual/quickcontrols2/nativestyle/CustomSpinBoxes.qml new file mode 100644 index 00000000000..b6de2b57f74 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CustomSpinBoxes.qml @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "SpinBoxes" + + Row { + spacing: container.rowSpacing + + SpinBox { + id: custombg + value: 1000 + to: 2000 + background: Rectangle { + border.color: "green" + implicitWidth: 50 + } + } + + SpinBox { + id: customIndicator + value: 500 + to: 2000 + + rightPadding: 17 + spacing: 0 + implicitWidth: 60 + implicitHeight: 25 + + up.indicator: Rectangle { + x: customIndicator.width - width - 4 + y: 4 + implicitWidth: customIndicator.rightPadding - 4 + implicitHeight: 8 + border.width: 1 + border.color: "green" + color: customIndicator.up.pressed ? "gray" : "transparent" + Text { + text: "+" + font.pixelSize: 8 + font.bold: true + anchors.centerIn: parent + } + } + + down.indicator: Rectangle { + x: customIndicator.width - width - 4 + y: height + 6 + implicitWidth: customIndicator.rightPadding - 4 + implicitHeight: 8 + border.width: 1 + border.color: "green" + color: customIndicator.down.pressed ? "gray" : "transparent" + Text { + text: "-" + font.pixelSize: 10 + font.bold: true + anchors.centerIn: parent + } + } + } + + SpinBox { + id: allCustom + value: 500 + to: 2000 + + rightPadding: 17 + spacing: 0 + implicitWidth: 60 + implicitHeight: 25 + + background: Rectangle { + border.color: "green" + implicitWidth: 50 + } + + up.indicator: Rectangle { + x: allCustom.width - width - 4 + y: 4 + implicitWidth: allCustom.rightPadding - 4 + implicitHeight: 8 + border.width: 1 + border.color: "green" + color: allCustom.up.pressed ? "gray" : "transparent" + Text { + text: "+" + font.pixelSize: 8 + font.bold: true + anchors.centerIn: parent + } + } + + down.indicator: Rectangle { + x: allCustom.width - width - 4 + y: height + 6 + implicitWidth: allCustom.rightPadding - 4 + implicitHeight: 8 + border.width: 1 + border.color: "green" + color: allCustom.down.pressed ? "gray" : "transparent" + Text { + text: "-" + font.pixelSize: 10 + font.bold: true + anchors.centerIn: parent + } + } + + contentItem: TextInput { + text: allCustom.displayText + font: allCustom.font + color: "green" + selectionColor: allCustom.palette.highlight + selectedTextColor: allCustom.palette.highlightedText + horizontalAlignment: Qt.AlignLeft + verticalAlignment: Qt.AlignVCenter + + topPadding: 2 + bottomPadding: 2 + leftPadding: 10 + rightPadding: 10 + + readOnly: !allCustom.editable + validator: allCustom.validator + inputMethodHints: allCustom.inputMethodHints + } + + } + + } + +} diff --git a/tests/manual/quickcontrols2/nativestyle/CustomTextAreas.qml b/tests/manual/quickcontrols2/nativestyle/CustomTextAreas.qml new file mode 100644 index 00000000000..77e97b0cc06 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CustomTextAreas.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "TextFields" + + Row { + spacing: container.rowSpacing + + TextArea { + id: customBackground + width: 200 + wrapMode: TextEdit.WordWrap + text: "Custom background - Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." + background: Rectangle { + implicitWidth: customBackground.contentWidth + implicitHeight: customBackground.contentHeight + border.width: customBackground.activeFocus ? 2 : 1 + color: control.palette.base + border.color: "green" + } + } + + TextArea { + width: 200 + placeholderText: "Large font" + font.pixelSize: 20 + wrapMode: TextEdit.WordWrap + text: "Large font - Lorem ipsum dolor sit amet, consectetur adipiscing elit" + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/CustomTextFields.qml b/tests/manual/quickcontrols2/nativestyle/CustomTextFields.qml new file mode 100644 index 00000000000..3e8ccd1e7b2 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/CustomTextFields.qml @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "TextFields" + + Row { + spacing: container.rowSpacing + + TextField { + placeholderText: "Custom background" + background: Rectangle { + implicitWidth: 130 + implicitHeight: 20 + border.width: control.activeFocus ? 2 : 1 + color: control.palette.base + border.color: "green" + } + } + TextField { + placeholderText: "Large font" + font.pixelSize: 20 + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/Dials.qml b/tests/manual/quickcontrols2/nativestyle/Dials.qml new file mode 100644 index 00000000000..f0655f25fb8 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/Dials.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "Dials" + + Row { + spacing: container.rowSpacing + + Dial { + width: 50 + height: 50 + from: 0 + to: 10 + value: 5 + } + + Dial { + width: 50 + height: 50 + from: 0 + to: 10 + value: 5 + stepSize: 1 + property int qqc2_style_tickPosition: 1 + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/Frames.qml b/tests/manual/quickcontrols2/nativestyle/Frames.qml new file mode 100644 index 00000000000..220f8d034ed --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/Frames.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "Frames" + + Row { + spacing: container.rowSpacing + + Frame { + width: 100 + height: 50 + } + + Frame { + Rectangle { + implicitWidth: label.width + 50 + implicitHeight: 45 + Label { + id: label + anchors.centerIn: parent + text: "Frame with contents" + } + } + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/ProgressBars.qml b/tests/manual/quickcontrols2/nativestyle/ProgressBars.qml new file mode 100644 index 00000000000..8abd076d963 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/ProgressBars.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "ProgressBars" + + property int time: 0 + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: { + time++ + if (time > 10) + time = 0 + } + } + + Row { + spacing: container.rowSpacing + + ProgressBar { + width: 100 + from: 0 + to: 10 + value: time + indeterminate: false + } + + ProgressBar { + width: 100 + from: 0 + to: 10 + value: time + enabled: false + indeterminate: false + } + + ProgressBar { + width: 100 + from: 0 + to: 10 + indeterminate: true + } + + ProgressBar { + width: 80 + from: 0 + to: 10 + value: time + indeterminate: false + property bool qqc2_style_small + } + + ProgressBar { + width: 60 + from: 0 + to: 10 + value: time + indeterminate: false + property bool qqc2_style_mini + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/RadioButtons.qml b/tests/manual/quickcontrols2/nativestyle/RadioButtons.qml new file mode 100644 index 00000000000..24a96b59109 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/RadioButtons.qml @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.impl + +ControlContainer { + id: container + title: "RadioButtons" + + Row { + spacing: container.rowSpacing + + Column { + RadioButton { + text: "Default" + checked: true + } + RadioButton { + text: "Default" + } + RadioButton { + text: "Default" + } + } + + Column { + RadioButton { + text: "Disabled" + enabled: false + } + RadioButton { + text: "Disabled" + enabled: false + } + RadioButton { + text: "Disabled" + enabled: false + checked: true + } + } + + Column { + RadioButton { + text: "Small" + property bool qqc2_style_small + } + RadioButton { + text: "Small" + checked: true + property bool qqc2_style_small + } + RadioButton { + text: "Small" + property bool qqc2_style_small + } + } + + Column { + RadioButton { + text: "Mini" + property bool qqc2_style_mini + } + RadioButton { + text: "Mini" + property bool qqc2_style_mini + } + RadioButton { + text: "Mini" + checked: true + property bool qqc2_style_mini + } + } + } + +} diff --git a/tests/manual/quickcontrols2/nativestyle/ScrollBars.qml b/tests/manual/quickcontrols2/nativestyle/ScrollBars.qml new file mode 100644 index 00000000000..a5764c789fa --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/ScrollBars.qml @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "ScrollBars" + + Row { + spacing: container.rowSpacing + + ScrollBar { + height: 200 + orientation: Qt.Vertical + size: 0.2 + policy: ScrollBar.AlwaysOn + } + + ScrollBar { + height: 150 + orientation: Qt.Vertical + size: 0.2 + policy: ScrollBar.AlwaysOn + property bool qqc2_style_small + } + + ScrollBar { + height: 100 + orientation: Qt.Vertical + size: 0.2 + policy: ScrollBar.AlwaysOn + property bool qqc2_style_mini + } + + Column { + spacing: container.rowSpacing + + ScrollBar { + width: 300 + orientation: Qt.Horizontal + size: 0.2 + policy: ScrollBar.AlwaysOn + } + + ScrollBar { + width: 200 + orientation: Qt.Horizontal + size: 0.2 + policy: ScrollBar.AlwaysOn + property bool qqc2_style_small + } + + ScrollBar { + width: 100 + orientation: Qt.Horizontal + size: 0.2 + policy: ScrollBar.AlwaysOn + property bool qqc2_style_mini + } + } + } + +} diff --git a/tests/manual/quickcontrols2/nativestyle/Sliders.qml b/tests/manual/quickcontrols2/nativestyle/Sliders.qml new file mode 100644 index 00000000000..81afa26c9f1 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/Sliders.qml @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "Sliders normal" + property int sliderWidth: 300 + property int sliderHeight: 140 + + Row { + spacing: 40 + + Column { + spacing: 15 + + Slider { + width: sliderWidth + from: 0 + to: 10 + value: 5 + } + + Slider { + width: sliderWidth + from: 0 + to: 10 + value: 5 + enabled: false + } + + Slider { + width: sliderWidth + from: 0 + to: 100 + value: 20 + stepSize: 20 + + property int qqc2_style_tickPosition: 1 + } + + Slider { + width: sliderWidth + from: 0 + to: 100 + stepSize: 5 + value: 65 + + property int qqc2_style_tickPosition: 2 + } + + Slider { + // Should show 9 tickmarks + width: sliderWidth + from: 3.3 + to: 3.7 + stepSize: 0.05 + value: 3.5 + property int qqc2_style_tickPosition: 3 + } + + } + + Row { + spacing: 20 + + Slider { + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 10 + value: 5 + } + + Slider { + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 10 + value: 5 + enabled: false + } + + Slider { + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 100 + value: 20 + stepSize: 20 + + property int qqc2_style_tickPosition: 1 + } + + Slider { + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 100 + stepSize: 5 + value: 65 + + property int qqc2_style_tickPosition: 2 + } + Slider { + // Should show 9 tickmarks + height: sliderHeight + orientation: Qt.Vertical + from: 3.3 + to: 3.7 + stepSize: 0.05 + value: 3.5 + property int qqc2_style_tickPosition: 3 + } + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/SlidersMini.qml b/tests/manual/quickcontrols2/nativestyle/SlidersMini.qml new file mode 100644 index 00000000000..4c7610c497e --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/SlidersMini.qml @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "Sliders mini" + property int sliderWidth: 100 + property int sliderHeight: 90 + + Row { + spacing: 40 + + Column { + spacing: 15 + + Slider { + width: sliderWidth + from: 0 + to: 10 + value: 5 + property bool qqc2_style_mini + } + + Slider { + width: sliderWidth + from: 0 + to: 10 + value: 5 + enabled: false + property bool qqc2_style_mini + } + + Slider { + width: sliderWidth + from: 0 + to: 100 + value: 20 + stepSize: 20 + + property bool qqc2_style_mini + property int qqc2_style_tickPosition: 1 + } + + Slider { + width: sliderWidth + from: 0 + to: 100 + stepSize: 5 + value: 65 + + property bool qqc2_style_mini + property int qqc2_style_tickPosition: 2 + } + } + + Row { + spacing: 20 + + Slider { + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 10 + value: 5 + property bool qqc2_style_mini + } + + Slider { + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 10 + value: 5 + enabled: false + property bool qqc2_style_mini + } + + Slider { + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 100 + value: 20 + stepSize: 20 + + property bool qqc2_style_mini + property int qqc2_style_tickPosition: 1 + } + + Slider { + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 100 + stepSize: 5 + value: 65 + + property bool qqc2_style_mini + property int qqc2_style_tickPosition: 2 + } + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/SlidersSmall.qml b/tests/manual/quickcontrols2/nativestyle/SlidersSmall.qml new file mode 100644 index 00000000000..04c9cb24e76 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/SlidersSmall.qml @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "Sliders small" + property int sliderWidth: 200 + property int sliderHeight: 100 + + Row { + spacing: 40 + + Column { + spacing: 15 + + Slider { + width: sliderWidth + from: 0 + to: 10 + value: 5 + property bool qqc2_style_small + } + + Slider { + width: sliderWidth + from: 0 + to: 10 + value: 5 + enabled: false + property bool qqc2_style_small + } + + Slider { + width: sliderWidth + from: 0 + to: 100 + value: 20 + stepSize: 20 + + property bool qqc2_style_small + property int qqc2_style_tickPosition: 1 + } + + Slider { + width: sliderWidth + from: 0 + to: 100 + stepSize: 5 + value: 65 + + property bool qqc2_style_small + property int qqc2_style_tickPosition: 2 + } + } + + Row { + spacing: 20 + + Slider { + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 10 + value: 5 + property bool qqc2_style_small + } + + Slider { + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 10 + value: 5 + enabled: false + property bool qqc2_style_small + } + + Slider { + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 100 + value: 20 + stepSize: 20 + + property bool qqc2_style_small + property int qqc2_style_tickPosition: 1 + } + + Slider { + height: sliderHeight + orientation: Qt.Vertical + from: 0 + to: 100 + stepSize: 5 + value: 65 + + property bool qqc2_style_small + property int qqc2_style_tickPosition: 2 + } + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/SpinBoxes.qml b/tests/manual/quickcontrols2/nativestyle/SpinBoxes.qml new file mode 100644 index 00000000000..552f159bb92 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/SpinBoxes.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "SpinBoxes" + + Row { + spacing: container.rowSpacing + + SpinBox { + value: 500 + to: 2000 + editable: true + } + + SpinBox { + value: 0 + enabled: false + } + + SpinBox { + value: 5 + from: 0 + to: 9 + property bool qqc2_style_small + } + + SpinBox { + value: 0 + from: -9 + to: 9 + property bool qqc2_style_mini + } + } + +} diff --git a/tests/manual/quickcontrols2/nativestyle/TextAreas.qml b/tests/manual/quickcontrols2/nativestyle/TextAreas.qml new file mode 100644 index 00000000000..d8d49c021ba --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/TextAreas.qml @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "TextAreas" + + Row { + spacing: container.rowSpacing + + TextArea { + id: defaultTextArea + width: 200 + wrapMode: TextEdit.WordWrap + selectByMouse: true + text: "Default - Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." + } + + TextArea { + enabled: false + width: 200 + wrapMode: TextEdit.WordWrap + selectByMouse: true + text: "Disabled - Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." + } + + ScrollView { + id: scrollView + width: 200 + height: defaultTextArea.height + + TextArea { + text: "Inside ScrollView - Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi " + + "ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit " + + "in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur " + + "sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + + "mollit anim id est laborum." + wrapMode: TextEdit.WordWrap + selectByMouse: true + } + } + } + + Row { + spacing: container.rowSpacing + + Frame { + id: frame + contentWidth: textArea.width + contentHeight: textArea.height + + TextArea { + id: textArea + width: 200 + height: 80 + wrapMode: TextEdit.WrapAnywhere + selectByMouse: true + text: "Inside frame - Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." + } + } + + Frame { + contentWidth: 200 + contentHeight: 100 + ScrollView { + id: scrollView2 + anchors.fill: parent + + TextArea { + id: area2 + text: "Inside Frame and ScrollView - Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " + + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi " + + "ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit " + + "in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur " + + "sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " + + "mollit anim id est laborum." + wrapMode: TextEdit.WordWrap + selectByMouse: true + } + } + } + + TextArea { + placeholderText: "Placeholder text" + selectByMouse: true + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/TextFields.qml b/tests/manual/quickcontrols2/nativestyle/TextFields.qml new file mode 100644 index 00000000000..10e97da5e8f --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/TextFields.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ControlContainer { + id: container + title: "TextFields" + + Row { + spacing: container.rowSpacing + + TextField { + text: "Default" + } + + TextField { + enabled: false + text: "Disabled" + } + + TextField { + placeholderText: "Placeholder text" + } + + TextField { + text: "Small" + property bool qqc2_style_small + } + + TextField { + text: "Mini" + property bool qqc2_style_mini + } + } +} diff --git a/tests/manual/quickcontrols2/nativestyle/checkbox-icon.png b/tests/manual/quickcontrols2/nativestyle/checkbox-icon.png new file mode 100644 index 00000000000..ee669b3a888 Binary files /dev/null and b/tests/manual/quickcontrols2/nativestyle/checkbox-icon.png differ diff --git a/tests/manual/quickcontrols2/nativestyle/checkbox-icon16.png b/tests/manual/quickcontrols2/nativestyle/checkbox-icon16.png new file mode 100644 index 00000000000..8d89eab8413 Binary files /dev/null and b/tests/manual/quickcontrols2/nativestyle/checkbox-icon16.png differ diff --git a/tests/manual/quickcontrols2/nativestyle/checkbox-icon@2x.png b/tests/manual/quickcontrols2/nativestyle/checkbox-icon@2x.png new file mode 100644 index 00000000000..51c5601de02 Binary files /dev/null and b/tests/manual/quickcontrols2/nativestyle/checkbox-icon@2x.png differ diff --git a/tests/manual/quickcontrols2/nativestyle/main.cpp b/tests/manual/quickcontrols2/nativestyle/main.cpp new file mode 100644 index 00000000000..cc48753154d --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/main.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QtQuickControls2/qquickstyle.h> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(QStringLiteral("qrc:/main.qml")); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, + &app, [url](QObject *obj, const QUrl &objUrl) { + if (!obj && url == objUrl) + QCoreApplication::exit(-1); + }, Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/tests/manual/quickcontrols2/nativestyle/main.qml b/tests/manual/quickcontrols2/nativestyle/main.qml new file mode 100644 index 00000000000..5e44118c643 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/main.qml @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + visible: true + width: 800 + height: 600 + title: qsTr("Desktop Gallery") + + TabBar { + id: bar + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 20 + anchors.rightMargin: 40 + + TabButton { + text: qsTr("Default controls") + } + + TabButton { + text: qsTr("Customized controls") + } + } + + StackLayout { + currentIndex: bar.currentIndex + anchors.top: bar.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 20 + + ScrollView { + contentWidth: availableWidth + + Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: 20 + + Buttons { } + CheckBoxes { } + RadioButtons { } + SpinBoxes { } + TextFields { } + TextAreas { } + ComboBoxes { } + Dials { } + Frames { } + ProgressBars { } + ScrollBars { } + Sliders { } + SlidersSmall { } + SlidersMini { } + } + } + + ScrollView { + contentWidth: availableWidth + + Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: 20 + + CustomButtons { } + CustomCheckBoxes { } + CustomRadioButtons { } + CustomSpinBoxes { } + CustomTextFields { } + CustomTextAreas { } + CustomComboBoxes { } + CustomDials { } + CustomFrames { } + CustomProgressBars { } + CustomScrollBars { } + CustomSliders { } + } + } + } + +} diff --git a/tests/manual/quickcontrols2/nativestyle/nativestyle.pro b/tests/manual/quickcontrols2/nativestyle/nativestyle.pro new file mode 100644 index 00000000000..9c700430fea --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/nativestyle.pro @@ -0,0 +1,39 @@ +QT += quick quickcontrols2 + +SOURCES += \ + main.cpp + +QML_FILES = \ + main.qml \ + ControlContainer.qml \ + Buttons.qml \ + CustomButtons.qml \ + Sliders.qml \ + SlidersSmall.qml \ + SlidersMini.qml \ + CustomSliders.qml \ + CheckBoxes.qml \ + CustomCheckBoxes.qml \ + RadioButtons.qml \ + CustomRadioButtons.qml \ + SpinBoxes.qml \ + CustomSpinBoxes.qml \ + TextFields.qml \ + CustomTextFields.qml \ + Frames.qml \ + CustomFrames.qml \ + TextAreas.qml \ + CustomTextAreas.qml \ + ComboBoxes.qml \ + CustomComboBoxes.qml \ + ScrollBars.qml \ + CustomScrollBars.qml \ + ProgressBars.qml \ + CustomProgressBars.qml \ + Dials.qml \ + CustomDials.qml \ + +OTHER_FILES += $$QML_FILES +RESOURCES += $$QML_FILES +RESOURCES += checkbox-icon.png checkbox-icon16.png checkbox-icon@2x.png + diff --git a/tests/manual/quickcontrols2/nativestyle/qml.qrc b/tests/manual/quickcontrols2/nativestyle/qml.qrc new file mode 100644 index 00000000000..fba642e53f2 --- /dev/null +++ b/tests/manual/quickcontrols2/nativestyle/qml.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + <file>ButtonsTab.qml</file> + <file>SlidersTab.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/quickcontrols2/qquickdialog/CMakeLists.txt b/tests/manual/quickcontrols2/qquickdialog/CMakeLists.txt new file mode 100644 index 00000000000..661a7dc76c0 --- /dev/null +++ b/tests/manual/quickcontrols2/qquickdialog/CMakeLists.txt @@ -0,0 +1,31 @@ +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(qquickdialog LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +qt_internal_add_manual_test(qquickdialog + GUI + SOURCES + qquickdialog.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Qml + Qt::QuickControls2 +) + +# Resources: +set(qmake_immediate_resource_files + "CustomDialog.qml" + "DialogLabel.qml" + "Marker.qml" + "qquickdialog.qml" + "qtquickcontrols2.conf" +) + +qt_internal_add_resource(qquickdialog "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) diff --git a/tests/manual/quickcontrols2/qquickdialog/CustomDialog.qml b/tests/manual/quickcontrols2/qquickdialog/CustomDialog.qml new file mode 100644 index 00000000000..fb191c9f4ef --- /dev/null +++ b/tests/manual/quickcontrols2/qquickdialog/CustomDialog.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls + +Dialog { + id: root + x: previousDialog ? previousDialog.x + previousDialog.width + space : 0 + y: previousDialog ? previousDialog.y : 0 + closePolicy: Dialog.NoAutoClose + visible: true + + property Dialog previousDialog + property int space: dialogSpacing + + Marker { + parent: root.footer.contentItem + visible: visualizeDialogButtonBoxContentItem + text: "footer.contentItem" + } + Marker { + parent: root.footer + visible: visualizeDialogButtonBox + text: "footer" + border.color: "red" + } +} diff --git a/tests/manual/quickcontrols2/qquickdialog/DialogLabel.qml b/tests/manual/quickcontrols2/qquickdialog/DialogLabel.qml new file mode 100644 index 00000000000..3a1533eb16d --- /dev/null +++ b/tests/manual/quickcontrols2/qquickdialog/DialogLabel.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls + +Label { + x: dialog.x + (dialog.width - width) / 2 + y: dialog.y - height + width: dialog.width + wrapMode: Label.Wrap + + property Dialog dialog +} diff --git a/tests/manual/quickcontrols2/qquickdialog/Marker.qml b/tests/manual/quickcontrols2/qquickdialog/Marker.qml new file mode 100644 index 00000000000..cd93d055700 --- /dev/null +++ b/tests/manual/quickcontrols2/qquickdialog/Marker.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Rectangle { + anchors.fill: parent + color: "transparent" + border.color: "darkorange" + + property alias text: label.text + + Text { + id: label + font.pixelSize: Qt.application.font.pixelSize * 0.6 + color: parent.border.color + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.margins: 4 + } +} diff --git a/tests/manual/quickcontrols2/qquickdialog/qquickdialog.cpp b/tests/manual/quickcontrols2/qquickdialog/qquickdialog.cpp new file mode 100644 index 00000000000..77863abe835 --- /dev/null +++ b/tests/manual/quickcontrols2/qquickdialog/qquickdialog.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/qquickdialog.qml")); + + return app.exec(); +} diff --git a/tests/manual/quickcontrols2/qquickdialog/qquickdialog.pro b/tests/manual/quickcontrols2/qquickdialog/qquickdialog.pro new file mode 100644 index 00000000000..aee7655b652 --- /dev/null +++ b/tests/manual/quickcontrols2/qquickdialog/qquickdialog.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = qquickdialog +QT += qml quickcontrols2 + +SOURCES += qquickdialog.cpp +RESOURCES += \ + qtquickcontrols2.conf \ + qquickdialog.qml \ + Marker.qml \ + CustomDialog.qml \ + DialogLabel.qml diff --git a/tests/manual/quickcontrols2/qquickdialog/qquickdialog.qml b/tests/manual/quickcontrols2/qquickdialog/qquickdialog.qml new file mode 100644 index 00000000000..41bf6ab7c3d --- /dev/null +++ b/tests/manual/quickcontrols2/qquickdialog/qquickdialog.qml @@ -0,0 +1,247 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + id: window + width: 1200 + height: 800 + title: "qquickdialog" + visible: true + + property alias visualizeDialogButtonBoxContentItem: visualizeDialogButtonBoxContentItemMenuItem.checked + property alias visualizeDialogButtonBox: visualizeDialogButtonBoxMenuItem.checked + + property int dialogSpacing: 60 + + header: ToolBar { + RowLayout { + anchors.fill: parent + Item { + Layout.fillWidth: true + } + + ToolButton { + text: "Settings" + onClicked: settingsMenu.open() + + Menu { + id: settingsMenu + width: 400 + + MenuItem { + id: visualizeDialogButtonBoxContentItemMenuItem + text: "Visualize DialogButtonBox contentItem" + checkable: true + } + + MenuItem { + id: visualizeDialogButtonBoxMenuItem + text: "Visualize DialogButtonBox" + checkable: true + } + } + } + } + } + + + DialogLabel { + text: "implicit width" + dialog: dialogImplicitWidthNoButtons + width: 100 + } + CustomDialog { + id: dialogImplicitWidthNoButtons + x: dialogSpacing + y: dialogSpacing + space: 200 + } + + DialogLabel { + text: "title, implicit width" + dialog: dialogImplicitWidthTitleNoButtons + width: 150 + } + CustomDialog { + id: dialogImplicitWidthTitleNoButtons + y: dialogSpacing + title: "Test" + previousDialog: dialogImplicitWidthNoButtons + space: 200 + } + + DialogLabel { + text: "title, fixed width" + dialog: dialogFixedWidthTitleNoButtons + } + CustomDialog { + id: dialogFixedWidthTitleNoButtons + y: dialogSpacing + width: 300 + title: "Test" + previousDialog: dialogImplicitWidthTitleNoButtons + space: 200 + } + + + DialogLabel { + text: "one standard button, implicit width" + dialog: dialogImplicitWidthOneButton + } + CustomDialog { + id: dialogImplicitWidthOneButton + x: dialogSpacing + y: dialogFixedWidthTitleNoButtons.y + dialogFixedWidthTitleNoButtons.height + dialogSpacing + standardButtons: Dialog.Ok + } + + DialogLabel { + text: "two standard buttons, implicit width" + dialog: dialogImplicitWidthTwoButtons + } + CustomDialog { + id: dialogImplicitWidthTwoButtons + standardButtons: Dialog.Ok | Dialog.Cancel + previousDialog: dialogImplicitWidthOneButton + } + + DialogLabel { + text: "three standard buttons, implicit width" + dialog: dialogImplicitWidthThreeButtons + } + CustomDialog { + id: dialogImplicitWidthThreeButtons + standardButtons: Dialog.Apply | Dialog.RestoreDefaults | Dialog.Cancel + previousDialog: dialogImplicitWidthTwoButtons + } + + + DialogLabel { + text: "text, one standard button, implicit width" + dialog: dialogTextImplicitWidthOneButton + } + CustomDialog { + id: dialogTextImplicitWidthOneButton + x: dialogSpacing + y: dialogImplicitWidthThreeButtons.y + dialogImplicitWidthThreeButtons.height + dialogSpacing + standardButtons: Dialog.Ok + + Label { + text: "A Label" + } + } + + DialogLabel { + text: "text, two standard buttons, implicit width" + dialog: dialogTextImplicitWidthTwoButtons + } + CustomDialog { + id: dialogTextImplicitWidthTwoButtons + standardButtons: Dialog.Ok | Dialog.Cancel + previousDialog: dialogTextImplicitWidthOneButton + + Label { + text: "A Label" + } + } + + DialogLabel { + text: "text, three standard buttons, implicit width" + dialog: dialogTextImplicitWidthThreeButtons + } + CustomDialog { + id: dialogTextImplicitWidthThreeButtons + standardButtons: Dialog.Apply | Dialog.RestoreDefaults | Dialog.Cancel + previousDialog: dialogTextImplicitWidthTwoButtons + + Label { + text: "A Label" + } + } + + + DialogLabel { + text: "one standard button, fixed width (300)" + dialog: dialogFixedWidthOneButton + } + CustomDialog { + id: dialogFixedWidthOneButton + x: dialogSpacing + y: dialogTextImplicitWidthThreeButtons.y + dialogTextImplicitWidthThreeButtons.height + dialogSpacing + width: 300 + standardButtons: Dialog.Ok + } + + DialogLabel { + text: "two standard buttons, fixed width (300)" + dialog: dialogFixedWidthTwoButtons + } + CustomDialog { + id: dialogFixedWidthTwoButtons + width: 300 + standardButtons: Dialog.Ok | Dialog.Cancel + previousDialog: dialogFixedWidthOneButton + } + + DialogLabel { + text: "three standard buttons, fixed width (300)" + dialog: dialogFixedWidthThreeButtons + } + CustomDialog { + id: dialogFixedWidthThreeButtons + width: 300 + standardButtons: Dialog.Apply | Dialog.RestoreDefaults | Dialog.Cancel + previousDialog: dialogFixedWidthTwoButtons + } +} diff --git a/tests/manual/quickcontrols2/qquickdialog/qtquickcontrols2.conf b/tests/manual/quickcontrols2/qquickdialog/qtquickcontrols2.conf new file mode 100644 index 00000000000..53f380bfc95 --- /dev/null +++ b/tests/manual/quickcontrols2/qquickdialog/qtquickcontrols2.conf @@ -0,0 +1,6 @@ +[Controls] +Style=Basic +;Style=Fusion +;Style=Imagine +;Style=Material +;Style=Universal diff --git a/tests/manual/quickcontrols2/screenshots/CMakeLists.txt b/tests/manual/quickcontrols2/screenshots/CMakeLists.txt new file mode 100644 index 00000000000..b6bd2926152 --- /dev/null +++ b/tests/manual/quickcontrols2/screenshots/CMakeLists.txt @@ -0,0 +1,40 @@ +# Generated from screenshots.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(screenshots LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## screenshots Binary: +##################################################################### + +qt_internal_add_manual_test(screenshots + GUI + SOURCES + screenshots.cpp + DEFINES + SNIPPETS_DIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../src/imports/controls/doc/snippets\\\" + PUBLIC_LIBRARIES + Qt::Gui + Qt::Quick + Qt::Widgets +) + +# Resources: +set(qmake_immediate_resource_files + "qtquickcontrols2.conf" + "screenshots.qml" +) + +qt_internal_add_resource(screenshots "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + + +#### Keys ignored in scope 1:.:.:screenshots.pro:<TRUE>: +# TEMPLATE = "app" diff --git a/tests/manual/quickcontrols2/screenshots/qtquickcontrols2.conf b/tests/manual/quickcontrols2/screenshots/qtquickcontrols2.conf new file mode 100644 index 00000000000..d2081db1d02 --- /dev/null +++ b/tests/manual/quickcontrols2/screenshots/qtquickcontrols2.conf @@ -0,0 +1,5 @@ +[Controls] +Style=Material + +[Material] +;Variant=Dense diff --git a/tests/manual/quickcontrols2/screenshots/screenshots.cpp b/tests/manual/quickcontrols2/screenshots/screenshots.cpp new file mode 100644 index 00000000000..e4e1844d6f3 --- /dev/null +++ b/tests/manual/quickcontrols2/screenshots/screenshots.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QQmlContext> +#include <QFileInfo> +#include <QDir> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl snippetsDir = QUrl::fromLocalFile(SNIPPETS_DIR); + Q_ASSERT(snippetsDir.isValid() && QFileInfo(snippetsDir.toLocalFile()).exists()); + engine.rootContext()->setContextProperty("snippetsDir", snippetsDir); + engine.rootContext()->setContextProperty("screenshotsDir", QUrl::fromLocalFile(QDir::currentPath())); + engine.rootContext()->setContextProperty("screenshotsDirStr", QDir::currentPath()); + engine.load(QUrl("qrc:/screenshots.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/tests/manual/quickcontrols2/screenshots/screenshots.pro b/tests/manual/quickcontrols2/screenshots/screenshots.pro new file mode 100644 index 00000000000..5894888f132 --- /dev/null +++ b/tests/manual/quickcontrols2/screenshots/screenshots.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = screenshots +QT += quick widgets + +DEFINES += SNIPPETS_DIR=\\\"$$PWD/../../../src/imports/controls/doc/snippets\\\" +message($$DEFINES) + +SOURCES += \ + screenshots.cpp + +RESOURCES += \ + screenshots.qml \ + qtquickcontrols2.conf diff --git a/tests/manual/quickcontrols2/screenshots/screenshots.qml b/tests/manual/quickcontrols2/screenshots/screenshots.qml new file mode 100644 index 00000000000..3496b32bd64 --- /dev/null +++ b/tests/manual/quickcontrols2/screenshots/screenshots.qml @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Qt.labs.folderlistmodel + +ApplicationWindow { + id: window + title: "Qt Quick Controls 2 - Screenshots" + visible: true + width: Math.max(600, loader.implicitWidth) + height: Math.max(600, loader.implicitHeight + header.implicitHeight + footer.implicitHeight) + + property string currentFilePath + property url lastSaveUrl + + Shortcut { + sequence: "Ctrl+Q" + onActivated: Qt.quit() + } + + header: ToolBar { + RowLayout { + anchors.fill: parent + + ToolButton { + text: "Choose Snippet" + focusPolicy: Qt.NoFocus + onClicked: snippetDrawer.open() + } + } + } + + Drawer { + id: snippetDrawer + width: window.width / 2 + height: window.height + + ListView { + id: snippetsListView + anchors.fill: parent + model: FolderListModel { + folder: snippetsDir + nameFilters: ["*.qml"] + showDirs: false + } + delegate: ItemDelegate { + width: parent.width + text: fileName + focusPolicy: Qt.NoFocus + + readonly property string baseName: fileBaseName + + contentItem: Label { + text: parent.text + elide: Text.ElideLeft + } + onClicked: { + snippetsListView.currentIndex = index; + loader.source = "file:///" + filePath; + currentFilePath = filePath; + snippetDrawer.close(); + } + } + } + } + + Loader { + id: loader + anchors.centerIn: parent + } + + ToolTip { + id: saveResultToolTip + x: window.contentItem.width / 2 - width / 2 + y: window.contentItem.height - height - 20 + timeout: 3000 + } + + footer: ToolBar { + RowLayout { + anchors.fill: parent + + ToolButton { + text: "Open Output Folder" + focusPolicy: Qt.NoFocus + onClicked: Qt.openUrlExternally(screenshotsDir) + } + + ToolButton { + text: "Open Last Screenshot" + focusPolicy: Qt.NoFocus + enabled: lastSaveUrl.toString().length > 0 + onClicked: Qt.openUrlExternally(lastSaveUrl) + } + + Item { + Layout.fillWidth: true + } + + ToolButton { + text: "Take Screenshot" + focusPolicy: Qt.NoFocus + enabled: loader.status === Loader.Ready + onClicked: { + if (!loader.item) + return; + + var grabSuccessful = loader.grabToImage(function(result) { + var savePath = screenshotsDirStr + "/" + snippetsListView.currentItem.baseName + ".png"; + if (result.saveToFile(savePath)) { + saveResultToolTip.text = "Successfully saved screenshot to output folder"; + lastSaveUrl = screenshotsDir + "/" + snippetsListView.currentItem.baseName + ".png"; + } else { + saveResultToolTip.text = "Failed to save screenshot"; + } + }) + if (!grabSuccessful) + saveResultToolTip.text = "Failed to grab image"; + saveResultToolTip.open(); + } + } + } + } +} diff --git a/tests/manual/quickcontrols2/shared/FontAwesome.otf b/tests/manual/quickcontrols2/shared/FontAwesome.otf new file mode 100644 index 00000000000..681bdd4d4c8 Binary files /dev/null and b/tests/manual/quickcontrols2/shared/FontAwesome.otf differ diff --git a/tests/manual/quickcontrols2/shared/FontAwesome.qml b/tests/manual/quickcontrols2/shared/FontAwesome.qml new file mode 100644 index 00000000000..d64176b4a4d --- /dev/null +++ b/tests/manual/quickcontrols2/shared/FontAwesome.qml @@ -0,0 +1,746 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick + +pragma Singleton + +QtObject { + + // Font Awesome by Dave Gandy - http://fontawesome.io + // Font Awesome is licensed under SIL OFL 1.1 (http://scripts.sil.org/OFL) + property FontLoader fontLoader: FontLoader { + source: "FontAwesome.otf" + } + + // Generated from copying the contents of https://fortawesome.github.io/Font-Awesome/cheatsheet/ and running it through + // sed -E 's/([0-9].[0-9])?..fa-([a-zA-Z0-9-]+) (\(alias\) )?\[\&\#x([a-f0-9]+);\]/\2: \"\\\u\4\";/g' + // | tr \; "\n" + // | awk '{ r="-[a-z0-9]"; while (match($0, r)) sub(r, toupper(substr($0, RSTART + 1, 1))); print "readonly property string" $0 }' + + // Some icon names have been manually edited either because the symbol is reserved or invalid. + + // Manually edited. Was "500px" + readonly property string i500px: "\uf26e" + readonly property string adjust: "\uf042" + readonly property string adn: "\uf170" + readonly property string alignCenter: "\uf037" + readonly property string alignJustify: "\uf039" + readonly property string alignLeft: "\uf036" + readonly property string alignRight: "\uf038" + readonly property string amazon: "\uf270" + readonly property string ambulance: "\uf0f9" + readonly property string anchor: "\uf13d" + readonly property string android: "\uf17b" + readonly property string angellist: "\uf209" + readonly property string angleDoubleDown: "\uf103" + readonly property string angleDoubleLeft: "\uf100" + readonly property string angleDoubleRight: "\uf101" + readonly property string angleDoubleUp: "\uf102" + readonly property string angleDown: "\uf107" + readonly property string angleLeft: "\uf104" + readonly property string angleRight: "\uf105" + readonly property string angleUp: "\uf106" + readonly property string apple: "\uf179" + readonly property string archive: "\uf187" + readonly property string areaChart: "\uf1fe" + readonly property string arrowCircleDown: "\uf0ab" + readonly property string arrowCircleLeft: "\uf0a8" + readonly property string arrowCircleODown: "\uf01a" + readonly property string arrowCircleOLeft: "\uf190" + readonly property string arrowCircleORight: "\uf18e" + readonly property string arrowCircleOUp: "\uf01b" + readonly property string arrowCircleRight: "\uf0a9" + readonly property string arrowCircleUp: "\uf0aa" + readonly property string arrowDown: "\uf063" + readonly property string arrowLeft: "\uf060" + readonly property string arrowRight: "\uf061" + readonly property string arrowUp: "\uf062" + readonly property string arrows: "\uf047" + readonly property string arrowsAlt: "\uf0b2" + readonly property string arrowsH: "\uf07e" + readonly property string arrowsV: "\uf07d" + readonly property string asterisk: "\uf069" + readonly property string at: "\uf1fa" + readonly property string automobile: "\uf1b9" + readonly property string backward: "\uf04a" + readonly property string balanceScale: "\uf24e" + readonly property string ban: "\uf05e" + readonly property string bank: "\uf19c" + readonly property string barChart: "\uf080" + readonly property string barChartO: "\uf080" + readonly property string barcode: "\uf02a" + readonly property string bars: "\uf0c9" + readonly property string battery0: "\uf244" + readonly property string battery1: "\uf243" + readonly property string battery2: "\uf242" + readonly property string battery3: "\uf241" + readonly property string battery4: "\uf240" + readonly property string batteryEmpty: "\uf244" + readonly property string batteryFull: "\uf240" + readonly property string batteryHalf: "\uf242" + readonly property string batteryQuarter: "\uf243" + readonly property string batteryThreeQuarters: "\uf241" + readonly property string bed: "\uf236" + readonly property string beer: "\uf0fc" + readonly property string behance: "\uf1b4" + readonly property string behanceSquare: "\uf1b5" + readonly property string bell: "\uf0f3" + readonly property string bellO: "\uf0a2" + readonly property string bellSlash: "\uf1f6" + readonly property string bellSlashO: "\uf1f7" + readonly property string bicycle: "\uf206" + readonly property string binoculars: "\uf1e5" + readonly property string birthdayCake: "\uf1fd" + readonly property string bitbucket: "\uf171" + readonly property string bitbucketSquare: "\uf172" + readonly property string bitcoin: "\uf15a" + readonly property string blackTie: "\uf27e" + readonly property string bold: "\uf032" + readonly property string bolt: "\uf0e7" + readonly property string bomb: "\uf1e2" + readonly property string book: "\uf02d" + readonly property string bookmark: "\uf02e" + readonly property string bookmarkO: "\uf097" + readonly property string briefcase: "\uf0b1" + readonly property string btc: "\uf15a" + readonly property string bug: "\uf188" + readonly property string building: "\uf1ad" + readonly property string buildingO: "\uf0f7" + readonly property string bullhorn: "\uf0a1" + readonly property string bullseye: "\uf140" + readonly property string bus: "\uf207" + readonly property string buysellads: "\uf20d" + readonly property string cab: "\uf1ba" + readonly property string calculator: "\uf1ec" + readonly property string calendar: "\uf073" + readonly property string calendarCheckO: "\uf274" + readonly property string calendarMinusO: "\uf272" + readonly property string calendarO: "\uf133" + readonly property string calendarPlusO: "\uf271" + readonly property string calendarTimesO: "\uf273" + readonly property string camera: "\uf030" + readonly property string cameraRetro: "\uf083" + readonly property string car: "\uf1b9" + readonly property string caretDown: "\uf0d7" + readonly property string caretLeft: "\uf0d9" + readonly property string caretRight: "\uf0da" + readonly property string caretSquareODown: "\uf150" + readonly property string caretSquareOLeft: "\uf191" + readonly property string caretSquareORight: "\uf152" + readonly property string caretSquareOUp: "\uf151" + readonly property string caretUp: "\uf0d8" + readonly property string cartArrowDown: "\uf218" + readonly property string cartPlus: "\uf217" + readonly property string cc: "\uf20a" + readonly property string ccAmex: "\uf1f3" + readonly property string ccDinersClub: "\uf24c" + readonly property string ccDiscover: "\uf1f2" + readonly property string ccJcb: "\uf24b" + readonly property string ccMastercard: "\uf1f1" + readonly property string ccPaypal: "\uf1f4" + readonly property string ccStripe: "\uf1f5" + readonly property string ccVisa: "\uf1f0" + readonly property string certificate: "\uf0a3" + readonly property string chain: "\uf0c1" + readonly property string chainBroken: "\uf127" + readonly property string check: "\uf00c" + readonly property string checkCircle: "\uf058" + readonly property string checkCircleO: "\uf05d" + readonly property string checkSquare: "\uf14a" + readonly property string checkSquareO: "\uf046" + readonly property string chevronCircleDown: "\uf13a" + readonly property string chevronCircleLeft: "\uf137" + readonly property string chevronCircleRight: "\uf138" + readonly property string chevronCircleUp: "\uf139" + readonly property string chevronDown: "\uf078" + readonly property string chevronLeft: "\uf053" + readonly property string chevronRight: "\uf054" + readonly property string chevronUp: "\uf077" + readonly property string child: "\uf1ae" + readonly property string chrome: "\uf268" + readonly property string circle: "\uf111" + readonly property string circleO: "\uf10c" + readonly property string circleONotch: "\uf1ce" + readonly property string circleThin: "\uf1db" + readonly property string clipboard: "\uf0ea" + readonly property string clockO: "\uf017" + readonly property string clone: "\uf24d" + readonly property string close: "\uf00d" + readonly property string cloud: "\uf0c2" + readonly property string cloudDownload: "\uf0ed" + readonly property string cloudUpload: "\uf0ee" + readonly property string cny: "\uf157" + readonly property string code: "\uf121" + readonly property string codeFork: "\uf126" + readonly property string codepen: "\uf1cb" + readonly property string coffee: "\uf0f4" + readonly property string cog: "\uf013" + readonly property string cogs: "\uf085" + readonly property string columns: "\uf0db" + readonly property string comment: "\uf075" + readonly property string commentO: "\uf0e5" + readonly property string commenting: "\uf27a" + readonly property string commentingO: "\uf27b" + readonly property string comments: "\uf086" + readonly property string commentsO: "\uf0e6" + readonly property string compass: "\uf14e" + readonly property string compress: "\uf066" + readonly property string connectdevelop: "\uf20e" + readonly property string contao: "\uf26d" + readonly property string copy: "\uf0c5" + readonly property string copyright: "\uf1f9" + readonly property string creativeCommons: "\uf25e" + readonly property string creditCard: "\uf09d" + readonly property string crop: "\uf125" + readonly property string crosshairs: "\uf05b" + readonly property string css3: "\uf13c" + readonly property string cube: "\uf1b2" + readonly property string cubes: "\uf1b3" + readonly property string cut: "\uf0c4" + readonly property string cutlery: "\uf0f5" + readonly property string dashboard: "\uf0e4" + readonly property string dashcube: "\uf210" + readonly property string database: "\uf1c0" + readonly property string dedent: "\uf03b" + readonly property string delicious: "\uf1a5" + readonly property string desktop: "\uf108" + readonly property string deviantart: "\uf1bd" + readonly property string diamond: "\uf219" + readonly property string digg: "\uf1a6" + readonly property string dollar: "\uf155" + readonly property string dotCircleO: "\uf192" + readonly property string download: "\uf019" + readonly property string dribbble: "\uf17d" + readonly property string dropbox: "\uf16b" + readonly property string drupal: "\uf1a9" + readonly property string edit: "\uf044" + readonly property string eject: "\uf052" + readonly property string ellipsisH: "\uf141" + readonly property string ellipsisV: "\uf142" + readonly property string empire: "\uf1d1" + readonly property string envelope: "\uf0e0" + readonly property string envelopeO: "\uf003" + readonly property string envelopeSquare: "\uf199" + readonly property string eraser: "\uf12d" + readonly property string eur: "\uf153" + readonly property string euro: "\uf153" + readonly property string exchange: "\uf0ec" + readonly property string exclamation: "\uf12a" + readonly property string exclamationCircle: "\uf06a" + readonly property string exclamationTriangle: "\uf071" + readonly property string expand: "\uf065" + readonly property string expeditedssl: "\uf23e" + readonly property string externalLink: "\uf08e" + readonly property string externalLinkSquare: "\uf14c" + readonly property string eye: "\uf06e" + readonly property string eyeSlash: "\uf070" + readonly property string eyedropper: "\uf1fb" + readonly property string facebook: "\uf09a" + readonly property string facebookF: "\uf09a" + readonly property string facebookOfficial: "\uf230" + readonly property string facebookSquare: "\uf082" + readonly property string fastBackward: "\uf049" + readonly property string fastForward: "\uf050" + readonly property string fax: "\uf1ac" + readonly property string feed: "\uf09e" + readonly property string female: "\uf182" + readonly property string fighterJet: "\uf0fb" + readonly property string file: "\uf15b" + readonly property string fileArchiveO: "\uf1c6" + readonly property string fileAudioO: "\uf1c7" + readonly property string fileCodeO: "\uf1c9" + readonly property string fileExcelO: "\uf1c3" + readonly property string fileImageO: "\uf1c5" + readonly property string fileMovieO: "\uf1c8" + readonly property string fileO: "\uf016" + readonly property string filePdfO: "\uf1c1" + readonly property string filePhotoO: "\uf1c5" + readonly property string filePictureO: "\uf1c5" + readonly property string filePowerpointO: "\uf1c4" + readonly property string fileSoundO: "\uf1c7" + readonly property string fileText: "\uf15c" + readonly property string fileTextO: "\uf0f6" + readonly property string fileVideoO: "\uf1c8" + readonly property string fileWordO: "\uf1c2" + readonly property string fileZipO: "\uf1c6" + readonly property string filesO: "\uf0c5" + readonly property string film: "\uf008" + readonly property string filter: "\uf0b0" + readonly property string fire: "\uf06d" + readonly property string fireExtinguisher: "\uf134" + readonly property string firefox: "\uf269" + readonly property string flag: "\uf024" + readonly property string flagCheckered: "\uf11e" + readonly property string flagO: "\uf11d" + readonly property string flash: "\uf0e7" + readonly property string flask: "\uf0c3" + readonly property string flickr: "\uf16e" + readonly property string floppyO: "\uf0c7" + readonly property string folder: "\uf07b" + readonly property string folderO: "\uf114" + readonly property string folderOpen: "\uf07c" + readonly property string folderOpenO: "\uf115" + readonly property string font: "\uf031" + readonly property string fonticons: "\uf280" + readonly property string forumbee: "\uf211" + readonly property string forward: "\uf04e" + readonly property string foursquare: "\uf180" + readonly property string frownO: "\uf119" + readonly property string futbolO: "\uf1e3" + readonly property string gamepad: "\uf11b" + readonly property string gavel: "\uf0e3" + readonly property string gbp: "\uf154" + readonly property string ge: "\uf1d1" + readonly property string gear: "\uf013" + readonly property string gears: "\uf085" + readonly property string genderless: "\uf22d" + readonly property string getPocket: "\uf265" + readonly property string gg: "\uf260" + readonly property string ggCircle: "\uf261" + readonly property string gift: "\uf06b" + readonly property string git: "\uf1d3" + readonly property string gitSquare: "\uf1d2" + readonly property string github: "\uf09b" + readonly property string githubAlt: "\uf113" + readonly property string githubSquare: "\uf092" + readonly property string gittip: "\uf184" + readonly property string glass: "\uf000" + readonly property string globe: "\uf0ac" + readonly property string google: "\uf1a0" + readonly property string googlePlus: "\uf0d5" + readonly property string googlePlusSquare: "\uf0d4" + readonly property string googleWallet: "\uf1ee" + readonly property string graduationCap: "\uf19d" + readonly property string gratipay: "\uf184" + readonly property string group: "\uf0c0" + readonly property string hSquare: "\uf0fd" + readonly property string hackerNews: "\uf1d4" + readonly property string handGrabO: "\uf255" + readonly property string handLizardO: "\uf258" + readonly property string handODown: "\uf0a7" + readonly property string handOLeft: "\uf0a5" + readonly property string handORight: "\uf0a4" + readonly property string handOUp: "\uf0a6" + readonly property string handPaperO: "\uf256" + readonly property string handPeaceO: "\uf25b" + readonly property string handPointerO: "\uf25a" + readonly property string handRockO: "\uf255" + readonly property string handScissorsO: "\uf257" + readonly property string handSpockO: "\uf259" + readonly property string handStopO: "\uf256" + readonly property string hddO: "\uf0a0" + readonly property string header: "\uf1dc" + readonly property string headphones: "\uf025" + readonly property string heart: "\uf004" + readonly property string heartO: "\uf08a" + readonly property string heartbeat: "\uf21e" + readonly property string history: "\uf1da" + readonly property string home: "\uf015" + readonly property string hospitalO: "\uf0f8" + readonly property string hotel: "\uf236" + readonly property string hourglass: "\uf254" + readonly property string hourglass1: "\uf251" + readonly property string hourglass2: "\uf252" + readonly property string hourglass3: "\uf253" + readonly property string hourglassEnd: "\uf253" + readonly property string hourglassHalf: "\uf252" + readonly property string hourglassO: "\uf250" + readonly property string hourglassStart: "\uf251" + readonly property string houzz: "\uf27c" + readonly property string html5: "\uf13b" + readonly property string iCursor: "\uf246" + readonly property string ils: "\uf20b" + readonly property string image: "\uf03e" + readonly property string inbox: "\uf01c" + readonly property string indent: "\uf03c" + readonly property string industry: "\uf275" + readonly property string info: "\uf129" + readonly property string infoCircle: "\uf05a" + readonly property string inr: "\uf156" + readonly property string instagram: "\uf16d" + readonly property string institution: "\uf19c" + readonly property string internetExplorer: "\uf26b" + readonly property string intersex: "\uf224" + readonly property string ioxhost: "\uf208" + readonly property string italic: "\uf033" + readonly property string joomla: "\uf1aa" + readonly property string jpy: "\uf157" + readonly property string jsfiddle: "\uf1cc" + readonly property string key: "\uf084" + readonly property string keyboardO: "\uf11c" + readonly property string krw: "\uf159" + readonly property string language: "\uf1ab" + readonly property string laptop: "\uf109" + readonly property string lastfm: "\uf202" + readonly property string lastfmSquare: "\uf203" + readonly property string leaf: "\uf06c" + readonly property string leanpub: "\uf212" + readonly property string legal: "\uf0e3" + readonly property string lemonO: "\uf094" + readonly property string levelDown: "\uf149" + readonly property string levelUp: "\uf148" + readonly property string lifeBouy: "\uf1cd" + readonly property string lifeBuoy: "\uf1cd" + readonly property string lifeRing: "\uf1cd" + readonly property string lifeSaver: "\uf1cd" + readonly property string lightbulbO: "\uf0eb" + readonly property string lineChart: "\uf201" + readonly property string link: "\uf0c1" + readonly property string linkedin: "\uf0e1" + readonly property string linkedinSquare: "\uf08c" + readonly property string linux: "\uf17c" + readonly property string list: "\uf03a" + readonly property string listAlt: "\uf022" + readonly property string listOl: "\uf0cb" + readonly property string listUl: "\uf0ca" + readonly property string locationArrow: "\uf124" + readonly property string lock: "\uf023" + readonly property string longArrowDown: "\uf175" + readonly property string longArrowLeft: "\uf177" + readonly property string longArrowRight: "\uf178" + readonly property string longArrowUp: "\uf176" + readonly property string magic: "\uf0d0" + readonly property string magnet: "\uf076" + readonly property string mailForward: "\uf064" + readonly property string mailReply: "\uf112" + readonly property string mailReplyAll: "\uf122" + readonly property string male: "\uf183" + readonly property string map: "\uf279" + readonly property string mapMarker: "\uf041" + readonly property string mapO: "\uf278" + readonly property string mapPin: "\uf276" + readonly property string mapSigns: "\uf277" + readonly property string mars: "\uf222" + readonly property string marsDouble: "\uf227" + readonly property string marsStroke: "\uf229" + readonly property string marsStrokeH: "\uf22b" + readonly property string marsStrokeV: "\uf22a" + readonly property string maxcdn: "\uf136" + readonly property string meanpath: "\uf20c" + readonly property string medium: "\uf23a" + readonly property string medkit: "\uf0fa" + readonly property string mehO: "\uf11a" + readonly property string mercury: "\uf223" + readonly property string microphone: "\uf130" + readonly property string microphoneSlash: "\uf131" + readonly property string minus: "\uf068" + readonly property string minusCircle: "\uf056" + readonly property string minusSquare: "\uf146" + readonly property string minusSquareO: "\uf147" + readonly property string mobile: "\uf10b" + readonly property string mobilePhone: "\uf10b" + readonly property string money: "\uf0d6" + readonly property string moonO: "\uf186" + readonly property string mortarBoard: "\uf19d" + readonly property string motorcycle: "\uf21c" + readonly property string mousePointer: "\uf245" + readonly property string music: "\uf001" + readonly property string navicon: "\uf0c9" + readonly property string neuter: "\uf22c" + readonly property string newspaperO: "\uf1ea" + readonly property string objectGroup: "\uf247" + readonly property string objectUngroup: "\uf248" + readonly property string odnoklassniki: "\uf263" + readonly property string odnoklassnikiSquare: "\uf264" + readonly property string opencart: "\uf23d" + readonly property string openid: "\uf19b" + readonly property string opera: "\uf26a" + readonly property string optinMonster: "\uf23c" + readonly property string outdent: "\uf03b" + readonly property string pagelines: "\uf18c" + readonly property string paintBrush: "\uf1fc" + readonly property string paperPlane: "\uf1d8" + readonly property string paperPlaneO: "\uf1d9" + readonly property string paperclip: "\uf0c6" + readonly property string paragraph: "\uf1dd" + readonly property string paste: "\uf0ea" + readonly property string pause: "\uf04c" + readonly property string paw: "\uf1b0" + readonly property string paypal: "\uf1ed" + readonly property string pencil: "\uf040" + readonly property string pencilSquare: "\uf14b" + readonly property string pencilSquareO: "\uf044" + readonly property string phone: "\uf095" + readonly property string phoneSquare: "\uf098" + readonly property string photo: "\uf03e" + readonly property string pictureO: "\uf03e" + readonly property string pieChart: "\uf200" + readonly property string piedPiper: "\uf1a7" + readonly property string piedPiperAlt: "\uf1a8" + readonly property string pinterest: "\uf0d2" + readonly property string pinterestP: "\uf231" + readonly property string pinterestSquare: "\uf0d3" + readonly property string plane: "\uf072" + readonly property string play: "\uf04b" + readonly property string playCircle: "\uf144" + readonly property string playCircleO: "\uf01d" + readonly property string plug: "\uf1e6" + readonly property string plus: "\uf067" + readonly property string plusCircle: "\uf055" + readonly property string plusSquare: "\uf0fe" + readonly property string plusSquareO: "\uf196" + readonly property string powerOff: "\uf011" + // Manually edited. Was "print" + readonly property string printer: "\uf02f" + readonly property string puzzlePiece: "\uf12e" + readonly property string qq: "\uf1d6" + readonly property string qrcode: "\uf029" + readonly property string question: "\uf128" + readonly property string questionCircle: "\uf059" + readonly property string quoteLeft: "\uf10d" + readonly property string quoteRight: "\uf10e" + readonly property string ra: "\uf1d0" + readonly property string random: "\uf074" + readonly property string rebel: "\uf1d0" + readonly property string recycle: "\uf1b8" + readonly property string reddit: "\uf1a1" + readonly property string redditSquare: "\uf1a2" + readonly property string refresh: "\uf021" + readonly property string registered: "\uf25d" + readonly property string remove: "\uf00d" + readonly property string renren: "\uf18b" + readonly property string reorder: "\uf0c9" + readonly property string repeat: "\uf01e" + readonly property string reply: "\uf112" + readonly property string replyAll: "\uf122" + readonly property string retweet: "\uf079" + readonly property string rmb: "\uf157" + readonly property string road: "\uf018" + readonly property string rocket: "\uf135" + readonly property string rotateLeft: "\uf0e2" + readonly property string rotateRight: "\uf01e" + readonly property string rouble: "\uf158" + readonly property string rss: "\uf09e" + readonly property string rssSquare: "\uf143" + readonly property string rub: "\uf158" + readonly property string ruble: "\uf158" + readonly property string rupee: "\uf156" + readonly property string safari: "\uf267" + readonly property string save: "\uf0c7" + readonly property string scissors: "\uf0c4" + readonly property string search: "\uf002" + readonly property string searchMinus: "\uf010" + readonly property string searchPlus: "\uf00e" + readonly property string sellsy: "\uf213" + readonly property string send: "\uf1d8" + readonly property string sendO: "\uf1d9" + readonly property string server: "\uf233" + readonly property string share: "\uf064" + readonly property string shareAlt: "\uf1e0" + readonly property string shareAltSquare: "\uf1e1" + readonly property string shareSquare: "\uf14d" + readonly property string shareSquareO: "\uf045" + readonly property string shekel: "\uf20b" + readonly property string sheqel: "\uf20b" + readonly property string shield: "\uf132" + readonly property string ship: "\uf21a" + readonly property string shirtsinbulk: "\uf214" + readonly property string shoppingCart: "\uf07a" + readonly property string signIn: "\uf090" + readonly property string signOut: "\uf08b" + readonly property string signal: "\uf012" + readonly property string simplybuilt: "\uf215" + readonly property string sitemap: "\uf0e8" + readonly property string skyatlas: "\uf216" + readonly property string skype: "\uf17e" + readonly property string slack: "\uf198" + readonly property string sliders: "\uf1de" + readonly property string slideshare: "\uf1e7" + readonly property string smileO: "\uf118" + readonly property string soccerBallO: "\uf1e3" + readonly property string sort: "\uf0dc" + readonly property string sortAlphaAsc: "\uf15d" + readonly property string sortAlphaDesc: "\uf15e" + readonly property string sortAmountAsc: "\uf160" + readonly property string sortAmountDesc: "\uf161" + readonly property string sortAsc: "\uf0de" + readonly property string sortDesc: "\uf0dd" + readonly property string sortDown: "\uf0dd" + readonly property string sortNumericAsc: "\uf162" + readonly property string sortNumericDesc: "\uf163" + readonly property string sortUp: "\uf0de" + readonly property string soundcloud: "\uf1be" + readonly property string spaceShuttle: "\uf197" + readonly property string spinner: "\uf110" + readonly property string spoon: "\uf1b1" + readonly property string spotify: "\uf1bc" + readonly property string square: "\uf0c8" + readonly property string squareO: "\uf096" + readonly property string stackExchange: "\uf18d" + readonly property string stackOverflow: "\uf16c" + readonly property string star: "\uf005" + readonly property string starHalf: "\uf089" + readonly property string starHalfEmpty: "\uf123" + readonly property string starHalfFull: "\uf123" + readonly property string starHalfO: "\uf123" + readonly property string starO: "\uf006" + readonly property string steam: "\uf1b6" + readonly property string steamSquare: "\uf1b7" + readonly property string stepBackward: "\uf048" + readonly property string stepForward: "\uf051" + readonly property string stethoscope: "\uf0f1" + readonly property string stickyNote: "\uf249" + readonly property string stickyNoteO: "\uf24a" + readonly property string stop: "\uf04d" + readonly property string streetView: "\uf21d" + readonly property string strikethrough: "\uf0cc" + readonly property string stumbleupon: "\uf1a4" + readonly property string stumbleuponCircle: "\uf1a3" + readonly property string subscript: "\uf12c" + readonly property string subway: "\uf239" + readonly property string suitcase: "\uf0f2" + readonly property string sunO: "\uf185" + readonly property string superscript: "\uf12b" + readonly property string support: "\uf1cd" + readonly property string table: "\uf0ce" + readonly property string tablet: "\uf10a" + readonly property string tachometer: "\uf0e4" + readonly property string tag: "\uf02b" + readonly property string tags: "\uf02c" + readonly property string tasks: "\uf0ae" + readonly property string taxi: "\uf1ba" + readonly property string television: "\uf26c" + readonly property string tencentWeibo: "\uf1d5" + readonly property string terminal: "\uf120" + readonly property string textHeight: "\uf034" + readonly property string textWidth: "\uf035" + readonly property string th: "\uf00a" + readonly property string thLarge: "\uf009" + readonly property string thList: "\uf00b" + readonly property string thumbTack: "\uf08d" + readonly property string thumbsDown: "\uf165" + readonly property string thumbsODown: "\uf088" + readonly property string thumbsOUp: "\uf087" + readonly property string thumbsUp: "\uf164" + readonly property string ticket: "\uf145" + readonly property string times: "\uf00d" + readonly property string timesCircle: "\uf057" + readonly property string timesCircleO: "\uf05c" + readonly property string tint: "\uf043" + readonly property string toggleDown: "\uf150" + readonly property string toggleLeft: "\uf191" + readonly property string toggleOff: "\uf204" + readonly property string toggleOn: "\uf205" + readonly property string toggleRight: "\uf152" + readonly property string toggleUp: "\uf151" + readonly property string trademark: "\uf25c" + readonly property string train: "\uf238" + readonly property string transgender: "\uf224" + readonly property string transgenderAlt: "\uf225" + readonly property string trash: "\uf1f8" + readonly property string trashO: "\uf014" + readonly property string tree: "\uf1bb" + readonly property string trello: "\uf181" + readonly property string tripadvisor: "\uf262" + readonly property string trophy: "\uf091" + readonly property string truck: "\uf0d1" + // Reserved word. Use turkishLira + // readonly property string try: "\uf195" + readonly property string tty: "\uf1e4" + readonly property string tumblr: "\uf173" + readonly property string tumblrSquare: "\uf174" + readonly property string turkishLira: "\uf195" + readonly property string tv: "\uf26c" + readonly property string twitch: "\uf1e8" + readonly property string twitter: "\uf099" + readonly property string twitterSquare: "\uf081" + readonly property string umbrella: "\uf0e9" + readonly property string underline: "\uf0cd" + readonly property string undo: "\uf0e2" + readonly property string university: "\uf19c" + readonly property string unlink: "\uf127" + readonly property string unlock: "\uf09c" + readonly property string unlockAlt: "\uf13e" + readonly property string unsorted: "\uf0dc" + readonly property string upload: "\uf093" + readonly property string usd: "\uf155" + readonly property string user: "\uf007" + readonly property string userMd: "\uf0f0" + readonly property string userPlus: "\uf234" + readonly property string userSecret: "\uf21b" + readonly property string userTimes: "\uf235" + readonly property string users: "\uf0c0" + readonly property string venus: "\uf221" + readonly property string venusDouble: "\uf226" + readonly property string venusMars: "\uf228" + readonly property string viacoin: "\uf237" + readonly property string videoCamera: "\uf03d" + readonly property string vimeo: "\uf27d" + readonly property string vimeoSquare: "\uf194" + readonly property string vine: "\uf1ca" + readonly property string vk: "\uf189" + readonly property string volumeDown: "\uf027" + readonly property string volumeOff: "\uf026" + readonly property string volumeUp: "\uf028" + readonly property string warning: "\uf071" + readonly property string wechat: "\uf1d7" + readonly property string weibo: "\uf18a" + readonly property string weixin: "\uf1d7" + readonly property string whatsapp: "\uf232" + readonly property string wheelchair: "\uf193" + readonly property string wifi: "\uf1eb" + readonly property string wikipediaW: "\uf266" + readonly property string windows: "\uf17a" + readonly property string won: "\uf159" + readonly property string wordpress: "\uf19a" + readonly property string wrench: "\uf0ad" + readonly property string xing: "\uf168" + readonly property string xingSquare: "\uf169" + readonly property string yCombinator: "\uf23b" + readonly property string yCombinatorSquare: "\uf1d4" + readonly property string yahoo: "\uf19e" + readonly property string yc: "\uf23b" + readonly property string ycSquare: "\uf1d4" + readonly property string yelp: "\uf1e9" + readonly property string yen: "\uf157" + readonly property string youtube: "\uf167" + readonly property string youtubePlay: "\uf16a" + readonly property string youtubeSquare: "\uf166" +} diff --git a/tests/manual/quickcontrols2/shared/FontAwesomeIcon.qml b/tests/manual/quickcontrols2/shared/FontAwesomeIcon.qml new file mode 100644 index 00000000000..74e7c5da129 --- /dev/null +++ b/tests/manual/quickcontrols2/shared/FontAwesomeIcon.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick +import "qrc:/shared" + +Text { + id: icon + property alias iconId: icon.text + property alias size: icon.font.pixelSize + font.family: FontAwesome.fontLoader.name +} diff --git a/tests/manual/quickcontrols2/shared/qmldir b/tests/manual/quickcontrols2/shared/qmldir new file mode 100644 index 00000000000..3cb55667c7a --- /dev/null +++ b/tests/manual/quickcontrols2/shared/qmldir @@ -0,0 +1,4 @@ +depends QtQuick 2.6 +singleton FontAwesome 1.0 FontAwesome.qml +FontAwesomeIcon 1.0 FontAwesomeIcon.qml + diff --git a/tests/manual/quickcontrols2/shared/shared.qrc b/tests/manual/quickcontrols2/shared/shared.qrc new file mode 100644 index 00000000000..8dbb3421568 --- /dev/null +++ b/tests/manual/quickcontrols2/shared/shared.qrc @@ -0,0 +1,8 @@ +<RCC> + <qresource prefix="/shared"> + <file>FontAwesome.qml</file> + <file>FontAwesomeIcon.qml</file> + <file>FontAwesome.otf</file> + <file>qmldir</file> + </qresource> +</RCC> diff --git a/tests/manual/quickcontrols2/styles-cover-flow/CMakeLists.txt b/tests/manual/quickcontrols2/styles-cover-flow/CMakeLists.txt new file mode 100644 index 00000000000..84d8460ad84 --- /dev/null +++ b/tests/manual/quickcontrols2/styles-cover-flow/CMakeLists.txt @@ -0,0 +1,44 @@ +# Generated from styles-cover-flow.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(styles-cover-flow LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## stylescoverflow Binary: +##################################################################### + +qt_internal_add_manual_test(stylescoverflow + GUI + SOURCES + styles-cover-flow.cpp + DEFINES + DOC_IMAGES_DIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/imports/controls/doc/images/\\\" + PUBLIC_LIBRARIES + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) + +file(GLOB resource_glob_0 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.qml,") +foreach(file IN LISTS resource_glob_0) + set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}") +endforeach() + +# Resources: +set(qmake_immediate_resource_files + ${resource_glob_0} +) + +qt_internal_add_resource(stylescoverflow "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + + +#### Keys ignored in scope 1:.:.:styles-cover-flow.pro:<TRUE>: +# TEMPLATE = "app" diff --git a/tests/manual/quickcontrols2/styles-cover-flow/CoverFlowDelegate.qml b/tests/manual/quickcontrols2/styles-cover-flow/CoverFlowDelegate.qml new file mode 100644 index 00000000000..061ecfa0a85 --- /dev/null +++ b/tests/manual/quickcontrols2/styles-cover-flow/CoverFlowDelegate.qml @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtGraphicalEffects +import QtQuick + +Item { + id: root + width: PathView.view.delegateSize + height: width + z: PathView.zOrder + + transform: [ + Rotation { + angle: root.PathView.rotateY + origin.x: sourceImage.width / 2 + origin.y: sourceImage.height * 0.3 + axis.x: 0 + axis.y: 1 + axis.z: 0 + }, + Scale { + xScale: 1.0 + yScale: root.PathView.scale + origin.x: sourceImage.width / 2 + origin.y: sourceImage.height * 0.4 + } + ] + + Image { + id: sourceImage + width: root.PathView.view.delegateSize + height: width + fillMode: Image.PreserveAspectFit + source: "file:/" + docImagesDir + model.source + + Rectangle { + x: (sourceImage.width - sourceImage.paintedWidth) / 2 + width: sourceImage.paintedWidth + (index == 6 ? 2 : 1) + height: sourceImage.height + color: "transparent" + border.color: "#f4f4f4" + antialiasing: true + visible: !model.dark + } + } + + ShaderEffectSource { + id: reflection + sourceItem: sourceImage + y: sourceItem.height + width: sourceItem.width + height: sourceItem.height + + transform: [ + Rotation { + origin.x: reflection.width / 2 + origin.y: reflection.height / 2 + axis.x: 1 + axis.y: 0 + axis.z: 0 + angle: 180 + } + ] + } + + Rectangle { + objectName: sourceImage.source.toString().slice(-20) + x: (parent.width - sourceImage.paintedWidth) / 2// + (paintedWidthDiff > 0 ? 1.0 - paintedWidthDiff : 0) + y: reflection.y + width: sourceImage.paintedWidth + (index == 6 ? 2 : 1) + height: sourceImage.paintedHeight + + // TODO: figure out how to get perfect x/width without using the current width hack +// readonly property real paintedWidthDiff: sourceImage.paintedWidth - Math.floor(sourceImage.paintedWidth) + + gradient: Gradient { + GradientStop { + position: 0.0 + color: Qt.rgba(backgroundColor.r, backgroundColor.g, backgroundColor.b, 0.33) + } + GradientStop { + // This determines the point at which the reflection fades out. + position: 1.0 + color: backgroundColor + } + } + } +} diff --git a/tests/manual/quickcontrols2/styles-cover-flow/CoverFlowPath.qml b/tests/manual/quickcontrols2/styles-cover-flow/CoverFlowPath.qml new file mode 100644 index 00000000000..0f70e6b8909 --- /dev/null +++ b/tests/manual/quickcontrols2/styles-cover-flow/CoverFlowPath.qml @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Path { + // Point 1 + property PathView pathView + + startX: 0 + startY: pathView.centerY + + PathAttribute { + name: "rotateY" + value: 50.0 + } + PathAttribute { + name: "scale" + value: 0.7 + } + PathAttribute { + name: "zOrder" + value: 1.0 + } + + // Line to point 2 + PathLine { + x: pathView.centerX - pathView.delegateSize * 0.4 + y: pathView.centerY + } + PathPercent { + value: 0.44 + } + PathAttribute { + name: "rotateY" + value: 50.0 + } + PathAttribute { + name: "scale" + value: 0.7 + } + PathAttribute { + name: "zOrder" + value: 10.0 + } + + // Quad to point 3 + PathQuad { + x: pathView.centerX + y: pathView.centerY + pathView.delegateSize * 0.04 + controlX: pathView.centerX - pathView.delegateSize * 0.2 + controlY: pathView.centerY + pathView.delegateSize * 0.04 + } + PathPercent { + value: 0.5 + } + PathAttribute { + name: "rotateY" + value: 0.0 + } + PathAttribute { + name: "scale" + value: 1.0 + } + PathAttribute { + name: "zOrder" + value: 50.0 + } + + // Quad to point 4 + PathQuad { + x: pathView.centerX + pathView.delegateSize * 0.4 + y: pathView.centerY + controlX: pathView.centerX + pathView.delegateSize * 0.2 + controlY: pathView.centerY + pathView.delegateSize * 0.04 + } + PathPercent { + value: 0.56 + } + PathAttribute { + name: "rotateY" + value: -50.0 + } + PathAttribute { + name: "scale" + value: 0.7 + } + PathAttribute { + name: "zOrder" + value: 10.0 + } + + // Line to point 5 + PathLine { + x: pathView.width + y: pathView.centerY + } + PathAttribute { + name: "rotateY" + value: -50.0 + } + PathAttribute { + name: "scale" + value: 0.7 + } + PathAttribute { + name: "zOrder" + value: 1.0 + } +} diff --git a/tests/manual/quickcontrols2/styles-cover-flow/styles-cover-flow.cpp b/tests/manual/quickcontrols2/styles-cover-flow/styles-cover-flow.cpp new file mode 100644 index 00000000000..d665d6139b8 --- /dev/null +++ b/tests/manual/quickcontrols2/styles-cover-flow/styles-cover-flow.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QQmlContext> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.rootContext()->setContextProperty("docImagesDir", QString(DOC_IMAGES_DIR)); + engine.load(QUrl("qrc:/styles-cover-flow.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/tests/manual/quickcontrols2/styles-cover-flow/styles-cover-flow.pro b/tests/manual/quickcontrols2/styles-cover-flow/styles-cover-flow.pro new file mode 100644 index 00000000000..2faa9fbabb5 --- /dev/null +++ b/tests/manual/quickcontrols2/styles-cover-flow/styles-cover-flow.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = stylescoverflow +QT += quick quickcontrols2 + +SOURCES += \ + styles-cover-flow.cpp + +RESOURCES += \ + $$files(*.qml, true) + +DEFINES += DOC_IMAGES_DIR=\\\"$$PWD/../../../src/imports/controls/doc/images/\\\" diff --git a/tests/manual/quickcontrols2/styles-cover-flow/styles-cover-flow.qml b/tests/manual/quickcontrols2/styles-cover-flow/styles-cover-flow.qml new file mode 100644 index 00000000000..0f400c0d5ed --- /dev/null +++ b/tests/manual/quickcontrols2/styles-cover-flow/styles-cover-flow.qml @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window + +Window { + // Different delegate positions and widths and window background colors + // can cause some unwanted "rogue pixels", so an easy way to get it perfect + // is to mess with the width. + width: 814 + height: 512 + visible: true + color: backgroundColor + flags: Qt.FramelessWindowHint + + readonly property color backgroundColor: "#ffffff" + + Shortcut { + sequence: "Ctrl+Q" + onActivated: Qt.quit() + } + + PathView { + id: view + anchors.fill: parent + anchors.leftMargin: 130 + anchors.rightMargin: 130 + model: ListModel { + ListElement { source: "qtquickcontrols2-basic.png"; dark: false } + ListElement { source: "qtquickcontrols2-fusion.png"; dark: false } + ListElement { source: "qtquickcontrols2-universal-light.png"; dark: false } + ListElement { source: "qtquickcontrols2-universal-dark.png"; dark: true } + ListElement { source: "qtquickcontrols2-material-dark.png"; dark: true } + ListElement { source: "qtquickcontrols2-imagine.png"; dark: false } + ListElement { source: "qtquickcontrols2-material-light.png"; dark: false } + } + + highlightRangeMode: PathView.StrictlyEnforceRange + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + pathItemCount: 9 + + property real centerX: width / 2 + property real centerY: height * 0.4 + property real delegateSize: 393 / 2 + + path: CoverFlowPath { + pathView: view + } + delegate: CoverFlowDelegate {} + } +} diff --git a/tests/manual/quickcontrols2/styles/CMakeLists.txt b/tests/manual/quickcontrols2/styles/CMakeLists.txt new file mode 100644 index 00000000000..7ba6c733bbb --- /dev/null +++ b/tests/manual/quickcontrols2/styles/CMakeLists.txt @@ -0,0 +1,37 @@ +# Generated from styles.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(styles LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## styles Binary: +##################################################################### + +qt_internal_add_manual_test(styles + GUI + SOURCES + styles.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) + +# Resources: +set(qmake_immediate_resource_files + "styles.qml" +) + +qt_internal_add_resource(styles "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) + + +#### Keys ignored in scope 1:.:.:styles.pro:<TRUE>: +# TEMPLATE = "app" diff --git a/tests/manual/quickcontrols2/styles/styles.cpp b/tests/manual/quickcontrols2/styles/styles.cpp new file mode 100644 index 00000000000..a0f0de7b081 --- /dev/null +++ b/tests/manual/quickcontrols2/styles/styles.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/styles.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/tests/manual/quickcontrols2/styles/styles.pro b/tests/manual/quickcontrols2/styles/styles.pro new file mode 100644 index 00000000000..060ab4f7e82 --- /dev/null +++ b/tests/manual/quickcontrols2/styles/styles.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = styles +QT += quick quickcontrols2 + +SOURCES += \ + styles.cpp + +RESOURCES += \ + styles.qml diff --git a/tests/manual/quickcontrols2/styles/styles.qml b/tests/manual/quickcontrols2/styles/styles.qml new file mode 100644 index 00000000000..83bd9b34412 --- /dev/null +++ b/tests/manual/quickcontrols2/styles/styles.qml @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +ApplicationWindow { + id: window + + visible: true + minimumWidth: column.implicitWidth + 80 + minimumHeight: column.implicitHeight + 80 + title: "Qt Quick Controls 2 - Styles" + + // for taking frameless screenshots: + // flags: Qt.Window | Qt.FramelessWindowHint + + ColumnLayout { + id: column + + spacing: 20 + anchors.fill: parent + anchors.margins: 40 + + GroupBox { + title: "Font Size" + topPadding: 30 + background.visible: false + + ColumnLayout { + anchors.fill: parent + anchors.leftMargin: 20 + + RadioButton { leftPadding: 0; text: "Small" } + RadioButton { leftPadding: 0; text: "Medium"; checked: true } + RadioButton { leftPadding: 0; text: "Large" } + } + } + + GroupBox { + title: "Audio" + topPadding: 30 + background.visible: false + + GridLayout { + columns: 2 + columnSpacing: 30 + anchors.fill: parent + anchors.leftMargin: 20 + + Label { text: "Volume" } + Slider { value: 1.0 } + Label { text: "Bass" } + Slider { value: 0.75 } + Label { text: "Treble" } + Slider { value: 0.5 } + } + } + + Button { + text: "Save" + Layout.alignment: Qt.AlignRight + } + + Item { Layout.fillHeight: true } + } +} diff --git a/tests/manual/quickcontrols2/swipedelegate/CloseOnCompletedWorks.qml b/tests/manual/quickcontrols2/swipedelegate/CloseOnCompletedWorks.qml new file mode 100644 index 00000000000..38dfde41c34 --- /dev/null +++ b/tests/manual/quickcontrols2/swipedelegate/CloseOnCompletedWorks.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2 +import QtQuick.Controls 2 +ApplicationWindow { + visible: true + width: 640 + height: 480 + + ListView { + anchors.fill: parent + model: 2 + + delegate: SwipeDelegate { + text: "Swipe me left (should not crash)" + + swipe.right: Label { + text: "Release (should not crash)" + } + + swipe.onCompleted: { + swipe.close() + } + } + } +} diff --git a/tests/manual/quickcontrols2/systemtrayicon/CMakeLists.txt b/tests/manual/quickcontrols2/systemtrayicon/CMakeLists.txt new file mode 100644 index 00000000000..b44a44967a1 --- /dev/null +++ b/tests/manual/quickcontrols2/systemtrayicon/CMakeLists.txt @@ -0,0 +1,38 @@ +# Generated from systemtrayicon.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(systemtrayicon LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## systemtrayicon Binary: +##################################################################### + +qt_internal_add_manual_test(systemtrayicon + GUI + SOURCES + systemtrayicon.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) + +# Resources: +set(systemtrayicon_resource_files + "images/qt_logo_green_256.png" + "systemtrayicon.qml" +) + +qt_internal_add_resource(systemtrayicon "systemtrayicon" + PREFIX + "/files" + FILES + ${systemtrayicon_resource_files} +) + + +#### Keys ignored in scope 1:.:.:systemtrayicon.pro:<TRUE>: +# TEMPLATE = "app" diff --git a/tests/manual/quickcontrols2/systemtrayicon/images/qt_logo_green_256.png b/tests/manual/quickcontrols2/systemtrayicon/images/qt_logo_green_256.png new file mode 100644 index 00000000000..a7b16ba4f92 Binary files /dev/null and b/tests/manual/quickcontrols2/systemtrayicon/images/qt_logo_green_256.png differ diff --git a/tests/manual/quickcontrols2/systemtrayicon/systemtrayicon.cpp b/tests/manual/quickcontrols2/systemtrayicon/systemtrayicon.cpp new file mode 100644 index 00000000000..1866a269bfc --- /dev/null +++ b/tests/manual/quickcontrols2/systemtrayicon/systemtrayicon.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/files/systemtrayicon.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/tests/manual/quickcontrols2/systemtrayicon/systemtrayicon.pro b/tests/manual/quickcontrols2/systemtrayicon/systemtrayicon.pro new file mode 100644 index 00000000000..24b9caa0cf1 --- /dev/null +++ b/tests/manual/quickcontrols2/systemtrayicon/systemtrayicon.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = systemtrayicon +QT += quick quickcontrols2 + +SOURCES += \ + systemtrayicon.cpp + +RESOURCES += \ + systemtrayicon.qrc diff --git a/tests/manual/quickcontrols2/systemtrayicon/systemtrayicon.qml b/tests/manual/quickcontrols2/systemtrayicon/systemtrayicon.qml new file mode 100644 index 00000000000..d44bc83b47c --- /dev/null +++ b/tests/manual/quickcontrols2/systemtrayicon/systemtrayicon.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import Qt.labs.platform + +ApplicationWindow { + id: window + + visible: true + title: "Qt Quick Controls 2 - System Tray Icon" + + MenuBar { + id: menuBar + + Menu { + id: fileMenu + title: qsTr("File") + + MenuItem { + id : quitItem + text : "Quit" + onTriggered: Qt.quit() + } + } + } + + SystemTrayIcon { + visible: true + icon.source: "qrc:/files/images/qt_logo_green_256.png" + + menu: Menu { + MenuItem { + text: qsTr("Quit") + onTriggered: Qt.quit() + } + } + + onActivated: console.log("Activated") + } +} diff --git a/tests/manual/quickcontrols2/systemtrayicon/systemtrayicon.qrc b/tests/manual/quickcontrols2/systemtrayicon/systemtrayicon.qrc new file mode 100644 index 00000000000..656476d940e --- /dev/null +++ b/tests/manual/quickcontrols2/systemtrayicon/systemtrayicon.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/files"> + <file>systemtrayicon.qml</file> + <file>images/qt_logo_green_256.png</file> + </qresource> +</RCC> diff --git a/tests/manual/quickcontrols2/testbench/+Imagine/ApplicationWindow.qml b/tests/manual/quickcontrols2/testbench/+Imagine/ApplicationWindow.qml new file mode 100644 index 00000000000..a8e49b073c5 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/+Imagine/ApplicationWindow.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls.Imagine + +ApplicationWindow { + Imagine.path: defaultImaginePath +} diff --git a/tests/manual/quickcontrols2/testbench/+Imagine/ContentPane.qml b/tests/manual/quickcontrols2/testbench/+Imagine/ContentPane.qml new file mode 100644 index 00000000000..3e1cad864e6 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/+Imagine/ContentPane.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls.Imagine + +Pane { + Imagine.path: settings.useCustomImaginePath && settings.imaginePath.length > 0 ? settings.imaginePath : undefined +} diff --git a/tests/manual/quickcontrols2/testbench/+Imagine/Dialog.qml b/tests/manual/quickcontrols2/testbench/+Imagine/Dialog.qml new file mode 100644 index 00000000000..7ea9619e955 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/+Imagine/Dialog.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls.Imagine + +Dialog { + Imagine.path: defaultImaginePath +} diff --git a/tests/manual/quickcontrols2/testbench/+Imagine/Menu.qml b/tests/manual/quickcontrols2/testbench/+Imagine/Menu.qml new file mode 100644 index 00000000000..9587e0d4c08 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/+Imagine/Menu.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls.Imagine + +Menu { + Imagine.path: defaultImaginePath +} diff --git a/tests/manual/quickcontrols2/testbench/+Imagine/ToolBar.qml b/tests/manual/quickcontrols2/testbench/+Imagine/ToolBar.qml new file mode 100644 index 00000000000..b1b32894a0b --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/+Imagine/ToolBar.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls.Imagine + +ToolBar { + // Seems to be necessary to get the default assets to be used here, + // though it should inherit the window's path + Imagine.path: defaultImaginePath +} diff --git a/tests/manual/quickcontrols2/testbench/.gitignore b/tests/manual/quickcontrols2/testbench/.gitignore new file mode 100644 index 00000000000..75fae8bc392 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/.gitignore @@ -0,0 +1,83 @@ +testbench +*.png +*.so +*.so.* +*.app +*.exe +*.dll +*.dylib +*.lib +*.exp +*.a +*.la +*.core +*.moc +*.o +*.obj +*.orig +*.swp +*.rej +*.so +*.pbxuser +*.mode1 +*.mode1v3 +*_pch.h.cpp +*_resource.rc +*~ +.#* +*.*# +.qmake.stash +.qmake.cache +.qmake.vars +*.prl +tags +.DS_Store +*.debug +Makefile* +*.Debug +*.Release +*.prl +*.pro.user +*.qmlproject.user* +moc_*.h +moc_*.cpp +ui_*.h +qrc_*.cpp +callgrind.out.* +pcviewer.cfg +*.flc +.*.swp +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +.pch +.rcc +.project +.cproject +.make.cache +android-build +app_process +qtc-debugging-helper +android-*.so-deployment-settings.json +*.directory +*_plugin_import.cpp +*_wrapper.sh +*_wrapper.bat +*.mak +*.xib +*.plist +*.pbxproj +*_plugin_import.cpp +*.xcsettings +*.xcscheme +*.xcodeproj +qt.conf +*.version +*.version.in +*.qmlc diff --git a/tests/manual/quickcontrols2/testbench/ApplicationWindow.qml b/tests/manual/quickcontrols2/testbench/ApplicationWindow.qml new file mode 100644 index 00000000000..3c6785c9131 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/ApplicationWindow.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls + +ApplicationWindow {} diff --git a/tests/manual/quickcontrols2/testbench/CMakeLists.txt b/tests/manual/quickcontrols2/testbench/CMakeLists.txt new file mode 100644 index 00000000000..42113cdd1e3 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/CMakeLists.txt @@ -0,0 +1,116 @@ +# Generated from testbench.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(testbench LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## testbench Binary: +##################################################################### + +qt_internal_add_manual_test(testbench + GUI + SOURCES + assetfixer.cpp assetfixer.h + clipboard.cpp clipboard.h + directoryvalidator.cpp directoryvalidator.h + main.cpp + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::Qml + Qt::Quick + Qt::QuickControls2 + Qt::QuickControls2Private +) + +# Resources: +set(qml_resource_files + "+Imagine/ApplicationWindow.qml" + "+Imagine/ContentPane.qml" + "+Imagine/Dialog.qml" + "+Imagine/Menu.qml" + "+Imagine/ToolBar.qml" + "ApplicationWindow.qml" + "ColorEditor.qml" + "ContentPane.qml" + "ControlContainer.qml" + "Dialog.qml" + "ExampleContainer.qml" + "Menu.qml" + "SettingsDialog.qml" + "ToolBar.qml" + "controls/BusyIndicator.qml" + "controls/Button.qml" + "controls/CheckBox.qml" + "controls/CheckDelegate.qml" + "controls/ComboBox.qml" + "controls/DelayButton.qml" + "controls/Dial.qml" + "controls/Dialog.qml" + "controls/Frame.qml" + "controls/GroupBox.qml" + "controls/ItemDelegate.qml" + "controls/Label.qml" + "controls/Menu.qml" + "controls/MenuBar.qml" + "controls/Page.qml" + "controls/PageIndicator.qml" + "controls/Pane.qml" + "controls/ProgressBar.qml" + "controls/RadioButton.qml" + "controls/RadioDelegate.qml" + "controls/RangeSlider.qml" + "controls/RoundButton.qml" + "controls/ScrollBar.qml" + "controls/ScrollIndicator.qml" + "controls/Slider.qml" + "controls/SpinBox.qml" + "controls/SplitView.qml" + "controls/SwipeDelegate.qml" + "controls/Switch.qml" + "controls/SwitchDelegate.qml" + "controls/TabBar.qml" + "controls/TextArea.qml" + "controls/TextField.qml" + "controls/ToolBar.qml" + "controls/ToolTip.qml" + "controls/Tumbler.qml" + "testbench.qml" +) + +qt_internal_add_resource(testbench "qml" + PREFIX + "/" + FILES + ${qml_resource_files} +) +set(fonts_resource_files + "fonts/fontawesome.ttf" +) + +qt_internal_add_resource(testbench "fonts" + PREFIX + "/" + FILES + ${fonts_resource_files} +) + + +#### Keys ignored in scope 1:.:.:testbench.pro:<TRUE>: +# QML_IMPORT_PATH = <EMPTY> +# TEMPLATE = "app" + +## Scopes: +##################################################################### + +#### Keys ignored in scope 3:.:.:deployment.pri:UNIX AND NOT ANDROID: +# INSTALLS = "target" + +#### Keys ignored in scope 5:.:.:deployment.pri:QNX: +# target.path = "/tmp/$${TARGET}/bin" + +#### Keys ignored in scope 6:.:.:deployment.pri:else: +# target.path = "/opt/$${TARGET}/bin" diff --git a/tests/manual/quickcontrols2/testbench/ColorEditor.qml b/tests/manual/quickcontrols2/testbench/ColorEditor.qml new file mode 100644 index 00000000000..2723f33dfc3 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/ColorEditor.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +RowLayout { + property alias labelText: label.text + property string toolTipText + property alias color: textField.text + + ToolTip.text: toolTipText + ToolTip.visible: textField.hovered + + Layout.columnSpan: 2 + + Label { + id: label + + Layout.fillWidth: true + } + + TextField { + id: textField + + validator: RegularExpressionValidator{ + regularExpression: /#?[0-9a-fA-F]*/ + } + + Layout.preferredWidth: 200 + } +} diff --git a/tests/manual/quickcontrols2/testbench/ContentPane.qml b/tests/manual/quickcontrols2/testbench/ContentPane.qml new file mode 100644 index 00000000000..0a8c2f826cb --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/ContentPane.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls + +Pane {} diff --git a/tests/manual/quickcontrols2/testbench/ControlContainer.qml b/tests/manual/quickcontrols2/testbench/ControlContainer.qml new file mode 100644 index 00000000000..7ad524214d6 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/ControlContainer.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Item { + id: container + + implicitWidth: delegate.implicitWidth + implicitHeight: delegate.implicitHeight + enabled: false + + property var controlMetaObject + property var states + + Loader { + id: delegate + sourceComponent: controlMetaObject ? controlMetaObject.component : null + + function is(state) { + return container.states.indexOf(state) !== -1 + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/Dialog.qml b/tests/manual/quickcontrols2/testbench/Dialog.qml new file mode 100644 index 00000000000..32c4806a5af --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/Dialog.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls + +Dialog {} diff --git a/tests/manual/quickcontrols2/testbench/ExampleContainer.qml b/tests/manual/quickcontrols2/testbench/ExampleContainer.qml new file mode 100644 index 00000000000..903e52db3e0 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/ExampleContainer.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Frame { + id: container + + property var controlMetaObject + + ColumnLayout { + id: exampleLayout + anchors.centerIn: parent + + Label { + text: !exampleLoader.active ? qsTr("Show example") : qsTr("Hide example") + + Layout.alignment: Qt.AlignHCenter + + MouseArea { + anchors.fill: parent + onClicked: exampleLoader.active = !exampleLoader.active + } + } + + Loader { + id: exampleLoader + active: false + sourceComponent: controlMetaObject ? controlMetaObject.exampleComponent : null + + Layout.preferredHeight: active ? item.implicitHeight : 0 + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/Menu.qml b/tests/manual/quickcontrols2/testbench/Menu.qml new file mode 100644 index 00000000000..377cc3a057c --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/Menu.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls + +Menu {} diff --git a/tests/manual/quickcontrols2/testbench/README.md b/tests/manual/quickcontrols2/testbench/README.md new file mode 100644 index 00000000000..bd434de6a2b --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/README.md @@ -0,0 +1,35 @@ +# Style Testbench + +The Style Testbench provides a way to quickly see how controls look in different states with a given style. + +When run with the Imagine style, the testbench will react to changes to image assets and automatically fix and reload them. +To use this functionality, click on the settings icon and then the settings menu item. +From there, check "Use Custom Imagine Style Assets" and provide a path to your custom assets in the text field. +If you want your 9-patch assets to be automatically fixed up (e.g. turn 4 pixel-thick 9-patch lines exported at +@4x to a 1 pixel-thick line), check "Fix Imagine Style Assets". + +## Custom Text colors + +To use custom text colors, enable the "Use Custom Palette" option in the settings dialog, and then provide colors in the relevant fields. As an example, the WindowText palette role affects text that is displayed directly against the window (labels, flat button text, etc.), ButtonText affects text that is displayed against a button's background, and so on. A full list of color roles can be found here: + +http://doc.qt.io/qt-5/qpalette.html#ColorRole-enum + +The custom text color settings apply to every style that supports palettes, until turned off. + +The "Copy Palette Settings To Clipboard" button in the settings dialog can be used to copy the current colors and share them with others. Once someone has your custom colors, they can import them with the "Imort Palette Settings From Clipboard" button. + +## Tips + +- Ensure that 9-patch lines are black (#000000) or red (#ff0000). If these colors are slightly + off (e.g. #010101), the assets won't display correctly when run in the application. +- Don't use pure black in assets that have black 9-patch lines, as this will confuse the asset fixer. + +## Shortcuts + +| Name | Shortcut | Shortcut (Mac) | Description | +|-------------------|--------------|----------------|--------------------------------------------------------------------------------------------------------------------------------------------------| +| Use Custom Assets | Ctrl+Shift+C | ⌘+Shift+C | If using the Imagine style, toggles between the default assets and the user's custom assets. Custom assets are specified in the settings dialog. | +| Fix Custom Assets | Ctrl+Shift+X | ⌘+Shift+X | If using the Imagine style, manually fixes the assets. This is done automatically when "Automatically Fix Custom Assets" checkbox is checked. | +| Reload Assets | Ctrl+R | ⌘+R | If using the Imagine style, reloads the assets from disk. This is usually done automatically. | +| Search/Filter | Ctrl+F | ⌘+F | Filter the controls that are shown. Case-sensitive. | +| Quit | Ctrl+Q | ⌘+Q | Quit the application. | diff --git a/tests/manual/quickcontrols2/testbench/SettingsDialog.qml b/tests/manual/quickcontrols2/testbench/SettingsDialog.qml new file mode 100644 index 00000000000..d11b5bea3e1 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/SettingsDialog.qml @@ -0,0 +1,447 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import Backend +import "." as Ui + +Ui.Dialog { + id: settingsDialog + title: "Settings" + width: 500 + height: 400 + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + property alias imaginePathTextField: imaginePathTextField + property alias customImagineStyleCheckBox: customImagineStyleCheckBox + property alias autoFixImagineAssetsCheckBox: autoFixImagineAssetsCheckBox + + onAboutToShow: { + styleComboBox.currentIndex = styleComboBox.styleIndex + customImagineStyleCheckBox.checked = settings.useCustomImaginePath + imaginePathTextField.text = settings.imaginePath + autoFixImagineAssetsCheckBox.checked = settings.autoFixImagineAssets + + updatePaletteSettingsControls(paletteSettings) + } + + onAccepted: { + settings.style = styleComboBox.displayText + settings.useCustomImaginePath = customImagineStyleCheckBox.checked + settings.imaginePath = imaginePathTextField.text + settings.autoFixImagineAssets = autoFixImagineAssetsCheckBox.checked + + paletteSettings.useCustomPalette = useCustomPaletteCheckBox.checked + paletteSettings.window = windowColorEditor.color + paletteSettings.windowText = windowTextColorEditor.color + paletteSettings.base = baseColorEditor.color + paletteSettings.text = textColorEditor.color + paletteSettings.button = buttonColorEditor.color + paletteSettings.buttonText = buttonTextColorEditor.color + paletteSettings.brightText = brightTextColorEditor.color + paletteSettings.toolTipBase = toolTipBaseColorEditor.color + paletteSettings.toolTipText = toolTipTextColorEditor.color + paletteSettings.light = lightColorEditor.color + paletteSettings.midlight = midlightColorEditor.color + paletteSettings.dark = darkColorEditor.color + paletteSettings.mid = midColorEditor.color + paletteSettings.shadow = shadowColorEditor.color + paletteSettings.highlight = highlightColorEditor.color + paletteSettings.highlightedText = highlightedTextColorEditor.color + paletteSettings.link = linkColorEditor.color + } + + function updatePaletteSettingsControls(source) { + useCustomPaletteCheckBox.checked = paletteSettings.useCustomPalette + windowColorEditor.color = source.window + windowTextColorEditor.color = source.windowText + baseColorEditor.color = source.base + textColorEditor.color = source.text + buttonColorEditor.color = source.button + buttonTextColorEditor.color = source.buttonText + brightTextColorEditor.color = source.brightText + toolTipBaseColorEditor.color = source.toolTipBase + toolTipTextColorEditor.color = source.toolTipText + lightColorEditor.color = source.light + midlightColorEditor.color = source.midlight + darkColorEditor.color = source.dark + midColorEditor.color = source.mid + shadowColorEditor.color = source.shadow + highlightColorEditor.color = source.highlight + highlightedTextColorEditor.color = source.highlightedText + linkColorEditor.color = source.link + } + + function paletteSettingsMap() { + var map = ({}); + map.window = windowColorEditor.color + map.windowText = windowTextColorEditor.color + map.base = baseColorEditor.color + map.text = textColorEditor.color + map.button = buttonColorEditor.color + map.buttonText = buttonTextColorEditor.color + map.brightText = brightTextColorEditor.color + map.toolTipBase = toolTipBaseColorEditor.color + map.toolTipText = toolTipTextColorEditor.color + map.light = lightColorEditor.color + map.midlight = midlightColorEditor.color + map.dark = darkColorEditor.color + map.mid = midColorEditor.color + map.shadow = shadowColorEditor.color + map.highlight = highlightColorEditor.color + map.highlightedText = highlightedTextColorEditor.color + map.link = linkColorEditor.color + return map; + } + + Clipboard { + id: clipboard + } + + DirectoryValidator { + id: directoryValidator + path: imaginePathTextField.text + } + + contentItem: Flickable { + contentWidth: settingsDialog.availableWidth + contentHeight: contentLayout.implicitHeight + flickableDirection: Qt.Vertical + clip: true + + ColumnLayout { + id: contentLayout + anchors.fill: parent + + GroupBox { + title: qsTr("General") + Layout.fillWidth: true + + GridLayout { + columns: 2 + + Label { + text: "Style:" + } + + ComboBox { + id: styleComboBox + model: availableStyles + + property int styleIndex: -1 + + Component.onCompleted: { + styleIndex = find(settings.style, Qt.MatchFixedString) + if (styleIndex !== -1) + currentIndex = styleIndex + } + + Layout.fillWidth: true + } + + Item { + Layout.fillWidth: true + } + + Label { + text: "Restart required" + color: "#e41e25" + opacity: styleComboBox.currentIndex !== styleComboBox.styleIndex ? 1.0 : 0.0 + Layout.topMargin: 12 + Layout.maximumHeight: styleComboBox.currentIndex !== styleComboBox.styleIndex ? implicitHeight : 0 + } + } + } + + GroupBox { + title: qsTr("Imagine Style") + visible: usingImagineStyle + Layout.fillWidth: true + Layout.columnSpan: 2 + + GridLayout { + columns: 2 + anchors.fill: parent + + CheckBox { + id: customImagineStyleCheckBox + text: qsTr("Use Custom Assets") + enabled: usingImagineStyle + + Layout.columnSpan: 2 + } + + Label { + text: "Asset Path" + enabled: usingImagineStyle && customImagineStyleCheckBox.checked + } + + TextField { + id: imaginePathTextField + text: settings.imaginePath + enabled: usingImagineStyle && customImagineStyleCheckBox.checked + + Layout.preferredWidth: 200 + Layout.fillWidth: true + + ToolTip { + text: "Path to a folder that contains Imagine style image assets" + visible: imaginePathTextField.hovered + delay: 500 + parent: imaginePathTextField + } + } + + Item { + Layout.fillWidth: true + } + + Label { + text: directoryValidator.errorMessage + color: "#e41e25" + opacity: !directoryValidator.valid ? 1.0 : 0.0 + elide: Label.ElideMiddle + Layout.topMargin: !directoryValidator.valid ? 12 : 0 + Layout.maximumHeight: !directoryValidator.valid ? implicitHeight : 0 + + Layout.fillWidth: true + } + + CheckBox { + id: autoFixImagineAssetsCheckBox + text: "Automatically Fix Custom Assets" + enabled: usingImagineStyle && customImagineStyleCheckBox.checked + + Layout.columnSpan: 2 + + ToolTip { + text: "If set, custom Imagine style assets will be modified to be compliant whenever they have changed on disk" + visible: autoFixImagineAssetsCheckBox.hovered + delay: 500 + parent: imaginePathTextField + } + } + } + } + + GroupBox { + title: qsTr("Palette") + Layout.fillWidth: true + + GridLayout { + columns: 2 + anchors.fill: parent + + CheckBox { + id: useCustomPaletteCheckBox + text: qsTr("Use Custom Palette") + } + + ColorEditor { + id: windowColorEditor + labelText: qsTr("Window") + toolTipText: qsTr("A general background color.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: windowTextColorEditor + labelText: qsTr("WindowText") + toolTipText: qsTr("A general foreground color.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: baseColorEditor + labelText: qsTr("Base") + toolTipText: qsTr("Used mostly as the background color for text editor controls and items views. It is usually white or another light color.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: textColorEditor + labelText: qsTr("Text") + toolTipText: qsTr("The foreground color used with Base. This is usually the same as the WindowText, in which case it must provide good contrast with Window and Base.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: buttonColorEditor + labelText: qsTr("Button") + toolTipText: qsTr("The general button background color. This background can be different from Window as some styles require a different background color for buttons.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: buttonTextColorEditor + labelText: qsTr("ButtonText") + toolTipText: qsTr("A foreground color used with the Button color.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: brightTextColorEditor + labelText: qsTr("BrightText") + toolTipText: qsTr("A text color that is very different from WindowText, and contrasts well with e.g. Dark. Typically used for text that needs to be drawn where Text, WindowText or ButtonText would give poor contrast, such as on highlighted buttons.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: toolTipBaseColorEditor + labelText: qsTr("ToolTipBase") + toolTipText: qsTr("Used as the background color for tooltips.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: toolTipTextColorEditor + labelText: qsTr("ToolTipText") + toolTipText: qsTr("Used as the foreground color for tooltips.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: lightColorEditor + labelText: qsTr("Light") + toolTipText: qsTr("Lighter than Button.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: midlightColorEditor + labelText: qsTr("Midlight") + toolTipText: qsTr("Between Button and Light.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: darkColorEditor + labelText: qsTr("Dark") + toolTipText: qsTr("Darker than Button.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: midColorEditor + labelText: qsTr("Mid") + toolTipText: qsTr("Between Button and Dark.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: shadowColorEditor + labelText: qsTr("Shadow") + toolTipText: qsTr("A very dark color.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: highlightColorEditor + labelText: qsTr("Highlight") + toolTipText: qsTr("A color to indicate a selected item or the current item.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: linkColorEditor + labelText: qsTr("Link") + toolTipText: qsTr("A text color used for hyperlinks.") + enabled: useCustomPaletteCheckBox.checked + } + + ColorEditor { + id: highlightedTextColorEditor + labelText: qsTr("HighlightedText") + toolTipText: qsTr("A text color that contrasts with Highlight.") + enabled: useCustomPaletteCheckBox.checked + } + + Button { + text: qsTr("Copy Palette Settings To Clipboard") + enabled: useCustomPaletteCheckBox.checked + onClicked: clipboard.copy(paletteSettingsMap()) + + Layout.columnSpan: 2 + Layout.alignment: Qt.AlignRight + } + + Button { + text: qsTr("Import Palette Settings From Clipboard") + enabled: useCustomPaletteCheckBox.checked + onClicked: updatePaletteSettingsControls(clipboard.paste()) + + Layout.columnSpan: 2 + Layout.alignment: Qt.AlignRight + } + } + } + + Item { + Layout.fillHeight: true + } + } + } + + footer: DialogButtonBox { + Button { + text: qsTr("OK") + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + enabled: !imaginePathTextField.enabled || (imaginePathTextField.enabled && directoryValidator.valid) + } + Button { + text: qsTr("Cancel") + DialogButtonBox.buttonRole: DialogButtonBox.RejectRole + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/ToolBar.qml b/tests/manual/quickcontrols2/testbench/ToolBar.qml new file mode 100644 index 00000000000..90cbc1951fa --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/ToolBar.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls + +ToolBar {} diff --git a/tests/manual/quickcontrols2/testbench/assetfixer.cpp b/tests/manual/quickcontrols2/testbench/assetfixer.cpp new file mode 100644 index 00000000000..4813dac50d4 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/assetfixer.cpp @@ -0,0 +1,564 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "assetfixer.h" + +#include <QDebug> +#include <QDir> +#include <QDirIterator> +#include <QImage> +#include <QLoggingCategory> +#include <QQmlApplicationEngine> +#include <QQuickWindow> +#include <QtMath> + +#include "directoryvalidator.h" + +Q_LOGGING_CATEGORY(lcAssetFixer, "qt.quick.controls.tools.testbench.assetfixer.brief") +Q_LOGGING_CATEGORY(lcAssetFixerVerbose, "qt.quick.controls.tools.testbench.assetfixer.verbose") + +static const QColor black = Qt::black; +static const QColor red = Qt::red; + +/* + This class: + + - Watches a given asset directory for changes. When it notices a change in the directory's + "last modification" time, it suggests that client code call fixAssets(). It suggests + rather than just doing it itself because the client code (QML) may want to wait a second + or two to see if more changes are coming before doing an expensive fixup, as exporting + a bunch of files into a directory will cause several directoryChanged() emissions from + QFileSystemWatcher. + - Fixes 9-patch image assets via the function below. +*/ + +/* + This function: + + - Crops the image to the area within the 9-patch lines if necessary. + This can happen if e.g. a shadow is applied to an asset in Illustrator + and it causes the image to be larger than necessary. + - Reduces the thickness of the 9-patch lines. This is necessary to enable + designers not to have to worry about creating one pixel-thick lines for + each DPI variant of an asset; they can simply export the asset at each + DPI variant as usual and this program will fix it for them. + + See README.md for more information. +*/ +bool cropImageToLines(QImage *image) +{ + QRect cropArea; + /* + We need to keep track of this because of the following case: + + ______________________ + ______________________ + || + oooooooooooooooooooooooo + || + + If we didn't keep track of thickness, the top edge's lines would be found fine, + but then we'd look at the bottom edge and we'd accidentally pick up the left edge's lines. + Keeping track of thickness ensures that we have some way of knowing if we're far enough + in for the line to belong to a certain edge. + + Note that this approach is still limited, as it doesn't account for the top edge, + but we have to start somewhere in order to find the thickness. + */ + int thickness = 0; + + bool cropTop = false; + bool foundOnePixelThick9PatchLine = false; + // We have to go row by row because otherwise we might find a pixel that + // belongs to e.g. the left edge. + for (int y = 0; y < qFloor(image->height() / 2.0) && !cropTop && !foundOnePixelThick9PatchLine; ++y) { + for (int x = 1; x < image->width() - 2 && !cropTop && !foundOnePixelThick9PatchLine; ++x) { + const QColor pixelColor = image->pixelColor(x, y); + if (pixelColor == black || pixelColor == red) { + if (y == 0) { + const QColor pixelColorBelow = image->pixelColor(x, y + 1); + if (pixelColorBelow != black && pixelColorBelow != red) { + // We've already found the top of the 9-patch line, and the row below it + // is a different color, so we know that it's one pixel thick, and that we're done. + // Note that we can't just assume all of the other edges are the same and return here, + // as we also need to account for e.g. shadows. + qCDebug(lcAssetFixerVerbose) << "found one-pixel-thick nine patch line on top edge at x" << x; + foundOnePixelThick9PatchLine = true; + thickness = 1; + } + } else { + // It's not already at the top edge, so crop the top edge. + cropTop = true; + + // Now that we've found the line, find out how thick it is. + for (int yy = y; yy < qFloor(image->height() / 2.0); ++yy) { + const QColor pixelColor = image->pixelColor(x, yy); + if (pixelColor == black || pixelColor == red) { + cropArea.setTop(yy); + } else { + break; + } + } + + // + 1 for the pixel that we leave in when cropping, + // another +1 for the fact that this else statement is only entered when y > 0 + if (thickness == 0) { + thickness = cropArea.top() - y + 2; + qCDebug(lcAssetFixerVerbose) << "found first croppable nine patch line on top edge at x" << x << "y" << y + << "with thickness" << thickness; + } else { + qCDebug(lcAssetFixerVerbose) << "found first croppable nine patch line on top edge at x" << x << "y" << y + << "using existing thickness of" << thickness; + } + } + } + } + } + + bool cropBottom = false; + foundOnePixelThick9PatchLine = false; + for (int y = image->height() - 1; y >= qCeil(image->height() / 2.0) && !cropBottom && !foundOnePixelThick9PatchLine; --y) { + for (int x = qMax(1, thickness); x < image->width() - 2 && !cropBottom && !foundOnePixelThick9PatchLine; ++x) { + const QColor pixelColor = image->pixelColor(x, y); + if (pixelColor == black || pixelColor == red) { + if (y == image->height() - 1) { + const QColor pixelColorAbove = image->pixelColor(x, y - 1); + if (pixelColorAbove != black && pixelColorAbove != red) { + // We've already found the bottom of the 9-patch line, and the row above it + // is a different color, so we know that it's one pixel thick, and that we're done. + qCDebug(lcAssetFixerVerbose) << "found one-pixel-thick nine patch line on bottom edge at x" << x; + foundOnePixelThick9PatchLine = true; + if (thickness == 0) + thickness = 1; + } + } else { + // It's not already at the bottom edge, so crop the bottom edge. + cropBottom = true; + + // Now that we've found the line, find out how thick it is. + for (int yy = y; yy >= qCeil(image->height() / 2.0); --yy) { + const QColor pixelColor = image->pixelColor(x, yy); + if (pixelColor == black || pixelColor == red) { + cropArea.setBottom(yy); + } else { + break; + } + } + + // + 1 for the pixel that we leave in when cropping, + // another +1 for the fact that this else statement is only entered when y < image->height() - 1 + if (thickness == 0) { + thickness = y - cropArea.bottom() + 2; + qCDebug(lcAssetFixerVerbose) << "found first croppable nine patch line on bottom edge at x" << x << "y" << y + << "with thickness" << thickness; + } else { + qCDebug(lcAssetFixerVerbose) << "found first croppable nine patch line on bottom edge at x" << x << "y" << y + << "using existing thickness of" << thickness; + } + } + break; + } + } + } + + bool cropLeft = false; + foundOnePixelThick9PatchLine = false; + for (int x = 0; x < qFloor(image->width() / 2.0) && !cropLeft && !foundOnePixelThick9PatchLine; ++x) { + for (int y = qMax(1, thickness); y < image->height() - 2 && !cropLeft && !foundOnePixelThick9PatchLine; ++y) { + const QColor pixelColor = image->pixelColor(x, y); + if (pixelColor == black || pixelColor == red) { + if (x == 0) { + const QColor pixelColorToTheRight = image->pixelColor(x + 1, y); + if (pixelColorToTheRight != black && pixelColorToTheRight != red) { + // We've already found the beginning of the 9-patch line, and the column after it + // is a different color, so we know that it's one pixel thick, and that we're done. + qCDebug(lcAssetFixerVerbose) << "found one-pixel-thick nine patch line on left edge at y" << y; + foundOnePixelThick9PatchLine = true; + } + } else { + // It's not already at the left edge, so crop the left edge. + cropLeft = true; + + // Now that we've found the line, find out how thick it is. + for (int xx = x; xx < qFloor(image->width() / 2.0); ++xx) { + const QColor pixelColor = image->pixelColor(xx, y); + if (pixelColor == black || pixelColor == red) { + cropArea.setLeft(xx); + } else { + break; + } + } + + // + 1 for the pixel that we leave in when cropping, + // another +1 for the fact that this else statement is only entered when x > 0 + if (thickness == 0) { + thickness = cropArea.left() - x + 2; + qCDebug(lcAssetFixerVerbose) << "found first croppable nine patch line on left edge at x" << x << "y" << y + << "with thickness" << thickness; + } else { + qCDebug(lcAssetFixerVerbose) << "found first croppable nine patch line on left edge at x" << x << "y" << y + << "using existing thickness of" << thickness; + } + } + } + } + } + + bool cropRight = false; + foundOnePixelThick9PatchLine = false; + for (int x = image->width() - 1; x >= qCeil(image->width() / 2.0) && !cropRight && !foundOnePixelThick9PatchLine; --x) { + for (int y = qMax(1, thickness); y < image->height() - 2 && !cropRight && !foundOnePixelThick9PatchLine; ++y) { + const QColor pixelColor = image->pixelColor(x, y); + if (pixelColor == black || pixelColor == red) { + if (x == image->width() - 1) { + const QColor pixelColorToTheLeft = image->pixelColor(x - 1, y); + if (pixelColorToTheLeft != black && pixelColorToTheLeft != red) { + // We've already found the end of the 9-patch line, and the column before it + // is a different color, so we know that it's one pixel thick, and that we're done. + qCDebug(lcAssetFixerVerbose) << "found one-pixel-thick nine patch line on right edge at y" << y; + foundOnePixelThick9PatchLine = true; + } + } else { + // It's not already at the right edge, so crop the right edge. + cropRight = true; + + // Now that we've found the line, find out how thick it is. + for (int xx = x; xx >= qCeil(image->width() / 2.0); --xx) { + const QColor pixelColor = image->pixelColor(xx, y); + if (pixelColor == black || pixelColor == red) { + cropArea.setRight(xx); + } else { + break; + } + } + + // + 1 for the pixel that we leave in when cropping, + // another +1 for the fact that this else statement is only entered when x < image->width() - 1 + if (thickness == 0) { + thickness = x - cropArea.right() + 2; + qCDebug(lcAssetFixerVerbose) << "found first croppable nine patch line on right edge at x" << x << "y" << y + << "with thickness" << thickness; + } else { + qCDebug(lcAssetFixerVerbose) << "found first croppable nine patch line on right edge at x" << x << "y" << y + << "using existing thickness of" << thickness; + } + } + break; + } + } + } + + const QRect copyArea(cropLeft ? cropArea.x() : (thickness ? thickness - 1 : 0), + cropTop ? cropArea.y() : (thickness ? thickness - 1 : 0), + cropRight ? cropArea.width() : image->width() - (thickness ? (thickness - 1) * 2 : 0), + cropBottom ? cropArea.height() : image->height() - (thickness ? (thickness - 1) * 2 : 0)); + + if (cropLeft | cropRight | cropTop | cropBottom) { + qCDebug(lcAssetFixerVerbose) << "cropping area" << copyArea; + *image = image->copy(copyArea); + return true; + } + + return false; +} + +AssetFixer::AssetFixer(QObject *parent) : + QObject(parent), + mComponentComplete(false), + mFirstWatch(true), + mShouldWatch(false), + mShouldFix(false), + mLastModified(QDateTime::fromSecsSinceEpoch(0)) +{ +} + +bool AssetFixer::shouldWatch() const +{ + return mShouldWatch; +} + +void AssetFixer::setShouldWatch(bool watch) +{ + if (watch == mShouldWatch) + return; + + stopWatching(); + + mShouldWatch = watch; + + startWatching(); + + emit shouldWatchChanged(); +} + +bool AssetFixer::shouldFix() const +{ + return mShouldFix; +} + +void AssetFixer::setShouldFix(bool fix) +{ + if (fix == mShouldFix) + return; + + mShouldFix = fix; + emit shouldFixChanged(); +} + +QString AssetFixer::assetDirectory() const +{ + return mAssetDirectory; +} + +void AssetFixer::setAssetDirectory(const QString &assetDirectory) +{ + if (assetDirectory == mAssetDirectory) + return; + + stopWatching(); + + const QString oldAssetDirectory = assetDirectory; + mAssetDirectory.clear(); + + if (isAssetDirectoryValid(assetDirectory)) { + mAssetDirectory = assetDirectory; + startWatching(); + } + + if (mAssetDirectory != oldAssetDirectory) + emit assetDirectoryChanged(); +} + +QUrl AssetFixer::assetDirectoryUrl() const +{ + return QUrl::fromLocalFile(mAssetDirectory); +} + +QDateTime AssetFixer::assetDirectoryLastModified() const +{ + return mLastModified; +} + +void AssetFixer::setAssetDirectoryLastModified(const QDateTime &assetDirectoryLastModified) +{ + if (assetDirectoryLastModified == mLastModified) + return; + + mLastModified = assetDirectoryLastModified; + emit assetDirectoryLastModifiedChanged(); +} + +void AssetFixer::componentComplete() +{ + mComponentComplete = true; +} + +void AssetFixer::classBegin() +{ +} + +void AssetFixer::onAssetsChanged() +{ + const QFileInfo fileInfo(mAssetDirectory); + const QDateTime lastModified = fileInfo.lastModified(); + + qCDebug(lcAssetFixer) << "Change in asset directory" << mAssetDirectory << "detected" + << "lastModified:" << lastModified; + const qint64 secsSinceLastModification = mLastModified.secsTo(lastModified); + if (secsSinceLastModification == 0) { + qCDebug(lcAssetFixer) << "Change in asset directory" << mAssetDirectory << "detected, " + << "but QFileInfo says the directory hasn't been modified; ignoring"; + } else { + setAssetDirectoryLastModified(lastModified); + + QString message; + if (lcAssetFixer().isDebugEnabled()) { + message = QString::fromLatin1("Change in asset directory %1 detected, and QFileInfo says that there have been " \ + "%2 seconds since it was previously last modified); %3").arg(mAssetDirectory).arg(secsSinceLastModification); + } + + if (shouldFix()) { + qCDebug(lcAssetFixer) << message.arg(QLatin1String("suggesting delayed fix")); + emit delayedFixSuggested(); + } else { + qCDebug(lcAssetFixer) << message.arg(QLatin1String("suggesting reload")); + emit reloadSuggested(); + } + } +} + +void AssetFixer::stopWatching() +{ + if (!mShouldWatch || mAssetDirectory.isEmpty() || !mComponentComplete) + return; + + disconnect(&mFileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, &AssetFixer::onAssetsChanged); + mFileSystemWatcher.removePath(mAssetDirectory); +} + +void AssetFixer::startWatching() +{ + if (!mShouldWatch || mAssetDirectory.isEmpty() || !mComponentComplete || !isAssetDirectoryValid(mAssetDirectory)) + return; + + if (mFileSystemWatcher.addPath(mAssetDirectory)) { + // TODO: for some reason this is not called when an image is edited, but is when the same image is "touch"ed. + // We could add watchers for each file, but then the application might have to be limited to displaying + // the elements for one control at a time so that we don't breach the 256 file descriptor limit on some platforms: + // http://doc.qt.io/qt-5/qfilesystemwatcher.html#details + + // We only emit a signal here rather than automatically responding to it ourselves, + // because we want to give the UI time to start animations. + connect(&mFileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, &AssetFixer::onAssetsChanged); + + const QFileInfo fileInfo(mAssetDirectory); + bool suggestFix = false; + if (mFirstWatch) { + mFirstWatch = false; + + // Here we check if the assets have been modified since the last time the application closed. + // Checking this avoids a slow startup (due to fixing up assets). + if (fileInfo.lastModified() > mLastModified) { + qCDebug(lcAssetFixer) << "asset directory" << mAssetDirectory << "was modified at" + << fileInfo.lastModified() << ", which is later than our last stored modification time of" + << mLastModified << "; suggesting fix"; + suggestFix = true; + } else { + qCDebug(lcAssetFixer) << "asset directory" << mAssetDirectory << "has not been modified since" + << "the application was last closed; a fix is not necessary"; + + // For some reason not all assets are updated if we don't do this. + emit reloadSuggested(); + } + + // Don't need to call setAssetDirectoryLastModified() here, as we should have gotten it from settings. + } else { + suggestFix = true; + } + + if (suggestFix) { + setAssetDirectoryLastModified(fileInfo.lastModified()); + emit fixSuggested(); + } + } else { + qWarning() << "Could not watch asset directory" << mAssetDirectory; + } +} + +bool AssetFixer::isAssetDirectoryValid(const QString &assetDirectory) +{ + DirectoryValidator validator; + validator.setPath(assetDirectory); + return validator.isValid(); +} + +void AssetFixer::clearImageCache() +{ + QQmlApplicationEngine *engine = qobject_cast<QQmlApplicationEngine*>(qmlEngine(this)); + if (!engine) { + qWarning() << "No QQmlApplicationEngine for AssetFixer - assets may not reload properly"; + return; + } + + QQuickWindow *window = qobject_cast<QQuickWindow*>(engine->rootObjects().first()); + if (!window) { + qWarning() << "No QQuickWindow - assets may not reload properly"; + return; + } + + // We can't seem to disable image caching on a per-Image basis (by the time the QQuickImages + // are available, the cache has already been filled), so we call this instead. + qCDebug(lcAssetFixer) << "Calling QQuickWindow::releaseResources() to clear pixmap cache"; + window->releaseResources(); +} + +void AssetFixer::fixAssets() +{ + if (!mShouldFix || !mComponentComplete || mAssetDirectory.isEmpty() || !isAssetDirectoryValid(mAssetDirectory)) + return; + + QDir assetDir(mAssetDirectory); + qCDebug(lcAssetFixer) << "Fixing up assets in" << assetDir.absolutePath() << "..."; + int filesChanged = 0; + + QStringList nameFilters; + nameFilters << QLatin1String("*.9.png"); + QDirIterator dirIt(assetDir.absolutePath(), nameFilters, QDir::Files | QDir::Readable | QDir::NoSymLinks); + while (dirIt.hasNext()) { + const QString imagePath = dirIt.next(); + + QImage image(imagePath); + if (image.isNull()) { + qWarning() << "Couldn't open image at" << imagePath; + return; + } + + qCDebug(lcAssetFixerVerbose).nospace() << "found " << imagePath << " (" << image.width() << "x" << image.height() << ") - " + << "checking if we need to crop 9-patch lines"; + + if (cropImageToLines(&image)) { + if (!image.save(imagePath)) { + qWarning() << "Couldn't save" << imagePath; + return; + } + + ++filesChanged; + } + } + + qCDebug(lcAssetFixer) << "Fixed" << filesChanged << "assets"; + + // Let the application know that it should reload the Imagine style's assets. + // Currently we always suggest a reload after fixing files, even if no files were fixed. + // This is because the default Imagine style assets are automatically loaded at first, and then we + // set a custom path shortly after, so we must ensure that the Imagine style is using the correct assets. + // Reloads are just a matter of changing Imagine.path, which is very fast. + emit reloadSuggested(); +} diff --git a/tests/manual/quickcontrols2/testbench/assetfixer.h b/tests/manual/quickcontrols2/testbench/assetfixer.h new file mode 100644 index 00000000000..4af9ccf4af6 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/assetfixer.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ASSETFIXER_H +#define ASSETFIXER_H + +#include <QObject> +#include <QDateTime> +#include <QFileSystemWatcher> +#include <QQmlParserStatus> +#include <QUrl> + +class AssetFixer : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_PROPERTY(bool shouldWatch READ shouldWatch WRITE setShouldWatch NOTIFY shouldWatchChanged FINAL) + Q_PROPERTY(bool shouldFix READ shouldFix WRITE setShouldFix NOTIFY shouldFixChanged FINAL) + Q_PROPERTY(QString assetDirectory READ assetDirectory WRITE setAssetDirectory NOTIFY assetDirectoryChanged FINAL) + Q_PROPERTY(QUrl assetDirectoryUrl READ assetDirectoryUrl NOTIFY assetDirectoryChanged FINAL) + Q_PROPERTY(QDateTime assetDirectoryLastModified READ assetDirectoryLastModified WRITE setAssetDirectoryLastModified + NOTIFY assetDirectoryLastModifiedChanged FINAL) + Q_INTERFACES(QQmlParserStatus) + +public: + explicit AssetFixer(QObject *parent = nullptr); + + bool shouldWatch() const; + void setShouldWatch(bool shouldWatch); + + bool shouldFix() const; + void setShouldFix(bool shouldFix); + + QString assetDirectory() const; + void setAssetDirectory(const QString &assetDirectory); + + QUrl assetDirectoryUrl() const; + + QDateTime assetDirectoryLastModified() const; + void setAssetDirectoryLastModified(const QDateTime &assetDirectoryLastModified); + +signals: + void shouldWatchChanged(); + void shouldFixChanged(); + void assetDirectoryChanged(); + void assetDirectoryLastModifiedChanged(); + + void fixSuggested(); + void delayedFixSuggested(); + void reloadSuggested(); + + void error(const QString &errorMessage); + +public slots: + void clearImageCache(); + void fixAssets(); + +protected: + void componentComplete() override; + void classBegin() override; + +private slots: + void onAssetsChanged(); + +private: + void stopWatching(); + void startWatching(); + + bool isAssetDirectoryValid(const QString &assetDirectory); + + bool mComponentComplete; + bool mFirstWatch; + bool mShouldWatch; + bool mShouldFix; + QString mAssetDirectory; + QFileSystemWatcher mFileSystemWatcher; + QDateTime mLastModified; +}; + +#endif // ASSETFIXER_H diff --git a/tests/manual/quickcontrols2/testbench/clipboard.cpp b/tests/manual/quickcontrols2/testbench/clipboard.cpp new file mode 100644 index 00000000000..1daebfc92fa --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/clipboard.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "clipboard.h" + +#include <QClipboard> +#include <QGuiApplication> +#include <QSettings> + +const QStringList keys = { + "Palette/window", + "Palette/windowText", + "Palette/base", + "Palette/text", + "Palette/button", + "Palette/buttonText", + "Palette/brightText", + "Palette/toolTipBase", + "Palette/toolTipText", + "Palette/light", + "Palette/midlight", + "Palette/dark", + "Palette/mid", + "Palette/shadow", + "Palette/highlight", + "Palette/highlightedText", + "Palette/link" +}; + +Clipboard::Clipboard(QObject *parent) : + QObject(parent) +{ +} + +// Converts the JS map into a big string and copies it to the clipboard. +void Clipboard::copy(const QJSValue &keyValueMap) +{ + QString paletteSettingsString; + QVariantMap map = keyValueMap.toVariant().value<QVariantMap>(); + const QList<QString> mapKeys = map.keys(); + for (const QString &key : mapKeys) { + paletteSettingsString += "Palette/" + key + "=" + map.value(key).toString() + ","; + } + + // Remove the trailing comma. + if (!paletteSettingsString.isEmpty()) + paletteSettingsString.chop(1); + + QGuiApplication::clipboard()->setText(paletteSettingsString); +} + +// Converts the big string into a JS map and returns it. +QVariant Clipboard::paste() const +{ + QClipboard *clipboard = QGuiApplication::clipboard(); + if (clipboard->text().isEmpty()) + return QVariant(); + + QVariantMap keyValueMap; + + const QStringList settingsList = clipboard->text().split(QLatin1Char(',')); + for (const QString &setting : settingsList) { + const QStringList keyValuePair = setting.split(QLatin1Char('=')); + if (keyValuePair.size() < 2) + continue; + + QString key = keyValuePair.first(); + if (keys.contains(key)) { + key.remove(QLatin1String("Palette/")); + const QString value = keyValuePair.last(); + + keyValueMap.insert(key, value); + } + } + + return QVariant(keyValueMap); +} diff --git a/tests/manual/quickcontrols2/testbench/clipboard.h b/tests/manual/quickcontrols2/testbench/clipboard.h new file mode 100644 index 00000000000..a21dd9c619b --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/clipboard.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CLIPBOARD_H +#define CLIPBOARD_H + +#include <QObject> +#include <QJSValue> +#include <QVariant> + +class Clipboard : public QObject +{ + Q_OBJECT +public: + explicit Clipboard(QObject *parent = nullptr); + +public slots: + void copy(const QJSValue &keyValueMap); + QVariant paste() const; + +// void copyPaletteSettingsToClipboard(); +// void importPaletteSettingsFromClipboard(); +}; + +#endif // CLIPBOARD_H diff --git a/tests/manual/quickcontrols2/testbench/controls/BusyIndicator.qml b/tests/manual/quickcontrols2/testbench/controls/BusyIndicator.qml new file mode 100644 index 00000000000..cc0f4518a49 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/BusyIndicator.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["mirrored"] + ] + + property Component component: BusyIndicator { + enabled: !is("disabled") + LayoutMirroring.enabled: is("mirrored") + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/Button.qml b/tests/manual/quickcontrols2/testbench/controls/Button.qml new file mode 100644 index 00000000000..43389520fb8 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/Button.qml @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["pressed"], + ["checkable", "checked"], + ["checkable", "checked", "disabled"], + ["checkable", "checked"], + ["highlighted"], + ["highlighted", "disabled"], + ["highlighted", "pressed"], + ["highlighted", "checkable"], + ["highlighted", "checkable", "pressed"], + ["highlighted", "checkable", "checked"], + ["icon"], + ["icon", "disabled"], + ["icon", "pressed"], + ["icon", "checkable", "checked"], + ["icon", "checkable", "checked", "disabled"], + ["icon", "checkable", "checked"], + ["icon", "highlighted"], + ["icon", "highlighted", "disabled"], + ["icon", "highlighted", "pressed"], + ["icon", "highlighted", "checkable"], + ["icon", "highlighted", "checkable", "pressed"], + ["icon", "highlighted", "checkable", "checked"], + ["flat"], + ["flat", "disabled"], + ["flat", "pressed"], + ["flat", "checkable"], + ["flat", "checkable", "checked"], + ["flat", "checkable", "pressed"], + ["flat", "checkable", "checked", "pressed"], + ["flat", "checkable", "highlighted"], + ["flat", "checkable", "highlighted", "pressed"], + ["flat", "checkable", "highlighted", "checked"], + ["icon", "flat"], + ["icon", "flat", "disabled"], + ["icon", "flat", "pressed"], + ["icon", "flat", "checkable"], + ["icon", "flat", "checkable", "checked"], + ["icon", "flat", "checkable", "pressed"], + ["icon", "flat", "checkable", "checked", "pressed"], + ["icon", "flat", "checkable", "highlighted"], + ["icon", "flat", "checkable", "highlighted", "pressed"], + ["icon", "flat", "checkable", "highlighted", "checked"] + ] + + property Component component: Button { + text: "Button" + enabled: !is("disabled") + flat: is("flat") + checkable: is("checkable") + checked: is("checked") + // Only set it if it's pressed, or the non-pressed examples will have no press effects + down: is("pressed") ? true : undefined + highlighted: is("highlighted") + icon.source: is("icon") ? "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png" : "" + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/CheckBox.qml b/tests/manual/quickcontrols2/testbench/controls/CheckBox.qml new file mode 100644 index 00000000000..0598dae8338 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/CheckBox.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["pressed"], + ["checked"], + ["checked", "disabled"], + ["checked", "pressed"], + ["partially-checked"], + ["partially-checked", "disabled"], + ["partially-checked", "pressed"], + ] + + property Component component: CheckBox { + text: "CheckBox" + enabled: !is("disabled") + checkState: is("checked") ? Qt.Checked : is("partially-checked") ? Qt.PartiallyChecked : Qt.Unchecked + // Only set it if it's pressed, or the non-pressed examples will have no press effects + down: is("pressed") ? true : undefined + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/CheckDelegate.qml b/tests/manual/quickcontrols2/testbench/controls/CheckDelegate.qml new file mode 100644 index 00000000000..8f546384ff1 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/CheckDelegate.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["pressed"], + ["checked"], + ["checked", "disabled"], + ["checked", "pressed"], + ["partially-checked"], + ["partially-checked", "disabled"], + ["partially-checked", "pressed"], + ] + + property Component component: CheckDelegate { + text: "CheckDelegate" + enabled: !is("disabled") + checkState: is("checked") ? Qt.Checked : is("partially-checked") ? Qt.PartiallyChecked : Qt.Unchecked + // Only set it if it's pressed, or the non-pressed examples will have no press effects + down: is("pressed") ? true : undefined + focusPolicy: Qt.StrongFocus + } + + property Component exampleComponent: ListView { + implicitWidth: 200 + implicitHeight: 200 + clip: true + model: 20 + delegate: CheckDelegate { + width: parent.width + text: "CheckDelegate" + focusPolicy: Qt.StrongFocus + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/ComboBox.qml b/tests/manual/quickcontrols2/testbench/controls/ComboBox.qml new file mode 100644 index 00000000000..75fb7701b23 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/ComboBox.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["pressed"], + ["open"], + ["editable"], + ["editable", "disabled"] + ] + + property Component component: ComboBox { + enabled: !is("disabled") + // Only set it if it's pressed, or the non-pressed examples will have no press effects + down: is("pressed") ? true : undefined + editable: is("editable") + model: ["ComboBox", "Apple", "Bird", "Cat", "Dog", "Elephant"] + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/DelayButton.qml b/tests/manual/quickcontrols2/testbench/controls/DelayButton.qml new file mode 100644 index 00000000000..914c1c5632e --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/DelayButton.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["disabled", "checked"], + ["pressed"], + ["checked"], + ] + + property Component component: Component { + DelayButton { + text: "DelayButton" + enabled: !is("disabled") + // Only set it if it's pressed, or the non-pressed examples will have no press effects + down: is("pressed") ? true : undefined + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/Dial.qml b/tests/manual/quickcontrols2/testbench/controls/Dial.qml new file mode 100644 index 00000000000..16c99ec8333 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/Dial.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + // TODO: no down property to test this with +// ["pressed"] + ] + + property Component component: Dial { + enabled: !is("disabled") + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/Dialog.qml b/tests/manual/quickcontrols2/testbench/controls/Dialog.qml new file mode 100644 index 00000000000..0ea9d3be79e --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/Dialog.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +// TODO +QtObject { + property string customControlName: qsTr("Dialog") + + property var supportedStates: [ + [], + ["modal"], + ["dim"] + ] + + property Component component: Button { + id: dialogButton + text: qsTr("Dialog") + hoverEnabled: true + + onClicked: dialog.open() + + Dialog { + id: dialog + x: (window.width - width) / 2 + y: (window.height - height) / 2 + standardButtons: Dialog.Ok | Dialog.Cancel + parent: window.contentItem + modal: is("modal") + dim: is("dim") || is("modal") + + Label { + text: "Lorem ipsum dolor sit amet, \nconsectetuer adipiscing elit, \n" + + "sed diam nonummy nibh euismod tincidunt ut \nlaoreet dolore magna aliquam erat volutpat." + } + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/Frame.qml b/tests/manual/quickcontrols2/testbench/controls/Frame.qml new file mode 100644 index 00000000000..dd88c3b8f33 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/Frame.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ] + + property Component component: Frame { + Label { + text: "Frame" + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/GroupBox.qml b/tests/manual/quickcontrols2/testbench/controls/GroupBox.qml new file mode 100644 index 00000000000..80ced76926a --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/GroupBox.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ] + + property Component component: GroupBox { + title: qsTr("Title") + + Label { + text: qsTr("GroupBox") + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/ItemDelegate.qml b/tests/manual/quickcontrols2/testbench/controls/ItemDelegate.qml new file mode 100644 index 00000000000..0b887e2f965 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/ItemDelegate.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["pressed"], + ["highlighted"], + ["highlighted", "pressed"] + ] + + property Component component: ItemDelegate { + text: "ItemDelegate" + enabled: !is("disabled") + checkable: is("checkable") + // Only set it if it's pressed, or the non-pressed examples will have no press effects + down: is("pressed") ? true : undefined + highlighted: is("highlighted") + focusPolicy: Qt.StrongFocus + } + + property Component exampleComponent: ListView { + implicitWidth: 200 + implicitHeight: 200 + clip: true + model: 20 + delegate: ItemDelegate { + width: parent.width + text: "ItemDelegate" + focusPolicy: Qt.StrongFocus + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/Label.qml b/tests/manual/quickcontrols2/testbench/controls/Label.qml new file mode 100644 index 00000000000..d8155a2016e --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/Label.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"] + ] + + property Component component: Label { + text: "Label with a <a href=\"http://doc.qt.io\">link</a>" + onTextChanged: print(text) + enabled: !is("disabled") + textFormat: Label.StyledText + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/Menu.qml b/tests/manual/quickcontrols2/testbench/controls/Menu.qml new file mode 100644 index 00000000000..ba15c052d30 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/Menu.qml @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +// TODO +QtObject { + property string customControlName: qsTr("Menu, MenuItem & MenuSeparator") + + property var supportedStates: [ + [] + ] + + property Component component: Button { + id: menuButton + text: qsTr("Menu") + checked: menu.visible + checkable: true + + Menu { + id: menu + x: 1 + y: 1 + parent.height + visible: menuButton.checked + closePolicy: Popup.CloseOnPressOutsideParent + + MenuItem { + text: "Normal" + } + MenuItem { + text: "Pressed" + down: true + } + MenuItem { + text: "Disabled" + enabled: false + } + + MenuSeparator {} + + MenuItem { + text: "Checked" + checked: true + } + MenuItem { + text: "Checked + Pressed" + checked: true + down: true + } + MenuItem { + text: "Checked + Disabled" + checked: true + enabled: false + } + + MenuSeparator {} + + Menu { + title: "Submenu" + + MenuItem { + text: "Submenu item" + } + } + + Menu { + title: "Disabled Submenu" + enabled: false + } + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/MenuBar.qml b/tests/manual/quickcontrols2/testbench/controls/MenuBar.qml new file mode 100644 index 00000000000..f435c9a5ae1 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/MenuBar.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +// TODO +QtObject { + property string customControlName: qsTr("MenuBar & MenuBarItem") + + property var supportedStates: [ + [] + ] + + property Component component: MenuBar { + MenuBarItem { + text: qsTr("Normal") + } + MenuBarItem { + text: qsTr("Pressed") + down: true + } + MenuBarItem { + text: qsTr("Highlighted") + highlighted: true + } + MenuBarItem { + text: qsTr("Disabled") + enabled: false + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/Page.qml b/tests/manual/quickcontrols2/testbench/controls/Page.qml new file mode 100644 index 00000000000..3d310676c32 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/Page.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ] + + property Component component: Page { + width: 100 + height: 100 + + Label { + text: "Page" + anchors.centerIn: parent + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/PageIndicator.qml b/tests/manual/quickcontrols2/testbench/controls/PageIndicator.qml new file mode 100644 index 00000000000..5de29ef10b5 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/PageIndicator.qml @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + // TODO: no down property to test this with +// ["pressed"] + ] + + property Component component: PageIndicator { + enabled: !is("disabled") + count: 5 + } + + property Component exampleComponent: ColumnLayout { + implicitWidth: 200 + implicitHeight: 200 + + // TODO: why doesn't this fill the ColumnLayout? :/ + StackLayout { + id: swipeView + currentIndex: pageIndicator.currentIndex + + Label { + text: qsTr("Page 1") + horizontalAlignment: Label.AlignHCenter + } + + Label { + text: qsTr("Page 2") + horizontalAlignment: Label.AlignHCenter + } + + Label { + text: qsTr("Page 3") + horizontalAlignment: Label.AlignHCenter + } + + Label { + text: qsTr("Page 4") + horizontalAlignment: Label.AlignHCenter + } + + Label { + text: qsTr("Page 5") + horizontalAlignment: Label.AlignHCenter + } + } + + PageIndicator { + id: pageIndicator + currentIndex: swipeView.currentIndex + count: swipeView.count + interactive: true + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/Pane.qml b/tests/manual/quickcontrols2/testbench/controls/Pane.qml new file mode 100644 index 00000000000..b5329b71dae --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/Pane.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ] + + property Component component: Pane { + width: 100 + height: 100 + + Label { + text: "Pane" + anchors.centerIn: parent + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/ProgressBar.qml b/tests/manual/quickcontrols2/testbench/controls/ProgressBar.qml new file mode 100644 index 00000000000..bc2d9045895 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/ProgressBar.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["indeterminate"] + ] + + property Component component: ProgressBar { + enabled: !is("disabled") + indeterminate: is("indeterminate") + value: 0.25 + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/RadioButton.qml b/tests/manual/quickcontrols2/testbench/controls/RadioButton.qml new file mode 100644 index 00000000000..7ca9bd0a8ba --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/RadioButton.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["pressed"], + ["checked"], + ["checked", "disabled"], + ["checked", "pressed"], + ] + + property Component component: Component { + RadioButton { + text: "RadioButton" + enabled: !is("disabled") + checked: is("checked") + // Only set it if it's pressed, or the non-pressed examples will have no press effects + down: is("pressed") ? true : undefined + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/RadioDelegate.qml b/tests/manual/quickcontrols2/testbench/controls/RadioDelegate.qml new file mode 100644 index 00000000000..ddafd14c695 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/RadioDelegate.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["pressed"], + ["checked"], + ["checked", "disabled"], + ["checked", "pressed"] + ] + + property Component component: Component { + RadioDelegate { + text: "RadioDelegate" + enabled: !is("disabled") + checked: is("checked") + // Only set it if it's pressed, or the non-pressed examples will have no press effects + down: is("pressed") ? true : undefined + focusPolicy: Qt.StrongFocus + } + } + + property Component exampleComponent: ListView { + implicitWidth: 200 + implicitHeight: 200 + clip: true + model: 20 + delegate: RadioDelegate { + width: parent.width + text: "RadioDelegate" + focusPolicy: Qt.StrongFocus + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/RangeSlider.qml b/tests/manual/quickcontrols2/testbench/controls/RangeSlider.qml new file mode 100644 index 00000000000..71208fb8222 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/RangeSlider.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + ["vertical"], + ["vertical", "disabled"], + ["vertical", "pressed"], + ["horizontal"], + ["horizontal", "disabled"], + ["horizontal", "pressed"] + ] + + property Component component: RangeSlider { + enabled: !is("disabled") + orientation: is("horizontal") ? Qt.Horizontal : Qt.Vertical + second.value: 0.5 + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/RoundButton.qml b/tests/manual/quickcontrols2/testbench/controls/RoundButton.qml new file mode 100644 index 00000000000..fb2d1d4396c --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/RoundButton.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["pressed"], + ["checked"], + ["checked", "disabled"], + ["highlighted"], + ["highlighted", "disabled"], + ["highlighted", "pressed"], + ["highlighted", "checked"], + ["highlighted", "checkable", "pressed"], + ["highlighted", "checkable", "checked"], + ["flat"], + ["flat", "disabled"], + ["flat", "pressed"], + ["flat", "checked"], + ["flat", "checkable"], + ["flat", "checkable", "pressed"], + ["flat", "checkable", "checked", "pressed"], + ["flat", "checkable", "highlighted"], + ["flat", "checkable", "highlighted", "pressed"], + ["flat", "checkable", "highlighted", "checked"] + ] + + property Component component: RoundButton { + text: "B" + enabled: !is("disabled") + flat: is("flat") + checkable: is("checkable") + // Only set it if it's pressed, or the non-pressed examples will have no press effects + down: is("pressed") ? true : undefined + highlighted: is("highlighted") + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/ScrollBar.qml b/tests/manual/quickcontrols2/testbench/controls/ScrollBar.qml new file mode 100644 index 00000000000..4ed80f750ea --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/ScrollBar.qml @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + ["vertical"], + ["vertical", "disabled"], + ["vertical", "interactive"], + ["vertical", "interactive", "disabled"], + ["horizontal"], + ["horizontal", "disabled"], + ["horizontal", "interactive"], + ["horizontal", "interactive", "disabled"] + ] + + property Component component: Frame { + width: 100 + height: 100 + clip: true + + Label { + text: "ABCDEFG\nHIJKLMN" + font.pixelSize: 40 + x: -horizontalScrollBar.position * width + y: -verticalScrollBar.position * height + } + + ScrollBar { + id: verticalScrollBar + enabled: !is("disabled") + orientation: Qt.Vertical + interactive: is("interactive") + visible: is("vertical") + size: 0.3 + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + + Binding { + target: verticalScrollBar + property: "active" + value: verticalScrollBar.visible + } + } + + ScrollBar { + id: horizontalScrollBar + enabled: !is("disabled") + orientation: Qt.Horizontal + interactive: is("interactive") + visible: is("horizontal") + size: 0.3 + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + + Binding { + target: horizontalScrollBar + property: "active" + value: horizontalScrollBar.visible + } + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/ScrollIndicator.qml b/tests/manual/quickcontrols2/testbench/controls/ScrollIndicator.qml new file mode 100644 index 00000000000..d9ee487d083 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/ScrollIndicator.qml @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + ["vertical"], + ["vertical", "disabled"], + ["horizontal"], + ["horizontal", "disabled"], + ] + + property Component component: Frame { + width: 100 + height: 100 + clip: true + + Label { + text: "ABCDEFG\nHIJKLMN" + font.pixelSize: 40 + x: horizontalScrollIndicator.position * width + y: verticalScrollIndicator.position * height + } + + ScrollIndicator { + id: verticalScrollIndicator + enabled: !is("disabled") + orientation: Qt.Vertical + active: true + visible: is("vertical") + size: 0.3 + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + } + + ScrollIndicator { + id: horizontalScrollIndicator + enabled: !is("disabled") + orientation: Qt.Horizontal + active: true + visible: is("horizontal") + size: 0.3 + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + + Binding { + target: horizontalScrollIndicator + property: "active" + value: horizontalScrollIndicator.visible + } + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/Slider.qml b/tests/manual/quickcontrols2/testbench/controls/Slider.qml new file mode 100644 index 00000000000..21e751acd7b --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/Slider.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + ["vertical"], + ["vertical", "disabled"], + ["vertical", "pressed"], + ["horizontal"], + ["horizontal", "disabled"], + ["horizontal", "pressed"] + ] + + property Component component: Slider { + enabled: !is("disabled") + orientation: is("horizontal") ? Qt.Horizontal : Qt.Vertical + value: 0.5 + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/SpinBox.qml b/tests/manual/quickcontrols2/testbench/controls/SpinBox.qml new file mode 100644 index 00000000000..22ca6ccefc0 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/SpinBox.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["pressed"], + ["disabled"], + ["mirrored"], + ["mirrored", "pressed"], + ["mirrored", "disabled"], + ["editable"], + ["editable", "pressed"], + ["editable", "disabled"], + ["editable", "mirrored"], + ["editable", "mirrored", "pressed"], + ["editable", "mirrored", "disabled"] + ] + + property Component component: SpinBox { + value: 1 + enabled: !is("disabled") + editable: is("editable") + up.pressed: is("pressed") + + LayoutMirroring.enabled: is("mirrored") + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/SplitView.qml b/tests/manual/quickcontrols2/testbench/controls/SplitView.qml new file mode 100644 index 00000000000..f2801def8f3 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/SplitView.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [] + ] + + property Component component: SplitView { + implicitWidth: 400 + implicitHeight: 100 + + Rectangle { + color: "salmon" + implicitWidth: 25 + implicitHeight: 25 + } + Rectangle { + color: "navajowhite" + implicitWidth: 100 + implicitHeight: 100 + } + Rectangle { + color: "steelblue" + implicitWidth: 200 + implicitHeight: 200 + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/SwipeDelegate.qml b/tests/manual/quickcontrols2/testbench/controls/SwipeDelegate.qml new file mode 100644 index 00000000000..13d0a4437c0 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/SwipeDelegate.qml @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["pressed"], + ["highlighted"], + ["highlighted", "pressed"] + ] + + property Component actionComponent: Component { + Rectangle { + color: SwipeDelegate.pressed ? "#333" : "#444" + width: parent ? parent.width : 0 + height: parent ? parent.height: 0 + clip: true + + Label { + text: "Test" + color: "white" + anchors.centerIn: parent + } + } + } + + property Component component: SwipeDelegate { + id: swipeDelegate + text: "SwipeDelegate" + enabled: !is("disabled") + checkable: is("checkable") + // Only set it if it's pressed, or the non-pressed examples will have no press effects + down: is("pressed") ? true : undefined + highlighted: is("highlighted") + focusPolicy: Qt.StrongFocus + + swipe.left: actionComponent + swipe.right: actionComponent + } + + property Component exampleComponent: ListView { + implicitWidth: 200 + implicitHeight: 200 + clip: true + model: 20 + delegate: SwipeDelegate { + width: parent.width + text: "SwipeDelegate" + focusPolicy: Qt.StrongFocus + + swipe.left: actionComponent + swipe.right: actionComponent + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/Switch.qml b/tests/manual/quickcontrols2/testbench/controls/Switch.qml new file mode 100644 index 00000000000..6e877a49952 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/Switch.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["pressed"], + ["checked"], + ["checked", "disabled"], + ["checked", "disabled", "mirrored"], + ["checked", "pressed"], + ["checked", "pressed", "mirrored"], + ["mirrored"], + ] + + property Component component: Switch { + text: "Switch" + enabled: !is("disabled") + checked: is("checked") + // Only set it if it's pressed, or the non-pressed examples will have no press effects + down: is("pressed") ? true : undefined + + LayoutMirroring.enabled: is("mirrored") + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/SwitchDelegate.qml b/tests/manual/quickcontrols2/testbench/controls/SwitchDelegate.qml new file mode 100644 index 00000000000..4f60da5537e --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/SwitchDelegate.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ["pressed"], + ["highlighted"], + ["highlighted", "pressed"], + ["mirrored"] + ] + + property Component component: SwitchDelegate { + text: "SwitchDelegate" + enabled: !is("disabled") + // Only set it if it's pressed, or the non-pressed examples will have no press effects + down: is("pressed") ? true : undefined + highlighted: is("highlighted") + focusPolicy: Qt.StrongFocus + + LayoutMirroring.enabled: is("mirrored") + } + + property Component exampleComponent: ListView { + implicitWidth: 200 + implicitHeight: 200 + clip: true + model: 20 + delegate: SwitchDelegate { + width: parent.width + text: "SwitchDelegate" + focusPolicy: Qt.StrongFocus + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/TabBar.qml b/tests/manual/quickcontrols2/testbench/controls/TabBar.qml new file mode 100644 index 00000000000..a7a1de490a8 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/TabBar.qml @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +// TODO +QtObject { + property string customControlName: qsTr("TabBar & TabButton") + + property var supportedStates: [ + ["header"], + ["header", "disabled"], + ["footer"], + ["footer", "disabled"] + ] + + property Component component: TabBar { + implicitHeight: tabButton1.implicitHeight + enabled: !is("disabled") + position: is("header") ? TabBar.Header : TabBar.Footer + + TabButton { + id: tabButton1 + text: qsTr("TabButton 1") + } + TabButton { + text: qsTr("TabButton 2") + } + TabButton { + text: qsTr("TabButton 3") + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/TextArea.qml b/tests/manual/quickcontrols2/testbench/controls/TextArea.qml new file mode 100644 index 00000000000..dfe28f79f44 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/TextArea.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ] + + property Component component: Column { + spacing: 10 + + TextArea { + text: "TextArea\nwith\ntext" + enabled: !is("disabled") + } + + TextArea { + placeholderText: "TextArea with placeholderText" + enabled: !is("disabled") + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/TextField.qml b/tests/manual/quickcontrols2/testbench/controls/TextField.qml new file mode 100644 index 00000000000..1eed3a6c4aa --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/TextField.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +QtObject { + property var supportedStates: [ + [], + ["disabled"], + ] + + property Component component: Column { + spacing: 10 + + TextField { + text: "TextField with text" + enabled: !is("disabled") + } + + TextField { + placeholderText: "TextField with placeholderText" + enabled: !is("disabled") + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/ToolBar.qml b/tests/manual/quickcontrols2/testbench/controls/ToolBar.qml new file mode 100644 index 00000000000..3aba3377822 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/ToolBar.qml @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +// TODO +QtObject { + property string customControlName: qsTr("ToolBar, ToolButton & ToolSeparator") + + property var supportedStates: [ + ["header"], + ["header", "disabled"], + ["footer"], + ["footer", "disabled"] + ] + + property Component component: ToolBar { + enabled: !is("disabled") + position: is("header") ? ToolBar.Header : ToolBar.Footer + + RowLayout { + anchors.fill: parent + + ToolButton { + text: qsTr("ToolButton 1") + } + ToolButton { + text: qsTr("ToolButton 2") + } + + ToolSeparator {} + + ToolButton { + text: qsTr("ToolButton 3") + } + } + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/ToolTip.qml b/tests/manual/quickcontrols2/testbench/controls/ToolTip.qml new file mode 100644 index 00000000000..ddcf92f8605 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/ToolTip.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +QtObject { + property var supportedStates: [ + [] + ] + + property Component component: Button { + text: qsTr("Hover over me") + + ToolTip.text: qsTr("ToolTip") + ToolTip.visible: hovered + ToolTip.delay: 500 + } +} diff --git a/tests/manual/quickcontrols2/testbench/controls/Tumbler.qml b/tests/manual/quickcontrols2/testbench/controls/Tumbler.qml new file mode 100644 index 00000000000..a2dbebef270 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/controls/Tumbler.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +QtObject { + property var supportedStates: [ + [], + ["disabled"] + ] + + property Component component: Tumbler { + model: 20 + enabled: !is("disabled") + + LayoutMirroring.enabled: is("mirrored") + } +} diff --git a/tests/manual/quickcontrols2/testbench/deployment.pri b/tests/manual/quickcontrols2/testbench/deployment.pri new file mode 100644 index 00000000000..c89af25a853 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/deployment.pri @@ -0,0 +1,14 @@ +unix:!android { + isEmpty(target.path) { + qnx { + target.path = /tmp/$${TARGET}/bin + } else { + target.path = /opt/$${TARGET}/bin + } + export(target.path) + } + INSTALLS += target +} + +export(INSTALLS) + diff --git a/tests/manual/quickcontrols2/testbench/directoryvalidator.cpp b/tests/manual/quickcontrols2/testbench/directoryvalidator.cpp new file mode 100644 index 00000000000..d0d4cd8d57c --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/directoryvalidator.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directoryvalidator.h" + +#include <QFileInfo> + +DirectoryValidator::DirectoryValidator(QObject *parent) : + QObject(parent) +{ +} + +QString DirectoryValidator::path() const +{ + return mPath; +} + +void DirectoryValidator::setPath(const QString &path) +{ + if (path == mPath) + return; + + const bool wasValid = isValid(); + const QString oldErrorMessage = mErrorMessage; + + mPath = path; + mErrorMessage.clear(); + + QFileInfo fileInfo(mPath); + if (!fileInfo.exists()) { + mErrorMessage = QLatin1String("Directory does not exist"); + } else { + if (!fileInfo.isDir()) { + mErrorMessage = QLatin1String("Not a directory"); + } + } + + if (isValid() != wasValid) + emit validChanged(); + + if (mErrorMessage != oldErrorMessage) + emit errorMessageChanged(); + + emit pathChanged(); +} + +bool DirectoryValidator::isValid() const +{ + return mErrorMessage.isEmpty(); +} + +QString DirectoryValidator::errorMessage() const +{ + return mErrorMessage; +} diff --git a/tests/manual/quickcontrols2/testbench/directoryvalidator.h b/tests/manual/quickcontrols2/testbench/directoryvalidator.h new file mode 100644 index 00000000000..a1650d863fb --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/directoryvalidator.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTORYVALIDATOR_H +#define DIRECTORYVALIDATOR_H + +#include <QObject> + +class DirectoryValidator : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged FINAL) + Q_PROPERTY(bool valid READ isValid NOTIFY validChanged FINAL) + Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged FINAL) + +public: + explicit DirectoryValidator(QObject *parent = nullptr); + + QString path() const; + void setPath(const QString &path); + + bool isValid() const; + QString errorMessage() const; + +signals: + void pathChanged(); + void validChanged(); + void errorMessageChanged(); + +private: + void updateValid(); + + QString mPath; + QString mErrorMessage; +}; + +#endif // DIRECTORYVALIDATOR_H diff --git a/tests/manual/quickcontrols2/testbench/fonts.qrc b/tests/manual/quickcontrols2/testbench/fonts.qrc new file mode 100644 index 00000000000..fc86e031836 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/fonts.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>fonts/fontawesome.ttf</file> + </qresource> +</RCC> diff --git a/tests/manual/quickcontrols2/testbench/fonts/LICENSE.txt b/tests/manual/quickcontrols2/testbench/fonts/LICENSE.txt new file mode 100644 index 00000000000..8fa3da363e9 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/fonts/LICENSE.txt @@ -0,0 +1,12 @@ +Font license info + + +## Font Awesome + + Copyright (C) 2016 by Dave Gandy + + Author: Dave Gandy + License: SIL () + Homepage: http://fortawesome.github.com/Font-Awesome/ + + diff --git a/tests/manual/quickcontrols2/testbench/fonts/fontawesome.ttf b/tests/manual/quickcontrols2/testbench/fonts/fontawesome.ttf new file mode 100644 index 00000000000..49b6c5da654 Binary files /dev/null and b/tests/manual/quickcontrols2/testbench/fonts/fontawesome.ttf differ diff --git a/tests/manual/quickcontrols2/testbench/main.cpp b/tests/manual/quickcontrols2/testbench/main.cpp new file mode 100644 index 00000000000..ddad828f306 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/main.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDebug> +#include <QFontDatabase> +#include <QGuiApplication> +#include <QSettings> +#include <QQmlApplicationEngine> +#include <QQmlContext> +#include <QQuickStyle> +#include <QtQuickControls2/private/qquickstyle_p.h> + +#include "assetfixer.h" +#include "clipboard.h" +#include "directoryvalidator.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication::setApplicationName("testbench"); + QGuiApplication::setOrganizationName("QtProject"); + + QGuiApplication app(argc, argv); + + QSettings settings; + QString style = QQuickStyle::name(); + if (!style.isEmpty() && !QQuickStylePrivate::isUsingDefaultStyle()) + settings.setValue("style", style); + else + QQuickStyle::setStyle(settings.value("style").isValid() ? settings.value("style").toString() : "Imagine"); + + if (QFontDatabase::addApplicationFont(":/fonts/fontawesome.ttf") == -1) { + qWarning() << "Failed to load fontawesome font"; + } + + QQmlApplicationEngine engine; + + qmlRegisterType<AssetFixer>("Backend", 1, 0, "AssetFixer"); + qmlRegisterType<Clipboard>("Backend", 1, 0, "Clipboard"); + qmlRegisterType<DirectoryValidator>("Backend", 1, 0, "DirectoryValidator"); + + engine.rootContext()->setContextProperty("availableStyles", QQuickStylePrivate::builtInStyles()); + + engine.load(QUrl(QStringLiteral("qrc:/testbench.qml"))); + + return app.exec(); +} + diff --git a/tests/manual/quickcontrols2/testbench/qml.qrc b/tests/manual/quickcontrols2/testbench/qml.qrc new file mode 100644 index 00000000000..82e69be6f31 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/qml.qrc @@ -0,0 +1,55 @@ +<RCC> + <qresource prefix="/"> + <file>ControlContainer.qml</file> + <file>controls/Button.qml</file> + <file>controls/CheckBox.qml</file> + <file>controls/RadioButton.qml</file> + <file>controls/CheckDelegate.qml</file> + <file>controls/ComboBox.qml</file> + <file>controls/DelayButton.qml</file> + <file>controls/Dial.qml</file> + <file>controls/Frame.qml</file> + <file>controls/GroupBox.qml</file> + <file>controls/ItemDelegate.qml</file> + <file>controls/Page.qml</file> + <file>controls/PageIndicator.qml</file> + <file>controls/Pane.qml</file> + <file>controls/ProgressBar.qml</file> + <file>controls/RadioDelegate.qml</file> + <file>controls/RangeSlider.qml</file> + <file>controls/RoundButton.qml</file> + <file>controls/ScrollBar.qml</file> + <file>controls/ScrollIndicator.qml</file> + <file>controls/Slider.qml</file> + <file>controls/SpinBox.qml</file> + <file>controls/SwipeDelegate.qml</file> + <file>controls/Switch.qml</file> + <file>controls/SwitchDelegate.qml</file> + <file>controls/TabBar.qml</file> + <file>controls/TextArea.qml</file> + <file>controls/TextField.qml</file> + <file>SettingsDialog.qml</file> + <file>ColorEditor.qml</file> + <file>controls/ToolBar.qml</file> + <file>controls/Dialog.qml</file> + <file>controls/Menu.qml</file> + <file>ExampleContainer.qml</file> + <file>controls/Label.qml</file> + <file>controls/ToolTip.qml</file> + <file>controls/Tumbler.qml</file> + <file>controls/BusyIndicator.qml</file> + <file>testbench.qml</file> + <file>controls/MenuBar.qml</file> + <file>controls/SplitView.qml</file> + <file>+Imagine/ApplicationWindow.qml</file> + <file>ApplicationWindow.qml</file> + <file>+Imagine/ToolBar.qml</file> + <file>ToolBar.qml</file> + <file>+Imagine/Menu.qml</file> + <file>Menu.qml</file> + <file>+Imagine/Dialog.qml</file> + <file>Dialog.qml</file> + <file>ContentPane.qml</file> + <file>+Imagine/ContentPane.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/quickcontrols2/testbench/testbench.pro b/tests/manual/quickcontrols2/testbench/testbench.pro new file mode 100644 index 00000000000..4509f4967d6 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/testbench.pro @@ -0,0 +1,24 @@ +TEMPLATE = app + +QT += qml quick quickcontrols2 quickcontrols2-private +CONFIG += c++11 + +HEADERS += \ + assetfixer.h \ + directoryvalidator.h \ + clipboard.h + +SOURCES += main.cpp \ + assetfixer.cpp \ + directoryvalidator.cpp \ + clipboard.cpp + +RESOURCES += qml.qrc \ + fonts.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Default rules for deployment. +include(deployment.pri) + diff --git a/tests/manual/quickcontrols2/testbench/testbench.qml b/tests/manual/quickcontrols2/testbench/testbench.qml new file mode 100644 index 00000000000..8f0951adae7 --- /dev/null +++ b/tests/manual/quickcontrols2/testbench/testbench.qml @@ -0,0 +1,533 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtQuick.Layouts +import QtQuick.Controls +import Qt.labs.folderlistmodel +import Qt.labs.settings + +import Backend +import "." as Ui + +Ui.ApplicationWindow { + id: window + visible: true + width: 1000 + height: 750 + title: "Style Testbench - " + settings.style + " Style" + (usingImagineStyle ? imagineTitleText : "") + + readonly property bool usingImagineStyle: settings.style === "Imagine" + // Some controls should be visible regardless of whether or not custom assets are lacking for it, + // so we use the default assets in some cases. + readonly property string defaultImaginePath: "qrc:/qt-project.org/imports/QtQuick/Controls/Imagine/images/" + property bool settingsLoaded: false + readonly property string imagineTitleText: " - " + (settings.useCustomImaginePath ? settings.imaginePath : "Default Assets") + + LoggingCategory { + id: brief + name: "qt.quick.controls.tools.testbench.assetfixer.brief" + } + + Shortcut { + sequence: "Ctrl+F" + onActivated: searchTextField.forceActiveFocus() + } + + Shortcut { + sequence: "Ctrl+Q" + onActivated: Qt.quit() + } + + Action { + id: fixAssetsAction + text: qsTr("Fix Custom Assets") + shortcut: "Ctrl+Shift+X" + enabled: usingImagineStyle + onTriggered: assetFixer.manualFix() + } + + Action { + id: useCustomAssetsAction + text: qsTr("Use Custom Assets") + shortcut: "Ctrl+Shift+C" + enabled: usingImagineStyle + checkable: true + checked: settings.useCustomImaginePath + onTriggered: settings.useCustomImaginePath = !settings.useCustomImaginePath + } + + Action { + id: reloadAssetsAction + text: qsTr("Reload Assets") + shortcut: "Ctrl+R" + enabled: usingImagineStyle + onTriggered: assetFixer.reloadAssets() + } + + FontMetrics { + id: fontMetrics + } + + Settings { + id: settings + + property alias windowX: window.x + property alias windowY: window.y + property alias windowWidth: window.width + property alias windowHeight: window.height + + property string style: "Imagine" + + property bool useCustomImaginePath + property string imaginePath + property bool autoFixImagineAssets + property alias imagineDirLastModified: assetFixer.assetDirectoryLastModified + + Component.onCompleted: settingsLoaded = true + } + + Settings { + id: paletteSettings + + category: "Palette" + + property bool useCustomPalette + property string window + property string windowText + property string base + property string text + property string button + property string buttonText + property string brightText + property string toolTipBase + property string toolTipText + property string light + property string midlight + property string dark + property string mid + property string shadow + property string highlight + property string highlightedText + property string link + } + + header: Ui.ToolBar { + RowLayout { + anchors.fill: parent + + ToolButton { + text: "\uf0c9" + font.family: "fontawesome" + font.pixelSize: Qt.application.font.pixelSize * 1.6 + onClicked: drawer.open() + } + + ToolSeparator {} + + TextField { + id: searchTextField + placeholderText: "Search" + } + + Item { + Layout.fillWidth: true + } + + ToolButton { + id: optionsMenuButton + text: "\ue800" + font.family: "FontAwesome" + font.pixelSize: Qt.application.font.pixelSize * 1.6 + checked: optionsMenu.visible + checkable: true + + onClicked: optionsMenu.open() + + Ui.Menu { + id: optionsMenu + x: 1 + y: 1 + parent.height + visible: optionsMenuButton.checked + closePolicy: Popup.CloseOnPressOutsideParent + + MenuItem { + text: qsTr("Open Asset Directory") + onClicked: Qt.openUrlExternally(assetFixer.assetDirectoryUrl) + enabled: usingImagineStyle + } + + MenuItem { + action: reloadAssetsAction + } + + MenuItem { + action: useCustomAssetsAction + } + + MenuItem { + action: fixAssetsAction + } + + MenuSeparator {} + + MenuItem { + id: settingsMenuItem + text: qsTr("Settings") + onTriggered: settingsDialog.open() + } + + MenuSeparator {} + + MenuItem { + text: qsTr("Quit") + onTriggered: Qt.quit() + } + } + } + } + } + + SettingsDialog { + id: settingsDialog + } + + Drawer { + id: drawer + width: parent.width * 0.33 + height: window.height + focus: false + modal: false + + Label { + text: "Drawer contents go here" + anchors.centerIn: parent + } + } + + AssetFixer { + id: assetFixer + assetDirectory: settings.imaginePath + // Don't start watching until the settings have loaded, as AssetFixer can be completed before it. + // AssetFixer needs the settings in order to check the last modified time of the asset directory. + // Also, wait until the UI has been rendered for the first time so that we can show our busy indicators, etc. + shouldWatch: usingImagineStyle && settings.useCustomImaginePath && settingsLoaded && initialUiRenderDelayTimer.hasRun + shouldFix: (shouldWatch && settings.autoFixImagineAssets) || manuallyFixing + + onFixSuggested: autoFix() + onDelayedFixSuggested: assetFixerFileSystemDelayTimer.restart() + onReloadSuggested: reloadAssets() + + property bool manuallyFixing: false + + function reloadAssets() { + console.log(brief, "Reloading assets...") + // Clear the model, otherwise ListView will keep the old items around + // with the old assets, even after clearing the pixmap cache + listView.resettingModel = true + listView.model = null + window.Imagine.path = "" + assetReloadNextFrameTimer.start() + } + + function autoFix() { + // This is a bit of a hack, but I can't think of a nice way to solve it. + // The problem is that shouldWatch becomes true, causing startWatching() to be called. + // If a fix is suggested as a result of that, this function is called. + // However, the shouldFix binding hasn't been updated yet, so even though shouldWatch + // and settings.autoFixImagineAssets are both true (the properties that make up its binding), + // the if check below fails. So, we check for that case with effectiveShouldFix. + var effectiveShouldFix = shouldWatch && settings.autoFixImagineAssets; + if (shouldWatch && effectiveShouldFix && assetDirectory.length > 0) { + fixEmUp(); + } + } + + function manualFix() { + fixEmUp(true); + } + + function fixEmUp(manually) { + assetFixer.manuallyFixing = !!manually + + // Disable image caching if it hasn't already been done. + assetFixer.clearImageCache() + + busyIndicatorRow.visible = true + assetFixerAnimationDelayTimer.start() + } + } + + // The controls' assets don't always "reload" if the path is cleared and then set in the same frame, + // so we delay the setting to the next frame. + Timer { + id: assetReloadNextFrameTimer + interval: 0 + onTriggered: { + window.Imagine.path = Qt.binding(function() { + return settings.useCustomImaginePath && settings.imaginePath.length > 0 ? settings.imaginePath : undefined + }) + + infoToolTip.text = "Reloaded assets" + infoToolTip.timeout = 1500 + infoToolTip.open() + + listView.model = controlFolderListModel + listView.resettingModel = false + + console.log(brief, "... reloaded assets.") + } + } + + // When exporting or deleting a large amount of assets (not uncommon), + // the filesystem watcher seems to emit directoryChanged() every second or so, + // so rather than process hundreds of assets every time we get notified, delay + // it until we haven't been notified for a while. + Timer { + id: assetFixerFileSystemDelayTimer + interval: 2000 + onRunningChanged: { + if (running) { + infoToolTip.text = "Assets changed on disk - reloading in 2 seconds if no further changes are detected" + infoToolTip.timeout = 2000 + infoToolTip.open() + } + } + onTriggered: assetFixer.autoFix() + } + + // Gives the BusyIndicator animation a chance to start. + Timer { + id: assetFixerAnimationDelayTimer + interval: 100 + onTriggered: { + assetFixer.fixAssets() + busyIndicatorRow.visible = false + assetFixer.manuallyFixing = false + } + } + + // Gives the UI a chance to render before the initial fixup. + Timer { + id: initialUiRenderDelayTimer + interval: 300 + running: true + onTriggered: hasRun = true + + property bool hasRun: false + } + + function getControlElements(control) { + var props = []; + for (var p in control) { + if (p !== "component" && typeof control[p] === 'object') + props.push(p); + } + return props; + } + + Ui.ContentPane { + id: contentPane + anchors.fill: parent + + palette.window: effectiveColor(paletteSettings.window) + palette.windowText: effectiveColor(paletteSettings.windowText) + palette.base: effectiveColor(paletteSettings.base) + palette.text: effectiveColor(paletteSettings.text) + palette.button: effectiveColor(paletteSettings.button) + palette.buttonText: effectiveColor(paletteSettings.buttonText) + palette.brightText: effectiveColor(paletteSettings.brightText) + palette.toolTipBase: effectiveColor(paletteSettings.toolTipBase) + palette.toolTipText: effectiveColor(paletteSettings.toolTipText) + palette.light: effectiveColor(paletteSettings.light) + palette.midlight: effectiveColor(paletteSettings.midlight) + palette.dark: effectiveColor(paletteSettings.dark) + palette.mid: effectiveColor(paletteSettings.mid) + palette.shadow: effectiveColor(paletteSettings.shadow) + palette.highlight: effectiveColor(paletteSettings.highlight) + palette.highlightedText: effectiveColor(paletteSettings.highlightedText) + palette.link: effectiveColor(paletteSettings.link) + + function effectiveColor(paletteColorString) { + return paletteSettings.useCustomPalette && paletteColorString.length > 0 ? paletteColorString : undefined + } + + FolderListModel { + id: controlFolderListModel + folder: "qrc:/controls" + showDirs: false + nameFilters: searchTextField.text.length > 0 ? ["*" + searchTextField.text + "*.qml"] : [] + caseSensitive: false + } + + ListView { + id: listView + anchors.fill: parent + spacing: 30 + visible: !busyIndicatorRow.visible && !resettingModel + + property bool resettingModel: false + + ScrollBar.vertical: ScrollBar { + parent: contentPane + anchors.top: parent.top + anchors.right: parent.right + anchors.bottom: parent.bottom + } + + model: controlFolderListModel + delegate: ColumnLayout { + id: rootDelegate + width: listView.width + + MenuSeparator { + Layout.fillWidth: true + visible: index !== 0 + } + + Label { + text: customControlName.length === 0 ? model.fileBaseName : customControlName + font.pixelSize: Qt.application.font.pixelSize * 2 + } + + readonly property var controlName: model.fileBaseName + readonly property var controlMetaObject: controlMetaObjectLoader.item + readonly property string customControlName: controlMetaObject && controlMetaObject.hasOwnProperty("customControlName") + ? controlMetaObject.customControlName : "" + readonly property var supportedStates: rootDelegate.controlMetaObject.supportedStates + readonly property int maxStateCombinations: { + var largest = 0; + for (var i = 0; i < supportedStates.length; ++i) { + var combinations = supportedStates[i]; + if (combinations.length > largest) + largest = combinations.length; + } + return largest; + } + + Loader { + id: controlMetaObjectLoader + source: "qrc" + model.filePath + } + + Flow { + spacing: 10 + + Layout.fillWidth: true + + Repeater { + id: stateRepeater + model: rootDelegate.supportedStates + + ColumnLayout { + id: labelWithDelegatesColumn + spacing: 4 + + readonly property var states: modelData + readonly property string statesAsString: states.join("\n") + + Label { + text: statesAsString.length > 0 ? statesAsString : "normal" + + // 4 is the most states for any element (Button) + Layout.preferredHeight: (fontMetrics.lineSpacing) * (rootDelegate.maxStateCombinations + 1) + } + + ControlContainer { + id: controlContainer + objectName: controlName + "ControlContainer" + controlMetaObject: rootDelegate.controlMetaObject + states: labelWithDelegatesColumn.states + + Layout.alignment: Qt.AlignHCenter + } + } + } + } + + ExampleContainer { + id: exampleContainer + controlMetaObject: rootDelegate.controlMetaObject + visible: !!controlMetaObject.exampleComponent + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: visible ? 14 : 0 + Layout.fillWidth: true + Layout.preferredHeight: visible ? implicitHeight : 0 + } + } + } + } + + RowLayout { + id: busyIndicatorRow + anchors.centerIn: parent + visible: false + + BusyIndicator { + id: busyIndicator + running: visible + } + + Label { + text: qsTr("Fixing assets...") + font.pixelSize: Qt.application.font.pixelSize * 2 + } + } + + ToolTip { + id: infoToolTip + x: (parent.width - width) / 2 + y: parent.height - height - 40 + parent: window.contentItem + } +} + diff --git a/tests/manual/quickcontrols2/viewinqwidget/CMakeLists.txt b/tests/manual/quickcontrols2/viewinqwidget/CMakeLists.txt new file mode 100644 index 00000000000..f91b0d8c021 --- /dev/null +++ b/tests/manual/quickcontrols2/viewinqwidget/CMakeLists.txt @@ -0,0 +1,41 @@ +# Generated from viewinqwidget.pro. + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(viewinqwidget LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +##################################################################### +## viewinqwidget Binary: +##################################################################### + +qt_internal_add_manual_test(viewinqwidget + GUI + SOURCES + main.cpp + DEFINES + SRCDIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}/\\\" + PUBLIC_LIBRARIES + Qt::Gui + Qt::Qml + Qt::Quick + Qt::QuickWidgets + Qt::Widgets +) + +# Resources: +set(viewinqwidget_resource_files + "main.qml" +) + +qt_internal_add_resource(viewinqwidget "viewinqwidget" + PREFIX + "/" + FILES + ${viewinqwidget_resource_files} +) + + +#### Keys ignored in scope 1:.:.:viewinqwidget.pro:<TRUE>: +# OTHER_FILES = "main.qml" diff --git a/tests/manual/quickcontrols2/viewinqwidget/main.cpp b/tests/manual/quickcontrols2/viewinqwidget/main.cpp new file mode 100644 index 00000000000..b6b7a5ff02d --- /dev/null +++ b/tests/manual/quickcontrols2/viewinqwidget/main.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QApplication> +#include <QHBoxLayout> +#include <QVBoxLayout> +#include <QDebug> +#include <QDir> +#include <QGroupBox> +#include <QScreen> +#include <QQmlApplicationEngine> +#include <QQmlError> +#include <QQuickView> +#include <QQuickWidget> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QWidget widget; + widget.setWindowTitle(QT_VERSION_STR); + + QHBoxLayout *hLayout = new QHBoxLayout(&widget); + QGroupBox *groupBox = new QGroupBox("QuickWidget", &widget); + QVBoxLayout *vLayout = new QVBoxLayout(groupBox); + QQuickWidget *quickWidget = new QQuickWidget(groupBox); + quickWidget->setMinimumSize(360, 520); + vLayout->addWidget(quickWidget); + quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + quickWidget->setSource(QUrl(QLatin1String("qrc:/main.qml"))); + if (quickWidget->status() == QQuickWidget::Error) { + qWarning() << quickWidget->errors(); + return 1; + } + hLayout->addWidget(groupBox); + + const QString gallerySource = + QDir::cleanPath(QLatin1String(SRCDIR"../../../examples/quickcontrols2/gallery/gallery.qml")); + QQmlApplicationEngine engine(QUrl::fromLocalFile(gallerySource)); + QObject *root = engine.rootObjects().value(0, nullptr); + if (!root || !root->isWindowType()) { + qWarning() << "Load error" << gallerySource; + return 1; + } + groupBox = new QGroupBox("QQuickView/createWindowContainer", &widget); + vLayout = new QVBoxLayout(groupBox); + QWidget *container = QWidget::createWindowContainer(qobject_cast<QWindow *>(root), groupBox); + container->setMinimumSize(360, 520); + vLayout->addWidget(container); + hLayout->addWidget(groupBox); + + const QRect availableGeometry = widget.screen()->availableGeometry(); + widget.move(availableGeometry.center() - QPoint(widget.sizeHint().width() / 2, widget.sizeHint().height() / 2)); + + widget.show(); + + return app.exec(); +} diff --git a/tests/manual/quickcontrols2/viewinqwidget/main.qml b/tests/manual/quickcontrols2/viewinqwidget/main.qml new file mode 100644 index 00000000000..5ac170b3204 --- /dev/null +++ b/tests/manual/quickcontrols2/viewinqwidget/main.qml @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + visible: true + width: 360 + height: 520 + + ComboBox { + model: ["First", "Second", "Third"] + anchors.centerIn: parent + } +} diff --git a/tests/manual/quickcontrols2/viewinqwidget/viewinqwidget.pro b/tests/manual/quickcontrols2/viewinqwidget/viewinqwidget.pro new file mode 100644 index 00000000000..649829d449b --- /dev/null +++ b/tests/manual/quickcontrols2/viewinqwidget/viewinqwidget.pro @@ -0,0 +1,6 @@ +QT += qml quick widgets quickwidgets +TARGET = viewinqwidget +SOURCES += $$PWD/main.cpp +OTHER_FILES += main.qml +RESOURCES += viewinqwidget.qrc +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/manual/quickcontrols2/viewinqwidget/viewinqwidget.qrc b/tests/manual/quickcontrols2/viewinqwidget/viewinqwidget.qrc new file mode 100644 index 00000000000..5f6483ac33f --- /dev/null +++ b/tests/manual/quickcontrols2/viewinqwidget/viewinqwidget.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/quickdialogs/CMakeLists.txt b/tests/manual/quickdialogs/CMakeLists.txt new file mode 100644 index 00000000000..f58b9ce388f --- /dev/null +++ b/tests/manual/quickdialogs/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(dialogs) diff --git a/tests/manual/quickdialogs/dialogs/CMakeLists.txt b/tests/manual/quickdialogs/dialogs/CMakeLists.txt new file mode 100644 index 00000000000..0980f40c405 --- /dev/null +++ b/tests/manual/quickdialogs/dialogs/CMakeLists.txt @@ -0,0 +1,34 @@ +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(dialogs LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +qt_internal_add_manual_test(dialogs + GUI + SOURCES + dialogs.cpp + PUBLIC_LIBRARIES + Qt::Gui + Qt::Qml + Qt::QuickControls2 +) + +# Resources: +set(qmake_immediate_resource_files + "dialogs.qml" + "FileDialogPage.qml" + "FolderDialogPage.qml" + "FontDialogPage.qml" + "StringListView.qml" + "MessageDialogPage.qml" + "qmldir" + "Theme.qml" +) + +qt_internal_add_resource(dialogs "qmake_immediate" + PREFIX + "/" + FILES + ${qmake_immediate_resource_files} +) diff --git a/tests/manual/quickdialogs/dialogs/FileDialogPage.qml b/tests/manual/quickdialogs/dialogs/FileDialogPage.qml new file mode 100644 index 00000000000..211725b8cec --- /dev/null +++ b/tests/manual/quickdialogs/dialogs/FileDialogPage.qml @@ -0,0 +1,357 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs +import QtQuick.Layouts + +import "." + +ColumnLayout { + property alias dialog: fileDialog + + // Put it all in another ColumnLayout so we can easily add margins. + ColumnLayout { + Layout.leftMargin: 12 + Layout.rightMargin: 12 + Layout.topMargin: 12 + Layout.bottomMargin: 12 + + GroupBox { + title: qsTr("Dialog properties") + + Layout.fillWidth: true + + GridLayout { + columns: 2 + anchors.fill: parent + + Label { + text: qsTr("modality") + + Layout.alignment: Qt.AlignTop + Layout.minimumWidth: ApplicationWindow.window.width * 0.2 + Layout.maximumWidth: ApplicationWindow.window.width * 0.2 + } + ButtonGroup { + id: modalityButtonGroup + buttons: modalityColumnLayout.children + } + ColumnLayout { + id: modalityColumnLayout + + RadioButton { + text: qsTr("Qt.NonModal") + + readonly property int modality: Qt.NonModal + } + RadioButton { + text: qsTr("Qt.WindowModal") + checked: true + + readonly property int modality: Qt.WindowModal + } + RadioButton { + text: qsTr("Qt.ApplicationModal") + + readonly property int modality: Qt.ApplicationModal + } + } + + Label { + text: qsTr("result") + } + TextField { + id: resultTextField + text: fileDialog.result === 1 ? qsTr("Accepted") : qsTr("Rejected") + readOnly: true + enabled: false + } + + Label { + text: qsTr("title") + } + TextField { + id: titleTextField + text: qsTr("Choose a file") + } + } + } + + GroupBox { + title: qsTr("FileDialog properties") + + Layout.fillWidth: true + + GridLayout { + columns: 2 + anchors.fill: parent + + Label { + text: qsTr("acceptLabel") + + Layout.minimumWidth: ApplicationWindow.window.width * 0.2 + Layout.maximumWidth: ApplicationWindow.window.width * 0.2 + } + TextField { + id: acceptLabelTextField + text: qsTr("OK") + } + + Label { + text: qsTr("currentFile") + } + TextField { + id: currentFileTextField + text: fileDialog.currentFile + readOnly: true + selectByMouse: true + + Layout.fillWidth: true + } + + Label { + text: qsTr("currentFolder") + } + TextField { + id: currentFolderTextField + text: fileDialog.currentFolder + readOnly: true + selectByMouse: true + + Layout.fillWidth: true + } + + Label { + text: qsTr("currentFiles") + + Layout.alignment: Qt.AlignTop + } + StringListView { + id: currentFilesListView + // QTBUG-72906 + model: [].concat(fileDialog.currentFiles) + } + + Label { + text: qsTr("options") + + Layout.alignment: Qt.AlignTop + } + ColumnLayout { + id: fileOptionsColumnLayout + + CheckBox { + id: dontResolveSymlinksCheckBox + text: qsTr("DontResolveSymlinks") + + readonly property int fileOption: checked ? FileDialog.DontResolveSymlinks : 0 + } + CheckBox { + id: dontConfirmOverwriteCheckBox + text: qsTr("DontConfirmOverwrite") + + readonly property int fileOption: checked ? FileDialog.DontConfirmOverwrite : 0 + } + CheckBox { + id: readOnlyCheckBox + text: qsTr("ReadOnly") + + readonly property int fileOption: checked ? FileDialog.ReadOnly : 0 + } + CheckBox { + id: hideNameFilterDetailsCheckBox + text: qsTr("HideNameFilterDetails") + + readonly property int fileOption: checked ? FileDialog.HideNameFilterDetails : 0 + } + } + + Label { + text: qsTr("fileMode") + + Layout.alignment: Qt.AlignTop + } + ButtonGroup { + id: fileModeButtonGroup + buttons: fileModeColumnLayout.children + } + ColumnLayout { + id: fileModeColumnLayout + + RadioButton { + text: qsTr("OpenFile") + + readonly property int fileMode: FileDialog.OpenFile + } + RadioButton { + text: qsTr("OpenFiles") + checked: true + + readonly property int fileMode: FileDialog.OpenFiles + } + RadioButton { + text: qsTr("SaveFile") + + readonly property int fileMode: FileDialog.SaveFile + } + } + + Label { + text: qsTr("nameFilters") + } + TextField { + id: nameFiltersTextField + text: ["Text files (*.txt)", "HTML files (*.html), Images (*.jpg *.png *.svg)"].join(",") + + Layout.fillWidth: true + + ToolTip.text: qsTr("For this example, a comma-separated string") + ToolTip.visible: hovered + ToolTip.delay: Theme.toolTipDelay + } + + Label { + text: qsTr("rejectLabel") + } + TextField { + id: rejectLabelTextField + text: qsTr("Cancel") + } + + Label { + text: qsTr("selectedFile") + } + TextField { + id: selectedFileTextField + text: fileDialog.selectedFile + readOnly: true + selectByMouse: true + + Layout.fillWidth: true + } + + Label { + text: qsTr("selectedFiles") + + Layout.alignment: Qt.AlignTop + } + StringListView { + id: selectedFilesListView + // QTBUG-72906 + model: [].concat(fileDialog.selectedFiles) + } + + Label { + text: qsTr("selectedNameFilter.name") + } + TextField { + id: selectedNameFilterNameTextField + text: fileDialog.selectedNameFilter.name + readOnly: true + selectByMouse: true + + Layout.fillWidth: true + } + + Label { + text: qsTr("selectedNameFilter.globs") + + Layout.alignment: Qt.AlignTop + } + StringListView { + id: selectedNameFilterGlobsListView + // QTBUG-72906 + model: [].concat(fileDialog.selectedNameFilter.globs) + } + + Label { + text: qsTr("selectedNameFilter.index") + } + TextField { + id: selectedNameFilterIndexTextField + text: fileDialog.selectedNameFilter.index + readOnly: true + selectByMouse: true + + Layout.fillWidth: true + } + + Label { + text: qsTr("selectedNameFilter.extensions") + + Layout.alignment: Qt.AlignTop + } + StringListView { + id: selectedNameFilterExtensionsListView + // QTBUG-72906 + model: [].concat(fileDialog.selectedNameFilter.extensions) + } + } + } + + FileDialog { + id: fileDialog + + modality: modalityButtonGroup.checkedButton.modality + title: titleTextField.text + + acceptLabel: acceptLabelTextField.text + fileMode: fileModeButtonGroup.checkedButton.fileMode + options: dontResolveSymlinksCheckBox.fileOption + | dontConfirmOverwriteCheckBox.fileOption + | readOnlyCheckBox.fileOption + | hideNameFilterDetailsCheckBox.fileOption + nameFilters: nameFiltersTextField.text.split(",") + rejectLabel: rejectLabelTextField.text + } + } +} diff --git a/tests/manual/quickdialogs/dialogs/FolderDialogPage.qml b/tests/manual/quickdialogs/dialogs/FolderDialogPage.qml new file mode 100644 index 00000000000..3f405bae481 --- /dev/null +++ b/tests/manual/quickdialogs/dialogs/FolderDialogPage.qml @@ -0,0 +1,215 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs +import QtQuick.Layouts + +import "." + +ColumnLayout { + property alias dialog: folderDialog + + // Put it all in another ColumnLayout so we can easily add margins. + ColumnLayout { + Layout.leftMargin: 12 + Layout.rightMargin: 12 + Layout.topMargin: 12 + Layout.bottomMargin: 12 + + GroupBox { + title: qsTr("Dialog properties") + + Layout.fillWidth: true + + GridLayout { + columns: 2 + anchors.fill: parent + + Label { + text: qsTr("modality") + + Layout.alignment: Qt.AlignTop + Layout.minimumWidth: ApplicationWindow.window.width * 0.2 + Layout.maximumWidth: ApplicationWindow.window.width * 0.2 + } + ButtonGroup { + id: modalityButtonGroup + buttons: modalityColumnLayout.children + } + ColumnLayout { + id: modalityColumnLayout + + RadioButton { + text: qsTr("Qt.NonModal") + + readonly property int modality: Qt.NonModal + } + RadioButton { + text: qsTr("Qt.WindowModal") + checked: true + + readonly property int modality: Qt.WindowModal + } + RadioButton { + text: qsTr("Qt.ApplicationModal") + + readonly property int modality: Qt.ApplicationModal + } + } + + Label { + text: qsTr("result") + } + TextField { + id: resultTextField + text: folderDialog.result === 1 ? qsTr("Accepted") : qsTr("Rejected") + readOnly: true + enabled: false + } + + Label { + text: qsTr("title") + } + TextField { + id: titleTextField + text: qsTr("Choose a folder") + } + } + } + + GroupBox { + title: qsTr("FolderDialog properties") + + Layout.fillWidth: true + + GridLayout { + columns: 2 + anchors.fill: parent + + Label { + text: qsTr("acceptLabel") + + Layout.minimumWidth: ApplicationWindow.window.width * 0.2 + Layout.maximumWidth: ApplicationWindow.window.width * 0.2 + } + TextField { + id: acceptLabelTextField + text: qsTr("OK") + } + + Label { + text: qsTr("currentFolder") + } + TextField { + id: currentFolderTextField + text: folderDialog.currentFolder + readOnly: true + selectByMouse: true + + Layout.fillWidth: true + } + + Label { + text: qsTr("options") + + Layout.alignment: Qt.AlignTop + } + ColumnLayout { + id: folderOptionsColumnLayout + + CheckBox { + id: dontResolveSymlinksCheckBox + text: qsTr("DontResolveSymlinks") + + readonly property int folderOption: checked ? FolderDialog.DontResolveSymlinks : 0 + } + CheckBox { + id: readOnlyCheckBox + text: qsTr("ReadOnly") + + readonly property int folderOption: checked ? FolderDialog.ReadOnly : 0 + } + } + + Label { + text: qsTr("rejectLabel") + } + TextField { + id: rejectLabelTextField + text: qsTr("Cancel") + } + + Label { + text: qsTr("selectedFolder") + } + TextField { + text: folderDialog.selectedFolder + readOnly: true + selectByMouse: true + + Layout.fillWidth: true + } + } + } + + FolderDialog { + id: folderDialog + + modality: modalityButtonGroup.checkedButton.modality + title: titleTextField.text + + acceptLabel: acceptLabelTextField.text + options: dontResolveSymlinksCheckBox.folderOption | readOnlyCheckBox.folderOption + rejectLabel: rejectLabelTextField.text + } + } +} diff --git a/tests/manual/quickdialogs/dialogs/FontDialogPage.qml b/tests/manual/quickdialogs/dialogs/FontDialogPage.qml new file mode 100644 index 00000000000..d79fe9e4412 --- /dev/null +++ b/tests/manual/quickdialogs/dialogs/FontDialogPage.qml @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs +import QtQuick.Layouts + +import "." + +ColumnLayout { + property alias dialog: fontDialog + + // Put it all in another ColumnLayout so we can easily add margins. + ColumnLayout { + Layout.leftMargin: 12 + Layout.rightMargin: 12 + Layout.topMargin: 12 + Layout.bottomMargin: 12 + + GroupBox { + title: qsTr("Dialog properties") + + Layout.fillWidth: true + + GridLayout { + columns: 2 + anchors.fill: parent + + Label { + text: qsTr("modality") + + Layout.alignment: Qt.AlignTop + Layout.minimumWidth: ApplicationWindow.window.width * 0.2 + Layout.maximumWidth: ApplicationWindow.window.width * 0.2 + } + ButtonGroup { + id: modalityButtonGroup + buttons: modalityColumnLayout.children + } + ColumnLayout { + id: modalityColumnLayout + + RadioButton { + text: qsTr("Qt.NonModal") + + readonly property int modality: Qt.NonModal + } + RadioButton { + text: qsTr("Qt.WindowModal") + checked: true + + readonly property int modality: Qt.WindowModal + } + RadioButton { + text: qsTr("Qt.ApplicationModal") + + readonly property int modality: Qt.ApplicationModal + } + } + + Label { + text: qsTr("result") + } + TextField { + id: resultTextField + text: fontDialog.result === 1 ? qsTr("Accepted") : qsTr("Rejected") + readOnly: true + enabled: false + } + + Label { + text: qsTr("title") + } + TextField { + id: titleTextField + text: qsTr("Pick a font") + } + } + } + + GroupBox { + title: qsTr("FontDialog properties") + + Layout.fillWidth: true + + GridLayout { + columns: 2 + anchors.fill: parent + + Label { + Layout.minimumWidth: ApplicationWindow.window.width * 0.2 + Layout.maximumWidth: ApplicationWindow.window.width * 0.2 + text: qsTr("currentFont") + } + TextField { + id: currentFontTextField + text: qsTr("AaBbYyZz") + font: fontDialog.currentFont + readOnly: true + selectByMouse: true + + Layout.fillWidth: true + } + + Label { + text: qsTr("selectedFont") + } + TextField { + id: selectedFontTextField + text: qsTr("AaBbYyZz") + font: fontDialog.selectedFont + readOnly: true + selectByMouse: true + + Layout.fillWidth: true + } + + Label { + text: qsTr("fontOptions") + + Layout.alignment: Qt.AlignTop + } + ColumnLayout { + id: fontOptionsColumnLayout + + CheckBox { + id: noButtons + text: qsTr("NoButtons") + + readonly property int fontOption: checked ? FontDialog.NoButtons : 0 + } + CheckBox { + id: scalableFonts + text: qsTr("ScalableFonts") + + readonly property int fontOption: checked ? FontDialog.ScalableFonts : 0 + } + CheckBox { + id: nonScalableFonts + text: qsTr("NonScalableFonts") + + readonly property int fontOption: checked ? FontDialog.NonScalableFonts : 0 + } + CheckBox { + id: monospacedFonts + text: qsTr("MonospacedFonts") + + readonly property int fontOption: checked ? FontDialog.MonospacedFonts : 0 + } + CheckBox { + id: proportionalFonts + text: qsTr("ProportionalFonts") + + readonly property int fontOption: checked ? FontDialog.ProportionalFonts : 0 + } + } + } + } + + FontDialog { + id: fontDialog + + modality: modalityButtonGroup.checkedButton.modality + title: titleTextField.text + options: noButtons.fontOption + | scalableFonts.fontOption + | nonScalableFonts.fontOption + | monospacedFonts.fontOption + | proportionalFonts.fontOption + } + } +} diff --git a/tests/manual/quickdialogs/dialogs/MessageDialogPage.qml b/tests/manual/quickdialogs/dialogs/MessageDialogPage.qml new file mode 100644 index 00000000000..7e66ed770e5 --- /dev/null +++ b/tests/manual/quickdialogs/dialogs/MessageDialogPage.qml @@ -0,0 +1,339 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs +import QtQuick.Layouts + +ColumnLayout { + property alias dialog: messageBox + + // Put it all in another ColumnLayout so we can easily add margins. + ColumnLayout { + Layout.leftMargin: 12 + Layout.rightMargin: 12 + Layout.topMargin: 12 + Layout.bottomMargin: 12 + + GroupBox { + title: qsTr("Dialog properties") + + Layout.fillWidth: true + + GridLayout { + columns: 2 + anchors.fill: parent + + Label { + text: qsTr("modality") + + Layout.alignment: Qt.AlignTop + Layout.minimumWidth: ApplicationWindow.window.width * 0.2 + Layout.maximumWidth: ApplicationWindow.window.width * 0.2 + } + ButtonGroup { + id: modalityButtonGroup + buttons: modalityColumnLayout.children + } + ColumnLayout { + id: modalityColumnLayout + + RadioButton { + text: qsTr("Qt.NonModal") + + readonly property int modality: Qt.NonModal + } + RadioButton { + text: qsTr("Qt.WindowModal") + checked: true + + readonly property int modality: Qt.WindowModal + } + RadioButton { + text: qsTr("Qt.ApplicationModal") + + readonly property int modality: Qt.ApplicationModal + } + } + + Label { + text: qsTr("result") + } + TextField { + id: resultTextField + text: messageBox.result === 1 ? qsTr("Accepted") : qsTr("Rejected") + readOnly: true + enabled: false + } + + Label { + text: qsTr("title") + } + TextField { + id: titleTextField + text: qsTr("Hello World") + } + } + } + + GroupBox { + title: qsTr("MessageBox properties") + + Layout.fillWidth: true + + ColumnLayout { + RowLayout { + Label { + text: qsTr("text") + } + TextField { + id: textProperty + text: qsTr("default text") + } + } + RowLayout { + Label { + text: qsTr("informativeText") + } + TextField { + id: informativeTextProperty + text: qsTr("default informative text") + } + } + + RowLayout { + Label { + text: qsTr("detailedText") + } + TextArea { + id: detailedTextProperty + background: Rectangle { + width: detailedTextProperty.width + height: detailedTextProperty.height + color: "white" + border.color: "black" + border.width: 1 + } + Layout.maximumWidth: ApplicationWindow.window.width * 0.5 + wrapMode: TextEdit.WordWrap + text: qsTr("This text will be displayed in the 'detailed text' textArea, which the user must press a button to see.\n" + + "If this is an empty string, the button will not be visible.") + } + } + + CheckBox { + id: okCheckbox + text: qsTr("Ok") + + readonly property int value: checked ? MessageDialog.Ok : MessageDialog.NoButton + } + CheckBox { + id: saveCheckbox + text: qsTr("Save") + + readonly property int value: checked ? MessageDialog.Save : MessageDialog.NoButton + } + CheckBox { + id: saveAllCheckbox + text: qsTr("Save All") + + readonly property int value: checked ? MessageDialog.SaveAll : MessageDialog.NoButton + } + CheckBox { + id: openCheckbox + text: qsTr("Open") + + readonly property int value: checked ? MessageDialog.Open : MessageDialog.NoButton + } + CheckBox { + id: yesCheckbox + text: qsTr("Yes") + + readonly property int value: checked ? MessageDialog.Yes : MessageDialog.NoButton + } + CheckBox { + id: yesToAllCheckbox + text: qsTr("Yes to all") + + readonly property int value: checked ? MessageDialog.YesToAll : MessageDialog.NoButton + } + CheckBox { + id: noCheckbox + text: qsTr("No") + + readonly property int value: checked ? MessageDialog.No : MessageDialog.NoButton + } + CheckBox { + id: noToAllCheckbox + text: qsTr("No to all") + + readonly property int value: checked ? MessageDialog.NoToAll : MessageDialog.NoButton + } + CheckBox { + id: abortCheckbox + text: qsTr("Abort") + + readonly property int value: checked ? MessageDialog.Abort : MessageDialog.NoButton + } + CheckBox { + id: retryCheckbox + text: qsTr("Retry") + + readonly property int value: checked ? MessageDialog.Retry : MessageDialog.NoButton + } + CheckBox { + id: ignoreCheckbox + text: qsTr("Ignore") + + readonly property int value: checked ? MessageDialog.Ignore : MessageDialog.NoButton + } + CheckBox { + id: closeCheckbox + text: qsTr("Close") + + readonly property int value: checked ? MessageDialog.Close : MessageDialog.NoButton + } + CheckBox { + id: cancelCheckbox + text: qsTr("Cancel") + + readonly property int value: checked ? MessageDialog.Cancel : MessageDialog.NoButton + } + CheckBox { + id: discardCheckbox + text: qsTr("Discard") + + readonly property int value: checked ? MessageDialog.Discard : MessageDialog.NoButton + } + CheckBox { + id: helpCheckbox + text: qsTr("Help") + + readonly property int value: checked ? MessageDialog.Help : MessageDialog.NoButton + } + CheckBox { + id: applyCheckbox + text: qsTr("Apply") + + readonly property int value: checked ? MessageDialog.Apply : MessageDialog.NoButton + } + CheckBox { + id: resetCheckbox + text: qsTr("Reset") + + readonly property int value: checked ? MessageDialog.Reset : MessageDialog.NoButton + } + } + } + + MessageDialog { + id: messageBox + buttons: okCheckbox.value | + saveCheckbox.value | + saveAllCheckbox.value | + openCheckbox.value | + yesCheckbox.value | + yesToAllCheckbox.value | + noCheckbox.value | + noToAllCheckbox.value | + abortCheckbox.value | + retryCheckbox.value | + ignoreCheckbox.value | + closeCheckbox.value | + cancelCheckbox.value | + discardCheckbox.value | + helpCheckbox.value | + applyCheckbox.value | + resetCheckbox.value + modality: modalityButtonGroup.checkedButton.modality + title: titleTextField.text + text: textProperty.text + informativeText: informativeTextProperty.text + detailedText: detailedTextProperty.text + onButtonClicked: function(button, role) { + if (button & MessageDialog.Ok) + console.log("Ok pressed") + else if (button & MessageDialog.Save) + console.log("Save pressed") + else if (button & MessageDialog.SaveAll) + console.log("Save to all pressed") + else if (button & MessageDialog.Open) + console.log("Open pressed") + else if (button & MessageDialog.Yes) + console.log("Yes pressed") + else if (button & MessageDialog.YesToAll) + console.log("Yes to all pressed") + else if (button & MessageDialog.No) + console.log("No pressed") + else if (button & MessageDialog.NoToAll) + console.log("No to all pressed") + else if (button & MessageDialog.Abort) + console.log("Abort pressed") + else if (button & MessageDialog.Retry) + console.log("Retry pressed") + else if (button & MessageDialog.Ignore) + console.log("Ignore pressed") + else if (button & MessageDialog.Close) + console.log("Close pressed") + else if (button & MessageDialog.Cancel) + console.log("Cancel pressed") + else if (button & MessageDialog.Discard) + console.log("Discard pressed") + else if (button & MessageDialog.Help) + console.log("Help pressed") + else if (button & MessageDialog.Apply) + console.log("Apply pressed") + else if (button & MessageDialog.Reset) + console.log("Rest pressed") + } + } + } +} diff --git a/tests/manual/quickdialogs/dialogs/StringListView.qml b/tests/manual/quickdialogs/dialogs/StringListView.qml new file mode 100644 index 00000000000..4a229404fc0 --- /dev/null +++ b/tests/manual/quickdialogs/dialogs/StringListView.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import "." + +ListView { + id: root + clip: true + boundsBehavior: Flickable.StopAtBounds + + Layout.fillWidth: true + Layout.preferredHeight: count > 0 ? 128 : noneLabel.implicitHeight + + ScrollBar.vertical: ScrollBar {} + + delegate: TextField { + width: root.width + text: modelData + readOnly: true + selectByMouse: true + } + + Label { + id: noneLabel + text: qsTr("(None)") + visible: root.count === 0 + } +} diff --git a/tests/manual/quickdialogs/dialogs/Theme.qml b/tests/manual/quickdialogs/dialogs/Theme.qml new file mode 100644 index 00000000000..8114f14eb19 --- /dev/null +++ b/tests/manual/quickdialogs/dialogs/Theme.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +pragma Singleton + +import QtQml + +QtObject { + readonly property int toolTipDelay: 1000 +} diff --git a/tests/manual/quickdialogs/dialogs/dialogs.cpp b/tests/manual/quickdialogs/dialogs/dialogs.cpp new file mode 100644 index 00000000000..8bab70e26dd --- /dev/null +++ b/tests/manual/quickdialogs/dialogs/dialogs.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qsettings.h> +#include <QtGui/qguiapplication.h> +#include <QtQml/qqmlapplicationengine.h> +#include <QtQuickControls2/qquickstyle.h> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QCoreApplication::setApplicationName("dialogs-manual-test"); + QCoreApplication::setOrganizationName("QtProject"); + + // Use native dialogs by default unless the user asked us not to. + QSettings settings; + const QVariant useNativeDialogs = settings.value("useNativeDialogs"); + if (useNativeDialogs.isValid()) { + if (!useNativeDialogs.toBool()) + QCoreApplication::setAttribute(Qt::AA_DontUseNativeDialogs); + } else { + // Set the default here so that we can use an alias in QML. + // Without this it defaults to CheckBox's checked default value, which is false. + settings.setValue("useNativeDialogs", true); + } + + QQmlApplicationEngine engine; + engine.setInitialProperties({{ "style", QQuickStyle::name() }}); + engine.load(QUrl(QStringLiteral("qrc:/dialogs.qml"))); + + return app.exec(); +} diff --git a/tests/manual/quickdialogs/dialogs/dialogs.pro b/tests/manual/quickdialogs/dialogs/dialogs.pro new file mode 100644 index 00000000000..abf80c5660c --- /dev/null +++ b/tests/manual/quickdialogs/dialogs/dialogs.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = dialogs +QT += qml quickcontrols2 + +SOURCES += dialogs.cpp +RESOURCES += \ + dialogs.qml \ + FileDialogPage.qml \ + FolderDialogPage.qml \ + FontDialogPage.qml \ + MessageBoxPage.qml \ + StringListView.qml \ + qmldir \ + Theme.qml diff --git a/tests/manual/quickdialogs/dialogs/dialogs.qml b/tests/manual/quickdialogs/dialogs/dialogs.qml new file mode 100644 index 00000000000..00655a1752a --- /dev/null +++ b/tests/manual/quickdialogs/dialogs/dialogs.qml @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import Qt.labs.settings + +ApplicationWindow { + id: window + width: 800 + height: 600 + title: "dialogs - style: " + style + visible: true + + required property string style + + Component.onCompleted: { + x = Screen.width / 2 - width / 2 + y = Screen.height / 2 - height / 2 + } + + Settings { + id: settings + + property alias useNativeDialogs: useNativeDialogsCheckBox.checked + property alias lastTabBarIndex: tabBar.currentIndex + } + + Page { + anchors.fill: parent + + header: TabBar { + id: tabBar + + TabButton { + text: qsTr("FileDialog") + } + TabButton { + text: qsTr("FolderDialog") + } + TabButton { + text: qsTr("FontDialog") + } + TabButton { + text: qsTr("MessageBox") + } + } + + ScrollView { + id: scrollView + anchors.fill: parent + clip: true + + StackLayout { + id: stackLayout + currentIndex: tabBar.currentIndex + width: scrollView.width + + FileDialogPage {} + FolderDialogPage {} + FontDialogPage {} + MessageDialogPage {} + } + } + } + + footer: ToolBar { + leftPadding: 12 + rightPadding: 12 + + RowLayout { + anchors.fill: parent + + CheckBox { + id: useNativeDialogsCheckBox + text: qsTr("Use Native Dialogs (requires restart)") + checked: settings.useNativeDialogs + } + + Item { + Layout.fillWidth: true + } + + Button { + text: qsTr("Open") + + onClicked: stackLayout.children[stackLayout.currentIndex].dialog.open() + } + } + } +} diff --git a/tests/manual/quickdialogs/dialogs/qmldir b/tests/manual/quickdialogs/dialogs/qmldir new file mode 100644 index 00000000000..4f4a6b7bf9c --- /dev/null +++ b/tests/manual/quickdialogs/dialogs/qmldir @@ -0,0 +1,3 @@ +module org.qtproject.examples.dialogs + +singleton Theme 1.0 Theme.qml diff --git a/tests/manual/scenegraph_lancelot/scenegrabber/CMakeLists.txt b/tests/manual/scenegraph_lancelot/scenegrabber/CMakeLists.txt deleted file mode 100644 index 0514b6660ed..00000000000 --- a/tests/manual/scenegraph_lancelot/scenegrabber/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -##################################################################### -## qmlscenegrabber Binary: -##################################################################### - -qt_internal_add_manual_test(qmlscenegrabber - OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.." # special case - SOURCES - main.cpp - PUBLIC_LIBRARIES - Qt::Gui - Qt::Quick -) - -qt6_add_shaders(qmlscenegrabber "qmlscenegrabber_shaders" - BATCHABLE - PREFIX - "shaders" - FILES - "../data/shared/shaders/basic_alpha.frag" - "../data/shared/shaders/basic.frag" - "../data/shared/shaders/cmyk.frag" - "../data/shared/shaders/culling.frag" - "../data/shared/shaders/desaturate.frag" - "../data/shared/shaders/edge.frag" - "../data/shared/shaders/gradient2.frag" - "../data/shared/shaders/gradient3.frag" - "../data/shared/shaders/gradient4.frag" - "../data/shared/shaders/gradient5.frag" - "../data/shared/shaders/gradient.frag" - "../data/shared/shaders/gradientgrid.frag" - "../data/shared/shaders/property.frag" - "../data/shared/shaders/shadow.frag" - "../data/shared/shaders/stencil.frag" - "../data/shared/shaders/subrect.vert" - "../data/shared/shaders/wave.vert" -) diff --git a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp deleted file mode 100644 index 55dc86b9fd5..00000000000 --- a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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/QTimer> -#include <QtCore/QDebug> -#include <QtCore/QFileInfo> -#include <QtCore/QHashFunctions> -#include <QtGui/QGuiApplication> -#include <QtGui/QImage> - -#include <QtQuick/QQuickView> -#include <QtQuick/QQuickItem> - -#ifdef Q_OS_WIN -# include <fcntl.h> -# include <io.h> -#endif // Q_OS_WIN - -// Timeout values: - -// A valid screen grab requires the scene to not change -// for SCENE_STABLE_TIME ms -#define SCENE_STABLE_TIME 200 - -// Give up after SCENE_TIMEOUT ms -#define SCENE_TIMEOUT 6000 - -//#define GRABBERDEBUG - -class GrabbingView : public QQuickView -{ - Q_OBJECT - -public: - GrabbingView(const QString &outputFile) - : ofile(outputFile), grabNo(0), isGrabbing(false), initDone(false), justShow(outputFile.isEmpty()) - { - if (justShow) - return; - grabTimer = new QTimer(this); - grabTimer->setSingleShot(true); - grabTimer->setInterval(SCENE_STABLE_TIME); - connect(grabTimer, SIGNAL(timeout()), SLOT(grab())); - - connect(this, SIGNAL(afterRendering()), SLOT(startGrabbing())); - - QTimer::singleShot(SCENE_TIMEOUT, this, SLOT(timedOut())); - } - -private slots: - void startGrabbing() - { - if (!initDone) { - initDone = true; - grabTimer->start(); - } - } - - void grab() - { - if (isGrabbing) - return; - isGrabbing = true; - grabNo++; -#ifdef GRABBERDEBUG - printf("grab no. %i\n", grabNo); -#endif - QImage img = grabWindow(); - if (!img.isNull() && img == lastGrab) { - sceneStabilized(); - } else { - lastGrab = img; - grabTimer->start(); - } - - isGrabbing = false; - } - - void sceneStabilized() - { -#ifdef GRABBERDEBUG - printf("...sceneStabilized IN\n"); -#endif - if (ofile == "-") { // Write to stdout - QFile of; -#ifdef Q_OS_WIN - // Make sure write to stdout doesn't do LF->CRLF - _setmode(_fileno(stdout), _O_BINARY); -#endif // Q_OS_WIN - if (!of.open(1, QIODevice::WriteOnly) || !lastGrab.save(&of, "ppm")) { - qWarning() << "Error: failed to write grabbed image to stdout."; - QGuiApplication::exit(2); - return; - } - } else { - if (!lastGrab.save(ofile)) { - qWarning() << "Error: failed to store grabbed image to" << ofile; - QGuiApplication::exit(2); - return; - } - } - QGuiApplication::exit(0); -#ifdef GRABBERDEBUG - printf("...sceneStabilized OUT\n"); -#endif - } - - void timedOut() - { - qWarning() << "Error: timed out waiting for scene to stabilize." << grabNo << "grab(s) done. Last grab was" << (lastGrab.isNull() ? "invalid." : "valid."); - QGuiApplication::exit(3); - } - -private: - QImage lastGrab; - QTimer *grabTimer = nullptr; - QString ofile; - int grabNo; - bool isGrabbing; - bool initDone; - bool justShow; -}; - - -int main(int argc, char *argv[]) -{ - qSetGlobalQHashSeed(0); - - QGuiApplication a(argc, argv); - - // Parse command line - QString ifile, ofile; - bool noText = false; - bool justShow = false; - QStringList args = a.arguments(); - int i = 0; - bool argError = false; - while (++i < args.size()) { - QString arg = args.at(i); - if ((arg == "-o") && (i < args.size()-1)) { - ofile = args.at(++i); - } - else if (arg == "-notext") { - noText = true; - } - else if (arg == "--cache-distance-fields") { - ; - } - else if (arg == "-viewonly") { - justShow = true; - } - else if (ifile.isEmpty()) { - ifile = arg; - } - else { - argError = true; - break; - } - } - if (argError || ifile.isEmpty() || (ofile.isEmpty() && !justShow)) { - qWarning() << "Usage:" << args.at(0).toLatin1().constData() << "[-notext] <qml-infile> {-o <outfile or - for ppm on stdout>|-viewonly}"; - return 1; - } - - QFileInfo ifi(ifile); - if (!ifi.exists() || !ifi.isReadable() || !ifi.isFile()) { - qWarning() << args.at(0).toLatin1().constData() << " error: unreadable input file" << ifile; - return 1; - } - // End parsing - - GrabbingView v(ofile); - v.setSource(QUrl::fromLocalFile(ifile)); - - if (noText) { - const QList<QQuickItem*> items = v.rootObject()->findChildren<QQuickItem*>(); - for (QQuickItem *item : items) { - if (QByteArray(item->metaObject()->className()).contains("Text")) - item->setVisible(false); - } - } - - v.show(); - - int retVal = a.exec(); -#ifdef GRABBERDEBUG - printf("...retVal=%i\n", retVal); -#endif - - return retVal; -} - -#include "main.moc" diff --git a/tests/manual/scenegraph_lancelot/scenegraph/CMakeLists.txt b/tests/manual/scenegraph_lancelot/scenegraph/CMakeLists.txt deleted file mode 100644 index 6127adf349e..00000000000 --- a/tests/manual/scenegraph_lancelot/scenegraph/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Generated from scenegraph.pro. - -##################################################################### -## tst_scenegraph Test: -##################################################################### - -# Collect test data -list(APPEND test_data "../data") - -qt_internal_add_test(tst_scenegraph_manual # special case - OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.." # special case - SOURCES - ../../../../../qtbase/tests/baselineserver/shared/baselineprotocol.cpp ../../../../../qtbase/tests/baselineserver/shared/baselineprotocol.h - ../../../../../qtbase/tests/baselineserver/shared/lookup3.cpp - ../../../../../qtbase/tests/baselineserver/shared/qbaselinetest.cpp ../../../../../qtbase/tests/baselineserver/shared/qbaselinetest.h - tst_scenegraph.cpp - DEFINES - QMAKESPEC=\\\"\\\" - INCLUDE_DIRECTORIES - ../../../../../qtbase/tests/baselineserver/shared - PUBLIC_LIBRARIES - Qt::Gui - Qt::Network - TESTDATA ${test_data} -) - -## Scopes: -##################################################################### - -#### Keys ignored in scope 3:.:.:scenegraph.pro:WIN32: -# TEST_HELPER_INSTALLS = ".././qmlscenegrabber.exe" - -#### Keys ignored in scope 6:.:.:scenegraph.pro:else: -# TEST_HELPER_INSTALLS = ".././qmlscenegrabber" diff --git a/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp b/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp deleted file mode 100644 index 2c28b5c9145..00000000000 --- a/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp +++ /dev/null @@ -1,298 +0,0 @@ - -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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 <qbaselinetest.h> - -#include <QtCore/QCoreApplication> -#include <QtCore/QDirIterator> -#include <QtCore/QDebug> -#include <QtCore/QProcess> -#include <QtGui/QImage> - -#include <algorithm> - -QString blockify(const QByteArray& s) -{ - const char* indent = "\n | "; - QByteArray block = s.trimmed(); - block.replace('\n', indent); - block.prepend(indent); - block.append('\n'); - return block; -} - -//#define TEXTLESS_TEST - -class tst_Scenegraph : public QObject -{ - Q_OBJECT - -public: - tst_Scenegraph(); - -private Q_SLOTS: - void initTestCase(); - void cleanup(); -#ifdef TEXTLESS_TEST - void testNoTextRendering_data(); - void testNoTextRendering(); -#endif - void testRendering_data(); - void testRendering(); - -private: - void setupTestSuite(const QByteArray& filter = QByteArray()); - void runTest(const QStringList& extraArgs = QStringList()); - bool renderAndGrab(const QString& qmlFile, const QStringList& extraArgs, QImage *screenshot, QString *errMsg); - quint16 checksumFileOrDir(const QString &path); - - QString testSuitePath; - QString grabberPath; - int consecutiveErrors; // Not test failures (image mismatches), but system failures (so no image at all) - bool aborted; // This run given up because of too many system failures - bool usingRhi; -}; - - -tst_Scenegraph::tst_Scenegraph() - : consecutiveErrors(0), aborted(false) -{ -} - - -void tst_Scenegraph::initTestCase() -{ - QString dataDir = QFINDTESTDATA("../data/."); - if (dataDir.isEmpty()) - dataDir = QStringLiteral("data"); - QFileInfo fi(dataDir); - if (!fi.exists() || !fi.isDir() || !fi.isReadable()) - QSKIP("Test suite data directory missing or unreadable: " + fi.canonicalFilePath().toLatin1()); - testSuitePath = fi.canonicalFilePath(); - -#if defined(Q_OS_WIN) - grabberPath = QFINDTESTDATA("qmlscenegrabber.exe"); -#elif defined(Q_OS_DARWIN) - grabberPath = QFINDTESTDATA("qmlscenegrabber.app/Contents/MacOS/qmlscenegrabber"); -#else - grabberPath = QFINDTESTDATA("qmlscenegrabber"); -#endif - if (grabberPath.isEmpty()) - grabberPath = QCoreApplication::applicationDirPath() + "/qmlscenegrabber"; - - const char *backendVarName = "QT_QUICK_BACKEND"; - const QString backend = qEnvironmentVariable(backendVarName, QString::fromLatin1("default")); - QBaselineTest::addClientProperty(QString::fromLatin1(backendVarName), backend); - - QString stack = backend; - if (stack != QLatin1String("software")) { -#if defined(Q_OS_WIN) - const char *defaultRhiBackend = "d3d11"; -#elif defined(Q_OS_DARWIN) - const char *defaultRhiBackend = "metal"; -#else - const char *defaultRhiBackend = "opengl"; -#endif - const QString rhiBackend = qEnvironmentVariable("QSG_RHI_BACKEND", QString::fromLatin1(defaultRhiBackend)); - stack = QString::fromLatin1("RHI_%1").arg(rhiBackend); - } - QBaselineTest::addClientProperty(QString::fromLatin1("GraphicsStack"), stack); - - QByteArray msg; - if (!QBaselineTest::connectToBaselineServer(&msg)) - QSKIP(msg); -} - - -void tst_Scenegraph::cleanup() -{ - // Allow subsystems time to settle - if (!aborted) - QTest::qWait(20); -} - -#ifdef TEXTLESS_TEST -void tst_Scenegraph::testNoTextRendering_data() -{ - setupTestSuite("text/"); - consecutiveErrors = 0; - aborted = false; -} - - -void tst_Scenegraph::testNoTextRendering() -{ - runTest(QStringList() << "-notext"); -} -#endif - -void tst_Scenegraph::testRendering_data() -{ - setupTestSuite(); - consecutiveErrors = 0; - aborted = false; -} - - -void tst_Scenegraph::testRendering() -{ - runTest(); -} - - -void tst_Scenegraph::setupTestSuite(const QByteArray& filter) -{ - QTest::addColumn<QString>("qmlFile"); - int numItems = 0; - - QStringList ignoreItems; - QFile ignoreFile(testSuitePath + "/Ignore"); - if (ignoreFile.open(QIODevice::ReadOnly)) { - while (!ignoreFile.atEnd()) { - QByteArray line = ignoreFile.readLine().trimmed(); - if (!line.isEmpty() && !line.startsWith('#')) - ignoreItems += line; - } - } - - QStringList itemFiles; - QDirIterator it(testSuitePath, QDirIterator::Subdirectories); - while (it.hasNext()) { - QString fp = it.next(); - if (fp.endsWith(".qml")) { - QString itemName = fp.mid(testSuitePath.length() + 1); - if (!ignoreItems.contains(itemName) && (filter.isEmpty() || !itemName.startsWith(filter))) - itemFiles.append(it.filePath()); - } - } - - std::sort(itemFiles.begin(), itemFiles.end()); - for (const QString &filePath : qAsConst(itemFiles)) { - QByteArray itemName = filePath.mid(testSuitePath.length() + 1).toLatin1(); - QBaselineTest::newRow(itemName, checksumFileOrDir(filePath)) << filePath; - numItems++; - } - - if (!numItems) - QSKIP("No .qml test files found in " + testSuitePath.toLatin1()); -} - - -void tst_Scenegraph::runTest(const QStringList& extraArgs) -{ - // qDebug() << "Rendering" << QTest::currentDataTag(); - - if (aborted) - QSKIP("System too unstable."); - - QFETCH(QString, qmlFile); - - QImage screenShot; - QString errorMessage; - if (renderAndGrab(qmlFile, extraArgs, &screenShot, &errorMessage)) { - consecutiveErrors = 0; - } - else { - if (++consecutiveErrors >= 3) - aborted = true; // Just give up if screen grabbing fails 3 times in a row - QFAIL(qPrintable("QuickView grabbing failed: " + errorMessage)); - } - - QBASELINE_TEST(screenShot); -} - - -bool tst_Scenegraph::renderAndGrab(const QString& qmlFile, const QStringList& extraArgs, QImage *screenshot, QString *errMsg) -{ - bool usePipe = true; // Whether to transport the grabbed image using temp. file or pipe. TBD: cmdline option - QProcess grabber; - grabber.setProcessChannelMode(QProcess::ForwardedErrorChannel); - QStringList args = extraArgs; - QString tmpfile = usePipe ? QString("-") : QString("/tmp/qmlscenegrabber-%1-out.ppm").arg(QCoreApplication::applicationPid()); - args << qmlFile << "-o" << tmpfile; - grabber.start(grabberPath, args, QIODevice::ReadOnly); - grabber.waitForFinished(17000); //### hardcoded, must be larger than the scene timeout in qmlscenegrabber - if (grabber.state() != QProcess::NotRunning) { - grabber.terminate(); - grabber.waitForFinished(3000); - } - QImage img; - bool res = usePipe ? img.load(&grabber, "ppm") : img.load(tmpfile); - if (!res || img.isNull()) { - if (errMsg) { - QString s("Failed to grab screen. qmlscenegrabber exitcode: %1. Process error: %2. Stderr:%3"); - *errMsg = s.arg(grabber.exitCode()).arg(grabber.errorString()).arg(blockify(grabber.readAllStandardError())); - } - if (!usePipe) - QFile::remove(tmpfile); - return false; - } - if (screenshot) - *screenshot = img; - if (!usePipe) - QFile::remove(tmpfile); - return true; -} - - -quint16 tst_Scenegraph::checksumFileOrDir(const QString &path) -{ - QFileInfo fi(path); - if (!fi.exists() || !fi.isReadable()) - return 0; - if (fi.isFile()) { - QFile f(path); - f.open(QIODevice::ReadOnly); - QByteArray contents = f.readAll(); - return qChecksum(contents); - } - if (fi.isDir()) { - static const QStringList nameFilters = QStringList() << "*.qml" << "*.cpp" << "*.png" << "*.jpg"; - quint16 cs = 0; - const auto entryList = QDir(fi.filePath()).entryList(nameFilters, - QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); - for (const QString &item : entryList) - cs ^= checksumFileOrDir(path + QLatin1Char('/') + item); - return cs; - } - return 0; -} - - -#define main _realmain -QTEST_MAIN(tst_Scenegraph) -#undef main - -int main(int argc, char *argv[]) -{ - QBaselineTest::handleCmdLineArgs(&argc, &argv); - return _realmain(argc, argv); -} - -#include "tst_scenegraph.moc" diff --git a/tests/manual/tableview/abstracttablemodel/CMakeLists.txt b/tests/manual/tableview/abstracttablemodel/CMakeLists.txt index 32d3af34bda..615a406aa12 100644 --- a/tests/manual/tableview/abstracttablemodel/CMakeLists.txt +++ b/tests/manual/tableview/abstracttablemodel/CMakeLists.txt @@ -1,5 +1,11 @@ # Generated from abstracttablemodel.pro. +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tableview_abstracttablemodel LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + ##################################################################### ## tableview_abstracttablemodel Binary: ##################################################################### diff --git a/tests/manual/tableview/abstracttablemodel/main.qml b/tests/manual/tableview/abstracttablemodel/main.qml index 9d849f2c8f0..3ee978a9c2c 100644 --- a/tests/manual/tableview/abstracttablemodel/main.qml +++ b/tests/manual/tableview/abstracttablemodel/main.qml @@ -37,13 +37,14 @@ ** ****************************************************************************/ -import QtQuick 2.14 -import QtQuick.Window 2.3 -import QtQml.Models 2.2 -import TestTableModel 0.1 -import QtQuick.Controls 2.5 - -Window { +import QtQuick +import QtQuick.Window +import QtQml.Models +import TestTableModel +import QtQuick.Controls +import Qt.labs.qmlmodels + +ApplicationWindow { id: window width: 640 height: 480 @@ -52,10 +53,8 @@ Window { property int selectedX: -1 property int selectedY: -1 - Rectangle { + Item { anchors.fill: parent - anchors.margins: 10 - color: "darkgray" Column { id: menu @@ -80,6 +79,12 @@ Window { text: "Remove column" onClicked: tableView.model.removeColumns(selectedX, 1) } + SpinBox { + id: spaceSpinBox + from: -100 + to: 100 + value: 0 + } } Row { @@ -111,11 +116,9 @@ Window { } } Button { - text: "inc space" - onClicked: { - tableView.columnSpacing += 1 - tableView.rowSpacing += 1 - } + id: flickingMode + checkable: true + text: checked ? "Flickable" : "Scrollable" } } Text { @@ -148,6 +151,7 @@ Window { columnSpacing: 1 rowSpacing: 1 + syncView: tableView syncDirection: Qt.Horizontal } @@ -176,6 +180,7 @@ Window { columnSpacing: 1 rowSpacing: 1 + syncView: tableView syncDirection: Qt.Vertical } @@ -188,12 +193,16 @@ Window { anchors.bottom: parent.bottom width: 200 clip: true + delegate: tableViewDelegate + columnSpacing: spaceSpinBox.value + rowSpacing: spaceSpinBox.value + interactive: flickingMode.checked + columnWidthProvider: function(c) { if (c > 30) return 100 - else - return 200; } + ScrollBar.horizontal: ScrollBar {} ScrollBar.vertical: ScrollBar {} @@ -201,32 +210,37 @@ Window { rowCount: 200 columnCount: 60 } - delegate: tableViewDelegate - columnSpacing: 1 - rowSpacing: 1 + + selectionModel: ItemSelectionModel { + model: tableView.model + } + } + + SelectionRectangle { + target: tableView } Component { id: tableViewDelegate Rectangle { id: delegate - implicitWidth: 100 - implicitHeight: 50 - color: display + implicitWidth: 50 + implicitHeight: 30 border.width: row === selectedY && column == selectedX ? 2 : 0 border.color: "darkgreen" + color: selected ? "lightgreen" : "white" + required property bool selected + + TapHandler { + onTapped: { + selectedX = column + selectedY = row + } + } Text { - anchors.fill: parent + anchors.centerIn: parent text: column + ", " + row - - MouseArea { - anchors.fill: parent - onClicked: { - selectedX = column - selectedY = row - } - } } } } diff --git a/tests/manual/tableview/listmodel/CMakeLists.txt b/tests/manual/tableview/listmodel/CMakeLists.txt index ce394762377..03def339d1f 100644 --- a/tests/manual/tableview/listmodel/CMakeLists.txt +++ b/tests/manual/tableview/listmodel/CMakeLists.txt @@ -1,5 +1,11 @@ # Generated from listmodel.pro. +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tableview_listmodel LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + ##################################################################### ## tableview_listmodel Binary: ##################################################################### diff --git a/tests/manual/tableview/storagemodel/CMakeLists.txt b/tests/manual/tableview/storagemodel/CMakeLists.txt index 397db3e1f76..2b455f3fb97 100644 --- a/tests/manual/tableview/storagemodel/CMakeLists.txt +++ b/tests/manual/tableview/storagemodel/CMakeLists.txt @@ -1,5 +1,11 @@ # Generated from storagemodel.pro. +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tableview_storage LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + ##################################################################### ## tableview_storage Binary: ##################################################################### diff --git a/tests/manual/tableview/storagemodel/storagemodel.cpp b/tests/manual/tableview/storagemodel/storagemodel.cpp index b43454b2499..f0394db6b8e 100644 --- a/tests/manual/tableview/storagemodel/storagemodel.cpp +++ b/tests/manual/tableview/storagemodel/storagemodel.cpp @@ -64,17 +64,20 @@ StorageModel::StorageModel(QObject *parent) : } QHash<int, QByteArray> StorageModel::roleNames() const { - static auto roles = QHash<int, QByteArray> { - { int(Role::Type), "type" }, - { int(Role::Heading), "heading" }, - { int(Role::Value), "value" }, - { int(Role::ValueMax), "valueMax" }, - { int(Role::ValueDisplay), "valueDisplay" }, - { int(Role::ValueMaxDisplay), "valueMaxDisplay" }, - { Qt::CheckStateRole, "checkState" }, - }; - static auto ret = roles.unite(QAbstractTableModel::roleNames());; - return ret; + static auto roles = [this]() { + auto roles = QHash<int, QByteArray> { + { int(Role::Type), "type" }, + { int(Role::Heading), "heading" }, + { int(Role::Value), "value" }, + { int(Role::ValueMax), "valueMax" }, + { int(Role::ValueDisplay), "valueDisplay" }, + { int(Role::ValueMaxDisplay), "valueMaxDisplay" }, + { Qt::CheckStateRole, "checkState" } + }; + roles.insert(QAbstractTableModel::roleNames()); + return roles; + }(); + return roles; } void StorageModel::refresh() diff --git a/tests/manual/tableview/tablemodel/form/CMakeLists.txt b/tests/manual/tableview/tablemodel/form/CMakeLists.txt index 00bea7bddca..af10a36368c 100644 --- a/tests/manual/tableview/tablemodel/form/CMakeLists.txt +++ b/tests/manual/tableview/tablemodel/form/CMakeLists.txt @@ -1,5 +1,11 @@ # Generated from form.pro. +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(form LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + ##################################################################### ## form Binary: ##################################################################### diff --git a/tests/manual/tableview/tablemodel/json/CMakeLists.txt b/tests/manual/tableview/tablemodel/json/CMakeLists.txt index 86d177d08c8..14ebd47eb68 100644 --- a/tests/manual/tableview/tablemodel/json/CMakeLists.txt +++ b/tests/manual/tableview/tablemodel/json/CMakeLists.txt @@ -1,5 +1,11 @@ # Generated from json.pro. +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(json LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + ##################################################################### ## json Binary: ##################################################################### diff --git a/tests/manual/touch/flicktext.qml b/tests/manual/touch/flicktext.qml index 9e842616871..e69d6207a97 100644 --- a/tests/manual/touch/flicktext.qml +++ b/tests/manual/touch/flicktext.qml @@ -380,6 +380,36 @@ Rectangle { text: "content X " + flick.contentX.toFixed(2) + " Y " + flick.contentY.toFixed(2) } } + + Column { + Row { + spacing: 2 + Examples.Button { + id: decrButton + text: "-" + onClicked: flick.flickDeceleration -= 100 + Timer { + running: decrButton.pressed + interval: 100; repeat: true + onTriggered: flick.flickDeceleration -= 100 + } + } + Text { + horizontalAlignment: Text.AlignHCenter + text: "decel:\n" + flick.flickDeceleration.toFixed(4) + } + Examples.Button { + id: incrButton + text: "+" + onClicked: flick.flickDeceleration += 100 + } + Timer { + running: incrButton.pressed + interval: 100; repeat: true + onTriggered: flick.flickDeceleration += 100 + } + } + } } Component.onCompleted: { diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 01fa0bf0433..0169ce19654 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,12 +1,5 @@ # Generated from tools.pro. - -qt_exclude_tool_directories_from_default_target( - qmlprofiler - qmlplugindump - qmleasing -) - if(QT_FEATURE_qml_devtools) add_subdirectory(qmldom) add_subdirectory(qmllint) @@ -20,20 +13,33 @@ if(QT_FEATURE_qml_devtools AND QT_FEATURE_xmlstreamwriter) # add_subdirectory(qmlcachegen) # special case end endif() -if(QT_FEATURE_thread AND NOT ANDROID AND NOT WASM AND NOT rtems) +if(QT_FEATURE_thread AND NOT ANDROID AND NOT WASM AND NOT IOS AND NOT rtems) add_subdirectory(qml) endif() -if(QT_FEATURE_qml_profiler AND QT_FEATURE_thread AND NOT ANDROID AND NOT WASM AND NOT rtems) +if(QT_FEATURE_qml_profiler + AND QT_FEATURE_thread + AND NOT ANDROID + AND NOT IOS + AND NOT WASM + AND NOT rtems) add_subdirectory(qmlprofiler) endif() -if(QT_FEATURE_qml_preview AND QT_FEATURE_thread AND NOT ANDROID AND NOT WASM AND NOT rtems) +if(QT_FEATURE_qml_preview AND QT_FEATURE_thread AND NOT ANDROID AND NOT WASM AND NOT IOS AND NOT rtems) add_subdirectory(qmlpreview) endif() -if(QT_BUILD_SHARED_LIBS AND QT_FEATURE_thread AND TARGET Qt::Quick AND NOT ANDROID AND NOT WASM AND NOT rtems) +if(QT_BUILD_SHARED_LIBS AND QT_FEATURE_thread AND TARGET Qt::Quick AND NOT ANDROID AND NOT WASM AND NOT IOS AND NOT rtems) add_subdirectory(qmlscene) add_subdirectory(qmltime) endif() -if(QT_BUILD_SHARED_LIBS AND QT_FEATURE_process AND QT_FEATURE_regularexpression AND QT_FEATURE_thread AND TARGET Qt::Quick AND NOT ANDROID AND NOT WASM AND NOT rtems) +if(QT_BUILD_SHARED_LIBS + AND QT_FEATURE_process + AND QT_FEATURE_regularexpression + AND QT_FEATURE_thread + AND TARGET Qt::Quick + AND NOT ANDROID + AND NOT IOS + AND NOT WASM + AND NOT rtems) add_subdirectory(qmlplugindump) endif() if(TARGET Qt::Quick @@ -48,6 +54,7 @@ if(TARGET Qt::Quick AND QT_FEATURE_spinbox AND QT_FEATURE_textedit AND NOT ANDROID + AND NOT IOS AND NOT WASM AND NOT rtems) add_subdirectory(qmleasing) @@ -55,9 +62,9 @@ endif() if(QT_FEATURE_thread AND TARGET Qt::QuickTest AND NOT ANDROID AND NOT WASM AND NOT rtems) add_subdirectory(qmltestrunner) endif() -if(QT_FEATURE_private_tests AND QT_FEATURE_thread AND NOT ANDROID AND NOT WASM AND NOT rtems) +if(QT_FEATURE_private_tests AND QT_FEATURE_thread AND NOT ANDROID AND NOT WASM AND NOT IOS AND NOT rtems) add_subdirectory(qmljs) endif() -if (QT_FEATURE_private_tests AND NOT ANDROID AND NOT WASM AND NOT rtems) +if (QT_FEATURE_private_tests AND NOT CMAKE_CROSSCOMPILING) add_subdirectory(qmljsrootgen) endif() diff --git a/tools/qml/CMakeLists.txt b/tools/qml/CMakeLists.txt index 099f3dc68d4..6cc772de9c0 100644 --- a/tools/qml/CMakeLists.txt +++ b/tools/qml/CMakeLists.txt @@ -1,13 +1,11 @@ # Generated from qml.pro. ##################################################################### -## qml Tool: +## qml App: ##################################################################### -qt_get_tool_target_name(target_name qml) -qt_internal_add_tool(${target_name} +qt_internal_add_app(qml TARGET_DESCRIPTION "QML Runtime" - TOOLS_TARGET Qml # special case SOURCES conf.h main.cpp @@ -16,12 +14,7 @@ qt_internal_add_tool(${target_name} Qt::QmlPrivate ) -# special case begin -# Don't set properties on a host tool when cross compiling, because it -# is not being built. -if(CMAKE_CROSSCOMPILING AND NOT QT_BUILD_TOOLS_WHEN_CROSSCOMPILING) - return() -endif() +set_target_properties(qml PROPERTIES WIN32_EXECUTABLE FALSE) set_source_files_properties( conf/default.qml @@ -30,7 +23,6 @@ set_source_files_properties( conf/content/resizeWindowToItem.qml PROPERTIES QT_SKIP_QUICKCOMPILER 1 ) -# special case end # Resources: set(qml_resource_files @@ -41,7 +33,7 @@ set(qml_resource_files "resources/qml-64.png" ) -qt_internal_add_resource(${target_name} "qml" +qt_internal_add_resource(qml qml PREFIX "/qt-project.org/QmlRuntime" FILES @@ -49,18 +41,17 @@ qt_internal_add_resource(${target_name} "qml" ) # Turn the tool into its own self-contained qml module -qt6_add_qml_module(${target_name} +qt6_add_qml_module(qml URI QmlRuntime.Config VERSION 1.0 - NO_CREATE_PLUGIN_TARGET ) -qt_internal_extend_target(${target_name} CONDITION TARGET Qt::Gui +qt_internal_extend_target(qml CONDITION TARGET Qt::Gui PUBLIC_LIBRARIES Qt::Gui ) -qt_internal_extend_target(${target_name} CONDITION TARGET Qt::Widgets +qt_internal_extend_target(qml CONDITION TARGET Qt::Widgets PUBLIC_LIBRARIES Qt::Widgets ) @@ -73,7 +64,7 @@ qt_internal_extend_target(${target_name} CONDITION TARGET Qt::Widgets # OTHER_FILES = "resources/Info.plist" # QMAKE_INFO_PLIST = "resources/Info.plist" -qt_internal_extend_target(${target_name} CONDITION QT_FEATURE_qml_debug +qt_internal_extend_target(qml CONDITION QT_FEATURE_qml_debug DEFINES QT_QML_DEBUG_NO_WARNING ) diff --git a/tools/qml/conf/resizeToItem.qml b/tools/qml/conf/resizeToItem.qml index 480995a6b0f..0325c07cc2b 100644 --- a/tools/qml/conf/resizeToItem.qml +++ b/tools/qml/conf/resizeToItem.qml @@ -52,6 +52,6 @@ import QmlRuntime.Config 1.0 Configuration { PartialScene { itemType: "QQuickItem" - container: "content/resizeWindowToItem.qml" + container: "qrc:/qt-project.org/QmlRuntime/conf/content/resizeWindowToItem.qml" } } diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 66f9dcba5f2..aab662bb750 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -408,8 +408,8 @@ int main(int argc, char *argv[]) QCommandLineParser parser; parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments); - const QCommandLineOption helpOption = parser.addHelpOption(); - const QCommandLineOption versionOption = parser.addVersionOption(); + parser.addHelpOption(); + parser.addVersionOption(); #ifdef QT_GUI_LIB QCommandLineOption apptypeOption(QStringList() << QStringLiteral("a") << QStringLiteral("apptype"), QCoreApplication::translate("main", "Select which application class to use. Default is gui."), @@ -484,14 +484,7 @@ int main(int argc, char *argv[]) parser.addPositionalArgument("args", QCoreApplication::translate("main", "Arguments after '--' are ignored, but passed through to the application.arguments variable in QML."), "[-- args...]"); - if (!parser.parse(QCoreApplication::arguments())) { - qWarning() << parser.errorText(); - exit(1); - } - if (parser.isSet(versionOption)) - parser.showVersion(); - if (parser.isSet(helpOption)) - parser.showHelp(); + parser.process(*app); if (parser.isSet(listConfOption)) listConfFiles(); if (applicationType == QmlApplicationTypeUnknown) { diff --git a/tools/qmlcachegen/Qt6QuickCompilerConfig.cmake.in b/tools/qmlcachegen/Qt6QuickCompilerConfig.cmake.in index fe19af78cb9..1ed1568de5a 100644 --- a/tools/qmlcachegen/Qt6QuickCompilerConfig.cmake.in +++ b/tools/qmlcachegen/Qt6QuickCompilerConfig.cmake.in @@ -1,4 +1,5 @@ -function(QTQUICK_COMPILER_ADD_RESOURCES) - message(WARNING "Use qt6_add_resources instead of qtquick_compiler_add_resources." - "QML and JavaScript files are automatically compiled then.") +function(qtquick_compiler_add_resources) + message(WARNING "Use qt_add_qml_module instead of qtquick_compiler_add_resources." + "QML and JavaScript files are automatically compiled when creating a QML" + " module.") endfunction() diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp index 6584d76af89..29fe6094698 100644 --- a/tools/qmlcachegen/qmlcachegen.cpp +++ b/tools/qmlcachegen/qmlcachegen.cpp @@ -93,7 +93,7 @@ int main(int argc, char **argv) QCommandLineOption filterResourceFileOption(QStringLiteral("filter-resource-file"), QCoreApplication::translate("main", "Filter out QML/JS files from a resource file that can be cached ahead of time instead")); parser.addOption(filterResourceFileOption); - QCommandLineOption resourceFileMappingOption(QStringLiteral("resource-file-mapping"), QCoreApplication::translate("main", "Path from original resource file to new one"), QCoreApplication::translate("main", "old-name:new-name")); + QCommandLineOption resourceFileMappingOption(QStringLiteral("resource-file-mapping"), QCoreApplication::translate("main", "Path from original resource file to new one"), QCoreApplication::translate("main", "old-name=new-name")); parser.addOption(resourceFileMappingOption); QCommandLineOption resourceOption(QStringLiteral("resource"), QCoreApplication::translate("main", "Qt resource file that might later contain one of the compiled files"), QCoreApplication::translate("main", "resource-file-name")); parser.addOption(resourceOption); @@ -106,9 +106,6 @@ int main(int argc, char **argv) QCommandLineOption directCallsOption(QStringLiteral("direct-calls"), QCoreApplication::translate("main", "This option is ignored.")); directCallsOption.setFlags(QCommandLineOption::HiddenFromHelp); parser.addOption(directCallsOption); - QCommandLineOption qmlJSRuntimeOption(QStringLiteral("qmljs-runtime"), QCoreApplication::translate("main", "This option is ignored.")); - qmlJSRuntimeOption.setFlags(QCommandLineOption::HiddenFromHelp); - parser.addOption(qmlJSRuntimeOption); QCommandLineOption includesOption(QStringLiteral("i"), QCoreApplication::translate("main", "This option is ignored."), QCoreApplication::translate("main", "ignored file")); includesOption.setFlags(QCommandLineOption::HiddenFromHelp); parser.addOption(includesOption); diff --git a/tools/qmlcachegen/qtquickcompiler.prf b/tools/qmlcachegen/qtquickcompiler.prf index 262ed08785f..b7413a3de36 100644 --- a/tools/qmlcachegen/qtquickcompiler.prf +++ b/tools/qmlcachegen/qtquickcompiler.prf @@ -77,6 +77,7 @@ for(res, QMLCACHE_RESOURCE_FILES) { defineReplace(qmlCacheOutputName) { name = $$absolute_path($$1, $$OUT_PWD) name = $$relative_path($$name, $$_PRO_FILE_PWD_) + contains(name, ^\\.\\..*): name = $$relative_path($$1, $$OUT_PWD) name = $$replace(name, \\.qml$, _qml) name = $$replace(name, \\.js$, _js) name = $$replace(name, \\.mjs$, _mjs) diff --git a/tools/qmldom/qmldomtool.cpp b/tools/qmldom/qmldomtool.cpp index 1ab9dedc6a2..01665786808 100644 --- a/tools/qmldom/qmldomtool.cpp +++ b/tools/qmldom/qmldomtool.cpp @@ -41,6 +41,7 @@ #include <QtQmlDom/private/qqmldomfieldfilter_p.h> #include <cstdio> +#include <optional> #if QT_CONFIG(commandlineparser) # include <QtCore/qcommandlineparser.h> @@ -145,6 +146,10 @@ int main(int argc, char *argv[]) } } + std::optional<DomType> fileType; + if (parser.isSet(reformatOption)) + fileType = DomType::QmlFile; + Dependencies dep = Dependencies::None; int nBackups = 2; @@ -205,15 +210,22 @@ int main(int argc, char *argv[]) if (dep != Dependencies::None) env.loadBuiltins(); foreach (QString s, positionalArguments) { - env.loadFile(s, QString(), nullptr, LoadOption::DefaultLoad); + env.loadFile(s, QString(), nullptr, LoadOption::DefaultLoad, fileType); } envPtr->loadPendingDependencies(env); + bool hadFailures = false; + const qsizetype largestFileSizeToCheck = 32000; if (parser.isSet(reformatOption)) { for (auto s : positionalArguments) { - DomItem qmlFile = env.path(Paths::qmldirFilePath(s)); + DomItem qmlFile = env.path(Paths::qmlFilePath(QFileInfo(s).canonicalFilePath())); if (qmlFile) { qDebug() << "reformatting" << s; FileWriter fw; + LineWriterOptions lwOptions; + WriteOutChecks checks = WriteOutCheck::Default; + if (std::shared_ptr<QmlFile> qmlFilePtr = qmlFile.ownerAs<QmlFile>()) + if (qmlFilePtr->code().size() > largestFileSizeToCheck) + checks = WriteOutCheck::None; QString target = s; QString rDir = parser.value(reformatDirOption); if (!rDir.isEmpty()) { @@ -221,16 +233,8 @@ int main(int argc, char *argv[]) QDir d(rDir); target = d.filePath(f.fileName()); } - switch (fw.write( - target, - [&qmlFile, target](QTextStream &ts) { - LineWriter lw([&ts](QStringView s) { ts << s; }, target); - OutWriter ow(lw); - qmlFile.writeOut(ow); - ow.eof(); - return true; - }, - nBackups)) { + MutableDomItem res = qmlFile.writeOut(target, nBackups, lwOptions, &fw, checks); + switch (fw.status) { case FileWriter::Status::ShouldWrite: case FileWriter::Status::SkippedDueToFailure: qWarning() << "failure reformatting " << s; @@ -241,10 +245,10 @@ int main(int argc, char *argv[]) case FileWriter::Status::SkippedEqual: qDebug() << "no change"; } + hadFailures = hadFailures || !bool(res); } } - } - if (parser.isSet(dumpOption) || !parser.isSet(reformatOption)) { + } else if (parser.isSet(dumpOption) || !parser.isSet(reformatOption)) { qDebug() << "will dump\n"; QTextStream ts(stdout); auto sink = [&ts](QStringView v) { diff --git a/tools/qmleasing/CMakeLists.txt b/tools/qmleasing/CMakeLists.txt index 7257b7cf6ed..7ad22a30336 100644 --- a/tools/qmleasing/CMakeLists.txt +++ b/tools/qmleasing/CMakeLists.txt @@ -22,6 +22,8 @@ qt_internal_add_app(qmleasing uic ) +set_target_properties(qmleasing PROPERTIES WIN32_EXECUTABLE FALSE) + # Resources: set(resources_resource_files "Button.qml" diff --git a/tools/qmlformat/qmlformat.cpp b/tools/qmlformat/qmlformat.cpp index 7f7cdfbb24c..930d5f32dc8 100644 --- a/tools/qmlformat/qmlformat.cpp +++ b/tools/qmlformat/qmlformat.cpp @@ -144,7 +144,8 @@ bool parseFile(const QString &filename, const Options &options) if (options.verbose) qWarning().noquote() << "Writing to file" << filename; FileWriter fw; - res = qmlFile.writeOut(filename, 2, lwOptions, &fw, checks); + const unsigned numberOfBackupFiles = 0; + res = qmlFile.writeOut(filename, numberOfBackupFiles, lwOptions, &fw, checks); } else { QFile out; out.open(stdout, QIODevice::WriteOnly); @@ -246,7 +247,7 @@ int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QCoreApplication::setApplicationName("qmlformat"); - QCoreApplication::setApplicationVersion("1.0"); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); const auto options = buildCommandLineOptions(app); if (!options.valid) { diff --git a/tools/qmlimportscanner/CMakeLists.txt b/tools/qmlimportscanner/CMakeLists.txt index eb00026bc16..1f4e4dcca4a 100644 --- a/tools/qmlimportscanner/CMakeLists.txt +++ b/tools/qmlimportscanner/CMakeLists.txt @@ -34,13 +34,18 @@ configure_package_config_file( ) write_basic_package_version_file( - "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake" VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) +qt_internal_write_qt_package_version_file( + "${INSTALL_CMAKE_NAMESPACE}${target}" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" +) qt_install(FILES "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake" "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake" + "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake" DESTINATION "${config_install_dir}" COMPONENT Devel ) diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp index d59dc4a2e1f..78f47d866ea 100644 --- a/tools/qmlimportscanner/main.cpp +++ b/tools/qmlimportscanner/main.cpp @@ -34,10 +34,13 @@ #include <private/qqmljsresourcefilemapper_p.h> #include <QtCore/QCoreApplication> +#include <QtCore/QDebug> +#include <QtCore/QDateTime> #include <QtCore/QDir> #include <QtCore/QDirIterator> #include <QtCore/QFile> #include <QtCore/QFileInfo> +#include <QtCore/QHash> #include <QtCore/QSet> #include <QtCore/QStringList> #include <QtCore/QMetaObject> @@ -47,12 +50,20 @@ #include <QtCore/QJsonArray> #include <QtCore/QJsonDocument> #include <QtCore/QLibraryInfo> +#include <QtCore/QLoggingCategory> #include <iostream> #include <algorithm> +#include <unordered_map> +#include <unordered_set> QT_USE_NAMESPACE +Q_LOGGING_CATEGORY(lcImportScanner, "qt.qml.import.scanner"); +Q_LOGGING_CATEGORY(lcImportScannerFiles, "qt.qml.import.scanner.files"); + +using FileImportsWithoutDepsCache = QHash<QString, QVariantList>; + namespace { QStringList g_qmlImportPaths; @@ -69,21 +80,25 @@ inline QString dependenciesLiteral() { return QStringLiteral("dependencies"); } inline QString moduleLiteral() { return QStringLiteral("module"); } inline QString javascriptLiteral() { return QStringLiteral("javascript"); } inline QString directoryLiteral() { return QStringLiteral("directory"); } +inline QString linkTargetLiteral() +{ + return QStringLiteral("linkTarget"); +} void printUsage(const QString &appNameIn) { - const std::wstring appName = appNameIn.toStdWString(); + const std::string appName = appNameIn.toStdString(); #ifndef QT_BOOTSTRAPPED const QString qmlPath = QLibraryInfo::path(QLibraryInfo::QmlImportsPath); #else const QString qmlPath = QStringLiteral("/home/user/dev/qt-install/qml"); #endif - std::wcerr + std::cerr << "Usage: " << appName << " -rootPath path/to/app/qml/directory -importPath path/to/qt/qml/directory\n" " " << appName << " -qmlFiles file1 file2 -importPath path/to/qt/qml/directory\n" " " << appName << " -qrcFiles file1.qrc file2.qrc -importPath path/to/qt/qml/directory\n\n" "Example: " << appName << " -rootPath . -importPath " - << QDir::toNativeSeparators(qmlPath).toStdWString() + << QDir::toNativeSeparators(qmlPath).toStdString() << '\n'; } @@ -140,8 +155,9 @@ QVariantList findImportsInAst(QQmlJS::AST::UiHeaderItemList *headerItemList, con return imports; } -QVariantList findQmlImportsInQmlFile(const QString &filePath); -QVariantList findQmlImportsInJavascriptFile(const QString &filePath); +QVariantList findQmlImportsInFileWithoutDeps(const QString &filePath, + FileImportsWithoutDepsCache + &fileImportsWithoutDepsCache); static QString versionSuffix(QTypeRevision version) { @@ -151,7 +167,18 @@ static QString versionSuffix(QTypeRevision version) // Read the qmldir file, extract a list of plugins by // parsing the "plugin", "import", and "classname" directives. -QVariantMap pluginsForModulePath(const QString &modulePath, const QString &version) { +QVariantMap pluginsForModulePath(const QString &modulePath, + const QString &version, + FileImportsWithoutDepsCache + &fileImportsWithoutDepsCache) { + using Cache = QHash<QPair<QString, QString>, QVariantMap>; + static Cache pluginsCache; + const QPair<QString, QString> cacheKey = std::make_pair(modulePath, version); + const Cache::const_iterator it = pluginsCache.find(cacheKey); + if (it != pluginsCache.end()) { + return *it; + } + QFile qmldirFile(modulePath + QLatin1String("/qmldir")); if (!qmldirFile.exists()) { qWarning() << "qmldir file not found at" << modulePath; @@ -193,6 +220,10 @@ QVariantMap pluginsForModulePath(const QString &modulePath, const QString &versi pluginInfo[pluginIsOptionalLiteral()] = true; } + if (!parser.linkTarget().isEmpty()) { + pluginInfo[linkTargetLiteral()] = parser.linkTarget(); + } + pluginInfo[classnamesLiteral()] = parser.classNames().join(QLatin1Char(' ')); QStringList importsAndDependencies; @@ -216,13 +247,17 @@ QVariantMap pluginsForModulePath(const QString &modulePath, const QString &versi QVariantList importsFromFiles; const auto components = parser.components(); for (const auto &component : components) { + const QString componentFullPath = modulePath + QLatin1Char('/') + component.fileName; importsFromFiles - += findQmlImportsInQmlFile(modulePath + QLatin1Char('/') + component.fileName); + += findQmlImportsInFileWithoutDeps(componentFullPath, + fileImportsWithoutDepsCache); } const auto scripts = parser.scripts(); for (const auto &script : scripts) { + const QString scriptFullPath = modulePath + QLatin1Char('/') + script.fileName; importsFromFiles - += findQmlImportsInJavascriptFile(modulePath + QLatin1Char('/') + script.fileName); + += findQmlImportsInFileWithoutDeps(scriptFullPath, + fileImportsWithoutDepsCache); } for (const QVariant &import : importsFromFiles) { @@ -235,8 +270,11 @@ QVariantMap pluginsForModulePath(const QString &modulePath, const QString &versi version.isEmpty() ? name : (name + QLatin1Char(' ') + version)); } - if (!importsAndDependencies.isEmpty()) + if (!importsAndDependencies.isEmpty()) { + importsAndDependencies.removeDuplicates(); pluginInfo[dependenciesLiteral()] = importsAndDependencies; + } + pluginsCache.insert(cacheKey, pluginInfo); return pluginInfo; } @@ -249,6 +287,7 @@ QPair<QString, QString> resolveImportPath(const QString &uri, const QString &ver const QStringList parts = uri.split(dot, Qt::SkipEmptyParts); QString ver = version; + QPair<QString, QString> candidate; while (true) { for (const QString &qmlImportPath : qAsConst(g_qmlImportPaths)) { // Search for the most specific version first, and search @@ -263,8 +302,15 @@ QPair<QString, QString> resolveImportPath(const QString &uri, const QString &ver if (relativePath.endsWith(slash)) relativePath.chop(1); const QString candidatePath = QDir::cleanPath(qmlImportPath + slash + relativePath); - if (QDir(candidatePath).exists()) - return qMakePair(candidatePath, relativePath); // import found + const QDir candidateDir(candidatePath); + if (candidateDir.exists()) { + const auto newCandidate = qMakePair(candidatePath, relativePath); // import found + if (candidateDir.exists(u"qmldir"_qs)) // if it has a qmldir, we are fine + return newCandidate; + else if (candidate.first.isEmpty()) + candidate = newCandidate; + // otherwise we keep looking if we can find the module again (with a qmldir this time) + } } else { for (int index = parts.count() - 1; index >= 0; --index) { QString relativePath = parts.mid(0, index + 1).join(slash) @@ -272,8 +318,14 @@ QPair<QString, QString> resolveImportPath(const QString &uri, const QString &ver if (relativePath.endsWith(slash)) relativePath.chop(1); const QString candidatePath = QDir::cleanPath(qmlImportPath + slash + relativePath); - if (QDir(candidatePath).exists()) - return qMakePair(candidatePath, relativePath); // import found + const QDir candidateDir(candidatePath); + if (candidateDir.exists()) { + const auto newCandidate = qMakePair(candidatePath, relativePath); // import found + if (candidateDir.exists(u"qmldir"_qs)) + return newCandidate; + else if (candidate.first.isEmpty()) + candidate = newCandidate; + } } } } @@ -289,61 +341,187 @@ QPair<QString, QString> resolveImportPath(const QString &uri, const QString &ver ver = ver.mid(0, lastDot); } - return QPair<QString, QString>(); // not found + return candidate; +} + +// Provides a hasher for module details stored in a QVariantMap disguised as a QVariant.. +// Only supports a subset of types. +struct ImportVariantHasher { + std::size_t operator()(const QVariant &importVariant) const + { + size_t computedHash = 0; + QVariantMap importMap = qvariant_cast<QVariantMap>(importVariant); + for (auto it = importMap.constKeyValueBegin(); it != importMap.constKeyValueEnd(); ++it) { + const QString &key = it->first; + const QVariant &value = it->second; + + if (!value.isValid() || value.isNull()) { + computedHash = qHashMulti(computedHash, key, 0); + continue; + } + + const auto valueTypeId = value.typeId(); + switch (valueTypeId) { + case QMetaType::QString: + computedHash = qHashMulti(computedHash, key, value.toString()); + break; + case QMetaType::Bool: + computedHash = qHashMulti(computedHash, key, value.toBool()); + break; + case QMetaType::QStringList: + computedHash = qHashMulti(computedHash, key, value.toStringList()); + break; + default: + Q_ASSERT_X(valueTypeId, "ImportVariantHasher", "Invalid variant type detected"); + break; + } + } + + return computedHash; + } +}; + +using ImportDetailsAndDeps = QPair<QVariantMap, QStringList>; + +// Returns the import information as it will be written out to the json / .cmake file. +// The dependencies are not stored in the same QVariantMap because we don't currently need that +// information in the output file. +ImportDetailsAndDeps +getImportDetails(const QVariant &inputImport, + FileImportsWithoutDepsCache &fileImportsWithoutDepsCache) { + + using Cache = std::unordered_map<QVariant, ImportDetailsAndDeps, ImportVariantHasher>; + static Cache cache; + + const Cache::const_iterator it = cache.find(inputImport); + if (it != cache.end()) { + return it->second; + } + + QVariantMap import = qvariant_cast<QVariantMap>(inputImport); + QStringList dependencies; + if (import.value(typeLiteral()) == moduleLiteral()) { + const QString version = import.value(versionLiteral()).toString(); + const QPair<QString, QString> paths = + resolveImportPath(import.value(nameLiteral()).toString(), version); + QVariantMap plugininfo; + if (!paths.first.isEmpty()) { + import.insert(pathLiteral(), paths.first); + import.insert(relativePathLiteral(), paths.second); + plugininfo = pluginsForModulePath(paths.first, + version, + fileImportsWithoutDepsCache); + } + QString linkTarget = plugininfo.value(linkTargetLiteral()).toString(); + QString plugins = plugininfo.value(pluginsLiteral()).toString(); + bool isOptional = plugininfo.value(pluginIsOptionalLiteral(), QVariant(false)).toBool(); + QString classnames = plugininfo.value(classnamesLiteral()).toString(); + if (!linkTarget.isEmpty()) + import.insert(linkTargetLiteral(), linkTarget); + if (!plugins.isEmpty()) + import.insert(QStringLiteral("plugin"), plugins); + if (isOptional) + import.insert(pluginIsOptionalLiteral(), true); + if (!classnames.isEmpty()) + import.insert(QStringLiteral("classname"), classnames); + if (plugininfo.contains(dependenciesLiteral())) { + dependencies = plugininfo.value(dependenciesLiteral()).toStringList(); + } + } + import.remove(versionLiteral()); + + const ImportDetailsAndDeps result = {import, dependencies}; + cache.insert({inputImport, result}); + return result; } -// Find absolute file system paths and plugins for a list of modules. -QVariantList findPathsForModuleImports(const QVariantList &imports) +// Parse a dependency string line into a QVariantMap, to be used as a key when processing imports +// in getGetDetailedModuleImportsIncludingDependencies. +QVariantMap dependencyStringToImport(const QString &line) { + const auto dep = QStringView{line}.split(QLatin1Char(' '), Qt::SkipEmptyParts); + const QString name = dep[0].toString(); + QVariantMap depImport; + depImport[typeLiteral()] = moduleLiteral(); + depImport[nameLiteral()] = name; + if (dep.length() > 1) + depImport[versionLiteral()] = dep[1].toString(); + return depImport; +} + +// Returns details of given input import and its recursive module dependencies. +// The details include absolute file system paths for the the module plugin, components, +// etc. +// An internal cache is used to prevent repeated computation for the same input module. +QVariantList getGetDetailedModuleImportsIncludingDependencies( + const QVariant &inputImport, + FileImportsWithoutDepsCache &fileImportsWithoutDepsCache) { + using Cache = std::unordered_map<QVariant, QVariantList, ImportVariantHasher>; + static Cache importsCacheWithDeps; + + const Cache::const_iterator it = importsCacheWithDeps.find(inputImport); + if (it != importsCacheWithDeps.end()) { + return it->second; + } + QVariantList done; - QVariantList importsCopy(imports); - - for (int i = 0; i < importsCopy.length(); ++i) { - QVariantMap import = qvariant_cast<QVariantMap>(importsCopy.at(i)); - if (import.value(typeLiteral()) == moduleLiteral()) { - const QString version = import.value(versionLiteral()).toString(); - const QPair<QString, QString> paths = - resolveImportPath(import.value(nameLiteral()).toString(), version); - QVariantMap plugininfo; - if (!paths.first.isEmpty()) { - import.insert(pathLiteral(), paths.first); - import.insert(relativePathLiteral(), paths.second); - plugininfo = pluginsForModulePath(paths.first, version); - } - QString plugins = plugininfo.value(pluginsLiteral()).toString(); - bool isOptional = plugininfo.value(pluginIsOptionalLiteral(), QVariant(false)).toBool(); - QString classnames = plugininfo.value(classnamesLiteral()).toString(); - if (!plugins.isEmpty()) - import.insert(QStringLiteral("plugin"), plugins); - if (isOptional) - import.insert(pluginIsOptionalLiteral(), true); - if (!classnames.isEmpty()) - import.insert(QStringLiteral("classname"), classnames); - if (plugininfo.contains(dependenciesLiteral())) { - const QStringList dependencies = plugininfo.value(dependenciesLiteral()).toStringList(); - for (const QString &line : dependencies) { - const auto dep = QStringView{line}.split(QLatin1Char(' '), Qt::SkipEmptyParts); - const QString name = dep[0].toString(); - QVariantMap depImport; - depImport[typeLiteral()] = moduleLiteral(); - depImport[nameLiteral()] = name; - if (dep.length() > 1) - depImport[versionLiteral()] = dep[1].toString(); - - if (!importsCopy.contains(depImport)) - importsCopy.append(depImport); + QVariantList importsToProcess; + std::unordered_set<QVariant, ImportVariantHasher> importsSeen; + importsToProcess.append(inputImport); + + for (int i = 0; i < importsToProcess.length(); ++i) { + const QVariant importToProcess = importsToProcess.at(i); + auto [details, deps] = getImportDetails(importToProcess, fileImportsWithoutDepsCache); + if (details.value(typeLiteral()) == moduleLiteral()) { + for (const QString &line : deps) { + const QVariantMap depImport = dependencyStringToImport(line); + + // Skip self-dependencies. + if (depImport == importToProcess) + continue; + + if (importsSeen.find(depImport) == importsSeen.end()) { + importsToProcess.append(depImport); + importsSeen.insert(depImport); } } } - import.remove(versionLiteral()); - done.append(import); + done.append(details); } + + importsCacheWithDeps.insert({inputImport, done}); return done; } +QVariantList mergeImports(const QVariantList &a, const QVariantList &b); + +// Returns details of given input imports and their recursive module dependencies. +QVariantList getGetDetailedModuleImportsIncludingDependencies( + const QVariantList &inputImports, + FileImportsWithoutDepsCache &fileImportsWithoutDepsCache) +{ + QVariantList result; + + // Get rid of duplicates in input module list. + QVariantList inputImportsCopy; + inputImportsCopy = mergeImports(inputImportsCopy, inputImports); + + // Collect recursive dependencies for each input module and merge into result, discarding + // duplicates. + for (auto it = inputImportsCopy.begin(); it != inputImportsCopy.end(); ++it) { + QVariantList imports = getGetDetailedModuleImportsIncludingDependencies( + *it, fileImportsWithoutDepsCache); + result = mergeImports(result, imports); + } + return result; +} + // Scan a single qml file for import statements QVariantList findQmlImportsInQmlCode(const QString &filePath, const QString &code) { + qCDebug(lcImportScannerFiles) << "Parsing code and finding imports in" << filePath + << "TS:" << QDateTime::currentMSecsSinceEpoch(); + QQmlJS::Engine engine; QQmlJS::Lexer lexer(&engine); lexer.setCode(code, /*line = */ 1); @@ -439,9 +617,17 @@ QVariantList findQmlImportsInJavascriptFile(const QString &filePath) return collector.imports; } -// Scan a single qml or js file for import statements -QVariantList findQmlImportsInFile(const QString &filePath) +// Scan a single qml or js file for import statements without resolving dependencies. +QVariantList findQmlImportsInFileWithoutDeps(const QString &filePath, + FileImportsWithoutDepsCache + &fileImportsWithoutDepsCache) { + const FileImportsWithoutDepsCache::const_iterator it = + fileImportsWithoutDepsCache.find(filePath); + if (it != fileImportsWithoutDepsCache.end()) { + return *it; + } + QVariantList imports; if (filePath == QLatin1String("-")) { QFile f; @@ -451,12 +637,47 @@ QVariantList findQmlImportsInFile(const QString &filePath) imports = findQmlImportsInQmlFile(filePath); } else if (filePath.endsWith(QLatin1String(".js"))) { imports = findQmlImportsInJavascriptFile(filePath); + } else { + qCDebug(lcImportScanner) << "Skipping file because it's not a .qml/.js file"; + return imports; } - return findPathsForModuleImports(imports); + fileImportsWithoutDepsCache.insert(filePath, imports); + return imports; +} + +// Scan a single qml or js file for import statements, resolve dependencies and return the full +// list of modules the file depends on. +QVariantList findQmlImportsInFile(const QString &filePath, + FileImportsWithoutDepsCache + &fileImportsWithoutDepsCache) { + const auto fileProcessTimeBegin = QDateTime::currentDateTime(); + + QVariantList imports = findQmlImportsInFileWithoutDeps(filePath, + fileImportsWithoutDepsCache); + if (imports.empty()) + return imports; + + const auto pathsTimeBegin = QDateTime::currentDateTime(); + + qCDebug(lcImportScanner) << "Finding module paths for imported modules in" << filePath + << "TS:" << pathsTimeBegin.toMSecsSinceEpoch(); + QVariantList importPaths = getGetDetailedModuleImportsIncludingDependencies( + imports, fileImportsWithoutDepsCache); + + const auto pathsTimeEnd = QDateTime::currentDateTime(); + const auto duration = pathsTimeBegin.msecsTo(pathsTimeEnd); + const auto fileProcessingDuration = fileProcessTimeBegin.msecsTo(pathsTimeEnd); + qCDebug(lcImportScanner) << "Found module paths:" << importPaths.count() + << "TS:" << pathsTimeEnd.toMSecsSinceEpoch() + << "Path resolution duration:" << duration << "msecs"; + qCDebug(lcImportScanner) << "Scan duration:" << fileProcessingDuration << "msecs"; + return importPaths; } // Merge two lists of imports, discard duplicates. +// Empirical tests show that for a small amount of values, the n^2 QVariantList comparison +// is still faster than using an unordered_set + hashing a complex QVariantMap. QVariantList mergeImports(const QVariantList &a, const QVariantList &b) { QVariantList merged = a; @@ -486,7 +707,9 @@ struct pathStartsWith { // Scan all qml files in directory for import statements -QVariantList findQmlImportsInDirectory(const QString &qmlDir) +QVariantList findQmlImportsInDirectory(const QString &qmlDir, + FileImportsWithoutDepsCache + &fileImportsWithoutDepsCache) { QVariantList ret; if (qmlDir.isEmpty()) @@ -520,8 +743,15 @@ QVariantList findQmlImportsInDirectory(const QString &qmlDir) } for (const QFileInfo &x : entries) - if (x.isFile()) - ret = mergeImports(ret, findQmlImportsInFile(x.absoluteFilePath())); + if (x.isFile()) { + const auto entryAbsolutePath = x.absoluteFilePath(); + qCDebug(lcImportScanner) << "Scanning file" << entryAbsolutePath + << "TS:" << QDateTime::currentMSecsSinceEpoch(); + ret = mergeImports(ret, + findQmlImportsInFile( + entryAbsolutePath, + fileImportsWithoutDepsCache)); + } } return ret; } @@ -529,19 +759,29 @@ QVariantList findQmlImportsInDirectory(const QString &qmlDir) // Find qml imports recursively from a root set of qml files. // The directories in qmlDirs are searched recursively. // The files in qmlFiles parsed directly. -QVariantList findQmlImportsRecursively(const QStringList &qmlDirs, const QStringList &scanFiles) +QVariantList findQmlImportsRecursively(const QStringList &qmlDirs, + const QStringList &scanFiles, + FileImportsWithoutDepsCache + &fileImportsWithoutDepsCache) { QVariantList ret; + qCDebug(lcImportScanner) << "Scanning" << qmlDirs.count() << "root directories and" + << scanFiles.count() << "files."; + // Scan all app root qml directories for imports for (const QString &qmlDir : qmlDirs) { - QVariantList imports = findQmlImportsInDirectory(qmlDir); + qCDebug(lcImportScanner) << "Scanning root" << qmlDir + << "TS:" << QDateTime::currentMSecsSinceEpoch(); + QVariantList imports = findQmlImportsInDirectory(qmlDir, fileImportsWithoutDepsCache); ret = mergeImports(ret, imports); } // Scan app qml files for imports for (const QString &file : scanFiles) { - QVariantList imports = findQmlImportsInFile(file); + qCDebug(lcImportScanner) << "Scanning file" << file + << "TS:" << QDateTime::currentMSecsSinceEpoch(); + QVariantList imports = findQmlImportsInFile(file, fileImportsWithoutDepsCache); ret = mergeImports(ret, imports); } @@ -622,6 +862,9 @@ int main(int argc, char *argv[]) return 1; } + // QQmlDirParser returnes QMultiHashes. Ensure deterministic output. + QHashSeed::setDeterministicGlobalSeed(); + QStringList qmlRootPaths; QStringList scanFiles; QStringList qmlImportPaths; @@ -683,8 +926,13 @@ int main(int argc, char *argv[]) g_qmlImportPaths = qmlImportPaths; + FileImportsWithoutDepsCache fileImportsWithoutDepsCache; + // Find the imports! - QVariantList imports = findQmlImportsRecursively(qmlRootPaths, scanFiles); + QVariantList imports = findQmlImportsRecursively(qmlRootPaths, + scanFiles, + fileImportsWithoutDepsCache + ); QByteArray content; if (generateCmakeContent) { diff --git a/tools/qmljs/CMakeLists.txt b/tools/qmljs/CMakeLists.txt index 147ddf008c1..8e41facd96b 100644 --- a/tools/qmljs/CMakeLists.txt +++ b/tools/qmljs/CMakeLists.txt @@ -1,13 +1,11 @@ # Generated from qmljs.pro. ##################################################################### -## qmljs Tool: +## qmljs App: ##################################################################### -qt_get_tool_target_name(target_name qmljs) -qt_internal_add_tool(${target_name} +qt_internal_add_app(qmljs TARGET_DESCRIPTION "QML JavaScript Tool" - TOOLS_TARGET Qml # special case SOURCES qmljs.cpp DEFINES @@ -38,6 +36,7 @@ qt_internal_add_tool(${target_name} Qt::CorePrivate Qt::QmlPrivate ) +set_target_properties(qmljs PROPERTIES WIN32_EXECUTABLE FALSE) #### Keys ignored in scope 1:.:.:qmljs.pro:<TRUE>: # QMAKE_TARGET_DESCRIPTION = "QML" "JavaScript" "Tool" @@ -46,42 +45,42 @@ qt_internal_add_tool(${target_name} ## Scopes: ##################################################################### -qt_internal_extend_target(${target_name} CONDITION WIN32 +qt_internal_extend_target(qmljs CONDITION WIN32 DEFINES NOMINMAX ) -qt_internal_extend_target(${target_name} CONDITION disassembler AND ((TEST_architecture_arch STREQUAL "i386") OR (TEST_architecture_arch STREQUAL "x86_64")) +qt_internal_extend_target(qmljs CONDITION disassembler AND ((TEST_architecture_arch STREQUAL "i386") OR (TEST_architecture_arch STREQUAL "x86_64")) DEFINES WTF_USE_UDIS86=1 ) -qt_internal_extend_target(${target_name} CONDITION (TEST_architecture_arch STREQUAL "arm") AND disassembler +qt_internal_extend_target(qmljs CONDITION (TEST_architecture_arch STREQUAL "arm") AND disassembler DEFINES WTF_USE_ARMV7_DISASSEMBLER=1 ) -qt_internal_extend_target(${target_name} CONDITION (TEST_architecture_arch STREQUAL "arm64") AND disassembler +qt_internal_extend_target(qmljs CONDITION (TEST_architecture_arch STREQUAL "arm64") AND disassembler DEFINES WTF_USE_ARM64_DISASSEMBLER=1 ) -qt_internal_extend_target(${target_name} CONDITION (TEST_architecture_arch STREQUAL "mips") AND disassembler +qt_internal_extend_target(qmljs CONDITION (TEST_architecture_arch STREQUAL "mips") AND disassembler DEFINES WTF_USE_MIPS32_DISASSEMBLER=1 ) -qt_internal_extend_target(${target_name} CONDITION NOT disassembler +qt_internal_extend_target(qmljs CONDITION NOT disassembler DEFINES WTF_USE_UDIS86=0 ) -qt_internal_extend_target(${target_name} CONDITION CMAKE_BUILD_TYPE STREQUAL Release +qt_internal_extend_target(qmljs CONDITION CMAKE_BUILD_TYPE STREQUAL Release DEFINES NDEBUG ) -qt_internal_extend_target(${target_name} CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STRGREATER 6 AND NOT CLANG AND NOT ICC +qt_internal_extend_target(qmljs CONDITION GCC AND QT_COMPILER_VERSION_MAJOR STRGREATER 6 AND NOT CLANG AND NOT ICC COMPILE_OPTIONS -Wno-expansion-to-defined ) diff --git a/tools/qmllint/checkidentifiers.cpp b/tools/qmllint/checkidentifiers.cpp index 72e0d6fd7de..74b31f3e6cc 100644 --- a/tools/qmllint/checkidentifiers.cpp +++ b/tools/qmllint/checkidentifiers.cpp @@ -157,7 +157,7 @@ void CheckIdentifiers::checkMemberAccess(const QVector<FieldMember> &members, detectedRestrictiveName = access.m_name; scope = QQmlJSScope::ConstPtr(); } else { - scope = *it; + scope = it->scope; } continue; @@ -190,7 +190,7 @@ void CheckIdentifiers::checkMemberAccess(const QVector<FieldMember> &members, QQmlJSScope::ConstPtr rootType; if (!access.m_parentType.isEmpty()) - rootType = m_types.value(access.m_parentType); + rootType = m_types.value(access.m_parentType).scope; else rootType = scope; @@ -222,17 +222,17 @@ void CheckIdentifiers::checkMemberAccess(const QVector<FieldMember> &members, auto it = m_types.find(access.m_name); // Something was found but it wasn't the attached type we were looking for, it could be a prefix - if (it != m_types.end() && !(*it) && i+1 < members.length()) { + if (it != m_types.end() && !it->scope && i+1 < members.length()) { // See whether this is due to us getting the prefixed property in two accesses (i.e. "T" and "Item") // by checking again with a fixed name. it = m_types.find(access.m_name + QLatin1Char('.') + members[++i].m_name); - if (it == m_types.end() || !(*it) || (*it)->attachedTypeName().isEmpty()) + if (it == m_types.end() || !it->scope || it->scope->attachedTypeName().isEmpty()) --i; } - if (it != m_types.end() && *it && !(*it)->attachedTypeName().isEmpty()) { - if (const auto attached = (*it)->attachedType()) { + if (it != m_types.end() && it->scope && !it->scope->attachedTypeName().isEmpty()) { + if (const auto attached = it->scope->attachedType()) { scope = attached; continue; } @@ -249,10 +249,10 @@ void CheckIdentifiers::checkMemberAccess(const QVector<FieldMember> &members, } void CheckIdentifiers::operator()( - const QHash<QString, QQmlJSScope::ConstPtr> &qmlIDs, - const QHash<QQmlJS::SourceLocation, SignalHandler> &signalHandlers, - const MemberAccessChains &memberAccessChains, - const QQmlJSScope::ConstPtr &root, const QString &rootId) const + const QQmlJSScopesById &qmlIDs, + const QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> &signalHandlers, + const MemberAccessChains &memberAccessChains, const QQmlJSScope::ConstPtr &root, + const QString &rootId) const { // revisit all scopes QQueue<QQmlJSScope::ConstPtr> workQueue; @@ -281,10 +281,10 @@ void CheckIdentifiers::operator()( continue; } - auto it = qmlIDs.find(memberAccessBase.m_name); - if (it != qmlIDs.end()) { - if (!it->isNull()) { - checkMemberAccess(memberAccessChain, *it); + if (!memberAccessBase.m_name.isEmpty()) { + auto scope = qmlIDs.scope(memberAccessBase.m_name, currentScope); + if (!scope.isNull()) { + checkMemberAccess(memberAccessChain, scope); continue; } else if (!memberAccessChain.isEmpty()) { // It could be a qualified type name @@ -295,7 +295,7 @@ void CheckIdentifiers::operator()( const auto typeIt = m_types.find(qualified); if (typeIt != m_types.end()) { memberAccessChain.takeFirst(); - checkMemberAccess(memberAccessChain, *typeIt); + checkMemberAccess(memberAccessChain, typeIt->scope); continue; } } @@ -365,7 +365,7 @@ void CheckIdentifiers::operator()( const QString baseName = memberAccessBase.m_name; auto typeIt = m_types.find(memberAccessBase.m_name); bool baseIsPrefixed = false; - while (typeIt != m_types.end() && typeIt->isNull()) { + while (typeIt != m_types.end() && typeIt->scope.isNull()) { // This is a namespaced import. Check with the full name. if (!memberAccessChain.isEmpty()) { auto location = memberAccessBase.m_location; @@ -379,11 +379,21 @@ void CheckIdentifiers::operator()( } } - if (typeIt != m_types.end() && !typeIt->isNull()) { - checkMemberAccess(memberAccessChain, *typeIt); + if (typeIt != m_types.end() && !typeIt->scope.isNull()) { + checkMemberAccess(memberAccessChain, typeIt->scope); continue; } + // If we're in a custom parser component (or one of their children) we cannot be sure + // that this is really an unqualified access. We have to err on the side of producing + // false negatives for the sake of usability. + if (qmlScope->isInCustomParserParent()) { + // We can handle Connections properly + if (qmlScope->baseType() + && qmlScope->baseType()->internalName() != u"QQmlConnections"_qs) + continue; + } + const auto location = memberAccessBase.m_location; if (baseIsPrefixed) { @@ -442,7 +452,7 @@ void CheckIdentifiers::operator()( const auto handler = signalHandlers[id.location]; colorOut.write(QLatin1String(handler.isMultiline ? "function(" : "("), QtInfoMsg); - const auto parameters = handler.signal.parameterNames(); + const auto parameters = handler.signalParameters; for (int numParams = parameters.size(); numParams > 0; --numParams) { colorOut.write(parameters.at(parameters.size() - numParams), QtInfoMsg); if (numParams > 1) diff --git a/tools/qmllint/checkidentifiers.h b/tools/qmllint/checkidentifiers.h index c23a64f9bdb..ed131db5d4b 100644 --- a/tools/qmllint/checkidentifiers.h +++ b/tools/qmllint/checkidentifiers.h @@ -32,14 +32,11 @@ #include <QtQmlCompiler/private/qqmljslogger_p.h> #include <QtQmlCompiler/private/qqmljsscope_p.h> #include <QtQmlCompiler/private/qqmljsimporter_p.h> +#include <QtQmlCompiler/private/qqmljsmetatypes_p.h> +#include <QtQmlCompiler/private/qqmljsscopesbyid_p.h> class QColorOutput; -struct SignalHandler { - QQmlJSMetaMethod signal; - bool isMultiline; -}; - struct FieldMember { QString m_name; @@ -57,10 +54,10 @@ class CheckIdentifiers m_logger(logger), m_code(code), m_types(types), m_fileName(fileName) {} - void operator ()(const QHash<QString, QQmlJSScope::ConstPtr> &qmlIDs, - const QHash<QQmlJS::SourceLocation, SignalHandler> &signalHandlers, - const MemberAccessChains &memberAccessChains, - const QQmlJSScope::ConstPtr &root, const QString &rootId) const; + void operator()(const QQmlJSScopesById &qmlIDs, + const QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> &signalHandlers, + const MemberAccessChains &memberAccessChains, const QQmlJSScope::ConstPtr &root, + const QString &rootId) const; private: void checkMemberAccess(const QVector<FieldMember> &members, diff --git a/tools/qmllint/findwarnings.cpp b/tools/qmllint/findwarnings.cpp index 916962a12d8..d4b5e393831 100644 --- a/tools/qmllint/findwarnings.cpp +++ b/tools/qmllint/findwarnings.cpp @@ -36,376 +36,108 @@ #include <QtQml/private/qqmljsast_p.h> #include <QtQml/private/qqmljslexer_p.h> #include <QtQml/private/qqmljsparser_p.h> -#include <QtQml/private/qv4codegen_p.h> #include <QtQml/private/qqmlimportresolver_p.h> +#include <QtCore/private/qduplicatetracker_p.h> + #include <QtCore/qfile.h> #include <QtCore/qdiriterator.h> #include <QtCore/qscopedvaluerollback.h> -void FindWarningVisitor::checkInheritanceCycle(QQmlJSScope::ConstPtr scope) +bool FindWarningVisitor::visit(QQmlJS::AST::UiObjectDefinition *uiod) { - QQmlJSScope::ConstPtr originalScope = scope; - QList<QQmlJSScope::ConstPtr> scopes; - while (!scope.isNull()) { - - for (const QQmlJSAnnotation &annotation : scope->annotations()) { - if (annotation.isDeprecation()) { - QQQmlJSDeprecation deprecation = annotation.deprecation(); - - QString message = QStringLiteral("Type \"%1\" is deprecated") - .arg(scope->internalName()); - - if (!deprecation.reason.isEmpty()) - message.append(QStringLiteral(" (Reason: %1)").arg(deprecation.reason)); + QQmlJSImportVisitor::visit(uiod); - m_logger.log(message, Log_Deprecation, originalScope->sourceLocation() - ); - } - } - - if (scopes.contains(scope)) { - QString inheritenceCycle; - for (const auto &seen: qAsConst(scopes)) { - if (!inheritenceCycle.isEmpty()) - inheritenceCycle.append(QLatin1String(" -> ")); - inheritenceCycle.append(seen->baseTypeName()); + const QString name = m_currentScope->baseTypeName(); + if (name.endsWith(u"Connections"_qs)) { + QString target; + auto member = uiod->initializer->members; + while (member) { + if (member->member->kind == QQmlJS::AST::Node::Kind_UiScriptBinding) { + auto asBinding = static_cast<QQmlJS::AST::UiScriptBinding *>(member->member); + if (asBinding->qualifiedId->name == u"target"_qs) { + if (asBinding->statement->kind == QQmlJS::AST::Node::Kind_ExpressionStatement) { + auto expr = static_cast<QQmlJS::AST::ExpressionStatement *>( + asBinding->statement) + ->expression; + if (auto idexpr = + QQmlJS::AST::cast<QQmlJS::AST::IdentifierExpression *>(expr)) { + target = idexpr->name.toString(); + } else { + // more complex expressions are not supported + } + } + break; + } } - - m_logger.log(QStringLiteral("%1 is part of an inheritance cycle: %2") - .arg(scope->internalName()) - .arg(inheritenceCycle), - Log_InheritanceCycle); - - m_unknownImports.insert(scope->internalName()); - break; + member = member->next; } - - scopes.append(scope); - - if (scope->baseTypeName().isEmpty()) { - break; - } else if (auto newScope = scope->baseType()) { - scope = newScope; + QQmlJSScope::ConstPtr targetScope; + if (target.isEmpty()) { + // no target set, connection comes from parentF + QQmlJSScope::Ptr scope = m_currentScope; + do { + if (auto parentScope = scope->parentScope(); !parentScope.isNull()) + scope = parentScope; + else + break; + } while (scope->scopeType() != QQmlJSScope::QMLScope); + targetScope = m_rootScopeImports.value(scope->baseTypeName()).scope; } else { - m_logger.log(scope->baseTypeName() - + QStringLiteral(" was not found. Did you add all import paths?"), - Log_Import); - m_unknownImports.insert(scope->baseTypeName()); - break; - } - } -} - -void FindWarningVisitor::checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr scope) -{ - // These warnings do not apply for custom parsers and their children and need to be handled on a - // case by case basis - if (scope->isInCustomParserParent()) - return; - - auto children = scope->childScopes(); - while (!children.isEmpty()) { - auto childScope = children.takeFirst(); - const auto type = childScope->scopeType(); - switch (type) { - case QQmlJSScope::GroupedPropertyScope: - case QQmlJSScope::AttachedPropertyScope: - if (!childScope->baseType()) { - m_logger.log( - QStringLiteral("unknown %1 property scope %2.") - .arg(type == QQmlJSScope::GroupedPropertyScope - ? QStringLiteral("grouped") - : QStringLiteral("attached"), - childScope->internalName()), - Log_UnqualifiedAccess, - childScope->sourceLocation() - ); + // there was a target, check if we already can find it + if (auto scope = m_scopesById.scope(target, m_currentScope)) { + targetScope = scope; + } else { + m_outstandingConnections.push_back({ target, m_currentScope, uiod }); + return false; // visit children later once target is known } - children.append(childScope->childScopes()); - default: - break; - } - } -} - -void FindWarningVisitor::flushPendingSignalParameters() -{ - const SignalHandler handler = m_signalHandlers[m_pendingSingalHandler]; - for (const QString ¶meter : handler.signal.parameterNames()) { - m_currentScope->insertJSIdentifier( - parameter, { - QQmlJSScope::JavaScriptIdentifier::Injected, - m_pendingSingalHandler - }); - } - m_pendingSingalHandler = QQmlJS::SourceLocation(); -} - -void FindWarningVisitor::checkDefaultProperty(const QQmlJSScope::ConstPtr &scope) -{ - if (scope == m_exportedRootScope || scope->isArrayScope() - || scope->isInlineComponent()) // inapplicable - return; - - // These warnings do not apply for custom parsers and their children and need to be handled on a - // case by case basis - if (scope->isInCustomParserParent()) - return; - - const QQmlJSScope *scopeOfDefaultProperty = nullptr; - QString defaultPropertyName; - // NB: start looking for default property in parent scope (because this - // scope is not suitable), but progress through baseType() - for (auto s = scope->parentScope(); s; s = s->baseType()) { - defaultPropertyName = s->defaultPropertyName(); - if (!defaultPropertyName.isEmpty()) { - scopeOfDefaultProperty = s.data(); - break; } - - // If the parent scope is based on Component it can have any child element - if (s->internalName() == QStringLiteral("QQmlComponent")) - return; - } - if (defaultPropertyName.isEmpty()) { - if (scope->parentScope()->isFullyResolved()) { - m_logger.log(QStringLiteral("Cannot assign to non-existent default property"), - Log_Property, scope->sourceLocation()); + for (const auto scope = targetScope; targetScope; targetScope = targetScope->baseType()) { + const auto connectionMethods = targetScope->ownMethods(); + for (const auto &method : connectionMethods) + m_currentScope->addOwnMethod(method); } - return; - } - - Q_ASSERT(scopeOfDefaultProperty); - Q_ASSERT(scope->parentScope()); - QQmlJSMetaProperty defaultProp = scopeOfDefaultProperty->property(defaultPropertyName); - - const QQmlJSScope *parentScope = scope->parentScope().get(); - - // abuse QHash feature to construct default value through - // operator[]. default bool is false, which is what's needed - if (m_scopeHasDefaultPropertyAssignment[parentScope] && !defaultProp.isList()) { - // already has some object assigned to a default property and - // this default property is not a list property - m_logger.log(QStringLiteral("Cannot assign multiple objects to a default non-list property"), - Log_Property, scope->sourceLocation()); } - m_scopeHasDefaultPropertyAssignment[parentScope] = true; - auto propType = defaultProp.type(); - if (propType.isNull() || !propType->isFullyResolved() - || !scope->isFullyResolved()) // should be an error somewhere else - return; - - // Assigning any element to a QQmlComponent property implicitly wraps it into a Component - // Check whether the property can be assigned the scope - if (propType->canAssign(scope)) - return; + addDefaultProperties(); + m_objectDefinitionScopes << m_currentScope; - m_logger.log(QStringLiteral("Cannot assign to default property of incompatible type"), - Log_Property, scope->sourceLocation()); -} - -void FindWarningVisitor::throwRecursionDepthError() -{ - QQmlJSImportVisitor::throwRecursionDepthError(); -} - -bool FindWarningVisitor::visit(QQmlJS::AST::ExpressionStatement *ast) -{ - if (m_pendingSingalHandler.isValid()) { - enterEnvironment(QQmlJSScope::JSFunctionScope, "signalhandler", ast->firstSourceLocation()); - flushPendingSignalParameters(); - } return true; } -void FindWarningVisitor::endVisit(QQmlJS::AST::ExpressionStatement *) -{ - if (m_currentScope->scopeType() == QQmlJSScope::JSFunctionScope - && m_currentScope->baseTypeName() == "signalhandler") { - leaveEnvironment(); - } -} - -bool FindWarningVisitor::visit(QQmlJS::AST::Block *block) -{ - if (!QQmlJSImportVisitor::visit(block)) - return false; - if (m_pendingSingalHandler.isValid()) - flushPendingSignalParameters(); - return true; -} - -bool FindWarningVisitor::visit(QQmlJS::AST::WithStatement *withStatement) -{ - m_logger.log(QStringLiteral("with statements are strongly discouraged in QML " - "and might cause false positives when analysing unqualified " - "identifiers"), - Log_WithStatement, withStatement->firstSourceLocation()); - - return QQmlJSImportVisitor::visit(withStatement); -} - -static QString signalName(QStringView handlerName) -{ - if (handlerName.startsWith(u"on") && handlerName.size() > 2) { - QString signal = handlerName.mid(2).toString(); - for (int i = 0; i < signal.length(); ++i) { - QChar &ch = signal[i]; - if (ch.isLower()) - return QString(); - if (ch.isUpper()) { - ch = ch.toLower(); - return signal; - } - } - } - return QString(); -} - -bool FindWarningVisitor::visit(QQmlJS::AST::UiScriptBinding *uisb) +void FindWarningVisitor::endVisit(QQmlJS::AST::UiObjectDefinition *uiod) { - using namespace QQmlJS::AST; - - const auto qmlScope = m_currentScope; - if (!QQmlJSImportVisitor::visit(uisb)) - return false; - - auto name = uisb->qualifiedId->name; - if (name == QLatin1String("id")) { - // Figure out whether the current scope is the root scope. - if (auto parentScope = qmlScope->parentScope()) { - if (!parentScope->parentScope()) { - const auto expstat = cast<ExpressionStatement *>(uisb->statement); - const auto identexp = cast<IdentifierExpression *>(expstat->expression); - m_rootId = identexp->name.toString(); - } - } - return true; - } - - if (!qmlScope->isFullyResolved()) - return true; - - const QString signal = signalName(name); - if (signal.isEmpty()) { - for (const auto &childScope : qmlScope->childScopes()) { - if ((childScope->scopeType() == QQmlJSScope::AttachedPropertyScope - || childScope->scopeType() == QQmlJSScope::GroupedPropertyScope) - && childScope->internalName() == name) { - return true; - } - } - - if (!qmlScope->hasProperty(name.toString())) { - // These warnings do not apply for custom parsers and their children and need to be - // handled on a case by case basis - - if (qmlScope->isInCustomParserParent()) - return true; - - // TODO: Can this be in a better suited category? - m_logger.log(QStringLiteral("Binding assigned to \"%1\", but no property \"%1\" " - "exists in the current element.") - .arg(name), - Log_Type, uisb->firstSourceLocation()); - return true; - } - - const auto property = qmlScope->property(name.toString()); - if (!property.type()) { - m_logger.log(QStringLiteral("No type found for property \"%1\". This may be due " - "to a missing import statement or incomplete " - "qmltypes files.") - .arg(name), - Log_Type, uisb->firstSourceLocation()); - } - - const auto &annotations = property.annotations(); - - const auto deprecationAnn = std::find_if(annotations.cbegin(), annotations.cend(), [](const QQmlJSAnnotation &ann) { return ann.isDeprecation(); }); - - if (deprecationAnn != annotations.cend()) { - const auto deprecation = deprecationAnn->deprecation(); - - QString message = QStringLiteral("Binding on deprecated property \"%1\"") - .arg(property.propertyName()); - - if (!deprecation.reason.isEmpty()) - message.append(QStringLiteral(" (Reason: %1)").arg(deprecation.reason)); - - m_logger.log(message, Log_Deprecation, uisb->firstSourceLocation()); - } - + auto childScope = m_currentScope; + QQmlJSImportVisitor::endVisit(uiod); - return true; + if (m_currentScope == m_globalScope + || m_currentScope->baseTypeName() == QStringLiteral("Component")) { + return; } + QString parentPropertyName; + QDuplicateTracker<QQmlJSScope::ConstPtr> seen; + for (QQmlJSScope::ConstPtr scope = childScope; scope && !seen.hasSeen(scope); + scope = scope->baseType()) { + parentPropertyName = scope->parentPropertyName(); + if (parentPropertyName.isEmpty()) + continue; - if (!qmlScope->hasMethod(signal)) { - m_logger.log( - QStringLiteral("no matching signal found for handler \"%1\"").arg(name.toString()), - Log_UnqualifiedAccess, uisb->firstSourceLocation()); - return true; - } + auto property = scope->property(parentPropertyName); + property.setType(QQmlJSScope::ConstPtr(m_currentScope)); - QQmlJSMetaMethod scopeSignal; - for (QQmlJSScope::ConstPtr scope = qmlScope; scope; scope = scope->baseType()) { - const auto methods = scope->ownMethods(); - const auto methodsRange = methods.equal_range(signal); - for (auto method = methodsRange.first; method != methodsRange.second; ++method) { - if (method->methodType() != QQmlJSMetaMethod::Signal) - continue; - scopeSignal = *method; - break; + if (childScope->hasOwnProperty(parentPropertyName)) { + Q_ASSERT(childScope->ownProperty(parentPropertyName).index() >= 0); + } else { + // it's a new property, so must adjust the index. the index is + // "outdated" as it's a relative index of scope, not childScope (or + // it might even be -1 in theory but this is likely an error) + property.setIndex(childScope->ownProperties().size()); } - } - const auto statement = uisb->statement; - if (ExpressionStatement *expr = cast<ExpressionStatement *>(statement)) { - if (FunctionExpression *func = expr->expression->asFunctionDefinition()) { - // functions are already handled - // they do not get names inserted according to the signal, but access their formal - // parameters. Let's still check if the names match, though. - const QStringList signalParameters = scopeSignal.parameterNames(); - qsizetype i = 0, end = signalParameters.length(); - for (FormalParameterList *formal = func->formals; - formal; ++i, formal = formal->next) { - if (i == end) { - m_logger.log( - QStringLiteral("Signal handler for \"%2\" has more formal" - " parameters than the signal it handles.") - .arg(name), - Log_Signal, - uisb->firstSourceLocation() - ); - } - - const QStringView handlerParameter = formal->element->bindingIdentifier; - const qsizetype j = signalParameters.indexOf(handlerParameter); - if (j == i || j < 0) - continue; - - m_logger.log(QStringLiteral("Parameter %1 to signal handler for \"%2\"" - " is called \"%3\". The signal has a parameter" - " of the same name in position %4.") - .arg(i + 1) - .arg(name, handlerParameter) - .arg(j + 1), - Log_Signal, uisb->firstSourceLocation()); - } - - return true; - } + // TODO: This is bad. We shouldn't add a new property but rather amend the existing one. + childScope->addOwnProperty(property); } - - const auto firstSourceLocation = statement->firstSourceLocation(); - bool hasMultilineStatementBody - = statement->lastSourceLocation().startLine > firstSourceLocation.startLine; - m_pendingSingalHandler = firstSourceLocation; - m_signalHandlers.insert(firstSourceLocation, {scopeSignal, hasMultilineStatementBody}); - return true; } bool FindWarningVisitor::visit(QQmlJS::AST::IdentifierExpression *idexp) @@ -424,40 +156,10 @@ bool FindWarningVisitor::visit(QQmlJS::AST::IdentifierExpression *idexp) FindWarningVisitor::FindWarningVisitor(QQmlJSImporter *importer, QStringList qmltypesFiles, QString code, QList<QQmlJS::SourceLocation> comments, QString fileName, bool silent) - : QQmlJSImportVisitor(importer, + : QQmlJSImportVisitor(QQmlJSScope::create(), importer, implicitImportDirectory(fileName, importer->resourceFileMapper()), - qmltypesFiles, fileName, code, silent), - m_code(code), - m_rootId(QLatin1String("<id>")), - m_filePath(fileName) + qmltypesFiles, fileName, code, silent) { - m_currentScope->setInternalName("global"); - - QLatin1String jsGlobVars[] = { - /* Not listed on the MDN page; browser and QML extensions: */ - // console/debug api - QLatin1String("console"), QLatin1String("print"), - // garbage collector - QLatin1String("gc"), - // i18n - QLatin1String("qsTr"), QLatin1String("qsTrId"), QLatin1String("QT_TR_NOOP"), - QLatin1String("QT_TRANSLATE_NOOP"), QLatin1String("QT_TRID_NOOP"), - // XMLHttpRequest - QLatin1String("XMLHttpRequest") - }; - - QQmlJSScope::JavaScriptIdentifier globalJavaScript = { - QQmlJSScope::JavaScriptIdentifier::LexicalScoped, - QQmlJS::SourceLocation() - }; - for (const char **globalName = QV4::Compiler::Codegen::s_globalNames; - *globalName != nullptr; - ++globalName) { - m_currentScope->insertJSIdentifier(QString::fromLatin1(*globalName), globalJavaScript); - } - for (const auto& jsGlobVar: jsGlobVars) - m_currentScope->insertJSIdentifier(jsGlobVar, globalJavaScript); - parseComments(comments); } @@ -540,8 +242,9 @@ bool FindWarningVisitor::check() { // now that all ids are known, revisit any Connections whose target were perviously unknown for (auto const &outstandingConnection: m_outstandingConnections) { - auto targetScope = m_scopesById[outstandingConnection.targetName]; if (outstandingConnection.scope) { + auto targetScope = m_scopesById.scope(outstandingConnection.targetName, + outstandingConnection.scope); for (const auto scope = targetScope; targetScope; targetScope = targetScope->baseType()) { const auto connectionMethods = targetScope->ownMethods(); @@ -549,106 +252,17 @@ bool FindWarningVisitor::check() outstandingConnection.scope->addOwnMethod(method); } } - QScopedValueRollback<QQmlJSScope::Ptr> rollback(m_currentScope, outstandingConnection.scope); + QScopedValueRollback<QQmlJSScope::Ptr> rollback(m_currentScope, + outstandingConnection.scope); outstandingConnection.uiod->initializer->accept(this); } - auto unusedImports = m_importLocations; - for (const QString &type : m_usedTypes) { - for (const auto &importLocation : m_importTypeLocationMap.values(type)) - unusedImports.remove(importLocation); - - // If there are no more unused imports left we can abort early - if (unusedImports.isEmpty()) - break; - } - - for (const auto &import : unusedImports) { - m_logger.log(QString::fromLatin1("Unused import at %1:%2:%3") - .arg(m_filePath) - .arg(import.startLine) - .arg(import.startColumn), - Log_UnusedImport, import); - } - CheckIdentifiers check(&m_logger, m_code, m_rootScopeImports, m_filePath); check(m_scopesById, m_signalHandlers, m_memberAccessChains, m_globalScope, m_rootId); return !m_logger.hasWarnings() && !m_logger.hasErrors(); } -bool FindWarningVisitor::visit(QQmlJS::AST::UiObjectBinding *uiob) -{ - if (!QQmlJSImportVisitor::visit(uiob)) - return false; - - checkInheritanceCycle(m_currentScope); - return true; -} - -bool FindWarningVisitor::visit(QQmlJS::AST::UiObjectDefinition *uiod) -{ - using namespace QQmlJS::AST; - - if (!QQmlJSImportVisitor::visit(uiod)) - return false; - - const QString name = m_currentScope->baseTypeName(); - if (name.isEmpty() || name.front().isLower()) - return false; // Ignore grouped properties for now - - checkInheritanceCycle(m_currentScope); - - if (name.endsWith("Connections")) { - QString target; - auto member = uiod->initializer->members; - while (member) { - if (member->member->kind == QQmlJS::AST::Node::Kind_UiScriptBinding) { - auto asBinding = static_cast<QQmlJS::AST::UiScriptBinding*>(member->member); - if (asBinding->qualifiedId->name == QLatin1String("target")) { - if (asBinding->statement->kind == QQmlJS::AST::Node::Kind_ExpressionStatement) { - auto expr = static_cast<QQmlJS::AST::ExpressionStatement*>(asBinding->statement)->expression; - if (auto idexpr = QQmlJS::AST::cast<QQmlJS::AST::IdentifierExpression*>(expr)) { - target = idexpr->name.toString(); - } else { - // more complex expressions are not supported - } - } - break; - } - } - member = member->next; - } - QQmlJSScope::ConstPtr targetScope; - if (target.isEmpty()) { - // no target set, connection comes from parentF - QQmlJSScope::Ptr scope = m_currentScope; - do { - scope = scope->parentScope(); // TODO: rename method - } while (scope->scopeType() != QQmlJSScope::QMLScope); - targetScope = m_rootScopeImports.value(scope->baseTypeName()); - } else { - // there was a target, check if we already can find it - auto scopeIt = m_scopesById.find(target); - if (scopeIt != m_scopesById.end()) { - targetScope = *scopeIt; - } else { - m_outstandingConnections.push_back({target, m_currentScope, uiod}); - return false; // visit children later once target is known - } - } - for (const auto scope = targetScope; targetScope; targetScope = targetScope->baseType()) { - const auto connectionMethods = targetScope->ownMethods(); - for (const auto &method : connectionMethods) - m_currentScope->addOwnMethod(method); - } - } - - checkDefaultProperty(m_currentScope); - - return true; -} - bool FindWarningVisitor::visit(QQmlJS::AST::PatternElement *element) { if (element->isVariableDeclaration()) { @@ -668,46 +282,6 @@ bool FindWarningVisitor::visit(QQmlJS::AST::PatternElement *element) return true; } -void FindWarningVisitor::endVisit(QQmlJS::AST::UiObjectDefinition *uiod) -{ - auto childScope = m_currentScope; - QQmlJSImportVisitor::endVisit(uiod); - - checkGroupedAndAttachedScopes(childScope); - - if (m_currentScope == m_globalScope - || m_currentScope->baseTypeName() == QStringLiteral("Component")) { - return; - } - - QString parentPropertyName; - for (QQmlJSScope::ConstPtr scope = childScope; scope; scope = scope->baseType()) { - parentPropertyName = scope->parentPropertyName(); - if (parentPropertyName.isEmpty()) - continue; - - auto property = scope->property(parentPropertyName); - property.setType(QQmlJSScope::ConstPtr(m_currentScope)); - - if (childScope->hasOwnProperty(parentPropertyName)) { - Q_ASSERT(childScope->ownProperty(parentPropertyName).index() >= 0); - } else { - // it's a new property, so must adjust the index. the index is - // "outdated" as it's a relative index of scope, not childScope (or - // it might even be -1 in theory but this is likely an error) - property.setIndex(childScope->ownProperties().size()); - } - - // TODO: This is bad. We shouldn't add a new property but rather amend the existing one. - childScope->addOwnProperty(property); - } -} - -bool FindWarningVisitor::visit(QQmlJS::AST::FieldMemberExpression *) -{ - return true; -} - void FindWarningVisitor::endVisit(QQmlJS::AST::FieldMemberExpression *fieldMember) { using namespace QQmlJS::AST; @@ -732,7 +306,8 @@ void FindWarningVisitor::endVisit(QQmlJS::AST::FieldMemberExpression *fieldMembe const QString name = fieldMember->name.toString(); if (m_importTypeLocationMap.contains(name)) { - if (auto it = m_rootScopeImports.find(name); it != m_rootScopeImports.end() && !*(it)) + auto it = m_rootScopeImports.find(name); + if (it != m_rootScopeImports.end() && !it->scope) m_usedTypes.insert(name); } @@ -745,11 +320,6 @@ void FindWarningVisitor::endVisit(QQmlJS::AST::FieldMemberExpression *fieldMembe } } -bool FindWarningVisitor::visit(QQmlJS::AST::BinaryExpression *) -{ - return true; -} - void FindWarningVisitor::endVisit(QQmlJS::AST::BinaryExpression *binExp) { if (binExp->op == QSOperator::As @@ -759,36 +329,3 @@ void FindWarningVisitor::endVisit(QQmlJS::AST::BinaryExpression *binExp) m_fieldMemberBase = nullptr; } } - -bool FindWarningVisitor::visit(QQmlJS::AST::UiPublicMember *uipb) -{ - QQmlJSImportVisitor::visit(uipb); - if (uipb->type == QQmlJS::AST::UiPublicMember::Property && uipb->memberType != nullptr - && !uipb->memberType->name.isEmpty() && uipb->memberType->name != QLatin1String("alias")) { - const auto name = uipb->memberType->name.toString(); - if (m_rootScopeImports.contains(name) && !m_rootScopeImports[name].isNull()) { - if (m_importTypeLocationMap.contains(name)) - m_usedTypes.insert(name); - } else { - m_logger.log(name + QStringLiteral(" was not found. Did you add all import paths?"), - Log_Import); - } - } - - return true; -} - -bool FindWarningVisitor::visit(QQmlJS::AST::StringLiteral *sl) -{ - const QString s = m_code.mid(sl->literalToken.begin(), sl->literalToken.length); - - if (s.contains(QLatin1Char('\r')) || s.contains(QLatin1Char('\n')) || s.contains(QChar(0x2028u)) - || s.contains(QChar(0x2029u))) { - m_logger.log(QStringLiteral("String contains unescaped line terminator which is " - "deprecated. Use a template " - "literal instead."), - Log_MultilineString, sl->literalToken); - } - - return true; -} diff --git a/tools/qmllint/findwarnings.h b/tools/qmllint/findwarnings.h index e2538fe5b8f..b558bcb2c22 100644 --- a/tools/qmllint/findwarnings.h +++ b/tools/qmllint/findwarnings.h @@ -64,68 +64,26 @@ class FindWarningVisitor : public QQmlJSImportVisitor bool check(); private: - QHash<QQmlJS::SourceLocation, SignalHandler> m_signalHandlers; - QQmlJS::SourceLocation m_pendingSingalHandler; - MemberAccessChains m_memberAccessChains; QQmlJS::AST::ExpressionNode *m_fieldMemberBase = nullptr; - QString m_code; - QString m_rootId; - QString m_filePath; - QSet<QString> m_unknownImports; - - struct OutstandingConnection - { - QString targetName; - QQmlJSScope::Ptr scope; - QQmlJS::AST::UiObjectDefinition *uiod; - }; - - QVarLengthArray<OutstandingConnection, 3> m_outstandingConnections; // Connections whose target we have not encountered - - // records of whether a default property has object assigned to it. for - // correctness, the scope that defines the default property acts as a key - QHash<const QQmlJSScope *, bool> m_scopeHasDefaultPropertyAssignment; void parseComments(const QList<QQmlJS::SourceLocation> &comments); - void checkInheritanceCycle(QQmlJSScope::ConstPtr scope); - void checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr scope); - void flushPendingSignalParameters(); - void checkDefaultProperty(const QQmlJSScope::ConstPtr &scope); - - void throwRecursionDepthError() override; - // work around compiler error in clang11 using QQmlJSImportVisitor::visit; using QQmlJSImportVisitor::endVisit; - // start block/scope handling - bool visit(QQmlJS::AST::ExpressionStatement *ast) override; - void endVisit(QQmlJS::AST::ExpressionStatement *ast) override; - bool visit(QQmlJS::AST::Block *ast) override; - bool visit(QQmlJS::AST::WithStatement *withStatement) override; - - /* --- end block handling --- */ - - bool visit(QQmlJS::AST::UiObjectBinding *uiob) override; bool visit(QQmlJS::AST::UiObjectDefinition *uiod) override; - void endVisit(QQmlJS::AST::UiObjectDefinition *) override; - bool visit(QQmlJS::AST::UiScriptBinding *uisb) override; - bool visit(QQmlJS::AST::UiPublicMember *uipb) override; + void endVisit(QQmlJS::AST::UiObjectDefinition *uiod) override; // expression handling bool visit(QQmlJS::AST::IdentifierExpression *idexp) override; bool visit(QQmlJS::AST::PatternElement *) override; - bool visit(QQmlJS::AST::FieldMemberExpression *idprop) override; void endVisit(QQmlJS::AST::FieldMemberExpression *) override; - bool visit(QQmlJS::AST::BinaryExpression *) override; void endVisit(QQmlJS::AST::BinaryExpression *) override; - - bool visit(QQmlJS::AST::StringLiteral *) override; }; #endif // FINDUNQUALIFIED_H diff --git a/tools/qmllint/main.cpp b/tools/qmllint/main.cpp index 69beb70264a..9da624b87fb 100644 --- a/tools/qmllint/main.cpp +++ b/tools/qmllint/main.cpp @@ -45,6 +45,7 @@ #include <QtCore/qjsonobject.h> #include <QtCore/qjsonarray.h> #include <QtCore/qjsondocument.h> +#include <QtCore/qloggingcategory.h> #include <QtCore/qscopeguard.h> #if QT_CONFIG(commandlineparser) @@ -61,7 +62,7 @@ constexpr int JSON_LOGGING_FORMAT_REVISION = 1; static bool lint_file(const QString &filename, const bool silent, QJsonArray *json, const QStringList &qmlImportPaths, const QStringList &qmltypesFiles, - const QString &resourceFile, + const QStringList &resourceFiles, const QMap<QString, QQmlJSLogger::Option> &options, QQmlJSImporter &importer) { QJsonArray warnings; @@ -179,6 +180,9 @@ static bool lint_file(const QString &filename, const bool silent, QJsonArray *js parser.rootNode()->accept(&v); success = v.check(); + if (v.logger().hasErrors()) + return; + if (json) { for (const auto &error : v.logger().errors()) addJsonWarning(error); @@ -189,10 +193,10 @@ static bool lint_file(const QString &filename, const bool silent, QJsonArray *js } }; - if (resourceFile.isEmpty()) { + if (resourceFiles.isEmpty()) { check(nullptr); } else { - QQmlJSResourceFileMapper mapper({ resourceFile }); + QQmlJSResourceFileMapper mapper(resourceFiles); check(&mapper); } } @@ -214,7 +218,7 @@ int main(int argv, char *argc[]) parser.setApplicationDescription(QLatin1String(R"(QML syntax verifier and analyzer All warnings can be set to three levels: - disabled - Fully disables the warning. + disable - Fully disables the warning. info - Displays the warning but does not influence the return code. warning - Displays the warning and leads to a non-zero exit code if encountered. )")); @@ -252,16 +256,16 @@ All warnings can be set to three levels: } // TODO: Remove after Qt 6.2 - QCommandLineOption disableCheckUnqualified(QStringList() << "no-unqualified-id", - QLatin1String("Don't warn about unqualified identifiers (deprecated, please use --unqualified disable instead)")); + QCommandLineOption disableCheckUnqualified(QStringList() << "no-unqualified-id"); + disableCheckUnqualified.setFlags(QCommandLineOption::HiddenFromHelp); parser.addOption(disableCheckUnqualified); - QCommandLineOption disableCheckWithStatement(QStringList() << "no-with-statement", - QLatin1String("Don't warn about with statements (deprecated, please use --with-statements disable instead)")); + QCommandLineOption disableCheckWithStatement(QStringList() << "no-with-statement"); + disableCheckWithStatement.setFlags(QCommandLineOption::HiddenFromHelp); parser.addOption(disableCheckWithStatement); - QCommandLineOption disableCheckInheritanceCycle(QStringList() << "no-inheritance-cycle", - QLatin1String("Don't warn about inheritance cycles (deprecated, please use --inheritance-cycle disable instead")); + QCommandLineOption disableCheckInheritanceCycle(QStringList() << "no-inheritance-cycle"); + disableCheckInheritanceCycle.setFlags(QCommandLineOption::HiddenFromHelp); parser.addOption(disableCheckInheritanceCycle); QCommandLineOption resourceOption( @@ -286,7 +290,8 @@ All warnings can be set to three levels: QLatin1String("Do not include default import directories or the current directory. " "This may be used to run qmllint on a project using a different Qt version.")); parser.addOption(qmlImportNoDefault); - settings.addOption(QLatin1String("DisableDefaultImports"), false); + const QString qmlImportNoDefaultSetting = QLatin1String("DisableDefaultImports"); + settings.addOption(qmlImportNoDefaultSetting, false); QCommandLineOption qmltypesFilesOption( QStringList() << "i" @@ -344,53 +349,44 @@ All warnings can be set to three levels: if (NoWarnUnqualified) { options[QStringLiteral("unqualified")].m_disabled = true; - qWarning() << "Warning: --no-unqualified-id is deprecated. See --help."; + qWarning() + << "Warning: --no-unqualified-id is deprecated. Use --unqualified disable instead."; } if (NoWarnWithStatement) { options[QStringLiteral("with")].m_disabled = true; - qWarning() << "Warning: --no-with-statement is deprecated. See --help."; + qWarning() << "Warning: --no-with-statement is deprecated. Use --with disable instead."; } if (NoWarnInheritanceCycle) { options[QStringLiteral("inheritance-cycle")].m_disabled = true; - qWarning() << "Warning: --no-inheritance-cycle is deprecated. See --help."; + qWarning() << "Warning: --no-inheritance-cycle is deprecated. Use --inheritance-cycle " + "disable instead."; } // use host qml import path as a sane default if not explicitly disabled - QStringList qmlImportPaths = parser.isSet(qmlImportNoDefault) - ? QStringList {} -# ifndef QT_BOOTSTRAPPED - : QStringList { QLibraryInfo::path(QLibraryInfo::QmlImportsPath), QDir::currentPath() }; -# else - : QStringList { QDir::currentPath() }; -# endif - - if (parser.isSet(qmlImportPathsOption)) - qmlImportPaths << parser.values(qmlImportPathsOption); + QStringList defaultImportPaths = + QStringList { QLibraryInfo::path(QLibraryInfo::QmlImportsPath), QDir::currentPath() }; - qmlImportPaths << settings.value(qmlImportPathsSetting).toStringList(); + QStringList qmlImportPaths = + parser.isSet(qmlImportNoDefault) ? QStringList {} : defaultImportPaths; - QStringList qmltypesFiles; + QStringList defaultQmltypesFiles; if (parser.isSet(qmltypesFilesOption)) { - qmltypesFiles = parser.values(qmltypesFilesOption); - } else if (settings.isSet(qmltypesFilesSetting) - && !settings.value(qmltypesFilesSetting).toStringList().isEmpty()) { - qmltypesFiles = parser.values(qmltypesFilesSetting); + defaultQmltypesFiles = parser.values(qmltypesFilesOption); } else { // If none are given explicitly, use the qmltypes files from the current directory. QDirIterator it(".", {"*.qmltypes"}, QDir::Files); while (it.hasNext()) { it.next(); - qmltypesFiles.append(it.fileInfo().absoluteFilePath()); + defaultQmltypesFiles.append(it.fileInfo().absoluteFilePath()); } } + QStringList qmltypesFiles = defaultQmltypesFiles; - QString resourceFile; - if (parser.isSet(resourceOption)) - resourceFile = parser.value(resourceOption); - else if (settings.isSet(resourceSetting)) - resourceFile = settings.value(resourceSetting).toString(); + const QStringList defaultResourceFiles = + parser.isSet(resourceOption) ? parser.values(resourceOption) : QStringList {}; + QStringList resourceFiles = defaultResourceFiles; #else bool silent = false; @@ -398,8 +394,9 @@ All warnings can be set to three levels: bool warnUnqualified = true; bool warnWithStatement = true; bool warnInheritanceCycle = true; - QStringList qmlImportPahs {}; + QStringList qmlImportPaths {}; QStringList qmltypesFiles {}; + QStringList resourceFiles {}; #endif bool success = true; QQmlJSImporter importer(qmlImportPaths, nullptr); @@ -411,13 +408,44 @@ All warnings can be set to three levels: if (!parser.isSet(ignoreSettings)) { settings.search(filename); updateLogLevels(); + + const QDir fileDir = QFileInfo(filename).absoluteDir(); + auto addAbsolutePaths = [&](QStringList &list, const QStringList &entries) { + for (const QString &file : entries) + list << (QFileInfo(file).isAbsolute() ? file : fileDir.filePath(file)); + }; + + resourceFiles = defaultResourceFiles; + + addAbsolutePaths(resourceFiles, settings.value(resourceSetting).toStringList()); + + qmltypesFiles = defaultQmltypesFiles; + if (settings.isSet(qmltypesFilesSetting) + && !settings.value(qmltypesFilesSetting).toStringList().isEmpty()) { + qmltypesFiles = {}; + addAbsolutePaths(qmltypesFiles, + settings.value(qmltypesFilesSetting).toStringList()); + } + + if (parser.isSet(qmlImportNoDefault) + || (settings.isSet(qmlImportNoDefaultSetting) + && settings.value(qmlImportNoDefaultSetting).toBool())) { + qmlImportPaths = {}; + } else { + qmlImportPaths = defaultImportPaths; + } + + if (parser.isSet(qmlImportPathsOption)) + qmlImportPaths << parser.values(qmlImportPathsOption); + + addAbsolutePaths(qmlImportPaths, settings.value(qmlImportPathsSetting).toStringList()); } #else const auto arguments = app.arguments(); for (const QString &filename : arguments) { #endif success &= lint_file(filename, silent, useJson ? &jsonFiles : nullptr, qmlImportPaths, - qmltypesFiles, resourceFile, options, importer); + qmltypesFiles, resourceFiles, options, importer); } if (useJson) { diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 9ee6db39da5..9354ac548c1 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -991,19 +991,9 @@ void compactDependencies(QStringList *dependencies) } } -inline std::wostream &operator<<(std::wostream &str, const QString &s) -{ -#ifdef Q_OS_WIN - str << reinterpret_cast<const wchar_t *>(s.utf16()); -#else - str << s.toStdWString(); -#endif - return str; -} - void printDebugMessage(QtMsgType, const QMessageLogContext &, const QString &msg) { - std::wcerr << msg << std::endl; + std::cerr << msg.toStdString() << std::endl; // In case of QtFatalMsg the calling code will abort() when appropriate. } diff --git a/tools/qmlpreview/CMakeLists.txt b/tools/qmlpreview/CMakeLists.txt index 4c347a404ea..792e1ec3f4c 100644 --- a/tools/qmlpreview/CMakeLists.txt +++ b/tools/qmlpreview/CMakeLists.txt @@ -1,13 +1,11 @@ # Generated from qmlpreview.pro. ##################################################################### -## qmlpreview Tool: +## qmlpreview App: ##################################################################### -qt_get_tool_target_name(target_name qmlpreview) -qt_internal_add_tool(${target_name} +qt_internal_add_app(qmlpreview TARGET_DESCRIPTION "QML Preview" - TOOLS_TARGET Qml # special case SOURCES main.cpp qmlpreviewapplication.cpp qmlpreviewapplication.h @@ -17,5 +15,7 @@ qt_internal_add_tool(${target_name} Qt::QmlDebugPrivate ) +set_target_properties(qmlpreview PROPERTIES WIN32_EXECUTABLE FALSE) + #### Keys ignored in scope 1:.:.:qmlpreview.pro:<TRUE>: # QMAKE_TARGET_DESCRIPTION = "QML" "Preview" diff --git a/tools/qmlscene/CMakeLists.txt b/tools/qmlscene/CMakeLists.txt index 4566a604413..a55022371f5 100644 --- a/tools/qmlscene/CMakeLists.txt +++ b/tools/qmlscene/CMakeLists.txt @@ -1,13 +1,11 @@ # Generated from qmlscene.pro. ##################################################################### -## qmlscene Tool: +## qmlscene App: ##################################################################### -qt_get_tool_target_name(target_name qmlscene) -qt_internal_add_tool(${target_name} +qt_internal_add_app(qmlscene TARGET_DESCRIPTION "QML Scene Viewer" - TOOLS_TARGET Qml # special case SOURCES main.cpp DEFINES @@ -21,18 +19,20 @@ qt_internal_add_tool(${target_name} Qt::QuickPrivate ) +set_target_properties(qmlscene PROPERTIES WIN32_EXECUTABLE FALSE) + #### Keys ignored in scope 1:.:.:qmlscene.pro:<TRUE>: # QMAKE_TARGET_DESCRIPTION = "QML" "Scene" "Viewer" ## Scopes: ##################################################################### -qt_internal_extend_target(${target_name} CONDITION TARGET Qt::Widgets +qt_internal_extend_target(qmlscene CONDITION TARGET Qt::Widgets PUBLIC_LIBRARIES Qt::Widgets ) -qt_internal_extend_target(${target_name} CONDITION QT_FEATURE_qml_debug +qt_internal_extend_target(qmlscene CONDITION QT_FEATURE_qml_debug DEFINES QT_QML_DEBUG_NO_WARNING ) diff --git a/tools/qmltime/CMakeLists.txt b/tools/qmltime/CMakeLists.txt index e8d2ff8f57d..d4569af23a1 100644 --- a/tools/qmltime/CMakeLists.txt +++ b/tools/qmltime/CMakeLists.txt @@ -27,5 +27,4 @@ endif() qt6_add_qml_module(${target_name} URI QmlTime VERSION 1.0 - NO_CREATE_PLUGIN_TARGET )